summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-20 13:43:21 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-20 13:43:21 -0700
commit06f4e926d256d902dd9a53dcb400fd74974ce087 (patch)
tree0b438b67f5f0eff6fd617bc497a9dace6164a488
parent8e7bfcbab3825d1b404d615cb1b54f44ff81f981 (diff)
parentd93515611bbc70c2fe4db232e5feb448ed8e4cc9 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1446 commits) macvlan: fix panic if lowerdev in a bond tg3: Add braces around 5906 workaround. tg3: Fix NETIF_F_LOOPBACK error macvlan: remove one synchronize_rcu() call networking: NET_CLS_ROUTE4 depends on INET irda: Fix error propagation in ircomm_lmp_connect_response() irda: Kill set but unused variable 'bytes' in irlan_check_command_param() irda: Kill set but unused variable 'clen' in ircomm_connect_indication() rxrpc: Fix set but unused variable 'usage' in rxrpc_get_transport() be2net: Kill set but unused variable 'req' in lancer_fw_download() irda: Kill set but unused vars 'saddr' and 'daddr' in irlan_provider_connect_indication() atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined. rxrpc: Fix set but unused variable 'usage' in rxrpc_get_peer(). rxrpc: Kill set but unused variable 'local' in rxrpc_UDP_error_handler() rxrpc: Kill set but unused variable 'sp' in rxrpc_process_connection() rxrpc: Kill set but unused variable 'sp' in rxrpc_rotate_tx_window() pkt_sched: Kill set but unused variable 'protocol' in tc_classify() isdn: capi: Use pr_debug() instead of ifdefs. tg3: Update version to 3.119 tg3: Apply rx_discards fix to 5719/5720 ... Fix up trivial conflicts in arch/x86/Kconfig and net/mac80211/agg-tx.c as per Davem.
-rw-r--r--Documentation/ABI/testing/sysfs-bus-bcma31
-rw-r--r--Documentation/feature-removal-schedule.txt21
-rw-r--r--Documentation/networking/batman-adv.txt11
-rw-r--r--Documentation/networking/bonding.txt34
-rw-r--r--Documentation/networking/igb.txt13
-rw-r--r--Documentation/sysctl/net.txt11
-rw-r--r--MAINTAINERS21
-rw-r--r--arch/mips/txx9/generic/setup_tx4939.c21
-rw-r--r--arch/powerpc/include/asm/systbl.h1
-rw-r--r--arch/powerpc/include/asm/unistd.h3
-rw-r--r--arch/sparc/include/asm/unistd.h3
-rw-r--r--arch/sparc/kernel/systbls_32.S2
-rw-r--r--arch/sparc/kernel/systbls_64.S4
-rw-r--r--arch/x86/Kbuild1
-rw-r--r--arch/x86/Kconfig1
-rw-r--r--arch/x86/ia32/ia32entry.S1
-rw-r--r--arch/x86/include/asm/unistd_32.h3
-rw-r--r--arch/x86/include/asm/unistd_64.h2
-rw-r--r--arch/x86/kernel/syscall_table_32.S1
-rw-r--r--arch/x86/net/Makefile4
-rw-r--r--arch/x86/net/bpf_jit.S140
-rw-r--r--arch/x86/net/bpf_jit_comp.c654
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/atm/eni.c5
-rw-r--r--drivers/atm/he.c4
-rw-r--r--drivers/atm/idt77252.c52
-rw-r--r--drivers/atm/iphase.c14
-rw-r--r--drivers/atm/solos-pci.c3
-rw-r--r--drivers/bcma/Kconfig33
-rw-r--r--drivers/bcma/Makefile7
-rw-r--r--drivers/bcma/README19
-rw-r--r--drivers/bcma/TODO3
-rw-r--r--drivers/bcma/bcma_private.h28
-rw-r--r--drivers/bcma/core.c51
-rw-r--r--drivers/bcma/driver_chipcommon.c89
-rw-r--r--drivers/bcma/driver_chipcommon_pmu.c134
-rw-r--r--drivers/bcma/driver_pci.c163
-rw-r--r--drivers/bcma/host_pci.c196
-rw-r--r--drivers/bcma/main.c247
-rw-r--r--drivers/bcma/scan.c360
-rw-r--r--drivers/bcma/scan.h56
-rw-r--r--drivers/bluetooth/Kconfig4
-rw-r--r--drivers/bluetooth/ath3k.c4
-rw-r--r--drivers/bluetooth/btmrvl_sdio.c124
-rw-r--r--drivers/bluetooth/btmrvl_sdio.h68
-rw-r--r--drivers/bluetooth/btusb.c1
-rw-r--r--drivers/bluetooth/hci_ath.c7
-rw-r--r--drivers/bluetooth/hci_h4.c7
-rw-r--r--drivers/bluetooth/hci_ldisc.c6
-rw-r--r--drivers/ieee802154/fakehard.c10
-rw-r--r--drivers/infiniband/core/addr.c9
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.c3
-rw-r--r--drivers/infiniband/hw/cxgb4/cm.c3
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c5
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.h1
-rw-r--r--drivers/infiniband/hw/nes/nes_nic.c59
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c11
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ethtool.c28
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c24
-rw-r--r--drivers/isdn/capi/Kconfig15
-rw-r--r--drivers/isdn/capi/Makefile1
-rw-r--r--drivers/isdn/capi/capi.c139
-rw-r--r--drivers/isdn/capi/capifs.c239
-rw-r--r--drivers/isdn/capi/capifs.h28
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c5
-rw-r--r--drivers/isdn/gigaset/ev-layer.c26
-rw-r--r--drivers/isdn/hardware/eicon/debug.c3
-rw-r--r--drivers/isdn/hardware/eicon/message.c23
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c6
-rw-r--r--drivers/isdn/hardware/mISDN/hfcsusb.c5
-rw-r--r--drivers/isdn/hisax/arcofi.c4
-rw-r--r--drivers/isdn/hisax/elsa_cs.c2
-rw-r--r--drivers/isdn/hisax/elsa_ser.c3
-rw-r--r--drivers/isdn/hisax/hfc_usb.c6
-rw-r--r--drivers/isdn/hisax/ipacx.c4
-rw-r--r--drivers/isdn/hisax/jade.c3
-rw-r--r--drivers/isdn/hisax/l3dss1.c4
-rw-r--r--drivers/isdn/hisax/l3ni1.c4
-rw-r--r--drivers/isdn/hisax/st5481.h1
-rw-r--r--drivers/isdn/hisax/st5481_init.c6
-rw-r--r--drivers/isdn/hisax/teles_cs.c2
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c11
-rw-r--r--drivers/isdn/i4l/isdn_common.c11
-rw-r--r--drivers/isdn/i4l/isdn_net.c2
-rw-r--r--drivers/isdn/i4l/isdn_tty.c2
-rw-r--r--drivers/isdn/mISDN/layer2.c20
-rw-r--r--drivers/isdn/mISDN/socket.c3
-rw-r--r--drivers/net/3c509.c16
-rw-r--r--drivers/net/3c59x.c4
-rw-r--r--drivers/net/8139cp.c46
-rw-r--r--drivers/net/acenic.c12
-rw-r--r--drivers/net/arm/etherh.c5
-rw-r--r--drivers/net/arm/ks8695net.c7
-rw-r--r--drivers/net/atl1c/atl1c_ethtool.c17
-rw-r--r--drivers/net/atl1c/atl1c_main.c27
-rw-r--r--drivers/net/atl1e/atl1e_ethtool.c7
-rw-r--r--drivers/net/atl1e/atl1e_main.c14
-rw-r--r--drivers/net/atlx/atl1.c29
-rw-r--r--drivers/net/atlx/atl2.c18
-rw-r--r--drivers/net/b44.c13
-rw-r--r--drivers/net/bcm63xx_enet.c7
-rw-r--r--drivers/net/benet/be.h74
-rw-r--r--drivers/net/benet/be_cmds.c341
-rw-r--r--drivers/net/benet/be_cmds.h457
-rw-r--r--drivers/net/benet/be_ethtool.c227
-rw-r--r--drivers/net/benet/be_hw.h4
-rw-r--r--drivers/net/benet/be_main.c637
-rw-r--r--drivers/net/bna/bfa_ioc.c13
-rw-r--r--drivers/net/bna/bna_ctrl.c21
-rw-r--r--drivers/net/bna/bna_txrx.c7
-rw-r--r--drivers/net/bna/bnad.c22
-rw-r--r--drivers/net/bna/bnad.h2
-rw-r--r--drivers/net/bna/bnad_ethtool.c70
-rw-r--r--drivers/net/bnx2.c184
-rw-r--r--drivers/net/bnx2.h3
-rw-r--r--drivers/net/bnx2x/bnx2x.h35
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.c643
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.h454
-rw-r--r--drivers/net/bnx2x/bnx2x_dcb.c202
-rw-r--r--drivers/net/bnx2x/bnx2x_dcb.h16
-rw-r--r--drivers/net/bnx2x/bnx2x_ethtool.c167
-rw-r--r--drivers/net/bnx2x/bnx2x_fw_defs.h2
-rw-r--r--drivers/net/bnx2x/bnx2x_fw_file_hdr.h2
-rw-r--r--drivers/net/bnx2x/bnx2x_hsi.h4
-rw-r--r--drivers/net/bnx2x/bnx2x_init.h2
-rw-r--r--drivers/net/bnx2x/bnx2x_init_ops.h2
-rw-r--r--drivers/net/bnx2x/bnx2x_link.c14
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c360
-rw-r--r--drivers/net/bnx2x/bnx2x_reg.h2
-rw-r--r--drivers/net/bnx2x/bnx2x_stats.c2
-rw-r--r--drivers/net/bnx2x/bnx2x_stats.h2
-rw-r--r--drivers/net/bonding/Makefile3
-rw-r--r--drivers/net/bonding/bond_3ad.c43
-rw-r--r--drivers/net/bonding/bond_3ad.h4
-rw-r--r--drivers/net/bonding/bond_alb.c57
-rw-r--r--drivers/net/bonding/bond_alb.h1
-rw-r--r--drivers/net/bonding/bond_main.c530
-rw-r--r--drivers/net/bonding/bond_procfs.c2
-rw-r--r--drivers/net/bonding/bond_sysfs.c84
-rw-r--r--drivers/net/bonding/bonding.h56
-rw-r--r--drivers/net/cassini.c37
-rw-r--r--drivers/net/chelsio/common.h5
-rw-r--r--drivers/net/chelsio/cxgb2.c59
-rw-r--r--drivers/net/chelsio/sge.c13
-rw-r--r--drivers/net/chelsio/tp.c5
-rw-r--r--drivers/net/chelsio/tp.h1
-rw-r--r--drivers/net/cnic.c62
-rw-r--r--drivers/net/cnic.h1
-rw-r--r--drivers/net/cnic_if.h6
-rw-r--r--drivers/net/cris/eth_v10.c4
-rw-r--r--drivers/net/cxgb3/adapter.h7
-rw-r--r--drivers/net/cxgb3/common.h1
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c117
-rw-r--r--drivers/net/cxgb3/sge.c7
-rw-r--r--drivers/net/cxgb4/cxgb4.h6
-rw-r--r--drivers/net/cxgb4/cxgb4_main.c103
-rw-r--r--drivers/net/cxgb4/sge.c4
-rw-r--r--drivers/net/cxgb4vf/adapter.h6
-rw-r--r--drivers/net/cxgb4vf/cxgb4vf_main.c73
-rw-r--r--drivers/net/cxgb4vf/sge.c4
-rw-r--r--drivers/net/depca.c35
-rw-r--r--drivers/net/dl2k.c29
-rw-r--r--drivers/net/dm9000.c57
-rw-r--r--drivers/net/dummy.c4
-rw-r--r--drivers/net/e100.c78
-rw-r--r--drivers/net/e1000/e1000.h5
-rw-r--r--drivers/net/e1000/e1000_ethtool.c60
-rw-r--r--drivers/net/e1000/e1000_main.c42
-rw-r--r--drivers/net/e1000e/82571.c22
-rw-r--r--drivers/net/e1000e/e1000.h12
-rw-r--r--drivers/net/e1000e/es2lan.c5
-rw-r--r--drivers/net/e1000e/ethtool.c154
-rw-r--r--drivers/net/e1000e/hw.h1
-rw-r--r--drivers/net/e1000e/ich8lan.c16
-rw-r--r--drivers/net/e1000e/lib.c18
-rw-r--r--drivers/net/e1000e/netdev.c213
-rw-r--r--drivers/net/e1000e/phy.c4
-rw-r--r--drivers/net/eepro.c2
-rw-r--r--drivers/net/ehea/ehea_ethtool.c46
-rw-r--r--drivers/net/ehea/ehea_main.c4
-rw-r--r--drivers/net/enc28j60.c5
-rw-r--r--drivers/net/enic/Makefile2
-rw-r--r--drivers/net/enic/enic.h5
-rw-r--r--drivers/net/enic/enic_dev.c62
-rw-r--r--drivers/net/enic/enic_dev.h7
-rw-r--r--drivers/net/enic/enic_main.c274
-rw-r--r--drivers/net/enic/enic_pp.c264
-rw-r--r--drivers/net/enic/enic_pp.h27
-rw-r--r--drivers/net/enic/enic_res.c4
-rw-r--r--drivers/net/enic/vnic_dev.c97
-rw-r--r--drivers/net/enic/vnic_dev.h6
-rw-r--r--drivers/net/enic/vnic_devcmd.h57
-rw-r--r--drivers/net/enic/vnic_vic.c5
-rw-r--r--drivers/net/enic/vnic_vic.h13
-rw-r--r--drivers/net/ewrk3.c58
-rw-r--r--drivers/net/forcedeth.c113
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c2
-rw-r--r--drivers/net/gianfar.c16
-rw-r--r--drivers/net/gianfar.h20
-rw-r--r--drivers/net/gianfar_ethtool.c110
-rw-r--r--drivers/net/greth.c46
-rw-r--r--drivers/net/greth.h4
-rw-r--r--drivers/net/hamachi.c78
-rw-r--r--drivers/net/hamradio/bpqether.c4
-rw-r--r--drivers/net/hp100.c12
-rw-r--r--drivers/net/ibm_newemac/core.c17
-rw-r--r--drivers/net/ibmlana.c7
-rw-r--r--drivers/net/ibmveth.c98
-rw-r--r--drivers/net/ifb.c4
-rw-r--r--drivers/net/igb/e1000_82575.c11
-rw-r--r--drivers/net/igb/igb.h2
-rw-r--r--drivers/net/igb/igb_ethtool.c48
-rw-r--r--drivers/net/igb/igb_main.c90
-rw-r--r--drivers/net/igbvf/ethtool.c14
-rw-r--r--drivers/net/ioc3-eth.c30
-rw-r--r--drivers/net/irda/smsc-ircc2.c44
-rw-r--r--drivers/net/ixgb/ixgb.h3
-rw-r--r--drivers/net/ixgb/ixgb_ethtool.c53
-rw-r--r--drivers/net/ixgbe/ixgbe.h111
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c61
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c178
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c532
-rw-r--r--drivers/net/ixgbe/ixgbe_common.h12
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82598.c2
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.c77
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.h2
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_nl.c109
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c191
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.c4
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c1037
-rw-r--r--drivers/net/ixgbe/ixgbe_mbx.h4
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.c20
-rw-r--r--drivers/net/ixgbe/ixgbe_sriov.c100
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h218
-rw-r--r--drivers/net/ixgbe/ixgbe_x540.c317
-rw-r--r--drivers/net/ixgbevf/ethtool.c8
-rw-r--r--drivers/net/ixgbevf/ixgbevf_main.c30
-rw-r--r--drivers/net/ixgbevf/mbx.h1
-rw-r--r--drivers/net/ixgbevf/vf.c34
-rw-r--r--drivers/net/ixgbevf/vf.h1
-rw-r--r--drivers/net/jme.c80
-rw-r--r--drivers/net/jme.h2
-rw-r--r--drivers/net/ksz884x.c82
-rw-r--r--drivers/net/loopback.c3
-rw-r--r--drivers/net/macb.c11
-rw-r--r--drivers/net/macvlan.c34
-rw-r--r--drivers/net/mdio.c23
-rw-r--r--drivers/net/mii.c31
-rw-r--r--drivers/net/mlx4/en_ethtool.c49
-rw-r--r--drivers/net/mlx4/en_netdev.c26
-rw-r--r--drivers/net/mlx4/en_rx.c2
-rw-r--r--drivers/net/mlx4/mlx4_en.h1
-rw-r--r--drivers/net/mv643xx_eth.c34
-rw-r--r--drivers/net/myri10ge/myri10ge.c68
-rw-r--r--drivers/net/natsemi.c11
-rw-r--r--drivers/net/ne3210.c15
-rw-r--r--drivers/net/netconsole.c82
-rw-r--r--drivers/net/netxen/netxen_nic.h2
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c117
-rw-r--r--drivers/net/netxen/netxen_nic_init.c3
-rw-r--r--drivers/net/netxen/netxen_nic_main.c55
-rw-r--r--drivers/net/niu.c63
-rw-r--r--drivers/net/niu.h1
-rw-r--r--drivers/net/ns83820.c8
-rw-r--r--drivers/net/pch_gbe/pch_gbe.h4
-rw-r--r--drivers/net/pch_gbe/pch_gbe_ethtool.c65
-rw-r--r--drivers/net/pch_gbe/pch_gbe_main.c48
-rw-r--r--drivers/net/pch_gbe/pch_gbe_param.c16
-rw-r--r--drivers/net/pch_gbe/pch_gbe_phy.c4
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c6
-rw-r--r--drivers/net/pcnet32.c90
-rw-r--r--drivers/net/phy/phy.c12
-rw-r--r--drivers/net/pptp.c10
-rw-r--r--drivers/net/ps3_gelic_net.c34
-rw-r--r--drivers/net/ps3_gelic_net.h3
-rw-r--r--drivers/net/ps3_gelic_wireless.c4
-rw-r--r--drivers/net/qla3xxx.c4
-rw-r--r--drivers/net/qlcnic/qlcnic.h416
-rw-r--r--drivers/net/qlcnic/qlcnic_ctx.c250
-rw-r--r--drivers/net/qlcnic/qlcnic_ethtool.c417
-rw-r--r--drivers/net/qlcnic/qlcnic_hdr.h40
-rw-r--r--drivers/net/qlcnic/qlcnic_hw.c578
-rw-r--r--drivers/net/qlcnic/qlcnic_init.c66
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c634
-rw-r--r--drivers/net/qlge/qlge.h2
-rw-r--r--drivers/net/qlge/qlge_ethtool.c74
-rw-r--r--drivers/net/qlge/qlge_main.c25
-rw-r--r--drivers/net/r8169.c1006
-rw-r--r--drivers/net/s2io.c197
-rw-r--r--drivers/net/s2io.h13
-rw-r--r--drivers/net/sc92031.c8
-rw-r--r--drivers/net/sfc/efx.c49
-rw-r--r--drivers/net/sfc/efx.h2
-rw-r--r--drivers/net/sfc/ethtool.c118
-rw-r--r--drivers/net/sfc/falcon.c4
-rw-r--r--drivers/net/sfc/falcon_xmac.c2
-rw-r--r--drivers/net/sfc/mac.h4
-rw-r--r--drivers/net/sfc/mcdi_mac.c2
-rw-r--r--drivers/net/sfc/mcdi_phy.c8
-rw-r--r--drivers/net/sfc/mdio_10g.c6
-rw-r--r--drivers/net/sfc/mdio_10g.h2
-rw-r--r--drivers/net/sfc/net_driver.h24
-rw-r--r--drivers/net/sfc/nic.c6
-rw-r--r--drivers/net/sfc/nic.h6
-rw-r--r--drivers/net/sfc/phy.h8
-rw-r--r--drivers/net/sfc/qt202x_phy.c2
-rw-r--r--drivers/net/sfc/rx.c3
-rw-r--r--drivers/net/sfc/selftest.c11
-rw-r--r--drivers/net/sfc/siena.c2
-rw-r--r--drivers/net/sfc/tenxpress.c4
-rw-r--r--drivers/net/sfc/tx.c9
-rw-r--r--drivers/net/sfc/txc43128_phy.c2
-rw-r--r--drivers/net/skge.c93
-rw-r--r--drivers/net/skge.h1
-rw-r--r--drivers/net/sky2.c195
-rw-r--r--drivers/net/sky2.h1
-rw-r--r--drivers/net/smc-mca.c6
-rw-r--r--drivers/net/smc911x.c4
-rw-r--r--drivers/net/smc91x.c4
-rw-r--r--drivers/net/smsc911x.c448
-rw-r--r--drivers/net/smsc911x.h22
-rw-r--r--drivers/net/spider_net.c15
-rw-r--r--drivers/net/spider_net.h7
-rw-r--r--drivers/net/spider_net_ethtool.c23
-rw-r--r--drivers/net/stmmac/dwmac1000_core.c5
-rw-r--r--drivers/net/stmmac/stmmac.h1
-rw-r--r--drivers/net/stmmac/stmmac_ethtool.c33
-rw-r--r--drivers/net/stmmac/stmmac_main.c86
-rw-r--r--drivers/net/sungem.c18
-rw-r--r--drivers/net/sunhme.c25
-rw-r--r--drivers/net/tehuti.c28
-rw-r--r--drivers/net/tg3.c3565
-rw-r--r--drivers/net/tg3.h281
-rw-r--r--drivers/net/tile/tilepro.c2
-rw-r--r--drivers/net/tokenring/madgemc.c2
-rw-r--r--drivers/net/tokenring/olympic.c57
-rw-r--r--drivers/net/tulip/21142.c14
-rw-r--r--drivers/net/tulip/Makefile2
-rw-r--r--drivers/net/tulip/de2104x.c183
-rw-r--r--drivers/net/tulip/de4x5.c4
-rw-r--r--drivers/net/tulip/dmfe.c9
-rw-r--r--drivers/net/tulip/eeprom.c4
-rw-r--r--drivers/net/tulip/interrupt.c48
-rw-r--r--drivers/net/tulip/media.c49
-rw-r--r--drivers/net/tulip/pnic.c22
-rw-r--r--drivers/net/tulip/pnic2.c16
-rw-r--r--drivers/net/tulip/timer.c47
-rw-r--r--drivers/net/tulip/tulip.h8
-rw-r--r--drivers/net/tulip/tulip_core.c50
-rw-r--r--drivers/net/tulip/uli526x.c71
-rw-r--r--drivers/net/tulip/winbond-840.c81
-rw-r--r--drivers/net/tulip/xircom_cb.c268
-rw-r--r--drivers/net/tun.c69
-rw-r--r--drivers/net/typhoon.c58
-rw-r--r--drivers/net/ucc_geth_ethtool.c1
-rw-r--r--drivers/net/usb/Kconfig2
-rw-r--r--drivers/net/usb/asix.c28
-rw-r--r--drivers/net/usb/catc.c2
-rw-r--r--drivers/net/usb/cdc_ncm.c13
-rw-r--r--drivers/net/usb/dm9601.c6
-rw-r--r--drivers/net/usb/plusb.c32
-rw-r--r--drivers/net/usb/rndis_host.c39
-rw-r--r--drivers/net/usb/rtl8150.c11
-rw-r--r--drivers/net/usb/smsc75xx.c131
-rw-r--r--drivers/net/usb/smsc95xx.c90
-rw-r--r--drivers/net/usb/usbnet.c6
-rw-r--r--drivers/net/veth.c48
-rw-r--r--drivers/net/via-rhine.c242
-rw-r--r--drivers/net/via-velocity.c28
-rw-r--r--drivers/net/virtio_net.c46
-rw-r--r--drivers/net/vmxnet3/vmxnet3_drv.c43
-rw-r--r--drivers/net/vmxnet3/vmxnet3_ethtool.c73
-rw-r--r--drivers/net/vmxnet3/vmxnet3_int.h11
-rw-r--r--drivers/net/vxge/vxge-config.c48
-rw-r--r--drivers/net/vxge/vxge-config.h70
-rw-r--r--drivers/net/vxge/vxge-ethtool.c104
-rw-r--r--drivers/net/vxge/vxge-main.c143
-rw-r--r--drivers/net/vxge/vxge-main.h14
-rw-r--r--drivers/net/vxge/vxge-traffic.h2
-rw-r--r--drivers/net/vxge/vxge-version.h4
-rw-r--r--drivers/net/wan/dlci.c4
-rw-r--r--drivers/net/wan/hdlc_fr.c9
-rw-r--r--drivers/net/wan/lapbether.c4
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile2
-rw-r--r--drivers/net/wireless/ath/Kconfig1
-rw-r--r--drivers/net/wireless/ath/Makefile1
-rw-r--r--drivers/net/wireless/ath/ar9170/Kconfig20
-rw-r--r--drivers/net/wireless/ath/ar9170/Makefile3
-rw-r--r--drivers/net/wireless/ath/ar9170/ar9170.h258
-rw-r--r--drivers/net/wireless/ath/ar9170/cmd.c127
-rw-r--r--drivers/net/wireless/ath/ar9170/cmd.h92
-rw-r--r--drivers/net/wireless/ath/ar9170/eeprom.h179
-rw-r--r--drivers/net/wireless/ath/ar9170/hw.h430
-rw-r--r--drivers/net/wireless/ath/ar9170/led.c181
-rw-r--r--drivers/net/wireless/ath/ar9170/mac.c519
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c2190
-rw-r--r--drivers/net/wireless/ath/ar9170/phy.c1719
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c1008
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.h82
-rw-r--r--drivers/net/wireless/ath/ath.h10
-rw-r--r--drivers/net/wireless/ath/ath5k/ahb.c28
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h31
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c7
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c73
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h7
-rw-r--r--drivers/net/wireless/ath/ath5k/caps.c3
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c65
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h17
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.c158
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c158
-rw-r--r--drivers/net/wireless/ath/ath5k/mac80211-ops.c9
-rw-r--r--drivers/net/wireless/ath/ath5k/pci.c32
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c35
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig21
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile6
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c18
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c45
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_calib.c43
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c34
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c44
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h178
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c387
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c125
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c189
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c35
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c99
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h47
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9340_initvals.h1525
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9485_initvals.h935
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h31
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c238
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c100
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h20
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c21
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c33
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c139
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h11
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c26
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c34
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c33
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c334
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h296
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c333
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_debug.c960
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_gpio.c216
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c165
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c415
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c778
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c50
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.h25
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h17
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c384
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h103
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c55
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c135
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c328
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h18
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c228
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h135
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c126
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.h82
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c174
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h2
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c94
-rw-r--r--drivers/net/wireless/ath/carl9170/tx.c164
-rw-r--r--drivers/net/wireless/ath/key.c38
-rw-r--r--drivers/net/wireless/ath/regd.c8
-rw-r--r--drivers/net/wireless/ath/regd_common.h2
-rw-r--r--drivers/net/wireless/b43/main.c69
-rw-r--r--drivers/net/wireless/b43/main.h1
-rw-r--r--drivers/net/wireless/b43/phy_n.c20
-rw-r--r--drivers/net/wireless/b43legacy/main.c52
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c7
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-4965-lib.c3
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-4965-rs.c3
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-core.c20
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-core.h1
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-dev.h4
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-hcmd.c4
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-helpers.h6
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-tx.c52
-rw-r--r--drivers/net/wireless/iwlegacy/iwl3945-base.c22
-rw-r--r--drivers/net/wireless/iwlegacy/iwl4965-base.c47
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig10
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c61
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c170
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c103
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c139
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c47
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c1073
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h70
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c45
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c59
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ict.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-led.c73
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c169
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c31
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h31
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c274
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tt.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tt.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c247
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c346
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c1223
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h113
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h812
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c270
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h121
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h43
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c1074
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h349
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c106
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h195
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h42
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c25
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h39
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c294
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h498
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c52
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h358
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c375
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.h92
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sv-open.c469
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-testmode.h151
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c116
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c3
-rw-r--r--drivers/net/wireless/libertas/cfg.c61
-rw-r--r--drivers/net/wireless/libertas/cmd.c285
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c46
-rw-r--r--drivers/net/wireless/libertas/debugfs.c41
-rw-r--r--drivers/net/wireless/libertas/decl.h8
-rw-r--r--drivers/net/wireless/libertas/defs.h120
-rw-r--r--drivers/net/wireless/libertas/dev.h20
-rw-r--r--drivers/net/wireless/libertas/ethtool.c3
-rw-r--r--drivers/net/wireless/libertas/host.h33
-rw-r--r--drivers/net/wireless/libertas/if_cs.c92
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c37
-rw-r--r--drivers/net/wireless/libertas/if_spi.c282
-rw-r--r--drivers/net/wireless/libertas/if_spi.h68
-rw-r--r--drivers/net/wireless/libertas/if_usb.c157
-rw-r--r--drivers/net/wireless/libertas/if_usb.h14
-rw-r--r--drivers/net/wireless/libertas/main.c171
-rw-r--r--drivers/net/wireless/libertas/mesh.c218
-rw-r--r--drivers/net/wireless/libertas/mesh.h6
-rw-r--r--drivers/net/wireless/libertas/rx.c41
-rw-r--r--drivers/net/wireless/libertas/tx.c34
-rw-r--r--drivers/net/wireless/libertas/types.h18
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c11
-rw-r--r--drivers/net/wireless/mwifiex/11n.c744
-rw-r--r--drivers/net/wireless/mwifiex/11n.h161
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c298
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.h32
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c616
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.h65
-rw-r--r--drivers/net/wireless/mwifiex/Kconfig21
-rw-r--r--drivers/net/wireless/mwifiex/Makefile41
-rw-r--r--drivers/net/wireless/mwifiex/README204
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c1417
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.h31
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c360
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c1414
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c770
-rw-r--r--drivers/net/wireless/mwifiex/decl.h129
-rw-r--r--drivers/net/wireless/mwifiex/fw.h1187
-rw-r--r--drivers/net/wireless/mwifiex/init.c645
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h331
-rw-r--r--drivers/net/wireless/mwifiex/join.c1423
-rw-r--r--drivers/net/wireless/mwifiex/main.c1055
-rw-r--r--drivers/net/wireless/mwifiex/main.h1004
-rw-r--r--drivers/net/wireless/mwifiex/scan.c3025
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c1754
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h305
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c1219
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c972
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c406
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c1593
-rw-r--r--drivers/net/wireless/mwifiex/sta_rx.c200
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c198
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c200
-rw-r--r--drivers/net/wireless/mwifiex/util.c202
-rw-r--r--drivers/net/wireless/mwifiex/util.h32
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c1231
-rw-r--r--drivers/net/wireless/mwifiex/wmm.h110
-rw-r--r--drivers/net/wireless/mwl8k.c875
-rw-r--r--drivers/net/wireless/p54/eeprom.c2
-rw-r--r--drivers/net/wireless/p54/fwio.c31
-rw-r--r--drivers/net/wireless/p54/lmac.h1
-rw-r--r--drivers/net/wireless/p54/main.c31
-rw-r--r--drivers/net/wireless/p54/p54.h2
-rw-r--r--drivers/net/wireless/p54/p54pci.c3
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig37
-rw-r--r--drivers/net/wireless/rt2x00/Makefile1
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c35
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c34
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c91
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h108
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c369
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c267
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c632
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h122
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c108
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c43
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c139
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00firmware.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00ht.c133
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h57
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c61
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c95
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c19
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h17
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c177
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h34
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c129
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h33
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c70
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c192
-rw-r--r--drivers/net/wireless/rtlwifi/Kconfig15
-rw-r--r--drivers/net/wireless/rtlwifi/Makefile1
-rw-r--r--drivers/net/wireless/rtlwifi/base.c733
-rw-r--r--drivers/net/wireless/rtlwifi/base.h60
-rw-r--r--drivers/net/wireless/rtlwifi/cam.c106
-rw-r--r--drivers/net/wireless/rtlwifi/cam.h5
-rw-r--r--drivers/net/wireless/rtlwifi/core.c416
-rw-r--r--drivers/net/wireless/rtlwifi/core.h1
-rw-r--r--drivers/net/wireless/rtlwifi/efuse.c234
-rw-r--r--drivers/net/wireless/rtlwifi/efuse.h5
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c609
-rw-r--r--drivers/net/wireless/rtlwifi/pci.h19
-rw-r--r--drivers/net/wireless/rtlwifi/ps.c261
-rw-r--r--drivers/net/wireless/rtlwifi/ps.h9
-rw-r--r--drivers/net/wireless/rtlwifi/rc.c212
-rw-r--r--drivers/net/wireless/rtlwifi/rc.h9
-rw-r--r--drivers/net/wireless/rtlwifi/regd.c97
-rw-r--r--drivers/net/wireless/rtlwifi/regd.h2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c525
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c115
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c128
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h76
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/def.h27
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/dm.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/dm.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.c509
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.h34
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/led.c19
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/led.h3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/phy.c223
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/phy.h55
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/reg.h58
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rf.c28
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rf.h17
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.c123
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.h14
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.c180
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.h11
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c13
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.h5
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/phy.c14
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/phy.h14
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/rf.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/rf.h4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/trx.c50
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/trx.h5
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/Makefile15
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/def.h598
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/dm.c733
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/dm.h164
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/fw.c654
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/fw.h375
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.c2512
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.h79
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/led.c149
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/led.h37
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/phy.c1740
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/phy.h101
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/reg.h1188
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/rf.c546
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/rf.h43
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/sw.c423
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/sw.h (renamed from drivers/net/wireless/iwlwifi/iwl-agn-led.h)19
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/table.c634
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/table.h49
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.c976
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.h45
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c19
-rw-r--r--drivers/net/wireless/rtlwifi/usb.h2
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h173
-rw-r--r--drivers/net/wireless/wl1251/cmd.h4
-rw-r--r--drivers/net/wireless/wl1251/event.c6
-rw-r--r--drivers/net/wireless/wl1251/main.c22
-rw-r--r--drivers/net/wireless/wl1251/ps.c23
-rw-r--r--drivers/net/wireless/wl1251/ps.h2
-rw-r--r--drivers/net/wireless/wl1251/wl1251.h9
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig2
-rw-r--r--drivers/net/wireless/wl12xx/acx.c201
-rw-r--r--drivers/net/wireless/wl12xx/acx.h102
-rw-r--r--drivers/net/wireless/wl12xx/boot.c283
-rw-r--r--drivers/net/wireless/wl12xx/boot.h52
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c113
-rw-r--r--drivers/net/wireless/wl12xx/cmd.h34
-rw-r--r--drivers/net/wireless/wl12xx/conf.h116
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c242
-rw-r--r--drivers/net/wireless/wl12xx/event.c34
-rw-r--r--drivers/net/wireless/wl12xx/event.h5
-rw-r--r--drivers/net/wireless/wl12xx/ini.h98
-rw-r--r--drivers/net/wireless/wl12xx/init.c149
-rw-r--r--drivers/net/wireless/wl12xx/init.h3
-rw-r--r--drivers/net/wireless/wl12xx/io.c11
-rw-r--r--drivers/net/wireless/wl12xx/io.h3
-rw-r--r--drivers/net/wireless/wl12xx/main.c827
-rw-r--r--drivers/net/wireless/wl12xx/ps.c33
-rw-r--r--drivers/net/wireless/wl12xx/ps.h2
-rw-r--r--drivers/net/wireless/wl12xx/reg.h15
-rw-r--r--drivers/net/wireless/wl12xx/rx.c80
-rw-r--r--drivers/net/wireless/wl12xx/scan.c260
-rw-r--r--drivers/net/wireless/wl12xx/scan.h114
-rw-r--r--drivers/net/wireless/wl12xx/sdio.c95
-rw-r--r--drivers/net/wireless/wl12xx/sdio_test.c20
-rw-r--r--drivers/net/wireless/wl12xx/spi.c17
-rw-r--r--drivers/net/wireless/wl12xx/testmode.c6
-rw-r--r--drivers/net/wireless/wl12xx/tx.c245
-rw-r--r--drivers/net/wireless/wl12xx/tx.h62
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h78
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c262
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h533
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.h2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al2230.c198
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al7230b.c240
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_rf2959.c78
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_uw2453.c86
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c4
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.h2
-rw-r--r--drivers/net/xen-netback/common.h7
-rw-r--r--drivers/net/xen-netback/interface.c84
-rw-r--r--drivers/net/xen-netback/xenbus.c2
-rw-r--r--drivers/net/xen-netfront.c106
-rw-r--r--drivers/s390/net/claw.c22
-rw-r--r--drivers/s390/net/ctcm_main.c2
-rw-r--r--drivers/s390/net/ctcm_mpc.c13
-rw-r--r--drivers/s390/net/lcs.c10
-rw-r--r--drivers/s390/net/netiucv.c2
-rw-r--r--drivers/s390/net/qeth_core.h26
-rw-r--r--drivers/s390/net/qeth_core_main.c150
-rw-r--r--drivers/s390/net/qeth_core_mpc.h17
-rw-r--r--drivers/s390/net/qeth_core_sys.c61
-rw-r--r--drivers/s390/net/qeth_l2_main.c21
-rw-r--r--drivers/s390/net/qeth_l3.h2
-rw-r--r--drivers/s390/net/qeth_l3_main.c261
-rw-r--r--drivers/s390/net/qeth_l3_sys.c103
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_fcoe.c11
-rw-r--r--drivers/scsi/cxgbi/libcxgbi.c10
-rw-r--r--drivers/scsi/fcoe/fcoe.c11
-rw-r--r--drivers/ssb/driver_chipcommon.c68
-rw-r--r--drivers/ssb/driver_chipcommon_pmu.c2
-rw-r--r--drivers/ssb/driver_pcicore.c255
-rw-r--r--drivers/ssb/main.c54
-rw-r--r--drivers/ssb/scan.c7
-rw-r--r--drivers/staging/hv/netvsc_drv.c3
-rw-r--r--firmware/Makefile6
-rw-r--r--firmware/WHENCE9
-rw-r--r--firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex9483
-rw-r--r--firmware/bnx2x/bnx2x-e1-6.2.9.0.fw.ihex9484
-rw-r--r--firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex13181
-rw-r--r--firmware/bnx2x/bnx2x-e1h-6.2.9.0.fw.ihex13192
-rw-r--r--firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex15456
-rw-r--r--firmware/bnx2x/bnx2x-e2-6.2.9.0.fw.ihex15473
-rw-r--r--include/linux/ath9k_platform.h7
-rw-r--r--include/linux/bcma/bcma.h224
-rw-r--r--include/linux/bcma/bcma_driver_chipcommon.h302
-rw-r--r--include/linux/bcma/bcma_driver_pci.h89
-rw-r--r--include/linux/bcma/bcma_regs.h34
-rw-r--r--include/linux/can/core.h4
-rw-r--r--include/linux/ethtool.h317
-rw-r--r--include/linux/filter.h76
-rw-r--r--include/linux/ieee80211.h20
-rw-r--r--include/linux/if_ether.h1
-rw-r--r--include/linux/if_vlan.h11
-rw-r--r--include/linux/mod_devicetable.h17
-rw-r--r--include/linux/mroute.h1
-rw-r--r--include/linux/net.h1
-rw-r--r--include/linux/netdevice.h46
-rw-r--r--include/linux/netfilter/ipset/ip_set_getport.h2
-rw-r--r--include/linux/netfilter/x_tables.h96
-rw-r--r--include/linux/nl80211.h371
-rw-r--r--include/linux/pkt_sched.h15
-rw-r--r--include/linux/rfkill-regulator.h48
-rw-r--r--include/linux/skbuff.h2
-rw-r--r--include/linux/smsc911x.h1
-rw-r--r--include/linux/socket.h2
-rw-r--r--include/linux/ssb/ssb.h3
-rw-r--r--include/linux/ssb/ssb_driver_chipcommon.h11
-rw-r--r--include/linux/ssb/ssb_regs.h2
-rw-r--r--include/linux/stmmac.h2
-rw-r--r--include/linux/syscalls.h2
-rw-r--r--include/linux/tipc.h2
-rw-r--r--include/linux/usb/rndis_host.h2
-rw-r--r--include/linux/wl12xx.h29
-rw-r--r--include/net/addrconf.h25
-rw-r--r--include/net/af_rxrpc.h3
-rw-r--r--include/net/af_unix.h2
-rw-r--r--include/net/atmclip.h2
-rw-r--r--include/net/bluetooth/hci.h51
-rw-r--r--include/net/bluetooth/hci_core.h42
-rw-r--r--include/net/bluetooth/l2cap.h182
-rw-r--r--include/net/bluetooth/mgmt.h57
-rw-r--r--include/net/caif/caif_dev.h50
-rw-r--r--include/net/caif/cfcnfg.h71
-rw-r--r--include/net/caif/cfctrl.h15
-rw-r--r--include/net/caif/cffrml.h7
-rw-r--r--include/net/caif/cfmuxl.h2
-rw-r--r--include/net/caif/cfpkt.h76
-rw-r--r--include/net/caif/cfsrvl.h32
-rw-r--r--include/net/cfg80211.h311
-rw-r--r--include/net/compat.h2
-rw-r--r--include/net/dst.h13
-rw-r--r--include/net/flow.h25
-rw-r--r--include/net/garp.h2
-rw-r--r--include/net/if_inet6.h11
-rw-r--r--include/net/inet6_connection_sock.h2
-rw-r--r--include/net/inet_connection_sock.h6
-rw-r--r--include/net/inet_sock.h26
-rw-r--r--include/net/inetpeer.h2
-rw-r--r--include/net/ip.h29
-rw-r--r--include/net/ip6_fib.h13
-rw-r--r--include/net/ip6_route.h26
-rw-r--r--include/net/ip_fib.h9
-rw-r--r--include/net/ip_vs.h14
-rw-r--r--include/net/ipv6.h30
-rw-r--r--include/net/ipx.h2
-rw-r--r--include/net/mac80211.h99
-rw-r--r--include/net/ndisc.h9
-rw-r--r--include/net/netevent.h2
-rw-r--r--include/net/netfilter/nf_conntrack.h2
-rw-r--r--include/net/netfilter/nf_conntrack_tuple.h4
-rw-r--r--include/net/netfilter/nf_nat.h4
-rw-r--r--include/net/netns/ipv4.h2
-rw-r--r--include/net/phonet/pn_dev.h2
-rw-r--r--include/net/ping.h55
-rw-r--r--include/net/rawv6.h4
-rw-r--r--include/net/route.h163
-rw-r--r--include/net/sctp/command.h1
-rw-r--r--include/net/sctp/constants.h18
-rw-r--r--include/net/sctp/sctp.h2
-rw-r--r--include/net/sctp/sm.h5
-rw-r--r--include/net/sctp/structs.h21
-rw-r--r--include/net/sctp/ulpevent.h3
-rw-r--r--include/net/sctp/user.h33
-rw-r--r--include/net/snmp.h14
-rw-r--r--include/net/sock.h54
-rw-r--r--include/net/transp_v6.h4
-rw-r--r--include/net/wimax.h5
-rw-r--r--include/net/xfrm.h15
-rw-r--r--include/rdma/ib_addr.h13
-rw-r--r--kernel/sys_ni.c2
-rw-r--r--net/802/garp.c22
-rw-r--r--net/8021q/vlan.c38
-rw-r--r--net/8021q/vlan.h2
-rw-r--r--net/8021q/vlan_core.c85
-rw-r--r--net/8021q/vlan_dev.c225
-rw-r--r--net/9p/client.c9
-rw-r--r--net/9p/trans_fd.c2
-rw-r--r--net/9p/trans_rdma.c2
-rw-r--r--net/Kconfig14
-rw-r--r--net/atm/lec.c4
-rw-r--r--net/ax25/af_ax25.c16
-rw-r--r--net/ax25/ax25_iface.c3
-rw-r--r--net/batman-adv/aggregation.c31
-rw-r--r--net/batman-adv/aggregation.h4
-rw-r--r--net/batman-adv/bat_debugfs.c4
-rw-r--r--net/batman-adv/bat_sysfs.c16
-rw-r--r--net/batman-adv/gateway_client.c296
-rw-r--r--net/batman-adv/gateway_client.h2
-rw-r--r--net/batman-adv/hard-interface.c107
-rw-r--r--net/batman-adv/hard-interface.h18
-rw-r--r--net/batman-adv/icmp_socket.c37
-rw-r--r--net/batman-adv/main.c20
-rw-r--r--net/batman-adv/main.h44
-rw-r--r--net/batman-adv/originator.c82
-rw-r--r--net/batman-adv/originator.h1
-rw-r--r--net/batman-adv/packet.h5
-rw-r--r--net/batman-adv/routing.c572
-rw-r--r--net/batman-adv/routing.h6
-rw-r--r--net/batman-adv/send.c72
-rw-r--r--net/batman-adv/send.h2
-rw-r--r--net/batman-adv/soft-interface.c463
-rw-r--r--net/batman-adv/translation-table.c474
-rw-r--r--net/batman-adv/translation-table.h24
-rw-r--r--net/batman-adv/types.h56
-rw-r--r--net/batman-adv/unicast.c20
-rw-r--r--net/batman-adv/vis.c146
-rw-r--r--net/bluetooth/bnep/bnep.h148
-rw-r--r--net/bluetooth/bnep/core.c71
-rw-r--r--net/bluetooth/bnep/sock.c2
-rw-r--r--net/bluetooth/cmtp/capi.c6
-rw-r--r--net/bluetooth/cmtp/cmtp.h11
-rw-r--r--net/bluetooth/cmtp/core.c28
-rw-r--r--net/bluetooth/cmtp/sock.c2
-rw-r--r--net/bluetooth/hci_conn.c95
-rw-r--r--net/bluetooth/hci_core.c154
-rw-r--r--net/bluetooth/hci_event.c267
-rw-r--r--net/bluetooth/hci_sysfs.c71
-rw-r--r--net/bluetooth/hidp/core.c96
-rw-r--r--net/bluetooth/hidp/hidp.h6
-rw-r--r--net/bluetooth/hidp/sock.c7
-rw-r--r--net/bluetooth/l2cap_core.c1966
-rw-r--r--net/bluetooth/l2cap_sock.c330
-rw-r--r--net/bluetooth/mgmt.c612
-rw-r--r--net/bluetooth/rfcomm/core.c23
-rw-r--r--net/bluetooth/rfcomm/sock.c5
-rw-r--r--net/bridge/br.c1
-rw-r--r--net/bridge/br_device.c100
-rw-r--r--net/bridge/br_fdb.c311
-rw-r--r--net/bridge/br_if.c104
-rw-r--r--net/bridge/br_input.c5
-rw-r--r--net/bridge/br_ioctl.c40
-rw-r--r--net/bridge/br_multicast.c12
-rw-r--r--net/bridge/br_netfilter.c4
-rw-r--r--net/bridge/br_netlink.c60
-rw-r--r--net/bridge/br_notify.c11
-rw-r--r--net/bridge/br_private.h22
-rw-r--r--net/bridge/br_private_stp.h13
-rw-r--r--net/bridge/br_stp.c48
-rw-r--r--net/bridge/br_stp_if.c21
-rw-r--r--net/bridge/br_sysfs_br.c39
-rw-r--r--net/bridge/br_sysfs_if.c26
-rw-r--r--net/caif/Makefile2
-rw-r--r--net/caif/caif_config_util.c99
-rw-r--r--net/caif/caif_dev.c387
-rw-r--r--net/caif/caif_socket.c106
-rw-r--r--net/caif/cfcnfg.c507
-rw-r--r--net/caif/cfctrl.c196
-rw-r--r--net/caif/cfdgml.c7
-rw-r--r--net/caif/cffrml.c60
-rw-r--r--net/caif/cfmuxl.c162
-rw-r--r--net/caif/cfpkt_skbuff.c205
-rw-r--r--net/caif/cfrfml.c4
-rw-r--r--net/caif/cfserl.c7
-rw-r--r--net/caif/cfsrvl.c40
-rw-r--r--net/caif/cfutill.c7
-rw-r--r--net/caif/cfveil.c11
-rw-r--r--net/caif/cfvidl.c5
-rw-r--r--net/caif/chnl_net.c45
-rw-r--r--net/can/af_can.c67
-rw-r--r--net/can/bcm.c2
-rw-r--r--net/can/raw.c2
-rw-r--r--net/compat.c16
-rw-r--r--net/core/dev.c187
-rw-r--r--net/core/dst.c54
-rw-r--r--net/core/ethtool.c196
-rw-r--r--net/core/fib_rules.c3
-rw-r--r--net/core/filter.c65
-rw-r--r--net/core/net-sysfs.c26
-rw-r--r--net/core/net_namespace.c12
-rw-r--r--net/core/netpoll.c28
-rw-r--r--net/core/pktgen.c199
-rw-r--r--net/core/rtnetlink.c25
-rw-r--r--net/core/skbuff.c3
-rw-r--r--net/core/sysctl_net_core.c9
-rw-r--r--net/core/utils.c24
-rw-r--r--net/dccp/ipv4.c53
-rw-r--r--net/dccp/ipv6.c10
-rw-r--r--net/dccp/output.c4
-rw-r--r--net/decnet/dn_dev.c10
-rw-r--r--net/decnet/dn_route.c15
-rw-r--r--net/decnet/dn_table.c4
-rw-r--r--net/dsa/slave.c1
-rw-r--r--net/econet/af_econet.c8
-rw-r--r--net/ipv4/Makefile2
-rw-r--r--net/ipv4/af_inet.c53
-rw-r--r--net/ipv4/ah4.c7
-rw-r--r--net/ipv4/cipso_ipv4.c113
-rw-r--r--net/ipv4/datagram.c22
-rw-r--r--net/ipv4/devinet.c4
-rw-r--r--net/ipv4/esp4.c7
-rw-r--r--net/ipv4/fib_frontend.c16
-rw-r--r--net/ipv4/fib_trie.c110
-rw-r--r--net/ipv4/icmp.c133
-rw-r--r--net/ipv4/igmp.c22
-rw-r--r--net/ipv4/inet_connection_sock.c59
-rw-r--r--net/ipv4/inet_diag.c2
-rw-r--r--net/ipv4/inet_lro.c4
-rw-r--r--net/ipv4/ip_forward.c2
-rw-r--r--net/ipv4/ip_fragment.c58
-rw-r--r--net/ipv4/ip_gre.c70
-rw-r--r--net/ipv4/ip_input.c4
-rw-r--r--net/ipv4/ip_options.c57
-rw-r--r--net/ipv4/ip_output.c158
-rw-r--r--net/ipv4/ip_sockglue.c37
-rw-r--r--net/ipv4/ipcomp.c4
-rw-r--r--net/ipv4/ipconfig.c35
-rw-r--r--net/ipv4/ipip.c36
-rw-r--r--net/ipv4/ipmr.c39
-rw-r--r--net/ipv4/netfilter/arp_tables.c18
-rw-r--r--net/ipv4/netfilter/ip_tables.c28
-rw-r--r--net/ipv4/netfilter/nf_nat_helper.c2
-rw-r--r--net/ipv4/ping.c935
-rw-r--r--net/ipv4/raw.c92
-rw-r--r--net/ipv4/route.c385
-rw-r--r--net/ipv4/syncookies.c22
-rw-r--r--net/ipv4/sysctl_net_ipv4.c68
-rw-r--r--net/ipv4/tcp.c7
-rw-r--r--net/ipv4/tcp_ipv4.c98
-rw-r--r--net/ipv4/tcp_output.c2
-rw-r--r--net/ipv4/udp.c78
-rw-r--r--net/ipv4/xfrm4_policy.c38
-rw-r--r--net/ipv4/xfrm4_state.c2
-rw-r--r--net/ipv6/addrconf.c42
-rw-r--r--net/ipv6/af_inet6.c2
-rw-r--r--net/ipv6/anycast.c16
-rw-r--r--net/ipv6/esp6.c5
-rw-r--r--net/ipv6/icmp.c8
-rw-r--r--net/ipv6/inet6_connection_sock.c2
-rw-r--r--net/ipv6/ip6_fib.c20
-rw-r--r--net/ipv6/ip6_input.c6
-rw-r--r--net/ipv6/ip6_output.c50
-rw-r--r--net/ipv6/ip6_tunnel.c46
-rw-r--r--net/ipv6/ip6mr.c4
-rw-r--r--net/ipv6/ipcomp6.c5
-rw-r--r--net/ipv6/mcast.c36
-rw-r--r--net/ipv6/mip6.c8
-rw-r--r--net/ipv6/ndisc.c51
-rw-r--r--net/ipv6/netfilter.c10
-rw-r--r--net/ipv6/netfilter/ip6_tables.c21
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c3
-rw-r--r--net/ipv6/proc.c40
-rw-r--r--net/ipv6/raw.c18
-rw-r--r--net/ipv6/reassembly.c4
-rw-r--r--net/ipv6/route.c157
-rw-r--r--net/ipv6/sit.c40
-rw-r--r--net/ipv6/syncookies.c13
-rw-r--r--net/ipv6/tcp_ipv6.c50
-rw-r--r--net/ipv6/udp.c22
-rw-r--r--net/ipv6/xfrm6_mode_beet.c2
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c6
-rw-r--r--net/ipv6/xfrm6_policy.c2
-rw-r--r--net/ipv6/xfrm6_tunnel.c10
-rw-r--r--net/irda/ircomm/ircomm_core.c6
-rw-r--r--net/irda/ircomm/ircomm_lmp.c5
-rw-r--r--net/irda/ircomm/ircomm_tty.c14
-rw-r--r--net/irda/irlan/irlan_filter.c4
-rw-r--r--net/irda/irlan/irlan_provider.c3
-rw-r--r--net/irda/irlap_event.c3
-rw-r--r--net/irda/irproc.c5
-rw-r--r--net/iucv/af_iucv.c9
-rw-r--r--net/iucv/iucv.c77
-rw-r--r--net/key/af_key.c2
-rw-r--r--net/l2tp/l2tp_core.c28
-rw-r--r--net/l2tp/l2tp_ip.c52
-rw-r--r--net/l2tp/l2tp_netlink.c3
-rw-r--r--net/mac80211/Kconfig1
-rw-r--r--net/mac80211/aes_ccm.c6
-rw-r--r--net/mac80211/agg-rx.c3
-rw-r--r--net/mac80211/agg-tx.c59
-rw-r--r--net/mac80211/cfg.c188
-rw-r--r--net/mac80211/debugfs.c91
-rw-r--r--net/mac80211/debugfs_key.c21
-rw-r--r--net/mac80211/debugfs_sta.c26
-rw-r--r--net/mac80211/driver-ops.h87
-rw-r--r--net/mac80211/driver-trace.h275
-rw-r--r--net/mac80211/ht.c27
-rw-r--r--net/mac80211/ibss.c21
-rw-r--r--net/mac80211/ieee80211_i.h51
-rw-r--r--net/mac80211/iface.c7
-rw-r--r--net/mac80211/key.c51
-rw-r--r--net/mac80211/key.h4
-rw-r--r--net/mac80211/main.c69
-rw-r--r--net/mac80211/mesh.c62
-rw-r--r--net/mac80211/mesh.h9
-rw-r--r--net/mac80211/mesh_hwmp.c42
-rw-r--r--net/mac80211/mesh_pathtbl.c166
-rw-r--r--net/mac80211/mesh_plink.c112
-rw-r--r--net/mac80211/mlme.c48
-rw-r--r--net/mac80211/pm.c29
-rw-r--r--net/mac80211/rc80211_minstrel.c4
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c27
-rw-r--r--net/mac80211/rx.c94
-rw-r--r--net/mac80211/scan.c122
-rw-r--r--net/mac80211/sta_info.c52
-rw-r--r--net/mac80211/sta_info.h56
-rw-r--r--net/mac80211/status.c19
-rw-r--r--net/mac80211/tkip.c4
-rw-r--r--net/mac80211/tkip.h4
-rw-r--r--net/mac80211/tx.c27
-rw-r--r--net/mac80211/util.c21
-rw-r--r--net/mac80211/wep.c34
-rw-r--r--net/mac80211/wep.h4
-rw-r--r--net/mac80211/work.c6
-rw-r--r--net/mac80211/wpa.c62
-rw-r--r--net/netfilter/ipset/ip_set_getport.c16
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipport.c2
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipportip.c2
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipportnet.c2
-rw-r--r--net/netfilter/ipset/ip_set_hash_netport.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c24
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c97
-rw-r--r--net/netfilter/nf_conntrack_sip.c16
-rw-r--r--net/netfilter/nf_conntrack_standalone.c2
-rw-r--r--net/netfilter/nfnetlink_log.c2
-rw-r--r--net/netfilter/x_tables.c9
-rw-r--r--net/netlabel/netlabel_cipso_v4.c4
-rw-r--r--net/netrom/af_netrom.c12
-rw-r--r--net/packet/af_packet.c2
-rw-r--r--net/phonet/pn_dev.c6
-rw-r--r--net/phonet/pn_netlink.c4
-rw-r--r--net/phonet/socket.c45
-rw-r--r--net/rfkill/Kconfig11
-rw-r--r--net/rfkill/Makefile1
-rw-r--r--net/rfkill/core.c2
-rw-r--r--net/rfkill/rfkill-regulator.c164
-rw-r--r--net/rose/af_rose.c16
-rw-r--r--net/rxrpc/ar-ack.c2
-rw-r--r--net/rxrpc/ar-connevent.c3
-rw-r--r--net/rxrpc/ar-error.c5
-rw-r--r--net/rxrpc/ar-peer.c6
-rw-r--r--net/rxrpc/ar-transport.c3
-rw-r--r--net/sched/Kconfig12
-rw-r--r--net/sched/Makefile1
-rw-r--r--net/sched/sch_api.c2
-rw-r--r--net/sched/sch_qfq.c1137
-rw-r--r--net/sched/sch_sfq.c2
-rw-r--r--net/sctp/bind_addr.c10
-rw-r--r--net/sctp/debug.c1
-rw-r--r--net/sctp/endpointola.c20
-rw-r--r--net/sctp/input.c19
-rw-r--r--net/sctp/ipv6.c185
-rw-r--r--net/sctp/outqueue.c19
-rw-r--r--net/sctp/protocol.c71
-rw-r--r--net/sctp/sm_make_chunk.c62
-rw-r--r--net/sctp/sm_sideeffect.c9
-rw-r--r--net/sctp/sm_statefuns.c89
-rw-r--r--net/sctp/sm_statetable.c78
-rw-r--r--net/sctp/socket.c95
-rw-r--r--net/sctp/transport.c27
-rw-r--r--net/sctp/ulpevent.c30
-rw-r--r--net/socket.c219
-rw-r--r--net/tipc/addr.h7
-rw-r--r--net/tipc/bcast.c22
-rw-r--r--net/tipc/bearer.c45
-rw-r--r--net/tipc/core.c3
-rw-r--r--net/tipc/discover.c150
-rw-r--r--net/tipc/discover.h11
-rw-r--r--net/tipc/link.c104
-rw-r--r--net/tipc/link.h1
-rw-r--r--net/tipc/msg.c25
-rw-r--r--net/tipc/msg.h161
-rw-r--r--net/tipc/port.c55
-rw-r--r--net/tipc/port.h14
-rw-r--r--net/tipc/socket.c27
-rw-r--r--net/tipc/subscr.c4
-rw-r--r--net/wireless/core.c106
-rw-r--r--net/wireless/core.h33
-rw-r--r--net/wireless/lib80211_crypt_wep.c3
-rw-r--r--net/wireless/mesh.c23
-rw-r--r--net/wireless/mlme.c19
-rw-r--r--net/wireless/nl80211.c790
-rw-r--r--net/wireless/nl80211.h11
-rw-r--r--net/wireless/reg.c74
-rw-r--r--net/wireless/scan.c77
-rw-r--r--net/wireless/sysfs.c2
-rw-r--r--net/wireless/util.c126
-rw-r--r--net/xfrm/xfrm_policy.c3
-rw-r--r--net/xfrm/xfrm_state.c12
-rw-r--r--scripts/mod/file2alias.c22
1198 files changed, 126858 insertions, 79620 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-bcma b/Documentation/ABI/testing/sysfs-bus-bcma
new file mode 100644
index 00000000000..06b62badddd
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-bcma
@@ -0,0 +1,31 @@
+What: /sys/bus/bcma/devices/.../manuf
+Date: May 2011
+KernelVersion: 2.6.40
+Contact: Rafał Miłecki <zajec5@gmail.com>
+Description:
+ Each BCMA core has it's manufacturer id. See
+ include/linux/bcma/bcma.h for possible values.
+
+What: /sys/bus/bcma/devices/.../id
+Date: May 2011
+KernelVersion: 2.6.40
+Contact: Rafał Miłecki <zajec5@gmail.com>
+Description:
+ There are a few types of BCMA cores, they can be identified by
+ id field.
+
+What: /sys/bus/bcma/devices/.../rev
+Date: May 2011
+KernelVersion: 2.6.40
+Contact: Rafał Miłecki <zajec5@gmail.com>
+Description:
+ BCMA cores of the same type can still slightly differ depending
+ on their revision. Use it for detailed programming.
+
+What: /sys/bus/bcma/devices/.../class
+Date: May 2011
+KernelVersion: 2.6.40
+Contact: Rafał Miłecki <zajec5@gmail.com>
+Description:
+ Each BCMA core is identified by few fields, including class it
+ belongs to. See include/linux/bcma/bcma.h for possible values.
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index f6a24e8aa11..4cba260e305 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -35,17 +35,6 @@ Who: Luis R. Rodriguez <lrodriguez@atheros.com>
---------------------------
-What: AR9170USB
-When: 2.6.40
-
-Why: This driver is deprecated and the firmware is no longer
- maintained. The replacement driver "carl9170" has been
- around for a while, so the devices are still supported.
-
-Who: Christian Lamparter <chunkeey@googlemail.com>
-
----------------------------
-
What: IRQF_SAMPLE_RANDOM
Check: IRQF_SAMPLE_RANDOM
When: July 2009
@@ -405,16 +394,6 @@ Who: anybody or Florian Mickler <florian@mickler.org>
----------------------------
-What: capifs
-When: February 2011
-Files: drivers/isdn/capi/capifs.*
-Why: udev fully replaces this special file system that only contains CAPI
- NCCI TTY device nodes. User space (pppdcapiplugin) works without
- noticing the difference.
-Who: Jan Kiszka <jan.kiszka@web.de>
-
-----------------------------
-
What: KVM paravirt mmu host support
When: January 2011
Why: The paravirt mmu host support is slower than non-paravirt mmu, both
diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt
index ee496eb2f4a..88d4afbdef9 100644
--- a/Documentation/networking/batman-adv.txt
+++ b/Documentation/networking/batman-adv.txt
@@ -1,4 +1,4 @@
-[state: 27-01-2011]
+[state: 17-04-2011]
BATMAN-ADV
----------
@@ -19,6 +19,7 @@ duce the overhead to a minimum. It does not depend on any (other)
network driver, and can be used on wifi as well as ethernet lan,
vpn, etc ... (anything with ethernet-style layer 2).
+
CONFIGURATION
-------------
@@ -160,13 +161,13 @@ face. Each entry can/has to have the following values:
-> "TQ mac value" - src mac's link quality towards mac address
of a neighbor originator's interface which
is being used for routing
--> "HNA mac" - HNA announced by source mac
+-> "TT mac" - TT announced by source mac
-> "PRIMARY" - this is a primary interface
-> "SEC mac" - secondary mac address of source
(requires preceding PRIMARY)
The TQ value has a range from 4 to 255 with 255 being the best.
-The HNA entries are showing which hosts are connected to the mesh
+The TT entries are showing which hosts are connected to the mesh
via bat0 or being bridged into the mesh network. The PRIMARY/SEC
values are only applied on primary interfaces
@@ -199,7 +200,7 @@ abled during run time. Following log_levels are defined:
0 - All debug output disabled
1 - Enable messages related to routing / flooding / broadcasting
-2 - Enable route or hna added / changed / deleted
+2 - Enable route or tt entry added / changed / deleted
3 - Enable all messages
The debug output can be changed at runtime using the file
@@ -207,7 +208,7 @@ The debug output can be changed at runtime using the file
# echo 2 > /sys/class/net/bat0/mesh/log_level
-will enable debug messages for when routes or HNAs change.
+will enable debug messages for when routes or TTs change.
BATCTL
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index e27202bb8d7..1f45bd887d6 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -1,7 +1,7 @@
Linux Ethernet Bonding Driver HOWTO
- Latest update: 23 September 2009
+ Latest update: 27 April 2011
Initial release : Thomas Davis <tadavis at lbl.gov>
Corrections, HA extensions : 2000/10/03-15 :
@@ -585,25 +585,23 @@ mode
chosen.
num_grat_arp
-
- Specifies the number of gratuitous ARPs to be issued after a
- failover event. One gratuitous ARP is issued immediately after
- the failover, subsequent ARPs are sent at a rate of one per link
- monitor interval (arp_interval or miimon, whichever is active).
-
- The valid range is 0 - 255; the default value is 1. This option
- affects only the active-backup mode. This option was added for
- bonding version 3.3.0.
-
num_unsol_na
- Specifies the number of unsolicited IPv6 Neighbor Advertisements
- to be issued after a failover event. One unsolicited NA is issued
- immediately after the failover.
-
- The valid range is 0 - 255; the default value is 1. This option
- affects only the active-backup mode. This option was added for
- bonding version 3.4.0.
+ Specify the number of peer notifications (gratuitous ARPs and
+ unsolicited IPv6 Neighbor Advertisements) to be issued after a
+ failover event. As soon as the link is up on the new slave
+ (possibly immediately) a peer notification is sent on the
+ bonding device and each VLAN sub-device. This is repeated at
+ each link monitor interval (arp_interval or miimon, whichever
+ is active) if the number is greater than 1.
+
+ The valid range is 0 - 255; the default value is 1. These options
+ affect only the active-backup mode. These options were added for
+ bonding versions 3.3.0 and 3.4.0 respectively.
+
+ From Linux 2.6.40 and bonding version 3.7.1, these notifications
+ are generated by the ipv4 and ipv6 code and the numbers of
+ repetitions cannot be set independently.
primary
diff --git a/Documentation/networking/igb.txt b/Documentation/networking/igb.txt
index 98953c0d534..9a2a037194a 100644
--- a/Documentation/networking/igb.txt
+++ b/Documentation/networking/igb.txt
@@ -93,6 +93,19 @@ Additional Configurations
REQUIREMENTS: MSI-X support is required for Multiqueue. If MSI-X is not
found, the system will fallback to MSI or to Legacy interrupts.
+ MAC and VLAN anti-spoofing feature
+ ----------------------------------
+ When a malicious driver attempts to send a spoofed packet, it is dropped by
+ the hardware and not transmitted. An interrupt is sent to the PF driver
+ notifying it of the spoof attempt.
+
+ When a spoofed packet is detected the PF driver will send the following
+ message to the system log (displayed by the "dmesg" command):
+
+ Spoof event(s) detected on VF(n)
+
+ Where n=the VF that attempted to do the spoofing.
+
Support
=======
diff --git a/Documentation/sysctl/net.txt b/Documentation/sysctl/net.txt
index cbd05ffc606..3201a7097e4 100644
--- a/Documentation/sysctl/net.txt
+++ b/Documentation/sysctl/net.txt
@@ -32,6 +32,17 @@ Table : Subdirectories in /proc/sys/net
1. /proc/sys/net/core - Network core options
-------------------------------------------------------
+bpf_jit_enable
+--------------
+
+This enables Berkeley Packet Filter Just in Time compiler.
+Currently supported on x86_64 architecture, bpf_jit provides a framework
+to speed packet filtering, the one used by tcpdump/libpcap for example.
+Values :
+ 0 - disable the JIT (default value)
+ 1 - enable the JIT
+ 2 - enable the JIT and ask the compiler to emit traces on kernel log.
+
rmem_default
------------
diff --git a/MAINTAINERS b/MAINTAINERS
index d76d63a4e89..49a0bf3a5b9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1232,13 +1232,6 @@ W: http://wireless.kernel.org/en/users/Drivers/ath9k
S: Supported
F: drivers/net/wireless/ath/ath9k/
-ATHEROS AR9170 WIRELESS DRIVER
-M: Christian Lamparter <chunkeey@web.de>
-L: linux-wireless@vger.kernel.org
-W: http://wireless.kernel.org/en/users/Drivers/ar9170
-S: Obsolete
-F: drivers/net/wireless/ath/ar9170/
-
CARL9170 LINUX COMMUNITY WIRELESS DRIVER
M: Christian Lamparter <chunkeey@googlemail.com>
L: linux-wireless@vger.kernel.org
@@ -3363,6 +3356,12 @@ F: Documentation/wimax/README.i2400m
F: drivers/net/wimax/i2400m/
F: include/linux/wimax/i2400m.h
+INTEL WIRELESS 3945ABG/BG, 4965AGN (iwlegacy)
+M: Stanislaw Gruszka <sgruszka@redhat.com>
+L: linux-wireless@vger.kernel.org
+S: Supported
+F: drivers/net/wireless/iwlegacy/
+
INTEL WIRELESS WIFI LINK (iwlwifi)
M: Wey-Yi Guy <wey-yi.w.guy@intel.com>
M: Intel Linux Wireless <ilw@linux.intel.com>
@@ -4385,6 +4384,7 @@ S: Maintained
F: net/ipv4/
F: net/ipv6/
F: include/net/ip*
+F: arch/x86/net/*
NETWORKING [LABELED] (NetLabel, CIPSO, Labeled IPsec, SECMARK)
M: Paul Moore <paul.moore@hp.com>
@@ -5832,6 +5832,13 @@ S: Maintained
F: drivers/ssb/
F: include/linux/ssb/
+BROADCOM SPECIFIC AMBA DRIVER (BCMA)
+M: Rafał Miłecki <zajec5@gmail.com>
+L: linux-wireless@vger.kernel.org
+S: Maintained
+F: drivers/bcma/
+F: include/linux/bcma/
+
SONY VAIO CONTROL DEVICE DRIVER
M: Mattia Dongili <malattia@linux.it>
L: platform-driver-x86@vger.kernel.org
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
index 3dc19f48295..e9f95dcde37 100644
--- a/arch/mips/txx9/generic/setup_tx4939.c
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -318,19 +318,15 @@ void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask)
}
#if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE)
-static int tx4939_get_eth_speed(struct net_device *dev)
+static u32 tx4939_get_eth_speed(struct net_device *dev)
{
- struct ethtool_cmd cmd = { ETHTOOL_GSET };
- int speed = 100; /* default 100Mbps */
- int err;
- if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
- return speed;
- err = dev->ethtool_ops->get_settings(dev, &cmd);
- if (err < 0)
- return speed;
- speed = cmd.speed == SPEED_100 ? 100 : 10;
- return speed;
+ struct ethtool_cmd cmd;
+ if (dev_ethtool_get_settings(dev, &cmd))
+ return 100; /* default 100Mbps */
+
+ return ethtool_cmd_speed(&cmd);
}
+
static int tx4939_netdev_event(struct notifier_block *this,
unsigned long event,
void *ptr)
@@ -343,8 +339,7 @@ static int tx4939_netdev_event(struct notifier_block *this,
else if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(1))
bit = TX4939_PCFG_SPEED1;
if (bit) {
- int speed = tx4939_get_eth_speed(dev);
- if (speed == 100)
+ if (tx4939_get_eth_speed(dev) == 100)
txx9_set64(&tx4939_ccfgptr->pcfg, bit);
else
txx9_clear64(&tx4939_ccfgptr->pcfg, bit);
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index 60f64b132bd..8489d372077 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -352,3 +352,4 @@ SYSCALL_SPU(name_to_handle_at)
COMPAT_SYS_SPU(open_by_handle_at)
COMPAT_SYS_SPU(clock_adjtime)
SYSCALL_SPU(syncfs)
+COMPAT_SYS_SPU(sendmmsg)
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index 3c215648ce6..6d23c8193ca 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -371,10 +371,11 @@
#define __NR_open_by_handle_at 346
#define __NR_clock_adjtime 347
#define __NR_syncfs 348
+#define __NR_sendmmsg 349
#ifdef __KERNEL__
-#define __NR_syscalls 349
+#define __NR_syscalls 350
#define __NR__exit __NR_exit
#define NR_syscalls __NR_syscalls
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index 9d897b6db98..c5387ed0add 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -404,8 +404,9 @@
#define __NR_open_by_handle_at 333
#define __NR_clock_adjtime 334
#define __NR_syncfs 335
+#define __NR_sendmmsg 336
-#define NR_syscalls 336
+#define NR_syscalls 337
#ifdef __32bit_syscall_numbers__
/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S
index 47ac73c32e8..332c83ff770 100644
--- a/arch/sparc/kernel/systbls_32.S
+++ b/arch/sparc/kernel/systbls_32.S
@@ -84,4 +84,4 @@ sys_call_table:
/*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
/*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
/*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
-/*335*/ .long sys_syncfs
+/*335*/ .long sys_syncfs, sys_sendmmsg
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index 4f3170c1ef4..43887ca0be0 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -85,7 +85,7 @@ sys_call_table32:
/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv
.word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init
/*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime
- .word sys_syncfs
+ .word sys_syncfs, compat_sys_sendmmsg
#endif /* CONFIG_COMPAT */
@@ -162,4 +162,4 @@ sys_call_table:
/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
.word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
/*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
- .word sys_syncfs
+ .word sys_syncfs, sys_sendmmsg
diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
index 0e103236b75..0e9dec6cadd 100644
--- a/arch/x86/Kbuild
+++ b/arch/x86/Kbuild
@@ -15,3 +15,4 @@ obj-y += vdso/
obj-$(CONFIG_IA32_EMULATION) += ia32/
obj-y += platform/
+obj-y += net/
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 4168e5d8632..880fcb6c86f 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -72,6 +72,7 @@ config X86
select GENERIC_IRQ_SHOW
select IRQ_FORCED_THREADING
select USE_GENERIC_SMP_HELPERS if SMP
+ select HAVE_BPF_JIT if (X86_64 && NET)
config INSTRUCTION_DECODER
def_bool (KPROBES || PERF_EVENTS)
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 849a9d23c71..95f5826be45 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -848,4 +848,5 @@ ia32_sys_call_table:
.quad compat_sys_open_by_handle_at
.quad compat_sys_clock_adjtime
.quad sys_syncfs
+ .quad compat_sys_sendmmsg /* 345 */
ia32_syscall_end:
diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h
index a755ef5e597..fb6a625c99b 100644
--- a/arch/x86/include/asm/unistd_32.h
+++ b/arch/x86/include/asm/unistd_32.h
@@ -350,10 +350,11 @@
#define __NR_open_by_handle_at 342
#define __NR_clock_adjtime 343
#define __NR_syncfs 344
+#define __NR_sendmmsg 345
#ifdef __KERNEL__
-#define NR_syscalls 345
+#define NR_syscalls 346
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h
index 160fa76bd57..79f90eb15aa 100644
--- a/arch/x86/include/asm/unistd_64.h
+++ b/arch/x86/include/asm/unistd_64.h
@@ -677,6 +677,8 @@ __SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at)
__SYSCALL(__NR_clock_adjtime, sys_clock_adjtime)
#define __NR_syncfs 306
__SYSCALL(__NR_syncfs, sys_syncfs)
+#define __NR_sendmmsg 307
+__SYSCALL(__NR_sendmmsg, sys_sendmmsg)
#ifndef __NO_STUBS
#define __ARCH_WANT_OLD_READDIR
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
index abce34d5c79..32cbffb0c49 100644
--- a/arch/x86/kernel/syscall_table_32.S
+++ b/arch/x86/kernel/syscall_table_32.S
@@ -344,3 +344,4 @@ ENTRY(sys_call_table)
.long sys_open_by_handle_at
.long sys_clock_adjtime
.long sys_syncfs
+ .long sys_sendmmsg /* 345 */
diff --git a/arch/x86/net/Makefile b/arch/x86/net/Makefile
new file mode 100644
index 00000000000..90568c33ddb
--- /dev/null
+++ b/arch/x86/net/Makefile
@@ -0,0 +1,4 @@
+#
+# Arch-specific network modules
+#
+obj-$(CONFIG_BPF_JIT) += bpf_jit.o bpf_jit_comp.o
diff --git a/arch/x86/net/bpf_jit.S b/arch/x86/net/bpf_jit.S
new file mode 100644
index 00000000000..66870223f8c
--- /dev/null
+++ b/arch/x86/net/bpf_jit.S
@@ -0,0 +1,140 @@
+/* bpf_jit.S : BPF JIT helper functions
+ *
+ * Copyright (C) 2011 Eric Dumazet (eric.dumazet@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+#include <linux/linkage.h>
+#include <asm/dwarf2.h>
+
+/*
+ * Calling convention :
+ * rdi : skb pointer
+ * esi : offset of byte(s) to fetch in skb (can be scratched)
+ * r8 : copy of skb->data
+ * r9d : hlen = skb->len - skb->data_len
+ */
+#define SKBDATA %r8
+
+sk_load_word_ind:
+ .globl sk_load_word_ind
+
+ add %ebx,%esi /* offset += X */
+# test %esi,%esi /* if (offset < 0) goto bpf_error; */
+ js bpf_error
+
+sk_load_word:
+ .globl sk_load_word
+
+ mov %r9d,%eax # hlen
+ sub %esi,%eax # hlen - offset
+ cmp $3,%eax
+ jle bpf_slow_path_word
+ mov (SKBDATA,%rsi),%eax
+ bswap %eax /* ntohl() */
+ ret
+
+
+sk_load_half_ind:
+ .globl sk_load_half_ind
+
+ add %ebx,%esi /* offset += X */
+ js bpf_error
+
+sk_load_half:
+ .globl sk_load_half
+
+ mov %r9d,%eax
+ sub %esi,%eax # hlen - offset
+ cmp $1,%eax
+ jle bpf_slow_path_half
+ movzwl (SKBDATA,%rsi),%eax
+ rol $8,%ax # ntohs()
+ ret
+
+sk_load_byte_ind:
+ .globl sk_load_byte_ind
+ add %ebx,%esi /* offset += X */
+ js bpf_error
+
+sk_load_byte:
+ .globl sk_load_byte
+
+ cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte */
+ jle bpf_slow_path_byte
+ movzbl (SKBDATA,%rsi),%eax
+ ret
+
+/**
+ * sk_load_byte_msh - BPF_S_LDX_B_MSH helper
+ *
+ * Implements BPF_S_LDX_B_MSH : ldxb 4*([offset]&0xf)
+ * Must preserve A accumulator (%eax)
+ * Inputs : %esi is the offset value, already known positive
+ */
+ENTRY(sk_load_byte_msh)
+ CFI_STARTPROC
+ cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte_msh */
+ jle bpf_slow_path_byte_msh
+ movzbl (SKBDATA,%rsi),%ebx
+ and $15,%bl
+ shl $2,%bl
+ ret
+ CFI_ENDPROC
+ENDPROC(sk_load_byte_msh)
+
+bpf_error:
+# force a return 0 from jit handler
+ xor %eax,%eax
+ mov -8(%rbp),%rbx
+ leaveq
+ ret
+
+/* rsi contains offset and can be scratched */
+#define bpf_slow_path_common(LEN) \
+ push %rdi; /* save skb */ \
+ push %r9; \
+ push SKBDATA; \
+/* rsi already has offset */ \
+ mov $LEN,%ecx; /* len */ \
+ lea -12(%rbp),%rdx; \
+ call skb_copy_bits; \
+ test %eax,%eax; \
+ pop SKBDATA; \
+ pop %r9; \
+ pop %rdi
+
+
+bpf_slow_path_word:
+ bpf_slow_path_common(4)
+ js bpf_error
+ mov -12(%rbp),%eax
+ bswap %eax
+ ret
+
+bpf_slow_path_half:
+ bpf_slow_path_common(2)
+ js bpf_error
+ mov -12(%rbp),%ax
+ rol $8,%ax
+ movzwl %ax,%eax
+ ret
+
+bpf_slow_path_byte:
+ bpf_slow_path_common(1)
+ js bpf_error
+ movzbl -12(%rbp),%eax
+ ret
+
+bpf_slow_path_byte_msh:
+ xchg %eax,%ebx /* dont lose A , X is about to be scratched */
+ bpf_slow_path_common(1)
+ js bpf_error
+ movzbl -12(%rbp),%eax
+ and $15,%al
+ shl $2,%al
+ xchg %eax,%ebx
+ ret
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
new file mode 100644
index 00000000000..bfab3fa10ed
--- /dev/null
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -0,0 +1,654 @@
+/* bpf_jit_comp.c : BPF JIT compiler
+ *
+ * Copyright (C) 2011 Eric Dumazet (eric.dumazet@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+#include <linux/moduleloader.h>
+#include <asm/cacheflush.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+
+/*
+ * Conventions :
+ * EAX : BPF A accumulator
+ * EBX : BPF X accumulator
+ * RDI : pointer to skb (first argument given to JIT function)
+ * RBP : frame pointer (even if CONFIG_FRAME_POINTER=n)
+ * ECX,EDX,ESI : scratch registers
+ * r9d : skb->len - skb->data_len (headlen)
+ * r8 : skb->data
+ * -8(RBP) : saved RBX value
+ * -16(RBP)..-80(RBP) : BPF_MEMWORDS values
+ */
+int bpf_jit_enable __read_mostly;
+
+/*
+ * assembly code in arch/x86/net/bpf_jit.S
+ */
+extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[];
+extern u8 sk_load_word_ind[], sk_load_half_ind[], sk_load_byte_ind[];
+
+static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
+{
+ if (len == 1)
+ *ptr = bytes;
+ else if (len == 2)
+ *(u16 *)ptr = bytes;
+ else {
+ *(u32 *)ptr = bytes;
+ barrier();
+ }
+ return ptr + len;
+}
+
+#define EMIT(bytes, len) do { prog = emit_code(prog, bytes, len); } while (0)
+
+#define EMIT1(b1) EMIT(b1, 1)
+#define EMIT2(b1, b2) EMIT((b1) + ((b2) << 8), 2)
+#define EMIT3(b1, b2, b3) EMIT((b1) + ((b2) << 8) + ((b3) << 16), 3)
+#define EMIT4(b1, b2, b3, b4) EMIT((b1) + ((b2) << 8) + ((b3) << 16) + ((b4) << 24), 4)
+#define EMIT1_off32(b1, off) do { EMIT1(b1); EMIT(off, 4);} while (0)
+
+#define CLEAR_A() EMIT2(0x31, 0xc0) /* xor %eax,%eax */
+#define CLEAR_X() EMIT2(0x31, 0xdb) /* xor %ebx,%ebx */
+
+static inline bool is_imm8(int value)
+{
+ return value <= 127 && value >= -128;
+}
+
+static inline bool is_near(int offset)
+{
+ return offset <= 127 && offset >= -128;
+}
+
+#define EMIT_JMP(offset) \
+do { \
+ if (offset) { \
+ if (is_near(offset)) \
+ EMIT2(0xeb, offset); /* jmp .+off8 */ \
+ else \
+ EMIT1_off32(0xe9, offset); /* jmp .+off32 */ \
+ } \
+} while (0)
+
+/* list of x86 cond jumps opcodes (. + s8)
+ * Add 0x10 (and an extra 0x0f) to generate far jumps (. + s32)
+ */
+#define X86_JB 0x72
+#define X86_JAE 0x73
+#define X86_JE 0x74
+#define X86_JNE 0x75
+#define X86_JBE 0x76
+#define X86_JA 0x77
+
+#define EMIT_COND_JMP(op, offset) \
+do { \
+ if (is_near(offset)) \
+ EMIT2(op, offset); /* jxx .+off8 */ \
+ else { \
+ EMIT2(0x0f, op + 0x10); \
+ EMIT(offset, 4); /* jxx .+off32 */ \
+ } \
+} while (0)
+
+#define COND_SEL(CODE, TOP, FOP) \
+ case CODE: \
+ t_op = TOP; \
+ f_op = FOP; \
+ goto cond_branch
+
+
+#define SEEN_DATAREF 1 /* might call external helpers */
+#define SEEN_XREG 2 /* ebx is used */
+#define SEEN_MEM 4 /* use mem[] for temporary storage */
+
+static inline void bpf_flush_icache(void *start, void *end)
+{
+ mm_segment_t old_fs = get_fs();
+
+ set_fs(KERNEL_DS);
+ smp_wmb();
+ flush_icache_range((unsigned long)start, (unsigned long)end);
+ set_fs(old_fs);
+}
+
+
+void bpf_jit_compile(struct sk_filter *fp)
+{
+ u8 temp[64];
+ u8 *prog;
+ unsigned int proglen, oldproglen = 0;
+ int ilen, i;
+ int t_offset, f_offset;
+ u8 t_op, f_op, seen = 0, pass;
+ u8 *image = NULL;
+ u8 *func;
+ int pc_ret0 = -1; /* bpf index of first RET #0 instruction (if any) */
+ unsigned int cleanup_addr; /* epilogue code offset */
+ unsigned int *addrs;
+ const struct sock_filter *filter = fp->insns;
+ int flen = fp->len;
+
+ if (!bpf_jit_enable)
+ return;
+
+ addrs = kmalloc(flen * sizeof(*addrs), GFP_KERNEL);
+ if (addrs == NULL)
+ return;
+
+ /* Before first pass, make a rough estimation of addrs[]
+ * each bpf instruction is translated to less than 64 bytes
+ */
+ for (proglen = 0, i = 0; i < flen; i++) {
+ proglen += 64;
+ addrs[i] = proglen;
+ }
+ cleanup_addr = proglen; /* epilogue address */
+
+ for (pass = 0; pass < 10; pass++) {
+ /* no prologue/epilogue for trivial filters (RET something) */
+ proglen = 0;
+ prog = temp;
+
+ if (seen) {
+ EMIT4(0x55, 0x48, 0x89, 0xe5); /* push %rbp; mov %rsp,%rbp */
+ EMIT4(0x48, 0x83, 0xec, 96); /* subq $96,%rsp */
+ /* note : must save %rbx in case bpf_error is hit */
+ if (seen & (SEEN_XREG | SEEN_DATAREF))
+ EMIT4(0x48, 0x89, 0x5d, 0xf8); /* mov %rbx, -8(%rbp) */
+ if (seen & SEEN_XREG)
+ CLEAR_X(); /* make sure we dont leek kernel memory */
+
+ /*
+ * If this filter needs to access skb data,
+ * loads r9 and r8 with :
+ * r9 = skb->len - skb->data_len
+ * r8 = skb->data
+ */
+ if (seen & SEEN_DATAREF) {
+ if (offsetof(struct sk_buff, len) <= 127)
+ /* mov off8(%rdi),%r9d */
+ EMIT4(0x44, 0x8b, 0x4f, offsetof(struct sk_buff, len));
+ else {
+ /* mov off32(%rdi),%r9d */
+ EMIT3(0x44, 0x8b, 0x8f);
+ EMIT(offsetof(struct sk_buff, len), 4);
+ }
+ if (is_imm8(offsetof(struct sk_buff, data_len)))
+ /* sub off8(%rdi),%r9d */
+ EMIT4(0x44, 0x2b, 0x4f, offsetof(struct sk_buff, data_len));
+ else {
+ EMIT3(0x44, 0x2b, 0x8f);
+ EMIT(offsetof(struct sk_buff, data_len), 4);
+ }
+
+ if (is_imm8(offsetof(struct sk_buff, data)))
+ /* mov off8(%rdi),%r8 */
+ EMIT4(0x4c, 0x8b, 0x47, offsetof(struct sk_buff, data));
+ else {
+ /* mov off32(%rdi),%r8 */
+ EMIT3(0x4c, 0x8b, 0x87);
+ EMIT(offsetof(struct sk_buff, data), 4);
+ }
+ }
+ }
+
+ switch (filter[0].code) {
+ case BPF_S_RET_K:
+ case BPF_S_LD_W_LEN:
+ case BPF_S_ANC_PROTOCOL:
+ case BPF_S_ANC_IFINDEX:
+ case BPF_S_ANC_MARK:
+ case BPF_S_ANC_RXHASH:
+ case BPF_S_ANC_CPU:
+ case BPF_S_ANC_QUEUE:
+ case BPF_S_LD_W_ABS:
+ case BPF_S_LD_H_ABS:
+ case BPF_S_LD_B_ABS:
+ /* first instruction sets A register (or is RET 'constant') */
+ break;
+ default:
+ /* make sure we dont leak kernel information to user */
+ CLEAR_A(); /* A = 0 */
+ }
+
+ for (i = 0; i < flen; i++) {
+ unsigned int K = filter[i].k;
+
+ switch (filter[i].code) {
+ case BPF_S_ALU_ADD_X: /* A += X; */
+ seen |= SEEN_XREG;
+ EMIT2(0x01, 0xd8); /* add %ebx,%eax */
+ break;
+ case BPF_S_ALU_ADD_K: /* A += K; */
+ if (!K)
+ break;
+ if (is_imm8(K))
+ EMIT3(0x83, 0xc0, K); /* add imm8,%eax */
+ else
+ EMIT1_off32(0x05, K); /* add imm32,%eax */
+ break;
+ case BPF_S_ALU_SUB_X: /* A -= X; */
+ seen |= SEEN_XREG;
+ EMIT2(0x29, 0xd8); /* sub %ebx,%eax */
+ break;
+ case BPF_S_ALU_SUB_K: /* A -= K */
+ if (!K)
+ break;
+ if (is_imm8(K))
+ EMIT3(0x83, 0xe8, K); /* sub imm8,%eax */
+ else
+ EMIT1_off32(0x2d, K); /* sub imm32,%eax */
+ break;
+ case BPF_S_ALU_MUL_X: /* A *= X; */
+ seen |= SEEN_XREG;
+ EMIT3(0x0f, 0xaf, 0xc3); /* imul %ebx,%eax */
+ break;
+ case BPF_S_ALU_MUL_K: /* A *= K */
+ if (is_imm8(K))
+ EMIT3(0x6b, 0xc0, K); /* imul imm8,%eax,%eax */
+ else {
+ EMIT2(0x69, 0xc0); /* imul imm32,%eax */
+ EMIT(K, 4);
+ }
+ break;
+ case BPF_S_ALU_DIV_X: /* A /= X; */
+ seen |= SEEN_XREG;
+ EMIT2(0x85, 0xdb); /* test %ebx,%ebx */
+ if (pc_ret0 != -1)
+ EMIT_COND_JMP(X86_JE, addrs[pc_ret0] - (addrs[i] - 4));
+ else {
+ EMIT_COND_JMP(X86_JNE, 2 + 5);
+ CLEAR_A();
+ EMIT1_off32(0xe9, cleanup_addr - (addrs[i] - 4)); /* jmp .+off32 */
+ }
+ EMIT4(0x31, 0xd2, 0xf7, 0xf3); /* xor %edx,%edx; div %ebx */
+ break;
+ case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */
+ EMIT3(0x48, 0x69, 0xc0); /* imul imm32,%rax,%rax */
+ EMIT(K, 4);
+ EMIT4(0x48, 0xc1, 0xe8, 0x20); /* shr $0x20,%rax */
+ break;
+ case BPF_S_ALU_AND_X:
+ seen |= SEEN_XREG;
+ EMIT2(0x21, 0xd8); /* and %ebx,%eax */
+ break;
+ case BPF_S_ALU_AND_K:
+ if (K >= 0xFFFFFF00) {
+ EMIT2(0x24, K & 0xFF); /* and imm8,%al */
+ } else if (K >= 0xFFFF0000) {
+ EMIT2(0x66, 0x25); /* and imm16,%ax */
+ EMIT2(K, 2);
+ } else {
+ EMIT1_off32(0x25, K); /* and imm32,%eax */
+ }
+ break;
+ case BPF_S_ALU_OR_X:
+ seen |= SEEN_XREG;
+ EMIT2(0x09, 0xd8); /* or %ebx,%eax */
+ break;
+ case BPF_S_ALU_OR_K:
+ if (is_imm8(K))
+ EMIT3(0x83, 0xc8, K); /* or imm8,%eax */
+ else
+ EMIT1_off32(0x0d, K); /* or imm32,%eax */
+ break;
+ case BPF_S_ALU_LSH_X: /* A <<= X; */
+ seen |= SEEN_XREG;
+ EMIT4(0x89, 0xd9, 0xd3, 0xe0); /* mov %ebx,%ecx; shl %cl,%eax */
+ break;
+ case BPF_S_ALU_LSH_K:
+ if (K == 0)
+ break;
+ else if (K == 1)
+ EMIT2(0xd1, 0xe0); /* shl %eax */
+ else
+ EMIT3(0xc1, 0xe0, K);
+ break;
+ case BPF_S_ALU_RSH_X: /* A >>= X; */
+ seen |= SEEN_XREG;
+ EMIT4(0x89, 0xd9, 0xd3, 0xe8); /* mov %ebx,%ecx; shr %cl,%eax */
+ break;
+ case BPF_S_ALU_RSH_K: /* A >>= K; */
+ if (K == 0)
+ break;
+ else if (K == 1)
+ EMIT2(0xd1, 0xe8); /* shr %eax */
+ else
+ EMIT3(0xc1, 0xe8, K);
+ break;
+ case BPF_S_ALU_NEG:
+ EMIT2(0xf7, 0xd8); /* neg %eax */
+ break;
+ case BPF_S_RET_K:
+ if (!K) {
+ if (pc_ret0 == -1)
+ pc_ret0 = i;
+ CLEAR_A();
+ } else {
+ EMIT1_off32(0xb8, K); /* mov $imm32,%eax */
+ }
+ /* fallinto */
+ case BPF_S_RET_A:
+ if (seen) {
+ if (i != flen - 1) {
+ EMIT_JMP(cleanup_addr - addrs[i]);
+ break;
+ }
+ if (seen & SEEN_XREG)
+ EMIT4(0x48, 0x8b, 0x5d, 0xf8); /* mov -8(%rbp),%rbx */
+ EMIT1(0xc9); /* leaveq */
+ }
+ EMIT1(0xc3); /* ret */
+ break;
+ case BPF_S_MISC_TAX: /* X = A */
+ seen |= SEEN_XREG;
+ EMIT2(0x89, 0xc3); /* mov %eax,%ebx */
+ break;
+ case BPF_S_MISC_TXA: /* A = X */
+ seen |= SEEN_XREG;
+ EMIT2(0x89, 0xd8); /* mov %ebx,%eax */
+ break;
+ case BPF_S_LD_IMM: /* A = K */
+ if (!K)
+ CLEAR_A();
+ else
+ EMIT1_off32(0xb8, K); /* mov $imm32,%eax */
+ break;
+ case BPF_S_LDX_IMM: /* X = K */
+ seen |= SEEN_XREG;
+ if (!K)
+ CLEAR_X();
+ else
+ EMIT1_off32(0xbb, K); /* mov $imm32,%ebx */
+ break;
+ case BPF_S_LD_MEM: /* A = mem[K] : mov off8(%rbp),%eax */
+ seen |= SEEN_MEM;
+ EMIT3(0x8b, 0x45, 0xf0 - K*4);
+ break;
+ case BPF_S_LDX_MEM: /* X = mem[K] : mov off8(%rbp),%ebx */
+ seen |= SEEN_XREG | SEEN_MEM;
+ EMIT3(0x8b, 0x5d, 0xf0 - K*4);
+ break;
+ case BPF_S_ST: /* mem[K] = A : mov %eax,off8(%rbp) */
+ seen |= SEEN_MEM;
+ EMIT3(0x89, 0x45, 0xf0 - K*4);
+ break;
+ case BPF_S_STX: /* mem[K] = X : mov %ebx,off8(%rbp) */
+ seen |= SEEN_XREG | SEEN_MEM;
+ EMIT3(0x89, 0x5d, 0xf0 - K*4);
+ break;
+ case BPF_S_LD_W_LEN: /* A = skb->len; */
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
+ if (is_imm8(offsetof(struct sk_buff, len)))
+ /* mov off8(%rdi),%eax */
+ EMIT3(0x8b, 0x47, offsetof(struct sk_buff, len));
+ else {
+ EMIT2(0x8b, 0x87);
+ EMIT(offsetof(struct sk_buff, len), 4);
+ }
+ break;
+ case BPF_S_LDX_W_LEN: /* X = skb->len; */
+ seen |= SEEN_XREG;
+ if (is_imm8(offsetof(struct sk_buff, len)))
+ /* mov off8(%rdi),%ebx */
+ EMIT3(0x8b, 0x5f, offsetof(struct sk_buff, len));
+ else {
+ EMIT2(0x8b, 0x9f);
+ EMIT(offsetof(struct sk_buff, len), 4);
+ }
+ break;
+ case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol); */
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, protocol) != 2);
+ if (is_imm8(offsetof(struct sk_buff, protocol))) {
+ /* movzwl off8(%rdi),%eax */
+ EMIT4(0x0f, 0xb7, 0x47, offsetof(struct sk_buff, protocol));
+ } else {
+ EMIT3(0x0f, 0xb7, 0x87); /* movzwl off32(%rdi),%eax */
+ EMIT(offsetof(struct sk_buff, protocol), 4);
+ }
+ EMIT2(0x86, 0xc4); /* ntohs() : xchg %al,%ah */
+ break;
+ case BPF_S_ANC_IFINDEX:
+ if (is_imm8(offsetof(struct sk_buff, dev))) {
+ /* movq off8(%rdi),%rax */
+ EMIT4(0x48, 0x8b, 0x47, offsetof(struct sk_buff, dev));
+ } else {
+ EMIT3(0x48, 0x8b, 0x87); /* movq off32(%rdi),%rax */
+ EMIT(offsetof(struct sk_buff, dev), 4);
+ }
+ EMIT3(0x48, 0x85, 0xc0); /* test %rax,%rax */
+ EMIT_COND_JMP(X86_JE, cleanup_addr - (addrs[i] - 6));
+ BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, ifindex) != 4);
+ EMIT2(0x8b, 0x80); /* mov off32(%rax),%eax */
+ EMIT(offsetof(struct net_device, ifindex), 4);
+ break;
+ case BPF_S_ANC_MARK:
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
+ if (is_imm8(offsetof(struct sk_buff, mark))) {
+ /* mov off8(%rdi),%eax */
+ EMIT3(0x8b, 0x47, offsetof(struct sk_buff, mark));
+ } else {
+ EMIT2(0x8b, 0x87);
+ EMIT(offsetof(struct sk_buff, mark), 4);
+ }
+ break;
+ case BPF_S_ANC_RXHASH:
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4);
+ if (is_imm8(offsetof(struct sk_buff, rxhash))) {
+ /* mov off8(%rdi),%eax */
+ EMIT3(0x8b, 0x47, offsetof(struct sk_buff, rxhash));
+ } else {
+ EMIT2(0x8b, 0x87);
+ EMIT(offsetof(struct sk_buff, rxhash), 4);
+ }
+ break;
+ case BPF_S_ANC_QUEUE:
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, queue_mapping) != 2);
+ if (is_imm8(offsetof(struct sk_buff, queue_mapping))) {
+ /* movzwl off8(%rdi),%eax */
+ EMIT4(0x0f, 0xb7, 0x47, offsetof(struct sk_buff, queue_mapping));
+ } else {
+ EMIT3(0x0f, 0xb7, 0x87); /* movzwl off32(%rdi),%eax */
+ EMIT(offsetof(struct sk_buff, queue_mapping), 4);
+ }
+ break;
+ case BPF_S_ANC_CPU:
+#ifdef CONFIG_SMP
+ EMIT4(0x65, 0x8b, 0x04, 0x25); /* mov %gs:off32,%eax */
+ EMIT((u32)(unsigned long)&cpu_number, 4); /* A = smp_processor_id(); */
+#else
+ CLEAR_A();
+#endif
+ break;
+ case BPF_S_LD_W_ABS:
+ func = sk_load_word;
+common_load: seen |= SEEN_DATAREF;
+ if ((int)K < 0)
+ goto out;
+ t_offset = func - (image + addrs[i]);
+ EMIT1_off32(0xbe, K); /* mov imm32,%esi */
+ EMIT1_off32(0xe8, t_offset); /* call */
+ break;
+ case BPF_S_LD_H_ABS:
+ func = sk_load_half;
+ goto common_load;
+ case BPF_S_LD_B_ABS:
+ func = sk_load_byte;
+ goto common_load;
+ case BPF_S_LDX_B_MSH:
+ if ((int)K < 0) {
+ if (pc_ret0 != -1) {
+ EMIT_JMP(addrs[pc_ret0] - addrs[i]);
+ break;
+ }
+ CLEAR_A();
+ EMIT_JMP(cleanup_addr - addrs[i]);
+ break;
+ }
+ seen |= SEEN_DATAREF | SEEN_XREG;
+ t_offset = sk_load_byte_msh - (image + addrs[i]);
+ EMIT1_off32(0xbe, K); /* mov imm32,%esi */
+ EMIT1_off32(0xe8, t_offset); /* call sk_load_byte_msh */
+ break;
+ case BPF_S_LD_W_IND:
+ func = sk_load_word_ind;
+common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG;
+ t_offset = func - (image + addrs[i]);
+ EMIT1_off32(0xbe, K); /* mov imm32,%esi */
+ EMIT1_off32(0xe8, t_offset); /* call sk_load_xxx_ind */
+ break;
+ case BPF_S_LD_H_IND:
+ func = sk_load_half_ind;
+ goto common_load_ind;
+ case BPF_S_LD_B_IND:
+ func = sk_load_byte_ind;
+ goto common_load_ind;
+ case BPF_S_JMP_JA:
+ t_offset = addrs[i + K] - addrs[i];
+ EMIT_JMP(t_offset);
+ break;
+ COND_SEL(BPF_S_JMP_JGT_K, X86_JA, X86_JBE);
+ COND_SEL(BPF_S_JMP_JGE_K, X86_JAE, X86_JB);
+ COND_SEL(BPF_S_JMP_JEQ_K, X86_JE, X86_JNE);
+ COND_SEL(BPF_S_JMP_JSET_K,X86_JNE, X86_JE);
+ COND_SEL(BPF_S_JMP_JGT_X, X86_JA, X86_JBE);
+ COND_SEL(BPF_S_JMP_JGE_X, X86_JAE, X86_JB);
+ COND_SEL(BPF_S_JMP_JEQ_X, X86_JE, X86_JNE);
+ COND_SEL(BPF_S_JMP_JSET_X,X86_JNE, X86_JE);
+
+cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+ t_offset = addrs[i + filter[i].jt] - addrs[i];
+
+ /* same targets, can avoid doing the test :) */
+ if (filter[i].jt == filter[i].jf) {
+ EMIT_JMP(t_offset);
+ break;
+ }
+
+ switch (filter[i].code) {
+ case BPF_S_JMP_JGT_X:
+ case BPF_S_JMP_JGE_X:
+ case BPF_S_JMP_JEQ_X:
+ seen |= SEEN_XREG;
+ EMIT2(0x39, 0xd8); /* cmp %ebx,%eax */
+ break;
+ case BPF_S_JMP_JSET_X:
+ seen |= SEEN_XREG;
+ EMIT2(0x85, 0xd8); /* test %ebx,%eax */
+ break;
+ case BPF_S_JMP_JEQ_K:
+ if (K == 0) {
+ EMIT2(0x85, 0xc0); /* test %eax,%eax */
+ break;
+ }
+ case BPF_S_JMP_JGT_K:
+ case BPF_S_JMP_JGE_K:
+ if (K <= 127)
+ EMIT3(0x83, 0xf8, K); /* cmp imm8,%eax */
+ else
+ EMIT1_off32(0x3d, K); /* cmp imm32,%eax */
+ break;
+ case BPF_S_JMP_JSET_K:
+ if (K <= 0xFF)
+ EMIT2(0xa8, K); /* test imm8,%al */
+ else if (!(K & 0xFFFF00FF))
+ EMIT3(0xf6, 0xc4, K >> 8); /* test imm8,%ah */
+ else if (K <= 0xFFFF) {
+ EMIT2(0x66, 0xa9); /* test imm16,%ax */
+ EMIT(K, 2);
+ } else {
+ EMIT1_off32(0xa9, K); /* test imm32,%eax */
+ }
+ break;
+ }
+ if (filter[i].jt != 0) {
+ if (filter[i].jf)
+ t_offset += is_near(f_offset) ? 2 : 6;
+ EMIT_COND_JMP(t_op, t_offset);
+ if (filter[i].jf)
+ EMIT_JMP(f_offset);
+ break;
+ }
+ EMIT_COND_JMP(f_op, f_offset);
+ break;
+ default:
+ /* hmm, too complex filter, give up with jit compiler */
+ goto out;
+ }
+ ilen = prog - temp;
+ if (image) {
+ if (unlikely(proglen + ilen > oldproglen)) {
+ pr_err("bpb_jit_compile fatal error\n");
+ kfree(addrs);
+ module_free(NULL, image);
+ return;
+ }
+ memcpy(image + proglen, temp, ilen);
+ }
+ proglen += ilen;
+ addrs[i] = proglen;
+ prog = temp;
+ }
+ /* last bpf instruction is always a RET :
+ * use it to give the cleanup instruction(s) addr
+ */
+ cleanup_addr = proglen - 1; /* ret */
+ if (seen)
+ cleanup_addr -= 1; /* leaveq */
+ if (seen & SEEN_XREG)
+ cleanup_addr -= 4; /* mov -8(%rbp),%rbx */
+
+ if (image) {
+ WARN_ON(proglen != oldproglen);
+ break;
+ }
+ if (proglen == oldproglen) {
+ image = module_alloc(max_t(unsigned int,
+ proglen,
+ sizeof(struct work_struct)));
+ if (!image)
+ goto out;
+ }
+ oldproglen = proglen;
+ }
+ if (bpf_jit_enable > 1)
+ pr_err("flen=%d proglen=%u pass=%d image=%p\n",
+ flen, proglen, pass, image);
+
+ if (image) {
+ if (bpf_jit_enable > 1)
+ print_hex_dump(KERN_ERR, "JIT code: ", DUMP_PREFIX_ADDRESS,
+ 16, 1, image, proglen, false);
+
+ bpf_flush_icache(image, image + proglen);
+
+ fp->bpf_func = (void *)image;
+ }
+out:
+ kfree(addrs);
+ return;
+}
+
+static void jit_free_defer(struct work_struct *arg)
+{
+ module_free(NULL, arg);
+}
+
+/* run from softirq, we must use a work_struct to call
+ * module_free() from process context
+ */
+void bpf_jit_free(struct sk_filter *fp)
+{
+ if (fp->bpf_func != sk_run_filter) {
+ struct work_struct *work = (struct work_struct *)fp->bpf_func;
+
+ INIT_WORK(work, jit_free_defer);
+ schedule_work(work);
+ }
+}
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 557a469c7aa..61631edfecc 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -68,6 +68,8 @@ source "drivers/watchdog/Kconfig"
source "drivers/ssb/Kconfig"
+source "drivers/bcma/Kconfig"
+
source "drivers/mfd/Kconfig"
source "drivers/regulator/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 3f135b6fb01..a29527f4ded 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -110,6 +110,7 @@ obj-$(CONFIG_HID) += hid/
obj-$(CONFIG_PPC_PS3) += ps3/
obj-$(CONFIG_OF) += of/
obj-$(CONFIG_SSB) += ssb/
+obj-$(CONFIG_BCMA) += bcma/
obj-$(CONFIG_VHOST_NET) += vhost/
obj-$(CONFIG_VLYNQ) += vlynq/
obj-$(CONFIG_STAGING) += staging/
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index c495fae7420..3230ea0df83 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -1469,10 +1469,7 @@ if (eni_boards) printk(KERN_INFO "loss: %ld\n",ENI_DEV(eni_boards)->lost);
static void bug_int(struct atm_dev *dev,unsigned long reason)
{
- struct eni_dev *eni_dev;
-
DPRINTK(">bug_int\n");
- eni_dev = ENI_DEV(dev);
if (reason & MID_DMA_ERR_ACK)
printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - DMA "
"error\n",dev->number);
@@ -1900,7 +1897,6 @@ static void eni_close(struct atm_vcc *vcc)
static int eni_open(struct atm_vcc *vcc)
{
- struct eni_dev *eni_dev;
struct eni_vcc *eni_vcc;
int error;
short vpi = vcc->vpi;
@@ -1910,7 +1906,6 @@ static int eni_open(struct atm_vcc *vcc)
EVENT("eni_open\n",0,0);
if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))
vcc->dev_data = NULL;
- eni_dev = ENI_DEV(vcc->dev);
if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
set_bit(ATM_VF_ADDR,&vcc->flags);
if (vcc->qos.aal != ATM_AAL0 && vcc->qos.aal != ATM_AAL5)
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index 6cf59bf281d..9a51df4f5b7 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -1801,7 +1801,7 @@ return_host_buffers:
next_rbrq_entry:
he_dev->rbrq_head = (struct he_rbrq *)
((unsigned long) he_dev->rbrq_base |
- RBRQ_MASK(++he_dev->rbrq_head));
+ RBRQ_MASK(he_dev->rbrq_head + 1));
}
read_unlock(&vcc_sklist_lock);
@@ -1884,7 +1884,7 @@ next_tbrq_entry:
pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
he_dev->tbrq_head = (struct he_tbrq *)
((unsigned long) he_dev->tbrq_base |
- TBRQ_MASK(++he_dev->tbrq_head));
+ TBRQ_MASK(he_dev->tbrq_head + 1));
}
if (updated) {
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index 048f99fe6f8..1f8d724a18b 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -1261,14 +1261,13 @@ idt77252_rx_raw(struct idt77252_dev *card)
PCI_DMA_FROMDEVICE);
while (head != tail) {
- unsigned int vpi, vci, pti;
+ unsigned int vpi, vci;
u32 header;
header = le32_to_cpu(*(u32 *) &queue->data[0]);
vpi = (header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT;
vci = (header & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT;
- pti = (header & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT;
#ifdef CONFIG_ATM_IDT77252_DEBUG
if (debug & DBG_RAW_CELL) {
@@ -2709,53 +2708,10 @@ idt77252_proc_read(struct atm_dev *dev, loff_t * pos, char *page)
static void
idt77252_collect_stat(struct idt77252_dev *card)
{
- u32 cdc, vpec, icc;
+ (void) readl(SAR_REG_CDC);
+ (void) readl(SAR_REG_VPEC);
+ (void) readl(SAR_REG_ICC);
- cdc = readl(SAR_REG_CDC);
- vpec = readl(SAR_REG_VPEC);
- icc = readl(SAR_REG_ICC);
-
-#ifdef NOTDEF
- printk("%s:", card->name);
-
- if (cdc & 0x7f0000) {
- char *s = "";
-
- printk(" [");
- if (cdc & (1 << 22)) {
- printk("%sRM ID", s);
- s = " | ";
- }
- if (cdc & (1 << 21)) {
- printk("%sCON TAB", s);
- s = " | ";
- }
- if (cdc & (1 << 20)) {
- printk("%sNO FB", s);
- s = " | ";
- }
- if (cdc & (1 << 19)) {
- printk("%sOAM CRC", s);
- s = " | ";
- }
- if (cdc & (1 << 18)) {
- printk("%sRM CRC", s);
- s = " | ";
- }
- if (cdc & (1 << 17)) {
- printk("%sRM FIFO", s);
- s = " | ";
- }
- if (cdc & (1 << 16)) {
- printk("%sRX FIFO", s);
- s = " | ";
- }
- printk("]");
- }
-
- printk(" CDC %04x, VPEC %04x, ICC: %04x\n",
- cdc & 0xffff, vpec & 0xffff, icc & 0xffff);
-#endif
}
static irqreturn_t
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index 1c674a91f14..dee4f01a64d 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -613,7 +613,6 @@ static int ia_que_tx (IADEV *iadev) {
struct sk_buff *skb;
int num_desc;
struct atm_vcc *vcc;
- struct ia_vcc *iavcc;
num_desc = ia_avail_descs(iadev);
while (num_desc && (skb = skb_dequeue(&iadev->tx_backlog))) {
@@ -627,7 +626,6 @@ static int ia_que_tx (IADEV *iadev) {
printk("Free the SKB on closed vci %d \n", vcc->vci);
break;
}
- iavcc = INPH_IA_VCC(vcc);
if (ia_pkt_tx (vcc, skb)) {
skb_queue_head(&iadev->tx_backlog, skb);
}
@@ -823,8 +821,6 @@ static void IaFrontEndIntr(IADEV *iadev) {
volatile IA_SUNI *suni;
volatile ia_mb25_t *mb25;
volatile suni_pm7345_t *suni_pm7345;
- u32 intr_status;
- u_int frmr_intr;
if(iadev->phy_type & FE_25MBIT_PHY) {
mb25 = (ia_mb25_t*)iadev->phy;
@@ -832,18 +828,18 @@ static void IaFrontEndIntr(IADEV *iadev) {
} else if (iadev->phy_type & FE_DS3_PHY) {
suni_pm7345 = (suni_pm7345_t *)iadev->phy;
/* clear FRMR interrupts */
- frmr_intr = suni_pm7345->suni_ds3_frm_intr_stat;
+ (void) suni_pm7345->suni_ds3_frm_intr_stat;
iadev->carrier_detect =
Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV));
} else if (iadev->phy_type & FE_E3_PHY ) {
suni_pm7345 = (suni_pm7345_t *)iadev->phy;
- frmr_intr = suni_pm7345->suni_e3_frm_maint_intr_ind;
+ (void) suni_pm7345->suni_e3_frm_maint_intr_ind;
iadev->carrier_detect =
Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat&SUNI_E3_LOS));
}
else {
suni = (IA_SUNI *)iadev->phy;
- intr_status = suni->suni_rsop_status & 0xff;
+ (void) suni->suni_rsop_status;
iadev->carrier_detect = Boolean(!(suni->suni_rsop_status & SUNI_LOSV));
}
if (iadev->carrier_detect)
@@ -2660,7 +2656,6 @@ static void ia_close(struct atm_vcc *vcc)
static int ia_open(struct atm_vcc *vcc)
{
- IADEV *iadev;
struct ia_vcc *ia_vcc;
int error;
if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))
@@ -2668,7 +2663,6 @@ static int ia_open(struct atm_vcc *vcc)
IF_EVENT(printk("ia: not partially allocated resources\n");)
vcc->dev_data = NULL;
}
- iadev = INPH_IA_DEV(vcc->dev);
if (vcc->vci != ATM_VPI_UNSPEC && vcc->vpi != ATM_VCI_UNSPEC)
{
IF_EVENT(printk("iphase open: unspec part\n");)
@@ -3052,11 +3046,9 @@ static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) {
static int ia_send(struct atm_vcc *vcc, struct sk_buff *skb)
{
IADEV *iadev;
- struct ia_vcc *iavcc;
unsigned long flags;
iadev = INPH_IA_DEV(vcc->dev);
- iavcc = INPH_IA_VCC(vcc);
if ((!skb)||(skb->len>(iadev->tx_buf_sz-sizeof(struct cpcs_trailer))))
{
if (!skb)
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index cd0ff66469b..5d1d0764513 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -527,7 +527,6 @@ static int flash_upgrade(struct solos_card *card, int chip)
{
const struct firmware *fw;
const char *fw_name;
- uint32_t data32 = 0;
int blocksize = 0;
int numblocks = 0;
int offset;
@@ -576,7 +575,7 @@ static int flash_upgrade(struct solos_card *card, int chip)
dev_info(&card->dev->dev, "Changing FPGA to Update mode\n");
iowrite32(1, card->config_regs + FPGA_MODE);
- data32 = ioread32(card->config_regs + FPGA_MODE);
+ (void) ioread32(card->config_regs + FPGA_MODE);
/* Set mode to Chip Erase */
if(chip == 0 || chip == 2)
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
new file mode 100644
index 00000000000..353781b5b78
--- /dev/null
+++ b/drivers/bcma/Kconfig
@@ -0,0 +1,33 @@
+config BCMA_POSSIBLE
+ bool
+ depends on HAS_IOMEM && HAS_DMA
+ default y
+
+menu "Broadcom specific AMBA"
+ depends on BCMA_POSSIBLE
+
+config BCMA
+ tristate "BCMA support"
+ depends on BCMA_POSSIBLE
+ help
+ Bus driver for Broadcom specific Advanced Microcontroller Bus
+ Architecture.
+
+config BCMA_HOST_PCI_POSSIBLE
+ bool
+ depends on BCMA && PCI = y
+ default y
+
+config BCMA_HOST_PCI
+ bool "Support for BCMA on PCI-host bus"
+ depends on BCMA_HOST_PCI_POSSIBLE
+
+config BCMA_DEBUG
+ bool "BCMA debugging"
+ depends on BCMA
+ help
+ This turns on additional debugging messages.
+
+ If unsure, say N
+
+endmenu
diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile
new file mode 100644
index 00000000000..0d56245bcb7
--- /dev/null
+++ b/drivers/bcma/Makefile
@@ -0,0 +1,7 @@
+bcma-y += main.o scan.o core.o
+bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
+bcma-y += driver_pci.o
+bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
+obj-$(CONFIG_BCMA) += bcma.o
+
+ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
diff --git a/drivers/bcma/README b/drivers/bcma/README
new file mode 100644
index 00000000000..f7e7ce46c60
--- /dev/null
+++ b/drivers/bcma/README
@@ -0,0 +1,19 @@
+Broadcom introduced new bus as replacement for older SSB. It is based on AMBA,
+however from programming point of view there is nothing AMBA specific we use.
+
+Standard AMBA drivers are platform specific, have hardcoded addresses and use
+AMBA standard fields like CID and PID.
+
+In case of Broadcom's cards every device consists of:
+1) Broadcom specific AMBA device. It is put on AMBA bus, but can not be treated
+ as standard AMBA device. Reading it's CID or PID can cause machine lockup.
+2) AMBA standard devices called ports or wrappers. They have CIDs (AMBA_CID)
+ and PIDs (0x103BB369), but we do not use that info for anything. One of that
+ devices is used for managing Broadcom specific core.
+
+Addresses of AMBA devices are not hardcoded in driver and have to be read from
+EPROM.
+
+In this situation we decided to introduce separated bus. It can contain up to
+16 devices identified by Broadcom specific fields: manufacturer, id, revision
+and class.
diff --git a/drivers/bcma/TODO b/drivers/bcma/TODO
new file mode 100644
index 00000000000..da7aa99fe81
--- /dev/null
+++ b/drivers/bcma/TODO
@@ -0,0 +1,3 @@
+- Interrupts
+- Defines for PCI core driver
+- Create kernel Documentation (use info from README)
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
new file mode 100644
index 00000000000..2f72e9c585f
--- /dev/null
+++ b/drivers/bcma/bcma_private.h
@@ -0,0 +1,28 @@
+#ifndef LINUX_BCMA_PRIVATE_H_
+#define LINUX_BCMA_PRIVATE_H_
+
+#ifndef pr_fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#endif
+
+#include <linux/bcma/bcma.h>
+#include <linux/delay.h>
+
+#define BCMA_CORE_SIZE 0x1000
+
+struct bcma_bus;
+
+/* main.c */
+extern int bcma_bus_register(struct bcma_bus *bus);
+extern void bcma_bus_unregister(struct bcma_bus *bus);
+
+/* scan.c */
+int bcma_bus_scan(struct bcma_bus *bus);
+
+#ifdef CONFIG_BCMA_HOST_PCI
+/* host_pci.c */
+extern int __init bcma_host_pci_init(void);
+extern void __exit bcma_host_pci_exit(void);
+#endif /* CONFIG_BCMA_HOST_PCI */
+
+#endif
diff --git a/drivers/bcma/core.c b/drivers/bcma/core.c
new file mode 100644
index 00000000000..ced379f7b37
--- /dev/null
+++ b/drivers/bcma/core.c
@@ -0,0 +1,51 @@
+/*
+ * Broadcom specific AMBA
+ * Core ops
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include <linux/bcma/bcma.h>
+
+bool bcma_core_is_enabled(struct bcma_device *core)
+{
+ if ((bcma_aread32(core, BCMA_IOCTL) & (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC))
+ != BCMA_IOCTL_CLK)
+ return false;
+ if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
+ return false;
+ return true;
+}
+EXPORT_SYMBOL_GPL(bcma_core_is_enabled);
+
+static void bcma_core_disable(struct bcma_device *core, u32 flags)
+{
+ if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
+ return;
+
+ bcma_awrite32(core, BCMA_IOCTL, flags);
+ bcma_aread32(core, BCMA_IOCTL);
+ udelay(10);
+
+ bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
+ udelay(1);
+}
+
+int bcma_core_enable(struct bcma_device *core, u32 flags)
+{
+ bcma_core_disable(core, flags);
+
+ bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags));
+ bcma_aread32(core, BCMA_IOCTL);
+
+ bcma_awrite32(core, BCMA_RESET_CTL, 0);
+ udelay(1);
+
+ bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags));
+ bcma_aread32(core, BCMA_IOCTL);
+ udelay(1);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(bcma_core_enable);
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
new file mode 100644
index 00000000000..606102256b4
--- /dev/null
+++ b/drivers/bcma/driver_chipcommon.c
@@ -0,0 +1,89 @@
+/*
+ * Broadcom specific AMBA
+ * ChipCommon core driver
+ *
+ * Copyright 2005, Broadcom Corporation
+ * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include <linux/bcma/bcma.h>
+
+static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
+ u32 mask, u32 value)
+{
+ value &= mask;
+ value |= bcma_cc_read32(cc, offset) & ~mask;
+ bcma_cc_write32(cc, offset, value);
+
+ return value;
+}
+
+void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
+{
+ if (cc->core->id.rev >= 11)
+ cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
+ cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
+ if (cc->core->id.rev >= 35)
+ cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);
+
+ if (cc->core->id.rev >= 20) {
+ bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0);
+ bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0);
+ }
+
+ if (cc->capabilities & BCMA_CC_CAP_PMU)
+ bcma_pmu_init(cc);
+ if (cc->capabilities & BCMA_CC_CAP_PCTL)
+ pr_err("Power control not implemented!\n");
+}
+
+/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
+void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
+{
+ /* instant NMI */
+ bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
+}
+
+void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
+{
+ bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value);
+}
+
+u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask)
+{
+ return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask;
+}
+
+u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
+{
+ return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
+}
+
+u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
+{
+ return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
+}
+
+u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
+{
+ return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
+}
+
+u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
+{
+ return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
+}
+EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
+
+u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
+{
+ return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
+}
+
+u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
+{
+ return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
+}
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
new file mode 100644
index 00000000000..f44177a644c
--- /dev/null
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -0,0 +1,134 @@
+/*
+ * Broadcom specific AMBA
+ * ChipCommon Power Management Unit driver
+ *
+ * Copyright 2009, Michael Buesch <mb@bu3sch.de>
+ * Copyright 2007, Broadcom Corporation
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include <linux/bcma/bcma.h>
+
+static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
+ u32 offset, u32 mask, u32 set)
+{
+ u32 value;
+
+ bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
+ bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
+ bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
+ value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
+ value &= mask;
+ value |= set;
+ bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
+ bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
+}
+
+static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
+{
+ struct bcma_bus *bus = cc->core->bus;
+
+ switch (bus->chipinfo.id) {
+ case 0x4313:
+ case 0x4331:
+ case 43224:
+ case 43225:
+ break;
+ default:
+ pr_err("PLL init unknown for device 0x%04X\n",
+ bus->chipinfo.id);
+ }
+}
+
+static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
+{
+ struct bcma_bus *bus = cc->core->bus;
+ u32 min_msk = 0, max_msk = 0;
+
+ switch (bus->chipinfo.id) {
+ case 0x4313:
+ min_msk = 0x200D;
+ max_msk = 0xFFFF;
+ break;
+ case 43224:
+ break;
+ default:
+ pr_err("PMU resource config unknown for device 0x%04X\n",
+ bus->chipinfo.id);
+ }
+
+ /* Set the resource masks. */
+ if (min_msk)
+ bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk);
+ if (max_msk)
+ bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk);
+}
+
+void bcma_pmu_swreg_init(struct bcma_drv_cc *cc)
+{
+ struct bcma_bus *bus = cc->core->bus;
+
+ switch (bus->chipinfo.id) {
+ case 0x4313:
+ case 0x4331:
+ case 43224:
+ break;
+ default:
+ pr_err("PMU switch/regulators init unknown for device "
+ "0x%04X\n", bus->chipinfo.id);
+ }
+}
+
+void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
+{
+ struct bcma_bus *bus = cc->core->bus;
+
+ switch (bus->chipinfo.id) {
+ case 0x4313:
+ bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
+ break;
+ case 0x4331:
+ pr_err("Enabling Ext PA lines not implemented\n");
+ break;
+ case 43224:
+ if (bus->chipinfo.rev == 0) {
+ pr_err("Workarounds for 43224 rev 0 not fully "
+ "implemented\n");
+ bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
+ } else {
+ bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
+ }
+ break;
+ default:
+ pr_err("Workarounds unknown for device 0x%04X\n",
+ bus->chipinfo.id);
+ }
+}
+
+void bcma_pmu_init(struct bcma_drv_cc *cc)
+{
+ u32 pmucap;
+
+ pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP);
+ cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION);
+
+ pr_debug("Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev,
+ pmucap);
+
+ if (cc->pmu.rev == 1)
+ bcma_cc_mask32(cc, BCMA_CC_PMU_CTL,
+ ~BCMA_CC_PMU_CTL_NOILPONW);
+ else
+ bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
+ BCMA_CC_PMU_CTL_NOILPONW);
+
+ if (cc->core->id.id == 0x4329 && cc->core->id.rev == 2)
+ pr_err("Fix for 4329b0 bad LPOM state not implemented!\n");
+
+ bcma_pmu_pll_init(cc);
+ bcma_pmu_resources_init(cc);
+ bcma_pmu_swreg_init(cc);
+ bcma_pmu_workarounds(cc);
+}
diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c
new file mode 100644
index 00000000000..e757e4e3c7e
--- /dev/null
+++ b/drivers/bcma/driver_pci.c
@@ -0,0 +1,163 @@
+/*
+ * Broadcom specific AMBA
+ * PCI Core
+ *
+ * Copyright 2005, Broadcom Corporation
+ * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include <linux/bcma/bcma.h>
+
+/**************************************************
+ * R/W ops.
+ **************************************************/
+
+static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
+{
+ pcicore_write32(pc, 0x130, address);
+ pcicore_read32(pc, 0x130);
+ return pcicore_read32(pc, 0x134);
+}
+
+#if 0
+static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
+{
+ pcicore_write32(pc, 0x130, address);
+ pcicore_read32(pc, 0x130);
+ pcicore_write32(pc, 0x134, data);
+}
+#endif
+
+static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
+{
+ const u16 mdio_control = 0x128;
+ const u16 mdio_data = 0x12C;
+ u32 v;
+ int i;
+
+ v = (1 << 30); /* Start of Transaction */
+ v |= (1 << 28); /* Write Transaction */
+ v |= (1 << 17); /* Turnaround */
+ v |= (0x1F << 18);
+ v |= (phy << 4);
+ pcicore_write32(pc, mdio_data, v);
+
+ udelay(10);
+ for (i = 0; i < 200; i++) {
+ v = pcicore_read32(pc, mdio_control);
+ if (v & 0x100 /* Trans complete */)
+ break;
+ msleep(1);
+ }
+}
+
+static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
+{
+ const u16 mdio_control = 0x128;
+ const u16 mdio_data = 0x12C;
+ int max_retries = 10;
+ u16 ret = 0;
+ u32 v;
+ int i;
+
+ v = 0x80; /* Enable Preamble Sequence */
+ v |= 0x2; /* MDIO Clock Divisor */
+ pcicore_write32(pc, mdio_control, v);
+
+ if (pc->core->id.rev >= 10) {
+ max_retries = 200;
+ bcma_pcie_mdio_set_phy(pc, device);
+ }
+
+ v = (1 << 30); /* Start of Transaction */
+ v |= (1 << 29); /* Read Transaction */
+ v |= (1 << 17); /* Turnaround */
+ if (pc->core->id.rev < 10)
+ v |= (u32)device << 22;
+ v |= (u32)address << 18;
+ pcicore_write32(pc, mdio_data, v);
+ /* Wait for the device to complete the transaction */
+ udelay(10);
+ for (i = 0; i < max_retries; i++) {
+ v = pcicore_read32(pc, mdio_control);
+ if (v & 0x100 /* Trans complete */) {
+ udelay(10);
+ ret = pcicore_read32(pc, mdio_data);
+ break;
+ }
+ msleep(1);
+ }
+ pcicore_write32(pc, mdio_control, 0);
+ return ret;
+}
+
+static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
+ u8 address, u16 data)
+{
+ const u16 mdio_control = 0x128;
+ const u16 mdio_data = 0x12C;
+ int max_retries = 10;
+ u32 v;
+ int i;
+
+ v = 0x80; /* Enable Preamble Sequence */
+ v |= 0x2; /* MDIO Clock Divisor */
+ pcicore_write32(pc, mdio_control, v);
+
+ if (pc->core->id.rev >= 10) {
+ max_retries = 200;
+ bcma_pcie_mdio_set_phy(pc, device);
+ }
+
+ v = (1 << 30); /* Start of Transaction */
+ v |= (1 << 28); /* Write Transaction */
+ v |= (1 << 17); /* Turnaround */
+ if (pc->core->id.rev < 10)
+ v |= (u32)device << 22;
+ v |= (u32)address << 18;
+ v |= data;
+ pcicore_write32(pc, mdio_data, v);
+ /* Wait for the device to complete the transaction */
+ udelay(10);
+ for (i = 0; i < max_retries; i++) {
+ v = pcicore_read32(pc, mdio_control);
+ if (v & 0x100 /* Trans complete */)
+ break;
+ msleep(1);
+ }
+ pcicore_write32(pc, mdio_control, 0);
+}
+
+/**************************************************
+ * Workarounds.
+ **************************************************/
+
+static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
+{
+ return (bcma_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
+}
+
+static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
+{
+ const u8 serdes_pll_device = 0x1D;
+ const u8 serdes_rx_device = 0x1F;
+ u16 tmp;
+
+ bcma_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
+ bcma_pcicore_polarity_workaround(pc));
+ tmp = bcma_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
+ if (tmp & 0x4000)
+ bcma_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
+}
+
+/**************************************************
+ * Init.
+ **************************************************/
+
+void bcma_core_pci_init(struct bcma_drv_pci *pc)
+{
+ bcma_pcicore_serdes_workaround(pc);
+}
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
new file mode 100644
index 00000000000..99dd36e8500
--- /dev/null
+++ b/drivers/bcma/host_pci.c
@@ -0,0 +1,196 @@
+/*
+ * Broadcom specific AMBA
+ * PCI Host
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include <linux/bcma/bcma.h>
+#include <linux/pci.h>
+
+static void bcma_host_pci_switch_core(struct bcma_device *core)
+{
+ pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN,
+ core->addr);
+ pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN2,
+ core->wrap);
+ core->bus->mapped_core = core;
+ pr_debug("Switched to core: 0x%X\n", core->id.id);
+}
+
+static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
+{
+ if (core->bus->mapped_core != core)
+ bcma_host_pci_switch_core(core);
+ return ioread8(core->bus->mmio + offset);
+}
+
+static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
+{
+ if (core->bus->mapped_core != core)
+ bcma_host_pci_switch_core(core);
+ return ioread16(core->bus->mmio + offset);
+}
+
+static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
+{
+ if (core->bus->mapped_core != core)
+ bcma_host_pci_switch_core(core);
+ return ioread32(core->bus->mmio + offset);
+}
+
+static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
+ u8 value)
+{
+ if (core->bus->mapped_core != core)
+ bcma_host_pci_switch_core(core);
+ iowrite8(value, core->bus->mmio + offset);
+}
+
+static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
+ u16 value)
+{
+ if (core->bus->mapped_core != core)
+ bcma_host_pci_switch_core(core);
+ iowrite16(value, core->bus->mmio + offset);
+}
+
+static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
+ u32 value)
+{
+ if (core->bus->mapped_core != core)
+ bcma_host_pci_switch_core(core);
+ iowrite32(value, core->bus->mmio + offset);
+}
+
+static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
+{
+ if (core->bus->mapped_core != core)
+ bcma_host_pci_switch_core(core);
+ return ioread32(core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
+}
+
+static void bcma_host_pci_awrite32(struct bcma_device *core, u16 offset,
+ u32 value)
+{
+ if (core->bus->mapped_core != core)
+ bcma_host_pci_switch_core(core);
+ iowrite32(value, core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
+}
+
+const struct bcma_host_ops bcma_host_pci_ops = {
+ .read8 = bcma_host_pci_read8,
+ .read16 = bcma_host_pci_read16,
+ .read32 = bcma_host_pci_read32,
+ .write8 = bcma_host_pci_write8,
+ .write16 = bcma_host_pci_write16,
+ .write32 = bcma_host_pci_write32,
+ .aread32 = bcma_host_pci_aread32,
+ .awrite32 = bcma_host_pci_awrite32,
+};
+
+static int bcma_host_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ struct bcma_bus *bus;
+ int err = -ENOMEM;
+ const char *name;
+ u32 val;
+
+ /* Alloc */
+ bus = kzalloc(sizeof(*bus), GFP_KERNEL);
+ if (!bus)
+ goto out;
+
+ /* Basic PCI configuration */
+ err = pci_enable_device(dev);
+ if (err)
+ goto err_kfree_bus;
+
+ name = dev_name(&dev->dev);
+ if (dev->driver && dev->driver->name)
+ name = dev->driver->name;
+ err = pci_request_regions(dev, name);
+ if (err)
+ goto err_pci_disable;
+ pci_set_master(dev);
+
+ /* Disable the RETRY_TIMEOUT register (0x41) to keep
+ * PCI Tx retries from interfering with C3 CPU state */
+ pci_read_config_dword(dev, 0x40, &val);
+ if ((val & 0x0000ff00) != 0)
+ pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
+
+ /* SSB needed additional powering up, do we have any AMBA PCI cards? */
+ if (!pci_is_pcie(dev))
+ pr_err("PCI card detected, report problems.\n");
+
+ /* Map MMIO */
+ err = -ENOMEM;
+ bus->mmio = pci_iomap(dev, 0, ~0UL);
+ if (!bus->mmio)
+ goto err_pci_release_regions;
+
+ /* Host specific */
+ bus->host_pci = dev;
+ bus->hosttype = BCMA_HOSTTYPE_PCI;
+ bus->ops = &bcma_host_pci_ops;
+
+ /* Register */
+ err = bcma_bus_register(bus);
+ if (err)
+ goto err_pci_unmap_mmio;
+
+ pci_set_drvdata(dev, bus);
+
+out:
+ return err;
+
+err_pci_unmap_mmio:
+ pci_iounmap(dev, bus->mmio);
+err_pci_release_regions:
+ pci_release_regions(dev);
+err_pci_disable:
+ pci_disable_device(dev);
+err_kfree_bus:
+ kfree(bus);
+ return err;
+}
+
+static void bcma_host_pci_remove(struct pci_dev *dev)
+{
+ struct bcma_bus *bus = pci_get_drvdata(dev);
+
+ bcma_bus_unregister(bus);
+ pci_iounmap(dev, bus->mmio);
+ pci_release_regions(dev);
+ pci_disable_device(dev);
+ kfree(bus);
+ pci_set_drvdata(dev, NULL);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
+
+static struct pci_driver bcma_pci_bridge_driver = {
+ .name = "bcma-pci-bridge",
+ .id_table = bcma_pci_bridge_tbl,
+ .probe = bcma_host_pci_probe,
+ .remove = bcma_host_pci_remove,
+};
+
+int __init bcma_host_pci_init(void)
+{
+ return pci_register_driver(&bcma_pci_bridge_driver);
+}
+
+void __exit bcma_host_pci_exit(void)
+{
+ pci_unregister_driver(&bcma_pci_bridge_driver);
+}
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
new file mode 100644
index 00000000000..be52344ed19
--- /dev/null
+++ b/drivers/bcma/main.c
@@ -0,0 +1,247 @@
+/*
+ * Broadcom specific AMBA
+ * Bus subsystem
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include <linux/bcma/bcma.h>
+
+MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
+MODULE_LICENSE("GPL");
+
+static int bcma_bus_match(struct device *dev, struct device_driver *drv);
+static int bcma_device_probe(struct device *dev);
+static int bcma_device_remove(struct device *dev);
+
+static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+ return sprintf(buf, "0x%03X\n", core->id.manuf);
+}
+static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+ return sprintf(buf, "0x%03X\n", core->id.id);
+}
+static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+ return sprintf(buf, "0x%02X\n", core->id.rev);
+}
+static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+ return sprintf(buf, "0x%X\n", core->id.class);
+}
+static struct device_attribute bcma_device_attrs[] = {
+ __ATTR_RO(manuf),
+ __ATTR_RO(id),
+ __ATTR_RO(rev),
+ __ATTR_RO(class),
+ __ATTR_NULL,
+};
+
+static struct bus_type bcma_bus_type = {
+ .name = "bcma",
+ .match = bcma_bus_match,
+ .probe = bcma_device_probe,
+ .remove = bcma_device_remove,
+ .dev_attrs = bcma_device_attrs,
+};
+
+static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
+{
+ struct bcma_device *core;
+
+ list_for_each_entry(core, &bus->cores, list) {
+ if (core->id.id == coreid)
+ return core;
+ }
+ return NULL;
+}
+
+static void bcma_release_core_dev(struct device *dev)
+{
+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+ kfree(core);
+}
+
+static int bcma_register_cores(struct bcma_bus *bus)
+{
+ struct bcma_device *core;
+ int err, dev_id = 0;
+
+ list_for_each_entry(core, &bus->cores, list) {
+ /* We support that cores ourself */
+ switch (core->id.id) {
+ case BCMA_CORE_CHIPCOMMON:
+ case BCMA_CORE_PCI:
+ case BCMA_CORE_PCIE:
+ continue;
+ }
+
+ core->dev.release = bcma_release_core_dev;
+ core->dev.bus = &bcma_bus_type;
+ dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
+
+ switch (bus->hosttype) {
+ case BCMA_HOSTTYPE_PCI:
+ core->dev.parent = &bus->host_pci->dev;
+ break;
+ case BCMA_HOSTTYPE_NONE:
+ case BCMA_HOSTTYPE_SDIO:
+ break;
+ }
+
+ err = device_register(&core->dev);
+ if (err) {
+ pr_err("Could not register dev for core 0x%03X\n",
+ core->id.id);
+ continue;
+ }
+ core->dev_registered = true;
+ dev_id++;
+ }
+
+ return 0;
+}
+
+static void bcma_unregister_cores(struct bcma_bus *bus)
+{
+ struct bcma_device *core;
+
+ list_for_each_entry(core, &bus->cores, list) {
+ if (core->dev_registered)
+ device_unregister(&core->dev);
+ }
+}
+
+int bcma_bus_register(struct bcma_bus *bus)
+{
+ int err;
+ struct bcma_device *core;
+
+ /* Scan for devices (cores) */
+ err = bcma_bus_scan(bus);
+ if (err) {
+ pr_err("Failed to scan: %d\n", err);
+ return -1;
+ }
+
+ /* Init CC core */
+ core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
+ if (core) {
+ bus->drv_cc.core = core;
+ bcma_core_chipcommon_init(&bus->drv_cc);
+ }
+
+ /* Init PCIE core */
+ core = bcma_find_core(bus, BCMA_CORE_PCIE);
+ if (core) {
+ bus->drv_pci.core = core;
+ bcma_core_pci_init(&bus->drv_pci);
+ }
+
+ /* Register found cores */
+ bcma_register_cores(bus);
+
+ pr_info("Bus registered\n");
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(bcma_bus_register);
+
+void bcma_bus_unregister(struct bcma_bus *bus)
+{
+ bcma_unregister_cores(bus);
+}
+EXPORT_SYMBOL_GPL(bcma_bus_unregister);
+
+int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
+{
+ drv->drv.name = drv->name;
+ drv->drv.bus = &bcma_bus_type;
+ drv->drv.owner = owner;
+
+ return driver_register(&drv->drv);
+}
+EXPORT_SYMBOL_GPL(__bcma_driver_register);
+
+void bcma_driver_unregister(struct bcma_driver *drv)
+{
+ driver_unregister(&drv->drv);
+}
+EXPORT_SYMBOL_GPL(bcma_driver_unregister);
+
+static int bcma_bus_match(struct device *dev, struct device_driver *drv)
+{
+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+ struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
+ const struct bcma_device_id *cid = &core->id;
+ const struct bcma_device_id *did;
+
+ for (did = adrv->id_table; did->manuf || did->id || did->rev; did++) {
+ if ((did->manuf == cid->manuf || did->manuf == BCMA_ANY_MANUF) &&
+ (did->id == cid->id || did->id == BCMA_ANY_ID) &&
+ (did->rev == cid->rev || did->rev == BCMA_ANY_REV) &&
+ (did->class == cid->class || did->class == BCMA_ANY_CLASS))
+ return 1;
+ }
+ return 0;
+}
+
+static int bcma_device_probe(struct device *dev)
+{
+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+ struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
+ drv);
+ int err = 0;
+
+ if (adrv->probe)
+ err = adrv->probe(core);
+
+ return err;
+}
+
+static int bcma_device_remove(struct device *dev)
+{
+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+ struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
+ drv);
+
+ if (adrv->remove)
+ adrv->remove(core);
+
+ return 0;
+}
+
+static int __init bcma_modinit(void)
+{
+ int err;
+
+ err = bus_register(&bcma_bus_type);
+ if (err)
+ return err;
+
+#ifdef CONFIG_BCMA_HOST_PCI
+ err = bcma_host_pci_init();
+ if (err) {
+ pr_err("PCI host initialization failed\n");
+ err = 0;
+ }
+#endif
+
+ return err;
+}
+fs_initcall(bcma_modinit);
+
+static void __exit bcma_modexit(void)
+{
+#ifdef CONFIG_BCMA_HOST_PCI
+ bcma_host_pci_exit();
+#endif
+ bus_unregister(&bcma_bus_type);
+}
+module_exit(bcma_modexit)
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
new file mode 100644
index 00000000000..40d7dcce893
--- /dev/null
+++ b/drivers/bcma/scan.c
@@ -0,0 +1,360 @@
+/*
+ * Broadcom specific AMBA
+ * Bus scanning
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "scan.h"
+#include "bcma_private.h"
+
+#include <linux/bcma/bcma.h>
+#include <linux/bcma/bcma_regs.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+struct bcma_device_id_name {
+ u16 id;
+ const char *name;
+};
+struct bcma_device_id_name bcma_device_names[] = {
+ { BCMA_CORE_OOB_ROUTER, "OOB Router" },
+ { BCMA_CORE_INVALID, "Invalid" },
+ { BCMA_CORE_CHIPCOMMON, "ChipCommon" },
+ { BCMA_CORE_ILINE20, "ILine 20" },
+ { BCMA_CORE_SRAM, "SRAM" },
+ { BCMA_CORE_SDRAM, "SDRAM" },
+ { BCMA_CORE_PCI, "PCI" },
+ { BCMA_CORE_MIPS, "MIPS" },
+ { BCMA_CORE_ETHERNET, "Fast Ethernet" },
+ { BCMA_CORE_V90, "V90" },
+ { BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" },
+ { BCMA_CORE_ADSL, "ADSL" },
+ { BCMA_CORE_ILINE100, "ILine 100" },
+ { BCMA_CORE_IPSEC, "IPSEC" },
+ { BCMA_CORE_UTOPIA, "UTOPIA" },
+ { BCMA_CORE_PCMCIA, "PCMCIA" },
+ { BCMA_CORE_INTERNAL_MEM, "Internal Memory" },
+ { BCMA_CORE_MEMC_SDRAM, "MEMC SDRAM" },
+ { BCMA_CORE_OFDM, "OFDM" },
+ { BCMA_CORE_EXTIF, "EXTIF" },
+ { BCMA_CORE_80211, "IEEE 802.11" },
+ { BCMA_CORE_PHY_A, "PHY A" },
+ { BCMA_CORE_PHY_B, "PHY B" },
+ { BCMA_CORE_PHY_G, "PHY G" },
+ { BCMA_CORE_MIPS_3302, "MIPS 3302" },
+ { BCMA_CORE_USB11_HOST, "USB 1.1 Host" },
+ { BCMA_CORE_USB11_DEV, "USB 1.1 Device" },
+ { BCMA_CORE_USB20_HOST, "USB 2.0 Host" },
+ { BCMA_CORE_USB20_DEV, "USB 2.0 Device" },
+ { BCMA_CORE_SDIO_HOST, "SDIO Host" },
+ { BCMA_CORE_ROBOSWITCH, "Roboswitch" },
+ { BCMA_CORE_PARA_ATA, "PATA" },
+ { BCMA_CORE_SATA_XORDMA, "SATA XOR-DMA" },
+ { BCMA_CORE_ETHERNET_GBIT, "GBit Ethernet" },
+ { BCMA_CORE_PCIE, "PCIe" },
+ { BCMA_CORE_PHY_N, "PHY N" },
+ { BCMA_CORE_SRAM_CTL, "SRAM Controller" },
+ { BCMA_CORE_MINI_MACPHY, "Mini MACPHY" },
+ { BCMA_CORE_ARM_1176, "ARM 1176" },
+ { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
+ { BCMA_CORE_PHY_LP, "PHY LP" },
+ { BCMA_CORE_PMU, "PMU" },
+ { BCMA_CORE_PHY_SSN, "PHY SSN" },
+ { BCMA_CORE_SDIO_DEV, "SDIO Device" },
+ { BCMA_CORE_ARM_CM3, "ARM CM3" },
+ { BCMA_CORE_PHY_HT, "PHY HT" },
+ { BCMA_CORE_MIPS_74K, "MIPS 74K" },
+ { BCMA_CORE_MAC_GBIT, "GBit MAC" },
+ { BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" },
+ { BCMA_CORE_PCIE_RC, "PCIe Root Complex" },
+ { BCMA_CORE_OCP_OCP_BRIDGE, "OCP to OCP Bridge" },
+ { BCMA_CORE_SHARED_COMMON, "Common Shared" },
+ { BCMA_CORE_OCP_AHB_BRIDGE, "OCP to AHB Bridge" },
+ { BCMA_CORE_SPI_HOST, "SPI Host" },
+ { BCMA_CORE_I2S, "I2S" },
+ { BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" },
+ { BCMA_CORE_SHIM, "SHIM" },
+ { BCMA_CORE_DEFAULT, "Default" },
+};
+const char *bcma_device_name(struct bcma_device_id *id)
+{
+ int i;
+
+ if (id->manuf == BCMA_MANUF_BCM) {
+ for (i = 0; i < ARRAY_SIZE(bcma_device_names); i++) {
+ if (bcma_device_names[i].id == id->id)
+ return bcma_device_names[i].name;
+ }
+ }
+ return "UNKNOWN";
+}
+
+static u32 bcma_scan_read32(struct bcma_bus *bus, u8 current_coreidx,
+ u16 offset)
+{
+ return readl(bus->mmio + offset);
+}
+
+static void bcma_scan_switch_core(struct bcma_bus *bus, u32 addr)
+{
+ if (bus->hosttype == BCMA_HOSTTYPE_PCI)
+ pci_write_config_dword(bus->host_pci, BCMA_PCI_BAR0_WIN,
+ addr);
+}
+
+static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 **eromptr)
+{
+ u32 ent = readl(*eromptr);
+ (*eromptr)++;
+ return ent;
+}
+
+static void bcma_erom_push_ent(u32 **eromptr)
+{
+ (*eromptr)--;
+}
+
+static s32 bcma_erom_get_ci(struct bcma_bus *bus, u32 **eromptr)
+{
+ u32 ent = bcma_erom_get_ent(bus, eromptr);
+ if (!(ent & SCAN_ER_VALID))
+ return -ENOENT;
+ if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_CI)
+ return -ENOENT;
+ return ent;
+}
+
+static bool bcma_erom_is_end(struct bcma_bus *bus, u32 **eromptr)
+{
+ u32 ent = bcma_erom_get_ent(bus, eromptr);
+ bcma_erom_push_ent(eromptr);
+ return (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID));
+}
+
+static bool bcma_erom_is_bridge(struct bcma_bus *bus, u32 **eromptr)
+{
+ u32 ent = bcma_erom_get_ent(bus, eromptr);
+ bcma_erom_push_ent(eromptr);
+ return (((ent & SCAN_ER_VALID)) &&
+ ((ent & SCAN_ER_TAGX) == SCAN_ER_TAG_ADDR) &&
+ ((ent & SCAN_ADDR_TYPE) == SCAN_ADDR_TYPE_BRIDGE));
+}
+
+static void bcma_erom_skip_component(struct bcma_bus *bus, u32 **eromptr)
+{
+ u32 ent;
+ while (1) {
+ ent = bcma_erom_get_ent(bus, eromptr);
+ if ((ent & SCAN_ER_VALID) &&
+ ((ent & SCAN_ER_TAG) == SCAN_ER_TAG_CI))
+ break;
+ if (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID))
+ break;
+ }
+ bcma_erom_push_ent(eromptr);
+}
+
+static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 **eromptr)
+{
+ u32 ent = bcma_erom_get_ent(bus, eromptr);
+ if (!(ent & SCAN_ER_VALID))
+ return -ENOENT;
+ if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_MP)
+ return -ENOENT;
+ return ent;
+}
+
+static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
+ u32 type, u8 port)
+{
+ u32 addrl, addrh, sizel, sizeh = 0;
+ u32 size;
+
+ u32 ent = bcma_erom_get_ent(bus, eromptr);
+ if ((!(ent & SCAN_ER_VALID)) ||
+ ((ent & SCAN_ER_TAGX) != SCAN_ER_TAG_ADDR) ||
+ ((ent & SCAN_ADDR_TYPE) != type) ||
+ (((ent & SCAN_ADDR_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) {
+ bcma_erom_push_ent(eromptr);
+ return -EINVAL;
+ }
+
+ addrl = ent & SCAN_ADDR_ADDR;
+ if (ent & SCAN_ADDR_AG32)
+ addrh = bcma_erom_get_ent(bus, eromptr);
+ else
+ addrh = 0;
+
+ if ((ent & SCAN_ADDR_SZ) == SCAN_ADDR_SZ_SZD) {
+ size = bcma_erom_get_ent(bus, eromptr);
+ sizel = size & SCAN_SIZE_SZ;
+ if (size & SCAN_SIZE_SG32)
+ sizeh = bcma_erom_get_ent(bus, eromptr);
+ } else
+ sizel = SCAN_ADDR_SZ_BASE <<
+ ((ent & SCAN_ADDR_SZ) >> SCAN_ADDR_SZ_SHIFT);
+
+ return addrl;
+}
+
+int bcma_bus_scan(struct bcma_bus *bus)
+{
+ u32 erombase;
+ u32 __iomem *eromptr, *eromend;
+
+ s32 cia, cib;
+ u8 ports[2], wrappers[2];
+
+ s32 tmp;
+ u8 i, j;
+
+ int err;
+
+ INIT_LIST_HEAD(&bus->cores);
+ bus->nr_cores = 0;
+
+ bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
+
+ tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
+ bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
+ bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
+ bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
+
+ erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
+ eromptr = bus->mmio;
+ eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
+
+ bcma_scan_switch_core(bus, erombase);
+
+ while (eromptr < eromend) {
+ struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
+ if (!core)
+ return -ENOMEM;
+ INIT_LIST_HEAD(&core->list);
+ core->bus = bus;
+
+ /* get CIs */
+ cia = bcma_erom_get_ci(bus, &eromptr);
+ if (cia < 0) {
+ bcma_erom_push_ent(&eromptr);
+ if (bcma_erom_is_end(bus, &eromptr))
+ break;
+ err= -EILSEQ;
+ goto out;
+ }
+ cib = bcma_erom_get_ci(bus, &eromptr);
+ if (cib < 0) {
+ err= -EILSEQ;
+ goto out;
+ }
+
+ /* parse CIs */
+ core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
+ core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
+ core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
+ ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
+ ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
+ wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
+ wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
+ core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
+
+ if (((core->id.manuf == BCMA_MANUF_ARM) &&
+ (core->id.id == 0xFFF)) ||
+ (ports[1] == 0)) {
+ bcma_erom_skip_component(bus, &eromptr);
+ continue;
+ }
+
+ /* check if component is a core at all */
+ if (wrappers[0] + wrappers[1] == 0) {
+ /* we could save addrl of the router
+ if (cid == BCMA_CORE_OOB_ROUTER)
+ */
+ bcma_erom_skip_component(bus, &eromptr);
+ continue;
+ }
+
+ if (bcma_erom_is_bridge(bus, &eromptr)) {
+ bcma_erom_skip_component(bus, &eromptr);
+ continue;
+ }
+
+ /* get & parse master ports */
+ for (i = 0; i < ports[0]; i++) {
+ u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
+ if (mst_port_d < 0) {
+ err= -EILSEQ;
+ goto out;
+ }
+ }
+
+ /* get & parse slave ports */
+ for (i = 0; i < ports[1]; i++) {
+ for (j = 0; ; j++) {
+ tmp = bcma_erom_get_addr_desc(bus, &eromptr,
+ SCAN_ADDR_TYPE_SLAVE, i);
+ if (tmp < 0) {
+ /* no more entries for port _i_ */
+ /* pr_debug("erom: slave port %d "
+ * "has %d descriptors\n", i, j); */
+ break;
+ } else {
+ if (i == 0 && j == 0)
+ core->addr = tmp;
+ }
+ }
+ }
+
+ /* get & parse master wrappers */
+ for (i = 0; i < wrappers[0]; i++) {
+ for (j = 0; ; j++) {
+ tmp = bcma_erom_get_addr_desc(bus, &eromptr,
+ SCAN_ADDR_TYPE_MWRAP, i);
+ if (tmp < 0) {
+ /* no more entries for port _i_ */
+ /* pr_debug("erom: master wrapper %d "
+ * "has %d descriptors\n", i, j); */
+ break;
+ } else {
+ if (i == 0 && j == 0)
+ core->wrap = tmp;
+ }
+ }
+ }
+
+ /* get & parse slave wrappers */
+ for (i = 0; i < wrappers[1]; i++) {
+ u8 hack = (ports[1] == 1) ? 0 : 1;
+ for (j = 0; ; j++) {
+ tmp = bcma_erom_get_addr_desc(bus, &eromptr,
+ SCAN_ADDR_TYPE_SWRAP, i + hack);
+ if (tmp < 0) {
+ /* no more entries for port _i_ */
+ /* pr_debug("erom: master wrapper %d "
+ * has %d descriptors\n", i, j); */
+ break;
+ } else {
+ if (wrappers[0] == 0 && !i && !j)
+ core->wrap = tmp;
+ }
+ }
+ }
+
+ pr_info("Core %d found: %s "
+ "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
+ bus->nr_cores, bcma_device_name(&core->id),
+ core->id.manuf, core->id.id, core->id.rev,
+ core->id.class);
+
+ core->core_index = bus->nr_cores++;
+ list_add(&core->list, &bus->cores);
+ continue;
+out:
+ return err;
+ }
+
+ return 0;
+}
diff --git a/drivers/bcma/scan.h b/drivers/bcma/scan.h
new file mode 100644
index 00000000000..113e6a66884
--- /dev/null
+++ b/drivers/bcma/scan.h
@@ -0,0 +1,56 @@
+#ifndef BCMA_SCAN_H_
+#define BCMA_SCAN_H_
+
+#define BCMA_ADDR_BASE 0x18000000
+#define BCMA_WRAP_BASE 0x18100000
+
+#define SCAN_ER_VALID 0x00000001
+#define SCAN_ER_TAGX 0x00000006 /* we have to ignore 0x8 bit when checking tag for SCAN_ER_TAG_ADDR */
+#define SCAN_ER_TAG 0x0000000E
+#define SCAN_ER_TAG_CI 0x00000000
+#define SCAN_ER_TAG_MP 0x00000002
+#define SCAN_ER_TAG_ADDR 0x00000004
+#define SCAN_ER_TAG_END 0x0000000E
+#define SCAN_ER_BAD 0xFFFFFFFF
+
+#define SCAN_CIA_CLASS 0x000000F0
+#define SCAN_CIA_CLASS_SHIFT 4
+#define SCAN_CIA_ID 0x000FFF00
+#define SCAN_CIA_ID_SHIFT 8
+#define SCAN_CIA_MANUF 0xFFF00000
+#define SCAN_CIA_MANUF_SHIFT 20
+
+#define SCAN_CIB_NMP 0x000001F0
+#define SCAN_CIB_NMP_SHIFT 4
+#define SCAN_CIB_NSP 0x00003E00
+#define SCAN_CIB_NSP_SHIFT 9
+#define SCAN_CIB_NMW 0x0007C000
+#define SCAN_CIB_NMW_SHIFT 14
+#define SCAN_CIB_NSW 0x00F80000
+#define SCAN_CIB_NSW_SHIFT 17
+#define SCAN_CIB_REV 0xFF000000
+#define SCAN_CIB_REV_SHIFT 24
+
+#define SCAN_ADDR_AG32 0x00000008
+#define SCAN_ADDR_SZ 0x00000030
+#define SCAN_ADDR_SZ_SHIFT 4
+#define SCAN_ADDR_SZ_4K 0x00000000
+#define SCAN_ADDR_SZ_8K 0x00000010
+#define SCAN_ADDR_SZ_16K 0x00000020
+#define SCAN_ADDR_SZ_SZD 0x00000030
+#define SCAN_ADDR_TYPE 0x000000C0
+#define SCAN_ADDR_TYPE_SLAVE 0x00000000
+#define SCAN_ADDR_TYPE_BRIDGE 0x00000040
+#define SCAN_ADDR_TYPE_SWRAP 0x00000080
+#define SCAN_ADDR_TYPE_MWRAP 0x000000C0
+#define SCAN_ADDR_PORT 0x00000F00
+#define SCAN_ADDR_PORT_SHIFT 8
+#define SCAN_ADDR_ADDR 0xFFFFF000
+
+#define SCAN_ADDR_SZ_BASE 0x00001000 /* 4KB */
+
+#define SCAN_SIZE_SZ_ALIGN 0x00000FFF
+#define SCAN_SIZE_SZ 0xFFFFF000
+#define SCAN_SIZE_SG32 0x00000008
+
+#endif /* BCMA_SCAN_H_ */
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index 8e0de9a0586..11b41fd40c2 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -188,7 +188,7 @@ config BT_MRVL
The core driver to support Marvell Bluetooth devices.
This driver is required if you want to support
- Marvell Bluetooth devices, such as 8688.
+ Marvell Bluetooth devices, such as 8688/8787.
Say Y here to compile Marvell Bluetooth driver
into the kernel or say M to compile it as module.
@@ -201,7 +201,7 @@ config BT_MRVL_SDIO
The driver for Marvell Bluetooth chipsets with SDIO interface.
This driver is required if you want to use Marvell Bluetooth
- devices with SDIO interface. Currently only SD8688 chipset is
+ devices with SDIO interface. Currently SD8688/SD8787 chipsets are
supported.
Say Y here to compile support for Marvell BT-over-SDIO driver
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 5577ed656e2..6bacef368fa 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -62,6 +62,7 @@ static struct usb_device_id ath3k_table[] = {
/* Atheros AR3011 with sflash firmware*/
{ USB_DEVICE(0x0CF3, 0x3002) },
+ { USB_DEVICE(0x13d3, 0x3304) },
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03F0, 0x311D) },
@@ -138,9 +139,6 @@ static int ath3k_load_firmware(struct usb_device *udev,
count -= size;
}
- kfree(send_buf);
- return 0;
-
error:
kfree(send_buf);
return err;
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index dcc2a6ec23f..7f521d4ac65 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -49,15 +49,59 @@
static u8 user_rmmod;
static u8 sdio_ireg;
+static const struct btmrvl_sdio_card_reg btmrvl_reg_8688 = {
+ .cfg = 0x03,
+ .host_int_mask = 0x04,
+ .host_intstatus = 0x05,
+ .card_status = 0x20,
+ .sq_read_base_addr_a0 = 0x10,
+ .sq_read_base_addr_a1 = 0x11,
+ .card_fw_status0 = 0x40,
+ .card_fw_status1 = 0x41,
+ .card_rx_len = 0x42,
+ .card_rx_unit = 0x43,
+ .io_port_0 = 0x00,
+ .io_port_1 = 0x01,
+ .io_port_2 = 0x02,
+};
+static const struct btmrvl_sdio_card_reg btmrvl_reg_8787 = {
+ .cfg = 0x00,
+ .host_int_mask = 0x02,
+ .host_intstatus = 0x03,
+ .card_status = 0x30,
+ .sq_read_base_addr_a0 = 0x40,
+ .sq_read_base_addr_a1 = 0x41,
+ .card_revision = 0x5c,
+ .card_fw_status0 = 0x60,
+ .card_fw_status1 = 0x61,
+ .card_rx_len = 0x62,
+ .card_rx_unit = 0x63,
+ .io_port_0 = 0x78,
+ .io_port_1 = 0x79,
+ .io_port_2 = 0x7a,
+};
+
static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = {
.helper = "sd8688_helper.bin",
.firmware = "sd8688.bin",
+ .reg = &btmrvl_reg_8688,
+ .sd_blksz_fw_dl = 64,
+};
+
+static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
+ .helper = NULL,
+ .firmware = "mrvl/sd8787_uapsta.bin",
+ .reg = &btmrvl_reg_8787,
+ .sd_blksz_fw_dl = 256,
};
static const struct sdio_device_id btmrvl_sdio_ids[] = {
/* Marvell SD8688 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105),
.driver_data = (unsigned long) &btmrvl_sdio_sd6888 },
+ /* Marvell SD8787 Bluetooth device */
+ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A),
+ .driver_data = (unsigned long) &btmrvl_sdio_sd8787 },
{ } /* Terminating entry */
};
@@ -69,7 +113,7 @@ static int btmrvl_sdio_get_rx_unit(struct btmrvl_sdio_card *card)
u8 reg;
int ret;
- reg = sdio_readb(card->func, CARD_RX_UNIT_REG, &ret);
+ reg = sdio_readb(card->func, card->reg->card_rx_unit, &ret);
if (!ret)
card->rx_unit = reg;
@@ -83,11 +127,11 @@ static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat)
*dat = 0;
- fws0 = sdio_readb(card->func, CARD_FW_STATUS0_REG, &ret);
+ fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret);
if (ret)
return -EIO;
- fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret);
+ fws1 = sdio_readb(card->func, card->reg->card_fw_status1, &ret);
if (ret)
return -EIO;
@@ -101,7 +145,7 @@ static int btmrvl_sdio_read_rx_len(struct btmrvl_sdio_card *card, u16 *dat)
u8 reg;
int ret;
- reg = sdio_readb(card->func, CARD_RX_LEN_REG, &ret);
+ reg = sdio_readb(card->func, card->reg->card_rx_len, &ret);
if (!ret)
*dat = (u16) reg << card->rx_unit;
@@ -113,7 +157,7 @@ static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card,
{
int ret;
- sdio_writeb(card->func, mask, HOST_INT_MASK_REG, &ret);
+ sdio_writeb(card->func, mask, card->reg->host_int_mask, &ret);
if (ret) {
BT_ERR("Unable to enable the host interrupt!");
ret = -EIO;
@@ -128,13 +172,13 @@ static int btmrvl_sdio_disable_host_int_mask(struct btmrvl_sdio_card *card,
u8 host_int_mask;
int ret;
- host_int_mask = sdio_readb(card->func, HOST_INT_MASK_REG, &ret);
+ host_int_mask = sdio_readb(card->func, card->reg->host_int_mask, &ret);
if (ret)
return -EIO;
host_int_mask &= ~mask;
- sdio_writeb(card->func, host_int_mask, HOST_INT_MASK_REG, &ret);
+ sdio_writeb(card->func, host_int_mask, card->reg->host_int_mask, &ret);
if (ret < 0) {
BT_ERR("Unable to disable the host interrupt!");
return -EIO;
@@ -150,7 +194,7 @@ static int btmrvl_sdio_poll_card_status(struct btmrvl_sdio_card *card, u8 bits)
int ret;
for (tries = 0; tries < MAX_POLL_TRIES * 1000; tries++) {
- status = sdio_readb(card->func, CARD_STATUS_REG, &ret);
+ status = sdio_readb(card->func, card->reg->card_status, &ret);
if (ret)
goto failed;
if ((status & bits) == bits)
@@ -299,7 +343,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
u8 base0, base1;
void *tmpfwbuf = NULL;
u8 *fwbuf;
- u16 len;
+ u16 len, blksz_dl = card->sd_blksz_fw_dl;
int txlen = 0, tx_blocks = 0, count = 0;
ret = request_firmware(&fw_firmware, card->firmware,
@@ -345,7 +389,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
base0 = sdio_readb(card->func,
- SQ_READ_BASE_ADDRESS_A0_REG, &ret);
+ card->reg->sq_read_base_addr_a0, &ret);
if (ret) {
BT_ERR("BASE0 register read failed:"
" base0 = 0x%04X(%d)."
@@ -355,7 +399,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
goto done;
}
base1 = sdio_readb(card->func,
- SQ_READ_BASE_ADDRESS_A1_REG, &ret);
+ card->reg->sq_read_base_addr_a1, &ret);
if (ret) {
BT_ERR("BASE1 register read failed:"
" base1 = 0x%04X(%d)."
@@ -403,20 +447,19 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
if (firmwarelen - offset < txlen)
txlen = firmwarelen - offset;
- tx_blocks =
- (txlen + SDIO_BLOCK_SIZE - 1) / SDIO_BLOCK_SIZE;
+ tx_blocks = (txlen + blksz_dl - 1) / blksz_dl;
memcpy(fwbuf, &firmware[offset], txlen);
}
ret = sdio_writesb(card->func, card->ioport, fwbuf,
- tx_blocks * SDIO_BLOCK_SIZE);
+ tx_blocks * blksz_dl);
if (ret < 0) {
BT_ERR("FW download, writesb(%d) failed @%d",
count, offset);
- sdio_writeb(card->func, HOST_CMD53_FIN, CONFIG_REG,
- &ret);
+ sdio_writeb(card->func, HOST_CMD53_FIN,
+ card->reg->cfg, &ret);
if (ret)
BT_ERR("writeb failed (CFG)");
}
@@ -597,7 +640,7 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func)
priv = card->priv;
- ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret);
+ ireg = sdio_readb(card->func, card->reg->host_intstatus, &ret);
if (ret) {
BT_ERR("sdio_readb: read int status register failed");
return;
@@ -613,7 +656,7 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func)
sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS |
UP_LD_HOST_INT_STATUS),
- HOST_INTSTATUS_REG, &ret);
+ card->reg->host_intstatus, &ret);
if (ret) {
BT_ERR("sdio_writeb: clear int status register failed");
return;
@@ -664,7 +707,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
goto release_irq;
}
- reg = sdio_readb(func, IO_PORT_0_REG, &ret);
+ reg = sdio_readb(func, card->reg->io_port_0, &ret);
if (ret < 0) {
ret = -EIO;
goto release_irq;
@@ -672,7 +715,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
card->ioport = reg;
- reg = sdio_readb(func, IO_PORT_1_REG, &ret);
+ reg = sdio_readb(func, card->reg->io_port_1, &ret);
if (ret < 0) {
ret = -EIO;
goto release_irq;
@@ -680,7 +723,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
card->ioport |= (reg << 8);
- reg = sdio_readb(func, IO_PORT_2_REG, &ret);
+ reg = sdio_readb(func, card->reg->io_port_2, &ret);
if (ret < 0) {
ret = -EIO;
goto release_irq;
@@ -815,6 +858,8 @@ exit:
static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card)
{
int ret = 0;
+ u8 fws0;
+ int pollnum = MAX_POLL_TRIES;
if (!card || !card->func) {
BT_ERR("card or function is NULL!");
@@ -827,20 +872,36 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card)
goto done;
}
- ret = btmrvl_sdio_download_helper(card);
+ /* Check if other function driver is downloading the firmware */
+ fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret);
if (ret) {
- BT_ERR("Failed to download helper!");
+ BT_ERR("Failed to read FW downloading status!");
ret = -EIO;
goto done;
}
+ if (fws0) {
+ BT_DBG("BT not the winner (%#x). Skip FW downloading", fws0);
+
+ /* Give other function more time to download the firmware */
+ pollnum *= 10;
+ } else {
+ if (card->helper) {
+ ret = btmrvl_sdio_download_helper(card);
+ if (ret) {
+ BT_ERR("Failed to download helper!");
+ ret = -EIO;
+ goto done;
+ }
+ }
- if (btmrvl_sdio_download_fw_w_helper(card)) {
- BT_ERR("Failed to download firmware!");
- ret = -EIO;
- goto done;
+ if (btmrvl_sdio_download_fw_w_helper(card)) {
+ BT_ERR("Failed to download firmware!");
+ ret = -EIO;
+ goto done;
+ }
}
- if (btmrvl_sdio_verify_fw_download(card, MAX_POLL_TRIES)) {
+ if (btmrvl_sdio_verify_fw_download(card, pollnum)) {
BT_ERR("FW failed to be active in time!");
ret = -ETIMEDOUT;
goto done;
@@ -864,7 +925,7 @@ static int btmrvl_sdio_wakeup_fw(struct btmrvl_private *priv)
sdio_claim_host(card->func);
- sdio_writeb(card->func, HOST_POWER_UP, CONFIG_REG, &ret);
+ sdio_writeb(card->func, HOST_POWER_UP, card->reg->cfg, &ret);
sdio_release_host(card->func);
@@ -893,8 +954,10 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
if (id->driver_data) {
struct btmrvl_sdio_device *data = (void *) id->driver_data;
- card->helper = data->helper;
+ card->helper = data->helper;
card->firmware = data->firmware;
+ card->reg = data->reg;
+ card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
}
if (btmrvl_sdio_register_dev(card) < 0) {
@@ -1011,3 +1074,4 @@ MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE("sd8688_helper.bin");
MODULE_FIRMWARE("sd8688.bin");
+MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
diff --git a/drivers/bluetooth/btmrvl_sdio.h b/drivers/bluetooth/btmrvl_sdio.h
index 27329f107e5..43d35a609ca 100644
--- a/drivers/bluetooth/btmrvl_sdio.h
+++ b/drivers/bluetooth/btmrvl_sdio.h
@@ -47,44 +47,46 @@
/* Max retry number of CMD53 write */
#define MAX_WRITE_IOMEM_RETRY 2
-/* Host Control Registers */
-#define IO_PORT_0_REG 0x00
-#define IO_PORT_1_REG 0x01
-#define IO_PORT_2_REG 0x02
-
-#define CONFIG_REG 0x03
-#define HOST_POWER_UP BIT(1)
-#define HOST_CMD53_FIN BIT(2)
-
-#define HOST_INT_MASK_REG 0x04
-#define HIM_DISABLE 0xff
-#define HIM_ENABLE (BIT(0) | BIT(1))
-
-#define HOST_INTSTATUS_REG 0x05
-#define UP_LD_HOST_INT_STATUS BIT(0)
-#define DN_LD_HOST_INT_STATUS BIT(1)
-
-/* Card Control Registers */
-#define SQ_READ_BASE_ADDRESS_A0_REG 0x10
-#define SQ_READ_BASE_ADDRESS_A1_REG 0x11
-
-#define CARD_STATUS_REG 0x20
-#define DN_LD_CARD_RDY BIT(0)
-#define CARD_IO_READY BIT(3)
-
-#define CARD_FW_STATUS0_REG 0x40
-#define CARD_FW_STATUS1_REG 0x41
-#define FIRMWARE_READY 0xfedc
-
-#define CARD_RX_LEN_REG 0x42
-#define CARD_RX_UNIT_REG 0x43
-
+/* register bitmasks */
+#define HOST_POWER_UP BIT(1)
+#define HOST_CMD53_FIN BIT(2)
+
+#define HIM_DISABLE 0xff
+#define HIM_ENABLE (BIT(0) | BIT(1))
+
+#define UP_LD_HOST_INT_STATUS BIT(0)
+#define DN_LD_HOST_INT_STATUS BIT(1)
+
+#define DN_LD_CARD_RDY BIT(0)
+#define CARD_IO_READY BIT(3)
+
+#define FIRMWARE_READY 0xfedc
+
+
+struct btmrvl_sdio_card_reg {
+ u8 cfg;
+ u8 host_int_mask;
+ u8 host_intstatus;
+ u8 card_status;
+ u8 sq_read_base_addr_a0;
+ u8 sq_read_base_addr_a1;
+ u8 card_revision;
+ u8 card_fw_status0;
+ u8 card_fw_status1;
+ u8 card_rx_len;
+ u8 card_rx_unit;
+ u8 io_port_0;
+ u8 io_port_1;
+ u8 io_port_2;
+};
struct btmrvl_sdio_card {
struct sdio_func *func;
u32 ioport;
const char *helper;
const char *firmware;
+ const struct btmrvl_sdio_card_reg *reg;
+ u16 sd_blksz_fw_dl;
u8 rx_unit;
struct btmrvl_private *priv;
};
@@ -92,6 +94,8 @@ struct btmrvl_sdio_card {
struct btmrvl_sdio_device {
const char *helper;
const char *firmware;
+ const struct btmrvl_sdio_card_reg *reg;
+ u16 sd_blksz_fw_dl;
};
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 762a5109c68..c2de8951e3f 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -104,6 +104,7 @@ static struct usb_device_id blacklist_table[] = {
/* Atheros 3011 with sflash firmware */
{ USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
+ { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c
index bd34406faaa..4093935ddf4 100644
--- a/drivers/bluetooth/hci_ath.c
+++ b/drivers/bluetooth/hci_ath.c
@@ -201,8 +201,13 @@ static struct sk_buff *ath_dequeue(struct hci_uart *hu)
/* Recv data */
static int ath_recv(struct hci_uart *hu, void *data, int count)
{
- if (hci_recv_stream_fragment(hu->hdev, data, count) < 0)
+ int ret;
+
+ ret = hci_recv_stream_fragment(hu->hdev, data, count);
+ if (ret < 0) {
BT_ERR("Frame Reassembly Failed");
+ return ret;
+ }
return count;
}
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
index 7b8ad93e2c3..2fcd8b387d6 100644
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -151,8 +151,13 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len)
/* Recv data */
static int h4_recv(struct hci_uart *hu, void *data, int count)
{
- if (hci_recv_stream_fragment(hu->hdev, data, count) < 0)
+ int ret;
+
+ ret = hci_recv_stream_fragment(hu->hdev, data, count);
+ if (ret < 0) {
BT_ERR("Frame Reassembly Failed");
+ return ret;
+ }
return count;
}
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 48ad2a7ab08..320f71803a2 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -359,6 +359,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
*/
static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count)
{
+ int ret;
struct hci_uart *hu = (void *)tty->disc_data;
if (!hu || tty != hu->tty)
@@ -368,8 +369,9 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *f
return;
spin_lock(&hu->rx_lock);
- hu->proto->recv(hu, (void *) data, count);
- hu->hdev->stat.byte_rx += count;
+ ret = hu->proto->recv(hu, (void *) data, count);
+ if (ret > 0)
+ hu->hdev->stat.byte_rx += count;
spin_unlock(&hu->rx_lock);
tty_unthrottle(tty);
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
index d9d0e13efe4..a5a49a1baae 100644
--- a/drivers/ieee802154/fakehard.c
+++ b/drivers/ieee802154/fakehard.c
@@ -393,16 +393,6 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
priv = netdev_priv(dev);
priv->phy = phy;
- /*
- * If the name is a format string the caller wants us to do a
- * name allocation.
- */
- if (strchr(dev->name, '%')) {
- err = dev_alloc_name(dev, dev->name);
- if (err < 0)
- goto out;
- }
-
wpan_phy_set_dev(phy, &pdev->dev);
SET_NETDEV_DEV(dev, &phy->dev);
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 4ffc224faa7..8e21d457b89 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -185,15 +185,20 @@ static int addr4_resolve(struct sockaddr_in *src_in,
__be32 dst_ip = dst_in->sin_addr.s_addr;
struct rtable *rt;
struct neighbour *neigh;
+ struct flowi4 fl4;
int ret;
- rt = ip_route_output(&init_net, dst_ip, src_ip, 0, addr->bound_dev_if);
+ memset(&fl4, 0, sizeof(fl4));
+ fl4.daddr = dst_ip;
+ fl4.saddr = src_ip;
+ fl4.flowi4_oif = addr->bound_dev_if;
+ rt = ip_route_output_key(&init_net, &fl4);
if (IS_ERR(rt)) {
ret = PTR_ERR(rt);
goto out;
}
src_in->sin_family = AF_INET;
- src_in->sin_addr.s_addr = rt->rt_src;
+ src_in->sin_addr.s_addr = fl4.saddr;
if (rt->dst.dev->flags & IFF_LOOPBACK) {
ret = rdma_translate_ip((struct sockaddr *) dst_in, addr);
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index 3216bcad7e8..23918413899 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -338,8 +338,9 @@ static struct rtable *find_route(struct t3cdev *dev, __be32 local_ip,
__be16 peer_port, u8 tos)
{
struct rtable *rt;
+ struct flowi4 fl4;
- rt = ip_route_output_ports(&init_net, NULL, peer_ip, local_ip,
+ rt = ip_route_output_ports(&init_net, &fl4, NULL, peer_ip, local_ip,
peer_port, local_port, IPPROTO_TCP,
tos, 0);
if (IS_ERR(rt))
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index d7ee70fc917..f660cd04ec2 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -315,8 +315,9 @@ static struct rtable *find_route(struct c4iw_dev *dev, __be32 local_ip,
__be16 peer_port, u8 tos)
{
struct rtable *rt;
+ struct flowi4 fl4;
- rt = ip_route_output_ports(&init_net, NULL, peer_ip, local_ip,
+ rt = ip_route_output_ports(&init_net, &fl4, NULL, peer_ip, local_ip,
peer_port, local_port, IPPROTO_TCP,
tos, 0);
if (IS_ERR(rt))
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 10d0a5ec9ad..96fa9a4cafd 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -2885,9 +2885,8 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
if ((cqe_errv &
(NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_TCPUDP_CSUM_ERR |
NES_NIC_ERRV_BITS_IPH_ERR | NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) {
- if (nesvnic->rx_checksum_disabled == 0) {
+ if (nesvnic->netdev->features & NETIF_F_RXCSUM)
rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
- }
} else
nes_debug(NES_DBG_CQ, "%s: unsuccessfully checksummed TCP or UDP packet."
" errv = 0x%X, pkt_type = 0x%X.\n",
@@ -2897,7 +2896,7 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
if ((cqe_errv &
(NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_IPH_ERR |
NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) {
- if (nesvnic->rx_checksum_disabled == 0) {
+ if (nesvnic->netdev->features & NETIF_F_RXCSUM) {
rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
/* nes_debug(NES_DBG_CQ, "%s: Reporting successfully checksummed IPv4 packet.\n",
nesvnic->netdev->name); */
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
index d2abe07133a..91594116f94 100644
--- a/drivers/infiniband/hw/nes/nes_hw.h
+++ b/drivers/infiniband/hw/nes/nes_hw.h
@@ -1245,7 +1245,6 @@ struct nes_vnic {
u8 next_qp_nic_index;
u8 of_device_registered;
u8 rdma_enabled;
- u8 rx_checksum_disabled;
u32 lro_max_aggr;
struct net_lro_mgr lro_mgr;
struct net_lro_desc lro_desc[NES_MAX_LRO_DESCRIPTORS];
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index e96b8fb5d44..d3a1c41cfd2 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -1093,34 +1093,6 @@ static const char nes_ethtool_stringset[][ETH_GSTRING_LEN] = {
};
#define NES_ETHTOOL_STAT_COUNT ARRAY_SIZE(nes_ethtool_stringset)
-/**
- * nes_netdev_get_rx_csum
- */
-static u32 nes_netdev_get_rx_csum (struct net_device *netdev)
-{
- struct nes_vnic *nesvnic = netdev_priv(netdev);
-
- if (nesvnic->rx_checksum_disabled)
- return 0;
- else
- return 1;
-}
-
-
-/**
- * nes_netdev_set_rc_csum
- */
-static int nes_netdev_set_rx_csum(struct net_device *netdev, u32 enable)
-{
- struct nes_vnic *nesvnic = netdev_priv(netdev);
-
- if (enable)
- nesvnic->rx_checksum_disabled = 0;
- else
- nesvnic->rx_checksum_disabled = 1;
- return 0;
-}
-
/**
* nes_netdev_get_sset_count
@@ -1521,7 +1493,7 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd
et_cmd->maxrxpkt = 511;
if (nesadapter->OneG_Mode) {
- et_cmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(et_cmd, SPEED_1000);
if (phy_type == NES_PHY_TYPE_PUMA_1G) {
et_cmd->supported = SUPPORTED_1000baseT_Full;
et_cmd->advertising = ADVERTISED_1000baseT_Full;
@@ -1560,7 +1532,7 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd
et_cmd->advertising = ADVERTISED_10000baseT_Full;
et_cmd->phy_address = mac_index;
}
- et_cmd->speed = SPEED_10000;
+ ethtool_cmd_speed_set(et_cmd, SPEED_10000);
et_cmd->autoneg = AUTONEG_DISABLE;
return 0;
}
@@ -1598,19 +1570,10 @@ static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd
}
-static int nes_netdev_set_flags(struct net_device *netdev, u32 flags)
-{
- return ethtool_op_set_flags(netdev, flags, ETH_FLAG_LRO);
-}
-
-
static const struct ethtool_ops nes_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_settings = nes_netdev_get_settings,
.set_settings = nes_netdev_set_settings,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .get_rx_csum = nes_netdev_get_rx_csum,
- .get_sg = ethtool_op_get_sg,
.get_strings = nes_netdev_get_strings,
.get_sset_count = nes_netdev_get_sset_count,
.get_ethtool_stats = nes_netdev_get_ethtool_stats,
@@ -1619,13 +1582,6 @@ static const struct ethtool_ops nes_ethtool_ops = {
.set_coalesce = nes_netdev_set_coalesce,
.get_pauseparam = nes_netdev_get_pauseparam,
.set_pauseparam = nes_netdev_set_pauseparam,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .set_rx_csum = nes_netdev_set_rx_csum,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = ethtool_op_set_tso,
- .get_flags = ethtool_op_get_flags,
- .set_flags = nes_netdev_set_flags,
};
@@ -1727,12 +1683,11 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
netdev->dev_addr[5] = (u8)u64temp;
memcpy(netdev->perm_addr, netdev->dev_addr, 6);
- if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV)) {
- netdev->features |= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
- netdev->features |= NETIF_F_GSO | NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
- } else {
- netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
- }
+ netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_IP_CSUM;
+ if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV))
+ netdev->hw_features |= NETIF_F_TSO;
+ netdev->features |= netdev->hw_features;
+ netdev->hw_features |= NETIF_F_LRO;
nes_debug(NES_DBG_INIT, "nesvnic = %p, reported features = 0x%lX, QPid = %d,"
" nic_index = %d, logical_port = %d, mac_index = %d.\n",
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index ab97f92fc25..7b6985a2e65 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -91,7 +91,6 @@ enum {
IPOIB_STOP_REAPER = 7,
IPOIB_FLAG_ADMIN_CM = 9,
IPOIB_FLAG_UMCAST = 10,
- IPOIB_FLAG_CSUM = 11,
IPOIB_MAX_BACKOFF_SECONDS = 16,
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 93d55806b96..39913a065f9 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -1463,8 +1463,7 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
ipoib_warn(priv, "enabling connected mode "
"will cause multicast packet drops\n");
-
- dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO);
+ netdev_update_features(dev);
rtnl_unlock();
priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
@@ -1474,13 +1473,7 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
if (!strcmp(buf, "datagram\n")) {
clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
-
- if (test_bit(IPOIB_FLAG_CSUM, &priv->flags)) {
- dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
- priv->dev->features |= NETIF_F_GRO;
- if (priv->hca_caps & IB_DEVICE_UD_TSO)
- dev->features |= NETIF_F_TSO;
- }
+ netdev_update_features(dev);
dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu));
rtnl_unlock();
ipoib_flush_paths(dev);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
index 19f7f5206f7..29bc7b5724a 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
@@ -42,32 +42,6 @@ static void ipoib_get_drvinfo(struct net_device *netdev,
strncpy(drvinfo->driver, "ipoib", sizeof(drvinfo->driver) - 1);
}
-static u32 ipoib_get_rx_csum(struct net_device *dev)
-{
- struct ipoib_dev_priv *priv = netdev_priv(dev);
- return test_bit(IPOIB_FLAG_CSUM, &priv->flags) &&
- !test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
-}
-
-static int ipoib_set_tso(struct net_device *dev, u32 data)
-{
- struct ipoib_dev_priv *priv = netdev_priv(dev);
-
- if (data) {
- if (!test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags) &&
- (dev->features & NETIF_F_SG) &&
- (priv->hca_caps & IB_DEVICE_UD_TSO)) {
- dev->features |= NETIF_F_TSO;
- } else {
- ipoib_warn(priv, "can't set TSO on\n");
- return -EOPNOTSUPP;
- }
- } else
- dev->features &= ~NETIF_F_TSO;
-
- return 0;
-}
-
static int ipoib_get_coalesce(struct net_device *dev,
struct ethtool_coalesce *coal)
{
@@ -108,8 +82,6 @@ static int ipoib_set_coalesce(struct net_device *dev,
static const struct ethtool_ops ipoib_ethtool_ops = {
.get_drvinfo = ipoib_get_drvinfo,
- .get_rx_csum = ipoib_get_rx_csum,
- .set_tso = ipoib_set_tso,
.get_coalesce = ipoib_get_coalesce,
.set_coalesce = ipoib_set_coalesce,
};
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 806d0292dc3..81ae61d68a2 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -292,7 +292,7 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
dev->stats.rx_bytes += skb->len;
skb->dev = dev;
- if (test_bit(IPOIB_FLAG_CSUM, &priv->flags) && likely(wc->csum_ok))
+ if ((dev->features & NETIF_F_RXCSUM) && likely(wc->csum_ok))
skb->ip_summed = CHECKSUM_UNNECESSARY;
napi_gro_receive(&priv->napi, skb);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index aca3b44f7ae..86addca9ddf 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -171,6 +171,16 @@ static int ipoib_stop(struct net_device *dev)
return 0;
}
+static u32 ipoib_fix_features(struct net_device *dev, u32 features)
+{
+ struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+ if (test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags))
+ features &= ~(NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+
+ return features;
+}
+
static int ipoib_change_mtu(struct net_device *dev, int new_mtu)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -970,6 +980,7 @@ static const struct net_device_ops ipoib_netdev_ops = {
.ndo_open = ipoib_open,
.ndo_stop = ipoib_stop,
.ndo_change_mtu = ipoib_change_mtu,
+ .ndo_fix_features = ipoib_fix_features,
.ndo_start_xmit = ipoib_start_xmit,
.ndo_tx_timeout = ipoib_timeout,
.ndo_set_multicast_list = ipoib_set_mcast_list,
@@ -1154,19 +1165,18 @@ int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca)
kfree(device_attr);
if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) {
- set_bit(IPOIB_FLAG_CSUM, &priv->flags);
- priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
- }
+ priv->dev->hw_features = NETIF_F_SG |
+ NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
- priv->dev->features |= NETIF_F_GRO;
+ if (priv->hca_caps & IB_DEVICE_UD_TSO)
+ priv->dev->hw_features |= NETIF_F_TSO;
- if (priv->dev->features & NETIF_F_SG && priv->hca_caps & IB_DEVICE_UD_TSO)
- priv->dev->features |= NETIF_F_TSO;
+ priv->dev->features |= priv->dev->hw_features;
+ }
return 0;
}
-
static struct net_device *ipoib_add_port(const char *format,
struct ib_device *hca, u8 port)
{
diff --git a/drivers/isdn/capi/Kconfig b/drivers/isdn/capi/Kconfig
index a168e8a891b..15c3ffd9d86 100644
--- a/drivers/isdn/capi/Kconfig
+++ b/drivers/isdn/capi/Kconfig
@@ -33,21 +33,6 @@ config ISDN_CAPI_CAPI20
standardized libcapi20 to access this functionality. You should say
Y/M here.
-config ISDN_CAPI_CAPIFS_BOOL
- bool "CAPI2.0 filesystem support (DEPRECATED)"
- depends on ISDN_CAPI_MIDDLEWARE && ISDN_CAPI_CAPI20
- help
- This option provides a special file system, similar to /dev/pts with
- device nodes for the special ttys established by using the
- middleware extension above.
- You no longer need this, udev fully replaces it. This feature is
- scheduled for removal.
-
-config ISDN_CAPI_CAPIFS
- tristate
- depends on ISDN_CAPI_CAPIFS_BOOL
- default ISDN_CAPI_CAPI20
-
config ISDN_CAPI_CAPIDRV
tristate "CAPI2.0 capidrv interface support"
depends on ISDN_I4L
diff --git a/drivers/isdn/capi/Makefile b/drivers/isdn/capi/Makefile
index 57123e3e497..4d5b4b71db1 100644
--- a/drivers/isdn/capi/Makefile
+++ b/drivers/isdn/capi/Makefile
@@ -7,7 +7,6 @@
obj-$(CONFIG_ISDN_CAPI) += kernelcapi.o
obj-$(CONFIG_ISDN_CAPI_CAPI20) += capi.o
obj-$(CONFIG_ISDN_CAPI_CAPIDRV) += capidrv.o
-obj-$(CONFIG_ISDN_CAPI_CAPIFS) += capifs.o
# Multipart objects.
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 0d708836703..e44933d5879 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -38,15 +38,10 @@
#include <linux/isdn/capiutil.h>
#include <linux/isdn/capicmd.h>
-#include "capifs.h"
-
MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface");
MODULE_AUTHOR("Carsten Paeth");
MODULE_LICENSE("GPL");
-#undef _DEBUG_TTYFUNCS /* call to tty_driver */
-#undef _DEBUG_DATAFLOW /* data flow */
-
/* -------- driver information -------------------------------------- */
static DEFINE_MUTEX(capi_mutex);
@@ -85,7 +80,6 @@ struct capiminor {
struct kref kref;
unsigned int minor;
- struct dentry *capifs_dentry;
struct capi20_appl *ap;
u32 ncci;
@@ -300,17 +294,8 @@ static void capiminor_free(struct capiminor *mp)
static void capincci_alloc_minor(struct capidev *cdev, struct capincci *np)
{
- struct capiminor *mp;
- dev_t device;
-
- if (!(cdev->userflags & CAPIFLAG_HIGHJACKING))
- return;
-
- mp = np->minorp = capiminor_alloc(&cdev->ap, np->ncci);
- if (mp) {
- device = MKDEV(capinc_tty_driver->major, mp->minor);
- mp->capifs_dentry = capifs_new_ncci(mp->minor, device);
- }
+ if (cdev->userflags & CAPIFLAG_HIGHJACKING)
+ np->minorp = capiminor_alloc(&cdev->ap, np->ncci);
}
static void capincci_free_minor(struct capincci *np)
@@ -319,8 +304,6 @@ static void capincci_free_minor(struct capincci *np)
struct tty_struct *tty;
if (mp) {
- capifs_free_ncci(mp->capifs_dentry);
-
tty = tty_port_tty_get(&mp->port);
if (tty) {
tty_vhangup(tty);
@@ -432,9 +415,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
tty = tty_port_tty_get(&mp->port);
if (!tty) {
-#ifdef _DEBUG_DATAFLOW
- printk(KERN_DEBUG "capi: currently no receiver\n");
-#endif
+ pr_debug("capi: currently no receiver\n");
return -1;
}
@@ -447,23 +428,17 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
}
if (ld->ops->receive_buf == NULL) {
-#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
- printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n");
-#endif
+ pr_debug("capi: ldisc has no receive_buf function\n");
/* fatal error, do not requeue */
goto free_skb;
}
if (mp->ttyinstop) {
-#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
- printk(KERN_DEBUG "capi: recv tty throttled\n");
-#endif
+ pr_debug("capi: recv tty throttled\n");
goto deref_ldisc;
}
if (tty->receive_room < datalen) {
-#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
- printk(KERN_DEBUG "capi: no room in tty\n");
-#endif
+ pr_debug("capi: no room in tty\n");
goto deref_ldisc;
}
@@ -479,10 +454,8 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
if (errcode == CAPI_NOERROR) {
skb_pull(skb, CAPIMSG_LEN(skb->data));
-#ifdef _DEBUG_DATAFLOW
- printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
- datahandle, skb->len);
-#endif
+ pr_debug("capi: DATA_B3_RESP %u len=%d => ldisc\n",
+ datahandle, skb->len);
ld->ops->receive_buf(tty, skb->data, NULL, skb->len);
} else {
printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
@@ -529,9 +502,7 @@ static void handle_minor_send(struct capiminor *mp)
return;
if (mp->ttyoutstop) {
-#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
- printk(KERN_DEBUG "capi: send: tty stopped\n");
-#endif
+ pr_debug("capi: send: tty stopped\n");
tty_kref_put(tty);
return;
}
@@ -573,10 +544,8 @@ static void handle_minor_send(struct capiminor *mp)
}
errcode = capi20_put_message(mp->ap, skb);
if (errcode == CAPI_NOERROR) {
-#ifdef _DEBUG_DATAFLOW
- printk(KERN_DEBUG "capi: DATA_B3_REQ %u len=%u\n",
- datahandle, len);
-#endif
+ pr_debug("capi: DATA_B3_REQ %u len=%u\n",
+ datahandle, len);
continue;
}
capiminor_del_ack(mp, datahandle);
@@ -650,10 +619,8 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
}
if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2);
-#ifdef _DEBUG_DATAFLOW
- printk(KERN_DEBUG "capi_signal: DATA_B3_IND %u len=%d\n",
- datahandle, skb->len-CAPIMSG_LEN(skb->data));
-#endif
+ pr_debug("capi_signal: DATA_B3_IND %u len=%d\n",
+ datahandle, skb->len-CAPIMSG_LEN(skb->data));
skb_queue_tail(&mp->inqueue, skb);
handle_minor_recv(mp);
@@ -661,11 +628,9 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
} else if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF) {
datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4);
-#ifdef _DEBUG_DATAFLOW
- printk(KERN_DEBUG "capi_signal: DATA_B3_CONF %u 0x%x\n",
- datahandle,
- CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2));
-#endif
+ pr_debug("capi_signal: DATA_B3_CONF %u 0x%x\n",
+ datahandle,
+ CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2));
kfree_skb(skb);
capiminor_del_ack(mp, datahandle);
tty = tty_port_tty_get(&mp->port);
@@ -1095,9 +1060,7 @@ static int capinc_tty_write(struct tty_struct *tty,
struct capiminor *mp = tty->driver_data;
struct sk_buff *skb;
-#ifdef _DEBUG_TTYFUNCS
- printk(KERN_DEBUG "capinc_tty_write(count=%d)\n", count);
-#endif
+ pr_debug("capinc_tty_write(count=%d)\n", count);
spin_lock_bh(&mp->outlock);
skb = mp->outskb;
@@ -1133,9 +1096,7 @@ static int capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
struct sk_buff *skb;
int ret = 1;
-#ifdef _DEBUG_TTYFUNCS
- printk(KERN_DEBUG "capinc_put_char(%u)\n", ch);
-#endif
+ pr_debug("capinc_put_char(%u)\n", ch);
spin_lock_bh(&mp->outlock);
skb = mp->outskb;
@@ -1174,9 +1135,7 @@ static void capinc_tty_flush_chars(struct tty_struct *tty)
struct capiminor *mp = tty->driver_data;
struct sk_buff *skb;
-#ifdef _DEBUG_TTYFUNCS
- printk(KERN_DEBUG "capinc_tty_flush_chars\n");
-#endif
+ pr_debug("capinc_tty_flush_chars\n");
spin_lock_bh(&mp->outlock);
skb = mp->outskb;
@@ -1200,9 +1159,7 @@ static int capinc_tty_write_room(struct tty_struct *tty)
room = CAPINC_MAX_SENDQUEUE-skb_queue_len(&mp->outqueue);
room *= CAPI_MAX_BLKSIZE;
-#ifdef _DEBUG_TTYFUNCS
- printk(KERN_DEBUG "capinc_tty_write_room = %d\n", room);
-#endif
+ pr_debug("capinc_tty_write_room = %d\n", room);
return room;
}
@@ -1210,12 +1167,10 @@ static int capinc_tty_chars_in_buffer(struct tty_struct *tty)
{
struct capiminor *mp = tty->driver_data;
-#ifdef _DEBUG_TTYFUNCS
- printk(KERN_DEBUG "capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%d\n",
- mp->outbytes, mp->nack,
- skb_queue_len(&mp->outqueue),
- skb_queue_len(&mp->inqueue));
-#endif
+ pr_debug("capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%d\n",
+ mp->outbytes, mp->nack,
+ skb_queue_len(&mp->outqueue),
+ skb_queue_len(&mp->inqueue));
return mp->outbytes;
}
@@ -1227,17 +1182,13 @@ static int capinc_tty_ioctl(struct tty_struct *tty,
static void capinc_tty_set_termios(struct tty_struct *tty, struct ktermios * old)
{
-#ifdef _DEBUG_TTYFUNCS
- printk(KERN_DEBUG "capinc_tty_set_termios\n");
-#endif
+ pr_debug("capinc_tty_set_termios\n");
}
static void capinc_tty_throttle(struct tty_struct *tty)
{
struct capiminor *mp = tty->driver_data;
-#ifdef _DEBUG_TTYFUNCS
- printk(KERN_DEBUG "capinc_tty_throttle\n");
-#endif
+ pr_debug("capinc_tty_throttle\n");
mp->ttyinstop = 1;
}
@@ -1245,9 +1196,7 @@ static void capinc_tty_unthrottle(struct tty_struct *tty)
{
struct capiminor *mp = tty->driver_data;
-#ifdef _DEBUG_TTYFUNCS
- printk(KERN_DEBUG "capinc_tty_unthrottle\n");
-#endif
+ pr_debug("capinc_tty_unthrottle\n");
mp->ttyinstop = 0;
handle_minor_recv(mp);
}
@@ -1256,9 +1205,7 @@ static void capinc_tty_stop(struct tty_struct *tty)
{
struct capiminor *mp = tty->driver_data;
-#ifdef _DEBUG_TTYFUNCS
- printk(KERN_DEBUG "capinc_tty_stop\n");
-#endif
+ pr_debug("capinc_tty_stop\n");
mp->ttyoutstop = 1;
}
@@ -1266,9 +1213,7 @@ static void capinc_tty_start(struct tty_struct *tty)
{
struct capiminor *mp = tty->driver_data;
-#ifdef _DEBUG_TTYFUNCS
- printk(KERN_DEBUG "capinc_tty_start\n");
-#endif
+ pr_debug("capinc_tty_start\n");
mp->ttyoutstop = 0;
handle_minor_send(mp);
}
@@ -1277,39 +1222,29 @@ static void capinc_tty_hangup(struct tty_struct *tty)
{
struct capiminor *mp = tty->driver_data;
-#ifdef _DEBUG_TTYFUNCS
- printk(KERN_DEBUG "capinc_tty_hangup\n");
-#endif
+ pr_debug("capinc_tty_hangup\n");
tty_port_hangup(&mp->port);
}
static int capinc_tty_break_ctl(struct tty_struct *tty, int state)
{
-#ifdef _DEBUG_TTYFUNCS
- printk(KERN_DEBUG "capinc_tty_break_ctl(%d)\n", state);
-#endif
+ pr_debug("capinc_tty_break_ctl(%d)\n", state);
return 0;
}
static void capinc_tty_flush_buffer(struct tty_struct *tty)
{
-#ifdef _DEBUG_TTYFUNCS
- printk(KERN_DEBUG "capinc_tty_flush_buffer\n");
-#endif
+ pr_debug("capinc_tty_flush_buffer\n");
}
static void capinc_tty_set_ldisc(struct tty_struct *tty)
{
-#ifdef _DEBUG_TTYFUNCS
- printk(KERN_DEBUG "capinc_tty_set_ldisc\n");
-#endif
+ pr_debug("capinc_tty_set_ldisc\n");
}
static void capinc_tty_send_xchar(struct tty_struct *tty, char ch)
{
-#ifdef _DEBUG_TTYFUNCS
- printk(KERN_DEBUG "capinc_tty_send_xchar(%d)\n", ch);
-#endif
+ pr_debug("capinc_tty_send_xchar(%d)\n", ch);
}
static const struct tty_operations capinc_ops = {
@@ -1514,10 +1449,8 @@ static int __init capi_init(void)
proc_init();
-#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
- compileinfo = " (middleware+capifs)";
-#elif defined(CONFIG_ISDN_CAPI_MIDDLEWARE)
- compileinfo = " (no capifs)";
+#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
+ compileinfo = " (middleware)";
#else
compileinfo = " (no middleware)";
#endif
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
deleted file mode 100644
index b4faed7fe0d..00000000000
--- a/drivers/isdn/capi/capifs.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/* $Id: capifs.c,v 1.1.2.3 2004/01/16 21:09:26 keil Exp $
- *
- * Copyright 2000 by Carsten Paeth <calle@calle.de>
- *
- * Heavily based on devpts filesystem from H. Peter Anvin
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/fs.h>
-#include <linux/mount.h>
-#include <linux/slab.h>
-#include <linux/namei.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/ctype.h>
-#include <linux/sched.h> /* current */
-
-#include "capifs.h"
-
-MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem");
-MODULE_AUTHOR("Carsten Paeth");
-MODULE_LICENSE("GPL");
-
-/* ------------------------------------------------------------------ */
-
-#define CAPIFS_SUPER_MAGIC (('C'<<8)|'N')
-
-static struct vfsmount *capifs_mnt;
-static int capifs_mnt_count;
-
-static struct {
- int setuid;
- int setgid;
- uid_t uid;
- gid_t gid;
- umode_t mode;
-} config = {.mode = 0600};
-
-/* ------------------------------------------------------------------ */
-
-static int capifs_remount(struct super_block *s, int *flags, char *data)
-{
- int setuid = 0;
- int setgid = 0;
- uid_t uid = 0;
- gid_t gid = 0;
- umode_t mode = 0600;
- char *this_char;
- char *new_opt = kstrdup(data, GFP_KERNEL);
-
- this_char = NULL;
- while ((this_char = strsep(&data, ",")) != NULL) {
- int n;
- char dummy;
- if (!*this_char)
- continue;
- if (sscanf(this_char, "uid=%i%c", &n, &dummy) == 1) {
- setuid = 1;
- uid = n;
- } else if (sscanf(this_char, "gid=%i%c", &n, &dummy) == 1) {
- setgid = 1;
- gid = n;
- } else if (sscanf(this_char, "mode=%o%c", &n, &dummy) == 1)
- mode = n & ~S_IFMT;
- else {
- kfree(new_opt);
- printk("capifs: called with bogus options\n");
- return -EINVAL;
- }
- }
-
- mutex_lock(&s->s_root->d_inode->i_mutex);
-
- replace_mount_options(s, new_opt);
- config.setuid = setuid;
- config.setgid = setgid;
- config.uid = uid;
- config.gid = gid;
- config.mode = mode;
-
- mutex_unlock(&s->s_root->d_inode->i_mutex);
-
- return 0;
-}
-
-static const struct super_operations capifs_sops =
-{
- .statfs = simple_statfs,
- .remount_fs = capifs_remount,
- .show_options = generic_show_options,
-};
-
-
-static int
-capifs_fill_super(struct super_block *s, void *data, int silent)
-{
- struct inode * inode;
-
- s->s_blocksize = 1024;
- s->s_blocksize_bits = 10;
- s->s_magic = CAPIFS_SUPER_MAGIC;
- s->s_op = &capifs_sops;
- s->s_time_gran = 1;
-
- inode = new_inode(s);
- if (!inode)
- goto fail;
- inode->i_ino = 1;
- inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
- inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
- inode->i_op = &simple_dir_inode_operations;
- inode->i_fop = &simple_dir_operations;
- inode->i_nlink = 2;
-
- s->s_root = d_alloc_root(inode);
- if (s->s_root)
- return 0;
-
- printk("capifs: get root dentry failed\n");
- iput(inode);
-fail:
- return -ENOMEM;
-}
-
-static struct dentry *capifs_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data)
-{
- return mount_single(fs_type, flags, data, capifs_fill_super);
-}
-
-static struct file_system_type capifs_fs_type = {
- .owner = THIS_MODULE,
- .name = "capifs",
- .mount = capifs_mount,
- .kill_sb = kill_anon_super,
-};
-
-static struct dentry *new_ncci(unsigned int number, dev_t device)
-{
- struct super_block *s = capifs_mnt->mnt_sb;
- struct dentry *root = s->s_root;
- struct dentry *dentry;
- struct inode *inode;
- char name[10];
- int namelen;
-
- mutex_lock(&root->d_inode->i_mutex);
-
- namelen = sprintf(name, "%d", number);
- dentry = lookup_one_len(name, root, namelen);
- if (IS_ERR(dentry)) {
- dentry = NULL;
- goto unlock_out;
- }
-
- if (dentry->d_inode) {
- dput(dentry);
- dentry = NULL;
- goto unlock_out;
- }
-
- inode = new_inode(s);
- if (!inode) {
- dput(dentry);
- dentry = NULL;
- goto unlock_out;
- }
-
- /* config contents is protected by root's i_mutex */
- inode->i_uid = config.setuid ? config.uid : current_fsuid();
- inode->i_gid = config.setgid ? config.gid : current_fsgid();
- inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
- inode->i_ino = number + 2;
- init_special_inode(inode, S_IFCHR|config.mode, device);
-
- d_instantiate(dentry, inode);
- dget(dentry);
-
-unlock_out:
- mutex_unlock(&root->d_inode->i_mutex);
-
- return dentry;
-}
-
-struct dentry *capifs_new_ncci(unsigned int number, dev_t device)
-{
- struct dentry *dentry;
-
- if (simple_pin_fs(&capifs_fs_type, &capifs_mnt, &capifs_mnt_count) < 0)
- return NULL;
-
- dentry = new_ncci(number, device);
- if (!dentry)
- simple_release_fs(&capifs_mnt, &capifs_mnt_count);
-
- return dentry;
-}
-
-void capifs_free_ncci(struct dentry *dentry)
-{
- struct dentry *root = capifs_mnt->mnt_sb->s_root;
- struct inode *inode;
-
- if (!dentry)
- return;
-
- mutex_lock(&root->d_inode->i_mutex);
-
- inode = dentry->d_inode;
- if (inode) {
- drop_nlink(inode);
- d_delete(dentry);
- dput(dentry);
- }
- dput(dentry);
-
- mutex_unlock(&root->d_inode->i_mutex);
-
- simple_release_fs(&capifs_mnt, &capifs_mnt_count);
-}
-
-static int __init capifs_init(void)
-{
- return register_filesystem(&capifs_fs_type);
-}
-
-static void __exit capifs_exit(void)
-{
- unregister_filesystem(&capifs_fs_type);
-}
-
-EXPORT_SYMBOL(capifs_new_ncci);
-EXPORT_SYMBOL(capifs_free_ncci);
-
-module_init(capifs_init);
-module_exit(capifs_exit);
diff --git a/drivers/isdn/capi/capifs.h b/drivers/isdn/capi/capifs.h
deleted file mode 100644
index e193d118953..00000000000
--- a/drivers/isdn/capi/capifs.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* $Id: capifs.h,v 1.1.2.2 2004/01/16 21:09:26 keil Exp $
- *
- * Copyright 2000 by Carsten Paeth <calle@calle.de>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/dcache.h>
-
-#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
-
-struct dentry *capifs_new_ncci(unsigned int num, dev_t device);
-void capifs_free_ncci(struct dentry *dentry);
-
-#else
-
-static inline struct dentry *capifs_new_ncci(unsigned int num, dev_t device)
-{
- return NULL;
-}
-
-static inline void capifs_free_ncci(struct dentry *dentry)
-{
-}
-
-#endif
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 8a3c5cfc4fe..3913f47ef86 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -1157,7 +1157,6 @@ static void write_iso_tasklet(unsigned long data)
struct urb *urb;
int status;
struct usb_iso_packet_descriptor *ifd;
- int offset;
unsigned long flags;
int i;
struct sk_buff *skb;
@@ -1225,7 +1224,6 @@ static void write_iso_tasklet(unsigned long data)
* successfully sent
* - all following frames are not sent at all
*/
- offset = done->limit; /* default (no error) */
for (i = 0; i < BAS_NUMFRAMES; i++) {
ifd = &urb->iso_frame_desc[i];
if (ifd->status ||
@@ -1235,9 +1233,6 @@ static void write_iso_tasklet(unsigned long data)
i, ifd->actual_length,
ifd->length,
get_usb_statmsg(ifd->status));
- offset = (ifd->offset +
- ifd->actual_length)
- % BAS_OUTBUFSIZE;
break;
}
}
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index a14187605f5..ba74646cf0e 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -390,12 +390,12 @@ static const struct zsau_resp_t {
*/
static int cid_of_response(char *s)
{
- unsigned long cid;
+ int cid;
int rc;
if (s[-1] != ';')
return 0; /* no CID separator */
- rc = strict_strtoul(s, 10, &cid);
+ rc = kstrtoint(s, 10, &cid);
if (rc)
return 0; /* CID not numeric */
if (cid < 1 || cid > 65535)
@@ -566,27 +566,19 @@ void gigaset_handle_modem_response(struct cardstate *cs)
case RT_ZCAU:
event->parameter = -1;
if (curarg + 1 < params) {
- unsigned long type, value;
-
- i = strict_strtoul(argv[curarg++], 16, &type);
- j = strict_strtoul(argv[curarg++], 16, &value);
+ u8 type, value;
- if (i == 0 && type < 256 &&
- j == 0 && value < 256)
+ i = kstrtou8(argv[curarg++], 16, &type);
+ j = kstrtou8(argv[curarg++], 16, &value);
+ if (i == 0 && j == 0)
event->parameter = (type << 8) | value;
} else
curarg = params - 1;
break;
case RT_NUMBER:
- event->parameter = -1;
- if (curarg < params) {
- unsigned long res;
- int rc;
-
- rc = strict_strtoul(argv[curarg++], 10, &res);
- if (rc == 0)
- event->parameter = res;
- }
+ if (curarg >= params ||
+ kstrtoint(argv[curarg++], 10, &event->parameter))
+ event->parameter = -1;
gig_dbg(DEBUG_EVENT, "parameter==%d", event->parameter);
break;
}
diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c
index 36264012088..7a9894cb455 100644
--- a/drivers/isdn/hardware/eicon/debug.c
+++ b/drivers/isdn/hardware/eicon/debug.c
@@ -861,7 +861,7 @@ static int diva_get_idi_adapter_info (IDI_CALL request, dword* serial, dword* lo
void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) {
diva_os_spin_lock_magic_t old_irql, old_irql1;
dword sec, usec, logical, serial, org_mask;
- int id, best_id = 0, free_id = -1;
+ int id, free_id = -1;
char tmp[128];
diva_dbg_entry_head_t* pmsg = NULL;
int len;
@@ -906,7 +906,6 @@ void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) {
and slot is still free - reuse it
*/
free_id = id;
- best_id = 1;
break;
}
}
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
index 8c5c563c4f1..a3395986df3 100644
--- a/drivers/isdn/hardware/eicon/message.c
+++ b/drivers/isdn/hardware/eicon/message.c
@@ -1198,7 +1198,6 @@ static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
word ch;
word i;
word Info;
- word CIP;
byte LinkLayer;
API_PARSE * ai;
API_PARSE * bp;
@@ -1340,7 +1339,6 @@ static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
add_s(plci,BC,&parms[6]);
add_s(plci,LLC,&parms[7]);
add_s(plci,HLC,&parms[8]);
- CIP = GET_WORD(parms[0].info);
if (a->Info_Mask[appl->Id-1] & 0x200)
{
/* early B3 connect (CIP mask bit 9) no release after a disc */
@@ -4830,7 +4828,6 @@ static void sig_ind(PLCI *plci)
dword x_Id;
dword Id;
dword rId;
- word Number = 0;
word i;
word cip;
dword cip_mask;
@@ -5106,7 +5103,7 @@ static void sig_ind(PLCI *plci)
}
}
- if(plci->appl) Number = plci->appl->Number++;
+ if(plci->appl) plci->appl->Number++;
switch(plci->Sig.Ind) {
/* Response to Get_Supported_Services request */
@@ -5894,7 +5891,6 @@ static void sig_ind(PLCI *plci)
break;
case TEL_CTRL:
- Number = 0;
ie = multi_fac_parms[0]; /* inspect the facility hook indications */
if(plci->State==ADVANCED_VOICE_SIG && ie[0]){
switch (ie[1]&0x91) {
@@ -10119,14 +10115,12 @@ static byte dtmf_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
static void dtmf_confirmation (dword Id, PLCI *plci)
{
- word Info;
word i;
byte result[4];
dbug (1, dprintf ("[%06lx] %s,%d: dtmf_confirmation",
UnMapId (Id), (char *)(FILE_), __LINE__));
- Info = GOOD;
result[0] = 2;
PUT_WORD (&result[1], DTMF_SUCCESS);
if (plci->dtmf_send_requests != 0)
@@ -11520,13 +11514,12 @@ static word mixer_restore_config (dword Id, PLCI *plci, byte Rc)
static void mixer_command (dword Id, PLCI *plci, byte Rc)
{
DIVA_CAPI_ADAPTER *a;
- word i, internal_command, Info;
+ word i, internal_command;
dbug (1, dprintf ("[%06lx] %s,%d: mixer_command %02x %04x %04x",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command,
plci->li_cmd));
- Info = GOOD;
a = plci->adapter;
internal_command = plci->internal_command;
plci->internal_command = 0;
@@ -11550,7 +11543,6 @@ static void mixer_command (dword Id, PLCI *plci, byte Rc)
{
dbug (1, dprintf ("[%06lx] %s,%d: Load mixer failed",
UnMapId (Id), (char *)(FILE_), __LINE__));
- Info = _FACILITY_NOT_SUPPORTED;
break;
}
if (plci->internal_command)
@@ -11592,7 +11584,6 @@ static void mixer_command (dword Id, PLCI *plci, byte Rc)
} while ((plci->li_plci_b_write_pos != plci->li_plci_b_req_pos)
&& !(plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG));
}
- Info = _FACILITY_NOT_SUPPORTED;
break;
}
if (plci->internal_command)
@@ -11610,7 +11601,6 @@ static void mixer_command (dword Id, PLCI *plci, byte Rc)
{
dbug (1, dprintf ("[%06lx] %s,%d: Unload mixer failed",
UnMapId (Id), (char *)(FILE_), __LINE__));
- Info = _FACILITY_NOT_SUPPORTED;
break;
}
if (plci->internal_command)
@@ -12448,13 +12438,11 @@ static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
static void mixer_indication_coefs_set (dword Id, PLCI *plci)
{
dword d;
- DIVA_CAPI_ADAPTER *a;
byte result[12];
dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_coefs_set",
UnMapId (Id), (char *)(FILE_), __LINE__));
- a = plci->adapter;
if (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos)
{
do
@@ -14111,13 +14099,11 @@ static void select_b_command (dword Id, PLCI *plci, byte Rc)
static void fax_connect_ack_command (dword Id, PLCI *plci, byte Rc)
{
- word Info;
word internal_command;
dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_ack_command %02x %04x",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
- Info = GOOD;
internal_command = plci->internal_command;
plci->internal_command = 0;
switch (internal_command)
@@ -14160,13 +14146,11 @@ static void fax_connect_ack_command (dword Id, PLCI *plci, byte Rc)
static void fax_edata_ack_command (dword Id, PLCI *plci, byte Rc)
{
- word Info;
word internal_command;
dbug (1, dprintf ("[%06lx] %s,%d: fax_edata_ack_command %02x %04x",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
- Info = GOOD;
internal_command = plci->internal_command;
plci->internal_command = 0;
switch (internal_command)
@@ -14395,13 +14379,11 @@ static void rtp_connect_b3_req_command (dword Id, PLCI *plci, byte Rc)
static void rtp_connect_b3_res_command (dword Id, PLCI *plci, byte Rc)
{
- word Info;
word internal_command;
dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
- Info = GOOD;
internal_command = plci->internal_command;
plci->internal_command = 0;
switch (internal_command)
@@ -14423,7 +14405,6 @@ static void rtp_connect_b3_res_command (dword Id, PLCI *plci, byte Rc)
{
dbug (1, dprintf ("[%06lx] %s,%d: RTP setting connect resp info failed %02x",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
- Info = _WRONG_STATE;
break;
}
if (plci_nl_busy (plci))
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index 4343abac0b1..b01a7be1300 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -405,7 +405,7 @@ hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz,
u_char *bdata, int count)
{
u_char *ptr, *ptr1, new_f2;
- int total, maxlen, new_z2;
+ int maxlen, new_z2;
struct zt *zp;
if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO))
@@ -431,7 +431,6 @@ hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz,
printk(KERN_WARNING "HFCPCI: receive out of memory\n");
return;
}
- total = count;
count -= 3;
ptr = skb_put(bch->rx_skb, count);
@@ -968,7 +967,6 @@ static void
ph_state_nt(struct dchannel *dch)
{
struct hfc_pci *hc = dch->hw;
- u_char val;
if (dch->debug)
printk(KERN_DEBUG "%s: NT newstate %x\n",
@@ -982,7 +980,7 @@ ph_state_nt(struct dchannel *dch)
hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
/* Clear already pending ints */
- val = Read_hfc(hc, HFCPCI_INT_S1);
+ (void) Read_hfc(hc, HFCPCI_INT_S1);
Write_hfc(hc, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE);
udelay(10);
Write_hfc(hc, HFCPCI_STATES, 4);
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
index 8700474747e..3ccbff13eaf 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -118,14 +118,12 @@ static void
ctrl_complete(struct urb *urb)
{
struct hfcsusb *hw = (struct hfcsusb *) urb->context;
- struct ctrl_buf *buf;
if (debug & DBG_HFC_CALL_TRACE)
printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
urb->dev = hw->dev;
if (hw->ctrl_cnt) {
- buf = &hw->ctrl_buff[hw->ctrl_out_idx];
hw->ctrl_cnt--; /* decrement actual count */
if (++hw->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
hw->ctrl_out_idx = 0; /* pointer wrap */
@@ -1726,7 +1724,6 @@ hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel)
static int
setup_hfcsusb(struct hfcsusb *hw)
{
- int err;
u_char b;
if (debug & DBG_HFC_CALL_TRACE)
@@ -1745,7 +1742,7 @@ setup_hfcsusb(struct hfcsusb *hw)
}
/* first set the needed config, interface and alternate */
- err = usb_set_interface(hw->dev, hw->if_used, hw->alt_used);
+ (void) usb_set_interface(hw->dev, hw->if_used, hw->alt_used);
hw->led_state = 0;
diff --git a/drivers/isdn/hisax/arcofi.c b/drivers/isdn/hisax/arcofi.c
index 85a8fd8dd0b..21cbbe1d556 100644
--- a/drivers/isdn/hisax/arcofi.c
+++ b/drivers/isdn/hisax/arcofi.c
@@ -30,8 +30,6 @@ add_arcofi_timer(struct IsdnCardState *cs) {
static void
send_arcofi(struct IsdnCardState *cs) {
- u_char val;
-
add_arcofi_timer(cs);
cs->dc.isac.mon_txp = 0;
cs->dc.isac.mon_txc = cs->dc.isac.arcofi_list->len;
@@ -45,7 +43,7 @@ send_arcofi(struct IsdnCardState *cs) {
cs->dc.isac.mocr &= 0x0f;
cs->dc.isac.mocr |= 0xa0;
cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
- val = cs->readisac(cs, ISAC_MOSR);
+ (void) cs->readisac(cs, ISAC_MOSR);
cs->writeisac(cs, ISAC_MOX1, cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]);
cs->dc.isac.mocr |= 0x10;
cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index 496d477af0f..9e5e87be756 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -129,12 +129,10 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
static int __devinit elsa_cs_config(struct pcmcia_device *link)
{
- local_info_t *dev;
int i;
IsdnCard_t icard;
dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
- dev = link->priv;
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c
index cbda3790a10..3fa9f617109 100644
--- a/drivers/isdn/hisax/elsa_ser.c
+++ b/drivers/isdn/hisax/elsa_ser.c
@@ -109,11 +109,10 @@ static void change_speed(struct IsdnCardState *cs, int baud)
{
int quot = 0, baud_base;
unsigned cval, fcr = 0;
- int bits;
/* byte size and parity */
- cval = 0x03; bits = 10;
+ cval = 0x03;
/* Determine divisor based on baud rate */
baud_base = BASE_BAUD;
quot = baud_base / baud;
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index ed9527aa5f2..f407de0e006 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -258,11 +258,9 @@ static void
ctrl_complete(struct urb *urb)
{
hfcusb_data *hfc = (hfcusb_data *) urb->context;
- ctrl_buft *buf;
urb->dev = hfc->dev;
if (hfc->ctrl_cnt) {
- buf = &hfc->ctrl_buff[hfc->ctrl_out_idx];
hfc->ctrl_cnt--; /* decrement actual count */
if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
hfc->ctrl_out_idx = 0; /* pointer wrap */
@@ -1097,7 +1095,7 @@ static int
hfc_usb_init(hfcusb_data * hfc)
{
usb_fifo *fifo;
- int i, err;
+ int i;
u_char b;
struct hisax_b_if *p_b_if[2];
@@ -1112,7 +1110,7 @@ hfc_usb_init(hfcusb_data * hfc)
}
/* first set the needed config, interface and alternate */
- err = usb_set_interface(hfc->dev, hfc->if_used, hfc->alt_used);
+ usb_set_interface(hfc->dev, hfc->if_used, hfc->alt_used);
/* do Chip reset */
write_usb(hfc, HFCUSB_CIRM, 8);
diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c
index 332104103e1..69084044418 100644
--- a/drivers/isdn/hisax/ipacx.c
+++ b/drivers/isdn/hisax/ipacx.c
@@ -96,7 +96,7 @@ dch_l2l1(struct PStack *st, int pr, void *arg)
{
struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
struct sk_buff *skb = arg;
- u_char cda1_cr, cda2_cr;
+ u_char cda1_cr;
switch (pr) {
case (PH_DATA |REQUEST):
@@ -163,7 +163,7 @@ dch_l2l1(struct PStack *st, int pr, void *arg)
cs->writeisac(cs, IPACX_CDA_TSDP10, 0x80); // Timeslot 0 is B1
cs->writeisac(cs, IPACX_CDA_TSDP11, 0x81); // Timeslot 0 is B1
cda1_cr = cs->readisac(cs, IPACX_CDA1_CR);
- cda2_cr = cs->readisac(cs, IPACX_CDA2_CR);
+ (void) cs->readisac(cs, IPACX_CDA2_CR);
if ((long)arg &1) { // loop B1
cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x0a);
}
diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c
index ea8f840871d..a06cea09158 100644
--- a/drivers/isdn/hisax/jade.c
+++ b/drivers/isdn/hisax/jade.c
@@ -23,10 +23,9 @@
int
JadeVersion(struct IsdnCardState *cs, char *s)
{
- int ver,i;
+ int ver;
int to = 50;
cs->BC_Write_Reg(cs, -1, 0x50, 0x19);
- i=0;
while (to) {
udelay(1);
ver = cs->BC_Read_Reg(cs, -1, 0x60);
diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c
index 8e2fd02ecce..b0d9ab1f21c 100644
--- a/drivers/isdn/hisax/l3dss1.c
+++ b/drivers/isdn/hisax/l3dss1.c
@@ -2943,7 +2943,7 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
static void
dss1up(struct PStack *st, int pr, void *arg)
{
- int i, mt, cr, cause, callState;
+ int i, mt, cr, callState;
char *ptr;
u_char *p;
struct sk_buff *skb = arg;
@@ -3034,12 +3034,10 @@ dss1up(struct PStack *st, int pr, void *arg)
return;
}
} else if (mt == MT_STATUS) {
- cause = 0;
if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {
ptr++;
if (*ptr++ == 2)
ptr++;
- cause = *ptr & 0x7f;
}
callState = 0;
if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) {
diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c
index 7b229c0ce11..092dcbb39d9 100644
--- a/drivers/isdn/hisax/l3ni1.c
+++ b/drivers/isdn/hisax/l3ni1.c
@@ -2883,7 +2883,7 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
static void
ni1up(struct PStack *st, int pr, void *arg)
{
- int i, mt, cr, cause, callState;
+ int i, mt, cr, callState;
char *ptr;
u_char *p;
struct sk_buff *skb = arg;
@@ -2986,12 +2986,10 @@ ni1up(struct PStack *st, int pr, void *arg)
return;
}
} else if (mt == MT_STATUS) {
- cause = 0;
if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {
ptr++;
if (*ptr++ == 2)
ptr++;
- cause = *ptr & 0x7f;
}
callState = 0;
if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) {
diff --git a/drivers/isdn/hisax/st5481.h b/drivers/isdn/hisax/st5481.h
index 64f78a8c28c..b9054cb7a0d 100644
--- a/drivers/isdn/hisax/st5481.h
+++ b/drivers/isdn/hisax/st5481.h
@@ -377,7 +377,6 @@ struct st5481_bcs {
};
struct st5481_adapter {
- struct list_head list;
int number_of_leds;
struct usb_device *usb_dev;
struct hisax_d_if hisax_d_if;
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
index 13751237bfc..9f7fd18ff77 100644
--- a/drivers/isdn/hisax/st5481_init.c
+++ b/drivers/isdn/hisax/st5481_init.c
@@ -46,8 +46,6 @@ module_param(debug, int, 0);
#endif
int st5481_debug;
-static LIST_HEAD(adapter_list);
-
/* ======================================================================
* registration/deregistration with the USB layer
*/
@@ -86,7 +84,6 @@ static int probe_st5481(struct usb_interface *intf,
adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i];
adapter->bcs[i].b_if.ifc.l2l1 = st5481_b_l2l1;
}
- list_add(&adapter->list, &adapter_list);
retval = st5481_setup_usb(adapter);
if (retval < 0)
@@ -125,6 +122,7 @@ static int probe_st5481(struct usb_interface *intf,
err_usb:
st5481_release_usb(adapter);
err:
+ kfree(adapter);
return -EIO;
}
@@ -142,8 +140,6 @@ static void disconnect_st5481(struct usb_interface *intf)
if (!adapter)
return;
- list_del(&adapter->list);
-
st5481_stop(adapter);
st5481_release_b(&adapter->bcs[1]);
st5481_release_b(&adapter->bcs[0]);
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index aa25e183bf7..360f9ec7c80 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -111,12 +111,10 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
static int __devinit teles_cs_config(struct pcmcia_device *link)
{
- local_info_t *dev;
int i;
IsdnCard_t icard;
dev_dbg(&link->dev, "teles_config(0x%p)\n", link);
- dev = link->priv;
i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
if (i != 0)
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 2ee93d04b2d..236cc7dadfd 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -155,7 +155,6 @@ put_log_buffer(hysdn_card * card, char *cp)
static ssize_t
hysdn_log_write(struct file *file, const char __user *buf, size_t count, loff_t * off)
{
- unsigned long u = 0;
int rc;
unsigned char valbuf[128];
hysdn_card *card = file->private_data;
@@ -167,12 +166,10 @@ hysdn_log_write(struct file *file, const char __user *buf, size_t count, loff_t
valbuf[count] = 0; /* terminating 0 */
- rc = strict_strtoul(valbuf, 0, &u);
-
- if (rc == 0) {
- card->debug_flags = u; /* remember debug flags */
- hysdn_addlog(card, "debug set to 0x%lx", card->debug_flags);
- }
+ rc = kstrtoul(valbuf, 0, &card->debug_flags);
+ if (rc < 0)
+ return rc;
+ hysdn_addlog(card, "debug set to 0x%lx", card->debug_flags);
return (count);
} /* hysdn_log_write */
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 15632bd2f64..6ed82add6ff 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -399,13 +399,8 @@ isdn_all_eaz(int di, int ch)
#include <linux/isdn/capicmd.h>
static int
-isdn_capi_rec_hl_msg(capi_msg *cm) {
-
- int di;
- int ch;
-
- di = (cm->adr.Controller & 0x7f) -1;
- ch = isdn_dc2minor(di, (cm->adr.Controller>>8)& 0x7f);
+isdn_capi_rec_hl_msg(capi_msg *cm)
+{
switch(cm->Command) {
case CAPI_FACILITY:
/* in the moment only handled in tty */
@@ -1278,7 +1273,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
uint minor = iminor(file->f_path.dentry->d_inode);
isdn_ctrl c;
int drvidx;
- int chidx;
int ret;
int i;
char __user *p;
@@ -1340,7 +1334,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
drvidx = isdn_minor2drv(minor);
if (drvidx < 0)
return -ENODEV;
- chidx = isdn_minor2chan(minor);
if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING))
return -ENODEV;
return 0;
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index 2a7d17c1948..97988111e45 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -1678,7 +1678,6 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
u32 your_seq;
__be32 local;
__be32 *addr, *mask;
- u16 unused;
if (skb->len < 14)
return;
@@ -1722,7 +1721,6 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
lp->cisco_last_slarp_in = jiffies;
my_seq = be32_to_cpup((__be32 *)(p + 0));
your_seq = be32_to_cpup((__be32 *)(p + 4));
- unused = be16_to_cpup((__be16 *)(p + 8));
p += 10;
lp->cisco_yourseq = my_seq;
lp->cisco_mineseen = your_seq;
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 607d846ae06..d8504279e50 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -998,7 +998,6 @@ isdn_tty_change_speed(modem_info * info)
{
uint cflag,
cval,
- fcr,
quot;
int i;
@@ -1037,7 +1036,6 @@ isdn_tty_change_speed(modem_info * info)
cval |= UART_LCR_PARITY;
if (!(cflag & PARODD))
cval |= UART_LCR_EPAR;
- fcr = 0;
/* CTS flow control flag and modem status interrupts */
if (cflag & CRTSCTS) {
diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c
index d0aeb44ee7c..5bc00156315 100644
--- a/drivers/isdn/mISDN/layer2.c
+++ b/drivers/isdn/mISDN/layer2.c
@@ -1640,7 +1640,7 @@ l2_tei_remove(struct FsmInst *fi, int event, void *arg)
}
static void
-l2_st14_persistant_da(struct FsmInst *fi, int event, void *arg)
+l2_st14_persistent_da(struct FsmInst *fi, int event, void *arg)
{
struct layer2 *l2 = fi->userdata;
struct sk_buff *skb = arg;
@@ -1654,7 +1654,7 @@ l2_st14_persistant_da(struct FsmInst *fi, int event, void *arg)
}
static void
-l2_st5_persistant_da(struct FsmInst *fi, int event, void *arg)
+l2_st5_persistent_da(struct FsmInst *fi, int event, void *arg)
{
struct layer2 *l2 = fi->userdata;
struct sk_buff *skb = arg;
@@ -1671,7 +1671,7 @@ l2_st5_persistant_da(struct FsmInst *fi, int event, void *arg)
}
static void
-l2_st6_persistant_da(struct FsmInst *fi, int event, void *arg)
+l2_st6_persistent_da(struct FsmInst *fi, int event, void *arg)
{
struct layer2 *l2 = fi->userdata;
struct sk_buff *skb = arg;
@@ -1685,7 +1685,7 @@ l2_st6_persistant_da(struct FsmInst *fi, int event, void *arg)
}
static void
-l2_persistant_da(struct FsmInst *fi, int event, void *arg)
+l2_persistent_da(struct FsmInst *fi, int event, void *arg)
{
struct layer2 *l2 = fi->userdata;
struct sk_buff *skb = arg;
@@ -1829,14 +1829,14 @@ static struct FsmNode L2FnList[] =
{ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error},
{ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest},
{ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest},
- {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistant_da},
+ {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistent_da},
{ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove},
{ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove},
- {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistant_da},
- {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistant_da},
- {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistant_da},
- {ST_L2_7, EV_L1_DEACTIVATE, l2_persistant_da},
- {ST_L2_8, EV_L1_DEACTIVATE, l2_persistant_da},
+ {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistent_da},
+ {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistent_da},
+ {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistent_da},
+ {ST_L2_7, EV_L1_DEACTIVATE, l2_persistent_da},
+ {ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da},
};
static int
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index 7446d8b4282..8e325227b4c 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -457,6 +457,9 @@ static int data_sock_getsockopt(struct socket *sock, int level, int optname,
if (get_user(len, optlen))
return -EFAULT;
+ if (len != sizeof(char))
+ return -EINVAL;
+
switch (optname) {
case MISDN_TIME_STAMP:
if (_pms(sk)->cmask & MISDN_TIME_STAMP)
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index 91abb965fb4..5f25889e27e 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -185,7 +185,7 @@ static int max_interrupt_work = 10;
static int nopnp;
#endif
-static int __devinit el3_common_init(struct net_device *dev);
+static int el3_common_init(struct net_device *dev);
static void el3_common_remove(struct net_device *dev);
static ushort id_read_eeprom(int index);
static ushort read_eeprom(int ioaddr, int index);
@@ -395,7 +395,7 @@ static struct isa_driver el3_isa_driver = {
static int isa_registered;
#ifdef CONFIG_PNP
-static struct pnp_device_id el3_pnp_ids[] = {
+static const struct pnp_device_id el3_pnp_ids[] __devinitconst = {
{ .id = "TCM5090" }, /* 3Com Etherlink III (TP) */
{ .id = "TCM5091" }, /* 3Com Etherlink III */
{ .id = "TCM5094" }, /* 3Com Etherlink III (combo) */
@@ -478,7 +478,7 @@ static int pnp_registered;
#endif /* CONFIG_PNP */
#ifdef CONFIG_EISA
-static struct eisa_device_id el3_eisa_ids[] = {
+static const struct eisa_device_id el3_eisa_ids[] __devinitconst = {
{ "TCM5090" },
{ "TCM5091" },
{ "TCM5092" },
@@ -508,7 +508,7 @@ static int eisa_registered;
#ifdef CONFIG_MCA
static int el3_mca_probe(struct device *dev);
-static short el3_mca_adapter_ids[] __initdata = {
+static const short el3_mca_adapter_ids[] __devinitconst = {
0x627c,
0x627d,
0x62db,
@@ -517,7 +517,7 @@ static short el3_mca_adapter_ids[] __initdata = {
0x0000
};
-static char *el3_mca_adapter_names[] __initdata = {
+static const char *const el3_mca_adapter_names[] __devinitconst = {
"3Com 3c529 EtherLink III (10base2)",
"3Com 3c529 EtherLink III (10baseT)",
"3Com 3c529 EtherLink III (test mode)",
@@ -601,7 +601,7 @@ static void el3_common_remove (struct net_device *dev)
}
#ifdef CONFIG_MCA
-static int __init el3_mca_probe(struct device *device)
+static int __devinit el3_mca_probe(struct device *device)
{
/* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch,
* heavily modified by Chris Beauregard
@@ -671,7 +671,7 @@ static int __init el3_mca_probe(struct device *device)
#endif /* CONFIG_MCA */
#ifdef CONFIG_EISA
-static int __init el3_eisa_probe (struct device *device)
+static int __devinit el3_eisa_probe (struct device *device)
{
short i;
int ioaddr, irq, if_port;
@@ -1207,7 +1207,7 @@ el3_netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->duplex = DUPLEX_FULL;
}
- ecmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(ecmd, SPEED_10);
EL3WINDOW(1);
return 0;
}
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 8cc22568ebd..99f43d27544 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -901,14 +901,14 @@ static const struct dev_pm_ops vortex_pm_ops = {
#endif /* !CONFIG_PM */
#ifdef CONFIG_EISA
-static struct eisa_device_id vortex_eisa_ids[] = {
+static const struct eisa_device_id vortex_eisa_ids[] __devinitconst = {
{ "TCM5920", CH_3C592 },
{ "TCM5970", CH_3C597 },
{ "" }
};
MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids);
-static int __init vortex_eisa_probe(struct device *device)
+static int __devinit vortex_eisa_probe(struct device *device)
{
void __iomem *ioaddr;
struct eisa_device *edev;
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index dd16e83933a..10c45051cae 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -758,8 +758,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
entry = cp->tx_head;
eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
- if (dev->features & NETIF_F_TSO)
- mss = skb_shinfo(skb)->gso_size;
+ mss = skb_shinfo(skb)->gso_size;
if (skb_shinfo(skb)->nr_frags == 0) {
struct cp_desc *txd = &cp->tx_ring[entry];
@@ -1416,32 +1415,23 @@ static void cp_set_msglevel(struct net_device *dev, u32 value)
cp->msg_enable = value;
}
-static u32 cp_get_rx_csum(struct net_device *dev)
+static int cp_set_features(struct net_device *dev, u32 features)
{
struct cp_private *cp = netdev_priv(dev);
- return (cpr16(CpCmd) & RxChkSum) ? 1 : 0;
-}
+ unsigned long flags;
-static int cp_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct cp_private *cp = netdev_priv(dev);
- u16 cmd = cp->cpcmd, newcmd;
+ if (!((dev->features ^ features) & NETIF_F_RXCSUM))
+ return 0;
- newcmd = cmd;
+ spin_lock_irqsave(&cp->lock, flags);
- if (data)
- newcmd |= RxChkSum;
+ if (features & NETIF_F_RXCSUM)
+ cp->cpcmd |= RxChkSum;
else
- newcmd &= ~RxChkSum;
-
- if (newcmd != cmd) {
- unsigned long flags;
+ cp->cpcmd &= ~RxChkSum;
- spin_lock_irqsave(&cp->lock, flags);
- cp->cpcmd = newcmd;
- cpw16_f(CpCmd, newcmd);
- spin_unlock_irqrestore(&cp->lock, flags);
- }
+ cpw16_f(CpCmd, cp->cpcmd);
+ spin_unlock_irqrestore(&cp->lock, flags);
return 0;
}
@@ -1554,11 +1544,6 @@ static const struct ethtool_ops cp_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_msglevel = cp_get_msglevel,
.set_msglevel = cp_set_msglevel,
- .get_rx_csum = cp_get_rx_csum,
- .set_rx_csum = cp_set_rx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum, /* local! */
- .set_sg = ethtool_op_set_sg,
- .set_tso = ethtool_op_set_tso,
.get_regs = cp_get_regs,
.get_wol = cp_get_wol,
.set_wol = cp_set_wol,
@@ -1831,6 +1816,7 @@ static const struct net_device_ops cp_netdev_ops = {
.ndo_do_ioctl = cp_ioctl,
.ndo_start_xmit = cp_start_xmit,
.ndo_tx_timeout = cp_tx_timeout,
+ .ndo_set_features = cp_set_features,
#if CP_VLAN_TAG_USED
.ndo_vlan_rx_register = cp_vlan_rx_register,
#endif
@@ -1934,6 +1920,9 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
cp->cpcmd = (pci_using_dac ? PCIDAC : 0) |
PCIMulRW | RxChkSum | CpRxOn | CpTxOn;
+ dev->features |= NETIF_F_RXCSUM;
+ dev->hw_features |= NETIF_F_RXCSUM;
+
regs = ioremap(pciaddr, CP_REGS_SIZE);
if (!regs) {
rc = -EIO;
@@ -1966,9 +1955,8 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_using_dac)
dev->features |= NETIF_F_HIGHDMA;
-#if 0 /* disabled by default until verified */
- dev->features |= NETIF_F_TSO;
-#endif
+ /* disabled by default until verified */
+ dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
dev->irq = pdev->irq;
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 01560bb67a7..d7c1bfe4b6e 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -2659,15 +2659,15 @@ static int ace_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
link = readl(&regs->GigLnkState);
if (link & LNK_1000MB)
- ecmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(ecmd, SPEED_1000);
else {
link = readl(&regs->FastLnkState);
if (link & LNK_100MB)
- ecmd->speed = SPEED_100;
+ ethtool_cmd_speed_set(ecmd, SPEED_100);
else if (link & LNK_10MB)
- ecmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(ecmd, SPEED_10);
else
- ecmd->speed = 0;
+ ethtool_cmd_speed_set(ecmd, 0);
}
if (link & LNK_FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
@@ -2719,9 +2719,9 @@ static int ace_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
link |= LNK_TX_FLOW_CTL_Y;
if (ecmd->autoneg == AUTONEG_ENABLE)
link |= LNK_NEGOTIATE;
- if (ecmd->speed != speed) {
+ if (ethtool_cmd_speed(ecmd) != speed) {
link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB);
- switch (speed) {
+ switch (ethtool_cmd_speed(ecmd)) {
case SPEED_1000:
link |= LNK_1000MB;
break;
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
index fbfb5b47c50..03e217a868d 100644
--- a/drivers/net/arm/etherh.c
+++ b/drivers/net/arm/etherh.c
@@ -591,10 +591,11 @@ static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i
static int etherh_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
cmd->supported = etherh_priv(dev)->supported;
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
cmd->duplex = DUPLEX_HALF;
cmd->port = dev->if_port == IF_PORT_10BASET ? PORT_TP : PORT_BNC;
- cmd->autoneg = dev->flags & IFF_AUTOMEDIA ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+ cmd->autoneg = (dev->flags & IFF_AUTOMEDIA ?
+ AUTONEG_ENABLE : AUTONEG_DISABLE);
return 0;
}
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c
index aa07657744c..a7b0caa1817 100644
--- a/drivers/net/arm/ks8695net.c
+++ b/drivers/net/arm/ks8695net.c
@@ -891,15 +891,16 @@ ks8695_wan_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
cmd->advertising |= ADVERTISED_Pause;
cmd->autoneg = AUTONEG_ENABLE;
- cmd->speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10;
+ ethtool_cmd_speed_set(cmd,
+ (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10);
cmd->duplex = (ctrl & WMC_WDS) ?
DUPLEX_FULL : DUPLEX_HALF;
} else {
/* auto-negotiation is disabled */
cmd->autoneg = AUTONEG_DISABLE;
- cmd->speed = (ctrl & WMC_WANF100) ?
- SPEED_100 : SPEED_10;
+ ethtool_cmd_speed_set(cmd, ((ctrl & WMC_WANF100) ?
+ SPEED_100 : SPEED_10));
cmd->duplex = (ctrl & WMC_WANFF) ?
DUPLEX_FULL : DUPLEX_HALF;
}
diff --git a/drivers/net/atl1c/atl1c_ethtool.c b/drivers/net/atl1c/atl1c_ethtool.c
index 7c521508313..7be884d0aaf 100644
--- a/drivers/net/atl1c/atl1c_ethtool.c
+++ b/drivers/net/atl1c/atl1c_ethtool.c
@@ -50,13 +50,13 @@ static int atl1c_get_settings(struct net_device *netdev,
ecmd->transceiver = XCVR_INTERNAL;
if (adapter->link_speed != SPEED_0) {
- ecmd->speed = adapter->link_speed;
+ ethtool_cmd_speed_set(ecmd, adapter->link_speed);
if (adapter->link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
} else {
- ecmd->speed = -1;
+ ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1;
}
@@ -77,7 +77,8 @@ static int atl1c_set_settings(struct net_device *netdev,
if (ecmd->autoneg == AUTONEG_ENABLE) {
autoneg_advertised = ADVERTISED_Autoneg;
} else {
- if (ecmd->speed == SPEED_1000) {
+ u32 speed = ethtool_cmd_speed(ecmd);
+ if (speed == SPEED_1000) {
if (ecmd->duplex != DUPLEX_FULL) {
if (netif_msg_link(adapter))
dev_warn(&adapter->pdev->dev,
@@ -86,7 +87,7 @@ static int atl1c_set_settings(struct net_device *netdev,
return -EINVAL;
}
autoneg_advertised = ADVERTISED_1000baseT_Full;
- } else if (ecmd->speed == SPEED_100) {
+ } else if (speed == SPEED_100) {
if (ecmd->duplex == DUPLEX_FULL)
autoneg_advertised = ADVERTISED_100baseT_Full;
else
@@ -113,11 +114,6 @@ static int atl1c_set_settings(struct net_device *netdev,
return 0;
}
-static u32 atl1c_get_tx_csum(struct net_device *netdev)
-{
- return (netdev->features & NETIF_F_HW_CSUM) != 0;
-}
-
static u32 atl1c_get_msglevel(struct net_device *netdev)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
@@ -307,9 +303,6 @@ static const struct ethtool_ops atl1c_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_eeprom_len = atl1c_get_eeprom_len,
.get_eeprom = atl1c_get_eeprom,
- .get_tx_csum = atl1c_get_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
};
void atl1c_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
index a6e1c36e48e..1269ba5d6e5 100644
--- a/drivers/net/atl1c/atl1c_main.c
+++ b/drivers/net/atl1c/atl1c_main.c
@@ -480,6 +480,15 @@ static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter,
adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ?
roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE;
}
+
+static u32 atl1c_fix_features(struct net_device *netdev, u32 features)
+{
+ if (netdev->mtu > MAX_TSO_FRAME_SIZE)
+ features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+
+ return features;
+}
+
/*
* atl1c_change_mtu - Change the Maximum Transfer Unit
* @netdev: network interface device structure
@@ -506,14 +515,8 @@ static int atl1c_change_mtu(struct net_device *netdev, int new_mtu)
netdev->mtu = new_mtu;
adapter->hw.max_frame_size = new_mtu;
atl1c_set_rxbufsize(adapter, netdev);
- if (new_mtu > MAX_TSO_FRAME_SIZE) {
- adapter->netdev->features &= ~NETIF_F_TSO;
- adapter->netdev->features &= ~NETIF_F_TSO6;
- } else {
- adapter->netdev->features |= NETIF_F_TSO;
- adapter->netdev->features |= NETIF_F_TSO6;
- }
atl1c_down(adapter);
+ netdev_update_features(netdev);
atl1c_up(adapter);
clear_bit(__AT_RESETTING, &adapter->flags);
if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) {
@@ -1088,10 +1091,8 @@ static void atl1c_configure_tx(struct atl1c_adapter *adapter)
u32 max_pay_load;
u16 tx_offload_thresh;
u32 txq_ctrl_data;
- u32 extra_size = 0; /* Jumbo frame threshold in QWORD unit */
u32 max_pay_load_data;
- extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN;
tx_offload_thresh = MAX_TX_OFFLOAD_THRESH;
AT_WRITE_REG(hw, REG_TX_TSO_OFFLOAD_THRESH,
(tx_offload_thresh >> 3) & TX_TSO_OFFLOAD_THRESH_MASK);
@@ -2536,6 +2537,7 @@ static int atl1c_suspend(struct device *dev)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
static int atl1c_resume(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -2562,6 +2564,7 @@ static int atl1c_resume(struct device *dev)
return 0;
}
+#endif
static void atl1c_shutdown(struct pci_dev *pdev)
{
@@ -2581,6 +2584,7 @@ static const struct net_device_ops atl1c_netdev_ops = {
.ndo_set_mac_address = atl1c_set_mac_addr,
.ndo_set_multicast_list = atl1c_set_multi,
.ndo_change_mtu = atl1c_change_mtu,
+ .ndo_fix_features = atl1c_fix_features,
.ndo_do_ioctl = atl1c_ioctl,
.ndo_tx_timeout = atl1c_tx_timeout,
.ndo_get_stats = atl1c_get_stats,
@@ -2601,12 +2605,13 @@ static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
atl1c_set_ethtool_ops(netdev);
/* TODO: add when ready */
- netdev->features = NETIF_F_SG |
+ netdev->hw_features = NETIF_F_SG |
NETIF_F_HW_CSUM |
NETIF_F_HW_VLAN_TX |
- NETIF_F_HW_VLAN_RX |
NETIF_F_TSO |
NETIF_F_TSO6;
+ netdev->features = netdev->hw_features |
+ NETIF_F_HW_VLAN_RX;
return 0;
}
diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c
index 1209297433b..6269438d365 100644
--- a/drivers/net/atl1e/atl1e_ethtool.c
+++ b/drivers/net/atl1e/atl1e_ethtool.c
@@ -51,13 +51,13 @@ static int atl1e_get_settings(struct net_device *netdev,
ecmd->transceiver = XCVR_INTERNAL;
if (adapter->link_speed != SPEED_0) {
- ecmd->speed = adapter->link_speed;
+ ethtool_cmd_speed_set(ecmd, adapter->link_speed);
if (adapter->link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
} else {
- ecmd->speed = -1;
+ ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1;
}
@@ -382,9 +382,6 @@ static const struct ethtool_ops atl1e_ethtool_ops = {
.get_eeprom_len = atl1e_get_eeprom_len,
.get_eeprom = atl1e_get_eeprom,
.set_eeprom = atl1e_set_eeprom,
- .set_tx_csum = ethtool_op_set_tx_hw_csum,
- .set_sg = ethtool_op_set_sg,
- .set_tso = ethtool_op_set_tso,
};
void atl1e_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index b0a71e2f28a..86a91228313 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -691,10 +691,8 @@ static void atl1e_cal_ring_size(struct atl1e_adapter *adapter, u32 *ring_size)
static void atl1e_init_ring_resources(struct atl1e_adapter *adapter)
{
- struct atl1e_tx_ring *tx_ring = NULL;
struct atl1e_rx_ring *rx_ring = NULL;
- tx_ring = &adapter->tx_ring;
rx_ring = &adapter->rx_ring;
rx_ring->real_page_size = adapter->rx_ring.page_size
@@ -1927,11 +1925,7 @@ void atl1e_down(struct atl1e_adapter *adapter)
* reschedule our watchdog timer */
set_bit(__AT_DOWN, &adapter->flags);
-#ifdef NETIF_F_LLTX
netif_stop_queue(netdev);
-#else
- netif_tx_disable(netdev);
-#endif
/* reset MAC to disable all RX/TX */
atl1e_reset_hw(&adapter->hw);
@@ -2223,10 +2217,10 @@ static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
netdev->watchdog_timeo = AT_TX_WATCHDOG;
atl1e_set_ethtool_ops(netdev);
- netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
- NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- netdev->features |= NETIF_F_LLTX;
- netdev->features |= NETIF_F_TSO;
+ netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO |
+ NETIF_F_HW_VLAN_TX;
+ netdev->features = netdev->hw_features |
+ NETIF_F_HW_VLAN_RX | NETIF_F_LLTX;
return 0;
}
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 67f40b9c16e..c5298d1ab74 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -2074,9 +2074,6 @@ static void atl1_intr_tx(struct atl1_adapter *adapter)
cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx);
while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) {
- struct tx_packet_desc *tpd;
-
- tpd = ATL1_TPD_DESC(tpd_ring, sw_tpd_next_to_clean);
buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean];
if (buffer_info->dma) {
pci_unmap_page(adapter->pdev, buffer_info->dma,
@@ -2572,7 +2569,7 @@ static s32 atl1_up(struct atl1_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
int err;
- int irq_flags = IRQF_SAMPLE_RANDOM;
+ int irq_flags = 0;
/* hardware has been reset, we need to reload some things */
atlx_set_multi(netdev);
@@ -2986,6 +2983,11 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_SG;
netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
+ netdev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_TSO;
+
+ /* is this valid? see atl1_setup_mac_ctrl() */
+ netdev->features |= NETIF_F_RXCSUM;
+
/*
* patch for some L1 of old version,
* the final version of L1 may not need these
@@ -3229,13 +3231,13 @@ static int atl1_get_settings(struct net_device *netdev,
if (netif_carrier_ok(adapter->netdev)) {
u16 link_speed, link_duplex;
atl1_get_speed_and_duplex(hw, &link_speed, &link_duplex);
- ecmd->speed = link_speed;
+ ethtool_cmd_speed_set(ecmd, link_speed);
if (link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
} else {
- ecmd->speed = -1;
+ ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1;
}
if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
@@ -3266,7 +3268,8 @@ static int atl1_set_settings(struct net_device *netdev,
if (ecmd->autoneg == AUTONEG_ENABLE)
hw->media_type = MEDIA_TYPE_AUTO_SENSOR;
else {
- if (ecmd->speed == SPEED_1000) {
+ u32 speed = ethtool_cmd_speed(ecmd);
+ if (speed == SPEED_1000) {
if (ecmd->duplex != DUPLEX_FULL) {
if (netif_msg_link(adapter))
dev_warn(&adapter->pdev->dev,
@@ -3275,7 +3278,7 @@ static int atl1_set_settings(struct net_device *netdev,
goto exit_sset;
}
hw->media_type = MEDIA_TYPE_1000M_FULL;
- } else if (ecmd->speed == SPEED_100) {
+ } else if (speed == SPEED_100) {
if (ecmd->duplex == DUPLEX_FULL)
hw->media_type = MEDIA_TYPE_100M_FULL;
else
@@ -3595,12 +3598,6 @@ static int atl1_set_pauseparam(struct net_device *netdev,
return 0;
}
-/* FIXME: is this right? -- CHS */
-static u32 atl1_get_rx_csum(struct net_device *netdev)
-{
- return 1;
-}
-
static void atl1_get_strings(struct net_device *netdev, u32 stringset,
u8 *data)
{
@@ -3668,13 +3665,9 @@ static const struct ethtool_ops atl1_ethtool_ops = {
.set_ringparam = atl1_set_ringparam,
.get_pauseparam = atl1_get_pauseparam,
.set_pauseparam = atl1_set_pauseparam,
- .get_rx_csum = atl1_get_rx_csum,
- .set_tx_csum = ethtool_op_set_tx_hw_csum,
.get_link = ethtool_op_get_link,
- .set_sg = ethtool_op_set_sg,
.get_strings = atl1_get_strings,
.nway_reset = atl1_nway_reset,
.get_ethtool_stats = atl1_get_ethtool_stats,
.get_sset_count = atl1_get_sset_count,
- .set_tso = ethtool_op_set_tso,
};
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
index e3cbf45dc61..16249e9b6b9 100644
--- a/drivers/net/atlx/atl2.c
+++ b/drivers/net/atlx/atl2.c
@@ -1411,9 +1411,8 @@ static int __devinit atl2_probe(struct pci_dev *pdev,
err = -EIO;
-#ifdef NETIF_F_HW_VLAN_TX
+ netdev->hw_features = NETIF_F_SG;
netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
-#endif
/* Init PHY as early as possible due to power saving issue */
atl2_phy_init(&adapter->hw);
@@ -1770,13 +1769,13 @@ static int atl2_get_settings(struct net_device *netdev,
ecmd->transceiver = XCVR_INTERNAL;
if (adapter->link_speed != SPEED_0) {
- ecmd->speed = adapter->link_speed;
+ ethtool_cmd_speed_set(ecmd, adapter->link_speed);
if (adapter->link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
} else {
- ecmd->speed = -1;
+ ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1;
}
@@ -1840,11 +1839,6 @@ static int atl2_set_settings(struct net_device *netdev,
return 0;
}
-static u32 atl2_get_tx_csum(struct net_device *netdev)
-{
- return (netdev->features & NETIF_F_HW_CSUM) != 0;
-}
-
static u32 atl2_get_msglevel(struct net_device *netdev)
{
return 0;
@@ -2112,12 +2106,6 @@ static const struct ethtool_ops atl2_ethtool_ops = {
.get_eeprom_len = atl2_get_eeprom_len,
.get_eeprom = atl2_get_eeprom,
.set_eeprom = atl2_set_eeprom,
- .get_tx_csum = atl2_get_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
-#ifdef NETIF_F_TSO
- .get_tso = ethtool_op_get_tso,
-#endif
};
static void atl2_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 2e2b76258ab..a69331e06b8 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1807,8 +1807,8 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if (bp->flags & B44_FLAG_ADV_100FULL)
cmd->advertising |= ADVERTISED_100baseT_Full;
cmd->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
- cmd->speed = (bp->flags & B44_FLAG_100_BASE_T) ?
- SPEED_100 : SPEED_10;
+ ethtool_cmd_speed_set(cmd, ((bp->flags & B44_FLAG_100_BASE_T) ?
+ SPEED_100 : SPEED_10));
cmd->duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
DUPLEX_FULL : DUPLEX_HALF;
cmd->port = 0;
@@ -1820,7 +1820,7 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if (cmd->autoneg == AUTONEG_ENABLE)
cmd->advertising |= ADVERTISED_Autoneg;
if (!netif_running(dev)){
- cmd->speed = 0;
+ ethtool_cmd_speed_set(cmd, 0);
cmd->duplex = 0xff;
}
cmd->maxtxpkt = 0;
@@ -1831,6 +1831,7 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct b44 *bp = netdev_priv(dev);
+ u32 speed = ethtool_cmd_speed(cmd);
/* We do not support gigabit. */
if (cmd->autoneg == AUTONEG_ENABLE) {
@@ -1838,8 +1839,8 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
(ADVERTISED_1000baseT_Half |
ADVERTISED_1000baseT_Full))
return -EINVAL;
- } else if ((cmd->speed != SPEED_100 &&
- cmd->speed != SPEED_10) ||
+ } else if ((speed != SPEED_100 &&
+ speed != SPEED_10) ||
(cmd->duplex != DUPLEX_HALF &&
cmd->duplex != DUPLEX_FULL)) {
return -EINVAL;
@@ -1873,7 +1874,7 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
} else {
bp->flags |= B44_FLAG_FORCE_LINK;
bp->flags &= ~(B44_FLAG_100_BASE_T | B44_FLAG_FULL_DUPLEX);
- if (cmd->speed == SPEED_100)
+ if (speed == SPEED_100)
bp->flags |= B44_FLAG_100_BASE_T;
if (cmd->duplex == DUPLEX_FULL)
bp->flags |= B44_FLAG_FULL_DUPLEX;
diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c
index c48104b0886..f1573d492e9 100644
--- a/drivers/net/bcm63xx_enet.c
+++ b/drivers/net/bcm63xx_enet.c
@@ -839,8 +839,8 @@ static int bcm_enet_open(struct net_device *dev)
if (ret)
goto out_phy_disconnect;
- ret = request_irq(priv->irq_rx, bcm_enet_isr_dma,
- IRQF_SAMPLE_RANDOM | IRQF_DISABLED, dev->name, dev);
+ ret = request_irq(priv->irq_rx, bcm_enet_isr_dma, IRQF_DISABLED,
+ dev->name, dev);
if (ret)
goto out_freeirq;
@@ -1346,7 +1346,8 @@ static int bcm_enet_get_settings(struct net_device *dev,
return phy_ethtool_gset(priv->phydev, cmd);
} else {
cmd->autoneg = 0;
- cmd->speed = (priv->force_speed_100) ? SPEED_100 : SPEED_10;
+ ethtool_cmd_speed_set(cmd, ((priv->force_speed_100)
+ ? SPEED_100 : SPEED_10));
cmd->duplex = (priv->force_duplex_full) ?
DUPLEX_FULL : DUPLEX_HALF;
cmd->supported = ADVERTISED_10baseT_Half |
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 2353eca3259..a7db870d164 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -49,6 +49,7 @@
#define OC_DEVICE_ID1 0x700 /* Device Id for BE2 cards */
#define OC_DEVICE_ID2 0x710 /* Device Id for BE3 cards */
#define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */
+#define OC_DEVICE_ID4 0xe228 /* Device id for VF in Lancer */
static inline char *nic_name(struct pci_dev *pdev)
{
@@ -58,6 +59,7 @@ static inline char *nic_name(struct pci_dev *pdev)
case OC_DEVICE_ID2:
return OC_NAME_BE;
case OC_DEVICE_ID3:
+ case OC_DEVICE_ID4:
return OC_NAME_LANCER;
case BE_DEVICE_ID2:
return BE3_NAME;
@@ -84,15 +86,14 @@ static inline char *nic_name(struct pci_dev *pdev)
#define MCC_CQ_LEN 256
#define MAX_RSS_QS 4 /* BE limit is 4 queues/port */
-#define BE_MAX_MSIX_VECTORS (MAX_RSS_QS + 1 + 1)/* RSS qs + 1 def Rx + Tx */
+#define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */
+#define BE_MAX_MSIX_VECTORS (MAX_RX_QS + 1)/* RX + TX */
#define BE_NAPI_WEIGHT 64
#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */
#define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST)
#define FW_VER_LEN 32
-#define BE_MAX_VF 32
-
struct be_dma_mem {
void *va;
dma_addr_t dma;
@@ -245,6 +246,43 @@ struct be_rx_obj {
struct be_drv_stats {
u8 be_on_die_temperature;
+ u64 be_tx_events;
+ u64 eth_red_drops;
+ u64 rx_drops_no_pbuf;
+ u64 rx_drops_no_txpb;
+ u64 rx_drops_no_erx_descr;
+ u64 rx_drops_no_tpre_descr;
+ u64 rx_drops_too_many_frags;
+ u64 rx_drops_invalid_ring;
+ u64 forwarded_packets;
+ u64 rx_drops_mtu;
+ u64 rx_crc_errors;
+ u64 rx_alignment_symbol_errors;
+ u64 rx_pause_frames;
+ u64 rx_priority_pause_frames;
+ u64 rx_control_frames;
+ u64 rx_in_range_errors;
+ u64 rx_out_range_errors;
+ u64 rx_frame_too_long;
+ u64 rx_address_match_errors;
+ u64 rx_dropped_too_small;
+ u64 rx_dropped_too_short;
+ u64 rx_dropped_header_too_small;
+ u64 rx_dropped_tcp_length;
+ u64 rx_dropped_runt;
+ u64 rx_ip_checksum_errs;
+ u64 rx_tcp_checksum_errs;
+ u64 rx_udp_checksum_errs;
+ u64 rx_switched_unicast_packets;
+ u64 rx_switched_multicast_packets;
+ u64 rx_switched_broadcast_packets;
+ u64 tx_pauseframes;
+ u64 tx_priority_pauseframes;
+ u64 tx_controlframes;
+ u64 rxpp_fifo_overflow_drop;
+ u64 rx_input_fifo_overflow_drop;
+ u64 pmem_fifo_overflow_drop;
+ u64 jabber_events;
};
struct be_vf_cfg {
@@ -276,7 +314,7 @@ struct be_adapter {
spinlock_t mcc_cq_lock;
struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS];
- bool msix_enabled;
+ u32 num_msix_vec;
bool isr_registered;
/* TX Rings */
@@ -287,7 +325,7 @@ struct be_adapter {
u32 cache_line_break[8];
/* Rx rings */
- struct be_rx_obj rx_obj[MAX_RSS_QS + 1]; /* one default non-rss Q */
+ struct be_rx_obj rx_obj[MAX_RX_QS];
u32 num_rx_qs;
u32 big_page_size; /* Compounded page size shared by rx wrbs */
@@ -308,10 +346,10 @@ struct be_adapter {
u16 work_counter;
/* Ethtool knobs and info */
- bool rx_csum; /* BE card must perform rx-checksumming */
char fw_ver[FW_VER_LEN];
u32 if_handle; /* Used to configure filtering */
u32 pmac_id; /* MAC addr handle used by BE card */
+ u32 beacon_state; /* for set_phys_id */
bool eeh_err;
bool link_up;
@@ -334,7 +372,7 @@ struct be_adapter {
bool be3_native;
bool sriov_enabled;
- struct be_vf_cfg vf_cfg[BE_MAX_VF];
+ struct be_vf_cfg *vf_cfg;
u8 is_virtfn;
u32 sli_family;
u8 hba_port_num;
@@ -347,10 +385,12 @@ struct be_adapter {
#define BE_GEN2 2
#define BE_GEN3 3
-#define lancer_chip(adapter) (adapter->pdev->device == OC_DEVICE_ID3)
+#define lancer_chip(adapter) ((adapter->pdev->device == OC_DEVICE_ID3) || \
+ (adapter->pdev->device == OC_DEVICE_ID4))
extern const struct ethtool_ops be_ethtool_ops;
+#define msix_enabled(adapter) (adapter->num_msix_vec > 0)
#define tx_stats(adapter) (&adapter->tx_stats)
#define rx_stats(rxo) (&rxo->stats)
@@ -455,18 +495,10 @@ static inline u8 is_udp_pkt(struct sk_buff *skb)
static inline void be_check_sriov_fn_type(struct be_adapter *adapter)
{
- u8 data;
u32 sli_intf;
- if (lancer_chip(adapter)) {
- pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET,
- &sli_intf);
- adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0;
- } else {
- pci_write_config_byte(adapter->pdev, 0xFE, 0xAA);
- pci_read_config_byte(adapter->pdev, 0xFE, &data);
- adapter->is_virtfn = (data != 0xAA);
- }
+ pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf);
+ adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0;
}
static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac)
@@ -482,9 +514,15 @@ static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac)
memcpy(mac, adapter->netdev->dev_addr, 3);
}
+static inline bool be_multi_rxq(const struct be_adapter *adapter)
+{
+ return adapter->num_rx_qs > 1;
+}
+
extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
u16 num_popped);
extern void be_link_status_update(struct be_adapter *adapter, bool link_up);
extern void netdev_stats_update(struct be_adapter *adapter);
+extern void be_parse_stats(struct be_adapter *adapter);
extern int be_load_fw(struct be_adapter *adapter, u8 *func);
#endif /* BE_H */
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 9dc9394fd4c..2463b1c9792 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -71,18 +71,38 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
CQE_STATUS_COMPL_MASK;
- if ((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) &&
+ if (((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) ||
+ (compl->tag0 == OPCODE_COMMON_WRITE_OBJECT)) &&
(compl->tag1 == CMD_SUBSYSTEM_COMMON)) {
adapter->flash_status = compl_status;
complete(&adapter->flash_compl);
}
if (compl_status == MCC_STATUS_SUCCESS) {
- if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) {
- struct be_cmd_resp_get_stats *resp =
- adapter->stats_cmd.va;
- be_dws_le_to_cpu(&resp->hw_stats,
- sizeof(resp->hw_stats));
+ if (((compl->tag0 == OPCODE_ETH_GET_STATISTICS) ||
+ (compl->tag0 == OPCODE_ETH_GET_PPORT_STATS)) &&
+ (compl->tag1 == CMD_SUBSYSTEM_ETH)) {
+ if (adapter->generation == BE_GEN3) {
+ if (lancer_chip(adapter)) {
+ struct lancer_cmd_resp_pport_stats
+ *resp = adapter->stats_cmd.va;
+ be_dws_le_to_cpu(&resp->pport_stats,
+ sizeof(resp->pport_stats));
+ } else {
+ struct be_cmd_resp_get_stats_v1 *resp =
+ adapter->stats_cmd.va;
+
+ be_dws_le_to_cpu(&resp->hw_stats,
+ sizeof(resp->hw_stats));
+ }
+ } else {
+ struct be_cmd_resp_get_stats_v0 *resp =
+ adapter->stats_cmd.va;
+
+ be_dws_le_to_cpu(&resp->hw_stats,
+ sizeof(resp->hw_stats));
+ }
+ be_parse_stats(adapter);
netdev_stats_update(adapter);
adapter->stats_cmd_sent = false;
}
@@ -292,12 +312,12 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
if (msecs > 4000) {
dev_err(&adapter->pdev->dev, "mbox poll timed out\n");
- be_detect_dump_ue(adapter);
+ if (!lancer_chip(adapter))
+ be_detect_dump_ue(adapter);
return -1;
}
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(msecs_to_jiffies(1));
+ msleep(1);
msecs++;
} while (true);
@@ -374,23 +394,25 @@ int be_cmd_POST(struct be_adapter *adapter)
{
u16 stage;
int status, timeout = 0;
+ struct device *dev = &adapter->pdev->dev;
do {
status = be_POST_stage_get(adapter, &stage);
if (status) {
- dev_err(&adapter->pdev->dev, "POST error; stage=0x%x\n",
- stage);
+ dev_err(dev, "POST error; stage=0x%x\n", stage);
return -1;
} else if (stage != POST_STAGE_ARMFW_RDY) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(2 * HZ);
+ if (msleep_interruptible(2000)) {
+ dev_err(dev, "Waiting for POST aborted\n");
+ return -EINTR;
+ }
timeout += 2;
} else {
return 0;
}
} while (timeout < 40);
- dev_err(&adapter->pdev->dev, "POST timeout; stage=0x%x\n", stage);
+ dev_err(dev, "POST timeout; stage=0x%x\n", stage);
return -1;
}
@@ -728,8 +750,6 @@ int be_cmd_cq_create(struct be_adapter *adapter,
if (lancer_chip(adapter)) {
req->hdr.version = 2;
req->page_size = 1; /* 1 for 4K */
- AMAP_SET_BITS(struct amap_cq_context_lancer, coalescwm, ctxt,
- coalesce_wm);
AMAP_SET_BITS(struct amap_cq_context_lancer, nodelay, ctxt,
no_delay);
AMAP_SET_BITS(struct amap_cq_context_lancer, count, ctxt,
@@ -1074,7 +1094,7 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id, u32 domain)
int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
{
struct be_mcc_wrb *wrb;
- struct be_cmd_req_get_stats *req;
+ struct be_cmd_req_hdr *hdr;
struct be_sge *sge;
int status = 0;
@@ -1088,14 +1108,62 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
status = -EBUSY;
goto err;
}
- req = nonemb_cmd->va;
+ hdr = nonemb_cmd->va;
sge = nonembedded_sgl(wrb);
- be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
+ be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1,
OPCODE_ETH_GET_STATISTICS);
+ be_cmd_hdr_prepare(hdr, CMD_SUBSYSTEM_ETH,
+ OPCODE_ETH_GET_STATISTICS, nonemb_cmd->size);
+
+ if (adapter->generation == BE_GEN3)
+ hdr->version = 1;
+
+ wrb->tag1 = CMD_SUBSYSTEM_ETH;
+ sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
+ sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
+ sge->len = cpu_to_le32(nonemb_cmd->size);
+
+ be_mcc_notify(adapter);
+ adapter->stats_cmd_sent = true;
+
+err:
+ spin_unlock_bh(&adapter->mcc_lock);
+ return status;
+}
+
+/* Lancer Stats */
+int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
+ struct be_dma_mem *nonemb_cmd)
+{
+
+ struct be_mcc_wrb *wrb;
+ struct lancer_cmd_req_pport_stats *req;
+ struct be_sge *sge;
+ int status = 0;
+
+ spin_lock_bh(&adapter->mcc_lock);
+
+ wrb = wrb_from_mccq(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+ goto err;
+ }
+ req = nonemb_cmd->va;
+ sge = nonembedded_sgl(wrb);
+
+ be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1,
+ OPCODE_ETH_GET_PPORT_STATS);
+
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
- OPCODE_ETH_GET_STATISTICS, sizeof(*req));
+ OPCODE_ETH_GET_PPORT_STATS, nonemb_cmd->size);
+
+
+ req->cmd_params.params.pport_num = cpu_to_le16(adapter->port_num);
+ req->cmd_params.params.reset_stats = 0;
+
+ wrb->tag1 = CMD_SUBSYSTEM_ETH;
sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
sge->len = cpu_to_le32(nonemb_cmd->size);
@@ -1110,7 +1178,7 @@ err:
/* Uses synchronous mcc */
int be_cmd_link_status_query(struct be_adapter *adapter,
- bool *link_up, u8 *mac_speed, u16 *link_speed)
+ bool *link_up, u8 *mac_speed, u16 *link_speed, u32 dom)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_link_status *req;
@@ -1186,6 +1254,116 @@ err:
return status;
}
+/* Uses synchronous mcc */
+int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size)
+{
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_get_fat *req;
+ int status;
+
+ spin_lock_bh(&adapter->mcc_lock);
+
+ wrb = wrb_from_mccq(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+ goto err;
+ }
+ req = embedded_payload(wrb);
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+ OPCODE_COMMON_MANAGE_FAT);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_MANAGE_FAT, sizeof(*req));
+ req->fat_operation = cpu_to_le32(QUERY_FAT);
+ status = be_mcc_notify_wait(adapter);
+ if (!status) {
+ struct be_cmd_resp_get_fat *resp = embedded_payload(wrb);
+ if (log_size && resp->log_size)
+ *log_size = le32_to_cpu(resp->log_size) -
+ sizeof(u32);
+ }
+err:
+ spin_unlock_bh(&adapter->mcc_lock);
+ return status;
+}
+
+void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf)
+{
+ struct be_dma_mem get_fat_cmd;
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_get_fat *req;
+ struct be_sge *sge;
+ u32 offset = 0, total_size, buf_size,
+ log_offset = sizeof(u32), payload_len;
+ int status;
+
+ if (buf_len == 0)
+ return;
+
+ total_size = buf_len;
+
+ get_fat_cmd.size = sizeof(struct be_cmd_req_get_fat) + 60*1024;
+ get_fat_cmd.va = pci_alloc_consistent(adapter->pdev,
+ get_fat_cmd.size,
+ &get_fat_cmd.dma);
+ if (!get_fat_cmd.va) {
+ status = -ENOMEM;
+ dev_err(&adapter->pdev->dev,
+ "Memory allocation failure while retrieving FAT data\n");
+ return;
+ }
+
+ spin_lock_bh(&adapter->mcc_lock);
+
+ while (total_size) {
+ buf_size = min(total_size, (u32)60*1024);
+ total_size -= buf_size;
+
+ wrb = wrb_from_mccq(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+ goto err;
+ }
+ req = get_fat_cmd.va;
+ sge = nonembedded_sgl(wrb);
+
+ payload_len = sizeof(struct be_cmd_req_get_fat) + buf_size;
+ be_wrb_hdr_prepare(wrb, payload_len, false, 1,
+ OPCODE_COMMON_MANAGE_FAT);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_MANAGE_FAT, payload_len);
+
+ sge->pa_hi = cpu_to_le32(upper_32_bits(get_fat_cmd.dma));
+ sge->pa_lo = cpu_to_le32(get_fat_cmd.dma & 0xFFFFFFFF);
+ sge->len = cpu_to_le32(get_fat_cmd.size);
+
+ req->fat_operation = cpu_to_le32(RETRIEVE_FAT);
+ req->read_log_offset = cpu_to_le32(log_offset);
+ req->read_log_length = cpu_to_le32(buf_size);
+ req->data_buffer_size = cpu_to_le32(buf_size);
+
+ status = be_mcc_notify_wait(adapter);
+ if (!status) {
+ struct be_cmd_resp_get_fat *resp = get_fat_cmd.va;
+ memcpy(buf + offset,
+ resp->data_buffer,
+ resp->read_log_length);
+ } else {
+ dev_err(&adapter->pdev->dev, "FAT Table Retrieve error\n");
+ goto err;
+ }
+ offset += buf_size;
+ log_offset += buf_size;
+ }
+err:
+ pci_free_consistent(adapter->pdev, get_fat_cmd.size,
+ get_fat_cmd.va,
+ get_fat_cmd.dma);
+ spin_unlock_bh(&adapter->mcc_lock);
+}
+
/* Uses Mbox */
int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver)
{
@@ -1293,12 +1471,24 @@ err:
/* Uses MCC for this command as it may be called in BH context
* Uses synchronous mcc
*/
-int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en)
+int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en)
{
struct be_mcc_wrb *wrb;
- struct be_cmd_req_promiscuous_config *req;
+ struct be_cmd_req_rx_filter *req;
+ struct be_dma_mem promiscous_cmd;
+ struct be_sge *sge;
int status;
+ memset(&promiscous_cmd, 0, sizeof(struct be_dma_mem));
+ promiscous_cmd.size = sizeof(struct be_cmd_req_rx_filter);
+ promiscous_cmd.va = pci_alloc_consistent(adapter->pdev,
+ promiscous_cmd.size, &promiscous_cmd.dma);
+ if (!promiscous_cmd.va) {
+ dev_err(&adapter->pdev->dev,
+ "Memory allocation failure\n");
+ return -ENOMEM;
+ }
+
spin_lock_bh(&adapter->mcc_lock);
wrb = wrb_from_mccq(adapter);
@@ -1306,26 +1496,30 @@ int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en)
status = -EBUSY;
goto err;
}
- req = embedded_payload(wrb);
- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, OPCODE_ETH_PROMISCUOUS);
+ req = promiscous_cmd.va;
+ sge = nonembedded_sgl(wrb);
- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
- OPCODE_ETH_PROMISCUOUS, sizeof(*req));
-
- /* In FW versions X.102.149/X.101.487 and later,
- * the port setting associated only with the
- * issuing pci function will take effect
- */
- if (port_num)
- req->port1_promiscuous = en;
- else
- req->port0_promiscuous = en;
+ be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
+ OPCODE_COMMON_NTWK_RX_FILTER);
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_NTWK_RX_FILTER, sizeof(*req));
+
+ req->if_id = cpu_to_le32(adapter->if_handle);
+ req->if_flags_mask = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS);
+ if (en)
+ req->if_flags = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS);
+
+ sge->pa_hi = cpu_to_le32(upper_32_bits(promiscous_cmd.dma));
+ sge->pa_lo = cpu_to_le32(promiscous_cmd.dma & 0xFFFFFFFF);
+ sge->len = cpu_to_le32(promiscous_cmd.size);
status = be_mcc_notify_wait(adapter);
err:
spin_unlock_bh(&adapter->mcc_lock);
+ pci_free_consistent(adapter->pdev, promiscous_cmd.size,
+ promiscous_cmd.va, promiscous_cmd.dma);
return status;
}
@@ -1608,6 +1802,81 @@ err:
return status;
}
+int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
+ u32 data_size, u32 data_offset, const char *obj_name,
+ u32 *data_written, u8 *addn_status)
+{
+ struct be_mcc_wrb *wrb;
+ struct lancer_cmd_req_write_object *req;
+ struct lancer_cmd_resp_write_object *resp;
+ void *ctxt = NULL;
+ int status;
+
+ spin_lock_bh(&adapter->mcc_lock);
+ adapter->flash_status = 0;
+
+ wrb = wrb_from_mccq(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+ goto err_unlock;
+ }
+
+ req = embedded_payload(wrb);
+
+ be_wrb_hdr_prepare(wrb, sizeof(struct lancer_cmd_req_write_object),
+ true, 1, OPCODE_COMMON_WRITE_OBJECT);
+ wrb->tag1 = CMD_SUBSYSTEM_COMMON;
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_WRITE_OBJECT,
+ sizeof(struct lancer_cmd_req_write_object));
+
+ ctxt = &req->context;
+ AMAP_SET_BITS(struct amap_lancer_write_obj_context,
+ write_length, ctxt, data_size);
+
+ if (data_size == 0)
+ AMAP_SET_BITS(struct amap_lancer_write_obj_context,
+ eof, ctxt, 1);
+ else
+ AMAP_SET_BITS(struct amap_lancer_write_obj_context,
+ eof, ctxt, 0);
+
+ be_dws_cpu_to_le(ctxt, sizeof(req->context));
+ req->write_offset = cpu_to_le32(data_offset);
+ strcpy(req->object_name, obj_name);
+ req->descriptor_count = cpu_to_le32(1);
+ req->buf_len = cpu_to_le32(data_size);
+ req->addr_low = cpu_to_le32((cmd->dma +
+ sizeof(struct lancer_cmd_req_write_object))
+ & 0xFFFFFFFF);
+ req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma +
+ sizeof(struct lancer_cmd_req_write_object)));
+
+ be_mcc_notify(adapter);
+ spin_unlock_bh(&adapter->mcc_lock);
+
+ if (!wait_for_completion_timeout(&adapter->flash_compl,
+ msecs_to_jiffies(12000)))
+ status = -1;
+ else
+ status = adapter->flash_status;
+
+ resp = embedded_payload(wrb);
+ if (!status) {
+ *data_written = le32_to_cpu(resp->actual_write_len);
+ } else {
+ *addn_status = resp->additional_status;
+ status = resp->status;
+ }
+
+ return status;
+
+err_unlock:
+ spin_unlock_bh(&adapter->mcc_lock);
+ return status;
+}
+
int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
u32 flash_type, u32 flash_opcode, u32 buf_size)
{
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 4f254cfaabe..8148cc66cbe 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -186,12 +186,14 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_NTWK_PMAC_ADD 59
#define OPCODE_COMMON_NTWK_PMAC_DEL 60
#define OPCODE_COMMON_FUNCTION_RESET 61
+#define OPCODE_COMMON_MANAGE_FAT 68
#define OPCODE_COMMON_ENABLE_DISABLE_BEACON 69
#define OPCODE_COMMON_GET_BEACON_STATE 70
#define OPCODE_COMMON_READ_TRANSRECV_DATA 73
#define OPCODE_COMMON_GET_PHY_DETAILS 102
#define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103
#define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121
+#define OPCODE_COMMON_WRITE_OBJECT 172
#define OPCODE_ETH_RSS_CONFIG 1
#define OPCODE_ETH_ACPI_CONFIG 2
@@ -202,6 +204,7 @@ struct be_mcc_mailbox {
#define OPCODE_ETH_TX_DESTROY 9
#define OPCODE_ETH_RX_DESTROY 10
#define OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG 12
+#define OPCODE_ETH_GET_PPORT_STATS 18
#define OPCODE_LOWLEVEL_HOST_DDR_DMA 17
#define OPCODE_LOWLEVEL_LOOPBACK_TEST 18
@@ -380,6 +383,24 @@ struct be_cmd_resp_cq_create {
u16 rsvd0;
} __packed;
+struct be_cmd_req_get_fat {
+ struct be_cmd_req_hdr hdr;
+ u32 fat_operation;
+ u32 read_log_offset;
+ u32 read_log_length;
+ u32 data_buffer_size;
+ u32 data_buffer[1];
+} __packed;
+
+struct be_cmd_resp_get_fat {
+ struct be_cmd_resp_hdr hdr;
+ u32 log_size;
+ u32 read_log_length;
+ u32 rsvd[2];
+ u32 data_buffer[1];
+} __packed;
+
+
/******************** Create MCCQ ***************************/
/* Pseudo amap definition in which each bit of the actual structure is defined
* as a byte: used to calculate offset/shift/mask of each field */
@@ -549,7 +570,7 @@ struct be_cmd_req_if_destroy {
};
/*************** HW Stats Get **********************************/
-struct be_port_rxf_stats {
+struct be_port_rxf_stats_v0 {
u32 rx_bytes_lsd; /* dword 0*/
u32 rx_bytes_msd; /* dword 1*/
u32 rx_total_frames; /* dword 2*/
@@ -618,8 +639,8 @@ struct be_port_rxf_stats {
u32 rx_input_fifo_overflow; /* dword 65*/
};
-struct be_rxf_stats {
- struct be_port_rxf_stats port[2];
+struct be_rxf_stats_v0 {
+ struct be_port_rxf_stats_v0 port[2];
u32 rx_drops_no_pbuf; /* dword 132*/
u32 rx_drops_no_txpb; /* dword 133*/
u32 rx_drops_no_erx_descr; /* dword 134*/
@@ -642,36 +663,227 @@ struct be_rxf_stats {
u32 rsvd1[6];
};
-struct be_erx_stats {
+struct be_erx_stats_v0 {
u32 rx_drops_no_fragments[44]; /* dwordS 0 to 43*/
- u32 debug_wdma_sent_hold; /* dword 44*/
- u32 debug_wdma_pbfree_sent_hold; /* dword 45*/
- u32 debug_wdma_zerobyte_pbfree_sent_hold; /* dword 46*/
- u32 debug_pmem_pbuf_dealloc; /* dword 47*/
+ u32 rsvd[4];
};
struct be_pmem_stats {
u32 eth_red_drops;
- u32 rsvd[4];
+ u32 rsvd[5];
};
-struct be_hw_stats {
- struct be_rxf_stats rxf;
+struct be_hw_stats_v0 {
+ struct be_rxf_stats_v0 rxf;
u32 rsvd[48];
- struct be_erx_stats erx;
+ struct be_erx_stats_v0 erx;
struct be_pmem_stats pmem;
};
-struct be_cmd_req_get_stats {
+struct be_cmd_req_get_stats_v0 {
+ struct be_cmd_req_hdr hdr;
+ u8 rsvd[sizeof(struct be_hw_stats_v0)];
+};
+
+struct be_cmd_resp_get_stats_v0 {
+ struct be_cmd_resp_hdr hdr;
+ struct be_hw_stats_v0 hw_stats;
+};
+
+#define make_64bit_val(hi_32, lo_32) (((u64)hi_32<<32) | lo_32)
+struct lancer_cmd_pport_stats {
+ u32 tx_packets_lo;
+ u32 tx_packets_hi;
+ u32 tx_unicast_packets_lo;
+ u32 tx_unicast_packets_hi;
+ u32 tx_multicast_packets_lo;
+ u32 tx_multicast_packets_hi;
+ u32 tx_broadcast_packets_lo;
+ u32 tx_broadcast_packets_hi;
+ u32 tx_bytes_lo;
+ u32 tx_bytes_hi;
+ u32 tx_unicast_bytes_lo;
+ u32 tx_unicast_bytes_hi;
+ u32 tx_multicast_bytes_lo;
+ u32 tx_multicast_bytes_hi;
+ u32 tx_broadcast_bytes_lo;
+ u32 tx_broadcast_bytes_hi;
+ u32 tx_discards_lo;
+ u32 tx_discards_hi;
+ u32 tx_errors_lo;
+ u32 tx_errors_hi;
+ u32 tx_pause_frames_lo;
+ u32 tx_pause_frames_hi;
+ u32 tx_pause_on_frames_lo;
+ u32 tx_pause_on_frames_hi;
+ u32 tx_pause_off_frames_lo;
+ u32 tx_pause_off_frames_hi;
+ u32 tx_internal_mac_errors_lo;
+ u32 tx_internal_mac_errors_hi;
+ u32 tx_control_frames_lo;
+ u32 tx_control_frames_hi;
+ u32 tx_packets_64_bytes_lo;
+ u32 tx_packets_64_bytes_hi;
+ u32 tx_packets_65_to_127_bytes_lo;
+ u32 tx_packets_65_to_127_bytes_hi;
+ u32 tx_packets_128_to_255_bytes_lo;
+ u32 tx_packets_128_to_255_bytes_hi;
+ u32 tx_packets_256_to_511_bytes_lo;
+ u32 tx_packets_256_to_511_bytes_hi;
+ u32 tx_packets_512_to_1023_bytes_lo;
+ u32 tx_packets_512_to_1023_bytes_hi;
+ u32 tx_packets_1024_to_1518_bytes_lo;
+ u32 tx_packets_1024_to_1518_bytes_hi;
+ u32 tx_packets_1519_to_2047_bytes_lo;
+ u32 tx_packets_1519_to_2047_bytes_hi;
+ u32 tx_packets_2048_to_4095_bytes_lo;
+ u32 tx_packets_2048_to_4095_bytes_hi;
+ u32 tx_packets_4096_to_8191_bytes_lo;
+ u32 tx_packets_4096_to_8191_bytes_hi;
+ u32 tx_packets_8192_to_9216_bytes_lo;
+ u32 tx_packets_8192_to_9216_bytes_hi;
+ u32 tx_lso_packets_lo;
+ u32 tx_lso_packets_hi;
+ u32 rx_packets_lo;
+ u32 rx_packets_hi;
+ u32 rx_unicast_packets_lo;
+ u32 rx_unicast_packets_hi;
+ u32 rx_multicast_packets_lo;
+ u32 rx_multicast_packets_hi;
+ u32 rx_broadcast_packets_lo;
+ u32 rx_broadcast_packets_hi;
+ u32 rx_bytes_lo;
+ u32 rx_bytes_hi;
+ u32 rx_unicast_bytes_lo;
+ u32 rx_unicast_bytes_hi;
+ u32 rx_multicast_bytes_lo;
+ u32 rx_multicast_bytes_hi;
+ u32 rx_broadcast_bytes_lo;
+ u32 rx_broadcast_bytes_hi;
+ u32 rx_unknown_protos;
+ u32 rsvd_69; /* Word 69 is reserved */
+ u32 rx_discards_lo;
+ u32 rx_discards_hi;
+ u32 rx_errors_lo;
+ u32 rx_errors_hi;
+ u32 rx_crc_errors_lo;
+ u32 rx_crc_errors_hi;
+ u32 rx_alignment_errors_lo;
+ u32 rx_alignment_errors_hi;
+ u32 rx_symbol_errors_lo;
+ u32 rx_symbol_errors_hi;
+ u32 rx_pause_frames_lo;
+ u32 rx_pause_frames_hi;
+ u32 rx_pause_on_frames_lo;
+ u32 rx_pause_on_frames_hi;
+ u32 rx_pause_off_frames_lo;
+ u32 rx_pause_off_frames_hi;
+ u32 rx_frames_too_long_lo;
+ u32 rx_frames_too_long_hi;
+ u32 rx_internal_mac_errors_lo;
+ u32 rx_internal_mac_errors_hi;
+ u32 rx_undersize_packets;
+ u32 rx_oversize_packets;
+ u32 rx_fragment_packets;
+ u32 rx_jabbers;
+ u32 rx_control_frames_lo;
+ u32 rx_control_frames_hi;
+ u32 rx_control_frames_unknown_opcode_lo;
+ u32 rx_control_frames_unknown_opcode_hi;
+ u32 rx_in_range_errors;
+ u32 rx_out_of_range_errors;
+ u32 rx_address_match_errors;
+ u32 rx_vlan_mismatch_errors;
+ u32 rx_dropped_too_small;
+ u32 rx_dropped_too_short;
+ u32 rx_dropped_header_too_small;
+ u32 rx_dropped_invalid_tcp_length;
+ u32 rx_dropped_runt;
+ u32 rx_ip_checksum_errors;
+ u32 rx_tcp_checksum_errors;
+ u32 rx_udp_checksum_errors;
+ u32 rx_non_rss_packets;
+ u32 rsvd_111;
+ u32 rx_ipv4_packets_lo;
+ u32 rx_ipv4_packets_hi;
+ u32 rx_ipv6_packets_lo;
+ u32 rx_ipv6_packets_hi;
+ u32 rx_ipv4_bytes_lo;
+ u32 rx_ipv4_bytes_hi;
+ u32 rx_ipv6_bytes_lo;
+ u32 rx_ipv6_bytes_hi;
+ u32 rx_nic_packets_lo;
+ u32 rx_nic_packets_hi;
+ u32 rx_tcp_packets_lo;
+ u32 rx_tcp_packets_hi;
+ u32 rx_iscsi_packets_lo;
+ u32 rx_iscsi_packets_hi;
+ u32 rx_management_packets_lo;
+ u32 rx_management_packets_hi;
+ u32 rx_switched_unicast_packets_lo;
+ u32 rx_switched_unicast_packets_hi;
+ u32 rx_switched_multicast_packets_lo;
+ u32 rx_switched_multicast_packets_hi;
+ u32 rx_switched_broadcast_packets_lo;
+ u32 rx_switched_broadcast_packets_hi;
+ u32 num_forwards_lo;
+ u32 num_forwards_hi;
+ u32 rx_fifo_overflow;
+ u32 rx_input_fifo_overflow;
+ u32 rx_drops_too_many_frags_lo;
+ u32 rx_drops_too_many_frags_hi;
+ u32 rx_drops_invalid_queue;
+ u32 rsvd_141;
+ u32 rx_drops_mtu_lo;
+ u32 rx_drops_mtu_hi;
+ u32 rx_packets_64_bytes_lo;
+ u32 rx_packets_64_bytes_hi;
+ u32 rx_packets_65_to_127_bytes_lo;
+ u32 rx_packets_65_to_127_bytes_hi;
+ u32 rx_packets_128_to_255_bytes_lo;
+ u32 rx_packets_128_to_255_bytes_hi;
+ u32 rx_packets_256_to_511_bytes_lo;
+ u32 rx_packets_256_to_511_bytes_hi;
+ u32 rx_packets_512_to_1023_bytes_lo;
+ u32 rx_packets_512_to_1023_bytes_hi;
+ u32 rx_packets_1024_to_1518_bytes_lo;
+ u32 rx_packets_1024_to_1518_bytes_hi;
+ u32 rx_packets_1519_to_2047_bytes_lo;
+ u32 rx_packets_1519_to_2047_bytes_hi;
+ u32 rx_packets_2048_to_4095_bytes_lo;
+ u32 rx_packets_2048_to_4095_bytes_hi;
+ u32 rx_packets_4096_to_8191_bytes_lo;
+ u32 rx_packets_4096_to_8191_bytes_hi;
+ u32 rx_packets_8192_to_9216_bytes_lo;
+ u32 rx_packets_8192_to_9216_bytes_hi;
+};
+
+struct pport_stats_params {
+ u16 pport_num;
+ u8 rsvd;
+ u8 reset_stats;
+};
+
+struct lancer_cmd_req_pport_stats {
struct be_cmd_req_hdr hdr;
- u8 rsvd[sizeof(struct be_hw_stats)];
+ union {
+ struct pport_stats_params params;
+ u8 rsvd[sizeof(struct lancer_cmd_pport_stats)];
+ } cmd_params;
};
-struct be_cmd_resp_get_stats {
+struct lancer_cmd_resp_pport_stats {
struct be_cmd_resp_hdr hdr;
- struct be_hw_stats hw_stats;
+ struct lancer_cmd_pport_stats pport_stats;
};
+static inline struct lancer_cmd_pport_stats*
+ pport_stats_from_cmd(struct be_adapter *adapter)
+{
+ struct lancer_cmd_resp_pport_stats *cmd = adapter->stats_cmd.va;
+ return &cmd->pport_stats;
+}
+
struct be_cmd_req_get_cntl_addnl_attribs {
struct be_cmd_req_hdr hdr;
u8 rsvd[8];
@@ -695,13 +907,6 @@ struct be_cmd_req_vlan_config {
u16 normal_vlan[64];
} __packed;
-struct be_cmd_req_promiscuous_config {
- struct be_cmd_req_hdr hdr;
- u8 port0_promiscuous;
- u8 port1_promiscuous;
- u16 rsvd0;
-} __packed;
-
/******************** Multicast MAC Config *******************/
#define BE_MAX_MC 64 /* set mcast promisc if > 64 */
struct macaddr {
@@ -716,11 +921,18 @@ struct be_cmd_req_mcast_mac_config {
struct macaddr mac[BE_MAX_MC];
} __packed;
-static inline struct be_hw_stats *
-hw_stats_from_cmd(struct be_cmd_resp_get_stats *cmd)
-{
- return &cmd->hw_stats;
-}
+/******************* RX FILTER ******************************/
+struct be_cmd_req_rx_filter {
+ struct be_cmd_req_hdr hdr;
+ u32 global_flags_mask;
+ u32 global_flags;
+ u32 if_flags_mask;
+ u32 if_flags;
+ u32 if_id;
+ u32 multicast_num;
+ struct macaddr mac[BE_MAX_MC];
+};
+
/******************** Link Status Query *******************/
struct be_cmd_req_link_status {
@@ -920,6 +1132,36 @@ struct be_cmd_write_flashrom {
struct flashrom_params params;
};
+/**************** Lancer Firmware Flash ************/
+struct amap_lancer_write_obj_context {
+ u8 write_length[24];
+ u8 reserved1[7];
+ u8 eof;
+} __packed;
+
+struct lancer_cmd_req_write_object {
+ struct be_cmd_req_hdr hdr;
+ u8 context[sizeof(struct amap_lancer_write_obj_context) / 8];
+ u32 write_offset;
+ u8 object_name[104];
+ u32 descriptor_count;
+ u32 buf_len;
+ u32 addr_low;
+ u32 addr_high;
+};
+
+struct lancer_cmd_resp_write_object {
+ u8 opcode;
+ u8 subsystem;
+ u8 rsvd1[2];
+ u8 status;
+ u8 additional_status;
+ u8 rsvd2[2];
+ u32 resp_len;
+ u32 actual_resp_len;
+ u32 actual_write_len;
+};
+
/************************ WOL *******************************/
struct be_cmd_req_acpi_wol_magic_config{
struct be_cmd_req_hdr hdr;
@@ -1061,6 +1303,151 @@ struct be_cmd_resp_set_func_cap {
u8 rsvd[212];
};
+/*************** HW Stats Get v1 **********************************/
+#define BE_TXP_SW_SZ 48
+struct be_port_rxf_stats_v1 {
+ u32 rsvd0[12];
+ u32 rx_crc_errors;
+ u32 rx_alignment_symbol_errors;
+ u32 rx_pause_frames;
+ u32 rx_priority_pause_frames;
+ u32 rx_control_frames;
+ u32 rx_in_range_errors;
+ u32 rx_out_range_errors;
+ u32 rx_frame_too_long;
+ u32 rx_address_match_errors;
+ u32 rx_dropped_too_small;
+ u32 rx_dropped_too_short;
+ u32 rx_dropped_header_too_small;
+ u32 rx_dropped_tcp_length;
+ u32 rx_dropped_runt;
+ u32 rsvd1[10];
+ u32 rx_ip_checksum_errs;
+ u32 rx_tcp_checksum_errs;
+ u32 rx_udp_checksum_errs;
+ u32 rsvd2[7];
+ u32 rx_switched_unicast_packets;
+ u32 rx_switched_multicast_packets;
+ u32 rx_switched_broadcast_packets;
+ u32 rsvd3[3];
+ u32 tx_pauseframes;
+ u32 tx_priority_pauseframes;
+ u32 tx_controlframes;
+ u32 rsvd4[10];
+ u32 rxpp_fifo_overflow_drop;
+ u32 rx_input_fifo_overflow_drop;
+ u32 pmem_fifo_overflow_drop;
+ u32 jabber_events;
+ u32 rsvd5[3];
+};
+
+
+struct be_rxf_stats_v1 {
+ struct be_port_rxf_stats_v1 port[4];
+ u32 rsvd0[2];
+ u32 rx_drops_no_pbuf;
+ u32 rx_drops_no_txpb;
+ u32 rx_drops_no_erx_descr;
+ u32 rx_drops_no_tpre_descr;
+ u32 rsvd1[6];
+ u32 rx_drops_too_many_frags;
+ u32 rx_drops_invalid_ring;
+ u32 forwarded_packets;
+ u32 rx_drops_mtu;
+ u32 rsvd2[14];
+};
+
+struct be_erx_stats_v1 {
+ u32 rx_drops_no_fragments[68]; /* dwordS 0 to 67*/
+ u32 rsvd[4];
+};
+
+struct be_hw_stats_v1 {
+ struct be_rxf_stats_v1 rxf;
+ u32 rsvd0[BE_TXP_SW_SZ];
+ struct be_erx_stats_v1 erx;
+ struct be_pmem_stats pmem;
+ u32 rsvd1[3];
+};
+
+struct be_cmd_req_get_stats_v1 {
+ struct be_cmd_req_hdr hdr;
+ u8 rsvd[sizeof(struct be_hw_stats_v1)];
+};
+
+struct be_cmd_resp_get_stats_v1 {
+ struct be_cmd_resp_hdr hdr;
+ struct be_hw_stats_v1 hw_stats;
+};
+
+static inline void *
+hw_stats_from_cmd(struct be_adapter *adapter)
+{
+ if (adapter->generation == BE_GEN3) {
+ struct be_cmd_resp_get_stats_v1 *cmd = adapter->stats_cmd.va;
+
+ return &cmd->hw_stats;
+ } else {
+ struct be_cmd_resp_get_stats_v0 *cmd = adapter->stats_cmd.va;
+
+ return &cmd->hw_stats;
+ }
+}
+
+static inline void *be_port_rxf_stats_from_cmd(struct be_adapter *adapter)
+{
+ if (adapter->generation == BE_GEN3) {
+ struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
+ struct be_rxf_stats_v1 *rxf_stats = &hw_stats->rxf;
+
+ return &rxf_stats->port[adapter->port_num];
+ } else {
+ struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
+ struct be_rxf_stats_v0 *rxf_stats = &hw_stats->rxf;
+
+ return &rxf_stats->port[adapter->port_num];
+ }
+}
+
+static inline void *be_rxf_stats_from_cmd(struct be_adapter *adapter)
+{
+ if (adapter->generation == BE_GEN3) {
+ struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
+
+ return &hw_stats->rxf;
+ } else {
+ struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
+
+ return &hw_stats->rxf;
+ }
+}
+
+static inline void *be_erx_stats_from_cmd(struct be_adapter *adapter)
+{
+ if (adapter->generation == BE_GEN3) {
+ struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
+
+ return &hw_stats->erx;
+ } else {
+ struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
+
+ return &hw_stats->erx;
+ }
+}
+
+static inline void *be_pmem_stats_from_cmd(struct be_adapter *adapter)
+{
+ if (adapter->generation == BE_GEN3) {
+ struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
+
+ return &hw_stats->pmem;
+ } else {
+ struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
+
+ return &hw_stats->pmem;
+ }
+}
+
extern int be_pci_fnum_get(struct be_adapter *adapter);
extern int be_cmd_POST(struct be_adapter *adapter);
extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
@@ -1093,18 +1480,19 @@ extern int be_cmd_rxq_create(struct be_adapter *adapter,
extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
int type);
extern int be_cmd_link_status_query(struct be_adapter *adapter,
- bool *link_up, u8 *mac_speed, u16 *link_speed);
+ bool *link_up, u8 *mac_speed, u16 *link_speed, u32 dom);
extern int be_cmd_reset(struct be_adapter *adapter);
extern int be_cmd_get_stats(struct be_adapter *adapter,
struct be_dma_mem *nonemb_cmd);
+extern int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
+ struct be_dma_mem *nonemb_cmd);
extern int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver);
extern int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd);
extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id,
u16 *vtag_array, u32 num, bool untagged,
bool promiscuous);
-extern int be_cmd_promiscuous_config(struct be_adapter *adapter,
- u8 port_num, bool en);
+extern int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en);
extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
struct net_device *netdev, struct be_dma_mem *mem);
extern int be_cmd_set_flow_control(struct be_adapter *adapter,
@@ -1124,6 +1512,11 @@ extern int be_cmd_get_beacon_state(struct be_adapter *adapter,
extern int be_cmd_write_flashrom(struct be_adapter *adapter,
struct be_dma_mem *cmd, u32 flash_oper,
u32 flash_opcode, u32 buf_size);
+extern int lancer_cmd_write_object(struct be_adapter *adapter,
+ struct be_dma_mem *cmd,
+ u32 data_size, u32 data_offset,
+ const char *obj_name,
+ u32 *data_written, u8 *addn_status);
int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
int offset);
extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
@@ -1148,4 +1541,6 @@ extern void be_detect_dump_ue(struct be_adapter *adapter);
extern int be_cmd_get_die_temperature(struct be_adapter *adapter);
extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter);
extern int be_cmd_check_native_mode(struct be_adapter *adapter);
+extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size);
+extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf);
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index aac248fbd18..facfe3ca5c4 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -26,8 +26,8 @@ struct be_ethtool_stat {
int offset;
};
-enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT,
- PMEMSTAT, DRVSTAT};
+enum {NETSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT,
+ DRVSTAT};
#define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \
offsetof(_struct, field)
#define NETSTAT_INFO(field) #field, NETSTAT,\
@@ -37,15 +37,8 @@ enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT,
FIELDINFO(struct be_tx_stats, field)
#define DRVSTAT_RX_INFO(field) #field, DRVSTAT_RX,\
FIELDINFO(struct be_rx_stats, field)
-#define MISCSTAT_INFO(field) #field, MISCSTAT,\
- FIELDINFO(struct be_rxf_stats, field)
-#define PORTSTAT_INFO(field) #field, PORTSTAT,\
- FIELDINFO(struct be_port_rxf_stats, \
- field)
-#define ERXSTAT_INFO(field) #field, ERXSTAT,\
- FIELDINFO(struct be_erx_stats, field)
-#define PMEMSTAT_INFO(field) #field, PMEMSTAT,\
- FIELDINFO(struct be_pmem_stats, field)
+#define ERXSTAT_INFO(field) #field, ERXSTAT,\
+ FIELDINFO(struct be_erx_stats_v1, field)
#define DRVSTAT_INFO(field) #field, DRVSTAT,\
FIELDINFO(struct be_drv_stats, \
field)
@@ -65,50 +58,41 @@ static const struct be_ethtool_stat et_stats[] = {
{DRVSTAT_TX_INFO(be_tx_stops)},
{DRVSTAT_TX_INFO(be_tx_events)},
{DRVSTAT_TX_INFO(be_tx_compl)},
- {PORTSTAT_INFO(rx_unicast_frames)},
- {PORTSTAT_INFO(rx_multicast_frames)},
- {PORTSTAT_INFO(rx_broadcast_frames)},
- {PORTSTAT_INFO(rx_crc_errors)},
- {PORTSTAT_INFO(rx_alignment_symbol_errors)},
- {PORTSTAT_INFO(rx_pause_frames)},
- {PORTSTAT_INFO(rx_control_frames)},
- {PORTSTAT_INFO(rx_in_range_errors)},
- {PORTSTAT_INFO(rx_out_range_errors)},
- {PORTSTAT_INFO(rx_frame_too_long)},
- {PORTSTAT_INFO(rx_address_match_errors)},
- {PORTSTAT_INFO(rx_vlan_mismatch)},
- {PORTSTAT_INFO(rx_dropped_too_small)},
- {PORTSTAT_INFO(rx_dropped_too_short)},
- {PORTSTAT_INFO(rx_dropped_header_too_small)},
- {PORTSTAT_INFO(rx_dropped_tcp_length)},
- {PORTSTAT_INFO(rx_dropped_runt)},
- {PORTSTAT_INFO(rx_fifo_overflow)},
- {PORTSTAT_INFO(rx_input_fifo_overflow)},
- {PORTSTAT_INFO(rx_ip_checksum_errs)},
- {PORTSTAT_INFO(rx_tcp_checksum_errs)},
- {PORTSTAT_INFO(rx_udp_checksum_errs)},
- {PORTSTAT_INFO(rx_non_rss_packets)},
- {PORTSTAT_INFO(rx_ipv4_packets)},
- {PORTSTAT_INFO(rx_ipv6_packets)},
- {PORTSTAT_INFO(rx_switched_unicast_packets)},
- {PORTSTAT_INFO(rx_switched_multicast_packets)},
- {PORTSTAT_INFO(rx_switched_broadcast_packets)},
- {PORTSTAT_INFO(tx_unicastframes)},
- {PORTSTAT_INFO(tx_multicastframes)},
- {PORTSTAT_INFO(tx_broadcastframes)},
- {PORTSTAT_INFO(tx_pauseframes)},
- {PORTSTAT_INFO(tx_controlframes)},
- {MISCSTAT_INFO(rx_drops_no_pbuf)},
- {MISCSTAT_INFO(rx_drops_no_txpb)},
- {MISCSTAT_INFO(rx_drops_no_erx_descr)},
- {MISCSTAT_INFO(rx_drops_no_tpre_descr)},
- {MISCSTAT_INFO(rx_drops_too_many_frags)},
- {MISCSTAT_INFO(rx_drops_invalid_ring)},
- {MISCSTAT_INFO(forwarded_packets)},
- {MISCSTAT_INFO(rx_drops_mtu)},
- {MISCSTAT_INFO(port0_jabber_events)},
- {MISCSTAT_INFO(port1_jabber_events)},
- {PMEMSTAT_INFO(eth_red_drops)},
+ {DRVSTAT_INFO(rx_crc_errors)},
+ {DRVSTAT_INFO(rx_alignment_symbol_errors)},
+ {DRVSTAT_INFO(rx_pause_frames)},
+ {DRVSTAT_INFO(rx_control_frames)},
+ {DRVSTAT_INFO(rx_in_range_errors)},
+ {DRVSTAT_INFO(rx_out_range_errors)},
+ {DRVSTAT_INFO(rx_frame_too_long)},
+ {DRVSTAT_INFO(rx_address_match_errors)},
+ {DRVSTAT_INFO(rx_dropped_too_small)},
+ {DRVSTAT_INFO(rx_dropped_too_short)},
+ {DRVSTAT_INFO(rx_dropped_header_too_small)},
+ {DRVSTAT_INFO(rx_dropped_tcp_length)},
+ {DRVSTAT_INFO(rx_dropped_runt)},
+ {DRVSTAT_INFO(rxpp_fifo_overflow_drop)},
+ {DRVSTAT_INFO(rx_input_fifo_overflow_drop)},
+ {DRVSTAT_INFO(rx_ip_checksum_errs)},
+ {DRVSTAT_INFO(rx_tcp_checksum_errs)},
+ {DRVSTAT_INFO(rx_udp_checksum_errs)},
+ {DRVSTAT_INFO(rx_switched_unicast_packets)},
+ {DRVSTAT_INFO(rx_switched_multicast_packets)},
+ {DRVSTAT_INFO(rx_switched_broadcast_packets)},
+ {DRVSTAT_INFO(tx_pauseframes)},
+ {DRVSTAT_INFO(tx_controlframes)},
+ {DRVSTAT_INFO(rx_priority_pause_frames)},
+ {DRVSTAT_INFO(pmem_fifo_overflow_drop)},
+ {DRVSTAT_INFO(jabber_events)},
+ {DRVSTAT_INFO(rx_drops_no_pbuf)},
+ {DRVSTAT_INFO(rx_drops_no_txpb)},
+ {DRVSTAT_INFO(rx_drops_no_erx_descr)},
+ {DRVSTAT_INFO(rx_drops_no_tpre_descr)},
+ {DRVSTAT_INFO(rx_drops_too_many_frags)},
+ {DRVSTAT_INFO(rx_drops_invalid_ring)},
+ {DRVSTAT_INFO(forwarded_packets)},
+ {DRVSTAT_INFO(rx_drops_mtu)},
+ {DRVSTAT_INFO(eth_red_drops)},
{DRVSTAT_INFO(be_on_die_temperature)}
};
#define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats)
@@ -156,6 +140,29 @@ be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
}
static int
+be_get_reg_len(struct net_device *netdev)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+ u32 log_size = 0;
+
+ if (be_physfn(adapter))
+ be_cmd_get_reg_len(adapter, &log_size);
+
+ return log_size;
+}
+
+static void
+be_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+
+ if (be_physfn(adapter)) {
+ memset(buf, 0, regs->len);
+ be_cmd_get_regs(adapter, regs->len, buf);
+ }
+}
+
+static int
be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
{
struct be_adapter *adapter = netdev_priv(netdev);
@@ -186,9 +193,9 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
struct be_rx_obj *rxo;
struct be_eq_obj *rx_eq;
struct be_eq_obj *tx_eq = &adapter->tx_eq;
- u32 tx_max, tx_min, tx_cur;
u32 rx_max, rx_min, rx_cur;
int status = 0, i;
+ u32 tx_cur;
if (coalesce->use_adaptive_tx_coalesce == 1)
return -EINVAL;
@@ -227,8 +234,6 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
}
}
- tx_max = coalesce->tx_coalesce_usecs_high;
- tx_min = coalesce->tx_coalesce_usecs_low;
tx_cur = coalesce->tx_coalesce_usecs;
if (tx_cur > BE_MAX_EQD)
@@ -242,32 +247,11 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
return 0;
}
-static u32 be_get_rx_csum(struct net_device *netdev)
-{
- struct be_adapter *adapter = netdev_priv(netdev);
-
- return adapter->rx_csum;
-}
-
-static int be_set_rx_csum(struct net_device *netdev, uint32_t data)
-{
- struct be_adapter *adapter = netdev_priv(netdev);
-
- if (data)
- adapter->rx_csum = true;
- else
- adapter->rx_csum = false;
-
- return 0;
-}
-
static void
be_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, uint64_t *data)
{
struct be_adapter *adapter = netdev_priv(netdev);
- struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats_cmd.va);
- struct be_erx_stats *erx_stats = &hw_stats->erx;
struct be_rx_obj *rxo;
void *p = NULL;
int i, j;
@@ -280,15 +264,6 @@ be_get_ethtool_stats(struct net_device *netdev,
case DRVSTAT_TX:
p = &adapter->tx_stats;
break;
- case PORTSTAT:
- p = &hw_stats->rxf.port[adapter->port_num];
- break;
- case MISCSTAT:
- p = &hw_stats->rxf;
- break;
- case PMEMSTAT:
- p = &hw_stats->pmem;
- break;
case DRVSTAT:
p = &adapter->drv_stats;
break;
@@ -306,7 +281,8 @@ be_get_ethtool_stats(struct net_device *netdev,
p = (u8 *)&rxo->stats + et_rx_stats[i].offset;
break;
case ERXSTAT:
- p = (u32 *)erx_stats + rxo->q.id;
+ p = (u32 *)be_erx_stats_from_cmd(adapter) +
+ rxo->q.id;
break;
}
data[ETHTOOL_STATS_NUM + j * ETHTOOL_RXSTATS_NUM + i] =
@@ -374,19 +350,28 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) {
status = be_cmd_link_status_query(adapter, &link_up,
- &mac_speed, &link_speed);
+ &mac_speed, &link_speed, 0);
be_link_status_update(adapter, link_up);
/* link_speed is in units of 10 Mbps */
if (link_speed) {
- ecmd->speed = link_speed*10;
+ ethtool_cmd_speed_set(ecmd, link_speed*10);
} else {
switch (mac_speed) {
+ case PHY_LINK_SPEED_10MBPS:
+ ethtool_cmd_speed_set(ecmd, SPEED_10);
+ break;
+ case PHY_LINK_SPEED_100MBPS:
+ ethtool_cmd_speed_set(ecmd, SPEED_100);
+ break;
case PHY_LINK_SPEED_1GBPS:
- ecmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(ecmd, SPEED_1000);
break;
case PHY_LINK_SPEED_10GBPS:
- ecmd->speed = SPEED_10000;
+ ethtool_cmd_speed_set(ecmd, SPEED_10000);
+ break;
+ case PHY_LINK_SPEED_ZERO:
+ ethtool_cmd_speed_set(ecmd, 0);
break;
}
}
@@ -429,14 +414,14 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
}
/* Save for future use */
- adapter->link_speed = ecmd->speed;
+ adapter->link_speed = ethtool_cmd_speed(ecmd);
adapter->port_type = ecmd->port;
adapter->transceiver = ecmd->transceiver;
adapter->autoneg = ecmd->autoneg;
dma_free_coherent(&adapter->pdev->dev, phy_cmd.size, phy_cmd.va,
phy_cmd.dma);
} else {
- ecmd->speed = adapter->link_speed;
+ ethtool_cmd_speed_set(ecmd, adapter->link_speed);
ecmd->port = adapter->port_type;
ecmd->transceiver = adapter->transceiver;
ecmd->autoneg = adapter->autoneg;
@@ -507,29 +492,33 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
}
static int
-be_phys_id(struct net_device *netdev, u32 data)
+be_set_phys_id(struct net_device *netdev,
+ enum ethtool_phys_id_state state)
{
struct be_adapter *adapter = netdev_priv(netdev);
- int status;
- u32 cur;
-
- be_cmd_get_beacon_state(adapter, adapter->hba_port_num, &cur);
- if (cur == BEACON_STATE_ENABLED)
- return 0;
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ be_cmd_get_beacon_state(adapter, adapter->hba_port_num,
+ &adapter->beacon_state);
+ return 1; /* cycle on/off once per second */
- if (data < 2)
- data = 2;
+ case ETHTOOL_ID_ON:
+ be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
+ BEACON_STATE_ENABLED);
+ break;
- status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
- BEACON_STATE_ENABLED);
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(data*HZ);
+ case ETHTOOL_ID_OFF:
+ be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
+ BEACON_STATE_DISABLED);
+ break;
- status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
- BEACON_STATE_DISABLED);
+ case ETHTOOL_ID_INACTIVE:
+ be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
+ adapter->beacon_state);
+ }
- return status;
+ return 0;
}
static bool
@@ -646,7 +635,7 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
}
if (be_cmd_link_status_query(adapter, &link_up, &mac_speed,
- &qos_link_speed) != 0) {
+ &qos_link_speed, 0) != 0) {
test->flags |= ETH_TEST_FL_FAILED;
data[4] = -1;
} else if (!mac_speed) {
@@ -660,11 +649,9 @@ be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
{
struct be_adapter *adapter = netdev_priv(netdev);
char file_name[ETHTOOL_FLASH_MAX_FILENAME];
- u32 region;
file_name[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
strcpy(file_name, efl->data);
- region = efl->region;
return be_load_fw(adapter, file_name);
}
@@ -725,18 +712,12 @@ const struct ethtool_ops be_ethtool_ops = {
.get_ringparam = be_get_ringparam,
.get_pauseparam = be_get_pauseparam,
.set_pauseparam = be_set_pauseparam,
- .get_rx_csum = be_get_rx_csum,
- .set_rx_csum = be_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_hw_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = ethtool_op_set_tso,
.get_strings = be_get_stat_strings,
- .phys_id = be_phys_id,
+ .set_phys_id = be_set_phys_id,
.get_sset_count = be_get_sset_count,
.get_ethtool_stats = be_get_ethtool_stats,
+ .get_regs_len = be_get_reg_len,
+ .get_regs = be_get_regs,
.flash_device = be_do_flash,
.self_test = be_self_test,
};
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h
index d4344a06090..53d658afea2 100644
--- a/drivers/net/benet/be_hw.h
+++ b/drivers/net/benet/be_hw.h
@@ -155,6 +155,10 @@
/********** SRIOV VF PCICFG OFFSET ********/
#define SRIOV_VF_PCICFG_OFFSET (4096)
+/********** FAT TABLE ********/
+#define RETRIEVE_FAT 0
+#define QUERY_FAT 1
+
/* Flashrom related descriptors */
#define IMAGE_TYPE_FIRMWARE 160
#define IMAGE_TYPE_BOOTCODE 224
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 9187fb4e08f..4b5e0ed49ed 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -42,6 +42,7 @@ static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = {
{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
{ PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID3)},
+ { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID4)},
{ 0 }
};
MODULE_DEVICE_TABLE(pci, be_dev_ids);
@@ -116,11 +117,6 @@ static char *ue_status_hi_desc[] = {
"Unknown"
};
-static inline bool be_multi_rxq(struct be_adapter *adapter)
-{
- return (adapter->num_rx_qs > 1);
-}
-
static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q)
{
struct be_dma_mem *mem = &q->dma_mem;
@@ -250,14 +246,185 @@ netdev_addr:
return status;
}
+static void populate_be2_stats(struct be_adapter *adapter)
+{
+
+ struct be_drv_stats *drvs = &adapter->drv_stats;
+ struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter);
+ struct be_port_rxf_stats_v0 *port_stats =
+ be_port_rxf_stats_from_cmd(adapter);
+ struct be_rxf_stats_v0 *rxf_stats =
+ be_rxf_stats_from_cmd(adapter);
+
+ drvs->rx_pause_frames = port_stats->rx_pause_frames;
+ drvs->rx_crc_errors = port_stats->rx_crc_errors;
+ drvs->rx_control_frames = port_stats->rx_control_frames;
+ drvs->rx_in_range_errors = port_stats->rx_in_range_errors;
+ drvs->rx_frame_too_long = port_stats->rx_frame_too_long;
+ drvs->rx_dropped_runt = port_stats->rx_dropped_runt;
+ drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs;
+ drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs;
+ drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs;
+ drvs->rxpp_fifo_overflow_drop = port_stats->rx_fifo_overflow;
+ drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length;
+ drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small;
+ drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short;
+ drvs->rx_out_range_errors = port_stats->rx_out_range_errors;
+ drvs->rx_input_fifo_overflow_drop =
+ port_stats->rx_input_fifo_overflow;
+ drvs->rx_dropped_header_too_small =
+ port_stats->rx_dropped_header_too_small;
+ drvs->rx_address_match_errors =
+ port_stats->rx_address_match_errors;
+ drvs->rx_alignment_symbol_errors =
+ port_stats->rx_alignment_symbol_errors;
+
+ drvs->tx_pauseframes = port_stats->tx_pauseframes;
+ drvs->tx_controlframes = port_stats->tx_controlframes;
+
+ if (adapter->port_num)
+ drvs->jabber_events =
+ rxf_stats->port1_jabber_events;
+ else
+ drvs->jabber_events =
+ rxf_stats->port0_jabber_events;
+ drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
+ drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
+ drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
+ drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
+ drvs->forwarded_packets = rxf_stats->forwarded_packets;
+ drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
+ drvs->rx_drops_no_tpre_descr =
+ rxf_stats->rx_drops_no_tpre_descr;
+ drvs->rx_drops_too_many_frags =
+ rxf_stats->rx_drops_too_many_frags;
+ adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops;
+}
+
+static void populate_be3_stats(struct be_adapter *adapter)
+{
+ struct be_drv_stats *drvs = &adapter->drv_stats;
+ struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter);
+
+ struct be_rxf_stats_v1 *rxf_stats =
+ be_rxf_stats_from_cmd(adapter);
+ struct be_port_rxf_stats_v1 *port_stats =
+ be_port_rxf_stats_from_cmd(adapter);
+
+ drvs->rx_priority_pause_frames = 0;
+ drvs->pmem_fifo_overflow_drop = 0;
+ drvs->rx_pause_frames = port_stats->rx_pause_frames;
+ drvs->rx_crc_errors = port_stats->rx_crc_errors;
+ drvs->rx_control_frames = port_stats->rx_control_frames;
+ drvs->rx_in_range_errors = port_stats->rx_in_range_errors;
+ drvs->rx_frame_too_long = port_stats->rx_frame_too_long;
+ drvs->rx_dropped_runt = port_stats->rx_dropped_runt;
+ drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs;
+ drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs;
+ drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs;
+ drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length;
+ drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small;
+ drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short;
+ drvs->rx_out_range_errors = port_stats->rx_out_range_errors;
+ drvs->rx_dropped_header_too_small =
+ port_stats->rx_dropped_header_too_small;
+ drvs->rx_input_fifo_overflow_drop =
+ port_stats->rx_input_fifo_overflow_drop;
+ drvs->rx_address_match_errors =
+ port_stats->rx_address_match_errors;
+ drvs->rx_alignment_symbol_errors =
+ port_stats->rx_alignment_symbol_errors;
+ drvs->rxpp_fifo_overflow_drop =
+ port_stats->rxpp_fifo_overflow_drop;
+ drvs->tx_pauseframes = port_stats->tx_pauseframes;
+ drvs->tx_controlframes = port_stats->tx_controlframes;
+ drvs->jabber_events = port_stats->jabber_events;
+ drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
+ drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
+ drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
+ drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
+ drvs->forwarded_packets = rxf_stats->forwarded_packets;
+ drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
+ drvs->rx_drops_no_tpre_descr =
+ rxf_stats->rx_drops_no_tpre_descr;
+ drvs->rx_drops_too_many_frags =
+ rxf_stats->rx_drops_too_many_frags;
+ adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops;
+}
+
+static void populate_lancer_stats(struct be_adapter *adapter)
+{
+
+ struct be_drv_stats *drvs = &adapter->drv_stats;
+ struct lancer_cmd_pport_stats *pport_stats = pport_stats_from_cmd
+ (adapter);
+ drvs->rx_priority_pause_frames = 0;
+ drvs->pmem_fifo_overflow_drop = 0;
+ drvs->rx_pause_frames =
+ make_64bit_val(pport_stats->rx_pause_frames_lo,
+ pport_stats->rx_pause_frames_hi);
+ drvs->rx_crc_errors = make_64bit_val(pport_stats->rx_crc_errors_hi,
+ pport_stats->rx_crc_errors_lo);
+ drvs->rx_control_frames =
+ make_64bit_val(pport_stats->rx_control_frames_hi,
+ pport_stats->rx_control_frames_lo);
+ drvs->rx_in_range_errors = pport_stats->rx_in_range_errors;
+ drvs->rx_frame_too_long =
+ make_64bit_val(pport_stats->rx_internal_mac_errors_hi,
+ pport_stats->rx_frames_too_long_lo);
+ drvs->rx_dropped_runt = pport_stats->rx_dropped_runt;
+ drvs->rx_ip_checksum_errs = pport_stats->rx_ip_checksum_errors;
+ drvs->rx_tcp_checksum_errs = pport_stats->rx_tcp_checksum_errors;
+ drvs->rx_udp_checksum_errs = pport_stats->rx_udp_checksum_errors;
+ drvs->rx_dropped_tcp_length =
+ pport_stats->rx_dropped_invalid_tcp_length;
+ drvs->rx_dropped_too_small = pport_stats->rx_dropped_too_small;
+ drvs->rx_dropped_too_short = pport_stats->rx_dropped_too_short;
+ drvs->rx_out_range_errors = pport_stats->rx_out_of_range_errors;
+ drvs->rx_dropped_header_too_small =
+ pport_stats->rx_dropped_header_too_small;
+ drvs->rx_input_fifo_overflow_drop = pport_stats->rx_fifo_overflow;
+ drvs->rx_address_match_errors = pport_stats->rx_address_match_errors;
+ drvs->rx_alignment_symbol_errors =
+ make_64bit_val(pport_stats->rx_symbol_errors_hi,
+ pport_stats->rx_symbol_errors_lo);
+ drvs->rxpp_fifo_overflow_drop = pport_stats->rx_fifo_overflow;
+ drvs->tx_pauseframes = make_64bit_val(pport_stats->tx_pause_frames_hi,
+ pport_stats->tx_pause_frames_lo);
+ drvs->tx_controlframes =
+ make_64bit_val(pport_stats->tx_control_frames_hi,
+ pport_stats->tx_control_frames_lo);
+ drvs->jabber_events = pport_stats->rx_jabbers;
+ drvs->rx_drops_no_pbuf = 0;
+ drvs->rx_drops_no_txpb = 0;
+ drvs->rx_drops_no_erx_descr = 0;
+ drvs->rx_drops_invalid_ring = pport_stats->rx_drops_invalid_queue;
+ drvs->forwarded_packets = make_64bit_val(pport_stats->num_forwards_hi,
+ pport_stats->num_forwards_lo);
+ drvs->rx_drops_mtu = make_64bit_val(pport_stats->rx_drops_mtu_hi,
+ pport_stats->rx_drops_mtu_lo);
+ drvs->rx_drops_no_tpre_descr = 0;
+ drvs->rx_drops_too_many_frags =
+ make_64bit_val(pport_stats->rx_drops_too_many_frags_hi,
+ pport_stats->rx_drops_too_many_frags_lo);
+}
+
+void be_parse_stats(struct be_adapter *adapter)
+{
+ if (adapter->generation == BE_GEN3) {
+ if (lancer_chip(adapter))
+ populate_lancer_stats(adapter);
+ else
+ populate_be3_stats(adapter);
+ } else {
+ populate_be2_stats(adapter);
+ }
+}
+
void netdev_stats_update(struct be_adapter *adapter)
{
- struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats_cmd.va);
- struct be_rxf_stats *rxf_stats = &hw_stats->rxf;
- struct be_port_rxf_stats *port_stats =
- &rxf_stats->port[adapter->port_num];
+ struct be_drv_stats *drvs = &adapter->drv_stats;
struct net_device_stats *dev_stats = &adapter->netdev->stats;
- struct be_erx_stats *erx_stats = &hw_stats->erx;
struct be_rx_obj *rxo;
int i;
@@ -267,43 +434,54 @@ void netdev_stats_update(struct be_adapter *adapter)
dev_stats->rx_bytes += rx_stats(rxo)->rx_bytes;
dev_stats->multicast += rx_stats(rxo)->rx_mcast_pkts;
/* no space in linux buffers: best possible approximation */
- dev_stats->rx_dropped +=
- erx_stats->rx_drops_no_fragments[rxo->q.id];
+ if (adapter->generation == BE_GEN3) {
+ if (!(lancer_chip(adapter))) {
+ struct be_erx_stats_v1 *erx_stats =
+ be_erx_stats_from_cmd(adapter);
+ dev_stats->rx_dropped +=
+ erx_stats->rx_drops_no_fragments[rxo->q.id];
+ }
+ } else {
+ struct be_erx_stats_v0 *erx_stats =
+ be_erx_stats_from_cmd(adapter);
+ dev_stats->rx_dropped +=
+ erx_stats->rx_drops_no_fragments[rxo->q.id];
+ }
}
dev_stats->tx_packets = tx_stats(adapter)->be_tx_pkts;
dev_stats->tx_bytes = tx_stats(adapter)->be_tx_bytes;
/* bad pkts received */
- dev_stats->rx_errors = port_stats->rx_crc_errors +
- port_stats->rx_alignment_symbol_errors +
- port_stats->rx_in_range_errors +
- port_stats->rx_out_range_errors +
- port_stats->rx_frame_too_long +
- port_stats->rx_dropped_too_small +
- port_stats->rx_dropped_too_short +
- port_stats->rx_dropped_header_too_small +
- port_stats->rx_dropped_tcp_length +
- port_stats->rx_dropped_runt +
- port_stats->rx_tcp_checksum_errs +
- port_stats->rx_ip_checksum_errs +
- port_stats->rx_udp_checksum_errs;
+ dev_stats->rx_errors = drvs->rx_crc_errors +
+ drvs->rx_alignment_symbol_errors +
+ drvs->rx_in_range_errors +
+ drvs->rx_out_range_errors +
+ drvs->rx_frame_too_long +
+ drvs->rx_dropped_too_small +
+ drvs->rx_dropped_too_short +
+ drvs->rx_dropped_header_too_small +
+ drvs->rx_dropped_tcp_length +
+ drvs->rx_dropped_runt +
+ drvs->rx_tcp_checksum_errs +
+ drvs->rx_ip_checksum_errs +
+ drvs->rx_udp_checksum_errs;
/* detailed rx errors */
- dev_stats->rx_length_errors = port_stats->rx_in_range_errors +
- port_stats->rx_out_range_errors +
- port_stats->rx_frame_too_long;
+ dev_stats->rx_length_errors = drvs->rx_in_range_errors +
+ drvs->rx_out_range_errors +
+ drvs->rx_frame_too_long;
- dev_stats->rx_crc_errors = port_stats->rx_crc_errors;
+ dev_stats->rx_crc_errors = drvs->rx_crc_errors;
/* frame alignment errors */
- dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors;
+ dev_stats->rx_frame_errors = drvs->rx_alignment_symbol_errors;
/* receiver fifo overrun */
/* drops_no_pbuf is no per i/f, it's per BE card */
- dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow +
- port_stats->rx_input_fifo_overflow +
- rxf_stats->rx_drops_no_pbuf;
+ dev_stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop +
+ drvs->rx_input_fifo_overflow_drop +
+ drvs->rx_drops_no_pbuf;
}
void be_link_status_update(struct be_adapter *adapter, bool link_up)
@@ -703,7 +881,7 @@ static void be_set_multicast_list(struct net_device *netdev)
struct be_adapter *adapter = netdev_priv(netdev);
if (netdev->flags & IFF_PROMISC) {
- be_cmd_promiscuous_config(adapter, adapter->port_num, 1);
+ be_cmd_promiscuous_config(adapter, true);
adapter->promiscuous = true;
goto done;
}
@@ -711,7 +889,7 @@ static void be_set_multicast_list(struct net_device *netdev)
/* BE was previously in promiscuous mode; disable it */
if (adapter->promiscuous) {
adapter->promiscuous = false;
- be_cmd_promiscuous_config(adapter, adapter->port_num, 0);
+ be_cmd_promiscuous_config(adapter, false);
}
/* Enable multicast promisc if num configured exceeds what we support */
@@ -993,9 +1171,10 @@ static void be_rx_compl_process(struct be_adapter *adapter,
struct be_rx_obj *rxo,
struct be_rx_compl_info *rxcp)
{
+ struct net_device *netdev = adapter->netdev;
struct sk_buff *skb;
- skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN);
+ skb = netdev_alloc_skb_ip_align(netdev, BE_HDR_LEN);
if (unlikely(!skb)) {
if (net_ratelimit())
dev_warn(&adapter->pdev->dev, "skb alloc failed\n");
@@ -1005,13 +1184,16 @@ static void be_rx_compl_process(struct be_adapter *adapter,
skb_fill_rx_data(adapter, rxo, skb, rxcp);
- if (likely(adapter->rx_csum && csum_passed(rxcp)))
+ if (likely((netdev->features & NETIF_F_RXCSUM) && csum_passed(rxcp)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
skb_checksum_none_assert(skb);
skb->truesize = skb->len + sizeof(struct sk_buff);
- skb->protocol = eth_type_trans(skb, adapter->netdev);
+ skb->protocol = eth_type_trans(skb, netdev);
+ if (adapter->netdev->features & NETIF_F_RXHASH)
+ skb->rxhash = rxcp->rss_hash;
+
if (unlikely(rxcp->vlanf)) {
if (!adapter->vlan_grp || adapter->vlans_added == 0) {
@@ -1073,6 +1255,8 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
skb->data_len = rxcp->pkt_size;
skb->truesize += rxcp->pkt_size;
skb->ip_summed = CHECKSUM_UNNECESSARY;
+ if (adapter->netdev->features & NETIF_F_RXHASH)
+ skb->rxhash = rxcp->rss_hash;
if (likely(!rxcp->vlanf))
napi_gro_frags(&eq_obj->napi);
@@ -1103,9 +1287,14 @@ static void be_parse_rx_compl_v1(struct be_adapter *adapter,
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, numfrags, compl);
rxcp->pkt_type =
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl);
- rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm, compl);
- rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag,
- compl);
+ rxcp->rss_hash =
+ AMAP_GET_BITS(struct amap_eth_rx_compl_v1, rsshash, rxcp);
+ if (rxcp->vlanf) {
+ rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm,
+ compl);
+ rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag,
+ compl);
+ }
}
static void be_parse_rx_compl_v0(struct be_adapter *adapter,
@@ -1130,9 +1319,14 @@ static void be_parse_rx_compl_v0(struct be_adapter *adapter,
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, numfrags, compl);
rxcp->pkt_type =
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl);
- rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm, compl);
- rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag,
- compl);
+ rxcp->rss_hash =
+ AMAP_GET_BITS(struct amap_eth_rx_compl_v0, rsshash, rxcp);
+ if (rxcp->vlanf) {
+ rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm,
+ compl);
+ rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag,
+ compl);
+ }
}
static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
@@ -1154,17 +1348,20 @@ static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
else
be_parse_rx_compl_v0(adapter, compl, rxcp);
- /* vlanf could be wrongly set in some cards. ignore if vtm is not set */
- if ((adapter->function_mode & 0x400) && !rxcp->vtm)
- rxcp->vlanf = 0;
+ if (rxcp->vlanf) {
+ /* vlanf could be wrongly set in some cards.
+ * ignore if vtm is not set */
+ if ((adapter->function_mode & 0x400) && !rxcp->vtm)
+ rxcp->vlanf = 0;
- if (!lancer_chip(adapter))
- rxcp->vlan_tag = swab16(rxcp->vlan_tag);
+ if (!lancer_chip(adapter))
+ rxcp->vlan_tag = swab16(rxcp->vlan_tag);
- if (((adapter->pvid & VLAN_VID_MASK) ==
- (rxcp->vlan_tag & VLAN_VID_MASK)) &&
- !adapter->vlan_tag[rxcp->vlan_tag])
- rxcp->vlanf = 0;
+ if (((adapter->pvid & VLAN_VID_MASK) ==
+ (rxcp->vlan_tag & VLAN_VID_MASK)) &&
+ !adapter->vlan_tag[rxcp->vlan_tag])
+ rxcp->vlanf = 0;
+ }
/* As the compl has been parsed, reset it; we wont touch it again */
compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] = 0;
@@ -1261,7 +1458,7 @@ static struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq)
return txcp;
}
-static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index)
+static u16 be_tx_compl_process(struct be_adapter *adapter, u16 last_index)
{
struct be_queue_info *txq = &adapter->tx_obj.q;
struct be_eth_wrb *wrb;
@@ -1288,9 +1485,8 @@ static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index)
queue_tail_inc(txq);
} while (cur_index != last_index);
- atomic_sub(num_wrbs, &txq->used);
-
kfree_skb(sent_skb);
+ return num_wrbs;
}
static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj)
@@ -1373,7 +1569,7 @@ static void be_tx_compl_clean(struct be_adapter *adapter)
struct be_queue_info *tx_cq = &adapter->tx_obj.cq;
struct be_queue_info *txq = &adapter->tx_obj.q;
struct be_eth_tx_compl *txcp;
- u16 end_idx, cmpl = 0, timeo = 0;
+ u16 end_idx, cmpl = 0, timeo = 0, num_wrbs = 0;
struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list;
struct sk_buff *sent_skb;
bool dummy_wrb;
@@ -1383,12 +1579,14 @@ static void be_tx_compl_clean(struct be_adapter *adapter)
while ((txcp = be_tx_compl_get(tx_cq))) {
end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl,
wrb_index, txcp);
- be_tx_compl_process(adapter, end_idx);
+ num_wrbs += be_tx_compl_process(adapter, end_idx);
cmpl++;
}
if (cmpl) {
be_cq_notify(adapter, tx_cq->id, false, cmpl);
+ atomic_sub(num_wrbs, &txq->used);
cmpl = 0;
+ num_wrbs = 0;
}
if (atomic_read(&txq->used) == 0 || ++timeo > 200)
@@ -1408,7 +1606,8 @@ static void be_tx_compl_clean(struct be_adapter *adapter)
index_adv(&end_idx,
wrb_cnt_for_skb(adapter, sent_skb, &dummy_wrb) - 1,
txq->len);
- be_tx_compl_process(adapter, end_idx);
+ num_wrbs = be_tx_compl_process(adapter, end_idx);
+ atomic_sub(num_wrbs, &txq->used);
}
}
@@ -1573,12 +1772,31 @@ static void be_rx_queues_destroy(struct be_adapter *adapter)
}
}
+static u32 be_num_rxqs_want(struct be_adapter *adapter)
+{
+ if (multi_rxq && (adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
+ !adapter->sriov_enabled && !(adapter->function_mode & 0x400)) {
+ return 1 + MAX_RSS_QS; /* one default non-RSS queue */
+ } else {
+ dev_warn(&adapter->pdev->dev,
+ "No support for multiple RX queues\n");
+ return 1;
+ }
+}
+
static int be_rx_queues_create(struct be_adapter *adapter)
{
struct be_queue_info *eq, *q, *cq;
struct be_rx_obj *rxo;
int rc, i;
+ adapter->num_rx_qs = min(be_num_rxqs_want(adapter),
+ msix_enabled(adapter) ?
+ adapter->num_msix_vec - 1 : 1);
+ if (adapter->num_rx_qs != MAX_RX_QS)
+ dev_warn(&adapter->pdev->dev,
+ "Can create only %d RX queues", adapter->num_rx_qs);
+
adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
for_all_rx_queues(adapter, rxo, i) {
rxo->adapter = adapter;
@@ -1724,12 +1942,15 @@ static int be_poll_rx(struct napi_struct *napi, int budget)
break;
/* Ignore flush completions */
- if (rxcp->num_rcvd) {
+ if (rxcp->num_rcvd && rxcp->pkt_size) {
if (do_gro(rxcp))
be_rx_compl_process_gro(adapter, rxo, rxcp);
else
be_rx_compl_process(adapter, rxo, rxcp);
+ } else if (rxcp->pkt_size == 0) {
+ be_rx_compl_discard(adapter, rxo, rxcp);
}
+
be_rx_stats_update(rxo, rxcp);
}
@@ -1760,12 +1981,12 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
struct be_queue_info *tx_cq = &adapter->tx_obj.cq;
struct be_eth_tx_compl *txcp;
int tx_compl = 0, mcc_compl, status = 0;
- u16 end_idx;
+ u16 end_idx, num_wrbs = 0;
while ((txcp = be_tx_compl_get(tx_cq))) {
end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl,
wrb_index, txcp);
- be_tx_compl_process(adapter, end_idx);
+ num_wrbs += be_tx_compl_process(adapter, end_idx);
tx_compl++;
}
@@ -1781,6 +2002,8 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
if (tx_compl) {
be_cq_notify(adapter, adapter->tx_obj.cq.id, true, tx_compl);
+ atomic_sub(num_wrbs, &txq->used);
+
/* As Tx wrbs have been freed up, wake up netdev queue if
* it was stopped due to lack of tx wrbs.
*/
@@ -1843,6 +2066,9 @@ static void be_worker(struct work_struct *work)
struct be_rx_obj *rxo;
int i;
+ if (!adapter->ue_detected && !lancer_chip(adapter))
+ be_detect_dump_ue(adapter);
+
/* when interrupts are not yet enabled, just reap any pending
* mcc completions */
if (!netif_running(adapter->netdev)) {
@@ -1855,15 +2081,16 @@ static void be_worker(struct work_struct *work)
be_cq_notify(adapter, mcc_obj->cq.id, false, mcc_compl);
}
- if (!adapter->ue_detected && !lancer_chip(adapter))
- be_detect_dump_ue(adapter);
-
goto reschedule;
}
- if (!adapter->stats_cmd_sent)
- be_cmd_get_stats(adapter, &adapter->stats_cmd);
-
+ if (!adapter->stats_cmd_sent) {
+ if (lancer_chip(adapter))
+ lancer_cmd_get_pport_stats(adapter,
+ &adapter->stats_cmd);
+ else
+ be_cmd_get_stats(adapter, &adapter->stats_cmd);
+ }
be_tx_rate_update(adapter);
for_all_rx_queues(adapter, rxo, i) {
@@ -1875,8 +2102,6 @@ static void be_worker(struct work_struct *work)
be_post_rx_frags(rxo, GFP_KERNEL);
}
}
- if (!adapter->ue_detected && !lancer_chip(adapter))
- be_detect_dump_ue(adapter);
reschedule:
adapter->work_counter++;
@@ -1885,51 +2110,35 @@ reschedule:
static void be_msix_disable(struct be_adapter *adapter)
{
- if (adapter->msix_enabled) {
+ if (msix_enabled(adapter)) {
pci_disable_msix(adapter->pdev);
- adapter->msix_enabled = false;
- }
-}
-
-static int be_num_rxqs_get(struct be_adapter *adapter)
-{
- if (multi_rxq && (adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
- !adapter->sriov_enabled && !(adapter->function_mode & 0x400)) {
- return 1 + MAX_RSS_QS; /* one default non-RSS queue */
- } else {
- dev_warn(&adapter->pdev->dev,
- "No support for multiple RX queues\n");
- return 1;
+ adapter->num_msix_vec = 0;
}
}
static void be_msix_enable(struct be_adapter *adapter)
{
#define BE_MIN_MSIX_VECTORS (1 + 1) /* Rx + Tx */
- int i, status;
+ int i, status, num_vec;
- adapter->num_rx_qs = be_num_rxqs_get(adapter);
+ num_vec = be_num_rxqs_want(adapter) + 1;
- for (i = 0; i < (adapter->num_rx_qs + 1); i++)
+ for (i = 0; i < num_vec; i++)
adapter->msix_entries[i].entry = i;
- status = pci_enable_msix(adapter->pdev, adapter->msix_entries,
- adapter->num_rx_qs + 1);
+ status = pci_enable_msix(adapter->pdev, adapter->msix_entries, num_vec);
if (status == 0) {
goto done;
} else if (status >= BE_MIN_MSIX_VECTORS) {
+ num_vec = status;
if (pci_enable_msix(adapter->pdev, adapter->msix_entries,
- status) == 0) {
- adapter->num_rx_qs = status - 1;
- dev_warn(&adapter->pdev->dev,
- "Could alloc only %d MSIx vectors. "
- "Using %d RX Qs\n", status, adapter->num_rx_qs);
+ num_vec) == 0)
goto done;
- }
}
return;
done:
- adapter->msix_enabled = true;
+ adapter->num_msix_vec = num_vec;
+ return;
}
static void be_sriov_enable(struct be_adapter *adapter)
@@ -1937,7 +2146,20 @@ static void be_sriov_enable(struct be_adapter *adapter)
be_check_sriov_fn_type(adapter);
#ifdef CONFIG_PCI_IOV
if (be_physfn(adapter) && num_vfs) {
- int status;
+ int status, pos;
+ u16 nvfs;
+
+ pos = pci_find_ext_capability(adapter->pdev,
+ PCI_EXT_CAP_ID_SRIOV);
+ pci_read_config_word(adapter->pdev,
+ pos + PCI_SRIOV_TOTAL_VF, &nvfs);
+
+ if (num_vfs > nvfs) {
+ dev_info(&adapter->pdev->dev,
+ "Device supports %d VFs and not %d\n",
+ nvfs, num_vfs);
+ num_vfs = nvfs;
+ }
status = pci_enable_sriov(adapter->pdev, num_vfs);
adapter->sriov_enabled = status ? false : true;
@@ -2010,8 +2232,7 @@ err_msix:
err:
dev_warn(&adapter->pdev->dev,
"MSIX Request IRQ failed - err %d\n", status);
- pci_disable_msix(adapter->pdev);
- adapter->msix_enabled = false;
+ be_msix_disable(adapter);
return status;
}
@@ -2020,7 +2241,7 @@ static int be_irq_register(struct be_adapter *adapter)
struct net_device *netdev = adapter->netdev;
int status;
- if (adapter->msix_enabled) {
+ if (msix_enabled(adapter)) {
status = be_msix_register(adapter);
if (status == 0)
goto done;
@@ -2053,7 +2274,7 @@ static void be_irq_unregister(struct be_adapter *adapter)
return;
/* INTx */
- if (!adapter->msix_enabled) {
+ if (!msix_enabled(adapter)) {
free_irq(netdev->irq, adapter);
goto done;
}
@@ -2095,7 +2316,7 @@ static int be_close(struct net_device *netdev)
be_cq_notify(adapter, rxo->cq.id, false, 0);
}
- if (adapter->msix_enabled) {
+ if (msix_enabled(adapter)) {
vec = be_msix_vec_get(adapter, tx_eq);
synchronize_irq(vec);
@@ -2148,7 +2369,7 @@ static int be_open(struct net_device *netdev)
be_async_mcc_enable(adapter);
status = be_cmd_link_status_query(adapter, &link_up, &mac_speed,
- &link_speed);
+ &link_speed, 0);
if (status)
goto err;
be_link_status_update(adapter, link_up);
@@ -2268,7 +2489,7 @@ static int be_setup(struct be_adapter *adapter)
BE_IF_FLAGS_PASS_L3L4_ERRORS;
en_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS;
- if (be_multi_rxq(adapter)) {
+ if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) {
cap_flags |= BE_IF_FLAGS_RSS;
en_flags |= BE_IF_FLAGS_RSS;
}
@@ -2325,7 +2546,6 @@ static int be_setup(struct be_adapter *adapter)
return 0;
- be_mcc_queues_destroy(adapter);
rx_qs_destroy:
be_rx_queues_destroy(adapter);
tx_qs_destroy:
@@ -2493,7 +2713,6 @@ static int be_flash_data(struct be_adapter *adapter,
"cmd to write to flash rom failed.\n");
return -1;
}
- yield();
}
}
return 0;
@@ -2511,32 +2730,96 @@ static int get_ufigen_type(struct flash_file_hdr_g2 *fhdr)
return 0;
}
-int be_load_fw(struct be_adapter *adapter, u8 *func)
+static int lancer_fw_download(struct be_adapter *adapter,
+ const struct firmware *fw)
{
- char fw_file[ETHTOOL_FLASH_MAX_FILENAME];
- const struct firmware *fw;
- struct flash_file_hdr_g2 *fhdr;
- struct flash_file_hdr_g3 *fhdr3;
- struct image_hdr *img_hdr_ptr = NULL;
+#define LANCER_FW_DOWNLOAD_CHUNK (32 * 1024)
+#define LANCER_FW_DOWNLOAD_LOCATION "/prg"
struct be_dma_mem flash_cmd;
- int status, i = 0, num_imgs = 0;
- const u8 *p;
+ const u8 *data_ptr = NULL;
+ u8 *dest_image_ptr = NULL;
+ size_t image_size = 0;
+ u32 chunk_size = 0;
+ u32 data_written = 0;
+ u32 offset = 0;
+ int status = 0;
+ u8 add_status = 0;
- if (!netif_running(adapter->netdev)) {
+ if (!IS_ALIGNED(fw->size, sizeof(u32))) {
dev_err(&adapter->pdev->dev,
- "Firmware load not allowed (interface is down)\n");
- return -EPERM;
+ "FW Image not properly aligned. "
+ "Length must be 4 byte aligned.\n");
+ status = -EINVAL;
+ goto lancer_fw_exit;
+ }
+
+ flash_cmd.size = sizeof(struct lancer_cmd_req_write_object)
+ + LANCER_FW_DOWNLOAD_CHUNK;
+ flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
+ &flash_cmd.dma, GFP_KERNEL);
+ if (!flash_cmd.va) {
+ status = -ENOMEM;
+ dev_err(&adapter->pdev->dev,
+ "Memory allocation failure while flashing\n");
+ goto lancer_fw_exit;
}
- strcpy(fw_file, func);
+ dest_image_ptr = flash_cmd.va +
+ sizeof(struct lancer_cmd_req_write_object);
+ image_size = fw->size;
+ data_ptr = fw->data;
- status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
- if (status)
- goto fw_exit;
+ while (image_size) {
+ chunk_size = min_t(u32, image_size, LANCER_FW_DOWNLOAD_CHUNK);
+
+ /* Copy the image chunk content. */
+ memcpy(dest_image_ptr, data_ptr, chunk_size);
+
+ status = lancer_cmd_write_object(adapter, &flash_cmd,
+ chunk_size, offset, LANCER_FW_DOWNLOAD_LOCATION,
+ &data_written, &add_status);
+
+ if (status)
+ break;
+
+ offset += data_written;
+ data_ptr += data_written;
+ image_size -= data_written;
+ }
+
+ if (!status) {
+ /* Commit the FW written */
+ status = lancer_cmd_write_object(adapter, &flash_cmd,
+ 0, offset, LANCER_FW_DOWNLOAD_LOCATION,
+ &data_written, &add_status);
+ }
+
+ dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va,
+ flash_cmd.dma);
+ if (status) {
+ dev_err(&adapter->pdev->dev,
+ "Firmware load error. "
+ "Status code: 0x%x Additional Status: 0x%x\n",
+ status, add_status);
+ goto lancer_fw_exit;
+ }
+
+ dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
+lancer_fw_exit:
+ return status;
+}
+
+static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw)
+{
+ struct flash_file_hdr_g2 *fhdr;
+ struct flash_file_hdr_g3 *fhdr3;
+ struct image_hdr *img_hdr_ptr = NULL;
+ struct be_dma_mem flash_cmd;
+ const u8 *p;
+ int status = 0, i = 0, num_imgs = 0;
p = fw->data;
fhdr = (struct flash_file_hdr_g2 *) p;
- dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file);
flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024;
flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
@@ -2545,7 +2828,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
status = -ENOMEM;
dev_err(&adapter->pdev->dev,
"Memory allocation failure while flashing\n");
- goto fw_exit;
+ goto be_fw_exit;
}
if ((adapter->generation == BE_GEN3) &&
@@ -2573,11 +2856,37 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
flash_cmd.dma);
if (status) {
dev_err(&adapter->pdev->dev, "Firmware load error\n");
- goto fw_exit;
+ goto be_fw_exit;
}
dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
+be_fw_exit:
+ return status;
+}
+
+int be_load_fw(struct be_adapter *adapter, u8 *fw_file)
+{
+ const struct firmware *fw;
+ int status;
+
+ if (!netif_running(adapter->netdev)) {
+ dev_err(&adapter->pdev->dev,
+ "Firmware load not allowed (interface is down)\n");
+ return -1;
+ }
+
+ status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
+ if (status)
+ goto fw_exit;
+
+ dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file);
+
+ if (lancer_chip(adapter))
+ status = lancer_fw_download(adapter, fw);
+ else
+ status = be_fw_download(adapter, fw);
+
fw_exit:
release_firmware(fw);
return status;
@@ -2606,10 +2915,14 @@ static void be_netdev_init(struct net_device *netdev)
struct be_rx_obj *rxo;
int i;
- netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
- NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
- NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
- NETIF_F_GRO | NETIF_F_TSO6;
+ netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
+ NETIF_F_HW_VLAN_TX;
+ if (be_multi_rxq(adapter))
+ netdev->hw_features |= NETIF_F_RXHASH;
+
+ netdev->features |= netdev->hw_features |
+ NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
@@ -2619,8 +2932,6 @@ static void be_netdev_init(struct net_device *netdev)
netdev->flags |= IFF_MULTICAST;
- adapter->rx_csum = true;
-
/* Default settings for Rx and Tx flow control */
adapter->rx_fc = true;
adapter->tx_fc = true;
@@ -2788,7 +3099,14 @@ static int be_stats_init(struct be_adapter *adapter)
{
struct be_dma_mem *cmd = &adapter->stats_cmd;
- cmd->size = sizeof(struct be_cmd_req_get_stats);
+ if (adapter->generation == BE_GEN2) {
+ cmd->size = sizeof(struct be_cmd_req_get_stats_v0);
+ } else {
+ if (lancer_chip(adapter))
+ cmd->size = sizeof(struct lancer_cmd_req_pport_stats);
+ else
+ cmd->size = sizeof(struct be_cmd_req_get_stats_v1);
+ }
cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma,
GFP_KERNEL);
if (cmd->va == NULL)
@@ -2814,6 +3132,7 @@ static void __devexit be_remove(struct pci_dev *pdev)
be_ctrl_cleanup(adapter);
+ kfree(adapter->vf_cfg);
be_sriov_disable(adapter);
be_msix_disable(adapter);
@@ -2841,7 +3160,8 @@ static int be_get_config(struct be_adapter *adapter)
memset(mac, 0, ETH_ALEN);
- if (be_physfn(adapter)) {
+ /* A default permanent address is given to each VF for Lancer*/
+ if (be_physfn(adapter) || lancer_chip(adapter)) {
status = be_cmd_mac_addr_query(adapter, mac,
MAC_ADDRESS_TYPE_NETWORK, true /*permanent */, 0);
@@ -2883,6 +3203,7 @@ static int be_dev_family_check(struct be_adapter *adapter)
adapter->generation = BE_GEN3;
break;
case OC_DEVICE_ID3:
+ case OC_DEVICE_ID4:
pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf);
if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
SLI_INTF_IF_TYPE_SHIFT;
@@ -2892,10 +3213,6 @@ static int be_dev_family_check(struct be_adapter *adapter)
dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n");
return -EINVAL;
}
- if (num_vfs > 0) {
- dev_err(&pdev->dev, "VFs not supported\n");
- return -EINVAL;
- }
adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >>
SLI_INTF_FAMILY_SHIFT);
adapter->generation = BE_GEN3;
@@ -2998,16 +3315,23 @@ static int __devinit be_probe(struct pci_dev *pdev,
}
be_sriov_enable(adapter);
+ if (adapter->sriov_enabled) {
+ adapter->vf_cfg = kcalloc(num_vfs,
+ sizeof(struct be_vf_cfg), GFP_KERNEL);
+
+ if (!adapter->vf_cfg)
+ goto free_netdev;
+ }
status = be_ctrl_init(adapter);
if (status)
- goto free_netdev;
+ goto free_vf_cfg;
if (lancer_chip(adapter)) {
status = lancer_test_and_set_rdy_state(adapter);
if (status) {
dev_err(&pdev->dev, "Adapter in non recoverable error\n");
- goto free_netdev;
+ goto ctrl_clean;
}
}
@@ -3050,9 +3374,24 @@ static int __devinit be_probe(struct pci_dev *pdev,
netif_carrier_off(netdev);
if (be_physfn(adapter) && adapter->sriov_enabled) {
- status = be_vf_eth_addr_config(adapter);
- if (status)
- goto unreg_netdev;
+ u8 mac_speed;
+ bool link_up;
+ u16 vf, lnk_speed;
+
+ if (!lancer_chip(adapter)) {
+ status = be_vf_eth_addr_config(adapter);
+ if (status)
+ goto unreg_netdev;
+ }
+
+ for (vf = 0; vf < num_vfs; vf++) {
+ status = be_cmd_link_status_query(adapter, &link_up,
+ &mac_speed, &lnk_speed, vf + 1);
+ if (!status)
+ adapter->vf_cfg[vf].vf_tx_rate = lnk_speed * 10;
+ else
+ goto unreg_netdev;
+ }
}
dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num);
@@ -3069,6 +3408,8 @@ stats_clean:
be_stats_cleanup(adapter);
ctrl_clean:
be_ctrl_cleanup(adapter);
+free_vf_cfg:
+ kfree(adapter->vf_cfg);
free_netdev:
be_sriov_disable(adapter);
free_netdev(netdev);
@@ -3153,16 +3494,15 @@ static void be_shutdown(struct pci_dev *pdev)
if (!adapter)
return;
- if (netif_running(adapter->netdev))
- cancel_delayed_work_sync(&adapter->work);
+ cancel_delayed_work_sync(&adapter->work);
netif_device_detach(adapter->netdev);
- be_cmd_reset_function(adapter);
-
if (adapter->wol)
be_setup_wol(adapter, true);
+ be_cmd_reset_function(adapter);
+
pci_disable_device(pdev);
}
@@ -3274,13 +3614,6 @@ static int __init be_init_module(void)
rx_frag_size = 2048;
}
- if (num_vfs > 32) {
- printk(KERN_WARNING DRV_NAME
- " : Module param num_vfs must not be greater than 32."
- "Using 32\n");
- num_vfs = 32;
- }
-
return pci_register_driver(&be_driver);
}
module_init(be_init_module);
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
index 7581518ecfa..fcb9bb3169e 100644
--- a/drivers/net/bna/bfa_ioc.c
+++ b/drivers/net/bna/bfa_ioc.c
@@ -82,7 +82,6 @@ static void bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc);
static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type,
u32 boot_param);
static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr);
-static u32 bfa_ioc_smem_pgoff(struct bfa_ioc *ioc, u32 fmaddr);
static void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc,
char *serial_num);
static void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc,
@@ -1274,13 +1273,12 @@ bfa_ioc_lpu_stop(struct bfa_ioc *ioc)
void
bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr)
{
- u32 pgnum, pgoff;
+ u32 pgnum;
u32 loff = 0;
int i;
u32 *fwsig = (u32 *) fwhdr;
pgnum = bfa_ioc_smem_pgnum(ioc, loff);
- pgoff = bfa_ioc_smem_pgoff(ioc, loff);
writel(pgnum, ioc->ioc_regs.host_page_num_fn);
for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr) / sizeof(u32));
@@ -1514,7 +1512,7 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
u32 boot_env)
{
u32 *fwimg;
- u32 pgnum, pgoff;
+ u32 pgnum;
u32 loff = 0;
u32 chunkno = 0;
u32 i;
@@ -1527,7 +1525,6 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno);
pgnum = bfa_ioc_smem_pgnum(ioc, loff);
- pgoff = bfa_ioc_smem_pgoff(ioc, loff);
writel(pgnum, ioc->ioc_regs.host_page_num_fn);
@@ -1925,12 +1922,6 @@ bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr)
return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr);
}
-static u32
-bfa_ioc_smem_pgoff(struct bfa_ioc *ioc, u32 fmaddr)
-{
- return PSS_SMEM_PGOFF(fmaddr);
-}
-
/**
* Register mailbox message handler function, to be called by common modules
*/
diff --git a/drivers/net/bna/bna_ctrl.c b/drivers/net/bna/bna_ctrl.c
index e1527472b96..53b14169e36 100644
--- a/drivers/net/bna/bna_ctrl.c
+++ b/drivers/net/bna/bna_ctrl.c
@@ -246,7 +246,6 @@ static void
bna_mbox_flush_q(struct bna *bna, struct list_head *q)
{
struct bna_mbox_qe *mb_qe = NULL;
- struct bfi_mhdr *cmd_h;
struct list_head *mb_q;
void (*cbfn)(void *arg, int status);
void *cbarg;
@@ -260,7 +259,6 @@ bna_mbox_flush_q(struct bna *bna, struct list_head *q)
bfa_q_qe_init(mb_qe);
bna->mbox_mod.msg_pending--;
- cmd_h = (struct bfi_mhdr *)(&mb_qe->cmd.msg[0]);
if (cbfn)
cbfn(cbarg, BNA_CB_NOT_EXEC);
}
@@ -2774,23 +2772,6 @@ bna_rit_mod_init(struct bna_rit_mod *rit_mod,
}
}
-static void
-bna_rit_mod_uninit(struct bna_rit_mod *rit_mod)
-{
- struct bna_rit_segment *rit_segment;
- struct list_head *qe;
- int i;
- int j;
-
- for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) {
- j = 0;
- list_for_each(qe, &rit_mod->rit_seg_pool[i]) {
- rit_segment = (struct bna_rit_segment *)qe;
- j++;
- }
- }
-}
-
/*
* Public functions
*/
@@ -2977,8 +2958,6 @@ bna_uninit(struct bna *bna)
bna_ucam_mod_uninit(&bna->ucam_mod);
- bna_rit_mod_uninit(&bna->rit_mod);
-
bna_ib_mod_uninit(&bna->ib_mod);
bna_rx_mod_uninit(&bna->rx_mod);
diff --git a/drivers/net/bna/bna_txrx.c b/drivers/net/bna/bna_txrx.c
index 58c7664040d..380085cc308 100644
--- a/drivers/net/bna/bna_txrx.c
+++ b/drivers/net/bna/bna_txrx.c
@@ -2229,14 +2229,11 @@ void
bna_rit_create(struct bna_rx *rx)
{
struct list_head *qe_rxp;
- struct bna *bna;
struct bna_rxp *rxp;
struct bna_rxq *q0 = NULL;
struct bna_rxq *q1 = NULL;
int offset;
- bna = rx->bna;
-
offset = 0;
list_for_each(qe_rxp, &rx->rxp_q) {
rxp = (struct bna_rxp *)qe_rxp;
@@ -2830,7 +2827,7 @@ bna_rx_create(struct bna *bna, struct bnad *bnad,
struct bna_mem_descr *dsqpt_mem; /* s/w qpt for data */
struct bna_mem_descr *hpage_mem; /* hdr page mem */
struct bna_mem_descr *dpage_mem; /* data page mem */
- int i, cpage_idx = 0, dpage_idx = 0, hpage_idx = 0, ret;
+ int i, cpage_idx = 0, dpage_idx = 0, hpage_idx = 0;
int dpage_count, hpage_count, rcb_idx;
struct bna_ib_config ibcfg;
/* Fail if we don't have enough RXPs, RXQs */
@@ -2924,7 +2921,7 @@ bna_rx_create(struct bna *bna, struct bnad *bnad,
ibcfg.interpkt_timeo = BFI_RX_INTERPKT_TIMEO;
ibcfg.ctrl_flags = BFI_IB_CF_INT_ENABLE;
- ret = bna_ib_config(rxp->cq.ib, &ibcfg);
+ bna_ib_config(rxp->cq.ib, &ibcfg);
/* Link rxqs to rxp */
_rxp_add_rxqs(rxp, q0, q1);
diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c
index 8e6ceab9f4d..e588511f47f 100644
--- a/drivers/net/bna/bnad.c
+++ b/drivers/net/bna/bnad.c
@@ -501,7 +501,7 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget)
skb_put(skb, ntohs(cmpl->length));
if (likely
- (bnad->rx_csum &&
+ ((bnad->netdev->features & NETIF_F_RXCSUM) &&
(((flags & BNA_CQ_EF_IPV4) &&
(flags & BNA_CQ_EF_L3_CKSUM_OK)) ||
(flags & BNA_CQ_EF_IPV6)) &&
@@ -2902,23 +2902,20 @@ bnad_netdev_init(struct bnad *bnad, bool using_dac)
{
struct net_device *netdev = bnad->netdev;
- netdev->features |= NETIF_F_IPV6_CSUM;
- netdev->features |= NETIF_F_TSO;
- netdev->features |= NETIF_F_TSO6;
+ netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_VLAN_TX;
- netdev->features |= NETIF_F_GRO;
- pr_warn("bna: GRO enabled, using kernel stack GRO\n");
+ netdev->vlan_features = NETIF_F_SG | NETIF_F_HIGHDMA |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_TSO | NETIF_F_TSO6;
- netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+ netdev->features |= netdev->hw_features |
+ NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
if (using_dac)
netdev->features |= NETIF_F_HIGHDMA;
- netdev->features |=
- NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_FILTER;
-
- netdev->vlan_features = netdev->features;
netdev->mem_start = bnad->mmio_start;
netdev->mem_end = bnad->mmio_start + bnad->mmio_len - 1;
@@ -2969,7 +2966,6 @@ bnad_init(struct bnad *bnad,
bnad->txq_depth = BNAD_TXQ_DEPTH;
bnad->rxq_depth = BNAD_RXQ_DEPTH;
- bnad->rx_csum = true;
bnad->tx_coalescing_timeo = BFI_TX_COALESCING_TIMEO;
bnad->rx_coalescing_timeo = BFI_RX_COALESCING_TIMEO;
diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h
index a89117fa497..ccdabad0a40 100644
--- a/drivers/net/bna/bnad.h
+++ b/drivers/net/bna/bnad.h
@@ -237,8 +237,6 @@ struct bnad {
struct bna_rx_config rx_config[BNAD_MAX_RXS];
struct bna_tx_config tx_config[BNAD_MAX_TXS];
- u32 rx_csum;
-
void __iomem *bar0; /* BAR0 address */
struct bna bna;
diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c
index 142d6047da2..3330cd78da2 100644
--- a/drivers/net/bna/bnad_ethtool.c
+++ b/drivers/net/bna/bnad_ethtool.c
@@ -237,10 +237,10 @@ bnad_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
cmd->phy_address = 0;
if (netif_carrier_ok(netdev)) {
- cmd->speed = SPEED_10000;
+ ethtool_cmd_speed_set(cmd, SPEED_10000);
cmd->duplex = DUPLEX_FULL;
} else {
- cmd->speed = -1;
+ ethtool_cmd_speed_set(cmd, -1);
cmd->duplex = -1;
}
cmd->transceiver = XCVR_EXTERNAL;
@@ -256,7 +256,8 @@ bnad_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
/* 10G full duplex setting supported only */
if (cmd->autoneg == AUTONEG_ENABLE)
return -EOPNOTSUPP; else {
- if ((cmd->speed == SPEED_10000) && (cmd->duplex == DUPLEX_FULL))
+ if ((ethtool_cmd_speed(cmd) == SPEED_10000)
+ && (cmd->duplex == DUPLEX_FULL))
return 0;
}
@@ -806,61 +807,6 @@ bnad_set_pauseparam(struct net_device *netdev,
return 0;
}
-static u32
-bnad_get_rx_csum(struct net_device *netdev)
-{
- u32 rx_csum;
- struct bnad *bnad = netdev_priv(netdev);
-
- rx_csum = bnad->rx_csum;
- return rx_csum;
-}
-
-static int
-bnad_set_rx_csum(struct net_device *netdev, u32 rx_csum)
-{
- struct bnad *bnad = netdev_priv(netdev);
-
- mutex_lock(&bnad->conf_mutex);
- bnad->rx_csum = rx_csum;
- mutex_unlock(&bnad->conf_mutex);
- return 0;
-}
-
-static int
-bnad_set_tx_csum(struct net_device *netdev, u32 tx_csum)
-{
- struct bnad *bnad = netdev_priv(netdev);
-
- mutex_lock(&bnad->conf_mutex);
- if (tx_csum) {
- netdev->features |= NETIF_F_IP_CSUM;
- netdev->features |= NETIF_F_IPV6_CSUM;
- } else {
- netdev->features &= ~NETIF_F_IP_CSUM;
- netdev->features &= ~NETIF_F_IPV6_CSUM;
- }
- mutex_unlock(&bnad->conf_mutex);
- return 0;
-}
-
-static int
-bnad_set_tso(struct net_device *netdev, u32 tso)
-{
- struct bnad *bnad = netdev_priv(netdev);
-
- mutex_lock(&bnad->conf_mutex);
- if (tso) {
- netdev->features |= NETIF_F_TSO;
- netdev->features |= NETIF_F_TSO6;
- } else {
- netdev->features &= ~NETIF_F_TSO;
- netdev->features &= ~NETIF_F_TSO6;
- }
- mutex_unlock(&bnad->conf_mutex);
- return 0;
-}
-
static void
bnad_get_strings(struct net_device *netdev, u32 stringset, u8 * string)
{
@@ -1256,14 +1202,6 @@ static struct ethtool_ops bnad_ethtool_ops = {
.set_ringparam = bnad_set_ringparam,
.get_pauseparam = bnad_get_pauseparam,
.set_pauseparam = bnad_set_pauseparam,
- .get_rx_csum = bnad_get_rx_csum,
- .set_rx_csum = bnad_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = bnad_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = bnad_set_tso,
.get_strings = bnad_get_strings,
.get_ethtool_stats = bnad_get_ethtool_stats,
.get_sset_count = bnad_get_sset_count
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index d8383a9af9a..57d3293c65b 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -3174,7 +3174,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
}
skb_checksum_none_assert(skb);
- if (bp->rx_csum &&
+ if ((bp->dev->features & NETIF_F_RXCSUM) &&
(status & (L2_FHDR_STATUS_TCP_SEGMENT |
L2_FHDR_STATUS_UDP_DATAGRAM))) {
@@ -6696,17 +6696,16 @@ bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if (bp->autoneg & AUTONEG_SPEED) {
cmd->autoneg = AUTONEG_ENABLE;
- }
- else {
+ } else {
cmd->autoneg = AUTONEG_DISABLE;
}
if (netif_carrier_ok(dev)) {
- cmd->speed = bp->line_speed;
+ ethtool_cmd_speed_set(cmd, bp->line_speed);
cmd->duplex = bp->duplex;
}
else {
- cmd->speed = -1;
+ ethtool_cmd_speed_set(cmd, -1);
cmd->duplex = -1;
}
spin_unlock_bh(&bp->phy_lock);
@@ -6758,21 +6757,21 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
advertising |= ADVERTISED_Autoneg;
}
else {
+ u32 speed = ethtool_cmd_speed(cmd);
if (cmd->port == PORT_FIBRE) {
- if ((cmd->speed != SPEED_1000 &&
- cmd->speed != SPEED_2500) ||
+ if ((speed != SPEED_1000 &&
+ speed != SPEED_2500) ||
(cmd->duplex != DUPLEX_FULL))
goto err_out_unlock;
- if (cmd->speed == SPEED_2500 &&
+ if (speed == SPEED_2500 &&
!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE))
goto err_out_unlock;
- }
- else if (cmd->speed == SPEED_1000 || cmd->speed == SPEED_2500)
+ } else if (speed == SPEED_1000 || speed == SPEED_2500)
goto err_out_unlock;
autoneg &= ~AUTONEG_SPEED;
- req_line_speed = cmd->speed;
+ req_line_speed = speed;
req_duplex = cmd->duplex;
advertising = 0;
}
@@ -7189,38 +7188,6 @@ bnx2_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
return 0;
}
-static u32
-bnx2_get_rx_csum(struct net_device *dev)
-{
- struct bnx2 *bp = netdev_priv(dev);
-
- return bp->rx_csum;
-}
-
-static int
-bnx2_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct bnx2 *bp = netdev_priv(dev);
-
- bp->rx_csum = data;
- return 0;
-}
-
-static int
-bnx2_set_tso(struct net_device *dev, u32 data)
-{
- struct bnx2 *bp = netdev_priv(dev);
-
- if (data) {
- dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN;
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- dev->features |= NETIF_F_TSO6;
- } else
- dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6 |
- NETIF_F_TSO_ECN);
- return 0;
-}
-
static struct {
char string[ETH_GSTRING_LEN];
} bnx2_stats_str_arr[] = {
@@ -7495,82 +7462,74 @@ bnx2_get_ethtool_stats(struct net_device *dev,
}
static int
-bnx2_phys_id(struct net_device *dev, u32 data)
+bnx2_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state)
{
struct bnx2 *bp = netdev_priv(dev);
- int i;
- u32 save;
- bnx2_set_power_state(bp, PCI_D0);
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ bnx2_set_power_state(bp, PCI_D0);
+
+ bp->leds_save = REG_RD(bp, BNX2_MISC_CFG);
+ REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC);
+ return 1; /* cycle on/off once per second */
+
+ case ETHTOOL_ID_ON:
+ REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE |
+ BNX2_EMAC_LED_1000MB_OVERRIDE |
+ BNX2_EMAC_LED_100MB_OVERRIDE |
+ BNX2_EMAC_LED_10MB_OVERRIDE |
+ BNX2_EMAC_LED_TRAFFIC_OVERRIDE |
+ BNX2_EMAC_LED_TRAFFIC);
+ break;
- if (data == 0)
- data = 2;
+ case ETHTOOL_ID_OFF:
+ REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE);
+ break;
- save = REG_RD(bp, BNX2_MISC_CFG);
- REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC);
+ case ETHTOOL_ID_INACTIVE:
+ REG_WR(bp, BNX2_EMAC_LED, 0);
+ REG_WR(bp, BNX2_MISC_CFG, bp->leds_save);
- for (i = 0; i < (data * 2); i++) {
- if ((i % 2) == 0) {
- REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE);
- }
- else {
- REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE |
- BNX2_EMAC_LED_1000MB_OVERRIDE |
- BNX2_EMAC_LED_100MB_OVERRIDE |
- BNX2_EMAC_LED_10MB_OVERRIDE |
- BNX2_EMAC_LED_TRAFFIC_OVERRIDE |
- BNX2_EMAC_LED_TRAFFIC);
- }
- msleep_interruptible(500);
- if (signal_pending(current))
- break;
+ if (!netif_running(dev))
+ bnx2_set_power_state(bp, PCI_D3hot);
+ break;
}
- REG_WR(bp, BNX2_EMAC_LED, 0);
- REG_WR(bp, BNX2_MISC_CFG, save);
-
- if (!netif_running(dev))
- bnx2_set_power_state(bp, PCI_D3hot);
return 0;
}
-static int
-bnx2_set_tx_csum(struct net_device *dev, u32 data)
+static u32
+bnx2_fix_features(struct net_device *dev, u32 features)
{
struct bnx2 *bp = netdev_priv(dev);
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- return ethtool_op_set_tx_ipv6_csum(dev, data);
- else
- return ethtool_op_set_tx_csum(dev, data);
+ if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN))
+ features |= NETIF_F_HW_VLAN_RX;
+
+ return features;
}
static int
-bnx2_set_flags(struct net_device *dev, u32 data)
+bnx2_set_features(struct net_device *dev, u32 features)
{
struct bnx2 *bp = netdev_priv(dev);
- int rc;
-
- if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) &&
- !(data & ETH_FLAG_RXVLAN))
- return -EINVAL;
/* TSO with VLAN tag won't work with current firmware */
- if (!(data & ETH_FLAG_TXVLAN))
- return -EINVAL;
-
- rc = ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH | ETH_FLAG_RXVLAN |
- ETH_FLAG_TXVLAN);
- if (rc)
- return rc;
+ if (features & NETIF_F_HW_VLAN_TX)
+ dev->vlan_features |= (dev->hw_features & NETIF_F_ALL_TSO);
+ else
+ dev->vlan_features &= ~NETIF_F_ALL_TSO;
- if ((!!(data & ETH_FLAG_RXVLAN) !=
+ if ((!!(features & NETIF_F_HW_VLAN_RX) !=
!!(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) &&
netif_running(dev)) {
bnx2_netif_stop(bp, false);
+ dev->features = features;
bnx2_set_rx_mode(dev);
bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);
bnx2_netif_start(bp, false);
+ return 1;
}
return 0;
@@ -7595,18 +7554,11 @@ static const struct ethtool_ops bnx2_ethtool_ops = {
.set_ringparam = bnx2_set_ringparam,
.get_pauseparam = bnx2_get_pauseparam,
.set_pauseparam = bnx2_set_pauseparam,
- .get_rx_csum = bnx2_get_rx_csum,
- .set_rx_csum = bnx2_set_rx_csum,
- .set_tx_csum = bnx2_set_tx_csum,
- .set_sg = ethtool_op_set_sg,
- .set_tso = bnx2_set_tso,
.self_test = bnx2_self_test,
.get_strings = bnx2_get_strings,
- .phys_id = bnx2_phys_id,
+ .set_phys_id = bnx2_set_phys_id,
.get_ethtool_stats = bnx2_get_ethtool_stats,
.get_sset_count = bnx2_get_sset_count,
- .set_flags = bnx2_set_flags,
- .get_flags = ethtool_op_get_flags,
};
/* Called with rtnl_lock */
@@ -8118,8 +8070,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->tx_ring_size = MAX_TX_DESC_CNT;
bnx2_set_rx_ring_size(bp, 255);
- bp->rx_csum = 1;
-
bp->tx_quick_cons_trip_int = 2;
bp->tx_quick_cons_trip = 20;
bp->tx_ticks_int = 18;
@@ -8311,17 +8261,14 @@ static const struct net_device_ops bnx2_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = bnx2_change_mac_addr,
.ndo_change_mtu = bnx2_change_mtu,
+ .ndo_fix_features = bnx2_fix_features,
+ .ndo_set_features = bnx2_set_features,
.ndo_tx_timeout = bnx2_tx_timeout,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = poll_bnx2,
#endif
};
-static inline void vlan_features_add(struct net_device *dev, u32 flags)
-{
- dev->vlan_features |= flags;
-}
-
static int __devinit
bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@@ -8361,20 +8308,17 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
memcpy(dev->dev_addr, bp->mac_addr, 6);
memcpy(dev->perm_addr, bp->mac_addr, 6);
- dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_GRO |
- NETIF_F_RXHASH;
- vlan_features_add(dev, NETIF_F_IP_CSUM | NETIF_F_SG);
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
- dev->features |= NETIF_F_IPV6_CSUM;
- vlan_features_add(dev, NETIF_F_IPV6_CSUM);
- }
- dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN;
- vlan_features_add(dev, NETIF_F_TSO | NETIF_F_TSO_ECN);
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
- dev->features |= NETIF_F_TSO6;
- vlan_features_add(dev, NETIF_F_TSO6);
- }
+ dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
+ NETIF_F_TSO | NETIF_F_TSO_ECN |
+ NETIF_F_RXHASH | NETIF_F_RXCSUM;
+
+ if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ dev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
+
+ dev->vlan_features = dev->hw_features;
+ dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ dev->features |= dev->hw_features;
+
if ((rc = register_netdev(dev))) {
dev_err(&pdev->dev, "Cannot register net device\n");
goto error;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 68020451dc4..bf371f6fe15 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -6754,8 +6754,6 @@ struct bnx2 {
u32 rx_max_ring_idx;
u32 rx_max_pg_ring_idx;
- u32 rx_csum;
-
/* TX constants */
int tx_ring_size;
u32 tx_wake_thresh;
@@ -6922,6 +6920,7 @@ struct bnx2 {
u8 num_tx_rings;
u8 num_rx_rings;
+ u32 leds_save;
u32 idle_chk_status_idx;
#ifdef BCM_CNIC
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index e0fca701d2f..668a578c49e 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -1,6 +1,6 @@
/* bnx2x.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
@@ -22,8 +22,8 @@
* (you will need to reboot afterwards) */
/* #define BNX2X_STOP_ON_ERROR */
-#define DRV_MODULE_VERSION "1.62.11-0"
-#define DRV_MODULE_RELDATE "2011/01/31"
+#define DRV_MODULE_VERSION "1.62.12-0"
+#define DRV_MODULE_RELDATE "2011/03/20"
#define BNX2X_BC_VER 0x040200
#define BNX2X_MULTI_QUEUE
@@ -473,7 +473,8 @@ struct bnx2x_fastpath {
#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 MIN_RX_AVAIL 128
+#define MIN_RX_SIZE_TPA 72
+#define MIN_RX_SIZE_NONTPA 10
#define INIT_JUMBO_RX_RING_SIZE MAX_RX_AVAIL
#define INIT_RX_RING_SIZE MAX_RX_AVAIL
#define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \
@@ -893,6 +894,22 @@ typedef enum {
(&bp->def_status_blk->sp_sb.\
index_values[HC_SP_INDEX_EQ_CONS])
+/* This is a data that will be used to create a link report message.
+ * We will keep the data used for the last link report in order
+ * to prevent reporting the same link parameters twice.
+ */
+struct bnx2x_link_report_data {
+ u16 line_speed; /* Effective line speed */
+ unsigned long link_report_flags;/* BNX2X_LINK_REPORT_XXX flags */
+};
+
+enum {
+ BNX2X_LINK_REPORT_FD, /* Full DUPLEX */
+ BNX2X_LINK_REPORT_LINK_DOWN,
+ BNX2X_LINK_REPORT_RX_FC_ON,
+ BNX2X_LINK_REPORT_TX_FC_ON,
+};
+
struct bnx2x {
/* Fields used in the tx and intr/napi performance paths
* are grouped together in the beginning of the structure
@@ -918,7 +935,6 @@ struct bnx2x {
int tx_ring_size;
- u32 rx_csum;
/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
#define ETH_OVREHEAD (ETH_HLEN + 8 + 8)
#define ETH_MIN_PACKET_SIZE 60
@@ -1026,6 +1042,9 @@ struct bnx2x {
struct link_params link_params;
struct link_vars link_vars;
+ u32 link_cnt;
+ struct bnx2x_link_report_data last_reported_link;
+
struct mdio_if_info mdio;
struct bnx2x_common common;
@@ -1223,6 +1242,10 @@ struct bnx2x {
/* DCBX Negotiation results */
struct dcbx_features dcbx_local_feat;
u32 dcbx_error;
+#ifdef BCM_DCBNL
+ struct dcbx_features dcbx_remote_feat;
+ u32 dcbx_remote_flags;
+#endif
u32 pending_max;
};
@@ -1442,6 +1465,8 @@ struct bnx2x_func_init_params {
#define WAIT_RAMROD_POLL 0x01
#define WAIT_RAMROD_COMMON 0x02
+void bnx2x_read_mf_cfg(struct bnx2x *bp);
+
/* dmae */
void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32);
void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 16581df5ee4..ca2bbc0e5d4 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -1,6 +1,6 @@
/* bnx2x_cmn.c: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
@@ -27,6 +27,49 @@
static int bnx2x_setup_irqs(struct bnx2x *bp);
+/**
+ * bnx2x_bz_fp - zero content of the fastpath structure.
+ *
+ * @bp: driver handle
+ * @index: fastpath index to be zeroed
+ *
+ * Makes sure the contents of the bp->fp[index].napi is kept
+ * intact.
+ */
+static inline void bnx2x_bz_fp(struct bnx2x *bp, int index)
+{
+ struct bnx2x_fastpath *fp = &bp->fp[index];
+ struct napi_struct orig_napi = fp->napi;
+ /* bzero bnx2x_fastpath contents */
+ memset(fp, 0, sizeof(*fp));
+
+ /* Restore the NAPI object as it has been already initialized */
+ fp->napi = orig_napi;
+}
+
+/**
+ * bnx2x_move_fp - move content of the fastpath structure.
+ *
+ * @bp: driver handle
+ * @from: source FP index
+ * @to: destination FP index
+ *
+ * Makes sure the contents of the bp->fp[to].napi is kept
+ * intact.
+ */
+static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to)
+{
+ struct bnx2x_fastpath *from_fp = &bp->fp[from];
+ struct bnx2x_fastpath *to_fp = &bp->fp[to];
+ struct napi_struct orig_napi = to_fp->napi;
+ /* Move bnx2x_fastpath contents */
+ memcpy(to_fp, from_fp, sizeof(*to_fp));
+ to_fp->index = to;
+
+ /* Restore the NAPI object as it has been already initialized */
+ to_fp->napi = orig_napi;
+}
+
/* free skb in the packet ring at pos idx
* return idx of last bd freed
*/
@@ -265,13 +308,15 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue,
*/
#define TPA_TSTAMP_OPT_LEN 12
/**
- * Calculate the approximate value of the MSS for this
- * aggregation using the first packet of it.
+ * bnx2x_set_lro_mss - calculate the approximate value of the MSS
*
- * @param bp
- * @param parsing_flags Parsing flags from the START CQE
- * @param len_on_bd Total length of the first packet for the
- * aggregation.
+ * @bp: driver handle
+ * @parsing_flags: parsing flags from the START CQE
+ * @len_on_bd: total length of the first packet for the
+ * aggregation.
+ *
+ * Approximate value of the MSS for this aggregation calculated using
+ * the first packet of it.
*/
static inline u16 bnx2x_set_lro_mss(struct bnx2x *bp, u16 parsing_flags,
u16 len_on_bd)
@@ -640,7 +685,7 @@ reuse_rx:
skb_checksum_none_assert(skb);
- if (bp->rx_csum) {
+ if (bp->dev->features & NETIF_F_RXCSUM) {
if (likely(BNX2X_RX_CSUM_OK(cqe)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
@@ -758,35 +803,119 @@ u16 bnx2x_get_mf_speed(struct bnx2x *bp)
return line_speed;
}
+/**
+ * bnx2x_fill_report_data - fill link report data to report
+ *
+ * @bp: driver handle
+ * @data: link state to update
+ *
+ * It uses a none-atomic bit operations because is called under the mutex.
+ */
+static inline void bnx2x_fill_report_data(struct bnx2x *bp,
+ struct bnx2x_link_report_data *data)
+{
+ u16 line_speed = bnx2x_get_mf_speed(bp);
+
+ memset(data, 0, sizeof(*data));
+
+ /* Fill the report data: efective line speed */
+ data->line_speed = line_speed;
+
+ /* Link is down */
+ if (!bp->link_vars.link_up || (bp->flags & MF_FUNC_DIS))
+ __set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &data->link_report_flags);
+
+ /* Full DUPLEX */
+ if (bp->link_vars.duplex == DUPLEX_FULL)
+ __set_bit(BNX2X_LINK_REPORT_FD, &data->link_report_flags);
+
+ /* Rx Flow Control is ON */
+ if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX)
+ __set_bit(BNX2X_LINK_REPORT_RX_FC_ON, &data->link_report_flags);
+
+ /* Tx Flow Control is ON */
+ if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ __set_bit(BNX2X_LINK_REPORT_TX_FC_ON, &data->link_report_flags);
+}
+
+/**
+ * bnx2x_link_report - report link status to OS.
+ *
+ * @bp: driver handle
+ *
+ * Calls the __bnx2x_link_report() under the same locking scheme
+ * as a link/PHY state managing code to ensure a consistent link
+ * reporting.
+ */
+
void bnx2x_link_report(struct bnx2x *bp)
{
- if (bp->flags & MF_FUNC_DIS) {
- netif_carrier_off(bp->dev);
- netdev_err(bp->dev, "NIC Link is Down\n");
- return;
- }
+ bnx2x_acquire_phy_lock(bp);
+ __bnx2x_link_report(bp);
+ bnx2x_release_phy_lock(bp);
+}
- if (bp->link_vars.link_up) {
- u16 line_speed;
+/**
+ * __bnx2x_link_report - report link status to OS.
+ *
+ * @bp: driver handle
+ *
+ * None atomic inmlementation.
+ * Should be called under the phy_lock.
+ */
+void __bnx2x_link_report(struct bnx2x *bp)
+{
+ struct bnx2x_link_report_data cur_data;
- if (bp->state == BNX2X_STATE_OPEN)
- netif_carrier_on(bp->dev);
- netdev_info(bp->dev, "NIC Link is Up, ");
+ /* reread mf_cfg */
+ if (!CHIP_IS_E1(bp))
+ bnx2x_read_mf_cfg(bp);
+
+ /* Read the current link report info */
+ bnx2x_fill_report_data(bp, &cur_data);
+
+ /* Don't report link down or exactly the same link status twice */
+ if (!memcmp(&cur_data, &bp->last_reported_link, sizeof(cur_data)) ||
+ (test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &bp->last_reported_link.link_report_flags) &&
+ test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &cur_data.link_report_flags)))
+ return;
- line_speed = bnx2x_get_mf_speed(bp);
+ bp->link_cnt++;
- pr_cont("%d Mbps ", line_speed);
+ /* We are going to report a new link parameters now -
+ * remember the current data for the next time.
+ */
+ memcpy(&bp->last_reported_link, &cur_data, sizeof(cur_data));
+
+ if (test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &cur_data.link_report_flags)) {
+ netif_carrier_off(bp->dev);
+ netdev_err(bp->dev, "NIC Link is Down\n");
+ return;
+ } else {
+ netif_carrier_on(bp->dev);
+ netdev_info(bp->dev, "NIC Link is Up, ");
+ pr_cont("%d Mbps ", cur_data.line_speed);
- if (bp->link_vars.duplex == DUPLEX_FULL)
+ if (test_and_clear_bit(BNX2X_LINK_REPORT_FD,
+ &cur_data.link_report_flags))
pr_cont("full duplex");
else
pr_cont("half duplex");
- if (bp->link_vars.flow_ctrl != BNX2X_FLOW_CTRL_NONE) {
- if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) {
+ /* Handle the FC at the end so that only these flags would be
+ * possibly set. This way we may easily check if there is no FC
+ * enabled.
+ */
+ if (cur_data.link_report_flags) {
+ if (test_bit(BNX2X_LINK_REPORT_RX_FC_ON,
+ &cur_data.link_report_flags)) {
pr_cont(", receive ");
- if (bp->link_vars.flow_ctrl &
- BNX2X_FLOW_CTRL_TX)
+ if (test_bit(BNX2X_LINK_REPORT_TX_FC_ON,
+ &cur_data.link_report_flags))
pr_cont("& transmit ");
} else {
pr_cont(", transmit ");
@@ -794,62 +923,9 @@ void bnx2x_link_report(struct bnx2x *bp)
pr_cont("flow control ON");
}
pr_cont("\n");
-
- } else { /* link_down */
- netif_carrier_off(bp->dev);
- netdev_err(bp->dev, "NIC Link is Down\n");
}
}
-/* Returns the number of actually allocated BDs */
-static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp,
- int rx_ring_size)
-{
- struct bnx2x *bp = fp->bp;
- u16 ring_prod, cqe_ring_prod;
- int i;
-
- fp->rx_comp_cons = 0;
- cqe_ring_prod = ring_prod = 0;
- for (i = 0; i < rx_ring_size; i++) {
- if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
- BNX2X_ERR("was only able to allocate "
- "%d rx skbs on queue[%d]\n", i, fp->index);
- fp->eth_q_stats.rx_skb_alloc_failed++;
- break;
- }
- ring_prod = NEXT_RX_IDX(ring_prod);
- cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod);
- WARN_ON(ring_prod <= i);
- }
-
- fp->rx_bd_prod = ring_prod;
- /* Limit the CQE producer by the CQE ring size */
- fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT,
- cqe_ring_prod);
- fp->rx_pkt = fp->rx_calls = 0;
-
- return i;
-}
-
-static inline void bnx2x_alloc_rx_bd_ring(struct bnx2x_fastpath *fp)
-{
- struct bnx2x *bp = fp->bp;
- int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size :
- MAX_RX_AVAIL/bp->num_queues;
-
- rx_ring_size = max_t(int, MIN_RX_AVAIL, rx_ring_size);
-
- bnx2x_alloc_rx_bds(fp, rx_ring_size);
-
- /* Warning!
- * this will generate an interrupt (to the TSTORM)
- * must only be done after chip is initialized
- */
- bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod,
- fp->rx_sge_prod);
-}
-
void bnx2x_init_rx_rings(struct bnx2x *bp)
{
int func = BP_FUNC(bp);
@@ -858,6 +934,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
u16 ring_prod;
int i, j;
+ /* Allocate TPA resources */
for_each_rx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
@@ -865,6 +942,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
"mtu %d rx_buf_size %d\n", bp->dev->mtu, fp->rx_buf_size);
if (!fp->disable_tpa) {
+ /* Fill the per-aggregation pool */
for (i = 0; i < max_agg_queues; i++) {
fp->tpa_pool[i].skb =
netdev_alloc_skb(bp->dev, fp->rx_buf_size);
@@ -919,13 +997,13 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
fp->rx_bd_cons = 0;
- bnx2x_set_next_page_rx_bd(fp);
-
- /* CQ ring */
- bnx2x_set_next_page_rx_cq(fp);
-
- /* Allocate BDs and initialize BD ring */
- bnx2x_alloc_rx_bd_ring(fp);
+ /* Activate BD ring */
+ /* Warning!
+ * this will generate an interrupt (to the TSTORM)
+ * must only be done after chip is initialized
+ */
+ bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod,
+ fp->rx_sge_prod);
if (j != 0)
continue;
@@ -959,27 +1037,40 @@ static void bnx2x_free_tx_skbs(struct bnx2x *bp)
}
}
+static void bnx2x_free_rx_bds(struct bnx2x_fastpath *fp)
+{
+ struct bnx2x *bp = fp->bp;
+ int i;
+
+ /* ring wasn't allocated */
+ if (fp->rx_buf_ring == NULL)
+ return;
+
+ 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;
+
+ dma_unmap_single(&bp->pdev->dev,
+ dma_unmap_addr(rx_buf, mapping),
+ fp->rx_buf_size, DMA_FROM_DEVICE);
+
+ rx_buf->skb = NULL;
+ dev_kfree_skb(skb);
+ }
+}
+
static void bnx2x_free_rx_skbs(struct bnx2x *bp)
{
- int i, j;
+ int j;
for_each_rx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
- 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;
-
- dma_unmap_single(&bp->pdev->dev,
- dma_unmap_addr(rx_buf, mapping),
- fp->rx_buf_size, DMA_FROM_DEVICE);
+ bnx2x_free_rx_bds(fp);
- rx_buf->skb = NULL;
- dev_kfree_skb(skb);
- }
if (!fp->disable_tpa)
bnx2x_free_tpa_pool(bp, fp, CHIP_IS_E1(bp) ?
ETH_MAX_AGGREGATION_QUEUES_E1 :
@@ -1345,29 +1436,47 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
+ /* Set the initial link reported state to link down */
+ bnx2x_acquire_phy_lock(bp);
+ memset(&bp->last_reported_link, 0, sizeof(bp->last_reported_link));
+ __set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &bp->last_reported_link.link_report_flags);
+ bnx2x_release_phy_lock(bp);
+
/* must be called before memory allocation and HW init */
bnx2x_ilt_set_info(bp);
+ /* zero fastpath structures preserving invariants like napi which are
+ * allocated only once
+ */
+ for_each_queue(bp, i)
+ bnx2x_bz_fp(bp, i);
+
/* Set the receive queues buffer size */
bnx2x_set_rx_buf_size(bp);
+ for_each_queue(bp, i)
+ bnx2x_fp(bp, i, disable_tpa) =
+ ((bp->flags & TPA_ENABLE_FLAG) == 0);
+
+#ifdef BCM_CNIC
+ /* We don't want TPA on FCoE L2 ring */
+ bnx2x_fcoe(bp, disable_tpa) = 1;
+#endif
+
if (bnx2x_alloc_mem(bp))
return -ENOMEM;
+ /* As long as bnx2x_alloc_mem() may possibly update
+ * bp->num_queues, bnx2x_set_real_num_queues() should always
+ * come after it.
+ */
rc = bnx2x_set_real_num_queues(bp);
if (rc) {
BNX2X_ERR("Unable to set real_num_queues\n");
goto load_error0;
}
- for_each_queue(bp, i)
- bnx2x_fp(bp, i, disable_tpa) =
- ((bp->flags & TPA_ENABLE_FLAG) == 0);
-
-#ifdef BCM_CNIC
- /* We don't want TPA on FCoE L2 ring */
- bnx2x_fcoe(bp, disable_tpa) = 1;
-#endif
bnx2x_napi_enable(bp);
/* Send LOAD_REQUEST command to MCP
@@ -1976,12 +2085,11 @@ static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data,
}
/**
- * Update PBD in GSO case.
+ * bnx2x_set_pbd_gso - update PBD in GSO case.
*
- * @param skb
- * @param tx_start_bd
- * @param pbd
- * @param xmit_type
+ * @skb: packet skb
+ * @pbd: parse BD
+ * @xmit_type: xmit flags
*/
static inline void bnx2x_set_pbd_gso(struct sk_buff *skb,
struct eth_tx_parse_bd_e1x *pbd,
@@ -2008,13 +2116,14 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb,
}
/**
+ * bnx2x_set_pbd_csum_e2 - update PBD with checksum and return header length
*
- * @param skb
- * @param tx_start_bd
- * @param pbd_e2
- * @param xmit_type
+ * @bp: driver handle
+ * @skb: packet skb
+ * @parsing_data: data to be updated
+ * @xmit_type: xmit flags
*
- * @return header len
+ * 57712 related
*/
static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb,
u32 *parsing_data, u32 xmit_type)
@@ -2039,13 +2148,12 @@ static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb,
}
/**
+ * bnx2x_set_pbd_csum - update PBD with checksum and return header length
*
- * @param skb
- * @param tx_start_bd
- * @param pbd
- * @param xmit_type
- *
- * @return Header length
+ * @bp: driver handle
+ * @skb: packet skb
+ * @pbd: parse BD to be updated
+ * @xmit_type: xmit flags
*/
static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb,
struct eth_tx_parse_bd_e1x *pbd,
@@ -2393,6 +2501,232 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p)
return 0;
}
+static void bnx2x_free_fp_mem_at(struct bnx2x *bp, int fp_index)
+{
+ union host_hc_status_block *sb = &bnx2x_fp(bp, fp_index, status_blk);
+ struct bnx2x_fastpath *fp = &bp->fp[fp_index];
+
+ /* Common */
+#ifdef BCM_CNIC
+ if (IS_FCOE_IDX(fp_index)) {
+ memset(sb, 0, sizeof(union host_hc_status_block));
+ fp->status_blk_mapping = 0;
+
+ } else {
+#endif
+ /* status blocks */
+ if (CHIP_IS_E2(bp))
+ BNX2X_PCI_FREE(sb->e2_sb,
+ bnx2x_fp(bp, fp_index,
+ status_blk_mapping),
+ sizeof(struct host_hc_status_block_e2));
+ else
+ BNX2X_PCI_FREE(sb->e1x_sb,
+ bnx2x_fp(bp, fp_index,
+ status_blk_mapping),
+ sizeof(struct host_hc_status_block_e1x));
+#ifdef BCM_CNIC
+ }
+#endif
+ /* Rx */
+ if (!skip_rx_queue(bp, fp_index)) {
+ bnx2x_free_rx_bds(fp);
+
+ /* fastpath rx rings: rx_buf rx_desc rx_comp */
+ BNX2X_FREE(bnx2x_fp(bp, fp_index, rx_buf_ring));
+ BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, rx_desc_ring),
+ bnx2x_fp(bp, fp_index, rx_desc_mapping),
+ sizeof(struct eth_rx_bd) * NUM_RX_BD);
+
+ BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, rx_comp_ring),
+ bnx2x_fp(bp, fp_index, rx_comp_mapping),
+ sizeof(struct eth_fast_path_rx_cqe) *
+ NUM_RCQ_BD);
+
+ /* SGE ring */
+ BNX2X_FREE(bnx2x_fp(bp, fp_index, rx_page_ring));
+ BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, rx_sge_ring),
+ bnx2x_fp(bp, fp_index, rx_sge_mapping),
+ BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
+ }
+
+ /* Tx */
+ if (!skip_tx_queue(bp, fp_index)) {
+ /* fastpath tx rings: tx_buf tx_desc */
+ BNX2X_FREE(bnx2x_fp(bp, fp_index, tx_buf_ring));
+ BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, tx_desc_ring),
+ bnx2x_fp(bp, fp_index, tx_desc_mapping),
+ sizeof(union eth_tx_bd_types) * NUM_TX_BD);
+ }
+ /* end of fastpath */
+}
+
+void bnx2x_free_fp_mem(struct bnx2x *bp)
+{
+ int i;
+ for_each_queue(bp, i)
+ bnx2x_free_fp_mem_at(bp, i);
+}
+
+static inline void set_sb_shortcuts(struct bnx2x *bp, int index)
+{
+ union host_hc_status_block status_blk = bnx2x_fp(bp, index, status_blk);
+ if (CHIP_IS_E2(bp)) {
+ bnx2x_fp(bp, index, sb_index_values) =
+ (__le16 *)status_blk.e2_sb->sb.index_values;
+ bnx2x_fp(bp, index, sb_running_index) =
+ (__le16 *)status_blk.e2_sb->sb.running_index;
+ } else {
+ bnx2x_fp(bp, index, sb_index_values) =
+ (__le16 *)status_blk.e1x_sb->sb.index_values;
+ bnx2x_fp(bp, index, sb_running_index) =
+ (__le16 *)status_blk.e1x_sb->sb.running_index;
+ }
+}
+
+static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index)
+{
+ union host_hc_status_block *sb;
+ struct bnx2x_fastpath *fp = &bp->fp[index];
+ int ring_size = 0;
+
+ /* if rx_ring_size specified - use it */
+ int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size :
+ MAX_RX_AVAIL/bp->num_queues;
+
+ /* allocate at least number of buffers required by FW */
+ rx_ring_size = max_t(int, fp->disable_tpa ? MIN_RX_SIZE_NONTPA :
+ MIN_RX_SIZE_TPA,
+ rx_ring_size);
+
+ bnx2x_fp(bp, index, bp) = bp;
+ bnx2x_fp(bp, index, index) = index;
+
+ /* Common */
+ sb = &bnx2x_fp(bp, index, status_blk);
+#ifdef BCM_CNIC
+ if (!IS_FCOE_IDX(index)) {
+#endif
+ /* status blocks */
+ if (CHIP_IS_E2(bp))
+ BNX2X_PCI_ALLOC(sb->e2_sb,
+ &bnx2x_fp(bp, index, status_blk_mapping),
+ sizeof(struct host_hc_status_block_e2));
+ else
+ BNX2X_PCI_ALLOC(sb->e1x_sb,
+ &bnx2x_fp(bp, index, status_blk_mapping),
+ sizeof(struct host_hc_status_block_e1x));
+#ifdef BCM_CNIC
+ }
+#endif
+ set_sb_shortcuts(bp, index);
+
+ /* Tx */
+ if (!skip_tx_queue(bp, index)) {
+ /* fastpath tx rings: tx_buf tx_desc */
+ BNX2X_ALLOC(bnx2x_fp(bp, index, tx_buf_ring),
+ sizeof(struct sw_tx_bd) * NUM_TX_BD);
+ BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, tx_desc_ring),
+ &bnx2x_fp(bp, index, tx_desc_mapping),
+ sizeof(union eth_tx_bd_types) * NUM_TX_BD);
+ }
+
+ /* Rx */
+ if (!skip_rx_queue(bp, index)) {
+ /* fastpath rx rings: rx_buf rx_desc rx_comp */
+ BNX2X_ALLOC(bnx2x_fp(bp, index, rx_buf_ring),
+ sizeof(struct sw_rx_bd) * NUM_RX_BD);
+ BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_desc_ring),
+ &bnx2x_fp(bp, index, rx_desc_mapping),
+ sizeof(struct eth_rx_bd) * NUM_RX_BD);
+
+ BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_comp_ring),
+ &bnx2x_fp(bp, index, rx_comp_mapping),
+ sizeof(struct eth_fast_path_rx_cqe) *
+ NUM_RCQ_BD);
+
+ /* SGE ring */
+ BNX2X_ALLOC(bnx2x_fp(bp, index, rx_page_ring),
+ sizeof(struct sw_rx_page) * NUM_RX_SGE);
+ BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_sge_ring),
+ &bnx2x_fp(bp, index, rx_sge_mapping),
+ BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
+ /* RX BD ring */
+ bnx2x_set_next_page_rx_bd(fp);
+
+ /* CQ ring */
+ bnx2x_set_next_page_rx_cq(fp);
+
+ /* BDs */
+ ring_size = bnx2x_alloc_rx_bds(fp, rx_ring_size);
+ if (ring_size < rx_ring_size)
+ goto alloc_mem_err;
+ }
+
+ return 0;
+
+/* handles low memory cases */
+alloc_mem_err:
+ BNX2X_ERR("Unable to allocate full memory for queue %d (size %d)\n",
+ index, ring_size);
+ /* FW will drop all packets if queue is not big enough,
+ * In these cases we disable the queue
+ * Min size diferent for TPA and non-TPA queues
+ */
+ if (ring_size < (fp->disable_tpa ?
+ MIN_RX_SIZE_TPA : MIN_RX_SIZE_NONTPA)) {
+ /* release memory allocated for this queue */
+ bnx2x_free_fp_mem_at(bp, index);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+int bnx2x_alloc_fp_mem(struct bnx2x *bp)
+{
+ int i;
+
+ /**
+ * 1. Allocate FP for leading - fatal if error
+ * 2. {CNIC} Allocate FCoE FP - fatal if error
+ * 3. Allocate RSS - fix number of queues if error
+ */
+
+ /* leading */
+ if (bnx2x_alloc_fp_mem_at(bp, 0))
+ return -ENOMEM;
+#ifdef BCM_CNIC
+ /* FCoE */
+ if (bnx2x_alloc_fp_mem_at(bp, FCOE_IDX))
+ return -ENOMEM;
+#endif
+ /* RSS */
+ for_each_nondefault_eth_queue(bp, i)
+ if (bnx2x_alloc_fp_mem_at(bp, i))
+ break;
+
+ /* handle memory failures */
+ if (i != BNX2X_NUM_ETH_QUEUES(bp)) {
+ int delta = BNX2X_NUM_ETH_QUEUES(bp) - i;
+
+ WARN_ON(delta < 0);
+#ifdef BCM_CNIC
+ /**
+ * move non eth FPs next to last eth FP
+ * must be done in that order
+ * FCOE_IDX < FWD_IDX < OOO_IDX
+ */
+
+ /* move FCoE fp */
+ bnx2x_move_fp(bp, FCOE_IDX, FCOE_IDX - delta);
+#endif
+ bp->num_queues -= delta;
+ BNX2X_ERR("Adjusted num of queues from %d to %d\n",
+ bp->num_queues + delta, bp->num_queues);
+ }
+
+ return 0;
+}
static int bnx2x_setup_irqs(struct bnx2x *bp)
{
@@ -2457,11 +2791,21 @@ alloc_err:
}
+static int bnx2x_reload_if_running(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (unlikely(!netif_running(dev)))
+ return 0;
+
+ bnx2x_nic_unload(bp, UNLOAD_NORMAL);
+ return bnx2x_nic_load(bp, LOAD_NORMAL);
+}
+
/* called with rtnl_lock */
int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
{
struct bnx2x *bp = netdev_priv(dev);
- int rc = 0;
if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
printk(KERN_ERR "Handling parity error recovery. Try again later\n");
@@ -2478,12 +2822,55 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
*/
dev->mtu = new_mtu;
- if (netif_running(dev)) {
- bnx2x_nic_unload(bp, UNLOAD_NORMAL);
- rc = bnx2x_nic_load(bp, LOAD_NORMAL);
+ return bnx2x_reload_if_running(dev);
+}
+
+u32 bnx2x_fix_features(struct net_device *dev, u32 features)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ /* TPA requires Rx CSUM offloading */
+ if (!(features & NETIF_F_RXCSUM) || bp->disable_tpa)
+ features &= ~NETIF_F_LRO;
+
+ return features;
+}
+
+int bnx2x_set_features(struct net_device *dev, u32 features)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ u32 flags = bp->flags;
+ bool bnx2x_reload = false;
+
+ if (features & NETIF_F_LRO)
+ flags |= TPA_ENABLE_FLAG;
+ else
+ flags &= ~TPA_ENABLE_FLAG;
+
+ if (features & NETIF_F_LOOPBACK) {
+ if (bp->link_params.loopback_mode != LOOPBACK_BMAC) {
+ bp->link_params.loopback_mode = LOOPBACK_BMAC;
+ bnx2x_reload = true;
+ }
+ } else {
+ if (bp->link_params.loopback_mode != LOOPBACK_NONE) {
+ bp->link_params.loopback_mode = LOOPBACK_NONE;
+ bnx2x_reload = true;
+ }
}
- return rc;
+ if (flags ^ bp->flags) {
+ bp->flags = flags;
+ bnx2x_reload = true;
+ }
+
+ if (bnx2x_reload) {
+ if (bp->recovery_state == BNX2X_RECOVERY_DONE)
+ return bnx2x_reload_if_running(dev);
+ /* else: bnx2x_nic_load() will be called at end of recovery */
+ }
+
+ return 0;
}
void bnx2x_tx_timeout(struct net_device *dev)
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h
index ef37b98d614..fab161e8030 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/bnx2x/bnx2x_cmn.h
@@ -1,6 +1,6 @@
/* bnx2x_cmn.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
@@ -25,260 +25,277 @@
extern int num_queues;
+/************************ Macros ********************************/
+#define BNX2X_PCI_FREE(x, y, size) \
+ do { \
+ if (x) { \
+ dma_free_coherent(&bp->pdev->dev, size, (void *)x, y); \
+ x = NULL; \
+ y = 0; \
+ } \
+ } while (0)
+
+#define BNX2X_FREE(x) \
+ do { \
+ if (x) { \
+ kfree((void *)x); \
+ x = NULL; \
+ } \
+ } while (0)
+
+#define BNX2X_PCI_ALLOC(x, y, size) \
+ do { \
+ x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \
+ if (x == NULL) \
+ goto alloc_mem_err; \
+ memset((void *)x, 0, size); \
+ } while (0)
+
+#define BNX2X_ALLOC(x, size) \
+ do { \
+ x = kzalloc(size, GFP_KERNEL); \
+ if (x == NULL) \
+ goto alloc_mem_err; \
+ } while (0)
+
/*********************** Interfaces ****************************
* Functions that need to be implemented by each driver version
*/
/**
- * Initialize link parameters structure variables.
- *
- * @param bp
- * @param load_mode
+ * bnx2x_initial_phy_init - initialize link parameters structure variables.
*
- * @return u8
+ * @bp: driver handle
+ * @load_mode: current mode
*/
u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode);
/**
- * Configure hw according to link parameters structure.
+ * bnx2x_link_set - configure hw according to link parameters structure.
*
- * @param bp
+ * @bp: driver handle
*/
void bnx2x_link_set(struct bnx2x *bp);
/**
- * Query link status
+ * bnx2x_link_test - query link status.
*
- * @param bp
- * @param is_serdes
+ * @bp: driver handle
+ * @is_serdes: bool
*
- * @return 0 - link is UP
+ * Returns 0 if link is UP.
*/
u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes);
/**
- * Handles link status change
+ * bnx2x__link_status_update - handles link status change.
*
- * @param bp
+ * @bp: driver handle
*/
void bnx2x__link_status_update(struct bnx2x *bp);
/**
- * Report link status to upper layer
- *
- * @param bp
+ * bnx2x_link_report - report link status to upper layer.
*
- * @return int
+ * @bp: driver handle
*/
void bnx2x_link_report(struct bnx2x *bp);
+/* None-atomic version of bnx2x_link_report() */
+void __bnx2x_link_report(struct bnx2x *bp);
+
/**
- * calculates MF speed according to current linespeed and MF
- * configuration
+ * bnx2x_get_mf_speed - calculate MF speed.
*
- * @param bp
+ * @bp: driver handle
*
- * @return u16
+ * Takes into account current linespeed and MF configuration.
*/
u16 bnx2x_get_mf_speed(struct bnx2x *bp);
/**
- * MSI-X slowpath interrupt handler
- *
- * @param irq
- * @param dev_instance
+ * bnx2x_msix_sp_int - MSI-X slowpath interrupt handler
*
- * @return irqreturn_t
+ * @irq: irq number
+ * @dev_instance: private instance
*/
irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance);
/**
- * non MSI-X interrupt handler
+ * bnx2x_interrupt - non MSI-X interrupt handler
*
- * @param irq
- * @param dev_instance
- *
- * @return irqreturn_t
+ * @irq: irq number
+ * @dev_instance: private instance
*/
irqreturn_t bnx2x_interrupt(int irq, void *dev_instance);
#ifdef BCM_CNIC
/**
- * Send command to cnic driver
+ * bnx2x_cnic_notify - send command to cnic driver
*
- * @param bp
- * @param cmd
+ * @bp: driver handle
+ * @cmd: command
*/
int bnx2x_cnic_notify(struct bnx2x *bp, int cmd);
/**
- * Provides cnic information for proper interrupt handling
+ * bnx2x_setup_cnic_irq_info - provides cnic with IRQ information
*
- * @param bp
+ * @bp: driver handle
*/
void bnx2x_setup_cnic_irq_info(struct bnx2x *bp);
#endif
/**
- * Enable HW interrupts.
+ * bnx2x_int_enable - enable HW interrupts.
*
- * @param bp
+ * @bp: driver handle
*/
void bnx2x_int_enable(struct bnx2x *bp);
/**
- * Disable interrupts. This function ensures that there are no
- * ISRs or SP DPCs (sp_task) are running after it returns.
+ * bnx2x_int_disable_sync - disable interrupts.
*
- * @param bp
- * @param disable_hw if true, disable HW interrupts.
+ * @bp: driver handle
+ * @disable_hw: true, disable HW interrupts.
+ *
+ * This function ensures that there are no
+ * ISRs or SP DPCs (sp_task) are running after it returns.
*/
void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw);
/**
- * Loads device firmware
+ * bnx2x_init_firmware - loads device firmware
*
- * @param bp
- *
- * @return int
+ * @bp: driver handle
*/
int bnx2x_init_firmware(struct bnx2x *bp);
/**
- * Init HW blocks according to current initialization stage:
- * COMMON, PORT or FUNCTION.
- *
- * @param bp
- * @param load_code: COMMON, PORT or FUNCTION
+ * bnx2x_init_hw - init HW blocks according to current initialization stage.
*
- * @return int
+ * @bp: driver handle
+ * @load_code: COMMON, PORT or FUNCTION
*/
int bnx2x_init_hw(struct bnx2x *bp, u32 load_code);
/**
- * Init driver internals:
+ * bnx2x_nic_init - init driver internals.
+ *
+ * @bp: driver handle
+ * @load_code: COMMON, PORT or FUNCTION
+ *
+ * Initializes:
* - rings
* - status blocks
* - etc.
- *
- * @param bp
- * @param load_code COMMON, PORT or FUNCTION
*/
void bnx2x_nic_init(struct bnx2x *bp, u32 load_code);
/**
- * Allocate driver's memory.
- *
- * @param bp
+ * bnx2x_alloc_mem - allocate driver's memory.
*
- * @return int
+ * @bp: driver handle
*/
int bnx2x_alloc_mem(struct bnx2x *bp);
/**
- * Release driver's memory.
+ * bnx2x_free_mem - release driver's memory.
*
- * @param bp
+ * @bp: driver handle
*/
void bnx2x_free_mem(struct bnx2x *bp);
/**
- * Setup eth Client.
+ * bnx2x_setup_client - setup eth client.
*
- * @param bp
- * @param fp
- * @param is_leading
- *
- * @return int
+ * @bp: driver handle
+ * @fp: pointer to fastpath structure
+ * @is_leading: boolean
*/
int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp,
int is_leading);
/**
- * Set number of queues according to mode
- *
- * @param bp
+ * bnx2x_set_num_queues - set number of queues according to mode.
*
+ * @bp: driver handle
*/
void bnx2x_set_num_queues(struct bnx2x *bp);
/**
- * Cleanup chip internals:
+ * bnx2x_chip_cleanup - cleanup chip internals.
+ *
+ * @bp: driver handle
+ * @unload_mode: COMMON, PORT, FUNCTION
+ *
* - Cleanup MAC configuration.
- * - Close clients.
+ * - Closes clients.
* - etc.
- *
- * @param bp
- * @param unload_mode
*/
void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode);
/**
- * Acquire HW lock.
+ * bnx2x_acquire_hw_lock - acquire HW lock.
*
- * @param bp
- * @param resource Resource bit which was locked
- *
- * @return int
+ * @bp: driver handle
+ * @resource: resource bit which was locked
*/
int bnx2x_acquire_hw_lock(struct bnx2x *bp, u32 resource);
/**
- * Release HW lock.
- *
- * @param bp driver handle
- * @param resource Resource bit which was locked
+ * bnx2x_release_hw_lock - release HW lock.
*
- * @return int
+ * @bp: driver handle
+ * @resource: resource bit which was locked
*/
int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource);
/**
- * Configure eth MAC address in the HW according to the value in
- * netdev->dev_addr.
+ * bnx2x_set_eth_mac - configure eth MAC address in the HW
*
- * @param bp driver handle
- * @param set
+ * @bp: driver handle
+ * @set: set or clear
+ *
+ * Configures according to the value in netdev->dev_addr.
*/
void bnx2x_set_eth_mac(struct bnx2x *bp, int set);
#ifdef BCM_CNIC
/**
- * Set/Clear FIP MAC(s) at the next enties in the CAM after the ETH
- * MAC(s). This function will wait until the ramdord completion
- * returns.
+ * bnx2x_set_fip_eth_mac_addr - Set/Clear FIP MAC(s)
*
- * @param bp driver handle
- * @param set set or clear the CAM entry
+ * @bp: driver handle
+ * @set: set or clear the CAM entry
*
- * @return 0 if cussess, -ENODEV if ramrod doesn't return.
+ * Used next enties in the CAM after the ETH MAC(s).
+ * This function will wait until the ramdord completion returns.
+ * Return 0 if cussess, -ENODEV if ramrod doesn't return.
*/
int bnx2x_set_fip_eth_mac_addr(struct bnx2x *bp, int set);
/**
- * Set/Clear ALL_ENODE mcast MAC.
- *
- * @param bp
- * @param set
+ * bnx2x_set_all_enode_macs - Set/Clear ALL_ENODE mcast MAC.
*
- * @return int
+ * @bp: driver handle
+ * @set: set or clear
*/
int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set);
#endif
/**
- * Set MAC filtering configurations.
+ * bnx2x_set_rx_mode - set MAC filtering configurations.
*
- * @remarks called with netif_tx_lock from dev_mcast.c
+ * @dev: netdevice
*
- * @param dev net_device
+ * called with netif_tx_lock from dev_mcast.c
*/
void bnx2x_set_rx_mode(struct net_device *dev);
/**
- * Configure MAC filtering rules in a FW.
+ * bnx2x_set_storm_rx_mode - configure MAC filtering rules in a FW.
*
- * @param bp driver handle
+ * @bp: driver handle
*/
void bnx2x_set_storm_rx_mode(struct bnx2x *bp);
@@ -290,63 +307,59 @@ bool bnx2x_reset_is_done(struct bnx2x *bp);
void bnx2x_disable_close_the_gate(struct bnx2x *bp);
/**
- * Perform statistics handling according to event
+ * bnx2x_stats_handle - perform statistics handling according to event.
*
- * @param bp driver handle
- * @param event bnx2x_stats_event
+ * @bp: driver handle
+ * @event: bnx2x_stats_event
*/
void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event);
/**
- * Handle ramrods completion
+ * bnx2x_sp_event - handle ramrods completion.
*
- * @param fp fastpath handle for the event
- * @param rr_cqe eth_rx_cqe
+ * @fp: fastpath handle for the event
+ * @rr_cqe: eth_rx_cqe
*/
void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe);
/**
- * Init/halt function before/after sending
- * CLIENT_SETUP/CFC_DEL for the first/last client.
+ * bnx2x_func_start - init function
*
- * @param bp
+ * @bp: driver handle
*
- * @return int
+ * Must be called before sending CLIENT_SETUP for the first client.
*/
int bnx2x_func_start(struct bnx2x *bp);
/**
- * Prepare ILT configurations according to current driver
- * parameters.
+ * bnx2x_ilt_set_info - prepare ILT configurations.
*
- * @param bp
+ * @bp: driver handle
*/
void bnx2x_ilt_set_info(struct bnx2x *bp);
/**
- * Inintialize dcbx protocol
+ * bnx2x_dcbx_init - initialize dcbx protocol.
*
- * @param bp
+ * @bp: driver handle
*/
void bnx2x_dcbx_init(struct bnx2x *bp);
/**
- * Set power state to the requested value. Currently only D0 and
- * D3hot are supported.
+ * bnx2x_set_power_state - set power state to the requested value.
*
- * @param bp
- * @param state D0 or D3hot
+ * @bp: driver handle
+ * @state: required state D0 or D3hot
*
- * @return int
+ * Currently only D0 and D3hot are supported.
*/
int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state);
/**
- * Updates MAX part of MF configuration in HW
- * (if required)
+ * bnx2x_update_max_mf_config - update MAX part of MF configuration in HW.
*
- * @param bp
- * @param value
+ * @bp: driver handle
+ * @value: new value
*/
void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value);
@@ -377,83 +390,72 @@ int bnx2x_resume(struct pci_dev *pdev);
/* Release IRQ vectors */
void bnx2x_free_irq(struct bnx2x *bp);
+void bnx2x_free_fp_mem(struct bnx2x *bp);
+int bnx2x_alloc_fp_mem(struct bnx2x *bp);
+
void bnx2x_init_rx_rings(struct bnx2x *bp);
void bnx2x_free_skbs(struct bnx2x *bp);
void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw);
void bnx2x_netif_start(struct bnx2x *bp);
/**
- * Fill msix_table, request vectors, update num_queues according
- * to number of available vectors
+ * bnx2x_enable_msix - set msix configuration.
*
- * @param bp
+ * @bp: driver handle
*
- * @return int
+ * fills msix_table, requests vectors, updates num_queues
+ * according to number of available vectors.
*/
int bnx2x_enable_msix(struct bnx2x *bp);
/**
- * Request msi mode from OS, updated internals accordingly
- *
- * @param bp
+ * bnx2x_enable_msi - request msi mode from OS, updated internals accordingly
*
- * @return int
+ * @bp: driver handle
*/
int bnx2x_enable_msi(struct bnx2x *bp);
/**
- * NAPI callback
+ * bnx2x_poll - NAPI callback
*
- * @param napi
- * @param budget
+ * @napi: napi structure
+ * @budget:
*
- * @return int
*/
int bnx2x_poll(struct napi_struct *napi, int budget);
/**
- * Allocate/release memories outsize main driver structure
+ * bnx2x_alloc_mem_bp - allocate memories outsize main driver structure
*
- * @param bp
- *
- * @return int
+ * @bp: driver handle
*/
int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp);
-void bnx2x_free_mem_bp(struct bnx2x *bp);
/**
- * Change mtu netdev callback
+ * bnx2x_free_mem_bp - release memories outsize main driver structure
*
- * @param dev
- * @param new_mtu
- *
- * @return int
+ * @bp: driver handle
*/
-int bnx2x_change_mtu(struct net_device *dev, int new_mtu);
+void bnx2x_free_mem_bp(struct bnx2x *bp);
/**
- * tx timeout netdev callback
+ * bnx2x_change_mtu - change mtu netdev callback
*
- * @param dev
- * @param new_mtu
+ * @dev: net device
+ * @new_mtu: requested mtu
*
- * @return int
*/
-void bnx2x_tx_timeout(struct net_device *dev);
+int bnx2x_change_mtu(struct net_device *dev, int new_mtu);
+
+u32 bnx2x_fix_features(struct net_device *dev, u32 features);
+int bnx2x_set_features(struct net_device *dev, u32 features);
-#ifdef BCM_VLAN
/**
- * vlan rx register netdev callback
+ * bnx2x_tx_timeout - tx timeout netdev callback
*
- * @param dev
- * @param new_mtu
- *
- * @return int
+ * @dev: net device
*/
-void bnx2x_vlan_rx_register(struct net_device *dev,
- struct vlan_group *vlgrp);
-
-#endif
+void bnx2x_tx_timeout(struct net_device *dev);
static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp)
{
@@ -705,7 +707,7 @@ static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp)
/**
* disables tx from stack point of view
*
- * @param bp
+ * @bp: driver handle
*/
static inline void bnx2x_tx_disable(struct bnx2x *bp)
{
@@ -880,6 +882,9 @@ static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp,
{
int i;
+ if (fp->disable_tpa)
+ return;
+
for (i = 0; i < last; i++)
bnx2x_free_rx_sge(bp, fp, i);
}
@@ -908,36 +913,39 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp,
}
}
-
-static inline void bnx2x_init_tx_rings(struct bnx2x *bp)
+static inline void bnx2x_init_tx_ring_one(struct bnx2x_fastpath *fp)
{
- int i, j;
+ int i;
- for_each_tx_queue(bp, j) {
- struct bnx2x_fastpath *fp = &bp->fp[j];
+ for (i = 1; i <= NUM_TX_RINGS; i++) {
+ struct eth_tx_next_bd *tx_next_bd =
+ &fp->tx_desc_ring[TX_DESC_CNT * i - 1].next_bd;
- for (i = 1; i <= NUM_TX_RINGS; i++) {
- struct eth_tx_next_bd *tx_next_bd =
- &fp->tx_desc_ring[TX_DESC_CNT * i - 1].next_bd;
+ tx_next_bd->addr_hi =
+ cpu_to_le32(U64_HI(fp->tx_desc_mapping +
+ BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
+ tx_next_bd->addr_lo =
+ cpu_to_le32(U64_LO(fp->tx_desc_mapping +
+ BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
+ }
- tx_next_bd->addr_hi =
- cpu_to_le32(U64_HI(fp->tx_desc_mapping +
- BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
- tx_next_bd->addr_lo =
- cpu_to_le32(U64_LO(fp->tx_desc_mapping +
- BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
- }
+ SET_FLAG(fp->tx_db.data.header.header, DOORBELL_HDR_DB_TYPE, 1);
+ fp->tx_db.data.zero_fill1 = 0;
+ fp->tx_db.data.prod = 0;
- SET_FLAG(fp->tx_db.data.header.header, DOORBELL_HDR_DB_TYPE, 1);
- fp->tx_db.data.zero_fill1 = 0;
- fp->tx_db.data.prod = 0;
+ fp->tx_pkt_prod = 0;
+ fp->tx_pkt_cons = 0;
+ fp->tx_bd_prod = 0;
+ fp->tx_bd_cons = 0;
+ fp->tx_pkt = 0;
+}
- fp->tx_pkt_prod = 0;
- fp->tx_pkt_cons = 0;
- fp->tx_bd_prod = 0;
- fp->tx_bd_cons = 0;
- fp->tx_pkt = 0;
- }
+static inline void bnx2x_init_tx_rings(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_tx_queue(bp, i)
+ bnx2x_init_tx_ring_one(&bp->fp[i]);
}
static inline void bnx2x_set_next_page_rx_bd(struct bnx2x_fastpath *fp)
@@ -992,6 +1000,44 @@ static inline void bnx2x_set_next_page_rx_cq(struct bnx2x_fastpath *fp)
}
}
+/* Returns the number of actually allocated BDs */
+static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp,
+ int rx_ring_size)
+{
+ struct bnx2x *bp = fp->bp;
+ u16 ring_prod, cqe_ring_prod;
+ int i;
+
+ fp->rx_comp_cons = 0;
+ cqe_ring_prod = ring_prod = 0;
+
+ /* This routine is called only during fo init so
+ * fp->eth_q_stats.rx_skb_alloc_failed = 0
+ */
+ for (i = 0; i < rx_ring_size; i++) {
+ if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
+ fp->eth_q_stats.rx_skb_alloc_failed++;
+ continue;
+ }
+ ring_prod = NEXT_RX_IDX(ring_prod);
+ cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod);
+ WARN_ON(ring_prod <= (i - fp->eth_q_stats.rx_skb_alloc_failed));
+ }
+
+ if (fp->eth_q_stats.rx_skb_alloc_failed)
+ BNX2X_ERR("was only able to allocate "
+ "%d rx skbs on queue[%d]\n",
+ (i - fp->eth_q_stats.rx_skb_alloc_failed), fp->index);
+
+ fp->rx_bd_prod = ring_prod;
+ /* Limit the CQE producer by the CQE ring size */
+ fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT,
+ cqe_ring_prod);
+ fp->rx_pkt = fp->rx_calls = 0;
+
+ return i - fp->eth_q_stats.rx_skb_alloc_failed;
+}
+
#ifdef BCM_CNIC
static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp)
{
@@ -1041,12 +1087,23 @@ static inline void storm_memset_cmng(struct bnx2x *bp,
struct cmng_struct_per_port *cmng,
u8 port)
{
- size_t size = sizeof(struct cmng_struct_per_port);
+ size_t size =
+ sizeof(struct rate_shaping_vars_per_port) +
+ sizeof(struct fairness_vars_per_port) +
+ sizeof(struct safc_struct_per_port) +
+ sizeof(struct pfc_struct_per_port);
u32 addr = BAR_XSTRORM_INTMEM +
XSTORM_CMNG_PER_PORT_VARS_OFFSET(port);
__storm_memset_struct(bp, addr, size, (u32 *)cmng);
+
+ addr += size + 4 /* SKIP DCB+LLFC */;
+ size = sizeof(struct cmng_struct_per_port) -
+ size /* written */ - 4 /*skipped*/;
+
+ __storm_memset_struct(bp, addr, size,
+ (u32 *)(cmng->traffic_type_to_priority_cos));
}
/* HW Lock for shared dual port PHYs */
@@ -1054,12 +1111,11 @@ void bnx2x_acquire_phy_lock(struct bnx2x *bp);
void bnx2x_release_phy_lock(struct bnx2x *bp);
/**
- * Extracts MAX BW part from MF configuration.
+ * bnx2x_extract_max_cfg - extract MAX BW part from MF configuration.
*
- * @param bp
- * @param mf_cfg
+ * @bp: driver handle
+ * @mf_cfg: MF configuration
*
- * @return u16
*/
static inline u16 bnx2x_extract_max_cfg(struct bnx2x *bp, u32 mf_cfg)
{
diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c
index 9a24d79c71d..410a49e571a 100644
--- a/drivers/net/bnx2x/bnx2x_dcb.c
+++ b/drivers/net/bnx2x/bnx2x_dcb.c
@@ -1,6 +1,6 @@
/* bnx2x_dcb.c: Broadcom Everest network driver.
*
- * Copyright 2009-2010 Broadcom Corporation
+ * Copyright 2009-2011 Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -485,6 +485,36 @@ static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp)
}
}
+#ifdef BCM_DCBNL
+static int bnx2x_dcbx_read_shmem_remote_mib(struct bnx2x *bp)
+{
+ struct lldp_remote_mib remote_mib = {0};
+ u32 dcbx_remote_mib_offset = SHMEM2_RD(bp, dcbx_remote_mib_offset);
+ int rc;
+
+ DP(NETIF_MSG_LINK, "dcbx_remote_mib_offset 0x%x\n",
+ dcbx_remote_mib_offset);
+
+ if (SHMEM_DCBX_REMOTE_MIB_NONE == dcbx_remote_mib_offset) {
+ BNX2X_ERR("FW doesn't support dcbx_remote_mib_offset\n");
+ return -EINVAL;
+ }
+
+ rc = bnx2x_dcbx_read_mib(bp, (u32 *)&remote_mib, dcbx_remote_mib_offset,
+ DCBX_READ_REMOTE_MIB);
+
+ if (rc) {
+ BNX2X_ERR("Faild to read remote mib from FW\n");
+ return rc;
+ }
+
+ /* save features and flags */
+ bp->dcbx_remote_feat = remote_mib.features;
+ bp->dcbx_remote_flags = remote_mib.flags;
+ return 0;
+}
+#endif
+
static int bnx2x_dcbx_read_shmem_neg_results(struct bnx2x *bp)
{
struct lldp_local_mib local_mib = {0};
@@ -571,6 +601,28 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
{
switch (state) {
case BNX2X_DCBX_STATE_NEG_RECEIVED:
+#ifdef BCM_CNIC
+ if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) {
+ struct cnic_ops *c_ops;
+ struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+ bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG;
+ cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI_OOO;
+ cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI;
+
+ rcu_read_lock();
+ c_ops = rcu_dereference(bp->cnic_ops);
+ if (c_ops) {
+ bnx2x_cnic_notify(bp, CNIC_CTL_STOP_ISCSI_CMD);
+ rcu_read_unlock();
+ return;
+ }
+ rcu_read_unlock();
+ }
+
+ /* fall through if no CNIC initialized */
+ case BNX2X_DCBX_STATE_ISCSI_STOPPED:
+#endif
+
{
DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_NEG_RECEIVED\n");
#ifdef BCM_DCBNL
@@ -579,6 +631,10 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
* negotiation results
*/
bnx2x_dcbnl_update_applist(bp, true);
+
+ /* Read rmeote mib if dcbx is in the FW */
+ if (bnx2x_dcbx_read_shmem_remote_mib(bp))
+ return;
#endif
/* Read neg results if dcbx is in the FW */
if (bnx2x_dcbx_read_shmem_neg_results(bp))
@@ -1057,12 +1113,6 @@ static void bnx2x_dcbx_get_num_pg_traf_type(struct bnx2x *bp,
}
}
-
-/*******************************************************************************
- * Description: single priority group
- *
- * Return:
- ******************************************************************************/
static void bnx2x_dcbx_ets_disabled_entry_data(struct bnx2x *bp,
struct cos_help_data *cos_data,
u32 pri_join_mask)
@@ -1075,11 +1125,6 @@ static void bnx2x_dcbx_ets_disabled_entry_data(struct bnx2x *bp,
cos_data->num_of_cos = 1;
}
-/*******************************************************************************
- * Description: updating the cos bw
- *
- * Return:
- ******************************************************************************/
static inline void bnx2x_dcbx_add_to_cos_bw(struct bnx2x *bp,
struct cos_entry_help_data *data,
u8 pg_bw)
@@ -1090,11 +1135,6 @@ static inline void bnx2x_dcbx_add_to_cos_bw(struct bnx2x *bp,
data->cos_bw += pg_bw;
}
-/*******************************************************************************
- * Description: single priority group
- *
- * Return:
- ******************************************************************************/
static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp,
struct cos_help_data *cos_data,
u32 *pg_pri_orginal_spread,
@@ -1347,11 +1387,6 @@ static void bnx2x_dcbx_two_pg_to_cos_params(
}
}
-/*******************************************************************************
- * Description: Still
- *
- * Return:
- ******************************************************************************/
static void bnx2x_dcbx_three_pg_to_cos_params(
struct bnx2x *bp,
struct pg_help_data *pg_help_data,
@@ -1539,11 +1574,6 @@ static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp,
}
}
-/*******************************************************************************
- * Description: Fill pfc_config struct that will be sent in DCBX start ramrod
- *
- * Return:
- ******************************************************************************/
static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp)
{
struct flow_control_configuration *pfc_fw_cfg = NULL;
@@ -2035,7 +2065,6 @@ static u8 bnx2x_dcbnl_set_dcbx(struct net_device *netdev, u8 state)
return 0;
}
-
static u8 bnx2x_dcbnl_get_featcfg(struct net_device *netdev, int featid,
u8 *flags)
{
@@ -2115,31 +2144,100 @@ static u8 bnx2x_dcbnl_set_featcfg(struct net_device *netdev, int featid,
return rval;
}
+static int bnx2x_peer_appinfo(struct net_device *netdev,
+ struct dcb_peer_app_info *info, u16* app_count)
+{
+ int i;
+ struct bnx2x *bp = netdev_priv(netdev);
+
+ DP(NETIF_MSG_LINK, "APP-INFO\n");
+
+ info->willing = (bp->dcbx_remote_flags & DCBX_APP_REM_WILLING) ?: 0;
+ info->error = (bp->dcbx_remote_flags & DCBX_APP_RX_ERROR) ?: 0;
+ *app_count = 0;
+
+ for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++)
+ if (bp->dcbx_remote_feat.app.app_pri_tbl[i].appBitfield &
+ DCBX_APP_ENTRY_VALID)
+ (*app_count)++;
+ return 0;
+}
+
+static int bnx2x_peer_apptable(struct net_device *netdev,
+ struct dcb_app *table)
+{
+ int i, j;
+ struct bnx2x *bp = netdev_priv(netdev);
+
+ DP(NETIF_MSG_LINK, "APP-TABLE\n");
+
+ for (i = 0, j = 0; i < DCBX_MAX_APP_PROTOCOL; i++) {
+ struct dcbx_app_priority_entry *ent =
+ &bp->dcbx_remote_feat.app.app_pri_tbl[i];
+
+ if (ent->appBitfield & DCBX_APP_ENTRY_VALID) {
+ table[j].selector = bnx2x_dcbx_dcbnl_app_idtype(ent);
+ table[j].priority = bnx2x_dcbx_dcbnl_app_up(ent);
+ table[j++].protocol = ent->app_id;
+ }
+ }
+ return 0;
+}
+
+static int bnx2x_cee_peer_getpg(struct net_device *netdev, struct cee_pg *pg)
+{
+ int i;
+ struct bnx2x *bp = netdev_priv(netdev);
+
+ pg->willing = (bp->dcbx_remote_flags & DCBX_ETS_REM_WILLING) ?: 0;
+
+ for (i = 0; i < CEE_DCBX_MAX_PGS; i++) {
+ pg->pg_bw[i] =
+ DCBX_PG_BW_GET(bp->dcbx_remote_feat.ets.pg_bw_tbl, i);
+ pg->prio_pg[i] =
+ DCBX_PRI_PG_GET(bp->dcbx_remote_feat.ets.pri_pg_tbl, i);
+ }
+ return 0;
+}
+
+static int bnx2x_cee_peer_getpfc(struct net_device *netdev,
+ struct cee_pfc *pfc)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ pfc->tcs_supported = bp->dcbx_remote_feat.pfc.pfc_caps;
+ pfc->pfc_en = bp->dcbx_remote_feat.pfc.pri_en_bitmap;
+ return 0;
+}
+
const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops = {
- .getstate = bnx2x_dcbnl_get_state,
- .setstate = bnx2x_dcbnl_set_state,
- .getpermhwaddr = bnx2x_dcbnl_get_perm_hw_addr,
- .setpgtccfgtx = bnx2x_dcbnl_set_pg_tccfg_tx,
- .setpgbwgcfgtx = bnx2x_dcbnl_set_pg_bwgcfg_tx,
- .setpgtccfgrx = bnx2x_dcbnl_set_pg_tccfg_rx,
- .setpgbwgcfgrx = bnx2x_dcbnl_set_pg_bwgcfg_rx,
- .getpgtccfgtx = bnx2x_dcbnl_get_pg_tccfg_tx,
- .getpgbwgcfgtx = bnx2x_dcbnl_get_pg_bwgcfg_tx,
- .getpgtccfgrx = bnx2x_dcbnl_get_pg_tccfg_rx,
- .getpgbwgcfgrx = bnx2x_dcbnl_get_pg_bwgcfg_rx,
- .setpfccfg = bnx2x_dcbnl_set_pfc_cfg,
- .getpfccfg = bnx2x_dcbnl_get_pfc_cfg,
- .setall = bnx2x_dcbnl_set_all,
- .getcap = bnx2x_dcbnl_get_cap,
- .getnumtcs = bnx2x_dcbnl_get_numtcs,
- .setnumtcs = bnx2x_dcbnl_set_numtcs,
- .getpfcstate = bnx2x_dcbnl_get_pfc_state,
- .setpfcstate = bnx2x_dcbnl_set_pfc_state,
- .setapp = bnx2x_dcbnl_set_app_up,
- .getdcbx = bnx2x_dcbnl_get_dcbx,
- .setdcbx = bnx2x_dcbnl_set_dcbx,
- .getfeatcfg = bnx2x_dcbnl_get_featcfg,
- .setfeatcfg = bnx2x_dcbnl_set_featcfg,
+ .getstate = bnx2x_dcbnl_get_state,
+ .setstate = bnx2x_dcbnl_set_state,
+ .getpermhwaddr = bnx2x_dcbnl_get_perm_hw_addr,
+ .setpgtccfgtx = bnx2x_dcbnl_set_pg_tccfg_tx,
+ .setpgbwgcfgtx = bnx2x_dcbnl_set_pg_bwgcfg_tx,
+ .setpgtccfgrx = bnx2x_dcbnl_set_pg_tccfg_rx,
+ .setpgbwgcfgrx = bnx2x_dcbnl_set_pg_bwgcfg_rx,
+ .getpgtccfgtx = bnx2x_dcbnl_get_pg_tccfg_tx,
+ .getpgbwgcfgtx = bnx2x_dcbnl_get_pg_bwgcfg_tx,
+ .getpgtccfgrx = bnx2x_dcbnl_get_pg_tccfg_rx,
+ .getpgbwgcfgrx = bnx2x_dcbnl_get_pg_bwgcfg_rx,
+ .setpfccfg = bnx2x_dcbnl_set_pfc_cfg,
+ .getpfccfg = bnx2x_dcbnl_get_pfc_cfg,
+ .setall = bnx2x_dcbnl_set_all,
+ .getcap = bnx2x_dcbnl_get_cap,
+ .getnumtcs = bnx2x_dcbnl_get_numtcs,
+ .setnumtcs = bnx2x_dcbnl_set_numtcs,
+ .getpfcstate = bnx2x_dcbnl_get_pfc_state,
+ .setpfcstate = bnx2x_dcbnl_set_pfc_state,
+ .setapp = bnx2x_dcbnl_set_app_up,
+ .getdcbx = bnx2x_dcbnl_get_dcbx,
+ .setdcbx = bnx2x_dcbnl_set_dcbx,
+ .getfeatcfg = bnx2x_dcbnl_get_featcfg,
+ .setfeatcfg = bnx2x_dcbnl_set_featcfg,
+ .peer_getappinfo = bnx2x_peer_appinfo,
+ .peer_getapptable = bnx2x_peer_apptable,
+ .cee_peer_getpg = bnx2x_cee_peer_getpg,
+ .cee_peer_getpfc = bnx2x_cee_peer_getpfc,
};
#endif /* BCM_DCBNL */
diff --git a/drivers/net/bnx2x/bnx2x_dcb.h b/drivers/net/bnx2x/bnx2x_dcb.h
index 71b8eda43bd..bed369d67e0 100644
--- a/drivers/net/bnx2x/bnx2x_dcb.h
+++ b/drivers/net/bnx2x/bnx2x_dcb.h
@@ -1,6 +1,6 @@
/* bnx2x_dcb.h: Broadcom Everest network driver.
*
- * Copyright 2009-2010 Broadcom Corporation
+ * Copyright 2009-2011 Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -61,9 +61,6 @@ struct bnx2x_dcbx_port_params {
#define BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE 1
#define BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID (BNX2X_DCBX_CONFIG_INV_VALUE)
-/*******************************************************************************
- * LLDP protocol configuration parameters.
- ******************************************************************************/
struct bnx2x_config_lldp_params {
u32 overwrite_settings;
u32 msg_tx_hold;
@@ -83,9 +80,6 @@ struct bnx2x_admin_priority_app_table {
u32 app_id;
};
-/*******************************************************************************
- * DCBX protocol configuration parameters.
- ******************************************************************************/
struct bnx2x_config_dcbx_params {
u32 overwrite_settings;
u32 admin_dcbx_version;
@@ -183,9 +177,13 @@ void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled);
enum {
BNX2X_DCBX_STATE_NEG_RECEIVED = 0x1,
- BNX2X_DCBX_STATE_TX_PAUSED = 0x2,
- BNX2X_DCBX_STATE_TX_RELEASED = 0x4
+#ifdef BCM_CNIC
+ BNX2X_DCBX_STATE_ISCSI_STOPPED,
+#endif
+ BNX2X_DCBX_STATE_TX_PAUSED,
+ BNX2X_DCBX_STATE_TX_RELEASED
};
+
void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state);
/* DCB netlink */
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index 89cb977898c..727fe89ff37 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -1,6 +1,6 @@
/* bnx2x_ethtool.c: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
@@ -167,6 +167,7 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct bnx2x *bp = netdev_priv(dev);
int cfg_idx = bnx2x_get_link_cfg_idx(bp);
+
/* Dual Media boards present all available port types */
cmd->supported = bp->port.supported[cfg_idx] |
(bp->port.supported[cfg_idx ^ 1] &
@@ -176,16 +177,16 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if ((bp->state == BNX2X_STATE_OPEN) &&
!(bp->flags & MF_FUNC_DIS) &&
(bp->link_vars.link_up)) {
- cmd->speed = bp->link_vars.line_speed;
+ ethtool_cmd_speed_set(cmd, bp->link_vars.line_speed);
cmd->duplex = bp->link_vars.duplex;
} else {
-
- cmd->speed = bp->link_params.req_line_speed[cfg_idx];
+ ethtool_cmd_speed_set(
+ cmd, bp->link_params.req_line_speed[cfg_idx]);
cmd->duplex = bp->link_params.req_duplex[cfg_idx];
}
if (IS_MF(bp))
- cmd->speed = bnx2x_get_mf_speed(bp);
+ ethtool_cmd_speed_set(cmd, bnx2x_get_mf_speed(bp));
if (bp->port.supported[cfg_idx] & SUPPORTED_TP)
cmd->port = PORT_TP;
@@ -206,10 +207,11 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->maxrxpkt = 0;
DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
- DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n"
+ DP_LEVEL " supported 0x%x advertising 0x%x speed %u\n"
DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n"
DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n",
- cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
+ cmd->cmd, cmd->supported, cmd->advertising,
+ ethtool_cmd_speed(cmd),
cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
@@ -226,16 +228,15 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return 0;
DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
- " supported 0x%x advertising 0x%x speed %d speed_hi %d\n"
+ " supported 0x%x advertising 0x%x speed %u\n"
" duplex %d port %d phy_address %d transceiver %d\n"
" autoneg %d maxtxpkt %d maxrxpkt %d\n",
- cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
- cmd->speed_hi,
+ cmd->cmd, cmd->supported, cmd->advertising,
+ ethtool_cmd_speed(cmd),
cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
- speed = cmd->speed;
- speed |= (cmd->speed_hi << 16);
+ speed = ethtool_cmd_speed(cmd);
if (IS_MF_SI(bp)) {
u32 part;
@@ -439,7 +440,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
break;
default:
- DP(NETIF_MSG_LINK, "Unsupported speed %d\n", speed);
+ DP(NETIF_MSG_LINK, "Unsupported speed %u\n", speed);
return -EINVAL;
}
@@ -1219,7 +1220,8 @@ static int bnx2x_set_ringparam(struct net_device *dev,
}
if ((ering->rx_pending > MAX_RX_AVAIL) ||
- (ering->rx_pending < MIN_RX_AVAIL) ||
+ (ering->rx_pending < (bp->disable_tpa ? MIN_RX_SIZE_NONTPA :
+ MIN_RX_SIZE_TPA)) ||
(ering->tx_pending > MAX_TX_AVAIL) ||
(ering->tx_pending <= MAX_SKB_FRAGS + 4))
return -EINVAL;
@@ -1299,91 +1301,6 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
return 0;
}
-static int bnx2x_set_flags(struct net_device *dev, u32 data)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int changed = 0;
- int rc = 0;
-
- if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
- printk(KERN_ERR "Handling parity error recovery. Try again later\n");
- return -EAGAIN;
- }
-
- if (!(data & ETH_FLAG_RXVLAN))
- return -EINVAL;
-
- if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa)
- return -EINVAL;
-
- rc = ethtool_op_set_flags(dev, data, ETH_FLAG_LRO | ETH_FLAG_RXVLAN |
- ETH_FLAG_TXVLAN | ETH_FLAG_RXHASH);
- if (rc)
- return rc;
-
- /* TPA requires Rx CSUM offloading */
- if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
- if (!(bp->flags & TPA_ENABLE_FLAG)) {
- bp->flags |= TPA_ENABLE_FLAG;
- changed = 1;
- }
- } else if (bp->flags & TPA_ENABLE_FLAG) {
- dev->features &= ~NETIF_F_LRO;
- bp->flags &= ~TPA_ENABLE_FLAG;
- changed = 1;
- }
-
- if (changed && netif_running(dev)) {
- bnx2x_nic_unload(bp, UNLOAD_NORMAL);
- rc = bnx2x_nic_load(bp, LOAD_NORMAL);
- }
-
- return rc;
-}
-
-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);
- int rc = 0;
-
- if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
- printk(KERN_ERR "Handling parity error recovery. Try again later\n");
- return -EAGAIN;
- }
-
- bp->rx_csum = data;
-
- /* Disable TPA, when Rx CSUM is disabled. Otherwise all
- TPA'ed packets will be discarded due to wrong TCP CSUM */
- if (!data) {
- u32 flags = ethtool_op_get_flags(dev);
-
- rc = bnx2x_set_flags(dev, (flags & ~ETH_FLAG_LRO));
- }
-
- return rc;
-}
-
-static int bnx2x_set_tso(struct net_device *dev, u32 data)
-{
- if (data) {
- dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
- dev->features |= NETIF_F_TSO6;
- } else {
- dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN);
- dev->features &= ~NETIF_F_TSO6;
- }
-
- return 0;
-}
-
static const struct {
char string[ETH_GSTRING_LEN];
} bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = {
@@ -2097,35 +2014,37 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev,
}
}
-static int bnx2x_phys_id(struct net_device *dev, u32 data)
+static int bnx2x_set_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
struct bnx2x *bp = netdev_priv(dev);
- int i;
if (!netif_running(dev))
- return 0;
+ return -EAGAIN;
if (!bp->port.pmf)
- return 0;
+ return -EOPNOTSUPP;
- if (data == 0)
- data = 2;
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ return 1; /* cycle on/off once per second */
- for (i = 0; i < (data * 2); i++) {
- if ((i % 2) == 0)
- bnx2x_set_led(&bp->link_params, &bp->link_vars,
- LED_MODE_ON, SPEED_1000);
- else
- bnx2x_set_led(&bp->link_params, &bp->link_vars,
- LED_MODE_FRONT_PANEL_OFF, 0);
+ case ETHTOOL_ID_ON:
+ bnx2x_set_led(&bp->link_params, &bp->link_vars,
+ LED_MODE_ON, SPEED_1000);
+ break;
- msleep_interruptible(500);
- if (signal_pending(current))
- break;
- }
+ case ETHTOOL_ID_OFF:
+ bnx2x_set_led(&bp->link_params, &bp->link_vars,
+ LED_MODE_FRONT_PANEL_OFF, 0);
+
+ break;
- bnx2x_set_led(&bp->link_params, &bp->link_vars,
- LED_MODE_OPER, bp->link_vars.line_speed);
+ case ETHTOOL_ID_INACTIVE:
+ bnx2x_set_led(&bp->link_params, &bp->link_vars,
+ LED_MODE_OPER,
+ bp->link_vars.line_speed);
+ }
return 0;
}
@@ -2204,20 +2123,10 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
.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_hw_csum,
- .set_flags = bnx2x_set_flags,
- .get_flags = ethtool_op_get_flags,
- .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 = bnx2x_self_test,
.get_sset_count = bnx2x_get_sset_count,
.get_strings = bnx2x_get_strings,
- .phys_id = bnx2x_phys_id,
+ .set_phys_id = bnx2x_set_phys_id,
.get_ethtool_stats = bnx2x_get_ethtool_stats,
.get_rxnfc = bnx2x_get_rxnfc,
.get_rxfh_indir = bnx2x_get_rxfh_indir,
diff --git a/drivers/net/bnx2x/bnx2x_fw_defs.h b/drivers/net/bnx2x/bnx2x_fw_defs.h
index f4e5b1ce814..9fe367836a5 100644
--- a/drivers/net/bnx2x/bnx2x_fw_defs.h
+++ b/drivers/net/bnx2x/bnx2x_fw_defs.h
@@ -1,6 +1,6 @@
/* bnx2x_fw_defs.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
diff --git a/drivers/net/bnx2x/bnx2x_fw_file_hdr.h b/drivers/net/bnx2x/bnx2x_fw_file_hdr.h
index f807262911e..f4a07fbaed0 100644
--- a/drivers/net/bnx2x/bnx2x_fw_file_hdr.h
+++ b/drivers/net/bnx2x/bnx2x_fw_file_hdr.h
@@ -1,6 +1,6 @@
/* bnx2x_fw_file_hdr.h: FW binary file header structure.
*
- * Copyright (c) 2007-2009 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h
index dac1bf9cbbf..cdf19fe7c7f 100644
--- a/drivers/net/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/bnx2x/bnx2x_hsi.h
@@ -1,6 +1,6 @@
/* bnx2x_hsi.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
@@ -1929,7 +1929,7 @@ struct host_func_stats {
#define BCM_5710_FW_MAJOR_VERSION 6
#define BCM_5710_FW_MINOR_VERSION 2
-#define BCM_5710_FW_REVISION_VERSION 5
+#define BCM_5710_FW_REVISION_VERSION 9
#define BCM_5710_FW_ENGINEERING_VERSION 0
#define BCM_5710_FW_COMPILE_FLAGS 1
diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h
index fa6dbe3f205..d5399206f66 100644
--- a/drivers/net/bnx2x/bnx2x_init.h
+++ b/drivers/net/bnx2x/bnx2x_init.h
@@ -1,7 +1,7 @@
/* bnx2x_init.h: Broadcom Everest network driver.
* Structures and macroes needed during the initialization.
*
- * Copyright (c) 2007-2009 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h
index 66df29fcf75..aafd0232393 100644
--- a/drivers/net/bnx2x/bnx2x_init_ops.h
+++ b/drivers/net/bnx2x/bnx2x_init_ops.h
@@ -2,7 +2,7 @@
* Static functions needed during the initialization.
* This file is "included" in bnx2x_main.c.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c
index 974ef2be36a..076e11f5769 100644
--- a/drivers/net/bnx2x/bnx2x_link.c
+++ b/drivers/net/bnx2x/bnx2x_link.c
@@ -385,7 +385,7 @@ u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
return 0;
}
/******************************************************************/
-/* ETS section */
+/* PFC section */
/******************************************************************/
static void bnx2x_bmac2_get_pfc_stat(struct link_params *params,
@@ -1301,14 +1301,12 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
return 0;
}
-/*
- * get_emac_base
- *
- * @param cb
- * @param mdc_mdio_access
- * @param port
+/**
+ * bnx2x_get_emac_base - retrive emac base address
*
- * @return u32
+ * @bp: driver handle
+ * @mdc_mdio_access: access type
+ * @port: port id
*
* This function selects the MDC/MDIO access (through emac0 or
* emac1) depend on the mdc_mdio_access, port, port swapped. Each
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index a97a4a1c344..f45c0caf324 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -1,6 +1,6 @@
/* bnx2x_main.c: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
@@ -2036,7 +2036,7 @@ static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp)
return CMNG_FNS_NONE;
}
-static void bnx2x_read_mf_cfg(struct bnx2x *bp)
+void bnx2x_read_mf_cfg(struct bnx2x *bp)
{
int vn, n = (CHIP_MODE_IS_4_PORT(bp) ? 2 : 1);
@@ -2123,7 +2123,6 @@ static inline void bnx2x_link_sync_notify(struct bnx2x *bp)
/* This function is called upon link interrupt */
static void bnx2x_link_attn(struct bnx2x *bp)
{
- u32 prev_link_status = bp->link_vars.link_status;
/* Make sure that we are synced with the current statistics */
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
@@ -2168,17 +2167,15 @@ static void bnx2x_link_attn(struct bnx2x *bp)
"single function mode without fairness\n");
}
+ __bnx2x_link_report(bp);
+
if (IS_MF(bp))
bnx2x_link_sync_notify(bp);
-
- /* indicate link status only if link status actually changed */
- if (prev_link_status != bp->link_vars.link_status)
- bnx2x_link_report(bp);
}
void bnx2x__link_status_update(struct bnx2x *bp)
{
- if ((bp->state != BNX2X_STATE_OPEN) || (bp->flags & MF_FUNC_DIS))
+ if (bp->state != BNX2X_STATE_OPEN)
return;
bnx2x_link_status_update(&bp->link_params, &bp->link_vars);
@@ -2188,10 +2185,6 @@ void bnx2x__link_status_update(struct bnx2x *bp)
else
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
- /* the link status update could be the result of a DCC event
- hence re-read the shmem mf configuration */
- bnx2x_read_mf_cfg(bp);
-
/* indicate link status */
bnx2x_link_report(bp);
}
@@ -3120,10 +3113,14 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
if (val & DRV_STATUS_SET_MF_BW)
bnx2x_set_mf_bw(bp);
- bnx2x__link_status_update(bp);
if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF))
bnx2x_pmf_update(bp);
+ /* Always call it here: bnx2x_link_report() will
+ * prevent the link indication duplication.
+ */
+ bnx2x__link_status_update(bp);
+
if (bp->port.pmf &&
(val & DRV_STATUS_DCBX_NEGOTIATION_RESULTS) &&
bp->dcbx_enabled > 0)
@@ -3904,10 +3901,9 @@ static void bnx2x_timer(unsigned long data)
if (poll) {
struct bnx2x_fastpath *fp = &bp->fp[0];
- int rc;
bnx2x_tx_int(fp);
- rc = bnx2x_rx_int(fp, 1000);
+ bnx2x_rx_int(fp, 1000);
}
if (!BP_NOMCP(bp)) {
@@ -4062,7 +4058,6 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid,
struct hc_status_block_data_e2 sb_data_e2;
struct hc_status_block_data_e1x sb_data_e1x;
struct hc_status_block_sm *hc_sm_p;
- struct hc_index_data *hc_index_p;
int data_size;
u32 *sb_data_p;
@@ -4083,7 +4078,6 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid,
sb_data_e2.common.host_sb_addr.hi = U64_HI(mapping);
sb_data_e2.common.host_sb_addr.lo = U64_LO(mapping);
hc_sm_p = sb_data_e2.common.state_machine;
- hc_index_p = sb_data_e2.index_data;
sb_data_p = (u32 *)&sb_data_e2;
data_size = sizeof(struct hc_status_block_data_e2)/sizeof(u32);
} else {
@@ -4097,7 +4091,6 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid,
sb_data_e1x.common.host_sb_addr.hi = U64_HI(mapping);
sb_data_e1x.common.host_sb_addr.lo = U64_LO(mapping);
hc_sm_p = sb_data_e1x.common.state_machine;
- hc_index_p = sb_data_e1x.index_data;
sb_data_p = (u32 *)&sb_data_e1x;
data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32);
}
@@ -4454,7 +4447,7 @@ static void bnx2x_init_fp_sb(struct bnx2x *bp, int fp_idx)
fp->state = BNX2X_FP_STATE_CLOSED;
- fp->index = fp->cid = fp_idx;
+ fp->cid = fp_idx;
fp->cl_id = BP_L_ID(bp) + fp_idx;
fp->fw_sb_id = bp->base_fw_ndsb + fp->cl_id + CNIC_CONTEXT_USE;
fp->igu_sb_id = bp->igu_base_sb + fp_idx + CNIC_CONTEXT_USE;
@@ -4566,9 +4559,11 @@ gunzip_nomem1:
static void bnx2x_gunzip_end(struct bnx2x *bp)
{
- kfree(bp->strm->workspace);
- kfree(bp->strm);
- bp->strm = NULL;
+ if (bp->strm) {
+ kfree(bp->strm->workspace);
+ kfree(bp->strm);
+ bp->strm = NULL;
+ }
if (bp->gunzip_buf) {
dma_free_coherent(&bp->pdev->dev, FW_BUF_SIZE, bp->gunzip_buf,
@@ -5876,9 +5871,6 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code)
bp->dmae_ready = 0;
spin_lock_init(&bp->dmae_lock);
- rc = bnx2x_gunzip_init(bp);
- if (rc)
- return rc;
switch (load_code) {
case FW_MSG_CODE_DRV_LOAD_COMMON:
@@ -5922,80 +5914,10 @@ init_hw_err:
void bnx2x_free_mem(struct bnx2x *bp)
{
-
-#define BNX2X_PCI_FREE(x, y, size) \
- do { \
- if (x) { \
- dma_free_coherent(&bp->pdev->dev, size, (void *)x, y); \
- x = NULL; \
- y = 0; \
- } \
- } while (0)
-
-#define BNX2X_FREE(x) \
- do { \
- if (x) { \
- kfree((void *)x); \
- x = NULL; \
- } \
- } while (0)
-
- int i;
+ bnx2x_gunzip_end(bp);
/* fastpath */
- /* Common */
- for_each_queue(bp, i) {
-#ifdef BCM_CNIC
- /* FCoE client uses default status block */
- if (IS_FCOE_IDX(i)) {
- union host_hc_status_block *sb =
- &bnx2x_fp(bp, i, status_blk);
- memset(sb, 0, sizeof(union host_hc_status_block));
- bnx2x_fp(bp, i, status_blk_mapping) = 0;
- } else {
-#endif
- /* status blocks */
- if (CHIP_IS_E2(bp))
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e2_sb),
- bnx2x_fp(bp, i, status_blk_mapping),
- sizeof(struct host_hc_status_block_e2));
- else
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e1x_sb),
- bnx2x_fp(bp, i, status_blk_mapping),
- sizeof(struct host_hc_status_block_e1x));
-#ifdef BCM_CNIC
- }
-#endif
- }
- /* Rx */
- for_each_rx_queue(bp, i) {
-
- /* fastpath rx rings: rx_buf rx_desc rx_comp */
- 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);
-
- /* SGE ring */
- BNX2X_FREE(bnx2x_fp(bp, i, rx_page_ring));
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_sge_ring),
- bnx2x_fp(bp, i, rx_sge_mapping),
- BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
- }
- /* Tx */
- for_each_tx_queue(bp, i) {
-
- /* fastpath tx rings: tx_buf tx_desc */
- 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(union eth_tx_bd_types) * NUM_TX_BD);
- }
+ bnx2x_free_fp_mem(bp);
/* end of fastpath */
BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping,
@@ -6028,101 +5950,13 @@ void bnx2x_free_mem(struct bnx2x *bp)
BCM_PAGE_SIZE * NUM_EQ_PAGES);
BNX2X_FREE(bp->rx_indir_table);
-
-#undef BNX2X_PCI_FREE
-#undef BNX2X_KFREE
}
-static inline void set_sb_shortcuts(struct bnx2x *bp, int index)
-{
- union host_hc_status_block status_blk = bnx2x_fp(bp, index, status_blk);
- if (CHIP_IS_E2(bp)) {
- bnx2x_fp(bp, index, sb_index_values) =
- (__le16 *)status_blk.e2_sb->sb.index_values;
- bnx2x_fp(bp, index, sb_running_index) =
- (__le16 *)status_blk.e2_sb->sb.running_index;
- } else {
- bnx2x_fp(bp, index, sb_index_values) =
- (__le16 *)status_blk.e1x_sb->sb.index_values;
- bnx2x_fp(bp, index, sb_running_index) =
- (__le16 *)status_blk.e1x_sb->sb.running_index;
- }
-}
int bnx2x_alloc_mem(struct bnx2x *bp)
{
-#define BNX2X_PCI_ALLOC(x, y, size) \
- do { \
- x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \
- if (x == NULL) \
- goto alloc_mem_err; \
- memset(x, 0, size); \
- } while (0)
-
-#define BNX2X_ALLOC(x, size) \
- do { \
- x = kzalloc(size, GFP_KERNEL); \
- if (x == NULL) \
- goto alloc_mem_err; \
- } while (0)
-
- int i;
-
- /* fastpath */
- /* Common */
- for_each_queue(bp, i) {
- union host_hc_status_block *sb = &bnx2x_fp(bp, i, status_blk);
- bnx2x_fp(bp, i, bp) = bp;
- /* status blocks */
-#ifdef BCM_CNIC
- if (!IS_FCOE_IDX(i)) {
-#endif
- if (CHIP_IS_E2(bp))
- BNX2X_PCI_ALLOC(sb->e2_sb,
- &bnx2x_fp(bp, i, status_blk_mapping),
- sizeof(struct host_hc_status_block_e2));
- else
- BNX2X_PCI_ALLOC(sb->e1x_sb,
- &bnx2x_fp(bp, i, status_blk_mapping),
- sizeof(struct host_hc_status_block_e1x));
-#ifdef BCM_CNIC
- }
-#endif
- set_sb_shortcuts(bp, i);
- }
- /* Rx */
- for_each_queue(bp, i) {
-
- /* fastpath rx rings: rx_buf rx_desc rx_comp */
- 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);
-
- /* SGE ring */
- BNX2X_ALLOC(bnx2x_fp(bp, i, rx_page_ring),
- sizeof(struct sw_rx_page) * NUM_RX_SGE);
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_sge_ring),
- &bnx2x_fp(bp, i, rx_sge_mapping),
- BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
- }
- /* Tx */
- for_each_queue(bp, i) {
-
- /* fastpath tx rings: tx_buf tx_desc */
- 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(union eth_tx_bd_types) * NUM_TX_BD);
- }
- /* end of fastpath */
+ if (bnx2x_gunzip_init(bp))
+ return -ENOMEM;
#ifdef BCM_CNIC
if (CHIP_IS_E2(bp))
@@ -6162,14 +5996,18 @@ int bnx2x_alloc_mem(struct bnx2x *bp)
BNX2X_ALLOC(bp->rx_indir_table, sizeof(bp->rx_indir_table[0]) *
TSTORM_INDIRECTION_TABLE_SIZE);
+
+ /* fastpath */
+ /* need to be done at the end, since it's self adjusting to amount
+ * of memory available for RSS queues
+ */
+ if (bnx2x_alloc_fp_mem(bp))
+ goto alloc_mem_err;
return 0;
alloc_mem_err:
bnx2x_free_mem(bp);
return -ENOMEM;
-
-#undef BNX2X_PCI_ALLOC
-#undef BNX2X_ALLOC
}
/*
@@ -6197,14 +6035,14 @@ static int bnx2x_func_stop(struct bnx2x *bp)
}
/**
- * Sets a MAC in a CAM for a few L2 Clients for E1x chips
+ * bnx2x_set_mac_addr_gen - set a MAC in a CAM for a few L2 Clients for E1x chips
*
- * @param bp driver descriptor
- * @param set set or clear an entry (1 or 0)
- * @param mac pointer to a buffer containing a MAC
- * @param cl_bit_vec bit vector of clients to register a MAC for
- * @param cam_offset offset in a CAM to use
- * @param is_bcast is the set MAC a broadcast address (for E1 only)
+ * @bp: driver handle
+ * @set: set or clear an entry (1 or 0)
+ * @mac: pointer to a buffer containing a MAC
+ * @cl_bit_vec: bit vector of clients to register a MAC for
+ * @cam_offset: offset in a CAM to use
+ * @is_bcast: is the set MAC a broadcast address (for E1 only)
*/
static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac,
u32 cl_bit_vec, u8 cam_offset,
@@ -6564,14 +6402,13 @@ void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp)
#ifdef BCM_CNIC
/**
- * Set iSCSI MAC(s) at the next enties in the CAM after the ETH
- * MAC(s). This function will wait until the ramdord completion
- * returns.
+ * bnx2x_set_iscsi_eth_mac_addr - set iSCSI MAC(s).
*
- * @param bp driver handle
- * @param set set or clear the CAM entry
+ * @bp: driver handle
+ * @set: set or clear the CAM entry
*
- * @return 0 if cussess, -ENODEV if ramrod doesn't return.
+ * This function will wait until the ramdord completion returns.
+ * Return 0 if success, -ENODEV if ramrod doesn't return.
*/
static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set)
{
@@ -6592,14 +6429,13 @@ static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set)
}
/**
- * Set FCoE L2 MAC(s) at the next enties in the CAM after the
- * ETH MAC(s). This function will wait until the ramdord
- * completion returns.
+ * bnx2x_set_fip_eth_mac_addr - set FCoE L2 MAC(s)
*
- * @param bp driver handle
- * @param set set or clear the CAM entry
+ * @bp: driver handle
+ * @set: set or clear the CAM entry
*
- * @return 0 if cussess, -ENODEV if ramrod doesn't return.
+ * This function will wait until the ramrod completion returns.
+ * Returns 0 if success, -ENODEV if ramrod doesn't return.
*/
int bnx2x_set_fip_eth_mac_addr(struct bnx2x *bp, int set)
{
@@ -6803,12 +6639,11 @@ static int bnx2x_setup_fw_client(struct bnx2x *bp,
}
/**
- * Configure interrupt mode according to current configuration.
- * In case of MSI-X it will also try to enable MSI-X.
+ * bnx2x_set_int_mode - configure interrupt mode
*
- * @param bp
+ * @bp: driver handle
*
- * @return int
+ * In case of MSI-X it will also try to enable MSI-X.
*/
static int __devinit bnx2x_set_int_mode(struct bnx2x *bp)
{
@@ -7392,10 +7227,11 @@ static void bnx2x_clp_reset_prep(struct bnx2x *bp, u32 *magic_val)
MF_CFG_WR(bp, shared_mf_config.clp_mb, val | SHARED_MF_CLP_MAGIC);
}
-/* Restore the value of the `magic' bit.
+/**
+ * bnx2x_clp_reset_done - restore the value of the `magic' bit.
*
- * @param pdev Device handle.
- * @param magic_val Old value of the `magic' bit.
+ * @bp: driver handle
+ * @magic_val: old value of the `magic' bit.
*/
static void bnx2x_clp_reset_done(struct bnx2x *bp, u32 magic_val)
{
@@ -7406,10 +7242,12 @@ static void bnx2x_clp_reset_done(struct bnx2x *bp, u32 magic_val)
}
/**
- * Prepares for MCP reset: takes care of CLP configurations.
+ * bnx2x_reset_mcp_prep - prepare for MCP reset.
*
- * @param bp
- * @param magic_val Old value of 'magic' bit.
+ * @bp: driver handle
+ * @magic_val: old value of 'magic' bit.
+ *
+ * Takes care of CLP configurations.
*/
static void bnx2x_reset_mcp_prep(struct bnx2x *bp, u32 *magic_val)
{
@@ -7434,10 +7272,10 @@ static void bnx2x_reset_mcp_prep(struct bnx2x *bp, u32 *magic_val)
#define MCP_TIMEOUT 5000 /* 5 seconds (in ms) */
#define MCP_ONE_TIMEOUT 100 /* 100 ms */
-/* Waits for MCP_ONE_TIMEOUT or MCP_ONE_TIMEOUT*10,
- * depending on the HW type.
+/**
+ * bnx2x_mcp_wait_one - wait for MCP_ONE_TIMEOUT
*
- * @param bp
+ * @bp: driver handle
*/
static inline void bnx2x_mcp_wait_one(struct bnx2x *bp)
{
@@ -8059,13 +7897,9 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
(val >= REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL) ?
FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY : 0;
- if (BP_E1HVN(bp) == 0) {
- pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc);
- bp->flags |= (pmc & PCI_PM_CAP_PME_D3cold) ? 0 : NO_WOL_FLAG;
- } else {
- /* no WOL capability for E1HVN != 0 */
- bp->flags |= NO_WOL_FLAG;
- }
+ pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc);
+ bp->flags |= (pmc & PCI_PM_CAP_PME_D3cold) ? 0 : NO_WOL_FLAG;
+
BNX2X_DEV_INFO("%sWoL capable\n",
(bp->flags & NO_WOL_FLAG) ? "not " : "");
@@ -8571,15 +8405,6 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp)
BNX2X_DEV_INFO("Read iSCSI MAC: "
"0x%x:0x%04x\n", val2, val);
bnx2x_set_mac_buf(iscsi_mac, val, val2);
-
- /* Disable iSCSI OOO if MAC configuration is
- * invalid.
- */
- if (!is_valid_ether_addr(iscsi_mac)) {
- bp->flags |= NO_ISCSI_OOO_FLAG |
- NO_ISCSI_FLAG;
- memset(iscsi_mac, 0, ETH_ALEN);
- }
} else
bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG;
@@ -8592,13 +8417,6 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp)
"0x%x:0x%04x\n", val2, val);
bnx2x_set_mac_buf(fip_mac, val, val2);
- /* Disable FCoE if MAC configuration is
- * invalid.
- */
- if (!is_valid_ether_addr(fip_mac)) {
- bp->flags |= NO_FCOE_FLAG;
- memset(bp->fip_mac, 0, ETH_ALEN);
- }
} else
bp->flags |= NO_FCOE_FLAG;
}
@@ -8629,13 +8447,29 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp)
else if (!IS_MF(bp))
memcpy(fip_mac, iscsi_mac, ETH_ALEN);
}
+
+ /* Disable iSCSI if MAC configuration is
+ * invalid.
+ */
+ if (!is_valid_ether_addr(iscsi_mac)) {
+ bp->flags |= NO_ISCSI_FLAG;
+ memset(iscsi_mac, 0, ETH_ALEN);
+ }
+
+ /* Disable FCoE if MAC configuration is
+ * invalid.
+ */
+ if (!is_valid_ether_addr(fip_mac)) {
+ bp->flags |= NO_FCOE_FLAG;
+ memset(bp->fip_mac, 0, ETH_ALEN);
+ }
#endif
}
static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
{
int /*abs*/func = BP_ABS_FUNC(bp);
- int vn, port;
+ int vn;
u32 val = 0;
int rc = 0;
@@ -8670,7 +8504,6 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
bp->mf_ov = 0;
bp->mf_mode = 0;
vn = BP_E1HVN(bp);
- port = BP_PORT(bp);
if (!CHIP_IS_E1(bp) && !BP_NOMCP(bp)) {
DP(NETIF_MSG_PROBE,
@@ -8904,8 +8737,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
bp->multi_mode = multi_mode;
bp->int_mode = int_mode;
- bp->dev->features |= NETIF_F_GRO;
-
/* Set TPA flags */
if (disable_tpa) {
bp->flags &= ~TPA_ENABLE_FLAG;
@@ -8925,8 +8756,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
bp->tx_ring_size = MAX_TX_AVAIL;
- bp->rx_csum = 1;
-
/* make sure that the numbers are in the right granularity */
bp->tx_ticks = (50 / BNX2X_BTR) * BNX2X_BTR;
bp->rx_ticks = (25 / BNX2X_BTR) * BNX2X_BTR;
@@ -9304,6 +9133,8 @@ static const struct net_device_ops bnx2x_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = bnx2x_ioctl,
.ndo_change_mtu = bnx2x_change_mtu,
+ .ndo_fix_features = bnx2x_fix_features,
+ .ndo_set_features = bnx2x_set_features,
.ndo_tx_timeout = bnx2x_tx_timeout,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = poll_bnx2x,
@@ -9430,20 +9261,20 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
dev->netdev_ops = &bnx2x_netdev_ops;
bnx2x_set_ethtool_ops(dev);
- dev->features |= NETIF_F_SG;
- dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+
+ dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 |
+ NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_HW_VLAN_TX;
+
+ dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA;
+
+ dev->features |= dev->hw_features | NETIF_F_HW_VLAN_RX;
if (bp->flags & USING_DAC_FLAG)
dev->features |= NETIF_F_HIGHDMA;
- dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
- dev->features |= NETIF_F_TSO6;
- dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
- dev->vlan_features |= NETIF_F_SG;
- dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
- if (bp->flags & USING_DAC_FLAG)
- dev->vlan_features |= NETIF_F_HIGHDMA;
- dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
- dev->vlan_features |= NETIF_F_TSO6;
+ /* Add Loopback capability to the device */
+ dev->hw_features |= NETIF_F_LOOPBACK;
#ifdef BCM_DCBNL
dev->dcbnl_ops = &bnx2x_dcbnl_ops;
@@ -10342,6 +10173,11 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
break;
}
+ case DRV_CTL_ISCSI_STOPPED_CMD: {
+ bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_ISCSI_STOPPED);
+ break;
+ }
+
default:
BNX2X_ERR("unknown command %x\n", ctl->cmd);
rc = -EINVAL;
diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h
index 1509a2318af..86bba25d2d3 100644
--- a/drivers/net/bnx2x/bnx2x_reg.h
+++ b/drivers/net/bnx2x/bnx2x_reg.h
@@ -1,6 +1,6 @@
/* bnx2x_reg.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c
index 3445ded6674..e535bfa0894 100644
--- a/drivers/net/bnx2x/bnx2x_stats.c
+++ b/drivers/net/bnx2x/bnx2x_stats.c
@@ -1,6 +1,6 @@
/* bnx2x_stats.c: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
diff --git a/drivers/net/bnx2x/bnx2x_stats.h b/drivers/net/bnx2x/bnx2x_stats.h
index 596798c4745..45d14d8bc1a 100644
--- a/drivers/net/bnx2x/bnx2x_stats.h
+++ b/drivers/net/bnx2x/bnx2x_stats.h
@@ -1,6 +1,6 @@
/* bnx2x_stats.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 3c5c014e82b..4c21bf6b8b2 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -9,6 +9,3 @@ bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_debugfs.o
proc-$(CONFIG_PROC_FS) += bond_procfs.o
bonding-objs += $(proc-y)
-ipv6-$(subst m,y,$(CONFIG_IPV6)) += bond_ipv6.o
-bonding-objs += $(ipv6-y)
-
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 31912f17653..c7537abca4f 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -716,11 +716,9 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val)
static u32 __get_agg_bandwidth(struct aggregator *aggregator)
{
u32 bandwidth = 0;
- u32 basic_speed;
if (aggregator->num_of_ports) {
- basic_speed = __get_link_speed(aggregator->lag_ports);
- switch (basic_speed) {
+ switch (__get_link_speed(aggregator->lag_ports)) {
case AD_LINK_SPEED_BITMASK_1MBPS:
bandwidth = aggregator->num_of_ports;
break;
@@ -2405,14 +2403,6 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
struct ad_info ad_info;
int res = 1;
- /* make sure that the slaves list will
- * not change during tx
- */
- read_lock(&bond->lock);
-
- if (!BOND_IS_OK(bond))
- goto out;
-
if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
pr_debug("%s: Error: bond_3ad_get_active_agg_info failed\n",
dev->name);
@@ -2466,39 +2456,20 @@ out:
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
}
- read_unlock(&bond->lock);
+
return NETDEV_TX_OK;
}
-int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev)
+void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond,
+ struct slave *slave)
{
- struct bonding *bond = netdev_priv(dev);
- struct slave *slave = NULL;
- int ret = NET_RX_DROP;
-
- if (!(dev->flags & IFF_MASTER))
- goto out;
-
- skb = skb_share_check(skb, GFP_ATOMIC);
- if (!skb)
- goto out;
+ if (skb->protocol != PKT_TYPE_LACPDU)
+ return;
if (!pskb_may_pull(skb, sizeof(struct lacpdu)))
- goto out;
+ return;
read_lock(&bond->lock);
- slave = bond_get_slave_by_dev(netdev_priv(dev), orig_dev);
- if (!slave)
- goto out_unlock;
-
bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len);
-
- ret = NET_RX_SUCCESS;
-
-out_unlock:
read_unlock(&bond->lock);
-out:
- dev_kfree_skb(skb);
-
- return ret;
}
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index 01b8a6af275..0ee3f1632c4 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -258,7 +258,6 @@ struct ad_bond_info {
* requested
*/
struct timer_list ad_timer;
- struct packet_type ad_pkt_type;
};
struct ad_slave_info {
@@ -280,7 +279,8 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave);
void bond_3ad_handle_link_change(struct slave *slave, char link);
int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
-int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev);
+void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond,
+ struct slave *slave);
int bond_3ad_set_carrier(struct bonding *bond);
#endif //__BOND_3AD_H__
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index ba715826e2a..8f2d2e7c70e 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -308,49 +308,33 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
_unlock_rx_hashtbl(bond);
}
-static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype, struct net_device *orig_dev)
+static void rlb_arp_recv(struct sk_buff *skb, struct bonding *bond,
+ struct slave *slave)
{
- struct bonding *bond;
- struct arp_pkt *arp = (struct arp_pkt *)skb->data;
- int res = NET_RX_DROP;
+ struct arp_pkt *arp;
- while (bond_dev->priv_flags & IFF_802_1Q_VLAN)
- bond_dev = vlan_dev_real_dev(bond_dev);
-
- if (!(bond_dev->priv_flags & IFF_BONDING) ||
- !(bond_dev->flags & IFF_MASTER))
- goto out;
+ if (skb->protocol != cpu_to_be16(ETH_P_ARP))
+ return;
+ arp = (struct arp_pkt *) skb->data;
if (!arp) {
pr_debug("Packet has no ARP data\n");
- goto out;
+ return;
}
- skb = skb_share_check(skb, GFP_ATOMIC);
- if (!skb)
- goto out;
-
- if (!pskb_may_pull(skb, arp_hdr_len(bond_dev)))
- goto out;
+ if (!pskb_may_pull(skb, arp_hdr_len(bond->dev)))
+ return;
if (skb->len < sizeof(struct arp_pkt)) {
pr_debug("Packet is too small to be an ARP\n");
- goto out;
+ return;
}
if (arp->op_code == htons(ARPOP_REPLY)) {
/* update rx hash table for this ARP */
- bond = netdev_priv(bond_dev);
rlb_update_entry_from_arp(bond, arp);
pr_debug("Server received an ARP Reply from client\n");
}
-
- res = NET_RX_SUCCESS;
-
-out:
- dev_kfree_skb(skb);
-
- return res;
}
/* Caller must hold bond lock for read */
@@ -759,7 +743,6 @@ static void rlb_init_table_entry(struct rlb_client_info *entry)
static int rlb_initialize(struct bonding *bond)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
- struct packet_type *pk_type = &(BOND_ALB_INFO(bond).rlb_pkt_type);
struct rlb_client_info *new_hashtbl;
int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info);
int i;
@@ -784,13 +767,8 @@ static int rlb_initialize(struct bonding *bond)
_unlock_rx_hashtbl(bond);
- /*initialize packet type*/
- pk_type->type = cpu_to_be16(ETH_P_ARP);
- pk_type->dev = bond->dev;
- pk_type->func = rlb_arp_recv;
-
/* register to receive ARPs */
- dev_add_pack(pk_type);
+ bond->recv_probe = rlb_arp_recv;
return 0;
}
@@ -799,8 +777,6 @@ static void rlb_deinitialize(struct bonding *bond)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
- dev_remove_pack(&(bond_info->rlb_pkt_type));
-
_lock_rx_hashtbl(bond);
kfree(bond_info->rx_hashtbl);
@@ -1249,16 +1225,10 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
skb_reset_mac_header(skb);
eth_data = eth_hdr(skb);
- /* make sure that the curr_active_slave and the slaves list do
- * not change during tx
+ /* make sure that the curr_active_slave do not change during tx
*/
- read_lock(&bond->lock);
read_lock(&bond->curr_slave_lock);
- if (!BOND_IS_OK(bond)) {
- goto out;
- }
-
switch (ntohs(skb->protocol)) {
case ETH_P_IP: {
const struct iphdr *iph = ip_hdr(skb);
@@ -1358,13 +1328,12 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
}
}
-out:
if (res) {
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
}
read_unlock(&bond->curr_slave_lock);
- read_unlock(&bond->lock);
+
return NETDEV_TX_OK;
}
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index 8ca7158b2dd..90f140a2d19 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -129,7 +129,6 @@ struct alb_bond_info {
int lp_counter;
/* -------- rlb parameters -------- */
int rlb_enabled;
- struct packet_type rlb_pkt_type;
struct rlb_client_info *rx_hashtbl; /* Receive hash table */
spinlock_t rx_hashtbl_lock;
u32 rx_hashtbl_head;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 16d6fe95469..088fd845ffd 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -89,8 +89,7 @@
static int max_bonds = BOND_DEFAULT_MAX_BONDS;
static int tx_queues = BOND_DEFAULT_TX_QUEUES;
-static int num_grat_arp = 1;
-static int num_unsol_na = 1;
+static int num_peer_notif = 1;
static int miimon = BOND_LINK_MON_INTERV;
static int updelay;
static int downdelay;
@@ -113,10 +112,10 @@ module_param(max_bonds, int, 0);
MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
module_param(tx_queues, int, 0);
MODULE_PARM_DESC(tx_queues, "Max number of transmit queues (default = 16)");
-module_param(num_grat_arp, int, 0644);
-MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event");
-module_param(num_unsol_na, int, 0644);
-MODULE_PARM_DESC(num_unsol_na, "Number of unsolicited IPv6 Neighbor Advertisements packets to send on failover event");
+module_param_named(num_grat_arp, num_peer_notif, int, 0644);
+MODULE_PARM_DESC(num_grat_arp, "Number of peer notifications to send on failover event (alias of num_unsol_na)");
+module_param_named(num_unsol_na, num_peer_notif, int, 0644);
+MODULE_PARM_DESC(num_unsol_na, "Number of peer notifications to send on failover event (alias of num_grat_arp)");
module_param(miimon, int, 0);
MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
module_param(updelay, int, 0);
@@ -234,7 +233,6 @@ struct bond_parm_tbl ad_select_tbl[] = {
/*-------------------------- Forward declarations ---------------------------*/
-static void bond_send_gratuitous_arp(struct bonding *bond);
static int bond_init(struct net_device *bond_dev);
static void bond_uninit(struct net_device *bond_dev);
@@ -346,32 +344,6 @@ out:
}
/**
- * bond_has_challenged_slaves
- * @bond: the bond we're working on
- *
- * Searches the slave list. Returns 1 if a vlan challenged slave
- * was found, 0 otherwise.
- *
- * Assumes bond->lock is held.
- */
-static int bond_has_challenged_slaves(struct bonding *bond)
-{
- struct slave *slave;
- int i;
-
- bond_for_each_slave(bond, slave, i) {
- if (slave->dev->features & NETIF_F_VLAN_CHALLENGED) {
- pr_debug("found VLAN challenged slave - %s\n",
- slave->dev->name);
- return 1;
- }
- }
-
- pr_debug("no VLAN challenged slaves found\n");
- return 0;
-}
-
-/**
* bond_next_vlan - safely skip to the next item in the vlans list.
* @bond: the bond we're working on
* @curr: item we're advancing from
@@ -631,7 +603,8 @@ down:
static int bond_update_speed_duplex(struct slave *slave)
{
struct net_device *slave_dev = slave->dev;
- struct ethtool_cmd etool;
+ struct ethtool_cmd etool = { .cmd = ETHTOOL_GSET };
+ u32 slave_speed;
int res;
/* Fake speed and duplex */
@@ -645,7 +618,8 @@ static int bond_update_speed_duplex(struct slave *slave)
if (res < 0)
return -1;
- switch (etool.speed) {
+ slave_speed = ethtool_cmd_speed(&etool);
+ switch (slave_speed) {
case SPEED_10:
case SPEED_100:
case SPEED_1000:
@@ -663,7 +637,7 @@ static int bond_update_speed_duplex(struct slave *slave)
return -1;
}
- slave->speed = etool.speed;
+ slave->speed = slave_speed;
slave->duplex = etool.duplex;
return 0;
@@ -1087,6 +1061,21 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
return bestslave;
}
+static bool bond_should_notify_peers(struct bonding *bond)
+{
+ struct slave *slave = bond->curr_active_slave;
+
+ pr_debug("bond_should_notify_peers: bond %s slave %s\n",
+ bond->dev->name, slave ? slave->dev->name : "NULL");
+
+ if (!slave || !bond->send_peer_notif ||
+ test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
+ return false;
+
+ bond->send_peer_notif--;
+ return true;
+}
+
/**
* change_active_interface - change the active slave into the specified one
* @bond: our bonding struct
@@ -1154,6 +1143,8 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
bond_set_slave_inactive_flags(old_active);
if (new_active) {
+ bool should_notify_peers = false;
+
bond_set_slave_active_flags(new_active);
if (bond->params.fail_over_mac)
@@ -1161,17 +1152,19 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
old_active);
if (netif_running(bond->dev)) {
- bond->send_grat_arp = bond->params.num_grat_arp;
- bond_send_gratuitous_arp(bond);
-
- bond->send_unsol_na = bond->params.num_unsol_na;
- bond_send_unsolicited_na(bond);
+ bond->send_peer_notif =
+ bond->params.num_peer_notif;
+ should_notify_peers =
+ bond_should_notify_peers(bond);
}
write_unlock_bh(&bond->curr_slave_lock);
read_unlock(&bond->lock);
netdev_bonding_change(bond->dev, NETDEV_BONDING_FAILOVER);
+ if (should_notify_peers)
+ netdev_bonding_change(bond->dev,
+ NETDEV_NOTIFY_PEERS);
read_lock(&bond->lock);
write_lock_bh(&bond->curr_slave_lock);
@@ -1387,52 +1380,68 @@ static int bond_sethwaddr(struct net_device *bond_dev,
return 0;
}
-#define BOND_VLAN_FEATURES \
- (NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | \
- NETIF_F_HW_VLAN_FILTER)
-
-/*
- * Compute the common dev->feature set available to all slaves. Some
- * feature bits are managed elsewhere, so preserve those feature bits
- * on the master device.
- */
-static int bond_compute_features(struct bonding *bond)
+static u32 bond_fix_features(struct net_device *dev, u32 features)
{
struct slave *slave;
- struct net_device *bond_dev = bond->dev;
- u32 features = bond_dev->features;
- u32 vlan_features = 0;
- unsigned short max_hard_header_len = max((u16)ETH_HLEN,
- bond_dev->hard_header_len);
+ struct bonding *bond = netdev_priv(dev);
+ u32 mask;
int i;
- features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES);
- features |= NETIF_F_GSO_MASK | NETIF_F_NO_CSUM;
+ read_lock(&bond->lock);
- if (!bond->first_slave)
- goto done;
+ if (!bond->first_slave) {
+ /* Disable adding VLANs to empty bond. But why? --mq */
+ features |= NETIF_F_VLAN_CHALLENGED;
+ goto out;
+ }
+ mask = features;
features &= ~NETIF_F_ONE_FOR_ALL;
+ features |= NETIF_F_ALL_FOR_ALL;
- vlan_features = bond->first_slave->dev->vlan_features;
bond_for_each_slave(bond, slave, i) {
features = netdev_increment_features(features,
slave->dev->features,
- NETIF_F_ONE_FOR_ALL);
+ mask);
+ }
+
+out:
+ read_unlock(&bond->lock);
+ return features;
+}
+
+#define BOND_VLAN_FEATURES (NETIF_F_ALL_TX_OFFLOADS | \
+ NETIF_F_SOFT_FEATURES | \
+ NETIF_F_LRO)
+
+static void bond_compute_features(struct bonding *bond)
+{
+ struct slave *slave;
+ struct net_device *bond_dev = bond->dev;
+ u32 vlan_features = BOND_VLAN_FEATURES;
+ unsigned short max_hard_header_len = ETH_HLEN;
+ int i;
+
+ read_lock(&bond->lock);
+
+ if (!bond->first_slave)
+ goto done;
+
+ bond_for_each_slave(bond, slave, i) {
vlan_features = netdev_increment_features(vlan_features,
- slave->dev->vlan_features,
- NETIF_F_ONE_FOR_ALL);
+ slave->dev->vlan_features, BOND_VLAN_FEATURES);
+
if (slave->dev->hard_header_len > max_hard_header_len)
max_hard_header_len = slave->dev->hard_header_len;
}
done:
- features |= (bond_dev->features & BOND_VLAN_FEATURES);
- bond_dev->features = netdev_fix_features(bond_dev, features);
- bond_dev->vlan_features = netdev_fix_features(bond_dev, vlan_features);
+ bond_dev->vlan_features = vlan_features;
bond_dev->hard_header_len = max_hard_header_len;
- return 0;
+ read_unlock(&bond->lock);
+
+ netdev_change_features(bond_dev);
}
static void bond_setup_by_slave(struct net_device *bond_dev,
@@ -1452,27 +1461,17 @@ static void bond_setup_by_slave(struct net_device *bond_dev,
}
/* On bonding slaves other than the currently active slave, suppress
- * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and
- * ARP on active-backup slaves with arp_validate enabled.
+ * duplicates except for alb non-mcast/bcast.
*/
static bool bond_should_deliver_exact_match(struct sk_buff *skb,
struct slave *slave,
struct bonding *bond)
{
if (bond_is_slave_inactive(slave)) {
- if (slave_do_arp_validate(bond, slave) &&
- skb->protocol == __cpu_to_be16(ETH_P_ARP))
- return false;
-
if (bond->params.mode == BOND_MODE_ALB &&
skb->pkt_type != PACKET_BROADCAST &&
skb->pkt_type != PACKET_MULTICAST)
- return false;
-
- if (bond->params.mode == BOND_MODE_8023AD &&
- skb->protocol == __cpu_to_be16(ETH_P_SLOW))
return false;
-
return true;
}
return false;
@@ -1496,6 +1495,15 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
if (bond->params.arp_interval)
slave->dev->last_rx = jiffies;
+ if (bond->recv_probe) {
+ struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
+
+ if (likely(nskb)) {
+ bond->recv_probe(nskb, bond, slave);
+ dev_kfree_skb(nskb);
+ }
+ }
+
if (bond_should_deliver_exact_match(skb, slave, bond)) {
return RX_HANDLER_EXACT;
}
@@ -1526,7 +1534,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
struct netdev_hw_addr *ha;
struct sockaddr addr;
int link_reporting;
- int old_features = bond_dev->features;
int res = 0;
if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&
@@ -1559,16 +1566,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
pr_warning("%s: Warning: enslaved VLAN challenged slave %s. Adding VLANs will be blocked as long as %s is part of bond %s\n",
bond_dev->name, slave_dev->name,
slave_dev->name, bond_dev->name);
- bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
}
} else {
pr_debug("%s: ! NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
- if (bond->slave_cnt == 0) {
- /* First slave, and it is not VLAN challenged,
- * so remove the block of adding VLANs over the bond.
- */
- bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED;
- }
}
/*
@@ -1757,10 +1757,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
new_slave->delay = 0;
new_slave->link_failure_count = 0;
- bond_compute_features(bond);
-
write_unlock_bh(&bond->lock);
+ bond_compute_features(bond);
+
read_lock(&bond->lock);
new_slave->last_arp_rx = jiffies;
@@ -1940,7 +1940,7 @@ err_free:
kfree(new_slave);
err_undo_flags:
- bond_dev->features = old_features;
+ bond_compute_features(bond);
return res;
}
@@ -1961,6 +1961,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave, *oldcurrent;
struct sockaddr addr;
+ u32 old_features = bond_dev->features;
/* slave is not a slave or master is not master of this slave */
if (!(slave_dev->flags & IFF_SLAVE) ||
@@ -2021,8 +2022,6 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
/* release the slave from its bond */
bond_detach_slave(bond, slave);
- bond_compute_features(bond);
-
if (bond->primary_slave == slave)
bond->primary_slave = NULL;
@@ -2066,24 +2065,23 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
*/
memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
- if (!bond->vlgrp) {
- bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
- } else {
+ if (bond->vlgrp) {
pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
bond_dev->name, bond_dev->name);
pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n",
bond_dev->name);
}
- } else if ((bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
- !bond_has_challenged_slaves(bond)) {
- pr_info("%s: last VLAN challenged slave %s left bond %s. VLAN blocking is removed\n",
- bond_dev->name, slave_dev->name, bond_dev->name);
- bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED;
}
write_unlock_bh(&bond->lock);
unblock_netpoll_tx();
+ bond_compute_features(bond);
+ if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
+ (old_features & NETIF_F_VLAN_CHALLENGED))
+ pr_info("%s: last VLAN challenged slave %s left bond %s. VLAN blocking is removed\n",
+ bond_dev->name, slave_dev->name, bond_dev->name);
+
/* must do this from outside any spinlocks */
bond_destroy_slave_symlinks(bond_dev, slave_dev);
@@ -2201,8 +2199,6 @@ static int bond_release_all(struct net_device *bond_dev)
bond_alb_deinit_slave(bond, slave);
}
- bond_compute_features(bond);
-
bond_destroy_slave_symlinks(bond_dev, slave_dev);
bond_del_vlans_from_slave(bond, slave_dev);
@@ -2251,9 +2247,7 @@ static int bond_release_all(struct net_device *bond_dev)
*/
memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
- if (!bond->vlgrp) {
- bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
- } else {
+ if (bond->vlgrp) {
pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
bond_dev->name, bond_dev->name);
pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n",
@@ -2264,6 +2258,9 @@ static int bond_release_all(struct net_device *bond_dev)
out:
write_unlock_bh(&bond->lock);
+
+ bond_compute_features(bond);
+
return 0;
}
@@ -2493,7 +2490,7 @@ static void bond_miimon_commit(struct bonding *bond)
bond_update_speed_duplex(slave);
- pr_info("%s: link status definitely up for interface %s, %d Mbps %s duplex.\n",
+ pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n",
bond->dev->name, slave->dev->name,
slave->speed, slave->duplex ? "full" : "half");
@@ -2570,6 +2567,7 @@ void bond_mii_monitor(struct work_struct *work)
{
struct bonding *bond = container_of(work, struct bonding,
mii_work.work);
+ bool should_notify_peers = false;
read_lock(&bond->lock);
if (bond->kill_timers)
@@ -2578,17 +2576,7 @@ void bond_mii_monitor(struct work_struct *work)
if (bond->slave_cnt == 0)
goto re_arm;
- if (bond->send_grat_arp) {
- read_lock(&bond->curr_slave_lock);
- bond_send_gratuitous_arp(bond);
- read_unlock(&bond->curr_slave_lock);
- }
-
- if (bond->send_unsol_na) {
- read_lock(&bond->curr_slave_lock);
- bond_send_unsolicited_na(bond);
- read_unlock(&bond->curr_slave_lock);
- }
+ should_notify_peers = bond_should_notify_peers(bond);
if (bond_miimon_inspect(bond)) {
read_unlock(&bond->lock);
@@ -2608,6 +2596,12 @@ re_arm:
msecs_to_jiffies(bond->params.miimon));
out:
read_unlock(&bond->lock);
+
+ if (should_notify_peers) {
+ rtnl_lock();
+ netdev_bonding_change(bond->dev, NETDEV_NOTIFY_PEERS);
+ rtnl_unlock();
+ }
}
static __be32 bond_glean_dev_ip(struct net_device *dev)
@@ -2751,44 +2745,6 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
}
}
-/*
- * Kick out a gratuitous ARP for an IP on the bonding master plus one
- * for each VLAN above us.
- *
- * Caller must hold curr_slave_lock for read or better
- */
-static void bond_send_gratuitous_arp(struct bonding *bond)
-{
- struct slave *slave = bond->curr_active_slave;
- struct vlan_entry *vlan;
- struct net_device *vlan_dev;
-
- pr_debug("bond_send_grat_arp: bond %s slave %s\n",
- bond->dev->name, slave ? slave->dev->name : "NULL");
-
- if (!slave || !bond->send_grat_arp ||
- test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
- return;
-
- bond->send_grat_arp--;
-
- if (bond->master_ip) {
- bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip,
- bond->master_ip, 0);
- }
-
- if (!bond->vlgrp)
- return;
-
- list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
- vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
- if (vlan->vlan_ip) {
- bond_arp_send(slave->dev, ARPOP_REPLY, vlan->vlan_ip,
- vlan->vlan_ip, vlan->vlan_id);
- }
- }
-}
-
static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 sip, __be32 tip)
{
int i;
@@ -2806,48 +2762,26 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32
}
}
-static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
+static void bond_arp_rcv(struct sk_buff *skb, struct bonding *bond,
+ struct slave *slave)
{
struct arphdr *arp;
- struct slave *slave;
- struct bonding *bond;
unsigned char *arp_ptr;
__be32 sip, tip;
- if (dev->priv_flags & IFF_802_1Q_VLAN) {
- /*
- * When using VLANS and bonding, dev and oriv_dev may be
- * incorrect if the physical interface supports VLAN
- * acceleration. With this change ARP validation now
- * works for hosts only reachable on the VLAN interface.
- */
- dev = vlan_dev_real_dev(dev);
- orig_dev = dev_get_by_index_rcu(dev_net(skb->dev),skb->skb_iif);
- }
-
- if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER))
- goto out;
+ if (skb->protocol != __cpu_to_be16(ETH_P_ARP))
+ return;
- bond = netdev_priv(dev);
read_lock(&bond->lock);
- pr_debug("bond_arp_rcv: bond %s skb->dev %s orig_dev %s\n",
- bond->dev->name, skb->dev ? skb->dev->name : "NULL",
- orig_dev ? orig_dev->name : "NULL");
-
- slave = bond_get_slave_by_dev(bond, orig_dev);
- if (!slave || !slave_do_arp_validate(bond, slave))
- goto out_unlock;
-
- skb = skb_share_check(skb, GFP_ATOMIC);
- if (!skb)
- goto out_unlock;
+ pr_debug("bond_arp_rcv: bond %s skb->dev %s\n",
+ bond->dev->name, skb->dev->name);
- if (!pskb_may_pull(skb, arp_hdr_len(dev)))
+ if (!pskb_may_pull(skb, arp_hdr_len(bond->dev)))
goto out_unlock;
arp = arp_hdr(skb);
- if (arp->ar_hln != dev->addr_len ||
+ if (arp->ar_hln != bond->dev->addr_len ||
skb->pkt_type == PACKET_OTHERHOST ||
skb->pkt_type == PACKET_LOOPBACK ||
arp->ar_hrd != htons(ARPHRD_ETHER) ||
@@ -2856,9 +2790,9 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack
goto out_unlock;
arp_ptr = (unsigned char *)(arp + 1);
- arp_ptr += dev->addr_len;
+ arp_ptr += bond->dev->addr_len;
memcpy(&sip, arp_ptr, 4);
- arp_ptr += 4 + dev->addr_len;
+ arp_ptr += 4 + bond->dev->addr_len;
memcpy(&tip, arp_ptr, 4);
pr_debug("bond_arp_rcv: %s %s/%d av %d sv %d sip %pI4 tip %pI4\n",
@@ -2881,9 +2815,6 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack
out_unlock:
read_unlock(&bond->lock);
-out:
- dev_kfree_skb(skb);
- return NET_RX_SUCCESS;
}
/*
@@ -3243,6 +3174,7 @@ void bond_activebackup_arp_mon(struct work_struct *work)
{
struct bonding *bond = container_of(work, struct bonding,
arp_work.work);
+ bool should_notify_peers = false;
int delta_in_ticks;
read_lock(&bond->lock);
@@ -3255,17 +3187,7 @@ void bond_activebackup_arp_mon(struct work_struct *work)
if (bond->slave_cnt == 0)
goto re_arm;
- if (bond->send_grat_arp) {
- read_lock(&bond->curr_slave_lock);
- bond_send_gratuitous_arp(bond);
- read_unlock(&bond->curr_slave_lock);
- }
-
- if (bond->send_unsol_na) {
- read_lock(&bond->curr_slave_lock);
- bond_send_unsolicited_na(bond);
- read_unlock(&bond->curr_slave_lock);
- }
+ should_notify_peers = bond_should_notify_peers(bond);
if (bond_ab_arp_inspect(bond, delta_in_ticks)) {
read_unlock(&bond->lock);
@@ -3286,6 +3208,12 @@ re_arm:
queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
out:
read_unlock(&bond->lock);
+
+ if (should_notify_peers) {
+ rtnl_lock();
+ netdev_bonding_change(bond->dev, NETDEV_NOTIFY_PEERS);
+ rtnl_unlock();
+ }
}
/*-------------------------- netdev event handling --------------------------*/
@@ -3339,8 +3267,8 @@ static int bond_slave_netdev_event(unsigned long event,
slave = bond_get_slave_by_dev(bond, slave_dev);
if (slave) {
- u16 old_speed = slave->speed;
- u16 old_duplex = slave->duplex;
+ u32 old_speed = slave->speed;
+ u8 old_duplex = slave->duplex;
bond_update_speed_duplex(slave);
@@ -3482,48 +3410,6 @@ static struct notifier_block bond_inetaddr_notifier = {
.notifier_call = bond_inetaddr_event,
};
-/*-------------------------- Packet type handling ---------------------------*/
-
-/* register to receive lacpdus on a bond */
-static void bond_register_lacpdu(struct bonding *bond)
-{
- struct packet_type *pk_type = &(BOND_AD_INFO(bond).ad_pkt_type);
-
- /* initialize packet type */
- pk_type->type = PKT_TYPE_LACPDU;
- pk_type->dev = bond->dev;
- pk_type->func = bond_3ad_lacpdu_recv;
-
- dev_add_pack(pk_type);
-}
-
-/* unregister to receive lacpdus on a bond */
-static void bond_unregister_lacpdu(struct bonding *bond)
-{
- dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type));
-}
-
-void bond_register_arp(struct bonding *bond)
-{
- struct packet_type *pt = &bond->arp_mon_pt;
-
- if (pt->type)
- return;
-
- pt->type = htons(ETH_P_ARP);
- pt->dev = bond->dev;
- pt->func = bond_arp_rcv;
- dev_add_pack(pt);
-}
-
-void bond_unregister_arp(struct bonding *bond)
-{
- struct packet_type *pt = &bond->arp_mon_pt;
-
- dev_remove_pack(pt);
- pt->type = 0;
-}
-
/*---------------------------- Hashing Policies -----------------------------*/
/*
@@ -3617,14 +3503,14 @@ static int bond_open(struct net_device *bond_dev)
queue_delayed_work(bond->wq, &bond->arp_work, 0);
if (bond->params.arp_validate)
- bond_register_arp(bond);
+ bond->recv_probe = bond_arp_rcv;
}
if (bond->params.mode == BOND_MODE_8023AD) {
INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
queue_delayed_work(bond->wq, &bond->ad_work, 0);
/* register to receive LACPDUs */
- bond_register_lacpdu(bond);
+ bond->recv_probe = bond_3ad_lacpdu_recv;
bond_3ad_initiate_agg_selection(bond, 1);
}
@@ -3635,18 +3521,9 @@ static int bond_close(struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
- if (bond->params.mode == BOND_MODE_8023AD) {
- /* Unregister the receive of LACPDUs */
- bond_unregister_lacpdu(bond);
- }
-
- if (bond->params.arp_validate)
- bond_unregister_arp(bond);
-
write_lock_bh(&bond->lock);
- bond->send_grat_arp = 0;
- bond->send_unsol_na = 0;
+ bond->send_peer_notif = 0;
/* signal timers not to re-arm */
bond->kill_timers = 1;
@@ -3682,6 +3559,7 @@ static int bond_close(struct net_device *bond_dev)
*/
bond_alb_deinitialize(bond);
}
+ bond->recv_probe = NULL;
return 0;
}
@@ -4105,10 +3983,6 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
int i, slave_no, res = 1;
struct iphdr *iph = ip_hdr(skb);
- read_lock(&bond->lock);
-
- if (!BOND_IS_OK(bond))
- goto out;
/*
* Start with the curr_active_slave that joined the bond as the
* default for sending IGMP traffic. For failover purposes one
@@ -4155,7 +4029,7 @@ out:
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
}
- read_unlock(&bond->lock);
+
return NETDEV_TX_OK;
}
@@ -4169,24 +4043,18 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
struct bonding *bond = netdev_priv(bond_dev);
int res = 1;
- read_lock(&bond->lock);
read_lock(&bond->curr_slave_lock);
- if (!BOND_IS_OK(bond))
- goto out;
-
- if (!bond->curr_active_slave)
- goto out;
+ if (bond->curr_active_slave)
+ res = bond_dev_queue_xmit(bond, skb,
+ bond->curr_active_slave->dev);
- res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
-
-out:
if (res)
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
read_unlock(&bond->curr_slave_lock);
- read_unlock(&bond->lock);
+
return NETDEV_TX_OK;
}
@@ -4203,11 +4071,6 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
int i;
int res = 1;
- read_lock(&bond->lock);
-
- if (!BOND_IS_OK(bond))
- goto out;
-
slave_no = bond->xmit_hash_policy(skb, bond->slave_cnt);
bond_for_each_slave(bond, slave, i) {
@@ -4227,12 +4090,11 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
}
}
-out:
if (res) {
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
}
- read_unlock(&bond->lock);
+
return NETDEV_TX_OK;
}
@@ -4247,11 +4109,6 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
int i;
int res = 1;
- read_lock(&bond->lock);
-
- if (!BOND_IS_OK(bond))
- goto out;
-
read_lock(&bond->curr_slave_lock);
start_at = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
@@ -4290,7 +4147,6 @@ out:
dev_kfree_skb(skb);
/* frame sent to all suitable interfaces */
- read_unlock(&bond->lock);
return NETDEV_TX_OK;
}
@@ -4322,10 +4178,8 @@ static inline int bond_slave_override(struct bonding *bond,
struct slave *slave = NULL;
struct slave *check_slave;
- read_lock(&bond->lock);
-
- if (!BOND_IS_OK(bond) || !skb->queue_mapping)
- goto out;
+ if (!skb->queue_mapping)
+ return 1;
/* Find out if any slaves have the same mapping as this skb. */
bond_for_each_slave(bond, check_slave, i) {
@@ -4341,8 +4195,6 @@ static inline int bond_slave_override(struct bonding *bond,
res = bond_dev_queue_xmit(bond, skb, slave->dev);
}
-out:
- read_unlock(&bond->lock);
return res;
}
@@ -4357,24 +4209,17 @@ static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb)
u16 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
if (unlikely(txq >= dev->real_num_tx_queues)) {
- do
+ do {
txq -= dev->real_num_tx_queues;
- while (txq >= dev->real_num_tx_queues);
+ } while (txq >= dev->real_num_tx_queues);
}
return txq;
}
-static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct bonding *bond = netdev_priv(dev);
- /*
- * If we risk deadlock from transmitting this in the
- * netpoll path, tell netpoll to queue the frame for later tx
- */
- if (is_netpoll_tx_blocked(dev))
- return NETDEV_TX_BUSY;
-
if (TX_QUEUE_OVERRIDE(bond->params.mode)) {
if (!bond_slave_override(bond, skb))
return NETDEV_TX_OK;
@@ -4404,6 +4249,29 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
+static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct bonding *bond = netdev_priv(dev);
+ netdev_tx_t ret = NETDEV_TX_OK;
+
+ /*
+ * If we risk deadlock from transmitting this in the
+ * netpoll path, tell netpoll to queue the frame for later tx
+ */
+ if (is_netpoll_tx_blocked(dev))
+ return NETDEV_TX_BUSY;
+
+ read_lock(&bond->lock);
+
+ if (bond->slave_cnt)
+ ret = __bond_start_xmit(skb, dev);
+ else
+ dev_kfree_skb(skb);
+
+ read_unlock(&bond->lock);
+
+ return ret;
+}
/*
* set bond mode specific net device operations
@@ -4448,11 +4316,6 @@ static void bond_ethtool_get_drvinfo(struct net_device *bond_dev,
static const struct ethtool_ops bond_ethtool_ops = {
.get_drvinfo = bond_ethtool_get_drvinfo,
.get_link = ethtool_op_get_link,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .get_tso = ethtool_op_get_tso,
- .get_ufo = ethtool_op_get_ufo,
- .get_flags = ethtool_op_get_flags,
};
static const struct net_device_ops bond_netdev_ops = {
@@ -4478,6 +4341,7 @@ static const struct net_device_ops bond_netdev_ops = {
#endif
.ndo_add_slave = bond_enslave,
.ndo_del_slave = bond_release,
+ .ndo_fix_features = bond_fix_features,
};
static void bond_destructor(struct net_device *bond_dev)
@@ -4533,14 +4397,14 @@ static void bond_setup(struct net_device *bond_dev)
* when there are slaves that are not hw accel
* capable
*/
- bond_dev->features |= (NETIF_F_HW_VLAN_TX |
- NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_FILTER);
- /* By default, we enable GRO on bonding devices.
- * Actual support requires lowlevel drivers are GRO ready.
- */
- bond_dev->features |= NETIF_F_GRO;
+ bond_dev->hw_features = BOND_VLAN_FEATURES |
+ NETIF_F_HW_VLAN_TX |
+ NETIF_F_HW_VLAN_RX |
+ NETIF_F_HW_VLAN_FILTER;
+
+ bond_dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_NO_CSUM);
+ bond_dev->features |= bond_dev->hw_features;
}
static void bond_work_cancel_all(struct bonding *bond)
@@ -4724,16 +4588,10 @@ static int bond_check_params(struct bond_params *params)
use_carrier = 1;
}
- if (num_grat_arp < 0 || num_grat_arp > 255) {
- pr_warning("Warning: num_grat_arp (%d) not in range 0-255 so it was reset to 1\n",
- num_grat_arp);
- num_grat_arp = 1;
- }
-
- if (num_unsol_na < 0 || num_unsol_na > 255) {
- pr_warning("Warning: num_unsol_na (%d) not in range 0-255 so it was reset to 1\n",
- num_unsol_na);
- num_unsol_na = 1;
+ if (num_peer_notif < 0 || num_peer_notif > 255) {
+ pr_warning("Warning: num_grat_arp/num_unsol_na (%d) not in range 0-255 so it was reset to 1\n",
+ num_peer_notif);
+ num_peer_notif = 1;
}
/* reset values for 802.3ad */
@@ -4925,8 +4783,7 @@ static int bond_check_params(struct bond_params *params)
params->mode = bond_mode;
params->xmit_policy = xmit_hashtype;
params->miimon = miimon;
- params->num_grat_arp = num_grat_arp;
- params->num_unsol_na = num_unsol_na;
+ params->num_peer_notif = num_peer_notif;
params->arp_interval = arp_interval;
params->arp_validate = arp_validate_value;
params->updelay = updelay;
@@ -5025,8 +4882,9 @@ int bond_create(struct net *net, const char *name)
rtnl_lock();
- bond_dev = alloc_netdev_mq(sizeof(struct bonding), name ? name : "",
- bond_setup, tx_queues);
+ bond_dev = alloc_netdev_mq(sizeof(struct bonding),
+ name ? name : "bond%d",
+ bond_setup, tx_queues);
if (!bond_dev) {
pr_err("%s: eek! can't alloc netdev!\n", name);
rtnl_unlock();
@@ -5036,26 +4894,10 @@ int bond_create(struct net *net, const char *name)
dev_net_set(bond_dev, net);
bond_dev->rtnl_link_ops = &bond_link_ops;
- if (!name) {
- res = dev_alloc_name(bond_dev, "bond%d");
- if (res < 0)
- goto out;
- } else {
- /*
- * If we're given a name to register
- * we need to ensure that its not already
- * registered
- */
- res = -EEXIST;
- if (__dev_get_by_name(net, name) != NULL)
- goto out;
- }
-
res = register_netdevice(bond_dev);
netif_carrier_off(bond_dev);
-out:
rtnl_unlock();
if (res < 0)
bond_destructor(bond_dev);
@@ -5121,7 +4963,6 @@ static int __init bonding_init(void)
register_netdevice_notifier(&bond_netdev_notifier);
register_inetaddr_notifier(&bond_inetaddr_notifier);
- bond_register_ipv6_notifier();
out:
return res;
err:
@@ -5136,7 +4977,6 @@ static void __exit bonding_exit(void)
{
unregister_netdevice_notifier(&bond_netdev_notifier);
unregister_inetaddr_notifier(&bond_inetaddr_notifier);
- bond_unregister_ipv6_notifier();
bond_destroy_sysfs();
bond_destroy_debugfs();
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
index c32ff55a34c..c97307ddd1c 100644
--- a/drivers/net/bonding/bond_procfs.c
+++ b/drivers/net/bonding/bond_procfs.c
@@ -4,8 +4,6 @@
#include "bonding.h"
-extern const char *bond_mode_name(int mode);
-
static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(RCU)
__acquires(&bond->lock)
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index de87aea6d01..4059bfc73db 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -422,11 +422,6 @@ static ssize_t bonding_store_arp_validate(struct device *d,
bond->dev->name, arp_validate_tbl[new_value].modename,
new_value);
- if (!bond->params.arp_validate && new_value)
- bond_register_arp(bond);
- else if (bond->params.arp_validate && !new_value)
- bond_unregister_arp(bond);
-
bond->params.arp_validate = new_value;
return count;
@@ -874,82 +869,28 @@ static DEVICE_ATTR(ad_select, S_IRUGO | S_IWUSR,
bonding_show_ad_select, bonding_store_ad_select);
/*
- * Show and set the number of grat ARP to send after a failover event.
+ * Show and set the number of peer notifications to send after a failover event.
*/
-static ssize_t bonding_show_n_grat_arp(struct device *d,
- struct device_attribute *attr,
- char *buf)
+static ssize_t bonding_show_num_peer_notif(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
{
struct bonding *bond = to_bond(d);
-
- return sprintf(buf, "%d\n", bond->params.num_grat_arp);
+ return sprintf(buf, "%d\n", bond->params.num_peer_notif);
}
-static ssize_t bonding_store_n_grat_arp(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t bonding_store_num_peer_notif(struct device *d,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- int new_value, ret = count;
struct bonding *bond = to_bond(d);
-
- if (sscanf(buf, "%d", &new_value) != 1) {
- pr_err("%s: no num_grat_arp value specified.\n",
- bond->dev->name);
- ret = -EINVAL;
- goto out;
- }
- if (new_value < 0 || new_value > 255) {
- pr_err("%s: Invalid num_grat_arp value %d not in range 0-255; rejected.\n",
- bond->dev->name, new_value);
- ret = -EINVAL;
- goto out;
- } else {
- bond->params.num_grat_arp = new_value;
- }
-out:
- return ret;
+ int err = kstrtou8(buf, 10, &bond->params.num_peer_notif);
+ return err ? err : count;
}
static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR,
- bonding_show_n_grat_arp, bonding_store_n_grat_arp);
-
-/*
- * Show and set the number of unsolicited NA's to send after a failover event.
- */
-static ssize_t bonding_show_n_unsol_na(struct device *d,
- struct device_attribute *attr,
- char *buf)
-{
- struct bonding *bond = to_bond(d);
-
- return sprintf(buf, "%d\n", bond->params.num_unsol_na);
-}
-
-static ssize_t bonding_store_n_unsol_na(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int new_value, ret = count;
- struct bonding *bond = to_bond(d);
-
- if (sscanf(buf, "%d", &new_value) != 1) {
- pr_err("%s: no num_unsol_na value specified.\n",
- bond->dev->name);
- ret = -EINVAL;
- goto out;
- }
-
- if (new_value < 0 || new_value > 255) {
- pr_err("%s: Invalid num_unsol_na value %d not in range 0-255; rejected.\n",
- bond->dev->name, new_value);
- ret = -EINVAL;
- goto out;
- } else
- bond->params.num_unsol_na = new_value;
-out:
- return ret;
-}
+ bonding_show_num_peer_notif, bonding_store_num_peer_notif);
static DEVICE_ATTR(num_unsol_na, S_IRUGO | S_IWUSR,
- bonding_show_n_unsol_na, bonding_store_n_unsol_na);
+ bonding_show_num_peer_notif, bonding_store_num_peer_notif);
/*
* Show and set the MII monitor interval. There are two tricky bits
@@ -1001,7 +942,6 @@ static ssize_t bonding_store_miimon(struct device *d,
bond->dev->name);
bond->params.arp_interval = 0;
if (bond->params.arp_validate) {
- bond_unregister_arp(bond);
bond->params.arp_validate =
BOND_ARP_VALIDATE_NONE;
}
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 90736cb4d97..ea1d005be92 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -24,8 +24,8 @@
#include "bond_3ad.h"
#include "bond_alb.h"
-#define DRV_VERSION "3.7.0"
-#define DRV_RELDATE "June 2, 2010"
+#define DRV_VERSION "3.7.1"
+#define DRV_RELDATE "April 27, 2011"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
@@ -39,16 +39,6 @@
netif_carrier_ok(dev))
/*
- * Checks whether bond is ready for transmit.
- *
- * Caller must hold bond->lock
- */
-#define BOND_IS_OK(bond) \
- (((bond)->dev->flags & IFF_UP) && \
- netif_running((bond)->dev) && \
- ((bond)->slave_cnt > 0))
-
-/*
* Checks whether slave is ready for transmit.
*/
#define SLAVE_IS_OK(slave) \
@@ -149,8 +139,7 @@ struct bond_params {
int mode;
int xmit_policy;
int miimon;
- int num_grat_arp;
- int num_unsol_na;
+ u8 num_peer_notif;
int arp_interval;
int arp_validate;
int use_carrier;
@@ -178,9 +167,6 @@ struct vlan_entry {
struct list_head vlan_list;
__be32 vlan_ip;
unsigned short vlan_id;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
- struct in6_addr vlan_ipv6;
-#endif
};
struct slave {
@@ -196,12 +182,12 @@ struct slave {
u8 backup:1, /* indicates backup slave. Value corresponds with
BOND_STATE_ACTIVE and BOND_STATE_BACKUP */
inactive:1; /* indicates inactive slave */
+ u8 duplex;
u32 original_mtu;
u32 link_failure_count;
- u8 perm_hwaddr[ETH_ALEN];
- u16 speed;
- u8 duplex;
+ u32 speed;
u16 queue_id;
+ u8 perm_hwaddr[ETH_ALEN];
struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */
struct tlb_slave_info tlb_info;
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -231,11 +217,12 @@ struct bonding {
struct slave *primary_slave;
bool force_primary;
s32 slave_cnt; /* never change this value outside the attach/detach wrappers */
+ void (*recv_probe)(struct sk_buff *, struct bonding *,
+ struct slave *);
rwlock_t lock;
rwlock_t curr_slave_lock;
s8 kill_timers;
- s8 send_grat_arp;
- s8 send_unsol_na;
+ u8 send_peer_notif;
s8 setup_by_slave;
s8 igmp_retrans;
#ifdef CONFIG_PROC_FS
@@ -260,9 +247,6 @@ struct bonding {
struct delayed_work alb_work;
struct delayed_work ad_work;
struct delayed_work mcast_work;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
- struct in6_addr master_ipv6;
-#endif
#ifdef CONFIG_DEBUG_FS
/* debugging suport via debugfs */
struct dentry *debug_dir;
@@ -409,13 +393,12 @@ void bond_set_mode_ops(struct bonding *bond, int mode);
int bond_parse_parm(const char *mode_arg, const struct bond_parm_tbl *tbl);
void bond_select_active_slave(struct bonding *bond);
void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
-void bond_register_arp(struct bonding *);
-void bond_unregister_arp(struct bonding *);
void bond_create_debugfs(void);
void bond_destroy_debugfs(void);
void bond_debug_register(struct bonding *bond);
void bond_debug_unregister(struct bonding *bond);
void bond_debug_reregister(struct bonding *bond);
+const char *bond_mode_name(int mode);
struct bond_net {
struct net * net; /* Associated network namespace */
@@ -459,23 +442,4 @@ extern const struct bond_parm_tbl fail_over_mac_tbl[];
extern const struct bond_parm_tbl pri_reselect_tbl[];
extern struct bond_parm_tbl ad_select_tbl[];
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-void bond_send_unsolicited_na(struct bonding *bond);
-void bond_register_ipv6_notifier(void);
-void bond_unregister_ipv6_notifier(void);
-#else
-static inline void bond_send_unsolicited_na(struct bonding *bond)
-{
- return;
-}
-static inline void bond_register_ipv6_notifier(void)
-{
- return;
-}
-static inline void bond_unregister_ipv6_notifier(void)
-{
- return;
-}
-#endif
-
#endif /* _LINUX_BONDING_H */
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 143a28c666a..22ce03e55b8 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -709,10 +709,11 @@ static void cas_begin_auto_negotiation(struct cas *cp, struct ethtool_cmd *ep)
if (ep->autoneg == AUTONEG_ENABLE)
cp->link_cntl = BMCR_ANENABLE;
else {
+ u32 speed = ethtool_cmd_speed(ep);
cp->link_cntl = 0;
- if (ep->speed == SPEED_100)
+ if (speed == SPEED_100)
cp->link_cntl |= BMCR_SPEED100;
- else if (ep->speed == SPEED_1000)
+ else if (speed == SPEED_1000)
cp->link_cntl |= CAS_BMCR_SPEED1000;
if (ep->duplex == DUPLEX_FULL)
cp->link_cntl |= BMCR_FULLDPLX;
@@ -4605,18 +4606,17 @@ static int cas_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if (bmcr & BMCR_ANENABLE) {
cmd->advertising |= ADVERTISED_Autoneg;
cmd->autoneg = AUTONEG_ENABLE;
- cmd->speed = ((speed == 10) ?
- SPEED_10 :
- ((speed == 1000) ?
- SPEED_1000 : SPEED_100));
+ ethtool_cmd_speed_set(cmd, ((speed == 10) ?
+ SPEED_10 :
+ ((speed == 1000) ?
+ SPEED_1000 : SPEED_100)));
cmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
} else {
cmd->autoneg = AUTONEG_DISABLE;
- cmd->speed =
- (bmcr & CAS_BMCR_SPEED1000) ?
- SPEED_1000 :
- ((bmcr & BMCR_SPEED100) ? SPEED_100:
- SPEED_10);
+ ethtool_cmd_speed_set(cmd, ((bmcr & CAS_BMCR_SPEED1000) ?
+ SPEED_1000 :
+ ((bmcr & BMCR_SPEED100) ?
+ SPEED_100 : SPEED_10)));
cmd->duplex =
(bmcr & BMCR_FULLDPLX) ?
DUPLEX_FULL : DUPLEX_HALF;
@@ -4633,14 +4633,14 @@ static int cas_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
* settings that we configured.
*/
if (cp->link_cntl & BMCR_ANENABLE) {
- cmd->speed = 0;
+ ethtool_cmd_speed_set(cmd, 0);
cmd->duplex = 0xff;
} else {
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
if (cp->link_cntl & BMCR_SPEED100) {
- cmd->speed = SPEED_100;
+ ethtool_cmd_speed_set(cmd, SPEED_100);
} else if (cp->link_cntl & CAS_BMCR_SPEED1000) {
- cmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(cmd, SPEED_1000);
}
cmd->duplex = (cp->link_cntl & BMCR_FULLDPLX)?
DUPLEX_FULL : DUPLEX_HALF;
@@ -4653,6 +4653,7 @@ static int cas_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct cas *cp = netdev_priv(dev);
unsigned long flags;
+ u32 speed = ethtool_cmd_speed(cmd);
/* Verify the settings we care about. */
if (cmd->autoneg != AUTONEG_ENABLE &&
@@ -4660,9 +4661,9 @@ static int cas_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return -EINVAL;
if (cmd->autoneg == AUTONEG_DISABLE &&
- ((cmd->speed != SPEED_1000 &&
- cmd->speed != SPEED_100 &&
- cmd->speed != SPEED_10) ||
+ ((speed != SPEED_1000 &&
+ speed != SPEED_100 &&
+ speed != SPEED_10) ||
(cmd->duplex != DUPLEX_HALF &&
cmd->duplex != DUPLEX_FULL)))
return -EINVAL;
diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h
index 092f31a126e..c26d863e169 100644
--- a/drivers/net/chelsio/common.h
+++ b/drivers/net/chelsio/common.h
@@ -264,11 +264,6 @@ struct adapter {
enum { /* adapter flags */
FULL_INIT_DONE = 1 << 0,
- TSO_CAPABLE = 1 << 2,
- TCP_CSUM_CAPABLE = 1 << 3,
- UDP_CSUM_CAPABLE = 1 << 4,
- VLAN_ACCEL_CAPABLE = 1 << 5,
- RX_CSUM_ENABLED = 1 << 6,
};
struct mdio_ops;
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index 0f71304e054..b422d83f534 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -192,10 +192,8 @@ static void link_start(struct port_info *p)
static void enable_hw_csum(struct adapter *adapter)
{
- if (adapter->flags & TSO_CAPABLE)
+ if (adapter->port[0].dev->hw_features & NETIF_F_TSO)
t1_tp_set_ip_checksum_offload(adapter->tp, 1); /* for TSO only */
- if (adapter->flags & UDP_CSUM_CAPABLE)
- t1_tp_set_udp_checksum_offload(adapter->tp, 1);
t1_tp_set_tcp_checksum_offload(adapter->tp, 1);
}
@@ -579,10 +577,10 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->advertising = p->link_config.advertising;
if (netif_carrier_ok(dev)) {
- cmd->speed = p->link_config.speed;
+ ethtool_cmd_speed_set(cmd, p->link_config.speed);
cmd->duplex = p->link_config.duplex;
} else {
- cmd->speed = -1;
+ ethtool_cmd_speed_set(cmd, -1);
cmd->duplex = -1;
}
@@ -640,11 +638,12 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return -EOPNOTSUPP; /* can't change speed/duplex */
if (cmd->autoneg == AUTONEG_DISABLE) {
- int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
+ u32 speed = ethtool_cmd_speed(cmd);
+ int cap = speed_duplex_to_caps(speed, cmd->duplex);
- if (!(lc->supported & cap) || cmd->speed == SPEED_1000)
+ if (!(lc->supported & cap) || (speed == SPEED_1000))
return -EINVAL;
- lc->requested_speed = cmd->speed;
+ lc->requested_speed = speed;
lc->requested_duplex = cmd->duplex;
lc->advertising = 0;
} else {
@@ -705,33 +704,6 @@ static int set_pauseparam(struct net_device *dev,
return 0;
}
-static u32 get_rx_csum(struct net_device *dev)
-{
- struct adapter *adapter = dev->ml_priv;
-
- return (adapter->flags & RX_CSUM_ENABLED) != 0;
-}
-
-static int set_rx_csum(struct net_device *dev, u32 data)
-{
- struct adapter *adapter = dev->ml_priv;
-
- if (data)
- adapter->flags |= RX_CSUM_ENABLED;
- else
- adapter->flags &= ~RX_CSUM_ENABLED;
- return 0;
-}
-
-static int set_tso(struct net_device *dev, u32 value)
-{
- struct adapter *adapter = dev->ml_priv;
-
- if (!(adapter->flags & TSO_CAPABLE))
- return value ? -EOPNOTSUPP : 0;
- return ethtool_op_set_tso(dev, value);
-}
-
static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
{
struct adapter *adapter = dev->ml_priv;
@@ -831,17 +803,12 @@ static const struct ethtool_ops t1_ethtool_ops = {
.get_eeprom = get_eeprom,
.get_pauseparam = get_pauseparam,
.set_pauseparam = set_pauseparam,
- .get_rx_csum = get_rx_csum,
- .set_rx_csum = set_rx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .set_sg = ethtool_op_set_sg,
.get_link = ethtool_op_get_link,
.get_strings = get_strings,
.get_sset_count = get_sset_count,
.get_ethtool_stats = get_stats,
.get_regs_len = get_regs_len,
.get_regs = get_regs,
- .set_tso = set_tso,
};
static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
@@ -1105,28 +1072,28 @@ static int __devinit init_one(struct pci_dev *pdev,
netdev->mem_start = mmio_start;
netdev->mem_end = mmio_start + mmio_len - 1;
netdev->ml_priv = adapter;
- netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
- netdev->features |= NETIF_F_LLTX;
+ netdev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_RXCSUM;
+ netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_RXCSUM | NETIF_F_LLTX;
- adapter->flags |= RX_CSUM_ENABLED | TCP_CSUM_CAPABLE;
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
if (vlan_tso_capable(adapter)) {
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
- adapter->flags |= VLAN_ACCEL_CAPABLE;
netdev->features |=
NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
#endif
/* T204: disable TSO */
if (!(is_T2(adapter)) || bi->port_number != 4) {
- adapter->flags |= TSO_CAPABLE;
+ netdev->hw_features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO;
}
}
netdev->netdev_ops = &cxgb_netdev_ops;
- netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ?
+ netdev->hard_header_len += (netdev->hw_features & NETIF_F_TSO) ?
sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt);
netif_napi_add(netdev, &adapter->napi, t1_poll, 64);
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 8754d447304..b948ea73755 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -929,7 +929,7 @@ void t1_sge_intr_enable(struct sge *sge)
u32 en = SGE_INT_ENABLE;
u32 val = readl(sge->adapter->regs + A_PL_ENABLE);
- if (sge->adapter->flags & TSO_CAPABLE)
+ if (sge->adapter->port[0].dev->hw_features & NETIF_F_TSO)
en &= ~F_PACKET_TOO_BIG;
writel(en, sge->adapter->regs + A_SG_INT_ENABLE);
writel(val | SGE_PL_INTR_MASK, sge->adapter->regs + A_PL_ENABLE);
@@ -952,7 +952,7 @@ int t1_sge_intr_error_handler(struct sge *sge)
struct adapter *adapter = sge->adapter;
u32 cause = readl(adapter->regs + A_SG_INT_CAUSE);
- if (adapter->flags & TSO_CAPABLE)
+ if (adapter->port[0].dev->hw_features & NETIF_F_TSO)
cause &= ~F_PACKET_TOO_BIG;
if (cause & F_RESPQ_EXHAUSTED)
sge->stats.respQ_empty++;
@@ -1369,6 +1369,7 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
const struct cpl_rx_pkt *p;
struct adapter *adapter = sge->adapter;
struct sge_port_stats *st;
+ struct net_device *dev;
skb = get_packet(adapter->pdev, fl, len - sge->rx_pkt_pad);
if (unlikely(!skb)) {
@@ -1384,9 +1385,10 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
__skb_pull(skb, sizeof(*p));
st = this_cpu_ptr(sge->port_stats[p->iff]);
+ dev = adapter->port[p->iff].dev;
- skb->protocol = eth_type_trans(skb, adapter->port[p->iff].dev);
- if ((adapter->flags & RX_CSUM_ENABLED) && p->csum == 0xffff &&
+ skb->protocol = eth_type_trans(skb, dev);
+ if ((dev->features & NETIF_F_RXCSUM) && p->csum == 0xffff &&
skb->protocol == htons(ETH_P_IP) &&
(skb->data[9] == IPPROTO_TCP || skb->data[9] == IPPROTO_UDP)) {
++st->rx_cso_good;
@@ -1838,8 +1840,7 @@ netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
- if (!(adapter->flags & UDP_CSUM_CAPABLE) &&
- skb->ip_summed == CHECKSUM_PARTIAL &&
+ if (skb->ip_summed == CHECKSUM_PARTIAL &&
ip_hdr(skb)->protocol == IPPROTO_UDP) {
if (unlikely(skb_checksum_help(skb))) {
pr_debug("%s: unable to do udp checksum\n", dev->name);
diff --git a/drivers/net/chelsio/tp.c b/drivers/net/chelsio/tp.c
index 6222d585e44..8bed4a59e65 100644
--- a/drivers/net/chelsio/tp.c
+++ b/drivers/net/chelsio/tp.c
@@ -152,11 +152,6 @@ void t1_tp_set_ip_checksum_offload(struct petp *tp, int enable)
set_csum_offload(tp, F_IP_CSUM, enable);
}
-void t1_tp_set_udp_checksum_offload(struct petp *tp, int enable)
-{
- set_csum_offload(tp, F_UDP_CSUM, enable);
-}
-
void t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable)
{
set_csum_offload(tp, F_TCP_CSUM, enable);
diff --git a/drivers/net/chelsio/tp.h b/drivers/net/chelsio/tp.h
index 32fc71e5891..dfd8ce25106 100644
--- a/drivers/net/chelsio/tp.h
+++ b/drivers/net/chelsio/tp.h
@@ -65,7 +65,6 @@ void t1_tp_intr_clear(struct petp *tp);
int t1_tp_intr_handler(struct petp *tp);
void t1_tp_get_mib_statistics(adapter_t *adap, struct tp_mib_statistics *tps);
-void t1_tp_set_udp_checksum_offload(struct petp *tp, int enable);
void t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable);
void t1_tp_set_ip_checksum_offload(struct petp *tp, int enable);
int t1_tp_set_coalescing_size(struct petp *tp, unsigned int size);
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 8cca60e4344..cde59b4e5ef 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -2966,31 +2966,36 @@ static int cnic_service_bnx2x(void *data, void *status_blk)
return 0;
}
-static void cnic_ulp_stop(struct cnic_dev *dev)
+static void cnic_ulp_stop_one(struct cnic_local *cp, int if_type)
{
- struct cnic_local *cp = dev->cnic_priv;
- int if_type;
-
- cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
+ struct cnic_ulp_ops *ulp_ops;
- for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
- struct cnic_ulp_ops *ulp_ops;
+ if (if_type == CNIC_ULP_ISCSI)
+ cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
- mutex_lock(&cnic_lock);
- ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type],
- lockdep_is_held(&cnic_lock));
- if (!ulp_ops) {
- mutex_unlock(&cnic_lock);
- continue;
- }
- set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
+ mutex_lock(&cnic_lock);
+ ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type],
+ lockdep_is_held(&cnic_lock));
+ if (!ulp_ops) {
mutex_unlock(&cnic_lock);
+ return;
+ }
+ set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
+ mutex_unlock(&cnic_lock);
- if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type]))
- ulp_ops->cnic_stop(cp->ulp_handle[if_type]);
+ if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type]))
+ ulp_ops->cnic_stop(cp->ulp_handle[if_type]);
- clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
- }
+ clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
+}
+
+static void cnic_ulp_stop(struct cnic_dev *dev)
+{
+ struct cnic_local *cp = dev->cnic_priv;
+ int if_type;
+
+ for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++)
+ cnic_ulp_stop_one(cp, if_type);
}
static void cnic_ulp_start(struct cnic_dev *dev)
@@ -3039,6 +3044,12 @@ static int cnic_ctl(void *data, struct cnic_ctl_info *info)
cnic_put(dev);
break;
+ case CNIC_CTL_STOP_ISCSI_CMD: {
+ struct cnic_local *cp = dev->cnic_priv;
+ set_bit(CNIC_LCL_FL_STOP_ISCSI, &cp->cnic_local_flags);
+ queue_delayed_work(cnic_wq, &cp->delete_task, 0);
+ break;
+ }
case CNIC_CTL_COMPLETION_CMD: {
u32 cid = BNX2X_SW_CID(info->data.comp.cid);
u32 l5_cid;
@@ -3562,8 +3573,12 @@ static void cnic_init_csk_state(struct cnic_sock *csk)
static int cnic_cm_connect(struct cnic_sock *csk, struct cnic_sockaddr *saddr)
{
+ struct cnic_local *cp = csk->dev->cnic_priv;
int err = 0;
+ if (cp->ethdev->drv_state & CNIC_DRV_STATE_NO_ISCSI)
+ return -EOPNOTSUPP;
+
if (!cnic_in_use(csk))
return -EINVAL;
@@ -3965,6 +3980,15 @@ static void cnic_delete_task(struct work_struct *work)
cp = container_of(work, struct cnic_local, delete_task.work);
dev = cp->dev;
+ if (test_and_clear_bit(CNIC_LCL_FL_STOP_ISCSI, &cp->cnic_local_flags)) {
+ struct drv_ctl_info info;
+
+ cnic_ulp_stop_one(cp, CNIC_ULP_ISCSI);
+
+ info.cmd = DRV_CTL_ISCSI_STOPPED_CMD;
+ cp->ethdev->drv_ctl(dev->netdev, &info);
+ }
+
for (i = 0; i < cp->max_cid_space; i++) {
struct cnic_context *ctx = &cp->ctx_tbl[i];
diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h
index 4456260c653..3367a6d3a77 100644
--- a/drivers/net/cnic.h
+++ b/drivers/net/cnic.h
@@ -226,6 +226,7 @@ struct cnic_local {
#define CNIC_LCL_FL_KWQ_INIT 0x0
#define CNIC_LCL_FL_L2_WAIT 0x1
#define CNIC_LCL_FL_RINGS_INITED 0x2
+#define CNIC_LCL_FL_STOP_ISCSI 0x4
struct cnic_dev *dev;
diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h
index e01b49ee359..fdd8e46a905 100644
--- a/drivers/net/cnic_if.h
+++ b/drivers/net/cnic_if.h
@@ -12,8 +12,8 @@
#ifndef CNIC_IF_H
#define CNIC_IF_H
-#define CNIC_MODULE_VERSION "2.2.13"
-#define CNIC_MODULE_RELDATE "Jan 31, 2011"
+#define CNIC_MODULE_VERSION "2.2.14"
+#define CNIC_MODULE_RELDATE "Mar 30, 2011"
#define CNIC_ULP_RDMA 0
#define CNIC_ULP_ISCSI 1
@@ -85,6 +85,7 @@ struct kcqe {
#define CNIC_CTL_STOP_CMD 1
#define CNIC_CTL_START_CMD 2
#define CNIC_CTL_COMPLETION_CMD 3
+#define CNIC_CTL_STOP_ISCSI_CMD 4
#define DRV_CTL_IO_WR_CMD 0x101
#define DRV_CTL_IO_RD_CMD 0x102
@@ -94,6 +95,7 @@ struct kcqe {
#define DRV_CTL_START_L2_CMD 0x106
#define DRV_CTL_STOP_L2_CMD 0x107
#define DRV_CTL_RET_L2_SPQ_CREDIT_CMD 0x10c
+#define DRV_CTL_ISCSI_STOPPED_CMD 0x10d
struct cnic_ctl_completion {
u32 cid;
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index 9d267d3a689..e66aceb57ce 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -491,8 +491,8 @@ e100_open(struct net_device *dev)
/* allocate the irq corresponding to the receiving DMA */
- if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rxtx_interrupt,
- IRQF_SAMPLE_RANDOM, cardname, (void *)dev)) {
+ if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rxtx_interrupt, 0, cardname,
+ (void *)dev)) {
goto grace_exit0;
}
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index ef67be59680..7300de5a142 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -50,11 +50,6 @@ struct adapter;
struct sge_qset;
struct port_info;
-enum { /* rx_offload flags */
- T3_RX_CSUM = 1 << 0,
- T3_LRO = 1 << 1,
-};
-
enum mac_idx_types {
LAN_MAC_IDX = 0,
SAN_MAC_IDX,
@@ -74,7 +69,6 @@ struct port_info {
struct vlan_group *vlan_grp;
struct sge_qset *qs;
u8 port_id;
- u8 rx_offload;
u8 nqsets;
u8 first_qset;
struct cphy phy;
@@ -212,7 +206,6 @@ struct sge_qset { /* an SGE queue set */
struct sge_fl fl[SGE_RXQ_PER_SET];
struct sge_txq txq[SGE_TXQ_PER_SET];
int nomem;
- int lro_enabled;
void *lro_va;
struct net_device *netdev;
struct netdev_queue *tx_q; /* associated netdev TX queue */
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index 5ccb77d078a..056ee8c831f 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -317,7 +317,6 @@ struct tp_params {
struct qset_params { /* SGE queue set parameters */
unsigned int polling; /* polling/interrupt service for rspq */
- unsigned int lro; /* large receive offload */
unsigned int coalesce_usecs; /* irq coalescing timer */
unsigned int rspq_size; /* # of entries in response queue */
unsigned int fl_size; /* # of entries in regular free list */
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 91089314329..9081ce03714 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -644,26 +644,6 @@ static void enable_all_napi(struct adapter *adap)
}
/**
- * set_qset_lro - Turn a queue set's LRO capability on and off
- * @dev: the device the qset is attached to
- * @qset_idx: the queue set index
- * @val: the LRO switch
- *
- * Sets LRO on or off for a particular queue set.
- * the device's features flag is updated to reflect the LRO
- * capability when all queues belonging to the device are
- * in the same state.
- */
-static void set_qset_lro(struct net_device *dev, int qset_idx, int val)
-{
- struct port_info *pi = netdev_priv(dev);
- struct adapter *adapter = pi->adapter;
-
- adapter->params.sge.qset[qset_idx].lro = !!val;
- adapter->sge.qs[qset_idx].lro_enabled = !!val;
-}
-
-/**
* setup_sge_qsets - configure SGE Tx/Rx/response queues
* @adap: the adapter
*
@@ -685,7 +665,6 @@ static int setup_sge_qsets(struct adapter *adap)
pi->qs = &adap->sge.qs[pi->first_qset];
for (j = 0; j < pi->nqsets; ++j, ++qset_idx) {
- set_qset_lro(dev, qset_idx, pi->rx_offload & T3_LRO);
err = t3_sge_alloc_qset(adap, qset_idx, 1,
(adap->flags & USING_MSIX) ? qset_idx + 1 :
irq_idx,
@@ -1749,23 +1728,26 @@ static int restart_autoneg(struct net_device *dev)
return 0;
}
-static int cxgb3_phys_id(struct net_device *dev, u32 data)
+static int set_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
- int i;
- if (data == 0)
- data = 2;
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ return 1; /* cycle on/off once per second */
- for (i = 0; i < data * 2; i++) {
+ case ETHTOOL_ID_OFF:
+ t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL, 0);
+ break;
+
+ case ETHTOOL_ID_ON:
+ case ETHTOOL_ID_INACTIVE:
t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL,
- (i & 1) ? F_GPIO0_OUT_VAL : 0);
- if (msleep_interruptible(500))
- break;
- }
- t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL,
F_GPIO0_OUT_VAL);
+ }
+
return 0;
}
@@ -1777,10 +1759,10 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->advertising = p->link_config.advertising;
if (netif_carrier_ok(dev)) {
- cmd->speed = p->link_config.speed;
+ ethtool_cmd_speed_set(cmd, p->link_config.speed);
cmd->duplex = p->link_config.duplex;
} else {
- cmd->speed = -1;
+ ethtool_cmd_speed_set(cmd, -1);
cmd->duplex = -1;
}
@@ -1839,7 +1821,8 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
* being requested.
*/
if (cmd->autoneg == AUTONEG_DISABLE) {
- int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
+ u32 speed = ethtool_cmd_speed(cmd);
+ int cap = speed_duplex_to_caps(speed, cmd->duplex);
if (lc->supported & cap)
return 0;
}
@@ -1847,11 +1830,12 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
}
if (cmd->autoneg == AUTONEG_DISABLE) {
- int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
+ u32 speed = ethtool_cmd_speed(cmd);
+ int cap = speed_duplex_to_caps(speed, cmd->duplex);
- if (!(lc->supported & cap) || cmd->speed == SPEED_1000)
+ if (!(lc->supported & cap) || (speed == SPEED_1000))
return -EINVAL;
- lc->requested_speed = cmd->speed;
+ lc->requested_speed = speed;
lc->requested_duplex = cmd->duplex;
lc->advertising = 0;
} else {
@@ -1907,29 +1891,6 @@ static int set_pauseparam(struct net_device *dev,
return 0;
}
-static u32 get_rx_csum(struct net_device *dev)
-{
- struct port_info *p = netdev_priv(dev);
-
- return p->rx_offload & T3_RX_CSUM;
-}
-
-static int set_rx_csum(struct net_device *dev, u32 data)
-{
- struct port_info *p = netdev_priv(dev);
-
- if (data) {
- p->rx_offload |= T3_RX_CSUM;
- } else {
- int i;
-
- p->rx_offload &= ~(T3_RX_CSUM | T3_LRO);
- for (i = p->first_qset; i < p->first_qset + p->nqsets; i++)
- set_qset_lro(dev, i, 0);
- }
- return 0;
-}
-
static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
{
struct port_info *pi = netdev_priv(dev);
@@ -2101,20 +2062,15 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
.set_eeprom = set_eeprom,
.get_pauseparam = get_pauseparam,
.set_pauseparam = set_pauseparam,
- .get_rx_csum = get_rx_csum,
- .set_rx_csum = set_rx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .set_sg = ethtool_op_set_sg,
.get_link = ethtool_op_get_link,
.get_strings = get_strings,
- .phys_id = cxgb3_phys_id,
+ .set_phys_id = set_phys_id,
.nway_reset = restart_autoneg,
.get_sset_count = get_sset_count,
.get_ethtool_stats = get_stats,
.get_regs_len = get_regs_len,
.get_regs = get_regs,
.get_wol = get_wol,
- .set_tso = ethtool_op_set_tso,
};
static int in_range(int val, int lo, int hi)
@@ -2162,15 +2118,6 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
MAX_RSPQ_ENTRIES))
return -EINVAL;
- if ((adapter->flags & FULL_INIT_DONE) && t.lro > 0)
- for_each_port(adapter, i) {
- pi = adap2pinfo(adapter, i);
- if (t.qset_idx >= pi->first_qset &&
- t.qset_idx < pi->first_qset + pi->nqsets &&
- !(pi->rx_offload & T3_RX_CSUM))
- return -EINVAL;
- }
-
if ((adapter->flags & FULL_INIT_DONE) &&
(t.rspq_size >= 0 || t.fl_size[0] >= 0 ||
t.fl_size[1] >= 0 || t.txq_size[0] >= 0 ||
@@ -2231,8 +2178,14 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
}
}
}
- if (t.lro >= 0)
- set_qset_lro(dev, t.qset_idx, t.lro);
+
+ if (t.lro >= 0) {
+ if (t.lro)
+ dev->wanted_features |= NETIF_F_GRO;
+ else
+ dev->wanted_features &= ~NETIF_F_GRO;
+ netdev_update_features(dev);
+ }
break;
}
@@ -2266,7 +2219,7 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
t.fl_size[0] = q->fl_size;
t.fl_size[1] = q->jumbo_size;
t.polling = q->polling;
- t.lro = q->lro;
+ t.lro = !!(dev->features & NETIF_F_GRO);
t.intr_lat = q->coalesce_usecs;
t.cong_thres = q->cong_thres;
t.qnum = q1;
@@ -3304,18 +3257,18 @@ static int __devinit init_one(struct pci_dev *pdev,
adapter->port[i] = netdev;
pi = netdev_priv(netdev);
pi->adapter = adapter;
- pi->rx_offload = T3_RX_CSUM | T3_LRO;
pi->port_id = i;
netif_carrier_off(netdev);
netdev->irq = pdev->irq;
netdev->mem_start = mmio_start;
netdev->mem_end = mmio_start + mmio_len - 1;
- netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
- netdev->features |= NETIF_F_GRO;
+ netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_TSO | NETIF_F_RXCSUM;
+ netdev->features |= netdev->hw_features |
+ NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
- netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
netdev->netdev_ops = &cxgb_netdev_ops;
SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
}
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index bfa2d56af1e..cba1401377a 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -2019,7 +2019,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
skb_pull(skb, sizeof(*p) + pad);
skb->protocol = eth_type_trans(skb, adap->port[p->iff]);
pi = netdev_priv(skb->dev);
- if ((pi->rx_offload & T3_RX_CSUM) && p->csum_valid &&
+ if ((skb->dev->features & NETIF_F_RXCSUM) && p->csum_valid &&
p->csum == htons(0xffff) && !p->fragment) {
qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -2120,7 +2120,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
offset = 2 + sizeof(struct cpl_rx_pkt);
cpl = qs->lro_va = sd->pg_chunk.va + 2;
- if ((pi->rx_offload & T3_RX_CSUM) &&
+ if ((qs->netdev->features & NETIF_F_RXCSUM) &&
cpl->csum_valid && cpl->csum == htons(0xffff)) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
@@ -2285,7 +2285,8 @@ static int process_responses(struct adapter *adap, struct sge_qset *qs,
q->next_holdoff = q->holdoff_tmr;
while (likely(budget_left && is_new_response(r, q))) {
- int packet_complete, eth, ethpad = 2, lro = qs->lro_enabled;
+ int packet_complete, eth, ethpad = 2;
+ int lro = !!(qs->netdev->features & NETIF_F_GRO);
struct sk_buff *skb = NULL;
u32 len, flags;
__be32 rss_hi, rss_lo;
diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h
index 01d49eaa44d..bc9982a4c1f 100644
--- a/drivers/net/cxgb4/cxgb4.h
+++ b/drivers/net/cxgb4/cxgb4.h
@@ -290,7 +290,6 @@ struct port_info {
u8 port_id;
u8 tx_chan;
u8 lport; /* associated offload logical port */
- u8 rx_offload; /* CSO, etc */
u8 nqsets; /* # of qsets */
u8 first_qset; /* index of first qset */
u8 rss_mode;
@@ -298,11 +297,6 @@ struct port_info {
u16 *rss;
};
-/* port_info.rx_offload flags */
-enum {
- RX_CSO = 1 << 0,
-};
-
struct dentry;
struct work_struct;
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
index 5352c8a23f4..7e3cfbe89e3 100644
--- a/drivers/net/cxgb4/cxgb4_main.c
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -1336,15 +1336,20 @@ static int restart_autoneg(struct net_device *dev)
return 0;
}
-static int identify_port(struct net_device *dev, u32 data)
+static int identify_port(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
+ unsigned int val;
struct adapter *adap = netdev2adap(dev);
- if (data == 0)
- data = 2; /* default to 2 seconds */
+ if (state == ETHTOOL_ID_ACTIVE)
+ val = 0xffff;
+ else if (state == ETHTOOL_ID_INACTIVE)
+ val = 0;
+ else
+ return -EINVAL;
- return t4_identify_port(adap, adap->fn, netdev2pinfo(dev)->viid,
- data * 5);
+ return t4_identify_port(adap, adap->fn, netdev2pinfo(dev)->viid, val);
}
static unsigned int from_fw_linkcaps(unsigned int type, unsigned int caps)
@@ -1431,7 +1436,8 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->supported = from_fw_linkcaps(p->port_type, p->link_cfg.supported);
cmd->advertising = from_fw_linkcaps(p->port_type,
p->link_cfg.advertising);
- cmd->speed = netif_carrier_ok(dev) ? p->link_cfg.speed : 0;
+ ethtool_cmd_speed_set(cmd,
+ netif_carrier_ok(dev) ? p->link_cfg.speed : 0);
cmd->duplex = DUPLEX_FULL;
cmd->autoneg = p->link_cfg.autoneg;
cmd->maxtxpkt = 0;
@@ -1455,6 +1461,7 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
unsigned int cap;
struct port_info *p = netdev_priv(dev);
struct link_config *lc = &p->link_cfg;
+ u32 speed = ethtool_cmd_speed(cmd);
if (cmd->duplex != DUPLEX_FULL) /* only full-duplex supported */
return -EINVAL;
@@ -1465,16 +1472,16 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
* being requested.
*/
if (cmd->autoneg == AUTONEG_DISABLE &&
- (lc->supported & speed_to_caps(cmd->speed)))
- return 0;
+ (lc->supported & speed_to_caps(speed)))
+ return 0;
return -EINVAL;
}
if (cmd->autoneg == AUTONEG_DISABLE) {
- cap = speed_to_caps(cmd->speed);
+ cap = speed_to_caps(speed);
- if (!(lc->supported & cap) || cmd->speed == SPEED_1000 ||
- cmd->speed == SPEED_10000)
+ if (!(lc->supported & cap) || (speed == SPEED_1000) ||
+ (speed == SPEED_10000))
return -EINVAL;
lc->requested_speed = cap;
lc->advertising = 0;
@@ -1526,24 +1533,6 @@ static int set_pauseparam(struct net_device *dev,
return 0;
}
-static u32 get_rx_csum(struct net_device *dev)
-{
- struct port_info *p = netdev_priv(dev);
-
- return p->rx_offload & RX_CSO;
-}
-
-static int set_rx_csum(struct net_device *dev, u32 data)
-{
- struct port_info *p = netdev_priv(dev);
-
- if (data)
- p->rx_offload |= RX_CSO;
- else
- p->rx_offload &= ~RX_CSO;
- return 0;
-}
-
static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
{
const struct port_info *pi = netdev_priv(dev);
@@ -1865,36 +1854,20 @@ static int set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
return err;
}
-#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
-
-static int set_tso(struct net_device *dev, u32 value)
-{
- if (value)
- dev->features |= TSO_FLAGS;
- else
- dev->features &= ~TSO_FLAGS;
- return 0;
-}
-
-static int set_flags(struct net_device *dev, u32 flags)
+static int cxgb_set_features(struct net_device *dev, u32 features)
{
+ const struct port_info *pi = netdev_priv(dev);
+ u32 changed = dev->features ^ features;
int err;
- unsigned long old_feat = dev->features;
- err = ethtool_op_set_flags(dev, flags, ETH_FLAG_RXHASH |
- ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN);
- if (err)
- return err;
-
- if ((old_feat ^ dev->features) & NETIF_F_HW_VLAN_RX) {
- const struct port_info *pi = netdev_priv(dev);
+ if (!(changed & NETIF_F_HW_VLAN_RX))
+ return 0;
- err = t4_set_rxmode(pi->adapter, pi->adapter->fn, pi->viid, -1,
- -1, -1, -1, !!(flags & ETH_FLAG_RXVLAN),
- true);
- if (err)
- dev->features = old_feat;
- }
+ err = t4_set_rxmode(pi->adapter, pi->adapter->fn, pi->viid, -1,
+ -1, -1, -1,
+ !!(features & NETIF_F_HW_VLAN_RX), true);
+ if (unlikely(err))
+ dev->features = features ^ NETIF_F_HW_VLAN_RX;
return err;
}
@@ -2005,13 +1978,9 @@ static struct ethtool_ops cxgb_ethtool_ops = {
.set_eeprom = set_eeprom,
.get_pauseparam = get_pauseparam,
.set_pauseparam = set_pauseparam,
- .get_rx_csum = get_rx_csum,
- .set_rx_csum = set_rx_csum,
- .set_tx_csum = ethtool_op_set_tx_ipv6_csum,
- .set_sg = ethtool_op_set_sg,
.get_link = ethtool_op_get_link,
.get_strings = get_strings,
- .phys_id = identify_port,
+ .set_phys_id = identify_port,
.nway_reset = restart_autoneg,
.get_sset_count = get_sset_count,
.get_ethtool_stats = get_stats,
@@ -2019,8 +1988,6 @@ static struct ethtool_ops cxgb_ethtool_ops = {
.get_regs = get_regs,
.get_wol = get_wol,
.set_wol = set_wol,
- .set_tso = set_tso,
- .set_flags = set_flags,
.get_rxnfc = get_rxnfc,
.get_rxfh_indir = get_rss_table,
.set_rxfh_indir = set_rss_table,
@@ -2877,6 +2844,7 @@ static const struct net_device_ops cxgb4_netdev_ops = {
.ndo_get_stats64 = cxgb_get_stats,
.ndo_set_rx_mode = cxgb_set_rxmode,
.ndo_set_mac_address = cxgb_set_mac_addr,
+ .ndo_set_features = cxgb_set_features,
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = cxgb_ioctl,
.ndo_change_mtu = cxgb_change_mtu,
@@ -3559,6 +3527,7 @@ static void free_some_resources(struct adapter *adapter)
t4_fw_bye(adapter, adapter->fn);
}
+#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \
NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA)
@@ -3660,14 +3629,14 @@ static int __devinit init_one(struct pci_dev *pdev,
pi = netdev_priv(netdev);
pi->adapter = adapter;
pi->xact_addr_filt = -1;
- pi->rx_offload = RX_CSO;
pi->port_id = i;
netdev->irq = pdev->irq;
- netdev->features |= NETIF_F_SG | TSO_FLAGS;
- netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
- netdev->features |= NETIF_F_GRO | NETIF_F_RXHASH | highdma;
- netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ netdev->hw_features = NETIF_F_SG | TSO_FLAGS |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_RXCSUM | NETIF_F_RXHASH |
+ NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ netdev->features |= netdev->hw_features | highdma;
netdev->vlan_features = netdev->features & VLAN_FEAT;
netdev->netdev_ops = &cxgb4_netdev_ops;
diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c
index 311471b439a..75a4b0fa19e 100644
--- a/drivers/net/cxgb4/sge.c
+++ b/drivers/net/cxgb4/sge.c
@@ -1556,7 +1556,6 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
{
bool csum_ok;
struct sk_buff *skb;
- struct port_info *pi;
const struct cpl_rx_pkt *pkt;
struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq);
@@ -1584,10 +1583,9 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
if (skb->dev->features & NETIF_F_RXHASH)
skb->rxhash = (__force u32)pkt->rsshdr.hash_val;
- pi = netdev_priv(skb->dev);
rxq->stats.pkts++;
- if (csum_ok && (pi->rx_offload & RX_CSO) &&
+ if (csum_ok && (q->netdev->features & NETIF_F_RXCSUM) &&
(pkt->l2info & htonl(RXF_UDP | RXF_TCP))) {
if (!pkt->ip_frag) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
diff --git a/drivers/net/cxgb4vf/adapter.h b/drivers/net/cxgb4vf/adapter.h
index 4766b4116b4..4fd821aadc8 100644
--- a/drivers/net/cxgb4vf/adapter.h
+++ b/drivers/net/cxgb4vf/adapter.h
@@ -97,17 +97,11 @@ struct port_info {
u16 rss_size; /* size of VI's RSS table slice */
u8 pidx; /* index into adapter port[] */
u8 port_id; /* physical port ID */
- u8 rx_offload; /* CSO, etc. */
u8 nqsets; /* # of "Queue Sets" */
u8 first_qset; /* index of first "Queue Set" */
struct link_config link_cfg; /* physical port configuration */
};
-/* port_info.rx_offload flags */
-enum {
- RX_CSO = 1 << 0,
-};
-
/*
* Scatter Gather Engine resources for the "adapter". Our ingress and egress
* queues are organized into "Queue Sets" with one ingress and one egress
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c
index 4661cbbd9bd..e71c08e547e 100644
--- a/drivers/net/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/cxgb4vf/cxgb4vf_main.c
@@ -1167,7 +1167,8 @@ static int cxgb4vf_get_settings(struct net_device *dev,
cmd->supported = pi->link_cfg.supported;
cmd->advertising = pi->link_cfg.advertising;
- cmd->speed = netif_carrier_ok(dev) ? pi->link_cfg.speed : -1;
+ ethtool_cmd_speed_set(cmd,
+ netif_carrier_ok(dev) ? pi->link_cfg.speed : -1);
cmd->duplex = DUPLEX_FULL;
cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
@@ -1326,37 +1327,22 @@ static void cxgb4vf_get_pauseparam(struct net_device *dev,
}
/*
- * Return whether RX Checksum Offloading is currently enabled for the device.
- */
-static u32 cxgb4vf_get_rx_csum(struct net_device *dev)
-{
- struct port_info *pi = netdev_priv(dev);
-
- return (pi->rx_offload & RX_CSO) != 0;
-}
-
-/*
- * Turn RX Checksum Offloading on or off for the device.
+ * Identify the port by blinking the port's LED.
*/
-static int cxgb4vf_set_rx_csum(struct net_device *dev, u32 csum)
+static int cxgb4vf_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
+ unsigned int val;
struct port_info *pi = netdev_priv(dev);
- if (csum)
- pi->rx_offload |= RX_CSO;
+ if (state == ETHTOOL_ID_ACTIVE)
+ val = 0xffff;
+ else if (state == ETHTOOL_ID_INACTIVE)
+ val = 0;
else
- pi->rx_offload &= ~RX_CSO;
- return 0;
-}
-
-/*
- * Identify the port by blinking the port's LED.
- */
-static int cxgb4vf_phys_id(struct net_device *dev, u32 id)
-{
- struct port_info *pi = netdev_priv(dev);
+ return -EINVAL;
- return t4vf_identify_port(pi->adapter, pi->viid, 5);
+ return t4vf_identify_port(pi->adapter, pi->viid, val);
}
/*
@@ -1560,18 +1546,6 @@ static void cxgb4vf_get_wol(struct net_device *dev,
*/
#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
-/*
- * Set TCP Segmentation Offloading feature capabilities.
- */
-static int cxgb4vf_set_tso(struct net_device *dev, u32 tso)
-{
- if (tso)
- dev->features |= TSO_FLAGS;
- else
- dev->features &= ~TSO_FLAGS;
- return 0;
-}
-
static struct ethtool_ops cxgb4vf_ethtool_ops = {
.get_settings = cxgb4vf_get_settings,
.get_drvinfo = cxgb4vf_get_drvinfo,
@@ -1582,19 +1556,14 @@ static struct ethtool_ops cxgb4vf_ethtool_ops = {
.get_coalesce = cxgb4vf_get_coalesce,
.set_coalesce = cxgb4vf_set_coalesce,
.get_pauseparam = cxgb4vf_get_pauseparam,
- .get_rx_csum = cxgb4vf_get_rx_csum,
- .set_rx_csum = cxgb4vf_set_rx_csum,
- .set_tx_csum = ethtool_op_set_tx_ipv6_csum,
- .set_sg = ethtool_op_set_sg,
.get_link = ethtool_op_get_link,
.get_strings = cxgb4vf_get_strings,
- .phys_id = cxgb4vf_phys_id,
+ .set_phys_id = cxgb4vf_phys_id,
.get_sset_count = cxgb4vf_get_sset_count,
.get_ethtool_stats = cxgb4vf_get_ethtool_stats,
.get_regs_len = cxgb4vf_get_regs_len,
.get_regs = cxgb4vf_get_regs,
.get_wol = cxgb4vf_get_wol,
- .set_tso = cxgb4vf_set_tso,
};
/*
@@ -2629,19 +2598,19 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev,
* it.
*/
pi->xact_addr_filt = -1;
- pi->rx_offload = RX_CSO;
netif_carrier_off(netdev);
netdev->irq = pdev->irq;
- netdev->features = (NETIF_F_SG | TSO_FLAGS |
- NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
- NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
- NETIF_F_GRO);
+ netdev->hw_features = NETIF_F_SG | TSO_FLAGS |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_HW_VLAN_TX | NETIF_F_RXCSUM;
+ netdev->vlan_features = NETIF_F_SG | TSO_FLAGS |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_HIGHDMA;
+ netdev->features = netdev->hw_features |
+ NETIF_F_HW_VLAN_RX;
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
- netdev->vlan_features =
- (netdev->features &
- ~(NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX));
#ifdef HAVE_NET_DEVICE_OPS
netdev->netdev_ops = &cxgb4vf_netdev_ops;
diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c
index bb65121f581..5182960e29f 100644
--- a/drivers/net/cxgb4vf/sge.c
+++ b/drivers/net/cxgb4vf/sge.c
@@ -1555,8 +1555,8 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
pi = netdev_priv(skb->dev);
rxq->stats.pkts++;
- if (csum_ok && (pi->rx_offload & RX_CSO) && !pkt->err_vec &&
- (be32_to_cpu(pkt->l2info) & (RXF_UDP|RXF_TCP))) {
+ if (csum_ok && (rspq->netdev->features & NETIF_F_RXCSUM) &&
+ !pkt->err_vec && (be32_to_cpu(pkt->l2info) & (RXF_UDP|RXF_TCP))) {
if (!pkt->ip_frag)
skb->ip_summed = CHECKSUM_UNNECESSARY;
else {
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 8b0084d17c8..17654059922 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -331,18 +331,18 @@ static struct {
"DE422",\
""}
-static char* __initdata depca_signature[] = DEPCA_SIGNATURE;
+static const char* const depca_signature[] __devinitconst = DEPCA_SIGNATURE;
enum depca_type {
DEPCA, de100, de101, de200, de201, de202, de210, de212, de422, unknown
};
-static char depca_string[] = "depca";
+static const char depca_string[] = "depca";
static int depca_device_remove (struct device *device);
#ifdef CONFIG_EISA
-static struct eisa_device_id depca_eisa_ids[] = {
+static const struct eisa_device_id depca_eisa_ids[] __devinitconst = {
{ "DEC4220", de422 },
{ "" }
};
@@ -367,19 +367,19 @@ static struct eisa_driver depca_eisa_driver = {
#define DE210_ID 0x628d
#define DE212_ID 0x6def
-static short depca_mca_adapter_ids[] = {
+static const short depca_mca_adapter_ids[] __devinitconst = {
DE210_ID,
DE212_ID,
0x0000
};
-static char *depca_mca_adapter_name[] = {
+static const char *depca_mca_adapter_name[] = {
"DEC EtherWORKS MC Adapter (DE210)",
"DEC EtherWORKS MC Adapter (DE212)",
NULL
};
-static enum depca_type depca_mca_adapter_type[] = {
+static const enum depca_type depca_mca_adapter_type[] = {
de210,
de212,
0
@@ -541,10 +541,9 @@ static void SetMulticastFilter(struct net_device *dev);
static int load_packet(struct net_device *dev, struct sk_buff *skb);
static void depca_dbg_open(struct net_device *dev);
-static u_char de1xx_irq[] __initdata = { 2, 3, 4, 5, 7, 9, 0 };
-static u_char de2xx_irq[] __initdata = { 5, 9, 10, 11, 15, 0 };
-static u_char de422_irq[] __initdata = { 5, 9, 10, 11, 0 };
-static u_char *depca_irq;
+static const u_char de1xx_irq[] __devinitconst = { 2, 3, 4, 5, 7, 9, 0 };
+static const u_char de2xx_irq[] __devinitconst = { 5, 9, 10, 11, 15, 0 };
+static const u_char de422_irq[] __devinitconst = { 5, 9, 10, 11, 0 };
static int irq;
static int io;
@@ -580,7 +579,7 @@ static const struct net_device_ops depca_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
};
-static int __init depca_hw_init (struct net_device *dev, struct device *device)
+static int __devinit depca_hw_init (struct net_device *dev, struct device *device)
{
struct depca_private *lp;
int i, j, offset, netRAM, mem_len, status = 0;
@@ -748,6 +747,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
if (dev->irq < 2) {
unsigned char irqnum;
unsigned long irq_mask, delay;
+ const u_char *depca_irq;
irq_mask = probe_irq_on();
@@ -770,6 +770,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
break;
default:
+ depca_irq = NULL;
break; /* Not reached */
}
@@ -1302,7 +1303,7 @@ static void SetMulticastFilter(struct net_device *dev)
}
}
-static int __init depca_common_init (u_long ioaddr, struct net_device **devp)
+static int __devinit depca_common_init (u_long ioaddr, struct net_device **devp)
{
int status = 0;
@@ -1333,7 +1334,7 @@ static int __init depca_common_init (u_long ioaddr, struct net_device **devp)
/*
** Microchannel bus I/O device probe
*/
-static int __init depca_mca_probe(struct device *device)
+static int __devinit depca_mca_probe(struct device *device)
{
unsigned char pos[2];
unsigned char where;
@@ -1457,7 +1458,7 @@ static int __init depca_mca_probe(struct device *device)
** ISA bus I/O device probe
*/
-static void __init depca_platform_probe (void)
+static void __devinit depca_platform_probe (void)
{
int i;
struct platform_device *pldev;
@@ -1497,7 +1498,7 @@ static void __init depca_platform_probe (void)
}
}
-static enum depca_type __init depca_shmem_probe (ulong *mem_start)
+static enum depca_type __devinit depca_shmem_probe (ulong *mem_start)
{
u_long mem_base[] = DEPCA_RAM_BASE_ADDRESSES;
enum depca_type adapter = unknown;
@@ -1558,7 +1559,7 @@ static int __devinit depca_isa_probe (struct platform_device *device)
*/
#ifdef CONFIG_EISA
-static int __init depca_eisa_probe (struct device *device)
+static int __devinit depca_eisa_probe (struct device *device)
{
enum depca_type adapter = unknown;
struct eisa_device *edev;
@@ -1629,7 +1630,7 @@ static int __devexit depca_device_remove (struct device *device)
** and Boot (readb) ROM. This will also give us a clue to the network RAM
** base address.
*/
-static int __init DepcaSignature(char *name, u_long base_addr)
+static int __devinit DepcaSignature(char *name, u_long base_addr)
{
u_int i, j, k;
void __iomem *ptr;
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index c05db604605..c445457b66d 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -1189,10 +1189,10 @@ static int rio_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->transceiver = XCVR_INTERNAL;
}
if ( np->link_status ) {
- cmd->speed = np->speed;
+ ethtool_cmd_speed_set(cmd, np->speed);
cmd->duplex = np->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
} else {
- cmd->speed = -1;
+ ethtool_cmd_speed_set(cmd, -1);
cmd->duplex = -1;
}
if ( np->an_enable)
@@ -1219,31 +1219,20 @@ static int rio_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
} else {
np->an_enable = 0;
if (np->speed == 1000) {
- cmd->speed = SPEED_100;
+ ethtool_cmd_speed_set(cmd, SPEED_100);
cmd->duplex = DUPLEX_FULL;
printk("Warning!! Can't disable Auto negotiation in 1000Mbps, change to Manual 100Mbps, Full duplex.\n");
}
- switch(cmd->speed + cmd->duplex) {
-
- case SPEED_10 + DUPLEX_HALF:
- np->speed = 10;
- np->full_duplex = 0;
- break;
-
- case SPEED_10 + DUPLEX_FULL:
+ switch (ethtool_cmd_speed(cmd)) {
+ case SPEED_10:
np->speed = 10;
- np->full_duplex = 1;
+ np->full_duplex = (cmd->duplex == DUPLEX_FULL);
break;
- case SPEED_100 + DUPLEX_HALF:
+ case SPEED_100:
np->speed = 100;
- np->full_duplex = 0;
- break;
- case SPEED_100 + DUPLEX_FULL:
- np->speed = 100;
- np->full_duplex = 1;
+ np->full_duplex = (cmd->duplex == DUPLEX_FULL);
break;
- case SPEED_1000 + DUPLEX_HALF:/* not supported */
- case SPEED_1000 + DUPLEX_FULL:/* not supported */
+ case SPEED_1000: /* not supported */
default:
return -EINVAL;
}
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index b7af5bab993..fbaff3584bd 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -131,8 +131,6 @@ typedef struct board_info {
u32 msg_enable;
u32 wake_state;
- int rx_csum;
- int can_csum;
int ip_summed;
} board_info_t;
@@ -470,47 +468,20 @@ static int dm9000_nway_reset(struct net_device *dev)
return mii_nway_restart(&dm->mii);
}
-static uint32_t dm9000_get_rx_csum(struct net_device *dev)
+static int dm9000_set_features(struct net_device *dev, u32 features)
{
board_info_t *dm = to_dm9000_board(dev);
- return dm->rx_csum;
-}
-
-static int dm9000_set_rx_csum_unlocked(struct net_device *dev, uint32_t data)
-{
- board_info_t *dm = to_dm9000_board(dev);
-
- if (dm->can_csum) {
- dm->rx_csum = data;
- iow(dm, DM9000_RCSR, dm->rx_csum ? RCSR_CSUM : 0);
+ u32 changed = dev->features ^ features;
+ unsigned long flags;
+ if (!(changed & NETIF_F_RXCSUM))
return 0;
- }
-
- return -EOPNOTSUPP;
-}
-
-static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data)
-{
- board_info_t *dm = to_dm9000_board(dev);
- unsigned long flags;
- int ret;
spin_lock_irqsave(&dm->lock, flags);
- ret = dm9000_set_rx_csum_unlocked(dev, data);
+ iow(dm, DM9000_RCSR, (features & NETIF_F_RXCSUM) ? RCSR_CSUM : 0);
spin_unlock_irqrestore(&dm->lock, flags);
- return ret;
-}
-
-static int dm9000_set_tx_csum(struct net_device *dev, uint32_t data)
-{
- board_info_t *dm = to_dm9000_board(dev);
- int ret = -EOPNOTSUPP;
-
- if (dm->can_csum)
- ret = ethtool_op_set_tx_csum(dev, data);
- return ret;
+ return 0;
}
static u32 dm9000_get_link(struct net_device *dev)
@@ -643,10 +614,6 @@ static const struct ethtool_ops dm9000_ethtool_ops = {
.get_eeprom_len = dm9000_get_eeprom_len,
.get_eeprom = dm9000_get_eeprom,
.set_eeprom = dm9000_set_eeprom,
- .get_rx_csum = dm9000_get_rx_csum,
- .set_rx_csum = dm9000_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = dm9000_set_tx_csum,
};
static void dm9000_show_carrier(board_info_t *db,
@@ -800,7 +767,9 @@ dm9000_init_dm9000(struct net_device *dev)
db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */
/* Checksum mode */
- dm9000_set_rx_csum_unlocked(dev, db->rx_csum);
+ if (dev->hw_features & NETIF_F_RXCSUM)
+ iow(db, DM9000_RCSR,
+ (dev->features & NETIF_F_RXCSUM) ? RCSR_CSUM : 0);
iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */
@@ -1049,7 +1018,7 @@ dm9000_rx(struct net_device *dev)
/* Pass to upper layer */
skb->protocol = eth_type_trans(skb, dev);
- if (db->rx_csum) {
+ if (dev->features & NETIF_F_RXCSUM) {
if ((((rxbyte & 0x1c) << 3) & rxbyte) == 0)
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
@@ -1358,6 +1327,7 @@ static const struct net_device_ops dm9000_netdev_ops = {
.ndo_set_multicast_list = dm9000_hash_table,
.ndo_do_ioctl = dm9000_ioctl,
.ndo_change_mtu = eth_change_mtu,
+ .ndo_set_features = dm9000_set_features,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = eth_mac_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1551,9 +1521,8 @@ dm9000_probe(struct platform_device *pdev)
/* dm9000a/b are capable of hardware checksum offload */
if (db->type == TYPE_DM9000A || db->type == TYPE_DM9000B) {
- db->can_csum = 1;
- db->rx_csum = 1;
- ndev->features |= NETIF_F_IP_CSUM;
+ ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
+ ndev->features |= ndev->hw_features;
}
/* from this point we assume that we have found a DM9000 */
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index ff2d29b1785..39cf9b9bd67 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -168,10 +168,6 @@ static int __init dummy_init_one(void)
if (!dev_dummy)
return -ENOMEM;
- err = dev_alloc_name(dev_dummy, dev_dummy->name);
- if (err < 0)
- goto err;
-
dev_dummy->rtnl_link_ops = &dummy_link_ops;
err = register_netdevice(dev_dummy);
if (err < 0)
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index b0aa9e68990..e336c7937f0 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -593,7 +593,6 @@ struct nic {
enum phy phy;
struct params params;
struct timer_list watchdog;
- struct timer_list blink_timer;
struct mii_if_info mii;
struct work_struct tx_timeout_task;
enum loopback loopback;
@@ -618,7 +617,6 @@ struct nic {
u32 rx_tco_frames;
u32 rx_over_length_errors;
- u16 leds;
u16 eeprom_wc;
__le16 eeprom[256];
spinlock_t mdio_lock;
@@ -1512,7 +1510,7 @@ static int e100_phy_init(struct nic *nic)
static int e100_hw_init(struct nic *nic)
{
- int err;
+ int err = 0;
e100_hw_reset(nic);
@@ -1668,7 +1666,8 @@ static void e100_adjust_adaptive_ifs(struct nic *nic, int speed, int duplex)
static void e100_watchdog(unsigned long data)
{
struct nic *nic = (struct nic *)data;
- struct ethtool_cmd cmd;
+ struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
+ u32 speed;
netif_printk(nic, timer, KERN_DEBUG, nic->netdev,
"right now = %ld\n", jiffies);
@@ -1676,10 +1675,11 @@ static void e100_watchdog(unsigned long data)
/* mii library handles link maintenance tasks */
mii_ethtool_gset(&nic->mii, &cmd);
+ speed = ethtool_cmd_speed(&cmd);
if (mii_link_ok(&nic->mii) && !netif_carrier_ok(nic->netdev)) {
netdev_info(nic->netdev, "NIC Link is Up %u Mbps %s Duplex\n",
- cmd.speed == SPEED_100 ? 100 : 10,
+ speed == SPEED_100 ? 100 : 10,
cmd.duplex == DUPLEX_FULL ? "Full" : "Half");
} else if (!mii_link_ok(&nic->mii) && netif_carrier_ok(nic->netdev)) {
netdev_info(nic->netdev, "NIC Link is Down\n");
@@ -1698,13 +1698,13 @@ static void e100_watchdog(unsigned long data)
spin_unlock_irq(&nic->cmd_lock);
e100_update_stats(nic);
- e100_adjust_adaptive_ifs(nic, cmd.speed, cmd.duplex);
+ e100_adjust_adaptive_ifs(nic, speed, cmd.duplex);
if (nic->mac <= mac_82557_D100_C)
/* Issue a multicast command to workaround a 557 lock up */
e100_set_multicast_list(nic->netdev);
- if (nic->flags & ich && cmd.speed==SPEED_10 && cmd.duplex==DUPLEX_HALF)
+ if (nic->flags & ich && speed == SPEED_10 && cmd.duplex == DUPLEX_HALF)
/* Need SW workaround for ICH[x] 10Mbps/half duplex Tx hang. */
nic->flags |= ich_10h_workaround;
else
@@ -2351,30 +2351,6 @@ err_clean_rx:
#define E100_82552_LED_OVERRIDE 0x19
#define E100_82552_LED_ON 0x000F /* LEDTX and LED_RX both on */
#define E100_82552_LED_OFF 0x000A /* LEDTX and LED_RX both off */
-static void e100_blink_led(unsigned long data)
-{
- struct nic *nic = (struct nic *)data;
- enum led_state {
- led_on = 0x01,
- led_off = 0x04,
- led_on_559 = 0x05,
- led_on_557 = 0x07,
- };
- u16 led_reg = MII_LED_CONTROL;
-
- if (nic->phy == phy_82552_v) {
- led_reg = E100_82552_LED_OVERRIDE;
-
- nic->leds = (nic->leds == E100_82552_LED_ON) ?
- E100_82552_LED_OFF : E100_82552_LED_ON;
- } else {
- nic->leds = (nic->leds & led_on) ? led_off :
- (nic->mac < mac_82559_D101M) ? led_on_557 :
- led_on_559;
- }
- mdio_write(nic->netdev, nic->mii.phy_id, led_reg, nic->leds);
- mod_timer(&nic->blink_timer, jiffies + HZ / 4);
-}
static int e100_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
{
@@ -2598,19 +2574,38 @@ static void e100_diag_test(struct net_device *netdev,
msleep_interruptible(4 * 1000);
}
-static int e100_phys_id(struct net_device *netdev, u32 data)
+static int e100_set_phys_id(struct net_device *netdev,
+ enum ethtool_phys_id_state state)
{
struct nic *nic = netdev_priv(netdev);
+ enum led_state {
+ led_on = 0x01,
+ led_off = 0x04,
+ led_on_559 = 0x05,
+ led_on_557 = 0x07,
+ };
u16 led_reg = (nic->phy == phy_82552_v) ? E100_82552_LED_OVERRIDE :
- MII_LED_CONTROL;
+ MII_LED_CONTROL;
+ u16 leds = 0;
- if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
- data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
- mod_timer(&nic->blink_timer, jiffies);
- msleep_interruptible(data * 1000);
- del_timer_sync(&nic->blink_timer);
- mdio_write(netdev, nic->mii.phy_id, led_reg, 0);
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ return 2;
+
+ case ETHTOOL_ID_ON:
+ leds = (nic->phy == phy_82552_v) ? E100_82552_LED_ON :
+ (nic->mac < mac_82559_D101M) ? led_on_557 : led_on_559;
+ break;
+
+ case ETHTOOL_ID_OFF:
+ leds = (nic->phy == phy_82552_v) ? E100_82552_LED_OFF : led_off;
+ break;
+
+ case ETHTOOL_ID_INACTIVE:
+ break;
+ }
+ mdio_write(netdev, nic->mii.phy_id, led_reg, leds);
return 0;
}
@@ -2691,7 +2686,7 @@ static const struct ethtool_ops e100_ethtool_ops = {
.set_ringparam = e100_set_ringparam,
.self_test = e100_diag_test,
.get_strings = e100_get_strings,
- .phys_id = e100_phys_id,
+ .set_phys_id = e100_set_phys_id,
.get_ethtool_stats = e100_get_ethtool_stats,
.get_sset_count = e100_get_sset_count,
};
@@ -2832,9 +2827,6 @@ static int __devinit e100_probe(struct pci_dev *pdev,
init_timer(&nic->watchdog);
nic->watchdog.function = e100_watchdog;
nic->watchdog.data = (unsigned long)nic;
- init_timer(&nic->blink_timer);
- nic->blink_timer.function = e100_blink_led;
- nic->blink_timer.data = (unsigned long)nic;
INIT_WORK(&nic->tx_timeout_task, e100_tx_timeout_task);
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index a881dd0093b..8676899120c 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -238,9 +238,6 @@ struct e1000_adapter {
struct work_struct reset_task;
u8 fc_autoneg;
- struct timer_list blink_timer;
- unsigned long led_status;
-
/* TX */
struct e1000_tx_ring *tx_ring; /* One per active queue */
unsigned int restart_queue;
@@ -349,7 +346,7 @@ extern int e1000_up(struct e1000_adapter *adapter);
extern void e1000_down(struct e1000_adapter *adapter);
extern void e1000_reinit_locked(struct e1000_adapter *adapter);
extern void e1000_reset(struct e1000_adapter *adapter);
-extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
+extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx);
extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index dd70738eb2f..ec0fa426cce 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -158,7 +158,7 @@ static int e1000_get_settings(struct net_device *netdev,
e1000_get_speed_and_duplex(hw, &adapter->link_speed,
&adapter->link_duplex);
- ecmd->speed = adapter->link_speed;
+ ethtool_cmd_speed_set(ecmd, adapter->link_speed);
/* unfortunately FULL_DUPLEX != DUPLEX_FULL
* and HALF_DUPLEX != DUPLEX_HALF */
@@ -168,7 +168,7 @@ static int e1000_get_settings(struct net_device *netdev,
else
ecmd->duplex = DUPLEX_HALF;
} else {
- ecmd->speed = -1;
+ ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1;
}
@@ -197,11 +197,13 @@ static int e1000_set_settings(struct net_device *netdev,
ADVERTISED_TP |
ADVERTISED_Autoneg;
ecmd->advertising = hw->autoneg_advertised;
- } else
- if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
+ } else {
+ u32 speed = ethtool_cmd_speed(ecmd);
+ if (e1000_set_spd_dplx(adapter, speed, ecmd->duplex)) {
clear_bit(__E1000_RESETTING, &adapter->flags);
return -EINVAL;
}
+ }
/* reset the link */
@@ -1753,46 +1755,28 @@ static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
return 0;
}
-/* toggle LED 4 times per second = 2 "blinks" per second */
-#define E1000_ID_INTERVAL (HZ/4)
-
-/* bit defines for adapter->led_status */
-#define E1000_LED_ON 0
-
-static void e1000_led_blink_callback(unsigned long data)
+static int e1000_set_phys_id(struct net_device *netdev,
+ enum ethtool_phys_id_state state)
{
- struct e1000_adapter *adapter = (struct e1000_adapter *) data;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- if (test_and_change_bit(E1000_LED_ON, &adapter->led_status))
- e1000_led_off(hw);
- else
- e1000_led_on(hw);
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ e1000_setup_led(hw);
+ return 2;
- mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL);
-}
-
-static int e1000_phys_id(struct net_device *netdev, u32 data)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
+ case ETHTOOL_ID_ON:
+ e1000_led_on(hw);
+ break;
- if (!data)
- data = INT_MAX;
+ case ETHTOOL_ID_OFF:
+ e1000_led_off(hw);
+ break;
- if (!adapter->blink_timer.function) {
- init_timer(&adapter->blink_timer);
- adapter->blink_timer.function = e1000_led_blink_callback;
- adapter->blink_timer.data = (unsigned long)adapter;
+ case ETHTOOL_ID_INACTIVE:
+ e1000_cleanup_led(hw);
}
- e1000_setup_led(hw);
- mod_timer(&adapter->blink_timer, jiffies);
- msleep_interruptible(data * 1000);
- del_timer_sync(&adapter->blink_timer);
-
- e1000_led_off(hw);
- clear_bit(E1000_LED_ON, &adapter->led_status);
- e1000_cleanup_led(hw);
return 0;
}
@@ -1929,7 +1913,7 @@ static const struct ethtool_ops e1000_ethtool_ops = {
.set_tso = e1000_set_tso,
.self_test = e1000_diag_test,
.get_strings = e1000_get_strings,
- .phys_id = e1000_phys_id,
+ .set_phys_id = e1000_set_phys_id,
.get_ethtool_stats = e1000_get_ethtool_stats,
.get_sset_count = e1000_get_sset_count,
.get_coalesce = e1000_get_coalesce,
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 477e066a1cf..c18cb8e883d 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -96,7 +96,6 @@ int e1000_up(struct e1000_adapter *adapter);
void e1000_down(struct e1000_adapter *adapter);
void e1000_reinit_locked(struct e1000_adapter *adapter);
void e1000_reset(struct e1000_adapter *adapter);
-int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
@@ -4385,7 +4384,6 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
struct mii_ioctl_data *data = if_mii(ifr);
int retval;
u16 mii_reg;
- u16 spddplx;
unsigned long flags;
if (hw->media_type != e1000_media_type_copper)
@@ -4424,17 +4422,18 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
hw->autoneg = 1;
hw->autoneg_advertised = 0x2F;
} else {
+ u32 speed;
if (mii_reg & 0x40)
- spddplx = SPEED_1000;
+ speed = SPEED_1000;
else if (mii_reg & 0x2000)
- spddplx = SPEED_100;
+ speed = SPEED_100;
else
- spddplx = SPEED_10;
- spddplx += (mii_reg & 0x100)
- ? DUPLEX_FULL :
- DUPLEX_HALF;
- retval = e1000_set_spd_dplx(adapter,
- spddplx);
+ speed = SPEED_10;
+ retval = e1000_set_spd_dplx(
+ adapter, speed,
+ ((mii_reg & 0x100)
+ ? DUPLEX_FULL :
+ DUPLEX_HALF));
if (retval)
return retval;
}
@@ -4596,20 +4595,24 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter)
}
}
-int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
+int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
{
struct e1000_hw *hw = &adapter->hw;
hw->autoneg = 0;
+ /* Make sure dplx is at most 1 bit and lsb of speed is not set
+ * for the switch() below to work */
+ if ((spd & 1) || (dplx & ~1))
+ goto err_inval;
+
/* Fiber NICs only allow 1000 gbps Full duplex */
if ((hw->media_type == e1000_media_type_fiber) &&
- spddplx != (SPEED_1000 + DUPLEX_FULL)) {
- e_err(probe, "Unsupported Speed/Duplex configuration\n");
- return -EINVAL;
- }
+ spd != SPEED_1000 &&
+ dplx != DUPLEX_FULL)
+ goto err_inval;
- switch (spddplx) {
+ switch (spd + dplx) {
case SPEED_10 + DUPLEX_HALF:
hw->forced_speed_duplex = e1000_10_half;
break;
@@ -4628,10 +4631,13 @@ int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
break;
case SPEED_1000 + DUPLEX_HALF: /* not supported */
default:
- e_err(probe, "Unsupported Speed/Duplex configuration\n");
- return -EINVAL;
+ goto err_inval;
}
return 0;
+
+err_inval:
+ e_err(probe, "Unsupported Speed/Duplex configuration\n");
+ return -EINVAL;
}
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 89a69035e53..8295f219243 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -300,6 +300,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
func->set_lan_id = e1000_set_lan_id_single_port;
func->check_mng_mode = e1000e_check_mng_mode_generic;
func->led_on = e1000e_led_on_generic;
+ func->blink_led = e1000e_blink_led_generic;
/* FWSM register */
mac->has_fwsm = true;
@@ -320,6 +321,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
default:
func->check_mng_mode = e1000e_check_mng_mode_generic;
func->led_on = e1000e_led_on_generic;
+ func->blink_led = e1000e_blink_led_generic;
/* FWSM register */
mac->has_fwsm = true;
@@ -431,9 +433,6 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
case e1000_82573:
case e1000_82574:
case e1000_82583:
- /* Disable ASPM L0s due to hardware errata */
- e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L0S);
-
if (pdev->device == E1000_DEV_ID_82573L) {
adapter->flags |= FLAG_HAS_JUMBO_FRAMES;
adapter->max_hw_frame_size = DEFAULT_JUMBO;
@@ -594,7 +593,7 @@ static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw)
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
- msleep(2);
+ usleep_range(2000, 4000);
i++;
} while (i < MDIO_OWNERSHIP_TIMEOUT);
@@ -816,7 +815,7 @@ static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw)
/* Check for pending operations. */
for (i = 0; i < E1000_FLASH_UPDATES; i++) {
- msleep(1);
+ usleep_range(1000, 2000);
if ((er32(EECD) & E1000_EECD_FLUPD) == 0)
break;
}
@@ -840,7 +839,7 @@ static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw)
ew32(EECD, eecd);
for (i = 0; i < E1000_FLASH_UPDATES; i++) {
- msleep(1);
+ usleep_range(1000, 2000);
if ((er32(EECD) & E1000_EECD_FLUPD) == 0)
break;
}
@@ -930,7 +929,7 @@ static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw)
if (er32(EEMNGCTL) &
E1000_NVM_CFG_DONE_PORT_0)
break;
- msleep(1);
+ usleep_range(1000, 2000);
timeout--;
}
if (!timeout) {
@@ -1037,7 +1036,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
ew32(TCTL, E1000_TCTL_PSP);
e1e_flush();
- msleep(10);
+ usleep_range(10000, 20000);
/*
* Must acquire the MDIO ownership before MAC reset.
@@ -2066,7 +2065,8 @@ struct e1000_info e1000_82573_info = {
| FLAG_HAS_SMART_POWER_DOWN
| FLAG_HAS_AMT
| FLAG_HAS_SWSM_ON_LOAD,
- .flags2 = FLAG2_DISABLE_ASPM_L1,
+ .flags2 = FLAG2_DISABLE_ASPM_L1
+ | FLAG2_DISABLE_ASPM_L0S,
.pba = 20,
.max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
.get_variants = e1000_get_variants_82571,
@@ -2086,7 +2086,8 @@ struct e1000_info e1000_82574_info = {
| FLAG_HAS_SMART_POWER_DOWN
| FLAG_HAS_AMT
| FLAG_HAS_CTRLEXT_ON_LOAD,
- .flags2 = FLAG2_CHECK_PHY_HANG,
+ .flags2 = FLAG2_CHECK_PHY_HANG
+ | FLAG2_DISABLE_ASPM_L0S,
.pba = 32,
.max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_82571,
@@ -2104,6 +2105,7 @@ struct e1000_info e1000_82583_info = {
| FLAG_HAS_SMART_POWER_DOWN
| FLAG_HAS_AMT
| FLAG_HAS_CTRLEXT_ON_LOAD,
+ .flags2 = FLAG2_DISABLE_ASPM_L0S,
.pba = 32,
.max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
.get_variants = e1000_get_variants_82571,
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 00bf595ebd6..9549879e66a 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -31,6 +31,7 @@
#ifndef _E1000_H_
#define _E1000_H_
+#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
@@ -39,6 +40,7 @@
#include <linux/pci.h>
#include <linux/pci-aspm.h>
#include <linux/crc32.h>
+#include <linux/if_vlan.h>
#include "hw.h"
@@ -280,7 +282,7 @@ struct e1000_adapter {
const struct e1000_info *ei;
- struct vlan_group *vlgrp;
+ unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
u32 bd_number;
u32 rx_buffer_len;
u16 mng_vlan_id;
@@ -389,13 +391,10 @@ struct e1000_adapter {
bool fc_autoneg;
- unsigned long led_status;
-
unsigned int flags;
unsigned int flags2;
struct work_struct downshift_task;
struct work_struct update_phy_task;
- struct work_struct led_blink_task;
struct work_struct print_hang_task;
bool idle_check;
@@ -456,6 +455,7 @@ struct e1000_info {
#define FLAG2_HAS_PHY_STATS (1 << 4)
#define FLAG2_HAS_EEE (1 << 5)
#define FLAG2_DMA_BURST (1 << 6)
+#define FLAG2_DISABLE_ASPM_L0S (1 << 7)
#define FLAG2_DISABLE_AIM (1 << 8)
#define FLAG2_CHECK_PHY_HANG (1 << 9)
@@ -484,7 +484,6 @@ extern const char e1000e_driver_version[];
extern void e1000e_check_options(struct e1000_adapter *adapter);
extern void e1000e_set_ethtool_ops(struct net_device *netdev);
-extern void e1000e_led_blink_task(struct work_struct *work);
extern int e1000e_up(struct e1000_adapter *adapter);
extern void e1000e_down(struct e1000_adapter *adapter);
@@ -502,7 +501,6 @@ extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter);
extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);
extern void e1000e_get_hw_control(struct e1000_adapter *adapter);
extern void e1000e_release_hw_control(struct e1000_adapter *adapter);
-extern void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
extern unsigned int copybreak;
@@ -573,7 +571,7 @@ extern s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data);
extern void e1000e_config_collision_dist(struct e1000_hw *hw);
extern s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw);
extern s32 e1000e_force_mac_fc(struct e1000_hw *hw);
-extern s32 e1000e_blink_led(struct e1000_hw *hw);
+extern s32 e1000e_blink_led_generic(struct e1000_hw *hw);
extern void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
extern s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw);
extern void e1000e_reset_adaptive(struct e1000_hw *hw);
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
index 2fefa820302..f4bbeb22f51 100644
--- a/drivers/net/e1000e/es2lan.c
+++ b/drivers/net/e1000e/es2lan.c
@@ -612,7 +612,7 @@ static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw)
while (timeout) {
if (er32(EEMNGCTL) & mask)
break;
- msleep(1);
+ usleep_range(1000, 2000);
timeout--;
}
if (!timeout) {
@@ -802,7 +802,7 @@ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw)
ew32(TCTL, E1000_TCTL_PSP);
e1e_flush();
- msleep(10);
+ usleep_range(10000, 20000);
ctrl = er32(CTRL);
@@ -1434,6 +1434,7 @@ static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw)
static struct e1000_mac_operations es2_mac_ops = {
.read_mac_addr = e1000_read_mac_addr_80003es2lan,
.id_led_init = e1000e_id_led_init,
+ .blink_led = e1000e_blink_led_generic,
.check_mng_mode = e1000e_check_mng_mode_generic,
/* check_for_link dependent on media type */
.cleanup_led = e1000e_cleanup_led_generic,
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 07f09e96e45..859d0d3af6c 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -122,6 +122,7 @@ static int e1000_get_settings(struct net_device *netdev,
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ u32 speed;
if (hw->phy.media_type == e1000_media_type_copper) {
@@ -159,23 +160,23 @@ static int e1000_get_settings(struct net_device *netdev,
ecmd->transceiver = XCVR_EXTERNAL;
}
- ecmd->speed = -1;
+ speed = -1;
ecmd->duplex = -1;
if (netif_running(netdev)) {
if (netif_carrier_ok(netdev)) {
- ecmd->speed = adapter->link_speed;
+ speed = adapter->link_speed;
ecmd->duplex = adapter->link_duplex - 1;
}
} else {
u32 status = er32(STATUS);
if (status & E1000_STATUS_LU) {
if (status & E1000_STATUS_SPEED_1000)
- ecmd->speed = 1000;
+ speed = SPEED_1000;
else if (status & E1000_STATUS_SPEED_100)
- ecmd->speed = 100;
+ speed = SPEED_100;
else
- ecmd->speed = 10;
+ speed = SPEED_10;
if (status & E1000_STATUS_FD)
ecmd->duplex = DUPLEX_FULL;
@@ -184,6 +185,7 @@ static int e1000_get_settings(struct net_device *netdev,
}
}
+ ethtool_cmd_speed_set(ecmd, speed);
ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) ||
hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
@@ -198,20 +200,25 @@ static int e1000_get_settings(struct net_device *netdev,
return 0;
}
-static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
+static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
{
struct e1000_mac_info *mac = &adapter->hw.mac;
mac->autoneg = 0;
+ /* Make sure dplx is at most 1 bit and lsb of speed is not set
+ * for the switch() below to work */
+ if ((spd & 1) || (dplx & ~1))
+ goto err_inval;
+
/* Fiber NICs only allow 1000 gbps Full duplex */
if ((adapter->hw.phy.media_type == e1000_media_type_fiber) &&
- spddplx != (SPEED_1000 + DUPLEX_FULL)) {
- e_err("Unsupported Speed/Duplex configuration\n");
- return -EINVAL;
+ spd != SPEED_1000 &&
+ dplx != DUPLEX_FULL) {
+ goto err_inval;
}
- switch (spddplx) {
+ switch (spd + dplx) {
case SPEED_10 + DUPLEX_HALF:
mac->forced_speed_duplex = ADVERTISE_10_HALF;
break;
@@ -230,10 +237,13 @@ static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
break;
case SPEED_1000 + DUPLEX_HALF: /* not supported */
default:
- e_err("Unsupported Speed/Duplex configuration\n");
- return -EINVAL;
+ goto err_inval;
}
return 0;
+
+err_inval:
+ e_err("Unsupported Speed/Duplex configuration\n");
+ return -EINVAL;
}
static int e1000_set_settings(struct net_device *netdev,
@@ -253,7 +263,7 @@ static int e1000_set_settings(struct net_device *netdev,
}
while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
if (ecmd->autoneg == AUTONEG_ENABLE) {
hw->mac.autoneg = 1;
@@ -269,7 +279,8 @@ static int e1000_set_settings(struct net_device *netdev,
if (adapter->fc_autoneg)
hw->fc.requested_mode = e1000_fc_default;
} else {
- if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
+ u32 speed = ethtool_cmd_speed(ecmd);
+ if (e1000_set_spd_dplx(adapter, speed, ecmd->duplex)) {
clear_bit(__E1000_RESETTING, &adapter->state);
return -EINVAL;
}
@@ -317,7 +328,7 @@ static int e1000_set_pauseparam(struct net_device *netdev,
adapter->fc_autoneg = pause->autoneg;
while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
if (adapter->fc_autoneg == AUTONEG_ENABLE) {
hw->fc.requested_mode = e1000_fc_default;
@@ -673,7 +684,7 @@ static int e1000_set_ringparam(struct net_device *netdev,
return -EINVAL;
while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
if (netif_running(adapter->netdev))
e1000e_down(adapter);
@@ -952,7 +963,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
/* Disable all the interrupts */
ew32(IMC, 0xFFFFFFFF);
- msleep(10);
+ usleep_range(10000, 20000);
/* Test each interrupt */
for (i = 0; i < 10; i++) {
@@ -984,7 +995,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
adapter->test_icr = 0;
ew32(IMC, mask);
ew32(ICS, mask);
- msleep(10);
+ usleep_range(10000, 20000);
if (adapter->test_icr & mask) {
*data = 3;
@@ -1002,7 +1013,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
adapter->test_icr = 0;
ew32(IMS, mask);
ew32(ICS, mask);
- msleep(10);
+ usleep_range(10000, 20000);
if (!(adapter->test_icr & mask)) {
*data = 4;
@@ -1020,7 +1031,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
adapter->test_icr = 0;
ew32(IMC, ~mask & 0x00007FFF);
ew32(ICS, ~mask & 0x00007FFF);
- msleep(10);
+ usleep_range(10000, 20000);
if (adapter->test_icr) {
*data = 5;
@@ -1031,7 +1042,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
/* Disable all the interrupts */
ew32(IMC, 0xFFFFFFFF);
- msleep(10);
+ usleep_range(10000, 20000);
/* Unhook test interrupt handler */
free_irq(irq, netdev);
@@ -1406,7 +1417,7 @@ static int e1000_set_82571_fiber_loopback(struct e1000_adapter *adapter)
*/
#define E1000_SERDES_LB_ON 0x410
ew32(SCTL, E1000_SERDES_LB_ON);
- msleep(10);
+ usleep_range(10000, 20000);
return 0;
}
@@ -1501,7 +1512,7 @@ static void e1000_loopback_cleanup(struct e1000_adapter *adapter)
hw->phy.media_type == e1000_media_type_internal_serdes) {
#define E1000_SERDES_LB_OFF 0x400
ew32(SCTL, E1000_SERDES_LB_OFF);
- msleep(10);
+ usleep_range(10000, 20000);
break;
}
/* Fall Through */
@@ -1851,64 +1862,35 @@ static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
return 0;
}
-/* toggle LED 4 times per second = 2 "blinks" per second */
-#define E1000_ID_INTERVAL (HZ/4)
-
-/* bit defines for adapter->led_status */
-#define E1000_LED_ON 0
-
-void e1000e_led_blink_task(struct work_struct *work)
-{
- struct e1000_adapter *adapter = container_of(work,
- struct e1000_adapter, led_blink_task);
-
- if (test_and_change_bit(E1000_LED_ON, &adapter->led_status))
- adapter->hw.mac.ops.led_off(&adapter->hw);
- else
- adapter->hw.mac.ops.led_on(&adapter->hw);
-}
-
-static void e1000_led_blink_callback(unsigned long data)
-{
- struct e1000_adapter *adapter = (struct e1000_adapter *) data;
-
- schedule_work(&adapter->led_blink_task);
- mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL);
-}
-
-static int e1000_phys_id(struct net_device *netdev, u32 data)
+static int e1000_set_phys_id(struct net_device *netdev,
+ enum ethtool_phys_id_state state)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- if (!data)
- data = INT_MAX;
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ if (!hw->mac.ops.blink_led)
+ return 2; /* cycle on/off twice per second */
- if ((hw->phy.type == e1000_phy_ife) ||
- (hw->mac.type == e1000_pchlan) ||
- (hw->mac.type == e1000_pch2lan) ||
- (hw->mac.type == e1000_82583) ||
- (hw->mac.type == e1000_82574)) {
- if (!adapter->blink_timer.function) {
- init_timer(&adapter->blink_timer);
- adapter->blink_timer.function =
- e1000_led_blink_callback;
- adapter->blink_timer.data = (unsigned long) adapter;
- }
- mod_timer(&adapter->blink_timer, jiffies);
- msleep_interruptible(data * 1000);
- del_timer_sync(&adapter->blink_timer);
+ hw->mac.ops.blink_led(hw);
+ break;
+
+ case ETHTOOL_ID_INACTIVE:
if (hw->phy.type == e1000_phy_ife)
e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0);
- } else {
- e1000e_blink_led(hw);
- msleep_interruptible(data * 1000);
- }
+ hw->mac.ops.led_off(hw);
+ hw->mac.ops.cleanup_led(hw);
+ break;
- hw->mac.ops.led_off(hw);
- clear_bit(E1000_LED_ON, &adapter->led_status);
- hw->mac.ops.cleanup_led(hw);
+ case ETHTOOL_ID_ON:
+ adapter->hw.mac.ops.led_on(&adapter->hw);
+ break;
+ case ETHTOOL_ID_OFF:
+ adapter->hw.mac.ops.led_off(&adapter->hw);
+ break;
+ }
return 0;
}
@@ -2020,6 +2002,31 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset,
}
}
+static int e1000e_set_flags(struct net_device *netdev, u32 data)
+{
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+ bool need_reset = false;
+ int rc;
+
+ need_reset = (data & ETH_FLAG_RXVLAN) !=
+ (netdev->features & NETIF_F_HW_VLAN_RX);
+
+ rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_RXVLAN |
+ ETH_FLAG_TXVLAN);
+
+ if (rc)
+ return rc;
+
+ if (need_reset) {
+ if (netif_running(netdev))
+ e1000e_reinit_locked(adapter);
+ else
+ e1000e_reset(adapter);
+ }
+
+ return 0;
+}
+
static const struct ethtool_ops e1000_ethtool_ops = {
.get_settings = e1000_get_settings,
.set_settings = e1000_set_settings,
@@ -2049,12 +2056,13 @@ static const struct ethtool_ops e1000_ethtool_ops = {
.set_tso = e1000_set_tso,
.self_test = e1000_diag_test,
.get_strings = e1000_get_strings,
- .phys_id = e1000_phys_id,
+ .set_phys_id = e1000_set_phys_id,
.get_ethtool_stats = e1000_get_ethtool_stats,
.get_sset_count = e1000e_get_sset_count,
.get_coalesce = e1000_get_coalesce,
.set_coalesce = e1000_set_coalesce,
.get_flags = ethtool_op_get_flags,
+ .set_flags = e1000e_set_flags,
};
void e1000e_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 307e1ec2241..6c2fa8327f5 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -756,6 +756,7 @@ struct e1000_host_mng_command_info {
/* Function pointers and static data for the MAC. */
struct e1000_mac_operations {
s32 (*id_led_init)(struct e1000_hw *);
+ s32 (*blink_led)(struct e1000_hw *);
bool (*check_mng_mode)(struct e1000_hw *);
s32 (*check_for_link)(struct e1000_hw *);
s32 (*cleanup_led)(struct e1000_hw *);
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index ce1dbfdca11..3369d1f6a39 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -338,7 +338,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
/* Ungate automatic PHY configuration on non-managed 82579 */
if ((hw->mac.type == e1000_pch2lan) &&
!(fwsm & E1000_ICH_FWSM_FW_VALID)) {
- msleep(10);
+ usleep_range(10000, 20000);
e1000_gate_hw_phy_config_ich8lan(hw, false);
}
@@ -427,7 +427,7 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
phy->id = 0;
while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) &&
(i++ < 100)) {
- msleep(1);
+ usleep_range(1000, 2000);
ret_val = e1000e_get_phy_id(hw);
if (ret_val)
return ret_val;
@@ -564,6 +564,8 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
mac->ops.check_mng_mode = e1000_check_mng_mode_ich8lan;
/* ID LED init */
mac->ops.id_led_init = e1000e_id_led_init;
+ /* blink LED */
+ mac->ops.blink_led = e1000e_blink_led_generic;
/* setup LED */
mac->ops.setup_led = e1000e_setup_led_generic;
/* cleanup LED */
@@ -767,6 +769,8 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
(!(er32(CTRL_EXT) & E1000_CTRL_EXT_LSECCK)))) {
adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
adapter->max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN;
+
+ hw->mac.ops.blink_led = NULL;
}
if ((adapter->hw.mac.type == e1000_ich8lan) &&
@@ -1704,7 +1708,7 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
goto out;
/* Allow time for h/w to get to quiescent state after reset */
- msleep(10);
+ usleep_range(10000, 20000);
/* Perform any necessary post-reset workarounds */
switch (hw->mac.type) {
@@ -1737,7 +1741,7 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
if (hw->mac.type == e1000_pch2lan) {
/* Ungate automatic PHY configuration on non-managed 82579 */
if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
- msleep(10);
+ usleep_range(10000, 20000);
e1000_gate_hw_phy_config_ich8lan(hw, false);
}
@@ -2532,7 +2536,7 @@ release:
*/
if (!ret_val) {
e1000e_reload_nvm(hw);
- msleep(10);
+ usleep_range(10000, 20000);
}
out:
@@ -3009,7 +3013,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
ew32(TCTL, E1000_TCTL_PSP);
e1e_flush();
- msleep(10);
+ usleep_range(10000, 20000);
/* Workaround for ICH8 bit corruption issue in FIFO memory */
if (hw->mac.type == e1000_ich8lan) {
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 96921de5df2..dd8ab05b559 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -144,7 +144,7 @@ void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value)
* @hw: pointer to the HW structure
* @rar_count: receive address registers
*
- * Setups the receive address registers by setting the base receive address
+ * Setup 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.
**/
@@ -868,7 +868,7 @@ static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
* milliseconds even if the other end is doing it in SW).
*/
for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
- msleep(10);
+ usleep_range(10000, 20000);
status = er32(STATUS);
if (status & E1000_STATUS_LU)
break;
@@ -930,7 +930,7 @@ s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw)
ew32(CTRL, ctrl);
e1e_flush();
- msleep(1);
+ usleep_range(1000, 2000);
/*
* For these adapters, the SW definable pin 1 is set when the optics
@@ -1181,7 +1181,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
* 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.
+ * turn OFF the TRANSMISSION of PAUSE frames.
*/
if (hw->fc.requested_mode == e1000_fc_full) {
hw->fc.current_mode = e1000_fc_full;
@@ -1385,7 +1385,7 @@ s32 e1000e_get_auto_rd_done(struct e1000_hw *hw)
while (i < AUTO_READ_DONE_TIMEOUT) {
if (er32(EECD) & E1000_EECD_AUTO_RD)
break;
- msleep(1);
+ usleep_range(1000, 2000);
i++;
}
@@ -1530,12 +1530,12 @@ s32 e1000e_cleanup_led_generic(struct e1000_hw *hw)
}
/**
- * e1000e_blink_led - Blink LED
+ * e1000e_blink_led_generic - Blink LED
* @hw: pointer to the HW structure
*
* Blink the LEDs which are set to be on.
**/
-s32 e1000e_blink_led(struct e1000_hw *hw)
+s32 e1000e_blink_led_generic(struct e1000_hw *hw)
{
u32 ledctl_blink = 0;
u32 i;
@@ -2087,8 +2087,6 @@ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
if (ret_val)
return ret_val;
- msleep(10);
-
while (widx < words) {
u8 write_opcode = NVM_WRITE_OPCODE_SPI;
@@ -2132,7 +2130,7 @@ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
}
}
- msleep(10);
+ usleep_range(10000, 20000);
nvm->ops.release(hw);
return 0;
}
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 506a0a0043b..0939040305f 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -58,6 +58,8 @@
char e1000e_driver_name[] = "e1000e";
const char e1000e_driver_version[] = DRV_VERSION;
+static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
+
static const struct e1000_info *e1000_info_tbl[] = {
[board_82571] = &e1000_82571_info,
[board_82572] = &e1000_82572_info,
@@ -459,13 +461,13 @@ static void e1000_receive_skb(struct e1000_adapter *adapter,
struct net_device *netdev, struct sk_buff *skb,
u8 status, __le16 vlan)
{
+ u16 tag = le16_to_cpu(vlan);
skb->protocol = eth_type_trans(skb, netdev);
- if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
- vlan_gro_receive(&adapter->napi, adapter->vlgrp,
- le16_to_cpu(vlan), skb);
- else
- napi_gro_receive(&adapter->napi, skb);
+ if (status & E1000_RXD_STAT_VP)
+ __vlan_hwaccel_put_tag(skb, tag);
+
+ napi_gro_receive(&adapter->napi, skb);
}
/**
@@ -2433,6 +2435,8 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
vfta |= (1 << (vid & 0x1F));
hw->mac.ops.write_vfta(hw, index, vfta);
}
+
+ set_bit(vid, adapter->active_vlans);
}
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
@@ -2441,13 +2445,6 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
struct e1000_hw *hw = &adapter->hw;
u32 vfta, index;
- if (!test_bit(__E1000_DOWN, &adapter->state))
- e1000_irq_disable(adapter);
- vlan_group_set_device(adapter->vlgrp, vid, NULL);
-
- if (!test_bit(__E1000_DOWN, &adapter->state))
- e1000_irq_enable(adapter);
-
if ((adapter->hw.mng_cookie.status &
E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
(vid == adapter->mng_vlan_id)) {
@@ -2463,93 +2460,105 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
vfta &= ~(1 << (vid & 0x1F));
hw->mac.ops.write_vfta(hw, index, vfta);
}
+
+ clear_bit(vid, adapter->active_vlans);
}
-static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
+/**
+ * e1000e_vlan_filter_disable - helper to disable hw VLAN filtering
+ * @adapter: board private structure to initialize
+ **/
+static void e1000e_vlan_filter_disable(struct e1000_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)
- return;
+ struct e1000_hw *hw = &adapter->hw;
+ u32 rctl;
- if (!vlan_group_get_device(adapter->vlgrp, vid)) {
- adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
- if (adapter->hw.mng_cookie.status &
- E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
- e1000_vlan_rx_add_vid(netdev, vid);
- adapter->mng_vlan_id = vid;
+ if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
+ /* disable VLAN receive filtering */
+ rctl = er32(RCTL);
+ rctl &= ~(E1000_RCTL_VFE | E1000_RCTL_CFIEN);
+ ew32(RCTL, rctl);
+
+ if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) {
+ e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
+ adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
}
-
- if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
- (vid != old_vid) &&
- !vlan_group_get_device(adapter->vlgrp, old_vid))
- e1000_vlan_rx_kill_vid(netdev, old_vid);
- } else {
- adapter->mng_vlan_id = vid;
}
}
+/**
+ * e1000e_vlan_filter_enable - helper to enable HW VLAN filtering
+ * @adapter: board private structure to initialize
+ **/
+static void e1000e_vlan_filter_enable(struct e1000_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 rctl;
-static void e1000_vlan_rx_register(struct net_device *netdev,
- struct vlan_group *grp)
+ if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
+ /* enable VLAN receive filtering */
+ rctl = er32(RCTL);
+ rctl |= E1000_RCTL_VFE;
+ rctl &= ~E1000_RCTL_CFIEN;
+ ew32(RCTL, rctl);
+ }
+}
+
+/**
+ * e1000e_vlan_strip_enable - helper to disable HW VLAN stripping
+ * @adapter: board private structure to initialize
+ **/
+static void e1000e_vlan_strip_disable(struct e1000_adapter *adapter)
{
- struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- u32 ctrl, rctl;
+ u32 ctrl;
- if (!test_bit(__E1000_DOWN, &adapter->state))
- e1000_irq_disable(adapter);
- adapter->vlgrp = grp;
+ /* disable VLAN tag insert/strip */
+ ctrl = er32(CTRL);
+ ctrl &= ~E1000_CTRL_VME;
+ ew32(CTRL, ctrl);
+}
- if (grp) {
- /* enable VLAN tag insert/strip */
- ctrl = er32(CTRL);
- ctrl |= E1000_CTRL_VME;
- ew32(CTRL, ctrl);
+/**
+ * e1000e_vlan_strip_enable - helper to enable HW VLAN stripping
+ * @adapter: board private structure to initialize
+ **/
+static void e1000e_vlan_strip_enable(struct e1000_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 ctrl;
- if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
- /* enable VLAN receive filtering */
- rctl = er32(RCTL);
- rctl &= ~E1000_RCTL_CFIEN;
- ew32(RCTL, rctl);
- e1000_update_mng_vlan(adapter);
- }
- } else {
- /* disable VLAN tag insert/strip */
- ctrl = er32(CTRL);
- ctrl &= ~E1000_CTRL_VME;
- ew32(CTRL, ctrl);
+ /* enable VLAN tag insert/strip */
+ ctrl = er32(CTRL);
+ ctrl |= E1000_CTRL_VME;
+ ew32(CTRL, ctrl);
+}
- if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
- if (adapter->mng_vlan_id !=
- (u16)E1000_MNG_VLAN_NONE) {
- e1000_vlan_rx_kill_vid(netdev,
- adapter->mng_vlan_id);
- adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
- }
- }
+static void e1000_update_mng_vlan(struct e1000_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->hw.mng_cookie.status &
+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
+ e1000_vlan_rx_add_vid(netdev, vid);
+ adapter->mng_vlan_id = vid;
}
- if (!test_bit(__E1000_DOWN, &adapter->state))
- e1000_irq_enable(adapter);
+ if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && (vid != old_vid))
+ e1000_vlan_rx_kill_vid(netdev, old_vid);
}
static void e1000_restore_vlan(struct e1000_adapter *adapter)
{
u16 vid;
- e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
-
- if (!adapter->vlgrp)
- return;
+ e1000_vlan_rx_add_vid(adapter->netdev, 0);
- for (vid = 0; vid < VLAN_N_VID; vid++) {
- if (!vlan_group_get_device(adapter->vlgrp, vid))
- continue;
+ for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
e1000_vlan_rx_add_vid(adapter->netdev, vid);
- }
}
static void e1000_init_manageability_pt(struct e1000_adapter *adapter)
@@ -2902,7 +2911,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
rctl = er32(RCTL);
ew32(RCTL, rctl & ~E1000_RCTL_EN);
e1e_flush();
- msleep(10);
+ usleep_range(10000, 20000);
if (adapter->flags2 & FLAG2_DMA_BURST) {
/*
@@ -3039,6 +3048,8 @@ static void e1000_set_multi(struct net_device *netdev)
if (netdev->flags & IFF_PROMISC) {
rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
rctl &= ~E1000_RCTL_VFE;
+ /* Do not hardware filter VLANs in promisc mode */
+ e1000e_vlan_filter_disable(adapter);
} else {
if (netdev->flags & IFF_ALLMULTI) {
rctl |= E1000_RCTL_MPE;
@@ -3046,8 +3057,7 @@ static void e1000_set_multi(struct net_device *netdev)
} else {
rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
}
- if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
- rctl |= E1000_RCTL_VFE;
+ e1000e_vlan_filter_enable(adapter);
}
ew32(RCTL, rctl);
@@ -3072,6 +3082,11 @@ static void e1000_set_multi(struct net_device *netdev)
*/
e1000_update_mc_addr_list(hw, NULL, 0);
}
+
+ if (netdev->features & NETIF_F_HW_VLAN_RX)
+ e1000e_vlan_strip_enable(adapter);
+ else
+ e1000e_vlan_strip_disable(adapter);
}
/**
@@ -3383,7 +3398,7 @@ void e1000e_down(struct e1000_adapter *adapter)
ew32(TCTL, tctl);
/* flush both disables and wait for them to finish */
e1e_flush();
- msleep(10);
+ usleep_range(10000, 20000);
napi_disable(&adapter->napi);
e1000_irq_disable(adapter);
@@ -3418,7 +3433,7 @@ void e1000e_reinit_locked(struct e1000_adapter *adapter)
{
might_sleep();
while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
e1000e_down(adapter);
e1000e_up(adapter);
clear_bit(__E1000_RESETTING, &adapter->state);
@@ -3721,10 +3736,8 @@ static int e1000_close(struct net_device *netdev)
* 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)))
+ if (adapter->hw.mng_cookie.status &
+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN)
e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
/*
@@ -4328,7 +4341,6 @@ static void e1000_watchdog_task(struct work_struct *work)
link_up:
spin_lock(&adapter->stats64_lock);
e1000e_update_stats(adapter);
- spin_unlock(&adapter->stats64_lock);
mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
adapter->tpt_old = adapter->stats.tpt;
@@ -4339,6 +4351,7 @@ link_up:
adapter->gorc_old = adapter->stats.gorc;
adapter->gotc = adapter->stats.gotc - adapter->gotc_old;
adapter->gotc_old = adapter->stats.gotc;
+ spin_unlock(&adapter->stats64_lock);
e1000e_update_adaptive(&adapter->hw);
@@ -5028,7 +5041,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
}
while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
/* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
adapter->max_frame_size = max_frame;
e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
@@ -5373,7 +5386,7 @@ static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16);
}
#endif
-void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
{
dev_info(&pdev->dev, "Disabling ASPM %s %s\n",
(state & PCIE_LINK_STATE_L0S) ? "L0s" : "",
@@ -5393,13 +5406,19 @@ static int __e1000_resume(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ u16 aspm_disable_flag = 0;
u32 err;
+ if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
+ aspm_disable_flag = PCIE_LINK_STATE_L0S;
+ if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
+ aspm_disable_flag |= PCIE_LINK_STATE_L1;
+ if (aspm_disable_flag)
+ e1000e_disable_aspm(pdev, aspm_disable_flag);
+
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
pci_save_state(pdev);
- if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
- e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
e1000e_set_interrupt_capability(adapter);
if (netif_running(netdev)) {
@@ -5643,11 +5662,17 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ u16 aspm_disable_flag = 0;
int err;
pci_ers_result_t result;
+ if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
+ aspm_disable_flag = PCIE_LINK_STATE_L0S;
if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
- e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
+ aspm_disable_flag |= PCIE_LINK_STATE_L1;
+ if (aspm_disable_flag)
+ e1000e_disable_aspm(pdev, aspm_disable_flag);
+
err = pci_enable_device_mem(pdev);
if (err) {
dev_err(&pdev->dev,
@@ -5714,7 +5739,7 @@ static void e1000_print_device_info(struct e1000_adapter *adapter)
u8 pba_str[E1000_PBANUM_LENGTH];
/* print bus type/speed/width info */
- e_info("(PCI Express:2.5GB/s:%s) %pM\n",
+ e_info("(PCI Express:2.5GT/s:%s) %pM\n",
/* bus width */
((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
"Width x1"),
@@ -5759,7 +5784,6 @@ static const struct net_device_ops e1000e_netdev_ops = {
.ndo_tx_timeout = e1000_tx_timeout,
.ndo_validate_addr = eth_validate_addr,
- .ndo_vlan_rx_register = e1000_vlan_rx_register,
.ndo_vlan_rx_add_vid = e1000_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = e1000_vlan_rx_kill_vid,
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -5789,12 +5813,17 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
resource_size_t flash_start, flash_len;
static int cards_found;
+ u16 aspm_disable_flag = 0;
int i, err, pci_using_dac;
u16 eeprom_data = 0;
u16 eeprom_apme_mask = E1000_EEPROM_APME;
+ if (ei->flags2 & FLAG2_DISABLE_ASPM_L0S)
+ aspm_disable_flag = PCIE_LINK_STATE_L0S;
if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
- e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
+ aspm_disable_flag |= PCIE_LINK_STATE_L1;
+ if (aspm_disable_flag)
+ e1000e_disable_aspm(pdev, aspm_disable_flag);
err = pci_enable_device_mem(pdev);
if (err)
@@ -5991,7 +6020,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround);
INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task);
INIT_WORK(&adapter->print_hang_task, e1000_print_hw_hang);
- INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task);
/* Initialize link parameters. User can change them with ethtool */
adapter->hw.mac.autoneg = 1;
@@ -6124,7 +6152,6 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
cancel_work_sync(&adapter->watchdog_task);
cancel_work_sync(&adapter->downshift_task);
cancel_work_sync(&adapter->update_phy_task);
- cancel_work_sync(&adapter->led_blink_task);
cancel_work_sync(&adapter->print_hang_task);
if (!(netdev->flags & IFF_UP))
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 6ae31fcfb62..484774c13c2 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -2372,7 +2372,7 @@ s32 e1000e_determine_phy_address(struct e1000_hw *hw)
ret_val = 0;
goto out;
}
- msleep(1);
+ usleep_range(1000, 2000);
i++;
} while (i < 10);
}
@@ -2740,7 +2740,7 @@ void e1000_power_down_phy_copper(struct e1000_hw *hw)
e1e_rphy(hw, PHY_CONTROL, &mii_reg);
mii_reg |= MII_CR_POWER_DOWN;
e1e_wphy(hw, PHY_CONTROL, mii_reg);
- msleep(1);
+ usleep_range(1000, 2000);
}
/**
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index eb35951a244..dfeb006035d 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -1703,7 +1703,7 @@ static int eepro_ethtool_get_settings(struct net_device *dev,
cmd->advertising |= ADVERTISED_AUI;
}
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
if (dev->if_port == TPE && lp->word[1] & ee_Duplex) {
cmd->duplex = DUPLEX_FULL;
diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c
index f3bbdcef338..7f642aef5e8 100644
--- a/drivers/net/ehea/ehea_ethtool.c
+++ b/drivers/net/ehea/ehea_ethtool.c
@@ -34,6 +34,7 @@
static int ehea_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct ehea_port *port = netdev_priv(dev);
+ u32 speed;
int ret;
ret = ehea_sense_port_attr(port);
@@ -43,17 +44,29 @@ static int ehea_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if (netif_carrier_ok(dev)) {
switch (port->port_speed) {
- case EHEA_SPEED_10M: cmd->speed = SPEED_10; break;
- case EHEA_SPEED_100M: cmd->speed = SPEED_100; break;
- case EHEA_SPEED_1G: cmd->speed = SPEED_1000; break;
- case EHEA_SPEED_10G: cmd->speed = SPEED_10000; break;
+ case EHEA_SPEED_10M:
+ speed = SPEED_10;
+ break;
+ case EHEA_SPEED_100M:
+ speed = SPEED_100;
+ break;
+ case EHEA_SPEED_1G:
+ speed = SPEED_1000;
+ break;
+ case EHEA_SPEED_10G:
+ speed = SPEED_10000;
+ break;
+ default:
+ speed = -1;
+ break; /* BUG */
}
cmd->duplex = port->full_duplex == 1 ?
DUPLEX_FULL : DUPLEX_HALF;
} else {
- cmd->speed = -1;
+ speed = ~0;
cmd->duplex = -1;
}
+ ethtool_cmd_speed_set(cmd, speed);
if (cmd->speed == SPEED_10000) {
cmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
@@ -167,11 +180,6 @@ static void ehea_set_msglevel(struct net_device *dev, u32 value)
port->msg_enable = value;
}
-static u32 ehea_get_rx_csum(struct net_device *dev)
-{
- return 1;
-}
-
static char ehea_ethtool_stats_keys[][ETH_GSTRING_LEN] = {
{"sig_comp_iv"},
{"swqe_refill_th"},
@@ -268,34 +276,16 @@ static void ehea_get_ethtool_stats(struct net_device *dev,
}
-static int ehea_set_flags(struct net_device *dev, u32 data)
-{
- /* Avoid changing the VLAN flags */
- if ((data & (ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN)) !=
- (ethtool_op_get_flags(dev) & (ETH_FLAG_RXVLAN |
- ETH_FLAG_TXVLAN))){
- return -EINVAL;
- }
-
- return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO
- | ETH_FLAG_TXVLAN
- | ETH_FLAG_RXVLAN);
-}
-
const struct ethtool_ops ehea_ethtool_ops = {
.get_settings = ehea_get_settings,
.get_drvinfo = ehea_get_drvinfo,
.get_msglevel = ehea_get_msglevel,
.set_msglevel = ehea_set_msglevel,
.get_link = ethtool_op_get_link,
- .set_tso = ethtool_op_set_tso,
.get_strings = ehea_get_strings,
.get_sset_count = ehea_get_sset_count,
.get_ethtool_stats = ehea_get_ethtool_stats,
- .get_rx_csum = ehea_get_rx_csum,
.set_settings = ehea_set_settings,
- .get_flags = ethtool_op_get_flags,
- .set_flags = ehea_set_flags,
.nway_reset = ehea_nway_reset, /* Restart autonegotiation */
};
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 2c60435f2be..6a0a8fca62b 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -3263,10 +3263,12 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
dev->netdev_ops = &ehea_netdev_ops;
ehea_set_ethtool_ops(dev);
+ dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO
+ | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_LRO;
dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO
| NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX
| NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER
- | NETIF_F_LLTX;
+ | NETIF_F_LLTX | NETIF_F_RXCSUM;
dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
if (use_lro)
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c
index 907b05a1c65..2837ce209cd 100644
--- a/drivers/net/enc28j60.c
+++ b/drivers/net/enc28j60.c
@@ -1488,7 +1488,7 @@ enc28j60_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->supported = SUPPORTED_10baseT_Half
| SUPPORTED_10baseT_Full
| SUPPORTED_TP;
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
cmd->duplex = priv->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
cmd->port = PORT_TP;
cmd->autoneg = AUTONEG_DISABLE;
@@ -1499,7 +1499,8 @@ enc28j60_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int
enc28j60_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- return enc28j60_setlink(dev, cmd->autoneg, cmd->speed, cmd->duplex);
+ return enc28j60_setlink(dev, cmd->autoneg,
+ ethtool_cmd_speed(cmd), cmd->duplex);
}
static u32 enc28j60_get_msglevel(struct net_device *dev)
diff --git a/drivers/net/enic/Makefile b/drivers/net/enic/Makefile
index 2e573be16c1..9d4974bba24 100644
--- a/drivers/net/enic/Makefile
+++ b/drivers/net/enic/Makefile
@@ -1,5 +1,5 @@
obj-$(CONFIG_ENIC) := enic.o
enic-y := enic_main.o vnic_cq.o vnic_intr.o vnic_wq.o \
- enic_res.o enic_dev.o vnic_dev.o vnic_rq.o vnic_vic.o
+ enic_res.o enic_dev.o enic_pp.o vnic_dev.o vnic_rq.o vnic_vic.o
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 3a3c3c8a3a9..38b351c7b97 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -32,7 +32,7 @@
#define DRV_NAME "enic"
#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION "2.1.1.12"
+#define DRV_VERSION "2.1.1.13"
#define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc"
#define ENIC_BARS_MAX 6
@@ -84,7 +84,6 @@ struct enic {
unsigned int flags;
unsigned int mc_count;
unsigned int uc_count;
- int csum_rx_enabled;
u32 port_mtu;
u32 rx_coalesce_usecs;
u32 tx_coalesce_usecs;
@@ -120,4 +119,6 @@ static inline struct device *enic_get_dev(struct enic *enic)
return &(enic->pdev->dev);
}
+void enic_reset_addr_lists(struct enic *enic);
+
#endif /* _ENIC_H_ */
diff --git a/drivers/net/enic/enic_dev.c b/drivers/net/enic/enic_dev.c
index 37ad3a1c82e..90687b14e60 100644
--- a/drivers/net/enic/enic_dev.c
+++ b/drivers/net/enic/enic_dev.c
@@ -177,24 +177,24 @@ int enic_vnic_dev_deinit(struct enic *enic)
return err;
}
-int enic_dev_init_prov(struct enic *enic, struct vic_provinfo *vp)
+int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp)
{
int err;
spin_lock(&enic->devcmd_lock);
- err = vnic_dev_init_prov(enic->vdev,
+ err = vnic_dev_init_prov2(enic->vdev,
(u8 *)vp, vic_provinfo_size(vp));
spin_unlock(&enic->devcmd_lock);
return err;
}
-int enic_dev_init_done(struct enic *enic, int *done, int *error)
+int enic_dev_deinit_done(struct enic *enic, int *status)
{
int err;
spin_lock(&enic->devcmd_lock);
- err = vnic_dev_init_done(enic->vdev, done, error);
+ err = vnic_dev_deinit_done(enic->vdev, status);
spin_unlock(&enic->devcmd_lock);
return err;
@@ -219,3 +219,57 @@ void enic_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
enic_del_vlan(enic, vid);
spin_unlock(&enic->devcmd_lock);
}
+
+int enic_dev_enable2(struct enic *enic, int active)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_enable2(enic->vdev, active);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
+int enic_dev_enable2_done(struct enic *enic, int *status)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_enable2_done(enic->vdev, status);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
+int enic_dev_status_to_errno(int devcmd_status)
+{
+ switch (devcmd_status) {
+ case ERR_SUCCESS:
+ return 0;
+ case ERR_EINVAL:
+ return -EINVAL;
+ case ERR_EFAULT:
+ return -EFAULT;
+ case ERR_EPERM:
+ return -EPERM;
+ case ERR_EBUSY:
+ return -EBUSY;
+ case ERR_ECMDUNKNOWN:
+ case ERR_ENOTSUPPORTED:
+ return -EOPNOTSUPP;
+ case ERR_EBADSTATE:
+ return -EINVAL;
+ case ERR_ENOMEM:
+ return -ENOMEM;
+ case ERR_ETIMEDOUT:
+ return -ETIMEDOUT;
+ case ERR_ELINKDOWN:
+ return -ENETDOWN;
+ case ERR_EINPROGRESS:
+ return -EINPROGRESS;
+ case ERR_EMAXRES:
+ default:
+ return (devcmd_status < 0) ? devcmd_status : -1;
+ }
+}
diff --git a/drivers/net/enic/enic_dev.h b/drivers/net/enic/enic_dev.h
index 495f57fcb88..d5f68133762 100644
--- a/drivers/net/enic/enic_dev.h
+++ b/drivers/net/enic/enic_dev.h
@@ -35,7 +35,10 @@ int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic);
int enic_dev_enable(struct enic *enic);
int enic_dev_disable(struct enic *enic);
int enic_vnic_dev_deinit(struct enic *enic);
-int enic_dev_init_prov(struct enic *enic, struct vic_provinfo *vp);
-int enic_dev_init_done(struct enic *enic, int *done, int *error);
+int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp);
+int enic_dev_deinit_done(struct enic *enic, int *status);
+int enic_dev_enable2(struct enic *enic, int arg);
+int enic_dev_enable2_done(struct enic *enic, int *status);
+int enic_dev_status_to_errno(int devcmd_status);
#endif /* _ENIC_DEV_H_ */
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 8b9cad5e971..3d99b0f1a23 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -45,6 +45,7 @@
#include "enic_res.h"
#include "enic.h"
#include "enic_dev.h"
+#include "enic_pp.h"
#define ENIC_NOTIFY_TIMER_PERIOD (2 * HZ)
#define WQ_ENET_MAX_DESC_LEN (1 << WQ_ENET_LEN_BITS)
@@ -179,10 +180,10 @@ static int enic_get_settings(struct net_device *netdev,
ecmd->transceiver = XCVR_EXTERNAL;
if (netif_carrier_ok(netdev)) {
- ecmd->speed = vnic_dev_port_speed(enic->vdev);
+ ethtool_cmd_speed_set(ecmd, vnic_dev_port_speed(enic->vdev));
ecmd->duplex = DUPLEX_FULL;
} else {
- ecmd->speed = -1;
+ ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1;
}
@@ -250,56 +251,6 @@ static void enic_get_ethtool_stats(struct net_device *netdev,
*(data++) = ((u64 *)&vstats->rx)[enic_rx_stats[i].offset];
}
-static u32 enic_get_rx_csum(struct net_device *netdev)
-{
- struct enic *enic = netdev_priv(netdev);
- return enic->csum_rx_enabled;
-}
-
-static int enic_set_rx_csum(struct net_device *netdev, u32 data)
-{
- struct enic *enic = netdev_priv(netdev);
-
- if (data && !ENIC_SETTING(enic, RXCSUM))
- return -EINVAL;
-
- enic->csum_rx_enabled = !!data;
-
- return 0;
-}
-
-static int enic_set_tx_csum(struct net_device *netdev, u32 data)
-{
- struct enic *enic = netdev_priv(netdev);
-
- if (data && !ENIC_SETTING(enic, TXCSUM))
- return -EINVAL;
-
- if (data)
- netdev->features |= NETIF_F_HW_CSUM;
- else
- netdev->features &= ~NETIF_F_HW_CSUM;
-
- return 0;
-}
-
-static int enic_set_tso(struct net_device *netdev, u32 data)
-{
- struct enic *enic = netdev_priv(netdev);
-
- if (data && !ENIC_SETTING(enic, TSO))
- return -EINVAL;
-
- if (data)
- netdev->features |=
- NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN;
- else
- netdev->features &=
- ~(NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN);
-
- return 0;
-}
-
static u32 enic_get_msglevel(struct net_device *netdev)
{
struct enic *enic = netdev_priv(netdev);
@@ -387,17 +338,8 @@ static const struct ethtool_ops enic_ethtool_ops = {
.get_strings = enic_get_strings,
.get_sset_count = enic_get_sset_count,
.get_ethtool_stats = enic_get_ethtool_stats,
- .get_rx_csum = enic_get_rx_csum,
- .set_rx_csum = enic_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = enic_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = enic_set_tso,
.get_coalesce = enic_get_coalesce,
.set_coalesce = enic_set_coalesce,
- .get_flags = ethtool_op_get_flags,
};
static void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf)
@@ -874,7 +816,7 @@ static struct net_device_stats *enic_get_stats(struct net_device *netdev)
return net_stats;
}
-static void enic_reset_addr_lists(struct enic *enic)
+void enic_reset_addr_lists(struct enic *enic)
{
enic->mc_count = 0;
enic->uc_count = 0;
@@ -1112,157 +1054,77 @@ static int enic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
return -EINVAL;
}
-static int enic_set_port_profile(struct enic *enic, u8 *mac)
-{
- struct vic_provinfo *vp;
- u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
- u16 os_type = VIC_GENERIC_PROV_OS_TYPE_LINUX;
- char uuid_str[38];
- char client_mac_str[18];
- u8 *client_mac;
- int err;
-
- err = enic_vnic_dev_deinit(enic);
- if (err)
- return err;
-
- enic_reset_addr_lists(enic);
-
- switch (enic->pp.request) {
-
- case PORT_REQUEST_ASSOCIATE:
-
- if (!(enic->pp.set & ENIC_SET_NAME) || !strlen(enic->pp.name))
- return -EINVAL;
-
- if (!is_valid_ether_addr(mac))
- return -EADDRNOTAVAIL;
-
- vp = vic_provinfo_alloc(GFP_KERNEL, oui,
- VIC_PROVINFO_GENERIC_TYPE);
- if (!vp)
- return -ENOMEM;
-
- vic_provinfo_add_tlv(vp,
- VIC_GENERIC_PROV_TLV_PORT_PROFILE_NAME_STR,
- strlen(enic->pp.name) + 1, enic->pp.name);
-
- if (!is_zero_ether_addr(enic->pp.mac_addr))
- client_mac = enic->pp.mac_addr;
- else
- client_mac = mac;
-
- vic_provinfo_add_tlv(vp,
- VIC_GENERIC_PROV_TLV_CLIENT_MAC_ADDR,
- ETH_ALEN, client_mac);
-
- sprintf(client_mac_str, "%pM", client_mac);
- vic_provinfo_add_tlv(vp,
- VIC_GENERIC_PROV_TLV_CLUSTER_PORT_UUID_STR,
- sizeof(client_mac_str), client_mac_str);
-
- if (enic->pp.set & ENIC_SET_INSTANCE) {
- sprintf(uuid_str, "%pUB", enic->pp.instance_uuid);
- vic_provinfo_add_tlv(vp,
- VIC_GENERIC_PROV_TLV_CLIENT_UUID_STR,
- sizeof(uuid_str), uuid_str);
- }
-
- if (enic->pp.set & ENIC_SET_HOST) {
- sprintf(uuid_str, "%pUB", enic->pp.host_uuid);
- vic_provinfo_add_tlv(vp,
- VIC_GENERIC_PROV_TLV_HOST_UUID_STR,
- sizeof(uuid_str), uuid_str);
- }
-
- os_type = htons(os_type);
- vic_provinfo_add_tlv(vp,
- VIC_GENERIC_PROV_TLV_OS_TYPE,
- sizeof(os_type), &os_type);
-
- err = enic_dev_init_prov(enic, vp);
- vic_provinfo_free(vp);
- if (err)
- return err;
- break;
-
- case PORT_REQUEST_DISASSOCIATE:
- break;
-
- default:
- return -EINVAL;
- }
-
- /* Set flag to indicate that the port assoc/disassoc
- * request has been sent out to fw
- */
- enic->pp.set |= ENIC_PORT_REQUEST_APPLIED;
-
- return 0;
-}
-
static int enic_set_vf_port(struct net_device *netdev, int vf,
struct nlattr *port[])
{
struct enic *enic = netdev_priv(netdev);
- struct enic_port_profile new_pp;
- int err = 0;
+ struct enic_port_profile prev_pp;
+ int err = 0, restore_pp = 1;
- memset(&new_pp, 0, sizeof(new_pp));
+ /* don't support VFs, yet */
+ if (vf != PORT_SELF_VF)
+ return -EOPNOTSUPP;
- if (port[IFLA_PORT_REQUEST]) {
- new_pp.set |= ENIC_SET_REQUEST;
- new_pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]);
- }
+ if (!port[IFLA_PORT_REQUEST])
+ return -EOPNOTSUPP;
+
+ memcpy(&prev_pp, &enic->pp, sizeof(enic->pp));
+ memset(&enic->pp, 0, sizeof(enic->pp));
+
+ enic->pp.set |= ENIC_SET_REQUEST;
+ enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]);
if (port[IFLA_PORT_PROFILE]) {
- new_pp.set |= ENIC_SET_NAME;
- memcpy(new_pp.name, nla_data(port[IFLA_PORT_PROFILE]),
+ enic->pp.set |= ENIC_SET_NAME;
+ memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]),
PORT_PROFILE_MAX);
}
if (port[IFLA_PORT_INSTANCE_UUID]) {
- new_pp.set |= ENIC_SET_INSTANCE;
- memcpy(new_pp.instance_uuid,
+ enic->pp.set |= ENIC_SET_INSTANCE;
+ memcpy(enic->pp.instance_uuid,
nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX);
}
if (port[IFLA_PORT_HOST_UUID]) {
- new_pp.set |= ENIC_SET_HOST;
- memcpy(new_pp.host_uuid,
+ enic->pp.set |= ENIC_SET_HOST;
+ memcpy(enic->pp.host_uuid,
nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);
}
- /* don't support VFs, yet */
- if (vf != PORT_SELF_VF)
- return -EOPNOTSUPP;
-
- if (!(new_pp.set & ENIC_SET_REQUEST))
- return -EOPNOTSUPP;
-
- if (new_pp.request == PORT_REQUEST_ASSOCIATE) {
- /* Special case handling */
- if (!is_zero_ether_addr(enic->pp.vf_mac))
- memcpy(new_pp.mac_addr, enic->pp.vf_mac, ETH_ALEN);
+ /* Special case handling: mac came from IFLA_VF_MAC */
+ if (!is_zero_ether_addr(prev_pp.vf_mac))
+ memcpy(enic->pp.mac_addr, prev_pp.vf_mac, ETH_ALEN);
if (is_zero_ether_addr(netdev->dev_addr))
random_ether_addr(netdev->dev_addr);
- }
- memcpy(&enic->pp, &new_pp, sizeof(struct enic_port_profile));
+ err = enic_process_set_pp_request(enic, &prev_pp, &restore_pp);
+ if (err) {
+ if (restore_pp) {
+ /* Things are still the way they were: Implicit
+ * DISASSOCIATE failed
+ */
+ memcpy(&enic->pp, &prev_pp, sizeof(enic->pp));
+ } else {
+ memset(&enic->pp, 0, sizeof(enic->pp));
+ memset(netdev->dev_addr, 0, ETH_ALEN);
+ }
+ } else {
+ /* Set flag to indicate that the port assoc/disassoc
+ * request has been sent out to fw
+ */
+ enic->pp.set |= ENIC_PORT_REQUEST_APPLIED;
- err = enic_set_port_profile(enic, netdev->dev_addr);
- if (err)
- goto set_port_profile_cleanup;
+ /* If DISASSOCIATE, clean up all assigned/saved macaddresses */
+ if (enic->pp.request == PORT_REQUEST_DISASSOCIATE) {
+ memset(enic->pp.mac_addr, 0, ETH_ALEN);
+ memset(netdev->dev_addr, 0, ETH_ALEN);
+ }
+ }
-set_port_profile_cleanup:
memset(enic->pp.vf_mac, 0, ETH_ALEN);
- if (err || enic->pp.request == PORT_REQUEST_DISASSOCIATE) {
- memset(netdev->dev_addr, 0, ETH_ALEN);
- memset(enic->pp.mac_addr, 0, ETH_ALEN);
- }
-
return err;
}
@@ -1270,34 +1132,15 @@ static int enic_get_vf_port(struct net_device *netdev, int vf,
struct sk_buff *skb)
{
struct enic *enic = netdev_priv(netdev);
- int err, error, done;
u16 response = PORT_PROFILE_RESPONSE_SUCCESS;
+ int err;
if (!(enic->pp.set & ENIC_PORT_REQUEST_APPLIED))
return -ENODATA;
- err = enic_dev_init_done(enic, &done, &error);
+ err = enic_process_get_pp_request(enic, enic->pp.request, &response);
if (err)
- error = err;
-
- switch (error) {
- case ERR_SUCCESS:
- if (!done)
- response = PORT_PROFILE_RESPONSE_INPROGRESS;
- break;
- case ERR_EINVAL:
- response = PORT_PROFILE_RESPONSE_INVALID;
- break;
- case ERR_EBADSTATE:
- response = PORT_PROFILE_RESPONSE_BADSTATE;
- break;
- case ERR_ENOMEM:
- response = PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES;
- break;
- default:
- response = PORT_PROFILE_RESPONSE_ERROR;
- break;
- }
+ return err;
NLA_PUT_U16(skb, IFLA_PORT_REQUEST, enic->pp.request);
NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response);
@@ -1407,7 +1250,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
skb_put(skb, bytes_written);
skb->protocol = eth_type_trans(skb, netdev);
- if (enic->csum_rx_enabled && !csum_not_calc) {
+ if ((netdev->features & NETIF_F_RXCSUM) && !csum_not_calc) {
skb->csum = htons(checksum);
skb->ip_summed = CHECKSUM_COMPLETE;
}
@@ -2536,17 +2379,18 @@ static int __devinit enic_probe(struct pci_dev *pdev,
dev_info(dev, "loopback tag=0x%04x\n", enic->loop_tag);
}
if (ENIC_SETTING(enic, TXCSUM))
- netdev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
+ netdev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM;
if (ENIC_SETTING(enic, TSO))
- netdev->features |= NETIF_F_TSO |
+ netdev->hw_features |= NETIF_F_TSO |
NETIF_F_TSO6 | NETIF_F_TSO_ECN;
- if (ENIC_SETTING(enic, LRO))
- netdev->features |= NETIF_F_GRO;
+ if (ENIC_SETTING(enic, RXCSUM))
+ netdev->hw_features |= NETIF_F_RXCSUM;
+
+ netdev->features |= netdev->hw_features;
+
if (using_dac)
netdev->features |= NETIF_F_HIGHDMA;
- enic->csum_rx_enabled = ENIC_SETTING(enic, RXCSUM);
-
err = register_netdev(netdev);
if (err) {
dev_err(dev, "Cannot register net device, aborting\n");
diff --git a/drivers/net/enic/enic_pp.c b/drivers/net/enic/enic_pp.c
new file mode 100644
index 00000000000..ffaa75dd1de
--- /dev/null
+++ b/drivers/net/enic/enic_pp.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2011 Cisco Systems, Inc. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/rtnetlink.h>
+#include <net/ip.h>
+
+#include "vnic_vic.h"
+#include "enic_res.h"
+#include "enic.h"
+#include "enic_dev.h"
+
+static int enic_set_port_profile(struct enic *enic)
+{
+ struct net_device *netdev = enic->netdev;
+ struct vic_provinfo *vp;
+ const u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
+ const u16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX);
+ char uuid_str[38];
+ char client_mac_str[18];
+ u8 *client_mac;
+ int err;
+
+ if (!(enic->pp.set & ENIC_SET_NAME) || !strlen(enic->pp.name))
+ return -EINVAL;
+
+ vp = vic_provinfo_alloc(GFP_KERNEL, oui,
+ VIC_PROVINFO_GENERIC_TYPE);
+ if (!vp)
+ return -ENOMEM;
+
+ VIC_PROVINFO_ADD_TLV(vp,
+ VIC_GENERIC_PROV_TLV_PORT_PROFILE_NAME_STR,
+ strlen(enic->pp.name) + 1, enic->pp.name);
+
+ if (!is_zero_ether_addr(enic->pp.mac_addr))
+ client_mac = enic->pp.mac_addr;
+ else
+ client_mac = netdev->dev_addr;
+
+ VIC_PROVINFO_ADD_TLV(vp,
+ VIC_GENERIC_PROV_TLV_CLIENT_MAC_ADDR,
+ ETH_ALEN, client_mac);
+
+ snprintf(client_mac_str, sizeof(client_mac_str), "%pM", client_mac);
+ VIC_PROVINFO_ADD_TLV(vp,
+ VIC_GENERIC_PROV_TLV_CLUSTER_PORT_UUID_STR,
+ sizeof(client_mac_str), client_mac_str);
+
+ if (enic->pp.set & ENIC_SET_INSTANCE) {
+ sprintf(uuid_str, "%pUB", enic->pp.instance_uuid);
+ VIC_PROVINFO_ADD_TLV(vp,
+ VIC_GENERIC_PROV_TLV_CLIENT_UUID_STR,
+ sizeof(uuid_str), uuid_str);
+ }
+
+ if (enic->pp.set & ENIC_SET_HOST) {
+ sprintf(uuid_str, "%pUB", enic->pp.host_uuid);
+ VIC_PROVINFO_ADD_TLV(vp,
+ VIC_GENERIC_PROV_TLV_HOST_UUID_STR,
+ sizeof(uuid_str), uuid_str);
+ }
+
+ VIC_PROVINFO_ADD_TLV(vp,
+ VIC_GENERIC_PROV_TLV_OS_TYPE,
+ sizeof(os_type), &os_type);
+
+ err = enic_dev_status_to_errno(enic_dev_init_prov2(enic, vp));
+
+add_tlv_failure:
+ vic_provinfo_free(vp);
+
+ return err;
+}
+
+static int enic_unset_port_profile(struct enic *enic)
+{
+ int err;
+
+ err = enic_vnic_dev_deinit(enic);
+ if (err)
+ return enic_dev_status_to_errno(err);
+
+ enic_reset_addr_lists(enic);
+
+ return 0;
+}
+
+static int enic_are_pp_different(struct enic_port_profile *pp1,
+ struct enic_port_profile *pp2)
+{
+ return strcmp(pp1->name, pp2->name) | !!memcmp(pp1->instance_uuid,
+ pp2->instance_uuid, PORT_UUID_MAX) |
+ !!memcmp(pp1->host_uuid, pp2->host_uuid, PORT_UUID_MAX) |
+ !!memcmp(pp1->mac_addr, pp2->mac_addr, ETH_ALEN);
+}
+
+static int enic_pp_preassociate(struct enic *enic,
+ struct enic_port_profile *prev_pp, int *restore_pp);
+static int enic_pp_disassociate(struct enic *enic,
+ struct enic_port_profile *prev_pp, int *restore_pp);
+static int enic_pp_preassociate_rr(struct enic *enic,
+ struct enic_port_profile *prev_pp, int *restore_pp);
+static int enic_pp_associate(struct enic *enic,
+ struct enic_port_profile *prev_pp, int *restore_pp);
+
+static int (*enic_pp_handlers[])(struct enic *enic,
+ struct enic_port_profile *prev_state, int *restore_pp) = {
+ [PORT_REQUEST_PREASSOCIATE] = enic_pp_preassociate,
+ [PORT_REQUEST_PREASSOCIATE_RR] = enic_pp_preassociate_rr,
+ [PORT_REQUEST_ASSOCIATE] = enic_pp_associate,
+ [PORT_REQUEST_DISASSOCIATE] = enic_pp_disassociate,
+};
+
+static const int enic_pp_handlers_count =
+ sizeof(enic_pp_handlers)/sizeof(*enic_pp_handlers);
+
+static int enic_pp_preassociate(struct enic *enic,
+ struct enic_port_profile *prev_pp, int *restore_pp)
+{
+ return -EOPNOTSUPP;
+}
+
+static int enic_pp_disassociate(struct enic *enic,
+ struct enic_port_profile *prev_pp, int *restore_pp)
+{
+ return enic_unset_port_profile(enic);
+}
+
+static int enic_pp_preassociate_rr(struct enic *enic,
+ struct enic_port_profile *prev_pp, int *restore_pp)
+{
+ int err;
+ int active = 0;
+
+ if (enic->pp.request != PORT_REQUEST_ASSOCIATE) {
+ /* If pre-associate is not part of an associate.
+ We always disassociate first */
+ err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](enic,
+ prev_pp, restore_pp);
+ if (err)
+ return err;
+
+ *restore_pp = 0;
+ }
+
+ *restore_pp = 0;
+
+ err = enic_set_port_profile(enic);
+ if (err)
+ return err;
+
+ /* If pre-associate is not part of an associate. */
+ if (enic->pp.request != PORT_REQUEST_ASSOCIATE)
+ err = enic_dev_status_to_errno(enic_dev_enable2(enic, active));
+
+ return err;
+}
+
+static int enic_pp_associate(struct enic *enic,
+ struct enic_port_profile *prev_pp, int *restore_pp)
+{
+ int err;
+ int active = 1;
+
+ /* Check if a pre-associate was called before */
+ if (prev_pp->request != PORT_REQUEST_PREASSOCIATE_RR ||
+ (prev_pp->request == PORT_REQUEST_PREASSOCIATE_RR &&
+ enic_are_pp_different(prev_pp, &enic->pp))) {
+ err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](
+ enic, prev_pp, restore_pp);
+ if (err)
+ return err;
+
+ *restore_pp = 0;
+ }
+
+ err = enic_pp_handlers[PORT_REQUEST_PREASSOCIATE_RR](
+ enic, prev_pp, restore_pp);
+ if (err)
+ return err;
+
+ *restore_pp = 0;
+
+ return enic_dev_status_to_errno(enic_dev_enable2(enic, active));
+}
+
+int enic_process_set_pp_request(struct enic *enic,
+ struct enic_port_profile *prev_pp, int *restore_pp)
+{
+ if (enic->pp.request < enic_pp_handlers_count
+ && enic_pp_handlers[enic->pp.request])
+ return enic_pp_handlers[enic->pp.request](enic,
+ prev_pp, restore_pp);
+ else
+ return -EOPNOTSUPP;
+}
+
+int enic_process_get_pp_request(struct enic *enic, int request,
+ u16 *response)
+{
+ int err, status = ERR_SUCCESS;
+
+ switch (request) {
+
+ case PORT_REQUEST_PREASSOCIATE_RR:
+ case PORT_REQUEST_ASSOCIATE:
+ err = enic_dev_enable2_done(enic, &status);
+ break;
+
+ case PORT_REQUEST_DISASSOCIATE:
+ err = enic_dev_deinit_done(enic, &status);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ if (err)
+ status = err;
+
+ switch (status) {
+ case ERR_SUCCESS:
+ *response = PORT_PROFILE_RESPONSE_SUCCESS;
+ break;
+ case ERR_EINVAL:
+ *response = PORT_PROFILE_RESPONSE_INVALID;
+ break;
+ case ERR_EBADSTATE:
+ *response = PORT_PROFILE_RESPONSE_BADSTATE;
+ break;
+ case ERR_ENOMEM:
+ *response = PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES;
+ break;
+ case ERR_EINPROGRESS:
+ *response = PORT_PROFILE_RESPONSE_INPROGRESS;
+ break;
+ default:
+ *response = PORT_PROFILE_RESPONSE_ERROR;
+ break;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/enic/enic_pp.h b/drivers/net/enic/enic_pp.h
new file mode 100644
index 00000000000..699e365a944
--- /dev/null
+++ b/drivers/net/enic/enic_pp.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2011 Cisco Systems, Inc. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef _ENIC_PP_H_
+#define _ENIC_PP_H_
+
+int enic_process_set_pp_request(struct enic *enic,
+ struct enic_port_profile *prev_pp, int *restore_pp);
+int enic_process_get_pp_request(struct enic *enic, int request,
+ u16 *response);
+
+#endif /* _ENIC_PP_H_ */
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index f111a37419c..6e5c6356e7d 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -98,9 +98,9 @@ int enic_get_vnic_config(struct enic *enic)
"vNIC MAC addr %pM wq/rq %d/%d mtu %d\n",
enic->mac_addr, c->wq_desc_count, c->rq_desc_count, c->mtu);
dev_info(enic_get_dev(enic), "vNIC csum tx/rx %d/%d "
- "tso/lro %d/%d intr timer %d usec rss %d\n",
+ "tso %d intr timer %d usec rss %d\n",
ENIC_SETTING(enic, TXCSUM), ENIC_SETTING(enic, RXCSUM),
- ENIC_SETTING(enic, TSO), ENIC_SETTING(enic, LRO),
+ ENIC_SETTING(enic, TSO),
c->intr_timer_usec, ENIC_SETTING(enic, RSS));
return 0;
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index c089b362a36..68f24ae860a 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -786,48 +786,6 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg)
return r;
}
-int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err)
-{
- u64 a0 = 0, a1 = 0;
- int wait = 1000;
- int ret;
-
- *done = 0;
-
- ret = vnic_dev_cmd(vdev, CMD_INIT_STATUS, &a0, &a1, wait);
- if (ret)
- return ret;
-
- *done = (a0 == 0);
-
- *err = (a0 == 0) ? (int)a1:0;
-
- return 0;
-}
-
-int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len)
-{
- u64 a0, a1 = len;
- int wait = 1000;
- dma_addr_t prov_pa;
- void *prov_buf;
- int ret;
-
- prov_buf = pci_alloc_consistent(vdev->pdev, len, &prov_pa);
- if (!prov_buf)
- return -ENOMEM;
-
- memcpy(prov_buf, buf, len);
-
- a0 = prov_pa;
-
- ret = vnic_dev_cmd(vdev, CMD_INIT_PROV_INFO, &a0, &a1, wait);
-
- pci_free_consistent(vdev->pdev, len, prov_buf, prov_pa);
-
- return ret;
-}
-
int vnic_dev_deinit(struct vnic_dev *vdev)
{
u64 a0 = 0, a1 = 0;
@@ -927,4 +885,59 @@ err_out:
return NULL;
}
+int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len)
+{
+ u64 a0, a1 = len;
+ int wait = 1000;
+ dma_addr_t prov_pa;
+ void *prov_buf;
+ int ret;
+
+ prov_buf = pci_alloc_consistent(vdev->pdev, len, &prov_pa);
+ if (!prov_buf)
+ return -ENOMEM;
+ memcpy(prov_buf, buf, len);
+
+ a0 = prov_pa;
+
+ ret = vnic_dev_cmd(vdev, CMD_INIT_PROV_INFO2, &a0, &a1, wait);
+
+ pci_free_consistent(vdev->pdev, len, prov_buf, prov_pa);
+
+ return ret;
+}
+
+int vnic_dev_enable2(struct vnic_dev *vdev, int active)
+{
+ u64 a0, a1 = 0;
+ int wait = 1000;
+
+ a0 = (active ? CMD_ENABLE2_ACTIVE : 0);
+
+ return vnic_dev_cmd(vdev, CMD_ENABLE2, &a0, &a1, wait);
+}
+
+static int vnic_dev_cmd_status(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
+ int *status)
+{
+ u64 a0 = cmd, a1 = 0;
+ int wait = 1000;
+ int ret;
+
+ ret = vnic_dev_cmd(vdev, CMD_STATUS, &a0, &a1, wait);
+ if (!ret)
+ *status = (int)a0;
+
+ return ret;
+}
+
+int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status)
+{
+ return vnic_dev_cmd_status(vdev, CMD_ENABLE2, status);
+}
+
+int vnic_dev_deinit_done(struct vnic_dev *vdev, int *status)
+{
+ return vnic_dev_cmd_status(vdev, CMD_DEINIT, status);
+}
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index e837546213a..cf482a2c9dd 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -108,8 +108,6 @@ int vnic_dev_disable(struct vnic_dev *vdev);
int vnic_dev_open(struct vnic_dev *vdev, int arg);
int vnic_dev_open_done(struct vnic_dev *vdev, int *done);
int vnic_dev_init(struct vnic_dev *vdev, int arg);
-int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err);
-int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len);
int vnic_dev_deinit(struct vnic_dev *vdev);
int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg);
int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done);
@@ -122,5 +120,9 @@ int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev,
struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar,
unsigned int num_bars);
+int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len);
+int vnic_dev_enable2(struct vnic_dev *vdev, int active);
+int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status);
+int vnic_dev_deinit_done(struct vnic_dev *vdev, int *status);
#endif /* _VNIC_DEV_H_ */
diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h
index d833a071bac..c5569bfb47a 100644
--- a/drivers/net/enic/vnic_devcmd.h
+++ b/drivers/net/enic/vnic_devcmd.h
@@ -267,17 +267,62 @@ enum vnic_devcmd_cmd {
/*
* As for BY_BDF except a0 is index of hvnlink subordinate vnic
- * or SR-IOV virtual vnic */
+ * or SR-IOV virtual vnic
+ */
CMD_PROXY_BY_INDEX = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 43),
/*
- * in: (u64)a0=paddr of buffer to put latest VIC VIF-CONFIG-INFO TLV in
- * (u32)a1=length of buffer in a0
- * out: (u64)a0=paddr of buffer with latest VIC VIF-CONFIG-INFO TLV
- * (u32)a1=actual length of latest VIC VIF-CONFIG-INFO TLV */
+ * For HPP toggle:
+ * adapter-info-get
+ * in: (u64)a0=phsical address of buffer passed in from caller.
+ * (u16)a1=size of buffer specified in a0.
+ * out: (u64)a0=phsical address of buffer passed in from caller.
+ * (u16)a1=actual bytes from VIF-CONFIG-INFO TLV, or
+ * 0 if no VIF-CONFIG-INFO TLV was ever received. */
CMD_CONFIG_INFO_GET = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 44),
+
+ /* init_prov_info2:
+ * Variant of CMD_INIT_PROV_INFO, where it will not try to enable
+ * the vnic until CMD_ENABLE2 is issued.
+ * (u64)a0=paddr of vnic_devcmd_provinfo
+ * (u32)a1=sizeof provision info */
+ CMD_INIT_PROV_INFO2 = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 47),
+
+ /* enable2:
+ * (u32)a0=0 ==> standby
+ * =CMD_ENABLE2_ACTIVE ==> active
+ */
+ CMD_ENABLE2 = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 48),
+
+ /*
+ * cmd_status:
+ * Returns the status of the specified command
+ * Input:
+ * a0 = command for which status is being queried.
+ * Possible values are:
+ * CMD_SOFT_RESET
+ * CMD_HANG_RESET
+ * CMD_OPEN
+ * CMD_INIT
+ * CMD_INIT_PROV_INFO
+ * CMD_DEINIT
+ * CMD_INIT_PROV_INFO2
+ * CMD_ENABLE2
+ * Output:
+ * if status == STAT_ERROR
+ * a0 = ERR_ENOTSUPPORTED - status for command in a0 is
+ * not supported
+ * if status == STAT_NONE
+ * a0 = status of the devcmd specified in a0 as follows.
+ * ERR_SUCCESS - command in a0 completed successfully
+ * ERR_EINPROGRESS - command in a0 is still in progress
+ */
+ CMD_STATUS = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 49),
};
+/* CMD_ENABLE2 flags */
+#define CMD_ENABLE2_ACTIVE 0x1
+
/* flags for CMD_OPEN */
#define CMD_OPENF_OPROM 0x1 /* open coming from option rom */
@@ -315,6 +360,8 @@ enum vnic_devcmd_error {
ERR_ETIMEDOUT = 8,
ERR_ELINKDOWN = 9,
ERR_EMAXRES = 10,
+ ERR_ENOTSUPPORTED = 11,
+ ERR_EINPROGRESS = 12,
};
/*
diff --git a/drivers/net/enic/vnic_vic.c b/drivers/net/enic/vnic_vic.c
index 4725b79de0e..24ef8cd4054 100644
--- a/drivers/net/enic/vnic_vic.c
+++ b/drivers/net/enic/vnic_vic.c
@@ -23,7 +23,8 @@
#include "vnic_vic.h"
-struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, u8 *oui, u8 type)
+struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, const u8 *oui,
+ const u8 type)
{
struct vic_provinfo *vp;
@@ -47,7 +48,7 @@ void vic_provinfo_free(struct vic_provinfo *vp)
}
int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length,
- void *value)
+ const void *value)
{
struct vic_provinfo_tlv *tlv;
diff --git a/drivers/net/enic/vnic_vic.h b/drivers/net/enic/vnic_vic.h
index f700f5d9e81..9ef81f14835 100644
--- a/drivers/net/enic/vnic_vic.h
+++ b/drivers/net/enic/vnic_vic.h
@@ -47,6 +47,7 @@ enum vic_generic_prov_os_type {
VIC_GENERIC_PROV_OS_TYPE_ESX = 1,
VIC_GENERIC_PROV_OS_TYPE_LINUX = 2,
VIC_GENERIC_PROV_OS_TYPE_WINDOWS = 3,
+ VIC_GENERIC_PROV_OS_TYPE_SOLARIS = 4,
};
struct vic_provinfo {
@@ -61,14 +62,22 @@ struct vic_provinfo {
} tlv[0];
} __packed;
+#define VIC_PROVINFO_ADD_TLV(vp, tlvtype, tlvlen, data) \
+ do { \
+ err = vic_provinfo_add_tlv(vp, tlvtype, tlvlen, data); \
+ if (err) \
+ goto add_tlv_failure; \
+ } while (0)
+
#define VIC_PROVINFO_MAX_DATA 1385
#define VIC_PROVINFO_MAX_TLV_DATA (VIC_PROVINFO_MAX_DATA - \
sizeof(struct vic_provinfo))
-struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, u8 *oui, u8 type);
+struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, const u8 *oui,
+ const u8 type);
void vic_provinfo_free(struct vic_provinfo *vp);
int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length,
- void *value);
+ const void *value);
size_t vic_provinfo_size(struct vic_provinfo *vp);
#endif /* _VNIC_VIC_H_ */
diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
index 380d0614a89..b5f6173130f 100644
--- a/drivers/net/ewrk3.c
+++ b/drivers/net/ewrk3.c
@@ -1545,7 +1545,7 @@ static int ewrk3_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
}
ecmd->supported |= SUPPORTED_10baseT_Half;
- ecmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(ecmd, SPEED_10);
ecmd->duplex = DUPLEX_HALF;
return 0;
}
@@ -1604,55 +1604,47 @@ static u32 ewrk3_get_link(struct net_device *dev)
return !(cmr & CMR_LINK);
}
-static int ewrk3_phys_id(struct net_device *dev, u32 data)
+static int ewrk3_set_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
struct ewrk3_private *lp = netdev_priv(dev);
unsigned long iobase = dev->base_addr;
- unsigned long flags;
u8 cr;
- int count;
-
- /* Toggle LED 4x per second */
- count = data << 2;
- spin_lock_irqsave(&lp->hw_lock, flags);
-
- /* Bail if a PHYS_ID is already in progress */
- if (lp->led_mask == 0) {
- spin_unlock_irqrestore(&lp->hw_lock, flags);
- return -EBUSY;
- }
+ spin_lock_irq(&lp->hw_lock);
- /* Prevent ISR from twiddling the LED */
- lp->led_mask = 0;
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ /* Prevent ISR from twiddling the LED */
+ lp->led_mask = 0;
+ spin_unlock_irq(&lp->hw_lock);
+ return 2; /* cycle on/off twice per second */
- while (count--) {
- /* Toggle the LED */
+ case ETHTOOL_ID_ON:
cr = inb(EWRK3_CR);
- outb(cr ^ CR_LED, EWRK3_CR);
+ outb(cr | CR_LED, EWRK3_CR);
+ break;
- /* Wait a little while */
- spin_unlock_irqrestore(&lp->hw_lock, flags);
- msleep(250);
- spin_lock_irqsave(&lp->hw_lock, flags);
+ case ETHTOOL_ID_OFF:
+ cr = inb(EWRK3_CR);
+ outb(cr & ~CR_LED, EWRK3_CR);
+ break;
- /* Exit if we got a signal */
- if (signal_pending(current))
- break;
+ case ETHTOOL_ID_INACTIVE:
+ lp->led_mask = CR_LED;
+ cr = inb(EWRK3_CR);
+ outb(cr & ~CR_LED, EWRK3_CR);
}
+ spin_unlock_irq(&lp->hw_lock);
- lp->led_mask = CR_LED;
- cr = inb(EWRK3_CR);
- outb(cr & ~CR_LED, EWRK3_CR);
- spin_unlock_irqrestore(&lp->hw_lock, flags);
- return signal_pending(current) ? -ERESTARTSYS : 0;
+ return 0;
}
static const struct ethtool_ops ethtool_ops_203 = {
.get_drvinfo = ewrk3_get_drvinfo,
.get_settings = ewrk3_get_settings,
.set_settings = ewrk3_set_settings,
- .phys_id = ewrk3_phys_id,
+ .set_phys_id = ewrk3_set_phys_id,
};
static const struct ethtool_ops ethtool_ops = {
@@ -1660,7 +1652,7 @@ static const struct ethtool_ops ethtool_ops = {
.get_settings = ewrk3_get_settings,
.set_settings = ewrk3_set_settings,
.get_link = ewrk3_get_link,
- .phys_id = ewrk3_phys_id,
+ .set_phys_id = ewrk3_set_phys_id,
};
/*
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index d5ab4dad505..d09e8b0add0 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -774,7 +774,6 @@ struct fe_priv {
u32 driver_data;
u32 device_id;
u32 register_size;
- int rx_csum;
u32 mac_in_use;
int mgmt_version;
int mgmt_sema;
@@ -3956,6 +3955,7 @@ static int nv_set_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
static int nv_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
struct fe_priv *np = netdev_priv(dev);
+ u32 speed;
int adv;
spin_lock_irq(&np->lock);
@@ -3975,23 +3975,26 @@ static int nv_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
if (netif_carrier_ok(dev)) {
switch (np->linkspeed & (NVREG_LINKSPEED_MASK)) {
case NVREG_LINKSPEED_10:
- ecmd->speed = SPEED_10;
+ speed = SPEED_10;
break;
case NVREG_LINKSPEED_100:
- ecmd->speed = SPEED_100;
+ speed = SPEED_100;
break;
case NVREG_LINKSPEED_1000:
- ecmd->speed = SPEED_1000;
+ speed = SPEED_1000;
+ break;
+ default:
+ speed = -1;
break;
}
ecmd->duplex = DUPLEX_HALF;
if (np->duplex)
ecmd->duplex = DUPLEX_FULL;
} else {
- ecmd->speed = -1;
+ speed = -1;
ecmd->duplex = -1;
}
-
+ ethtool_cmd_speed_set(ecmd, speed);
ecmd->autoneg = np->autoneg;
ecmd->advertising = ADVERTISED_MII;
@@ -4030,6 +4033,7 @@ static int nv_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
struct fe_priv *np = netdev_priv(dev);
+ u32 speed = ethtool_cmd_speed(ecmd);
if (ecmd->port != PORT_MII)
return -EINVAL;
@@ -4055,7 +4059,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
/* Note: autonegotiation disable, speed 1000 intentionally
* forbidden - no one should need that. */
- if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100)
+ if (speed != SPEED_10 && speed != SPEED_100)
return -EINVAL;
if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
return -EINVAL;
@@ -4139,13 +4143,13 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
- if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_HALF)
+ if (speed == SPEED_10 && ecmd->duplex == DUPLEX_HALF)
adv |= ADVERTISE_10HALF;
- if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_FULL)
+ if (speed == SPEED_10 && ecmd->duplex == DUPLEX_FULL)
adv |= ADVERTISE_10FULL;
- if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_HALF)
+ if (speed == SPEED_100 && ecmd->duplex == DUPLEX_HALF)
adv |= ADVERTISE_100HALF;
- if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_FULL)
+ if (speed == SPEED_100 && ecmd->duplex == DUPLEX_FULL)
adv |= ADVERTISE_100FULL;
np->pause_flags &= ~(NV_PAUSEFRAME_AUTONEG|NV_PAUSEFRAME_RX_ENABLE|NV_PAUSEFRAME_TX_ENABLE);
if (np->pause_flags & NV_PAUSEFRAME_RX_REQ) {/* for rx we set both advertisements but disable tx pause */
@@ -4264,16 +4268,6 @@ static int nv_nway_reset(struct net_device *dev)
return ret;
}
-static int nv_set_tso(struct net_device *dev, u32 value)
-{
- struct fe_priv *np = netdev_priv(dev);
-
- if ((np->driver_data & DEV_HAS_CHECKSUM))
- return ethtool_op_set_tso(dev, value);
- else
- return -EOPNOTSUPP;
-}
-
static void nv_get_ringparam(struct net_device *dev, struct ethtool_ringparam* ring)
{
struct fe_priv *np = netdev_priv(dev);
@@ -4480,58 +4474,36 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam*
return 0;
}
-static u32 nv_get_rx_csum(struct net_device *dev)
+static u32 nv_fix_features(struct net_device *dev, u32 features)
{
- struct fe_priv *np = netdev_priv(dev);
- return np->rx_csum != 0;
+ /* vlan is dependent on rx checksum offload */
+ if (features & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX))
+ features |= NETIF_F_RXCSUM;
+
+ return features;
}
-static int nv_set_rx_csum(struct net_device *dev, u32 data)
+static int nv_set_features(struct net_device *dev, u32 features)
{
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
- int retcode = 0;
-
- if (np->driver_data & DEV_HAS_CHECKSUM) {
- if (data) {
- np->rx_csum = 1;
- np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
- } else {
- np->rx_csum = 0;
- /* vlan is dependent on rx checksum offload */
- if (!(np->vlanctl_bits & NVREG_VLANCONTROL_ENABLE))
- np->txrxctl_bits &= ~NVREG_TXRXCTL_RXCHECK;
- }
- if (netif_running(dev)) {
- spin_lock_irq(&np->lock);
- writel(np->txrxctl_bits, base + NvRegTxRxControl);
- spin_unlock_irq(&np->lock);
- }
- } else {
- return -EINVAL;
- }
+ u32 changed = dev->features ^ features;
- return retcode;
-}
+ if (changed & NETIF_F_RXCSUM) {
+ spin_lock_irq(&np->lock);
-static int nv_set_tx_csum(struct net_device *dev, u32 data)
-{
- struct fe_priv *np = netdev_priv(dev);
+ if (features & NETIF_F_RXCSUM)
+ np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
+ else
+ np->txrxctl_bits &= ~NVREG_TXRXCTL_RXCHECK;
- if (np->driver_data & DEV_HAS_CHECKSUM)
- return ethtool_op_set_tx_csum(dev, data);
- else
- return -EOPNOTSUPP;
-}
+ if (netif_running(dev))
+ writel(np->txrxctl_bits, base + NvRegTxRxControl);
-static int nv_set_sg(struct net_device *dev, u32 data)
-{
- struct fe_priv *np = netdev_priv(dev);
+ spin_unlock_irq(&np->lock);
+ }
- if (np->driver_data & DEV_HAS_CHECKSUM)
- return ethtool_op_set_sg(dev, data);
- else
- return -EOPNOTSUPP;
+ return 0;
}
static int nv_get_sset_count(struct net_device *dev, int sset)
@@ -4896,15 +4868,10 @@ static const struct ethtool_ops ops = {
.get_regs_len = nv_get_regs_len,
.get_regs = nv_get_regs,
.nway_reset = nv_nway_reset,
- .set_tso = nv_set_tso,
.get_ringparam = nv_get_ringparam,
.set_ringparam = nv_set_ringparam,
.get_pauseparam = nv_get_pauseparam,
.set_pauseparam = nv_set_pauseparam,
- .get_rx_csum = nv_get_rx_csum,
- .set_rx_csum = nv_set_rx_csum,
- .set_tx_csum = nv_set_tx_csum,
- .set_sg = nv_set_sg,
.get_strings = nv_get_strings,
.get_ethtool_stats = nv_get_ethtool_stats,
.get_sset_count = nv_get_sset_count,
@@ -5235,6 +5202,8 @@ static const struct net_device_ops nv_netdev_ops = {
.ndo_start_xmit = nv_start_xmit,
.ndo_tx_timeout = nv_tx_timeout,
.ndo_change_mtu = nv_change_mtu,
+ .ndo_fix_features = nv_fix_features,
+ .ndo_set_features = nv_set_features,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = nv_set_mac_address,
.ndo_set_multicast_list = nv_set_multicast,
@@ -5251,6 +5220,8 @@ static const struct net_device_ops nv_netdev_ops_optimized = {
.ndo_start_xmit = nv_start_xmit_optimized,
.ndo_tx_timeout = nv_tx_timeout,
.ndo_change_mtu = nv_change_mtu,
+ .ndo_fix_features = nv_fix_features,
+ .ndo_set_features = nv_set_features,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = nv_set_mac_address,
.ndo_set_multicast_list = nv_set_multicast,
@@ -5364,11 +5335,10 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
np->pkt_limit = NV_PKTLIMIT_2;
if (id->driver_data & DEV_HAS_CHECKSUM) {
- np->rx_csum = 1;
np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
- dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
- dev->features |= NETIF_F_TSO;
- dev->features |= NETIF_F_GRO;
+ dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG |
+ NETIF_F_TSO | NETIF_F_RXCSUM;
+ dev->features |= dev->hw_features;
}
np->vlanctl_bits = 0;
@@ -5384,7 +5354,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
np->pause_flags |= NV_PAUSEFRAME_TX_CAPABLE | NV_PAUSEFRAME_TX_REQ;
}
-
err = -ENOMEM;
np->base = ioremap(addr, np->register_size);
if (!np->base)
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 5131e61c358..21abb5c01a5 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -956,8 +956,6 @@ static const struct ethtool_ops fs_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_msglevel = fs_get_msglevel,
.set_msglevel = fs_set_msglevel,
- .set_tx_csum = ethtool_op_set_tx_csum, /* local! */
- .set_sg = ethtool_op_set_sg,
.get_regs = fs_get_regs,
};
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 2a0ad9a501b..ff60b23a5b7 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -365,7 +365,7 @@ static void gfar_init_mac(struct net_device *ndev)
gfar_write(&regs->rir0, DEFAULT_RIR0);
}
- if (priv->rx_csum_enable)
+ if (ndev->features & NETIF_F_RXCSUM)
rctrl |= RCTRL_CHECKSUMMING;
if (priv->extended_hash) {
@@ -463,6 +463,7 @@ static const struct net_device_ops gfar_netdev_ops = {
.ndo_start_xmit = gfar_start_xmit,
.ndo_stop = gfar_close,
.ndo_change_mtu = gfar_change_mtu,
+ .ndo_set_features = gfar_set_features,
.ndo_set_multicast_list = gfar_set_multi,
.ndo_tx_timeout = gfar_timeout,
.ndo_do_ioctl = gfar_ioctl,
@@ -513,7 +514,7 @@ void unlock_tx_qs(struct gfar_private *priv)
/* Returns 1 if incoming frames use an FCB */
static inline int gfar_uses_fcb(struct gfar_private *priv)
{
- return priv->vlgrp || priv->rx_csum_enable ||
+ return priv->vlgrp || (priv->ndev->features & NETIF_F_RXCSUM) ||
(priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER);
}
@@ -1030,10 +1031,11 @@ static int gfar_probe(struct platform_device *ofdev)
netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll, GFAR_DEV_WEIGHT);
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
- priv->rx_csum_enable = 1;
- dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_HIGHDMA;
- } else
- priv->rx_csum_enable = 0;
+ dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
+ NETIF_F_RXCSUM;
+ dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG |
+ NETIF_F_RXCSUM | NETIF_F_HIGHDMA;
+ }
priv->vlgrp = NULL;
@@ -2697,7 +2699,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
if (priv->padding)
skb_pull(skb, priv->padding);
- if (priv->rx_csum_enable)
+ if (dev->features & NETIF_F_RXCSUM)
gfar_rx_checksum(skb, fcb);
/* Tell the skb what kind of packet this is */
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index b2fe7edefad..fc86f519544 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -382,23 +382,6 @@ extern const char gfar_driver_version[];
#define BD_LFLAG(flags) ((flags) << 16)
#define BD_LENGTH_MASK 0x0000ffff
-#define CLASS_CODE_UNRECOG 0x00
-#define CLASS_CODE_DUMMY1 0x01
-#define CLASS_CODE_ETHERTYPE1 0x02
-#define CLASS_CODE_ETHERTYPE2 0x03
-#define CLASS_CODE_USER_PROG1 0x04
-#define CLASS_CODE_USER_PROG2 0x05
-#define CLASS_CODE_USER_PROG3 0x06
-#define CLASS_CODE_USER_PROG4 0x07
-#define CLASS_CODE_TCP_IPV4 0x08
-#define CLASS_CODE_UDP_IPV4 0x09
-#define CLASS_CODE_AH_ESP_IPV4 0x0a
-#define CLASS_CODE_SCTP_IPV4 0x0b
-#define CLASS_CODE_TCP_IPV6 0x0c
-#define CLASS_CODE_UDP_IPV6 0x0d
-#define CLASS_CODE_AH_ESP_IPV6 0x0e
-#define CLASS_CODE_SCTP_IPV6 0x0f
-
#define FPR_FILER_MASK 0xFFFFFFFF
#define MAX_FILER_IDX 0xFF
@@ -1100,7 +1083,7 @@ struct gfar_private {
struct device_node *phy_node;
struct device_node *tbi_node;
u32 device_flags;
- unsigned char rx_csum_enable:1,
+ unsigned char
extended_hash:1,
bd_stash_en:1,
rx_filer_enable:1,
@@ -1170,6 +1153,7 @@ extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
extern void gfar_configure_coalescing(struct gfar_private *priv,
unsigned long tx_mask, unsigned long rx_mask);
void gfar_init_sysfs(struct net_device *dev);
+int gfar_set_features(struct net_device *dev, u32 features);
extern const struct ethtool_ops gfar_ethtool_ops;
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 3bc8e276ba4..493d743839d 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -517,15 +517,15 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva
return err;
}
-static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
+int gfar_set_features(struct net_device *dev, u32 features)
{
struct gfar_private *priv = netdev_priv(dev);
unsigned long flags;
int err = 0, i = 0;
+ u32 changed = dev->features ^ features;
- if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
- return -EOPNOTSUPP;
-
+ if (!(changed & NETIF_F_RXCSUM))
+ return 0;
if (dev->flags & IFF_UP) {
/* Halt TX and RX, and process the frames which
@@ -546,58 +546,15 @@ static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
/* Now we take down the rings to rebuild them */
stop_gfar(dev);
- }
- spin_lock_irqsave(&priv->bflock, flags);
- priv->rx_csum_enable = data;
- spin_unlock_irqrestore(&priv->bflock, flags);
+ dev->features = features;
- if (dev->flags & IFF_UP) {
err = startup_gfar(dev);
netif_tx_wake_all_queues(dev);
}
return err;
}
-static uint32_t gfar_get_rx_csum(struct net_device *dev)
-{
- struct gfar_private *priv = netdev_priv(dev);
-
- if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
- return 0;
-
- return priv->rx_csum_enable;
-}
-
-static int gfar_set_tx_csum(struct net_device *dev, uint32_t data)
-{
- struct gfar_private *priv = netdev_priv(dev);
-
- if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
- return -EOPNOTSUPP;
-
- netif_tx_lock_bh(dev);
-
- if (data)
- dev->features |= NETIF_F_IP_CSUM;
- else
- dev->features &= ~NETIF_F_IP_CSUM;
-
- netif_tx_unlock_bh(dev);
-
- return 0;
-}
-
-static uint32_t gfar_get_tx_csum(struct net_device *dev)
-{
- struct gfar_private *priv = netdev_priv(dev);
-
- if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
- return 0;
-
- return (dev->features & NETIF_F_IP_CSUM) != 0;
-}
-
static uint32_t gfar_get_msglevel(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
@@ -645,42 +602,6 @@ static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
}
#endif
-static int gfar_ethflow_to_class(int flow_type, u64 *class)
-{
- switch (flow_type) {
- case TCP_V4_FLOW:
- *class = CLASS_CODE_TCP_IPV4;
- break;
- case UDP_V4_FLOW:
- *class = CLASS_CODE_UDP_IPV4;
- break;
- case AH_V4_FLOW:
- case ESP_V4_FLOW:
- *class = CLASS_CODE_AH_ESP_IPV4;
- break;
- case SCTP_V4_FLOW:
- *class = CLASS_CODE_SCTP_IPV4;
- break;
- case TCP_V6_FLOW:
- *class = CLASS_CODE_TCP_IPV6;
- break;
- case UDP_V6_FLOW:
- *class = CLASS_CODE_UDP_IPV6;
- break;
- case AH_V6_FLOW:
- case ESP_V6_FLOW:
- *class = CLASS_CODE_AH_ESP_IPV6;
- break;
- case SCTP_V6_FLOW:
- *class = CLASS_CODE_SCTP_IPV6;
- break;
- default:
- return 0;
- }
-
- return 1;
-}
-
static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow)
{
u32 fcr = 0x0, fpr = FPR_FILER_MASK;
@@ -778,11 +699,6 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u
case UDP_V6_FLOW:
cmp_rqfpr = RQFPR_IPV6 |RQFPR_UDP;
break;
- case IPV4_FLOW:
- cmp_rqfpr = RQFPR_IPV4;
- case IPV6_FLOW:
- cmp_rqfpr = RQFPR_IPV6;
- break;
default:
printk(KERN_ERR "Right now this class is not supported\n");
return 0;
@@ -848,18 +764,9 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u
static int gfar_set_hash_opts(struct gfar_private *priv, struct ethtool_rxnfc *cmd)
{
- u64 class;
-
- if (!gfar_ethflow_to_class(cmd->flow_type, &class))
- return -EINVAL;
-
- if (class < CLASS_CODE_USER_PROG1 ||
- class > CLASS_CODE_SCTP_IPV6)
- return -EINVAL;
-
/* write the filer rules here */
if (!gfar_ethflow_to_filer_table(priv, cmd->data, cmd->flow_type))
- return -1;
+ return -EINVAL;
return 0;
}
@@ -894,11 +801,6 @@ const struct ethtool_ops gfar_ethtool_ops = {
.get_strings = gfar_gstrings,
.get_sset_count = gfar_sset_count,
.get_ethtool_stats = gfar_fill_stats,
- .get_rx_csum = gfar_get_rx_csum,
- .get_tx_csum = gfar_get_tx_csum,
- .set_rx_csum = gfar_set_rx_csum,
- .set_tx_csum = gfar_set_tx_csum,
- .set_sg = ethtool_op_set_sg,
.get_msglevel = gfar_get_msglevel,
.set_msglevel = gfar_set_msglevel,
#ifdef CONFIG_PM
diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index 396ff7d785d..f181304a7ab 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -901,7 +901,7 @@ static int greth_rx_gbit(struct net_device *dev, int limit)
skb_put(skb, pkt_len);
- if (greth->flags & GRETH_FLAG_RX_CSUM && hw_checksummed(status))
+ if (dev->features & NETIF_F_RXCSUM && hw_checksummed(status))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
skb_checksum_none_assert(skb);
@@ -1142,41 +1142,6 @@ static void greth_get_regs(struct net_device *dev, struct ethtool_regs *regs, vo
buff[i] = greth_read_bd(&greth_regs[i]);
}
-static u32 greth_get_rx_csum(struct net_device *dev)
-{
- struct greth_private *greth = netdev_priv(dev);
- return (greth->flags & GRETH_FLAG_RX_CSUM) != 0;
-}
-
-static int greth_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct greth_private *greth = netdev_priv(dev);
-
- spin_lock_bh(&greth->devlock);
-
- if (data)
- greth->flags |= GRETH_FLAG_RX_CSUM;
- else
- greth->flags &= ~GRETH_FLAG_RX_CSUM;
-
- spin_unlock_bh(&greth->devlock);
-
- return 0;
-}
-
-static u32 greth_get_tx_csum(struct net_device *dev)
-{
- return (dev->features & NETIF_F_IP_CSUM) != 0;
-}
-
-static int greth_set_tx_csum(struct net_device *dev, u32 data)
-{
- netif_tx_lock_bh(dev);
- ethtool_op_set_tx_csum(dev, data);
- netif_tx_unlock_bh(dev);
- return 0;
-}
-
static const struct ethtool_ops greth_ethtool_ops = {
.get_msglevel = greth_get_msglevel,
.set_msglevel = greth_set_msglevel,
@@ -1185,10 +1150,6 @@ static const struct ethtool_ops greth_ethtool_ops = {
.get_drvinfo = greth_get_drvinfo,
.get_regs_len = greth_get_regs_len,
.get_regs = greth_get_regs,
- .get_rx_csum = greth_get_rx_csum,
- .set_rx_csum = greth_set_rx_csum,
- .get_tx_csum = greth_get_tx_csum,
- .set_tx_csum = greth_set_tx_csum,
.get_link = ethtool_op_get_link,
};
@@ -1570,9 +1531,10 @@ static int __devinit greth_of_probe(struct platform_device *ofdev)
GRETH_REGSAVE(regs->status, 0xFF);
if (greth->gbit_mac) {
- dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HIGHDMA;
+ dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_RXCSUM;
+ dev->features = dev->hw_features | NETIF_F_HIGHDMA;
greth_netdev_ops.ndo_start_xmit = greth_start_xmit_gbit;
- greth->flags = GRETH_FLAG_RX_CSUM;
}
if (greth->multicast) {
diff --git a/drivers/net/greth.h b/drivers/net/greth.h
index be0f2062bd1..9a0040dee4d 100644
--- a/drivers/net/greth.h
+++ b/drivers/net/greth.h
@@ -77,9 +77,6 @@
*/
#define MAX_FRAME_SIZE 1520
-/* Flags */
-#define GRETH_FLAG_RX_CSUM 0x1
-
/* GRETH APB registers */
struct greth_regs {
u32 control;
@@ -133,7 +130,6 @@ struct greth_private {
unsigned int duplex;
u32 msg_enable;
- u32 flags;
u8 phyaddr;
u8 multicast;
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 80d25ed5334..a09041aa850 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -132,13 +132,8 @@ static int tx_params[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
/*
* RX_CHECKSUM turns on card-generated receive checksum generation for
* TCP and UDP packets. Otherwise the upper layers do the calculation.
- * TX_CHECKSUM won't do anything too useful, even if it works. There's no
- * easy mechanism by which to tell the TCP/UDP stack that it need not
- * generate checksums for this device. But if somebody can find a way
- * to get that to work, most of the card work is in here already.
* 3/10/1999 Pete Wyckoff <wyckoff@ca.sandia.gov>
*/
-#undef TX_CHECKSUM
#define RX_CHECKSUM
/* Operational parameters that usually are not changed. */
@@ -630,11 +625,6 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
SET_NETDEV_DEV(dev, &pdev->dev);
-#ifdef TX_CHECKSUM
- printk("check that skbcopy in ip_queue_xmit isn't happening\n");
- dev->hard_header_len += 8; /* for cksum tag */
-#endif
-
for (i = 0; i < 6; i++)
dev->dev_addr[i] = 1 ? read_eeprom(ioaddr, 4 + i)
: readb(ioaddr + StationAddr + i);
@@ -937,11 +927,7 @@ static int hamachi_open(struct net_device *dev)
/* always 1, takes no more time to do it */
writew(0x0001, ioaddr + RxChecksum);
-#ifdef TX_CHECKSUM
- writew(0x0001, ioaddr + TxChecksum);
-#else
writew(0x0000, ioaddr + TxChecksum);
-#endif
writew(0x8000, ioaddr + MACCnfg); /* Soft reset the MAC */
writew(0x215F, ioaddr + MACCnfg);
writew(0x000C, ioaddr + FrameGap0);
@@ -1226,40 +1212,6 @@ static void hamachi_init_ring(struct net_device *dev)
}
-#ifdef TX_CHECKSUM
-#define csum_add(it, val) \
-do { \
- it += (u16) (val); \
- if (it & 0xffff0000) { \
- it &= 0xffff; \
- ++it; \
- } \
-} while (0)
- /* printk("add %04x --> %04x\n", val, it); \ */
-
-/* uh->len already network format, do not swap */
-#define pseudo_csum_udp(sum,ih,uh) do { \
- sum = 0; \
- csum_add(sum, (ih)->saddr >> 16); \
- csum_add(sum, (ih)->saddr & 0xffff); \
- csum_add(sum, (ih)->daddr >> 16); \
- csum_add(sum, (ih)->daddr & 0xffff); \
- csum_add(sum, cpu_to_be16(IPPROTO_UDP)); \
- csum_add(sum, (uh)->len); \
-} while (0)
-
-/* swap len */
-#define pseudo_csum_tcp(sum,ih,len) do { \
- sum = 0; \
- csum_add(sum, (ih)->saddr >> 16); \
- csum_add(sum, (ih)->saddr & 0xffff); \
- csum_add(sum, (ih)->daddr >> 16); \
- csum_add(sum, (ih)->daddr & 0xffff); \
- csum_add(sum, cpu_to_be16(IPPROTO_TCP)); \
- csum_add(sum, htons(len)); \
-} while (0)
-#endif
-
static netdev_tx_t hamachi_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
@@ -1292,36 +1244,6 @@ static netdev_tx_t hamachi_start_xmit(struct sk_buff *skb,
hmp->tx_skbuff[entry] = skb;
-#ifdef TX_CHECKSUM
- {
- /* tack on checksum tag */
- u32 tagval = 0;
- struct ethhdr *eh = (struct ethhdr *)skb->data;
- if (eh->h_proto == cpu_to_be16(ETH_P_IP)) {
- struct iphdr *ih = (struct iphdr *)((char *)eh + ETH_HLEN);
- if (ih->protocol == IPPROTO_UDP) {
- struct udphdr *uh
- = (struct udphdr *)((char *)ih + ih->ihl*4);
- u32 offset = ((unsigned char *)uh + 6) - skb->data;
- u32 pseudo;
- pseudo_csum_udp(pseudo, ih, uh);
- pseudo = htons(pseudo);
- printk("udp cksum was %04x, sending pseudo %04x\n",
- uh->check, pseudo);
- uh->check = 0; /* zero out uh->check before card calc */
- /*
- * start at 14 (skip ethhdr), store at offset (uh->check),
- * use pseudo value given.
- */
- tagval = (14 << 24) | (offset << 16) | pseudo;
- } else if (ih->protocol == IPPROTO_TCP) {
- printk("tcp, no auto cksum\n");
- }
- }
- *(u32 *)skb_push(skb, 8) = tagval;
- }
-#endif
-
hmp->tx_ring[entry].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
skb->data, skb->len, PCI_DMA_TODEVICE));
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 8931168d3e7..18d8affecd1 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -516,10 +516,6 @@ static int bpq_new_device(struct net_device *edev)
memcpy(bpq->dest_addr, bcast_addr, sizeof(bpq_eth_addr));
memcpy(bpq->acpt_addr, bcast_addr, sizeof(bpq_eth_addr));
- err = dev_alloc_name(ndev, ndev->name);
- if (err < 0)
- goto error;
-
err = register_netdevice(ndev);
if (err)
goto error;
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index 8e10d2f6a5a..c52a1df5d92 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -188,14 +188,14 @@ struct hp100_private {
* variables
*/
#ifdef CONFIG_ISA
-static const char *hp100_isa_tbl[] = {
+static const char *const hp100_isa_tbl[] __devinitconst = {
"HWPF150", /* HP J2573 rev A */
"HWP1950", /* HP J2573 */
};
#endif
#ifdef CONFIG_EISA
-static struct eisa_device_id hp100_eisa_tbl[] = {
+static const struct eisa_device_id hp100_eisa_tbl[] __devinitconst = {
{ "HWPF180" }, /* HP J2577 rev A */
{ "HWP1920" }, /* HP 27248B */
{ "HWP1940" }, /* HP J2577 */
@@ -336,7 +336,7 @@ static __devinit const char *hp100_read_id(int ioaddr)
}
#ifdef CONFIG_ISA
-static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr)
+static __devinit int hp100_isa_probe1(struct net_device *dev, int ioaddr)
{
const char *sig;
int i;
@@ -372,7 +372,7 @@ static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr)
* EISA and PCI are handled by device infrastructure.
*/
-static int __init hp100_isa_probe(struct net_device *dev, int addr)
+static int __devinit hp100_isa_probe(struct net_device *dev, int addr)
{
int err = -ENODEV;
@@ -396,7 +396,7 @@ static int __init hp100_isa_probe(struct net_device *dev, int addr)
#endif /* CONFIG_ISA */
#if !defined(MODULE) && defined(CONFIG_ISA)
-struct net_device * __init hp100_probe(int unit)
+struct net_device * __devinit hp100_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
int err;
@@ -2843,7 +2843,7 @@ static void cleanup_dev(struct net_device *d)
}
#ifdef CONFIG_EISA
-static int __init hp100_eisa_probe (struct device *gendev)
+static int __devinit hp100_eisa_probe (struct device *gendev)
{
struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
struct eisa_device *edev = to_eisa_device(gendev);
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 3bb990b6651..079450fe5e9 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -2053,13 +2053,6 @@ static void emac_ethtool_get_pauseparam(struct net_device *ndev,
mutex_unlock(&dev->link_lock);
}
-static u32 emac_ethtool_get_rx_csum(struct net_device *ndev)
-{
- struct emac_instance *dev = netdev_priv(ndev);
-
- return dev->tah_dev != NULL;
-}
-
static int emac_get_regs_len(struct emac_instance *dev)
{
if (emac_has_feature(dev, EMAC_FTR_EMAC4))
@@ -2203,15 +2196,11 @@ static const struct ethtool_ops emac_ethtool_ops = {
.get_ringparam = emac_ethtool_get_ringparam,
.get_pauseparam = emac_ethtool_get_pauseparam,
- .get_rx_csum = emac_ethtool_get_rx_csum,
-
.get_strings = emac_ethtool_get_strings,
.get_sset_count = emac_ethtool_get_sset_count,
.get_ethtool_stats = emac_ethtool_get_ethtool_stats,
.get_link = ethtool_op_get_link,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .get_sg = ethtool_op_get_sg,
};
static int emac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
@@ -2859,8 +2848,10 @@ static int __devinit emac_probe(struct platform_device *ofdev)
if (err != 0)
goto err_detach_tah;
- if (dev->tah_dev)
- ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+ if (dev->tah_dev) {
+ ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG;
+ ndev->features |= ndev->hw_features | NETIF_F_RXCSUM;
+ }
ndev->watchdog_timeo = 5 * HZ;
if (emac_phy_supports_gige(dev->phy_mode)) {
ndev->netdev_ops = &emac_gige_netdev_ops;
diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c
index 8ff68ae6b52..136d7544cc3 100644
--- a/drivers/net/ibmlana.c
+++ b/drivers/net/ibmlana.c
@@ -782,7 +782,8 @@ static int ibmlana_open(struct net_device *dev)
/* register resources - only necessary for IRQ */
- result = request_irq(priv->realirq, irq_handler, IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev);
+ result = request_irq(priv->realirq, irq_handler, IRQF_SHARED,
+ dev->name, dev);
if (result != 0) {
printk(KERN_ERR "%s: failed to register irq %d\n", dev->name, dev->irq);
return result;
@@ -894,12 +895,12 @@ static int ibmlana_irq;
static int ibmlana_io;
static int startslot; /* counts through slots when probing multiple devices */
-static short ibmlana_adapter_ids[] __initdata = {
+static const short ibmlana_adapter_ids[] __devinitconst = {
IBM_LANA_ID,
0x0000
};
-static char *ibmlana_adapter_names[] __devinitdata = {
+static const char *const ibmlana_adapter_names[] __devinitconst = {
"IBM LAN Adapter/A",
NULL
};
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 5522d459654..b388d782c7c 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -710,7 +710,7 @@ static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
SUPPORTED_FIBRE);
cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg |
ADVERTISED_FIBRE);
- cmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(cmd, SPEED_1000);
cmd->duplex = DUPLEX_FULL;
cmd->port = PORT_FIBRE;
cmd->phy_address = 0;
@@ -729,45 +729,24 @@ static void netdev_get_drvinfo(struct net_device *dev,
sizeof(info->version) - 1);
}
-static void ibmveth_set_rx_csum_flags(struct net_device *dev, u32 data)
+static u32 ibmveth_fix_features(struct net_device *dev, u32 features)
{
- struct ibmveth_adapter *adapter = netdev_priv(dev);
-
- if (data) {
- adapter->rx_csum = 1;
- } else {
- /*
- * Since the ibmveth firmware interface does not have the
- * concept of separate tx/rx checksum offload enable, if rx
- * checksum is disabled we also have to disable tx checksum
- * offload. Once we disable rx checksum offload, we are no
- * longer allowed to send tx buffers that are not properly
- * checksummed.
- */
- adapter->rx_csum = 0;
- dev->features &= ~NETIF_F_IP_CSUM;
- dev->features &= ~NETIF_F_IPV6_CSUM;
- }
-}
+ /*
+ * Since the ibmveth firmware interface does not have the
+ * concept of separate tx/rx checksum offload enable, if rx
+ * checksum is disabled we also have to disable tx checksum
+ * offload. Once we disable rx checksum offload, we are no
+ * longer allowed to send tx buffers that are not properly
+ * checksummed.
+ */
-static void ibmveth_set_tx_csum_flags(struct net_device *dev, u32 data)
-{
- struct ibmveth_adapter *adapter = netdev_priv(dev);
+ if (!(features & NETIF_F_RXCSUM))
+ features &= ~NETIF_F_ALL_CSUM;
- if (data) {
- if (adapter->fw_ipv4_csum_support)
- dev->features |= NETIF_F_IP_CSUM;
- if (adapter->fw_ipv6_csum_support)
- dev->features |= NETIF_F_IPV6_CSUM;
- adapter->rx_csum = 1;
- } else {
- dev->features &= ~NETIF_F_IP_CSUM;
- dev->features &= ~NETIF_F_IPV6_CSUM;
- }
+ return features;
}
-static int ibmveth_set_csum_offload(struct net_device *dev, u32 data,
- void (*done) (struct net_device *, u32))
+static int ibmveth_set_csum_offload(struct net_device *dev, u32 data)
{
struct ibmveth_adapter *adapter = netdev_priv(dev);
unsigned long set_attr, clr_attr, ret_attr;
@@ -827,8 +806,8 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data,
} else
adapter->fw_ipv6_csum_support = data;
- if (ret == H_SUCCESS || ret6 == H_SUCCESS)
- done(dev, data);
+ if (ret != H_SUCCESS || ret6 != H_SUCCESS)
+ adapter->rx_csum = data;
else
rc1 = -EIO;
} else {
@@ -844,41 +823,22 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data,
return rc1 ? rc1 : rc2;
}
-static int ibmveth_set_rx_csum(struct net_device *dev, u32 data)
+static int ibmveth_set_features(struct net_device *dev, u32 features)
{
struct ibmveth_adapter *adapter = netdev_priv(dev);
+ int rx_csum = !!(features & NETIF_F_RXCSUM);
+ int rc;
- if ((data && adapter->rx_csum) || (!data && !adapter->rx_csum))
- return 0;
-
- return ibmveth_set_csum_offload(dev, data, ibmveth_set_rx_csum_flags);
-}
-
-static int ibmveth_set_tx_csum(struct net_device *dev, u32 data)
-{
- struct ibmveth_adapter *adapter = netdev_priv(dev);
- int rc = 0;
-
- if (data && (dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)))
- return 0;
- if (!data && !(dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)))
+ if (rx_csum == adapter->rx_csum)
return 0;
- if (data && !adapter->rx_csum)
- rc = ibmveth_set_csum_offload(dev, data,
- ibmveth_set_tx_csum_flags);
- else
- ibmveth_set_tx_csum_flags(dev, data);
+ rc = ibmveth_set_csum_offload(dev, rx_csum);
+ if (rc && !adapter->rx_csum)
+ dev->features = features & ~(NETIF_F_ALL_CSUM | NETIF_F_RXCSUM);
return rc;
}
-static u32 ibmveth_get_rx_csum(struct net_device *dev)
-{
- struct ibmveth_adapter *adapter = netdev_priv(dev);
- return adapter->rx_csum;
-}
-
static void ibmveth_get_strings(struct net_device *dev, u32 stringset, u8 *data)
{
int i;
@@ -914,13 +874,9 @@ static const struct ethtool_ops netdev_ethtool_ops = {
.get_drvinfo = netdev_get_drvinfo,
.get_settings = netdev_get_settings,
.get_link = ethtool_op_get_link,
- .set_tx_csum = ibmveth_set_tx_csum,
- .get_rx_csum = ibmveth_get_rx_csum,
- .set_rx_csum = ibmveth_set_rx_csum,
.get_strings = ibmveth_get_strings,
.get_sset_count = ibmveth_get_sset_count,
.get_ethtool_stats = ibmveth_get_ethtool_stats,
- .set_sg = ethtool_op_set_sg,
};
static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -1345,6 +1301,8 @@ static const struct net_device_ops ibmveth_netdev_ops = {
.ndo_set_multicast_list = ibmveth_set_multicast_list,
.ndo_do_ioctl = ibmveth_ioctl,
.ndo_change_mtu = ibmveth_change_mtu,
+ .ndo_fix_features = ibmveth_fix_features,
+ .ndo_set_features = ibmveth_set_features,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = eth_mac_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1412,7 +1370,9 @@ static int __devinit ibmveth_probe(struct vio_dev *dev,
netdev->netdev_ops = &ibmveth_netdev_ops;
netdev->ethtool_ops = &netdev_ethtool_ops;
SET_NETDEV_DEV(netdev, &dev->dev);
- netdev->features |= NETIF_F_SG;
+ netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+ netdev->features |= netdev->hw_features;
memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
@@ -1437,7 +1397,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev,
netdev_dbg(netdev, "registering netdev...\n");
- ibmveth_set_csum_offload(netdev, 1, ibmveth_set_tx_csum_flags);
+ ibmveth_set_features(netdev, netdev->features);
rc = register_netdev(netdev);
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index e07d487f015..4fecaed67fc 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -233,10 +233,6 @@ static int __init ifb_init_one(int index)
if (!dev_ifb)
return -ENOMEM;
- err = dev_alloc_name(dev_ifb, dev_ifb->name);
- if (err < 0)
- goto err;
-
dev_ifb->rtnl_link_ops = &ifb_link_ops;
err = register_netdevice(dev_ifb);
if (err < 0)
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index 6b256c275e1..0f563c8c5ff 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -244,6 +244,14 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
*/
size += NVM_WORD_SIZE_BASE_SHIFT;
+ /*
+ * Check for invalid size
+ */
+ if ((hw->mac.type == e1000_82576) && (size > 15)) {
+ printk("igb: The NVM size is not valid, "
+ "defaulting to 32K.\n");
+ size = 15;
+ }
nvm->word_size = 1 << size;
if (nvm->word_size == (1 << 15))
nvm->page_size = 128;
@@ -1877,7 +1885,7 @@ static s32 igb_validate_nvm_checksum_82580(struct e1000_hw *hw)
}
if (nvm_data & NVM_COMPATIBILITY_BIT_MASK) {
- /* if chekcsums compatibility bit is set validate checksums
+ /* if checksums compatibility bit is set validate checksums
* for all 4 ports. */
eeprom_regions_count = 4;
}
@@ -1988,6 +1996,7 @@ static s32 igb_update_nvm_checksum_i350(struct e1000_hw *hw)
out:
return ret_val;
}
+
/**
* igb_set_eee_i350 - Enable/disable EEE support
* @hw: pointer to the HW structure
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 1c687e298d5..f4fa4b1751c 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -360,7 +360,7 @@ 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_set_spd_dplx(struct igb_adapter *, u32, u8);
extern int igb_setup_tx_resources(struct igb_ring *);
extern int igb_setup_rx_resources(struct igb_ring *);
extern void igb_free_tx_resources(struct igb_ring *);
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index d976733bbcc..fdc895e5a3f 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -178,11 +178,11 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
if ((status & E1000_STATUS_SPEED_1000) ||
hw->phy.media_type != e1000_media_type_copper)
- ecmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(ecmd, SPEED_1000);
else if (status & E1000_STATUS_SPEED_100)
- ecmd->speed = SPEED_100;
+ ethtool_cmd_speed_set(ecmd, SPEED_100);
else
- ecmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(ecmd, SPEED_10);
if ((status & E1000_STATUS_FD) ||
hw->phy.media_type != e1000_media_type_copper)
@@ -190,7 +190,7 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
else
ecmd->duplex = DUPLEX_HALF;
} else {
- ecmd->speed = -1;
+ ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1;
}
@@ -223,7 +223,8 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
if (adapter->fc_autoneg)
hw->fc.requested_mode = e1000_fc_default;
} else {
- if (igb_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
+ u32 speed = ethtool_cmd_speed(ecmd);
+ if (igb_set_spd_dplx(adapter, speed, ecmd->duplex)) {
clear_bit(__IGB_RESETTING, &adapter->state);
return -EINVAL;
}
@@ -1963,27 +1964,28 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
/* bit defines for adapter->led_status */
#define IGB_LED_ON 0
-static int igb_phys_id(struct net_device *netdev, u32 data)
+static int igb_set_phys_id(struct net_device *netdev,
+ enum ethtool_phys_id_state state)
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- unsigned long timeout;
- timeout = data * 1000;
-
- /*
- * msleep_interruptable only accepts unsigned int so we are limited
- * in how long a duration we can wait
- */
- if (!timeout || timeout > UINT_MAX)
- timeout = UINT_MAX;
-
- igb_blink_led(hw);
- msleep_interruptible(timeout);
-
- igb_led_off(hw);
- clear_bit(IGB_LED_ON, &adapter->led_status);
- igb_cleanup_led(hw);
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ igb_blink_led(hw);
+ return 2;
+ case ETHTOOL_ID_ON:
+ igb_blink_led(hw);
+ break;
+ case ETHTOOL_ID_OFF:
+ igb_led_off(hw);
+ break;
+ case ETHTOOL_ID_INACTIVE:
+ igb_led_off(hw);
+ clear_bit(IGB_LED_ON, &adapter->led_status);
+ igb_cleanup_led(hw);
+ break;
+ }
return 0;
}
@@ -2215,7 +2217,7 @@ static const struct ethtool_ops igb_ethtool_ops = {
.set_tso = igb_set_tso,
.self_test = igb_diag_test,
.get_strings = igb_get_strings,
- .phys_id = igb_phys_id,
+ .set_phys_id = igb_set_phys_id,
.get_sset_count = igb_get_sset_count,
.get_ethtool_stats = igb_get_ethtool_stats,
.get_coalesce = igb_get_coalesce,
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 0dfd1b93829..ce7838e5582 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3532,6 +3532,25 @@ bool igb_has_link(struct igb_adapter *adapter)
return link_active;
}
+static bool igb_thermal_sensor_event(struct e1000_hw *hw, u32 event)
+{
+ bool ret = false;
+ u32 ctrl_ext, thstat;
+
+ /* check for thermal sensor event on i350, copper only */
+ if (hw->mac.type == e1000_i350) {
+ thstat = rd32(E1000_THSTAT);
+ ctrl_ext = rd32(E1000_CTRL_EXT);
+
+ if ((hw->phy.media_type == e1000_media_type_copper) &&
+ !(ctrl_ext & E1000_CTRL_EXT_LINK_MODE_SGMII)) {
+ ret = !!(thstat & event);
+ }
+ }
+
+ return ret;
+}
+
/**
* igb_watchdog - Timer Call-back
* @data: pointer to adapter cast into an unsigned long
@@ -3550,7 +3569,7 @@ static void igb_watchdog_task(struct work_struct *work)
watchdog_task);
struct e1000_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
- u32 link, ctrl_ext, thstat;
+ u32 link;
int i;
link = igb_has_link(adapter);
@@ -3574,25 +3593,14 @@ static void igb_watchdog_task(struct work_struct *work)
((ctrl & E1000_CTRL_RFCE) ? "RX" :
((ctrl & E1000_CTRL_TFCE) ? "TX" : "None")));
- /* check for thermal sensor event on i350,
- * copper only */
- if (hw->mac.type == e1000_i350) {
- thstat = rd32(E1000_THSTAT);
- ctrl_ext = rd32(E1000_CTRL_EXT);
- if ((hw->phy.media_type ==
- e1000_media_type_copper) && !(ctrl_ext &
- E1000_CTRL_EXT_LINK_MODE_SGMII)) {
- if (thstat &
- E1000_THSTAT_LINK_THROTTLE) {
- printk(KERN_INFO "igb: %s The "
- "network adapter link "
- "speed was downshifted "
- "because it "
- "overheated.\n",
- netdev->name);
- }
- }
+ /* check for thermal sensor event */
+ if (igb_thermal_sensor_event(hw, E1000_THSTAT_LINK_THROTTLE)) {
+ printk(KERN_INFO "igb: %s The network adapter "
+ "link speed was downshifted "
+ "because it overheated.\n",
+ netdev->name);
}
+
/* adjust timeout factor according to speed/duplex */
adapter->tx_timeout_factor = 1;
switch (adapter->link_speed) {
@@ -3618,22 +3626,15 @@ static void igb_watchdog_task(struct work_struct *work)
if (netif_carrier_ok(netdev)) {
adapter->link_speed = 0;
adapter->link_duplex = 0;
- /* check for thermal sensor event on i350
- * copper only*/
- if (hw->mac.type == e1000_i350) {
- thstat = rd32(E1000_THSTAT);
- ctrl_ext = rd32(E1000_CTRL_EXT);
- if ((hw->phy.media_type ==
- e1000_media_type_copper) && !(ctrl_ext &
- E1000_CTRL_EXT_LINK_MODE_SGMII)) {
- if (thstat & E1000_THSTAT_PWR_DOWN) {
- printk(KERN_ERR "igb: %s The "
- "network adapter was stopped "
- "because it overheated.\n",
+
+ /* check for thermal sensor event */
+ if (igb_thermal_sensor_event(hw, E1000_THSTAT_PWR_DOWN)) {
+ printk(KERN_ERR "igb: %s The network adapter "
+ "was stopped because it "
+ "overheated.\n",
netdev->name);
- }
- }
}
+
/* Links status message must follow this format */
printk(KERN_INFO "igb: %s NIC Link is Down\n",
netdev->name);
@@ -6348,21 +6349,25 @@ static void igb_restore_vlan(struct igb_adapter *adapter)
}
}
-int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx)
+int igb_set_spd_dplx(struct igb_adapter *adapter, u32 spd, u8 dplx)
{
struct pci_dev *pdev = adapter->pdev;
struct e1000_mac_info *mac = &adapter->hw.mac;
mac->autoneg = 0;
+ /* Make sure dplx is at most 1 bit and lsb of speed is not set
+ * for the switch() below to work */
+ if ((spd & 1) || (dplx & ~1))
+ goto err_inval;
+
/* Fiber NIC's only allow 1000 Gbps Full duplex */
if ((adapter->hw.phy.media_type == e1000_media_type_internal_serdes) &&
- spddplx != (SPEED_1000 + DUPLEX_FULL)) {
- dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n");
- return -EINVAL;
- }
+ spd != SPEED_1000 &&
+ dplx != DUPLEX_FULL)
+ goto err_inval;
- switch (spddplx) {
+ switch (spd + dplx) {
case SPEED_10 + DUPLEX_HALF:
mac->forced_speed_duplex = ADVERTISE_10_HALF;
break;
@@ -6381,10 +6386,13 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx)
break;
case SPEED_1000 + DUPLEX_HALF: /* not supported */
default:
- dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n");
- return -EINVAL;
+ goto err_inval;
}
return 0;
+
+err_inval:
+ dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n");
+ return -EINVAL;
}
static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake)
diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c
index 1d943aa7c7a..b0b14d63dfb 100644
--- a/drivers/net/igbvf/ethtool.c
+++ b/drivers/net/igbvf/ethtool.c
@@ -90,18 +90,18 @@ static int igbvf_get_settings(struct net_device *netdev,
status = er32(STATUS);
if (status & E1000_STATUS_LU) {
if (status & E1000_STATUS_SPEED_1000)
- ecmd->speed = 1000;
+ ethtool_cmd_speed_set(ecmd, SPEED_1000);
else if (status & E1000_STATUS_SPEED_100)
- ecmd->speed = 100;
+ ethtool_cmd_speed_set(ecmd, SPEED_100);
else
- ecmd->speed = 10;
+ ethtool_cmd_speed_set(ecmd, SPEED_10);
if (status & E1000_STATUS_FD)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
} else {
- ecmd->speed = -1;
+ ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1;
}
@@ -391,11 +391,6 @@ static int igbvf_set_wol(struct net_device *netdev,
return -EOPNOTSUPP;
}
-static int igbvf_phys_id(struct net_device *netdev, u32 data)
-{
- return 0;
-}
-
static int igbvf_get_coalesce(struct net_device *netdev,
struct ethtool_coalesce *ec)
{
@@ -527,7 +522,6 @@ static const struct ethtool_ops igbvf_ethtool_ops = {
.self_test = igbvf_diag_test,
.get_sset_count = igbvf_get_sset_count,
.get_strings = igbvf_get_strings,
- .phys_id = igbvf_phys_id,
.get_ethtool_stats = igbvf_get_ethtool_stats,
.get_coalesce = igbvf_get_coalesce,
.set_coalesce = igbvf_set_coalesce,
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index c8ee8d28767..96c95617195 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -90,8 +90,6 @@ struct ioc3_private {
u32 emcr, ehar_h, ehar_l;
spinlock_t ioc3_lock;
struct mii_if_info mii;
- unsigned long flags;
-#define IOC3_FLAG_RX_CHECKSUMS 1
struct pci_dev *pdev;
@@ -609,7 +607,7 @@ static inline void ioc3_rx(struct net_device *dev)
goto next;
}
- if (likely(ip->flags & IOC3_FLAG_RX_CHECKSUMS))
+ if (likely(dev->features & NETIF_F_RXCSUM))
ioc3_tcpudp_checksum(skb,
w0 & ERXBUF_IPCKSUM_MASK, len);
@@ -1328,6 +1326,7 @@ static int __devinit ioc3_probe(struct pci_dev *pdev,
dev->watchdog_timeo = 5 * HZ;
dev->netdev_ops = &ioc3_netdev_ops;
dev->ethtool_ops = &ioc3_ethtool_ops;
+ dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
dev->features = NETIF_F_IP_CSUM;
sw_physid1 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID1);
@@ -1618,37 +1617,12 @@ static u32 ioc3_get_link(struct net_device *dev)
return rc;
}
-static u32 ioc3_get_rx_csum(struct net_device *dev)
-{
- struct ioc3_private *ip = netdev_priv(dev);
-
- return ip->flags & IOC3_FLAG_RX_CHECKSUMS;
-}
-
-static int ioc3_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct ioc3_private *ip = netdev_priv(dev);
-
- spin_lock_bh(&ip->ioc3_lock);
- if (data)
- ip->flags |= IOC3_FLAG_RX_CHECKSUMS;
- else
- ip->flags &= ~IOC3_FLAG_RX_CHECKSUMS;
- spin_unlock_bh(&ip->ioc3_lock);
-
- return 0;
-}
-
static const struct ethtool_ops ioc3_ethtool_ops = {
.get_drvinfo = ioc3_get_drvinfo,
.get_settings = ioc3_get_settings,
.set_settings = ioc3_set_settings,
.nway_reset = ioc3_nway_reset,
.get_link = ioc3_get_link,
- .get_rx_csum = ioc3_get_rx_csum,
- .set_rx_csum = ioc3_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum
};
static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 8800e1fe412..69b5707db36 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -222,19 +222,19 @@ static void smsc_ircc_set_transceiver_for_speed(struct smsc_ircc_cb *self, u32 s
static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self);
/* Probing */
-static int __init smsc_ircc_look_for_chips(void);
-static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type);
-static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned short cfg_base, char *type);
-static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type);
-static int __init smsc_superio_fdc(unsigned short cfg_base);
-static int __init smsc_superio_lpc(unsigned short cfg_base);
+static int smsc_ircc_look_for_chips(void);
+static const struct smsc_chip * smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type);
+static int smsc_superio_flat(const struct smsc_chip *chips, unsigned short cfg_base, char *type);
+static int smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type);
+static int smsc_superio_fdc(unsigned short cfg_base);
+static int smsc_superio_lpc(unsigned short cfg_base);
#ifdef CONFIG_PCI
-static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf);
-static int __init preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf);
-static void __init preconfigure_ali_port(struct pci_dev *dev,
+static int preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf);
+static int preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf);
+static void preconfigure_ali_port(struct pci_dev *dev,
unsigned short port);
-static int __init preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf);
-static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
+static int preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf);
+static int smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
unsigned short ircc_fir,
unsigned short ircc_sir,
unsigned char ircc_dma,
@@ -366,7 +366,7 @@ static inline void register_bank(int iobase, int bank)
}
/* PNP hotplug support */
-static const struct pnp_device_id smsc_ircc_pnp_table[] = {
+static const struct pnp_device_id smsc_ircc_pnp_table[] __devinitconst = {
{ .id = "SMCf010", .driver_data = 0 },
/* and presumably others */
{ }
@@ -515,7 +515,7 @@ static const struct net_device_ops smsc_ircc_netdev_ops = {
* Try to open driver instance
*
*/
-static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq)
+static int __devinit smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq)
{
struct smsc_ircc_cb *self;
struct net_device *dev;
@@ -2273,7 +2273,7 @@ static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned sho
}
-static int __init smsc_access(unsigned short cfg_base, unsigned char reg)
+static int __devinit smsc_access(unsigned short cfg_base, unsigned char reg)
{
IRDA_DEBUG(1, "%s\n", __func__);
@@ -2281,7 +2281,7 @@ static int __init smsc_access(unsigned short cfg_base, unsigned char reg)
return inb(cfg_base) != reg ? -1 : 0;
}
-static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type)
+static const struct smsc_chip * __devinit smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type)
{
u8 devid, xdevid, rev;
@@ -2406,7 +2406,7 @@ static int __init smsc_superio_lpc(unsigned short cfg_base)
#ifdef CONFIG_PCI
#define PCIID_VENDOR_INTEL 0x8086
#define PCIID_VENDOR_ALI 0x10b9
-static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __initdata = {
+static const struct smsc_ircc_subsystem_configuration subsystem_configurations[] __devinitconst = {
/*
* Subsystems needing entries:
* 0x10b9:0x1533 0x103c:0x0850 HP nx9010 family
@@ -2532,7 +2532,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini
* (FIR port, SIR port, FIR DMA, FIR IRQ)
* through the chip configuration port.
*/
-static int __init preconfigure_smsc_chip(struct
+static int __devinit preconfigure_smsc_chip(struct
smsc_ircc_subsystem_configuration
*conf)
{
@@ -2633,7 +2633,7 @@ static int __init preconfigure_smsc_chip(struct
* or Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge.
* They all work the same way!
*/
-static int __init preconfigure_through_82801(struct pci_dev *dev,
+static int __devinit preconfigure_through_82801(struct pci_dev *dev,
struct
smsc_ircc_subsystem_configuration
*conf)
@@ -2786,7 +2786,7 @@ static int __init preconfigure_through_82801(struct pci_dev *dev,
* This is based on reverse-engineering since ALi does not
* provide any data sheet for the 1533 chip.
*/
-static void __init preconfigure_ali_port(struct pci_dev *dev,
+static void __devinit preconfigure_ali_port(struct pci_dev *dev,
unsigned short port)
{
unsigned char reg;
@@ -2824,7 +2824,7 @@ static void __init preconfigure_ali_port(struct pci_dev *dev,
IRDA_MESSAGE("Activated ALi 1533 ISA bridge port 0x%04x.\n", port);
}
-static int __init preconfigure_through_ali(struct pci_dev *dev,
+static int __devinit preconfigure_through_ali(struct pci_dev *dev,
struct
smsc_ircc_subsystem_configuration
*conf)
@@ -2837,7 +2837,7 @@ static int __init preconfigure_through_ali(struct pci_dev *dev,
return preconfigure_smsc_chip(conf);
}
-static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
+static int __devinit smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
unsigned short ircc_fir,
unsigned short ircc_sir,
unsigned char ircc_dma,
@@ -2849,7 +2849,7 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
int ret = 0;
for_each_pci_dev(dev) {
- struct smsc_ircc_subsystem_configuration *conf;
+ const struct smsc_ircc_subsystem_configuration *conf;
/*
* Cache the subsystem vendor/device:
diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
index 8f3df044e81..49e8408f05f 100644
--- a/drivers/net/ixgb/ixgb.h
+++ b/drivers/net/ixgb/ixgb.h
@@ -157,9 +157,6 @@ struct ixgb_adapter {
u16 link_duplex;
struct work_struct tx_timeout_task;
- struct timer_list blink_timer;
- unsigned long led_status;
-
/* TX */
struct ixgb_desc_ring tx_ring ____cacheline_aligned_in_smp;
unsigned int restart_queue;
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index cc53aa1541b..6da890b9534 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -104,10 +104,10 @@ ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
ecmd->transceiver = XCVR_EXTERNAL;
if (netif_carrier_ok(adapter->netdev)) {
- ecmd->speed = SPEED_10000;
+ ethtool_cmd_speed_set(ecmd, SPEED_10000);
ecmd->duplex = DUPLEX_FULL;
} else {
- ecmd->speed = -1;
+ ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1;
}
@@ -129,9 +129,10 @@ static int
ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
+ u32 speed = ethtool_cmd_speed(ecmd);
if (ecmd->autoneg == AUTONEG_ENABLE ||
- ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
+ (speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
return -EINVAL;
if (netif_running(adapter->netdev)) {
@@ -610,45 +611,23 @@ err_setup_rx:
return err;
}
-/* toggle LED 4 times per second = 2 "blinks" per second */
-#define IXGB_ID_INTERVAL (HZ/4)
-
-/* bit defines for adapter->led_status */
-#define IXGB_LED_ON 0
-
-static void
-ixgb_led_blink_callback(unsigned long data)
-{
- struct ixgb_adapter *adapter = (struct ixgb_adapter *)data;
-
- if (test_and_change_bit(IXGB_LED_ON, &adapter->led_status))
- ixgb_led_off(&adapter->hw);
- else
- ixgb_led_on(&adapter->hw);
-
- mod_timer(&adapter->blink_timer, jiffies + IXGB_ID_INTERVAL);
-}
-
static int
-ixgb_phys_id(struct net_device *netdev, u32 data)
+ixgb_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
- if (!data)
- data = INT_MAX;
-
- if (!adapter->blink_timer.function) {
- init_timer(&adapter->blink_timer);
- adapter->blink_timer.function = ixgb_led_blink_callback;
- adapter->blink_timer.data = (unsigned long)adapter;
- }
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ return 2;
- mod_timer(&adapter->blink_timer, jiffies);
+ case ETHTOOL_ID_ON:
+ ixgb_led_on(&adapter->hw);
+ break;
- msleep_interruptible(data * 1000);
- del_timer_sync(&adapter->blink_timer);
- ixgb_led_off(&adapter->hw);
- clear_bit(IXGB_LED_ON, &adapter->led_status);
+ case ETHTOOL_ID_OFF:
+ case ETHTOOL_ID_INACTIVE:
+ ixgb_led_off(&adapter->hw);
+ }
return 0;
}
@@ -766,7 +745,7 @@ static const struct ethtool_ops ixgb_ethtool_ops = {
.set_msglevel = ixgb_set_msglevel,
.set_tso = ixgb_set_tso,
.get_strings = ixgb_get_strings,
- .phys_id = ixgb_phys_id,
+ .set_phys_id = ixgb_set_phys_id,
.get_sset_count = ixgb_get_sset_count,
.get_ethtool_stats = ixgb_get_ethtool_stats,
.get_flags = ethtool_op_get_flags,
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 8d468028bb5..e467b20ed1f 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -106,6 +106,7 @@
#define IXGBE_MAX_VF_FUNCTIONS 64
#define IXGBE_MAX_VFTA_ENTRIES 128
#define MAX_EMULATION_MAC_ADDRS 16
+#define IXGBE_MAX_PF_MACVLANS 15
#define VMDQ_P(p) ((p) + adapter->num_vfs)
struct vf_data_storage {
@@ -121,6 +122,15 @@ struct vf_data_storage {
u16 tx_rate;
};
+struct vf_macvlans {
+ struct list_head l;
+ int vf;
+ int rar_entry;
+ bool free;
+ bool is_macvlan;
+ u8 vf_macvlan[ETH_ALEN];
+};
+
/* wrapper around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer */
struct ixgbe_tx_buffer {
@@ -331,10 +341,52 @@ struct ixgbe_q_vector {
/* board specific private data structure */
struct ixgbe_adapter {
- struct timer_list watchdog_timer;
+ unsigned long state;
+
+ /* Some features need tri-state capability,
+ * thus the additional *_CAPABLE flags.
+ */
+ u32 flags;
+#define IXGBE_FLAG_RX_CSUM_ENABLED (u32)(1)
+#define IXGBE_FLAG_MSI_CAPABLE (u32)(1 << 1)
+#define IXGBE_FLAG_MSI_ENABLED (u32)(1 << 2)
+#define IXGBE_FLAG_MSIX_CAPABLE (u32)(1 << 3)
+#define IXGBE_FLAG_MSIX_ENABLED (u32)(1 << 4)
+#define IXGBE_FLAG_RX_1BUF_CAPABLE (u32)(1 << 6)
+#define IXGBE_FLAG_RX_PS_CAPABLE (u32)(1 << 7)
+#define IXGBE_FLAG_RX_PS_ENABLED (u32)(1 << 8)
+#define IXGBE_FLAG_IN_NETPOLL (u32)(1 << 9)
+#define IXGBE_FLAG_DCA_ENABLED (u32)(1 << 10)
+#define IXGBE_FLAG_DCA_CAPABLE (u32)(1 << 11)
+#define IXGBE_FLAG_IMIR_ENABLED (u32)(1 << 12)
+#define IXGBE_FLAG_MQ_CAPABLE (u32)(1 << 13)
+#define IXGBE_FLAG_DCB_ENABLED (u32)(1 << 14)
+#define IXGBE_FLAG_RSS_ENABLED (u32)(1 << 16)
+#define IXGBE_FLAG_RSS_CAPABLE (u32)(1 << 17)
+#define IXGBE_FLAG_VMDQ_CAPABLE (u32)(1 << 18)
+#define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 19)
+#define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 20)
+#define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 22)
+#define IXGBE_FLAG_NEED_LINK_CONFIG (u32)(1 << 23)
+#define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 24)
+#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 25)
+#define IXGBE_FLAG_FCOE_CAPABLE (u32)(1 << 26)
+#define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 27)
+#define IXGBE_FLAG_SRIOV_CAPABLE (u32)(1 << 28)
+#define IXGBE_FLAG_SRIOV_ENABLED (u32)(1 << 29)
+
+ u32 flags2;
+#define IXGBE_FLAG2_RSC_CAPABLE (u32)(1)
+#define IXGBE_FLAG2_RSC_ENABLED (u32)(1 << 1)
+#define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE (u32)(1 << 2)
+#define IXGBE_FLAG2_TEMP_SENSOR_EVENT (u32)(1 << 3)
+#define IXGBE_FLAG2_SEARCH_FOR_SFP (u32)(1 << 4)
+#define IXGBE_FLAG2_SFP_NEEDS_RESET (u32)(1 << 5)
+#define IXGBE_FLAG2_RESET_REQUESTED (u32)(1 << 6)
+#define IXGBE_FLAG2_FDIR_REQUIRES_REINIT (u32)(1 << 7)
+
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
u16 bd_number;
- struct work_struct reset_task;
struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
/* DCB parameters */
@@ -377,43 +429,6 @@ struct ixgbe_adapter {
u32 alloc_rx_page_failed;
u32 alloc_rx_buff_failed;
- /* Some features need tri-state capability,
- * thus the additional *_CAPABLE flags.
- */
- u32 flags;
-#define IXGBE_FLAG_RX_CSUM_ENABLED (u32)(1)
-#define IXGBE_FLAG_MSI_CAPABLE (u32)(1 << 1)
-#define IXGBE_FLAG_MSI_ENABLED (u32)(1 << 2)
-#define IXGBE_FLAG_MSIX_CAPABLE (u32)(1 << 3)
-#define IXGBE_FLAG_MSIX_ENABLED (u32)(1 << 4)
-#define IXGBE_FLAG_RX_1BUF_CAPABLE (u32)(1 << 6)
-#define IXGBE_FLAG_RX_PS_CAPABLE (u32)(1 << 7)
-#define IXGBE_FLAG_RX_PS_ENABLED (u32)(1 << 8)
-#define IXGBE_FLAG_IN_NETPOLL (u32)(1 << 9)
-#define IXGBE_FLAG_DCA_ENABLED (u32)(1 << 10)
-#define IXGBE_FLAG_DCA_CAPABLE (u32)(1 << 11)
-#define IXGBE_FLAG_IMIR_ENABLED (u32)(1 << 12)
-#define IXGBE_FLAG_MQ_CAPABLE (u32)(1 << 13)
-#define IXGBE_FLAG_DCB_ENABLED (u32)(1 << 14)
-#define IXGBE_FLAG_RSS_ENABLED (u32)(1 << 16)
-#define IXGBE_FLAG_RSS_CAPABLE (u32)(1 << 17)
-#define IXGBE_FLAG_VMDQ_CAPABLE (u32)(1 << 18)
-#define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 19)
-#define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 20)
-#define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 22)
-#define IXGBE_FLAG_IN_SFP_LINK_TASK (u32)(1 << 23)
-#define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 24)
-#define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 25)
-#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 26)
-#define IXGBE_FLAG_FCOE_CAPABLE (u32)(1 << 27)
-#define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 28)
-#define IXGBE_FLAG_SRIOV_CAPABLE (u32)(1 << 29)
-#define IXGBE_FLAG_SRIOV_ENABLED (u32)(1 << 30)
-
- u32 flags2;
-#define IXGBE_FLAG2_RSC_CAPABLE (u32)(1)
-#define IXGBE_FLAG2_RSC_ENABLED (u32)(1 << 1)
-#define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE (u32)(1 << 2)
/* default to trying for four seconds */
#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
@@ -434,7 +449,6 @@ struct ixgbe_adapter {
u32 rx_eitr_param;
u32 tx_eitr_param;
- unsigned long state;
u64 tx_busy;
unsigned int tx_ring_count;
unsigned int rx_ring_count;
@@ -443,15 +457,12 @@ struct ixgbe_adapter {
bool link_up;
unsigned long link_check_timeout;
- struct work_struct watchdog_task;
- struct work_struct sfp_task;
- struct timer_list sfp_timer;
- struct work_struct multispeed_fiber_task;
- struct work_struct sfp_config_module_task;
+ struct work_struct service_task;
+ struct timer_list service_timer;
u32 fdir_pballoc;
u32 atr_sample_rate;
+ unsigned long fdir_overflow; /* number of times ATR was backed off */
spinlock_t fdir_perfect_lock;
- struct work_struct fdir_reinit_task;
#ifdef IXGBE_FCOE
struct ixgbe_fcoe fcoe;
#endif /* IXGBE_FCOE */
@@ -461,7 +472,7 @@ struct ixgbe_adapter {
u16 eeprom_version;
int node;
- struct work_struct check_overtemp_task;
+ u32 led_reg;
u32 interrupt_event;
char lsc_int_name[IFNAMSIZ + 9];
@@ -470,13 +481,17 @@ struct ixgbe_adapter {
unsigned int num_vfs;
struct vf_data_storage *vfinfo;
int vf_rate_link_speed;
+ struct vf_macvlans vf_mvs;
+ struct vf_macvlans *mv_list;
+ bool antispoofing_enabled;
};
enum ixbge_state_t {
__IXGBE_TESTING,
__IXGBE_RESETTING,
__IXGBE_DOWN,
- __IXGBE_SFP_MODULE_NOT_FOUND
+ __IXGBE_SERVICE_SCHED,
+ __IXGBE_IN_SFP_INIT,
};
struct ixgbe_rsc_cb {
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 845c679c8b8..8179e5060a1 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -37,6 +37,7 @@
#define IXGBE_82598_RAR_ENTRIES 16
#define IXGBE_82598_MC_TBL_SIZE 128
#define IXGBE_82598_VFT_TBL_SIZE 128
+#define IXGBE_82598_RX_PB_SIZE 512
static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
@@ -197,14 +198,35 @@ out:
* @hw: pointer to hardware structure
*
* Starts the hardware using the generic start_hw function.
- * Then set pcie completion timeout
+ * Disables relaxed ordering Then set pcie completion timeout
+ *
**/
static s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw)
{
+ u32 regval;
+ u32 i;
s32 ret_val = 0;
ret_val = ixgbe_start_hw_generic(hw);
+ /* Disable relaxed ordering */
+ for (i = 0; ((i < hw->mac.max_tx_queues) &&
+ (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
+ regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
+ regval &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval);
+ }
+
+ for (i = 0; ((i < hw->mac.max_rx_queues) &&
+ (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
+ regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
+ regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
+ IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
+ }
+
+ hw->mac.rx_pb_size = IXGBE_82598_RX_PB_SIZE;
+
/* set the completion timeout for interface */
if (ret_val == 0)
ixgbe_set_pcie_completion_timeout(hw);
@@ -1064,7 +1086,7 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK;
if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS)
break;
- msleep(10);
+ usleep_range(10000, 20000);
}
if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) {
@@ -1188,6 +1210,38 @@ out:
return physical_layer;
}
+/**
+ * ixgbe_set_lan_id_multi_port_pcie_82598 - Set LAN id for PCIe multiple
+ * port devices.
+ * @hw: pointer to the HW structure
+ *
+ * Calls common function and corrects issue with some single port devices
+ * that enable LAN1 but not LAN0.
+ **/
+static void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw)
+{
+ struct ixgbe_bus_info *bus = &hw->bus;
+ u16 pci_gen = 0;
+ u16 pci_ctrl2 = 0;
+
+ ixgbe_set_lan_id_multi_port_pcie(hw);
+
+ /* check if LAN0 is disabled */
+ hw->eeprom.ops.read(hw, IXGBE_PCIE_GENERAL_PTR, &pci_gen);
+ if ((pci_gen != 0) && (pci_gen != 0xFFFF)) {
+
+ hw->eeprom.ops.read(hw, pci_gen + IXGBE_PCIE_CTRL2, &pci_ctrl2);
+
+ /* if LAN0 is completely disabled force function to 0 */
+ if ((pci_ctrl2 & IXGBE_PCIE_CTRL2_LAN_DISABLE) &&
+ !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DISABLE_SELECT) &&
+ !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DUMMY_ENABLE)) {
+
+ bus->func = 0;
+ }
+ }
+}
+
static struct ixgbe_mac_operations mac_ops_82598 = {
.init_hw = &ixgbe_init_hw_generic,
.reset_hw = &ixgbe_reset_hw_82598,
@@ -1199,7 +1253,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
.get_mac_addr = &ixgbe_get_mac_addr_generic,
.stop_adapter = &ixgbe_stop_adapter_generic,
.get_bus_info = &ixgbe_get_bus_info_generic,
- .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie,
+ .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie_82598,
.read_analog_reg8 = &ixgbe_read_analog_reg8_82598,
.write_analog_reg8 = &ixgbe_write_analog_reg8_82598,
.setup_link = &ixgbe_setup_mac_link_82598,
@@ -1227,6 +1281,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
.init_params = &ixgbe_init_eeprom_params_generic,
.read = &ixgbe_read_eerd_generic,
+ .read_buffer = &ixgbe_read_eerd_buffer_generic,
.calc_checksum = &ixgbe_calc_eeprom_checksum_generic,
.validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
.update_checksum = &ixgbe_update_eeprom_checksum_generic,
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 00aeba385a2..8ee661245af 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -38,6 +38,7 @@
#define IXGBE_82599_RAR_ENTRIES 128
#define IXGBE_82599_MC_TBL_SIZE 128
#define IXGBE_82599_VFT_TBL_SIZE 128
+#define IXGBE_82599_RX_PB_SIZE 512
static void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
@@ -61,6 +62,7 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
bool autoneg,
bool autoneg_wait_to_complete);
static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
+static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw);
static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
{
@@ -86,7 +88,8 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
if ((mac->ops.get_media_type(hw) ==
ixgbe_media_type_backplane) &&
(hw->phy.smart_speed == ixgbe_smart_speed_auto ||
- hw->phy.smart_speed == ixgbe_smart_speed_on))
+ hw->phy.smart_speed == ixgbe_smart_speed_on) &&
+ !ixgbe_verify_lesm_fw_enabled_82599(hw))
mac->ops.setup_link = &ixgbe_setup_mac_link_smartspeed;
else
mac->ops.setup_link = &ixgbe_setup_mac_link_82599;
@@ -107,7 +110,6 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
&data_offset);
-
if (ret_val != 0)
goto setup_sfp_out;
@@ -127,9 +129,13 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
}
/* Release the semaphore */
- ixgbe_release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
- /* Delay obtaining semaphore again to allow FW access */
- msleep(hw->eeprom.semaphore_delay);
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+ /*
+ * Delay obtaining semaphore again to allow FW access,
+ * semaphore_delay is in ms usleep_range needs us.
+ */
+ usleep_range(hw->eeprom.semaphore_delay * 1000,
+ hw->eeprom.semaphore_delay * 2000);
/* Now restart DSP by setting Restart_AN and clearing LMS */
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw,
@@ -138,7 +144,7 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
/* Wait for AN to leave state 0 */
for (i = 0; i < 10; i++) {
- msleep(4);
+ usleep_range(4000, 8000);
reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1);
if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)
break;
@@ -353,6 +359,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_82599_SFP:
case IXGBE_DEV_ID_82599_SFP_FCOE:
case IXGBE_DEV_ID_82599_SFP_EM:
+ case IXGBE_DEV_ID_82599_SFP_SF2:
media_type = ixgbe_media_type_fiber;
break;
case IXGBE_DEV_ID_82599_CX4:
@@ -361,6 +368,9 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_82599_T3_LOM:
media_type = ixgbe_media_type_copper;
break;
+ case IXGBE_DEV_ID_82599_LS:
+ media_type = ixgbe_media_type_fiber_lco;
+ break;
default:
media_type = ixgbe_media_type_unknown;
break;
@@ -486,7 +496,7 @@ static void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
*
* Set the link speed in the AUTOC register and restarts link.
**/
-s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
+static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
bool autoneg,
bool autoneg_wait_to_complete)
@@ -1176,7 +1186,7 @@ s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc)
if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
IXGBE_FDIRCTRL_INIT_DONE)
break;
- msleep(1);
+ usleep_range(1000, 2000);
}
if (i >= IXGBE_FDIR_INIT_DONE_POLL)
hw_dbg(hw, "Flow Director Signature poll time exceeded!\n");
@@ -1271,7 +1281,7 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc)
if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
IXGBE_FDIRCTRL_INIT_DONE)
break;
- msleep(1);
+ usleep_range(1000, 2000);
}
if (i >= IXGBE_FDIR_INIT_DONE_POLL)
hw_dbg(hw, "Flow Director Perfect poll time exceeded!\n");
@@ -1740,30 +1750,29 @@ static s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val)
* ixgbe_start_hw_82599 - Prepare hardware for Tx/Rx
* @hw: pointer to hardware structure
*
- * Starts the hardware using the generic start_hw function.
- * Then performs device-specific:
- * Clears the rate limiter registers.
+ * Starts the hardware using the generic start_hw function
+ * and the generation start_hw function.
+ * Then performs revision-specific operations, if any.
**/
static s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
{
- u32 q_num;
- s32 ret_val;
+ s32 ret_val = 0;
ret_val = ixgbe_start_hw_generic(hw);
+ if (ret_val != 0)
+ goto out;
- /* Clear the rate limiters */
- for (q_num = 0; q_num < hw->mac.max_tx_queues; q_num++) {
- IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, q_num);
- IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
- }
- IXGBE_WRITE_FLUSH(hw);
+ ret_val = ixgbe_start_hw_gen2(hw);
+ if (ret_val != 0)
+ goto out;
/* We need to run link autotry after the driver loads */
hw->mac.autotry_restart = true;
+ hw->mac.rx_pb_size = IXGBE_82599_RX_PB_SIZE;
if (ret_val == 0)
ret_val = ixgbe_verify_fw_version_82599(hw);
-
+out:
return ret_val;
}
@@ -1775,7 +1784,7 @@ static s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
* If PHY already detected, maintains current PHY type in hw struct,
* otherwise executes the PHY detection routine.
**/
-s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
+static s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
{
s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
@@ -1968,21 +1977,6 @@ static s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
}
/**
- * ixgbe_get_device_caps_82599 - Get additional device capabilities
- * @hw: pointer to hardware structure
- * @device_caps: the EEPROM word with the extra device capabilities
- *
- * This function will read the EEPROM location for the device capabilities,
- * and return the word through device_caps.
- **/
-static s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps)
-{
- hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps);
-
- return 0;
-}
-
-/**
* ixgbe_verify_fw_version_82599 - verify fw version for 82599
* @hw: pointer to hardware structure
*
@@ -2030,6 +2024,110 @@ fw_version_out:
return status;
}
+/**
+ * ixgbe_verify_lesm_fw_enabled_82599 - Checks LESM FW module state.
+ * @hw: pointer to hardware structure
+ *
+ * Returns true if the LESM FW module is present and enabled. Otherwise
+ * returns false. Smart Speed must be disabled if LESM FW module is enabled.
+ **/
+static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw)
+{
+ bool lesm_enabled = false;
+ u16 fw_offset, fw_lesm_param_offset, fw_lesm_state;
+ s32 status;
+
+ /* get the offset to the Firmware Module block */
+ status = hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset);
+
+ if ((status != 0) ||
+ (fw_offset == 0) || (fw_offset == 0xFFFF))
+ goto out;
+
+ /* get the offset to the LESM Parameters block */
+ status = hw->eeprom.ops.read(hw, (fw_offset +
+ IXGBE_FW_LESM_PARAMETERS_PTR),
+ &fw_lesm_param_offset);
+
+ if ((status != 0) ||
+ (fw_lesm_param_offset == 0) || (fw_lesm_param_offset == 0xFFFF))
+ goto out;
+
+ /* get the lesm state word */
+ status = hw->eeprom.ops.read(hw, (fw_lesm_param_offset +
+ IXGBE_FW_LESM_STATE_1),
+ &fw_lesm_state);
+
+ if ((status == 0) &&
+ (fw_lesm_state & IXGBE_FW_LESM_STATE_ENABLED))
+ lesm_enabled = true;
+
+out:
+ return lesm_enabled;
+}
+
+/**
+ * ixgbe_read_eeprom_buffer_82599 - Read EEPROM word(s) using
+ * fastest available method
+ *
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in EEPROM to read
+ * @words: number of words
+ * @data: word(s) read from the EEPROM
+ *
+ * Retrieves 16 bit word(s) read from EEPROM
+ **/
+static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data)
+{
+ struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+ s32 ret_val = IXGBE_ERR_CONFIG;
+
+ /*
+ * If EEPROM is detected and can be addressed using 14 bits,
+ * use EERD otherwise use bit bang
+ */
+ if ((eeprom->type == ixgbe_eeprom_spi) &&
+ (offset + (words - 1) <= IXGBE_EERD_MAX_ADDR))
+ ret_val = ixgbe_read_eerd_buffer_generic(hw, offset, words,
+ data);
+ else
+ ret_val = ixgbe_read_eeprom_buffer_bit_bang_generic(hw, offset,
+ words,
+ data);
+
+ return ret_val;
+}
+
+/**
+ * ixgbe_read_eeprom_82599 - Read EEPROM word using
+ * fastest available method
+ *
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to read
+ * @data: word read from the EEPROM
+ *
+ * Reads a 16 bit word from the EEPROM
+ **/
+static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
+ u16 offset, u16 *data)
+{
+ struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+ s32 ret_val = IXGBE_ERR_CONFIG;
+
+ /*
+ * If EEPROM is detected and can be addressed using 14 bits,
+ * use EERD otherwise use bit bang
+ */
+ if ((eeprom->type == ixgbe_eeprom_spi) &&
+ (offset <= IXGBE_EERD_MAX_ADDR))
+ ret_val = ixgbe_read_eerd_generic(hw, offset, data);
+ else
+ ret_val = ixgbe_read_eeprom_bit_bang_generic(hw, offset, data);
+
+ return ret_val;
+}
+
static struct ixgbe_mac_operations mac_ops_82599 = {
.init_hw = &ixgbe_init_hw_generic,
.reset_hw = &ixgbe_reset_hw_82599,
@@ -2040,7 +2138,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
.enable_rx_dma = &ixgbe_enable_rx_dma_82599,
.get_mac_addr = &ixgbe_get_mac_addr_generic,
.get_san_mac_addr = &ixgbe_get_san_mac_addr_generic,
- .get_device_caps = &ixgbe_get_device_caps_82599,
+ .get_device_caps = &ixgbe_get_device_caps_generic,
.get_wwn_prefix = &ixgbe_get_wwn_prefix_generic,
.stop_adapter = &ixgbe_stop_adapter_generic,
.get_bus_info = &ixgbe_get_bus_info_generic,
@@ -2076,8 +2174,10 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
.init_params = &ixgbe_init_eeprom_params_generic,
- .read = &ixgbe_read_eerd_generic,
+ .read = &ixgbe_read_eeprom_82599,
+ .read_buffer = &ixgbe_read_eeprom_buffer_82599,
.write = &ixgbe_write_eeprom_generic,
+ .write_buffer = &ixgbe_write_eeprom_buffer_bit_bang_generic,
.calc_checksum = &ixgbe_calc_eeprom_checksum_generic,
.validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
.update_checksum = &ixgbe_update_eeprom_checksum_generic,
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index bcd952916eb..b894b42a741 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -54,6 +54,13 @@ static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw);
static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);
static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
+static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg);
+static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data);
+static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data);
+static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
+ u16 offset);
/**
* ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
@@ -96,6 +103,45 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_start_hw_gen2 - Init sequence for common device family
+ * @hw: pointer to hw structure
+ *
+ * Performs the init sequence common to the second generation
+ * of 10 GbE devices.
+ * Devices in the second generation:
+ * 82599
+ * X540
+ **/
+s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw)
+{
+ u32 i;
+ u32 regval;
+
+ /* Clear the rate limiters */
+ for (i = 0; i < hw->mac.max_tx_queues; i++) {
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
+ IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
+ }
+ IXGBE_WRITE_FLUSH(hw);
+
+ /* Disable relaxed ordering */
+ for (i = 0; i < hw->mac.max_tx_queues; i++) {
+ regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
+ regval &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval);
+ }
+
+ for (i = 0; i < hw->mac.max_rx_queues; i++) {
+ regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
+ regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
+ IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
+ }
+
+ return 0;
+}
+
+/**
* ixgbe_init_hw_generic - Generic hardware initialization
* @hw: pointer to hardware structure
*
@@ -464,7 +510,7 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
reg_val &= ~(IXGBE_RXCTRL_RXEN);
IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_val);
IXGBE_WRITE_FLUSH(hw);
- msleep(2);
+ usleep_range(2000, 4000);
/* Clear interrupt mask to stop from interrupts being generated */
IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
@@ -545,6 +591,8 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
/* Set default semaphore delay to 10ms which is a well
* tested value */
eeprom->semaphore_delay = 10;
+ /* Clear EEPROM page size, it will be initialized as needed */
+ eeprom->word_page_size = 0;
/*
* Check for EEPROM present first.
@@ -577,26 +625,78 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
}
/**
- * ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
+ * ixgbe_write_eeprom_buffer_bit_bang_generic - Write EEPROM using bit-bang
* @hw: pointer to hardware structure
- * @offset: offset within the EEPROM to be written to
- * @data: 16 bit word to be written to the EEPROM
+ * @offset: offset within the EEPROM to write
+ * @words: number of words
+ * @data: 16 bit word(s) to write to EEPROM
*
- * If ixgbe_eeprom_update_checksum is not called after this function, the
- * EEPROM will most likely contain an invalid checksum.
+ * Reads 16 bit word(s) from EEPROM through bit-bang method
**/
-s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
+s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data)
{
- s32 status;
- u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
+ s32 status = 0;
+ u16 i, count;
hw->eeprom.ops.init_params(hw);
- if (offset >= hw->eeprom.word_size) {
+ if (words == 0) {
+ status = IXGBE_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+
+ if (offset + words > hw->eeprom.word_size) {
status = IXGBE_ERR_EEPROM;
goto out;
}
+ /*
+ * The EEPROM page size cannot be queried from the chip. We do lazy
+ * initialization. It is worth to do that when we write large buffer.
+ */
+ if ((hw->eeprom.word_page_size == 0) &&
+ (words > IXGBE_EEPROM_PAGE_SIZE_MAX))
+ ixgbe_detect_eeprom_page_size_generic(hw, offset);
+
+ /*
+ * We cannot hold synchronization semaphores for too long
+ * to avoid other entity starvation. However it is more efficient
+ * to read in bursts than synchronizing access for each word.
+ */
+ for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
+ count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
+ IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
+ status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset + i,
+ count, &data[i]);
+
+ if (status != 0)
+ break;
+ }
+
+out:
+ return status;
+}
+
+/**
+ * ixgbe_write_eeprom_buffer_bit_bang - Writes 16 bit word(s) to EEPROM
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be written to
+ * @words: number of word(s)
+ * @data: 16 bit word(s) to be written to the EEPROM
+ *
+ * If ixgbe_eeprom_update_checksum is not called after this function, the
+ * EEPROM will most likely contain an invalid checksum.
+ **/
+static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data)
+{
+ s32 status;
+ u16 word;
+ u16 page_size;
+ u16 i;
+ u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
+
/* Prepare the EEPROM for writing */
status = ixgbe_acquire_eeprom(hw);
@@ -608,62 +708,147 @@ s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
}
if (status == 0) {
- ixgbe_standby_eeprom(hw);
+ for (i = 0; i < words; i++) {
+ ixgbe_standby_eeprom(hw);
- /* Send the WRITE ENABLE command (8 bit opcode ) */
- ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_WREN_OPCODE_SPI,
- IXGBE_EEPROM_OPCODE_BITS);
+ /* Send the WRITE ENABLE command (8 bit opcode ) */
+ ixgbe_shift_out_eeprom_bits(hw,
+ IXGBE_EEPROM_WREN_OPCODE_SPI,
+ IXGBE_EEPROM_OPCODE_BITS);
- ixgbe_standby_eeprom(hw);
+ ixgbe_standby_eeprom(hw);
- /*
- * Some SPI eeproms use the 8th address bit embedded in the
- * opcode
- */
- if ((hw->eeprom.address_bits == 8) && (offset >= 128))
- write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+ /*
+ * Some SPI eeproms use the 8th address bit embedded
+ * in the opcode
+ */
+ if ((hw->eeprom.address_bits == 8) &&
+ ((offset + i) >= 128))
+ write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+
+ /* Send the Write command (8-bit opcode + addr) */
+ ixgbe_shift_out_eeprom_bits(hw, write_opcode,
+ IXGBE_EEPROM_OPCODE_BITS);
+ ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
+ hw->eeprom.address_bits);
+
+ page_size = hw->eeprom.word_page_size;
+
+ /* Send the data in burst via SPI*/
+ do {
+ word = data[i];
+ word = (word >> 8) | (word << 8);
+ ixgbe_shift_out_eeprom_bits(hw, word, 16);
+
+ if (page_size == 0)
+ break;
+
+ /* do not wrap around page */
+ if (((offset + i) & (page_size - 1)) ==
+ (page_size - 1))
+ break;
+ } while (++i < words);
+
+ ixgbe_standby_eeprom(hw);
+ usleep_range(10000, 20000);
+ }
+ /* Done with writing - release the EEPROM */
+ ixgbe_release_eeprom(hw);
+ }
- /* Send the Write command (8-bit opcode + addr) */
- ixgbe_shift_out_eeprom_bits(hw, write_opcode,
- IXGBE_EEPROM_OPCODE_BITS);
- ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
- hw->eeprom.address_bits);
+ return status;
+}
- /* Send the data */
- data = (data >> 8) | (data << 8);
- ixgbe_shift_out_eeprom_bits(hw, data, 16);
- ixgbe_standby_eeprom(hw);
+/**
+ * ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be written to
+ * @data: 16 bit word to be written to the EEPROM
+ *
+ * If ixgbe_eeprom_update_checksum is not called after this function, the
+ * EEPROM will most likely contain an invalid checksum.
+ **/
+s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
+{
+ s32 status;
- /* Done with writing - release the EEPROM */
- ixgbe_release_eeprom(hw);
+ hw->eeprom.ops.init_params(hw);
+
+ if (offset >= hw->eeprom.word_size) {
+ status = IXGBE_ERR_EEPROM;
+ goto out;
}
+ status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1, &data);
+
out:
return status;
}
/**
- * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
+ * ixgbe_read_eeprom_buffer_bit_bang_generic - Read EEPROM using bit-bang
* @hw: pointer to hardware structure
* @offset: offset within the EEPROM to be read
- * @data: read 16 bit value from EEPROM
+ * @words: number of word(s)
+ * @data: read 16 bit words(s) from EEPROM
*
- * Reads 16 bit value from EEPROM through bit-bang method
+ * Reads 16 bit word(s) from EEPROM through bit-bang method
**/
-s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
- u16 *data)
+s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data)
{
- s32 status;
- u16 word_in;
- u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
+ s32 status = 0;
+ u16 i, count;
hw->eeprom.ops.init_params(hw);
- if (offset >= hw->eeprom.word_size) {
+ if (words == 0) {
+ status = IXGBE_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+
+ if (offset + words > hw->eeprom.word_size) {
status = IXGBE_ERR_EEPROM;
goto out;
}
+ /*
+ * We cannot hold synchronization semaphores for too long
+ * to avoid other entity starvation. However it is more efficient
+ * to read in bursts than synchronizing access for each word.
+ */
+ for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
+ count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
+ IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
+
+ status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset + i,
+ count, &data[i]);
+
+ if (status != 0)
+ break;
+ }
+
+out:
+ return status;
+}
+
+/**
+ * ixgbe_read_eeprom_buffer_bit_bang - Read EEPROM using bit-bang
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be read
+ * @words: number of word(s)
+ * @data: read 16 bit word(s) from EEPROM
+ *
+ * Reads 16 bit word(s) from EEPROM through bit-bang method
+ **/
+static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data)
+{
+ s32 status;
+ u16 word_in;
+ u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
+ u16 i;
+
/* Prepare the EEPROM for reading */
status = ixgbe_acquire_eeprom(hw);
@@ -675,29 +860,145 @@ s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
}
if (status == 0) {
- ixgbe_standby_eeprom(hw);
+ for (i = 0; i < words; i++) {
+ ixgbe_standby_eeprom(hw);
+ /*
+ * Some SPI eeproms use the 8th address bit embedded
+ * in the opcode
+ */
+ if ((hw->eeprom.address_bits == 8) &&
+ ((offset + i) >= 128))
+ read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+
+ /* Send the READ command (opcode + addr) */
+ ixgbe_shift_out_eeprom_bits(hw, read_opcode,
+ IXGBE_EEPROM_OPCODE_BITS);
+ ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
+ hw->eeprom.address_bits);
+
+ /* Read the data. */
+ word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
+ data[i] = (word_in >> 8) | (word_in << 8);
+ }
- /*
- * Some SPI eeproms use the 8th address bit embedded in the
- * opcode
- */
- if ((hw->eeprom.address_bits == 8) && (offset >= 128))
- read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+ /* End this read operation */
+ ixgbe_release_eeprom(hw);
+ }
- /* Send the READ command (opcode + addr) */
- ixgbe_shift_out_eeprom_bits(hw, read_opcode,
- IXGBE_EEPROM_OPCODE_BITS);
- ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
- hw->eeprom.address_bits);
+ return status;
+}
+
+/**
+ * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be read
+ * @data: read 16 bit value from EEPROM
+ *
+ * Reads 16 bit value from EEPROM through bit-bang method
+ **/
+s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 *data)
+{
+ s32 status;
- /* Read the data. */
- word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
- *data = (word_in >> 8) | (word_in << 8);
+ hw->eeprom.ops.init_params(hw);
- /* End this read operation */
- ixgbe_release_eeprom(hw);
+ if (offset >= hw->eeprom.word_size) {
+ status = IXGBE_ERR_EEPROM;
+ goto out;
+ }
+
+ status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
+
+out:
+ return status;
+}
+
+/**
+ * ixgbe_read_eerd_buffer_generic - Read EEPROM word(s) using EERD
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to read
+ * @words: number of word(s)
+ * @data: 16 bit word(s) from the EEPROM
+ *
+ * Reads a 16 bit word(s) from the EEPROM using the EERD register.
+ **/
+s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data)
+{
+ u32 eerd;
+ s32 status = 0;
+ u32 i;
+
+ hw->eeprom.ops.init_params(hw);
+
+ if (words == 0) {
+ status = IXGBE_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+
+ if (offset >= hw->eeprom.word_size) {
+ status = IXGBE_ERR_EEPROM;
+ goto out;
}
+ for (i = 0; i < words; i++) {
+ eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) +
+ IXGBE_EEPROM_RW_REG_START;
+
+ IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
+ status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ);
+
+ if (status == 0) {
+ data[i] = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
+ IXGBE_EEPROM_RW_REG_DATA);
+ } else {
+ hw_dbg(hw, "Eeprom read timed out\n");
+ goto out;
+ }
+ }
+out:
+ return status;
+}
+
+/**
+ * ixgbe_detect_eeprom_page_size_generic - Detect EEPROM page size
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be used as a scratch pad
+ *
+ * Discover EEPROM page size by writing marching data at given offset.
+ * This function is called only when we are writing a new large buffer
+ * at given offset so the data would be overwritten anyway.
+ **/
+static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
+ u16 offset)
+{
+ u16 data[IXGBE_EEPROM_PAGE_SIZE_MAX];
+ s32 status = 0;
+ u16 i;
+
+ for (i = 0; i < IXGBE_EEPROM_PAGE_SIZE_MAX; i++)
+ data[i] = i;
+
+ hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX;
+ status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset,
+ IXGBE_EEPROM_PAGE_SIZE_MAX, data);
+ hw->eeprom.word_page_size = 0;
+ if (status != 0)
+ goto out;
+
+ status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
+ if (status != 0)
+ goto out;
+
+ /*
+ * When writing in burst more than the actual page size
+ * EEPROM address wraps around current page.
+ */
+ hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX - data[0];
+
+ hw_dbg(hw, "Detected EEPROM page size = %d words.",
+ hw->eeprom.word_page_size);
out:
return status;
}
@@ -712,33 +1013,75 @@ out:
**/
s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
{
- u32 eerd;
- s32 status;
+ return ixgbe_read_eerd_buffer_generic(hw, offset, 1, data);
+}
+
+/**
+ * ixgbe_write_eewr_buffer_generic - Write EEPROM word(s) using EEWR
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to write
+ * @words: number of words
+ * @data: word(s) write to the EEPROM
+ *
+ * Write a 16 bit word(s) to the EEPROM using the EEWR register.
+ **/
+s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data)
+{
+ u32 eewr;
+ s32 status = 0;
+ u16 i;
hw->eeprom.ops.init_params(hw);
+ if (words == 0) {
+ status = IXGBE_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+
if (offset >= hw->eeprom.word_size) {
status = IXGBE_ERR_EEPROM;
goto out;
}
- eerd = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) +
- IXGBE_EEPROM_RW_REG_START;
+ for (i = 0; i < words; i++) {
+ eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
+ (data[i] << IXGBE_EEPROM_RW_REG_DATA) |
+ IXGBE_EEPROM_RW_REG_START;
- IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
- status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ);
+ status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
+ if (status != 0) {
+ hw_dbg(hw, "Eeprom write EEWR timed out\n");
+ goto out;
+ }
- if (status == 0)
- *data = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
- IXGBE_EEPROM_RW_REG_DATA);
- else
- hw_dbg(hw, "Eeprom read timed out\n");
+ IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
+
+ status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
+ if (status != 0) {
+ hw_dbg(hw, "Eeprom write EEWR timed out\n");
+ goto out;
+ }
+ }
out:
return status;
}
/**
+ * ixgbe_write_eewr_generic - Write EEPROM word using EEWR
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to write
+ * @data: word write to the EEPROM
+ *
+ * Write a 16 bit word to the EEPROM using the EEWR register.
+ **/
+s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
+{
+ return ixgbe_write_eewr_buffer_generic(hw, offset, 1, &data);
+}
+
+/**
* ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status
* @hw: pointer to hardware structure
* @ee_reg: EEPROM flag for polling
@@ -746,7 +1089,7 @@ out:
* Polls the status bit (bit 1) of the EERD or EEWR to determine when the
* read or write is done respectively.
**/
-s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
+static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
{
u32 i;
u32 reg;
@@ -846,6 +1189,28 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
udelay(50);
}
+ if (i == timeout) {
+ hw_dbg(hw, "Driver can't access the Eeprom - SMBI Semaphore "
+ "not granted.\n");
+ /*
+ * this release is particularly important because our attempts
+ * above to get the semaphore may have succeeded, and if there
+ * was a timeout, we should unconditionally clear the semaphore
+ * bits to free the driver to make progress
+ */
+ ixgbe_release_eeprom_semaphore(hw);
+
+ udelay(50);
+ /*
+ * one last try
+ * If the SMBI bit is 0 when we read it, then the bit will be
+ * set and we have the semaphore
+ */
+ swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
+ if (!(swsm & IXGBE_SWSM_SMBI))
+ status = 0;
+ }
+
/* Now get the semaphore between SW/FW through the SWESMBI bit */
if (status == 0) {
for (i = 0; i < timeout; i++) {
@@ -1112,8 +1477,12 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
- /* Delay before attempt to obtain semaphore again to allow FW access */
- msleep(hw->eeprom.semaphore_delay);
+ /*
+ * Delay before attempt to obtain semaphore again to allow FW
+ * access. semaphore_delay is in ms we need us for usleep_range
+ */
+ usleep_range(hw->eeprom.semaphore_delay * 1000,
+ hw->eeprom.semaphore_delay * 2000);
}
/**
@@ -2189,7 +2558,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
* thread currently using resource (swmask)
*/
ixgbe_release_eeprom_semaphore(hw);
- msleep(5);
+ usleep_range(5000, 10000);
timeout--;
}
@@ -2263,7 +2632,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
autoc_reg |= IXGBE_AUTOC_AN_RESTART;
autoc_reg |= IXGBE_AUTOC_FLU;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
- msleep(10);
+ usleep_range(10000, 20000);
}
led_reg &= ~IXGBE_LED_MODE_MASK(index);
@@ -2883,3 +3252,18 @@ void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf)
pfvfspoof &= ~(1 << vf_target_shift);
IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
}
+
+/**
+ * ixgbe_get_device_caps_generic - Get additional device capabilities
+ * @hw: pointer to hardware structure
+ * @device_caps: the EEPROM word with the extra device capabilities
+ *
+ * This function will read the EEPROM location for the device capabilities,
+ * and return the word through device_caps.
+ **/
+s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps)
+{
+ hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps);
+
+ return 0;
+}
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h
index 508f635fc2c..46be83cfb50 100644
--- a/drivers/net/ixgbe/ixgbe_common.h
+++ b/drivers/net/ixgbe/ixgbe_common.h
@@ -35,6 +35,7 @@ u32 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw);
s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw);
s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw);
s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw);
+s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw);
s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw);
s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num,
u32 pba_num_size);
@@ -48,14 +49,22 @@ s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw);
s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
+s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data);
s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data);
+s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data);
+s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
+s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data);
s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
u16 *data);
+s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data);
u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw);
s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
u16 *checksum_val);
s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw);
-s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg);
s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
u32 enable_addr);
@@ -89,6 +98,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index);
void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf);
void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf);
+s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps);
#define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c
index 1bc57e52cee..771d01a60d0 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82598.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c
@@ -289,7 +289,7 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
* Configure queue statistics registers, all queues belonging to same traffic
* class uses a single set of queue statistics counters.
*/
-s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
+static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
{
u32 reg = 0;
u8 i = 0;
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c
index 025af8c53dd..d50cf78c234 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82599.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c
@@ -39,36 +39,52 @@
*/
static s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw, u8 rx_pba)
{
- s32 ret_val = 0;
- u32 value = IXGBE_RXPBSIZE_64KB;
+ int num_tcs = IXGBE_MAX_PACKET_BUFFERS;
+ u32 rx_pb_size = hw->mac.rx_pb_size << IXGBE_RXPBSIZE_SHIFT;
+ u32 rxpktsize;
+ u32 txpktsize;
+ u32 txpbthresh;
u8 i = 0;
- /* Setup Rx packet buffer sizes */
- switch (rx_pba) {
- case pba_80_48:
- /* Setup the first four at 80KB */
- value = IXGBE_RXPBSIZE_80KB;
- for (; i < 4; i++)
- IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
- /* Setup the last four at 48KB...don't re-init i */
- value = IXGBE_RXPBSIZE_48KB;
- /* Fall Through */
- case pba_equal:
- default:
- for (; i < IXGBE_MAX_PACKET_BUFFERS; i++)
- IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
-
- /* Setup Tx packet buffer sizes */
- for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
- IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i),
- IXGBE_TXPBSIZE_20KB);
- IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i),
- IXGBE_TXPBTHRESH_DCB);
- }
- break;
+ /*
+ * This really means configure the first half of the TCs
+ * (Traffic Classes) to use 5/8 of the Rx packet buffer
+ * space. To determine the size of the buffer for each TC,
+ * we are multiplying the average size by 5/4 and applying
+ * it to half of the traffic classes.
+ */
+ if (rx_pba == pba_80_48) {
+ rxpktsize = (rx_pb_size * 5) / (num_tcs * 4);
+ rx_pb_size -= rxpktsize * (num_tcs / 2);
+ for (; i < (num_tcs / 2); i++)
+ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
+ }
+
+ /* Divide the remaining Rx packet buffer evenly among the TCs */
+ rxpktsize = rx_pb_size / (num_tcs - i);
+ for (; i < num_tcs; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
+
+ /*
+ * Setup Tx packet buffer and threshold equally for all TCs
+ * TXPBTHRESH register is set in K so divide by 1024 and subtract
+ * 10 since the largest packet we support is just over 9K.
+ */
+ txpktsize = IXGBE_TXPBSIZE_MAX / num_tcs;
+ txpbthresh = (txpktsize / 1024) - IXGBE_TXPKT_SIZE_MAX;
+ for (i = 0; i < num_tcs; i++) {
+ IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), txpktsize);
+ IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), txpbthresh);
+ }
+
+ /* Clear unused TCs, if any, to zero buffer size*/
+ for (; i < MAX_TRAFFIC_CLASS; i++) {
+ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), 0);
}
- return ret_val;
+ return 0;
}
/**
@@ -285,12 +301,17 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en)
IXGBE_WRITE_REG(hw, IXGBE_FCCFG, reg);
/*
* Enable Receive PFC
- * We will always honor XOFF frames we receive when
- * we are in PFC mode.
+ * 82599 will always honor XOFF frames we receive when
+ * we are in PFC mode however X540 only honors enabled
+ * traffic classes.
*/
reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
reg &= ~IXGBE_MFLCN_RFCE;
reg |= IXGBE_MFLCN_RPFCE | IXGBE_MFLCN_DPF;
+
+ if (hw->mac.type == ixgbe_mac_X540)
+ reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT;
+
IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg);
} else {
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h
index 148fd8b477a..2de71a50315 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82599.h
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h
@@ -92,8 +92,10 @@
#define IXGBE_RXPBSIZE_64KB 0x00010000 /* 64KB Packet Buffer */
#define IXGBE_RXPBSIZE_80KB 0x00014000 /* 80KB Packet Buffer */
#define IXGBE_RXPBSIZE_128KB 0x00020000 /* 128KB Packet Buffer */
+#define IXGBE_TXPBSIZE_MAX 0x00028000 /* 160KB Packet Buffer*/
#define IXGBE_TXPBTHRESH_DCB 0xA /* THRESH value for DCB mode */
+#define IXGBE_TXPKT_SIZE_MAX 0xA /* Max Tx Packet size */
/* SECTXMINIFG DCB */
#define IXGBE_SECTX_DCB 0x00001F00 /* DCB TX Buffer IFG */
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index 327c8614198..5e7ed225851 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -347,18 +347,28 @@ static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority,
static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct dcb_app app = {
+ .selector = DCB_APP_IDTYPE_ETHTYPE,
+ .protocol = ETH_P_FCOE,
+ };
+ u8 up = dcb_getapp(netdev, &app);
int ret;
- if (!adapter->dcb_set_bitmap ||
- !(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
- return DCB_NO_HW_CHG;
-
ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
MAX_TRAFFIC_CLASS);
-
if (ret)
return DCB_NO_HW_CHG;
+ /* In IEEE mode app data must be parsed into DCBX format for
+ * hardware routines.
+ */
+ if (adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)
+ up = (1 << up);
+
+#ifdef IXGBE_FCOE
+ if (up && (up != (1 << adapter->fcoe.up)))
+ adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
+
/*
* Only take down the adapter if an app change occurred. FCoE
* may shuffle tx rings in this case and this can not be done
@@ -366,12 +376,15 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
*/
if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
+
+ ixgbe_fcoe_setapp(adapter, up);
if (netif_running(netdev))
netdev->netdev_ops->ndo_stop(netdev);
ixgbe_clear_interrupt_scheme(adapter);
}
+#endif
if (adapter->dcb_cfg.pfc_mode_enable) {
switch (adapter->hw.mac.type) {
@@ -399,12 +412,14 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
}
}
+#ifdef IXGBE_FCOE
if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
ixgbe_init_interrupt_scheme(adapter);
if (netif_running(netdev))
netdev->netdev_ops->ndo_open(netdev);
ret = DCB_HW_CHG_RST;
}
+#endif
if (adapter->dcb_set_bitmap & BIT_PFC) {
u8 pfc_en;
@@ -558,68 +573,6 @@ static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
return dcb_getapp(netdev, &app);
}
-/**
- * ixgbe_dcbnl_setapp - set the DCBX application user priority
- * @netdev : the corresponding netdev
- * @idtype : identifies the id as ether type or TCP/UDP port number
- * @id: id is either ether type or TCP/UDP port number
- * @up: the 802.1p user priority bitmap
- *
- * Returns : 0 on success or 1 on error
- */
-static u8 ixgbe_dcbnl_setapp(struct net_device *netdev,
- u8 idtype, u16 id, u8 up)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- u8 rval = 1;
- struct dcb_app app = {
- .selector = idtype,
- .protocol = id,
- .priority = up
- };
-
- if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
- return rval;
-
- rval = dcb_setapp(netdev, &app);
-
- switch (idtype) {
- case DCB_APP_IDTYPE_ETHTYPE:
-#ifdef IXGBE_FCOE
- if (id == ETH_P_FCOE) {
- u8 old_tc;
-
- /* Get current programmed tc */
- old_tc = adapter->fcoe.tc;
- rval = ixgbe_fcoe_setapp(adapter, up);
-
- if (rval ||
- !(adapter->flags & IXGBE_FLAG_DCB_ENABLED) ||
- !(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
- break;
-
- /* The FCoE application priority may be changed multiple
- * times in quick succession with switches that build up
- * TLVs. To avoid creating uneeded device resets this
- * checks the actual HW configuration and clears
- * BIT_APP_UPCHG if a HW configuration change is not
- * need
- */
- if (old_tc == adapter->fcoe.tc)
- adapter->dcb_set_bitmap &= ~BIT_APP_UPCHG;
- else
- adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
- }
-#endif
- break;
- case DCB_APP_IDTYPE_PORTNUM:
- break;
- default:
- break;
- }
- return rval;
-}
-
static int ixgbe_dcbnl_ieee_getets(struct net_device *dev,
struct ieee_ets *ets)
{
@@ -745,25 +698,14 @@ static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev,
if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
return -EINVAL;
-#ifdef IXGBE_FCOE
- if (app->selector == 1 && app->protocol == ETH_P_FCOE) {
- if (adapter->fcoe.tc == app->priority)
- goto setapp;
- /* In IEEE mode map up to tc 1:1 */
- adapter->fcoe.tc = app->priority;
- adapter->fcoe.up = app->priority;
+ dcb_setapp(dev, app);
- /* Force hardware reset required to push FCoE
- * setup on {tx|rx}_rings
- */
- adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
+#ifdef IXGBE_FCOE
+ if (app->selector == 1 && app->protocol == ETH_P_FCOE &&
+ adapter->fcoe.tc == app->priority)
ixgbe_dcbnl_set_all(dev);
- }
-
-setapp:
#endif
- dcb_setapp(dev, app);
return 0;
}
@@ -838,7 +780,6 @@ const struct dcbnl_rtnl_ops dcbnl_ops = {
.getpfcstate = ixgbe_dcbnl_getpfcstate,
.setpfcstate = ixgbe_dcbnl_setpfcstate,
.getapp = ixgbe_dcbnl_getapp,
- .setapp = ixgbe_dcbnl_setapp,
.getdcbx = ixgbe_dcbnl_getdcbx,
.setdcbx = ixgbe_dcbnl_setdcbx,
};
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 76380a2b35a..cb1555bc854 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -84,6 +84,7 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"hw_rsc_flushed", IXGBE_STAT(rsc_total_flush)},
{"fdir_match", IXGBE_STAT(stats.fdirmatch)},
{"fdir_miss", IXGBE_STAT(stats.fdirmiss)},
+ {"fdir_overflow", IXGBE_STAT(fdir_overflow)},
{"rx_fifo_errors", IXGBE_NETDEV_STAT(rx_fifo_errors)},
{"rx_missed_errors", IXGBE_NETDEV_STAT(rx_missed_errors)},
{"tx_aborted_errors", IXGBE_NETDEV_STAT(tx_aborted_errors)},
@@ -102,6 +103,10 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)},
{"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)},
{"rx_no_dma_resources", IXGBE_STAT(hw_rx_no_dma_resources)},
+ {"os2bmc_rx_by_bmc", IXGBE_STAT(stats.o2bgptc)},
+ {"os2bmc_tx_by_bmc", IXGBE_STAT(stats.b2ospc)},
+ {"os2bmc_tx_by_host", IXGBE_STAT(stats.o2bspc)},
+ {"os2bmc_rx_by_host", IXGBE_STAT(stats.b2ogprc)},
#ifdef IXGBE_FCOE
{"fcoe_bad_fccrc", IXGBE_STAT(stats.fccrc)},
{"rx_fcoe_dropped", IXGBE_STAT(stats.fcoerpdc)},
@@ -288,20 +293,20 @@ static int ixgbe_get_settings(struct net_device *netdev,
if (link_up) {
switch (link_speed) {
case IXGBE_LINK_SPEED_10GB_FULL:
- ecmd->speed = SPEED_10000;
+ ethtool_cmd_speed_set(ecmd, SPEED_10000);
break;
case IXGBE_LINK_SPEED_1GB_FULL:
- ecmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(ecmd, SPEED_1000);
break;
case IXGBE_LINK_SPEED_100_FULL:
- ecmd->speed = SPEED_100;
+ ethtool_cmd_speed_set(ecmd, SPEED_100);
break;
default:
break;
}
ecmd->duplex = DUPLEX_FULL;
} else {
- ecmd->speed = -1;
+ ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1;
}
@@ -346,9 +351,10 @@ static int ixgbe_set_settings(struct net_device *netdev,
}
} else {
/* in this case we currently only support 10Gb/FULL */
+ u32 speed = ethtool_cmd_speed(ecmd);
if ((ecmd->autoneg == AUTONEG_ENABLE) ||
(ecmd->advertising != ADVERTISED_10000baseT_Full) ||
- (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
+ (speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
return -EINVAL;
}
@@ -846,11 +852,8 @@ static int ixgbe_get_eeprom(struct net_device *netdev,
if (!eeprom_buff)
return -ENOMEM;
- for (i = 0; i < eeprom_len; i++) {
- if ((ret_val = hw->eeprom.ops.read(hw, first_word + i,
- &eeprom_buff[i])))
- break;
- }
+ ret_val = hw->eeprom.ops.read_buffer(hw, first_word, eeprom_len,
+ eeprom_buff);
/* Device's eeprom is always little-endian, word addressable */
for (i = 0; i < eeprom_len; i++)
@@ -931,7 +934,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
}
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
if (!netif_running(adapter->netdev)) {
for (i = 0; i < adapter->num_tx_queues; i++)
@@ -1030,9 +1033,6 @@ static int ixgbe_get_sset_count(struct net_device *netdev, int sset)
return IXGBE_TEST_LEN;
case ETH_SS_STATS:
return IXGBE_STATS_LEN;
- case ETH_SS_NTUPLE_FILTERS:
- return ETHTOOL_MAX_NTUPLE_LIST_ENTRY *
- ETHTOOL_MAX_NTUPLE_STRING_PER_ENTRY;
default:
return -EOPNOTSUPP;
}
@@ -1238,46 +1238,62 @@ static const struct ixgbe_reg_test reg_test_82598[] = {
{ 0, 0, 0, 0 }
};
-static const u32 register_test_patterns[] = {
- 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
-};
-
-#define REG_PATTERN_TEST(R, M, W) \
-{ \
- u32 pat, val, before; \
- for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) { \
- before = readl(adapter->hw.hw_addr + R); \
- writel((register_test_patterns[pat] & W), \
- (adapter->hw.hw_addr + R)); \
- val = readl(adapter->hw.hw_addr + R); \
- if (val != (register_test_patterns[pat] & W & M)) { \
- e_err(drv, "pattern test reg %04X failed: got " \
- "0x%08X expected 0x%08X\n", \
- R, val, (register_test_patterns[pat] & W & M)); \
- *data = R; \
- writel(before, adapter->hw.hw_addr + R); \
- return 1; \
- } \
- writel(before, adapter->hw.hw_addr + R); \
- } \
+static bool reg_pattern_test(struct ixgbe_adapter *adapter, u64 *data, int reg,
+ u32 mask, u32 write)
+{
+ u32 pat, val, before;
+ static const u32 test_pattern[] = {
+ 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
+
+ for (pat = 0; pat < ARRAY_SIZE(test_pattern); pat++) {
+ before = readl(adapter->hw.hw_addr + reg);
+ writel((test_pattern[pat] & write),
+ (adapter->hw.hw_addr + reg));
+ val = readl(adapter->hw.hw_addr + reg);
+ if (val != (test_pattern[pat] & write & mask)) {
+ e_err(drv, "pattern test reg %04X failed: got "
+ "0x%08X expected 0x%08X\n",
+ reg, val, (test_pattern[pat] & write & mask));
+ *data = reg;
+ writel(before, adapter->hw.hw_addr + reg);
+ return 1;
+ }
+ writel(before, adapter->hw.hw_addr + reg);
+ }
+ return 0;
}
-#define REG_SET_AND_CHECK(R, M, W) \
-{ \
- u32 val, before; \
- before = readl(adapter->hw.hw_addr + R); \
- writel((W & M), (adapter->hw.hw_addr + R)); \
- val = readl(adapter->hw.hw_addr + R); \
- if ((W & M) != (val & M)) { \
- e_err(drv, "set/check reg %04X test failed: got 0x%08X " \
- "expected 0x%08X\n", R, (val & M), (W & M)); \
- *data = R; \
- writel(before, (adapter->hw.hw_addr + R)); \
- return 1; \
- } \
- writel(before, (adapter->hw.hw_addr + R)); \
+static bool reg_set_and_check(struct ixgbe_adapter *adapter, u64 *data, int reg,
+ u32 mask, u32 write)
+{
+ u32 val, before;
+ before = readl(adapter->hw.hw_addr + reg);
+ writel((write & mask), (adapter->hw.hw_addr + reg));
+ val = readl(adapter->hw.hw_addr + reg);
+ if ((write & mask) != (val & mask)) {
+ e_err(drv, "set/check reg %04X test failed: got 0x%08X "
+ "expected 0x%08X\n", reg, (val & mask), (write & mask));
+ *data = reg;
+ writel(before, (adapter->hw.hw_addr + reg));
+ return 1;
+ }
+ writel(before, (adapter->hw.hw_addr + reg));
+ 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 ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
{
const struct ixgbe_reg_test *test;
@@ -1328,13 +1344,13 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
switch (test->test_type) {
case PATTERN_TEST:
REG_PATTERN_TEST(test->reg + (i * 0x40),
- test->mask,
- test->write);
+ test->mask,
+ test->write);
break;
case SET_READ_TEST:
REG_SET_AND_CHECK(test->reg + (i * 0x40),
- test->mask,
- test->write);
+ test->mask,
+ test->write);
break;
case WRITE_NO_TEST:
writel(test->write,
@@ -1343,18 +1359,18 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
break;
case TABLE32_TEST:
REG_PATTERN_TEST(test->reg + (i * 4),
- test->mask,
- test->write);
+ test->mask,
+ test->write);
break;
case TABLE64_TEST_LO:
REG_PATTERN_TEST(test->reg + (i * 8),
- test->mask,
- test->write);
+ test->mask,
+ test->write);
break;
case TABLE64_TEST_HI:
REG_PATTERN_TEST((test->reg + 4) + (i * 8),
- test->mask,
- test->write);
+ test->mask,
+ test->write);
break;
}
}
@@ -1417,7 +1433,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)
/* Disable all the interrupts */
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF);
- msleep(10);
+ usleep_range(10000, 20000);
/* Test each interrupt */
for (; i < 10; i++) {
@@ -1437,7 +1453,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)
~mask & 0x00007FFF);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
~mask & 0x00007FFF);
- msleep(10);
+ usleep_range(10000, 20000);
if (adapter->test_icr & mask) {
*data = 3;
@@ -1454,7 +1470,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)
adapter->test_icr = 0;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask);
- msleep(10);
+ usleep_range(10000, 20000);
if (!(adapter->test_icr &mask)) {
*data = 4;
@@ -1474,7 +1490,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)
~mask & 0x00007FFF);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
~mask & 0x00007FFF);
- msleep(10);
+ usleep_range(10000, 20000);
if (adapter->test_icr) {
*data = 5;
@@ -1485,7 +1501,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)
/* Disable all the interrupts */
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF);
- msleep(10);
+ usleep_range(10000, 20000);
/* Unhook test interrupt handler */
free_irq(irq, netdev);
@@ -1598,6 +1614,13 @@ static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw;
u32 reg_data;
+ /* X540 needs to set the MACC.FLU bit to force link up */
+ if (adapter->hw.mac.type == ixgbe_mac_X540) {
+ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_MACC);
+ reg_data |= IXGBE_MACC_FLU;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_MACC, reg_data);
+ }
+
/* right now we only support MAC loopback in the driver */
reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
/* Setup MAC loopback */
@@ -1613,7 +1636,7 @@ static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter)
reg_data |= IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_AUTOC, reg_data);
IXGBE_WRITE_FLUSH(&adapter->hw);
- msleep(10);
+ usleep_range(10000, 20000);
/* Disable Atlas Tx lanes; re-enabled in reset path */
if (hw->mac.type == ixgbe_mac_82598EB) {
@@ -1999,25 +2022,30 @@ static int ixgbe_nway_reset(struct net_device *netdev)
return 0;
}
-static int ixgbe_phys_id(struct net_device *netdev, u32 data)
+static int ixgbe_set_phys_id(struct net_device *netdev,
+ enum ethtool_phys_id_state state)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
- u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
- u32 i;
- if (!data || data > 300)
- data = 300;
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ adapter->led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+ return 2;
- for (i = 0; i < (data * 1000); i += 400) {
+ case ETHTOOL_ID_ON:
hw->mac.ops.led_on(hw, IXGBE_LED_ON);
- msleep_interruptible(200);
+ break;
+
+ case ETHTOOL_ID_OFF:
hw->mac.ops.led_off(hw, IXGBE_LED_ON);
- msleep_interruptible(200);
- }
+ break;
- /* Restore LED settings */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_LEDCTL, led_reg);
+ case ETHTOOL_ID_INACTIVE:
+ /* Restore LED settings */
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_LEDCTL, adapter->led_reg);
+ break;
+ }
return 0;
}
@@ -2230,8 +2258,13 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data)
need_reset = (data & ETH_FLAG_RXVLAN) !=
(netdev->features & NETIF_F_HW_VLAN_RX);
+ if ((data & ETH_FLAG_RXHASH) &&
+ !(adapter->flags & IXGBE_FLAG_RSS_ENABLED))
+ return -EOPNOTSUPP;
+
rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | ETH_FLAG_NTUPLE |
- ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN);
+ ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN |
+ ETH_FLAG_RXHASH);
if (rc)
return rc;
@@ -2465,7 +2498,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
.set_tso = ixgbe_set_tso,
.self_test = ixgbe_diag_test,
.get_strings = ixgbe_get_strings,
- .phys_id = ixgbe_phys_id,
+ .set_phys_id = ixgbe_set_phys_id,
.get_sset_count = ixgbe_get_sset_count,
.get_ethtool_stats = ixgbe_get_ethtool_stats,
.get_coalesce = ixgbe_get_coalesce,
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c
index dba7d77588e..05920726e82 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ixgbe/ixgbe_fcoe.c
@@ -416,8 +416,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
if (!ddp->udl)
goto ddp_out;
- ddp->err = (fcerr | fceofe);
- if (ddp->err)
+ if (fcerr | fceofe)
goto ddp_out;
fcstat = (sterr & IXGBE_RXDADV_STAT_FCSTAT);
@@ -428,6 +427,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_FCPRSP) {
pci_unmap_sg(adapter->pdev, ddp->sgl,
ddp->sgc, DMA_FROM_DEVICE);
+ ddp->err = (fcerr | fceofe);
ddp->sgl = NULL;
ddp->sgc = 0;
}
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index e145f2c455c..fa01b0b03b7 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -51,8 +51,12 @@
char ixgbe_driver_name[] = "ixgbe";
static const char ixgbe_driver_string[] =
"Intel(R) 10 Gigabit PCI Express Network Driver";
-
-#define DRV_VERSION "3.2.9-k2"
+#define MAJ 3
+#define MIN 3
+#define BUILD 8
+#define KFIX 2
+#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
+ __stringify(BUILD) "-k" __stringify(KFIX)
const char ixgbe_driver_version[] = DRV_VERSION;
static const char ixgbe_copyright[] =
"Copyright (c) 1999-2011 Intel Corporation.";
@@ -120,6 +124,10 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = {
board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T),
board_X540 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF2),
+ board_82599 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_LS),
+ board_82599 },
/* required last entry */
{0, }
@@ -185,6 +193,22 @@ static inline void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
}
+static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)
+{
+ if (!test_bit(__IXGBE_DOWN, &adapter->state) &&
+ !test_and_set_bit(__IXGBE_SERVICE_SCHED, &adapter->state))
+ schedule_work(&adapter->service_task);
+}
+
+static void ixgbe_service_event_complete(struct ixgbe_adapter *adapter)
+{
+ BUG_ON(!test_bit(__IXGBE_SERVICE_SCHED, &adapter->state));
+
+ /* flush memory to make sure state is correct before next watchog */
+ smp_mb__before_clear_bit();
+ clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);
+}
+
struct ixgbe_reg_info {
u32 ofs;
char *name;
@@ -811,7 +835,19 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring)
#define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */
-static void ixgbe_tx_timeout(struct net_device *netdev);
+/**
+ * ixgbe_tx_timeout_reset - initiate reset due to Tx timeout
+ * @adapter: driver private struct
+ **/
+static void ixgbe_tx_timeout_reset(struct ixgbe_adapter *adapter)
+{
+
+ /* Do the reset outside of interrupt context */
+ if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+ adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED;
+ ixgbe_service_event_schedule(adapter);
+ }
+}
/**
* ixgbe_clean_tx_irq - Reclaim resources after transmit completes
@@ -893,7 +929,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
adapter->tx_timeout_count + 1, tx_ring->queue_index);
/* schedule immediate reset if we believe we hung */
- ixgbe_tx_timeout(adapter->netdev);
+ ixgbe_tx_timeout_reset(adapter);
/* the adapter is about to reset, no point in enabling stuff */
return true;
@@ -943,8 +979,6 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN);
- rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
- IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(reg_idx), rxctrl);
}
@@ -962,7 +996,6 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
- txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(reg_idx), txctrl);
break;
case ixgbe_mac_82599EB:
@@ -972,7 +1005,6 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
- txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(reg_idx), txctrl);
break;
default:
@@ -1061,8 +1093,14 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
return 0;
}
-
#endif /* CONFIG_IXGBE_DCA */
+
+static inline void ixgbe_rx_hash(union ixgbe_adv_rx_desc *rx_desc,
+ struct sk_buff *skb)
+{
+ skb->rxhash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);
+}
+
/**
* ixgbe_receive_skb - Send a completed packet up the stack
* @adapter: board private structure
@@ -1454,6 +1492,8 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
}
ixgbe_rx_checksum(adapter, rx_desc, skb);
+ if (adapter->netdev->features & NETIF_F_RXHASH)
+ ixgbe_rx_hash(rx_desc, skb);
/* probably a little skewed due to removing CRC */
total_rx_bytes += skb->len;
@@ -1787,35 +1827,51 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
}
/**
- * ixgbe_check_overtemp_task - worker thread to check over tempurature
- * @work: pointer to work_struct containing our data
+ * ixgbe_check_overtemp_subtask - check for over tempurature
+ * @adapter: pointer to adapter
**/
-static void ixgbe_check_overtemp_task(struct work_struct *work)
+static void ixgbe_check_overtemp_subtask(struct ixgbe_adapter *adapter)
{
- struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- check_overtemp_task);
struct ixgbe_hw *hw = &adapter->hw;
u32 eicr = adapter->interrupt_event;
- if (!(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE))
+ if (test_bit(__IXGBE_DOWN, &adapter->state))
return;
+ if (!(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
+ !(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_EVENT))
+ return;
+
+ adapter->flags2 &= ~IXGBE_FLAG2_TEMP_SENSOR_EVENT;
+
switch (hw->device_id) {
- case IXGBE_DEV_ID_82599_T3_LOM: {
- u32 autoneg;
- bool link_up = false;
+ case IXGBE_DEV_ID_82599_T3_LOM:
+ /*
+ * Since the warning interrupt is for both ports
+ * we don't have to check if:
+ * - This interrupt wasn't for our port.
+ * - We may have missed the interrupt so always have to
+ * check if we got a LSC
+ */
+ if (!(eicr & IXGBE_EICR_GPI_SDP0) &&
+ !(eicr & IXGBE_EICR_LSC))
+ return;
+
+ if (!(eicr & IXGBE_EICR_LSC) && hw->mac.ops.check_link) {
+ u32 autoneg;
+ bool link_up = false;
- if (hw->mac.ops.check_link)
hw->mac.ops.check_link(hw, &autoneg, &link_up, false);
- if (((eicr & IXGBE_EICR_GPI_SDP0) && (!link_up)) ||
- (eicr & IXGBE_EICR_LSC))
- /* Check if this is due to overtemp */
- if (hw->phy.ops.check_overtemp(hw) == IXGBE_ERR_OVERTEMP)
- break;
- return;
- }
+ if (link_up)
+ return;
+ }
+
+ /* Check if this is not due to overtemp */
+ if (hw->phy.ops.check_overtemp(hw) != IXGBE_ERR_OVERTEMP)
+ return;
+
+ break;
default:
if (!(eicr & IXGBE_EICR_GPI_SDP0))
return;
@@ -1825,8 +1881,8 @@ static void ixgbe_check_overtemp_task(struct work_struct *work)
"Network adapter has been stopped because it has over heated. "
"Restart the computer. If the problem persists, "
"power off the system and replace the adapter\n");
- /* write to clear the interrupt */
- IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0);
+
+ adapter->interrupt_event = 0;
}
static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr)
@@ -1848,15 +1904,19 @@ static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr)
if (eicr & IXGBE_EICR_GPI_SDP2) {
/* Clear the interrupt */
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2);
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- schedule_work(&adapter->sfp_config_module_task);
+ if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+ adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
+ ixgbe_service_event_schedule(adapter);
+ }
}
if (eicr & IXGBE_EICR_GPI_SDP1) {
/* Clear the interrupt */
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- schedule_work(&adapter->multispeed_fiber_task);
+ if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+ adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
+ ixgbe_service_event_schedule(adapter);
+ }
}
}
@@ -1870,7 +1930,7 @@ static void ixgbe_check_lsc(struct ixgbe_adapter *adapter)
if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC);
IXGBE_WRITE_FLUSH(hw);
- schedule_work(&adapter->watchdog_task);
+ ixgbe_service_event_schedule(adapter);
}
}
@@ -1898,26 +1958,32 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
switch (hw->mac.type) {
case ixgbe_mac_82599EB:
- ixgbe_check_sfp_event(adapter, eicr);
- if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
- ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) {
- adapter->interrupt_event = eicr;
- schedule_work(&adapter->check_overtemp_task);
- }
- /* now fallthrough to handle Flow Director */
case ixgbe_mac_X540:
/* Handle Flow Director Full threshold interrupt */
if (eicr & IXGBE_EICR_FLOW_DIR) {
+ int reinit_count = 0;
int i;
- IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_FLOW_DIR);
- /* Disable transmits before FDIR Re-initialization */
- netif_tx_stop_all_queues(netdev);
for (i = 0; i < adapter->num_tx_queues; i++) {
- struct ixgbe_ring *tx_ring =
- adapter->tx_ring[i];
+ struct ixgbe_ring *ring = adapter->tx_ring[i];
if (test_and_clear_bit(__IXGBE_TX_FDIR_INIT_DONE,
- &tx_ring->state))
- schedule_work(&adapter->fdir_reinit_task);
+ &ring->state))
+ reinit_count++;
+ }
+ if (reinit_count) {
+ /* no more flow director interrupts until after init */
+ IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_FLOW_DIR);
+ eicr &= ~IXGBE_EICR_FLOW_DIR;
+ adapter->flags2 |= IXGBE_FLAG2_FDIR_REQUIRES_REINIT;
+ ixgbe_service_event_schedule(adapter);
+ }
+ }
+ ixgbe_check_sfp_event(adapter, eicr);
+ if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
+ ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) {
+ if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+ adapter->interrupt_event = eicr;
+ adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_EVENT;
+ ixgbe_service_event_schedule(adapter);
}
}
break;
@@ -1927,8 +1993,10 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
ixgbe_check_fan_failure(adapter, eicr);
+ /* re-enable the original interrupt state, no lsc, no queues */
if (!test_bit(__IXGBE_DOWN, &adapter->state))
- IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
+ IXGBE_WRITE_REG(hw, IXGBE_EIMS, eicr &
+ ~(IXGBE_EIMS_LSC | IXGBE_EIMS_RTX_QUEUE));
return IRQ_HANDLED;
}
@@ -2513,8 +2581,11 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
ixgbe_check_sfp_event(adapter, eicr);
if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) {
- adapter->interrupt_event = eicr;
- schedule_work(&adapter->check_overtemp_task);
+ if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+ adapter->interrupt_event = eicr;
+ adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_EVENT;
+ ixgbe_service_event_schedule(adapter);
+ }
}
break;
default:
@@ -2731,7 +2802,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
/* poll to verify queue is enabled */
do {
- msleep(1);
+ usleep_range(1000, 2000);
txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
} while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE));
if (!wait_loop)
@@ -3023,7 +3094,7 @@ static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
return;
do {
- msleep(1);
+ usleep_range(1000, 2000);
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
} while (--wait_loop && !(rxdctl & IXGBE_RXDCTL_ENABLE));
@@ -3178,7 +3249,9 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
/* enable Tx loopback for VF/PF communication */
IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
/* Enable MAC Anti-Spoofing */
- hw->mac.ops.set_mac_anti_spoofing(hw, (adapter->num_vfs != 0),
+ hw->mac.ops.set_mac_anti_spoofing(hw,
+ (adapter->antispoofing_enabled =
+ (adapter->num_vfs != 0)),
adapter->num_vfs);
}
@@ -3487,7 +3560,7 @@ static int ixgbe_write_uc_addr_list(struct net_device *netdev)
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
unsigned int vfn = adapter->num_vfs;
- unsigned int rar_entries = hw->mac.num_rar_entries - (vfn + 1);
+ unsigned int rar_entries = IXGBE_MAX_PF_MACVLANS;
int count = 0;
/* return ENOMEM indicating insufficient memory for addresses */
@@ -3760,31 +3833,16 @@ static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw)
**/
static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter)
{
- struct ixgbe_hw *hw = &adapter->hw;
+ /*
+ * We are assuming the worst case scenerio here, and that
+ * is that an SFP was inserted/removed after the reset
+ * but before SFP detection was enabled. As such the best
+ * solution is to just start searching as soon as we start
+ */
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+ adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
- if (hw->phy.multispeed_fiber) {
- /*
- * In multispeed fiber setups, the device may not have
- * had a physical connection when the driver loaded.
- * If that's the case, the initial link configuration
- * couldn't get the MAC into 10G or 1G mode, so we'll
- * never have a link status change interrupt fire.
- * We need to try and force an autonegotiation
- * session, then bring up link.
- */
- if (hw->mac.ops.setup_sfp)
- hw->mac.ops.setup_sfp(hw);
- if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
- schedule_work(&adapter->multispeed_fiber_task);
- } else {
- /*
- * Direct Attach Cu and non-multispeed fiber modules
- * still need to be configured properly prior to
- * attempting link.
- */
- if (!(adapter->flags & IXGBE_FLAG_IN_SFP_MOD_TASK))
- schedule_work(&adapter->sfp_config_module_task);
- }
+ adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
}
/**
@@ -3860,9 +3918,10 @@ static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter)
if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
gpie |= IXGBE_SDP1_GPIEN;
- if (hw->mac.type == ixgbe_mac_82599EB)
+ if (hw->mac.type == ixgbe_mac_82599EB) {
gpie |= IXGBE_SDP1_GPIEN;
gpie |= IXGBE_SDP2_GPIEN;
+ }
IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
}
@@ -3913,17 +3972,6 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
e_crit(drv, "Fan has stopped, replace the adapter\n");
}
- /*
- * For hot-pluggable SFP+ devices, a new SFP+ module may have
- * arrived before interrupts were enabled but after probe. Such
- * devices wouldn't have their type identified yet. We need to
- * kick off the SFP+ module setup first, then try to bring up link.
- * If we're not hot-pluggable SFP+, we just need to configure link
- * and bring it up.
- */
- if (hw->phy.type == ixgbe_phy_none)
- schedule_work(&adapter->sfp_config_module_task);
-
/* enable transmits */
netif_tx_start_all_queues(adapter->netdev);
@@ -3931,7 +3979,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
* link up interrupt but shouldn't be a problem */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
adapter->link_check_timeout = jiffies;
- mod_timer(&adapter->watchdog_timer, jiffies);
+ mod_timer(&adapter->service_timer, jiffies);
/* Set PF Reset Done bit so PF/VF Mail Ops can work */
ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
@@ -3944,8 +3992,11 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
{
WARN_ON(in_interrupt());
+ /* put off any impending NetWatchDogTimeout */
+ adapter->netdev->trans_start = jiffies;
+
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
ixgbe_down(adapter);
/*
* If SR-IOV enabled then wait a bit before bringing the adapter
@@ -3972,10 +4023,20 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw;
int err;
+ /* lock SFP init bit to prevent race conditions with the watchdog */
+ while (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
+ usleep_range(1000, 2000);
+
+ /* clear all SFP and link config related flags while holding SFP_INIT */
+ adapter->flags2 &= ~(IXGBE_FLAG2_SEARCH_FOR_SFP |
+ IXGBE_FLAG2_SFP_NEEDS_RESET);
+ adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
+
err = hw->mac.ops.init_hw(hw);
switch (err) {
case 0:
case IXGBE_ERR_SFP_NOT_PRESENT:
+ case IXGBE_ERR_SFP_NOT_SUPPORTED:
break;
case IXGBE_ERR_MASTER_REQUESTS_PENDING:
e_dev_err("master disable timed out\n");
@@ -3993,6 +4054,8 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
e_dev_err("Hardware Error: %d\n", err);
}
+ clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
+
/* reprogram the RAR[0] in case user changed it. */
hw->mac.ops.set_rar(hw, 0, hw->mac.addr, adapter->num_vfs,
IXGBE_RAH_AV);
@@ -4121,26 +4184,12 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
struct net_device *netdev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw;
u32 rxctrl;
- u32 txdctl;
int i;
int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
/* signal that we are down to the interrupt handler */
set_bit(__IXGBE_DOWN, &adapter->state);
- /* disable receive for all VFs and wait one second */
- if (adapter->num_vfs) {
- /* ping all the active vfs to let them know we are going down */
- ixgbe_ping_all_vfs(adapter);
-
- /* Disable all VFTE/VFRE TX/RX */
- ixgbe_disable_tx_rx(adapter);
-
- /* Mark all the VFs as inactive */
- for (i = 0 ; i < adapter->num_vfs; i++)
- adapter->vfinfo[i].clear_to_send = 0;
- }
-
/* disable receives */
rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
@@ -4150,15 +4199,11 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
/* this call also flushes the previous write */
ixgbe_disable_rx_queue(adapter, adapter->rx_ring[i]);
- msleep(10);
+ usleep_range(10000, 20000);
netif_tx_stop_all_queues(netdev);
- clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
- del_timer_sync(&adapter->sfp_timer);
- del_timer_sync(&adapter->watchdog_timer);
- cancel_work_sync(&adapter->watchdog_task);
-
+ /* call carrier off first to avoid false dev_watchdog timeouts */
netif_carrier_off(netdev);
netif_tx_disable(netdev);
@@ -4166,6 +4211,25 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_napi_disable_all(adapter);
+ adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT |
+ IXGBE_FLAG2_RESET_REQUESTED);
+ adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
+
+ del_timer_sync(&adapter->service_timer);
+
+ /* disable receive for all VFs and wait one second */
+ if (adapter->num_vfs) {
+ /* ping all the active vfs to let them know we are going down */
+ ixgbe_ping_all_vfs(adapter);
+
+ /* Disable all VFTE/VFRE TX/RX */
+ ixgbe_disable_tx_rx(adapter);
+
+ /* Mark all the VFs as inactive */
+ for (i = 0 ; i < adapter->num_vfs; i++)
+ adapter->vfinfo[i].clear_to_send = 0;
+ }
+
/* Cleanup the affinity_hint CPU mask memory and callback */
for (i = 0; i < num_q_vectors; i++) {
struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
@@ -4175,21 +4239,13 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
free_cpumask_var(q_vector->affinity_mask);
}
- if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
- adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
- cancel_work_sync(&adapter->fdir_reinit_task);
-
- if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
- cancel_work_sync(&adapter->check_overtemp_task);
-
/* disable transmits in the hardware now that interrupts are off */
for (i = 0; i < adapter->num_tx_queues; i++) {
u8 reg_idx = adapter->tx_ring[i]->reg_idx;
- txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
- IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx),
- (txdctl & ~IXGBE_TXDCTL_ENABLE));
+ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH);
}
- /* Disable the Tx DMA engine on 82599 */
+
+ /* Disable the Tx DMA engine on 82599 and X540 */
switch (hw->mac.type) {
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
@@ -4201,9 +4257,6 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
break;
}
- /* clear n-tuple filters that are cached */
- ethtool_ntuple_flush(netdev);
-
if (!pci_channel_offline(adapter->pdev))
ixgbe_reset(adapter);
@@ -4267,25 +4320,8 @@ static void ixgbe_tx_timeout(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- adapter->tx_timeout_count++;
-
/* Do the reset outside of interrupt context */
- schedule_work(&adapter->reset_task);
-}
-
-static void ixgbe_reset_task(struct work_struct *work)
-{
- struct ixgbe_adapter *adapter;
- adapter = container_of(work, struct ixgbe_adapter, reset_task);
-
- /* If we're already down or resetting, just bail */
- if (test_bit(__IXGBE_DOWN, &adapter->state) ||
- test_bit(__IXGBE_RESETTING, &adapter->state))
- return;
-
- ixgbe_dump(adapter);
- netdev_err(adapter->netdev, "Reset adapter\n");
- ixgbe_reinit_locked(adapter);
+ ixgbe_tx_timeout_reset(adapter);
}
/**
@@ -4567,8 +4603,8 @@ static inline bool ixgbe_cache_ring_rss(struct ixgbe_adapter *adapter)
#ifdef CONFIG_IXGBE_DCB
/* ixgbe_get_first_reg_idx - Return first register index associated with ring */
-void ixgbe_get_first_reg_idx(struct ixgbe_adapter *adapter, u8 tc,
- unsigned int *tx, unsigned int *rx)
+static void ixgbe_get_first_reg_idx(struct ixgbe_adapter *adapter, u8 tc,
+ unsigned int *tx, unsigned int *rx)
{
struct net_device *dev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw;
@@ -5133,57 +5169,6 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
}
/**
- * ixgbe_sfp_timer - worker thread to find a missing module
- * @data: pointer to our adapter struct
- **/
-static void ixgbe_sfp_timer(unsigned long data)
-{
- struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
-
- /*
- * Do the sfp_timer outside of interrupt context due to the
- * delays that sfp+ detection requires
- */
- schedule_work(&adapter->sfp_task);
-}
-
-/**
- * ixgbe_sfp_task - worker thread to find a missing module
- * @work: pointer to work_struct containing our data
- **/
-static void ixgbe_sfp_task(struct work_struct *work)
-{
- struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- sfp_task);
- struct ixgbe_hw *hw = &adapter->hw;
-
- if ((hw->phy.type == ixgbe_phy_nl) &&
- (hw->phy.sfp_type == ixgbe_sfp_type_not_present)) {
- s32 ret = hw->phy.ops.identify_sfp(hw);
- if (ret == IXGBE_ERR_SFP_NOT_PRESENT)
- goto reschedule;
- ret = hw->phy.ops.reset(hw);
- if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) {
- e_dev_err("failed to initialize because an unsupported "
- "SFP+ module type was detected.\n");
- e_dev_err("Reload the driver after installing a "
- "supported module.\n");
- unregister_netdev(adapter->netdev);
- } else {
- e_info(probe, "detected SFP+: %d\n", hw->phy.sfp_type);
- }
- /* don't need this routine any more */
- clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
- }
- return;
-reschedule:
- if (test_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state))
- mod_timer(&adapter->sfp_timer,
- round_jiffies(jiffies + (2 * HZ)));
-}
-
-/**
* ixgbe_sw_init - Initialize general software structures (struct ixgbe_adapter)
* @adapter: board private structure to initialize
*
@@ -5899,8 +5884,13 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH);
break;
- case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
+ /* OS2BMC stats are X540 only*/
+ hwstats->o2bgptc += IXGBE_READ_REG(hw, IXGBE_O2BGPTC);
+ hwstats->o2bspc += IXGBE_READ_REG(hw, IXGBE_O2BSPC);
+ hwstats->b2ospc += IXGBE_READ_REG(hw, IXGBE_B2OSPC);
+ hwstats->b2ogprc += IXGBE_READ_REG(hw, IXGBE_B2OGPRC);
+ case ixgbe_mac_82599EB:
hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */
hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
@@ -5974,23 +5964,66 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
}
/**
- * ixgbe_watchdog - Timer Call-back
- * @data: pointer to adapter cast into an unsigned long
+ * ixgbe_fdir_reinit_subtask - worker thread to reinit FDIR filter table
+ * @adapter - pointer to the device adapter structure
**/
-static void ixgbe_watchdog(unsigned long data)
+static void ixgbe_fdir_reinit_subtask(struct ixgbe_adapter *adapter)
{
- struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
struct ixgbe_hw *hw = &adapter->hw;
- u64 eics = 0;
int i;
- /*
- * Do the watchdog outside of interrupt context due to the lovely
- * delays that some of the newer hardware requires
- */
+ if (!(adapter->flags2 & IXGBE_FLAG2_FDIR_REQUIRES_REINIT))
+ return;
+
+ adapter->flags2 &= ~IXGBE_FLAG2_FDIR_REQUIRES_REINIT;
+ /* if interface is down do nothing */
if (test_bit(__IXGBE_DOWN, &adapter->state))
- goto watchdog_short_circuit;
+ return;
+
+ /* do nothing if we are not using signature filters */
+ if (!(adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE))
+ return;
+
+ adapter->fdir_overflow++;
+
+ if (ixgbe_reinit_fdir_tables_82599(hw) == 0) {
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ set_bit(__IXGBE_TX_FDIR_INIT_DONE,
+ &(adapter->tx_ring[i]->state));
+ /* re-enable flow director interrupts */
+ IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_FLOW_DIR);
+ } else {
+ e_err(probe, "failed to finish FDIR re-initialization, "
+ "ignored adding FDIR ATR filters\n");
+ }
+}
+
+/**
+ * ixgbe_check_hang_subtask - check for hung queues and dropped interrupts
+ * @adapter - pointer to the device adapter structure
+ *
+ * This function serves two purposes. First it strobes the interrupt lines
+ * in order to make certain interrupts are occuring. Secondly it sets the
+ * bits needed to check for TX hangs. As a result we should immediately
+ * determine if a hang has occured.
+ */
+static void ixgbe_check_hang_subtask(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u64 eics = 0;
+ int i;
+
+ /* If we're down or resetting, just bail */
+ if (test_bit(__IXGBE_DOWN, &adapter->state) ||
+ test_bit(__IXGBE_RESETTING, &adapter->state))
+ return;
+
+ /* Force detection of hung controller */
+ if (netif_carrier_ok(adapter->netdev)) {
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ set_check_for_tx_hang(adapter->tx_ring[i]);
+ }
if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) {
/*
@@ -6000,108 +6033,172 @@ static void ixgbe_watchdog(unsigned long data)
*/
IXGBE_WRITE_REG(hw, IXGBE_EICS,
(IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
- goto watchdog_reschedule;
- }
-
- /* get one bit for every active tx/rx interrupt vector */
- for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
- struct ixgbe_q_vector *qv = adapter->q_vector[i];
- if (qv->rxr_count || qv->txr_count)
- eics |= ((u64)1 << i);
+ } else {
+ /* get one bit for every active tx/rx interrupt vector */
+ for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
+ struct ixgbe_q_vector *qv = adapter->q_vector[i];
+ if (qv->rxr_count || qv->txr_count)
+ eics |= ((u64)1 << i);
+ }
}
- /* Cause software interrupt to ensure rx rings are cleaned */
+ /* Cause software interrupt to ensure rings are cleaned */
ixgbe_irq_rearm_queues(adapter, eics);
-watchdog_reschedule:
- /* Reset the timer */
- mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
-
-watchdog_short_circuit:
- schedule_work(&adapter->watchdog_task);
}
/**
- * ixgbe_multispeed_fiber_task - worker thread to configure multispeed fiber
- * @work: pointer to work_struct containing our data
+ * ixgbe_watchdog_update_link - update the link status
+ * @adapter - pointer to the device adapter structure
+ * @link_speed - pointer to a u32 to store the link_speed
**/
-static void ixgbe_multispeed_fiber_task(struct work_struct *work)
+static void ixgbe_watchdog_update_link(struct ixgbe_adapter *adapter)
{
- struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- multispeed_fiber_task);
struct ixgbe_hw *hw = &adapter->hw;
- u32 autoneg;
- bool negotiation;
+ u32 link_speed = adapter->link_speed;
+ bool link_up = adapter->link_up;
+ int i;
- adapter->flags |= IXGBE_FLAG_IN_SFP_LINK_TASK;
- autoneg = hw->phy.autoneg_advertised;
- if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
- hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation);
- hw->mac.autotry_restart = false;
- if (hw->mac.ops.setup_link)
- hw->mac.ops.setup_link(hw, autoneg, negotiation, true);
- adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
- adapter->flags &= ~IXGBE_FLAG_IN_SFP_LINK_TASK;
+ if (!(adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE))
+ return;
+
+ if (hw->mac.ops.check_link) {
+ hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
+ } else {
+ /* always assume link is up, if no check link function */
+ link_speed = IXGBE_LINK_SPEED_10GB_FULL;
+ link_up = true;
+ }
+ if (link_up) {
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
+ hw->mac.ops.fc_enable(hw, i);
+ } else {
+ hw->mac.ops.fc_enable(hw, 0);
+ }
+ }
+
+ if (link_up ||
+ time_after(jiffies, (adapter->link_check_timeout +
+ IXGBE_TRY_LINK_TIMEOUT))) {
+ adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
+ IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
+ IXGBE_WRITE_FLUSH(hw);
+ }
+
+ adapter->link_up = link_up;
+ adapter->link_speed = link_speed;
}
/**
- * ixgbe_sfp_config_module_task - worker thread to configure a new SFP+ module
- * @work: pointer to work_struct containing our data
+ * ixgbe_watchdog_link_is_up - update netif_carrier status and
+ * print link up message
+ * @adapter - pointer to the device adapter structure
**/
-static void ixgbe_sfp_config_module_task(struct work_struct *work)
+static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
{
- struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- sfp_config_module_task);
+ struct net_device *netdev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw;
- u32 err;
+ u32 link_speed = adapter->link_speed;
+ bool flow_rx, flow_tx;
- adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK;
+ /* only continue if link was previously down */
+ if (netif_carrier_ok(netdev))
+ return;
- /* Time for electrical oscillations to settle down */
- msleep(100);
- err = hw->phy.ops.identify_sfp(hw);
+ adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
- if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
- e_dev_err("failed to initialize because an unsupported SFP+ "
- "module type was detected.\n");
- e_dev_err("Reload the driver after installing a supported "
- "module.\n");
- unregister_netdev(adapter->netdev);
- return;
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB: {
+ u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
+ flow_rx = !!(frctl & IXGBE_FCTRL_RFCE);
+ flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X);
+ }
+ break;
+ case ixgbe_mac_X540:
+ case ixgbe_mac_82599EB: {
+ u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+ u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
+ flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE);
+ flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X);
+ }
+ break;
+ default:
+ flow_tx = false;
+ flow_rx = false;
+ break;
}
- if (hw->mac.ops.setup_sfp)
- hw->mac.ops.setup_sfp(hw);
+ e_info(drv, "NIC Link is Up %s, Flow Control: %s\n",
+ (link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
+ "10 Gbps" :
+ (link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
+ "1 Gbps" :
+ (link_speed == IXGBE_LINK_SPEED_100_FULL ?
+ "100 Mbps" :
+ "unknown speed"))),
+ ((flow_rx && flow_tx) ? "RX/TX" :
+ (flow_rx ? "RX" :
+ (flow_tx ? "TX" : "None"))));
- if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
- /* This will also work for DA Twinax connections */
- schedule_work(&adapter->multispeed_fiber_task);
- adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK;
+ netif_carrier_on(netdev);
+#ifdef HAVE_IPLINK_VF_CONFIG
+ ixgbe_check_vf_rate_limit(adapter);
+#endif /* HAVE_IPLINK_VF_CONFIG */
}
/**
- * ixgbe_fdir_reinit_task - worker thread to reinit FDIR filter table
- * @work: pointer to work_struct containing our data
+ * ixgbe_watchdog_link_is_down - update netif_carrier status and
+ * print link down message
+ * @adapter - pointer to the adapter structure
**/
-static void ixgbe_fdir_reinit_task(struct work_struct *work)
+static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter* adapter)
{
- struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- fdir_reinit_task);
+ struct net_device *netdev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw;
+
+ adapter->link_up = false;
+ adapter->link_speed = 0;
+
+ /* only continue if link was up previously */
+ if (!netif_carrier_ok(netdev))
+ return;
+
+ /* poll for SFP+ cable when link is down */
+ if (ixgbe_is_sfp(hw) && hw->mac.type == ixgbe_mac_82598EB)
+ adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
+
+ e_info(drv, "NIC Link is Down\n");
+ netif_carrier_off(netdev);
+}
+
+/**
+ * ixgbe_watchdog_flush_tx - flush queues on link down
+ * @adapter - pointer to the device adapter structure
+ **/
+static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter)
+{
int i;
+ int some_tx_pending = 0;
- if (ixgbe_reinit_fdir_tables_82599(hw) == 0) {
- for (i = 0; i < adapter->num_tx_queues; i++)
- set_bit(__IXGBE_TX_FDIR_INIT_DONE,
- &(adapter->tx_ring[i]->state));
- } else {
- e_err(probe, "failed to finish FDIR re-initialization, "
- "ignored adding FDIR ATR filters\n");
+ if (!netif_carrier_ok(adapter->netdev)) {
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ struct ixgbe_ring *tx_ring = adapter->tx_ring[i];
+ if (tx_ring->next_to_use != tx_ring->next_to_clean) {
+ some_tx_pending = 1;
+ break;
+ }
+ }
+
+ if (some_tx_pending) {
+ /* We've lost link, so the controller stops DMA,
+ * but we've got queued Tx work that's never going
+ * to get done, so reset controller to flush Tx.
+ * (Do the reset outside of interrupt context).
+ */
+ adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED;
+ }
}
- /* Done FDIR Re-initialization, enable transmits */
- netif_tx_start_all_queues(adapter->netdev);
}
static void ixgbe_spoof_check(struct ixgbe_adapter *adapter)
@@ -6124,133 +6221,186 @@ static void ixgbe_spoof_check(struct ixgbe_adapter *adapter)
e_warn(drv, "%d Spoofed packets detected\n", ssvpc);
}
-static DEFINE_MUTEX(ixgbe_watchdog_lock);
+/**
+ * ixgbe_watchdog_subtask - check and bring link up
+ * @adapter - pointer to the device adapter structure
+ **/
+static void ixgbe_watchdog_subtask(struct ixgbe_adapter *adapter)
+{
+ /* if interface is down do nothing */
+ if (test_bit(__IXGBE_DOWN, &adapter->state))
+ return;
+
+ ixgbe_watchdog_update_link(adapter);
+
+ if (adapter->link_up)
+ ixgbe_watchdog_link_is_up(adapter);
+ else
+ ixgbe_watchdog_link_is_down(adapter);
+
+ ixgbe_spoof_check(adapter);
+ ixgbe_update_stats(adapter);
+
+ ixgbe_watchdog_flush_tx(adapter);
+}
/**
- * ixgbe_watchdog_task - worker thread to bring link up
- * @work: pointer to work_struct containing our data
+ * ixgbe_sfp_detection_subtask - poll for SFP+ cable
+ * @adapter - the ixgbe adapter structure
**/
-static void ixgbe_watchdog_task(struct work_struct *work)
+static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter)
{
- struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- watchdog_task);
- struct net_device *netdev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw;
- u32 link_speed;
- bool link_up;
- int i;
- struct ixgbe_ring *tx_ring;
- int some_tx_pending = 0;
+ s32 err;
- mutex_lock(&ixgbe_watchdog_lock);
+ /* not searching for SFP so there is nothing to do here */
+ if (!(adapter->flags2 & IXGBE_FLAG2_SEARCH_FOR_SFP) &&
+ !(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET))
+ return;
- link_up = adapter->link_up;
- link_speed = adapter->link_speed;
+ /* someone else is in init, wait until next service event */
+ if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
+ return;
- if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) {
- hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
- if (link_up) {
-#ifdef CONFIG_DCB
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
- hw->mac.ops.fc_enable(hw, i);
- } else {
- hw->mac.ops.fc_enable(hw, 0);
- }
-#else
- hw->mac.ops.fc_enable(hw, 0);
-#endif
- }
+ err = hw->phy.ops.identify_sfp(hw);
+ if (err == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ goto sfp_out;
- if (link_up ||
- time_after(jiffies, (adapter->link_check_timeout +
- IXGBE_TRY_LINK_TIMEOUT))) {
- adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
- IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
- }
- adapter->link_up = link_up;
- adapter->link_speed = link_speed;
+ if (err == IXGBE_ERR_SFP_NOT_PRESENT) {
+ /* If no cable is present, then we need to reset
+ * the next time we find a good cable. */
+ adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
}
- if (link_up) {
- if (!netif_carrier_ok(netdev)) {
- bool flow_rx, flow_tx;
-
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB: {
- u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
- flow_rx = !!(frctl & IXGBE_FCTRL_RFCE);
- flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X);
- }
- break;
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540: {
- u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
- u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
- flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE);
- flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X);
- }
- break;
- default:
- flow_tx = false;
- flow_rx = false;
- break;
- }
+ /* exit on error */
+ if (err)
+ goto sfp_out;
- e_info(drv, "NIC Link is Up %s, Flow Control: %s\n",
- (link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
- "10 Gbps" :
- (link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
- "1 Gbps" :
- (link_speed == IXGBE_LINK_SPEED_100_FULL ?
- "100 Mbps" :
- "unknown speed"))),
- ((flow_rx && flow_tx) ? "RX/TX" :
- (flow_rx ? "RX" :
- (flow_tx ? "TX" : "None"))));
-
- netif_carrier_on(netdev);
- ixgbe_check_vf_rate_limit(adapter);
- } else {
- /* Force detection of hung controller */
- for (i = 0; i < adapter->num_tx_queues; i++) {
- tx_ring = adapter->tx_ring[i];
- set_check_for_tx_hang(tx_ring);
- }
- }
- } else {
- adapter->link_up = false;
- adapter->link_speed = 0;
- if (netif_carrier_ok(netdev)) {
- e_info(drv, "NIC Link is Down\n");
- netif_carrier_off(netdev);
- }
- }
+ /* exit if reset not needed */
+ if (!(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET))
+ goto sfp_out;
- if (!netif_carrier_ok(netdev)) {
- for (i = 0; i < adapter->num_tx_queues; i++) {
- tx_ring = adapter->tx_ring[i];
- if (tx_ring->next_to_use != tx_ring->next_to_clean) {
- some_tx_pending = 1;
- break;
- }
- }
+ adapter->flags2 &= ~IXGBE_FLAG2_SFP_NEEDS_RESET;
- if (some_tx_pending) {
- /* We've lost link, so the controller stops DMA,
- * but we've got queued Tx work that's never going
- * to get done, so reset controller to flush Tx.
- * (Do the reset outside of interrupt context).
- */
- schedule_work(&adapter->reset_task);
- }
+ /*
+ * A module may be identified correctly, but the EEPROM may not have
+ * support for that module. setup_sfp() will fail in that case, so
+ * we should not allow that module to load.
+ */
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ err = hw->phy.ops.reset(hw);
+ else
+ err = hw->mac.ops.setup_sfp(hw);
+
+ if (err == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ goto sfp_out;
+
+ adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
+ e_info(probe, "detected SFP+: %d\n", hw->phy.sfp_type);
+
+sfp_out:
+ clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
+
+ if ((err == IXGBE_ERR_SFP_NOT_SUPPORTED) &&
+ (adapter->netdev->reg_state == NETREG_REGISTERED)) {
+ e_dev_err("failed to initialize because an unsupported "
+ "SFP+ module type was detected.\n");
+ e_dev_err("Reload the driver after installing a "
+ "supported module.\n");
+ unregister_netdev(adapter->netdev);
}
+}
- ixgbe_spoof_check(adapter);
- ixgbe_update_stats(adapter);
- mutex_unlock(&ixgbe_watchdog_lock);
+/**
+ * ixgbe_sfp_link_config_subtask - set up link SFP after module install
+ * @adapter - the ixgbe adapter structure
+ **/
+static void ixgbe_sfp_link_config_subtask(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 autoneg;
+ bool negotiation;
+
+ if (!(adapter->flags & IXGBE_FLAG_NEED_LINK_CONFIG))
+ return;
+
+ /* someone else is in init, wait until next service event */
+ if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
+ return;
+
+ adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
+
+ autoneg = hw->phy.autoneg_advertised;
+ if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
+ hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation);
+ hw->mac.autotry_restart = false;
+ if (hw->mac.ops.setup_link)
+ hw->mac.ops.setup_link(hw, autoneg, negotiation, true);
+
+ adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
+ adapter->link_check_timeout = jiffies;
+ clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
+}
+
+/**
+ * ixgbe_service_timer - Timer Call-back
+ * @data: pointer to adapter cast into an unsigned long
+ **/
+static void ixgbe_service_timer(unsigned long data)
+{
+ struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
+ unsigned long next_event_offset;
+
+ /* poll faster when waiting for link */
+ if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE)
+ next_event_offset = HZ / 10;
+ else
+ next_event_offset = HZ * 2;
+
+ /* Reset the timer */
+ mod_timer(&adapter->service_timer, next_event_offset + jiffies);
+
+ ixgbe_service_event_schedule(adapter);
+}
+
+static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter)
+{
+ if (!(adapter->flags2 & IXGBE_FLAG2_RESET_REQUESTED))
+ return;
+
+ adapter->flags2 &= ~IXGBE_FLAG2_RESET_REQUESTED;
+
+ /* If we're already down or resetting, just bail */
+ if (test_bit(__IXGBE_DOWN, &adapter->state) ||
+ test_bit(__IXGBE_RESETTING, &adapter->state))
+ return;
+
+ ixgbe_dump(adapter);
+ netdev_err(adapter->netdev, "Reset adapter\n");
+ adapter->tx_timeout_count++;
+
+ ixgbe_reinit_locked(adapter);
+}
+
+/**
+ * ixgbe_service_task - manages and runs subtasks
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbe_service_task(struct work_struct *work)
+{
+ struct ixgbe_adapter *adapter = container_of(work,
+ struct ixgbe_adapter,
+ service_task);
+
+ ixgbe_reset_subtask(adapter);
+ ixgbe_sfp_detection_subtask(adapter);
+ ixgbe_sfp_link_config_subtask(adapter);
+ ixgbe_check_overtemp_subtask(adapter);
+ ixgbe_watchdog_subtask(adapter);
+ ixgbe_fdir_reinit_subtask(adapter);
+ ixgbe_check_hang_subtask(adapter);
+
+ ixgbe_service_event_complete(adapter);
}
static int ixgbe_tso(struct ixgbe_adapter *adapter,
@@ -7089,6 +7239,8 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
#ifdef CONFIG_PCI_IOV
struct ixgbe_hw *hw = &adapter->hw;
int err;
+ int num_vf_macvlans, i;
+ struct vf_macvlans *mv_list;
if (hw->mac.type == ixgbe_mac_82598EB || !max_vfs)
return;
@@ -7105,6 +7257,26 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
e_err(probe, "Failed to enable PCI sriov: %d\n", err);
goto err_novfs;
}
+
+ num_vf_macvlans = hw->mac.num_rar_entries -
+ (IXGBE_MAX_PF_MACVLANS + 1 + adapter->num_vfs);
+
+ adapter->mv_list = mv_list = kcalloc(num_vf_macvlans,
+ sizeof(struct vf_macvlans),
+ GFP_KERNEL);
+ if (mv_list) {
+ /* Initialize list of VF macvlans */
+ INIT_LIST_HEAD(&adapter->vf_mvs.l);
+ for (i = 0; i < num_vf_macvlans; i++) {
+ mv_list->vf = -1;
+ mv_list->free = true;
+ mv_list->rar_entry = hw->mac.num_rar_entries -
+ (i + adapter->num_vfs + 1);
+ list_add(&mv_list->l, &adapter->vf_mvs.l);
+ mv_list++;
+ }
+ }
+
/* If call to enable VFs succeeded then allocate memory
* for per VF control structures.
*/
@@ -7275,22 +7447,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
hw->phy.mdio.mdio_read = ixgbe_mdio_read;
hw->phy.mdio.mdio_write = ixgbe_mdio_write;
- /* set up this timer and work struct before calling get_invariants
- * which might start the timer
- */
- init_timer(&adapter->sfp_timer);
- adapter->sfp_timer.function = ixgbe_sfp_timer;
- adapter->sfp_timer.data = (unsigned long) adapter;
-
- INIT_WORK(&adapter->sfp_task, ixgbe_sfp_task);
-
- /* multispeed fiber has its own tasklet, called from GPI SDP1 context */
- INIT_WORK(&adapter->multispeed_fiber_task, ixgbe_multispeed_fiber_task);
-
- /* a new SFP+ module arrival, called from GPI SDP2 context */
- INIT_WORK(&adapter->sfp_config_module_task,
- ixgbe_sfp_config_module_task);
-
ii->get_invariants(hw);
/* setup the private structure */
@@ -7324,17 +7480,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
hw->phy.reset_if_overtemp = false;
if (err == IXGBE_ERR_SFP_NOT_PRESENT &&
hw->mac.type == ixgbe_mac_82598EB) {
- /*
- * Start a kernel thread to watch for a module to arrive.
- * Only do this for 82598, since 82599 will generate
- * interrupts on module arrival.
- */
- set_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
- mod_timer(&adapter->sfp_timer,
- round_jiffies(jiffies + (2 * HZ)));
err = 0;
} else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
- e_dev_err("failed to initialize because an unsupported SFP+ "
+ e_dev_err("failed to load because an unsupported SFP+ "
"module type was detected.\n");
e_dev_err("Reload the driver after installing a supported "
"module.\n");
@@ -7356,9 +7504,16 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6;
netdev->features |= NETIF_F_GRO;
+ netdev->features |= NETIF_F_RXHASH;
- if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
netdev->features |= NETIF_F_SCTP_CSUM;
+ break;
+ default:
+ break;
+ }
netdev->vlan_features |= NETIF_F_TSO;
netdev->vlan_features |= NETIF_F_TSO6;
@@ -7419,17 +7574,19 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
(hw->mac.type == ixgbe_mac_82599EB))))
hw->mac.ops.disable_tx_laser(hw);
- init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = ixgbe_watchdog;
- adapter->watchdog_timer.data = (unsigned long)adapter;
+ setup_timer(&adapter->service_timer, &ixgbe_service_timer,
+ (unsigned long) adapter);
- INIT_WORK(&adapter->reset_task, ixgbe_reset_task);
- INIT_WORK(&adapter->watchdog_task, ixgbe_watchdog_task);
+ INIT_WORK(&adapter->service_task, ixgbe_service_task);
+ clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);
err = ixgbe_init_interrupt_scheme(adapter);
if (err)
goto err_sw_init;
+ if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED))
+ netdev->features &= ~NETIF_F_RXHASH;
+
switch (pdev->device) {
case IXGBE_DEV_ID_82599_SFP:
/* Only this subdevice supports WOL */
@@ -7458,8 +7615,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
/* print bus type/speed/width info */
e_dev_info("(PCI Express:%s:%s) %pM\n",
- (hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0Gb/s" :
- hw->bus.speed == ixgbe_bus_speed_2500 ? "2.5Gb/s" :
+ (hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0GT/s" :
+ hw->bus.speed == ixgbe_bus_speed_2500 ? "2.5GT/s" :
"Unknown"),
(hw->bus.width == ixgbe_bus_width_pcie_x8 ? "Width x8" :
hw->bus.width == ixgbe_bus_width_pcie_x4 ? "Width x4" :
@@ -7508,13 +7665,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
/* carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev);
- if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
- adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
- INIT_WORK(&adapter->fdir_reinit_task, ixgbe_fdir_reinit_task);
-
- if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
- INIT_WORK(&adapter->check_overtemp_task,
- ixgbe_check_overtemp_task);
#ifdef CONFIG_IXGBE_DCA
if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
@@ -7541,11 +7691,7 @@ err_sw_init:
err_eeprom:
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
ixgbe_disable_sriov(adapter);
- clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
- del_timer_sync(&adapter->sfp_timer);
- cancel_work_sync(&adapter->sfp_task);
- cancel_work_sync(&adapter->multispeed_fiber_task);
- cancel_work_sync(&adapter->sfp_config_module_task);
+ adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
iounmap(hw->hw_addr);
err_ioremap:
free_netdev(netdev);
@@ -7573,24 +7719,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
struct net_device *netdev = adapter->netdev;
set_bit(__IXGBE_DOWN, &adapter->state);
-
- /*
- * The timers may be rescheduled, so explicitly disable them
- * from being rescheduled.
- */
- clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
- del_timer_sync(&adapter->watchdog_timer);
- del_timer_sync(&adapter->sfp_timer);
-
- cancel_work_sync(&adapter->watchdog_task);
- cancel_work_sync(&adapter->sfp_task);
- cancel_work_sync(&adapter->multispeed_fiber_task);
- cancel_work_sync(&adapter->sfp_config_module_task);
- if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
- adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
- cancel_work_sync(&adapter->fdir_reinit_task);
- if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
- cancel_work_sync(&adapter->check_overtemp_task);
+ cancel_work_sync(&adapter->service_task);
#ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
diff --git a/drivers/net/ixgbe/ixgbe_mbx.h b/drivers/net/ixgbe/ixgbe_mbx.h
index fe6ea81dc7f..b239bdac38d 100644
--- a/drivers/net/ixgbe/ixgbe_mbx.h
+++ b/drivers/net/ixgbe/ixgbe_mbx.h
@@ -36,9 +36,6 @@
#define IXGBE_VFMAILBOX 0x002FC
#define IXGBE_VFMBMEM 0x00200
-#define IXGBE_PFMAILBOX(x) (0x04B00 + (4 * x))
-#define IXGBE_PFMBMEM(vfn) (0x13000 + (64 * vfn))
-
#define IXGBE_PFMAILBOX_STS 0x00000001 /* Initiate message send to VF */
#define IXGBE_PFMAILBOX_ACK 0x00000002 /* Ack message recv'd from VF */
#define IXGBE_PFMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */
@@ -70,6 +67,7 @@
#define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
#define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */
#define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */
+#define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */
/* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index df5b8aa4795..735f686c3b3 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -449,7 +449,8 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
MDIO_MMD_AN,
&autoneg_reg);
- autoneg_reg &= ~ADVERTISE_100FULL;
+ autoneg_reg &= ~(ADVERTISE_100FULL |
+ ADVERTISE_100HALF);
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
autoneg_reg |= ADVERTISE_100FULL;
@@ -656,7 +657,8 @@ s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw)
MDIO_MMD_AN,
&autoneg_reg);
- autoneg_reg &= ~ADVERTISE_100FULL;
+ autoneg_reg &= ~(ADVERTISE_100FULL |
+ ADVERTISE_100HALF);
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
autoneg_reg |= ADVERTISE_100FULL;
@@ -753,7 +755,7 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
&phy_data);
if ((phy_data & MDIO_CTRL1_RESET) == 0)
break;
- msleep(10);
+ usleep_range(10000, 20000);
}
if ((phy_data & MDIO_CTRL1_RESET) != 0) {
@@ -782,7 +784,7 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
case IXGBE_DELAY_NL:
data_offset++;
hw_dbg(hw, "DELAY: %d MS\n", edata);
- msleep(edata);
+ usleep_range(edata * 1000, edata * 2000);
break;
case IXGBE_DATA_NL:
hw_dbg(hw, "DATA:\n");
@@ -1220,7 +1222,7 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
swfw_mask = IXGBE_GSSR_PHY0_SM;
do {
- if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != 0) {
+ if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != 0) {
status = IXGBE_ERR_SWFW_SYNC;
goto read_byte_out;
}
@@ -1267,7 +1269,7 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
break;
fail:
- ixgbe_release_swfw_sync(hw, swfw_mask);
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
msleep(100);
ixgbe_i2c_bus_clear(hw);
retry++;
@@ -1278,7 +1280,7 @@ fail:
} while (retry < max_retry);
- ixgbe_release_swfw_sync(hw, swfw_mask);
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
read_byte_out:
return status;
@@ -1306,7 +1308,7 @@ s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
else
swfw_mask = IXGBE_GSSR_PHY0_SM;
- if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != 0) {
+ if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != 0) {
status = IXGBE_ERR_SWFW_SYNC;
goto write_byte_out;
}
@@ -1350,7 +1352,7 @@ fail:
hw_dbg(hw, "I2C byte write error.\n");
} while (retry < max_retry);
- ixgbe_release_swfw_sync(hw, swfw_mask);
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
write_byte_out:
return status;
diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c
index 6e50d832894..ac99b0458fe 100644
--- a/drivers/net/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ixgbe/ixgbe_sriov.c
@@ -82,6 +82,21 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
return 0;
}
+static void ixgbe_restore_vf_macvlans(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct list_head *pos;
+ struct vf_macvlans *entry;
+
+ list_for_each(pos, &adapter->vf_mvs.l) {
+ entry = list_entry(pos, struct vf_macvlans, l);
+ if (entry->free == false)
+ hw->mac.ops.set_rar(hw, entry->rar_entry,
+ entry->vf_macvlan,
+ entry->vf, IXGBE_RAH_AV);
+ }
+}
+
void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
@@ -102,6 +117,9 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
}
}
+
+ /* Restore any VF macvlans */
+ ixgbe_restore_vf_macvlans(adapter);
}
static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
@@ -110,7 +128,7 @@ static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add);
}
-void ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf)
+static void ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf)
{
struct ixgbe_hw *hw = &adapter->hw;
int new_mtu = msgbuf[1];
@@ -200,6 +218,61 @@ static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
return 0;
}
+static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
+ int vf, int index, unsigned char *mac_addr)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct list_head *pos;
+ struct vf_macvlans *entry;
+
+ if (index <= 1) {
+ list_for_each(pos, &adapter->vf_mvs.l) {
+ entry = list_entry(pos, struct vf_macvlans, l);
+ if (entry->vf == vf) {
+ entry->vf = -1;
+ entry->free = true;
+ entry->is_macvlan = false;
+ hw->mac.ops.clear_rar(hw, entry->rar_entry);
+ }
+ }
+ }
+
+ /*
+ * If index was zero then we were asked to clear the uc list
+ * for the VF. We're done.
+ */
+ if (!index)
+ return 0;
+
+ entry = NULL;
+
+ list_for_each(pos, &adapter->vf_mvs.l) {
+ entry = list_entry(pos, struct vf_macvlans, l);
+ if (entry->free)
+ break;
+ }
+
+ /*
+ * If we traversed the entire list and didn't find a free entry
+ * then we're out of space on the RAR table. Also entry may
+ * be NULL because the original memory allocation for the list
+ * failed, which is not fatal but does mean we can't support
+ * VF requests for MACVLAN because we couldn't allocate
+ * memory for the list management required.
+ */
+ if (!entry || !entry->free)
+ return -ENOSPC;
+
+ entry->free = false;
+ entry->is_macvlan = true;
+ entry->vf = vf;
+ memcpy(entry->vf_macvlan, mac_addr, ETH_ALEN);
+
+ hw->mac.ops.set_rar(hw, entry->rar_entry, mac_addr, vf, IXGBE_RAH_AV);
+
+ return 0;
+}
+
int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
{
unsigned char vf_mac_addr[6];
@@ -251,12 +324,12 @@ static inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
{
u32 mbx_size = IXGBE_VFMAILBOX_SIZE;
- u32 msgbuf[mbx_size];
+ u32 msgbuf[IXGBE_VFMAILBOX_SIZE];
struct ixgbe_hw *hw = &adapter->hw;
s32 retval;
int entries;
u16 *hash_list;
- int add, vid;
+ int add, vid, index;
u8 *new_mac;
retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
@@ -345,6 +418,24 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
retval = ixgbe_set_vf_vlan(adapter, add, vid, vf);
}
break;
+ case IXGBE_VF_SET_MACVLAN:
+ index = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >>
+ IXGBE_VT_MSGINFO_SHIFT;
+ /*
+ * If the VF is allowed to set MAC filters then turn off
+ * anti-spoofing to avoid false positives. An index
+ * greater than 0 will indicate the VF is setting a
+ * macvlan MAC filter.
+ */
+ if (index > 0 && adapter->antispoofing_enabled) {
+ hw->mac.ops.set_mac_anti_spoofing(hw, false,
+ adapter->num_vfs);
+ hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf);
+ adapter->antispoofing_enabled = false;
+ }
+ retval = ixgbe_set_vf_macvlan(adapter, vf, index,
+ (unsigned char *)(&msgbuf[1]));
+ break;
default:
e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]);
retval = IXGBE_ERR_MBX;
@@ -452,7 +543,8 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
goto out;
ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf);
ixgbe_set_vmolr(hw, vf, false);
- hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
+ if (adapter->antispoofing_enabled)
+ hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
adapter->vfinfo[vf].pf_vlan = vlan;
adapter->vfinfo[vf].pf_qos = qos;
dev_info(&adapter->pdev->dev,
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 25c1fb7eda0..fa43f2507f4 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -58,9 +58,11 @@
#define IXGBE_DEV_ID_82599_SFP_FCOE 0x1529
#define IXGBE_SUBDEV_ID_82599_SFP 0x11A9
#define IXGBE_DEV_ID_82599_SFP_EM 0x1507
+#define IXGBE_DEV_ID_82599_SFP_SF2 0x154D
#define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC
#define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8
#define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C
+#define IXGBE_DEV_ID_82599_LS 0x154F
#define IXGBE_DEV_ID_X540T 0x1528
/* General Registers */
@@ -163,6 +165,9 @@
(0x0D018 + ((_i - 64) * 0x40)))
#define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : \
(0x0D028 + ((_i - 64) * 0x40)))
+#define IXGBE_RSCCTL(_i) (((_i) < 64) ? (0x0102C + ((_i) * 0x40)) : \
+ (0x0D02C + ((_i - 64) * 0x40)))
+#define IXGBE_RSCDBU 0x03028
#define IXGBE_RDDCC 0x02F20
#define IXGBE_RXMEMWRAP 0x03190
#define IXGBE_STARCTRL 0x03024
@@ -227,17 +232,23 @@
#define IXGBE_VLVF(_i) (0x0F100 + ((_i) * 4)) /* 64 of these (0-63) */
#define IXGBE_VLVFB(_i) (0x0F200 + ((_i) * 4)) /* 128 of these (0-127) */
#define IXGBE_VMVIR(_i) (0x08000 + ((_i) * 4)) /* 64 of these (0-63) */
-#define IXGBE_VT_CTL 0x051B0
-#define IXGBE_VFRE(_i) (0x051E0 + ((_i) * 4))
-#define IXGBE_VFTE(_i) (0x08110 + ((_i) * 4))
-#define IXGBE_VMECM(_i) (0x08790 + ((_i) * 4))
-#define IXGBE_QDE 0x2F04
-#define IXGBE_VMOLR(_i) (0x0F000 + ((_i) * 4)) /* 64 total */
-#define IXGBE_UTA(_i) (0x0F400 + ((_i) * 4))
-#define IXGBE_VMRCTL(_i) (0x0F600 + ((_i) * 4))
-#define IXGBE_VMRVLAN(_i) (0x0F610 + ((_i) * 4))
-#define IXGBE_VMRVM(_i) (0x0F630 + ((_i) * 4))
-#define IXGBE_L34T_IMIR(_i) (0x0E800 + ((_i) * 4)) /*128 of these (0-127)*/
+#define IXGBE_VT_CTL 0x051B0
+#define IXGBE_PFMAILBOX(_i) (0x04B00 + (4 * (_i))) /* 64 total */
+#define IXGBE_PFMBMEM(_i) (0x13000 + (64 * (_i))) /* 64 Mailboxes, 16 DW each */
+#define IXGBE_PFMBICR(_i) (0x00710 + (4 * (_i))) /* 4 total */
+#define IXGBE_PFMBIMR(_i) (0x00720 + (4 * (_i))) /* 4 total */
+#define IXGBE_VFRE(_i) (0x051E0 + ((_i) * 4))
+#define IXGBE_VFTE(_i) (0x08110 + ((_i) * 4))
+#define IXGBE_VMECM(_i) (0x08790 + ((_i) * 4))
+#define IXGBE_QDE 0x2F04
+#define IXGBE_VMTXSW(_i) (0x05180 + ((_i) * 4)) /* 2 total */
+#define IXGBE_VMOLR(_i) (0x0F000 + ((_i) * 4)) /* 64 total */
+#define IXGBE_UTA(_i) (0x0F400 + ((_i) * 4))
+#define IXGBE_MRCTL(_i) (0x0F600 + ((_i) * 4))
+#define IXGBE_VMRVLAN(_i) (0x0F610 + ((_i) * 4))
+#define IXGBE_VMRVM(_i) (0x0F630 + ((_i) * 4))
+#define IXGBE_L34T_IMIR(_i) (0x0E800 + ((_i) * 4)) /*128 of these (0-127)*/
+#define IXGBE_RXFECCERR0 0x051B8
#define IXGBE_LLITHRESH 0x0EC90
#define IXGBE_IMIR(_i) (0x05A80 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* 8 of these (0-7) */
@@ -364,7 +375,7 @@
#define IXGBE_WUFC_FLX5 0x00200000 /* Flexible Filter 5 Enable */
#define IXGBE_WUFC_FLX_FILTERS 0x000F0000 /* Mask for 4 flex filters */
#define IXGBE_WUFC_EXT_FLX_FILTERS 0x00300000 /* Mask for Ext. flex filters */
-#define IXGBE_WUFC_ALL_FILTERS 0x003F00FF /* Mask for all 6 wakeup filters*/
+#define IXGBE_WUFC_ALL_FILTERS 0x003F00FF /* Mask for all wakeup filters */
#define IXGBE_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */
/* Wake Up Status */
@@ -406,7 +417,6 @@
#define IXGBE_SECTXSTAT 0x08804
#define IXGBE_SECTXBUFFAF 0x08808
#define IXGBE_SECTXMINIFG 0x08810
-#define IXGBE_SECTXSTAT 0x08804
#define IXGBE_SECRXCTRL 0x08D00
#define IXGBE_SECRXSTAT 0x08D04
@@ -499,21 +509,6 @@
#define IXGBE_SECTXCTRL_STORE_FORWARD_ENABLE 0x4
-/* HW RSC registers */
-#define IXGBE_RSCCTL(_i) (((_i) < 64) ? (0x0102C + ((_i) * 0x40)) : \
- (0x0D02C + ((_i - 64) * 0x40)))
-#define IXGBE_RSCDBU 0x03028
-#define IXGBE_RSCCTL_RSCEN 0x01
-#define IXGBE_RSCCTL_MAXDESC_1 0x00
-#define IXGBE_RSCCTL_MAXDESC_4 0x04
-#define IXGBE_RSCCTL_MAXDESC_8 0x08
-#define IXGBE_RSCCTL_MAXDESC_16 0x0C
-#define IXGBE_RXDADV_RSCCNT_SHIFT 17
-#define IXGBE_GPIE_RSC_DELAY_SHIFT 11
-#define IXGBE_RXDADV_RSCCNT_MASK 0x001E0000
-#define IXGBE_RSCDBU_RSCACKDIS 0x00000080
-#define IXGBE_RDRXCTL_RSCFRSTSIZE 0x003E0000
-
/* DCB registers */
#define IXGBE_RTRPCS 0x02430
#define IXGBE_RTTDCS 0x04900
@@ -522,6 +517,7 @@
#define IXGBE_RTRUP2TC 0x03020
#define IXGBE_RTTUP2TC 0x0C800
#define IXGBE_RTRPT4C(_i) (0x02140 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_TXLLQ(_i) (0x082E0 + ((_i) * 4)) /* 4 of these (0-3) */
#define IXGBE_RTRPT4S(_i) (0x02160 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_RTTDT2C(_i) (0x04910 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_RTTDT2S(_i) (0x04930 + ((_i) * 4)) /* 8 of these (0-7) */
@@ -540,7 +536,7 @@
(IXGBE_RTTBCNRC_RF_DEC_MASK << IXGBE_RTTBCNRC_RF_INT_SHIFT)
-/* FCoE registers */
+/* FCoE DMA Context Registers */
#define IXGBE_FCPTRL 0x02410 /* FC User Desc. PTR Low */
#define IXGBE_FCPTRH 0x02414 /* FC USer Desc. PTR High */
#define IXGBE_FCBUFF 0x02418 /* FC Buffer Control */
@@ -677,6 +673,10 @@
#define IXGBE_FCOEDWRC 0x0242C /* Number of FCoE DWords Received */
#define IXGBE_FCOEPTC 0x08784 /* Number of FCoE Packets Transmitted */
#define IXGBE_FCOEDWTC 0x08788 /* Number of FCoE DWords Transmitted */
+#define IXGBE_O2BGPTC 0x041C4
+#define IXGBE_O2BSPC 0x087B0
+#define IXGBE_B2OSPC 0x041C0
+#define IXGBE_B2OGPRC 0x02F90
#define IXGBE_PCRC8ECL 0x0E810
#define IXGBE_PCRC8ECH 0x0E811
#define IXGBE_PCRC8ECH_MASK 0x1F
@@ -742,17 +742,10 @@
#define IXGBE_PBACLR_82599 0x11068
#define IXGBE_CIAA_82599 0x11088
#define IXGBE_CIAD_82599 0x1108C
-#define IXGBE_PCIE_DIAG_0_82599 0x11090
-#define IXGBE_PCIE_DIAG_1_82599 0x11094
-#define IXGBE_PCIE_DIAG_2_82599 0x11098
-#define IXGBE_PCIE_DIAG_3_82599 0x1109C
-#define IXGBE_PCIE_DIAG_4_82599 0x110A0
-#define IXGBE_PCIE_DIAG_5_82599 0x110A4
-#define IXGBE_PCIE_DIAG_6_82599 0x110A8
-#define IXGBE_PCIE_DIAG_7_82599 0x110C0
-#define IXGBE_INTRPT_CSR_82599 0x110B0
-#define IXGBE_INTRPT_MASK_82599 0x110B8
+#define IXGBE_PICAUSE 0x110B0
+#define IXGBE_PIENA 0x110B8
#define IXGBE_CDQ_MBR_82599 0x110B4
+#define IXGBE_PCIESPARE 0x110BC
#define IXGBE_MISC_REG_82599 0x110F0
#define IXGBE_ECC_CTRL_0_82599 0x11100
#define IXGBE_ECC_CTRL_1_82599 0x11104
@@ -785,7 +778,19 @@
#define IXGBE_SYSTIML 0x08C0C /* System time register Low - RO */
#define IXGBE_SYSTIMH 0x08C10 /* System time register High - RO */
#define IXGBE_TIMINCA 0x08C14 /* Increment attributes register - RW */
-#define IXGBE_RXUDP 0x08C1C /* Time Sync Rx UDP Port - RW */
+#define IXGBE_TIMADJL 0x08C18 /* Time Adjustment Offset register Low - RW */
+#define IXGBE_TIMADJH 0x08C1C /* Time Adjustment Offset register High - RW */
+#define IXGBE_TSAUXC 0x08C20 /* TimeSync Auxiliary Control register - RW */
+#define IXGBE_TRGTTIML0 0x08C24 /* Target Time Register 0 Low - RW */
+#define IXGBE_TRGTTIMH0 0x08C28 /* Target Time Register 0 High - RW */
+#define IXGBE_TRGTTIML1 0x08C2C /* Target Time Register 1 Low - RW */
+#define IXGBE_TRGTTIMH1 0x08C30 /* Target Time Register 1 High - RW */
+#define IXGBE_FREQOUT0 0x08C34 /* Frequency Out 0 Control register - RW */
+#define IXGBE_FREQOUT1 0x08C38 /* Frequency Out 1 Control register - RW */
+#define IXGBE_AUXSTMPL0 0x08C3C /* Auxiliary Time Stamp 0 register Low - RO */
+#define IXGBE_AUXSTMPH0 0x08C40 /* Auxiliary Time Stamp 0 register High - RO */
+#define IXGBE_AUXSTMPL1 0x08C44 /* Auxiliary Time Stamp 1 register Low - RO */
+#define IXGBE_AUXSTMPH1 0x08C48 /* Auxiliary Time Stamp 1 register High - RO */
/* Diagnostic Registers */
#define IXGBE_RDSTATCTL 0x02C20
@@ -829,8 +834,20 @@
#define IXGBE_TXDATARDPTR(_i) (0x0C720 + ((_i) * 4)) /* 8 of these C720-C72C*/
#define IXGBE_TXDESCRDPTR(_i) (0x0C730 + ((_i) * 4)) /* 8 of these C730-C73C*/
#define IXGBE_PCIEECCCTL 0x1106C
+#define IXGBE_RXWRPTR(_i) (0x03100 + ((_i) * 4)) /* 8 of these 3100-310C*/
+#define IXGBE_RXUSED(_i) (0x03120 + ((_i) * 4)) /* 8 of these 3120-312C*/
+#define IXGBE_RXRDPTR(_i) (0x03140 + ((_i) * 4)) /* 8 of these 3140-314C*/
+#define IXGBE_RXRDWRPTR(_i) (0x03160 + ((_i) * 4)) /* 8 of these 3160-310C*/
+#define IXGBE_TXWRPTR(_i) (0x0C100 + ((_i) * 4)) /* 8 of these C100-C10C*/
+#define IXGBE_TXUSED(_i) (0x0C120 + ((_i) * 4)) /* 8 of these C120-C12C*/
+#define IXGBE_TXRDPTR(_i) (0x0C140 + ((_i) * 4)) /* 8 of these C140-C14C*/
+#define IXGBE_TXRDWRPTR(_i) (0x0C160 + ((_i) * 4)) /* 8 of these C160-C10C*/
#define IXGBE_PCIEECCCTL0 0x11100
#define IXGBE_PCIEECCCTL1 0x11104
+#define IXGBE_RXDBUECC 0x03F70
+#define IXGBE_TXDBUECC 0x0CF70
+#define IXGBE_RXDBUEST 0x03F74
+#define IXGBE_TXDBUEST 0x0CF74
#define IXGBE_PBTXECC 0x0C300
#define IXGBE_PBRXECC 0x03300
#define IXGBE_GHECCR 0x110B0
@@ -871,6 +888,7 @@
#define IXGBE_AUTOC3 0x042AC
#define IXGBE_ANLP1 0x042B0
#define IXGBE_ANLP2 0x042B4
+#define IXGBE_MACC 0x04330
#define IXGBE_ATLASCTL 0x04800
#define IXGBE_MMNGC 0x042D0
#define IXGBE_ANLPNP1 0x042D4
@@ -883,14 +901,49 @@
#define IXGBE_MPVC 0x04318
#define IXGBE_SGMIIC 0x04314
+/* Statistics Registers */
+#define IXGBE_RXNFGPC 0x041B0
+#define IXGBE_RXNFGBCL 0x041B4
+#define IXGBE_RXNFGBCH 0x041B8
+#define IXGBE_RXDGPC 0x02F50
+#define IXGBE_RXDGBCL 0x02F54
+#define IXGBE_RXDGBCH 0x02F58
+#define IXGBE_RXDDGPC 0x02F5C
+#define IXGBE_RXDDGBCL 0x02F60
+#define IXGBE_RXDDGBCH 0x02F64
+#define IXGBE_RXLPBKGPC 0x02F68
+#define IXGBE_RXLPBKGBCL 0x02F6C
+#define IXGBE_RXLPBKGBCH 0x02F70
+#define IXGBE_RXDLPBKGPC 0x02F74
+#define IXGBE_RXDLPBKGBCL 0x02F78
+#define IXGBE_RXDLPBKGBCH 0x02F7C
+#define IXGBE_TXDGPC 0x087A0
+#define IXGBE_TXDGBCL 0x087A4
+#define IXGBE_TXDGBCH 0x087A8
+
+#define IXGBE_RXDSTATCTRL 0x02F40
+
+/* Copper Pond 2 link timeout */
#define IXGBE_VALIDATE_LINK_READY_TIMEOUT 50
/* Omer CORECTL */
#define IXGBE_CORECTL 0x014F00
/* BARCTRL */
-#define IXGBE_BARCTRL 0x110F4
-#define IXGBE_BARCTRL_FLSIZE 0x0700
-#define IXGBE_BARCTRL_CSRSIZE 0x2000
+#define IXGBE_BARCTRL 0x110F4
+#define IXGBE_BARCTRL_FLSIZE 0x0700
+#define IXGBE_BARCTRL_FLSIZE_SHIFT 8
+#define IXGBE_BARCTRL_CSRSIZE 0x2000
+
+/* RSCCTL Bit Masks */
+#define IXGBE_RSCCTL_RSCEN 0x01
+#define IXGBE_RSCCTL_MAXDESC_1 0x00
+#define IXGBE_RSCCTL_MAXDESC_4 0x04
+#define IXGBE_RSCCTL_MAXDESC_8 0x08
+#define IXGBE_RSCCTL_MAXDESC_16 0x0C
+
+/* RSCDBU Bit Masks */
+#define IXGBE_RSCDBU_RSCSMALDIS_MASK 0x0000007F
+#define IXGBE_RSCDBU_RSCACKDIS 0x00000080
/* RDRXCTL Bit Masks */
#define IXGBE_RDRXCTL_RDMTS_1_2 0x00000000 /* Rx Desc Min Threshold Size */
@@ -898,6 +951,8 @@
#define IXGBE_RDRXCTL_MVMEN 0x00000020
#define IXGBE_RDRXCTL_DMAIDONE 0x00000008 /* DMA init cycle done */
#define IXGBE_RDRXCTL_AGGDIS 0x00010000 /* Aggregation disable */
+#define IXGBE_RDRXCTL_RSCFRSTSIZE 0x003E0000 /* RSC First packet size */
+#define IXGBE_RDRXCTL_RSCLLIDIS 0x00800000 /* Disable RSC compl on LLI */
#define IXGBE_RDRXCTL_RSCACKC 0x02000000 /* must set 1 when RSC enabled */
#define IXGBE_RDRXCTL_FCOE_WRFIX 0x04000000 /* must set 1 when RSC enabled */
@@ -969,8 +1024,8 @@
#define IXGBE_MSCA_OP_CODE_SHIFT 26 /* OP CODE shift */
#define IXGBE_MSCA_ADDR_CYCLE 0x00000000 /* OP CODE 00 (addr cycle) */
#define IXGBE_MSCA_WRITE 0x04000000 /* OP CODE 01 (write) */
-#define IXGBE_MSCA_READ 0x08000000 /* OP CODE 10 (read) */
-#define IXGBE_MSCA_READ_AUTOINC 0x0C000000 /* OP CODE 11 (read, auto inc)*/
+#define IXGBE_MSCA_READ 0x0C000000 /* OP CODE 11 (read) */
+#define IXGBE_MSCA_READ_AUTOINC 0x08000000 /* OP CODE 10 (read, auto inc)*/
#define IXGBE_MSCA_ST_CODE_MASK 0x30000000 /* ST Code mask */
#define IXGBE_MSCA_ST_CODE_SHIFT 28 /* ST Code shift */
#define IXGBE_MSCA_NEW_PROTOCOL 0x00000000 /* ST CODE 00 (new protocol) */
@@ -1057,6 +1112,7 @@
#define IXGBE_GPIE_EIMEN 0x00000040 /* Immediate Interrupt Enable */
#define IXGBE_GPIE_EIAME 0x40000000
#define IXGBE_GPIE_PBA_SUPPORT 0x80000000
+#define IXGBE_GPIE_RSC_DELAY_SHIFT 11
#define IXGBE_GPIE_VTMODE_MASK 0x0000C000 /* VT Mode Mask */
#define IXGBE_GPIE_VTMODE_16 0x00004000 /* 16 VFs 8 queues per VF */
#define IXGBE_GPIE_VTMODE_32 0x00008000 /* 32 VFs 4 queues per VF */
@@ -1291,6 +1347,11 @@
#define IXGBE_FTQF_POOL_SHIFT 8
#define IXGBE_FTQF_5TUPLE_MASK_MASK 0x0000001F
#define IXGBE_FTQF_5TUPLE_MASK_SHIFT 25
+#define IXGBE_FTQF_SOURCE_ADDR_MASK 0x1E
+#define IXGBE_FTQF_DEST_ADDR_MASK 0x1D
+#define IXGBE_FTQF_SOURCE_PORT_MASK 0x1B
+#define IXGBE_FTQF_DEST_PORT_MASK 0x17
+#define IXGBE_FTQF_PROTOCOL_COMP_MASK 0x0F
#define IXGBE_FTQF_POOL_MASK_EN 0x40000000
#define IXGBE_FTQF_QUEUE_ENABLE 0x80000000
@@ -1333,11 +1394,11 @@
*
* Current filters:
* EAPOL 802.1x (0x888e): Filter 0
- * BCN (0x8904): Filter 1
+ * FCoE (0x8906): Filter 2
* 1588 (0x88f7): Filter 3
+ * FIP (0x8914): Filter 4
*/
#define IXGBE_ETQF_FILTER_EAPOL 0
-#define IXGBE_ETQF_FILTER_BCN 1
#define IXGBE_ETQF_FILTER_FCOE 2
#define IXGBE_ETQF_FILTER_1588 3
#define IXGBE_ETQF_FILTER_FIP 4
@@ -1448,6 +1509,11 @@
#define IXGBE_AUTOC2_10G_XFI (0x1 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
#define IXGBE_AUTOC2_10G_SFI (0x2 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
+#define IXGBE_MACC_FLU 0x00000001
+#define IXGBE_MACC_FSV_10G 0x00030000
+#define IXGBE_MACC_FS 0x00040000
+#define IXGBE_MAC_RX2TX_LPBK 0x00000002
+
/* LINKS Bit Masks */
#define IXGBE_LINKS_KX_AN_COMP 0x80000000
#define IXGBE_LINKS_UP 0x40000000
@@ -1501,7 +1567,6 @@
#define IXGBE_ANLP1_ASM_PAUSE 0x0800
#define IXGBE_ANLP1_AN_STATE_MASK 0x000f0000
-
/* SW Semaphore Register bitmasks */
#define IXGBE_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
#define IXGBE_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
@@ -1514,6 +1579,10 @@
#define IXGBE_GSSR_PHY1_SM 0x0004
#define IXGBE_GSSR_MAC_CSR_SM 0x0008
#define IXGBE_GSSR_FLASH_SM 0x0010
+#define IXGBE_GSSR_SW_MNG_SM 0x0400
+
+/* FW Status register bitmask */
+#define IXGBE_FWSTS_FWRI 0x00000200 /* Firmware Reset Indication */
/* EEC Register */
#define IXGBE_EEC_SK 0x00000001 /* EEPROM Clock */
@@ -1534,6 +1603,7 @@
/* EEPROM Addressing bits based on type (0-small, 1-large) */
#define IXGBE_EEC_ADDR_SIZE 0x00000400
#define IXGBE_EEC_SIZE 0x00007800 /* EEPROM Size */
+#define IXGBE_EERD_MAX_ADDR 0x00003FFF /* EERD alows 14 bits for addr. */
#define IXGBE_EEC_SIZE_SHIFT 11
#define IXGBE_EEPROM_WORD_SIZE_SHIFT 6
@@ -1563,8 +1633,10 @@
#define IXGBE_FW_PTR 0x0F
#define IXGBE_PBANUM0_PTR 0x15
#define IXGBE_PBANUM1_PTR 0x16
-#define IXGBE_DEVICE_CAPS 0x2C
+#define IXGBE_FREE_SPACE_PTR 0X3E
#define IXGBE_SAN_MAC_ADDR_PTR 0x28
+#define IXGBE_DEVICE_CAPS 0x2C
+#define IXGBE_SERIAL_NUMBER_MAC_ADDR 0x11
#define IXGBE_PCIE_MSIX_82599_CAPS 0x72
#define IXGBE_PCIE_MSIX_82598_CAPS 0x62
@@ -1601,6 +1673,10 @@
#define IXGBE_ETH_LENGTH_OF_ADDRESS 6
+#define IXGBE_EEPROM_PAGE_SIZE_MAX 128
+#define IXGBE_EEPROM_RD_BUFFER_MAX_COUNT 512 /* EEPROM words # read in burst */
+#define IXGBE_EEPROM_WR_BUFFER_MAX_COUNT 256 /* EEPROM words # wr in burst */
+
#ifndef IXGBE_EEPROM_GRANT_ATTEMPTS
#define IXGBE_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
#endif
@@ -1616,14 +1692,25 @@
#define IXGBE_FLUDONE_ATTEMPTS 20000
#endif
+#define IXGBE_PCIE_CTRL2 0x5 /* PCIe Control 2 Offset */
+#define IXGBE_PCIE_CTRL2_DUMMY_ENABLE 0x8 /* Dummy Function Enable */
+#define IXGBE_PCIE_CTRL2_LAN_DISABLE 0x2 /* LAN PCI Disable */
+#define IXGBE_PCIE_CTRL2_DISABLE_SELECT 0x1 /* LAN Disable Select */
+
#define IXGBE_SAN_MAC_ADDR_PORT0_OFFSET 0x0
#define IXGBE_SAN_MAC_ADDR_PORT1_OFFSET 0x3
#define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1
#define IXGBE_DEVICE_CAPS_FCOE_OFFLOADS 0x2
+#define IXGBE_FW_LESM_PARAMETERS_PTR 0x2
+#define IXGBE_FW_LESM_STATE_1 0x1
+#define IXGBE_FW_LESM_STATE_ENABLED 0x8000 /* LESM Enable bit */
#define IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR 0x4
-#define IXGBE_FW_PATCH_VERSION_4 0x7
-
-/* Alternative SAN MAC Address Block */
+#define IXGBE_FW_PATCH_VERSION_4 0x7
+#define IXGBE_FCOE_IBA_CAPS_BLK_PTR 0x33 /* iSCSI/FCOE block */
+#define IXGBE_FCOE_IBA_CAPS_FCOE 0x20 /* FCOE flags */
+#define IXGBE_ISCSI_FCOE_BLK_PTR 0x17 /* iSCSI/FCOE block */
+#define IXGBE_ISCSI_FCOE_FLAGS_OFFSET 0x0 /* FCOE flags */
+#define IXGBE_ISCSI_FCOE_FLAGS_ENABLE 0x1 /* FCOE flags enable bit */
#define IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR 0x27 /* Alt. SAN MAC block */
#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET 0x0 /* Alt. SAN MAC capability */
#define IXGBE_ALT_SAN_MAC_ADDR_PORT0_OFFSET 0x1 /* Alt. SAN MAC 0 offset */
@@ -1688,6 +1775,7 @@
/* Transmit Config masks */
#define IXGBE_TXDCTL_ENABLE 0x02000000 /* Enable specific Tx Queue */
#define IXGBE_TXDCTL_SWFLSH 0x04000000 /* Tx Desc. write-back flushing */
+#define IXGBE_TXDCTL_WTHRESH_SHIFT 16 /* shift to WTHRESH bits */
/* Enable short packet padding to 64 bytes */
#define IXGBE_TX_PAD_ENABLE 0x00000400
#define IXGBE_JUMBO_FRAME_ENABLE 0x00000004 /* Allow jumbo frames */
@@ -1701,9 +1789,9 @@
#define IXGBE_RXCTRL_RXEN 0x00000001 /* Enable Receiver */
#define IXGBE_RXCTRL_DMBYPS 0x00000002 /* Descriptor Monitor Bypass */
#define IXGBE_RXDCTL_ENABLE 0x02000000 /* Enable specific Rx Queue */
-#define IXGBE_RXDCTL_VME 0x40000000 /* VLAN mode enable */
#define IXGBE_RXDCTL_RLPMLMASK 0x00003FFF /* Only supported on the X540 */
#define IXGBE_RXDCTL_RLPML_EN 0x00008000
+#define IXGBE_RXDCTL_VME 0x40000000 /* VLAN mode enable */
#define IXGBE_FCTRL_SBP 0x00000002 /* Store Bad Packet */
#define IXGBE_FCTRL_MPE 0x00000100 /* Multicast Promiscuous Ena*/
@@ -1719,6 +1807,8 @@
#define IXGBE_MFLCN_RPFCE 0x00000004 /* Receive Priority FC Enable */
#define IXGBE_MFLCN_RFCE 0x00000008 /* Receive FC Enable */
+#define IXGBE_MFLCN_RPFCE_SHIFT 4
+
/* Multiple Receive Queue Control */
#define IXGBE_MRQC_RSSEN 0x00000001 /* RSS Enable */
#define IXGBE_MRQC_MRQE_MASK 0xF /* Bits 3:0 */
@@ -1859,6 +1949,8 @@
#define IXGBE_RXDADV_PKTTYPE_MASK 0x0000FFF0
#define IXGBE_RXDADV_PKTTYPE_MASK_EX 0x0001FFF0
#define IXGBE_RXDADV_HDRBUFLEN_MASK 0x00007FE0
+#define IXGBE_RXDADV_RSCCNT_MASK 0x001E0000
+#define IXGBE_RXDADV_RSCCNT_SHIFT 17
#define IXGBE_RXDADV_HDRBUFLEN_SHIFT 5
#define IXGBE_RXDADV_SPLITHEADER_EN 0x00001000
#define IXGBE_RXDADV_SPH 0x8000
@@ -1934,15 +2026,6 @@
#define IXGBE_VFLRE(_i) (((_i & 1) ? 0x001C0 : 0x00600))
#define IXGBE_VFLREC(_i) (0x00700 + (_i * 4))
-/* Little Endian defines */
-#ifndef __le32
-#define __le32 u32
-#endif
-#ifndef __le64
-#define __le64 u64
-
-#endif
-
enum ixgbe_fdir_pballoc_type {
IXGBE_FDIR_PBALLOC_64K = 0,
IXGBE_FDIR_PBALLOC_128K,
@@ -2141,8 +2224,6 @@ typedef u32 ixgbe_link_speed;
IXGBE_LINK_SPEED_1GB_FULL | \
IXGBE_LINK_SPEED_10GB_FULL)
-#define IXGBE_PCIE_DEV_CTRL_2 0xC8
-#define PCIE_COMPL_TO_VALUE 0x05
/* Physical layer type */
typedef u32 ixgbe_physical_layer;
@@ -2315,6 +2396,7 @@ enum ixgbe_sfp_type {
enum ixgbe_media_type {
ixgbe_media_type_unknown = 0,
ixgbe_media_type_fiber,
+ ixgbe_media_type_fiber_lco,
ixgbe_media_type_copper,
ixgbe_media_type_backplane,
ixgbe_media_type_cx4,
@@ -2478,6 +2560,10 @@ struct ixgbe_hw_stats {
u64 fcoeptc;
u64 fcoedwrc;
u64 fcoedwtc;
+ u64 b2ospc;
+ u64 b2ogprc;
+ u64 o2bgptc;
+ u64 o2bspc;
};
/* forward declaration */
@@ -2491,7 +2577,9 @@ typedef u8* (*ixgbe_mc_addr_itr) (struct ixgbe_hw *hw, u8 **mc_addr_ptr,
struct ixgbe_eeprom_operations {
s32 (*init_params)(struct ixgbe_hw *);
s32 (*read)(struct ixgbe_hw *, u16, u16 *);
+ s32 (*read_buffer)(struct ixgbe_hw *, u16, u16, u16 *);
s32 (*write)(struct ixgbe_hw *, u16, u16);
+ s32 (*write_buffer)(struct ixgbe_hw *, u16, u16, u16 *);
s32 (*validate_checksum)(struct ixgbe_hw *, u16 *);
s32 (*update_checksum)(struct ixgbe_hw *);
u16 (*calc_checksum)(struct ixgbe_hw *);
@@ -2577,6 +2665,7 @@ struct ixgbe_eeprom_info {
u32 semaphore_delay;
u16 word_size;
u16 address_bits;
+ u16 word_page_size;
};
#define IXGBE_FLAGS_DOUBLE_RESET_REQUIRED 0x01
@@ -2597,6 +2686,7 @@ struct ixgbe_mac_info {
u32 vft_size;
u32 num_rar_entries;
u32 rar_highwater;
+ u32 rx_pb_size;
u32 max_tx_queues;
u32 max_rx_queues;
u32 max_msix_vectors;
diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c
index d9323c08f5c..4ed687be2fe 100644
--- a/drivers/net/ixgbe/ixgbe_x540.c
+++ b/drivers/net/ixgbe/ixgbe_x540.c
@@ -37,6 +37,7 @@
#define IXGBE_X540_RAR_ENTRIES 128
#define IXGBE_X540_MC_TBL_SIZE 128
#define IXGBE_X540_VFT_TBL_SIZE 128
+#define IXGBE_X540_RX_PB_SIZE 384
static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw);
static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw);
@@ -226,6 +227,28 @@ mac_reset_top:
}
/**
+ * ixgbe_start_hw_X540 - Prepare hardware for Tx/Rx
+ * @hw: pointer to hardware structure
+ *
+ * Starts the hardware using the generic start_hw function
+ * and the generation start_hw function.
+ * Then performs revision-specific operations, if any.
+ **/
+static s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw)
+{
+ s32 ret_val = 0;
+
+ ret_val = ixgbe_start_hw_generic(hw);
+ if (ret_val != 0)
+ goto out;
+
+ ret_val = ixgbe_start_hw_gen2(hw);
+ hw->mac.rx_pb_size = IXGBE_X540_RX_PB_SIZE;
+out:
+ return ret_val;
+}
+
+/**
* ixgbe_get_supported_physical_layer_X540 - Returns physical layer type
* @hw: pointer to hardware structure
*
@@ -281,74 +304,105 @@ static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
}
/**
- * ixgbe_read_eerd_X540 - Read EEPROM word using EERD
- * @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to read
- * @data: word read from the EERPOM
+ * ixgbe_read_eerd_X540- Read EEPROM word using EERD
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to read
+ * @data: word read from the EEPROM
+ *
+ * Reads a 16 bit word from the EEPROM using the EERD register.
**/
static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
{
- s32 status;
+ s32 status = 0;
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0)
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
+ 0)
status = ixgbe_read_eerd_generic(hw, offset, data);
else
status = IXGBE_ERR_SWFW_SYNC;
- ixgbe_release_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM);
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status;
}
/**
- * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR
- * @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to write
- * @data: word write to the EEPROM
+ * ixgbe_read_eerd_buffer_X540 - Read EEPROM word(s) using EERD
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to read
+ * @words: number of words
+ * @data: word(s) read from the EEPROM
*
- * Write a 16 bit word to the EEPROM using the EEWR register.
+ * Reads a 16 bit word(s) from the EEPROM using the EERD register.
**/
-static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
+static s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw,
+ u16 offset, u16 words, u16 *data)
{
- u32 eewr;
- s32 status;
+ s32 status = 0;
- hw->eeprom.ops.init_params(hw);
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
+ 0)
+ status = ixgbe_read_eerd_buffer_generic(hw, offset,
+ words, data);
+ else
+ status = IXGBE_ERR_SWFW_SYNC;
- if (offset >= hw->eeprom.word_size) {
- status = IXGBE_ERR_EEPROM;
- goto out;
- }
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+ return status;
+}
- eewr = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) |
- (data << IXGBE_EEPROM_RW_REG_DATA) |
- IXGBE_EEPROM_RW_REG_START;
+/**
+ * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to write
+ * @data: word write to the EEPROM
+ *
+ * Write a 16 bit word to the EEPROM using the EEWR register.
+ **/
+static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
+{
+ s32 status = 0;
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
- status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
- if (status != 0) {
- hw_dbg(hw, "Eeprom write EEWR timed out\n");
- goto out;
- }
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0)
+ status = ixgbe_write_eewr_generic(hw, offset, data);
+ else
+ status = IXGBE_ERR_SWFW_SYNC;
- IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+ return status;
+}
- status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
- if (status != 0) {
- hw_dbg(hw, "Eeprom write EEWR timed out\n");
- goto out;
- }
- } else {
+/**
+ * ixgbe_write_eewr_buffer_X540 - Write EEPROM word(s) using EEWR
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to write
+ * @words: number of words
+ * @data: word(s) write to the EEPROM
+ *
+ * Write a 16 bit word(s) to the EEPROM using the EEWR register.
+ **/
+static s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw,
+ u16 offset, u16 words, u16 *data)
+{
+ s32 status = 0;
+
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
+ 0)
+ status = ixgbe_write_eewr_buffer_generic(hw, offset,
+ words, data);
+ else
status = IXGBE_ERR_SWFW_SYNC;
- }
-out:
- ixgbe_release_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM);
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status;
}
/**
- * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum
- * @hw: pointer to hardware structure
+ * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum
+ *
+ * This function does not use synchronization for EERD and EEWR. It can
+ * be used internally by function which utilize ixgbe_acquire_swfw_sync_X540.
+ *
+ * @hw: pointer to hardware structure
**/
static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
{
@@ -359,9 +413,15 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
u16 pointer = 0;
u16 word = 0;
+ /*
+ * Do not use hw->eeprom.ops.read because we do not want to take
+ * the synchronization semaphores here. Instead use
+ * ixgbe_read_eerd_generic
+ */
+
/* Include 0x0-0x3F in the checksum */
for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
- if (hw->eeprom.ops.read(hw, i, &word) != 0) {
+ if (ixgbe_read_eerd_generic(hw, i, &word) != 0) {
hw_dbg(hw, "EEPROM read failed\n");
break;
}
@@ -376,7 +436,7 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
continue;
- if (hw->eeprom.ops.read(hw, i, &pointer) != 0) {
+ if (ixgbe_read_eerd_generic(hw, i, &pointer) != 0) {
hw_dbg(hw, "EEPROM read failed\n");
break;
}
@@ -386,7 +446,7 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
pointer >= hw->eeprom.word_size)
continue;
- if (hw->eeprom.ops.read(hw, pointer, &length) != 0) {
+ if (ixgbe_read_eerd_generic(hw, pointer, &length) != 0) {
hw_dbg(hw, "EEPROM read failed\n");
break;
}
@@ -397,7 +457,7 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
continue;
for (j = pointer+1; j <= pointer+length; j++) {
- if (hw->eeprom.ops.read(hw, j, &word) != 0) {
+ if (ixgbe_read_eerd_generic(hw, j, &word) != 0) {
hw_dbg(hw, "EEPROM read failed\n");
break;
}
@@ -411,6 +471,62 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_validate_eeprom_checksum_X540 - Validate EEPROM checksum
+ * @hw: pointer to hardware structure
+ * @checksum_val: calculated checksum
+ *
+ * Performs checksum calculation and validates the EEPROM checksum. If the
+ * caller does not need checksum_val, the value can be NULL.
+ **/
+static s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw,
+ u16 *checksum_val)
+{
+ s32 status;
+ u16 checksum;
+ u16 read_checksum = 0;
+
+ /*
+ * Read the first word from the EEPROM. If this times out or fails, do
+ * not continue or we could be in for a very long wait while every
+ * EEPROM read fails
+ */
+ status = hw->eeprom.ops.read(hw, 0, &checksum);
+
+ if (status != 0) {
+ hw_dbg(hw, "EEPROM read failed\n");
+ goto out;
+ }
+
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
+ checksum = hw->eeprom.ops.calc_checksum(hw);
+
+ /*
+ * Do not use hw->eeprom.ops.read because we do not want to take
+ * the synchronization semaphores twice here.
+ */
+ ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
+ &read_checksum);
+
+ /*
+ * Verify read checksum from EEPROM is the same as
+ * calculated checksum
+ */
+ if (read_checksum != checksum)
+ status = IXGBE_ERR_EEPROM_CHECKSUM;
+
+ /* If the user cares, return the calculated checksum */
+ if (checksum_val)
+ *checksum_val = checksum;
+ } else {
+ status = IXGBE_ERR_SWFW_SYNC;
+ }
+
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+out:
+ return status;
+}
+
+/**
* ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash
* @hw: pointer to hardware structure
*
@@ -421,11 +537,35 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
{
s32 status;
+ u16 checksum;
+
+ /*
+ * Read the first word from the EEPROM. If this times out or fails, do
+ * not continue or we could be in for a very long wait while every
+ * EEPROM read fails
+ */
+ status = hw->eeprom.ops.read(hw, 0, &checksum);
+
+ if (status != 0)
+ hw_dbg(hw, "EEPROM read failed\n");
- status = ixgbe_update_eeprom_checksum_generic(hw);
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
+ checksum = hw->eeprom.ops.calc_checksum(hw);
+
+ /*
+ * Do not use hw->eeprom.ops.write because we do not want to
+ * take the synchronization semaphores twice here.
+ */
+ status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM,
+ checksum);
- if (status)
+ if (status == 0)
status = ixgbe_update_flash_X540(hw);
+ else
+ status = IXGBE_ERR_SWFW_SYNC;
+ }
+
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status;
}
@@ -452,7 +592,7 @@ static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_EEC, flup);
status = ixgbe_poll_flash_update_done_X540(hw);
- if (status)
+ if (status == 0)
hw_dbg(hw, "Flash update complete\n");
else
hw_dbg(hw, "Flash update time out\n");
@@ -466,11 +606,10 @@ static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw)
}
status = ixgbe_poll_flash_update_done_X540(hw);
- if (status)
+ if (status == 0)
hw_dbg(hw, "Flash update complete\n");
else
hw_dbg(hw, "Flash update time out\n");
-
}
out:
return status;
@@ -542,7 +681,7 @@ static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask)
* resource (swmask)
*/
ixgbe_release_swfw_sync_semaphore(hw);
- msleep(5);
+ usleep_range(5000, 10000);
}
}
@@ -564,7 +703,7 @@ static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask)
}
}
- msleep(5);
+ usleep_range(5000, 10000);
return 0;
}
@@ -588,7 +727,7 @@ static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask)
IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync);
ixgbe_release_swfw_sync_semaphore(hw);
- msleep(5);
+ usleep_range(5000, 10000);
}
/**
@@ -658,10 +797,70 @@ static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw)
IXGBE_WRITE_FLUSH(hw);
}
+/**
+ * ixgbe_blink_led_start_X540 - Blink LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to blink
+ *
+ * Devices that implement the version 2 interface:
+ * X540
+ **/
+static s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index)
+{
+ u32 macc_reg;
+ u32 ledctl_reg;
+
+ /*
+ * In order for the blink bit in the LED control register
+ * to work, link and speed must be forced in the MAC. We
+ * will reverse this when we stop the blinking.
+ */
+ macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC);
+ macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS;
+ IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg);
+
+ /* Set the LED to LINK_UP + BLINK. */
+ ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+ ledctl_reg &= ~IXGBE_LED_MODE_MASK(index);
+ ledctl_reg |= IXGBE_LED_BLINK(index);
+ IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_blink_led_stop_X540 - Stop blinking LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to stop blinking
+ *
+ * Devices that implement the version 2 interface:
+ * X540
+ **/
+static s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index)
+{
+ u32 macc_reg;
+ u32 ledctl_reg;
+
+ /* Restore the LED to its default value. */
+ ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+ ledctl_reg &= ~IXGBE_LED_MODE_MASK(index);
+ ledctl_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
+ ledctl_reg &= ~IXGBE_LED_BLINK(index);
+ IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg);
+
+ /* Unforce link and speed in the MAC. */
+ macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC);
+ macc_reg &= ~(IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS);
+ IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return 0;
+}
static struct ixgbe_mac_operations mac_ops_X540 = {
.init_hw = &ixgbe_init_hw_generic,
.reset_hw = &ixgbe_reset_hw_X540,
- .start_hw = &ixgbe_start_hw_generic,
+ .start_hw = &ixgbe_start_hw_X540,
.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic,
.get_media_type = &ixgbe_get_media_type_X540,
.get_supported_physical_layer =
@@ -669,7 +868,7 @@ static struct ixgbe_mac_operations mac_ops_X540 = {
.enable_rx_dma = &ixgbe_enable_rx_dma_generic,
.get_mac_addr = &ixgbe_get_mac_addr_generic,
.get_san_mac_addr = &ixgbe_get_san_mac_addr_generic,
- .get_device_caps = NULL,
+ .get_device_caps = &ixgbe_get_device_caps_generic,
.get_wwn_prefix = &ixgbe_get_wwn_prefix_generic,
.stop_adapter = &ixgbe_stop_adapter_generic,
.get_bus_info = &ixgbe_get_bus_info_generic,
@@ -681,8 +880,8 @@ static struct ixgbe_mac_operations mac_ops_X540 = {
.get_link_capabilities = &ixgbe_get_copper_link_capabilities_generic,
.led_on = &ixgbe_led_on_generic,
.led_off = &ixgbe_led_off_generic,
- .blink_led_start = &ixgbe_blink_led_start_generic,
- .blink_led_stop = &ixgbe_blink_led_stop_generic,
+ .blink_led_start = &ixgbe_blink_led_start_X540,
+ .blink_led_stop = &ixgbe_blink_led_stop_X540,
.set_rar = &ixgbe_set_rar_generic,
.clear_rar = &ixgbe_clear_rar_generic,
.set_vmdq = &ixgbe_set_vmdq_generic,
@@ -705,9 +904,11 @@ static struct ixgbe_mac_operations mac_ops_X540 = {
static struct ixgbe_eeprom_operations eeprom_ops_X540 = {
.init_params = &ixgbe_init_eeprom_params_X540,
.read = &ixgbe_read_eerd_X540,
+ .read_buffer = &ixgbe_read_eerd_buffer_X540,
.write = &ixgbe_write_eewr_X540,
+ .write_buffer = &ixgbe_write_eewr_buffer_X540,
.calc_checksum = &ixgbe_calc_eeprom_checksum_X540,
- .validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
+ .validate_checksum = &ixgbe_validate_eeprom_checksum_X540,
.update_checksum = &ixgbe_update_eeprom_checksum_X540,
};
diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c
index 0563ab29264..deee3754b1f 100644
--- a/drivers/net/ixgbevf/ethtool.c
+++ b/drivers/net/ixgbevf/ethtool.c
@@ -104,11 +104,13 @@ static int ixgbevf_get_settings(struct net_device *netdev,
hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
if (link_up) {
- ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
- SPEED_10000 : SPEED_1000;
+ ethtool_cmd_speed_set(
+ ecmd,
+ (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
+ SPEED_10000 : SPEED_1000);
ecmd->duplex = DUPLEX_FULL;
} else {
- ecmd->speed = -1;
+ ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1;
}
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c
index 05fa7c85dee..d7ab202fb95 100644
--- a/drivers/net/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ixgbevf/ixgbevf_main.c
@@ -1460,6 +1460,34 @@ static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter)
}
}
+static int ixgbevf_write_uc_addr_list(struct net_device *netdev)
+{
+ struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
+ int count = 0;
+
+ if ((netdev_uc_count(netdev)) > 10) {
+ printk(KERN_ERR "Too many unicast filters - No Space\n");
+ return -ENOSPC;
+ }
+
+ if (!netdev_uc_empty(netdev)) {
+ struct netdev_hw_addr *ha;
+ netdev_for_each_uc_addr(ha, netdev) {
+ hw->mac.ops.set_uc_addr(hw, ++count, ha->addr);
+ udelay(200);
+ }
+ } else {
+ /*
+ * If the list is empty then send message to PF driver to
+ * clear all macvlans on this VF.
+ */
+ hw->mac.ops.set_uc_addr(hw, 0, NULL);
+ }
+
+ return count;
+}
+
/**
* ixgbevf_set_rx_mode - Multicast set
* @netdev: network interface device structure
@@ -1476,6 +1504,8 @@ static void ixgbevf_set_rx_mode(struct net_device *netdev)
/* reprogram multicast list */
if (hw->mac.ops.update_mc_addr_list)
hw->mac.ops.update_mc_addr_list(hw, netdev);
+
+ ixgbevf_write_uc_addr_list(netdev);
}
static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter)
diff --git a/drivers/net/ixgbevf/mbx.h b/drivers/net/ixgbevf/mbx.h
index b2b5bf5daa3..ea393eb03f3 100644
--- a/drivers/net/ixgbevf/mbx.h
+++ b/drivers/net/ixgbevf/mbx.h
@@ -81,6 +81,7 @@
#define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
#define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */
#define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */
+#define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */
/* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4
diff --git a/drivers/net/ixgbevf/vf.c b/drivers/net/ixgbevf/vf.c
index eecd3bf6833..aa3682e8c47 100644
--- a/drivers/net/ixgbevf/vf.c
+++ b/drivers/net/ixgbevf/vf.c
@@ -216,6 +216,39 @@ static s32 ixgbevf_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr)
return 0;
}
+static s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
+{
+ struct ixgbe_mbx_info *mbx = &hw->mbx;
+ u32 msgbuf[3];
+ u8 *msg_addr = (u8 *)(&msgbuf[1]);
+ s32 ret_val;
+
+ memset(msgbuf, 0, sizeof(msgbuf));
+ /*
+ * If index is one then this is the start of a new list and needs
+ * indication to the PF so it can do it's own list management.
+ * If it is zero then that tells the PF to just clear all of
+ * this VF's macvlans and there is no new list.
+ */
+ msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT;
+ msgbuf[0] |= IXGBE_VF_SET_MACVLAN;
+ if (addr)
+ memcpy(msg_addr, addr, 6);
+ ret_val = mbx->ops.write_posted(hw, msgbuf, 3);
+
+ if (!ret_val)
+ ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
+
+ msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
+
+ if (!ret_val)
+ if (msgbuf[0] ==
+ (IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK))
+ ret_val = -ENOMEM;
+
+ return ret_val;
+}
+
/**
* ixgbevf_set_rar_vf - set device MAC address
* @hw: pointer to hardware structure
@@ -378,6 +411,7 @@ static struct ixgbe_mac_operations ixgbevf_mac_ops = {
.check_link = ixgbevf_check_mac_link_vf,
.set_rar = ixgbevf_set_rar_vf,
.update_mc_addr_list = ixgbevf_update_mc_addr_list_vf,
+ .set_uc_addr = ixgbevf_set_uc_addr_vf,
.set_vfta = ixgbevf_set_vfta_vf,
};
diff --git a/drivers/net/ixgbevf/vf.h b/drivers/net/ixgbevf/vf.h
index 23eb114c149..10306b492ee 100644
--- a/drivers/net/ixgbevf/vf.h
+++ b/drivers/net/ixgbevf/vf.h
@@ -62,6 +62,7 @@ struct ixgbe_mac_operations {
/* RAR, Multicast, VLAN */
s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32);
+ s32 (*set_uc_addr)(struct ixgbe_hw *, u32, u8 *);
s32 (*init_rx_addrs)(struct ixgbe_hw *);
s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *);
s32 (*enable_mc)(struct ixgbe_hw *);
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index 994c80939c7..b5b174a8c14 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -2230,17 +2230,9 @@ jme_change_mtu(struct net_device *netdev, int new_mtu)
jme_restart_rx_engine(jme);
}
- if (new_mtu > 1900) {
- netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
- NETIF_F_TSO | NETIF_F_TSO6);
- } else {
- if (test_bit(JME_FLAG_TXCSUM, &jme->flags))
- netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
- if (test_bit(JME_FLAG_TSO, &jme->flags))
- netdev->features |= NETIF_F_TSO | NETIF_F_TSO6;
- }
-
netdev->mtu = new_mtu;
+ netdev_update_features(netdev);
+
jme_reset_link(jme);
return 0;
@@ -2563,7 +2555,8 @@ jme_set_settings(struct net_device *netdev,
struct jme_adapter *jme = netdev_priv(netdev);
int rc, fdc = 0;
- if (ecmd->speed == SPEED_1000 && ecmd->autoneg != AUTONEG_ENABLE)
+ if (ethtool_cmd_speed(ecmd) == SPEED_1000
+ && ecmd->autoneg != AUTONEG_ENABLE)
return -EINVAL;
/*
@@ -2640,19 +2633,20 @@ jme_set_msglevel(struct net_device *netdev, u32 value)
}
static u32
-jme_get_rx_csum(struct net_device *netdev)
+jme_fix_features(struct net_device *netdev, u32 features)
{
- struct jme_adapter *jme = netdev_priv(netdev);
- return jme->reg_rxmcs & RXMCS_CHECKSUM;
+ if (netdev->mtu > 1900)
+ features &= ~(NETIF_F_ALL_TSO | NETIF_F_ALL_CSUM);
+ return features;
}
static int
-jme_set_rx_csum(struct net_device *netdev, u32 on)
+jme_set_features(struct net_device *netdev, u32 features)
{
struct jme_adapter *jme = netdev_priv(netdev);
spin_lock_bh(&jme->rxmcs_lock);
- if (on)
+ if (features & NETIF_F_RXCSUM)
jme->reg_rxmcs |= RXMCS_CHECKSUM;
else
jme->reg_rxmcs &= ~RXMCS_CHECKSUM;
@@ -2663,42 +2657,6 @@ jme_set_rx_csum(struct net_device *netdev, u32 on)
}
static int
-jme_set_tx_csum(struct net_device *netdev, u32 on)
-{
- struct jme_adapter *jme = netdev_priv(netdev);
-
- if (on) {
- set_bit(JME_FLAG_TXCSUM, &jme->flags);
- if (netdev->mtu <= 1900)
- netdev->features |=
- NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
- } else {
- clear_bit(JME_FLAG_TXCSUM, &jme->flags);
- netdev->features &=
- ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
- }
-
- return 0;
-}
-
-static int
-jme_set_tso(struct net_device *netdev, u32 on)
-{
- struct jme_adapter *jme = netdev_priv(netdev);
-
- if (on) {
- set_bit(JME_FLAG_TSO, &jme->flags);
- if (netdev->mtu <= 1900)
- netdev->features |= NETIF_F_TSO | NETIF_F_TSO6;
- } else {
- clear_bit(JME_FLAG_TSO, &jme->flags);
- netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
- }
-
- return 0;
-}
-
-static int
jme_nway_reset(struct net_device *netdev)
{
struct jme_adapter *jme = netdev_priv(netdev);
@@ -2839,11 +2797,6 @@ static const struct ethtool_ops jme_ethtool_ops = {
.get_link = jme_get_link,
.get_msglevel = jme_get_msglevel,
.set_msglevel = jme_set_msglevel,
- .get_rx_csum = jme_get_rx_csum,
- .set_rx_csum = jme_set_rx_csum,
- .set_tx_csum = jme_set_tx_csum,
- .set_tso = jme_set_tso,
- .set_sg = ethtool_op_set_sg,
.nway_reset = jme_nway_reset,
.get_eeprom_len = jme_get_eeprom_len,
.get_eeprom = jme_get_eeprom,
@@ -2903,6 +2856,8 @@ static const struct net_device_ops jme_netdev_ops = {
.ndo_change_mtu = jme_change_mtu,
.ndo_tx_timeout = jme_tx_timeout,
.ndo_vlan_rx_register = jme_vlan_rx_register,
+ .ndo_fix_features = jme_fix_features,
+ .ndo_set_features = jme_set_features,
};
static int __devinit
@@ -2957,6 +2912,12 @@ jme_init_one(struct pci_dev *pdev,
netdev->netdev_ops = &jme_netdev_ops;
netdev->ethtool_ops = &jme_ethtool_ops;
netdev->watchdog_timeo = TX_TIMEOUT;
+ netdev->hw_features = NETIF_F_IP_CSUM |
+ NETIF_F_IPV6_CSUM |
+ NETIF_F_SG |
+ NETIF_F_TSO |
+ NETIF_F_TSO6 |
+ NETIF_F_RXCSUM;
netdev->features = NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM |
NETIF_F_SG |
@@ -3040,8 +3001,9 @@ jme_init_one(struct pci_dev *pdev,
jme->reg_txpfc = 0;
jme->reg_pmcs = PMCS_MFEN;
jme->reg_gpreg1 = GPREG1_DEFAULT;
- set_bit(JME_FLAG_TXCSUM, &jme->flags);
- set_bit(JME_FLAG_TSO, &jme->flags);
+
+ if (jme->reg_rxmcs & RXMCS_CHECKSUM)
+ netdev->features |= NETIF_F_RXCSUM;
/*
* Get Max Read Req Size from PCI Config Space
diff --git a/drivers/net/jme.h b/drivers/net/jme.h
index 8bf30451e82..e9aaeca96ab 100644
--- a/drivers/net/jme.h
+++ b/drivers/net/jme.h
@@ -468,8 +468,6 @@ struct jme_adapter {
enum jme_flags_bits {
JME_FLAG_MSI = 1,
JME_FLAG_SSET = 2,
- JME_FLAG_TXCSUM = 3,
- JME_FLAG_TSO = 4,
JME_FLAG_POLL = 5,
JME_FLAG_SHUTDOWN = 6,
};
diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c
index 7f7d5708a65..41ea5920c15 100644
--- a/drivers/net/ksz884x.c
+++ b/drivers/net/ksz884x.c
@@ -1221,7 +1221,6 @@ struct ksz_port_info {
#define LINK_INT_WORKING (1 << 0)
#define SMALL_PACKET_TX_BUG (1 << 1)
#define HALF_DUPLEX_SIGNAL_BUG (1 << 2)
-#define IPV6_CSUM_GEN_HACK (1 << 3)
#define RX_HUGE_FRAME (1 << 4)
#define STP_SUPPORT (1 << 8)
@@ -3748,7 +3747,6 @@ static int hw_init(struct ksz_hw *hw)
if (1 == rc)
hw->features |= HALF_DUPLEX_SIGNAL_BUG;
}
- hw->features |= IPV6_CSUM_GEN_HACK;
return rc;
}
@@ -4887,8 +4885,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev)
left = hw_alloc_pkt(hw, skb->len, num);
if (left) {
if (left < num ||
- ((hw->features & IPV6_CSUM_GEN_HACK) &&
- (CHECKSUM_PARTIAL == skb->ip_summed) &&
+ ((CHECKSUM_PARTIAL == skb->ip_summed) &&
(ETH_P_IPV6 == htons(skb->protocol)))) {
struct sk_buff *org_skb = skb;
@@ -6001,6 +5998,7 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
struct dev_priv *priv = netdev_priv(dev);
struct dev_info *hw_priv = priv->adapter;
struct ksz_port *port = &priv->port;
+ u32 speed = ethtool_cmd_speed(cmd);
int rc;
/*
@@ -6009,11 +6007,11 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
*/
if (cmd->autoneg && priv->advertising == cmd->advertising) {
cmd->advertising |= ADVERTISED_ALL;
- if (10 == cmd->speed)
+ if (10 == speed)
cmd->advertising &=
~(ADVERTISED_100baseT_Full |
ADVERTISED_100baseT_Half);
- else if (100 == cmd->speed)
+ else if (100 == speed)
cmd->advertising &=
~(ADVERTISED_10baseT_Full |
ADVERTISED_10baseT_Half);
@@ -6035,8 +6033,8 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
port->force_link = 0;
} else {
port->duplex = cmd->duplex + 1;
- if (cmd->speed != 1000)
- port->speed = cmd->speed;
+ if (1000 != speed)
+ port->speed = speed;
if (cmd->autoneg)
port->force_link = 0;
else
@@ -6583,57 +6581,33 @@ static void netdev_get_ethtool_stats(struct net_device *dev,
}
/**
- * netdev_get_rx_csum - get receive checksum support
+ * netdev_set_features - set receive checksum support
* @dev: Network device.
- *
- * This function gets receive checksum support setting.
- *
- * Return true if receive checksum is enabled; false otherwise.
- */
-static u32 netdev_get_rx_csum(struct net_device *dev)
-{
- struct dev_priv *priv = netdev_priv(dev);
- struct dev_info *hw_priv = priv->adapter;
- struct ksz_hw *hw = &hw_priv->hw;
-
- return hw->rx_cfg &
- (DMA_RX_CSUM_UDP |
- DMA_RX_CSUM_TCP |
- DMA_RX_CSUM_IP);
-}
-
-/**
- * netdev_set_rx_csum - set receive checksum support
- * @dev: Network device.
- * @data: Zero to disable receive checksum support.
+ * @features: New device features (offloads).
*
* This function sets receive checksum support setting.
*
* Return 0 if successful; otherwise an error code.
*/
-static int netdev_set_rx_csum(struct net_device *dev, u32 data)
+static int netdev_set_features(struct net_device *dev, u32 features)
{
struct dev_priv *priv = netdev_priv(dev);
struct dev_info *hw_priv = priv->adapter;
struct ksz_hw *hw = &hw_priv->hw;
- u32 new_setting = hw->rx_cfg;
- if (data)
- new_setting |=
- (DMA_RX_CSUM_UDP | DMA_RX_CSUM_TCP |
- DMA_RX_CSUM_IP);
- else
- new_setting &=
- ~(DMA_RX_CSUM_UDP | DMA_RX_CSUM_TCP |
- DMA_RX_CSUM_IP);
- new_setting &= ~DMA_RX_CSUM_UDP;
mutex_lock(&hw_priv->lock);
- if (new_setting != hw->rx_cfg) {
- hw->rx_cfg = new_setting;
- if (hw->enabled)
- writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL);
- }
+
+ /* see note in hw_setup() */
+ if (features & NETIF_F_RXCSUM)
+ hw->rx_cfg |= DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP;
+ else
+ hw->rx_cfg &= ~(DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP);
+
+ if (hw->enabled)
+ writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL);
+
mutex_unlock(&hw_priv->lock);
+
return 0;
}
@@ -6658,12 +6632,6 @@ static struct ethtool_ops netdev_ethtool_ops = {
.get_strings = netdev_get_strings,
.get_sset_count = netdev_get_sset_count,
.get_ethtool_stats = netdev_get_ethtool_stats,
- .get_rx_csum = netdev_get_rx_csum,
- .set_rx_csum = netdev_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,
};
/*
@@ -6828,14 +6796,15 @@ static int __init netdev_init(struct net_device *dev)
/* 500 ms timeout */
dev->watchdog_timeo = HZ / 2;
- dev->features |= NETIF_F_IP_CSUM;
+ dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_RXCSUM;
/*
* Hardware does not really support IPv6 checksum generation, but
- * driver actually runs faster with this on. Refer IPV6_CSUM_GEN_HACK.
+ * driver actually runs faster with this on.
*/
- dev->features |= NETIF_F_IPV6_CSUM;
- dev->features |= NETIF_F_SG;
+ dev->hw_features |= NETIF_F_IPV6_CSUM;
+
+ dev->features |= dev->hw_features;
sema_init(&priv->proc_sem, 1);
@@ -6860,6 +6829,7 @@ static const struct net_device_ops netdev_ops = {
.ndo_start_xmit = netdev_tx,
.ndo_tx_timeout = netdev_tx_timeout,
.ndo_change_mtu = netdev_change_mtu,
+ .ndo_set_features = netdev_set_features,
.ndo_set_mac_address = netdev_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = netdev_ioctl,
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index d70fb76edb7..4ce9e5f2c06 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -174,7 +174,8 @@ static void loopback_setup(struct net_device *dev)
| NETIF_F_HIGHDMA
| NETIF_F_LLTX
| NETIF_F_NETNS_LOCAL
- | NETIF_F_VLAN_CHALLENGED;
+ | NETIF_F_VLAN_CHALLENGED
+ | NETIF_F_LOOPBACK;
dev->ethtool_ops = &loopback_ethtool_ops;
dev->header_ops = &eth_header_ops;
dev->netdev_ops = &loopback_ops;
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 79ccb54ab00..629bd2649c0 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -576,6 +576,11 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
* add that if/when we get our hands on a full-blown MII PHY.
*/
+ if (status & MACB_BIT(ISR_ROVR)) {
+ /* We missed at least one packet */
+ bp->hw_stats.rx_overruns++;
+ }
+
if (status & MACB_BIT(HRESP)) {
/*
* TODO: Reset the hardware, and maybe move the printk
@@ -1024,7 +1029,8 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev)
hwstat->rx_jabbers +
hwstat->rx_undersize_pkts +
hwstat->rx_length_mismatch);
- nstat->rx_over_errors = hwstat->rx_resource_errors;
+ nstat->rx_over_errors = hwstat->rx_resource_errors +
+ hwstat->rx_overruns;
nstat->rx_crc_errors = hwstat->rx_fcs_errors;
nstat->rx_frame_errors = hwstat->rx_align_errors;
nstat->rx_fifo_errors = hwstat->rx_overruns;
@@ -1171,8 +1177,7 @@ static int __init macb_probe(struct platform_device *pdev)
}
dev->irq = platform_get_irq(pdev, 0);
- err = request_irq(dev->irq, macb_interrupt, IRQF_SAMPLE_RANDOM,
- dev->name, dev);
+ err = request_irq(dev->irq, macb_interrupt, 0, dev->name, dev);
if (err) {
printk(KERN_ERR
"%s: Unable to request IRQ %d (error %d)\n",
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index d8e4e69ad0b..d72a70615c0 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -70,16 +70,17 @@ static void macvlan_hash_add(struct macvlan_dev *vlan)
hlist_add_head_rcu(&vlan->hlist, &port->vlan_hash[addr[5]]);
}
-static void macvlan_hash_del(struct macvlan_dev *vlan)
+static void macvlan_hash_del(struct macvlan_dev *vlan, bool sync)
{
hlist_del_rcu(&vlan->hlist);
- synchronize_rcu();
+ if (sync)
+ synchronize_rcu();
}
static void macvlan_hash_change_addr(struct macvlan_dev *vlan,
const unsigned char *addr)
{
- macvlan_hash_del(vlan);
+ macvlan_hash_del(vlan, true);
/* Now that we are unhashed it is safe to change the device
* address without confusing packet delivery.
*/
@@ -345,7 +346,7 @@ static int macvlan_stop(struct net_device *dev)
dev_uc_del(lowerdev, dev->dev_addr);
hash_del:
- macvlan_hash_del(vlan);
+ macvlan_hash_del(vlan, !dev->dismantle);
return 0;
}
@@ -415,7 +416,7 @@ static struct lock_class_key macvlan_netdev_addr_lock_key;
#define MACVLAN_FEATURES \
(NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO_ROBUST | \
- NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO)
+ NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM)
#define MACVLAN_STATE_MASK \
((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT))
@@ -517,12 +518,6 @@ static void macvlan_ethtool_get_drvinfo(struct net_device *dev,
snprintf(drvinfo->version, 32, "0.1");
}
-static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev)
-{
- const struct macvlan_dev *vlan = netdev_priv(dev);
- return dev_ethtool_get_rx_csum(vlan->lowerdev);
-}
-
static int macvlan_ethtool_get_settings(struct net_device *dev,
struct ethtool_cmd *cmd)
{
@@ -530,18 +525,10 @@ static int macvlan_ethtool_get_settings(struct net_device *dev,
return dev_ethtool_get_settings(vlan->lowerdev, cmd);
}
-static u32 macvlan_ethtool_get_flags(struct net_device *dev)
-{
- const struct macvlan_dev *vlan = netdev_priv(dev);
- return dev_ethtool_get_flags(vlan->lowerdev);
-}
-
static const struct ethtool_ops macvlan_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_settings = macvlan_ethtool_get_settings,
- .get_rx_csum = macvlan_ethtool_get_rx_csum,
.get_drvinfo = macvlan_ethtool_get_drvinfo,
- .get_flags = macvlan_ethtool_get_flags,
};
static const struct net_device_ops macvlan_netdev_ops = {
@@ -598,8 +585,8 @@ static int macvlan_port_create(struct net_device *dev)
err = netdev_rx_handler_register(dev, macvlan_handle_frame, port);
if (err)
kfree(port);
-
- dev->priv_flags |= IFF_MACVLAN_PORT;
+ else
+ dev->priv_flags |= IFF_MACVLAN_PORT;
return err;
}
@@ -791,6 +778,7 @@ static int macvlan_device_event(struct notifier_block *unused,
struct net_device *dev = ptr;
struct macvlan_dev *vlan, *next;
struct macvlan_port *port;
+ LIST_HEAD(list_kill);
if (!macvlan_port_exists(dev))
return NOTIFY_DONE;
@@ -816,7 +804,9 @@ static int macvlan_device_event(struct notifier_block *unused,
break;
list_for_each_entry_safe(vlan, next, &port->vlans, list)
- vlan->dev->rtnl_link_ops->dellink(vlan->dev, NULL);
+ vlan->dev->rtnl_link_ops->dellink(vlan->dev, &list_kill);
+ unregister_netdevice_many(&list_kill);
+ list_del(&list_kill);
break;
case NETDEV_PRE_TYPE_CHANGE:
/* Forbid underlaying device to change its type. */
diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c
index e85bf04cf81..16fbb11d92a 100644
--- a/drivers/net/mdio.c
+++ b/drivers/net/mdio.c
@@ -176,6 +176,9 @@ static u32 mdio45_get_an(const struct mdio_if_info *mdio, u16 addr)
* @npage_adv: Modes currently advertised on next pages
* @npage_lpa: Modes advertised by link partner on next pages
*
+ * The @ecmd parameter is expected to have been cleared before calling
+ * mdio45_ethtool_gset_npage().
+ *
* Since the CSRs for auto-negotiation using next pages are not fully
* standardised, this function does not attempt to decode them. The
* caller must pass them in.
@@ -185,6 +188,7 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,
u32 npage_adv, u32 npage_lpa)
{
int reg;
+ u32 speed;
ecmd->transceiver = XCVR_INTERNAL;
ecmd->phy_address = mdio->prtad;
@@ -287,33 +291,36 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,
if (modes & (ADVERTISED_10000baseT_Full |
ADVERTISED_10000baseKX4_Full |
ADVERTISED_10000baseKR_Full)) {
- ecmd->speed = SPEED_10000;
+ speed = SPEED_10000;
ecmd->duplex = DUPLEX_FULL;
} else if (modes & (ADVERTISED_1000baseT_Full |
ADVERTISED_1000baseT_Half |
ADVERTISED_1000baseKX_Full)) {
- ecmd->speed = SPEED_1000;
+ speed = SPEED_1000;
ecmd->duplex = !(modes & ADVERTISED_1000baseT_Half);
} else if (modes & (ADVERTISED_100baseT_Full |
ADVERTISED_100baseT_Half)) {
- ecmd->speed = SPEED_100;
+ speed = SPEED_100;
ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
} else {
- ecmd->speed = SPEED_10;
+ speed = SPEED_10;
ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
}
} else {
/* Report forced settings */
reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
MDIO_CTRL1);
- ecmd->speed = (((reg & MDIO_PMA_CTRL1_SPEED1000) ? 100 : 1) *
- ((reg & MDIO_PMA_CTRL1_SPEED100) ? 100 : 10));
+ speed = (((reg & MDIO_PMA_CTRL1_SPEED1000) ? 100 : 1)
+ * ((reg & MDIO_PMA_CTRL1_SPEED100) ? 100 : 10));
ecmd->duplex = (reg & MDIO_CTRL1_FULLDPLX ||
- ecmd->speed == SPEED_10000);
+ speed == SPEED_10000);
}
+ ethtool_cmd_speed_set(ecmd, speed);
+
/* 10GBASE-T MDI/MDI-X */
- if (ecmd->port == PORT_TP && ecmd->speed == SPEED_10000) {
+ if (ecmd->port == PORT_TP
+ && (ethtool_cmd_speed(ecmd) == SPEED_10000)) {
switch (mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
MDIO_PMA_10GBT_SWAPPOL)) {
case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX:
diff --git a/drivers/net/mii.c b/drivers/net/mii.c
index d4fc00b1ff9..c62e7816d54 100644
--- a/drivers/net/mii.c
+++ b/drivers/net/mii.c
@@ -62,6 +62,9 @@ static u32 mii_get_an(struct mii_if_info *mii, u16 addr)
* @mii: MII interface
* @ecmd: requested ethtool_cmd
*
+ * The @ecmd parameter is expected to have been cleared before calling
+ * mii_ethtool_gset().
+ *
* Returns 0 for success, negative on error.
*/
int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
@@ -122,22 +125,25 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
if (nego & (ADVERTISED_1000baseT_Full |
ADVERTISED_1000baseT_Half)) {
- ecmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(ecmd, SPEED_1000);
ecmd->duplex = !!(nego & ADVERTISED_1000baseT_Full);
} else if (nego & (ADVERTISED_100baseT_Full |
ADVERTISED_100baseT_Half)) {
- ecmd->speed = SPEED_100;
+ ethtool_cmd_speed_set(ecmd, SPEED_100);
ecmd->duplex = !!(nego & ADVERTISED_100baseT_Full);
} else {
- ecmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(ecmd, SPEED_10);
ecmd->duplex = !!(nego & ADVERTISED_10baseT_Full);
}
} else {
ecmd->autoneg = AUTONEG_DISABLE;
- ecmd->speed = ((bmcr & BMCR_SPEED1000 &&
- (bmcr & BMCR_SPEED100) == 0) ? SPEED_1000 :
- (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10);
+ ethtool_cmd_speed_set(ecmd,
+ ((bmcr & BMCR_SPEED1000 &&
+ (bmcr & BMCR_SPEED100) == 0) ?
+ SPEED_1000 :
+ ((bmcr & BMCR_SPEED100) ?
+ SPEED_100 : SPEED_10)));
ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
}
@@ -158,10 +164,11 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
{
struct net_device *dev = mii->dev;
+ u32 speed = ethtool_cmd_speed(ecmd);
- if (ecmd->speed != SPEED_10 &&
- ecmd->speed != SPEED_100 &&
- ecmd->speed != SPEED_1000)
+ if (speed != SPEED_10 &&
+ speed != SPEED_100 &&
+ speed != SPEED_1000)
return -EINVAL;
if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
return -EINVAL;
@@ -173,7 +180,7 @@ int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
return -EINVAL;
if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
return -EINVAL;
- if ((ecmd->speed == SPEED_1000) && (!mii->supports_gmii))
+ if ((speed == SPEED_1000) && (!mii->supports_gmii))
return -EINVAL;
/* ignore supported, maxtxpkt, maxrxpkt */
@@ -231,9 +238,9 @@ int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 |
BMCR_SPEED1000 | BMCR_FULLDPLX);
- if (ecmd->speed == SPEED_1000)
+ if (speed == SPEED_1000)
tmp |= BMCR_SPEED1000;
- else if (ecmd->speed == SPEED_100)
+ else if (speed == SPEED_100)
tmp |= BMCR_SPEED100;
if (ecmd->duplex == DUPLEX_FULL) {
tmp |= BMCR_FULLDPLX;
diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c
index d54b7abf022..2e858e4dcf4 100644
--- a/drivers/net/mlx4/en_ethtool.c
+++ b/drivers/net/mlx4/en_ethtool.c
@@ -57,37 +57,6 @@ mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
drvinfo->eedump_len = 0;
}
-static u32 mlx4_en_get_tso(struct net_device *dev)
-{
- return (dev->features & NETIF_F_TSO) != 0;
-}
-
-static int mlx4_en_set_tso(struct net_device *dev, u32 data)
-{
- struct mlx4_en_priv *priv = netdev_priv(dev);
-
- if (data) {
- if (!priv->mdev->LSO_support)
- return -EPERM;
- dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
- } else
- dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
- return 0;
-}
-
-static u32 mlx4_en_get_rx_csum(struct net_device *dev)
-{
- struct mlx4_en_priv *priv = netdev_priv(dev);
- return priv->rx_csum;
-}
-
-static int mlx4_en_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct mlx4_en_priv *priv = netdev_priv(dev);
- priv->rx_csum = (data != 0);
- return 0;
-}
-
static const char main_strings[][ETH_GSTRING_LEN] = {
"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
@@ -296,10 +265,10 @@ static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
trans_type = priv->port_state.transciver;
if (netif_carrier_ok(dev)) {
- cmd->speed = priv->port_state.link_speed;
+ ethtool_cmd_speed_set(cmd, priv->port_state.link_speed);
cmd->duplex = DUPLEX_FULL;
} else {
- cmd->speed = -1;
+ ethtool_cmd_speed_set(cmd, -1);
cmd->duplex = -1;
}
@@ -323,7 +292,8 @@ static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int mlx4_en_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
if ((cmd->autoneg == AUTONEG_ENABLE) ||
- (cmd->speed != SPEED_10000) || (cmd->duplex != DUPLEX_FULL))
+ (ethtool_cmd_speed(cmd) != SPEED_10000) ||
+ (cmd->duplex != DUPLEX_FULL))
return -EINVAL;
/* Nothing to change */
@@ -483,17 +453,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
.get_drvinfo = mlx4_en_get_drvinfo,
.get_settings = mlx4_en_get_settings,
.set_settings = mlx4_en_set_settings,
-#ifdef NETIF_F_TSO
- .get_tso = mlx4_en_get_tso,
- .set_tso = mlx4_en_set_tso,
-#endif
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
.get_link = ethtool_op_get_link,
- .get_rx_csum = mlx4_en_get_rx_csum,
- .set_rx_csum = mlx4_en_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_ipv6_csum,
.get_strings = mlx4_en_get_strings,
.get_sset_count = mlx4_en_get_sset_count,
.get_ethtool_stats = mlx4_en_get_ethtool_stats,
@@ -508,7 +468,6 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
.set_pauseparam = mlx4_en_set_pauseparam,
.get_ringparam = mlx4_en_get_ringparam,
.set_ringparam = mlx4_en_set_ringparam,
- .get_flags = ethtool_op_get_flags,
};
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index 77063f91c56..61850adae6f 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -1083,7 +1083,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
priv->prof = prof;
priv->port = port;
priv->port_up = false;
- priv->rx_csum = 1;
priv->flags = prof->flags;
priv->tx_ring_num = prof->tx_ring_num;
priv->rx_ring_num = prof->rx_ring_num;
@@ -1141,21 +1140,16 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
/*
* Set driver features
*/
- dev->features |= NETIF_F_SG;
- dev->vlan_features |= NETIF_F_SG;
- dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
- dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
- dev->features |= NETIF_F_HIGHDMA;
- dev->features |= NETIF_F_HW_VLAN_TX |
- NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_FILTER;
- dev->features |= NETIF_F_GRO;
- if (mdev->LSO_support) {
- dev->features |= NETIF_F_TSO;
- dev->features |= NETIF_F_TSO6;
- dev->vlan_features |= NETIF_F_TSO;
- dev->vlan_features |= NETIF_F_TSO6;
- }
+ dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+ if (mdev->LSO_support)
+ dev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6;
+
+ dev->vlan_features = dev->hw_features;
+
+ dev->hw_features |= NETIF_F_RXCSUM;
+ dev->features = dev->hw_features | NETIF_F_HIGHDMA |
+ NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
+ NETIF_F_HW_VLAN_FILTER;
mdev->pndev[port] = dev;
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index 62dd21b06df..277215fb9d7 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -584,7 +584,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
ring->bytes += length;
ring->packets++;
- if (likely(priv->rx_csum)) {
+ if (likely(dev->features & NETIF_F_RXCSUM)) {
if ((cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPOK)) &&
(cqe->checksum == cpu_to_be16(0xffff))) {
priv->port_stats.rx_chksum_good++;
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
index e30f6099c0d..0b5150df058 100644
--- a/drivers/net/mlx4/mlx4_en.h
+++ b/drivers/net/mlx4/mlx4_en.h
@@ -451,7 +451,6 @@ struct mlx4_en_priv {
int registered;
int allocated;
int stride;
- int rx_csum;
u64 mac;
int mac_index;
unsigned max_mtu;
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 34425b94452..a5d9b1c310b 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1444,13 +1444,13 @@ mv643xx_eth_get_settings_phyless(struct mv643xx_eth_private *mp,
cmd->advertising = ADVERTISED_MII;
switch (port_status & PORT_SPEED_MASK) {
case PORT_SPEED_10:
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
break;
case PORT_SPEED_100:
- cmd->speed = SPEED_100;
+ ethtool_cmd_speed_set(cmd, SPEED_100);
break;
case PORT_SPEED_1000:
- cmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(cmd, SPEED_1000);
break;
default:
cmd->speed = -1;
@@ -1575,18 +1575,12 @@ mv643xx_eth_set_ringparam(struct net_device *dev, struct ethtool_ringparam *er)
return 0;
}
-static u32
-mv643xx_eth_get_rx_csum(struct net_device *dev)
-{
- struct mv643xx_eth_private *mp = netdev_priv(dev);
-
- return !!(rdlp(mp, PORT_CONFIG) & 0x02000000);
-}
static int
-mv643xx_eth_set_rx_csum(struct net_device *dev, u32 rx_csum)
+mv643xx_eth_set_features(struct net_device *dev, u32 features)
{
struct mv643xx_eth_private *mp = netdev_priv(dev);
+ u32 rx_csum = features & NETIF_F_RXCSUM;
wrlp(mp, PORT_CONFIG, rx_csum ? 0x02000000 : 0x00000000);
@@ -1634,11 +1628,6 @@ static void mv643xx_eth_get_ethtool_stats(struct net_device *dev,
}
}
-static int mv643xx_eth_set_flags(struct net_device *dev, u32 data)
-{
- return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO);
-}
-
static int mv643xx_eth_get_sset_count(struct net_device *dev, int sset)
{
if (sset == ETH_SS_STATS)
@@ -1657,14 +1646,8 @@ static const struct ethtool_ops mv643xx_eth_ethtool_ops = {
.set_coalesce = mv643xx_eth_set_coalesce,
.get_ringparam = mv643xx_eth_get_ringparam,
.set_ringparam = mv643xx_eth_set_ringparam,
- .get_rx_csum = mv643xx_eth_get_rx_csum,
- .set_rx_csum = mv643xx_eth_set_rx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .set_sg = ethtool_op_set_sg,
.get_strings = mv643xx_eth_get_strings,
.get_ethtool_stats = mv643xx_eth_get_ethtool_stats,
- .get_flags = ethtool_op_get_flags,
- .set_flags = mv643xx_eth_set_flags,
.get_sset_count = mv643xx_eth_get_sset_count,
};
@@ -2264,7 +2247,7 @@ static void port_start(struct mv643xx_eth_private *mp)
* frames to RX queue #0, and include the pseudo-header when
* calculating receive checksums.
*/
- wrlp(mp, PORT_CONFIG, 0x02000000);
+ mv643xx_eth_set_features(mp->dev, mp->dev->features);
/*
* Treat BPDUs as normal multicasts, and disable partition mode.
@@ -2848,6 +2831,7 @@ static const struct net_device_ops mv643xx_eth_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = mv643xx_eth_ioctl,
.ndo_change_mtu = mv643xx_eth_change_mtu,
+ .ndo_set_features = mv643xx_eth_set_features,
.ndo_tx_timeout = mv643xx_eth_tx_timeout,
.ndo_get_stats = mv643xx_eth_get_stats,
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -2930,7 +2914,9 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
dev->watchdog_timeo = 2 * HZ;
dev->base_addr = 0;
- dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
+ dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_RXCSUM | NETIF_F_LRO;
+ dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM;
SET_NETDEV_DEV(dev, &pdev->dev);
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 1446de59ae5..b1358f79ba0 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -205,7 +205,6 @@ struct myri10ge_priv {
int tx_boundary; /* boundary transmits cannot cross */
int num_slices;
int running; /* running? */
- int csum_flag; /* rx_csums? */
int small_bytes;
int big_bytes;
int max_intr_slots;
@@ -1386,7 +1385,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum,
skb->protocol = eth_type_trans(skb, dev);
skb_record_rx_queue(skb, ss - &mgp->ss[0]);
- if (mgp->csum_flag) {
+ if (dev->features & NETIF_F_RXCSUM) {
if ((skb->protocol == htons(ETH_P_IP)) ||
(skb->protocol == htons(ETH_P_IPV6))) {
skb->csum = csum;
@@ -1645,7 +1644,7 @@ myri10ge_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
int i;
cmd->autoneg = AUTONEG_DISABLE;
- cmd->speed = SPEED_10000;
+ ethtool_cmd_speed_set(cmd, SPEED_10000);
cmd->duplex = DUPLEX_FULL;
/*
@@ -1757,43 +1756,6 @@ myri10ge_get_ringparam(struct net_device *netdev,
ring->tx_pending = ring->tx_max_pending;
}
-static u32 myri10ge_get_rx_csum(struct net_device *netdev)
-{
- struct myri10ge_priv *mgp = netdev_priv(netdev);
-
- if (mgp->csum_flag)
- return 1;
- else
- return 0;
-}
-
-static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled)
-{
- struct myri10ge_priv *mgp = netdev_priv(netdev);
- int err = 0;
-
- if (csum_enabled)
- mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
- else {
- netdev->features &= ~NETIF_F_LRO;
- mgp->csum_flag = 0;
-
- }
- return err;
-}
-
-static int myri10ge_set_tso(struct net_device *netdev, u32 tso_enabled)
-{
- struct myri10ge_priv *mgp = netdev_priv(netdev);
- u32 flags = mgp->features & (NETIF_F_TSO6 | NETIF_F_TSO);
-
- if (tso_enabled)
- netdev->features |= flags;
- else
- netdev->features &= ~flags;
- return 0;
-}
-
static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = {
"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
@@ -1944,11 +1906,6 @@ static u32 myri10ge_get_msglevel(struct net_device *netdev)
return mgp->msg_enable;
}
-static int myri10ge_set_flags(struct net_device *netdev, u32 value)
-{
- return ethtool_op_set_flags(netdev, value, ETH_FLAG_LRO);
-}
-
static const struct ethtool_ops myri10ge_ethtool_ops = {
.get_settings = myri10ge_get_settings,
.get_drvinfo = myri10ge_get_drvinfo,
@@ -1957,19 +1914,12 @@ static const struct ethtool_ops myri10ge_ethtool_ops = {
.get_pauseparam = myri10ge_get_pauseparam,
.set_pauseparam = myri10ge_set_pauseparam,
.get_ringparam = myri10ge_get_ringparam,
- .get_rx_csum = myri10ge_get_rx_csum,
- .set_rx_csum = myri10ge_set_rx_csum,
- .set_tx_csum = ethtool_op_set_tx_hw_csum,
- .set_sg = ethtool_op_set_sg,
- .set_tso = myri10ge_set_tso,
.get_link = ethtool_op_get_link,
.get_strings = myri10ge_get_strings,
.get_sset_count = myri10ge_get_sset_count,
.get_ethtool_stats = myri10ge_get_ethtool_stats,
.set_msglevel = myri10ge_set_msglevel,
.get_msglevel = myri10ge_get_msglevel,
- .get_flags = ethtool_op_get_flags,
- .set_flags = myri10ge_set_flags
};
static int myri10ge_allocate_rings(struct myri10ge_slice_state *ss)
@@ -3136,6 +3086,14 @@ static int myri10ge_set_mac_address(struct net_device *dev, void *addr)
return 0;
}
+static u32 myri10ge_fix_features(struct net_device *dev, u32 features)
+{
+ if (!(features & NETIF_F_RXCSUM))
+ features &= ~NETIF_F_LRO;
+
+ return features;
+}
+
static int myri10ge_change_mtu(struct net_device *dev, int new_mtu)
{
struct myri10ge_priv *mgp = netdev_priv(dev);
@@ -3834,6 +3792,7 @@ static const struct net_device_ops myri10ge_netdev_ops = {
.ndo_get_stats = myri10ge_get_stats,
.ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = myri10ge_change_mtu,
+ .ndo_fix_features = myri10ge_fix_features,
.ndo_set_multicast_list = myri10ge_set_multicast_list,
.ndo_set_mac_address = myri10ge_set_mac_address,
};
@@ -3860,7 +3819,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
mgp = netdev_priv(netdev);
mgp->dev = netdev;
mgp->pdev = pdev;
- mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
mgp->pause = myri10ge_flow_control;
mgp->intr_coal_delay = myri10ge_intr_coal_delay;
mgp->msg_enable = netif_msg_init(myri10ge_debug, MYRI10GE_MSG_DEFAULT);
@@ -3976,11 +3934,11 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->netdev_ops = &myri10ge_netdev_ops;
netdev->mtu = myri10ge_initial_mtu;
netdev->base_addr = mgp->iomem_base;
- netdev->features = mgp->features;
+ netdev->hw_features = mgp->features | NETIF_F_LRO | NETIF_F_RXCSUM;
+ netdev->features = netdev->hw_features;
if (dac_enabled)
netdev->features |= NETIF_F_HIGHDMA;
- netdev->features |= NETIF_F_LRO;
netdev->vlan_features |= mgp->features;
if (mgp->fw_ver_tiny < 37)
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 1074231f0a0..b78be088c4a 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -2820,7 +2820,7 @@ static int netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
u32 tmp;
ecmd->port = dev->if_port;
- ecmd->speed = np->speed;
+ ethtool_cmd_speed_set(ecmd, np->speed);
ecmd->duplex = np->duplex;
ecmd->autoneg = np->autoneg;
ecmd->advertising = 0;
@@ -2878,9 +2878,9 @@ static int netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
tmp = mii_nway_result(
np->advertising & mdio_read(dev, MII_LPA));
if (tmp == LPA_100FULL || tmp == LPA_100HALF)
- ecmd->speed = SPEED_100;
+ ethtool_cmd_speed_set(ecmd, SPEED_100);
else
- ecmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(ecmd, SPEED_10);
if (tmp == LPA_100FULL || tmp == LPA_10FULL)
ecmd->duplex = DUPLEX_FULL;
else
@@ -2908,7 +2908,8 @@ static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
return -EINVAL;
}
} else if (ecmd->autoneg == AUTONEG_DISABLE) {
- if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100)
+ u32 speed = ethtool_cmd_speed(ecmd);
+ if (speed != SPEED_10 && speed != SPEED_100)
return -EINVAL;
if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
return -EINVAL;
@@ -2956,7 +2957,7 @@ static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
if (ecmd->advertising & ADVERTISED_100baseT_Full)
np->advertising |= ADVERTISE_100FULL;
} else {
- np->speed = ecmd->speed;
+ np->speed = ethtool_cmd_speed(ecmd);
np->duplex = ecmd->duplex;
/* user overriding the initial full duplex parm? */
if (np->duplex == DUPLEX_HALF)
diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c
index 243ed2aee88..e8984b0ca52 100644
--- a/drivers/net/ne3210.c
+++ b/drivers/net/ne3210.c
@@ -80,17 +80,20 @@ static void ne3210_block_output(struct net_device *dev, int count, const unsigne
#define NE3210_DEBUG 0x0
-static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
-static unsigned int shmem_map[] __initdata = {0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0};
-static const char *ifmap[] __initdata = {"UTP", "?", "BNC", "AUI"};
-static int ifmap_val[] __initdata = {
+static const unsigned char irq_map[] __devinitconst =
+ { 15, 12, 11, 10, 9, 7, 5, 3 };
+static const unsigned int shmem_map[] __devinitconst =
+ { 0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0 };
+static const char *const ifmap[] __devinitconst =
+ { "UTP", "?", "BNC", "AUI" };
+static const int ifmap_val[] __devinitconst = {
IF_PORT_10BASET,
IF_PORT_UNKNOWN,
IF_PORT_10BASE2,
IF_PORT_AUI,
};
-static int __init ne3210_eisa_probe (struct device *device)
+static int __devinit ne3210_eisa_probe (struct device *device)
{
unsigned long ioaddr, phys_mem;
int i, retval, port_index;
@@ -313,7 +316,7 @@ static void ne3210_block_output(struct net_device *dev, int count,
memcpy_toio(shmem, buf, count);
}
-static struct eisa_device_id ne3210_ids[] = {
+static const struct eisa_device_id ne3210_ids[] __devinitconst = {
{ "EGL0101" },
{ "NVL1801" },
{ "" },
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index eb41e44921e..a83e101440f 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -242,34 +242,6 @@ static struct netconsole_target *to_target(struct config_item *item)
}
/*
- * Wrapper over simple_strtol (base 10) with sanity and range checking.
- * We return (signed) long only because we may want to return errors.
- * Do not use this to convert numbers that are allowed to be negative.
- */
-static long strtol10_check_range(const char *cp, long min, long max)
-{
- long ret;
- char *p = (char *) cp;
-
- WARN_ON(min < 0);
- WARN_ON(max < min);
-
- ret = simple_strtol(p, &p, 10);
-
- if (*p && (*p != '\n')) {
- printk(KERN_ERR "netconsole: invalid input\n");
- return -EINVAL;
- }
- if ((ret < min) || (ret > max)) {
- printk(KERN_ERR "netconsole: input %ld must be between "
- "%ld and %ld\n", ret, min, max);
- return -EINVAL;
- }
-
- return ret;
-}
-
-/*
* Attribute operations for netconsole_target.
*/
@@ -327,12 +299,14 @@ static ssize_t store_enabled(struct netconsole_target *nt,
const char *buf,
size_t count)
{
+ int enabled;
int err;
- long enabled;
- enabled = strtol10_check_range(buf, 0, 1);
- if (enabled < 0)
- return enabled;
+ err = kstrtoint(buf, 10, &enabled);
+ if (err < 0)
+ return err;
+ if (enabled < 0 || enabled > 1)
+ return -EINVAL;
if (enabled) { /* 1 */
@@ -384,8 +358,7 @@ static ssize_t store_local_port(struct netconsole_target *nt,
const char *buf,
size_t count)
{
- long local_port;
-#define __U16_MAX ((__u16) ~0U)
+ int rv;
if (nt->enabled) {
printk(KERN_ERR "netconsole: target (%s) is enabled, "
@@ -394,12 +367,9 @@ static ssize_t store_local_port(struct netconsole_target *nt,
return -EINVAL;
}
- local_port = strtol10_check_range(buf, 0, __U16_MAX);
- if (local_port < 0)
- return local_port;
-
- nt->np.local_port = local_port;
-
+ rv = kstrtou16(buf, 10, &nt->np.local_port);
+ if (rv < 0)
+ return rv;
return strnlen(buf, count);
}
@@ -407,8 +377,7 @@ static ssize_t store_remote_port(struct netconsole_target *nt,
const char *buf,
size_t count)
{
- long remote_port;
-#define __U16_MAX ((__u16) ~0U)
+ int rv;
if (nt->enabled) {
printk(KERN_ERR "netconsole: target (%s) is enabled, "
@@ -417,12 +386,9 @@ static ssize_t store_remote_port(struct netconsole_target *nt,
return -EINVAL;
}
- remote_port = strtol10_check_range(buf, 0, __U16_MAX);
- if (remote_port < 0)
- return remote_port;
-
- nt->np.remote_port = remote_port;
-
+ rv = kstrtou16(buf, 10, &nt->np.remote_port);
+ if (rv < 0)
+ return rv;
return strnlen(buf, count);
}
@@ -463,8 +429,6 @@ static ssize_t store_remote_mac(struct netconsole_target *nt,
size_t count)
{
u8 remote_mac[ETH_ALEN];
- char *p = (char *) buf;
- int i;
if (nt->enabled) {
printk(KERN_ERR "netconsole: target (%s) is enabled, "
@@ -473,23 +437,13 @@ static ssize_t store_remote_mac(struct netconsole_target *nt,
return -EINVAL;
}
- for (i = 0; i < ETH_ALEN - 1; i++) {
- remote_mac[i] = simple_strtoul(p, &p, 16);
- if (*p != ':')
- goto invalid;
- p++;
- }
- remote_mac[ETH_ALEN - 1] = simple_strtoul(p, &p, 16);
- if (*p && (*p != '\n'))
- goto invalid;
-
+ if (!mac_pton(buf, remote_mac))
+ return -EINVAL;
+ if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n')
+ return -EINVAL;
memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN);
return strnlen(buf, count);
-
-invalid:
- printk(KERN_ERR "netconsole: invalid input\n");
- return -EINVAL;
}
/*
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 679dc8519c5..77220687b92 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1177,7 +1177,7 @@ struct netxen_adapter {
u8 max_sds_rings;
u8 driver_mismatch;
u8 msix_supported;
- u8 rx_csum;
+ u8 __pad;
u8 pci_using_dac;
u8 portnum;
u8 physical_port;
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 3bdcc803ec6..b34fb74d07e 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -117,7 +117,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->port = PORT_TP;
- ecmd->speed = adapter->link_speed;
+ ethtool_cmd_speed_set(ecmd, adapter->link_speed);
ecmd->duplex = adapter->link_duplex;
ecmd->autoneg = adapter->link_autoneg;
@@ -134,7 +134,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
}
if (netif_running(dev) && adapter->has_link_events) {
- ecmd->speed = adapter->link_speed;
+ ethtool_cmd_speed_set(ecmd, adapter->link_speed);
ecmd->autoneg = adapter->link_autoneg;
ecmd->duplex = adapter->link_duplex;
goto skip;
@@ -146,10 +146,10 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
u16 pcifn = adapter->ahw.pci_func;
val = NXRD32(adapter, P3_LINK_SPEED_REG(pcifn));
- ecmd->speed = P3_LINK_SPEED_MHZ *
- P3_LINK_SPEED_VAL(pcifn, val);
+ ethtool_cmd_speed_set(ecmd, P3_LINK_SPEED_MHZ *
+ P3_LINK_SPEED_VAL(pcifn, val));
} else
- ecmd->speed = SPEED_10000;
+ ethtool_cmd_speed_set(ecmd, SPEED_10000);
ecmd->duplex = DUPLEX_FULL;
ecmd->autoneg = AUTONEG_DISABLE;
@@ -251,6 +251,7 @@ static int
netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
struct netxen_adapter *adapter = netdev_priv(dev);
+ u32 speed = ethtool_cmd_speed(ecmd);
int ret;
if (adapter->ahw.port_type != NETXEN_NIC_GBE)
@@ -259,14 +260,14 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
if (!(adapter->capabilities & NX_FW_CAPABILITY_GBE_LINK_CFG))
return -EOPNOTSUPP;
- ret = nx_fw_cmd_set_gbe_port(adapter, ecmd->speed, ecmd->duplex,
+ ret = nx_fw_cmd_set_gbe_port(adapter, speed, ecmd->duplex,
ecmd->autoneg);
if (ret == NX_RCODE_NOT_SUPPORTED)
return -EOPNOTSUPP;
else if (ret)
return -EIO;
- adapter->link_speed = ecmd->speed;
+ adapter->link_speed = speed;
adapter->link_duplex = ecmd->duplex;
adapter->link_autoneg = ecmd->autoneg;
@@ -676,62 +677,6 @@ netxen_nic_get_ethtool_stats(struct net_device *dev,
}
}
-static u32 netxen_nic_get_tx_csum(struct net_device *dev)
-{
- return dev->features & NETIF_F_IP_CSUM;
-}
-
-static u32 netxen_nic_get_rx_csum(struct net_device *dev)
-{
- struct netxen_adapter *adapter = netdev_priv(dev);
- return adapter->rx_csum;
-}
-
-static int netxen_nic_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct netxen_adapter *adapter = netdev_priv(dev);
-
- if (data) {
- adapter->rx_csum = data;
- return 0;
- }
-
- if (dev->features & NETIF_F_LRO) {
- if (netxen_config_hw_lro(adapter, NETXEN_NIC_LRO_DISABLED))
- return -EIO;
-
- dev->features &= ~NETIF_F_LRO;
- netxen_send_lro_cleanup(adapter);
- netdev_info(dev, "disabling LRO as rx_csum is off\n");
- }
- adapter->rx_csum = data;
- return 0;
-}
-
-static u32 netxen_nic_get_tso(struct net_device *dev)
-{
- struct netxen_adapter *adapter = netdev_priv(dev);
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0;
-
- return (dev->features & NETIF_F_TSO) != 0;
-}
-
-static int netxen_nic_set_tso(struct net_device *dev, u32 data)
-{
- if (data) {
- struct netxen_adapter *adapter = netdev_priv(dev);
-
- dev->features |= NETIF_F_TSO;
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- dev->features |= NETIF_F_TSO6;
- } else
- dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-
- return 0;
-}
-
static void
netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
@@ -866,43 +811,6 @@ static int netxen_get_intr_coalesce(struct net_device *netdev,
return 0;
}
-static int netxen_nic_set_flags(struct net_device *netdev, u32 data)
-{
- struct netxen_adapter *adapter = netdev_priv(netdev);
- int hw_lro;
-
- if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
- return -EINVAL;
-
- if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO))
- return -EINVAL;
-
- if (!adapter->rx_csum) {
- netdev_info(netdev, "rx csum is off, cannot toggle LRO\n");
- return -EINVAL;
- }
-
- if (!!(data & ETH_FLAG_LRO) == !!(netdev->features & NETIF_F_LRO))
- return 0;
-
- if (data & ETH_FLAG_LRO) {
- hw_lro = NETXEN_NIC_LRO_ENABLED;
- netdev->features |= NETIF_F_LRO;
- } else {
- hw_lro = NETXEN_NIC_LRO_DISABLED;
- netdev->features &= ~NETIF_F_LRO;
- }
-
- if (netxen_config_hw_lro(adapter, hw_lro))
- return -EIO;
-
- if ((hw_lro == 0) && netxen_send_lro_cleanup(adapter))
- return -EIO;
-
-
- return 0;
-}
-
const struct ethtool_ops netxen_nic_ethtool_ops = {
.get_settings = netxen_nic_get_settings,
.set_settings = netxen_nic_set_settings,
@@ -916,21 +824,12 @@ const struct ethtool_ops netxen_nic_ethtool_ops = {
.set_ringparam = netxen_nic_set_ringparam,
.get_pauseparam = netxen_nic_get_pauseparam,
.set_pauseparam = netxen_nic_set_pauseparam,
- .get_tx_csum = netxen_nic_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .set_sg = ethtool_op_set_sg,
- .get_tso = netxen_nic_get_tso,
- .set_tso = netxen_nic_set_tso,
.get_wol = netxen_nic_get_wol,
.set_wol = netxen_nic_set_wol,
.self_test = netxen_nic_diag_test,
.get_strings = netxen_nic_get_strings,
.get_ethtool_stats = netxen_nic_get_ethtool_stats,
.get_sset_count = netxen_get_sset_count,
- .get_rx_csum = netxen_nic_get_rx_csum,
- .set_rx_csum = netxen_nic_set_rx_csum,
.get_coalesce = netxen_get_intr_coalesce,
.set_coalesce = netxen_set_intr_coalesce,
- .get_flags = ethtool_op_get_flags,
- .set_flags = netxen_nic_set_flags,
};
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 731077d8d96..7f999671c7b 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -1483,7 +1483,8 @@ static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter,
if (!skb)
goto no_skb;
- if (likely(adapter->rx_csum && cksum == STATUS_CKSUM_OK)) {
+ if (likely((adapter->netdev->features & NETIF_F_RXCSUM)
+ && cksum == STATUS_CKSUM_OK)) {
adapter->stats.csummed++;
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index e8a4b665599..b644383017f 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -485,6 +485,37 @@ static void netxen_set_multicast_list(struct net_device *dev)
adapter->set_multi(dev);
}
+static u32 netxen_fix_features(struct net_device *dev, u32 features)
+{
+ if (!(features & NETIF_F_RXCSUM)) {
+ netdev_info(dev, "disabling LRO as RXCSUM is off\n");
+
+ features &= ~NETIF_F_LRO;
+ }
+
+ return features;
+}
+
+static int netxen_set_features(struct net_device *dev, u32 features)
+{
+ struct netxen_adapter *adapter = netdev_priv(dev);
+ int hw_lro;
+
+ if (!((dev->features ^ features) & NETIF_F_LRO))
+ return 0;
+
+ hw_lro = (features & NETIF_F_LRO) ? NETXEN_NIC_LRO_ENABLED
+ : NETXEN_NIC_LRO_DISABLED;
+
+ if (netxen_config_hw_lro(adapter, hw_lro))
+ return -EIO;
+
+ if (!(features & NETIF_F_LRO) && netxen_send_lro_cleanup(adapter))
+ return -EIO;
+
+ return 0;
+}
+
static const struct net_device_ops netxen_netdev_ops = {
.ndo_open = netxen_nic_open,
.ndo_stop = netxen_nic_close,
@@ -495,6 +526,8 @@ static const struct net_device_ops netxen_netdev_ops = {
.ndo_set_mac_address = netxen_nic_set_mac,
.ndo_change_mtu = netxen_nic_change_mtu,
.ndo_tx_timeout = netxen_tx_timeout,
+ .ndo_fix_features = netxen_fix_features,
+ .ndo_set_features = netxen_set_features,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = netxen_nic_poll_controller,
#endif
@@ -905,7 +938,7 @@ netxen_nic_request_irq(struct netxen_adapter *adapter)
struct nx_host_sds_ring *sds_ring;
int err, ring;
- unsigned long flags = IRQF_SAMPLE_RANDOM;
+ unsigned long flags = 0;
struct net_device *netdev = adapter->netdev;
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
@@ -1196,7 +1229,6 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
int err = 0;
struct pci_dev *pdev = adapter->pdev;
- adapter->rx_csum = 1;
adapter->mc_enabled = 0;
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
adapter->max_mc_count = 38;
@@ -1210,14 +1242,13 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
- netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
- netdev->features |= (NETIF_F_GRO);
- netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+ netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
+ NETIF_F_RXCSUM;
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
- netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
- netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
- }
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ netdev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
+
+ netdev->vlan_features |= netdev->hw_features;
if (adapter->pci_using_dac) {
netdev->features |= NETIF_F_HIGHDMA;
@@ -1225,10 +1256,12 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
}
if (adapter->capabilities & NX_FW_CAPABILITY_FVLANTX)
- netdev->features |= (NETIF_F_HW_VLAN_TX);
+ netdev->hw_features |= NETIF_F_HW_VLAN_TX;
if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)
- netdev->features |= NETIF_F_LRO;
+ netdev->hw_features |= NETIF_F_LRO;
+
+ netdev->features |= netdev->hw_features;
netdev->irq = adapter->msix_entries[0].vector;
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 32678b6c6b3..cc25bff0bd3 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -1233,7 +1233,7 @@ static int link_status_1g_rgmii(struct niu *np, int *link_up_p)
bmsr = err;
if (bmsr & BMSR_LSTATUS) {
- u16 adv, lpa, common, estat;
+ u16 adv, lpa;
err = mii_read(np, np->phy_addr, MII_ADVERTISE);
if (err < 0)
@@ -1245,12 +1245,9 @@ static int link_status_1g_rgmii(struct niu *np, int *link_up_p)
goto out;
lpa = err;
- common = adv & lpa;
-
err = mii_read(np, np->phy_addr, MII_ESTATUS);
if (err < 0)
goto out;
- estat = err;
link_up = 1;
current_speed = SPEED_1000;
current_duplex = DUPLEX_FULL;
@@ -1650,7 +1647,7 @@ static int xcvr_init_10g(struct niu *np)
break;
}
- return 0;
+ return err;
}
static int mii_reset(struct niu *np)
@@ -2381,17 +2378,14 @@ static int serdes_init_10g_serdes(struct niu *np)
struct niu_link_config *lp = &np->link_config;
unsigned long ctrl_reg, test_cfg_reg, pll_cfg, i;
u64 ctrl_val, test_cfg_val, sig, mask, val;
- u64 reset_val;
switch (np->port) {
case 0:
- reset_val = ENET_SERDES_RESET_0;
ctrl_reg = ENET_SERDES_0_CTRL_CFG;
test_cfg_reg = ENET_SERDES_0_TEST_CFG;
pll_cfg = ENET_SERDES_0_PLL_CFG;
break;
case 1:
- reset_val = ENET_SERDES_RESET_1;
ctrl_reg = ENET_SERDES_1_CTRL_CFG;
test_cfg_reg = ENET_SERDES_1_TEST_CFG;
pll_cfg = ENET_SERDES_1_PLL_CFG;
@@ -6071,8 +6065,7 @@ static int niu_request_irq(struct niu *np)
for (i = 0; i < np->num_ldg; i++) {
struct niu_ldg *lp = &np->ldg[i];
- err = request_irq(lp->irq, niu_interrupt,
- IRQF_SHARED | IRQF_SAMPLE_RANDOM,
+ err = request_irq(lp->irq, niu_interrupt, IRQF_SHARED,
np->irq_name[i], lp);
if (err)
goto out_free_irqs;
@@ -6851,7 +6844,7 @@ static int niu_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->supported = lp->supported;
cmd->advertising = lp->active_advertising;
cmd->autoneg = lp->active_autoneg;
- cmd->speed = lp->active_speed;
+ ethtool_cmd_speed_set(cmd, lp->active_speed);
cmd->duplex = lp->active_duplex;
cmd->port = (np->flags & NIU_FLAGS_FIBER) ? PORT_FIBRE : PORT_TP;
cmd->transceiver = (np->flags & NIU_FLAGS_XCVR_SERDES) ?
@@ -6866,7 +6859,7 @@ static int niu_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
struct niu_link_config *lp = &np->link_config;
lp->advertising = cmd->advertising;
- lp->speed = cmd->speed;
+ lp->speed = ethtool_cmd_speed(cmd);
lp->duplex = cmd->duplex;
lp->autoneg = cmd->autoneg;
return niu_init_link(np);
@@ -7023,6 +7016,7 @@ static int niu_ethflow_to_class(int flow_type, u64 *class)
case UDP_V4_FLOW:
*class = CLASS_CODE_UDP_IPV4;
break;
+ case AH_ESP_V4_FLOW:
case AH_V4_FLOW:
case ESP_V4_FLOW:
*class = CLASS_CODE_AH_ESP_IPV4;
@@ -7036,6 +7030,7 @@ static int niu_ethflow_to_class(int flow_type, u64 *class)
case UDP_V6_FLOW:
*class = CLASS_CODE_UDP_IPV6;
break;
+ case AH_ESP_V6_FLOW:
case AH_V6_FLOW:
case ESP_V6_FLOW:
*class = CLASS_CODE_AH_ESP_IPV6;
@@ -7889,37 +7884,35 @@ static void niu_force_led(struct niu *np, int on)
nw64_mac(reg, val);
}
-static int niu_phys_id(struct net_device *dev, u32 data)
+static int niu_set_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
+
{
struct niu *np = netdev_priv(dev);
- u64 orig_led_state;
- int i;
if (!netif_running(dev))
return -EAGAIN;
- if (data == 0)
- data = 2;
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ np->orig_led_state = niu_led_state_save(np);
+ return 1; /* cycle on/off once per second */
- orig_led_state = niu_led_state_save(np);
- for (i = 0; i < (data * 2); i++) {
- int on = ((i % 2) == 0);
+ case ETHTOOL_ID_ON:
+ niu_force_led(np, 1);
+ break;
- niu_force_led(np, on);
+ case ETHTOOL_ID_OFF:
+ niu_force_led(np, 0);
+ break;
- if (msleep_interruptible(500))
- break;
+ case ETHTOOL_ID_INACTIVE:
+ niu_led_state_restore(np, np->orig_led_state);
}
- niu_led_state_restore(np, orig_led_state);
return 0;
}
-static int niu_set_flags(struct net_device *dev, u32 data)
-{
- return ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH);
-}
-
static const struct ethtool_ops niu_ethtool_ops = {
.get_drvinfo = niu_get_drvinfo,
.get_link = ethtool_op_get_link,
@@ -7933,11 +7926,9 @@ static const struct ethtool_ops niu_ethtool_ops = {
.get_strings = niu_get_strings,
.get_sset_count = niu_get_sset_count,
.get_ethtool_stats = niu_get_ethtool_stats,
- .phys_id = niu_phys_id,
+ .set_phys_id = niu_set_phys_id,
.get_rxnfc = niu_get_nfc,
.set_rxnfc = niu_set_nfc,
- .set_flags = niu_set_flags,
- .get_flags = ethtool_op_get_flags,
};
static int niu_ldg_assign_ldn(struct niu *np, struct niu_parent *parent,
@@ -8131,7 +8122,7 @@ static int __devinit niu_pci_vpd_scan_props(struct niu *np,
netif_printk(np, probe, KERN_DEBUG, np->dev,
"VPD_SCAN: start[%x] end[%x]\n", start, end);
while (start < end) {
- int len, err, instance, type, prop_len;
+ int len, err, prop_len;
char namebuf[64];
u8 *prop_buf;
int max_len;
@@ -8147,8 +8138,6 @@ static int __devinit niu_pci_vpd_scan_props(struct niu *np,
len = err;
start += 3;
- instance = niu_pci_eeprom_read(np, start);
- type = niu_pci_eeprom_read(np, start + 3);
prop_len = niu_pci_eeprom_read(np, start + 4);
err = niu_pci_vpd_get_propname(np, start + 5, namebuf, 64);
if (err < 0)
@@ -9768,8 +9757,8 @@ static void __devinit niu_device_announce(struct niu *np)
static void __devinit niu_set_basic_features(struct net_device *dev)
{
- dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM |
- NETIF_F_GRO | NETIF_F_RXHASH);
+ dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXHASH;
+ dev->features |= dev->hw_features | NETIF_F_RXCSUM;
}
static int __devinit niu_pci_init_one(struct pci_dev *pdev,
diff --git a/drivers/net/niu.h b/drivers/net/niu.h
index a41fa8ebe05..51e177e1860 100644
--- a/drivers/net/niu.h
+++ b/drivers/net/niu.h
@@ -3279,6 +3279,7 @@ struct niu {
unsigned long xpcs_off;
struct timer_list timer;
+ u64 orig_led_state;
const struct niu_phy_ops *phy_ops;
int phy_addr;
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 6667e0667a8..3e4040f2f3c 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -1251,7 +1251,7 @@ static int ns83820_get_settings(struct net_device *ndev,
/*
* Here's the list of available ethtool commands from other drivers:
* cmd->advertising =
- * cmd->speed =
+ * ethtool_cmd_speed_set(cmd, ...)
* cmd->duplex =
* cmd->port = 0;
* cmd->phy_address =
@@ -1289,13 +1289,13 @@ static int ns83820_get_settings(struct net_device *ndev,
cmd->duplex = fullduplex ? DUPLEX_FULL : DUPLEX_HALF;
switch (cfg / CFG_SPDSTS0 & 3) {
case 2:
- cmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(cmd, SPEED_1000);
break;
case 1:
- cmd->speed = SPEED_100;
+ ethtool_cmd_speed_set(cmd, SPEED_100);
break;
default:
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
break;
}
cmd->autoneg = (tbicr & TBICR_MR_AN_ENABLE)
diff --git a/drivers/net/pch_gbe/pch_gbe.h b/drivers/net/pch_gbe/pch_gbe.h
index bf126e76fab..59fac77d0db 100644
--- a/drivers/net/pch_gbe/pch_gbe.h
+++ b/drivers/net/pch_gbe/pch_gbe.h
@@ -597,8 +597,6 @@ struct pch_gbe_hw_stats {
* @rx_ring: Pointer of Rx descriptor ring structure
* @rx_buffer_len: Receive buffer length
* @tx_queue_len: Transmit queue length
- * @rx_csum: Receive TCP/IP checksum enable/disable
- * @tx_csum: Transmit TCP/IP checksum enable/disable
* @have_msi: PCI MSI mode flag
*/
@@ -623,8 +621,6 @@ struct pch_gbe_adapter {
struct pch_gbe_rx_ring *rx_ring;
unsigned long rx_buffer_len;
unsigned long tx_queue_len;
- bool rx_csum;
- bool tx_csum;
bool have_msi;
};
diff --git a/drivers/net/pch_gbe/pch_gbe_ethtool.c b/drivers/net/pch_gbe/pch_gbe_ethtool.c
index d2174a40d70..ea2d8e41887 100644
--- a/drivers/net/pch_gbe/pch_gbe_ethtool.c
+++ b/drivers/net/pch_gbe/pch_gbe_ethtool.c
@@ -92,7 +92,7 @@ static int pch_gbe_get_settings(struct net_device *netdev,
ecmd->advertising &= ~(ADVERTISED_TP | ADVERTISED_1000baseT_Half);
if (!netif_carrier_ok(adapter->netdev))
- ecmd->speed = -1;
+ ethtool_cmd_speed_set(ecmd, -1);
return ret;
}
@@ -109,12 +109,15 @@ static int pch_gbe_set_settings(struct net_device *netdev,
{
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
struct pch_gbe_hw *hw = &adapter->hw;
+ u32 speed = ethtool_cmd_speed(ecmd);
int ret;
pch_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET);
- if (ecmd->speed == USHRT_MAX) {
- ecmd->speed = SPEED_1000;
+ /* when set_settings() is called with a ethtool_cmd previously
+ * filled by get_settings() on a down link, speed is -1: */
+ if (speed == UINT_MAX) {
+ speed = SPEED_1000;
ecmd->duplex = DUPLEX_FULL;
}
ret = mii_ethtool_sset(&adapter->mii, ecmd);
@@ -122,7 +125,7 @@ static int pch_gbe_set_settings(struct net_device *netdev,
pr_err("Error: mii_ethtool_sset\n");
return ret;
}
- hw->mac.link_speed = ecmd->speed;
+ hw->mac.link_speed = speed;
hw->mac.link_duplex = ecmd->duplex;
hw->phy.autoneg_advertised = ecmd->advertising;
hw->mac.autoneg = ecmd->autoneg;
@@ -434,57 +437,6 @@ static int pch_gbe_set_pauseparam(struct net_device *netdev,
}
/**
- * pch_gbe_get_rx_csum - Report whether receive checksums are turned on or off
- * @netdev: Network interface device structure
- * Returns
- * true(1): Checksum On
- * false(0): Checksum Off
- */
-static u32 pch_gbe_get_rx_csum(struct net_device *netdev)
-{
- struct pch_gbe_adapter *adapter = netdev_priv(netdev);
-
- return adapter->rx_csum;
-}
-
-/**
- * pch_gbe_set_rx_csum - Turn receive checksum on or off
- * @netdev: Network interface device structure
- * @data: Checksum On[true] or Off[false]
- * Returns
- * 0: Successful.
- * Negative value: Failed.
- */
-static int pch_gbe_set_rx_csum(struct net_device *netdev, u32 data)
-{
- struct pch_gbe_adapter *adapter = netdev_priv(netdev);
-
- adapter->rx_csum = data;
- if ((netif_running(netdev)))
- pch_gbe_reinit_locked(adapter);
- else
- pch_gbe_reset(adapter);
-
- return 0;
-}
-
-/**
- * pch_gbe_set_tx_csum - Turn transmit checksums on or off
- * @netdev: Network interface device structure
- * @data: Checksum on[true] or off[false]
- * Returns
- * 0: Successful.
- * Negative value: Failed.
- */
-static int pch_gbe_set_tx_csum(struct net_device *netdev, u32 data)
-{
- struct pch_gbe_adapter *adapter = netdev_priv(netdev);
-
- adapter->tx_csum = data;
- return ethtool_op_set_tx_ipv6_csum(netdev, data);
-}
-
-/**
* pch_gbe_get_strings - Return a set of strings that describe the requested
* objects
* @netdev: Network interface device structure
@@ -554,9 +506,6 @@ static const struct ethtool_ops pch_gbe_ethtool_ops = {
.set_ringparam = pch_gbe_set_ringparam,
.get_pauseparam = pch_gbe_get_pauseparam,
.set_pauseparam = pch_gbe_set_pauseparam,
- .get_rx_csum = pch_gbe_get_rx_csum,
- .set_rx_csum = pch_gbe_set_rx_csum,
- .set_tx_csum = pch_gbe_set_tx_csum,
.get_strings = pch_gbe_get_strings,
.get_ethtool_stats = pch_gbe_get_ethtool_stats,
.get_sset_count = pch_gbe_get_sset_count,
diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c
index 56d049a472d..c2476fd9657 100644
--- a/drivers/net/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/pch_gbe/pch_gbe_main.c
@@ -659,6 +659,7 @@ static void pch_gbe_configure_tx(struct pch_gbe_adapter *adapter)
*/
static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter)
{
+ struct net_device *netdev = adapter->netdev;
struct pch_gbe_hw *hw = &adapter->hw;
u32 rx_mode, tcpip;
@@ -669,7 +670,7 @@ static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter)
tcpip = ioread32(&hw->reg->TCPIP_ACC);
- if (adapter->rx_csum) {
+ if (netdev->features & NETIF_F_RXCSUM) {
tcpip &= ~PCH_GBE_RX_TCPIPACC_OFF;
tcpip |= PCH_GBE_RX_TCPIPACC_EN;
} else {
@@ -890,12 +891,12 @@ static void pch_gbe_watchdog(unsigned long data)
struct pch_gbe_adapter *adapter = (struct pch_gbe_adapter *)data;
struct net_device *netdev = adapter->netdev;
struct pch_gbe_hw *hw = &adapter->hw;
- struct ethtool_cmd cmd;
pr_debug("right now = %ld\n", jiffies);
pch_gbe_update_stats(adapter);
if ((mii_link_ok(&adapter->mii)) && (!netif_carrier_ok(netdev))) {
+ struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
netdev->tx_queue_len = adapter->tx_queue_len;
/* mii library handles link maintenance tasks */
if (mii_ethtool_gset(&adapter->mii, &cmd)) {
@@ -905,7 +906,7 @@ static void pch_gbe_watchdog(unsigned long data)
PCH_GBE_WATCHDOG_PERIOD));
return;
}
- hw->mac.link_speed = cmd.speed;
+ hw->mac.link_speed = ethtool_cmd_speed(&cmd);
hw->mac.link_duplex = cmd.duplex;
/* Set the RGMII control. */
pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed,
@@ -915,7 +916,7 @@ static void pch_gbe_watchdog(unsigned long data)
hw->mac.link_duplex);
netdev_dbg(netdev,
"Link is Up %d Mbps %s-Duplex\n",
- cmd.speed,
+ hw->mac.link_speed,
cmd.duplex == DUPLEX_FULL ? "Full" : "Half");
netif_carrier_on(netdev);
netif_wake_queue(netdev);
@@ -953,7 +954,7 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,
frame_ctrl = 0;
if (unlikely(skb->len < PCH_GBE_SHORT_PKT))
frame_ctrl |= PCH_GBE_TXD_CTRL_APAD;
- if (unlikely(!adapter->tx_csum))
+ if (skb->ip_summed == CHECKSUM_NONE)
frame_ctrl |= PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF;
/* Performs checksum processing */
@@ -961,7 +962,7 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,
* It is because the hardware accelerator does not support a checksum,
* when the received data size is less than 64 bytes.
*/
- if ((skb->len < PCH_GBE_SHORT_PKT) && (adapter->tx_csum)) {
+ if (skb->len < PCH_GBE_SHORT_PKT && skb->ip_summed != CHECKSUM_NONE) {
frame_ctrl |= PCH_GBE_TXD_CTRL_APAD |
PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF;
if (skb->protocol == htons(ETH_P_IP)) {
@@ -1429,7 +1430,7 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter,
length = (rx_desc->rx_words_eob) - 3;
/* Decide the data conversion method */
- if (!adapter->rx_csum) {
+ if (!(netdev->features & NETIF_F_RXCSUM)) {
/* [Header:14][payload] */
if (NET_IP_ALIGN) {
/* Because alignment differs,
@@ -2032,6 +2033,29 @@ static int pch_gbe_change_mtu(struct net_device *netdev, int new_mtu)
}
/**
+ * pch_gbe_set_features - Reset device after features changed
+ * @netdev: Network interface device structure
+ * @features: New features
+ * Returns
+ * 0: HW state updated successfully
+ */
+static int pch_gbe_set_features(struct net_device *netdev, u32 features)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ u32 changed = features ^ netdev->features;
+
+ if (!(changed & NETIF_F_RXCSUM))
+ return 0;
+
+ if (netif_running(netdev))
+ pch_gbe_reinit_locked(adapter);
+ else
+ pch_gbe_reset(adapter);
+
+ return 0;
+}
+
+/**
* pch_gbe_ioctl - Controls register through a MII interface
* @netdev: Network interface device structure
* @ifr: Pointer to ifr structure
@@ -2131,6 +2155,7 @@ static const struct net_device_ops pch_gbe_netdev_ops = {
.ndo_set_mac_address = pch_gbe_set_mac,
.ndo_tx_timeout = pch_gbe_tx_timeout,
.ndo_change_mtu = pch_gbe_change_mtu,
+ .ndo_set_features = pch_gbe_set_features,
.ndo_do_ioctl = pch_gbe_ioctl,
.ndo_set_multicast_list = &pch_gbe_set_multi,
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -2336,7 +2361,9 @@ static int pch_gbe_probe(struct pci_dev *pdev,
netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD;
netif_napi_add(netdev, &adapter->napi,
pch_gbe_napi_poll, PCH_GBE_RX_WEIGHT);
- netdev->features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO;
+ netdev->hw_features = NETIF_F_RXCSUM |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+ netdev->features = netdev->hw_features;
pch_gbe_set_ethtool_ops(netdev);
pch_gbe_mac_load_mac_addr(&adapter->hw);
@@ -2375,11 +2402,6 @@ static int pch_gbe_probe(struct pci_dev *pdev,
pch_gbe_check_options(adapter);
- if (adapter->tx_csum)
- netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
- else
- netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-
/* initialize the wol settings based on the eeprom settings */
adapter->wake_up_evt = PCH_GBE_WL_INIT_SETTING;
dev_info(&pdev->dev, "MAC address : %pM\n", netdev->dev_addr);
diff --git a/drivers/net/pch_gbe/pch_gbe_param.c b/drivers/net/pch_gbe/pch_gbe_param.c
index ef0996a0eaa..5b5d90a47e2 100644
--- a/drivers/net/pch_gbe/pch_gbe_param.c
+++ b/drivers/net/pch_gbe/pch_gbe_param.c
@@ -426,6 +426,8 @@ full_duplex_only:
void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
{
struct pch_gbe_hw *hw = &adapter->hw;
+ struct net_device *dev = adapter->netdev;
+ int val;
{ /* Transmit Descriptor Count */
static const struct pch_gbe_option opt = {
@@ -466,9 +468,10 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
.err = "defaulting to Enabled",
.def = PCH_GBE_DEFAULT_RX_CSUM
};
- adapter->rx_csum = XsumRX;
- pch_gbe_validate_option((int *)(&adapter->rx_csum),
- &opt, adapter);
+ val = XsumRX;
+ pch_gbe_validate_option(&val, &opt, adapter);
+ if (!val)
+ dev->features &= ~NETIF_F_RXCSUM;
}
{ /* Checksum Offload Enable/Disable */
static const struct pch_gbe_option opt = {
@@ -477,9 +480,10 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
.err = "defaulting to Enabled",
.def = PCH_GBE_DEFAULT_TX_CSUM
};
- adapter->tx_csum = XsumTX;
- pch_gbe_validate_option((int *)(&adapter->tx_csum),
- &opt, adapter);
+ val = XsumTX;
+ pch_gbe_validate_option(&val, &opt, adapter);
+ if (!val)
+ dev->features &= ~NETIF_F_ALL_CSUM;
}
{ /* Flow Control */
static const struct pch_gbe_option opt = {
diff --git a/drivers/net/pch_gbe/pch_gbe_phy.c b/drivers/net/pch_gbe/pch_gbe_phy.c
index 923a687acd3..28bb9603d73 100644
--- a/drivers/net/pch_gbe/pch_gbe_phy.c
+++ b/drivers/net/pch_gbe/pch_gbe_phy.c
@@ -247,7 +247,7 @@ inline void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw)
void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw)
{
struct pch_gbe_adapter *adapter;
- struct ethtool_cmd cmd;
+ struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
int ret;
u16 mii_reg;
@@ -256,7 +256,7 @@ void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw)
if (ret)
pr_err("Error: mii_ethtool_gset\n");
- cmd.speed = hw->mac.link_speed;
+ ethtool_cmd_speed_set(&cmd, hw->mac.link_speed);
cmd.duplex = hw->mac.link_duplex;
cmd.advertising = hw->phy.autoneg_advertised;
cmd.autoneg = hw->mac.autoneg;
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 10859175644..288e4f1317e 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -1860,7 +1860,7 @@ static int smc_netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
tmp = inw(ioaddr + CONFIG);
ecmd->port = (tmp & CFG_AUI_SELECT) ? PORT_AUI : PORT_TP;
ecmd->transceiver = XCVR_INTERNAL;
- ecmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(ecmd, SPEED_10);
ecmd->phy_address = ioaddr + MGMT;
SMC_SELECT_BANK(0);
@@ -1875,8 +1875,8 @@ static int smc_netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
u16 tmp;
unsigned int ioaddr = dev->base_addr;
- if (ecmd->speed != SPEED_10)
- return -EINVAL;
+ if (ethtool_cmd_speed(ecmd) != SPEED_10)
+ return -EINVAL;
if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
return -EINVAL;
if (ecmd->port != PORT_TP && ecmd->port != PORT_AUI)
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 768037602df..b48aba9e422 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -295,12 +295,14 @@ struct pcnet32_private {
struct net_device *next;
struct mii_if_info mii_if;
struct timer_list watchdog_timer;
- struct timer_list blink_timer;
u32 msg_enable; /* debug message level */
/* each bit indicates an available PHY */
u32 phymask;
unsigned short chip_version; /* which variant this is */
+
+ /* saved registers during ethtool blink */
+ u16 save_regs[4];
};
static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *);
@@ -324,8 +326,6 @@ static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits);
static void pcnet32_ethtool_test(struct net_device *dev,
struct ethtool_test *eth_test, u64 * data);
static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1);
-static int pcnet32_phys_id(struct net_device *dev, u32 data);
-static void pcnet32_led_blink_callback(struct net_device *dev);
static int pcnet32_get_regs_len(struct net_device *dev);
static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
void *ptr);
@@ -1022,7 +1022,8 @@ clean_up:
return rc;
} /* end pcnet32_loopback_test */
-static void pcnet32_led_blink_callback(struct net_device *dev)
+static int pcnet32_set_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
struct pcnet32_private *lp = netdev_priv(dev);
struct pcnet32_access *a = &lp->a;
@@ -1030,50 +1031,31 @@ static void pcnet32_led_blink_callback(struct net_device *dev)
unsigned long flags;
int i;
- spin_lock_irqsave(&lp->lock, flags);
- for (i = 4; i < 8; i++)
- a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000);
- spin_unlock_irqrestore(&lp->lock, flags);
-
- mod_timer(&lp->blink_timer, PCNET32_BLINK_TIMEOUT);
-}
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ /* Save the current value of the bcrs */
+ spin_lock_irqsave(&lp->lock, flags);
+ for (i = 4; i < 8; i++)
+ lp->save_regs[i - 4] = a->read_bcr(ioaddr, i);
+ spin_unlock_irqrestore(&lp->lock, flags);
+ return 2; /* cycle on/off twice per second */
-static int pcnet32_phys_id(struct net_device *dev, u32 data)
-{
- struct pcnet32_private *lp = netdev_priv(dev);
- struct pcnet32_access *a = &lp->a;
- ulong ioaddr = dev->base_addr;
- unsigned long flags;
- int i, regs[4];
+ case ETHTOOL_ID_ON:
+ case ETHTOOL_ID_OFF:
+ /* Blink the led */
+ spin_lock_irqsave(&lp->lock, flags);
+ for (i = 4; i < 8; i++)
+ a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000);
+ spin_unlock_irqrestore(&lp->lock, flags);
+ break;
- if (!lp->blink_timer.function) {
- init_timer(&lp->blink_timer);
- lp->blink_timer.function = (void *)pcnet32_led_blink_callback;
- lp->blink_timer.data = (unsigned long)dev;
+ case ETHTOOL_ID_INACTIVE:
+ /* Restore the original value of the bcrs */
+ spin_lock_irqsave(&lp->lock, flags);
+ for (i = 4; i < 8; i++)
+ a->write_bcr(ioaddr, i, lp->save_regs[i - 4]);
+ spin_unlock_irqrestore(&lp->lock, flags);
}
-
- /* Save the current value of the bcrs */
- spin_lock_irqsave(&lp->lock, flags);
- for (i = 4; i < 8; i++)
- regs[i - 4] = a->read_bcr(ioaddr, i);
- spin_unlock_irqrestore(&lp->lock, flags);
-
- mod_timer(&lp->blink_timer, jiffies);
- set_current_state(TASK_INTERRUPTIBLE);
-
- /* AV: the limit here makes no sense whatsoever */
- if ((!data) || (data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ)))
- data = (u32) (MAX_SCHEDULE_TIMEOUT / HZ);
-
- msleep_interruptible(data * 1000);
- del_timer_sync(&lp->blink_timer);
-
- /* Restore the original value of the bcrs */
- spin_lock_irqsave(&lp->lock, flags);
- for (i = 4; i < 8; i++)
- a->write_bcr(ioaddr, i, regs[i - 4]);
- spin_unlock_irqrestore(&lp->lock, flags);
-
return 0;
}
@@ -1450,7 +1432,7 @@ static const struct ethtool_ops pcnet32_ethtool_ops = {
.set_ringparam = pcnet32_set_ringparam,
.get_strings = pcnet32_get_strings,
.self_test = pcnet32_ethtool_test,
- .phys_id = pcnet32_phys_id,
+ .set_phys_id = pcnet32_set_phys_id,
.get_regs_len = pcnet32_get_regs_len,
.get_regs = pcnet32_get_regs,
.get_sset_count = pcnet32_get_sset_count,
@@ -2117,7 +2099,7 @@ static int pcnet32_open(struct net_device *dev)
int first_phy = -1;
u16 bmcr;
u32 bcr9;
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
/*
* There is really no good other way to handle multiple PHYs
@@ -2133,9 +2115,9 @@ static int pcnet32_open(struct net_device *dev)
ecmd.port = PORT_MII;
ecmd.transceiver = XCVR_INTERNAL;
ecmd.autoneg = AUTONEG_DISABLE;
- ecmd.speed =
- lp->
- options & PCNET32_PORT_100 ? SPEED_100 : SPEED_10;
+ ethtool_cmd_speed_set(&ecmd,
+ (lp->options & PCNET32_PORT_100) ?
+ SPEED_100 : SPEED_10);
bcr9 = lp->a.read_bcr(ioaddr, 9);
if (lp->options & PCNET32_PORT_FD) {
@@ -2781,11 +2763,11 @@ static void pcnet32_check_media(struct net_device *dev, int verbose)
netif_carrier_on(dev);
if (lp->mii) {
if (netif_msg_link(lp)) {
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = {
+ .cmd = ETHTOOL_GSET };
mii_ethtool_gset(&lp->mii_if, &ecmd);
- netdev_info(dev, "link up, %sMbps, %s-duplex\n",
- (ecmd.speed == SPEED_100)
- ? "100" : "10",
+ netdev_info(dev, "link up, %uMbps, %s-duplex\n",
+ ethtool_cmd_speed(&ecmd),
(ecmd.duplex == DUPLEX_FULL)
? "full" : "half");
}
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index f7670330f98..a4759576075 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -238,6 +238,8 @@ static void phy_sanitize_settings(struct phy_device *phydev)
*/
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
{
+ u32 speed = ethtool_cmd_speed(cmd);
+
if (cmd->phy_address != phydev->addr)
return -EINVAL;
@@ -253,16 +255,16 @@ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
return -EINVAL;
if (cmd->autoneg == AUTONEG_DISABLE &&
- ((cmd->speed != SPEED_1000 &&
- cmd->speed != SPEED_100 &&
- cmd->speed != SPEED_10) ||
+ ((speed != SPEED_1000 &&
+ speed != SPEED_100 &&
+ speed != SPEED_10) ||
(cmd->duplex != DUPLEX_HALF &&
cmd->duplex != DUPLEX_FULL)))
return -EINVAL;
phydev->autoneg = cmd->autoneg;
- phydev->speed = cmd->speed;
+ phydev->speed = speed;
phydev->advertising = cmd->advertising;
@@ -286,7 +288,7 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
cmd->advertising = phydev->advertising;
- cmd->speed = phydev->speed;
+ ethtool_cmd_speed_set(cmd, phydev->speed);
cmd->duplex = phydev->duplex;
cmd->port = PORT_MII;
cmd->phy_address = phydev->addr;
diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c
index 51dfcf8023c..1286fe212dc 100644
--- a/drivers/net/pptp.c
+++ b/drivers/net/pptp.c
@@ -175,6 +175,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
struct pptp_opt *opt = &po->proto.pptp;
struct pptp_gre_header *hdr;
unsigned int header_len = sizeof(*hdr);
+ struct flowi4 fl4;
int islcp;
int len;
unsigned char *data;
@@ -189,7 +190,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
if (sk_pppox(po)->sk_state & PPPOX_DEAD)
goto tx_error;
- rt = ip_route_output_ports(&init_net, NULL,
+ rt = ip_route_output_ports(&init_net, &fl4, NULL,
opt->dst_addr.sin_addr.s_addr,
opt->src_addr.sin_addr.s_addr,
0, 0, IPPROTO_GRE,
@@ -270,8 +271,8 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
iph->frag_off = 0;
iph->protocol = IPPROTO_GRE;
iph->tos = 0;
- iph->daddr = rt->rt_dst;
- iph->saddr = rt->rt_src;
+ iph->daddr = fl4.daddr;
+ iph->saddr = fl4.saddr;
iph->ttl = ip4_dst_hoplimit(&rt->dst);
iph->tot_len = htons(skb->len);
@@ -434,6 +435,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
struct pppox_sock *po = pppox_sk(sk);
struct pptp_opt *opt = &po->proto.pptp;
struct rtable *rt;
+ struct flowi4 fl4;
int error = 0;
if (sp->sa_protocol != PX_PROTO_PPTP)
@@ -463,7 +465,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
po->chan.private = sk;
po->chan.ops = &pptp_chan_ops;
- rt = ip_route_output_ports(&init_net, sk,
+ rt = ip_route_output_ports(&init_net, &fl4, sk,
opt->dst_addr.sin_addr.s_addr,
opt->src_addr.sin_addr.s_addr,
0, 0,
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index ffdf7349ef7..b1f251da153 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -951,7 +951,7 @@ static void gelic_net_pass_skb_up(struct gelic_descr *descr,
skb->protocol = eth_type_trans(skb, netdev);
/* checksum offload */
- if (card->rx_csum) {
+ if (netdev->features & NETIF_F_RXCSUM) {
if ((data_status & GELIC_DESCR_DATA_STATUS_CHK_MASK) &&
(!(data_error & GELIC_DESCR_DATA_ERROR_CHK_MASK)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -1243,17 +1243,17 @@ static int gelic_ether_get_settings(struct net_device *netdev,
switch (card->ether_port_status & GELIC_LV1_ETHER_SPEED_MASK) {
case GELIC_LV1_ETHER_SPEED_10:
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
break;
case GELIC_LV1_ETHER_SPEED_100:
- cmd->speed = SPEED_100;
+ ethtool_cmd_speed_set(cmd, SPEED_100);
break;
case GELIC_LV1_ETHER_SPEED_1000:
- cmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(cmd, SPEED_1000);
break;
default:
pr_info("%s: speed unknown\n", __func__);
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
break;
}
@@ -1312,21 +1312,6 @@ static int gelic_ether_set_settings(struct net_device *netdev,
return 0;
}
-u32 gelic_net_get_rx_csum(struct net_device *netdev)
-{
- struct gelic_card *card = netdev_card(netdev);
-
- return card->rx_csum;
-}
-
-int gelic_net_set_rx_csum(struct net_device *netdev, u32 data)
-{
- struct gelic_card *card = netdev_card(netdev);
-
- card->rx_csum = data;
- return 0;
-}
-
static void gelic_net_get_wol(struct net_device *netdev,
struct ethtool_wolinfo *wol)
{
@@ -1411,10 +1396,6 @@ static const struct ethtool_ops gelic_ether_ethtool_ops = {
.get_settings = gelic_ether_get_settings,
.set_settings = gelic_ether_set_settings,
.get_link = ethtool_op_get_link,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .get_rx_csum = gelic_net_get_rx_csum,
- .set_rx_csum = gelic_net_set_rx_csum,
.get_wol = gelic_net_get_wol,
.set_wol = gelic_net_set_wol,
};
@@ -1512,7 +1493,11 @@ int __devinit gelic_net_setup_netdev(struct net_device *netdev,
int status;
u64 v1, v2;
+ netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
+
netdev->features = NETIF_F_IP_CSUM;
+ if (GELIC_CARD_RX_CSUM_DEFAULT)
+ netdev->features |= NETIF_F_RXCSUM;
status = lv1_net_control(bus_id(card), dev_id(card),
GELIC_LV1_GET_MAC_ADDRESS,
@@ -1756,7 +1741,6 @@ static int __devinit ps3_gelic_driver_probe(struct ps3_system_bus_device *dev)
/* setup card structure */
card->irq_mask = GELIC_CARD_RXINT | GELIC_CARD_TXINT |
GELIC_CARD_PORT_STATUS_CHANGED;
- card->rx_csum = GELIC_CARD_RX_CSUM_DEFAULT;
if (gelic_card_init_chain(card, &card->tx_chain,
diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h
index fadadf9097a..d9a55b93898 100644
--- a/drivers/net/ps3_gelic_net.h
+++ b/drivers/net/ps3_gelic_net.h
@@ -290,7 +290,6 @@ struct gelic_card {
struct gelic_descr_chain tx_chain;
struct gelic_descr_chain rx_chain;
int rx_dma_restart_required;
- int rx_csum;
/*
* tx_lock guards tx descriptor list and
* tx_dma_progress.
@@ -377,8 +376,6 @@ extern int gelic_net_setup_netdev(struct net_device *netdev,
/* shared ethtool ops */
extern void gelic_net_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *info);
-extern u32 gelic_net_get_rx_csum(struct net_device *netdev);
-extern int gelic_net_set_rx_csum(struct net_device *netdev, u32 data);
extern void gelic_net_poll_controller(struct net_device *netdev);
#endif /* _GELIC_NET_H */
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index b5ae29d20f2..2e62938c0f8 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -2581,10 +2581,6 @@ static const struct net_device_ops gelic_wl_netdevice_ops = {
static const struct ethtool_ops gelic_wl_ethtool_ops = {
.get_drvinfo = gelic_net_get_drvinfo,
.get_link = gelic_wl_get_link,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .get_rx_csum = gelic_net_get_rx_csum,
- .set_rx_csum = gelic_net_set_rx_csum,
};
static void __devinit gelic_wl_setup_netdev_ops(struct net_device *netdev)
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 348b4f1367c..d495a6859fd 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -1725,7 +1725,7 @@ static int ql_get_settings(struct net_device *ndev, struct ethtool_cmd *ecmd)
}
ecmd->advertising = ql_supported_modes(qdev);
ecmd->autoneg = ql_get_auto_cfg_status(qdev);
- ecmd->speed = ql_get_speed(qdev);
+ ethtool_cmd_speed_set(ecmd, ql_get_speed(qdev));
ecmd->duplex = ql_get_full_dup(qdev);
return 0;
}
@@ -3468,7 +3468,7 @@ static int ql_adapter_up(struct ql3_adapter *qdev)
{
struct net_device *ndev = qdev->ndev;
int err;
- unsigned long irq_flags = IRQF_SAMPLE_RANDOM | IRQF_SHARED;
+ unsigned long irq_flags = IRQF_SHARED;
unsigned long hw_flags;
if (ql_alloc_mem_resources(qdev)) {
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index b0dead00b2d..480ef5cb6ef 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -29,13 +29,15 @@
#include <linux/io.h>
#include <asm/byteorder.h>
+#include <linux/bitops.h>
+#include <linux/if_vlan.h>
#include "qlcnic_hdr.h"
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 15
-#define QLCNIC_LINUX_VERSIONID "5.0.15"
+#define _QLCNIC_LINUX_SUBVERSION 18
+#define QLCNIC_LINUX_VERSIONID "5.0.18"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
@@ -93,8 +95,6 @@
#define TX_IP_PKT 0x04
#define TX_TCP_LSO 0x05
#define TX_TCP_LSO6 0x06
-#define TX_IPSEC 0x07
-#define TX_IPSEC_CMD 0x0a
#define TX_TCPV6_PKT 0x0b
#define TX_UDPV6_PKT 0x0c
@@ -118,7 +118,6 @@
#define PHAN_PEG_RCV_INITIALIZED 0xff01
#define NUM_RCV_DESC_RINGS 3
-#define NUM_STS_DESC_RINGS 4
#define RCV_RING_NORMAL 0
#define RCV_RING_JUMBO 1
@@ -201,7 +200,7 @@ struct rcv_desc {
__le16 reserved;
__le32 buffer_length; /* allocated buffer length (usually 2K) */
__le64 addr_buffer;
-};
+} __packed;
/* opcode field in status_desc */
#define QLCNIC_SYN_OFFLOAD 0x03
@@ -293,6 +292,7 @@ struct uni_data_desc{
/* Flash Defines and Structures */
#define QLCNIC_FLT_LOCATION 0x3F1000
#define QLCNIC_FW_IMAGE_REGION 0x74
+#define QLCNIC_BOOTLD_REGION 0X72
struct qlcnic_flt_header {
u16 version;
u16 len;
@@ -307,7 +307,7 @@ struct qlcnic_flt_entry {
u8 reserved1;
u32 size;
u32 start_addr;
- u32 end_add;
+ u32 end_addr;
};
/* Magic number to let user know flash is programmed */
@@ -366,12 +366,6 @@ struct qlcnic_skb_frag {
u64 length;
};
-struct qlcnic_recv_crb {
- u32 crb_rcv_producer[NUM_RCV_DESC_RINGS];
- u32 crb_sts_consumer[NUM_STS_DESC_RINGS];
- u32 sw_int_mask[NUM_STS_DESC_RINGS];
-};
-
/* Following defines are for the state of the buffers */
#define QLCNIC_BUFFER_FREE 0
#define QLCNIC_BUFFER_BUSY 1
@@ -388,10 +382,10 @@ struct qlcnic_cmd_buffer {
/* In rx_buffer, we do not need multiple fragments as is a single buffer */
struct qlcnic_rx_buffer {
- struct list_head list;
+ u16 ref_handle;
struct sk_buff *skb;
+ struct list_head list;
u64 dma;
- u16 ref_handle;
};
/* Board types */
@@ -399,6 +393,48 @@ struct qlcnic_rx_buffer {
#define QLCNIC_XGBE 0x02
/*
+ * Interrupt coalescing defaults. The defaults are for 1500 MTU. It is
+ * adjusted based on configured MTU.
+ */
+#define QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US 3
+#define QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS 256
+
+#define QLCNIC_INTR_DEFAULT 0x04
+#define QLCNIC_CONFIG_INTR_COALESCE 3
+
+struct qlcnic_nic_intr_coalesce {
+ u8 type;
+ u8 sts_ring_mask;
+ u16 rx_packets;
+ u16 rx_time_us;
+ u16 flag;
+ u32 timer_out;
+};
+
+struct qlcnic_dump_template_hdr {
+ __le32 type;
+ __le32 offset;
+ __le32 size;
+ __le32 cap_mask;
+ __le32 num_entries;
+ __le32 version;
+ __le32 timestamp;
+ __le32 checksum;
+ __le32 drv_cap_mask;
+ __le32 sys_info[3];
+ __le32 saved_state[16];
+ __le32 cap_sizes[8];
+ __le32 rsvd[0];
+};
+
+struct qlcnic_fw_dump {
+ u8 clr; /* flag to indicate if dump is cleared */
+ u32 size; /* total size of the dump */
+ void *data; /* dump data area */
+ struct qlcnic_dump_template_hdr *tmpl_hdr;
+};
+
+/*
* One hardware_context{} per adapter
* contains interrupt info as well shared hardware info.
*/
@@ -416,6 +452,9 @@ struct qlcnic_hardware_context {
u8 linkup;
u16 port_type;
u16 board_type;
+
+ struct qlcnic_nic_intr_coalesce coal;
+ struct qlcnic_fw_dump fw_dump;
};
struct qlcnic_adapter_stats {
@@ -443,50 +482,49 @@ struct qlcnic_adapter_stats {
* be one Rcv Descriptor for normal packets, one for jumbo and may be others.
*/
struct qlcnic_host_rds_ring {
- u32 producer;
+ void __iomem *crb_rcv_producer;
+ struct rcv_desc *desc_head;
+ struct qlcnic_rx_buffer *rx_buf_arr;
u32 num_desc;
+ u32 producer;
u32 dma_size;
u32 skb_size;
u32 flags;
- void __iomem *crb_rcv_producer;
- struct rcv_desc *desc_head;
- struct qlcnic_rx_buffer *rx_buf_arr;
struct list_head free_list;
spinlock_t lock;
dma_addr_t phys_addr;
-};
+} ____cacheline_internodealigned_in_smp;
struct qlcnic_host_sds_ring {
u32 consumer;
u32 num_desc;
void __iomem *crb_sts_consumer;
- void __iomem *crb_intr_mask;
struct status_desc *desc_head;
struct qlcnic_adapter *adapter;
struct napi_struct napi;
struct list_head free_list[NUM_RCV_DESC_RINGS];
+ void __iomem *crb_intr_mask;
int irq;
dma_addr_t phys_addr;
char name[IFNAMSIZ+4];
-};
+} ____cacheline_internodealigned_in_smp;
struct qlcnic_host_tx_ring {
u32 producer;
- __le32 *hw_consumer;
u32 sw_consumer;
- void __iomem *crb_cmd_producer;
u32 num_desc;
-
- struct netdev_queue *txq;
-
- struct qlcnic_cmd_buffer *cmd_buf_arr;
+ void __iomem *crb_cmd_producer;
struct cmd_desc_type0 *desc_head;
+ struct qlcnic_cmd_buffer *cmd_buf_arr;
+ __le32 *hw_consumer;
+
dma_addr_t phys_addr;
dma_addr_t hw_cons_phys_addr;
-};
+ struct netdev_queue *txq;
+} ____cacheline_internodealigned_in_smp;
/*
* Receive context. There is one such structure per instance of the
@@ -495,12 +533,12 @@ struct qlcnic_host_tx_ring {
* present elsewhere.
*/
struct qlcnic_recv_context {
+ struct qlcnic_host_rds_ring *rds_rings;
+ struct qlcnic_host_sds_ring *sds_rings;
u32 state;
u16 context_id;
u16 virt_port;
- struct qlcnic_host_rds_ring *rds_rings;
- struct qlcnic_host_sds_ring *sds_rings;
};
/* HW context creation */
@@ -539,9 +577,6 @@ struct qlcnic_recv_context {
#define QLCNIC_CDRP_CMD_DESTROY_RX_CTX 0x00000008
#define QLCNIC_CDRP_CMD_CREATE_TX_CTX 0x00000009
#define QLCNIC_CDRP_CMD_DESTROY_TX_CTX 0x0000000a
-#define QLCNIC_CDRP_CMD_SETUP_STATISTICS 0x0000000e
-#define QLCNIC_CDRP_CMD_GET_STATISTICS 0x0000000f
-#define QLCNIC_CDRP_CMD_DELETE_STATISTICS 0x00000010
#define QLCNIC_CDRP_CMD_SET_MTU 0x00000012
#define QLCNIC_CDRP_CMD_READ_PHY 0x00000013
#define QLCNIC_CDRP_CMD_WRITE_PHY 0x00000014
@@ -550,17 +585,11 @@ struct qlcnic_recv_context {
#define QLCNIC_CDRP_CMD_SET_FLOW_CTL 0x00000017
#define QLCNIC_CDRP_CMD_READ_MAX_MTU 0x00000018
#define QLCNIC_CDRP_CMD_READ_MAX_LRO 0x00000019
-#define QLCNIC_CDRP_CMD_CONFIGURE_TOE 0x0000001a
-#define QLCNIC_CDRP_CMD_FUNC_ATTRIB 0x0000001b
-#define QLCNIC_CDRP_CMD_READ_PEXQ_PARAMETERS 0x0000001c
-#define QLCNIC_CDRP_CMD_GET_LIC_CAPABILITIES 0x0000001d
-#define QLCNIC_CDRP_CMD_READ_MAX_LRO_PER_BOARD 0x0000001e
#define QLCNIC_CDRP_CMD_MAC_ADDRESS 0x0000001f
#define QLCNIC_CDRP_CMD_GET_PCI_INFO 0x00000020
#define QLCNIC_CDRP_CMD_GET_NIC_INFO 0x00000021
#define QLCNIC_CDRP_CMD_SET_NIC_INFO 0x00000022
-#define QLCNIC_CDRP_CMD_RESET_NPAR 0x00000023
#define QLCNIC_CDRP_CMD_GET_ESWITCH_CAPABILITY 0x00000024
#define QLCNIC_CDRP_CMD_TOGGLE_ESWITCH 0x00000025
#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS 0x00000026
@@ -568,8 +597,12 @@ struct qlcnic_recv_context {
#define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH 0x00000028
#define QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG 0x00000029
#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATS 0x0000002a
+#define QLCNIC_CDRP_CMD_CONFIG_PORT 0x0000002E
+#define QLCNIC_CDRP_CMD_TEMP_SIZE 0x0000002f
+#define QLCNIC_CDRP_CMD_GET_TEMP_HDR 0x00000030
#define QLCNIC_RCODE_SUCCESS 0
+#define QLCNIC_RCODE_NOT_SUPPORTED 9
#define QLCNIC_RCODE_TIMEOUT 17
#define QLCNIC_DESTROY_CTX_RESET 0
@@ -598,14 +631,14 @@ struct qlcnic_hostrq_sds_ring {
__le32 ring_size; /* Ring entries */
__le16 msi_index;
__le16 rsvd; /* Padding */
-};
+} __packed;
struct qlcnic_hostrq_rds_ring {
__le64 host_phys_addr; /* Ring base addr */
__le64 buff_size; /* Packet buffer size */
__le32 ring_size; /* Ring entries */
__le32 ring_kind; /* Class of ring */
-};
+} __packed;
struct qlcnic_hostrq_rx_ctx {
__le64 host_rsp_dma_addr; /* Response dma'd here */
@@ -626,17 +659,17 @@ struct qlcnic_hostrq_rx_ctx {
- N hostrq_rds_rings
- N hostrq_sds_rings */
char data[0];
-};
+} __packed;
struct qlcnic_cardrsp_rds_ring{
__le32 host_producer_crb; /* Crb to use */
__le32 rsvd1; /* Padding */
-};
+} __packed;
struct qlcnic_cardrsp_sds_ring {
__le32 host_consumer_crb; /* Crb to use */
__le32 interrupt_crb; /* Crb to use */
-};
+} __packed;
struct qlcnic_cardrsp_rx_ctx {
/* These ring offsets are relative to data[0] below */
@@ -655,7 +688,7 @@ struct qlcnic_cardrsp_rx_ctx {
- N cardrsp_rds_rings
- N cardrs_sds_rings */
char data[0];
-};
+} __packed;
#define SIZEOF_HOSTRQ_RX(HOSTRQ_RX, rds_rings, sds_rings) \
(sizeof(HOSTRQ_RX) + \
@@ -675,7 +708,7 @@ struct qlcnic_hostrq_cds_ring {
__le64 host_phys_addr; /* Ring base addr */
__le32 ring_size; /* Ring entries */
__le32 rsvd; /* Padding */
-};
+} __packed;
struct qlcnic_hostrq_tx_ctx {
__le64 host_rsp_dma_addr; /* Response dma'd here */
@@ -690,12 +723,12 @@ struct qlcnic_hostrq_tx_ctx {
__le16 rsvd3; /* Padding */
struct qlcnic_hostrq_cds_ring cds_ring; /* Desc of cds ring */
u8 reserved[128]; /* future expansion */
-};
+} __packed;
struct qlcnic_cardrsp_cds_ring {
__le32 host_producer_crb; /* Crb to use */
__le32 interrupt_crb; /* Crb to use */
-};
+} __packed;
struct qlcnic_cardrsp_tx_ctx {
__le32 host_ctx_state; /* Starting state */
@@ -704,7 +737,7 @@ struct qlcnic_cardrsp_tx_ctx {
u8 virt_port; /* Virtual/Logical id of port */
struct qlcnic_cardrsp_cds_ring cds_ring; /* Card cds settings */
u8 reserved[128]; /* future expansion */
-};
+} __packed;
#define SIZEOF_HOSTRQ_TX(HOSTRQ_TX) (sizeof(HOSTRQ_TX))
#define SIZEOF_CARDRSP_TX(CARDRSP_TX) (sizeof(CARDRSP_TX))
@@ -738,40 +771,6 @@ struct qlcnic_mac_list_s {
uint8_t mac_addr[ETH_ALEN+2];
};
-/*
- * Interrupt coalescing defaults. The defaults are for 1500 MTU. It is
- * adjusted based on configured MTU.
- */
-#define QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US 3
-#define QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS 256
-#define QLCNIC_DEFAULT_INTR_COALESCE_TX_PACKETS 64
-#define QLCNIC_DEFAULT_INTR_COALESCE_TX_TIME_US 4
-
-#define QLCNIC_INTR_DEFAULT 0x04
-
-union qlcnic_nic_intr_coalesce_data {
- struct {
- u16 rx_packets;
- u16 rx_time_us;
- u16 tx_packets;
- u16 tx_time_us;
- } data;
- u64 word;
-};
-
-struct qlcnic_nic_intr_coalesce {
- u16 stats_time_us;
- u16 rate_sample_time;
- u16 flags;
- u16 rsvd_1;
- u32 low_threshold;
- u32 high_threshold;
- union qlcnic_nic_intr_coalesce_data normal;
- union qlcnic_nic_intr_coalesce_data low;
- union qlcnic_nic_intr_coalesce_data high;
- union qlcnic_nic_intr_coalesce_data irq;
-};
-
#define QLCNIC_HOST_REQUEST 0x13
#define QLCNIC_REQUEST 0x14
@@ -783,50 +782,20 @@ struct qlcnic_nic_intr_coalesce {
/*
* Driver --> Firmware
*/
-#define QLCNIC_H2C_OPCODE_START 0
-#define QLCNIC_H2C_OPCODE_CONFIG_RSS 1
-#define QLCNIC_H2C_OPCODE_CONFIG_RSS_TBL 2
-#define QLCNIC_H2C_OPCODE_CONFIG_INTR_COALESCE 3
-#define QLCNIC_H2C_OPCODE_CONFIG_LED 4
-#define QLCNIC_H2C_OPCODE_CONFIG_PROMISCUOUS 5
-#define QLCNIC_H2C_OPCODE_CONFIG_L2_MAC 6
-#define QLCNIC_H2C_OPCODE_LRO_REQUEST 7
-#define QLCNIC_H2C_OPCODE_GET_SNMP_STATS 8
-#define QLCNIC_H2C_OPCODE_PROXY_START_REQUEST 9
-#define QLCNIC_H2C_OPCODE_PROXY_STOP_REQUEST 10
-#define QLCNIC_H2C_OPCODE_PROXY_SET_MTU 11
-#define QLCNIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE 12
-#define QLCNIC_H2C_OPCODE_GET_FINGER_PRINT_REQUEST 13
-#define QLCNIC_H2C_OPCODE_INSTALL_LICENSE_REQUEST 14
-#define QLCNIC_H2C_OPCODE_GET_LICENSE_CAPABILITY_REQUEST 15
-#define QLCNIC_H2C_OPCODE_GET_NET_STATS 16
-#define QLCNIC_H2C_OPCODE_PROXY_UPDATE_P2V 17
-#define QLCNIC_H2C_OPCODE_CONFIG_IPADDR 18
-#define QLCNIC_H2C_OPCODE_PROXY_STOP_DONE 20
-#define QLCNIC_H2C_OPCODE_GET_LINKEVENT 21
-#define QLCNIC_C2C_OPCODE 22
-#define QLCNIC_H2C_OPCODE_CONFIG_BRIDGING 23
-#define QLCNIC_H2C_OPCODE_CONFIG_HW_LRO 24
-#define QLCNIC_H2C_OPCODE_LAST 25
+#define QLCNIC_H2C_OPCODE_CONFIG_RSS 0x1
+#define QLCNIC_H2C_OPCODE_CONFIG_INTR_COALESCE 0x3
+#define QLCNIC_H2C_OPCODE_CONFIG_LED 0x4
+#define QLCNIC_H2C_OPCODE_LRO_REQUEST 0x7
+#define QLCNIC_H2C_OPCODE_SET_MAC_RECEIVE_MODE 0xc
+#define QLCNIC_H2C_OPCODE_CONFIG_IPADDR 0x12
+#define QLCNIC_H2C_OPCODE_GET_LINKEVENT 0x15
+#define QLCNIC_H2C_OPCODE_CONFIG_BRIDGING 0x17
+#define QLCNIC_H2C_OPCODE_CONFIG_HW_LRO 0x18
/*
* Firmware --> Driver
*/
-#define QLCNIC_C2H_OPCODE_START 128
-#define QLCNIC_C2H_OPCODE_CONFIG_RSS_RESPONSE 129
-#define QLCNIC_C2H_OPCODE_CONFIG_RSS_TBL_RESPONSE 130
-#define QLCNIC_C2H_OPCODE_CONFIG_MAC_RESPONSE 131
-#define QLCNIC_C2H_OPCODE_CONFIG_PROMISCUOUS_RESPONSE 132
-#define QLCNIC_C2H_OPCODE_CONFIG_L2_MAC_RESPONSE 133
-#define QLCNIC_C2H_OPCODE_LRO_DELETE_RESPONSE 134
-#define QLCNIC_C2H_OPCODE_LRO_ADD_FAILURE_RESPONSE 135
-#define QLCNIC_C2H_OPCODE_GET_SNMP_STATS 136
-#define QLCNIC_C2H_OPCODE_GET_FINGER_PRINT_REPLY 137
-#define QLCNIC_C2H_OPCODE_INSTALL_LICENSE_REPLY 138
-#define QLCNIC_C2H_OPCODE_GET_LICENSE_CAPABILITIES_REPLY 139
-#define QLCNIC_C2H_OPCODE_GET_NET_STATS_RESPONSE 140
#define QLCNIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE 141
-#define QLCNIC_C2H_OPCODE_LAST 142
#define VPORT_MISS_MODE_DROP 0 /* drop all unmatched */
#define VPORT_MISS_MODE_ACCEPT_ALL 1 /* accept all packets */
@@ -895,7 +864,7 @@ struct qlcnic_nic_req {
__le64 qhdr;
__le64 req_hdr;
__le64 words[6];
-};
+} __packed;
struct qlcnic_mac_req {
u8 op;
@@ -906,7 +875,7 @@ struct qlcnic_mac_req {
struct qlcnic_vlan_req {
__le16 vlan_id;
__le16 rsvd[3];
-};
+} __packed;
struct qlcnic_ipaddr {
__be32 ipv4;
@@ -929,7 +898,8 @@ struct qlcnic_ipaddr {
#define QLCNIC_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
-#define MSIX_ENTRIES_PER_ADAPTER NUM_STS_DESC_RINGS
+#define QLCNIC_DEF_NUM_STS_DESC_RINGS 4
+#define QLCNIC_MIN_NUM_RSS_RINGS 2
#define QLCNIC_MSIX_TBL_SPACE 8192
#define QLCNIC_PCI_REG_MSIX_TBL 0x44
#define QLCNIC_MSIX_TBL_PGSIZE 4096
@@ -942,6 +912,7 @@ struct qlcnic_ipaddr {
#define __QLCNIC_RESETTING 2
#define __QLCNIC_START_FW 4
#define __QLCNIC_AER 5
+#define __QLCNIC_DIAG_RES_ALLOC 6
#define QLCNIC_INTERRUPT_TEST 1
#define QLCNIC_LOOPBACK_TEST 2
@@ -965,14 +936,14 @@ struct qlcnic_filter_hash {
};
struct qlcnic_adapter {
- struct qlcnic_hardware_context ahw;
-
+ struct qlcnic_hardware_context *ahw;
+ struct qlcnic_recv_context *recv_ctx;
+ struct qlcnic_host_tx_ring *tx_ring;
struct net_device *netdev;
struct pci_dev *pdev;
- struct list_head mac_list;
- spinlock_t tx_clean_lock;
- spinlock_t mac_learn_lock;
+ unsigned long state;
+ u32 flags;
u16 num_txd;
u16 num_rxd;
@@ -983,14 +954,12 @@ struct qlcnic_adapter {
u8 max_rds_rings;
u8 max_sds_rings;
u8 msix_supported;
- u8 rx_csum;
u8 portnum;
u8 physical_port;
u8 reset_context;
u8 mc_enabled;
u8 max_mc_count;
- u8 rss_supported;
u8 fw_wait_cnt;
u8 fw_fail_cnt;
u8 tx_timeo_cnt;
@@ -1015,7 +984,6 @@ struct qlcnic_adapter {
u32 fw_hal_version;
u32 capabilities;
- u32 flags;
u32 irq;
u32 temp;
@@ -1033,31 +1001,29 @@ struct qlcnic_adapter {
u8 mac_addr[ETH_ALEN];
u64 dev_rst_time;
+ unsigned long vlans[BITS_TO_LONGS(VLAN_N_VID)];
- struct vlan_group *vlgrp;
struct qlcnic_npar_info *npars;
struct qlcnic_eswitch *eswitch;
struct qlcnic_nic_template *nic_ops;
struct qlcnic_adapter_stats stats;
-
- struct qlcnic_recv_context recv_ctx;
- struct qlcnic_host_tx_ring *tx_ring;
+ struct list_head mac_list;
void __iomem *tgt_mask_reg;
void __iomem *tgt_status_reg;
void __iomem *crb_int_state_reg;
void __iomem *isr_int_vec;
- struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
+ struct msix_entry *msix_entries;
struct delayed_work fw_work;
- struct qlcnic_nic_intr_coalesce coal;
struct qlcnic_filter_hash fhash;
- unsigned long state;
+ spinlock_t tx_clean_lock;
+ spinlock_t mac_learn_lock;
__le32 file_prd_off; /*File fw product offset*/
u32 fw_version;
const struct firmware *fw;
@@ -1079,7 +1045,7 @@ struct qlcnic_info {
__le16 min_tx_bw;
__le16 max_tx_bw;
u8 reserved2[104];
-};
+} __packed;
struct qlcnic_pci_info {
__le16 id; /* pci function id */
@@ -1093,7 +1059,7 @@ struct qlcnic_pci_info {
u8 mac[ETH_ALEN];
u8 reserved2[106];
-};
+} __packed;
struct qlcnic_npar_info {
u16 pvid;
@@ -1210,15 +1176,160 @@ struct __qlcnic_esw_statistics {
__le64 local_frames;
__le64 numbytes;
__le64 rsvd[3];
-};
+} __packed;
struct qlcnic_esw_statistics {
struct __qlcnic_esw_statistics rx;
struct __qlcnic_esw_statistics tx;
};
-int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val);
-int qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val);
+struct qlcnic_common_entry_hdr {
+ __le32 type;
+ __le32 offset;
+ __le32 cap_size;
+ u8 mask;
+ u8 rsvd[2];
+ u8 flags;
+} __packed;
+
+struct __crb {
+ __le32 addr;
+ u8 stride;
+ u8 rsvd1[3];
+ __le32 data_size;
+ __le32 no_ops;
+ __le32 rsvd2[4];
+} __packed;
+
+struct __ctrl {
+ __le32 addr;
+ u8 stride;
+ u8 index_a;
+ __le16 timeout;
+ __le32 data_size;
+ __le32 no_ops;
+ u8 opcode;
+ u8 index_v;
+ u8 shl_val;
+ u8 shr_val;
+ __le32 val1;
+ __le32 val2;
+ __le32 val3;
+} __packed;
+
+struct __cache {
+ __le32 addr;
+ u8 stride;
+ u8 rsvd;
+ __le16 init_tag_val;
+ __le32 size;
+ __le32 no_ops;
+ __le32 ctrl_addr;
+ __le32 ctrl_val;
+ __le32 read_addr;
+ u8 read_addr_stride;
+ u8 read_addr_num;
+ u8 rsvd1[2];
+} __packed;
+
+struct __ocm {
+ u8 rsvd[8];
+ __le32 size;
+ __le32 no_ops;
+ u8 rsvd1[8];
+ __le32 read_addr;
+ __le32 read_addr_stride;
+} __packed;
+
+struct __mem {
+ u8 rsvd[24];
+ __le32 addr;
+ __le32 size;
+} __packed;
+
+struct __mux {
+ __le32 addr;
+ u8 rsvd[4];
+ __le32 size;
+ __le32 no_ops;
+ __le32 val;
+ __le32 val_stride;
+ __le32 read_addr;
+ u8 rsvd2[4];
+} __packed;
+
+struct __queue {
+ __le32 sel_addr;
+ __le16 stride;
+ u8 rsvd[2];
+ __le32 size;
+ __le32 no_ops;
+ u8 rsvd2[8];
+ __le32 read_addr;
+ u8 read_addr_stride;
+ u8 read_addr_cnt;
+ u8 rsvd3[2];
+} __packed;
+
+struct qlcnic_dump_entry {
+ struct qlcnic_common_entry_hdr hdr;
+ union {
+ struct __crb crb;
+ struct __cache cache;
+ struct __ocm ocm;
+ struct __mem mem;
+ struct __mux mux;
+ struct __queue que;
+ struct __ctrl ctrl;
+ } region;
+} __packed;
+
+enum op_codes {
+ QLCNIC_DUMP_NOP = 0,
+ QLCNIC_DUMP_READ_CRB = 1,
+ QLCNIC_DUMP_READ_MUX = 2,
+ QLCNIC_DUMP_QUEUE = 3,
+ QLCNIC_DUMP_BRD_CONFIG = 4,
+ QLCNIC_DUMP_READ_OCM = 6,
+ QLCNIC_DUMP_PEG_REG = 7,
+ QLCNIC_DUMP_L1_DTAG = 8,
+ QLCNIC_DUMP_L1_ITAG = 9,
+ QLCNIC_DUMP_L1_DATA = 11,
+ QLCNIC_DUMP_L1_INST = 12,
+ QLCNIC_DUMP_L2_DTAG = 21,
+ QLCNIC_DUMP_L2_ITAG = 22,
+ QLCNIC_DUMP_L2_DATA = 23,
+ QLCNIC_DUMP_L2_INST = 24,
+ QLCNIC_DUMP_READ_ROM = 71,
+ QLCNIC_DUMP_READ_MEM = 72,
+ QLCNIC_DUMP_READ_CTRL = 98,
+ QLCNIC_DUMP_TLHDR = 99,
+ QLCNIC_DUMP_RDEND = 255
+};
+
+#define QLCNIC_DUMP_WCRB BIT_0
+#define QLCNIC_DUMP_RWCRB BIT_1
+#define QLCNIC_DUMP_ANDCRB BIT_2
+#define QLCNIC_DUMP_ORCRB BIT_3
+#define QLCNIC_DUMP_POLLCRB BIT_4
+#define QLCNIC_DUMP_RD_SAVE BIT_5
+#define QLCNIC_DUMP_WRT_SAVED BIT_6
+#define QLCNIC_DUMP_MOD_SAVE_ST BIT_7
+#define QLCNIC_DUMP_SKIP BIT_7
+
+#define QLCNIC_DUMP_MASK_MIN 3
+#define QLCNIC_DUMP_MASK_DEF 0x0f
+#define QLCNIC_DUMP_MASK_MAX 0xff
+#define QLCNIC_FORCE_FW_DUMP_KEY 0xdeadfeed
+
+struct qlcnic_dump_operations {
+ enum op_codes opcode;
+ u32 (*handler)(struct qlcnic_adapter *,
+ struct qlcnic_dump_entry *, u32 *);
+};
+
+int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter);
+int qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config);
u32 qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off);
int qlcnic_hw_write_wx_2M(struct qlcnic_adapter *, ulong off, u32 data);
@@ -1264,6 +1375,7 @@ int qlcnic_wol_supported(struct qlcnic_adapter *adapter);
int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate);
void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter);
void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter);
+int qlcnic_dump_fw(struct qlcnic_adapter *);
/* Functions from qlcnic_init.c */
int qlcnic_load_firmware(struct qlcnic_adapter *adapter);
@@ -1274,7 +1386,7 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter);
int qlcnic_setup_idc_param(struct qlcnic_adapter *adapter);
int qlcnic_check_flash_fw_ver(struct qlcnic_adapter *adapter);
-int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, int addr, int *valp);
+int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, u32 addr, u32 *valp);
int qlcnic_rom_fast_read_words(struct qlcnic_adapter *adapter, int addr,
u8 *bytes, size_t size);
int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter);
@@ -1294,7 +1406,7 @@ void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter);
int qlcnic_check_fw_status(struct qlcnic_adapter *adapter);
void qlcnic_watchdog_task(struct work_struct *work);
-void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid,
+void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter,
struct qlcnic_host_rds_ring *rds_ring);
int qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max);
void qlcnic_set_multi(struct net_device *netdev);
@@ -1308,6 +1420,8 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup);
int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu);
int qlcnic_change_mtu(struct net_device *netdev, int new_mtu);
+u32 qlcnic_fix_features(struct net_device *netdev, u32 features);
+int qlcnic_set_features(struct net_device *netdev, u32 features);
int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable);
int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable);
int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
@@ -1322,6 +1436,9 @@ u32 qlcnic_issue_cmd(struct qlcnic_adapter *adapter,
void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings);
int qlcnic_diag_alloc_res(struct net_device *netdev, int test);
netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
+int qlcnic_validate_max_rss(struct net_device *netdev, u8 max_hw, u8 val);
+int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data);
+void qlcnic_dev_request_reset(struct qlcnic_adapter *);
/* Management functions */
int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*);
@@ -1379,8 +1496,7 @@ static const struct qlcnic_brdinfo qlcnic_boards[] = {
static inline u32 qlcnic_tx_avail(struct qlcnic_host_tx_ring *tx_ring)
{
- smp_mb();
- if (tx_ring->producer < tx_ring->sw_consumer)
+ if (likely(tx_ring->producer < tx_ring->sw_consumer))
return tx_ring->sw_consumer - tx_ring->producer;
else
return tx_ring->sw_consumer + tx_ring->num_desc -
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index 27631f23b3f..bab041a5c75 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -64,14 +64,105 @@ qlcnic_issue_cmd(struct qlcnic_adapter *adapter,
return rcode;
}
+static uint32_t qlcnic_temp_checksum(uint32_t *temp_buffer, u16 temp_size)
+{
+ uint64_t sum = 0;
+ int count = temp_size / sizeof(uint32_t);
+ while (count-- > 0)
+ sum += *temp_buffer++;
+ while (sum >> 32)
+ sum = (sum & 0xFFFFFFFF) + (sum >> 32);
+ return ~sum;
+}
+
+int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
+{
+ int err, i;
+ u16 temp_size;
+ void *tmp_addr;
+ u32 version, csum, *template, *tmp_buf;
+ struct qlcnic_hardware_context *ahw;
+ struct qlcnic_dump_template_hdr *tmpl_hdr, *tmp_tmpl;
+ dma_addr_t tmp_addr_t = 0;
+
+ ahw = adapter->ahw;
+ err = qlcnic_issue_cmd(adapter,
+ adapter->ahw->pci_func,
+ adapter->fw_hal_version,
+ 0,
+ 0,
+ 0,
+ QLCNIC_CDRP_CMD_TEMP_SIZE);
+ if (err != QLCNIC_RCODE_SUCCESS) {
+ err = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
+ dev_err(&adapter->pdev->dev,
+ "Failed to get template size %d\n", err);
+ err = -EIO;
+ return err;
+ }
+ version = QLCRD32(adapter, QLCNIC_ARG3_CRB_OFFSET);
+ temp_size = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET);
+ if (!temp_size)
+ return -EIO;
+
+ tmp_addr = dma_alloc_coherent(&adapter->pdev->dev, temp_size,
+ &tmp_addr_t, GFP_KERNEL);
+ if (!tmp_addr) {
+ dev_err(&adapter->pdev->dev,
+ "Can't get memory for FW dump template\n");
+ return -ENOMEM;
+ }
+ err = qlcnic_issue_cmd(adapter,
+ adapter->ahw->pci_func,
+ adapter->fw_hal_version,
+ LSD(tmp_addr_t),
+ MSD(tmp_addr_t),
+ temp_size,
+ QLCNIC_CDRP_CMD_GET_TEMP_HDR);
+
+ if (err != QLCNIC_RCODE_SUCCESS) {
+ dev_err(&adapter->pdev->dev,
+ "Failed to get mini dump template header %d\n", err);
+ err = -EIO;
+ goto error;
+ }
+ tmp_tmpl = (struct qlcnic_dump_template_hdr *) tmp_addr;
+ csum = qlcnic_temp_checksum((uint32_t *) tmp_addr, temp_size);
+ if (csum) {
+ dev_err(&adapter->pdev->dev,
+ "Template header checksum validation failed\n");
+ err = -EIO;
+ goto error;
+ }
+ ahw->fw_dump.tmpl_hdr = vzalloc(temp_size);
+ if (!ahw->fw_dump.tmpl_hdr) {
+ err = -EIO;
+ goto error;
+ }
+ tmp_buf = (u32 *) tmp_addr;
+ template = (u32 *) ahw->fw_dump.tmpl_hdr;
+ for (i = 0; i < temp_size/sizeof(u32); i++)
+ *template++ = __le32_to_cpu(*tmp_buf++);
+
+ tmpl_hdr = ahw->fw_dump.tmpl_hdr;
+ if (tmpl_hdr->cap_mask > QLCNIC_DUMP_MASK_DEF &&
+ tmpl_hdr->cap_mask <= QLCNIC_DUMP_MASK_MAX)
+ tmpl_hdr->drv_cap_mask = tmpl_hdr->cap_mask;
+ else
+ tmpl_hdr->drv_cap_mask = QLCNIC_DUMP_MASK_DEF;
+error:
+ dma_free_coherent(&adapter->pdev->dev, temp_size, tmp_addr, tmp_addr_t);
+ return err;
+}
+
int
qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu)
{
- struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
if (recv_ctx->state == QLCNIC_HOST_CTX_STATE_ACTIVE) {
if (qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
+ adapter->ahw->pci_func,
adapter->fw_hal_version,
recv_ctx->context_id,
mtu,
@@ -102,12 +193,12 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
u64 phys_addr;
- int i, nrds_rings, nsds_rings;
+ u8 i, nrds_rings, nsds_rings;
size_t rq_size, rsp_size;
u32 cap, reg, val, reg2;
int err;
- struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
nrds_rings = adapter->max_rds_rings;
nsds_rings = adapter->max_sds_rings;
@@ -119,14 +210,14 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
SIZEOF_CARDRSP_RX(struct qlcnic_cardrsp_rx_ctx, nrds_rings,
nsds_rings);
- addr = pci_alloc_consistent(adapter->pdev,
- rq_size, &hostrq_phys_addr);
+ addr = dma_alloc_coherent(&adapter->pdev->dev, rq_size,
+ &hostrq_phys_addr, GFP_KERNEL);
if (addr == NULL)
return -ENOMEM;
prq = (struct qlcnic_hostrq_rx_ctx *)addr;
- addr = pci_alloc_consistent(adapter->pdev,
- rsp_size, &cardrsp_phys_addr);
+ addr = dma_alloc_coherent(&adapter->pdev->dev, rsp_size,
+ &cardrsp_phys_addr, GFP_KERNEL);
if (addr == NULL) {
err = -ENOMEM;
goto out_free_rq;
@@ -151,7 +242,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
prq->num_rds_rings = cpu_to_le16(nrds_rings);
prq->num_sds_rings = cpu_to_le16(nsds_rings);
- prq->rds_ring_offset = cpu_to_le32(0);
+ prq->rds_ring_offset = 0;
val = le32_to_cpu(prq->rds_ring_offset) +
(sizeof(struct qlcnic_hostrq_rds_ring) * nrds_rings);
@@ -187,7 +278,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
phys_addr = hostrq_phys_addr;
err = qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
+ adapter->ahw->pci_func,
adapter->fw_hal_version,
(u32)(phys_addr >> 32),
(u32)(phys_addr & 0xffffffff),
@@ -207,7 +298,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
rds_ring = &recv_ctx->rds_rings[i];
reg = le32_to_cpu(prsp_rds[i].host_producer_crb);
- rds_ring->crb_rcv_producer = adapter->ahw.pci_base0 + reg;
+ rds_ring->crb_rcv_producer = adapter->ahw->pci_base0 + reg;
}
prsp_sds = ((struct qlcnic_cardrsp_sds_ring *)
@@ -219,8 +310,8 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
reg2 = le32_to_cpu(prsp_sds[i].interrupt_crb);
- sds_ring->crb_sts_consumer = adapter->ahw.pci_base0 + reg;
- sds_ring->crb_intr_mask = adapter->ahw.pci_base0 + reg2;
+ sds_ring->crb_sts_consumer = adapter->ahw->pci_base0 + reg;
+ sds_ring->crb_intr_mask = adapter->ahw->pci_base0 + reg2;
}
recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
@@ -228,19 +319,20 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
recv_ctx->virt_port = prsp->virt_port;
out_free_rsp:
- pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr);
+ dma_free_coherent(&adapter->pdev->dev, rsp_size, prsp,
+ cardrsp_phys_addr);
out_free_rq:
- pci_free_consistent(adapter->pdev, rq_size, prq, hostrq_phys_addr);
+ dma_free_coherent(&adapter->pdev->dev, rq_size, prq, hostrq_phys_addr);
return err;
}
static void
qlcnic_fw_cmd_destroy_rx_ctx(struct qlcnic_adapter *adapter)
{
- struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
if (qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
+ adapter->ahw->pci_func,
adapter->fw_hal_version,
recv_ctx->context_id,
QLCNIC_DESTROY_CTX_RESET,
@@ -274,14 +366,14 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter)
*(tx_ring->hw_consumer) = 0;
rq_size = SIZEOF_HOSTRQ_TX(struct qlcnic_hostrq_tx_ctx);
- rq_addr = pci_alloc_consistent(adapter->pdev,
- rq_size, &rq_phys_addr);
+ rq_addr = dma_alloc_coherent(&adapter->pdev->dev, rq_size,
+ &rq_phys_addr, GFP_KERNEL);
if (!rq_addr)
return -ENOMEM;
rsp_size = SIZEOF_CARDRSP_TX(struct qlcnic_cardrsp_tx_ctx);
- rsp_addr = pci_alloc_consistent(adapter->pdev,
- rsp_size, &rsp_phys_addr);
+ rsp_addr = dma_alloc_coherent(&adapter->pdev->dev, rsp_size,
+ &rsp_phys_addr, GFP_KERNEL);
if (!rsp_addr) {
err = -ENOMEM;
goto out_free_rq;
@@ -313,7 +405,7 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter)
phys_addr = rq_phys_addr;
err = qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
+ adapter->ahw->pci_func,
adapter->fw_hal_version,
(u32)(phys_addr >> 32),
((u32)phys_addr & 0xffffffff),
@@ -322,7 +414,7 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter)
if (err == QLCNIC_RCODE_SUCCESS) {
temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
- tx_ring->crb_cmd_producer = adapter->ahw.pci_base0 + temp;
+ tx_ring->crb_cmd_producer = adapter->ahw->pci_base0 + temp;
adapter->tx_context_id =
le16_to_cpu(prsp->context_id);
@@ -332,10 +424,11 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter)
err = -EIO;
}
- pci_free_consistent(adapter->pdev, rsp_size, rsp_addr, rsp_phys_addr);
+ dma_free_coherent(&adapter->pdev->dev, rsp_size, rsp_addr,
+ rsp_phys_addr);
out_free_rq:
- pci_free_consistent(adapter->pdev, rq_size, rq_addr, rq_phys_addr);
+ dma_free_coherent(&adapter->pdev->dev, rq_size, rq_addr, rq_phys_addr);
return err;
}
@@ -344,7 +437,7 @@ static void
qlcnic_fw_cmd_destroy_tx_ctx(struct qlcnic_adapter *adapter)
{
if (qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
+ adapter->ahw->pci_func,
adapter->fw_hal_version,
adapter->tx_context_id,
QLCNIC_DESTROY_CTX_RESET,
@@ -357,33 +450,15 @@ qlcnic_fw_cmd_destroy_tx_ctx(struct qlcnic_adapter *adapter)
}
int
-qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val)
-{
-
- if (qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
- adapter->fw_hal_version,
- reg,
- 0,
- 0,
- QLCNIC_CDRP_CMD_READ_PHY)) {
-
- return -EIO;
- }
-
- return QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
-}
-
-int
-qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val)
+qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config)
{
return qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
+ adapter->ahw->pci_func,
adapter->fw_hal_version,
- reg,
- val,
+ config,
+ 0,
0,
- QLCNIC_CDRP_CMD_WRITE_PHY);
+ QLCNIC_CDRP_CMD_CONFIG_PORT);
}
int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
@@ -398,20 +473,19 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
struct pci_dev *pdev = adapter->pdev;
- recv_ctx = &adapter->recv_ctx;
+ recv_ctx = adapter->recv_ctx;
tx_ring = adapter->tx_ring;
- tx_ring->hw_consumer = (__le32 *)pci_alloc_consistent(pdev, sizeof(u32),
- &tx_ring->hw_cons_phys_addr);
+ tx_ring->hw_consumer = (__le32 *) dma_alloc_coherent(&pdev->dev,
+ sizeof(u32), &tx_ring->hw_cons_phys_addr, GFP_KERNEL);
if (tx_ring->hw_consumer == NULL) {
dev_err(&pdev->dev, "failed to allocate tx consumer\n");
return -ENOMEM;
}
- *(tx_ring->hw_consumer) = 0;
/* cmd desc ring */
- addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring),
- &tx_ring->phys_addr);
+ addr = dma_alloc_coherent(&pdev->dev, TX_DESC_RINGSIZE(tx_ring),
+ &tx_ring->phys_addr, GFP_KERNEL);
if (addr == NULL) {
dev_err(&pdev->dev, "failed to allocate tx desc ring\n");
@@ -423,9 +497,9 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
- addr = pci_alloc_consistent(adapter->pdev,
+ addr = dma_alloc_coherent(&adapter->pdev->dev,
RCV_DESC_RINGSIZE(rds_ring),
- &rds_ring->phys_addr);
+ &rds_ring->phys_addr, GFP_KERNEL);
if (addr == NULL) {
dev_err(&pdev->dev,
"failed to allocate rds ring [%d]\n", ring);
@@ -439,9 +513,9 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
sds_ring = &recv_ctx->sds_rings[ring];
- addr = pci_alloc_consistent(adapter->pdev,
+ addr = dma_alloc_coherent(&adapter->pdev->dev,
STATUS_DESC_RINGSIZE(sds_ring),
- &sds_ring->phys_addr);
+ &sds_ring->phys_addr, GFP_KERNEL);
if (addr == NULL) {
dev_err(&pdev->dev,
"failed to allocate sds ring [%d]\n", ring);
@@ -501,11 +575,11 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
struct qlcnic_host_tx_ring *tx_ring;
int ring;
- recv_ctx = &adapter->recv_ctx;
+ recv_ctx = adapter->recv_ctx;
tx_ring = adapter->tx_ring;
if (tx_ring->hw_consumer != NULL) {
- pci_free_consistent(adapter->pdev,
+ dma_free_coherent(&adapter->pdev->dev,
sizeof(u32),
tx_ring->hw_consumer,
tx_ring->hw_cons_phys_addr);
@@ -513,7 +587,7 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
}
if (tx_ring->desc_head != NULL) {
- pci_free_consistent(adapter->pdev,
+ dma_free_coherent(&adapter->pdev->dev,
TX_DESC_RINGSIZE(tx_ring),
tx_ring->desc_head, tx_ring->phys_addr);
tx_ring->desc_head = NULL;
@@ -523,7 +597,7 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
rds_ring = &recv_ctx->rds_rings[ring];
if (rds_ring->desc_head != NULL) {
- pci_free_consistent(adapter->pdev,
+ dma_free_coherent(&adapter->pdev->dev,
RCV_DESC_RINGSIZE(rds_ring),
rds_ring->desc_head,
rds_ring->phys_addr);
@@ -535,7 +609,7 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
sds_ring = &recv_ctx->sds_rings[ring];
if (sds_ring->desc_head != NULL) {
- pci_free_consistent(adapter->pdev,
+ dma_free_coherent(&adapter->pdev->dev,
STATUS_DESC_RINGSIZE(sds_ring),
sds_ring->desc_head,
sds_ring->phys_addr);
@@ -551,9 +625,9 @@ int qlcnic_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac)
int err;
u32 arg1;
- arg1 = adapter->ahw.pci_func | BIT_8;
+ arg1 = adapter->ahw->pci_func | BIT_8;
err = qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
+ adapter->ahw->pci_func,
adapter->fw_hal_version,
arg1,
0,
@@ -582,15 +656,15 @@ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter,
void *nic_info_addr;
size_t nic_size = sizeof(struct qlcnic_info);
- nic_info_addr = pci_alloc_consistent(adapter->pdev,
- nic_size, &nic_dma_t);
+ nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size,
+ &nic_dma_t, GFP_KERNEL);
if (!nic_info_addr)
return -ENOMEM;
memset(nic_info_addr, 0, nic_size);
nic_info = (struct qlcnic_info *) nic_info_addr;
err = qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
+ adapter->ahw->pci_func,
adapter->fw_hal_version,
MSD(nic_dma_t),
LSD(nic_dma_t),
@@ -623,7 +697,8 @@ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter,
err = -EIO;
}
- pci_free_consistent(adapter->pdev, nic_size, nic_info_addr, nic_dma_t);
+ dma_free_coherent(&adapter->pdev->dev, nic_size, nic_info_addr,
+ nic_dma_t);
return err;
}
@@ -639,8 +714,8 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic)
if (adapter->op_mode != QLCNIC_MGMT_FUNC)
return err;
- nic_info_addr = pci_alloc_consistent(adapter->pdev, nic_size,
- &nic_dma_t);
+ nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size,
+ &nic_dma_t, GFP_KERNEL);
if (!nic_info_addr)
return -ENOMEM;
@@ -659,7 +734,7 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic)
nic_info->max_tx_bw = cpu_to_le16(nic->max_tx_bw);
err = qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
+ adapter->ahw->pci_func,
adapter->fw_hal_version,
MSD(nic_dma_t),
LSD(nic_dma_t),
@@ -672,7 +747,8 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic)
err = -EIO;
}
- pci_free_consistent(adapter->pdev, nic_size, nic_info_addr, nic_dma_t);
+ dma_free_coherent(&adapter->pdev->dev, nic_size, nic_info_addr,
+ nic_dma_t);
return err;
}
@@ -687,15 +763,15 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter,
size_t npar_size = sizeof(struct qlcnic_pci_info);
size_t pci_size = npar_size * QLCNIC_MAX_PCI_FUNC;
- pci_info_addr = pci_alloc_consistent(adapter->pdev, pci_size,
- &pci_info_dma_t);
+ pci_info_addr = dma_alloc_coherent(&adapter->pdev->dev, pci_size,
+ &pci_info_dma_t, GFP_KERNEL);
if (!pci_info_addr)
return -ENOMEM;
memset(pci_info_addr, 0, pci_size);
npar = (struct qlcnic_pci_info *) pci_info_addr;
err = qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
+ adapter->ahw->pci_func,
adapter->fw_hal_version,
MSD(pci_info_dma_t),
LSD(pci_info_dma_t),
@@ -721,7 +797,7 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter,
err = -EIO;
}
- pci_free_consistent(adapter->pdev, pci_size, pci_info_addr,
+ dma_free_coherent(&adapter->pdev->dev, pci_size, pci_info_addr,
pci_info_dma_t);
return err;
}
@@ -741,7 +817,7 @@ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id,
arg1 |= pci_func << 8;
err = qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
+ adapter->ahw->pci_func,
adapter->fw_hal_version,
arg1,
0,
@@ -775,14 +851,14 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func,
return -ENOMEM;
if (adapter->op_mode != QLCNIC_MGMT_FUNC &&
- func != adapter->ahw.pci_func) {
+ func != adapter->ahw->pci_func) {
dev_err(&adapter->pdev->dev,
"Not privilege to query stats for func=%d", func);
return -EIO;
}
- stats_addr = pci_alloc_consistent(adapter->pdev, stats_size,
- &stats_dma_t);
+ stats_addr = dma_alloc_coherent(&adapter->pdev->dev, stats_size,
+ &stats_dma_t, GFP_KERNEL);
if (!stats_addr) {
dev_err(&adapter->pdev->dev, "Unable to allocate memory\n");
return -ENOMEM;
@@ -793,7 +869,7 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func,
arg1 |= rx_tx << 15 | stats_size << 16;
err = qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
+ adapter->ahw->pci_func,
adapter->fw_hal_version,
arg1,
MSD(stats_dma_t),
@@ -816,7 +892,7 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func,
esw_stats->numbytes = le64_to_cpu(stats->numbytes);
}
- pci_free_consistent(adapter->pdev, stats_size, stats_addr,
+ dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr,
stats_dma_t);
return err;
}
@@ -900,7 +976,7 @@ int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw,
arg1 |= BIT_14 | rx_tx << 15;
return qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
+ adapter->ahw->pci_func,
adapter->fw_hal_version,
arg1,
0,
@@ -921,7 +997,7 @@ __qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
u8 pci_func;
pci_func = (*arg1 >> 8);
err = qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
+ adapter->ahw->pci_func,
adapter->fw_hal_version,
*arg1,
0,
@@ -999,7 +1075,7 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter,
}
err = qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
+ adapter->ahw->pci_func,
adapter->fw_hal_version,
arg1,
arg2,
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 45b2755d6cb..9efc690a289 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -150,10 +150,10 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
struct qlcnic_adapter *adapter = netdev_priv(dev);
int check_sfp_module = 0;
- u16 pcifn = adapter->ahw.pci_func;
+ u16 pcifn = adapter->ahw->pci_func;
/* read which mode */
- if (adapter->ahw.port_type == QLCNIC_GBE) {
+ if (adapter->ahw->port_type == QLCNIC_GBE) {
ecmd->supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
@@ -166,11 +166,11 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ADVERTISED_1000baseT_Half |
ADVERTISED_1000baseT_Full);
- ecmd->speed = adapter->link_speed;
+ ethtool_cmd_speed_set(ecmd, adapter->link_speed);
ecmd->duplex = adapter->link_duplex;
ecmd->autoneg = adapter->link_autoneg;
- } else if (adapter->ahw.port_type == QLCNIC_XGBE) {
+ } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
u32 val;
val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
@@ -183,15 +183,15 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
}
if (netif_running(dev) && adapter->has_link_events) {
- ecmd->speed = adapter->link_speed;
+ ethtool_cmd_speed_set(ecmd, adapter->link_speed);
ecmd->autoneg = adapter->link_autoneg;
ecmd->duplex = adapter->link_duplex;
goto skip;
}
val = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn));
- ecmd->speed = P3P_LINK_SPEED_MHZ *
- P3P_LINK_SPEED_VAL(pcifn, val);
+ ethtool_cmd_speed_set(ecmd, P3P_LINK_SPEED_MHZ *
+ P3P_LINK_SPEED_VAL(pcifn, val));
ecmd->duplex = DUPLEX_FULL;
ecmd->autoneg = AUTONEG_DISABLE;
} else
@@ -201,7 +201,7 @@ skip:
ecmd->phy_address = adapter->physical_port;
ecmd->transceiver = XCVR_EXTERNAL;
- switch (adapter->ahw.board_type) {
+ switch (adapter->ahw->board_type) {
case QLCNIC_BRDTYPE_P3P_REF_QG:
case QLCNIC_BRDTYPE_P3P_4_GB:
case QLCNIC_BRDTYPE_P3P_4_GB_MM:
@@ -238,7 +238,7 @@ skip:
ecmd->autoneg = AUTONEG_DISABLE;
break;
case QLCNIC_BRDTYPE_P3P_10G_TP:
- if (adapter->ahw.port_type == QLCNIC_XGBE) {
+ if (adapter->ahw->port_type == QLCNIC_XGBE) {
ecmd->autoneg = AUTONEG_DISABLE;
ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
ecmd->advertising |=
@@ -256,7 +256,7 @@ skip:
break;
default:
dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
- adapter->ahw.board_type);
+ adapter->ahw->board_type);
return -EIO;
}
@@ -284,50 +284,44 @@ skip:
static int
qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
+ u32 config = 0;
+ u32 ret = 0;
struct qlcnic_adapter *adapter = netdev_priv(dev);
- __u32 status;
+
+ if (adapter->ahw->port_type != QLCNIC_GBE)
+ return -EOPNOTSUPP;
/* read which mode */
- if (adapter->ahw.port_type == QLCNIC_GBE) {
- /* autonegotiation */
- if (qlcnic_fw_cmd_set_phy(adapter,
- QLCNIC_NIU_GB_MII_MGMT_ADDR_AUTONEG,
- ecmd->autoneg) != 0)
- return -EIO;
- else
- adapter->link_autoneg = ecmd->autoneg;
+ if (ecmd->duplex)
+ config |= 0x1;
- if (qlcnic_fw_cmd_query_phy(adapter,
- QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
- &status) != 0)
- return -EIO;
+ if (ecmd->autoneg)
+ config |= 0x2;
- switch (ecmd->speed) {
- case SPEED_10:
- qlcnic_set_phy_speed(status, 0);
- break;
- case SPEED_100:
- qlcnic_set_phy_speed(status, 1);
- break;
- case SPEED_1000:
- qlcnic_set_phy_speed(status, 2);
- break;
- }
+ switch (ethtool_cmd_speed(ecmd)) {
+ case SPEED_10:
+ config |= (0 << 8);
+ break;
+ case SPEED_100:
+ config |= (1 << 8);
+ break;
+ case SPEED_1000:
+ config |= (10 << 8);
+ break;
+ default:
+ return -EIO;
+ }
- if (ecmd->duplex == DUPLEX_HALF)
- qlcnic_clear_phy_duplex(status);
- if (ecmd->duplex == DUPLEX_FULL)
- qlcnic_set_phy_duplex(status);
- if (qlcnic_fw_cmd_set_phy(adapter,
- QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
- *((int *)&status)) != 0)
- return -EIO;
- else {
- adapter->link_speed = ecmd->speed;
- adapter->link_duplex = ecmd->duplex;
- }
- } else
+ ret = qlcnic_fw_cmd_set_port(adapter, config);
+
+ if (ret == QLCNIC_RCODE_NOT_SUPPORTED)
return -EOPNOTSUPP;
+ else if (ret)
+ return -EIO;
+
+ adapter->link_speed = ethtool_cmd_speed(ecmd);
+ adapter->link_duplex = ecmd->duplex;
+ adapter->link_autoneg = ecmd->autoneg;
if (!netif_running(dev))
return 0;
@@ -340,14 +334,14 @@ static void
qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
{
struct qlcnic_adapter *adapter = netdev_priv(dev);
- struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
struct qlcnic_host_sds_ring *sds_ring;
u32 *regs_buff = p;
int ring, i = 0, j = 0;
memset(p, 0, qlcnic_get_regs_len(dev));
regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
- (adapter->ahw.revision_id << 16) | (adapter->pdev)->device;
+ (adapter->ahw->revision_id << 16) | (adapter->pdev)->device;
regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
regs_buff[1] = QLCNIC_MGMT_API_VERSION;
@@ -382,7 +376,7 @@ static u32 qlcnic_test_link(struct net_device *dev)
u32 val;
val = QLCRD32(adapter, CRB_XG_STATE_P3P);
- val = XG_LINK_STATE_P3P(adapter->ahw.pci_func, val);
+ val = XG_LINK_STATE_P3P(adapter->ahw->pci_func, val);
return (val == XG_LINK_UP_P3P) ? 0 : 1;
}
@@ -474,6 +468,39 @@ qlcnic_set_ringparam(struct net_device *dev,
return qlcnic_reset_context(adapter);
}
+static void qlcnic_get_channels(struct net_device *dev,
+ struct ethtool_channels *channel)
+{
+ struct qlcnic_adapter *adapter = netdev_priv(dev);
+
+ channel->max_rx = rounddown_pow_of_two(min_t(int,
+ adapter->max_rx_ques, num_online_cpus()));
+ channel->max_tx = adapter->max_tx_ques;
+
+ channel->rx_count = adapter->max_sds_rings;
+ channel->tx_count = adapter->max_tx_ques;
+}
+
+static int qlcnic_set_channels(struct net_device *dev,
+ struct ethtool_channels *channel)
+{
+ struct qlcnic_adapter *adapter = netdev_priv(dev);
+ int err;
+
+ if (channel->other_count || channel->combined_count ||
+ channel->tx_count != channel->max_tx)
+ return -EINVAL;
+
+ err = qlcnic_validate_max_rss(dev, channel->max_rx, channel->rx_count);
+ if (err)
+ return err;
+
+ err = qlcnic_set_max_rss(adapter, channel->rx_count);
+ netdev_info(dev, "allocated 0x%x sds rings\n",
+ adapter->max_sds_rings);
+ return err;
+}
+
static void
qlcnic_get_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
@@ -482,7 +509,7 @@ qlcnic_get_pauseparam(struct net_device *netdev,
int port = adapter->physical_port;
__u32 val;
- if (adapter->ahw.port_type == QLCNIC_GBE) {
+ if (adapter->ahw->port_type == QLCNIC_GBE) {
if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
return;
/* get flow control settings */
@@ -504,7 +531,7 @@ qlcnic_get_pauseparam(struct net_device *netdev,
pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
break;
}
- } else if (adapter->ahw.port_type == QLCNIC_XGBE) {
+ } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
return;
pause->rx_pause = 1;
@@ -515,7 +542,7 @@ qlcnic_get_pauseparam(struct net_device *netdev,
pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val));
} else {
dev_err(&netdev->dev, "Unknown board type: %x\n",
- adapter->ahw.port_type);
+ adapter->ahw->port_type);
}
}
@@ -528,7 +555,7 @@ qlcnic_set_pauseparam(struct net_device *netdev,
__u32 val;
/* read mode */
- if (adapter->ahw.port_type == QLCNIC_GBE) {
+ if (adapter->ahw->port_type == QLCNIC_GBE) {
if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
return -EIO;
/* set flow control */
@@ -571,7 +598,7 @@ qlcnic_set_pauseparam(struct net_device *netdev,
break;
}
QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
- } else if (adapter->ahw.port_type == QLCNIC_XGBE) {
+ } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
if (!pause->rx_pause || pause->autoneg)
return -EOPNOTSUPP;
@@ -593,7 +620,7 @@ qlcnic_set_pauseparam(struct net_device *netdev,
QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val);
} else {
dev_err(&netdev->dev, "Unknown board type: %x\n",
- adapter->ahw.port_type);
+ adapter->ahw->port_type);
}
return 0;
}
@@ -639,8 +666,8 @@ static int qlcnic_irq_test(struct net_device *netdev)
goto clear_it;
adapter->diag_cnt = 0;
- ret = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func,
- adapter->fw_hal_version, adapter->portnum,
+ ret = qlcnic_issue_cmd(adapter, adapter->ahw->pci_func,
+ adapter->fw_hal_version, adapter->ahw->pci_func,
0, 0, 0x00000011);
if (ret)
goto done;
@@ -749,14 +776,14 @@ qlcnic_get_ethtool_stats(struct net_device *dev,
return;
memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
- ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func,
+ ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
if (ret)
return;
qlcnic_fill_device_stats(&index, data, &port_stats.rx);
- ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func,
+ ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
if (ret)
return;
@@ -764,115 +791,49 @@ qlcnic_get_ethtool_stats(struct net_device *dev,
qlcnic_fill_device_stats(&index, data, &port_stats.tx);
}
-static int qlcnic_set_tx_csum(struct net_device *dev, u32 data)
-{
- struct qlcnic_adapter *adapter = netdev_priv(dev);
-
- if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
- return -EOPNOTSUPP;
- if (data)
- dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
- else
- dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-
- return 0;
-
-}
-static u32 qlcnic_get_tx_csum(struct net_device *dev)
-{
- return dev->features & NETIF_F_IP_CSUM;
-}
-
-static u32 qlcnic_get_rx_csum(struct net_device *dev)
-{
- struct qlcnic_adapter *adapter = netdev_priv(dev);
- return adapter->rx_csum;
-}
-
-static int qlcnic_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct qlcnic_adapter *adapter = netdev_priv(dev);
-
- if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
- return -EOPNOTSUPP;
- if (!!data) {
- adapter->rx_csum = !!data;
- return 0;
- }
-
- if (dev->features & NETIF_F_LRO) {
- if (qlcnic_config_hw_lro(adapter, QLCNIC_LRO_DISABLED))
- return -EIO;
-
- dev->features &= ~NETIF_F_LRO;
- qlcnic_send_lro_cleanup(adapter);
- dev_info(&adapter->pdev->dev,
- "disabling LRO as rx_csum is off\n");
- }
- adapter->rx_csum = !!data;
- return 0;
-}
-
-static u32 qlcnic_get_tso(struct net_device *dev)
-{
- return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0;
-}
-
-static int qlcnic_set_tso(struct net_device *dev, u32 data)
-{
- struct qlcnic_adapter *adapter = netdev_priv(dev);
- if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO))
- return -EOPNOTSUPP;
- if (data)
- dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
- else
- dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-
- return 0;
-}
-
-static int qlcnic_blink_led(struct net_device *dev, u32 val)
+static int qlcnic_set_led(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
struct qlcnic_adapter *adapter = netdev_priv(dev);
int max_sds_rings = adapter->max_sds_rings;
- int dev_down = 0;
- int ret;
-
- if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
- dev_down = 1;
- if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
- return -EIO;
- ret = qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST);
- if (ret) {
- clear_bit(__QLCNIC_RESETTING, &adapter->state);
- return ret;
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
+ if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+ return -EIO;
+
+ if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST)) {
+ clear_bit(__QLCNIC_RESETTING, &adapter->state);
+ return -EIO;
+ }
+ set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
}
- }
- ret = adapter->nic_ops->config_led(adapter, 1, 0xf);
- if (ret) {
+ if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0)
+ return 0;
+
dev_err(&adapter->pdev->dev,
"Failed to set LED blink state.\n");
- goto done;
- }
+ break;
- msleep_interruptible(val * 1000);
+ case ETHTOOL_ID_INACTIVE:
+ if (adapter->nic_ops->config_led(adapter, 0, 0xf))
+ dev_err(&adapter->pdev->dev,
+ "Failed to reset LED blink state.\n");
- ret = adapter->nic_ops->config_led(adapter, 0, 0xf);
- if (ret) {
- dev_err(&adapter->pdev->dev,
- "Failed to reset LED blink state.\n");
- goto done;
+ break;
+
+ default:
+ return -EINVAL;
}
-done:
- if (dev_down) {
+ if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) {
qlcnic_diag_free_res(dev, max_sds_rings);
clear_bit(__QLCNIC_RESETTING, &adapter->state);
}
- return ret;
+ return -EIO;
}
static void
@@ -936,8 +897,8 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev,
*/
if (ethcoal->rx_coalesce_usecs > 0xffff ||
ethcoal->rx_max_coalesced_frames > 0xffff ||
- ethcoal->tx_coalesce_usecs > 0xffff ||
- ethcoal->tx_max_coalesced_frames > 0xffff ||
+ ethcoal->tx_coalesce_usecs ||
+ ethcoal->tx_max_coalesced_frames ||
ethcoal->rx_coalesce_usecs_irq ||
ethcoal->rx_max_coalesced_frames_irq ||
ethcoal->tx_coalesce_usecs_irq ||
@@ -959,21 +920,17 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev,
if (!ethcoal->rx_coalesce_usecs ||
!ethcoal->rx_max_coalesced_frames) {
- adapter->coal.flags = QLCNIC_INTR_DEFAULT;
- adapter->coal.normal.data.rx_time_us =
+ adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT;
+ adapter->ahw->coal.rx_time_us =
QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
- adapter->coal.normal.data.rx_packets =
+ adapter->ahw->coal.rx_packets =
QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
} else {
- adapter->coal.flags = 0;
- adapter->coal.normal.data.rx_time_us =
- ethcoal->rx_coalesce_usecs;
- adapter->coal.normal.data.rx_packets =
- ethcoal->rx_max_coalesced_frames;
+ adapter->ahw->coal.flag = 0;
+ adapter->ahw->coal.rx_time_us = ethcoal->rx_coalesce_usecs;
+ adapter->ahw->coal.rx_packets =
+ ethcoal->rx_max_coalesced_frames;
}
- adapter->coal.normal.data.tx_time_us = ethcoal->tx_coalesce_usecs;
- adapter->coal.normal.data.tx_packets =
- ethcoal->tx_max_coalesced_frames;
qlcnic_config_intr_coalesce(adapter);
@@ -988,66 +945,102 @@ static int qlcnic_get_intr_coalesce(struct net_device *netdev,
if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
return -EINVAL;
- ethcoal->rx_coalesce_usecs = adapter->coal.normal.data.rx_time_us;
- ethcoal->tx_coalesce_usecs = adapter->coal.normal.data.tx_time_us;
- ethcoal->rx_max_coalesced_frames =
- adapter->coal.normal.data.rx_packets;
- ethcoal->tx_max_coalesced_frames =
- adapter->coal.normal.data.tx_packets;
+ ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us;
+ ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets;
return 0;
}
-static int qlcnic_set_flags(struct net_device *netdev, u32 data)
+static u32 qlcnic_get_msglevel(struct net_device *netdev)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
- int hw_lro;
-
- if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
- return -EINVAL;
-
- if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO))
- return -EINVAL;
-
- if (!adapter->rx_csum) {
- dev_info(&adapter->pdev->dev, "rx csum is off, "
- "cannot toggle lro\n");
- return -EINVAL;
- }
- if ((data & ETH_FLAG_LRO) && (netdev->features & NETIF_F_LRO))
- return 0;
-
- if (data & ETH_FLAG_LRO) {
- hw_lro = QLCNIC_LRO_ENABLED;
- netdev->features |= NETIF_F_LRO;
- } else {
- hw_lro = 0;
- netdev->features &= ~NETIF_F_LRO;
- }
+ return adapter->msg_enable;
+}
- if (qlcnic_config_hw_lro(adapter, hw_lro))
- return -EIO;
+static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
+{
+ struct qlcnic_adapter *adapter = netdev_priv(netdev);
- if ((hw_lro == 0) && qlcnic_send_lro_cleanup(adapter))
- return -EIO;
+ adapter->msg_enable = msglvl;
+}
+static int
+qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
+{
+ struct qlcnic_adapter *adapter = netdev_priv(netdev);
+ struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
+ dump->len = fw_dump->tmpl_hdr->size + fw_dump->size;
+ dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
+ dump->version = adapter->fw_version;
return 0;
}
-static u32 qlcnic_get_msglevel(struct net_device *netdev)
+static int
+qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
+ void *buffer)
{
+ int i, copy_sz;
+ u32 *hdr_ptr, *data;
struct qlcnic_adapter *adapter = netdev_priv(netdev);
+ struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
- return adapter->msg_enable;
+ if (qlcnic_api_lock(adapter))
+ return -EIO;
+ if (!fw_dump->clr) {
+ netdev_info(netdev, "Dump not available\n");
+ qlcnic_api_unlock(adapter);
+ return -EINVAL;
+ }
+ /* Copy template header first */
+ copy_sz = fw_dump->tmpl_hdr->size;
+ hdr_ptr = (u32 *) fw_dump->tmpl_hdr;
+ data = (u32 *) buffer;
+ for (i = 0; i < copy_sz/sizeof(u32); i++)
+ *data++ = cpu_to_le32(*hdr_ptr++);
+
+ /* Copy captured dump data */
+ memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
+ dump->len = copy_sz + fw_dump->size;
+ dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
+
+ /* Free dump area once data has been captured */
+ vfree(fw_dump->data);
+ fw_dump->data = NULL;
+ fw_dump->clr = 0;
+ qlcnic_api_unlock(adapter);
+
+ return 0;
}
-static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
+static int
+qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
{
+ int ret = 0;
struct qlcnic_adapter *adapter = netdev_priv(netdev);
+ struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
- adapter->msg_enable = msglvl;
+ if (val->flag == QLCNIC_FORCE_FW_DUMP_KEY) {
+ netdev_info(netdev, "Forcing a FW dump\n");
+ qlcnic_dev_request_reset(adapter);
+ } else {
+ if (val->flag > QLCNIC_DUMP_MASK_MAX ||
+ val->flag < QLCNIC_DUMP_MASK_MIN) {
+ netdev_info(netdev,
+ "Invalid dump level: 0x%x\n", val->flag);
+ ret = -EINVAL;
+ goto out;
+ }
+ if (qlcnic_api_lock(adapter))
+ return -EIO;
+ fw_dump->tmpl_hdr->drv_cap_mask = val->flag & 0xff;
+ qlcnic_api_unlock(adapter);
+ netdev_info(netdev, "Driver mask changed to: 0x%x\n",
+ fw_dump->tmpl_hdr->drv_cap_mask);
+ }
+out:
+ return ret;
}
const struct ethtool_ops qlcnic_ethtool_ops = {
@@ -1061,26 +1054,22 @@ const struct ethtool_ops qlcnic_ethtool_ops = {
.get_eeprom = qlcnic_get_eeprom,
.get_ringparam = qlcnic_get_ringparam,
.set_ringparam = qlcnic_set_ringparam,
+ .get_channels = qlcnic_get_channels,
+ .set_channels = qlcnic_set_channels,
.get_pauseparam = qlcnic_get_pauseparam,
.set_pauseparam = qlcnic_set_pauseparam,
- .get_tx_csum = qlcnic_get_tx_csum,
- .set_tx_csum = qlcnic_set_tx_csum,
- .set_sg = ethtool_op_set_sg,
- .get_tso = qlcnic_get_tso,
- .set_tso = qlcnic_set_tso,
.get_wol = qlcnic_get_wol,
.set_wol = qlcnic_set_wol,
.self_test = qlcnic_diag_test,
.get_strings = qlcnic_get_strings,
.get_ethtool_stats = qlcnic_get_ethtool_stats,
.get_sset_count = qlcnic_get_sset_count,
- .get_rx_csum = qlcnic_get_rx_csum,
- .set_rx_csum = qlcnic_set_rx_csum,
.get_coalesce = qlcnic_get_intr_coalesce,
.set_coalesce = qlcnic_set_intr_coalesce,
- .get_flags = ethtool_op_get_flags,
- .set_flags = qlcnic_set_flags,
- .phys_id = qlcnic_blink_led,
+ .set_phys_id = qlcnic_set_led,
.set_msglevel = qlcnic_set_msglevel,
.get_msglevel = qlcnic_get_msglevel,
+ .get_dump_flag = qlcnic_get_dump_flag,
+ .get_dump_data = qlcnic_get_dump_data,
+ .set_dump = qlcnic_set_dump,
};
diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h
index 726ef555b6b..d14506f764e 100644
--- a/drivers/net/qlcnic/qlcnic_hdr.h
+++ b/drivers/net/qlcnic/qlcnic_hdr.h
@@ -492,10 +492,10 @@ enum {
#define TEST_AGT_CTRL (0x00)
-#define TA_CTL_START 1
-#define TA_CTL_ENABLE 2
-#define TA_CTL_WRITE 4
-#define TA_CTL_BUSY 8
+#define TA_CTL_START BIT_0
+#define TA_CTL_ENABLE BIT_1
+#define TA_CTL_WRITE BIT_2
+#define TA_CTL_BUSY BIT_3
/*
* Register offsets for MN
@@ -765,6 +765,38 @@ struct qlcnic_legacy_intr_set {
#define QLCNIC_MAX_PCI_FUNC 8
#define QLCNIC_MAX_VLAN_FILTERS 64
+/* FW dump defines */
+#define MIU_TEST_CTR 0x41000090
+#define MIU_TEST_ADDR_LO 0x41000094
+#define MIU_TEST_ADDR_HI 0x41000098
+#define FLASH_ROM_WINDOW 0x42110030
+#define FLASH_ROM_DATA 0x42150000
+
+static const u32 MIU_TEST_READ_DATA[] = {
+ 0x410000A8, 0x410000AC, 0x410000B8, 0x410000BC, };
+
+#define QLCNIC_FW_DUMP_REG1 0x00130060
+#define QLCNIC_FW_DUMP_REG2 0x001e0000
+#define QLCNIC_FLASH_SEM2_LK 0x0013C010
+#define QLCNIC_FLASH_SEM2_ULK 0x0013C014
+#define QLCNIC_FLASH_LOCK_ID 0x001B2100
+
+#define QLCNIC_RD_DUMP_REG(addr, bar0, data) do { \
+ writel((addr & 0xFFFF0000), (void *) (bar0 + \
+ QLCNIC_FW_DUMP_REG1)); \
+ readl((void *) (bar0 + QLCNIC_FW_DUMP_REG1)); \
+ *data = readl((void *) (bar0 + QLCNIC_FW_DUMP_REG2 + \
+ LSW(addr))); \
+} while (0)
+
+#define QLCNIC_WR_DUMP_REG(addr, bar0, data) do { \
+ writel((addr & 0xFFFF0000), (void *) (bar0 + \
+ QLCNIC_FW_DUMP_REG1)); \
+ readl((void *) (bar0 + QLCNIC_FW_DUMP_REG1)); \
+ writel(data, (void *) (bar0 + QLCNIC_FW_DUMP_REG2 + LSW(addr)));\
+ readl((void *) (bar0 + QLCNIC_FW_DUMP_REG2 + LSW(addr))); \
+} while (0)
+
/* PCI function operational mode */
enum {
QLCNIC_MGMT_FUNC = 0,
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index 616940f0a8d..e9656616f2a 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -9,6 +9,7 @@
#include <linux/slab.h>
#include <net/ip.h>
+#include <linux/bitops.h>
#define MASK(n) ((1ULL<<(n))-1)
#define OCM_WIN_P3P(addr) (addr & 0xffc0000)
@@ -457,7 +458,7 @@ int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
- word = QLCNIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE |
+ word = QLCNIC_H2C_OPCODE_SET_MAC_RECEIVE_MODE |
((u64)adapter->portnum << 16);
req.req_hdr = cpu_to_le64(word);
@@ -532,33 +533,31 @@ void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter)
}
}
-#define QLCNIC_CONFIG_INTR_COALESCE 3
-
/*
* Send the interrupt coalescing parameter set by ethtool to the card.
*/
int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter)
{
struct qlcnic_nic_req req;
- u64 word[6];
- int rv, i;
+ int rv;
memset(&req, 0, sizeof(struct qlcnic_nic_req));
req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
- word[0] = QLCNIC_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16);
- req.req_hdr = cpu_to_le64(word[0]);
-
- memcpy(&word[0], &adapter->coal, sizeof(adapter->coal));
- for (i = 0; i < 6; i++)
- req.words[i] = cpu_to_le64(word[i]);
+ req.req_hdr = cpu_to_le64(QLCNIC_CONFIG_INTR_COALESCE |
+ ((u64) adapter->portnum << 16));
+ req.words[0] = cpu_to_le64(((u64) adapter->ahw->coal.flag) << 32);
+ req.words[2] = cpu_to_le64(adapter->ahw->coal.rx_packets |
+ ((u64) adapter->ahw->coal.rx_time_us) << 16);
+ req.words[5] = cpu_to_le64(adapter->ahw->coal.timer_out |
+ ((u64) adapter->ahw->coal.type) << 32 |
+ ((u64) adapter->ahw->coal.sts_ring_mask) << 40);
rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
if (rv != 0)
dev_err(&adapter->netdev->dev,
"Could not send interrupt coalescing parameters\n");
-
return rv;
}
@@ -568,6 +567,9 @@ int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable)
u64 word;
int rv;
+ if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
+ return 0;
+
memset(&req, 0, sizeof(struct qlcnic_nic_req));
req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
@@ -713,6 +715,9 @@ int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter)
u64 word;
int rv;
+ if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
+ return 0;
+
memset(&req, 0, sizeof(struct qlcnic_nic_req));
req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
@@ -754,6 +759,43 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu)
return rc;
}
+
+u32 qlcnic_fix_features(struct net_device *netdev, u32 features)
+{
+ struct qlcnic_adapter *adapter = netdev_priv(netdev);
+
+ if ((adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
+ u32 changed = features ^ netdev->features;
+ features ^= changed & (NETIF_F_ALL_CSUM | NETIF_F_RXCSUM);
+ }
+
+ if (!(features & NETIF_F_RXCSUM))
+ features &= ~NETIF_F_LRO;
+
+ return features;
+}
+
+
+int qlcnic_set_features(struct net_device *netdev, u32 features)
+{
+ struct qlcnic_adapter *adapter = netdev_priv(netdev);
+ u32 changed = netdev->features ^ features;
+ int hw_lro = (features & NETIF_F_LRO) ? QLCNIC_LRO_ENABLED : 0;
+
+ if (!(changed & NETIF_F_LRO))
+ return 0;
+
+ netdev->features = features ^ NETIF_F_LRO;
+
+ if (qlcnic_config_hw_lro(adapter, hw_lro))
+ return -EIO;
+
+ if ((hw_lro == 0) && qlcnic_send_lro_cleanup(adapter))
+ return -EIO;
+
+ return 0;
+}
+
/*
* Changes the CRB window to the specified window.
*/
@@ -780,7 +822,7 @@ qlcnic_pci_get_crb_addr_2M(struct qlcnic_adapter *adapter,
m = &crb_128M_2M_map[CRB_BLK(off)].sub_block[CRB_SUBBLK(off)];
if (m->valid && (m->start_128M <= off) && (m->end_128M > off)) {
- *addr = adapter->ahw.pci_base0 + m->start_2M +
+ *addr = adapter->ahw->pci_base0 + m->start_2M +
(off - m->start_128M);
return 0;
}
@@ -788,7 +830,7 @@ qlcnic_pci_get_crb_addr_2M(struct qlcnic_adapter *adapter,
/*
* Not in direct map, use crb window
*/
- *addr = adapter->ahw.pci_base0 + CRB_INDIRECT_2M + (off & MASK(16));
+ *addr = adapter->ahw->pci_base0 + CRB_INDIRECT_2M + (off & MASK(16));
return 1;
}
@@ -801,7 +843,7 @@ static int
qlcnic_pci_set_crbwindow_2M(struct qlcnic_adapter *adapter, ulong off)
{
u32 window;
- void __iomem *addr = adapter->ahw.pci_base0 + CRB_WINDOW_2M;
+ void __iomem *addr = adapter->ahw->pci_base0 + CRB_WINDOW_2M;
off -= QLCNIC_PCI_CRBSPACE;
@@ -838,13 +880,13 @@ qlcnic_hw_write_wx_2M(struct qlcnic_adapter *adapter, ulong off, u32 data)
if (rv > 0) {
/* indirect access */
- write_lock_irqsave(&adapter->ahw.crb_lock, flags);
+ write_lock_irqsave(&adapter->ahw->crb_lock, flags);
crb_win_lock(adapter);
rv = qlcnic_pci_set_crbwindow_2M(adapter, off);
if (!rv)
writel(data, addr);
crb_win_unlock(adapter);
- write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
+ write_unlock_irqrestore(&adapter->ahw->crb_lock, flags);
return rv;
}
@@ -869,12 +911,12 @@ qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off)
if (rv > 0) {
/* indirect access */
- write_lock_irqsave(&adapter->ahw.crb_lock, flags);
+ write_lock_irqsave(&adapter->ahw->crb_lock, flags);
crb_win_lock(adapter);
if (!qlcnic_pci_set_crbwindow_2M(adapter, off))
data = readl(addr);
crb_win_unlock(adapter);
- write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
+ write_unlock_irqrestore(&adapter->ahw->crb_lock, flags);
return data;
}
@@ -904,9 +946,9 @@ qlcnic_pci_set_window_2M(struct qlcnic_adapter *adapter,
window = OCM_WIN_P3P(addr);
- writel(window, adapter->ahw.ocm_win_crb);
+ writel(window, adapter->ahw->ocm_win_crb);
/* read back to flush */
- readl(adapter->ahw.ocm_win_crb);
+ readl(adapter->ahw->ocm_win_crb);
*start = QLCNIC_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr);
return 0;
@@ -920,13 +962,13 @@ qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off,
int ret;
u32 start;
- mutex_lock(&adapter->ahw.mem_lock);
+ mutex_lock(&adapter->ahw->mem_lock);
ret = qlcnic_pci_set_window_2M(adapter, off, &start);
if (ret != 0)
goto unlock;
- addr = adapter->ahw.pci_base0 + start;
+ addr = adapter->ahw->pci_base0 + start;
if (op == 0) /* read */
*data = readq(addr);
@@ -934,7 +976,7 @@ qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off,
writeq(*data, addr);
unlock:
- mutex_unlock(&adapter->ahw.mem_lock);
+ mutex_unlock(&adapter->ahw->mem_lock);
return ret;
}
@@ -942,23 +984,23 @@ unlock:
void
qlcnic_pci_camqm_read_2M(struct qlcnic_adapter *adapter, u64 off, u64 *data)
{
- void __iomem *addr = adapter->ahw.pci_base0 +
+ void __iomem *addr = adapter->ahw->pci_base0 +
QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM);
- mutex_lock(&adapter->ahw.mem_lock);
+ mutex_lock(&adapter->ahw->mem_lock);
*data = readq(addr);
- mutex_unlock(&adapter->ahw.mem_lock);
+ mutex_unlock(&adapter->ahw->mem_lock);
}
void
qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *adapter, u64 off, u64 data)
{
- void __iomem *addr = adapter->ahw.pci_base0 +
+ void __iomem *addr = adapter->ahw->pci_base0 +
QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM);
- mutex_lock(&adapter->ahw.mem_lock);
+ mutex_lock(&adapter->ahw->mem_lock);
writeq(data, addr);
- mutex_unlock(&adapter->ahw.mem_lock);
+ mutex_unlock(&adapter->ahw->mem_lock);
}
#define MAX_CTL_CHECK 1000
@@ -997,7 +1039,7 @@ qlcnic_pci_mem_write_2M(struct qlcnic_adapter *adapter,
correct:
off8 = off & ~0xf;
- mutex_lock(&adapter->ahw.mem_lock);
+ mutex_lock(&adapter->ahw->mem_lock);
writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
@@ -1049,7 +1091,7 @@ correct:
ret = 0;
done:
- mutex_unlock(&adapter->ahw.mem_lock);
+ mutex_unlock(&adapter->ahw->mem_lock);
return ret;
}
@@ -1091,7 +1133,7 @@ qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter,
correct:
off8 = off & ~0xf;
- mutex_lock(&adapter->ahw.mem_lock);
+ mutex_lock(&adapter->ahw->mem_lock);
writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
@@ -1121,7 +1163,7 @@ correct:
ret = 0;
}
- mutex_unlock(&adapter->ahw.mem_lock);
+ mutex_unlock(&adapter->ahw->mem_lock);
return ret;
}
@@ -1145,7 +1187,7 @@ int qlcnic_get_board_info(struct qlcnic_adapter *adapter)
if (qlcnic_rom_fast_read(adapter, offset, &board_type))
return -EIO;
- adapter->ahw.board_type = board_type;
+ adapter->ahw->board_type = board_type;
if (board_type == QLCNIC_BRDTYPE_P3P_4_GB_MM) {
u32 gpio = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_PAD_GPIO_I);
@@ -1164,20 +1206,20 @@ int qlcnic_get_board_info(struct qlcnic_adapter *adapter)
case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
case QLCNIC_BRDTYPE_P3P_10G_XFP:
case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
- adapter->ahw.port_type = QLCNIC_XGBE;
+ adapter->ahw->port_type = QLCNIC_XGBE;
break;
case QLCNIC_BRDTYPE_P3P_REF_QG:
case QLCNIC_BRDTYPE_P3P_4_GB:
case QLCNIC_BRDTYPE_P3P_4_GB_MM:
- adapter->ahw.port_type = QLCNIC_GBE;
+ adapter->ahw->port_type = QLCNIC_GBE;
break;
case QLCNIC_BRDTYPE_P3P_10G_TP:
- adapter->ahw.port_type = (adapter->portnum < 2) ?
+ adapter->ahw->port_type = (adapter->portnum < 2) ?
QLCNIC_XGBE : QLCNIC_GBE;
break;
default:
dev_err(&pdev->dev, "unknown board type %x\n", board_type);
- adapter->ahw.port_type = QLCNIC_XGBE;
+ adapter->ahw->port_type = QLCNIC_XGBE;
break;
}
@@ -1220,3 +1262,461 @@ int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
return rv;
}
+
+/* FW dump related functions */
+static u32
+qlcnic_dump_crb(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
+ u32 *buffer)
+{
+ int i;
+ u32 addr, data;
+ struct __crb *crb = &entry->region.crb;
+ void __iomem *base = adapter->ahw->pci_base0;
+
+ addr = crb->addr;
+
+ for (i = 0; i < crb->no_ops; i++) {
+ QLCNIC_RD_DUMP_REG(addr, base, &data);
+ *buffer++ = cpu_to_le32(addr);
+ *buffer++ = cpu_to_le32(data);
+ addr += crb->stride;
+ }
+ return crb->no_ops * 2 * sizeof(u32);
+}
+
+static u32
+qlcnic_dump_ctrl(struct qlcnic_adapter *adapter,
+ struct qlcnic_dump_entry *entry, u32 *buffer)
+{
+ int i, k, timeout = 0;
+ void __iomem *base = adapter->ahw->pci_base0;
+ u32 addr, data;
+ u8 opcode, no_ops;
+ struct __ctrl *ctr = &entry->region.ctrl;
+ struct qlcnic_dump_template_hdr *t_hdr = adapter->ahw->fw_dump.tmpl_hdr;
+
+ addr = ctr->addr;
+ no_ops = ctr->no_ops;
+
+ for (i = 0; i < no_ops; i++) {
+ k = 0;
+ opcode = 0;
+ for (k = 0; k < 8; k++) {
+ if (!(ctr->opcode & (1 << k)))
+ continue;
+ switch (1 << k) {
+ case QLCNIC_DUMP_WCRB:
+ QLCNIC_WR_DUMP_REG(addr, base, ctr->val1);
+ break;
+ case QLCNIC_DUMP_RWCRB:
+ QLCNIC_RD_DUMP_REG(addr, base, &data);
+ QLCNIC_WR_DUMP_REG(addr, base, data);
+ break;
+ case QLCNIC_DUMP_ANDCRB:
+ QLCNIC_RD_DUMP_REG(addr, base, &data);
+ QLCNIC_WR_DUMP_REG(addr, base,
+ (data & ctr->val2));
+ break;
+ case QLCNIC_DUMP_ORCRB:
+ QLCNIC_RD_DUMP_REG(addr, base, &data);
+ QLCNIC_WR_DUMP_REG(addr, base,
+ (data | ctr->val3));
+ break;
+ case QLCNIC_DUMP_POLLCRB:
+ while (timeout <= ctr->timeout) {
+ QLCNIC_RD_DUMP_REG(addr, base, &data);
+ if ((data & ctr->val2) == ctr->val1)
+ break;
+ msleep(1);
+ timeout++;
+ }
+ if (timeout > ctr->timeout) {
+ dev_info(&adapter->pdev->dev,
+ "Timed out, aborting poll CRB\n");
+ return -EINVAL;
+ }
+ break;
+ case QLCNIC_DUMP_RD_SAVE:
+ if (ctr->index_a)
+ addr = t_hdr->saved_state[ctr->index_a];
+ QLCNIC_RD_DUMP_REG(addr, base, &data);
+ t_hdr->saved_state[ctr->index_v] = data;
+ break;
+ case QLCNIC_DUMP_WRT_SAVED:
+ if (ctr->index_v)
+ data = t_hdr->saved_state[ctr->index_v];
+ else
+ data = ctr->val1;
+ if (ctr->index_a)
+ addr = t_hdr->saved_state[ctr->index_a];
+ QLCNIC_WR_DUMP_REG(addr, base, data);
+ break;
+ case QLCNIC_DUMP_MOD_SAVE_ST:
+ data = t_hdr->saved_state[ctr->index_v];
+ data <<= ctr->shl_val;
+ data >>= ctr->shr_val;
+ if (ctr->val2)
+ data &= ctr->val2;
+ data |= ctr->val3;
+ data += ctr->val1;
+ t_hdr->saved_state[ctr->index_v] = data;
+ break;
+ default:
+ dev_info(&adapter->pdev->dev,
+ "Unknown opcode\n");
+ break;
+ }
+ }
+ addr += ctr->stride;
+ }
+ return 0;
+}
+
+static u32
+qlcnic_dump_mux(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
+ u32 *buffer)
+{
+ int loop;
+ u32 val, data = 0;
+ struct __mux *mux = &entry->region.mux;
+ void __iomem *base = adapter->ahw->pci_base0;
+
+ val = mux->val;
+ for (loop = 0; loop < mux->no_ops; loop++) {
+ QLCNIC_WR_DUMP_REG(mux->addr, base, val);
+ QLCNIC_RD_DUMP_REG(mux->read_addr, base, &data);
+ *buffer++ = cpu_to_le32(val);
+ *buffer++ = cpu_to_le32(data);
+ val += mux->val_stride;
+ }
+ return 2 * mux->no_ops * sizeof(u32);
+}
+
+static u32
+qlcnic_dump_que(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
+ u32 *buffer)
+{
+ int i, loop;
+ u32 cnt, addr, data, que_id = 0;
+ void __iomem *base = adapter->ahw->pci_base0;
+ struct __queue *que = &entry->region.que;
+
+ addr = que->read_addr;
+ cnt = que->read_addr_cnt;
+
+ for (loop = 0; loop < que->no_ops; loop++) {
+ QLCNIC_WR_DUMP_REG(que->sel_addr, base, que_id);
+ for (i = 0; i < cnt; i++) {
+ QLCNIC_RD_DUMP_REG(addr, base, &data);
+ *buffer++ = cpu_to_le32(data);
+ addr += que->read_addr_stride;
+ }
+ que_id += que->stride;
+ }
+ return que->no_ops * cnt * sizeof(u32);
+}
+
+static u32
+qlcnic_dump_ocm(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
+ u32 *buffer)
+{
+ int i;
+ u32 data;
+ void __iomem *addr;
+ struct __ocm *ocm = &entry->region.ocm;
+
+ addr = adapter->ahw->pci_base0 + ocm->read_addr;
+ for (i = 0; i < ocm->no_ops; i++) {
+ data = readl(addr);
+ *buffer++ = cpu_to_le32(data);
+ addr += ocm->read_addr_stride;
+ }
+ return ocm->no_ops * sizeof(u32);
+}
+
+static u32
+qlcnic_read_rom(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
+ u32 *buffer)
+{
+ int i, count = 0;
+ u32 fl_addr, size, val, lck_val, addr;
+ struct __mem *rom = &entry->region.mem;
+ void __iomem *base = adapter->ahw->pci_base0;
+
+ fl_addr = rom->addr;
+ size = rom->size/4;
+lock_try:
+ lck_val = readl(base + QLCNIC_FLASH_SEM2_LK);
+ if (!lck_val && count < MAX_CTL_CHECK) {
+ msleep(10);
+ count++;
+ goto lock_try;
+ }
+ writel(adapter->ahw->pci_func, (base + QLCNIC_FLASH_LOCK_ID));
+ for (i = 0; i < size; i++) {
+ addr = fl_addr & 0xFFFF0000;
+ QLCNIC_WR_DUMP_REG(FLASH_ROM_WINDOW, base, addr);
+ addr = LSW(fl_addr) + FLASH_ROM_DATA;
+ QLCNIC_RD_DUMP_REG(addr, base, &val);
+ fl_addr += 4;
+ *buffer++ = cpu_to_le32(val);
+ }
+ readl(base + QLCNIC_FLASH_SEM2_ULK);
+ return rom->size;
+}
+
+static u32
+qlcnic_dump_l1_cache(struct qlcnic_adapter *adapter,
+ struct qlcnic_dump_entry *entry, u32 *buffer)
+{
+ int i;
+ u32 cnt, val, data, addr;
+ void __iomem *base = adapter->ahw->pci_base0;
+ struct __cache *l1 = &entry->region.cache;
+
+ val = l1->init_tag_val;
+
+ for (i = 0; i < l1->no_ops; i++) {
+ QLCNIC_WR_DUMP_REG(l1->addr, base, val);
+ QLCNIC_WR_DUMP_REG(l1->ctrl_addr, base, LSW(l1->ctrl_val));
+ addr = l1->read_addr;
+ cnt = l1->read_addr_num;
+ while (cnt) {
+ QLCNIC_RD_DUMP_REG(addr, base, &data);
+ *buffer++ = cpu_to_le32(data);
+ addr += l1->read_addr_stride;
+ cnt--;
+ }
+ val += l1->stride;
+ }
+ return l1->no_ops * l1->read_addr_num * sizeof(u32);
+}
+
+static u32
+qlcnic_dump_l2_cache(struct qlcnic_adapter *adapter,
+ struct qlcnic_dump_entry *entry, u32 *buffer)
+{
+ int i;
+ u32 cnt, val, data, addr;
+ u8 poll_mask, poll_to, time_out = 0;
+ void __iomem *base = adapter->ahw->pci_base0;
+ struct __cache *l2 = &entry->region.cache;
+
+ val = l2->init_tag_val;
+ poll_mask = LSB(MSW(l2->ctrl_val));
+ poll_to = MSB(MSW(l2->ctrl_val));
+
+ for (i = 0; i < l2->no_ops; i++) {
+ QLCNIC_WR_DUMP_REG(l2->addr, base, val);
+ do {
+ QLCNIC_WR_DUMP_REG(l2->ctrl_addr, base,
+ LSW(l2->ctrl_val));
+ QLCNIC_RD_DUMP_REG(l2->ctrl_addr, base, &data);
+ if (!(data & poll_mask))
+ break;
+ msleep(1);
+ time_out++;
+ } while (time_out <= poll_to);
+ if (time_out > poll_to)
+ return -EINVAL;
+
+ addr = l2->read_addr;
+ cnt = l2->read_addr_num;
+ while (cnt) {
+ QLCNIC_RD_DUMP_REG(addr, base, &data);
+ *buffer++ = cpu_to_le32(data);
+ addr += l2->read_addr_stride;
+ cnt--;
+ }
+ val += l2->stride;
+ }
+ return l2->no_ops * l2->read_addr_num * sizeof(u32);
+}
+
+static u32
+qlcnic_read_memory(struct qlcnic_adapter *adapter,
+ struct qlcnic_dump_entry *entry, u32 *buffer)
+{
+ u32 addr, data, test, ret = 0;
+ int i, reg_read;
+ struct __mem *mem = &entry->region.mem;
+ void __iomem *base = adapter->ahw->pci_base0;
+
+ reg_read = mem->size;
+ addr = mem->addr;
+ /* check for data size of multiple of 16 and 16 byte alignment */
+ if ((addr & 0xf) || (reg_read%16)) {
+ dev_info(&adapter->pdev->dev,
+ "Unaligned memory addr:0x%x size:0x%x\n",
+ addr, reg_read);
+ return -EINVAL;
+ }
+
+ mutex_lock(&adapter->ahw->mem_lock);
+
+ while (reg_read != 0) {
+ QLCNIC_WR_DUMP_REG(MIU_TEST_ADDR_LO, base, addr);
+ QLCNIC_WR_DUMP_REG(MIU_TEST_ADDR_HI, base, 0);
+ QLCNIC_WR_DUMP_REG(MIU_TEST_CTR, base,
+ TA_CTL_ENABLE | TA_CTL_START);
+
+ for (i = 0; i < MAX_CTL_CHECK; i++) {
+ QLCNIC_RD_DUMP_REG(MIU_TEST_CTR, base, &test);
+ if (!(test & TA_CTL_BUSY))
+ break;
+ }
+ if (i == MAX_CTL_CHECK) {
+ if (printk_ratelimit()) {
+ dev_err(&adapter->pdev->dev,
+ "failed to read through agent\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+ for (i = 0; i < 4; i++) {
+ QLCNIC_RD_DUMP_REG(MIU_TEST_READ_DATA[i], base, &data);
+ *buffer++ = cpu_to_le32(data);
+ }
+ addr += 16;
+ reg_read -= 16;
+ ret += 16;
+ }
+out:
+ mutex_unlock(&adapter->ahw->mem_lock);
+ return mem->size;
+}
+
+static u32
+qlcnic_dump_nop(struct qlcnic_adapter *adapter,
+ struct qlcnic_dump_entry *entry, u32 *buffer)
+{
+ entry->hdr.flags |= QLCNIC_DUMP_SKIP;
+ return 0;
+}
+
+struct qlcnic_dump_operations fw_dump_ops[] = {
+ { QLCNIC_DUMP_NOP, qlcnic_dump_nop },
+ { QLCNIC_DUMP_READ_CRB, qlcnic_dump_crb },
+ { QLCNIC_DUMP_READ_MUX, qlcnic_dump_mux },
+ { QLCNIC_DUMP_QUEUE, qlcnic_dump_que },
+ { QLCNIC_DUMP_BRD_CONFIG, qlcnic_read_rom },
+ { QLCNIC_DUMP_READ_OCM, qlcnic_dump_ocm },
+ { QLCNIC_DUMP_PEG_REG, qlcnic_dump_ctrl },
+ { QLCNIC_DUMP_L1_DTAG, qlcnic_dump_l1_cache },
+ { QLCNIC_DUMP_L1_ITAG, qlcnic_dump_l1_cache },
+ { QLCNIC_DUMP_L1_DATA, qlcnic_dump_l1_cache },
+ { QLCNIC_DUMP_L1_INST, qlcnic_dump_l1_cache },
+ { QLCNIC_DUMP_L2_DTAG, qlcnic_dump_l2_cache },
+ { QLCNIC_DUMP_L2_ITAG, qlcnic_dump_l2_cache },
+ { QLCNIC_DUMP_L2_DATA, qlcnic_dump_l2_cache },
+ { QLCNIC_DUMP_L2_INST, qlcnic_dump_l2_cache },
+ { QLCNIC_DUMP_READ_ROM, qlcnic_read_rom },
+ { QLCNIC_DUMP_READ_MEM, qlcnic_read_memory },
+ { QLCNIC_DUMP_READ_CTRL, qlcnic_dump_ctrl },
+ { QLCNIC_DUMP_TLHDR, qlcnic_dump_nop },
+ { QLCNIC_DUMP_RDEND, qlcnic_dump_nop },
+};
+
+/* Walk the template and collect dump for each entry in the dump template */
+static int
+qlcnic_valid_dump_entry(struct device *dev, struct qlcnic_dump_entry *entry,
+ u32 size)
+{
+ int ret = 1;
+ if (size != entry->hdr.cap_size) {
+ dev_info(dev,
+ "Invalidate dump, Type:%d\tMask:%d\tSize:%dCap_size:%d\n",
+ entry->hdr.type, entry->hdr.mask, size, entry->hdr.cap_size);
+ dev_info(dev, "Aborting further dump capture\n");
+ ret = 0;
+ }
+ return ret;
+}
+
+int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
+{
+ u32 *buffer;
+ char mesg[64];
+ char *msg[] = {mesg, NULL};
+ int i, k, ops_cnt, ops_index, dump_size = 0;
+ u32 entry_offset, dump, no_entries, buf_offset = 0;
+ struct qlcnic_dump_entry *entry;
+ struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
+ struct qlcnic_dump_template_hdr *tmpl_hdr = fw_dump->tmpl_hdr;
+
+ if (fw_dump->clr) {
+ dev_info(&adapter->pdev->dev,
+ "Previous dump not cleared, not capturing dump\n");
+ return -EIO;
+ }
+ /* Calculate the size for dump data area only */
+ for (i = 2, k = 1; (i & QLCNIC_DUMP_MASK_MAX); i <<= 1, k++)
+ if (i & tmpl_hdr->drv_cap_mask)
+ dump_size += tmpl_hdr->cap_sizes[k];
+ if (!dump_size)
+ return -EIO;
+
+ fw_dump->data = vzalloc(dump_size);
+ if (!fw_dump->data) {
+ dev_info(&adapter->pdev->dev,
+ "Unable to allocate (%d KB) for fw dump\n",
+ dump_size/1024);
+ return -ENOMEM;
+ }
+ buffer = fw_dump->data;
+ fw_dump->size = dump_size;
+ no_entries = tmpl_hdr->num_entries;
+ ops_cnt = ARRAY_SIZE(fw_dump_ops);
+ entry_offset = tmpl_hdr->offset;
+ tmpl_hdr->sys_info[0] = QLCNIC_DRIVER_VERSION;
+ tmpl_hdr->sys_info[1] = adapter->fw_version;
+
+ for (i = 0; i < no_entries; i++) {
+ entry = (struct qlcnic_dump_entry *) ((void *) tmpl_hdr +
+ entry_offset);
+ if (!(entry->hdr.mask & tmpl_hdr->drv_cap_mask)) {
+ entry->hdr.flags |= QLCNIC_DUMP_SKIP;
+ entry_offset += entry->hdr.offset;
+ continue;
+ }
+ /* Find the handler for this entry */
+ ops_index = 0;
+ while (ops_index < ops_cnt) {
+ if (entry->hdr.type == fw_dump_ops[ops_index].opcode)
+ break;
+ ops_index++;
+ }
+ if (ops_index == ops_cnt) {
+ dev_info(&adapter->pdev->dev,
+ "Invalid entry type %d, exiting dump\n",
+ entry->hdr.type);
+ goto error;
+ }
+ /* Collect dump for this entry */
+ dump = fw_dump_ops[ops_index].handler(adapter, entry, buffer);
+ if (dump && !qlcnic_valid_dump_entry(&adapter->pdev->dev, entry,
+ dump))
+ entry->hdr.flags |= QLCNIC_DUMP_SKIP;
+ buf_offset += entry->hdr.cap_size;
+ entry_offset += entry->hdr.offset;
+ buffer = fw_dump->data + buf_offset;
+ }
+ if (dump_size != buf_offset) {
+ dev_info(&adapter->pdev->dev,
+ "Captured(%d) and expected size(%d) do not match\n",
+ buf_offset, dump_size);
+ goto error;
+ } else {
+ fw_dump->clr = 1;
+ snprintf(mesg, sizeof(mesg), "FW dump for device: %d\n",
+ adapter->pdev->devfn);
+ dev_info(&adapter->pdev->dev, "Dump data, %d bytes captured\n",
+ fw_dump->size);
+ /* Send a udev event to notify availability of FW dump */
+ kobject_uevent_env(&adapter->pdev->dev.kobj, KOBJ_CHANGE, msg);
+ return 0;
+ }
+error:
+ vfree(fw_dump->data);
+ return -EINVAL;
+}
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index a7f1d5b7e81..5b8bbcf904d 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -94,7 +94,7 @@ void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter)
struct qlcnic_rx_buffer *rx_buf;
int i, ring;
- recv_ctx = &adapter->recv_ctx;
+ recv_ctx = adapter->recv_ctx;
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
for (i = 0; i < rds_ring->num_desc; ++i) {
@@ -119,7 +119,7 @@ void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter)
struct qlcnic_rx_buffer *rx_buf;
int i, ring;
- recv_ctx = &adapter->recv_ctx;
+ recv_ctx = adapter->recv_ctx;
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
@@ -173,7 +173,7 @@ void qlcnic_free_sw_resources(struct qlcnic_adapter *adapter)
struct qlcnic_host_tx_ring *tx_ring;
int ring;
- recv_ctx = &adapter->recv_ctx;
+ recv_ctx = adapter->recv_ctx;
if (recv_ctx->rds_rings == NULL)
goto skip_rds;
@@ -226,7 +226,7 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter)
}
tx_ring->cmd_buf_arr = cmd_buf_arr;
- recv_ctx = &adapter->recv_ctx;
+ recv_ctx = adapter->recv_ctx;
size = adapter->max_rds_rings * sizeof(struct qlcnic_host_rds_ring);
rds_ring = kzalloc(size, GFP_KERNEL);
@@ -345,7 +345,7 @@ static int qlcnic_wait_rom_done(struct qlcnic_adapter *adapter)
}
static int do_rom_fast_read(struct qlcnic_adapter *adapter,
- int addr, int *valp)
+ u32 addr, u32 *valp)
{
QLCWR32(adapter, QLCNIC_ROMUSB_ROM_ADDRESS, addr);
QLCWR32(adapter, QLCNIC_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
@@ -398,7 +398,7 @@ qlcnic_rom_fast_read_words(struct qlcnic_adapter *adapter, int addr,
return ret;
}
-int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, int addr, int *valp)
+int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, u32 addr, u32 *valp)
{
int ret;
@@ -864,7 +864,7 @@ nomn:
for (i = 0; i < entries; i++) {
__le32 flags, file_chiprev, offs;
- u8 chiprev = adapter->ahw.revision_id;
+ u8 chiprev = adapter->ahw->revision_id;
u32 flagbit;
offs = cpu_to_le32(ptab_descr->findex) +
@@ -1130,9 +1130,20 @@ qlcnic_load_firmware(struct qlcnic_adapter *adapter)
} else {
u64 data;
u32 hi, lo;
-
- size = (QLCNIC_IMAGE_START - QLCNIC_BOOTLD_START) / 8;
- flashaddr = QLCNIC_BOOTLD_START;
+ int ret;
+ struct qlcnic_flt_entry bootld_entry;
+
+ ret = qlcnic_get_flt_entry(adapter, QLCNIC_BOOTLD_REGION,
+ &bootld_entry);
+ if (!ret) {
+ size = bootld_entry.size / 8;
+ flashaddr = bootld_entry.start_addr;
+ } else {
+ size = (QLCNIC_IMAGE_START - QLCNIC_BOOTLD_START) / 8;
+ flashaddr = QLCNIC_BOOTLD_START;
+ dev_info(&pdev->dev,
+ "using legacy method to get flash fw region");
+ }
for (i = 0; i < size; i++) {
if (qlcnic_rom_fast_read(adapter,
@@ -1379,8 +1390,8 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter,
skb = buffer->skb;
- if (likely(adapter->rx_csum && (cksum == STATUS_CKSUM_OK ||
- cksum == STATUS_CKSUM_LOOP))) {
+ if (likely((adapter->netdev->features & NETIF_F_RXCSUM) &&
+ (cksum == STATUS_CKSUM_OK || cksum == STATUS_CKSUM_LOOP))) {
adapter->stats.csummed++;
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else {
@@ -1394,7 +1405,7 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter,
return skb;
}
-static int
+static inline int
qlcnic_check_rx_tagging(struct qlcnic_adapter *adapter, struct sk_buff *skb,
u16 *vlan_tag)
{
@@ -1425,7 +1436,7 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter,
int ring, u64 sts_data0)
{
struct net_device *netdev = adapter->netdev;
- struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
struct qlcnic_rx_buffer *buffer;
struct sk_buff *skb;
struct qlcnic_host_rds_ring *rds_ring;
@@ -1467,10 +1478,10 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter,
skb->protocol = eth_type_trans(skb, netdev);
- if ((vid != 0xffff) && adapter->vlgrp)
- vlan_gro_receive(&sds_ring->napi, adapter->vlgrp, vid, skb);
- else
- napi_gro_receive(&sds_ring->napi, skb);
+ if (vid != 0xffff)
+ __vlan_hwaccel_put_tag(skb, vid);
+
+ napi_gro_receive(&sds_ring->napi, skb);
adapter->stats.rx_pkts++;
adapter->stats.rxbytes += length;
@@ -1488,7 +1499,7 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,
int ring, u64 sts_data0, u64 sts_data1)
{
struct net_device *netdev = adapter->netdev;
- struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
struct qlcnic_rx_buffer *buffer;
struct sk_buff *skb;
struct qlcnic_host_rds_ring *rds_ring;
@@ -1552,10 +1563,9 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,
length = skb->len;
- if ((vid != 0xffff) && adapter->vlgrp)
- vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vid);
- else
- netif_receive_skb(skb);
+ if (vid != 0xffff)
+ __vlan_hwaccel_put_tag(skb, vid);
+ netif_receive_skb(skb);
adapter->stats.lro_pkts++;
adapter->stats.lrobytes += length;
@@ -1625,7 +1635,7 @@ skip:
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
struct qlcnic_host_rds_ring *rds_ring =
- &adapter->recv_ctx.rds_rings[ring];
+ &adapter->recv_ctx->rds_rings[ring];
if (!list_empty(&sds_ring->free_list[ring])) {
list_for_each(cur, &sds_ring->free_list[ring]) {
@@ -1651,12 +1661,13 @@ skip:
}
void
-qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid,
+qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter,
struct qlcnic_host_rds_ring *rds_ring)
{
struct rcv_desc *pdesc;
struct qlcnic_rx_buffer *buffer;
- int producer, count = 0;
+ int count = 0;
+ u32 producer;
struct list_head *head;
producer = rds_ring->producer;
@@ -1696,7 +1707,8 @@ qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter,
{
struct rcv_desc *pdesc;
struct qlcnic_rx_buffer *buffer;
- int producer, count = 0;
+ int count = 0;
+ uint32_t producer;
struct list_head *head;
if (!spin_trylock(&rds_ring->lock))
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index cb1a1ef36c0..3ab7d2c7baf 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -13,12 +13,12 @@
#include <linux/swab.h>
#include <linux/dma-mapping.h>
-#include <linux/if_vlan.h>
#include <net/ip.h>
#include <linux/ipv6.h>
#include <linux/inetdevice.h>
#include <linux/sysfs.h>
#include <linux/aer.h>
+#include <linux/log2.h>
MODULE_DESCRIPTION("QLogic 1/10 GbE Converged/Intelligent Ethernet Driver");
MODULE_LICENSE("GPL");
@@ -98,6 +98,9 @@ static int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32);
static int qlcnicvf_start_firmware(struct qlcnic_adapter *);
static void qlcnic_set_netdev_features(struct qlcnic_adapter *,
struct qlcnic_esw_func_cfg *);
+static void qlcnic_vlan_rx_add(struct net_device *, u16);
+static void qlcnic_vlan_rx_del(struct net_device *, u16);
+
/* PCI Device ID Table */
#define ENTRY(device) \
{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \
@@ -113,7 +116,7 @@ static DEFINE_PCI_DEVICE_TABLE(qlcnic_pci_tbl) = {
MODULE_DEVICE_TABLE(pci, qlcnic_pci_tbl);
-void
+inline void
qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
struct qlcnic_host_tx_ring *tx_ring)
{
@@ -169,7 +172,7 @@ qlcnic_napi_add(struct qlcnic_adapter *adapter, struct net_device *netdev)
{
int ring;
struct qlcnic_host_sds_ring *sds_ring;
- struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
if (qlcnic_alloc_sds_rings(recv_ctx, adapter->max_sds_rings))
return -ENOMEM;
@@ -193,14 +196,14 @@ qlcnic_napi_del(struct qlcnic_adapter *adapter)
{
int ring;
struct qlcnic_host_sds_ring *sds_ring;
- struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
sds_ring = &recv_ctx->sds_rings[ring];
netif_napi_del(&sds_ring->napi);
}
- qlcnic_free_sds_rings(&adapter->recv_ctx);
+ qlcnic_free_sds_rings(adapter->recv_ctx);
}
static void
@@ -208,7 +211,7 @@ qlcnic_napi_enable(struct qlcnic_adapter *adapter)
{
int ring;
struct qlcnic_host_sds_ring *sds_ring;
- struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
return;
@@ -225,7 +228,7 @@ qlcnic_napi_disable(struct qlcnic_adapter *adapter)
{
int ring;
struct qlcnic_host_sds_ring *sds_ring;
- struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
return;
@@ -317,13 +320,6 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p)
return 0;
}
-static void qlcnic_vlan_rx_register(struct net_device *netdev,
- struct vlan_group *grp)
-{
- struct qlcnic_adapter *adapter = netdev_priv(netdev);
- adapter->vlgrp = grp;
-}
-
static const struct net_device_ops qlcnic_netdev_ops = {
.ndo_open = qlcnic_open,
.ndo_stop = qlcnic_close,
@@ -333,8 +329,11 @@ static const struct net_device_ops qlcnic_netdev_ops = {
.ndo_set_multicast_list = qlcnic_set_multi,
.ndo_set_mac_address = qlcnic_set_mac,
.ndo_change_mtu = qlcnic_change_mtu,
+ .ndo_fix_features = qlcnic_fix_features,
+ .ndo_set_features = qlcnic_set_features,
.ndo_tx_timeout = qlcnic_tx_timeout,
- .ndo_vlan_rx_register = qlcnic_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = qlcnic_vlan_rx_add,
+ .ndo_vlan_rx_kill_vid = qlcnic_vlan_rx_del,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = qlcnic_poll_controller,
#endif
@@ -352,72 +351,87 @@ static struct qlcnic_nic_template qlcnic_vf_ops = {
.start_firmware = qlcnicvf_start_firmware
};
-static void
-qlcnic_setup_intr(struct qlcnic_adapter *adapter)
+static int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
{
- const struct qlcnic_legacy_intr_set *legacy_intrp;
struct pci_dev *pdev = adapter->pdev;
- int err, num_msix;
-
- if (adapter->rss_supported) {
- num_msix = (num_online_cpus() >= MSIX_ENTRIES_PER_ADAPTER) ?
- MSIX_ENTRIES_PER_ADAPTER : 2;
- } else
- num_msix = 1;
+ int err = -1;
adapter->max_sds_rings = 1;
-
adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED);
-
- legacy_intrp = &legacy_intr[adapter->ahw.pci_func];
-
- adapter->int_vec_bit = legacy_intrp->int_vec_bit;
- adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter,
- legacy_intrp->tgt_status_reg);
- adapter->tgt_mask_reg = qlcnic_get_ioaddr(adapter,
- legacy_intrp->tgt_mask_reg);
- adapter->isr_int_vec = qlcnic_get_ioaddr(adapter, ISR_INT_VECTOR);
-
- adapter->crb_int_state_reg = qlcnic_get_ioaddr(adapter,
- ISR_INT_STATE_REG);
-
qlcnic_set_msix_bit(pdev, 0);
if (adapter->msix_supported) {
-
+ enable_msix:
qlcnic_init_msix_entries(adapter, num_msix);
err = pci_enable_msix(pdev, adapter->msix_entries, num_msix);
if (err == 0) {
adapter->flags |= QLCNIC_MSIX_ENABLED;
qlcnic_set_msix_bit(pdev, 1);
- if (adapter->rss_supported)
- adapter->max_sds_rings = num_msix;
+ adapter->max_sds_rings = num_msix;
dev_info(&pdev->dev, "using msi-x interrupts\n");
- return;
+ return err;
}
+ if (err > 0) {
+ num_msix = rounddown_pow_of_two(err);
+ if (num_msix)
+ goto enable_msix;
+ }
+ }
+ return err;
+}
- if (err > 0)
- pci_disable_msix(pdev);
- /* fall through for msi */
- }
+static void qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter)
+{
+ const struct qlcnic_legacy_intr_set *legacy_intrp;
+ struct pci_dev *pdev = adapter->pdev;
if (use_msi && !pci_enable_msi(pdev)) {
adapter->flags |= QLCNIC_MSI_ENABLED;
adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter,
- msi_tgt_status[adapter->ahw.pci_func]);
+ msi_tgt_status[adapter->ahw->pci_func]);
dev_info(&pdev->dev, "using msi interrupts\n");
adapter->msix_entries[0].vector = pdev->irq;
return;
}
+ legacy_intrp = &legacy_intr[adapter->ahw->pci_func];
+
+ adapter->int_vec_bit = legacy_intrp->int_vec_bit;
+ adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter,
+ legacy_intrp->tgt_status_reg);
+ adapter->tgt_mask_reg = qlcnic_get_ioaddr(adapter,
+ legacy_intrp->tgt_mask_reg);
+ adapter->isr_int_vec = qlcnic_get_ioaddr(adapter, ISR_INT_VECTOR);
+
+ adapter->crb_int_state_reg = qlcnic_get_ioaddr(adapter,
+ ISR_INT_STATE_REG);
dev_info(&pdev->dev, "using legacy interrupts\n");
adapter->msix_entries[0].vector = pdev->irq;
}
static void
+qlcnic_setup_intr(struct qlcnic_adapter *adapter)
+{
+ int num_msix;
+
+ if (adapter->msix_supported) {
+ num_msix = (num_online_cpus() >=
+ QLCNIC_DEF_NUM_STS_DESC_RINGS) ?
+ QLCNIC_DEF_NUM_STS_DESC_RINGS :
+ QLCNIC_MIN_NUM_RSS_RINGS;
+ } else
+ num_msix = 1;
+
+ if (!qlcnic_enable_msix(adapter, num_msix))
+ return;
+
+ qlcnic_enable_msi_legacy(adapter);
+}
+
+static void
qlcnic_teardown_intr(struct qlcnic_adapter *adapter)
{
if (adapter->flags & QLCNIC_MSIX_ENABLED)
@@ -429,8 +443,8 @@ qlcnic_teardown_intr(struct qlcnic_adapter *adapter)
static void
qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter)
{
- if (adapter->ahw.pci_base0 != NULL)
- iounmap(adapter->ahw.pci_base0);
+ if (adapter->ahw->pci_base0 != NULL)
+ iounmap(adapter->ahw->pci_base0);
}
static int
@@ -464,8 +478,10 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
pfn = pci_info[i].id;
- if (pfn > QLCNIC_MAX_PCI_FUNC)
- return QL_STATUS_INVALID_PARAM;
+ if (pfn > QLCNIC_MAX_PCI_FUNC) {
+ ret = QL_STATUS_INVALID_PARAM;
+ goto err_eswitch;
+ }
adapter->npars[pfn].active = (u8)pci_info[i].active;
adapter->npars[pfn].type = (u8)pci_info[i].type;
adapter->npars[pfn].phy_port = (u8)pci_info[i].default_port;
@@ -498,7 +514,7 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
u32 ref_count;
int i, ret = 1;
u32 data = QLCNIC_MGMT_FUNC;
- void __iomem *priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE;
+ void __iomem *priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE;
/* If other drivers are not in use set their privilege level */
ref_count = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
@@ -510,16 +526,16 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
id = i;
if (adapter->npars[i].type != QLCNIC_TYPE_NIC ||
- id == adapter->ahw.pci_func)
+ id == adapter->ahw->pci_func)
continue;
data |= (qlcnic_config_npars &
QLC_DEV_SET_DRV(0xf, id));
}
} else {
data = readl(priv_op);
- data = (data & ~QLC_DEV_SET_DRV(0xf, adapter->ahw.pci_func)) |
+ data = (data & ~QLC_DEV_SET_DRV(0xf, adapter->ahw->pci_func)) |
(QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC,
- adapter->ahw.pci_func));
+ adapter->ahw->pci_func));
}
writel(data, priv_op);
qlcnic_api_unlock(adapter);
@@ -537,22 +553,23 @@ qlcnic_check_vf(struct qlcnic_adapter *adapter)
u32 op_mode, priv_level;
/* Determine FW API version */
- adapter->fw_hal_version = readl(adapter->ahw.pci_base0 + QLCNIC_FW_API);
+ adapter->fw_hal_version = readl(adapter->ahw->pci_base0 +
+ QLCNIC_FW_API);
/* Find PCI function number */
pci_read_config_dword(adapter->pdev, QLCNIC_MSIX_TABLE_OFFSET, &func);
- msix_base_addr = adapter->ahw.pci_base0 + QLCNIC_MSIX_BASE;
+ msix_base_addr = adapter->ahw->pci_base0 + QLCNIC_MSIX_BASE;
msix_base = readl(msix_base_addr);
func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE;
- adapter->ahw.pci_func = func;
+ adapter->ahw->pci_func = func;
/* Determine function privilege level */
- priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE;
+ priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE;
op_mode = readl(priv_op);
if (op_mode == QLC_DEV_DRV_DEFAULT)
priv_level = QLCNIC_MGMT_FUNC;
else
- priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func);
+ priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func);
if (priv_level == QLCNIC_NON_PRIV_FUNC) {
adapter->op_mode = QLCNIC_NON_PRIV_FUNC;
@@ -591,13 +608,14 @@ qlcnic_setup_pci_map(struct qlcnic_adapter *adapter)
dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20));
- adapter->ahw.pci_base0 = mem_ptr0;
- adapter->ahw.pci_len0 = pci_len0;
+ adapter->ahw->pci_base0 = mem_ptr0;
+ adapter->ahw->pci_len0 = pci_len0;
qlcnic_check_vf(adapter);
- adapter->ahw.ocm_win_crb = qlcnic_get_ioaddr(adapter,
- QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(adapter->ahw.pci_func)));
+ adapter->ahw->ocm_win_crb = qlcnic_get_ioaddr(adapter,
+ QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(
+ adapter->ahw->pci_func)));
return 0;
}
@@ -639,7 +657,7 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
dev_info(&pdev->dev, "firmware v%d.%d.%d\n",
fw_major, fw_minor, fw_build);
- if (adapter->ahw.port_type == QLCNIC_XGBE) {
+ if (adapter->ahw->port_type == QLCNIC_XGBE) {
if (adapter->flags & QLCNIC_ESWITCH_ENABLED) {
adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_VF;
adapter->max_rxd = MAX_RCV_DESCRIPTORS_VF;
@@ -651,7 +669,7 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
- } else if (adapter->ahw.port_type == QLCNIC_GBE) {
+ } else if (adapter->ahw->port_type == QLCNIC_GBE) {
adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G;
adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
@@ -659,7 +677,6 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
}
adapter->msix_supported = !!use_msi_x;
- adapter->rss_supported = !!use_msi_x;
adapter->num_txd = MAX_CMD_DESCRIPTORS;
@@ -672,7 +689,7 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter)
int err;
struct qlcnic_info nic_info;
- err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func);
+ err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw->pci_func);
if (err)
return err;
@@ -708,6 +725,22 @@ qlcnic_set_vlan_config(struct qlcnic_adapter *adapter,
}
static void
+qlcnic_vlan_rx_add(struct net_device *netdev, u16 vid)
+{
+ struct qlcnic_adapter *adapter = netdev_priv(netdev);
+ set_bit(vid, adapter->vlans);
+}
+
+static void
+qlcnic_vlan_rx_del(struct net_device *netdev, u16 vid)
+{
+ struct qlcnic_adapter *adapter = netdev_priv(netdev);
+
+ qlcnic_restore_indev_addr(netdev, NETDEV_DOWN);
+ clear_bit(vid, adapter->vlans);
+}
+
+static void
qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter,
struct qlcnic_esw_func_cfg *esw_cfg)
{
@@ -734,7 +767,7 @@ qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter)
if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
return 0;
- esw_cfg.pci_func = adapter->ahw.pci_func;
+ esw_cfg.pci_func = adapter->ahw->pci_func;
if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg))
return -EIO;
qlcnic_set_vlan_config(adapter, &esw_cfg);
@@ -750,28 +783,27 @@ qlcnic_set_netdev_features(struct qlcnic_adapter *adapter,
struct net_device *netdev = adapter->netdev;
unsigned long features, vlan_features;
- features = (NETIF_F_SG | NETIF_F_IP_CSUM |
+ features = (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
NETIF_F_IPV6_CSUM | NETIF_F_GRO);
vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM |
- NETIF_F_IPV6_CSUM);
+ NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_FILTER);
if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) {
features |= (NETIF_F_TSO | NETIF_F_TSO6);
vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6);
}
- if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
+
+ if (netdev->features & NETIF_F_LRO)
features |= NETIF_F_LRO;
if (esw_cfg->offload_flags & BIT_0) {
netdev->features |= features;
- adapter->rx_csum = 1;
if (!(esw_cfg->offload_flags & BIT_1))
netdev->features &= ~NETIF_F_TSO;
if (!(esw_cfg->offload_flags & BIT_2))
netdev->features &= ~NETIF_F_TSO6;
} else {
netdev->features &= ~features;
- adapter->rx_csum = 0;
}
netdev->vlan_features = (features & vlan_features);
@@ -791,14 +823,14 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter)
if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED)
return 0;
- priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE;
+ priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE;
op_mode = readl(priv_op);
- priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func);
+ priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func);
if (op_mode == QLC_DEV_DRV_DEFAULT)
priv_level = QLCNIC_MGMT_FUNC;
else
- priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func);
+ priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func);
if (adapter->flags & QLCNIC_ESWITCH_ENABLED) {
if (priv_level == QLCNIC_MGMT_FUNC) {
@@ -1038,7 +1070,7 @@ qlcnic_request_irq(struct qlcnic_adapter *adapter)
unsigned long flags = 0;
struct net_device *netdev = adapter->netdev;
- struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) {
handler = qlcnic_tmp_intr;
@@ -1075,7 +1107,7 @@ qlcnic_free_irq(struct qlcnic_adapter *adapter)
int ring;
struct qlcnic_host_sds_ring *sds_ring;
- struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
sds_ring = &recv_ctx->sds_rings[ring];
@@ -1083,20 +1115,6 @@ qlcnic_free_irq(struct qlcnic_adapter *adapter)
}
}
-static void
-qlcnic_init_coalesce_defaults(struct qlcnic_adapter *adapter)
-{
- adapter->coal.flags = QLCNIC_INTR_DEFAULT;
- adapter->coal.normal.data.rx_time_us =
- QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
- adapter->coal.normal.data.rx_packets =
- QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
- adapter->coal.normal.data.tx_time_us =
- QLCNIC_DEFAULT_INTR_COALESCE_TX_TIME_US;
- adapter->coal.normal.data.tx_packets =
- QLCNIC_DEFAULT_INTR_COALESCE_TX_PACKETS;
-}
-
static int
__qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
{
@@ -1115,14 +1133,14 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
return -EIO;
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
- rds_ring = &adapter->recv_ctx.rds_rings[ring];
- qlcnic_post_rx_buffers(adapter, ring, rds_ring);
+ rds_ring = &adapter->recv_ctx->rds_rings[ring];
+ qlcnic_post_rx_buffers(adapter, rds_ring);
}
qlcnic_set_multi(netdev);
qlcnic_fw_cmd_set_mtu(adapter, netdev->mtu);
- adapter->ahw.linkup = 0;
+ adapter->ahw->linkup = 0;
if (adapter->max_sds_rings > 1)
qlcnic_config_rss(adapter, 1);
@@ -1230,8 +1248,6 @@ qlcnic_attach(struct qlcnic_adapter *adapter)
goto err_out_free_hw;
}
- qlcnic_init_coalesce_defaults(adapter);
-
qlcnic_create_sysfs_entries(adapter);
adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC;
@@ -1272,7 +1288,7 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings)
clear_bit(__QLCNIC_DEV_UP, &adapter->state);
if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) {
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
- sds_ring = &adapter->recv_ctx.sds_rings[ring];
+ sds_ring = &adapter->recv_ctx->sds_rings[ring];
qlcnic_disable_int(sds_ring);
}
}
@@ -1293,6 +1309,48 @@ out:
netif_device_attach(netdev);
}
+static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
+{
+ int err = 0;
+ adapter->ahw = kzalloc(sizeof(struct qlcnic_hardware_context),
+ GFP_KERNEL);
+ if (!adapter->ahw) {
+ dev_err(&adapter->pdev->dev,
+ "Failed to allocate recv ctx resources for adapter\n");
+ err = -ENOMEM;
+ goto err_out;
+ }
+ adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context),
+ GFP_KERNEL);
+ if (!adapter->recv_ctx) {
+ dev_err(&adapter->pdev->dev,
+ "Failed to allocate recv ctx resources for adapter\n");
+ kfree(adapter->ahw);
+ adapter->ahw = NULL;
+ err = -ENOMEM;
+ goto err_out;
+ }
+ /* Initialize interrupt coalesce parameters */
+ adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT;
+ adapter->ahw->coal.rx_time_us = QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
+ adapter->ahw->coal.rx_packets = QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
+err_out:
+ return err;
+}
+
+static void qlcnic_free_adapter_resources(struct qlcnic_adapter *adapter)
+{
+ kfree(adapter->recv_ctx);
+ adapter->recv_ctx = NULL;
+
+ if (adapter->ahw->fw_dump.tmpl_hdr) {
+ vfree(adapter->ahw->fw_dump.tmpl_hdr);
+ adapter->ahw->fw_dump.tmpl_hdr = NULL;
+ }
+ kfree(adapter->ahw);
+ adapter->ahw = NULL;
+}
+
int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
@@ -1325,13 +1383,13 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
}
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
- rds_ring = &adapter->recv_ctx.rds_rings[ring];
- qlcnic_post_rx_buffers(adapter, ring, rds_ring);
+ rds_ring = &adapter->recv_ctx->rds_rings[ring];
+ qlcnic_post_rx_buffers(adapter, rds_ring);
}
if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) {
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
- sds_ring = &adapter->recv_ctx.sds_rings[ring];
+ sds_ring = &adapter->recv_ctx->sds_rings[ring];
qlcnic_enable_int(sds_ring);
}
}
@@ -1399,7 +1457,6 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter,
int err;
struct pci_dev *pdev = adapter->pdev;
- adapter->rx_csum = 1;
adapter->mc_enabled = 0;
adapter->max_mc_count = 38;
@@ -1410,26 +1467,24 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter,
SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops);
- netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM |
- NETIF_F_IPV6_CSUM | NETIF_F_GRO | NETIF_F_HW_VLAN_RX);
- netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM |
- NETIF_F_IPV6_CSUM);
+ netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM;
- if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) {
- netdev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
- netdev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6);
- }
+ if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO)
+ netdev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6;
+ if (pci_using_dac)
+ netdev->hw_features |= NETIF_F_HIGHDMA;
- if (pci_using_dac) {
- netdev->features |= NETIF_F_HIGHDMA;
- netdev->vlan_features |= NETIF_F_HIGHDMA;
- }
+ netdev->vlan_features = netdev->hw_features;
if (adapter->capabilities & QLCNIC_FW_CAPABILITY_FVLANTX)
- netdev->features |= (NETIF_F_HW_VLAN_TX);
-
+ netdev->hw_features |= NETIF_F_HW_VLAN_TX;
if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
- netdev->features |= NETIF_F_LRO;
+ netdev->hw_features |= NETIF_F_LRO;
+
+ netdev->features |= netdev->hw_features |
+ NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
+
netdev->irq = adapter->msix_entries[0].vector;
netif_carrier_off(netdev);
@@ -1459,6 +1514,19 @@ static int qlcnic_set_dma_mask(struct pci_dev *pdev, u8 *pci_using_dac)
return 0;
}
+static int
+qlcnic_alloc_msix_entries(struct qlcnic_adapter *adapter, u16 count)
+{
+ adapter->msix_entries = kcalloc(count, sizeof(struct msix_entry),
+ GFP_KERNEL);
+
+ if (adapter->msix_entries)
+ return 0;
+
+ dev_err(&adapter->pdev->dev, "failed allocating msix_entries\n");
+ return -ENOMEM;
+}
+
static int __devinit
qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@@ -1501,23 +1569,30 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter = netdev_priv(netdev);
adapter->netdev = netdev;
adapter->pdev = pdev;
- adapter->dev_rst_time = jiffies;
+ if (qlcnic_alloc_adapter_resources(adapter))
+ goto err_out_free_netdev;
+
+ adapter->dev_rst_time = jiffies;
revision_id = pdev->revision;
- adapter->ahw.revision_id = revision_id;
+ adapter->ahw->revision_id = revision_id;
- rwlock_init(&adapter->ahw.crb_lock);
- mutex_init(&adapter->ahw.mem_lock);
+ rwlock_init(&adapter->ahw->crb_lock);
+ mutex_init(&adapter->ahw->mem_lock);
spin_lock_init(&adapter->tx_clean_lock);
INIT_LIST_HEAD(&adapter->mac_list);
err = qlcnic_setup_pci_map(adapter);
if (err)
- goto err_out_free_netdev;
+ goto err_out_free_hw;
/* This will be reset for mezz cards */
- adapter->portnum = adapter->ahw.pci_func;
+ adapter->portnum = adapter->ahw->pci_func;
+
+ /* Get FW dump template and store it */
+ if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC)
+ qlcnic_fw_cmd_get_minidump_temp(adapter);
err = qlcnic_get_board_info(adapter);
if (err) {
@@ -1545,11 +1620,15 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pr_info("%s: %s Board Chip rev 0x%x\n",
module_name(THIS_MODULE),
- brd_name, adapter->ahw.revision_id);
+ brd_name, adapter->ahw->revision_id);
}
qlcnic_clear_stats(adapter);
+ err = qlcnic_alloc_msix_entries(adapter, adapter->max_rx_ques);
+ if (err)
+ goto err_out_decr_ref;
+
qlcnic_setup_intr(adapter);
err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac);
@@ -1560,7 +1639,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY);
- switch (adapter->ahw.port_type) {
+ switch (adapter->ahw->port_type) {
case QLCNIC_GBE:
dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n",
adapter->netdev->name);
@@ -1578,6 +1657,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err_out_disable_msi:
qlcnic_teardown_intr(adapter);
+ kfree(adapter->msix_entries);
err_out_decr_ref:
qlcnic_clr_all_drv_state(adapter, 0);
@@ -1585,6 +1665,9 @@ err_out_decr_ref:
err_out_iounmap:
qlcnic_cleanup_pci_map(adapter);
+err_out_free_hw:
+ qlcnic_free_adapter_resources(adapter);
+
err_out_free_netdev:
free_netdev(netdev);
@@ -1626,6 +1709,7 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev)
qlcnic_free_lb_filters_mem(adapter);
qlcnic_teardown_intr(adapter);
+ kfree(adapter->msix_entries);
qlcnic_remove_diag_entries(adapter);
@@ -1638,6 +1722,7 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
+ qlcnic_free_adapter_resources(adapter);
free_netdev(netdev);
}
static int __qlcnic_shutdown(struct pci_dev *pdev)
@@ -1819,6 +1904,7 @@ static void qlcnic_change_filter(struct qlcnic_adapter *adapter,
vlan_req->vlan_id = vlan_id;
tx_ring->producer = get_next_index(producer, tx_ring->num_desc);
+ smp_mb();
}
#define QLCNIC_MAC_HASH(MAC)\
@@ -1879,58 +1965,122 @@ qlcnic_send_filter(struct qlcnic_adapter *adapter,
spin_unlock(&adapter->mac_learn_lock);
}
-static void
-qlcnic_tso_check(struct net_device *netdev,
- struct qlcnic_host_tx_ring *tx_ring,
+static int
+qlcnic_tx_pkt(struct qlcnic_adapter *adapter,
struct cmd_desc_type0 *first_desc,
struct sk_buff *skb)
{
- u8 opcode = TX_ETHER_PKT;
- __be16 protocol = skb->protocol;
- u16 flags = 0;
- int copied, offset, copy_len, hdr_len = 0, tso = 0;
+ u8 opcode = 0, hdr_len = 0;
+ u16 flags = 0, vlan_tci = 0;
+ int copied, offset, copy_len;
struct cmd_desc_type0 *hwdesc;
struct vlan_ethhdr *vh;
- struct qlcnic_adapter *adapter = netdev_priv(netdev);
+ struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring;
+ u16 protocol = ntohs(skb->protocol);
u32 producer = tx_ring->producer;
- __le16 vlan_oob = first_desc->flags_opcode &
- cpu_to_le16(FLAGS_VLAN_OOB);
+
+ if (protocol == ETH_P_8021Q) {
+ vh = (struct vlan_ethhdr *)skb->data;
+ flags = FLAGS_VLAN_TAGGED;
+ vlan_tci = vh->h_vlan_TCI;
+ } else if (vlan_tx_tag_present(skb)) {
+ flags = FLAGS_VLAN_OOB;
+ vlan_tci = vlan_tx_tag_get(skb);
+ }
+ if (unlikely(adapter->pvid)) {
+ if (vlan_tci && !(adapter->flags & QLCNIC_TAGGING_ENABLED))
+ return -EIO;
+ if (vlan_tci && (adapter->flags & QLCNIC_TAGGING_ENABLED))
+ goto set_flags;
+
+ flags = FLAGS_VLAN_OOB;
+ vlan_tci = adapter->pvid;
+ }
+set_flags:
+ qlcnic_set_tx_vlan_tci(first_desc, vlan_tci);
+ qlcnic_set_tx_flags_opcode(first_desc, flags, opcode);
if (*(skb->data) & BIT_0) {
flags |= BIT_0;
memcpy(&first_desc->eth_addr, skb->data, ETH_ALEN);
}
-
- if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
+ opcode = TX_ETHER_PKT;
+ if ((adapter->netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
skb_shinfo(skb)->gso_size > 0) {
hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
first_desc->total_hdr_length = hdr_len;
- if (vlan_oob) {
+
+ opcode = (protocol == ETH_P_IPV6) ? TX_TCP_LSO6 : TX_TCP_LSO;
+
+ /* For LSO, we need to copy the MAC/IP/TCP headers into
+ * the descriptor ring */
+ copied = 0;
+ offset = 2;
+
+ if (flags & FLAGS_VLAN_OOB) {
first_desc->total_hdr_length += VLAN_HLEN;
first_desc->tcp_hdr_offset = VLAN_HLEN;
first_desc->ip_hdr_offset = VLAN_HLEN;
/* Only in case of TSO on vlan device */
flags |= FLAGS_VLAN_TAGGED;
+
+ /* Create a TSO vlan header template for firmware */
+
+ hwdesc = &tx_ring->desc_head[producer];
+ tx_ring->cmd_buf_arr[producer].skb = NULL;
+
+ copy_len = min((int)sizeof(struct cmd_desc_type0) -
+ offset, hdr_len + VLAN_HLEN);
+
+ vh = (struct vlan_ethhdr *)((char *) hwdesc + 2);
+ skb_copy_from_linear_data(skb, vh, 12);
+ vh->h_vlan_proto = htons(ETH_P_8021Q);
+ vh->h_vlan_TCI = htons(vlan_tci);
+
+ skb_copy_from_linear_data_offset(skb, 12,
+ (char *)vh + 16, copy_len - 16);
+
+ copied = copy_len - VLAN_HLEN;
+ offset = 0;
+
+ producer = get_next_index(producer, tx_ring->num_desc);
}
- opcode = (protocol == cpu_to_be16(ETH_P_IPV6)) ?
- TX_TCP_LSO6 : TX_TCP_LSO;
- tso = 1;
+ while (copied < hdr_len) {
+
+ copy_len = min((int)sizeof(struct cmd_desc_type0) -
+ offset, (hdr_len - copied));
+
+ hwdesc = &tx_ring->desc_head[producer];
+ tx_ring->cmd_buf_arr[producer].skb = NULL;
+
+ skb_copy_from_linear_data_offset(skb, copied,
+ (char *) hwdesc + offset, copy_len);
+
+ copied += copy_len;
+ offset = 0;
+
+ producer = get_next_index(producer, tx_ring->num_desc);
+ }
+
+ tx_ring->producer = producer;
+ smp_mb();
+ adapter->stats.lso_frames++;
} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
u8 l4proto;
- if (protocol == cpu_to_be16(ETH_P_IP)) {
+ if (protocol == ETH_P_IP) {
l4proto = ip_hdr(skb)->protocol;
if (l4proto == IPPROTO_TCP)
opcode = TX_TCP_PKT;
else if (l4proto == IPPROTO_UDP)
opcode = TX_UDP_PKT;
- } else if (protocol == cpu_to_be16(ETH_P_IPV6)) {
+ } else if (protocol == ETH_P_IPV6) {
l4proto = ipv6_hdr(skb)->nexthdr;
if (l4proto == IPPROTO_TCP)
@@ -1939,63 +2089,11 @@ qlcnic_tso_check(struct net_device *netdev,
opcode = TX_UDPV6_PKT;
}
}
-
first_desc->tcp_hdr_offset += skb_transport_offset(skb);
first_desc->ip_hdr_offset += skb_network_offset(skb);
qlcnic_set_tx_flags_opcode(first_desc, flags, opcode);
- if (!tso)
- return;
-
- /* For LSO, we need to copy the MAC/IP/TCP headers into
- * the descriptor ring
- */
- copied = 0;
- offset = 2;
-
- if (vlan_oob) {
- /* Create a TSO vlan header template for firmware */
-
- hwdesc = &tx_ring->desc_head[producer];
- tx_ring->cmd_buf_arr[producer].skb = NULL;
-
- copy_len = min((int)sizeof(struct cmd_desc_type0) - offset,
- hdr_len + VLAN_HLEN);
-
- vh = (struct vlan_ethhdr *)((char *)hwdesc + 2);
- skb_copy_from_linear_data(skb, vh, 12);
- vh->h_vlan_proto = htons(ETH_P_8021Q);
- vh->h_vlan_TCI = (__be16)swab16((u16)first_desc->vlan_TCI);
-
- skb_copy_from_linear_data_offset(skb, 12,
- (char *)vh + 16, copy_len - 16);
-
- copied = copy_len - VLAN_HLEN;
- offset = 0;
-
- producer = get_next_index(producer, tx_ring->num_desc);
- }
-
- while (copied < hdr_len) {
-
- copy_len = min((int)sizeof(struct cmd_desc_type0) - offset,
- (hdr_len - copied));
-
- hwdesc = &tx_ring->desc_head[producer];
- tx_ring->cmd_buf_arr[producer].skb = NULL;
-
- skb_copy_from_linear_data_offset(skb, copied,
- (char *)hwdesc + offset, copy_len);
-
- copied += copy_len;
- offset = 0;
-
- producer = get_next_index(producer, tx_ring->num_desc);
- }
-
- tx_ring->producer = producer;
- barrier();
- adapter->stats.lso_frames++;
+ return 0;
}
static int
@@ -2046,39 +2144,21 @@ out_err:
return -ENOMEM;
}
-static int
-qlcnic_check_tx_tagging(struct qlcnic_adapter *adapter,
- struct sk_buff *skb,
- struct cmd_desc_type0 *first_desc)
+static void
+qlcnic_unmap_buffers(struct pci_dev *pdev, struct sk_buff *skb,
+ struct qlcnic_cmd_buffer *pbuf)
{
- u8 opcode = 0;
- u16 flags = 0;
- __be16 protocol = skb->protocol;
- struct vlan_ethhdr *vh;
+ struct qlcnic_skb_frag *nf = &pbuf->frag_array[0];
+ int nr_frags = skb_shinfo(skb)->nr_frags;
+ int i;
- if (protocol == cpu_to_be16(ETH_P_8021Q)) {
- vh = (struct vlan_ethhdr *)skb->data;
- protocol = vh->h_vlan_encapsulated_proto;
- flags = FLAGS_VLAN_TAGGED;
- qlcnic_set_tx_vlan_tci(first_desc, ntohs(vh->h_vlan_TCI));
- } else if (vlan_tx_tag_present(skb)) {
- flags = FLAGS_VLAN_OOB;
- qlcnic_set_tx_vlan_tci(first_desc, vlan_tx_tag_get(skb));
+ for (i = 0; i < nr_frags; i++) {
+ nf = &pbuf->frag_array[i+1];
+ pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE);
}
- if (unlikely(adapter->pvid)) {
- if (first_desc->vlan_TCI &&
- !(adapter->flags & QLCNIC_TAGGING_ENABLED))
- return -EIO;
- if (first_desc->vlan_TCI &&
- (adapter->flags & QLCNIC_TAGGING_ENABLED))
- goto set_flags;
- flags = FLAGS_VLAN_OOB;
- qlcnic_set_tx_vlan_tci(first_desc, adapter->pvid);
- }
-set_flags:
- qlcnic_set_tx_flags_opcode(first_desc, flags, opcode);
- return 0;
+ nf = &pbuf->frag_array[0];
+ pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE);
}
static inline void
@@ -2103,7 +2183,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
int i, k;
u32 producer;
- int frag_count, no_of_desc;
+ int frag_count;
u32 num_txd = tx_ring->num_desc;
if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
@@ -2133,12 +2213,8 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
frag_count = 1 + skb_shinfo(skb)->nr_frags;
}
- /* 4 fragments per cmd des */
- no_of_desc = (frag_count + 3) >> 2;
-
if (unlikely(qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH)) {
netif_stop_queue(netdev);
- smp_mb();
if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH)
netif_start_queue(netdev);
else {
@@ -2155,9 +2231,6 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
first_desc = hwdesc = &tx_ring->desc_head[producer];
qlcnic_clear_cmddesc((u64 *)hwdesc);
- if (qlcnic_check_tx_tagging(adapter, skb, first_desc))
- goto drop_packet;
-
if (qlcnic_map_tx_skb(pdev, skb, pbuf)) {
adapter->stats.tx_dma_map_error++;
goto drop_packet;
@@ -2201,8 +2274,10 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
tx_ring->producer = get_next_index(producer, num_txd);
+ smp_mb();
- qlcnic_tso_check(netdev, tx_ring, first_desc, skb);
+ if (unlikely(qlcnic_tx_pkt(adapter, first_desc, skb)))
+ goto unwind_buff;
if (qlcnic_mac_learn)
qlcnic_send_filter(adapter, tx_ring, first_desc, skb);
@@ -2214,6 +2289,8 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
+unwind_buff:
+ qlcnic_unmap_buffers(pdev, skb, pbuf);
drop_packet:
adapter->stats.txdropped++;
dev_kfree_skb_any(skb);
@@ -2260,16 +2337,16 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup)
{
struct net_device *netdev = adapter->netdev;
- if (adapter->ahw.linkup && !linkup) {
+ if (adapter->ahw->linkup && !linkup) {
netdev_info(netdev, "NIC Link is down\n");
- adapter->ahw.linkup = 0;
+ adapter->ahw->linkup = 0;
if (netif_running(netdev)) {
netif_carrier_off(netdev);
netif_stop_queue(netdev);
}
- } else if (!adapter->ahw.linkup && linkup) {
+ } else if (!adapter->ahw->linkup && linkup) {
netdev_info(netdev, "NIC Link is up\n");
- adapter->ahw.linkup = 1;
+ adapter->ahw->linkup = 1;
if (netif_running(netdev)) {
netif_carrier_on(netdev);
netif_wake_queue(netdev);
@@ -2505,7 +2582,7 @@ static void qlcnic_poll_controller(struct net_device *netdev)
int ring;
struct qlcnic_host_sds_ring *sds_ring;
struct qlcnic_adapter *adapter = netdev_priv(netdev);
- struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
disable_irq(adapter->irq);
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
@@ -2756,6 +2833,8 @@ skip_ack_check:
set_bit(__QLCNIC_START_FW, &adapter->state);
QLCDB(adapter, DRV, "Restarting fw\n");
qlcnic_idc_debug_info(adapter, 0);
+ QLCDB(adapter, DRV, "Take FW dump\n");
+ qlcnic_dump_fw(adapter);
}
qlcnic_api_unlock(adapter);
@@ -2854,7 +2933,7 @@ qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter)
}
/*Transit to RESET state from READY state only */
-static void
+void
qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
{
u32 state;
@@ -3266,6 +3345,56 @@ static struct device_attribute dev_attr_diag_mode = {
.store = qlcnic_store_diag_mode,
};
+int qlcnic_validate_max_rss(struct net_device *netdev, u8 max_hw, u8 val)
+{
+ if (!use_msi_x && !use_msi) {
+ netdev_info(netdev, "no msix or msi support, hence no rss\n");
+ return -EINVAL;
+ }
+
+ if ((val > max_hw) || (val < 2) || !is_power_of_2(val)) {
+ netdev_info(netdev, "rss_ring valid range [2 - %x] in "
+ " powers of 2\n", max_hw);
+ return -EINVAL;
+ }
+ return 0;
+
+}
+
+int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data)
+{
+ struct net_device *netdev = adapter->netdev;
+ int err = 0;
+
+ if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+ return -EBUSY;
+
+ netif_device_detach(netdev);
+ if (netif_running(netdev))
+ __qlcnic_down(adapter, netdev);
+ qlcnic_detach(adapter);
+ qlcnic_teardown_intr(adapter);
+
+ if (qlcnic_enable_msix(adapter, data)) {
+ netdev_info(netdev, "failed setting max_rss; rss disabled\n");
+ qlcnic_enable_msi_legacy(adapter);
+ }
+
+ if (netif_running(netdev)) {
+ err = qlcnic_attach(adapter);
+ if (err)
+ goto done;
+ err = __qlcnic_up(adapter, netdev);
+ if (err)
+ goto done;
+ qlcnic_restore_indev_addr(netdev, NETDEV_UP);
+ }
+ done:
+ netif_device_attach(netdev);
+ clear_bit(__QLCNIC_RESETTING, &adapter->state);
+ return err;
+}
+
static int
qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter,
loff_t offset, size_t size)
@@ -3396,7 +3525,6 @@ qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj,
return size;
}
-
static struct bin_attribute bin_attr_crb = {
.attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)},
.size = 0,
@@ -3515,7 +3643,7 @@ validate_esw_config(struct qlcnic_adapter *adapter,
u8 pci_func;
int i;
- op_mode = readl(adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE);
+ op_mode = readl(adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE);
for (i = 0; i < count; i++) {
pci_func = esw_cfg[i].pci_func;
@@ -3581,13 +3709,13 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
if (qlcnic_config_switch_port(adapter, &esw_cfg[i]))
return QL_STATUS_INVALID_PARAM;
- if (adapter->ahw.pci_func != esw_cfg[i].pci_func)
+ if (adapter->ahw->pci_func != esw_cfg[i].pci_func)
continue;
op_mode = esw_cfg[i].op_mode;
qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]);
esw_cfg[i].op_mode = op_mode;
- esw_cfg[i].pci_func = adapter->ahw.pci_func;
+ esw_cfg[i].pci_func = adapter->ahw->pci_func;
switch (esw_cfg[i].op_mode) {
case QLCNIC_PORT_DEFAULTS:
@@ -3968,14 +4096,14 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
dev_info(dev, "failed to create crb sysfs entry\n");
if (device_create_bin_file(dev, &bin_attr_mem))
dev_info(dev, "failed to create mem sysfs entry\n");
+ if (device_create_bin_file(dev, &bin_attr_pci_config))
+ dev_info(dev, "failed to create pci config sysfs entry");
if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
return;
if (device_create_bin_file(dev, &bin_attr_esw_config))
dev_info(dev, "failed to create esw config sysfs entry");
if (adapter->op_mode != QLCNIC_MGMT_FUNC)
return;
- if (device_create_bin_file(dev, &bin_attr_pci_config))
- dev_info(dev, "failed to create pci config sysfs entry");
if (device_create_bin_file(dev, &bin_attr_npar_config))
dev_info(dev, "failed to create npar config sysfs entry");
if (device_create_bin_file(dev, &bin_attr_pm_config))
@@ -3996,12 +4124,12 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
device_remove_file(dev, &dev_attr_diag_mode);
device_remove_bin_file(dev, &bin_attr_crb);
device_remove_bin_file(dev, &bin_attr_mem);
+ device_remove_bin_file(dev, &bin_attr_pci_config);
if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
return;
device_remove_bin_file(dev, &bin_attr_esw_config);
if (adapter->op_mode != QLCNIC_MGMT_FUNC)
return;
- device_remove_bin_file(dev, &bin_attr_pci_config);
device_remove_bin_file(dev, &bin_attr_npar_config);
device_remove_bin_file(dev, &bin_attr_pm_config);
device_remove_bin_file(dev, &bin_attr_esw_stats);
@@ -4048,14 +4176,10 @@ qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event)
qlcnic_config_indev_addr(adapter, netdev, event);
- if (!adapter->vlgrp)
- return;
-
- for (vid = 0; vid < VLAN_N_VID; vid++) {
- dev = vlan_group_get_device(adapter->vlgrp, vid);
+ for_each_set_bit(vid, adapter->vlans, VLAN_N_VID) {
+ dev = vlan_find_dev(netdev, vid);
if (!dev)
continue;
-
qlcnic_config_indev_addr(adapter, dev, event);
}
}
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 4757c59a07a..d32850715f5 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -2134,7 +2134,7 @@ struct ql_adapter {
struct delayed_work mpi_idc_work;
struct delayed_work mpi_core_to_log;
struct completion ide_completion;
- struct nic_operations *nic_ops;
+ const struct nic_operations *nic_ops;
u16 device_id;
struct timer_list timer;
atomic_t lb_count;
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index 8149cc9de4c..19b00fa0eaf 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -356,7 +356,7 @@ static int ql_get_settings(struct net_device *ndev,
ecmd->port = PORT_FIBRE;
}
- ecmd->speed = SPEED_10000;
+ ethtool_cmd_speed_set(ecmd, SPEED_10000);
ecmd->duplex = DUPLEX_FULL;
return 0;
@@ -412,31 +412,31 @@ static int ql_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
return 0;
}
-static int ql_phys_id(struct net_device *ndev, u32 data)
+static int ql_set_phys_id(struct net_device *ndev,
+ enum ethtool_phys_id_state state)
+
{
struct ql_adapter *qdev = netdev_priv(ndev);
- u32 led_reg, i;
- int status;
-
- /* Save the current LED settings */
- status = ql_mb_get_led_cfg(qdev);
- if (status)
- return status;
- led_reg = qdev->led_config;
- /* Start blinking the led */
- if (!data || data > 300)
- data = 300;
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ /* Save the current LED settings */
+ if (ql_mb_get_led_cfg(qdev))
+ return -EIO;
- for (i = 0; i < (data * 10); i++)
+ /* Start blinking */
ql_mb_set_led_cfg(qdev, QL_LED_BLINK);
+ return 0;
- /* Restore LED settings */
- status = ql_mb_set_led_cfg(qdev, led_reg);
- if (status)
- return status;
+ case ETHTOOL_ID_INACTIVE:
+ /* Restore LED settings */
+ if (ql_mb_set_led_cfg(qdev, qdev->led_config))
+ return -EIO;
+ return 0;
- return 0;
+ default:
+ return -EINVAL;
+ }
}
static int ql_start_loopback(struct ql_adapter *qdev)
@@ -655,32 +655,6 @@ static int ql_set_pauseparam(struct net_device *netdev,
return status;
}
-static u32 ql_get_rx_csum(struct net_device *netdev)
-{
- struct ql_adapter *qdev = netdev_priv(netdev);
- return qdev->rx_csum;
-}
-
-static int ql_set_rx_csum(struct net_device *netdev, uint32_t data)
-{
- struct ql_adapter *qdev = netdev_priv(netdev);
- qdev->rx_csum = data;
- return 0;
-}
-
-static int ql_set_tso(struct net_device *ndev, uint32_t data)
-{
-
- if (data) {
- ndev->features |= NETIF_F_TSO;
- ndev->features |= NETIF_F_TSO6;
- } else {
- ndev->features &= ~NETIF_F_TSO;
- ndev->features &= ~NETIF_F_TSO6;
- }
- return 0;
-}
-
static u32 ql_get_msglevel(struct net_device *ndev)
{
struct ql_adapter *qdev = netdev_priv(ndev);
@@ -703,18 +677,10 @@ const struct ethtool_ops qlge_ethtool_ops = {
.get_msglevel = ql_get_msglevel,
.set_msglevel = ql_set_msglevel,
.get_link = ethtool_op_get_link,
- .phys_id = ql_phys_id,
+ .set_phys_id = ql_set_phys_id,
.self_test = ql_self_test,
.get_pauseparam = ql_get_pauseparam,
.set_pauseparam = ql_set_pauseparam,
- .get_rx_csum = ql_get_rx_csum,
- .set_rx_csum = ql_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = ql_set_tso,
.get_coalesce = ql_get_coalesce,
.set_coalesce = ql_set_coalesce,
.get_sset_count = ql_get_sset_count,
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 5bb31194543..6c9d124cfc7 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -1571,7 +1571,7 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev,
skb->protocol = eth_type_trans(skb, ndev);
skb_checksum_none_assert(skb);
- if (qdev->rx_csum &&
+ if ((ndev->features & NETIF_F_RXCSUM) &&
!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
/* TCP frame. */
if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
@@ -1684,7 +1684,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,
/* If rx checksum is on, and there are no
* csum or frame errors.
*/
- if (qdev->rx_csum &&
+ if ((ndev->features & NETIF_F_RXCSUM) &&
!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
/* TCP frame. */
if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
@@ -2004,7 +2004,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev,
/* If rx checksum is on, and there are no
* csum or frame errors.
*/
- if (qdev->rx_csum &&
+ if ((ndev->features & NETIF_F_RXCSUM) &&
!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
/* TCP frame. */
if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
@@ -4412,12 +4412,12 @@ error:
rtnl_unlock();
}
-static struct nic_operations qla8012_nic_ops = {
+static const struct nic_operations qla8012_nic_ops = {
.get_flash = ql_get_8012_flash_params,
.port_initialize = ql_8012_port_initialize,
};
-static struct nic_operations qla8000_nic_ops = {
+static const struct nic_operations qla8000_nic_ops = {
.get_flash = ql_get_8000_flash_params,
.port_initialize = ql_8000_port_initialize,
};
@@ -4621,7 +4621,6 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
/*
* Set up the operating parameters.
*/
- qdev->rx_csum = 1;
qdev->workqueue = create_singlethread_workqueue(ndev->name);
INIT_DELAYED_WORK(&qdev->asic_reset_work, ql_asic_reset_work);
INIT_DELAYED_WORK(&qdev->mpi_reset_work, ql_mpi_reset_work);
@@ -4695,15 +4694,11 @@ static int __devinit qlge_probe(struct pci_dev *pdev,
qdev = netdev_priv(ndev);
SET_NETDEV_DEV(ndev, &pdev->dev);
- ndev->features = (0
- | NETIF_F_IP_CSUM
- | NETIF_F_SG
- | NETIF_F_TSO
- | NETIF_F_TSO6
- | NETIF_F_TSO_ECN
- | NETIF_F_HW_VLAN_TX
- | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER);
- ndev->features |= NETIF_F_GRO;
+ ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN |
+ NETIF_F_HW_VLAN_TX | NETIF_F_RXCSUM;
+ ndev->features = ndev->hw_features |
+ NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
if (test_bit(QL_DMA64, &qdev->flags))
ndev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 397c36810a1..04f4e6086cd 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -37,6 +37,8 @@
#define FIRMWARE_8168D_1 "rtl_nic/rtl8168d-1.fw"
#define FIRMWARE_8168D_2 "rtl_nic/rtl8168d-2.fw"
+#define FIRMWARE_8168E_1 "rtl_nic/rtl8168e-1.fw"
+#define FIRMWARE_8168E_2 "rtl_nic/rtl8168e-2.fw"
#define FIRMWARE_8105E_1 "rtl_nic/rtl8105e-1.fw"
#ifdef RTL8169_DEBUG
@@ -96,89 +98,125 @@ static const int multicast_filter_limit = 32;
#define RTL_R32(reg) readl (ioaddr + (reg))
enum mac_version {
- RTL_GIGA_MAC_NONE = 0x00,
- RTL_GIGA_MAC_VER_01 = 0x01, // 8169
- RTL_GIGA_MAC_VER_02 = 0x02, // 8169S
- RTL_GIGA_MAC_VER_03 = 0x03, // 8110S
- RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
- RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
- RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
- RTL_GIGA_MAC_VER_07 = 0x07, // 8102e
- RTL_GIGA_MAC_VER_08 = 0x08, // 8102e
- RTL_GIGA_MAC_VER_09 = 0x09, // 8102e
- RTL_GIGA_MAC_VER_10 = 0x0a, // 8101e
- RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
- RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be
- RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb
- RTL_GIGA_MAC_VER_14 = 0x0e, // 8101 ?
- RTL_GIGA_MAC_VER_15 = 0x0f, // 8101 ?
- RTL_GIGA_MAC_VER_16 = 0x11, // 8101Ec
- RTL_GIGA_MAC_VER_17 = 0x10, // 8168Bf
- RTL_GIGA_MAC_VER_18 = 0x12, // 8168CP
- RTL_GIGA_MAC_VER_19 = 0x13, // 8168C
- RTL_GIGA_MAC_VER_20 = 0x14, // 8168C
- RTL_GIGA_MAC_VER_21 = 0x15, // 8168C
- RTL_GIGA_MAC_VER_22 = 0x16, // 8168C
- RTL_GIGA_MAC_VER_23 = 0x17, // 8168CP
- RTL_GIGA_MAC_VER_24 = 0x18, // 8168CP
- RTL_GIGA_MAC_VER_25 = 0x19, // 8168D
- RTL_GIGA_MAC_VER_26 = 0x1a, // 8168D
- RTL_GIGA_MAC_VER_27 = 0x1b, // 8168DP
- RTL_GIGA_MAC_VER_28 = 0x1c, // 8168DP
- RTL_GIGA_MAC_VER_29 = 0x1d, // 8105E
- RTL_GIGA_MAC_VER_30 = 0x1e, // 8105E
+ RTL_GIGA_MAC_VER_01 = 0,
+ RTL_GIGA_MAC_VER_02,
+ RTL_GIGA_MAC_VER_03,
+ RTL_GIGA_MAC_VER_04,
+ RTL_GIGA_MAC_VER_05,
+ RTL_GIGA_MAC_VER_06,
+ RTL_GIGA_MAC_VER_07,
+ RTL_GIGA_MAC_VER_08,
+ RTL_GIGA_MAC_VER_09,
+ RTL_GIGA_MAC_VER_10,
+ RTL_GIGA_MAC_VER_11,
+ RTL_GIGA_MAC_VER_12,
+ RTL_GIGA_MAC_VER_13,
+ RTL_GIGA_MAC_VER_14,
+ RTL_GIGA_MAC_VER_15,
+ RTL_GIGA_MAC_VER_16,
+ RTL_GIGA_MAC_VER_17,
+ RTL_GIGA_MAC_VER_18,
+ RTL_GIGA_MAC_VER_19,
+ RTL_GIGA_MAC_VER_20,
+ RTL_GIGA_MAC_VER_21,
+ RTL_GIGA_MAC_VER_22,
+ RTL_GIGA_MAC_VER_23,
+ RTL_GIGA_MAC_VER_24,
+ RTL_GIGA_MAC_VER_25,
+ RTL_GIGA_MAC_VER_26,
+ RTL_GIGA_MAC_VER_27,
+ RTL_GIGA_MAC_VER_28,
+ RTL_GIGA_MAC_VER_29,
+ RTL_GIGA_MAC_VER_30,
+ RTL_GIGA_MAC_VER_31,
+ RTL_GIGA_MAC_VER_32,
+ RTL_GIGA_MAC_VER_33,
+ RTL_GIGA_MAC_NONE = 0xff,
};
-#define _R(NAME,MAC,MASK) \
- { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK }
+enum rtl_tx_desc_version {
+ RTL_TD_0 = 0,
+ RTL_TD_1 = 1,
+};
+
+#define _R(NAME,TD,FW) \
+ { .name = NAME, .txd_version = TD, .fw_name = FW }
static const struct {
const char *name;
- u8 mac_version;
- u32 RxConfigMask; /* Clears the bits supported by this chip */
-} rtl_chip_info[] = {
- _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880), // 8169
- _R("RTL8169s", RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S
- _R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S
- _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
- _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd
- _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe
- _R("RTL8102e", RTL_GIGA_MAC_VER_07, 0xff7e1880), // PCI-E
- _R("RTL8102e", RTL_GIGA_MAC_VER_08, 0xff7e1880), // PCI-E
- _R("RTL8102e", RTL_GIGA_MAC_VER_09, 0xff7e1880), // PCI-E
- _R("RTL8101e", RTL_GIGA_MAC_VER_10, 0xff7e1880), // PCI-E
- _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
- _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
- _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
- _R("RTL8100e", RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139
- _R("RTL8100e", RTL_GIGA_MAC_VER_15, 0xff7e1880), // PCI-E 8139
- _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_17, 0xff7e1880), // PCI-E
- _R("RTL8101e", RTL_GIGA_MAC_VER_16, 0xff7e1880), // PCI-E
- _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_18, 0xff7e1880), // PCI-E
- _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_19, 0xff7e1880), // PCI-E
- _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_20, 0xff7e1880), // PCI-E
- _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_21, 0xff7e1880), // PCI-E
- _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_22, 0xff7e1880), // PCI-E
- _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_23, 0xff7e1880), // PCI-E
- _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E
- _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880), // PCI-E
- _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_26, 0xff7e1880), // PCI-E
- _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, 0xff7e1880), // PCI-E
- _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_28, 0xff7e1880), // PCI-E
- _R("RTL8105e", RTL_GIGA_MAC_VER_29, 0xff7e1880), // PCI-E
- _R("RTL8105e", RTL_GIGA_MAC_VER_30, 0xff7e1880) // PCI-E
-};
-#undef _R
-
-static const struct rtl_firmware_info {
- int mac_version;
+ enum rtl_tx_desc_version txd_version;
const char *fw_name;
-} rtl_firmware_infos[] = {
- { .mac_version = RTL_GIGA_MAC_VER_25, .fw_name = FIRMWARE_8168D_1 },
- { .mac_version = RTL_GIGA_MAC_VER_26, .fw_name = FIRMWARE_8168D_2 },
- { .mac_version = RTL_GIGA_MAC_VER_29, .fw_name = FIRMWARE_8105E_1 },
- { .mac_version = RTL_GIGA_MAC_VER_30, .fw_name = FIRMWARE_8105E_1 }
+} rtl_chip_infos[] = {
+ /* PCI devices. */
+ [RTL_GIGA_MAC_VER_01] =
+ _R("RTL8169", RTL_TD_0, NULL),
+ [RTL_GIGA_MAC_VER_02] =
+ _R("RTL8169s", RTL_TD_0, NULL),
+ [RTL_GIGA_MAC_VER_03] =
+ _R("RTL8110s", RTL_TD_0, NULL),
+ [RTL_GIGA_MAC_VER_04] =
+ _R("RTL8169sb/8110sb", RTL_TD_0, NULL),
+ [RTL_GIGA_MAC_VER_05] =
+ _R("RTL8169sc/8110sc", RTL_TD_0, NULL),
+ [RTL_GIGA_MAC_VER_06] =
+ _R("RTL8169sc/8110sc", RTL_TD_0, NULL),
+ /* PCI-E devices. */
+ [RTL_GIGA_MAC_VER_07] =
+ _R("RTL8102e", RTL_TD_1, NULL),
+ [RTL_GIGA_MAC_VER_08] =
+ _R("RTL8102e", RTL_TD_1, NULL),
+ [RTL_GIGA_MAC_VER_09] =
+ _R("RTL8102e", RTL_TD_1, NULL),
+ [RTL_GIGA_MAC_VER_10] =
+ _R("RTL8101e", RTL_TD_0, NULL),
+ [RTL_GIGA_MAC_VER_11] =
+ _R("RTL8168b/8111b", RTL_TD_0, NULL),
+ [RTL_GIGA_MAC_VER_12] =
+ _R("RTL8168b/8111b", RTL_TD_0, NULL),
+ [RTL_GIGA_MAC_VER_13] =
+ _R("RTL8101e", RTL_TD_0, NULL),
+ [RTL_GIGA_MAC_VER_14] =
+ _R("RTL8100e", RTL_TD_0, NULL),
+ [RTL_GIGA_MAC_VER_15] =
+ _R("RTL8100e", RTL_TD_0, NULL),
+ [RTL_GIGA_MAC_VER_16] =
+ _R("RTL8101e", RTL_TD_0, NULL),
+ [RTL_GIGA_MAC_VER_17] =
+ _R("RTL8168b/8111b", RTL_TD_0, NULL),
+ [RTL_GIGA_MAC_VER_18] =
+ _R("RTL8168cp/8111cp", RTL_TD_1, NULL),
+ [RTL_GIGA_MAC_VER_19] =
+ _R("RTL8168c/8111c", RTL_TD_1, NULL),
+ [RTL_GIGA_MAC_VER_20] =
+ _R("RTL8168c/8111c", RTL_TD_1, NULL),
+ [RTL_GIGA_MAC_VER_21] =
+ _R("RTL8168c/8111c", RTL_TD_1, NULL),
+ [RTL_GIGA_MAC_VER_22] =
+ _R("RTL8168c/8111c", RTL_TD_1, NULL),
+ [RTL_GIGA_MAC_VER_23] =
+ _R("RTL8168cp/8111cp", RTL_TD_1, NULL),
+ [RTL_GIGA_MAC_VER_24] =
+ _R("RTL8168cp/8111cp", RTL_TD_1, NULL),
+ [RTL_GIGA_MAC_VER_25] =
+ _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_1),
+ [RTL_GIGA_MAC_VER_26] =
+ _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_2),
+ [RTL_GIGA_MAC_VER_27] =
+ _R("RTL8168dp/8111dp", RTL_TD_1, NULL),
+ [RTL_GIGA_MAC_VER_28] =
+ _R("RTL8168dp/8111dp", RTL_TD_1, NULL),
+ [RTL_GIGA_MAC_VER_29] =
+ _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1),
+ [RTL_GIGA_MAC_VER_30] =
+ _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1),
+ [RTL_GIGA_MAC_VER_31] =
+ _R("RTL8168dp/8111dp", RTL_TD_1, NULL),
+ [RTL_GIGA_MAC_VER_32] =
+ _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_1),
+ [RTL_GIGA_MAC_VER_33] =
+ _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_2)
};
+#undef _R
enum cfg_version {
RTL_CFG_0 = 0x00,
@@ -232,6 +270,9 @@ enum rtl_registers {
IntrStatus = 0x3e,
TxConfig = 0x40,
RxConfig = 0x44,
+
+#define RTL_RX_CONFIG_MASK 0xff7e1880u
+
RxMissed = 0x4c,
Cfg9346 = 0x50,
Config0 = 0x51,
@@ -325,7 +366,9 @@ enum rtl8168_registers {
#define OCPAR_FLAG 0x80000000
#define OCPAR_GPHY_WRITE_CMD 0x8000f060
#define OCPAR_GPHY_READ_CMD 0x0000f060
- RDSAR1 = 0xd0 /* 8168c only. Undocumented on 8168dp */
+ RDSAR1 = 0xd0, /* 8168c only. Undocumented on 8168dp */
+ MISC = 0xf0, /* 8168e only. */
+#define TXPLA_RST (1 << 29)
};
enum rtl_register_content {
@@ -403,6 +446,7 @@ enum rtl_register_content {
BWF = (1 << 6), /* Accept Broadcast wakeup frame */
MWF = (1 << 5), /* Accept Multicast wakeup frame */
UWF = (1 << 4), /* Accept Unicast wakeup frame */
+ Spi_en = (1 << 3),
LanWake = (1 << 1), /* LanWake enable/disable */
PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */
@@ -451,21 +495,69 @@ enum rtl_register_content {
CounterDump = 0x8,
};
-enum desc_status_bit {
+enum rtl_desc_bit {
+ /* First doubleword. */
DescOwn = (1 << 31), /* Descriptor is owned by NIC */
RingEnd = (1 << 30), /* End of descriptor ring */
FirstFrag = (1 << 29), /* First segment of a packet */
LastFrag = (1 << 28), /* Final segment of a packet */
+};
+
+/* Generic case. */
+enum rtl_tx_desc_bit {
+ /* First doubleword. */
+ TD_LSO = (1 << 27), /* Large Send Offload */
+#define TD_MSS_MAX 0x07ffu /* MSS value */
- /* Tx private */
- LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */
- MSSShift = 16, /* MSS value position */
- MSSMask = 0xfff, /* MSS value + LargeSend bit: 12 bits */
- IPCS = (1 << 18), /* Calculate IP checksum */
- UDPCS = (1 << 17), /* Calculate UDP/IP checksum */
- TCPCS = (1 << 16), /* Calculate TCP/IP checksum */
- TxVlanTag = (1 << 17), /* Add VLAN tag */
+ /* Second doubleword. */
+ TxVlanTag = (1 << 17), /* Add VLAN tag */
+};
+
+/* 8169, 8168b and 810x except 8102e. */
+enum rtl_tx_desc_bit_0 {
+ /* First doubleword. */
+#define TD0_MSS_SHIFT 16 /* MSS position (11 bits) */
+ TD0_TCP_CS = (1 << 16), /* Calculate TCP/IP checksum */
+ TD0_UDP_CS = (1 << 17), /* Calculate UDP/IP checksum */
+ TD0_IP_CS = (1 << 18), /* Calculate IP checksum */
+};
+
+/* 8102e, 8168c and beyond. */
+enum rtl_tx_desc_bit_1 {
+ /* Second doubleword. */
+#define TD1_MSS_SHIFT 18 /* MSS position (11 bits) */
+ TD1_IP_CS = (1 << 29), /* Calculate IP checksum */
+ TD1_TCP_CS = (1 << 30), /* Calculate TCP/IP checksum */
+ TD1_UDP_CS = (1 << 31), /* Calculate UDP/IP checksum */
+};
+static const struct rtl_tx_desc_info {
+ struct {
+ u32 udp;
+ u32 tcp;
+ } checksum;
+ u16 mss_shift;
+ u16 opts_offset;
+} tx_desc_info [] = {
+ [RTL_TD_0] = {
+ .checksum = {
+ .udp = TD0_IP_CS | TD0_UDP_CS,
+ .tcp = TD0_IP_CS | TD0_TCP_CS
+ },
+ .mss_shift = TD0_MSS_SHIFT,
+ .opts_offset = 0
+ },
+ [RTL_TD_1] = {
+ .checksum = {
+ .udp = TD1_IP_CS | TD1_UDP_CS,
+ .tcp = TD1_IP_CS | TD1_TCP_CS
+ },
+ .mss_shift = TD1_MSS_SHIFT,
+ .opts_offset = 1
+ }
+};
+
+enum rtl_rx_desc_bit {
/* Rx private */
PID1 = (1 << 18), /* Protocol ID bit 1/2 */
PID0 = (1 << 17), /* Protocol ID bit 2/2 */
@@ -525,13 +617,13 @@ struct rtl8169_counters {
struct rtl8169_private {
void __iomem *mmio_addr; /* memory map physical address */
- struct pci_dev *pci_dev; /* Index of PCI device */
+ struct pci_dev *pci_dev;
struct net_device *dev;
struct napi_struct napi;
- spinlock_t lock; /* spin lock flag */
+ spinlock_t lock;
u32 msg_enable;
- int chipset;
- int mac_version;
+ u16 txd_version;
+ u16 mac_version;
u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
u32 dirty_rx;
@@ -547,7 +639,6 @@ struct rtl8169_private {
u16 intr_event;
u16 napi_event;
u16 intr_mask;
- int phy_1000_ctrl_reg;
struct mdio_ops {
void (*write)(void __iomem *, int, int);
@@ -588,6 +679,8 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(RTL8169_VERSION);
MODULE_FIRMWARE(FIRMWARE_8168D_1);
MODULE_FIRMWARE(FIRMWARE_8168D_2);
+MODULE_FIRMWARE(FIRMWARE_8168E_1);
+MODULE_FIRMWARE(FIRMWARE_8168E_2);
MODULE_FIRMWARE(FIRMWARE_8105E_1);
static int rtl8169_open(struct net_device *dev);
@@ -659,32 +752,49 @@ static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd)
#define OOB_CMD_DRIVER_START 0x05
#define OOB_CMD_DRIVER_STOP 0x06
+static u16 rtl8168_get_ocp_reg(struct rtl8169_private *tp)
+{
+ return (tp->mac_version == RTL_GIGA_MAC_VER_31) ? 0xb8 : 0x10;
+}
+
static void rtl8168_driver_start(struct rtl8169_private *tp)
{
+ u16 reg;
int i;
rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START);
+ reg = rtl8168_get_ocp_reg(tp);
+
for (i = 0; i < 10; i++) {
msleep(10);
- if (ocp_read(tp, 0x0f, 0x0010) & 0x00000800)
+ if (ocp_read(tp, 0x0f, reg) & 0x00000800)
break;
}
}
static void rtl8168_driver_stop(struct rtl8169_private *tp)
{
+ u16 reg;
int i;
rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP);
+ reg = rtl8168_get_ocp_reg(tp);
+
for (i = 0; i < 10; i++) {
msleep(10);
- if ((ocp_read(tp, 0x0f, 0x0010) & 0x00000800) == 0)
+ if ((ocp_read(tp, 0x0f, reg) & 0x00000800) == 0)
break;
}
}
+static int r8168dp_check_dash(struct rtl8169_private *tp)
+{
+ u16 reg = rtl8168_get_ocp_reg(tp);
+
+ return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0;
+}
static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
{
@@ -983,9 +1093,8 @@ static void rtl8169_xmii_reset_enable(struct rtl8169_private *tp)
}
static void __rtl8169_check_link_status(struct net_device *dev,
- struct rtl8169_private *tp,
- void __iomem *ioaddr,
- bool pm)
+ struct rtl8169_private *tp,
+ void __iomem *ioaddr, bool pm)
{
unsigned long flags;
@@ -1102,6 +1211,11 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
return 0;
}
+static const char *rtl_lookup_firmware_name(struct rtl8169_private *tp)
+{
+ return rtl_chip_infos[tp->mac_version].fw_name;
+}
+
static void rtl8169_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
@@ -1110,6 +1224,8 @@ static void rtl8169_get_drvinfo(struct net_device *dev,
strcpy(info->driver, MODULENAME);
strcpy(info->version, RTL8169_VERSION);
strcpy(info->bus_info, pci_name(tp->pci_dev));
+ strncpy(info->fw_version, IS_ERR_OR_NULL(tp->fw) ? "N/A" :
+ rtl_lookup_firmware_name(tp), sizeof(info->fw_version) - 1);
}
static int rtl8169_get_regs_len(struct net_device *dev)
@@ -1171,16 +1287,7 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
/* The 8100e/8101e/8102e do Fast Ethernet only. */
- if ((tp->mac_version != RTL_GIGA_MAC_VER_07) &&
- (tp->mac_version != RTL_GIGA_MAC_VER_08) &&
- (tp->mac_version != RTL_GIGA_MAC_VER_09) &&
- (tp->mac_version != RTL_GIGA_MAC_VER_10) &&
- (tp->mac_version != RTL_GIGA_MAC_VER_13) &&
- (tp->mac_version != RTL_GIGA_MAC_VER_14) &&
- (tp->mac_version != RTL_GIGA_MAC_VER_15) &&
- (tp->mac_version != RTL_GIGA_MAC_VER_16) &&
- (tp->mac_version != RTL_GIGA_MAC_VER_29) &&
- (tp->mac_version != RTL_GIGA_MAC_VER_30)) {
+ if (tp->mii.supports_gmii) {
if (adv & ADVERTISED_1000baseT_Half)
giga_ctrl |= ADVERTISE_1000HALF;
if (adv & ADVERTISED_1000baseT_Full)
@@ -1210,12 +1317,10 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
bmcr |= BMCR_FULLDPLX;
}
- tp->phy_1000_ctrl_reg = giga_ctrl;
-
rtl_writephy(tp, MII_BMCR, bmcr);
- if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
+ if (tp->mac_version == RTL_GIGA_MAC_VER_02 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_03) {
if ((speed == SPEED_100) && (autoneg != AUTONEG_ENABLE)) {
rtl_writephy(tp, 0x17, 0x2138);
rtl_writephy(tp, 0x0e, 0x0260);
@@ -1237,10 +1342,14 @@ static int rtl8169_set_speed(struct net_device *dev,
int ret;
ret = tp->set_speed(dev, autoneg, speed, duplex, advertising);
+ if (ret < 0)
+ goto out;
- if (netif_running(dev) && (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL))
+ if (netif_running(dev) && (autoneg == AUTONEG_ENABLE) &&
+ (advertising & ADVERTISED_1000baseT_Full)) {
mod_timer(&tp->timer, jiffies + RTL8169_PHY_TIMEOUT);
-
+ }
+out:
return ret;
}
@@ -1250,22 +1359,25 @@ static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
unsigned long flags;
int ret;
+ del_timer_sync(&tp->timer);
+
spin_lock_irqsave(&tp->lock, flags);
- ret = rtl8169_set_speed(dev,
- cmd->autoneg, cmd->speed, cmd->duplex, cmd->advertising);
+ ret = rtl8169_set_speed(dev, cmd->autoneg, ethtool_cmd_speed(cmd),
+ cmd->duplex, cmd->advertising);
spin_unlock_irqrestore(&tp->lock, flags);
return ret;
}
-static u32 rtl8169_get_rx_csum(struct net_device *dev)
+static u32 rtl8169_fix_features(struct net_device *dev, u32 features)
{
- struct rtl8169_private *tp = netdev_priv(dev);
+ if (dev->mtu > TD_MSS_MAX)
+ features &= ~NETIF_F_ALL_TSO;
- return tp->cp_cmd & RxChkSum;
+ return features;
}
-static int rtl8169_set_rx_csum(struct net_device *dev, u32 data)
+static int rtl8169_set_features(struct net_device *dev, u32 features)
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
@@ -1273,11 +1385,16 @@ static int rtl8169_set_rx_csum(struct net_device *dev, u32 data)
spin_lock_irqsave(&tp->lock, flags);
- if (data)
+ if (features & NETIF_F_RXCSUM)
tp->cp_cmd |= RxChkSum;
else
tp->cp_cmd &= ~RxChkSum;
+ if (dev->features & NETIF_F_HW_VLAN_RX)
+ tp->cp_cmd |= RxVlan;
+ else
+ tp->cp_cmd &= ~RxVlan;
+
RTL_W16(CPlusCmd, tp->cp_cmd);
RTL_R16(CPlusCmd);
@@ -1293,27 +1410,6 @@ static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00;
}
-#define NETIF_F_HW_VLAN_TX_RX (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX)
-
-static void rtl8169_vlan_mode(struct net_device *dev)
-{
- struct rtl8169_private *tp = netdev_priv(dev);
- void __iomem *ioaddr = tp->mmio_addr;
- unsigned long flags;
-
- spin_lock_irqsave(&tp->lock, flags);
- if (dev->features & NETIF_F_HW_VLAN_RX)
- tp->cp_cmd |= RxVlan;
- else
- tp->cp_cmd &= ~RxVlan;
- RTL_W16(CPlusCmd, tp->cp_cmd);
- /* PCI commit */
- RTL_R16(CPlusCmd);
- spin_unlock_irqrestore(&tp->lock, flags);
-
- dev->vlan_features = dev->features &~ NETIF_F_HW_VLAN_TX_RX;
-}
-
static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb)
{
u32 opts2 = le32_to_cpu(desc->opts2);
@@ -1339,7 +1435,7 @@ static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->advertising = (status & TBINwEnable) ? ADVERTISED_Autoneg : 0;
cmd->autoneg = !!(status & TBINwEnable);
- cmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(cmd, SPEED_1000);
cmd->duplex = DUPLEX_FULL; /* Always set */
return 0;
@@ -1424,11 +1520,11 @@ static void rtl8169_update_counters(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
+ struct device *d = &tp->pci_dev->dev;
struct rtl8169_counters *counters;
dma_addr_t paddr;
u32 cmd;
int wait = 1000;
- struct device *d = &tp->pci_dev->dev;
/*
* Some chips are unable to dump tally counters when the receiver
@@ -1448,7 +1544,6 @@ static void rtl8169_update_counters(struct net_device *dev)
while (wait--) {
if ((RTL_R32(CounterAddrLow) & CounterDump) == 0) {
- /* copy updated counters */
memcpy(&tp->counters, counters, sizeof(*counters));
break;
}
@@ -1494,28 +1589,6 @@ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
}
}
-static int rtl8169_set_flags(struct net_device *dev, u32 data)
-{
- struct rtl8169_private *tp = netdev_priv(dev);
- unsigned long old_feat = dev->features;
- int rc;
-
- if ((tp->mac_version == RTL_GIGA_MAC_VER_05) &&
- !(data & ETH_FLAG_RXVLAN)) {
- netif_info(tp, drv, dev, "8110SCd requires hardware Rx VLAN\n");
- return -EINVAL;
- }
-
- rc = ethtool_op_set_flags(dev, data, ETH_FLAG_TXVLAN | ETH_FLAG_RXVLAN);
- if (rc)
- return rc;
-
- if ((old_feat ^ dev->features) & NETIF_F_HW_VLAN_RX)
- rtl8169_vlan_mode(dev);
-
- return 0;
-}
-
static const struct ethtool_ops rtl8169_ethtool_ops = {
.get_drvinfo = rtl8169_get_drvinfo,
.get_regs_len = rtl8169_get_regs_len,
@@ -1524,24 +1597,18 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
.set_settings = rtl8169_set_settings,
.get_msglevel = rtl8169_get_msglevel,
.set_msglevel = rtl8169_set_msglevel,
- .get_rx_csum = rtl8169_get_rx_csum,
- .set_rx_csum = rtl8169_set_rx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .set_sg = ethtool_op_set_sg,
- .set_tso = ethtool_op_set_tso,
.get_regs = rtl8169_get_regs,
.get_wol = rtl8169_get_wol,
.set_wol = rtl8169_set_wol,
.get_strings = rtl8169_get_strings,
.get_sset_count = rtl8169_get_sset_count,
.get_ethtool_stats = rtl8169_get_ethtool_stats,
- .set_flags = rtl8169_set_flags,
- .get_flags = ethtool_op_get_flags,
};
static void rtl8169_get_mac_version(struct rtl8169_private *tp,
- void __iomem *ioaddr)
+ struct net_device *dev, u8 default_version)
{
+ void __iomem *ioaddr = tp->mmio_addr;
/*
* The driver currently handles the 8168Bf and the 8168Be identically
* but they can be identified more specifically through the test below
@@ -1558,6 +1625,11 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
u32 val;
int mac_version;
} mac_info[] = {
+ /* 8168E family. */
+ { 0x7cf00000, 0x2c200000, RTL_GIGA_MAC_VER_33 },
+ { 0x7cf00000, 0x2c100000, RTL_GIGA_MAC_VER_32 },
+ { 0x7c800000, 0x2c000000, RTL_GIGA_MAC_VER_33 },
+
/* 8168D family. */
{ 0x7cf00000, 0x28300000, RTL_GIGA_MAC_VER_26 },
{ 0x7cf00000, 0x28100000, RTL_GIGA_MAC_VER_25 },
@@ -1566,6 +1638,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
/* 8168DP family. */
{ 0x7cf00000, 0x28800000, RTL_GIGA_MAC_VER_27 },
{ 0x7cf00000, 0x28a00000, RTL_GIGA_MAC_VER_28 },
+ { 0x7cf00000, 0x28b00000, RTL_GIGA_MAC_VER_31 },
/* 8168C family. */
{ 0x7cf00000, 0x3cb00000, RTL_GIGA_MAC_VER_24 },
@@ -1585,6 +1658,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
{ 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 },
/* 8101 family. */
+ { 0x7cf00000, 0x40b00000, RTL_GIGA_MAC_VER_30 },
{ 0x7cf00000, 0x40a00000, RTL_GIGA_MAC_VER_30 },
{ 0x7cf00000, 0x40900000, RTL_GIGA_MAC_VER_29 },
{ 0x7c800000, 0x40800000, RTL_GIGA_MAC_VER_30 },
@@ -1621,6 +1695,12 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
while ((reg & p->mask) != p->val)
p++;
tp->mac_version = p->mac_version;
+
+ if (tp->mac_version == RTL_GIGA_MAC_NONE) {
+ netif_notice(tp, probe, dev,
+ "unknown MAC, using family default\n");
+ tp->mac_version = default_version;
+ }
}
static void rtl8169_print_mac_version(struct rtl8169_private *tp)
@@ -1690,14 +1770,14 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
case PHY_BJMPN:
if (regno > index) {
netif_err(tp, probe, tp->dev,
- "Out of range of firmware\n");
+ "Out of range of firmware\n");
return;
}
break;
case PHY_READCOUNT_EQ_SKIP:
if (index + 2 >= fw_size) {
netif_err(tp, probe, tp->dev,
- "Out of range of firmware\n");
+ "Out of range of firmware\n");
return;
}
break;
@@ -1706,7 +1786,7 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
case PHY_SKIPN:
if (index + 1 + regno >= fw_size) {
netif_err(tp, probe, tp->dev,
- "Out of range of firmware\n");
+ "Out of range of firmware\n");
return;
}
break;
@@ -1762,10 +1842,7 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
index++;
break;
case PHY_READCOUNT_EQ_SKIP:
- if (count == data)
- index += 2;
- else
- index += 1;
+ index += (count == data) ? 2 : 1;
break;
case PHY_COMP_EQ_SKIPN:
if (predata == data)
@@ -2176,7 +2253,7 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp)
/*
* Tx Error Issue
- * enhance line driver power
+ * Enhance line driver power
*/
{ 0x1f, 0x0002 },
{ 0x06, 0x5561 },
@@ -2288,7 +2365,7 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp)
/*
* Tx Error Issue
- * enhance line driver power
+ * Enhance line driver power
*/
{ 0x1f, 0x0002 },
{ 0x06, 0x5561 },
@@ -2444,6 +2521,79 @@ static void rtl8168d_4_hw_phy_config(struct rtl8169_private *tp)
rtl_patchphy(tp, 0x0d, 1 << 5);
}
+static void rtl8168e_hw_phy_config(struct rtl8169_private *tp)
+{
+ static const struct phy_reg phy_reg_init[] = {
+ /* Enable Delay cap */
+ { 0x1f, 0x0005 },
+ { 0x05, 0x8b80 },
+ { 0x06, 0xc896 },
+ { 0x1f, 0x0000 },
+
+ /* Channel estimation fine tune */
+ { 0x1f, 0x0001 },
+ { 0x0b, 0x6c20 },
+ { 0x07, 0x2872 },
+ { 0x1c, 0xefff },
+ { 0x1f, 0x0003 },
+ { 0x14, 0x6420 },
+ { 0x1f, 0x0000 },
+
+ /* Update PFM & 10M TX idle timer */
+ { 0x1f, 0x0007 },
+ { 0x1e, 0x002f },
+ { 0x15, 0x1919 },
+ { 0x1f, 0x0000 },
+
+ { 0x1f, 0x0007 },
+ { 0x1e, 0x00ac },
+ { 0x18, 0x0006 },
+ { 0x1f, 0x0000 }
+ };
+
+ rtl_apply_firmware(tp);
+
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+
+ /* DCO enable for 10M IDLE Power */
+ rtl_writephy(tp, 0x1f, 0x0007);
+ rtl_writephy(tp, 0x1e, 0x0023);
+ rtl_w1w0_phy(tp, 0x17, 0x0006, 0x0000);
+ rtl_writephy(tp, 0x1f, 0x0000);
+
+ /* For impedance matching */
+ rtl_writephy(tp, 0x1f, 0x0002);
+ rtl_w1w0_phy(tp, 0x08, 0x8000, 0x7f00);
+ rtl_writephy(tp, 0x1f, 0x0000);
+
+ /* PHY auto speed down */
+ rtl_writephy(tp, 0x1f, 0x0007);
+ rtl_writephy(tp, 0x1e, 0x002d);
+ rtl_w1w0_phy(tp, 0x18, 0x0050, 0x0000);
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_w1w0_phy(tp, 0x14, 0x8000, 0x0000);
+
+ rtl_writephy(tp, 0x1f, 0x0005);
+ rtl_writephy(tp, 0x05, 0x8b86);
+ rtl_w1w0_phy(tp, 0x06, 0x0001, 0x0000);
+ rtl_writephy(tp, 0x1f, 0x0000);
+
+ rtl_writephy(tp, 0x1f, 0x0005);
+ rtl_writephy(tp, 0x05, 0x8b85);
+ rtl_w1w0_phy(tp, 0x06, 0x0000, 0x2000);
+ rtl_writephy(tp, 0x1f, 0x0007);
+ rtl_writephy(tp, 0x1e, 0x0020);
+ rtl_w1w0_phy(tp, 0x15, 0x0000, 0x1100);
+ rtl_writephy(tp, 0x1f, 0x0006);
+ rtl_writephy(tp, 0x00, 0x5a00);
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, 0x0d, 0x0007);
+ rtl_writephy(tp, 0x0e, 0x003c);
+ rtl_writephy(tp, 0x0d, 0x4007);
+ rtl_writephy(tp, 0x0e, 0x0000);
+ rtl_writephy(tp, 0x0d, 0x0000);
+}
+
static void rtl8102e_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
@@ -2558,6 +2708,13 @@ static void rtl_hw_phy_config(struct net_device *dev)
case RTL_GIGA_MAC_VER_30:
rtl8105e_hw_phy_config(tp);
break;
+ case RTL_GIGA_MAC_VER_31:
+ /* None. */
+ break;
+ case RTL_GIGA_MAC_VER_32:
+ case RTL_GIGA_MAC_VER_33:
+ rtl8168e_hw_phy_config(tp);
+ break;
default:
break;
@@ -2574,9 +2731,6 @@ static void rtl8169_phy_timer(unsigned long __opaque)
assert(tp->mac_version > RTL_GIGA_MAC_VER_01);
- if (!(tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL))
- return;
-
spin_lock_irq(&tp->lock);
if (tp->phy_reset_pending(tp)) {
@@ -2601,28 +2755,6 @@ out_unlock:
spin_unlock_irq(&tp->lock);
}
-static inline void rtl8169_delete_timer(struct net_device *dev)
-{
- struct rtl8169_private *tp = netdev_priv(dev);
- struct timer_list *timer = &tp->timer;
-
- if (tp->mac_version <= RTL_GIGA_MAC_VER_01)
- return;
-
- del_timer_sync(timer);
-}
-
-static inline void rtl8169_request_timer(struct net_device *dev)
-{
- struct rtl8169_private *tp = netdev_priv(dev);
- struct timer_list *timer = &tp->timer;
-
- if (tp->mac_version <= RTL_GIGA_MAC_VER_01)
- return;
-
- mod_timer(timer, jiffies + RTL8169_PHY_TIMEOUT);
-}
-
#ifdef CONFIG_NET_POLL_CONTROLLER
/*
* Polling 'interrupt' - used by things like netconsole to send skbs
@@ -2690,11 +2822,11 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
rtl8169_phy_reset(dev, tp);
rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL,
- ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
- (tp->mii.supports_gmii ?
- ADVERTISED_1000baseT_Half |
- ADVERTISED_1000baseT_Full : 0));
+ ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
+ (tp->mii.supports_gmii ?
+ ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full : 0));
if (RTL_R8(PHYstatus) & TBI_Enable)
netif_info(tp, link, dev, "TBI auto-negotiating\n");
@@ -2747,7 +2879,8 @@ static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return netif_running(dev) ? tp->do_ioctl(tp, data, cmd) : -ENODEV;
}
-static int rtl_xmii_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd)
+static int rtl_xmii_ioctl(struct rtl8169_private *tp,
+ struct mii_ioctl_data *data, int cmd)
{
switch (cmd) {
case SIOCGMIIPHY:
@@ -2847,6 +2980,8 @@ static const struct net_device_ops rtl8169_netdev_ops = {
.ndo_tx_timeout = rtl8169_tx_timeout,
.ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = rtl8169_change_mtu,
+ .ndo_fix_features = rtl8169_fix_features,
+ .ndo_set_features = rtl8169_set_features,
.ndo_set_mac_address = rtl_set_mac_address,
.ndo_do_ioctl = rtl8169_ioctl,
.ndo_set_multicast_list = rtl_set_rx_mode,
@@ -2866,6 +3001,7 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp)
ops->read = r8168dp_1_mdio_read;
break;
case RTL_GIGA_MAC_VER_28:
+ case RTL_GIGA_MAC_VER_31:
ops->write = r8168dp_2_mdio_write;
ops->read = r8168dp_2_mdio_read;
break;
@@ -2907,33 +3043,82 @@ static void r810x_pll_power_up(struct rtl8169_private *tp)
static void r8168_phy_power_up(struct rtl8169_private *tp)
{
rtl_writephy(tp, 0x1f, 0x0000);
- rtl_writephy(tp, 0x0e, 0x0000);
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_11:
+ case RTL_GIGA_MAC_VER_12:
+ case RTL_GIGA_MAC_VER_17:
+ case RTL_GIGA_MAC_VER_18:
+ case RTL_GIGA_MAC_VER_19:
+ case RTL_GIGA_MAC_VER_20:
+ case RTL_GIGA_MAC_VER_21:
+ case RTL_GIGA_MAC_VER_22:
+ case RTL_GIGA_MAC_VER_23:
+ case RTL_GIGA_MAC_VER_24:
+ case RTL_GIGA_MAC_VER_25:
+ case RTL_GIGA_MAC_VER_26:
+ case RTL_GIGA_MAC_VER_27:
+ case RTL_GIGA_MAC_VER_28:
+ case RTL_GIGA_MAC_VER_31:
+ rtl_writephy(tp, 0x0e, 0x0000);
+ break;
+ default:
+ break;
+ }
rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE);
}
static void r8168_phy_power_down(struct rtl8169_private *tp)
{
rtl_writephy(tp, 0x1f, 0x0000);
- rtl_writephy(tp, 0x0e, 0x0200);
- rtl_writephy(tp, MII_BMCR, BMCR_PDOWN);
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_32:
+ case RTL_GIGA_MAC_VER_33:
+ rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE | BMCR_PDOWN);
+ break;
+
+ case RTL_GIGA_MAC_VER_11:
+ case RTL_GIGA_MAC_VER_12:
+ case RTL_GIGA_MAC_VER_17:
+ case RTL_GIGA_MAC_VER_18:
+ case RTL_GIGA_MAC_VER_19:
+ case RTL_GIGA_MAC_VER_20:
+ case RTL_GIGA_MAC_VER_21:
+ case RTL_GIGA_MAC_VER_22:
+ case RTL_GIGA_MAC_VER_23:
+ case RTL_GIGA_MAC_VER_24:
+ case RTL_GIGA_MAC_VER_25:
+ case RTL_GIGA_MAC_VER_26:
+ case RTL_GIGA_MAC_VER_27:
+ case RTL_GIGA_MAC_VER_28:
+ case RTL_GIGA_MAC_VER_31:
+ rtl_writephy(tp, 0x0e, 0x0200);
+ default:
+ rtl_writephy(tp, MII_BMCR, BMCR_PDOWN);
+ break;
+ }
}
static void r8168_pll_power_down(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
- if (((tp->mac_version == RTL_GIGA_MAC_VER_27) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_28)) &&
- (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) {
+ if ((tp->mac_version == RTL_GIGA_MAC_VER_27 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_28 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_31) &&
+ r8168dp_check_dash(tp)) {
return;
}
- if (((tp->mac_version == RTL_GIGA_MAC_VER_23) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_24)) &&
+ if ((tp->mac_version == RTL_GIGA_MAC_VER_23 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_24) &&
(RTL_R16(CPlusCmd) & ASF)) {
return;
}
+ if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_33)
+ rtl_ephy_write(ioaddr, 0x19, 0xff64);
+
if (__rtl8169_get_wol(tp) & WAKE_ANY) {
rtl_writephy(tp, 0x1f, 0x0000);
rtl_writephy(tp, MII_BMCR, 0x0000);
@@ -2950,6 +3135,9 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_26:
case RTL_GIGA_MAC_VER_27:
case RTL_GIGA_MAC_VER_28:
+ case RTL_GIGA_MAC_VER_31:
+ case RTL_GIGA_MAC_VER_32:
+ case RTL_GIGA_MAC_VER_33:
RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80);
break;
}
@@ -2959,9 +3147,10 @@ static void r8168_pll_power_up(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
- if (((tp->mac_version == RTL_GIGA_MAC_VER_27) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_28)) &&
- (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) {
+ if ((tp->mac_version == RTL_GIGA_MAC_VER_27 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_28 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_31) &&
+ r8168dp_check_dash(tp)) {
return;
}
@@ -2970,6 +3159,9 @@ static void r8168_pll_power_up(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_26:
case RTL_GIGA_MAC_VER_27:
case RTL_GIGA_MAC_VER_28:
+ case RTL_GIGA_MAC_VER_31:
+ case RTL_GIGA_MAC_VER_32:
+ case RTL_GIGA_MAC_VER_33:
RTL_W8(PMCH, RTL_R8(PMCH) | 0x80);
break;
}
@@ -3024,6 +3216,9 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_26:
case RTL_GIGA_MAC_VER_27:
case RTL_GIGA_MAC_VER_28:
+ case RTL_GIGA_MAC_VER_31:
+ case RTL_GIGA_MAC_VER_32:
+ case RTL_GIGA_MAC_VER_33:
ops->down = r8168_pll_power_down;
ops->up = r8168_pll_power_up;
break;
@@ -3035,6 +3230,22 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)
}
}
+static void rtl_hw_reset(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+ int i;
+
+ /* Soft reset the chip. */
+ RTL_W8(ChipCmd, CmdReset);
+
+ /* Check that the chip has finished the reset. */
+ for (i = 0; i < 100; i++) {
+ if ((RTL_R8(ChipCmd) & CmdReset) == 0)
+ break;
+ msleep_interruptible(1);
+ }
+}
+
static int __devinit
rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@@ -3044,7 +3255,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
struct mii_if_info *mii;
struct net_device *dev;
void __iomem *ioaddr;
- unsigned int i;
+ int chipset, i;
int rc;
if (netif_msg_drv(&debug)) {
@@ -3134,6 +3345,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rc = -EIO;
goto err_out_free_res_3;
}
+ tp->mmio_addr = ioaddr;
tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
if (!tp->pcie_cap)
@@ -3141,22 +3353,14 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
RTL_W16(IntrMask, 0x0000);
- /* Soft reset the chip. */
- RTL_W8(ChipCmd, CmdReset);
-
- /* Check that the chip has finished the reset. */
- for (i = 0; i < 100; i++) {
- if ((RTL_R8(ChipCmd) & CmdReset) == 0)
- break;
- msleep_interruptible(1);
- }
+ rtl_hw_reset(tp);
RTL_W16(IntrStatus, 0xffff);
pci_set_master(pdev);
/* Identify chip attached to board */
- rtl8169_get_mac_version(tp, ioaddr);
+ rtl8169_get_mac_version(tp, dev, cfg->default_ver);
/*
* Pretend we are using VLANs; This bypasses a nasty bug where
@@ -3168,25 +3372,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rtl_init_mdio_ops(tp);
rtl_init_pll_power_ops(tp);
- /* Use appropriate default if unknown */
- if (tp->mac_version == RTL_GIGA_MAC_NONE) {
- netif_notice(tp, probe, dev,
- "unknown MAC, using family default\n");
- tp->mac_version = cfg->default_ver;
- }
-
rtl8169_print_mac_version(tp);
- for (i = 0; i < ARRAY_SIZE(rtl_chip_info); i++) {
- if (tp->mac_version == rtl_chip_info[i].mac_version)
- break;
- }
- if (i == ARRAY_SIZE(rtl_chip_info)) {
- dev_err(&pdev->dev,
- "driver bug, MAC version not found in rtl_chip_info\n");
- goto err_out_msi_4;
- }
- tp->chipset = i;
+ chipset = tp->mac_version;
+ tp->txd_version = rtl_chip_infos[chipset].txd_version;
RTL_W8(Cfg9346, Cfg9346_Unlock);
RTL_W8(Config1, RTL_R8(Config1) | PMEnable);
@@ -3206,8 +3395,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->phy_reset_pending = rtl8169_tbi_reset_pending;
tp->link_ok = rtl8169_tbi_link_ok;
tp->do_ioctl = rtl_tbi_ioctl;
-
- tp->phy_1000_ctrl_reg = ADVERTISE_1000FULL; /* Implied by TBI */
} else {
tp->set_speed = rtl8169_set_speed_xmii;
tp->get_settings = rtl8169_gset_xmii;
@@ -3219,8 +3406,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
spin_lock_init(&tp->lock);
- tp->mmio_addr = ioaddr;
-
/* Get MAC address */
for (i = 0; i < MAC_ADDR_LEN; i++)
dev->dev_addr[i] = RTL_R8(MAC0 + i);
@@ -3233,7 +3418,19 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
- dev->features |= NETIF_F_HW_VLAN_TX_RX | NETIF_F_GRO;
+ /* don't enable SG, IP_CSUM and TSO by default - it might not work
+ * properly for all devices */
+ dev->features |= NETIF_F_RXCSUM |
+ NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+
+ dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
+ NETIF_F_RXCSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
+ NETIF_F_HIGHDMA;
+
+ if (tp->mac_version == RTL_GIGA_MAC_VER_05)
+ /* 8110SCd requires hardware Rx VLAN - disallow toggling */
+ dev->hw_features &= ~NETIF_F_HW_VLAN_RX;
tp->intr_mask = 0xffff;
tp->hw_start = cfg->hw_start;
@@ -3253,12 +3450,12 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, dev);
netif_info(tp, probe, dev, "%s at 0x%lx, %pM, XID %08x IRQ %d\n",
- rtl_chip_info[tp->chipset].name,
- dev->base_addr, dev->dev_addr,
+ rtl_chip_infos[chipset].name, dev->base_addr, dev->dev_addr,
(u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq);
- if ((tp->mac_version == RTL_GIGA_MAC_VER_27) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_28)) {
+ if (tp->mac_version == RTL_GIGA_MAC_VER_27 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_28 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_31) {
rtl8168_driver_start(tp);
}
@@ -3290,8 +3487,9 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
- if ((tp->mac_version == RTL_GIGA_MAC_VER_27) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_28)) {
+ if (tp->mac_version == RTL_GIGA_MAC_VER_27 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_28 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_31) {
rtl8168_driver_stop(tp);
}
@@ -3314,33 +3512,23 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
static void rtl_request_firmware(struct rtl8169_private *tp)
{
- int i;
-
/* Return early if the firmware is already loaded / cached. */
- if (!IS_ERR(tp->fw))
- goto out;
-
- for (i = 0; i < ARRAY_SIZE(rtl_firmware_infos); i++) {
- const struct rtl_firmware_info *info = rtl_firmware_infos + i;
+ if (IS_ERR(tp->fw)) {
+ const char *name;
- if (info->mac_version == tp->mac_version) {
- const char *name = info->fw_name;
+ name = rtl_lookup_firmware_name(tp);
+ if (name) {
int rc;
rc = request_firmware(&tp->fw, name, &tp->pci_dev->dev);
- if (rc < 0) {
- netif_warn(tp, ifup, tp->dev, "unable to load "
- "firmware patch %s (%d)\n", name, rc);
- goto out_disable_request_firmware;
- }
- goto out;
+ if (rc >= 0)
+ return;
+
+ netif_warn(tp, ifup, tp->dev, "unable to load "
+ "firmware patch %s (%d)\n", name, rc);
}
+ tp->fw = NULL;
}
-
-out_disable_request_firmware:
- tp->fw = NULL;
-out:
- return;
}
static int rtl8169_open(struct net_device *dev)
@@ -3386,14 +3574,12 @@ static int rtl8169_open(struct net_device *dev)
rtl8169_init_phy(dev, tp);
- rtl8169_vlan_mode(dev);
+ rtl8169_set_features(dev, dev->features);
rtl_pll_power_up(tp);
rtl_hw_start(dev);
- rtl8169_request_timer(dev);
-
tp->saved_wolopts = 0;
pm_runtime_put_noidle(&pdev->dev);
@@ -3425,7 +3611,8 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
rtl8169_irq_mask_and_ack(ioaddr);
if (tp->mac_version == RTL_GIGA_MAC_VER_27 ||
- tp->mac_version == RTL_GIGA_MAC_VER_28) {
+ tp->mac_version == RTL_GIGA_MAC_VER_28 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_31) {
while (RTL_R8(TxPoll) & NPQ)
udelay(20);
@@ -3443,7 +3630,7 @@ static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp)
void __iomem *ioaddr = tp->mmio_addr;
u32 cfg = rtl8169_rx_config;
- cfg |= (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
+ cfg |= (RTL_R32(RxConfig) & RTL_RX_CONFIG_MASK);
RTL_W32(RxConfig, cfg);
/* Set DMA burst size and Interframe Gap Time */
@@ -3454,25 +3641,14 @@ static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp)
static void rtl_hw_start(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
- void __iomem *ioaddr = tp->mmio_addr;
- unsigned int i;
- /* Soft reset the chip. */
- RTL_W8(ChipCmd, CmdReset);
-
- /* Check that the chip has finished the reset. */
- for (i = 0; i < 100; i++) {
- if ((RTL_R8(ChipCmd) & CmdReset) == 0)
- break;
- msleep_interruptible(1);
- }
+ rtl_hw_reset(tp);
tp->hw_start(dev);
netif_start_queue(dev);
}
-
static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp,
void __iomem *ioaddr)
{
@@ -3538,26 +3714,26 @@ static void rtl_hw_start_8169(struct net_device *dev)
}
RTL_W8(Cfg9346, Cfg9346_Unlock);
- if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_04))
+ if (tp->mac_version == RTL_GIGA_MAC_VER_01 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_02 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_03 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_04)
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
RTL_W8(EarlyTxThres, NoEarlyTx);
rtl_set_rx_max_size(ioaddr, rx_buf_sz);
- if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_04))
+ if (tp->mac_version == RTL_GIGA_MAC_VER_01 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_02 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_03 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_04)
rtl_set_rx_tx_config_registers(tp);
tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
- if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
+ if (tp->mac_version == RTL_GIGA_MAC_VER_02 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_03) {
dprintk("Set MAC Reg C+CR Offset 0xE0. "
"Bit-3 and bit-14 MUST be 1\n");
tp->cp_cmd |= (1 << 14);
@@ -3575,10 +3751,10 @@ static void rtl_hw_start_8169(struct net_device *dev)
rtl_set_rx_tx_desc_registers(tp, ioaddr);
- if ((tp->mac_version != RTL_GIGA_MAC_VER_01) &&
- (tp->mac_version != RTL_GIGA_MAC_VER_02) &&
- (tp->mac_version != RTL_GIGA_MAC_VER_03) &&
- (tp->mac_version != RTL_GIGA_MAC_VER_04)) {
+ if (tp->mac_version != RTL_GIGA_MAC_VER_01 &&
+ tp->mac_version != RTL_GIGA_MAC_VER_02 &&
+ tp->mac_version != RTL_GIGA_MAC_VER_03 &&
+ tp->mac_version != RTL_GIGA_MAC_VER_04) {
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
rtl_set_rx_tx_config_registers(tp);
}
@@ -3822,6 +3998,17 @@ static void rtl_hw_start_8168d(void __iomem *ioaddr, struct pci_dev *pdev)
RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
}
+static void rtl_hw_start_8168dp(void __iomem *ioaddr, struct pci_dev *pdev)
+{
+ rtl_csi_access_enable_1(ioaddr);
+
+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+
+ RTL_W8(MaxTxPacketSize, TxPacketMax);
+
+ rtl_disable_clock_request(pdev);
+}
+
static void rtl_hw_start_8168d_4(void __iomem *ioaddr, struct pci_dev *pdev)
{
static const struct ephy_info e_info_8168d_4[] = {
@@ -3848,6 +4035,41 @@ static void rtl_hw_start_8168d_4(void __iomem *ioaddr, struct pci_dev *pdev)
rtl_enable_clock_request(pdev);
}
+static void rtl_hw_start_8168e(void __iomem *ioaddr, struct pci_dev *pdev)
+{
+ static const struct ephy_info e_info_8168e[] = {
+ { 0x00, 0x0200, 0x0100 },
+ { 0x00, 0x0000, 0x0004 },
+ { 0x06, 0x0002, 0x0001 },
+ { 0x06, 0x0000, 0x0030 },
+ { 0x07, 0x0000, 0x2000 },
+ { 0x00, 0x0000, 0x0020 },
+ { 0x03, 0x5800, 0x2000 },
+ { 0x03, 0x0000, 0x0001 },
+ { 0x01, 0x0800, 0x1000 },
+ { 0x07, 0x0000, 0x4000 },
+ { 0x1e, 0x0000, 0x2000 },
+ { 0x19, 0xffff, 0xfe6c },
+ { 0x0a, 0x0000, 0x0040 }
+ };
+
+ rtl_csi_access_enable_2(ioaddr);
+
+ rtl_ephy_init(ioaddr, e_info_8168e, ARRAY_SIZE(e_info_8168e));
+
+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+
+ RTL_W8(MaxTxPacketSize, TxPacketMax);
+
+ rtl_disable_clock_request(pdev);
+
+ /* Reset tx FIFO pointer */
+ RTL_W32(MISC, RTL_R32(MISC) | TXPLA_RST);
+ RTL_W32(MISC, RTL_R32(MISC) & ~TXPLA_RST);
+
+ RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en);
+}
+
static void rtl_hw_start_8168(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@@ -3885,55 +4107,64 @@ static void rtl_hw_start_8168(struct net_device *dev)
switch (tp->mac_version) {
case RTL_GIGA_MAC_VER_11:
rtl_hw_start_8168bb(ioaddr, pdev);
- break;
+ break;
case RTL_GIGA_MAC_VER_12:
case RTL_GIGA_MAC_VER_17:
rtl_hw_start_8168bef(ioaddr, pdev);
- break;
+ break;
case RTL_GIGA_MAC_VER_18:
rtl_hw_start_8168cp_1(ioaddr, pdev);
- break;
+ break;
case RTL_GIGA_MAC_VER_19:
rtl_hw_start_8168c_1(ioaddr, pdev);
- break;
+ break;
case RTL_GIGA_MAC_VER_20:
rtl_hw_start_8168c_2(ioaddr, pdev);
- break;
+ break;
case RTL_GIGA_MAC_VER_21:
rtl_hw_start_8168c_3(ioaddr, pdev);
- break;
+ break;
case RTL_GIGA_MAC_VER_22:
rtl_hw_start_8168c_4(ioaddr, pdev);
- break;
+ break;
case RTL_GIGA_MAC_VER_23:
rtl_hw_start_8168cp_2(ioaddr, pdev);
- break;
+ break;
case RTL_GIGA_MAC_VER_24:
rtl_hw_start_8168cp_3(ioaddr, pdev);
- break;
+ break;
case RTL_GIGA_MAC_VER_25:
case RTL_GIGA_MAC_VER_26:
case RTL_GIGA_MAC_VER_27:
rtl_hw_start_8168d(ioaddr, pdev);
- break;
+ break;
case RTL_GIGA_MAC_VER_28:
rtl_hw_start_8168d_4(ioaddr, pdev);
- break;
+ break;
+
+ case RTL_GIGA_MAC_VER_31:
+ rtl_hw_start_8168dp(ioaddr, pdev);
+ break;
+
+ case RTL_GIGA_MAC_VER_32:
+ case RTL_GIGA_MAC_VER_33:
+ rtl_hw_start_8168e(ioaddr, pdev);
+ break;
default:
printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n",
dev->name, tp->mac_version);
- break;
+ break;
}
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
@@ -4017,10 +4248,10 @@ static void rtl_hw_start_8105e_1(void __iomem *ioaddr, struct pci_dev *pdev)
{ 0x0a, 0, 0x0020 }
};
- /* Force LAN exit from ASPM if Rx/Tx are not idel */
+ /* Force LAN exit from ASPM if Rx/Tx are not idle */
RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800);
- /* disable Early Tally Counter */
+ /* Disable Early Tally Counter */
RTL_W32(FuncEvent, RTL_R32(FuncEvent) & ~0x010000);
RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET);
@@ -4041,8 +4272,8 @@ static void rtl_hw_start_8101(struct net_device *dev)
void __iomem *ioaddr = tp->mmio_addr;
struct pci_dev *pdev = tp->pci_dev;
- if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
+ if (tp->mac_version == RTL_GIGA_MAC_VER_13 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_16) {
int cap = tp->pcie_cap;
if (cap) {
@@ -4105,6 +4336,8 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
return -EINVAL;
dev->mtu = new_mtu;
+ netdev_update_features(dev);
+
return 0;
}
@@ -4342,6 +4575,7 @@ static void rtl8169_reset_task(struct work_struct *work)
struct rtl8169_private *tp =
container_of(work, struct rtl8169_private, task.work);
struct net_device *dev = tp->dev;
+ int i;
rtnl_lock();
@@ -4350,19 +4584,15 @@ static void rtl8169_reset_task(struct work_struct *work)
rtl8169_wait_for_quiescence(dev);
- rtl8169_rx_interrupt(dev, tp, tp->mmio_addr, ~(u32)0);
+ for (i = 0; i < NUM_RX_DESC; i++)
+ rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz);
+
rtl8169_tx_clear(tp);
- if (tp->dirty_rx == tp->cur_rx) {
- rtl8169_init_ring_indexes(tp);
- rtl_hw_start(dev);
- netif_wake_queue(dev);
- rtl8169_check_link_status(dev, tp, tp->mmio_addr);
- } else {
- if (net_ratelimit())
- netif_emerg(tp, intr, dev, "Rx buffers shortage\n");
- rtl8169_schedule_work(dev, rtl8169_reset_task);
- }
+ rtl8169_init_ring_indexes(tp);
+ rtl_hw_start(dev);
+ netif_wake_queue(dev);
+ rtl8169_check_link_status(dev, tp, tp->mmio_addr);
out_unlock:
rtnl_unlock();
@@ -4379,7 +4609,7 @@ static void rtl8169_tx_timeout(struct net_device *dev)
}
static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
- u32 opts1)
+ u32 *opts)
{
struct skb_shared_info *info = skb_shinfo(skb);
unsigned int cur_frag, entry;
@@ -4406,10 +4636,12 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
goto err_out;
}
- /* anti gcc 2.95.3 bugware (sic) */
- status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
+ /* Anti gcc 2.95.3 bugware (sic) */
+ status = opts[0] | len |
+ (RingEnd * !((entry + 1) % NUM_TX_DESC));
txd->opts1 = cpu_to_le32(status);
+ txd->opts2 = cpu_to_le32(opts[1]);
txd->addr = cpu_to_le64(mapping);
tp->tx_skb[entry].len = len;
@@ -4427,24 +4659,26 @@ err_out:
return -EIO;
}
-static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev)
+static inline void rtl8169_tso_csum(struct rtl8169_private *tp,
+ struct sk_buff *skb, u32 *opts)
{
- if (dev->features & NETIF_F_TSO) {
- u32 mss = skb_shinfo(skb)->gso_size;
+ const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version;
+ u32 mss = skb_shinfo(skb)->gso_size;
+ int offset = info->opts_offset;
- if (mss)
- return LargeSend | ((mss & MSSMask) << MSSShift);
- }
- if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ if (mss) {
+ opts[0] |= TD_LSO;
+ opts[offset] |= min(mss, TD_MSS_MAX) << info->mss_shift;
+ } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
const struct iphdr *ip = ip_hdr(skb);
if (ip->protocol == IPPROTO_TCP)
- return IPCS | TCPCS;
+ opts[offset] |= info->checksum.tcp;
else if (ip->protocol == IPPROTO_UDP)
- return IPCS | UDPCS;
- WARN_ON(1); /* we need a WARN() */
+ opts[offset] |= info->checksum.udp;
+ else
+ WARN_ON_ONCE(1);
}
- return 0;
}
static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
@@ -4457,7 +4691,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
struct device *d = &tp->pci_dev->dev;
dma_addr_t mapping;
u32 status, len;
- u32 opts1;
+ u32 opts[2];
int frags;
if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
@@ -4478,31 +4712,35 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
tp->tx_skb[entry].len = len;
txd->addr = cpu_to_le64(mapping);
- txd->opts2 = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb));
- opts1 = DescOwn | rtl8169_tso_csum(skb, dev);
+ opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb));
+ opts[0] = DescOwn;
- frags = rtl8169_xmit_frags(tp, skb, opts1);
+ rtl8169_tso_csum(tp, skb, opts);
+
+ frags = rtl8169_xmit_frags(tp, skb, opts);
if (frags < 0)
goto err_dma_1;
else if (frags)
- opts1 |= FirstFrag;
+ opts[0] |= FirstFrag;
else {
- opts1 |= FirstFrag | LastFrag;
+ opts[0] |= FirstFrag | LastFrag;
tp->tx_skb[entry].skb = skb;
}
+ txd->opts2 = cpu_to_le32(opts[1]);
+
wmb();
- /* anti gcc 2.95.3 bugware (sic) */
- status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
+ /* Anti gcc 2.95.3 bugware (sic) */
+ status = opts[0] | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
txd->opts1 = cpu_to_le32(status);
tp->cur_tx += frags + 1;
wmb();
- RTL_W8(TxPoll, NPQ); /* set polling bit */
+ RTL_W8(TxPoll, NPQ);
if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) {
netif_stop_queue(dev);
@@ -4659,20 +4897,12 @@ static struct sk_buff *rtl8169_try_rx_copy(void *data,
return skb;
}
-/*
- * Warning : rtl8169_rx_interrupt() might be called :
- * 1) from NAPI (softirq) context
- * (polling = 1 : we should call netif_receive_skb())
- * 2) from process context (rtl8169_reset_task())
- * (polling = 0 : we must call netif_rx() instead)
- */
static int rtl8169_rx_interrupt(struct net_device *dev,
struct rtl8169_private *tp,
void __iomem *ioaddr, u32 budget)
{
unsigned int cur_rx, rx_left;
unsigned int count;
- int polling = (budget != ~(u32)0) ? 1 : 0;
cur_rx = tp->cur_rx;
rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
@@ -4732,10 +4962,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
rtl8169_rx_vlan_tag(desc, skb);
- if (likely(polling))
- napi_gro_receive(&tp->napi, skb);
- else
- netif_rx(skb);
+ napi_gro_receive(&tp->napi, skb);
dev->stats.rx_bytes += pkt_size;
dev->stats.rx_packets++;
@@ -4798,6 +5025,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
case RTL_GIGA_MAC_VER_24:
case RTL_GIGA_MAC_VER_27:
case RTL_GIGA_MAC_VER_28:
+ case RTL_GIGA_MAC_VER_31:
/* Experimental science. Pktgen proof. */
case RTL_GIGA_MAC_VER_12:
case RTL_GIGA_MAC_VER_25:
@@ -4890,7 +5118,7 @@ static void rtl8169_down(struct net_device *dev)
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
- rtl8169_delete_timer(dev);
+ del_timer_sync(&tp->timer);
netif_stop_queue(dev);
@@ -4927,7 +5155,7 @@ static int rtl8169_close(struct net_device *dev)
pm_runtime_get_sync(&pdev->dev);
- /* update counters before going down */
+ /* Update counters before going down */
rtl8169_update_counters(dev);
rtl8169_down(dev);
@@ -4982,7 +5210,7 @@ static void rtl_set_rx_mode(struct net_device *dev)
spin_lock_irqsave(&tp->lock, flags);
tmp = rtl8169_rx_config | rx_mode |
- (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
+ (RTL_R32(RxConfig) & RTL_RX_CONFIG_MASK);
if (tp->mac_version > RTL_GIGA_MAC_VER_06) {
u32 data = mc_filter[0];
@@ -5120,15 +5348,15 @@ static int rtl8169_runtime_idle(struct device *device)
}
static const struct dev_pm_ops rtl8169_pm_ops = {
- .suspend = rtl8169_suspend,
- .resume = rtl8169_resume,
- .freeze = rtl8169_suspend,
- .thaw = rtl8169_resume,
- .poweroff = rtl8169_suspend,
- .restore = rtl8169_resume,
- .runtime_suspend = rtl8169_runtime_suspend,
- .runtime_resume = rtl8169_runtime_resume,
- .runtime_idle = rtl8169_runtime_idle,
+ .suspend = rtl8169_suspend,
+ .resume = rtl8169_resume,
+ .freeze = rtl8169_suspend,
+ .thaw = rtl8169_resume,
+ .poweroff = rtl8169_suspend,
+ .restore = rtl8169_resume,
+ .runtime_suspend = rtl8169_runtime_suspend,
+ .runtime_resume = rtl8169_runtime_resume,
+ .runtime_idle = rtl8169_runtime_idle,
};
#define RTL8169_PM_OPS (&rtl8169_pm_ops)
@@ -5147,7 +5375,7 @@ static void rtl_shutdown(struct pci_dev *pdev)
rtl8169_net_suspend(dev);
- /* restore original MAC address */
+ /* Restore original MAC address */
rtl_rar_set(tp, dev->perm_addr);
spin_lock_irq(&tp->lock);
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 337bdcd5abc..89cfee7e864 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -2244,13 +2244,12 @@ static int verify_xena_quiescence(struct s2io_nic *sp)
static void fix_mac_address(struct s2io_nic *sp)
{
struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u64 val64;
int i = 0;
while (fix_mac[i] != END_SIGN) {
writeq(fix_mac[i++], &bar0->gpio_control);
udelay(10);
- val64 = readq(&bar0->gpio_control);
+ (void) readq(&bar0->gpio_control);
}
}
@@ -2727,7 +2726,6 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
int j;
struct sk_buff *skb;
struct RxD_t *rxdp;
- struct buffAdd *ba;
struct RxD1 *rxdp1;
struct RxD3 *rxdp3;
struct mac_info *mac_control = &sp->mac_control;
@@ -2751,7 +2749,6 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
memset(rxdp, 0, sizeof(struct RxD1));
} else if (sp->rxd_mode == RXD_MODE_3B) {
rxdp3 = (struct RxD3 *)rxdp;
- ba = &mac_control->rings[ring_no].ba[blk][j];
pci_unmap_single(sp->pdev,
(dma_addr_t)rxdp3->Buffer0_ptr,
BUF0_LEN,
@@ -5383,7 +5380,7 @@ static int s2io_ethtool_sset(struct net_device *dev,
{
struct s2io_nic *sp = netdev_priv(dev);
if ((info->autoneg == AUTONEG_ENABLE) ||
- (info->speed != SPEED_10000) ||
+ (ethtool_cmd_speed(info) != SPEED_10000) ||
(info->duplex != DUPLEX_FULL))
return -EINVAL;
else {
@@ -5417,10 +5414,10 @@ static int s2io_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
info->transceiver = XCVR_EXTERNAL;
if (netif_carrier_ok(sp->dev)) {
- info->speed = 10000;
+ ethtool_cmd_speed_set(info, SPEED_10000);
info->duplex = DUPLEX_FULL;
} else {
- info->speed = -1;
+ ethtool_cmd_speed_set(info, -1);
info->duplex = -1;
}
@@ -5484,83 +5481,79 @@ static void s2io_ethtool_gregs(struct net_device *dev,
}
}
-/**
- * s2io_phy_id - timer function that alternates adapter LED.
- * @data : address of the private member of the device structure, which
- * is a pointer to the s2io_nic structure, provided as an u32.
- * Description: This is actually the timer function that alternates the
- * adapter LED bit of the adapter control bit to set/reset every time on
- * invocation. The timer is set for 1/2 a second, hence tha NIC blinks
- * once every second.
+/*
+ * s2io_set_led - control NIC led
*/
-static void s2io_phy_id(unsigned long data)
+static void s2io_set_led(struct s2io_nic *sp, bool on)
{
- struct s2io_nic *sp = (struct s2io_nic *)data;
struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u64 val64 = 0;
- u16 subid;
+ u16 subid = sp->pdev->subsystem_device;
+ u64 val64;
- subid = sp->pdev->subsystem_device;
if ((sp->device_type == XFRAME_II_DEVICE) ||
((subid & 0xFF) >= 0x07)) {
val64 = readq(&bar0->gpio_control);
- val64 ^= GPIO_CTRL_GPIO_0;
+ if (on)
+ val64 |= GPIO_CTRL_GPIO_0;
+ else
+ val64 &= ~GPIO_CTRL_GPIO_0;
+
writeq(val64, &bar0->gpio_control);
} else {
val64 = readq(&bar0->adapter_control);
- val64 ^= ADAPTER_LED_ON;
+ if (on)
+ val64 |= ADAPTER_LED_ON;
+ else
+ val64 &= ~ADAPTER_LED_ON;
+
writeq(val64, &bar0->adapter_control);
}
- mod_timer(&sp->id_timer, jiffies + HZ / 2);
}
/**
- * s2io_ethtool_idnic - To physically identify the nic on the system.
- * @sp : private member of the device structure, which is a pointer to the
- * s2io_nic structure.
- * @id : pointer to the structure with identification parameters given by
- * ethtool.
+ * s2io_ethtool_set_led - To physically identify the nic on the system.
+ * @dev : network device
+ * @state: led setting
+ *
* Description: Used to physically identify the NIC on the system.
* The Link LED will blink for a time specified by the user for
* identification.
* NOTE: The Link has to be Up to be able to blink the LED. Hence
* identification is possible only if it's link is up.
- * Return value:
- * int , returns 0 on success
*/
-static int s2io_ethtool_idnic(struct net_device *dev, u32 data)
+static int s2io_ethtool_set_led(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
- u64 val64 = 0, last_gpio_ctrl_val;
struct s2io_nic *sp = netdev_priv(dev);
struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u16 subid;
+ u16 subid = sp->pdev->subsystem_device;
- subid = sp->pdev->subsystem_device;
- last_gpio_ctrl_val = readq(&bar0->gpio_control);
if ((sp->device_type == XFRAME_I_DEVICE) && ((subid & 0xFF) < 0x07)) {
- val64 = readq(&bar0->adapter_control);
+ u64 val64 = readq(&bar0->adapter_control);
if (!(val64 & ADAPTER_CNTL_EN)) {
pr_err("Adapter Link down, cannot blink LED\n");
- return -EFAULT;
+ return -EAGAIN;
}
}
- if (sp->id_timer.function == NULL) {
- init_timer(&sp->id_timer);
- sp->id_timer.function = s2io_phy_id;
- sp->id_timer.data = (unsigned long)sp;
- }
- mod_timer(&sp->id_timer, jiffies);
- if (data)
- msleep_interruptible(data * HZ);
- else
- msleep_interruptible(MAX_FLICKER_TIME);
- del_timer_sync(&sp->id_timer);
- if (CARDS_WITH_FAULTY_LINK_INDICATORS(sp->device_type, subid)) {
- writeq(last_gpio_ctrl_val, &bar0->gpio_control);
- last_gpio_ctrl_val = readq(&bar0->gpio_control);
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ sp->adapt_ctrl_org = readq(&bar0->gpio_control);
+ return 1; /* cycle on/off once per second */
+
+ case ETHTOOL_ID_ON:
+ s2io_set_led(sp, true);
+ break;
+
+ case ETHTOOL_ID_OFF:
+ s2io_set_led(sp, false);
+ break;
+
+ case ETHTOOL_ID_INACTIVE:
+ if (CARDS_WITH_FAULTY_LINK_INDICATORS(sp->device_type, subid))
+ writeq(sp->adapt_ctrl_org, &bar0->gpio_control);
}
return 0;
@@ -6625,25 +6618,6 @@ static int s2io_ethtool_get_regs_len(struct net_device *dev)
}
-static u32 s2io_ethtool_get_rx_csum(struct net_device *dev)
-{
- struct s2io_nic *sp = netdev_priv(dev);
-
- return sp->rx_csum;
-}
-
-static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct s2io_nic *sp = netdev_priv(dev);
-
- if (data)
- sp->rx_csum = 1;
- else
- sp->rx_csum = 0;
-
- return 0;
-}
-
static int s2io_get_eeprom_len(struct net_device *dev)
{
return XENA_EEPROM_SPACE;
@@ -6695,61 +6669,27 @@ static void s2io_ethtool_get_strings(struct net_device *dev,
}
}
-static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
-{
- if (data)
- dev->features |= NETIF_F_IP_CSUM;
- else
- dev->features &= ~NETIF_F_IP_CSUM;
-
- return 0;
-}
-
-static u32 s2io_ethtool_op_get_tso(struct net_device *dev)
-{
- return (dev->features & NETIF_F_TSO) != 0;
-}
-
-static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data)
-{
- if (data)
- dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
- else
- dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-
- return 0;
-}
-
-static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
+static int s2io_set_features(struct net_device *dev, u32 features)
{
struct s2io_nic *sp = netdev_priv(dev);
- int rc = 0;
- int changed = 0;
-
- if (ethtool_invalid_flags(dev, data, ETH_FLAG_LRO))
- return -EINVAL;
-
- if (data & ETH_FLAG_LRO) {
- if (!(dev->features & NETIF_F_LRO)) {
- dev->features |= NETIF_F_LRO;
- changed = 1;
- }
- } else if (dev->features & NETIF_F_LRO) {
- dev->features &= ~NETIF_F_LRO;
- changed = 1;
- }
+ u32 changed = (features ^ dev->features) & NETIF_F_LRO;
if (changed && netif_running(dev)) {
+ int rc;
+
s2io_stop_all_tx_queue(sp);
s2io_card_down(sp);
+ dev->features = features;
rc = s2io_card_up(sp);
if (rc)
s2io_reset(sp);
else
s2io_start_all_tx_queue(sp);
+
+ return rc ? rc : 1;
}
- return rc;
+ return 0;
}
static const struct ethtool_ops netdev_ethtool_ops = {
@@ -6765,18 +6705,9 @@ static const struct ethtool_ops netdev_ethtool_ops = {
.get_ringparam = s2io_ethtool_gringparam,
.get_pauseparam = s2io_ethtool_getpause_data,
.set_pauseparam = s2io_ethtool_setpause_data,
- .get_rx_csum = s2io_ethtool_get_rx_csum,
- .set_rx_csum = s2io_ethtool_set_rx_csum,
- .set_tx_csum = s2io_ethtool_op_set_tx_csum,
- .set_flags = s2io_ethtool_set_flags,
- .get_flags = ethtool_op_get_flags,
- .set_sg = ethtool_op_set_sg,
- .get_tso = s2io_ethtool_op_get_tso,
- .set_tso = s2io_ethtool_op_set_tso,
- .set_ufo = ethtool_op_set_ufo,
.self_test = s2io_ethtool_test,
.get_strings = s2io_ethtool_get_strings,
- .phys_id = s2io_ethtool_idnic,
+ .set_phys_id = s2io_ethtool_set_led,
.get_ethtool_stats = s2io_get_ethtool_stats,
.get_sset_count = s2io_get_sset_count,
};
@@ -7545,7 +7476,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) &&
((!ring_data->lro) ||
(ring_data->lro && (!(rxdp->Control_1 & RXD_FRAME_IP_FRAG)))) &&
- (sp->rx_csum)) {
+ (dev->features & NETIF_F_RXCSUM)) {
l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1);
l4_csum = RXD_GET_L4_CKSUM(rxdp->Control_1);
if ((l3_csum == L3_CKSUM_OK) && (l4_csum == L4_CKSUM_OK)) {
@@ -7806,6 +7737,7 @@ static const struct net_device_ops s2io_netdev_ops = {
.ndo_do_ioctl = s2io_ioctl,
.ndo_set_mac_address = s2io_set_mac_addr,
.ndo_change_mtu = s2io_change_mtu,
+ .ndo_set_features = s2io_set_features,
.ndo_vlan_rx_register = s2io_vlan_rx_register,
.ndo_vlan_rx_kill_vid = s2io_vlan_rx_kill_vid,
.ndo_tx_timeout = s2io_tx_watchdog,
@@ -8047,17 +7979,18 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
/* Driver entry points */
dev->netdev_ops = &s2io_netdev_ops;
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- dev->features |= NETIF_F_LRO;
- dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+ dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_TSO | NETIF_F_TSO6 |
+ NETIF_F_RXCSUM | NETIF_F_LRO;
+ dev->features |= dev->hw_features |
+ NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ if (sp->device_type & XFRAME_II_DEVICE) {
+ dev->hw_features |= NETIF_F_UFO;
+ if (ufo)
+ dev->features |= NETIF_F_UFO;
+ }
if (sp->high_dma_flag == true)
dev->features |= NETIF_F_HIGHDMA;
- dev->features |= NETIF_F_TSO;
- dev->features |= NETIF_F_TSO6;
- if ((sp->device_type & XFRAME_II_DEVICE) && (ufo)) {
- dev->features |= NETIF_F_UFO;
- dev->features |= NETIF_F_HW_CSUM;
- }
dev->watchdog_timeo = WATCH_DOG_TIMEOUT;
INIT_WORK(&sp->rst_timer_task, s2io_restart_nic);
INIT_WORK(&sp->set_link_task, s2io_set_link);
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 2d144979f6f..800b3a44e65 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -893,9 +893,6 @@ struct s2io_nic {
u16 all_multi_pos;
u16 promisc_flg;
- /* Id timer, used to blink NIC to physically identify NIC. */
- struct timer_list id_timer;
-
/* Restart timer, used to restart NIC if the device is stuck and
* a schedule task that will set the correct Link state once the
* NIC's PHY has stabilized after a state change.
@@ -1005,18 +1002,16 @@ static inline void writeq(u64 val, void __iomem *addr)
#define LF 2
static inline void SPECIAL_REG_WRITE(u64 val, void __iomem *addr, int order)
{
- u32 ret;
-
if (order == LF) {
writel((u32) (val), addr);
- ret = readl(addr);
+ (void) readl(addr);
writel((u32) (val >> 32), (addr + 4));
- ret = readl(addr + 4);
+ (void) readl(addr + 4);
} else {
writel((u32) (val >> 32), (addr + 4));
- ret = readl(addr + 4);
+ (void) readl(addr + 4);
writel((u32) (val), addr);
- ret = readl(addr);
+ (void) readl(addr);
}
}
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index 76290a8c3c1..fa74314ef78 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -1173,7 +1173,8 @@ static int sc92031_ethtool_get_settings(struct net_device *dev,
if (phy_ctrl & PhyCtrlAne)
cmd->advertising |= ADVERTISED_Autoneg;
- cmd->speed = (output_status & 0x2) ? SPEED_100 : SPEED_10;
+ ethtool_cmd_speed_set(cmd,
+ (output_status & 0x2) ? SPEED_100 : SPEED_10);
cmd->duplex = (output_status & 0x4) ? DUPLEX_FULL : DUPLEX_HALF;
cmd->port = PORT_MII;
cmd->phy_address = phy_address;
@@ -1188,10 +1189,11 @@ static int sc92031_ethtool_set_settings(struct net_device *dev,
{
struct sc92031_priv *priv = netdev_priv(dev);
void __iomem *port_base = priv->port_base;
+ u32 speed = ethtool_cmd_speed(cmd);
u32 phy_ctrl;
u32 old_phy_ctrl;
- if (!(cmd->speed == SPEED_10 || cmd->speed == SPEED_100))
+ if (!(speed == SPEED_10 || speed == SPEED_100))
return -EINVAL;
if (!(cmd->duplex == DUPLEX_HALF || cmd->duplex == DUPLEX_FULL))
return -EINVAL;
@@ -1229,7 +1231,7 @@ static int sc92031_ethtool_set_settings(struct net_device *dev,
// FIXME: Whole branch guessed
phy_ctrl = 0;
- if (cmd->speed == SPEED_10)
+ if (speed == SPEED_10)
phy_ctrl |= PhyCtrlSpd10;
else /* cmd->speed == SPEED_100 */
phy_ctrl |= PhyCtrlSpd100;
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index a3c2aab53de..c914729f955 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -798,11 +798,6 @@ void efx_link_status_changed(struct efx_nic *efx)
if (!netif_running(efx->net_dev))
return;
- if (efx->port_inhibited) {
- netif_carrier_off(efx->net_dev);
- return;
- }
-
if (link_state->up != netif_carrier_ok(efx->net_dev)) {
efx->n_link_state_changes++;
@@ -838,7 +833,7 @@ void efx_link_set_advertising(struct efx_nic *efx, u32 advertising)
}
}
-void efx_link_set_wanted_fc(struct efx_nic *efx, enum efx_fc_type wanted_fc)
+void efx_link_set_wanted_fc(struct efx_nic *efx, u8 wanted_fc)
{
efx->wanted_fc = wanted_fc;
if (efx->link_advertising) {
@@ -1319,8 +1314,20 @@ static void efx_remove_interrupts(struct efx_nic *efx)
static void efx_set_channels(struct efx_nic *efx)
{
+ struct efx_channel *channel;
+ struct efx_tx_queue *tx_queue;
+
efx->tx_channel_offset =
separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0;
+
+ /* We need to adjust the TX queue numbers if we have separate
+ * RX-only and TX-only channels.
+ */
+ efx_for_each_channel(channel, efx) {
+ efx_for_each_channel_tx_queue(tx_queue, channel)
+ tx_queue->queue -= (efx->tx_channel_offset *
+ EFX_TXQ_TYPES);
+ }
}
static int efx_probe_nic(struct efx_nic *efx)
@@ -1438,7 +1445,7 @@ static void efx_start_all(struct efx_nic *efx)
* restart the transmit interface early so the watchdog timer stops */
efx_start_port(efx);
- if (efx_dev_registered(efx) && !efx->port_inhibited)
+ if (efx_dev_registered(efx) && netif_device_present(efx->net_dev))
netif_tx_wake_all_queues(efx->net_dev);
efx_for_each_channel(channel, efx)
@@ -1876,6 +1883,17 @@ static void efx_set_multicast_list(struct net_device *net_dev)
/* Otherwise efx_start_port() will do this */
}
+static int efx_set_features(struct net_device *net_dev, u32 data)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+
+ /* If disabling RX n-tuple filtering, clear existing filters */
+ if (net_dev->features & ~data & NETIF_F_NTUPLE)
+ efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
+
+ return 0;
+}
+
static const struct net_device_ops efx_netdev_ops = {
.ndo_open = efx_net_open,
.ndo_stop = efx_net_stop,
@@ -1887,6 +1905,7 @@ static const struct net_device_ops efx_netdev_ops = {
.ndo_change_mtu = efx_change_mtu,
.ndo_set_mac_address = efx_set_mac_address,
.ndo_set_multicast_list = efx_set_multicast_list,
+ .ndo_set_features = efx_set_features,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = efx_netpoll,
#endif
@@ -2090,6 +2109,7 @@ int efx_reset(struct efx_nic *efx, enum reset_type method)
netif_info(efx, drv, efx->net_dev, "resetting (%s)\n",
RESET_TYPE(method));
+ netif_device_detach(efx->net_dev);
efx_reset_down(efx, method);
rc = efx->type->reset(efx, method);
@@ -2123,6 +2143,7 @@ out:
efx->state = STATE_DISABLED;
} else {
netif_dbg(efx, drv, efx->net_dev, "reset complete\n");
+ netif_device_attach(efx->net_dev);
}
return rc;
}
@@ -2235,7 +2256,7 @@ static bool efx_port_dummy_op_poll(struct efx_nic *efx)
return false;
}
-static struct efx_phy_operations efx_dummy_phy_operations = {
+static const struct efx_phy_operations efx_dummy_phy_operations = {
.init = efx_port_dummy_op_int,
.reconfigure = efx_port_dummy_op_int,
.poll = efx_port_dummy_op_poll,
@@ -2251,7 +2272,7 @@ static struct efx_phy_operations efx_dummy_phy_operations = {
/* This zeroes out and then fills in the invariants in a struct
* efx_nic (including all sub-structures).
*/
-static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
+static int efx_init_struct(struct efx_nic *efx, const struct efx_nic_type *type,
struct pci_dev *pci_dev, struct net_device *net_dev)
{
int i;
@@ -2271,7 +2292,6 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name));
efx->net_dev = net_dev;
- efx->rx_checksum_enabled = true;
spin_lock_init(&efx->stats_lock);
mutex_init(&efx->mac_lock);
efx->mac_op = type->default_mac_ops;
@@ -2442,7 +2462,7 @@ static int efx_pci_probe_main(struct efx_nic *efx)
static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
const struct pci_device_id *entry)
{
- struct efx_nic_type *type = (struct efx_nic_type *) entry->driver_data;
+ const struct efx_nic_type *type = (const struct efx_nic_type *) entry->driver_data;
struct net_device *net_dev;
struct efx_nic *efx;
int i, rc;
@@ -2454,12 +2474,15 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
return -ENOMEM;
net_dev->features |= (type->offload_features | NETIF_F_SG |
NETIF_F_HIGHDMA | NETIF_F_TSO |
- NETIF_F_GRO);
+ NETIF_F_RXCSUM);
if (type->offload_features & NETIF_F_V6_CSUM)
net_dev->features |= NETIF_F_TSO6;
/* Mask for features that also apply to VLAN devices */
net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG |
- NETIF_F_HIGHDMA | NETIF_F_TSO);
+ NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
+ NETIF_F_RXCSUM);
+ /* All offloads can be toggled */
+ net_dev->hw_features = net_dev->features & ~NETIF_F_HIGHDMA;
efx = netdev_priv(net_dev);
pci_set_drvdata(pci_dev, efx);
SET_NETDEV_DEV(net_dev, &pci_dev->dev);
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 3d83a1f74fe..b0d1209ea18 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -142,6 +142,6 @@ static inline void efx_schedule_channel(struct efx_channel *channel)
extern void efx_link_status_changed(struct efx_nic *efx);
extern void efx_link_set_advertising(struct efx_nic *efx, u32);
-extern void efx_link_set_wanted_fc(struct efx_nic *efx, enum efx_fc_type);
+extern void efx_link_set_wanted_fc(struct efx_nic *efx, u8);
#endif /* EFX_EFX_H */
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 807178ef65a..d229027dc36 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -178,19 +178,27 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = {
*/
/* Identify device by flashing LEDs */
-static int efx_ethtool_phys_id(struct net_device *net_dev, u32 count)
+static int efx_ethtool_phys_id(struct net_device *net_dev,
+ enum ethtool_phys_id_state state)
{
struct efx_nic *efx = netdev_priv(net_dev);
+ enum efx_led_mode mode = EFX_LED_DEFAULT;
- do {
- efx->type->set_id_led(efx, EFX_LED_ON);
- schedule_timeout_interruptible(HZ / 2);
-
- efx->type->set_id_led(efx, EFX_LED_OFF);
- schedule_timeout_interruptible(HZ / 2);
- } while (!signal_pending(current) && --count != 0);
+ switch (state) {
+ case ETHTOOL_ID_ON:
+ mode = EFX_LED_ON;
+ break;
+ case ETHTOOL_ID_OFF:
+ mode = EFX_LED_OFF;
+ break;
+ case ETHTOOL_ID_INACTIVE:
+ mode = EFX_LED_DEFAULT;
+ break;
+ case ETHTOOL_ID_ACTIVE:
+ return 1; /* cycle on/off once per second */
+ }
- efx->type->set_id_led(efx, EFX_LED_DEFAULT);
+ efx->type->set_id_led(efx, mode);
return 0;
}
@@ -211,7 +219,7 @@ static int efx_ethtool_get_settings(struct net_device *net_dev,
ecmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
if (LOOPBACK_INTERNAL(efx)) {
- ecmd->speed = link_state->speed;
+ ethtool_cmd_speed_set(ecmd, link_state->speed);
ecmd->duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF;
}
@@ -226,7 +234,8 @@ static int efx_ethtool_set_settings(struct net_device *net_dev,
int rc;
/* GMAC does not support 1000Mbps HD */
- if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) {
+ if ((ethtool_cmd_speed(ecmd) == SPEED_1000) &&
+ (ecmd->duplex != DUPLEX_FULL)) {
netif_dbg(efx, drv, efx->net_dev,
"rejecting unsupported 1000Mbps HD setting\n");
return -EINVAL;
@@ -518,72 +527,6 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
}
}
-static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable)
-{
- struct efx_nic *efx __attribute__ ((unused)) = netdev_priv(net_dev);
- u32 features;
-
- features = NETIF_F_TSO;
- if (efx->type->offload_features & NETIF_F_V6_CSUM)
- features |= NETIF_F_TSO6;
-
- if (enable)
- net_dev->features |= features;
- else
- net_dev->features &= ~features;
-
- return 0;
-}
-
-static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- u32 features = efx->type->offload_features & NETIF_F_ALL_CSUM;
-
- if (enable)
- net_dev->features |= features;
- else
- net_dev->features &= ~features;
-
- return 0;
-}
-
-static int efx_ethtool_set_rx_csum(struct net_device *net_dev, u32 enable)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
-
- /* No way to stop the hardware doing the checks; we just
- * ignore the result.
- */
- efx->rx_checksum_enabled = !!enable;
-
- return 0;
-}
-
-static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
-
- return efx->rx_checksum_enabled;
-}
-
-static int efx_ethtool_set_flags(struct net_device *net_dev, u32 data)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- u32 supported = (efx->type->offload_features &
- (ETH_FLAG_RXHASH | ETH_FLAG_NTUPLE));
- int rc;
-
- rc = ethtool_op_set_flags(net_dev, data, supported);
- if (rc)
- return rc;
-
- if (!(data & ETH_FLAG_NTUPLE))
- efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
-
- return 0;
-}
-
static void efx_ethtool_self_test(struct net_device *net_dev,
struct ethtool_test *test, u64 *data)
{
@@ -755,7 +698,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
struct ethtool_pauseparam *pause)
{
struct efx_nic *efx = netdev_priv(net_dev);
- enum efx_fc_type wanted_fc, old_fc;
+ u8 wanted_fc, old_fc;
u32 old_adv;
bool reset;
int rc = 0;
@@ -1012,8 +955,9 @@ static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev,
if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_CLEAR)
return efx_filter_remove_filter(efx, &filter);
- else
- return efx_filter_insert_filter(efx, &filter, true);
+
+ rc = efx_filter_insert_filter(efx, &filter, true);
+ return rc < 0 ? rc : 0;
}
static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev,
@@ -1070,22 +1014,10 @@ const struct ethtool_ops efx_ethtool_ops = {
.set_ringparam = efx_ethtool_set_ringparam,
.get_pauseparam = efx_ethtool_get_pauseparam,
.set_pauseparam = efx_ethtool_set_pauseparam,
- .get_rx_csum = efx_ethtool_get_rx_csum,
- .set_rx_csum = efx_ethtool_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- /* Need to enable/disable IPv6 too */
- .set_tx_csum = efx_ethtool_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- /* Need to enable/disable TSO-IPv6 too */
- .set_tso = efx_ethtool_set_tso,
- .get_flags = ethtool_op_get_flags,
- .set_flags = efx_ethtool_set_flags,
.get_sset_count = efx_ethtool_get_sset_count,
.self_test = efx_ethtool_self_test,
.get_strings = efx_ethtool_get_strings,
- .phys_id = efx_ethtool_phys_id,
+ .set_phys_id = efx_ethtool_phys_id,
.get_ethtool_stats = efx_ethtool_get_stats,
.get_wol = efx_ethtool_get_wol,
.set_wol = efx_ethtool_set_wol,
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index d96b23769bd..60176e873d6 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -1703,7 +1703,7 @@ static int falcon_set_wol(struct efx_nic *efx, u32 type)
**************************************************************************
*/
-struct efx_nic_type falcon_a1_nic_type = {
+const struct efx_nic_type falcon_a1_nic_type = {
.probe = falcon_probe_nic,
.remove = falcon_remove_nic,
.init = falcon_init_nic,
@@ -1744,7 +1744,7 @@ struct efx_nic_type falcon_a1_nic_type = {
.reset_world_flags = ETH_RESET_IRQ,
};
-struct efx_nic_type falcon_b0_nic_type = {
+const struct efx_nic_type falcon_b0_nic_type = {
.probe = falcon_probe_nic,
.remove = falcon_remove_nic,
.init = falcon_init_nic,
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index 2c9ee5db3bf..9516452c079 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -362,7 +362,7 @@ void falcon_poll_xmac(struct efx_nic *efx)
falcon_ack_status_intr(efx);
}
-struct efx_mac_operations falcon_xmac_operations = {
+const struct efx_mac_operations falcon_xmac_operations = {
.reconfigure = falcon_reconfigure_xmac,
.update_stats = falcon_update_stats_xmac,
.check_fault = falcon_xmac_check_fault,
diff --git a/drivers/net/sfc/mac.h b/drivers/net/sfc/mac.h
index 6886cdf87c1..d6a255d0856 100644
--- a/drivers/net/sfc/mac.h
+++ b/drivers/net/sfc/mac.h
@@ -13,8 +13,8 @@
#include "net_driver.h"
-extern struct efx_mac_operations falcon_xmac_operations;
-extern struct efx_mac_operations efx_mcdi_mac_operations;
+extern const struct efx_mac_operations falcon_xmac_operations;
+extern const struct efx_mac_operations efx_mcdi_mac_operations;
extern int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
u32 dma_len, int enable, int clear);
diff --git a/drivers/net/sfc/mcdi_mac.c b/drivers/net/sfc/mcdi_mac.c
index 33f7294edb4..50c20777a56 100644
--- a/drivers/net/sfc/mcdi_mac.c
+++ b/drivers/net/sfc/mcdi_mac.c
@@ -138,7 +138,7 @@ static bool efx_mcdi_mac_check_fault(struct efx_nic *efx)
}
-struct efx_mac_operations efx_mcdi_mac_operations = {
+const struct efx_mac_operations efx_mcdi_mac_operations = {
.reconfigure = efx_mcdi_mac_reconfigure,
.update_stats = efx_port_dummy_op_void,
.check_fault = efx_mcdi_mac_check_fault,
diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c
index 7e3c65b0c99..6c63ab0710a 100644
--- a/drivers/net/sfc/mcdi_phy.c
+++ b/drivers/net/sfc/mcdi_phy.c
@@ -513,7 +513,7 @@ static void efx_mcdi_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *e
ecmd->supported =
mcdi_to_ethtool_cap(phy_cfg->media, phy_cfg->supported_cap);
ecmd->advertising = efx->link_advertising;
- ecmd->speed = efx->link_state.speed;
+ ethtool_cmd_speed_set(ecmd, efx->link_state.speed);
ecmd->duplex = efx->link_state.fd;
ecmd->port = mcdi_to_ethtool_media(phy_cfg->media);
ecmd->phy_address = phy_cfg->port;
@@ -545,7 +545,7 @@ static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ec
caps = (ethtool_to_mcdi_cap(ecmd->advertising) |
1 << MC_CMD_PHY_CAP_AN_LBN);
} else if (ecmd->duplex) {
- switch (ecmd->speed) {
+ switch (ethtool_cmd_speed(ecmd)) {
case 10: caps = 1 << MC_CMD_PHY_CAP_10FDX_LBN; break;
case 100: caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN; break;
case 1000: caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN; break;
@@ -553,7 +553,7 @@ static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ec
default: return -EINVAL;
}
} else {
- switch (ecmd->speed) {
+ switch (ethtool_cmd_speed(ecmd)) {
case 10: caps = 1 << MC_CMD_PHY_CAP_10HDX_LBN; break;
case 100: caps = 1 << MC_CMD_PHY_CAP_100HDX_LBN; break;
case 1000: caps = 1 << MC_CMD_PHY_CAP_1000HDX_LBN; break;
@@ -739,7 +739,7 @@ static const char *efx_mcdi_phy_test_name(struct efx_nic *efx,
return NULL;
}
-struct efx_phy_operations efx_mcdi_phy_ops = {
+const struct efx_phy_operations efx_mcdi_phy_ops = {
.probe = efx_mcdi_phy_probe,
.init = efx_port_dummy_op_int,
.reconfigure = efx_mcdi_phy_reconfigure,
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 19e68c26d10..7ab385c8136 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -232,12 +232,12 @@ void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
*/
int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- struct ethtool_cmd prev;
+ struct ethtool_cmd prev = { .cmd = ETHTOOL_GSET };
efx->phy_op->get_settings(efx, &prev);
if (ecmd->advertising == prev.advertising &&
- ecmd->speed == prev.speed &&
+ ethtool_cmd_speed(ecmd) == ethtool_cmd_speed(&prev) &&
ecmd->duplex == prev.duplex &&
ecmd->port == prev.port &&
ecmd->autoneg == prev.autoneg)
@@ -284,7 +284,7 @@ void efx_mdio_an_reconfigure(struct efx_nic *efx)
efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg);
}
-enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx)
+u8 efx_mdio_get_pause(struct efx_nic *efx)
{
BUILD_BUG_ON(EFX_FC_AUTO & (EFX_FC_RX | EFX_FC_TX));
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index df0703940c8..a97dbbd2de9 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -92,7 +92,7 @@ extern void efx_mdio_an_reconfigure(struct efx_nic *efx);
/* Get pause parameters from AN if available (otherwise return
* requested pause parameters)
*/
-enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx);
+u8 efx_mdio_get_pause(struct efx_nic *efx);
/* Wait for specified MMDs to exit reset within a timeout */
extern int efx_mdio_wait_reset_mmds(struct efx_nic *efx,
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 191a311da2d..e8d5f03a89f 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -449,11 +449,9 @@ enum nic_state {
struct efx_nic;
/* Pseudo bit-mask flow control field */
-enum efx_fc_type {
- EFX_FC_RX = FLOW_CTRL_RX,
- EFX_FC_TX = FLOW_CTRL_TX,
- EFX_FC_AUTO = 4,
-};
+#define EFX_FC_RX FLOW_CTRL_RX
+#define EFX_FC_TX FLOW_CTRL_TX
+#define EFX_FC_AUTO 4
/**
* struct efx_link_state - Current state of the link
@@ -465,7 +463,7 @@ enum efx_fc_type {
struct efx_link_state {
bool up;
bool fd;
- enum efx_fc_type fc;
+ u8 fc;
unsigned int speed;
};
@@ -670,16 +668,14 @@ struct efx_filter_state;
* @mtd_list: List of MTDs attached to the NIC
* @nic_data: Hardware dependent state
* @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode,
- * @port_inhibited, efx_monitor() and efx_reconfigure_port()
+ * efx_monitor() and efx_reconfigure_port()
* @port_enabled: Port enabled indicator.
* Serialises efx_stop_all(), efx_start_all(), efx_monitor() and
* efx_mac_work() with kernel interfaces. Safe to read under any
* one of the rtnl_lock, mac_lock, or netif_tx_lock, but all three must
* be held to modify it.
- * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock
* @port_initialized: Port initialized?
* @net_dev: Operating system network device. Consider holding the rtnl lock
- * @rx_checksum_enabled: RX checksumming enabled
* @stats_buffer: DMA buffer for statistics
* @mac_op: MAC interface
* @phy_type: PHY type
@@ -765,18 +761,16 @@ struct efx_nic {
struct mutex mac_lock;
struct work_struct mac_work;
bool port_enabled;
- bool port_inhibited;
bool port_initialized;
struct net_device *net_dev;
- bool rx_checksum_enabled;
struct efx_buffer stats_buffer;
- struct efx_mac_operations *mac_op;
+ const struct efx_mac_operations *mac_op;
unsigned int phy_type;
- struct efx_phy_operations *phy_op;
+ const struct efx_phy_operations *phy_op;
void *phy_data;
struct mdio_if_info mdio;
unsigned int mdio_bus;
@@ -788,7 +782,7 @@ struct efx_nic {
bool promiscuous;
union efx_multicast_hash multicast_hash;
- enum efx_fc_type wanted_fc;
+ u8 wanted_fc;
atomic_t rx_reset;
enum efx_loopback_mode loopback_mode;
@@ -897,7 +891,7 @@ struct efx_nic_type {
void (*resume_wol)(struct efx_nic *efx);
int (*test_registers)(struct efx_nic *efx);
int (*test_nvram)(struct efx_nic *efx);
- struct efx_mac_operations *default_mac_ops;
+ const struct efx_mac_operations *default_mac_ops;
int revision;
unsigned int mem_map_size;
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c
index 9b29a8d7c44..f2a2b947f86 100644
--- a/drivers/net/sfc/nic.c
+++ b/drivers/net/sfc/nic.c
@@ -852,7 +852,6 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event)
unsigned expected_ptr;
bool rx_ev_pkt_ok, discard = false, checksummed;
struct efx_rx_queue *rx_queue;
- struct efx_nic *efx = channel->efx;
/* Basic packet information */
rx_ev_byte_cnt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_BYTE_CNT);
@@ -875,9 +874,8 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event)
* UDP/IP, then we can rely on the hardware checksum.
*/
checksummed =
- likely(efx->rx_checksum_enabled) &&
- (rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP ||
- rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP);
+ rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP ||
+ rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP;
} else {
efx_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok, &discard);
checksummed = false;
diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h
index d91701abd33..4bd1f2839df 100644
--- a/drivers/net/sfc/nic.h
+++ b/drivers/net/sfc/nic.h
@@ -152,9 +152,9 @@ struct siena_nic_data {
int wol_filter_id;
};
-extern struct efx_nic_type falcon_a1_nic_type;
-extern struct efx_nic_type falcon_b0_nic_type;
-extern struct efx_nic_type siena_a0_nic_type;
+extern const struct efx_nic_type falcon_a1_nic_type;
+extern const struct efx_nic_type falcon_b0_nic_type;
+extern const struct efx_nic_type siena_a0_nic_type;
/**************************************************************************
*
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h
index b3b79472421..11d148cd844 100644
--- a/drivers/net/sfc/phy.h
+++ b/drivers/net/sfc/phy.h
@@ -13,14 +13,14 @@
/****************************************************************************
* 10Xpress (SFX7101) PHY
*/
-extern struct efx_phy_operations falcon_sfx7101_phy_ops;
+extern const struct efx_phy_operations falcon_sfx7101_phy_ops;
extern void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);
/****************************************************************************
* AMCC/Quake QT202x PHYs
*/
-extern struct efx_phy_operations falcon_qt202x_phy_ops;
+extern const struct efx_phy_operations falcon_qt202x_phy_ops;
/* These PHYs provide various H/W control states for LEDs */
#define QUAKE_LED_LINK_INVAL (0)
@@ -39,7 +39,7 @@ extern void falcon_qt202x_set_led(struct efx_nic *p, int led, int state);
/****************************************************************************
* Transwitch CX4 retimer
*/
-extern struct efx_phy_operations falcon_txc_phy_ops;
+extern const struct efx_phy_operations falcon_txc_phy_ops;
#define TXC_GPIO_DIR_INPUT 0
#define TXC_GPIO_DIR_OUTPUT 1
@@ -50,7 +50,7 @@ extern void falcon_txc_set_gpio_val(struct efx_nic *efx, int pin, int val);
/****************************************************************************
* Siena managed PHYs
*/
-extern struct efx_phy_operations efx_mcdi_phy_ops;
+extern const struct efx_phy_operations efx_mcdi_phy_ops;
extern int efx_mcdi_mdio_read(struct efx_nic *efx, unsigned int bus,
unsigned int prtad, unsigned int devad,
diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c
index 55f90924247..7ad97e39740 100644
--- a/drivers/net/sfc/qt202x_phy.c
+++ b/drivers/net/sfc/qt202x_phy.c
@@ -449,7 +449,7 @@ static void qt202x_phy_remove(struct efx_nic *efx)
efx->phy_data = NULL;
}
-struct efx_phy_operations falcon_qt202x_phy_ops = {
+const struct efx_phy_operations falcon_qt202x_phy_ops = {
.probe = qt202x_phy_probe,
.init = qt202x_phy_init,
.reconfigure = qt202x_phy_reconfigure,
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index c0fdb59030f..b7dc891b446 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -605,6 +605,9 @@ void __efx_rx_packet(struct efx_channel *channel,
skb_record_rx_queue(skb, channel->channel);
}
+ if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM)))
+ checksummed = false;
+
if (likely(checksummed || rx_buf->is_page)) {
efx_rx_packet_gro(channel, rx_buf, eh, checksummed);
return;
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 50ad3bcaf68..822f6c2a6a7 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -695,12 +695,12 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
/* Offline (i.e. disruptive) testing
* This checks MAC and PHY loopback on the specified port. */
- /* force the carrier state off so the kernel doesn't transmit during
- * the loopback test, and the watchdog timeout doesn't fire. Also put
- * falcon into loopback for the register test.
+ /* Detach the device so the kernel doesn't transmit during the
+ * loopback test and the watchdog timeout doesn't fire.
*/
+ netif_device_detach(efx->net_dev);
+
mutex_lock(&efx->mac_lock);
- efx->port_inhibited = true;
if (efx->loopback_modes) {
/* We need the 312 clock from the PHY to test the XMAC
* registers, so move into XGMII loopback if available */
@@ -750,12 +750,11 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
/* restore the PHY to the previous state */
mutex_lock(&efx->mac_lock);
efx->phy_mode = phy_mode;
- efx->port_inhibited = false;
efx->loopback_mode = loopback_mode;
__efx_reconfigure_port(efx);
mutex_unlock(&efx->mac_lock);
- netif_tx_wake_all_queues(efx->net_dev);
+ netif_device_attach(efx->net_dev);
return rc_test;
}
diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c
index 837869b71db..fb4721f780f 100644
--- a/drivers/net/sfc/siena.c
+++ b/drivers/net/sfc/siena.c
@@ -599,7 +599,7 @@ static void siena_init_wol(struct efx_nic *efx)
**************************************************************************
*/
-struct efx_nic_type siena_a0_nic_type = {
+const struct efx_nic_type siena_a0_nic_type = {
.probe = siena_probe_nic,
.remove = siena_remove_nic,
.init = siena_init_nic,
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index efdceb35aaa..7b0fd89e7b8 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -460,7 +460,7 @@ tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
/* In loopback, the PHY automatically brings up the correct interface,
* but doesn't advertise the correct speed. So override it */
if (LOOPBACK_EXTERNAL(efx))
- ecmd->speed = SPEED_10000;
+ ethtool_cmd_speed_set(ecmd, SPEED_10000);
}
static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
@@ -478,7 +478,7 @@ static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
advertising & ADVERTISED_10000baseT_Full);
}
-struct efx_phy_operations falcon_sfx7101_phy_ops = {
+const struct efx_phy_operations falcon_sfx7101_phy_ops = {
.probe = tenxpress_phy_probe,
.init = tenxpress_phy_init,
.reconfigure = tenxpress_phy_reconfigure,
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index d2c85dfdf3b..84eb99e0f8d 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -205,7 +205,9 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
goto unwind;
}
smp_mb();
- netif_tx_start_queue(tx_queue->core_txq);
+ if (likely(!efx->loopback_selftest))
+ netif_tx_start_queue(
+ tx_queue->core_txq);
}
insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask;
@@ -338,8 +340,7 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
struct efx_tx_queue *tx_queue;
unsigned index, type;
- if (unlikely(efx->port_inhibited))
- return NETDEV_TX_BUSY;
+ EFX_WARN_ON_PARANOID(!netif_device_present(net_dev));
index = skb_get_queue_mapping(skb);
type = skb->ip_summed == CHECKSUM_PARTIAL ? EFX_TXQ_TYPE_OFFLOAD : 0;
@@ -436,7 +437,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
smp_mb();
if (unlikely(netif_tx_queue_stopped(tx_queue->core_txq)) &&
likely(efx->port_enabled) &&
- likely(!efx->port_inhibited)) {
+ likely(netif_device_present(efx->net_dev))) {
fill_level = tx_queue->insert_count - tx_queue->read_count;
if (fill_level < EFX_TXQ_THRESHOLD(efx)) {
EFX_BUG_ON_PARANOID(!efx_dev_registered(efx));
diff --git a/drivers/net/sfc/txc43128_phy.c b/drivers/net/sfc/txc43128_phy.c
index d9886addcc9..7c21b334a75 100644
--- a/drivers/net/sfc/txc43128_phy.c
+++ b/drivers/net/sfc/txc43128_phy.c
@@ -545,7 +545,7 @@ static void txc43128_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
mdio45_ethtool_gset(&efx->mdio, ecmd);
}
-struct efx_phy_operations falcon_txc_phy_ops = {
+const struct efx_phy_operations falcon_txc_phy_ops = {
.probe = txc43128_phy_probe,
.init = txc43128_phy_init,
.reconfigure = txc43128_phy_reconfigure,
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 35b28f42d20..52a48cb7544 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -303,7 +303,7 @@ static int skge_get_settings(struct net_device *dev,
ecmd->advertising = skge->advertising;
ecmd->autoneg = skge->autoneg;
- ecmd->speed = skge->speed;
+ ethtool_cmd_speed_set(ecmd, skge->speed);
ecmd->duplex = skge->duplex;
return 0;
}
@@ -321,8 +321,9 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
skge->speed = -1;
} else {
u32 setting;
+ u32 speed = ethtool_cmd_speed(ecmd);
- switch (ecmd->speed) {
+ switch (speed) {
case SPEED_1000:
if (ecmd->duplex == DUPLEX_FULL)
setting = SUPPORTED_1000baseT_Full;
@@ -355,7 +356,7 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
if ((setting & supported) == 0)
return -EINVAL;
- skge->speed = ecmd->speed;
+ skge->speed = speed;
skge->duplex = ecmd->duplex;
}
@@ -537,46 +538,6 @@ static int skge_nway_reset(struct net_device *dev)
return 0;
}
-static int skge_set_sg(struct net_device *dev, u32 data)
-{
- struct skge_port *skge = netdev_priv(dev);
- struct skge_hw *hw = skge->hw;
-
- if (hw->chip_id == CHIP_ID_GENESIS && data)
- return -EOPNOTSUPP;
- return ethtool_op_set_sg(dev, data);
-}
-
-static int skge_set_tx_csum(struct net_device *dev, u32 data)
-{
- struct skge_port *skge = netdev_priv(dev);
- struct skge_hw *hw = skge->hw;
-
- if (hw->chip_id == CHIP_ID_GENESIS && data)
- return -EOPNOTSUPP;
-
- return ethtool_op_set_tx_csum(dev, data);
-}
-
-static u32 skge_get_rx_csum(struct net_device *dev)
-{
- struct skge_port *skge = netdev_priv(dev);
-
- return skge->rx_csum;
-}
-
-/* Only Yukon supports checksum offload. */
-static int skge_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct skge_port *skge = netdev_priv(dev);
-
- if (skge->hw->chip_id == CHIP_ID_GENESIS && data)
- return -EOPNOTSUPP;
-
- skge->rx_csum = data;
- return 0;
-}
-
static void skge_get_pauseparam(struct net_device *dev,
struct ethtool_pauseparam *ecmd)
{
@@ -786,28 +747,27 @@ static void skge_led(struct skge_port *skge, enum led_mode mode)
}
/* blink LED's for finding board */
-static int skge_phys_id(struct net_device *dev, u32 data)
+static int skge_set_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
struct skge_port *skge = netdev_priv(dev);
- unsigned long ms;
- enum led_mode mode = LED_MODE_TST;
- if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
- ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT / HZ) * 1000;
- else
- ms = data * 1000;
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ return 2; /* cycle on/off twice per second */
- while (ms > 0) {
- skge_led(skge, mode);
- mode ^= LED_MODE_TST;
+ case ETHTOOL_ID_ON:
+ skge_led(skge, LED_MODE_TST);
+ break;
- if (msleep_interruptible(BLINK_MS))
- break;
- ms -= BLINK_MS;
- }
+ case ETHTOOL_ID_OFF:
+ skge_led(skge, LED_MODE_OFF);
+ break;
- /* back to regular LED state */
- skge_led(skge, netif_running(dev) ? LED_MODE_ON : LED_MODE_OFF);
+ case ETHTOOL_ID_INACTIVE:
+ /* back to regular LED state */
+ skge_led(skge, netif_running(dev) ? LED_MODE_ON : LED_MODE_OFF);
+ }
return 0;
}
@@ -925,12 +885,8 @@ static const struct ethtool_ops skge_ethtool_ops = {
.set_pauseparam = skge_set_pauseparam,
.get_coalesce = skge_get_coalesce,
.set_coalesce = skge_set_coalesce,
- .set_sg = skge_set_sg,
- .set_tx_csum = skge_set_tx_csum,
- .get_rx_csum = skge_get_rx_csum,
- .set_rx_csum = skge_set_rx_csum,
.get_strings = skge_get_strings,
- .phys_id = skge_phys_id,
+ .set_phys_id = skge_set_phys_id,
.get_sset_count = skge_get_sset_count,
.get_ethtool_stats = skge_get_ethtool_stats,
};
@@ -3085,7 +3041,8 @@ static struct sk_buff *skge_rx_get(struct net_device *dev,
}
skb_put(skb, len);
- if (skge->rx_csum) {
+
+ if (dev->features & NETIF_F_RXCSUM) {
skb->csum = csum;
skb->ip_summed = CHECKSUM_COMPLETE;
}
@@ -3847,10 +3804,10 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
setup_timer(&skge->link_timer, xm_link_timer, (unsigned long) skge);
if (hw->chip_id != CHIP_ID_GENESIS) {
- dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
- skge->rx_csum = 1;
+ dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
+ NETIF_F_RXCSUM;
+ dev->features |= dev->hw_features;
}
- dev->features |= NETIF_F_GRO;
/* read the mac address */
memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 51c0214ac25..598bf7a1a55 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -2460,7 +2460,6 @@ struct skge_port {
struct timer_list link_timer;
enum pause_control flow_control;
enum pause_status flow_status;
- u8 rx_csum;
u8 blink_on;
u8 wol;
u8 autoneg; /* AUTONEG_ENABLE, AUTONEG_DISABLE */
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index ff8d262dc27..3ee41da130c 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1198,12 +1198,12 @@ static void rx_set_checksum(struct sky2_port *sky2)
sky2_write32(sky2->hw,
Q_ADDR(rxqaddr[sky2->port], Q_CSR),
- (sky2->flags & SKY2_FLAG_RX_CHECKSUM)
+ (sky2->netdev->features & NETIF_F_RXCSUM)
? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
}
/* Enable/disable receive hash calculation (RSS) */
-static void rx_set_rss(struct net_device *dev)
+static void rx_set_rss(struct net_device *dev, u32 features)
{
struct sky2_port *sky2 = netdev_priv(dev);
struct sky2_hw *hw = sky2->hw;
@@ -1216,7 +1216,7 @@ static void rx_set_rss(struct net_device *dev)
}
/* Program RSS initial values */
- if (dev->features & NETIF_F_RXHASH) {
+ if (features & NETIF_F_RXHASH) {
u32 key[nkeys];
get_random_bytes(key, nkeys * sizeof(u32));
@@ -1322,32 +1322,32 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return err;
}
-#define NETIF_F_ALL_VLAN (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)
+#define SKY2_VLAN_OFFLOADS (NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO)
-static void sky2_vlan_mode(struct net_device *dev)
+static void sky2_vlan_mode(struct net_device *dev, u32 features)
{
struct sky2_port *sky2 = netdev_priv(dev);
struct sky2_hw *hw = sky2->hw;
u16 port = sky2->port;
- if (dev->features & NETIF_F_HW_VLAN_RX)
+ if (features & NETIF_F_HW_VLAN_RX)
sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
RX_VLAN_STRIP_ON);
else
sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
RX_VLAN_STRIP_OFF);
- dev->vlan_features = dev->features &~ NETIF_F_ALL_VLAN;
- if (dev->features & NETIF_F_HW_VLAN_TX)
+ if (features & NETIF_F_HW_VLAN_TX) {
sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
TX_VLAN_TAG_ON);
- else {
+
+ dev->vlan_features |= SKY2_VLAN_OFFLOADS;
+ } else {
sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
TX_VLAN_TAG_OFF);
/* Can't do transmit offload of vlan without hw vlan */
- dev->vlan_features &= ~(NETIF_F_TSO | NETIF_F_SG
- | NETIF_F_ALL_CSUM);
+ dev->vlan_features &= ~SKY2_VLAN_OFFLOADS;
}
}
@@ -1463,7 +1463,7 @@ static void sky2_rx_start(struct sky2_port *sky2)
rx_set_checksum(sky2);
if (!(hw->flags & SKY2_HW_RSS_BROKEN))
- rx_set_rss(sky2->netdev);
+ rx_set_rss(sky2->netdev, sky2->netdev->features);
/* submit Rx ring */
for (i = 0; i < sky2->rx_pending; i++) {
@@ -1626,7 +1626,8 @@ static void sky2_hw_up(struct sky2_port *sky2)
sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
sky2->tx_ring_size - 1);
- sky2_vlan_mode(sky2->netdev);
+ sky2_vlan_mode(sky2->netdev, sky2->netdev->features);
+ netdev_update_features(sky2->netdev);
sky2_rx_start(sky2);
}
@@ -2261,12 +2262,9 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
hw->chip_id == CHIP_ID_YUKON_FE_P))
return -EINVAL;
- /* TSO, etc on Yukon Ultra and MTU > 1500 not supported */
- if (new_mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U)
- dev->features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM);
-
if (!netif_running(dev)) {
dev->mtu = new_mtu;
+ netdev_update_features(dev);
return 0;
}
@@ -2288,6 +2286,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
sky2_rx_clean(sky2);
dev->mtu = new_mtu;
+ netdev_update_features(dev);
mode = DATA_BLIND_VAL(DATA_BLIND_DEF) |
GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
@@ -2535,8 +2534,11 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status)
"%s: receive checksum problem (status = %#x)\n",
sky2->netdev->name, status);
- /* Disable checksum offload */
- sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM;
+ /* Disable checksum offload
+ * It will be reenabled on next ndo_set_features, but if it's
+ * really broken, will get disabled again
+ */
+ sky2->netdev->features &= ~NETIF_F_RXCSUM;
sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
BMU_DIS_RX_CHKSUM);
}
@@ -2591,7 +2593,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
/* This chip reports checksum status differently */
if (hw->flags & SKY2_HW_NEW_LE) {
- if ((sky2->flags & SKY2_FLAG_RX_CHECKSUM) &&
+ if ((dev->features & NETIF_F_RXCSUM) &&
(le->css & (CSS_ISIPV4 | CSS_ISIPV6)) &&
(le->css & CSS_TCPUDPCSOK))
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -2616,7 +2618,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
sky2->rx_tag = length;
/* fall through */
case OP_RXCHKS:
- if (likely(sky2->flags & SKY2_FLAG_RX_CHECKSUM))
+ if (likely(dev->features & NETIF_F_RXCSUM))
sky2_rx_checksum(sky2, status);
break;
@@ -3411,10 +3413,10 @@ static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->phy_address = PHY_ADDR_MARV;
if (sky2_is_copper(hw)) {
ecmd->port = PORT_TP;
- ecmd->speed = sky2->speed;
+ ethtool_cmd_speed_set(ecmd, sky2->speed);
ecmd->supported |= SUPPORTED_Autoneg | SUPPORTED_TP;
} else {
- ecmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(ecmd, SPEED_1000);
ecmd->port = PORT_FIBRE;
ecmd->supported |= SUPPORTED_Autoneg | SUPPORTED_FIBRE;
}
@@ -3450,8 +3452,9 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
sky2->speed = -1;
} else {
u32 setting;
+ u32 speed = ethtool_cmd_speed(ecmd);
- switch (ecmd->speed) {
+ switch (speed) {
case SPEED_1000:
if (ecmd->duplex == DUPLEX_FULL)
setting = SUPPORTED_1000baseT_Full;
@@ -3484,7 +3487,7 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
if ((setting & supported) == 0)
return -EINVAL;
- sky2->speed = ecmd->speed;
+ sky2->speed = speed;
sky2->duplex = ecmd->duplex;
sky2->flags &= ~SKY2_FLAG_AUTO_SPEED;
}
@@ -3552,28 +3555,6 @@ static const struct sky2_stat {
{ "tx_fifo_underrun", GM_TXE_FIFO_UR },
};
-static u32 sky2_get_rx_csum(struct net_device *dev)
-{
- struct sky2_port *sky2 = netdev_priv(dev);
-
- return !!(sky2->flags & SKY2_FLAG_RX_CHECKSUM);
-}
-
-static int sky2_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct sky2_port *sky2 = netdev_priv(dev);
-
- if (data)
- sky2->flags |= SKY2_FLAG_RX_CHECKSUM;
- else
- sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM;
-
- sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
- data ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
-
- return 0;
-}
-
static u32 sky2_get_msglevel(struct net_device *netdev)
{
struct sky2_port *sky2 = netdev_priv(netdev);
@@ -3826,23 +3807,24 @@ static void sky2_led(struct sky2_port *sky2, enum led_mode mode)
}
/* blink LED's for finding board */
-static int sky2_phys_id(struct net_device *dev, u32 data)
+static int sky2_set_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
struct sky2_port *sky2 = netdev_priv(dev);
- unsigned int i;
-
- if (data == 0)
- data = UINT_MAX;
- for (i = 0; i < data; i++) {
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ return 1; /* cycle on/off once per second */
+ case ETHTOOL_ID_INACTIVE:
+ sky2_led(sky2, MO_LED_NORM);
+ break;
+ case ETHTOOL_ID_ON:
sky2_led(sky2, MO_LED_ON);
- if (msleep_interruptible(500))
- break;
+ break;
+ case ETHTOOL_ID_OFF:
sky2_led(sky2, MO_LED_OFF);
- if (msleep_interruptible(500))
- break;
+ break;
}
- sky2_led(sky2, MO_LED_NORM);
return 0;
}
@@ -4083,34 +4065,6 @@ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs,
}
}
-/* In order to do Jumbo packets on these chips, need to turn off the
- * transmit store/forward. Therefore checksum offload won't work.
- */
-static int no_tx_offload(struct net_device *dev)
-{
- const struct sky2_port *sky2 = netdev_priv(dev);
- const struct sky2_hw *hw = sky2->hw;
-
- return dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U;
-}
-
-static int sky2_set_tx_csum(struct net_device *dev, u32 data)
-{
- if (data && no_tx_offload(dev))
- return -EINVAL;
-
- return ethtool_op_set_tx_csum(dev, data);
-}
-
-
-static int sky2_set_tso(struct net_device *dev, u32 data)
-{
- if (data && no_tx_offload(dev))
- return -EINVAL;
-
- return ethtool_op_set_tso(dev, data);
-}
-
static int sky2_get_eeprom_len(struct net_device *dev)
{
struct sky2_port *sky2 = netdev_priv(dev);
@@ -4213,31 +4167,36 @@ static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom
return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len);
}
-static int sky2_set_flags(struct net_device *dev, u32 data)
+static u32 sky2_fix_features(struct net_device *dev, u32 features)
{
- struct sky2_port *sky2 = netdev_priv(dev);
- unsigned long old_feat = dev->features;
- u32 supported = 0;
- int rc;
+ const struct sky2_port *sky2 = netdev_priv(dev);
+ const struct sky2_hw *hw = sky2->hw;
- if (!(sky2->hw->flags & SKY2_HW_RSS_BROKEN))
- supported |= ETH_FLAG_RXHASH;
+ /* In order to do Jumbo packets on these chips, need to turn off the
+ * transmit store/forward. Therefore checksum offload won't work.
+ */
+ if (dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U)
+ features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM);
- if (!(sky2->hw->flags & SKY2_HW_VLAN_BROKEN))
- supported |= ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN;
+ return features;
+}
- printk(KERN_DEBUG "sky2 set_flags: supported %x data %x\n",
- supported, data);
+static int sky2_set_features(struct net_device *dev, u32 features)
+{
+ struct sky2_port *sky2 = netdev_priv(dev);
+ u32 changed = dev->features ^ features;
- rc = ethtool_op_set_flags(dev, data, supported);
- if (rc)
- return rc;
+ if (changed & NETIF_F_RXCSUM) {
+ u32 on = features & NETIF_F_RXCSUM;
+ sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+ on ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
+ }
- if ((old_feat ^ dev->features) & NETIF_F_RXHASH)
- rx_set_rss(dev);
+ if (changed & NETIF_F_RXHASH)
+ rx_set_rss(dev, features);
- if ((old_feat ^ dev->features) & NETIF_F_ALL_VLAN)
- sky2_vlan_mode(dev);
+ if (changed & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX))
+ sky2_vlan_mode(dev, features);
return 0;
}
@@ -4257,11 +4216,6 @@ static const struct ethtool_ops sky2_ethtool_ops = {
.get_eeprom_len = sky2_get_eeprom_len,
.get_eeprom = sky2_get_eeprom,
.set_eeprom = sky2_set_eeprom,
- .set_sg = ethtool_op_set_sg,
- .set_tx_csum = sky2_set_tx_csum,
- .set_tso = sky2_set_tso,
- .get_rx_csum = sky2_get_rx_csum,
- .set_rx_csum = sky2_set_rx_csum,
.get_strings = sky2_get_strings,
.get_coalesce = sky2_get_coalesce,
.set_coalesce = sky2_set_coalesce,
@@ -4269,11 +4223,9 @@ static const struct ethtool_ops sky2_ethtool_ops = {
.set_ringparam = sky2_set_ringparam,
.get_pauseparam = sky2_get_pauseparam,
.set_pauseparam = sky2_set_pauseparam,
- .phys_id = sky2_phys_id,
+ .set_phys_id = sky2_set_phys_id,
.get_sset_count = sky2_get_sset_count,
.get_ethtool_stats = sky2_get_ethtool_stats,
- .set_flags = sky2_set_flags,
- .get_flags = ethtool_op_get_flags,
};
#ifdef CONFIG_SKY2_DEBUG
@@ -4553,6 +4505,8 @@ static const struct net_device_ops sky2_netdev_ops[2] = {
.ndo_set_mac_address = sky2_set_mac_address,
.ndo_set_multicast_list = sky2_set_multicast,
.ndo_change_mtu = sky2_change_mtu,
+ .ndo_fix_features = sky2_fix_features,
+ .ndo_set_features = sky2_set_features,
.ndo_tx_timeout = sky2_tx_timeout,
.ndo_get_stats64 = sky2_get_stats,
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -4568,6 +4522,8 @@ static const struct net_device_ops sky2_netdev_ops[2] = {
.ndo_set_mac_address = sky2_set_mac_address,
.ndo_set_multicast_list = sky2_set_multicast,
.ndo_change_mtu = sky2_change_mtu,
+ .ndo_fix_features = sky2_fix_features,
+ .ndo_set_features = sky2_set_features,
.ndo_tx_timeout = sky2_tx_timeout,
.ndo_get_stats64 = sky2_get_stats,
},
@@ -4600,7 +4556,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
/* Auto speed and flow control */
sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE;
if (hw->chip_id != CHIP_ID_YUKON_XL)
- sky2->flags |= SKY2_FLAG_RX_CHECKSUM;
+ dev->hw_features |= NETIF_F_RXCSUM;
sky2->flow_mode = FC_BOTH;
@@ -4619,18 +4575,21 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
sky2->port = port;
- dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG
- | NETIF_F_TSO | NETIF_F_GRO;
+ dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO;
if (highmem)
dev->features |= NETIF_F_HIGHDMA;
/* Enable receive hashing unless hardware is known broken */
if (!(hw->flags & SKY2_HW_RSS_BROKEN))
- dev->features |= NETIF_F_RXHASH;
+ dev->hw_features |= NETIF_F_RXHASH;
+
+ if (!(hw->flags & SKY2_HW_VLAN_BROKEN)) {
+ dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ dev->vlan_features |= SKY2_VLAN_OFFLOADS;
+ }
- if (!(hw->flags & SKY2_HW_VLAN_BROKEN))
- dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ dev->features |= dev->hw_features;
/* read the mac address */
memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 0c6d10c5f05..318c9ae7bf9 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -2254,7 +2254,6 @@ struct sky2_port {
u8 wol; /* WAKE_ bits */
u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */
u16 flags;
-#define SKY2_FLAG_RX_CHECKSUM 0x0001
#define SKY2_FLAG_AUTO_SPEED 0x0002
#define SKY2_FLAG_AUTO_PAUSE 0x0004
diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c
index d07c39cb4da..0f29f261fcf 100644
--- a/drivers/net/smc-mca.c
+++ b/drivers/net/smc-mca.c
@@ -156,7 +156,7 @@ static const struct {
{ 14, 15 }
};
-static short smc_mca_adapter_ids[] __initdata = {
+static const short smc_mca_adapter_ids[] __devinitconst = {
0x61c8,
0x61c9,
0x6fc0,
@@ -168,7 +168,7 @@ static short smc_mca_adapter_ids[] __initdata = {
0x0000
};
-static char *smc_mca_adapter_names[] __initdata = {
+static const char *const smc_mca_adapter_names[] __devinitconst = {
"SMC Ethercard PLUS Elite/A BNC/AUI (WD8013EP/A)",
"SMC Ethercard PLUS Elite/A UTP/AUI (WD8013WP/A)",
"WD Ethercard PLUS/A (WD8003E/A or WD8003ET/A)",
@@ -199,7 +199,7 @@ static const struct net_device_ops ultramca_netdev_ops = {
#endif
};
-static int __init ultramca_probe(struct device *gen_dev)
+static int __devinit ultramca_probe(struct device *gen_dev)
{
unsigned short ioaddr;
struct net_device *dev;
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 66831f37839..053863aefb1 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -1488,9 +1488,9 @@ smc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
SUPPORTED_TP | SUPPORTED_AUI;
if (lp->ctl_rspeed == 10)
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
else if (lp->ctl_rspeed == 100)
- cmd->speed = SPEED_100;
+ ethtool_cmd_speed_set(cmd, SPEED_100);
cmd->autoneg = AUTONEG_DISABLE;
if (lp->mii.phy_id==1)
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 43654a3bb0e..dc4805f473e 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -1565,9 +1565,9 @@ smc_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
SUPPORTED_TP | SUPPORTED_AUI;
if (lp->ctl_rspeed == 10)
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
else if (lp->ctl_rspeed == 100)
- cmd->speed = SPEED_100;
+ ethtool_cmd_speed_set(cmd, SPEED_100);
cmd->autoneg = AUTONEG_DISABLE;
cmd->transceiver = XCVR_INTERNAL;
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 4b42ecc63dc..c6d47d10590 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -29,6 +29,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/crc32.h>
#include <linux/delay.h>
#include <linux/errno.h>
@@ -69,6 +71,17 @@ static int debug = 3;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+struct smsc911x_data;
+
+struct smsc911x_ops {
+ u32 (*reg_read)(struct smsc911x_data *pdata, u32 reg);
+ void (*reg_write)(struct smsc911x_data *pdata, u32 reg, u32 val);
+ void (*rx_readfifo)(struct smsc911x_data *pdata,
+ unsigned int *buf, unsigned int wordcount);
+ void (*tx_writefifo)(struct smsc911x_data *pdata,
+ unsigned int *buf, unsigned int wordcount);
+};
+
struct smsc911x_data {
void __iomem *ioaddr;
@@ -116,8 +129,14 @@ struct smsc911x_data {
unsigned int clear_bits_mask;
unsigned int hashhi;
unsigned int hashlo;
+
+ /* register access functions */
+ const struct smsc911x_ops *ops;
};
+/* Easy access to information */
+#define __smsc_shift(pdata, reg) ((reg) << ((pdata)->config.shift))
+
static inline u32 __smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg)
{
if (pdata->config.flags & SMSC911X_USE_32BIT)
@@ -131,13 +150,29 @@ static inline u32 __smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg)
return 0;
}
+static inline u32
+__smsc911x_reg_read_shift(struct smsc911x_data *pdata, u32 reg)
+{
+ if (pdata->config.flags & SMSC911X_USE_32BIT)
+ return readl(pdata->ioaddr + __smsc_shift(pdata, reg));
+
+ if (pdata->config.flags & SMSC911X_USE_16BIT)
+ return (readw(pdata->ioaddr +
+ __smsc_shift(pdata, reg)) & 0xFFFF) |
+ ((readw(pdata->ioaddr +
+ __smsc_shift(pdata, reg + 2)) & 0xFFFF) << 16);
+
+ BUG();
+ return 0;
+}
+
static inline u32 smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg)
{
u32 data;
unsigned long flags;
spin_lock_irqsave(&pdata->dev_lock, flags);
- data = __smsc911x_reg_read(pdata, reg);
+ data = pdata->ops->reg_read(pdata, reg);
spin_unlock_irqrestore(&pdata->dev_lock, flags);
return data;
@@ -160,13 +195,32 @@ static inline void __smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg,
BUG();
}
+static inline void
+__smsc911x_reg_write_shift(struct smsc911x_data *pdata, u32 reg, u32 val)
+{
+ if (pdata->config.flags & SMSC911X_USE_32BIT) {
+ writel(val, pdata->ioaddr + __smsc_shift(pdata, reg));
+ return;
+ }
+
+ if (pdata->config.flags & SMSC911X_USE_16BIT) {
+ writew(val & 0xFFFF,
+ pdata->ioaddr + __smsc_shift(pdata, reg));
+ writew((val >> 16) & 0xFFFF,
+ pdata->ioaddr + __smsc_shift(pdata, reg + 2));
+ return;
+ }
+
+ BUG();
+}
+
static inline void smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg,
u32 val)
{
unsigned long flags;
spin_lock_irqsave(&pdata->dev_lock, flags);
- __smsc911x_reg_write(pdata, reg, val);
+ pdata->ops->reg_write(pdata, reg, val);
spin_unlock_irqrestore(&pdata->dev_lock, flags);
}
@@ -202,6 +256,40 @@ out:
spin_unlock_irqrestore(&pdata->dev_lock, flags);
}
+/* Writes a packet to the TX_DATA_FIFO - shifted version */
+static inline void
+smsc911x_tx_writefifo_shift(struct smsc911x_data *pdata, unsigned int *buf,
+ unsigned int wordcount)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&pdata->dev_lock, flags);
+
+ if (pdata->config.flags & SMSC911X_SWAP_FIFO) {
+ while (wordcount--)
+ __smsc911x_reg_write_shift(pdata, TX_DATA_FIFO,
+ swab32(*buf++));
+ goto out;
+ }
+
+ if (pdata->config.flags & SMSC911X_USE_32BIT) {
+ writesl(pdata->ioaddr + __smsc_shift(pdata,
+ TX_DATA_FIFO), buf, wordcount);
+ goto out;
+ }
+
+ if (pdata->config.flags & SMSC911X_USE_16BIT) {
+ while (wordcount--)
+ __smsc911x_reg_write_shift(pdata,
+ TX_DATA_FIFO, *buf++);
+ goto out;
+ }
+
+ BUG();
+out:
+ spin_unlock_irqrestore(&pdata->dev_lock, flags);
+}
+
/* Reads a packet out of the RX_DATA_FIFO */
static inline void
smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf,
@@ -234,6 +322,40 @@ out:
spin_unlock_irqrestore(&pdata->dev_lock, flags);
}
+/* Reads a packet out of the RX_DATA_FIFO - shifted version */
+static inline void
+smsc911x_rx_readfifo_shift(struct smsc911x_data *pdata, unsigned int *buf,
+ unsigned int wordcount)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&pdata->dev_lock, flags);
+
+ if (pdata->config.flags & SMSC911X_SWAP_FIFO) {
+ while (wordcount--)
+ *buf++ = swab32(__smsc911x_reg_read_shift(pdata,
+ RX_DATA_FIFO));
+ goto out;
+ }
+
+ if (pdata->config.flags & SMSC911X_USE_32BIT) {
+ readsl(pdata->ioaddr + __smsc_shift(pdata,
+ RX_DATA_FIFO), buf, wordcount);
+ goto out;
+ }
+
+ if (pdata->config.flags & SMSC911X_USE_16BIT) {
+ while (wordcount--)
+ *buf++ = __smsc911x_reg_read_shift(pdata,
+ RX_DATA_FIFO);
+ goto out;
+ }
+
+ BUG();
+out:
+ spin_unlock_irqrestore(&pdata->dev_lock, flags);
+}
+
/* waits for MAC not busy, with timeout. Only called by smsc911x_mac_read
* and smsc911x_mac_write, so assumes mac_lock is held */
static int smsc911x_mac_complete(struct smsc911x_data *pdata)
@@ -248,8 +370,8 @@ static int smsc911x_mac_complete(struct smsc911x_data *pdata)
if (!(val & MAC_CSR_CMD_CSR_BUSY_))
return 0;
}
- SMSC_WARNING(HW, "Timed out waiting for MAC not BUSY. "
- "MAC_CSR_CMD: 0x%08X", val);
+ SMSC_WARN(pdata, hw, "Timed out waiting for MAC not BUSY. "
+ "MAC_CSR_CMD: 0x%08X", val);
return -EIO;
}
@@ -262,7 +384,7 @@ static u32 smsc911x_mac_read(struct smsc911x_data *pdata, unsigned int offset)
temp = smsc911x_reg_read(pdata, MAC_CSR_CMD);
if (unlikely(temp & MAC_CSR_CMD_CSR_BUSY_)) {
- SMSC_WARNING(HW, "MAC busy at entry");
+ SMSC_WARN(pdata, hw, "MAC busy at entry");
return 0xFFFFFFFF;
}
@@ -277,7 +399,7 @@ static u32 smsc911x_mac_read(struct smsc911x_data *pdata, unsigned int offset)
if (likely(smsc911x_mac_complete(pdata) == 0))
return smsc911x_reg_read(pdata, MAC_CSR_DATA);
- SMSC_WARNING(HW, "MAC busy after read");
+ SMSC_WARN(pdata, hw, "MAC busy after read");
return 0xFFFFFFFF;
}
@@ -291,8 +413,8 @@ static void smsc911x_mac_write(struct smsc911x_data *pdata,
temp = smsc911x_reg_read(pdata, MAC_CSR_CMD);
if (unlikely(temp & MAC_CSR_CMD_CSR_BUSY_)) {
- SMSC_WARNING(HW,
- "smsc911x_mac_write failed, MAC busy at entry");
+ SMSC_WARN(pdata, hw,
+ "smsc911x_mac_write failed, MAC busy at entry");
return;
}
@@ -310,8 +432,7 @@ static void smsc911x_mac_write(struct smsc911x_data *pdata,
if (likely(smsc911x_mac_complete(pdata) == 0))
return;
- SMSC_WARNING(HW,
- "smsc911x_mac_write failed, MAC busy after write");
+ SMSC_WARN(pdata, hw, "smsc911x_mac_write failed, MAC busy after write");
}
/* Get a phy register */
@@ -326,8 +447,7 @@ static int smsc911x_mii_read(struct mii_bus *bus, int phyaddr, int regidx)
/* Confirm MII not busy */
if (unlikely(smsc911x_mac_read(pdata, MII_ACC) & MII_ACC_MII_BUSY_)) {
- SMSC_WARNING(HW,
- "MII is busy in smsc911x_mii_read???");
+ SMSC_WARN(pdata, hw, "MII is busy in smsc911x_mii_read???");
reg = -EIO;
goto out;
}
@@ -343,7 +463,7 @@ static int smsc911x_mii_read(struct mii_bus *bus, int phyaddr, int regidx)
goto out;
}
- SMSC_WARNING(HW, "Timed out waiting for MII read to finish");
+ SMSC_WARN(pdata, hw, "Timed out waiting for MII read to finish");
reg = -EIO;
out:
@@ -364,8 +484,7 @@ static int smsc911x_mii_write(struct mii_bus *bus, int phyaddr, int regidx,
/* Confirm MII not busy */
if (unlikely(smsc911x_mac_read(pdata, MII_ACC) & MII_ACC_MII_BUSY_)) {
- SMSC_WARNING(HW,
- "MII is busy in smsc911x_mii_write???");
+ SMSC_WARN(pdata, hw, "MII is busy in smsc911x_mii_write???");
reg = -EIO;
goto out;
}
@@ -385,7 +504,7 @@ static int smsc911x_mii_write(struct mii_bus *bus, int phyaddr, int regidx,
goto out;
}
- SMSC_WARNING(HW, "Timed out waiting for MII write to finish");
+ SMSC_WARN(pdata, hw, "Timed out waiting for MII write to finish");
reg = -EIO;
out:
@@ -426,18 +545,20 @@ static void smsc911x_phy_initialise_external(struct smsc911x_data *pdata)
unsigned int hwcfg = smsc911x_reg_read(pdata, HW_CFG);
if (pdata->config.flags & SMSC911X_FORCE_INTERNAL_PHY) {
- SMSC_TRACE(HW, "Forcing internal PHY");
+ SMSC_TRACE(pdata, hw, "Forcing internal PHY");
pdata->using_extphy = 0;
} else if (pdata->config.flags & SMSC911X_FORCE_EXTERNAL_PHY) {
- SMSC_TRACE(HW, "Forcing external PHY");
+ SMSC_TRACE(pdata, hw, "Forcing external PHY");
smsc911x_phy_enable_external(pdata);
pdata->using_extphy = 1;
} else if (hwcfg & HW_CFG_EXT_PHY_DET_) {
- SMSC_TRACE(HW, "HW_CFG EXT_PHY_DET set, using external PHY");
+ SMSC_TRACE(pdata, hw,
+ "HW_CFG EXT_PHY_DET set, using external PHY");
smsc911x_phy_enable_external(pdata);
pdata->using_extphy = 1;
} else {
- SMSC_TRACE(HW, "HW_CFG EXT_PHY_DET clear, using internal PHY");
+ SMSC_TRACE(pdata, hw,
+ "HW_CFG EXT_PHY_DET clear, using internal PHY");
pdata->using_extphy = 0;
}
}
@@ -499,7 +620,7 @@ static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata)
wrsz += (u32)((ulong)pdata->loopback_tx_pkt & 0x3);
wrsz >>= 2;
- smsc911x_tx_writefifo(pdata, (unsigned int *)bufp, wrsz);
+ pdata->ops->tx_writefifo(pdata, (unsigned int *)bufp, wrsz);
/* Wait till transmit is done */
i = 60;
@@ -509,13 +630,13 @@ static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata)
} while ((i--) && (!status));
if (!status) {
- SMSC_WARNING(HW, "Failed to transmit "
- "during loopback test");
+ SMSC_WARN(pdata, hw,
+ "Failed to transmit during loopback test");
continue;
}
if (status & TX_STS_ES_) {
- SMSC_WARNING(HW, "Transmit encountered "
- "errors during loopback test");
+ SMSC_WARN(pdata, hw,
+ "Transmit encountered errors during loopback test");
continue;
}
@@ -527,13 +648,13 @@ static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata)
} while ((i--) && (!status));
if (!status) {
- SMSC_WARNING(HW,
- "Failed to receive during loopback test");
+ SMSC_WARN(pdata, hw,
+ "Failed to receive during loopback test");
continue;
}
if (status & RX_STS_ES_) {
- SMSC_WARNING(HW, "Receive encountered "
- "errors during loopback test");
+ SMSC_WARN(pdata, hw,
+ "Receive encountered errors during loopback test");
continue;
}
@@ -543,12 +664,12 @@ static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata)
rdsz += (u32)((ulong)pdata->loopback_rx_pkt & 0x3);
rdsz >>= 2;
- smsc911x_rx_readfifo(pdata, (unsigned int *)bufp, rdsz);
+ pdata->ops->rx_readfifo(pdata, (unsigned int *)bufp, rdsz);
if (pktlength != (MIN_PACKET_SIZE + 4)) {
- SMSC_WARNING(HW, "Unexpected packet size "
- "during loop back test, size=%d, will retry",
- pktlength);
+ SMSC_WARN(pdata, hw, "Unexpected packet size "
+ "during loop back test, size=%d, will retry",
+ pktlength);
} else {
unsigned int j;
int mismatch = 0;
@@ -560,12 +681,12 @@ static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata)
}
}
if (!mismatch) {
- SMSC_TRACE(HW, "Successfully verified "
+ SMSC_TRACE(pdata, hw, "Successfully verified "
"loopback packet");
return 0;
} else {
- SMSC_WARNING(HW, "Data mismatch "
- "during loop back test, will retry");
+ SMSC_WARN(pdata, hw, "Data mismatch "
+ "during loop back test, will retry");
}
}
}
@@ -582,7 +703,7 @@ static int smsc911x_phy_reset(struct smsc911x_data *pdata)
BUG_ON(!phy_dev);
BUG_ON(!phy_dev->bus);
- SMSC_TRACE(HW, "Performing PHY BCR Reset");
+ SMSC_TRACE(pdata, hw, "Performing PHY BCR Reset");
smsc911x_mii_write(phy_dev->bus, phy_dev->addr, MII_BMCR, BMCR_RESET);
do {
msleep(1);
@@ -591,7 +712,7 @@ static int smsc911x_phy_reset(struct smsc911x_data *pdata)
} while ((i--) && (temp & BMCR_RESET));
if (temp & BMCR_RESET) {
- SMSC_WARNING(HW, "PHY reset failed to complete.");
+ SMSC_WARN(pdata, hw, "PHY reset failed to complete");
return -EIO;
}
/* Extra delay required because the phy may not be completed with
@@ -695,11 +816,11 @@ static void smsc911x_phy_update_flowcontrol(struct smsc911x_data *pdata)
else
afc &= ~0xF;
- SMSC_TRACE(HW, "rx pause %s, tx pause %s",
- (cap & FLOW_CTRL_RX ? "enabled" : "disabled"),
- (cap & FLOW_CTRL_TX ? "enabled" : "disabled"));
+ SMSC_TRACE(pdata, hw, "rx pause %s, tx pause %s",
+ (cap & FLOW_CTRL_RX ? "enabled" : "disabled"),
+ (cap & FLOW_CTRL_TX ? "enabled" : "disabled"));
} else {
- SMSC_TRACE(HW, "half duplex");
+ SMSC_TRACE(pdata, hw, "half duplex");
flow = 0;
afc |= 0xF;
}
@@ -722,17 +843,17 @@ static void smsc911x_phy_adjust_link(struct net_device *dev)
if (phy_dev->duplex != pdata->last_duplex) {
unsigned int mac_cr;
- SMSC_TRACE(HW, "duplex state has changed");
+ SMSC_TRACE(pdata, hw, "duplex state has changed");
spin_lock_irqsave(&pdata->mac_lock, flags);
mac_cr = smsc911x_mac_read(pdata, MAC_CR);
if (phy_dev->duplex) {
- SMSC_TRACE(HW,
- "configuring for full duplex mode");
+ SMSC_TRACE(pdata, hw,
+ "configuring for full duplex mode");
mac_cr |= MAC_CR_FDPX_;
} else {
- SMSC_TRACE(HW,
- "configuring for half duplex mode");
+ SMSC_TRACE(pdata, hw,
+ "configuring for half duplex mode");
mac_cr &= ~MAC_CR_FDPX_;
}
smsc911x_mac_write(pdata, MAC_CR, mac_cr);
@@ -744,9 +865,9 @@ static void smsc911x_phy_adjust_link(struct net_device *dev)
carrier = netif_carrier_ok(dev);
if (carrier != pdata->last_carrier) {
- SMSC_TRACE(HW, "carrier state has changed");
+ SMSC_TRACE(pdata, hw, "carrier state has changed");
if (carrier) {
- SMSC_TRACE(HW, "configuring for carrier OK");
+ SMSC_TRACE(pdata, hw, "configuring for carrier OK");
if ((pdata->gpio_orig_setting & GPIO_CFG_LED1_EN_) &&
(!pdata->using_extphy)) {
/* Restore original GPIO configuration */
@@ -755,7 +876,7 @@ static void smsc911x_phy_adjust_link(struct net_device *dev)
pdata->gpio_setting);
}
} else {
- SMSC_TRACE(HW, "configuring for no carrier");
+ SMSC_TRACE(pdata, hw, "configuring for no carrier");
/* Check global setting that LED1
* usage is 10/100 indicator */
pdata->gpio_setting = smsc911x_reg_read(pdata,
@@ -787,25 +908,25 @@ static int smsc911x_mii_probe(struct net_device *dev)
/* find the first phy */
phydev = phy_find_first(pdata->mii_bus);
if (!phydev) {
- pr_err("%s: no PHY found\n", dev->name);
+ netdev_err(dev, "no PHY found\n");
return -ENODEV;
}
- SMSC_TRACE(PROBE, "PHY: addr %d, phy_id 0x%08X",
- phydev->addr, phydev->phy_id);
+ SMSC_TRACE(pdata, probe, "PHY: addr %d, phy_id 0x%08X",
+ phydev->addr, phydev->phy_id);
ret = phy_connect_direct(dev, phydev,
&smsc911x_phy_adjust_link, 0,
pdata->config.phy_interface);
if (ret) {
- pr_err("%s: Could not attach to PHY\n", dev->name);
+ netdev_err(dev, "Could not attach to PHY\n");
return ret;
}
- pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name,
- dev_name(&phydev->dev), phydev->irq);
+ netdev_info(dev,
+ "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
+ phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
/* mask with MAC supported features */
phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
@@ -818,13 +939,13 @@ static int smsc911x_mii_probe(struct net_device *dev)
#ifdef USE_PHY_WORK_AROUND
if (smsc911x_phy_loopbacktest(dev) < 0) {
- SMSC_WARNING(HW, "Failed Loop Back Test");
+ SMSC_WARN(pdata, hw, "Failed Loop Back Test");
return -ENODEV;
}
- SMSC_TRACE(HW, "Passed Loop Back Test");
+ SMSC_TRACE(pdata, hw, "Passed Loop Back Test");
#endif /* USE_PHY_WORK_AROUND */
- SMSC_TRACE(HW, "phy initialised successfully");
+ SMSC_TRACE(pdata, hw, "phy initialised successfully");
return 0;
}
@@ -860,8 +981,8 @@ static int __devinit smsc911x_mii_init(struct platform_device *pdev,
smsc911x_phy_initialise_external(pdata);
break;
default:
- SMSC_TRACE(HW, "External PHY is not supported, "
- "using internal PHY");
+ SMSC_TRACE(pdata, hw, "External PHY is not supported, "
+ "using internal PHY");
pdata->using_extphy = 0;
break;
}
@@ -872,12 +993,12 @@ static int __devinit smsc911x_mii_init(struct platform_device *pdev,
}
if (mdiobus_register(pdata->mii_bus)) {
- SMSC_WARNING(PROBE, "Error registering mii bus");
+ SMSC_WARN(pdata, probe, "Error registering mii bus");
goto err_out_free_bus_2;
}
if (smsc911x_mii_probe(dev) < 0) {
- SMSC_WARNING(PROBE, "Error registering mii bus");
+ SMSC_WARN(pdata, probe, "Error registering mii bus");
goto err_out_unregister_bus_3;
}
@@ -913,8 +1034,7 @@ static void smsc911x_tx_update_txcounters(struct net_device *dev)
* does not reference a hardware defined reserved bit
* but rather a driver defined one.
*/
- SMSC_WARNING(HW,
- "Packet tag reserved bit is high");
+ SMSC_WARN(pdata, hw, "Packet tag reserved bit is high");
} else {
if (unlikely(tx_stat & TX_STS_ES_)) {
dev->stats.tx_errors++;
@@ -977,8 +1097,8 @@ smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes)
} while ((val & RX_DP_CTRL_RX_FFWD_) && --timeout);
if (unlikely(timeout == 0))
- SMSC_WARNING(HW, "Timed out waiting for "
- "RX FFWD to finish, RX_DP_CTRL: 0x%08X", val);
+ SMSC_WARN(pdata, hw, "Timed out waiting for "
+ "RX FFWD to finish, RX_DP_CTRL: 0x%08X", val);
} else {
unsigned int temp;
while (pktwords--)
@@ -1021,8 +1141,8 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
smsc911x_rx_counterrors(dev, rxstat);
if (unlikely(rxstat & RX_STS_ES_)) {
- SMSC_WARNING(RX_ERR,
- "Discarding packet with error bit set");
+ SMSC_WARN(pdata, rx_err,
+ "Discarding packet with error bit set");
/* Packet has an error, discard it and continue with
* the next */
smsc911x_rx_fastforward(pdata, pktwords);
@@ -1032,8 +1152,8 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN);
if (unlikely(!skb)) {
- SMSC_WARNING(RX_ERR,
- "Unable to allocate skb for rx packet");
+ SMSC_WARN(pdata, rx_err,
+ "Unable to allocate skb for rx packet");
/* Drop the packet and stop this polling iteration */
smsc911x_rx_fastforward(pdata, pktwords);
dev->stats.rx_dropped++;
@@ -1046,8 +1166,8 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
/* Align IP on 16B boundary */
skb_reserve(skb, NET_IP_ALIGN);
skb_put(skb, pktlength - 4);
- smsc911x_rx_readfifo(pdata, (unsigned int *)skb->head,
- pktwords);
+ pdata->ops->rx_readfifo(pdata,
+ (unsigned int *)skb->head, pktwords);
skb->protocol = eth_type_trans(skb, dev);
skb_checksum_none_assert(skb);
netif_receive_skb(skb);
@@ -1083,8 +1203,8 @@ static void smsc911x_rx_multicast_update(struct smsc911x_data *pdata)
smsc911x_mac_write(pdata, MAC_CR, mac_cr);
smsc911x_mac_write(pdata, HASHH, pdata->hashhi);
smsc911x_mac_write(pdata, HASHL, pdata->hashlo);
- SMSC_TRACE(HW, "maccr 0x%08X, HASHH 0x%08X, HASHL 0x%08X",
- mac_cr, pdata->hashhi, pdata->hashlo);
+ SMSC_TRACE(pdata, hw, "maccr 0x%08X, HASHH 0x%08X, HASHL 0x%08X",
+ mac_cr, pdata->hashhi, pdata->hashlo);
}
static void smsc911x_rx_multicast_update_workaround(struct smsc911x_data *pdata)
@@ -1102,7 +1222,7 @@ static void smsc911x_rx_multicast_update_workaround(struct smsc911x_data *pdata)
/* Check Rx has stopped */
if (smsc911x_mac_read(pdata, MAC_CR) & MAC_CR_RXEN_)
- SMSC_WARNING(DRV, "Rx not stopped");
+ SMSC_WARN(pdata, drv, "Rx not stopped");
/* Perform the update - safe to do now Rx has stopped */
smsc911x_rx_multicast_update(pdata);
@@ -1131,7 +1251,7 @@ static int smsc911x_soft_reset(struct smsc911x_data *pdata)
} while ((--timeout) && (temp & HW_CFG_SRST_));
if (unlikely(temp & HW_CFG_SRST_)) {
- SMSC_WARNING(DRV, "Failed to complete reset");
+ SMSC_WARN(pdata, drv, "Failed to complete reset");
return -EIO;
}
return 0;
@@ -1160,18 +1280,18 @@ static int smsc911x_open(struct net_device *dev)
/* if the phy is not yet registered, retry later*/
if (!pdata->phy_dev) {
- SMSC_WARNING(HW, "phy_dev is NULL");
+ SMSC_WARN(pdata, hw, "phy_dev is NULL");
return -EAGAIN;
}
if (!is_valid_ether_addr(dev->dev_addr)) {
- SMSC_WARNING(HW, "dev_addr is not a valid MAC address");
+ SMSC_WARN(pdata, hw, "dev_addr is not a valid MAC address");
return -EADDRNOTAVAIL;
}
/* Reset the LAN911x */
if (smsc911x_soft_reset(pdata)) {
- SMSC_WARNING(HW, "soft reset failed");
+ SMSC_WARN(pdata, hw, "soft reset failed");
return -EIO;
}
@@ -1191,8 +1311,8 @@ static int smsc911x_open(struct net_device *dev)
}
if (unlikely(timeout == 0))
- SMSC_WARNING(IFUP,
- "Timed out waiting for EEPROM busy bit to clear");
+ SMSC_WARN(pdata, ifup,
+ "Timed out waiting for EEPROM busy bit to clear");
smsc911x_reg_write(pdata, GPIO_CFG, 0x70070000);
@@ -1210,22 +1330,22 @@ static int smsc911x_open(struct net_device *dev)
intcfg = ((10 << 24) | INT_CFG_IRQ_EN_);
if (pdata->config.irq_polarity) {
- SMSC_TRACE(IFUP, "irq polarity: active high");
+ SMSC_TRACE(pdata, ifup, "irq polarity: active high");
intcfg |= INT_CFG_IRQ_POL_;
} else {
- SMSC_TRACE(IFUP, "irq polarity: active low");
+ SMSC_TRACE(pdata, ifup, "irq polarity: active low");
}
if (pdata->config.irq_type) {
- SMSC_TRACE(IFUP, "irq type: push-pull");
+ SMSC_TRACE(pdata, ifup, "irq type: push-pull");
intcfg |= INT_CFG_IRQ_TYPE_;
} else {
- SMSC_TRACE(IFUP, "irq type: open drain");
+ SMSC_TRACE(pdata, ifup, "irq type: open drain");
}
smsc911x_reg_write(pdata, INT_CFG, intcfg);
- SMSC_TRACE(IFUP, "Testing irq handler using IRQ %d", dev->irq);
+ SMSC_TRACE(pdata, ifup, "Testing irq handler using IRQ %d", dev->irq);
pdata->software_irq_signal = 0;
smp_wmb();
@@ -1241,14 +1361,15 @@ static int smsc911x_open(struct net_device *dev)
}
if (!pdata->software_irq_signal) {
- dev_warn(&dev->dev, "ISR failed signaling test (IRQ %d)\n",
- dev->irq);
+ netdev_warn(dev, "ISR failed signaling test (IRQ %d)\n",
+ dev->irq);
return -ENODEV;
}
- SMSC_TRACE(IFUP, "IRQ handler passed test using IRQ %d", dev->irq);
+ SMSC_TRACE(pdata, ifup, "IRQ handler passed test using IRQ %d",
+ dev->irq);
- dev_info(&dev->dev, "SMSC911x/921x identified at %#08lx, IRQ: %d\n",
- (unsigned long)pdata->ioaddr, dev->irq);
+ netdev_info(dev, "SMSC911x/921x identified at %#08lx, IRQ: %d\n",
+ (unsigned long)pdata->ioaddr, dev->irq);
/* Reset the last known duplex and carrier */
pdata->last_duplex = -1;
@@ -1313,7 +1434,7 @@ static int smsc911x_stop(struct net_device *dev)
if (pdata->phy_dev)
phy_stop(pdata->phy_dev);
- SMSC_TRACE(IFDOWN, "Interface stopped");
+ SMSC_TRACE(pdata, ifdown, "Interface stopped");
return 0;
}
@@ -1331,8 +1452,8 @@ static int smsc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
freespace = smsc911x_reg_read(pdata, TX_FIFO_INF) & TX_FIFO_INF_TDFREE_;
if (unlikely(freespace < TX_FIFO_LOW_THRESHOLD))
- SMSC_WARNING(TX_ERR,
- "Tx data fifo low, space available: %d", freespace);
+ SMSC_WARN(pdata, tx_err,
+ "Tx data fifo low, space available: %d", freespace);
/* Word alignment adjustment */
tx_cmd_a = (u32)((ulong)skb->data & 0x03) << 16;
@@ -1350,7 +1471,7 @@ static int smsc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
wrsz += (u32)((ulong)skb->data & 0x3);
wrsz >>= 2;
- smsc911x_tx_writefifo(pdata, (unsigned int *)bufp, wrsz);
+ pdata->ops->tx_writefifo(pdata, (unsigned int *)bufp, wrsz);
freespace -= (skb->len + 32);
dev_kfree_skb(skb);
@@ -1432,7 +1553,7 @@ static void smsc911x_set_multicast_list(struct net_device *dev)
* receiving data */
if (!pdata->multicast_update_pending) {
unsigned int temp;
- SMSC_TRACE(HW, "scheduling mcast update");
+ SMSC_TRACE(pdata, hw, "scheduling mcast update");
pdata->multicast_update_pending = 1;
/* Request the hardware to stop, then perform the
@@ -1474,7 +1595,7 @@ static irqreturn_t smsc911x_irqhandler(int irq, void *dev_id)
if (unlikely(intsts & inten & INT_STS_RXSTOP_INT_)) {
/* Called when there is a multicast update scheduled and
* it is now safe to complete the update */
- SMSC_TRACE(INTR, "RX Stop interrupt");
+ SMSC_TRACE(pdata, intr, "RX Stop interrupt");
smsc911x_reg_write(pdata, INT_STS, INT_STS_RXSTOP_INT_);
if (pdata->multicast_update_pending)
smsc911x_rx_multicast_update_workaround(pdata);
@@ -1491,7 +1612,7 @@ static irqreturn_t smsc911x_irqhandler(int irq, void *dev_id)
}
if (unlikely(intsts & inten & INT_STS_RXE_)) {
- SMSC_TRACE(INTR, "RX Error interrupt");
+ SMSC_TRACE(pdata, intr, "RX Error interrupt");
smsc911x_reg_write(pdata, INT_STS, INT_STS_RXE_);
serviced = IRQ_HANDLED;
}
@@ -1505,8 +1626,7 @@ static irqreturn_t smsc911x_irqhandler(int irq, void *dev_id)
/* Schedule a NAPI poll */
__napi_schedule(&pdata->napi);
} else {
- SMSC_WARNING(RX_ERR,
- "napi_schedule_prep failed");
+ SMSC_WARN(pdata, rx_err, "napi_schedule_prep failed");
}
serviced = IRQ_HANDLED;
}
@@ -1543,7 +1663,7 @@ static int smsc911x_set_mac_address(struct net_device *dev, void *p)
smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
spin_unlock_irq(&pdata->mac_lock);
- dev_info(&dev->dev, "MAC Address: %pM\n", dev->dev_addr);
+ netdev_info(dev, "MAC Address: %pM\n", dev->dev_addr);
return 0;
}
@@ -1649,9 +1769,9 @@ static int smsc911x_eeprom_send_cmd(struct smsc911x_data *pdata, u32 op)
int timeout = 100;
u32 e2cmd;
- SMSC_TRACE(DRV, "op 0x%08x", op);
+ SMSC_TRACE(pdata, drv, "op 0x%08x", op);
if (smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_) {
- SMSC_WARNING(DRV, "Busy at start");
+ SMSC_WARN(pdata, drv, "Busy at start");
return -EBUSY;
}
@@ -1664,12 +1784,12 @@ static int smsc911x_eeprom_send_cmd(struct smsc911x_data *pdata, u32 op)
} while ((e2cmd & E2P_CMD_EPC_BUSY_) && (--timeout));
if (!timeout) {
- SMSC_TRACE(DRV, "TIMED OUT");
+ SMSC_TRACE(pdata, drv, "TIMED OUT");
return -EAGAIN;
}
if (e2cmd & E2P_CMD_EPC_TIMEOUT_) {
- SMSC_TRACE(DRV, "Error occurred during eeprom operation");
+ SMSC_TRACE(pdata, drv, "Error occurred during eeprom operation");
return -EINVAL;
}
@@ -1682,7 +1802,7 @@ static int smsc911x_eeprom_read_location(struct smsc911x_data *pdata,
u32 op = E2P_CMD_EPC_CMD_READ_ | address;
int ret;
- SMSC_TRACE(DRV, "address 0x%x", address);
+ SMSC_TRACE(pdata, drv, "address 0x%x", address);
ret = smsc911x_eeprom_send_cmd(pdata, op);
if (!ret)
@@ -1698,7 +1818,7 @@ static int smsc911x_eeprom_write_location(struct smsc911x_data *pdata,
u32 temp;
int ret;
- SMSC_TRACE(DRV, "address 0x%x, data 0x%x", address, data);
+ SMSC_TRACE(pdata, drv, "address 0x%x, data 0x%x", address, data);
ret = smsc911x_eeprom_send_cmd(pdata, op);
if (!ret) {
@@ -1811,26 +1931,26 @@ static int __devinit smsc911x_init(struct net_device *dev)
struct smsc911x_data *pdata = netdev_priv(dev);
unsigned int byte_test;
- SMSC_TRACE(PROBE, "Driver Parameters:");
- SMSC_TRACE(PROBE, "LAN base: 0x%08lX",
- (unsigned long)pdata->ioaddr);
- SMSC_TRACE(PROBE, "IRQ: %d", dev->irq);
- SMSC_TRACE(PROBE, "PHY will be autodetected.");
+ SMSC_TRACE(pdata, probe, "Driver Parameters:");
+ SMSC_TRACE(pdata, probe, "LAN base: 0x%08lX",
+ (unsigned long)pdata->ioaddr);
+ SMSC_TRACE(pdata, probe, "IRQ: %d", dev->irq);
+ SMSC_TRACE(pdata, probe, "PHY will be autodetected.");
spin_lock_init(&pdata->dev_lock);
spin_lock_init(&pdata->mac_lock);
if (pdata->ioaddr == 0) {
- SMSC_WARNING(PROBE, "pdata->ioaddr: 0x00000000");
+ SMSC_WARN(pdata, probe, "pdata->ioaddr: 0x00000000");
return -ENODEV;
}
/* Check byte ordering */
byte_test = smsc911x_reg_read(pdata, BYTE_TEST);
- SMSC_TRACE(PROBE, "BYTE_TEST: 0x%08X", byte_test);
+ SMSC_TRACE(pdata, probe, "BYTE_TEST: 0x%08X", byte_test);
if (byte_test == 0x43218765) {
- SMSC_TRACE(PROBE, "BYTE_TEST looks swapped, "
- "applying WORD_SWAP");
+ SMSC_TRACE(pdata, probe, "BYTE_TEST looks swapped, "
+ "applying WORD_SWAP");
smsc911x_reg_write(pdata, WORD_SWAP, 0xffffffff);
/* 1 dummy read of BYTE_TEST is needed after a write to
@@ -1841,12 +1961,13 @@ static int __devinit smsc911x_init(struct net_device *dev)
}
if (byte_test != 0x87654321) {
- SMSC_WARNING(DRV, "BYTE_TEST: 0x%08X", byte_test);
+ SMSC_WARN(pdata, drv, "BYTE_TEST: 0x%08X", byte_test);
if (((byte_test >> 16) & 0xFFFF) == (byte_test & 0xFFFF)) {
- SMSC_WARNING(PROBE,
- "top 16 bits equal to bottom 16 bits");
- SMSC_TRACE(PROBE, "This may mean the chip is set "
- "for 32 bit while the bus is reading 16 bit");
+ SMSC_WARN(pdata, probe,
+ "top 16 bits equal to bottom 16 bits");
+ SMSC_TRACE(pdata, probe,
+ "This may mean the chip is set "
+ "for 32 bit while the bus is reading 16 bit");
}
return -ENODEV;
}
@@ -1881,17 +2002,18 @@ static int __devinit smsc911x_init(struct net_device *dev)
break;
default:
- SMSC_WARNING(PROBE, "LAN911x not identified, idrev: 0x%08X",
- pdata->idrev);
+ SMSC_WARN(pdata, probe, "LAN911x not identified, idrev: 0x%08X",
+ pdata->idrev);
return -ENODEV;
}
- SMSC_TRACE(PROBE, "LAN911x identified, idrev: 0x%08X, generation: %d",
- pdata->idrev, pdata->generation);
+ SMSC_TRACE(pdata, probe,
+ "LAN911x identified, idrev: 0x%08X, generation: %d",
+ pdata->idrev, pdata->generation);
if (pdata->generation == 0)
- SMSC_WARNING(PROBE,
- "This driver is not intended for this chip revision");
+ SMSC_WARN(pdata, probe,
+ "This driver is not intended for this chip revision");
/* workaround for platforms without an eeprom, where the mac address
* is stored elsewhere and set by the bootloader. This saves the
@@ -1931,7 +2053,7 @@ static int __devexit smsc911x_drv_remove(struct platform_device *pdev)
BUG_ON(!pdata->ioaddr);
BUG_ON(!pdata->phy_dev);
- SMSC_TRACE(IFDOWN, "Stopping driver.");
+ SMSC_TRACE(pdata, ifdown, "Stopping driver");
phy_disconnect(pdata->phy_dev);
pdata->phy_dev = NULL;
@@ -1955,6 +2077,22 @@ static int __devexit smsc911x_drv_remove(struct platform_device *pdev)
return 0;
}
+/* standard register acces */
+static const struct smsc911x_ops standard_smsc911x_ops = {
+ .reg_read = __smsc911x_reg_read,
+ .reg_write = __smsc911x_reg_write,
+ .rx_readfifo = smsc911x_rx_readfifo,
+ .tx_writefifo = smsc911x_tx_writefifo,
+};
+
+/* shifted register access */
+static const struct smsc911x_ops shifted_smsc911x_ops = {
+ .reg_read = __smsc911x_reg_read_shift,
+ .reg_write = __smsc911x_reg_write_shift,
+ .rx_readfifo = smsc911x_rx_readfifo_shift,
+ .tx_writefifo = smsc911x_tx_writefifo_shift,
+};
+
static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
{
struct net_device *dev;
@@ -1965,11 +2103,11 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
int res_size, irq_flags;
int retval;
- pr_info("%s: Driver version %s.\n", SMSC_CHIPNAME, SMSC_DRV_VERSION);
+ pr_info("Driver version %s\n", SMSC_DRV_VERSION);
/* platform data specifies irq & dynamic bus configuration */
if (!pdev->dev.platform_data) {
- pr_warning("%s: platform_data not provided\n", SMSC_CHIPNAME);
+ pr_warn("platform_data not provided\n");
retval = -ENODEV;
goto out_0;
}
@@ -1979,8 +2117,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
if (!res)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
- pr_warning("%s: Could not allocate resource.\n",
- SMSC_CHIPNAME);
+ pr_warn("Could not allocate resource\n");
retval = -ENODEV;
goto out_0;
}
@@ -1988,8 +2125,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq_res) {
- pr_warning("%s: Could not allocate irq resource.\n",
- SMSC_CHIPNAME);
+ pr_warn("Could not allocate irq resource\n");
retval = -ENODEV;
goto out_0;
}
@@ -2001,7 +2137,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
dev = alloc_etherdev(sizeof(struct smsc911x_data));
if (!dev) {
- pr_warning("%s: Could not allocate device.\n", SMSC_CHIPNAME);
+ pr_warn("Could not allocate device\n");
retval = -ENOMEM;
goto out_release_io_1;
}
@@ -2021,12 +2157,17 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
pdata->msg_enable = ((1 << debug) - 1);
if (pdata->ioaddr == NULL) {
- SMSC_WARNING(PROBE,
- "Error smsc911x base address invalid");
+ SMSC_WARN(pdata, probe, "Error smsc911x base address invalid");
retval = -ENOMEM;
goto out_free_netdev_2;
}
+ /* assume standard, non-shifted, access to HW registers */
+ pdata->ops = &standard_smsc911x_ops;
+ /* apply the right access if shifting is needed */
+ if (config->shift)
+ pdata->ops = &shifted_smsc911x_ops;
+
retval = smsc911x_init(dev);
if (retval < 0)
goto out_unmap_io_3;
@@ -2047,8 +2188,8 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
retval = request_irq(dev->irq, smsc911x_irqhandler,
irq_flags | IRQF_SHARED, dev->name, dev);
if (retval) {
- SMSC_WARNING(PROBE,
- "Unable to claim requested irq: %d", dev->irq);
+ SMSC_WARN(pdata, probe,
+ "Unable to claim requested irq: %d", dev->irq);
goto out_unmap_io_3;
}
@@ -2056,17 +2197,16 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
retval = register_netdev(dev);
if (retval) {
- SMSC_WARNING(PROBE,
- "Error %i registering device", retval);
+ SMSC_WARN(pdata, probe, "Error %i registering device", retval);
goto out_unset_drvdata_4;
} else {
- SMSC_TRACE(PROBE, "Network interface: \"%s\"", dev->name);
+ SMSC_TRACE(pdata, probe,
+ "Network interface: \"%s\"", dev->name);
}
retval = smsc911x_mii_init(pdev, dev);
if (retval) {
- SMSC_WARNING(PROBE,
- "Error %i initialising mii", retval);
+ SMSC_WARN(pdata, probe, "Error %i initialising mii", retval);
goto out_unregister_netdev_5;
}
@@ -2075,10 +2215,12 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
/* Check if mac address has been specified when bringing interface up */
if (is_valid_ether_addr(dev->dev_addr)) {
smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
- SMSC_TRACE(PROBE, "MAC Address is specified by configuration");
+ SMSC_TRACE(pdata, probe,
+ "MAC Address is specified by configuration");
} else if (is_valid_ether_addr(pdata->config.mac)) {
memcpy(dev->dev_addr, pdata->config.mac, 6);
- SMSC_TRACE(PROBE, "MAC Address specified by platform data");
+ SMSC_TRACE(pdata, probe,
+ "MAC Address specified by platform data");
} else {
/* Try reading mac address from device. if EEPROM is present
* it will already have been set */
@@ -2086,20 +2228,20 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
if (is_valid_ether_addr(dev->dev_addr)) {
/* eeprom values are valid so use them */
- SMSC_TRACE(PROBE,
- "Mac Address is read from LAN911x EEPROM");
+ SMSC_TRACE(pdata, probe,
+ "Mac Address is read from LAN911x EEPROM");
} else {
/* eeprom values are invalid, generate random MAC */
random_ether_addr(dev->dev_addr);
smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
- SMSC_TRACE(PROBE,
- "MAC Address is set to random_ether_addr");
+ SMSC_TRACE(pdata, probe,
+ "MAC Address is set to random_ether_addr");
}
}
spin_unlock_irq(&pdata->mac_lock);
- dev_info(&dev->dev, "MAC Address: %pM\n", dev->dev_addr);
+ netdev_info(dev, "MAC Address: %pM\n", dev->dev_addr);
return 0;
diff --git a/drivers/net/smsc911x.h b/drivers/net/smsc911x.h
index 50f712e99e9..8d67aacf886 100644
--- a/drivers/net/smsc911x.h
+++ b/drivers/net/smsc911x.h
@@ -33,25 +33,21 @@
* can be successfully looped back */
#define USE_PHY_WORK_AROUND
-#define DPRINTK(nlevel, klevel, fmt, args...) \
- ((void)((NETIF_MSG_##nlevel & pdata->msg_enable) && \
- printk(KERN_##klevel "%s: %s: " fmt "\n", \
- pdata->dev->name, __func__, ## args)))
-
#if USE_DEBUG >= 1
-#define SMSC_WARNING(nlevel, fmt, args...) \
- DPRINTK(nlevel, WARNING, fmt, ## args)
+#define SMSC_WARN(pdata, nlevel, fmt, args...) \
+ netif_warn(pdata, nlevel, (pdata)->dev, \
+ "%s: " fmt "\n", __func__, ##args)
#else
-#define SMSC_WARNING(nlevel, fmt, args...) \
- ({ do {} while (0); 0; })
+#define SMSC_WARN(pdata, nlevel, fmt, args...) \
+ no_printk(fmt "\n", ##args)
#endif
#if USE_DEBUG >= 2
-#define SMSC_TRACE(nlevel, fmt, args...) \
- DPRINTK(nlevel, INFO, fmt, ## args)
+#define SMSC_TRACE(pdata, nlevel, fmt, args...) \
+ netif_info(pdata, nlevel, pdata->dev, fmt "\n", ##args)
#else
-#define SMSC_TRACE(nlevel, fmt, args...) \
- ({ do {} while (0); 0; })
+#define SMSC_TRACE(pdata, nlevel, fmt, args...) \
+ no_printk(fmt "\n", ##args)
#endif
#ifdef CONFIG_DEBUG_SPINLOCK
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index cb6bcca9d54..949f124e127 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -994,15 +994,13 @@ spider_net_pass_skb_up(struct spider_net_descr *descr,
skb->protocol = eth_type_trans(skb, netdev);
/* checksum offload */
- if (card->options.rx_csum) {
+ skb_checksum_none_assert(skb);
+ if (netdev->features & NETIF_F_RXCSUM) {
if ( ( (data_status & SPIDER_NET_DATA_STATUS_CKSUM_MASK) ==
SPIDER_NET_DATA_STATUS_CKSUM_MASK) &&
!(data_error & SPIDER_NET_DATA_ERR_CKSUM_MASK))
skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
- skb_checksum_none_assert(skb);
- } else
- skb_checksum_none_assert(skb);
+ }
if (data_status & SPIDER_NET_VLAN_PACKET) {
/* further enhancements: HW-accel VLAN
@@ -2322,14 +2320,15 @@ spider_net_setup_netdev(struct spider_net_card *card)
card->aneg_timer.function = spider_net_link_phy;
card->aneg_timer.data = (unsigned long) card;
- card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT;
-
netif_napi_add(netdev, &card->napi,
spider_net_poll, SPIDER_NET_NAPI_WEIGHT);
spider_net_setup_netdev_ops(netdev);
- netdev->features = NETIF_F_IP_CSUM | NETIF_F_LLTX;
+ netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
+ if (SPIDER_NET_RX_CSUM_DEFAULT)
+ netdev->features |= NETIF_F_RXCSUM;
+ netdev->features |= NETIF_F_IP_CSUM | NETIF_F_LLTX;
/* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
* NETIF_F_HW_VLAN_FILTER */
diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h
index 05f74cbdd61..020f64a8fcf 100644
--- a/drivers/net/spider_net.h
+++ b/drivers/net/spider_net.h
@@ -429,12 +429,6 @@ struct spider_net_descr_chain {
* 701b8000 would be correct, but every packets gets that flag */
#define SPIDER_NET_DESTROY_RX_FLAGS 0x700b8000
-/* this will be bigger some time */
-struct spider_net_options {
- int rx_csum; /* for rx: if 0 ip_summed=NONE,
- if 1 and hw has verified, ip_summed=UNNECESSARY */
-};
-
#define SPIDER_NET_DEFAULT_MSG ( NETIF_MSG_DRV | \
NETIF_MSG_PROBE | \
NETIF_MSG_LINK | \
@@ -487,7 +481,6 @@ struct spider_net_card {
/* for ethtool */
int msg_enable;
struct spider_net_extra_stats spider_stats;
- struct spider_net_options options;
/* Must be last item in struct */
struct spider_net_descr darray[0];
diff --git a/drivers/net/spider_net_ethtool.c b/drivers/net/spider_net_ethtool.c
index 5bae728c382..9c288cd7d17 100644
--- a/drivers/net/spider_net_ethtool.c
+++ b/drivers/net/spider_net_ethtool.c
@@ -58,7 +58,7 @@ spider_net_ethtool_get_settings(struct net_device *netdev,
cmd->advertising = (ADVERTISED_1000baseT_Full |
ADVERTISED_FIBRE);
cmd->port = PORT_FIBRE;
- cmd->speed = card->phy.speed;
+ ethtool_cmd_speed_set(cmd, card->phy.speed);
cmd->duplex = DUPLEX_FULL;
return 0;
@@ -115,24 +115,6 @@ spider_net_ethtool_nway_reset(struct net_device *netdev)
return 0;
}
-static u32
-spider_net_ethtool_get_rx_csum(struct net_device *netdev)
-{
- struct spider_net_card *card = netdev_priv(netdev);
-
- return card->options.rx_csum;
-}
-
-static int
-spider_net_ethtool_set_rx_csum(struct net_device *netdev, u32 n)
-{
- struct spider_net_card *card = netdev_priv(netdev);
-
- card->options.rx_csum = n;
- return 0;
-}
-
-
static void
spider_net_ethtool_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ering)
@@ -189,9 +171,6 @@ const struct ethtool_ops spider_net_ethtool_ops = {
.set_msglevel = spider_net_ethtool_set_msglevel,
.get_link = ethtool_op_get_link,
.nway_reset = spider_net_ethtool_nway_reset,
- .get_rx_csum = spider_net_ethtool_get_rx_csum,
- .set_rx_csum = spider_net_ethtool_set_rx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
.get_ringparam = spider_net_ethtool_get_ringparam,
.get_strings = spider_net_get_strings,
.get_sset_count = spider_net_get_sset_count,
diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c
index 6ae4c3f4c63..f20455cbfbb 100644
--- a/drivers/net/stmmac/dwmac1000_core.c
+++ b/drivers/net/stmmac/dwmac1000_core.c
@@ -178,10 +178,11 @@ static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode)
{
unsigned int pmt = 0;
- if (mode == WAKE_MAGIC) {
+ if (mode & WAKE_MAGIC) {
CHIP_DBG(KERN_DEBUG "GMAC: WOL Magic frame\n");
pmt |= power_down | magic_pkt_en;
- } else if (mode == WAKE_UCAST) {
+ }
+ if (mode & WAKE_UCAST) {
CHIP_DBG(KERN_DEBUG "GMAC: WOL on global unicast\n");
pmt |= global_unicast;
}
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h
index 5f06c4706ab..2b076b31362 100644
--- a/drivers/net/stmmac/stmmac.h
+++ b/drivers/net/stmmac/stmmac.h
@@ -21,7 +21,6 @@
*******************************************************************************/
#define DRV_MODULE_VERSION "Nov_2010"
-#include <linux/platform_device.h>
#include <linux/stmmac.h>
#include "common.h"
diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
index fd719edc7f7..ae5213a8c4c 100644
--- a/drivers/net/stmmac/stmmac_ethtool.c
+++ b/drivers/net/stmmac/stmmac_ethtool.c
@@ -197,13 +197,6 @@ static void stmmac_ethtool_gregs(struct net_device *dev,
}
}
-static u32 stmmac_ethtool_get_rx_csum(struct net_device *dev)
-{
- struct stmmac_priv *priv = netdev_priv(dev);
-
- return priv->rx_coe;
-}
-
static void
stmmac_get_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
@@ -241,20 +234,11 @@ stmmac_set_pauseparam(struct net_device *netdev,
new_pause |= FLOW_TX;
priv->flow_ctrl = new_pause;
+ phy->autoneg = pause->autoneg;
if (phy->autoneg) {
- if (netif_running(netdev)) {
- struct ethtool_cmd cmd;
- /* auto-negotiation automatically restarted */
- cmd.cmd = ETHTOOL_NWAY_RST;
- cmd.supported = phy->supported;
- cmd.advertising = phy->advertising;
- cmd.autoneg = phy->autoneg;
- cmd.speed = phy->speed;
- cmd.duplex = phy->duplex;
- cmd.phy_address = phy->addr;
- ret = phy_ethtool_sset(phy, &cmd);
- }
+ if (netif_running(netdev))
+ ret = phy_start_aneg(phy);
} else
priv->hw->mac->flow_ctrl(priv->ioaddr, phy->duplex,
priv->flow_ctrl, priv->pause);
@@ -315,7 +299,7 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
spin_lock_irq(&priv->lock);
if (device_can_wakeup(priv->device)) {
- wol->supported = WAKE_MAGIC;
+ wol->supported = WAKE_MAGIC | WAKE_UCAST;
wol->wolopts = priv->wolopts;
}
spin_unlock_irq(&priv->lock);
@@ -324,7 +308,7 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct stmmac_priv *priv = netdev_priv(dev);
- u32 support = WAKE_MAGIC;
+ u32 support = WAKE_MAGIC | WAKE_UCAST;
if (!device_can_wakeup(priv->device))
return -EINVAL;
@@ -358,11 +342,6 @@ static struct ethtool_ops stmmac_ethtool_ops = {
.get_regs = stmmac_ethtool_gregs,
.get_regs_len = stmmac_ethtool_get_regs_len,
.get_link = ethtool_op_get_link,
- .get_rx_csum = stmmac_ethtool_get_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_ipv6_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
.get_pauseparam = stmmac_get_pauseparam,
.set_pauseparam = stmmac_set_pauseparam,
.get_ethtool_stats = stmmac_get_ethtool_stats,
@@ -370,8 +349,6 @@ static struct ethtool_ops stmmac_ethtool_ops = {
.get_wol = stmmac_get_wol,
.set_wol = stmmac_set_wol,
.get_sset_count = stmmac_get_sset_count,
- .get_tso = ethtool_op_get_tso,
- .set_tso = ethtool_op_set_tso,
};
void stmmac_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index cc973fc3840..e15c4a0bb96 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -116,9 +116,6 @@ static int tc = TC_DEFAULT;
module_param(tc, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(tc, "DMA threshold control value");
-#define RX_NO_COALESCE 1 /* Always interrupt on completion */
-#define TX_NO_COALESCE -1 /* No moderation by default */
-
/* Pay attention to tune this parameter; take care of both
* hardware capability and network stabitily/performance impact.
* Many tests showed that ~4ms latency seems to be good enough. */
@@ -139,7 +136,6 @@ static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
-static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev);
/**
* stmmac_verify_args - verify the driver parameters.
@@ -831,6 +827,7 @@ static int stmmac_open(struct net_device *dev)
pr_info("stmmac: Rx Checksum Offload Engine supported\n");
if (priv->plat->tx_coe)
pr_info("\tTX Checksum insertion supported\n");
+ netdev_update_features(dev);
/* Initialise the MMC (if present) to disable all interrupts. */
writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK);
@@ -934,46 +931,6 @@ static int stmmac_release(struct net_device *dev)
return 0;
}
-/*
- * To perform emulated hardware segmentation on skb.
- */
-static int stmmac_sw_tso(struct stmmac_priv *priv, struct sk_buff *skb)
-{
- struct sk_buff *segs, *curr_skb;
- int gso_segs = skb_shinfo(skb)->gso_segs;
-
- /* Estimate the number of fragments in the worst case */
- if (unlikely(stmmac_tx_avail(priv) < gso_segs)) {
- netif_stop_queue(priv->dev);
- TX_DBG(KERN_ERR "%s: TSO BUG! Tx Ring full when queue awake\n",
- __func__);
- if (stmmac_tx_avail(priv) < gso_segs)
- return NETDEV_TX_BUSY;
-
- netif_wake_queue(priv->dev);
- }
- TX_DBG("\tstmmac_sw_tso: segmenting: skb %p (len %d)\n",
- skb, skb->len);
-
- segs = skb_gso_segment(skb, priv->dev->features & ~NETIF_F_TSO);
- if (IS_ERR(segs))
- goto sw_tso_end;
-
- do {
- curr_skb = segs;
- segs = segs->next;
- TX_DBG("\t\tcurrent skb->len: %d, *curr %p,"
- "*next %p\n", curr_skb->len, curr_skb, segs);
- curr_skb->next = NULL;
- stmmac_xmit(curr_skb, priv->dev);
- } while (segs);
-
-sw_tso_end:
- dev_kfree_skb(skb);
-
- return NETDEV_TX_OK;
-}
-
static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb,
struct net_device *dev,
int csum_insertion)
@@ -1051,16 +1008,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
!skb_is_gso(skb) ? "isn't" : "is");
#endif
- if (unlikely(skb_is_gso(skb)))
- return stmmac_sw_tso(priv, skb);
-
- if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) {
- if (unlikely((!priv->plat->tx_coe) ||
- (priv->no_csum_insertion)))
- skb_checksum_help(skb);
- else
- csum_insertion = 1;
- }
+ csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL);
desc = priv->dma_tx + entry;
first = desc;
@@ -1380,18 +1328,29 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
return -EINVAL;
}
+ dev->mtu = new_mtu;
+ netdev_update_features(dev);
+
+ return 0;
+}
+
+static u32 stmmac_fix_features(struct net_device *dev, u32 features)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ if (!priv->rx_coe)
+ features &= ~NETIF_F_RXCSUM;
+ if (!priv->plat->tx_coe)
+ features &= ~NETIF_F_ALL_CSUM;
+
/* Some GMAC devices have a bugged Jumbo frame support that
* needs to have the Tx COE disabled for oversized frames
* (due to limited buffer sizes). In this case we disable
* the TX csum insertionin the TDES and not use SF. */
- if ((priv->plat->bugged_jumbo) && (priv->dev->mtu > ETH_DATA_LEN))
- priv->no_csum_insertion = 1;
- else
- priv->no_csum_insertion = 0;
+ if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN))
+ features &= ~NETIF_F_ALL_CSUM;
- dev->mtu = new_mtu;
-
- return 0;
+ return features;
}
static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
@@ -1471,6 +1430,7 @@ static const struct net_device_ops stmmac_netdev_ops = {
.ndo_start_xmit = stmmac_xmit,
.ndo_stop = stmmac_release,
.ndo_change_mtu = stmmac_change_mtu,
+ .ndo_fix_features = stmmac_fix_features,
.ndo_set_multicast_list = stmmac_multicast_list,
.ndo_tx_timeout = stmmac_tx_timeout,
.ndo_do_ioctl = stmmac_ioctl,
@@ -1501,8 +1461,8 @@ static int stmmac_probe(struct net_device *dev)
dev->netdev_ops = &stmmac_netdev_ops;
stmmac_set_ethtool_ops(dev);
- dev->features |= NETIF_F_SG | NETIF_F_HIGHDMA |
- NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+ dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+ dev->features |= dev->hw_features | NETIF_F_HIGHDMA;
dev->watchdog_timeo = msecs_to_jiffies(watchdog);
#ifdef STMMAC_VLAN_TAG_USED
/* Both mac100 and gmac support receive VLAN tag detection */
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index d3be735c471..ab593009926 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -1294,7 +1294,7 @@ static void gem_begin_auto_negotiation(struct gem *gp, struct ethtool_cmd *ep)
autoneg = 1;
} else {
autoneg = 0;
- speed = ep->speed;
+ speed = ethtool_cmd_speed(ep);
duplex = ep->duplex;
}
@@ -2642,7 +2642,7 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
/* Return current PHY settings */
spin_lock_irq(&gp->lock);
cmd->autoneg = gp->want_autoneg;
- cmd->speed = gp->phy_mii.speed;
+ ethtool_cmd_speed_set(cmd, gp->phy_mii.speed);
cmd->duplex = gp->phy_mii.duplex;
cmd->advertising = gp->phy_mii.advertising;
@@ -2659,7 +2659,7 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
SUPPORTED_Autoneg);
cmd->advertising = cmd->supported;
- cmd->speed = 0;
+ ethtool_cmd_speed_set(cmd, 0);
cmd->duplex = cmd->port = cmd->phy_address =
cmd->transceiver = cmd->autoneg = 0;
@@ -2673,7 +2673,7 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->advertising = cmd->supported;
cmd->transceiver = XCVR_INTERNAL;
if (gp->lstate == link_up)
- cmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(cmd, SPEED_1000);
cmd->duplex = DUPLEX_FULL;
cmd->autoneg = 1;
}
@@ -2686,6 +2686,7 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int gem_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct gem *gp = netdev_priv(dev);
+ u32 speed = ethtool_cmd_speed(cmd);
/* Verify the settings we care about. */
if (cmd->autoneg != AUTONEG_ENABLE &&
@@ -2697,9 +2698,9 @@ static int gem_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return -EINVAL;
if (cmd->autoneg == AUTONEG_DISABLE &&
- ((cmd->speed != SPEED_1000 &&
- cmd->speed != SPEED_100 &&
- cmd->speed != SPEED_10) ||
+ ((speed != SPEED_1000 &&
+ speed != SPEED_100 &&
+ speed != SPEED_10) ||
(cmd->duplex != DUPLEX_HALF &&
cmd->duplex != DUPLEX_FULL)))
return -EINVAL;
@@ -3146,7 +3147,8 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
gp->phy_mii.def ? gp->phy_mii.def->name : "no");
/* GEM can do it all... */
- dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_LLTX;
+ dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
+ dev->features |= dev->hw_features | NETIF_F_RXCSUM | NETIF_F_LLTX;
if (pci_using_dac)
dev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index bff2f7999ff..30aad54b1b3 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -1383,7 +1383,7 @@ force_link:
if (ep == NULL || ep->autoneg == AUTONEG_ENABLE) {
hp->sw_bmcr = BMCR_SPEED100;
} else {
- if (ep->speed == SPEED_100)
+ if (ethtool_cmd_speed(ep) == SPEED_100)
hp->sw_bmcr = BMCR_SPEED100;
else
hp->sw_bmcr = 0;
@@ -2401,6 +2401,7 @@ static void happy_meal_set_multicast(struct net_device *dev)
static int hme_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct happy_meal *hp = netdev_priv(dev);
+ u32 speed;
cmd->supported =
(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
@@ -2420,10 +2421,9 @@ static int hme_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if (hp->sw_bmcr & BMCR_ANENABLE) {
cmd->autoneg = AUTONEG_ENABLE;
- cmd->speed =
- (hp->sw_lpa & (LPA_100HALF | LPA_100FULL)) ?
- SPEED_100 : SPEED_10;
- if (cmd->speed == SPEED_100)
+ speed = ((hp->sw_lpa & (LPA_100HALF | LPA_100FULL)) ?
+ SPEED_100 : SPEED_10);
+ if (speed == SPEED_100)
cmd->duplex =
(hp->sw_lpa & (LPA_100FULL)) ?
DUPLEX_FULL : DUPLEX_HALF;
@@ -2433,13 +2433,12 @@ static int hme_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
DUPLEX_FULL : DUPLEX_HALF;
} else {
cmd->autoneg = AUTONEG_DISABLE;
- cmd->speed =
- (hp->sw_bmcr & BMCR_SPEED100) ?
- SPEED_100 : SPEED_10;
+ speed = (hp->sw_bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;
cmd->duplex =
(hp->sw_bmcr & BMCR_FULLDPLX) ?
DUPLEX_FULL : DUPLEX_HALF;
}
+ ethtool_cmd_speed_set(cmd, speed);
return 0;
}
@@ -2452,8 +2451,8 @@ static int hme_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->autoneg != AUTONEG_DISABLE)
return -EINVAL;
if (cmd->autoneg == AUTONEG_DISABLE &&
- ((cmd->speed != SPEED_100 &&
- cmd->speed != SPEED_10) ||
+ ((ethtool_cmd_speed(cmd) != SPEED_100 &&
+ ethtool_cmd_speed(cmd) != SPEED_10) ||
(cmd->duplex != DUPLEX_HALF &&
cmd->duplex != DUPLEX_FULL)))
return -EINVAL;
@@ -2788,7 +2787,8 @@ static int __devinit happy_meal_sbus_probe_one(struct platform_device *op, int i
dev->ethtool_ops = &hme_ethtool_ops;
/* Happy Meal can do it all... */
- dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
+ dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
+ dev->features |= dev->hw_features | NETIF_F_RXCSUM;
dev->irq = op->archdata.irqs[0];
@@ -3113,7 +3113,8 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
dev->dma = 0;
/* Happy Meal can do it all... */
- dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
+ dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
+ dev->features |= dev->hw_features | NETIF_F_RXCSUM;
#if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
/* Hook up PCI register/descriptor accessors. */
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 8564ec5cfb7..80fbee0d40a 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -2017,9 +2017,11 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ndev->irq = pdev->irq;
ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO
| NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_FILTER
+ NETIF_F_HW_VLAN_FILTER | NETIF_F_RXCSUM
/*| NETIF_F_FRAGLIST */
;
+ ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
+ NETIF_F_TSO | NETIF_F_HW_VLAN_TX;
if (pci_using_dac)
ndev->features |= NETIF_F_HIGHDMA;
@@ -2149,7 +2151,7 @@ static int bdx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE);
- ecmd->speed = SPEED_10000;
+ ethtool_cmd_speed_set(ecmd, SPEED_10000);
ecmd->duplex = DUPLEX_FULL;
ecmd->port = PORT_FIBRE;
ecmd->transceiver = XCVR_EXTERNAL; /* what does it mean? */
@@ -2188,24 +2190,6 @@ bdx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
}
/*
- * bdx_get_rx_csum - report whether receive checksums are turned on or off
- * @netdev
- */
-static u32 bdx_get_rx_csum(struct net_device *netdev)
-{
- return 1; /* always on */
-}
-
-/*
- * bdx_get_tx_csum - report whether transmit checksums are turned on or off
- * @netdev
- */
-static u32 bdx_get_tx_csum(struct net_device *netdev)
-{
- return (netdev->features & NETIF_F_IP_CSUM) != 0;
-}
-
-/*
* bdx_get_coalesce - get interrupt coalescing parameters
* @netdev
* @ecoal
@@ -2424,10 +2408,6 @@ static void bdx_set_ethtool_ops(struct net_device *netdev)
.set_coalesce = bdx_set_coalesce,
.get_ringparam = bdx_get_ringparam,
.set_ringparam = bdx_set_ringparam,
- .get_rx_csum = bdx_get_rx_csum,
- .get_tx_csum = bdx_get_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .get_tso = ethtool_op_get_tso,
.get_strings = bdx_get_strings,
.get_sset_count = bdx_get_sset_count,
.get_ethtool_stats = bdx_get_ethtool_stats,
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 7a5daefb6f3..db19332a7d8 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -62,12 +62,36 @@
#include "tg3.h"
+/* Functions & macros to verify TG3_FLAGS types */
+
+static inline int _tg3_flag(enum TG3_FLAGS flag, unsigned long *bits)
+{
+ return test_bit(flag, bits);
+}
+
+static inline void _tg3_flag_set(enum TG3_FLAGS flag, unsigned long *bits)
+{
+ set_bit(flag, bits);
+}
+
+static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
+{
+ clear_bit(flag, bits);
+}
+
+#define tg3_flag(tp, flag) \
+ _tg3_flag(TG3_FLAG_##flag, (tp)->tg3_flags)
+#define tg3_flag_set(tp, flag) \
+ _tg3_flag_set(TG3_FLAG_##flag, (tp)->tg3_flags)
+#define tg3_flag_clear(tp, flag) \
+ _tg3_flag_clear(TG3_FLAG_##flag, (tp)->tg3_flags)
+
#define DRV_MODULE_NAME "tg3"
#define TG3_MAJ_NUM 3
-#define TG3_MIN_NUM 117
+#define TG3_MIN_NUM 119
#define DRV_MODULE_VERSION \
__stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
-#define DRV_MODULE_RELDATE "January 25, 2011"
+#define DRV_MODULE_RELDATE "May 18, 2011"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -85,26 +109,25 @@
/* length of time before we decide the hardware is borked,
* and dev->tx_timeout() should be called to fix the problem
*/
+
#define TG3_TX_TIMEOUT (5 * HZ)
/* hardware minimum and maximum for a single frame's data payload */
#define TG3_MIN_MTU 60
#define TG3_MAX_MTU(tp) \
- ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) ? 9000 : 1500)
+ (tg3_flag(tp, JUMBO_CAPABLE) ? 9000 : 1500)
/* These numbers seem to be hard coded in the NIC firmware somehow.
* You can't change the ring sizes, but you can change where you place
* them in the NIC onboard memory.
*/
#define TG3_RX_STD_RING_SIZE(tp) \
- ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || \
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) ? \
- RX_STD_MAX_SIZE_5717 : 512)
+ (tg3_flag(tp, LRG_PROD_RING_CAP) ? \
+ TG3_RX_STD_MAX_SIZE_5717 : TG3_RX_STD_MAX_SIZE_5700)
#define TG3_DEF_RX_RING_PENDING 200
#define TG3_RX_JMB_RING_SIZE(tp) \
- ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || \
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) ? \
- 1024 : 256)
+ (tg3_flag(tp, LRG_PROD_RING_CAP) ? \
+ TG3_RX_JMB_MAX_SIZE_5717 : TG3_RX_JMB_MAX_SIZE_5700)
#define TG3_DEF_RX_JUMBO_RING_PENDING 100
#define TG3_RSS_INDIR_TBL_SIZE 128
@@ -167,11 +190,6 @@
#define TG3_RAW_IP_ALIGN 2
-/* number of ETHTOOL_GSTATS u64's */
-#define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64))
-
-#define TG3_NUM_TEST 6
-
#define TG3_FW_UPDATE_TIMEOUT_SEC 5
#define FIRMWARE_TG3 "tigon/tg3.bin"
@@ -266,6 +284,7 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = {
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57791)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57795)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5719)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5720)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -280,7 +299,7 @@ MODULE_DEVICE_TABLE(pci, tg3_pci_tbl);
static const struct {
const char string[ETH_GSTRING_LEN];
-} ethtool_stats_keys[TG3_NUM_STATS] = {
+} ethtool_stats_keys[] = {
{ "rx_octets" },
{ "rx_fragments" },
{ "rx_ucast_packets" },
@@ -356,12 +375,17 @@ static const struct {
{ "ring_status_update" },
{ "nic_irqs" },
{ "nic_avoided_irqs" },
- { "nic_tx_threshold_hit" }
+ { "nic_tx_threshold_hit" },
+
+ { "mbuf_lwm_thresh_hit" },
};
+#define TG3_NUM_STATS ARRAY_SIZE(ethtool_stats_keys)
+
+
static const struct {
const char string[ETH_GSTRING_LEN];
-} ethtool_test_keys[TG3_NUM_TEST] = {
+} ethtool_test_keys[] = {
{ "nvram test (online) " },
{ "link test (online) " },
{ "register test (offline)" },
@@ -370,6 +394,9 @@ static const struct {
{ "interrupt test (offline)" },
};
+#define TG3_NUM_TEST ARRAY_SIZE(ethtool_test_keys)
+
+
static void tg3_write32(struct tg3 *tp, u32 off, u32 val)
{
writel(val, tp->regs + off);
@@ -467,8 +494,7 @@ static u32 tg3_read_indirect_mbox(struct tg3 *tp, u32 off)
*/
static void _tw32_flush(struct tg3 *tp, u32 off, u32 val, u32 usec_wait)
{
- if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) ||
- (tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))
+ if (tg3_flag(tp, PCIX_TARGET_HWBUG) || tg3_flag(tp, ICH_WORKAROUND))
/* Non-posted methods */
tp->write32(tp, off, val);
else {
@@ -488,8 +514,7 @@ static void _tw32_flush(struct tg3 *tp, u32 off, u32 val, u32 usec_wait)
static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val)
{
tp->write32_mbox(tp, off, val);
- if (!(tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) &&
- !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))
+ if (!tg3_flag(tp, MBOX_WRITE_REORDER) && !tg3_flag(tp, ICH_WORKAROUND))
tp->read32_mbox(tp, off);
}
@@ -497,9 +522,9 @@ static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val)
{
void __iomem *mbox = tp->regs + off;
writel(val, mbox);
- if (tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG)
+ if (tg3_flag(tp, TXD_MBOX_HWBUG))
writel(val, mbox);
- if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)
+ if (tg3_flag(tp, MBOX_WRITE_REORDER))
readl(mbox);
}
@@ -528,12 +553,12 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
{
unsigned long flags;
- if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) &&
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 &&
(off >= NIC_SRAM_STATS_BLK) && (off < NIC_SRAM_TX_BUFFER_DESC))
return;
spin_lock_irqsave(&tp->indirect_lock, flags);
- if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) {
+ if (tg3_flag(tp, SRAM_USE_CONFIG)) {
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
@@ -553,14 +578,14 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
{
unsigned long flags;
- if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) &&
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 &&
(off >= NIC_SRAM_STATS_BLK) && (off < NIC_SRAM_TX_BUFFER_DESC)) {
*val = 0;
return;
}
spin_lock_irqsave(&tp->indirect_lock, flags);
- if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) {
+ if (tg3_flag(tp, SRAM_USE_CONFIG)) {
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
@@ -597,7 +622,7 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
int ret = 0;
u32 status, req, gnt;
- if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
+ if (!tg3_flag(tp, ENABLE_APE))
return 0;
switch (locknum) {
@@ -643,7 +668,7 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
{
u32 gnt;
- if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
+ if (!tg3_flag(tp, ENABLE_APE))
return;
switch (locknum) {
@@ -687,14 +712,14 @@ static void tg3_enable_ints(struct tg3 *tp)
struct tg3_napi *tnapi = &tp->napi[i];
tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
- if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
+ if (tg3_flag(tp, 1SHOT_MSI))
tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
tp->coal_now |= tnapi->coal_now;
}
/* Force an initial interrupt */
- if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) &&
+ if (!tg3_flag(tp, TAGGED_STATUS) &&
(tp->napi[0].hw_status->status & SD_STATUS_UPDATED))
tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
else
@@ -710,9 +735,7 @@ static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
unsigned int work_exists = 0;
/* check for phy events */
- if (!(tp->tg3_flags &
- (TG3_FLAG_USE_LINKCHG_REG |
- TG3_FLAG_POLL_SERDES))) {
+ if (!(tg3_flag(tp, USE_LINKCHG_REG) || tg3_flag(tp, POLL_SERDES))) {
if (sblk->status & SD_STATUS_LINK_CHG)
work_exists = 1;
}
@@ -740,8 +763,7 @@ static void tg3_int_reenable(struct tg3_napi *tnapi)
* The last_tag we write above tells the chip which piece of
* work we've completed.
*/
- if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) &&
- tg3_has_work(tnapi))
+ if (!tg3_flag(tp, TAGGED_STATUS) && tg3_has_work(tnapi))
tw32(HOSTCC_MODE, tp->coalesce_mode |
HOSTCC_MODE_ENABLE | tnapi->coal_now);
}
@@ -751,8 +773,7 @@ static void tg3_switch_clocks(struct tg3 *tp)
u32 clock_ctrl;
u32 orig_clock_ctrl;
- if ((tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) ||
- (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
+ if (tg3_flag(tp, CPMU_PRESENT) || tg3_flag(tp, 5780_CLASS))
return;
clock_ctrl = tr32(TG3PCI_CLOCK_CTRL);
@@ -763,7 +784,7 @@ static void tg3_switch_clocks(struct tg3 *tp)
0x1f);
tp->pci_clock_ctrl = clock_ctrl;
- if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+ if (tg3_flag(tp, 5705_PLUS)) {
if (orig_clock_ctrl & CLOCK_CTRL_625_CORE) {
tw32_wait_f(TG3PCI_CLOCK_CTRL,
clock_ctrl | CLOCK_CTRL_625_CORE, 40);
@@ -880,6 +901,104 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
return ret;
}
+static int tg3_phy_cl45_write(struct tg3 *tp, u32 devad, u32 addr, u32 val)
+{
+ int err;
+
+ err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad);
+ if (err)
+ goto done;
+
+ err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr);
+ if (err)
+ goto done;
+
+ err = tg3_writephy(tp, MII_TG3_MMD_CTRL,
+ MII_TG3_MMD_CTRL_DATA_NOINC | devad);
+ if (err)
+ goto done;
+
+ err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, val);
+
+done:
+ return err;
+}
+
+static int tg3_phy_cl45_read(struct tg3 *tp, u32 devad, u32 addr, u32 *val)
+{
+ int err;
+
+ err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad);
+ if (err)
+ goto done;
+
+ err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr);
+ if (err)
+ goto done;
+
+ err = tg3_writephy(tp, MII_TG3_MMD_CTRL,
+ MII_TG3_MMD_CTRL_DATA_NOINC | devad);
+ if (err)
+ goto done;
+
+ err = tg3_readphy(tp, MII_TG3_MMD_ADDRESS, val);
+
+done:
+ return err;
+}
+
+static int tg3_phydsp_read(struct tg3 *tp, u32 reg, u32 *val)
+{
+ int err;
+
+ err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
+ if (!err)
+ err = tg3_readphy(tp, MII_TG3_DSP_RW_PORT, val);
+
+ return err;
+}
+
+static int tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
+{
+ int err;
+
+ err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
+ if (!err)
+ err = tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
+
+ return err;
+}
+
+static int tg3_phy_auxctl_read(struct tg3 *tp, int reg, u32 *val)
+{
+ int err;
+
+ err = tg3_writephy(tp, MII_TG3_AUX_CTRL,
+ (reg << MII_TG3_AUXCTL_MISC_RDSEL_SHIFT) |
+ MII_TG3_AUXCTL_SHDWSEL_MISC);
+ if (!err)
+ err = tg3_readphy(tp, MII_TG3_AUX_CTRL, val);
+
+ return err;
+}
+
+static int tg3_phy_auxctl_write(struct tg3 *tp, int reg, u32 set)
+{
+ if (reg == MII_TG3_AUXCTL_SHDWSEL_MISC)
+ set |= MII_TG3_AUXCTL_MISC_WREN;
+
+ return tg3_writephy(tp, MII_TG3_AUX_CTRL, set | reg);
+}
+
+#define TG3_PHY_AUXCTL_SMDSP_ENABLE(tp) \
+ tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \
+ MII_TG3_AUXCTL_ACTL_SMDSP_ENA | \
+ MII_TG3_AUXCTL_ACTL_TX_6DB)
+
+#define TG3_PHY_AUXCTL_SMDSP_DISABLE(tp) \
+ tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \
+ MII_TG3_AUXCTL_ACTL_TX_6DB);
+
static int tg3_bmcr_reset(struct tg3 *tp)
{
u32 phy_control;
@@ -982,7 +1101,7 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
return;
}
- if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_INBAND_DISABLE))
+ if (!tg3_flag(tp, RGMII_INBAND_DISABLE))
val |= MAC_PHYCFG2_EMODE_MASK_MASK |
MAC_PHYCFG2_FMODE_MASK_MASK |
MAC_PHYCFG2_GMODE_MASK_MASK |
@@ -995,10 +1114,10 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
val = tr32(MAC_PHYCFG1);
val &= ~(MAC_PHYCFG1_RXCLK_TO_MASK | MAC_PHYCFG1_TXCLK_TO_MASK |
MAC_PHYCFG1_RGMII_EXT_RX_DEC | MAC_PHYCFG1_RGMII_SND_STAT_EN);
- if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_INBAND_DISABLE)) {
- if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
+ if (!tg3_flag(tp, RGMII_INBAND_DISABLE)) {
+ if (tg3_flag(tp, RGMII_EXT_IBND_RX_EN))
val |= MAC_PHYCFG1_RGMII_EXT_RX_DEC;
- if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
+ if (tg3_flag(tp, RGMII_EXT_IBND_TX_EN))
val |= MAC_PHYCFG1_RGMII_SND_STAT_EN;
}
val |= MAC_PHYCFG1_RXCLK_TIMEOUT | MAC_PHYCFG1_TXCLK_TIMEOUT |
@@ -1013,13 +1132,13 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
MAC_RGMII_MODE_TX_ENABLE |
MAC_RGMII_MODE_TX_LOWPWR |
MAC_RGMII_MODE_TX_RESET);
- if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_INBAND_DISABLE)) {
- if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
+ if (!tg3_flag(tp, RGMII_INBAND_DISABLE)) {
+ if (tg3_flag(tp, RGMII_EXT_IBND_RX_EN))
val |= MAC_RGMII_MODE_RX_INT_B |
MAC_RGMII_MODE_RX_QUALITY |
MAC_RGMII_MODE_RX_ACTIVITY |
MAC_RGMII_MODE_RX_ENG_DET;
- if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
+ if (tg3_flag(tp, RGMII_EXT_IBND_TX_EN))
val |= MAC_RGMII_MODE_TX_ENABLE |
MAC_RGMII_MODE_TX_LOWPWR |
MAC_RGMII_MODE_TX_RESET;
@@ -1033,7 +1152,7 @@ static void tg3_mdio_start(struct tg3 *tp)
tw32_f(MAC_MI_MODE, tp->mi_mode);
udelay(80);
- if ((tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) &&
+ if (tg3_flag(tp, MDIOBUS_INITED) &&
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
tg3_mdio_config_5785(tp);
}
@@ -1044,8 +1163,7 @@ static int tg3_mdio_init(struct tg3 *tp)
u32 reg;
struct phy_device *phydev;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+ if (tg3_flag(tp, 5717_PLUS)) {
u32 is_serdes;
tp->phy_addr = PCI_FUNC(tp->pdev->devfn) + 1;
@@ -1062,8 +1180,7 @@ static int tg3_mdio_init(struct tg3 *tp)
tg3_mdio_start(tp);
- if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) ||
- (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED))
+ if (!tg3_flag(tp, USE_PHYLIB) || tg3_flag(tp, MDIOBUS_INITED))
return 0;
tp->mdio_bus = mdiobus_alloc();
@@ -1119,11 +1236,11 @@ static int tg3_mdio_init(struct tg3 *tp)
PHY_BRCM_RX_REFCLK_UNUSED |
PHY_BRCM_DIS_TXCRXC_NOENRGY |
PHY_BRCM_AUTO_PWRDWN_ENABLE;
- if (tp->tg3_flags3 & TG3_FLG3_RGMII_INBAND_DISABLE)
+ if (tg3_flag(tp, RGMII_INBAND_DISABLE))
phydev->dev_flags |= PHY_BRCM_STD_IBND_DISABLE;
- if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
+ if (tg3_flag(tp, RGMII_EXT_IBND_RX_EN))
phydev->dev_flags |= PHY_BRCM_EXT_IBND_RX_ENABLE;
- if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
+ if (tg3_flag(tp, RGMII_EXT_IBND_TX_EN))
phydev->dev_flags |= PHY_BRCM_EXT_IBND_TX_ENABLE;
/* fallthru */
case PHY_ID_RTL8211C:
@@ -1137,7 +1254,7 @@ static int tg3_mdio_init(struct tg3 *tp)
break;
}
- tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED;
+ tg3_flag_set(tp, MDIOBUS_INITED);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
tg3_mdio_config_5785(tp);
@@ -1147,59 +1264,13 @@ static int tg3_mdio_init(struct tg3 *tp)
static void tg3_mdio_fini(struct tg3 *tp)
{
- if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
- tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED;
+ if (tg3_flag(tp, MDIOBUS_INITED)) {
+ tg3_flag_clear(tp, MDIOBUS_INITED);
mdiobus_unregister(tp->mdio_bus);
mdiobus_free(tp->mdio_bus);
}
}
-static int tg3_phy_cl45_write(struct tg3 *tp, u32 devad, u32 addr, u32 val)
-{
- int err;
-
- err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad);
- if (err)
- goto done;
-
- err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr);
- if (err)
- goto done;
-
- err = tg3_writephy(tp, MII_TG3_MMD_CTRL,
- MII_TG3_MMD_CTRL_DATA_NOINC | devad);
- if (err)
- goto done;
-
- err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, val);
-
-done:
- return err;
-}
-
-static int tg3_phy_cl45_read(struct tg3 *tp, u32 devad, u32 addr, u32 *val)
-{
- int err;
-
- err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad);
- if (err)
- goto done;
-
- err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr);
- if (err)
- goto done;
-
- err = tg3_writephy(tp, MII_TG3_MMD_CTRL,
- MII_TG3_MMD_CTRL_DATA_NOINC | devad);
- if (err)
- goto done;
-
- err = tg3_readphy(tp, MII_TG3_MMD_ADDRESS, val);
-
-done:
- return err;
-}
-
/* tp->lock is held. */
static inline void tg3_generate_fw_event(struct tg3 *tp)
{
@@ -1247,8 +1318,7 @@ static void tg3_ump_link_report(struct tg3 *tp)
u32 reg;
u32 val;
- if (!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
- !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+ if (!tg3_flag(tp, 5780_CLASS) || !tg3_flag(tp, ENABLE_ASF))
return;
tg3_wait_for_event_ack(tp);
@@ -1308,6 +1378,11 @@ static void tg3_link_report(struct tg3 *tp)
"on" : "off",
(tp->link_config.active_flowctrl & FLOW_CTRL_RX) ?
"on" : "off");
+
+ if (tp->phy_flags & TG3_PHYFLG_EEE_CAP)
+ netdev_info(tp->dev, "EEE is %s\n",
+ tp->setlpicnt ? "enabled" : "disabled");
+
tg3_ump_link_report(tp);
}
}
@@ -1373,13 +1448,12 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
u32 old_rx_mode = tp->rx_mode;
u32 old_tx_mode = tp->tx_mode;
- if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
+ if (tg3_flag(tp, USE_PHYLIB))
autoneg = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]->autoneg;
else
autoneg = tp->link_config.autoneg;
- if (autoneg == AUTONEG_ENABLE &&
- (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)) {
+ if (autoneg == AUTONEG_ENABLE && tg3_flag(tp, PAUSE_AUTONEG)) {
if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES)
flowctrl = tg3_resolve_flowctrl_1000X(lcladv, rmtadv);
else
@@ -1576,28 +1650,6 @@ static void tg3_phy_fini(struct tg3 *tp)
}
}
-static int tg3_phydsp_read(struct tg3 *tp, u32 reg, u32 *val)
-{
- int err;
-
- err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
- if (!err)
- err = tg3_readphy(tp, MII_TG3_DSP_RW_PORT, val);
-
- return err;
-}
-
-static int tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
-{
- int err;
-
- err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
- if (!err)
- err = tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
-
- return err;
-}
-
static void tg3_phy_fet_toggle_apd(struct tg3 *tp, bool enable)
{
u32 phytest;
@@ -1622,9 +1674,8 @@ static void tg3_phy_toggle_apd(struct tg3 *tp, bool enable)
{
u32 reg;
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
- ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) &&
+ if (!tg3_flag(tp, 5705_PLUS) ||
+ (tg3_flag(tp, 5717_PLUS) &&
(tp->phy_flags & TG3_PHYFLG_MII_SERDES)))
return;
@@ -1658,7 +1709,7 @@ static void tg3_phy_toggle_automdix(struct tg3 *tp, int enable)
{
u32 phy;
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
+ if (!tg3_flag(tp, 5705_PLUS) ||
(tp->phy_flags & TG3_PHYFLG_ANY_SERDES))
return;
@@ -1680,31 +1731,33 @@ static void tg3_phy_toggle_automdix(struct tg3 *tp, int enable)
tg3_writephy(tp, MII_TG3_FET_TEST, ephy);
}
} else {
- phy = MII_TG3_AUXCTL_MISC_RDSEL_MISC |
- MII_TG3_AUXCTL_SHDWSEL_MISC;
- if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, phy) &&
- !tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy)) {
+ int ret;
+
+ ret = tg3_phy_auxctl_read(tp,
+ MII_TG3_AUXCTL_SHDWSEL_MISC, &phy);
+ if (!ret) {
if (enable)
phy |= MII_TG3_AUXCTL_MISC_FORCE_AMDIX;
else
phy &= ~MII_TG3_AUXCTL_MISC_FORCE_AMDIX;
- phy |= MII_TG3_AUXCTL_MISC_WREN;
- tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
+ tg3_phy_auxctl_write(tp,
+ MII_TG3_AUXCTL_SHDWSEL_MISC, phy);
}
}
}
static void tg3_phy_set_wirespeed(struct tg3 *tp)
{
+ int ret;
u32 val;
if (tp->phy_flags & TG3_PHYFLG_NO_ETH_WIRE_SPEED)
return;
- if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007) &&
- !tg3_readphy(tp, MII_TG3_AUX_CTRL, &val))
- tg3_writephy(tp, MII_TG3_AUX_CTRL,
- (val | (1 << 15) | (1 << 4)));
+ ret = tg3_phy_auxctl_read(tp, MII_TG3_AUXCTL_SHDWSEL_MISC, &val);
+ if (!ret)
+ tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_MISC,
+ val | MII_TG3_AUXCTL_MISC_WIRESPD_EN);
}
static void tg3_phy_apply_otp(struct tg3 *tp)
@@ -1716,11 +1769,8 @@ static void tg3_phy_apply_otp(struct tg3 *tp)
otp = tp->phy_otp;
- /* Enable SM_DSP clock and tx 6dB coding. */
- phy = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
- MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
- MII_TG3_AUXCTL_ACTL_TX_6DB;
- tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
+ if (TG3_PHY_AUXCTL_SMDSP_ENABLE(tp))
+ return;
phy = ((otp & TG3_OTP_AGCTGT_MASK) >> TG3_OTP_AGCTGT_SHIFT);
phy |= MII_TG3_DSP_TAP1_AGCTGT_DFLT;
@@ -1744,10 +1794,7 @@ static void tg3_phy_apply_otp(struct tg3 *tp)
((otp & TG3_OTP_RCOFF_MASK) >> TG3_OTP_RCOFF_SHIFT);
tg3_phydsp_write(tp, MII_TG3_DSP_EXP97, phy);
- /* Turn off SM_DSP clock. */
- phy = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
- MII_TG3_AUXCTL_ACTL_TX_6DB;
- tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
+ TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
}
static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
@@ -1776,29 +1823,9 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
tg3_phy_cl45_read(tp, MDIO_MMD_AN,
TG3_CL45_D7_EEERES_STAT, &val);
- switch (val) {
- case TG3_CL45_D7_EEERES_STAT_LP_1000T:
- switch (GET_ASIC_REV(tp->pci_chip_rev_id)) {
- case ASIC_REV_5717:
- case ASIC_REV_5719:
- case ASIC_REV_57765:
- /* Enable SM_DSP clock and tx 6dB coding. */
- val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
- MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
- MII_TG3_AUXCTL_ACTL_TX_6DB;
- tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
-
- tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000);
-
- /* Turn off SM_DSP clock. */
- val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
- MII_TG3_AUXCTL_ACTL_TX_6DB;
- tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
- }
- /* Fallthrough */
- case TG3_CL45_D7_EEERES_STAT_LP_100TX:
+ if (val == TG3_CL45_D7_EEERES_STAT_LP_1000T ||
+ val == TG3_CL45_D7_EEERES_STAT_LP_100TX)
tp->setlpicnt = 2;
- }
}
if (!tp->setlpicnt) {
@@ -1807,6 +1834,23 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
}
}
+static void tg3_phy_eee_enable(struct tg3 *tp)
+{
+ u32 val;
+
+ if (tp->link_config.active_speed == SPEED_1000 &&
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) &&
+ !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+ tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0003);
+ TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+ }
+
+ val = tr32(TG3_CPMU_EEE_MODE);
+ tw32(TG3_CPMU_EEE_MODE, val | TG3_CPMU_EEEMD_LPI_ENABLE);
+}
+
static int tg3_wait_macro_done(struct tg3 *tp)
{
int limit = 100;
@@ -1945,8 +1989,9 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
(MII_TG3_CTRL_AS_MASTER |
MII_TG3_CTRL_ENABLE_AS_MASTER));
- /* Enable SM_DSP_CLOCK and 6dB. */
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
+ err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp);
+ if (err)
+ return err;
/* Block the PHY control access. */
tg3_phydsp_write(tp, 0x8005, 0x0800);
@@ -1965,13 +2010,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200);
tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0000);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
- /* Set Extended packet length bit for jumbo frames */
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4400);
- } else {
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
- }
+ TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
tg3_writephy(tp, MII_TG3_CTRL, phy9_orig);
@@ -2047,8 +2086,7 @@ static int tg3_phy_reset(struct tg3 *tp)
}
}
- if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) &&
+ if (tg3_flag(tp, 5717_PLUS) &&
(tp->phy_flags & TG3_PHYFLG_MII_SERDES))
return 0;
@@ -2060,49 +2098,57 @@ static int tg3_phy_reset(struct tg3 *tp)
tg3_phy_toggle_apd(tp, false);
out:
- if (tp->phy_flags & TG3_PHYFLG_ADC_BUG) {
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
+ if ((tp->phy_flags & TG3_PHYFLG_ADC_BUG) &&
+ !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
tg3_phydsp_write(tp, 0x201f, 0x2aaa);
tg3_phydsp_write(tp, 0x000a, 0x0323);
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+ TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
}
+
if (tp->phy_flags & TG3_PHYFLG_5704_A0_BUG) {
tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68);
tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68);
}
+
if (tp->phy_flags & TG3_PHYFLG_BER_BUG) {
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
- tg3_phydsp_write(tp, 0x000a, 0x310b);
- tg3_phydsp_write(tp, 0x201f, 0x9506);
- tg3_phydsp_write(tp, 0x401f, 0x14e2);
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+ if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+ tg3_phydsp_write(tp, 0x000a, 0x310b);
+ tg3_phydsp_write(tp, 0x201f, 0x9506);
+ tg3_phydsp_write(tp, 0x401f, 0x14e2);
+ TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+ }
} else if (tp->phy_flags & TG3_PHYFLG_JITTER_BUG) {
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
- tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a);
- if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) {
- tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b);
- tg3_writephy(tp, MII_TG3_TEST1,
- MII_TG3_TEST1_TRIM_EN | 0x4);
- } else
- tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b);
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+ if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+ tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a);
+ if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) {
+ tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b);
+ tg3_writephy(tp, MII_TG3_TEST1,
+ MII_TG3_TEST1_TRIM_EN | 0x4);
+ } else
+ tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b);
+
+ TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+ }
}
+
/* Set Extended packet length bit (bit 14) on all chips that */
/* support jumbo frames */
if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5401) {
/* Cannot do read-modify-write on 5401 */
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
- } else if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
+ tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, 0x4c20);
+ } else if (tg3_flag(tp, JUMBO_CAPABLE)) {
/* Set bit 14 with read-modify-write to preserve other bits */
- if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0007) &&
- !tg3_readphy(tp, MII_TG3_AUX_CTRL, &val))
- tg3_writephy(tp, MII_TG3_AUX_CTRL, val | 0x4000);
+ err = tg3_phy_auxctl_read(tp,
+ MII_TG3_AUXCTL_SHDWSEL_AUXCTL, &val);
+ if (!err)
+ tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL,
+ val | MII_TG3_AUXCTL_ACTL_EXTPKTLEN);
}
/* Set phy register 0x10 bit 0 to high fifo elasticity to support
* jumbo frames transmission.
*/
- if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
+ if (tg3_flag(tp, JUMBO_CAPABLE)) {
if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &val))
tg3_writephy(tp, MII_TG3_EXT_CTRL,
val | MII_TG3_EXT_CTRL_FIFO_ELASTIC);
@@ -2123,14 +2169,15 @@ static void tg3_frob_aux_power(struct tg3 *tp)
bool need_vaux = false;
/* The GPIOs do something completely different on 57765. */
- if ((tp->tg3_flags2 & TG3_FLG2_IS_NIC) == 0 ||
+ if (!tg3_flag(tp, IS_NIC) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
return;
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) &&
tp->pdev_peer != tp->pdev) {
struct net_device *dev_peer;
@@ -2140,17 +2187,16 @@ static void tg3_frob_aux_power(struct tg3 *tp)
if (dev_peer) {
struct tg3 *tp_peer = netdev_priv(dev_peer);
- if (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE)
+ if (tg3_flag(tp_peer, INIT_COMPLETE))
return;
- if ((tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) ||
- (tp_peer->tg3_flags & TG3_FLAG_ENABLE_ASF))
+ if (tg3_flag(tp_peer, WOL_ENABLE) ||
+ tg3_flag(tp_peer, ENABLE_ASF))
need_vaux = true;
}
}
- if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) ||
- (tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+ if (tg3_flag(tp, WOL_ENABLE) || tg3_flag(tp, ENABLE_ASF))
need_vaux = true;
if (need_vaux) {
@@ -2304,11 +2350,10 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
tg3_writephy(tp, MII_TG3_EXT_CTRL,
MII_TG3_EXT_CTRL_FORCE_LED_OFF);
- tg3_writephy(tp, MII_TG3_AUX_CTRL,
- MII_TG3_AUXCTL_SHDWSEL_PWRCTL |
- MII_TG3_AUXCTL_PCTL_100TX_LPWR |
- MII_TG3_AUXCTL_PCTL_SPR_ISOLATE |
- MII_TG3_AUXCTL_PCTL_VREG_11V);
+ val = MII_TG3_AUXCTL_PCTL_100TX_LPWR |
+ MII_TG3_AUXCTL_PCTL_SPR_ISOLATE |
+ MII_TG3_AUXCTL_PCTL_VREG_11V;
+ tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_PWRCTL, val);
}
/* The PHY should not be powered down on some chips because
@@ -2334,7 +2379,7 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
/* tp->lock is held. */
static int tg3_nvram_lock(struct tg3 *tp)
{
- if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+ if (tg3_flag(tp, NVRAM)) {
int i;
if (tp->nvram_lock_cnt == 0) {
@@ -2357,7 +2402,7 @@ static int tg3_nvram_lock(struct tg3 *tp)
/* tp->lock is held. */
static void tg3_nvram_unlock(struct tg3 *tp)
{
- if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+ if (tg3_flag(tp, NVRAM)) {
if (tp->nvram_lock_cnt > 0)
tp->nvram_lock_cnt--;
if (tp->nvram_lock_cnt == 0)
@@ -2368,8 +2413,7 @@ static void tg3_nvram_unlock(struct tg3 *tp)
/* tp->lock is held. */
static void tg3_enable_nvram_access(struct tg3 *tp)
{
- if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
- !(tp->tg3_flags3 & TG3_FLG3_PROTECTED_NVRAM)) {
+ if (tg3_flag(tp, 5750_PLUS) && !tg3_flag(tp, PROTECTED_NVRAM)) {
u32 nvaccess = tr32(NVRAM_ACCESS);
tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
@@ -2379,8 +2423,7 @@ static void tg3_enable_nvram_access(struct tg3 *tp)
/* tp->lock is held. */
static void tg3_disable_nvram_access(struct tg3 *tp)
{
- if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
- !(tp->tg3_flags3 & TG3_FLG3_PROTECTED_NVRAM)) {
+ if (tg3_flag(tp, 5750_PLUS) && !tg3_flag(tp, PROTECTED_NVRAM)) {
u32 nvaccess = tr32(NVRAM_ACCESS);
tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
@@ -2450,10 +2493,10 @@ static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd)
static u32 tg3_nvram_phys_addr(struct tg3 *tp, u32 addr)
{
- if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
- (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
- (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
- !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
+ if (tg3_flag(tp, NVRAM) &&
+ tg3_flag(tp, NVRAM_BUFFERED) &&
+ tg3_flag(tp, FLASH) &&
+ !tg3_flag(tp, NO_NVRAM_ADDR_TRANS) &&
(tp->nvram_jedecnum == JEDEC_ATMEL))
addr = ((addr / tp->nvram_pagesize) <<
@@ -2465,10 +2508,10 @@ static u32 tg3_nvram_phys_addr(struct tg3 *tp, u32 addr)
static u32 tg3_nvram_logical_addr(struct tg3 *tp, u32 addr)
{
- if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
- (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
- (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
- !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
+ if (tg3_flag(tp, NVRAM) &&
+ tg3_flag(tp, NVRAM_BUFFERED) &&
+ tg3_flag(tp, FLASH) &&
+ !tg3_flag(tp, NO_NVRAM_ADDR_TRANS) &&
(tp->nvram_jedecnum == JEDEC_ATMEL))
addr = ((addr >> ATMEL_AT45DB0X1B_PAGE_POS) *
@@ -2488,7 +2531,7 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
{
int ret;
- if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
+ if (!tg3_flag(tp, NVRAM))
return tg3_nvram_read_using_eeprom(tp, offset, val);
offset = tg3_nvram_phys_addr(tp, offset);
@@ -2580,7 +2623,7 @@ static int tg3_power_up(struct tg3 *tp)
pci_set_power_state(tp->pdev, PCI_D0);
/* Switch out of Vaux if it is a NIC */
- if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
+ if (tg3_flag(tp, IS_NIC))
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100);
return 0;
@@ -2594,7 +2637,7 @@ static int tg3_power_down_prepare(struct tg3 *tp)
tg3_enable_register_access(tp);
/* Restore the CLKREQ setting. */
- if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG) {
+ if (tg3_flag(tp, CLKREQ_BUG)) {
u16 lnkctl;
pci_read_config_word(tp->pdev,
@@ -2611,9 +2654,9 @@ static int tg3_power_down_prepare(struct tg3 *tp)
misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
device_should_wake = device_may_wakeup(&tp->pdev->dev) &&
- (tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
+ tg3_flag(tp, WOL_ENABLE);
- if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ if (tg3_flag(tp, USE_PHYLIB)) {
do_low_power = false;
if ((tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) &&
!(tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) {
@@ -2634,9 +2677,8 @@ static int tg3_power_down_prepare(struct tg3 *tp)
ADVERTISED_Autoneg |
ADVERTISED_10baseT_Half;
- if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
- device_should_wake) {
- if (tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB)
+ if (tg3_flag(tp, ENABLE_ASF) || device_should_wake) {
+ if (tg3_flag(tp, WOL_SPEED_100MB))
advertising |=
ADVERTISED_100baseT_Half |
ADVERTISED_100baseT_Full |
@@ -2681,7 +2723,7 @@ static int tg3_power_down_prepare(struct tg3 *tp)
val = tr32(GRC_VCPU_EXT_CTRL);
tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_DISABLE_WOL);
- } else if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+ } else if (!tg3_flag(tp, ENABLE_ASF)) {
int i;
u32 val;
@@ -2692,7 +2734,7 @@ static int tg3_power_down_prepare(struct tg3 *tp)
msleep(1);
}
}
- if (tp->tg3_flags & TG3_FLAG_WOL_CAP)
+ if (tg3_flag(tp, WOL_CAP))
tg3_write_mem(tp, NIC_SRAM_WOL_MBOX, WOL_SIGNATURE |
WOL_DRV_STATE_SHUTDOWN |
WOL_DRV_WOL |
@@ -2702,8 +2744,13 @@ static int tg3_power_down_prepare(struct tg3 *tp)
u32 mac_mode;
if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) {
- if (do_low_power) {
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
+ if (do_low_power &&
+ !(tp->phy_flags & TG3_PHYFLG_IS_FET)) {
+ tg3_phy_auxctl_write(tp,
+ MII_TG3_AUXCTL_SHDWSEL_PWRCTL,
+ MII_TG3_AUXCTL_PCTL_WOL_EN |
+ MII_TG3_AUXCTL_PCTL_100TX_LPWR |
+ MII_TG3_AUXCTL_PCTL_CL_AB_TXDAC);
udelay(40);
}
@@ -2715,8 +2762,7 @@ static int tg3_power_down_prepare(struct tg3 *tp)
mac_mode |= tp->mac_mode & MAC_MODE_LINK_POLARITY;
if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
ASIC_REV_5700) {
- u32 speed = (tp->tg3_flags &
- TG3_FLAG_WOL_SPEED_100MB) ?
+ u32 speed = tg3_flag(tp, WOL_SPEED_100MB) ?
SPEED_100 : SPEED_10;
if (tg3_5700_link_polarity(tp, speed))
mac_mode |= MAC_MODE_LINK_POLARITY;
@@ -2727,17 +2773,15 @@ static int tg3_power_down_prepare(struct tg3 *tp)
mac_mode = MAC_MODE_PORT_MODE_TBI;
}
- if (!(tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
+ if (!tg3_flag(tp, 5750_PLUS))
tw32(MAC_LED_CTRL, tp->led_ctrl);
mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
- if (((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
- !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) &&
- ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
- (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)))
+ if ((tg3_flag(tp, 5705_PLUS) && !tg3_flag(tp, 5780_CLASS)) &&
+ (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE)))
mac_mode |= MAC_MODE_KEEP_FRAME_IN_WOL;
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+ if (tg3_flag(tp, ENABLE_APE))
mac_mode |= MAC_MODE_APE_TX_EN |
MAC_MODE_APE_RX_EN |
MAC_MODE_TDE_ENABLE;
@@ -2749,7 +2793,7 @@ static int tg3_power_down_prepare(struct tg3 *tp)
udelay(10);
}
- if (!(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB) &&
+ if (!tg3_flag(tp, WOL_SPEED_100MB) &&
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
u32 base_val;
@@ -2760,12 +2804,11 @@ static int tg3_power_down_prepare(struct tg3 *tp)
tw32_wait_f(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK |
CLOCK_CTRL_PWRDOWN_PLL133, 40);
- } else if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
- (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) ||
- (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)) {
+ } else if (tg3_flag(tp, 5780_CLASS) ||
+ tg3_flag(tp, CPMU_PRESENT) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
/* do nothing */
- } else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
- (tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) {
+ } else if (!(tg3_flag(tp, 5750_PLUS) && tg3_flag(tp, ENABLE_ASF))) {
u32 newbits1, newbits2;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
@@ -2774,7 +2817,7 @@ static int tg3_power_down_prepare(struct tg3 *tp)
CLOCK_CTRL_TXCLK_DISABLE |
CLOCK_CTRL_ALTCLK);
newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE;
- } else if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+ } else if (tg3_flag(tp, 5705_PLUS)) {
newbits1 = CLOCK_CTRL_625_CORE;
newbits2 = newbits1 | CLOCK_CTRL_ALTCLK;
} else {
@@ -2788,7 +2831,7 @@ static int tg3_power_down_prepare(struct tg3 *tp)
tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2,
40);
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+ if (!tg3_flag(tp, 5705_PLUS)) {
u32 newbits3;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
@@ -2805,8 +2848,7 @@ static int tg3_power_down_prepare(struct tg3 *tp)
}
}
- if (!(device_should_wake) &&
- !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+ if (!(device_should_wake) && !tg3_flag(tp, ENABLE_ASF))
tg3_power_down_phy(tp, do_low_power);
tg3_frob_aux_power(tp);
@@ -2818,7 +2860,7 @@ static int tg3_power_down_prepare(struct tg3 *tp)
val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1);
tw32(0x7d00, val);
- if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+ if (!tg3_flag(tp, ENABLE_ASF)) {
int err;
err = tg3_nvram_lock(tp);
@@ -2837,7 +2879,7 @@ static void tg3_power_down(struct tg3 *tp)
{
tg3_power_down_prepare(tp);
- pci_wake_from_d3(tp->pdev, tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
+ pci_wake_from_d3(tp->pdev, tg3_flag(tp, WOL_ENABLE));
pci_set_power_state(tp->pdev, PCI_D3hot);
}
@@ -2888,106 +2930,54 @@ static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8
}
}
-static void tg3_phy_copper_begin(struct tg3 *tp)
+static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)
{
- u32 new_adv;
- int i;
+ int err = 0;
+ u32 val, new_adv;
- if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
- /* Entering low power mode. Disable gigabit and
- * 100baseT advertisements.
- */
- tg3_writephy(tp, MII_TG3_CTRL, 0);
+ new_adv = ADVERTISE_CSMA;
+ if (advertise & ADVERTISED_10baseT_Half)
+ new_adv |= ADVERTISE_10HALF;
+ if (advertise & ADVERTISED_10baseT_Full)
+ new_adv |= ADVERTISE_10FULL;
+ if (advertise & ADVERTISED_100baseT_Half)
+ new_adv |= ADVERTISE_100HALF;
+ if (advertise & ADVERTISED_100baseT_Full)
+ new_adv |= ADVERTISE_100FULL;
- new_adv = (ADVERTISE_10HALF | ADVERTISE_10FULL |
- ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
- if (tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB)
- new_adv |= (ADVERTISE_100HALF | ADVERTISE_100FULL);
+ new_adv |= tg3_advert_flowctrl_1000T(flowctrl);
- tg3_writephy(tp, MII_ADVERTISE, new_adv);
- } else if (tp->link_config.speed == SPEED_INVALID) {
- if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
- tp->link_config.advertising &=
- ~(ADVERTISED_1000baseT_Half |
- ADVERTISED_1000baseT_Full);
+ err = tg3_writephy(tp, MII_ADVERTISE, new_adv);
+ if (err)
+ goto done;
- new_adv = ADVERTISE_CSMA;
- if (tp->link_config.advertising & ADVERTISED_10baseT_Half)
- new_adv |= ADVERTISE_10HALF;
- if (tp->link_config.advertising & ADVERTISED_10baseT_Full)
- new_adv |= ADVERTISE_10FULL;
- if (tp->link_config.advertising & ADVERTISED_100baseT_Half)
- 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 &
- (ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full)) {
- new_adv = 0;
- if (tp->link_config.advertising & ADVERTISED_1000baseT_Half)
- new_adv |= MII_TG3_CTRL_ADV_1000_HALF;
- if (tp->link_config.advertising & ADVERTISED_1000baseT_Full)
- new_adv |= MII_TG3_CTRL_ADV_1000_FULL;
- if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY) &&
- (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
- 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);
- }
- } else {
- new_adv = tg3_advert_flowctrl_1000T(tp->link_config.flowctrl);
- new_adv |= ADVERTISE_CSMA;
+ if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
+ goto done;
- /* Asking for a specific link mode. */
- if (tp->link_config.speed == SPEED_1000) {
- tg3_writephy(tp, MII_ADVERTISE, new_adv);
+ new_adv = 0;
+ if (advertise & ADVERTISED_1000baseT_Half)
+ new_adv |= MII_TG3_CTRL_ADV_1000_HALF;
+ if (advertise & ADVERTISED_1000baseT_Full)
+ new_adv |= MII_TG3_CTRL_ADV_1000_FULL;
- if (tp->link_config.duplex == DUPLEX_FULL)
- new_adv = MII_TG3_CTRL_ADV_1000_FULL;
- else
- new_adv = MII_TG3_CTRL_ADV_1000_HALF;
- if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
- tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)
- new_adv |= (MII_TG3_CTRL_AS_MASTER |
- MII_TG3_CTRL_ENABLE_AS_MASTER);
- } else {
- if (tp->link_config.speed == SPEED_100) {
- if (tp->link_config.duplex == DUPLEX_FULL)
- new_adv |= ADVERTISE_100FULL;
- else
- new_adv |= ADVERTISE_100HALF;
- } else {
- if (tp->link_config.duplex == DUPLEX_FULL)
- new_adv |= ADVERTISE_10FULL;
- else
- new_adv |= ADVERTISE_10HALF;
- }
- tg3_writephy(tp, MII_ADVERTISE, new_adv);
-
- new_adv = 0;
- }
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
+ 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);
- }
+ err = tg3_writephy(tp, MII_TG3_CTRL, new_adv);
+ if (err)
+ goto done;
- if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
- u32 val;
+ if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP))
+ goto done;
- tw32(TG3_CPMU_EEE_MODE,
- tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE);
+ tw32(TG3_CPMU_EEE_MODE,
+ tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE);
- /* Enable SM_DSP clock and tx 6dB coding. */
- val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
- MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
- MII_TG3_AUXCTL_ACTL_TX_6DB;
- tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
+ err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp);
+ if (!err) {
+ u32 err2;
switch (GET_ASIC_REV(tp->pci_chip_rev_id)) {
case ASIC_REV_5717:
@@ -3004,22 +2994,66 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
}
val = 0;
- if (tp->link_config.autoneg == AUTONEG_ENABLE) {
- /* Advertise 100-BaseTX EEE ability */
- if (tp->link_config.advertising &
- ADVERTISED_100baseT_Full)
- val |= MDIO_AN_EEE_ADV_100TX;
- /* Advertise 1000-BaseT EEE ability */
- if (tp->link_config.advertising &
- ADVERTISED_1000baseT_Full)
- val |= MDIO_AN_EEE_ADV_1000T;
+ /* Advertise 100-BaseTX EEE ability */
+ if (advertise & ADVERTISED_100baseT_Full)
+ val |= MDIO_AN_EEE_ADV_100TX;
+ /* Advertise 1000-BaseT EEE ability */
+ if (advertise & ADVERTISED_1000baseT_Full)
+ val |= MDIO_AN_EEE_ADV_1000T;
+ err = tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
+
+ err2 = TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+ if (!err)
+ err = err2;
+ }
+
+done:
+ return err;
+}
+
+static void tg3_phy_copper_begin(struct tg3 *tp)
+{
+ u32 new_adv;
+ int i;
+
+ if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
+ new_adv = ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full;
+ if (tg3_flag(tp, WOL_SPEED_100MB))
+ new_adv |= ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full;
+
+ tg3_phy_autoneg_cfg(tp, new_adv,
+ FLOW_CTRL_TX | FLOW_CTRL_RX);
+ } else if (tp->link_config.speed == SPEED_INVALID) {
+ if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
+ tp->link_config.advertising &=
+ ~(ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full);
+
+ tg3_phy_autoneg_cfg(tp, tp->link_config.advertising,
+ tp->link_config.flowctrl);
+ } else {
+ /* Asking for a specific link mode. */
+ if (tp->link_config.speed == SPEED_1000) {
+ if (tp->link_config.duplex == DUPLEX_FULL)
+ new_adv = ADVERTISED_1000baseT_Full;
+ else
+ new_adv = ADVERTISED_1000baseT_Half;
+ } else if (tp->link_config.speed == SPEED_100) {
+ if (tp->link_config.duplex == DUPLEX_FULL)
+ new_adv = ADVERTISED_100baseT_Full;
+ else
+ new_adv = ADVERTISED_100baseT_Half;
+ } else {
+ if (tp->link_config.duplex == DUPLEX_FULL)
+ new_adv = ADVERTISED_10baseT_Full;
+ else
+ new_adv = ADVERTISED_10baseT_Half;
}
- tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
- /* Turn off SM_DSP clock. */
- val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
- MII_TG3_AUXCTL_ACTL_TX_6DB;
- tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
+ tg3_phy_autoneg_cfg(tp, new_adv,
+ tp->link_config.flowctrl);
}
if (tp->link_config.autoneg == AUTONEG_DISABLE &&
@@ -3077,7 +3111,7 @@ static int tg3_init_5401phy_dsp(struct tg3 *tp)
/* Turn off tap power management. */
/* Set Extended packet length bit */
- err = tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
+ err = tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, 0x4c20);
err |= tg3_phydsp_write(tp, 0x0012, 0x1804);
err |= tg3_phydsp_write(tp, 0x0013, 0x1204);
@@ -3140,7 +3174,7 @@ static int tg3_adv_1000T_flowctrl_ok(struct tg3 *tp, u32 *lcladv, u32 *rmtadv)
if (curadv != reqadv)
return 0;
- if (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)
+ if (tg3_flag(tp, PAUSE_AUTONEG))
tg3_readphy(tp, MII_LPA, rmtadv);
} else {
/* Reprogram the advertisement register, even if it
@@ -3183,7 +3217,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
udelay(80);
}
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02);
+ tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_PWRCTL, 0);
/* Some third-party PHYs need to be reset on link going
* down.
@@ -3203,7 +3237,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5401) {
tg3_readphy(tp, MII_BMSR, &bmsr);
if (tg3_readphy(tp, MII_BMSR, &bmsr) ||
- !(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE))
+ !tg3_flag(tp, INIT_COMPLETE))
bmsr = 0;
if (!(bmsr & BMSR_LSTATUS)) {
@@ -3264,11 +3298,13 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
current_duplex = DUPLEX_INVALID;
if (tp->phy_flags & TG3_PHYFLG_CAPACITIVE_COUPLING) {
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4007);
- tg3_readphy(tp, MII_TG3_AUX_CTRL, &val);
- if (!(val & (1 << 10))) {
- val |= (1 << 10);
- tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
+ err = tg3_phy_auxctl_read(tp,
+ MII_TG3_AUXCTL_SHDWSEL_MISCTEST,
+ &val);
+ if (!err && !(val & (1 << 10))) {
+ tg3_phy_auxctl_write(tp,
+ MII_TG3_AUXCTL_SHDWSEL_MISCTEST,
+ val | (1 << 10));
goto relink;
}
}
@@ -3341,8 +3377,8 @@ relink:
tg3_phy_copper_begin(tp);
tg3_readphy(tp, MII_BMSR, &bmsr);
- if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
- (bmsr & BMSR_LSTATUS))
+ if ((!tg3_readphy(tp, MII_BMSR, &bmsr) && (bmsr & BMSR_LSTATUS)) ||
+ (tp->mac_mode & MAC_MODE_PORT_INT_LPBACK))
current_link_up = 1;
}
@@ -3385,7 +3421,7 @@ relink:
tg3_phy_eee_adjust(tp, current_link_up);
- if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) {
+ if (tg3_flag(tp, USE_LINKCHG_REG)) {
/* Polled via timer. */
tw32_f(MAC_EVENT, 0);
} else {
@@ -3396,8 +3432,7 @@ relink:
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 &&
current_link_up == 1 &&
tp->link_config.active_speed == SPEED_1000 &&
- ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ||
- (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED))) {
+ (tg3_flag(tp, PCIX_MODE) || tg3_flag(tp, PCI_HIGH_SPEED))) {
udelay(120);
tw32_f(MAC_STATUS,
(MAC_STATUS_SYNC_CHANGED |
@@ -3409,7 +3444,7 @@ relink:
}
/* Prevent send BD corruption. */
- if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG) {
+ if (tg3_flag(tp, CLKREQ_BUG)) {
u16 oldlnkctl, newlnkctl;
pci_read_config_word(tp->pdev,
@@ -3804,7 +3839,7 @@ static void tg3_init_bcm8002(struct tg3 *tp)
int i;
/* Reset when initting first time or we have a link. */
- if ((tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) &&
+ if (tg3_flag(tp, INIT_COMPLETE) &&
!(mac_status & MAC_STATUS_PCS_SYNCED))
return;
@@ -4065,9 +4100,9 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
orig_active_speed = tp->link_config.active_speed;
orig_active_duplex = tp->link_config.active_duplex;
- if (!(tp->tg3_flags2 & TG3_FLG2_HW_AUTONEG) &&
+ if (!tg3_flag(tp, HW_AUTONEG) &&
netif_carrier_ok(tp->dev) &&
- (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)) {
+ tg3_flag(tp, INIT_COMPLETE)) {
mac_status = tr32(MAC_STATUS);
mac_status &= (MAC_STATUS_PCS_SYNCED |
MAC_STATUS_SIGNAL_DET |
@@ -4098,7 +4133,7 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
current_link_up = 0;
mac_status = tr32(MAC_STATUS);
- if (tp->tg3_flags2 & TG3_FLG2_HW_AUTONEG)
+ if (tg3_flag(tp, HW_AUTONEG))
current_link_up = tg3_setup_fiber_hw_autoneg(tp, mac_status);
else
current_link_up = tg3_setup_fiber_by_hand(tp, mac_status);
@@ -4297,7 +4332,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
current_duplex = DUPLEX_FULL;
else
current_duplex = DUPLEX_HALF;
- } else if (!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+ } else if (!tg3_flag(tp, 5780_CLASS)) {
/* Link is up via parallel detect */
} else {
current_link_up = 0;
@@ -4394,6 +4429,7 @@ static void tg3_serdes_parallel_detect(struct tg3 *tp)
static int tg3_setup_phy(struct tg3 *tp, int force_reset)
{
+ u32 val;
int err;
if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
@@ -4404,7 +4440,7 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
err = tg3_setup_copper_phy(tp, force_reset);
if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX) {
- u32 val, scale;
+ u32 scale;
val = tr32(TG3_CPMU_CLCK_STAT) & CPMU_CLCK_STAT_MAC_CLCK_MASK;
if (val == CPMU_CLCK_STAT_MAC_CLCK_62_5)
@@ -4419,19 +4455,22 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
tw32(GRC_MISC_CFG, val);
}
+ val = (2 << TX_LENGTHS_IPG_CRS_SHIFT) |
+ (6 << TX_LENGTHS_IPG_SHIFT);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ val |= tr32(MAC_TX_LENGTHS) &
+ (TX_LENGTHS_JMB_FRM_LEN_MSK |
+ TX_LENGTHS_CNT_DWN_VAL_MSK);
+
if (tp->link_config.active_speed == SPEED_1000 &&
tp->link_config.active_duplex == DUPLEX_HALF)
- tw32(MAC_TX_LENGTHS,
- ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
- (6 << TX_LENGTHS_IPG_SHIFT) |
- (0xff << TX_LENGTHS_SLOT_TIME_SHIFT)));
+ tw32(MAC_TX_LENGTHS, val |
+ (0xff << TX_LENGTHS_SLOT_TIME_SHIFT));
else
- tw32(MAC_TX_LENGTHS,
- ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
- (6 << TX_LENGTHS_IPG_SHIFT) |
- (32 << TX_LENGTHS_SLOT_TIME_SHIFT)));
+ tw32(MAC_TX_LENGTHS, val |
+ (32 << TX_LENGTHS_SLOT_TIME_SHIFT));
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+ if (!tg3_flag(tp, 5705_PLUS)) {
if (netif_carrier_ok(tp->dev)) {
tw32(HOSTCC_STAT_COAL_TICKS,
tp->coal.stats_block_coalesce_usecs);
@@ -4440,8 +4479,8 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
}
}
- if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND) {
- u32 val = tr32(PCIE_PWR_MGMT_THRESH);
+ if (tg3_flag(tp, ASPM_WORKAROUND)) {
+ val = tr32(PCIE_PWR_MGMT_THRESH);
if (!netif_carrier_ok(tp->dev))
val = (val & ~PCIE_PWR_MGMT_L1_THRESH_MSK) |
tp->pwrmgmt_thresh;
@@ -4458,6 +4497,123 @@ static inline int tg3_irq_sync(struct tg3 *tp)
return tp->irq_sync;
}
+static inline void tg3_rd32_loop(struct tg3 *tp, u32 *dst, u32 off, u32 len)
+{
+ int i;
+
+ dst = (u32 *)((u8 *)dst + off);
+ for (i = 0; i < len; i += sizeof(u32))
+ *dst++ = tr32(off + i);
+}
+
+static void tg3_dump_legacy_regs(struct tg3 *tp, u32 *regs)
+{
+ tg3_rd32_loop(tp, regs, TG3PCI_VENDOR, 0xb0);
+ tg3_rd32_loop(tp, regs, MAILBOX_INTERRUPT_0, 0x200);
+ tg3_rd32_loop(tp, regs, MAC_MODE, 0x4f0);
+ tg3_rd32_loop(tp, regs, SNDDATAI_MODE, 0xe0);
+ tg3_rd32_loop(tp, regs, SNDDATAC_MODE, 0x04);
+ tg3_rd32_loop(tp, regs, SNDBDS_MODE, 0x80);
+ tg3_rd32_loop(tp, regs, SNDBDI_MODE, 0x48);
+ tg3_rd32_loop(tp, regs, SNDBDC_MODE, 0x04);
+ tg3_rd32_loop(tp, regs, RCVLPC_MODE, 0x20);
+ tg3_rd32_loop(tp, regs, RCVLPC_SELLST_BASE, 0x15c);
+ tg3_rd32_loop(tp, regs, RCVDBDI_MODE, 0x0c);
+ tg3_rd32_loop(tp, regs, RCVDBDI_JUMBO_BD, 0x3c);
+ tg3_rd32_loop(tp, regs, RCVDBDI_BD_PROD_IDX_0, 0x44);
+ tg3_rd32_loop(tp, regs, RCVDCC_MODE, 0x04);
+ tg3_rd32_loop(tp, regs, RCVBDI_MODE, 0x20);
+ tg3_rd32_loop(tp, regs, RCVCC_MODE, 0x14);
+ tg3_rd32_loop(tp, regs, RCVLSC_MODE, 0x08);
+ tg3_rd32_loop(tp, regs, MBFREE_MODE, 0x08);
+ tg3_rd32_loop(tp, regs, HOSTCC_MODE, 0x100);
+
+ if (tg3_flag(tp, SUPPORT_MSIX))
+ tg3_rd32_loop(tp, regs, HOSTCC_RXCOL_TICKS_VEC1, 0x180);
+
+ tg3_rd32_loop(tp, regs, MEMARB_MODE, 0x10);
+ tg3_rd32_loop(tp, regs, BUFMGR_MODE, 0x58);
+ tg3_rd32_loop(tp, regs, RDMAC_MODE, 0x08);
+ tg3_rd32_loop(tp, regs, WDMAC_MODE, 0x08);
+ tg3_rd32_loop(tp, regs, RX_CPU_MODE, 0x04);
+ tg3_rd32_loop(tp, regs, RX_CPU_STATE, 0x04);
+ tg3_rd32_loop(tp, regs, RX_CPU_PGMCTR, 0x04);
+ tg3_rd32_loop(tp, regs, RX_CPU_HWBKPT, 0x04);
+
+ if (!tg3_flag(tp, 5705_PLUS)) {
+ tg3_rd32_loop(tp, regs, TX_CPU_MODE, 0x04);
+ tg3_rd32_loop(tp, regs, TX_CPU_STATE, 0x04);
+ tg3_rd32_loop(tp, regs, TX_CPU_PGMCTR, 0x04);
+ }
+
+ tg3_rd32_loop(tp, regs, GRCMBOX_INTERRUPT_0, 0x110);
+ tg3_rd32_loop(tp, regs, FTQ_RESET, 0x120);
+ tg3_rd32_loop(tp, regs, MSGINT_MODE, 0x0c);
+ tg3_rd32_loop(tp, regs, DMAC_MODE, 0x04);
+ tg3_rd32_loop(tp, regs, GRC_MODE, 0x4c);
+
+ if (tg3_flag(tp, NVRAM))
+ tg3_rd32_loop(tp, regs, NVRAM_CMD, 0x24);
+}
+
+static void tg3_dump_state(struct tg3 *tp)
+{
+ int i;
+ u32 *regs;
+
+ regs = kzalloc(TG3_REG_BLK_SIZE, GFP_ATOMIC);
+ if (!regs) {
+ netdev_err(tp->dev, "Failed allocating register dump buffer\n");
+ return;
+ }
+
+ if (tg3_flag(tp, PCI_EXPRESS)) {
+ /* Read up to but not including private PCI registers */
+ for (i = 0; i < TG3_PCIE_TLDLPL_PORT; i += sizeof(u32))
+ regs[i / sizeof(u32)] = tr32(i);
+ } else
+ tg3_dump_legacy_regs(tp, regs);
+
+ for (i = 0; i < TG3_REG_BLK_SIZE / sizeof(u32); i += 4) {
+ if (!regs[i + 0] && !regs[i + 1] &&
+ !regs[i + 2] && !regs[i + 3])
+ continue;
+
+ netdev_err(tp->dev, "0x%08x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+ i * 4,
+ regs[i + 0], regs[i + 1], regs[i + 2], regs[i + 3]);
+ }
+
+ kfree(regs);
+
+ for (i = 0; i < tp->irq_cnt; i++) {
+ struct tg3_napi *tnapi = &tp->napi[i];
+
+ /* SW status block */
+ netdev_err(tp->dev,
+ "%d: Host status block [%08x:%08x:(%04x:%04x:%04x):(%04x:%04x)]\n",
+ i,
+ tnapi->hw_status->status,
+ tnapi->hw_status->status_tag,
+ tnapi->hw_status->rx_jumbo_consumer,
+ tnapi->hw_status->rx_consumer,
+ tnapi->hw_status->rx_mini_consumer,
+ tnapi->hw_status->idx[0].rx_producer,
+ tnapi->hw_status->idx[0].tx_consumer);
+
+ netdev_err(tp->dev,
+ "%d: NAPI info [%08x:%08x:(%04x:%04x:%04x):%04x:(%04x:%04x:%04x:%04x)]\n",
+ i,
+ tnapi->last_tag, tnapi->last_irq_tag,
+ tnapi->tx_prod, tnapi->tx_cons, tnapi->tx_pending,
+ tnapi->rx_rcb_ptr,
+ tnapi->prodring.rx_std_prod_idx,
+ tnapi->prodring.rx_std_cons_idx,
+ tnapi->prodring.rx_jmb_prod_idx,
+ tnapi->prodring.rx_jmb_cons_idx);
+ }
+}
+
/* This is called whenever we suspect that the system chipset is re-
* ordering the sequence of MMIO to the tx send mailbox. The symptom
* is bogus tx completions. We try to recover by setting the
@@ -4466,7 +4622,7 @@ static inline int tg3_irq_sync(struct tg3 *tp)
*/
static void tg3_tx_recover(struct tg3 *tp)
{
- BUG_ON((tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) ||
+ BUG_ON(tg3_flag(tp, MBOX_WRITE_REORDER) ||
tp->write32_tx_mbox == tg3_write_indirect_mbox);
netdev_warn(tp->dev,
@@ -4476,7 +4632,7 @@ static void tg3_tx_recover(struct tg3 *tp)
"and include system chipset information.\n");
spin_lock(&tp->lock);
- tp->tg3_flags |= TG3_FLAG_TX_RECOVERY_PENDING;
+ tg3_flag_set(tp, TX_RECOVERY_PENDING);
spin_unlock(&tp->lock);
}
@@ -4500,7 +4656,7 @@ static void tg3_tx(struct tg3_napi *tnapi)
struct netdev_queue *txq;
int index = tnapi - tp->napi;
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+ if (tg3_flag(tp, ENABLE_TSS))
index--;
txq = netdev_get_tx_queue(tp->dev, index);
@@ -4815,7 +4971,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
skb = copy_skb;
}
- if ((tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) &&
+ if ((tp->dev->features & NETIF_F_RXCSUM) &&
(desc->type_flags & RXD_FLAG_TCPUDP_CSUM) &&
(((desc->ip_tcp_csum & RXD_TCPCSUM_MASK)
>> RXD_TCPCSUM_SHIFT) == 0xffff))
@@ -4868,7 +5024,7 @@ next_pkt_nopost:
tw32_rx_mbox(tnapi->consmbox, sw_idx);
/* Refill RX ring(s). */
- if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)) {
+ if (!tg3_flag(tp, ENABLE_RSS)) {
if (work_mask & RXD_OPAQUE_RING_STD) {
tpr->rx_std_prod_idx = std_prod_idx &
tp->rx_std_ring_mask;
@@ -4901,16 +5057,14 @@ next_pkt_nopost:
static void tg3_poll_link(struct tg3 *tp)
{
/* handle link change and other phy events */
- if (!(tp->tg3_flags &
- (TG3_FLAG_USE_LINKCHG_REG |
- TG3_FLAG_POLL_SERDES))) {
+ if (!(tg3_flag(tp, USE_LINKCHG_REG) || tg3_flag(tp, POLL_SERDES))) {
struct tg3_hw_status *sblk = tp->napi[0].hw_status;
if (sblk->status & SD_STATUS_LINK_CHG) {
sblk->status = SD_STATUS_UPDATED |
(sblk->status & ~SD_STATUS_LINK_CHG);
spin_lock(&tp->lock);
- if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ if (tg3_flag(tp, USE_PHYLIB)) {
tw32_f(MAC_STATUS,
(MAC_STATUS_SYNC_CHANGED |
MAC_STATUS_CFG_CHANGED |
@@ -5057,7 +5211,7 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
/* run TX completion thread */
if (tnapi->hw_status->idx[0].tx_consumer != tnapi->tx_cons) {
tg3_tx(tnapi);
- if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
+ if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING)))
return work_done;
}
@@ -5068,7 +5222,7 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
if (*(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)
work_done += tg3_rx(tnapi, budget - work_done);
- if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) {
+ if (tg3_flag(tp, ENABLE_RSS) && tnapi == &tp->napi[1]) {
struct tg3_rx_prodring_set *dpr = &tp->napi[0].prodring;
int i, err = 0;
u32 std_prod_idx = dpr->rx_std_prod_idx;
@@ -5107,7 +5261,7 @@ static int tg3_poll_msix(struct napi_struct *napi, int budget)
while (1) {
work_done = tg3_poll_work(tnapi, work_done, budget);
- if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
+ if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING)))
goto tx_recovery;
if (unlikely(work_done >= budget))
@@ -5141,6 +5295,40 @@ tx_recovery:
return work_done;
}
+static void tg3_process_error(struct tg3 *tp)
+{
+ u32 val;
+ bool real_error = false;
+
+ if (tg3_flag(tp, ERROR_PROCESSED))
+ return;
+
+ /* Check Flow Attention register */
+ val = tr32(HOSTCC_FLOW_ATTN);
+ if (val & ~HOSTCC_FLOW_ATTN_MBUF_LWM) {
+ netdev_err(tp->dev, "FLOW Attention error. Resetting chip.\n");
+ real_error = true;
+ }
+
+ if (tr32(MSGINT_STATUS) & ~MSGINT_STATUS_MSI_REQ) {
+ netdev_err(tp->dev, "MSI Status error. Resetting chip.\n");
+ real_error = true;
+ }
+
+ if (tr32(RDMAC_STATUS) || tr32(WDMAC_STATUS)) {
+ netdev_err(tp->dev, "DMA Status error. Resetting chip.\n");
+ real_error = true;
+ }
+
+ if (!real_error)
+ return;
+
+ tg3_dump_state(tp);
+
+ tg3_flag_set(tp, ERROR_PROCESSED);
+ schedule_work(&tp->reset_task);
+}
+
static int tg3_poll(struct napi_struct *napi, int budget)
{
struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
@@ -5149,17 +5337,20 @@ static int tg3_poll(struct napi_struct *napi, int budget)
struct tg3_hw_status *sblk = tnapi->hw_status;
while (1) {
+ if (sblk->status & SD_STATUS_ERROR)
+ tg3_process_error(tp);
+
tg3_poll_link(tp);
work_done = tg3_poll_work(tnapi, work_done, budget);
- if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
+ if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING)))
goto tx_recovery;
if (unlikely(work_done >= budget))
break;
- if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) {
+ if (tg3_flag(tp, TAGGED_STATUS)) {
/* tp->last_tag is used in tg3_int_reenable() below
* to tell the hw how much work has been processed,
* so we must read it before checking for more work.
@@ -5326,7 +5517,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
* interrupt is ours and will flush the status block.
*/
if (unlikely(!(sblk->status & SD_STATUS_UPDATED))) {
- if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
+ if (tg3_flag(tp, CHIP_RESETTING) ||
(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
handled = 0;
goto out;
@@ -5375,7 +5566,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
* interrupt is ours and will flush the status block.
*/
if (unlikely(sblk->status_tag == tnapi->last_irq_tag)) {
- if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
+ if (tg3_flag(tp, CHIP_RESETTING) ||
(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
handled = 0;
goto out;
@@ -5488,14 +5679,14 @@ static void tg3_reset_task(struct work_struct *work)
tg3_full_lock(tp, 1);
- restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER;
- tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER;
+ restart_timer = tg3_flag(tp, RESTART_TIMER);
+ tg3_flag_clear(tp, RESTART_TIMER);
- if (tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING) {
+ if (tg3_flag(tp, TX_RECOVERY_PENDING)) {
tp->write32_tx_mbox = tg3_write32_tx_mbox;
tp->write32_rx_mbox = tg3_write_flush_reg32;
- tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER;
- tp->tg3_flags &= ~TG3_FLAG_TX_RECOVERY_PENDING;
+ tg3_flag_set(tp, MBOX_WRITE_REORDER);
+ tg3_flag_clear(tp, TX_RECOVERY_PENDING);
}
tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
@@ -5515,21 +5706,13 @@ out:
tg3_phy_start(tp);
}
-static void tg3_dump_short_state(struct tg3 *tp)
-{
- netdev_err(tp->dev, "DEBUG: MAC_TX_STATUS[%08x] MAC_RX_STATUS[%08x]\n",
- tr32(MAC_TX_STATUS), tr32(MAC_RX_STATUS));
- netdev_err(tp->dev, "DEBUG: RDMAC_STATUS[%08x] WDMAC_STATUS[%08x]\n",
- tr32(RDMAC_STATUS), tr32(WDMAC_STATUS));
-}
-
static void tg3_tx_timeout(struct net_device *dev)
{
struct tg3 *tp = netdev_priv(dev);
if (netif_msg_tx_err(tp)) {
netdev_err(dev, "transmit timed out, resetting\n");
- tg3_dump_short_state(tp);
+ tg3_dump_state(tp);
}
schedule_work(&tp->reset_task);
@@ -5548,7 +5731,7 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
int len)
{
#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
- if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG)
+ if (tg3_flag(tp, 40BIT_DMA_BUG))
return ((u64) mapping + len) > DMA_BIT_MASK(40);
return 0;
#else
@@ -5556,18 +5739,62 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
#endif
}
-static void tg3_set_txd(struct tg3_napi *, int, dma_addr_t, int, u32, u32);
+static void tg3_set_txd(struct tg3_napi *tnapi, int entry,
+ dma_addr_t mapping, int len, u32 flags,
+ u32 mss_and_is_end)
+{
+ struct tg3_tx_buffer_desc *txd = &tnapi->tx_ring[entry];
+ int is_end = (mss_and_is_end & 0x1);
+ u32 mss = (mss_and_is_end >> 1);
+ u32 vlan_tag = 0;
+
+ if (is_end)
+ flags |= TXD_FLAG_END;
+ if (flags & TXD_FLAG_VLAN) {
+ vlan_tag = flags >> 16;
+ flags &= 0xffff;
+ }
+ vlan_tag |= (mss << TXD_MSS_SHIFT);
+
+ txd->addr_hi = ((u64) mapping >> 32);
+ txd->addr_lo = ((u64) mapping & 0xffffffff);
+ txd->len_flags = (len << TXD_LEN_SHIFT) | flags;
+ txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT;
+}
+
+static void tg3_skb_error_unmap(struct tg3_napi *tnapi,
+ struct sk_buff *skb, int last)
+{
+ int i;
+ u32 entry = tnapi->tx_prod;
+ struct ring_info *txb = &tnapi->tx_buffers[entry];
+
+ pci_unmap_single(tnapi->tp->pdev,
+ dma_unmap_addr(txb, mapping),
+ skb_headlen(skb),
+ PCI_DMA_TODEVICE);
+ for (i = 0; i <= last; i++) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+ entry = NEXT_TX(entry);
+ txb = &tnapi->tx_buffers[entry];
+
+ pci_unmap_page(tnapi->tp->pdev,
+ dma_unmap_addr(txb, mapping),
+ frag->size, PCI_DMA_TODEVICE);
+ }
+}
/* Workaround 4GB and 40-bit hardware DMA bugs. */
static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
- struct sk_buff *skb, u32 last_plus_one,
- u32 *start, u32 base_flags, u32 mss)
+ struct sk_buff *skb,
+ u32 base_flags, u32 mss)
{
struct tg3 *tp = tnapi->tp;
struct sk_buff *new_skb;
dma_addr_t new_addr = 0;
- u32 entry = *start;
- int i, ret = 0;
+ u32 entry = tnapi->tx_prod;
+ int ret = 0;
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701)
new_skb = skb_copy(skb, GFP_ATOMIC);
@@ -5583,55 +5810,30 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
ret = -1;
} else {
/* New SKB is guaranteed to be linear. */
- entry = *start;
new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len,
PCI_DMA_TODEVICE);
/* Make sure the mapping succeeded */
if (pci_dma_mapping_error(tp->pdev, new_addr)) {
ret = -1;
dev_kfree_skb(new_skb);
- new_skb = NULL;
/* Make sure new skb does not cross any 4G boundaries.
* Drop the packet if it does.
*/
- } else if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
- tg3_4g_overflow_test(new_addr, new_skb->len)) {
+ } else if (tg3_flag(tp, 4G_DMA_BNDRY_BUG) &&
+ tg3_4g_overflow_test(new_addr, new_skb->len)) {
pci_unmap_single(tp->pdev, new_addr, new_skb->len,
PCI_DMA_TODEVICE);
ret = -1;
dev_kfree_skb(new_skb);
- new_skb = NULL;
} else {
+ tnapi->tx_buffers[entry].skb = new_skb;
+ dma_unmap_addr_set(&tnapi->tx_buffers[entry],
+ mapping, new_addr);
+
tg3_set_txd(tnapi, entry, new_addr, new_skb->len,
base_flags, 1 | (mss << 1));
- *start = NEXT_TX(entry);
- }
- }
-
- /* Now clean up the sw ring entries. */
- i = 0;
- while (entry != last_plus_one) {
- int len;
-
- if (i == 0)
- len = skb_headlen(skb);
- else
- len = skb_shinfo(skb)->frags[i-1].size;
-
- pci_unmap_single(tp->pdev,
- dma_unmap_addr(&tnapi->tx_buffers[entry],
- mapping),
- len, PCI_DMA_TODEVICE);
- if (i == 0) {
- tnapi->tx_buffers[entry].skb = new_skb;
- dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping,
- new_addr);
- } else {
- tnapi->tx_buffers[entry].skb = NULL;
}
- entry = NEXT_TX(entry);
- i++;
}
dev_kfree_skb(skb);
@@ -5639,202 +5841,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
return ret;
}
-static void tg3_set_txd(struct tg3_napi *tnapi, int entry,
- dma_addr_t mapping, int len, u32 flags,
- u32 mss_and_is_end)
-{
- struct tg3_tx_buffer_desc *txd = &tnapi->tx_ring[entry];
- int is_end = (mss_and_is_end & 0x1);
- u32 mss = (mss_and_is_end >> 1);
- u32 vlan_tag = 0;
-
- if (is_end)
- flags |= TXD_FLAG_END;
- if (flags & TXD_FLAG_VLAN) {
- vlan_tag = flags >> 16;
- flags &= 0xffff;
- }
- vlan_tag |= (mss << TXD_MSS_SHIFT);
-
- txd->addr_hi = ((u64) mapping >> 32);
- txd->addr_lo = ((u64) mapping & 0xffffffff);
- txd->len_flags = (len << TXD_LEN_SHIFT) | flags;
- txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT;
-}
-
-/* hard_start_xmit for devices that don't have any bugs and
- * support TG3_FLG2_HW_TSO_2 and TG3_FLG2_HW_TSO_3 only.
- */
-static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
- struct net_device *dev)
-{
- struct tg3 *tp = netdev_priv(dev);
- u32 len, entry, base_flags, mss;
- dma_addr_t mapping;
- struct tg3_napi *tnapi;
- struct netdev_queue *txq;
- unsigned int i, last;
-
- txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
- tnapi = &tp->napi[skb_get_queue_mapping(skb)];
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
- tnapi++;
-
- /* We are running in BH disabled context with netif_tx_lock
- * and TX reclaim runs via tp->napi.poll inside of a software
- * interrupt. Furthermore, IRQ processing runs lockless so we have
- * no IRQ context deadlocks to worry about either. Rejoice!
- */
- if (unlikely(tg3_tx_avail(tnapi) <= (skb_shinfo(skb)->nr_frags + 1))) {
- if (!netif_tx_queue_stopped(txq)) {
- netif_tx_stop_queue(txq);
-
- /* This is a hard error, log it. */
- netdev_err(dev,
- "BUG! Tx Ring full when queue awake!\n");
- }
- return NETDEV_TX_BUSY;
- }
-
- entry = tnapi->tx_prod;
- base_flags = 0;
- mss = skb_shinfo(skb)->gso_size;
- if (mss) {
- int tcp_opt_len, ip_tcp_len;
- u32 hdrlen;
-
- if (skb_header_cloned(skb) &&
- pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
- dev_kfree_skb(skb);
- goto out_unlock;
- }
-
- if (skb_is_gso_v6(skb)) {
- hdrlen = skb_headlen(skb) - ETH_HLEN;
- } else {
- struct iphdr *iph = ip_hdr(skb);
-
- tcp_opt_len = tcp_optlen(skb);
- ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr);
-
- iph->check = 0;
- iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len);
- hdrlen = ip_tcp_len + tcp_opt_len;
- }
-
- if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) {
- mss |= (hdrlen & 0xc) << 12;
- if (hdrlen & 0x10)
- base_flags |= 0x00000010;
- base_flags |= (hdrlen & 0x3e0) << 5;
- } else
- mss |= hdrlen << 9;
-
- base_flags |= (TXD_FLAG_CPU_PRE_DMA |
- TXD_FLAG_CPU_POST_DMA);
-
- tcp_hdr(skb)->check = 0;
-
- } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
- base_flags |= TXD_FLAG_TCPUDP_CSUM;
- }
-
- if (vlan_tx_tag_present(skb))
- base_flags |= (TXD_FLAG_VLAN |
- (vlan_tx_tag_get(skb) << 16));
-
- len = skb_headlen(skb);
-
- /* Queue skb data, a.k.a. the main skb fragment. */
- mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(tp->pdev, mapping)) {
- dev_kfree_skb(skb);
- goto out_unlock;
- }
-
- tnapi->tx_buffers[entry].skb = skb;
- dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping, mapping);
-
- if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) &&
- !mss && skb->len > VLAN_ETH_FRAME_LEN)
- base_flags |= TXD_FLAG_JMB_PKT;
-
- tg3_set_txd(tnapi, entry, mapping, len, base_flags,
- (skb_shinfo(skb)->nr_frags == 0) | (mss << 1));
-
- entry = NEXT_TX(entry);
-
- /* Now loop through additional data fragments, and queue them. */
- if (skb_shinfo(skb)->nr_frags > 0) {
- last = skb_shinfo(skb)->nr_frags - 1;
- for (i = 0; i <= last; i++) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-
- len = frag->size;
- mapping = pci_map_page(tp->pdev,
- frag->page,
- frag->page_offset,
- len, PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(tp->pdev, mapping))
- goto dma_error;
-
- tnapi->tx_buffers[entry].skb = NULL;
- dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping,
- mapping);
-
- tg3_set_txd(tnapi, entry, mapping, len,
- base_flags, (i == last) | (mss << 1));
-
- entry = NEXT_TX(entry);
- }
- }
-
- /* Packets are ready, update Tx producer idx local and on card. */
- tw32_tx_mbox(tnapi->prodmbox, entry);
-
- tnapi->tx_prod = entry;
- if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) {
- netif_tx_stop_queue(txq);
-
- /* netif_tx_stop_queue() must be done before checking
- * checking tx index in tg3_tx_avail() below, because in
- * tg3_tx(), we update tx index before checking for
- * netif_tx_queue_stopped().
- */
- smp_mb();
- if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))
- netif_tx_wake_queue(txq);
- }
-
-out_unlock:
- mmiowb();
-
- return NETDEV_TX_OK;
-
-dma_error:
- last = i;
- entry = tnapi->tx_prod;
- tnapi->tx_buffers[entry].skb = NULL;
- pci_unmap_single(tp->pdev,
- dma_unmap_addr(&tnapi->tx_buffers[entry], mapping),
- skb_headlen(skb),
- PCI_DMA_TODEVICE);
- for (i = 0; i <= last; i++) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- entry = NEXT_TX(entry);
-
- pci_unmap_page(tp->pdev,
- dma_unmap_addr(&tnapi->tx_buffers[entry],
- mapping),
- frag->size, PCI_DMA_TODEVICE);
- }
-
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
-}
-
-static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *,
- struct net_device *);
+static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *);
/* Use GSO to workaround a rare TSO bug that may be triggered when the
* TSO header is greater than 80 bytes.
@@ -5868,7 +5875,7 @@ static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb)
nskb = segs;
segs = segs->next;
nskb->next = NULL;
- tg3_start_xmit_dma_bug(nskb, tp->dev);
+ tg3_start_xmit(nskb, tp->dev);
} while (segs);
tg3_tso_bug_end:
@@ -5878,22 +5885,21 @@ tg3_tso_bug_end:
}
/* hard_start_xmit for devices that have the 4G bug and/or 40-bit bug and
- * support TG3_FLG2_HW_TSO_1 or firmware TSO only.
+ * support TG3_FLAG_HW_TSO_1 or firmware TSO only.
*/
-static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
- struct net_device *dev)
+static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct tg3 *tp = netdev_priv(dev);
u32 len, entry, base_flags, mss;
- int would_hit_hwbug;
+ int i = -1, would_hit_hwbug;
dma_addr_t mapping;
struct tg3_napi *tnapi;
struct netdev_queue *txq;
- unsigned int i, last;
+ unsigned int last;
txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
tnapi = &tp->napi[skb_get_queue_mapping(skb)];
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+ if (tg3_flag(tp, ENABLE_TSS))
tnapi++;
/* We are running in BH disabled context with netif_tx_lock
@@ -5944,13 +5950,15 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
}
if (unlikely((ETH_HLEN + hdr_len) > 80) &&
- (tp->tg3_flags2 & TG3_FLG2_TSO_BUG))
+ tg3_flag(tp, TSO_BUG))
return tg3_tso_bug(tp, skb);
base_flags |= (TXD_FLAG_CPU_PRE_DMA |
TXD_FLAG_CPU_POST_DMA);
- if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
+ if (tg3_flag(tp, HW_TSO_1) ||
+ tg3_flag(tp, HW_TSO_2) ||
+ tg3_flag(tp, HW_TSO_3)) {
tcp_hdr(skb)->check = 0;
base_flags &= ~TXD_FLAG_TCPUDP_CSUM;
} else
@@ -5959,14 +5967,14 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
IPPROTO_TCP,
0);
- if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) {
+ if (tg3_flag(tp, HW_TSO_3)) {
mss |= (hdr_len & 0xc) << 12;
if (hdr_len & 0x10)
base_flags |= 0x00000010;
base_flags |= (hdr_len & 0x3e0) << 5;
- } else if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2)
+ } else if (tg3_flag(tp, HW_TSO_2))
mss |= hdr_len << 9;
- else if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_1) ||
+ else if (tg3_flag(tp, HW_TSO_1) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
if (tcp_opt_len || iph->ihl > 5) {
int tsflags;
@@ -5988,7 +5996,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
base_flags |= (TXD_FLAG_VLAN |
(vlan_tx_tag_get(skb) << 16));
- if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) &&
+ if (tg3_flag(tp, USE_JUMBO_BDFLAG) &&
!mss && skb->len > VLAN_ETH_FRAME_LEN)
base_flags |= TXD_FLAG_JMB_PKT;
@@ -6005,18 +6013,18 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
would_hit_hwbug = 0;
- if ((tp->tg3_flags3 & TG3_FLG3_SHORT_DMA_BUG) && len <= 8)
+ if (tg3_flag(tp, SHORT_DMA_BUG) && len <= 8)
would_hit_hwbug = 1;
- if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
+ if (tg3_flag(tp, 4G_DMA_BNDRY_BUG) &&
tg3_4g_overflow_test(mapping, len))
would_hit_hwbug = 1;
- if ((tp->tg3_flags3 & TG3_FLG3_40BIT_DMA_LIMIT_BUG) &&
+ if (tg3_flag(tp, 40BIT_DMA_LIMIT_BUG) &&
tg3_40bit_overflow_test(tp, mapping, len))
would_hit_hwbug = 1;
- if (tp->tg3_flags3 & TG3_FLG3_5701_DMA_BUG)
+ if (tg3_flag(tp, 5701_DMA_BUG))
would_hit_hwbug = 1;
tg3_set_txd(tnapi, entry, mapping, len, base_flags,
@@ -6042,19 +6050,21 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
if (pci_dma_mapping_error(tp->pdev, mapping))
goto dma_error;
- if ((tp->tg3_flags3 & TG3_FLG3_SHORT_DMA_BUG) &&
+ if (tg3_flag(tp, SHORT_DMA_BUG) &&
len <= 8)
would_hit_hwbug = 1;
- if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
+ if (tg3_flag(tp, 4G_DMA_BNDRY_BUG) &&
tg3_4g_overflow_test(mapping, len))
would_hit_hwbug = 1;
- if ((tp->tg3_flags3 & TG3_FLG3_40BIT_DMA_LIMIT_BUG) &&
+ if (tg3_flag(tp, 40BIT_DMA_LIMIT_BUG) &&
tg3_40bit_overflow_test(tp, mapping, len))
would_hit_hwbug = 1;
- if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
+ if (tg3_flag(tp, HW_TSO_1) ||
+ tg3_flag(tp, HW_TSO_2) ||
+ tg3_flag(tp, HW_TSO_3))
tg3_set_txd(tnapi, entry, mapping, len,
base_flags, (i == last)|(mss << 1));
else
@@ -6066,20 +6076,15 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
}
if (would_hit_hwbug) {
- u32 last_plus_one = entry;
- u32 start;
-
- start = entry - 1 - skb_shinfo(skb)->nr_frags;
- start &= (TG3_TX_RING_SIZE - 1);
+ tg3_skb_error_unmap(tnapi, skb, i);
/* If the workaround fails due to memory/mapping
* failure, silently drop this packet.
*/
- if (tigon3_dma_hwbug_workaround(tnapi, skb, last_plus_one,
- &start, base_flags, mss))
+ if (tigon3_dma_hwbug_workaround(tnapi, skb, base_flags, mss))
goto out_unlock;
- entry = start;
+ entry = NEXT_TX(tnapi->tx_prod);
}
/* Packets are ready, update Tx producer idx local and on card. */
@@ -6105,25 +6110,66 @@ out_unlock:
return NETDEV_TX_OK;
dma_error:
- last = i;
- entry = tnapi->tx_prod;
- tnapi->tx_buffers[entry].skb = NULL;
- pci_unmap_single(tp->pdev,
- dma_unmap_addr(&tnapi->tx_buffers[entry], mapping),
- skb_headlen(skb),
- PCI_DMA_TODEVICE);
- for (i = 0; i <= last; i++) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- entry = NEXT_TX(entry);
+ tg3_skb_error_unmap(tnapi, skb, i);
+ dev_kfree_skb(skb);
+ tnapi->tx_buffers[tnapi->tx_prod].skb = NULL;
+ return NETDEV_TX_OK;
+}
- pci_unmap_page(tp->pdev,
- dma_unmap_addr(&tnapi->tx_buffers[entry],
- mapping),
- frag->size, PCI_DMA_TODEVICE);
+static void tg3_set_loopback(struct net_device *dev, u32 features)
+{
+ struct tg3 *tp = netdev_priv(dev);
+
+ if (features & NETIF_F_LOOPBACK) {
+ if (tp->mac_mode & MAC_MODE_PORT_INT_LPBACK)
+ return;
+
+ /*
+ * Clear MAC_MODE_HALF_DUPLEX or you won't get packets back in
+ * loopback mode if Half-Duplex mode was negotiated earlier.
+ */
+ tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
+
+ /* Enable internal MAC loopback mode */
+ tp->mac_mode |= MAC_MODE_PORT_INT_LPBACK;
+ spin_lock_bh(&tp->lock);
+ tw32(MAC_MODE, tp->mac_mode);
+ netif_carrier_on(tp->dev);
+ spin_unlock_bh(&tp->lock);
+ netdev_info(dev, "Internal MAC loopback mode enabled.\n");
+ } else {
+ if (!(tp->mac_mode & MAC_MODE_PORT_INT_LPBACK))
+ return;
+
+ /* Disable internal MAC loopback mode */
+ tp->mac_mode &= ~MAC_MODE_PORT_INT_LPBACK;
+ spin_lock_bh(&tp->lock);
+ tw32(MAC_MODE, tp->mac_mode);
+ /* Force link status check */
+ tg3_setup_phy(tp, 1);
+ spin_unlock_bh(&tp->lock);
+ netdev_info(dev, "Internal MAC loopback mode disabled.\n");
}
+}
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
+static u32 tg3_fix_features(struct net_device *dev, u32 features)
+{
+ struct tg3 *tp = netdev_priv(dev);
+
+ if (dev->mtu > ETH_DATA_LEN && tg3_flag(tp, 5780_CLASS))
+ features &= ~NETIF_F_ALL_TSO;
+
+ return features;
+}
+
+static int tg3_set_features(struct net_device *dev, u32 features)
+{
+ u32 changed = dev->features ^ features;
+
+ if ((changed & NETIF_F_LOOPBACK) && netif_running(dev))
+ tg3_set_loopback(dev, features);
+
+ return 0;
}
static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
@@ -6132,16 +6178,18 @@ static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
dev->mtu = new_mtu;
if (new_mtu > ETH_DATA_LEN) {
- if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
- tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
- ethtool_op_set_tso(dev, 0);
+ if (tg3_flag(tp, 5780_CLASS)) {
+ netdev_update_features(dev);
+ tg3_flag_clear(tp, TSO_CAPABLE);
} else {
- tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
+ tg3_flag_set(tp, JUMBO_RING_ENABLE);
}
} else {
- if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
- tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
- tp->tg3_flags &= ~TG3_FLAG_JUMBO_RING_ENABLE;
+ if (tg3_flag(tp, 5780_CLASS)) {
+ tg3_flag_set(tp, TSO_CAPABLE);
+ netdev_update_features(dev);
+ }
+ tg3_flag_clear(tp, JUMBO_RING_ENABLE);
}
}
@@ -6195,7 +6243,7 @@ static void tg3_rx_prodring_free(struct tg3 *tp,
tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i],
tp->rx_pkt_map_sz);
- if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
+ if (tg3_flag(tp, JUMBO_CAPABLE)) {
for (i = tpr->rx_jmb_cons_idx;
i != tpr->rx_jmb_prod_idx;
i = (i + 1) & tp->rx_jmb_ring_mask) {
@@ -6211,8 +6259,7 @@ static void tg3_rx_prodring_free(struct tg3 *tp,
tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i],
tp->rx_pkt_map_sz);
- if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
- !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+ if (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS)) {
for (i = 0; i <= tp->rx_jmb_ring_mask; i++)
tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i],
TG3_RX_JMB_MAP_SZ);
@@ -6249,7 +6296,7 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
memset(tpr->rx_std, 0, TG3_RX_STD_RING_BYTES(tp));
rx_pkt_dma_sz = TG3_RX_STD_DMA_SZ;
- if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) &&
+ if (tg3_flag(tp, 5780_CLASS) &&
tp->dev->mtu > ETH_DATA_LEN)
rx_pkt_dma_sz = TG3_RX_JMB_DMA_SZ;
tp->rx_pkt_map_sz = TG3_RX_DMA_TO_MAP_SZ(rx_pkt_dma_sz);
@@ -6282,13 +6329,12 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
}
}
- if (!(tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) ||
- (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
+ if (!tg3_flag(tp, JUMBO_CAPABLE) || tg3_flag(tp, 5780_CLASS))
goto done;
memset(tpr->rx_jmb, 0, TG3_RX_JMB_RING_BYTES(tp));
- if (!(tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE))
+ if (!tg3_flag(tp, JUMBO_RING_ENABLE))
goto done;
for (i = 0; i <= tp->rx_jmb_ring_mask; i++) {
@@ -6357,8 +6403,7 @@ static int tg3_rx_prodring_init(struct tg3 *tp,
if (!tpr->rx_std)
goto err_out;
- if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
- !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+ if (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS)) {
tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE(tp),
GFP_KERNEL);
if (!tpr->rx_jmb_buffers)
@@ -6556,8 +6601,8 @@ static int tg3_alloc_consistent(struct tg3 *tp)
/* If multivector TSS is enabled, vector 0 does not handle
* tx interrupts. Don't allocate any resources for it.
*/
- if ((!i && !(tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)) ||
- (i && (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS))) {
+ if ((!i && !tg3_flag(tp, ENABLE_TSS)) ||
+ (i && tg3_flag(tp, ENABLE_TSS))) {
tnapi->tx_buffers = kzalloc(sizeof(struct ring_info) *
TG3_TX_RING_SIZE,
GFP_KERNEL);
@@ -6597,7 +6642,7 @@ static int tg3_alloc_consistent(struct tg3 *tp)
* If multivector RSS is enabled, vector 0 does not handle
* rx or tx interrupts. Don't allocate any resources for it.
*/
- if (!i && (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS))
+ if (!i && tg3_flag(tp, ENABLE_RSS))
continue;
tnapi->rx_rcb = dma_alloc_coherent(&tp->pdev->dev,
@@ -6627,7 +6672,7 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit, int
unsigned int i;
u32 val;
- if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+ if (tg3_flag(tp, 5705_PLUS)) {
switch (ofs) {
case RCVLSC_MODE:
case DMAC_MODE:
@@ -6737,7 +6782,7 @@ static void tg3_ape_send_event(struct tg3 *tp, u32 event)
u32 apedata;
/* NCSI does not support APE events */
- if (tp->tg3_flags3 & TG3_FLG3_APE_HAS_NCSI)
+ if (tg3_flag(tp, APE_HAS_NCSI))
return;
apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
@@ -6776,7 +6821,7 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)
u32 event;
u32 apedata;
- if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
+ if (!tg3_flag(tp, ENABLE_APE))
return;
switch (kind) {
@@ -6805,7 +6850,7 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)
tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, 0x0);
if (device_may_wakeup(&tp->pdev->dev) &&
- (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) {
+ tg3_flag(tp, WOL_ENABLE)) {
tg3_ape_write32(tp, TG3_APE_HOST_WOL_SPEED,
TG3_APE_HOST_WOL_SPEED_AUTO);
apedata = TG3_APE_HOST_DRVR_STATE_WOL;
@@ -6834,7 +6879,7 @@ static void tg3_write_sig_pre_reset(struct tg3 *tp, int kind)
tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX,
NIC_SRAM_FIRMWARE_MBOX_MAGIC1);
- if (tp->tg3_flags2 & TG3_FLG2_ASF_NEW_HANDSHAKE) {
+ if (tg3_flag(tp, ASF_NEW_HANDSHAKE)) {
switch (kind) {
case RESET_KIND_INIT:
tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
@@ -6864,7 +6909,7 @@ static void tg3_write_sig_pre_reset(struct tg3 *tp, int kind)
/* tp->lock is held. */
static void tg3_write_sig_post_reset(struct tg3 *tp, int kind)
{
- if (tp->tg3_flags2 & TG3_FLG2_ASF_NEW_HANDSHAKE) {
+ if (tg3_flag(tp, ASF_NEW_HANDSHAKE)) {
switch (kind) {
case RESET_KIND_INIT:
tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
@@ -6888,7 +6933,7 @@ static void tg3_write_sig_post_reset(struct tg3 *tp, int kind)
/* tp->lock is held. */
static void tg3_write_sig_legacy(struct tg3 *tp, int kind)
{
- if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
+ if (tg3_flag(tp, ENABLE_ASF)) {
switch (kind) {
case RESET_KIND_INIT:
tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
@@ -6939,9 +6984,8 @@ static int tg3_poll_fw(struct tg3 *tp)
* of the above loop as an error, but do report the lack of
* running firmware once.
*/
- if (i >= 100000 &&
- !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) {
- tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED;
+ if (i >= 100000 && !tg3_flag(tp, NO_FWARE_REPORTED)) {
+ tg3_flag_set(tp, NO_FWARE_REPORTED);
netdev_info(tp->dev, "No firmware running\n");
}
@@ -6974,10 +7018,10 @@ static void tg3_restore_pci_state(struct tg3 *tp)
/* Set MAX PCI retry to zero. */
val = (PCISTATE_ROM_ENABLE | PCISTATE_ROM_RETRY_ENABLE);
if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 &&
- (tp->tg3_flags & TG3_FLAG_PCIX_MODE))
+ tg3_flag(tp, PCIX_MODE))
val |= PCISTATE_RETRY_SAME_DMA;
/* Allow reads and writes to the APE register and memory space. */
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+ if (tg3_flag(tp, ENABLE_APE))
val |= PCISTATE_ALLOW_APE_CTLSPC_WR |
PCISTATE_ALLOW_APE_SHMEM_WR |
PCISTATE_ALLOW_APE_PSPACE_WR;
@@ -6986,7 +7030,7 @@ static void tg3_restore_pci_state(struct tg3 *tp)
pci_write_config_word(tp->pdev, PCI_COMMAND, tp->pci_cmd);
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) {
- if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)
+ if (tg3_flag(tp, PCI_EXPRESS))
pcie_set_readrq(tp->pdev, tp->pcie_readrq);
else {
pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
@@ -6997,7 +7041,7 @@ static void tg3_restore_pci_state(struct tg3 *tp)
}
/* Make sure PCI-X relaxed ordering bit is clear. */
- if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) {
+ if (tg3_flag(tp, PCIX_MODE)) {
u16 pcix_cmd;
pci_read_config_word(tp->pdev, tp->pcix_cap + PCI_X_CMD,
@@ -7007,12 +7051,12 @@ static void tg3_restore_pci_state(struct tg3 *tp)
pcix_cmd);
}
- if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
+ if (tg3_flag(tp, 5780_CLASS)) {
/* Chip reset on 5780 will reset MSI enable bit,
* so need to restore it.
*/
- if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+ if (tg3_flag(tp, USING_MSI)) {
u16 ctrl;
pci_read_config_word(tp->pdev,
@@ -7052,7 +7096,7 @@ static int tg3_chip_reset(struct tg3 *tp)
tg3_save_pci_state(tp);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
- (tp->tg3_flags3 & TG3_FLG3_5755_PLUS))
+ tg3_flag(tp, 5755_PLUS))
tw32(GRC_FASTBOOT_PC, 0);
/*
@@ -7071,7 +7115,7 @@ static int tg3_chip_reset(struct tg3 *tp)
* at this time, but the irq handler may still be called due to irq
* sharing or irqpoll.
*/
- tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING;
+ tg3_flag_set(tp, CHIP_RESETTING);
for (i = 0; i < tp->irq_cnt; i++) {
struct tg3_napi *tnapi = &tp->napi[i];
if (tnapi->hw_status) {
@@ -7094,10 +7138,10 @@ static int tg3_chip_reset(struct tg3 *tp)
/* do the reset */
val = GRC_MISC_CFG_CORECLK_RESET;
- if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
+ if (tg3_flag(tp, PCI_EXPRESS)) {
/* Force PCIe 1.0a mode */
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
- !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
+ !tg3_flag(tp, 57765_PLUS) &&
tr32(TG3_PCIE_PHY_TSTCTL) ==
(TG3_PCIE_PHY_TSTCTL_PCIE10 | TG3_PCIE_PHY_TSTCTL_PSCRAM))
tw32(TG3_PCIE_PHY_TSTCTL, TG3_PCIE_PHY_TSTCTL_PSCRAM);
@@ -7115,8 +7159,7 @@ static int tg3_chip_reset(struct tg3 *tp)
}
/* Manage gphy power for all CPMU absent PCIe devices. */
- if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
- !(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT))
+ if (tg3_flag(tp, 5705_PLUS) && !tg3_flag(tp, CPMU_PRESENT))
val |= GRC_MISC_CFG_KEEP_GPHY_POWER;
tw32(GRC_MISC_CFG, val);
@@ -7149,7 +7192,7 @@ static int tg3_chip_reset(struct tg3 *tp)
udelay(120);
- if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && tp->pcie_cap) {
+ if (tg3_flag(tp, PCI_EXPRESS) && tp->pcie_cap) {
u16 val16;
if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A0) {
@@ -7175,7 +7218,7 @@ static int tg3_chip_reset(struct tg3 *tp)
* Older PCIe devices only support the 128 byte
* MPS setting. Enforce the restriction.
*/
- if (!(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT))
+ if (!tg3_flag(tp, CPMU_PRESENT))
val16 &= ~PCI_EXP_DEVCTL_PAYLOAD;
pci_write_config_word(tp->pdev,
tp->pcie_cap + PCI_EXP_DEVCTL,
@@ -7194,10 +7237,11 @@ static int tg3_chip_reset(struct tg3 *tp)
tg3_restore_pci_state(tp);
- tp->tg3_flags &= ~TG3_FLAG_CHIP_RESETTING;
+ tg3_flag_clear(tp, CHIP_RESETTING);
+ tg3_flag_clear(tp, ERROR_PROCESSED);
val = 0;
- if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
+ if (tg3_flag(tp, 5780_CLASS))
val = tr32(MEMARB_MODE);
tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE);
@@ -7222,7 +7266,7 @@ static int tg3_chip_reset(struct tg3 *tp)
tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl);
}
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+ if (tg3_flag(tp, ENABLE_APE))
tp->mac_mode = MAC_MODE_APE_TX_EN |
MAC_MODE_APE_RX_EN |
MAC_MODE_TDE_ENABLE;
@@ -7247,28 +7291,33 @@ static int tg3_chip_reset(struct tg3 *tp)
tg3_mdio_start(tp);
- if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
+ if (tg3_flag(tp, PCI_EXPRESS) &&
tp->pci_chip_rev_id != CHIPREV_ID_5750_A0 &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
- !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) {
+ !tg3_flag(tp, 57765_PLUS)) {
val = tr32(0x7c00);
tw32(0x7c00, val | (1 << 25));
}
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
+ val = tr32(TG3_CPMU_CLCK_ORIDE);
+ tw32(TG3_CPMU_CLCK_ORIDE, val & ~CPMU_CLCK_ORIDE_MAC_ORIDE_EN);
+ }
+
/* Reprobe ASF enable state. */
- tp->tg3_flags &= ~TG3_FLAG_ENABLE_ASF;
- tp->tg3_flags2 &= ~TG3_FLG2_ASF_NEW_HANDSHAKE;
+ tg3_flag_clear(tp, ENABLE_ASF);
+ tg3_flag_clear(tp, ASF_NEW_HANDSHAKE);
tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
if (val == NIC_SRAM_DATA_SIG_MAGIC) {
u32 nic_cfg;
tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
- tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
+ tg3_flag_set(tp, ENABLE_ASF);
tp->last_event_jiffies = jiffies;
- if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
- tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE;
+ if (tg3_flag(tp, 5750_PLUS))
+ tg3_flag_set(tp, ASF_NEW_HANDSHAKE);
}
}
@@ -7278,8 +7327,7 @@ static int tg3_chip_reset(struct tg3 *tp)
/* tp->lock is held. */
static void tg3_stop_fw(struct tg3 *tp)
{
- if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
- !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
+ if (tg3_flag(tp, ENABLE_ASF) && !tg3_flag(tp, ENABLE_APE)) {
/* Wait for RX cpu to ACK the previous event. */
tg3_wait_for_event_ack(tp);
@@ -7325,8 +7373,7 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset)
{
int i;
- BUG_ON(offset == TX_CPU_BASE &&
- (tp->tg3_flags2 & TG3_FLG2_5705_PLUS));
+ BUG_ON(offset == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS));
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
u32 val = tr32(GRC_VCPU_EXT_CTRL);
@@ -7361,7 +7408,7 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset)
}
/* Clear firmware's nvram arbitration. */
- if (tp->tg3_flags & TG3_FLAG_NVRAM)
+ if (tg3_flag(tp, NVRAM))
tw32(NVRAM_SWARB, SWARB_REQ_CLR0);
return 0;
}
@@ -7379,15 +7426,14 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b
int err, lock_err, i;
void (*write_op)(struct tg3 *, u32, u32);
- if (cpu_base == TX_CPU_BASE &&
- (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+ if (cpu_base == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS)) {
netdev_err(tp->dev,
"%s: Trying to load TX cpu firmware which is 5705\n",
__func__);
return -EINVAL;
}
- if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+ if (tg3_flag(tp, 5705_PLUS))
write_op = tg3_write_mem;
else
write_op = tg3_write_indirect_reg32;
@@ -7473,8 +7519,6 @@ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp)
return 0;
}
-/* 5705 needs a special version of the TSO firmware. */
-
/* tp->lock is held. */
static int tg3_load_tso_firmware(struct tg3 *tp)
{
@@ -7483,7 +7527,9 @@ static int tg3_load_tso_firmware(struct tg3 *tp)
unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size;
int err, i;
- if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
+ if (tg3_flag(tp, HW_TSO_1) ||
+ tg3_flag(tp, HW_TSO_2) ||
+ tg3_flag(tp, HW_TSO_3))
return 0;
fw_data = (void *)tp->fw->data;
@@ -7552,7 +7598,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
if (!netif_running(dev))
return 0;
- if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
+ if (tg3_flag(tp, ENABLE_ASF)) {
u32 addr0_high, addr0_low, addr1_high, addr1_low;
addr0_high = tr32(MAC_ADDR_0_HIGH);
@@ -7587,7 +7633,7 @@ static void tg3_set_bdinfo(struct tg3 *tp, u32 bdinfo_addr,
(bdinfo_addr + TG3_BDINFO_MAXLEN_FLAGS),
maxlen_flags);
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+ if (!tg3_flag(tp, 5705_PLUS))
tg3_write_mem(tp,
(bdinfo_addr + TG3_BDINFO_NIC_ADDR),
nic_addr);
@@ -7598,7 +7644,7 @@ static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
{
int i;
- if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)) {
+ if (!tg3_flag(tp, ENABLE_TSS)) {
tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs);
tw32(HOSTCC_TXMAX_FRAMES, ec->tx_max_coalesced_frames);
tw32(HOSTCC_TXCOAL_MAXF_INT, ec->tx_max_coalesced_frames_irq);
@@ -7608,7 +7654,7 @@ static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
tw32(HOSTCC_TXCOAL_MAXF_INT, 0);
}
- if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)) {
+ if (!tg3_flag(tp, ENABLE_RSS)) {
tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs);
tw32(HOSTCC_RXMAX_FRAMES, ec->rx_max_coalesced_frames);
tw32(HOSTCC_RXCOAL_MAXF_INT, ec->rx_max_coalesced_frames_irq);
@@ -7618,7 +7664,7 @@ static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
tw32(HOSTCC_RXCOAL_MAXF_INT, 0);
}
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+ if (!tg3_flag(tp, 5705_PLUS)) {
u32 val = ec->stats_block_coalesce_usecs;
tw32(HOSTCC_RXCOAL_TICK_INT, ec->rx_coalesce_usecs_irq);
@@ -7640,7 +7686,7 @@ static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
reg = HOSTCC_RXCOAL_MAXF_INT_VEC1 + i * 0x18;
tw32(reg, ec->rx_max_coalesced_frames_irq);
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS) {
+ if (tg3_flag(tp, ENABLE_TSS)) {
reg = HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18;
tw32(reg, ec->tx_coalesce_usecs);
reg = HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18;
@@ -7655,7 +7701,7 @@ static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
tw32(HOSTCC_RXMAX_FRAMES_VEC1 + i * 0x18, 0);
tw32(HOSTCC_RXCOAL_MAXF_INT_VEC1 + i * 0x18, 0);
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS) {
+ if (tg3_flag(tp, ENABLE_TSS)) {
tw32(HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18, 0);
tw32(HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18, 0);
tw32(HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18, 0);
@@ -7671,10 +7717,9 @@ static void tg3_rings_reset(struct tg3 *tp)
struct tg3_napi *tnapi = &tp->napi[0];
/* Disable all transmit rings but the first. */
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+ if (!tg3_flag(tp, 5705_PLUS))
limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 16;
- else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+ else if (tg3_flag(tp, 5717_PLUS))
limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 4;
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 2;
@@ -7688,10 +7733,9 @@ static void tg3_rings_reset(struct tg3 *tp)
/* Disable all receive return rings but the first. */
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+ if (tg3_flag(tp, 5717_PLUS))
limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 17;
- else if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+ else if (!tg3_flag(tp, 5705_PLUS))
limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 16;
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
@@ -7708,16 +7752,16 @@ static void tg3_rings_reset(struct tg3 *tp)
tw32_mailbox_f(tp->napi[0].int_mbox, 1);
/* Zero mailbox registers. */
- if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX) {
+ if (tg3_flag(tp, SUPPORT_MSIX)) {
for (i = 1; i < tp->irq_max; i++) {
tp->napi[i].tx_prod = 0;
tp->napi[i].tx_cons = 0;
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+ if (tg3_flag(tp, ENABLE_TSS))
tw32_mailbox(tp->napi[i].prodmbox, 0);
tw32_rx_mbox(tp->napi[i].consmbox, 0);
tw32_mailbox_f(tp->napi[i].int_mbox, 1);
}
- if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS))
+ if (!tg3_flag(tp, ENABLE_TSS))
tw32_mailbox(tp->napi[0].prodmbox, 0);
} else {
tp->napi[0].tx_prod = 0;
@@ -7727,7 +7771,7 @@ static void tg3_rings_reset(struct tg3 *tp)
}
/* Make sure the NIC-based send BD rings are disabled. */
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+ if (!tg3_flag(tp, 5705_PLUS)) {
u32 mbox = MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW;
for (i = 0; i < 16; i++)
tw32_tx_mbox(mbox + i * 8, 0);
@@ -7787,6 +7831,47 @@ static void tg3_rings_reset(struct tg3 *tp)
}
}
+static void tg3_setup_rxbd_thresholds(struct tg3 *tp)
+{
+ u32 val, bdcache_maxcnt, host_rep_thresh, nic_rep_thresh;
+
+ if (!tg3_flag(tp, 5750_PLUS) ||
+ tg3_flag(tp, 5780_CLASS) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
+ bdcache_maxcnt = TG3_SRAM_RX_STD_BDCACHE_SIZE_5700;
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+ bdcache_maxcnt = TG3_SRAM_RX_STD_BDCACHE_SIZE_5755;
+ else
+ bdcache_maxcnt = TG3_SRAM_RX_STD_BDCACHE_SIZE_5906;
+
+ nic_rep_thresh = min(bdcache_maxcnt / 2, tp->rx_std_max_post);
+ host_rep_thresh = max_t(u32, tp->rx_pending / 8, 1);
+
+ val = min(nic_rep_thresh, host_rep_thresh);
+ tw32(RCVBDI_STD_THRESH, val);
+
+ if (tg3_flag(tp, 57765_PLUS))
+ tw32(STD_REPLENISH_LWM, bdcache_maxcnt);
+
+ if (!tg3_flag(tp, JUMBO_CAPABLE) || tg3_flag(tp, 5780_CLASS))
+ return;
+
+ if (!tg3_flag(tp, 5705_PLUS))
+ bdcache_maxcnt = TG3_SRAM_RX_JMB_BDCACHE_SIZE_5700;
+ else
+ bdcache_maxcnt = TG3_SRAM_RX_JMB_BDCACHE_SIZE_5717;
+
+ host_rep_thresh = max_t(u32, tp->rx_jumbo_pending / 8, 1);
+
+ val = min(bdcache_maxcnt / 2, host_rep_thresh);
+ tw32(RCVBDI_JUMBO_THRESH, val);
+
+ if (tg3_flag(tp, 57765_PLUS))
+ tw32(JMB_REPLENISH_LWM, bdcache_maxcnt);
+}
+
/* tp->lock is held. */
static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
{
@@ -7800,7 +7885,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tg3_write_sig_pre_reset(tp, RESET_KIND_INIT);
- if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)
+ if (tg3_flag(tp, INIT_COMPLETE))
tg3_abort_hw(tp, 1);
/* Enable MAC control of LPI */
@@ -7820,7 +7905,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
val |= TG3_CPMU_EEEMD_SND_IDX_DET_EN;
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+ if (tg3_flag(tp, ENABLE_APE))
val |= TG3_CPMU_EEEMD_APE_TX_DET_EN;
tw32_f(TG3_CPMU_EEE_MODE, val);
@@ -7879,7 +7964,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS);
}
- if (tp->tg3_flags3 & TG3_FLG3_L1PLLPD_EN) {
+ if (tg3_flag(tp, L1PLLPD_EN)) {
u32 grc_mode = tr32(GRC_MODE);
/* Access the lower 1K of PL PCIE block registers. */
@@ -7909,6 +7994,22 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(GRC_MODE, grc_mode);
}
+ if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_57765_AX) {
+ u32 grc_mode = tr32(GRC_MODE);
+
+ /* Access the lower 1K of DL PCIE block registers. */
+ val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK;
+ tw32(GRC_MODE, val | GRC_MODE_PCIE_DL_SEL);
+
+ val = tr32(TG3_PCIE_TLDLPL_PORT +
+ TG3_PCIE_DL_LO_FTSMAX);
+ val &= ~TG3_PCIE_DL_LO_FTSMAX_MSK;
+ tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_DL_LO_FTSMAX,
+ val | TG3_PCIE_DL_LO_FTSMAX_VAL);
+
+ tw32(GRC_MODE, grc_mode);
+ }
+
val = tr32(TG3_CPMU_LSPD_10MB_CLK);
val &= ~CPMU_LSPD_10MB_MACCLK_MASK;
val |= CPMU_LSPD_10MB_MACCLK_6_25;
@@ -7920,20 +8021,20 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
* other revision. But do not set this on PCI Express
* chips and don't even touch the clocks if the CPMU is present.
*/
- if (!(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT)) {
- if (!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
+ if (!tg3_flag(tp, CPMU_PRESENT)) {
+ if (!tg3_flag(tp, PCI_EXPRESS))
tp->pci_clock_ctrl |= CLOCK_CTRL_DELAY_PCI_GRANT;
tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl);
}
if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 &&
- (tp->tg3_flags & TG3_FLAG_PCIX_MODE)) {
+ tg3_flag(tp, PCIX_MODE)) {
val = tr32(TG3PCI_PCISTATE);
val |= PCISTATE_RETRY_SAME_DMA;
tw32(TG3PCI_PCISTATE, val);
}
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
+ if (tg3_flag(tp, ENABLE_APE)) {
/* Allow reads and writes to the
* APE register and memory space.
*/
@@ -7960,11 +8061,14 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
if (err)
return err;
- if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
+ if (tg3_flag(tp, 57765_PLUS)) {
val = tr32(TG3PCI_DMA_RW_CTRL) &
~DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0)
val &= ~DMA_RWCTRL_CRDRDR_RDMA_MRRS_MSK;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765 &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
+ val |= DMA_RWCTRL_TAGGED_STAT_WA;
tw32(TG3PCI_DMA_RW_CTRL, val | tp->dma_rwctrl);
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) {
@@ -7999,7 +8103,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(GRC_MISC_CFG, val);
/* Initialize MBUF/DESC pool. */
- if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
+ if (tg3_flag(tp, 5750_PLUS)) {
/* Do nothing. */
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE);
@@ -8009,7 +8113,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE96);
tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE);
tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE);
- } else if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) {
+ } else if (tg3_flag(tp, TSO_CAPABLE)) {
int fw_len;
fw_len = tp->fw_len;
@@ -8043,6 +8147,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
val = BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
val |= BUFMGR_MODE_NO_TX_UNDERRUN;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+ tp->pci_chip_rev_id == CHIPREV_ID_5719_A0 ||
+ tp->pci_chip_rev_id == CHIPREV_ID_5720_A0)
+ val |= BUFMGR_MODE_MBLOW_ATTN_ENAB;
tw32(BUFMGR_MODE, val);
for (i = 0; i < 2000; i++) {
if (tr32(BUFMGR_MODE) & BUFMGR_MODE_ENABLE)
@@ -8054,21 +8162,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
return -ENODEV;
}
- /* Setup replenish threshold. */
- val = tp->rx_pending / 8;
- if (val == 0)
- val = 1;
- else if (val > tp->rx_std_max_post)
- val = tp->rx_std_max_post;
- else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
- if (tp->pci_chip_rev_id == CHIPREV_ID_5906_A1)
- tw32(ISO_PKT_TX, (tr32(ISO_PKT_TX) & ~0x3) | 0x2);
-
- if (val > (TG3_RX_INTERNAL_RING_SZ_5906 / 2))
- val = TG3_RX_INTERNAL_RING_SZ_5906 / 2;
- }
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5906_A1)
+ tw32(ISO_PKT_TX, (tr32(ISO_PKT_TX) & ~0x3) | 0x2);
- tw32(RCVBDI_STD_THRESH, val);
+ tg3_setup_rxbd_thresholds(tp);
/* Initialize TG3_BDINFO's at:
* RCVDBDI_STD_BD: standard eth size rx ring
@@ -8091,13 +8188,12 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
((u64) tpr->rx_std_mapping >> 32));
tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
((u64) tpr->rx_std_mapping & 0xffffffff));
- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719)
+ if (!tg3_flag(tp, 5717_PLUS))
tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR,
NIC_SRAM_RX_BUFFER_DESC);
/* Disable the mini ring */
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+ if (!tg3_flag(tp, 5705_PLUS))
tw32(RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS,
BDINFO_FLAGS_DISABLED);
@@ -8105,20 +8201,18 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
* blocks on those devices that have them.
*/
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
- ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
- !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))) {
- /* Setup replenish threshold. */
- tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8);
+ (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS))) {
- if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
+ if (tg3_flag(tp, JUMBO_RING_ENABLE)) {
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH,
((u64) tpr->rx_jmb_mapping >> 32));
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
((u64) tpr->rx_jmb_mapping & 0xffffffff));
+ val = TG3_RX_JMB_RING_SIZE(tp) <<
+ BDINFO_FLAGS_MAXLEN_SHIFT;
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
- (RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT) |
- BDINFO_FLAGS_USE_EXT_RECV);
- if (!(tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) ||
+ val | BDINFO_FLAGS_USE_EXT_RECV);
+ if (!tg3_flag(tp, USE_JUMBO_BDFLAG) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
NIC_SRAM_RX_JUMBO_BUFFER_DESC);
@@ -8127,32 +8221,27 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
BDINFO_FLAGS_DISABLED);
}
- if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
+ if (tg3_flag(tp, 57765_PLUS)) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
- val = RX_STD_MAX_SIZE_5705;
+ val = TG3_RX_STD_MAX_SIZE_5700;
else
- val = RX_STD_MAX_SIZE_5717;
+ val = TG3_RX_STD_MAX_SIZE_5717;
val <<= BDINFO_FLAGS_MAXLEN_SHIFT;
val |= (TG3_RX_STD_DMA_SZ << 2);
} else
val = TG3_RX_STD_DMA_SZ << BDINFO_FLAGS_MAXLEN_SHIFT;
} else
- val = RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT;
+ val = TG3_RX_STD_MAX_SIZE_5700 << BDINFO_FLAGS_MAXLEN_SHIFT;
tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, val);
tpr->rx_std_prod_idx = tp->rx_pending;
tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, tpr->rx_std_prod_idx);
- tpr->rx_jmb_prod_idx = (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) ?
- tp->rx_jumbo_pending : 0;
+ tpr->rx_jmb_prod_idx =
+ tg3_flag(tp, JUMBO_RING_ENABLE) ? tp->rx_jumbo_pending : 0;
tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, tpr->rx_jmb_prod_idx);
- if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
- tw32(STD_REPLENISH_LWM, 32);
- tw32(JMB_REPLENISH_LWM, 16);
- }
-
tg3_rings_reset(tp);
/* Initialize MAC address and backoff seed. */
@@ -8165,10 +8254,16 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
/* The slot time is changed by tg3_setup_phy if we
* run at gigabit with half duplex.
*/
- tw32(MAC_TX_LENGTHS,
- (2 << TX_LENGTHS_IPG_CRS_SHIFT) |
- (6 << TX_LENGTHS_IPG_SHIFT) |
- (32 << TX_LENGTHS_SLOT_TIME_SHIFT));
+ val = (2 << TX_LENGTHS_IPG_CRS_SHIFT) |
+ (6 << TX_LENGTHS_IPG_SHIFT) |
+ (32 << TX_LENGTHS_SLOT_TIME_SHIFT);
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ val |= tr32(MAC_TX_LENGTHS) &
+ (TX_LENGTHS_JMB_FRM_LEN_MSK |
+ TX_LENGTHS_CNT_DWN_VAL_MSK);
+
+ tw32(MAC_TX_LENGTHS, val);
/* Receive rules. */
tw32(MAC_RCV_RULE_CFG, RCV_RULE_CFG_DEFAULT_CLASS);
@@ -8195,33 +8290,39 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) {
- if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE &&
+ if (tg3_flag(tp, TSO_CAPABLE) &&
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
rdmac_mode |= RDMAC_MODE_FIFO_SIZE_128;
} else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) &&
- !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) {
+ !tg3_flag(tp, IS_5788)) {
rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST;
}
}
- if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)
+ if (tg3_flag(tp, PCI_EXPRESS))
rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST;
- if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
+ if (tg3_flag(tp, HW_TSO_1) ||
+ tg3_flag(tp, HW_TSO_2) ||
+ tg3_flag(tp, HW_TSO_3))
rdmac_mode |= RDMAC_MODE_IPV4_LSO_EN;
- if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
+ if (tg3_flag(tp, 57765_PLUS) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ rdmac_mode |= tr32(RDMAC_MODE) & RDMAC_MODE_H2BNC_VLAN_DET;
+
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
- (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) {
+ tg3_flag(tp, 57765_PLUS)) {
val = tr32(TG3_RDMA_RSRVCTRL_REG);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
val &= ~(TG3_RDMA_RSRVCTRL_TXMRGN_MASK |
TG3_RDMA_RSRVCTRL_FIFO_LWM_MASK |
TG3_RDMA_RSRVCTRL_FIFO_HWM_MASK);
@@ -8233,7 +8334,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
}
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val |
TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K |
@@ -8241,12 +8343,12 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
}
/* Receive/send statistics. */
- if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
+ if (tg3_flag(tp, 5750_PLUS)) {
val = tr32(RCVLPC_STATS_ENABLE);
val &= ~RCVLPC_STATSENAB_DACK_FIX;
tw32(RCVLPC_STATS_ENABLE, val);
} else if ((rdmac_mode & RDMAC_MODE_FIFO_SIZE_128) &&
- (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) {
+ tg3_flag(tp, TSO_CAPABLE)) {
val = tr32(RCVLPC_STATS_ENABLE);
val &= ~RCVLPC_STATSENAB_LNGBRST_RFIX;
tw32(RCVLPC_STATS_ENABLE, val);
@@ -8269,7 +8371,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
__tg3_set_coalesce(tp, &tp->coal);
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+ if (!tg3_flag(tp, 5705_PLUS)) {
/* Status/statistics block address. See tg3_timer,
* the tg3_periodic_fetch_stats call there, and
* tg3_get_stats to see how this works for 5705/5750 chips.
@@ -8295,7 +8397,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(RCVCC_MODE, RCVCC_MODE_ENABLE | RCVCC_MODE_ATTN_ENABLE);
tw32(RCVLPC_MODE, RCVLPC_MODE_ENABLE);
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+ if (!tg3_flag(tp, 5705_PLUS))
tw32(RCVLSC_MODE, RCVLSC_MODE_ENABLE | RCVLSC_MODE_ATTN_ENABLE);
if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) {
@@ -8305,13 +8407,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
udelay(10);
}
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+ if (tg3_flag(tp, ENABLE_APE))
tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
else
tp->mac_mode = 0;
tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
+ if (!tg3_flag(tp, 5705_PLUS) &&
!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700)
tp->mac_mode |= MAC_MODE_LINK_POLARITY;
@@ -8319,12 +8421,12 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
udelay(40);
/* tp->grc_local_ctrl is partially set up during tg3_get_invariants().
- * If TG3_FLG2_IS_NIC is zero, we should read the
+ * If TG3_FLAG_IS_NIC is zero, we should read the
* register to preserve the GPIO settings for LOMs. The GPIOs,
* whether used as inputs or outputs, are set by boot code after
* reset.
*/
- if (!(tp->tg3_flags2 & TG3_FLG2_IS_NIC)) {
+ if (!tg3_flag(tp, IS_NIC)) {
u32 gpio_mask;
gpio_mask = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE1 |
@@ -8342,21 +8444,20 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tp->grc_local_ctrl |= tr32(GRC_LOCAL_CTRL) & gpio_mask;
/* GPIO1 must be driven high for eeprom write protect */
- if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT)
+ if (tg3_flag(tp, EEPROM_WRITE_PROT))
tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 |
GRC_LCLCTRL_GPIO_OUTPUT1);
}
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
udelay(100);
- if ((tp->tg3_flags2 & TG3_FLG2_USING_MSIX) &&
- tp->irq_cnt > 1) {
+ if (tg3_flag(tp, USING_MSIX) && tp->irq_cnt > 1) {
val = tr32(MSGINT_MODE);
val |= MSGINT_MODE_MULTIVEC_EN | MSGINT_MODE_ENABLE;
tw32(MSGINT_MODE, val);
}
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+ if (!tg3_flag(tp, 5705_PLUS)) {
tw32_f(DMAC_MODE, DMAC_MODE_ENABLE);
udelay(40);
}
@@ -8369,18 +8470,18 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) {
- if ((tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) &&
+ if (tg3_flag(tp, TSO_CAPABLE) &&
(tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 ||
tp->pci_chip_rev_id == CHIPREV_ID_5705_A2)) {
/* nothing */
} else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) &&
- !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) {
+ !tg3_flag(tp, IS_5788)) {
val |= WDMAC_MODE_RX_ACCEL;
}
}
/* Enable host coalescing bug fix */
- if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
+ if (tg3_flag(tp, 5755_PLUS))
val |= WDMAC_MODE_STATUS_TAG_FIX;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
@@ -8389,7 +8490,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32_f(WDMAC_MODE, val);
udelay(40);
- if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) {
+ if (tg3_flag(tp, PCIX_MODE)) {
u16 pcix_cmd;
pci_read_config_word(tp->pdev, tp->pcix_cap + PCI_X_CMD,
@@ -8409,7 +8510,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
udelay(40);
tw32(RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE);
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+ if (!tg3_flag(tp, 5705_PLUS))
tw32(MBFREE_MODE, MBFREE_MODE_ENABLE);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
@@ -8421,15 +8522,16 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(SNDBDC_MODE, SNDBDC_MODE_ENABLE | SNDBDC_MODE_ATTN_ENABLE);
tw32(RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB);
val = RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+ if (tg3_flag(tp, LRG_PROD_RING_CAP))
val |= RCVDBDI_MODE_LRG_RING_SZ;
tw32(RCVDBDI_MODE, val);
tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);
- if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
+ if (tg3_flag(tp, HW_TSO_1) ||
+ tg3_flag(tp, HW_TSO_2) ||
+ tg3_flag(tp, HW_TSO_3))
tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8);
val = SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE;
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+ if (tg3_flag(tp, ENABLE_TSS))
val |= SNDBDI_MODE_MULTI_TXQ_EN;
tw32(SNDBDI_MODE, val);
tw32(SNDBDS_MODE, SNDBDS_MODE_ENABLE | SNDBDS_MODE_ATTN_ENABLE);
@@ -8440,20 +8542,28 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
return err;
}
- if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) {
+ if (tg3_flag(tp, TSO_CAPABLE)) {
err = tg3_load_tso_firmware(tp);
if (err)
return err;
}
tp->tx_mode = TX_MODE_ENABLE;
- if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
+
+ if (tg3_flag(tp, 5755_PLUS) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
tp->tx_mode |= TX_MODE_MBUF_LOCKUP_FIX;
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
+ val = TX_MODE_JMB_FRM_LEN | TX_MODE_CNT_DN_MODE;
+ tp->tx_mode &= ~val;
+ tp->tx_mode |= tr32(MAC_TX_MODE) & val;
+ }
+
tw32_f(MAC_TX_MODE, tp->tx_mode);
udelay(100);
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) {
+ if (tg3_flag(tp, ENABLE_RSS)) {
u32 reg = MAC_RSS_INDIR_TBL_0;
u8 *ent = (u8 *)&val;
@@ -8482,10 +8592,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
}
tp->rx_mode = RX_MODE_ENABLE;
- if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
+ if (tg3_flag(tp, 5755_PLUS))
tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE;
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)
+ if (tg3_flag(tp, ENABLE_RSS))
tp->rx_mode |= RX_MODE_RSS_ENABLE |
RX_MODE_RSS_ITBL_HASH_BITS_7 |
RX_MODE_RSS_IPV6_HASH_EN |
@@ -8532,11 +8642,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) {
/* Use hardware link auto-negotiation */
- tp->tg3_flags2 |= TG3_FLG2_HW_AUTONEG;
+ tg3_flag_set(tp, HW_AUTONEG);
}
if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) &&
- (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) {
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
u32 tmp;
tmp = tr32(SERDES_RX_CTRL);
@@ -8546,7 +8656,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
}
- if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
+ if (!tg3_flag(tp, USE_PHYLIB)) {
if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER;
tp->link_config.speed = tp->link_config.orig_speed;
@@ -8579,12 +8689,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(MAC_RCV_RULE_1, 0x86000004 & RCV_RULE_DISABLE_MASK);
tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK);
- if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
- !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
+ if (tg3_flag(tp, 5705_PLUS) && !tg3_flag(tp, 5780_CLASS))
limit = 8;
else
limit = 16;
- if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)
+ if (tg3_flag(tp, ENABLE_ASF))
limit -= 4;
switch (limit) {
case 16:
@@ -8622,7 +8731,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
break;
}
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+ if (tg3_flag(tp, ENABLE_APE))
/* Write our heartbeat update interval to APE. */
tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_INT_MS,
APE_HOST_HEARTBEAT_INT_DISABLE);
@@ -8688,7 +8797,21 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp)
TG3_STAT_ADD32(&sp->rx_undersize_packets, MAC_RX_STATS_UNDERSIZE);
TG3_STAT_ADD32(&sp->rxbds_empty, RCVLPC_NO_RCV_BD_CNT);
- TG3_STAT_ADD32(&sp->rx_discards, RCVLPC_IN_DISCARDS_CNT);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
+ tp->pci_chip_rev_id != CHIPREV_ID_5719_A0 &&
+ tp->pci_chip_rev_id != CHIPREV_ID_5720_A0) {
+ TG3_STAT_ADD32(&sp->rx_discards, RCVLPC_IN_DISCARDS_CNT);
+ } else {
+ u32 val = tr32(HOSTCC_FLOW_ATTN);
+ val = (val & HOSTCC_FLOW_ATTN_MBUF_LWM) ? 1 : 0;
+ if (val) {
+ tw32(HOSTCC_FLOW_ATTN, HOSTCC_FLOW_ATTN_MBUF_LWM);
+ sp->rx_discards.low += val;
+ if (sp->rx_discards.low < val)
+ sp->rx_discards.high += 1;
+ }
+ sp->mbuf_lwm_thresh_hit = sp->rx_discards;
+ }
TG3_STAT_ADD32(&sp->rx_errors, RCVLPC_IN_ERRORS_CNT);
}
@@ -8701,7 +8824,7 @@ static void tg3_timer(unsigned long __opaque)
spin_lock(&tp->lock);
- if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
+ if (!tg3_flag(tp, TAGGED_STATUS)) {
/* All of this garbage is because when using non-tagged
* IRQ status the mailbox/status_block protocol the chip
* uses with the cpu is race prone.
@@ -8715,7 +8838,7 @@ static void tg3_timer(unsigned long __opaque)
}
if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
- tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER;
+ tg3_flag_set(tp, RESTART_TIMER);
spin_unlock(&tp->lock);
schedule_work(&tp->reset_task);
return;
@@ -8724,16 +8847,13 @@ static void tg3_timer(unsigned long __opaque)
/* This part only runs once per second. */
if (!--tp->timer_counter) {
- if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+ if (tg3_flag(tp, 5705_PLUS))
tg3_periodic_fetch_stats(tp);
- if (tp->setlpicnt && !--tp->setlpicnt) {
- u32 val = tr32(TG3_CPMU_EEE_MODE);
- tw32(TG3_CPMU_EEE_MODE,
- val | TG3_CPMU_EEEMD_LPI_ENABLE);
- }
+ if (tp->setlpicnt && !--tp->setlpicnt)
+ tg3_phy_eee_enable(tp);
- if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) {
+ if (tg3_flag(tp, USE_LINKCHG_REG)) {
u32 mac_stat;
int phy_event;
@@ -8748,7 +8868,7 @@ static void tg3_timer(unsigned long __opaque)
if (phy_event)
tg3_setup_phy(tp, 0);
- } else if (tp->tg3_flags & TG3_FLAG_POLL_SERDES) {
+ } else if (tg3_flag(tp, POLL_SERDES)) {
u32 mac_stat = tr32(MAC_STATUS);
int need_setup = 0;
@@ -8773,7 +8893,7 @@ static void tg3_timer(unsigned long __opaque)
tg3_setup_phy(tp, 0);
}
} else if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) &&
- (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+ tg3_flag(tp, 5780_CLASS)) {
tg3_serdes_parallel_detect(tp);
}
@@ -8798,8 +8918,7 @@ static void tg3_timer(unsigned long __opaque)
* resets.
*/
if (!--tp->asf_counter) {
- if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
- !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
+ if (tg3_flag(tp, ENABLE_ASF) && !tg3_flag(tp, ENABLE_APE)) {
tg3_wait_for_event_ack(tp);
tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
@@ -8835,16 +8954,16 @@ static int tg3_request_irq(struct tg3 *tp, int irq_num)
name[IFNAMSIZ-1] = 0;
}
- if (tp->tg3_flags2 & TG3_FLG2_USING_MSI_OR_MSIX) {
+ if (tg3_flag(tp, USING_MSI) || tg3_flag(tp, USING_MSIX)) {
fn = tg3_msi;
- if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
+ if (tg3_flag(tp, 1SHOT_MSI))
fn = tg3_msi_1shot;
- flags = IRQF_SAMPLE_RANDOM;
+ flags = 0;
} else {
fn = tg3_interrupt;
- if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
+ if (tg3_flag(tp, TAGGED_STATUS))
fn = tg3_interrupt_tagged;
- flags = IRQF_SHARED | IRQF_SAMPLE_RANDOM;
+ flags = IRQF_SHARED;
}
return request_irq(tnapi->irq_vec, fn, flags, name, tnapi);
@@ -8868,8 +8987,7 @@ static int tg3_test_interrupt(struct tg3 *tp)
* Turn off MSI one shot mode. Otherwise this test has no
* observable way to know whether the interrupt was delivered.
*/
- if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
- (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
+ if (tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) {
val = tr32(MSGINT_MODE) | MSGINT_MODE_ONE_SHOT_DISABLE;
tw32(MSGINT_MODE, val);
}
@@ -8911,8 +9029,7 @@ static int tg3_test_interrupt(struct tg3 *tp)
if (intr_ok) {
/* Reenable MSI one shot mode. */
- if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
- (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
+ if (tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) {
val = tr32(MSGINT_MODE) & ~MSGINT_MODE_ONE_SHOT_DISABLE;
tw32(MSGINT_MODE, val);
}
@@ -8930,7 +9047,7 @@ static int tg3_test_msi(struct tg3 *tp)
int err;
u16 pci_cmd;
- if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSI))
+ if (!tg3_flag(tp, USING_MSI))
return 0;
/* Turn off SERR reporting in case MSI terminates with Master
@@ -8960,7 +9077,7 @@ static int tg3_test_msi(struct tg3 *tp)
pci_disable_msi(tp->pdev);
- tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
+ tg3_flag_clear(tp, USING_MSI);
tp->napi[0].irq_vec = tp->pdev->irq;
err = tg3_request_irq(tp, 0);
@@ -9057,9 +9174,11 @@ static bool tg3_enable_msix(struct tg3 *tp)
}
if (tp->irq_cnt > 1) {
- tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
- tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS;
+ tg3_flag_set(tp, ENABLE_RSS);
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
+ tg3_flag_set(tp, ENABLE_TSS);
netif_set_real_num_tx_queues(tp->dev, tp->irq_cnt - 1);
}
}
@@ -9069,8 +9188,8 @@ static bool tg3_enable_msix(struct tg3 *tp)
static void tg3_ints_init(struct tg3 *tp)
{
- if ((tp->tg3_flags & TG3_FLAG_SUPPORT_MSI_OR_MSIX) &&
- !(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
+ if ((tg3_flag(tp, SUPPORT_MSI) || tg3_flag(tp, SUPPORT_MSIX)) &&
+ !tg3_flag(tp, TAGGED_STATUS)) {
/* All MSI supporting chips should support tagged
* status. Assert that this is the case.
*/
@@ -9079,21 +9198,19 @@ static void tg3_ints_init(struct tg3 *tp)
goto defcfg;
}
- if ((tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX) && tg3_enable_msix(tp))
- tp->tg3_flags2 |= TG3_FLG2_USING_MSIX;
- else if ((tp->tg3_flags & TG3_FLAG_SUPPORT_MSI) &&
- pci_enable_msi(tp->pdev) == 0)
- tp->tg3_flags2 |= TG3_FLG2_USING_MSI;
+ if (tg3_flag(tp, SUPPORT_MSIX) && tg3_enable_msix(tp))
+ tg3_flag_set(tp, USING_MSIX);
+ else if (tg3_flag(tp, SUPPORT_MSI) && pci_enable_msi(tp->pdev) == 0)
+ tg3_flag_set(tp, USING_MSI);
- if (tp->tg3_flags2 & TG3_FLG2_USING_MSI_OR_MSIX) {
+ if (tg3_flag(tp, USING_MSI) || tg3_flag(tp, USING_MSIX)) {
u32 msi_mode = tr32(MSGINT_MODE);
- if ((tp->tg3_flags2 & TG3_FLG2_USING_MSIX) &&
- tp->irq_cnt > 1)
+ if (tg3_flag(tp, USING_MSIX) && tp->irq_cnt > 1)
msi_mode |= MSGINT_MODE_MULTIVEC_EN;
tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE);
}
defcfg:
- if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSIX)) {
+ if (!tg3_flag(tp, USING_MSIX)) {
tp->irq_cnt = 1;
tp->napi[0].irq_vec = tp->pdev->irq;
netif_set_real_num_tx_queues(tp->dev, 1);
@@ -9103,12 +9220,14 @@ defcfg:
static void tg3_ints_fini(struct tg3 *tp)
{
- if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX)
+ if (tg3_flag(tp, USING_MSIX))
pci_disable_msix(tp->pdev);
- else if (tp->tg3_flags2 & TG3_FLG2_USING_MSI)
+ else if (tg3_flag(tp, USING_MSI))
pci_disable_msi(tp->pdev);
- tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI_OR_MSIX;
- tp->tg3_flags3 &= ~(TG3_FLG3_ENABLE_RSS | TG3_FLG3_ENABLE_TSS);
+ tg3_flag_clear(tp, USING_MSI);
+ tg3_flag_clear(tp, USING_MSIX);
+ tg3_flag_clear(tp, ENABLE_RSS);
+ tg3_flag_clear(tp, ENABLE_TSS);
}
static int tg3_open(struct net_device *dev)
@@ -9123,10 +9242,10 @@ static int tg3_open(struct net_device *dev)
return err;
} else if (err) {
netdev_warn(tp->dev, "TSO capability disabled\n");
- tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
- } else if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) {
+ tg3_flag_clear(tp, TSO_CAPABLE);
+ } else if (!tg3_flag(tp, TSO_CAPABLE)) {
netdev_notice(tp->dev, "TSO capability restored\n");
- tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
+ tg3_flag_set(tp, TSO_CAPABLE);
}
}
@@ -9139,7 +9258,7 @@ static int tg3_open(struct net_device *dev)
tg3_full_lock(tp, 0);
tg3_disable_ints(tp);
- tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
+ tg3_flag_clear(tp, INIT_COMPLETE);
tg3_full_unlock(tp);
@@ -9180,7 +9299,7 @@ static int tg3_open(struct net_device *dev)
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
tg3_free_rings(tp);
} else {
- if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
+ if (tg3_flag(tp, TAGGED_STATUS))
tp->timer_offset = HZ;
else
tp->timer_offset = HZ / 10;
@@ -9202,7 +9321,7 @@ static int tg3_open(struct net_device *dev)
if (err)
goto err_out3;
- if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+ if (tg3_flag(tp, USING_MSI)) {
err = tg3_test_msi(tp);
if (err) {
@@ -9214,8 +9333,7 @@ static int tg3_open(struct net_device *dev)
goto err_out2;
}
- if (!(tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
- (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
+ if (!tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) {
u32 val = tr32(PCIE_TRANSACTION_CFG);
tw32(PCIE_TRANSACTION_CFG,
@@ -9228,13 +9346,20 @@ static int tg3_open(struct net_device *dev)
tg3_full_lock(tp, 0);
add_timer(&tp->timer);
- tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
+ tg3_flag_set(tp, INIT_COMPLETE);
tg3_enable_ints(tp);
tg3_full_unlock(tp);
netif_tx_start_all_queues(dev);
+ /*
+ * Reset loopback feature if it was turned on while the device was down
+ * make sure that it's installed properly now.
+ */
+ if (dev->features & NETIF_F_LOOPBACK)
+ tg3_set_loopback(dev, dev->features);
+
return 0;
err_out3:
@@ -9277,7 +9402,7 @@ static int tg3_close(struct net_device *dev)
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
tg3_free_rings(tp);
- tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
+ tg3_flag_clear(tp, INIT_COMPLETE);
tg3_full_unlock(tp);
@@ -9424,6 +9549,8 @@ static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp)
ESTAT_ADD(nic_avoided_irqs);
ESTAT_ADD(nic_tx_threshold_hit);
+ ESTAT_ADD(mbuf_lwm_thresh_hit);
+
return estats;
}
@@ -9534,7 +9661,7 @@ static void __tg3_set_rx_mode(struct net_device *dev)
/* When ASF is in use, we always keep the RX_MODE_KEEP_VLAN_TAG
* flag clear.
*/
- if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+ if (!tg3_flag(tp, ENABLE_ASF))
rx_mode |= RX_MODE_KEEP_VLAN_TAG;
#endif
@@ -9588,82 +9715,26 @@ static void tg3_set_rx_mode(struct net_device *dev)
tg3_full_unlock(tp);
}
-#define TG3_REGDUMP_LEN (32 * 1024)
-
static int tg3_get_regs_len(struct net_device *dev)
{
- return TG3_REGDUMP_LEN;
+ return TG3_REG_BLK_SIZE;
}
static void tg3_get_regs(struct net_device *dev,
struct ethtool_regs *regs, void *_p)
{
- u32 *p = _p;
struct tg3 *tp = netdev_priv(dev);
- u8 *orig_p = _p;
- int i;
regs->version = 0;
- memset(p, 0, TG3_REGDUMP_LEN);
+ memset(_p, 0, TG3_REG_BLK_SIZE);
if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
return;
tg3_full_lock(tp, 0);
-#define __GET_REG32(reg) (*(p)++ = tr32(reg))
-#define GET_REG32_LOOP(base, len) \
-do { p = (u32 *)(orig_p + (base)); \
- for (i = 0; i < len; i += 4) \
- __GET_REG32((base) + i); \
-} while (0)
-#define GET_REG32_1(reg) \
-do { p = (u32 *)(orig_p + (reg)); \
- __GET_REG32((reg)); \
-} while (0)
-
- GET_REG32_LOOP(TG3PCI_VENDOR, 0xb0);
- GET_REG32_LOOP(MAILBOX_INTERRUPT_0, 0x200);
- GET_REG32_LOOP(MAC_MODE, 0x4f0);
- GET_REG32_LOOP(SNDDATAI_MODE, 0xe0);
- GET_REG32_1(SNDDATAC_MODE);
- GET_REG32_LOOP(SNDBDS_MODE, 0x80);
- GET_REG32_LOOP(SNDBDI_MODE, 0x48);
- GET_REG32_1(SNDBDC_MODE);
- GET_REG32_LOOP(RCVLPC_MODE, 0x20);
- GET_REG32_LOOP(RCVLPC_SELLST_BASE, 0x15c);
- GET_REG32_LOOP(RCVDBDI_MODE, 0x0c);
- GET_REG32_LOOP(RCVDBDI_JUMBO_BD, 0x3c);
- GET_REG32_LOOP(RCVDBDI_BD_PROD_IDX_0, 0x44);
- GET_REG32_1(RCVDCC_MODE);
- GET_REG32_LOOP(RCVBDI_MODE, 0x20);
- GET_REG32_LOOP(RCVCC_MODE, 0x14);
- GET_REG32_LOOP(RCVLSC_MODE, 0x08);
- GET_REG32_1(MBFREE_MODE);
- GET_REG32_LOOP(HOSTCC_MODE, 0x100);
- GET_REG32_LOOP(MEMARB_MODE, 0x10);
- GET_REG32_LOOP(BUFMGR_MODE, 0x58);
- GET_REG32_LOOP(RDMAC_MODE, 0x08);
- GET_REG32_LOOP(WDMAC_MODE, 0x08);
- GET_REG32_1(RX_CPU_MODE);
- GET_REG32_1(RX_CPU_STATE);
- GET_REG32_1(RX_CPU_PGMCTR);
- GET_REG32_1(RX_CPU_HWBKPT);
- GET_REG32_1(TX_CPU_MODE);
- GET_REG32_1(TX_CPU_STATE);
- GET_REG32_1(TX_CPU_PGMCTR);
- GET_REG32_LOOP(GRCMBOX_INTERRUPT_0, 0x110);
- GET_REG32_LOOP(FTQ_RESET, 0x120);
- GET_REG32_LOOP(MSGINT_MODE, 0x0c);
- GET_REG32_1(DMAC_MODE);
- GET_REG32_LOOP(GRC_MODE, 0x4c);
- if (tp->tg3_flags & TG3_FLAG_NVRAM)
- GET_REG32_LOOP(NVRAM_CMD, 0x24);
-
-#undef __GET_REG32
-#undef GET_REG32_LOOP
-#undef GET_REG32_1
+ tg3_dump_legacy_regs(tp, (u32 *)_p);
tg3_full_unlock(tp);
}
@@ -9683,7 +9754,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
u32 i, offset, len, b_offset, b_count;
__be32 val;
- if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM)
+ if (tg3_flag(tp, NO_NVRAM))
return -EINVAL;
if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
@@ -9751,7 +9822,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
return -EAGAIN;
- if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+ if (tg3_flag(tp, NO_NVRAM) ||
eeprom->magic != TG3_EEPROM_MAGIC)
return -EINVAL;
@@ -9803,7 +9874,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct tg3 *tp = netdev_priv(dev);
- if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ if (tg3_flag(tp, USE_PHYLIB)) {
struct phy_device *phydev;
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
return -EAGAIN;
@@ -9831,10 +9902,10 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->advertising = tp->link_config.advertising;
if (netif_running(dev)) {
- cmd->speed = tp->link_config.active_speed;
+ ethtool_cmd_speed_set(cmd, tp->link_config.active_speed);
cmd->duplex = tp->link_config.active_duplex;
} else {
- cmd->speed = SPEED_INVALID;
+ ethtool_cmd_speed_set(cmd, SPEED_INVALID);
cmd->duplex = DUPLEX_INVALID;
}
cmd->phy_address = tp->phy_addr;
@@ -9848,8 +9919,9 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct tg3 *tp = netdev_priv(dev);
+ u32 speed = ethtool_cmd_speed(cmd);
- if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ if (tg3_flag(tp, USE_PHYLIB)) {
struct phy_device *phydev;
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
return -EAGAIN;
@@ -9897,14 +9969,14 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->advertising &= mask;
} else {
if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) {
- if (cmd->speed != SPEED_1000)
+ if (speed != SPEED_1000)
return -EINVAL;
if (cmd->duplex != DUPLEX_FULL)
return -EINVAL;
} else {
- if (cmd->speed != SPEED_100 &&
- cmd->speed != SPEED_10)
+ if (speed != SPEED_100 &&
+ speed != SPEED_10)
return -EINVAL;
}
}
@@ -9919,7 +9991,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
tp->link_config.duplex = DUPLEX_INVALID;
} else {
tp->link_config.advertising = 0;
- tp->link_config.speed = cmd->speed;
+ tp->link_config.speed = speed;
tp->link_config.duplex = cmd->duplex;
}
@@ -9949,14 +10021,12 @@ static void tg3_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct tg3 *tp = netdev_priv(dev);
- if ((tp->tg3_flags & TG3_FLAG_WOL_CAP) &&
- device_can_wakeup(&tp->pdev->dev))
+ if (tg3_flag(tp, WOL_CAP) && device_can_wakeup(&tp->pdev->dev))
wol->supported = WAKE_MAGIC;
else
wol->supported = 0;
wol->wolopts = 0;
- if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) &&
- device_can_wakeup(&tp->pdev->dev))
+ if (tg3_flag(tp, WOL_ENABLE) && device_can_wakeup(&tp->pdev->dev))
wol->wolopts = WAKE_MAGIC;
memset(&wol->sopass, 0, sizeof(wol->sopass));
}
@@ -9969,19 +10039,18 @@ static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
if (wol->wolopts & ~WAKE_MAGIC)
return -EINVAL;
if ((wol->wolopts & WAKE_MAGIC) &&
- !((tp->tg3_flags & TG3_FLAG_WOL_CAP) && device_can_wakeup(dp)))
+ !(tg3_flag(tp, WOL_CAP) && device_can_wakeup(dp)))
return -EINVAL;
device_set_wakeup_enable(dp, wol->wolopts & WAKE_MAGIC);
spin_lock_bh(&tp->lock);
if (device_may_wakeup(dp))
- tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
+ tg3_flag_set(tp, WOL_ENABLE);
else
- tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE;
+ tg3_flag_clear(tp, WOL_ENABLE);
spin_unlock_bh(&tp->lock);
-
return 0;
}
@@ -9997,33 +10066,6 @@ static void tg3_set_msglevel(struct net_device *dev, u32 value)
tp->msg_enable = value;
}
-static int tg3_set_tso(struct net_device *dev, u32 value)
-{
- struct tg3 *tp = netdev_priv(dev);
-
- if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) {
- if (value)
- return -EINVAL;
- return 0;
- }
- if ((dev->features & NETIF_F_IPV6_CSUM) &&
- ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) ||
- (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3))) {
- if (value) {
- dev->features |= NETIF_F_TSO6;
- if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
- (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
- GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
- dev->features |= NETIF_F_TSO_ECN;
- } else
- dev->features &= ~(NETIF_F_TSO6 | NETIF_F_TSO_ECN);
- }
- return ethtool_op_set_tso(dev, value);
-}
-
static int tg3_nway_reset(struct net_device *dev)
{
struct tg3 *tp = netdev_priv(dev);
@@ -10035,7 +10077,7 @@ static int tg3_nway_reset(struct net_device *dev)
if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
return -EINVAL;
- if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ if (tg3_flag(tp, USE_PHYLIB)) {
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
return -EAGAIN;
r = phy_start_aneg(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
@@ -10064,7 +10106,7 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *
ering->rx_max_pending = tp->rx_std_ring_mask;
ering->rx_mini_max_pending = 0;
- if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE)
+ if (tg3_flag(tp, JUMBO_RING_ENABLE))
ering->rx_jumbo_max_pending = tp->rx_jmb_ring_mask;
else
ering->rx_jumbo_max_pending = 0;
@@ -10073,7 +10115,7 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *
ering->rx_pending = tp->rx_pending;
ering->rx_mini_pending = 0;
- if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE)
+ if (tg3_flag(tp, JUMBO_RING_ENABLE))
ering->rx_jumbo_pending = tp->rx_jumbo_pending;
else
ering->rx_jumbo_pending = 0;
@@ -10090,7 +10132,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
(ering->rx_jumbo_pending > tp->rx_jmb_ring_mask) ||
(ering->tx_pending > TG3_TX_RING_SIZE - 1) ||
(ering->tx_pending <= MAX_SKB_FRAGS) ||
- ((tp->tg3_flags2 & TG3_FLG2_TSO_BUG) &&
+ (tg3_flag(tp, TSO_BUG) &&
(ering->tx_pending <= (MAX_SKB_FRAGS * 3))))
return -EINVAL;
@@ -10104,7 +10146,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
tp->rx_pending = ering->rx_pending;
- if ((tp->tg3_flags2 & TG3_FLG2_MAX_RXPEND_64) &&
+ if (tg3_flag(tp, MAX_RXPEND_64) &&
tp->rx_pending > 63)
tp->rx_pending = 63;
tp->rx_jumbo_pending = ering->rx_jumbo_pending;
@@ -10131,7 +10173,7 @@ 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->autoneg = !!tg3_flag(tp, PAUSE_AUTONEG);
if (tp->link_config.active_flowctrl & FLOW_CTRL_RX)
epause->rx_pause = 1;
@@ -10149,7 +10191,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
struct tg3 *tp = netdev_priv(dev);
int err = 0;
- if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ if (tg3_flag(tp, USE_PHYLIB)) {
u32 newadv;
struct phy_device *phydev;
@@ -10177,9 +10219,9 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
newadv = 0;
if (epause->autoneg)
- tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
+ tg3_flag_set(tp, PAUSE_AUTONEG);
else
- tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
+ tg3_flag_clear(tp, PAUSE_AUTONEG);
if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) {
u32 oldadv = phydev->advertising &
@@ -10221,9 +10263,9 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
tg3_full_lock(tp, irq_sync);
if (epause->autoneg)
- tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
+ tg3_flag_set(tp, PAUSE_AUTONEG);
else
- tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
+ tg3_flag_clear(tp, PAUSE_AUTONEG);
if (epause->rx_pause)
tp->link_config.flowctrl |= FLOW_CTRL_RX;
else
@@ -10246,50 +10288,6 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
return err;
}
-static u32 tg3_get_rx_csum(struct net_device *dev)
-{
- struct tg3 *tp = netdev_priv(dev);
- return (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0;
-}
-
-static int tg3_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct tg3 *tp = netdev_priv(dev);
-
- if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) {
- if (data != 0)
- return -EINVAL;
- return 0;
- }
-
- spin_lock_bh(&tp->lock);
- if (data)
- tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
- else
- tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
- spin_unlock_bh(&tp->lock);
-
- return 0;
-}
-
-static int tg3_set_tx_csum(struct net_device *dev, u32 data)
-{
- struct tg3 *tp = netdev_priv(dev);
-
- if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) {
- if (data != 0)
- return -EINVAL;
- return 0;
- }
-
- if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
- ethtool_op_set_tx_ipv6_csum(dev, data);
- else
- ethtool_op_set_tx_csum(dev, data);
-
- return 0;
-}
-
static int tg3_get_sset_count(struct net_device *dev, int sset)
{
switch (sset) {
@@ -10317,35 +10315,38 @@ static void tg3_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
}
}
-static int tg3_phys_id(struct net_device *dev, u32 data)
+static int tg3_set_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
struct tg3 *tp = netdev_priv(dev);
- int i;
if (!netif_running(tp->dev))
return -EAGAIN;
- if (data == 0)
- data = UINT_MAX / 2;
-
- for (i = 0; i < (data * 2); i++) {
- if ((i % 2) == 0)
- tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE |
- LED_CTRL_1000MBPS_ON |
- LED_CTRL_100MBPS_ON |
- LED_CTRL_10MBPS_ON |
- LED_CTRL_TRAFFIC_OVERRIDE |
- LED_CTRL_TRAFFIC_BLINK |
- LED_CTRL_TRAFFIC_LED);
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ return 1; /* cycle on/off once per second */
+
+ case ETHTOOL_ID_ON:
+ tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE |
+ LED_CTRL_1000MBPS_ON |
+ LED_CTRL_100MBPS_ON |
+ LED_CTRL_10MBPS_ON |
+ LED_CTRL_TRAFFIC_OVERRIDE |
+ LED_CTRL_TRAFFIC_BLINK |
+ LED_CTRL_TRAFFIC_LED);
+ break;
- else
- tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE |
- LED_CTRL_TRAFFIC_OVERRIDE);
+ case ETHTOOL_ID_OFF:
+ tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE |
+ LED_CTRL_TRAFFIC_OVERRIDE);
+ break;
- if (msleep_interruptible(500))
- break;
+ case ETHTOOL_ID_INACTIVE:
+ tw32(MAC_LED_CTRL, tp->led_ctrl);
+ break;
}
- tw32(MAC_LED_CTRL, tp->led_ctrl);
+
return 0;
}
@@ -10356,6 +10357,80 @@ static void tg3_get_ethtool_stats(struct net_device *dev,
memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats));
}
+static __be32 * tg3_vpd_readblock(struct tg3 *tp)
+{
+ int i;
+ __be32 *buf;
+ u32 offset = 0, len = 0;
+ u32 magic, val;
+
+ if (tg3_flag(tp, NO_NVRAM) || tg3_nvram_read(tp, 0, &magic))
+ return NULL;
+
+ if (magic == TG3_EEPROM_MAGIC) {
+ for (offset = TG3_NVM_DIR_START;
+ offset < TG3_NVM_DIR_END;
+ offset += TG3_NVM_DIRENT_SIZE) {
+ if (tg3_nvram_read(tp, offset, &val))
+ return NULL;
+
+ if ((val >> TG3_NVM_DIRTYPE_SHIFT) ==
+ TG3_NVM_DIRTYPE_EXTVPD)
+ break;
+ }
+
+ if (offset != TG3_NVM_DIR_END) {
+ len = (val & TG3_NVM_DIRTYPE_LENMSK) * 4;
+ if (tg3_nvram_read(tp, offset + 4, &offset))
+ return NULL;
+
+ offset = tg3_nvram_logical_addr(tp, offset);
+ }
+ }
+
+ if (!offset || !len) {
+ offset = TG3_NVM_VPD_OFF;
+ len = TG3_NVM_VPD_LEN;
+ }
+
+ buf = kmalloc(len, GFP_KERNEL);
+ if (buf == NULL)
+ return NULL;
+
+ if (magic == TG3_EEPROM_MAGIC) {
+ for (i = 0; i < len; i += 4) {
+ /* The data is in little-endian format in NVRAM.
+ * Use the big-endian read routines to preserve
+ * the byte order as it exists in NVRAM.
+ */
+ if (tg3_nvram_read_be32(tp, offset + i, &buf[i/4]))
+ goto error;
+ }
+ } else {
+ u8 *ptr;
+ ssize_t cnt;
+ unsigned int pos = 0;
+
+ ptr = (u8 *)&buf[0];
+ for (i = 0; pos < len && i < 3; i++, pos += cnt, ptr += cnt) {
+ cnt = pci_read_vpd(tp->pdev, pos,
+ len - pos, ptr);
+ if (cnt == -ETIMEDOUT || cnt == -EINTR)
+ cnt = 0;
+ else if (cnt < 0)
+ goto error;
+ }
+ if (pos != len)
+ goto error;
+ }
+
+ return buf;
+
+error:
+ kfree(buf);
+ return NULL;
+}
+
#define NVRAM_TEST_SIZE 0x100
#define NVRAM_SELFBOOT_FORMAT1_0_SIZE 0x14
#define NVRAM_SELFBOOT_FORMAT1_2_SIZE 0x18
@@ -10369,7 +10444,7 @@ static int tg3_test_nvram(struct tg3 *tp)
__be32 *buf;
int i, j, k, err = 0, size;
- if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM)
+ if (tg3_flag(tp, NO_NVRAM))
return 0;
if (tg3_nvram_read(tp, 0, &magic) != 0)
@@ -10495,14 +10570,11 @@ static int tg3_test_nvram(struct tg3 *tp)
if (csum != le32_to_cpu(buf[0xfc/4]))
goto out;
- for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) {
- /* The data is in little-endian format in NVRAM.
- * Use the big-endian read routines to preserve
- * the byte order as it exists in NVRAM.
- */
- if (tg3_nvram_read_be32(tp, TG3_NVM_VPD_OFF + i, &buf[i/4]))
- goto out;
- }
+ kfree(buf);
+
+ buf = tg3_vpd_readblock(tp);
+ if (!buf)
+ return -ENOMEM;
i = pci_vpd_find_tag((u8 *)buf, 0, TG3_NVM_VPD_LEN,
PCI_VPD_LRDT_RO_DATA);
@@ -10714,9 +10786,9 @@ static int tg3_test_registers(struct tg3 *tp)
};
is_5705 = is_5750 = 0;
- if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+ if (tg3_flag(tp, 5705_PLUS)) {
is_5705 = 1;
- if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
+ if (tg3_flag(tp, 5750_PLUS))
is_5750 = 1;
}
@@ -10727,7 +10799,7 @@ static int tg3_test_registers(struct tg3 *tp)
if (!is_5705 && (reg_tbl[i].flags & TG3_FL_5705))
continue;
- if ((tp->tg3_flags2 & TG3_FLG2_IS_5788) &&
+ if (tg3_flag(tp, IS_5788) &&
(reg_tbl[i].flags & TG3_FL_NOT_5788))
continue;
@@ -10850,16 +10922,15 @@ static int tg3_test_memory(struct tg3 *tp)
int err = 0;
int i;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+ if (tg3_flag(tp, 5717_PLUS))
mem_tbl = mem_tbl_5717;
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
mem_tbl = mem_tbl_57765;
- else if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
+ else if (tg3_flag(tp, 5755_PLUS))
mem_tbl = mem_tbl_5755;
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
mem_tbl = mem_tbl_5906;
- else if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+ else if (tg3_flag(tp, 5705_PLUS))
mem_tbl = mem_tbl_5705;
else
mem_tbl = mem_tbl_570x;
@@ -10875,11 +10946,35 @@ static int tg3_test_memory(struct tg3 *tp)
#define TG3_MAC_LOOPBACK 0
#define TG3_PHY_LOOPBACK 1
+#define TG3_TSO_LOOPBACK 2
+
+#define TG3_TSO_MSS 500
+
+#define TG3_TSO_IP_HDR_LEN 20
+#define TG3_TSO_TCP_HDR_LEN 20
+#define TG3_TSO_TCP_OPT_LEN 12
+
+static const u8 tg3_tso_header[] = {
+0x08, 0x00,
+0x45, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x40, 0x00,
+0x40, 0x06, 0x00, 0x00,
+0x0a, 0x00, 0x00, 0x01,
+0x0a, 0x00, 0x00, 0x02,
+0x0d, 0x00, 0xe0, 0x00,
+0x00, 0x00, 0x01, 0x00,
+0x00, 0x00, 0x02, 0x00,
+0x80, 0x10, 0x10, 0x00,
+0x14, 0x09, 0x00, 0x00,
+0x01, 0x01, 0x08, 0x0a,
+0x11, 0x11, 0x11, 0x11,
+0x11, 0x11, 0x11, 0x11,
+};
-static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
+static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode)
{
u32 mac_mode, rx_start_idx, rx_idx, tx_idx, opaque_key;
- u32 desc_idx, coal_now;
+ u32 base_flags = 0, mss = 0, desc_idx, coal_now, data_off, val;
struct sk_buff *skb, *rx_skb;
u8 *tx_data;
dma_addr_t map;
@@ -10891,9 +10986,9 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
tnapi = &tp->napi[0];
rnapi = &tp->napi[0];
if (tp->irq_cnt > 1) {
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)
+ if (tg3_flag(tp, ENABLE_RSS))
rnapi = &tp->napi[1];
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+ if (tg3_flag(tp, ENABLE_TSS))
tnapi = &tp->napi[1];
}
coal_now = tnapi->coal_now | rnapi->coal_now;
@@ -10905,22 +11000,20 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
* all newer ASIC revisions.
*/
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
- (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT))
+ tg3_flag(tp, CPMU_PRESENT))
return 0;
mac_mode = tp->mac_mode &
~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX);
mac_mode |= MAC_MODE_PORT_INT_LPBACK;
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+ if (!tg3_flag(tp, 5705_PLUS))
mac_mode |= MAC_MODE_LINK_POLARITY;
if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
mac_mode |= MAC_MODE_PORT_MODE_MII;
else
mac_mode |= MAC_MODE_PORT_MODE_GMII;
tw32(MAC_MODE, mac_mode);
- } else if (loopback_mode == TG3_PHY_LOOPBACK) {
- u32 val;
-
+ } else {
if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
tg3_phy_fet_toggle_apd(tp, false);
val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED100;
@@ -10968,13 +11061,11 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
break;
mdelay(1);
}
- } else {
- return -EINVAL;
}
err = -EIO;
- tx_len = 1514;
+ tx_len = pktsz;
skb = netdev_alloc_skb(tp->dev, tx_len);
if (!skb)
return -ENOMEM;
@@ -10983,9 +11074,58 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
memcpy(tx_data, tp->dev->dev_addr, 6);
memset(tx_data + 6, 0x0, 8);
- tw32(MAC_RX_MTU_SIZE, tx_len + 4);
+ tw32(MAC_RX_MTU_SIZE, tx_len + ETH_FCS_LEN);
+
+ if (loopback_mode == TG3_TSO_LOOPBACK) {
+ struct iphdr *iph = (struct iphdr *)&tx_data[ETH_HLEN];
+
+ u32 hdr_len = TG3_TSO_IP_HDR_LEN + TG3_TSO_TCP_HDR_LEN +
+ TG3_TSO_TCP_OPT_LEN;
+
+ memcpy(tx_data + ETH_ALEN * 2, tg3_tso_header,
+ sizeof(tg3_tso_header));
+ mss = TG3_TSO_MSS;
+
+ val = tx_len - ETH_ALEN * 2 - sizeof(tg3_tso_header);
+ num_pkts = DIV_ROUND_UP(val, TG3_TSO_MSS);
+
+ /* Set the total length field in the IP header */
+ iph->tot_len = htons((u16)(mss + hdr_len));
+
+ base_flags = (TXD_FLAG_CPU_PRE_DMA |
+ TXD_FLAG_CPU_POST_DMA);
+
+ if (tg3_flag(tp, HW_TSO_1) ||
+ tg3_flag(tp, HW_TSO_2) ||
+ tg3_flag(tp, HW_TSO_3)) {
+ struct tcphdr *th;
+ val = ETH_HLEN + TG3_TSO_IP_HDR_LEN;
+ th = (struct tcphdr *)&tx_data[val];
+ th->check = 0;
+ } else
+ base_flags |= TXD_FLAG_TCPUDP_CSUM;
+
+ if (tg3_flag(tp, HW_TSO_3)) {
+ mss |= (hdr_len & 0xc) << 12;
+ if (hdr_len & 0x10)
+ base_flags |= 0x00000010;
+ base_flags |= (hdr_len & 0x3e0) << 5;
+ } else if (tg3_flag(tp, HW_TSO_2))
+ mss |= hdr_len << 9;
+ else if (tg3_flag(tp, HW_TSO_1) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
+ mss |= (TG3_TSO_TCP_OPT_LEN << 9);
+ } else {
+ base_flags |= (TG3_TSO_TCP_OPT_LEN << 10);
+ }
+
+ data_off = ETH_ALEN * 2 + sizeof(tg3_tso_header);
+ } else {
+ num_pkts = 1;
+ data_off = ETH_HLEN;
+ }
- for (i = 14; i < tx_len; i++)
+ for (i = data_off; i < tx_len; i++)
tx_data[i] = (u8) (i & 0xff);
map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE);
@@ -11001,12 +11141,10 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
rx_start_idx = rnapi->hw_status->idx[0].rx_producer;
- num_pkts = 0;
-
- tg3_set_txd(tnapi, tnapi->tx_prod, map, tx_len, 0, 1);
+ tg3_set_txd(tnapi, tnapi->tx_prod, map, tx_len,
+ base_flags, (mss << 1) | 1);
tnapi->tx_prod++;
- num_pkts++;
tw32_tx_mbox(tnapi->prodmbox, tnapi->tx_prod);
tr32_mailbox(tnapi->prodmbox);
@@ -11036,29 +11174,56 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
if (rx_idx != rx_start_idx + num_pkts)
goto out;
- desc = &rnapi->rx_rcb[rx_start_idx];
- desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
- opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
- if (opaque_key != RXD_OPAQUE_RING_STD)
- goto out;
+ val = data_off;
+ while (rx_idx != rx_start_idx) {
+ desc = &rnapi->rx_rcb[rx_start_idx++];
+ desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
+ opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
- if ((desc->err_vlan & RXD_ERR_MASK) != 0 &&
- (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII))
- goto out;
+ if ((desc->err_vlan & RXD_ERR_MASK) != 0 &&
+ (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII))
+ goto out;
- rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4;
- if (rx_len != tx_len)
- goto out;
+ rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT)
+ - ETH_FCS_LEN;
- rx_skb = tpr->rx_std_buffers[desc_idx].skb;
+ if (loopback_mode != TG3_TSO_LOOPBACK) {
+ if (rx_len != tx_len)
+ goto out;
- map = dma_unmap_addr(&tpr->rx_std_buffers[desc_idx], mapping);
- pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, PCI_DMA_FROMDEVICE);
+ if (pktsz <= TG3_RX_STD_DMA_SZ - ETH_FCS_LEN) {
+ if (opaque_key != RXD_OPAQUE_RING_STD)
+ goto out;
+ } else {
+ if (opaque_key != RXD_OPAQUE_RING_JUMBO)
+ goto out;
+ }
+ } else if ((desc->type_flags & RXD_FLAG_TCPUDP_CSUM) &&
+ (desc->ip_tcp_csum & RXD_TCPCSUM_MASK)
+ >> RXD_TCPCSUM_SHIFT != 0xffff) {
+ goto out;
+ }
- for (i = 14; i < tx_len; i++) {
- if (*(rx_skb->data + i) != (u8) (i & 0xff))
+ if (opaque_key == RXD_OPAQUE_RING_STD) {
+ rx_skb = tpr->rx_std_buffers[desc_idx].skb;
+ map = dma_unmap_addr(&tpr->rx_std_buffers[desc_idx],
+ mapping);
+ } else if (opaque_key == RXD_OPAQUE_RING_JUMBO) {
+ rx_skb = tpr->rx_jmb_buffers[desc_idx].skb;
+ map = dma_unmap_addr(&tpr->rx_jmb_buffers[desc_idx],
+ mapping);
+ } else
goto out;
+
+ pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len,
+ PCI_DMA_FROMDEVICE);
+
+ for (i = data_off; i < rx_len; i++, val++) {
+ if (*(rx_skb->data + i) != (u8) (val & 0xff))
+ goto out;
+ }
}
+
err = 0;
/* tg3_free_rings will unmap and free the rx_skb */
@@ -11066,10 +11231,13 @@ out:
return err;
}
-#define TG3_MAC_LOOPBACK_FAILED 1
-#define TG3_PHY_LOOPBACK_FAILED 2
-#define TG3_LOOPBACK_FAILED (TG3_MAC_LOOPBACK_FAILED | \
- TG3_PHY_LOOPBACK_FAILED)
+#define TG3_STD_LOOPBACK_FAILED 1
+#define TG3_JMB_LOOPBACK_FAILED 2
+#define TG3_TSO_LOOPBACK_FAILED 4
+
+#define TG3_MAC_LOOPBACK_SHIFT 0
+#define TG3_PHY_LOOPBACK_SHIFT 4
+#define TG3_LOOPBACK_FAILED 0x00000077
static int tg3_test_loopback(struct tg3 *tp)
{
@@ -11088,11 +11256,20 @@ static int tg3_test_loopback(struct tg3 *tp)
goto done;
}
+ if (tg3_flag(tp, ENABLE_RSS)) {
+ int i;
+
+ /* Reroute all rx packets to the 1st queue */
+ for (i = MAC_RSS_INDIR_TBL_0;
+ i < MAC_RSS_INDIR_TBL_0 + TG3_RSS_INDIR_TBL_SIZE; i += 4)
+ tw32(i, 0x0);
+ }
+
/* Turn off gphy autopowerdown. */
if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD)
tg3_phy_toggle_apd(tp, false);
- if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) {
+ if (tg3_flag(tp, CPMU_PRESENT)) {
int i;
u32 status;
@@ -11118,10 +11295,14 @@ static int tg3_test_loopback(struct tg3 *tp)
CPMU_CTRL_LINK_AWARE_MODE));
}
- if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK))
- err |= TG3_MAC_LOOPBACK_FAILED;
+ if (tg3_run_loopback(tp, ETH_FRAME_LEN, TG3_MAC_LOOPBACK))
+ err |= TG3_STD_LOOPBACK_FAILED << TG3_MAC_LOOPBACK_SHIFT;
- if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) {
+ if (tg3_flag(tp, JUMBO_RING_ENABLE) &&
+ tg3_run_loopback(tp, 9000 + ETH_HLEN, TG3_MAC_LOOPBACK))
+ err |= TG3_JMB_LOOPBACK_FAILED << TG3_MAC_LOOPBACK_SHIFT;
+
+ if (tg3_flag(tp, CPMU_PRESENT)) {
tw32(TG3_CPMU_CTRL, cpmuctrl);
/* Release the mutex */
@@ -11129,9 +11310,18 @@ static int tg3_test_loopback(struct tg3 *tp)
}
if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
- !(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
- if (tg3_run_loopback(tp, TG3_PHY_LOOPBACK))
- err |= TG3_PHY_LOOPBACK_FAILED;
+ !tg3_flag(tp, USE_PHYLIB)) {
+ if (tg3_run_loopback(tp, ETH_FRAME_LEN, TG3_PHY_LOOPBACK))
+ err |= TG3_STD_LOOPBACK_FAILED <<
+ TG3_PHY_LOOPBACK_SHIFT;
+ if (tg3_flag(tp, TSO_CAPABLE) &&
+ tg3_run_loopback(tp, ETH_FRAME_LEN, TG3_TSO_LOOPBACK))
+ err |= TG3_TSO_LOOPBACK_FAILED <<
+ TG3_PHY_LOOPBACK_SHIFT;
+ if (tg3_flag(tp, JUMBO_RING_ENABLE) &&
+ tg3_run_loopback(tp, 9000 + ETH_HLEN, TG3_PHY_LOOPBACK))
+ err |= TG3_JMB_LOOPBACK_FAILED <<
+ TG3_PHY_LOOPBACK_SHIFT;
}
/* Re-enable gphy autopowerdown. */
@@ -11176,7 +11366,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
tg3_halt(tp, RESET_KIND_SUSPEND, 1);
err = tg3_nvram_lock(tp);
tg3_halt_cpu(tp, RX_CPU_BASE);
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+ if (!tg3_flag(tp, 5705_PLUS))
tg3_halt_cpu(tp, TX_CPU_BASE);
if (!err)
tg3_nvram_unlock(tp);
@@ -11206,7 +11396,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
if (netif_running(dev)) {
- tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
+ tg3_flag_set(tp, INIT_COMPLETE);
err2 = tg3_restart_hw(tp, 1);
if (!err2)
tg3_netif_start(tp);
@@ -11228,7 +11418,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
struct tg3 *tp = netdev_priv(dev);
int err;
- if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ if (tg3_flag(tp, USE_PHYLIB)) {
struct phy_device *phydev;
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
return -EAGAIN;
@@ -11247,9 +11437,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
break; /* We have no PHY */
- if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) ||
- ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
- !netif_running(dev)))
+ if (!netif_running(dev))
return -EAGAIN;
spin_lock_bh(&tp->lock);
@@ -11265,9 +11453,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
break; /* We have no PHY */
- if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) ||
- ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
- !netif_running(dev)))
+ if (!netif_running(dev))
return -EAGAIN;
spin_lock_bh(&tp->lock);
@@ -11297,7 +11483,7 @@ static int tg3_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
u32 max_rxcoal_tick_int = 0, max_txcoal_tick_int = 0;
u32 max_stat_coal_ticks = 0, min_stat_coal_ticks = 0;
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+ if (!tg3_flag(tp, 5705_PLUS)) {
max_rxcoal_tick_int = MAX_RXCOAL_TICK_INT;
max_txcoal_tick_int = MAX_TXCOAL_TICK_INT;
max_stat_coal_ticks = MAX_STAT_COAL_TICKS;
@@ -11364,14 +11550,9 @@ static const struct ethtool_ops tg3_ethtool_ops = {
.set_ringparam = tg3_set_ringparam,
.get_pauseparam = tg3_get_pauseparam,
.set_pauseparam = tg3_set_pauseparam,
- .get_rx_csum = tg3_get_rx_csum,
- .set_rx_csum = tg3_set_rx_csum,
- .set_tx_csum = tg3_set_tx_csum,
- .set_sg = ethtool_op_set_sg,
- .set_tso = tg3_set_tso,
.self_test = tg3_self_test,
.get_strings = tg3_get_strings,
- .phys_id = tg3_phys_id,
+ .set_phys_id = tg3_set_phys_id,
.get_ethtool_stats = tg3_get_ethtool_stats,
.get_coalesce = tg3_get_coalesce,
.set_coalesce = tg3_set_coalesce,
@@ -11416,8 +11597,7 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp)
{
u32 val;
- if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
- tg3_nvram_read(tp, 0, &val) != 0)
+ if (tg3_flag(tp, NO_NVRAM) || tg3_nvram_read(tp, 0, &val) != 0)
return;
/* Selfboot format */
@@ -11452,19 +11632,19 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp)
nvcfg1 = tr32(NVRAM_CFG1);
if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) {
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tg3_flag_set(tp, FLASH);
} else {
nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
tw32(NVRAM_CFG1, nvcfg1);
}
- if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) ||
- (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
+ tg3_flag(tp, 5780_CLASS)) {
switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) {
case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
tp->nvram_jedecnum = JEDEC_ATMEL;
tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
break;
case FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED:
tp->nvram_jedecnum = JEDEC_ATMEL;
@@ -11473,12 +11653,12 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp)
case FLASH_VENDOR_ATMEL_EEPROM:
tp->nvram_jedecnum = JEDEC_ATMEL;
tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
break;
case FLASH_VENDOR_ST:
tp->nvram_jedecnum = JEDEC_ST;
tp->nvram_pagesize = ST_M45PEX0_PAGE_SIZE;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
break;
case FLASH_VENDOR_SAIFUN:
tp->nvram_jedecnum = JEDEC_SAIFUN;
@@ -11493,7 +11673,7 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp)
} else {
tp->nvram_jedecnum = JEDEC_ATMEL;
tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
}
}
@@ -11532,29 +11712,29 @@ static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp)
/* NVRAM protection for TPM */
if (nvcfg1 & (1 << 27))
- tp->tg3_flags3 |= TG3_FLG3_PROTECTED_NVRAM;
+ tg3_flag_set(tp, PROTECTED_NVRAM);
switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
case FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ:
case FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ:
tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
break;
case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
+ tg3_flag_set(tp, FLASH);
break;
case FLASH_5752VENDOR_ST_M45PE10:
case FLASH_5752VENDOR_ST_M45PE20:
case FLASH_5752VENDOR_ST_M45PE40:
tp->nvram_jedecnum = JEDEC_ST;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
+ tg3_flag_set(tp, FLASH);
break;
}
- if (tp->tg3_flags2 & TG3_FLG2_FLASH) {
+ if (tg3_flag(tp, FLASH)) {
tg3_nvram_get_pagesize(tp, nvcfg1);
} else {
/* For eeprom, set pagesize to maximum eeprom size */
@@ -11573,7 +11753,7 @@ static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp)
/* NVRAM protection for TPM */
if (nvcfg1 & (1 << 27)) {
- tp->tg3_flags3 |= TG3_FLG3_PROTECTED_NVRAM;
+ tg3_flag_set(tp, PROTECTED_NVRAM);
protect = 1;
}
@@ -11584,8 +11764,8 @@ static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp)
case FLASH_5755VENDOR_ATMEL_FLASH_3:
case FLASH_5755VENDOR_ATMEL_FLASH_5:
tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
+ tg3_flag_set(tp, FLASH);
tp->nvram_pagesize = 264;
if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 ||
nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5)
@@ -11602,8 +11782,8 @@ static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp)
case FLASH_5752VENDOR_ST_M45PE20:
case FLASH_5752VENDOR_ST_M45PE40:
tp->nvram_jedecnum = JEDEC_ST;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
+ tg3_flag_set(tp, FLASH);
tp->nvram_pagesize = 256;
if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10)
tp->nvram_size = (protect ?
@@ -11633,7 +11813,7 @@ static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp)
case FLASH_5787VENDOR_MICRO_EEPROM_64KHZ:
case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
@@ -11644,16 +11824,16 @@ static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp)
case FLASH_5755VENDOR_ATMEL_FLASH_2:
case FLASH_5755VENDOR_ATMEL_FLASH_3:
tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
+ tg3_flag_set(tp, FLASH);
tp->nvram_pagesize = 264;
break;
case FLASH_5752VENDOR_ST_M45PE10:
case FLASH_5752VENDOR_ST_M45PE20:
case FLASH_5752VENDOR_ST_M45PE40:
tp->nvram_jedecnum = JEDEC_ST;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
+ tg3_flag_set(tp, FLASH);
tp->nvram_pagesize = 256;
break;
}
@@ -11667,7 +11847,7 @@ static void __devinit tg3_get_5761_nvram_info(struct tg3 *tp)
/* NVRAM protection for TPM */
if (nvcfg1 & (1 << 27)) {
- tp->tg3_flags3 |= TG3_FLG3_PROTECTED_NVRAM;
+ tg3_flag_set(tp, PROTECTED_NVRAM);
protect = 1;
}
@@ -11682,9 +11862,9 @@ static void __devinit tg3_get_5761_nvram_info(struct tg3 *tp)
case FLASH_5761VENDOR_ATMEL_MDB081D:
case FLASH_5761VENDOR_ATMEL_MDB161D:
tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
- tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
+ tg3_flag_set(tp, FLASH);
+ tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
tp->nvram_pagesize = 256;
break;
case FLASH_5761VENDOR_ST_A_M45PE20:
@@ -11696,8 +11876,8 @@ static void __devinit tg3_get_5761_nvram_info(struct tg3 *tp)
case FLASH_5761VENDOR_ST_M_M45PE80:
case FLASH_5761VENDOR_ST_M_M45PE16:
tp->nvram_jedecnum = JEDEC_ST;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
+ tg3_flag_set(tp, FLASH);
tp->nvram_pagesize = 256;
break;
}
@@ -11737,7 +11917,7 @@ static void __devinit tg3_get_5761_nvram_info(struct tg3 *tp)
static void __devinit tg3_get_5906_nvram_info(struct tg3 *tp)
{
tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
}
@@ -11751,7 +11931,7 @@ static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp)
case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ:
case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
@@ -11765,8 +11945,8 @@ static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp)
case FLASH_57780VENDOR_ATMEL_AT45DB041D:
case FLASH_57780VENDOR_ATMEL_AT45DB041B:
tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
+ tg3_flag_set(tp, FLASH);
switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
@@ -11788,8 +11968,8 @@ static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp)
case FLASH_5752VENDOR_ST_M45PE20:
case FLASH_5752VENDOR_ST_M45PE40:
tp->nvram_jedecnum = JEDEC_ST;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
+ tg3_flag_set(tp, FLASH);
switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
case FLASH_5752VENDOR_ST_M45PE10:
@@ -11804,13 +11984,13 @@ static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp)
}
break;
default:
- tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM;
+ tg3_flag_set(tp, NO_NVRAM);
return;
}
tg3_nvram_get_pagesize(tp, nvcfg1);
if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
- tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+ tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
}
@@ -11824,7 +12004,7 @@ static void __devinit tg3_get_5717_nvram_info(struct tg3 *tp)
case FLASH_5717VENDOR_ATMEL_EEPROM:
case FLASH_5717VENDOR_MICRO_EEPROM:
tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
@@ -11838,11 +12018,13 @@ static void __devinit tg3_get_5717_nvram_info(struct tg3 *tp)
case FLASH_5717VENDOR_ATMEL_ADB021D:
case FLASH_5717VENDOR_ATMEL_45USPT:
tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
+ tg3_flag_set(tp, FLASH);
switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
case FLASH_5717VENDOR_ATMEL_MDB021D:
+ /* Detect size with tg3_nvram_get_size() */
+ break;
case FLASH_5717VENDOR_ATMEL_ADB021B:
case FLASH_5717VENDOR_ATMEL_ADB021D:
tp->nvram_size = TG3_NVRAM_SIZE_256KB;
@@ -11863,13 +12045,15 @@ static void __devinit tg3_get_5717_nvram_info(struct tg3 *tp)
case FLASH_5717VENDOR_ST_25USPT:
case FLASH_5717VENDOR_ST_45USPT:
tp->nvram_jedecnum = JEDEC_ST;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
+ tg3_flag_set(tp, FLASH);
switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
case FLASH_5717VENDOR_ST_M_M25PE20:
- case FLASH_5717VENDOR_ST_A_M25PE20:
case FLASH_5717VENDOR_ST_M_M45PE20:
+ /* Detect size with tg3_nvram_get_size() */
+ break;
+ case FLASH_5717VENDOR_ST_A_M25PE20:
case FLASH_5717VENDOR_ST_A_M45PE20:
tp->nvram_size = TG3_NVRAM_SIZE_256KB;
break;
@@ -11879,13 +12063,125 @@ static void __devinit tg3_get_5717_nvram_info(struct tg3 *tp)
}
break;
default:
- tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM;
+ tg3_flag_set(tp, NO_NVRAM);
+ return;
+ }
+
+ tg3_nvram_get_pagesize(tp, nvcfg1);
+ if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
+ tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
+}
+
+static void __devinit tg3_get_5720_nvram_info(struct tg3 *tp)
+{
+ u32 nvcfg1, nvmpinstrp;
+
+ nvcfg1 = tr32(NVRAM_CFG1);
+ nvmpinstrp = nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK;
+
+ switch (nvmpinstrp) {
+ case FLASH_5720_EEPROM_HD:
+ case FLASH_5720_EEPROM_LD:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
+
+ nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+ tw32(NVRAM_CFG1, nvcfg1);
+ if (nvmpinstrp == FLASH_5720_EEPROM_HD)
+ tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+ else
+ tp->nvram_pagesize = ATMEL_AT24C02_CHIP_SIZE;
+ return;
+ case FLASH_5720VENDOR_M_ATMEL_DB011D:
+ case FLASH_5720VENDOR_A_ATMEL_DB011B:
+ case FLASH_5720VENDOR_A_ATMEL_DB011D:
+ case FLASH_5720VENDOR_M_ATMEL_DB021D:
+ case FLASH_5720VENDOR_A_ATMEL_DB021B:
+ case FLASH_5720VENDOR_A_ATMEL_DB021D:
+ case FLASH_5720VENDOR_M_ATMEL_DB041D:
+ case FLASH_5720VENDOR_A_ATMEL_DB041B:
+ case FLASH_5720VENDOR_A_ATMEL_DB041D:
+ case FLASH_5720VENDOR_M_ATMEL_DB081D:
+ case FLASH_5720VENDOR_A_ATMEL_DB081D:
+ case FLASH_5720VENDOR_ATMEL_45USPT:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
+ tg3_flag_set(tp, FLASH);
+
+ switch (nvmpinstrp) {
+ case FLASH_5720VENDOR_M_ATMEL_DB021D:
+ case FLASH_5720VENDOR_A_ATMEL_DB021B:
+ case FLASH_5720VENDOR_A_ATMEL_DB021D:
+ tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+ break;
+ case FLASH_5720VENDOR_M_ATMEL_DB041D:
+ case FLASH_5720VENDOR_A_ATMEL_DB041B:
+ case FLASH_5720VENDOR_A_ATMEL_DB041D:
+ tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+ break;
+ case FLASH_5720VENDOR_M_ATMEL_DB081D:
+ case FLASH_5720VENDOR_A_ATMEL_DB081D:
+ tp->nvram_size = TG3_NVRAM_SIZE_1MB;
+ break;
+ default:
+ tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+ break;
+ }
+ break;
+ case FLASH_5720VENDOR_M_ST_M25PE10:
+ case FLASH_5720VENDOR_M_ST_M45PE10:
+ case FLASH_5720VENDOR_A_ST_M25PE10:
+ case FLASH_5720VENDOR_A_ST_M45PE10:
+ case FLASH_5720VENDOR_M_ST_M25PE20:
+ case FLASH_5720VENDOR_M_ST_M45PE20:
+ case FLASH_5720VENDOR_A_ST_M25PE20:
+ case FLASH_5720VENDOR_A_ST_M45PE20:
+ case FLASH_5720VENDOR_M_ST_M25PE40:
+ case FLASH_5720VENDOR_M_ST_M45PE40:
+ case FLASH_5720VENDOR_A_ST_M25PE40:
+ case FLASH_5720VENDOR_A_ST_M45PE40:
+ case FLASH_5720VENDOR_M_ST_M25PE80:
+ case FLASH_5720VENDOR_M_ST_M45PE80:
+ case FLASH_5720VENDOR_A_ST_M25PE80:
+ case FLASH_5720VENDOR_A_ST_M45PE80:
+ case FLASH_5720VENDOR_ST_25USPT:
+ case FLASH_5720VENDOR_ST_45USPT:
+ tp->nvram_jedecnum = JEDEC_ST;
+ tg3_flag_set(tp, NVRAM_BUFFERED);
+ tg3_flag_set(tp, FLASH);
+
+ switch (nvmpinstrp) {
+ case FLASH_5720VENDOR_M_ST_M25PE20:
+ case FLASH_5720VENDOR_M_ST_M45PE20:
+ case FLASH_5720VENDOR_A_ST_M25PE20:
+ case FLASH_5720VENDOR_A_ST_M45PE20:
+ tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+ break;
+ case FLASH_5720VENDOR_M_ST_M25PE40:
+ case FLASH_5720VENDOR_M_ST_M45PE40:
+ case FLASH_5720VENDOR_A_ST_M25PE40:
+ case FLASH_5720VENDOR_A_ST_M45PE40:
+ tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+ break;
+ case FLASH_5720VENDOR_M_ST_M25PE80:
+ case FLASH_5720VENDOR_M_ST_M45PE80:
+ case FLASH_5720VENDOR_A_ST_M25PE80:
+ case FLASH_5720VENDOR_A_ST_M45PE80:
+ tp->nvram_size = TG3_NVRAM_SIZE_1MB;
+ break;
+ default:
+ tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+ break;
+ }
+ break;
+ default:
+ tg3_flag_set(tp, NO_NVRAM);
return;
}
tg3_nvram_get_pagesize(tp, nvcfg1);
if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
- tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+ tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
}
/* Chips other than 5700/5701 use the NVRAM for fetching info. */
@@ -11905,7 +12201,7 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
- tp->tg3_flags |= TG3_FLAG_NVRAM;
+ tg3_flag_set(tp, NVRAM);
if (tg3_nvram_lock(tp)) {
netdev_warn(tp->dev,
@@ -11935,6 +12231,8 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
tg3_get_5717_nvram_info(tp);
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ tg3_get_5720_nvram_info(tp);
else
tg3_get_nvram_info(tp);
@@ -11945,7 +12243,8 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
tg3_nvram_unlock(tp);
} else {
- tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED);
+ tg3_flag_clear(tp, NVRAM);
+ tg3_flag_clear(tp, NVRAM_BUFFERED);
tg3_get_eeprom_size(tp);
}
@@ -12128,7 +12427,7 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len,
nvram_cmd |= NVRAM_CMD_LAST;
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 &&
- !(tp->tg3_flags3 & TG3_FLG3_5755_PLUS) &&
+ !tg3_flag(tp, 5755_PLUS) &&
(tp->nvram_jedecnum == JEDEC_ST) &&
(nvram_cmd & NVRAM_CMD_FIRST)) {
@@ -12138,7 +12437,7 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len,
break;
}
- if (!(tp->tg3_flags2 & TG3_FLG2_FLASH)) {
+ if (!tg3_flag(tp, FLASH)) {
/* We always do complete word writes to eeprom. */
nvram_cmd |= (NVRAM_CMD_FIRST | NVRAM_CMD_LAST);
}
@@ -12154,13 +12453,13 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf)
{
int ret;
- if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) {
+ if (tg3_flag(tp, EEPROM_WRITE_PROT)) {
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl &
~GRC_LCLCTRL_GPIO_OUTPUT1);
udelay(40);
}
- if (!(tp->tg3_flags & TG3_FLAG_NVRAM)) {
+ if (!tg3_flag(tp, NVRAM)) {
ret = tg3_nvram_write_block_using_eeprom(tp, offset, len, buf);
} else {
u32 grc_mode;
@@ -12170,16 +12469,13 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf)
return ret;
tg3_enable_nvram_access(tp);
- if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
- !(tp->tg3_flags3 & TG3_FLG3_PROTECTED_NVRAM))
+ if (tg3_flag(tp, 5750_PLUS) && !tg3_flag(tp, PROTECTED_NVRAM))
tw32(NVRAM_WRITE1, 0x406);
grc_mode = tr32(GRC_MODE);
tw32(GRC_MODE, grc_mode | GRC_MODE_NVRAM_WR_ENABLE);
- if ((tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) ||
- !(tp->tg3_flags2 & TG3_FLG2_FLASH)) {
-
+ if (tg3_flag(tp, NVRAM_BUFFERED) || !tg3_flag(tp, FLASH)) {
ret = tg3_nvram_write_block_buffered(tp, offset, len,
buf);
} else {
@@ -12194,7 +12490,7 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf)
tg3_nvram_unlock(tp);
}
- if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) {
+ if (tg3_flag(tp, EEPROM_WRITE_PROT)) {
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
udelay(40);
}
@@ -12316,19 +12612,20 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
tp->led_ctrl = LED_CTRL_MODE_PHY_1;
/* Assume an onboard device and WOL capable by default. */
- tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT | TG3_FLAG_WOL_CAP;
+ tg3_flag_set(tp, EEPROM_WRITE_PROT);
+ tg3_flag_set(tp, WOL_CAP);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
if (!(tr32(PCIE_TRANSACTION_CFG) & PCIE_TRANS_CFG_LOM)) {
- tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
- tp->tg3_flags2 |= TG3_FLG2_IS_NIC;
+ tg3_flag_clear(tp, EEPROM_WRITE_PROT);
+ tg3_flag_set(tp, IS_NIC);
}
val = tr32(VCPU_CFGSHDW);
if (val & VCPU_CFGSHDW_ASPM_DBNC)
- tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND;
+ tg3_flag_set(tp, ASPM_WORKAROUND);
if ((val & VCPU_CFGSHDW_WOL_ENABLE) &&
(val & VCPU_CFGSHDW_WOL_MAGPKT)) {
- tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
+ tg3_flag_set(tp, WOL_ENABLE);
device_set_wakeup_enable(&tp->pdev->dev, true);
}
goto done;
@@ -12345,9 +12642,9 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
tg3_read_mem(tp, NIC_SRAM_DATA_VER, &ver);
ver >>= NIC_SRAM_DATA_VER_SHIFT;
- if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) &&
- (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) &&
- (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5703) &&
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5703 &&
(ver > 0) && (ver < 0x100))
tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &cfg2);
@@ -12371,13 +12668,13 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
tp->phy_id = eeprom_phy_id;
if (eeprom_phy_serdes) {
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+ if (!tg3_flag(tp, 5705_PLUS))
tp->phy_flags |= TG3_PHYFLG_PHY_SERDES;
else
tp->phy_flags |= TG3_PHYFLG_MII_SERDES;
}
- if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
+ if (tg3_flag(tp, 5750_PLUS))
led_cfg = cfg2 & (NIC_SRAM_DATA_CFG_LED_MODE_MASK |
SHASTA_EXT_LED_MODE_MASK);
else
@@ -12437,34 +12734,34 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
tp->led_ctrl = LED_CTRL_MODE_PHY_1;
if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) {
- tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
+ tg3_flag_set(tp, EEPROM_WRITE_PROT);
if ((tp->pdev->subsystem_vendor ==
PCI_VENDOR_ID_ARIMA) &&
(tp->pdev->subsystem_device == 0x205a ||
tp->pdev->subsystem_device == 0x2063))
- tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
+ tg3_flag_clear(tp, EEPROM_WRITE_PROT);
} else {
- tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
- tp->tg3_flags2 |= TG3_FLG2_IS_NIC;
+ tg3_flag_clear(tp, EEPROM_WRITE_PROT);
+ tg3_flag_set(tp, IS_NIC);
}
if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
- tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
- if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
- tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE;
+ tg3_flag_set(tp, ENABLE_ASF);
+ if (tg3_flag(tp, 5750_PLUS))
+ tg3_flag_set(tp, ASF_NEW_HANDSHAKE);
}
if ((nic_cfg & NIC_SRAM_DATA_CFG_APE_ENABLE) &&
- (tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
- tp->tg3_flags3 |= TG3_FLG3_ENABLE_APE;
+ tg3_flag(tp, 5750_PLUS))
+ tg3_flag_set(tp, ENABLE_APE);
if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES &&
!(nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL))
- tp->tg3_flags &= ~TG3_FLAG_WOL_CAP;
+ tg3_flag_clear(tp, WOL_CAP);
- if ((tp->tg3_flags & TG3_FLAG_WOL_CAP) &&
+ if (tg3_flag(tp, WOL_CAP) &&
(nic_cfg & NIC_SRAM_DATA_CFG_WOL_ENABLE)) {
- tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
+ tg3_flag_set(tp, WOL_ENABLE);
device_set_wakeup_enable(&tp->pdev->dev, true);
}
@@ -12476,33 +12773,33 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
if (cfg2 & (1 << 18))
tp->phy_flags |= TG3_PHYFLG_SERDES_PREEMPHASIS;
- if (((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) ||
- ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
- GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX))) &&
+ if ((tg3_flag(tp, 57765_PLUS) ||
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
+ GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX)) &&
(cfg2 & NIC_SRAM_DATA_CFG_2_APD_EN))
tp->phy_flags |= TG3_PHYFLG_ENABLE_APD;
- if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
+ if (tg3_flag(tp, PCI_EXPRESS) &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
- !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) {
+ !tg3_flag(tp, 57765_PLUS)) {
u32 cfg3;
tg3_read_mem(tp, NIC_SRAM_DATA_CFG_3, &cfg3);
if (cfg3 & NIC_SRAM_ASPM_DEBOUNCE)
- tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND;
+ tg3_flag_set(tp, ASPM_WORKAROUND);
}
if (cfg4 & NIC_SRAM_RGMII_INBAND_DISABLE)
- tp->tg3_flags3 |= TG3_FLG3_RGMII_INBAND_DISABLE;
+ tg3_flag_set(tp, RGMII_INBAND_DISABLE);
if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_RX_EN)
- tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_RX_EN;
+ tg3_flag_set(tp, RGMII_EXT_IBND_RX_EN);
if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_TX_EN)
- tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_TX_EN;
+ tg3_flag_set(tp, RGMII_EXT_IBND_TX_EN);
}
done:
- if (tp->tg3_flags & TG3_FLAG_WOL_CAP)
+ if (tg3_flag(tp, WOL_CAP))
device_set_wakeup_enable(&tp->pdev->dev,
- tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
+ tg3_flag(tp, WOL_ENABLE));
else
device_set_wakeup_capable(&tp->pdev->dev, false);
}
@@ -12592,18 +12889,17 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
int err;
/* flow control autonegotiation is default behavior */
- tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
+ tg3_flag_set(tp, PAUSE_AUTONEG);
tp->link_config.flowctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
- if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
+ if (tg3_flag(tp, USE_PHYLIB))
return tg3_phy_init(tp);
/* Reading the PHY ID register can conflict with ASF
* firmware access to the PHY hardware.
*/
err = 0;
- if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
- (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
+ if (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE)) {
hw_phy_id = hw_phy_id_masked = TG3_PHY_ID_INVALID;
} else {
/* Now read the physical PHY_ID from the chip and verify
@@ -12659,9 +12955,9 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
tg3_phy_init_link_config(tp);
if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) &&
- !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) &&
- !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
- u32 bmsr, adv_reg, tg3_ctrl, mask;
+ !tg3_flag(tp, ENABLE_APE) &&
+ !tg3_flag(tp, ENABLE_ASF)) {
+ u32 bmsr, mask;
tg3_readphy(tp, MII_BMSR, &bmsr);
if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
@@ -12672,36 +12968,18 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
if (err)
return err;
- adv_reg = (ADVERTISE_10HALF | ADVERTISE_10FULL |
- ADVERTISE_100HALF | ADVERTISE_100FULL |
- ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
- tg3_ctrl = 0;
- if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) {
- tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF |
- MII_TG3_CTRL_ADV_1000_FULL);
- if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
- tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)
- tg3_ctrl |= (MII_TG3_CTRL_AS_MASTER |
- MII_TG3_CTRL_ENABLE_AS_MASTER);
- }
+ tg3_phy_set_wirespeed(tp);
mask = (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full);
if (!tg3_copper_is_advertising_all(tp, mask)) {
- tg3_writephy(tp, MII_ADVERTISE, adv_reg);
-
- if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY))
- tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl);
+ tg3_phy_autoneg_cfg(tp, tp->link_config.advertising,
+ tp->link_config.flowctrl);
tg3_writephy(tp, MII_BMCR,
BMCR_ANENABLE | BMCR_ANRESTART);
}
- tg3_phy_set_wirespeed(tp);
-
- tg3_writephy(tp, MII_ADVERTISE, adv_reg);
- if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY))
- tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl);
}
skip_phy_reset:
@@ -12721,46 +12999,11 @@ static void __devinit tg3_read_vpd(struct tg3 *tp)
u8 *vpd_data;
unsigned int block_end, rosize, len;
int j, i = 0;
- u32 magic;
- if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
- tg3_nvram_read(tp, 0x0, &magic))
- goto out_no_vpd;
-
- vpd_data = kmalloc(TG3_NVM_VPD_LEN, GFP_KERNEL);
+ vpd_data = (u8 *)tg3_vpd_readblock(tp);
if (!vpd_data)
goto out_no_vpd;
- if (magic == TG3_EEPROM_MAGIC) {
- for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) {
- u32 tmp;
-
- /* The data is in little-endian format in NVRAM.
- * Use the big-endian read routines to preserve
- * the byte order as it exists in NVRAM.
- */
- if (tg3_nvram_read_be32(tp, TG3_NVM_VPD_OFF + i, &tmp))
- goto out_not_found;
-
- memcpy(&vpd_data[i], &tmp, sizeof(tmp));
- }
- } else {
- ssize_t cnt;
- unsigned int pos = 0;
-
- for (; pos < TG3_NVM_VPD_LEN && i < 3; i++, pos += cnt) {
- cnt = pci_read_vpd(tp->pdev, pos,
- TG3_NVM_VPD_LEN - pos,
- &vpd_data[pos]);
- if (cnt == -ETIMEDOUT || cnt == -EINTR)
- cnt = 0;
- else if (cnt < 0)
- goto out_not_found;
- }
- if (pos != TG3_NVM_VPD_LEN)
- goto out_not_found;
- }
-
i = pci_vpd_find_tag(vpd_data, 0, TG3_NVM_VPD_LEN,
PCI_VPD_LRDT_RO_DATA);
if (i < 0)
@@ -13014,7 +13257,7 @@ static void __devinit tg3_read_mgmtfw_ver(struct tg3 *tp)
if (offset == TG3_NVM_DIR_END)
return;
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+ if (!tg3_flag(tp, 5705_PLUS))
start = 0x08000000;
else if (tg3_nvram_read(tp, offset - 4, &start))
return;
@@ -13054,8 +13297,7 @@ static void __devinit tg3_read_dash_ver(struct tg3 *tp)
u32 apedata;
char *fwtype;
- if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) ||
- !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+ if (!tg3_flag(tp, ENABLE_APE) || !tg3_flag(tp, ENABLE_ASF))
return;
apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
@@ -13069,7 +13311,7 @@ static void __devinit tg3_read_dash_ver(struct tg3 *tp)
apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION);
if (tg3_ape_read32(tp, TG3_APE_FW_FEATURES) & TG3_APE_FW_FEATURE_NCSI) {
- tp->tg3_flags3 |= TG3_FLG3_APE_HAS_NCSI;
+ tg3_flag_set(tp, APE_HAS_NCSI);
fwtype = "NCSI";
} else {
fwtype = "DASH";
@@ -13093,7 +13335,7 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
if (tp->fw_ver[0] != 0)
vpd_vers = true;
- if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) {
+ if (tg3_flag(tp, NO_NVRAM)) {
strcat(tp->fw_ver, "sb");
return;
}
@@ -13110,8 +13352,7 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
else
return;
- if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
- (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) || vpd_vers)
+ if (!tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE) || vpd_vers)
goto done;
tg3_read_mgmtfw_ver(tp);
@@ -13122,21 +13363,14 @@ done:
static struct pci_dev * __devinit tg3_find_peer(struct tg3 *);
-static inline void vlan_features_add(struct net_device *dev, unsigned long flags)
-{
- dev->vlan_features |= flags;
-}
-
static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp)
{
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
- return 4096;
- else if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
- !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
- return 1024;
+ if (tg3_flag(tp, LRG_PROD_RING_CAP))
+ return TG3_RX_RET_MAX_SIZE_5717;
+ else if (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS))
+ return TG3_RX_RET_MAX_SIZE_5700;
else
- return 512;
+ return TG3_RX_RET_MAX_SIZE_5705;
}
static DEFINE_PCI_DEVICE_TABLE(tg3_write_reorder_chipsets) = {
@@ -13181,7 +13415,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719)
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720)
pci_read_config_dword(tp->pdev,
TG3PCI_GEN2_PRODID_ASICREV,
&prod_id_asic_rev);
@@ -13258,15 +13493,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (bridge->subordinate &&
(bridge->subordinate->number ==
tp->pdev->bus->number)) {
-
- tp->tg3_flags2 |= TG3_FLG2_ICH_WORKAROUND;
+ tg3_flag_set(tp, ICH_WORKAROUND);
pci_dev_put(bridge);
break;
}
}
}
- if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
static struct tg3_dev_id {
u32 vendor;
u32 device;
@@ -13291,7 +13525,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->pdev->bus->number) &&
(bridge->subordinate->subordinate >=
tp->pdev->bus->number)) {
- tp->tg3_flags3 |= TG3_FLG3_5701_DMA_BUG;
+ tg3_flag_set(tp, 5701_DMA_BUG);
pci_dev_put(bridge);
break;
}
@@ -13306,8 +13540,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
*/
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
- tp->tg3_flags2 |= TG3_FLG2_5780_CLASS;
- tp->tg3_flags |= TG3_FLAG_40BIT_DMA_BUG;
+ tg3_flag_set(tp, 5780_CLASS);
+ tg3_flag_set(tp, 40BIT_DMA_BUG);
tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
} else {
struct pci_dev *bridge = NULL;
@@ -13321,7 +13555,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->pdev->bus->number) &&
(bridge->subordinate->subordinate >=
tp->pdev->bus->number)) {
- tp->tg3_flags |= TG3_FLAG_40BIT_DMA_BUG;
+ tg3_flag_set(tp, 40BIT_DMA_BUG);
pci_dev_put(bridge);
break;
}
@@ -13336,13 +13570,18 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
tp->pdev_peer = tg3_find_peer(tp);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
- tp->tg3_flags3 |= TG3_FLG3_5717_PLUS;
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ tg3_flag_set(tp, 5717_PLUS);
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 ||
+ tg3_flag(tp, 5717_PLUS))
+ tg3_flag_set(tp, 57765_PLUS);
/* Intentionally exclude ASIC_REV_5906 */
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
@@ -13351,97 +13590,102 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
- (tp->tg3_flags3 & TG3_FLG3_5717_PLUS))
- tp->tg3_flags3 |= TG3_FLG3_5755_PLUS;
+ tg3_flag(tp, 57765_PLUS))
+ tg3_flag_set(tp, 5755_PLUS);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 ||
- (tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
- (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
- tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
-
- if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) ||
- (tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
- tp->tg3_flags2 |= TG3_FLG2_5705_PLUS;
-
- /* 5700 B0 chips do not support checksumming correctly due
- * to hardware bugs.
- */
- if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0)
- tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS;
- else {
- unsigned long features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_GRO;
+ tg3_flag(tp, 5755_PLUS) ||
+ tg3_flag(tp, 5780_CLASS))
+ tg3_flag_set(tp, 5750_PLUS);
- tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
- if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
- features |= NETIF_F_IPV6_CSUM;
- tp->dev->features |= features;
- vlan_features_add(tp->dev, features);
- }
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 ||
+ tg3_flag(tp, 5750_PLUS))
+ tg3_flag_set(tp, 5705_PLUS);
/* Determine TSO capabilities */
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
; /* Do nothing. HW bug. */
- else if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
- tp->tg3_flags2 |= TG3_FLG2_HW_TSO_3;
- else if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
+ else if (tg3_flag(tp, 57765_PLUS))
+ tg3_flag_set(tp, HW_TSO_3);
+ else if (tg3_flag(tp, 5755_PLUS) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
- tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
- else if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
- tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 | TG3_FLG2_TSO_BUG;
+ tg3_flag_set(tp, HW_TSO_2);
+ else if (tg3_flag(tp, 5750_PLUS)) {
+ tg3_flag_set(tp, HW_TSO_1);
+ tg3_flag_set(tp, TSO_BUG);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 &&
tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2)
- tp->tg3_flags2 &= ~TG3_FLG2_TSO_BUG;
+ tg3_flag_clear(tp, TSO_BUG);
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 &&
tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) {
- tp->tg3_flags2 |= TG3_FLG2_TSO_BUG;
+ tg3_flag_set(tp, TSO_BUG);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
tp->fw_needed = FIRMWARE_TG3TSO5;
else
tp->fw_needed = FIRMWARE_TG3TSO;
}
+ /* Selectively allow TSO based on operating conditions */
+ if (tg3_flag(tp, HW_TSO_1) ||
+ tg3_flag(tp, HW_TSO_2) ||
+ tg3_flag(tp, HW_TSO_3) ||
+ (tp->fw_needed && !tg3_flag(tp, ENABLE_ASF)))
+ tg3_flag_set(tp, TSO_CAPABLE);
+ else {
+ tg3_flag_clear(tp, TSO_CAPABLE);
+ tg3_flag_clear(tp, TSO_BUG);
+ tp->fw_needed = NULL;
+ }
+
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
+ tp->fw_needed = FIRMWARE_TG3;
+
tp->irq_max = 1;
- if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
- tp->tg3_flags |= TG3_FLAG_SUPPORT_MSI;
+ if (tg3_flag(tp, 5750_PLUS)) {
+ tg3_flag_set(tp, SUPPORT_MSI);
if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX ||
GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_BX ||
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 &&
tp->pci_chip_rev_id <= CHIPREV_ID_5714_A2 &&
tp->pdev_peer == tp->pdev))
- tp->tg3_flags &= ~TG3_FLAG_SUPPORT_MSI;
+ tg3_flag_clear(tp, SUPPORT_MSI);
- if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
+ if (tg3_flag(tp, 5755_PLUS) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
- tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
+ tg3_flag_set(tp, 1SHOT_MSI);
}
- if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
- tp->tg3_flags |= TG3_FLAG_SUPPORT_MSIX;
+ if (tg3_flag(tp, 57765_PLUS)) {
+ tg3_flag_set(tp, SUPPORT_MSIX);
tp->irq_max = TG3_IRQ_MAX_VECS;
}
}
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
- tp->tg3_flags3 |= TG3_FLG3_SHORT_DMA_BUG;
- else if (!(tp->tg3_flags3 & TG3_FLG3_5755_PLUS)) {
- tp->tg3_flags3 |= TG3_FLG3_4G_DMA_BNDRY_BUG;
- tp->tg3_flags3 |= TG3_FLG3_40BIT_DMA_LIMIT_BUG;
- }
+ /* All chips can get confused if TX buffers
+ * straddle the 4GB address boundary.
+ */
+ tg3_flag_set(tp, 4G_DMA_BNDRY_BUG);
+
+ if (tg3_flag(tp, 5755_PLUS))
+ tg3_flag_set(tp, SHORT_DMA_BUG);
+ else
+ tg3_flag_set(tp, 40BIT_DMA_LIMIT_BUG);
- if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
+ if (tg3_flag(tp, 5717_PLUS))
+ tg3_flag_set(tp, LRG_PROD_RING_CAP);
+
+ if (tg3_flag(tp, 57765_PLUS) &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719)
- tp->tg3_flags3 |= TG3_FLG3_USE_JUMBO_BDFLAG;
+ tg3_flag_set(tp, USE_JUMBO_BDFLAG);
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
- (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
- (tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG))
- tp->tg3_flags |= TG3_FLAG_JUMBO_CAPABLE;
+ if (!tg3_flag(tp, 5705_PLUS) ||
+ tg3_flag(tp, 5780_CLASS) ||
+ tg3_flag(tp, USE_JUMBO_BDFLAG))
+ tg3_flag_set(tp, JUMBO_CAPABLE);
pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
&pci_state_reg);
@@ -13450,10 +13694,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (tp->pcie_cap != 0) {
u16 lnkctl;
- tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
+ tg3_flag_set(tp, PCI_EXPRESS);
tp->pcie_readrq = 4096;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
tp->pcie_readrq = 2048;
pcie_set_readrq(tp->pdev, tp->pcie_readrq);
@@ -13462,20 +13707,23 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->pcie_cap + PCI_EXP_LNKCTL,
&lnkctl);
if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN) {
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
- tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
+ ASIC_REV_5906) {
+ tg3_flag_clear(tp, HW_TSO_2);
+ tg3_flag_clear(tp, TSO_CAPABLE);
+ }
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
tp->pci_chip_rev_id == CHIPREV_ID_57780_A0 ||
tp->pci_chip_rev_id == CHIPREV_ID_57780_A1)
- tp->tg3_flags3 |= TG3_FLG3_CLKREQ_BUG;
+ tg3_flag_set(tp, CLKREQ_BUG);
} else if (tp->pci_chip_rev_id == CHIPREV_ID_5717_A0) {
- tp->tg3_flags3 |= TG3_FLG3_L1PLLPD_EN;
+ tg3_flag_set(tp, L1PLLPD_EN);
}
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
- tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
- } else if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
- (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+ tg3_flag_set(tp, PCI_EXPRESS);
+ } else if (!tg3_flag(tp, 5705_PLUS) ||
+ tg3_flag(tp, 5780_CLASS)) {
tp->pcix_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_PCIX);
if (!tp->pcix_cap) {
dev_err(&tp->pdev->dev,
@@ -13484,7 +13732,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
}
if (!(pci_state_reg & PCISTATE_CONV_PCI_MODE))
- tp->tg3_flags |= TG3_FLAG_PCIX_MODE;
+ tg3_flag_set(tp, PCIX_MODE);
}
/* If we have an AMD 762 or VIA K8T800 chipset, write
@@ -13494,8 +13742,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
* posted to the chip in order.
*/
if (pci_dev_present(tg3_write_reorder_chipsets) &&
- !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
- tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER;
+ !tg3_flag(tp, PCI_EXPRESS))
+ tg3_flag_set(tp, MBOX_WRITE_REORDER);
pci_read_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
&tp->pci_cacheline_sz);
@@ -13512,17 +13760,17 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
/* 5700 BX chips need to have their TX producer index
* mailboxes written twice to workaround a bug.
*/
- tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG;
+ tg3_flag_set(tp, TXD_MBOX_HWBUG);
/* If we are in PCI-X mode, enable register write workaround.
*
* The workaround is to use indirect register accesses
* for all chip writes not to mailbox registers.
*/
- if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) {
+ if (tg3_flag(tp, PCIX_MODE)) {
u32 pm_reg;
- tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG;
+ tg3_flag_set(tp, PCIX_TARGET_HWBUG);
/* The chip can have it's power management PCI config
* space registers clobbered due to this bug.
@@ -13545,9 +13793,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
}
if ((pci_state_reg & PCISTATE_BUS_SPEED_HIGH) != 0)
- tp->tg3_flags |= TG3_FLAG_PCI_HIGH_SPEED;
+ tg3_flag_set(tp, PCI_HIGH_SPEED);
if ((pci_state_reg & PCISTATE_BUS_32BIT) != 0)
- tp->tg3_flags |= TG3_FLAG_PCI_32BIT;
+ tg3_flag_set(tp, PCI_32BIT);
/* Chip-specific fixup from Broadcom driver */
if ((tp->pci_chip_rev_id == CHIPREV_ID_5704_A0) &&
@@ -13565,10 +13813,10 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->write32_rx_mbox = tg3_write32;
/* Various workaround register access methods */
- if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG)
+ if (tg3_flag(tp, PCIX_TARGET_HWBUG))
tp->write32 = tg3_write_indirect_reg32;
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 ||
- ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
+ (tg3_flag(tp, PCI_EXPRESS) &&
tp->pci_chip_rev_id == CHIPREV_ID_5750_A0)) {
/*
* Back to back register writes can cause problems on these
@@ -13580,14 +13828,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->write32 = tg3_write_flush_reg32;
}
- if ((tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) ||
- (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)) {
+ if (tg3_flag(tp, TXD_MBOX_HWBUG) || tg3_flag(tp, MBOX_WRITE_REORDER)) {
tp->write32_tx_mbox = tg3_write32_tx_mbox;
- if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)
+ if (tg3_flag(tp, MBOX_WRITE_REORDER))
tp->write32_rx_mbox = tg3_write_flush_reg32;
}
- if (tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND) {
+ if (tg3_flag(tp, ICH_WORKAROUND)) {
tp->read32 = tg3_read_indirect_reg32;
tp->write32 = tg3_write_indirect_reg32;
tp->read32_mbox = tg3_read_indirect_mbox;
@@ -13610,13 +13857,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
}
if (tp->write32 == tg3_write_indirect_reg32 ||
- ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) &&
+ (tg3_flag(tp, PCIX_MODE) &&
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)))
- tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG;
+ tg3_flag_set(tp, SRAM_USE_CONFIG);
/* Get eeprom hw config before calling tg3_set_power_state().
- * In particular, the TG3_FLG2_IS_NIC flag must be
+ * In particular, the TG3_FLAG_IS_NIC flag must be
* determined before calling tg3_set_power_state() so that
* we know whether or not to switch out of Vaux power.
* When the flag is set, it means that GPIO1 is used for eeprom
@@ -13625,7 +13872,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
*/
tg3_get_eeprom_hw_cfg(tp);
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
+ if (tg3_flag(tp, ENABLE_APE)) {
/* Allow reads and writes to the
* APE register and memory space.
*/
@@ -13640,16 +13887,16 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
- (tp->tg3_flags3 & TG3_FLG3_5717_PLUS))
- tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
+ tg3_flag(tp, 57765_PLUS))
+ tg3_flag_set(tp, CPMU_PRESENT);
- /* Set up tp->grc_local_ctrl before calling tg_power_up().
+ /* Set up tp->grc_local_ctrl before calling tg3_power_up().
* GPIO1 driven high will bring 5700's external PHY out of reset.
* It is also used as eeprom write protect on LOMs.
*/
tp->grc_local_ctrl = GRC_LCLCTRL_INT_ON_ATTN | GRC_LCLCTRL_AUTO_SEEPROM;
- if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) ||
- (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT))
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
+ tg3_flag(tp, EEPROM_WRITE_PROT))
tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 |
GRC_LCLCTRL_GPIO_OUTPUT1);
/* Unused GPIO3 must be driven as output on 5752 because there
@@ -13667,7 +13914,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
/* Turn off the debug UART. */
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
- if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
+ if (tg3_flag(tp, IS_NIC))
/* Keep VMain power. */
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE0 |
GRC_LCLCTRL_GPIO_OUTPUT0;
@@ -13683,26 +13930,25 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
/* Derive initial jumbo mode from MTU assigned in
* ether_setup() via the alloc_etherdev() call
*/
- if (tp->dev->mtu > ETH_DATA_LEN &&
- !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
- tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
+ if (tp->dev->mtu > ETH_DATA_LEN && !tg3_flag(tp, 5780_CLASS))
+ tg3_flag_set(tp, JUMBO_RING_ENABLE);
/* Determine WakeOnLan speed to use. */
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
tp->pci_chip_rev_id == CHIPREV_ID_5701_B0 ||
tp->pci_chip_rev_id == CHIPREV_ID_5701_B2) {
- tp->tg3_flags &= ~(TG3_FLAG_WOL_SPEED_100MB);
+ tg3_flag_clear(tp, WOL_SPEED_100MB);
} else {
- tp->tg3_flags |= TG3_FLAG_WOL_SPEED_100MB;
+ tg3_flag_set(tp, WOL_SPEED_100MB);
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
tp->phy_flags |= TG3_PHYFLG_IS_FET;
/* A few boards don't want Ethernet@WireSpeed phy feature */
- if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) ||
- ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
(tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) &&
(tp->pci_chip_rev_id != CHIPREV_ID_5705_A1)) ||
(tp->phy_flags & TG3_PHYFLG_IS_FET) ||
@@ -13715,11 +13961,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0)
tp->phy_flags |= TG3_PHYFLG_5704_A0_BUG;
- if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
+ if (tg3_flag(tp, 5705_PLUS) &&
!(tp->phy_flags & TG3_PHYFLG_IS_FET) &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57780 &&
- !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) {
+ !tg3_flag(tp, 57765_PLUS)) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
@@ -13740,7 +13986,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->phy_otp = TG3_OTP_DEFAULT;
}
- if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT)
+ if (tg3_flag(tp, CPMU_PRESENT))
tp->mi_mode = MAC_MI_MODE_500KHZ_CONST;
else
tp->mi_mode = MAC_MI_MODE_BASE;
@@ -13750,9 +13996,17 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX)
tp->coalesce_mode |= HOSTCC_MODE_32BYTE;
+ /* Set these bits to enable statistics workaround. */
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+ tp->pci_chip_rev_id == CHIPREV_ID_5719_A0 ||
+ tp->pci_chip_rev_id == CHIPREV_ID_5720_A0) {
+ tp->coalesce_mode |= HOSTCC_MODE_ATTN;
+ tp->grc_mode |= GRC_MODE_IRQ_ON_FLOW_ATTN;
+ }
+
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
- tp->tg3_flags3 |= TG3_FLG3_USE_PHYLIB;
+ tg3_flag_set(tp, USE_PHYLIB);
err = tg3_mdio_init(tp);
if (err)
@@ -13760,7 +14014,15 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
/* Initialize data/descriptor byte/word swapping. */
val = tr32(GRC_MODE);
- val &= GRC_MODE_HOST_STACKUP;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ val &= (GRC_MODE_BYTE_SWAP_B2HRX_DATA |
+ GRC_MODE_WORD_SWAP_B2HRX_DATA |
+ GRC_MODE_B2HRX_ENABLE |
+ GRC_MODE_HTX2B_ENABLE |
+ GRC_MODE_HOST_STACKUP);
+ else
+ val &= GRC_MODE_HOST_STACKUP;
+
tw32(GRC_MODE, val | tp->grc_mode);
tg3_switch_clocks(tp);
@@ -13771,7 +14033,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
&pci_state_reg);
if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0 &&
- (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) == 0) {
+ !tg3_flag(tp, PCIX_TARGET_HWBUG)) {
u32 chiprevid = GET_CHIP_REV_ID(tp->misc_host_ctrl);
if (chiprevid == CHIPREV_ID_5701_A0 ||
@@ -13790,7 +14052,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
writel(0x00000000, sram_base + 4);
writel(0xffffffff, sram_base + 4);
if (readl(sram_base) != 0x00000000)
- tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG;
+ tg3_flag_set(tp, PCIX_TARGET_HWBUG);
}
}
@@ -13803,12 +14065,12 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
(grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 ||
grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M))
- tp->tg3_flags2 |= TG3_FLG2_IS_5788;
+ tg3_flag_set(tp, IS_5788);
- if (!(tp->tg3_flags2 & TG3_FLG2_IS_5788) &&
- (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700))
- tp->tg3_flags |= TG3_FLAG_TAGGED_STATUS;
- if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) {
+ if (!tg3_flag(tp, IS_5788) &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700)
+ tg3_flag_set(tp, TAGGED_STATUS);
+ if (tg3_flag(tp, TAGGED_STATUS)) {
tp->coalesce_mode |= (HOSTCC_MODE_CLRTICK_RXBD |
HOSTCC_MODE_CLRTICK_TXBD);
@@ -13818,7 +14080,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
}
/* Preserve the APE MAC_MODE bits */
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+ if (tg3_flag(tp, ENABLE_APE))
tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
else
tp->mac_mode = TG3_DEF_MAC_MODE;
@@ -13865,9 +14127,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
* status register in those cases.
*/
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700)
- tp->tg3_flags |= TG3_FLAG_USE_LINKCHG_REG;
+ tg3_flag_set(tp, USE_LINKCHG_REG);
else
- tp->tg3_flags &= ~TG3_FLAG_USE_LINKCHG_REG;
+ tg3_flag_clear(tp, USE_LINKCHG_REG);
/* The led_ctrl is set during tg3_phy_probe, here we might
* have to force the link status polling mechanism based
@@ -13877,19 +14139,19 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) {
tp->phy_flags |= TG3_PHYFLG_USE_MI_INTERRUPT;
- tp->tg3_flags |= TG3_FLAG_USE_LINKCHG_REG;
+ tg3_flag_set(tp, USE_LINKCHG_REG);
}
/* For all SERDES we poll the MAC status register. */
if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
- tp->tg3_flags |= TG3_FLAG_POLL_SERDES;
+ tg3_flag_set(tp, POLL_SERDES);
else
- tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES;
+ tg3_flag_clear(tp, POLL_SERDES);
tp->rx_offset = NET_IP_ALIGN;
tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
- (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) {
+ tg3_flag(tp, PCIX_MODE)) {
tp->rx_offset = 0;
#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
tp->rx_copy_thresh = ~(u16)0;
@@ -13910,7 +14172,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
tp->rx_std_max_post = 8;
- if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND)
+ if (tg3_flag(tp, ASPM_WORKAROUND))
tp->pwrmgmt_thresh = tr32(PCIE_PWR_MGMT_THRESH) &
PCIE_PWR_MGMT_L1_THRESH_MSK;
@@ -13957,16 +14219,15 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
#endif
mac_offset = 0x7c;
- if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
- (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
+ tg3_flag(tp, 5780_CLASS)) {
if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID)
mac_offset = 0xcc;
if (tg3_nvram_lock(tp))
tw32_f(NVRAM_CMD, NVRAM_CMD_RESET);
else
tg3_nvram_unlock(tp);
- } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+ } else if (tg3_flag(tp, 5717_PLUS)) {
if (PCI_FUNC(tp->pdev->devfn) & 1)
mac_offset = 0xcc;
if (PCI_FUNC(tp->pdev->devfn) > 1)
@@ -13991,7 +14252,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
}
if (!addr_ok) {
/* Next, try NVRAM. */
- if (!(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) &&
+ if (!tg3_flag(tp, NO_NVRAM) &&
!tg3_nvram_read_be32(tp, mac_offset + 0, &hi) &&
!tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) {
memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2);
@@ -14042,7 +14303,7 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val)
*/
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 &&
- !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
+ !tg3_flag(tp, PCI_EXPRESS))
goto out;
#if defined(CONFIG_PPC64) || defined(CONFIG_IA64) || defined(CONFIG_PARISC)
@@ -14055,7 +14316,7 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val)
#endif
#endif
- if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
+ if (tg3_flag(tp, 57765_PLUS)) {
val = goal ? 0 : DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
goto out;
}
@@ -14074,8 +14335,7 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val)
* other than 5700 and 5701 which do not implement the
* boundary bits.
*/
- if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) &&
- !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) {
+ if (tg3_flag(tp, PCIX_MODE) && !tg3_flag(tp, PCI_EXPRESS)) {
switch (cacheline_size) {
case 16:
case 32:
@@ -14100,7 +14360,7 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val)
DMA_RWCTRL_WRITE_BNDRY_384_PCIX);
break;
}
- } else if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
+ } else if (tg3_flag(tp, PCI_EXPRESS)) {
switch (cacheline_size) {
case 16:
case 32:
@@ -14272,13 +14532,13 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
tp->dma_rwctrl = tg3_calc_dma_bndry(tp, tp->dma_rwctrl);
- if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
+ if (tg3_flag(tp, 57765_PLUS))
goto out;
- if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
+ if (tg3_flag(tp, PCI_EXPRESS)) {
/* DMA read watermark not used on PCIE */
tp->dma_rwctrl |= 0x00180000;
- } else if (!(tp->tg3_flags & TG3_FLAG_PCIX_MODE)) {
+ } else if (!tg3_flag(tp, PCIX_MODE)) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)
tp->dma_rwctrl |= 0x003f0000;
@@ -14294,7 +14554,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
* do the less restrictive ONE_DMA workaround for
* better performance.
*/
- if ((tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) &&
+ if (tg3_flag(tp, 40BIT_DMA_BUG) &&
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
tp->dma_rwctrl |= 0x8000;
else if (ccval == 0x6 || ccval == 0x7)
@@ -14423,7 +14683,6 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
}
if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) !=
DMA_RWCTRL_WRITE_BNDRY_16) {
-
/* DMA test passed without adjusting DMA boundary,
* now look for chipsets that are known to expose the
* DMA bug without failing the test.
@@ -14447,7 +14706,7 @@ out_nofree:
static void __devinit tg3_init_bufmgr_config(struct tg3 *tp)
{
- if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
+ if (tg3_flag(tp, 57765_PLUS)) {
tp->bufmgr_config.mbuf_read_dma_low_water =
DEFAULT_MB_RDMA_LOW_WATER_5705;
tp->bufmgr_config.mbuf_mac_rx_low_water =
@@ -14461,7 +14720,7 @@ static void __devinit tg3_init_bufmgr_config(struct tg3 *tp)
DEFAULT_MB_MACRX_LOW_WATER_JUMBO_57765;
tp->bufmgr_config.mbuf_high_water_jumbo =
DEFAULT_MB_HIGH_WATER_JUMBO_57765;
- } else if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+ } else if (tg3_flag(tp, 5705_PLUS)) {
tp->bufmgr_config.mbuf_read_dma_low_water =
DEFAULT_MB_RDMA_LOW_WATER_5705;
tp->bufmgr_config.mbuf_mac_rx_low_water =
@@ -14525,6 +14784,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
case TG3_PHY_ID_BCM5718S: return "5718S";
case TG3_PHY_ID_BCM57765: return "57765";
case TG3_PHY_ID_BCM5719C: return "5719C";
+ case TG3_PHY_ID_BCM5720C: return "5720C";
case TG3_PHY_ID_BCM8002: return "8002/serdes";
case 0: return "serdes";
default: return "unknown";
@@ -14533,10 +14793,10 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
static char * __devinit tg3_bus_string(struct tg3 *tp, char *str)
{
- if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
+ if (tg3_flag(tp, PCI_EXPRESS)) {
strcpy(str, "PCI Express");
return str;
- } else if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) {
+ } else if (tg3_flag(tp, PCIX_MODE)) {
u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL) & 0x1f;
strcpy(str, "PCIX:");
@@ -14555,12 +14815,12 @@ static char * __devinit tg3_bus_string(struct tg3 *tp, char *str)
strcat(str, "100MHz");
} else {
strcpy(str, "PCI:");
- if (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED)
+ if (tg3_flag(tp, PCI_HIGH_SPEED))
strcat(str, "66MHz");
else
strcat(str, "33MHz");
}
- if (tp->tg3_flags & TG3_FLAG_PCI_32BIT)
+ if (tg3_flag(tp, PCI_32BIT))
strcat(str, ":32-bit");
else
strcat(str, ":64-bit");
@@ -14619,7 +14879,7 @@ static void __devinit tg3_init_coal(struct tg3 *tp)
ec->tx_coalesce_usecs_irq = DEFAULT_TXCOAL_TICK_INT_CLRTCKS;
}
- if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+ if (tg3_flag(tp, 5705_PLUS)) {
ec->rx_coalesce_usecs_irq = 0;
ec->tx_coalesce_usecs_irq = 0;
ec->stats_block_coalesce_usecs = 0;
@@ -14637,22 +14897,8 @@ static const struct net_device_ops tg3_netdev_ops = {
.ndo_do_ioctl = tg3_ioctl,
.ndo_tx_timeout = tg3_tx_timeout,
.ndo_change_mtu = tg3_change_mtu,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = tg3_poll_controller,
-#endif
-};
-
-static const struct net_device_ops tg3_netdev_ops_dma_bug = {
- .ndo_open = tg3_open,
- .ndo_stop = tg3_close,
- .ndo_start_xmit = tg3_start_xmit_dma_bug,
- .ndo_get_stats64 = tg3_get_stats64,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_multicast_list = tg3_set_rx_mode,
- .ndo_set_mac_address = tg3_set_mac_addr,
- .ndo_do_ioctl = tg3_ioctl,
- .ndo_tx_timeout = tg3_tx_timeout,
- .ndo_change_mtu = tg3_change_mtu,
+ .ndo_fix_features = tg3_fix_features,
+ .ndo_set_features = tg3_set_features,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = tg3_poll_controller,
#endif
@@ -14667,6 +14913,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
u32 sndmbx, rcvmbx, intmbx;
char str[40];
u64 dma_mask, persist_dma_mask;
+ u32 features = 0;
printk_once(KERN_INFO "%s\n", version);
@@ -14702,8 +14949,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
SET_NETDEV_DEV(dev, &pdev->dev);
- dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-
tp = netdev_priv(dev);
tp->pdev = pdev;
tp->dev = dev;
@@ -14753,6 +14998,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
dev->ethtool_ops = &tg3_ethtool_ops;
dev->watchdog_timeo = TG3_TX_TIMEOUT;
+ dev->netdev_ops = &tg3_netdev_ops;
dev->irq = pdev->irq;
err = tg3_get_invariants(tp);
@@ -14762,23 +15008,15 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
goto err_out_iounmap;
}
- if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719)
- dev->netdev_ops = &tg3_netdev_ops;
- else
- dev->netdev_ops = &tg3_netdev_ops_dma_bug;
-
-
/* The EPB bridge inside 5714, 5715, and 5780 and any
* device behind the EPB cannot support DMA addresses > 40-bit.
* On 64-bit systems with IOMMU, use 40-bit dma_mask.
* On 64-bit systems without IOMMU, use 64-bit dma_mask and
* do DMA address check in tg3_start_xmit().
*/
- if (tp->tg3_flags2 & TG3_FLG2_IS_5788)
+ if (tg3_flag(tp, IS_5788))
persist_dma_mask = dma_mask = DMA_BIT_MASK(32);
- else if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) {
+ else if (tg3_flag(tp, 40BIT_DMA_BUG)) {
persist_dma_mask = dma_mask = DMA_BIT_MASK(40);
#ifdef CONFIG_HIGHMEM
dma_mask = DMA_BIT_MASK(64);
@@ -14790,7 +15028,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
if (dma_mask > DMA_BIT_MASK(32)) {
err = pci_set_dma_mask(pdev, dma_mask);
if (!err) {
- dev->features |= NETIF_F_HIGHDMA;
+ features |= NETIF_F_HIGHDMA;
err = pci_set_consistent_dma_mask(pdev,
persist_dma_mask);
if (err < 0) {
@@ -14811,48 +15049,58 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tg3_init_bufmgr_config(tp);
- /* Selectively allow TSO based on operating conditions */
- if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) ||
- (tp->fw_needed && !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)))
- tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
- else {
- tp->tg3_flags2 &= ~(TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG);
- tp->fw_needed = NULL;
- }
+ features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
- tp->fw_needed = FIRMWARE_TG3;
+ /* 5700 B0 chips do not support checksumming correctly due
+ * to hardware bugs.
+ */
+ if (tp->pci_chip_rev_id != CHIPREV_ID_5700_B0) {
+ features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
+
+ if (tg3_flag(tp, 5755_PLUS))
+ features |= NETIF_F_IPV6_CSUM;
+ }
/* TSO is on by default on chips that support hardware TSO.
* Firmware TSO on older chips gives lower performance, so it
* is off by default, but can be enabled using ethtool.
*/
- if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) &&
- (dev->features & NETIF_F_IP_CSUM)) {
- dev->features |= NETIF_F_TSO;
- vlan_features_add(dev, NETIF_F_TSO);
- }
- if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) ||
- (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3)) {
- if (dev->features & NETIF_F_IPV6_CSUM) {
- dev->features |= NETIF_F_TSO6;
- vlan_features_add(dev, NETIF_F_TSO6);
- }
- if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
+ if ((tg3_flag(tp, HW_TSO_1) ||
+ tg3_flag(tp, HW_TSO_2) ||
+ tg3_flag(tp, HW_TSO_3)) &&
+ (features & NETIF_F_IP_CSUM))
+ features |= NETIF_F_TSO;
+ if (tg3_flag(tp, HW_TSO_2) || tg3_flag(tp, HW_TSO_3)) {
+ if (features & NETIF_F_IPV6_CSUM)
+ features |= NETIF_F_TSO6;
+ if (tg3_flag(tp, HW_TSO_3) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
- dev->features |= NETIF_F_TSO_ECN;
- vlan_features_add(dev, NETIF_F_TSO_ECN);
- }
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+ features |= NETIF_F_TSO_ECN;
}
+ dev->features |= features;
+ dev->vlan_features |= features;
+
+ /*
+ * Add loopback capability only for a subset of devices that support
+ * MAC-LOOPBACK. Eventually this need to be enhanced to allow INT-PHY
+ * loopback for the remaining devices.
+ */
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780 &&
+ !tg3_flag(tp, CPMU_PRESENT))
+ /* Add the loopback capability */
+ features |= NETIF_F_LOOPBACK;
+
+ dev->hw_features |= features;
+
if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 &&
- !(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) &&
+ !tg3_flag(tp, TSO_CAPABLE) &&
!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH)) {
- tp->tg3_flags2 |= TG3_FLG2_MAX_RXPEND_64;
+ tg3_flag_set(tp, MAX_RXPEND_64);
tp->rx_pending = 63;
}
@@ -14863,7 +15111,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
goto err_out_iounmap;
}
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
+ if (tg3_flag(tp, ENABLE_APE)) {
tp->aperegs = pci_ioremap_bar(pdev, BAR_2);
if (!tp->aperegs) {
dev_err(&pdev->dev,
@@ -14874,7 +15122,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tg3_ape_lock_init(tp);
- if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)
+ if (tg3_flag(tp, ENABLE_ASF))
tg3_read_dash_ver(tp);
}
@@ -14918,7 +15166,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
else
tnapi->coal_now = HOSTCC_MODE_NOW;
- if (!(tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX))
+ if (!tg3_flag(tp, SUPPORT_MSIX))
break;
/*
@@ -14972,21 +15220,25 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
ethtype = "10/100/1000Base-T";
netdev_info(dev, "attached PHY is %s (%s Ethernet) "
- "(WireSpeed[%d])\n", tg3_phy_string(tp), ethtype,
- (tp->phy_flags & TG3_PHYFLG_NO_ETH_WIRE_SPEED) == 0);
+ "(WireSpeed[%d], EEE[%d])\n",
+ tg3_phy_string(tp), ethtype,
+ (tp->phy_flags & TG3_PHYFLG_NO_ETH_WIRE_SPEED) == 0,
+ (tp->phy_flags & TG3_PHYFLG_EEE_CAP) != 0);
}
netdev_info(dev, "RXcsums[%d] LinkChgREG[%d] MIirq[%d] ASF[%d] TSOcap[%d]\n",
- (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0,
- (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0,
+ (dev->features & NETIF_F_RXCSUM) != 0,
+ tg3_flag(tp, USE_LINKCHG_REG) != 0,
(tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT) != 0,
- (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0,
- (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
+ tg3_flag(tp, ENABLE_ASF) != 0,
+ tg3_flag(tp, TSO_CAPABLE) != 0);
netdev_info(dev, "dma_rwctrl[%08x] dma_mask[%d-bit]\n",
tp->dma_rwctrl,
pdev->dma_mask == DMA_BIT_MASK(32) ? 32 :
((u64)pdev->dma_mask) == DMA_BIT_MASK(40) ? 40 : 64);
+ pci_save_state(pdev);
+
return 0;
err_out_apeunmap:
@@ -15025,7 +15277,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
cancel_work_sync(&tp->reset_task);
- if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ if (!tg3_flag(tp, USE_PHYLIB)) {
tg3_phy_fini(tp);
tg3_mdio_fini(tp);
}
@@ -15071,7 +15323,7 @@ static int tg3_suspend(struct device *device)
tg3_full_lock(tp, 0);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
- tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
+ tg3_flag_clear(tp, INIT_COMPLETE);
tg3_full_unlock(tp);
err = tg3_power_down_prepare(tp);
@@ -15080,7 +15332,7 @@ static int tg3_suspend(struct device *device)
tg3_full_lock(tp, 0);
- tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
+ tg3_flag_set(tp, INIT_COMPLETE);
err2 = tg3_restart_hw(tp, 1);
if (err2)
goto out;
@@ -15115,7 +15367,7 @@ static int tg3_resume(struct device *device)
tg3_full_lock(tp, 0);
- tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
+ tg3_flag_set(tp, INIT_COMPLETE);
err = tg3_restart_hw(tp, 1);
if (err)
goto out;
@@ -15143,11 +15395,156 @@ static SIMPLE_DEV_PM_OPS(tg3_pm_ops, tg3_suspend, tg3_resume);
#endif /* CONFIG_PM_SLEEP */
+/**
+ * tg3_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 tg3_io_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct tg3 *tp = netdev_priv(netdev);
+ pci_ers_result_t err = PCI_ERS_RESULT_NEED_RESET;
+
+ netdev_info(netdev, "PCI I/O error detected\n");
+
+ rtnl_lock();
+
+ if (!netif_running(netdev))
+ goto done;
+
+ tg3_phy_stop(tp);
+
+ tg3_netif_stop(tp);
+
+ del_timer_sync(&tp->timer);
+ tg3_flag_clear(tp, RESTART_TIMER);
+
+ /* Want to make sure that the reset task doesn't run */
+ cancel_work_sync(&tp->reset_task);
+ tg3_flag_clear(tp, TX_RECOVERY_PENDING);
+ tg3_flag_clear(tp, RESTART_TIMER);
+
+ netif_device_detach(netdev);
+
+ /* Clean up software state, even if MMIO is blocked */
+ tg3_full_lock(tp, 0);
+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
+ tg3_full_unlock(tp);
+
+done:
+ if (state == pci_channel_io_perm_failure)
+ err = PCI_ERS_RESULT_DISCONNECT;
+ else
+ pci_disable_device(pdev);
+
+ rtnl_unlock();
+
+ return err;
+}
+
+/**
+ * tg3_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.
+ * At this point, the card has exprienced a hard reset,
+ * followed by fixups by BIOS, and has its config space
+ * set up identically to what it was at cold boot.
+ */
+static pci_ers_result_t tg3_io_slot_reset(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct tg3 *tp = netdev_priv(netdev);
+ pci_ers_result_t rc = PCI_ERS_RESULT_DISCONNECT;
+ int err;
+
+ rtnl_lock();
+
+ if (pci_enable_device(pdev)) {
+ netdev_err(netdev, "Cannot re-enable PCI device after reset.\n");
+ goto done;
+ }
+
+ pci_set_master(pdev);
+ pci_restore_state(pdev);
+ pci_save_state(pdev);
+
+ if (!netif_running(netdev)) {
+ rc = PCI_ERS_RESULT_RECOVERED;
+ goto done;
+ }
+
+ err = tg3_power_up(tp);
+ if (err) {
+ netdev_err(netdev, "Failed to restore register access.\n");
+ goto done;
+ }
+
+ rc = PCI_ERS_RESULT_RECOVERED;
+
+done:
+ rtnl_unlock();
+
+ return rc;
+}
+
+/**
+ * tg3_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 tg3_io_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct tg3 *tp = netdev_priv(netdev);
+ int err;
+
+ rtnl_lock();
+
+ if (!netif_running(netdev))
+ goto done;
+
+ tg3_full_lock(tp, 0);
+ tg3_flag_set(tp, INIT_COMPLETE);
+ err = tg3_restart_hw(tp, 1);
+ tg3_full_unlock(tp);
+ if (err) {
+ netdev_err(netdev, "Cannot restart hardware after reset.\n");
+ goto done;
+ }
+
+ netif_device_attach(netdev);
+
+ tp->timer.expires = jiffies + tp->timer_offset;
+ add_timer(&tp->timer);
+
+ tg3_netif_start(tp);
+
+ tg3_phy_start(tp);
+
+done:
+ rtnl_unlock();
+}
+
+static struct pci_error_handlers tg3_err_handler = {
+ .error_detected = tg3_io_error_detected,
+ .slot_reset = tg3_io_slot_reset,
+ .resume = tg3_io_resume
+};
+
static struct pci_driver tg3_driver = {
.name = DRV_MODULE_NAME,
.id_table = tg3_pci_tbl,
.probe = tg3_init_one,
.remove = __devexit_p(tg3_remove_one),
+ .err_handler = &tg3_err_handler,
.driver.pm = TG3_PM_OPS,
};
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 5e96706ad10..5b3d2f34da7 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -23,11 +23,13 @@
#define TG3_BDINFO_NIC_ADDR 0xcUL /* 32-bit */
#define TG3_BDINFO_SIZE 0x10UL
-#define TG3_RX_INTERNAL_RING_SZ_5906 32
-
-#define RX_STD_MAX_SIZE_5705 512
-#define RX_STD_MAX_SIZE_5717 2048
-#define RX_JUMBO_MAX_SIZE 0xdeadbeef /* XXX */
+#define TG3_RX_STD_MAX_SIZE_5700 512
+#define TG3_RX_STD_MAX_SIZE_5717 2048
+#define TG3_RX_JMB_MAX_SIZE_5700 256
+#define TG3_RX_JMB_MAX_SIZE_5717 1024
+#define TG3_RX_RET_MAX_SIZE_5700 1024
+#define TG3_RX_RET_MAX_SIZE_5705 512
+#define TG3_RX_RET_MAX_SIZE_5717 4096
/* First 256 bytes are a mirror of PCI config space. */
#define TG3PCI_VENDOR 0x00000000
@@ -54,6 +56,7 @@
#define TG3PCI_DEVICE_TIGON3_57791 0x16b2
#define TG3PCI_DEVICE_TIGON3_57795 0x16b6
#define TG3PCI_DEVICE_TIGON3_5719 0x1657
+#define TG3PCI_DEVICE_TIGON3_5720 0x165f
/* 0x04 --> 0x2c unused */
#define TG3PCI_SUBVENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM
#define TG3PCI_SUBDEVICE_ID_BROADCOM_95700A6 0x1644
@@ -142,6 +145,7 @@
#define CHIPREV_ID_5717_A0 0x05717000
#define CHIPREV_ID_57765_A0 0x57785000
#define CHIPREV_ID_5719_A0 0x05719000
+#define CHIPREV_ID_5720_A0 0x05720000
#define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12)
#define ASIC_REV_5700 0x07
#define ASIC_REV_5701 0x00
@@ -163,6 +167,7 @@
#define ASIC_REV_5717 0x5717
#define ASIC_REV_57765 0x57785
#define ASIC_REV_5719 0x5719
+#define ASIC_REV_5720 0x5720
#define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8)
#define CHIPREV_5700_AX 0x70
#define CHIPREV_5700_BX 0x71
@@ -175,6 +180,7 @@
#define CHIPREV_5750_BX 0x41
#define CHIPREV_5784_AX 0x57840
#define CHIPREV_5761_AX 0x57610
+#define CHIPREV_57765_AX 0x577650
#define GET_METAL_REV(CHIP_REV_ID) ((CHIP_REV_ID) & 0xff)
#define METAL_REV_A0 0x00
#define METAL_REV_A1 0x01
@@ -183,6 +189,7 @@
#define METAL_REV_B2 0x02
#define TG3PCI_DMA_RW_CTRL 0x0000006c
#define DMA_RWCTRL_DIS_CACHE_ALIGNMENT 0x00000001
+#define DMA_RWCTRL_TAGGED_STAT_WA 0x00000080
#define DMA_RWCTRL_CRDRDR_RDMA_MRRS_MSK 0x00000380
#define DMA_RWCTRL_READ_BNDRY_MASK 0x00000700
#define DMA_RWCTRL_READ_BNDRY_DISAB 0x00000000
@@ -473,6 +480,8 @@
#define TX_MODE_BIG_BCKOFF_ENABLE 0x00000020
#define TX_MODE_LONG_PAUSE_ENABLE 0x00000040
#define TX_MODE_MBUF_LOCKUP_FIX 0x00000100
+#define TX_MODE_JMB_FRM_LEN 0x00400000
+#define TX_MODE_CNT_DN_MODE 0x00800000
#define MAC_TX_STATUS 0x00000460
#define TX_STATUS_XOFFED 0x00000001
#define TX_STATUS_SENT_XOFF 0x00000002
@@ -487,6 +496,8 @@
#define TX_LENGTHS_IPG_SHIFT 8
#define TX_LENGTHS_IPG_CRS_MASK 0x00003000
#define TX_LENGTHS_IPG_CRS_SHIFT 12
+#define TX_LENGTHS_JMB_FRM_LEN_MSK 0x00ff0000
+#define TX_LENGTHS_CNT_DWN_VAL_MSK 0xff000000
#define MAC_RX_MODE 0x00000468
#define RX_MODE_RESET 0x00000001
#define RX_MODE_ENABLE 0x00000002
@@ -1079,6 +1090,9 @@
#define CPMU_HST_ACC_MACCLK_6_25 0x00130000
/* 0x3620 --> 0x3630 unused */
+#define TG3_CPMU_CLCK_ORIDE 0x00003624
+#define CPMU_CLCK_ORIDE_MAC_ORIDE_EN 0x80000000
+
#define TG3_CPMU_CLCK_STAT 0x00003630
#define CPMU_CLCK_STAT_MAC_CLCK_MASK 0x001f0000
#define CPMU_CLCK_STAT_MAC_CLCK_62_5 0x00000000
@@ -1188,6 +1202,7 @@
#define HOSTCC_STATS_BLK_NIC_ADDR 0x00003c40
#define HOSTCC_STATUS_BLK_NIC_ADDR 0x00003c44
#define HOSTCC_FLOW_ATTN 0x00003c48
+#define HOSTCC_FLOW_ATTN_MBUF_LWM 0x00000040
/* 0x3c4c --> 0x3c50 unused */
#define HOSTCC_JUMBO_CON_IDX 0x00003c50
#define HOSTCC_STD_CON_IDX 0x00003c54
@@ -1321,6 +1336,7 @@
#define RDMAC_MODE_MULT_DMA_RD_DIS 0x01000000
#define RDMAC_MODE_IPV4_LSO_EN 0x08000000
#define RDMAC_MODE_IPV6_LSO_EN 0x10000000
+#define RDMAC_MODE_H2BNC_VLAN_DET 0x20000000
#define RDMAC_STATUS 0x00004804
#define RDMAC_STATUS_TGTABORT 0x00000004
#define RDMAC_STATUS_MSTABORT 0x00000008
@@ -1597,6 +1613,7 @@
#define MSGINT_MODE_ONE_SHOT_DISABLE 0x00000020
#define MSGINT_MODE_MULTIVEC_EN 0x00000080
#define MSGINT_STATUS 0x00006004
+#define MSGINT_STATUS_MSI_REQ 0x00000001
#define MSGINT_FIFO 0x00006008
/* 0x600c --> 0x6400 unused */
@@ -1613,6 +1630,8 @@
#define GRC_MODE_WSWAP_NONFRM_DATA 0x00000004
#define GRC_MODE_BSWAP_DATA 0x00000010
#define GRC_MODE_WSWAP_DATA 0x00000020
+#define GRC_MODE_BYTE_SWAP_B2HRX_DATA 0x00000040
+#define GRC_MODE_WORD_SWAP_B2HRX_DATA 0x00000080
#define GRC_MODE_SPLITHDR 0x00000100
#define GRC_MODE_NOFRM_CRACKING 0x00000200
#define GRC_MODE_INCL_CRC 0x00000400
@@ -1620,8 +1639,10 @@
#define GRC_MODE_NOIRQ_ON_SENDS 0x00002000
#define GRC_MODE_NOIRQ_ON_RCV 0x00004000
#define GRC_MODE_FORCE_PCI32BIT 0x00008000
+#define GRC_MODE_B2HRX_ENABLE 0x00008000
#define GRC_MODE_HOST_STACKUP 0x00010000
#define GRC_MODE_HOST_SENDBDS 0x00020000
+#define GRC_MODE_HTX2B_ENABLE 0x00040000
#define GRC_MODE_NO_TX_PHDR_CSUM 0x00100000
#define GRC_MODE_NVRAM_WR_ENABLE 0x00200000
#define GRC_MODE_PCIE_TL_SEL 0x00000000
@@ -1818,6 +1839,38 @@
#define FLASH_5717VENDOR_ATMEL_45USPT 0x03400000
#define FLASH_5717VENDOR_ST_25USPT 0x03400002
#define FLASH_5717VENDOR_ST_45USPT 0x03400001
+#define FLASH_5720_EEPROM_HD 0x00000001
+#define FLASH_5720_EEPROM_LD 0x00000003
+#define FLASH_5720VENDOR_M_ATMEL_DB011D 0x01000000
+#define FLASH_5720VENDOR_M_ATMEL_DB021D 0x01000002
+#define FLASH_5720VENDOR_M_ATMEL_DB041D 0x01000001
+#define FLASH_5720VENDOR_M_ATMEL_DB081D 0x01000003
+#define FLASH_5720VENDOR_M_ST_M25PE10 0x02000000
+#define FLASH_5720VENDOR_M_ST_M25PE20 0x02000002
+#define FLASH_5720VENDOR_M_ST_M25PE40 0x02000001
+#define FLASH_5720VENDOR_M_ST_M25PE80 0x02000003
+#define FLASH_5720VENDOR_M_ST_M45PE10 0x03000000
+#define FLASH_5720VENDOR_M_ST_M45PE20 0x03000002
+#define FLASH_5720VENDOR_M_ST_M45PE40 0x03000001
+#define FLASH_5720VENDOR_M_ST_M45PE80 0x03000003
+#define FLASH_5720VENDOR_A_ATMEL_DB011B 0x01800000
+#define FLASH_5720VENDOR_A_ATMEL_DB021B 0x01800002
+#define FLASH_5720VENDOR_A_ATMEL_DB041B 0x01800001
+#define FLASH_5720VENDOR_A_ATMEL_DB011D 0x01c00000
+#define FLASH_5720VENDOR_A_ATMEL_DB021D 0x01c00002
+#define FLASH_5720VENDOR_A_ATMEL_DB041D 0x01c00001
+#define FLASH_5720VENDOR_A_ATMEL_DB081D 0x01c00003
+#define FLASH_5720VENDOR_A_ST_M25PE10 0x02800000
+#define FLASH_5720VENDOR_A_ST_M25PE20 0x02800002
+#define FLASH_5720VENDOR_A_ST_M25PE40 0x02800001
+#define FLASH_5720VENDOR_A_ST_M25PE80 0x02800003
+#define FLASH_5720VENDOR_A_ST_M45PE10 0x02c00000
+#define FLASH_5720VENDOR_A_ST_M45PE20 0x02c00002
+#define FLASH_5720VENDOR_A_ST_M45PE40 0x02c00001
+#define FLASH_5720VENDOR_A_ST_M45PE80 0x02c00003
+#define FLASH_5720VENDOR_ATMEL_45USPT 0x03c00000
+#define FLASH_5720VENDOR_ST_25USPT 0x03c00002
+#define FLASH_5720VENDOR_ST_45USPT 0x03c00001
#define NVRAM_CFG1_5752PAGE_SIZE_MASK 0x70000000
#define FLASH_5752PAGE_SIZE_256 0x00000000
#define FLASH_5752PAGE_SIZE_512 0x10000000
@@ -1899,11 +1952,16 @@
/* Alternate PCIE definitions */
#define TG3_PCIE_TLDLPL_PORT 0x00007c00
+#define TG3_PCIE_DL_LO_FTSMAX 0x0000000c
+#define TG3_PCIE_DL_LO_FTSMAX_MSK 0x000000ff
+#define TG3_PCIE_DL_LO_FTSMAX_VAL 0x0000002c
#define TG3_PCIE_PL_LO_PHYCTL1 0x00000004
#define TG3_PCIE_PL_LO_PHYCTL1_L1PLLPD_EN 0x00001000
#define TG3_PCIE_PL_LO_PHYCTL5 0x00000014
#define TG3_PCIE_PL_LO_PHYCTL5_DIS_L2CLKREQ 0x80000000
+#define TG3_REG_BLK_SIZE 0x00008000
+
/* OTP bit definitions */
#define TG3_OTP_AGCTGT_MASK 0x000000e0
#define TG3_OTP_AGCTGT_SHIFT 1
@@ -1955,7 +2013,9 @@
#define TG3_NVM_DIR_END 0x78
#define TG3_NVM_DIRENT_SIZE 0xc
#define TG3_NVM_DIRTYPE_SHIFT 24
+#define TG3_NVM_DIRTYPE_LENMSK 0x003fffff
#define TG3_NVM_DIRTYPE_ASFINI 1
+#define TG3_NVM_DIRTYPE_EXTVPD 20
#define TG3_NVM_PTREV_BCVER 0x94
#define TG3_NVM_BCVER_MAJMSK 0x0000ff00
#define TG3_NVM_BCVER_MAJSFT 8
@@ -2079,6 +2139,13 @@
#define NIC_SRAM_MBUF_POOL_BASE5705 0x00010000
#define NIC_SRAM_MBUF_POOL_SIZE5705 0x0000e000
+#define TG3_SRAM_RX_STD_BDCACHE_SIZE_5700 128
+#define TG3_SRAM_RX_STD_BDCACHE_SIZE_5755 64
+#define TG3_SRAM_RX_STD_BDCACHE_SIZE_5906 32
+
+#define TG3_SRAM_RX_JMB_BDCACHE_SIZE_5700 64
+#define TG3_SRAM_RX_JMB_BDCACHE_SIZE_5717 16
+
/* Currently this is fixed. */
#define TG3_PHY_MII_ADDR 0x01
@@ -2119,7 +2186,7 @@
#define MII_TG3_DSP_TAP26_OPCSINPT 0x0004
#define MII_TG3_DSP_AADJ1CH0 0x001f
#define MII_TG3_DSP_CH34TP2 0x4022
-#define MII_TG3_DSP_CH34TP2_HIBW01 0x0010
+#define MII_TG3_DSP_CH34TP2_HIBW01 0x017b
#define MII_TG3_DSP_AADJ1CH3 0x601f
#define MII_TG3_DSP_AADJ1CH3_ADCCKADJ 0x0002
#define MII_TG3_DSP_EXP1_INT_STAT 0x0f01
@@ -2132,19 +2199,26 @@
#define MII_TG3_AUX_CTRL 0x18 /* auxiliary control register */
+#define MII_TG3_AUXCTL_SHDWSEL_AUXCTL 0x0000
+#define MII_TG3_AUXCTL_ACTL_TX_6DB 0x0400
+#define MII_TG3_AUXCTL_ACTL_SMDSP_ENA 0x0800
+#define MII_TG3_AUXCTL_ACTL_EXTPKTLEN 0x4000
+
+#define MII_TG3_AUXCTL_SHDWSEL_PWRCTL 0x0002
+#define MII_TG3_AUXCTL_PCTL_WOL_EN 0x0008
#define MII_TG3_AUXCTL_PCTL_100TX_LPWR 0x0010
#define MII_TG3_AUXCTL_PCTL_SPR_ISOLATE 0x0020
+#define MII_TG3_AUXCTL_PCTL_CL_AB_TXDAC 0x0040
#define MII_TG3_AUXCTL_PCTL_VREG_11V 0x0180
-#define MII_TG3_AUXCTL_SHDWSEL_PWRCTL 0x0002
-#define MII_TG3_AUXCTL_MISC_WREN 0x8000
-#define MII_TG3_AUXCTL_MISC_FORCE_AMDIX 0x0200
-#define MII_TG3_AUXCTL_MISC_RDSEL_MISC 0x7000
+#define MII_TG3_AUXCTL_SHDWSEL_MISCTEST 0x0004
+
#define MII_TG3_AUXCTL_SHDWSEL_MISC 0x0007
+#define MII_TG3_AUXCTL_MISC_WIRESPD_EN 0x0010
+#define MII_TG3_AUXCTL_MISC_FORCE_AMDIX 0x0200
+#define MII_TG3_AUXCTL_MISC_RDSEL_SHIFT 12
+#define MII_TG3_AUXCTL_MISC_WREN 0x8000
-#define MII_TG3_AUXCTL_ACTL_SMDSP_ENA 0x0800
-#define MII_TG3_AUXCTL_ACTL_TX_6DB 0x0400
-#define MII_TG3_AUXCTL_SHDWSEL_AUXCTL 0x0000
#define MII_TG3_AUX_STAT 0x19 /* auxiliary status register */
#define MII_TG3_AUX_STAT_LPASS 0x0004
@@ -2564,7 +2638,12 @@ struct tg3_hw_stats {
tg3_stat64_t nic_avoided_irqs;
tg3_stat64_t nic_tx_threshold_hit;
- u8 __reserved4[0xb00-0x9c0];
+ /* NOT a part of the hardware statistics block format.
+ * These stats are here as storage for tg3_periodic_fetch_stats().
+ */
+ tg3_stat64_t mbuf_lwm_thresh_hit;
+
+ u8 __reserved4[0xb00-0x9c8];
};
/* 'mapping' is superfluous as the chip does not write into
@@ -2696,6 +2775,8 @@ struct tg3_ethtool_stats {
u64 nic_irqs;
u64 nic_avoided_irqs;
u64 nic_tx_threshold_hit;
+
+ u64 mbuf_lwm_thresh_hit;
};
struct tg3_rx_prodring_set {
@@ -2745,6 +2826,86 @@ struct tg3_napi {
unsigned int irq_vec;
};
+enum TG3_FLAGS {
+ TG3_FLAG_TAGGED_STATUS = 0,
+ TG3_FLAG_TXD_MBOX_HWBUG,
+ TG3_FLAG_USE_LINKCHG_REG,
+ TG3_FLAG_ERROR_PROCESSED,
+ TG3_FLAG_ENABLE_ASF,
+ TG3_FLAG_ASPM_WORKAROUND,
+ TG3_FLAG_POLL_SERDES,
+ TG3_FLAG_MBOX_WRITE_REORDER,
+ TG3_FLAG_PCIX_TARGET_HWBUG,
+ TG3_FLAG_WOL_SPEED_100MB,
+ TG3_FLAG_WOL_ENABLE,
+ TG3_FLAG_EEPROM_WRITE_PROT,
+ TG3_FLAG_NVRAM,
+ TG3_FLAG_NVRAM_BUFFERED,
+ TG3_FLAG_SUPPORT_MSI,
+ TG3_FLAG_SUPPORT_MSIX,
+ TG3_FLAG_PCIX_MODE,
+ TG3_FLAG_PCI_HIGH_SPEED,
+ TG3_FLAG_PCI_32BIT,
+ TG3_FLAG_SRAM_USE_CONFIG,
+ TG3_FLAG_TX_RECOVERY_PENDING,
+ TG3_FLAG_WOL_CAP,
+ TG3_FLAG_JUMBO_RING_ENABLE,
+ TG3_FLAG_PAUSE_AUTONEG,
+ TG3_FLAG_CPMU_PRESENT,
+ TG3_FLAG_40BIT_DMA_BUG,
+ TG3_FLAG_BROKEN_CHECKSUMS,
+ TG3_FLAG_JUMBO_CAPABLE,
+ TG3_FLAG_CHIP_RESETTING,
+ TG3_FLAG_INIT_COMPLETE,
+ TG3_FLAG_RESTART_TIMER,
+ TG3_FLAG_TSO_BUG,
+ TG3_FLAG_IS_5788,
+ TG3_FLAG_MAX_RXPEND_64,
+ TG3_FLAG_TSO_CAPABLE,
+ TG3_FLAG_PCI_EXPRESS,
+ TG3_FLAG_ASF_NEW_HANDSHAKE,
+ TG3_FLAG_HW_AUTONEG,
+ TG3_FLAG_IS_NIC,
+ TG3_FLAG_FLASH,
+ TG3_FLAG_HW_TSO_1,
+ TG3_FLAG_5705_PLUS,
+ TG3_FLAG_5750_PLUS,
+ TG3_FLAG_HW_TSO_3,
+ TG3_FLAG_USING_MSI,
+ TG3_FLAG_USING_MSIX,
+ TG3_FLAG_ICH_WORKAROUND,
+ TG3_FLAG_5780_CLASS,
+ TG3_FLAG_HW_TSO_2,
+ TG3_FLAG_1SHOT_MSI,
+ TG3_FLAG_NO_FWARE_REPORTED,
+ TG3_FLAG_NO_NVRAM_ADDR_TRANS,
+ TG3_FLAG_ENABLE_APE,
+ TG3_FLAG_PROTECTED_NVRAM,
+ TG3_FLAG_5701_DMA_BUG,
+ TG3_FLAG_USE_PHYLIB,
+ TG3_FLAG_MDIOBUS_INITED,
+ TG3_FLAG_LRG_PROD_RING_CAP,
+ TG3_FLAG_RGMII_INBAND_DISABLE,
+ TG3_FLAG_RGMII_EXT_IBND_RX_EN,
+ TG3_FLAG_RGMII_EXT_IBND_TX_EN,
+ TG3_FLAG_CLKREQ_BUG,
+ TG3_FLAG_5755_PLUS,
+ TG3_FLAG_NO_NVRAM,
+ TG3_FLAG_ENABLE_RSS,
+ TG3_FLAG_ENABLE_TSS,
+ TG3_FLAG_4G_DMA_BNDRY_BUG,
+ TG3_FLAG_40BIT_DMA_LIMIT_BUG,
+ TG3_FLAG_SHORT_DMA_BUG,
+ TG3_FLAG_USE_JUMBO_BDFLAG,
+ TG3_FLAG_L1PLLPD_EN,
+ TG3_FLAG_57765_PLUS,
+ TG3_FLAG_APE_HAS_NCSI,
+ TG3_FLAG_5717_PLUS,
+
+ /* Add new flags before this comment and TG3_FLAG_NUMBER_OF_FLAGS */
+ TG3_FLAG_NUMBER_OF_FLAGS, /* Last entry in enum TG3_FLAGS */
+};
+
struct tg3 {
/* begin "general, frequently-used members" cacheline section */
@@ -2768,7 +2929,7 @@ struct tg3 {
/* SMP locking strategy:
*
* lock: Held during reset, PHY access, timer, and when
- * updating tg3_flags and tg3_flags2.
+ * updating tg3_flags.
*
* netif_tx_lock: Held during tg3_start_xmit. tg3_tx holds
* netif_tx_lock when it needs to call
@@ -2825,94 +2986,13 @@ struct tg3 {
struct tg3_ethtool_stats estats;
struct tg3_ethtool_stats estats_prev;
+ DECLARE_BITMAP(tg3_flags, TG3_FLAG_NUMBER_OF_FLAGS);
+
union {
unsigned long phy_crc_errors;
unsigned long last_event_jiffies;
};
- u32 tg3_flags;
-#define TG3_FLAG_TAGGED_STATUS 0x00000001
-#define TG3_FLAG_TXD_MBOX_HWBUG 0x00000002
-#define TG3_FLAG_RX_CHECKSUMS 0x00000004
-#define TG3_FLAG_USE_LINKCHG_REG 0x00000008
-#define TG3_FLAG_ENABLE_ASF 0x00000020
-#define TG3_FLAG_ASPM_WORKAROUND 0x00000040
-#define TG3_FLAG_POLL_SERDES 0x00000080
-#define TG3_FLAG_MBOX_WRITE_REORDER 0x00000100
-#define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200
-#define TG3_FLAG_WOL_SPEED_100MB 0x00000400
-#define TG3_FLAG_WOL_ENABLE 0x00000800
-#define TG3_FLAG_EEPROM_WRITE_PROT 0x00001000
-#define TG3_FLAG_NVRAM 0x00002000
-#define TG3_FLAG_NVRAM_BUFFERED 0x00004000
-#define TG3_FLAG_SUPPORT_MSI 0x00008000
-#define TG3_FLAG_SUPPORT_MSIX 0x00010000
-#define TG3_FLAG_SUPPORT_MSI_OR_MSIX (TG3_FLAG_SUPPORT_MSI | \
- TG3_FLAG_SUPPORT_MSIX)
-#define TG3_FLAG_PCIX_MODE 0x00020000
-#define TG3_FLAG_PCI_HIGH_SPEED 0x00040000
-#define TG3_FLAG_PCI_32BIT 0x00080000
-#define TG3_FLAG_SRAM_USE_CONFIG 0x00100000
-#define TG3_FLAG_TX_RECOVERY_PENDING 0x00200000
-#define TG3_FLAG_WOL_CAP 0x00400000
-#define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000
-#define TG3_FLAG_PAUSE_AUTONEG 0x02000000
-#define TG3_FLAG_CPMU_PRESENT 0x04000000
-#define TG3_FLAG_40BIT_DMA_BUG 0x08000000
-#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000
-#define TG3_FLAG_JUMBO_CAPABLE 0x20000000
-#define TG3_FLAG_CHIP_RESETTING 0x40000000
-#define TG3_FLAG_INIT_COMPLETE 0x80000000
- u32 tg3_flags2;
-#define TG3_FLG2_RESTART_TIMER 0x00000001
-#define TG3_FLG2_TSO_BUG 0x00000002
-#define TG3_FLG2_IS_5788 0x00000008
-#define TG3_FLG2_MAX_RXPEND_64 0x00000010
-#define TG3_FLG2_TSO_CAPABLE 0x00000020
-#define TG3_FLG2_PCI_EXPRESS 0x00000200
-#define TG3_FLG2_ASF_NEW_HANDSHAKE 0x00000400
-#define TG3_FLG2_HW_AUTONEG 0x00000800
-#define TG3_FLG2_IS_NIC 0x00001000
-#define TG3_FLG2_FLASH 0x00008000
-#define TG3_FLG2_HW_TSO_1 0x00010000
-#define TG3_FLG2_5705_PLUS 0x00040000
-#define TG3_FLG2_5750_PLUS 0x00080000
-#define TG3_FLG2_HW_TSO_3 0x00100000
-#define TG3_FLG2_USING_MSI 0x00200000
-#define TG3_FLG2_USING_MSIX 0x00400000
-#define TG3_FLG2_USING_MSI_OR_MSIX (TG3_FLG2_USING_MSI | \
- TG3_FLG2_USING_MSIX)
-#define TG3_FLG2_ICH_WORKAROUND 0x02000000
-#define TG3_FLG2_5780_CLASS 0x04000000
-#define TG3_FLG2_HW_TSO_2 0x08000000
-#define TG3_FLG2_HW_TSO (TG3_FLG2_HW_TSO_1 | \
- TG3_FLG2_HW_TSO_2 | \
- TG3_FLG2_HW_TSO_3)
-#define TG3_FLG2_1SHOT_MSI 0x10000000
-#define TG3_FLG2_NO_FWARE_REPORTED 0x40000000
- u32 tg3_flags3;
-#define TG3_FLG3_NO_NVRAM_ADDR_TRANS 0x00000001
-#define TG3_FLG3_ENABLE_APE 0x00000002
-#define TG3_FLG3_PROTECTED_NVRAM 0x00000004
-#define TG3_FLG3_5701_DMA_BUG 0x00000008
-#define TG3_FLG3_USE_PHYLIB 0x00000010
-#define TG3_FLG3_MDIOBUS_INITED 0x00000020
-#define TG3_FLG3_RGMII_INBAND_DISABLE 0x00000100
-#define TG3_FLG3_RGMII_EXT_IBND_RX_EN 0x00000200
-#define TG3_FLG3_RGMII_EXT_IBND_TX_EN 0x00000400
-#define TG3_FLG3_CLKREQ_BUG 0x00000800
-#define TG3_FLG3_5755_PLUS 0x00002000
-#define TG3_FLG3_NO_NVRAM 0x00004000
-#define TG3_FLG3_ENABLE_RSS 0x00020000
-#define TG3_FLG3_ENABLE_TSS 0x00040000
-#define TG3_FLG3_4G_DMA_BNDRY_BUG 0x00080000
-#define TG3_FLG3_40BIT_DMA_LIMIT_BUG 0x00100000
-#define TG3_FLG3_SHORT_DMA_BUG 0x00200000
-#define TG3_FLG3_USE_JUMBO_BDFLAG 0x00400000
-#define TG3_FLG3_L1PLLPD_EN 0x00800000
-#define TG3_FLG3_5717_PLUS 0x01000000
-#define TG3_FLG3_APE_HAS_NCSI 0x02000000
-
struct timer_list timer;
u16 timer_counter;
u16 timer_multiplier;
@@ -2983,6 +3063,7 @@ struct tg3 {
#define TG3_PHY_ID_BCM5718S 0xbc050ff0
#define TG3_PHY_ID_BCM57765 0x5c0d8a40
#define TG3_PHY_ID_BCM5719C 0x5c0d8a20
+#define TG3_PHY_ID_BCM5720C 0x5c0d8b60
#define TG3_PHY_ID_BCM5906 0xdc00ac40
#define TG3_PHY_ID_BCM8002 0x60010140
#define TG3_PHY_ID_INVALID 0xffffffff
@@ -3049,6 +3130,7 @@ struct tg3 {
int nvram_lock_cnt;
u32 nvram_size;
+#define TG3_NVRAM_SIZE_2KB 0x00000800
#define TG3_NVRAM_SIZE_64KB 0x00010000
#define TG3_NVRAM_SIZE_128KB 0x00020000
#define TG3_NVRAM_SIZE_256KB 0x00040000
@@ -3064,6 +3146,9 @@ struct tg3 {
#define JEDEC_SAIFUN 0x4f
#define JEDEC_SST 0xbf
+#define ATMEL_AT24C02_CHIP_SIZE TG3_NVRAM_SIZE_2KB
+#define ATMEL_AT24C02_PAGE_SIZE (8)
+
#define ATMEL_AT24C64_CHIP_SIZE TG3_NVRAM_SIZE_64KB
#define ATMEL_AT24C64_PAGE_SIZE (32)
diff --git a/drivers/net/tile/tilepro.c b/drivers/net/tile/tilepro.c
index 0825db6d883..1e980fdd9d7 100644
--- a/drivers/net/tile/tilepro.c
+++ b/drivers/net/tile/tilepro.c
@@ -1930,7 +1930,7 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)
unsigned int len = skb->len;
unsigned char *data = skb->data;
- unsigned int csum_start = skb->csum_start - skb_headroom(skb);
+ unsigned int csum_start = skb_checksum_start_offset(skb);
lepp_frag_t frags[LEPP_MAX_FRAGS];
diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
index 2bedc0ace81..1313aa1315f 100644
--- a/drivers/net/tokenring/madgemc.c
+++ b/drivers/net/tokenring/madgemc.c
@@ -727,7 +727,7 @@ static int __devexit madgemc_remove(struct device *device)
return 0;
}
-static short madgemc_adapter_ids[] __initdata = {
+static const short madgemc_adapter_ids[] __devinitconst = {
0x002d,
0x0000
};
diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
index 2684003b8ab..e3855aeb13d 100644
--- a/drivers/net/tokenring/olympic.c
+++ b/drivers/net/tokenring/olympic.c
@@ -86,6 +86,7 @@
#include <linux/timer.h>
#include <linux/in.h>
#include <linux/ioport.h>
+#include <linux/seq_file.h>
#include <linux/string.h>
#include <linux/proc_fs.h>
#include <linux/ptrace.h>
@@ -193,7 +194,7 @@ static void olympic_arb_cmd(struct net_device *dev);
static int olympic_change_mtu(struct net_device *dev, int mtu);
static void olympic_srb_bh(struct net_device *dev) ;
static void olympic_asb_bh(struct net_device *dev) ;
-static int olympic_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) ;
+static const struct file_operations olympic_proc_ops;
static const struct net_device_ops olympic_netdev_ops = {
.ndo_open = olympic_open,
@@ -272,7 +273,7 @@ static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device
char proc_name[20] ;
strcpy(proc_name,"olympic_") ;
strcat(proc_name,dev->name) ;
- create_proc_read_entry(proc_name,0,init_net.proc_net,olympic_proc_info,(void *)dev) ;
+ proc_create_data(proc_name, 0, init_net.proc_net, &olympic_proc_ops, dev);
printk("Olympic: Network Monitor information: /proc/%s\n",proc_name);
}
return 0 ;
@@ -1615,29 +1616,25 @@ static int olympic_change_mtu(struct net_device *dev, int mtu)
return 0 ;
}
-static int olympic_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
+static int olympic_proc_show(struct seq_file *m, void *v)
{
- struct net_device *dev = (struct net_device *)data ;
+ struct net_device *dev = m->private;
struct olympic_private *olympic_priv=netdev_priv(dev);
u8 __iomem *oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ;
u8 __iomem *opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ;
- int size = 0 ;
- int len=0;
- off_t begin=0;
- off_t pos=0;
u8 addr[6];
u8 addr2[6];
int i;
- size = sprintf(buffer,
+ seq_printf(m,
"IBM Pit/Pit-Phy/Olympic Chipset Token Ring Adapter %s\n",dev->name);
- size += sprintf(buffer+size, "\n%6s: Adapter Address : Node Address : Functional Addr\n",
+ seq_printf(m, "\n%6s: Adapter Address : Node Address : Functional Addr\n",
dev->name);
for (i = 0 ; i < 6 ; i++)
addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr) + i);
- size += sprintf(buffer+size, "%6s: %pM : %pM : %02x:%02x:%02x:%02x\n",
+ seq_printf(m, "%6s: %pM : %pM : %02x:%02x:%02x:%02x\n",
dev->name,
dev->dev_addr, addr,
readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)),
@@ -1645,9 +1642,9 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt
readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2),
readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3));
- size += sprintf(buffer+size, "\n%6s: Token Ring Parameters Table:\n", dev->name);
+ seq_printf(m, "\n%6s: Token Ring Parameters Table:\n", dev->name);
- size += sprintf(buffer+size, "%6s: Physical Addr : Up Node Address : Poll Address : AccPri : Auth Src : Att Code :\n",
+ seq_printf(m, "%6s: Physical Addr : Up Node Address : Poll Address : AccPri : Auth Src : Att Code :\n",
dev->name) ;
for (i = 0 ; i < 6 ; i++)
@@ -1655,7 +1652,7 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt
for (i = 0 ; i < 6 ; i++)
addr2[i] = readb(opt+offsetof(struct olympic_parameters_table, poll_addr) + i);
- size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x : %pM : %pM : %04x : %04x : %04x :\n",
+ seq_printf(m, "%6s: %02x:%02x:%02x:%02x : %pM : %pM : %04x : %04x : %04x :\n",
dev->name,
readb(opt+offsetof(struct olympic_parameters_table, phys_addr)),
readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+1),
@@ -1666,12 +1663,12 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt
swab16(readw(opt+offsetof(struct olympic_parameters_table, auth_source_class))),
swab16(readw(opt+offsetof(struct olympic_parameters_table, att_code))));
- size += sprintf(buffer+size, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n",
+ seq_printf(m, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n",
dev->name) ;
for (i = 0 ; i < 6 ; i++)
addr[i] = readb(opt+offsetof(struct olympic_parameters_table, source_addr) + i);
- size += sprintf(buffer+size, "%6s: %pM : %04x : %04x : %04x : %04x : %04x : %04x : \n",
+ seq_printf(m, "%6s: %pM : %04x : %04x : %04x : %04x : %04x : %04x : \n",
dev->name, addr,
swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_type))),
swab16(readw(opt+offsetof(struct olympic_parameters_table, major_vector))),
@@ -1680,12 +1677,12 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt
swab16(readw(opt+offsetof(struct olympic_parameters_table, mon_error))),
swab16(readw(opt+offsetof(struct olympic_parameters_table, frame_correl))));
- size += sprintf(buffer+size, "%6s: Beacon Details : Tx : Rx : NAUN Node Address : NAUN Node Phys : \n",
+ seq_printf(m, "%6s: Beacon Details : Tx : Rx : NAUN Node Address : NAUN Node Phys : \n",
dev->name) ;
for (i = 0 ; i < 6 ; i++)
addr[i] = readb(opt+offsetof(struct olympic_parameters_table, beacon_naun) + i);
- size += sprintf(buffer+size, "%6s: : %02x : %02x : %pM : %02x:%02x:%02x:%02x : \n",
+ seq_printf(m, "%6s: : %02x : %02x : %pM : %02x:%02x:%02x:%02x : \n",
dev->name,
swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_transmit))),
swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_receive))),
@@ -1695,19 +1692,21 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt
readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+2),
readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+3));
- len=size;
- pos=begin+size;
- if (pos<offset) {
- len=0;
- begin=pos;
- }
- *start=buffer+(offset-begin); /* Start of wanted data */
- len-=(offset-begin); /* Start slop */
- if(len>length)
- len=length; /* Ending slop */
- return len;
+ return 0;
}
+static int olympic_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, olympic_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations olympic_proc_ops = {
+ .open = olympic_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static void __devexit olympic_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev) ;
diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c
index 007d8e75666..092c3faa882 100644
--- a/drivers/net/tulip/21142.c
+++ b/drivers/net/tulip/21142.c
@@ -122,8 +122,8 @@ void t21142_start_nway(struct net_device *dev)
tp->nway = tp->mediasense = 1;
tp->nwayset = tp->lpar = 0;
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: Restarting 21143 autonegotiation, csr14=%08x\n",
- dev->name, csr14);
+ netdev_dbg(dev, "Restarting 21143 autonegotiation, csr14=%08x\n",
+ csr14);
iowrite32(0x0001, ioaddr + CSR13);
udelay(100);
iowrite32(csr14, ioaddr + CSR14);
@@ -206,14 +206,14 @@ void t21142_lnk_change(struct net_device *dev, int csr5)
#if 0 /* Restart shouldn't be needed. */
iowrite32(tp->csr6 | RxOn, ioaddr + CSR6);
if (tulip_debug > 2)
- printk(KERN_DEBUG "%s: Restarting Tx and Rx, CSR5 is %08x\n",
- dev->name, ioread32(ioaddr + CSR5));
+ netdev_dbg(dev, " Restarting Tx and Rx, CSR5 is %08x\n",
+ ioread32(ioaddr + CSR5));
#endif
tulip_start_rxtx(tp);
if (tulip_debug > 2)
- printk(KERN_DEBUG "%s: Setting CSR6 %08x/%x CSR12 %08x\n",
- dev->name, tp->csr6, ioread32(ioaddr + CSR6),
- ioread32(ioaddr + CSR12));
+ netdev_dbg(dev, " Setting CSR6 %08x/%x CSR12 %08x\n",
+ tp->csr6, ioread32(ioaddr + CSR6),
+ ioread32(ioaddr + CSR12));
} else if ((tp->nwayset && (csr5 & 0x08000000) &&
(dev->if_port == 3 || dev->if_port == 5) &&
(csr12 & 2) == 2) ||
diff --git a/drivers/net/tulip/Makefile b/drivers/net/tulip/Makefile
index 200cbf7c815..5e8be38b45b 100644
--- a/drivers/net/tulip/Makefile
+++ b/drivers/net/tulip/Makefile
@@ -2,6 +2,8 @@
# Makefile for the Linux "Tulip" family network device drivers.
#
+ccflags-$(CONFIG_NET_TULIP) := -DDEBUG
+
obj-$(CONFIG_PCMCIA_XIRCOM) += xircom_cb.o
obj-$(CONFIG_DM9102) += dmfe.o
obj-$(CONFIG_WINBOND_840) += winbond-840.o
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index b13c6b040be..e2f69235118 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -27,6 +27,8 @@
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define DRV_NAME "de2104x"
#define DRV_VERSION "0.7"
#define DRV_RELDATE "Mar 17, 2004"
@@ -51,7 +53,7 @@
/* These identify the driver base version and may not be removed. */
static char version[] =
-KERN_INFO DRV_NAME " PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n";
+"PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")";
MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
MODULE_DESCRIPTION("Intel/Digital 21040/1 series PCI Ethernet driver");
@@ -73,8 +75,6 @@ static int rx_copybreak = 100;
module_param (rx_copybreak, int, 0);
MODULE_PARM_DESC (rx_copybreak, "de2104x Breakpoint at which Rx packets are copied");
-#define PFX DRV_NAME ": "
-
#define DE_DEF_MSG_ENABLE (NETIF_MSG_DRV | \
NETIF_MSG_PROBE | \
NETIF_MSG_LINK | \
@@ -377,18 +377,16 @@ static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
static void de_rx_err_acct (struct de_private *de, unsigned rx_tail,
u32 status, u32 len)
{
- if (netif_msg_rx_err (de))
- printk (KERN_DEBUG
- "%s: rx err, slot %d status 0x%x len %d\n",
- de->dev->name, rx_tail, status, len);
+ netif_dbg(de, rx_err, de->dev,
+ "rx err, slot %d status 0x%x len %d\n",
+ rx_tail, status, len);
if ((status & 0x38000300) != 0x0300) {
/* Ingore earlier buffers. */
if ((status & 0xffff) != 0x7fff) {
- if (netif_msg_rx_err(de))
- dev_warn(&de->dev->dev,
- "Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
- status);
+ netif_warn(de, rx_err, de->dev,
+ "Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
+ status);
de->net_stats.rx_length_errors++;
}
} else if (status & RxError) {
@@ -435,10 +433,9 @@ static void de_rx (struct de_private *de)
copying_skb = (len <= rx_copybreak);
- if (unlikely(netif_msg_rx_status(de)))
- printk(KERN_DEBUG "%s: rx slot %d status 0x%x len %d copying? %d\n",
- de->dev->name, rx_tail, status, len,
- copying_skb);
+ netif_dbg(de, rx_status, de->dev,
+ "rx slot %d status 0x%x len %d copying? %d\n",
+ rx_tail, status, len, copying_skb);
buflen = copying_skb ? (len + RX_OFFSET) : de->rx_buf_sz;
copy_skb = dev_alloc_skb (buflen);
@@ -491,7 +488,7 @@ rx_next:
}
if (!rx_work)
- dev_warn(&de->dev->dev, "rx work limit reached\n");
+ netdev_warn(de->dev, "rx work limit reached\n");
de->rx_tail = rx_tail;
}
@@ -506,10 +503,9 @@ static irqreturn_t de_interrupt (int irq, void *dev_instance)
if ((!(status & (IntrOK|IntrErr))) || (status == 0xFFFF))
return IRQ_NONE;
- if (netif_msg_intr(de))
- printk(KERN_DEBUG "%s: intr, status %08x mode %08x desc %u/%u/%u\n",
- dev->name, status, dr32(MacMode),
- de->rx_tail, de->tx_head, de->tx_tail);
+ netif_dbg(de, intr, dev, "intr, status %08x mode %08x desc %u/%u/%u\n",
+ status, dr32(MacMode),
+ de->rx_tail, de->tx_head, de->tx_tail);
dw32(MacStatus, status);
@@ -534,9 +530,9 @@ static irqreturn_t de_interrupt (int irq, void *dev_instance)
pci_read_config_word(de->pdev, PCI_STATUS, &pci_status);
pci_write_config_word(de->pdev, PCI_STATUS, pci_status);
- dev_err(&de->dev->dev,
- "PCI bus error, status=%08x, PCI status=%04x\n",
- status, pci_status);
+ netdev_err(de->dev,
+ "PCI bus error, status=%08x, PCI status=%04x\n",
+ status, pci_status);
}
return IRQ_HANDLED;
@@ -572,9 +568,9 @@ static void de_tx (struct de_private *de)
if (status & LastFrag) {
if (status & TxError) {
- if (netif_msg_tx_err(de))
- printk(KERN_DEBUG "%s: tx err, status 0x%x\n",
- de->dev->name, status);
+ netif_dbg(de, tx_err, de->dev,
+ "tx err, status 0x%x\n",
+ status);
de->net_stats.tx_errors++;
if (status & TxOWC)
de->net_stats.tx_window_errors++;
@@ -587,9 +583,8 @@ static void de_tx (struct de_private *de)
} else {
de->net_stats.tx_packets++;
de->net_stats.tx_bytes += skb->len;
- if (netif_msg_tx_done(de))
- printk(KERN_DEBUG "%s: tx done, slot %d\n",
- de->dev->name, tx_tail);
+ netif_dbg(de, tx_done, de->dev,
+ "tx done, slot %d\n", tx_tail);
}
dev_kfree_skb_irq(skb);
}
@@ -646,9 +641,8 @@ static netdev_tx_t de_start_xmit (struct sk_buff *skb,
wmb();
de->tx_head = NEXT_TX(entry);
- if (netif_msg_tx_queued(de))
- printk(KERN_DEBUG "%s: tx queued, slot %d, skblen %d\n",
- dev->name, entry, skb->len);
+ netif_dbg(de, tx_queued, dev, "tx queued, slot %d, skblen %d\n",
+ entry, skb->len);
if (tx_free == 0)
netif_stop_queue(dev);
@@ -873,7 +867,7 @@ static void de_stop_rxtx (struct de_private *de)
udelay(100);
}
- dev_warn(&de->dev->dev, "timeout expired stopping DMA\n");
+ netdev_warn(de->dev, "timeout expired, stopping DMA\n");
}
static inline void de_start_rxtx (struct de_private *de)
@@ -907,9 +901,8 @@ static void de_link_up(struct de_private *de)
{
if (!netif_carrier_ok(de->dev)) {
netif_carrier_on(de->dev);
- if (netif_msg_link(de))
- dev_info(&de->dev->dev, "link up, media %s\n",
- media_name[de->media_type]);
+ netif_info(de, link, de->dev, "link up, media %s\n",
+ media_name[de->media_type]);
}
}
@@ -917,8 +910,7 @@ static void de_link_down(struct de_private *de)
{
if (netif_carrier_ok(de->dev)) {
netif_carrier_off(de->dev);
- if (netif_msg_link(de))
- dev_info(&de->dev->dev, "link down\n");
+ netif_info(de, link, de->dev, "link down\n");
}
}
@@ -928,8 +920,7 @@ static void de_set_media (struct de_private *de)
u32 macmode = dr32(MacMode);
if (de_is_running(de))
- dev_warn(&de->dev->dev,
- "chip is running while changing media!\n");
+ netdev_warn(de->dev, "chip is running while changing media!\n");
if (de->de21040)
dw32(CSR11, FULL_DUPLEX_MAGIC);
@@ -948,18 +939,13 @@ static void de_set_media (struct de_private *de)
else
macmode &= ~FullDuplex;
- if (netif_msg_link(de))
- dev_info(&de->dev->dev, "set link %s\n", media_name[media]);
- if (netif_msg_hw(de)) {
- dev_info(&de->dev->dev, "mode 0x%x, sia 0x%x,0x%x,0x%x,0x%x\n",
- dr32(MacMode), dr32(SIAStatus),
- dr32(CSR13), dr32(CSR14), dr32(CSR15));
-
- dev_info(&de->dev->dev,
- "set mode 0x%x, set sia 0x%x,0x%x,0x%x\n",
- macmode, de->media[media].csr13,
- de->media[media].csr14, de->media[media].csr15);
- }
+ netif_info(de, link, de->dev, "set link %s\n", media_name[media]);
+ netif_info(de, hw, de->dev, "mode 0x%x, sia 0x%x,0x%x,0x%x,0x%x\n",
+ dr32(MacMode), dr32(SIAStatus),
+ dr32(CSR13), dr32(CSR14), dr32(CSR15));
+ netif_info(de, hw, de->dev, "set mode 0x%x, set sia 0x%x,0x%x,0x%x\n",
+ macmode, de->media[media].csr13,
+ de->media[media].csr14, de->media[media].csr15);
if (macmode != dr32(MacMode))
dw32(MacMode, macmode);
}
@@ -996,9 +982,8 @@ static void de21040_media_timer (unsigned long data)
if (!netif_carrier_ok(dev))
de_link_up(de);
else
- if (netif_msg_timer(de))
- dev_info(&dev->dev, "%s link ok, status %x\n",
- media_name[de->media_type], status);
+ netif_info(de, timer, dev, "%s link ok, status %x\n",
+ media_name[de->media_type], status);
return;
}
@@ -1025,9 +1010,8 @@ no_link_yet:
de->media_timer.expires = jiffies + DE_TIMER_NO_LINK;
add_timer(&de->media_timer);
- if (netif_msg_timer(de))
- dev_info(&dev->dev, "no link, trying media %s, status %x\n",
- media_name[de->media_type], status);
+ netif_info(de, timer, dev, "no link, trying media %s, status %x\n",
+ media_name[de->media_type], status);
}
static unsigned int de_ok_to_advertise (struct de_private *de, u32 new_media)
@@ -1085,11 +1069,10 @@ static void de21041_media_timer (unsigned long data)
if (!netif_carrier_ok(dev))
de_link_up(de);
else
- if (netif_msg_timer(de))
- dev_info(&dev->dev,
- "%s link ok, mode %x status %x\n",
- media_name[de->media_type],
- dr32(MacMode), status);
+ netif_info(de, timer, dev,
+ "%s link ok, mode %x status %x\n",
+ media_name[de->media_type],
+ dr32(MacMode), status);
return;
}
@@ -1163,9 +1146,8 @@ no_link_yet:
de->media_timer.expires = jiffies + DE_TIMER_NO_LINK;
add_timer(&de->media_timer);
- if (netif_msg_timer(de))
- dev_info(&dev->dev, "no link, trying media %s, status %x\n",
- media_name[de->media_type], status);
+ netif_info(de, timer, dev, "no link, trying media %s, status %x\n",
+ media_name[de->media_type], status);
}
static void de_media_interrupt (struct de_private *de, u32 status)
@@ -1401,14 +1383,13 @@ static int de_open (struct net_device *dev)
struct de_private *de = netdev_priv(dev);
int rc;
- if (netif_msg_ifup(de))
- printk(KERN_DEBUG "%s: enabling interface\n", dev->name);
+ netif_dbg(de, ifup, dev, "enabling interface\n");
de->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
rc = de_alloc_rings(de);
if (rc) {
- dev_err(&dev->dev, "ring allocation failure, err=%d\n", rc);
+ netdev_err(dev, "ring allocation failure, err=%d\n", rc);
return rc;
}
@@ -1416,14 +1397,14 @@ static int de_open (struct net_device *dev)
rc = request_irq(dev->irq, de_interrupt, IRQF_SHARED, dev->name, dev);
if (rc) {
- dev_err(&dev->dev, "IRQ %d request failure, err=%d\n",
- dev->irq, rc);
+ netdev_err(dev, "IRQ %d request failure, err=%d\n",
+ dev->irq, rc);
goto err_out_free;
}
rc = de_init_hw(de);
if (rc) {
- dev_err(&dev->dev, "h/w init failure, err=%d\n", rc);
+ netdev_err(dev, "h/w init failure, err=%d\n", rc);
goto err_out_free_irq;
}
@@ -1444,8 +1425,7 @@ static int de_close (struct net_device *dev)
struct de_private *de = netdev_priv(dev);
unsigned long flags;
- if (netif_msg_ifdown(de))
- printk(KERN_DEBUG "%s: disabling interface\n", dev->name);
+ netif_dbg(de, ifdown, dev, "disabling interface\n");
del_timer_sync(&de->media_timer);
@@ -1466,9 +1446,9 @@ static void de_tx_timeout (struct net_device *dev)
{
struct de_private *de = netdev_priv(dev);
- printk(KERN_DEBUG "%s: NIC status %08x mode %08x sia %08x desc %u/%u/%u\n",
- dev->name, dr32(MacStatus), dr32(MacMode), dr32(SIAStatus),
- de->rx_tail, de->tx_head, de->tx_tail);
+ netdev_dbg(dev, "NIC status %08x mode %08x sia %08x desc %u/%u/%u\n",
+ dr32(MacStatus), dr32(MacMode), dr32(SIAStatus),
+ de->rx_tail, de->tx_head, de->tx_tail);
del_timer_sync(&de->media_timer);
@@ -1518,18 +1498,17 @@ static int __de_get_settings(struct de_private *de, struct ethtool_cmd *ecmd)
switch (de->media_type) {
case DE_MEDIA_AUI:
ecmd->port = PORT_AUI;
- ecmd->speed = 5;
break;
case DE_MEDIA_BNC:
ecmd->port = PORT_BNC;
- ecmd->speed = 2;
break;
default:
ecmd->port = PORT_TP;
- ecmd->speed = SPEED_10;
break;
}
+ ethtool_cmd_speed_set(ecmd, 10);
+
if (dr32(MacMode) & FullDuplex)
ecmd->duplex = DUPLEX_FULL;
else
@@ -1550,9 +1529,7 @@ static int __de_set_settings(struct de_private *de, struct ethtool_cmd *ecmd)
u32 new_media;
unsigned int media_lock;
- if (ecmd->speed != SPEED_10 && ecmd->speed != 5 && ecmd->speed != 2)
- return -EINVAL;
- if (de->de21040 && ecmd->speed == 2)
+ if (ethtool_cmd_speed(ecmd) != 10)
return -EINVAL;
if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
return -EINVAL;
@@ -1696,9 +1673,8 @@ static int de_nway_reset(struct net_device *dev)
status = dr32(SIAStatus);
dw32(SIAStatus, (status & ~NWayState) | NWayRestart);
- if (netif_msg_link(de))
- dev_info(&de->dev->dev, "link nway restart, status %x,%x\n",
- status, dr32(SIAStatus));
+ netif_info(de, link, dev, "link nway restart, status %x,%x\n",
+ status, dr32(SIAStatus));
return 0;
}
@@ -1743,7 +1719,8 @@ static void __devinit de21040_get_mac_address (struct de_private *de)
de->dev->dev_addr[i] = value;
udelay(1);
if (boguscnt <= 0)
- pr_warning(PFX "timeout reading 21040 MAC address byte %u\n", i);
+ pr_warn("timeout reading 21040 MAC address byte %u\n",
+ i);
}
}
@@ -1929,8 +1906,10 @@ static void __devinit de21041_get_srom_info (struct de_private *de)
de->media[idx].csr14,
de->media[idx].csr15);
- } else if (netif_msg_probe(de))
- pr_cont("\n");
+ } else {
+ if (netif_msg_probe(de))
+ pr_cont("\n");
+ }
if (bufp > ((void *)&ee_data[DE_EEPROM_SIZE - 3]))
break;
@@ -1999,7 +1978,7 @@ static int __devinit de_init_one (struct pci_dev *pdev,
#ifndef MODULE
if (board_idx == 0)
- printk("%s", version);
+ pr_info("%s\n", version);
#endif
/* allocate a new ethernet device structure, and fill in defaults */
@@ -2041,7 +2020,7 @@ static int __devinit de_init_one (struct pci_dev *pdev,
/* check for invalid IRQ value */
if (pdev->irq < 2) {
rc = -EIO;
- pr_err(PFX "invalid irq (%d) for pci dev %s\n",
+ pr_err("invalid irq (%d) for pci dev %s\n",
pdev->irq, pci_name(pdev));
goto err_out_res;
}
@@ -2052,12 +2031,12 @@ static int __devinit de_init_one (struct pci_dev *pdev,
pciaddr = pci_resource_start(pdev, 1);
if (!pciaddr) {
rc = -EIO;
- pr_err(PFX "no MMIO resource for pci dev %s\n", pci_name(pdev));
+ pr_err("no MMIO resource for pci dev %s\n", pci_name(pdev));
goto err_out_res;
}
if (pci_resource_len(pdev, 1) < DE_REGS_SIZE) {
rc = -EIO;
- pr_err(PFX "MMIO resource (%llx) too small on pci dev %s\n",
+ pr_err("MMIO resource (%llx) too small on pci dev %s\n",
(unsigned long long)pci_resource_len(pdev, 1),
pci_name(pdev));
goto err_out_res;
@@ -2067,7 +2046,7 @@ static int __devinit de_init_one (struct pci_dev *pdev,
regs = ioremap_nocache(pciaddr, DE_REGS_SIZE);
if (!regs) {
rc = -EIO;
- pr_err(PFX "Cannot map PCI MMIO (%llx@%lx) on pci dev %s\n",
+ pr_err("Cannot map PCI MMIO (%llx@%lx) on pci dev %s\n",
(unsigned long long)pci_resource_len(pdev, 1),
pciaddr, pci_name(pdev));
goto err_out_res;
@@ -2080,7 +2059,7 @@ static int __devinit de_init_one (struct pci_dev *pdev,
/* make sure hardware is not running */
rc = de_reset_mac(de);
if (rc) {
- pr_err(PFX "Cannot reset MAC, pci dev %s\n", pci_name(pdev));
+ pr_err("Cannot reset MAC, pci dev %s\n", pci_name(pdev));
goto err_out_iomap;
}
@@ -2100,11 +2079,11 @@ static int __devinit de_init_one (struct pci_dev *pdev,
goto err_out_iomap;
/* print info about board and interface just registered */
- dev_info(&dev->dev, "%s at 0x%lx, %pM, IRQ %d\n",
- de->de21040 ? "21040" : "21041",
- dev->base_addr,
- dev->dev_addr,
- dev->irq);
+ netdev_info(dev, "%s at 0x%lx, %pM, IRQ %d\n",
+ de->de21040 ? "21040" : "21041",
+ dev->base_addr,
+ dev->dev_addr,
+ dev->irq);
pci_set_drvdata(pdev, dev);
@@ -2192,7 +2171,7 @@ static int de_resume (struct pci_dev *pdev)
if (!netif_running(dev))
goto out_attach;
if ((retval = pci_enable_device(pdev))) {
- dev_err(&dev->dev, "pci_enable_device failed in resume\n");
+ netdev_err(dev, "pci_enable_device failed in resume\n");
goto out;
}
pci_set_master(pdev);
@@ -2221,7 +2200,7 @@ static struct pci_driver de_driver = {
static int __init de_init (void)
{
#ifdef MODULE
- printk("%s", version);
+ pr_info("%s\n", version);
#endif
return pci_register_driver(&de_driver);
}
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index efaa1d69b72..45144d5bd11 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -1995,7 +1995,7 @@ SetMulticastFilter(struct net_device *dev)
static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST;
-static int __init de4x5_eisa_probe (struct device *gendev)
+static int __devinit de4x5_eisa_probe (struct device *gendev)
{
struct eisa_device *edev;
u_long iobase;
@@ -2097,7 +2097,7 @@ static int __devexit de4x5_eisa_remove (struct device *device)
return 0;
}
-static struct eisa_device_id de4x5_eisa_ids[] = {
+static const struct eisa_device_id de4x5_eisa_ids[] __devinitconst = {
{ "DEC4250", 0 }, /* 0 is the board name index... */
{ "" }
};
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index fb07f48910a..46851273196 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -295,8 +295,7 @@ enum dmfe_CR6_bits {
/* Global variable declaration ----------------------------- */
static int __devinitdata printed_version;
static const char version[] __devinitconst =
- KERN_INFO DRV_NAME ": Davicom DM9xxx net driver, version "
- DRV_VERSION " (" DRV_RELDATE ")\n";
+ "Davicom DM9xxx net driver, version " DRV_VERSION " (" DRV_RELDATE ")";
static int dmfe_debug;
static unsigned char dmfe_media_mode = DMFE_AUTO;
@@ -381,7 +380,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
DMFE_DBUG(0, "dmfe_init_one()", 0);
if (!printed_version++)
- printk(version);
+ pr_info("%s\n", version);
/*
* SPARC on-board DM910x chips should be handled by the main
@@ -406,7 +405,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
SET_NETDEV_DEV(dev, &pdev->dev);
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
- pr_warning("32-bit PCI DMA not available\n");
+ pr_warn("32-bit PCI DMA not available\n");
err = -ENODEV;
goto err_out_free;
}
@@ -2203,7 +2202,7 @@ static int __init dmfe_init_module(void)
{
int rc;
- printk(version);
+ pr_info("%s\n", version);
printed_version = 1;
DMFE_DBUG(0, "init_module() ", debug);
diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c
index 296486bf095..fa5eee925f2 100644
--- a/drivers/net/tulip/eeprom.c
+++ b/drivers/net/tulip/eeprom.c
@@ -222,8 +222,8 @@ subsequent_board:
/* there is no phy information, don't even try to build mtable */
if (count == 0) {
if (tulip_debug > 0)
- pr_warning("%s: no phy info, aborting mtable build\n",
- dev->name);
+ pr_warn("%s: no phy info, aborting mtable build\n",
+ dev->name);
return;
}
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
index 0013642903e..5350d753e0f 100644
--- a/drivers/net/tulip/interrupt.c
+++ b/drivers/net/tulip/interrupt.c
@@ -125,12 +125,12 @@ int tulip_poll(struct napi_struct *napi, int budget)
#endif
if (tulip_debug > 4)
- printk(KERN_DEBUG " In tulip_rx(), entry %d %08x\n",
- entry, tp->rx_ring[entry].status);
+ netdev_dbg(dev, " In tulip_rx(), entry %d %08x\n",
+ entry, tp->rx_ring[entry].status);
do {
if (ioread32(tp->base_addr + CSR5) == 0xffffffff) {
- printk(KERN_DEBUG " In tulip_poll(), hardware disappeared\n");
+ netdev_dbg(dev, " In tulip_poll(), hardware disappeared\n");
break;
}
/* Acknowledge current RX interrupt sources. */
@@ -145,9 +145,9 @@ int tulip_poll(struct napi_struct *napi, int budget)
if (tp->dirty_rx + RX_RING_SIZE == tp->cur_rx)
break;
- if (tulip_debug > 5)
- printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %08x\n",
- dev->name, entry, status);
+ if (tulip_debug > 5)
+ netdev_dbg(dev, "In tulip_rx(), entry %d %08x\n",
+ entry, status);
if (++work_done >= budget)
goto not_done;
@@ -184,9 +184,9 @@ int tulip_poll(struct napi_struct *napi, int budget)
}
} else {
/* There was a fatal error. */
- if (tulip_debug > 2)
- printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n",
- dev->name, status);
+ if (tulip_debug > 2)
+ netdev_dbg(dev, "Receive error, Rx status %08x\n",
+ status);
dev->stats.rx_errors++; /* end of a packet.*/
if (pkt_len > 1518 ||
(status & RxDescRunt))
@@ -367,16 +367,16 @@ static int tulip_rx(struct net_device *dev)
int received = 0;
if (tulip_debug > 4)
- printk(KERN_DEBUG " In tulip_rx(), entry %d %08x\n",
- entry, tp->rx_ring[entry].status);
+ netdev_dbg(dev, "In tulip_rx(), entry %d %08x\n",
+ entry, tp->rx_ring[entry].status);
/* If we own the next entry, it is a new packet. Send it up. */
while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
s32 status = le32_to_cpu(tp->rx_ring[entry].status);
short pkt_len;
if (tulip_debug > 5)
- printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %08x\n",
- dev->name, entry, status);
+ netdev_dbg(dev, "In tulip_rx(), entry %d %08x\n",
+ entry, status);
if (--rx_work_limit < 0)
break;
@@ -404,16 +404,16 @@ static int tulip_rx(struct net_device *dev)
/* Ingore earlier buffers. */
if ((status & 0xffff) != 0x7fff) {
if (tulip_debug > 1)
- dev_warn(&dev->dev,
- "Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
- status);
+ netdev_warn(dev,
+ "Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
+ status);
dev->stats.rx_length_errors++;
}
} else {
/* There was a fatal error. */
if (tulip_debug > 2)
- printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n",
- dev->name, status);
+ netdev_dbg(dev, "Receive error, Rx status %08x\n",
+ status);
dev->stats.rx_errors++; /* end of a packet.*/
if (pkt_len > 1518 ||
(status & RxDescRunt))
@@ -573,8 +573,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
#endif /* CONFIG_TULIP_NAPI */
if (tulip_debug > 4)
- printk(KERN_DEBUG "%s: interrupt csr5=%#8.8x new csr5=%#8.8x\n",
- dev->name, csr5, ioread32(ioaddr + CSR5));
+ netdev_dbg(dev, "interrupt csr5=%#8.8x new csr5=%#8.8x\n",
+ csr5, ioread32(ioaddr + CSR5));
if (csr5 & (TxNoBuf | TxDied | TxIntr | TimerInt)) {
@@ -605,8 +605,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
/* There was an major error, log it. */
#ifndef final_version
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: Transmit error, Tx status %08x\n",
- dev->name, status);
+ netdev_dbg(dev, "Transmit error, Tx status %08x\n",
+ status);
#endif
dev->stats.tx_errors++;
if (status & 0x4104)
@@ -804,8 +804,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
}
if (tulip_debug > 4)
- printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#04x\n",
- dev->name, ioread32(ioaddr + CSR5));
+ netdev_dbg(dev, "exiting interrupt, csr5=%#04x\n",
+ ioread32(ioaddr + CSR5));
return IRQ_HANDLED;
}
diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c
index a0c770ee4b6..4bd13922875 100644
--- a/drivers/net/tulip/media.c
+++ b/drivers/net/tulip/media.c
@@ -182,8 +182,8 @@ void tulip_select_media(struct net_device *dev, int startup)
switch (mleaf->type) {
case 0: /* 21140 non-MII xcvr. */
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: Using a 21140 non-MII transceiver with control setting %02x\n",
- dev->name, p[1]);
+ netdev_dbg(dev, "Using a 21140 non-MII transceiver with control setting %02x\n",
+ p[1]);
dev->if_port = p[0];
if (startup)
iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12);
@@ -204,15 +204,14 @@ void tulip_select_media(struct net_device *dev, int startup)
struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
unsigned char *rst = rleaf->leafdata;
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: Resetting the transceiver\n",
- dev->name);
+ netdev_dbg(dev, "Resetting the transceiver\n");
for (i = 0; i < rst[0]; i++)
iowrite32(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
}
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: 21143 non-MII %s transceiver control %04x/%04x\n",
- dev->name, medianame[dev->if_port],
- setup[0], setup[1]);
+ netdev_dbg(dev, "21143 non-MII %s transceiver control %04x/%04x\n",
+ medianame[dev->if_port],
+ setup[0], setup[1]);
if (p[0] & 0x40) { /* SIA (CSR13-15) setup values are provided. */
csr13val = setup[0];
csr14val = setup[1];
@@ -239,8 +238,8 @@ void tulip_select_media(struct net_device *dev, int startup)
if (startup) iowrite32(csr13val, ioaddr + CSR13);
}
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: Setting CSR15 to %08x/%08x\n",
- dev->name, csr15dir, csr15val);
+ netdev_dbg(dev, "Setting CSR15 to %08x/%08x\n",
+ csr15dir, csr15val);
if (mleaf->type == 4)
new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18);
else
@@ -316,9 +315,9 @@ void tulip_select_media(struct net_device *dev, int startup)
if (tp->mii_advertise == 0)
tp->mii_advertise = tp->advertising[phy_num];
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: Advertising %04x on MII %d\n",
- dev->name, tp->mii_advertise,
- tp->phys[phy_num]);
+ netdev_dbg(dev, " Advertising %04x on MII %d\n",
+ tp->mii_advertise,
+ tp->phys[phy_num]);
tulip_mdio_write(dev, tp->phys[phy_num], 4, tp->mii_advertise);
}
break;
@@ -335,8 +334,7 @@ void tulip_select_media(struct net_device *dev, int startup)
struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
unsigned char *rst = rleaf->leafdata;
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: Resetting the transceiver\n",
- dev->name);
+ netdev_dbg(dev, "Resetting the transceiver\n");
for (i = 0; i < rst[0]; i++)
iowrite32(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
}
@@ -344,20 +342,21 @@ void tulip_select_media(struct net_device *dev, int startup)
break;
}
default:
- printk(KERN_DEBUG "%s: Invalid media table selection %d\n",
- dev->name, mleaf->type);
+ netdev_dbg(dev, " Invalid media table selection %d\n",
+ mleaf->type);
new_csr6 = 0x020E0000;
}
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: Using media type %s, CSR12 is %02x\n",
- dev->name, medianame[dev->if_port],
+ netdev_dbg(dev, "Using media type %s, CSR12 is %02x\n",
+ medianame[dev->if_port],
ioread32(ioaddr + CSR12) & 0xff);
} else if (tp->chip_id == LC82C168) {
if (startup && ! tp->medialock)
dev->if_port = tp->mii_cnt ? 11 : 0;
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: PNIC PHY status is %3.3x, media %s\n",
- dev->name, ioread32(ioaddr + 0xB8), medianame[dev->if_port]);
+ netdev_dbg(dev, "PNIC PHY status is %3.3x, media %s\n",
+ ioread32(ioaddr + 0xB8),
+ medianame[dev->if_port]);
if (tp->mii_cnt) {
new_csr6 = 0x810C0000;
iowrite32(0x0001, ioaddr + CSR15);
@@ -388,9 +387,9 @@ void tulip_select_media(struct net_device *dev, int startup)
} else
new_csr6 = 0x03860000;
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: No media description table, assuming %s transceiver, CSR12 %02x\n",
- dev->name, medianame[dev->if_port],
- ioread32(ioaddr + CSR12));
+ netdev_dbg(dev, "No media description table, assuming %s transceiver, CSR12 %02x\n",
+ medianame[dev->if_port],
+ ioread32(ioaddr + CSR12));
}
tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0);
@@ -504,8 +503,8 @@ void __devinit tulip_find_mii (struct net_device *dev, int board_idx)
/* Fixup for DLink with miswired PHY. */
if (mii_advert != to_advert) {
- printk(KERN_DEBUG "tulip%d: Advertising %04x on PHY %d, previously advertising %04x\n",
- board_idx, to_advert, phy, mii_advert);
+ pr_debug("tulip%d: Advertising %04x on PHY %d, previously advertising %04x\n",
+ board_idx, to_advert, phy, mii_advert);
tulip_mdio_write (dev, phy, 4, to_advert);
}
diff --git a/drivers/net/tulip/pnic.c b/drivers/net/tulip/pnic.c
index a63e64b6863..aa4d9dad039 100644
--- a/drivers/net/tulip/pnic.c
+++ b/drivers/net/tulip/pnic.c
@@ -40,8 +40,8 @@ void pnic_do_nway(struct net_device *dev)
new_csr6 |= 0x00000200;
}
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: PNIC autonegotiated status %08x, %s\n",
- dev->name, phy_reg, medianame[dev->if_port]);
+ netdev_dbg(dev, "PNIC autonegotiated status %08x, %s\n",
+ phy_reg, medianame[dev->if_port]);
if (tp->csr6 != new_csr6) {
tp->csr6 = new_csr6;
/* Restart Tx */
@@ -58,8 +58,8 @@ void pnic_lnk_change(struct net_device *dev, int csr5)
int phy_reg = ioread32(ioaddr + 0xB8);
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: PNIC link changed state %08x, CSR5 %08x\n",
- dev->name, phy_reg, csr5);
+ netdev_dbg(dev, "PNIC link changed state %08x, CSR5 %08x\n",
+ phy_reg, csr5);
if (ioread32(ioaddr + CSR5) & TPLnkFail) {
iowrite32((ioread32(ioaddr + CSR7) & ~TPLnkFail) | TPLnkPass, ioaddr + CSR7);
/* If we use an external MII, then we mustn't use the
@@ -114,8 +114,8 @@ void pnic_timer(unsigned long data)
int csr5 = ioread32(ioaddr + CSR5);
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: PNIC timer PHY status %08x, %s CSR5 %08x\n",
- dev->name, phy_reg, medianame[dev->if_port], csr5);
+ netdev_dbg(dev, "PNIC timer PHY status %08x, %s CSR5 %08x\n",
+ phy_reg, medianame[dev->if_port], csr5);
if (phy_reg & 0x04000000) { /* Remote link fault */
iowrite32(0x0201F078, ioaddr + 0xB8);
next_tick = 1*HZ;
@@ -125,11 +125,11 @@ void pnic_timer(unsigned long data)
next_tick = 60*HZ;
} else if (csr5 & TPLnkFail) { /* 100baseTx link beat */
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: %s link beat failed, CSR12 %04x, CSR5 %08x, PHY %03x\n",
- dev->name, medianame[dev->if_port],
- csr12,
- ioread32(ioaddr + CSR5),
- ioread32(ioaddr + 0xB8));
+ netdev_dbg(dev, "%s link beat failed, CSR12 %04x, CSR5 %08x, PHY %03x\n",
+ medianame[dev->if_port],
+ csr12,
+ ioread32(ioaddr + CSR5),
+ ioread32(ioaddr + 0xB8));
next_tick = 3*HZ;
if (tp->medialock) {
} else if (tp->nwayset && (dev->if_port & 1)) {
diff --git a/drivers/net/tulip/pnic2.c b/drivers/net/tulip/pnic2.c
index 4690c8e6920..93358ee4d83 100644
--- a/drivers/net/tulip/pnic2.c
+++ b/drivers/net/tulip/pnic2.c
@@ -125,8 +125,8 @@ void pnic2_start_nway(struct net_device *dev)
csr14 |= 0x00001184;
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: Restarting PNIC2 autonegotiation, csr14=%08x\n",
- dev->name, csr14);
+ netdev_dbg(dev, "Restarting PNIC2 autonegotiation, csr14=%08x\n",
+ csr14);
/* tell pnic2_lnk_change we are doing an nway negotiation */
dev->if_port = 0;
@@ -137,8 +137,7 @@ void pnic2_start_nway(struct net_device *dev)
tp->csr6 = ioread32(ioaddr + CSR6);
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: On Entry to Nway, csr6=%08x\n",
- dev->name, tp->csr6);
+ netdev_dbg(dev, "On Entry to Nway, csr6=%08x\n", tp->csr6);
/* mask off any bits not to touch
* comment at top of file explains mask value
@@ -271,9 +270,10 @@ void pnic2_lnk_change(struct net_device *dev, int csr5)
iowrite32(1, ioaddr + CSR13);
if (tulip_debug > 2)
- printk(KERN_DEBUG "%s: Setting CSR6 %08x/%x CSR12 %08x\n",
- dev->name, tp->csr6,
- ioread32(ioaddr + CSR6), ioread32(ioaddr + CSR12));
+ netdev_dbg(dev, "Setting CSR6 %08x/%x CSR12 %08x\n",
+ tp->csr6,
+ ioread32(ioaddr + CSR6),
+ ioread32(ioaddr + CSR12));
/* now the following actually writes out the
* new csr6 values
@@ -324,7 +324,7 @@ void pnic2_lnk_change(struct net_device *dev, int csr5)
/* Link blew? Maybe restart NWay. */
if (tulip_debug > 2)
- printk(KERN_DEBUG "%s: Ugh! Link blew?\n", dev->name);
+ netdev_dbg(dev, "Ugh! Link blew?\n");
del_timer_sync(&tp->timer);
pnic2_start_nway(dev);
diff --git a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c
index 36c2725ec88..2017faf2d0e 100644
--- a/drivers/net/tulip/timer.c
+++ b/drivers/net/tulip/timer.c
@@ -28,11 +28,11 @@ void tulip_media_task(struct work_struct *work)
unsigned long flags;
if (tulip_debug > 2) {
- printk(KERN_DEBUG "%s: Media selection tick, %s, status %08x mode %08x SIA %08x %08x %08x %08x\n",
- dev->name, medianame[dev->if_port],
- ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR6),
- csr12, ioread32(ioaddr + CSR13),
- ioread32(ioaddr + CSR14), ioread32(ioaddr + CSR15));
+ netdev_dbg(dev, "Media selection tick, %s, status %08x mode %08x SIA %08x %08x %08x %08x\n",
+ medianame[dev->if_port],
+ ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR6),
+ csr12, ioread32(ioaddr + CSR13),
+ ioread32(ioaddr + CSR14), ioread32(ioaddr + CSR15));
}
switch (tp->chip_id) {
case DC21140:
@@ -48,9 +48,9 @@ void tulip_media_task(struct work_struct *work)
Assume this a generic MII or SYM transceiver. */
next_tick = 60*HZ;
if (tulip_debug > 2)
- printk(KERN_DEBUG "%s: network media monitor CSR6 %08x CSR12 0x%02x\n",
- dev->name,
- ioread32(ioaddr + CSR6), csr12 & 0xff);
+ netdev_dbg(dev, "network media monitor CSR6 %08x CSR12 0x%02x\n",
+ ioread32(ioaddr + CSR6),
+ csr12 & 0xff);
break;
}
mleaf = &tp->mtable->mleaf[tp->cur_index];
@@ -62,8 +62,8 @@ void tulip_media_task(struct work_struct *work)
s8 bitnum = p[offset];
if (p[offset+1] & 0x80) {
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: Transceiver monitor tick CSR12=%#02x, no media sense\n",
- dev->name, csr12);
+ netdev_dbg(dev, "Transceiver monitor tick CSR12=%#02x, no media sense\n",
+ csr12);
if (mleaf->type == 4) {
if (mleaf->media == 3 && (csr12 & 0x02))
goto select_next_media;
@@ -71,17 +71,16 @@ void tulip_media_task(struct work_struct *work)
break;
}
if (tulip_debug > 2)
- printk(KERN_DEBUG "%s: Transceiver monitor tick: CSR12=%#02x bit %d is %d, expecting %d\n",
- dev->name, csr12, (bitnum >> 1) & 7,
- (csr12 & (1 << ((bitnum >> 1) & 7))) != 0,
- (bitnum >= 0));
+ netdev_dbg(dev, "Transceiver monitor tick: CSR12=%#02x bit %d is %d, expecting %d\n",
+ csr12, (bitnum >> 1) & 7,
+ (csr12 & (1 << ((bitnum >> 1) & 7))) != 0,
+ (bitnum >= 0));
/* Check that the specified bit has the proper value. */
if ((bitnum < 0) !=
((csr12 & (1 << ((bitnum >> 1) & 7))) != 0)) {
if (tulip_debug > 2)
- printk(KERN_DEBUG "%s: Link beat detected for %s\n",
- dev->name,
- medianame[mleaf->media & MEDIA_MASK]);
+ netdev_dbg(dev, "Link beat detected for %s\n",
+ medianame[mleaf->media & MEDIA_MASK]);
if ((p[2] & 0x61) == 0x01) /* Bogus Znyx board. */
goto actually_mii;
netif_carrier_on(dev);
@@ -99,10 +98,9 @@ void tulip_media_task(struct work_struct *work)
if (tulip_media_cap[dev->if_port] & MediaIsFD)
goto select_next_media; /* Skip FD entries. */
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: No link beat on media %s, trying transceiver type %s\n",
- dev->name,
- medianame[mleaf->media & MEDIA_MASK],
- medianame[tp->mtable->mleaf[tp->cur_index].media]);
+ netdev_dbg(dev, "No link beat on media %s, trying transceiver type %s\n",
+ medianame[mleaf->media & MEDIA_MASK],
+ medianame[tp->mtable->mleaf[tp->cur_index].media]);
tulip_select_media(dev, 0);
/* Restart the transmit process. */
tulip_restart_rxtx(tp);
@@ -166,10 +164,9 @@ void comet_timer(unsigned long data)
int next_tick = 60*HZ;
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: Comet link status %04x partner capability %04x\n",
- dev->name,
- tulip_mdio_read(dev, tp->phys[0], 1),
- tulip_mdio_read(dev, tp->phys[0], 5));
+ netdev_dbg(dev, "Comet link status %04x partner capability %04x\n",
+ tulip_mdio_read(dev, tp->phys[0], 1),
+ tulip_mdio_read(dev, tp->phys[0], 5));
/* mod_timer synchronizes us with potential add_timer calls
* from interrupts.
*/
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
index ed66a16711d..9db528967da 100644
--- a/drivers/net/tulip/tulip.h
+++ b/drivers/net/tulip/tulip.h
@@ -547,11 +547,9 @@ static inline void tulip_stop_rxtx(struct tulip_private *tp)
udelay(10);
if (!i)
- printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed"
- " (CSR5 0x%x CSR6 0x%x)\n",
- pci_name(tp->pdev),
- ioread32(ioaddr + CSR5),
- ioread32(ioaddr + CSR6));
+ netdev_dbg(tp->dev, "tulip_stop_rxtx() failed (CSR5 0x%x CSR6 0x%x)\n",
+ ioread32(ioaddr + CSR5),
+ ioread32(ioaddr + CSR6));
}
}
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 5c01e260f1b..82f87647207 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -12,6 +12,7 @@
Please submit bugs to http://bugzilla.kernel.org/ .
*/
+#define pr_fmt(fmt) "tulip: " fmt
#define DRV_NAME "tulip"
#ifdef CONFIG_TULIP_NAPI
@@ -119,8 +120,6 @@ module_param(csr0, int, 0);
module_param_array(options, int, NULL, 0);
module_param_array(full_duplex, int, NULL, 0);
-#define PFX DRV_NAME ": "
-
#ifdef TULIP_DEBUG
int tulip_debug = TULIP_DEBUG;
#else
@@ -331,8 +330,7 @@ static void tulip_up(struct net_device *dev)
udelay(100);
if (tulip_debug > 1)
- printk(KERN_DEBUG "%s: tulip_up(), irq==%d\n",
- dev->name, dev->irq);
+ netdev_dbg(dev, "tulip_up(), irq==%d\n", dev->irq);
iowrite32(tp->rx_ring_dma, ioaddr + CSR3);
iowrite32(tp->tx_ring_dma, ioaddr + CSR4);
@@ -499,10 +497,10 @@ media_picked:
iowrite32(0, ioaddr + CSR2); /* Rx poll demand */
if (tulip_debug > 2) {
- printk(KERN_DEBUG "%s: Done tulip_up(), CSR0 %08x, CSR5 %08x CSR6 %08x\n",
- dev->name, ioread32(ioaddr + CSR0),
- ioread32(ioaddr + CSR5),
- ioread32(ioaddr + CSR6));
+ netdev_dbg(dev, "Done tulip_up(), CSR0 %08x, CSR5 %08x CSR6 %08x\n",
+ ioread32(ioaddr + CSR0),
+ ioread32(ioaddr + CSR5),
+ ioread32(ioaddr + CSR6));
}
/* Set the timer to switch to check for link beat and perhaps switch
@@ -843,8 +841,7 @@ static int tulip_close (struct net_device *dev)
tulip_down (dev);
if (tulip_debug > 1)
- dev_printk(KERN_DEBUG, &dev->dev,
- "Shutting down ethercard, status was %02x\n",
+ netdev_dbg(dev, "Shutting down ethercard, status was %02x\n",
ioread32 (ioaddr + CSR5));
free_irq (dev->irq, dev);
@@ -1207,7 +1204,7 @@ static void __devinit tulip_mwi_config (struct pci_dev *pdev,
u32 csr0;
if (tulip_debug > 3)
- printk(KERN_DEBUG "%s: tulip_mwi_config()\n", pci_name(pdev));
+ netdev_dbg(dev, "tulip_mwi_config()\n");
tp->csr0 = csr0 = 0;
@@ -1269,8 +1266,8 @@ static void __devinit tulip_mwi_config (struct pci_dev *pdev,
out:
tp->csr0 = csr0;
if (tulip_debug > 2)
- printk(KERN_DEBUG "%s: MWI config cacheline=%d, csr0=%08x\n",
- pci_name(pdev), cache, csr0);
+ netdev_dbg(dev, "MWI config cacheline=%d, csr0=%08x\n",
+ cache, csr0);
}
#endif
@@ -1340,13 +1337,13 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
*/
if (pdev->subsystem_vendor == PCI_VENDOR_ID_LMC) {
- pr_err(PFX "skipping LMC card\n");
+ pr_err("skipping LMC card\n");
return -ENODEV;
} else if (pdev->subsystem_vendor == PCI_VENDOR_ID_SBE &&
(pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_T3E3 ||
pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P0 ||
pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P1)) {
- pr_err(PFX "skipping SBE T3E3 port\n");
+ pr_err("skipping SBE T3E3 port\n");
return -ENODEV;
}
@@ -1362,13 +1359,13 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
if (pdev->vendor == 0x1282 && pdev->device == 0x9100 &&
pdev->revision < 0x30) {
- pr_info(PFX "skipping early DM9100 with Crc bug (use dmfe)\n");
+ pr_info("skipping early DM9100 with Crc bug (use dmfe)\n");
return -ENODEV;
}
dp = pci_device_to_OF_node(pdev);
if (!(dp && of_get_property(dp, "local-mac-address", NULL))) {
- pr_info(PFX "skipping DM910x expansion card (use dmfe)\n");
+ pr_info("skipping DM910x expansion card (use dmfe)\n");
return -ENODEV;
}
}
@@ -1415,16 +1412,14 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
i = pci_enable_device(pdev);
if (i) {
- pr_err(PFX "Cannot enable tulip board #%d, aborting\n",
- board_idx);
+ pr_err("Cannot enable tulip board #%d, aborting\n", board_idx);
return i;
}
/* The chip will fail to enter a low-power state later unless
* first explicitly commanded into D0 */
if (pci_set_power_state(pdev, PCI_D0)) {
- printk (KERN_NOTICE PFX
- "Failed to set power state to D0\n");
+ pr_notice("Failed to set power state to D0\n");
}
irq = pdev->irq;
@@ -1432,13 +1427,13 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
/* alloc_etherdev ensures aligned and zeroed private structures */
dev = alloc_etherdev (sizeof (*tp));
if (!dev) {
- pr_err(PFX "ether device alloc failed, aborting\n");
+ pr_err("ether device alloc failed, aborting\n");
return -ENOMEM;
}
SET_NETDEV_DEV(dev, &pdev->dev);
if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) {
- pr_err(PFX "%s: I/O region (0x%llx@0x%llx) too small, aborting\n",
+ pr_err("%s: I/O region (0x%llx@0x%llx) too small, aborting\n",
pci_name(pdev),
(unsigned long long)pci_resource_len (pdev, 0),
(unsigned long long)pci_resource_start (pdev, 0));
@@ -1483,7 +1478,8 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
if (sig == 0x09811317) {
tp->flags |= COMET_PM;
tp->wolinfo.supported = WAKE_PHY | WAKE_MAGIC;
- printk(KERN_INFO "tulip_init_one: Enabled WOL support for AN983B\n");
+ pr_info("%s: Enabled WOL support for AN983B\n",
+ __func__);
}
}
tp->pdev = pdev;
@@ -1879,7 +1875,7 @@ save_state:
tulip_set_wolopts(pdev, tp->wolinfo.wolopts);
rc = pci_enable_wake(pdev, pstate, tp->wolinfo.wolopts);
if (rc)
- printk("tulip: pci_enable_wake failed (%d)\n", rc);
+ pr_err("pci_enable_wake failed (%d)\n", rc);
}
pci_set_power_state(pdev, pstate);
@@ -1905,12 +1901,12 @@ static int tulip_resume(struct pci_dev *pdev)
return 0;
if ((retval = pci_enable_device(pdev))) {
- pr_err(PFX "pci_enable_device failed in resume\n");
+ pr_err("pci_enable_device failed in resume\n");
return retval;
}
if ((retval = request_irq(dev->irq, tulip_interrupt, IRQF_SHARED, dev->name, dev))) {
- pr_err(PFX "request_irq failed in resume\n");
+ pr_err("request_irq failed in resume\n");
return retval;
}
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index 74217dbf014..9e63f406f72 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -209,8 +209,7 @@ enum uli526x_CR6_bits {
/* Global variable declaration ----------------------------- */
static int __devinitdata printed_version;
static const char version[] __devinitconst =
- KERN_INFO DRV_NAME ": ULi M5261/M5263 net driver, version "
- DRV_VERSION " (" DRV_RELDATE ")\n";
+ "ULi M5261/M5263 net driver, version " DRV_VERSION " (" DRV_RELDATE ")";
static int uli526x_debug;
static unsigned char uli526x_media_mode = ULI526X_AUTO;
@@ -283,7 +282,7 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev,
ULI526X_DBUG(0, "uli526x_init_one()", 0);
if (!printed_version++)
- printk(version);
+ pr_info("%s\n", version);
/* Init network device */
dev = alloc_etherdev(sizeof(*db));
@@ -292,7 +291,7 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev,
SET_NETDEV_DEV(dev, &pdev->dev);
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
- pr_warning("32-bit PCI DMA not available\n");
+ pr_warn("32-bit PCI DMA not available\n");
err = -ENODEV;
goto err_out_free;
}
@@ -390,9 +389,9 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev,
if (err)
goto err_out_res;
- dev_info(&dev->dev, "ULi M%04lx at pci%s, %pM, irq %d\n",
- ent->driver_data >> 16, pci_name(pdev),
- dev->dev_addr, dev->irq);
+ netdev_info(dev, "ULi M%04lx at pci%s, %pM, irq %d\n",
+ ent->driver_data >> 16, pci_name(pdev),
+ dev->dev_addr, dev->irq);
pci_set_master(pdev);
@@ -524,7 +523,7 @@ static void uli526x_init(struct net_device *dev)
}
}
if(phy_tmp == 32)
- pr_warning("Can not find the phy address!!!");
+ pr_warn("Can not find the phy address!!!\n");
/* Parser SROM and media mode */
db->media_mode = uli526x_media_mode;
@@ -590,7 +589,7 @@ static netdev_tx_t uli526x_start_xmit(struct sk_buff *skb,
/* Too large packet check */
if (skb->len > MAX_PACKET_SIZE) {
- pr_err("big packet = %d\n", (u16)skb->len);
+ netdev_err(dev, "big packet = %d\n", (u16)skb->len);
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -600,7 +599,7 @@ static netdev_tx_t uli526x_start_xmit(struct sk_buff *skb,
/* No Tx resource check, it never happen nromally */
if (db->tx_packet_cnt >= TX_FREE_DESC_CNT) {
spin_unlock_irqrestore(&db->lock, flags);
- pr_err("No Tx resource %ld\n", db->tx_packet_cnt);
+ netdev_err(dev, "No Tx resource %ld\n", db->tx_packet_cnt);
return NETDEV_TX_BUSY;
}
@@ -667,15 +666,6 @@ static int uli526x_stop(struct net_device *dev)
/* free allocated rx buffer */
uli526x_free_rxbuffer(db);
-#if 0
- /* show statistic counter */
- printk(DRV_NAME ": FU:%lx EC:%lx LC:%lx NC:%lx LOC:%lx TXJT:%lx RESET:%lx RCR8:%lx FAL:%lx TT:%lx\n",
- db->tx_fifo_underrun, db->tx_excessive_collision,
- db->tx_late_collision, db->tx_no_carrier, db->tx_loss_carrier,
- db->tx_jabber_timeout, db->reset_count, db->reset_cr8,
- db->reset_fatal, db->reset_TXtimeout);
-#endif
-
return 0;
}
@@ -755,7 +745,6 @@ static void uli526x_free_tx_pkt(struct net_device *dev,
txptr = db->tx_remove_ptr;
while(db->tx_packet_cnt) {
tdes0 = le32_to_cpu(txptr->tdes0);
- /* printk(DRV_NAME ": tdes0=%x\n", tdes0); */
if (tdes0 & 0x80000000)
break;
@@ -765,7 +754,6 @@ static void uli526x_free_tx_pkt(struct net_device *dev,
/* Transmit statistic counter */
if ( tdes0 != 0x7fffffff ) {
- /* printk(DRV_NAME ": tdes0=%x\n", tdes0); */
dev->stats.collisions += (tdes0 >> 3) & 0xf;
dev->stats.tx_bytes += le32_to_cpu(txptr->tdes1) & 0x7ff;
if (tdes0 & TDES0_ERR_MASK) {
@@ -838,7 +826,6 @@ static void uli526x_rx_packet(struct net_device *dev, struct uli526x_board_info
/* error summary bit check */
if (rdes0 & 0x8000) {
/* This is a error packet */
- //printk(DRV_NAME ": rdes0: %lx\n", rdes0);
dev->stats.rx_errors++;
if (rdes0 & 1)
dev->stats.rx_fifo_errors++;
@@ -945,12 +932,12 @@ ULi_ethtool_gset(struct uli526x_board_info *db, struct ethtool_cmd *ecmd)
ecmd->transceiver = XCVR_EXTERNAL;
- ecmd->speed = 10;
+ ethtool_cmd_speed_set(ecmd, SPEED_10);
ecmd->duplex = DUPLEX_HALF;
if(db->op_mode==ULI526X_100MHF || db->op_mode==ULI526X_100MFD)
{
- ecmd->speed = 100;
+ ethtool_cmd_speed_set(ecmd, SPEED_100);
}
if(db->op_mode==ULI526X_10MFD || db->op_mode==ULI526X_100MFD)
{
@@ -958,7 +945,7 @@ ULi_ethtool_gset(struct uli526x_board_info *db, struct ethtool_cmd *ecmd)
}
if(db->link_failed)
{
- ecmd->speed = -1;
+ ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1;
}
@@ -1024,7 +1011,6 @@ static void uli526x_timer(unsigned long data)
struct net_device *dev = (struct net_device *) data;
struct uli526x_board_info *db = netdev_priv(dev);
unsigned long flags;
- u8 TmpSpeed=10;
//ULI526X_DBUG(0, "uli526x_timer()", 0);
spin_lock_irqsave(&db->lock, flags);
@@ -1047,8 +1033,7 @@ static void uli526x_timer(unsigned long data)
if ( time_after(jiffies, dev_trans_start(dev) + ULI526X_TX_TIMEOUT) ) {
db->reset_TXtimeout++;
db->wait_reset = 1;
- printk( "%s: Tx timeout - resetting\n",
- dev->name);
+ netdev_err(dev, " Tx timeout - resetting\n");
}
}
@@ -1070,7 +1055,7 @@ static void uli526x_timer(unsigned long data)
/* Link Failed */
ULI526X_DBUG(0, "Link Failed", tmp_cr12);
netif_carrier_off(dev);
- pr_info("%s NIC Link is Down\n",dev->name);
+ netdev_info(dev, "NIC Link is Down\n");
db->link_failed = 1;
/* For Force 10/100M Half/Full mode: Enable Auto-Nego mode */
@@ -1096,18 +1081,13 @@ static void uli526x_timer(unsigned long data)
if(db->link_failed==0)
{
- if(db->op_mode==ULI526X_100MHF || db->op_mode==ULI526X_100MFD)
- {
- TmpSpeed = 100;
- }
- if(db->op_mode==ULI526X_10MFD || db->op_mode==ULI526X_100MFD)
- {
- pr_info("%s NIC Link is Up %d Mbps Full duplex\n",dev->name,TmpSpeed);
- }
- else
- {
- pr_info("%s NIC Link is Up %d Mbps Half duplex\n",dev->name,TmpSpeed);
- }
+ netdev_info(dev, "NIC Link is Up %d Mbps %s duplex\n",
+ (db->op_mode == ULI526X_100MHF ||
+ db->op_mode == ULI526X_100MFD)
+ ? 100 : 10,
+ (db->op_mode == ULI526X_10MFD ||
+ db->op_mode == ULI526X_100MFD)
+ ? "Full" : "Half");
netif_carrier_on(dev);
}
/* SHOW_MEDIA_TYPE(db->op_mode); */
@@ -1116,7 +1096,7 @@ static void uli526x_timer(unsigned long data)
{
if(db->init==1)
{
- pr_info("%s NIC Link is Down\n",dev->name);
+ netdev_info(dev, "NIC Link is Down\n");
netif_carrier_off(dev);
}
}
@@ -1242,7 +1222,7 @@ static int uli526x_resume(struct pci_dev *pdev)
err = pci_set_power_state(pdev, PCI_D0);
if (err) {
- dev_warn(&dev->dev, "Could not put device into D0\n");
+ netdev_warn(dev, "Could not put device into D0\n");
return err;
}
@@ -1443,7 +1423,7 @@ static void send_filter_frame(struct net_device *dev, int mc_cnt)
update_cr6(db->cr6_data, dev->base_addr);
dev->trans_start = jiffies;
} else
- pr_err("No Tx resource - Send_filter_frame!\n");
+ netdev_err(dev, "No Tx resource - Send_filter_frame!\n");
}
@@ -1540,7 +1520,6 @@ static u8 uli526x_sense_speed(struct uli526x_board_info * db)
else
phy_mode = 0x1000;
- /* printk(DRV_NAME ": Phy_mode %x ",phy_mode); */
switch (phy_mode) {
case 0x1000: db->op_mode = ULI526X_10MHF; break;
case 0x2000: db->op_mode = ULI526X_10MFD; break;
@@ -1829,7 +1808,7 @@ MODULE_PARM_DESC(mode, "ULi M5261/M5263: Bit 0: 10/100Mbps, bit 2: duplex, bit 8
static int __init uli526x_init_module(void)
{
- printk(version);
+ pr_info("%s\n", version);
printed_version = 1;
ULI526X_DBUG(0, "init_module() ", debug);
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index f0b231035de..862eadf0719 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -44,6 +44,8 @@
* Wake-On-LAN
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define DRV_NAME "winbond-840"
#define DRV_VERSION "1.01-e"
#define DRV_RELDATE "Sep-11-2006"
@@ -139,7 +141,7 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
/* These identify the driver base version and may not be removed. */
static const char version[] __initconst =
- KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) "
+ "v" DRV_VERSION " (2.4 port) "
DRV_RELDATE " Donald Becker <becker@scyld.com>\n"
" http://www.scyld.com/network/drivers.html\n";
@@ -375,8 +377,8 @@ static int __devinit w840_probe1 (struct pci_dev *pdev,
irq = pdev->irq;
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
- pr_warning("Winbond-840: Device %s disabled due to DMA limitations\n",
- pci_name(pdev));
+ pr_warn("Device %s disabled due to DMA limitations\n",
+ pci_name(pdev));
return -EIO;
}
dev = alloc_etherdev(sizeof(*np));
@@ -643,8 +645,7 @@ static int netdev_open(struct net_device *dev)
goto out_err;
if (debug > 1)
- printk(KERN_DEBUG "%s: w89c840_open() irq %d\n",
- dev->name, dev->irq);
+ netdev_dbg(dev, "w89c840_open() irq %d\n", dev->irq);
if((i=alloc_ringdesc(dev)))
goto out_err;
@@ -656,7 +657,7 @@ static int netdev_open(struct net_device *dev)
netif_start_queue(dev);
if (debug > 2)
- printk(KERN_DEBUG "%s: Done netdev_open()\n", dev->name);
+ netdev_dbg(dev, "Done netdev_open()\n");
/* Set the timer to check for link beat. */
init_timer(&np->timer);
@@ -785,9 +786,9 @@ static void netdev_timer(unsigned long data)
void __iomem *ioaddr = np->base_addr;
if (debug > 2)
- printk(KERN_DEBUG "%s: Media selection timer tick, status %08x config %08x\n",
- dev->name, ioread32(ioaddr + IntrStatus),
- ioread32(ioaddr + NetworkConfig));
+ netdev_dbg(dev, "Media selection timer tick, status %08x config %08x\n",
+ ioread32(ioaddr + IntrStatus),
+ ioread32(ioaddr + NetworkConfig));
spin_lock_irq(&np->lock);
update_csr6(dev, update_link(dev));
spin_unlock_irq(&np->lock);
@@ -1054,8 +1055,8 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irq(&np->lock);
if (debug > 4) {
- printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d\n",
- dev->name, np->cur_tx, entry);
+ netdev_dbg(dev, "Transmit frame #%d queued in slot %d\n",
+ np->cur_tx, entry);
}
return NETDEV_TX_OK;
}
@@ -1072,8 +1073,8 @@ static void netdev_tx_done(struct net_device *dev)
if (tx_status & 0x8000) { /* There was an error, log it. */
#ifndef final_version
if (debug > 1)
- printk(KERN_DEBUG "%s: Transmit error, Tx status %08x\n",
- dev->name, tx_status);
+ netdev_dbg(dev, "Transmit error, Tx status %08x\n",
+ tx_status);
#endif
np->stats.tx_errors++;
if (tx_status & 0x0104) np->stats.tx_aborted_errors++;
@@ -1085,8 +1086,8 @@ static void netdev_tx_done(struct net_device *dev)
} else {
#ifndef final_version
if (debug > 3)
- printk(KERN_DEBUG "%s: Transmit slot %d ok, Tx status %08x\n",
- dev->name, entry, tx_status);
+ netdev_dbg(dev, "Transmit slot %d ok, Tx status %08x\n",
+ entry, tx_status);
#endif
np->stats.tx_bytes += np->tx_skbuff[entry]->len;
np->stats.collisions += (tx_status >> 3) & 15;
@@ -1129,8 +1130,7 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
iowrite32(intr_status & 0x001ffff, ioaddr + IntrStatus);
if (debug > 4)
- printk(KERN_DEBUG "%s: Interrupt, status %04x\n",
- dev->name, intr_status);
+ netdev_dbg(dev, "Interrupt, status %04x\n", intr_status);
if ((intr_status & (NormalIntr|AbnormalIntr)) == 0)
break;
@@ -1171,8 +1171,8 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
} while (1);
if (debug > 3)
- printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x\n",
- dev->name, ioread32(ioaddr + IntrStatus));
+ netdev_dbg(dev, "exiting interrupt, status=%#4.4x\n",
+ ioread32(ioaddr + IntrStatus));
return IRQ_RETVAL(handled);
}
@@ -1185,8 +1185,8 @@ static int netdev_rx(struct net_device *dev)
int work_limit = np->dirty_rx + RX_RING_SIZE - np->cur_rx;
if (debug > 4) {
- printk(KERN_DEBUG " In netdev_rx(), entry %d status %04x\n",
- entry, np->rx_ring[entry].status);
+ netdev_dbg(dev, " In netdev_rx(), entry %d status %04x\n",
+ entry, np->rx_ring[entry].status);
}
/* If EOP is set on the next entry, it's a new packet. Send it up. */
@@ -1195,8 +1195,8 @@ static int netdev_rx(struct net_device *dev)
s32 status = desc->status;
if (debug > 4)
- printk(KERN_DEBUG " netdev_rx() status was %08x\n",
- status);
+ netdev_dbg(dev, " netdev_rx() status was %08x\n",
+ status);
if (status < 0)
break;
if ((status & 0x38008300) != 0x0300) {
@@ -1211,8 +1211,8 @@ static int netdev_rx(struct net_device *dev)
} else if (status & 0x8000) {
/* There was a fatal error. */
if (debug > 2)
- printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n",
- dev->name, status);
+ netdev_dbg(dev, "Receive error, Rx status %08x\n",
+ status);
np->stats.rx_errors++; /* end of a packet.*/
if (status & 0x0890) np->stats.rx_length_errors++;
if (status & 0x004C) np->stats.rx_frame_errors++;
@@ -1225,8 +1225,8 @@ static int netdev_rx(struct net_device *dev)
#ifndef final_version
if (debug > 4)
- printk(KERN_DEBUG " netdev_rx() normal Rx pkt length %d status %x\n",
- pkt_len, status);
+ netdev_dbg(dev, " netdev_rx() normal Rx pkt length %d status %x\n",
+ pkt_len, status);
#endif
/* Check if the packet is long enough to accept without copying
to a minimally-sized skbuff. */
@@ -1251,10 +1251,10 @@ static int netdev_rx(struct net_device *dev)
#ifndef final_version /* Remove after testing. */
/* You will want this info for the initial debug. */
if (debug > 5)
- printk(KERN_DEBUG " Rx data %pM %pM %02x%02x %pI4\n",
- &skb->data[0], &skb->data[6],
- skb->data[12], skb->data[13],
- &skb->data[14]);
+ netdev_dbg(dev, " Rx data %pM %pM %02x%02x %pI4\n",
+ &skb->data[0], &skb->data[6],
+ skb->data[12], skb->data[13],
+ &skb->data[14]);
#endif
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
@@ -1292,8 +1292,7 @@ static void netdev_error(struct net_device *dev, int intr_status)
void __iomem *ioaddr = np->base_addr;
if (debug > 2)
- printk(KERN_DEBUG "%s: Abnormal event, %08x\n",
- dev->name, intr_status);
+ netdev_dbg(dev, "Abnormal event, %08x\n", intr_status);
if (intr_status == 0xffffffff)
return;
spin_lock(&np->lock);
@@ -1313,8 +1312,7 @@ static void netdev_error(struct net_device *dev, int intr_status)
new = 127; /* load full packet before starting */
new = (np->csr6 & ~(0x7F << 14)) | (new<<14);
#endif
- printk(KERN_DEBUG "%s: Tx underflow, new csr6 %08x\n",
- dev->name, new);
+ netdev_dbg(dev, "Tx underflow, new csr6 %08x\n", new);
update_csr6(dev, new);
}
if (intr_status & RxDied) { /* Missed a Rx frame. */
@@ -1487,13 +1485,12 @@ static int netdev_close(struct net_device *dev)
netif_stop_queue(dev);
if (debug > 1) {
- printk(KERN_DEBUG "%s: Shutting down ethercard, status was %08x Config %08x\n",
- dev->name, ioread32(ioaddr + IntrStatus),
- ioread32(ioaddr + NetworkConfig));
- printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d\n",
- dev->name,
- np->cur_tx, np->dirty_tx,
- np->cur_rx, np->dirty_rx);
+ netdev_dbg(dev, "Shutting down ethercard, status was %08x Config %08x\n",
+ ioread32(ioaddr + IntrStatus),
+ ioread32(ioaddr + NetworkConfig));
+ netdev_dbg(dev, "Queue pointers were Tx %d / %d, Rx %d / %d\n",
+ np->cur_tx, np->dirty_tx,
+ np->cur_rx, np->dirty_rx);
}
/* Stop the chip's Tx and Rx processes. */
diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c
index 5a73752be2c..988b8eb24d3 100644
--- a/drivers/net/tulip/xircom_cb.c
+++ b/drivers/net/tulip/xircom_cb.c
@@ -37,15 +37,6 @@
#include <asm/irq.h>
#endif
-#ifdef DEBUG
-#define enter(x) printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__)
-#define leave(x) printk("Leave: %s, %s line %i\n",x,__FILE__,__LINE__)
-#else
-#define enter(x) do {} while (0)
-#define leave(x) do {} while (0)
-#endif
-
-
MODULE_DESCRIPTION("Xircom Cardbus ethernet driver");
MODULE_AUTHOR("Arjan van de Ven <arjanv@redhat.com>");
MODULE_LICENSE("GPL");
@@ -161,7 +152,7 @@ static struct pci_driver xircom_ops = {
};
-#ifdef DEBUG
+#if defined DEBUG && DEBUG > 1
static void print_binary(unsigned int number)
{
int i,i2;
@@ -176,7 +167,7 @@ static void print_binary(unsigned int number)
if ((i&3)==0)
buffer[i2++]=' ';
}
- printk("%s\n",buffer);
+ pr_debug("%s\n",buffer);
}
#endif
@@ -205,7 +196,6 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
struct xircom_private *private;
unsigned long flags;
unsigned short tmp16;
- enter("xircom_probe");
/* First do the PCI initialisation */
@@ -272,8 +262,8 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
goto reg_fail;
}
- dev_info(&dev->dev, "Xircom cardbus revision %i at irq %i\n",
- pdev->revision, pdev->irq);
+ netdev_info(dev, "Xircom cardbus revision %i at irq %i\n",
+ pdev->revision, pdev->irq);
/* start the transmitter to get a heartbeat */
/* TODO: send 2 dummy packets here */
transceiver_voodoo(private);
@@ -285,7 +275,6 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
trigger_receive(private);
- leave("xircom_probe");
return 0;
reg_fail:
@@ -310,7 +299,6 @@ static void __devexit xircom_remove(struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
struct xircom_private *card = netdev_priv(dev);
- enter("xircom_remove");
pci_free_consistent(pdev,8192,card->rx_buffer,card->rx_dma_handle);
pci_free_consistent(pdev,8192,card->tx_buffer,card->tx_dma_handle);
@@ -318,7 +306,6 @@ static void __devexit xircom_remove(struct pci_dev *pdev)
unregister_netdev(dev);
free_netdev(dev);
pci_set_drvdata(pdev, NULL);
- leave("xircom_remove");
}
static irqreturn_t xircom_interrupt(int irq, void *dev_instance)
@@ -328,17 +315,15 @@ static irqreturn_t xircom_interrupt(int irq, void *dev_instance)
unsigned int status;
int i;
- enter("xircom_interrupt\n");
-
spin_lock(&card->lock);
status = inl(card->io_port+CSR5);
-#ifdef DEBUG
+#if defined DEBUG && DEBUG > 1
print_binary(status);
- printk("tx status 0x%08x 0x%08x\n",
- card->tx_buffer[0], card->tx_buffer[4]);
- printk("rx status 0x%08x 0x%08x\n",
- card->rx_buffer[0], card->rx_buffer[4]);
+ pr_debug("tx status 0x%08x 0x%08x\n",
+ card->tx_buffer[0], card->tx_buffer[4]);
+ pr_debug("rx status 0x%08x 0x%08x\n",
+ card->rx_buffer[0], card->rx_buffer[4]);
#endif
/* Handle shared irq and hotplug */
if (status == 0 || status == 0xffffffff) {
@@ -348,9 +333,9 @@ static irqreturn_t xircom_interrupt(int irq, void *dev_instance)
if (link_status_changed(card)) {
int newlink;
- printk(KERN_DEBUG "xircom_cb: Link status has changed\n");
+ netdev_dbg(dev, "Link status has changed\n");
newlink = link_status(card);
- dev_info(&dev->dev, "Link is %i mbit\n", newlink);
+ netdev_info(dev, "Link is %d mbit\n", newlink);
if (newlink)
netif_carrier_on(dev);
else
@@ -369,9 +354,7 @@ static irqreturn_t xircom_interrupt(int irq, void *dev_instance)
for (i=0;i<NUMDESCRIPTORS;i++)
investigate_read_descriptor(dev,card,i,bufferoffsets[i]);
-
spin_unlock(&card->lock);
- leave("xircom_interrupt");
return IRQ_HANDLED;
}
@@ -382,7 +365,6 @@ static netdev_tx_t xircom_start_xmit(struct sk_buff *skb,
unsigned long flags;
int nextdescriptor;
int desc;
- enter("xircom_start_xmit");
card = netdev_priv(dev);
spin_lock_irqsave(&card->lock,flags);
@@ -424,13 +406,10 @@ static netdev_tx_t xircom_start_xmit(struct sk_buff *skb,
netif_stop_queue(dev);
}
card->transmit_used = nextdescriptor;
- leave("xircom-start_xmit - sent");
spin_unlock_irqrestore(&card->lock,flags);
return NETDEV_TX_OK;
}
-
-
/* Uh oh... no free descriptor... drop the packet */
netif_stop_queue(dev);
spin_unlock_irqrestore(&card->lock,flags);
@@ -446,18 +425,16 @@ static int xircom_open(struct net_device *dev)
{
struct xircom_private *xp = netdev_priv(dev);
int retval;
- enter("xircom_open");
- pr_info("xircom cardbus adaptor found, registering as %s, using irq %i\n",
- dev->name, dev->irq);
+
+ netdev_info(dev, "xircom cardbus adaptor found, using irq %i\n",
+ dev->irq);
retval = request_irq(dev->irq, xircom_interrupt, IRQF_SHARED, dev->name, dev);
- if (retval) {
- leave("xircom_open - No IRQ");
+ if (retval)
return retval;
- }
xircom_up(xp);
xp->open = 1;
- leave("xircom_open");
+
return 0;
}
@@ -466,7 +443,6 @@ static int xircom_close(struct net_device *dev)
struct xircom_private *card;
unsigned long flags;
- enter("xircom_close");
card = netdev_priv(dev);
netif_stop_queue(dev); /* we don't want new packets */
@@ -486,8 +462,6 @@ static int xircom_close(struct net_device *dev)
card->open = 0;
free_irq(dev->irq,dev);
- leave("xircom_close");
-
return 0;
}
@@ -507,8 +481,6 @@ static void initialize_card(struct xircom_private *card)
{
unsigned int val;
unsigned long flags;
- enter("initialize_card");
-
spin_lock_irqsave(&card->lock, flags);
@@ -534,8 +506,6 @@ static void initialize_card(struct xircom_private *card)
deactivate_transmitter(card);
spin_unlock_irqrestore(&card->lock, flags);
-
- leave("initialize_card");
}
/*
@@ -547,12 +517,9 @@ ignored; I chose zero.
static void trigger_transmit(struct xircom_private *card)
{
unsigned int val;
- enter("trigger_transmit");
val = 0;
outl(val, card->io_port + CSR1);
-
- leave("trigger_transmit");
}
/*
@@ -565,12 +532,9 @@ ignored; I chose zero.
static void trigger_receive(struct xircom_private *card)
{
unsigned int val;
- enter("trigger_receive");
val = 0;
outl(val, card->io_port + CSR2);
-
- leave("trigger_receive");
}
/*
@@ -581,8 +545,6 @@ static void setup_descriptors(struct xircom_private *card)
{
u32 address;
int i;
- enter("setup_descriptors");
-
BUG_ON(card->rx_buffer == NULL);
BUG_ON(card->tx_buffer == NULL);
@@ -636,8 +598,6 @@ static void setup_descriptors(struct xircom_private *card)
/* wite the transmit descriptor ring to the card */
address = card->tx_dma_handle;
outl(address, card->io_port + CSR4); /* xmit descr list address */
-
- leave("setup_descriptors");
}
/*
@@ -647,13 +607,10 @@ valid by setting the address in the card to 0x00.
static void remove_descriptors(struct xircom_private *card)
{
unsigned int val;
- enter("remove_descriptors");
val = 0;
outl(val, card->io_port + CSR3); /* Receive descriptor address */
outl(val, card->io_port + CSR4); /* Send descriptor address */
-
- leave("remove_descriptors");
}
/*
@@ -665,21 +622,17 @@ This function also clears the status-bit.
static int link_status_changed(struct xircom_private *card)
{
unsigned int val;
- enter("link_status_changed");
val = inl(card->io_port + CSR5); /* Status register */
- if ((val & (1 << 27)) == 0) { /* no change */
- leave("link_status_changed - nochange");
+ if ((val & (1 << 27)) == 0) /* no change */
return 0;
- }
/* clear the event by writing a 1 to the bit in the
status register. */
val = (1 << 27);
outl(val, card->io_port + CSR5);
- leave("link_status_changed - changed");
return 1;
}
@@ -691,16 +644,12 @@ in a non-stopped state.
static int transmit_active(struct xircom_private *card)
{
unsigned int val;
- enter("transmit_active");
val = inl(card->io_port + CSR5); /* Status register */
- if ((val & (7 << 20)) == 0) { /* transmitter disabled */
- leave("transmit_active - inactive");
+ if ((val & (7 << 20)) == 0) /* transmitter disabled */
return 0;
- }
- leave("transmit_active - active");
return 1;
}
@@ -711,17 +660,12 @@ in a non-stopped state.
static int receive_active(struct xircom_private *card)
{
unsigned int val;
- enter("receive_active");
-
val = inl(card->io_port + CSR5); /* Status register */
- if ((val & (7 << 17)) == 0) { /* receiver disabled */
- leave("receive_active - inactive");
+ if ((val & (7 << 17)) == 0) /* receiver disabled */
return 0;
- }
- leave("receive_active - active");
return 1;
}
@@ -739,8 +683,6 @@ static void activate_receiver(struct xircom_private *card)
{
unsigned int val;
int counter;
- enter("activate_receiver");
-
val = inl(card->io_port + CSR6); /* Operation mode */
@@ -761,7 +703,7 @@ static void activate_receiver(struct xircom_private *card)
udelay(50);
counter--;
if (counter <= 0)
- pr_err("Receiver failed to deactivate\n");
+ netdev_err(card->dev, "Receiver failed to deactivate\n");
}
/* enable the receiver */
@@ -778,10 +720,9 @@ static void activate_receiver(struct xircom_private *card)
udelay(50);
counter--;
if (counter <= 0)
- pr_err("Receiver failed to re-activate\n");
+ netdev_err(card->dev,
+ "Receiver failed to re-activate\n");
}
-
- leave("activate_receiver");
}
/*
@@ -795,7 +736,6 @@ static void deactivate_receiver(struct xircom_private *card)
{
unsigned int val;
int counter;
- enter("deactivate_receiver");
val = inl(card->io_port + CSR6); /* Operation mode */
val = val & ~2; /* disable the receiver */
@@ -809,11 +749,8 @@ static void deactivate_receiver(struct xircom_private *card)
udelay(50);
counter--;
if (counter <= 0)
- pr_err("Receiver failed to deactivate\n");
+ netdev_err(card->dev, "Receiver failed to deactivate\n");
}
-
-
- leave("deactivate_receiver");
}
@@ -831,8 +768,6 @@ static void activate_transmitter(struct xircom_private *card)
{
unsigned int val;
int counter;
- enter("activate_transmitter");
-
val = inl(card->io_port + CSR6); /* Operation mode */
@@ -852,7 +787,8 @@ static void activate_transmitter(struct xircom_private *card)
udelay(50);
counter--;
if (counter <= 0)
- pr_err("Transmitter failed to deactivate\n");
+ netdev_err(card->dev,
+ "Transmitter failed to deactivate\n");
}
/* enable the transmitter */
@@ -869,10 +805,9 @@ static void activate_transmitter(struct xircom_private *card)
udelay(50);
counter--;
if (counter <= 0)
- pr_err("Transmitter failed to re-activate\n");
+ netdev_err(card->dev,
+ "Transmitter failed to re-activate\n");
}
-
- leave("activate_transmitter");
}
/*
@@ -886,7 +821,6 @@ static void deactivate_transmitter(struct xircom_private *card)
{
unsigned int val;
int counter;
- enter("deactivate_transmitter");
val = inl(card->io_port + CSR6); /* Operation mode */
val = val & ~2; /* disable the transmitter */
@@ -900,11 +834,9 @@ static void deactivate_transmitter(struct xircom_private *card)
udelay(50);
counter--;
if (counter <= 0)
- pr_err("Transmitter failed to deactivate\n");
+ netdev_err(card->dev,
+ "Transmitter failed to deactivate\n");
}
-
-
- leave("deactivate_transmitter");
}
@@ -916,13 +848,10 @@ must be called with the lock held and interrupts disabled.
static void enable_transmit_interrupt(struct xircom_private *card)
{
unsigned int val;
- enter("enable_transmit_interrupt");
val = inl(card->io_port + CSR7); /* Interrupt enable register */
val |= 1; /* enable the transmit interrupt */
outl(val, card->io_port + CSR7);
-
- leave("enable_transmit_interrupt");
}
@@ -934,13 +863,10 @@ must be called with the lock held and interrupts disabled.
static void enable_receive_interrupt(struct xircom_private *card)
{
unsigned int val;
- enter("enable_receive_interrupt");
val = inl(card->io_port + CSR7); /* Interrupt enable register */
val = val | (1 << 6); /* enable the receive interrupt */
outl(val, card->io_port + CSR7);
-
- leave("enable_receive_interrupt");
}
/*
@@ -951,13 +877,10 @@ must be called with the lock held and interrupts disabled.
static void enable_link_interrupt(struct xircom_private *card)
{
unsigned int val;
- enter("enable_link_interrupt");
val = inl(card->io_port + CSR7); /* Interrupt enable register */
val = val | (1 << 27); /* enable the link status chage interrupt */
outl(val, card->io_port + CSR7);
-
- leave("enable_link_interrupt");
}
@@ -970,12 +893,9 @@ must be called with the lock held and interrupts disabled.
static void disable_all_interrupts(struct xircom_private *card)
{
unsigned int val;
- enter("enable_all_interrupts");
val = 0; /* disable all interrupts */
outl(val, card->io_port + CSR7);
-
- leave("disable_all_interrupts");
}
/*
@@ -986,7 +906,6 @@ must be called with the lock held and interrupts disabled.
static void enable_common_interrupts(struct xircom_private *card)
{
unsigned int val;
- enter("enable_link_interrupt");
val = inl(card->io_port + CSR7); /* Interrupt enable register */
val |= (1<<16); /* Normal Interrupt Summary */
@@ -998,8 +917,6 @@ static void enable_common_interrupts(struct xircom_private *card)
val |= (1<<2); /* Transmit Buffer Unavailable */
val |= (1<<1); /* Transmit Process Stopped */
outl(val, card->io_port + CSR7);
-
- leave("enable_link_interrupt");
}
/*
@@ -1010,13 +927,11 @@ must be called with the lock held and interrupts disabled.
static int enable_promisc(struct xircom_private *card)
{
unsigned int val;
- enter("enable_promisc");
val = inl(card->io_port + CSR6);
val = val | (1 << 6);
outl(val, card->io_port + CSR6);
- leave("enable_promisc");
return 1;
}
@@ -1031,7 +946,6 @@ Must be called in locked state with interrupts disabled
static int link_status(struct xircom_private *card)
{
unsigned int val;
- enter("link_status");
val = inb(card->io_port + CSR12);
@@ -1042,7 +956,6 @@ static int link_status(struct xircom_private *card)
/* If we get here -> no link at all */
- leave("link_status");
return 0;
}
@@ -1061,8 +974,6 @@ static void read_mac_address(struct xircom_private *card)
unsigned long flags;
int i;
- enter("read_mac_address");
-
spin_lock_irqsave(&card->lock, flags);
outl(1 << 12, card->io_port + CSR9); /* enable boot rom access */
@@ -1090,7 +1001,6 @@ static void read_mac_address(struct xircom_private *card)
}
spin_unlock_irqrestore(&card->lock, flags);
pr_debug(" %pM\n", card->dev->dev_addr);
- leave("read_mac_address");
}
@@ -1103,8 +1013,6 @@ static void transceiver_voodoo(struct xircom_private *card)
{
unsigned long flags;
- enter("transceiver_voodoo");
-
/* disable all powermanagement */
pci_write_config_dword(card->pdev, PCI_POWERMGMT, 0x0000);
@@ -1122,7 +1030,6 @@ static void transceiver_voodoo(struct xircom_private *card)
spin_unlock_irqrestore(&card->lock, flags);
netif_start_queue(card->dev);
- leave("transceiver_voodoo");
}
@@ -1131,8 +1038,6 @@ static void xircom_up(struct xircom_private *card)
unsigned long flags;
int i;
- enter("xircom_up");
-
/* disable all powermanagement */
pci_write_config_dword(card->pdev, PCI_POWERMGMT, 0x0000);
@@ -1156,87 +1061,84 @@ static void xircom_up(struct xircom_private *card)
trigger_receive(card);
trigger_transmit(card);
netif_start_queue(card->dev);
- leave("xircom_up");
}
/* Bufferoffset is in BYTES */
-static void investigate_read_descriptor(struct net_device *dev,struct xircom_private *card, int descnr, unsigned int bufferoffset)
+static void
+investigate_read_descriptor(struct net_device *dev, struct xircom_private *card,
+ int descnr, unsigned int bufferoffset)
{
- int status;
-
- enter("investigate_read_descriptor");
- status = le32_to_cpu(card->rx_buffer[4*descnr]);
+ int status;
- if ((status > 0)) { /* packet received */
+ status = le32_to_cpu(card->rx_buffer[4*descnr]);
- /* TODO: discard error packets */
+ if (status > 0) { /* packet received */
- short pkt_len = ((status >> 16) & 0x7ff) - 4; /* minus 4, we don't want the CRC */
- struct sk_buff *skb;
+ /* TODO: discard error packets */
- if (pkt_len > 1518) {
- pr_err("Packet length %i is bogus\n", pkt_len);
- pkt_len = 1518;
- }
+ short pkt_len = ((status >> 16) & 0x7ff) - 4;
+ /* minus 4, we don't want the CRC */
+ struct sk_buff *skb;
- skb = dev_alloc_skb(pkt_len + 2);
- if (skb == NULL) {
- dev->stats.rx_dropped++;
- goto out;
- }
- skb_reserve(skb, 2);
- skb_copy_to_linear_data(skb, (unsigned char*)&card->rx_buffer[bufferoffset / 4], pkt_len);
- skb_put(skb, pkt_len);
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
-
- out:
- /* give the buffer back to the card */
- card->rx_buffer[4*descnr] = cpu_to_le32(0x80000000);
- trigger_receive(card);
+ if (pkt_len > 1518) {
+ netdev_err(dev, "Packet length %i is bogus\n", pkt_len);
+ pkt_len = 1518;
}
- leave("investigate_read_descriptor");
-
+ skb = dev_alloc_skb(pkt_len + 2);
+ if (skb == NULL) {
+ dev->stats.rx_dropped++;
+ goto out;
+ }
+ skb_reserve(skb, 2);
+ skb_copy_to_linear_data(skb,
+ &card->rx_buffer[bufferoffset / 4],
+ pkt_len);
+ skb_put(skb, pkt_len);
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb);
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
+
+out:
+ /* give the buffer back to the card */
+ card->rx_buffer[4*descnr] = cpu_to_le32(0x80000000);
+ trigger_receive(card);
+ }
}
/* Bufferoffset is in BYTES */
-static void investigate_write_descriptor(struct net_device *dev, struct xircom_private *card, int descnr, unsigned int bufferoffset)
+static void
+investigate_write_descriptor(struct net_device *dev,
+ struct xircom_private *card,
+ int descnr, unsigned int bufferoffset)
{
- int status;
-
- enter("investigate_write_descriptor");
+ int status;
- status = le32_to_cpu(card->tx_buffer[4*descnr]);
+ status = le32_to_cpu(card->tx_buffer[4*descnr]);
#if 0
- if (status & 0x8000) { /* Major error */
- pr_err("Major transmit error status %x\n", status);
- card->tx_buffer[4*descnr] = 0;
- netif_wake_queue (dev);
- }
+ if (status & 0x8000) { /* Major error */
+ pr_err("Major transmit error status %x\n", status);
+ card->tx_buffer[4*descnr] = 0;
+ netif_wake_queue (dev);
+ }
#endif
- if (status > 0) { /* bit 31 is 0 when done */
- if (card->tx_skb[descnr]!=NULL) {
- dev->stats.tx_bytes += card->tx_skb[descnr]->len;
- dev_kfree_skb_irq(card->tx_skb[descnr]);
- }
- card->tx_skb[descnr] = NULL;
- /* Bit 8 in the status field is 1 if there was a collision */
- if (status&(1<<8))
- dev->stats.collisions++;
- card->tx_buffer[4*descnr] = 0; /* descriptor is free again */
- netif_wake_queue (dev);
- dev->stats.tx_packets++;
+ if (status > 0) { /* bit 31 is 0 when done */
+ if (card->tx_skb[descnr]!=NULL) {
+ dev->stats.tx_bytes += card->tx_skb[descnr]->len;
+ dev_kfree_skb_irq(card->tx_skb[descnr]);
}
-
- leave("investigate_write_descriptor");
-
+ card->tx_skb[descnr] = NULL;
+ /* Bit 8 in the status field is 1 if there was a collision */
+ if (status & (1 << 8))
+ dev->stats.collisions++;
+ card->tx_buffer[4*descnr] = 0; /* descriptor is free again */
+ netif_wake_queue (dev);
+ dev->stats.tx_packets++;
+ }
}
-
static int __init xircom_init(void)
{
return pci_register_driver(&xircom_ops);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index f5e9ac00a07..74e94054ab1 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -123,6 +123,9 @@ struct tun_struct {
gid_t group;
struct net_device *dev;
+ u32 set_features;
+#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
+ NETIF_F_TSO6|NETIF_F_UFO)
struct fasync_struct *fasync;
struct tap_filter txflt;
@@ -451,12 +454,20 @@ tun_net_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
+static u32 tun_net_fix_features(struct net_device *dev, u32 features)
+{
+ struct tun_struct *tun = netdev_priv(dev);
+
+ return (features & tun->set_features) | (features & ~TUN_USER_FEATURES);
+}
+
static const struct net_device_ops tun_netdev_ops = {
.ndo_uninit = tun_net_uninit,
.ndo_open = tun_net_open,
.ndo_stop = tun_net_close,
.ndo_start_xmit = tun_net_xmit,
.ndo_change_mtu = tun_net_change_mtu,
+ .ndo_fix_features = tun_net_fix_features,
};
static const struct net_device_ops tap_netdev_ops = {
@@ -465,6 +476,7 @@ static const struct net_device_ops tap_netdev_ops = {
.ndo_stop = tun_net_close,
.ndo_start_xmit = tun_net_xmit,
.ndo_change_mtu = tun_net_change_mtu,
+ .ndo_fix_features = tun_net_fix_features,
.ndo_set_multicast_list = tun_net_mclist,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
@@ -628,8 +640,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
kfree_skb(skb);
return -EINVAL;
}
- } else if (tun->flags & TUN_NOCHECKSUM)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ }
switch (tun->flags & TUN_TYPE_MASK) {
case TUN_TUN_DEV:
@@ -1088,11 +1099,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
tun_net_init(dev);
- if (strchr(dev->name, '%')) {
- err = dev_alloc_name(dev, dev->name);
- if (err < 0)
- goto err_free_sk;
- }
+ dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST |
+ TUN_USER_FEATURES;
+ dev->features = dev->hw_features;
err = register_netdevice(tun->dev);
if (err < 0)
@@ -1158,18 +1167,12 @@ static int tun_get_iff(struct net *net, struct tun_struct *tun,
/* This is like a cut-down ethtool ops, except done via tun fd so no
* privs required. */
-static int set_offload(struct net_device *dev, unsigned long arg)
+static int set_offload(struct tun_struct *tun, unsigned long arg)
{
- u32 old_features, features;
-
- old_features = dev->features;
- /* Unset features, set them as we chew on the arg. */
- features = (old_features & ~(NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST
- |NETIF_F_TSO_ECN|NETIF_F_TSO|NETIF_F_TSO6
- |NETIF_F_UFO));
+ u32 features = 0;
if (arg & TUN_F_CSUM) {
- features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
+ features |= NETIF_F_HW_CSUM;
arg &= ~TUN_F_CSUM;
if (arg & (TUN_F_TSO4|TUN_F_TSO6)) {
@@ -1195,9 +1198,8 @@ static int set_offload(struct net_device *dev, unsigned long arg)
if (arg)
return -EINVAL;
- dev->features = features;
- if (old_features != dev->features)
- netdev_features_change(dev);
+ tun->set_features = features;
+ netdev_update_features(tun->dev);
return 0;
}
@@ -1262,12 +1264,9 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
case TUNSETNOCSUM:
/* Disable/Enable checksum */
- if (arg)
- tun->flags |= TUN_NOCHECKSUM;
- else
- tun->flags &= ~TUN_NOCHECKSUM;
- tun_debug(KERN_INFO, tun, "checksum %s\n",
+ /* [unimplemented] */
+ tun_debug(KERN_INFO, tun, "ignored: set checksum %s\n",
arg ? "disabled" : "enabled");
break;
@@ -1316,7 +1315,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
break;
#endif
case TUNSETOFFLOAD:
- ret = set_offload(tun->dev, arg);
+ ret = set_offload(tun, arg);
break;
case TUNSETTXFILTER:
@@ -1548,7 +1547,7 @@ static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
cmd->supported = 0;
cmd->advertising = 0;
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
cmd->duplex = DUPLEX_FULL;
cmd->port = PORT_TP;
cmd->phy_address = 0;
@@ -1595,30 +1594,12 @@ static void tun_set_msglevel(struct net_device *dev, u32 value)
#endif
}
-static u32 tun_get_rx_csum(struct net_device *dev)
-{
- struct tun_struct *tun = netdev_priv(dev);
- return (tun->flags & TUN_NOCHECKSUM) == 0;
-}
-
-static int tun_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct tun_struct *tun = netdev_priv(dev);
- if (data)
- tun->flags &= ~TUN_NOCHECKSUM;
- else
- tun->flags |= TUN_NOCHECKSUM;
- return 0;
-}
-
static const struct ethtool_ops tun_ethtool_ops = {
.get_settings = tun_get_settings,
.get_drvinfo = tun_get_drvinfo,
.get_msglevel = tun_get_msglevel,
.set_msglevel = tun_set_msglevel,
.get_link = ethtool_op_get_link,
- .get_rx_csum = tun_get_rx_csum,
- .set_rx_csum = tun_set_rx_csum
};
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 82653cb0785..3de4283344e 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -1050,7 +1050,7 @@ typhoon_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
/* need to get stats to make these link speed/duplex valid */
typhoon_do_get_stats(tp);
- cmd->speed = tp->speed;
+ ethtool_cmd_speed_set(cmd, tp->speed);
cmd->duplex = tp->duplex;
cmd->phy_address = 0;
cmd->transceiver = XCVR_INTERNAL;
@@ -1068,25 +1068,26 @@ static int
typhoon_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct typhoon *tp = netdev_priv(dev);
+ u32 speed = ethtool_cmd_speed(cmd);
struct cmd_desc xp_cmd;
__le16 xcvr;
int err;
err = -EINVAL;
- if(cmd->autoneg == AUTONEG_ENABLE) {
+ if (cmd->autoneg == AUTONEG_ENABLE) {
xcvr = TYPHOON_XCVR_AUTONEG;
} else {
- if(cmd->duplex == DUPLEX_HALF) {
- if(cmd->speed == SPEED_10)
+ if (cmd->duplex == DUPLEX_HALF) {
+ if (speed == SPEED_10)
xcvr = TYPHOON_XCVR_10HALF;
- else if(cmd->speed == SPEED_100)
+ else if (speed == SPEED_100)
xcvr = TYPHOON_XCVR_100HALF;
else
goto out;
- } else if(cmd->duplex == DUPLEX_FULL) {
- if(cmd->speed == SPEED_10)
+ } else if (cmd->duplex == DUPLEX_FULL) {
+ if (speed == SPEED_10)
xcvr = TYPHOON_XCVR_10FULL;
- else if(cmd->speed == SPEED_100)
+ else if (speed == SPEED_100)
xcvr = TYPHOON_XCVR_100FULL;
else
goto out;
@@ -1105,7 +1106,7 @@ typhoon_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
tp->speed = 0xff; /* invalid */
tp->duplex = 0xff; /* invalid */
} else {
- tp->speed = cmd->speed;
+ tp->speed = speed;
tp->duplex = cmd->duplex;
}
@@ -1144,28 +1145,6 @@ typhoon_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
return 0;
}
-static u32
-typhoon_get_rx_csum(struct net_device *dev)
-{
- /* For now, we don't allow turning off RX checksums.
- */
- return 1;
-}
-
-static int
-typhoon_set_flags(struct net_device *dev, u32 data)
-{
- /* There's no way to turn off the RX VLAN offloading and stripping
- * on the current 3XP firmware -- it does not respect the offload
- * settings -- so we only allow the user to toggle the TX processing.
- */
- if (!(data & ETH_FLAG_RXVLAN))
- return -EINVAL;
-
- return ethtool_op_set_flags(dev, data,
- ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN);
-}
-
static void
typhoon_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
{
@@ -1187,13 +1166,7 @@ static const struct ethtool_ops typhoon_ethtool_ops = {
.get_wol = typhoon_get_wol,
.set_wol = typhoon_set_wol,
.get_link = ethtool_op_get_link,
- .get_rx_csum = typhoon_get_rx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .set_sg = ethtool_op_set_sg,
- .set_tso = ethtool_op_set_tso,
.get_ringparam = typhoon_get_ringparam,
- .set_flags = typhoon_set_flags,
- .get_flags = ethtool_op_get_flags,
};
static int
@@ -2482,10 +2455,15 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* We can handle scatter gather, up to 16 entries, and
* we can do IP checksumming (only version 4, doh...)
+ *
+ * There's no way to turn off the RX VLAN offloading and stripping
+ * on the current 3XP firmware -- it does not respect the offload
+ * settings -- so we only allow the user to toggle the TX processing.
*/
- dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
- dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- dev->features |= NETIF_F_TSO;
+ dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
+ NETIF_F_HW_VLAN_TX;
+ dev->features = dev->hw_features |
+ NETIF_F_HW_VLAN_RX | NETIF_F_RXCSUM;
if(register_netdev(dev) < 0) {
err_msg = "unable to register netdev";
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c
index 6f92e48f02d..537fbc0a440 100644
--- a/drivers/net/ucc_geth_ethtool.c
+++ b/drivers/net/ucc_geth_ethtool.c
@@ -410,7 +410,6 @@ static const struct ethtool_ops uec_ethtool_ops = {
.set_ringparam = uec_set_ringparam,
.get_pauseparam = uec_get_pauseparam,
.set_pauseparam = uec_set_pauseparam,
- .set_sg = ethtool_op_set_sg,
.get_sset_count = uec_get_sset_count,
.get_strings = uec_get_strings,
.get_ethtool_stats = uec_get_ethtool_stats,
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 3ec22c30779..9d4f9117260 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -258,7 +258,7 @@ config USB_NET_NET1080
optionally with LEDs that indicate traffic
config USB_NET_PLUSB
- tristate "Prolific PL-2301/2302 based cables"
+ tristate "Prolific PL-2301/2302/25A1 based cables"
# if the handshake/init/reset problems, from original 'plusb',
# are ever resolved ... then remove "experimental"
depends on USB_USBNET && EXPERIMENTAL
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index 6140b56cce5..6998aa6b7bb 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -847,7 +847,7 @@ static void ax88172_set_multicast(struct net_device *net)
static int ax88172_link_reset(struct usbnet *dev)
{
u8 mode;
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
mii_check_media(&dev->mii, 1, 1);
mii_ethtool_gset(&dev->mii, &ecmd);
@@ -856,8 +856,8 @@ static int ax88172_link_reset(struct usbnet *dev)
if (ecmd.duplex != DUPLEX_FULL)
mode |= ~AX88172_MEDIUM_FD;
- netdev_dbg(dev->net, "ax88172_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n",
- ecmd.speed, ecmd.duplex, mode);
+ netdev_dbg(dev->net, "ax88172_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n",
+ ethtool_cmd_speed(&ecmd), ecmd.duplex, mode);
asix_write_medium_mode(dev, mode);
@@ -947,20 +947,20 @@ static const struct ethtool_ops ax88772_ethtool_ops = {
static int ax88772_link_reset(struct usbnet *dev)
{
u16 mode;
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
mii_check_media(&dev->mii, 1, 1);
mii_ethtool_gset(&dev->mii, &ecmd);
mode = AX88772_MEDIUM_DEFAULT;
- if (ecmd.speed != SPEED_100)
+ if (ethtool_cmd_speed(&ecmd) != SPEED_100)
mode &= ~AX_MEDIUM_PS;
if (ecmd.duplex != DUPLEX_FULL)
mode &= ~AX_MEDIUM_FD;
- netdev_dbg(dev->net, "ax88772_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n",
- ecmd.speed, ecmd.duplex, mode);
+ netdev_dbg(dev->net, "ax88772_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n",
+ ethtool_cmd_speed(&ecmd), ecmd.duplex, mode);
asix_write_medium_mode(dev, mode);
@@ -1173,18 +1173,20 @@ static int marvell_led_status(struct usbnet *dev, u16 speed)
static int ax88178_link_reset(struct usbnet *dev)
{
u16 mode;
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
struct asix_data *data = (struct asix_data *)&dev->data;
+ u32 speed;
netdev_dbg(dev->net, "ax88178_link_reset()\n");
mii_check_media(&dev->mii, 1, 1);
mii_ethtool_gset(&dev->mii, &ecmd);
mode = AX88178_MEDIUM_DEFAULT;
+ speed = ethtool_cmd_speed(&ecmd);
- if (ecmd.speed == SPEED_1000)
+ if (speed == SPEED_1000)
mode |= AX_MEDIUM_GM;
- else if (ecmd.speed == SPEED_100)
+ else if (speed == SPEED_100)
mode |= AX_MEDIUM_PS;
else
mode &= ~(AX_MEDIUM_PS | AX_MEDIUM_GM);
@@ -1196,13 +1198,13 @@ static int ax88178_link_reset(struct usbnet *dev)
else
mode &= ~AX_MEDIUM_FD;
- netdev_dbg(dev->net, "ax88178_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n",
- ecmd.speed, ecmd.duplex, mode);
+ netdev_dbg(dev->net, "ax88178_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n",
+ speed, ecmd.duplex, mode);
asix_write_medium_mode(dev, mode);
if (data->phymode == PHY_MODE_MARVELL && data->ledmode)
- marvell_led_status(dev, ecmd.speed);
+ marvell_led_status(dev, speed);
return 0;
}
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index 97687d33590..d7221c4a5dc 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -686,7 +686,7 @@ static int catc_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->supported = SUPPORTED_10baseT_Half | SUPPORTED_TP;
cmd->advertising = ADVERTISED_10baseT_Half | ADVERTISED_TP;
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
cmd->duplex = DUPLEX_HALF;
cmd->port = PORT_TP;
cmd->phy_address = 0;
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 1033ef6476a..4ab557d0287 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -54,13 +54,13 @@
#include <linux/usb/usbnet.h>
#include <linux/usb/cdc.h>
-#define DRIVER_VERSION "23-Apr-2011"
+#define DRIVER_VERSION "06-May-2011"
/* CDC NCM subclass 3.2.1 */
#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10
/* Maximum NTB length */
-#define CDC_NCM_NTB_MAX_SIZE_TX (16384 + 4) /* bytes, must be short terminated */
+#define CDC_NCM_NTB_MAX_SIZE_TX 16384 /* bytes */
#define CDC_NCM_NTB_MAX_SIZE_RX 16384 /* bytes */
/* Minimum value for MaxDatagramSize, ch. 6.2.9 */
@@ -722,7 +722,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
} else {
/* reset variables */
- skb_out = alloc_skb(ctx->tx_max, GFP_ATOMIC);
+ skb_out = alloc_skb((ctx->tx_max + 1), GFP_ATOMIC);
if (skb_out == NULL) {
if (skb != NULL) {
dev_kfree_skb_any(skb);
@@ -861,8 +861,11 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
/* store last offset */
last_offset = offset;
- if ((last_offset < ctx->tx_max) && ((last_offset %
- le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0)) {
+ if (((last_offset < ctx->tx_max) && ((last_offset %
+ le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0)) ||
+ (((last_offset == ctx->tx_max) && ((ctx->tx_max %
+ le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0)) &&
+ (ctx->tx_max < le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize)))) {
/* force short packet */
*(((u8 *)skb_out->data) + last_offset) = 0;
last_offset++;
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index 5002f5be47b..1d93133e9b7 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -599,13 +599,13 @@ static void dm9601_status(struct usbnet *dev, struct urb *urb)
static int dm9601_link_reset(struct usbnet *dev)
{
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
mii_check_media(&dev->mii, 1, 1);
mii_ethtool_gset(&dev->mii, &ecmd);
- netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n",
- ecmd.speed, ecmd.duplex);
+ netdev_dbg(dev->net, "link_reset() speed: %u duplex: %d\n",
+ ethtool_cmd_speed(&ecmd), ecmd.duplex);
return 0;
}
diff --git a/drivers/net/usb/plusb.c b/drivers/net/usb/plusb.c
index 823c5375130..217aec8a768 100644
--- a/drivers/net/usb/plusb.c
+++ b/drivers/net/usb/plusb.c
@@ -45,6 +45,14 @@
* seems to get wedged under load. Prolific docs are weak, and
* don't identify differences between PL2301 and PL2302, much less
* anything to explain the different PL2302 versions observed.
+ *
+ * NOTE: pl2501 has several modes, including pl2301 and pl2302
+ * compatibility. Some docs suggest the difference between 2301
+ * and 2302 is only to make MS-Windows use a different driver...
+ *
+ * pl25a1 glue based on patch from Tony Gibbs. Prolific "docs" on
+ * this chip are as usual incomplete about what control messages
+ * are supported.
*/
/*
@@ -86,16 +94,20 @@ pl_set_QuickLink_features(struct usbnet *dev, int val)
static int pl_reset(struct usbnet *dev)
{
+ int status;
+
/* some units seem to need this reset, others reject it utterly.
* FIXME be more like "naplink" or windows drivers.
*/
- (void) pl_set_QuickLink_features(dev,
+ status = pl_set_QuickLink_features(dev,
PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E);
+ if (status != 0 && netif_msg_probe(dev))
+ netif_dbg(dev, link, dev->net, "pl_reset --> %d\n", status);
return 0;
}
static const struct driver_info prolific_info = {
- .description = "Prolific PL-2301/PL-2302",
+ .description = "Prolific PL-2301/PL-2302/PL-25A1",
.flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT,
/* some PL-2302 versions seem to fail usb_set_interface() */
.reset = pl_reset,
@@ -111,6 +123,7 @@ static const struct driver_info prolific_info = {
static const struct usb_device_id products [] = {
+/* full speed cables */
{
USB_DEVICE(0x067b, 0x0000), // PL-2301
.driver_info = (unsigned long) &prolific_info,
@@ -119,6 +132,15 @@ static const struct usb_device_id products [] = {
.driver_info = (unsigned long) &prolific_info,
},
+/* high speed cables */
+{
+ USB_DEVICE(0x067b, 0x25a1), /* PL-25A1, no eeprom */
+ .driver_info = (unsigned long) &prolific_info,
+}, {
+ USB_DEVICE(0x050d, 0x258a), /* Belkin F5U258/F5U279 (PL-25A1) */
+ .driver_info = (unsigned long) &prolific_info,
+},
+
{ }, // END
};
MODULE_DEVICE_TABLE(usb, products);
@@ -134,16 +156,16 @@ static struct usb_driver plusb_driver = {
static int __init plusb_init(void)
{
- return usb_register(&plusb_driver);
+ return usb_register(&plusb_driver);
}
module_init(plusb_init);
static void __exit plusb_exit(void)
{
- usb_deregister(&plusb_driver);
+ usb_deregister(&plusb_driver);
}
module_exit(plusb_exit);
MODULE_AUTHOR("David Brownell");
-MODULE_DESCRIPTION("Prolific PL-2301/2302 USB Host to Host Link Driver");
+MODULE_DESCRIPTION("Prolific PL-2301/2302/25A1 USB Host to Host Link Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index 5994a25c56a..255d6a424a6 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -104,8 +104,10 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
{
struct cdc_state *info = (void *) &dev->data;
+ struct usb_cdc_notification notification;
int master_ifnum;
int retval;
+ int partial;
unsigned count;
__le32 rsp;
u32 xid = 0, msg_len, request_id;
@@ -133,13 +135,20 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
if (unlikely(retval < 0 || xid == 0))
return retval;
- // FIXME Seems like some devices discard responses when
- // we time out and cancel our "get response" requests...
- // so, this is fragile. Probably need to poll for status.
+ /* Some devices don't respond on the control channel until
+ * polled on the status channel, so do that first. */
+ if (dev->driver_info->data & RNDIS_DRIVER_DATA_POLL_STATUS) {
+ retval = usb_interrupt_msg(
+ dev->udev,
+ usb_rcvintpipe(dev->udev,
+ dev->status->desc.bEndpointAddress),
+ &notification, sizeof(notification), &partial,
+ RNDIS_CONTROL_TIMEOUT_MS);
+ if (unlikely(retval < 0))
+ return retval;
+ }
- /* ignore status endpoint, just poll the control channel;
- * the request probably completed immediately
- */
+ /* Poll the control channel; the request probably completed immediately */
rsp = buf->msg_type | RNDIS_MSG_COMPLETION;
for (count = 0; count < 10; count++) {
memset(buf, 0, CONTROL_BUFFER_SIZE);
@@ -581,17 +590,33 @@ static const struct driver_info rndis_info = {
.tx_fixup = rndis_tx_fixup,
};
+static const struct driver_info rndis_poll_status_info = {
+ .description = "RNDIS device (poll status before control)",
+ .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
+ .data = RNDIS_DRIVER_DATA_POLL_STATUS,
+ .bind = rndis_bind,
+ .unbind = rndis_unbind,
+ .status = rndis_status,
+ .rx_fixup = rndis_rx_fixup,
+ .tx_fixup = rndis_tx_fixup,
+};
+
/*-------------------------------------------------------------------------*/
static const struct usb_device_id products [] = {
{
+ /* 2Wire HomePortal 1000SW */
+ USB_DEVICE_AND_INTERFACE_INFO(0x1630, 0x0042,
+ USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
+ .driver_info = (unsigned long) &rndis_poll_status_info,
+}, {
/* RNDIS is MSFT's un-official variant of CDC ACM */
USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
.driver_info = (unsigned long) &rndis_info,
}, {
/* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
- .driver_info = (unsigned long) &rndis_info,
+ .driver_info = (unsigned long) &rndis_poll_status_info,
}, {
/* RNDIS for tethering */
USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
index e85c89c6706..041fb7d43c4 100644
--- a/drivers/net/usb/rtl8150.c
+++ b/drivers/net/usb/rtl8150.c
@@ -843,10 +843,11 @@ static int rtl8150_get_settings(struct net_device *netdev, struct ethtool_cmd *e
get_registers(dev, BMCR, 2, &bmcr);
get_registers(dev, ANLP, 2, &lpa);
if (bmcr & BMCR_ANENABLE) {
+ u32 speed = ((lpa & (LPA_100HALF | LPA_100FULL)) ?
+ SPEED_100 : SPEED_10);
+ ethtool_cmd_speed_set(ecmd, speed);
ecmd->autoneg = AUTONEG_ENABLE;
- ecmd->speed = (lpa & (LPA_100HALF | LPA_100FULL)) ?
- SPEED_100 : SPEED_10;
- if (ecmd->speed == SPEED_100)
+ if (speed == SPEED_100)
ecmd->duplex = (lpa & LPA_100FULL) ?
DUPLEX_FULL : DUPLEX_HALF;
else
@@ -854,8 +855,8 @@ static int rtl8150_get_settings(struct net_device *netdev, struct ethtool_cmd *e
DUPLEX_FULL : DUPLEX_HALF;
} else {
ecmd->autoneg = AUTONEG_DISABLE;
- ecmd->speed = (bmcr & BMCR_SPEED100) ?
- SPEED_100 : SPEED_10;
+ ethtool_cmd_speed_set(ecmd, ((bmcr & BMCR_SPEED100) ?
+ SPEED_100 : SPEED_10));
ecmd->duplex = (bmcr & BMCR_FULLDPLX) ?
DUPLEX_FULL : DUPLEX_HALF;
}
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 753ee6eb7ed..15b3d6888ae 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -65,7 +65,6 @@ struct smsc75xx_priv {
struct usbnet *dev;
u32 rfe_ctl;
u32 multicast_hash_table[DP_SEL_VHF_HASH_LEN];
- bool use_rx_csum;
struct mutex dataport_mutex;
spinlock_t rfe_ctl_lock;
struct work_struct set_multicast;
@@ -504,7 +503,7 @@ static int smsc75xx_update_flowcontrol(struct usbnet *dev, u8 duplex,
static int smsc75xx_link_reset(struct usbnet *dev)
{
struct mii_if_info *mii = &dev->mii;
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
u16 lcladv, rmtadv;
int ret;
@@ -520,8 +519,9 @@ static int smsc75xx_link_reset(struct usbnet *dev)
lcladv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
rmtadv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_LPA);
- netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x"
- " rmtadv: %04x", ecmd.speed, ecmd.duplex, lcladv, rmtadv);
+ netif_dbg(dev, link, dev->net, "speed: %u duplex: %d lcladv: %04x"
+ " rmtadv: %04x", ethtool_cmd_speed(&ecmd),
+ ecmd.duplex, lcladv, rmtadv);
return smsc75xx_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv);
}
@@ -548,28 +548,6 @@ static void smsc75xx_status(struct usbnet *dev, struct urb *urb)
"unexpected interrupt, intdata=0x%08X", intdata);
}
-/* Enable or disable Rx checksum offload engine */
-static int smsc75xx_set_rx_csum_offload(struct usbnet *dev)
-{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);
-
- if (pdata->use_rx_csum)
- pdata->rfe_ctl |= RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM;
- else
- pdata->rfe_ctl &= ~(RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM);
-
- spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);
-
- ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
- check_warn_return(ret, "Error writing RFE_CTL");
-
- return 0;
-}
-
static int smsc75xx_ethtool_get_eeprom_len(struct net_device *net)
{
return MAX_EEPROM_SIZE;
@@ -599,34 +577,6 @@ static int smsc75xx_ethtool_set_eeprom(struct net_device *netdev,
return smsc75xx_write_eeprom(dev, ee->offset, ee->len, data);
}
-static u32 smsc75xx_ethtool_get_rx_csum(struct net_device *netdev)
-{
- struct usbnet *dev = netdev_priv(netdev);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
-
- return pdata->use_rx_csum;
-}
-
-static int smsc75xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val)
-{
- struct usbnet *dev = netdev_priv(netdev);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
-
- pdata->use_rx_csum = !!val;
-
- return smsc75xx_set_rx_csum_offload(dev);
-}
-
-static int smsc75xx_ethtool_set_tso(struct net_device *netdev, u32 data)
-{
- if (data)
- netdev->features |= NETIF_F_TSO | NETIF_F_TSO6;
- else
- netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-
- return 0;
-}
-
static const struct ethtool_ops smsc75xx_ethtool_ops = {
.get_link = usbnet_get_link,
.nway_reset = usbnet_nway_reset,
@@ -638,12 +588,6 @@ static const struct ethtool_ops smsc75xx_ethtool_ops = {
.get_eeprom_len = smsc75xx_ethtool_get_eeprom_len,
.get_eeprom = smsc75xx_ethtool_get_eeprom,
.set_eeprom = smsc75xx_ethtool_set_eeprom,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_hw_csum,
- .get_rx_csum = smsc75xx_ethtool_get_rx_csum,
- .set_rx_csum = smsc75xx_ethtool_set_rx_csum,
- .get_tso = ethtool_op_get_tso,
- .set_tso = smsc75xx_ethtool_set_tso,
};
static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
@@ -782,6 +726,30 @@ static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu)
return usbnet_change_mtu(netdev, new_mtu);
}
+/* Enable or disable Rx checksum offload engine */
+static int smsc75xx_set_features(struct net_device *netdev, u32 features)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);
+
+ if (features & NETIF_F_RXCSUM)
+ pdata->rfe_ctl |= RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM;
+ else
+ pdata->rfe_ctl &= ~(RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM);
+
+ spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);
+ /* it's racing here! */
+
+ ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+ check_warn_return(ret, "Error writing RFE_CTL");
+
+ return 0;
+}
+
static int smsc75xx_reset(struct usbnet *dev)
{
struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
@@ -960,11 +928,7 @@ static int smsc75xx_reset(struct usbnet *dev)
netif_dbg(dev, ifup, dev->net, "RFE_CTL set to 0x%08x", pdata->rfe_ctl);
/* Enable or disable checksum offload engines */
- ethtool_op_set_tx_hw_csum(dev->net, DEFAULT_TX_CSUM_ENABLE);
- ret = smsc75xx_set_rx_csum_offload(dev);
- check_warn_return(ret, "Failed to set rx csum offload: %d", ret);
-
- smsc75xx_ethtool_set_tso(dev->net, DEFAULT_TSO_ENABLE);
+ smsc75xx_set_features(dev->net, dev->net->features);
smsc75xx_set_multicast(dev->net);
@@ -1037,6 +1001,7 @@ static const struct net_device_ops smsc75xx_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = smsc75xx_ioctl,
.ndo_set_multicast_list = smsc75xx_set_multicast,
+ .ndo_set_features = smsc75xx_set_features,
};
static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
@@ -1065,10 +1030,17 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write);
- pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE;
+ if (DEFAULT_TX_CSUM_ENABLE) {
+ dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+ if (DEFAULT_TSO_ENABLE)
+ dev->net->features |= NETIF_F_SG |
+ NETIF_F_TSO | NETIF_F_TSO6;
+ }
+ if (DEFAULT_RX_CSUM_ENABLE)
+ dev->net->features |= NETIF_F_RXCSUM;
- /* We have to advertise SG otherwise TSO cannot be enabled */
- dev->net->features |= NETIF_F_SG;
+ dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_RXCSUM;
/* Init all registers */
ret = smsc75xx_reset(dev);
@@ -1091,10 +1063,11 @@ static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf)
}
}
-static void smsc75xx_rx_csum_offload(struct sk_buff *skb, u32 rx_cmd_a,
- u32 rx_cmd_b)
+static void smsc75xx_rx_csum_offload(struct usbnet *dev, struct sk_buff *skb,
+ u32 rx_cmd_a, u32 rx_cmd_b)
{
- if (unlikely(rx_cmd_a & RX_CMD_A_LCSM)) {
+ if (!(dev->net->features & NETIF_F_RXCSUM) ||
+ unlikely(rx_cmd_a & RX_CMD_A_LCSM)) {
skb->ip_summed = CHECKSUM_NONE;
} else {
skb->csum = ntohs((u16)(rx_cmd_b >> RX_CMD_B_CSUM_SHIFT));
@@ -1104,8 +1077,6 @@ static void smsc75xx_rx_csum_offload(struct sk_buff *skb, u32 rx_cmd_a,
static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
-
while (skb->len > 0) {
u32 rx_cmd_a, rx_cmd_b, align_count, size;
struct sk_buff *ax_skb;
@@ -1145,11 +1116,8 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
/* last frame in this batch */
if (skb->len == size) {
- if (pdata->use_rx_csum)
- smsc75xx_rx_csum_offload(skb, rx_cmd_a,
- rx_cmd_b);
- else
- skb->ip_summed = CHECKSUM_NONE;
+ smsc75xx_rx_csum_offload(dev, skb, rx_cmd_a,
+ rx_cmd_b);
skb_trim(skb, skb->len - 4); /* remove fcs */
skb->truesize = size + sizeof(struct sk_buff);
@@ -1167,11 +1135,8 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
ax_skb->data = packet;
skb_set_tail_pointer(ax_skb, size);
- if (pdata->use_rx_csum)
- smsc75xx_rx_csum_offload(ax_skb, rx_cmd_a,
- rx_cmd_b);
- else
- ax_skb->ip_summed = CHECKSUM_NONE;
+ smsc75xx_rx_csum_offload(dev, ax_skb, rx_cmd_a,
+ rx_cmd_b);
skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
ax_skb->truesize = size + sizeof(struct sk_buff);
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 48d4efdb495..f74f3ce7152 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -52,8 +52,6 @@ struct smsc95xx_priv {
u32 hash_hi;
u32 hash_lo;
spinlock_t mac_cr_lock;
- bool use_tx_csum;
- bool use_rx_csum;
};
struct usb_context {
@@ -459,7 +457,7 @@ static int smsc95xx_link_reset(struct usbnet *dev)
{
struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
struct mii_if_info *mii = &dev->mii;
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
unsigned long flags;
u16 lcladv, rmtadv;
u32 intdata;
@@ -474,8 +472,9 @@ static int smsc95xx_link_reset(struct usbnet *dev)
lcladv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
rmtadv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_LPA);
- netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x rmtadv: %04x\n",
- ecmd.speed, ecmd.duplex, lcladv, rmtadv);
+ netif_dbg(dev, link, dev->net,
+ "speed: %u duplex: %d lcladv: %04x rmtadv: %04x\n",
+ ethtool_cmd_speed(&ecmd), ecmd.duplex, lcladv, rmtadv);
spin_lock_irqsave(&pdata->mac_cr_lock, flags);
if (ecmd.duplex != DUPLEX_FULL) {
@@ -517,22 +516,24 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb)
}
/* Enable or disable Tx & Rx checksum offload engines */
-static int smsc95xx_set_csums(struct usbnet *dev)
+static int smsc95xx_set_features(struct net_device *netdev, u32 features)
{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct usbnet *dev = netdev_priv(netdev);
u32 read_buf;
- int ret = smsc95xx_read_reg(dev, COE_CR, &read_buf);
+ int ret;
+
+ ret = smsc95xx_read_reg(dev, COE_CR, &read_buf);
if (ret < 0) {
netdev_warn(dev->net, "Failed to read COE_CR: %d\n", ret);
return ret;
}
- if (pdata->use_tx_csum)
+ if (features & NETIF_F_HW_CSUM)
read_buf |= Tx_COE_EN_;
else
read_buf &= ~Tx_COE_EN_;
- if (pdata->use_rx_csum)
+ if (features & NETIF_F_RXCSUM)
read_buf |= Rx_COE_EN_;
else
read_buf &= ~Rx_COE_EN_;
@@ -576,43 +577,6 @@ static int smsc95xx_ethtool_set_eeprom(struct net_device *netdev,
return smsc95xx_write_eeprom(dev, ee->offset, ee->len, data);
}
-static u32 smsc95xx_ethtool_get_rx_csum(struct net_device *netdev)
-{
- struct usbnet *dev = netdev_priv(netdev);
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
-
- return pdata->use_rx_csum;
-}
-
-static int smsc95xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val)
-{
- struct usbnet *dev = netdev_priv(netdev);
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
-
- pdata->use_rx_csum = !!val;
-
- return smsc95xx_set_csums(dev);
-}
-
-static u32 smsc95xx_ethtool_get_tx_csum(struct net_device *netdev)
-{
- struct usbnet *dev = netdev_priv(netdev);
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
-
- return pdata->use_tx_csum;
-}
-
-static int smsc95xx_ethtool_set_tx_csum(struct net_device *netdev, u32 val)
-{
- struct usbnet *dev = netdev_priv(netdev);
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
-
- pdata->use_tx_csum = !!val;
-
- ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum);
- return smsc95xx_set_csums(dev);
-}
-
static const struct ethtool_ops smsc95xx_ethtool_ops = {
.get_link = usbnet_get_link,
.nway_reset = usbnet_nway_reset,
@@ -624,10 +588,6 @@ static const struct ethtool_ops smsc95xx_ethtool_ops = {
.get_eeprom_len = smsc95xx_ethtool_get_eeprom_len,
.get_eeprom = smsc95xx_ethtool_get_eeprom,
.set_eeprom = smsc95xx_ethtool_set_eeprom,
- .get_tx_csum = smsc95xx_ethtool_get_tx_csum,
- .set_tx_csum = smsc95xx_ethtool_set_tx_csum,
- .get_rx_csum = smsc95xx_ethtool_get_rx_csum,
- .set_rx_csum = smsc95xx_ethtool_set_rx_csum,
};
static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
@@ -755,7 +715,6 @@ static int smsc95xx_phy_initialize(struct usbnet *dev)
static int smsc95xx_reset(struct usbnet *dev)
{
struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
- struct net_device *netdev = dev->net;
u32 read_buf, write_buf, burst_cap;
int ret = 0, timeout;
@@ -975,12 +934,7 @@ static int smsc95xx_reset(struct usbnet *dev)
}
/* Enable or disable checksum offload engines */
- ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum);
- ret = smsc95xx_set_csums(dev);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to set csum offload: %d\n", ret);
- return ret;
- }
+ smsc95xx_set_features(dev->net, dev->net->features);
smsc95xx_set_multicast(dev->net);
@@ -1019,6 +973,7 @@ static const struct net_device_ops smsc95xx_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = smsc95xx_ioctl,
.ndo_set_multicast_list = smsc95xx_set_multicast,
+ .ndo_set_features = smsc95xx_set_features,
};
static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
@@ -1045,8 +1000,12 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
spin_lock_init(&pdata->mac_cr_lock);
- pdata->use_tx_csum = DEFAULT_TX_CSUM_ENABLE;
- pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE;
+ if (DEFAULT_TX_CSUM_ENABLE)
+ dev->net->features |= NETIF_F_HW_CSUM;
+ if (DEFAULT_RX_CSUM_ENABLE)
+ dev->net->features |= NETIF_F_RXCSUM;
+
+ dev->net->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
smsc95xx_init_mac_address(dev);
@@ -1056,7 +1015,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
dev->net->netdev_ops = &smsc95xx_netdev_ops;
dev->net->ethtool_ops = &smsc95xx_ethtool_ops;
dev->net->flags |= IFF_MULTICAST;
- dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD;
+ dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM;
return 0;
}
@@ -1080,8 +1039,6 @@ static void smsc95xx_rx_csum_offload(struct sk_buff *skb)
static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
-
while (skb->len > 0) {
u32 header, align_count;
struct sk_buff *ax_skb;
@@ -1123,7 +1080,7 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
/* last frame in this batch */
if (skb->len == size) {
- if (pdata->use_rx_csum)
+ if (dev->net->features & NETIF_F_RXCSUM)
smsc95xx_rx_csum_offload(skb);
skb_trim(skb, skb->len - 4); /* remove fcs */
skb->truesize = size + sizeof(struct sk_buff);
@@ -1141,7 +1098,7 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
ax_skb->data = packet;
skb_set_tail_pointer(ax_skb, size);
- if (pdata->use_rx_csum)
+ if (dev->net->features & NETIF_F_RXCSUM)
smsc95xx_rx_csum_offload(ax_skb);
skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
ax_skb->truesize = size + sizeof(struct sk_buff);
@@ -1174,8 +1131,7 @@ static u32 smsc95xx_calc_csum_preamble(struct sk_buff *skb)
static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
struct sk_buff *skb, gfp_t flags)
{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
- bool csum = pdata->use_tx_csum && (skb->ip_summed == CHECKSUM_PARTIAL);
+ bool csum = skb->ip_summed == CHECKSUM_PARTIAL;
int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD;
u32 tx_cmd_a, tx_cmd_b;
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 9ab439d144e..e6dd2446696 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1541,9 +1541,9 @@ EXPORT_SYMBOL_GPL(usbnet_resume);
static int __init usbnet_init(void)
{
- /* compiler should optimize this out */
- BUILD_BUG_ON (sizeof (((struct sk_buff *)0)->cb)
- < sizeof (struct skb_data));
+ /* Compiler should optimize this out. */
+ BUILD_BUG_ON(
+ FIELD_SIZEOF(struct sk_buff, cb) < sizeof(struct skb_data));
random_ether_addr(node_id);
return 0;
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 3b99f64104f..8461576fa01 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -22,7 +22,6 @@
#define MIN_MTU 68 /* Min L3 MTU */
#define MAX_MTU 65535 /* Max L3 MTU (arbitrary) */
-#define MTU_PAD (ETH_HLEN + 4) /* Max difference between L2 and L3 size MTU */
struct veth_net_stats {
unsigned long rx_packets;
@@ -36,7 +35,6 @@ struct veth_net_stats {
struct veth_priv {
struct net_device *peer;
struct veth_net_stats __percpu *stats;
- unsigned ip_summed;
};
/*
@@ -53,7 +51,7 @@ static int veth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
cmd->supported = 0;
cmd->advertising = 0;
- cmd->speed = SPEED_10000;
+ ethtool_cmd_speed_set(cmd, SPEED_10000);
cmd->duplex = DUPLEX_FULL;
cmd->port = PORT_TP;
cmd->phy_address = 0;
@@ -99,47 +97,10 @@ static void veth_get_ethtool_stats(struct net_device *dev,
data[0] = priv->peer->ifindex;
}
-static u32 veth_get_rx_csum(struct net_device *dev)
-{
- struct veth_priv *priv;
-
- priv = netdev_priv(dev);
- return priv->ip_summed == CHECKSUM_UNNECESSARY;
-}
-
-static int veth_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct veth_priv *priv;
-
- priv = netdev_priv(dev);
- priv->ip_summed = data ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
- return 0;
-}
-
-static u32 veth_get_tx_csum(struct net_device *dev)
-{
- return (dev->features & NETIF_F_NO_CSUM) != 0;
-}
-
-static int veth_set_tx_csum(struct net_device *dev, u32 data)
-{
- if (data)
- dev->features |= NETIF_F_NO_CSUM;
- else
- dev->features &= ~NETIF_F_NO_CSUM;
- return 0;
-}
-
static const struct ethtool_ops veth_ethtool_ops = {
.get_settings = veth_get_settings,
.get_drvinfo = veth_get_drvinfo,
.get_link = ethtool_op_get_link,
- .get_rx_csum = veth_get_rx_csum,
- .set_rx_csum = veth_set_rx_csum,
- .get_tx_csum = veth_get_tx_csum,
- .set_tx_csum = veth_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
.get_strings = veth_get_strings,
.get_sset_count = veth_get_sset_count,
.get_ethtool_stats = veth_get_ethtool_stats,
@@ -168,8 +129,9 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
/* don't change ip_summed == CHECKSUM_PARTIAL, as that
will cause bad checksum on forwarded packets */
- if (skb->ip_summed == CHECKSUM_NONE)
- skb->ip_summed = rcv_priv->ip_summed;
+ if (skb->ip_summed == CHECKSUM_NONE &&
+ rcv->features & NETIF_F_RXCSUM)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
length = skb->len;
if (dev_forward_skb(rcv, skb) != NET_RX_SUCCESS)
@@ -304,6 +266,8 @@ static void veth_setup(struct net_device *dev)
dev->ethtool_ops = &veth_ethtool_ops;
dev->features |= NETIF_F_LLTX;
dev->destructor = veth_dev_free;
+
+ dev->hw_features = NETIF_F_NO_CSUM | NETIF_F_SG | NETIF_F_RXCSUM;
}
/*
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index eb5d75df5d5..7f23ab913fd 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -29,6 +29,8 @@
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define DRV_NAME "via-rhine"
#define DRV_VERSION "1.5.0"
#define DRV_RELDATE "2010-10-09"
@@ -37,6 +39,7 @@
/* A few user-configurable values.
These may be modified when a driver module is loaded. */
+#define DEBUG
static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */
static int max_interrupt_work = 20;
@@ -111,8 +114,7 @@ static const int multicast_filter_limit = 32;
/* These identify the driver base version and may not be removed. */
static const char version[] __devinitconst =
- KERN_INFO DRV_NAME ".c:v1.10-LK" DRV_VERSION " " DRV_RELDATE
- " Written by Donald Becker\n";
+ "v1.10-LK" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker";
/* This driver was written to use PCI memory space. Some early versions
of the Rhine may only work correctly with I/O space accesses. */
@@ -495,14 +497,15 @@ static void rhine_set_vlan_cam_mask(void __iomem *ioaddr, u32 mask);
static void rhine_init_cam_filter(struct net_device *dev);
static void rhine_update_vcam(struct net_device *dev);
-#define RHINE_WAIT_FOR(condition) do { \
- int i=1024; \
- while (!(condition) && --i) \
- ; \
- if (debug > 1 && i < 512) \
- printk(KERN_INFO "%s: %4d cycles used @ %s:%d\n", \
- DRV_NAME, 1024-i, __func__, __LINE__); \
-} while(0)
+#define RHINE_WAIT_FOR(condition) \
+do { \
+ int i = 1024; \
+ while (!(condition) && --i) \
+ ; \
+ if (debug > 1 && i < 512) \
+ pr_info("%4d cycles used @ %s:%d\n", \
+ 1024 - i, __func__, __LINE__); \
+} while (0)
static inline u32 get_intr_status(struct net_device *dev)
{
@@ -571,8 +574,8 @@ static void rhine_power_init(struct net_device *dev)
default:
reason = "Unknown";
}
- printk(KERN_INFO "%s: Woke system up. Reason: %s.\n",
- DRV_NAME, reason);
+ netdev_info(dev, "Woke system up. Reason: %s\n",
+ reason);
}
}
}
@@ -586,8 +589,7 @@ static void rhine_chip_reset(struct net_device *dev)
IOSYNC;
if (ioread8(ioaddr + ChipCmd1) & Cmd1Reset) {
- printk(KERN_INFO "%s: Reset not complete yet. "
- "Trying harder.\n", DRV_NAME);
+ netdev_info(dev, "Reset not complete yet. Trying harder.\n");
/* Force reset */
if (rp->quirks & rqForceReset)
@@ -598,9 +600,9 @@ static void rhine_chip_reset(struct net_device *dev)
}
if (debug > 1)
- printk(KERN_INFO "%s: Reset %s.\n", dev->name,
- (ioread8(ioaddr + ChipCmd1) & Cmd1Reset) ?
- "failed" : "succeeded");
+ netdev_info(dev, "Reset %s\n",
+ (ioread8(ioaddr + ChipCmd1) & Cmd1Reset) ?
+ "failed" : "succeeded");
}
#ifdef USE_MMIO
@@ -728,9 +730,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
/* when built into the kernel, we only print version if device is found */
#ifndef MODULE
- static int printed_version;
- if (!printed_version++)
- printk(version);
+ pr_info_once("%s\n", version);
#endif
io_size = 256;
@@ -765,8 +765,8 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
/* this should always be supported */
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
- printk(KERN_ERR "32-bit PCI DMA addresses not supported by "
- "the card!?\n");
+ dev_err(&pdev->dev,
+ "32-bit PCI DMA addresses not supported by the card!?\n");
goto err_out;
}
@@ -774,7 +774,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
if ((pci_resource_len(pdev, 0) < io_size) ||
(pci_resource_len(pdev, 1) < io_size)) {
rc = -EIO;
- printk(KERN_ERR "Insufficient PCI resources, aborting\n");
+ dev_err(&pdev->dev, "Insufficient PCI resources, aborting\n");
goto err_out;
}
@@ -786,7 +786,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
dev = alloc_etherdev(sizeof(struct rhine_private));
if (!dev) {
rc = -ENOMEM;
- printk(KERN_ERR "alloc_etherdev failed\n");
+ dev_err(&pdev->dev, "alloc_etherdev failed\n");
goto err_out;
}
SET_NETDEV_DEV(dev, &pdev->dev);
@@ -804,8 +804,9 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
ioaddr = pci_iomap(pdev, bar, io_size);
if (!ioaddr) {
rc = -EIO;
- printk(KERN_ERR "ioremap failed for device %s, region 0x%X "
- "@ 0x%lX\n", pci_name(pdev), io_size, memaddr);
+ dev_err(&pdev->dev,
+ "ioremap failed for device %s, region 0x%X @ 0x%lX\n",
+ pci_name(pdev), io_size, memaddr);
goto err_out_free_res;
}
@@ -820,8 +821,9 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
unsigned char b = readb(ioaddr+reg);
if (a != b) {
rc = -EIO;
- printk(KERN_ERR "MMIO do not match PIO [%02x] "
- "(%02x != %02x)\n", reg, a, b);
+ dev_err(&pdev->dev,
+ "MMIO do not match PIO [%02x] (%02x != %02x)\n",
+ reg, a, b);
goto err_out_unmap;
}
}
@@ -836,13 +838,15 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
for (i = 0; i < 6; i++)
dev->dev_addr[i] = ioread8(ioaddr + StationAddr + i);
- memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
- if (!is_valid_ether_addr(dev->perm_addr)) {
- rc = -EIO;
- printk(KERN_ERR "Invalid MAC address\n");
- goto err_out_unmap;
+ if (!is_valid_ether_addr(dev->dev_addr)) {
+ /* Report it and use a random ethernet address instead */
+ netdev_err(dev, "Invalid MAC address: %pM\n", dev->dev_addr);
+ random_ether_addr(dev->dev_addr);
+ netdev_info(dev, "Using random MAC address: %pM\n",
+ dev->dev_addr);
}
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
/* For Rhine-I/II, phy_id is loaded from EEPROM */
if (!phy_id)
@@ -878,14 +882,14 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
if (rc)
goto err_out_unmap;
- printk(KERN_INFO "%s: VIA %s at 0x%lx, %pM, IRQ %d.\n",
- dev->name, name,
+ netdev_info(dev, "VIA %s at 0x%lx, %pM, IRQ %d\n",
+ name,
#ifdef USE_MMIO
- memaddr,
+ memaddr,
#else
- (long)ioaddr,
+ (long)ioaddr,
#endif
- dev->dev_addr, pdev->irq);
+ dev->dev_addr, pdev->irq);
pci_set_drvdata(pdev, dev);
@@ -896,11 +900,11 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
mdio_write(dev, phy_id, MII_BMCR, mii_cmd);
if (mii_status != 0xffff && mii_status != 0x0000) {
rp->mii_if.advertising = mdio_read(dev, phy_id, 4);
- printk(KERN_INFO "%s: MII PHY found at address "
- "%d, status 0x%4.4x advertising %4.4x "
- "Link %4.4x.\n", dev->name, phy_id,
- mii_status, rp->mii_if.advertising,
- mdio_read(dev, phy_id, 5));
+ netdev_info(dev,
+ "MII PHY found at address %d, status 0x%04x advertising %04x Link %04x\n",
+ phy_id,
+ mii_status, rp->mii_if.advertising,
+ mdio_read(dev, phy_id, 5));
/* set IFF_RUNNING */
if (mii_status & BMSR_LSTATUS)
@@ -912,8 +916,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
}
rp->mii_if.phy_id = phy_id;
if (debug > 1 && avoid_D3)
- printk(KERN_INFO "%s: No D3 power state at shutdown.\n",
- dev->name);
+ netdev_info(dev, "No D3 power state at shutdown\n");
return 0;
@@ -938,7 +941,7 @@ static int alloc_ring(struct net_device* dev)
TX_RING_SIZE * sizeof(struct tx_desc),
&ring_dma);
if (!ring) {
- printk(KERN_ERR "Could not allocate DMA memory.\n");
+ netdev_err(dev, "Could not allocate DMA memory\n");
return -ENOMEM;
}
if (rp->quirks & rqRhineI) {
@@ -1098,8 +1101,8 @@ static void rhine_check_media(struct net_device *dev, unsigned int init_media)
iowrite8(ioread8(ioaddr + ChipCmd1) & ~Cmd1FDuplex,
ioaddr + ChipCmd1);
if (debug > 1)
- printk(KERN_INFO "%s: force_media %d, carrier %d\n", dev->name,
- rp->mii_if.force_media, netif_carrier_ok(dev));
+ netdev_info(dev, "force_media %d, carrier %d\n",
+ rp->mii_if.force_media, netif_carrier_ok(dev));
}
/* Called after status of force_media possibly changed */
@@ -1113,9 +1116,8 @@ static void rhine_set_carrier(struct mii_if_info *mii)
else /* Let MMI library update carrier status */
rhine_check_media(mii->dev, 0);
if (debug > 1)
- printk(KERN_INFO "%s: force_media %d, carrier %d\n",
- mii->dev->name, mii->force_media,
- netif_carrier_ok(mii->dev));
+ netdev_info(mii->dev, "force_media %d, carrier %d\n",
+ mii->force_media, netif_carrier_ok(mii->dev));
}
/**
@@ -1402,8 +1404,7 @@ static int rhine_open(struct net_device *dev)
return rc;
if (debug > 1)
- printk(KERN_DEBUG "%s: rhine_open() irq %d.\n",
- dev->name, rp->pdev->irq);
+ netdev_dbg(dev, "%s() irq %d\n", __func__, rp->pdev->irq);
rc = alloc_ring(dev);
if (rc) {
@@ -1415,10 +1416,9 @@ static int rhine_open(struct net_device *dev)
rhine_chip_reset(dev);
init_registers(dev);
if (debug > 2)
- printk(KERN_DEBUG "%s: Done rhine_open(), status %4.4x "
- "MII status: %4.4x.\n",
- dev->name, ioread16(ioaddr + ChipCmd),
- mdio_read(dev, rp->mii_if.phy_id, MII_BMSR));
+ netdev_dbg(dev, "%s() Done - status %04x MII status: %04x\n",
+ __func__, ioread16(ioaddr + ChipCmd),
+ mdio_read(dev, rp->mii_if.phy_id, MII_BMSR));
netif_start_queue(dev);
@@ -1461,10 +1461,9 @@ static void rhine_tx_timeout(struct net_device *dev)
struct rhine_private *rp = netdev_priv(dev);
void __iomem *ioaddr = rp->base;
- printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status "
- "%4.4x, resetting...\n",
- dev->name, ioread16(ioaddr + IntrStatus),
- mdio_read(dev, rp->mii_if.phy_id, MII_BMSR));
+ netdev_warn(dev, "Transmit timed out, status %04x, PHY status %04x, resetting...\n",
+ ioread16(ioaddr + IntrStatus),
+ mdio_read(dev, rp->mii_if.phy_id, MII_BMSR));
schedule_work(&rp->reset_task);
}
@@ -1551,8 +1550,8 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
spin_unlock_irqrestore(&rp->lock, flags);
if (debug > 4) {
- printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
- dev->name, rp->cur_tx-1, entry);
+ netdev_dbg(dev, "Transmit frame #%d queued in slot %d\n",
+ rp->cur_tx-1, entry);
}
return NETDEV_TX_OK;
}
@@ -1578,8 +1577,8 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance)
IOSYNC;
if (debug > 4)
- printk(KERN_DEBUG "%s: Interrupt, status %8.8x.\n",
- dev->name, intr_status);
+ netdev_dbg(dev, "Interrupt, status %08x\n",
+ intr_status);
if (intr_status & (IntrRxDone | IntrRxErr | IntrRxDropped |
IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf)) {
@@ -1597,9 +1596,9 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance)
RHINE_WAIT_FOR(!(ioread8(ioaddr+ChipCmd) & CmdTxOn));
if (debug > 2 &&
ioread8(ioaddr+ChipCmd) & CmdTxOn)
- printk(KERN_WARNING "%s: "
- "rhine_interrupt() Tx engine "
- "still on.\n", dev->name);
+ netdev_warn(dev,
+ "%s: Tx engine still on\n",
+ __func__);
}
rhine_tx(dev);
}
@@ -1611,16 +1610,15 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance)
rhine_error(dev, intr_status);
if (--boguscnt < 0) {
- printk(KERN_WARNING "%s: Too much work at interrupt, "
- "status=%#8.8x.\n",
- dev->name, intr_status);
+ netdev_warn(dev, "Too much work at interrupt, status=%#08x\n",
+ intr_status);
break;
}
}
if (debug > 3)
- printk(KERN_DEBUG "%s: exiting interrupt, status=%8.8x.\n",
- dev->name, ioread16(ioaddr + IntrStatus));
+ netdev_dbg(dev, "exiting interrupt, status=%08x\n",
+ ioread16(ioaddr + IntrStatus));
return IRQ_RETVAL(handled);
}
@@ -1637,15 +1635,14 @@ static void rhine_tx(struct net_device *dev)
while (rp->dirty_tx != rp->cur_tx) {
txstatus = le32_to_cpu(rp->tx_ring[entry].tx_status);
if (debug > 6)
- printk(KERN_DEBUG "Tx scavenge %d status %8.8x.\n",
- entry, txstatus);
+ netdev_dbg(dev, "Tx scavenge %d status %08x\n",
+ entry, txstatus);
if (txstatus & DescOwn)
break;
if (txstatus & 0x8000) {
if (debug > 1)
- printk(KERN_DEBUG "%s: Transmit error, "
- "Tx status %8.8x.\n",
- dev->name, txstatus);
+ netdev_dbg(dev, "Transmit error, Tx status %08x\n",
+ txstatus);
dev->stats.tx_errors++;
if (txstatus & 0x0400)
dev->stats.tx_carrier_errors++;
@@ -1668,9 +1665,9 @@ static void rhine_tx(struct net_device *dev)
else
dev->stats.collisions += txstatus & 0x0F;
if (debug > 6)
- printk(KERN_DEBUG "collisions: %1.1x:%1.1x\n",
- (txstatus >> 3) & 0xF,
- txstatus & 0xF);
+ netdev_dbg(dev, "collisions: %1.1x:%1.1x\n",
+ (txstatus >> 3) & 0xF,
+ txstatus & 0xF);
dev->stats.tx_bytes += rp->tx_skbuff[entry]->len;
dev->stats.tx_packets++;
}
@@ -1703,7 +1700,7 @@ static void rhine_tx(struct net_device *dev)
static inline u16 rhine_get_vlan_tci(struct sk_buff *skb, int data_size)
{
u8 *trailer = (u8 *)skb->data + ((data_size + 3) & ~3) + 2;
- return ntohs(*(u16 *)trailer);
+ return be16_to_cpup((__be16 *)trailer);
}
/* Process up to limit frames from receive ring */
@@ -1714,9 +1711,9 @@ static int rhine_rx(struct net_device *dev, int limit)
int entry = rp->cur_rx % RX_RING_SIZE;
if (debug > 4) {
- printk(KERN_DEBUG "%s: rhine_rx(), entry %d status %8.8x.\n",
- dev->name, entry,
- le32_to_cpu(rp->rx_head_desc->rx_status));
+ netdev_dbg(dev, "%s(), entry %d status %08x\n",
+ __func__, entry,
+ le32_to_cpu(rp->rx_head_desc->rx_status));
}
/* If EOP is set on the next entry, it's a new packet. Send it up. */
@@ -1730,26 +1727,26 @@ static int rhine_rx(struct net_device *dev, int limit)
break;
if (debug > 4)
- printk(KERN_DEBUG "rhine_rx() status is %8.8x.\n",
- desc_status);
+ netdev_dbg(dev, "%s() status is %08x\n",
+ __func__, desc_status);
if ((desc_status & (RxWholePkt | RxErr)) != RxWholePkt) {
if ((desc_status & RxWholePkt) != RxWholePkt) {
- printk(KERN_WARNING "%s: Oversized Ethernet "
- "frame spanned multiple buffers, entry "
- "%#x length %d status %8.8x!\n",
- dev->name, entry, data_size,
- desc_status);
- printk(KERN_WARNING "%s: Oversized Ethernet "
- "frame %p vs %p.\n", dev->name,
- rp->rx_head_desc, &rp->rx_ring[entry]);
+ netdev_warn(dev,
+ "Oversized Ethernet frame spanned multiple buffers, "
+ "entry %#x length %d status %08x!\n",
+ entry, data_size,
+ desc_status);
+ netdev_warn(dev,
+ "Oversized Ethernet frame %p vs %p\n",
+ rp->rx_head_desc,
+ &rp->rx_ring[entry]);
dev->stats.rx_length_errors++;
} else if (desc_status & RxErr) {
/* There was a error. */
if (debug > 2)
- printk(KERN_DEBUG "rhine_rx() Rx "
- "error was %8.8x.\n",
- desc_status);
+ netdev_dbg(dev, "%s() Rx error was %08x\n",
+ __func__, desc_status);
dev->stats.rx_errors++;
if (desc_status & 0x0030)
dev->stats.rx_length_errors++;
@@ -1791,9 +1788,7 @@ static int rhine_rx(struct net_device *dev, int limit)
} else {
skb = rp->rx_skbuff[entry];
if (skb == NULL) {
- printk(KERN_ERR "%s: Inconsistent Rx "
- "descriptor chain.\n",
- dev->name);
+ netdev_err(dev, "Inconsistent Rx descriptor chain\n");
break;
}
rp->rx_skbuff[entry] = NULL;
@@ -1886,9 +1881,8 @@ static void rhine_restart_tx(struct net_device *dev) {
else {
/* This should never happen */
if (debug > 1)
- printk(KERN_WARNING "%s: rhine_restart_tx() "
- "Another error occurred %8.8x.\n",
- dev->name, intr_status);
+ netdev_warn(dev, "%s() Another error occurred %08x\n",
+ __func__, intr_status);
}
}
@@ -1909,21 +1903,19 @@ static void rhine_error(struct net_device *dev, int intr_status)
}
if (intr_status & IntrTxAborted) {
if (debug > 1)
- printk(KERN_INFO "%s: Abort %8.8x, frame dropped.\n",
- dev->name, intr_status);
+ netdev_info(dev, "Abort %08x, frame dropped\n",
+ intr_status);
}
if (intr_status & IntrTxUnderrun) {
if (rp->tx_thresh < 0xE0)
BYTE_REG_BITS_SET((rp->tx_thresh += 0x20), 0x80, ioaddr + TxConfig);
if (debug > 1)
- printk(KERN_INFO "%s: Transmitter underrun, Tx "
- "threshold now %2.2x.\n",
- dev->name, rp->tx_thresh);
+ netdev_info(dev, "Transmitter underrun, Tx threshold now %02x\n",
+ rp->tx_thresh);
}
if (intr_status & IntrTxDescRace) {
if (debug > 2)
- printk(KERN_INFO "%s: Tx descriptor write-back race.\n",
- dev->name);
+ netdev_info(dev, "Tx descriptor write-back race\n");
}
if ((intr_status & IntrTxError) &&
(intr_status & (IntrTxAborted |
@@ -1932,9 +1924,8 @@ static void rhine_error(struct net_device *dev, int intr_status)
BYTE_REG_BITS_SET((rp->tx_thresh += 0x20), 0x80, ioaddr + TxConfig);
}
if (debug > 1)
- printk(KERN_INFO "%s: Unspecified error. Tx "
- "threshold now %2.2x.\n",
- dev->name, rp->tx_thresh);
+ netdev_info(dev, "Unspecified error. Tx threshold now %02x\n",
+ rp->tx_thresh);
}
if (intr_status & (IntrTxAborted | IntrTxUnderrun | IntrTxDescRace |
IntrTxError))
@@ -1944,8 +1935,8 @@ static void rhine_error(struct net_device *dev, int intr_status)
IntrTxError | IntrTxAborted | IntrNormalSummary |
IntrTxDescRace)) {
if (debug > 1)
- printk(KERN_ERR "%s: Something Wicked happened! "
- "%8.8x.\n", dev->name, intr_status);
+ netdev_err(dev, "Something Wicked happened! %08x\n",
+ intr_status);
}
spin_unlock(&rp->lock);
@@ -2145,9 +2136,8 @@ static int rhine_close(struct net_device *dev)
spin_lock_irq(&rp->lock);
if (debug > 1)
- printk(KERN_DEBUG "%s: Shutting down ethercard, "
- "status was %4.4x.\n",
- dev->name, ioread16(ioaddr + ChipCmd));
+ netdev_dbg(dev, "Shutting down ethercard, status was %04x\n",
+ ioread16(ioaddr + ChipCmd));
/* Switch to loopback mode to avoid hardware races. */
iowrite8(rp->tx_thresh | 0x02, ioaddr + TxConfig);
@@ -2265,12 +2255,12 @@ static int rhine_resume(struct pci_dev *pdev)
return 0;
if (request_irq(dev->irq, rhine_interrupt, IRQF_SHARED, dev->name, dev))
- printk(KERN_ERR "via-rhine %s: request_irq failed\n", dev->name);
+ netdev_err(dev, "request_irq failed\n");
ret = pci_set_power_state(pdev, PCI_D0);
if (debug > 1)
- printk(KERN_INFO "%s: Entering power state D0 %s (%d).\n",
- dev->name, ret ? "failed" : "succeeded", ret);
+ netdev_info(dev, "Entering power state D0 %s (%d)\n",
+ ret ? "failed" : "succeeded", ret);
pci_restore_state(pdev);
@@ -2326,17 +2316,15 @@ static int __init rhine_init(void)
{
/* when a module, this is printed whether or not devices are found in probe */
#ifdef MODULE
- printk(version);
+ pr_info("%s\n", version);
#endif
if (dmi_check_system(rhine_dmi_table)) {
/* these BIOSes fail at PXE boot if chip is in D3 */
avoid_D3 = 1;
- printk(KERN_WARNING "%s: Broken BIOS detected, avoid_D3 "
- "enabled.\n",
- DRV_NAME);
+ pr_warn("Broken BIOS detected, avoid_D3 enabled\n");
}
else if (avoid_D3)
- printk(KERN_INFO "%s: avoid_D3 set.\n", DRV_NAME);
+ pr_info("avoid_D3 set\n");
return pci_register_driver(&rhine_driver);
}
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 4fe05175384..06daa9d6fee 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -2600,8 +2600,7 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb,
/*
* Handle hardware checksum
*/
- if ((dev->features & NETIF_F_IP_CSUM) &&
- (skb->ip_summed == CHECKSUM_PARTIAL)) {
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
const struct iphdr *ip = ip_hdr(skb);
if (ip->protocol == IPPROTO_TCP)
td_ptr->tdesc1.TCR |= TCR0_TCPCK;
@@ -2841,6 +2840,7 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
dev->ethtool_ops = &velocity_ethtool_ops;
netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT);
+ dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_HW_VLAN_TX;
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM;
@@ -3182,7 +3182,8 @@ static void velocity_ethtool_down(struct net_device *dev)
pci_set_power_state(vptr->pdev, PCI_D3hot);
}
-static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+static int velocity_get_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
{
struct velocity_info *vptr = netdev_priv(dev);
struct mac_regs __iomem *regs = vptr->mac_regs;
@@ -3228,12 +3229,14 @@ static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd
break;
}
}
+
if (status & VELOCITY_SPEED_1000)
- cmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(cmd, SPEED_1000);
else if (status & VELOCITY_SPEED_100)
- cmd->speed = SPEED_100;
+ ethtool_cmd_speed_set(cmd, SPEED_100);
else
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
+
cmd->autoneg = (status & VELOCITY_AUTONEG_ENABLE) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
cmd->port = PORT_TP;
cmd->transceiver = XCVR_INTERNAL;
@@ -3247,9 +3250,11 @@ static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd
return 0;
}
-static int velocity_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+static int velocity_set_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
{
struct velocity_info *vptr = netdev_priv(dev);
+ u32 speed = ethtool_cmd_speed(cmd);
u32 curr_status;
u32 new_status = 0;
int ret = 0;
@@ -3258,9 +3263,9 @@ static int velocity_set_settings(struct net_device *dev, struct ethtool_cmd *cmd
curr_status &= (~VELOCITY_LINK_FAIL);
new_status |= ((cmd->autoneg) ? VELOCITY_AUTONEG_ENABLE : 0);
- new_status |= ((cmd->speed == SPEED_1000) ? VELOCITY_SPEED_1000 : 0);
- new_status |= ((cmd->speed == SPEED_100) ? VELOCITY_SPEED_100 : 0);
- new_status |= ((cmd->speed == SPEED_10) ? VELOCITY_SPEED_10 : 0);
+ new_status |= ((speed == SPEED_1000) ? VELOCITY_SPEED_1000 : 0);
+ new_status |= ((speed == SPEED_100) ? VELOCITY_SPEED_100 : 0);
+ new_status |= ((speed == SPEED_10) ? VELOCITY_SPEED_10 : 0);
new_status |= ((cmd->duplex == DUPLEX_FULL) ? VELOCITY_DUPLEX_FULL : 0);
if ((new_status & VELOCITY_AUTONEG_ENABLE) &&
@@ -3457,13 +3462,10 @@ static const struct ethtool_ops velocity_ethtool_ops = {
.get_settings = velocity_get_settings,
.set_settings = velocity_set_settings,
.get_drvinfo = velocity_get_drvinfo,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
.get_wol = velocity_ethtool_get_wol,
.set_wol = velocity_ethtool_set_wol,
.get_msglevel = velocity_get_msglevel,
.set_msglevel = velocity_set_msglevel,
- .set_sg = ethtool_op_set_sg,
.get_link = velocity_get_link,
.get_coalesce = velocity_get_coalesce,
.set_coalesce = velocity_set_coalesce,
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 82dba5aaf42..0cb0b063267 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -710,17 +710,6 @@ static int virtnet_close(struct net_device *dev)
return 0;
}
-static int virtnet_set_tx_csum(struct net_device *dev, u32 data)
-{
- struct virtnet_info *vi = netdev_priv(dev);
- struct virtio_device *vdev = vi->vdev;
-
- if (data && !virtio_has_feature(vdev, VIRTIO_NET_F_CSUM))
- return -ENOSYS;
-
- return ethtool_op_set_tx_hw_csum(dev, data);
-}
-
static void virtnet_set_rx_mode(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
@@ -822,10 +811,6 @@ static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)
}
static const struct ethtool_ops virtnet_ethtool_ops = {
- .set_tx_csum = virtnet_set_tx_csum,
- .set_sg = ethtool_op_set_sg,
- .set_tso = ethtool_op_set_tso,
- .set_ufo = ethtool_op_set_ufo,
.get_link = ethtool_op_get_link,
};
@@ -912,22 +897,29 @@ static int virtnet_probe(struct virtio_device *vdev)
SET_NETDEV_DEV(dev, &vdev->dev);
/* Do we support "hardware" checksums? */
- if (csum && virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) {
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) {
/* This opens up the world of extra features. */
- dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
- if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
- dev->features |= NETIF_F_TSO | NETIF_F_UFO
+ dev->hw_features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
+ if (csum)
+ dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
+
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
+ dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO
| NETIF_F_TSO_ECN | NETIF_F_TSO6;
}
/* Individual feature bits: what can host handle? */
- if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO4))
- dev->features |= NETIF_F_TSO;
- if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO6))
- dev->features |= NETIF_F_TSO6;
- if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
- dev->features |= NETIF_F_TSO_ECN;
- if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO))
- dev->features |= NETIF_F_UFO;
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO4))
+ dev->hw_features |= NETIF_F_TSO;
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO6))
+ dev->hw_features |= NETIF_F_TSO6;
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
+ dev->hw_features |= NETIF_F_TSO_ECN;
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO))
+ dev->hw_features |= NETIF_F_UFO;
+
+ if (gso)
+ dev->features |= dev->hw_features & (NETIF_F_ALL_TSO|NETIF_F_UFO);
+ /* (!csum && gso) case will be fixed by register_netdev() */
}
/* Configuration may specify what MAC to use. Otherwise random. */
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index c16ed961153..fa6e2ac7475 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -1083,7 +1083,7 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter,
struct sk_buff *skb,
union Vmxnet3_GenericDesc *gdesc)
{
- if (!gdesc->rcd.cnc && adapter->rxcsum) {
+ if (!gdesc->rcd.cnc && adapter->netdev->features & NETIF_F_RXCSUM) {
/* typical case: TCP/UDP over IP and both csums are correct */
if ((le32_to_cpu(gdesc->dword[3]) & VMXNET3_RCD_CSUM_OK) ==
VMXNET3_RCD_CSUM_OK) {
@@ -2082,10 +2082,10 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
devRead->misc.ddLen = cpu_to_le32(sizeof(struct vmxnet3_adapter));
/* set up feature flags */
- if (adapter->rxcsum)
+ if (adapter->netdev->features & NETIF_F_RXCSUM)
devRead->misc.uptFeatures |= UPT1_F_RXCSUM;
- if (adapter->lro) {
+ if (adapter->netdev->features & NETIF_F_LRO) {
devRead->misc.uptFeatures |= UPT1_F_LRO;
devRead->misc.maxNumRxSG = cpu_to_le16(1 + MAX_SKB_FRAGS);
}
@@ -2594,9 +2594,6 @@ vmxnet3_change_mtu(struct net_device *netdev, int new_mtu)
if (new_mtu < VMXNET3_MIN_MTU || new_mtu > VMXNET3_MAX_MTU)
return -EINVAL;
- if (new_mtu > 1500 && !adapter->jumbo_frame)
- return -EINVAL;
-
netdev->mtu = new_mtu;
/*
@@ -2642,28 +2639,18 @@ vmxnet3_declare_features(struct vmxnet3_adapter *adapter, bool dma64)
{
struct net_device *netdev = adapter->netdev;
- netdev->features = NETIF_F_SG |
- NETIF_F_HW_CSUM |
- NETIF_F_HW_VLAN_TX |
- NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_FILTER |
- NETIF_F_TSO |
- NETIF_F_TSO6 |
- NETIF_F_LRO;
-
- printk(KERN_INFO "features: sg csum vlan jf tso tsoIPv6 lro");
-
- adapter->rxcsum = true;
- adapter->jumbo_frame = true;
- adapter->lro = true;
-
- if (dma64) {
+ netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM |
+ NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_TX |
+ NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_LRO;
+ if (dma64)
netdev->features |= NETIF_F_HIGHDMA;
- printk(" highDMA");
- }
+ netdev->vlan_features = netdev->hw_features & ~NETIF_F_HW_VLAN_TX;
+ netdev->features = netdev->hw_features |
+ NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
- netdev->vlan_features = netdev->features;
- printk("\n");
+ netdev_info(adapter->netdev,
+ "features: sg csum vlan jf tso tsoIPv6 lro%s\n",
+ dma64 ? " highDMA" : "");
}
@@ -2876,6 +2863,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
.ndo_start_xmit = vmxnet3_xmit_frame,
.ndo_set_mac_address = vmxnet3_set_mac_addr,
.ndo_change_mtu = vmxnet3_change_mtu,
+ .ndo_set_features = vmxnet3_set_features,
.ndo_get_stats = vmxnet3_get_stats,
.ndo_tx_timeout = vmxnet3_tx_timeout,
.ndo_set_multicast_list = vmxnet3_set_mc,
@@ -2896,6 +2884,9 @@ vmxnet3_probe_device(struct pci_dev *pdev,
int num_tx_queues;
int num_rx_queues;
+ if (!pci_msi_enabled())
+ enable_mq = 0;
+
#ifdef VMXNET3_RSS
if (enable_mq)
num_rx_queues = min(VMXNET3_DEVICE_MAX_RX_QUEUES,
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index 976467253d2..dc959fe27aa 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -33,40 +33,6 @@ struct vmxnet3_stat_desc {
};
-static u32
-vmxnet3_get_rx_csum(struct net_device *netdev)
-{
- struct vmxnet3_adapter *adapter = netdev_priv(netdev);
- return adapter->rxcsum;
-}
-
-
-static int
-vmxnet3_set_rx_csum(struct net_device *netdev, u32 val)
-{
- struct vmxnet3_adapter *adapter = netdev_priv(netdev);
- unsigned long flags;
-
- if (adapter->rxcsum != val) {
- adapter->rxcsum = val;
- if (netif_running(netdev)) {
- if (val)
- adapter->shared->devRead.misc.uptFeatures |=
- UPT1_F_RXCSUM;
- else
- adapter->shared->devRead.misc.uptFeatures &=
- ~UPT1_F_RXCSUM;
-
- spin_lock_irqsave(&adapter->cmd_lock, flags);
- VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
- VMXNET3_CMD_UPDATE_FEATURE);
- spin_unlock_irqrestore(&adapter->cmd_lock, flags);
- }
- }
- return 0;
-}
-
-
/* per tq stats maintained by the device */
static const struct vmxnet3_stat_desc
vmxnet3_tq_dev_stats[] = {
@@ -296,31 +262,28 @@ vmxnet3_get_strings(struct net_device *netdev, u32 stringset, u8 *buf)
}
}
-static int
-vmxnet3_set_flags(struct net_device *netdev, u32 data)
+int vmxnet3_set_features(struct net_device *netdev, u32 features)
{
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
- u8 lro_requested = (data & ETH_FLAG_LRO) == 0 ? 0 : 1;
- u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1;
unsigned long flags;
+ u32 changed = features ^ netdev->features;
- if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
- return -EINVAL;
-
- if (lro_requested ^ lro_present) {
- /* toggle the LRO feature*/
- netdev->features ^= NETIF_F_LRO;
-
- /* Update private LRO flag */
- adapter->lro = lro_requested;
+ if (changed & (NETIF_F_RXCSUM|NETIF_F_LRO)) {
+ if (features & NETIF_F_RXCSUM)
+ adapter->shared->devRead.misc.uptFeatures |=
+ UPT1_F_RXCSUM;
+ else
+ adapter->shared->devRead.misc.uptFeatures &=
+ ~UPT1_F_RXCSUM;
/* update harware LRO capability accordingly */
- if (lro_requested)
+ if (features & NETIF_F_LRO)
adapter->shared->devRead.misc.uptFeatures |=
UPT1_F_LRO;
else
adapter->shared->devRead.misc.uptFeatures &=
~UPT1_F_LRO;
+
spin_lock_irqsave(&adapter->cmd_lock, flags);
VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
VMXNET3_CMD_UPDATE_FEATURE);
@@ -462,10 +425,10 @@ vmxnet3_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
ecmd->transceiver = XCVR_INTERNAL;
if (adapter->link_speed) {
- ecmd->speed = adapter->link_speed;
+ ethtool_cmd_speed_set(ecmd, adapter->link_speed);
ecmd->duplex = DUPLEX_FULL;
} else {
- ecmd->speed = -1;
+ ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1;
}
return 0;
@@ -657,17 +620,7 @@ static struct ethtool_ops vmxnet3_ethtool_ops = {
.get_wol = vmxnet3_get_wol,
.set_wol = vmxnet3_set_wol,
.get_link = ethtool_op_get_link,
- .get_rx_csum = vmxnet3_get_rx_csum,
- .set_rx_csum = vmxnet3_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_hw_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = ethtool_op_set_tso,
.get_strings = vmxnet3_get_strings,
- .get_flags = ethtool_op_get_flags,
- .set_flags = vmxnet3_set_flags,
.get_sset_count = vmxnet3_get_sset_count,
.get_ethtool_stats = vmxnet3_get_ethtool_stats,
.get_ringparam = vmxnet3_get_ringparam,
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
index fb5d245ac87..f50d36fdf40 100644
--- a/drivers/net/vmxnet3/vmxnet3_int.h
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -68,10 +68,10 @@
/*
* Version numbers
*/
-#define VMXNET3_DRIVER_VERSION_STRING "1.0.25.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING "1.1.9.0-k"
/* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM 0x01001900
+#define VMXNET3_DRIVER_VERSION_NUM 0x01010900
#if defined(CONFIG_PCI_MSI)
/* RSS only makes sense if MSI-X is supported. */
@@ -329,10 +329,6 @@ struct vmxnet3_adapter {
u8 __iomem *hw_addr0; /* for BAR 0 */
u8 __iomem *hw_addr1; /* for BAR 1 */
- /* feature control */
- bool rxcsum;
- bool lro;
- bool jumbo_frame;
#ifdef VMXNET3_RSS
struct UPT1_RSSConf *rss_conf;
bool rss;
@@ -404,6 +400,9 @@ void
vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter);
int
+vmxnet3_set_features(struct net_device *netdev, u32 features);
+
+int
vmxnet3_create_queues(struct vmxnet3_adapter *adapter,
u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size);
diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c
index 401bebf5950..32763b2dd73 100644
--- a/drivers/net/vxge/vxge-config.c
+++ b/drivers/net/vxge/vxge-config.c
@@ -159,16 +159,15 @@ vxge_hw_vpath_fw_api(struct __vxge_hw_virtualpath *vpath, u32 action,
u32 fw_memo, u32 offset, u64 *data0, u64 *data1,
u64 *steer_ctrl)
{
- struct vxge_hw_vpath_reg __iomem *vp_reg;
+ struct vxge_hw_vpath_reg __iomem *vp_reg = vpath->vp_reg;
enum vxge_hw_status status;
u64 val64;
- u32 retry = 0, max_retry = 100;
-
- vp_reg = vpath->vp_reg;
+ u32 retry = 0, max_retry = 3;
- if (vpath->vp_open) {
- max_retry = 3;
- spin_lock(&vpath->lock);
+ spin_lock(&vpath->lock);
+ if (!vpath->vp_open) {
+ spin_unlock(&vpath->lock);
+ max_retry = 100;
}
writeq(*data0, &vp_reg->rts_access_steer_data0);
@@ -1000,7 +999,7 @@ exit:
/**
* vxge_hw_device_hw_info_get - Get the hw information
* Returns the vpath mask that has the bits set for each vpath allocated
- * for the driver, FW version information and the first mac addresse for
+ * for the driver, FW version information, and the first mac address for
* each vpath
*/
enum vxge_hw_status __devinit
@@ -1064,9 +1063,10 @@ vxge_hw_device_hw_info_get(void __iomem *bar0,
val64 = readq(&toc->toc_vpath_pointer[i]);
+ spin_lock_init(&vpath.lock);
vpath.vp_reg = (struct vxge_hw_vpath_reg __iomem *)
(bar0 + val64);
- vpath.vp_open = 0;
+ vpath.vp_open = VXGE_HW_VP_NOT_OPEN;
status = __vxge_hw_vpath_pci_func_mode_get(&vpath, hw_info);
if (status != VXGE_HW_OK)
@@ -1090,7 +1090,7 @@ vxge_hw_device_hw_info_get(void __iomem *bar0,
val64 = readq(&toc->toc_vpath_pointer[i]);
vpath.vp_reg = (struct vxge_hw_vpath_reg __iomem *)
(bar0 + val64);
- vpath.vp_open = 0;
+ vpath.vp_open = VXGE_HW_VP_NOT_OPEN;
status = __vxge_hw_vpath_addr_get(&vpath,
hw_info->mac_addrs[i],
@@ -4646,7 +4646,27 @@ static void __vxge_hw_vp_terminate(struct __vxge_hw_device *hldev, u32 vp_id)
vpath->hldev->tim_int_mask1, vpath->vp_id);
hldev->stats.hw_dev_info_stats.vpath_info[vpath->vp_id] = NULL;
- memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
+ /* If the whole struct __vxge_hw_virtualpath is zeroed, nothing will
+ * work after the interface is brought down.
+ */
+ spin_lock(&vpath->lock);
+ vpath->vp_open = VXGE_HW_VP_NOT_OPEN;
+ spin_unlock(&vpath->lock);
+
+ vpath->vpmgmt_reg = NULL;
+ vpath->nofl_db = NULL;
+ vpath->max_mtu = 0;
+ vpath->vsport_number = 0;
+ vpath->max_kdfc_db = 0;
+ vpath->max_nofl_db = 0;
+ vpath->ringh = NULL;
+ vpath->fifoh = NULL;
+ memset(&vpath->vpath_handles, 0, sizeof(struct list_head));
+ vpath->stats_block = 0;
+ vpath->hw_stats = NULL;
+ vpath->hw_stats_sav = NULL;
+ vpath->sw_stats = NULL;
+
exit:
return;
}
@@ -4670,7 +4690,7 @@ __vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id,
vpath = &hldev->virtual_paths[vp_id];
- spin_lock_init(&hldev->virtual_paths[vp_id].lock);
+ spin_lock_init(&vpath->lock);
vpath->vp_id = vp_id;
vpath->vp_open = VXGE_HW_VP_OPEN;
vpath->hldev = hldev;
@@ -5019,10 +5039,6 @@ enum vxge_hw_status vxge_hw_vpath_close(struct __vxge_hw_vpath_handle *vp)
__vxge_hw_vp_terminate(devh, vp_id);
- spin_lock(&vpath->lock);
- vpath->vp_open = VXGE_HW_VP_NOT_OPEN;
- spin_unlock(&vpath->lock);
-
vpath_close_exit:
return status;
}
diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h
index 3c53aa732c9..359b9b9f804 100644
--- a/drivers/net/vxge/vxge-config.h
+++ b/drivers/net/vxge/vxge-config.h
@@ -412,44 +412,48 @@ struct vxge_hw_vp_config {
* See also: struct vxge_hw_tim_intr_config{}.
*/
struct vxge_hw_device_config {
- u32 dma_blockpool_initial;
- u32 dma_blockpool_max;
-#define VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE 0
-#define VXGE_HW_INITIAL_DMA_BLOCK_POOL_SIZE 0
-#define VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE 4
-#define VXGE_HW_MAX_DMA_BLOCK_POOL_SIZE 4096
-
-#define VXGE_HW_MAX_PAYLOAD_SIZE_512 2
-
- u32 intr_mode;
-#define VXGE_HW_INTR_MODE_IRQLINE 0
-#define VXGE_HW_INTR_MODE_MSIX 1
-#define VXGE_HW_INTR_MODE_MSIX_ONE_SHOT 2
-
-#define VXGE_HW_INTR_MODE_DEF 0
-
- u32 rth_en;
-#define VXGE_HW_RTH_DISABLE 0
-#define VXGE_HW_RTH_ENABLE 1
-#define VXGE_HW_RTH_DEFAULT 0
-
- u32 rth_it_type;
-#define VXGE_HW_RTH_IT_TYPE_SOLO_IT 0
-#define VXGE_HW_RTH_IT_TYPE_MULTI_IT 1
-#define VXGE_HW_RTH_IT_TYPE_DEFAULT 0
-
- u32 rts_mac_en;
+ u32 device_poll_millis;
+#define VXGE_HW_MIN_DEVICE_POLL_MILLIS 1
+#define VXGE_HW_MAX_DEVICE_POLL_MILLIS 100000
+#define VXGE_HW_DEF_DEVICE_POLL_MILLIS 1000
+
+ u32 dma_blockpool_initial;
+ u32 dma_blockpool_max;
+#define VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE 0
+#define VXGE_HW_INITIAL_DMA_BLOCK_POOL_SIZE 0
+#define VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE 4
+#define VXGE_HW_MAX_DMA_BLOCK_POOL_SIZE 4096
+
+#define VXGE_HW_MAX_PAYLOAD_SIZE_512 2
+
+ u32 intr_mode:2,
+#define VXGE_HW_INTR_MODE_IRQLINE 0
+#define VXGE_HW_INTR_MODE_MSIX 1
+#define VXGE_HW_INTR_MODE_MSIX_ONE_SHOT 2
+
+#define VXGE_HW_INTR_MODE_DEF 0
+
+ rth_en:1,
+#define VXGE_HW_RTH_DISABLE 0
+#define VXGE_HW_RTH_ENABLE 1
+#define VXGE_HW_RTH_DEFAULT 0
+
+ rth_it_type:1,
+#define VXGE_HW_RTH_IT_TYPE_SOLO_IT 0
+#define VXGE_HW_RTH_IT_TYPE_MULTI_IT 1
+#define VXGE_HW_RTH_IT_TYPE_DEFAULT 0
+
+ rts_mac_en:1,
#define VXGE_HW_RTS_MAC_DISABLE 0
#define VXGE_HW_RTS_MAC_ENABLE 1
#define VXGE_HW_RTS_MAC_DEFAULT 0
- struct vxge_hw_vp_config vp_config[VXGE_HW_MAX_VIRTUAL_PATHS];
-
- u32 device_poll_millis;
-#define VXGE_HW_MIN_DEVICE_POLL_MILLIS 1
-#define VXGE_HW_MAX_DEVICE_POLL_MILLIS 100000
-#define VXGE_HW_DEF_DEVICE_POLL_MILLIS 1000
+ hwts_en:1;
+#define VXGE_HW_HWTS_DISABLE 0
+#define VXGE_HW_HWTS_ENABLE 1
+#define VXGE_HW_HWTS_DEFAULT 1
+ struct vxge_hw_vp_config vp_config[VXGE_HW_MAX_VIRTUAL_PATHS];
};
/**
diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c
index c5eb034107f..92dd72d3f9d 100644
--- a/drivers/net/vxge/vxge-ethtool.c
+++ b/drivers/net/vxge/vxge-ethtool.c
@@ -33,7 +33,8 @@ static int vxge_ethtool_sset(struct net_device *dev, struct ethtool_cmd *info)
{
/* We currently only support 10Gb/FULL */
if ((info->autoneg == AUTONEG_ENABLE) ||
- (info->speed != SPEED_10000) || (info->duplex != DUPLEX_FULL))
+ (ethtool_cmd_speed(info) != SPEED_10000) ||
+ (info->duplex != DUPLEX_FULL))
return -EINVAL;
return 0;
@@ -58,10 +59,10 @@ static int vxge_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
info->transceiver = XCVR_EXTERNAL;
if (netif_carrier_ok(dev)) {
- info->speed = SPEED_10000;
+ ethtool_cmd_speed_set(info, SPEED_10000);
info->duplex = DUPLEX_FULL;
} else {
- info->speed = -1;
+ ethtool_cmd_speed_set(info, -1);
info->duplex = -1;
}
@@ -134,22 +135,29 @@ static void vxge_ethtool_gregs(struct net_device *dev,
/**
* vxge_ethtool_idnic - To physically identify the nic on the system.
* @dev : device pointer.
- * @id : pointer to the structure with identification parameters given by
- * ethtool.
+ * @state : requested LED state
*
* Used to physically identify the NIC on the system.
- * The Link LED will blink for a time specified by the user.
- * Return value:
* 0 on success
*/
-static int vxge_ethtool_idnic(struct net_device *dev, u32 data)
+static int vxge_ethtool_idnic(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
struct vxgedev *vdev = netdev_priv(dev);
struct __vxge_hw_device *hldev = vdev->devh;
- vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_ON);
- msleep_interruptible(data ? (data * HZ) : VXGE_MAX_FLICKER_TIME);
- vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_OFF);
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_ON);
+ break;
+
+ case ETHTOOL_ID_INACTIVE:
+ vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_OFF);
+ break;
+
+ default:
+ return -EINVAL;
+ }
return 0;
}
@@ -1064,35 +1072,6 @@ static int vxge_ethtool_get_regs_len(struct net_device *dev)
return sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath;
}
-static u32 vxge_get_rx_csum(struct net_device *dev)
-{
- struct vxgedev *vdev = netdev_priv(dev);
-
- return vdev->rx_csum;
-}
-
-static int vxge_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct vxgedev *vdev = netdev_priv(dev);
-
- if (data)
- vdev->rx_csum = 1;
- else
- vdev->rx_csum = 0;
-
- return 0;
-}
-
-static int vxge_ethtool_op_set_tso(struct net_device *dev, u32 data)
-{
- if (data)
- dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
- else
- dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-
- return 0;
-}
-
static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset)
{
struct vxgedev *vdev = netdev_priv(dev);
@@ -1112,40 +1091,6 @@ static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset)
}
}
-static int vxge_set_flags(struct net_device *dev, u32 data)
-{
- struct vxgedev *vdev = netdev_priv(dev);
- enum vxge_hw_status status;
-
- if (ethtool_invalid_flags(dev, data, ETH_FLAG_RXHASH))
- return -EINVAL;
-
- if (!!(data & ETH_FLAG_RXHASH) == vdev->devh->config.rth_en)
- return 0;
-
- if (netif_running(dev) || (vdev->config.rth_steering == NO_STEERING))
- return -EINVAL;
-
- vdev->devh->config.rth_en = !!(data & ETH_FLAG_RXHASH);
-
- /* Enabling RTH requires some of the logic in vxge_device_register and a
- * vpath reset. Due to these restrictions, only allow modification
- * while the interface is down.
- */
- status = vxge_reset_all_vpaths(vdev);
- if (status != VXGE_HW_OK) {
- vdev->devh->config.rth_en = !vdev->devh->config.rth_en;
- return -EFAULT;
- }
-
- if (vdev->devh->config.rth_en)
- dev->features |= NETIF_F_RXHASH;
- else
- dev->features &= ~NETIF_F_RXHASH;
-
- return 0;
-}
-
static int vxge_fw_flash(struct net_device *dev, struct ethtool_flash *parms)
{
struct vxgedev *vdev = netdev_priv(dev);
@@ -1174,19 +1119,10 @@ static const struct ethtool_ops vxge_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_pauseparam = vxge_ethtool_getpause_data,
.set_pauseparam = vxge_ethtool_setpause_data,
- .get_rx_csum = vxge_get_rx_csum,
- .set_rx_csum = vxge_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_ipv6_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = vxge_ethtool_op_set_tso,
.get_strings = vxge_ethtool_get_strings,
- .phys_id = vxge_ethtool_idnic,
+ .set_phys_id = vxge_ethtool_idnic,
.get_sset_count = vxge_ethtool_get_sset_count,
.get_ethtool_stats = vxge_get_ethtool_stats,
- .set_flags = vxge_set_flags,
.flash_device = vxge_fw_flash,
};
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index aff68c1118d..fc837cf6bd4 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -304,22 +304,14 @@ vxge_rx_complete(struct vxge_ring *ring, struct sk_buff *skb, u16 vlan,
"%s: %s:%d skb protocol = %d",
ring->ndev->name, __func__, __LINE__, skb->protocol);
- if (ring->gro_enable) {
- if (ring->vlgrp && ext_info->vlan &&
- (ring->vlan_tag_strip ==
- VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE))
- vlan_gro_receive(ring->napi_p, ring->vlgrp,
- ext_info->vlan, skb);
- else
- napi_gro_receive(ring->napi_p, skb);
- } else {
- if (ring->vlgrp && vlan &&
- (ring->vlan_tag_strip ==
- VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE))
- vlan_hwaccel_receive_skb(skb, ring->vlgrp, vlan);
- else
- netif_receive_skb(skb);
- }
+ if (ring->vlgrp && ext_info->vlan &&
+ (ring->vlan_tag_strip ==
+ VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE))
+ vlan_gro_receive(ring->napi_p, ring->vlgrp,
+ ext_info->vlan, skb);
+ else
+ napi_gro_receive(ring->napi_p, skb);
+
vxge_debug_entryexit(VXGE_TRACE,
"%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__);
}
@@ -490,7 +482,7 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
if ((ext_info.proto & VXGE_HW_FRAME_PROTO_TCP_OR_UDP) &&
!(ext_info.proto & VXGE_HW_FRAME_PROTO_IP_FRAG) &&
- ring->rx_csum && /* Offload Rx side CSUM */
+ (dev->features & NETIF_F_RXCSUM) && /* Offload Rx side CSUM */
ext_info.l3_cksum == VXGE_HW_L3_CKSUM_OK &&
ext_info.l4_cksum == VXGE_HW_L4_CKSUM_OK)
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -2094,11 +2086,9 @@ static int vxge_open_vpaths(struct vxgedev *vdev)
vdev->config.fifo_indicate_max_pkts;
vpath->fifo.tx_vector_no = 0;
vpath->ring.rx_vector_no = 0;
- vpath->ring.rx_csum = vdev->rx_csum;
vpath->ring.rx_hwts = vdev->rx_hwts;
vpath->is_open = 1;
vdev->vp_handles[i] = vpath->handle;
- vpath->ring.gro_enable = vdev->config.gro_enable;
vpath->ring.vlan_tag_strip = vdev->vlan_tag_strip;
vdev->stats.vpaths_open++;
} else {
@@ -2670,6 +2660,40 @@ static void vxge_poll_vp_lockup(unsigned long data)
mod_timer(&vdev->vp_lockup_timer, jiffies + HZ / 1000);
}
+static u32 vxge_fix_features(struct net_device *dev, u32 features)
+{
+ u32 changed = dev->features ^ features;
+
+ /* Enabling RTH requires some of the logic in vxge_device_register and a
+ * vpath reset. Due to these restrictions, only allow modification
+ * while the interface is down.
+ */
+ if ((changed & NETIF_F_RXHASH) && netif_running(dev))
+ features ^= NETIF_F_RXHASH;
+
+ return features;
+}
+
+static int vxge_set_features(struct net_device *dev, u32 features)
+{
+ struct vxgedev *vdev = netdev_priv(dev);
+ u32 changed = dev->features ^ features;
+
+ if (!(changed & NETIF_F_RXHASH))
+ return 0;
+
+ /* !netif_running() ensured by vxge_fix_features() */
+
+ vdev->devh->config.rth_en = !!(features & NETIF_F_RXHASH);
+ if (vxge_reset_all_vpaths(vdev) != VXGE_HW_OK) {
+ dev->features = features ^ NETIF_F_RXHASH;
+ vdev->devh->config.rth_en = !!(dev->features & NETIF_F_RXHASH);
+ return -EIO;
+ }
+
+ return 0;
+}
+
/**
* vxge_open
* @dev: pointer to the device structure.
@@ -3112,8 +3136,7 @@ vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats)
return net_stats;
}
-static enum vxge_hw_status vxge_timestamp_config(struct vxgedev *vdev,
- int enable)
+static enum vxge_hw_status vxge_timestamp_config(struct __vxge_hw_device *devh)
{
enum vxge_hw_status status;
u64 val64;
@@ -3123,27 +3146,24 @@ static enum vxge_hw_status vxge_timestamp_config(struct vxgedev *vdev,
* required for the driver to load (due to a hardware bug),
* there is no need to do anything special here.
*/
- if (enable)
- val64 = VXGE_HW_XMAC_TIMESTAMP_EN |
- VXGE_HW_XMAC_TIMESTAMP_USE_LINK_ID(0) |
- VXGE_HW_XMAC_TIMESTAMP_INTERVAL(0);
- else
- val64 = 0;
+ val64 = VXGE_HW_XMAC_TIMESTAMP_EN |
+ VXGE_HW_XMAC_TIMESTAMP_USE_LINK_ID(0) |
+ VXGE_HW_XMAC_TIMESTAMP_INTERVAL(0);
- status = vxge_hw_mgmt_reg_write(vdev->devh,
+ status = vxge_hw_mgmt_reg_write(devh,
vxge_hw_mgmt_reg_type_mrpcim,
0,
offsetof(struct vxge_hw_mrpcim_reg,
xmac_timestamp),
val64);
- vxge_hw_device_flush_io(vdev->devh);
+ vxge_hw_device_flush_io(devh);
+ devh->config.hwts_en = VXGE_HW_HWTS_ENABLE;
return status;
}
static int vxge_hwtstamp_ioctl(struct vxgedev *vdev, void __user *data)
{
struct hwtstamp_config config;
- enum vxge_hw_status status;
int i;
if (copy_from_user(&config, data, sizeof(config)))
@@ -3164,10 +3184,6 @@ static int vxge_hwtstamp_ioctl(struct vxgedev *vdev, void __user *data)
switch (config.rx_filter) {
case HWTSTAMP_FILTER_NONE:
- status = vxge_timestamp_config(vdev, 0);
- if (status != VXGE_HW_OK)
- return -EFAULT;
-
vdev->rx_hwts = 0;
config.rx_filter = HWTSTAMP_FILTER_NONE;
break;
@@ -3186,8 +3202,7 @@ static int vxge_hwtstamp_ioctl(struct vxgedev *vdev, void __user *data)
case HWTSTAMP_FILTER_PTP_V2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
- status = vxge_timestamp_config(vdev, 1);
- if (status != VXGE_HW_OK)
+ if (vdev->devh->config.hwts_en != VXGE_HW_HWTS_ENABLE)
return -EFAULT;
vdev->rx_hwts = 1;
@@ -3378,6 +3393,8 @@ static const struct net_device_ops vxge_netdev_ops = {
.ndo_do_ioctl = vxge_ioctl,
.ndo_set_mac_address = vxge_set_mac_addr,
.ndo_change_mtu = vxge_change_mtu,
+ .ndo_fix_features = vxge_fix_features,
+ .ndo_set_features = vxge_set_features,
.ndo_vlan_rx_register = vxge_vlan_rx_register,
.ndo_vlan_rx_kill_vid = vxge_vlan_rx_kill_vid,
.ndo_vlan_rx_add_vid = vxge_vlan_rx_add_vid,
@@ -3424,14 +3441,21 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
vdev->devh = hldev;
vdev->pdev = hldev->pdev;
memcpy(&vdev->config, config, sizeof(struct vxge_config));
- vdev->rx_csum = 1; /* Enable Rx CSUM by default. */
vdev->rx_hwts = 0;
vdev->titan1 = (vdev->pdev->revision == VXGE_HW_TITAN1_PCI_REVISION);
SET_NETDEV_DEV(ndev, &vdev->pdev->dev);
- ndev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_FILTER;
+ ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_SG |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_TSO | NETIF_F_TSO6 |
+ NETIF_F_HW_VLAN_TX;
+ if (vdev->config.rth_steering != NO_STEERING)
+ ndev->hw_features |= NETIF_F_RXHASH;
+
+ ndev->features |= ndev->hw_features |
+ NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
+
/* Driver entry points */
ndev->irq = vdev->pdev->irq;
ndev->base_addr = (unsigned long) hldev->bar0;
@@ -3443,11 +3467,6 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
vxge_initialize_ethtool_ops(ndev);
- if (vdev->config.rth_steering != NO_STEERING) {
- ndev->features |= NETIF_F_RXHASH;
- hldev->config.rth_en = VXGE_HW_RTH_ENABLE;
- }
-
/* Allocate memory for vpath */
vdev->vpaths = kzalloc((sizeof(struct vxge_vpath)) *
no_of_vpath, GFP_KERNEL);
@@ -3459,9 +3478,6 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
goto _out1;
}
- ndev->features |= NETIF_F_SG;
-
- ndev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
"%s : checksuming enabled", __func__);
@@ -3471,11 +3487,6 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
"%s : using High DMA", __func__);
}
- ndev->features |= NETIF_F_TSO | NETIF_F_TSO6;
-
- if (vdev->config.gro_enable)
- ndev->features |= NETIF_F_GRO;
-
ret = register_netdev(ndev);
if (ret) {
vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
@@ -4005,15 +4016,6 @@ static void __devinit vxge_print_parm(struct vxgedev *vdev, u64 vpath_mask)
vdev->config.tx_steering_type = 0;
}
- if (vdev->config.gro_enable) {
- vxge_debug_init(VXGE_ERR,
- "%s: Generic receive offload enabled",
- vdev->ndev->name);
- } else
- vxge_debug_init(VXGE_TRACE,
- "%s: Generic receive offload disabled",
- vdev->ndev->name);
-
if (vdev->config.addr_learn_en)
vxge_debug_init(VXGE_TRACE,
"%s: MAC Address learning enabled", vdev->ndev->name);
@@ -4575,12 +4577,29 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
goto _exit4;
}
+ /* Always enable HWTS. This will always cause the FCS to be invalid,
+ * due to the fact that HWTS is using the FCS as the location of the
+ * timestamp. The HW FCS checking will still correctly determine if
+ * there is a valid checksum, and the FCS is being removed by the driver
+ * anyway. So no fucntionality is being lost. Since it is always
+ * enabled, we now simply use the ioctl call to set whether or not the
+ * driver should be paying attention to the HWTS.
+ */
+ if (is_privileged == VXGE_HW_OK) {
+ status = vxge_timestamp_config(hldev);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR, "%s: HWTS enable failed",
+ VXGE_DRIVER_NAME);
+ ret = -EFAULT;
+ goto _exit4;
+ }
+ }
+
vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_LL);
/* set private device info */
pci_set_drvdata(pdev, hldev);
- ll_config->gro_enable = VXGE_GRO_ALWAYS_AGGREGATE;
ll_config->fifo_indicate_max_pkts = VXGE_FIFO_INDICATE_MAX_PKTS;
ll_config->addr_learn_en = addr_learn_en;
ll_config->rth_algorithm = RTH_ALG_JENKINS;
diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h
index 40474f0da57..ed120aba443 100644
--- a/drivers/net/vxge/vxge-main.h
+++ b/drivers/net/vxge/vxge-main.h
@@ -168,9 +168,6 @@ struct vxge_config {
#define NEW_NAPI_WEIGHT 64
int napi_weight;
-#define VXGE_GRO_DONOT_AGGREGATE 0
-#define VXGE_GRO_ALWAYS_AGGREGATE 1
- int gro_enable;
int intr_type;
#define INTA 0
#define MSI 1
@@ -290,13 +287,11 @@ struct vxge_ring {
unsigned long interrupt_count;
unsigned long jiffies;
- /* copy of the flag indicating whether rx_csum is to be used */
- u32 rx_csum:1,
- rx_hwts:1;
+ /* copy of the flag indicating whether rx_hwts is to be used */
+ u32 rx_hwts:1;
int pkts_processed;
int budget;
- int gro_enable;
struct napi_struct napi;
struct napi_struct *napi_p;
@@ -369,9 +364,8 @@ struct vxgedev {
*/
u16 all_multi_flg;
- /* A flag indicating whether rx_csum is to be used or not. */
- u32 rx_csum:1,
- rx_hwts:1,
+ /* A flag indicating whether rx_hwts is to be used or not. */
+ u32 rx_hwts:1,
titan1:1;
struct vxge_msix_entry *vxge_entries;
diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h
index 6c2fc0b72af..4a518a3b131 100644
--- a/drivers/net/vxge/vxge-traffic.h
+++ b/drivers/net/vxge/vxge-traffic.h
@@ -240,7 +240,7 @@ struct vxge_hw_tim_intr_config {
u32 btimer_val;
#define VXGE_HW_MIN_TIM_BTIMER_VAL 0
#define VXGE_HW_MAX_TIM_BTIMER_VAL 67108864
-#define VXGE_HW_USE_FLASH_DEFAULT 0xffffffff
+#define VXGE_HW_USE_FLASH_DEFAULT (~0)
u32 timer_ac_en;
#define VXGE_HW_TIM_TIMER_AC_ENABLE 1
diff --git a/drivers/net/vxge/vxge-version.h b/drivers/net/vxge/vxge-version.h
index 581e21525e8..b9efa28bab3 100644
--- a/drivers/net/vxge/vxge-version.h
+++ b/drivers/net/vxge/vxge-version.h
@@ -16,8 +16,8 @@
#define VXGE_VERSION_MAJOR "2"
#define VXGE_VERSION_MINOR "5"
-#define VXGE_VERSION_FIX "2"
-#define VXGE_VERSION_BUILD "22259"
+#define VXGE_VERSION_FIX "3"
+#define VXGE_VERSION_BUILD "22640"
#define VXGE_VERSION_FOR "k"
#define VXGE_FW_VER(maj, min, bld) (((maj) << 16) + ((min) << 8) + (bld))
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c
index 1481a446fef..21b104db5a9 100644
--- a/drivers/net/wan/dlci.c
+++ b/drivers/net/wan/dlci.c
@@ -341,10 +341,6 @@ static int dlci_add(struct dlci_add *dlci)
}
}
- err = dev_alloc_name(master, master->name);
- if (err < 0)
- goto err2;
-
*(short *)(master->dev_addr) = dlci->dlci;
dlp = netdev_priv(master);
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 0edb535bb2b..fc433f28c04 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -1070,7 +1070,7 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
hdlc_device *hdlc = dev_to_hdlc(frad);
pvc_device *pvc;
struct net_device *dev;
- int result, used;
+ int used;
if ((pvc = add_pvc(frad, dlci)) == NULL) {
printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n",
@@ -1106,13 +1106,6 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
dev->tx_queue_len = 0;
dev->ml_priv = pvc;
- result = dev_alloc_name(dev, dev->name);
- if (result < 0) {
- free_netdev(dev);
- delete_unused_pvcs(hdlc);
- return result;
- }
-
if (register_netdevice(dev) != 0) {
free_netdev(dev);
delete_unused_pvcs(hdlc);
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
index 7f5bb913c8b..eec463f99c0 100644
--- a/drivers/net/wan/lapbether.c
+++ b/drivers/net/wan/lapbether.c
@@ -338,10 +338,6 @@ static int lapbeth_new_device(struct net_device *dev)
dev_hold(dev);
lapbeth->ethdev = dev;
- rc = dev_alloc_name(ndev, ndev->name);
- if (rc < 0)
- goto fail;
-
rc = -EIO;
if (register_netdevice(ndev))
goto fail;
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 7aeb113cbb9..f354bd4e121 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -284,5 +284,6 @@ source "drivers/net/wireless/rtlwifi/Kconfig"
source "drivers/net/wireless/wl1251/Kconfig"
source "drivers/net/wireless/wl12xx/Kconfig"
source "drivers/net/wireless/zd1211rw/Kconfig"
+source "drivers/net/wireless/mwifiex/Kconfig"
endif # WLAN
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index ddd3fb6ba1d..7bba6a82b87 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -56,3 +56,5 @@ obj-$(CONFIG_WL12XX) += wl12xx/
obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/
obj-$(CONFIG_IWM) += iwmc3200wifi/
+
+obj-$(CONFIG_MWIFIEX) += mwifiex/
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index 92c216263ee..d1b23067619 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -24,7 +24,6 @@ config ATH_DEBUG
source "drivers/net/wireless/ath/ath5k/Kconfig"
source "drivers/net/wireless/ath/ath9k/Kconfig"
-source "drivers/net/wireless/ath/ar9170/Kconfig"
source "drivers/net/wireless/ath/carl9170/Kconfig"
endif
diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile
index 6d711ec97ec..0e8f528c81c 100644
--- a/drivers/net/wireless/ath/Makefile
+++ b/drivers/net/wireless/ath/Makefile
@@ -1,6 +1,5 @@
obj-$(CONFIG_ATH5K) += ath5k/
obj-$(CONFIG_ATH9K_HW) += ath9k/
-obj-$(CONFIG_AR9170_USB) += ar9170/
obj-$(CONFIG_CARL9170) += carl9170/
obj-$(CONFIG_ATH_COMMON) += ath.o
diff --git a/drivers/net/wireless/ath/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig
deleted file mode 100644
index 7b9672b0d09..00000000000
--- a/drivers/net/wireless/ath/ar9170/Kconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-config AR9170_USB
- tristate "Atheros AR9170 802.11n USB support (OBSOLETE)"
- depends on USB && MAC80211
- select FW_LOADER
- help
- This driver is going to get replaced by carl9170.
-
- This is a driver for the Atheros "otus" 802.11n USB devices.
-
- These devices require additional firmware (2 files).
- For now, these files can be downloaded from here:
-
- http://wireless.kernel.org/en/users/Drivers/ar9170
-
- If you choose to build a module, it'll be called ar9170usb.
-
-config AR9170_LEDS
- bool
- depends on AR9170_USB && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = AR9170_USB)
- default y
diff --git a/drivers/net/wireless/ath/ar9170/Makefile b/drivers/net/wireless/ath/ar9170/Makefile
deleted file mode 100644
index 8d91c7ee321..00000000000
--- a/drivers/net/wireless/ath/ar9170/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-ar9170usb-objs := usb.o main.o cmd.o mac.o phy.o led.o
-
-obj-$(CONFIG_AR9170_USB) += ar9170usb.o
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
deleted file mode 100644
index 371e4ce4952..00000000000
--- a/drivers/net/wireless/ath/ar9170/ar9170.h
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Driver specific definitions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- * Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef __AR9170_H
-#define __AR9170_H
-
-#include <linux/completion.h>
-#include <linux/spinlock.h>
-#include <net/cfg80211.h>
-#include <net/mac80211.h>
-#ifdef CONFIG_AR9170_LEDS
-#include <linux/leds.h>
-#endif /* CONFIG_AR9170_LEDS */
-#include "eeprom.h"
-#include "hw.h"
-
-#include "../regd.h"
-
-#define PAYLOAD_MAX (AR9170_MAX_CMD_LEN/4 - 1)
-
-enum ar9170_bw {
- AR9170_BW_20,
- AR9170_BW_40_BELOW,
- AR9170_BW_40_ABOVE,
-
- __AR9170_NUM_BW,
-};
-
-static inline enum ar9170_bw nl80211_to_ar9170(enum nl80211_channel_type type)
-{
- switch (type) {
- case NL80211_CHAN_NO_HT:
- case NL80211_CHAN_HT20:
- return AR9170_BW_20;
- case NL80211_CHAN_HT40MINUS:
- return AR9170_BW_40_BELOW;
- case NL80211_CHAN_HT40PLUS:
- return AR9170_BW_40_ABOVE;
- default:
- BUG();
- }
-}
-
-enum ar9170_rf_init_mode {
- AR9170_RFI_NONE,
- AR9170_RFI_WARM,
- AR9170_RFI_COLD,
-};
-
-#define AR9170_MAX_RX_BUFFER_SIZE 8192
-
-#ifdef CONFIG_AR9170_LEDS
-struct ar9170;
-
-struct ar9170_led {
- struct ar9170 *ar;
- struct led_classdev l;
- char name[32];
- unsigned int toggled;
- bool last_state;
- bool registered;
-};
-
-#endif /* CONFIG_AR9170_LEDS */
-
-enum ar9170_device_state {
- AR9170_UNKNOWN_STATE,
- AR9170_STOPPED,
- AR9170_IDLE,
- AR9170_STARTED,
-};
-
-struct ar9170_rxstream_mpdu_merge {
- struct ar9170_rx_head plcp;
- bool has_plcp;
-};
-
-struct ar9170_tx_queue_stats {
- unsigned int len;
- unsigned int limit;
- unsigned int count;
-};
-
-#define AR9170_QUEUE_TIMEOUT 64
-#define AR9170_TX_TIMEOUT 8
-#define AR9170_JANITOR_DELAY 128
-#define AR9170_TX_INVALID_RATE 0xffffffff
-
-#define AR9170_NUM_TX_LIMIT_HARD AR9170_TXQ_DEPTH
-#define AR9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH - 10)
-
-struct ar9170 {
- struct ieee80211_hw *hw;
- struct ath_common common;
- struct mutex mutex;
- enum ar9170_device_state state;
- bool registered;
- unsigned long bad_hw_nagger;
-
- int (*open)(struct ar9170 *);
- void (*stop)(struct ar9170 *);
- int (*tx)(struct ar9170 *, struct sk_buff *);
- int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 ,
- void *, u32 , void *);
- void (*callback_cmd)(struct ar9170 *, u32 , void *);
- int (*flush)(struct ar9170 *);
-
- /* interface mode settings */
- struct ieee80211_vif *vif;
-
- /* beaconing */
- struct sk_buff *beacon;
- struct work_struct beacon_work;
- bool enable_beacon;
-
- /* cryptographic engine */
- u64 usedkeys;
- bool rx_software_decryption;
- bool disable_offload;
-
- /* filter settings */
- u64 cur_mc_hash;
- u32 cur_filter;
- unsigned int filter_state;
- bool sniffer_enabled;
-
- /* PHY */
- struct ieee80211_channel *channel;
- int noise[4];
-
- /* power calibration data */
- u8 power_5G_leg[4];
- u8 power_2G_cck[4];
- u8 power_2G_ofdm[4];
- u8 power_5G_ht20[8];
- u8 power_5G_ht40[8];
- u8 power_2G_ht20[8];
- u8 power_2G_ht40[8];
-
- u8 phy_heavy_clip;
-
-#ifdef CONFIG_AR9170_LEDS
- struct delayed_work led_work;
- struct ar9170_led leds[AR9170_NUM_LEDS];
-#endif /* CONFIG_AR9170_LEDS */
-
- /* qos queue settings */
- spinlock_t tx_stats_lock;
- struct ar9170_tx_queue_stats tx_stats[5];
- struct ieee80211_tx_queue_params edcf[5];
-
- spinlock_t cmdlock;
- __le32 cmdbuf[PAYLOAD_MAX + 1];
-
- /* MAC statistics */
- struct ieee80211_low_level_stats stats;
-
- /* EEPROM */
- struct ar9170_eeprom eeprom;
-
- /* tx queues - as seen by hw - */
- struct sk_buff_head tx_pending[__AR9170_NUM_TXQ];
- struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
- struct delayed_work tx_janitor;
-
- /* rxstream mpdu merge */
- struct ar9170_rxstream_mpdu_merge rx_mpdu;
- struct sk_buff *rx_failover;
- int rx_failover_missing;
-
- /* (cached) HW A-MPDU settings */
- u8 global_ampdu_density;
- u8 global_ampdu_factor;
-};
-
-struct ar9170_tx_info {
- unsigned long timeout;
-};
-
-#define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED)
-#define IS_ACCEPTING_CMD(a) (((struct ar9170 *)a)->state >= AR9170_IDLE)
-
-/* exported interface */
-void *ar9170_alloc(size_t priv_size);
-int ar9170_register(struct ar9170 *ar, struct device *pdev);
-void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb);
-void ar9170_unregister(struct ar9170 *ar);
-void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb);
-void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);
-int ar9170_nag_limiter(struct ar9170 *ar);
-
-/* MAC */
-void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
-int ar9170_init_mac(struct ar9170 *ar);
-int ar9170_set_qos(struct ar9170 *ar);
-int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hast);
-int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter);
-int ar9170_set_operating_mode(struct ar9170 *ar);
-int ar9170_set_beacon_timers(struct ar9170 *ar);
-int ar9170_set_dyn_sifs_ack(struct ar9170 *ar);
-int ar9170_set_slot_time(struct ar9170 *ar);
-int ar9170_set_basic_rates(struct ar9170 *ar);
-int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry);
-int ar9170_update_beacon(struct ar9170 *ar);
-void ar9170_new_beacon(struct work_struct *work);
-int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
- u8 keyidx, u8 *keydata, int keylen);
-int ar9170_disable_key(struct ar9170 *ar, u8 id);
-
-/* LEDs */
-#ifdef CONFIG_AR9170_LEDS
-int ar9170_register_leds(struct ar9170 *ar);
-void ar9170_unregister_leds(struct ar9170 *ar);
-#endif /* CONFIG_AR9170_LEDS */
-int ar9170_init_leds(struct ar9170 *ar);
-int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state);
-
-/* PHY / RF */
-int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band);
-int ar9170_init_rf(struct ar9170 *ar);
-int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
- enum ar9170_rf_init_mode rfi, enum ar9170_bw bw);
-
-#endif /* __AR9170_H */
diff --git a/drivers/net/wireless/ath/ar9170/cmd.c b/drivers/net/wireless/ath/ar9170/cmd.c
deleted file mode 100644
index 6452c5055a6..00000000000
--- a/drivers/net/wireless/ath/ar9170/cmd.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Basic HW register/memory/command access functions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- * Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "ar9170.h"
-#include "cmd.h"
-
-int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len)
-{
- int err;
-
- if (unlikely(!IS_ACCEPTING_CMD(ar)))
- return 0;
-
- err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL);
- if (err)
- wiphy_debug(ar->hw->wiphy, "writing memory failed\n");
- return err;
-}
-
-int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
-{
- const __le32 buf[2] = {
- cpu_to_le32(reg),
- cpu_to_le32(val),
- };
- int err;
-
- if (unlikely(!IS_ACCEPTING_CMD(ar)))
- return 0;
-
- err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf),
- (u8 *) buf, 0, NULL);
- if (err)
- wiphy_debug(ar->hw->wiphy, "writing reg %#x (val %#x) failed\n",
- reg, val);
- return err;
-}
-
-int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out)
-{
- int i, err;
- __le32 *offs, *res;
-
- if (unlikely(!IS_ACCEPTING_CMD(ar)))
- return 0;
-
- /* abuse "out" for the register offsets, must be same length */
- offs = (__le32 *)out;
- for (i = 0; i < nregs; i++)
- offs[i] = cpu_to_le32(regs[i]);
-
- /* also use the same buffer for the input */
- res = (__le32 *)out;
-
- err = ar->exec_cmd(ar, AR9170_CMD_RREG,
- 4 * nregs, (u8 *)offs,
- 4 * nregs, (u8 *)res);
- if (err)
- return err;
-
- /* convert result to cpu endian */
- for (i = 0; i < nregs; i++)
- out[i] = le32_to_cpu(res[i]);
-
- return 0;
-}
-
-int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
-{
- return ar9170_read_mreg(ar, 1, &reg, val);
-}
-
-int ar9170_echo_test(struct ar9170 *ar, u32 v)
-{
- __le32 echobuf = cpu_to_le32(v);
- __le32 echores;
- int err;
-
- if (unlikely(!IS_ACCEPTING_CMD(ar)))
- return -ENODEV;
-
- err = ar->exec_cmd(ar, AR9170_CMD_ECHO,
- 4, (u8 *)&echobuf,
- 4, (u8 *)&echores);
- if (err)
- return err;
-
- if (echobuf != echores)
- return -EINVAL;
-
- return 0;
-}
diff --git a/drivers/net/wireless/ath/ar9170/cmd.h b/drivers/net/wireless/ath/ar9170/cmd.h
deleted file mode 100644
index ec8134b4b94..00000000000
--- a/drivers/net/wireless/ath/ar9170/cmd.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Basic HW register/memory/command access functions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- * Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef __CMD_H
-#define __CMD_H
-
-#include "ar9170.h"
-
-/* basic HW access */
-int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len);
-int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val);
-int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val);
-int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out);
-int ar9170_echo_test(struct ar9170 *ar, u32 v);
-
-/*
- * Macros to facilitate writing multiple registers in a single
- * write-combining USB command. Note that when the first group
- * fails the whole thing will fail without any others attempted,
- * but you won't know which write in the group failed.
- */
-#define ar9170_regwrite_begin(ar) \
-do { \
- int __nreg = 0, __err = 0; \
- struct ar9170 *__ar = ar;
-
-#define ar9170_regwrite(r, v) do { \
- __ar->cmdbuf[2 * __nreg + 1] = cpu_to_le32(r); \
- __ar->cmdbuf[2 * __nreg + 2] = cpu_to_le32(v); \
- __nreg++; \
- if ((__nreg >= PAYLOAD_MAX/2)) { \
- if (IS_ACCEPTING_CMD(__ar)) \
- __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \
- 8 * __nreg, \
- (u8 *) &__ar->cmdbuf[1], \
- 0, NULL); \
- __nreg = 0; \
- if (__err) \
- goto __regwrite_out; \
- } \
-} while (0)
-
-#define ar9170_regwrite_finish() \
-__regwrite_out : \
- if (__nreg) { \
- if (IS_ACCEPTING_CMD(__ar)) \
- __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \
- 8 * __nreg, \
- (u8 *) &__ar->cmdbuf[1], \
- 0, NULL); \
- __nreg = 0; \
- }
-
-#define ar9170_regwrite_result() \
- __err; \
-} while (0);
-
-#endif /* __CMD_H */
diff --git a/drivers/net/wireless/ath/ar9170/eeprom.h b/drivers/net/wireless/ath/ar9170/eeprom.h
deleted file mode 100644
index 6c466388342..00000000000
--- a/drivers/net/wireless/ath/ar9170/eeprom.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * EEPROM layout
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- * Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef __AR9170_EEPROM_H
-#define __AR9170_EEPROM_H
-
-#define AR5416_MAX_CHAINS 2
-#define AR5416_MODAL_SPURS 5
-
-struct ar9170_eeprom_modal {
- __le32 antCtrlChain[AR5416_MAX_CHAINS];
- __le32 antCtrlCommon;
- s8 antennaGainCh[AR5416_MAX_CHAINS];
- u8 switchSettling;
- u8 txRxAttenCh[AR5416_MAX_CHAINS];
- u8 rxTxMarginCh[AR5416_MAX_CHAINS];
- s8 adcDesiredSize;
- s8 pgaDesiredSize;
- u8 xlnaGainCh[AR5416_MAX_CHAINS];
- u8 txEndToXpaOff;
- u8 txEndToRxOn;
- u8 txFrameToXpaOn;
- u8 thresh62;
- s8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
- u8 xpdGain;
- u8 xpd;
- s8 iqCalICh[AR5416_MAX_CHAINS];
- s8 iqCalQCh[AR5416_MAX_CHAINS];
- u8 pdGainOverlap;
- u8 ob;
- u8 db;
- u8 xpaBiasLvl;
- u8 pwrDecreaseFor2Chain;
- u8 pwrDecreaseFor3Chain;
- u8 txFrameToDataStart;
- u8 txFrameToPaOn;
- u8 ht40PowerIncForPdadc;
- u8 bswAtten[AR5416_MAX_CHAINS];
- u8 bswMargin[AR5416_MAX_CHAINS];
- u8 swSettleHt40;
- u8 reserved[22];
- struct spur_channel {
- __le16 spurChan;
- u8 spurRangeLow;
- u8 spurRangeHigh;
- } __packed spur_channels[AR5416_MODAL_SPURS];
-} __packed;
-
-#define AR5416_NUM_PD_GAINS 4
-#define AR5416_PD_GAIN_ICEPTS 5
-
-struct ar9170_calibration_data_per_freq {
- u8 pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
- u8 vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
-} __packed;
-
-#define AR5416_NUM_5G_CAL_PIERS 8
-#define AR5416_NUM_2G_CAL_PIERS 4
-
-#define AR5416_NUM_5G_TARGET_PWRS 8
-#define AR5416_NUM_2G_CCK_TARGET_PWRS 3
-#define AR5416_NUM_2G_OFDM_TARGET_PWRS 4
-#define AR5416_MAX_NUM_TGT_PWRS 8
-
-struct ar9170_calibration_target_power_legacy {
- u8 freq;
- u8 power[4];
-} __packed;
-
-struct ar9170_calibration_target_power_ht {
- u8 freq;
- u8 power[8];
-} __packed;
-
-#define AR5416_NUM_CTLS 24
-
-struct ar9170_calctl_edges {
- u8 channel;
-#define AR9170_CALCTL_EDGE_FLAGS 0xC0
- u8 power_flags;
-} __packed;
-
-#define AR5416_NUM_BAND_EDGES 8
-
-struct ar9170_calctl_data {
- struct ar9170_calctl_edges
- control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
-} __packed;
-
-
-struct ar9170_eeprom {
- __le16 length;
- __le16 checksum;
- __le16 version;
- u8 operating_flags;
-#define AR9170_OPFLAG_5GHZ 1
-#define AR9170_OPFLAG_2GHZ 2
- u8 misc;
- __le16 reg_domain[2];
- u8 mac_address[6];
- u8 rx_mask;
- u8 tx_mask;
- __le16 rf_silent;
- __le16 bluetooth_options;
- __le16 device_capabilities;
- __le32 build_number;
- u8 deviceType;
- u8 reserved[33];
-
- u8 customer_data[64];
-
- struct ar9170_eeprom_modal
- modal_header[2];
-
- u8 cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS];
- u8 cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS];
-
- struct ar9170_calibration_data_per_freq
- cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS],
- cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
-
- /* power calibration data */
- struct ar9170_calibration_target_power_legacy
- cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS];
- struct ar9170_calibration_target_power_ht
- cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS],
- cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS];
-
- struct ar9170_calibration_target_power_legacy
- cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS],
- cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS];
- struct ar9170_calibration_target_power_ht
- cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS],
- cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS];
-
- /* conformance testing limits */
- u8 ctl_index[AR5416_NUM_CTLS];
- struct ar9170_calctl_data
- ctl_data[AR5416_NUM_CTLS];
-
- u8 pad;
- __le16 subsystem_id;
-} __packed;
-
-#endif /* __AR9170_EEPROM_H */
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h
deleted file mode 100644
index 06f1f3c951a..00000000000
--- a/drivers/net/wireless/ath/ar9170/hw.h
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Hardware-specific definitions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- * Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef __AR9170_HW_H
-#define __AR9170_HW_H
-
-#define AR9170_MAX_CMD_LEN 64
-
-enum ar9170_cmd {
- AR9170_CMD_RREG = 0x00,
- AR9170_CMD_WREG = 0x01,
- AR9170_CMD_RMEM = 0x02,
- AR9170_CMD_WMEM = 0x03,
- AR9170_CMD_BITAND = 0x04,
- AR9170_CMD_BITOR = 0x05,
- AR9170_CMD_EKEY = 0x28,
- AR9170_CMD_DKEY = 0x29,
- AR9170_CMD_FREQUENCY = 0x30,
- AR9170_CMD_RF_INIT = 0x31,
- AR9170_CMD_SYNTH = 0x32,
- AR9170_CMD_FREQ_START = 0x33,
- AR9170_CMD_ECHO = 0x80,
- AR9170_CMD_TALLY = 0x81,
- AR9170_CMD_TALLY_APD = 0x82,
- AR9170_CMD_CONFIG = 0x83,
- AR9170_CMD_RESET = 0x90,
- AR9170_CMD_DKRESET = 0x91,
- AR9170_CMD_DKTX_STATUS = 0x92,
- AR9170_CMD_FDC = 0xA0,
- AR9170_CMD_WREEPROM = 0xB0,
- AR9170_CMD_WFLASH = 0xB0,
- AR9170_CMD_FLASH_ERASE = 0xB1,
- AR9170_CMD_FLASH_PROG = 0xB2,
- AR9170_CMD_FLASH_CHKSUM = 0xB3,
- AR9170_CMD_FLASH_READ = 0xB4,
- AR9170_CMD_FW_DL_INIT = 0xB5,
- AR9170_CMD_MEM_WREEPROM = 0xBB,
-};
-
-/* endpoints */
-#define AR9170_EP_TX 1
-#define AR9170_EP_RX 2
-#define AR9170_EP_IRQ 3
-#define AR9170_EP_CMD 4
-
-#define AR9170_EEPROM_START 0x1600
-
-#define AR9170_GPIO_REG_BASE 0x1d0100
-#define AR9170_GPIO_REG_PORT_TYPE AR9170_GPIO_REG_BASE
-#define AR9170_GPIO_REG_DATA (AR9170_GPIO_REG_BASE + 4)
-#define AR9170_NUM_LEDS 2
-
-
-#define AR9170_USB_REG_BASE 0x1e1000
-#define AR9170_USB_REG_DMA_CTL (AR9170_USB_REG_BASE + 0x108)
-#define AR9170_DMA_CTL_ENABLE_TO_DEVICE 0x1
-#define AR9170_DMA_CTL_ENABLE_FROM_DEVICE 0x2
-#define AR9170_DMA_CTL_HIGH_SPEED 0x4
-#define AR9170_DMA_CTL_PACKET_MODE 0x8
-
-#define AR9170_USB_REG_MAX_AGG_UPLOAD (AR9170_USB_REG_BASE + 0x110)
-#define AR9170_USB_REG_UPLOAD_TIME_CTL (AR9170_USB_REG_BASE + 0x114)
-
-
-
-#define AR9170_MAC_REG_BASE 0x1c3000
-
-#define AR9170_MAC_REG_TSF_L (AR9170_MAC_REG_BASE + 0x514)
-#define AR9170_MAC_REG_TSF_H (AR9170_MAC_REG_BASE + 0x518)
-
-#define AR9170_MAC_REG_ATIM_WINDOW (AR9170_MAC_REG_BASE + 0x51C)
-#define AR9170_MAC_REG_BCN_PERIOD (AR9170_MAC_REG_BASE + 0x520)
-#define AR9170_MAC_REG_PRETBTT (AR9170_MAC_REG_BASE + 0x524)
-
-#define AR9170_MAC_REG_MAC_ADDR_L (AR9170_MAC_REG_BASE + 0x610)
-#define AR9170_MAC_REG_MAC_ADDR_H (AR9170_MAC_REG_BASE + 0x614)
-#define AR9170_MAC_REG_BSSID_L (AR9170_MAC_REG_BASE + 0x618)
-#define AR9170_MAC_REG_BSSID_H (AR9170_MAC_REG_BASE + 0x61c)
-
-#define AR9170_MAC_REG_GROUP_HASH_TBL_L (AR9170_MAC_REG_BASE + 0x624)
-#define AR9170_MAC_REG_GROUP_HASH_TBL_H (AR9170_MAC_REG_BASE + 0x628)
-
-#define AR9170_MAC_REG_RX_TIMEOUT (AR9170_MAC_REG_BASE + 0x62C)
-
-#define AR9170_MAC_REG_BASIC_RATE (AR9170_MAC_REG_BASE + 0x630)
-#define AR9170_MAC_REG_MANDATORY_RATE (AR9170_MAC_REG_BASE + 0x634)
-#define AR9170_MAC_REG_RTS_CTS_RATE (AR9170_MAC_REG_BASE + 0x638)
-#define AR9170_MAC_REG_BACKOFF_PROTECT (AR9170_MAC_REG_BASE + 0x63c)
-#define AR9170_MAC_REG_RX_THRESHOLD (AR9170_MAC_REG_BASE + 0x640)
-#define AR9170_MAC_REG_RX_PE_DELAY (AR9170_MAC_REG_BASE + 0x64C)
-
-#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK (AR9170_MAC_REG_BASE + 0x658)
-#define AR9170_MAC_REG_SNIFFER (AR9170_MAC_REG_BASE + 0x674)
-#define AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC BIT(0)
-#define AR9170_MAC_REG_SNIFFER_DEFAULTS 0x02000000
-#define AR9170_MAC_REG_ENCRYPTION (AR9170_MAC_REG_BASE + 0x678)
-#define AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE BIT(3)
-#define AR9170_MAC_REG_ENCRYPTION_DEFAULTS 0x70
-
-#define AR9170_MAC_REG_MISC_680 (AR9170_MAC_REG_BASE + 0x680)
-#define AR9170_MAC_REG_TX_UNDERRUN (AR9170_MAC_REG_BASE + 0x688)
-
-#define AR9170_MAC_REG_FRAMETYPE_FILTER (AR9170_MAC_REG_BASE + 0x68c)
-#define AR9170_MAC_REG_FTF_ASSOC_REQ BIT(0)
-#define AR9170_MAC_REG_FTF_ASSOC_RESP BIT(1)
-#define AR9170_MAC_REG_FTF_REASSOC_REQ BIT(2)
-#define AR9170_MAC_REG_FTF_REASSOC_RESP BIT(3)
-#define AR9170_MAC_REG_FTF_PRB_REQ BIT(4)
-#define AR9170_MAC_REG_FTF_PRB_RESP BIT(5)
-#define AR9170_MAC_REG_FTF_BIT6 BIT(6)
-#define AR9170_MAC_REG_FTF_BIT7 BIT(7)
-#define AR9170_MAC_REG_FTF_BEACON BIT(8)
-#define AR9170_MAC_REG_FTF_ATIM BIT(9)
-#define AR9170_MAC_REG_FTF_DEASSOC BIT(10)
-#define AR9170_MAC_REG_FTF_AUTH BIT(11)
-#define AR9170_MAC_REG_FTF_DEAUTH BIT(12)
-#define AR9170_MAC_REG_FTF_BIT13 BIT(13)
-#define AR9170_MAC_REG_FTF_BIT14 BIT(14)
-#define AR9170_MAC_REG_FTF_BIT15 BIT(15)
-#define AR9170_MAC_REG_FTF_BAR BIT(24)
-#define AR9170_MAC_REG_FTF_BA BIT(25)
-#define AR9170_MAC_REG_FTF_PSPOLL BIT(26)
-#define AR9170_MAC_REG_FTF_RTS BIT(27)
-#define AR9170_MAC_REG_FTF_CTS BIT(28)
-#define AR9170_MAC_REG_FTF_ACK BIT(29)
-#define AR9170_MAC_REG_FTF_CFE BIT(30)
-#define AR9170_MAC_REG_FTF_CFE_ACK BIT(31)
-#define AR9170_MAC_REG_FTF_DEFAULTS 0x0700ffff
-#define AR9170_MAC_REG_FTF_MONITOR 0xfd00ffff
-
-#define AR9170_MAC_REG_RX_TOTAL (AR9170_MAC_REG_BASE + 0x6A0)
-#define AR9170_MAC_REG_RX_CRC32 (AR9170_MAC_REG_BASE + 0x6A4)
-#define AR9170_MAC_REG_RX_CRC16 (AR9170_MAC_REG_BASE + 0x6A8)
-#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI (AR9170_MAC_REG_BASE + 0x6AC)
-#define AR9170_MAC_REG_RX_OVERRUN (AR9170_MAC_REG_BASE + 0x6B0)
-#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL (AR9170_MAC_REG_BASE + 0x6BC)
-#define AR9170_MAC_REG_TX_RETRY (AR9170_MAC_REG_BASE + 0x6CC)
-#define AR9170_MAC_REG_TX_TOTAL (AR9170_MAC_REG_BASE + 0x6F4)
-
-
-#define AR9170_MAC_REG_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0x690)
-#define AR9170_MAC_REG_EIFS_AND_SIFS (AR9170_MAC_REG_BASE + 0x698)
-
-#define AR9170_MAC_REG_SLOT_TIME (AR9170_MAC_REG_BASE + 0x6F0)
-
-#define AR9170_MAC_REG_POWERMANAGEMENT (AR9170_MAC_REG_BASE + 0x700)
-#define AR9170_MAC_REG_POWERMGT_IBSS 0xe0
-#define AR9170_MAC_REG_POWERMGT_AP 0xa1
-#define AR9170_MAC_REG_POWERMGT_STA 0x2
-#define AR9170_MAC_REG_POWERMGT_AP_WDS 0x3
-#define AR9170_MAC_REG_POWERMGT_DEFAULTS (0xf << 24)
-
-#define AR9170_MAC_REG_ROLL_CALL_TBL_L (AR9170_MAC_REG_BASE + 0x704)
-#define AR9170_MAC_REG_ROLL_CALL_TBL_H (AR9170_MAC_REG_BASE + 0x708)
-
-#define AR9170_MAC_REG_AC0_CW (AR9170_MAC_REG_BASE + 0xB00)
-#define AR9170_MAC_REG_AC1_CW (AR9170_MAC_REG_BASE + 0xB04)
-#define AR9170_MAC_REG_AC2_CW (AR9170_MAC_REG_BASE + 0xB08)
-#define AR9170_MAC_REG_AC3_CW (AR9170_MAC_REG_BASE + 0xB0C)
-#define AR9170_MAC_REG_AC4_CW (AR9170_MAC_REG_BASE + 0xB10)
-#define AR9170_MAC_REG_AC1_AC0_AIFS (AR9170_MAC_REG_BASE + 0xB14)
-#define AR9170_MAC_REG_AC3_AC2_AIFS (AR9170_MAC_REG_BASE + 0xB18)
-
-#define AR9170_MAC_REG_RETRY_MAX (AR9170_MAC_REG_BASE + 0xB28)
-
-#define AR9170_MAC_REG_FCS_SELECT (AR9170_MAC_REG_BASE + 0xBB0)
-#define AR9170_MAC_FCS_SWFCS 0x1
-#define AR9170_MAC_FCS_FIFO_PROT 0x4
-
-
-#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND (AR9170_MAC_REG_BASE + 0xB30)
-
-#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xB44)
-#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xB48)
-
-#define AR9170_MAC_REG_AMPDU_FACTOR (AR9170_MAC_REG_BASE + 0xB9C)
-#define AR9170_MAC_REG_AMPDU_DENSITY (AR9170_MAC_REG_BASE + 0xBA0)
-
-#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xC00)
-#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xC50)
-
-#define AR9170_MAC_REG_TXRX_MPI (AR9170_MAC_REG_BASE + 0xD7C)
-#define AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f
-#define AR9170_MAC_TXRX_MPI_TX_TO_MASK 0x0000fff0
-#define AR9170_MAC_TXRX_MPI_RX_MPI_MASK 0x000f0000
-#define AR9170_MAC_TXRX_MPI_RX_TO_MASK 0xfff00000
-
-#define AR9170_MAC_REG_BCN_ADDR (AR9170_MAC_REG_BASE + 0xD84)
-#define AR9170_MAC_REG_BCN_LENGTH (AR9170_MAC_REG_BASE + 0xD88)
-#define AR9170_MAC_REG_BCN_PLCP (AR9170_MAC_REG_BASE + 0xD90)
-#define AR9170_MAC_REG_BCN_CTRL (AR9170_MAC_REG_BASE + 0xD94)
-#define AR9170_MAC_REG_BCN_HT1 (AR9170_MAC_REG_BASE + 0xDA0)
-#define AR9170_MAC_REG_BCN_HT2 (AR9170_MAC_REG_BASE + 0xDA4)
-
-
-#define AR9170_PWR_REG_BASE 0x1D4000
-
-#define AR9170_PWR_REG_CLOCK_SEL (AR9170_PWR_REG_BASE + 0x008)
-#define AR9170_PWR_CLK_AHB_40MHZ 0
-#define AR9170_PWR_CLK_AHB_20_22MHZ 1
-#define AR9170_PWR_CLK_AHB_40_44MHZ 2
-#define AR9170_PWR_CLK_AHB_80_88MHZ 3
-#define AR9170_PWR_CLK_DAC_160_INV_DLY 0x70
-
-
-/* put beacon here in memory */
-#define AR9170_BEACON_BUFFER_ADDRESS 0x117900
-
-
-struct ar9170_tx_control {
- __le16 length;
- __le16 mac_control;
- __le32 phy_control;
- u8 frame_data[0];
-} __packed;
-
-/* these are either-or */
-#define AR9170_TX_MAC_PROT_RTS 0x0001
-#define AR9170_TX_MAC_PROT_CTS 0x0002
-
-#define AR9170_TX_MAC_NO_ACK 0x0004
-/* if unset, MAC will only do SIFS space before frame */
-#define AR9170_TX_MAC_BACKOFF 0x0008
-#define AR9170_TX_MAC_BURST 0x0010
-#define AR9170_TX_MAC_AGGR 0x0020
-
-/* encryption is a two-bit field */
-#define AR9170_TX_MAC_ENCR_NONE 0x0000
-#define AR9170_TX_MAC_ENCR_RC4 0x0040
-#define AR9170_TX_MAC_ENCR_CENC 0x0080
-#define AR9170_TX_MAC_ENCR_AES 0x00c0
-
-#define AR9170_TX_MAC_MMIC 0x0100
-#define AR9170_TX_MAC_HW_DURATION 0x0200
-#define AR9170_TX_MAC_QOS_SHIFT 10
-#define AR9170_TX_MAC_QOS_MASK (3 << AR9170_TX_MAC_QOS_SHIFT)
-#define AR9170_TX_MAC_AGGR_QOS_BIT1 0x0400
-#define AR9170_TX_MAC_AGGR_QOS_BIT2 0x0800
-#define AR9170_TX_MAC_DISABLE_TXOP 0x1000
-#define AR9170_TX_MAC_TXOP_RIFS 0x2000
-#define AR9170_TX_MAC_IMM_AMPDU 0x4000
-#define AR9170_TX_MAC_RATE_PROBE 0x8000
-
-/* either-or */
-#define AR9170_TX_PHY_MOD_MASK 0x00000003
-#define AR9170_TX_PHY_MOD_CCK 0x00000000
-#define AR9170_TX_PHY_MOD_OFDM 0x00000001
-#define AR9170_TX_PHY_MOD_HT 0x00000002
-
-/* depends on modulation */
-#define AR9170_TX_PHY_SHORT_PREAMBLE 0x00000004
-#define AR9170_TX_PHY_GREENFIELD 0x00000004
-
-#define AR9170_TX_PHY_BW_SHIFT 3
-#define AR9170_TX_PHY_BW_MASK (3 << AR9170_TX_PHY_BW_SHIFT)
-#define AR9170_TX_PHY_BW_20MHZ 0
-#define AR9170_TX_PHY_BW_40MHZ 2
-#define AR9170_TX_PHY_BW_40MHZ_DUP 3
-
-#define AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT 6
-#define AR9170_TX_PHY_TX_HEAVY_CLIP_MASK (7 << AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT)
-
-#define AR9170_TX_PHY_TX_PWR_SHIFT 9
-#define AR9170_TX_PHY_TX_PWR_MASK (0x3f << AR9170_TX_PHY_TX_PWR_SHIFT)
-
-/* not part of the hw-spec */
-#define AR9170_TX_PHY_QOS_SHIFT 25
-#define AR9170_TX_PHY_QOS_MASK (3 << AR9170_TX_PHY_QOS_SHIFT)
-
-#define AR9170_TX_PHY_TXCHAIN_SHIFT 15
-#define AR9170_TX_PHY_TXCHAIN_MASK (7 << AR9170_TX_PHY_TXCHAIN_SHIFT)
-#define AR9170_TX_PHY_TXCHAIN_1 1
-/* use for cck, ofdm 6/9/12/18/24 and HT if capable */
-#define AR9170_TX_PHY_TXCHAIN_2 5
-
-#define AR9170_TX_PHY_MCS_SHIFT 18
-#define AR9170_TX_PHY_MCS_MASK (0x7f << AR9170_TX_PHY_MCS_SHIFT)
-
-#define AR9170_TX_PHY_SHORT_GI 0x80000000
-
-#define AR5416_MAX_RATE_POWER 63
-
-struct ar9170_rx_head {
- u8 plcp[12];
-} __packed;
-
-struct ar9170_rx_phystatus {
- union {
- struct {
- u8 rssi_ant0, rssi_ant1, rssi_ant2,
- rssi_ant0x, rssi_ant1x, rssi_ant2x,
- rssi_combined;
- } __packed;
- u8 rssi[7];
- } __packed;
-
- u8 evm_stream0[6], evm_stream1[6];
- u8 phy_err;
-} __packed;
-
-struct ar9170_rx_macstatus {
- u8 SAidx, DAidx;
- u8 error;
- u8 status;
-} __packed;
-
-#define AR9170_ENC_ALG_NONE 0x0
-#define AR9170_ENC_ALG_WEP64 0x1
-#define AR9170_ENC_ALG_TKIP 0x2
-#define AR9170_ENC_ALG_AESCCMP 0x4
-#define AR9170_ENC_ALG_WEP128 0x5
-#define AR9170_ENC_ALG_WEP256 0x6
-#define AR9170_ENC_ALG_CENC 0x7
-
-#define AR9170_RX_ENC_SOFTWARE 0x8
-
-static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t)
-{
- return (t->SAidx & 0xc0) >> 4 |
- (t->DAidx & 0xc0) >> 6;
-}
-
-#define AR9170_RX_STATUS_MODULATION_MASK 0x03
-#define AR9170_RX_STATUS_MODULATION_CCK 0x00
-#define AR9170_RX_STATUS_MODULATION_OFDM 0x01
-#define AR9170_RX_STATUS_MODULATION_HT 0x02
-#define AR9170_RX_STATUS_MODULATION_DUPOFDM 0x03
-
-/* depends on modulation */
-#define AR9170_RX_STATUS_SHORT_PREAMBLE 0x08
-#define AR9170_RX_STATUS_GREENFIELD 0x08
-
-#define AR9170_RX_STATUS_MPDU_MASK 0x30
-#define AR9170_RX_STATUS_MPDU_SINGLE 0x00
-#define AR9170_RX_STATUS_MPDU_FIRST 0x20
-#define AR9170_RX_STATUS_MPDU_MIDDLE 0x30
-#define AR9170_RX_STATUS_MPDU_LAST 0x10
-
-#define AR9170_RX_ERROR_RXTO 0x01
-#define AR9170_RX_ERROR_OVERRUN 0x02
-#define AR9170_RX_ERROR_DECRYPT 0x04
-#define AR9170_RX_ERROR_FCS 0x08
-#define AR9170_RX_ERROR_WRONG_RA 0x10
-#define AR9170_RX_ERROR_PLCP 0x20
-#define AR9170_RX_ERROR_MMIC 0x40
-#define AR9170_RX_ERROR_FATAL 0x80
-
-struct ar9170_cmd_tx_status {
- u8 dst[ETH_ALEN];
- __le32 rate;
- __le16 status;
-} __packed;
-
-#define AR9170_TX_STATUS_COMPLETE 0x00
-#define AR9170_TX_STATUS_RETRY 0x01
-#define AR9170_TX_STATUS_FAILED 0x02
-
-struct ar9170_cmd_ba_failed_count {
- __le16 failed;
- __le16 rate;
-} __packed;
-
-struct ar9170_cmd_response {
- u8 flag;
- u8 type;
- __le16 padding;
-
- union {
- struct ar9170_cmd_tx_status tx_status;
- struct ar9170_cmd_ba_failed_count ba_fail_cnt;
- u8 data[0];
- };
-} __packed;
-
-/* QoS */
-
-/* mac80211 queue to HW/FW map */
-static const u8 ar9170_qos_hwmap[4] = { 3, 2, 0, 1 };
-
-/* HW/FW queue to mac80211 map */
-static const u8 ar9170_qos_mac80211map[4] = { 2, 3, 1, 0 };
-
-enum ar9170_txq {
- AR9170_TXQ_BE,
- AR9170_TXQ_BK,
- AR9170_TXQ_VI,
- AR9170_TXQ_VO,
-
- __AR9170_NUM_TXQ,
-};
-
-#define AR9170_TXQ_DEPTH 32
-#define AR9170_TX_MAX_PENDING 128
-#define AR9170_RX_STREAM_MAX_SIZE 65535
-
-#endif /* __AR9170_HW_H */
diff --git a/drivers/net/wireless/ath/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c
deleted file mode 100644
index 832d90087f8..00000000000
--- a/drivers/net/wireless/ath/ar9170/led.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * LED handling
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- * Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "ar9170.h"
-#include "cmd.h"
-
-int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state)
-{
- return ar9170_write_reg(ar, AR9170_GPIO_REG_DATA, led_state);
-}
-
-int ar9170_init_leds(struct ar9170 *ar)
-{
- int err;
-
- /* disable LEDs */
- /* GPIO [0/1 mode: output, 2/3: input] */
- err = ar9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3);
- if (err)
- goto out;
-
- /* GPIO 0/1 value: off */
- err = ar9170_set_leds_state(ar, 0);
-
-out:
- return err;
-}
-
-#ifdef CONFIG_AR9170_LEDS
-static void ar9170_update_leds(struct work_struct *work)
-{
- struct ar9170 *ar = container_of(work, struct ar9170, led_work.work);
- int i, tmp, blink_delay = 1000;
- u32 led_val = 0;
- bool rerun = false;
-
- if (unlikely(!IS_ACCEPTING_CMD(ar)))
- return ;
-
- mutex_lock(&ar->mutex);
- for (i = 0; i < AR9170_NUM_LEDS; i++)
- if (ar->leds[i].registered && ar->leds[i].toggled) {
- led_val |= 1 << i;
-
- tmp = 70 + 200 / (ar->leds[i].toggled);
- if (tmp < blink_delay)
- blink_delay = tmp;
-
- if (ar->leds[i].toggled > 1)
- ar->leds[i].toggled = 0;
-
- rerun = true;
- }
-
- ar9170_set_leds_state(ar, led_val);
- mutex_unlock(&ar->mutex);
-
- if (!rerun)
- return;
-
- ieee80211_queue_delayed_work(ar->hw,
- &ar->led_work,
- msecs_to_jiffies(blink_delay));
-}
-
-static void ar9170_led_brightness_set(struct led_classdev *led,
- enum led_brightness brightness)
-{
- struct ar9170_led *arl = container_of(led, struct ar9170_led, l);
- struct ar9170 *ar = arl->ar;
-
- if (unlikely(!arl->registered))
- return ;
-
- if (arl->last_state != !!brightness) {
- arl->toggled++;
- arl->last_state = !!brightness;
- }
-
- if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled))
- ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ/10);
-}
-
-static int ar9170_register_led(struct ar9170 *ar, int i, char *name,
- char *trigger)
-{
- int err;
-
- snprintf(ar->leds[i].name, sizeof(ar->leds[i].name),
- "ar9170-%s::%s", wiphy_name(ar->hw->wiphy), name);
-
- ar->leds[i].ar = ar;
- ar->leds[i].l.name = ar->leds[i].name;
- ar->leds[i].l.brightness_set = ar9170_led_brightness_set;
- ar->leds[i].l.brightness = 0;
- ar->leds[i].l.default_trigger = trigger;
-
- err = led_classdev_register(wiphy_dev(ar->hw->wiphy),
- &ar->leds[i].l);
- if (err)
- wiphy_err(ar->hw->wiphy, "failed to register %s LED (%d).\n",
- ar->leds[i].name, err);
- else
- ar->leds[i].registered = true;
-
- return err;
-}
-
-void ar9170_unregister_leds(struct ar9170 *ar)
-{
- int i;
-
- for (i = 0; i < AR9170_NUM_LEDS; i++)
- if (ar->leds[i].registered) {
- led_classdev_unregister(&ar->leds[i].l);
- ar->leds[i].registered = false;
- ar->leds[i].toggled = 0;
- }
-
- cancel_delayed_work_sync(&ar->led_work);
-}
-
-int ar9170_register_leds(struct ar9170 *ar)
-{
- int err;
-
- INIT_DELAYED_WORK(&ar->led_work, ar9170_update_leds);
-
- err = ar9170_register_led(ar, 0, "tx",
- ieee80211_get_tx_led_name(ar->hw));
- if (err)
- goto fail;
-
- err = ar9170_register_led(ar, 1, "assoc",
- ieee80211_get_assoc_led_name(ar->hw));
- if (err)
- goto fail;
-
- return 0;
-
-fail:
- ar9170_unregister_leds(ar);
- return err;
-}
-
-#endif /* CONFIG_AR9170_LEDS */
diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c
deleted file mode 100644
index 857e8610429..00000000000
--- a/drivers/net/wireless/ath/ar9170/mac.c
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * MAC programming
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- * Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <asm/unaligned.h>
-
-#include "ar9170.h"
-#include "cmd.h"
-
-int ar9170_set_dyn_sifs_ack(struct ar9170 *ar)
-{
- u32 val;
-
- if (conf_is_ht40(&ar->hw->conf))
- val = 0x010a;
- else {
- if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
- val = 0x105;
- else
- val = 0x104;
- }
-
- return ar9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
-}
-
-int ar9170_set_slot_time(struct ar9170 *ar)
-{
- u32 slottime = 20;
-
- if (!ar->vif)
- return 0;
-
- if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) ||
- ar->vif->bss_conf.use_short_slot)
- slottime = 9;
-
- return ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, slottime << 10);
-}
-
-int ar9170_set_basic_rates(struct ar9170 *ar)
-{
- u8 cck, ofdm;
-
- if (!ar->vif)
- return 0;
-
- ofdm = ar->vif->bss_conf.basic_rates >> 4;
-
- /* FIXME: is still necessary? */
- if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
- cck = 0;
- else
- cck = ar->vif->bss_conf.basic_rates & 0xf;
-
- return ar9170_write_reg(ar, AR9170_MAC_REG_BASIC_RATE,
- ofdm << 8 | cck);
-}
-
-int ar9170_set_qos(struct ar9170 *ar)
-{
- ar9170_regwrite_begin(ar);
-
- ar9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
- (ar->edcf[0].cw_max << 16));
- ar9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
- (ar->edcf[1].cw_max << 16));
- ar9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
- (ar->edcf[2].cw_max << 16));
- ar9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
- (ar->edcf[3].cw_max << 16));
- ar9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
- (ar->edcf[4].cw_max << 16));
-
- ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_AIFS,
- ((ar->edcf[0].aifs * 9 + 10)) |
- ((ar->edcf[1].aifs * 9 + 10) << 12) |
- ((ar->edcf[2].aifs * 9 + 10) << 24));
- ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_AIFS,
- ((ar->edcf[2].aifs * 9 + 10) >> 8) |
- ((ar->edcf[3].aifs * 9 + 10) << 4) |
- ((ar->edcf[4].aifs * 9 + 10) << 16));
-
- ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
- ar->edcf[0].txop | ar->edcf[1].txop << 16);
- ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
- ar->edcf[2].txop | ar->edcf[3].txop << 16);
-
- ar9170_regwrite_finish();
-
- return ar9170_regwrite_result();
-}
-
-static int ar9170_set_ampdu_density(struct ar9170 *ar, u8 mpdudensity)
-{
- u32 val;
-
- /* don't allow AMPDU density > 8us */
- if (mpdudensity > 6)
- return -EINVAL;
-
- /* Watch out! Otus uses slightly different density values. */
- val = 0x140a00 | (mpdudensity ? (mpdudensity + 1) : 0);
-
- ar9170_regwrite_begin(ar);
- ar9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, val);
- ar9170_regwrite_finish();
-
- return ar9170_regwrite_result();
-}
-
-int ar9170_init_mac(struct ar9170 *ar)
-{
- ar9170_regwrite_begin(ar);
-
- ar9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
-
- ar9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0);
-
- /* enable MMIC */
- ar9170_regwrite(AR9170_MAC_REG_SNIFFER,
- AR9170_MAC_REG_SNIFFER_DEFAULTS);
-
- ar9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
-
- ar9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
- ar9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
- ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
-
- /* CF-END mode */
- ar9170_regwrite(0x1c3b2c, 0x19000000);
-
- /* NAV protects ACK only (in TXOP) */
- ar9170_regwrite(0x1c3b38, 0x201);
-
- /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
- /* OTUS set AM to 0x1 */
- ar9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
-
- ar9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
-
- /* AGG test code*/
- /* Aggregation MAX number and timeout */
- ar9170_regwrite(0x1c3b9c, 0x10000a);
-
- ar9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
- AR9170_MAC_REG_FTF_DEFAULTS);
-
- /* Enable deaggregator, response in sniffer mode */
- ar9170_regwrite(0x1c3c40, 0x1 | 1<<30);
-
- /* rate sets */
- ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
- ar9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
- ar9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x10b01bb);
-
- /* MIMO response control */
- ar9170_regwrite(0x1c3694, 0x4003C1E);/* bit 26~28 otus-AM */
-
- /* switch MAC to OTUS interface */
- ar9170_regwrite(0x1c3600, 0x3);
-
- ar9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
-
- /* set PHY register read timeout (??) */
- ar9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
-
- /* Disable Rx TimeOut, workaround for BB. */
- ar9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
-
- /* Set CPU clock frequency to 88/80MHz */
- ar9170_regwrite(AR9170_PWR_REG_CLOCK_SEL,
- AR9170_PWR_CLK_AHB_80_88MHZ |
- AR9170_PWR_CLK_DAC_160_INV_DLY);
-
- /* Set WLAN DMA interrupt mode: generate int per packet */
- ar9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
-
- ar9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
- AR9170_MAC_FCS_FIFO_PROT);
-
- /* Disables the CF_END frame, undocumented register */
- ar9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
- 0x141E0F48);
-
- ar9170_regwrite_finish();
-
- return ar9170_regwrite_result();
-}
-
-static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac)
-{
- static const u8 zero[ETH_ALEN] = { 0 };
-
- if (!mac)
- mac = zero;
-
- ar9170_regwrite_begin(ar);
-
- ar9170_regwrite(reg, get_unaligned_le32(mac));
- ar9170_regwrite(reg + 4, get_unaligned_le16(mac + 4));
-
- ar9170_regwrite_finish();
-
- return ar9170_regwrite_result();
-}
-
-int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hash)
-{
- int err;
-
- ar9170_regwrite_begin(ar);
- ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32);
- ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash);
- ar9170_regwrite_finish();
- err = ar9170_regwrite_result();
- if (err)
- return err;
-
- ar->cur_mc_hash = mc_hash;
- return 0;
-}
-
-int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter)
-{
- int err;
-
- err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER, filter);
- if (err)
- return err;
-
- ar->cur_filter = filter;
- return 0;
-}
-
-static int ar9170_set_promiscouous(struct ar9170 *ar)
-{
- u32 encr_mode, sniffer;
- int err;
-
- err = ar9170_read_reg(ar, AR9170_MAC_REG_SNIFFER, &sniffer);
- if (err)
- return err;
-
- err = ar9170_read_reg(ar, AR9170_MAC_REG_ENCRYPTION, &encr_mode);
- if (err)
- return err;
-
- if (ar->sniffer_enabled) {
- sniffer |= AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
-
- /*
- * Rx decryption works in place.
- *
- * If we don't disable it, the hardware will render all
- * encrypted frames which are encrypted with an unknown
- * key useless.
- */
-
- encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
- ar->sniffer_enabled = true;
- } else {
- sniffer &= ~AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
-
- if (ar->rx_software_decryption)
- encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
- else
- encr_mode &= ~AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
- }
-
- ar9170_regwrite_begin(ar);
- ar9170_regwrite(AR9170_MAC_REG_ENCRYPTION, encr_mode);
- ar9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
- ar9170_regwrite_finish();
-
- return ar9170_regwrite_result();
-}
-
-int ar9170_set_operating_mode(struct ar9170 *ar)
-{
- struct ath_common *common = &ar->common;
- u32 pm_mode = AR9170_MAC_REG_POWERMGT_DEFAULTS;
- u8 *mac_addr, *bssid;
- int err;
-
- if (ar->vif) {
- mac_addr = common->macaddr;
- bssid = common->curbssid;
-
- switch (ar->vif->type) {
- case NL80211_IFTYPE_MESH_POINT:
- case NL80211_IFTYPE_ADHOC:
- pm_mode |= AR9170_MAC_REG_POWERMGT_IBSS;
- break;
- case NL80211_IFTYPE_AP:
- pm_mode |= AR9170_MAC_REG_POWERMGT_AP;
- break;
- case NL80211_IFTYPE_WDS:
- pm_mode |= AR9170_MAC_REG_POWERMGT_AP_WDS;
- break;
- case NL80211_IFTYPE_MONITOR:
- ar->sniffer_enabled = true;
- ar->rx_software_decryption = true;
- break;
- default:
- pm_mode |= AR9170_MAC_REG_POWERMGT_STA;
- break;
- }
- } else {
- mac_addr = NULL;
- bssid = NULL;
- }
-
- err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
- if (err)
- return err;
-
- err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
- if (err)
- return err;
-
- err = ar9170_set_promiscouous(ar);
- if (err)
- return err;
-
- /* set AMPDU density to 8us. */
- err = ar9170_set_ampdu_density(ar, 6);
- if (err)
- return err;
-
- ar9170_regwrite_begin(ar);
-
- ar9170_regwrite(AR9170_MAC_REG_POWERMANAGEMENT, pm_mode);
- ar9170_regwrite_finish();
-
- return ar9170_regwrite_result();
-}
-
-int ar9170_set_hwretry_limit(struct ar9170 *ar, unsigned int max_retry)
-{
- u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
-
- return ar9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
-}
-
-int ar9170_set_beacon_timers(struct ar9170 *ar)
-{
- u32 v = 0;
- u32 pretbtt = 0;
-
- if (ar->vif) {
- v |= ar->vif->bss_conf.beacon_int;
-
- if (ar->enable_beacon) {
- switch (ar->vif->type) {
- case NL80211_IFTYPE_MESH_POINT:
- case NL80211_IFTYPE_ADHOC:
- v |= BIT(25);
- break;
- case NL80211_IFTYPE_AP:
- v |= BIT(24);
- pretbtt = (ar->vif->bss_conf.beacon_int - 6) <<
- 16;
- break;
- default:
- break;
- }
- }
-
- v |= ar->vif->bss_conf.dtim_period << 16;
- }
-
- ar9170_regwrite_begin(ar);
- ar9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
- ar9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
- ar9170_regwrite_finish();
- return ar9170_regwrite_result();
-}
-
-int ar9170_update_beacon(struct ar9170 *ar)
-{
- struct sk_buff *skb;
- __le32 *data, *old = NULL;
- u32 word;
- int i;
-
- skb = ieee80211_beacon_get(ar->hw, ar->vif);
- if (!skb)
- return -ENOMEM;
-
- data = (__le32 *)skb->data;
- if (ar->beacon)
- old = (__le32 *)ar->beacon->data;
-
- ar9170_regwrite_begin(ar);
- for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
- /*
- * XXX: This accesses beyond skb data for up
- * to the last 3 bytes!!
- */
-
- if (old && (data[i] == old[i]))
- continue;
-
- word = le32_to_cpu(data[i]);
- ar9170_regwrite(AR9170_BEACON_BUFFER_ADDRESS + 4 * i, word);
- }
-
- /* XXX: use skb->cb info */
- if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
- ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
- ((skb->len + 4) << (3 + 16)) + 0x0400);
- else
- ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
- ((skb->len + 4) << 16) + 0x001b);
-
- ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4);
- ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS);
- ar9170_regwrite(AR9170_MAC_REG_BCN_CTRL, 1);
-
- ar9170_regwrite_finish();
-
- dev_kfree_skb(ar->beacon);
- ar->beacon = skb;
-
- return ar9170_regwrite_result();
-}
-
-void ar9170_new_beacon(struct work_struct *work)
-{
- struct ar9170 *ar = container_of(work, struct ar9170,
- beacon_work);
- struct sk_buff *skb;
-
- if (unlikely(!IS_STARTED(ar)))
- return ;
-
- mutex_lock(&ar->mutex);
-
- if (!ar->vif)
- goto out;
-
- ar9170_update_beacon(ar);
-
- rcu_read_lock();
- while ((skb = ieee80211_get_buffered_bc(ar->hw, ar->vif)))
- ar9170_op_tx(ar->hw, skb);
-
- rcu_read_unlock();
-
- out:
- mutex_unlock(&ar->mutex);
-}
-
-int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
- u8 keyidx, u8 *keydata, int keylen)
-{
- __le32 vals[7];
- static const u8 bcast[ETH_ALEN] =
- { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- u8 dummy;
-
- mac = mac ? : bcast;
-
- vals[0] = cpu_to_le32((keyidx << 16) + id);
- vals[1] = cpu_to_le32(mac[1] << 24 | mac[0] << 16 | ktype);
- vals[2] = cpu_to_le32(mac[5] << 24 | mac[4] << 16 |
- mac[3] << 8 | mac[2]);
- memset(&vals[3], 0, 16);
- if (keydata)
- memcpy(&vals[3], keydata, keylen);
-
- return ar->exec_cmd(ar, AR9170_CMD_EKEY,
- sizeof(vals), (u8 *)vals,
- 1, &dummy);
-}
-
-int ar9170_disable_key(struct ar9170 *ar, u8 id)
-{
- __le32 val = cpu_to_le32(id);
- u8 dummy;
-
- return ar->exec_cmd(ar, AR9170_CMD_EKEY,
- sizeof(val), (u8 *)&val,
- 1, &dummy);
-}
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
deleted file mode 100644
index ccc2edaaeda..00000000000
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ /dev/null
@@ -1,2190 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * mac80211 interaction code
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2009, Christian Lamparter <chunkeey@web.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- * Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/etherdevice.h>
-#include <net/mac80211.h>
-#include "ar9170.h"
-#include "hw.h"
-#include "cmd.h"
-
-static int modparam_nohwcrypt;
-module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
-MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
-
-#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \
- .bitrate = (_bitrate), \
- .flags = (_flags), \
- .hw_value = (_hw_rate) | (_txpidx) << 4, \
-}
-
-static struct ieee80211_rate __ar9170_ratetable[] = {
- RATE(10, 0, 0, 0),
- RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE),
- RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE),
- RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE),
- RATE(60, 0xb, 0, 0),
- RATE(90, 0xf, 0, 0),
- RATE(120, 0xa, 0, 0),
- RATE(180, 0xe, 0, 0),
- RATE(240, 0x9, 0, 0),
- RATE(360, 0xd, 1, 0),
- RATE(480, 0x8, 2, 0),
- RATE(540, 0xc, 3, 0),
-};
-#undef RATE
-
-#define ar9170_g_ratetable (__ar9170_ratetable + 0)
-#define ar9170_g_ratetable_size 12
-#define ar9170_a_ratetable (__ar9170_ratetable + 4)
-#define ar9170_a_ratetable_size 8
-
-/*
- * NB: The hw_value is used as an index into the ar9170_phy_freq_params
- * array in phy.c so that we don't have to do frequency lookups!
- */
-#define CHAN(_freq, _idx) { \
- .center_freq = (_freq), \
- .hw_value = (_idx), \
- .max_power = 18, /* XXX */ \
-}
-
-static struct ieee80211_channel ar9170_2ghz_chantable[] = {
- CHAN(2412, 0),
- CHAN(2417, 1),
- CHAN(2422, 2),
- CHAN(2427, 3),
- CHAN(2432, 4),
- CHAN(2437, 5),
- CHAN(2442, 6),
- CHAN(2447, 7),
- CHAN(2452, 8),
- CHAN(2457, 9),
- CHAN(2462, 10),
- CHAN(2467, 11),
- CHAN(2472, 12),
- CHAN(2484, 13),
-};
-
-static struct ieee80211_channel ar9170_5ghz_chantable[] = {
- CHAN(4920, 14),
- CHAN(4940, 15),
- CHAN(4960, 16),
- CHAN(4980, 17),
- CHAN(5040, 18),
- CHAN(5060, 19),
- CHAN(5080, 20),
- CHAN(5180, 21),
- CHAN(5200, 22),
- CHAN(5220, 23),
- CHAN(5240, 24),
- CHAN(5260, 25),
- CHAN(5280, 26),
- CHAN(5300, 27),
- CHAN(5320, 28),
- CHAN(5500, 29),
- CHAN(5520, 30),
- CHAN(5540, 31),
- CHAN(5560, 32),
- CHAN(5580, 33),
- CHAN(5600, 34),
- CHAN(5620, 35),
- CHAN(5640, 36),
- CHAN(5660, 37),
- CHAN(5680, 38),
- CHAN(5700, 39),
- CHAN(5745, 40),
- CHAN(5765, 41),
- CHAN(5785, 42),
- CHAN(5805, 43),
- CHAN(5825, 44),
- CHAN(5170, 45),
- CHAN(5190, 46),
- CHAN(5210, 47),
- CHAN(5230, 48),
-};
-#undef CHAN
-
-#define AR9170_HT_CAP \
-{ \
- .ht_supported = true, \
- .cap = IEEE80211_HT_CAP_MAX_AMSDU | \
- IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
- IEEE80211_HT_CAP_SGI_40 | \
- IEEE80211_HT_CAP_GRN_FLD | \
- IEEE80211_HT_CAP_DSSSCCK40 | \
- IEEE80211_HT_CAP_SM_PS, \
- .ampdu_factor = 3, \
- .ampdu_density = 6, \
- .mcs = { \
- .rx_mask = { 0xff, 0xff, 0, 0, 0x1, 0, 0, 0, 0, 0, }, \
- .rx_highest = cpu_to_le16(300), \
- .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
- }, \
-}
-
-static struct ieee80211_supported_band ar9170_band_2GHz = {
- .channels = ar9170_2ghz_chantable,
- .n_channels = ARRAY_SIZE(ar9170_2ghz_chantable),
- .bitrates = ar9170_g_ratetable,
- .n_bitrates = ar9170_g_ratetable_size,
- .ht_cap = AR9170_HT_CAP,
-};
-
-static struct ieee80211_supported_band ar9170_band_5GHz = {
- .channels = ar9170_5ghz_chantable,
- .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
- .bitrates = ar9170_a_ratetable,
- .n_bitrates = ar9170_a_ratetable_size,
- .ht_cap = AR9170_HT_CAP,
-};
-
-static void ar9170_tx(struct ar9170 *ar);
-
-static inline u16 ar9170_get_seq_h(struct ieee80211_hdr *hdr)
-{
- return le16_to_cpu(hdr->seq_ctrl) >> 4;
-}
-
-static inline u16 ar9170_get_seq(struct sk_buff *skb)
-{
- struct ar9170_tx_control *txc = (void *) skb->data;
- return ar9170_get_seq_h((void *) txc->frame_data);
-}
-
-#ifdef AR9170_QUEUE_DEBUG
-static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
-{
- struct ar9170_tx_control *txc = (void *) skb->data;
- struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
- struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
- struct ieee80211_hdr *hdr = (void *) txc->frame_data;
-
- wiphy_debug(ar->hw->wiphy,
- "=> FRAME [skb:%p, q:%d, DA:[%pM] s:%d "
- "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
- skb, skb_get_queue_mapping(skb),
- ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr),
- le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
- jiffies_to_msecs(arinfo->timeout - jiffies));
-}
-
-static void __ar9170_dump_txqueue(struct ar9170 *ar,
- struct sk_buff_head *queue)
-{
- struct sk_buff *skb;
- int i = 0;
-
- printk(KERN_DEBUG "---[ cut here ]---\n");
- wiphy_debug(ar->hw->wiphy, "%d entries in queue.\n",
- skb_queue_len(queue));
-
- skb_queue_walk(queue, skb) {
- printk(KERN_DEBUG "index:%d =>\n", i++);
- ar9170_print_txheader(ar, skb);
- }
- if (i != skb_queue_len(queue))
- printk(KERN_DEBUG "WARNING: queue frame counter "
- "mismatch %d != %d\n", skb_queue_len(queue), i);
- printk(KERN_DEBUG "---[ end ]---\n");
-}
-#endif /* AR9170_QUEUE_DEBUG */
-
-#ifdef AR9170_QUEUE_DEBUG
-static void ar9170_dump_txqueue(struct ar9170 *ar,
- struct sk_buff_head *queue)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&queue->lock, flags);
- __ar9170_dump_txqueue(ar, queue);
- spin_unlock_irqrestore(&queue->lock, flags);
-}
-#endif /* AR9170_QUEUE_DEBUG */
-
-#ifdef AR9170_QUEUE_STOP_DEBUG
-static void __ar9170_dump_txstats(struct ar9170 *ar)
-{
- int i;
-
- wiphy_debug(ar->hw->wiphy, "QoS queue stats\n");
-
- for (i = 0; i < __AR9170_NUM_TXQ; i++)
- wiphy_debug(ar->hw->wiphy,
- "queue:%d limit:%d len:%d waitack:%d stopped:%d\n",
- i, ar->tx_stats[i].limit, ar->tx_stats[i].len,
- skb_queue_len(&ar->tx_status[i]),
- ieee80211_queue_stopped(ar->hw, i));
-}
-#endif /* AR9170_QUEUE_STOP_DEBUG */
-
-/* caller must guarantee exclusive access for _bin_ queue. */
-static void ar9170_recycle_expired(struct ar9170 *ar,
- struct sk_buff_head *queue,
- struct sk_buff_head *bin)
-{
- struct sk_buff *skb, *old = NULL;
- unsigned long flags;
-
- spin_lock_irqsave(&queue->lock, flags);
- while ((skb = skb_peek(queue))) {
- struct ieee80211_tx_info *txinfo;
- struct ar9170_tx_info *arinfo;
-
- txinfo = IEEE80211_SKB_CB(skb);
- arinfo = (void *) txinfo->rate_driver_data;
-
- if (time_is_before_jiffies(arinfo->timeout)) {
-#ifdef AR9170_QUEUE_DEBUG
- wiphy_debug(ar->hw->wiphy,
- "[%ld > %ld] frame expired => recycle\n",
- jiffies, arinfo->timeout);
- ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
- __skb_unlink(skb, queue);
- __skb_queue_tail(bin, skb);
- } else {
- break;
- }
-
- if (unlikely(old == skb)) {
- /* bail out - queue is shot. */
-
- WARN_ON(1);
- break;
- }
- old = skb;
- }
- spin_unlock_irqrestore(&queue->lock, flags);
-}
-
-static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
- u16 tx_status)
-{
- struct ieee80211_tx_info *txinfo;
- unsigned int retries = 0;
-
- txinfo = IEEE80211_SKB_CB(skb);
- ieee80211_tx_info_clear_status(txinfo);
-
- switch (tx_status) {
- case AR9170_TX_STATUS_RETRY:
- retries = 2;
- case AR9170_TX_STATUS_COMPLETE:
- txinfo->flags |= IEEE80211_TX_STAT_ACK;
- break;
-
- case AR9170_TX_STATUS_FAILED:
- retries = ar->hw->conf.long_frame_max_tx_count;
- break;
-
- default:
- wiphy_err(ar->hw->wiphy,
- "invalid tx_status response (%x)\n", tx_status);
- break;
- }
-
- txinfo->status.rates[0].count = retries + 1;
- skb_pull(skb, sizeof(struct ar9170_tx_control));
- ieee80211_tx_status_irqsafe(ar->hw, skb);
-}
-
-void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
-{
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data;
- unsigned int queue = skb_get_queue_mapping(skb);
- unsigned long flags;
-
- spin_lock_irqsave(&ar->tx_stats_lock, flags);
- ar->tx_stats[queue].len--;
-
- if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) {
-#ifdef AR9170_QUEUE_STOP_DEBUG
- wiphy_debug(ar->hw->wiphy, "wake queue %d\n", queue);
- __ar9170_dump_txstats(ar);
-#endif /* AR9170_QUEUE_STOP_DEBUG */
- ieee80211_wake_queue(ar->hw, queue);
- }
- spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-
- if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
- ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED);
- } else {
- arinfo->timeout = jiffies +
- msecs_to_jiffies(AR9170_TX_TIMEOUT);
-
- skb_queue_tail(&ar->tx_status[queue], skb);
- }
-
- if (!ar->tx_stats[queue].len &&
- !skb_queue_empty(&ar->tx_pending[queue])) {
- ar9170_tx(ar);
- }
-}
-
-static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
- const u8 *mac,
- struct sk_buff_head *queue,
- const u32 rate)
-{
- unsigned long flags;
- struct sk_buff *skb;
-
- /*
- * Unfortunately, the firmware does not tell to which (queued) frame
- * this transmission status report belongs to.
- *
- * So we have to make risky guesses - with the scarce information
- * the firmware provided (-> destination MAC, and phy_control) -
- * and hope that we picked the right one...
- */
-
- spin_lock_irqsave(&queue->lock, flags);
- skb_queue_walk(queue, skb) {
- struct ar9170_tx_control *txc = (void *) skb->data;
- struct ieee80211_hdr *hdr = (void *) txc->frame_data;
- u32 r;
-
- if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) {
-#ifdef AR9170_QUEUE_DEBUG
- wiphy_debug(ar->hw->wiphy,
- "skip frame => DA %pM != %pM\n",
- mac, ieee80211_get_DA(hdr));
- ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
- continue;
- }
-
- r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >>
- AR9170_TX_PHY_MCS_SHIFT;
-
- if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) {
-#ifdef AR9170_QUEUE_DEBUG
- wiphy_debug(ar->hw->wiphy,
- "skip frame => rate %d != %d\n", rate, r);
- ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
- continue;
- }
-
- __skb_unlink(skb, queue);
- spin_unlock_irqrestore(&queue->lock, flags);
- return skb;
- }
-
-#ifdef AR9170_QUEUE_DEBUG
- wiphy_err(ar->hw->wiphy,
- "ESS:[%pM] does not have any outstanding frames in queue.\n",
- mac);
- __ar9170_dump_txqueue(ar, queue);
-#endif /* AR9170_QUEUE_DEBUG */
- spin_unlock_irqrestore(&queue->lock, flags);
-
- return NULL;
-}
-
-/*
- * This worker tries to keeps an maintain tx_status queues.
- * So we can guarantee that incoming tx_status reports are
- * actually for a pending frame.
- */
-
-static void ar9170_tx_janitor(struct work_struct *work)
-{
- struct ar9170 *ar = container_of(work, struct ar9170,
- tx_janitor.work);
- struct sk_buff_head waste;
- unsigned int i;
- bool resched = false;
-
- if (unlikely(!IS_STARTED(ar)))
- return ;
-
- skb_queue_head_init(&waste);
-
- for (i = 0; i < __AR9170_NUM_TXQ; i++) {
-#ifdef AR9170_QUEUE_DEBUG
- wiphy_debug(ar->hw->wiphy, "garbage collector scans queue:%d\n",
- i);
- ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
- ar9170_dump_txqueue(ar, &ar->tx_status[i]);
-#endif /* AR9170_QUEUE_DEBUG */
-
- ar9170_recycle_expired(ar, &ar->tx_status[i], &waste);
- ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste);
- skb_queue_purge(&waste);
-
- if (!skb_queue_empty(&ar->tx_status[i]) ||
- !skb_queue_empty(&ar->tx_pending[i]))
- resched = true;
- }
-
- if (!resched)
- return;
-
- ieee80211_queue_delayed_work(ar->hw,
- &ar->tx_janitor,
- msecs_to_jiffies(AR9170_JANITOR_DELAY));
-}
-
-void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
-{
- struct ar9170_cmd_response *cmd = (void *) buf;
-
- if ((cmd->type & 0xc0) != 0xc0) {
- ar->callback_cmd(ar, len, buf);
- return;
- }
-
- /* hardware event handlers */
- switch (cmd->type) {
- case 0xc1: {
- /*
- * TX status notification:
- * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1
- *
- * XX always 81
- * YY always 00
- * M1-M6 is the MAC address
- * R1-R4 is the transmit rate
- * S1-S2 is the transmit status
- */
-
- struct sk_buff *skb;
- u32 phy = le32_to_cpu(cmd->tx_status.rate);
- u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >>
- AR9170_TX_PHY_QOS_SHIFT;
-#ifdef AR9170_QUEUE_DEBUG
- wiphy_debug(ar->hw->wiphy,
- "recv tx_status for %pm, p:%08x, q:%d\n",
- cmd->tx_status.dst, phy, q);
-#endif /* AR9170_QUEUE_DEBUG */
-
- skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst,
- &ar->tx_status[q],
- AR9170_TX_INVALID_RATE);
- if (unlikely(!skb))
- return ;
-
- ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status));
- break;
- }
-
- case 0xc0:
- /*
- * pre-TBTT event
- */
- if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
- ieee80211_queue_work(ar->hw, &ar->beacon_work);
- break;
-
- case 0xc2:
- /*
- * (IBSS) beacon send notification
- * bytes: 04 c2 XX YY B4 B3 B2 B1
- *
- * XX always 80
- * YY always 00
- * B1-B4 "should" be the number of send out beacons.
- */
- break;
-
- case 0xc3:
- /* End of Atim Window */
- break;
-
- case 0xc4:
- /* BlockACK bitmap */
- break;
-
- case 0xc5:
- /* BlockACK events */
- break;
-
- case 0xc6:
- /* Watchdog Interrupt */
- break;
-
- case 0xc9:
- /* retransmission issue / SIFS/EIFS collision ?! */
- break;
-
- /* firmware debug */
- case 0xca:
- printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4,
- (char *)buf + 4);
- break;
- case 0xcb:
- len -= 4;
-
- switch (len) {
- case 1:
- printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n",
- *((char *)buf + 4));
- break;
- case 2:
- printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n",
- le16_to_cpup((__le16 *)((char *)buf + 4)));
- break;
- case 4:
- printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n",
- le32_to_cpup((__le32 *)((char *)buf + 4)));
- break;
- case 8:
- printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n",
- (unsigned long)le64_to_cpup(
- (__le64 *)((char *)buf + 4)));
- break;
- }
- break;
- case 0xcc:
- print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE,
- (char *)buf + 4, len - 4);
- break;
-
- default:
- pr_info("received unhandled event %x\n", cmd->type);
- print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
- break;
- }
-}
-
-static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar)
-{
- memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head));
- ar->rx_mpdu.has_plcp = false;
-}
-
-int ar9170_nag_limiter(struct ar9170 *ar)
-{
- bool print_message;
-
- /*
- * we expect all sorts of errors in promiscuous mode.
- * don't bother with it, it's OK!
- */
- if (ar->sniffer_enabled)
- return false;
-
- /*
- * only go for frequent errors! The hardware tends to
- * do some stupid thing once in a while under load, in
- * noisy environments or just for fun!
- */
- if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit())
- print_message = true;
- else
- print_message = false;
-
- /* reset threshold for "once in a while" */
- ar->bad_hw_nagger = jiffies + HZ / 4;
- return print_message;
-}
-
-static int ar9170_rx_mac_status(struct ar9170 *ar,
- struct ar9170_rx_head *head,
- struct ar9170_rx_macstatus *mac,
- struct ieee80211_rx_status *status)
-{
- u8 error, decrypt;
-
- BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
- BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4);
-
- error = mac->error;
- if (error & AR9170_RX_ERROR_MMIC) {
- status->flag |= RX_FLAG_MMIC_ERROR;
- error &= ~AR9170_RX_ERROR_MMIC;
- }
-
- if (error & AR9170_RX_ERROR_PLCP) {
- status->flag |= RX_FLAG_FAILED_PLCP_CRC;
- error &= ~AR9170_RX_ERROR_PLCP;
-
- if (!(ar->filter_state & FIF_PLCPFAIL))
- return -EINVAL;
- }
-
- if (error & AR9170_RX_ERROR_FCS) {
- status->flag |= RX_FLAG_FAILED_FCS_CRC;
- error &= ~AR9170_RX_ERROR_FCS;
-
- if (!(ar->filter_state & FIF_FCSFAIL))
- return -EINVAL;
- }
-
- decrypt = ar9170_get_decrypt_type(mac);
- if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
- decrypt != AR9170_ENC_ALG_NONE)
- status->flag |= RX_FLAG_DECRYPTED;
-
- /* ignore wrong RA errors */
- error &= ~AR9170_RX_ERROR_WRONG_RA;
-
- if (error & AR9170_RX_ERROR_DECRYPT) {
- error &= ~AR9170_RX_ERROR_DECRYPT;
- /*
- * Rx decryption is done in place,
- * the original data is lost anyway.
- */
-
- return -EINVAL;
- }
-
- /* drop any other error frames */
- if (unlikely(error)) {
- /* TODO: update netdevice's RX dropped/errors statistics */
-
- if (ar9170_nag_limiter(ar))
- wiphy_debug(ar->hw->wiphy,
- "received frame with suspicious error code (%#x).\n",
- error);
-
- return -EINVAL;
- }
-
- status->band = ar->channel->band;
- status->freq = ar->channel->center_freq;
-
- switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) {
- case AR9170_RX_STATUS_MODULATION_CCK:
- if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
- status->flag |= RX_FLAG_SHORTPRE;
- switch (head->plcp[0]) {
- case 0x0a:
- status->rate_idx = 0;
- break;
- case 0x14:
- status->rate_idx = 1;
- break;
- case 0x37:
- status->rate_idx = 2;
- break;
- case 0x6e:
- status->rate_idx = 3;
- break;
- default:
- if (ar9170_nag_limiter(ar))
- wiphy_err(ar->hw->wiphy,
- "invalid plcp cck rate (%x).\n",
- head->plcp[0]);
- return -EINVAL;
- }
- break;
-
- case AR9170_RX_STATUS_MODULATION_DUPOFDM:
- case AR9170_RX_STATUS_MODULATION_OFDM:
- switch (head->plcp[0] & 0xf) {
- case 0xb:
- status->rate_idx = 0;
- break;
- case 0xf:
- status->rate_idx = 1;
- break;
- case 0xa:
- status->rate_idx = 2;
- break;
- case 0xe:
- status->rate_idx = 3;
- break;
- case 0x9:
- status->rate_idx = 4;
- break;
- case 0xd:
- status->rate_idx = 5;
- break;
- case 0x8:
- status->rate_idx = 6;
- break;
- case 0xc:
- status->rate_idx = 7;
- break;
- default:
- if (ar9170_nag_limiter(ar))
- wiphy_err(ar->hw->wiphy,
- "invalid plcp ofdm rate (%x).\n",
- head->plcp[0]);
- return -EINVAL;
- }
- if (status->band == IEEE80211_BAND_2GHZ)
- status->rate_idx += 4;
- break;
-
- case AR9170_RX_STATUS_MODULATION_HT:
- if (head->plcp[3] & 0x80)
- status->flag |= RX_FLAG_40MHZ;
- if (head->plcp[6] & 0x80)
- status->flag |= RX_FLAG_SHORT_GI;
-
- status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f);
- status->flag |= RX_FLAG_HT;
- break;
-
- default:
- if (ar9170_nag_limiter(ar))
- wiphy_err(ar->hw->wiphy, "invalid modulation\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void ar9170_rx_phy_status(struct ar9170 *ar,
- struct ar9170_rx_phystatus *phy,
- struct ieee80211_rx_status *status)
-{
- int i;
-
- BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20);
-
- for (i = 0; i < 3; i++)
- if (phy->rssi[i] != 0x80)
- status->antenna |= BIT(i);
-
- /* post-process RSSI */
- for (i = 0; i < 7; i++)
- if (phy->rssi[i] & 0x80)
- phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f;
-
- /* TODO: we could do something with phy_errors */
- status->signal = ar->noise[0] + phy->rssi_combined;
-}
-
-static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len)
-{
- struct sk_buff *skb;
- int reserved = 0;
- struct ieee80211_hdr *hdr = (void *) buf;
-
- if (ieee80211_is_data_qos(hdr->frame_control)) {
- u8 *qc = ieee80211_get_qos_ctl(hdr);
- reserved += NET_IP_ALIGN;
-
- if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
- reserved += NET_IP_ALIGN;
- }
-
- if (ieee80211_has_a4(hdr->frame_control))
- reserved += NET_IP_ALIGN;
-
- reserved = 32 + (reserved & NET_IP_ALIGN);
-
- skb = dev_alloc_skb(len + reserved);
- if (likely(skb)) {
- skb_reserve(skb, reserved);
- memcpy(skb_put(skb, len), buf, len);
- }
-
- return skb;
-}
-
-/*
- * If the frame alignment is right (or the kernel has
- * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
- * is only a single MPDU in the USB frame, then we could
- * submit to mac80211 the SKB directly. However, since
- * there may be multiple packets in one SKB in stream
- * mode, and we need to observe the proper ordering,
- * this is non-trivial.
- */
-
-static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
-{
- struct ar9170_rx_head *head;
- struct ar9170_rx_macstatus *mac;
- struct ar9170_rx_phystatus *phy = NULL;
- struct ieee80211_rx_status status;
- struct sk_buff *skb;
- int mpdu_len;
-
- if (unlikely(!IS_STARTED(ar) || len < (sizeof(*mac))))
- return ;
-
- /* Received MPDU */
- mpdu_len = len - sizeof(*mac);
-
- mac = (void *)(buf + mpdu_len);
- if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) {
- /* this frame is too damaged and can't be used - drop it */
-
- return ;
- }
-
- switch (mac->status & AR9170_RX_STATUS_MPDU_MASK) {
- case AR9170_RX_STATUS_MPDU_FIRST:
- /* first mpdu packet has the plcp header */
- if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
- head = (void *) buf;
- memcpy(&ar->rx_mpdu.plcp, (void *) buf,
- sizeof(struct ar9170_rx_head));
-
- mpdu_len -= sizeof(struct ar9170_rx_head);
- buf += sizeof(struct ar9170_rx_head);
- ar->rx_mpdu.has_plcp = true;
- } else {
- if (ar9170_nag_limiter(ar))
- wiphy_err(ar->hw->wiphy,
- "plcp info is clipped.\n");
- return ;
- }
- break;
-
- case AR9170_RX_STATUS_MPDU_LAST:
- /* last mpdu has a extra tail with phy status information */
-
- if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
- mpdu_len -= sizeof(struct ar9170_rx_phystatus);
- phy = (void *)(buf + mpdu_len);
- } else {
- if (ar9170_nag_limiter(ar))
- wiphy_err(ar->hw->wiphy,
- "frame tail is clipped.\n");
- return ;
- }
-
- case AR9170_RX_STATUS_MPDU_MIDDLE:
- /* middle mpdus are just data */
- if (unlikely(!ar->rx_mpdu.has_plcp)) {
- if (!ar9170_nag_limiter(ar))
- return ;
-
- wiphy_err(ar->hw->wiphy,
- "rx stream did not start with a first_mpdu frame tag.\n");
-
- return ;
- }
-
- head = &ar->rx_mpdu.plcp;
- break;
-
- case AR9170_RX_STATUS_MPDU_SINGLE:
- /* single mpdu - has plcp (head) and phy status (tail) */
- head = (void *) buf;
-
- mpdu_len -= sizeof(struct ar9170_rx_head);
- mpdu_len -= sizeof(struct ar9170_rx_phystatus);
-
- buf += sizeof(struct ar9170_rx_head);
- phy = (void *)(buf + mpdu_len);
- break;
-
- default:
- BUG_ON(1);
- break;
- }
-
- if (unlikely(mpdu_len < FCS_LEN))
- return ;
-
- memset(&status, 0, sizeof(status));
- if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status)))
- return ;
-
- if (phy)
- ar9170_rx_phy_status(ar, phy, &status);
-
- skb = ar9170_rx_copy_data(buf, mpdu_len);
- if (likely(skb)) {
- memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
- ieee80211_rx_irqsafe(ar->hw, skb);
- }
-}
-
-void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
-{
- unsigned int i, tlen, resplen, wlen = 0, clen = 0;
- u8 *tbuf, *respbuf;
-
- tbuf = skb->data;
- tlen = skb->len;
-
- while (tlen >= 4) {
- clen = tbuf[1] << 8 | tbuf[0];
- wlen = ALIGN(clen, 4);
-
- /* check if this is stream has a valid tag.*/
- if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
- /*
- * TODO: handle the highly unlikely event that the
- * corrupted stream has the TAG at the right position.
- */
-
- /* check if the frame can be repaired. */
- if (!ar->rx_failover_missing) {
- /* this is no "short read". */
- if (ar9170_nag_limiter(ar)) {
- wiphy_err(ar->hw->wiphy,
- "missing tag!\n");
- goto err_telluser;
- } else
- goto err_silent;
- }
-
- if (ar->rx_failover_missing > tlen) {
- if (ar9170_nag_limiter(ar)) {
- wiphy_err(ar->hw->wiphy,
- "possible multi stream corruption!\n");
- goto err_telluser;
- } else
- goto err_silent;
- }
-
- memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
- ar->rx_failover_missing -= tlen;
-
- if (ar->rx_failover_missing <= 0) {
- /*
- * nested ar9170_rx call!
- * termination is guaranteed, even when the
- * combined frame also have a element with
- * a bad tag.
- */
-
- ar->rx_failover_missing = 0;
- ar9170_rx(ar, ar->rx_failover);
-
- skb_reset_tail_pointer(ar->rx_failover);
- skb_trim(ar->rx_failover, 0);
- }
-
- return ;
- }
-
- /* check if stream is clipped */
- if (wlen > tlen - 4) {
- if (ar->rx_failover_missing) {
- /* TODO: handle double stream corruption. */
- if (ar9170_nag_limiter(ar)) {
- wiphy_err(ar->hw->wiphy,
- "double rx stream corruption!\n");
- goto err_telluser;
- } else
- goto err_silent;
- }
-
- /*
- * save incomplete data set.
- * the firmware will resend the missing bits when
- * the rx - descriptor comes round again.
- */
-
- memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
- ar->rx_failover_missing = clen - tlen;
- return ;
- }
- resplen = clen;
- respbuf = tbuf + 4;
- tbuf += wlen + 4;
- tlen -= wlen + 4;
-
- i = 0;
-
- /* weird thing, but this is the same in the original driver */
- while (resplen > 2 && i < 12 &&
- respbuf[0] == 0xff && respbuf[1] == 0xff) {
- i += 2;
- resplen -= 2;
- respbuf += 2;
- }
-
- if (resplen < 4)
- continue;
-
- /* found the 6 * 0xffff marker? */
- if (i == 12)
- ar9170_handle_command_response(ar, respbuf, resplen);
- else
- ar9170_handle_mpdu(ar, respbuf, clen);
- }
-
- if (tlen) {
- if (net_ratelimit())
- wiphy_err(ar->hw->wiphy,
- "%d bytes of unprocessed data left in rx stream!\n",
- tlen);
-
- goto err_telluser;
- }
-
- return ;
-
-err_telluser:
- wiphy_err(ar->hw->wiphy,
- "damaged RX stream data [want:%d, data:%d, rx:%d, pending:%d ]\n",
- clen, wlen, tlen, ar->rx_failover_missing);
-
- if (ar->rx_failover_missing)
- print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
- ar->rx_failover->data,
- ar->rx_failover->len);
-
- print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
- skb->data, skb->len);
-
- wiphy_err(ar->hw->wiphy,
- "If you see this message frequently, please check your hardware and cables.\n");
-
-err_silent:
- if (ar->rx_failover_missing) {
- skb_reset_tail_pointer(ar->rx_failover);
- skb_trim(ar->rx_failover, 0);
- ar->rx_failover_missing = 0;
- }
-}
-
-#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \
-do { \
- queue.aifs = ai_fs; \
- queue.cw_min = cwmin; \
- queue.cw_max = cwmax; \
- queue.txop = _txop; \
-} while (0)
-
-static int ar9170_op_start(struct ieee80211_hw *hw)
-{
- struct ar9170 *ar = hw->priv;
- int err, i;
-
- mutex_lock(&ar->mutex);
-
- /* reinitialize queues statistics */
- memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
- for (i = 0; i < __AR9170_NUM_TXQ; i++)
- ar->tx_stats[i].limit = AR9170_TXQ_DEPTH;
-
- /* reset QoS defaults */
- AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/
- AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023, 0); /* BACKGROUND */
- AR9170_FILL_QUEUE(ar->edcf[2], 2, 7, 15, 94); /* VIDEO */
- AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */
- AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */
-
- /* set sane AMPDU defaults */
- ar->global_ampdu_density = 6;
- ar->global_ampdu_factor = 3;
-
- ar->bad_hw_nagger = jiffies;
-
- err = ar->open(ar);
- if (err)
- goto out;
-
- err = ar9170_init_mac(ar);
- if (err)
- goto out;
-
- err = ar9170_set_qos(ar);
- if (err)
- goto out;
-
- err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
- if (err)
- goto out;
-
- err = ar9170_init_rf(ar);
- if (err)
- goto out;
-
- /* start DMA */
- err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
- if (err)
- goto out;
-
- ar->state = AR9170_STARTED;
-
-out:
- mutex_unlock(&ar->mutex);
- return err;
-}
-
-static void ar9170_op_stop(struct ieee80211_hw *hw)
-{
- struct ar9170 *ar = hw->priv;
- unsigned int i;
-
- if (IS_STARTED(ar))
- ar->state = AR9170_IDLE;
-
- cancel_delayed_work_sync(&ar->tx_janitor);
-#ifdef CONFIG_AR9170_LEDS
- cancel_delayed_work_sync(&ar->led_work);
-#endif
- cancel_work_sync(&ar->beacon_work);
-
- mutex_lock(&ar->mutex);
-
- if (IS_ACCEPTING_CMD(ar)) {
- ar9170_set_leds_state(ar, 0);
-
- /* stop DMA */
- ar9170_write_reg(ar, 0x1c3d30, 0);
- ar->stop(ar);
- }
-
- for (i = 0; i < __AR9170_NUM_TXQ; i++) {
- skb_queue_purge(&ar->tx_pending[i]);
- skb_queue_purge(&ar->tx_status[i]);
- }
-
- mutex_unlock(&ar->mutex);
-}
-
-static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
-{
- struct ieee80211_hdr *hdr;
- struct ar9170_tx_control *txc;
- struct ieee80211_tx_info *info;
- struct ieee80211_tx_rate *txrate;
- struct ar9170_tx_info *arinfo;
- unsigned int queue = skb_get_queue_mapping(skb);
- u16 keytype = 0;
- u16 len, icv = 0;
-
- BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
-
- hdr = (void *)skb->data;
- info = IEEE80211_SKB_CB(skb);
- len = skb->len;
-
- txc = (void *)skb_push(skb, sizeof(*txc));
-
- if (info->control.hw_key) {
- icv = info->control.hw_key->icv_len;
-
- switch (info->control.hw_key->cipher) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- case WLAN_CIPHER_SUITE_TKIP:
- keytype = AR9170_TX_MAC_ENCR_RC4;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- keytype = AR9170_TX_MAC_ENCR_AES;
- break;
- default:
- WARN_ON(1);
- goto err_out;
- }
- }
-
- /* Length */
- txc->length = cpu_to_le16(len + icv + 4);
-
- txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
- AR9170_TX_MAC_BACKOFF);
- txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
- AR9170_TX_MAC_QOS_SHIFT);
- txc->mac_control |= cpu_to_le16(keytype);
- txc->phy_control = cpu_to_le32(0);
-
- if (info->flags & IEEE80211_TX_CTL_NO_ACK)
- txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
-
- txrate = &info->control.rates[0];
- if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
- txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
- else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
- txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
-
- arinfo = (void *)info->rate_driver_data;
- arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT);
-
- if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
- (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
- /*
- * WARNING:
- * Putting the QoS queue bits into an unexplored territory is
- * certainly not elegant.
- *
- * In my defense: This idea provides a reasonable way to
- * smuggle valuable information to the tx_status callback.
- * Also, the idea behind this bit-abuse came straight from
- * the original driver code.
- */
-
- txc->phy_control |=
- cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
-
- txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
- }
-
- return 0;
-
-err_out:
- skb_pull(skb, sizeof(*txc));
- return -EINVAL;
-}
-
-static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
-{
- struct ar9170_tx_control *txc;
- struct ieee80211_tx_info *info;
- struct ieee80211_rate *rate = NULL;
- struct ieee80211_tx_rate *txrate;
- u32 power, chains;
-
- txc = (void *) skb->data;
- info = IEEE80211_SKB_CB(skb);
- txrate = &info->control.rates[0];
-
- if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
- txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
-
- if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
- txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
-
- if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
- txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
- /* this works because 40 MHz is 2 and dup is 3 */
- if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
- txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
-
- if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
- txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
-
- if (txrate->flags & IEEE80211_TX_RC_MCS) {
- u32 r = txrate->idx;
- u8 *txpower;
-
- /* heavy clip control */
- txc->phy_control |= cpu_to_le32((r & 0x7) << 7);
-
- r <<= AR9170_TX_PHY_MCS_SHIFT;
- BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK);
-
- txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
- txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
-
- if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
- if (info->band == IEEE80211_BAND_5GHZ)
- txpower = ar->power_5G_ht40;
- else
- txpower = ar->power_2G_ht40;
- } else {
- if (info->band == IEEE80211_BAND_5GHZ)
- txpower = ar->power_5G_ht20;
- else
- txpower = ar->power_2G_ht20;
- }
-
- power = txpower[(txrate->idx) & 7];
- } else {
- u8 *txpower;
- u32 mod;
- u32 phyrate;
- u8 idx = txrate->idx;
-
- if (info->band != IEEE80211_BAND_2GHZ) {
- idx += 4;
- txpower = ar->power_5G_leg;
- mod = AR9170_TX_PHY_MOD_OFDM;
- } else {
- if (idx < 4) {
- txpower = ar->power_2G_cck;
- mod = AR9170_TX_PHY_MOD_CCK;
- } else {
- mod = AR9170_TX_PHY_MOD_OFDM;
- txpower = ar->power_2G_ofdm;
- }
- }
-
- rate = &__ar9170_ratetable[idx];
-
- phyrate = rate->hw_value & 0xF;
- power = txpower[(rate->hw_value & 0x30) >> 4];
- phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
-
- txc->phy_control |= cpu_to_le32(mod);
- txc->phy_control |= cpu_to_le32(phyrate);
- }
-
- power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
- power &= AR9170_TX_PHY_TX_PWR_MASK;
- txc->phy_control |= cpu_to_le32(power);
-
- /* set TX chains */
- if (ar->eeprom.tx_mask == 1) {
- chains = AR9170_TX_PHY_TXCHAIN_1;
- } else {
- chains = AR9170_TX_PHY_TXCHAIN_2;
-
- /* >= 36M legacy OFDM - use only one chain */
- if (rate && rate->bitrate >= 360)
- chains = AR9170_TX_PHY_TXCHAIN_1;
- }
- txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
-}
-
-static void ar9170_tx(struct ar9170 *ar)
-{
- struct sk_buff *skb;
- unsigned long flags;
- struct ieee80211_tx_info *info;
- struct ar9170_tx_info *arinfo;
- unsigned int i, frames, frames_failed, remaining_space;
- int err;
- bool schedule_garbagecollector = false;
-
- BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
-
- if (unlikely(!IS_STARTED(ar)))
- return ;
-
- remaining_space = AR9170_TX_MAX_PENDING;
-
- for (i = 0; i < __AR9170_NUM_TXQ; i++) {
- spin_lock_irqsave(&ar->tx_stats_lock, flags);
- frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
- skb_queue_len(&ar->tx_pending[i]));
-
- if (remaining_space < frames) {
-#ifdef AR9170_QUEUE_DEBUG
- wiphy_debug(ar->hw->wiphy,
- "tx quota reached queue:%d, "
- "remaining slots:%d, needed:%d\n",
- i, remaining_space, frames);
-#endif /* AR9170_QUEUE_DEBUG */
- frames = remaining_space;
- }
-
- ar->tx_stats[i].len += frames;
- ar->tx_stats[i].count += frames;
- if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
-#ifdef AR9170_QUEUE_DEBUG
- wiphy_debug(ar->hw->wiphy, "queue %d full\n", i);
- wiphy_debug(ar->hw->wiphy, "stuck frames: ===>\n");
- ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
- ar9170_dump_txqueue(ar, &ar->tx_status[i]);
-#endif /* AR9170_QUEUE_DEBUG */
-
-#ifdef AR9170_QUEUE_STOP_DEBUG
- wiphy_debug(ar->hw->wiphy, "stop queue %d\n", i);
- __ar9170_dump_txstats(ar);
-#endif /* AR9170_QUEUE_STOP_DEBUG */
- ieee80211_stop_queue(ar->hw, i);
- }
-
- spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-
- if (!frames)
- continue;
-
- frames_failed = 0;
- while (frames) {
- skb = skb_dequeue(&ar->tx_pending[i]);
- if (unlikely(!skb)) {
- frames_failed += frames;
- frames = 0;
- break;
- }
-
- info = IEEE80211_SKB_CB(skb);
- arinfo = (void *) info->rate_driver_data;
-
- /* TODO: cancel stuck frames */
- arinfo->timeout = jiffies +
- msecs_to_jiffies(AR9170_TX_TIMEOUT);
-
-#ifdef AR9170_QUEUE_DEBUG
- wiphy_debug(ar->hw->wiphy, "send frame q:%d =>\n", i);
- ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
-
- err = ar->tx(ar, skb);
- if (unlikely(err)) {
- frames_failed++;
- dev_kfree_skb_any(skb);
- } else {
- remaining_space--;
- schedule_garbagecollector = true;
- }
-
- frames--;
- }
-
-#ifdef AR9170_QUEUE_DEBUG
- wiphy_debug(ar->hw->wiphy,
- "ar9170_tx report for queue %d\n", i);
-
- wiphy_debug(ar->hw->wiphy,
- "unprocessed pending frames left:\n");
- ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
-#endif /* AR9170_QUEUE_DEBUG */
-
- if (unlikely(frames_failed)) {
-#ifdef AR9170_QUEUE_DEBUG
- wiphy_debug(ar->hw->wiphy,
- "frames failed %d =>\n", frames_failed);
-#endif /* AR9170_QUEUE_DEBUG */
-
- spin_lock_irqsave(&ar->tx_stats_lock, flags);
- ar->tx_stats[i].len -= frames_failed;
- ar->tx_stats[i].count -= frames_failed;
-#ifdef AR9170_QUEUE_STOP_DEBUG
- wiphy_debug(ar->hw->wiphy, "wake queue %d\n", i);
- __ar9170_dump_txstats(ar);
-#endif /* AR9170_QUEUE_STOP_DEBUG */
- ieee80211_wake_queue(ar->hw, i);
- spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
- }
- }
-
- if (!schedule_garbagecollector)
- return;
-
- ieee80211_queue_delayed_work(ar->hw,
- &ar->tx_janitor,
- msecs_to_jiffies(AR9170_JANITOR_DELAY));
-}
-
-void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct ar9170 *ar = hw->priv;
- struct ieee80211_tx_info *info;
- unsigned int queue;
-
- if (unlikely(!IS_STARTED(ar)))
- goto err_free;
-
- if (unlikely(ar9170_tx_prepare(ar, skb)))
- goto err_free;
-
- queue = skb_get_queue_mapping(skb);
- info = IEEE80211_SKB_CB(skb);
- ar9170_tx_prepare_phy(ar, skb);
- skb_queue_tail(&ar->tx_pending[queue], skb);
-
- ar9170_tx(ar);
- return;
-
-err_free:
- dev_kfree_skb_any(skb);
-}
-
-static int ar9170_op_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
-{
- struct ar9170 *ar = hw->priv;
- struct ath_common *common = &ar->common;
- int err = 0;
-
- mutex_lock(&ar->mutex);
-
- if (ar->vif) {
- err = -EBUSY;
- goto unlock;
- }
-
- ar->vif = vif;
- memcpy(common->macaddr, vif->addr, ETH_ALEN);
-
- if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
- ar->rx_software_decryption = true;
- ar->disable_offload = true;
- }
-
- ar->cur_filter = 0;
- err = ar9170_update_frame_filter(ar, AR9170_MAC_REG_FTF_DEFAULTS);
- if (err)
- goto unlock;
-
- err = ar9170_set_operating_mode(ar);
-
-unlock:
- mutex_unlock(&ar->mutex);
- return err;
-}
-
-static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
-{
- struct ar9170 *ar = hw->priv;
-
- mutex_lock(&ar->mutex);
- ar->vif = NULL;
- ar9170_update_frame_filter(ar, 0);
- ar9170_set_beacon_timers(ar);
- dev_kfree_skb(ar->beacon);
- ar->beacon = NULL;
- ar->sniffer_enabled = false;
- ar->rx_software_decryption = false;
- ar9170_set_operating_mode(ar);
- mutex_unlock(&ar->mutex);
-}
-
-static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
-{
- struct ar9170 *ar = hw->priv;
- int err = 0;
-
- mutex_lock(&ar->mutex);
-
- if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
- /* TODO */
- err = 0;
- }
-
- if (changed & IEEE80211_CONF_CHANGE_PS) {
- /* TODO */
- err = 0;
- }
-
- if (changed & IEEE80211_CONF_CHANGE_POWER) {
- /* TODO */
- err = 0;
- }
-
- if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
- /*
- * is it long_frame_max_tx_count or short_frame_max_tx_count?
- */
-
- err = ar9170_set_hwretry_limit(ar,
- ar->hw->conf.long_frame_max_tx_count);
- if (err)
- goto out;
- }
-
- if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-
- /* adjust slot time for 5 GHz */
- err = ar9170_set_slot_time(ar);
- if (err)
- goto out;
-
- err = ar9170_set_dyn_sifs_ack(ar);
- if (err)
- goto out;
-
- err = ar9170_set_channel(ar, hw->conf.channel,
- AR9170_RFI_NONE,
- nl80211_to_ar9170(hw->conf.channel_type));
- if (err)
- goto out;
- }
-
-out:
- mutex_unlock(&ar->mutex);
- return err;
-}
-
-static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw,
- struct netdev_hw_addr_list *mc_list)
-{
- u64 mchash;
- struct netdev_hw_addr *ha;
-
- /* always get broadcast frames */
- mchash = 1ULL << (0xff >> 2);
-
- netdev_hw_addr_list_for_each(ha, mc_list)
- mchash |= 1ULL << (ha->addr[5] >> 2);
-
- return mchash;
-}
-
-static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *new_flags,
- u64 multicast)
-{
- struct ar9170 *ar = hw->priv;
-
- if (unlikely(!IS_ACCEPTING_CMD(ar)))
- return ;
-
- mutex_lock(&ar->mutex);
-
- /* mask supported flags */
- *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
- FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
- ar->filter_state = *new_flags;
- /*
- * We can support more by setting the sniffer bit and
- * then checking the error flags, later.
- */
-
- if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
- multicast = ~0ULL;
-
- if (multicast != ar->cur_mc_hash)
- ar9170_update_multicast(ar, multicast);
-
- if (changed_flags & FIF_CONTROL) {
- u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
- AR9170_MAC_REG_FTF_RTS |
- AR9170_MAC_REG_FTF_CTS |
- AR9170_MAC_REG_FTF_ACK |
- AR9170_MAC_REG_FTF_CFE |
- AR9170_MAC_REG_FTF_CFE_ACK;
-
- if (*new_flags & FIF_CONTROL)
- filter |= ar->cur_filter;
- else
- filter &= (~ar->cur_filter);
-
- ar9170_update_frame_filter(ar, filter);
- }
-
- if (changed_flags & FIF_PROMISC_IN_BSS) {
- ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
- ar9170_set_operating_mode(ar);
- }
-
- mutex_unlock(&ar->mutex);
-}
-
-
-static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changed)
-{
- struct ar9170 *ar = hw->priv;
- struct ath_common *common = &ar->common;
- int err = 0;
-
- mutex_lock(&ar->mutex);
-
- if (changed & BSS_CHANGED_BSSID) {
- memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
- err = ar9170_set_operating_mode(ar);
- if (err)
- goto out;
- }
-
- if (changed & BSS_CHANGED_BEACON_ENABLED)
- ar->enable_beacon = bss_conf->enable_beacon;
-
- if (changed & BSS_CHANGED_BEACON) {
- err = ar9170_update_beacon(ar);
- if (err)
- goto out;
- }
-
- if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON |
- BSS_CHANGED_BEACON_INT)) {
- err = ar9170_set_beacon_timers(ar);
- if (err)
- goto out;
- }
-
- if (changed & BSS_CHANGED_ASSOC) {
-#ifndef CONFIG_AR9170_LEDS
- /* enable assoc LED. */
- err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
-#endif /* CONFIG_AR9170_LEDS */
- }
-
- if (changed & BSS_CHANGED_HT) {
- /* TODO */
- err = 0;
- }
-
- if (changed & BSS_CHANGED_ERP_SLOT) {
- err = ar9170_set_slot_time(ar);
- if (err)
- goto out;
- }
-
- if (changed & BSS_CHANGED_BASIC_RATES) {
- err = ar9170_set_basic_rates(ar);
- if (err)
- goto out;
- }
-
-out:
- mutex_unlock(&ar->mutex);
-}
-
-static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
-{
- struct ar9170 *ar = hw->priv;
- int err;
- u64 tsf;
-#define NR 3
- static const u32 addr[NR] = { AR9170_MAC_REG_TSF_H,
- AR9170_MAC_REG_TSF_L,
- AR9170_MAC_REG_TSF_H };
- u32 val[NR];
- int loops = 0;
-
- mutex_lock(&ar->mutex);
-
- while (loops++ < 10) {
- err = ar9170_read_mreg(ar, NR, addr, val);
- if (err || val[0] == val[2])
- break;
- }
-
- mutex_unlock(&ar->mutex);
-
- if (WARN_ON(err))
- return 0;
- tsf = val[0];
- tsf = (tsf << 32) | val[1];
- return tsf;
-#undef NR
-}
-
-static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- struct ieee80211_vif *vif, struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key)
-{
- struct ar9170 *ar = hw->priv;
- int err = 0, i;
- u8 ktype;
-
- if ((!ar->vif) || (ar->disable_offload))
- return -EOPNOTSUPP;
-
- switch (key->cipher) {
- case WLAN_CIPHER_SUITE_WEP40:
- ktype = AR9170_ENC_ALG_WEP64;
- break;
- case WLAN_CIPHER_SUITE_WEP104:
- ktype = AR9170_ENC_ALG_WEP128;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- ktype = AR9170_ENC_ALG_TKIP;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- ktype = AR9170_ENC_ALG_AESCCMP;
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- mutex_lock(&ar->mutex);
- if (cmd == SET_KEY) {
- if (unlikely(!IS_STARTED(ar))) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- /* group keys need all-zeroes address */
- if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
- sta = NULL;
-
- if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
- for (i = 0; i < 64; i++)
- if (!(ar->usedkeys & BIT(i)))
- break;
- if (i == 64) {
- ar->rx_software_decryption = true;
- ar9170_set_operating_mode(ar);
- err = -ENOSPC;
- goto out;
- }
- } else {
- i = 64 + key->keyidx;
- }
-
- key->hw_key_idx = i;
-
- err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
- key->key, min_t(u8, 16, key->keylen));
- if (err)
- goto out;
-
- if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
- err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
- ktype, 1, key->key + 16, 16);
- if (err)
- goto out;
-
- /*
- * hardware is not capable generating the MMIC
- * for fragmented frames!
- */
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
- }
-
- if (i < 64)
- ar->usedkeys |= BIT(i);
-
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- } else {
- if (unlikely(!IS_STARTED(ar))) {
- /* The device is gone... together with the key ;-) */
- err = 0;
- goto out;
- }
-
- err = ar9170_disable_key(ar, key->hw_key_idx);
- if (err)
- goto out;
-
- if (key->hw_key_idx < 64) {
- ar->usedkeys &= ~BIT(key->hw_key_idx);
- } else {
- err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
- AR9170_ENC_ALG_NONE, 0,
- NULL, 0);
- if (err)
- goto out;
-
- if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
- err = ar9170_upload_key(ar, key->hw_key_idx,
- NULL,
- AR9170_ENC_ALG_NONE, 1,
- NULL, 0);
- if (err)
- goto out;
- }
-
- }
- }
-
- ar9170_regwrite_begin(ar);
- ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
- ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
- ar9170_regwrite_finish();
- err = ar9170_regwrite_result();
-
-out:
- mutex_unlock(&ar->mutex);
-
- return err;
-}
-
-static int ar9170_get_stats(struct ieee80211_hw *hw,
- struct ieee80211_low_level_stats *stats)
-{
- struct ar9170 *ar = hw->priv;
- u32 val;
- int err;
-
- mutex_lock(&ar->mutex);
- err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
- ar->stats.dot11ACKFailureCount += val;
-
- memcpy(stats, &ar->stats, sizeof(*stats));
- mutex_unlock(&ar->mutex);
-
- return 0;
-}
-
-static int ar9170_get_survey(struct ieee80211_hw *hw, int idx,
- struct survey_info *survey)
-{
- struct ar9170 *ar = hw->priv;
- struct ieee80211_conf *conf = &hw->conf;
-
- if (idx != 0)
- return -ENOENT;
-
- /* TODO: update noise value, e.g. call ar9170_set_channel */
-
- survey->channel = conf->channel;
- survey->filled = SURVEY_INFO_NOISE_DBM;
- survey->noise = ar->noise[0];
-
- return 0;
-}
-
-static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
- const struct ieee80211_tx_queue_params *param)
-{
- struct ar9170 *ar = hw->priv;
- int ret;
-
- mutex_lock(&ar->mutex);
- if (queue < __AR9170_NUM_TXQ) {
- memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
- param, sizeof(*param));
-
- ret = ar9170_set_qos(ar);
- } else {
- ret = -EINVAL;
- }
-
- mutex_unlock(&ar->mutex);
- return ret;
-}
-
-static int ar9170_ampdu_action(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- enum ieee80211_ampdu_mlme_action action,
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
- u8 buf_size)
-{
- switch (action) {
- case IEEE80211_AMPDU_RX_START:
- case IEEE80211_AMPDU_RX_STOP:
- /* Handled by firmware */
- break;
-
- default:
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
-
-static const struct ieee80211_ops ar9170_ops = {
- .start = ar9170_op_start,
- .stop = ar9170_op_stop,
- .tx = ar9170_op_tx,
- .add_interface = ar9170_op_add_interface,
- .remove_interface = ar9170_op_remove_interface,
- .config = ar9170_op_config,
- .prepare_multicast = ar9170_op_prepare_multicast,
- .configure_filter = ar9170_op_configure_filter,
- .conf_tx = ar9170_conf_tx,
- .bss_info_changed = ar9170_op_bss_info_changed,
- .get_tsf = ar9170_op_get_tsf,
- .set_key = ar9170_set_key,
- .get_stats = ar9170_get_stats,
- .get_survey = ar9170_get_survey,
- .ampdu_action = ar9170_ampdu_action,
-};
-
-void *ar9170_alloc(size_t priv_size)
-{
- struct ieee80211_hw *hw;
- struct ar9170 *ar;
- struct sk_buff *skb;
- int i;
-
- /*
- * this buffer is used for rx stream reconstruction.
- * Under heavy load this device (or the transport layer?)
- * tends to split the streams into separate rx descriptors.
- */
-
- skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL);
- if (!skb)
- goto err_nomem;
-
- hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
- if (!hw)
- goto err_nomem;
-
- ar = hw->priv;
- ar->hw = hw;
- ar->rx_failover = skb;
-
- mutex_init(&ar->mutex);
- spin_lock_init(&ar->cmdlock);
- spin_lock_init(&ar->tx_stats_lock);
- for (i = 0; i < __AR9170_NUM_TXQ; i++) {
- skb_queue_head_init(&ar->tx_status[i]);
- skb_queue_head_init(&ar->tx_pending[i]);
- }
- ar9170_rx_reset_rx_mpdu(ar);
- INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
- INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
-
- /* all hw supports 2.4 GHz, so set channel to 1 by default */
- ar->channel = &ar9170_2ghz_chantable[0];
-
- /* first part of wiphy init */
- ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_WDS) |
- BIT(NL80211_IFTYPE_ADHOC);
- ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_SIGNAL_DBM;
-
- ar->hw->queues = __AR9170_NUM_TXQ;
- ar->hw->extra_tx_headroom = 8;
-
- ar->hw->max_rates = 1;
- ar->hw->max_rate_tries = 3;
-
- for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
- ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
-
- return ar;
-
-err_nomem:
- kfree_skb(skb);
- return ERR_PTR(-ENOMEM);
-}
-
-static int ar9170_read_eeprom(struct ar9170 *ar)
-{
-#define RW 8 /* number of words to read at once */
-#define RB (sizeof(u32) * RW)
- struct ath_regulatory *regulatory = &ar->common.regulatory;
- u8 *eeprom = (void *)&ar->eeprom;
- u8 *addr = ar->eeprom.mac_address;
- __le32 offsets[RW];
- unsigned int rx_streams, tx_streams, tx_params = 0;
- int i, j, err, bands = 0;
-
- BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
-
- BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
-#ifndef __CHECKER__
- /* don't want to handle trailing remains */
- BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
-#endif
-
- for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
- for (j = 0; j < RW; j++)
- offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
- RB * i + 4 * j);
-
- err = ar->exec_cmd(ar, AR9170_CMD_RREG,
- RB, (u8 *) &offsets,
- RB, eeprom + RB * i);
- if (err)
- return err;
- }
-
-#undef RW
-#undef RB
-
- if (ar->eeprom.length == cpu_to_le16(0xFFFF))
- return -ENODATA;
-
- if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
- ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
- bands++;
- }
- if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
- ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
- bands++;
- }
-
- rx_streams = hweight8(ar->eeprom.rx_mask);
- tx_streams = hweight8(ar->eeprom.tx_mask);
-
- if (rx_streams != tx_streams)
- tx_params = IEEE80211_HT_MCS_TX_RX_DIFF;
-
- if (tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS)
- tx_params = (tx_streams - 1) <<
- IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
-
- ar9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params;
- ar9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params;
-
- /*
- * I measured this, a bandswitch takes roughly
- * 135 ms and a frequency switch about 80.
- *
- * FIXME: measure these values again once EEPROM settings
- * are used, that will influence them!
- */
- if (bands == 2)
- ar->hw->channel_change_time = 135 * 1000;
- else
- ar->hw->channel_change_time = 80 * 1000;
-
- regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
- regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
-
- /* second part of wiphy init */
- SET_IEEE80211_PERM_ADDR(ar->hw, addr);
-
- return bands ? 0 : -EINVAL;
-}
-
-static int ar9170_reg_notifier(struct wiphy *wiphy,
- struct regulatory_request *request)
-{
- struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
- struct ar9170 *ar = hw->priv;
-
- return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory);
-}
-
-int ar9170_register(struct ar9170 *ar, struct device *pdev)
-{
- struct ath_regulatory *regulatory = &ar->common.regulatory;
- int err;
-
- /* try to read EEPROM, init MAC addr */
- err = ar9170_read_eeprom(ar);
- if (err)
- goto err_out;
-
- err = ath_regd_init(regulatory, ar->hw->wiphy,
- ar9170_reg_notifier);
- if (err)
- goto err_out;
-
- err = ieee80211_register_hw(ar->hw);
- if (err)
- goto err_out;
-
- if (!ath_is_world_regd(regulatory))
- regulatory_hint(ar->hw->wiphy, regulatory->alpha2);
-
- err = ar9170_init_leds(ar);
- if (err)
- goto err_unreg;
-
-#ifdef CONFIG_AR9170_LEDS
- err = ar9170_register_leds(ar);
- if (err)
- goto err_unreg;
-#endif /* CONFIG_AR9170_LEDS */
-
- dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
- wiphy_name(ar->hw->wiphy));
-
- ar->registered = true;
- return 0;
-
-err_unreg:
- ieee80211_unregister_hw(ar->hw);
-
-err_out:
- return err;
-}
-
-void ar9170_unregister(struct ar9170 *ar)
-{
- if (ar->registered) {
-#ifdef CONFIG_AR9170_LEDS
- ar9170_unregister_leds(ar);
-#endif /* CONFIG_AR9170_LEDS */
-
- ieee80211_unregister_hw(ar->hw);
- }
-
- kfree_skb(ar->rx_failover);
- mutex_destroy(&ar->mutex);
-}
diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c
deleted file mode 100644
index aa8d06ba1ee..00000000000
--- a/drivers/net/wireless/ath/ar9170/phy.c
+++ /dev/null
@@ -1,1719 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * PHY and RF code
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- * Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/bitrev.h>
-#include "ar9170.h"
-#include "cmd.h"
-
-static int ar9170_init_power_cal(struct ar9170 *ar)
-{
- ar9170_regwrite_begin(ar);
-
- ar9170_regwrite(0x1bc000 + 0x993c, 0x7f);
- ar9170_regwrite(0x1bc000 + 0x9934, 0x3f3f3f3f);
- ar9170_regwrite(0x1bc000 + 0x9938, 0x3f3f3f3f);
- ar9170_regwrite(0x1bc000 + 0xa234, 0x3f3f3f3f);
- ar9170_regwrite(0x1bc000 + 0xa238, 0x3f3f3f3f);
- ar9170_regwrite(0x1bc000 + 0xa38c, 0x3f3f3f3f);
- ar9170_regwrite(0x1bc000 + 0xa390, 0x3f3f3f3f);
- ar9170_regwrite(0x1bc000 + 0xa3cc, 0x3f3f3f3f);
- ar9170_regwrite(0x1bc000 + 0xa3d0, 0x3f3f3f3f);
- ar9170_regwrite(0x1bc000 + 0xa3d4, 0x3f3f3f3f);
-
- ar9170_regwrite_finish();
- return ar9170_regwrite_result();
-}
-
-struct ar9170_phy_init {
- u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20;
-};
-
-static struct ar9170_phy_init ar5416_phy_init[] = {
- { 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
- { 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, },
- { 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, },
- { 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, },
- { 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, },
- { 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, },
- { 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, },
- { 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
- { 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, },
- { 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
- { 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
- { 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
- { 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, },
- { 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, },
- { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, },
- { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, },
- { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, },
- { 0x1c5850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, },
- { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, },
- { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, },
- { 0x1c585c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, },
- { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, },
- { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, },
- { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, },
- { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, },
- { 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, },
- { 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, },
- { 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, },
- { 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, },
- { 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
- { 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
- { 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
- { 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
- { 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, },
- { 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, },
- { 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, },
- { 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, },
- { 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, },
- { 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, },
- { 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
- { 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, },
- { 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, },
- { 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
- { 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
- { 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, },
- { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, },
- { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, },
- { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, },
- { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, },
- { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, },
- { 0x1c59c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, },
- { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, },
- { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, },
- { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, },
- { 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, },
- { 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, },
- { 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, },
- { 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, },
- { 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, },
- { 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, },
- { 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, },
- { 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, },
- { 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, },
- { 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, },
- { 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, },
- { 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, },
- { 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, },
- { 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
- { 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, },
- { 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, },
- { 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, },
- { 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, },
- { 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, },
- { 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, },
- { 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, },
- { 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, },
- { 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, },
- { 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, },
- { 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, },
- { 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, },
- { 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, },
- { 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, },
- { 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, },
- { 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, },
- { 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, },
- { 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, },
- { 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, },
- { 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, },
- { 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, },
- { 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, },
- { 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, },
- { 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, },
- { 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, },
- { 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, },
- { 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, },
- { 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, },
- { 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, },
- { 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
- { 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
- { 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, },
- { 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, },
- { 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
- { 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, },
- { 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, },
- { 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, },
- { 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, },
- { 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, },
- { 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, },
- { 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, },
- { 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
- { 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, },
- { 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, },
- { 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, },
- { 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, },
- { 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, },
- { 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, },
- { 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, },
- { 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
- { 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, },
- { 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, },
- { 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, },
- { 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, },
- { 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, },
- { 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, },
- { 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, },
- { 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, },
- { 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, },
- { 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
- { 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, },
- { 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, },
- { 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, },
- { 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, },
- { 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, },
- { 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, },
- { 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, },
- { 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, },
- { 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, },
- { 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, },
- { 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
- { 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
- { 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
- { 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, },
- { 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, },
- { 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, },
- { 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
- { 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, },
- { 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, },
- { 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, },
- { 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, },
- { 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, },
- { 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, },
- { 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, },
- { 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, },
- { 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
- { 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
- { 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, },
- { 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, },
- { 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, },
- { 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, },
- { 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
- { 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
- { 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, },
- { 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, },
- { 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, },
- { 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, },
- { 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
- { 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, },
- { 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
- { 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, },
- { 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, },
- { 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, },
- { 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, },
- { 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, },
- { 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, },
- { 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, },
- { 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, },
- { 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, },
- { 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, },
- { 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, },
- { 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, },
- { 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
- { 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
- { 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
- { 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, },
- { 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, },
- { 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, },
- { 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
- { 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
- { 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
- { 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, },
- { 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
- { 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
- { 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
- { 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
- { 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
- { 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
- { 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, },
- { 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
- { 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
- { 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
- { 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
- { 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
- { 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
- { 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
- { 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
- { 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
- { 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
-/* { 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */
- { 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, },
- { 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, },
- { 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, },
- { 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, },
- { 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, },
- { 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, },
- { 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, },
- { 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, },
- { 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, },
- { 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, },
- { 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, },
- { 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, },
- { 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, },
- { 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, },
- { 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, },
- { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, }
-};
-
-/*
- * look up a certain register in ar5416_phy_init[] and return the init. value
- * for the band and bandwidth given. Return 0 if register address not found.
- */
-static u32 ar9170_get_default_phy_reg_val(u32 reg, bool is_2ghz, bool is_40mhz)
-{
- unsigned int i;
- for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
- if (ar5416_phy_init[i].reg != reg)
- continue;
-
- if (is_2ghz) {
- if (is_40mhz)
- return ar5416_phy_init[i]._2ghz_40;
- else
- return ar5416_phy_init[i]._2ghz_20;
- } else {
- if (is_40mhz)
- return ar5416_phy_init[i]._5ghz_40;
- else
- return ar5416_phy_init[i]._5ghz_20;
- }
- }
- return 0;
-}
-
-/*
- * initialize some phy regs from eeprom values in modal_header[]
- * acc. to band and bandwidth
- */
-static int ar9170_init_phy_from_eeprom(struct ar9170 *ar,
- bool is_2ghz, bool is_40mhz)
-{
- static const u8 xpd2pd[16] = {
- 0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x6, 0x2,
- 0x2, 0x3, 0x7, 0x2, 0xB, 0x2, 0x2, 0x2
- };
- u32 defval, newval;
- /* pointer to the modal_header acc. to band */
- struct ar9170_eeprom_modal *m = &ar->eeprom.modal_header[is_2ghz];
-
- ar9170_regwrite_begin(ar);
-
- /* ant common control (index 0) */
- newval = le32_to_cpu(m->antCtrlCommon);
- ar9170_regwrite(0x1c5964, newval);
-
- /* ant control chain 0 (index 1) */
- newval = le32_to_cpu(m->antCtrlChain[0]);
- ar9170_regwrite(0x1c5960, newval);
-
- /* ant control chain 2 (index 2) */
- newval = le32_to_cpu(m->antCtrlChain[1]);
- ar9170_regwrite(0x1c7960, newval);
-
- /* SwSettle (index 3) */
- if (!is_40mhz) {
- defval = ar9170_get_default_phy_reg_val(0x1c5844,
- is_2ghz, is_40mhz);
- newval = (defval & ~0x3f80) |
- ((m->switchSettling & 0x7f) << 7);
- ar9170_regwrite(0x1c5844, newval);
- }
-
- /* adcDesired, pdaDesired (index 4) */
- defval = ar9170_get_default_phy_reg_val(0x1c5850, is_2ghz, is_40mhz);
- newval = (defval & ~0xffff) | ((u8)m->pgaDesiredSize << 8) |
- ((u8)m->adcDesiredSize);
- ar9170_regwrite(0x1c5850, newval);
-
- /* TxEndToXpaOff, TxFrameToXpaOn (index 5) */
- defval = ar9170_get_default_phy_reg_val(0x1c5834, is_2ghz, is_40mhz);
- newval = (m->txEndToXpaOff << 24) | (m->txEndToXpaOff << 16) |
- (m->txFrameToXpaOn << 8) | m->txFrameToXpaOn;
- ar9170_regwrite(0x1c5834, newval);
-
- /* TxEndToRxOn (index 6) */
- defval = ar9170_get_default_phy_reg_val(0x1c5828, is_2ghz, is_40mhz);
- newval = (defval & ~0xff0000) | (m->txEndToRxOn << 16);
- ar9170_regwrite(0x1c5828, newval);
-
- /* thresh62 (index 7) */
- defval = ar9170_get_default_phy_reg_val(0x1c8864, is_2ghz, is_40mhz);
- newval = (defval & ~0x7f000) | (m->thresh62 << 12);
- ar9170_regwrite(0x1c8864, newval);
-
- /* tx/rx attenuation chain 0 (index 8) */
- defval = ar9170_get_default_phy_reg_val(0x1c5848, is_2ghz, is_40mhz);
- newval = (defval & ~0x3f000) | ((m->txRxAttenCh[0] & 0x3f) << 12);
- ar9170_regwrite(0x1c5848, newval);
-
- /* tx/rx attenuation chain 2 (index 9) */
- defval = ar9170_get_default_phy_reg_val(0x1c7848, is_2ghz, is_40mhz);
- newval = (defval & ~0x3f000) | ((m->txRxAttenCh[1] & 0x3f) << 12);
- ar9170_regwrite(0x1c7848, newval);
-
- /* tx/rx margin chain 0 (index 10) */
- defval = ar9170_get_default_phy_reg_val(0x1c620c, is_2ghz, is_40mhz);
- newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[0] & 0x3f) << 18);
- /* bsw margin chain 0 for 5GHz only */
- if (!is_2ghz)
- newval = (newval & ~0x3c00) | ((m->bswMargin[0] & 0xf) << 10);
- ar9170_regwrite(0x1c620c, newval);
-
- /* tx/rx margin chain 2 (index 11) */
- defval = ar9170_get_default_phy_reg_val(0x1c820c, is_2ghz, is_40mhz);
- newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[1] & 0x3f) << 18);
- ar9170_regwrite(0x1c820c, newval);
-
- /* iqCall, iqCallq chain 0 (index 12) */
- defval = ar9170_get_default_phy_reg_val(0x1c5920, is_2ghz, is_40mhz);
- newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[0] & 0x3f) << 5) |
- ((u8)m->iqCalQCh[0] & 0x1f);
- ar9170_regwrite(0x1c5920, newval);
-
- /* iqCall, iqCallq chain 2 (index 13) */
- defval = ar9170_get_default_phy_reg_val(0x1c7920, is_2ghz, is_40mhz);
- newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[1] & 0x3f) << 5) |
- ((u8)m->iqCalQCh[1] & 0x1f);
- ar9170_regwrite(0x1c7920, newval);
-
- /* xpd gain mask (index 14) */
- defval = ar9170_get_default_phy_reg_val(0x1c6258, is_2ghz, is_40mhz);
- newval = (defval & ~0xf0000) | (xpd2pd[m->xpdGain & 0xf] << 16);
- ar9170_regwrite(0x1c6258, newval);
- ar9170_regwrite_finish();
-
- return ar9170_regwrite_result();
-}
-
-int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
-{
- int i, err;
- u32 val;
- bool is_2ghz = band == IEEE80211_BAND_2GHZ;
- bool is_40mhz = conf_is_ht40(&ar->hw->conf);
-
- ar9170_regwrite_begin(ar);
-
- for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
- if (is_40mhz) {
- if (is_2ghz)
- val = ar5416_phy_init[i]._2ghz_40;
- else
- val = ar5416_phy_init[i]._5ghz_40;
- } else {
- if (is_2ghz)
- val = ar5416_phy_init[i]._2ghz_20;
- else
- val = ar5416_phy_init[i]._5ghz_20;
- }
-
- ar9170_regwrite(ar5416_phy_init[i].reg, val);
- }
-
- ar9170_regwrite_finish();
- err = ar9170_regwrite_result();
- if (err)
- return err;
-
- err = ar9170_init_phy_from_eeprom(ar, is_2ghz, is_40mhz);
- if (err)
- return err;
-
- err = ar9170_init_power_cal(ar);
- if (err)
- return err;
-
- /* XXX: remove magic! */
- if (is_2ghz)
- err = ar9170_write_reg(ar, 0x1d4014, 0x5163);
- else
- err = ar9170_write_reg(ar, 0x1d4014, 0x5143);
-
- return err;
-}
-
-struct ar9170_rf_init {
- u32 reg, _5ghz, _2ghz;
-};
-
-static struct ar9170_rf_init ar9170_rf_init[] = {
- /* bank 0 */
- { 0x1c58b0, 0x1e5795e5, 0x1e5795e5},
- { 0x1c58e0, 0x02008020, 0x02008020},
- /* bank 1 */
- { 0x1c58b0, 0x02108421, 0x02108421},
- { 0x1c58ec, 0x00000008, 0x00000008},
- /* bank 2 */
- { 0x1c58b0, 0x0e73ff17, 0x0e73ff17},
- { 0x1c58e0, 0x00000420, 0x00000420},
- /* bank 3 */
- { 0x1c58f0, 0x01400018, 0x01c00018},
- /* bank 4 */
- { 0x1c58b0, 0x000001a1, 0x000001a1},
- { 0x1c58e8, 0x00000001, 0x00000001},
- /* bank 5 */
- { 0x1c58b0, 0x00000013, 0x00000013},
- { 0x1c58e4, 0x00000002, 0x00000002},
- /* bank 6 */
- { 0x1c58b0, 0x00000000, 0x00000000},
- { 0x1c58b0, 0x00000000, 0x00000000},
- { 0x1c58b0, 0x00000000, 0x00000000},
- { 0x1c58b0, 0x00000000, 0x00000000},
- { 0x1c58b0, 0x00000000, 0x00000000},
- { 0x1c58b0, 0x00004000, 0x00004000},
- { 0x1c58b0, 0x00006c00, 0x00006c00},
- { 0x1c58b0, 0x00002c00, 0x00002c00},
- { 0x1c58b0, 0x00004800, 0x00004800},
- { 0x1c58b0, 0x00004000, 0x00004000},
- { 0x1c58b0, 0x00006000, 0x00006000},
- { 0x1c58b0, 0x00001000, 0x00001000},
- { 0x1c58b0, 0x00004000, 0x00004000},
- { 0x1c58b0, 0x00007c00, 0x00007c00},
- { 0x1c58b0, 0x00007c00, 0x00007c00},
- { 0x1c58b0, 0x00007c00, 0x00007c00},
- { 0x1c58b0, 0x00007c00, 0x00007c00},
- { 0x1c58b0, 0x00007c00, 0x00007c00},
- { 0x1c58b0, 0x00087c00, 0x00087c00},
- { 0x1c58b0, 0x00007c00, 0x00007c00},
- { 0x1c58b0, 0x00005400, 0x00005400},
- { 0x1c58b0, 0x00000c00, 0x00000c00},
- { 0x1c58b0, 0x00001800, 0x00001800},
- { 0x1c58b0, 0x00007c00, 0x00007c00},
- { 0x1c58b0, 0x00006c00, 0x00006c00},
- { 0x1c58b0, 0x00006c00, 0x00006c00},
- { 0x1c58b0, 0x00007c00, 0x00007c00},
- { 0x1c58b0, 0x00002c00, 0x00002c00},
- { 0x1c58b0, 0x00003c00, 0x00003c00},
- { 0x1c58b0, 0x00003800, 0x00003800},
- { 0x1c58b0, 0x00001c00, 0x00001c00},
- { 0x1c58b0, 0x00000800, 0x00000800},
- { 0x1c58b0, 0x00000408, 0x00000408},
- { 0x1c58b0, 0x00004c15, 0x00004c15},
- { 0x1c58b0, 0x00004188, 0x00004188},
- { 0x1c58b0, 0x0000201e, 0x0000201e},
- { 0x1c58b0, 0x00010408, 0x00010408},
- { 0x1c58b0, 0x00000801, 0x00000801},
- { 0x1c58b0, 0x00000c08, 0x00000c08},
- { 0x1c58b0, 0x0000181e, 0x0000181e},
- { 0x1c58b0, 0x00001016, 0x00001016},
- { 0x1c58b0, 0x00002800, 0x00002800},
- { 0x1c58b0, 0x00004010, 0x00004010},
- { 0x1c58b0, 0x0000081c, 0x0000081c},
- { 0x1c58b0, 0x00000115, 0x00000115},
- { 0x1c58b0, 0x00000015, 0x00000015},
- { 0x1c58b0, 0x00000066, 0x00000066},
- { 0x1c58b0, 0x0000001c, 0x0000001c},
- { 0x1c58b0, 0x00000000, 0x00000000},
- { 0x1c58b0, 0x00000004, 0x00000004},
- { 0x1c58b0, 0x00000015, 0x00000015},
- { 0x1c58b0, 0x0000001f, 0x0000001f},
- { 0x1c58e0, 0x00000000, 0x00000400},
- /* bank 7 */
- { 0x1c58b0, 0x000000a0, 0x000000a0},
- { 0x1c58b0, 0x00000000, 0x00000000},
- { 0x1c58b0, 0x00000040, 0x00000040},
- { 0x1c58f0, 0x0000001c, 0x0000001c},
-};
-
-static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz)
-{
- int err, i;
-
- ar9170_regwrite_begin(ar);
-
- for (i = 0; i < ARRAY_SIZE(ar9170_rf_init); i++)
- ar9170_regwrite(ar9170_rf_init[i].reg,
- band5ghz ? ar9170_rf_init[i]._5ghz
- : ar9170_rf_init[i]._2ghz);
-
- ar9170_regwrite_finish();
- err = ar9170_regwrite_result();
- if (err)
- wiphy_err(ar->hw->wiphy, "rf init failed\n");
- return err;
-}
-
-static int ar9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
- u32 freq, enum ar9170_bw bw)
-{
- int err;
- u32 d0, d1, td0, td1, fd0, fd1;
- u8 chansel;
- u8 refsel0 = 1, refsel1 = 0;
- u8 lf_synth = 0;
-
- switch (bw) {
- case AR9170_BW_40_ABOVE:
- freq += 10;
- break;
- case AR9170_BW_40_BELOW:
- freq -= 10;
- break;
- case AR9170_BW_20:
- break;
- case __AR9170_NUM_BW:
- BUG();
- }
-
- if (band5ghz) {
- if (freq % 10) {
- chansel = (freq - 4800) / 5;
- } else {
- chansel = ((freq - 4800) / 10) * 2;
- refsel0 = 0;
- refsel1 = 1;
- }
- chansel = byte_rev_table[chansel];
- } else {
- if (freq == 2484) {
- chansel = 10 + (freq - 2274) / 5;
- lf_synth = 1;
- } else
- chansel = 16 + (freq - 2272) / 5;
- chansel *= 4;
- chansel = byte_rev_table[chansel];
- }
-
- d1 = chansel;
- d0 = 0x21 |
- refsel0 << 3 |
- refsel1 << 2 |
- lf_synth << 1;
- td0 = d0 & 0x1f;
- td1 = d1 & 0x1f;
- fd0 = td1 << 5 | td0;
-
- td0 = (d0 >> 5) & 0x7;
- td1 = (d1 >> 5) & 0x7;
- fd1 = td1 << 5 | td0;
-
- ar9170_regwrite_begin(ar);
-
- ar9170_regwrite(0x1c58b0, fd0);
- ar9170_regwrite(0x1c58e8, fd1);
-
- ar9170_regwrite_finish();
- err = ar9170_regwrite_result();
- if (err)
- return err;
-
- msleep(10);
-
- return 0;
-}
-
-struct ar9170_phy_freq_params {
- u8 coeff_exp;
- u16 coeff_man;
- u8 coeff_exp_shgi;
- u16 coeff_man_shgi;
-};
-
-struct ar9170_phy_freq_entry {
- u16 freq;
- struct ar9170_phy_freq_params params[__AR9170_NUM_BW];
-};
-
-/* NB: must be in sync with channel tables in main! */
-static const struct ar9170_phy_freq_entry ar9170_phy_freq_params[] = {
-/*
- * freq,
- * 20MHz,
- * 40MHz (below),
- * 40Mhz (above),
- */
- { 2412, {
- { 3, 21737, 3, 19563, },
- { 3, 21827, 3, 19644, },
- { 3, 21647, 3, 19482, },
- } },
- { 2417, {
- { 3, 21692, 3, 19523, },
- { 3, 21782, 3, 19604, },
- { 3, 21602, 3, 19442, },
- } },
- { 2422, {
- { 3, 21647, 3, 19482, },
- { 3, 21737, 3, 19563, },
- { 3, 21558, 3, 19402, },
- } },
- { 2427, {
- { 3, 21602, 3, 19442, },
- { 3, 21692, 3, 19523, },
- { 3, 21514, 3, 19362, },
- } },
- { 2432, {
- { 3, 21558, 3, 19402, },
- { 3, 21647, 3, 19482, },
- { 3, 21470, 3, 19323, },
- } },
- { 2437, {
- { 3, 21514, 3, 19362, },
- { 3, 21602, 3, 19442, },
- { 3, 21426, 3, 19283, },
- } },
- { 2442, {
- { 3, 21470, 3, 19323, },
- { 3, 21558, 3, 19402, },
- { 3, 21382, 3, 19244, },
- } },
- { 2447, {
- { 3, 21426, 3, 19283, },
- { 3, 21514, 3, 19362, },
- { 3, 21339, 3, 19205, },
- } },
- { 2452, {
- { 3, 21382, 3, 19244, },
- { 3, 21470, 3, 19323, },
- { 3, 21295, 3, 19166, },
- } },
- { 2457, {
- { 3, 21339, 3, 19205, },
- { 3, 21426, 3, 19283, },
- { 3, 21252, 3, 19127, },
- } },
- { 2462, {
- { 3, 21295, 3, 19166, },
- { 3, 21382, 3, 19244, },
- { 3, 21209, 3, 19088, },
- } },
- { 2467, {
- { 3, 21252, 3, 19127, },
- { 3, 21339, 3, 19205, },
- { 3, 21166, 3, 19050, },
- } },
- { 2472, {
- { 3, 21209, 3, 19088, },
- { 3, 21295, 3, 19166, },
- { 3, 21124, 3, 19011, },
- } },
- { 2484, {
- { 3, 21107, 3, 18996, },
- { 3, 21192, 3, 19073, },
- { 3, 21022, 3, 18920, },
- } },
- { 4920, {
- { 4, 21313, 4, 19181, },
- { 4, 21356, 4, 19220, },
- { 4, 21269, 4, 19142, },
- } },
- { 4940, {
- { 4, 21226, 4, 19104, },
- { 4, 21269, 4, 19142, },
- { 4, 21183, 4, 19065, },
- } },
- { 4960, {
- { 4, 21141, 4, 19027, },
- { 4, 21183, 4, 19065, },
- { 4, 21098, 4, 18988, },
- } },
- { 4980, {
- { 4, 21056, 4, 18950, },
- { 4, 21098, 4, 18988, },
- { 4, 21014, 4, 18912, },
- } },
- { 5040, {
- { 4, 20805, 4, 18725, },
- { 4, 20846, 4, 18762, },
- { 4, 20764, 4, 18687, },
- } },
- { 5060, {
- { 4, 20723, 4, 18651, },
- { 4, 20764, 4, 18687, },
- { 4, 20682, 4, 18614, },
- } },
- { 5080, {
- { 4, 20641, 4, 18577, },
- { 4, 20682, 4, 18614, },
- { 4, 20601, 4, 18541, },
- } },
- { 5180, {
- { 4, 20243, 4, 18219, },
- { 4, 20282, 4, 18254, },
- { 4, 20204, 4, 18183, },
- } },
- { 5200, {
- { 4, 20165, 4, 18148, },
- { 4, 20204, 4, 18183, },
- { 4, 20126, 4, 18114, },
- } },
- { 5220, {
- { 4, 20088, 4, 18079, },
- { 4, 20126, 4, 18114, },
- { 4, 20049, 4, 18044, },
- } },
- { 5240, {
- { 4, 20011, 4, 18010, },
- { 4, 20049, 4, 18044, },
- { 4, 19973, 4, 17976, },
- } },
- { 5260, {
- { 4, 19935, 4, 17941, },
- { 4, 19973, 4, 17976, },
- { 4, 19897, 4, 17907, },
- } },
- { 5280, {
- { 4, 19859, 4, 17873, },
- { 4, 19897, 4, 17907, },
- { 4, 19822, 4, 17840, },
- } },
- { 5300, {
- { 4, 19784, 4, 17806, },
- { 4, 19822, 4, 17840, },
- { 4, 19747, 4, 17772, },
- } },
- { 5320, {
- { 4, 19710, 4, 17739, },
- { 4, 19747, 4, 17772, },
- { 4, 19673, 4, 17706, },
- } },
- { 5500, {
- { 4, 19065, 4, 17159, },
- { 4, 19100, 4, 17190, },
- { 4, 19030, 4, 17127, },
- } },
- { 5520, {
- { 4, 18996, 4, 17096, },
- { 4, 19030, 4, 17127, },
- { 4, 18962, 4, 17065, },
- } },
- { 5540, {
- { 4, 18927, 4, 17035, },
- { 4, 18962, 4, 17065, },
- { 4, 18893, 4, 17004, },
- } },
- { 5560, {
- { 4, 18859, 4, 16973, },
- { 4, 18893, 4, 17004, },
- { 4, 18825, 4, 16943, },
- } },
- { 5580, {
- { 4, 18792, 4, 16913, },
- { 4, 18825, 4, 16943, },
- { 4, 18758, 4, 16882, },
- } },
- { 5600, {
- { 4, 18725, 4, 16852, },
- { 4, 18758, 4, 16882, },
- { 4, 18691, 4, 16822, },
- } },
- { 5620, {
- { 4, 18658, 4, 16792, },
- { 4, 18691, 4, 16822, },
- { 4, 18625, 4, 16762, },
- } },
- { 5640, {
- { 4, 18592, 4, 16733, },
- { 4, 18625, 4, 16762, },
- { 4, 18559, 4, 16703, },
- } },
- { 5660, {
- { 4, 18526, 4, 16673, },
- { 4, 18559, 4, 16703, },
- { 4, 18493, 4, 16644, },
- } },
- { 5680, {
- { 4, 18461, 4, 16615, },
- { 4, 18493, 4, 16644, },
- { 4, 18428, 4, 16586, },
- } },
- { 5700, {
- { 4, 18396, 4, 16556, },
- { 4, 18428, 4, 16586, },
- { 4, 18364, 4, 16527, },
- } },
- { 5745, {
- { 4, 18252, 4, 16427, },
- { 4, 18284, 4, 16455, },
- { 4, 18220, 4, 16398, },
- } },
- { 5765, {
- { 4, 18189, 5, 32740, },
- { 4, 18220, 4, 16398, },
- { 4, 18157, 5, 32683, },
- } },
- { 5785, {
- { 4, 18126, 5, 32626, },
- { 4, 18157, 5, 32683, },
- { 4, 18094, 5, 32570, },
- } },
- { 5805, {
- { 4, 18063, 5, 32514, },
- { 4, 18094, 5, 32570, },
- { 4, 18032, 5, 32458, },
- } },
- { 5825, {
- { 4, 18001, 5, 32402, },
- { 4, 18032, 5, 32458, },
- { 4, 17970, 5, 32347, },
- } },
- { 5170, {
- { 4, 20282, 4, 18254, },
- { 4, 20321, 4, 18289, },
- { 4, 20243, 4, 18219, },
- } },
- { 5190, {
- { 4, 20204, 4, 18183, },
- { 4, 20243, 4, 18219, },
- { 4, 20165, 4, 18148, },
- } },
- { 5210, {
- { 4, 20126, 4, 18114, },
- { 4, 20165, 4, 18148, },
- { 4, 20088, 4, 18079, },
- } },
- { 5230, {
- { 4, 20049, 4, 18044, },
- { 4, 20088, 4, 18079, },
- { 4, 20011, 4, 18010, },
- } },
-};
-
-static const struct ar9170_phy_freq_params *
-ar9170_get_hw_dyn_params(struct ieee80211_channel *channel,
- enum ar9170_bw bw)
-{
- unsigned int chanidx = 0;
- u16 freq = 2412;
-
- if (channel) {
- chanidx = channel->hw_value;
- freq = channel->center_freq;
- }
-
- BUG_ON(chanidx >= ARRAY_SIZE(ar9170_phy_freq_params));
-
- BUILD_BUG_ON(__AR9170_NUM_BW != 3);
-
- WARN_ON(ar9170_phy_freq_params[chanidx].freq != freq);
-
- return &ar9170_phy_freq_params[chanidx].params[bw];
-}
-
-
-int ar9170_init_rf(struct ar9170 *ar)
-{
- const struct ar9170_phy_freq_params *freqpar;
- __le32 cmd[7];
- int err;
-
- err = ar9170_init_rf_banks_0_7(ar, false);
- if (err)
- return err;
-
- err = ar9170_init_rf_bank4_pwr(ar, false, 2412, AR9170_BW_20);
- if (err)
- return err;
-
- freqpar = ar9170_get_hw_dyn_params(NULL, AR9170_BW_20);
-
- cmd[0] = cpu_to_le32(2412 * 1000);
- cmd[1] = cpu_to_le32(0);
- cmd[2] = cpu_to_le32(1);
- cmd[3] = cpu_to_le32(freqpar->coeff_exp);
- cmd[4] = cpu_to_le32(freqpar->coeff_man);
- cmd[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
- cmd[6] = cpu_to_le32(freqpar->coeff_man_shgi);
-
- /* RF_INIT echoes the command back to us */
- err = ar->exec_cmd(ar, AR9170_CMD_RF_INIT,
- sizeof(cmd), (u8 *)cmd,
- sizeof(cmd), (u8 *)cmd);
- if (err)
- return err;
-
- msleep(1000);
-
- return ar9170_echo_test(ar, 0xaabbccdd);
-}
-
-static int ar9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f)
-{
- int idx = nfreqs - 2;
-
- while (idx >= 0) {
- if (f >= freqs[idx])
- return idx;
- idx--;
- }
-
- return 0;
-}
-
-static s32 ar9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
-{
- /* nothing to interpolate, it's horizontal */
- if (y2 == y1)
- return y1;
-
- /* check if we hit one of the edges */
- if (x == x1)
- return y1;
- if (x == x2)
- return y2;
-
- /* x1 == x2 is bad, hopefully == x */
- if (x2 == x1)
- return y1;
-
- return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1));
-}
-
-static u8 ar9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
-{
-#define SHIFT 8
- s32 y;
-
- y = ar9170_interpolate_s32(x << SHIFT,
- x1 << SHIFT, y1 << SHIFT,
- x2 << SHIFT, y2 << SHIFT);
-
- /*
- * XXX: unwrap this expression
- * Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)?
- * Can we rely on the compiler to optimise away the div?
- */
- return (y >> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1));
-#undef SHIFT
-}
-
-static u8 ar9170_interpolate_val(u8 x, u8 *x_array, u8 *y_array)
-{
- int i;
-
- for (i = 0; i < 3; i++)
- if (x <= x_array[i + 1])
- break;
-
- return ar9170_interpolate_u8(x,
- x_array[i],
- y_array[i],
- x_array[i + 1],
- y_array[i + 1]);
-}
-
-static int ar9170_set_freq_cal_data(struct ar9170 *ar,
- struct ieee80211_channel *channel)
-{
- u8 *cal_freq_pier;
- u8 vpds[2][AR5416_PD_GAIN_ICEPTS];
- u8 pwrs[2][AR5416_PD_GAIN_ICEPTS];
- int chain, idx, i;
- u32 phy_data = 0;
- u8 f, tmp;
-
- switch (channel->band) {
- case IEEE80211_BAND_2GHZ:
- f = channel->center_freq - 2300;
- cal_freq_pier = ar->eeprom.cal_freq_pier_2G;
- i = AR5416_NUM_2G_CAL_PIERS - 1;
- break;
-
- case IEEE80211_BAND_5GHZ:
- f = (channel->center_freq - 4800) / 5;
- cal_freq_pier = ar->eeprom.cal_freq_pier_5G;
- i = AR5416_NUM_5G_CAL_PIERS - 1;
- break;
-
- default:
- return -EINVAL;
- break;
- }
-
- for (; i >= 0; i--) {
- if (cal_freq_pier[i] != 0xff)
- break;
- }
- if (i < 0)
- return -EINVAL;
-
- idx = ar9170_find_freq_idx(i, cal_freq_pier, f);
-
- ar9170_regwrite_begin(ar);
-
- for (chain = 0; chain < AR5416_MAX_CHAINS; chain++) {
- for (i = 0; i < AR5416_PD_GAIN_ICEPTS; i++) {
- struct ar9170_calibration_data_per_freq *cal_pier_data;
- int j;
-
- switch (channel->band) {
- case IEEE80211_BAND_2GHZ:
- cal_pier_data = &ar->eeprom.
- cal_pier_data_2G[chain][idx];
- break;
-
- case IEEE80211_BAND_5GHZ:
- cal_pier_data = &ar->eeprom.
- cal_pier_data_5G[chain][idx];
- break;
-
- default:
- return -EINVAL;
- }
-
- for (j = 0; j < 2; j++) {
- vpds[j][i] = ar9170_interpolate_u8(f,
- cal_freq_pier[idx],
- cal_pier_data->vpd_pdg[j][i],
- cal_freq_pier[idx + 1],
- cal_pier_data[1].vpd_pdg[j][i]);
-
- pwrs[j][i] = ar9170_interpolate_u8(f,
- cal_freq_pier[idx],
- cal_pier_data->pwr_pdg[j][i],
- cal_freq_pier[idx + 1],
- cal_pier_data[1].pwr_pdg[j][i]) / 2;
- }
- }
-
- for (i = 0; i < 76; i++) {
- if (i < 25) {
- tmp = ar9170_interpolate_val(i, &pwrs[0][0],
- &vpds[0][0]);
- } else {
- tmp = ar9170_interpolate_val(i - 12,
- &pwrs[1][0],
- &vpds[1][0]);
- }
-
- phy_data |= tmp << ((i & 3) << 3);
- if ((i & 3) == 3) {
- ar9170_regwrite(0x1c6280 + chain * 0x1000 +
- (i & ~3), phy_data);
- phy_data = 0;
- }
- }
-
- for (i = 19; i < 32; i++)
- ar9170_regwrite(0x1c6280 + chain * 0x1000 + (i << 2),
- 0x0);
- }
-
- ar9170_regwrite_finish();
- return ar9170_regwrite_result();
-}
-
-static u8 ar9170_get_max_edge_power(struct ar9170 *ar,
- struct ar9170_calctl_edges edges[],
- u32 freq)
-{
- int i;
- u8 rc = AR5416_MAX_RATE_POWER;
- u8 f;
- if (freq < 3000)
- f = freq - 2300;
- else
- f = (freq - 4800) / 5;
-
- for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) {
- if (edges[i].channel == 0xff)
- break;
- if (f == edges[i].channel) {
- /* exact freq match */
- rc = edges[i].power_flags & ~AR9170_CALCTL_EDGE_FLAGS;
- break;
- }
- if (i > 0 && f < edges[i].channel) {
- if (f > edges[i - 1].channel &&
- edges[i - 1].power_flags &
- AR9170_CALCTL_EDGE_FLAGS) {
- /* lower channel has the inband flag set */
- rc = edges[i - 1].power_flags &
- ~AR9170_CALCTL_EDGE_FLAGS;
- }
- break;
- }
- }
-
- if (i == AR5416_NUM_BAND_EDGES) {
- if (f > edges[i - 1].channel &&
- edges[i - 1].power_flags & AR9170_CALCTL_EDGE_FLAGS) {
- /* lower channel has the inband flag set */
- rc = edges[i - 1].power_flags &
- ~AR9170_CALCTL_EDGE_FLAGS;
- }
- }
- return rc;
-}
-
-static u8 ar9170_get_heavy_clip(struct ar9170 *ar,
- struct ar9170_calctl_edges edges[],
- u32 freq, enum ar9170_bw bw)
-{
- u8 f;
- int i;
- u8 rc = 0;
-
- if (freq < 3000)
- f = freq - 2300;
- else
- f = (freq - 4800) / 5;
-
- if (bw == AR9170_BW_40_BELOW || bw == AR9170_BW_40_ABOVE)
- rc |= 0xf0;
-
- for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) {
- if (edges[i].channel == 0xff)
- break;
- if (f == edges[i].channel) {
- if (!(edges[i].power_flags & AR9170_CALCTL_EDGE_FLAGS))
- rc |= 0x0f;
- break;
- }
- }
-
- return rc;
-}
-
-/*
- * calculate the conformance test limits and the heavy clip parameter
- * and apply them to ar->power* (derived from otus hal/hpmain.c, line 3706)
- */
-static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
-{
- u8 ctl_grp; /* CTL group */
- u8 ctl_idx; /* CTL index */
- int i, j;
- struct ctl_modes {
- u8 ctl_mode;
- u8 max_power;
- u8 *pwr_cal_data;
- int pwr_cal_len;
- } *modes;
-
- /*
- * order is relevant in the mode_list_*: we fall back to the
- * lower indices if any mode is missed in the EEPROM.
- */
- struct ctl_modes mode_list_2ghz[] = {
- { CTL_11B, 0, ar->power_2G_cck, 4 },
- { CTL_11G, 0, ar->power_2G_ofdm, 4 },
- { CTL_2GHT20, 0, ar->power_2G_ht20, 8 },
- { CTL_2GHT40, 0, ar->power_2G_ht40, 8 },
- };
- struct ctl_modes mode_list_5ghz[] = {
- { CTL_11A, 0, ar->power_5G_leg, 4 },
- { CTL_5GHT20, 0, ar->power_5G_ht20, 8 },
- { CTL_5GHT40, 0, ar->power_5G_ht40, 8 },
- };
- int nr_modes;
-
-#define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n])
-
- ar->phy_heavy_clip = 0;
-
- /*
- * TODO: investigate the differences between OTUS'
- * hpreg.c::zfHpGetRegulatoryDomain() and
- * ath/regd.c::ath_regd_get_band_ctl() -
- * e.g. for FCC3_WORLD the OTUS procedure
- * always returns CTL_FCC, while the one in ath/ delivers
- * CTL_ETSI for 2GHz and CTL_FCC for 5GHz.
- */
- ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory,
- ar->hw->conf.channel->band);
-
- /* ctl group not found - either invalid band (NO_CTL) or ww roaming */
- if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL)
- ctl_grp = CTL_FCC;
-
- if (ctl_grp != CTL_FCC)
- /* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */
- return;
-
- if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
- modes = mode_list_2ghz;
- nr_modes = ARRAY_SIZE(mode_list_2ghz);
- } else {
- modes = mode_list_5ghz;
- nr_modes = ARRAY_SIZE(mode_list_5ghz);
- }
-
- for (i = 0; i < nr_modes; i++) {
- u8 c = ctl_grp | modes[i].ctl_mode;
- for (ctl_idx = 0; ctl_idx < AR5416_NUM_CTLS; ctl_idx++)
- if (c == ar->eeprom.ctl_index[ctl_idx])
- break;
- if (ctl_idx < AR5416_NUM_CTLS) {
- int f_off = 0;
-
- /* determine heav clip parameter from
- the 11G edges array */
- if (modes[i].ctl_mode == CTL_11G) {
- ar->phy_heavy_clip =
- ar9170_get_heavy_clip(ar,
- EDGES(ctl_idx, 1),
- freq, bw);
- }
-
- /* adjust freq for 40MHz */
- if (modes[i].ctl_mode == CTL_2GHT40 ||
- modes[i].ctl_mode == CTL_5GHT40) {
- if (bw == AR9170_BW_40_BELOW)
- f_off = -10;
- else
- f_off = 10;
- }
-
- modes[i].max_power =
- ar9170_get_max_edge_power(ar, EDGES(ctl_idx, 1),
- freq+f_off);
-
- /*
- * TODO: check if the regulatory max. power is
- * controlled by cfg80211 for DFS
- * (hpmain applies it to max_power itself for DFS freq)
- */
-
- } else {
- /*
- * Workaround in otus driver, hpmain.c, line 3906:
- * if no data for 5GHT20 are found, take the
- * legacy 5G value.
- * We extend this here to fallback from any other *HT or
- * 11G, too.
- */
- int k = i;
-
- modes[i].max_power = AR5416_MAX_RATE_POWER;
- while (k-- > 0) {
- if (modes[k].max_power !=
- AR5416_MAX_RATE_POWER) {
- modes[i].max_power = modes[k].max_power;
- break;
- }
- }
- }
-
- /* apply max power to pwr_cal_data (ar->power_*) */
- for (j = 0; j < modes[i].pwr_cal_len; j++) {
- modes[i].pwr_cal_data[j] = min(modes[i].pwr_cal_data[j],
- modes[i].max_power);
- }
- }
-
- if (ar->phy_heavy_clip & 0xf0) {
- ar->power_2G_ht40[0]--;
- ar->power_2G_ht40[1]--;
- ar->power_2G_ht40[2]--;
- }
- if (ar->phy_heavy_clip & 0xf) {
- ar->power_2G_ht20[0]++;
- ar->power_2G_ht20[1]++;
- ar->power_2G_ht20[2]++;
- }
-
-
-#undef EDGES
-}
-
-static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
-{
- struct ar9170_calibration_target_power_legacy *ctpl;
- struct ar9170_calibration_target_power_ht *ctph;
- u8 *ctpres;
- int ntargets;
- int idx, i, n;
- u8 ackpower, ackchains, f;
- u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
-
- if (freq < 3000)
- f = freq - 2300;
- else
- f = (freq - 4800)/5;
-
- /*
- * cycle through the various modes
- *
- * legacy modes first: 5G, 2G CCK, 2G OFDM
- */
- for (i = 0; i < 3; i++) {
- switch (i) {
- case 0: /* 5 GHz legacy */
- ctpl = &ar->eeprom.cal_tgt_pwr_5G[0];
- ntargets = AR5416_NUM_5G_TARGET_PWRS;
- ctpres = ar->power_5G_leg;
- break;
- case 1: /* 2.4 GHz CCK */
- ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0];
- ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS;
- ctpres = ar->power_2G_cck;
- break;
- case 2: /* 2.4 GHz OFDM */
- ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0];
- ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
- ctpres = ar->power_2G_ofdm;
- break;
- default:
- BUG();
- }
-
- for (n = 0; n < ntargets; n++) {
- if (ctpl[n].freq == 0xff)
- break;
- pwr_freqs[n] = ctpl[n].freq;
- }
- ntargets = n;
- idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
- for (n = 0; n < 4; n++)
- ctpres[n] = ar9170_interpolate_u8(
- f,
- ctpl[idx + 0].freq,
- ctpl[idx + 0].power[n],
- ctpl[idx + 1].freq,
- ctpl[idx + 1].power[n]);
- }
-
- /*
- * HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40
- */
- for (i = 0; i < 4; i++) {
- switch (i) {
- case 0: /* 5 GHz HT 20 */
- ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0];
- ntargets = AR5416_NUM_5G_TARGET_PWRS;
- ctpres = ar->power_5G_ht20;
- break;
- case 1: /* 5 GHz HT 40 */
- ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0];
- ntargets = AR5416_NUM_5G_TARGET_PWRS;
- ctpres = ar->power_5G_ht40;
- break;
- case 2: /* 2.4 GHz HT 20 */
- ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0];
- ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
- ctpres = ar->power_2G_ht20;
- break;
- case 3: /* 2.4 GHz HT 40 */
- ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0];
- ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
- ctpres = ar->power_2G_ht40;
- break;
- default:
- BUG();
- }
-
- for (n = 0; n < ntargets; n++) {
- if (ctph[n].freq == 0xff)
- break;
- pwr_freqs[n] = ctph[n].freq;
- }
- ntargets = n;
- idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
- for (n = 0; n < 8; n++)
- ctpres[n] = ar9170_interpolate_u8(
- f,
- ctph[idx + 0].freq,
- ctph[idx + 0].power[n],
- ctph[idx + 1].freq,
- ctph[idx + 1].power[n]);
- }
-
-
- /* calc. conformance test limits and apply to ar->power*[] */
- ar9170_calc_ctl(ar, freq, bw);
-
- /* set ACK/CTS TX power */
- ar9170_regwrite_begin(ar);
-
- if (ar->eeprom.tx_mask != 1)
- ackchains = AR9170_TX_PHY_TXCHAIN_2;
- else
- ackchains = AR9170_TX_PHY_TXCHAIN_1;
-
- if (freq < 3000)
- ackpower = ar->power_2G_ofdm[0] & 0x3f;
- else
- ackpower = ar->power_5G_leg[0] & 0x3f;
-
- ar9170_regwrite(0x1c3694, ackpower << 20 | ackchains << 26);
- ar9170_regwrite(0x1c3bb4, ackpower << 5 | ackchains << 11 |
- ackpower << 21 | ackchains << 27);
-
- ar9170_regwrite_finish();
- return ar9170_regwrite_result();
-}
-
-static int ar9170_calc_noise_dbm(u32 raw_noise)
-{
- if (raw_noise & 0x100)
- return ~((raw_noise & 0x0ff) >> 1);
- else
- return (raw_noise & 0xff) >> 1;
-}
-
-int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
- enum ar9170_rf_init_mode rfi, enum ar9170_bw bw)
-{
- const struct ar9170_phy_freq_params *freqpar;
- u32 cmd, tmp, offs;
- __le32 vals[8];
- int i, err;
- bool bandswitch;
-
- /* clear BB heavy clip enable */
- err = ar9170_write_reg(ar, 0x1c59e0, 0x200);
- if (err)
- return err;
-
- /* may be NULL at first setup */
- if (ar->channel)
- bandswitch = ar->channel->band != channel->band;
- else
- bandswitch = true;
-
- /* HW workaround */
- if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] &&
- channel->center_freq <= 2417)
- bandswitch = true;
-
- err = ar->exec_cmd(ar, AR9170_CMD_FREQ_START, 0, NULL, 0, NULL);
- if (err)
- return err;
-
- if (rfi != AR9170_RFI_NONE || bandswitch) {
- u32 val = 0x400;
-
- if (rfi == AR9170_RFI_COLD)
- val = 0x800;
-
- /* warm/cold reset BB/ADDA */
- err = ar9170_write_reg(ar, 0x1d4004, val);
- if (err)
- return err;
-
- err = ar9170_write_reg(ar, 0x1d4004, 0x0);
- if (err)
- return err;
-
- err = ar9170_init_phy(ar, channel->band);
- if (err)
- return err;
-
- err = ar9170_init_rf_banks_0_7(ar,
- channel->band == IEEE80211_BAND_5GHZ);
- if (err)
- return err;
-
- cmd = AR9170_CMD_RF_INIT;
- } else {
- cmd = AR9170_CMD_FREQUENCY;
- }
-
- err = ar9170_init_rf_bank4_pwr(ar,
- channel->band == IEEE80211_BAND_5GHZ,
- channel->center_freq, bw);
- if (err)
- return err;
-
- switch (bw) {
- case AR9170_BW_20:
- tmp = 0x240;
- offs = 0;
- break;
- case AR9170_BW_40_BELOW:
- tmp = 0x2c4;
- offs = 3;
- break;
- case AR9170_BW_40_ABOVE:
- tmp = 0x2d4;
- offs = 1;
- break;
- default:
- BUG();
- return -ENOSYS;
- }
-
- if (ar->eeprom.tx_mask != 1)
- tmp |= 0x100;
-
- err = ar9170_write_reg(ar, 0x1c5804, tmp);
- if (err)
- return err;
-
- err = ar9170_set_freq_cal_data(ar, channel);
- if (err)
- return err;
-
- err = ar9170_set_power_cal(ar, channel->center_freq, bw);
- if (err)
- return err;
-
- freqpar = ar9170_get_hw_dyn_params(channel, bw);
-
- vals[0] = cpu_to_le32(channel->center_freq * 1000);
- vals[1] = cpu_to_le32(conf_is_ht40(&ar->hw->conf));
- vals[2] = cpu_to_le32(offs << 2 | 1);
- vals[3] = cpu_to_le32(freqpar->coeff_exp);
- vals[4] = cpu_to_le32(freqpar->coeff_man);
- vals[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
- vals[6] = cpu_to_le32(freqpar->coeff_man_shgi);
- vals[7] = cpu_to_le32(1000);
-
- err = ar->exec_cmd(ar, cmd, sizeof(vals), (u8 *)vals,
- sizeof(vals), (u8 *)vals);
- if (err)
- return err;
-
- if (ar->phy_heavy_clip) {
- err = ar9170_write_reg(ar, 0x1c59e0,
- 0x200 | ar->phy_heavy_clip);
- if (err) {
- if (ar9170_nag_limiter(ar))
- wiphy_err(ar->hw->wiphy,
- "failed to set heavy clip\n");
- }
- }
-
- for (i = 0; i < 2; i++) {
- ar->noise[i] = ar9170_calc_noise_dbm(
- (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff);
-
- ar->noise[i + 2] = ar9170_calc_noise_dbm(
- (le32_to_cpu(vals[5 + i]) >> 23) & 0x1ff);
- }
-
- ar->channel = channel;
- return 0;
-}
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
deleted file mode 100644
index d3be6f9816b..00000000000
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ /dev/null
@@ -1,1008 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * USB - frontend
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2009, Christian Lamparter <chunkeey@web.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- * Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/firmware.h>
-#include <linux/etherdevice.h>
-#include <linux/device.h>
-#include <net/mac80211.h>
-#include "ar9170.h"
-#include "cmd.h"
-#include "hw.h"
-#include "usb.h"
-
-MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
-MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
-MODULE_FIRMWARE("ar9170.fw");
-
-enum ar9170_requirements {
- AR9170_REQ_FW1_ONLY = 1,
-};
-
-static struct usb_device_id ar9170_usb_ids[] = {
- /* Atheros 9170 */
- { USB_DEVICE(0x0cf3, 0x9170) },
- /* Atheros TG121N */
- { USB_DEVICE(0x0cf3, 0x1001) },
- /* TP-Link TL-WN821N v2 */
- { USB_DEVICE(0x0cf3, 0x1002) },
- /* 3Com Dual Band 802.11n USB Adapter */
- { USB_DEVICE(0x0cf3, 0x1010) },
- /* H3C Dual Band 802.11n USB Adapter */
- { USB_DEVICE(0x0cf3, 0x1011) },
- /* Cace Airpcap NX */
- { USB_DEVICE(0xcace, 0x0300) },
- /* D-Link DWA 160 A1 */
- { USB_DEVICE(0x07d1, 0x3c10) },
- /* D-Link DWA 160 A2 */
- { USB_DEVICE(0x07d1, 0x3a09) },
- /* Netgear WNA1000 */
- { USB_DEVICE(0x0846, 0x9040) },
- /* Netgear WNDA3100 */
- { USB_DEVICE(0x0846, 0x9010) },
- /* Netgear WN111 v2 */
- { USB_DEVICE(0x0846, 0x9001) },
- /* Zydas ZD1221 */
- { USB_DEVICE(0x0ace, 0x1221) },
- /* Proxim ORiNOCO 802.11n USB */
- { USB_DEVICE(0x1435, 0x0804) },
- /* WNC Generic 11n USB Dongle */
- { USB_DEVICE(0x1435, 0x0326) },
- /* ZyXEL NWD271N */
- { USB_DEVICE(0x0586, 0x3417) },
- /* Z-Com UB81 BG */
- { USB_DEVICE(0x0cde, 0x0023) },
- /* Z-Com UB82 ABG */
- { USB_DEVICE(0x0cde, 0x0026) },
- /* Sphairon Homelink 1202 */
- { USB_DEVICE(0x0cde, 0x0027) },
- /* Arcadyan WN7512 */
- { USB_DEVICE(0x083a, 0xf522) },
- /* Planex GWUS300 */
- { USB_DEVICE(0x2019, 0x5304) },
- /* IO-Data WNGDNUS2 */
- { USB_DEVICE(0x04bb, 0x093f) },
- /* AVM FRITZ!WLAN USB Stick N */
- { USB_DEVICE(0x057C, 0x8401) },
- /* NEC WL300NU-G */
- { USB_DEVICE(0x0409, 0x0249) },
- /* AVM FRITZ!WLAN USB Stick N 2.4 */
- { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
- /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */
- { USB_DEVICE(0x1668, 0x1200) },
-
- /* terminate */
- {}
-};
-MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);
-
-static void ar9170_usb_submit_urb(struct ar9170_usb *aru)
-{
- struct urb *urb;
- unsigned long flags;
- int err;
-
- if (unlikely(!IS_STARTED(&aru->common)))
- return ;
-
- spin_lock_irqsave(&aru->tx_urb_lock, flags);
- if (atomic_read(&aru->tx_submitted_urbs) >= AR9170_NUM_TX_URBS) {
- spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
- return ;
- }
- atomic_inc(&aru->tx_submitted_urbs);
-
- urb = usb_get_from_anchor(&aru->tx_pending);
- if (!urb) {
- atomic_dec(&aru->tx_submitted_urbs);
- spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
-
- return ;
- }
- spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
-
- aru->tx_pending_urbs--;
- usb_anchor_urb(urb, &aru->tx_submitted);
-
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (unlikely(err)) {
- if (ar9170_nag_limiter(&aru->common))
- dev_err(&aru->udev->dev, "submit_urb failed (%d).\n",
- err);
-
- usb_unanchor_urb(urb);
- atomic_dec(&aru->tx_submitted_urbs);
- ar9170_tx_callback(&aru->common, urb->context);
- }
-
- usb_free_urb(urb);
-}
-
-static void ar9170_usb_tx_urb_complete_frame(struct urb *urb)
-{
- struct sk_buff *skb = urb->context;
- struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
-
- if (unlikely(!aru)) {
- dev_kfree_skb_irq(skb);
- return ;
- }
-
- atomic_dec(&aru->tx_submitted_urbs);
-
- ar9170_tx_callback(&aru->common, skb);
-
- ar9170_usb_submit_urb(aru);
-}
-
-static void ar9170_usb_tx_urb_complete(struct urb *urb)
-{
-}
-
-static void ar9170_usb_irq_completed(struct urb *urb)
-{
- struct ar9170_usb *aru = urb->context;
-
- switch (urb->status) {
- /* everything is fine */
- case 0:
- break;
-
- /* disconnect */
- case -ENOENT:
- case -ECONNRESET:
- case -ENODEV:
- case -ESHUTDOWN:
- goto free;
-
- default:
- goto resubmit;
- }
-
- ar9170_handle_command_response(&aru->common, urb->transfer_buffer,
- urb->actual_length);
-
-resubmit:
- usb_anchor_urb(urb, &aru->rx_submitted);
- if (usb_submit_urb(urb, GFP_ATOMIC)) {
- usb_unanchor_urb(urb);
- goto free;
- }
-
- return;
-
-free:
- usb_free_coherent(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
-}
-
-static void ar9170_usb_rx_completed(struct urb *urb)
-{
- struct sk_buff *skb = urb->context;
- struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
- int err;
-
- if (!aru)
- goto free;
-
- switch (urb->status) {
- /* everything is fine */
- case 0:
- break;
-
- /* disconnect */
- case -ENOENT:
- case -ECONNRESET:
- case -ENODEV:
- case -ESHUTDOWN:
- goto free;
-
- default:
- goto resubmit;
- }
-
- skb_put(skb, urb->actual_length);
- ar9170_rx(&aru->common, skb);
-
-resubmit:
- skb_reset_tail_pointer(skb);
- skb_trim(skb, 0);
-
- usb_anchor_urb(urb, &aru->rx_submitted);
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (unlikely(err)) {
- usb_unanchor_urb(urb);
- goto free;
- }
-
- return ;
-
-free:
- dev_kfree_skb_irq(skb);
-}
-
-static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
- struct urb *urb, gfp_t gfp)
-{
- struct sk_buff *skb;
-
- skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE + 32, gfp);
- if (!skb)
- return -ENOMEM;
-
- /* reserve some space for mac80211's radiotap */
- skb_reserve(skb, 32);
-
- usb_fill_bulk_urb(urb, aru->udev,
- usb_rcvbulkpipe(aru->udev, AR9170_EP_RX),
- skb->data, min(skb_tailroom(skb),
- AR9170_MAX_RX_BUFFER_SIZE),
- ar9170_usb_rx_completed, skb);
-
- return 0;
-}
-
-static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
-{
- struct urb *urb = NULL;
- void *ibuf;
- int err = -ENOMEM;
-
- /* initialize interrupt endpoint */
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb)
- goto out;
-
- ibuf = usb_alloc_coherent(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
- if (!ibuf)
- goto out;
-
- usb_fill_int_urb(urb, aru->udev,
- usb_rcvintpipe(aru->udev, AR9170_EP_IRQ), ibuf,
- 64, ar9170_usb_irq_completed, aru, 1);
- urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- usb_anchor_urb(urb, &aru->rx_submitted);
- err = usb_submit_urb(urb, GFP_KERNEL);
- if (err) {
- usb_unanchor_urb(urb);
- usb_free_coherent(aru->udev, 64, urb->transfer_buffer,
- urb->transfer_dma);
- }
-
-out:
- usb_free_urb(urb);
- return err;
-}
-
-static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru)
-{
- struct urb *urb;
- int i;
- int err = -EINVAL;
-
- for (i = 0; i < AR9170_NUM_RX_URBS; i++) {
- err = -ENOMEM;
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb)
- goto err_out;
-
- err = ar9170_usb_prep_rx_urb(aru, urb, GFP_KERNEL);
- if (err) {
- usb_free_urb(urb);
- goto err_out;
- }
-
- usb_anchor_urb(urb, &aru->rx_submitted);
- err = usb_submit_urb(urb, GFP_KERNEL);
- if (err) {
- usb_unanchor_urb(urb);
- dev_kfree_skb_any((void *) urb->transfer_buffer);
- usb_free_urb(urb);
- goto err_out;
- }
- usb_free_urb(urb);
- }
-
- /* the device now waiting for a firmware. */
- aru->common.state = AR9170_IDLE;
- return 0;
-
-err_out:
-
- usb_kill_anchored_urbs(&aru->rx_submitted);
- return err;
-}
-
-static int ar9170_usb_flush(struct ar9170 *ar)
-{
- struct ar9170_usb *aru = (void *) ar;
- struct urb *urb;
- int ret, err = 0;
-
- if (IS_STARTED(ar))
- aru->common.state = AR9170_IDLE;
-
- usb_wait_anchor_empty_timeout(&aru->tx_pending,
- msecs_to_jiffies(800));
- while ((urb = usb_get_from_anchor(&aru->tx_pending))) {
- ar9170_tx_callback(&aru->common, (void *) urb->context);
- usb_free_urb(urb);
- }
-
- /* lets wait a while until the tx - queues are dried out */
- ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
- msecs_to_jiffies(100));
- if (ret == 0)
- err = -ETIMEDOUT;
-
- usb_kill_anchored_urbs(&aru->tx_submitted);
-
- if (IS_ACCEPTING_CMD(ar))
- aru->common.state = AR9170_STARTED;
-
- return err;
-}
-
-static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru)
-{
- int err;
-
- aru->common.state = AR9170_UNKNOWN_STATE;
-
- err = ar9170_usb_flush(&aru->common);
- if (err)
- dev_err(&aru->udev->dev, "stuck tx urbs!\n");
-
- usb_poison_anchored_urbs(&aru->tx_submitted);
- usb_poison_anchored_urbs(&aru->rx_submitted);
-}
-
-static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
- unsigned int plen, void *payload,
- unsigned int outlen, void *out)
-{
- struct ar9170_usb *aru = (void *) ar;
- struct urb *urb = NULL;
- unsigned long flags;
- int err = -ENOMEM;
-
- if (unlikely(!IS_ACCEPTING_CMD(ar)))
- return -EPERM;
-
- if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4))
- return -EINVAL;
-
- urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (unlikely(!urb))
- goto err_free;
-
- ar->cmdbuf[0] = cpu_to_le32(plen);
- ar->cmdbuf[0] |= cpu_to_le32(cmd << 8);
- /* writing multiple regs fills this buffer already */
- if (plen && payload != (u8 *)(&ar->cmdbuf[1]))
- memcpy(&ar->cmdbuf[1], payload, plen);
-
- spin_lock_irqsave(&aru->common.cmdlock, flags);
- aru->readbuf = (u8 *)out;
- aru->readlen = outlen;
- spin_unlock_irqrestore(&aru->common.cmdlock, flags);
-
- usb_fill_int_urb(urb, aru->udev,
- usb_sndintpipe(aru->udev, AR9170_EP_CMD),
- aru->common.cmdbuf, plen + 4,
- ar9170_usb_tx_urb_complete, NULL, 1);
-
- usb_anchor_urb(urb, &aru->tx_submitted);
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (unlikely(err)) {
- usb_unanchor_urb(urb);
- usb_free_urb(urb);
- goto err_unbuf;
- }
- usb_free_urb(urb);
-
- err = wait_for_completion_timeout(&aru->cmd_wait, HZ);
- if (err == 0) {
- err = -ETIMEDOUT;
- goto err_unbuf;
- }
-
- if (aru->readlen != outlen) {
- err = -EMSGSIZE;
- goto err_unbuf;
- }
-
- return 0;
-
-err_unbuf:
- /* Maybe the device was removed in the second we were waiting? */
- if (IS_STARTED(ar)) {
- dev_err(&aru->udev->dev, "no command feedback "
- "received (%d).\n", err);
-
- /* provide some maybe useful debug information */
- print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE,
- aru->common.cmdbuf, plen + 4);
- dump_stack();
- }
-
- /* invalidate to avoid completing the next prematurely */
- spin_lock_irqsave(&aru->common.cmdlock, flags);
- aru->readbuf = NULL;
- aru->readlen = 0;
- spin_unlock_irqrestore(&aru->common.cmdlock, flags);
-
-err_free:
-
- return err;
-}
-
-static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb)
-{
- struct ar9170_usb *aru = (struct ar9170_usb *) ar;
- struct urb *urb;
-
- if (unlikely(!IS_STARTED(ar))) {
- /* Seriously, what were you drink... err... thinking!? */
- return -EPERM;
- }
-
- urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (unlikely(!urb))
- return -ENOMEM;
-
- usb_fill_bulk_urb(urb, aru->udev,
- usb_sndbulkpipe(aru->udev, AR9170_EP_TX),
- skb->data, skb->len,
- ar9170_usb_tx_urb_complete_frame, skb);
- urb->transfer_flags |= URB_ZERO_PACKET;
-
- usb_anchor_urb(urb, &aru->tx_pending);
- aru->tx_pending_urbs++;
-
- usb_free_urb(urb);
-
- ar9170_usb_submit_urb(aru);
- return 0;
-}
-
-static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
-{
- struct ar9170_usb *aru = (void *) ar;
- unsigned long flags;
- u32 in, out;
-
- if (unlikely(!buffer))
- return ;
-
- in = le32_to_cpup((__le32 *)buffer);
- out = le32_to_cpu(ar->cmdbuf[0]);
-
- /* mask off length byte */
- out &= ~0xFF;
-
- if (aru->readlen >= 0) {
- /* add expected length */
- out |= aru->readlen;
- } else {
- /* add obtained length */
- out |= in & 0xFF;
- }
-
- /*
- * Some commands (e.g: AR9170_CMD_FREQUENCY) have a variable response
- * length and we cannot predict the correct length in advance.
- * So we only check if we provided enough space for the data.
- */
- if (unlikely(out < in)) {
- dev_warn(&aru->udev->dev, "received invalid command response "
- "got %d bytes, instead of %d bytes "
- "and the resp length is %d bytes\n",
- in, out, len);
- print_hex_dump_bytes("ar9170 invalid resp: ",
- DUMP_PREFIX_OFFSET, buffer, len);
- /*
- * Do not complete, then the command times out,
- * and we get a stack trace from there.
- */
- return ;
- }
-
- spin_lock_irqsave(&aru->common.cmdlock, flags);
- if (aru->readbuf && len > 0) {
- memcpy(aru->readbuf, buffer + 4, len - 4);
- aru->readbuf = NULL;
- }
- complete(&aru->cmd_wait);
- spin_unlock_irqrestore(&aru->common.cmdlock, flags);
-}
-
-static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
- size_t len, u32 addr, bool complete)
-{
- int transfer, err;
- u8 *buf = kmalloc(4096, GFP_KERNEL);
-
- if (!buf)
- return -ENOMEM;
-
- while (len) {
- transfer = min_t(int, len, 4096);
- memcpy(buf, data, transfer);
-
- err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
- 0x30 /* FW DL */, 0x40 | USB_DIR_OUT,
- addr >> 8, 0, buf, transfer, 1000);
-
- if (err < 0) {
- kfree(buf);
- return err;
- }
-
- len -= transfer;
- data += transfer;
- addr += transfer;
- }
- kfree(buf);
-
- if (complete) {
- err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
- 0x31 /* FW DL COMPLETE */,
- 0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 5000);
- }
-
- return 0;
-}
-
-static int ar9170_usb_reset(struct ar9170_usb *aru)
-{
- int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
-
- if (lock) {
- ret = usb_lock_device_for_reset(aru->udev, aru->intf);
- if (ret < 0) {
- dev_err(&aru->udev->dev, "unable to lock device "
- "for reset (%d).\n", ret);
- return ret;
- }
- }
-
- ret = usb_reset_device(aru->udev);
- if (lock)
- usb_unlock_device(aru->udev);
-
- /* let it rest - for a second - */
- msleep(1000);
-
- return ret;
-}
-
-static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
-{
- int err;
-
- if (!aru->init_values)
- goto upload_fw_start;
-
- /* First, upload initial values to device RAM */
- err = ar9170_usb_upload(aru, aru->init_values->data,
- aru->init_values->size, 0x102800, false);
- if (err) {
- dev_err(&aru->udev->dev, "firmware part 1 "
- "upload failed (%d).\n", err);
- return err;
- }
-
-upload_fw_start:
-
- /* Then, upload the firmware itself and start it */
- return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
- 0x200000, true);
-}
-
-static int ar9170_usb_init_transport(struct ar9170_usb *aru)
-{
- struct ar9170 *ar = (void *) &aru->common;
- int err;
-
- ar9170_regwrite_begin(ar);
-
- /* Set USB Rx stream mode MAX packet number to 2 */
- ar9170_regwrite(AR9170_USB_REG_MAX_AGG_UPLOAD, 0x4);
-
- /* Set USB Rx stream mode timeout to 10us */
- ar9170_regwrite(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80);
-
- ar9170_regwrite_finish();
-
- err = ar9170_regwrite_result();
- if (err)
- dev_err(&aru->udev->dev, "USB setup failed (%d).\n", err);
-
- return err;
-}
-
-static void ar9170_usb_stop(struct ar9170 *ar)
-{
- struct ar9170_usb *aru = (void *) ar;
- int ret;
-
- if (IS_ACCEPTING_CMD(ar))
- aru->common.state = AR9170_STOPPED;
-
- ret = ar9170_usb_flush(ar);
- if (ret)
- dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
-
- usb_poison_anchored_urbs(&aru->tx_submitted);
-
- /*
- * Note:
- * So far we freed all tx urbs, but we won't dare to touch any rx urbs.
- * Else we would end up with a unresponsive device...
- */
-}
-
-static int ar9170_usb_open(struct ar9170 *ar)
-{
- struct ar9170_usb *aru = (void *) ar;
- int err;
-
- usb_unpoison_anchored_urbs(&aru->tx_submitted);
- err = ar9170_usb_init_transport(aru);
- if (err) {
- usb_poison_anchored_urbs(&aru->tx_submitted);
- return err;
- }
-
- aru->common.state = AR9170_IDLE;
- return 0;
-}
-
-static int ar9170_usb_init_device(struct ar9170_usb *aru)
-{
- int err;
-
- err = ar9170_usb_alloc_rx_irq_urb(aru);
- if (err)
- goto err_out;
-
- err = ar9170_usb_alloc_rx_bulk_urbs(aru);
- if (err)
- goto err_unrx;
-
- err = ar9170_usb_upload_firmware(aru);
- if (err) {
- err = ar9170_echo_test(&aru->common, 0x60d43110);
- if (err) {
- /* force user invention, by disabling the device */
- err = usb_driver_set_configuration(aru->udev, -1);
- dev_err(&aru->udev->dev, "device is in a bad state. "
- "please reconnect it!\n");
- goto err_unrx;
- }
- }
-
- return 0;
-
-err_unrx:
- ar9170_usb_cancel_urbs(aru);
-
-err_out:
- return err;
-}
-
-static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
-{
- struct device *parent = aru->udev->dev.parent;
- struct usb_device *udev;
-
- /*
- * Store a copy of the usb_device pointer locally.
- * This is because device_release_driver initiates
- * ar9170_usb_disconnect, which in turn frees our
- * driver context (aru).
- */
- udev = aru->udev;
-
- complete(&aru->firmware_loading_complete);
-
- /* unbind anything failed */
- if (parent)
- device_lock(parent);
-
- device_release_driver(&udev->dev);
- if (parent)
- device_unlock(parent);
-
- usb_put_dev(udev);
-}
-
-static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
-{
- struct ar9170_usb *aru = context;
- int err;
-
- aru->firmware = fw;
-
- if (!fw) {
- dev_err(&aru->udev->dev, "firmware file not found.\n");
- goto err_freefw;
- }
-
- err = ar9170_usb_init_device(aru);
- if (err)
- goto err_freefw;
-
- err = ar9170_usb_open(&aru->common);
- if (err)
- goto err_unrx;
-
- err = ar9170_register(&aru->common, &aru->udev->dev);
-
- ar9170_usb_stop(&aru->common);
- if (err)
- goto err_unrx;
-
- complete(&aru->firmware_loading_complete);
- usb_put_dev(aru->udev);
- return;
-
- err_unrx:
- ar9170_usb_cancel_urbs(aru);
-
- err_freefw:
- ar9170_usb_firmware_failed(aru);
-}
-
-static void ar9170_usb_firmware_inits(const struct firmware *fw,
- void *context)
-{
- struct ar9170_usb *aru = context;
- int err;
-
- if (!fw) {
- dev_err(&aru->udev->dev, "file with init values not found.\n");
- ar9170_usb_firmware_failed(aru);
- return;
- }
-
- aru->init_values = fw;
-
- /* ok so we have the init values -- get code for two-stage */
-
- err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-2.fw",
- &aru->udev->dev, GFP_KERNEL, aru,
- ar9170_usb_firmware_finish);
- if (err)
- ar9170_usb_firmware_failed(aru);
-}
-
-static void ar9170_usb_firmware_step2(const struct firmware *fw, void *context)
-{
- struct ar9170_usb *aru = context;
- int err;
-
- if (fw) {
- ar9170_usb_firmware_finish(fw, context);
- return;
- }
-
- if (aru->req_one_stage_fw) {
- dev_err(&aru->udev->dev, "ar9170.fw firmware file "
- "not found and is required for this device\n");
- ar9170_usb_firmware_failed(aru);
- return;
- }
-
- dev_err(&aru->udev->dev, "ar9170.fw firmware file "
- "not found, trying old firmware...\n");
-
- err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-1.fw",
- &aru->udev->dev, GFP_KERNEL, aru,
- ar9170_usb_firmware_inits);
- if (err)
- ar9170_usb_firmware_failed(aru);
-}
-
-static bool ar9170_requires_one_stage(const struct usb_device_id *id)
-{
- if (!id->driver_info)
- return false;
- if (id->driver_info == AR9170_REQ_FW1_ONLY)
- return true;
- return false;
-}
-
-static int ar9170_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct ar9170_usb *aru;
- struct ar9170 *ar;
- struct usb_device *udev;
- int err;
-
- aru = ar9170_alloc(sizeof(*aru));
- if (IS_ERR(aru)) {
- err = PTR_ERR(aru);
- goto out;
- }
-
- udev = interface_to_usbdev(intf);
- usb_get_dev(udev);
- aru->udev = udev;
- aru->intf = intf;
- ar = &aru->common;
-
- aru->req_one_stage_fw = ar9170_requires_one_stage(id);
-
- usb_set_intfdata(intf, aru);
- SET_IEEE80211_DEV(ar->hw, &intf->dev);
-
- init_usb_anchor(&aru->rx_submitted);
- init_usb_anchor(&aru->tx_pending);
- init_usb_anchor(&aru->tx_submitted);
- init_completion(&aru->cmd_wait);
- init_completion(&aru->firmware_loading_complete);
- spin_lock_init(&aru->tx_urb_lock);
-
- aru->tx_pending_urbs = 0;
- atomic_set(&aru->tx_submitted_urbs, 0);
-
- aru->common.stop = ar9170_usb_stop;
- aru->common.flush = ar9170_usb_flush;
- aru->common.open = ar9170_usb_open;
- aru->common.tx = ar9170_usb_tx;
- aru->common.exec_cmd = ar9170_usb_exec_cmd;
- aru->common.callback_cmd = ar9170_usb_callback_cmd;
-
-#ifdef CONFIG_PM
- udev->reset_resume = 1;
-#endif /* CONFIG_PM */
- err = ar9170_usb_reset(aru);
- if (err)
- goto err_freehw;
-
- usb_get_dev(aru->udev);
- return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw",
- &aru->udev->dev, GFP_KERNEL, aru,
- ar9170_usb_firmware_step2);
-err_freehw:
- usb_set_intfdata(intf, NULL);
- usb_put_dev(udev);
- ieee80211_free_hw(ar->hw);
-out:
- return err;
-}
-
-static void ar9170_usb_disconnect(struct usb_interface *intf)
-{
- struct ar9170_usb *aru = usb_get_intfdata(intf);
-
- if (!aru)
- return;
-
- aru->common.state = AR9170_IDLE;
-
- wait_for_completion(&aru->firmware_loading_complete);
-
- ar9170_unregister(&aru->common);
- ar9170_usb_cancel_urbs(aru);
-
- usb_put_dev(aru->udev);
- usb_set_intfdata(intf, NULL);
- ieee80211_free_hw(aru->common.hw);
-
- release_firmware(aru->init_values);
- release_firmware(aru->firmware);
-}
-
-#ifdef CONFIG_PM
-static int ar9170_suspend(struct usb_interface *intf,
- pm_message_t message)
-{
- struct ar9170_usb *aru = usb_get_intfdata(intf);
-
- if (!aru)
- return -ENODEV;
-
- aru->common.state = AR9170_IDLE;
- ar9170_usb_cancel_urbs(aru);
-
- return 0;
-}
-
-static int ar9170_resume(struct usb_interface *intf)
-{
- struct ar9170_usb *aru = usb_get_intfdata(intf);
- int err;
-
- if (!aru)
- return -ENODEV;
-
- usb_unpoison_anchored_urbs(&aru->rx_submitted);
- usb_unpoison_anchored_urbs(&aru->tx_submitted);
-
- err = ar9170_usb_init_device(aru);
- if (err)
- goto err_unrx;
-
- err = ar9170_usb_open(&aru->common);
- if (err)
- goto err_unrx;
-
- return 0;
-
-err_unrx:
- aru->common.state = AR9170_IDLE;
- ar9170_usb_cancel_urbs(aru);
-
- return err;
-}
-#endif /* CONFIG_PM */
-
-static struct usb_driver ar9170_driver = {
- .name = "ar9170usb",
- .probe = ar9170_usb_probe,
- .disconnect = ar9170_usb_disconnect,
- .id_table = ar9170_usb_ids,
- .soft_unbind = 1,
-#ifdef CONFIG_PM
- .suspend = ar9170_suspend,
- .resume = ar9170_resume,
- .reset_resume = ar9170_resume,
-#endif /* CONFIG_PM */
-};
-
-static int __init ar9170_init(void)
-{
- return usb_register(&ar9170_driver);
-}
-
-static void __exit ar9170_exit(void)
-{
- usb_deregister(&ar9170_driver);
-}
-
-module_init(ar9170_init);
-module_exit(ar9170_exit);
diff --git a/drivers/net/wireless/ath/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h
deleted file mode 100644
index 919b06046eb..00000000000
--- a/drivers/net/wireless/ath/ar9170/usb.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Atheros AR9170 USB driver
- *
- * Driver specific definitions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2009, Christian Lamparter <chunkeey@web.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- * Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef __USB_H
-#define __USB_H
-
-#include <linux/usb.h>
-#include <linux/completion.h>
-#include <linux/spinlock.h>
-#include <linux/leds.h>
-#include <net/cfg80211.h>
-#include <net/mac80211.h>
-#include <linux/firmware.h>
-#include "eeprom.h"
-#include "hw.h"
-#include "ar9170.h"
-
-#define AR9170_NUM_RX_URBS 16
-#define AR9170_NUM_TX_URBS 8
-
-struct firmware;
-
-struct ar9170_usb {
- struct ar9170 common;
- struct usb_device *udev;
- struct usb_interface *intf;
-
- struct usb_anchor rx_submitted;
- struct usb_anchor tx_pending;
- struct usb_anchor tx_submitted;
-
- bool req_one_stage_fw;
-
- spinlock_t tx_urb_lock;
- atomic_t tx_submitted_urbs;
- unsigned int tx_pending_urbs;
-
- struct completion cmd_wait;
- struct completion firmware_loading_complete;
- int readlen;
- u8 *readbuf;
-
- const struct firmware *init_values;
- const struct firmware *firmware;
-};
-
-#endif /* __USB_H */
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index a6c6a466000..7cf4317a2a8 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -119,17 +119,11 @@ struct ath_ops {
void (*write)(void *, u32 val, u32 reg_offset);
void (*enable_write_buffer)(void *);
void (*write_flush) (void *);
+ u32 (*rmw)(void *, u32 reg_offset, u32 set, u32 clr);
};
struct ath_common;
-
-struct ath_bus_ops {
- enum ath_bus_type ath_bus_type;
- void (*read_cachesize)(struct ath_common *common, int *csz);
- bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
- void (*bt_coex_prep)(struct ath_common *common);
- void (*extn_synch_en)(struct ath_common *common);
-};
+struct ath_bus_ops;
struct ath_common {
void *ah;
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c
index 82324e98efe..ea998278155 100644
--- a/drivers/net/wireless/ath/ath5k/ahb.c
+++ b/drivers/net/wireless/ath/ath5k/ahb.c
@@ -18,6 +18,7 @@
#include <linux/nl80211.h>
#include <linux/platform_device.h>
+#include <linux/etherdevice.h>
#include <ar231x_platform.h>
#include "ath5k.h"
#include "debug.h"
@@ -62,10 +63,27 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah)
return 0;
}
+static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
+{
+ struct ath5k_softc *sc = ah->ah_sc;
+ struct platform_device *pdev = to_platform_device(sc->dev);
+ struct ar231x_board_config *bcfg = pdev->dev.platform_data;
+ u8 *cfg_mac;
+
+ if (to_platform_device(sc->dev)->id == 0)
+ cfg_mac = bcfg->config->wlan0_mac;
+ else
+ cfg_mac = bcfg->config->wlan1_mac;
+
+ memcpy(mac, cfg_mac, ETH_ALEN);
+ return 0;
+}
+
static const struct ath_bus_ops ath_ahb_bus_ops = {
.ath_bus_type = ATH_AHB,
.read_cachesize = ath5k_ahb_read_cachesize,
.eeprom_read = ath5k_ahb_eeprom_read,
+ .eeprom_read_mac = ath5k_ahb_eeprom_read_mac,
};
/*Initialization*/
@@ -142,6 +160,16 @@ static int ath_ahb_probe(struct platform_device *pdev)
else
reg |= AR5K_AR5312_ENABLE_WLAN1;
__raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
+
+ /*
+ * On a dual-band AR5312, the multiband radio is only
+ * used as pass-through. Disable 2 GHz support in the
+ * driver for it
+ */
+ if (to_platform_device(sc->dev)->id == 0 &&
+ (bcfg->config->flags & (BD_WLAN0|BD_WLAN1)) ==
+ (BD_WLAN1|BD_WLAN0))
+ __set_bit(ATH_STAT_2G_DISABLED, sc->status);
}
ret = ath5k_init_softc(sc, &ath_ahb_bus_ops);
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 8a06dbd3962..bb50700436f 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -224,8 +224,7 @@
/* SIFS */
#define AR5K_INIT_SIFS_TURBO 6
-/* XXX: 8 from initvals 10 from standard */
-#define AR5K_INIT_SIFS_DEFAULT_BG 8
+#define AR5K_INIT_SIFS_DEFAULT_BG 10
#define AR5K_INIT_SIFS_DEFAULT_A 16
#define AR5K_INIT_SIFS_HALF_RATE 32
#define AR5K_INIT_SIFS_QUARTER_RATE 64
@@ -453,12 +452,10 @@ struct ath5k_tx_status {
u16 ts_seqnum;
u16 ts_tstamp;
u8 ts_status;
- u8 ts_rate[4];
- u8 ts_retry[4];
u8 ts_final_idx;
+ u8 ts_final_retry;
s8 ts_rssi;
u8 ts_shortretry;
- u8 ts_longretry;
u8 ts_virtcol;
u8 ts_antenna;
};
@@ -875,6 +872,19 @@ enum ath5k_int {
AR5K_INT_QTRIG = 0x40000000, /* Non common */
AR5K_INT_GLOBAL = 0x80000000,
+ AR5K_INT_TX_ALL = AR5K_INT_TXOK
+ | AR5K_INT_TXDESC
+ | AR5K_INT_TXERR
+ | AR5K_INT_TXEOL
+ | AR5K_INT_TXURN,
+
+ AR5K_INT_RX_ALL = AR5K_INT_RXOK
+ | AR5K_INT_RXDESC
+ | AR5K_INT_RXERR
+ | AR5K_INT_RXNOFRM
+ | AR5K_INT_RXEOL
+ | AR5K_INT_RXORN,
+
AR5K_INT_COMMON = AR5K_INT_RXOK
| AR5K_INT_RXDESC
| AR5K_INT_RXERR
@@ -1058,6 +1068,7 @@ struct ath5k_hw {
u8 ah_coverage_class;
bool ah_ack_bitrate_high;
u8 ah_bwmode;
+ bool ah_short_slot;
/* Antenna Control */
u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
@@ -1144,6 +1155,13 @@ struct ath5k_hw {
struct ath5k_rx_status *);
};
+struct ath_bus_ops {
+ enum ath_bus_type ath_bus_type;
+ void (*read_cachesize)(struct ath_common *common, int *csz);
+ bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
+ int (*eeprom_read_mac)(struct ath5k_hw *ah, u8 *mac);
+};
+
/*
* Prototypes
*/
@@ -1227,13 +1245,12 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah);
/* EEPROM access functions */
int ath5k_eeprom_init(struct ath5k_hw *ah);
void ath5k_eeprom_detach(struct ath5k_hw *ah);
-int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
/* Protocol Control Unit Functions */
/* Helpers */
int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
- int len, struct ieee80211_rate *rate);
+ int len, struct ieee80211_rate *rate, bool shortpre);
unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah);
unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah);
extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index bc824056048..1588401de3c 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -313,12 +313,17 @@ int ath5k_hw_init(struct ath5k_softc *sc)
goto err;
}
+ if (test_bit(ATH_STAT_2G_DISABLED, sc->status)) {
+ __clear_bit(AR5K_MODE_11B, ah->ah_capabilities.cap_mode);
+ __clear_bit(AR5K_MODE_11G, ah->ah_capabilities.cap_mode);
+ }
+
/* Crypto settings */
common->keymax = (sc->ah->ah_version == AR5K_AR5210 ?
AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211);
if (srev >= AR5K_SREV_AR5212_V4 &&
- (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 &&
+ (ee->ee_version < AR5K_EEPROM_VERSION_5_0 ||
!AR5K_EEPROM_AES_DIS(ee->ee_misc5)))
common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM;
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 349a5963931..22047628ccf 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1444,6 +1444,21 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
}
static void
+ath5k_set_current_imask(struct ath5k_softc *sc)
+{
+ enum ath5k_int imask = sc->imask;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sc->irqlock, flags);
+ if (sc->rx_pending)
+ imask &= ~AR5K_INT_RX_ALL;
+ if (sc->tx_pending)
+ imask &= ~AR5K_INT_TX_ALL;
+ ath5k_hw_set_imr(sc->ah, imask);
+ spin_unlock_irqrestore(&sc->irqlock, flags);
+}
+
+static void
ath5k_tasklet_rx(unsigned long data)
{
struct ath5k_rx_status rs = {};
@@ -1506,6 +1521,8 @@ next:
} while (ath5k_rxbuf_setup(sc, bf) == 0);
unlock:
spin_unlock(&sc->rxbuflock);
+ sc->rx_pending = false;
+ ath5k_set_current_imask(sc);
}
@@ -1573,28 +1590,28 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
struct ath5k_txq *txq, struct ath5k_tx_status *ts)
{
struct ieee80211_tx_info *info;
+ u8 tries[3];
int i;
sc->stats.tx_all_count++;
sc->stats.tx_bytes_count += skb->len;
info = IEEE80211_SKB_CB(skb);
+ tries[0] = info->status.rates[0].count;
+ tries[1] = info->status.rates[1].count;
+ tries[2] = info->status.rates[2].count;
+
ieee80211_tx_info_clear_status(info);
- for (i = 0; i < 4; i++) {
+
+ for (i = 0; i < ts->ts_final_idx; i++) {
struct ieee80211_tx_rate *r =
&info->status.rates[i];
- if (ts->ts_rate[i]) {
- r->idx = ath5k_hw_to_driver_rix(sc, ts->ts_rate[i]);
- r->count = ts->ts_retry[i];
- } else {
- r->idx = -1;
- r->count = 0;
- }
+ r->count = tries[i];
}
- /* count the successful attempt as well */
- info->status.rates[ts->ts_final_idx].count++;
+ info->status.rates[ts->ts_final_idx].count = ts->ts_final_retry;
+ info->status.rates[ts->ts_final_idx + 1].idx = -1;
if (unlikely(ts->ts_status)) {
sc->stats.ack_fail++;
@@ -1609,6 +1626,9 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
} else {
info->flags |= IEEE80211_TX_STAT_ACK;
info->status.ack_signal = ts->ts_rssi;
+
+ /* count the successful attempt as well */
+ info->status.rates[ts->ts_final_idx].count++;
}
/*
@@ -1690,6 +1710,9 @@ ath5k_tasklet_tx(unsigned long data)
for (i=0; i < AR5K_NUM_TX_QUEUES; i++)
if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i)))
ath5k_tx_processq(sc, &sc->txqs[i]);
+
+ sc->tx_pending = false;
+ ath5k_set_current_imask(sc);
}
@@ -2119,6 +2142,20 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah)
* AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */
}
+static void
+ath5k_schedule_rx(struct ath5k_softc *sc)
+{
+ sc->rx_pending = true;
+ tasklet_schedule(&sc->rxtq);
+}
+
+static void
+ath5k_schedule_tx(struct ath5k_softc *sc)
+{
+ sc->tx_pending = true;
+ tasklet_schedule(&sc->txtq);
+}
+
irqreturn_t
ath5k_intr(int irq, void *dev_id)
{
@@ -2161,7 +2198,7 @@ ath5k_intr(int irq, void *dev_id)
ieee80211_queue_work(sc->hw, &sc->reset_work);
}
else
- tasklet_schedule(&sc->rxtq);
+ ath5k_schedule_rx(sc);
} else {
if (status & AR5K_INT_SWBA) {
tasklet_hi_schedule(&sc->beacontq);
@@ -2179,10 +2216,10 @@ ath5k_intr(int irq, void *dev_id)
ath5k_hw_update_tx_triglevel(ah, true);
}
if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR))
- tasklet_schedule(&sc->rxtq);
+ ath5k_schedule_rx(sc);
if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC
| AR5K_INT_TXERR | AR5K_INT_TXEOL))
- tasklet_schedule(&sc->txtq);
+ ath5k_schedule_tx(sc);
if (status & AR5K_INT_BMISS) {
/* TODO */
}
@@ -2201,6 +2238,9 @@ ath5k_intr(int irq, void *dev_id)
} while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
+ if (sc->rx_pending || sc->tx_pending)
+ ath5k_set_current_imask(sc);
+
if (unlikely(!counter))
ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
@@ -2354,7 +2394,7 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
spin_lock_init(&sc->rxbuflock);
spin_lock_init(&sc->txbuflock);
spin_lock_init(&sc->block);
-
+ spin_lock_init(&sc->irqlock);
/* Setup interrupt handler */
ret = request_irq(sc->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
@@ -2572,6 +2612,8 @@ done:
static void stop_tasklets(struct ath5k_softc *sc)
{
+ sc->rx_pending = false;
+ sc->tx_pending = false;
tasklet_kill(&sc->rxtq);
tasklet_kill(&sc->txtq);
tasklet_kill(&sc->calib);
@@ -2838,7 +2880,7 @@ ath5k_init(struct ieee80211_hw *hw)
INIT_WORK(&sc->reset_work, ath5k_reset_work);
INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work);
- ret = ath5k_eeprom_read_mac(ah, mac);
+ ret = ath5k_hw_common(ah)->bus_ops->eeprom_read_mac(ah, mac);
if (ret) {
ATH5K_ERR(sc, "unable to read address from EEPROM\n");
goto err_queues;
@@ -2898,7 +2940,6 @@ ath5k_deinit_softc(struct ath5k_softc *sc)
* XXX: ??? detach ath5k_hw ???
* Other than that, it's straightforward...
*/
- ath5k_debug_finish_device(sc);
ieee80211_unregister_hw(hw);
ath5k_desc_free(sc);
ath5k_txq_release(sc);
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 978f1f4ac2f..b294f330501 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -193,12 +193,13 @@ struct ath5k_softc {
dma_addr_t desc_daddr; /* DMA (physical) address */
size_t desc_len; /* size of TX/RX descriptors */
- DECLARE_BITMAP(status, 5);
+ 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_LEDSOFT 3 /* enable LED gpio status */
#define ATH_STAT_STARTED 4 /* opened & irqs enabled */
+#define ATH_STAT_2G_DISABLED 5 /* multiband radio without 2G */
unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
struct ieee80211_channel *curchan; /* current h/w channel */
@@ -207,6 +208,10 @@ struct ath5k_softc {
enum ath5k_int imask; /* interrupt mask copy */
+ spinlock_t irqlock;
+ bool rx_pending; /* rx tasklet pending */
+ bool tx_pending; /* tx tasklet pending */
+
u8 lladdr[ETH_ALEN];
u8 bssidmask[ETH_ALEN];
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c
index f77e8a703c5..7dd88e1c3ff 100644
--- a/drivers/net/wireless/ath/ath5k/caps.c
+++ b/drivers/net/wireless/ath/ath5k/caps.c
@@ -94,6 +94,9 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
}
}
+ if ((ah->ah_radio_5ghz_revision & 0xf0) == AR5K_SREV_RAD_2112)
+ __clear_bit(AR5K_MODE_11A, caps->cap_mode);
+
/* Set number of supported TX queues */
if (ah->ah_version == AR5K_AR5210)
caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU;
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 0230f30e9e9..0bf7313b8a1 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -888,65 +888,38 @@ static const struct file_operations fops_queue = {
void
ath5k_debug_init_device(struct ath5k_softc *sc)
{
- sc->debug.level = ath5k_debug;
+ struct dentry *phydir;
- sc->debug.debugfs_phydir = debugfs_create_dir("ath5k",
- sc->hw->wiphy->debugfsdir);
+ sc->debug.level = ath5k_debug;
- sc->debug.debugfs_debug = debugfs_create_file("debug",
- S_IWUSR | S_IRUSR,
- sc->debug.debugfs_phydir, sc, &fops_debug);
+ phydir = debugfs_create_dir("ath5k", sc->hw->wiphy->debugfsdir);
+ if (!phydir)
+ return;
- sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUSR,
- sc->debug.debugfs_phydir, sc, &fops_registers);
+ debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, sc,
+ &fops_debug);
- sc->debug.debugfs_beacon = debugfs_create_file("beacon",
- S_IWUSR | S_IRUSR,
- sc->debug.debugfs_phydir, sc, &fops_beacon);
+ debugfs_create_file("registers", S_IRUSR, phydir, sc, &fops_registers);
- sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR,
- sc->debug.debugfs_phydir, sc, &fops_reset);
+ debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, sc,
+ &fops_beacon);
- sc->debug.debugfs_antenna = debugfs_create_file("antenna",
- S_IWUSR | S_IRUSR,
- sc->debug.debugfs_phydir, sc, &fops_antenna);
+ debugfs_create_file("reset", S_IWUSR, phydir, sc, &fops_reset);
- sc->debug.debugfs_misc = debugfs_create_file("misc",
- S_IRUSR,
- sc->debug.debugfs_phydir, sc, &fops_misc);
+ debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, sc,
+ &fops_antenna);
- sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors",
- S_IWUSR | S_IRUSR,
- sc->debug.debugfs_phydir, sc,
- &fops_frameerrors);
+ debugfs_create_file("misc", S_IRUSR, phydir, sc, &fops_misc);
- sc->debug.debugfs_ani = debugfs_create_file("ani",
- S_IWUSR | S_IRUSR,
- sc->debug.debugfs_phydir, sc,
- &fops_ani);
+ debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, sc,
+ &fops_frameerrors);
- sc->debug.debugfs_queue = debugfs_create_file("queue",
- S_IWUSR | S_IRUSR,
- sc->debug.debugfs_phydir, sc,
- &fops_queue);
-}
+ debugfs_create_file("ani", S_IWUSR | S_IRUSR, phydir, sc, &fops_ani);
-void
-ath5k_debug_finish_device(struct ath5k_softc *sc)
-{
- debugfs_remove(sc->debug.debugfs_debug);
- debugfs_remove(sc->debug.debugfs_registers);
- debugfs_remove(sc->debug.debugfs_beacon);
- debugfs_remove(sc->debug.debugfs_reset);
- debugfs_remove(sc->debug.debugfs_antenna);
- debugfs_remove(sc->debug.debugfs_misc);
- debugfs_remove(sc->debug.debugfs_frameerrors);
- debugfs_remove(sc->debug.debugfs_ani);
- debugfs_remove(sc->debug.debugfs_queue);
- debugfs_remove(sc->debug.debugfs_phydir);
+ debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, sc,
+ &fops_queue);
}
-
/* functions used in other places */
void
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
index b0355aef68d..193dd2d4ea3 100644
--- a/drivers/net/wireless/ath/ath5k/debug.h
+++ b/drivers/net/wireless/ath/ath5k/debug.h
@@ -68,17 +68,6 @@ struct ath5k_buf;
struct ath5k_dbg_info {
unsigned int level; /* debug level */
- /* debugfs entries */
- struct dentry *debugfs_phydir;
- struct dentry *debugfs_debug;
- struct dentry *debugfs_registers;
- struct dentry *debugfs_beacon;
- struct dentry *debugfs_reset;
- struct dentry *debugfs_antenna;
- struct dentry *debugfs_misc;
- struct dentry *debugfs_frameerrors;
- struct dentry *debugfs_ani;
- struct dentry *debugfs_queue;
};
/**
@@ -141,9 +130,6 @@ void
ath5k_debug_init_device(struct ath5k_softc *sc);
void
-ath5k_debug_finish_device(struct ath5k_softc *sc);
-
-void
ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah);
void
@@ -167,9 +153,6 @@ static inline void
ath5k_debug_init_device(struct ath5k_softc *sc) {}
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
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c
index a8fcc94269f..62172d58572 100644
--- a/drivers/net/wireless/ath/ath5k/desc.c
+++ b/drivers/net/wireless/ath/ath5k/desc.c
@@ -185,6 +185,12 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
struct ath5k_hw_4w_tx_ctl *tx_ctl;
unsigned int frame_len;
+ /*
+ * Use local variables for these to reduce load/store access on
+ * uncached memory
+ */
+ u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0;
+
tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
/*
@@ -208,8 +214,9 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
if (tx_power > AR5K_TUNE_MAX_TXPOWER)
tx_power = AR5K_TUNE_MAX_TXPOWER;
- /* Clear descriptor */
- memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
+ /* Clear descriptor status area */
+ memset(&desc->ud.ds_tx5212.tx_stat, 0,
+ sizeof(desc->ud.ds_tx5212.tx_stat));
/* Setup control descriptor */
@@ -221,7 +228,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
return -EINVAL;
- tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
+ txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
/* Verify and set buffer length */
@@ -232,21 +239,17 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
return -EINVAL;
- tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
+ txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
- tx_ctl->tx_control_0 |=
- AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
- AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
- tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
- AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
- tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0,
- AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
- tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
+ txctl0 |= 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);
+ txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
+ txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
+ txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
#define _TX_FLAGS(_c, _flag) \
if (flags & AR5K_TXDESC_##_flag) { \
- tx_ctl->tx_control_##_c |= \
- AR5K_4W_TX_DESC_CTL##_c##_##_flag; \
+ txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag; \
}
_TX_FLAGS(0, CLRDMASK);
@@ -262,8 +265,8 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
* WEP crap
*/
if (key_index != AR5K_TXKEYIX_INVALID) {
- tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
- tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index,
+ txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
+ txctl1 |= AR5K_REG_SM(key_index,
AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX);
}
@@ -274,12 +277,16 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
if ((flags & AR5K_TXDESC_RTSENA) &&
(flags & AR5K_TXDESC_CTSENA))
return -EINVAL;
- tx_ctl->tx_control_2 |= rtscts_duration &
- AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
- tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
+ txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
+ txctl3 |= AR5K_REG_SM(rtscts_rate,
AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
}
+ tx_ctl->tx_control_0 = txctl0;
+ tx_ctl->tx_control_1 = txctl1;
+ tx_ctl->tx_control_2 = txctl2;
+ tx_ctl->tx_control_3 = txctl3;
+
return 0;
}
@@ -364,7 +371,7 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
- ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
+ ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0,
AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
/*TODO: ts->ts_virtcol + test*/
ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
@@ -373,9 +380,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
ts->ts_antenna = 1;
ts->ts_status = 0;
- ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0,
- AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
- ts->ts_retry[0] = ts->ts_longretry;
ts->ts_final_idx = 0;
if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
@@ -401,81 +405,48 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
{
struct ath5k_hw_4w_tx_ctl *tx_ctl;
struct ath5k_hw_tx_status *tx_status;
+ u32 txstat0, txstat1;
tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
tx_status = &desc->ud.ds_tx5212.tx_stat;
+ txstat1 = ACCESS_ONCE(tx_status->tx_status_1);
+
/* No frame has been send or error */
- if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE)))
+ if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE)))
return -EINPROGRESS;
+ txstat0 = ACCESS_ONCE(tx_status->tx_status_0);
+
/*
* Get descriptor status
*/
- ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
+ ts->ts_tstamp = AR5K_REG_MS(txstat0,
AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
- ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
+ ts->ts_shortretry = AR5K_REG_MS(txstat0,
AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
- ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
+ ts->ts_final_retry = AR5K_REG_MS(txstat0,
AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
- ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
+ ts->ts_seqnum = AR5K_REG_MS(txstat1,
AR5K_DESC_TX_STATUS1_SEQ_NUM);
- ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
+ ts->ts_rssi = AR5K_REG_MS(txstat1,
AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
- ts->ts_antenna = (tx_status->tx_status_1 &
+ ts->ts_antenna = (txstat1 &
AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1;
ts->ts_status = 0;
- ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1,
+ ts->ts_final_idx = AR5K_REG_MS(txstat1,
AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212);
- /* The longretry counter has the number of un-acked retries
- * for the final rate. To get the total number of retries
- * we have to add the retry counters for the other rates
- * as well
- */
- ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry;
- switch (ts->ts_final_idx) {
- case 3:
- ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3,
- AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
-
- ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2,
- AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
- ts->ts_longretry += ts->ts_retry[2];
- /* fall through */
- case 2:
- ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3,
- AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
-
- ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2,
- AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
- ts->ts_longretry += ts->ts_retry[1];
- /* fall through */
- case 1:
- ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3,
- AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
-
- ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2,
- AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
- ts->ts_longretry += ts->ts_retry[0];
- /* fall through */
- case 0:
- ts->ts_rate[0] = tx_ctl->tx_control_3 &
- AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
- break;
- }
-
/* TX error */
- if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
- if (tx_status->tx_status_0 &
- AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
+ if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
+ if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
ts->ts_status |= AR5K_TXERR_XRETRY;
- if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
+ if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
ts->ts_status |= AR5K_TXERR_FIFO;
- if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
+ if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED)
ts->ts_status |= AR5K_TXERR_FILT;
}
@@ -609,37 +580,37 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
struct ath5k_rx_status *rs)
{
struct ath5k_hw_rx_status *rx_status;
+ u32 rxstat0, rxstat1;
rx_status = &desc->ud.ds_rx.rx_stat;
+ rxstat1 = ACCESS_ONCE(rx_status->rx_status_1);
/* No frame received / not ready */
- if (unlikely(!(rx_status->rx_status_1 &
- AR5K_5212_RX_DESC_STATUS1_DONE)))
+ if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE)))
return -EINPROGRESS;
memset(rs, 0, sizeof(struct ath5k_rx_status));
+ rxstat0 = ACCESS_ONCE(rx_status->rx_status_0);
/*
* Frame receive status
*/
- rs->rs_datalen = rx_status->rx_status_0 &
- AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
- rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
+ rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
+ rs->rs_rssi = AR5K_REG_MS(rxstat0,
AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
- rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
+ rs->rs_rate = AR5K_REG_MS(rxstat0,
AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
- rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
+ rs->rs_antenna = AR5K_REG_MS(rxstat0,
AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA);
- rs->rs_more = !!(rx_status->rx_status_0 &
- AR5K_5212_RX_DESC_STATUS0_MORE);
- rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
+ rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE);
+ rs->rs_tstamp = AR5K_REG_MS(rxstat1,
AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
/*
* Key table status
*/
- if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
- rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
+ if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
+ rs->rs_keyix = AR5K_REG_MS(rxstat1,
AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
else
rs->rs_keyix = AR5K_RXKEYIX_INVALID;
@@ -647,27 +618,22 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
/*
* Receive/descriptor errors
*/
- if (!(rx_status->rx_status_1 &
- AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
- if (rx_status->rx_status_1 &
- AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
+ if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
+ if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
rs->rs_status |= AR5K_RXERR_CRC;
- if (rx_status->rx_status_1 &
- AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
+ if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
rs->rs_status |= AR5K_RXERR_PHY;
- rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1,
+ rs->rs_phyerr = AR5K_REG_MS(rxstat1,
AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE);
if (!ah->ah_capabilities.cap_has_phyerr_counters)
ath5k_ani_phy_error_report(ah, rs->rs_phyerr);
}
- if (rx_status->rx_status_1 &
- AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
+ if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
rs->rs_status |= AR5K_RXERR_DECRYPT;
- if (rx_status->rx_status_1 &
- AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
+ if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
rs->rs_status |= AR5K_RXERR_MIC;
}
return 0;
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index efb672cb31e..1fef84f87c7 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -660,6 +660,53 @@ ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
}
+static int
+ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ struct ath5k_chan_pcal_info *chinfo;
+ u8 pier, pdg;
+
+ switch (mode) {
+ case AR5K_EEPROM_MODE_11A:
+ if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
+ return 0;
+ chinfo = ee->ee_pwr_cal_a;
+ break;
+ case AR5K_EEPROM_MODE_11B:
+ if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
+ return 0;
+ chinfo = ee->ee_pwr_cal_b;
+ break;
+ case AR5K_EEPROM_MODE_11G:
+ if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
+ return 0;
+ chinfo = ee->ee_pwr_cal_g;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+ if (!chinfo[pier].pd_curves)
+ continue;
+
+ for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
+ struct ath5k_pdgain_info *pd =
+ &chinfo[pier].pd_curves[pdg];
+
+ if (pd != NULL) {
+ kfree(pd->pd_step);
+ kfree(pd->pd_pwr);
+ }
+ }
+
+ kfree(chinfo[pier].pd_curves);
+ }
+
+ return 0;
+}
+
/* Convert RF5111 specific data to generic raw data
* used by interpolation code */
static int
@@ -684,7 +731,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
GFP_KERNEL);
if (!chinfo[pier].pd_curves)
- return -ENOMEM;
+ goto err_out;
/* Only one curve for RF5111
* find out which one and place
@@ -708,12 +755,12 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
sizeof(u8), GFP_KERNEL);
if (!pd->pd_step)
- return -ENOMEM;
+ goto err_out;
pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
sizeof(s16), GFP_KERNEL);
if (!pd->pd_pwr)
- return -ENOMEM;
+ goto err_out;
/* Fill raw dataset
* (convert power to 0.25dB units
@@ -734,6 +781,10 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
}
return 0;
+
+err_out:
+ ath5k_eeprom_free_pcal_info(ah, mode);
+ return -ENOMEM;
}
/* Parse EEPROM data */
@@ -867,7 +918,7 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
GFP_KERNEL);
if (!chinfo[pier].pd_curves)
- return -ENOMEM;
+ goto err_out;
/* Fill pd_curves */
for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
@@ -886,14 +937,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
sizeof(u8), GFP_KERNEL);
if (!pd->pd_step)
- return -ENOMEM;
+ goto err_out;
pd->pd_pwr = kcalloc(pd->pd_points,
sizeof(s16), GFP_KERNEL);
if (!pd->pd_pwr)
- return -ENOMEM;
-
+ goto err_out;
/* Fill raw dataset
* (all power levels are in 0.25dB units) */
@@ -925,13 +975,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
sizeof(u8), GFP_KERNEL);
if (!pd->pd_step)
- return -ENOMEM;
+ goto err_out;
pd->pd_pwr = kcalloc(pd->pd_points,
sizeof(s16), GFP_KERNEL);
if (!pd->pd_pwr)
- return -ENOMEM;
+ goto err_out;
/* Fill raw dataset
* (all power levels are in 0.25dB units) */
@@ -954,6 +1004,10 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
}
return 0;
+
+err_out:
+ ath5k_eeprom_free_pcal_info(ah, mode);
+ return -ENOMEM;
}
/* Parse EEPROM data */
@@ -1156,7 +1210,7 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
GFP_KERNEL);
if (!chinfo[pier].pd_curves)
- return -ENOMEM;
+ goto err_out;
/* Fill pd_curves */
for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
@@ -1177,13 +1231,13 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
sizeof(u8), GFP_KERNEL);
if (!pd->pd_step)
- return -ENOMEM;
+ goto err_out;
pd->pd_pwr = kcalloc(pd->pd_points,
sizeof(s16), GFP_KERNEL);
if (!pd->pd_pwr)
- return -ENOMEM;
+ goto err_out;
/* Fill raw dataset
* convert all pwr levels to
@@ -1213,6 +1267,10 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
}
return 0;
+
+err_out:
+ ath5k_eeprom_free_pcal_info(ah, mode);
+ return -ENOMEM;
}
/* Parse EEPROM data */
@@ -1534,53 +1592,6 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
return 0;
}
-static int
-ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
-{
- struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
- struct ath5k_chan_pcal_info *chinfo;
- u8 pier, pdg;
-
- switch (mode) {
- case AR5K_EEPROM_MODE_11A:
- if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
- return 0;
- chinfo = ee->ee_pwr_cal_a;
- break;
- case AR5K_EEPROM_MODE_11B:
- if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
- return 0;
- chinfo = ee->ee_pwr_cal_b;
- break;
- case AR5K_EEPROM_MODE_11G:
- if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
- return 0;
- chinfo = ee->ee_pwr_cal_g;
- break;
- default:
- return -EINVAL;
- }
-
- for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
- if (!chinfo[pier].pd_curves)
- continue;
-
- for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
- struct ath5k_pdgain_info *pd =
- &chinfo[pier].pd_curves[pdg];
-
- if (pd != NULL) {
- kfree(pd->pd_step);
- kfree(pd->pd_pwr);
- }
- }
-
- kfree(chinfo[pier].pd_curves);
- }
-
- return 0;
-}
-
/* Read conformance test limits used for regulatory control */
static int
ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
@@ -1721,35 +1732,6 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
return ret;
}
-/*
- * Read the MAC address from eeprom
- */
-int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
-{
- u8 mac_d[ETH_ALEN] = {};
- u32 total, offset;
- u16 data;
- int octet;
-
- AR5K_EEPROM_READ(0x20, data);
-
- for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
- AR5K_EEPROM_READ(offset, data);
-
- total += data;
- mac_d[octet + 1] = data & 0xff;
- mac_d[octet] = data >> 8;
- octet += 2;
- }
-
- if (!total || total == 3 * 0xffff)
- return -EINVAL;
-
- memcpy(mac, mac_d, ETH_ALEN);
-
- return 0;
-}
-
/***********************\
* Init/Detach functions *
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 9be29b728b1..807bd644016 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -282,6 +282,15 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if (changes & BSS_CHANGED_BEACON_INT)
sc->bintval = bss_conf->beacon_int;
+ if (changes & BSS_CHANGED_ERP_SLOT) {
+ int slot_time;
+
+ ah->ah_short_slot = bss_conf->use_short_slot;
+ slot_time = ath5k_hw_get_default_slottime(ah) +
+ 3 * ah->ah_coverage_class;
+ ath5k_hw_set_ifs_intervals(ah, slot_time);
+ }
+
if (changes & BSS_CHANGED_ASSOC) {
avf->assoc = bss_conf->assoc;
if (bss_conf->assoc)
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c
index 3c44689a700..296c316a834 100644
--- a/drivers/net/wireless/ath/ath5k/pci.c
+++ b/drivers/net/wireless/ath/ath5k/pci.c
@@ -17,6 +17,7 @@
#include <linux/nl80211.h>
#include <linux/pci.h>
#include <linux/pci-aspm.h>
+#include <linux/etherdevice.h>
#include "../ath.h"
#include "ath5k.h"
#include "debug.h"
@@ -108,11 +109,42 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah)
return 0;
}
+/*
+ * Read the MAC address from eeprom or platform_data
+ */
+static int ath5k_pci_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
+{
+ u8 mac_d[ETH_ALEN] = {};
+ u32 total, offset;
+ u16 data;
+ int octet;
+
+ AR5K_EEPROM_READ(0x20, data);
+
+ for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
+ AR5K_EEPROM_READ(offset, data);
+
+ total += data;
+ mac_d[octet + 1] = data & 0xff;
+ mac_d[octet] = data >> 8;
+ octet += 2;
+ }
+
+ if (!total || total == 3 * 0xffff)
+ return -EINVAL;
+
+ memcpy(mac, mac_d, ETH_ALEN);
+
+ return 0;
+}
+
+
/* Common ath_bus_opts structure */
static const struct ath_bus_ops ath_pci_bus_ops = {
.ath_bus_type = ATH_PCI,
.read_cachesize = ath5k_pci_read_cachesize,
.eeprom_read = ath5k_pci_eeprom_read,
+ .eeprom_read_mac = ath5k_pci_eeprom_read_mac,
};
/********************\
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index d9b3f828455..712a9ac4000 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -75,7 +75,7 @@ static const unsigned int ack_rates_high[] =
* bwmodes.
*/
int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
- int len, struct ieee80211_rate *rate)
+ int len, struct ieee80211_rate *rate, bool shortpre)
{
struct ath5k_softc *sc = ah->ah_sc;
int sifs, preamble, plcp_bits, sym_time;
@@ -84,9 +84,15 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
/* Fallback */
if (!ah->ah_bwmode) {
- dur = ieee80211_generic_frame_duration(sc->hw,
- NULL, len, rate);
- return le16_to_cpu(dur);
+ __le16 raw_dur = ieee80211_generic_frame_duration(sc->hw,
+ NULL, len, rate);
+
+ /* subtract difference between long and short preamble */
+ dur = le16_to_cpu(raw_dur);
+ if (shortpre)
+ dur -= 96;
+
+ return dur;
}
bitrate = rate->bitrate;
@@ -145,9 +151,9 @@ unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE;
break;
case AR5K_BWMODE_DEFAULT:
- slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
default:
- if (channel->hw_value & CHANNEL_CCK)
+ slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
+ if ((channel->hw_value & CHANNEL_CCK) && !ah->ah_short_slot)
slot_time = AR5K_INIT_SLOT_TIME_B;
break;
}
@@ -263,27 +269,14 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah)
* 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 = ath5k_hw_get_frame_duration(ah, 10, rate);
+ tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false);
ath5k_hw_reg_write(ah, tx_time, reg);
if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
continue;
- /*
- * We're not distinguishing short preamble here,
- * This is true, all we'll get is a longer value here
- * which is not necessarilly bad. We could use
- * export ieee80211_frame_duration() but that needs to be
- * fixed first to be properly used by mac802111 drivers:
- *
- * - remove erp stuff and let the routine figure ofdm
- * erp rates
- * - remove passing argument ieee80211_local as
- * drivers don't have access to it
- * - move drivers using ieee80211_generic_frame_duration()
- * to this
- */
+ tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, true);
ath5k_hw_reg_write(ah, tx_time,
reg + (AR5K_SET_SHORT_PREAMBLE << 2));
}
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 3343fb9e494..b18c5021aac 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -519,7 +519,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
return -EINVAL;
sifs = ath5k_hw_get_default_sifs(ah);
- sifs_clock = ath5k_hw_htoclock(ah, sifs);
+ sifs_clock = ath5k_hw_htoclock(ah, sifs - 2);
/* EIFS
* Txtime of ack at lowest rate + SIFS + DIFS
@@ -550,7 +550,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
else
rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0];
- ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);
+ ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false);
/* ack_tx_time includes an SIFS already */
eifs = ack_tx_time + sifs + 2 * slot_time;
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 84206898f77..3510de2cf62 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -159,6 +159,11 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)
rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211);
/*
+ * Set default Tx frame to Tx data start delay
+ */
+ txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT;
+
+ /*
* 5210 initvals don't include usec settings
* so we need to use magic values here for
* tx/rx latencies
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index ad57a6d2311..d9ff8413ab9 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -5,7 +5,7 @@ config ATH9K_COMMON
config ATH9K
tristate "Atheros 802.11n wireless cards support"
- depends on PCI && MAC80211
+ depends on MAC80211
select ATH9K_HW
select MAC80211_LEDS
select LEDS_CLASS
@@ -23,6 +23,25 @@ config ATH9K
If you choose to build a module, it'll be called ath9k.
+config ATH9K_PCI
+ bool "Atheros ath9k PCI/PCIe bus support"
+ depends on ATH9K && PCI
+ default PCI
+ ---help---
+ This option enables the PCI bus support in ath9k.
+
+ Say Y, if you have a compatible PCI/PCIe wireless card.
+
+config ATH9K_AHB
+ bool "Atheros ath9k AHB bus support"
+ depends on ATH9K
+ default n
+ ---help---
+ This option enables the AHB bus support in ath9k.
+
+ Say Y, if you have a SoC with a compatible built-in
+ wireless MAC. Say N if unsure.
+
config ATH9K_DEBUGFS
bool "Atheros ath9k debugging"
depends on ATH9K && DEBUG_FS
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 4d66ca8042e..05a6fade7b1 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -6,8 +6,8 @@ ath9k-y += beacon.o \
xmit.o \
ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o
-ath9k-$(CONFIG_PCI) += pci.o
-ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o
+ath9k-$(CONFIG_ATH9K_PCI) += pci.o
+ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
obj-$(CONFIG_ATH9K) += ath9k.o
@@ -48,4 +48,6 @@ ath9k_htc-y += htc_hst.o \
htc_drv_init.o \
htc_drv_gpio.o
+ath9k_htc-$(CONFIG_ATH9K_HTC_DEBUGFS) += htc_drv_debug.o
+
obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 9cb0efa9b4c..61956392f2d 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -21,6 +21,18 @@
#include <linux/ath9k_platform.h>
#include "ath9k.h"
+static const struct platform_device_id ath9k_platform_id_table[] = {
+ {
+ .name = "ath9k",
+ .driver_data = AR5416_AR9100_DEVID,
+ },
+ {
+ .name = "ar934x_wmac",
+ .driver_data = AR9300_DEVID_AR9340,
+ },
+ {},
+};
+
/* return bus cachesize in 4B word units */
static void ath_ahb_read_cachesize(struct ath_common *common, int *csz)
{
@@ -57,6 +69,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
struct ath_softc *sc;
struct ieee80211_hw *hw;
struct resource *res;
+ const struct platform_device_id *id = platform_get_device_id(pdev);
int irq;
int ret = 0;
struct ath_hw *ah;
@@ -116,7 +129,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
goto err_free_hw;
}
- ret = ath9k_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops);
+ ret = ath9k_init_device(id->driver_data, sc, 0x0, &ath_ahb_bus_ops);
if (ret) {
dev_err(&pdev->dev, "failed to initialize device\n");
goto err_irq;
@@ -165,8 +178,11 @@ static struct platform_driver ath_ahb_driver = {
.name = "ath9k",
.owner = THIS_MODULE,
},
+ .id_table = ath9k_platform_id_table,
};
+MODULE_DEVICE_TABLE(platform, ath9k_platform_id_table);
+
int ath_ahb_init(void)
{
return platform_driver_register(&ath_ahb_driver);
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 2e31c775351..5a1f4f511bc 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -899,12 +899,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
* check here default level should not modify INI setting.
*/
if (use_new_ani(ah)) {
- const struct ani_ofdm_level_entry *entry_ofdm;
- const struct ani_cck_level_entry *entry_cck;
-
- entry_ofdm = &ofdm_level_table[ATH9K_ANI_OFDM_DEF_LEVEL];
- entry_cck = &cck_level_table[ATH9K_ANI_CCK_DEF_LEVEL];
-
ah->aniperiod = ATH9K_ANI_PERIOD_NEW;
ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW;
} else {
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 106c0b06cf5..4bf9dab4f2b 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -44,6 +44,34 @@ static const int m1ThreshExt_off = 127;
static const int m2ThreshExt_off = 127;
+static void ar5008_rf_bank_setup(u32 *bank, struct ar5416IniArray *array,
+ int col)
+{
+ int i;
+
+ for (i = 0; i < array->ia_rows; i++)
+ bank[i] = INI_RA(array, i, col);
+}
+
+
+#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) \
+ ar5008_write_rf_array(ah, iniarray, regData, &(regWr))
+
+static void ar5008_write_rf_array(struct ath_hw *ah, struct ar5416IniArray *array,
+ u32 *data, unsigned int *writecnt)
+{
+ int r;
+
+ ENABLE_REGWRITE_BUFFER(ah);
+
+ for (r = 0; r < array->ia_rows; r++) {
+ REG_WRITE(ah, INI_RA(array, r, 0), data[r]);
+ DO_DELAY(*writecnt);
+ }
+
+ REGWRITE_BUFFER_FLUSH(ah);
+}
+
/**
* ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters
* @rfbuf:
@@ -530,16 +558,16 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah,
eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
/* Setup Bank 0 Write */
- RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
+ ar5008_rf_bank_setup(ah->analogBank0Data, &ah->iniBank0, 1);
/* Setup Bank 1 Write */
- RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
+ ar5008_rf_bank_setup(ah->analogBank1Data, &ah->iniBank1, 1);
/* Setup Bank 2 Write */
- RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
+ ar5008_rf_bank_setup(ah->analogBank2Data, &ah->iniBank2, 1);
/* Setup Bank 6 Write */
- RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
+ ar5008_rf_bank_setup(ah->analogBank3Data, &ah->iniBank3,
modesIndex);
{
int i;
@@ -569,7 +597,7 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah,
}
/* Setup Bank 7 Setup */
- RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
+ ar5008_rf_bank_setup(ah->analogBank7Data, &ah->iniBank7, 1);
/* Write Analog registers */
REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
@@ -729,6 +757,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
struct ath9k_channel *chan)
{
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+ struct ath_common *common = ath9k_hw_common(ah);
int i, regWrites = 0;
struct ieee80211_channel *channel = chan->chan;
u32 modesIndex, freqIndex;
@@ -805,7 +834,8 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
REG_WRITE(ah, reg, val);
if (reg >= 0x7800 && reg < 0x78a0
- && ah->config.analog_shiftreg) {
+ && ah->config.analog_shiftreg
+ && (common->bus_ops->ath_bus_type != ATH_USB)) {
udelay(100);
}
@@ -835,7 +865,8 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
REG_WRITE(ah, reg, val);
if (reg >= 0x7800 && reg < 0x78a0
- && ah->config.analog_shiftreg) {
+ && ah->config.analog_shiftreg
+ && (common->bus_ops->ath_bus_type != ATH_USB)) {
udelay(100);
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 76388c6d669..cb611b287b3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -26,6 +26,27 @@ enum ar9002_cal_types {
IQ_MISMATCH_CAL = BIT(2),
};
+static bool ar9002_hw_is_cal_supported(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ enum ar9002_cal_types cal_type)
+{
+ bool supported = false;
+ switch (ah->supp_cals & cal_type) {
+ case IQ_MISMATCH_CAL:
+ /* Run IQ Mismatch for non-CCK only */
+ if (!IS_CHAN_B(chan))
+ supported = true;
+ break;
+ case ADC_GAIN_CAL:
+ case ADC_DC_CAL:
+ /* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */
+ if (!IS_CHAN_B(chan) &&
+ !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
+ supported = true;
+ break;
+ }
+ return supported;
+}
static void ar9002_hw_setup_calibration(struct ath_hw *ah,
struct ath9k_cal_list *currCal)
@@ -858,26 +879,32 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
ah->supp_cals = IQ_MISMATCH_CAL;
- if (AR_SREV_9160_10_OR_LATER(ah) &&
- !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) {
+ if (AR_SREV_9160_10_OR_LATER(ah))
ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL;
+ if (AR_SREV_9287(ah))
+ ah->supp_cals &= ~ADC_GAIN_CAL;
+ if (ar9002_hw_is_cal_supported(ah, chan, ADC_GAIN_CAL)) {
INIT_CAL(&ah->adcgain_caldata);
INSERT_CAL(ah, &ah->adcgain_caldata);
ath_dbg(common, ATH_DBG_CALIBRATE,
- "enabling ADC Gain Calibration.\n");
+ "enabling ADC Gain Calibration.\n");
+ }
+ if (ar9002_hw_is_cal_supported(ah, chan, ADC_DC_CAL)) {
INIT_CAL(&ah->adcdc_caldata);
INSERT_CAL(ah, &ah->adcdc_caldata);
ath_dbg(common, ATH_DBG_CALIBRATE,
- "enabling ADC DC Calibration.\n");
+ "enabling ADC DC Calibration.\n");
}
- INIT_CAL(&ah->iq_caldata);
- INSERT_CAL(ah, &ah->iq_caldata);
- ath_dbg(common, ATH_DBG_CALIBRATE,
- "enabling IQ Calibration.\n");
+ if (ar9002_hw_is_cal_supported(ah, chan, IQ_MISMATCH_CAL)) {
+ INIT_CAL(&ah->iq_caldata);
+ INSERT_CAL(ah, &ah->iq_caldata);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "enabling IQ Calibration.\n");
+ }
ah->cal_list_curr = ah->cal_list;
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index 399ab3bb299..7a332f16b79 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -290,7 +290,6 @@ static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
| (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
| SM(txPower, AR_XmitPower)
| (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
- | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
| (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
| (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
@@ -311,6 +310,16 @@ static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
}
}
+static void ar9002_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val)
+{
+ struct ar5416_desc *ads = AR5416DESC(ds);
+
+ if (val)
+ ads->ds_ctl0 |= AR_ClrDestMask;
+ else
+ ads->ds_ctl0 &= ~AR_ClrDestMask;
+}
+
static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
void *lastds,
u32 durUpdateEn, u32 rtsctsRate,
@@ -406,26 +415,6 @@ static void ar9002_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
}
-static void ar9002_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
- u32 burstDuration)
-{
- struct ar5416_desc *ads = AR5416DESC(ds);
-
- ads->ds_ctl2 &= ~AR_BurstDur;
- ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
-}
-
-static void ar9002_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
- u32 vmf)
-{
- struct ar5416_desc *ads = AR5416DESC(ds);
-
- if (vmf)
- ads->ds_ctl0 |= AR_VirtMoreFrag;
- else
- ads->ds_ctl0 &= ~AR_VirtMoreFrag;
-}
-
void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
u32 size, u32 flags)
{
@@ -458,6 +447,5 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle;
ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last;
ops->clr11n_aggr = ar9002_hw_clr11n_aggr;
- ops->set11n_burstduration = ar9002_hw_set11n_burstduration;
- ops->set11n_virtualmorefrag = ar9002_hw_set11n_virtualmorefrag;
+ ops->set_clrdmask = ar9002_hw_set_clrdmask;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index 7d68d61e406..a57e963cf0d 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -517,23 +517,7 @@ static void ar9002_hw_set_nf_limits(struct ath_hw *ah)
}
}
-void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
-{
- struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
-
- priv_ops->set_rf_regs = NULL;
- priv_ops->rf_alloc_ext_banks = NULL;
- priv_ops->rf_free_ext_banks = NULL;
- priv_ops->rf_set_freq = ar9002_hw_set_channel;
- priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
- priv_ops->olc_init = ar9002_olc_init;
- priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
- priv_ops->do_getnf = ar9002_hw_do_getnf;
-
- ar9002_hw_set_nf_limits(ah);
-}
-
-void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
+static void ar9002_hw_antdiv_comb_conf_get(struct ath_hw *ah,
struct ath_hw_antcomb_conf *antconf)
{
u32 regval;
@@ -545,10 +529,11 @@ void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
AR_PHY_9285_ANT_DIV_ALT_LNACONF_S;
antconf->fast_div_bias = (regval & AR_PHY_9285_FAST_DIV_BIAS) >>
AR_PHY_9285_FAST_DIV_BIAS_S;
+ antconf->lna1_lna2_delta = -3;
+ antconf->div_group = 0;
}
-EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_get);
-void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
+static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah,
struct ath_hw_antcomb_conf *antconf)
{
u32 regval;
@@ -566,4 +551,23 @@ void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval);
}
-EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_set);
+
+void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
+{
+ struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+ struct ath_hw_ops *ops = ath9k_hw_ops(ah);
+
+ priv_ops->set_rf_regs = NULL;
+ priv_ops->rf_alloc_ext_banks = NULL;
+ priv_ops->rf_free_ext_banks = NULL;
+ priv_ops->rf_set_freq = ar9002_hw_set_channel;
+ priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
+ priv_ops->olc_init = ar9002_olc_init;
+ priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
+ priv_ops->do_getnf = ar9002_hw_do_getnf;
+
+ ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get;
+ ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set;
+
+ ar9002_hw_set_nf_limits(ah);
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
index 37663dbbcf5..47780ef1c89 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
@@ -483,7 +483,11 @@
#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000
#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19
+#define AR_PHY_TX_PWRCTRL8 0xa278
+
#define AR_PHY_TX_PWRCTRL9 0xa27C
+
+#define AR_PHY_TX_PWRCTRL10 0xa394
#define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00
#define AR_PHY_TX_DESIRED_SCALE_CCK_S 10
#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000
@@ -495,6 +499,8 @@
#define AR_PHY_CH0_TX_PWRCTRL11 0xa398
#define AR_PHY_CH1_TX_PWRCTRL11 0xb398
+#define AR_PHY_CH0_TX_PWRCTRL12 0xa3dc
+#define AR_PHY_CH0_TX_PWRCTRL13 0xa3e0
#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00
#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index 9ecca93392e..f915a3dbfca 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -34,10 +34,10 @@ static const u32 ar9300_2p2_radio_postamble[][5] = {
static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
- {0x0000a2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
- {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
- {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
- {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+ {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+ {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+ {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
@@ -119,14 +119,14 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
{0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
{0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
{0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
- {0x0000b2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
- {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
- {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
- {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000c2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
- {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
- {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
- {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+ {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+ {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+ {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+ {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+ {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+ {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+ {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
{0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
@@ -835,10 +835,10 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
- {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
- {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
- {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
- {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
+ {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
+ {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+ {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
{0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
{0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
{0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
@@ -920,14 +920,14 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
{0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
{0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
{0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
- {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
- {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
- {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
- {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
- {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
- {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
- {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
+ {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
+ {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+ {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+ {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
+ {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
+ {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+ {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
{0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
{0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
{0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
@@ -941,10 +941,10 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
- {0x0000a2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800},
- {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000},
- {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000},
- {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
+ {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
+ {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
+ {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
{0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
{0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
{0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
@@ -1026,14 +1026,14 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
{0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
{0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
{0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
- {0x0000b2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800},
- {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000},
- {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000},
- {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000c2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800},
- {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000},
- {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000},
- {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
+ {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
+ {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
+ {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+ {0x0000c2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
+ {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
+ {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
+ {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
{0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
{0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
@@ -1307,10 +1307,10 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
- {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
- {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
- {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
- {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+ {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+ {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+ {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
@@ -1329,21 +1329,21 @@ static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = {
{0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
{0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
- {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
- {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
- {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83},
- {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84},
- {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3},
- {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5},
- {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9},
- {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb},
- {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
- {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
- {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
- {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
- {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
- {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
- {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
+ {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
+ {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
+ {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
+ {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
+ {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
+ {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
+ {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
+ {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
+ {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
@@ -1361,45 +1361,45 @@ static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = {
{0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
- {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
- {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
- {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83},
- {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84},
- {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3},
- {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5},
- {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9},
- {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb},
- {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
- {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
- {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
- {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
- {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
- {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
- {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
+ {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
+ {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
+ {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
+ {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
+ {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
+ {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
+ {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
+ {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
+ {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
- {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
- {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
- {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
- {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
- {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
- {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
- {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
- {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
- {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
- {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
- {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
- {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
- {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
- {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
- {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
- {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
- {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
+ {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
+ {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
+ {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
+ {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
+ {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
+ {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+ {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+ {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+ {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+ {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+ {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+ {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+ {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+ {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+ {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+ {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+ {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+ {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
{0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 4a4cd88429c..f276cb922b4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -18,13 +18,13 @@
#include "hw-ops.h"
#include "ar9003_phy.h"
-#define MPASS 3
#define MAX_MEASUREMENT 8
-#define MAX_DIFFERENCE 10
+#define MAX_MAG_DELTA 11
+#define MAX_PHS_DELTA 10
struct coeff {
- int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
- int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
+ int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
+ int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
int iqc_coeff[2];
};
@@ -185,17 +185,19 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
/* Accumulate IQ cal measures for active chains */
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- ah->totalPowerMeasI[i] +=
- REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
- ah->totalPowerMeasQ[i] +=
- REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
- ah->totalIqCorrMeas[i] +=
- (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
- ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
- "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
- ah->cal_samples, i, ah->totalPowerMeasI[i],
- ah->totalPowerMeasQ[i],
- ah->totalIqCorrMeas[i]);
+ if (ah->txchainmask & BIT(i)) {
+ ah->totalPowerMeasI[i] +=
+ REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+ ah->totalPowerMeasQ[i] +=
+ REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+ ah->totalIqCorrMeas[i] +=
+ (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+ "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+ ah->cal_samples, i, ah->totalPowerMeasI[i],
+ ah->totalPowerMeasQ[i],
+ ah->totalIqCorrMeas[i]);
+ }
}
}
@@ -608,36 +610,48 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
return true;
}
-static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg)
+static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
+ int max_delta)
{
- int diff[MPASS];
-
- diff[0] = abs(mp_coeff[0] - mp_coeff[1]);
- diff[1] = abs(mp_coeff[1] - mp_coeff[2]);
- diff[2] = abs(mp_coeff[2] - mp_coeff[0]);
-
- if (diff[0] > MAX_DIFFERENCE &&
- diff[1] > MAX_DIFFERENCE &&
- diff[2] > MAX_DIFFERENCE)
- return false;
+ int mp_max = -64, max_idx = 0;
+ int mp_min = 63, min_idx = 0;
+ int mp_avg = 0, i, outlier_idx = 0;
+
+ /* find min/max mismatch across all calibrated gains */
+ for (i = 0; i < nmeasurement; i++) {
+ mp_avg += mp_coeff[i];
+ if (mp_coeff[i] > mp_max) {
+ mp_max = mp_coeff[i];
+ max_idx = i;
+ } else if (mp_coeff[i] < mp_min) {
+ mp_min = mp_coeff[i];
+ min_idx = i;
+ }
+ }
- if (diff[0] <= diff[1] && diff[0] <= diff[2])
- *mp_avg = (mp_coeff[0] + mp_coeff[1]) / 2;
- else if (diff[1] <= diff[2])
- *mp_avg = (mp_coeff[1] + mp_coeff[2]) / 2;
- else
- *mp_avg = (mp_coeff[2] + mp_coeff[0]) / 2;
+ /* find average (exclude max abs value) */
+ for (i = 0; i < nmeasurement; i++) {
+ if ((abs(mp_coeff[i]) < abs(mp_max)) ||
+ (abs(mp_coeff[i]) < abs(mp_min)))
+ mp_avg += mp_coeff[i];
+ }
+ mp_avg /= (nmeasurement - 1);
- return true;
+ /* detect outlier */
+ if (abs(mp_max - mp_min) > max_delta) {
+ if (abs(mp_max - mp_avg) > abs(mp_min - mp_avg))
+ outlier_idx = max_idx;
+ else
+ outlier_idx = min_idx;
+ }
+ mp_coeff[outlier_idx] = mp_avg;
}
static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
u8 num_chains,
struct coeff *coeff)
{
- struct ath_common *common = ath9k_hw_common(ah);
int i, im, nmeasurement;
- int magnitude, phase;
u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
@@ -657,37 +671,28 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
/* Load the average of 2 passes */
for (i = 0; i < num_chains; i++) {
- if (AR_SREV_9485(ah))
- nmeasurement = REG_READ_FIELD(ah,
- AR_PHY_TX_IQCAL_STATUS_B0_9485,
- AR_PHY_CALIBRATED_GAINS_0);
- else
- nmeasurement = REG_READ_FIELD(ah,
- AR_PHY_TX_IQCAL_STATUS_B0,
- AR_PHY_CALIBRATED_GAINS_0);
+ nmeasurement = REG_READ_FIELD(ah,
+ AR_PHY_TX_IQCAL_STATUS_B0,
+ AR_PHY_CALIBRATED_GAINS_0);
if (nmeasurement > MAX_MEASUREMENT)
nmeasurement = MAX_MEASUREMENT;
- for (im = 0; im < nmeasurement; im++) {
- /*
- * Determine which 2 passes are closest and compute avg
- * magnitude
- */
- if (!ar9003_hw_compute_closest_pass_and_avg(coeff->mag_coeff[i][im],
- &magnitude))
- goto disable_txiqcal;
+ /* detect outlier only if nmeasurement > 1 */
+ if (nmeasurement > 1) {
+ /* Detect magnitude outlier */
+ ar9003_hw_detect_outlier(coeff->mag_coeff[i],
+ nmeasurement, MAX_MAG_DELTA);
- /*
- * Determine which 2 passes are closest and compute avg
- * phase
- */
- if (!ar9003_hw_compute_closest_pass_and_avg(coeff->phs_coeff[i][im],
- &phase))
- goto disable_txiqcal;
+ /* Detect phase outlier */
+ ar9003_hw_detect_outlier(coeff->phs_coeff[i],
+ nmeasurement, MAX_PHS_DELTA);
+ }
+
+ for (im = 0; im < nmeasurement; im++) {
- coeff->iqc_coeff[0] = (magnitude & 0x7f) |
- ((phase & 0x7f) << 7);
+ coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) |
+ ((coeff->phs_coeff[i][im] & 0x7f) << 7);
if ((im % 2) == 0)
REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
@@ -707,141 +712,37 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
return;
-disable_txiqcal:
- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
- AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x0);
- REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
- AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x0);
-
- ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n");
}
-static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
+static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- static const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
- AR_PHY_TX_IQCAL_STATUS_B0,
- AR_PHY_TX_IQCAL_STATUS_B1,
- AR_PHY_TX_IQCAL_STATUS_B2,
- };
- static const u32 chan_info_tab[] = {
- AR_PHY_CHAN_INFO_TAB_0,
- AR_PHY_CHAN_INFO_TAB_1,
- AR_PHY_CHAN_INFO_TAB_2,
- };
- struct coeff coeff;
- s32 iq_res[6];
- s32 i, j, ip, im, nmeasurement;
- u8 nchains = get_streams(common->tx_chainmask);
-
- for (ip = 0; ip < MPASS; ip++) {
- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
- AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
- DELPT);
- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
- AR_PHY_TX_IQCAL_START_DO_CAL,
- AR_PHY_TX_IQCAL_START_DO_CAL);
-
- if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
- AR_PHY_TX_IQCAL_START_DO_CAL,
- 0, AH_WAIT_TIMEOUT)) {
- ath_dbg(common, ATH_DBG_CALIBRATE,
- "Tx IQ Cal not complete.\n");
- goto TX_IQ_CAL_FAILED;
- }
-
- nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0,
- AR_PHY_CALIBRATED_GAINS_0);
- if (nmeasurement > MAX_MEASUREMENT)
- nmeasurement = MAX_MEASUREMENT;
-
- for (i = 0; i < nchains; i++) {
- ath_dbg(common, ATH_DBG_CALIBRATE,
- "Doing Tx IQ Cal for chain %d.\n", i);
- for (im = 0; im < nmeasurement; im++) {
- if (REG_READ(ah, txiqcal_status[i]) &
- AR_PHY_TX_IQCAL_STATUS_FAILED) {
- ath_dbg(common, ATH_DBG_CALIBRATE,
- "Tx IQ Cal failed for chain %d.\n", i);
- goto TX_IQ_CAL_FAILED;
- }
-
- for (j = 0; j < 3; j++) {
- u8 idx = 2 * j,
- offset = 4 * (3 * im + j);
-
- REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
- AR_PHY_CHAN_INFO_TAB_S2_READ,
- 0);
-
- /* 32 bits */
- iq_res[idx] = REG_READ(ah,
- chan_info_tab[i] +
- offset);
-
- REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
- AR_PHY_CHAN_INFO_TAB_S2_READ,
- 1);
-
- /* 16 bits */
- iq_res[idx+1] = 0xffff & REG_READ(ah,
- chan_info_tab[i] +
- offset);
-
- ath_dbg(common, ATH_DBG_CALIBRATE,
- "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
- idx, iq_res[idx], idx+1, iq_res[idx+1]);
- }
-
- if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
- coeff.iqc_coeff)) {
- ath_dbg(common, ATH_DBG_CALIBRATE,
- "Failed in calculation of IQ correction.\n");
- goto TX_IQ_CAL_FAILED;
- }
- coeff.mag_coeff[i][im][ip] =
- coeff.iqc_coeff[0] & 0x7f;
- coeff.phs_coeff[i][im][ip] =
- (coeff.iqc_coeff[0] >> 7) & 0x7f;
-
- if (coeff.mag_coeff[i][im][ip] > 63)
- coeff.mag_coeff[i][im][ip] -= 128;
- if (coeff.phs_coeff[i][im][ip] > 63)
- coeff.phs_coeff[i][im][ip] -= 128;
-
- }
- }
- }
-
- ar9003_hw_tx_iqcal_load_avg_2_passes(ah, nchains, &coeff);
-
- return;
-
-TX_IQ_CAL_FAILED:
- ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
-}
-
-static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
-{
u8 tx_gain_forced;
- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1_9485,
- AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT);
tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
AR_PHY_TXGAIN_FORCE);
if (tx_gain_forced)
REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
AR_PHY_TXGAIN_FORCE, 0);
- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START_9485,
- AR_PHY_TX_IQCAL_START_DO_CAL_9485, 1);
+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
+ AR_PHY_TX_IQCAL_START_DO_CAL, 1);
+
+ if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
+ AR_PHY_TX_IQCAL_START_DO_CAL, 0,
+ AH_WAIT_TIMEOUT)) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Tx IQ Cal is not completed.\n");
+ return false;
+ }
+ return true;
}
static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
- AR_PHY_TX_IQCAL_STATUS_B0_9485,
+ AR_PHY_TX_IQCAL_STATUS_B0,
AR_PHY_TX_IQCAL_STATUS_B1,
AR_PHY_TX_IQCAL_STATUS_B2,
};
@@ -853,7 +754,7 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
struct coeff coeff;
s32 iq_res[6];
u8 num_chains = 0;
- int i, ip, im, j;
+ int i, im, j;
int nmeasurement;
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
@@ -861,71 +762,69 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
num_chains++;
}
- for (ip = 0; ip < MPASS; ip++) {
- for (i = 0; i < num_chains; i++) {
- nmeasurement = REG_READ_FIELD(ah,
- AR_PHY_TX_IQCAL_STATUS_B0_9485,
- AR_PHY_CALIBRATED_GAINS_0);
- if (nmeasurement > MAX_MEASUREMENT)
- nmeasurement = MAX_MEASUREMENT;
+ for (i = 0; i < num_chains; i++) {
+ nmeasurement = REG_READ_FIELD(ah,
+ AR_PHY_TX_IQCAL_STATUS_B0,
+ AR_PHY_CALIBRATED_GAINS_0);
+ if (nmeasurement > MAX_MEASUREMENT)
+ nmeasurement = MAX_MEASUREMENT;
- for (im = 0; im < nmeasurement; im++) {
- ath_dbg(common, ATH_DBG_CALIBRATE,
- "Doing Tx IQ Cal for chain %d.\n", i);
+ for (im = 0; im < nmeasurement; im++) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Doing Tx IQ Cal for chain %d.\n", i);
- if (REG_READ(ah, txiqcal_status[i]) &
- AR_PHY_TX_IQCAL_STATUS_FAILED) {
- ath_dbg(common, ATH_DBG_CALIBRATE,
+ if (REG_READ(ah, txiqcal_status[i]) &
+ AR_PHY_TX_IQCAL_STATUS_FAILED) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
"Tx IQ Cal failed for chain %d.\n", i);
- goto tx_iqcal_fail;
- }
+ goto tx_iqcal_fail;
+ }
- for (j = 0; j < 3; j++) {
- u32 idx = 2 * j, offset = 4 * (3 * im + j);
+ for (j = 0; j < 3; j++) {
+ u32 idx = 2 * j, offset = 4 * (3 * im + j);
- REG_RMW_FIELD(ah,
+ REG_RMW_FIELD(ah,
AR_PHY_CHAN_INFO_MEMORY,
AR_PHY_CHAN_INFO_TAB_S2_READ,
0);
- /* 32 bits */
- iq_res[idx] = REG_READ(ah,
- chan_info_tab[i] +
- offset);
+ /* 32 bits */
+ iq_res[idx] = REG_READ(ah,
+ chan_info_tab[i] +
+ offset);
- REG_RMW_FIELD(ah,
+ REG_RMW_FIELD(ah,
AR_PHY_CHAN_INFO_MEMORY,
AR_PHY_CHAN_INFO_TAB_S2_READ,
1);
- /* 16 bits */
- iq_res[idx + 1] = 0xffff & REG_READ(ah,
- chan_info_tab[i] + offset);
+ /* 16 bits */
+ iq_res[idx + 1] = 0xffff & REG_READ(ah,
+ chan_info_tab[i] + offset);
- ath_dbg(common, ATH_DBG_CALIBRATE,
- "IQ RES[%d]=0x%x"
- "IQ_RES[%d]=0x%x\n",
- idx, iq_res[idx], idx + 1,
- iq_res[idx + 1]);
- }
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "IQ RES[%d]=0x%x"
+ "IQ_RES[%d]=0x%x\n",
+ idx, iq_res[idx], idx + 1,
+ iq_res[idx + 1]);
+ }
- if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
- coeff.iqc_coeff)) {
- ath_dbg(common, ATH_DBG_CALIBRATE,
- "Failed in calculation of IQ correction.\n");
- goto tx_iqcal_fail;
- }
+ if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
+ coeff.iqc_coeff)) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Failed in calculation of \
+ IQ correction.\n");
+ goto tx_iqcal_fail;
+ }
- coeff.mag_coeff[i][im][ip] =
- coeff.iqc_coeff[0] & 0x7f;
- coeff.phs_coeff[i][im][ip] =
- (coeff.iqc_coeff[0] >> 7) & 0x7f;
+ coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
+ coeff.phs_coeff[i][im] =
+ (coeff.iqc_coeff[0] >> 7) & 0x7f;
- if (coeff.mag_coeff[i][im][ip] > 63)
- coeff.mag_coeff[i][im][ip] -= 128;
- if (coeff.phs_coeff[i][im][ip] > 63)
- coeff.phs_coeff[i][im][ip] -= 128;
- }
+ if (coeff.mag_coeff[i][im] > 63)
+ coeff.mag_coeff[i][im] -= 128;
+ if (coeff.phs_coeff[i][im] > 63)
+ coeff.phs_coeff[i][im] -= 128;
}
}
ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff);
@@ -940,31 +839,37 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
struct ath9k_channel *chan)
{
struct ath_common *common = ath9k_hw_common(ah);
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
int val;
+ bool txiqcal_done = false;
val = REG_READ(ah, AR_ENT_OTP);
ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val);
- if (AR_SREV_9485(ah))
- ar9003_hw_set_chain_masks(ah, 0x1, 0x1);
- else if (val & AR_ENT_OTP_CHAIN2_DISABLE)
+ /* Configure rx/tx chains before running AGC/TxiQ cals */
+ if (val & AR_ENT_OTP_CHAIN2_DISABLE)
ar9003_hw_set_chain_masks(ah, 0x3, 0x3);
else
- /*
- * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain
- * mode before running AGC/TxIQ cals
- */
- ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
+ ar9003_hw_set_chain_masks(ah, pCap->rx_chainmask,
+ pCap->tx_chainmask);
/* Do Tx IQ Calibration */
- if (AR_SREV_9485(ah))
- ar9003_hw_tx_iq_cal_run(ah);
- else
- ar9003_hw_tx_iq_cal(ah);
+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
+ AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
+ DELPT);
- REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
- udelay(5);
- REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+ /*
+ * For AR9485 or later chips, TxIQ cal runs as part of
+ * AGC calibration
+ */
+ if (AR_SREV_9485_OR_LATER(ah))
+ txiqcal_done = true;
+ else {
+ txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
+ REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
+ udelay(5);
+ REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+ }
/* Calibrate the AGC */
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
@@ -979,7 +884,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
return false;
}
- if (AR_SREV_9485(ah))
+ if (txiqcal_done)
ar9003_hw_tx_iq_cal_post_proc(ah);
/* Revert chainmasks to their original values before NF cal */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 6eadf975ae4..1e220354e4b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -652,7 +652,7 @@ static const struct ar9300_eeprom ar9300_x113 = {
.regDmn = { LE16(0), LE16(0x1f) },
.txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
.opCapFlags = {
- .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
+ .opFlags = AR5416_OPFLAGS_11A,
.eepMisc = 0,
},
.rfSilent = 0,
@@ -922,7 +922,7 @@ static const struct ar9300_eeprom ar9300_x113 = {
.db_stage2 = {3, 3, 3}, /* 3 chain */
.db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
.db_stage4 = {3, 3, 3}, /* don't exist for 2G */
- .xpaBiasLvl = 0,
+ .xpaBiasLvl = 0xf,
.txFrameToDataStart = 0x0e,
.txFrameToPaOn = 0x0e,
.txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
@@ -3217,7 +3217,6 @@ static int ar9300_compress_decision(struct ath_hw *ah,
u8 *word, int length, int mdata_size)
{
struct ath_common *common = ath9k_hw_common(ah);
- u8 *dptr;
const struct ar9300_eeprom *eep = NULL;
switch (code) {
@@ -3235,7 +3234,6 @@ static int ar9300_compress_decision(struct ath_hw *ah,
break;
case _CompressBlock:
if (reference == 0) {
- dptr = mptr;
} else {
eep = ar9003_eeprom_struct_find_by_id(reference);
if (eep == NULL) {
@@ -3444,13 +3442,15 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
{
int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
- if (AR_SREV_9485(ah))
+ if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
else {
REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
- REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB,
- bias >> 2);
- REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1);
+ REG_RMW_FIELD(ah, AR_CH0_THERM,
+ AR_CH0_THERM_XPABIASLVL_MSB,
+ bias >> 2);
+ REG_RMW_FIELD(ah, AR_CH0_THERM,
+ AR_CH0_THERM_XPASHORT2GND, 1);
}
}
@@ -3497,34 +3497,77 @@ static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
{
+ int chain;
+ u32 regval;
+ u32 ant_div_ctl1;
+ static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
+ AR_PHY_SWITCH_CHAIN_0,
+ AR_PHY_SWITCH_CHAIN_1,
+ AR_PHY_SWITCH_CHAIN_2,
+ };
+
u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
+
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
- value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
- REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
-
- if (!AR_SREV_9485(ah)) {
- value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
- REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL,
- value);
-
- value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
- REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL,
- value);
+ for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
+ if ((ah->rxchainmask & BIT(chain)) ||
+ (ah->txchainmask & BIT(chain))) {
+ value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
+ is2ghz);
+ REG_RMW_FIELD(ah, switch_chain_reg[chain],
+ AR_SWITCH_TABLE_ALL, value);
+ }
}
if (AR_SREV_9485(ah)) {
value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
- REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_CTRL_ALL,
- value);
- REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_ENABLE,
- value >> 6);
- REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, AR_FAST_DIV_ENABLE,
- value >> 7);
+ /*
+ * main_lnaconf, alt_lnaconf, main_tb, alt_tb
+ * are the fields present
+ */
+ regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+ regval &= (~AR_ANT_DIV_CTRL_ALL);
+ regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
+ /* enable_lnadiv */
+ regval &= (~AR_PHY_9485_ANT_DIV_LNADIV);
+ regval |= ((value >> 6) & 0x1) <<
+ AR_PHY_9485_ANT_DIV_LNADIV_S;
+ REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
+
+ /*enable fast_div */
+ regval = REG_READ(ah, AR_PHY_CCK_DETECT);
+ regval &= (~AR_FAST_DIV_ENABLE);
+ regval |= ((value >> 7) & 0x1) <<
+ AR_FAST_DIV_ENABLE_S;
+ REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
+ ant_div_ctl1 =
+ ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
+ /* check whether antenna diversity is enabled */
+ if ((ant_div_ctl1 >> 0x6) == 0x3) {
+ regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+ /*
+ * clear bits 25-30 main_lnaconf, alt_lnaconf,
+ * main_tb, alt_tb
+ */
+ regval &= (~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
+ AR_PHY_9485_ANT_DIV_ALT_LNACONF |
+ AR_PHY_9485_ANT_DIV_ALT_GAINTB |
+ AR_PHY_9485_ANT_DIV_MAIN_GAINTB));
+ /* by default use LNA1 for the main antenna */
+ regval |= (AR_PHY_9485_ANT_DIV_LNA1 <<
+ AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S);
+ regval |= (AR_PHY_9485_ANT_DIV_LNA2 <<
+ AR_PHY_9485_ANT_DIV_ALT_LNACONF_S);
+ REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
+ }
+
+
}
+
}
static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
@@ -3634,13 +3677,16 @@ static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
/* Test value. if 0 then attenuation is unused. Don't load anything. */
for (i = 0; i < 3; i++) {
- value = ar9003_hw_atten_chain_get(ah, i, chan);
- REG_RMW_FIELD(ah, ext_atten_reg[i],
- AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
-
- value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
- REG_RMW_FIELD(ah, ext_atten_reg[i],
- AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value);
+ if (ah->txchainmask & BIT(i)) {
+ value = ar9003_hw_atten_chain_get(ah, i, chan);
+ REG_RMW_FIELD(ah, ext_atten_reg[i],
+ AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
+
+ value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
+ REG_RMW_FIELD(ah, ext_atten_reg[i],
+ AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
+ value);
+ }
}
}
@@ -3749,8 +3795,9 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
ar9003_hw_drive_strength_apply(ah);
ar9003_hw_atten_apply(ah, chan);
- ar9003_hw_internal_regulator_apply(ah);
- if (AR_SREV_9485(ah))
+ if (!AR_SREV_9340(ah))
+ ar9003_hw_internal_regulator_apply(ah);
+ if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
ar9003_hw_apply_tuning_caps(ah);
}
@@ -3994,6 +4041,16 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
);
+ /* Write the power for duplicated frames - HT40 */
+
+ /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
+ REG_WRITE(ah, 0xa3e0,
+ POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
+ POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
+ POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
+ POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
+ );
+
/* Write the HT20 power per rate set */
/* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 7f5de6e4448..a55eddbb258 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -18,6 +18,7 @@
#include "ar9003_mac.h"
#include "ar9003_2p2_initvals.h"
#include "ar9485_initvals.h"
+#include "ar9340_initvals.h"
/* General hardware code for the AR9003 hadware family */
@@ -28,109 +29,105 @@
*/
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
{
- if (AR_SREV_9485_11(ah)) {
+ if (AR_SREV_9340(ah)) {
/* mac */
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
- ar9485_1_1_mac_core,
- ARRAY_SIZE(ar9485_1_1_mac_core), 2);
+ ar9340_1p0_mac_core,
+ ARRAY_SIZE(ar9340_1p0_mac_core), 2);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
- ar9485_1_1_mac_postamble,
- ARRAY_SIZE(ar9485_1_1_mac_postamble), 5);
+ ar9340_1p0_mac_postamble,
+ ARRAY_SIZE(ar9340_1p0_mac_postamble), 5);
/* bb */
- INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1,
- ARRAY_SIZE(ar9485_1_1), 2);
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
- ar9485_1_1_baseband_core,
- ARRAY_SIZE(ar9485_1_1_baseband_core), 2);
+ ar9340_1p0_baseband_core,
+ ARRAY_SIZE(ar9340_1p0_baseband_core), 2);
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
- ar9485_1_1_baseband_postamble,
- ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5);
+ ar9340_1p0_baseband_postamble,
+ ARRAY_SIZE(ar9340_1p0_baseband_postamble), 5);
/* radio */
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
- ar9485_1_1_radio_core,
- ARRAY_SIZE(ar9485_1_1_radio_core), 2);
+ ar9340_1p0_radio_core,
+ ARRAY_SIZE(ar9340_1p0_radio_core), 2);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
- ar9485_1_1_radio_postamble,
- ARRAY_SIZE(ar9485_1_1_radio_postamble), 2);
+ ar9340_1p0_radio_postamble,
+ ARRAY_SIZE(ar9340_1p0_radio_postamble), 5);
/* soc */
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
- ar9485_1_1_soc_preamble,
- ARRAY_SIZE(ar9485_1_1_soc_preamble), 2);
+ ar9340_1p0_soc_preamble,
+ ARRAY_SIZE(ar9340_1p0_soc_preamble), 2);
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
- INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
+ ar9340_1p0_soc_postamble,
+ ARRAY_SIZE(ar9340_1p0_soc_postamble), 5);
/* rx/tx gain */
INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9485_common_rx_gain_1_1,
- ARRAY_SIZE(ar9485_common_rx_gain_1_1), 2);
+ ar9340Common_wo_xlna_rx_gain_table_1p0,
+ ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
+ 5);
INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9485_modes_lowest_ob_db_tx_gain_1_1,
- ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
+ ar9340Modes_high_ob_db_tx_gain_table_1p0,
+ ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0),
5);
- /* Load PCIE SERDES settings from INI */
-
- /* Awake Setting */
-
- INIT_INI_ARRAY(&ah->iniPcieSerdes,
- ar9485_1_1_pcie_phy_clkreq_disable_L1,
- ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
- 2);
-
- /* Sleep Setting */
+ INIT_INI_ARRAY(&ah->iniModesAdditional,
+ ar9340Modes_fast_clock_1p0,
+ ARRAY_SIZE(ar9340Modes_fast_clock_1p0),
+ 3);
- INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
- ar9485_1_1_pcie_phy_clkreq_disable_L1,
- ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
+ INIT_INI_ARRAY(&ah->iniModesAdditional_40M,
+ ar9340_1p0_radio_core_40M,
+ ARRAY_SIZE(ar9340_1p0_radio_core_40M),
2);
- } else if (AR_SREV_9485(ah)) {
+ } else if (AR_SREV_9485_11(ah)) {
/* mac */
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
- ar9485_1_0_mac_core,
- ARRAY_SIZE(ar9485_1_0_mac_core), 2);
+ ar9485_1_1_mac_core,
+ ARRAY_SIZE(ar9485_1_1_mac_core), 2);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
- ar9485_1_0_mac_postamble,
- ARRAY_SIZE(ar9485_1_0_mac_postamble), 5);
+ ar9485_1_1_mac_postamble,
+ ARRAY_SIZE(ar9485_1_1_mac_postamble), 5);
/* bb */
- INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_0,
- ARRAY_SIZE(ar9485_1_0), 2);
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1,
+ ARRAY_SIZE(ar9485_1_1), 2);
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
- ar9485_1_0_baseband_core,
- ARRAY_SIZE(ar9485_1_0_baseband_core), 2);
+ ar9485_1_1_baseband_core,
+ ARRAY_SIZE(ar9485_1_1_baseband_core), 2);
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
- ar9485_1_0_baseband_postamble,
- ARRAY_SIZE(ar9485_1_0_baseband_postamble), 5);
+ ar9485_1_1_baseband_postamble,
+ ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5);
/* radio */
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
- ar9485_1_0_radio_core,
- ARRAY_SIZE(ar9485_1_0_radio_core), 2);
+ ar9485_1_1_radio_core,
+ ARRAY_SIZE(ar9485_1_1_radio_core), 2);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
- ar9485_1_0_radio_postamble,
- ARRAY_SIZE(ar9485_1_0_radio_postamble), 2);
+ ar9485_1_1_radio_postamble,
+ ARRAY_SIZE(ar9485_1_1_radio_postamble), 2);
/* soc */
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
- ar9485_1_0_soc_preamble,
- ARRAY_SIZE(ar9485_1_0_soc_preamble), 2);
+ ar9485_1_1_soc_preamble,
+ ARRAY_SIZE(ar9485_1_1_soc_preamble), 2);
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0);
/* rx/tx gain */
INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9485Common_rx_gain_1_0,
- ARRAY_SIZE(ar9485Common_rx_gain_1_0), 2);
+ ar9485Common_wo_xlna_rx_gain_1_1,
+ ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 2);
INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9485Modes_lowest_ob_db_tx_gain_1_0,
- ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
+ ar9485_modes_lowest_ob_db_tx_gain_1_1,
+ ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
5);
/* Load PCIE SERDES settings from INI */
@@ -138,15 +135,15 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
/* Awake Setting */
INIT_INI_ARRAY(&ah->iniPcieSerdes,
- ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1,
- ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1),
+ ar9485_1_1_pcie_phy_clkreq_disable_L1,
+ ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
2);
/* Sleep Setting */
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
- ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1,
- ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1),
+ ar9485_1_1_pcie_phy_clkreq_disable_L1,
+ ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
2);
} else {
/* mac */
@@ -223,15 +220,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
switch (ar9003_hw_get_tx_gain_idx(ah)) {
case 0:
default:
- if (AR_SREV_9485_11(ah))
+ if (AR_SREV_9340(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9485_modes_lowest_ob_db_tx_gain_1_1,
- ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
+ ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+ ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
5);
- else if (AR_SREV_9485(ah))
+ else if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9485Modes_lowest_ob_db_tx_gain_1_0,
- ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
+ ar9485_modes_lowest_ob_db_tx_gain_1_1,
+ ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
5);
else
INIT_INI_ARRAY(&ah->iniModesTxGain,
@@ -240,15 +237,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
5);
break;
case 1:
- if (AR_SREV_9485_11(ah))
+ if (AR_SREV_9340(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9485Modes_high_ob_db_tx_gain_1_1,
- ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
+ ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+ ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
5);
- else if (AR_SREV_9485(ah))
+ else if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9485Modes_high_ob_db_tx_gain_1_0,
- ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_0),
+ ar9485Modes_high_ob_db_tx_gain_1_1,
+ ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
5);
else
INIT_INI_ARRAY(&ah->iniModesTxGain,
@@ -257,15 +254,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
5);
break;
case 2:
- if (AR_SREV_9485_11(ah))
+ if (AR_SREV_9340(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9485Modes_low_ob_db_tx_gain_1_1,
- ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
+ ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+ ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
5);
- else if (AR_SREV_9485(ah))
+ else if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9485Modes_low_ob_db_tx_gain_1_0,
- ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_0),
+ ar9485Modes_low_ob_db_tx_gain_1_1,
+ ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
5);
else
INIT_INI_ARRAY(&ah->iniModesTxGain,
@@ -274,15 +271,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
5);
break;
case 3:
- if (AR_SREV_9485_11(ah))
+ if (AR_SREV_9340(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9485Modes_high_power_tx_gain_1_1,
- ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
+ ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+ ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
5);
- else if (AR_SREV_9485(ah))
+ else if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9485Modes_high_power_tx_gain_1_0,
- ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_0),
+ ar9485Modes_high_power_tx_gain_1_1,
+ ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
5);
else
INIT_INI_ARRAY(&ah->iniModesTxGain,
@@ -298,15 +295,15 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
switch (ar9003_hw_get_rx_gain_idx(ah)) {
case 0:
default:
- if (AR_SREV_9485_11(ah))
+ if (AR_SREV_9340(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9485_common_rx_gain_1_1,
- ARRAY_SIZE(ar9485_common_rx_gain_1_1),
+ ar9340Common_rx_gain_table_1p0,
+ ARRAY_SIZE(ar9340Common_rx_gain_table_1p0),
2);
- else if (AR_SREV_9485(ah))
+ else if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9485Common_rx_gain_1_0,
- ARRAY_SIZE(ar9485Common_rx_gain_1_0),
+ ar9485Common_wo_xlna_rx_gain_1_1,
+ ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
2);
else
INIT_INI_ARRAY(&ah->iniModesRxGain,
@@ -315,15 +312,15 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
2);
break;
case 1:
- if (AR_SREV_9485_11(ah))
+ if (AR_SREV_9340(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9485Common_wo_xlna_rx_gain_1_1,
- ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
+ ar9340Common_wo_xlna_rx_gain_table_1p0,
+ ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
2);
- else if (AR_SREV_9485(ah))
+ else if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9485Common_wo_xlna_rx_gain_1_0,
- ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_0),
+ ar9485Common_wo_xlna_rx_gain_1_1,
+ ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
2);
else
INIT_INI_ARRAY(&ah->iniModesRxGain,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 038a0cbfc6e..be6adec33dd 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -329,7 +329,6 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
| (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
| SM(txpower, AR_XmitPower)
| (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
- | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
| (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
| (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0);
@@ -350,6 +349,16 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
ads->ctl22 = 0;
}
+static void ar9003_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val)
+{
+ struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+
+ if (val)
+ ads->ctl11 |= AR_ClrDestMask;
+ else
+ ads->ctl11 &= ~AR_ClrDestMask;
+}
+
static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
void *lastds,
u32 durUpdateEn, u32 rtsctsRate,
@@ -475,27 +484,6 @@ static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr);
}
-static void ar9003_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
- u32 burstDuration)
-{
- struct ar9003_txc *ads = (struct ar9003_txc *) ds;
-
- ads->ctl13 &= ~AR_BurstDur;
- ads->ctl13 |= SM(burstDuration, AR_BurstDur);
-
-}
-
-static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
- u32 vmf)
-{
- struct ar9003_txc *ads = (struct ar9003_txc *) ds;
-
- if (vmf)
- ads->ctl11 |= AR_VirtMoreFrag;
- else
- ads->ctl11 &= ~AR_VirtMoreFrag;
-}
-
void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains)
{
struct ar9003_txc *ads = ds;
@@ -520,8 +508,7 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
ops->set11n_aggr_middle = ar9003_hw_set11n_aggr_middle;
ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last;
ops->clr11n_aggr = ar9003_hw_clr11n_aggr;
- ops->set11n_burstduration = ar9003_hw_set11n_burstduration;
- ops->set11n_virtualmorefrag = ar9003_hw_set11n_virtualmorefrag;
+ ops->set_clrdmask = ar9003_hw_set_clrdmask;
}
void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index eb250d6b803..25f3c2fdf2b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -75,16 +75,42 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
freq = centers.synth_center;
if (freq < 4800) { /* 2 GHz, fractional mode */
- if (AR_SREV_9485(ah))
- channelSel = CHANSEL_2G_9485(freq);
- else
+ if (AR_SREV_9485(ah)) {
+ u32 chan_frac;
+
+ /*
+ * freq_ref = 40 / (refdiva >> amoderefsel); where refdiva=1 and amoderefsel=0
+ * ndiv = ((chan_mhz * 4) / 3) / freq_ref;
+ * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000
+ */
+ channelSel = (freq * 4) / 120;
+ chan_frac = (((freq * 4) % 120) * 0x20000) / 120;
+ channelSel = (channelSel << 17) | chan_frac;
+ } else if (AR_SREV_9340(ah)) {
+ if (ah->is_clk_25mhz) {
+ u32 chan_frac;
+
+ channelSel = (freq * 2) / 75;
+ chan_frac = (((freq * 2) % 75) * 0x20000) / 75;
+ channelSel = (channelSel << 17) | chan_frac;
+ } else
+ channelSel = CHANSEL_2G(freq) >> 1;
+ } else
channelSel = CHANSEL_2G(freq);
/* Set to 2G mode */
bMode = 1;
} else {
- channelSel = CHANSEL_5G(freq);
- /* Doubler is ON, so, divide channelSel by 2. */
- channelSel >>= 1;
+ if (AR_SREV_9340(ah) && ah->is_clk_25mhz) {
+ u32 chan_frac;
+
+ channelSel = (freq * 2) / 75;
+ chan_frac = ((freq % 75) * 0x20000) / 75;
+ channelSel = (channelSel << 17) | chan_frac;
+ } else {
+ channelSel = CHANSEL_5G(freq);
+ /* Doubler is ON, so, divide channelSel by 2. */
+ channelSel >>= 1;
+ }
/* Set to 5G mode */
bMode = 0;
}
@@ -142,7 +168,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
* is out-of-band and can be ignored.
*/
- if (AR_SREV_9485(ah)) {
+ if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) {
spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah,
IS_CHAN_2GHZ(chan));
if (spur_fbin_ptr[0] == 0) /* No spur */
@@ -167,7 +193,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
for (i = 0; i < max_spur_cnts; i++) {
negative = 0;
- if (AR_SREV_9485(ah))
+ if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i],
IS_CHAN_2GHZ(chan)) - synth_freq;
else
@@ -401,7 +427,7 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah,
ar9003_hw_spur_ofdm_clear(ah);
- for (i = 0; spurChansPtr[i] && i < 5; i++) {
+ for (i = 0; i < AR_EEPROM_MODAL_SPURS && spurChansPtr[i]; i++) {
freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq;
if (abs(freq_offset) < range) {
ar9003_hw_spur_ofdm_work(ah, chan, freq_offset);
@@ -590,29 +616,25 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
unsigned int regWrites = 0, i;
struct ieee80211_channel *channel = chan->chan;
- u32 modesIndex, freqIndex;
+ u32 modesIndex;
switch (chan->chanmode) {
case CHANNEL_A:
case CHANNEL_A_HT20:
modesIndex = 1;
- freqIndex = 1;
break;
case CHANNEL_A_HT40PLUS:
case CHANNEL_A_HT40MINUS:
modesIndex = 2;
- freqIndex = 1;
break;
case CHANNEL_G:
case CHANNEL_G_HT20:
case CHANNEL_B:
modesIndex = 4;
- freqIndex = 2;
break;
case CHANNEL_G_HT40PLUS:
case CHANNEL_G_HT40MINUS:
modesIndex = 3;
- freqIndex = 2;
break;
default:
@@ -637,6 +659,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
REG_WRITE_ARRAY(&ah->iniModesAdditional,
modesIndex, regWrites);
+ if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
+ REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
+
ar9003_hw_override_ini(ah);
ar9003_hw_set_channel_regs(ah, chan);
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
@@ -1159,9 +1184,52 @@ static void ar9003_hw_set_radar_conf(struct ath_hw *ah)
conf->radar_inband = 8;
}
+static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf)
+{
+ u32 regval;
+
+ regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+ antconf->main_lna_conf = (regval & AR_PHY_9485_ANT_DIV_MAIN_LNACONF) >>
+ AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S;
+ antconf->alt_lna_conf = (regval & AR_PHY_9485_ANT_DIV_ALT_LNACONF) >>
+ AR_PHY_9485_ANT_DIV_ALT_LNACONF_S;
+ antconf->fast_div_bias = (regval & AR_PHY_9485_ANT_FAST_DIV_BIAS) >>
+ AR_PHY_9485_ANT_FAST_DIV_BIAS_S;
+ antconf->lna1_lna2_delta = -9;
+ antconf->div_group = 2;
+}
+
+static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf)
+{
+ u32 regval;
+
+ regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+ regval &= ~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
+ AR_PHY_9485_ANT_DIV_ALT_LNACONF |
+ AR_PHY_9485_ANT_FAST_DIV_BIAS |
+ AR_PHY_9485_ANT_DIV_MAIN_GAINTB |
+ AR_PHY_9485_ANT_DIV_ALT_GAINTB);
+ regval |= ((antconf->main_lna_conf <<
+ AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S)
+ & AR_PHY_9485_ANT_DIV_MAIN_LNACONF);
+ regval |= ((antconf->alt_lna_conf << AR_PHY_9485_ANT_DIV_ALT_LNACONF_S)
+ & AR_PHY_9485_ANT_DIV_ALT_LNACONF);
+ regval |= ((antconf->fast_div_bias << AR_PHY_9485_ANT_FAST_DIV_BIAS_S)
+ & AR_PHY_9485_ANT_FAST_DIV_BIAS);
+ regval |= ((antconf->main_gaintb << AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S)
+ & AR_PHY_9485_ANT_DIV_MAIN_GAINTB);
+ regval |= ((antconf->alt_gaintb << AR_PHY_9485_ANT_DIV_ALT_GAINTB_S)
+ & AR_PHY_9485_ANT_DIV_ALT_GAINTB);
+
+ REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
+}
+
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
{
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+ struct ath_hw_ops *ops = ath9k_hw_ops(ah);
static const u32 ar9300_cca_regs[6] = {
AR_PHY_CCA_0,
AR_PHY_CCA_1,
@@ -1188,6 +1256,9 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
priv_ops->set_radar_params = ar9003_hw_set_radar_params;
+ ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get;
+ ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set;
+
ar9003_hw_set_nf_limits(ah);
ar9003_hw_set_radar_conf(ah);
memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs));
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 8bdda2cf9dd..c7505b48e5c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -261,12 +261,34 @@
#define AR_PHY_EXT_CCA0 (AR_AGC_BASE + 0x20)
#define AR_PHY_RESTART (AR_AGC_BASE + 0x24)
+/*
+ * Antenna Diversity settings
+ */
#define AR_PHY_MC_GAIN_CTRL (AR_AGC_BASE + 0x28)
#define AR_ANT_DIV_CTRL_ALL 0x7e000000
#define AR_ANT_DIV_CTRL_ALL_S 25
#define AR_ANT_DIV_ENABLE 0x1000000
#define AR_ANT_DIV_ENABLE_S 24
+
+#define AR_PHY_9485_ANT_FAST_DIV_BIAS 0x00007e00
+#define AR_PHY_9485_ANT_FAST_DIV_BIAS_S 9
+#define AR_PHY_9485_ANT_DIV_LNADIV 0x01000000
+#define AR_PHY_9485_ANT_DIV_LNADIV_S 24
+#define AR_PHY_9485_ANT_DIV_ALT_LNACONF 0x06000000
+#define AR_PHY_9485_ANT_DIV_ALT_LNACONF_S 25
+#define AR_PHY_9485_ANT_DIV_MAIN_LNACONF 0x18000000
+#define AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S 27
+#define AR_PHY_9485_ANT_DIV_ALT_GAINTB 0x20000000
+#define AR_PHY_9485_ANT_DIV_ALT_GAINTB_S 29
+#define AR_PHY_9485_ANT_DIV_MAIN_GAINTB 0x40000000
+#define AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S 30
+
+#define AR_PHY_9485_ANT_DIV_LNA1_MINUS_LNA2 0x0
+#define AR_PHY_9485_ANT_DIV_LNA2 0x1
+#define AR_PHY_9485_ANT_DIV_LNA1 0x2
+#define AR_PHY_9485_ANT_DIV_LNA1_PLUS_LNA2 0x3
+
#define AR_PHY_EXTCHN_PWRTHR1 (AR_AGC_BASE + 0x2c)
#define AR_PHY_EXT_CHN_WIN (AR_AGC_BASE + 0x30)
#define AR_PHY_20_40_DET_THR (AR_AGC_BASE + 0x34)
@@ -548,15 +570,12 @@
#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300)
-#define AR_PHY_TX_IQCAL_START_9485 (AR_SM_BASE + 0x3c4)
-#define AR_PHY_TX_IQCAL_START_DO_CAL_9485 0x80000000
-#define AR_PHY_TX_IQCAL_START_DO_CAL_9485_S 31
-#define AR_PHY_TX_IQCAL_CONTROL_1_9485 (AR_SM_BASE + 0x3c8)
-#define AR_PHY_TX_IQCAL_STATUS_B0_9485 (AR_SM_BASE + 0x3f0)
-
-#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448)
-#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440)
-#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c)
+#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + AR_SREV_9485(ah) ? \
+ 0x3c8 : 0x448)
+#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + AR_SREV_9485(ah) ? \
+ 0x3c4 : 0x440)
+#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + AR_SREV_9485(ah) ? \
+ 0x3f0 : 0x48c)
#define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \
(AR_SREV_9485(ah) ? \
0x3d0 : 0x450) + ((_i) << 2))
@@ -588,7 +607,7 @@
#define AR_PHY_65NM_CH0_BIAS2 0x160c4
#define AR_PHY_65NM_CH0_BIAS4 0x160cc
#define AR_PHY_65NM_CH0_RXTX4 0x1610c
-#define AR_PHY_65NM_CH0_THERM (AR_SREV_9485(ah) ? 0x1628c : 0x16290)
+#define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 : 0x1628c)
#define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000
#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
@@ -758,10 +777,10 @@
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24
#define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004
-#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000
-#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18
-#define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001
-#define AR_PHY_TX_IQCAL_START_DO_CAL_S 0
+#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000
+#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18
+#define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001
+#define AR_PHY_TX_IQCAL_START_DO_CAL_S 0
#define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001
#define AR_PHY_CALIBRATED_GAINS_0 0x3e
diff --git a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
new file mode 100644
index 00000000000..815a8af1bee
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
@@ -0,0 +1,1525 @@
+/*
+ * Copyright (c) 2011 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef INITVALS_9340_H
+#define INITVALS_9340_H
+
+static const u32 ar9340_1p0_radio_postamble[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800},
+ {0x0001610c, 0x08000000, 0x08000000, 0x00000000, 0x00000000},
+ {0x00016140, 0x10804000, 0x10804000, 0x50804000, 0x50804000},
+ {0x0001650c, 0x08000000, 0x08000000, 0x00000000, 0x00000000},
+ {0x00016540, 0x10804000, 0x10804000, 0x50804000, 0x50804000},
+};
+
+static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+ {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+ {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+ {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+ {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+ {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
+ {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
+ {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
+ {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
+ {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
+ {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
+ {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
+ {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
+ {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
+ {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
+ {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
+ {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
+ {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
+ {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
+ {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
+ {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
+ {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
+ {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
+ {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
+ {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
+ {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+ {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+ {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+ {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+ {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+ {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+ {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+ {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+ {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+ {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+ {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+ {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+ {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
+ {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
+ {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
+ {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
+ {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
+ {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
+ {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
+ {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
+ {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
+ {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
+ {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
+ {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
+ {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
+ {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
+ {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
+ {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
+ {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
+ {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
+ {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
+ {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
+ {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+ {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+ {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+ {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+ {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+ {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+ {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+ {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+ {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+ {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+ {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+};
+
+static const u32 ar9340Modes_fast_clock_1p0[][3] = {
+ /* Addr 5G_HT20 5G_HT40 */
+ {0x00001030, 0x00000268, 0x000004d0},
+ {0x00001070, 0x0000018c, 0x00000318},
+ {0x000010b0, 0x00000fd0, 0x00001fa0},
+ {0x00008014, 0x044c044c, 0x08980898},
+ {0x0000801c, 0x148ec02b, 0x148ec057},
+ {0x00008318, 0x000044c0, 0x00008980},
+ {0x00009e00, 0x03721821, 0x03721821},
+ {0x0000a230, 0x0000000b, 0x00000016},
+ {0x0000a254, 0x00000898, 0x00001130},
+};
+
+static const u32 ar9340_1p0_radio_core[][2] = {
+ /* Addr allmodes */
+ {0x00016000, 0x36db6db6},
+ {0x00016004, 0x6db6db40},
+ {0x00016008, 0x73f00000},
+ {0x0001600c, 0x00000000},
+ {0x00016040, 0x7f80fff8},
+ {0x00016044, 0x03b6d2db},
+ {0x00016048, 0x24925266},
+ {0x0001604c, 0x000f0278},
+ {0x00016050, 0x6db6db6c},
+ {0x00016054, 0x6db60000},
+ {0x00016080, 0x00080000},
+ {0x00016084, 0x0e48048c},
+ {0x00016088, 0x14214514},
+ {0x0001608c, 0x119f081c},
+ {0x00016090, 0x24926490},
+ {0x00016094, 0x00000000},
+ {0x00016098, 0xd411eb84},
+ {0x0001609c, 0x03e47f32},
+ {0x000160a0, 0xc2108ffe},
+ {0x000160a4, 0x812fc370},
+ {0x000160a8, 0x423c8000},
+ {0x000160ac, 0xa4646800},
+ {0x000160b0, 0x00fe7f46},
+ {0x000160b4, 0x92480000},
+ {0x000160c0, 0x006db6db},
+ {0x000160c4, 0x6db6db60},
+ {0x000160c8, 0x6db6db6c},
+ {0x000160cc, 0x6de6db6c},
+ {0x000160d0, 0xb6da4924},
+ {0x00016100, 0x04cb0001},
+ {0x00016104, 0xfff80000},
+ {0x00016108, 0x00080010},
+ {0x0001610c, 0x00000000},
+ {0x00016140, 0x50804008},
+ {0x00016144, 0x01884080},
+ {0x00016148, 0x000080c0},
+ {0x00016280, 0x01000015},
+ {0x00016284, 0x05530000},
+ {0x00016288, 0x00318000},
+ {0x0001628c, 0x50000000},
+ {0x00016290, 0x4080294f},
+ {0x00016380, 0x00000000},
+ {0x00016384, 0x00000000},
+ {0x00016388, 0x00800700},
+ {0x0001638c, 0x00800700},
+ {0x00016390, 0x00800700},
+ {0x00016394, 0x00000000},
+ {0x00016398, 0x00000000},
+ {0x0001639c, 0x00000000},
+ {0x000163a0, 0x00000001},
+ {0x000163a4, 0x00000001},
+ {0x000163a8, 0x00000000},
+ {0x000163ac, 0x00000000},
+ {0x000163b0, 0x00000000},
+ {0x000163b4, 0x00000000},
+ {0x000163b8, 0x00000000},
+ {0x000163bc, 0x00000000},
+ {0x000163c0, 0x000000a0},
+ {0x000163c4, 0x000c0000},
+ {0x000163c8, 0x14021402},
+ {0x000163cc, 0x00001402},
+ {0x000163d0, 0x00000000},
+ {0x000163d4, 0x00000000},
+ {0x00016400, 0x36db6db6},
+ {0x00016404, 0x6db6db40},
+ {0x00016408, 0x73f00000},
+ {0x0001640c, 0x00000000},
+ {0x00016440, 0x7f80fff8},
+ {0x00016444, 0x03b6d2db},
+ {0x00016448, 0x24927266},
+ {0x0001644c, 0x000f0278},
+ {0x00016450, 0x6db6db6c},
+ {0x00016454, 0x6db60000},
+ {0x00016500, 0x04cb0001},
+ {0x00016504, 0xfff80000},
+ {0x00016508, 0x00080010},
+ {0x0001650c, 0x00000000},
+ {0x00016540, 0x50804008},
+ {0x00016544, 0x01884080},
+ {0x00016548, 0x000080c0},
+ {0x00016780, 0x00000000},
+ {0x00016784, 0x00000000},
+ {0x00016788, 0x00800700},
+ {0x0001678c, 0x00800700},
+ {0x00016790, 0x00800700},
+ {0x00016794, 0x00000000},
+ {0x00016798, 0x00000000},
+ {0x0001679c, 0x00000000},
+ {0x000167a0, 0x00000001},
+ {0x000167a4, 0x00000001},
+ {0x000167a8, 0x00000000},
+ {0x000167ac, 0x00000000},
+ {0x000167b0, 0x00000000},
+ {0x000167b4, 0x00000000},
+ {0x000167b8, 0x00000000},
+ {0x000167bc, 0x00000000},
+ {0x000167c0, 0x000000a0},
+ {0x000167c4, 0x000c0000},
+ {0x000167c8, 0x14021402},
+ {0x000167cc, 0x00001402},
+ {0x000167d0, 0x00000000},
+ {0x000167d4, 0x00000000},
+};
+
+static const u32 ar9340_1p0_radio_core_40M[][2] = {
+ {0x0001609c, 0x02566f3a},
+ {0x000160ac, 0xa4647c00},
+ {0x000160b0, 0x01885f5a},
+};
+
+static const u32 ar9340_1p0_mac_postamble[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
+ {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
+ {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
+ {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
+ {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
+ {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
+ {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
+ {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
+};
+
+static const u32 ar9340_1p0_soc_postamble[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
+};
+
+static const u32 ar9340_1p0_baseband_postamble[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
+ {0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e},
+ {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+ {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
+ {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+ {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
+ {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044},
+ {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
+ {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
+ {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
+ {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e},
+ {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
+ {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
+ {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
+ {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
+ {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27},
+ {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
+ {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
+ {0x0000a204, 0x00003fc0, 0x00003fc4, 0x00003fc4, 0x00003fc0},
+ {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
+ {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
+ {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
+ {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
+ {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
+ {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
+ {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
+ {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
+ {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+ {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
+ {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
+ {0x0000a288, 0x00000220, 0x00000220, 0x00000110, 0x00000110},
+ {0x0000a28c, 0x00011111, 0x00011111, 0x00022222, 0x00022222},
+ {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
+ {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
+ {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
+ {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+ {0x0000ae04, 0x00180000, 0x00180000, 0x00180000, 0x00180000},
+ {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+ {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
+ {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
+};
+
+static const u32 ar9340_1p0_baseband_core[][2] = {
+ /* Addr allmodes */
+ {0x00009800, 0xafe68e30},
+ {0x00009804, 0xfd14e000},
+ {0x00009808, 0x9c0a9f6b},
+ {0x0000980c, 0x04900000},
+ {0x00009814, 0xb280c00a},
+ {0x00009818, 0x00000000},
+ {0x0000981c, 0x00020028},
+ {0x00009834, 0x5f3ca3de},
+ {0x00009838, 0x0108ecff},
+ {0x0000983c, 0x14750600},
+ {0x00009880, 0x201fff00},
+ {0x00009884, 0x00001042},
+ {0x000098a4, 0x00200400},
+ {0x000098b0, 0x52440bbe},
+ {0x000098d0, 0x004b6a8e},
+ {0x000098d4, 0x00000820},
+ {0x000098dc, 0x00000000},
+ {0x000098f0, 0x00000000},
+ {0x000098f4, 0x00000000},
+ {0x00009c04, 0xff55ff55},
+ {0x00009c08, 0x0320ff55},
+ {0x00009c0c, 0x00000000},
+ {0x00009c10, 0x00000000},
+ {0x00009c14, 0x00046384},
+ {0x00009c18, 0x05b6b440},
+ {0x00009c1c, 0x00b6b440},
+ {0x00009d00, 0xc080a333},
+ {0x00009d04, 0x40206c10},
+ {0x00009d08, 0x009c4060},
+ {0x00009d0c, 0x9883800a},
+ {0x00009d10, 0x01834061},
+ {0x00009d14, 0x00c0040b},
+ {0x00009d18, 0x00000000},
+ {0x00009e08, 0x0038230c},
+ {0x00009e24, 0x990bb515},
+ {0x00009e28, 0x0c6f0000},
+ {0x00009e30, 0x06336f77},
+ {0x00009e34, 0x6af6532f},
+ {0x00009e38, 0x0cc80c00},
+ {0x00009e3c, 0xcf946222},
+ {0x00009e40, 0x0d261820},
+ {0x00009e4c, 0x00001004},
+ {0x00009e50, 0x00ff03f1},
+ {0x00009e54, 0x00000000},
+ {0x00009fc0, 0x803e4788},
+ {0x00009fc4, 0x0001efb5},
+ {0x00009fcc, 0x40000014},
+ {0x00009fd0, 0x01193b93},
+ {0x0000a20c, 0x00000000},
+ {0x0000a220, 0x00000000},
+ {0x0000a224, 0x00000000},
+ {0x0000a228, 0x10002310},
+ {0x0000a22c, 0x01036a1e},
+ {0x0000a234, 0x10000fff},
+ {0x0000a23c, 0x00000000},
+ {0x0000a244, 0x0c000000},
+ {0x0000a2a0, 0x00000001},
+ {0x0000a2c0, 0x00000001},
+ {0x0000a2c8, 0x00000000},
+ {0x0000a2cc, 0x18c43433},
+ {0x0000a2d4, 0x00000000},
+ {0x0000a2dc, 0x00000000},
+ {0x0000a2e0, 0x00000000},
+ {0x0000a2e4, 0x00000000},
+ {0x0000a2e8, 0x00000000},
+ {0x0000a2ec, 0x00000000},
+ {0x0000a2f0, 0x00000000},
+ {0x0000a2f4, 0x00000000},
+ {0x0000a2f8, 0x00000000},
+ {0x0000a344, 0x00000000},
+ {0x0000a34c, 0x00000000},
+ {0x0000a350, 0x0000a000},
+ {0x0000a364, 0x00000000},
+ {0x0000a370, 0x00000000},
+ {0x0000a390, 0x00000001},
+ {0x0000a394, 0x00000444},
+ {0x0000a398, 0x001f0e0f},
+ {0x0000a39c, 0x0075393f},
+ {0x0000a3a0, 0xb79f6427},
+ {0x0000a3a4, 0x00000000},
+ {0x0000a3a8, 0xaaaaaaaa},
+ {0x0000a3ac, 0x3c466478},
+ {0x0000a3c0, 0x20202020},
+ {0x0000a3c4, 0x22222220},
+ {0x0000a3c8, 0x20200020},
+ {0x0000a3cc, 0x20202020},
+ {0x0000a3d0, 0x20202020},
+ {0x0000a3d4, 0x20202020},
+ {0x0000a3d8, 0x20202020},
+ {0x0000a3dc, 0x20202020},
+ {0x0000a3e0, 0x20202020},
+ {0x0000a3e4, 0x20202020},
+ {0x0000a3e8, 0x20202020},
+ {0x0000a3ec, 0x20202020},
+ {0x0000a3f0, 0x00000000},
+ {0x0000a3f4, 0x00000246},
+ {0x0000a3f8, 0x0cdbd380},
+ {0x0000a3fc, 0x000f0f01},
+ {0x0000a400, 0x8fa91f01},
+ {0x0000a404, 0x00000000},
+ {0x0000a408, 0x0e79e5c6},
+ {0x0000a40c, 0x00820820},
+ {0x0000a414, 0x1ce739ce},
+ {0x0000a418, 0x2d001dce},
+ {0x0000a41c, 0x1ce739ce},
+ {0x0000a420, 0x000001ce},
+ {0x0000a424, 0x1ce739ce},
+ {0x0000a428, 0x000001ce},
+ {0x0000a42c, 0x1ce739ce},
+ {0x0000a430, 0x1ce739ce},
+ {0x0000a434, 0x00000000},
+ {0x0000a438, 0x00001801},
+ {0x0000a43c, 0x00000000},
+ {0x0000a440, 0x00000000},
+ {0x0000a444, 0x00000000},
+ {0x0000a448, 0x04000080},
+ {0x0000a44c, 0x00000001},
+ {0x0000a450, 0x00010000},
+ {0x0000a458, 0x00000000},
+ {0x0000a600, 0x00000000},
+ {0x0000a604, 0x00000000},
+ {0x0000a608, 0x00000000},
+ {0x0000a60c, 0x00000000},
+ {0x0000a610, 0x00000000},
+ {0x0000a614, 0x00000000},
+ {0x0000a618, 0x00000000},
+ {0x0000a61c, 0x00000000},
+ {0x0000a620, 0x00000000},
+ {0x0000a624, 0x00000000},
+ {0x0000a628, 0x00000000},
+ {0x0000a62c, 0x00000000},
+ {0x0000a630, 0x00000000},
+ {0x0000a634, 0x00000000},
+ {0x0000a638, 0x00000000},
+ {0x0000a63c, 0x00000000},
+ {0x0000a640, 0x00000000},
+ {0x0000a644, 0x3fad9d74},
+ {0x0000a648, 0x0048060a},
+ {0x0000a64c, 0x00000637},
+ {0x0000a670, 0x03020100},
+ {0x0000a674, 0x09080504},
+ {0x0000a678, 0x0d0c0b0a},
+ {0x0000a67c, 0x13121110},
+ {0x0000a680, 0x31301514},
+ {0x0000a684, 0x35343332},
+ {0x0000a688, 0x00000036},
+ {0x0000a690, 0x00000838},
+ {0x0000a7c0, 0x00000000},
+ {0x0000a7c4, 0xfffffffc},
+ {0x0000a7c8, 0x00000000},
+ {0x0000a7cc, 0x00000000},
+ {0x0000a7d0, 0x00000000},
+ {0x0000a7d4, 0x00000004},
+ {0x0000a7dc, 0x00000000},
+ {0x0000a8d0, 0x004b6a8e},
+ {0x0000a8d4, 0x00000820},
+ {0x0000a8dc, 0x00000000},
+ {0x0000a8f0, 0x00000000},
+ {0x0000a8f4, 0x00000000},
+ {0x0000b2d0, 0x00000080},
+ {0x0000b2d4, 0x00000000},
+ {0x0000b2dc, 0x00000000},
+ {0x0000b2e0, 0x00000000},
+ {0x0000b2e4, 0x00000000},
+ {0x0000b2e8, 0x00000000},
+ {0x0000b2ec, 0x00000000},
+ {0x0000b2f0, 0x00000000},
+ {0x0000b2f4, 0x00000000},
+ {0x0000b2f8, 0x00000000},
+ {0x0000b408, 0x0e79e5c0},
+ {0x0000b40c, 0x00820820},
+ {0x0000b420, 0x00000000},
+};
+
+static const u32 ar9340Modes_high_power_tx_gain_table_1p0[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
+ {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+ {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
+ {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
+ {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
+ {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
+ {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
+ {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
+ {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
+ {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
+ {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
+ {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
+ {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
+ {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
+ {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
+ {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
+ {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
+ {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
+ {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
+ {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
+ {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
+ {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
+ {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
+ {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
+ {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
+ {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
+ {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
+ {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
+ {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
+ {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
+ {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
+ {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
+ {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
+ {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
+ {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
+ {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
+ {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
+ {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
+ {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
+ {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
+ {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
+ {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
+ {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
+ {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
+ {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
+ {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
+ {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
+ {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
+ {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
+ {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
+ {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
+ {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+ {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+ {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+ {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+};
+
+static const u32 ar9340Modes_high_ob_db_tx_gain_table_1p0[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
+ {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+ {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
+ {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
+ {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
+ {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
+ {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
+ {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
+ {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
+ {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
+ {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
+ {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
+ {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
+ {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
+ {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
+ {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
+ {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
+ {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
+ {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
+ {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
+ {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
+ {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
+ {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
+ {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
+ {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
+ {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
+ {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
+ {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
+ {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
+ {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
+ {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
+ {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
+ {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
+ {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
+ {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
+ {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
+ {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
+ {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
+ {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
+ {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
+ {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
+ {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
+ {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
+ {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
+ {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
+ {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
+ {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
+ {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
+ {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
+ {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
+ {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
+ {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x00016044, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4},
+ {0x00016048, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266},
+ {0x00016444, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4},
+ {0x00016448, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266},
+};
+static const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
+ {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+ {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
+ {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
+ {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
+ {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
+ {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
+ {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
+ {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
+ {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
+ {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
+ {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
+ {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
+ {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
+ {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
+ {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
+ {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
+ {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
+ {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
+ {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
+ {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
+ {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
+ {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
+ {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
+ {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
+ {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
+ {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+ {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
+ {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
+ {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
+ {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
+ {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
+ {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
+ {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
+ {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
+ {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
+ {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
+ {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
+ {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
+ {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
+ {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
+ {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
+ {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
+ {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
+ {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
+ {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
+ {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
+ {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
+ {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
+ {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
+ {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
+ {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
+ {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x00016044, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db},
+ {0x00016048, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266},
+ {0x00016444, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db},
+ {0x00016448, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266},
+};
+
+
+static const u32 ar9340Common_rx_gain_table_1p0[][2] = {
+ /* Addr allmodes */
+ {0x0000a000, 0x00010000},
+ {0x0000a004, 0x00030002},
+ {0x0000a008, 0x00050004},
+ {0x0000a00c, 0x00810080},
+ {0x0000a010, 0x00830082},
+ {0x0000a014, 0x01810180},
+ {0x0000a018, 0x01830182},
+ {0x0000a01c, 0x01850184},
+ {0x0000a020, 0x01890188},
+ {0x0000a024, 0x018b018a},
+ {0x0000a028, 0x018d018c},
+ {0x0000a02c, 0x01910190},
+ {0x0000a030, 0x01930192},
+ {0x0000a034, 0x01950194},
+ {0x0000a038, 0x038a0196},
+ {0x0000a03c, 0x038c038b},
+ {0x0000a040, 0x0390038d},
+ {0x0000a044, 0x03920391},
+ {0x0000a048, 0x03940393},
+ {0x0000a04c, 0x03960395},
+ {0x0000a050, 0x00000000},
+ {0x0000a054, 0x00000000},
+ {0x0000a058, 0x00000000},
+ {0x0000a05c, 0x00000000},
+ {0x0000a060, 0x00000000},
+ {0x0000a064, 0x00000000},
+ {0x0000a068, 0x00000000},
+ {0x0000a06c, 0x00000000},
+ {0x0000a070, 0x00000000},
+ {0x0000a074, 0x00000000},
+ {0x0000a078, 0x00000000},
+ {0x0000a07c, 0x00000000},
+ {0x0000a080, 0x22222229},
+ {0x0000a084, 0x1d1d1d1d},
+ {0x0000a088, 0x1d1d1d1d},
+ {0x0000a08c, 0x1d1d1d1d},
+ {0x0000a090, 0x171d1d1d},
+ {0x0000a094, 0x11111717},
+ {0x0000a098, 0x00030311},
+ {0x0000a09c, 0x00000000},
+ {0x0000a0a0, 0x00000000},
+ {0x0000a0a4, 0x00000000},
+ {0x0000a0a8, 0x00000000},
+ {0x0000a0ac, 0x00000000},
+ {0x0000a0b0, 0x00000000},
+ {0x0000a0b4, 0x00000000},
+ {0x0000a0b8, 0x00000000},
+ {0x0000a0bc, 0x00000000},
+ {0x0000a0c0, 0x001f0000},
+ {0x0000a0c4, 0x01000101},
+ {0x0000a0c8, 0x011e011f},
+ {0x0000a0cc, 0x011c011d},
+ {0x0000a0d0, 0x02030204},
+ {0x0000a0d4, 0x02010202},
+ {0x0000a0d8, 0x021f0200},
+ {0x0000a0dc, 0x0302021e},
+ {0x0000a0e0, 0x03000301},
+ {0x0000a0e4, 0x031e031f},
+ {0x0000a0e8, 0x0402031d},
+ {0x0000a0ec, 0x04000401},
+ {0x0000a0f0, 0x041e041f},
+ {0x0000a0f4, 0x0502041d},
+ {0x0000a0f8, 0x05000501},
+ {0x0000a0fc, 0x051e051f},
+ {0x0000a100, 0x06010602},
+ {0x0000a104, 0x061f0600},
+ {0x0000a108, 0x061d061e},
+ {0x0000a10c, 0x07020703},
+ {0x0000a110, 0x07000701},
+ {0x0000a114, 0x00000000},
+ {0x0000a118, 0x00000000},
+ {0x0000a11c, 0x00000000},
+ {0x0000a120, 0x00000000},
+ {0x0000a124, 0x00000000},
+ {0x0000a128, 0x00000000},
+ {0x0000a12c, 0x00000000},
+ {0x0000a130, 0x00000000},
+ {0x0000a134, 0x00000000},
+ {0x0000a138, 0x00000000},
+ {0x0000a13c, 0x00000000},
+ {0x0000a140, 0x001f0000},
+ {0x0000a144, 0x01000101},
+ {0x0000a148, 0x011e011f},
+ {0x0000a14c, 0x011c011d},
+ {0x0000a150, 0x02030204},
+ {0x0000a154, 0x02010202},
+ {0x0000a158, 0x021f0200},
+ {0x0000a15c, 0x0302021e},
+ {0x0000a160, 0x03000301},
+ {0x0000a164, 0x031e031f},
+ {0x0000a168, 0x0402031d},
+ {0x0000a16c, 0x04000401},
+ {0x0000a170, 0x041e041f},
+ {0x0000a174, 0x0502041d},
+ {0x0000a178, 0x05000501},
+ {0x0000a17c, 0x051e051f},
+ {0x0000a180, 0x06010602},
+ {0x0000a184, 0x061f0600},
+ {0x0000a188, 0x061d061e},
+ {0x0000a18c, 0x07020703},
+ {0x0000a190, 0x07000701},
+ {0x0000a194, 0x00000000},
+ {0x0000a198, 0x00000000},
+ {0x0000a19c, 0x00000000},
+ {0x0000a1a0, 0x00000000},
+ {0x0000a1a4, 0x00000000},
+ {0x0000a1a8, 0x00000000},
+ {0x0000a1ac, 0x00000000},
+ {0x0000a1b0, 0x00000000},
+ {0x0000a1b4, 0x00000000},
+ {0x0000a1b8, 0x00000000},
+ {0x0000a1bc, 0x00000000},
+ {0x0000a1c0, 0x00000000},
+ {0x0000a1c4, 0x00000000},
+ {0x0000a1c8, 0x00000000},
+ {0x0000a1cc, 0x00000000},
+ {0x0000a1d0, 0x00000000},
+ {0x0000a1d4, 0x00000000},
+ {0x0000a1d8, 0x00000000},
+ {0x0000a1dc, 0x00000000},
+ {0x0000a1e0, 0x00000000},
+ {0x0000a1e4, 0x00000000},
+ {0x0000a1e8, 0x00000000},
+ {0x0000a1ec, 0x00000000},
+ {0x0000a1f0, 0x00000396},
+ {0x0000a1f4, 0x00000396},
+ {0x0000a1f8, 0x00000396},
+ {0x0000a1fc, 0x00000196},
+ {0x0000b000, 0x00010000},
+ {0x0000b004, 0x00030002},
+ {0x0000b008, 0x00050004},
+ {0x0000b00c, 0x00810080},
+ {0x0000b010, 0x00830082},
+ {0x0000b014, 0x01810180},
+ {0x0000b018, 0x01830182},
+ {0x0000b01c, 0x01850184},
+ {0x0000b020, 0x02810280},
+ {0x0000b024, 0x02830282},
+ {0x0000b028, 0x02850284},
+ {0x0000b02c, 0x02890288},
+ {0x0000b030, 0x028b028a},
+ {0x0000b034, 0x0388028c},
+ {0x0000b038, 0x038a0389},
+ {0x0000b03c, 0x038c038b},
+ {0x0000b040, 0x0390038d},
+ {0x0000b044, 0x03920391},
+ {0x0000b048, 0x03940393},
+ {0x0000b04c, 0x03960395},
+ {0x0000b050, 0x00000000},
+ {0x0000b054, 0x00000000},
+ {0x0000b058, 0x00000000},
+ {0x0000b05c, 0x00000000},
+ {0x0000b060, 0x00000000},
+ {0x0000b064, 0x00000000},
+ {0x0000b068, 0x00000000},
+ {0x0000b06c, 0x00000000},
+ {0x0000b070, 0x00000000},
+ {0x0000b074, 0x00000000},
+ {0x0000b078, 0x00000000},
+ {0x0000b07c, 0x00000000},
+ {0x0000b080, 0x32323232},
+ {0x0000b084, 0x2f2f3232},
+ {0x0000b088, 0x23282a2d},
+ {0x0000b08c, 0x1c1e2123},
+ {0x0000b090, 0x14171919},
+ {0x0000b094, 0x0e0e1214},
+ {0x0000b098, 0x03050707},
+ {0x0000b09c, 0x00030303},
+ {0x0000b0a0, 0x00000000},
+ {0x0000b0a4, 0x00000000},
+ {0x0000b0a8, 0x00000000},
+ {0x0000b0ac, 0x00000000},
+ {0x0000b0b0, 0x00000000},
+ {0x0000b0b4, 0x00000000},
+ {0x0000b0b8, 0x00000000},
+ {0x0000b0bc, 0x00000000},
+ {0x0000b0c0, 0x003f0020},
+ {0x0000b0c4, 0x00400041},
+ {0x0000b0c8, 0x0140005f},
+ {0x0000b0cc, 0x0160015f},
+ {0x0000b0d0, 0x017e017f},
+ {0x0000b0d4, 0x02410242},
+ {0x0000b0d8, 0x025f0240},
+ {0x0000b0dc, 0x027f0260},
+ {0x0000b0e0, 0x0341027e},
+ {0x0000b0e4, 0x035f0340},
+ {0x0000b0e8, 0x037f0360},
+ {0x0000b0ec, 0x04400441},
+ {0x0000b0f0, 0x0460045f},
+ {0x0000b0f4, 0x0541047f},
+ {0x0000b0f8, 0x055f0540},
+ {0x0000b0fc, 0x057f0560},
+ {0x0000b100, 0x06400641},
+ {0x0000b104, 0x0660065f},
+ {0x0000b108, 0x067e067f},
+ {0x0000b10c, 0x07410742},
+ {0x0000b110, 0x075f0740},
+ {0x0000b114, 0x077f0760},
+ {0x0000b118, 0x07800781},
+ {0x0000b11c, 0x07a0079f},
+ {0x0000b120, 0x07c107bf},
+ {0x0000b124, 0x000007c0},
+ {0x0000b128, 0x00000000},
+ {0x0000b12c, 0x00000000},
+ {0x0000b130, 0x00000000},
+ {0x0000b134, 0x00000000},
+ {0x0000b138, 0x00000000},
+ {0x0000b13c, 0x00000000},
+ {0x0000b140, 0x003f0020},
+ {0x0000b144, 0x00400041},
+ {0x0000b148, 0x0140005f},
+ {0x0000b14c, 0x0160015f},
+ {0x0000b150, 0x017e017f},
+ {0x0000b154, 0x02410242},
+ {0x0000b158, 0x025f0240},
+ {0x0000b15c, 0x027f0260},
+ {0x0000b160, 0x0341027e},
+ {0x0000b164, 0x035f0340},
+ {0x0000b168, 0x037f0360},
+ {0x0000b16c, 0x04400441},
+ {0x0000b170, 0x0460045f},
+ {0x0000b174, 0x0541047f},
+ {0x0000b178, 0x055f0540},
+ {0x0000b17c, 0x057f0560},
+ {0x0000b180, 0x06400641},
+ {0x0000b184, 0x0660065f},
+ {0x0000b188, 0x067e067f},
+ {0x0000b18c, 0x07410742},
+ {0x0000b190, 0x075f0740},
+ {0x0000b194, 0x077f0760},
+ {0x0000b198, 0x07800781},
+ {0x0000b19c, 0x07a0079f},
+ {0x0000b1a0, 0x07c107bf},
+ {0x0000b1a4, 0x000007c0},
+ {0x0000b1a8, 0x00000000},
+ {0x0000b1ac, 0x00000000},
+ {0x0000b1b0, 0x00000000},
+ {0x0000b1b4, 0x00000000},
+ {0x0000b1b8, 0x00000000},
+ {0x0000b1bc, 0x00000000},
+ {0x0000b1c0, 0x00000000},
+ {0x0000b1c4, 0x00000000},
+ {0x0000b1c8, 0x00000000},
+ {0x0000b1cc, 0x00000000},
+ {0x0000b1d0, 0x00000000},
+ {0x0000b1d4, 0x00000000},
+ {0x0000b1d8, 0x00000000},
+ {0x0000b1dc, 0x00000000},
+ {0x0000b1e0, 0x00000000},
+ {0x0000b1e4, 0x00000000},
+ {0x0000b1e8, 0x00000000},
+ {0x0000b1ec, 0x00000000},
+ {0x0000b1f0, 0x00000396},
+ {0x0000b1f4, 0x00000396},
+ {0x0000b1f8, 0x00000396},
+ {0x0000b1fc, 0x00000196},
+};
+
+static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+ {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+ {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+ {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+ {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+ {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
+ {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
+ {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
+ {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
+ {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
+ {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
+ {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
+ {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
+ {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
+ {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
+ {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
+ {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
+ {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
+ {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
+ {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
+ {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
+ {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
+ {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
+ {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
+ {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
+ {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+ {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+ {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+ {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+ {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+ {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+ {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+ {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+ {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+ {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+ {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+ {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+ {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
+ {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
+ {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
+ {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
+ {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
+ {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
+ {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
+ {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
+ {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
+ {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
+ {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
+ {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
+ {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
+ {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
+ {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
+ {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
+ {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
+ {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
+ {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
+ {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
+ {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+ {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+ {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+ {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+ {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+ {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+ {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+ {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+ {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+ {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+ {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+};
+
+static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+ {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+ {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+ {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+ {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+ {0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400},
+ {0x0000a518, 0x21020220, 0x21020220, 0x15000402, 0x15000402},
+ {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
+ {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000603, 0x1b000603},
+ {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000a02, 0x1f000a02},
+ {0x0000a528, 0x34022225, 0x34022225, 0x23000a04, 0x23000a04},
+ {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x26000a20, 0x26000a20},
+ {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2a000e20, 0x2a000e20},
+ {0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22},
+ {0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24},
+ {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640},
+ {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660},
+ {0x0000a544, 0x5302266c, 0x5302266c, 0x3b001861, 0x3b001861},
+ {0x0000a548, 0x5702286c, 0x5702286c, 0x3e001a81, 0x3e001a81},
+ {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x42001a83, 0x42001a83},
+ {0x0000a550, 0x61042a6c, 0x61042a6c, 0x44001c84, 0x44001c84},
+ {0x0000a554, 0x66062a6c, 0x66062a6c, 0x48001ce3, 0x48001ce3},
+ {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x4c001ce5, 0x4c001ce5},
+ {0x0000a55c, 0x7006308c, 0x7006308c, 0x50001ce9, 0x50001ce9},
+ {0x0000a560, 0x730a308a, 0x730a308a, 0x54001ceb, 0x54001ceb},
+ {0x0000a564, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+ {0x0000a568, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+ {0x0000a56c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+ {0x0000a570, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+ {0x0000a574, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+ {0x0000a578, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+ {0x0000a57c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+ {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+ {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+ {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+ {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+ {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+ {0x0000a594, 0x1c800223, 0x1c800223, 0x11800400, 0x11800400},
+ {0x0000a598, 0x21820220, 0x21820220, 0x15800402, 0x15800402},
+ {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
+ {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603},
+ {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02},
+ {0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04},
+ {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20},
+ {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20},
+ {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22},
+ {0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24},
+ {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640},
+ {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660},
+ {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b801861, 0x3b801861},
+ {0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e801a81, 0x3e801a81},
+ {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42801a83, 0x42801a83},
+ {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x44801c84, 0x44801c84},
+ {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x48801ce3, 0x48801ce3},
+ {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c801ce5, 0x4c801ce5},
+ {0x0000a5dc, 0x7086308c, 0x7086308c, 0x50801ce9, 0x50801ce9},
+ {0x0000a5e0, 0x738a308a, 0x738a308a, 0x54801ceb, 0x54801ceb},
+ {0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+ {0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+ {0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+ {0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+ {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+ {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+ {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+ {0x00016044, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
+ {0x00016048, 0x24927266, 0x24927266, 0x8e483266, 0x8e483266},
+ {0x00016444, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
+ {0x00016448, 0x24927266, 0x24927266, 0x8e482266, 0x8e482266},
+};
+
+static const u32 ar9340_1p0_mac_core[][2] = {
+ /* Addr allmodes */
+ {0x00000008, 0x00000000},
+ {0x00000030, 0x00020085},
+ {0x00000034, 0x00000005},
+ {0x00000040, 0x00000000},
+ {0x00000044, 0x00000000},
+ {0x00000048, 0x00000008},
+ {0x0000004c, 0x00000010},
+ {0x00000050, 0x00000000},
+ {0x00001040, 0x002ffc0f},
+ {0x00001044, 0x002ffc0f},
+ {0x00001048, 0x002ffc0f},
+ {0x0000104c, 0x002ffc0f},
+ {0x00001050, 0x002ffc0f},
+ {0x00001054, 0x002ffc0f},
+ {0x00001058, 0x002ffc0f},
+ {0x0000105c, 0x002ffc0f},
+ {0x00001060, 0x002ffc0f},
+ {0x00001064, 0x002ffc0f},
+ {0x000010f0, 0x00000100},
+ {0x00001270, 0x00000000},
+ {0x000012b0, 0x00000000},
+ {0x000012f0, 0x00000000},
+ {0x0000143c, 0x00000000},
+ {0x0000147c, 0x00000000},
+ {0x00008000, 0x00000000},
+ {0x00008004, 0x00000000},
+ {0x00008008, 0x00000000},
+ {0x0000800c, 0x00000000},
+ {0x00008018, 0x00000000},
+ {0x00008020, 0x00000000},
+ {0x00008038, 0x00000000},
+ {0x0000803c, 0x00000000},
+ {0x00008040, 0x00000000},
+ {0x00008044, 0x00000000},
+ {0x00008048, 0x00000000},
+ {0x0000804c, 0xffffffff},
+ {0x00008054, 0x00000000},
+ {0x00008058, 0x00000000},
+ {0x0000805c, 0x000fc78f},
+ {0x00008060, 0x0000000f},
+ {0x00008064, 0x00000000},
+ {0x00008070, 0x00000310},
+ {0x00008074, 0x00000020},
+ {0x00008078, 0x00000000},
+ {0x0000809c, 0x0000000f},
+ {0x000080a0, 0x00000000},
+ {0x000080a4, 0x02ff0000},
+ {0x000080a8, 0x0e070605},
+ {0x000080ac, 0x0000000d},
+ {0x000080b0, 0x00000000},
+ {0x000080b4, 0x00000000},
+ {0x000080b8, 0x00000000},
+ {0x000080bc, 0x00000000},
+ {0x000080c0, 0x2a800000},
+ {0x000080c4, 0x06900168},
+ {0x000080c8, 0x13881c20},
+ {0x000080cc, 0x01f40000},
+ {0x000080d0, 0x00252500},
+ {0x000080d4, 0x00a00000},
+ {0x000080d8, 0x00400000},
+ {0x000080dc, 0x00000000},
+ {0x000080e0, 0xffffffff},
+ {0x000080e4, 0x0000ffff},
+ {0x000080e8, 0x3f3f3f3f},
+ {0x000080ec, 0x00000000},
+ {0x000080f0, 0x00000000},
+ {0x000080f4, 0x00000000},
+ {0x000080fc, 0x00020000},
+ {0x00008100, 0x00000000},
+ {0x00008108, 0x00000052},
+ {0x0000810c, 0x00000000},
+ {0x00008110, 0x00000000},
+ {0x00008114, 0x000007ff},
+ {0x00008118, 0x000000aa},
+ {0x0000811c, 0x00003210},
+ {0x00008124, 0x00000000},
+ {0x00008128, 0x00000000},
+ {0x0000812c, 0x00000000},
+ {0x00008130, 0x00000000},
+ {0x00008134, 0x00000000},
+ {0x00008138, 0x00000000},
+ {0x0000813c, 0x0000ffff},
+ {0x00008144, 0xffffffff},
+ {0x00008168, 0x00000000},
+ {0x0000816c, 0x00000000},
+ {0x00008170, 0x18486200},
+ {0x00008174, 0x33332210},
+ {0x00008178, 0x00000000},
+ {0x0000817c, 0x00020000},
+ {0x000081c0, 0x00000000},
+ {0x000081c4, 0x33332210},
+ {0x000081c8, 0x00000000},
+ {0x000081cc, 0x00000000},
+ {0x000081d4, 0x00000000},
+ {0x000081ec, 0x00000000},
+ {0x000081f0, 0x00000000},
+ {0x000081f4, 0x00000000},
+ {0x000081f8, 0x00000000},
+ {0x000081fc, 0x00000000},
+ {0x00008240, 0x00100000},
+ {0x00008244, 0x0010f424},
+ {0x00008248, 0x00000800},
+ {0x0000824c, 0x0001e848},
+ {0x00008250, 0x00000000},
+ {0x00008254, 0x00000000},
+ {0x00008258, 0x00000000},
+ {0x0000825c, 0x40000000},
+ {0x00008260, 0x00080922},
+ {0x00008264, 0x9d400010},
+ {0x00008268, 0xffffffff},
+ {0x0000826c, 0x0000ffff},
+ {0x00008270, 0x00000000},
+ {0x00008274, 0x40000000},
+ {0x00008278, 0x003e4180},
+ {0x0000827c, 0x00000004},
+ {0x00008284, 0x0000002c},
+ {0x00008288, 0x0000002c},
+ {0x0000828c, 0x000000ff},
+ {0x00008294, 0x00000000},
+ {0x00008298, 0x00000000},
+ {0x0000829c, 0x00000000},
+ {0x00008300, 0x00000140},
+ {0x00008314, 0x00000000},
+ {0x0000831c, 0x0000010d},
+ {0x00008328, 0x00000000},
+ {0x0000832c, 0x00000007},
+ {0x00008330, 0x00000302},
+ {0x00008334, 0x00000700},
+ {0x00008338, 0x00ff0000},
+ {0x0000833c, 0x02400000},
+ {0x00008340, 0x000107ff},
+ {0x00008344, 0xaa48105b},
+ {0x00008348, 0x008f0000},
+ {0x0000835c, 0x00000000},
+ {0x00008360, 0xffffffff},
+ {0x00008364, 0xffffffff},
+ {0x00008368, 0x00000000},
+ {0x00008370, 0x00000000},
+ {0x00008374, 0x000000ff},
+ {0x00008378, 0x00000000},
+ {0x0000837c, 0x00000000},
+ {0x00008380, 0xffffffff},
+ {0x00008384, 0xffffffff},
+ {0x00008390, 0xffffffff},
+ {0x00008394, 0xffffffff},
+ {0x00008398, 0x00000000},
+ {0x0000839c, 0x00000000},
+ {0x000083a0, 0x00000000},
+ {0x000083a4, 0x0000fa14},
+ {0x000083a8, 0x000f0c00},
+ {0x000083ac, 0x33332210},
+ {0x000083b0, 0x33332210},
+ {0x000083b4, 0x33332210},
+ {0x000083b8, 0x33332210},
+ {0x000083bc, 0x00000000},
+ {0x000083c0, 0x00000000},
+ {0x000083c4, 0x00000000},
+ {0x000083c8, 0x00000000},
+ {0x000083cc, 0x00000200},
+ {0x000083d0, 0x000301ff},
+};
+
+static const u32 ar9340Common_wo_xlna_rx_gain_table_1p0[][2] = {
+ /* Addr allmodes */
+ {0x0000a000, 0x00010000},
+ {0x0000a004, 0x00030002},
+ {0x0000a008, 0x00050004},
+ {0x0000a00c, 0x00810080},
+ {0x0000a010, 0x00830082},
+ {0x0000a014, 0x01810180},
+ {0x0000a018, 0x01830182},
+ {0x0000a01c, 0x01850184},
+ {0x0000a020, 0x01890188},
+ {0x0000a024, 0x018b018a},
+ {0x0000a028, 0x018d018c},
+ {0x0000a02c, 0x03820190},
+ {0x0000a030, 0x03840383},
+ {0x0000a034, 0x03880385},
+ {0x0000a038, 0x038a0389},
+ {0x0000a03c, 0x038c038b},
+ {0x0000a040, 0x0390038d},
+ {0x0000a044, 0x03920391},
+ {0x0000a048, 0x03940393},
+ {0x0000a04c, 0x03960395},
+ {0x0000a050, 0x00000000},
+ {0x0000a054, 0x00000000},
+ {0x0000a058, 0x00000000},
+ {0x0000a05c, 0x00000000},
+ {0x0000a060, 0x00000000},
+ {0x0000a064, 0x00000000},
+ {0x0000a068, 0x00000000},
+ {0x0000a06c, 0x00000000},
+ {0x0000a070, 0x00000000},
+ {0x0000a074, 0x00000000},
+ {0x0000a078, 0x00000000},
+ {0x0000a07c, 0x00000000},
+ {0x0000a080, 0x29292929},
+ {0x0000a084, 0x29292929},
+ {0x0000a088, 0x29292929},
+ {0x0000a08c, 0x29292929},
+ {0x0000a090, 0x22292929},
+ {0x0000a094, 0x1d1d2222},
+ {0x0000a098, 0x0c111117},
+ {0x0000a09c, 0x00030303},
+ {0x0000a0a0, 0x00000000},
+ {0x0000a0a4, 0x00000000},
+ {0x0000a0a8, 0x00000000},
+ {0x0000a0ac, 0x00000000},
+ {0x0000a0b0, 0x00000000},
+ {0x0000a0b4, 0x00000000},
+ {0x0000a0b8, 0x00000000},
+ {0x0000a0bc, 0x00000000},
+ {0x0000a0c0, 0x001f0000},
+ {0x0000a0c4, 0x01000101},
+ {0x0000a0c8, 0x011e011f},
+ {0x0000a0cc, 0x011c011d},
+ {0x0000a0d0, 0x02030204},
+ {0x0000a0d4, 0x02010202},
+ {0x0000a0d8, 0x021f0200},
+ {0x0000a0dc, 0x0302021e},
+ {0x0000a0e0, 0x03000301},
+ {0x0000a0e4, 0x031e031f},
+ {0x0000a0e8, 0x0402031d},
+ {0x0000a0ec, 0x04000401},
+ {0x0000a0f0, 0x041e041f},
+ {0x0000a0f4, 0x0502041d},
+ {0x0000a0f8, 0x05000501},
+ {0x0000a0fc, 0x051e051f},
+ {0x0000a100, 0x06010602},
+ {0x0000a104, 0x061f0600},
+ {0x0000a108, 0x061d061e},
+ {0x0000a10c, 0x07020703},
+ {0x0000a110, 0x07000701},
+ {0x0000a114, 0x00000000},
+ {0x0000a118, 0x00000000},
+ {0x0000a11c, 0x00000000},
+ {0x0000a120, 0x00000000},
+ {0x0000a124, 0x00000000},
+ {0x0000a128, 0x00000000},
+ {0x0000a12c, 0x00000000},
+ {0x0000a130, 0x00000000},
+ {0x0000a134, 0x00000000},
+ {0x0000a138, 0x00000000},
+ {0x0000a13c, 0x00000000},
+ {0x0000a140, 0x001f0000},
+ {0x0000a144, 0x01000101},
+ {0x0000a148, 0x011e011f},
+ {0x0000a14c, 0x011c011d},
+ {0x0000a150, 0x02030204},
+ {0x0000a154, 0x02010202},
+ {0x0000a158, 0x021f0200},
+ {0x0000a15c, 0x0302021e},
+ {0x0000a160, 0x03000301},
+ {0x0000a164, 0x031e031f},
+ {0x0000a168, 0x0402031d},
+ {0x0000a16c, 0x04000401},
+ {0x0000a170, 0x041e041f},
+ {0x0000a174, 0x0502041d},
+ {0x0000a178, 0x05000501},
+ {0x0000a17c, 0x051e051f},
+ {0x0000a180, 0x06010602},
+ {0x0000a184, 0x061f0600},
+ {0x0000a188, 0x061d061e},
+ {0x0000a18c, 0x07020703},
+ {0x0000a190, 0x07000701},
+ {0x0000a194, 0x00000000},
+ {0x0000a198, 0x00000000},
+ {0x0000a19c, 0x00000000},
+ {0x0000a1a0, 0x00000000},
+ {0x0000a1a4, 0x00000000},
+ {0x0000a1a8, 0x00000000},
+ {0x0000a1ac, 0x00000000},
+ {0x0000a1b0, 0x00000000},
+ {0x0000a1b4, 0x00000000},
+ {0x0000a1b8, 0x00000000},
+ {0x0000a1bc, 0x00000000},
+ {0x0000a1c0, 0x00000000},
+ {0x0000a1c4, 0x00000000},
+ {0x0000a1c8, 0x00000000},
+ {0x0000a1cc, 0x00000000},
+ {0x0000a1d0, 0x00000000},
+ {0x0000a1d4, 0x00000000},
+ {0x0000a1d8, 0x00000000},
+ {0x0000a1dc, 0x00000000},
+ {0x0000a1e0, 0x00000000},
+ {0x0000a1e4, 0x00000000},
+ {0x0000a1e8, 0x00000000},
+ {0x0000a1ec, 0x00000000},
+ {0x0000a1f0, 0x00000396},
+ {0x0000a1f4, 0x00000396},
+ {0x0000a1f8, 0x00000396},
+ {0x0000a1fc, 0x00000196},
+ {0x0000b000, 0x00010000},
+ {0x0000b004, 0x00030002},
+ {0x0000b008, 0x00050004},
+ {0x0000b00c, 0x00810080},
+ {0x0000b010, 0x00830082},
+ {0x0000b014, 0x01810180},
+ {0x0000b018, 0x01830182},
+ {0x0000b01c, 0x01850184},
+ {0x0000b020, 0x02810280},
+ {0x0000b024, 0x02830282},
+ {0x0000b028, 0x02850284},
+ {0x0000b02c, 0x02890288},
+ {0x0000b030, 0x028b028a},
+ {0x0000b034, 0x0388028c},
+ {0x0000b038, 0x038a0389},
+ {0x0000b03c, 0x038c038b},
+ {0x0000b040, 0x0390038d},
+ {0x0000b044, 0x03920391},
+ {0x0000b048, 0x03940393},
+ {0x0000b04c, 0x03960395},
+ {0x0000b050, 0x00000000},
+ {0x0000b054, 0x00000000},
+ {0x0000b058, 0x00000000},
+ {0x0000b05c, 0x00000000},
+ {0x0000b060, 0x00000000},
+ {0x0000b064, 0x00000000},
+ {0x0000b068, 0x00000000},
+ {0x0000b06c, 0x00000000},
+ {0x0000b070, 0x00000000},
+ {0x0000b074, 0x00000000},
+ {0x0000b078, 0x00000000},
+ {0x0000b07c, 0x00000000},
+ {0x0000b080, 0x32323232},
+ {0x0000b084, 0x2f2f3232},
+ {0x0000b088, 0x23282a2d},
+ {0x0000b08c, 0x1c1e2123},
+ {0x0000b090, 0x14171919},
+ {0x0000b094, 0x0e0e1214},
+ {0x0000b098, 0x03050707},
+ {0x0000b09c, 0x00030303},
+ {0x0000b0a0, 0x00000000},
+ {0x0000b0a4, 0x00000000},
+ {0x0000b0a8, 0x00000000},
+ {0x0000b0ac, 0x00000000},
+ {0x0000b0b0, 0x00000000},
+ {0x0000b0b4, 0x00000000},
+ {0x0000b0b8, 0x00000000},
+ {0x0000b0bc, 0x00000000},
+ {0x0000b0c0, 0x003f0020},
+ {0x0000b0c4, 0x00400041},
+ {0x0000b0c8, 0x0140005f},
+ {0x0000b0cc, 0x0160015f},
+ {0x0000b0d0, 0x017e017f},
+ {0x0000b0d4, 0x02410242},
+ {0x0000b0d8, 0x025f0240},
+ {0x0000b0dc, 0x027f0260},
+ {0x0000b0e0, 0x0341027e},
+ {0x0000b0e4, 0x035f0340},
+ {0x0000b0e8, 0x037f0360},
+ {0x0000b0ec, 0x04400441},
+ {0x0000b0f0, 0x0460045f},
+ {0x0000b0f4, 0x0541047f},
+ {0x0000b0f8, 0x055f0540},
+ {0x0000b0fc, 0x057f0560},
+ {0x0000b100, 0x06400641},
+ {0x0000b104, 0x0660065f},
+ {0x0000b108, 0x067e067f},
+ {0x0000b10c, 0x07410742},
+ {0x0000b110, 0x075f0740},
+ {0x0000b114, 0x077f0760},
+ {0x0000b118, 0x07800781},
+ {0x0000b11c, 0x07a0079f},
+ {0x0000b120, 0x07c107bf},
+ {0x0000b124, 0x000007c0},
+ {0x0000b128, 0x00000000},
+ {0x0000b12c, 0x00000000},
+ {0x0000b130, 0x00000000},
+ {0x0000b134, 0x00000000},
+ {0x0000b138, 0x00000000},
+ {0x0000b13c, 0x00000000},
+ {0x0000b140, 0x003f0020},
+ {0x0000b144, 0x00400041},
+ {0x0000b148, 0x0140005f},
+ {0x0000b14c, 0x0160015f},
+ {0x0000b150, 0x017e017f},
+ {0x0000b154, 0x02410242},
+ {0x0000b158, 0x025f0240},
+ {0x0000b15c, 0x027f0260},
+ {0x0000b160, 0x0341027e},
+ {0x0000b164, 0x035f0340},
+ {0x0000b168, 0x037f0360},
+ {0x0000b16c, 0x04400441},
+ {0x0000b170, 0x0460045f},
+ {0x0000b174, 0x0541047f},
+ {0x0000b178, 0x055f0540},
+ {0x0000b17c, 0x057f0560},
+ {0x0000b180, 0x06400641},
+ {0x0000b184, 0x0660065f},
+ {0x0000b188, 0x067e067f},
+ {0x0000b18c, 0x07410742},
+ {0x0000b190, 0x075f0740},
+ {0x0000b194, 0x077f0760},
+ {0x0000b198, 0x07800781},
+ {0x0000b19c, 0x07a0079f},
+ {0x0000b1a0, 0x07c107bf},
+ {0x0000b1a4, 0x000007c0},
+ {0x0000b1a8, 0x00000000},
+ {0x0000b1ac, 0x00000000},
+ {0x0000b1b0, 0x00000000},
+ {0x0000b1b4, 0x00000000},
+ {0x0000b1b8, 0x00000000},
+ {0x0000b1bc, 0x00000000},
+ {0x0000b1c0, 0x00000000},
+ {0x0000b1c4, 0x00000000},
+ {0x0000b1c8, 0x00000000},
+ {0x0000b1cc, 0x00000000},
+ {0x0000b1d0, 0x00000000},
+ {0x0000b1d4, 0x00000000},
+ {0x0000b1d8, 0x00000000},
+ {0x0000b1dc, 0x00000000},
+ {0x0000b1e0, 0x00000000},
+ {0x0000b1e4, 0x00000000},
+ {0x0000b1e8, 0x00000000},
+ {0x0000b1ec, 0x00000000},
+ {0x0000b1f0, 0x00000396},
+ {0x0000b1f4, 0x00000396},
+ {0x0000b1f8, 0x00000396},
+ {0x0000b1fc, 0x00000196},
+};
+
+static const u32 ar9340_1p0_soc_preamble[][2] = {
+ /* Addr allmodes */
+ {0x000040a4, 0x00a0c1c9},
+ {0x00007008, 0x00000000},
+ {0x00007020, 0x00000000},
+ {0x00007034, 0x00000002},
+ {0x00007038, 0x000004c2},
+};
+
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
index 71cc0a3a29f..fbdde29f0ab 100644
--- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
@@ -17,931 +17,6 @@
#ifndef INITVALS_9485_H
#define INITVALS_9485_H
-static const u32 ar9485Common_1_0[][2] = {
- /* Addr allmodes */
- {0x00007010, 0x00000022},
- {0x00007020, 0x00000000},
- {0x00007034, 0x00000002},
- {0x00007038, 0x000004c2},
-};
-
-static const u32 ar9485_1_0_mac_postamble[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
- {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
- {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
- {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
- {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
- {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
- {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
- {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
- {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
-};
-
-static const u32 ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1[][2] = {
- /* Addr allmodes */
- {0x00018c00, 0x10212e5e},
- {0x00018c04, 0x000801d8},
- {0x00018c08, 0x0000580c},
-};
-
-static const u32 ar9485Common_wo_xlna_rx_gain_1_0[][2] = {
- /* Addr allmodes */
- {0x0000a000, 0x00010000},
- {0x0000a004, 0x00030002},
- {0x0000a008, 0x00050004},
- {0x0000a00c, 0x00810080},
- {0x0000a010, 0x01800082},
- {0x0000a014, 0x01820181},
- {0x0000a018, 0x01840183},
- {0x0000a01c, 0x01880185},
- {0x0000a020, 0x018a0189},
- {0x0000a024, 0x02850284},
- {0x0000a028, 0x02890288},
- {0x0000a02c, 0x03850384},
- {0x0000a030, 0x03890388},
- {0x0000a034, 0x038b038a},
- {0x0000a038, 0x038d038c},
- {0x0000a03c, 0x03910390},
- {0x0000a040, 0x03930392},
- {0x0000a044, 0x03950394},
- {0x0000a048, 0x00000396},
- {0x0000a04c, 0x00000000},
- {0x0000a050, 0x00000000},
- {0x0000a054, 0x00000000},
- {0x0000a058, 0x00000000},
- {0x0000a05c, 0x00000000},
- {0x0000a060, 0x00000000},
- {0x0000a064, 0x00000000},
- {0x0000a068, 0x00000000},
- {0x0000a06c, 0x00000000},
- {0x0000a070, 0x00000000},
- {0x0000a074, 0x00000000},
- {0x0000a078, 0x00000000},
- {0x0000a07c, 0x00000000},
- {0x0000a080, 0x28282828},
- {0x0000a084, 0x28282828},
- {0x0000a088, 0x28282828},
- {0x0000a08c, 0x28282828},
- {0x0000a090, 0x28282828},
- {0x0000a094, 0x21212128},
- {0x0000a098, 0x171c1c1c},
- {0x0000a09c, 0x02020212},
- {0x0000a0a0, 0x00000202},
- {0x0000a0a4, 0x00000000},
- {0x0000a0a8, 0x00000000},
- {0x0000a0ac, 0x00000000},
- {0x0000a0b0, 0x00000000},
- {0x0000a0b4, 0x00000000},
- {0x0000a0b8, 0x00000000},
- {0x0000a0bc, 0x00000000},
- {0x0000a0c0, 0x001f0000},
- {0x0000a0c4, 0x111f1100},
- {0x0000a0c8, 0x111d111e},
- {0x0000a0cc, 0x111b111c},
- {0x0000a0d0, 0x22032204},
- {0x0000a0d4, 0x22012202},
- {0x0000a0d8, 0x221f2200},
- {0x0000a0dc, 0x221d221e},
- {0x0000a0e0, 0x33013302},
- {0x0000a0e4, 0x331f3300},
- {0x0000a0e8, 0x4402331e},
- {0x0000a0ec, 0x44004401},
- {0x0000a0f0, 0x441e441f},
- {0x0000a0f4, 0x55015502},
- {0x0000a0f8, 0x551f5500},
- {0x0000a0fc, 0x6602551e},
- {0x0000a100, 0x66006601},
- {0x0000a104, 0x661e661f},
- {0x0000a108, 0x7703661d},
- {0x0000a10c, 0x77017702},
- {0x0000a110, 0x00007700},
- {0x0000a114, 0x00000000},
- {0x0000a118, 0x00000000},
- {0x0000a11c, 0x00000000},
- {0x0000a120, 0x00000000},
- {0x0000a124, 0x00000000},
- {0x0000a128, 0x00000000},
- {0x0000a12c, 0x00000000},
- {0x0000a130, 0x00000000},
- {0x0000a134, 0x00000000},
- {0x0000a138, 0x00000000},
- {0x0000a13c, 0x00000000},
- {0x0000a140, 0x001f0000},
- {0x0000a144, 0x111f1100},
- {0x0000a148, 0x111d111e},
- {0x0000a14c, 0x111b111c},
- {0x0000a150, 0x22032204},
- {0x0000a154, 0x22012202},
- {0x0000a158, 0x221f2200},
- {0x0000a15c, 0x221d221e},
- {0x0000a160, 0x33013302},
- {0x0000a164, 0x331f3300},
- {0x0000a168, 0x4402331e},
- {0x0000a16c, 0x44004401},
- {0x0000a170, 0x441e441f},
- {0x0000a174, 0x55015502},
- {0x0000a178, 0x551f5500},
- {0x0000a17c, 0x6602551e},
- {0x0000a180, 0x66006601},
- {0x0000a184, 0x661e661f},
- {0x0000a188, 0x7703661d},
- {0x0000a18c, 0x77017702},
- {0x0000a190, 0x00007700},
- {0x0000a194, 0x00000000},
- {0x0000a198, 0x00000000},
- {0x0000a19c, 0x00000000},
- {0x0000a1a0, 0x00000000},
- {0x0000a1a4, 0x00000000},
- {0x0000a1a8, 0x00000000},
- {0x0000a1ac, 0x00000000},
- {0x0000a1b0, 0x00000000},
- {0x0000a1b4, 0x00000000},
- {0x0000a1b8, 0x00000000},
- {0x0000a1bc, 0x00000000},
- {0x0000a1c0, 0x00000000},
- {0x0000a1c4, 0x00000000},
- {0x0000a1c8, 0x00000000},
- {0x0000a1cc, 0x00000000},
- {0x0000a1d0, 0x00000000},
- {0x0000a1d4, 0x00000000},
- {0x0000a1d8, 0x00000000},
- {0x0000a1dc, 0x00000000},
- {0x0000a1e0, 0x00000000},
- {0x0000a1e4, 0x00000000},
- {0x0000a1e8, 0x00000000},
- {0x0000a1ec, 0x00000000},
- {0x0000a1f0, 0x00000396},
- {0x0000a1f4, 0x00000396},
- {0x0000a1f8, 0x00000396},
- {0x0000a1fc, 0x00000296},
-};
-
-static const u32 ar9485Modes_high_power_tx_gain_1_0[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
- {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
- {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
- {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
- {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
- {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
- {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
- {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
- {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
- {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
- {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
- {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
- {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
- {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
- {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
- {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
- {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
- {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
- {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
- {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
- {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
- {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
- {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
- {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
- {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
- {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
- {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
- {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
- {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
-};
-
-static const u32 ar9485_1_0[][2] = {
- /* Addr allmodes */
- {0x0000a580, 0x00000000},
- {0x0000a584, 0x00000000},
- {0x0000a588, 0x00000000},
- {0x0000a58c, 0x00000000},
- {0x0000a590, 0x00000000},
- {0x0000a594, 0x00000000},
- {0x0000a598, 0x00000000},
- {0x0000a59c, 0x00000000},
- {0x0000a5a0, 0x00000000},
- {0x0000a5a4, 0x00000000},
- {0x0000a5a8, 0x00000000},
- {0x0000a5ac, 0x00000000},
- {0x0000a5b0, 0x00000000},
- {0x0000a5b4, 0x00000000},
- {0x0000a5b8, 0x00000000},
- {0x0000a5bc, 0x00000000},
-};
-
-static const u32 ar9485_1_0_radio_core[][2] = {
- /* Addr allmodes */
- {0x00016000, 0x36db6db6},
- {0x00016004, 0x6db6db40},
- {0x00016008, 0x73800000},
- {0x0001600c, 0x00000000},
- {0x00016040, 0x7f80fff8},
- {0x00016048, 0x6c92426e},
- {0x0001604c, 0x000f0278},
- {0x00016050, 0x6db6db6c},
- {0x00016054, 0x6db60000},
- {0x00016080, 0x00080000},
- {0x00016084, 0x0e48048c},
- {0x00016088, 0x14214514},
- {0x0001608c, 0x119f081e},
- {0x00016090, 0x24926490},
- {0x00016098, 0xd28b3330},
- {0x000160a0, 0xc2108ffe},
- {0x000160a4, 0x812fc370},
- {0x000160a8, 0x423c8000},
- {0x000160b4, 0x92480040},
- {0x000160c0, 0x006db6db},
- {0x000160c4, 0x0186db60},
- {0x000160c8, 0x6db6db6c},
- {0x000160cc, 0x6de6fbe0},
- {0x000160d0, 0xf7dfcf3c},
- {0x00016100, 0x04cb0001},
- {0x00016104, 0xfff80015},
- {0x00016108, 0x00080010},
- {0x00016144, 0x01884080},
- {0x00016148, 0x00008040},
- {0x00016180, 0x08453333},
- {0x00016184, 0x18e82f01},
- {0x00016188, 0x00000000},
- {0x0001618c, 0x00000000},
- {0x00016240, 0x08400000},
- {0x00016244, 0x1bf90f00},
- {0x00016248, 0x00000000},
- {0x0001624c, 0x00000000},
- {0x00016280, 0x01000015},
- {0x00016284, 0x00d30000},
- {0x00016288, 0x00318000},
- {0x0001628c, 0x50000000},
- {0x00016290, 0x4b96210f},
- {0x00016380, 0x00000000},
- {0x00016384, 0x00000000},
- {0x00016388, 0x00800700},
- {0x0001638c, 0x00800700},
- {0x00016390, 0x00800700},
- {0x00016394, 0x00000000},
- {0x00016398, 0x00000000},
- {0x0001639c, 0x00000000},
- {0x000163a0, 0x00000001},
- {0x000163a4, 0x00000001},
- {0x000163a8, 0x00000000},
- {0x000163ac, 0x00000000},
- {0x000163b0, 0x00000000},
- {0x000163b4, 0x00000000},
- {0x000163b8, 0x00000000},
- {0x000163bc, 0x00000000},
- {0x000163c0, 0x000000a0},
- {0x000163c4, 0x000c0000},
- {0x000163c8, 0x14021402},
- {0x000163cc, 0x00001402},
- {0x000163d0, 0x00000000},
- {0x000163d4, 0x00000000},
- {0x00016c40, 0x1319c178},
- {0x00016c44, 0x10000000},
-};
-
-static const u32 ar9485Modes_lowest_ob_db_tx_gain_1_0[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
- {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
- {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
- {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
- {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
- {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
- {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
- {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
- {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
- {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
- {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
- {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
- {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
- {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
- {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
- {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
- {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
- {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
- {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
- {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
- {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
- {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
- {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
- {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
- {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
- {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
- {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
- {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
- {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
-};
-
-static const u32 ar9485_1_0_baseband_core[][2] = {
- /* Addr allmodes */
- {0x00009800, 0xafe68e30},
- {0x00009804, 0xfd14e000},
- {0x00009808, 0x9c0a8f6b},
- {0x0000980c, 0x04800000},
- {0x00009814, 0x9280c00a},
- {0x00009818, 0x00000000},
- {0x0000981c, 0x00020028},
- {0x00009834, 0x5f3ca3de},
- {0x00009838, 0x0108ecff},
- {0x0000983c, 0x14750600},
- {0x00009880, 0x201fff00},
- {0x00009884, 0x00001042},
- {0x000098a4, 0x00200400},
- {0x000098b0, 0x52440bbe},
- {0x000098bc, 0x00000002},
- {0x000098d0, 0x004b6a8e},
- {0x000098d4, 0x00000820},
- {0x000098dc, 0x00000000},
- {0x000098f0, 0x00000000},
- {0x000098f4, 0x00000000},
- {0x00009c04, 0x00000000},
- {0x00009c08, 0x03200000},
- {0x00009c0c, 0x00000000},
- {0x00009c10, 0x00000000},
- {0x00009c14, 0x00046384},
- {0x00009c18, 0x05b6b440},
- {0x00009c1c, 0x00b6b440},
- {0x00009d00, 0xc080a333},
- {0x00009d04, 0x40206c10},
- {0x00009d08, 0x009c4060},
- {0x00009d0c, 0x1883800a},
- {0x00009d10, 0x01834061},
- {0x00009d14, 0x00c00400},
- {0x00009d18, 0x00000000},
- {0x00009d1c, 0x00000000},
- {0x00009e08, 0x0038233c},
- {0x00009e24, 0x990bb515},
- {0x00009e28, 0x0a6f0000},
- {0x00009e30, 0x06336f77},
- {0x00009e34, 0x6af6532f},
- {0x00009e38, 0x0cc80c00},
- {0x00009e40, 0x0d261820},
- {0x00009e4c, 0x00001004},
- {0x00009e50, 0x00ff03f1},
- {0x00009fc0, 0x80be4788},
- {0x00009fc4, 0x0001efb5},
- {0x00009fcc, 0x40000014},
- {0x0000a20c, 0x00000000},
- {0x0000a210, 0x00000000},
- {0x0000a220, 0x00000000},
- {0x0000a224, 0x00000000},
- {0x0000a228, 0x10002310},
- {0x0000a23c, 0x00000000},
- {0x0000a244, 0x0c000000},
- {0x0000a2a0, 0x00000001},
- {0x0000a2c0, 0x00000001},
- {0x0000a2c8, 0x00000000},
- {0x0000a2cc, 0x18c43433},
- {0x0000a2d4, 0x00000000},
- {0x0000a2dc, 0x00000000},
- {0x0000a2e0, 0x00000000},
- {0x0000a2e4, 0x00000000},
- {0x0000a2e8, 0x00000000},
- {0x0000a2ec, 0x00000000},
- {0x0000a2f0, 0x00000000},
- {0x0000a2f4, 0x00000000},
- {0x0000a2f8, 0x00000000},
- {0x0000a344, 0x00000000},
- {0x0000a34c, 0x00000000},
- {0x0000a350, 0x0000a000},
- {0x0000a364, 0x00000000},
- {0x0000a370, 0x00000000},
- {0x0000a390, 0x00000001},
- {0x0000a394, 0x00000444},
- {0x0000a398, 0x001f0e0f},
- {0x0000a39c, 0x0075393f},
- {0x0000a3a0, 0xb79f6427},
- {0x0000a3a4, 0x00000000},
- {0x0000a3a8, 0xaaaaaaaa},
- {0x0000a3ac, 0x3c466478},
- {0x0000a3c0, 0x20202020},
- {0x0000a3c4, 0x22222220},
- {0x0000a3c8, 0x20200020},
- {0x0000a3cc, 0x20202020},
- {0x0000a3d0, 0x20202020},
- {0x0000a3d4, 0x20202020},
- {0x0000a3d8, 0x20202020},
- {0x0000a3dc, 0x20202020},
- {0x0000a3e0, 0x20202020},
- {0x0000a3e4, 0x20202020},
- {0x0000a3e8, 0x20202020},
- {0x0000a3ec, 0x20202020},
- {0x0000a3f0, 0x00000000},
- {0x0000a3f4, 0x00000006},
- {0x0000a3f8, 0x0cdbd380},
- {0x0000a3fc, 0x000f0f01},
- {0x0000a400, 0x8fa91f01},
- {0x0000a404, 0x00000000},
- {0x0000a408, 0x0e79e5c6},
- {0x0000a40c, 0x00820820},
- {0x0000a414, 0x1ce739ce},
- {0x0000a418, 0x2d0011ce},
- {0x0000a41c, 0x1ce739ce},
- {0x0000a420, 0x000001ce},
- {0x0000a424, 0x1ce739ce},
- {0x0000a428, 0x000001ce},
- {0x0000a42c, 0x1ce739ce},
- {0x0000a430, 0x1ce739ce},
- {0x0000a434, 0x00000000},
- {0x0000a438, 0x00001801},
- {0x0000a43c, 0x00000000},
- {0x0000a440, 0x00000000},
- {0x0000a444, 0x00000000},
- {0x0000a448, 0x04000000},
- {0x0000a44c, 0x00000001},
- {0x0000a450, 0x00010000},
- {0x0000a458, 0x00000000},
- {0x0000a5c4, 0x3fad9d74},
- {0x0000a5c8, 0x0048060a},
- {0x0000a5cc, 0x00000637},
- {0x0000a760, 0x03020100},
- {0x0000a764, 0x09080504},
- {0x0000a768, 0x0d0c0b0a},
- {0x0000a76c, 0x13121110},
- {0x0000a770, 0x31301514},
- {0x0000a774, 0x35343332},
- {0x0000a778, 0x00000036},
- {0x0000a780, 0x00000838},
- {0x0000a7c0, 0x00000000},
- {0x0000a7c4, 0xfffffffc},
- {0x0000a7c8, 0x00000000},
- {0x0000a7cc, 0x00000000},
- {0x0000a7d0, 0x00000000},
- {0x0000a7d4, 0x00000004},
- {0x0000a7dc, 0x00000001},
-};
-
-static const u32 ar9485Modes_high_ob_db_tx_gain_1_0[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
- {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
- {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
- {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
- {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
- {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
- {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
- {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
- {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
- {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
- {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
- {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
- {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
- {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
- {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
- {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
- {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
- {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
- {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
- {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
- {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
- {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
- {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
- {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
- {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
- {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
- {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
- {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
- {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
-};
-
-static const u32 ar9485Common_rx_gain_1_0[][2] = {
- /* Addr allmodes */
- {0x0000a000, 0x00010000},
- {0x0000a004, 0x00030002},
- {0x0000a008, 0x00050004},
- {0x0000a00c, 0x00810080},
- {0x0000a010, 0x01800082},
- {0x0000a014, 0x01820181},
- {0x0000a018, 0x01840183},
- {0x0000a01c, 0x01880185},
- {0x0000a020, 0x018a0189},
- {0x0000a024, 0x02850284},
- {0x0000a028, 0x02890288},
- {0x0000a02c, 0x03850384},
- {0x0000a030, 0x03890388},
- {0x0000a034, 0x038b038a},
- {0x0000a038, 0x038d038c},
- {0x0000a03c, 0x03910390},
- {0x0000a040, 0x03930392},
- {0x0000a044, 0x03950394},
- {0x0000a048, 0x00000396},
- {0x0000a04c, 0x00000000},
- {0x0000a050, 0x00000000},
- {0x0000a054, 0x00000000},
- {0x0000a058, 0x00000000},
- {0x0000a05c, 0x00000000},
- {0x0000a060, 0x00000000},
- {0x0000a064, 0x00000000},
- {0x0000a068, 0x00000000},
- {0x0000a06c, 0x00000000},
- {0x0000a070, 0x00000000},
- {0x0000a074, 0x00000000},
- {0x0000a078, 0x00000000},
- {0x0000a07c, 0x00000000},
- {0x0000a080, 0x28282828},
- {0x0000a084, 0x28282828},
- {0x0000a088, 0x28282828},
- {0x0000a08c, 0x28282828},
- {0x0000a090, 0x28282828},
- {0x0000a094, 0x21212128},
- {0x0000a098, 0x171c1c1c},
- {0x0000a09c, 0x02020212},
- {0x0000a0a0, 0x00000202},
- {0x0000a0a4, 0x00000000},
- {0x0000a0a8, 0x00000000},
- {0x0000a0ac, 0x00000000},
- {0x0000a0b0, 0x00000000},
- {0x0000a0b4, 0x00000000},
- {0x0000a0b8, 0x00000000},
- {0x0000a0bc, 0x00000000},
- {0x0000a0c0, 0x001f0000},
- {0x0000a0c4, 0x111f1100},
- {0x0000a0c8, 0x111d111e},
- {0x0000a0cc, 0x111b111c},
- {0x0000a0d0, 0x22032204},
- {0x0000a0d4, 0x22012202},
- {0x0000a0d8, 0x221f2200},
- {0x0000a0dc, 0x221d221e},
- {0x0000a0e0, 0x33013302},
- {0x0000a0e4, 0x331f3300},
- {0x0000a0e8, 0x4402331e},
- {0x0000a0ec, 0x44004401},
- {0x0000a0f0, 0x441e441f},
- {0x0000a0f4, 0x55015502},
- {0x0000a0f8, 0x551f5500},
- {0x0000a0fc, 0x6602551e},
- {0x0000a100, 0x66006601},
- {0x0000a104, 0x661e661f},
- {0x0000a108, 0x7703661d},
- {0x0000a10c, 0x77017702},
- {0x0000a110, 0x00007700},
- {0x0000a114, 0x00000000},
- {0x0000a118, 0x00000000},
- {0x0000a11c, 0x00000000},
- {0x0000a120, 0x00000000},
- {0x0000a124, 0x00000000},
- {0x0000a128, 0x00000000},
- {0x0000a12c, 0x00000000},
- {0x0000a130, 0x00000000},
- {0x0000a134, 0x00000000},
- {0x0000a138, 0x00000000},
- {0x0000a13c, 0x00000000},
- {0x0000a140, 0x001f0000},
- {0x0000a144, 0x111f1100},
- {0x0000a148, 0x111d111e},
- {0x0000a14c, 0x111b111c},
- {0x0000a150, 0x22032204},
- {0x0000a154, 0x22012202},
- {0x0000a158, 0x221f2200},
- {0x0000a15c, 0x221d221e},
- {0x0000a160, 0x33013302},
- {0x0000a164, 0x331f3300},
- {0x0000a168, 0x4402331e},
- {0x0000a16c, 0x44004401},
- {0x0000a170, 0x441e441f},
- {0x0000a174, 0x55015502},
- {0x0000a178, 0x551f5500},
- {0x0000a17c, 0x6602551e},
- {0x0000a180, 0x66006601},
- {0x0000a184, 0x661e661f},
- {0x0000a188, 0x7703661d},
- {0x0000a18c, 0x77017702},
- {0x0000a190, 0x00007700},
- {0x0000a194, 0x00000000},
- {0x0000a198, 0x00000000},
- {0x0000a19c, 0x00000000},
- {0x0000a1a0, 0x00000000},
- {0x0000a1a4, 0x00000000},
- {0x0000a1a8, 0x00000000},
- {0x0000a1ac, 0x00000000},
- {0x0000a1b0, 0x00000000},
- {0x0000a1b4, 0x00000000},
- {0x0000a1b8, 0x00000000},
- {0x0000a1bc, 0x00000000},
- {0x0000a1c0, 0x00000000},
- {0x0000a1c4, 0x00000000},
- {0x0000a1c8, 0x00000000},
- {0x0000a1cc, 0x00000000},
- {0x0000a1d0, 0x00000000},
- {0x0000a1d4, 0x00000000},
- {0x0000a1d8, 0x00000000},
- {0x0000a1dc, 0x00000000},
- {0x0000a1e0, 0x00000000},
- {0x0000a1e4, 0x00000000},
- {0x0000a1e8, 0x00000000},
- {0x0000a1ec, 0x00000000},
- {0x0000a1f0, 0x00000396},
- {0x0000a1f4, 0x00000396},
- {0x0000a1f8, 0x00000396},
- {0x0000a1fc, 0x00000296},
-};
-
-static const u32 ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1[][2] = {
- /* Addr allmodes */
- {0x00018c00, 0x10252e5e},
- {0x00018c04, 0x000801d8},
- {0x00018c08, 0x0000580c},
-};
-
-static const u32 ar9485_1_0_pcie_phy_clkreq_enable_L1[][2] = {
- /* Addr allmodes */
- {0x00018c00, 0x10253e5e},
- {0x00018c04, 0x000801d8},
- {0x00018c08, 0x0000580c},
-};
-
-static const u32 ar9485_1_0_soc_preamble[][2] = {
- /* Addr allmodes */
- {0x00004090, 0x00aa10aa},
- {0x000040a4, 0x00a0c9c9},
- {0x00007048, 0x00000004},
-};
-
-static const u32 ar9485_fast_clock_1_0_baseband_postamble[][3] = {
- /* Addr 5G_HT20 5G_HT40 */
- {0x00009e00, 0x03721821, 0x03721821},
- {0x0000a230, 0x0000400b, 0x00004016},
- {0x0000a254, 0x00000898, 0x00001130},
-};
-
-static const u32 ar9485_1_0_baseband_postamble[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
- {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005},
- {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e},
- {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
- {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
- {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
- {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
- {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044},
- {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
- {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
- {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
- {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e},
- {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
- {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
- {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
- {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
- {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222},
- {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324},
- {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010},
- {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
- {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0},
- {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
- {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b},
- {0x0000a234, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff},
- {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
- {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
- {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
- {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
- {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
- {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501},
- {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
- {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
- {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0},
- {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
- {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
- {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
- {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000be04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
- {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-};
-
-static const u32 ar9485Modes_low_ob_db_tx_gain_1_0[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
- {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
- {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
- {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
- {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
- {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
- {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
- {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
- {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
- {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
- {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
- {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
- {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
- {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
- {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
- {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
- {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
- {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
- {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
- {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
- {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
- {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
- {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
- {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
- {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
- {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
- {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
- {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
- {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
- {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
-};
-
-static const u32 ar9485_1_0_pcie_phy_clkreq_disable_L1[][2] = {
- /* Addr allmodes */
- {0x00018c00, 0x10213e5e},
- {0x00018c04, 0x000801d8},
- {0x00018c08, 0x0000580c},
-};
-
-static const u32 ar9485_1_0_radio_postamble[][2] = {
- /* Addr allmodes */
- {0x0001609c, 0x0b283f31},
- {0x000160ac, 0x24611800},
- {0x000160b0, 0x03284f3e},
- {0x0001610c, 0x00170000},
- {0x00016140, 0x10804008},
-};
-
-static const u32 ar9485_1_0_mac_core[][2] = {
- /* Addr allmodes */
- {0x00000008, 0x00000000},
- {0x00000030, 0x00020085},
- {0x00000034, 0x00000005},
- {0x00000040, 0x00000000},
- {0x00000044, 0x00000000},
- {0x00000048, 0x00000008},
- {0x0000004c, 0x00000010},
- {0x00000050, 0x00000000},
- {0x00001040, 0x002ffc0f},
- {0x00001044, 0x002ffc0f},
- {0x00001048, 0x002ffc0f},
- {0x0000104c, 0x002ffc0f},
- {0x00001050, 0x002ffc0f},
- {0x00001054, 0x002ffc0f},
- {0x00001058, 0x002ffc0f},
- {0x0000105c, 0x002ffc0f},
- {0x00001060, 0x002ffc0f},
- {0x00001064, 0x002ffc0f},
- {0x000010f0, 0x00000100},
- {0x00001270, 0x00000000},
- {0x000012b0, 0x00000000},
- {0x000012f0, 0x00000000},
- {0x0000143c, 0x00000000},
- {0x0000147c, 0x00000000},
- {0x00008000, 0x00000000},
- {0x00008004, 0x00000000},
- {0x00008008, 0x00000000},
- {0x0000800c, 0x00000000},
- {0x00008018, 0x00000000},
- {0x00008020, 0x00000000},
- {0x00008038, 0x00000000},
- {0x0000803c, 0x00000000},
- {0x00008040, 0x00000000},
- {0x00008044, 0x00000000},
- {0x00008048, 0x00000000},
- {0x0000804c, 0xffffffff},
- {0x00008054, 0x00000000},
- {0x00008058, 0x00000000},
- {0x0000805c, 0x000fc78f},
- {0x00008060, 0x0000000f},
- {0x00008064, 0x00000000},
- {0x00008070, 0x00000310},
- {0x00008074, 0x00000020},
- {0x00008078, 0x00000000},
- {0x0000809c, 0x0000000f},
- {0x000080a0, 0x00000000},
- {0x000080a4, 0x02ff0000},
- {0x000080a8, 0x0e070605},
- {0x000080ac, 0x0000000d},
- {0x000080b0, 0x00000000},
- {0x000080b4, 0x00000000},
- {0x000080b8, 0x00000000},
- {0x000080bc, 0x00000000},
- {0x000080c0, 0x2a800000},
- {0x000080c4, 0x06900168},
- {0x000080c8, 0x13881c20},
- {0x000080cc, 0x01f40000},
- {0x000080d0, 0x00252500},
- {0x000080d4, 0x00a00000},
- {0x000080d8, 0x00400000},
- {0x000080dc, 0x00000000},
- {0x000080e0, 0xffffffff},
- {0x000080e4, 0x0000ffff},
- {0x000080e8, 0x3f3f3f3f},
- {0x000080ec, 0x00000000},
- {0x000080f0, 0x00000000},
- {0x000080f4, 0x00000000},
- {0x000080fc, 0x00020000},
- {0x00008100, 0x00000000},
- {0x00008108, 0x00000052},
- {0x0000810c, 0x00000000},
- {0x00008110, 0x00000000},
- {0x00008114, 0x000007ff},
- {0x00008118, 0x000000aa},
- {0x0000811c, 0x00003210},
- {0x00008124, 0x00000000},
- {0x00008128, 0x00000000},
- {0x0000812c, 0x00000000},
- {0x00008130, 0x00000000},
- {0x00008134, 0x00000000},
- {0x00008138, 0x00000000},
- {0x0000813c, 0x0000ffff},
- {0x00008144, 0xffffffff},
- {0x00008168, 0x00000000},
- {0x0000816c, 0x00000000},
- {0x00008170, 0x18486200},
- {0x00008174, 0x33332210},
- {0x00008178, 0x00000000},
- {0x0000817c, 0x00020000},
- {0x000081c0, 0x00000000},
- {0x000081c4, 0x33332210},
- {0x000081c8, 0x00000000},
- {0x000081cc, 0x00000000},
- {0x000081d4, 0x00000000},
- {0x000081ec, 0x00000000},
- {0x000081f0, 0x00000000},
- {0x000081f4, 0x00000000},
- {0x000081f8, 0x00000000},
- {0x000081fc, 0x00000000},
- {0x00008240, 0x00100000},
- {0x00008244, 0x0010f400},
- {0x00008248, 0x00000800},
- {0x0000824c, 0x0001e800},
- {0x00008250, 0x00000000},
- {0x00008254, 0x00000000},
- {0x00008258, 0x00000000},
- {0x0000825c, 0x40000000},
- {0x00008260, 0x00080922},
- {0x00008264, 0x9ca00010},
- {0x00008268, 0xffffffff},
- {0x0000826c, 0x0000ffff},
- {0x00008270, 0x00000000},
- {0x00008274, 0x40000000},
- {0x00008278, 0x003e4180},
- {0x0000827c, 0x00000004},
- {0x00008284, 0x0000002c},
- {0x00008288, 0x0000002c},
- {0x0000828c, 0x000000ff},
- {0x00008294, 0x00000000},
- {0x00008298, 0x00000000},
- {0x0000829c, 0x00000000},
- {0x00008300, 0x00000140},
- {0x00008314, 0x00000000},
- {0x0000831c, 0x0000010d},
- {0x00008328, 0x00000000},
- {0x0000832c, 0x00000007},
- {0x00008330, 0x00000302},
- {0x00008334, 0x00000700},
- {0x00008338, 0x00ff0000},
- {0x0000833c, 0x02400000},
- {0x00008340, 0x000107ff},
- {0x00008344, 0xa248105b},
- {0x00008348, 0x008f0000},
- {0x0000835c, 0x00000000},
- {0x00008360, 0xffffffff},
- {0x00008364, 0xffffffff},
- {0x00008368, 0x00000000},
- {0x00008370, 0x00000000},
- {0x00008374, 0x000000ff},
- {0x00008378, 0x00000000},
- {0x0000837c, 0x00000000},
- {0x00008380, 0xffffffff},
- {0x00008384, 0xffffffff},
- {0x00008390, 0xffffffff},
- {0x00008394, 0xffffffff},
- {0x00008398, 0x00000000},
- {0x0000839c, 0x00000000},
- {0x000083a0, 0x00000000},
- {0x000083a4, 0x0000fa14},
- {0x000083a8, 0x000f0c00},
- {0x000083ac, 0x33332210},
- {0x000083b0, 0x33332210},
- {0x000083b4, 0x33332210},
- {0x000083b8, 0x33332210},
- {0x000083bc, 0x00000000},
- {0x000083c0, 0x00000000},
- {0x000083c4, 0x00000000},
- {0x000083c8, 0x00000000},
- {0x000083cc, 0x00000200},
- {0x000083d0, 0x000301ff},
-};
-
static const u32 ar9485_1_1_mac_core[][2] = {
/* Addr allmodes */
{0x00000008, 0x00000000},
@@ -1321,7 +396,7 @@ static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = {
{0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
- {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb},
+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
{0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
{0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
@@ -1394,7 +469,7 @@ static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = {
{0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
- {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb},
+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
{0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
{0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
@@ -1560,7 +635,7 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = {
{0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
- {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb},
+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
{0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
{0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
@@ -1653,7 +728,7 @@ static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = {
{0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
- {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb},
+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
{0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
{0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
@@ -1752,7 +827,7 @@ static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = {
{0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
- {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb},
+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
{0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
{0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 099bd4183ad..03b37d7be1c 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -62,7 +62,6 @@ struct ath_node;
#define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i))
struct ath_config {
- u32 ath_aggr_prot;
u16 txpowlimit;
u8 cabqReadytime;
};
@@ -120,13 +119,11 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
/* RX / TX */
/***********/
-#define ATH_MAX_ANTENNA 3
#define ATH_RXBUF 512
#define ATH_TXBUF 512
#define ATH_TXBUF_RESERVE 5
#define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE)
#define ATH_TXMAXTRY 13
-#define ATH_MGT_TXMAXTRY 4
#define TID_TO_WME_AC(_tid) \
((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
@@ -202,6 +199,7 @@ struct ath_atx_ac {
int sched;
struct list_head list;
struct list_head tid_q;
+ bool clear_ps_filter;
};
struct ath_frame_info {
@@ -257,8 +255,12 @@ struct ath_node {
#endif
struct ath_atx_tid tid[WME_NUM_TID];
struct ath_atx_ac ac[WME_NUM_AC];
+ int ps_key;
+
u16 maxampdu;
u8 mpdudensity;
+
+ bool sleeping;
};
#define AGGR_CLEANUP BIT(1)
@@ -340,17 +342,18 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
+void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an);
+bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an);
+
/********/
/* VIFs */
/********/
struct ath_vif {
int av_bslot;
- bool is_bslot_active;
+ bool is_bslot_active, primary_sta_vif;
__le64 tsf_adjust; /* TSF adjustment for staggered beacons */
- enum nl80211_iftype av_opmode;
struct ath_buf *av_bcbuf;
- u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */
};
/*******************/
@@ -362,7 +365,7 @@ struct ath_vif {
* number of BSSIDs) if a given beacon does not go out even after waiting this
* number of beacon intervals, the game's up.
*/
-#define BSTUCK_THRESH (9 * ATH_BCBUF)
+#define BSTUCK_THRESH 9
#define ATH_BCBUF 4
#define ATH_DEFAULT_BINTVAL 100 /* TU */
#define ATH_DEFAULT_BMISS_LIMIT 10
@@ -386,7 +389,7 @@ struct ath_beacon {
u32 beaconq;
u32 bmisscnt;
u32 ast_be_xmit;
- u64 bc_tstamp;
+ u32 bc_tstamp;
struct ieee80211_vif *bslot[ATH_BCBUF];
int slottime;
int slotupdate;
@@ -401,6 +404,7 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif);
void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
int ath_beaconq_config(struct ath_softc *sc);
+void ath_set_beacon(struct ath_softc *sc);
void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);
/*******/
@@ -418,6 +422,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);
#define ATH_PAPRD_TIMEOUT 100 /* msecs */
void ath_hw_check(struct work_struct *work);
+void ath_hw_pll_work(struct work_struct *work);
void ath_paprd_calibrate(struct work_struct *work);
void ath_ani_calibrate(unsigned long data);
@@ -448,6 +453,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc);
#define ATH_LED_PIN_DEF 1
#define ATH_LED_PIN_9287 8
+#define ATH_LED_PIN_9300 10
#define ATH_LED_PIN_9485 6
#ifdef CONFIG_MAC80211_LEDS
@@ -477,7 +483,6 @@ static inline void ath_deinit_leds(struct ath_softc *sc)
#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO 30
#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO2 20
-#define ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA -3
#define ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA -1
#define ATH_ANT_DIV_COMB_LNA1_DELTA_HI -4
#define ATH_ANT_DIV_COMB_LNA1_DELTA_MID -2
@@ -550,6 +555,7 @@ struct ath_ant_comb {
#define SC_OP_BT_SCAN BIT(13)
#define SC_OP_ANI_RUN BIT(14)
#define SC_OP_ENABLE_APM BIT(15)
+#define SC_OP_PRIM_STA_VIF BIT(16)
/* Powersave flags */
#define PS_WAIT_FOR_BEACON BIT(0)
@@ -557,6 +563,7 @@ struct ath_ant_comb {
#define PS_WAIT_FOR_PSPOLL_DATA BIT(2)
#define PS_WAIT_FOR_TX_ACK BIT(3)
#define PS_BEACON_SYNC BIT(4)
+#define PS_TSFOOR_SYNC BIT(5)
struct ath_rate_table;
@@ -667,7 +674,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode);
bool ath9k_uses_beacons(int type);
-#ifdef CONFIG_PCI
+#ifdef CONFIG_ATH9K_PCI
int ath_pci_init(void);
void ath_pci_exit(void);
#else
@@ -675,7 +682,7 @@ static inline int ath_pci_init(void) { return 0; };
static inline void ath_pci_exit(void) {};
#endif
-#ifdef CONFIG_ATHEROS_AR71XX
+#ifdef CONFIG_ATH9K_AHB
int ath_ahb_init(void);
void ath_ahb_exit(void);
#else
@@ -688,8 +695,6 @@ void ath9k_ps_restore(struct ath_softc *sc);
u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate);
-void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
-
void ath_start_rfkill_poll(struct ath_softc *sc);
extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw);
void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 6d2a545fc35..637dbc5f7b6 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -57,8 +57,8 @@ int ath_beaconq_config(struct ath_softc *sc)
/*
* Associates the beacon frame buffer with a transmit descriptor. Will set
- * up all required antenna switch parameters, rate codes, and channel flags.
- * Beacons are always sent out at the lowest rate, and are not retried.
+ * up rate codes, and channel flags. Beacons are always sent out at the
+ * lowest rate, and are not retried.
*/
static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
struct ath_buf *bf, int rateidx)
@@ -68,7 +68,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
struct ath_common *common = ath9k_hw_common(ah);
struct ath_desc *ds;
struct ath9k_11n_rate_series series[4];
- int flags, antenna, ctsrate = 0, ctsduration = 0;
+ int flags, ctsrate = 0, ctsduration = 0;
struct ieee80211_supported_band *sband;
u8 rate = 0;
@@ -76,12 +76,6 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
flags = ATH9K_TXDESC_NOACK;
ds->ds_link = 0;
- /*
- * Switch antenna every beacon.
- * Should only switch every beacon period, not for every SWBA
- * XXX assumes two antennae
- */
- antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
sband = &sc->sbands[common->hw->conf.channel->band];
rate = sband->bitrates[rateidx].hw_value;
@@ -278,7 +272,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif)
return -ENOMEM;
tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
- sc->beacon.bc_tstamp = le64_to_cpu(tstamp);
+ sc->beacon.bc_tstamp = (u32) le64_to_cpu(tstamp);
/* Calculate a TSF adjustment factor required for staggered beacons. */
if (avp->av_bslot > 0) {
u64 tsfadjust;
@@ -294,8 +288,8 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif)
* adjustment. Other slots are adjusted to get the timestamp
* close to the TBTT for the BSS.
*/
- tsfadjust = intval * avp->av_bslot / ATH_BCBUF;
- avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
+ tsfadjust = TU_TO_USEC(intval * avp->av_bslot) / ATH_BCBUF;
+ avp->tsf_adjust = cpu_to_le64(tsfadjust);
ath_dbg(common, ATH_DBG_BEACON,
"stagger beacons, bslot %d intval %u tsfadjust %llu\n",
@@ -326,9 +320,11 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
if (avp->av_bcbuf != NULL) {
struct ath_buf *bf;
+ avp->is_bslot_active = false;
if (avp->av_bslot != -1) {
sc->beacon.bslot[avp->av_bslot] = NULL;
sc->nbcnvifs--;
+ avp->av_bslot = -1;
}
bf = avp->av_bcbuf;
@@ -369,12 +365,13 @@ void ath_beacon_tasklet(unsigned long data)
if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
sc->beacon.bmisscnt++;
- if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
+ if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) {
ath_dbg(common, ATH_DBG_BSTUCK,
"missed %u consecutive beacons\n",
sc->beacon.bmisscnt);
ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq);
- ath9k_hw_bstuck_nfcal(ah);
+ if (sc->beacon.bmisscnt > 3)
+ ath9k_hw_bstuck_nfcal(ah);
} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
ath_dbg(common, ATH_DBG_BSTUCK,
"beacon is officially stuck\n");
@@ -385,13 +382,6 @@ void ath_beacon_tasklet(unsigned long data)
return;
}
- if (sc->beacon.bmisscnt != 0) {
- ath_dbg(common, ATH_DBG_BSTUCK,
- "resume beacon xmit after %u misses\n",
- sc->beacon.bmisscnt);
- sc->beacon.bmisscnt = 0;
- }
-
/*
* Generate beacon frames. we are sending frames
* staggered so calculate the slot for this frame based
@@ -401,21 +391,14 @@ void ath_beacon_tasklet(unsigned long data)
intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
tsf = ath9k_hw_gettsf64(ah);
- tsftu = TSF_TO_TU(tsf>>32, tsf);
- slot = ((tsftu % intval) * ATH_BCBUF) / intval;
- /*
- * Reverse the slot order to get slot 0 on the TBTT offset that does
- * not require TSF adjustment and other slots adding
- * slot/ATH_BCBUF * beacon_int to timestamp. For example, with
- * ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 ..
- * and slot 0 is at correct offset to TBTT.
- */
- slot = ATH_BCBUF - slot - 1;
+ tsf += TU_TO_USEC(ah->config.sw_beacon_response_time);
+ tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF);
+ slot = (tsftu % (intval * ATH_BCBUF)) / intval;
vif = sc->beacon.bslot[slot];
ath_dbg(common, ATH_DBG_BEACON,
"slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
- slot, tsf, tsftu, intval, vif);
+ slot, tsf, tsftu / ATH_BCBUF, intval, vif);
bfaddr = 0;
if (vif) {
@@ -424,6 +407,13 @@ void ath_beacon_tasklet(unsigned long data)
bfaddr = bf->bf_daddr;
bc = 1;
}
+
+ if (sc->beacon.bmisscnt != 0) {
+ ath_dbg(common, ATH_DBG_BSTUCK,
+ "resume beacon xmit after %u misses\n",
+ sc->beacon.bmisscnt);
+ sc->beacon.bmisscnt = 0;
+ }
}
/*
@@ -463,13 +453,17 @@ static void ath9k_beacon_init(struct ath_softc *sc,
u32 next_beacon,
u32 beacon_period)
{
- if (beacon_period & ATH9K_BEACON_RESET_TSF)
+ if (sc->sc_flags & SC_OP_TSF_RESET) {
ath9k_ps_wakeup(sc);
+ ath9k_hw_reset_tsf(sc->sc_ah);
+ }
ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period);
- if (beacon_period & ATH9K_BEACON_RESET_TSF)
+ if (sc->sc_flags & SC_OP_TSF_RESET) {
ath9k_ps_restore(sc);
+ sc->sc_flags &= ~SC_OP_TSF_RESET;
+ }
}
/*
@@ -484,18 +478,14 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
u32 nexttbtt, intval;
/* NB: the beacon interval is kept internally in TU's */
- intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+ intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
intval /= ATH_BCBUF; /* for staggered beacons */
nexttbtt = intval;
- if (sc->sc_flags & SC_OP_TSF_RESET)
- intval |= ATH9K_BEACON_RESET_TSF;
-
/*
* In AP mode we enable the beacon timers and SWBA interrupts to
* prepare beacon frames.
*/
- intval |= ATH9K_BEACON_ENA;
ah->imask |= ATH9K_INT_SWBA;
ath_beaconq_config(sc);
@@ -505,11 +495,6 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
ath9k_beacon_init(sc, nexttbtt, intval);
sc->beacon.bmisscnt = 0;
ath9k_hw_set_interrupts(ah, ah->imask);
-
- /* Clear the reset TSF flag, so that subsequent beacon updation
- will not reset the HW TSF. */
-
- sc->sc_flags &= ~SC_OP_TSF_RESET;
}
/*
@@ -635,7 +620,13 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
ath9k_hw_disable_interrupts(ah);
ath9k_hw_set_sta_beacon_timers(ah, &bs);
ah->imask |= ATH9K_INT_BMISS;
- ath9k_hw_set_interrupts(ah, ah->imask);
+
+ /*
+ * If the beacon config is called beacause of TSFOOR,
+ * Interrupts will be enabled back at the end of ath9k_tasklet
+ */
+ if (!(sc->ps_flags & PS_TSFOOR_SYNC))
+ ath9k_hw_set_interrupts(ah, ah->imask);
}
static void ath_beacon_config_adhoc(struct ath_softc *sc,
@@ -643,25 +634,20 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
- u64 tsf;
- u32 tsftu, intval, nexttbtt;
-
- intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
-
-
- /* Pull nexttbtt forward to reflect the current TSF */
-
- nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
- if (nexttbtt == 0)
- nexttbtt = intval;
- else if (intval)
- nexttbtt = roundup(nexttbtt, intval);
-
- tsf = ath9k_hw_gettsf64(ah);
- tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
- do {
- nexttbtt += intval;
- } while (nexttbtt < tsftu);
+ u32 tsf, delta, intval, nexttbtt;
+
+ tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE);
+ intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
+
+ if (!sc->beacon.bc_tstamp)
+ nexttbtt = tsf + intval;
+ else {
+ if (tsf > sc->beacon.bc_tstamp)
+ delta = (tsf - sc->beacon.bc_tstamp);
+ else
+ delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp));
+ nexttbtt = tsf + roundup(delta, intval);
+ }
ath_dbg(common, ATH_DBG_BEACON,
"IBSS nexttbtt %u intval %u (%u)\n",
@@ -672,7 +658,6 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
* if we need to manually prepare beacon frames. Otherwise we use a
* self-linked tx descriptor and let the hardware deal with things.
*/
- intval |= ATH9K_BEACON_ENA;
ah->imask |= ATH9K_INT_SWBA;
ath_beaconq_config(sc);
@@ -682,25 +667,71 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
ath9k_hw_disable_interrupts(ah);
ath9k_beacon_init(sc, nexttbtt, intval);
sc->beacon.bmisscnt = 0;
- ath9k_hw_set_interrupts(ah, ah->imask);
+ /*
+ * If the beacon config is called beacause of TSFOOR,
+ * Interrupts will be enabled back at the end of ath9k_tasklet
+ */
+ if (!(sc->ps_flags & PS_TSFOOR_SYNC))
+ ath9k_hw_set_interrupts(ah, ah->imask);
}
-void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
+static bool ath9k_allow_beacon_config(struct ath_softc *sc,
+ struct ieee80211_vif *vif)
{
struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- enum nl80211_iftype iftype;
+ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+ struct ath_vif *avp = (void *)vif->drv_priv;
- /* Setup the beacon configuration parameters */
- if (vif) {
- struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
- iftype = vif->type;
- cur_conf->beacon_interval = bss_conf->beacon_int;
- cur_conf->dtim_period = bss_conf->dtim_period;
- } else {
- iftype = sc->sc_ah->opmode;
+ /*
+ * Can not have different beacon interval on multiple
+ * AP interface case
+ */
+ if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
+ (sc->nbcnvifs > 1) &&
+ (vif->type == NL80211_IFTYPE_AP) &&
+ (cur_conf->beacon_interval != bss_conf->beacon_int)) {
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Changing beacon interval of multiple \
+ AP interfaces !\n");
+ return false;
}
+ /*
+ * Can not configure station vif's beacon config
+ * while on AP opmode
+ */
+ if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
+ (vif->type != NL80211_IFTYPE_AP)) {
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "STA vif's beacon not allowed on AP mode\n");
+ return false;
+ }
+ /*
+ * Do not allow beacon config if HW was already configured
+ * with another STA vif
+ */
+ if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
+ (vif->type == NL80211_IFTYPE_STATION) &&
+ (sc->sc_flags & SC_OP_BEACONS) &&
+ !avp->primary_sta_vif) {
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Beacon already configured for a station interface\n");
+ return false;
+ }
+ return true;
+}
+void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
+{
+ struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
+ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+
+ if (!ath9k_allow_beacon_config(sc, vif))
+ return;
+
+ /* Setup the beacon configuration parameters */
+ cur_conf->beacon_interval = bss_conf->beacon_int;
+ cur_conf->dtim_period = bss_conf->dtim_period;
cur_conf->listen_interval = 1;
cur_conf->dtim_count = 1;
cur_conf->bmiss_timeout =
@@ -723,9 +754,37 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
if (cur_conf->dtim_period == 0)
cur_conf->dtim_period = 1;
- switch (iftype) {
+ ath_set_beacon(sc);
+}
+
+static bool ath_has_valid_bslot(struct ath_softc *sc)
+{
+ struct ath_vif *avp;
+ int slot;
+ bool found = false;
+
+ for (slot = 0; slot < ATH_BCBUF; slot++) {
+ if (sc->beacon.bslot[slot]) {
+ avp = (void *)sc->beacon.bslot[slot]->drv_priv;
+ if (avp->is_bslot_active) {
+ found = true;
+ break;
+ }
+ }
+ }
+ return found;
+}
+
+
+void ath_set_beacon(struct ath_softc *sc)
+{
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
+
+ switch (sc->sc_ah->opmode) {
case NL80211_IFTYPE_AP:
- ath_beacon_config_ap(sc, cur_conf);
+ if (ath_has_valid_bslot(sc))
+ ath_beacon_config_ap(sc, cur_conf);
break;
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
@@ -746,26 +805,15 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
void ath9k_set_beaconing_status(struct ath_softc *sc, bool status)
{
struct ath_hw *ah = sc->sc_ah;
- struct ath_vif *avp;
- int slot;
- bool found = false;
+
+ if (!ath_has_valid_bslot(sc))
+ return;
ath9k_ps_wakeup(sc);
if (status) {
- for (slot = 0; slot < ATH_BCBUF; slot++) {
- if (sc->beacon.bslot[slot]) {
- avp = (void *)sc->beacon.bslot[slot]->drv_priv;
- if (avp->is_bslot_active) {
- found = true;
- break;
- }
- }
- }
- if (found) {
- /* Re-enable beaconing */
- ah->imask |= ATH9K_INT_SWBA;
- ath9k_hw_set_interrupts(ah, ah->imask);
- }
+ /* Re-enable beaconing */
+ ah->imask |= ATH9K_INT_SWBA;
+ ath9k_hw_set_interrupts(ah, ah->imask);
} else {
/* Disable SWBA interrupt */
ah->imask &= ~ATH9K_INT_SWBA;
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index d33bf204c99..23f15a7ca7f 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -51,6 +51,10 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
.bt_hold_rx_clear = true,
};
u32 i;
+ bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity;
+
+ if (AR_SREV_9300_20_OR_LATER(ah))
+ rxclear_polarity = !ath_bt_config.bt_rxclear_polarity;
btcoex_hw->bt_coex_mode =
(btcoex_hw->bt_coex_mode & AR_BT_QCU_THRESH) |
@@ -59,7 +63,7 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
SM(ath_bt_config.bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) |
SM(ath_bt_config.bt_mode, AR_BT_MODE) |
SM(ath_bt_config.bt_quiet_collision, AR_BT_QUIET) |
- SM(ath_bt_config.bt_rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) |
+ SM(rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) |
SM(ath_bt_config.bt_priority_time, AR_BT_PRIORITY_TIME) |
SM(ath_bt_config.bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) |
SM(qnum, AR_BT_QCU_THRESH);
@@ -142,6 +146,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
}
EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight);
+
static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
{
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
@@ -152,9 +157,22 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
* enable coex 3-wire
*/
REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_hw->bt_coex_mode);
- REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights);
REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2);
+
+ if (AR_SREV_9300_20_OR_LATER(ah)) {
+ REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, ah->bt_coex_wlan_weight[0]);
+ REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, ah->bt_coex_wlan_weight[1]);
+ REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, ah->bt_coex_bt_weight[0]);
+ REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, ah->bt_coex_bt_weight[1]);
+ REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, ah->bt_coex_bt_weight[2]);
+ REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, ah->bt_coex_bt_weight[3]);
+
+ } else
+ REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights);
+
+
+
if (AR_SREV_9271(ah)) {
val = REG_READ(ah, 0x50040);
val &= 0xFFFFFEFF;
@@ -202,10 +220,86 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) {
REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE);
- REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0);
REG_WRITE(ah, AR_BT_COEX_MODE2, 0);
+
+ if (AR_SREV_9300_20_OR_LATER(ah)) {
+ REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, 0);
+ REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, 0);
+ REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, 0);
+ REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, 0);
+ REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, 0);
+ REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, 0);
+ } else
+ REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0);
+
}
ah->btcoex_hw.enabled = false;
}
EXPORT_SYMBOL(ath9k_hw_btcoex_disable);
+
+static void ar9003_btcoex_bt_stomp(struct ath_hw *ah,
+ enum ath_stomp_type stomp_type)
+{
+ ah->bt_coex_bt_weight[0] = AR9300_BT_WGHT;
+ ah->bt_coex_bt_weight[1] = AR9300_BT_WGHT;
+ ah->bt_coex_bt_weight[2] = AR9300_BT_WGHT;
+ ah->bt_coex_bt_weight[3] = AR9300_BT_WGHT;
+
+
+ switch (stomp_type) {
+ case ATH_BTCOEX_STOMP_ALL:
+ ah->bt_coex_wlan_weight[0] = AR9300_STOMP_ALL_WLAN_WGHT0;
+ ah->bt_coex_wlan_weight[1] = AR9300_STOMP_ALL_WLAN_WGHT1;
+ break;
+ case ATH_BTCOEX_STOMP_LOW:
+ ah->bt_coex_wlan_weight[0] = AR9300_STOMP_LOW_WLAN_WGHT0;
+ ah->bt_coex_wlan_weight[1] = AR9300_STOMP_LOW_WLAN_WGHT1;
+ break;
+ case ATH_BTCOEX_STOMP_NONE:
+ ah->bt_coex_wlan_weight[0] = AR9300_STOMP_NONE_WLAN_WGHT0;
+ ah->bt_coex_wlan_weight[1] = AR9300_STOMP_NONE_WLAN_WGHT1;
+ break;
+
+ default:
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ "Invalid Stomptype\n");
+ break;
+ }
+
+ ath9k_hw_btcoex_enable(ah);
+}
+
+/*
+ * Configures appropriate weight based on stomp type.
+ */
+void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
+ enum ath_stomp_type stomp_type)
+{
+ if (AR_SREV_9300_20_OR_LATER(ah)) {
+ ar9003_btcoex_bt_stomp(ah, stomp_type);
+ return;
+ }
+
+ switch (stomp_type) {
+ case ATH_BTCOEX_STOMP_ALL:
+ ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+ AR_STOMP_ALL_WLAN_WGHT);
+ break;
+ case ATH_BTCOEX_STOMP_LOW:
+ ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+ AR_STOMP_LOW_WLAN_WGHT);
+ break;
+ case ATH_BTCOEX_STOMP_NONE:
+ ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+ AR_STOMP_NONE_WLAN_WGHT);
+ break;
+ default:
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ "Invalid Stomptype\n");
+ break;
+ }
+
+ ath9k_hw_btcoex_enable(ah);
+}
+EXPORT_SYMBOL(ath9k_hw_btcoex_bt_stomp);
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 588dfd464dd..a9efca83d67 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -19,9 +19,13 @@
#include "hw.h"
-#define ATH_WLANACTIVE_GPIO 5
-#define ATH_BTACTIVE_GPIO 6
-#define ATH_BTPRIORITY_GPIO 7
+#define ATH_WLANACTIVE_GPIO_9280 5
+#define ATH_BTACTIVE_GPIO_9280 6
+#define ATH_BTPRIORITY_GPIO_9285 7
+
+#define ATH_WLANACTIVE_GPIO_9300 5
+#define ATH_BTACTIVE_GPIO_9300 4
+#define ATH_BTPRIORITY_GPIO_9300 8
#define ATH_BTCOEX_DEF_BT_PERIOD 45
#define ATH_BTCOEX_DEF_DUTY_CYCLE 55
@@ -32,6 +36,14 @@
#define ATH_BT_CNT_THRESHOLD 3
#define ATH_BT_CNT_SCAN_THRESHOLD 15
+/* Defines the BT AR_BT_COEX_WGHT used */
+enum ath_stomp_type {
+ ATH_BTCOEX_NO_STOMP,
+ ATH_BTCOEX_STOMP_ALL,
+ ATH_BTCOEX_STOMP_LOW,
+ ATH_BTCOEX_STOMP_NONE
+};
+
enum ath_btcoex_scheme {
ATH_BTCOEX_CFG_NONE,
ATH_BTCOEX_CFG_2WIRE,
@@ -57,5 +69,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
u32 wlan_weight);
void ath9k_hw_btcoex_enable(struct ath_hw *ah);
void ath9k_hw_btcoex_disable(struct ath_hw *ah);
+void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
+ enum ath_stomp_type stomp_type);
#endif
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 8649581fa4d..558b228a717 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -69,15 +69,21 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
int16_t *nfarray)
{
struct ath_common *common = ath9k_hw_common(ah);
+ struct ieee80211_conf *conf = &common->hw->conf;
struct ath_nf_limits *limit;
struct ath9k_nfcal_hist *h;
bool high_nf_mid = false;
+ u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
int i;
h = cal->nfCalHist;
limit = ath9k_hw_get_nf_limits(ah, ah->curchan);
for (i = 0; i < NUM_NF_READINGS; i++) {
+ if (!(chainmask & (1 << i)) ||
+ ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
+ continue;
+
h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
@@ -225,6 +231,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
int32_t val;
u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
struct ath_common *common = ath9k_hw_common(ah);
+ struct ieee80211_conf *conf = &common->hw->conf;
s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
if (ah->caldata)
@@ -234,6 +241,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
if (chainmask & (1 << i)) {
s16 nfval;
+ if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
+ continue;
+
if (h)
nfval = h[i].privNF;
else
@@ -293,6 +303,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
ENABLE_REGWRITE_BUFFER(ah);
for (i = 0; i < NUM_NF_READINGS; i++) {
if (chainmask & (1 << i)) {
+ if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
+ continue;
+
val = REG_READ(ah, ah->nf_regs[i]);
val &= 0xFFFFFE00;
val |= (((u32) (-50) << 1) & 0x1ff);
@@ -396,14 +409,6 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
}
}
-s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
-{
- if (!ah->curchan || !ah->curchan->noisefloor)
- return ath9k_hw_get_default_nf(ah, chan);
-
- return ah->curchan->noisefloor;
-}
-EXPORT_SYMBOL(ath9k_hw_getchan_noise);
void ath9k_hw_bstuck_nfcal(struct ath_hw *ah)
{
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index b8973eb8d85..4420780fa3b 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -106,7 +106,6 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan);
void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
struct ath9k_channel *chan);
void ath9k_hw_bstuck_nfcal(struct ath_hw *ah);
-s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
void ath9k_hw_reset_calibration(struct ath_hw *ah,
struct ath9k_cal_list *currCal);
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 615e68276e7..74535e6dfb8 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -116,7 +116,7 @@ void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
if (chan->band == IEEE80211_BAND_2GHZ) {
ichan->chanmode = CHANNEL_G;
- ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G;
+ ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
} else {
ichan->chanmode = CHANNEL_A;
ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
@@ -158,37 +158,6 @@ int ath9k_cmn_count_streams(unsigned int chainmask, int max)
}
EXPORT_SYMBOL(ath9k_cmn_count_streams);
-/*
- * Configures appropriate weight based on stomp type.
- */
-void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common,
- enum ath_stomp_type stomp_type)
-{
- struct ath_hw *ah = common->ah;
-
- switch (stomp_type) {
- case ATH_BTCOEX_STOMP_ALL:
- ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
- AR_STOMP_ALL_WLAN_WGHT);
- break;
- case ATH_BTCOEX_STOMP_LOW:
- ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
- AR_STOMP_LOW_WLAN_WGHT);
- break;
- case ATH_BTCOEX_STOMP_NONE:
- ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
- AR_STOMP_NONE_WLAN_WGHT);
- break;
- default:
- ath_dbg(common, ATH_DBG_BTCOEX,
- "Invalid Stomptype\n");
- break;
- }
-
- ath9k_hw_btcoex_enable(ah);
-}
-EXPORT_SYMBOL(ath9k_cmn_btcoex_bt_stomp);
-
void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
u16 new_txpow, u16 *txpower)
{
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index b2f7b5f8909..5124f1420b3 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -50,14 +50,6 @@
#define ATH_EP_RND(x, mul) \
((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
-/* Defines the BT AR_BT_COEX_WGHT used */
-enum ath_stomp_type {
- ATH_BTCOEX_NO_STOMP,
- ATH_BTCOEX_STOMP_ALL,
- ATH_BTCOEX_STOMP_LOW,
- ATH_BTCOEX_STOMP_NONE
-};
-
int ath9k_cmn_padpos(__le16 frame_control);
int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 8df5a92a20f..bad1a87249b 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -326,6 +326,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
sc->debug.stats.istats.dtimsync++;
if (status & ATH9K_INT_DTIM)
sc->debug.stats.istats.dtim++;
+ if (status & ATH9K_INT_TSFOOR)
+ sc->debug.stats.istats.tsfoor++;
}
static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
@@ -380,8 +382,11 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
len += snprintf(buf + len, sizeof(buf) - len,
"%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim);
len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "TSFOOR", sc->debug.stats.istats.tsfoor);
+ len += snprintf(buf + len, sizeof(buf) - len,
"%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
+
if (len > sizeof(buf))
len = sizeof(buf);
@@ -845,7 +850,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
struct ath_softc *sc = file->private_data;
char *buf;
- unsigned int len = 0, size = 1152;
+ unsigned int len = 0, size = 1400;
ssize_t retval = 0;
buf = kzalloc(size, GFP_KERNEL);
@@ -874,6 +879,34 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
"%18s : %10u\n", "DECRYPT BUSY ERR",
sc->debug.stats.rxstats.decrypt_busy_err);
+ len += snprintf(buf + len, size - len,
+ "%18s : %10d\n", "RSSI-CTL0",
+ sc->debug.stats.rxstats.rs_rssi_ctl0);
+
+ len += snprintf(buf + len, size - len,
+ "%18s : %10d\n", "RSSI-CTL1",
+ sc->debug.stats.rxstats.rs_rssi_ctl1);
+
+ len += snprintf(buf + len, size - len,
+ "%18s : %10d\n", "RSSI-CTL2",
+ sc->debug.stats.rxstats.rs_rssi_ctl2);
+
+ len += snprintf(buf + len, size - len,
+ "%18s : %10d\n", "RSSI-EXT0",
+ sc->debug.stats.rxstats.rs_rssi_ext0);
+
+ len += snprintf(buf + len, size - len,
+ "%18s : %10d\n", "RSSI-EXT1",
+ sc->debug.stats.rxstats.rs_rssi_ext1);
+
+ len += snprintf(buf + len, size - len,
+ "%18s : %10d\n", "RSSI-EXT2",
+ sc->debug.stats.rxstats.rs_rssi_ext2);
+
+ len += snprintf(buf + len, size - len,
+ "%18s : %10d\n", "Rx Antenna",
+ sc->debug.stats.rxstats.rs_antenna);
+
PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN);
PHY_ERR("TIMING", ATH9K_PHYERR_TIMING);
PHY_ERR("PARITY", ATH9K_PHYERR_PARITY);
@@ -948,6 +981,16 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
RX_PHY_ERR_INC(phyerr);
}
+ sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0;
+ sc->debug.stats.rxstats.rs_rssi_ctl1 = rs->rs_rssi_ctl1;
+ sc->debug.stats.rxstats.rs_rssi_ctl2 = rs->rs_rssi_ctl2;
+
+ sc->debug.stats.rxstats.rs_rssi_ext0 = rs->rs_rssi_ext0;
+ sc->debug.stats.rxstats.rs_rssi_ext1 = rs->rs_rssi_ext1;
+ sc->debug.stats.rxstats.rs_rssi_ext2 = rs->rs_rssi_ext2;
+
+ sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna;
+
#undef RX_STAT_INC
#undef RX_PHY_ERR_INC
}
@@ -1088,67 +1131,43 @@ int ath9k_init_debug(struct ath_hw *ah)
return -ENOMEM;
#ifdef CONFIG_ATH_DEBUG
- if (!debugfs_create_file("debug", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, sc, &fops_debug))
- goto err;
+ debugfs_create_file("debug", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+ sc, &fops_debug);
#endif
-
- if (!debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy,
- sc, &fops_dma))
- goto err;
-
- if (!debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy,
- sc, &fops_interrupt))
- goto err;
-
- if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, sc, &fops_wiphy))
- goto err;
-
- if (!debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy,
- sc, &fops_xmit))
- goto err;
-
- if (!debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy,
- sc, &fops_stations))
- goto err;
-
- if (!debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy,
- sc, &fops_misc))
- goto err;
-
- if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy,
- sc, &fops_recv))
- goto err;
-
- if (!debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, sc, &fops_rx_chainmask))
- goto err;
-
- if (!debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, sc, &fops_tx_chainmask))
- goto err;
-
- if (!debugfs_create_file("regidx", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, sc, &fops_regidx))
- goto err;
-
- if (!debugfs_create_file("regval", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, sc, &fops_regval))
- goto err;
-
- if (!debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca))
- goto err;
-
- if (!debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy,
- sc, &fops_regdump))
- goto err;
+ debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_dma);
+ debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_interrupt);
+ debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+ sc, &fops_wiphy);
+ debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_xmit);
+ debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_stations);
+ debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_misc);
+ debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_recv);
+ debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR,
+ sc->debug.debugfs_phy, sc, &fops_rx_chainmask);
+ debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
+ sc->debug.debugfs_phy, sc, &fops_tx_chainmask);
+ debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+ sc, &fops_regidx);
+ debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+ sc, &fops_regval);
+ debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR,
+ sc->debug.debugfs_phy,
+ &ah->config.cwm_ignore_extcca);
+ debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_regdump);
+
+ debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
+ sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
+
+ debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
+ sc->debug.debugfs_phy, &sc->sc_ah->gpio_val);
sc->debug.regidx = 0;
return 0;
-err:
- debugfs_remove_recursive(sc->debug.debugfs_phy);
- sc->debug.debugfs_phy = NULL;
- return -ENOMEM;
}
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 59338de0ce1..5488a324cc1 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -54,6 +54,9 @@ struct ath_buf;
* @dtimsync: DTIM sync lossage
* @dtim: RX Beacon with DTIM
* @bb_watchdog: Baseband watchdog
+ * @tsfoor: TSF out of range, indicates that the corrected TSF received
+ * from a beacon differs from the PCU's internal TSF by more than a
+ * (programmable) threshold
*/
struct ath_interrupt_stats {
u32 total;
@@ -78,6 +81,7 @@ struct ath_interrupt_stats {
u32 dtimsync;
u32 dtim;
u32 bb_watchdog;
+ u32 tsfoor;
};
/**
@@ -157,6 +161,13 @@ struct ath_rx_stats {
u32 post_delim_crc_err;
u32 decrypt_busy_err;
u32 phy_err_stats[ATH9K_PHYERR_MAX];
+ int8_t rs_rssi_ctl0;
+ int8_t rs_rssi_ctl1;
+ int8_t rs_rssi_ctl2;
+ int8_t rs_rssi_ext0;
+ int8_t rs_rssi_ext1;
+ int8_t rs_rssi_ext2;
+ u8 rs_antenna;
};
struct ath_stats {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index bd82447f5b7..3e316133f11 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -436,7 +436,11 @@ struct modal_eep_4k_header {
u8 db2_2:4, db2_3:4;
u8 db2_4:4, reserved:4;
#endif
- u8 futureModal[4];
+ u8 tx_diversity;
+ u8 flc_pwr_thresh;
+ u8 bb_scale_smrt_antenna;
+#define EEP_4K_BB_DESIRED_SCALE_MASK 0x1f
+ u8 futureModal[1];
struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
} __packed;
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index bc77a308c90..6f714dd7236 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -781,6 +781,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
{
struct modal_eep_4k_header *pModal;
struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+ struct base_eep_header_4k *pBase = &eep->baseEepHeader;
u8 txRxAttenLocal;
u8 ob[5], db1[5], db2[5];
u8 ant_div_control1, ant_div_control2;
@@ -1003,6 +1004,31 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
AR_PHY_SETTLING_SWITCH,
pModal->swSettleHt40);
}
+ if (AR_SREV_9271(ah) || AR_SREV_9285(ah)) {
+ u8 bb_desired_scale = (pModal->bb_scale_smrt_antenna &
+ EEP_4K_BB_DESIRED_SCALE_MASK);
+ if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) {
+ u32 pwrctrl, mask, clr;
+
+ mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25);
+ pwrctrl = mask * bb_desired_scale;
+ clr = mask * 0x1f;
+ REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr);
+ REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr);
+ REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr);
+
+ mask = BIT(0)|BIT(5)|BIT(15);
+ pwrctrl = mask * bb_desired_scale;
+ clr = mask * 0x1f;
+ REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr);
+
+ mask = BIT(0)|BIT(5);
+ pwrctrl = mask * bb_desired_scale;
+ clr = mask * 0x1f;
+ REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr);
+ REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr);
+ }
+ }
}
static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index 8cd8333cc08..b87db476309 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -319,10 +319,9 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
u16 numXpdGain, xpdMask;
u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0};
u32 reg32, regOffset, regChainOffset, regval;
- int16_t modalIdx, diff = 0;
+ int16_t diff = 0;
struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
- modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
xpdMask = pEepData->modalHeader.xpdGain;
if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
@@ -392,6 +391,8 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
numXpdGain);
}
+ ENABLE_REGWRITE_BUFFER(ah);
+
if (i == 0) {
if (!ath9k_hw_ar9287_get_eeprom(ah,
EEP_OL_PWRCTRL)) {
@@ -442,6 +443,7 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
regOffset += 4;
}
}
+ REGWRITE_BUFFER_FLUSH(ah);
}
}
@@ -757,6 +759,8 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
}
+ ENABLE_REGWRITE_BUFFER(ah);
+
/* OFDM power per rate */
REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
ATH9K_POW_SM(ratesArray[rate18mb], 24)
@@ -840,6 +844,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
| ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
| ATH9K_POW_SM(ratesArray[rateDupCck], 0));
}
+ REGWRITE_BUFFER_FLUSH(ah);
}
static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah,
@@ -852,35 +857,12 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah,
{
struct ar9287_eeprom *eep = &ah->eeprom.map9287;
struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
- u16 antWrites[AR9287_ANT_16S];
u32 regChainOffset, regval;
u8 txRxAttenLocal;
- int i, j, offset_num;
+ int i;
pModal = &eep->modalHeader;
- antWrites[0] = (u16)((pModal->antCtrlCommon >> 28) & 0xF);
- antWrites[1] = (u16)((pModal->antCtrlCommon >> 24) & 0xF);
- antWrites[2] = (u16)((pModal->antCtrlCommon >> 20) & 0xF);
- antWrites[3] = (u16)((pModal->antCtrlCommon >> 16) & 0xF);
- antWrites[4] = (u16)((pModal->antCtrlCommon >> 12) & 0xF);
- antWrites[5] = (u16)((pModal->antCtrlCommon >> 8) & 0xF);
- antWrites[6] = (u16)((pModal->antCtrlCommon >> 4) & 0xF);
- antWrites[7] = (u16)(pModal->antCtrlCommon & 0xF);
-
- offset_num = 8;
-
- for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) {
- antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 28) & 0xf);
- antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 10) & 0x3);
- antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 8) & 0x3);
- antWrites[j++] = 0;
- antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 6) & 0x3);
- antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 4) & 0x3);
- antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 2) & 0x3);
- antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3);
- }
-
REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
for (i = 0; i < AR9287_MAX_CHAINS; i++) {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index fccd87df730..c031854b569 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -231,6 +231,10 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
integer = swab32(pModal->antCtrlChain[i]);
pModal->antCtrlChain[i] = integer;
}
+ for (i = 0; i < 3; i++) {
+ word = swab16(pModal->xpaBiasLvlFreq[i]);
+ pModal->xpaBiasLvlFreq[i] = word;
+ }
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
word = swab16(pModal->spurChans[i].spurChan);
@@ -799,6 +803,8 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
pwr_table_offset,
&diff);
+ ENABLE_REGWRITE_BUFFER(ah);
+
if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
if (OLC_FOR_AR9280_20_LATER) {
REG_WRITE(ah,
@@ -847,6 +853,7 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
regOffset += 4;
}
+ REGWRITE_BUFFER_FLUSH(ah);
}
}
@@ -1205,6 +1212,8 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
}
}
+ ENABLE_REGWRITE_BUFFER(ah);
+
REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
ATH9K_POW_SM(ratesArray[rate18mb], 24)
| ATH9K_POW_SM(ratesArray[rate12mb], 16)
@@ -1291,6 +1300,8 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
| ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
+
+ REGWRITE_BUFFER_FLUSH(ah);
}
static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 0fb8f8ac275..0349b3a1cc5 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -41,12 +41,16 @@ void ath_init_leds(struct ath_softc *sc)
{
int ret;
- if (AR_SREV_9287(sc->sc_ah))
- sc->sc_ah->led_pin = ATH_LED_PIN_9287;
- else if (AR_SREV_9485(sc->sc_ah))
- sc->sc_ah->led_pin = ATH_LED_PIN_9485;
- else
- sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
+ if (sc->sc_ah->led_pin < 0) {
+ if (AR_SREV_9287(sc->sc_ah))
+ sc->sc_ah->led_pin = ATH_LED_PIN_9287;
+ else if (AR_SREV_9485(sc->sc_ah))
+ sc->sc_ah->led_pin = ATH_LED_PIN_9485;
+ else if (AR_SREV_9300(sc->sc_ah))
+ sc->sc_ah->led_pin = ATH_LED_PIN_9300;
+ else
+ sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
+ }
/* Configure gpio 1 for output */
ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
@@ -136,10 +140,10 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
static void ath9k_gen_timer_start(struct ath_hw *ah,
struct ath_gen_timer *timer,
- u32 timer_next,
+ u32 trig_timeout,
u32 timer_period)
{
- ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
+ ath9k_hw_gen_timer_start(ah, timer, trig_timeout, timer_period);
if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
ath9k_hw_disable_interrupts(ah);
@@ -172,17 +176,17 @@ static void ath_btcoex_period_timer(unsigned long data)
struct ath_softc *sc = (struct ath_softc *) data;
struct ath_hw *ah = sc->sc_ah;
struct ath_btcoex *btcoex = &sc->btcoex;
- struct ath_common *common = ath9k_hw_common(ah);
u32 timer_period;
bool is_btscan;
+ ath9k_ps_wakeup(sc);
ath_detect_bt_priority(sc);
is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
spin_lock_bh(&btcoex->btcoex_lock);
- ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL :
+ ath9k_hw_btcoex_bt_stomp(ah, is_btscan ? ATH_BTCOEX_STOMP_ALL :
btcoex->bt_stomp_type);
spin_unlock_bh(&btcoex->btcoex_lock);
@@ -193,11 +197,12 @@ static void ath_btcoex_period_timer(unsigned long data)
timer_period = is_btscan ? btcoex->btscan_no_stomp :
btcoex->btcoex_no_stomp;
- ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, 0,
+ ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, timer_period,
timer_period * 10);
btcoex->hw_timer_enabled = true;
}
+ ath9k_ps_restore(sc);
mod_timer(&btcoex->period_timer, jiffies +
msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
}
@@ -217,14 +222,16 @@ static void ath_btcoex_no_stomp_timer(void *arg)
ath_dbg(common, ATH_DBG_BTCOEX,
"no stomp timer running\n");
+ ath9k_ps_wakeup(sc);
spin_lock_bh(&btcoex->btcoex_lock);
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
- ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE);
+ ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
- ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW);
+ ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW);
spin_unlock_bh(&btcoex->btcoex_lock);
+ ath9k_ps_restore(sc);
}
int ath_init_btcoex_timer(struct ath_softc *sc)
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 2d10239ce82..2e3a33a5340 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -17,11 +17,9 @@
#include "htc.h"
/* identify firmware images */
-#define FIRMWARE_AR7010 "ar7010.fw"
-#define FIRMWARE_AR7010_1_1 "ar7010_1_1.fw"
-#define FIRMWARE_AR9271 "ar9271.fw"
+#define FIRMWARE_AR7010_1_1 "htc_7010.fw"
+#define FIRMWARE_AR9271 "htc_9271.fw"
-MODULE_FIRMWARE(FIRMWARE_AR7010);
MODULE_FIRMWARE(FIRMWARE_AR7010_1_1);
MODULE_FIRMWARE(FIRMWARE_AR9271);
@@ -80,7 +78,7 @@ static void hif_usb_regout_cb(struct urb *urb)
if (cmd) {
ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
- cmd->skb, 1);
+ cmd->skb, true);
kfree(cmd);
}
@@ -126,6 +124,90 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
return ret;
}
+static void hif_usb_mgmt_cb(struct urb *urb)
+{
+ struct cmd_buf *cmd = (struct cmd_buf *)urb->context;
+ struct hif_device_usb *hif_dev = cmd->hif_dev;
+ bool txok = true;
+
+ if (!cmd || !cmd->skb || !cmd->hif_dev)
+ return;
+
+ switch (urb->status) {
+ case 0:
+ break;
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ENODEV:
+ case -ESHUTDOWN:
+ txok = false;
+
+ /*
+ * If the URBs are being flushed, no need to complete
+ * this packet.
+ */
+ spin_lock(&hif_dev->tx.tx_lock);
+ if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) {
+ spin_unlock(&hif_dev->tx.tx_lock);
+ dev_kfree_skb_any(cmd->skb);
+ kfree(cmd);
+ return;
+ }
+ spin_unlock(&hif_dev->tx.tx_lock);
+
+ break;
+ default:
+ txok = false;
+ break;
+ }
+
+ skb_pull(cmd->skb, 4);
+ ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
+ cmd->skb, txok);
+ kfree(cmd);
+}
+
+static int hif_usb_send_mgmt(struct hif_device_usb *hif_dev,
+ struct sk_buff *skb)
+{
+ struct urb *urb;
+ struct cmd_buf *cmd;
+ int ret = 0;
+ __le16 *hdr;
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (urb == NULL)
+ return -ENOMEM;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
+ if (cmd == NULL) {
+ usb_free_urb(urb);
+ return -ENOMEM;
+ }
+
+ cmd->skb = skb;
+ cmd->hif_dev = hif_dev;
+
+ hdr = (__le16 *) skb_push(skb, 4);
+ *hdr++ = cpu_to_le16(skb->len - 4);
+ *hdr++ = cpu_to_le16(ATH_USB_TX_STREAM_MODE_TAG);
+
+ usb_fill_bulk_urb(urb, hif_dev->udev,
+ usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE),
+ skb->data, skb->len,
+ hif_usb_mgmt_cb, cmd);
+
+ usb_anchor_urb(urb, &hif_dev->mgmt_submitted);
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
+ if (ret) {
+ usb_unanchor_urb(urb);
+ kfree(cmd);
+ }
+ usb_free_urb(urb);
+
+ return ret;
+}
+
static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev,
struct sk_buff_head *list)
{
@@ -133,7 +215,22 @@ static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev,
while ((skb = __skb_dequeue(list)) != NULL) {
dev_kfree_skb_any(skb);
- TX_STAT_INC(skb_dropped);
+ }
+}
+
+static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev,
+ struct sk_buff_head *queue,
+ bool txok)
+{
+ struct sk_buff *skb;
+
+ while ((skb = __skb_dequeue(queue)) != NULL) {
+ ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
+ skb, txok);
+ if (txok)
+ TX_STAT_INC(skb_success);
+ else
+ TX_STAT_INC(skb_failed);
}
}
@@ -141,7 +238,7 @@ static void hif_usb_tx_cb(struct urb *urb)
{
struct tx_buf *tx_buf = (struct tx_buf *) urb->context;
struct hif_device_usb *hif_dev;
- struct sk_buff *skb;
+ bool txok = true;
if (!tx_buf || !tx_buf->hif_dev)
return;
@@ -155,10 +252,7 @@ static void hif_usb_tx_cb(struct urb *urb)
case -ECONNRESET:
case -ENODEV:
case -ESHUTDOWN:
- /*
- * The URB has been killed, free the SKBs.
- */
- ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
+ txok = false;
/*
* If the URBs are being flushed, no need to add this
@@ -167,41 +261,19 @@ static void hif_usb_tx_cb(struct urb *urb)
spin_lock(&hif_dev->tx.tx_lock);
if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) {
spin_unlock(&hif_dev->tx.tx_lock);
+ ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
return;
}
spin_unlock(&hif_dev->tx.tx_lock);
- /*
- * In the stop() case, this URB has to be added to
- * the free list.
- */
- goto add_free;
+ break;
default:
+ txok = false;
break;
}
- /*
- * Check if TX has been stopped, this is needed because
- * this CB could have been invoked just after the TX lock
- * was released in hif_stop() and kill_urb() hasn't been
- * called yet.
- */
- spin_lock(&hif_dev->tx.tx_lock);
- if (hif_dev->tx.flags & HIF_USB_TX_STOP) {
- spin_unlock(&hif_dev->tx.tx_lock);
- ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
- goto add_free;
- }
- spin_unlock(&hif_dev->tx.tx_lock);
-
- /* Complete the queued SKBs. */
- while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) {
- ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
- skb, 1);
- TX_STAT_INC(skb_completed);
- }
+ ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, txok);
-add_free:
/* Re-initialize the SKB queue */
tx_buf->len = tx_buf->offset = 0;
__skb_queue_head_init(&tx_buf->skb_queue);
@@ -274,7 +346,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev)
ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC);
if (ret) {
tx_buf->len = tx_buf->offset = 0;
- ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
+ ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, false);
__skb_queue_head_init(&tx_buf->skb_queue);
list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
hif_dev->tx.tx_buf_cnt++;
@@ -286,10 +358,11 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev)
return ret;
}
-static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb,
- struct ath9k_htc_tx_ctl *tx_ctl)
+static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb)
{
+ struct ath9k_htc_tx_ctl *tx_ctl;
unsigned long flags;
+ int ret = 0;
spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
@@ -304,26 +377,36 @@ static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb,
return -ENOMEM;
}
- __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb);
- hif_dev->tx.tx_skb_cnt++;
+ spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
- /* Send normal frames immediately */
- if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL)))
- __hif_usb_tx(hif_dev);
+ tx_ctl = HTC_SKB_CB(skb);
+
+ /* Mgmt/Beacon frames don't use the TX buffer pool */
+ if ((tx_ctl->type == ATH9K_HTC_MGMT) ||
+ (tx_ctl->type == ATH9K_HTC_BEACON)) {
+ ret = hif_usb_send_mgmt(hif_dev, skb);
+ }
+
+ spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
+
+ if ((tx_ctl->type == ATH9K_HTC_NORMAL) ||
+ (tx_ctl->type == ATH9K_HTC_AMPDU)) {
+ __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb);
+ hif_dev->tx.tx_skb_cnt++;
+ }
/* Check if AMPDUs have to be sent immediately */
- if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) &&
- (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) &&
+ if ((hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) &&
(hif_dev->tx.tx_skb_cnt < 2)) {
__hif_usb_tx(hif_dev);
}
spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
- return 0;
+ return ret;
}
-static void hif_usb_start(void *hif_handle, u8 pipe_id)
+static void hif_usb_start(void *hif_handle)
{
struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
unsigned long flags;
@@ -335,14 +418,14 @@ static void hif_usb_start(void *hif_handle, u8 pipe_id)
spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
}
-static void hif_usb_stop(void *hif_handle, u8 pipe_id)
+static void hif_usb_stop(void *hif_handle)
{
struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
unsigned long flags;
spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
- ath9k_skb_queue_purge(hif_dev, &hif_dev->tx.tx_skb_queue);
+ ath9k_skb_queue_complete(hif_dev, &hif_dev->tx.tx_skb_queue, false);
hif_dev->tx.tx_skb_cnt = 0;
hif_dev->tx.flags |= HIF_USB_TX_STOP;
spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
@@ -352,17 +435,18 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id)
&hif_dev->tx.tx_pending, list) {
usb_kill_urb(tx_buf->urb);
}
+
+ usb_kill_anchored_urbs(&hif_dev->mgmt_submitted);
}
-static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb,
- struct ath9k_htc_tx_ctl *tx_ctl)
+static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb)
{
struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
int ret = 0;
switch (pipe_id) {
case USB_WLAN_TX_PIPE:
- ret = hif_usb_send_tx(hif_dev, skb, tx_ctl);
+ ret = hif_usb_send_tx(hif_dev, skb);
break;
case USB_REG_OUT_PIPE:
ret = hif_usb_send_regout(hif_dev, skb);
@@ -377,6 +461,40 @@ static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb,
return ret;
}
+static inline bool check_index(struct sk_buff *skb, u8 idx)
+{
+ struct ath9k_htc_tx_ctl *tx_ctl;
+
+ tx_ctl = HTC_SKB_CB(skb);
+
+ if ((tx_ctl->type == ATH9K_HTC_AMPDU) &&
+ (tx_ctl->sta_idx == idx))
+ return true;
+
+ return false;
+}
+
+static void hif_usb_sta_drain(void *hif_handle, u8 idx)
+{
+ struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
+ struct sk_buff *skb, *tmp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
+
+ skb_queue_walk_safe(&hif_dev->tx.tx_skb_queue, skb, tmp) {
+ if (check_index(skb, idx)) {
+ __skb_unlink(skb, &hif_dev->tx.tx_skb_queue);
+ ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
+ skb, false);
+ hif_dev->tx.tx_skb_cnt--;
+ TX_STAT_INC(skb_failed);
+ }
+ }
+
+ spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
+}
+
static struct ath9k_htc_hif hif_usb = {
.transport = ATH9K_HIF_USB,
.name = "ath9k_hif_usb",
@@ -386,6 +504,7 @@ static struct ath9k_htc_hif hif_usb = {
.start = hif_usb_start,
.stop = hif_usb_stop,
+ .sta_drain = hif_usb_sta_drain,
.send = hif_usb_send,
};
@@ -567,6 +686,9 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
case -ESHUTDOWN:
goto free;
default:
+ skb_reset_tail_pointer(skb);
+ skb_trim(skb, 0);
+
goto resubmit;
}
@@ -591,23 +713,15 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
USB_REG_IN_PIPE),
nskb->data, MAX_REG_IN_BUF_SIZE,
ath9k_hif_usb_reg_in_cb, nskb);
-
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret) {
- kfree_skb(nskb);
- urb->context = NULL;
- }
-
- return;
}
resubmit:
- skb_reset_tail_pointer(skb);
- skb_trim(skb, 0);
-
+ usb_anchor_urb(urb, &hif_dev->reg_in_submitted);
ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret)
+ if (ret) {
+ usb_unanchor_urb(urb);
goto free;
+ }
return;
free:
@@ -641,6 +755,8 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
kfree(tx_buf->buf);
kfree(tx_buf);
}
+
+ usb_kill_anchored_urbs(&hif_dev->mgmt_submitted);
}
static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
@@ -652,6 +768,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
INIT_LIST_HEAD(&hif_dev->tx.tx_pending);
spin_lock_init(&hif_dev->tx.tx_lock);
__skb_queue_head_init(&hif_dev->tx.tx_skb_queue);
+ init_usb_anchor(&hif_dev->mgmt_submitted);
for (i = 0; i < MAX_TX_URB_NUM; i++) {
tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL);
@@ -748,43 +865,67 @@ err_urb:
return ret;
}
-static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev)
+static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev)
{
- if (hif_dev->reg_in_urb) {
- usb_kill_urb(hif_dev->reg_in_urb);
- if (hif_dev->reg_in_urb->context)
- kfree_skb((void *)hif_dev->reg_in_urb->context);
- usb_free_urb(hif_dev->reg_in_urb);
- hif_dev->reg_in_urb = NULL;
- }
+ usb_kill_anchored_urbs(&hif_dev->reg_in_submitted);
}
-static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev)
+static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev)
{
- struct sk_buff *skb;
+ struct urb *urb = NULL;
+ struct sk_buff *skb = NULL;
+ int i, ret;
- hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (hif_dev->reg_in_urb == NULL)
- return -ENOMEM;
+ init_usb_anchor(&hif_dev->reg_in_submitted);
- skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL);
- if (!skb)
- goto err;
+ for (i = 0; i < MAX_REG_IN_URB_NUM; i++) {
- usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev,
- usb_rcvbulkpipe(hif_dev->udev,
- USB_REG_IN_PIPE),
- skb->data, MAX_REG_IN_BUF_SIZE,
- ath9k_hif_usb_reg_in_cb, skb);
+ /* Allocate URB */
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (urb == NULL) {
+ ret = -ENOMEM;
+ goto err_urb;
+ }
- if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0)
- goto err;
+ /* Allocate buffer */
+ skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL);
+ if (!skb) {
+ ret = -ENOMEM;
+ goto err_skb;
+ }
+
+ usb_fill_bulk_urb(urb, hif_dev->udev,
+ usb_rcvbulkpipe(hif_dev->udev,
+ USB_REG_IN_PIPE),
+ skb->data, MAX_REG_IN_BUF_SIZE,
+ ath9k_hif_usb_reg_in_cb, skb);
+
+ /* Anchor URB */
+ usb_anchor_urb(urb, &hif_dev->reg_in_submitted);
+
+ /* Submit URB */
+ ret = usb_submit_urb(urb, GFP_KERNEL);
+ if (ret) {
+ usb_unanchor_urb(urb);
+ goto err_submit;
+ }
+
+ /*
+ * Drop reference count.
+ * This ensures that the URB is freed when killing them.
+ */
+ usb_free_urb(urb);
+ }
return 0;
-err:
- ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
- return -ENOMEM;
+err_submit:
+ kfree_skb(skb);
+err_skb:
+ usb_free_urb(urb);
+err_urb:
+ ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
+ return ret;
}
static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
@@ -801,7 +942,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
goto err_rx;
/* Register Read */
- if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0)
+ if (ath9k_hif_usb_alloc_reg_in_urbs(hif_dev) < 0)
goto err_reg;
return 0;
@@ -816,7 +957,7 @@ err:
static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
{
usb_kill_anchored_urbs(&hif_dev->regout_submitted);
- ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
+ ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
}
@@ -1026,10 +1167,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
/* Find out which firmware to load */
if (IS_AR7010_DEVICE(id->driver_info))
- if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202)
- hif_dev->fw_name = FIRMWARE_AR7010_1_1;
- else
- hif_dev->fw_name = FIRMWARE_AR7010;
+ hif_dev->fw_name = FIRMWARE_AR7010_1_1;
else
hif_dev->fw_name = FIRMWARE_AR9271;
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index 7b9d863d403..2bdcdbc14b1 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -17,6 +17,9 @@
#ifndef HTC_USB_H
#define HTC_USB_H
+#define MAJOR_VERSION_REQ 1
+#define MINOR_VERSION_REQ 2
+
#define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB))
#define AR9271_FIRMWARE 0x501000
@@ -31,7 +34,7 @@
/* FIXME: Verify these numbers (with Windows) */
#define MAX_TX_URB_NUM 8
-#define MAX_TX_BUF_NUM 1024
+#define MAX_TX_BUF_NUM 256
#define MAX_TX_BUF_SIZE 32768
#define MAX_TX_AGGR_NUM 20
@@ -40,7 +43,7 @@
#define MAX_PKT_NUM_IN_TRANSFER 10
#define MAX_REG_OUT_URB_NUM 1
-#define MAX_REG_OUT_BUF_NUM 8
+#define MAX_REG_IN_URB_NUM 64
#define MAX_REG_IN_BUF_SIZE 64
@@ -90,9 +93,10 @@ struct hif_device_usb {
const struct firmware *firmware;
struct htc_target *htc_handle;
struct hif_usb_tx tx;
- struct urb *reg_in_urb;
struct usb_anchor regout_submitted;
struct usb_anchor rx_submitted;
+ struct usb_anchor reg_in_submitted;
+ struct usb_anchor mgmt_submitted;
struct sk_buff *remain_skb;
const char *fw_name;
int rx_remain_len;
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 753a245c5ad..dfc7a982fc7 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -66,13 +66,13 @@ enum htc_opmode {
HTC_M_WDS = 2
};
-#define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr)
-#define ATH9K_HTC_AMPDU 1
+#define ATH9K_HTC_AMPDU 1
#define ATH9K_HTC_NORMAL 2
+#define ATH9K_HTC_BEACON 3
+#define ATH9K_HTC_MGMT 4
#define ATH9K_HTC_TX_CTSONLY 0x1
#define ATH9K_HTC_TX_RTSCTS 0x2
-#define ATH9K_HTC_TX_USE_MIN_RATE 0x100
struct tx_frame_hdr {
u8 data_type;
@@ -82,7 +82,8 @@ struct tx_frame_hdr {
__be32 flags; /* ATH9K_HTC_TX_* */
u8 key_type;
u8 keyix;
- u8 reserved[26];
+ u8 cookie;
+ u8 pad;
} __packed;
struct tx_mgmt_hdr {
@@ -92,50 +93,34 @@ struct tx_mgmt_hdr {
u8 flags;
u8 key_type;
u8 keyix;
- u16 reserved;
+ u8 cookie;
+ u8 pad;
} __packed;
struct tx_beacon_header {
- u8 len_changed;
u8 vif_index;
+ u8 len_changed;
u16 rev;
} __packed;
-struct ath9k_htc_target_hw {
- u32 flags;
- u32 flags_ext;
- u32 ampdu_limit;
- u8 ampdu_subframes;
- u8 tx_chainmask;
- u8 tx_chainmask_legacy;
- u8 rtscts_ratecode;
- u8 protmode;
-} __packed;
+#define MAX_TX_AMPDU_SUBFRAMES_9271 17
+#define MAX_TX_AMPDU_SUBFRAMES_7010 22
struct ath9k_htc_cap_target {
- u32 flags;
- u32 flags_ext;
- u32 ampdu_limit;
+ __be32 ampdu_limit;
u8 ampdu_subframes;
+ u8 enable_coex;
u8 tx_chainmask;
- u8 tx_chainmask_legacy;
- u8 rtscts_ratecode;
- u8 protmode;
+ u8 pad;
} __packed;
struct ath9k_htc_target_vif {
u8 index;
- u8 des_bssid[ETH_ALEN];
- __be32 opmode;
+ u8 opmode;
u8 myaddr[ETH_ALEN];
- u8 bssid[ETH_ALEN];
- u32 flags;
- u32 flags_ext;
- u16 ps_sta;
- __be16 rtsthreshold;
u8 ath_cap;
- u8 node;
- s8 mcast_rate;
+ __be16 rtsthreshold;
+ u8 pad;
} __packed;
#define ATH_HTC_STA_AUTH 0x0001
@@ -143,27 +128,16 @@ struct ath9k_htc_target_vif {
#define ATH_HTC_STA_ERP 0x0004
#define ATH_HTC_STA_HT 0x0008
-/* FIXME: UAPSD variables */
struct ath9k_htc_target_sta {
- u16 associd;
- u16 txpower;
- u32 ucastkey;
u8 macaddr[ETH_ALEN];
u8 bssid[ETH_ALEN];
u8 sta_index;
u8 vif_index;
- u8 vif_sta;
- __be16 flags; /* ATH_HTC_STA_* */
- u16 htcap;
- u8 valid;
- u16 capinfo;
- struct ath9k_htc_target_hw *hw;
- struct ath9k_htc_target_vif *vif;
- u16 txseqmgmt;
u8 is_vif_sta;
- u16 maxampdu;
- u16 iv16;
- u32 iv32;
+ __be16 flags; /* ATH_HTC_STA_* */
+ __be16 htcap;
+ __be16 maxampdu;
+ u8 pad;
} __packed;
struct ath9k_htc_target_aggr {
@@ -197,12 +171,38 @@ struct ath9k_htc_target_rate {
struct ath9k_htc_rate rates;
};
-struct ath9k_htc_target_stats {
- __be32 tx_shortretry;
- __be32 tx_longretry;
- __be32 tx_xretries;
- __be32 ht_txunaggr_xretry;
- __be32 ht_tx_xretries;
+struct ath9k_htc_target_rate_mask {
+ u8 vif_index;
+ u8 band;
+ __be32 mask;
+ u16 pad;
+} __packed;
+
+struct ath9k_htc_target_int_stats {
+ __be32 rx;
+ __be32 rxorn;
+ __be32 rxeol;
+ __be32 txurn;
+ __be32 txto;
+ __be32 cst;
+} __packed;
+
+struct ath9k_htc_target_tx_stats {
+ __be32 xretries;
+ __be32 fifoerr;
+ __be32 filtered;
+ __be32 timer_exp;
+ __be32 shortretries;
+ __be32 longretries;
+ __be32 qnull;
+ __be32 encap_fail;
+ __be32 nobuf;
+} __packed;
+
+struct ath9k_htc_target_rx_stats {
+ __be32 nobuf;
+ __be32 host_send;
+ __be32 host_done;
} __packed;
#define ATH9K_HTC_MAX_VIF 2
@@ -244,6 +244,8 @@ struct ath9k_htc_vif {
u8 index;
u16 seq_no;
bool beacon_configured;
+ int bslot;
+ __le64 tsfadjust;
};
struct ath9k_vif_iter_data {
@@ -282,23 +284,65 @@ struct ath9k_htc_rx {
spinlock_t rxbuflock;
};
+#define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */
+#define ATH9K_HTC_TX_TIMEOUT_INTERVAL 2500 /* ms */
+#define ATH9K_HTC_TX_RESERVE 10
+#define ATH9K_HTC_TX_TIMEOUT_COUNT 20
+#define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE)
+
+#define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0)
+#define ATH9K_HTC_OP_TX_DRAIN BIT(1)
+
+struct ath9k_htc_tx {
+ u8 flags;
+ int queued_cnt;
+ struct sk_buff_head mgmt_ep_queue;
+ struct sk_buff_head cab_ep_queue;
+ struct sk_buff_head data_be_queue;
+ struct sk_buff_head data_bk_queue;
+ struct sk_buff_head data_vi_queue;
+ struct sk_buff_head data_vo_queue;
+ struct sk_buff_head tx_failed;
+ DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM);
+ struct timer_list cleanup_timer;
+ spinlock_t tx_lock;
+};
+
struct ath9k_htc_tx_ctl {
u8 type; /* ATH9K_HTC_* */
+ u8 epid;
+ u8 txok;
+ u8 sta_idx;
+ unsigned long timestamp;
};
+static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+
+ BUILD_BUG_ON(sizeof(struct ath9k_htc_tx_ctl) >
+ IEEE80211_TX_INFO_DRIVER_DATA_SIZE);
+ return (struct ath9k_htc_tx_ctl *) &tx_info->driver_data;
+}
+
#ifdef CONFIG_ATH9K_HTC_DEBUGFS
#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++)
+#define CAB_STAT_INC priv->debug.tx_stats.cab_queued++
#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
+void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
+ struct ath_htc_rx_status *rxs);
+
struct ath_tx_stats {
u32 buf_queued;
u32 buf_completed;
u32 skb_queued;
- u32 skb_completed;
- u32 skb_dropped;
+ u32 skb_success;
+ u32 skb_failed;
+ u32 cab_queued;
u32 queue_stats[WME_NUM_AC];
};
@@ -306,55 +350,57 @@ struct ath_rx_stats {
u32 skb_allocated;
u32 skb_completed;
u32 skb_dropped;
+ u32 err_crc;
+ u32 err_decrypt_crc;
+ u32 err_mic;
+ u32 err_pre_delim;
+ u32 err_post_delim;
+ u32 err_decrypt_busy;
+ u32 err_phy;
+ u32 err_phy_stats[ATH9K_PHYERR_MAX];
};
struct ath9k_debug {
struct dentry *debugfs_phy;
- struct dentry *debugfs_tgt_stats;
- struct dentry *debugfs_xmit;
- struct dentry *debugfs_recv;
struct ath_tx_stats tx_stats;
struct ath_rx_stats rx_stats;
- u32 txrate;
};
#else
#define TX_STAT_INC(c) do { } while (0)
#define RX_STAT_INC(c) do { } while (0)
+#define CAB_STAT_INC do { } while (0)
#define TX_QSTAT_INC(c) do { } while (0)
+static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
+ struct ath_htc_rx_status *rxs)
+{
+}
+
#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
#define ATH_LED_PIN_DEF 1
-#define ATH_LED_PIN_9287 8
+#define ATH_LED_PIN_9287 10
#define ATH_LED_PIN_9271 15
#define ATH_LED_PIN_7010 12
-#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
-#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
-
-enum ath_led_type {
- ATH_LED_RADIO,
- ATH_LED_ASSOC,
- ATH_LED_TX,
- ATH_LED_RX
-};
-struct ath_led {
- struct ath9k_htc_priv *priv;
- struct led_classdev led_cdev;
- enum ath_led_type led_type;
- struct delayed_work brightness_work;
- char name[32];
- bool registered;
- int brightness;
-};
+#define BSTUCK_THRESHOLD 10
+
+/*
+ * Adjust these when the max. no of beaconing interfaces is
+ * increased.
+ */
+#define DEFAULT_SWBA_RESPONSE 40 /* in TUs */
+#define MIN_SWBA_RESPONSE 10 /* in TUs */
struct htc_beacon_config {
+ struct ieee80211_vif *bslot[ATH9K_HTC_MAX_BCN_VIF];
u16 beacon_interval;
u16 dtim_period;
u16 bmiss_timeout;
+ u32 bmiss_cnt;
};
struct ath_btcoex {
@@ -372,14 +418,11 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv);
#define OP_INVALID BIT(0)
#define OP_SCANNING BIT(1)
-#define OP_LED_ASSOCIATED BIT(2)
-#define OP_LED_ON BIT(3)
-#define OP_ENABLE_BEACON BIT(4)
-#define OP_LED_DEINIT BIT(5)
-#define OP_BT_PRIORITY_DETECTED BIT(6)
-#define OP_BT_SCAN BIT(7)
-#define OP_ANI_RUNNING BIT(8)
-#define OP_TSF_RESET BIT(9)
+#define OP_ENABLE_BEACON BIT(2)
+#define OP_BT_PRIORITY_DETECTED BIT(3)
+#define OP_BT_SCAN BIT(4)
+#define OP_ANI_RUNNING BIT(5)
+#define OP_TSF_RESET BIT(6)
struct ath9k_htc_priv {
struct device *dev;
@@ -388,6 +431,9 @@ struct ath9k_htc_priv {
struct htc_target *htc;
struct wmi *wmi;
+ u16 fw_version_major;
+ u16 fw_version_minor;
+
enum htc_endpoint_id wmi_cmd_ep;
enum htc_endpoint_id beacon_ep;
enum htc_endpoint_id cab_ep;
@@ -411,27 +457,23 @@ struct ath9k_htc_priv {
u16 txpowlimit;
u16 nvifs;
u16 nstations;
- u32 bmiss_cnt;
bool rearm_ani;
bool reconfig_beacon;
+ unsigned int rxfilter;
struct ath9k_hw_cal_data caldata;
+ struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
spinlock_t beacon_lock;
+ struct htc_beacon_config cur_beacon_conf;
- bool tx_queues_stop;
- spinlock_t tx_lock;
+ struct ath9k_htc_rx rx;
+ struct ath9k_htc_tx tx;
- struct ieee80211_vif *vif;
- struct htc_beacon_config cur_beacon_conf;
- unsigned int rxfilter;
struct tasklet_struct swba_tasklet;
struct tasklet_struct rx_tasklet;
- struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
- struct ath9k_htc_rx rx;
- struct tasklet_struct tx_tasklet;
- struct sk_buff_head tx_queue;
struct delayed_work ani_work;
+ struct tasklet_struct tx_failed_tasklet;
struct work_struct ps_work;
struct work_struct fatal_work;
@@ -440,15 +482,13 @@ struct ath9k_htc_priv {
bool ps_enabled;
bool ps_idle;
- struct ath_led radio_led;
- struct ath_led assoc_led;
- struct ath_led tx_led;
- struct ath_led rx_led;
- struct delayed_work ath9k_led_blink_work;
- int led_on_duration;
- int led_off_duration;
- int led_on_cnt;
- int led_off_cnt;
+#ifdef CONFIG_MAC80211_LEDS
+ enum led_brightness brightness;
+ bool led_registered;
+ char led_name[32];
+ struct led_classdev led_cdev;
+ struct work_struct led_work;
+#endif
int beaconq;
int cabq;
@@ -470,11 +510,18 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
void ath9k_htc_reset(struct ath9k_htc_priv *priv);
+void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv,
+ struct ieee80211_vif *vif);
+void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv,
+ struct ieee80211_vif *vif);
+void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv,
+ struct ieee80211_vif *vif);
void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv);
void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
struct ieee80211_vif *vif);
void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv);
-void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending);
+void ath9k_htc_swba(struct ath9k_htc_priv *priv,
+ struct wmi_event_swba *swba);
void ath9k_htc_rxep(void *priv, struct sk_buff *skb,
enum htc_endpoint_id ep_id);
@@ -483,7 +530,8 @@ void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id,
void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
enum htc_endpoint_id ep_id, bool txok);
-int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv);
+int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
+ u8 enable_coex);
void ath9k_htc_station_work(struct work_struct *work);
void ath9k_htc_aggr_work(struct work_struct *work);
void ath9k_htc_ani_work(struct work_struct *work);
@@ -491,14 +539,23 @@ void ath9k_htc_start_ani(struct ath9k_htc_priv *priv);
void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv);
int ath9k_tx_init(struct ath9k_htc_priv *priv);
-void ath9k_tx_tasklet(unsigned long data);
-int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb);
+int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
+ struct sk_buff *skb, u8 slot, bool is_cab);
void ath9k_tx_cleanup(struct ath9k_htc_priv *priv);
bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype);
int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv);
int get_hw_qnum(u16 queue, int *hwq_map);
int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
struct ath9k_tx_queue_info *qinfo);
+void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv);
+void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv);
+int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv);
+void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot);
+void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv);
+void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event);
+void ath9k_htc_tx_failed(struct ath9k_htc_priv *priv);
+void ath9k_tx_failed_tasklet(unsigned long data);
+void ath9k_htc_tx_cleanup_timer(unsigned long data);
int ath9k_rx_init(struct ath9k_htc_priv *priv);
void ath9k_rx_cleanup(struct ath9k_htc_priv *priv);
@@ -516,9 +573,24 @@ void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw);
void ath9k_htc_radio_enable(struct ieee80211_hw *hw);
void ath9k_htc_radio_disable(struct ieee80211_hw *hw);
-void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv);
+
+#ifdef CONFIG_MAC80211_LEDS
void ath9k_init_leds(struct ath9k_htc_priv *priv);
void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
+void ath9k_led_work(struct work_struct *work);
+#else
+static inline void ath9k_init_leds(struct ath9k_htc_priv *priv)
+{
+}
+
+static inline void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
+{
+}
+
+static inline void ath9k_led_work(struct work_struct *work)
+{
+}
+#endif
int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
u16 devid, char *product, u32 drv_info);
@@ -528,15 +600,9 @@ void ath9k_htc_suspend(struct htc_target *htc_handle);
int ath9k_htc_resume(struct htc_target *htc_handle);
#endif
#ifdef CONFIG_ATH9K_HTC_DEBUGFS
-int ath9k_htc_debug_create_root(void);
-void ath9k_htc_debug_remove_root(void);
int ath9k_htc_init_debug(struct ath_hw *ah);
-void ath9k_htc_exit_debug(struct ath_hw *ah);
#else
-static inline int ath9k_htc_debug_create_root(void) { return 0; };
-static inline void ath9k_htc_debug_remove_root(void) {};
static inline int ath9k_htc_init_debug(struct ath_hw *ah) { return 0; };
-static inline void ath9k_htc_exit_debug(struct ath_hw *ah) {};
#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
#endif /* HTC_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index 8d1d8792436..0ded2c66d5f 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -18,6 +18,50 @@
#define FUDGE 2
+void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
+{
+ struct ath_hw *ah = priv->ah;
+ struct ath9k_tx_queue_info qi, qi_be;
+
+ memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
+ memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info));
+
+ ath9k_hw_get_txq_props(ah, priv->beaconq, &qi);
+
+ if (priv->ah->opmode == NL80211_IFTYPE_AP) {
+ qi.tqi_aifs = 1;
+ qi.tqi_cwmin = 0;
+ qi.tqi_cwmax = 0;
+ } else if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) {
+ int qnum = priv->hwq_map[WME_AC_BE];
+
+ ath9k_hw_get_txq_props(ah, qnum, &qi_be);
+
+ qi.tqi_aifs = qi_be.tqi_aifs;
+
+ /*
+ * For WIFI Beacon Distribution
+ * Long slot time : 2x cwmin
+ * Short slot time : 4x cwmin
+ */
+ if (ah->slottime == ATH9K_SLOT_TIME_20)
+ qi.tqi_cwmin = 2*qi_be.tqi_cwmin;
+ else
+ qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
+
+ qi.tqi_cwmax = qi_be.tqi_cwmax;
+
+ }
+
+ if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) {
+ ath_err(ath9k_hw_common(ah),
+ "Unable to update beacon queue %u!\n", priv->beaconq);
+ } else {
+ ath9k_hw_resettxqueue(ah, priv->beaconq);
+ }
+}
+
+
static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
struct htc_beacon_config *bss_conf)
{
@@ -30,7 +74,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
__be32 htc_imask = 0;
u64 tsf;
int num_beacons, offset, dtim_dec_count, cfp_dec_count;
- int ret;
+ int ret __attribute__ ((unused));
u8 cmd_rsp;
memset(&bs, 0, sizeof(bs));
@@ -146,7 +190,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
enum ath9k_int imask = 0;
u32 nexttbtt, intval, tsftu;
__be32 htc_imask = 0;
- int ret;
+ int ret __attribute__ ((unused));
u8 cmd_rsp;
u64 tsf;
@@ -154,8 +198,17 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
intval /= ATH9K_HTC_MAX_BCN_VIF;
nexttbtt = intval;
+ /*
+ * To reduce beacon misses under heavy TX load,
+ * set the beacon response time to a larger value.
+ */
+ if (intval > DEFAULT_SWBA_RESPONSE)
+ priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE;
+ else
+ priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE;
+
if (priv->op_flags & OP_TSF_RESET) {
- intval |= ATH9K_BEACON_RESET_TSF;
+ ath9k_hw_reset_tsf(priv->ah);
priv->op_flags &= ~OP_TSF_RESET;
} else {
/*
@@ -168,18 +221,20 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
} while (nexttbtt < tsftu);
}
- intval |= ATH9K_BEACON_ENA;
-
if (priv->op_flags & OP_ENABLE_BEACON)
imask |= ATH9K_INT_SWBA;
ath_dbg(common, ATH_DBG_CONFIG,
- "AP Beacon config, intval: %d, nexttbtt: %u imask: 0x%x\n",
- bss_conf->beacon_interval, nexttbtt, imask);
+ "AP Beacon config, intval: %d, nexttbtt: %u, resp_time: %d "
+ "imask: 0x%x\n",
+ bss_conf->beacon_interval, nexttbtt,
+ priv->ah->config.sw_beacon_response_time, imask);
+
+ ath9k_htc_beaconq_config(priv);
WMI_CMD(WMI_DISABLE_INTR_CMDID);
- ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
- priv->bmiss_cnt = 0;
+ ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval));
+ priv->cur_beacon_conf.bmiss_cnt = 0;
htc_imask = cpu_to_be32(imask);
WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
}
@@ -191,7 +246,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
enum ath9k_int imask = 0;
u32 nexttbtt, intval, tsftu;
__be32 htc_imask = 0;
- int ret;
+ int ret __attribute__ ((unused));
u8 cmd_rsp;
u64 tsf;
@@ -207,17 +262,26 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
nexttbtt += intval;
} while (nexttbtt < tsftu);
- intval |= ATH9K_BEACON_ENA;
+ /*
+ * Only one IBSS interfce is allowed.
+ */
+ if (intval > DEFAULT_SWBA_RESPONSE)
+ priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE;
+ else
+ priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE;
+
if (priv->op_flags & OP_ENABLE_BEACON)
imask |= ATH9K_INT_SWBA;
ath_dbg(common, ATH_DBG_CONFIG,
- "IBSS Beacon config, intval: %d, nexttbtt: %u, imask: 0x%x\n",
- bss_conf->beacon_interval, nexttbtt, imask);
+ "IBSS Beacon config, intval: %d, nexttbtt: %u, "
+ "resp_time: %d, imask: 0x%x\n",
+ bss_conf->beacon_interval, nexttbtt,
+ priv->ah->config.sw_beacon_response_time, imask);
WMI_CMD(WMI_DISABLE_INTR_CMDID);
- ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
- priv->bmiss_cnt = 0;
+ ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval));
+ priv->cur_beacon_conf.bmiss_cnt = 0;
htc_imask = cpu_to_be32(imask);
WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
}
@@ -228,38 +292,101 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
dev_kfree_skb_any(skb);
}
-void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending)
+static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv,
+ int slot)
{
- struct ath9k_htc_vif *avp = (void *)priv->vif->drv_priv;
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct ieee80211_vif *vif;
+ struct sk_buff *skb;
+ struct ieee80211_hdr *hdr;
+ int padpos, padsize, ret, tx_slot;
+
+ spin_lock_bh(&priv->beacon_lock);
+
+ vif = priv->cur_beacon_conf.bslot[slot];
+
+ skb = ieee80211_get_buffered_bc(priv->hw, vif);
+
+ while(skb) {
+ hdr = (struct ieee80211_hdr *) skb->data;
+
+ padpos = ath9k_cmn_padpos(hdr->frame_control);
+ padsize = padpos & 3;
+ if (padsize && skb->len > padpos) {
+ if (skb_headroom(skb) < padsize) {
+ dev_kfree_skb_any(skb);
+ goto next;
+ }
+ skb_push(skb, padsize);
+ memmove(skb->data, skb->data + padsize, padpos);
+ }
+
+ tx_slot = ath9k_htc_tx_get_slot(priv);
+ if (tx_slot < 0) {
+ ath_dbg(common, ATH_DBG_XMIT, "No free CAB slot\n");
+ dev_kfree_skb_any(skb);
+ goto next;
+ }
+
+ ret = ath9k_htc_tx_start(priv, skb, tx_slot, true);
+ if (ret != 0) {
+ ath9k_htc_tx_clear_slot(priv, tx_slot);
+ dev_kfree_skb_any(skb);
+
+ ath_dbg(common, ATH_DBG_XMIT,
+ "Failed to send CAB frame\n");
+ } else {
+ spin_lock_bh(&priv->tx.tx_lock);
+ priv->tx.queued_cnt++;
+ spin_unlock_bh(&priv->tx.tx_lock);
+ }
+ next:
+ skb = ieee80211_get_buffered_bc(priv->hw, vif);
+ }
+
+ spin_unlock_bh(&priv->beacon_lock);
+}
+
+static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv,
+ int slot)
+{
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct ieee80211_vif *vif;
+ struct ath9k_htc_vif *avp;
struct tx_beacon_header beacon_hdr;
- struct ath9k_htc_tx_ctl tx_ctl;
+ struct ath9k_htc_tx_ctl *tx_ctl;
struct ieee80211_tx_info *info;
+ struct ieee80211_mgmt *mgmt;
struct sk_buff *beacon;
u8 *tx_fhdr;
+ int ret;
memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header));
- memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
-
- /* FIXME: Handle BMISS */
- if (beacon_pending != 0) {
- priv->bmiss_cnt++;
- return;
- }
spin_lock_bh(&priv->beacon_lock);
+ vif = priv->cur_beacon_conf.bslot[slot];
+ avp = (struct ath9k_htc_vif *)vif->drv_priv;
+
if (unlikely(priv->op_flags & OP_SCANNING)) {
spin_unlock_bh(&priv->beacon_lock);
return;
}
/* Get a new beacon */
- beacon = ieee80211_beacon_get(priv->hw, priv->vif);
+ beacon = ieee80211_beacon_get(priv->hw, vif);
if (!beacon) {
spin_unlock_bh(&priv->beacon_lock);
return;
}
+ /*
+ * Update the TSF adjust value here, the HW will
+ * add this value for every beacon.
+ */
+ mgmt = (struct ieee80211_mgmt *)beacon->data;
+ mgmt->u.beacon.timestamp = avp->tsfadjust;
+
info = IEEE80211_SKB_CB(beacon);
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
struct ieee80211_hdr *hdr =
@@ -269,45 +396,149 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending)
hdr->seq_ctrl |= cpu_to_le16(avp->seq_no);
}
- tx_ctl.type = ATH9K_HTC_NORMAL;
+ tx_ctl = HTC_SKB_CB(beacon);
+ memset(tx_ctl, 0, sizeof(*tx_ctl));
+
+ tx_ctl->type = ATH9K_HTC_BEACON;
+ tx_ctl->epid = priv->beacon_ep;
+
beacon_hdr.vif_index = avp->index;
tx_fhdr = skb_push(beacon, sizeof(beacon_hdr));
memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr));
- htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl);
+ ret = htc_send(priv->htc, beacon);
+ if (ret != 0) {
+ if (ret == -ENOMEM) {
+ ath_dbg(common, ATH_DBG_BSTUCK,
+ "Failed to send beacon, no free TX buffer\n");
+ }
+ dev_kfree_skb_any(beacon);
+ }
spin_unlock_bh(&priv->beacon_lock);
}
-/* Currently, only for IBSS */
-void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
+static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv,
+ struct wmi_event_swba *swba)
{
- struct ath_hw *ah = priv->ah;
- struct ath9k_tx_queue_info qi, qi_be;
- int qnum = priv->hwq_map[WME_AC_BE];
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ u64 tsf;
+ u32 tsftu;
+ u16 intval;
+ int slot;
- memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
- memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info));
+ intval = priv->cur_beacon_conf.beacon_interval & ATH9K_BEACON_PERIOD;
- ath9k_hw_get_txq_props(ah, qnum, &qi_be);
+ tsf = be64_to_cpu(swba->tsf);
+ tsftu = TSF_TO_TU(tsf >> 32, tsf);
+ slot = ((tsftu % intval) * ATH9K_HTC_MAX_BCN_VIF) / intval;
+ slot = ATH9K_HTC_MAX_BCN_VIF - slot - 1;
- qi.tqi_aifs = qi_be.tqi_aifs;
- /* For WIFI Beacon Distribution
- * Long slot time : 2x cwmin
- * Short slot time : 4x cwmin
- */
- if (ah->slottime == ATH9K_SLOT_TIME_20)
- qi.tqi_cwmin = 2*qi_be.tqi_cwmin;
- else
- qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
- qi.tqi_cwmax = qi_be.tqi_cwmax;
+ ath_dbg(common, ATH_DBG_BEACON,
+ "Choose slot: %d, tsf: %llu, tsftu: %u, intval: %u\n",
+ slot, tsf, tsftu, intval);
- if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) {
- ath_err(ath9k_hw_common(ah),
- "Unable to update beacon queue %u!\n", qnum);
- } else {
- ath9k_hw_resettxqueue(ah, priv->beaconq);
+ return slot;
+}
+
+void ath9k_htc_swba(struct ath9k_htc_priv *priv,
+ struct wmi_event_swba *swba)
+{
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ int slot;
+
+ if (swba->beacon_pending != 0) {
+ priv->cur_beacon_conf.bmiss_cnt++;
+ if (priv->cur_beacon_conf.bmiss_cnt > BSTUCK_THRESHOLD) {
+ ath_dbg(common, ATH_DBG_BSTUCK,
+ "Beacon stuck, HW reset\n");
+ ieee80211_queue_work(priv->hw,
+ &priv->fatal_work);
+ }
+ return;
}
+
+ if (priv->cur_beacon_conf.bmiss_cnt) {
+ ath_dbg(common, ATH_DBG_BSTUCK,
+ "Resuming beacon xmit after %u misses\n",
+ priv->cur_beacon_conf.bmiss_cnt);
+ priv->cur_beacon_conf.bmiss_cnt = 0;
+ }
+
+ slot = ath9k_htc_choose_bslot(priv, swba);
+ spin_lock_bh(&priv->beacon_lock);
+ if (priv->cur_beacon_conf.bslot[slot] == NULL) {
+ spin_unlock_bh(&priv->beacon_lock);
+ return;
+ }
+ spin_unlock_bh(&priv->beacon_lock);
+
+ ath9k_htc_send_buffered(priv, slot);
+ ath9k_htc_send_beacon(priv, slot);
+}
+
+void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv,
+ struct ieee80211_vif *vif)
+{
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv;
+ int i = 0;
+
+ spin_lock_bh(&priv->beacon_lock);
+ for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) {
+ if (priv->cur_beacon_conf.bslot[i] == NULL) {
+ avp->bslot = i;
+ break;
+ }
+ }
+
+ priv->cur_beacon_conf.bslot[avp->bslot] = vif;
+ spin_unlock_bh(&priv->beacon_lock);
+
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Added interface at beacon slot: %d\n", avp->bslot);
+}
+
+void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv,
+ struct ieee80211_vif *vif)
+{
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv;
+
+ spin_lock_bh(&priv->beacon_lock);
+ priv->cur_beacon_conf.bslot[avp->bslot] = NULL;
+ spin_unlock_bh(&priv->beacon_lock);
+
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Removed interface at beacon slot: %d\n", avp->bslot);
+}
+
+/*
+ * Calculate the TSF adjustment value for all slots
+ * other than zero.
+ */
+void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv,
+ struct ieee80211_vif *vif)
+{
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv;
+ struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
+ u64 tsfadjust;
+
+ if (avp->bslot == 0)
+ return;
+
+ /*
+ * The beacon interval cannot be different for multi-AP mode,
+ * and we reach here only for VIF slots greater than zero,
+ * so beacon_interval is guaranteed to be set in cur_conf.
+ */
+ tsfadjust = cur_conf->beacon_interval * avp->bslot / ATH9K_HTC_MAX_BCN_VIF;
+ avp->tsfadjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
+
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "tsfadjust is: %llu for bslot: %d\n",
+ (unsigned long long)tsfadjust, avp->bslot);
}
static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
new file mode 100644
index 00000000000..aa48b3abbc4
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -0,0 +1,960 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "htc.h"
+
+static int ath9k_debugfs_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath9k_htc_priv *priv = file->private_data;
+ struct ath9k_htc_target_int_stats cmd_rsp;
+ char buf[512];
+ unsigned int len = 0;
+ int ret = 0;
+
+ memset(&cmd_rsp, 0, sizeof(cmd_rsp));
+
+ ath9k_htc_ps_wakeup(priv);
+
+ WMI_CMD(WMI_INT_STATS_CMDID);
+ if (ret) {
+ ath9k_htc_ps_restore(priv);
+ return -EINVAL;
+ }
+
+ ath9k_htc_ps_restore(priv);
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "RX",
+ be32_to_cpu(cmd_rsp.rx));
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "RXORN",
+ be32_to_cpu(cmd_rsp.rxorn));
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "RXEOL",
+ be32_to_cpu(cmd_rsp.rxeol));
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "TXURN",
+ be32_to_cpu(cmd_rsp.txurn));
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "TXTO",
+ be32_to_cpu(cmd_rsp.txto));
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "CST",
+ be32_to_cpu(cmd_rsp.cst));
+
+ if (len > sizeof(buf))
+ len = sizeof(buf);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_tgt_int_stats = {
+ .read = read_file_tgt_int_stats,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath9k_htc_priv *priv = file->private_data;
+ struct ath9k_htc_target_tx_stats cmd_rsp;
+ char buf[512];
+ unsigned int len = 0;
+ int ret = 0;
+
+ memset(&cmd_rsp, 0, sizeof(cmd_rsp));
+
+ ath9k_htc_ps_wakeup(priv);
+
+ WMI_CMD(WMI_TX_STATS_CMDID);
+ if (ret) {
+ ath9k_htc_ps_restore(priv);
+ return -EINVAL;
+ }
+
+ ath9k_htc_ps_restore(priv);
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "Xretries",
+ be32_to_cpu(cmd_rsp.xretries));
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "FifoErr",
+ be32_to_cpu(cmd_rsp.fifoerr));
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "Filtered",
+ be32_to_cpu(cmd_rsp.filtered));
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "TimerExp",
+ be32_to_cpu(cmd_rsp.timer_exp));
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "ShortRetries",
+ be32_to_cpu(cmd_rsp.shortretries));
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "LongRetries",
+ be32_to_cpu(cmd_rsp.longretries));
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "QueueNull",
+ be32_to_cpu(cmd_rsp.qnull));
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "EncapFail",
+ be32_to_cpu(cmd_rsp.encap_fail));
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "NoBuf",
+ be32_to_cpu(cmd_rsp.nobuf));
+
+ if (len > sizeof(buf))
+ len = sizeof(buf);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_tgt_tx_stats = {
+ .read = read_file_tgt_tx_stats,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath9k_htc_priv *priv = file->private_data;
+ struct ath9k_htc_target_rx_stats cmd_rsp;
+ char buf[512];
+ unsigned int len = 0;
+ int ret = 0;
+
+ memset(&cmd_rsp, 0, sizeof(cmd_rsp));
+
+ ath9k_htc_ps_wakeup(priv);
+
+ WMI_CMD(WMI_RX_STATS_CMDID);
+ if (ret) {
+ ath9k_htc_ps_restore(priv);
+ return -EINVAL;
+ }
+
+ ath9k_htc_ps_restore(priv);
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "NoBuf",
+ be32_to_cpu(cmd_rsp.nobuf));
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "HostSend",
+ be32_to_cpu(cmd_rsp.host_send));
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "HostDone",
+ be32_to_cpu(cmd_rsp.host_done));
+
+ if (len > sizeof(buf))
+ len = sizeof(buf);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_tgt_rx_stats = {
+ .read = read_file_tgt_rx_stats,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath9k_htc_priv *priv = file->private_data;
+ char buf[512];
+ unsigned int len = 0;
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "Buffers queued",
+ priv->debug.tx_stats.buf_queued);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "Buffers completed",
+ priv->debug.tx_stats.buf_completed);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "SKBs queued",
+ priv->debug.tx_stats.skb_queued);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "SKBs success",
+ priv->debug.tx_stats.skb_success);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "SKBs failed",
+ priv->debug.tx_stats.skb_failed);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "CAB queued",
+ priv->debug.tx_stats.cab_queued);
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "BE queued",
+ priv->debug.tx_stats.queue_stats[WME_AC_BE]);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "BK queued",
+ priv->debug.tx_stats.queue_stats[WME_AC_BK]);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "VI queued",
+ priv->debug.tx_stats.queue_stats[WME_AC_VI]);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%20s : %10u\n", "VO queued",
+ priv->debug.tx_stats.queue_stats[WME_AC_VO]);
+
+ if (len > sizeof(buf))
+ len = sizeof(buf);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_xmit = {
+ .read = read_file_xmit,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
+ struct ath_htc_rx_status *rxs)
+{
+#define RX_PHY_ERR_INC(c) priv->debug.rx_stats.err_phy_stats[c]++
+
+ if (rxs->rs_status & ATH9K_RXERR_CRC)
+ priv->debug.rx_stats.err_crc++;
+ if (rxs->rs_status & ATH9K_RXERR_DECRYPT)
+ priv->debug.rx_stats.err_decrypt_crc++;
+ if (rxs->rs_status & ATH9K_RXERR_MIC)
+ priv->debug.rx_stats.err_mic++;
+ if (rxs->rs_status & ATH9K_RX_DELIM_CRC_PRE)
+ priv->debug.rx_stats.err_pre_delim++;
+ if (rxs->rs_status & ATH9K_RX_DELIM_CRC_POST)
+ priv->debug.rx_stats.err_post_delim++;
+ if (rxs->rs_status & ATH9K_RX_DECRYPT_BUSY)
+ priv->debug.rx_stats.err_decrypt_busy++;
+
+ if (rxs->rs_status & ATH9K_RXERR_PHY) {
+ priv->debug.rx_stats.err_phy++;
+ if (rxs->rs_phyerr < ATH9K_PHYERR_MAX)
+ RX_PHY_ERR_INC(rxs->rs_phyerr);
+ }
+
+#undef RX_PHY_ERR_INC
+}
+
+static ssize_t read_file_recv(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+#define PHY_ERR(s, p) \
+ len += snprintf(buf + len, size - len, "%20s : %10u\n", s, \
+ priv->debug.rx_stats.err_phy_stats[p]);
+
+ struct ath9k_htc_priv *priv = file->private_data;
+ char *buf;
+ unsigned int len = 0, size = 1500;
+ ssize_t retval = 0;
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ len += snprintf(buf + len, size - len,
+ "%20s : %10u\n", "SKBs allocated",
+ priv->debug.rx_stats.skb_allocated);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10u\n", "SKBs completed",
+ priv->debug.rx_stats.skb_completed);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10u\n", "SKBs Dropped",
+ priv->debug.rx_stats.skb_dropped);
+
+ len += snprintf(buf + len, size - len,
+ "%20s : %10u\n", "CRC ERR",
+ priv->debug.rx_stats.err_crc);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10u\n", "DECRYPT CRC ERR",
+ priv->debug.rx_stats.err_decrypt_crc);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10u\n", "MIC ERR",
+ priv->debug.rx_stats.err_mic);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10u\n", "PRE-DELIM CRC ERR",
+ priv->debug.rx_stats.err_pre_delim);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10u\n", "POST-DELIM CRC ERR",
+ priv->debug.rx_stats.err_post_delim);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10u\n", "DECRYPT BUSY ERR",
+ priv->debug.rx_stats.err_decrypt_busy);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10u\n", "TOTAL PHY ERR",
+ priv->debug.rx_stats.err_phy);
+
+
+ PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN);
+ PHY_ERR("TIMING", ATH9K_PHYERR_TIMING);
+ PHY_ERR("PARITY", ATH9K_PHYERR_PARITY);
+ PHY_ERR("RATE", ATH9K_PHYERR_RATE);
+ PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH);
+ PHY_ERR("RADAR", ATH9K_PHYERR_RADAR);
+ PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE);
+ PHY_ERR("TOR", ATH9K_PHYERR_TOR);
+ PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING);
+ PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
+ PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
+ PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
+ PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP);
+ PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE);
+ PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART);
+ PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT);
+ PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING);
+ PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC);
+ PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
+ PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE);
+ PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART);
+ PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
+ PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP);
+ PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR);
+ PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
+ PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
+
+ if (len > size)
+ len = size;
+
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return retval;
+
+#undef PHY_ERR
+}
+
+static const struct file_operations fops_recv = {
+ .read = read_file_recv,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+static ssize_t read_file_slot(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath9k_htc_priv *priv = file->private_data;
+ char buf[512];
+ unsigned int len = 0;
+
+ spin_lock_bh(&priv->tx.tx_lock);
+
+ len += snprintf(buf + len, sizeof(buf) - len, "TX slot bitmap : ");
+
+ len += bitmap_scnprintf(buf + len, sizeof(buf) - len,
+ priv->tx.tx_slot, MAX_TX_BUF_NUM);
+
+ len += snprintf(buf + len, sizeof(buf) - len, "\n");
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "Used slots : %d\n",
+ bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM));
+
+ spin_unlock_bh(&priv->tx.tx_lock);
+
+ if (len > sizeof(buf))
+ len = sizeof(buf);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_slot = {
+ .read = read_file_slot,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+static ssize_t read_file_queue(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath9k_htc_priv *priv = file->private_data;
+ char buf[512];
+ unsigned int len = 0;
+
+ len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+ "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue));
+
+ len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+ "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue));
+
+ len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+ "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue));
+
+ len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+ "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue));
+
+ len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+ "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue));
+
+ len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+ "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue));
+
+ len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+ "Failed queue", skb_queue_len(&priv->tx.tx_failed));
+
+ spin_lock_bh(&priv->tx.tx_lock);
+ len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+ "Queued count", priv->tx.queued_cnt);
+ spin_unlock_bh(&priv->tx.tx_lock);
+
+ if (len > sizeof(buf))
+ len = sizeof(buf);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+
+}
+
+static const struct file_operations fops_queue = {
+ .read = read_file_queue,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+static ssize_t read_file_debug(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath9k_htc_priv *priv = file->private_data;
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ char buf[32];
+ unsigned int len;
+
+ len = sprintf(buf, "0x%08x\n", common->debug_mask);
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath9k_htc_priv *priv = file->private_data;
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ unsigned long mask;
+ char buf[32];
+ ssize_t len;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ if (strict_strtoul(buf, 0, &mask))
+ return -EINVAL;
+
+ common->debug_mask = mask;
+ return count;
+}
+
+static const struct file_operations fops_debug = {
+ .read = read_file_debug,
+ .write = write_file_debug,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath9k_htc_priv *priv = file->private_data;
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct base_eep_header *pBase = NULL;
+ unsigned int len = 0, size = 1500;
+ ssize_t retval = 0;
+ char *buf;
+
+ /*
+ * This can be done since all the 3 EEPROM families have the
+ * same base header upto a certain point, and we are interested in
+ * the data only upto that point.
+ */
+
+ if (AR_SREV_9271(priv->ah))
+ pBase = (struct base_eep_header *)
+ &priv->ah->eeprom.map4k.baseEepHeader;
+ else if (priv->ah->hw_version.usbdev == AR9280_USB)
+ pBase = (struct base_eep_header *)
+ &priv->ah->eeprom.def.baseEepHeader;
+ else if (priv->ah->hw_version.usbdev == AR9287_USB)
+ pBase = (struct base_eep_header *)
+ &priv->ah->eeprom.map9287.baseEepHeader;
+
+ if (pBase == NULL) {
+ ath_err(common, "Unknown EEPROM type\n");
+ return 0;
+ }
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n", "Major Version",
+ pBase->version >> 12);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n", "Minor Version",
+ pBase->version & 0xFFF);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n", "Checksum",
+ pBase->checksum);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n", "Length",
+ pBase->length);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n", "RegDomain1",
+ pBase->regDmn[0]);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n", "RegDomain2",
+ pBase->regDmn[1]);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n",
+ "TX Mask", pBase->txMask);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n",
+ "RX Mask", pBase->rxMask);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n",
+ "Allow 5GHz",
+ !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n",
+ "Allow 2GHz",
+ !!(pBase->opCapFlags & AR5416_OPFLAGS_11G));
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n",
+ "Disable 2GHz HT20",
+ !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT20));
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n",
+ "Disable 2GHz HT40",
+ !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT40));
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n",
+ "Disable 5Ghz HT20",
+ !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT20));
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n",
+ "Disable 5Ghz HT40",
+ !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT40));
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n",
+ "Big Endian",
+ !!(pBase->eepMisc & 0x01));
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n",
+ "Cal Bin Major Ver",
+ (pBase->binBuildNumber >> 24) & 0xFF);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n",
+ "Cal Bin Minor Ver",
+ (pBase->binBuildNumber >> 16) & 0xFF);
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n",
+ "Cal Bin Build",
+ (pBase->binBuildNumber >> 8) & 0xFF);
+
+ /*
+ * UB91 specific data.
+ */
+ if (AR_SREV_9271(priv->ah)) {
+ struct base_eep_header_4k *pBase4k =
+ &priv->ah->eeprom.map4k.baseEepHeader;
+
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n",
+ "TX Gain type",
+ pBase4k->txGainType);
+ }
+
+ /*
+ * UB95 specific data.
+ */
+ if (priv->ah->hw_version.usbdev == AR9287_USB) {
+ struct base_eep_ar9287_header *pBase9287 =
+ &priv->ah->eeprom.map9287.baseEepHeader;
+
+ len += snprintf(buf + len, size - len,
+ "%20s : %10ddB\n",
+ "Power Table Offset",
+ pBase9287->pwrTableOffset);
+
+ len += snprintf(buf + len, size - len,
+ "%20s : %10d\n",
+ "OpenLoop Power Ctrl",
+ pBase9287->openLoopPwrCntl);
+ }
+
+ len += snprintf(buf + len, size - len,
+ "%20s : %02X:%02X:%02X:%02X:%02X:%02X\n",
+ "MacAddress",
+ pBase->macAddr[0], pBase->macAddr[1], pBase->macAddr[2],
+ pBase->macAddr[3], pBase->macAddr[4], pBase->macAddr[5]);
+ if (len > size)
+ len = size;
+
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return retval;
+}
+
+static const struct file_operations fops_base_eeprom = {
+ .read = read_file_base_eeprom,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+static ssize_t read_4k_modal_eeprom(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+#define PR_EEP(_s, _val) \
+ do { \
+ len += snprintf(buf + len, size - len, "%20s : %10d\n", \
+ _s, (_val)); \
+ } while (0)
+
+ struct ath9k_htc_priv *priv = file->private_data;
+ struct modal_eep_4k_header *pModal = &priv->ah->eeprom.map4k.modalHeader;
+ unsigned int len = 0, size = 2048;
+ ssize_t retval = 0;
+ char *buf;
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
+ PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
+ PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
+ PR_EEP("Switch Settle", pModal->switchSettling);
+ PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
+ PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
+ PR_EEP("ADC Desired size", pModal->adcDesiredSize);
+ PR_EEP("PGA Desired size", pModal->pgaDesiredSize);
+ PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]);
+ PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
+ PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
+ PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
+ PR_EEP("CCA Threshold)", pModal->thresh62);
+ PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
+ PR_EEP("xpdGain", pModal->xpdGain);
+ PR_EEP("External PD", pModal->xpd);
+ PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
+ PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
+ PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
+ PR_EEP("O/D Bias Version", pModal->version);
+ PR_EEP("CCK OutputBias", pModal->ob_0);
+ PR_EEP("BPSK OutputBias", pModal->ob_1);
+ PR_EEP("QPSK OutputBias", pModal->ob_2);
+ PR_EEP("16QAM OutputBias", pModal->ob_3);
+ PR_EEP("64QAM OutputBias", pModal->ob_4);
+ PR_EEP("CCK Driver1_Bias", pModal->db1_0);
+ PR_EEP("BPSK Driver1_Bias", pModal->db1_1);
+ PR_EEP("QPSK Driver1_Bias", pModal->db1_2);
+ PR_EEP("16QAM Driver1_Bias", pModal->db1_3);
+ PR_EEP("64QAM Driver1_Bias", pModal->db1_4);
+ PR_EEP("CCK Driver2_Bias", pModal->db2_0);
+ PR_EEP("BPSK Driver2_Bias", pModal->db2_1);
+ PR_EEP("QPSK Driver2_Bias", pModal->db2_2);
+ PR_EEP("16QAM Driver2_Bias", pModal->db2_3);
+ PR_EEP("64QAM Driver2_Bias", pModal->db2_4);
+ PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
+ PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
+ PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
+ PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
+ PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
+ PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
+ PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
+ PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]);
+ PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]);
+ PR_EEP("Ant. Diversity ctl1", pModal->antdiv_ctl1);
+ PR_EEP("Ant. Diversity ctl2", pModal->antdiv_ctl2);
+ PR_EEP("TX Diversity", pModal->tx_diversity);
+
+ if (len > size)
+ len = size;
+
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return retval;
+
+#undef PR_EEP
+}
+
+static ssize_t read_def_modal_eeprom(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+#define PR_EEP(_s, _val) \
+ do { \
+ if (pBase->opCapFlags & AR5416_OPFLAGS_11G) { \
+ pModal = &priv->ah->eeprom.def.modalHeader[1]; \
+ len += snprintf(buf + len, size - len, "%20s : %8d%7s", \
+ _s, (_val), "|"); \
+ } \
+ if (pBase->opCapFlags & AR5416_OPFLAGS_11A) { \
+ pModal = &priv->ah->eeprom.def.modalHeader[0]; \
+ len += snprintf(buf + len, size - len, "%9d\n", \
+ (_val)); \
+ } \
+ } while (0)
+
+ struct ath9k_htc_priv *priv = file->private_data;
+ struct base_eep_header *pBase = &priv->ah->eeprom.def.baseEepHeader;
+ struct modal_eep_header *pModal = NULL;
+ unsigned int len = 0, size = 3500;
+ ssize_t retval = 0;
+ char *buf;
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ len += snprintf(buf + len, size - len,
+ "%31s %15s\n", "2G", "5G");
+ len += snprintf(buf + len, size - len,
+ "%32s %16s\n", "====", "====\n");
+
+ PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
+ PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]);
+ PR_EEP("Chain2 Ant. Control", pModal->antCtrlChain[2]);
+ PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
+ PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
+ PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]);
+ PR_EEP("Chain2 Ant. Gain", pModal->antennaGainCh[2]);
+ PR_EEP("Switch Settle", pModal->switchSettling);
+ PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
+ PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]);
+ PR_EEP("Chain2 TxRxAtten", pModal->txRxAttenCh[2]);
+ PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
+ PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]);
+ PR_EEP("Chain2 RxTxMargin", pModal->rxTxMarginCh[2]);
+ PR_EEP("ADC Desired size", pModal->adcDesiredSize);
+ PR_EEP("PGA Desired size", pModal->pgaDesiredSize);
+ PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]);
+ PR_EEP("Chain1 xlna Gain", pModal->xlnaGainCh[1]);
+ PR_EEP("Chain2 xlna Gain", pModal->xlnaGainCh[2]);
+ PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
+ PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
+ PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
+ PR_EEP("CCA Threshold)", pModal->thresh62);
+ PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
+ PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]);
+ PR_EEP("Chain2 NF Threshold", pModal->noiseFloorThreshCh[2]);
+ PR_EEP("xpdGain", pModal->xpdGain);
+ PR_EEP("External PD", pModal->xpd);
+ PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
+ PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]);
+ PR_EEP("Chain2 I Coefficient", pModal->iqCalICh[2]);
+ PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
+ PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]);
+ PR_EEP("Chain2 Q Coefficient", pModal->iqCalQCh[2]);
+ PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
+ PR_EEP("Chain0 OutputBias", pModal->ob);
+ PR_EEP("Chain0 DriverBias", pModal->db);
+ PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
+ PR_EEP("2chain pwr decrease", pModal->pwrDecreaseFor2Chain);
+ PR_EEP("3chain pwr decrease", pModal->pwrDecreaseFor3Chain);
+ PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
+ PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
+ PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
+ PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
+ PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]);
+ PR_EEP("Chain2 bswAtten", pModal->bswAtten[2]);
+ PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
+ PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]);
+ PR_EEP("Chain2 bswMargin", pModal->bswMargin[2]);
+ PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
+ PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]);
+ PR_EEP("Chain1 xatten2Db", pModal->xatten2Db[1]);
+ PR_EEP("Chain2 xatten2Db", pModal->xatten2Db[2]);
+ PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]);
+ PR_EEP("Chain1 xatten2Margin", pModal->xatten2Margin[1]);
+ PR_EEP("Chain2 xatten2Margin", pModal->xatten2Margin[2]);
+ PR_EEP("Chain1 OutputBias", pModal->ob_ch1);
+ PR_EEP("Chain1 DriverBias", pModal->db_ch1);
+ PR_EEP("LNA Control", pModal->lna_ctl);
+ PR_EEP("XPA Bias Freq0", pModal->xpaBiasLvlFreq[0]);
+ PR_EEP("XPA Bias Freq1", pModal->xpaBiasLvlFreq[1]);
+ PR_EEP("XPA Bias Freq2", pModal->xpaBiasLvlFreq[2]);
+
+ if (len > size)
+ len = size;
+
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return retval;
+
+#undef PR_EEP
+}
+
+static ssize_t read_9287_modal_eeprom(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+#define PR_EEP(_s, _val) \
+ do { \
+ len += snprintf(buf + len, size - len, "%20s : %10d\n", \
+ _s, (_val)); \
+ } while (0)
+
+ struct ath9k_htc_priv *priv = file->private_data;
+ struct modal_eep_ar9287_header *pModal = &priv->ah->eeprom.map9287.modalHeader;
+ unsigned int len = 0, size = 3000;
+ ssize_t retval = 0;
+ char *buf;
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
+ PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]);
+ PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
+ PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
+ PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]);
+ PR_EEP("Switch Settle", pModal->switchSettling);
+ PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
+ PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]);
+ PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
+ PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]);
+ PR_EEP("ADC Desired size", pModal->adcDesiredSize);
+ PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
+ PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
+ PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
+ PR_EEP("CCA Threshold)", pModal->thresh62);
+ PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
+ PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]);
+ PR_EEP("xpdGain", pModal->xpdGain);
+ PR_EEP("External PD", pModal->xpd);
+ PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
+ PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]);
+ PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
+ PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]);
+ PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
+ PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
+ PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
+ PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
+ PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
+ PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
+ PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]);
+ PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
+ PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]);
+ PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
+ PR_EEP("AR92x7 Version", pModal->version);
+ PR_EEP("DriverBias1", pModal->db1);
+ PR_EEP("DriverBias2", pModal->db1);
+ PR_EEP("CCK OutputBias", pModal->ob_cck);
+ PR_EEP("PSK OutputBias", pModal->ob_psk);
+ PR_EEP("QAM OutputBias", pModal->ob_qam);
+ PR_EEP("PAL_OFF OutputBias", pModal->ob_pal_off);
+
+ if (len > size)
+ len = size;
+
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return retval;
+
+#undef PR_EEP
+}
+
+static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath9k_htc_priv *priv = file->private_data;
+
+ if (AR_SREV_9271(priv->ah))
+ return read_4k_modal_eeprom(file, user_buf, count, ppos);
+ else if (priv->ah->hw_version.usbdev == AR9280_USB)
+ return read_def_modal_eeprom(file, user_buf, count, ppos);
+ else if (priv->ah->hw_version.usbdev == AR9287_USB)
+ return read_9287_modal_eeprom(file, user_buf, count, ppos);
+
+ return 0;
+}
+
+static const struct file_operations fops_modal_eeprom = {
+ .read = read_file_modal_eeprom,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+int ath9k_htc_init_debug(struct ath_hw *ah)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+
+ priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME,
+ priv->hw->wiphy->debugfsdir);
+ if (!priv->debug.debugfs_phy)
+ return -ENOMEM;
+
+ debugfs_create_file("tgt_int_stats", S_IRUSR, priv->debug.debugfs_phy,
+ priv, &fops_tgt_int_stats);
+ debugfs_create_file("tgt_tx_stats", S_IRUSR, priv->debug.debugfs_phy,
+ priv, &fops_tgt_tx_stats);
+ debugfs_create_file("tgt_rx_stats", S_IRUSR, priv->debug.debugfs_phy,
+ priv, &fops_tgt_rx_stats);
+ debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy,
+ priv, &fops_xmit);
+ debugfs_create_file("recv", S_IRUSR, priv->debug.debugfs_phy,
+ priv, &fops_recv);
+ debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy,
+ priv, &fops_slot);
+ debugfs_create_file("queue", S_IRUSR, priv->debug.debugfs_phy,
+ priv, &fops_queue);
+ debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy,
+ priv, &fops_debug);
+ debugfs_create_file("base_eeprom", S_IRUSR, priv->debug.debugfs_phy,
+ priv, &fops_base_eeprom);
+ debugfs_create_file("modal_eeprom", S_IRUSR, priv->debug.debugfs_phy,
+ priv, &fops_modal_eeprom);
+
+ return 0;
+}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
index 7e630a81b45..af57fe5aab9 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -65,17 +65,19 @@ static void ath_btcoex_period_work(struct work_struct *work)
u32 timer_period;
bool is_btscan;
int ret;
- u8 cmd_rsp, aggr;
ath_detect_bt_priority(priv);
is_btscan = !!(priv->op_flags & OP_BT_SCAN);
- aggr = priv->op_flags & OP_BT_PRIORITY_DETECTED;
-
- WMI_CMD_BUF(WMI_AGGR_LIMIT_CMD, &aggr);
+ ret = ath9k_htc_update_cap_target(priv,
+ !!(priv->op_flags & OP_BT_PRIORITY_DETECTED));
+ if (ret) {
+ ath_err(common, "Unable to set BTCOEX parameters\n");
+ return;
+ }
- ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL :
+ ath9k_hw_btcoex_bt_stomp(priv->ah, is_btscan ? ATH_BTCOEX_STOMP_ALL :
btcoex->bt_stomp_type);
timer_period = is_btscan ? btcoex->btscan_no_stomp :
@@ -103,9 +105,9 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work)
"time slice work for bt and wlan\n");
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
- ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE);
+ ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
- ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW);
+ ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW);
}
void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv)
@@ -152,140 +154,41 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv)
/* LED */
/*******/
-static void ath9k_led_blink_work(struct work_struct *work)
+#ifdef CONFIG_MAC80211_LEDS
+void ath9k_led_work(struct work_struct *work)
{
- struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
- ath9k_led_blink_work.work);
+ struct ath9k_htc_priv *priv = container_of(work,
+ struct ath9k_htc_priv,
+ led_work);
- if (!(priv->op_flags & OP_LED_ASSOCIATED))
- return;
-
- if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
- (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
- ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
- else
- ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
- (priv->op_flags & OP_LED_ON) ? 1 : 0);
-
- ieee80211_queue_delayed_work(priv->hw,
- &priv->ath9k_led_blink_work,
- (priv->op_flags & OP_LED_ON) ?
- msecs_to_jiffies(priv->led_off_duration) :
- msecs_to_jiffies(priv->led_on_duration));
-
- priv->led_on_duration = priv->led_on_cnt ?
- max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
- ATH_LED_ON_DURATION_IDLE;
- priv->led_off_duration = priv->led_off_cnt ?
- max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
- ATH_LED_OFF_DURATION_IDLE;
- priv->led_on_cnt = priv->led_off_cnt = 0;
-
- if (priv->op_flags & OP_LED_ON)
- priv->op_flags &= ~OP_LED_ON;
- else
- priv->op_flags |= OP_LED_ON;
-}
-
-static void ath9k_led_brightness_work(struct work_struct *work)
-{
- struct ath_led *led = container_of(work, struct ath_led,
- brightness_work.work);
- struct ath9k_htc_priv *priv = led->priv;
-
- switch (led->brightness) {
- case LED_OFF:
- if (led->led_type == ATH_LED_ASSOC ||
- led->led_type == ATH_LED_RADIO) {
- ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
- (led->led_type == ATH_LED_RADIO));
- priv->op_flags &= ~OP_LED_ASSOCIATED;
- if (led->led_type == ATH_LED_RADIO)
- priv->op_flags &= ~OP_LED_ON;
- } else {
- priv->led_off_cnt++;
- }
- break;
- case LED_FULL:
- if (led->led_type == ATH_LED_ASSOC) {
- priv->op_flags |= OP_LED_ASSOCIATED;
- ieee80211_queue_delayed_work(priv->hw,
- &priv->ath9k_led_blink_work, 0);
- } else if (led->led_type == ATH_LED_RADIO) {
- ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
- priv->op_flags |= OP_LED_ON;
- } else {
- priv->led_on_cnt++;
- }
- break;
- default:
- break;
- }
+ ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
+ (priv->brightness == LED_OFF));
}
static void ath9k_led_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
- struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
- struct ath9k_htc_priv *priv = led->priv;
-
- led->brightness = brightness;
- if (!(priv->op_flags & OP_LED_DEINIT))
- ieee80211_queue_delayed_work(priv->hw,
- &led->brightness_work, 0);
-}
-
-void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
-{
- cancel_delayed_work_sync(&priv->radio_led.brightness_work);
- cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
- cancel_delayed_work_sync(&priv->tx_led.brightness_work);
- cancel_delayed_work_sync(&priv->rx_led.brightness_work);
-}
-
-static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
- char *trigger)
-{
- int ret;
-
- led->priv = priv;
- led->led_cdev.name = led->name;
- led->led_cdev.default_trigger = trigger;
- led->led_cdev.brightness_set = ath9k_led_brightness;
+ struct ath9k_htc_priv *priv = container_of(led_cdev,
+ struct ath9k_htc_priv,
+ led_cdev);
- ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
- if (ret)
- ath_err(ath9k_hw_common(priv->ah),
- "Failed to register led:%s", led->name);
- else
- led->registered = 1;
-
- INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
-
- return ret;
-}
-
-static void ath9k_unregister_led(struct ath_led *led)
-{
- if (led->registered) {
- led_classdev_unregister(&led->led_cdev);
- led->registered = 0;
- }
+ /* Not locked, but it's just a tiny green light..*/
+ priv->brightness = brightness;
+ ieee80211_queue_work(priv->hw, &priv->led_work);
}
void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
{
- priv->op_flags |= OP_LED_DEINIT;
- ath9k_unregister_led(&priv->assoc_led);
- priv->op_flags &= ~OP_LED_ASSOCIATED;
- ath9k_unregister_led(&priv->tx_led);
- ath9k_unregister_led(&priv->rx_led);
- ath9k_unregister_led(&priv->radio_led);
+ if (!priv->led_registered)
+ return;
+
+ ath9k_led_brightness(&priv->led_cdev, LED_OFF);
+ led_classdev_unregister(&priv->led_cdev);
+ cancel_work_sync(&priv->led_work);
}
void ath9k_init_leds(struct ath9k_htc_priv *priv)
{
- char *trigger;
int ret;
if (AR_SREV_9287(priv->ah))
@@ -303,48 +206,21 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv)
/* LED off, active low */
ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
- INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
-
- trigger = ieee80211_get_radio_led_name(priv->hw);
- snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
- "ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
- ret = ath9k_register_led(priv, &priv->radio_led, trigger);
- priv->radio_led.led_type = ATH_LED_RADIO;
- if (ret)
- goto fail;
-
- trigger = ieee80211_get_assoc_led_name(priv->hw);
- snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
- "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
- ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
- priv->assoc_led.led_type = ATH_LED_ASSOC;
- if (ret)
- goto fail;
-
- trigger = ieee80211_get_tx_led_name(priv->hw);
- snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
- "ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
- ret = ath9k_register_led(priv, &priv->tx_led, trigger);
- priv->tx_led.led_type = ATH_LED_TX;
- if (ret)
- goto fail;
-
- trigger = ieee80211_get_rx_led_name(priv->hw);
- snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
- "ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
- ret = ath9k_register_led(priv, &priv->rx_led, trigger);
- priv->rx_led.led_type = ATH_LED_RX;
- if (ret)
- goto fail;
-
- priv->op_flags &= ~OP_LED_DEINIT;
+ snprintf(priv->led_name, sizeof(priv->led_name),
+ "ath9k_htc-%s", wiphy_name(priv->hw->wiphy));
+ priv->led_cdev.name = priv->led_name;
+ priv->led_cdev.brightness_set = ath9k_led_brightness;
- return;
+ ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &priv->led_cdev);
+ if (ret < 0)
+ return;
+
+ INIT_WORK(&priv->led_work, ath9k_led_work);
+ priv->led_registered = true;
-fail:
- cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
- ath9k_deinit_leds(priv);
+ return;
}
+#endif
/*******************/
/* Rfkill */
@@ -398,9 +274,9 @@ void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
/* Start TX */
htc_start(priv->htc);
- spin_lock_bh(&priv->tx_lock);
- priv->tx_queues_stop = false;
- spin_unlock_bh(&priv->tx_lock);
+ spin_lock_bh(&priv->tx.tx_lock);
+ priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
+ spin_unlock_bh(&priv->tx.tx_lock);
ieee80211_wake_queues(hw);
WMI_CMD(WMI_ENABLE_INTR_CMDID);
@@ -429,13 +305,15 @@ void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
/* Stop TX */
ieee80211_stop_queues(hw);
- htc_stop(priv->htc);
+ ath9k_htc_tx_drain(priv);
WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
- skb_queue_purge(&priv->tx_queue);
/* Stop RX */
WMI_CMD(WMI_STOP_RECV_CMDID);
+ /* Clear the WMI event queue */
+ ath9k_wmi_event_drain(priv);
+
/*
* The MIB counters have to be disabled here,
* since the target doesn't do it.
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index fc67c937e17..bfdc8a88718 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -117,6 +117,21 @@ static struct ieee80211_rate ath9k_legacy_rates[] = {
RATE(540, 0x0c, 0),
};
+#ifdef CONFIG_MAC80211_LEDS
+static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = {
+ { .throughput = 0 * 1024, .blink_time = 334 },
+ { .throughput = 1 * 1024, .blink_time = 260 },
+ { .throughput = 5 * 1024, .blink_time = 220 },
+ { .throughput = 10 * 1024, .blink_time = 190 },
+ { .throughput = 20 * 1024, .blink_time = 170 },
+ { .throughput = 50 * 1024, .blink_time = 150 },
+ { .throughput = 70 * 1024, .blink_time = 130 },
+ { .throughput = 100 * 1024, .blink_time = 110 },
+ { .throughput = 200 * 1024, .blink_time = 80 },
+ { .throughput = 300 * 1024, .blink_time = 50 },
+};
+#endif
+
static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
{
int time_left;
@@ -140,7 +155,6 @@ static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
static void ath9k_deinit_priv(struct ath9k_htc_priv *priv)
{
- ath9k_htc_exit_debug(priv->ah);
ath9k_hw_deinit(priv->ah);
kfree(priv->ah);
priv->ah = NULL;
@@ -244,7 +258,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid,
*/
if (IS_AR7010_DEVICE(drv_info))
- priv->htc->credits = 45;
+ priv->htc->credits = 48;
else
priv->htc->credits = 33;
@@ -430,13 +444,16 @@ static void ath9k_regwrite_flush(void *hw_priv)
mutex_unlock(&priv->wmi->multi_write_mutex);
}
-static const struct ath_ops ath9k_common_ops = {
- .read = ath9k_regread,
- .multi_read = ath9k_multi_regread,
- .write = ath9k_regwrite,
- .enable_write_buffer = ath9k_enable_regwrite_buffer,
- .write_flush = ath9k_regwrite_flush,
-};
+static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
+{
+ u32 val;
+
+ val = ath9k_regread(hw_priv, reg_offset);
+ val &= ~clr;
+ val |= set;
+ ath9k_regwrite(hw_priv, val, reg_offset);
+ return val;
+}
static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
{
@@ -561,13 +578,7 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
int i = 0;
/* Get the hardware key cache size. */
- common->keymax = priv->ah->caps.keycache_size;
- if (common->keymax > ATH_KEYMAX) {
- ath_dbg(common, ATH_DBG_ANY,
- "Warning, using only %u entries in %u key cache\n",
- ATH_KEYMAX, common->keymax);
- common->keymax = ATH_KEYMAX;
- }
+ common->keymax = AR_KEYTABLE_SIZE;
if (priv->ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
@@ -646,7 +657,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
{
struct ath_hw *ah = NULL;
struct ath_common *common;
- int ret = 0, csz = 0;
+ int i, ret = 0, csz = 0;
priv->op_flags |= OP_INVALID;
@@ -658,30 +669,35 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
ah->hw_version.subsysid = 0; /* FIXME */
ah->hw_version.usbdev = drv_info;
ah->ah_flags |= AH_USE_EEPROM;
+ ah->reg_ops.read = ath9k_regread;
+ ah->reg_ops.multi_read = ath9k_multi_regread;
+ ah->reg_ops.write = ath9k_regwrite;
+ ah->reg_ops.enable_write_buffer = ath9k_enable_regwrite_buffer;
+ ah->reg_ops.write_flush = ath9k_regwrite_flush;
+ ah->reg_ops.rmw = ath9k_reg_rmw;
priv->ah = ah;
common = ath9k_hw_common(ah);
- common->ops = &ath9k_common_ops;
+ common->ops = &ah->reg_ops;
common->bus_ops = &ath9k_usb_bus_ops;
common->ah = ah;
common->hw = priv->hw;
common->priv = priv;
common->debug_mask = ath9k_debug;
- spin_lock_init(&priv->wmi->wmi_lock);
spin_lock_init(&priv->beacon_lock);
- spin_lock_init(&priv->tx_lock);
+ spin_lock_init(&priv->tx.tx_lock);
mutex_init(&priv->mutex);
mutex_init(&priv->htc_pm_lock);
- tasklet_init(&priv->swba_tasklet, ath9k_swba_tasklet,
- (unsigned long)priv);
tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet,
(unsigned long)priv);
- tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet,
+ tasklet_init(&priv->tx_failed_tasklet, ath9k_tx_failed_tasklet,
(unsigned long)priv);
INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work);
INIT_WORK(&priv->ps_work, ath9k_ps_work);
INIT_WORK(&priv->fatal_work, ath9k_fatal_work);
+ setup_timer(&priv->tx.cleanup_timer, ath9k_htc_tx_cleanup_timer,
+ (unsigned long)priv);
/*
* Cache line size is used to size and align various
@@ -698,16 +714,13 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
goto err_hw;
}
- ret = ath9k_htc_init_debug(ah);
- if (ret) {
- ath_err(common, "Unable to create debugfs files\n");
- goto err_debug;
- }
-
ret = ath9k_init_queues(priv);
if (ret)
goto err_queues;
+ for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++)
+ priv->cur_beacon_conf.bslot[i] = NULL;
+
ath9k_init_crypto(priv);
ath9k_init_channels_rates(priv);
ath9k_init_misc(priv);
@@ -720,8 +733,6 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
return 0;
err_queues:
- ath9k_htc_exit_debug(ah);
-err_debug:
ath9k_hw_deinit(ah);
err_hw:
@@ -742,17 +753,27 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
IEEE80211_HW_HAS_RATE_CONTROL |
IEEE80211_HW_RX_INCLUDES_FCS |
IEEE80211_HW_SUPPORTS_PS |
- IEEE80211_HW_PS_NULLFUNC_STACK;
+ IEEE80211_HW_PS_NULLFUNC_STACK |
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC);
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_P2P_GO) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT);
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
hw->queues = 4;
hw->channel_change_time = 5000;
hw->max_listen_interval = 10;
+
+ if (AR_SREV_9271(priv->ah))
+ hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_9271;
+ else
+ hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_7010;
+
hw->vif_data_size = sizeof(struct ath9k_htc_vif);
hw->sta_data_size = sizeof(struct ath9k_htc_sta);
@@ -779,6 +800,43 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
}
+static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
+{
+ struct ieee80211_hw *hw = priv->hw;
+ struct wmi_fw_version cmd_rsp;
+ int ret;
+
+ memset(&cmd_rsp, 0, sizeof(cmd_rsp));
+
+ WMI_CMD(WMI_GET_FW_VERSION);
+ if (ret)
+ return -EINVAL;
+
+ priv->fw_version_major = be16_to_cpu(cmd_rsp.major);
+ priv->fw_version_minor = be16_to_cpu(cmd_rsp.minor);
+
+ snprintf(hw->wiphy->fw_version, ETHTOOL_BUSINFO_LEN, "%d.%d",
+ priv->fw_version_major,
+ priv->fw_version_minor);
+
+ dev_info(priv->dev, "ath9k_htc: FW Version: %d.%d\n",
+ priv->fw_version_major,
+ priv->fw_version_minor);
+
+ /*
+ * Check if the available FW matches the driver's
+ * required version.
+ */
+ if (priv->fw_version_major != MAJOR_VERSION_REQ ||
+ priv->fw_version_minor != MINOR_VERSION_REQ) {
+ dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n",
+ MAJOR_VERSION_REQ, MINOR_VERSION_REQ);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int ath9k_init_device(struct ath9k_htc_priv *priv,
u16 devid, char *product, u32 drv_info)
{
@@ -798,6 +856,10 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
common = ath9k_hw_common(ah);
ath9k_set_hw_capab(priv, hw);
+ error = ath9k_init_firmware_version(priv);
+ if (error != 0)
+ goto err_fw;
+
/* Initialize regulatory */
error = ath_regd_init(&common->regulatory, priv->hw->wiphy,
ath9k_reg_notifier);
@@ -816,6 +878,13 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
if (error != 0)
goto err_rx;
+#ifdef CONFIG_MAC80211_LEDS
+ /* must be initialized before ieee80211_register_hw */
+ priv->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(priv->hw,
+ IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_htc_tpt_blink,
+ ARRAY_SIZE(ath9k_htc_tpt_blink));
+#endif
+
/* Register with mac80211 */
error = ieee80211_register_hw(hw);
if (error)
@@ -828,6 +897,12 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
goto err_world;
}
+ error = ath9k_htc_init_debug(priv->ah);
+ if (error) {
+ ath_err(common, "Unable to create debugfs files\n");
+ goto err_world;
+ }
+
ath_dbg(common, ATH_DBG_CONFIG,
"WMI:%d, BCN:%d, CAB:%d, UAPSD:%d, MGMT:%d, "
"BE:%d, BK:%d, VI:%d, VO:%d\n",
@@ -858,6 +933,8 @@ err_rx:
err_tx:
/* Nothing */
err_regd:
+ /* Nothing */
+err_fw:
ath9k_deinit_priv(priv);
err_init:
return error;
@@ -946,38 +1023,20 @@ int ath9k_htc_resume(struct htc_target *htc_handle)
static int __init ath9k_htc_init(void)
{
- int error;
-
- error = ath9k_htc_debug_create_root();
- if (error < 0) {
- printk(KERN_ERR
- "ath9k_htc: Unable to create debugfs root: %d\n",
- error);
- goto err_dbg;
- }
-
- error = ath9k_hif_usb_init();
- if (error < 0) {
+ if (ath9k_hif_usb_init() < 0) {
printk(KERN_ERR
"ath9k_htc: No USB devices found,"
" driver not installed.\n");
- error = -ENODEV;
- goto err_usb;
+ return -ENODEV;
}
return 0;
-
-err_usb:
- ath9k_htc_debug_remove_root();
-err_dbg:
- return error;
}
module_init(ath9k_htc_init);
static void __exit ath9k_htc_exit(void)
{
ath9k_hif_usb_exit();
- ath9k_htc_debug_remove_root();
printk(KERN_INFO "ath9k_htc: Driver unloaded\n");
}
module_exit(ath9k_htc_exit);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index db8c0c044e9..5aa104fe7ee 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -16,10 +16,6 @@
#include "htc.h"
-#ifdef CONFIG_ATH9K_HTC_DEBUGFS
-static struct dentry *ath9k_debugfs_root;
-#endif
-
/*************/
/* Utilities */
/*************/
@@ -197,11 +193,16 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
ath9k_htc_stop_ani(priv);
ieee80211_stop_queues(priv->hw);
- htc_stop(priv->htc);
+
+ del_timer_sync(&priv->tx.cleanup_timer);
+ ath9k_htc_tx_drain(priv);
+
WMI_CMD(WMI_DISABLE_INTR_CMDID);
WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
WMI_CMD(WMI_STOP_RECV_CMDID);
+ ath9k_wmi_event_drain(priv);
+
caldata = &priv->caldata;
ret = ath9k_hw_reset(ah, ah->curchan, caldata, false);
if (ret) {
@@ -225,6 +226,9 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
ath9k_htc_vif_reconfig(priv);
ieee80211_wake_queues(priv->hw);
+ mod_timer(&priv->tx.cleanup_timer,
+ jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
+
ath9k_htc_ps_restore(priv);
mutex_unlock(&priv->mutex);
}
@@ -250,11 +254,16 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
ath9k_htc_ps_wakeup(priv);
- htc_stop(priv->htc);
+
+ del_timer_sync(&priv->tx.cleanup_timer);
+ ath9k_htc_tx_drain(priv);
+
WMI_CMD(WMI_DISABLE_INTR_CMDID);
WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
WMI_CMD(WMI_STOP_RECV_CMDID);
+ ath9k_wmi_event_drain(priv);
+
ath_dbg(common, ATH_DBG_CONFIG,
"(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
priv->ah->curchan->channel,
@@ -263,6 +272,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
if (!fastcc)
caldata = &priv->caldata;
+
ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
if (ret) {
ath_err(common,
@@ -296,6 +306,9 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
ath9k_htc_vif_reconfig(priv);
+ mod_timer(&priv->tx.cleanup_timer,
+ jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
+
err:
ath9k_htc_ps_restore(priv);
return ret;
@@ -319,6 +332,11 @@ static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
hvif.index = priv->mon_vif_idx;
WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
+ if (ret) {
+ ath_err(common, "Unable to remove monitor interface at idx: %d\n",
+ priv->mon_vif_idx);
+ }
+
priv->nvifs--;
priv->vif_slot &= ~(1 << priv->mon_vif_idx);
}
@@ -349,7 +367,7 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
- hvif.opmode = cpu_to_be32(HTC_M_MONITOR);
+ hvif.opmode = HTC_M_MONITOR;
hvif.index = ffz(priv->vif_slot);
WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
@@ -382,7 +400,7 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
tsta.is_vif_sta = 1;
tsta.sta_index = sta_idx;
tsta.vif_index = hvif.index;
- tsta.maxampdu = 0xffff;
+ tsta.maxampdu = cpu_to_be16(0xffff);
WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
if (ret) {
@@ -449,6 +467,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
struct ath9k_htc_sta *ista;
int ret, sta_idx;
u8 cmd_rsp;
+ u16 maxampdu;
if (priv->nstations >= ATH9K_HTC_MAX_STA)
return -ENOBUFS;
@@ -463,9 +482,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
ista = (struct ath9k_htc_sta *) sta->drv_priv;
memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
- tsta.associd = common->curaid;
tsta.is_vif_sta = 0;
- tsta.valid = true;
ista->index = sta_idx;
} else {
memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
@@ -474,7 +491,15 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
tsta.sta_index = sta_idx;
tsta.vif_index = avp->index;
- tsta.maxampdu = 0xffff;
+
+ if (!sta) {
+ tsta.maxampdu = cpu_to_be16(0xffff);
+ } else {
+ maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
+ sta->ht_cap.ampdu_factor);
+ tsta.maxampdu = cpu_to_be16(maxampdu);
+ }
+
if (sta && sta->ht_cap.ht_supported)
tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
@@ -547,7 +572,8 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
return 0;
}
-int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
+int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
+ u8 enable_coex)
{
struct ath9k_htc_cap_target tcap;
int ret;
@@ -555,13 +581,9 @@ int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
- /* FIXME: Values are hardcoded */
- tcap.flags = 0x240c40;
- tcap.flags_ext = 0x80601000;
- tcap.ampdu_limit = 0xffff0000;
- tcap.ampdu_subframes = 20;
- tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask;
- tcap.protmode = 1;
+ tcap.ampdu_limit = cpu_to_be32(0xffff);
+ tcap.ampdu_subframes = priv->hw->max_tx_aggregation_subframes;
+ tcap.enable_coex = enable_coex;
tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
@@ -709,218 +731,13 @@ static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
(aggr.aggr_enable) ? "Starting" : "Stopping",
sta->addr, tid);
- spin_lock_bh(&priv->tx_lock);
+ spin_lock_bh(&priv->tx.tx_lock);
ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP;
- spin_unlock_bh(&priv->tx_lock);
+ spin_unlock_bh(&priv->tx.tx_lock);
return ret;
}
-/*********/
-/* DEBUG */
-/*********/
-
-#ifdef CONFIG_ATH9K_HTC_DEBUGFS
-
-static int ath9k_debugfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath9k_htc_priv *priv = file->private_data;
- struct ath9k_htc_target_stats cmd_rsp;
- char buf[512];
- unsigned int len = 0;
- int ret = 0;
-
- memset(&cmd_rsp, 0, sizeof(cmd_rsp));
-
- WMI_CMD(WMI_TGT_STATS_CMDID);
- if (ret)
- return -EINVAL;
-
-
- len += snprintf(buf + len, sizeof(buf) - len,
- "%19s : %10u\n", "TX Short Retries",
- be32_to_cpu(cmd_rsp.tx_shortretry));
- len += snprintf(buf + len, sizeof(buf) - len,
- "%19s : %10u\n", "TX Long Retries",
- be32_to_cpu(cmd_rsp.tx_longretry));
- len += snprintf(buf + len, sizeof(buf) - len,
- "%19s : %10u\n", "TX Xretries",
- be32_to_cpu(cmd_rsp.tx_xretries));
- len += snprintf(buf + len, sizeof(buf) - len,
- "%19s : %10u\n", "TX Unaggr. Xretries",
- be32_to_cpu(cmd_rsp.ht_txunaggr_xretry));
- len += snprintf(buf + len, sizeof(buf) - len,
- "%19s : %10u\n", "TX Xretries (HT)",
- be32_to_cpu(cmd_rsp.ht_tx_xretries));
- len += snprintf(buf + len, sizeof(buf) - len,
- "%19s : %10u\n", "TX Rate", priv->debug.txrate);
-
- if (len > sizeof(buf))
- len = sizeof(buf);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_tgt_stats = {
- .read = read_file_tgt_stats,
- .open = ath9k_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath9k_htc_priv *priv = file->private_data;
- char buf[512];
- unsigned int len = 0;
-
- len += snprintf(buf + len, sizeof(buf) - len,
- "%20s : %10u\n", "Buffers queued",
- priv->debug.tx_stats.buf_queued);
- len += snprintf(buf + len, sizeof(buf) - len,
- "%20s : %10u\n", "Buffers completed",
- priv->debug.tx_stats.buf_completed);
- len += snprintf(buf + len, sizeof(buf) - len,
- "%20s : %10u\n", "SKBs queued",
- priv->debug.tx_stats.skb_queued);
- len += snprintf(buf + len, sizeof(buf) - len,
- "%20s : %10u\n", "SKBs completed",
- priv->debug.tx_stats.skb_completed);
- len += snprintf(buf + len, sizeof(buf) - len,
- "%20s : %10u\n", "SKBs dropped",
- priv->debug.tx_stats.skb_dropped);
-
- len += snprintf(buf + len, sizeof(buf) - len,
- "%20s : %10u\n", "BE queued",
- priv->debug.tx_stats.queue_stats[WME_AC_BE]);
- len += snprintf(buf + len, sizeof(buf) - len,
- "%20s : %10u\n", "BK queued",
- priv->debug.tx_stats.queue_stats[WME_AC_BK]);
- len += snprintf(buf + len, sizeof(buf) - len,
- "%20s : %10u\n", "VI queued",
- priv->debug.tx_stats.queue_stats[WME_AC_VI]);
- len += snprintf(buf + len, sizeof(buf) - len,
- "%20s : %10u\n", "VO queued",
- priv->debug.tx_stats.queue_stats[WME_AC_VO]);
-
- if (len > sizeof(buf))
- len = sizeof(buf);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_xmit = {
- .read = read_file_xmit,
- .open = ath9k_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t read_file_recv(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath9k_htc_priv *priv = file->private_data;
- char buf[512];
- unsigned int len = 0;
-
- len += snprintf(buf + len, sizeof(buf) - len,
- "%20s : %10u\n", "SKBs allocated",
- priv->debug.rx_stats.skb_allocated);
- len += snprintf(buf + len, sizeof(buf) - len,
- "%20s : %10u\n", "SKBs completed",
- priv->debug.rx_stats.skb_completed);
- len += snprintf(buf + len, sizeof(buf) - len,
- "%20s : %10u\n", "SKBs Dropped",
- priv->debug.rx_stats.skb_dropped);
-
- if (len > sizeof(buf))
- len = sizeof(buf);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_recv = {
- .read = read_file_recv,
- .open = ath9k_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-int ath9k_htc_init_debug(struct ath_hw *ah)
-{
- struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
-
- if (!ath9k_debugfs_root)
- return -ENOENT;
-
- priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy),
- ath9k_debugfs_root);
- if (!priv->debug.debugfs_phy)
- goto err;
-
- priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR,
- priv->debug.debugfs_phy,
- priv, &fops_tgt_stats);
- if (!priv->debug.debugfs_tgt_stats)
- goto err;
-
-
- priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR,
- priv->debug.debugfs_phy,
- priv, &fops_xmit);
- if (!priv->debug.debugfs_xmit)
- goto err;
-
- priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR,
- priv->debug.debugfs_phy,
- priv, &fops_recv);
- if (!priv->debug.debugfs_recv)
- goto err;
-
- return 0;
-
-err:
- ath9k_htc_exit_debug(ah);
- return -ENOMEM;
-}
-
-void ath9k_htc_exit_debug(struct ath_hw *ah)
-{
- struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
-
- debugfs_remove(priv->debug.debugfs_recv);
- debugfs_remove(priv->debug.debugfs_xmit);
- debugfs_remove(priv->debug.debugfs_tgt_stats);
- debugfs_remove(priv->debug.debugfs_phy);
-}
-
-int ath9k_htc_debug_create_root(void)
-{
- ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
- if (!ath9k_debugfs_root)
- return -ENOENT;
-
- return 0;
-}
-
-void ath9k_htc_debug_remove_root(void)
-{
- debugfs_remove(ath9k_debugfs_root);
- ath9k_debugfs_root = NULL;
-}
-
-#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
-
/*******/
/* ANI */
/*******/
@@ -1040,7 +857,8 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr;
struct ath9k_htc_priv *priv = hw->priv;
- int padpos, padsize, ret;
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ int padpos, padsize, ret, slot;
hdr = (struct ieee80211_hdr *) skb->data;
@@ -1048,30 +866,32 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
padpos = ath9k_cmn_padpos(hdr->frame_control);
padsize = padpos & 3;
if (padsize && skb->len > padpos) {
- if (skb_headroom(skb) < padsize)
+ if (skb_headroom(skb) < padsize) {
+ ath_dbg(common, ATH_DBG_XMIT, "No room for padding\n");
goto fail_tx;
+ }
skb_push(skb, padsize);
memmove(skb->data, skb->data + padsize, padpos);
}
- ret = ath9k_htc_tx_start(priv, skb);
- if (ret != 0) {
- if (ret == -ENOMEM) {
- ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
- "Stopping TX queues\n");
- ieee80211_stop_queues(hw);
- spin_lock_bh(&priv->tx_lock);
- priv->tx_queues_stop = true;
- spin_unlock_bh(&priv->tx_lock);
- } else {
- ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
- "Tx failed\n");
- }
+ slot = ath9k_htc_tx_get_slot(priv);
+ if (slot < 0) {
+ ath_dbg(common, ATH_DBG_XMIT, "No free TX slot\n");
goto fail_tx;
}
+ ret = ath9k_htc_tx_start(priv, skb, slot, false);
+ if (ret != 0) {
+ ath_dbg(common, ATH_DBG_XMIT, "Tx failed\n");
+ goto clear_slot;
+ }
+
+ ath9k_htc_check_stop_queues(priv);
+
return;
+clear_slot:
+ ath9k_htc_tx_clear_slot(priv, slot);
fail_tx:
dev_kfree_skb_any(skb);
}
@@ -1122,7 +942,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
ath9k_host_rx_init(priv);
- ret = ath9k_htc_update_cap_target(priv);
+ ret = ath9k_htc_update_cap_target(priv, 0);
if (ret)
ath_dbg(common, ATH_DBG_CONFIG,
"Failed to update capability in target\n");
@@ -1130,12 +950,15 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
priv->op_flags &= ~OP_INVALID;
htc_start(priv->htc);
- spin_lock_bh(&priv->tx_lock);
- priv->tx_queues_stop = false;
- spin_unlock_bh(&priv->tx_lock);
+ spin_lock_bh(&priv->tx.tx_lock);
+ priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
+ spin_unlock_bh(&priv->tx.tx_lock);
ieee80211_wake_queues(hw);
+ mod_timer(&priv->tx.cleanup_timer,
+ jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
+
if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) {
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_LOW_WLAN_WGHT);
@@ -1152,7 +975,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
struct ath9k_htc_priv *priv = hw->priv;
struct ath_hw *ah = priv->ah;
struct ath_common *common = ath9k_hw_common(ah);
- int ret = 0;
+ int ret __attribute__ ((unused));
u8 cmd_rsp;
mutex_lock(&priv->mutex);
@@ -1164,25 +987,27 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
}
ath9k_htc_ps_wakeup(priv);
- htc_stop(priv->htc);
+
WMI_CMD(WMI_DISABLE_INTR_CMDID);
WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
WMI_CMD(WMI_STOP_RECV_CMDID);
- tasklet_kill(&priv->swba_tasklet);
tasklet_kill(&priv->rx_tasklet);
- tasklet_kill(&priv->tx_tasklet);
- skb_queue_purge(&priv->tx_queue);
+ del_timer_sync(&priv->tx.cleanup_timer);
+ ath9k_htc_tx_drain(priv);
+ ath9k_wmi_event_drain(priv);
mutex_unlock(&priv->mutex);
/* Cancel all the running timers/work .. */
cancel_work_sync(&priv->fatal_work);
cancel_work_sync(&priv->ps_work);
- cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
+
+#ifdef CONFIG_MAC80211_LEDS
+ cancel_work_sync(&priv->led_work);
+#endif
ath9k_htc_stop_ani(priv);
- ath9k_led_stop_brightness(priv);
mutex_lock(&priv->mutex);
@@ -1245,13 +1070,13 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
switch (vif->type) {
case NL80211_IFTYPE_STATION:
- hvif.opmode = cpu_to_be32(HTC_M_STA);
+ hvif.opmode = HTC_M_STA;
break;
case NL80211_IFTYPE_ADHOC:
- hvif.opmode = cpu_to_be32(HTC_M_IBSS);
+ hvif.opmode = HTC_M_IBSS;
break;
case NL80211_IFTYPE_AP:
- hvif.opmode = cpu_to_be32(HTC_M_HOSTAP);
+ hvif.opmode = HTC_M_HOSTAP;
break;
default:
ath_err(common,
@@ -1281,14 +1106,20 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
priv->vif_slot |= (1 << avp->index);
priv->nvifs++;
- priv->vif = vif;
INC_VIF(priv, vif->type);
+
+ if ((vif->type == NL80211_IFTYPE_AP) ||
+ (vif->type == NL80211_IFTYPE_ADHOC))
+ ath9k_htc_assign_bslot(priv, vif);
+
ath9k_htc_set_opmode(priv);
if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
- !(priv->op_flags & OP_ANI_RUNNING))
+ !(priv->op_flags & OP_ANI_RUNNING)) {
+ ath9k_hw_set_tsfadjust(priv->ah, 1);
ath9k_htc_start_ani(priv);
+ }
ath_dbg(common, ATH_DBG_CONFIG,
"Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index);
@@ -1317,13 +1148,21 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
hvif.index = avp->index;
WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
+ if (ret) {
+ ath_err(common, "Unable to remove interface at idx: %d\n",
+ avp->index);
+ }
priv->nvifs--;
priv->vif_slot &= ~(1 << avp->index);
ath9k_htc_remove_station(priv, vif, NULL);
- priv->vif = NULL;
DEC_VIF(priv, vif->type);
+
+ if ((vif->type == NL80211_IFTYPE_AP) ||
+ (vif->type == NL80211_IFTYPE_ADHOC))
+ ath9k_htc_remove_bslot(priv, vif);
+
ath9k_htc_set_opmode(priv);
/*
@@ -1493,10 +1332,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
struct ieee80211_sta *sta)
{
struct ath9k_htc_priv *priv = hw->priv;
+ struct ath9k_htc_sta *ista;
int ret;
mutex_lock(&priv->mutex);
ath9k_htc_ps_wakeup(priv);
+ ista = (struct ath9k_htc_sta *) sta->drv_priv;
+ htc_sta_drain(priv->htc, ista->index);
ret = ath9k_htc_remove_station(priv, vif, sta);
ath9k_htc_ps_restore(priv);
mutex_unlock(&priv->mutex);
@@ -1644,6 +1486,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) {
ath_dbg(common, ATH_DBG_CONFIG,
"Beacon enabled for BSS: %pM\n", bss_conf->bssid);
+ ath9k_htc_set_tsfadjust(priv, vif);
priv->op_flags |= OP_ENABLE_BEACON;
ath9k_htc_beacon_config(priv, vif);
}
@@ -1741,6 +1584,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
int ret = 0;
mutex_lock(&priv->mutex);
+ ath9k_htc_ps_wakeup(priv);
switch (action) {
case IEEE80211_AMPDU_RX_START:
@@ -1758,14 +1602,15 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
break;
case IEEE80211_AMPDU_TX_OPERATIONAL:
ista = (struct ath9k_htc_sta *) sta->drv_priv;
- spin_lock_bh(&priv->tx_lock);
+ spin_lock_bh(&priv->tx.tx_lock);
ista->tid_state[tid] = AGGR_OPERATIONAL;
- spin_unlock_bh(&priv->tx_lock);
+ spin_unlock_bh(&priv->tx.tx_lock);
break;
default:
ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
}
+ ath9k_htc_ps_restore(priv);
mutex_unlock(&priv->mutex);
return ret;
@@ -1816,6 +1661,55 @@ static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
mutex_unlock(&priv->mutex);
}
+/*
+ * Currently, this is used only for selecting the minimum rate
+ * for management frames, rate selection for data frames remain
+ * unaffected.
+ */
+static int ath9k_htc_set_bitrate_mask(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ const struct cfg80211_bitrate_mask *mask)
+{
+ struct ath9k_htc_priv *priv = hw->priv;
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct ath9k_htc_target_rate_mask tmask;
+ struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
+ int ret = 0;
+ u8 cmd_rsp;
+
+ memset(&tmask, 0, sizeof(struct ath9k_htc_target_rate_mask));
+
+ tmask.vif_index = avp->index;
+ tmask.band = IEEE80211_BAND_2GHZ;
+ tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_2GHZ].legacy);
+
+ WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
+ if (ret) {
+ ath_err(common,
+ "Unable to set 2G rate mask for "
+ "interface at idx: %d\n", avp->index);
+ goto out;
+ }
+
+ tmask.band = IEEE80211_BAND_5GHZ;
+ tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_5GHZ].legacy);
+
+ WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
+ if (ret) {
+ ath_err(common,
+ "Unable to set 5G rate mask for "
+ "interface at idx: %d\n", avp->index);
+ goto out;
+ }
+
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Set bitrate masks: 0x%x, 0x%x\n",
+ mask->control[IEEE80211_BAND_2GHZ].legacy,
+ mask->control[IEEE80211_BAND_5GHZ].legacy);
+out:
+ return ret;
+}
+
struct ieee80211_ops ath9k_htc_ops = {
.tx = ath9k_htc_tx,
.start = ath9k_htc_start,
@@ -1838,4 +1732,5 @@ struct ieee80211_ops ath9k_htc_ops = {
.set_rts_threshold = ath9k_htc_set_rts_threshold,
.rfkill_poll = ath9k_htc_rfkill_poll_state,
.set_coverage_class = ath9k_htc_set_coverage_class,
+ .set_bitrate_mask = ath9k_htc_set_bitrate_mask,
};
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 4a4f27ba96a..a898dac2233 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -53,6 +53,138 @@ int get_hw_qnum(u16 queue, int *hwq_map)
}
}
+void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv)
+{
+ spin_lock_bh(&priv->tx.tx_lock);
+ priv->tx.queued_cnt++;
+ if ((priv->tx.queued_cnt >= ATH9K_HTC_TX_THRESHOLD) &&
+ !(priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) {
+ priv->tx.flags |= ATH9K_HTC_OP_TX_QUEUES_STOP;
+ ieee80211_stop_queues(priv->hw);
+ }
+ spin_unlock_bh(&priv->tx.tx_lock);
+}
+
+void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv)
+{
+ spin_lock_bh(&priv->tx.tx_lock);
+ if ((priv->tx.queued_cnt < ATH9K_HTC_TX_THRESHOLD) &&
+ (priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) {
+ priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
+ ieee80211_wake_queues(priv->hw);
+ }
+ spin_unlock_bh(&priv->tx.tx_lock);
+}
+
+int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv)
+{
+ int slot;
+
+ spin_lock_bh(&priv->tx.tx_lock);
+ slot = find_first_zero_bit(priv->tx.tx_slot, MAX_TX_BUF_NUM);
+ if (slot >= MAX_TX_BUF_NUM) {
+ spin_unlock_bh(&priv->tx.tx_lock);
+ return -ENOBUFS;
+ }
+ __set_bit(slot, priv->tx.tx_slot);
+ spin_unlock_bh(&priv->tx.tx_lock);
+
+ return slot;
+}
+
+void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot)
+{
+ spin_lock_bh(&priv->tx.tx_lock);
+ __clear_bit(slot, priv->tx.tx_slot);
+ spin_unlock_bh(&priv->tx.tx_lock);
+}
+
+static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv,
+ u16 qnum)
+{
+ enum htc_endpoint_id epid;
+
+ switch (qnum) {
+ case 0:
+ TX_QSTAT_INC(WME_AC_VO);
+ epid = priv->data_vo_ep;
+ break;
+ case 1:
+ TX_QSTAT_INC(WME_AC_VI);
+ epid = priv->data_vi_ep;
+ break;
+ case 2:
+ TX_QSTAT_INC(WME_AC_BE);
+ epid = priv->data_be_ep;
+ break;
+ case 3:
+ default:
+ TX_QSTAT_INC(WME_AC_BK);
+ epid = priv->data_bk_ep;
+ break;
+ }
+
+ return epid;
+}
+
+static inline struct sk_buff_head*
+get_htc_epid_queue(struct ath9k_htc_priv *priv, u8 epid)
+{
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct sk_buff_head *epid_queue = NULL;
+
+ if (epid == priv->mgmt_ep)
+ epid_queue = &priv->tx.mgmt_ep_queue;
+ else if (epid == priv->cab_ep)
+ epid_queue = &priv->tx.cab_ep_queue;
+ else if (epid == priv->data_be_ep)
+ epid_queue = &priv->tx.data_be_queue;
+ else if (epid == priv->data_bk_ep)
+ epid_queue = &priv->tx.data_bk_queue;
+ else if (epid == priv->data_vi_ep)
+ epid_queue = &priv->tx.data_vi_queue;
+ else if (epid == priv->data_vo_ep)
+ epid_queue = &priv->tx.data_vo_queue;
+ else
+ ath_err(common, "Invalid EPID: %d\n", epid);
+
+ return epid_queue;
+}
+
+/*
+ * Removes the driver header and returns the TX slot number
+ */
+static inline int strip_drv_header(struct ath9k_htc_priv *priv,
+ struct sk_buff *skb)
+{
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct ath9k_htc_tx_ctl *tx_ctl;
+ int slot;
+
+ tx_ctl = HTC_SKB_CB(skb);
+
+ if (tx_ctl->epid == priv->mgmt_ep) {
+ struct tx_mgmt_hdr *tx_mhdr =
+ (struct tx_mgmt_hdr *)skb->data;
+ slot = tx_mhdr->cookie;
+ skb_pull(skb, sizeof(struct tx_mgmt_hdr));
+ } else if ((tx_ctl->epid == priv->data_bk_ep) ||
+ (tx_ctl->epid == priv->data_be_ep) ||
+ (tx_ctl->epid == priv->data_vi_ep) ||
+ (tx_ctl->epid == priv->data_vo_ep) ||
+ (tx_ctl->epid == priv->cab_ep)) {
+ struct tx_frame_hdr *tx_fhdr =
+ (struct tx_frame_hdr *)skb->data;
+ slot = tx_fhdr->cookie;
+ skb_pull(skb, sizeof(struct tx_frame_hdr));
+ } else {
+ ath_err(common, "Unsupported EPID: %d\n", tx_ctl->epid);
+ slot = -EINVAL;
+ }
+
+ return slot;
+}
+
int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
struct ath9k_tx_queue_info *qinfo)
{
@@ -79,23 +211,140 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
return error;
}
-int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
+static void ath9k_htc_tx_mgmt(struct ath9k_htc_priv *priv,
+ struct ath9k_htc_vif *avp,
+ struct sk_buff *skb,
+ u8 sta_idx, u8 vif_idx, u8 slot)
+{
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_mgmt *mgmt;
+ struct ieee80211_hdr *hdr;
+ struct tx_mgmt_hdr mgmt_hdr;
+ struct ath9k_htc_tx_ctl *tx_ctl;
+ u8 *tx_fhdr;
+
+ tx_ctl = HTC_SKB_CB(skb);
+ hdr = (struct ieee80211_hdr *) skb->data;
+
+ memset(tx_ctl, 0, sizeof(*tx_ctl));
+ memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr));
+
+ /*
+ * Set the TSF adjust value for probe response
+ * frame also.
+ */
+ if (avp && unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
+ mgmt = (struct ieee80211_mgmt *)skb->data;
+ mgmt->u.probe_resp.timestamp = avp->tsfadjust;
+ }
+
+ tx_ctl->type = ATH9K_HTC_MGMT;
+
+ mgmt_hdr.node_idx = sta_idx;
+ mgmt_hdr.vif_idx = vif_idx;
+ mgmt_hdr.tidno = 0;
+ mgmt_hdr.flags = 0;
+ mgmt_hdr.cookie = slot;
+
+ mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
+ if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
+ mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
+ else
+ mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
+
+ tx_fhdr = skb_push(skb, sizeof(mgmt_hdr));
+ memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr));
+ tx_ctl->epid = priv->mgmt_ep;
+}
+
+static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv,
+ struct ieee80211_vif *vif,
+ struct sk_buff *skb,
+ u8 sta_idx, u8 vif_idx, u8 slot,
+ bool is_cab)
+{
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr;
+ struct ath9k_htc_tx_ctl *tx_ctl;
+ struct tx_frame_hdr tx_hdr;
+ u32 flags = 0;
+ u8 *qc, *tx_fhdr;
+ u16 qnum;
+
+ tx_ctl = HTC_SKB_CB(skb);
+ hdr = (struct ieee80211_hdr *) skb->data;
+
+ memset(tx_ctl, 0, sizeof(*tx_ctl));
+ memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
+
+ tx_hdr.node_idx = sta_idx;
+ tx_hdr.vif_idx = vif_idx;
+ tx_hdr.cookie = slot;
+
+ /*
+ * This is a bit redundant but it helps to get
+ * the per-packet index quickly when draining the
+ * TX queue in the HIF layer. Otherwise we would
+ * have to parse the packet contents ...
+ */
+ tx_ctl->sta_idx = sta_idx;
+
+ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+ tx_ctl->type = ATH9K_HTC_AMPDU;
+ tx_hdr.data_type = ATH9K_HTC_AMPDU;
+ } else {
+ tx_ctl->type = ATH9K_HTC_NORMAL;
+ tx_hdr.data_type = ATH9K_HTC_NORMAL;
+ }
+
+ if (ieee80211_is_data_qos(hdr->frame_control)) {
+ qc = ieee80211_get_qos_ctl(hdr);
+ tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
+ }
+
+ /* Check for RTS protection */
+ if (priv->hw->wiphy->rts_threshold != (u32) -1)
+ if (skb->len > priv->hw->wiphy->rts_threshold)
+ flags |= ATH9K_HTC_TX_RTSCTS;
+
+ /* CTS-to-self */
+ if (!(flags & ATH9K_HTC_TX_RTSCTS) &&
+ (vif && vif->bss_conf.use_cts_prot))
+ flags |= ATH9K_HTC_TX_CTSONLY;
+
+ tx_hdr.flags = cpu_to_be32(flags);
+ tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
+ if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
+ tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
+ else
+ tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
+
+ tx_fhdr = skb_push(skb, sizeof(tx_hdr));
+ memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
+
+ if (is_cab) {
+ CAB_STAT_INC;
+ tx_ctl->epid = priv->cab_ep;
+ return;
+ }
+
+ qnum = skb_get_queue_mapping(skb);
+ tx_ctl->epid = get_htc_epid(priv, qnum);
+}
+
+int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
+ struct sk_buff *skb,
+ u8 slot, bool is_cab)
{
struct ieee80211_hdr *hdr;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_sta *sta = tx_info->control.sta;
struct ieee80211_vif *vif = tx_info->control.vif;
struct ath9k_htc_sta *ista;
- struct ath9k_htc_vif *avp;
- struct ath9k_htc_tx_ctl tx_ctl;
- enum htc_endpoint_id epid;
- u16 qnum;
- __le16 fc;
- u8 *tx_fhdr;
+ struct ath9k_htc_vif *avp = NULL;
u8 sta_idx, vif_idx;
hdr = (struct ieee80211_hdr *) skb->data;
- fc = hdr->frame_control;
/*
* Find out on which interface this packet has to be
@@ -124,218 +373,430 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
sta_idx = priv->vif_sta_pos[vif_idx];
}
- memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
+ if (ieee80211_is_data(hdr->frame_control))
+ ath9k_htc_tx_data(priv, vif, skb,
+ sta_idx, vif_idx, slot, is_cab);
+ else
+ ath9k_htc_tx_mgmt(priv, avp, skb,
+ sta_idx, vif_idx, slot);
- if (ieee80211_is_data(fc)) {
- struct tx_frame_hdr tx_hdr;
- u32 flags = 0;
- u8 *qc;
- memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
+ return htc_send(priv->htc, skb);
+}
- tx_hdr.node_idx = sta_idx;
- tx_hdr.vif_idx = vif_idx;
+static inline bool __ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
+ struct ath9k_htc_sta *ista, u8 tid)
+{
+ bool ret = false;
- if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
- tx_ctl.type = ATH9K_HTC_AMPDU;
- tx_hdr.data_type = ATH9K_HTC_AMPDU;
- } else {
- tx_ctl.type = ATH9K_HTC_NORMAL;
- tx_hdr.data_type = ATH9K_HTC_NORMAL;
- }
+ spin_lock_bh(&priv->tx.tx_lock);
+ if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP))
+ ret = true;
+ spin_unlock_bh(&priv->tx.tx_lock);
+
+ return ret;
+}
+
+static void ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
+ struct ieee80211_vif *vif,
+ struct sk_buff *skb)
+{
+ struct ieee80211_sta *sta;
+ struct ieee80211_hdr *hdr;
+ __le16 fc;
+
+ hdr = (struct ieee80211_hdr *) skb->data;
+ fc = hdr->frame_control;
+
+ rcu_read_lock();
+
+ sta = ieee80211_find_sta(vif, hdr->addr1);
+ if (!sta) {
+ rcu_read_unlock();
+ return;
+ }
+ if (sta && conf_is_ht(&priv->hw->conf) &&
+ !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
if (ieee80211_is_data_qos(fc)) {
+ u8 *qc, tid;
+ struct ath9k_htc_sta *ista;
+
qc = ieee80211_get_qos_ctl(hdr);
- tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
+ tid = qc[0] & 0xf;
+ ista = (struct ath9k_htc_sta *)sta->drv_priv;
+ if (__ath9k_htc_check_tx_aggr(priv, ista, tid)) {
+ ieee80211_start_tx_ba_session(sta, tid, 0);
+ spin_lock_bh(&priv->tx.tx_lock);
+ ista->tid_state[tid] = AGGR_PROGRESS;
+ spin_unlock_bh(&priv->tx.tx_lock);
+ }
}
+ }
- /* Check for RTS protection */
- if (priv->hw->wiphy->rts_threshold != (u32) -1)
- if (skb->len > priv->hw->wiphy->rts_threshold)
- flags |= ATH9K_HTC_TX_RTSCTS;
+ rcu_read_unlock();
+}
- /* CTS-to-self */
- if (!(flags & ATH9K_HTC_TX_RTSCTS) &&
- (vif && vif->bss_conf.use_cts_prot))
- flags |= ATH9K_HTC_TX_CTSONLY;
+static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
+ struct sk_buff *skb,
+ struct __wmi_event_txstatus *txs)
+{
+ struct ieee80211_vif *vif;
+ struct ath9k_htc_tx_ctl *tx_ctl;
+ struct ieee80211_tx_info *tx_info;
+ struct ieee80211_tx_rate *rate;
+ struct ieee80211_conf *cur_conf = &priv->hw->conf;
+ bool txok;
+ int slot;
- tx_hdr.flags = cpu_to_be32(flags);
- tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
- if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
- tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
- else
- tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
+ slot = strip_drv_header(priv, skb);
+ if (slot < 0) {
+ dev_kfree_skb_any(skb);
+ return;
+ }
- tx_fhdr = skb_push(skb, sizeof(tx_hdr));
- memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
+ tx_ctl = HTC_SKB_CB(skb);
+ txok = tx_ctl->txok;
+ tx_info = IEEE80211_SKB_CB(skb);
+ vif = tx_info->control.vif;
+ rate = &tx_info->status.rates[0];
- qnum = skb_get_queue_mapping(skb);
+ memset(&tx_info->status, 0, sizeof(tx_info->status));
- switch (qnum) {
- case 0:
- TX_QSTAT_INC(WME_AC_VO);
- epid = priv->data_vo_ep;
- break;
- case 1:
- TX_QSTAT_INC(WME_AC_VI);
- epid = priv->data_vi_ep;
- break;
- case 2:
- TX_QSTAT_INC(WME_AC_BE);
- epid = priv->data_be_ep;
- break;
- case 3:
- default:
- TX_QSTAT_INC(WME_AC_BK);
- epid = priv->data_bk_ep;
- break;
- }
- } else {
- struct tx_mgmt_hdr mgmt_hdr;
+ /*
+ * URB submission failed for this frame, it never reached
+ * the target.
+ */
+ if (!txok || !vif || !txs)
+ goto send_mac80211;
+
+ if (txs->ts_flags & ATH9K_HTC_TXSTAT_ACK)
+ tx_info->flags |= IEEE80211_TX_STAT_ACK;
- memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr));
+ if (txs->ts_flags & ATH9K_HTC_TXSTAT_FILT)
+ tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
- tx_ctl.type = ATH9K_HTC_NORMAL;
+ if (txs->ts_flags & ATH9K_HTC_TXSTAT_RTC_CTS)
+ rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
- mgmt_hdr.node_idx = sta_idx;
- mgmt_hdr.vif_idx = vif_idx;
- mgmt_hdr.tidno = 0;
- mgmt_hdr.flags = 0;
+ rate->count = 1;
+ rate->idx = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_RATE);
- mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
- if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
- mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
- else
- mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
+ if (txs->ts_flags & ATH9K_HTC_TXSTAT_MCS) {
+ rate->flags |= IEEE80211_TX_RC_MCS;
- tx_fhdr = skb_push(skb, sizeof(mgmt_hdr));
- memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr));
- epid = priv->mgmt_ep;
+ if (txs->ts_flags & ATH9K_HTC_TXSTAT_CW40)
+ rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+ if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI)
+ rate->flags |= IEEE80211_TX_RC_SHORT_GI;
+ } else {
+ if (cur_conf->channel->band == IEEE80211_BAND_5GHZ)
+ rate->idx += 4; /* No CCK rates */
}
- return htc_send(priv->htc, skb, epid, &tx_ctl);
+ ath9k_htc_check_tx_aggr(priv, vif, skb);
+
+send_mac80211:
+ spin_lock_bh(&priv->tx.tx_lock);
+ if (WARN_ON(--priv->tx.queued_cnt < 0))
+ priv->tx.queued_cnt = 0;
+ spin_unlock_bh(&priv->tx.tx_lock);
+
+ ath9k_htc_tx_clear_slot(priv, slot);
+
+ /* Send status to mac80211 */
+ ieee80211_tx_status(priv->hw, skb);
}
-static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
- struct ath9k_htc_sta *ista, u8 tid)
+static inline void ath9k_htc_tx_drainq(struct ath9k_htc_priv *priv,
+ struct sk_buff_head *queue)
{
- bool ret = false;
+ struct sk_buff *skb;
- spin_lock_bh(&priv->tx_lock);
- if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP))
- ret = true;
- spin_unlock_bh(&priv->tx_lock);
+ while ((skb = skb_dequeue(queue)) != NULL) {
+ ath9k_htc_tx_process(priv, skb, NULL);
+ }
+}
- return ret;
+void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv)
+{
+ struct ath9k_htc_tx_event *event, *tmp;
+
+ spin_lock_bh(&priv->tx.tx_lock);
+ priv->tx.flags |= ATH9K_HTC_OP_TX_DRAIN;
+ spin_unlock_bh(&priv->tx.tx_lock);
+
+ /*
+ * Ensure that all pending TX frames are flushed,
+ * and that the TX completion/failed tasklets is killed.
+ */
+ htc_stop(priv->htc);
+ tasklet_kill(&priv->wmi->wmi_event_tasklet);
+ tasklet_kill(&priv->tx_failed_tasklet);
+
+ ath9k_htc_tx_drainq(priv, &priv->tx.mgmt_ep_queue);
+ ath9k_htc_tx_drainq(priv, &priv->tx.cab_ep_queue);
+ ath9k_htc_tx_drainq(priv, &priv->tx.data_be_queue);
+ ath9k_htc_tx_drainq(priv, &priv->tx.data_bk_queue);
+ ath9k_htc_tx_drainq(priv, &priv->tx.data_vi_queue);
+ ath9k_htc_tx_drainq(priv, &priv->tx.data_vo_queue);
+ ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed);
+
+ /*
+ * The TX cleanup timer has already been killed.
+ */
+ spin_lock_bh(&priv->wmi->event_lock);
+ list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) {
+ list_del(&event->list);
+ kfree(event);
+ }
+ spin_unlock_bh(&priv->wmi->event_lock);
+
+ spin_lock_bh(&priv->tx.tx_lock);
+ priv->tx.flags &= ~ATH9K_HTC_OP_TX_DRAIN;
+ spin_unlock_bh(&priv->tx.tx_lock);
}
-void ath9k_tx_tasklet(unsigned long data)
+void ath9k_tx_failed_tasklet(unsigned long data)
{
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
- struct ieee80211_vif *vif;
- struct ieee80211_sta *sta;
- struct ieee80211_hdr *hdr;
- struct ieee80211_tx_info *tx_info;
- struct sk_buff *skb = NULL;
- __le16 fc;
- while ((skb = skb_dequeue(&priv->tx_queue)) != NULL) {
+ spin_lock_bh(&priv->tx.tx_lock);
+ if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) {
+ spin_unlock_bh(&priv->tx.tx_lock);
+ return;
+ }
+ spin_unlock_bh(&priv->tx.tx_lock);
- hdr = (struct ieee80211_hdr *) skb->data;
- fc = hdr->frame_control;
- tx_info = IEEE80211_SKB_CB(skb);
- vif = tx_info->control.vif;
+ ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed);
+}
- memset(&tx_info->status, 0, sizeof(tx_info->status));
+static inline bool check_cookie(struct ath9k_htc_priv *priv,
+ struct sk_buff *skb,
+ u8 cookie, u8 epid)
+{
+ u8 fcookie = 0;
+
+ if (epid == priv->mgmt_ep) {
+ struct tx_mgmt_hdr *hdr;
+ hdr = (struct tx_mgmt_hdr *) skb->data;
+ fcookie = hdr->cookie;
+ } else if ((epid == priv->data_bk_ep) ||
+ (epid == priv->data_be_ep) ||
+ (epid == priv->data_vi_ep) ||
+ (epid == priv->data_vo_ep) ||
+ (epid == priv->cab_ep)) {
+ struct tx_frame_hdr *hdr;
+ hdr = (struct tx_frame_hdr *) skb->data;
+ fcookie = hdr->cookie;
+ }
- if (!vif)
- goto send_mac80211;
+ if (fcookie == cookie)
+ return true;
- rcu_read_lock();
+ return false;
+}
- sta = ieee80211_find_sta(vif, hdr->addr1);
- if (!sta) {
- rcu_read_unlock();
- ieee80211_tx_status(priv->hw, skb);
- continue;
+static struct sk_buff* ath9k_htc_tx_get_packet(struct ath9k_htc_priv *priv,
+ struct __wmi_event_txstatus *txs)
+{
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct sk_buff_head *epid_queue;
+ struct sk_buff *skb, *tmp;
+ unsigned long flags;
+ u8 epid = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_EPID);
+
+ epid_queue = get_htc_epid_queue(priv, epid);
+ if (!epid_queue)
+ return NULL;
+
+ spin_lock_irqsave(&epid_queue->lock, flags);
+ skb_queue_walk_safe(epid_queue, skb, tmp) {
+ if (check_cookie(priv, skb, txs->cookie, epid)) {
+ __skb_unlink(skb, epid_queue);
+ spin_unlock_irqrestore(&epid_queue->lock, flags);
+ return skb;
}
+ }
+ spin_unlock_irqrestore(&epid_queue->lock, flags);
+
+ ath_dbg(common, ATH_DBG_XMIT,
+ "No matching packet for cookie: %d, epid: %d\n",
+ txs->cookie, epid);
- /* Check if we need to start aggregation */
+ return NULL;
+}
- if (sta && conf_is_ht(&priv->hw->conf) &&
- !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
- if (ieee80211_is_data_qos(fc)) {
- u8 *qc, tid;
- struct ath9k_htc_sta *ista;
+void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event)
+{
+ struct wmi_event_txstatus *txs = (struct wmi_event_txstatus *)wmi_event;
+ struct __wmi_event_txstatus *__txs;
+ struct sk_buff *skb;
+ struct ath9k_htc_tx_event *tx_pend;
+ int i;
- qc = ieee80211_get_qos_ctl(hdr);
- tid = qc[0] & 0xf;
- ista = (struct ath9k_htc_sta *)sta->drv_priv;
+ for (i = 0; i < txs->cnt; i++) {
+ WARN_ON(txs->cnt > HTC_MAX_TX_STATUS);
- if (ath9k_htc_check_tx_aggr(priv, ista, tid)) {
- ieee80211_start_tx_ba_session(sta, tid, 0);
- spin_lock_bh(&priv->tx_lock);
- ista->tid_state[tid] = AGGR_PROGRESS;
- spin_unlock_bh(&priv->tx_lock);
- }
- }
- }
+ __txs = &txs->txstatus[i];
- rcu_read_unlock();
+ skb = ath9k_htc_tx_get_packet(priv, __txs);
+ if (!skb) {
+ /*
+ * Store this event, so that the TX cleanup
+ * routine can check later for the needed packet.
+ */
+ tx_pend = kzalloc(sizeof(struct ath9k_htc_tx_event),
+ GFP_ATOMIC);
+ if (!tx_pend)
+ continue;
+
+ memcpy(&tx_pend->txs, __txs,
+ sizeof(struct __wmi_event_txstatus));
+
+ spin_lock(&priv->wmi->event_lock);
+ list_add_tail(&tx_pend->list,
+ &priv->wmi->pending_tx_events);
+ spin_unlock(&priv->wmi->event_lock);
- send_mac80211:
- /* Send status to mac80211 */
- ieee80211_tx_status(priv->hw, skb);
+ continue;
+ }
+
+ ath9k_htc_tx_process(priv, skb, __txs);
}
/* Wake TX queues if needed */
- spin_lock_bh(&priv->tx_lock);
- if (priv->tx_queues_stop) {
- priv->tx_queues_stop = false;
- spin_unlock_bh(&priv->tx_lock);
- ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
- "Waking up TX queues\n");
- ieee80211_wake_queues(priv->hw);
- return;
- }
- spin_unlock_bh(&priv->tx_lock);
+ ath9k_htc_check_wake_queues(priv);
}
void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb,
enum htc_endpoint_id ep_id, bool txok)
{
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv;
- struct ath_common *common = ath9k_hw_common(priv->ah);
- struct ieee80211_tx_info *tx_info;
+ struct ath9k_htc_tx_ctl *tx_ctl;
+ struct sk_buff_head *epid_queue;
- if (!skb)
+ tx_ctl = HTC_SKB_CB(skb);
+ tx_ctl->txok = txok;
+ tx_ctl->timestamp = jiffies;
+
+ if (!txok) {
+ skb_queue_tail(&priv->tx.tx_failed, skb);
+ tasklet_schedule(&priv->tx_failed_tasklet);
return;
+ }
- if (ep_id == priv->mgmt_ep) {
- skb_pull(skb, sizeof(struct tx_mgmt_hdr));
- } else if ((ep_id == priv->data_bk_ep) ||
- (ep_id == priv->data_be_ep) ||
- (ep_id == priv->data_vi_ep) ||
- (ep_id == priv->data_vo_ep)) {
- skb_pull(skb, sizeof(struct tx_frame_hdr));
- } else {
- ath_err(common, "Unsupported TX EPID: %d\n", ep_id);
+ epid_queue = get_htc_epid_queue(priv, ep_id);
+ if (!epid_queue) {
dev_kfree_skb_any(skb);
return;
}
- tx_info = IEEE80211_SKB_CB(skb);
+ skb_queue_tail(epid_queue, skb);
+}
- if (txok)
- tx_info->flags |= IEEE80211_TX_STAT_ACK;
+static inline bool check_packet(struct ath9k_htc_priv *priv, struct sk_buff *skb)
+{
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct ath9k_htc_tx_ctl *tx_ctl;
- skb_queue_tail(&priv->tx_queue, skb);
- tasklet_schedule(&priv->tx_tasklet);
+ tx_ctl = HTC_SKB_CB(skb);
+
+ if (time_after(jiffies,
+ tx_ctl->timestamp +
+ msecs_to_jiffies(ATH9K_HTC_TX_TIMEOUT_INTERVAL))) {
+ ath_dbg(common, ATH_DBG_XMIT,
+ "Dropping a packet due to TX timeout\n");
+ return true;
+ }
+
+ return false;
+}
+
+static void ath9k_htc_tx_cleanup_queue(struct ath9k_htc_priv *priv,
+ struct sk_buff_head *epid_queue)
+{
+ bool process = false;
+ unsigned long flags;
+ struct sk_buff *skb, *tmp;
+ struct sk_buff_head queue;
+
+ skb_queue_head_init(&queue);
+
+ spin_lock_irqsave(&epid_queue->lock, flags);
+ skb_queue_walk_safe(epid_queue, skb, tmp) {
+ if (check_packet(priv, skb)) {
+ __skb_unlink(skb, epid_queue);
+ __skb_queue_tail(&queue, skb);
+ process = true;
+ }
+ }
+ spin_unlock_irqrestore(&epid_queue->lock, flags);
+
+ if (process) {
+ skb_queue_walk_safe(&queue, skb, tmp) {
+ __skb_unlink(skb, &queue);
+ ath9k_htc_tx_process(priv, skb, NULL);
+ }
+ }
+}
+
+void ath9k_htc_tx_cleanup_timer(unsigned long data)
+{
+ struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) data;
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct ath9k_htc_tx_event *event, *tmp;
+ struct sk_buff *skb;
+
+ spin_lock(&priv->wmi->event_lock);
+ list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) {
+
+ skb = ath9k_htc_tx_get_packet(priv, &event->txs);
+ if (skb) {
+ ath_dbg(common, ATH_DBG_XMIT,
+ "Found packet for cookie: %d, epid: %d\n",
+ event->txs.cookie,
+ MS(event->txs.ts_rate, ATH9K_HTC_TXSTAT_EPID));
+
+ ath9k_htc_tx_process(priv, skb, &event->txs);
+ list_del(&event->list);
+ kfree(event);
+ continue;
+ }
+
+ if (++event->count >= ATH9K_HTC_TX_TIMEOUT_COUNT) {
+ list_del(&event->list);
+ kfree(event);
+ }
+ }
+ spin_unlock(&priv->wmi->event_lock);
+
+ /*
+ * Check if status-pending packets have to be cleaned up.
+ */
+ ath9k_htc_tx_cleanup_queue(priv, &priv->tx.mgmt_ep_queue);
+ ath9k_htc_tx_cleanup_queue(priv, &priv->tx.cab_ep_queue);
+ ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_be_queue);
+ ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_bk_queue);
+ ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vi_queue);
+ ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vo_queue);
+
+ /* Wake TX queues if needed */
+ ath9k_htc_check_wake_queues(priv);
+
+ mod_timer(&priv->tx.cleanup_timer,
+ jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
}
int ath9k_tx_init(struct ath9k_htc_priv *priv)
{
- skb_queue_head_init(&priv->tx_queue);
+ skb_queue_head_init(&priv->tx.mgmt_ep_queue);
+ skb_queue_head_init(&priv->tx.cab_ep_queue);
+ skb_queue_head_init(&priv->tx.data_be_queue);
+ skb_queue_head_init(&priv->tx.data_bk_queue);
+ skb_queue_head_init(&priv->tx.data_vi_queue);
+ skb_queue_head_init(&priv->tx.data_vo_queue);
+ skb_queue_head_init(&priv->tx.tx_failed);
return 0;
}
@@ -507,8 +968,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
int last_rssi = ATH_RSSI_DUMMY_MARKER;
__le16 fc;
- if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) {
- ath_err(common, "Corrupted RX frame, dropping\n");
+ if (skb->len < HTC_RX_FRAME_HEADER_SIZE) {
+ ath_err(common, "Corrupted RX frame, dropping (len: %d)\n",
+ skb->len);
goto rx_next;
}
@@ -522,6 +984,8 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
goto rx_next;
}
+ ath9k_htc_err_stat_rx(priv, rxstatus);
+
/* Get the RX status information */
memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE);
skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE);
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index 62e139a30a7..cee970fdf65 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -17,8 +17,8 @@
#include "htc.h"
static int htc_issue_send(struct htc_target *target, struct sk_buff* skb,
- u16 len, u8 flags, u8 epid,
- struct ath9k_htc_tx_ctl *tx_ctl)
+ u16 len, u8 flags, u8 epid)
+
{
struct htc_frame_hdr *hdr;
struct htc_endpoint *endpoint = &target->endpoint[epid];
@@ -30,8 +30,8 @@ static int htc_issue_send(struct htc_target *target, struct sk_buff* skb,
hdr->flags = flags;
hdr->payload_len = cpu_to_be16(len);
- status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb,
- tx_ctl);
+ status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb);
+
return status;
}
@@ -162,7 +162,7 @@ static int htc_config_pipe_credits(struct htc_target *target)
target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS;
- ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
+ ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
if (ret)
goto err;
@@ -197,7 +197,7 @@ static int htc_setup_complete(struct htc_target *target)
target->htc_flags |= HTC_OP_START_WAIT;
- ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
+ ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
if (ret)
goto err;
@@ -268,7 +268,7 @@ int htc_connect_service(struct htc_target *target,
conn_msg->dl_pipeid = endpoint->dl_pipeid;
conn_msg->ul_pipeid = endpoint->ul_pipeid;
- ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
+ ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
if (ret)
goto err;
@@ -286,35 +286,33 @@ err:
return ret;
}
-int htc_send(struct htc_target *target, struct sk_buff *skb,
- enum htc_endpoint_id epid, struct ath9k_htc_tx_ctl *tx_ctl)
+int htc_send(struct htc_target *target, struct sk_buff *skb)
{
- return htc_issue_send(target, skb, skb->len, 0, epid, tx_ctl);
+ struct ath9k_htc_tx_ctl *tx_ctl;
+
+ tx_ctl = HTC_SKB_CB(skb);
+ return htc_issue_send(target, skb, skb->len, 0, tx_ctl->epid);
}
-void htc_stop(struct htc_target *target)
+int htc_send_epid(struct htc_target *target, struct sk_buff *skb,
+ enum htc_endpoint_id epid)
{
- enum htc_endpoint_id epid;
- struct htc_endpoint *endpoint;
+ return htc_issue_send(target, skb, skb->len, 0, epid);
+}
- for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) {
- endpoint = &target->endpoint[epid];
- if (endpoint->service_id != 0)
- target->hif->stop(target->hif_dev, endpoint->ul_pipeid);
- }
+void htc_stop(struct htc_target *target)
+{
+ target->hif->stop(target->hif_dev);
}
void htc_start(struct htc_target *target)
{
- enum htc_endpoint_id epid;
- struct htc_endpoint *endpoint;
+ target->hif->start(target->hif_dev);
+}
- for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) {
- endpoint = &target->endpoint[epid];
- if (endpoint->service_id != 0)
- target->hif->start(target->hif_dev,
- endpoint->ul_pipeid);
- }
+void htc_sta_drain(struct htc_target *target, u8 idx)
+{
+ target->hif->sta_drain(target->hif_dev, idx);
}
void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h
index ecd018798c4..91a5305db95 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.h
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.h
@@ -33,10 +33,10 @@ struct ath9k_htc_hif {
u8 control_dl_pipe;
u8 control_ul_pipe;
- void (*start) (void *hif_handle, u8 pipe);
- void (*stop) (void *hif_handle, u8 pipe);
- int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf,
- struct ath9k_htc_tx_ctl *tx_ctl);
+ void (*start) (void *hif_handle);
+ void (*stop) (void *hif_handle);
+ void (*sta_drain) (void *hif_handle, u8 idx);
+ int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf);
};
enum htc_endpoint_id {
@@ -83,21 +83,10 @@ struct htc_ep_callbacks {
void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id);
};
-#define HTC_TX_QUEUE_SIZE 256
-
-struct htc_txq {
- struct sk_buff *buf[HTC_TX_QUEUE_SIZE];
- u32 txqdepth;
- u16 txbuf_cnt;
- u16 txq_head;
- u16 txq_tail;
-};
-
struct htc_endpoint {
u16 service_id;
struct htc_ep_callbacks ep_callbacks;
- struct htc_txq htc_txq;
u32 max_txqdepth;
int max_msglen;
@@ -205,10 +194,12 @@ int htc_init(struct htc_target *target);
int htc_connect_service(struct htc_target *target,
struct htc_service_connreq *service_connreq,
enum htc_endpoint_id *conn_rsp_eid);
-int htc_send(struct htc_target *target, struct sk_buff *skb,
- enum htc_endpoint_id eid, struct ath9k_htc_tx_ctl *tx_ctl);
+int htc_send(struct htc_target *target, struct sk_buff *skb);
+int htc_send_epid(struct htc_target *target, struct sk_buff *skb,
+ enum htc_endpoint_id epid);
void htc_stop(struct htc_target *target);
void htc_start(struct htc_target *target);
+void htc_sta_drain(struct htc_target *target, u8 idx);
void ath9k_htc_rx_msg(struct htc_target *htc_handle,
struct sk_buff *skb, u32 len, u8 pipe_id);
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index c8f254fe0f0..8b8f0445aef 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -116,16 +116,21 @@ static inline void ath9k_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
ath9k_hw_ops(ah)->clr11n_aggr(ah, ds);
}
-static inline void ath9k_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
- u32 burstDuration)
+static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val)
{
- ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration);
+ ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val);
}
-static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
- u32 vmf)
+static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf)
{
- ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf);
+ ath9k_hw_ops(ah)->antdiv_comb_conf_get(ah, antconf);
+}
+
+static inline void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf)
+{
+ ath9k_hw_ops(ah)->antdiv_comb_conf_set(ah, antconf);
}
/* Private hardware call ops */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index c95bc5cc1a1..b75b5dca4e2 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -130,6 +130,20 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
}
EXPORT_SYMBOL(ath9k_hw_wait);
+void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
+ int column, unsigned int *writecnt)
+{
+ int r;
+
+ ENABLE_REGWRITE_BUFFER(ah);
+ for (r = 0; r < array->ia_rows; r++) {
+ REG_WRITE(ah, INI_RA(array, r, 0),
+ INI_RA(array, r, column));
+ DO_DELAY(*writecnt);
+ }
+ REGWRITE_BUFFER_FLUSH(ah);
+}
+
u32 ath9k_hw_reverse_bits(u32 val, u32 n)
{
u32 retval;
@@ -142,25 +156,6 @@ u32 ath9k_hw_reverse_bits(u32 val, u32 n)
return retval;
}
-bool ath9k_get_channel_edges(struct ath_hw *ah,
- u16 flags, u16 *low,
- u16 *high)
-{
- struct ath9k_hw_capabilities *pCap = &ah->caps;
-
- if (flags & CHANNEL_5GHZ) {
- *low = pCap->low_5ghz_chan;
- *high = pCap->high_5ghz_chan;
- return true;
- }
- if ((flags & CHANNEL_2GHZ)) {
- *low = pCap->low_2ghz_chan;
- *high = pCap->high_2ghz_chan;
- return true;
- }
- return false;
-}
-
u16 ath9k_hw_computetxtime(struct ath_hw *ah,
u8 phy, int kbps,
u32 frameLen, u16 rateix,
@@ -252,6 +247,17 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
{
u32 val;
+ switch (ah->hw_version.devid) {
+ case AR5416_AR9100_DEVID:
+ ah->hw_version.macVersion = AR_SREV_VERSION_9100;
+ break;
+ case AR9300_DEVID_AR9340:
+ ah->hw_version.macVersion = AR_SREV_VERSION_9340;
+ val = REG_READ(ah, AR_SREV);
+ ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
+ return;
+ }
+
val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
if (val == 0xFF) {
@@ -364,11 +370,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
ah->config.spurchans[i][1] = AR_NO_SPUR;
}
- if (ah->hw_version.devid != AR2427_DEVID_PCIE)
- ah->config.ht_enable = 1;
- else
- ah->config.ht_enable = 0;
-
/* PAPRD needs some more work to be enabled */
ah->config.paprd_disable = 1;
@@ -410,6 +411,8 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
ah->sta_id1_defaults =
AR_STA_ID1_CRPT_MIC_ENABLE |
AR_STA_ID1_MCAST_KSRCH;
+ if (AR_SREV_9100(ah))
+ ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX;
ah->enable_32kHz_clock = DONT_USE_32KHZ;
ah->slottime = 20;
ah->globaltxtimeout = (u32) -1;
@@ -470,7 +473,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
return ecode;
}
- if (!AR_SREV_9100(ah)) {
+ if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) {
ath9k_hw_ani_setup(ah);
ath9k_hw_ani_init(ah);
}
@@ -492,9 +495,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah);
int r = 0;
- if (ah->hw_version.devid == AR5416_AR9100_DEVID)
- ah->hw_version.macVersion = AR_SREV_VERSION_9100;
-
ath9k_hw_read_revisions(ah);
/*
@@ -552,6 +552,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
case AR_SREV_VERSION_9271:
case AR_SREV_VERSION_9300:
case AR_SREV_VERSION_9485:
+ case AR_SREV_VERSION_9340:
break;
default:
ath_err(common,
@@ -560,7 +561,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
return -EOPNOTSUPP;
}
- if (AR_SREV_9271(ah) || AR_SREV_9100(ah))
+ if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah))
ah->is_pciexpress = false;
ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
@@ -629,6 +630,7 @@ int ath9k_hw_init(struct ath_hw *ah)
case AR2427_DEVID_PCIE:
case AR9300_DEVID_PCIE:
case AR9300_DEVID_AR9485_PCIE:
+ case AR9300_DEVID_AR9340:
break;
default:
if (common->bus_ops->ath_bus_type == ATH_USB)
@@ -671,48 +673,89 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
REGWRITE_BUFFER_FLUSH(ah);
}
-unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
+u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
{
- REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) & ~(PLL3_DO_MEAS_MASK)));
- udelay(100);
- REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) | PLL3_DO_MEAS_MASK));
+ REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
+ udelay(100);
+ REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
- while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0)
- udelay(100);
+ while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0)
+ udelay(100);
- return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3;
+ return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3;
}
EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc);
-#define DPLL2_KD_VAL 0x3D
-#define DPLL2_KI_VAL 0x06
-#define DPLL3_PHASE_SHIFT_VAL 0x1
-
static void ath9k_hw_init_pll(struct ath_hw *ah,
struct ath9k_channel *chan)
{
u32 pll;
if (AR_SREV_9485(ah)) {
- REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666);
- REG_WRITE(ah, AR_CH0_DDR_DPLL2, 0x19e82f01);
- REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3,
- AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
-
- REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
- udelay(1000);
+ /* program BB PLL ki and kd value, ki=0x4, kd=0x40 */
+ REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+ AR_CH0_BB_DPLL2_PLL_PWD, 0x1);
+ REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+ AR_CH0_DPLL2_KD, 0x40);
+ REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+ AR_CH0_DPLL2_KI, 0x4);
- REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666);
+ REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1,
+ AR_CH0_BB_DPLL1_REFDIV, 0x5);
+ REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1,
+ AR_CH0_BB_DPLL1_NINI, 0x58);
+ REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1,
+ AR_CH0_BB_DPLL1_NFRAC, 0x0);
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
- AR_CH0_DPLL2_KD, DPLL2_KD_VAL);
+ AR_CH0_BB_DPLL2_OUTDIV, 0x1);
+ REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+ AR_CH0_BB_DPLL2_LOCAL_PLL, 0x1);
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
- AR_CH0_DPLL2_KI, DPLL2_KI_VAL);
+ AR_CH0_BB_DPLL2_EN_NEGTRIG, 0x1);
+ /* program BB PLL phase_shift to 0x6 */
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
- AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
- REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c);
+ AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x6);
+
+ REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+ AR_CH0_BB_DPLL2_PLL_PWD, 0x0);
+ udelay(1000);
+ } else if (AR_SREV_9340(ah)) {
+ u32 regval, pll2_divint, pll2_divfrac, refdiv;
+
+ REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
+ udelay(1000);
+
+ REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16);
+ udelay(100);
+
+ if (ah->is_clk_25mhz) {
+ pll2_divint = 0x54;
+ pll2_divfrac = 0x1eb85;
+ refdiv = 3;
+ } else {
+ pll2_divint = 88;
+ pll2_divfrac = 0;
+ refdiv = 5;
+ }
+
+ regval = REG_READ(ah, AR_PHY_PLL_MODE);
+ regval |= (0x1 << 16);
+ REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
+ udelay(100);
+
+ REG_WRITE(ah, AR_PHY_PLL_CONTROL, (refdiv << 27) |
+ (pll2_divint << 18) | pll2_divfrac);
+ udelay(100);
+
+ regval = REG_READ(ah, AR_PHY_PLL_MODE);
+ regval = (regval & 0x80071fff) | (0x1 << 30) | (0x1 << 13) |
+ (0x4 << 26) | (0x18 << 19);
+ REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
+ REG_WRITE(ah, AR_PHY_PLL_MODE,
+ REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff);
udelay(1000);
}
@@ -720,6 +763,9 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
+ if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
+ udelay(1000);
+
/* Switch the core clock for ar9271 to 117Mhz */
if (AR_SREV_9271(ah)) {
udelay(500);
@@ -729,17 +775,34 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
udelay(RTC_PLL_SETTLE_DELAY);
REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
+
+ if (AR_SREV_9340(ah)) {
+ if (ah->is_clk_25mhz) {
+ REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
+ REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
+ REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
+ } else {
+ REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
+ REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
+ REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
+ }
+ udelay(100);
+ }
}
static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
enum nl80211_iftype opmode)
{
+ u32 sync_default = AR_INTR_SYNC_DEFAULT;
u32 imr_reg = AR_IMR_TXERR |
AR_IMR_TXURN |
AR_IMR_RXERR |
AR_IMR_RXORN |
AR_IMR_BCNMISC;
+ if (AR_SREV_9340(ah))
+ sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+
if (AR_SREV_9300_20_OR_LATER(ah)) {
imr_reg |= AR_IMR_RXOK_HP;
if (ah->config.rx_intr_mitigation)
@@ -770,7 +833,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
if (!AR_SREV_9100(ah)) {
REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
- REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
+ REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
}
@@ -830,8 +893,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
ah->misc_mode);
if (ah->misc_mode != 0)
- REG_WRITE(ah, AR_PCU_MISC,
- REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
+ REG_SET_BIT(ah, AR_PCU_MISC, ah->misc_mode);
if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ)
sifstime = 16;
@@ -899,23 +961,19 @@ u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan)
static inline void ath9k_hw_set_dma(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- u32 regval;
ENABLE_REGWRITE_BUFFER(ah);
/*
* set AHB_MODE not to do cacheline prefetches
*/
- if (!AR_SREV_9300_20_OR_LATER(ah)) {
- regval = REG_READ(ah, AR_AHB_MODE);
- REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
- }
+ if (!AR_SREV_9300_20_OR_LATER(ah))
+ REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN);
/*
* let mac dma reads be in 128 byte chunks
*/
- regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
- REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
+ REG_RMW(ah, AR_TXCFG, AR_TXCFG_DMASZ_128B, AR_TXCFG_DMASZ_MASK);
REGWRITE_BUFFER_FLUSH(ah);
@@ -932,8 +990,7 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
/*
* let mac dma writes be in 128 byte chunks
*/
- regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
- REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
+ REG_RMW(ah, AR_RXCFG, AR_RXCFG_DMASZ_128B, AR_RXCFG_DMASZ_MASK);
/*
* Setup receive FIFO threshold to hold off TX activities
@@ -972,30 +1029,27 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
{
- u32 val;
+ u32 mask = AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC;
+ u32 set = AR_STA_ID1_KSRCH_MODE;
- val = REG_READ(ah, AR_STA_ID1);
- val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
switch (opmode) {
- case NL80211_IFTYPE_AP:
- REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
- | AR_STA_ID1_KSRCH_MODE);
- REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
- break;
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
- REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
- | AR_STA_ID1_KSRCH_MODE);
+ set |= AR_STA_ID1_ADHOC;
REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
break;
+ case NL80211_IFTYPE_AP:
+ set |= AR_STA_ID1_STA_AP;
+ /* fall through */
case NL80211_IFTYPE_STATION:
- REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
+ REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
break;
default:
- if (ah->is_monitoring)
- REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
+ if (!ah->is_monitoring)
+ set = 0;
break;
}
+ REG_RMW(ah, AR_STA_ID1, set, mask);
}
void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
@@ -1021,10 +1075,8 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
u32 tmpReg;
if (AR_SREV_9100(ah)) {
- u32 val = REG_READ(ah, AR_RTC_DERIVED_CLK);
- val &= ~AR_RTC_DERIVED_CLK_PERIOD;
- val |= SM(1, AR_RTC_DERIVED_CLK_PERIOD);
- REG_WRITE(ah, AR_RTC_DERIVED_CLK, val);
+ REG_RMW_FIELD(ah, AR_RTC_DERIVED_CLK,
+ AR_RTC_DERIVED_CLK_PERIOD, 1);
(void)REG_READ(ah, AR_RTC_DERIVED_CLK);
}
@@ -1212,6 +1264,20 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
return true;
}
+static void ath9k_hw_apply_gpio_override(struct ath_hw *ah)
+{
+ u32 gpio_mask = ah->gpio_mask;
+ int i;
+
+ for (i = 0; gpio_mask; i++, gpio_mask >>= 1) {
+ if (!(gpio_mask & 1))
+ continue;
+
+ ath9k_hw_cfg_output(ah, i, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ ath9k_hw_set_gpio(ah, i, !!(ah->gpio_val & BIT(i)));
+ }
+}
+
bool ath9k_hw_check_alive(struct ath_hw *ah)
{
int count = 50;
@@ -1409,7 +1475,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REGWRITE_BUFFER_FLUSH(ah);
ah->intr_txqs = 0;
- for (i = 0; i < ah->caps.total_queues; i++)
+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
ath9k_hw_resettxqueue(ah, i);
ath9k_hw_init_interrupt_masks(ah, ah->opmode);
@@ -1426,8 +1492,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ar9002_hw_enable_wep_aggregation(ah);
}
- REG_WRITE(ah, AR_STA_ID1,
- REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
+ REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
ath9k_hw_set_dma(ah);
@@ -1480,7 +1545,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
}
#ifdef __BIG_ENDIAN
- else
+ else if (AR_SREV_9340(ah))
+ REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0);
+ else
REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
#endif
}
@@ -1491,6 +1558,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
if (AR_SREV_9300_20_OR_LATER(ah))
ar9003_hw_bb_watchdog_config(ah);
+ ath9k_hw_apply_gpio_override(ah);
+
return 0;
}
EXPORT_SYMBOL(ath9k_hw_reset);
@@ -1670,21 +1739,15 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
case NL80211_IFTYPE_MESH_POINT:
REG_SET_BIT(ah, AR_TXCFG,
AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
- REG_WRITE(ah, AR_NEXT_NDP_TIMER,
- TU_TO_USEC(next_beacon +
- (ah->atim_window ? ah->
- atim_window : 1)));
+ REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon +
+ TU_TO_USEC(ah->atim_window ? ah->atim_window : 1));
flags |= AR_NDP_TIMER_EN;
case NL80211_IFTYPE_AP:
- REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
- REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
- TU_TO_USEC(next_beacon -
- ah->config.
- dma_beacon_response_time));
- REG_WRITE(ah, AR_NEXT_SWBA,
- TU_TO_USEC(next_beacon -
- ah->config.
- sw_beacon_response_time));
+ REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon);
+ REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, next_beacon -
+ TU_TO_USEC(ah->config.dma_beacon_response_time));
+ REG_WRITE(ah, AR_NEXT_SWBA, next_beacon -
+ TU_TO_USEC(ah->config.sw_beacon_response_time));
flags |=
AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
break;
@@ -1696,18 +1759,13 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
break;
}
- REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
- REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
- REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
- REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
+ REG_WRITE(ah, AR_BEACON_PERIOD, beacon_period);
+ REG_WRITE(ah, AR_DMA_BEACON_PERIOD, beacon_period);
+ REG_WRITE(ah, AR_SWBA_PERIOD, beacon_period);
+ REG_WRITE(ah, AR_NDP_PERIOD, beacon_period);
REGWRITE_BUFFER_FLUSH(ah);
- beacon_period &= ~ATH9K_BEACON_ENA;
- if (beacon_period & ATH9K_BEACON_RESET_TSF) {
- ath9k_hw_reset_tsf(ah);
- }
-
REG_SET_BIT(ah, AR_TIMER_MODE, flags);
}
EXPORT_SYMBOL(ath9k_hw_beaconinit);
@@ -1795,7 +1853,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah);
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
- u16 capField = 0, eeval;
+ u16 eeval;
u8 ant_div_ctl1, tx_chainmask, rx_chainmask;
eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
@@ -1806,8 +1864,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
eeval |= AR9285_RDEXT_DEFAULT;
regulatory->current_rd_ext = eeval;
- capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
-
if (ah->opmode != NL80211_IFTYPE_AP &&
ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
if (regulatory->current_rd == 0x64 ||
@@ -1842,6 +1898,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
!(AR_SREV_9271(ah)))
/* CB71: GPIO 0 is pulled down to indicate 3 rx chains */
pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7;
+ else if (AR_SREV_9100(ah))
+ pCap->rx_chainmask = 0x7;
else
/* Use rx_chainmask from EEPROM. */
pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
@@ -1852,36 +1910,13 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
if (AR_SREV_9300_20_OR_LATER(ah))
ah->misc_mode |= AR_PCU_ALWAYS_PERFORM_KEYSEARCH;
- pCap->low_2ghz_chan = 2312;
- pCap->high_2ghz_chan = 2732;
-
- pCap->low_5ghz_chan = 4920;
- pCap->high_5ghz_chan = 6100;
-
common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM;
- if (ah->config.ht_enable)
+ if (ah->hw_version.devid != AR2427_DEVID_PCIE)
pCap->hw_caps |= ATH9K_HW_CAP_HT;
else
pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
- if (capField & AR_EEPROM_EEPCAP_MAXQCU)
- pCap->total_queues =
- MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
- else
- pCap->total_queues = ATH9K_NUM_TX_QUEUES;
-
- if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
- pCap->keycache_size =
- 1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
- else
- pCap->keycache_size = AR_KEYTABLE_SIZE;
-
- if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
- pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1;
- else
- pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
-
if (AR_SREV_9271(ah))
pCap->num_gpio_pins = AR9271_NUM_GPIO;
else if (AR_DEVID_7010(ah))
@@ -1900,8 +1935,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->rts_aggr_limit = (8 * 1024);
}
- pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
-
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT);
if (ah->rfsilent & EEP_RFSILENT_ENABLED) {
@@ -1923,32 +1956,23 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
else
pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
- if (regulatory->current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) {
- pCap->reg_cap =
- AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
- AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
- AR_EEPROM_EEREGCAP_EN_KK_U2 |
- AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
- } else {
- pCap->reg_cap =
- AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
- AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
- }
-
- /* Advertise midband for AR5416 with FCC midband set in eeprom */
- if (regulatory->current_rd_ext & (1 << REG_EXT_FCC_MIDBAND) &&
- AR_SREV_5416(ah))
- pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
-
- if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) {
- btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
- btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
-
- if (AR_SREV_9285(ah)) {
+ if (common->btcoex_enabled) {
+ if (AR_SREV_9300_20_OR_LATER(ah)) {
btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
- btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO;
- } else {
- btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
+ btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300;
+ btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300;
+ btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300;
+ } else if (AR_SREV_9280_20_OR_LATER(ah)) {
+ btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280;
+ btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280;
+
+ if (AR_SREV_9285(ah)) {
+ btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
+ btcoex_hw->btpriority_gpio =
+ ATH_BTPRIORITY_GPIO_9285;
+ } else {
+ btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
+ }
}
} else {
btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
@@ -1998,6 +2022,22 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
}
+ if (AR_SREV_9485(ah)) {
+ ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
+ /*
+ * enable the diversity-combining algorithm only when
+ * both enable_lna_div and enable_fast_div are set
+ * Table for Diversity
+ * ant_div_alt_lnaconf bit 0-1
+ * ant_div_main_lnaconf bit 2-3
+ * ant_div_alt_gaintb bit 4
+ * ant_div_main_gaintb bit 5
+ * enable_ant_div_lnadiv bit 6
+ * enable_ant_fast_div bit 7
+ */
+ if ((ant_div_ctl1 >> 0x6) == 0x3)
+ pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
+ }
if (AR_SREV_9485_10(ah)) {
pCap->pcie_lcr_extsync_en = true;
@@ -2186,11 +2226,9 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
REG_WRITE(ah, AR_PHY_ERR, phybits);
if (phybits)
- REG_WRITE(ah, AR_RXCFG,
- REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
+ REG_SET_BIT(ah, AR_RXCFG, AR_RXCFG_ZLFDMA);
else
- REG_WRITE(ah, AR_RXCFG,
- REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
+ REG_CLR_BIT(ah, AR_RXCFG, AR_RXCFG_ZLFDMA);
REGWRITE_BUFFER_FLUSH(ah);
}
@@ -2366,10 +2404,11 @@ static u32 rightmost_index(struct ath_gen_timer_table *timer_table, u32 *mask)
return timer_table->gen_timer_index[b];
}
-static u32 ath9k_hw_gettsf32(struct ath_hw *ah)
+u32 ath9k_hw_gettsf32(struct ath_hw *ah)
{
return REG_READ(ah, AR_TSF_L32);
}
+EXPORT_SYMBOL(ath9k_hw_gettsf32);
struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
void (*trigger)(void *),
@@ -2402,11 +2441,11 @@ EXPORT_SYMBOL(ath_gen_timer_alloc);
void ath9k_hw_gen_timer_start(struct ath_hw *ah,
struct ath_gen_timer *timer,
- u32 timer_next,
+ u32 trig_timeout,
u32 timer_period)
{
struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
- u32 tsf;
+ u32 tsf, timer_next;
BUG_ON(!timer_period);
@@ -2414,18 +2453,13 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah,
tsf = ath9k_hw_gettsf32(ah);
+ timer_next = tsf + trig_timeout;
+
ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER,
"current tsf %x period %x timer_next %x\n",
tsf, timer_period, timer_next);
/*
- * Pull timer_next forward if the current TSF already passed it
- * because of software latency
- */
- if (timer_next < tsf)
- timer_next = tsf + timer_period;
-
- /*
* Program generic timer registers
*/
REG_WRITE(ah, gen_tmr_configuration[timer->index].next_addr,
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 6650fd48415..7af2773d2bf 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -43,6 +43,7 @@
#define AR9287_DEVID_PCI 0x002d
#define AR9287_DEVID_PCIE 0x002e
#define AR9300_DEVID_PCIE 0x0030
+#define AR9300_DEVID_AR9340 0x0031
#define AR9300_DEVID_AR9485_PCIE 0x0032
#define AR5416_AR9100_DEVID 0x000b
@@ -55,6 +56,9 @@
#define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa
#define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab
+#define AR9300_NUM_BT_WEIGHTS 4
+#define AR9300_NUM_WLAN_WEIGHTS 4
+
#define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1)
#define ATH_DEFAULT_NOISE_FLOOR -95
@@ -65,53 +69,49 @@
/* Register read/write primitives */
#define REG_WRITE(_ah, _reg, _val) \
- ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg))
+ (_ah)->reg_ops.write((_ah), (_val), (_reg))
#define REG_READ(_ah, _reg) \
- ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
+ (_ah)->reg_ops.read((_ah), (_reg))
#define REG_READ_MULTI(_ah, _addr, _val, _cnt) \
- ath9k_hw_common(_ah)->ops->multi_read((_ah), (_addr), (_val), (_cnt))
+ (_ah)->reg_ops.multi_read((_ah), (_addr), (_val), (_cnt))
+
+#define REG_RMW(_ah, _reg, _set, _clr) \
+ (_ah)->reg_ops.rmw((_ah), (_reg), (_set), (_clr))
#define ENABLE_REGWRITE_BUFFER(_ah) \
do { \
- if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \
- ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \
+ if ((_ah)->reg_ops.enable_write_buffer) \
+ (_ah)->reg_ops.enable_write_buffer((_ah)); \
} while (0)
#define REGWRITE_BUFFER_FLUSH(_ah) \
do { \
- if (ath9k_hw_common(_ah)->ops->write_flush) \
- ath9k_hw_common(_ah)->ops->write_flush((_ah)); \
+ if ((_ah)->reg_ops.write_flush) \
+ (_ah)->reg_ops.write_flush((_ah)); \
} while (0)
#define SM(_v, _f) (((_v) << _f##_S) & _f)
#define MS(_v, _f) (((_v) & _f) >> _f##_S)
-#define REG_RMW(_a, _r, _set, _clr) \
- REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
#define REG_RMW_FIELD(_a, _r, _f, _v) \
- REG_WRITE(_a, _r, \
- (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
+ REG_RMW(_a, _r, (((_v) << _f##_S) & _f), (_f))
#define REG_READ_FIELD(_a, _r, _f) \
(((REG_READ(_a, _r) & _f) >> _f##_S))
#define REG_SET_BIT(_a, _r, _f) \
- REG_WRITE(_a, _r, REG_READ(_a, _r) | (_f))
+ REG_RMW(_a, _r, (_f), 0)
#define REG_CLR_BIT(_a, _r, _f) \
- REG_WRITE(_a, _r, REG_READ(_a, _r) & ~(_f))
+ REG_RMW(_a, _r, 0, (_f))
-#define DO_DELAY(x) do { \
- if ((++(x) % 64) == 0) \
- udelay(1); \
+#define DO_DELAY(x) do { \
+ if (((++(x) % 64) == 0) && \
+ (ath9k_hw_common(ah)->bus_ops->ath_bus_type \
+ != ATH_USB)) \
+ udelay(1); \
} while (0)
-#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \
- int r; \
- for (r = 0; r < ((iniarray)->ia_rows); r++) { \
- REG_WRITE(ah, INI_RA((iniarray), (r), 0), \
- INI_RA((iniarray), r, (column))); \
- DO_DELAY(regWr); \
- } \
- } while (0)
+#define REG_WRITE_ARRAY(iniarray, column, regWr) \
+ ath9k_hw_write_array(ah, iniarray, column, &(regWr))
#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
@@ -125,7 +125,7 @@
#define AR_GPIO_BIT(_gpio) (1 << (_gpio))
#define BASE_ACTIVATE_DELAY 100
-#define RTC_PLL_SETTLE_DELAY 100
+#define RTC_PLL_SETTLE_DELAY (AR_SREV_9340(ah) ? 1000 : 100)
#define COEF_SCALE_S 24
#define HT40_CHANNEL_CENTER_SHIFT 10
@@ -178,7 +178,6 @@ enum ath9k_hw_caps {
ATH9K_HW_CAP_HT = BIT(0),
ATH9K_HW_CAP_RFSILENT = BIT(1),
ATH9K_HW_CAP_CST = BIT(2),
- ATH9K_HW_CAP_ENHANCEDPM = BIT(3),
ATH9K_HW_CAP_AUTOSLEEP = BIT(4),
ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(5),
ATH9K_HW_CAP_EDMA = BIT(6),
@@ -195,17 +194,11 @@ enum ath9k_hw_caps {
struct ath9k_hw_capabilities {
u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
- u16 total_queues;
- u16 keycache_size;
- u16 low_5ghz_chan, high_5ghz_chan;
- u16 low_2ghz_chan, high_2ghz_chan;
u16 rts_aggr_limit;
u8 tx_chainmask;
u8 rx_chainmask;
u8 max_txchains;
u8 max_rxchains;
- u16 tx_triglevel_max;
- u16 reg_cap;
u8 num_gpio_pins;
u8 rx_hp_qdepth;
u8 rx_lp_qdepth;
@@ -227,7 +220,6 @@ struct ath9k_ops_config {
u8 pcie_clock_req;
u32 pcie_waen;
u8 analog_shiftreg;
- u8 ht_enable;
u8 paprd_disable;
u32 ofdm_trig_low;
u32 ofdm_trig_high;
@@ -412,8 +404,6 @@ struct ath9k_beacon_state {
u32 bs_nextdtim;
u32 bs_intval;
#define ATH9K_BEACON_PERIOD 0x0000ffff
-#define ATH9K_BEACON_ENA 0x00800000
-#define ATH9K_BEACON_RESET_TSF 0x01000000
#define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */
u32 bs_dtimperiod;
u16 bs_cfpperiod;
@@ -489,6 +479,10 @@ struct ath_hw_antcomb_conf {
u8 main_lna_conf;
u8 alt_lna_conf;
u8 fast_div_bias;
+ u8 main_gaintb;
+ u8 alt_gaintb;
+ int lna1_lna2_delta;
+ u8 div_group;
};
/**
@@ -638,10 +632,12 @@ struct ath_hw_ops {
u32 numDelims);
void (*set11n_aggr_last)(struct ath_hw *ah, void *ds);
void (*clr11n_aggr)(struct ath_hw *ah, void *ds);
- void (*set11n_burstduration)(struct ath_hw *ah, void *ds,
- u32 burstDuration);
- void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds,
- u32 vmf);
+ void (*set_clrdmask)(struct ath_hw *ah, void *ds, bool val);
+ void (*antdiv_comb_conf_get)(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf);
+ void (*antdiv_comb_conf_set)(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf);
+
};
struct ath_nf_limits {
@@ -655,6 +651,8 @@ struct ath_nf_limits {
#define AH_UNPLUGGED 0x2 /* The card has been physically removed. */
struct ath_hw {
+ struct ath_ops reg_ops;
+
struct ieee80211_hw *hw;
struct ath_common common;
struct ath9k_hw_version hw_version;
@@ -784,6 +782,8 @@ struct ath_hw {
/* Bluetooth coexistance */
struct ath_btcoex_hw btcoex_hw;
+ u32 bt_coex_bt_weight[AR9300_NUM_BT_WEIGHTS];
+ u32 bt_coex_wlan_weight[AR9300_NUM_WLAN_WEIGHTS];
u32 intr_txqs;
u8 txchainmask;
@@ -794,7 +794,9 @@ struct ath_hw {
u32 originalGain[22];
int initPDADC;
int PDADCdelta;
- u8 led_pin;
+ int led_pin;
+ u32 gpio_mask;
+ u32 gpio_val;
struct ar5416IniArray iniModes;
struct ar5416IniArray iniCommon;
@@ -810,6 +812,7 @@ struct ath_hw {
struct ar5416IniArray iniPcieSerdes;
struct ar5416IniArray iniPcieSerdesLowPower;
struct ar5416IniArray iniModesAdditional;
+ struct ar5416IniArray iniModesAdditional_40M;
struct ar5416IniArray iniModesRxGain;
struct ar5416IniArray iniModesTxGain;
struct ar5416IniArray iniModes_9271_1_0_only;
@@ -856,6 +859,16 @@ struct ath_hw {
/* Enterprise mode cap */
u32 ent_mode;
+
+ bool is_clk_25mhz;
+};
+
+struct ath_bus_ops {
+ enum ath_bus_type ath_bus_type;
+ void (*read_cachesize)(struct ath_common *common, int *csz);
+ bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
+ void (*bt_coex_prep)(struct ath_common *common);
+ void (*extn_synch_en)(struct ath_common *common);
};
static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
@@ -900,15 +913,12 @@ void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
-void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
- struct ath_hw_antcomb_conf *antconf);
-void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
- struct ath_hw_antcomb_conf *antconf);
/* General Operation */
bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
+void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
+ int column, unsigned int *writecnt);
u32 ath9k_hw_reverse_bits(u32 val, u32 n);
-bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
u16 ath9k_hw_computetxtime(struct ath_hw *ah,
u8 phy, int kbps,
u32 frameLen, u16 rateix, bool shortPreamble);
@@ -924,12 +934,13 @@ void ath9k_hw_setopmode(struct ath_hw *ah);
void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
void ath9k_hw_setbssidmask(struct ath_hw *ah);
void ath9k_hw_write_associd(struct ath_hw *ah);
+u32 ath9k_hw_gettsf32(struct ath_hw *ah);
u64 ath9k_hw_gettsf64(struct ath_hw *ah);
void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
void ath9k_hw_reset_tsf(struct ath_hw *ah);
void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
void ath9k_hw_init_global_settings(struct ath_hw *ah);
-unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
+u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
void ath9k_hw_set11nmac2040(struct ath_hw *ah);
void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 79aec983279..b172d150951 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -15,6 +15,7 @@
*/
#include <linux/slab.h>
+#include <linux/ath9k_platform.h>
#include "ath9k.h"
@@ -195,10 +196,27 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
return val;
}
-static const struct ath_ops ath9k_common_ops = {
- .read = ath9k_ioread32,
- .write = ath9k_iowrite32,
-};
+static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
+{
+ struct ath_hw *ah = (struct ath_hw *) hw_priv;
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ath_softc *sc = (struct ath_softc *) common->priv;
+ unsigned long uninitialized_var(flags);
+ u32 val;
+
+ if (ah->config.serialize_regmode == SER_REG_MODE_ON)
+ spin_lock_irqsave(&sc->sc_serial_rw, flags);
+
+ val = ioread32(sc->mem + reg_offset);
+ val &= ~clr;
+ val |= set;
+ iowrite32(val, sc->mem + reg_offset);
+
+ if (ah->config.serialize_regmode == SER_REG_MODE_ON)
+ spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
+
+ return val;
+}
/**************************/
/* Initialization */
@@ -389,13 +407,7 @@ void ath9k_init_crypto(struct ath_softc *sc)
int i = 0;
/* Get the hardware key cache size. */
- common->keymax = sc->sc_ah->caps.keycache_size;
- if (common->keymax > ATH_KEYMAX) {
- ath_dbg(common, ATH_DBG_ANY,
- "Warning, using only %u entries in %u key cache\n",
- ATH_KEYMAX, common->keymax);
- common->keymax = ATH_KEYMAX;
- }
+ common->keymax = AR_KEYTABLE_SIZE;
/*
* Reset the key cache since some parts do not
@@ -537,6 +549,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
const struct ath_bus_ops *bus_ops)
{
+ struct ath9k_platform_data *pdata = sc->dev->platform_data;
struct ath_hw *ah = NULL;
struct ath_common *common;
int ret = 0, i;
@@ -549,13 +562,23 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
ah->hw = sc->hw;
ah->hw_version.devid = devid;
ah->hw_version.subsysid = subsysid;
+ ah->reg_ops.read = ath9k_ioread32;
+ ah->reg_ops.write = ath9k_iowrite32;
+ ah->reg_ops.rmw = ath9k_reg_rmw;
sc->sc_ah = ah;
- if (!sc->dev->platform_data)
+ if (!pdata) {
ah->ah_flags |= AH_USE_EEPROM;
+ sc->sc_ah->led_pin = -1;
+ } else {
+ sc->sc_ah->gpio_mask = pdata->gpio_mask;
+ sc->sc_ah->gpio_val = pdata->gpio_val;
+ sc->sc_ah->led_pin = pdata->led_pin;
+ ah->is_clk_25mhz = pdata->is_clk_25mhz;
+ }
common = ath9k_hw_common(ah);
- common->ops = &ath9k_common_ops;
+ common->ops = &ah->reg_ops;
common->bus_ops = bus_ops;
common->ah = ah;
common->hw = sc->hw;
@@ -587,6 +610,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
if (ret)
goto err_hw;
+ if (pdata && pdata->macaddr)
+ memcpy(common->macaddr, pdata->macaddr, ETH_ALEN);
+
ret = ath9k_init_queues(sc);
if (ret)
goto err_queues;
@@ -679,6 +705,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
if (AR_SREV_5416(sc->sc_ah))
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+ hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+
hw->queues = 4;
hw->max_rates = 4;
hw->channel_change_time = 5000;
@@ -773,6 +801,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
INIT_WORK(&sc->hw_check_work, ath_hw_check);
INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
+ INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
ath_init_leds(sc);
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index edc1cbbfeca..bd6d2b9d736 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -209,15 +209,8 @@ bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
{
u32 cw;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath9k_tx_queue_info *qi;
- if (q >= pCap->total_queues) {
- ath_dbg(common, ATH_DBG_QUEUE,
- "Set TXQ properties, invalid queue: %u\n", q);
- return false;
- }
-
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
ath_dbg(common, ATH_DBG_QUEUE,
@@ -280,15 +273,8 @@ bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
struct ath9k_tx_queue_info *qinfo)
{
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath9k_tx_queue_info *qi;
- if (q >= pCap->total_queues) {
- ath_dbg(common, ATH_DBG_QUEUE,
- "Get TXQ properties, invalid queue: %u\n", q);
- return false;
- }
-
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
ath_dbg(common, ATH_DBG_QUEUE,
@@ -320,28 +306,27 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
{
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_tx_queue_info *qi;
- struct ath9k_hw_capabilities *pCap = &ah->caps;
int q;
switch (type) {
case ATH9K_TX_QUEUE_BEACON:
- q = pCap->total_queues - 1;
+ q = ATH9K_NUM_TX_QUEUES - 1;
break;
case ATH9K_TX_QUEUE_CAB:
- q = pCap->total_queues - 2;
+ q = ATH9K_NUM_TX_QUEUES - 2;
break;
case ATH9K_TX_QUEUE_PSPOLL:
q = 1;
break;
case ATH9K_TX_QUEUE_UAPSD:
- q = pCap->total_queues - 3;
+ q = ATH9K_NUM_TX_QUEUES - 3;
break;
case ATH9K_TX_QUEUE_DATA:
- for (q = 0; q < pCap->total_queues; q++)
+ for (q = 0; q < ATH9K_NUM_TX_QUEUES; q++)
if (ah->txq[q].tqi_type ==
ATH9K_TX_QUEUE_INACTIVE)
break;
- if (q == pCap->total_queues) {
+ if (q == ATH9K_NUM_TX_QUEUES) {
ath_err(common, "No available TX queue\n");
return -1;
}
@@ -382,15 +367,9 @@ EXPORT_SYMBOL(ath9k_hw_setuptxqueue);
bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
{
- struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_tx_queue_info *qi;
- if (q >= pCap->total_queues) {
- ath_dbg(common, ATH_DBG_QUEUE,
- "Release TXQ, invalid queue: %u\n", q);
- return false;
- }
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
ath_dbg(common, ATH_DBG_QUEUE,
@@ -414,18 +393,11 @@ EXPORT_SYMBOL(ath9k_hw_releasetxqueue);
bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
{
- struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_channel *chan = ah->curchan;
struct ath9k_tx_queue_info *qi;
u32 cwMin, chanCwMin, value;
- if (q >= pCap->total_queues) {
- ath_dbg(common, ATH_DBG_QUEUE,
- "Reset TXQ, invalid queue: %u\n", q);
- return false;
- }
-
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
ath_dbg(common, ATH_DBG_QUEUE,
@@ -458,17 +430,21 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
- REG_WRITE(ah, AR_DMISC(q),
- AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
+
+ if (AR_SREV_9340(ah))
+ REG_WRITE(ah, AR_DMISC(q),
+ AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x1);
+ else
+ REG_WRITE(ah, AR_DMISC(q),
+ AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
if (qi->tqi_cbrPeriod) {
REG_WRITE(ah, AR_QCBRCFG(q),
SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
- REG_WRITE(ah, AR_QMISC(q),
- REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR |
- (qi->tqi_cbrOverflowLimit ?
- AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
+ REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_FSP_CBR |
+ (qi->tqi_cbrOverflowLimit ?
+ AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
}
if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
REG_WRITE(ah, AR_QRDYTIMECFG(q),
@@ -481,40 +457,31 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
(qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
if (qi->tqi_burstTime
- && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
- REG_WRITE(ah, AR_QMISC(q),
- REG_READ(ah, AR_QMISC(q)) |
- AR_Q_MISC_RDYTIME_EXP_POLICY);
+ && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE))
+ REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_RDYTIME_EXP_POLICY);
- }
-
- if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
- REG_WRITE(ah, AR_DMISC(q),
- REG_READ(ah, AR_DMISC(q)) |
- AR_D_MISC_POST_FR_BKOFF_DIS);
- }
+ if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE)
+ REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS);
REGWRITE_BUFFER_FLUSH(ah);
- if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
- REG_WRITE(ah, AR_DMISC(q),
- REG_READ(ah, AR_DMISC(q)) |
- AR_D_MISC_FRAG_BKOFF_EN);
- }
+ if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
+ REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_FRAG_BKOFF_EN);
+
switch (qi->tqi_type) {
case ATH9K_TX_QUEUE_BEACON:
ENABLE_REGWRITE_BUFFER(ah);
- REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
- | AR_Q_MISC_FSP_DBA_GATED
- | AR_Q_MISC_BEACON_USE
- | AR_Q_MISC_CBR_INCR_DIS1);
+ REG_SET_BIT(ah, AR_QMISC(q),
+ AR_Q_MISC_FSP_DBA_GATED
+ | AR_Q_MISC_BEACON_USE
+ | AR_Q_MISC_CBR_INCR_DIS1);
- REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
- | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
+ REG_SET_BIT(ah, AR_DMISC(q),
+ (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
- | AR_D_MISC_BEACON_USE
- | AR_D_MISC_POST_FR_BKOFF_DIS);
+ | AR_D_MISC_BEACON_USE
+ | AR_D_MISC_POST_FR_BKOFF_DIS);
REGWRITE_BUFFER_FLUSH(ah);
@@ -533,41 +500,38 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
case ATH9K_TX_QUEUE_CAB:
ENABLE_REGWRITE_BUFFER(ah);
- REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
- | AR_Q_MISC_FSP_DBA_GATED
- | AR_Q_MISC_CBR_INCR_DIS1
- | AR_Q_MISC_CBR_INCR_DIS0);
+ REG_SET_BIT(ah, AR_QMISC(q),
+ AR_Q_MISC_FSP_DBA_GATED
+ | AR_Q_MISC_CBR_INCR_DIS1
+ | AR_Q_MISC_CBR_INCR_DIS0);
value = (qi->tqi_readyTime -
(ah->config.sw_beacon_response_time -
ah->config.dma_beacon_response_time) -
ah->config.additional_swba_backoff) * 1024;
REG_WRITE(ah, AR_QRDYTIMECFG(q),
value | AR_Q_RDYTIMECFG_EN);
- REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
- | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
+ REG_SET_BIT(ah, AR_DMISC(q),
+ (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
REGWRITE_BUFFER_FLUSH(ah);
break;
case ATH9K_TX_QUEUE_PSPOLL:
- REG_WRITE(ah, AR_QMISC(q),
- REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
+ REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_CBR_INCR_DIS1);
break;
case ATH9K_TX_QUEUE_UAPSD:
- REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) |
- AR_D_MISC_POST_FR_BKOFF_DIS);
+ REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS);
break;
default:
break;
}
if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
- REG_WRITE(ah, AR_DMISC(q),
- REG_READ(ah, AR_DMISC(q)) |
- SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
- AR_D_MISC_ARB_LOCKOUT_CNTRL) |
- AR_D_MISC_POST_FR_BKOFF_DIS);
+ REG_SET_BIT(ah, AR_DMISC(q),
+ SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
+ AR_D_MISC_ARB_LOCKOUT_CNTRL) |
+ AR_D_MISC_POST_FR_BKOFF_DIS);
}
if (AR_SREV_9300_20_OR_LATER(ah))
@@ -754,7 +718,6 @@ EXPORT_SYMBOL(ath9k_hw_abortpcurecv);
bool ath9k_hw_stopdmarecv(struct ath_hw *ah, bool *reset)
{
#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */
-#define AH_RX_TIME_QUANTUM 100 /* usec */
struct ath_common *common = ath9k_hw_common(ah);
u32 mac_status, last_mac_status = 0;
int i;
@@ -797,7 +760,6 @@ bool ath9k_hw_stopdmarecv(struct ath_hw *ah, bool *reset)
return true;
}
-#undef AH_RX_TIME_QUANTUM
#undef AH_RX_STOP_DMA_TIMEOUT
}
EXPORT_SYMBOL(ath9k_hw_stopdmarecv);
@@ -855,10 +817,14 @@ EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
void ath9k_hw_enable_interrupts(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
+ u32 sync_default = AR_INTR_SYNC_DEFAULT;
if (!(ah->imask & ATH9K_INT_GLOBAL))
return;
+ if (AR_SREV_9340(ah))
+ sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+
ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n");
REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
if (!AR_SREV_9100(ah)) {
@@ -867,10 +833,8 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
- REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
- AR_INTR_SYNC_DEFAULT);
- REG_WRITE(ah, AR_INTR_SYNC_MASK,
- AR_INTR_SYNC_DEFAULT);
+ REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
+ REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default);
}
ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
@@ -926,6 +890,9 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
mask |= AR_IMR_GENTMR;
}
+ if (ints & ATH9K_INT_GENTIMER)
+ mask |= AR_IMR_GENTMR;
+
if (ints & (ATH9K_INT_BMISC)) {
mask |= AR_IMR_BCNMISC;
if (ints & ATH9K_INT_TIM)
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index c2a59386fb9..b60c130917f 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -239,7 +239,6 @@ struct ath_desc {
void *ds_vdata;
} __packed __aligned(4);
-#define ATH9K_TXDESC_CLRDMASK 0x0001
#define ATH9K_TXDESC_NOACK 0x0002
#define ATH9K_TXDESC_RTSENA 0x0004
#define ATH9K_TXDESC_CTSENA 0x0008
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 1482fa65083..17ebdf1e8b7 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -299,7 +299,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
if (sc->sc_flags & SC_OP_BEACONS)
- ath_beacon_config(sc, NULL);
+ ath_set_beacon(sc);
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2);
ath_start_ani(common);
@@ -624,6 +624,43 @@ out:
ath9k_ps_restore(sc);
}
+static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
+{
+ static int count;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+
+ if (pll_sqsum >= 0x40000) {
+ count++;
+ if (count == 3) {
+ /* Rx is hung for more than 500ms. Reset it */
+ ath_dbg(common, ATH_DBG_RESET,
+ "Possible RX hang, resetting");
+ ath_reset(sc, true);
+ count = 0;
+ }
+ } else
+ count = 0;
+}
+
+void ath_hw_pll_work(struct work_struct *work)
+{
+ struct ath_softc *sc = container_of(work, struct ath_softc,
+ hw_pll_work.work);
+ u32 pll_sqsum;
+
+ if (AR_SREV_9485(sc->sc_ah)) {
+
+ ath9k_ps_wakeup(sc);
+ pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
+ ath9k_ps_restore(sc);
+
+ ath_hw_pll_rx_hang_check(sc, pll_sqsum);
+
+ ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
+ }
+}
+
+
void ath9k_tasklet(unsigned long data)
{
struct ath_softc *sc = (struct ath_softc *)data;
@@ -652,6 +689,17 @@ void ath9k_tasklet(unsigned long data)
!ath9k_hw_check_alive(ah))
ieee80211_queue_work(sc->hw, &sc->hw_check_work);
+ if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
+ /*
+ * TSF sync does not look correct; remain awake to sync with
+ * the next Beacon.
+ */
+ ath_dbg(common, ATH_DBG_PS,
+ "TSFOOR - Sync with next Beacon\n");
+ sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC |
+ PS_TSFOOR_SYNC;
+ }
+
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL |
ATH9K_INT_RXORN);
@@ -674,16 +722,6 @@ void ath9k_tasklet(unsigned long data)
ath_tx_tasklet(sc);
}
- if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
- /*
- * TSF sync does not look correct; remain awake to sync with
- * the next Beacon.
- */
- ath_dbg(common, ATH_DBG_PS,
- "TSFOOR - Sync with next Beacon\n");
- sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
- }
-
if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
if (status & ATH9K_INT_GENTIMER)
ath_gen_timer_isr(sc->sc_ah);
@@ -828,48 +866,6 @@ chip_reset:
#undef SCHED_INTR
}
-static void ath9k_bss_assoc_info(struct ath_softc *sc,
- struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf)
-{
- struct ath_hw *ah = sc->sc_ah;
- struct ath_common *common = ath9k_hw_common(ah);
-
- if (bss_conf->assoc) {
- ath_dbg(common, ATH_DBG_CONFIG,
- "Bss Info ASSOC %d, bssid: %pM\n",
- bss_conf->aid, common->curbssid);
-
- /* New association, store aid */
- common->curaid = bss_conf->aid;
- ath9k_hw_write_associd(ah);
-
- /*
- * Request a re-configuration of Beacon related timers
- * on the receipt of the first Beacon frame (i.e.,
- * after time sync with the AP).
- */
- sc->ps_flags |= PS_BEACON_SYNC;
-
- /* Configure the beacon */
- ath_beacon_config(sc, vif);
-
- /* Reset rssi stats */
- sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
- sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
-
- sc->sc_flags |= SC_OP_ANI_RUN;
- ath_start_ani(common);
- } else {
- ath_dbg(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
- common->curaid = 0;
- /* Stop ANI */
- sc->sc_flags &= ~SC_OP_ANI_RUN;
- del_timer_sync(&common->ani.timer);
- }
-}
-
void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
{
struct ath_hw *ah = sc->sc_ah;
@@ -899,7 +895,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
goto out;
}
if (sc->sc_flags & SC_OP_BEACONS)
- ath_beacon_config(sc, NULL); /* restart beacons */
+ ath_set_beacon(sc); /* restart beacons */
/* Re-Enable interrupts */
ath9k_hw_set_interrupts(ah, ah->imask);
@@ -1006,7 +1002,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
sc->config.txpowlimit, &sc->curtxpow);
if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL)))
- ath_beacon_config(sc, NULL); /* restart beacons */
+ ath_set_beacon(sc); /* restart beacons */
ath9k_hw_set_interrupts(ah, ah->imask);
@@ -1389,7 +1385,9 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
ath9k_hw_set_tsfadjust(ah, 0);
sc->sc_flags &= ~SC_OP_TSF_RESET;
- if (iter_data.nwds + iter_data.nmeshes)
+ if (iter_data.nmeshes)
+ ah->opmode = NL80211_IFTYPE_MESH_POINT;
+ else if (iter_data.nwds)
ah->opmode = NL80211_IFTYPE_AP;
else if (iter_data.nadhocs)
ah->opmode = NL80211_IFTYPE_ADHOC;
@@ -1413,6 +1411,7 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
/* Set up ANI */
if ((iter_data.naps + iter_data.nadhocs) > 0) {
+ sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
sc->sc_flags |= SC_OP_ANI_RUN;
ath_start_ani(common);
} else {
@@ -1452,7 +1451,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath_vif *avp = (void *)vif->drv_priv;
int ret = 0;
ath9k_ps_wakeup(sc);
@@ -1482,8 +1480,9 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
}
}
- if ((vif->type == NL80211_IFTYPE_ADHOC) &&
- sc->nvifs > 0) {
+ if ((ah->opmode == NL80211_IFTYPE_ADHOC) ||
+ ((vif->type == NL80211_IFTYPE_ADHOC) &&
+ sc->nvifs > 0)) {
ath_err(common, "Cannot create ADHOC interface when other"
" interfaces already exist.\n");
ret = -EINVAL;
@@ -1493,10 +1492,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
ath_dbg(common, ATH_DBG_CONFIG,
"Attach a VIF of type: %d\n", vif->type);
- /* Set the VIF opmode */
- avp->av_opmode = vif->type;
- avp->av_bslot = -1;
-
sc->nvifs++;
ath9k_do_vif_add_setup(hw, vif);
@@ -1782,23 +1777,68 @@ static int ath9k_sta_add(struct ieee80211_hw *hw,
struct ieee80211_sta *sta)
{
struct ath_softc *sc = hw->priv;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_node *an = (struct ath_node *) sta->drv_priv;
+ struct ieee80211_key_conf ps_key = { };
ath_node_attach(sc, sta);
+ if (vif->type != NL80211_IFTYPE_AP &&
+ vif->type != NL80211_IFTYPE_AP_VLAN)
+ return 0;
+
+ an->ps_key = ath_key_config(common, vif, sta, &ps_key);
+
return 0;
}
+static void ath9k_del_ps_key(struct ath_softc *sc,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_node *an = (struct ath_node *) sta->drv_priv;
+ struct ieee80211_key_conf ps_key = { .hw_key_idx = an->ps_key };
+
+ if (!an->ps_key)
+ return;
+
+ ath_key_delete(common, &ps_key);
+}
+
static int ath9k_sta_remove(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
struct ath_softc *sc = hw->priv;
+ ath9k_del_ps_key(sc, vif, sta);
ath_node_detach(sc, sta);
return 0;
}
+static void ath9k_sta_notify(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum sta_notify_cmd cmd,
+ struct ieee80211_sta *sta)
+{
+ struct ath_softc *sc = hw->priv;
+ struct ath_node *an = (struct ath_node *) sta->drv_priv;
+
+ switch (cmd) {
+ case STA_NOTIFY_SLEEP:
+ an->sleeping = true;
+ if (ath_tx_aggr_sleep(sc, an))
+ ieee80211_sta_set_tim(sta);
+ break;
+ case STA_NOTIFY_AWAKE:
+ an->sleeping = false;
+ ath_tx_aggr_wakeup(sc, an);
+ break;
+ }
+}
+
static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
@@ -1855,12 +1895,29 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
if (ath9k_modparam_nohwcrypt)
return -ENOSPC;
+ if (vif->type == NL80211_IFTYPE_ADHOC &&
+ (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
+ key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
+ !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+ /*
+ * For now, disable hw crypto for the RSN IBSS group keys. This
+ * could be optimized in the future to use a modified key cache
+ * design to support per-STA RX GTK, but until that gets
+ * implemented, use of software crypto for group addressed
+ * frames is a acceptable to allow RSN IBSS to be used.
+ */
+ return -EOPNOTSUPP;
+ }
+
mutex_lock(&sc->mutex);
ath9k_ps_wakeup(sc);
ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n");
switch (cmd) {
case SET_KEY:
+ if (sta)
+ ath9k_del_ps_key(sc, vif, sta);
+
ret = ath_key_config(common, vif, sta, key);
if (ret >= 0) {
key->hw_key_idx = ret;
@@ -1886,6 +1943,92 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
return ret;
}
+static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+ struct ath_softc *sc = data;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+ struct ath_vif *avp = (void *)vif->drv_priv;
+
+ switch (sc->sc_ah->opmode) {
+ case NL80211_IFTYPE_ADHOC:
+ /* There can be only one vif available */
+ memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
+ common->curaid = bss_conf->aid;
+ ath9k_hw_write_associd(sc->sc_ah);
+ /* configure beacon */
+ if (bss_conf->enable_beacon)
+ ath_beacon_config(sc, vif);
+ break;
+ case NL80211_IFTYPE_STATION:
+ /*
+ * Skip iteration if primary station vif's bss info
+ * was not changed
+ */
+ if (sc->sc_flags & SC_OP_PRIM_STA_VIF)
+ break;
+
+ if (bss_conf->assoc) {
+ sc->sc_flags |= SC_OP_PRIM_STA_VIF;
+ avp->primary_sta_vif = true;
+ memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
+ common->curaid = bss_conf->aid;
+ ath9k_hw_write_associd(sc->sc_ah);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Bss Info ASSOC %d, bssid: %pM\n",
+ bss_conf->aid, common->curbssid);
+ ath_beacon_config(sc, vif);
+ /*
+ * Request a re-configuration of Beacon related timers
+ * on the receipt of the first Beacon frame (i.e.,
+ * after time sync with the AP).
+ */
+ sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
+ /* Reset rssi stats */
+ sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
+ sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
+
+ sc->sc_flags |= SC_OP_ANI_RUN;
+ ath_start_ani(common);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
+{
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+ struct ath_vif *avp = (void *)vif->drv_priv;
+
+ /* Reconfigure bss info */
+ if (avp->primary_sta_vif && !bss_conf->assoc) {
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Bss Info DISASSOC %d, bssid %pM\n",
+ common->curaid, common->curbssid);
+ sc->sc_flags &= ~(SC_OP_PRIM_STA_VIF | SC_OP_BEACONS);
+ avp->primary_sta_vif = false;
+ memset(common->curbssid, 0, ETH_ALEN);
+ common->curaid = 0;
+ }
+
+ ieee80211_iterate_active_interfaces_atomic(
+ sc->hw, ath9k_bss_iter, sc);
+
+ /*
+ * None of station vifs are associated.
+ * Clear bssid & aid
+ */
+ if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
+ !(sc->sc_flags & SC_OP_PRIM_STA_VIF)) {
+ ath9k_hw_write_associd(sc->sc_ah);
+ /* Stop ANI */
+ sc->sc_flags &= ~SC_OP_ANI_RUN;
+ del_timer_sync(&common->ani.timer);
+ }
+}
static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
@@ -1893,7 +2036,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
u32 changed)
{
struct ath_softc *sc = hw->priv;
- struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ath_vif *avp = (void *)vif->drv_priv;
@@ -1904,20 +2046,10 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
mutex_lock(&sc->mutex);
if (changed & BSS_CHANGED_BSSID) {
- /* Set BSSID */
- memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
- memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
- common->curaid = 0;
- ath9k_hw_write_associd(ah);
-
- /* Set aggregation protection mode parameters */
- sc->config.ath_aggr_prot = 0;
+ ath9k_config_bss(sc, vif);
ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n",
common->curbssid, common->curaid);
-
- /* need to reconfigure the beacon */
- sc->sc_flags &= ~SC_OP_BEACONS ;
}
/* Enable transmission of beacons (AP, IBSS, MESH) */
@@ -1958,7 +2090,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_BEACON_INT) {
- cur_conf->beacon_interval = bss_conf->beacon_int;
/*
* In case of AP mode, the HW TSF has to be reset
* when the beacon interval changes.
@@ -1970,9 +2101,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
if (!error)
ath_beacon_config(sc, vif);
ath9k_set_beaconing_status(sc, true);
- } else {
+ } else
ath_beacon_config(sc, vif);
- }
}
if (changed & BSS_CHANGED_ERP_PREAMBLE) {
@@ -1994,12 +2124,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
}
- if (changed & BSS_CHANGED_ASSOC) {
- ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
- bss_conf->assoc);
- ath9k_bss_assoc_info(sc, hw, vif, bss_conf);
- }
-
mutex_unlock(&sc->mutex);
ath9k_ps_restore(sc);
}
@@ -2145,10 +2269,9 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
struct ath_common *common = ath9k_hw_common(ah);
int timeout = 200; /* ms */
int i, j;
+ bool drain_txq;
- ath9k_ps_wakeup(sc);
mutex_lock(&sc->mutex);
-
cancel_delayed_work_sync(&sc->tx_complete_work);
if (sc->sc_flags & SC_OP_INVALID) {
@@ -2161,7 +2284,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
timeout = 1;
for (j = 0; j < timeout; j++) {
- int npend = 0;
+ bool npend = false;
if (j)
usleep_range(1000, 2000);
@@ -2170,22 +2293,43 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
if (!ATH_TXQ_SETUP(sc, i))
continue;
- npend += ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
+ npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
+
+ if (npend)
+ break;
}
if (!npend)
goto out;
}
- if (!ath_drain_all_txq(sc, false))
+ ath9k_ps_wakeup(sc);
+ spin_lock_bh(&sc->sc_pcu_lock);
+ drain_txq = ath_drain_all_txq(sc, false);
+ spin_unlock_bh(&sc->sc_pcu_lock);
+ if (!drain_txq)
ath_reset(sc, false);
-
+ ath9k_ps_restore(sc);
ieee80211_wake_queues(hw);
out:
ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
mutex_unlock(&sc->mutex);
- ath9k_ps_restore(sc);
+}
+
+static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
+{
+ struct ath_softc *sc = hw->priv;
+ int i;
+
+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+ if (!ATH_TXQ_SETUP(sc, i))
+ continue;
+
+ if (ath9k_has_pending_frames(sc, &sc->tx.txq[i]))
+ return true;
+ }
+ return false;
}
struct ieee80211_ops ath9k_ops = {
@@ -2199,6 +2343,7 @@ struct ieee80211_ops ath9k_ops = {
.configure_filter = ath9k_configure_filter,
.sta_add = ath9k_sta_add,
.sta_remove = ath9k_sta_remove,
+ .sta_notify = ath9k_sta_notify,
.conf_tx = ath9k_conf_tx,
.bss_info_changed = ath9k_bss_info_changed,
.set_key = ath9k_set_key,
@@ -2210,4 +2355,5 @@ struct ieee80211_ops ath9k_ops = {
.rfkill_poll = ath9k_rfkill_poll_state,
.set_coverage_class = ath9k_set_coverage_class,
.flush = ath9k_flush,
+ .tx_frames_pending = ath9k_tx_frames_pending,
};
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 5e3d7496986..9441bf8ca2f 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -19,7 +19,6 @@
#define CHANSEL_DIV 15
#define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV)
-#define CHANSEL_2G_9485(_freq) ((((_freq) * 0x10000) - 215) / CHANSEL_DIV)
#define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV)
#define AR_PHY_BASE 0x9800
@@ -38,26 +37,15 @@
#define AR_PHY_CLC_Q0 0x0000ffd0
#define AR_PHY_CLC_Q0_S 5
-#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \
- int r; \
- for (r = 0; r < ((iniarray)->ia_rows); r++) { \
- REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \
- DO_DELAY(regWr); \
- } \
- } while (0)
-
#define ANTSWAP_AB 0x0001
#define REDUCE_CHAIN_0 0x00000050
#define REDUCE_CHAIN_1 0x00000051
#define AR_PHY_CHIP_ID 0x9818
-#define RF_BANK_SETUP(_bank, _iniarray, _col) do { \
- int i; \
- for (i = 0; i < (_iniarray)->ia_rows; i++) \
- (_bank)[i] = INI_RA((_iniarray), i, _col);; \
- } while (0)
-
#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
+#define AR_PHY_PLL_CONTROL 0x16180
+#define AR_PHY_PLL_MODE 0x16184
+
#endif
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 4c0d36a6980..4ccbf2ddb55 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -854,14 +854,13 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
}
-static bool ath_rc_update_per(struct ath_softc *sc,
+static void ath_rc_update_per(struct ath_softc *sc,
const struct ath_rate_table *rate_table,
struct ath_rate_priv *ath_rc_priv,
struct ieee80211_tx_info *tx_info,
int tx_rate, int xretries, int retries,
u32 now_msec)
{
- bool state_change = false;
int count, n_bad_frames;
u8 last_per;
static const u32 nretry_to_per_lookup[10] = {
@@ -992,8 +991,6 @@ static bool ath_rc_update_per(struct ath_softc *sc,
}
}
-
- return state_change;
}
static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
@@ -1017,7 +1014,6 @@ static void ath_rc_update_ht(struct ath_softc *sc,
u32 now_msec = jiffies_to_msecs(jiffies);
int rate;
u8 last_per;
- bool state_change = false;
const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
int size = ath_rc_priv->rate_table_size;
@@ -1027,9 +1023,9 @@ static void ath_rc_update_ht(struct ath_softc *sc,
last_per = ath_rc_priv->per[tx_rate];
/* Update PER first */
- state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
- tx_info, tx_rate, xretries,
- retries, now_msec);
+ ath_rc_update_per(sc, rate_table, ath_rc_priv,
+ tx_info, tx_rate, xretries,
+ retries, now_msec);
/*
* If this rate looks bad (high PER) then stop using it for
@@ -1092,8 +1088,7 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
if (!(rate->flags & IEEE80211_TX_RC_MCS))
return rate->idx;
- while (rate->idx > mcs_rix_off[i] &&
- i < ARRAY_SIZE(mcs_rix_off)) {
+ while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) {
rix++; i++;
}
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index b29c80def35..4f52e0429f9 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -28,6 +28,33 @@ static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta,
(alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50);
}
+static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio,
+ int curr_main_set, int curr_alt_set,
+ int alt_rssi_avg, int main_rssi_avg)
+{
+ bool result = false;
+ switch (div_group) {
+ case 0:
+ if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)
+ result = true;
+ break;
+ case 1:
+ if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) &&
+ (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) &&
+ (alt_rssi_avg >= (main_rssi_avg - 5))) ||
+ ((curr_main_set == ATH_ANT_DIV_COMB_LNA1) &&
+ (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) &&
+ (alt_rssi_avg >= (main_rssi_avg - 2)))) &&
+ (alt_rssi_avg >= 4))
+ result = true;
+ else
+ result = false;
+ break;
+ }
+
+ return result;
+}
+
static inline bool ath9k_check_auto_sleep(struct ath_softc *sc)
{
return sc->ps_enabled &&
@@ -75,7 +102,6 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
*sc->rx.rxlink = bf->bf_daddr;
sc->rx.rxlink = &ds->ds_link;
- ath9k_hw_rxena(ah);
}
static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
@@ -426,9 +452,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
else
rfilt |= ATH9K_RX_FILTER_BEACON;
- if ((AR_SREV_9280_20_OR_LATER(sc->sc_ah) ||
- AR_SREV_9285_12_OR_LATER(sc->sc_ah)) &&
- (sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
+ if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
(sc->rx.rxfilter & FIF_PSPOLL))
rfilt |= ATH9K_RX_FILTER_PSPOLL;
@@ -574,7 +598,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
sc->ps_flags &= ~PS_BEACON_SYNC;
ath_dbg(common, ATH_DBG_PS,
"Reconfigure Beacon timers based on timestamp from the AP\n");
- ath_beacon_config(sc, NULL);
+ ath_set_beacon(sc);
+ sc->ps_flags &= ~PS_TSFOOR_SYNC;
}
if (ath_beacon_dtim_pending_cab(skb)) {
@@ -919,7 +944,8 @@ static void ath9k_process_rssi(struct ath_common *common,
int last_rssi;
__le16 fc;
- if (ah->opmode != NL80211_IFTYPE_STATION)
+ if ((ah->opmode != NL80211_IFTYPE_STATION) &&
+ (ah->opmode != NL80211_IFTYPE_ADHOC))
return;
fc = hdr->frame_control;
@@ -1291,49 +1317,138 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
}
}
-static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf)
+static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
+ struct ath_ant_comb *antcomb, int alt_ratio)
{
- /* Adjust the fast_div_bias based on main and alt lna conf */
- switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) {
- case (0x01): /* A-B LNA2 */
- ant_conf->fast_div_bias = 0x3b;
- break;
- case (0x02): /* A-B LNA1 */
- ant_conf->fast_div_bias = 0x3d;
- break;
- case (0x03): /* A-B A+B */
- ant_conf->fast_div_bias = 0x1;
- break;
- case (0x10): /* LNA2 A-B */
- ant_conf->fast_div_bias = 0x7;
- break;
- case (0x12): /* LNA2 LNA1 */
- ant_conf->fast_div_bias = 0x2;
- break;
- case (0x13): /* LNA2 A+B */
- ant_conf->fast_div_bias = 0x7;
- break;
- case (0x20): /* LNA1 A-B */
- ant_conf->fast_div_bias = 0x6;
- break;
- case (0x21): /* LNA1 LNA2 */
- ant_conf->fast_div_bias = 0x0;
- break;
- case (0x23): /* LNA1 A+B */
- ant_conf->fast_div_bias = 0x6;
- break;
- case (0x30): /* A+B A-B */
- ant_conf->fast_div_bias = 0x1;
- break;
- case (0x31): /* A+B LNA2 */
- ant_conf->fast_div_bias = 0x3b;
- break;
- case (0x32): /* A+B LNA1 */
- ant_conf->fast_div_bias = 0x3d;
- break;
- default:
- break;
+ if (ant_conf->div_group == 0) {
+ /* Adjust the fast_div_bias based on main and alt lna conf */
+ switch ((ant_conf->main_lna_conf << 4) |
+ ant_conf->alt_lna_conf) {
+ case (0x01): /* A-B LNA2 */
+ ant_conf->fast_div_bias = 0x3b;
+ break;
+ case (0x02): /* A-B LNA1 */
+ ant_conf->fast_div_bias = 0x3d;
+ break;
+ case (0x03): /* A-B A+B */
+ ant_conf->fast_div_bias = 0x1;
+ break;
+ case (0x10): /* LNA2 A-B */
+ ant_conf->fast_div_bias = 0x7;
+ break;
+ case (0x12): /* LNA2 LNA1 */
+ ant_conf->fast_div_bias = 0x2;
+ break;
+ case (0x13): /* LNA2 A+B */
+ ant_conf->fast_div_bias = 0x7;
+ break;
+ case (0x20): /* LNA1 A-B */
+ ant_conf->fast_div_bias = 0x6;
+ break;
+ case (0x21): /* LNA1 LNA2 */
+ ant_conf->fast_div_bias = 0x0;
+ break;
+ case (0x23): /* LNA1 A+B */
+ ant_conf->fast_div_bias = 0x6;
+ break;
+ case (0x30): /* A+B A-B */
+ ant_conf->fast_div_bias = 0x1;
+ break;
+ case (0x31): /* A+B LNA2 */
+ ant_conf->fast_div_bias = 0x3b;
+ break;
+ case (0x32): /* A+B LNA1 */
+ ant_conf->fast_div_bias = 0x3d;
+ break;
+ default:
+ break;
+ }
+ } else if (ant_conf->div_group == 2) {
+ /* Adjust the fast_div_bias based on main and alt_lna_conf */
+ switch ((ant_conf->main_lna_conf << 4) |
+ ant_conf->alt_lna_conf) {
+ case (0x01): /* A-B LNA2 */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x02): /* A-B LNA1 */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x03): /* A-B A+B */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x10): /* LNA2 A-B */
+ if (!(antcomb->scan) &&
+ (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
+ ant_conf->fast_div_bias = 0x1;
+ else
+ ant_conf->fast_div_bias = 0x2;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x12): /* LNA2 LNA1 */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x13): /* LNA2 A+B */
+ if (!(antcomb->scan) &&
+ (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
+ ant_conf->fast_div_bias = 0x1;
+ else
+ ant_conf->fast_div_bias = 0x2;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x20): /* LNA1 A-B */
+ if (!(antcomb->scan) &&
+ (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
+ ant_conf->fast_div_bias = 0x1;
+ else
+ ant_conf->fast_div_bias = 0x2;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x21): /* LNA1 LNA2 */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x23): /* LNA1 A+B */
+ if (!(antcomb->scan) &&
+ (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
+ ant_conf->fast_div_bias = 0x1;
+ else
+ ant_conf->fast_div_bias = 0x2;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x30): /* A+B A-B */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x31): /* A+B LNA2 */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x32): /* A+B LNA1 */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ default:
+ break;
+ }
+
}
+
}
/* Antenna diversity and combining */
@@ -1342,7 +1457,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
struct ath_hw_antcomb_conf div_ant_conf;
struct ath_ant_comb *antcomb = &sc->ant_comb;
int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
- int curr_main_set, curr_bias;
+ int curr_main_set;
int main_rssi = rs->rs_rssi_ctl0;
int alt_rssi = rs->rs_rssi_ctl1;
int rx_ant_conf, main_ant_conf;
@@ -1353,8 +1468,8 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
ATH_ANT_RX_MASK;
- /* Record packet only when alt_rssi is positive */
- if (alt_rssi > 0) {
+ /* Record packet only when both main_rssi and alt_rssi is positive */
+ if (main_rssi > 0 && alt_rssi > 0) {
antcomb->total_pkt_count++;
antcomb->main_total_rssi += main_rssi;
antcomb->alt_total_rssi += alt_rssi;
@@ -1396,7 +1511,6 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf);
curr_alt_set = div_ant_conf.alt_lna_conf;
curr_main_set = div_ant_conf.main_lna_conf;
- curr_bias = div_ant_conf.fast_div_bias;
antcomb->count++;
@@ -1415,7 +1529,9 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
}
if (!antcomb->scan) {
- if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) {
+ if (ath_ant_div_comb_alt_check(div_ant_conf.div_group,
+ alt_ratio, curr_main_set, curr_alt_set,
+ alt_rssi_avg, main_rssi_avg)) {
if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) {
/* Switch main and alt LNA */
div_ant_conf.main_lna_conf =
@@ -1444,7 +1560,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
}
if ((alt_rssi_avg < (main_rssi_avg +
- ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA)))
+ div_ant_conf.lna1_lna2_delta)))
goto div_comb_done;
}
@@ -1558,8 +1674,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
antcomb->quick_scan_cnt++;
div_comb_done:
- ath_ant_div_conf_fast_divbias(&div_ant_conf);
-
+ ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio);
ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf);
antcomb->scan_start_time = jiffies;
@@ -1746,7 +1861,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
if ((sc->ps_flags & (PS_WAIT_FOR_BEACON |
PS_WAIT_FOR_CAB |
PS_WAIT_FOR_PSPOLL_DATA)) ||
- unlikely(ath9k_check_auto_sleep(sc)))
+ ath9k_check_auto_sleep(sc))
ath_rx_ps(sc, skb);
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
@@ -1767,6 +1882,7 @@ requeue:
} else {
list_move_tail(&bf->list, &sc->rx.rxbuf);
ath_rx_buf_link(sc, bf);
+ ath9k_hw_rxena(ah);
}
} while (1);
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 8fa8acfde62..456f3ec20fe 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -693,7 +693,7 @@
#define AR_RC_APB 0x00000002
#define AR_RC_HOSTIF 0x00000100
-#define AR_WA 0x4004
+#define AR_WA (AR_SREV_9340(ah) ? 0x40c4 : 0x4004)
#define AR_WA_BIT6 (1 << 6)
#define AR_WA_BIT7 (1 << 7)
#define AR_WA_BIT23 (1 << 23)
@@ -712,7 +712,7 @@
#define AR_PM_STATE 0x4008
#define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000
-#define AR_HOST_TIMEOUT 0x4018
+#define AR_HOST_TIMEOUT (AR_SREV_9340(ah) ? 0x4008 : 0x4018)
#define AR_HOST_TIMEOUT_APB_CNTR 0x0000FFFF
#define AR_HOST_TIMEOUT_APB_CNTR_S 0
#define AR_HOST_TIMEOUT_LCL_CNTR 0xFFFF0000
@@ -742,7 +742,8 @@
#define EEPROM_PROTECT_WP_1024_2047 0x8000
#define AR_SREV \
- ((AR_SREV_9100(ah)) ? 0x0600 : 0x4020)
+ ((AR_SREV_9100(ah)) ? 0x0600 : (AR_SREV_9340(ah) \
+ ? 0x400c : 0x4020))
#define AR_SREV_ID \
((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF)
@@ -790,6 +791,7 @@
#define AR_SREV_VERSION_9485 0x240
#define AR_SREV_REVISION_9485_10 0
#define AR_SREV_REVISION_9485_11 1
+#define AR_SREV_VERSION_9340 0x300
#define AR_SREV_5416(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -858,9 +860,7 @@
#define AR_SREV_9300(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300))
#define AR_SREV_9300_20_OR_LATER(_ah) \
- (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
- ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20)))
+ ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300)
#define AR_SREV_9485(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485))
@@ -870,6 +870,11 @@
#define AR_SREV_9485_11(_ah) \
(AR_SREV_9485(_ah) && \
((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11))
+#define AR_SREV_9485_OR_LATER(_ah) \
+ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485))
+
+#define AR_SREV_9340(_ah) \
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340))
#define AR_SREV_9285E_20(_ah) \
(AR_SREV_9285_12_OR_LATER(_ah) && \
@@ -912,11 +917,11 @@ enum ath_usb_dev {
#define AR_INTR_SPURIOUS 0xFFFFFFFF
-#define AR_INTR_SYNC_CAUSE_CLR 0x4028
+#define AR_INTR_SYNC_CAUSE (AR_SREV_9340(ah) ? 0x4010 : 0x4028)
+#define AR_INTR_SYNC_CAUSE_CLR (AR_SREV_9340(ah) ? 0x4010 : 0x4028)
-#define AR_INTR_SYNC_CAUSE 0x4028
-#define AR_INTR_SYNC_ENABLE 0x402c
+#define AR_INTR_SYNC_ENABLE (AR_SREV_9340(ah) ? 0x4014 : 0x402c)
#define AR_INTR_SYNC_ENABLE_GPIO 0xFFFC0000
#define AR_INTR_SYNC_ENABLE_GPIO_S 18
@@ -956,24 +961,24 @@ enum {
};
-#define AR_INTR_ASYNC_MASK 0x4030
+#define AR_INTR_ASYNC_MASK (AR_SREV_9340(ah) ? 0x4018 : 0x4030)
#define AR_INTR_ASYNC_MASK_GPIO 0xFFFC0000
#define AR_INTR_ASYNC_MASK_GPIO_S 18
-#define AR_INTR_SYNC_MASK 0x4034
+#define AR_INTR_SYNC_MASK (AR_SREV_9340(ah) ? 0x401c : 0x4034)
#define AR_INTR_SYNC_MASK_GPIO 0xFFFC0000
#define AR_INTR_SYNC_MASK_GPIO_S 18
-#define AR_INTR_ASYNC_CAUSE_CLR 0x4038
-#define AR_INTR_ASYNC_CAUSE 0x4038
+#define AR_INTR_ASYNC_CAUSE_CLR (AR_SREV_9340(ah) ? 0x4020 : 0x4038)
+#define AR_INTR_ASYNC_CAUSE (AR_SREV_9340(ah) ? 0x4020 : 0x4038)
-#define AR_INTR_ASYNC_ENABLE 0x403c
+#define AR_INTR_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4024 : 0x403c)
#define AR_INTR_ASYNC_ENABLE_GPIO 0xFFFC0000
#define AR_INTR_ASYNC_ENABLE_GPIO_S 18
#define AR_PCIE_SERDES 0x4040
#define AR_PCIE_SERDES2 0x4044
-#define AR_PCIE_PM_CTRL 0x4014
+#define AR_PCIE_PM_CTRL (AR_SREV_9340(ah) ? 0x4004 : 0x4014)
#define AR_PCIE_PM_CTRL_ENA 0x00080000
#define AR_NUM_GPIO 14
@@ -984,7 +989,7 @@ enum {
#define AR9300_NUM_GPIO 17
#define AR7010_NUM_GPIO 16
-#define AR_GPIO_IN_OUT 0x4048
+#define AR_GPIO_IN_OUT (AR_SREV_9340(ah) ? 0x4028 : 0x4048)
#define AR_GPIO_IN_VAL 0x0FFFC000
#define AR_GPIO_IN_VAL_S 14
#define AR928X_GPIO_IN_VAL 0x000FFC00
@@ -998,11 +1003,12 @@ enum {
#define AR7010_GPIO_IN_VAL 0x0000FFFF
#define AR7010_GPIO_IN_VAL_S 0
-#define AR_GPIO_IN 0x404c
+#define AR_GPIO_IN (AR_SREV_9340(ah) ? 0x402c : 0x404c)
#define AR9300_GPIO_IN_VAL 0x0001FFFF
#define AR9300_GPIO_IN_VAL_S 0
-#define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)
+#define AR_GPIO_OE_OUT (AR_SREV_9340(ah) ? 0x4030 : \
+ (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c))
#define AR_GPIO_OE_OUT_DRV 0x3
#define AR_GPIO_OE_OUT_DRV_NO 0x0
#define AR_GPIO_OE_OUT_DRV_LOW 0x1
@@ -1024,11 +1030,13 @@ enum {
#define AR7010_GPIO_INT_MASK 0x52024
#define AR7010_GPIO_FUNCTION 0x52028
-#define AR_GPIO_INTR_POL (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050)
+#define AR_GPIO_INTR_POL (AR_SREV_9340(ah) ? 0x4038 : \
+ (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050))
#define AR_GPIO_INTR_POL_VAL 0x0001FFFF
#define AR_GPIO_INTR_POL_VAL_S 0
-#define AR_GPIO_INPUT_EN_VAL (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054)
+#define AR_GPIO_INPUT_EN_VAL (AR_SREV_9340(ah) ? 0x403c : \
+ (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054))
#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004
#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2
#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008
@@ -1046,13 +1054,15 @@ enum {
#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000
#define AR_GPIO_JTAG_DISABLE 0x00020000
-#define AR_GPIO_INPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058)
+#define AR_GPIO_INPUT_MUX1 (AR_SREV_9340(ah) ? 0x4040 : \
+ (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058))
#define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000
#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16
#define AR_GPIO_INPUT_MUX1_BT_PRIORITY 0x00000f00
#define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S 8
-#define AR_GPIO_INPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c)
+#define AR_GPIO_INPUT_MUX2 (AR_SREV_9340(ah) ? 0x4044 : \
+ (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c))
#define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f
#define AR_GPIO_INPUT_MUX2_CLK25_S 0
#define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0
@@ -1060,13 +1070,18 @@ enum {
#define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00
#define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8
-#define AR_GPIO_OUTPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060)
-#define AR_GPIO_OUTPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064)
-#define AR_GPIO_OUTPUT_MUX3 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068)
+#define AR_GPIO_OUTPUT_MUX1 (AR_SREV_9340(ah) ? 0x4048 : \
+ (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060))
+#define AR_GPIO_OUTPUT_MUX2 (AR_SREV_9340(ah) ? 0x404c : \
+ (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064))
+#define AR_GPIO_OUTPUT_MUX3 (AR_SREV_9340(ah) ? 0x4050 : \
+ (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068))
-#define AR_INPUT_STATE (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c)
+#define AR_INPUT_STATE (AR_SREV_9340(ah) ? 0x4054 : \
+ (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c))
-#define AR_EEPROM_STATUS_DATA (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c)
+#define AR_EEPROM_STATUS_DATA (AR_SREV_9340(ah) ? 0x40c8 : \
+ (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c))
#define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff
#define AR_EEPROM_STATUS_DATA_VAL_S 0
#define AR_EEPROM_STATUS_DATA_BUSY 0x00010000
@@ -1074,28 +1089,51 @@ enum {
#define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000
#define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000
-#define AR_OBS (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080)
+#define AR_OBS (AR_SREV_9340(ah) ? 0x405c : \
+ (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080))
#define AR_GPIO_PDPU (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088)
-#define AR_PCIE_MSI (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094)
+#define AR_PCIE_MSI (AR_SREV_9340(ah) ? 0x40d8 : \
+ (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094))
#define AR_PCIE_MSI_ENABLE 0x00000001
-#define AR_INTR_PRIO_SYNC_ENABLE 0x40c4
-#define AR_INTR_PRIO_ASYNC_MASK 0x40c8
-#define AR_INTR_PRIO_SYNC_MASK 0x40cc
-#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4
+#define AR_INTR_PRIO_SYNC_ENABLE (AR_SREV_9340(ah) ? 0x4088 : 0x40c4)
+#define AR_INTR_PRIO_ASYNC_MASK (AR_SREV_9340(ah) ? 0x408c : 0x40c8)
+#define AR_INTR_PRIO_SYNC_MASK (AR_SREV_9340(ah) ? 0x4090 : 0x40cc)
+#define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4)
#define AR_ENT_OTP 0x40d8
#define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000
#define AR_ENT_OTP_MPSD 0x00800000
-#define AR_CH0_BB_DPLL2 0x16184
+
+#define AR_CH0_BB_DPLL1 0x16180
+#define AR_CH0_BB_DPLL1_REFDIV 0xF8000000
+#define AR_CH0_BB_DPLL1_REFDIV_S 27
+#define AR_CH0_BB_DPLL1_NINI 0x07FC0000
+#define AR_CH0_BB_DPLL1_NINI_S 18
+#define AR_CH0_BB_DPLL1_NFRAC 0x0003FFFF
+#define AR_CH0_BB_DPLL1_NFRAC_S 0
+
+#define AR_CH0_BB_DPLL2 0x16184
+#define AR_CH0_BB_DPLL2_LOCAL_PLL 0x40000000
+#define AR_CH0_BB_DPLL2_LOCAL_PLL_S 30
+#define AR_CH0_DPLL2_KI 0x3C000000
+#define AR_CH0_DPLL2_KI_S 26
+#define AR_CH0_DPLL2_KD 0x03F80000
+#define AR_CH0_DPLL2_KD_S 19
+#define AR_CH0_BB_DPLL2_EN_NEGTRIG 0x00040000
+#define AR_CH0_BB_DPLL2_EN_NEGTRIG_S 18
+#define AR_CH0_BB_DPLL2_PLL_PWD 0x00010000
+#define AR_CH0_BB_DPLL2_PLL_PWD_S 16
+#define AR_CH0_BB_DPLL2_OUTDIV 0x0000E000
+#define AR_CH0_BB_DPLL2_OUTDIV_S 13
+
#define AR_CH0_BB_DPLL3 0x16188
+#define AR_CH0_BB_DPLL3_PHASE_SHIFT 0x3F800000
+#define AR_CH0_BB_DPLL3_PHASE_SHIFT_S 23
+
#define AR_CH0_DDR_DPLL2 0x16244
#define AR_CH0_DDR_DPLL3 0x16248
-#define AR_CH0_DPLL2_KD 0x03F80000
-#define AR_CH0_DPLL2_KD_S 19
-#define AR_CH0_DPLL2_KI 0x3C000000
-#define AR_CH0_DPLL2_KI_S 26
#define AR_CH0_DPLL3_PHASE_SHIFT 0x3F800000
#define AR_CH0_DPLL3_PHASE_SHIFT_S 23
#define AR_PHY_CCA_NOM_VAL_2GHZ -118
@@ -1144,6 +1182,7 @@ enum {
#define AR_RTC_PLL_REFDIV_5 0x000000c0
#define AR_RTC_PLL_CLKSEL 0x00000300
#define AR_RTC_PLL_CLKSEL_S 8
+#define AR_RTC_PLL_BYPASS 0x00010000
#define PLL3 0x16188
#define PLL3_DO_MEAS_MASK 0x40000000
@@ -1190,7 +1229,8 @@ enum {
/* RTC_DERIVED_* - only for AR9100 */
-#define AR_RTC_DERIVED_CLK (AR_RTC_BASE + 0x0038)
+#define AR_RTC_DERIVED_CLK \
+ (AR_SREV_9100(ah) ? (AR_RTC_BASE + 0x0038) : 0x7038)
#define AR_RTC_DERIVED_CLK_PERIOD 0x0000fffe
#define AR_RTC_DERIVED_CLK_PERIOD_S 1
@@ -1396,6 +1436,7 @@ enum {
#define AR_STA_ID1_PCF 0x00100000
#define AR_STA_ID1_USE_DEFANT 0x00200000
#define AR_STA_ID1_DEFANT_UPDATE 0x00400000
+#define AR_STA_ID1_AR9100_BA_FIX 0x00400000
#define AR_STA_ID1_RTS_USE_DEF 0x00800000
#define AR_STA_ID1_ACKCTS_6MB 0x01000000
#define AR_STA_ID1_BASE_RATE_11B 0x02000000
@@ -1668,6 +1709,22 @@ enum {
#define AR_BTCOEX_WL_WGHT 0xffff0000
#define AR_BTCOEX_WL_WGHT_S 16
+#define AR_BT_COEX_WL_WEIGHTS0 0x8174
+#define AR_BT_COEX_WL_WEIGHTS1 0x81c4
+
+#define AR_BT_COEX_BT_WEIGHTS0 0x83ac
+#define AR_BT_COEX_BT_WEIGHTS1 0x83b0
+#define AR_BT_COEX_BT_WEIGHTS2 0x83b4
+#define AR_BT_COEX_BT_WEIGHTS3 0x83b8
+
+#define AR9300_BT_WGHT 0xcccc4444
+#define AR9300_STOMP_ALL_WLAN_WGHT0 0xfffffff0
+#define AR9300_STOMP_ALL_WLAN_WGHT1 0xfffffff0
+#define AR9300_STOMP_LOW_WLAN_WGHT0 0x88888880
+#define AR9300_STOMP_LOW_WLAN_WGHT1 0x88888880
+#define AR9300_STOMP_NONE_WLAN_WGHT0 0x00000000
+#define AR9300_STOMP_NONE_WLAN_WGHT1 0x00000000
+
#define AR_BT_COEX_MODE2 0x817c
#define AR_BT_BCN_MISS_THRESH 0x000000ff
#define AR_BT_BCN_MISS_THRESH_S 0
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index d3d24904f62..f9b1eb4853c 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -23,20 +23,18 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
return "WMI_ECHO_CMDID";
case WMI_ACCESS_MEMORY_CMDID:
return "WMI_ACCESS_MEMORY_CMDID";
+ case WMI_GET_FW_VERSION:
+ return "WMI_GET_FW_VERSION";
case WMI_DISABLE_INTR_CMDID:
return "WMI_DISABLE_INTR_CMDID";
case WMI_ENABLE_INTR_CMDID:
return "WMI_ENABLE_INTR_CMDID";
- case WMI_RX_LINK_CMDID:
- return "WMI_RX_LINK_CMDID";
case WMI_ATH_INIT_CMDID:
return "WMI_ATH_INIT_CMDID";
case WMI_ABORT_TXQ_CMDID:
return "WMI_ABORT_TXQ_CMDID";
case WMI_STOP_TX_DMA_CMDID:
return "WMI_STOP_TX_DMA_CMDID";
- case WMI_STOP_DMA_RECV_CMDID:
- return "WMI_STOP_DMA_RECV_CMDID";
case WMI_ABORT_TX_DMA_CMDID:
return "WMI_ABORT_TX_DMA_CMDID";
case WMI_DRAIN_TXQ_CMDID:
@@ -51,8 +49,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
return "WMI_FLUSH_RECV_CMDID";
case WMI_SET_MODE_CMDID:
return "WMI_SET_MODE_CMDID";
- case WMI_RESET_CMDID:
- return "WMI_RESET_CMDID";
case WMI_NODE_CREATE_CMDID:
return "WMI_NODE_CREATE_CMDID";
case WMI_NODE_REMOVE_CMDID:
@@ -61,8 +57,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
return "WMI_VAP_REMOVE_CMDID";
case WMI_VAP_CREATE_CMDID:
return "WMI_VAP_CREATE_CMDID";
- case WMI_BEACON_UPDATE_CMDID:
- return "WMI_BEACON_UPDATE_CMDID";
case WMI_REG_READ_CMDID:
return "WMI_REG_READ_CMDID";
case WMI_REG_WRITE_CMDID:
@@ -71,22 +65,22 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
return "WMI_RC_STATE_CHANGE_CMDID";
case WMI_RC_RATE_UPDATE_CMDID:
return "WMI_RC_RATE_UPDATE_CMDID";
- case WMI_DEBUG_INFO_CMDID:
- return "WMI_DEBUG_INFO_CMDID";
- case WMI_HOST_ATTACH:
- return "WMI_HOST_ATTACH";
case WMI_TARGET_IC_UPDATE_CMDID:
return "WMI_TARGET_IC_UPDATE_CMDID";
- case WMI_TGT_STATS_CMDID:
- return "WMI_TGT_STATS_CMDID";
case WMI_TX_AGGR_ENABLE_CMDID:
return "WMI_TX_AGGR_ENABLE_CMDID";
case WMI_TGT_DETACH_CMDID:
return "WMI_TGT_DETACH_CMDID";
- case WMI_TGT_TXQ_ENABLE_CMDID:
- return "WMI_TGT_TXQ_ENABLE_CMDID";
- case WMI_AGGR_LIMIT_CMD:
- return "WMI_AGGR_LIMIT_CMD";
+ case WMI_NODE_UPDATE_CMDID:
+ return "WMI_NODE_UPDATE_CMDID";
+ case WMI_INT_STATS_CMDID:
+ return "WMI_INT_STATS_CMDID";
+ case WMI_TX_STATS_CMDID:
+ return "WMI_TX_STATS_CMDID";
+ case WMI_RX_STATS_CMDID:
+ return "WMI_RX_STATS_CMDID";
+ case WMI_BITRATE_MASK_CMDID:
+ return "WMI_BITRATE_MASK_CMDID";
}
return "Bogus";
@@ -102,9 +96,15 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
wmi->drv_priv = priv;
wmi->stopped = false;
+ skb_queue_head_init(&wmi->wmi_event_queue);
+ spin_lock_init(&wmi->wmi_lock);
+ spin_lock_init(&wmi->event_lock);
mutex_init(&wmi->op_mutex);
mutex_init(&wmi->multi_write_mutex);
init_completion(&wmi->cmd_wait);
+ INIT_LIST_HEAD(&wmi->pending_tx_events);
+ tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet,
+ (unsigned long)wmi);
return wmi;
}
@@ -120,11 +120,65 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv)
kfree(priv->wmi);
}
-void ath9k_swba_tasklet(unsigned long data)
+void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv)
{
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
+ unsigned long flags;
- ath9k_htc_swba(priv, priv->wmi->beacon_pending);
+ tasklet_kill(&priv->wmi->wmi_event_tasklet);
+ spin_lock_irqsave(&priv->wmi->wmi_lock, flags);
+ __skb_queue_purge(&priv->wmi->wmi_event_queue);
+ spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags);
+}
+
+void ath9k_wmi_event_tasklet(unsigned long data)
+{
+ struct wmi *wmi = (struct wmi *)data;
+ struct ath9k_htc_priv *priv = wmi->drv_priv;
+ struct wmi_cmd_hdr *hdr;
+ void *wmi_event;
+ struct wmi_event_swba *swba;
+ struct sk_buff *skb = NULL;
+ unsigned long flags;
+ u16 cmd_id;
+
+ do {
+ spin_lock_irqsave(&wmi->wmi_lock, flags);
+ skb = __skb_dequeue(&wmi->wmi_event_queue);
+ if (!skb) {
+ spin_unlock_irqrestore(&wmi->wmi_lock, flags);
+ return;
+ }
+ spin_unlock_irqrestore(&wmi->wmi_lock, flags);
+
+ hdr = (struct wmi_cmd_hdr *) skb->data;
+ cmd_id = be16_to_cpu(hdr->command_id);
+ wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
+
+ switch (cmd_id) {
+ case WMI_SWBA_EVENTID:
+ swba = (struct wmi_event_swba *) wmi_event;
+ ath9k_htc_swba(priv, swba);
+ break;
+ case WMI_FATAL_EVENTID:
+ ieee80211_queue_work(wmi->drv_priv->hw,
+ &wmi->drv_priv->fatal_work);
+ break;
+ case WMI_TXSTATUS_EVENTID:
+ spin_lock_bh(&priv->tx.tx_lock);
+ if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) {
+ spin_unlock_bh(&priv->tx.tx_lock);
+ break;
+ }
+ spin_unlock_bh(&priv->tx.tx_lock);
+
+ ath9k_htc_txstatus(priv, wmi_event);
+ break;
+ default:
+ break;
+ }
+
+ kfree_skb(skb);
+ } while (1);
}
void ath9k_fatal_work(struct work_struct *work)
@@ -153,10 +207,6 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
struct wmi *wmi = (struct wmi *) priv;
struct wmi_cmd_hdr *hdr;
u16 cmd_id;
- void *wmi_event;
-#ifdef CONFIG_ATH9K_HTC_DEBUGFS
- __be32 txrate;
-#endif
if (unlikely(wmi->stopped))
goto free_skb;
@@ -165,26 +215,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
cmd_id = be16_to_cpu(hdr->command_id);
if (cmd_id & 0x1000) {
- wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
- switch (cmd_id) {
- case WMI_SWBA_EVENTID:
- wmi->beacon_pending = *(u8 *)wmi_event;
- tasklet_schedule(&wmi->drv_priv->swba_tasklet);
- break;
- case WMI_FATAL_EVENTID:
- ieee80211_queue_work(wmi->drv_priv->hw,
- &wmi->drv_priv->fatal_work);
- break;
- case WMI_TXRATE_EVENTID:
-#ifdef CONFIG_ATH9K_HTC_DEBUGFS
- txrate = ((struct wmi_event_txrate *)wmi_event)->txrate;
- wmi->drv_priv->debug.txrate = be32_to_cpu(txrate);
-#endif
- break;
- default:
- break;
- }
- kfree_skb(skb);
+ spin_lock(&wmi->wmi_lock);
+ __skb_queue_tail(&wmi->wmi_event_queue, skb);
+ spin_unlock(&wmi->wmi_lock);
+ tasklet_schedule(&wmi->wmi_event_tasklet);
return;
}
@@ -243,7 +277,7 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi,
hdr->command_id = cpu_to_be16(cmd);
hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id);
- return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL);
+ return htc_send_epid(wmi->htc, skb, wmi->ctrl_epid);
}
int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
index 42084277522..6095eeb6e02 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.h
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -17,7 +17,6 @@
#ifndef WMI_H
#define WMI_H
-
struct wmi_event_txrate {
__be32 txrate;
struct {
@@ -31,18 +30,65 @@ struct wmi_cmd_hdr {
__be16 seq_no;
} __packed;
+struct wmi_fw_version {
+ __be16 major;
+ __be16 minor;
+
+} __packed;
+
+struct wmi_event_swba {
+ __be64 tsf;
+ u8 beacon_pending;
+};
+
+/*
+ * 64 - HTC header - WMI header - 1 / txstatus
+ * And some other hdr. space is also accounted for.
+ * 12 seems to be the magic number.
+ */
+#define HTC_MAX_TX_STATUS 12
+
+#define ATH9K_HTC_TXSTAT_ACK BIT(0)
+#define ATH9K_HTC_TXSTAT_FILT BIT(1)
+#define ATH9K_HTC_TXSTAT_RTC_CTS BIT(2)
+#define ATH9K_HTC_TXSTAT_MCS BIT(3)
+#define ATH9K_HTC_TXSTAT_CW40 BIT(4)
+#define ATH9K_HTC_TXSTAT_SGI BIT(5)
+
+/*
+ * Legacy rates are indicated as indices.
+ * HT rates are indicated as dot11 numbers.
+ * This allows us to resrict the rate field
+ * to 4 bits.
+ */
+#define ATH9K_HTC_TXSTAT_RATE 0x0f
+#define ATH9K_HTC_TXSTAT_RATE_S 0
+
+#define ATH9K_HTC_TXSTAT_EPID 0xf0
+#define ATH9K_HTC_TXSTAT_EPID_S 4
+
+struct __wmi_event_txstatus {
+ u8 cookie;
+ u8 ts_rate; /* Also holds EP ID */
+ u8 ts_flags;
+};
+
+struct wmi_event_txstatus {
+ u8 cnt;
+ struct __wmi_event_txstatus txstatus[HTC_MAX_TX_STATUS];
+} __packed;
+
enum wmi_cmd_id {
WMI_ECHO_CMDID = 0x0001,
WMI_ACCESS_MEMORY_CMDID,
/* Commands to Target */
+ WMI_GET_FW_VERSION,
WMI_DISABLE_INTR_CMDID,
WMI_ENABLE_INTR_CMDID,
- WMI_RX_LINK_CMDID,
WMI_ATH_INIT_CMDID,
WMI_ABORT_TXQ_CMDID,
WMI_STOP_TX_DMA_CMDID,
- WMI_STOP_DMA_RECV_CMDID,
WMI_ABORT_TX_DMA_CMDID,
WMI_DRAIN_TXQ_CMDID,
WMI_DRAIN_TXQ_ALL_CMDID,
@@ -50,24 +96,22 @@ enum wmi_cmd_id {
WMI_STOP_RECV_CMDID,
WMI_FLUSH_RECV_CMDID,
WMI_SET_MODE_CMDID,
- WMI_RESET_CMDID,
WMI_NODE_CREATE_CMDID,
WMI_NODE_REMOVE_CMDID,
WMI_VAP_REMOVE_CMDID,
WMI_VAP_CREATE_CMDID,
- WMI_BEACON_UPDATE_CMDID,
WMI_REG_READ_CMDID,
WMI_REG_WRITE_CMDID,
WMI_RC_STATE_CHANGE_CMDID,
WMI_RC_RATE_UPDATE_CMDID,
- WMI_DEBUG_INFO_CMDID,
- WMI_HOST_ATTACH,
WMI_TARGET_IC_UPDATE_CMDID,
- WMI_TGT_STATS_CMDID,
WMI_TX_AGGR_ENABLE_CMDID,
WMI_TGT_DETACH_CMDID,
- WMI_TGT_TXQ_ENABLE_CMDID,
- WMI_AGGR_LIMIT_CMD = 0x0026,
+ WMI_NODE_UPDATE_CMDID,
+ WMI_INT_STATS_CMDID,
+ WMI_TX_STATS_CMDID,
+ WMI_RX_STATS_CMDID,
+ WMI_BITRATE_MASK_CMDID,
};
enum wmi_event_id {
@@ -76,9 +120,8 @@ enum wmi_event_id {
WMI_FATAL_EVENTID,
WMI_TXTO_EVENTID,
WMI_BMISS_EVENTID,
- WMI_WLAN_TXCOMP_EVENTID,
WMI_DELBA_EVENTID,
- WMI_TXRATE_EVENTID,
+ WMI_TXSTATUS_EVENTID,
};
#define MAX_CMD_NUMBER 62
@@ -88,6 +131,12 @@ struct register_write {
__be32 val;
};
+struct ath9k_htc_tx_event {
+ int count;
+ struct __wmi_event_txstatus txs;
+ struct list_head list;
+};
+
struct wmi {
struct ath9k_htc_priv *drv_priv;
struct htc_target *htc;
@@ -95,12 +144,16 @@ struct wmi {
struct mutex op_mutex;
struct completion cmd_wait;
enum wmi_cmd_id last_cmd_id;
+ struct sk_buff_head wmi_event_queue;
+ struct tasklet_struct wmi_event_tasklet;
u16 tx_seq_id;
u8 *cmd_rsp_buf;
u32 cmd_rsp_len;
bool stopped;
- u8 beacon_pending;
+ struct list_head pending_tx_events;
+ spinlock_t event_lock;
+
spinlock_t wmi_lock;
atomic_t mwrite_cnt;
@@ -117,8 +170,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
u8 *cmd_buf, u32 cmd_len,
u8 *rsp_buf, u32 rsp_len,
u32 timeout);
-void ath9k_swba_tasklet(unsigned long data);
+void ath9k_wmi_event_tasklet(unsigned long data);
void ath9k_fatal_work(struct work_struct *work);
+void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv);
#define WMI_CMD(_wmi_cmd) \
do { \
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 88fa7fdffd0..97dd1fac98b 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -357,6 +357,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
struct ath_frame_info *fi;
int nframes;
u8 tidno;
+ bool clear_filter;
skb = bf->bf_mpdu;
hdr = (struct ieee80211_hdr *)skb->data;
@@ -441,22 +442,24 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
/* transmit completion */
acked_cnt++;
} else {
- if (!(tid->state & AGGR_CLEANUP) && retry) {
- if (fi->retries < ATH_MAX_SW_RETRIES) {
- ath_tx_set_retry(sc, txq, bf->bf_mpdu);
- txpending = 1;
- } else {
- bf->bf_state.bf_type |= BUF_XRETRY;
- txfail = 1;
- sendbar = 1;
- txfail_cnt++;
- }
- } else {
+ if ((tid->state & AGGR_CLEANUP) || !retry) {
/*
* cleanup in progress, just fail
* the un-acked sub-frames
*/
txfail = 1;
+ } else if (fi->retries < ATH_MAX_SW_RETRIES) {
+ if (!(ts->ts_status & ATH9K_TXERR_FILT) ||
+ !an->sleeping)
+ ath_tx_set_retry(sc, txq, bf->bf_mpdu);
+
+ clear_filter = true;
+ txpending = 1;
+ } else {
+ bf->bf_state.bf_type |= BUF_XRETRY;
+ txfail = 1;
+ sendbar = 1;
+ txfail_cnt++;
}
}
@@ -496,6 +499,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
!txfail, sendbar);
} else {
/* retry the un-acked ones */
+ ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false);
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) {
if (bf->bf_next == NULL && bf_last->bf_stale) {
struct ath_buf *tbf;
@@ -546,7 +550,12 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
/* prepend un-acked frames to the beginning of the pending frame queue */
if (!list_empty(&bf_pending)) {
+ if (an->sleeping)
+ ieee80211_sta_set_tim(sta);
+
spin_lock_bh(&txq->axq_lock);
+ if (clear_filter)
+ tid->ac->clear_ps_filter = true;
list_splice(&bf_pending, &tid->buf_q);
ath_tx_queue_tid(txq, tid);
spin_unlock_bh(&txq->axq_lock);
@@ -816,6 +825,11 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
bf = list_first_entry(&bf_q, struct ath_buf, list);
bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list);
+ if (tid->ac->clear_ps_filter) {
+ tid->ac->clear_ps_filter = false;
+ ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true);
+ }
+
/* if only one frame, send as non-aggregate */
if (bf == bf->bf_lastbf) {
fi = get_frame_info(bf->bf_mpdu);
@@ -896,6 +910,67 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
ath_tx_flush_tid(sc, txtid);
}
+bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an)
+{
+ struct ath_atx_tid *tid;
+ struct ath_atx_ac *ac;
+ struct ath_txq *txq;
+ bool buffered = false;
+ int tidno;
+
+ for (tidno = 0, tid = &an->tid[tidno];
+ tidno < WME_NUM_TID; tidno++, tid++) {
+
+ if (!tid->sched)
+ continue;
+
+ ac = tid->ac;
+ txq = ac->txq;
+
+ spin_lock_bh(&txq->axq_lock);
+
+ if (!list_empty(&tid->buf_q))
+ buffered = true;
+
+ tid->sched = false;
+ list_del(&tid->list);
+
+ if (ac->sched) {
+ ac->sched = false;
+ list_del(&ac->list);
+ }
+
+ spin_unlock_bh(&txq->axq_lock);
+ }
+
+ return buffered;
+}
+
+void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
+{
+ struct ath_atx_tid *tid;
+ struct ath_atx_ac *ac;
+ struct ath_txq *txq;
+ int tidno;
+
+ for (tidno = 0, tid = &an->tid[tidno];
+ tidno < WME_NUM_TID; tidno++, tid++) {
+
+ ac = tid->ac;
+ txq = ac->txq;
+
+ spin_lock_bh(&txq->axq_lock);
+ ac->clear_ps_filter = true;
+
+ if (!list_empty(&tid->buf_q) && !tid->paused) {
+ ath_tx_queue_tid(txq, tid);
+ ath_txq_schedule(sc, txq);
+ }
+
+ spin_unlock_bh(&txq->axq_lock);
+ }
+}
+
void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
{
struct ath_atx_tid *txtid;
@@ -1451,7 +1526,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
struct ieee80211_hdr *hdr;
struct ath_frame_info *fi = get_frame_info(skb);
- struct ath_node *an;
+ struct ath_node *an = NULL;
struct ath_atx_tid *tid;
enum ath9k_key_type keytype;
u16 seqno = 0;
@@ -1459,11 +1534,13 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
+ if (sta)
+ an = (struct ath_node *) sta->drv_priv;
+
hdr = (struct ieee80211_hdr *)skb->data;
- if (sta && ieee80211_is_data_qos(hdr->frame_control) &&
+ if (an && ieee80211_is_data_qos(hdr->frame_control) &&
conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) {
- an = (struct ath_node *) sta->drv_priv;
tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
/*
@@ -1479,6 +1556,8 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
memset(fi, 0, sizeof(*fi));
if (hw_key)
fi->keyix = hw_key->hw_key_idx;
+ else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0)
+ fi->keyix = an->ps_key;
else
fi->keyix = ATH9K_TXKEYIX_INVALID;
fi->keytype = keytype;
@@ -1491,7 +1570,6 @@ static int setup_tx_flags(struct sk_buff *skb)
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
int flags = 0;
- flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
flags |= ATH9K_TXDESC_INTREQ;
if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
@@ -1585,8 +1663,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
rix = rates[i].idx;
series[i].Tries = rates[i].count;
- if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) ||
- (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) {
+ if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
flags |= ATH9K_TXDESC_RTSENA;
} else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
@@ -1655,8 +1732,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
!is_pspoll, ctsrate,
0, series, 4, flags);
- if (sc->config.ath_aggr_prot && flags)
- ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192);
}
static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw,
@@ -1754,6 +1829,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
if (txctl->paprd)
bf->bf_state.bfs_paprd_timestamp = jiffies;
+ if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
+ ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true);
+
ath_tx_send_normal(sc, txctl->txq, tid, &bf_head);
}
@@ -1767,6 +1845,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_sta *sta = info->control.sta;
+ struct ieee80211_vif *vif = info->control.vif;
struct ath_softc *sc = hw->priv;
struct ath_txq *txq = txctl->txq;
struct ath_buf *bf;
@@ -1804,6 +1883,11 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
memmove(skb->data, skb->data + padsize, padpos);
}
+ if ((vif && vif->type != NL80211_IFTYPE_AP &&
+ vif->type != NL80211_IFTYPE_AP_VLAN) ||
+ !ieee80211_is_data(hdr->frame_control))
+ info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
+
setup_frame_info(hw, skb, frmlen);
/*
@@ -1980,7 +2064,7 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
if (ieee80211_is_data(hdr->frame_control) &&
(ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN |
ATH9K_TX_DELIM_UNDERRUN)) &&
- ah->tx_trig_level >= sc->sc_ah->caps.tx_triglevel_max)
+ ah->tx_trig_level >= sc->sc_ah->config.max_txtrig_level)
tx_info->status.rates[tx_rateindex].count =
hw->max_rate_tries;
}
@@ -2099,28 +2183,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
}
}
-static void ath_hw_pll_work(struct work_struct *work)
-{
- struct ath_softc *sc = container_of(work, struct ath_softc,
- hw_pll_work.work);
- static int count;
-
- if (AR_SREV_9485(sc->sc_ah)) {
- if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) {
- count++;
-
- if (count == 3) {
- /* Rx is hung for more than 500ms. Reset it */
- ath_reset(sc, true);
- count = 0;
- }
- } else
- count = 0;
-
- ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
- }
-}
-
static void ath_tx_complete_poll_work(struct work_struct *work)
{
struct ath_softc *sc = container_of(work, struct ath_softc,
@@ -2144,33 +2206,6 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
} else {
txq->axq_tx_inprogress = true;
}
- } else {
- /* If the queue has pending buffers, then it
- * should be doing tx work (and have axq_depth).
- * Shouldn't get to this state I think..but
- * we do.
- */
- if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) &&
- (txq->pending_frames > 0 ||
- !list_empty(&txq->axq_acq) ||
- txq->stopped)) {
- ath_err(ath9k_hw_common(sc->sc_ah),
- "txq: %p axq_qnum: %u,"
- " mac80211_qnum: %i"
- " axq_link: %p"
- " pending frames: %i"
- " axq_acq empty: %i"
- " stopped: %i"
- " axq_depth: 0 Attempting to"
- " restart tx logic.\n",
- txq, txq->axq_qnum,
- txq->mac80211_qnum,
- txq->axq_link,
- txq->pending_frames,
- list_empty(&txq->axq_acq),
- txq->stopped);
- ath_txq_schedule(sc, txq);
- }
}
spin_unlock_bh(&txq->axq_lock);
}
@@ -2342,7 +2377,6 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
}
INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
- INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
error = ath_tx_edma_init(sc);
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index 3d4ed586373..bb578690935 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -448,6 +448,8 @@ struct carl9170_ba_stats {
struct carl9170_sta_info {
bool ht_sta;
+ bool sleeping;
+ atomic_t pending_frames;
unsigned int ampdu_max_len;
struct carl9170_sta_tid *agg[CARL9170_NUM_TID];
struct carl9170_ba_stats stats[CARL9170_NUM_TID];
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 89fe60accf8..7d5c65ea94e 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -883,7 +883,7 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw,
* then checking the error flags, later.
*/
- if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
+ if (*new_flags & FIF_ALLMULTI)
multicast = ~0ULL;
if (multicast != ar->cur_mc_hash)
@@ -1193,6 +1193,8 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw,
struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
unsigned int i;
+ atomic_set(&sta_info->pending_frames, 0);
+
if (sta->ht_cap.ht_supported) {
if (sta->ht_cap.ampdu_density > 6) {
/*
@@ -1467,99 +1469,17 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw,
enum sta_notify_cmd cmd,
struct ieee80211_sta *sta)
{
- struct ar9170 *ar = hw->priv;
struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
- struct sk_buff *skb, *tmp;
- struct sk_buff_head free;
- int i;
switch (cmd) {
case STA_NOTIFY_SLEEP:
- /*
- * Since the peer is no longer listening, we have to return
- * as many SKBs as possible back to the mac80211 stack.
- * It will deal with the retry procedure, once the peer
- * has become available again.
- *
- * NB: Ideally, the driver should return the all frames in
- * the correct, ascending order. However, I think that this
- * functionality should be implemented in the stack and not
- * here...
- */
-
- __skb_queue_head_init(&free);
-
- if (sta->ht_cap.ht_supported) {
- rcu_read_lock();
- for (i = 0; i < CARL9170_NUM_TID; i++) {
- struct carl9170_sta_tid *tid_info;
-
- tid_info = rcu_dereference(sta_info->agg[i]);
-
- if (!tid_info)
- continue;
-
- spin_lock_bh(&ar->tx_ampdu_list_lock);
- if (tid_info->state >
- CARL9170_TID_STATE_SUSPEND)
- tid_info->state =
- CARL9170_TID_STATE_SUSPEND;
- spin_unlock_bh(&ar->tx_ampdu_list_lock);
-
- spin_lock_bh(&tid_info->lock);
- while ((skb = __skb_dequeue(&tid_info->queue)))
- __skb_queue_tail(&free, skb);
- spin_unlock_bh(&tid_info->lock);
- }
- rcu_read_unlock();
- }
-
- for (i = 0; i < ar->hw->queues; i++) {
- spin_lock_bh(&ar->tx_pending[i].lock);
- skb_queue_walk_safe(&ar->tx_pending[i], skb, tmp) {
- struct _carl9170_tx_superframe *super;
- struct ieee80211_hdr *hdr;
- struct ieee80211_tx_info *info;
-
- super = (void *) skb->data;
- hdr = (void *) super->frame_data;
-
- if (compare_ether_addr(hdr->addr1, sta->addr))
- continue;
-
- __skb_unlink(skb, &ar->tx_pending[i]);
-
- info = IEEE80211_SKB_CB(skb);
- if (info->flags & IEEE80211_TX_CTL_AMPDU)
- atomic_dec(&ar->tx_ampdu_upload);
-
- carl9170_tx_status(ar, skb, false);
- }
- spin_unlock_bh(&ar->tx_pending[i].lock);
- }
-
- while ((skb = __skb_dequeue(&free)))
- carl9170_tx_status(ar, skb, false);
-
+ sta_info->sleeping = true;
+ if (atomic_read(&sta_info->pending_frames))
+ ieee80211_sta_block_awake(hw, sta, true);
break;
case STA_NOTIFY_AWAKE:
- if (!sta->ht_cap.ht_supported)
- return;
-
- rcu_read_lock();
- for (i = 0; i < CARL9170_NUM_TID; i++) {
- struct carl9170_sta_tid *tid_info;
-
- tid_info = rcu_dereference(sta_info->agg[i]);
-
- if (!tid_info)
- continue;
-
- if ((tid_info->state == CARL9170_TID_STATE_SUSPEND))
- tid_info->state = CARL9170_TID_STATE_IDLE;
- }
- rcu_read_unlock();
+ sta_info->sleeping = false;
break;
}
}
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index cb70ed7ec5c..e94084fcf6f 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -104,12 +104,60 @@ static void carl9170_tx_accounting(struct ar9170 *ar, struct sk_buff *skb)
spin_unlock_bh(&ar->tx_stats_lock);
}
+/* needs rcu_read_lock */
+static struct ieee80211_sta *__carl9170_get_tx_sta(struct ar9170 *ar,
+ struct sk_buff *skb)
+{
+ struct _carl9170_tx_superframe *super = (void *) skb->data;
+ struct ieee80211_hdr *hdr = (void *) super->frame_data;
+ struct ieee80211_vif *vif;
+ unsigned int vif_id;
+
+ vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
+ CARL9170_TX_SUPER_MISC_VIF_ID_S;
+
+ if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC))
+ return NULL;
+
+ vif = rcu_dereference(ar->vif_priv[vif_id].vif);
+ if (unlikely(!vif))
+ return NULL;
+
+ /*
+ * Normally we should use wrappers like ieee80211_get_DA to get
+ * the correct peer ieee80211_sta.
+ *
+ * But there is a problem with indirect traffic (broadcasts, or
+ * data which is designated for other stations) in station mode.
+ * The frame will be directed to the AP for distribution and not
+ * to the actual destination.
+ */
+
+ return ieee80211_find_sta(vif, hdr->addr1);
+}
+
+static void carl9170_tx_ps_unblock(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct ieee80211_sta *sta;
+ struct carl9170_sta_info *sta_info;
+
+ rcu_read_lock();
+ sta = __carl9170_get_tx_sta(ar, skb);
+ if (unlikely(!sta))
+ goto out_rcu;
+
+ sta_info = (struct carl9170_sta_info *) sta->drv_priv;
+ if (atomic_dec_return(&sta_info->pending_frames) == 0)
+ ieee80211_sta_block_awake(ar->hw, sta, false);
+
+out_rcu:
+ rcu_read_unlock();
+}
+
static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb)
{
- struct ieee80211_tx_info *txinfo;
int queue;
- txinfo = IEEE80211_SKB_CB(skb);
queue = skb_get_queue_mapping(skb);
spin_lock_bh(&ar->tx_stats_lock);
@@ -135,6 +183,7 @@ static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb)
}
spin_unlock_bh(&ar->tx_stats_lock);
+
if (atomic_dec_and_test(&ar->tx_total_queued))
complete(&ar->tx_flush);
}
@@ -329,13 +378,9 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
{
struct _carl9170_tx_superframe *super = (void *) skb->data;
struct ieee80211_hdr *hdr = (void *) super->frame_data;
- struct ieee80211_tx_info *tx_info;
- struct carl9170_tx_info *ar_info;
- struct carl9170_sta_info *sta_info;
struct ieee80211_sta *sta;
+ struct carl9170_sta_info *sta_info;
struct carl9170_sta_tid *tid_info;
- struct ieee80211_vif *vif;
- unsigned int vif_id;
u8 tid;
if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) ||
@@ -343,30 +388,8 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
(!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR))))
return;
- tx_info = IEEE80211_SKB_CB(skb);
- ar_info = (void *) tx_info->rate_driver_data;
-
- vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
- CARL9170_TX_SUPER_MISC_VIF_ID_S;
-
- if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC))
- return;
-
rcu_read_lock();
- vif = rcu_dereference(ar->vif_priv[vif_id].vif);
- if (unlikely(!vif))
- goto out_rcu;
-
- /*
- * Normally we should use wrappers like ieee80211_get_DA to get
- * the correct peer ieee80211_sta.
- *
- * But there is a problem with indirect traffic (broadcasts, or
- * data which is designated for other stations) in station mode.
- * The frame will be directed to the AP for distribution and not
- * to the actual destination.
- */
- sta = ieee80211_find_sta(vif, hdr->addr1);
+ sta = __carl9170_get_tx_sta(ar, skb);
if (unlikely(!sta))
goto out_rcu;
@@ -427,6 +450,7 @@ void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
if (txinfo->flags & IEEE80211_TX_CTL_AMPDU)
carl9170_tx_status_process_ampdu(ar, skb, txinfo);
+ carl9170_tx_ps_unblock(ar, skb);
carl9170_tx_put_skb(skb);
}
@@ -540,11 +564,7 @@ static void carl9170_tx_ampdu_timeout(struct ar9170 *ar)
struct sk_buff *skb;
struct ieee80211_tx_info *txinfo;
struct carl9170_tx_info *arinfo;
- struct _carl9170_tx_superframe *super;
struct ieee80211_sta *sta;
- struct ieee80211_vif *vif;
- struct ieee80211_hdr *hdr;
- unsigned int vif_id;
rcu_read_lock();
list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
@@ -562,20 +582,7 @@ static void carl9170_tx_ampdu_timeout(struct ar9170 *ar)
msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT)))
goto unlock;
- super = (void *) skb->data;
- hdr = (void *) super->frame_data;
-
- vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
- CARL9170_TX_SUPER_MISC_VIF_ID_S;
-
- if (WARN_ON(vif_id >= AR9170_MAX_VIRTUAL_MAC))
- goto unlock;
-
- vif = rcu_dereference(ar->vif_priv[vif_id].vif);
- if (WARN_ON(!vif))
- goto unlock;
-
- sta = ieee80211_find_sta(vif, hdr->addr1);
+ sta = __carl9170_get_tx_sta(ar, skb);
if (WARN_ON(!sta))
goto unlock;
@@ -611,7 +618,6 @@ static void __carl9170_tx_process_status(struct ar9170 *ar,
{
struct sk_buff *skb;
struct ieee80211_tx_info *txinfo;
- struct carl9170_tx_info *arinfo;
unsigned int r, t, q;
bool success = true;
@@ -627,7 +633,6 @@ static void __carl9170_tx_process_status(struct ar9170 *ar,
}
txinfo = IEEE80211_SKB_CB(skb);
- arinfo = (void *) txinfo->rate_driver_data;
if (!(info & CARL9170_TX_STATUS_SUCCESS))
success = false;
@@ -1199,15 +1204,6 @@ static struct sk_buff *carl9170_tx_pick_skb(struct ar9170 *ar,
arinfo = (void *) info->rate_driver_data;
arinfo->timeout = jiffies;
-
- /*
- * increase ref count to "2".
- * Ref counting is the easiest way to solve the race between
- * the the urb's completion routine: carl9170_tx_callback and
- * wlan tx status functions: carl9170_tx_status/janitor.
- */
- carl9170_tx_get_skb(skb);
-
return skb;
err_unlock:
@@ -1228,6 +1224,36 @@ void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb)
__carl9170_tx_process_status(ar, super->s.cookie, q);
}
+static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct ieee80211_sta *sta;
+ struct carl9170_sta_info *sta_info;
+
+ rcu_read_lock();
+ sta = __carl9170_get_tx_sta(ar, skb);
+ if (!sta)
+ goto out_rcu;
+
+ sta_info = (void *) sta->drv_priv;
+ if (unlikely(sta_info->sleeping)) {
+ struct ieee80211_tx_info *tx_info;
+
+ rcu_read_unlock();
+
+ tx_info = IEEE80211_SKB_CB(skb);
+ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
+ atomic_dec(&ar->tx_ampdu_upload);
+
+ tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+ carl9170_tx_status(ar, skb, false);
+ return true;
+ }
+
+out_rcu:
+ rcu_read_unlock();
+ return false;
+}
+
static void carl9170_tx(struct ar9170 *ar)
{
struct sk_buff *skb;
@@ -1247,6 +1273,9 @@ static void carl9170_tx(struct ar9170 *ar)
if (unlikely(!skb))
break;
+ if (unlikely(carl9170_tx_ps_drop(ar, skb)))
+ continue;
+
atomic_inc(&ar->tx_total_pending);
q = __carl9170_get_queue(ar, i);
@@ -1256,6 +1285,16 @@ static void carl9170_tx(struct ar9170 *ar)
*/
skb_queue_tail(&ar->tx_status[q], skb);
+ /*
+ * increase ref count to "2".
+ * Ref counting is the easiest way to solve the
+ * race between the urb's completion routine:
+ * carl9170_tx_callback
+ * and wlan tx status functions:
+ * carl9170_tx_status/janitor.
+ */
+ carl9170_tx_get_skb(skb);
+
carl9170_usb_tx(ar, skb);
schedule_garbagecollector = true;
}
@@ -1275,7 +1314,6 @@ static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
struct carl9170_sta_info *sta_info;
struct carl9170_sta_tid *agg;
struct sk_buff *iter;
- unsigned int max;
u16 tid, seq, qseq, off;
bool run = false;
@@ -1285,7 +1323,6 @@ static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
rcu_read_lock();
agg = rcu_dereference(sta_info->agg[tid]);
- max = sta_info->ampdu_max_len;
if (!agg)
goto err_unlock_rcu;
@@ -1368,6 +1405,11 @@ void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
* all ressouces which are associated with the frame.
*/
+ if (sta) {
+ struct carl9170_sta_info *stai = (void *) sta->drv_priv;
+ atomic_inc(&stai->pending_frames);
+ }
+
if (info->flags & IEEE80211_TX_CTL_AMPDU) {
run = carl9170_tx_ampdu_queue(ar, sta, skb);
if (run)
diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c
index 37b8e115375..a61ef3d6d89 100644
--- a/drivers/net/wireless/ath/key.c
+++ b/drivers/net/wireless/ath/key.c
@@ -23,6 +23,14 @@
#define REG_READ (common->ops->read)
#define REG_WRITE(_ah, _reg, _val) (common->ops->write)(_ah, _val, _reg)
+#define ENABLE_REGWRITE_BUFFER(_ah) \
+ if (common->ops->enable_write_buffer) \
+ common->ops->enable_write_buffer((_ah));
+
+#define REGWRITE_BUFFER_FLUSH(_ah) \
+ if (common->ops->write_flush) \
+ common->ops->write_flush((_ah));
+
#define IEEE80211_WEP_NKID 4 /* number of key ids */
@@ -42,6 +50,8 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry)
keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
+ ENABLE_REGWRITE_BUFFER(ah);
+
REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
@@ -66,6 +76,8 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry)
}
+ REGWRITE_BUFFER_FLUSH(ah);
+
return true;
}
EXPORT_SYMBOL(ath_hw_keyreset);
@@ -104,9 +116,13 @@ static bool ath_hw_keysetmac(struct ath_common *common,
} else {
macLo = macHi = 0;
}
+ ENABLE_REGWRITE_BUFFER(ah);
+
REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag);
+ REGWRITE_BUFFER_FLUSH(ah);
+
return true;
}
@@ -223,6 +239,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
mic4 = get_unaligned_le32(k->kv_txmic + 4);
+ ENABLE_REGWRITE_BUFFER(ah);
+
/* Write RX[31:0] and TX[31:16] */
REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
@@ -236,6 +254,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
AR_KEYTABLE_TYPE_CLR);
+ REGWRITE_BUFFER_FLUSH(ah);
+
} else {
/*
* TKIP uses four key cache entries (two for group
@@ -258,6 +278,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
mic0 = get_unaligned_le32(k->kv_mic + 0);
mic2 = get_unaligned_le32(k->kv_mic + 4);
+ ENABLE_REGWRITE_BUFFER(ah);
+
/* Write MIC key[31:0] */
REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
@@ -270,8 +292,12 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
AR_KEYTABLE_TYPE_CLR);
+
+ REGWRITE_BUFFER_FLUSH(ah);
}
+ ENABLE_REGWRITE_BUFFER(ah);
+
/* MAC address registers are reserved for the MIC entry */
REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
@@ -283,7 +309,11 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
*/
REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
+
+ REGWRITE_BUFFER_FLUSH(ah);
} else {
+ ENABLE_REGWRITE_BUFFER(ah);
+
/* Write key[47:0] */
REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
@@ -296,6 +326,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+ REGWRITE_BUFFER_FLUSH(ah);
+
/* Write MAC address for the entry */
(void) ath_hw_keysetmac(common, entry, mac);
}
@@ -451,6 +483,9 @@ int ath_key_config(struct ath_common *common,
memset(&hk, 0, sizeof(hk));
switch (key->cipher) {
+ case 0:
+ hk.kv_type = ATH_CIPHER_CLR;
+ break;
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
hk.kv_type = ATH_CIPHER_WEP;
@@ -466,7 +501,8 @@ int ath_key_config(struct ath_common *common,
}
hk.kv_len = key->keylen;
- memcpy(hk.kv_val, key->key, key->keylen);
+ if (key->keylen)
+ memcpy(hk.kv_val, key->key, key->keylen);
if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
switch (vif->type) {
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 0e1b8793c86..028310f263c 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -97,8 +97,8 @@ static const struct ieee80211_regdomain ath_world_regdom_66_69 = {
}
};
-/* Can be used by 0x67, 0x6A and 0x68 */
-static const struct ieee80211_regdomain ath_world_regdom_67_68_6A = {
+/* Can be used by 0x67, 0x68, 0x6A and 0x6C */
+static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
.n_reg_rules = 4,
.alpha2 = "99",
.reg_rules = {
@@ -151,7 +151,8 @@ ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg)
case 0x67:
case 0x68:
case 0x6A:
- return &ath_world_regdom_67_68_6A;
+ case 0x6C:
+ return &ath_world_regdom_67_68_6A_6C;
default:
WARN_ON(1);
return ath_default_world_regdomain();
@@ -333,6 +334,7 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy,
case 0x63:
case 0x66:
case 0x67:
+ case 0x6C:
ath_reg_apply_beaconing_flags(wiphy, initiator);
break;
case 0x68:
diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h
index 5c2cfe69415..24b53839fc3 100644
--- a/drivers/net/wireless/ath/regd_common.h
+++ b/drivers/net/wireless/ath/regd_common.h
@@ -86,6 +86,7 @@ enum EnumRd {
WOR9_WORLD = 0x69,
WORA_WORLD = 0x6A,
WORB_WORLD = 0x6B,
+ WORC_WORLD = 0x6C,
MKK3_MKKB = 0x80,
MKK3_MKKA2 = 0x81,
@@ -282,6 +283,7 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = {
{WOR9_WORLD, NO_CTL, NO_CTL},
{WORA_WORLD, NO_CTL, NO_CTL},
{WORB_WORLD, NO_CTL, NO_CTL},
+ {WORC_WORLD, NO_CTL, NO_CTL},
};
static struct country_code_to_enum_rd allCountries[] = {
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 5af40d9170a..5a43984bdce 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2686,6 +2686,17 @@ out:
dev->mac_suspended++;
}
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */
+void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on)
+{
+ u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW);
+ if (on)
+ tmslow |= B43_TMSLOW_MACPHYCLKEN;
+ else
+ tmslow &= ~B43_TMSLOW_MACPHYCLKEN;
+ ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
+}
+
static void b43_adjust_opmode(struct b43_wldev *dev)
{
struct b43_wl *wl = dev->wl;
@@ -2842,7 +2853,7 @@ static int b43_chip_init(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
int err;
- u32 value32, macctl;
+ u32 macctl;
u16 value16;
/* Initialize the MAC control */
@@ -2920,9 +2931,7 @@ static int b43_chip_init(struct b43_wldev *dev)
b43_write32(dev, B43_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
b43_write32(dev, B43_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
- value32 = ssb_read32(dev->dev, SSB_TMSLOW);
- value32 |= 0x00100000;
- ssb_write32(dev->dev, SSB_TMSLOW, value32);
+ b43_mac_phy_clock_set(dev, true);
b43_write16(dev, B43_MMIO_POWERUP_DELAY,
dev->dev->bus->chipco.fast_pwrup_delay);
@@ -4213,33 +4222,18 @@ static void b43_bluetooth_coext_disable(struct b43_wldev *dev)
static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)
{
-#ifdef CONFIG_SSB_DRIVER_PCICORE
struct ssb_bus *bus = dev->dev->bus;
u32 tmp;
- if (bus->pcicore.dev &&
- bus->pcicore.dev->id.coreid == SSB_DEV_PCI &&
- bus->pcicore.dev->id.revision <= 5) {
- /* IMCFGLO timeouts workaround. */
+ if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) ||
+ (bus->chip_id == 0x4312)) {
tmp = ssb_read32(dev->dev, SSB_IMCFGLO);
- switch (bus->bustype) {
- case SSB_BUSTYPE_PCI:
- case SSB_BUSTYPE_PCMCIA:
- tmp &= ~SSB_IMCFGLO_REQTO;
- tmp &= ~SSB_IMCFGLO_SERTO;
- tmp |= 0x32;
- break;
- case SSB_BUSTYPE_SSB:
- tmp &= ~SSB_IMCFGLO_REQTO;
- tmp &= ~SSB_IMCFGLO_SERTO;
- tmp |= 0x53;
- break;
- default:
- break;
- }
+ tmp &= ~SSB_IMCFGLO_REQTO;
+ tmp &= ~SSB_IMCFGLO_SERTO;
+ tmp |= 0x3;
ssb_write32(dev->dev, SSB_IMCFGLO, tmp);
+ ssb_commit_settings(bus);
}
-#endif /* CONFIG_SSB_DRIVER_PCICORE */
}
static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle)
@@ -4863,25 +4857,8 @@ static void b43_one_core_detach(struct ssb_device *dev)
static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)
{
struct b43_wldev *wldev;
- struct pci_dev *pdev;
int err = -ENOMEM;
- if (!list_empty(&wl->devlist)) {
- /* We are not the first core on this chip. */
- pdev = (dev->bus->bustype == SSB_BUSTYPE_PCI) ? dev->bus->host_pci : NULL;
- /* Only special chips support more than one wireless
- * core, although some of the other chips have more than
- * one wireless core as well. Check for this and
- * bail out early.
- */
- if (!pdev ||
- ((pdev->device != 0x4321) &&
- (pdev->device != 0x4313) && (pdev->device != 0x431A))) {
- b43dbg(wl, "Ignoring unconnected 802.11 core\n");
- return -ENODEV;
- }
- }
-
wldev = kzalloc(sizeof(*wldev), GFP_KERNEL);
if (!wldev)
goto out;
@@ -5002,7 +4979,7 @@ out:
return err;
}
-static int b43_probe(struct ssb_device *dev, const struct ssb_device_id *id)
+static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id)
{
struct b43_wl *wl;
int err;
@@ -5040,7 +5017,7 @@ static int b43_probe(struct ssb_device *dev, const struct ssb_device_id *id)
return err;
}
-static void b43_remove(struct ssb_device *dev)
+static void b43_ssb_remove(struct ssb_device *dev)
{
struct b43_wl *wl = ssb_get_devtypedata(dev);
struct b43_wldev *wldev = ssb_get_drvdata(dev);
@@ -5083,8 +5060,8 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason)
static struct ssb_driver b43_ssb_driver = {
.name = KBUILD_MODNAME,
.id_table = b43_ssb_tbl,
- .probe = b43_probe,
- .remove = b43_remove,
+ .probe = b43_ssb_probe,
+ .remove = b43_ssb_remove,
};
static void b43_print_driverinfo(void)
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index 40db03678d9..a0d327f1318 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -133,6 +133,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags);
void b43_mac_suspend(struct b43_wldev *dev);
void b43_mac_enable(struct b43_wldev *dev);
+void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on);
struct b43_request_fw_context;
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 8a00f9a95db..b075a3f82a4 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -2281,6 +2281,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
+ save_regs_phy[8] = 0;
} else {
save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
@@ -2289,6 +2290,8 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
+ save_regs_phy[7] = 0;
+ save_regs_phy[8] = 0;
}
b43_nphy_rssi_select(dev, 5, type);
@@ -3537,17 +3540,6 @@ static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */
-static void b43_nphy_mac_phy_clock_set(struct b43_wldev *dev, bool on)
-{
- u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW);
- if (on)
- tmslow |= B43_TMSLOW_MACPHYCLKEN;
- else
- tmslow &= ~B43_TMSLOW_MACPHYCLKEN;
- ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
-}
-
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreSetState */
static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask)
{
@@ -3688,7 +3680,7 @@ int b43_phy_initn(struct b43_wldev *dev)
b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA);
b43_nphy_bmac_clock_fgc(dev, 0);
- b43_nphy_mac_phy_clock_set(dev, true);
+ b43_mac_phy_clock_set(dev, true);
b43_nphy_pa_override(dev, false);
b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
@@ -3845,8 +3837,8 @@ static int b43_nphy_set_channel(struct b43_wldev *dev,
{
struct b43_phy *phy = &dev->phy;
- const struct b43_nphy_channeltab_entry_rev2 *tabent_r2;
- const struct b43_nphy_channeltab_entry_rev3 *tabent_r3;
+ const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
+ const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
u8 tmp;
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index c7fd73e3ad7..1ab8861dd43 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2234,7 +2234,7 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
b43legacy_write32(dev, B43legacy_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
value32 = ssb_read32(dev->dev, SSB_TMSLOW);
- value32 |= 0x00100000;
+ value32 |= B43legacy_TMSLOW_MACPHYCLKEN;
ssb_write32(dev->dev, SSB_TMSLOW, value32);
b43legacy_write16(dev, B43legacy_MMIO_POWERUP_DELAY,
@@ -3104,37 +3104,6 @@ static void setup_struct_wldev_for_init(struct b43legacy_wldev *dev)
memset(&dev->noisecalc, 0, sizeof(dev->noisecalc));
}
-static void b43legacy_imcfglo_timeouts_workaround(struct b43legacy_wldev *dev)
-{
-#ifdef CONFIG_SSB_DRIVER_PCICORE
- struct ssb_bus *bus = dev->dev->bus;
- u32 tmp;
-
- if (bus->pcicore.dev &&
- bus->pcicore.dev->id.coreid == SSB_DEV_PCI &&
- bus->pcicore.dev->id.revision <= 5) {
- /* IMCFGLO timeouts workaround. */
- tmp = ssb_read32(dev->dev, SSB_IMCFGLO);
- switch (bus->bustype) {
- case SSB_BUSTYPE_PCI:
- case SSB_BUSTYPE_PCMCIA:
- tmp &= ~SSB_IMCFGLO_REQTO;
- tmp &= ~SSB_IMCFGLO_SERTO;
- tmp |= 0x32;
- break;
- case SSB_BUSTYPE_SSB:
- tmp &= ~SSB_IMCFGLO_REQTO;
- tmp &= ~SSB_IMCFGLO_SERTO;
- tmp |= 0x53;
- break;
- default:
- break;
- }
- ssb_write32(dev->dev, SSB_IMCFGLO, tmp);
- }
-#endif /* CONFIG_SSB_DRIVER_PCICORE */
-}
-
static void b43legacy_set_synth_pu_delay(struct b43legacy_wldev *dev,
bool idle) {
u16 pu_delay = 1050;
@@ -3278,7 +3247,6 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev)
/* Enable IRQ routing to this device. */
ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev);
- b43legacy_imcfglo_timeouts_workaround(dev);
prepare_phy_data_for_init(dev);
b43legacy_phy_calibrate(dev);
err = b43legacy_chip_init(dev);
@@ -3728,26 +3696,8 @@ static int b43legacy_one_core_attach(struct ssb_device *dev,
struct b43legacy_wl *wl)
{
struct b43legacy_wldev *wldev;
- struct pci_dev *pdev;
int err = -ENOMEM;
- if (!list_empty(&wl->devlist)) {
- /* We are not the first core on this chip. */
- pdev = (dev->bus->bustype == SSB_BUSTYPE_PCI) ? dev->bus->host_pci : NULL;
- /* Only special chips support more than one wireless
- * core, although some of the other chips have more than
- * one wireless core as well. Check for this and
- * bail out early.
- */
- if (!pdev ||
- ((pdev->device != 0x4321) &&
- (pdev->device != 0x4313) &&
- (pdev->device != 0x431A))) {
- b43legacydbg(wl, "Ignoring unconnected 802.11 core\n");
- return -ENODEV;
- }
- }
-
wldev = kzalloc(sizeof(*wldev), GFP_KERNEL);
if (!wldev)
goto out;
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index 1d9aed64572..d5084829c9e 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -79,13 +79,8 @@ struct net_device * hostap_add_interface(struct local_info *local,
if (!rtnl_locked)
rtnl_lock();
- ret = 0;
- if (strchr(dev->name, '%'))
- ret = dev_alloc_name(dev, dev->name);
-
SET_NETDEV_DEV(dev, mdev->dev.parent);
- if (ret >= 0)
- ret = register_netdevice(dev);
+ ret = register_netdevice(dev);
if (!rtnl_locked)
rtnl_unlock();
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c
index 5a8a3cce27b..7e5e85a017b 100644
--- a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c
+++ b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c
@@ -955,9 +955,6 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
if (priv->cfg->scan_rx_antennas[band])
rx_ant = priv->cfg->scan_rx_antennas[band];
- if (priv->cfg->scan_tx_antennas[band])
- scan_tx_antennas = priv->cfg->scan_tx_antennas[band];
-
priv->scan_tx_ant[band] = iwl4965_toggle_tx_ant(priv,
priv->scan_tx_ant[band],
scan_tx_antennas);
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
index 31ac672b64e..24d149909ba 100644
--- a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
@@ -2604,7 +2604,7 @@ static ssize_t iwl4965_rs_sta_dbgfs_scale_table_write(struct file *file,
struct iwl_lq_sta *lq_sta = file->private_data;
struct iwl_priv *priv;
char buf[64];
- int buf_size;
+ size_t buf_size;
u32 parsed_rate;
struct iwl_station_priv *sta_priv =
container_of(lq_sta, struct iwl_station_priv, lq_sta);
@@ -2860,7 +2860,6 @@ static struct rate_control_ops rs_4965_ops = {
int iwl4965_rate_control_register(void)
{
- pr_err("Registering 4965 rate control operations\n");
return ieee80211_rate_control_register(&rs_4965_ops);
}
diff --git a/drivers/net/wireless/iwlegacy/iwl-core.c b/drivers/net/wireless/iwlegacy/iwl-core.c
index 42db0fc8b92..42df8321dae 100644
--- a/drivers/net/wireless/iwlegacy/iwl-core.c
+++ b/drivers/net/wireless/iwlegacy/iwl-core.c
@@ -211,10 +211,7 @@ int iwl_legacy_init_geos(struct iwl_priv *priv)
if (!iwl_legacy_is_channel_valid(ch))
continue;
- if (iwl_legacy_is_channel_a_band(ch))
- sband = &priv->bands[IEEE80211_BAND_5GHZ];
- else
- sband = &priv->bands[IEEE80211_BAND_2GHZ];
+ sband = &priv->bands[ch->band];
geo_ch = &sband->channels[sband->n_channels++];
@@ -2117,10 +2114,9 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed)
IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
channel->hw_value, changed);
- if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
- test_bit(STATUS_SCANNING, &priv->status))) {
+ if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
scan_active = 1;
- IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
+ IWL_DEBUG_MAC80211(priv, "scan active\n");
}
if (changed & (IEEE80211_CONF_CHANGE_SMPS |
@@ -2440,11 +2436,13 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
- if (!iwl_legacy_is_alive(priv))
- return;
-
mutex_lock(&priv->mutex);
+ if (!iwl_legacy_is_alive(priv)) {
+ mutex_unlock(&priv->mutex);
+ return;
+ }
+
if (changes & BSS_CHANGED_QOS) {
unsigned long flags;
@@ -2653,7 +2651,7 @@ unplugged:
none:
/* re-enable interrupts here since we don't have anything to service. */
- /* only Re-enable if diabled by irq */
+ /* only Re-enable if disabled by irq */
if (test_bit(STATUS_INT_ENABLED, &priv->status))
iwl_legacy_enable_interrupts(priv);
spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/net/wireless/iwlegacy/iwl-core.h b/drivers/net/wireless/iwlegacy/iwl-core.h
index f03b463e437..bc66c604106 100644
--- a/drivers/net/wireless/iwlegacy/iwl-core.h
+++ b/drivers/net/wireless/iwlegacy/iwl-core.h
@@ -287,7 +287,6 @@ struct iwl_cfg {
struct iwl_base_params *base_params;
/* params likely to change within a device family */
u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
- u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
enum iwl_led_mode led_mode;
};
diff --git a/drivers/net/wireless/iwlegacy/iwl-dev.h b/drivers/net/wireless/iwlegacy/iwl-dev.h
index f43ac1eb901..be0106c6a2d 100644
--- a/drivers/net/wireless/iwlegacy/iwl-dev.h
+++ b/drivers/net/wireless/iwlegacy/iwl-dev.h
@@ -134,7 +134,7 @@ struct iwl_queue {
* space more than this */
int high_mark; /* high watermark, stop queue if free
* space less than this */
-} __packed;
+};
/* One for each TFD */
struct iwl_tx_info {
@@ -290,6 +290,7 @@ enum {
CMD_SIZE_HUGE = (1 << 0),
CMD_ASYNC = (1 << 1),
CMD_WANT_SKB = (1 << 2),
+ CMD_MAPPED = (1 << 3),
};
#define DEF_CMD_PAYLOAD_SIZE 320
@@ -1076,7 +1077,6 @@ struct iwl_priv {
spinlock_t hcmd_lock; /* protect hcmd */
spinlock_t reg_lock; /* protect hw register access */
struct mutex mutex;
- struct mutex sync_cmd_mutex; /* enable serialization of sync commands */
/* basic pci-network driver stuff */
struct pci_dev *pci_dev;
diff --git a/drivers/net/wireless/iwlegacy/iwl-hcmd.c b/drivers/net/wireless/iwlegacy/iwl-hcmd.c
index 9d721cbda5b..62b4b09122c 100644
--- a/drivers/net/wireless/iwlegacy/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlegacy/iwl-hcmd.c
@@ -145,6 +145,8 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
int cmd_idx;
int ret;
+ lockdep_assert_held(&priv->mutex);
+
BUG_ON(cmd->flags & CMD_ASYNC);
/* A synchronous command can not have a callback set. */
@@ -152,7 +154,6 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",
iwl_legacy_get_cmd_string(cmd->id));
- mutex_lock(&priv->sync_cmd_mutex);
set_bit(STATUS_HCMD_ACTIVE, &priv->status);
IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n",
@@ -224,7 +225,6 @@ fail:
cmd->reply_page = 0;
}
out:
- mutex_unlock(&priv->sync_cmd_mutex);
return ret;
}
EXPORT_SYMBOL(iwl_legacy_send_cmd_sync);
diff --git a/drivers/net/wireless/iwlegacy/iwl-helpers.h b/drivers/net/wireless/iwlegacy/iwl-helpers.h
index 02132e75583..a6effdae63f 100644
--- a/drivers/net/wireless/iwlegacy/iwl-helpers.h
+++ b/drivers/net/wireless/iwlegacy/iwl-helpers.h
@@ -149,6 +149,12 @@ static inline void iwl_legacy_disable_interrupts(struct iwl_priv *priv)
IWL_DEBUG_ISR(priv, "Disabled interrupts\n");
}
+static inline void iwl_legacy_enable_rfkill_int(struct iwl_priv *priv)
+{
+ IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n");
+ iwl_write32(priv, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
+}
+
static inline void iwl_legacy_enable_interrupts(struct iwl_priv *priv)
{
IWL_DEBUG_ISR(priv, "Enabling interrupts\n");
diff --git a/drivers/net/wireless/iwlegacy/iwl-tx.c b/drivers/net/wireless/iwlegacy/iwl-tx.c
index a227773cb38..4fff995c6f3 100644
--- a/drivers/net/wireless/iwlegacy/iwl-tx.c
+++ b/drivers/net/wireless/iwlegacy/iwl-tx.c
@@ -146,33 +146,32 @@ void iwl_legacy_cmd_queue_unmap(struct iwl_priv *priv)
{
struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
struct iwl_queue *q = &txq->q;
- bool huge = false;
int i;
if (q->n_bd == 0)
return;
while (q->read_ptr != q->write_ptr) {
- /* we have no way to tell if it is a huge cmd ATM */
i = iwl_legacy_get_cmd_index(q, q->read_ptr, 0);
- if (txq->meta[i].flags & CMD_SIZE_HUGE)
- huge = true;
- else
+ if (txq->meta[i].flags & CMD_MAPPED) {
pci_unmap_single(priv->pci_dev,
dma_unmap_addr(&txq->meta[i], mapping),
dma_unmap_len(&txq->meta[i], len),
PCI_DMA_BIDIRECTIONAL);
+ txq->meta[i].flags = 0;
+ }
q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd);
}
- if (huge) {
- i = q->n_window;
+ i = q->n_window;
+ if (txq->meta[i].flags & CMD_MAPPED) {
pci_unmap_single(priv->pci_dev,
dma_unmap_addr(&txq->meta[i], mapping),
dma_unmap_len(&txq->meta[i], len),
PCI_DMA_BIDIRECTIONAL);
+ txq->meta[i].flags = 0;
}
}
EXPORT_SYMBOL(iwl_legacy_cmd_queue_unmap);
@@ -467,29 +466,27 @@ int iwl_legacy_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
return -EIO;
}
+ spin_lock_irqsave(&priv->hcmd_lock, flags);
+
if (iwl_legacy_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
- IWL_ERR(priv, "No space in command queue\n");
- IWL_ERR(priv, "Restarting adapter due to queue full\n");
+ spin_unlock_irqrestore(&priv->hcmd_lock, flags);
+
+ IWL_ERR(priv, "Restarting adapter due to command queue full\n");
queue_work(priv->workqueue, &priv->restart);
return -ENOSPC;
}
- spin_lock_irqsave(&priv->hcmd_lock, flags);
-
- /* If this is a huge cmd, mark the huge flag also on the meta.flags
- * of the _original_ cmd. This is used for DMA mapping clean up.
- */
- if (cmd->flags & CMD_SIZE_HUGE) {
- idx = iwl_legacy_get_cmd_index(q, q->write_ptr, 0);
- txq->meta[idx].flags = CMD_SIZE_HUGE;
- }
-
idx = iwl_legacy_get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
out_cmd = txq->cmd[idx];
out_meta = &txq->meta[idx];
+ if (WARN_ON(out_meta->flags & CMD_MAPPED)) {
+ spin_unlock_irqrestore(&priv->hcmd_lock, flags);
+ return -ENOSPC;
+ }
+
memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */
- out_meta->flags = cmd->flags;
+ out_meta->flags = cmd->flags | CMD_MAPPED;
if (cmd->flags & CMD_WANT_SKB)
out_meta->source = cmd;
if (cmd->flags & CMD_ASYNC)
@@ -610,6 +607,7 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
struct iwl_device_cmd *cmd;
struct iwl_cmd_meta *meta;
struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
+ unsigned long flags;
/* 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
@@ -623,14 +621,6 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
return;
}
- /* If this is a huge cmd, clear the huge flag on the meta.flags
- * of the _original_ cmd. So that iwl_legacy_cmd_queue_free won't unmap
- * the DMA buffer for the scan (huge) command.
- */
- if (huge) {
- cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, 0);
- txq->meta[cmd_index].flags = 0;
- }
cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, huge);
cmd = txq->cmd[cmd_index];
meta = &txq->meta[cmd_index];
@@ -647,6 +637,8 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
} else if (meta->callback)
meta->callback(priv, cmd, pkt);
+ spin_lock_irqsave(&priv->hcmd_lock, flags);
+
iwl_legacy_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
if (!(meta->flags & CMD_ASYNC)) {
@@ -655,6 +647,10 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
iwl_legacy_get_cmd_string(cmd->hdr.cmd));
wake_up_interruptible(&priv->wait_command_queue);
}
+
+ /* Mark as unmapped */
meta->flags = 0;
+
+ spin_unlock_irqrestore(&priv->hcmd_lock, flags);
}
EXPORT_SYMBOL(iwl_legacy_tx_cmd_complete);
diff --git a/drivers/net/wireless/iwlegacy/iwl3945-base.c b/drivers/net/wireless/iwlegacy/iwl3945-base.c
index cc7ebcee60e..0ee6be6a9c5 100644
--- a/drivers/net/wireless/iwlegacy/iwl3945-base.c
+++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c
@@ -2748,11 +2748,12 @@ 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);
+ mutex_lock(&priv->mutex);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
+ goto out;
- mutex_lock(&priv->mutex);
iwl3945_init_alive_start(priv);
+out:
mutex_unlock(&priv->mutex);
}
@@ -2761,11 +2762,12 @@ static void iwl3945_bg_alive_start(struct work_struct *data)
struct iwl_priv *priv =
container_of(data, struct iwl_priv, alive_start.work);
+ mutex_lock(&priv->mutex);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
+ goto out;
- mutex_lock(&priv->mutex);
iwl3945_alive_start(priv);
+out:
mutex_unlock(&priv->mutex);
}
@@ -2995,10 +2997,12 @@ static void iwl3945_bg_restart(struct work_struct *data)
} else {
iwl3945_down(priv);
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ mutex_lock(&priv->mutex);
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+ mutex_unlock(&priv->mutex);
return;
+ }
- mutex_lock(&priv->mutex);
__iwl3945_up(priv);
mutex_unlock(&priv->mutex);
}
@@ -3009,11 +3013,12 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
struct iwl_priv *priv =
container_of(data, struct iwl_priv, rx_replenish);
+ mutex_lock(&priv->mutex);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
+ goto out;
- mutex_lock(&priv->mutex);
iwl3945_rx_replenish(priv);
+out:
mutex_unlock(&priv->mutex);
}
@@ -3810,7 +3815,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
INIT_LIST_HEAD(&priv->free_frames);
mutex_init(&priv->mutex);
- mutex_init(&priv->sync_cmd_mutex);
priv->ieee_channels = NULL;
priv->ieee_rates = NULL;
diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c
index a62fe24ee59..af2ae22fcfd 100644
--- a/drivers/net/wireless/iwlegacy/iwl4965-base.c
+++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c
@@ -1069,9 +1069,12 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
}
/* Re-enable all interrupts */
- /* only Re-enable if diabled by irq */
+ /* only Re-enable if disabled by irq */
if (test_bit(STATUS_INT_ENABLED, &priv->status))
iwl_legacy_enable_interrupts(priv);
+ /* Re-enable RF_KILL if it occurred */
+ else if (handled & CSR_INT_BIT_RF_KILL)
+ iwl_legacy_enable_rfkill_int(priv);
#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
if (iwl_legacy_get_debug_level(priv) & (IWL_DL_ISR)) {
@@ -2139,7 +2142,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv);
static void __iwl4965_down(struct iwl_priv *priv)
{
unsigned long flags;
- int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
+ int exit_pending;
IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
@@ -2401,11 +2404,12 @@ 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);
+ mutex_lock(&priv->mutex);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
+ goto out;
- mutex_lock(&priv->mutex);
priv->cfg->ops->lib->init_alive_start(priv);
+out:
mutex_unlock(&priv->mutex);
}
@@ -2414,11 +2418,12 @@ static void iwl4965_bg_alive_start(struct work_struct *data)
struct iwl_priv *priv =
container_of(data, struct iwl_priv, alive_start.work);
+ mutex_lock(&priv->mutex);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
+ goto out;
- mutex_lock(&priv->mutex);
iwl4965_alive_start(priv);
+out:
mutex_unlock(&priv->mutex);
}
@@ -2468,10 +2473,12 @@ static void iwl4965_bg_restart(struct work_struct *data)
} else {
iwl4965_down(priv);
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ mutex_lock(&priv->mutex);
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+ mutex_unlock(&priv->mutex);
return;
+ }
- mutex_lock(&priv->mutex);
__iwl4965_up(priv);
mutex_unlock(&priv->mutex);
}
@@ -2624,9 +2631,10 @@ void iwl4965_mac_stop(struct ieee80211_hw *hw)
flush_workqueue(priv->workqueue);
- /* enable interrupts again in order to receive rfkill changes */
+ /* User space software may expect getting rfkill changes
+ * even if interface is down */
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
- iwl_legacy_enable_interrupts(priv);
+ iwl_legacy_enable_rfkill_int(priv);
IWL_DEBUG_MAC80211(priv, "leave\n");
}
@@ -2847,21 +2855,22 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(priv, "enter\n");
+ mutex_lock(&priv->mutex);
+
if (iwl_legacy_is_rfkill(priv))
- goto out_exit;
+ goto out;
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
test_bit(STATUS_SCANNING, &priv->status))
- goto out_exit;
+ goto out;
if (!iwl_legacy_is_associated_ctx(ctx))
- goto out_exit;
+ goto out;
/* channel switch in progress */
if (priv->switch_rxon.switch_in_progress == true)
- goto out_exit;
+ goto out;
- mutex_lock(&priv->mutex);
if (priv->cfg->ops->lib->set_channel_switch) {
ch = channel->hw_value;
@@ -2917,7 +2926,6 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw,
}
out:
mutex_unlock(&priv->mutex);
-out_exit:
if (!priv->switch_rxon.switch_in_progress)
ieee80211_chswitch_done(ctx->vif, false);
IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -3116,7 +3124,6 @@ static int iwl4965_init_drv(struct iwl_priv *priv)
INIT_LIST_HEAD(&priv->free_frames);
mutex_init(&priv->mutex);
- mutex_init(&priv->sync_cmd_mutex);
priv->ieee_channels = NULL;
priv->ieee_rates = NULL;
@@ -3173,7 +3180,7 @@ static void iwl4965_hw_detect(struct iwl_priv *priv)
{
priv->hw_rev = _iwl_legacy_read32(priv, CSR_HW_REV);
priv->hw_wa_rev = _iwl_legacy_read32(priv, CSR_HW_REV_WA_REG);
- pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id);
+ priv->rev_id = priv->pci_dev->revision;
IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id);
}
@@ -3406,14 +3413,14 @@ iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* 8. Enable interrupts and read RFKILL state
*********************************************/
- /* enable interrupts if needed: hw bug w/a */
+ /* enable rfkill interrupt: hw bug w/a */
pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
}
- iwl_legacy_enable_interrupts(priv);
+ iwl_legacy_enable_rfkill_int(priv);
/* If platform's RF_KILL switch is NOT set to KILL */
if (iwl_read32(priv, CSR_GP_CNTRL) &
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 17d555f2215..ad3bdba6bee 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -102,6 +102,16 @@ config IWLWIFI_DEVICE_TRACING
occur.
endmenu
+config IWLWIFI_DEVICE_SVTOOL
+ bool "iwlwifi device svtool support"
+ depends on IWLAGN
+ select NL80211_TESTMODE
+ help
+ This option enables the svtool support for iwlwifi device through
+ NL80211_TESTMODE. svtool is a software validation tool that runs in
+ the user space and interacts with the device in the kernel space
+ through the generic netlink message via NL80211_TESTMODE channel.
+
config IWL_P2P
bool "iwlwifi experimental P2P support"
depends on IWLAGN
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 9d6ee836426..822660483f9 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -1,8 +1,8 @@
# AGN
obj-$(CONFIG_IWLAGN) += iwlagn.o
-iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o
+iwlagn-objs := iwl-agn.o iwl-agn-rs.o
iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o
-iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o
+iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o
iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o
iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
@@ -14,9 +14,9 @@ iwlagn-objs += iwl-6000.o
iwlagn-objs += iwl-1000.o
iwlagn-objs += iwl-2000.o
-iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
+iwlagn-$(CONFIG_IWLWIFI_DEVICE_SVTOOL) += iwl-sv-open.o
CFLAGS_iwl-devtrace.o := -I$(src)
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 27c5007e577..b4c81931e13 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -45,8 +45,6 @@
#include "iwl-agn.h"
#include "iwl-helpers.h"
#include "iwl-agn-hw.h"
-#include "iwl-agn-led.h"
-#include "iwl-agn-debugfs.h"
/* Highest firmware API version supported */
#define IWL1000_UCODE_API_MAX 5
@@ -57,12 +55,10 @@
#define IWL100_UCODE_API_MIN 5
#define IWL1000_FW_PRE "iwlwifi-1000-"
-#define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode"
-#define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api)
+#define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode"
#define IWL100_FW_PRE "iwlwifi-100-"
-#define _IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode"
-#define IWL100_MODULE_FIRMWARE(api) _IWL100_MODULE_FIRMWARE(api)
+#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode"
/*
@@ -124,10 +120,10 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
{
- if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
- priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+ if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+ iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
priv->cfg->base_params->num_of_queues =
- priv->cfg->mod_params->num_of_queues;
+ iwlagn_mod_params.num_of_queues;
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -141,7 +137,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
- priv->hw_params.max_bsm_size = 0;
priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ);
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -176,24 +171,13 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
static struct iwl_lib_ops iwl1000_lib = {
.set_hw_params = iwl1000_hw_set_hw_params,
- .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
- .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwlagn_txq_set_sched,
- .txq_agg_enable = iwlagn_txq_agg_enable,
- .txq_agg_disable = iwlagn_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
.txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwlagn_rx_handler_setup,
.setup_deferred_work = iwlagn_setup_deferred_work,
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
- .load_ucode = iwlagn_load_ucode,
- .dump_nic_event_log = iwl_dump_nic_event_log,
- .dump_nic_error_log = iwl_dump_nic_error_log,
- .dump_csr = iwl_dump_csr,
- .dump_fh = iwl_dump_fh,
- .init_alive_start = iwlagn_init_alive_start,
- .alive_notify = iwlagn_alive_notify,
.send_tx_power = iwlagn_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
.apm_ops = {
@@ -208,45 +192,21 @@ static struct iwl_lib_ops iwl1000_lib = {
EEPROM_REG_BAND_4_CHANNELS,
EEPROM_REG_BAND_5_CHANNELS,
EEPROM_REG_BAND_24_HT40_CHANNELS,
- EEPROM_REG_BAND_52_HT40_CHANNELS
+ EEPROM_REGULATORY_BAND_NO_HT40,
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
},
- .isr_ops = {
- .isr = iwl_isr_ict,
- .free = iwl_free_isr_ict,
- .alloc = iwl_alloc_isr_ict,
- .reset = iwl_reset_ict,
- .disable = iwl_disable_ict,
- },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
- .tt_ops = {
- .lower_power_detection = iwl_tt_is_low_power_state,
- .tt_power_mode = iwl_tt_current_power_mode,
- .ct_kill_check = iwl_check_for_ct_kill,
- }
};
static const struct iwl_ops iwl1000_ops = {
.lib = &iwl1000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static struct iwl_base_params iwl1000_base_params = {
@@ -254,8 +214,6 @@ static struct iwl_base_params iwl1000_base_params = {
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
.eeprom_size = OTP_LOW_IMAGE_SIZE,
.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
- .set_l0s = true,
- .use_bsm = false,
.max_ll_items = OTP_MAX_LL_ITEMS_1000,
.shadow_ram_support = false,
.led_compensation = 51,
@@ -265,9 +223,6 @@ static struct iwl_base_params iwl1000_base_params = {
.chain_noise_scale = 1000,
.wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 128,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
};
static struct iwl_ht_params iwl1000_ht_params = {
.ht_greenfield_support = true,
@@ -281,7 +236,6 @@ static struct iwl_ht_params iwl1000_ht_params = {
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
.ops = &iwl1000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl1000_base_params, \
.led_mode = IWL_LED_BLINK
@@ -303,7 +257,6 @@ struct iwl_cfg iwl1000_bg_cfg = {
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
.ops = &iwl1000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl1000_base_params, \
.led_mode = IWL_LED_RF_STATE, \
.rx_with_siso_diversity = true
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index d7b6126408c..89b8da7a6c8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -46,30 +46,25 @@
#include "iwl-helpers.h"
#include "iwl-agn-hw.h"
#include "iwl-6000-hw.h"
-#include "iwl-agn-led.h"
-#include "iwl-agn-debugfs.h"
/* Highest firmware API version supported */
#define IWL2030_UCODE_API_MAX 5
#define IWL2000_UCODE_API_MAX 5
-#define IWL200_UCODE_API_MAX 5
+#define IWL105_UCODE_API_MAX 5
/* Lowest firmware API version supported */
#define IWL2030_UCODE_API_MIN 5
#define IWL2000_UCODE_API_MIN 5
-#define IWL200_UCODE_API_MIN 5
+#define IWL105_UCODE_API_MIN 5
#define IWL2030_FW_PRE "iwlwifi-2030-"
-#define _IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode"
-#define IWL2030_MODULE_FIRMWARE(api) _IWL2030_MODULE_FIRMWARE(api)
+#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode"
#define IWL2000_FW_PRE "iwlwifi-2000-"
-#define _IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode"
-#define IWL2000_MODULE_FIRMWARE(api) _IWL2000_MODULE_FIRMWARE(api)
+#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode"
-#define IWL200_FW_PRE "iwlwifi-200-"
-#define _IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE #api ".ucode"
-#define IWL200_MODULE_FIRMWARE(api) _IWL200_MODULE_FIRMWARE(api)
+#define IWL105_FW_PRE "iwlwifi-105-"
+#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE #api ".ucode"
static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
{
@@ -101,6 +96,8 @@ static void iwl2000_nic_config(struct iwl_priv *priv)
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER);
+ if (priv->cfg->disable_otp_refresh)
+ iwl_write_prph(priv, APMG_ANALOG_SVR_REG, 0x80000010);
}
static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
@@ -130,10 +127,10 @@ static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
{
- if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
- priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+ if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+ iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
priv->cfg->base_params->num_of_queues =
- priv->cfg->mod_params->num_of_queues;
+ iwlagn_mod_params.num_of_queues;
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -147,7 +144,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
- priv->hw_params.max_bsm_size = 0;
priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ);
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -256,11 +252,7 @@ static int iwl2030_hw_channel_switch(struct iwl_priv *priv,
static struct iwl_lib_ops iwl2000_lib = {
.set_hw_params = iwl2000_hw_set_hw_params,
- .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
- .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwlagn_txq_set_sched,
- .txq_agg_enable = iwlagn_txq_agg_enable,
- .txq_agg_disable = iwlagn_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
.txq_init = iwl_hw_tx_queue_init,
@@ -268,13 +260,6 @@ static struct iwl_lib_ops iwl2000_lib = {
.setup_deferred_work = iwlagn_bt_setup_deferred_work,
.cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
- .load_ucode = iwlagn_load_ucode,
- .dump_nic_event_log = iwl_dump_nic_event_log,
- .dump_nic_error_log = iwl_dump_nic_error_log,
- .dump_csr = iwl_dump_csr,
- .dump_fh = iwl_dump_fh,
- .init_alive_start = iwlagn_init_alive_start,
- .alive_notify = iwlagn_alive_notify,
.send_tx_power = iwlagn_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
.set_channel_switch = iwl2030_hw_channel_switch,
@@ -290,70 +275,40 @@ static struct iwl_lib_ops iwl2000_lib = {
EEPROM_REG_BAND_4_CHANNELS,
EEPROM_REG_BAND_5_CHANNELS,
EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
- EEPROM_REG_BAND_52_HT40_CHANNELS
+ EEPROM_REGULATORY_BAND_NO_HT40,
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
},
- .isr_ops = {
- .isr = iwl_isr_ict,
- .free = iwl_free_isr_ict,
- .alloc = iwl_alloc_isr_ict,
- .reset = iwl_reset_ict,
- .disable = iwl_disable_ict,
- },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
- .tt_ops = {
- .lower_power_detection = iwl_tt_is_low_power_state,
- .tt_power_mode = iwl_tt_current_power_mode,
- .ct_kill_check = iwl_check_for_ct_kill,
- }
};
static const struct iwl_ops iwl2000_ops = {
.lib = &iwl2000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl2030_ops = {
.lib = &iwl2000_lib,
.hcmd = &iwlagn_bt_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
-static const struct iwl_ops iwl200_ops = {
+static const struct iwl_ops iwl105_ops = {
.lib = &iwl2000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
-static const struct iwl_ops iwl230_ops = {
+static const struct iwl_ops iwl135_ops = {
.lib = &iwl2000_lib,
.hcmd = &iwlagn_bt_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static struct iwl_base_params iwl2000_base_params = {
@@ -361,8 +316,6 @@ static struct iwl_base_params iwl2000_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
.pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
.shadow_ram_support = true,
.led_compensation = 51,
@@ -373,9 +326,6 @@ static struct iwl_base_params iwl2000_base_params = {
.chain_noise_scale = 1000,
.wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
.shadow_reg_enable = true,
};
@@ -385,8 +335,6 @@ static struct iwl_base_params iwl2030_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
.pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
.shadow_ram_support = true,
.led_compensation = 57,
@@ -397,9 +345,6 @@ static struct iwl_base_params iwl2030_base_params = {
.chain_noise_scale = 1000,
.wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
.shadow_reg_enable = true,
};
@@ -409,7 +354,6 @@ static struct iwl_ht_params iwl2000_ht_params = {
};
static struct iwl_bt_params iwl2030_bt_params = {
- .bt_statistics = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.advanced_bt_coexist = true,
.agg_time_limit = BT_AGG_THRESHOLD_DEF,
@@ -426,12 +370,12 @@ static struct iwl_bt_params iwl2030_bt_params = {
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.ops = &iwl2000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl2000_base_params, \
.need_dc_calib = true, \
.need_temp_offset_calib = true, \
.led_mode = IWL_LED_RF_STATE, \
- .iq_invert = true \
+ .iq_invert = true, \
+ .disable_otp_refresh = true \
struct iwl_cfg iwl2000_2bgn_cfg = {
.name = "2000 Series 2x2 BGN",
@@ -451,7 +395,6 @@ struct iwl_cfg iwl2000_2bg_cfg = {
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.ops = &iwl2030_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl2030_base_params, \
.bt_params = &iwl2030_bt_params, \
.need_dc_calib = true, \
@@ -471,45 +414,13 @@ struct iwl_cfg iwl2030_2bg_cfg = {
IWL_DEVICE_2030,
};
-#define IWL_DEVICE_6035 \
- .fw_name_pre = IWL2030_FW_PRE, \
- .ucode_api_max = IWL2030_UCODE_API_MAX, \
- .ucode_api_min = IWL2030_UCODE_API_MIN, \
- .eeprom_ver = EEPROM_6035_EEPROM_VERSION, \
- .eeprom_calib_ver = EEPROM_6035_TX_POWER_VERSION, \
- .ops = &iwl2030_ops, \
- .mod_params = &iwlagn_mod_params, \
- .base_params = &iwl2030_base_params, \
- .bt_params = &iwl2030_bt_params, \
- .need_dc_calib = true, \
- .need_temp_offset_calib = true, \
- .led_mode = IWL_LED_RF_STATE, \
- .adv_pm = true \
-
-struct iwl_cfg iwl6035_2agn_cfg = {
- .name = "2000 Series 2x2 AGN/BT",
- IWL_DEVICE_6035,
- .ht_params = &iwl2000_ht_params,
-};
-
-struct iwl_cfg iwl6035_2abg_cfg = {
- .name = "2000 Series 2x2 ABG/BT",
- IWL_DEVICE_6035,
-};
-
-struct iwl_cfg iwl6035_2bg_cfg = {
- .name = "2000 Series 2x2 BG/BT",
- IWL_DEVICE_6035,
-};
-
-#define IWL_DEVICE_200 \
- .fw_name_pre = IWL200_FW_PRE, \
- .ucode_api_max = IWL200_UCODE_API_MAX, \
- .ucode_api_min = IWL200_UCODE_API_MIN, \
+#define IWL_DEVICE_105 \
+ .fw_name_pre = IWL105_FW_PRE, \
+ .ucode_api_max = IWL105_UCODE_API_MAX, \
+ .ucode_api_min = IWL105_UCODE_API_MIN, \
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
- .ops = &iwl200_ops, \
- .mod_params = &iwlagn_mod_params, \
+ .ops = &iwl105_ops, \
.base_params = &iwl2000_base_params, \
.need_dc_calib = true, \
.need_temp_offset_calib = true, \
@@ -517,25 +428,24 @@ struct iwl_cfg iwl6035_2bg_cfg = {
.adv_pm = true, \
.rx_with_siso_diversity = true \
-struct iwl_cfg iwl200_bg_cfg = {
- .name = "200 Series 1x1 BG",
- IWL_DEVICE_200,
+struct iwl_cfg iwl105_bg_cfg = {
+ .name = "105 Series 1x1 BG",
+ IWL_DEVICE_105,
};
-struct iwl_cfg iwl200_bgn_cfg = {
- .name = "200 Series 1x1 BGN",
- IWL_DEVICE_200,
+struct iwl_cfg iwl105_bgn_cfg = {
+ .name = "105 Series 1x1 BGN",
+ IWL_DEVICE_105,
.ht_params = &iwl2000_ht_params,
};
-#define IWL_DEVICE_230 \
- .fw_name_pre = IWL200_FW_PRE, \
- .ucode_api_max = IWL200_UCODE_API_MAX, \
- .ucode_api_min = IWL200_UCODE_API_MIN, \
+#define IWL_DEVICE_135 \
+ .fw_name_pre = IWL105_FW_PRE, \
+ .ucode_api_max = IWL105_UCODE_API_MAX, \
+ .ucode_api_min = IWL105_UCODE_API_MIN, \
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
- .ops = &iwl230_ops, \
- .mod_params = &iwlagn_mod_params, \
+ .ops = &iwl135_ops, \
.base_params = &iwl2030_base_params, \
.bt_params = &iwl2030_bt_params, \
.need_dc_calib = true, \
@@ -544,17 +454,17 @@ struct iwl_cfg iwl200_bgn_cfg = {
.adv_pm = true, \
.rx_with_siso_diversity = true \
-struct iwl_cfg iwl230_bg_cfg = {
- .name = "200 Series 1x1 BG/BT",
- IWL_DEVICE_230,
+struct iwl_cfg iwl135_bg_cfg = {
+ .name = "105 Series 1x1 BG/BT",
+ IWL_DEVICE_135,
};
-struct iwl_cfg iwl230_bgn_cfg = {
- .name = "200 Series 1x1 BGN/BT",
- IWL_DEVICE_230,
+struct iwl_cfg iwl135_bgn_cfg = {
+ .name = "105 Series 1x1 BGN/BT",
+ IWL_DEVICE_135,
.ht_params = &iwl2000_ht_params,
};
MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL200_MODULE_FIRMWARE(IWL200_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 3975e45e750..05ad47628b6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 22e045b5bce..98f81df166e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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
@@ -45,10 +45,8 @@
#include "iwl-sta.h"
#include "iwl-helpers.h"
#include "iwl-agn.h"
-#include "iwl-agn-led.h"
#include "iwl-agn-hw.h"
#include "iwl-5000-hw.h"
-#include "iwl-agn-debugfs.h"
/* Highest firmware API version supported */
#define IWL5000_UCODE_API_MAX 5
@@ -59,12 +57,10 @@
#define IWL5150_UCODE_API_MIN 1
#define IWL5000_FW_PRE "iwlwifi-5000-"
-#define _IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode"
-#define IWL5000_MODULE_FIRMWARE(api) _IWL5000_MODULE_FIRMWARE(api)
+#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode"
#define IWL5150_FW_PRE "iwlwifi-5150-"
-#define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode"
-#define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api)
+#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode"
/* NIC configuration for 5000 series */
static void iwl5000_nic_config(struct iwl_priv *priv)
@@ -168,10 +164,10 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
{
- if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
- priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+ if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+ iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
priv->cfg->base_params->num_of_queues =
- priv->cfg->mod_params->num_of_queues;
+ iwlagn_mod_params.num_of_queues;
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -185,7 +181,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
- priv->hw_params.max_bsm_size = 0;
priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ);
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -214,10 +209,10 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
{
- if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
- priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+ if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+ iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
priv->cfg->base_params->num_of_queues =
- priv->cfg->mod_params->num_of_queues;
+ iwlagn_mod_params.num_of_queues;
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -231,7 +226,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
- priv->hw_params.max_bsm_size = 0;
priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ);
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -263,7 +257,7 @@ static void iwl5150_temperature(struct iwl_priv *priv)
u32 vt = 0;
s32 offset = iwl_temp_calib_to_offset(priv);
- vt = le32_to_cpu(priv->_agn.statistics.general.common.temperature);
+ vt = le32_to_cpu(priv->statistics.common.temperature);
vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
/* now vt hold the temperature in Kelvin */
priv->temperature = KELVIN_TO_CELSIUS(vt);
@@ -345,24 +339,13 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
static struct iwl_lib_ops iwl5000_lib = {
.set_hw_params = iwl5000_hw_set_hw_params,
- .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
- .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwlagn_txq_set_sched,
- .txq_agg_enable = iwlagn_txq_agg_enable,
- .txq_agg_disable = iwlagn_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
.txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwlagn_rx_handler_setup,
.setup_deferred_work = iwlagn_setup_deferred_work,
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
- .dump_nic_event_log = iwl_dump_nic_event_log,
- .dump_nic_error_log = iwl_dump_nic_error_log,
- .dump_csr = iwl_dump_csr,
- .dump_fh = iwl_dump_fh,
- .load_ucode = iwlagn_load_ucode,
- .init_alive_start = iwlagn_init_alive_start,
- .alive_notify = iwlagn_alive_notify,
.send_tx_power = iwlagn_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
.set_channel_switch = iwl5000_hw_channel_switch,
@@ -380,56 +363,24 @@ static struct iwl_lib_ops iwl5000_lib = {
EEPROM_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
},
- .isr_ops = {
- .isr = iwl_isr_ict,
- .free = iwl_free_isr_ict,
- .alloc = iwl_alloc_isr_ict,
- .reset = iwl_reset_ict,
- .disable = iwl_disable_ict,
- },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
- .tt_ops = {
- .lower_power_detection = iwl_tt_is_low_power_state,
- .tt_power_mode = iwl_tt_current_power_mode,
- .ct_kill_check = iwl_check_for_ct_kill,
- }
};
static struct iwl_lib_ops iwl5150_lib = {
.set_hw_params = iwl5150_hw_set_hw_params,
- .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
- .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwlagn_txq_set_sched,
- .txq_agg_enable = iwlagn_txq_agg_enable,
- .txq_agg_disable = iwlagn_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
.txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwlagn_rx_handler_setup,
.setup_deferred_work = iwlagn_setup_deferred_work,
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
- .dump_nic_event_log = iwl_dump_nic_event_log,
- .dump_nic_error_log = iwl_dump_nic_error_log,
- .dump_csr = iwl_dump_csr,
- .load_ucode = iwlagn_load_ucode,
- .init_alive_start = iwlagn_init_alive_start,
- .alive_notify = iwlagn_alive_notify,
.send_tx_power = iwlagn_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
.set_channel_switch = iwl5000_hw_channel_switch,
@@ -447,51 +398,25 @@ static struct iwl_lib_ops iwl5150_lib = {
EEPROM_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
},
- .isr_ops = {
- .isr = iwl_isr_ict,
- .free = iwl_free_isr_ict,
- .alloc = iwl_alloc_isr_ict,
- .reset = iwl_reset_ict,
- .disable = iwl_disable_ict,
- },
.temp_ops = {
.temperature = iwl5150_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
- .tt_ops = {
- .lower_power_detection = iwl_tt_is_low_power_state,
- .tt_power_mode = iwl_tt_current_power_mode,
- .ct_kill_check = iwl_check_for_ct_kill,
- }
};
static const struct iwl_ops iwl5000_ops = {
.lib = &iwl5000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl5150_ops = {
.lib = &iwl5150_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static struct iwl_base_params iwl5000_base_params = {
@@ -499,17 +424,12 @@ static struct iwl_base_params iwl5000_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
- .set_l0s = true,
- .use_bsm = false,
.led_compensation = 51,
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
.wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
};
static struct iwl_ht_params iwl5000_ht_params = {
.ht_greenfield_support = true,
@@ -523,7 +443,6 @@ static struct iwl_ht_params iwl5000_ht_params = {
.eeprom_ver = EEPROM_5000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
.ops = &iwl5000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl5000_base_params, \
.led_mode = IWL_LED_BLINK
@@ -567,7 +486,6 @@ struct iwl_cfg iwl5350_agn_cfg = {
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
.ops = &iwl5000_ops,
- .mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params,
.ht_params = &iwl5000_ht_params,
.led_mode = IWL_LED_BLINK,
@@ -581,7 +499,6 @@ struct iwl_cfg iwl5350_agn_cfg = {
.eeprom_ver = EEPROM_5050_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
.ops = &iwl5150_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl5000_base_params, \
.need_dc_calib = true, \
.led_mode = IWL_LED_BLINK, \
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
index 47891e16a75..b27986e57c9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index a745b01c0ec..a7921f9a03c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -46,8 +46,6 @@
#include "iwl-helpers.h"
#include "iwl-agn-hw.h"
#include "iwl-6000-hw.h"
-#include "iwl-agn-led.h"
-#include "iwl-agn-debugfs.h"
/* Highest firmware API version supported */
#define IWL6000_UCODE_API_MAX 4
@@ -60,20 +58,16 @@
#define IWL6000G2_UCODE_API_MIN 4
#define IWL6000_FW_PRE "iwlwifi-6000-"
-#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
-#define IWL6000_MODULE_FIRMWARE(api) _IWL6000_MODULE_FIRMWARE(api)
+#define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
#define IWL6050_FW_PRE "iwlwifi-6050-"
-#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
-#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
+#define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
#define IWL6005_FW_PRE "iwlwifi-6000g2a-"
-#define _IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode"
-#define IWL6005_MODULE_FIRMWARE(api) _IWL6005_MODULE_FIRMWARE(api)
+#define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode"
#define IWL6030_FW_PRE "iwlwifi-6000g2b-"
-#define _IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode"
-#define IWL6030_MODULE_FIRMWARE(api) _IWL6030_MODULE_FIRMWARE(api)
+#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode"
static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
{
@@ -85,7 +79,7 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
static void iwl6050_additional_nic_config(struct iwl_priv *priv)
{
/* Indicate calibration version to uCode. */
- if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
+ if (iwlagn_eeprom_calib_version(priv) >= 6)
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
}
@@ -93,7 +87,7 @@ static void iwl6050_additional_nic_config(struct iwl_priv *priv)
static void iwl6150_additional_nic_config(struct iwl_priv *priv)
{
/* Indicate calibration version to uCode. */
- if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
+ if (iwlagn_eeprom_calib_version(priv) >= 6)
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
@@ -159,10 +153,10 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
{
- if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
- priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+ if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+ iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
priv->cfg->base_params->num_of_queues =
- priv->cfg->mod_params->num_of_queues;
+ iwlagn_mod_params.num_of_queues;
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -176,7 +170,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
- priv->hw_params.max_bsm_size = 0;
priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ);
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -285,24 +278,13 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
static struct iwl_lib_ops iwl6000_lib = {
.set_hw_params = iwl6000_hw_set_hw_params,
- .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
- .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwlagn_txq_set_sched,
- .txq_agg_enable = iwlagn_txq_agg_enable,
- .txq_agg_disable = iwlagn_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
.txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwlagn_rx_handler_setup,
.setup_deferred_work = iwlagn_setup_deferred_work,
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
- .load_ucode = iwlagn_load_ucode,
- .dump_nic_event_log = iwl_dump_nic_event_log,
- .dump_nic_error_log = iwl_dump_nic_error_log,
- .dump_csr = iwl_dump_csr,
- .dump_fh = iwl_dump_fh,
- .init_alive_start = iwlagn_init_alive_start,
- .alive_notify = iwlagn_alive_notify,
.send_tx_power = iwlagn_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
.set_channel_switch = iwl6000_hw_channel_switch,
@@ -320,45 +302,19 @@ static struct iwl_lib_ops iwl6000_lib = {
EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
},
- .isr_ops = {
- .isr = iwl_isr_ict,
- .free = iwl_free_isr_ict,
- .alloc = iwl_alloc_isr_ict,
- .reset = iwl_reset_ict,
- .disable = iwl_disable_ict,
- },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
- .tt_ops = {
- .lower_power_detection = iwl_tt_is_low_power_state,
- .tt_power_mode = iwl_tt_current_power_mode,
- .ct_kill_check = iwl_check_for_ct_kill,
- }
};
static struct iwl_lib_ops iwl6030_lib = {
.set_hw_params = iwl6000_hw_set_hw_params,
- .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
- .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwlagn_txq_set_sched,
- .txq_agg_enable = iwlagn_txq_agg_enable,
- .txq_agg_disable = iwlagn_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
.txq_init = iwl_hw_tx_queue_init,
@@ -366,13 +322,6 @@ static struct iwl_lib_ops iwl6030_lib = {
.setup_deferred_work = iwlagn_bt_setup_deferred_work,
.cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
- .load_ucode = iwlagn_load_ucode,
- .dump_nic_event_log = iwl_dump_nic_event_log,
- .dump_nic_error_log = iwl_dump_nic_error_log,
- .dump_csr = iwl_dump_csr,
- .dump_fh = iwl_dump_fh,
- .init_alive_start = iwlagn_init_alive_start,
- .alive_notify = iwlagn_alive_notify,
.send_tx_power = iwlagn_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
.set_channel_switch = iwl6000_hw_channel_switch,
@@ -390,36 +339,14 @@ static struct iwl_lib_ops iwl6030_lib = {
EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
},
- .isr_ops = {
- .isr = iwl_isr_ict,
- .free = iwl_free_isr_ict,
- .alloc = iwl_alloc_isr_ict,
- .reset = iwl_reset_ict,
- .disable = iwl_disable_ict,
- },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
- .tt_ops = {
- .lower_power_detection = iwl_tt_is_low_power_state,
- .tt_power_mode = iwl_tt_current_power_mode,
- .ct_kill_check = iwl_check_for_ct_kill,
- }
};
static struct iwl_nic_ops iwl6050_nic_ops = {
@@ -434,34 +361,26 @@ static const struct iwl_ops iwl6000_ops = {
.lib = &iwl6000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl6050_ops = {
.lib = &iwl6000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
.nic = &iwl6050_nic_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl6150_ops = {
.lib = &iwl6000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
.nic = &iwl6150_nic_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl6030_ops = {
.lib = &iwl6030_lib,
.hcmd = &iwlagn_bt_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static struct iwl_base_params iwl6000_base_params = {
@@ -469,8 +388,6 @@ static struct iwl_base_params iwl6000_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
.pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
.led_compensation = 51,
@@ -481,9 +398,6 @@ static struct iwl_base_params iwl6000_base_params = {
.chain_noise_scale = 1000,
.wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
.shadow_reg_enable = true,
};
@@ -492,8 +406,6 @@ static struct iwl_base_params iwl6050_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
.pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
.shadow_ram_support = true,
.led_compensation = 51,
@@ -504,9 +416,6 @@ static struct iwl_base_params iwl6050_base_params = {
.chain_noise_scale = 1500,
.wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 1024,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
.shadow_reg_enable = true,
};
static struct iwl_base_params iwl6000_g2_base_params = {
@@ -514,8 +423,6 @@ static struct iwl_base_params iwl6000_g2_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
.pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
.led_compensation = 57,
@@ -526,9 +433,6 @@ static struct iwl_base_params iwl6000_g2_base_params = {
.chain_noise_scale = 1000,
.wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
.shadow_reg_enable = true,
};
@@ -538,7 +442,6 @@ static struct iwl_ht_params iwl6000_ht_params = {
};
static struct iwl_bt_params iwl6000_bt_params = {
- .bt_statistics = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.advanced_bt_coexist = true,
.agg_time_limit = BT_AGG_THRESHOLD_DEF,
@@ -554,7 +457,6 @@ static struct iwl_bt_params iwl6000_bt_params = {
.eeprom_ver = EEPROM_6005_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
.ops = &iwl6000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl6000_g2_base_params, \
.need_dc_calib = true, \
.need_temp_offset_calib = true, \
@@ -583,7 +485,6 @@ struct iwl_cfg iwl6005_2bg_cfg = {
.eeprom_ver = EEPROM_6030_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
.ops = &iwl6030_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl6000_g2_base_params, \
.bt_params = &iwl6000_bt_params, \
.need_dc_calib = true, \
@@ -613,6 +514,22 @@ struct iwl_cfg iwl6030_2bg_cfg = {
IWL_DEVICE_6030,
};
+struct iwl_cfg iwl6035_2agn_cfg = {
+ .name = "6035 Series 2x2 AGN/BT",
+ IWL_DEVICE_6030,
+ .ht_params = &iwl6000_ht_params,
+};
+
+struct iwl_cfg iwl6035_2abg_cfg = {
+ .name = "6035 Series 2x2 ABG/BT",
+ IWL_DEVICE_6030,
+};
+
+struct iwl_cfg iwl6035_2bg_cfg = {
+ .name = "6035 Series 2x2 BG/BT",
+ IWL_DEVICE_6030,
+};
+
struct iwl_cfg iwl1030_bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 1030 BGN",
IWL_DEVICE_6030,
@@ -649,7 +566,6 @@ struct iwl_cfg iwl130_bg_cfg = {
.eeprom_ver = EEPROM_6000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \
.ops = &iwl6000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl6000_base_params, \
.pa_type = IWL_PA_INTERNAL, \
.led_mode = IWL_LED_BLINK
@@ -679,7 +595,6 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
.ops = &iwl6050_ops, \
.eeprom_ver = EEPROM_6050_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl6050_base_params, \
.need_dc_calib = true, \
.led_mode = IWL_LED_BLINK, \
@@ -704,7 +619,6 @@ struct iwl_cfg iwl6150_bgn_cfg = {
.eeprom_ver = EEPROM_6150_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION,
.ops = &iwl6150_ops,
- .mod_params = &iwlagn_mod_params,
.base_params = &iwl6050_base_params,
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
@@ -720,7 +634,6 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
.ops = &iwl6000_ops,
- .mod_params = &iwlagn_mod_params,
.base_params = &iwl6000_base_params,
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index 9006293e740..0f6bb9b2e64 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -605,7 +605,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
}
-void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
+void iwl_sensitivity_calibration(struct iwl_priv *priv)
{
u32 rx_enable_time;
u32 fa_cck;
@@ -631,16 +631,9 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
}
spin_lock_irqsave(&priv->lock, flags);
- if (iwl_bt_statistics(priv)) {
- rx_info = &(((struct iwl_bt_notif_statistics *)resp)->
- rx.general.common);
- ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm);
- cck = &(((struct iwl_bt_notif_statistics *)resp)->rx.cck);
- } else {
- rx_info = &(((struct iwl_notif_statistics *)resp)->rx.general);
- ofdm = &(((struct iwl_notif_statistics *)resp)->rx.ofdm);
- cck = &(((struct iwl_notif_statistics *)resp)->rx.cck);
- }
+ rx_info = &priv->statistics.rx_non_phy;
+ ofdm = &priv->statistics.rx_ofdm;
+ cck = &priv->statistics.rx_cck;
if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
IWL_DEBUG_CALIB(priv, "<< invalid data.\n");
spin_unlock_irqrestore(&priv->lock, flags);
@@ -851,7 +844,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
* 1) Which antennas are connected.
* 2) Differential rx gain settings to balance the 3 receivers.
*/
-void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
+void iwl_chain_noise_calibration(struct iwl_priv *priv)
{
struct iwl_chain_noise_data *data = NULL;
@@ -896,13 +889,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
}
spin_lock_irqsave(&priv->lock, flags);
- if (iwl_bt_statistics(priv)) {
- rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)->
- rx.general.common);
- } else {
- rx_info = &(((struct iwl_notif_statistics *)stat_resp)->
- rx.general);
- }
+
+ rx_info = &priv->statistics.rx_non_phy;
+
if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n");
spin_unlock_irqrestore(&priv->lock, flags);
@@ -911,19 +900,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK);
rxon_chnum = le16_to_cpu(ctx->staging.channel);
- if (iwl_bt_statistics(priv)) {
- stat_band24 = !!(((struct iwl_bt_notif_statistics *)
- stat_resp)->flag &
- STATISTICS_REPLY_FLG_BAND_24G_MSK);
- stat_chnum = le32_to_cpu(((struct iwl_bt_notif_statistics *)
- stat_resp)->flag) >> 16;
- } else {
- stat_band24 = !!(((struct iwl_notif_statistics *)
- stat_resp)->flag &
- STATISTICS_REPLY_FLG_BAND_24G_MSK);
- stat_chnum = le32_to_cpu(((struct iwl_notif_statistics *)
- stat_resp)->flag) >> 16;
- }
+ stat_band24 =
+ !!(priv->statistics.flag & STATISTICS_REPLY_FLG_BAND_24G_MSK);
+ stat_chnum = le32_to_cpu(priv->statistics.flag) >> 16;
/* Make sure we accumulate data for just the associated channel
* (even if scanning). */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
index e37ae726163..4ef4dd93425 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -66,8 +66,8 @@
#include "iwl-core.h"
#include "iwl-commands.h"
-void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp);
-void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp);
+void iwl_chain_noise_calibration(struct iwl_priv *priv);
+void iwl_sensitivity_calibration(struct iwl_priv *priv);
void iwl_init_sensitivity(struct iwl_priv *priv);
void iwl_reset_run_time_calib(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
deleted file mode 100644
index b500aaae53e..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ /dev/null
@@ -1,1073 +0,0 @@
-/******************************************************************************
-*
-* GPL LICENSE SUMMARY
-*
-* Copyright(c) 2008 - 2010 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:
-* Intel Linux Wireless <ilw@linux.intel.com>
-* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-*****************************************************************************/
-#include "iwl-agn.h"
-#include "iwl-agn-debugfs.h"
-
-static const char *fmt_value = " %-30s %10u\n";
-static const char *fmt_hex = " %-30s 0x%02X\n";
-static const char *fmt_table = " %-30s %10u %10u %10u %10u\n";
-static const char *fmt_header =
- "%-32s current cumulative delta max\n";
-
-static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
-{
- int p = 0;
- u32 flag;
-
- if (iwl_bt_statistics(priv))
- flag = le32_to_cpu(priv->_agn.statistics_bt.flag);
- else
- flag = le32_to_cpu(priv->_agn.statistics.flag);
-
- p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
- if (flag & UCODE_STATISTICS_CLEAR_MSK)
- p += scnprintf(buf + p, bufsz - p,
- "\tStatistics have been cleared\n");
- p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
- (flag & UCODE_STATISTICS_FREQUENCY_MSK)
- ? "2.4 GHz" : "5.2 GHz");
- p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
- (flag & UCODE_STATISTICS_NARROW_BAND_MSK)
- ? "enabled" : "disabled");
-
- return p;
-}
-
-ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
- {
- struct iwl_priv *priv = file->private_data;
- int pos = 0;
- char *buf;
- int bufsz = sizeof(struct statistics_rx_phy) * 40 +
- sizeof(struct statistics_rx_non_phy) * 40 +
- sizeof(struct statistics_rx_ht_phy) * 40 + 400;
- ssize_t ret;
- struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
- struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
- struct statistics_rx_non_phy *general, *accum_general;
- struct statistics_rx_non_phy *delta_general, *max_general;
- struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IWL_ERR(priv, "Can not allocate Buffer\n");
- return -ENOMEM;
- }
-
- /*
- * the statistic information display here is based on
- * the last statistics notification from uCode
- * might not reflect the current uCode activity
- */
- if (iwl_bt_statistics(priv)) {
- ofdm = &priv->_agn.statistics_bt.rx.ofdm;
- cck = &priv->_agn.statistics_bt.rx.cck;
- general = &priv->_agn.statistics_bt.rx.general.common;
- ht = &priv->_agn.statistics_bt.rx.ofdm_ht;
- accum_ofdm = &priv->_agn.accum_statistics_bt.rx.ofdm;
- accum_cck = &priv->_agn.accum_statistics_bt.rx.cck;
- accum_general =
- &priv->_agn.accum_statistics_bt.rx.general.common;
- accum_ht = &priv->_agn.accum_statistics_bt.rx.ofdm_ht;
- delta_ofdm = &priv->_agn.delta_statistics_bt.rx.ofdm;
- delta_cck = &priv->_agn.delta_statistics_bt.rx.cck;
- delta_general =
- &priv->_agn.delta_statistics_bt.rx.general.common;
- delta_ht = &priv->_agn.delta_statistics_bt.rx.ofdm_ht;
- max_ofdm = &priv->_agn.max_delta_bt.rx.ofdm;
- max_cck = &priv->_agn.max_delta_bt.rx.cck;
- max_general = &priv->_agn.max_delta_bt.rx.general.common;
- max_ht = &priv->_agn.max_delta_bt.rx.ofdm_ht;
- } else {
- ofdm = &priv->_agn.statistics.rx.ofdm;
- cck = &priv->_agn.statistics.rx.cck;
- general = &priv->_agn.statistics.rx.general;
- ht = &priv->_agn.statistics.rx.ofdm_ht;
- accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm;
- accum_cck = &priv->_agn.accum_statistics.rx.cck;
- accum_general = &priv->_agn.accum_statistics.rx.general;
- accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht;
- delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm;
- delta_cck = &priv->_agn.delta_statistics.rx.cck;
- delta_general = &priv->_agn.delta_statistics.rx.general;
- delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht;
- max_ofdm = &priv->_agn.max_delta.rx.ofdm;
- max_cck = &priv->_agn.max_delta.rx.cck;
- max_general = &priv->_agn.max_delta.rx.general;
- max_ht = &priv->_agn.max_delta.rx.ofdm_ht;
- }
-
- pos += iwl_statistics_flag(priv, buf, bufsz);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_Rx - OFDM:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "ina_cnt:",
- le32_to_cpu(ofdm->ina_cnt),
- accum_ofdm->ina_cnt,
- delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_cnt:",
- le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
- delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "plcp_err:",
- le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
- delta_ofdm->plcp_err, max_ofdm->plcp_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_err:",
- le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
- delta_ofdm->crc32_err, max_ofdm->crc32_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "overrun_err:",
- le32_to_cpu(ofdm->overrun_err),
- accum_ofdm->overrun_err, delta_ofdm->overrun_err,
- max_ofdm->overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "early_overrun_err:",
- le32_to_cpu(ofdm->early_overrun_err),
- accum_ofdm->early_overrun_err,
- delta_ofdm->early_overrun_err,
- max_ofdm->early_overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_good:",
- le32_to_cpu(ofdm->crc32_good),
- accum_ofdm->crc32_good, delta_ofdm->crc32_good,
- max_ofdm->crc32_good);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "false_alarm_cnt:",
- le32_to_cpu(ofdm->false_alarm_cnt),
- accum_ofdm->false_alarm_cnt,
- delta_ofdm->false_alarm_cnt,
- max_ofdm->false_alarm_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_sync_err_cnt:",
- le32_to_cpu(ofdm->fina_sync_err_cnt),
- accum_ofdm->fina_sync_err_cnt,
- delta_ofdm->fina_sync_err_cnt,
- max_ofdm->fina_sync_err_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sfd_timeout:",
- le32_to_cpu(ofdm->sfd_timeout),
- accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout,
- max_ofdm->sfd_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_timeout:",
- le32_to_cpu(ofdm->fina_timeout),
- accum_ofdm->fina_timeout, delta_ofdm->fina_timeout,
- max_ofdm->fina_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "unresponded_rts:",
- le32_to_cpu(ofdm->unresponded_rts),
- accum_ofdm->unresponded_rts,
- delta_ofdm->unresponded_rts,
- max_ofdm->unresponded_rts);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "rxe_frame_lmt_ovrun:",
- le32_to_cpu(ofdm->rxe_frame_limit_overrun),
- accum_ofdm->rxe_frame_limit_overrun,
- delta_ofdm->rxe_frame_limit_overrun,
- max_ofdm->rxe_frame_limit_overrun);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_ack_cnt:",
- le32_to_cpu(ofdm->sent_ack_cnt),
- accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt,
- max_ofdm->sent_ack_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_cts_cnt:",
- le32_to_cpu(ofdm->sent_cts_cnt),
- accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt,
- max_ofdm->sent_cts_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_ba_rsp_cnt:",
- le32_to_cpu(ofdm->sent_ba_rsp_cnt),
- accum_ofdm->sent_ba_rsp_cnt,
- delta_ofdm->sent_ba_rsp_cnt,
- max_ofdm->sent_ba_rsp_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "dsp_self_kill:",
- le32_to_cpu(ofdm->dsp_self_kill),
- accum_ofdm->dsp_self_kill,
- delta_ofdm->dsp_self_kill,
- max_ofdm->dsp_self_kill);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "mh_format_err:",
- le32_to_cpu(ofdm->mh_format_err),
- accum_ofdm->mh_format_err,
- delta_ofdm->mh_format_err,
- max_ofdm->mh_format_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "re_acq_main_rssi_sum:",
- le32_to_cpu(ofdm->re_acq_main_rssi_sum),
- accum_ofdm->re_acq_main_rssi_sum,
- delta_ofdm->re_acq_main_rssi_sum,
- max_ofdm->re_acq_main_rssi_sum);
-
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_Rx - CCK:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "ina_cnt:",
- le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
- delta_cck->ina_cnt, max_cck->ina_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_cnt:",
- le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
- delta_cck->fina_cnt, max_cck->fina_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "plcp_err:",
- le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
- delta_cck->plcp_err, max_cck->plcp_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_err:",
- le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
- delta_cck->crc32_err, max_cck->crc32_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "overrun_err:",
- le32_to_cpu(cck->overrun_err),
- accum_cck->overrun_err, delta_cck->overrun_err,
- max_cck->overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "early_overrun_err:",
- le32_to_cpu(cck->early_overrun_err),
- accum_cck->early_overrun_err,
- delta_cck->early_overrun_err,
- max_cck->early_overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_good:",
- le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
- delta_cck->crc32_good, max_cck->crc32_good);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "false_alarm_cnt:",
- le32_to_cpu(cck->false_alarm_cnt),
- accum_cck->false_alarm_cnt,
- delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_sync_err_cnt:",
- le32_to_cpu(cck->fina_sync_err_cnt),
- accum_cck->fina_sync_err_cnt,
- delta_cck->fina_sync_err_cnt,
- max_cck->fina_sync_err_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sfd_timeout:",
- le32_to_cpu(cck->sfd_timeout),
- accum_cck->sfd_timeout, delta_cck->sfd_timeout,
- max_cck->sfd_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_timeout:",
- le32_to_cpu(cck->fina_timeout),
- accum_cck->fina_timeout, delta_cck->fina_timeout,
- max_cck->fina_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "unresponded_rts:",
- le32_to_cpu(cck->unresponded_rts),
- accum_cck->unresponded_rts, delta_cck->unresponded_rts,
- max_cck->unresponded_rts);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "rxe_frame_lmt_ovrun:",
- le32_to_cpu(cck->rxe_frame_limit_overrun),
- accum_cck->rxe_frame_limit_overrun,
- delta_cck->rxe_frame_limit_overrun,
- max_cck->rxe_frame_limit_overrun);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_ack_cnt:",
- le32_to_cpu(cck->sent_ack_cnt),
- accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt,
- max_cck->sent_ack_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_cts_cnt:",
- le32_to_cpu(cck->sent_cts_cnt),
- accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt,
- max_cck->sent_cts_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_ba_rsp_cnt:",
- le32_to_cpu(cck->sent_ba_rsp_cnt),
- accum_cck->sent_ba_rsp_cnt,
- delta_cck->sent_ba_rsp_cnt,
- max_cck->sent_ba_rsp_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "dsp_self_kill:",
- le32_to_cpu(cck->dsp_self_kill),
- accum_cck->dsp_self_kill, delta_cck->dsp_self_kill,
- max_cck->dsp_self_kill);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "mh_format_err:",
- le32_to_cpu(cck->mh_format_err),
- accum_cck->mh_format_err, delta_cck->mh_format_err,
- max_cck->mh_format_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "re_acq_main_rssi_sum:",
- le32_to_cpu(cck->re_acq_main_rssi_sum),
- accum_cck->re_acq_main_rssi_sum,
- delta_cck->re_acq_main_rssi_sum,
- max_cck->re_acq_main_rssi_sum);
-
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_Rx - GENERAL:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "bogus_cts:",
- le32_to_cpu(general->bogus_cts),
- accum_general->bogus_cts, delta_general->bogus_cts,
- max_general->bogus_cts);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "bogus_ack:",
- le32_to_cpu(general->bogus_ack),
- accum_general->bogus_ack, delta_general->bogus_ack,
- max_general->bogus_ack);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "non_bssid_frames:",
- le32_to_cpu(general->non_bssid_frames),
- accum_general->non_bssid_frames,
- delta_general->non_bssid_frames,
- max_general->non_bssid_frames);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "filtered_frames:",
- le32_to_cpu(general->filtered_frames),
- accum_general->filtered_frames,
- delta_general->filtered_frames,
- max_general->filtered_frames);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "non_channel_beacons:",
- le32_to_cpu(general->non_channel_beacons),
- accum_general->non_channel_beacons,
- delta_general->non_channel_beacons,
- max_general->non_channel_beacons);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "channel_beacons:",
- le32_to_cpu(general->channel_beacons),
- accum_general->channel_beacons,
- delta_general->channel_beacons,
- max_general->channel_beacons);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "num_missed_bcon:",
- le32_to_cpu(general->num_missed_bcon),
- accum_general->num_missed_bcon,
- delta_general->num_missed_bcon,
- max_general->num_missed_bcon);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "adc_rx_saturation_time:",
- le32_to_cpu(general->adc_rx_saturation_time),
- accum_general->adc_rx_saturation_time,
- delta_general->adc_rx_saturation_time,
- max_general->adc_rx_saturation_time);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "ina_detect_search_tm:",
- le32_to_cpu(general->ina_detection_search_time),
- accum_general->ina_detection_search_time,
- delta_general->ina_detection_search_time,
- max_general->ina_detection_search_time);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_silence_rssi_a:",
- le32_to_cpu(general->beacon_silence_rssi_a),
- accum_general->beacon_silence_rssi_a,
- delta_general->beacon_silence_rssi_a,
- max_general->beacon_silence_rssi_a);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_silence_rssi_b:",
- le32_to_cpu(general->beacon_silence_rssi_b),
- accum_general->beacon_silence_rssi_b,
- delta_general->beacon_silence_rssi_b,
- max_general->beacon_silence_rssi_b);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_silence_rssi_c:",
- le32_to_cpu(general->beacon_silence_rssi_c),
- accum_general->beacon_silence_rssi_c,
- delta_general->beacon_silence_rssi_c,
- max_general->beacon_silence_rssi_c);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "interference_data_flag:",
- le32_to_cpu(general->interference_data_flag),
- accum_general->interference_data_flag,
- delta_general->interference_data_flag,
- max_general->interference_data_flag);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "channel_load:",
- le32_to_cpu(general->channel_load),
- accum_general->channel_load,
- delta_general->channel_load,
- max_general->channel_load);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "dsp_false_alarms:",
- le32_to_cpu(general->dsp_false_alarms),
- accum_general->dsp_false_alarms,
- delta_general->dsp_false_alarms,
- max_general->dsp_false_alarms);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_rssi_a:",
- le32_to_cpu(general->beacon_rssi_a),
- accum_general->beacon_rssi_a,
- delta_general->beacon_rssi_a,
- max_general->beacon_rssi_a);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_rssi_b:",
- le32_to_cpu(general->beacon_rssi_b),
- accum_general->beacon_rssi_b,
- delta_general->beacon_rssi_b,
- max_general->beacon_rssi_b);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_rssi_c:",
- le32_to_cpu(general->beacon_rssi_c),
- accum_general->beacon_rssi_c,
- delta_general->beacon_rssi_c,
- max_general->beacon_rssi_c);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_energy_a:",
- le32_to_cpu(general->beacon_energy_a),
- accum_general->beacon_energy_a,
- delta_general->beacon_energy_a,
- max_general->beacon_energy_a);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_energy_b:",
- le32_to_cpu(general->beacon_energy_b),
- accum_general->beacon_energy_b,
- delta_general->beacon_energy_b,
- max_general->beacon_energy_b);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_energy_c:",
- le32_to_cpu(general->beacon_energy_c),
- accum_general->beacon_energy_c,
- delta_general->beacon_energy_c,
- max_general->beacon_energy_c);
-
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_Rx - OFDM_HT:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "plcp_err:",
- le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
- delta_ht->plcp_err, max_ht->plcp_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "overrun_err:",
- le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
- delta_ht->overrun_err, max_ht->overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "early_overrun_err:",
- le32_to_cpu(ht->early_overrun_err),
- accum_ht->early_overrun_err,
- delta_ht->early_overrun_err,
- max_ht->early_overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_good:",
- le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
- delta_ht->crc32_good, max_ht->crc32_good);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_err:",
- le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
- delta_ht->crc32_err, max_ht->crc32_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "mh_format_err:",
- le32_to_cpu(ht->mh_format_err),
- accum_ht->mh_format_err,
- delta_ht->mh_format_err, max_ht->mh_format_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg_crc32_good:",
- le32_to_cpu(ht->agg_crc32_good),
- accum_ht->agg_crc32_good,
- delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg_mpdu_cnt:",
- le32_to_cpu(ht->agg_mpdu_cnt),
- accum_ht->agg_mpdu_cnt,
- delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg_cnt:",
- le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
- delta_ht->agg_cnt, max_ht->agg_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "unsupport_mcs:",
- le32_to_cpu(ht->unsupport_mcs),
- accum_ht->unsupport_mcs,
- delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
-
-ssize_t iwl_ucode_tx_stats_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = file->private_data;
- int pos = 0;
- char *buf;
- int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
- ssize_t ret;
- struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IWL_ERR(priv, "Can not allocate Buffer\n");
- return -ENOMEM;
- }
-
- /* the statistic information display here is based on
- * the last statistics notification from uCode
- * might not reflect the current uCode activity
- */
- if (iwl_bt_statistics(priv)) {
- tx = &priv->_agn.statistics_bt.tx;
- accum_tx = &priv->_agn.accum_statistics_bt.tx;
- delta_tx = &priv->_agn.delta_statistics_bt.tx;
- max_tx = &priv->_agn.max_delta_bt.tx;
- } else {
- tx = &priv->_agn.statistics.tx;
- accum_tx = &priv->_agn.accum_statistics.tx;
- delta_tx = &priv->_agn.delta_statistics.tx;
- max_tx = &priv->_agn.max_delta.tx;
- }
-
- pos += iwl_statistics_flag(priv, buf, bufsz);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_Tx:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "preamble:",
- le32_to_cpu(tx->preamble_cnt),
- accum_tx->preamble_cnt,
- delta_tx->preamble_cnt, max_tx->preamble_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "rx_detected_cnt:",
- le32_to_cpu(tx->rx_detected_cnt),
- accum_tx->rx_detected_cnt,
- delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "bt_prio_defer_cnt:",
- le32_to_cpu(tx->bt_prio_defer_cnt),
- accum_tx->bt_prio_defer_cnt,
- delta_tx->bt_prio_defer_cnt,
- max_tx->bt_prio_defer_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "bt_prio_kill_cnt:",
- le32_to_cpu(tx->bt_prio_kill_cnt),
- accum_tx->bt_prio_kill_cnt,
- delta_tx->bt_prio_kill_cnt,
- max_tx->bt_prio_kill_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "few_bytes_cnt:",
- le32_to_cpu(tx->few_bytes_cnt),
- accum_tx->few_bytes_cnt,
- delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "cts_timeout:",
- le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
- delta_tx->cts_timeout, max_tx->cts_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "ack_timeout:",
- le32_to_cpu(tx->ack_timeout),
- accum_tx->ack_timeout,
- delta_tx->ack_timeout, max_tx->ack_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "expected_ack_cnt:",
- le32_to_cpu(tx->expected_ack_cnt),
- accum_tx->expected_ack_cnt,
- delta_tx->expected_ack_cnt,
- max_tx->expected_ack_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "actual_ack_cnt:",
- le32_to_cpu(tx->actual_ack_cnt),
- accum_tx->actual_ack_cnt,
- delta_tx->actual_ack_cnt,
- max_tx->actual_ack_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "dump_msdu_cnt:",
- le32_to_cpu(tx->dump_msdu_cnt),
- accum_tx->dump_msdu_cnt,
- delta_tx->dump_msdu_cnt,
- max_tx->dump_msdu_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "abort_nxt_frame_mismatch:",
- le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
- accum_tx->burst_abort_next_frame_mismatch_cnt,
- delta_tx->burst_abort_next_frame_mismatch_cnt,
- max_tx->burst_abort_next_frame_mismatch_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "abort_missing_nxt_frame:",
- le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
- accum_tx->burst_abort_missing_next_frame_cnt,
- delta_tx->burst_abort_missing_next_frame_cnt,
- max_tx->burst_abort_missing_next_frame_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "cts_timeout_collision:",
- le32_to_cpu(tx->cts_timeout_collision),
- accum_tx->cts_timeout_collision,
- delta_tx->cts_timeout_collision,
- max_tx->cts_timeout_collision);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "ack_ba_timeout_collision:",
- le32_to_cpu(tx->ack_or_ba_timeout_collision),
- accum_tx->ack_or_ba_timeout_collision,
- delta_tx->ack_or_ba_timeout_collision,
- max_tx->ack_or_ba_timeout_collision);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg ba_timeout:",
- le32_to_cpu(tx->agg.ba_timeout),
- accum_tx->agg.ba_timeout,
- delta_tx->agg.ba_timeout,
- max_tx->agg.ba_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg ba_resched_frames:",
- le32_to_cpu(tx->agg.ba_reschedule_frames),
- accum_tx->agg.ba_reschedule_frames,
- delta_tx->agg.ba_reschedule_frames,
- max_tx->agg.ba_reschedule_frames);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg scd_query_agg_frame:",
- le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
- accum_tx->agg.scd_query_agg_frame_cnt,
- delta_tx->agg.scd_query_agg_frame_cnt,
- max_tx->agg.scd_query_agg_frame_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg scd_query_no_agg:",
- le32_to_cpu(tx->agg.scd_query_no_agg),
- accum_tx->agg.scd_query_no_agg,
- delta_tx->agg.scd_query_no_agg,
- max_tx->agg.scd_query_no_agg);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg scd_query_agg:",
- le32_to_cpu(tx->agg.scd_query_agg),
- accum_tx->agg.scd_query_agg,
- delta_tx->agg.scd_query_agg,
- max_tx->agg.scd_query_agg);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg scd_query_mismatch:",
- le32_to_cpu(tx->agg.scd_query_mismatch),
- accum_tx->agg.scd_query_mismatch,
- delta_tx->agg.scd_query_mismatch,
- max_tx->agg.scd_query_mismatch);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg frame_not_ready:",
- le32_to_cpu(tx->agg.frame_not_ready),
- accum_tx->agg.frame_not_ready,
- delta_tx->agg.frame_not_ready,
- max_tx->agg.frame_not_ready);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg underrun:",
- le32_to_cpu(tx->agg.underrun),
- accum_tx->agg.underrun,
- delta_tx->agg.underrun, max_tx->agg.underrun);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg bt_prio_kill:",
- le32_to_cpu(tx->agg.bt_prio_kill),
- accum_tx->agg.bt_prio_kill,
- delta_tx->agg.bt_prio_kill,
- max_tx->agg.bt_prio_kill);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg rx_ba_rsp_cnt:",
- le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
- accum_tx->agg.rx_ba_rsp_cnt,
- delta_tx->agg.rx_ba_rsp_cnt,
- max_tx->agg.rx_ba_rsp_cnt);
-
- if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
- pos += scnprintf(buf + pos, bufsz - pos,
- "tx power: (1/2 dB step)\n");
- if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_hex, "antenna A:",
- tx->tx_power.ant_a);
- if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_hex, "antenna B:",
- tx->tx_power.ant_b);
- if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_hex, "antenna C:",
- tx->tx_power.ant_c);
- }
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
-
-ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = file->private_data;
- int pos = 0;
- char *buf;
- int bufsz = sizeof(struct statistics_general) * 10 + 300;
- ssize_t ret;
- struct statistics_general_common *general, *accum_general;
- struct statistics_general_common *delta_general, *max_general;
- struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
- struct statistics_div *div, *accum_div, *delta_div, *max_div;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IWL_ERR(priv, "Can not allocate Buffer\n");
- return -ENOMEM;
- }
-
- /* the statistic information display here is based on
- * the last statistics notification from uCode
- * might not reflect the current uCode activity
- */
- if (iwl_bt_statistics(priv)) {
- general = &priv->_agn.statistics_bt.general.common;
- dbg = &priv->_agn.statistics_bt.general.common.dbg;
- div = &priv->_agn.statistics_bt.general.common.div;
- accum_general = &priv->_agn.accum_statistics_bt.general.common;
- accum_dbg = &priv->_agn.accum_statistics_bt.general.common.dbg;
- accum_div = &priv->_agn.accum_statistics_bt.general.common.div;
- delta_general = &priv->_agn.delta_statistics_bt.general.common;
- max_general = &priv->_agn.max_delta_bt.general.common;
- delta_dbg = &priv->_agn.delta_statistics_bt.general.common.dbg;
- max_dbg = &priv->_agn.max_delta_bt.general.common.dbg;
- delta_div = &priv->_agn.delta_statistics_bt.general.common.div;
- max_div = &priv->_agn.max_delta_bt.general.common.div;
- } else {
- general = &priv->_agn.statistics.general.common;
- dbg = &priv->_agn.statistics.general.common.dbg;
- div = &priv->_agn.statistics.general.common.div;
- accum_general = &priv->_agn.accum_statistics.general.common;
- accum_dbg = &priv->_agn.accum_statistics.general.common.dbg;
- accum_div = &priv->_agn.accum_statistics.general.common.div;
- delta_general = &priv->_agn.delta_statistics.general.common;
- max_general = &priv->_agn.max_delta.general.common;
- delta_dbg = &priv->_agn.delta_statistics.general.common.dbg;
- max_dbg = &priv->_agn.max_delta.general.common.dbg;
- delta_div = &priv->_agn.delta_statistics.general.common.div;
- max_div = &priv->_agn.max_delta.general.common.div;
- }
-
- pos += iwl_statistics_flag(priv, buf, bufsz);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_General:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_value, "temperature:",
- le32_to_cpu(general->temperature));
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_value, "temperature_m:",
- le32_to_cpu(general->temperature_m));
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_value, "ttl_timestamp:",
- le32_to_cpu(general->ttl_timestamp));
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "burst_check:",
- le32_to_cpu(dbg->burst_check),
- accum_dbg->burst_check,
- delta_dbg->burst_check, max_dbg->burst_check);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "burst_count:",
- le32_to_cpu(dbg->burst_count),
- accum_dbg->burst_count,
- delta_dbg->burst_count, max_dbg->burst_count);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "wait_for_silence_timeout_count:",
- le32_to_cpu(dbg->wait_for_silence_timeout_cnt),
- accum_dbg->wait_for_silence_timeout_cnt,
- delta_dbg->wait_for_silence_timeout_cnt,
- max_dbg->wait_for_silence_timeout_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sleep_time:",
- le32_to_cpu(general->sleep_time),
- accum_general->sleep_time,
- delta_general->sleep_time, max_general->sleep_time);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "slots_out:",
- le32_to_cpu(general->slots_out),
- accum_general->slots_out,
- delta_general->slots_out, max_general->slots_out);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "slots_idle:",
- le32_to_cpu(general->slots_idle),
- accum_general->slots_idle,
- delta_general->slots_idle, max_general->slots_idle);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "tx_on_a:",
- le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
- delta_div->tx_on_a, max_div->tx_on_a);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "tx_on_b:",
- le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
- delta_div->tx_on_b, max_div->tx_on_b);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "exec_time:",
- le32_to_cpu(div->exec_time), accum_div->exec_time,
- delta_div->exec_time, max_div->exec_time);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "probe_time:",
- le32_to_cpu(div->probe_time), accum_div->probe_time,
- delta_div->probe_time, max_div->probe_time);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "rx_enable_counter:",
- le32_to_cpu(general->rx_enable_counter),
- accum_general->rx_enable_counter,
- delta_general->rx_enable_counter,
- max_general->rx_enable_counter);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "num_of_sos_states:",
- le32_to_cpu(general->num_of_sos_states),
- accum_general->num_of_sos_states,
- delta_general->num_of_sos_states,
- max_general->num_of_sos_states);
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
-
-ssize_t iwl_ucode_bt_stats_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
- int pos = 0;
- char *buf;
- int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200;
- ssize_t ret;
- struct statistics_bt_activity *bt, *accum_bt;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- if (!priv->bt_enable_flag)
- return -EINVAL;
-
- /* make request to uCode to retrieve statistics information */
- mutex_lock(&priv->mutex);
- ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
- mutex_unlock(&priv->mutex);
-
- if (ret) {
- IWL_ERR(priv,
- "Error sending statistics request: %zd\n", ret);
- return -EAGAIN;
- }
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IWL_ERR(priv, "Can not allocate Buffer\n");
- return -ENOMEM;
- }
-
- /*
- * the statistic information display here is based on
- * the last statistics notification from uCode
- * might not reflect the current uCode activity
- */
- bt = &priv->_agn.statistics_bt.general.activity;
- accum_bt = &priv->_agn.accum_statistics_bt.general.activity;
-
- pos += iwl_statistics_flag(priv, buf, bufsz);
- pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n");
- pos += scnprintf(buf + pos, bufsz - pos,
- "\t\t\tcurrent\t\t\taccumulative\n");
- pos += scnprintf(buf + pos, bufsz - pos,
- "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
- le32_to_cpu(bt->hi_priority_tx_req_cnt),
- accum_bt->hi_priority_tx_req_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
- le32_to_cpu(bt->hi_priority_tx_denied_cnt),
- accum_bt->hi_priority_tx_denied_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
- le32_to_cpu(bt->lo_priority_tx_req_cnt),
- accum_bt->lo_priority_tx_req_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
- le32_to_cpu(bt->lo_priority_tx_denied_cnt),
- accum_bt->lo_priority_tx_denied_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
- le32_to_cpu(bt->hi_priority_rx_req_cnt),
- accum_bt->hi_priority_rx_req_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
- le32_to_cpu(bt->hi_priority_rx_denied_cnt),
- accum_bt->hi_priority_rx_denied_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
- le32_to_cpu(bt->lo_priority_rx_req_cnt),
- accum_bt->lo_priority_rx_req_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
- le32_to_cpu(bt->lo_priority_rx_denied_cnt),
- accum_bt->lo_priority_rx_denied_cnt);
-
- pos += scnprintf(buf + pos, bufsz - pos,
- "(rx)num_bt_kills:\t\t%u\t\t\t%u\n",
- le32_to_cpu(priv->_agn.statistics_bt.rx.
- general.num_bt_kills),
- priv->_agn.accum_statistics_bt.rx.
- general.num_bt_kills);
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
-
-ssize_t iwl_reply_tx_error_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
- int pos = 0;
- char *buf;
- int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) +
- (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200;
- ssize_t ret;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IWL_ERR(priv, "Can not allocate Buffer\n");
- return -ENOMEM;
- }
-
- pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n");
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY),
- priv->_agn.reply_tx_stats.pp_delay);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES),
- priv->_agn.reply_tx_stats.pp_few_bytes);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO),
- priv->_agn.reply_tx_stats.pp_bt_prio);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD),
- priv->_agn.reply_tx_stats.pp_quiet_period);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK),
- priv->_agn.reply_tx_stats.pp_calc_ttak);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_tx_fail_reason(
- TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY),
- priv->_agn.reply_tx_stats.int_crossed_retry);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT),
- priv->_agn.reply_tx_stats.short_limit);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT),
- priv->_agn.reply_tx_stats.long_limit);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN),
- priv->_agn.reply_tx_stats.fifo_underrun);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW),
- priv->_agn.reply_tx_stats.drain_flow);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH),
- priv->_agn.reply_tx_stats.rfkill_flush);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE),
- priv->_agn.reply_tx_stats.life_expire);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS),
- priv->_agn.reply_tx_stats.dest_ps);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED),
- priv->_agn.reply_tx_stats.host_abort);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY),
- priv->_agn.reply_tx_stats.pp_delay);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID),
- priv->_agn.reply_tx_stats.sta_invalid);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED),
- priv->_agn.reply_tx_stats.frag_drop);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE),
- priv->_agn.reply_tx_stats.tid_disable);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED),
- priv->_agn.reply_tx_stats.fifo_flush);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_tx_fail_reason(
- TX_STATUS_FAIL_INSUFFICIENT_CF_POLL),
- priv->_agn.reply_tx_stats.insuff_cf_poll);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX),
- priv->_agn.reply_tx_stats.fail_hw_drop);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_tx_fail_reason(
- TX_STATUS_FAIL_NO_BEACON_ON_RADAR),
- priv->_agn.reply_tx_stats.sta_color_mismatch);
- pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
- priv->_agn.reply_tx_stats.unknown);
-
- pos += scnprintf(buf + pos, bufsz - pos,
- "\nStatistics_Agg_TX_Error:\n");
-
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK),
- priv->_agn.reply_agg_tx_stats.underrun);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK),
- priv->_agn.reply_agg_tx_stats.bt_prio);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK),
- priv->_agn.reply_agg_tx_stats.few_bytes);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK),
- priv->_agn.reply_agg_tx_stats.abort);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_agg_tx_fail_reason(
- AGG_TX_STATE_LAST_SENT_TTL_MSK),
- priv->_agn.reply_agg_tx_stats.last_sent_ttl);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_agg_tx_fail_reason(
- AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK),
- priv->_agn.reply_agg_tx_stats.last_sent_try);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_agg_tx_fail_reason(
- AGG_TX_STATE_LAST_SENT_BT_KILL_MSK),
- priv->_agn.reply_agg_tx_stats.last_sent_bt_kill);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK),
- priv->_agn.reply_agg_tx_stats.scd_query);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_agg_tx_fail_reason(
- AGG_TX_STATE_TEST_BAD_CRC32_MSK),
- priv->_agn.reply_agg_tx_stats.bad_crc32);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK),
- priv->_agn.reply_agg_tx_stats.response);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK),
- priv->_agn.reply_agg_tx_stats.dump_tx);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK),
- priv->_agn.reply_agg_tx_stats.delay_tx);
- pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
- priv->_agn.reply_agg_tx_stats.unknown);
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
deleted file mode 100644
index f2573b5486c..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/******************************************************************************
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2008 - 2010 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:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *****************************************************************************/
-
-#include "iwl-dev.h"
-#include "iwl-core.h"
-#include "iwl-debug.h"
-
-#ifdef CONFIG_IWLWIFI_DEBUGFS
-ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-#else
-static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-static ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-static ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
index 27b5a3eec9d..2ef9448b1c2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -81,52 +81,13 @@
*
******************************************************************************/
-/*
- * 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 iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
-{
- u16 count;
- int ret;
-
- for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
- /* Request semaphore */
- iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-
- /* See if we got it */
- ret = iwl_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 (ret >= 0) {
- IWL_DEBUG_IO(priv,
- "Acquired semaphore after %d tries.\n",
- count+1);
- return ret;
- }
- }
-
- return ret;
-}
-
-void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv)
-{
- iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-
-}
-
int iwl_eeprom_check_version(struct iwl_priv *priv)
{
u16 eeprom_ver;
u16 calib_ver;
eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
- calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv);
+ calib_ver = iwlagn_eeprom_calib_version(priv);
if (eeprom_ver < priv->cfg->eeprom_ver ||
calib_ver < priv->cfg->eeprom_calib_ver)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 41543ad4cb8..b12c72d63cc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -37,54 +37,6 @@
#include "iwl-io.h"
#include "iwl-agn.h"
-int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
- struct iwl_rxon_context *ctx)
-{
- int ret = 0;
- struct iwl5000_rxon_assoc_cmd rxon_assoc;
- const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
- const struct iwl_rxon_cmd *rxon2 = &ctx->active;
-
- if ((rxon1->flags == rxon2->flags) &&
- (rxon1->filter_flags == rxon2->filter_flags) &&
- (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
- (rxon1->ofdm_ht_single_stream_basic_rates ==
- rxon2->ofdm_ht_single_stream_basic_rates) &&
- (rxon1->ofdm_ht_dual_stream_basic_rates ==
- rxon2->ofdm_ht_dual_stream_basic_rates) &&
- (rxon1->ofdm_ht_triple_stream_basic_rates ==
- rxon2->ofdm_ht_triple_stream_basic_rates) &&
- (rxon1->acquisition_data == rxon2->acquisition_data) &&
- (rxon1->rx_chain == rxon2->rx_chain) &&
- (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
- IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
- return 0;
- }
-
- rxon_assoc.flags = ctx->staging.flags;
- rxon_assoc.filter_flags = ctx->staging.filter_flags;
- rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
- rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
- rxon_assoc.reserved1 = 0;
- rxon_assoc.reserved2 = 0;
- rxon_assoc.reserved3 = 0;
- rxon_assoc.ofdm_ht_single_stream_basic_rates =
- ctx->staging.ofdm_ht_single_stream_basic_rates;
- rxon_assoc.ofdm_ht_dual_stream_basic_rates =
- ctx->staging.ofdm_ht_dual_stream_basic_rates;
- rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
- rxon_assoc.ofdm_ht_triple_stream_basic_rates =
- ctx->staging.ofdm_ht_triple_stream_basic_rates;
- rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
-
- ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
- sizeof(rxon_assoc), &rxon_assoc, NULL);
- if (ret)
- return ret;
-
- return ret;
-}
-
int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
{
struct iwl_tx_ant_config_cmd tx_ant_cmd = {
@@ -102,12 +54,6 @@ int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
}
}
-/* Currently this is the superset of everything */
-static u16 iwlagn_get_hcmd_size(u8 cmd_id, u16 len)
-{
- return len;
-}
-
static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
{
u16 size = (u16)sizeof(struct iwl_addsta_cmd);
@@ -364,7 +310,6 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
}
struct iwl_hcmd_ops iwlagn_hcmd = {
- .rxon_assoc = iwlagn_send_rxon_assoc,
.commit_rxon = iwlagn_commit_rxon,
.set_rxon_chain = iwlagn_set_rxon_chain,
.set_tx_ant = iwlagn_send_tx_ant_config,
@@ -373,7 +318,6 @@ struct iwl_hcmd_ops iwlagn_hcmd = {
};
struct iwl_hcmd_ops iwlagn_bt_hcmd = {
- .rxon_assoc = iwlagn_send_rxon_assoc,
.commit_rxon = iwlagn_commit_rxon,
.set_rxon_chain = iwlagn_set_rxon_chain,
.set_tx_ant = iwlagn_send_tx_ant_config,
@@ -382,7 +326,6 @@ struct iwl_hcmd_ops iwlagn_bt_hcmd = {
};
struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
- .get_hcmd_size = iwlagn_get_hcmd_size,
.build_addsta_hcmd = iwlagn_build_addsta_hcmd,
.gain_computation = iwlagn_gain_computation,
.chain_noise_reset = iwlagn_chain_noise_reset,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
index a52b82c8e7a..7bd19f4e66d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
index ed0148d714d..0d5fda44c3a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -59,8 +59,6 @@ void iwl_free_isr_ict(struct iwl_priv *priv)
int iwl_alloc_isr_ict(struct iwl_priv *priv)
{
- if (priv->cfg->base_params->use_isr_legacy)
- return 0;
/* allocate shrared data table */
priv->_agn.ict_tbl_vir =
dma_alloc_coherent(&priv->pci_dev->dev,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.c b/drivers/net/wireless/iwlwifi/iwl-agn-led.c
deleted file mode 100644
index c1190d96561..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-agn-led.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2010 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:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/wireless.h>
-#include <net/mac80211.h>
-#include <linux/etherdevice.h>
-#include <asm/unaligned.h>
-
-#include "iwl-commands.h"
-#include "iwl-dev.h"
-#include "iwl-core.h"
-#include "iwl-io.h"
-#include "iwl-agn-led.h"
-
-/* Send led command */
-static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
-{
- struct iwl_host_cmd cmd = {
- .id = REPLY_LEDS_CMD,
- .len = sizeof(struct iwl_led_cmd),
- .data = led_cmd,
- .flags = CMD_ASYNC,
- .callback = NULL,
- };
- u32 reg;
-
- reg = iwl_read32(priv, CSR_LED_REG);
- if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
- iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
-
- return iwl_send_cmd(priv, &cmd);
-}
-
-/* Set led register off */
-void iwlagn_led_enable(struct iwl_priv *priv)
-{
- iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
-}
-
-const struct iwl_led_ops iwlagn_led_ops = {
- .cmd = iwl_send_led_cmd,
-};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 08ccb9496f7..8e79653aed9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -172,6 +172,7 @@ static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status)
static void iwlagn_set_tx_status(struct iwl_priv *priv,
struct ieee80211_tx_info *info,
+ struct iwl_rxon_context *ctx,
struct iwlagn_tx_resp *tx_resp,
int txq_id, bool is_agg)
{
@@ -186,6 +187,13 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv,
if (!iwl_is_tx_success(status))
iwlagn_count_tx_err_status(priv, status);
+ if (status == TX_STATUS_FAIL_PASSIVE_NO_RX &&
+ iwl_is_associated_ctx(ctx) && ctx->vif &&
+ ctx->vif->type == NL80211_IFTYPE_STATION) {
+ ctx->last_tx_rejected = true;
+ iwl_stop_queue(priv, &priv->txq[txq_id]);
+ }
+
IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags "
"0x%x retries %d\n",
txq_id,
@@ -242,15 +250,16 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
/* # frames attempted by Tx command */
if (agg->frame_count == 1) {
+ struct iwl_tx_info *txb;
+
/* Only one frame was attempted; no block-ack will arrive */
idx = start_idx;
IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
agg->frame_count, agg->start_idx, idx);
- iwlagn_set_tx_status(priv,
- IEEE80211_SKB_CB(
- priv->txq[txq_id].txb[idx].skb),
- tx_resp, txq_id, true);
+ txb = &priv->txq[txq_id].txb[idx];
+ iwlagn_set_tx_status(priv, IEEE80211_SKB_CB(txb->skb),
+ txb->ctx, tx_resp, txq_id, true);
agg->wait_for_ba = 0;
} else {
/* Two or more frames were attempted; expect block-ack */
@@ -391,7 +400,8 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct ieee80211_tx_info *info;
struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
- u32 status = le16_to_cpu(tx_resp->status.status);
+ struct iwl_tx_info *txb;
+ u32 status = le16_to_cpu(tx_resp->status.status);
int tid;
int sta_id;
int freed;
@@ -406,7 +416,8 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
}
txq->time_stamp = jiffies;
- info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
+ txb = &txq->txb[txq->q.read_ptr];
+ info = IEEE80211_SKB_CB(txb->skb);
memset(&info->status, 0, sizeof(info->status));
tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >>
@@ -450,12 +461,14 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
iwl_wake_queue(priv, txq);
}
} else {
- iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false);
+ iwlagn_set_tx_status(priv, info, txb->ctx, tx_resp,
+ txq_id, false);
freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
if (priv->mac80211_registered &&
- (iwl_queue_space(&txq->q) > txq->q.low_mark))
+ iwl_queue_space(&txq->q) > txq->q.low_mark &&
+ status != TX_STATUS_FAIL_PASSIVE_NO_RX)
iwl_wake_queue(priv, txq);
}
@@ -470,8 +483,6 @@ void iwlagn_rx_handler_setup(struct iwl_priv *priv)
/* init calibration handlers */
priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] =
iwlagn_rx_calib_result;
- priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] =
- iwlagn_rx_calib_complete;
priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx;
/* set up notification wait support */
@@ -482,8 +493,10 @@ void iwlagn_rx_handler_setup(struct iwl_priv *priv)
void iwlagn_setup_deferred_work(struct iwl_priv *priv)
{
- /* in agn, the tx power calibration is done in uCode */
- priv->disable_tx_power_cal = 1;
+ /*
+ * nothing need to be done here anymore
+ * still keep for future use if needed
+ */
}
int iwlagn_hw_valid_rtc_data_addr(u32 addr)
@@ -534,9 +547,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
void iwlagn_temperature(struct iwl_priv *priv)
{
/* store temperature from correct statistics (in Celsius) */
- priv->temperature = le32_to_cpu((iwl_bt_statistics(priv)) ?
- priv->_agn.statistics_bt.general.common.temperature :
- priv->_agn.statistics.general.common.temperature);
+ priv->temperature = le32_to_cpu(priv->statistics.common.temperature);
iwl_tt_handler(priv);
}
@@ -652,10 +663,9 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
- if (!priv->cfg->base_params->use_isr_legacy)
- rb_timeout = RX_RB_TIMEOUT;
+ rb_timeout = RX_RB_TIMEOUT;
- if (priv->cfg->mod_params->amsdu_size_8K)
+ if (iwlagn_mod_params.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;
@@ -913,7 +923,6 @@ void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority)
list_add_tail(&rxb->list, &rxq->rx_free);
rxq->free_count++;
- priv->alloc_rxb_page++;
spin_unlock_irqrestore(&rxq->lock, flags);
}
@@ -1285,9 +1294,17 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
* mean we never reach it, but at the same time work around
* the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
* here instead of IWL_GOOD_CRC_TH_DISABLED.
+ *
+ * This was fixed in later versions along with some other
+ * scan changes, and the threshold behaves as a flag in those
+ * versions.
*/
- scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
- IWL_GOOD_CRC_TH_NEVER;
+ if (priv->new_scan_threshold_behaviour)
+ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+ IWL_GOOD_CRC_TH_DISABLED;
+ else
+ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+ IWL_GOOD_CRC_TH_NEVER;
band = priv->scan_band;
@@ -2245,34 +2262,44 @@ int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
/* notification wait support */
void iwlagn_init_notification_wait(struct iwl_priv *priv,
struct iwl_notification_wait *wait_entry,
+ u8 cmd,
void (*fn)(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt),
- u8 cmd)
+ struct iwl_rx_packet *pkt,
+ void *data),
+ void *fn_data)
{
wait_entry->fn = fn;
+ wait_entry->fn_data = fn_data;
wait_entry->cmd = cmd;
wait_entry->triggered = false;
+ wait_entry->aborted = false;
spin_lock_bh(&priv->_agn.notif_wait_lock);
list_add(&wait_entry->list, &priv->_agn.notif_waits);
spin_unlock_bh(&priv->_agn.notif_wait_lock);
}
-signed long iwlagn_wait_notification(struct iwl_priv *priv,
- struct iwl_notification_wait *wait_entry,
- unsigned long timeout)
+int iwlagn_wait_notification(struct iwl_priv *priv,
+ struct iwl_notification_wait *wait_entry,
+ unsigned long timeout)
{
int ret;
ret = wait_event_timeout(priv->_agn.notif_waitq,
- wait_entry->triggered,
+ wait_entry->triggered || wait_entry->aborted,
timeout);
spin_lock_bh(&priv->_agn.notif_wait_lock);
list_del(&wait_entry->list);
spin_unlock_bh(&priv->_agn.notif_wait_lock);
- return ret;
+ if (wait_entry->aborted)
+ return -EIO;
+
+ /* return value is always >= 0 */
+ if (ret <= 0)
+ return -ETIMEDOUT;
+ return 0;
}
void iwlagn_remove_notification(struct iwl_priv *priv,
@@ -2282,3 +2309,87 @@ void iwlagn_remove_notification(struct iwl_priv *priv,
list_del(&wait_entry->list);
spin_unlock_bh(&priv->_agn.notif_wait_lock);
}
+
+int iwlagn_start_device(struct iwl_priv *priv)
+{
+ int ret;
+
+ if (iwl_prepare_card_hw(priv)) {
+ IWL_WARN(priv, "Exit HW not ready\n");
+ return -EIO;
+ }
+
+ /* If platform's RF_KILL switch is NOT set to KILL */
+ if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
+ clear_bit(STATUS_RF_KILL_HW, &priv->status);
+ else
+ set_bit(STATUS_RF_KILL_HW, &priv->status);
+
+ if (iwl_is_rfkill(priv)) {
+ wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
+ iwl_enable_interrupts(priv);
+ return -ERFKILL;
+ }
+
+ iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+
+ ret = iwlagn_hw_nic_init(priv);
+ if (ret) {
+ IWL_ERR(priv, "Unable to init nic\n");
+ return ret;
+ }
+
+ /* 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_DRV_GP1_BIT_CMD_BLOCKED);
+
+ /* clear (again), then enable host interrupts */
+ iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+ iwl_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);
+
+ return 0;
+}
+
+void iwlagn_stop_device(struct iwl_priv *priv)
+{
+ unsigned long flags;
+
+ /* stop and reset the on-board processor */
+ iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+
+ /* tell the device to stop sending interrupts */
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl_disable_interrupts(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ iwl_synchronize_irq(priv);
+
+ /* device going down, Stop using ICT table */
+ iwl_disable_ict(priv);
+
+ /*
+ * If a HW restart happens during firmware loading,
+ * then the firmware loading might call this function
+ * and later it might be called again due to the
+ * restart. So don't process again if the device is
+ * already dead.
+ */
+ if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) {
+ iwlagn_txq_ctx_stop(priv);
+ iwlagn_rxq_stop(priv);
+
+ /* Power-down device's busmaster DMA clocks */
+ iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
+ udelay(5);
+ }
+
+ /* Make sure (redundant) we've released our request to stay awake */
+ iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+
+ /* Stop the device, and put it in low power state */
+ iwl_apm_stop(priv);
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index d03b4734c89..91f26556ac2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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
@@ -115,13 +115,18 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
/* FIXME:RS: ^^ should be INV (legacy) */
};
+static inline u8 rs_extract_rate(u32 rate_n_flags)
+{
+ return (u8)(rate_n_flags & RATE_MCS_RATE_MSK);
+}
+
static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
{
int idx = 0;
/* HT rate format */
if (rate_n_flags & RATE_MCS_HT_MSK) {
- idx = (rate_n_flags & 0xff);
+ idx = rs_extract_rate(rate_n_flags);
if (idx >= IWL_RATE_MIMO3_6M_PLCP)
idx = idx - IWL_RATE_MIMO3_6M_PLCP;
@@ -138,7 +143,8 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
/* legacy rate format, search for match in table */
} else {
for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
- if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
+ if (iwl_rates[idx].plcp ==
+ rs_extract_rate(rate_n_flags))
return idx;
}
@@ -239,11 +245,6 @@ static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
#define MCS_INDEX_PER_STREAM (8)
-static inline u8 rs_extract_rate(u32 rate_n_flags)
-{
- return (u8)(rate_n_flags & 0xFF);
-}
-
static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
{
window->data = 0;
@@ -2770,16 +2771,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
gfp_t gfp)
{
- struct iwl_lq_sta *lq_sta;
struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv;
struct iwl_priv *priv;
priv = (struct iwl_priv *)priv_rate;
IWL_DEBUG_RATE(priv, "create station rate scale window\n");
- lq_sta = &sta_priv->lq_sta;
-
- return lq_sta;
+ return &sta_priv->lq_sta;
}
/*
@@ -2912,7 +2910,8 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
ant_toggle_cnt = 1;
repeat_rate = IWL_NUMBER_TRY;
} else {
- repeat_rate = IWL_HT_NUMBER_TRY;
+ repeat_rate = min(IWL_HT_NUMBER_TRY,
+ LINK_QUAL_AGG_DISABLE_START_DEF - 1);
}
lq_cmd->general_params.mimo_delimiter =
@@ -3087,7 +3086,7 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
struct iwl_lq_sta *lq_sta = file->private_data;
struct iwl_priv *priv;
char buf[64];
- int buf_size;
+ size_t buf_size;
u32 parsed_rate;
struct iwl_station_priv *sta_priv =
container_of(lq_sta, struct iwl_station_priv, lq_sta);
@@ -3257,7 +3256,6 @@ static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
{
char buff[120];
int desc = 0;
- ssize_t ret;
struct iwl_lq_sta *lq_sta = file->private_data;
struct iwl_priv *priv;
@@ -3274,8 +3272,7 @@ static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
"Bit Rate= %d Mb/s\n",
iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);
- ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
- return ret;
+ return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
}
static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index 184828c72b3..bdae82e7fa9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -41,20 +41,6 @@ struct iwl_rate_info {
u8 next_rs_tgg; /* next rate used in TGG rs algo */
};
-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 */
- u8 next_rs; /* next rate used in rs algo */
- u8 prev_rs_tgg; /* previous rate used in TGG rs algo */
- 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 iwl_rate_info iwl_rates[IWL_RATE_COUNT];
@@ -75,7 +61,6 @@ enum {
IWL_RATE_60M_INDEX,
IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/
IWL_RATE_COUNT_LEGACY = IWL_RATE_COUNT - 1, /* Excluding 60M */
- IWL_RATE_COUNT_3945 = IWL_RATE_COUNT - 1,
IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
IWL_RATE_INVALID = IWL_RATE_COUNT,
};
@@ -98,7 +83,6 @@ enum {
enum {
IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
- IWL39_LAST_OFDM_RATE = IWL_RATE_54M_INDEX,
IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX,
IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX,
IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
@@ -213,7 +197,6 @@ enum {
IWL_CCK_BASIC_RATES_MASK)
#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
-#define IWL_RATES_MASK_3945 ((1 << IWL_RATE_COUNT_3945) - 1)
#define IWL_INVALID_VALUE -1
@@ -453,19 +436,9 @@ static inline u8 first_antenna(u8 mask)
}
-/**
- * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
- *
- * 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 iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
-
/* Initialize station's rate scaling information after adding station */
extern void iwl_rs_rate_init(struct iwl_priv *priv,
struct ieee80211_sta *sta, u8 sta_id);
-extern void iwl3945_rs_rate_init(struct iwl_priv *priv,
- struct ieee80211_sta *sta, u8 sta_id);
/**
* iwl_rate_control_register - Register the rate control algorithm callbacks
@@ -478,7 +451,6 @@ extern void iwl3945_rs_rate_init(struct iwl_priv *priv,
*
*/
extern int iwlagn_rate_control_register(void);
-extern int iwl3945_rate_control_register(void);
/**
* iwl_rate_control_unregister - Unregister the rate control callbacks
@@ -487,6 +459,5 @@ extern int iwl3945_rate_control_register(void);
* the driver is unloaded.
*/
extern void iwlagn_rate_control_unregister(void);
-extern void iwl3945_rate_control_unregister(void);
#endif /* __iwl_agn__rs__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index fbbde0712fa..02387430f7f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -29,6 +29,7 @@
#include "iwl-sta.h"
#include "iwl-core.h"
#include "iwl-agn-calib.h"
+#include "iwl-helpers.h"
static int iwlagn_disable_bss(struct iwl_priv *priv,
struct iwl_rxon_context *ctx,
@@ -57,8 +58,9 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
u8 old_dev_type = send->dev_type;
int ret;
- iwlagn_init_notification_wait(priv, &disable_wait, NULL,
- REPLY_WIPAN_DEACTIVATION_COMPLETE);
+ iwlagn_init_notification_wait(priv, &disable_wait,
+ REPLY_WIPAN_DEACTIVATION_COMPLETE,
+ NULL, NULL);
send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
send->dev_type = RXON_DEV_TYPE_P2P;
@@ -71,13 +73,9 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
IWL_ERR(priv, "Error disabling PAN (%d)\n", ret);
iwlagn_remove_notification(priv, &disable_wait);
} else {
- signed long wait_res;
-
- wait_res = iwlagn_wait_notification(priv, &disable_wait, HZ);
- if (wait_res == 0) {
+ ret = iwlagn_wait_notification(priv, &disable_wait, HZ);
+ if (ret)
IWL_ERR(priv, "Timed out waiting for PAN disable\n");
- ret = -EIO;
- }
}
return ret;
@@ -123,6 +121,151 @@ static int iwlagn_update_beacon(struct iwl_priv *priv,
return iwlagn_send_beacon_cmd(priv);
}
+static int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ int ret = 0;
+ struct iwl_rxon_assoc_cmd rxon_assoc;
+ const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
+ const struct iwl_rxon_cmd *rxon2 = &ctx->active;
+
+ if ((rxon1->flags == rxon2->flags) &&
+ (rxon1->filter_flags == rxon2->filter_flags) &&
+ (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
+ (rxon1->ofdm_ht_single_stream_basic_rates ==
+ rxon2->ofdm_ht_single_stream_basic_rates) &&
+ (rxon1->ofdm_ht_dual_stream_basic_rates ==
+ rxon2->ofdm_ht_dual_stream_basic_rates) &&
+ (rxon1->ofdm_ht_triple_stream_basic_rates ==
+ rxon2->ofdm_ht_triple_stream_basic_rates) &&
+ (rxon1->acquisition_data == rxon2->acquisition_data) &&
+ (rxon1->rx_chain == rxon2->rx_chain) &&
+ (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
+ IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
+ return 0;
+ }
+
+ rxon_assoc.flags = ctx->staging.flags;
+ rxon_assoc.filter_flags = ctx->staging.filter_flags;
+ rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
+ rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
+ rxon_assoc.reserved1 = 0;
+ rxon_assoc.reserved2 = 0;
+ rxon_assoc.reserved3 = 0;
+ rxon_assoc.ofdm_ht_single_stream_basic_rates =
+ ctx->staging.ofdm_ht_single_stream_basic_rates;
+ rxon_assoc.ofdm_ht_dual_stream_basic_rates =
+ ctx->staging.ofdm_ht_dual_stream_basic_rates;
+ rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
+ rxon_assoc.ofdm_ht_triple_stream_basic_rates =
+ ctx->staging.ofdm_ht_triple_stream_basic_rates;
+ rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
+
+ ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
+ sizeof(rxon_assoc), &rxon_assoc, NULL);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int iwlagn_rxon_disconn(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ int ret;
+ struct iwl_rxon_cmd *active = (void *)&ctx->active;
+
+ if (ctx->ctxid == IWL_RXON_CTX_BSS)
+ ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
+ else
+ ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
+ if (ret)
+ return ret;
+
+ /*
+ * Un-assoc RXON clears the station table and WEP
+ * keys, so we have to restore those afterwards.
+ */
+ iwl_clear_ucode_stations(priv, ctx);
+ iwl_restore_stations(priv, ctx);
+ ret = iwl_restore_default_wep_keys(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
+ return ret;
+ }
+
+ memcpy(active, &ctx->staging, sizeof(*active));
+ return 0;
+}
+
+static int iwlagn_rxon_connect(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ int ret;
+ struct iwl_rxon_cmd *active = (void *)&ctx->active;
+
+ /* RXON timing must be before associated RXON */
+ ret = iwl_send_rxon_timing(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
+ return ret;
+ }
+ /* QoS info may be cleared by previous un-assoc RXON */
+ iwlagn_update_qos(priv, ctx);
+
+ /*
+ * We'll run into this code path when beaconing is
+ * enabled, but then we also need to send the beacon
+ * to the device.
+ */
+ if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
+ ret = iwlagn_update_beacon(priv, ctx->vif);
+ if (ret) {
+ IWL_ERR(priv,
+ "Error sending required beacon (%d)!\n",
+ ret);
+ return ret;
+ }
+ }
+
+ priv->start_calib = 0;
+ /*
+ * Apply the new configuration.
+ *
+ * Associated RXON doesn't clear the station table in uCode,
+ * so we don't need to restore stations etc. after this.
+ */
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+ sizeof(struct iwl_rxon_cmd), &ctx->staging);
+ if (ret) {
+ IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
+ return ret;
+ }
+ memcpy(active, &ctx->staging, sizeof(*active));
+
+ iwl_reprogram_ap_sta(priv, ctx);
+
+ /* IBSS beacon needs to be sent after setting assoc */
+ if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
+ if (iwlagn_update_beacon(priv, ctx->vif))
+ IWL_ERR(priv, "Error sending IBSS beacon\n");
+ iwl_init_sensitivity(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.
+ *
+ * It's expected we set power here if channel is changing.
+ */
+ ret = iwl_set_tx_power(priv, priv->tx_power_next, true);
+ if (ret) {
+ IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
/**
* iwlagn_commit_rxon - commit staging_rxon to hardware
*
@@ -130,6 +273,16 @@ static int iwlagn_update_beacon(struct iwl_priv *priv,
* 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.
+ *
+ * The connect/disconnect flow should be as the following:
+ *
+ * 1. make sure send RXON command with association bit unset if not connect
+ * this should include the channel and the band for the candidate
+ * to be connected to
+ * 2. Add Station before RXON association with the AP
+ * 3. RXON_timing has to send before RXON for connection
+ * 4. full RXON command - associated bit set
+ * 5. use RXON_ASSOC command to update any flags changes
*/
int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
@@ -179,6 +332,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
else
ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ iwl_print_rx_config_cmd(priv, ctx);
ret = iwl_check_rxon_cmd(priv, ctx);
if (ret) {
IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
@@ -202,14 +356,13 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
* and other flags for the current radio configuration.
*/
if (!iwl_full_rxon_required(priv, ctx)) {
- ret = iwl_send_rxon_assoc(priv, ctx);
+ ret = iwlagn_send_rxon_assoc(priv, ctx);
if (ret) {
IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
return ret;
}
memcpy(active, &ctx->staging, sizeof(*active));
- iwl_print_rx_config_cmd(priv, ctx);
return 0;
}
@@ -219,7 +372,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
return ret;
}
- iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
+ iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto);
IWL_DEBUG_INFO(priv,
"Going to commit RXON\n"
@@ -237,92 +390,13 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
* set up filters in the device.
*/
if ((old_assoc && new_assoc) || !new_assoc) {
- if (ctx->ctxid == IWL_RXON_CTX_BSS)
- ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
- else
- ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
+ ret = iwlagn_rxon_disconn(priv, ctx);
if (ret)
return ret;
-
- memcpy(active, &ctx->staging, sizeof(*active));
-
- /*
- * Un-assoc RXON clears the station table and WEP
- * keys, so we have to restore those afterwards.
- */
- iwl_clear_ucode_stations(priv, ctx);
- iwl_restore_stations(priv, ctx);
- ret = iwl_restore_default_wep_keys(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
- return ret;
- }
- }
-
- /* RXON timing must be before associated RXON */
- ret = iwl_send_rxon_timing(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
- return ret;
- }
-
- if (new_assoc) {
- /* QoS info may be cleared by previous un-assoc RXON */
- iwlagn_update_qos(priv, ctx);
-
- /*
- * We'll run into this code path when beaconing is
- * enabled, but then we also need to send the beacon
- * to the device.
- */
- if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
- ret = iwlagn_update_beacon(priv, ctx->vif);
- if (ret) {
- IWL_ERR(priv,
- "Error sending required beacon (%d)!\n",
- ret);
- return ret;
- }
- }
-
- priv->start_calib = 0;
- /*
- * Apply the new configuration.
- *
- * Associated RXON doesn't clear the station table in uCode,
- * so we don't need to restore stations etc. after this.
- */
- ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
- sizeof(struct iwl_rxon_cmd), &ctx->staging);
- if (ret) {
- IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
- return ret;
- }
- memcpy(active, &ctx->staging, sizeof(*active));
-
- iwl_reprogram_ap_sta(priv, ctx);
-
- /* IBSS beacon needs to be sent after setting assoc */
- if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
- if (iwlagn_update_beacon(priv, ctx->vif))
- IWL_ERR(priv, "Error sending IBSS beacon\n");
}
- iwl_print_rx_config_cmd(priv, ctx);
-
- iwl_init_sensitivity(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.
- *
- * It's expected we set power here if channel is changing.
- */
- ret = iwl_set_tx_power(priv, priv->tx_power_next, true);
- if (ret) {
- IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
- return ret;
- }
+ if (new_assoc)
+ return iwlagn_rxon_connect(priv, ctx);
return 0;
}
@@ -595,6 +669,18 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
priv->timestamp = bss_conf->timestamp;
ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
} else {
+ /*
+ * If we disassociate while there are pending
+ * frames, just wake up the queues and let the
+ * frames "escape" ... This shouldn't really
+ * be happening to start with, but we should
+ * not get stuck in this case either since it
+ * can happen if userspace gets confused.
+ */
+ if (ctx->last_tx_rejected) {
+ ctx->last_tx_rejected = false;
+ iwl_wake_any_queue(priv, ctx);
+ }
ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
}
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index 35f085ac336..079275f2c64 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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.
@@ -474,7 +474,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
memset(&priv->stations[sta_id].keyinfo, 0,
sizeof(struct iwl_hw_key));
memset(&priv->stations[sta_id].sta.key, 0,
- sizeof(struct iwl4965_keyinfo));
+ sizeof(struct iwl_keyinfo));
priv->stations[sta_id].sta.key.key_flags =
STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
index e3a8216a033..348f74f1c8e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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.
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
index d55060427ca..d118ed29bf3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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.
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 0712b67283a..342de780a36 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -98,9 +98,9 @@ static inline int get_fifo_from_tid(struct iwl_rxon_context *ctx, u16 tid)
/**
* iwlagn_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
*/
-void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
- struct iwl_tx_queue *txq,
- u16 byte_cnt)
+static void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ u16 byte_cnt)
{
struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
int write_ptr = txq->q.write_ptr;
@@ -112,21 +112,19 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
- if (txq_id != priv->cmd_queue) {
- sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
- sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
-
- switch (sec_ctl & TX_CMD_SEC_MSK) {
- case TX_CMD_SEC_CCM:
- len += CCMP_MIC_LEN;
- break;
- case TX_CMD_SEC_TKIP:
- len += TKIP_ICV_LEN;
- break;
- case TX_CMD_SEC_WEP:
- len += WEP_IV_LEN + WEP_ICV_LEN;
- break;
- }
+ sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
+ sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
+
+ switch (sec_ctl & TX_CMD_SEC_MSK) {
+ case TX_CMD_SEC_CCM:
+ len += CCMP_MIC_LEN;
+ break;
+ case TX_CMD_SEC_TKIP:
+ len += TKIP_ICV_LEN;
+ break;
+ case TX_CMD_SEC_WEP:
+ len += WEP_IV_LEN + WEP_ICV_LEN;
+ break;
}
bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
@@ -138,8 +136,8 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
}
-void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
- struct iwl_tx_queue *txq)
+static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq)
{
struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
int txq_id = txq->q.id;
@@ -222,13 +220,8 @@ void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
}
-int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
- int tx_fifo, int sta_id, int tid, u16 ssn_idx)
+static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, int sta_id, int tid)
{
- unsigned long flags;
- u16 ra_tid;
- int ret;
-
if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
(IWLAGN_FIRST_AMPDU_QUEUE +
priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
@@ -240,12 +233,33 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
return -EINVAL;
}
- ra_tid = BUILD_RAxTID(sta_id, tid);
-
/* Modify device's station table to Tx this TID */
- ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
- if (ret)
- return ret;
+ return iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
+}
+
+void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv,
+ struct ieee80211_sta *sta,
+ int tid, int frame_limit)
+{
+ int sta_id, tx_fifo, txq_id, ssn_idx;
+ u16 ra_tid;
+ unsigned long flags;
+ struct iwl_tid_data *tid_data;
+
+ sta_id = iwl_sta_id(sta);
+ if (WARN_ON(sta_id == IWL_INVALID_STATION))
+ return;
+ if (WARN_ON(tid >= MAX_TID_COUNT))
+ return;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ tid_data = &priv->stations[sta_id].tid[tid];
+ ssn_idx = SEQ_TO_SN(tid_data->seq_number);
+ txq_id = tid_data->agg.txq_id;
+ tx_fifo = tid_data->agg.tx_fifo;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ ra_tid = BUILD_RAxTID(sta_id, tid);
spin_lock_irqsave(&priv->lock, flags);
@@ -271,10 +285,10 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
iwl_write_targ_mem(priv, priv->scd_base_addr +
IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
sizeof(u32),
- ((SCD_WIN_SIZE <<
+ ((frame_limit <<
IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
- ((SCD_FRAME_LIMIT <<
+ ((frame_limit <<
IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
@@ -284,12 +298,10 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
}
-int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
- u16 ssn_idx, u8 tx_fifo)
+static int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
+ u16 ssn_idx, u8 tx_fifo)
{
if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
(IWLAGN_FIRST_AMPDU_QUEUE +
@@ -525,7 +537,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
struct iwl_tx_cmd *tx_cmd;
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
int txq_id;
- dma_addr_t phys_addr;
+ dma_addr_t phys_addr = 0;
dma_addr_t txcmd_phys;
dma_addr_t scratch_phys;
u16 len, firstlen, secondlen;
@@ -552,7 +564,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
spin_lock_irqsave(&priv->lock, flags);
if (iwl_is_rfkill(priv)) {
IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
- goto drop_unlock;
+ goto drop_unlock_priv;
}
fc = hdr->frame_control;
@@ -577,7 +589,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
- goto drop_unlock;
+ goto drop_unlock_priv;
}
}
@@ -621,10 +633,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (ieee80211_is_data_qos(fc)) {
qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
- if (WARN_ON_ONCE(tid >= MAX_TID_COUNT)) {
- spin_unlock(&priv->sta_lock);
- goto drop_unlock;
- }
+
+ if (WARN_ON_ONCE(tid >= MAX_TID_COUNT))
+ goto drop_unlock_sta;
+
seq_number = priv->stations[sta_id].tid[tid].seq_number;
seq_number &= IEEE80211_SCTL_SEQ;
hdr->seq_ctrl = hdr->seq_ctrl &
@@ -642,18 +654,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
txq = &priv->txq[txq_id];
q = &txq->q;
- if (unlikely(iwl_queue_space(q) < q->high_mark)) {
- spin_unlock(&priv->sta_lock);
- goto drop_unlock;
- }
-
- if (ieee80211_is_data_qos(fc)) {
- priv->stations[sta_id].tid[tid].tfds_in_queue++;
- if (!ieee80211_has_morefrags(fc))
- priv->stations[sta_id].tid[tid].seq_number = seq_number;
- }
-
- spin_unlock(&priv->sta_lock);
+ if (unlikely(iwl_queue_space(q) < q->high_mark))
+ goto drop_unlock_sta;
/* Set up driver data for this TFD */
memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
@@ -717,12 +719,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
txcmd_phys = pci_map_single(priv->pci_dev,
&out_cmd->hdr, firstlen,
PCI_DMA_BIDIRECTIONAL);
+ if (unlikely(pci_dma_mapping_error(priv->pci_dev, txcmd_phys)))
+ goto drop_unlock_sta;
dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
dma_unmap_len_set(out_meta, len, firstlen);
- /* Add buffer containing Tx command and MAC(!) header to TFD's
- * first entry */
- priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
- txcmd_phys, firstlen, 1, 0);
if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1;
@@ -737,10 +737,30 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (secondlen > 0) {
phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
secondlen, PCI_DMA_TODEVICE);
+ if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) {
+ pci_unmap_single(priv->pci_dev,
+ dma_unmap_addr(out_meta, mapping),
+ dma_unmap_len(out_meta, len),
+ PCI_DMA_BIDIRECTIONAL);
+ goto drop_unlock_sta;
+ }
+ }
+
+ if (ieee80211_is_data_qos(fc)) {
+ priv->stations[sta_id].tid[tid].tfds_in_queue++;
+ if (!ieee80211_has_morefrags(fc))
+ priv->stations[sta_id].tid[tid].seq_number = seq_number;
+ }
+
+ spin_unlock(&priv->sta_lock);
+
+ /* Attach buffers to TFD */
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ txcmd_phys, firstlen, 1, 0);
+ if (secondlen > 0)
priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
phys_addr, secondlen,
0, 0);
- }
scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
offsetof(struct iwl_tx_cmd, scratch);
@@ -759,8 +779,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Set up entry for this TFD in Tx byte-count array */
if (info->flags & IEEE80211_TX_CTL_AMPDU)
- priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq,
- le16_to_cpu(tx_cmd->len));
+ iwlagn_txq_update_byte_cnt_tbl(priv, txq,
+ le16_to_cpu(tx_cmd->len));
pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
firstlen, PCI_DMA_BIDIRECTIONAL);
@@ -806,7 +826,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
return 0;
-drop_unlock:
+drop_unlock_sta:
+ spin_unlock(&priv->sta_lock);
+drop_unlock_priv:
spin_unlock_irqrestore(&priv->lock, flags);
return -1;
}
@@ -1039,11 +1061,11 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
tid_data = &priv->stations[sta_id].tid[tid];
*ssn = SEQ_TO_SN(tid_data->seq_number);
tid_data->agg.txq_id = txq_id;
+ tid_data->agg.tx_fifo = tx_fifo;
iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id);
spin_unlock_irqrestore(&priv->sta_lock, flags);
- ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo,
- sta_id, tid, *ssn);
+ ret = iwlagn_txq_agg_enable(priv, txq_id, sta_id, tid);
if (ret)
return ret;
@@ -1130,8 +1152,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
* to deactivate the uCode queue, just return "success" to allow
* mac80211 to clean up it own data.
*/
- priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn,
- tx_fifo_id);
+ iwlagn_txq_agg_disable(priv, txq_id, ssn, tx_fifo_id);
spin_unlock_irqrestore(&priv->lock, flags);
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
@@ -1160,8 +1181,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
u16 ssn = SEQ_TO_SN(tid_data->seq_number);
int tx_fifo = get_fifo_from_tid(ctx, tid);
IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
- priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
- ssn, tx_fifo);
+ iwlagn_txq_agg_disable(priv, txq_id, ssn, tx_fifo);
tid_data->agg.state = IWL_AGG_OFF;
ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
}
@@ -1241,8 +1261,7 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
txq_id >= IWLAGN_FIRST_AMPDU_QUEUE);
tx_info->skb = NULL;
- if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
- priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
+ iwlagn_txq_inval_byte_cnt_tbl(priv, txq);
priv->cfg->ops->lib->txq_free_tfd(priv, txq);
}
@@ -1260,11 +1279,11 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
struct iwl_compressed_ba_resp *ba_resp)
{
- int i, sh, ack;
+ int sh;
u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
- int successes = 0;
struct ieee80211_tx_info *info;
+ u64 bitmap, sent_bitmap;
if (unlikely(!agg->wait_for_ba)) {
if (unlikely(ba_resp->bitmap))
@@ -1278,70 +1297,42 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
/* Calculate shift to align block-ack bits with our Tx window bits */
sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4);
- if (sh < 0) /* tbw something is wrong with indices */
+ if (sh < 0)
sh += 0x100;
- if (agg->frame_count > (64 - sh)) {
- IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
- return -1;
- }
- if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
+ /*
+ * Check for success or failure according to the
+ * transmitted bitmap and block-ack bitmap
+ */
+ bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
+ sent_bitmap = bitmap & agg->bitmap;
+
+ /* Sanity check values reported by uCode */
+ if (ba_resp->txed_2_done > ba_resp->txed) {
+ IWL_DEBUG_TX_REPLY(priv,
+ "bogus sent(%d) and ack(%d) count\n",
+ ba_resp->txed, ba_resp->txed_2_done);
/*
- * sent and ack information provided by uCode
- * use it instead of figure out ourself
+ * set txed_2_done = txed,
+ * so it won't impact rate scale
*/
- if (ba_resp->txed_2_done > ba_resp->txed) {
- IWL_DEBUG_TX_REPLY(priv,
- "bogus sent(%d) and ack(%d) count\n",
- ba_resp->txed, ba_resp->txed_2_done);
- /*
- * set txed_2_done = txed,
- * so it won't impact rate scale
- */
- ba_resp->txed = ba_resp->txed_2_done;
- }
- IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
- ba_resp->txed, ba_resp->txed_2_done);
- } else {
- u64 bitmap, sent_bitmap;
-
- /* don't use 64-bit values for now */
- bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
-
- /* check for success or failure according to the
- * transmitted bitmap and block-ack bitmap */
- sent_bitmap = bitmap & agg->bitmap;
-
- /* For each frame attempted in aggregation,
- * update driver's record of tx frame's status. */
- i = 0;
- while (sent_bitmap) {
- ack = sent_bitmap & 1ULL;
- successes += ack;
- IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
- ack ? "ACK" : "NACK", i,
- (agg->start_idx + i) & 0xff,
- agg->start_idx + i);
- sent_bitmap >>= 1;
- ++i;
- }
+ ba_resp->txed = ba_resp->txed_2_done;
+ }
+ IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
+ ba_resp->txed, ba_resp->txed_2_done);
- IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n",
- (unsigned long long)bitmap);
+ /* Find the first ACKed frame to store the TX status */
+ while (sent_bitmap && !(sent_bitmap & 1)) {
+ agg->start_idx = (agg->start_idx + 1) & 0xff;
+ sent_bitmap >>= 1;
}
info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb);
memset(&info->status, 0, sizeof(info->status));
info->flags |= IEEE80211_TX_STAT_ACK;
info->flags |= IEEE80211_TX_STAT_AMPDU;
- if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
- info->status.ampdu_ack_len = ba_resp->txed_2_done;
- info->status.ampdu_len = ba_resp->txed;
-
- } else {
- info->status.ampdu_ack_len = successes;
- info->status.ampdu_len = agg->frame_count;
- }
+ info->status.ampdu_ack_len = ba_resp->txed_2_done;
+ info->status.ampdu_len = ba_resp->txed;
iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index d807e5e2b71..8bda0e8d666 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -161,47 +161,19 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name,
}
static int iwlagn_load_given_ucode(struct iwl_priv *priv,
- struct fw_desc *inst_image,
- struct fw_desc *data_image)
+ struct fw_img *image)
{
int ret = 0;
- ret = iwlagn_load_section(priv, "INST", inst_image,
+ ret = iwlagn_load_section(priv, "INST", &image->code,
IWLAGN_RTC_INST_LOWER_BOUND);
if (ret)
return ret;
- return iwlagn_load_section(priv, "DATA", data_image,
+ return iwlagn_load_section(priv, "DATA", &image->data,
IWLAGN_RTC_DATA_LOWER_BOUND);
}
-int iwlagn_load_ucode(struct iwl_priv *priv)
-{
- int ret = 0;
-
- /* check whether init ucode should be loaded, or rather runtime ucode */
- if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) {
- IWL_DEBUG_INFO(priv, "Init ucode found. Loading init ucode...\n");
- ret = iwlagn_load_given_ucode(priv,
- &priv->ucode_init, &priv->ucode_init_data);
- if (!ret) {
- IWL_DEBUG_INFO(priv, "Init ucode load complete.\n");
- priv->ucode_type = UCODE_INIT;
- }
- } else {
- IWL_DEBUG_INFO(priv, "Init ucode not found, or already loaded. "
- "Loading runtime ucode...\n");
- ret = iwlagn_load_given_ucode(priv,
- &priv->ucode_code, &priv->ucode_data);
- if (!ret) {
- IWL_DEBUG_INFO(priv, "Runtime ucode load complete.\n");
- priv->ucode_type = UCODE_RT;
- }
- }
-
- return ret;
-}
-
/*
* Calibration
*/
@@ -297,33 +269,9 @@ void iwlagn_rx_calib_result(struct iwl_priv *priv,
iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
}
-void iwlagn_rx_calib_complete(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
+int iwlagn_init_alive_start(struct iwl_priv *priv)
{
- IWL_DEBUG_INFO(priv, "Init. calibration is completed, restarting fw.\n");
- queue_work(priv->workqueue, &priv->restart);
-}
-
-void iwlagn_init_alive_start(struct iwl_priv *priv)
-{
- int ret = 0;
-
- /* initialize uCode was loaded... 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)) {
- /* Runtime instruction load was bad;
- * take it all the way back down so we can try again */
- IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
- goto restart;
- }
-
- ret = priv->cfg->ops->lib->alive_notify(priv);
- if (ret) {
- IWL_WARN(priv,
- "Could not complete ALIVE transition: %d\n", ret);
- goto restart;
- }
+ int ret;
if (priv->cfg->bt_params &&
priv->cfg->bt_params->advanced_bt_coexist) {
@@ -333,24 +281,25 @@ void iwlagn_init_alive_start(struct iwl_priv *priv)
* no need to close the envlope since we are going
* to load the runtime uCode later.
*/
- iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
+ ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+ if (ret)
+ return ret;
}
- iwlagn_send_calib_cfg(priv);
+
+ ret = iwlagn_send_calib_cfg(priv);
+ if (ret)
+ return ret;
/**
* temperature offset calibration is only needed for runtime ucode,
* so prepare the value now.
*/
if (priv->cfg->need_temp_offset_calib)
- iwlagn_set_temperature_offset_calib(priv);
+ return iwlagn_set_temperature_offset_calib(priv);
- return;
-
-restart:
- /* real restart (first load init_ucode) */
- queue_work(priv->workqueue, &priv->restart);
+ return 0;
}
static int iwlagn_send_wimax_coex(struct iwl_priv *priv)
@@ -413,25 +362,30 @@ void iwlagn_send_prio_tbl(struct iwl_priv *priv)
IWL_ERR(priv, "failed to send BT prio tbl command\n");
}
-void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
+int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
{
struct iwl_bt_coex_prot_env_cmd env_cmd;
+ int ret;
env_cmd.action = action;
env_cmd.type = type;
- if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV,
- sizeof(env_cmd), &env_cmd))
+ ret = iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV,
+ sizeof(env_cmd), &env_cmd);
+ if (ret)
IWL_ERR(priv, "failed to send BT env command\n");
+ return ret;
}
-int iwlagn_alive_notify(struct iwl_priv *priv)
+static int iwlagn_alive_notify(struct iwl_priv *priv)
{
const struct queue_to_fifo_ac *queue_to_fifo;
+ struct iwl_rxon_context *ctx;
u32 a;
unsigned long flags;
int i, chan;
u32 reg_val;
+ int ret;
spin_lock_irqsave(&priv->lock, flags);
@@ -500,6 +454,8 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
for (i = 0; i < 4; i++)
atomic_set(&priv->queue_stop_count[i], 0);
+ for_each_context(priv, ctx)
+ ctx->last_tx_rejected = false;
/* reset to 0 to enable all the queue first */
priv->txq_ctx_active_msk = 0;
@@ -527,12 +483,15 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
iwl_clear_bits_prph(priv, APMG_PCIDEV_STT_REG,
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
- iwlagn_send_wimax_coex(priv);
+ ret = iwlagn_send_wimax_coex(priv);
+ if (ret)
+ return ret;
- iwlagn_set_Xtal_calib(priv);
- iwl_send_calib_results(priv);
+ ret = iwlagn_set_Xtal_calib(priv);
+ if (ret)
+ return ret;
- return 0;
+ return iwl_send_calib_results(priv);
}
@@ -541,11 +500,12 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
* 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 iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
+static int iwlcore_verify_inst_sparse(struct iwl_priv *priv,
+ struct fw_desc *fw_desc)
{
+ __le32 *image = (__le32 *)fw_desc->v_addr;
+ u32 len = fw_desc->len;
u32 val;
- int ret = 0;
- u32 errcnt = 0;
u32 i;
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
@@ -556,104 +516,204 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
* if IWL_DL_IO is set */
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
i + IWLAGN_RTC_INST_LOWER_BOUND);
- val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
- if (val != le32_to_cpu(*image)) {
- ret = -EIO;
- errcnt++;
- if (errcnt >= 3)
- break;
- }
+ val = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
+ if (val != le32_to_cpu(*image))
+ return -EIO;
}
- return ret;
+ return 0;
}
-/**
- * iwlcore_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 void iwl_print_mismatch_inst(struct iwl_priv *priv,
+ struct fw_desc *fw_desc)
{
+ __le32 *image = (__le32 *)fw_desc->v_addr;
+ u32 len = fw_desc->len;
u32 val;
- u32 save_len = len;
- int ret = 0;
- u32 errcnt;
+ u32 offs;
+ int errors = 0;
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
IWLAGN_RTC_INST_LOWER_BOUND);
- errcnt = 0;
- for (; len > 0; len -= sizeof(u32), image++) {
+ for (offs = 0;
+ offs < len && errors < 20;
+ offs += 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_direct32(priv, HBUS_TARG_MEM_RDAT);
+ val = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
- IWL_ERR(priv, "uCode INST section is invalid at "
- "offset 0x%x, is 0x%x, s/b 0x%x\n",
- save_len - len, val, le32_to_cpu(*image));
- ret = -EIO;
- errcnt++;
- if (errcnt >= 20)
- break;
+ IWL_ERR(priv, "uCode INST section at "
+ "offset 0x%x, is 0x%x, s/b 0x%x\n",
+ offs, val, le32_to_cpu(*image));
+ errors++;
}
}
-
- if (!errcnt)
- IWL_DEBUG_INFO(priv,
- "ucode image in INSTRUCTION memory is good\n");
-
- return ret;
}
/**
* iwl_verify_ucode - determine which instruction image is in SRAM,
* and verify its contents
*/
-int iwl_verify_ucode(struct iwl_priv *priv)
+static int iwl_verify_ucode(struct iwl_priv *priv, struct fw_img *img)
+{
+ if (!iwlcore_verify_inst_sparse(priv, &img->code)) {
+ IWL_DEBUG_INFO(priv, "uCode is good in inst SRAM\n");
+ return 0;
+ }
+
+ IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
+
+ iwl_print_mismatch_inst(priv, &img->code);
+ return -EIO;
+}
+
+struct iwlagn_alive_data {
+ bool valid;
+ u8 subtype;
+};
+
+static void iwlagn_alive_fn(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt,
+ void *data)
{
- __le32 *image;
- u32 len;
+ struct iwlagn_alive_data *alive_data = data;
+ struct iwl_alive_resp *palive;
+
+ palive = &pkt->u.alive_frame;
+
+ IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
+ "0x%01X 0x%01X\n",
+ palive->is_valid, palive->ver_type,
+ palive->ver_subtype);
+
+ priv->device_pointers.error_event_table =
+ le32_to_cpu(palive->error_event_table_ptr);
+ priv->device_pointers.log_event_table =
+ le32_to_cpu(palive->log_event_table_ptr);
+
+ alive_data->subtype = palive->ver_subtype;
+ alive_data->valid = palive->is_valid == UCODE_VALID_OK;
+}
+
+#define UCODE_ALIVE_TIMEOUT HZ
+#define UCODE_CALIB_TIMEOUT (2*HZ)
+
+int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
+ struct fw_img *image,
+ int subtype, int alternate_subtype)
+{
+ struct iwl_notification_wait alive_wait;
+ struct iwlagn_alive_data alive_data;
int ret;
+ enum iwlagn_ucode_subtype old_type;
- /* Try bootstrap */
- image = (__le32 *)priv->ucode_boot.v_addr;
- len = priv->ucode_boot.len;
- ret = iwlcore_verify_inst_sparse(priv, image, len);
- if (!ret) {
- IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
- return 0;
+ ret = iwlagn_start_device(priv);
+ if (ret)
+ return ret;
+
+ iwlagn_init_notification_wait(priv, &alive_wait, REPLY_ALIVE,
+ iwlagn_alive_fn, &alive_data);
+
+ old_type = priv->ucode_type;
+ priv->ucode_type = subtype;
+
+ ret = iwlagn_load_given_ucode(priv, image);
+ if (ret) {
+ priv->ucode_type = old_type;
+ iwlagn_remove_notification(priv, &alive_wait);
+ return ret;
}
- /* Try initialize */
- image = (__le32 *)priv->ucode_init.v_addr;
- len = priv->ucode_init.len;
- ret = iwlcore_verify_inst_sparse(priv, image, len);
- if (!ret) {
- IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
- return 0;
+ /* Remove all resets to allow NIC to operate */
+ iwl_write32(priv, CSR_RESET, 0);
+
+ /*
+ * Some things may run in the background now, but we
+ * just wait for the ALIVE notification here.
+ */
+ ret = iwlagn_wait_notification(priv, &alive_wait, UCODE_ALIVE_TIMEOUT);
+ if (ret) {
+ priv->ucode_type = old_type;
+ return ret;
}
- /* Try runtime/protocol */
- image = (__le32 *)priv->ucode_code.v_addr;
- len = priv->ucode_code.len;
- ret = iwlcore_verify_inst_sparse(priv, image, len);
- if (!ret) {
- IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
- return 0;
+ if (!alive_data.valid) {
+ IWL_ERR(priv, "Loaded ucode is not valid!\n");
+ priv->ucode_type = old_type;
+ return -EIO;
+ }
+
+ if (alive_data.subtype != subtype &&
+ alive_data.subtype != alternate_subtype) {
+ IWL_ERR(priv,
+ "Loaded ucode is not expected type (got %d, expected %d)!\n",
+ alive_data.subtype, subtype);
+ priv->ucode_type = old_type;
+ return -EIO;
}
- IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
+ ret = iwl_verify_ucode(priv, image);
+ if (ret) {
+ priv->ucode_type = old_type;
+ return ret;
+ }
+
+ /* delay a bit to give rfkill time to run */
+ msleep(5);
+
+ ret = iwlagn_alive_notify(priv);
+ if (ret) {
+ IWL_WARN(priv,
+ "Could not complete ALIVE transition: %d\n", ret);
+ priv->ucode_type = old_type;
+ return ret;
+ }
+
+ return 0;
+}
+
+int iwlagn_run_init_ucode(struct iwl_priv *priv)
+{
+ struct iwl_notification_wait calib_wait;
+ int ret;
+
+ lockdep_assert_held(&priv->mutex);
+
+ /* No init ucode required? Curious, but maybe ok */
+ if (!priv->ucode_init.code.len)
+ return 0;
+
+ if (priv->ucode_type != UCODE_SUBTYPE_NONE_LOADED)
+ return 0;
+
+ iwlagn_init_notification_wait(priv, &calib_wait,
+ CALIBRATION_COMPLETE_NOTIFICATION,
+ NULL, NULL);
+
+ /* Will also start the device */
+ ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init,
+ UCODE_SUBTYPE_INIT, -1);
+ if (ret)
+ goto error;
+
+ ret = iwlagn_init_alive_start(priv);
+ if (ret)
+ goto error;
+
+ /*
+ * Some things may run in the background now, but we
+ * just wait for the calibration complete notification.
+ */
+ ret = iwlagn_wait_notification(priv, &calib_wait, UCODE_CALIB_TIMEOUT);
- /* 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;
- ret = iwl_verify_inst_full(priv, image, len);
+ goto out;
+ error:
+ iwlagn_remove_notification(priv, &calib_wait);
+ out:
+ /* Whatever happened, stop the device */
+ iwlagn_stop_device(priv);
return ret;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 321b18b5913..3ecc3198d9b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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.
@@ -59,7 +59,6 @@
#include "iwl-sta.h"
#include "iwl-agn-calib.h"
#include "iwl-agn.h"
-#include "iwl-agn-led.h"
/******************************************************************************
@@ -103,70 +102,6 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
}
}
-static void iwl_clear_free_frames(struct iwl_priv *priv)
-{
- struct list_head *element;
-
- IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n",
- priv->frames_count);
-
- while (!list_empty(&priv->free_frames)) {
- element = priv->free_frames.next;
- list_del(element);
- kfree(list_entry(element, struct iwl_frame, list));
- priv->frames_count--;
- }
-
- if (priv->frames_count) {
- IWL_WARN(priv, "%d frames still in use. Did we lose one?\n",
- priv->frames_count);
- priv->frames_count = 0;
- }
-}
-
-static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv)
-{
- struct iwl_frame *frame;
- struct list_head *element;
- if (list_empty(&priv->free_frames)) {
- frame = kzalloc(sizeof(*frame), GFP_KERNEL);
- if (!frame) {
- IWL_ERR(priv, "Could not allocate frame!\n");
- return NULL;
- }
-
- priv->frames_count++;
- return frame;
- }
-
- element = priv->free_frames.next;
- list_del(element);
- return list_entry(element, struct iwl_frame, list);
-}
-
-static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
-{
- memset(frame, 0, sizeof(*frame));
- list_add(&frame->list, &priv->free_frames);
-}
-
-static u32 iwl_fill_beacon_frame(struct iwl_priv *priv,
- struct ieee80211_hdr *hdr,
- int left)
-{
- lockdep_assert_held(&priv->mutex);
-
- if (!priv->beacon_skb)
- return 0;
-
- if (priv->beacon_skb->len > left)
- return 0;
-
- memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len);
-
- return priv->beacon_skb->len;
-}
-
/* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */
static void iwl_set_beacon_tim(struct iwl_priv *priv,
struct iwl_tx_beacon_cmd *tx_beacon_cmd,
@@ -194,13 +129,18 @@ static void iwl_set_beacon_tim(struct iwl_priv *priv,
IWL_WARN(priv, "Unable to find TIM Element in beacon\n");
}
-static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
- struct iwl_frame *frame)
+int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
{
struct iwl_tx_beacon_cmd *tx_beacon_cmd;
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_TX_BEACON,
+ .flags = CMD_SIZE_HUGE,
+ };
u32 frame_size;
u32 rate_flags;
u32 rate;
+ int err;
+
/*
* We have to set up the TX command, the TX Beacon command, and the
* beacon contents.
@@ -213,17 +153,19 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
return 0;
}
- /* Initialize memory */
- tx_beacon_cmd = &frame->u.beacon;
- memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
+ if (WARN_ON(!priv->beacon_skb))
+ return -EINVAL;
+
+ /* Allocate beacon memory */
+ tx_beacon_cmd = kzalloc(sizeof(*tx_beacon_cmd) + priv->beacon_skb->len,
+ GFP_KERNEL);
+ if (!tx_beacon_cmd)
+ return -ENOMEM;
+
+ frame_size = priv->beacon_skb->len;
/* Set up TX beacon contents */
- frame_size = iwl_fill_beacon_frame(priv, tx_beacon_cmd->frame,
- sizeof(frame->u) - sizeof(*tx_beacon_cmd));
- if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE))
- return 0;
- if (!frame_size)
- return 0;
+ memcpy(tx_beacon_cmd->frame, priv->beacon_skb->data, frame_size);
/* Set up TX command fields */
tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
@@ -246,35 +188,16 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
tx_beacon_cmd->tx.rate_n_flags = iwl_hw_set_rate_n_flags(rate,
rate_flags);
- return sizeof(*tx_beacon_cmd) + frame_size;
-}
+ /* Submit command */
+ cmd.len = sizeof(*tx_beacon_cmd) + frame_size;
+ cmd.data = tx_beacon_cmd;
-int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
-{
- struct iwl_frame *frame;
- unsigned int frame_size;
- int rc;
-
- frame = iwl_get_free_frame(priv);
- if (!frame) {
- IWL_ERR(priv, "Could not obtain free frame buffer for beacon "
- "command.\n");
- return -ENOMEM;
- }
+ err = iwl_send_cmd_sync(priv, &cmd);
- frame_size = iwl_hw_get_beacon_cmd(priv, frame);
- if (!frame_size) {
- IWL_ERR(priv, "Error configuring the beacon command\n");
- iwl_free_frame(priv, frame);
- return -EINVAL;
- }
-
- rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
- &frame->u.cmd[0]);
+ /* Free temporary storage */
+ kfree(tx_beacon_cmd);
- iwl_free_frame(priv, frame);
-
- return rc;
+ return err;
}
static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
@@ -395,7 +318,9 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
return -EINVAL;
}
- BUG_ON(addr & ~DMA_BIT_MASK(36));
+ if (WARN_ON(addr & ~DMA_BIT_MASK(36)))
+ return -EINVAL;
+
if (unlikely(addr & ~IWL_TX_DMA_MASK))
IWL_ERR(priv, "Unaligned address = %llx\n",
(unsigned long long)addr);
@@ -409,7 +334,7 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
* Tell nic 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
+ * supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
* channels supported in hardware.
*/
int iwl_hw_tx_queue_init(struct iwl_priv *priv,
@@ -483,12 +408,14 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
container_of(work, struct iwl_priv, bt_full_concurrency);
struct iwl_rxon_context *ctx;
+ mutex_lock(&priv->mutex);
+
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
+ goto out;
/* dont send host command if rf-kill is on */
if (!iwl_is_ready_rf(priv))
- return;
+ goto out;
IWL_DEBUG_INFO(priv, "BT coex in %s mode\n",
priv->bt_full_concurrent ?
@@ -498,15 +425,15 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
* LQ & RXON updated cmds must be sent before BT Config cmd
* to avoid 3-wire collisions
*/
- mutex_lock(&priv->mutex);
for_each_context(priv, ctx) {
if (priv->cfg->ops->hcmd->set_rxon_chain)
priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
iwlcore_commit_rxon(priv, ctx);
}
- mutex_unlock(&priv->mutex);
priv->cfg->ops->hcmd->send_bt_config(priv);
+out:
+ mutex_unlock(&priv->mutex);
}
/**
@@ -556,7 +483,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
}
/* Set starting address; reads will auto-increment */
- _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
+ iwl_write32(priv, HBUS_TARG_MEM_RADDR, ptr);
rmb();
/*
@@ -564,13 +491,13 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
* place event id # at far right for easier visual parsing.
*/
for (i = 0; i < num_events; i++) {
- ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
- time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ ev = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
+ time = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
if (mode == 0) {
trace_iwlwifi_dev_ucode_cont_event(priv,
0, time, ev);
} else {
- data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ data = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
trace_iwlwifi_dev_ucode_cont_event(priv,
time, data, ev);
}
@@ -588,10 +515,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv)
u32 num_wraps; /* # times uCode wrapped to top of log */
u32 next_entry; /* index of next entry to be written by uCode */
- if (priv->ucode_type == UCODE_INIT)
- base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
- else
- base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
+ base = priv->device_pointers.error_event_table;
if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
capacity = iwl_read_targ_mem(priv, base);
num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
@@ -720,7 +644,10 @@ static void iwl_rx_handle(struct iwl_priv *priv)
/* 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);
+ if (WARN_ON(rxb == NULL)) {
+ i = (i + 1) & RX_QUEUE_MASK;
+ continue;
+ }
rxq->queue[i] = NULL;
@@ -760,13 +687,15 @@ static void iwl_rx_handle(struct iwl_priv *priv)
if (w->cmd == pkt->hdr.cmd) {
w->triggered = true;
if (w->fn)
- w->fn(priv, pkt);
+ w->fn(priv, pkt, w->fn_data);
}
}
spin_unlock(&priv->_agn.notif_wait_lock);
wake_up_all(&priv->_agn.notif_waitq);
}
+ if (priv->pre_rx_handler)
+ priv->pre_rx_handler(priv, rxb);
/* Based on type of command response or notification,
* handle those that need handling via function in
@@ -837,199 +766,6 @@ static void iwl_rx_handle(struct iwl_priv *priv)
iwlagn_rx_queue_restock(priv);
}
-/* call this function to flush any scheduled tasklet */
-static inline void iwl_synchronize_irq(struct iwl_priv *priv)
-{
- /* wait to make sure we flush pending tasklet*/
- synchronize_irq(priv->pci_dev->irq);
- tasklet_kill(&priv->irq_tasklet);
-}
-
-static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
-{
- u32 inta, handled = 0;
- u32 inta_fh;
- unsigned long flags;
- u32 i;
-#ifdef CONFIG_IWLWIFI_DEBUG
- u32 inta_mask;
-#endif
-
- spin_lock_irqsave(&priv->lock, flags);
-
- /* Ack/clear/reset pending uCode interrupts.
- * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
- * and will clear only when CSR_FH_INT_STATUS gets cleared. */
- inta = iwl_read32(priv, CSR_INT);
- iwl_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);
-
-#ifdef CONFIG_IWLWIFI_DEBUG
- if (iwl_get_debug_level(priv) & IWL_DL_ISR) {
- /* just for debug */
- inta_mask = iwl_read32(priv, CSR_INT_MASK);
- IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
- inta, inta_mask, inta_fh);
- }
-#endif
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not
- * atomic, make sure that inta covers all the interrupts that
- * we've discovered, even if FH interrupt came in just after
- * reading CSR_INT. */
- if (inta_fh & CSR49_FH_INT_RX_MASK)
- inta |= CSR_INT_BIT_FH_RX;
- if (inta_fh & CSR49_FH_INT_TX_MASK)
- inta |= CSR_INT_BIT_FH_TX;
-
- /* Now service all interrupt bits discovered above. */
- if (inta & CSR_INT_BIT_HW_ERR) {
- IWL_ERR(priv, "Hardware error detected. Restarting.\n");
-
- /* Tell the device to stop sending interrupts */
- iwl_disable_interrupts(priv);
-
- priv->isr_stats.hw++;
- iwl_irq_handle_error(priv);
-
- handled |= CSR_INT_BIT_HW_ERR;
-
- return;
- }
-
-#ifdef CONFIG_IWLWIFI_DEBUG
- if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
- /* NIC fires this, but we don't use it, redundant with WAKEUP */
- if (inta & CSR_INT_BIT_SCD) {
- IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
- "the frame/frames.\n");
- priv->isr_stats.sch++;
- }
-
- /* Alive notification via Rx interrupt will do the real work */
- if (inta & CSR_INT_BIT_ALIVE) {
- IWL_DEBUG_ISR(priv, "Alive interrupt\n");
- priv->isr_stats.alive++;
- }
- }
-#endif
- /* Safely ignore these bits for debug checks below */
- inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
-
- /* HW RF KILL switch toggled */
- if (inta & CSR_INT_BIT_RF_KILL) {
- int hw_rf_kill = 0;
- if (!(iwl_read32(priv, CSR_GP_CNTRL) &
- CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
- hw_rf_kill = 1;
-
- IWL_WARN(priv, "RF_KILL bit toggled to %s.\n",
- hw_rf_kill ? "disable radio" : "enable radio");
-
- priv->isr_stats.rfkill++;
-
- /* driver only loads ucode once setting the interface up.
- * the driver allows loading the ucode even if the radio
- * is killed. Hence update the killswitch state here. The
- * rfkill handler will care about restarting if needed.
- */
- if (!test_bit(STATUS_ALIVE, &priv->status)) {
- if (hw_rf_kill)
- set_bit(STATUS_RF_KILL_HW, &priv->status);
- else
- clear_bit(STATUS_RF_KILL_HW, &priv->status);
- wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
- }
-
- handled |= CSR_INT_BIT_RF_KILL;
- }
-
- /* Chip got too hot and stopped itself */
- if (inta & CSR_INT_BIT_CT_KILL) {
- IWL_ERR(priv, "Microcode CT kill error detected.\n");
- priv->isr_stats.ctkill++;
- handled |= CSR_INT_BIT_CT_KILL;
- }
-
- /* Error detected by uCode */
- if (inta & CSR_INT_BIT_SW_ERR) {
- IWL_ERR(priv, "Microcode SW error detected. "
- " Restarting 0x%X.\n", inta);
- priv->isr_stats.sw++;
- iwl_irq_handle_error(priv);
- handled |= CSR_INT_BIT_SW_ERR;
- }
-
- /*
- * uCode wakes up after power-down sleep.
- * Tell device about any new tx or host commands enqueued,
- * and about any Rx buffers made available while asleep.
- */
- if (inta & CSR_INT_BIT_WAKEUP) {
- IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
- iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
- for (i = 0; i < priv->hw_params.max_txq_num; i++)
- iwl_txq_update_write_ptr(priv, &priv->txq[i]);
- priv->isr_stats.wakeup++;
- handled |= CSR_INT_BIT_WAKEUP;
- }
-
- /* All uCode command responses, including Tx command responses,
- * Rx "responses" (frame-received notification), and other
- * notifications from uCode come through here*/
- if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
- iwl_rx_handle(priv);
- priv->isr_stats.rx++;
- handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
- }
-
- /* This "Tx" DMA channel is used only for loading uCode */
- if (inta & CSR_INT_BIT_FH_TX) {
- IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
- priv->isr_stats.tx++;
- handled |= CSR_INT_BIT_FH_TX;
- /* Wake up uCode load routine, now that load is complete */
- priv->ucode_write_complete = 1;
- wake_up_interruptible(&priv->wait_command_queue);
- }
-
- if (inta & ~handled) {
- IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
- priv->isr_stats.unhandled++;
- }
-
- if (inta & ~(priv->inta_mask)) {
- IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
- inta & ~priv->inta_mask);
- IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh);
- }
-
- /* Re-enable all interrupts */
- /* only Re-enable if disabled by irq */
- if (test_bit(STATUS_INT_ENABLED, &priv->status))
- iwl_enable_interrupts(priv);
- /* Re-enable RF_KILL if it occurred */
- else if (handled & CSR_INT_BIT_RF_KILL)
- iwl_enable_rfkill_int(priv);
-
-#ifdef CONFIG_IWLWIFI_DEBUG
- if (iwl_get_debug_level(priv) & (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);
- IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
- "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
- }
-#endif
-}
-
/* tasklet for iwlagn interrupt */
static void iwl_irq_tasklet(struct iwl_priv *priv)
{
@@ -1171,7 +907,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
iwl_write32(priv, CSR_FH_INT_STATUS,
- CSR49_FH_INT_RX_MASK);
+ CSR_FH_INT_RX_MASK);
}
if (inta & CSR_INT_BIT_RX_PERIODIC) {
handled |= CSR_INT_BIT_RX_PERIODIC;
@@ -1209,7 +945,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* This "Tx" DMA channel is used only for loading uCode */
if (inta & CSR_INT_BIT_FH_TX) {
- iwl_write32(priv, CSR_FH_INT_STATUS, CSR49_FH_INT_TX_MASK);
+ iwl_write32(priv, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK);
IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
priv->isr_stats.tx++;
handled |= CSR_INT_BIT_FH_TX;
@@ -1357,26 +1093,48 @@ static struct attribute_group iwl_attribute_group = {
*
******************************************************************************/
-static void iwl_dealloc_ucode_pci(struct iwl_priv *priv)
+static void iwl_free_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc)
+{
+ if (desc->v_addr)
+ dma_free_coherent(&pci_dev->dev, desc->len,
+ desc->v_addr, desc->p_addr);
+ desc->v_addr = NULL;
+ desc->len = 0;
+}
+
+static void iwl_free_fw_img(struct pci_dev *pci_dev, struct fw_img *img)
+{
+ iwl_free_fw_desc(pci_dev, &img->code);
+ iwl_free_fw_desc(pci_dev, &img->data);
+}
+
+static int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc,
+ const void *data, size_t len)
{
- 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);
+ if (!len) {
+ desc->v_addr = NULL;
+ return -EINVAL;
+ }
+
+ desc->v_addr = dma_alloc_coherent(&pci_dev->dev, len,
+ &desc->p_addr, GFP_KERNEL);
+ if (!desc->v_addr)
+ return -ENOMEM;
+ desc->len = len;
+ memcpy(desc->v_addr, data, len);
+ return 0;
}
-static void iwl_nic_start(struct iwl_priv *priv)
+static void iwl_dealloc_ucode_pci(struct iwl_priv *priv)
{
- /* Remove all resets to allow NIC to operate */
- iwl_write32(priv, CSR_RESET, 0);
+ iwl_free_fw_img(priv->pci_dev, &priv->ucode_rt);
+ iwl_free_fw_img(priv->pci_dev, &priv->ucode_init);
}
struct iwlagn_ucode_capabilities {
u32 max_probe_length;
u32 standard_phy_calibration_size;
- bool pan;
+ u32 flags;
};
static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
@@ -1422,8 +1180,8 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
}
struct iwlagn_firmware_pieces {
- const void *inst, *data, *init, *init_data, *boot;
- size_t inst_size, data_size, init_size, init_data_size, boot_size;
+ const void *inst, *data, *init, *init_data;
+ size_t inst_size, data_size, init_size, init_data_size;
u32 build;
@@ -1444,28 +1202,18 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
switch (api_ver) {
default:
- /*
- * 4965 doesn't revision the firmware file format
- * along with the API version, it always uses v1
- * file format.
- */
- if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) !=
- CSR_HW_REV_TYPE_4965) {
- hdr_size = 28;
- if (ucode_raw->size < hdr_size) {
- IWL_ERR(priv, "File size too small!\n");
- return -EINVAL;
- }
- pieces->build = le32_to_cpu(ucode->u.v2.build);
- pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
- pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
- pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
- pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
- pieces->boot_size = le32_to_cpu(ucode->u.v2.boot_size);
- src = ucode->u.v2.data;
- break;
+ hdr_size = 28;
+ if (ucode_raw->size < hdr_size) {
+ IWL_ERR(priv, "File size too small!\n");
+ return -EINVAL;
}
- /* fall through for 4965 */
+ pieces->build = le32_to_cpu(ucode->u.v2.build);
+ pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
+ pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
+ pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
+ pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
+ src = ucode->u.v2.data;
+ break;
case 0:
case 1:
case 2:
@@ -1479,7 +1227,6 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
pieces->data_size = le32_to_cpu(ucode->u.v1.data_size);
pieces->init_size = le32_to_cpu(ucode->u.v1.init_size);
pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size);
- pieces->boot_size = le32_to_cpu(ucode->u.v1.boot_size);
src = ucode->u.v1.data;
break;
}
@@ -1487,7 +1234,7 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
/* Verify size of file vs. image size info in file's header */
if (ucode_raw->size != hdr_size + pieces->inst_size +
pieces->data_size + pieces->init_size +
- pieces->init_data_size + pieces->boot_size) {
+ pieces->init_data_size) {
IWL_ERR(priv,
"uCode file size %d does not match expected size\n",
@@ -1503,8 +1250,6 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
src += pieces->init_size;
pieces->init_data = src;
src += pieces->init_data_size;
- pieces->boot = src;
- src += pieces->boot_size;
return 0;
}
@@ -1605,8 +1350,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
pieces->init_data_size = tlv_len;
break;
case IWL_UCODE_TLV_BOOT:
- pieces->boot = tlv_data;
- pieces->boot_size = tlv_len;
+ IWL_ERR(priv, "Found unexpected BOOT ucode\n");
break;
case IWL_UCODE_TLV_PROBE_MAX_LEN:
if (tlv_len != sizeof(u32))
@@ -1617,7 +1361,23 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
case IWL_UCODE_TLV_PAN:
if (tlv_len)
goto invalid_tlv_len;
- capa->pan = true;
+ capa->flags |= IWL_UCODE_TLV_FLAGS_PAN;
+ break;
+ case IWL_UCODE_TLV_FLAGS:
+ /* must be at least one u32 */
+ if (tlv_len < sizeof(u32))
+ goto invalid_tlv_len;
+ /* and a proper number of u32s */
+ if (tlv_len % sizeof(u32))
+ goto invalid_tlv_len;
+ /*
+ * This driver only reads the first u32 as
+ * right now no more features are defined,
+ * if that changes then either the driver
+ * will not work with the new firmware, or
+ * it'll not take advantage of new features.
+ */
+ capa->flags = le32_to_cpup((__le32 *)tlv_data);
break;
case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
if (tlv_len != sizeof(u32))
@@ -1667,7 +1427,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
le32_to_cpup((__le32 *)tlv_data);
break;
default:
- IWL_WARN(priv, "unknown TLV: %d\n", tlv_type);
+ IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type);
break;
}
}
@@ -1806,8 +1566,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
pieces.init_size);
IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n",
pieces.init_data_size);
- IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %Zd\n",
- pieces.boot_size);
/* Verify that uCode images will fit in card's SRAM */
if (pieces.inst_size > priv->hw_params.max_inst_size) {
@@ -1834,48 +1592,25 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
goto try_again;
}
- if (pieces.boot_size > priv->hw_params.max_bsm_size) {
- IWL_ERR(priv, "uCode boot instr len %Zd too large to fit in\n",
- pieces.boot_size);
- goto try_again;
- }
-
/* Allocate ucode buffers for card's bus-master loading ... */
/* Runtime instructions and 2 copies of data:
* 1) unmodified from disk
* 2) backup cache for save/restore during power-downs */
- priv->ucode_code.len = pieces.inst_size;
- iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code);
-
- priv->ucode_data.len = pieces.data_size;
- iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data);
-
- priv->ucode_data_backup.len = pieces.data_size;
- 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)
+ if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.code,
+ pieces.inst, pieces.inst_size))
+ goto err_pci_alloc;
+ if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.data,
+ pieces.data, pieces.data_size))
goto err_pci_alloc;
/* Initialization instructions and data */
if (pieces.init_size && pieces.init_data_size) {
- priv->ucode_init.len = pieces.init_size;
- iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init);
-
- priv->ucode_init_data.len = pieces.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)
+ if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.code,
+ pieces.init, pieces.init_size))
goto err_pci_alloc;
- }
-
- /* Bootstrap (instructions only, no data) */
- if (pieces.boot_size) {
- priv->ucode_boot.len = pieces.boot_size;
- iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot);
-
- if (!priv->ucode_boot.v_addr)
+ if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.data,
+ pieces.init_data, pieces.init_data_size))
goto err_pci_alloc;
}
@@ -1901,50 +1636,19 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
priv->cfg->base_params->max_event_log_size;
priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;
- if (ucode_capa.pan) {
+ priv->new_scan_threshold_behaviour =
+ !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
+
+ if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
} else
priv->sta_key_max_num = STA_KEY_MAX_NUM;
- /* Copy images into buffers for card's bus-master reads ... */
-
- /* Runtime instructions (first block of data in file) */
- IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n",
- pieces.inst_size);
- memcpy(priv->ucode_code.v_addr, pieces.inst, pieces.inst_size);
-
- IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
- priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
-
- /*
- * Runtime data
- * NOTE: Copy into backup buffer will be done in iwl_up()
- */
- IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n",
- pieces.data_size);
- memcpy(priv->ucode_data.v_addr, pieces.data, pieces.data_size);
- memcpy(priv->ucode_data_backup.v_addr, pieces.data, pieces.data_size);
-
- /* Initialization instructions */
- if (pieces.init_size) {
- IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
- pieces.init_size);
- memcpy(priv->ucode_init.v_addr, pieces.init, pieces.init_size);
- }
-
- /* Initialization data */
- if (pieces.init_data_size) {
- IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
- pieces.init_data_size);
- memcpy(priv->ucode_init_data.v_addr, pieces.init_data,
- pieces.init_data_size);
- }
-
- /* Bootstrap instructions */
- IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n",
- pieces.boot_size);
- memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size);
+ if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
+ priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
+ else
+ priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
/*
* figure out the offset of chain noise reset and gain commands
@@ -2076,13 +1780,13 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
u32 desc, time, count, base, data1;
u32 blink1, blink2, ilink1, ilink2;
u32 pc, hcmd;
+ struct iwl_error_event_table table;
- if (priv->ucode_type == UCODE_INIT) {
- base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
+ base = priv->device_pointers.error_event_table;
+ if (priv->ucode_type == UCODE_SUBTYPE_INIT) {
if (!base)
base = priv->_agn.init_errlog_ptr;
} else {
- base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
if (!base)
base = priv->_agn.inst_errlog_ptr;
}
@@ -2090,11 +1794,15 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
IWL_ERR(priv,
"Not valid error log pointer 0x%08X for %s uCode\n",
- base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
+ base,
+ (priv->ucode_type == UCODE_SUBTYPE_INIT)
+ ? "Init" : "RT");
return;
}
- count = iwl_read_targ_mem(priv, base);
+ iwl_read_targ_mem_words(priv, base, &table, sizeof(table));
+
+ count = table.valid;
if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
IWL_ERR(priv, "Start IWL Error Log Dump:\n");
@@ -2102,18 +1810,18 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
priv->status, count);
}
- desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
+ desc = table.error_id;
priv->isr_stats.err_code = desc;
- pc = iwl_read_targ_mem(priv, base + 2 * sizeof(u32));
- blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
- blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
- ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32));
- ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32));
- data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32));
- data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32));
- line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
- time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
- hcmd = iwl_read_targ_mem(priv, base + 22 * sizeof(u32));
+ pc = table.pc;
+ blink1 = table.blink1;
+ blink2 = table.blink2;
+ ilink1 = table.ilink1;
+ ilink2 = table.ilink2;
+ data1 = table.data1;
+ data2 = table.data2;
+ line = table.line;
+ time = table.tsf_low;
+ hcmd = table.hcmd;
trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line,
blink1, blink2, ilink1, ilink2);
@@ -2147,12 +1855,11 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
if (num_events == 0)
return pos;
- if (priv->ucode_type == UCODE_INIT) {
- base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
+ base = priv->device_pointers.log_event_table;
+ if (priv->ucode_type == UCODE_SUBTYPE_INIT) {
if (!base)
base = priv->_agn.init_evtlog_ptr;
} else {
- base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
if (!base)
base = priv->_agn.inst_evtlog_ptr;
}
@@ -2169,14 +1876,14 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
iwl_grab_nic_access(priv);
/* Set starting address; reads will auto-increment */
- _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
+ iwl_write32(priv, HBUS_TARG_MEM_RADDR, ptr);
rmb();
/* "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_direct32(priv, HBUS_TARG_MEM_RDAT);
- time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ ev = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
+ time = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
if (mode == 0) {
/* data, ev */
if (bufsz) {
@@ -2190,7 +1897,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
time, ev);
}
} else {
- data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ data = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
if (bufsz) {
pos += scnprintf(*buf + pos, bufsz - pos,
"EVT_LOGT:%010u:0x%08x:%04u\n",
@@ -2261,13 +1968,12 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
int pos = 0;
size_t bufsz = 0;
- if (priv->ucode_type == UCODE_INIT) {
- base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
+ base = priv->device_pointers.log_event_table;
+ if (priv->ucode_type == UCODE_SUBTYPE_INIT) {
logsize = priv->_agn.init_evtlog_size;
if (!base)
base = priv->_agn.init_evtlog_ptr;
} else {
- base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
logsize = priv->_agn.inst_evtlog_size;
if (!base)
base = priv->_agn.inst_evtlog_ptr;
@@ -2276,7 +1982,9 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
IWL_ERR(priv,
"Invalid event log pointer 0x%08X for %s uCode\n",
- base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
+ base,
+ (priv->ucode_type == UCODE_SUBTYPE_INIT)
+ ? "Init" : "RT");
return -EINVAL;
}
@@ -2423,30 +2131,14 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg)
* from protocol/runtime uCode (initialization uCode's
* Alive gets handled by iwl_init_alive_start()).
*/
-static void iwl_alive_start(struct iwl_priv *priv)
+int iwl_alive_start(struct iwl_priv *priv)
{
int ret = 0;
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
- IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
-
- /* 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)) {
- /* Runtime instruction load was bad;
- * take it all the way back down so we can try again */
- IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n");
- goto restart;
- }
-
- ret = priv->cfg->ops->lib->alive_notify(priv);
- if (ret) {
- IWL_WARN(priv,
- "Could not complete ALIVE transition [ntf]: %d\n", ret);
- goto restart;
- }
+ iwl_reset_ict(priv);
+ IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
/* After the ALIVE response, we can send host commands to the uCode */
set_bit(STATUS_ALIVE, &priv->status);
@@ -2455,7 +2147,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwl_setup_watchdog(priv);
if (iwl_is_rfkill(priv))
- return;
+ return -ERFKILL;
/* download priority table before any calibration request */
if (priv->cfg->bt_params &&
@@ -2469,10 +2161,14 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwlagn_send_prio_tbl(priv);
/* FIXME: w/a to force change uCode BT state machine */
- iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
- BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
- iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
- BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+ ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+ if (ret)
+ return ret;
+ ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+ if (ret)
+ return ret;
}
if (priv->hw_params.calib_rt_cfg)
iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg);
@@ -2514,30 +2210,23 @@ static void iwl_alive_start(struct iwl_priv *priv)
set_bit(STATUS_READY, &priv->status);
/* Configure the adapter for unassociated operation */
- iwlcore_commit_rxon(priv, ctx);
+ ret = iwlcore_commit_rxon(priv, ctx);
+ if (ret)
+ return ret;
/* At this point, the NIC is initialized and operational */
iwl_rf_kill_ct_config(priv);
IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
- wake_up_interruptible(&priv->wait_command_queue);
-
- iwl_power_update_mode(priv, true);
- IWL_DEBUG_INFO(priv, "Updated power mode\n");
-
- return;
-
- restart:
- queue_work(priv->workqueue, &priv->restart);
+ return iwl_power_update_mode(priv, true);
}
static void iwl_cancel_deferred_work(struct iwl_priv *priv);
static void __iwl_down(struct iwl_priv *priv)
{
- unsigned long flags;
- int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
+ int exit_pending;
IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
@@ -2563,40 +2252,15 @@ static void __iwl_down(struct iwl_priv *priv)
priv->bt_full_concurrent = false;
priv->bt_ci_compliance = 0;
- /* Unblock any waiting calls */
- wake_up_interruptible_all(&priv->wait_command_queue);
-
/* Wipe out the EXIT_PENDING status bit if we are not actually
* exiting the module */
if (!exit_pending)
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);
-
- /* tell the device to stop sending interrupts */
- spin_lock_irqsave(&priv->lock, flags);
- iwl_disable_interrupts(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
- iwl_synchronize_irq(priv);
-
if (priv->mac80211_registered)
ieee80211_stop_queues(priv->hw);
- /* If we have not previously called iwl_init() then
- * clear all bits but the RF Kill bit and return */
- if (!iwl_is_init(priv)) {
- priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
- STATUS_RF_KILL_HW |
- test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
- STATUS_GEO_CONFIGURED |
- test_bit(STATUS_EXIT_PENDING, &priv->status) <<
- STATUS_EXIT_PENDING;
- goto exit;
- }
-
- /* ...otherwise clear out all the status bits but the RF Kill
- * bit and continue taking the NIC down. */
+ /* Clear out all status bits but a few that are stable across reset */
priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
@@ -2606,31 +2270,10 @@ static void __iwl_down(struct iwl_priv *priv)
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
STATUS_EXIT_PENDING;
- /* device going down, Stop using ICT table */
- if (priv->cfg->ops->lib->isr_ops.disable)
- priv->cfg->ops->lib->isr_ops.disable(priv);
-
- iwlagn_txq_ctx_stop(priv);
- iwlagn_rxq_stop(priv);
-
- /* Power-down device's busmaster DMA clocks */
- iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
- udelay(5);
-
- /* Make sure (redundant) we've released our request to stay awake */
- iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-
- /* Stop the device, and put it in low power state */
- iwl_apm_stop(priv);
-
- exit:
- memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
+ iwlagn_stop_device(priv);
dev_kfree_skb(priv->beacon_skb);
priv->beacon_skb = NULL;
-
- /* clear out any free frames */
- iwl_clear_free_frames(priv);
}
static void iwl_down(struct iwl_priv *priv)
@@ -2644,9 +2287,10 @@ static void iwl_down(struct iwl_priv *priv)
#define HW_READY_TIMEOUT (50)
+/* Note: returns poll_bit return value, which is >= 0 if success */
static int iwl_set_hw_ready(struct iwl_priv *priv)
{
- int ret = 0;
+ int ret;
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
@@ -2656,25 +2300,21 @@ static int iwl_set_hw_ready(struct iwl_priv *priv)
CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
HW_READY_TIMEOUT);
- if (ret != -ETIMEDOUT)
- priv->hw_ready = true;
- else
- priv->hw_ready = false;
- IWL_DEBUG_INFO(priv, "hardware %s\n",
- (priv->hw_ready == 1) ? "ready" : "not ready");
+ IWL_DEBUG_INFO(priv, "hardware%s ready\n", ret < 0 ? " not" : "");
return ret;
}
-static int iwl_prepare_card_hw(struct iwl_priv *priv)
+/* Note: returns standard 0/-ERROR code */
+int iwl_prepare_card_hw(struct iwl_priv *priv)
{
- int ret = 0;
+ int ret;
IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter\n");
ret = iwl_set_hw_ready(priv);
- if (priv->hw_ready)
- return ret;
+ if (ret >= 0)
+ return 0;
/* If HW is not ready, prepare the conditions to check again */
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
@@ -2684,10 +2324,13 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv)
~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
- /* HW should be ready by now, check again. */
- if (ret != -ETIMEDOUT)
- iwl_set_hw_ready(priv);
+ if (ret < 0)
+ return ret;
+ /* HW should be ready by now, check again. */
+ ret = iwl_set_hw_ready(priv);
+ if (ret >= 0)
+ return 0;
return ret;
}
@@ -2696,19 +2339,15 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv)
static int __iwl_up(struct iwl_priv *priv)
{
struct iwl_rxon_context *ctx;
- int i;
int ret;
+ lockdep_assert_held(&priv->mutex);
+
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
return -EIO;
}
- if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
- IWL_ERR(priv, "ucode not available for device bringup\n");
- return -EIO;
- }
-
for_each_context(priv, ctx) {
ret = iwlagn_alloc_bcast_station(priv, ctx);
if (ret) {
@@ -2717,89 +2356,33 @@ static int __iwl_up(struct iwl_priv *priv)
}
}
- iwl_prepare_card_hw(priv);
-
- if (!priv->hw_ready) {
- IWL_WARN(priv, "Exit HW not ready\n");
- return -EIO;
- }
-
- /* If platform's RF_KILL switch is NOT set to KILL */
- if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
- clear_bit(STATUS_RF_KILL_HW, &priv->status);
- else
- set_bit(STATUS_RF_KILL_HW, &priv->status);
-
- if (iwl_is_rfkill(priv)) {
- wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
-
- iwl_enable_interrupts(priv);
- IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
- return 0;
+ ret = iwlagn_run_init_ucode(priv);
+ if (ret) {
+ IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret);
+ goto error;
}
- iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
-
- /* must be initialised before iwl_hw_nic_init */
- if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
- priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
- else
- priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
-
- ret = iwlagn_hw_nic_init(priv);
+ ret = iwlagn_load_ucode_wait_alive(priv,
+ &priv->ucode_rt,
+ UCODE_SUBTYPE_REGULAR,
+ UCODE_SUBTYPE_REGULAR_NEW);
if (ret) {
- IWL_ERR(priv, "Unable to init nic\n");
- return ret;
+ IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret);
+ goto error;
}
- /* 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_DRV_GP1_BIT_CMD_BLOCKED);
-
- /* clear (again), then enable host interrupts */
- iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
- iwl_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);
-
- /* 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);
-
- for (i = 0; i < MAX_HW_RESTARTS; i++) {
-
- /* load bootstrap state machine,
- * load bootstrap program into processor's memory,
- * prepare to load the "initialize" uCode */
- ret = priv->cfg->ops->lib->load_ucode(priv);
-
- if (ret) {
- IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n",
- ret);
- continue;
- }
-
- /* start card; "initialize" will load runtime ucode */
- iwl_nic_start(priv);
-
- IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n");
-
- return 0;
- }
+ ret = iwl_alive_start(priv);
+ if (ret)
+ goto error;
+ return 0;
+ error:
set_bit(STATUS_EXIT_PENDING, &priv->status);
__iwl_down(priv);
clear_bit(STATUS_EXIT_PENDING, &priv->status);
- /* tried to restart and config the device for as long as our
- * patience could withstand */
- IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i);
- return -EIO;
+ IWL_ERR(priv, "Unable to initialize device.\n");
+ return ret;
}
@@ -2809,36 +2392,6 @@ static int __iwl_up(struct iwl_priv *priv)
*
*****************************************************************************/
-static void iwl_bg_init_alive_start(struct work_struct *data)
-{
- struct iwl_priv *priv =
- container_of(data, struct iwl_priv, init_alive_start.work);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- mutex_lock(&priv->mutex);
- priv->cfg->ops->lib->init_alive_start(priv);
- mutex_unlock(&priv->mutex);
-}
-
-static void iwl_bg_alive_start(struct work_struct *data)
-{
- struct iwl_priv *priv =
- container_of(data, struct iwl_priv, alive_start.work);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- /* enable dram interrupt */
- if (priv->cfg->ops->lib->isr_ops.reset)
- priv->cfg->ops->lib->isr_ops.reset(priv);
-
- mutex_lock(&priv->mutex);
- iwl_alive_start(priv);
- mutex_unlock(&priv->mutex);
-}
-
static void iwl_bg_run_time_calib_work(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work, struct iwl_priv,
@@ -2853,22 +2406,49 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
}
if (priv->start_calib) {
- if (iwl_bt_statistics(priv)) {
- iwl_chain_noise_calibration(priv,
- (void *)&priv->_agn.statistics_bt);
- iwl_sensitivity_calibration(priv,
- (void *)&priv->_agn.statistics_bt);
- } else {
- iwl_chain_noise_calibration(priv,
- (void *)&priv->_agn.statistics);
- iwl_sensitivity_calibration(priv,
- (void *)&priv->_agn.statistics);
- }
+ iwl_chain_noise_calibration(priv);
+ iwl_sensitivity_calibration(priv);
}
mutex_unlock(&priv->mutex);
}
+static void iwlagn_prepare_restart(struct iwl_priv *priv)
+{
+ struct iwl_rxon_context *ctx;
+ bool bt_full_concurrent;
+ u8 bt_ci_compliance;
+ u8 bt_load;
+ u8 bt_status;
+
+ lockdep_assert_held(&priv->mutex);
+
+ for_each_context(priv, ctx)
+ ctx->vif = NULL;
+ priv->is_open = 0;
+
+ /*
+ * __iwl_down() will clear the BT status variables,
+ * which is correct, but when we restart we really
+ * want to keep them so restore them afterwards.
+ *
+ * The restart process will later pick them up and
+ * re-configure the hw when we reconfigure the BT
+ * command.
+ */
+ bt_full_concurrent = priv->bt_full_concurrent;
+ bt_ci_compliance = priv->bt_ci_compliance;
+ bt_load = priv->bt_traffic_load;
+ bt_status = priv->bt_status;
+
+ __iwl_down(priv);
+
+ priv->bt_full_concurrent = bt_full_concurrent;
+ priv->bt_ci_compliance = bt_ci_compliance;
+ priv->bt_traffic_load = bt_load;
+ priv->bt_status = bt_status;
+}
+
static void iwl_bg_restart(struct work_struct *data)
{
struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -2877,50 +2457,13 @@ static void iwl_bg_restart(struct work_struct *data)
return;
if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
- struct iwl_rxon_context *ctx;
- bool bt_full_concurrent;
- u8 bt_ci_compliance;
- u8 bt_load;
- u8 bt_status;
-
mutex_lock(&priv->mutex);
- for_each_context(priv, ctx)
- ctx->vif = NULL;
- priv->is_open = 0;
-
- /*
- * __iwl_down() will clear the BT status variables,
- * which is correct, but when we restart we really
- * want to keep them so restore them afterwards.
- *
- * The restart process will later pick them up and
- * re-configure the hw when we reconfigure the BT
- * command.
- */
- bt_full_concurrent = priv->bt_full_concurrent;
- bt_ci_compliance = priv->bt_ci_compliance;
- bt_load = priv->bt_traffic_load;
- bt_status = priv->bt_status;
-
- __iwl_down(priv);
-
- priv->bt_full_concurrent = bt_full_concurrent;
- priv->bt_ci_compliance = bt_ci_compliance;
- priv->bt_traffic_load = bt_load;
- priv->bt_status = bt_status;
-
+ iwlagn_prepare_restart(priv);
mutex_unlock(&priv->mutex);
iwl_cancel_deferred_work(priv);
ieee80211_restart_hw(priv->hw);
} else {
- iwl_down(priv);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- mutex_lock(&priv->mutex);
- __iwl_up(priv);
- mutex_unlock(&priv->mutex);
+ WARN_ON(1);
}
}
@@ -3031,8 +2574,6 @@ unlock:
*
*****************************************************************************/
-#define UCODE_READY_TIMEOUT (4 * HZ)
-
/*
* Not a mac80211 entry point function, but it fits in with all the
* other mac80211 functions grouped here.
@@ -3055,14 +2596,16 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
- if (!priv->cfg->base_params->broken_powersave)
- hw->flags |= IEEE80211_HW_SUPPORTS_PS |
- IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
+ hw->flags |= IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
if (priv->cfg->sku & IWL_SKU_N)
hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
IEEE80211_HW_SUPPORTS_STATIC_SMPS;
+ if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP)
+ hw->flags |= IEEE80211_HW_MFP_CAPABLE;
+
hw->sta_data_size = sizeof(struct iwl_station_priv);
hw->vif_data_size = sizeof(struct iwl_vif_priv);
@@ -3112,7 +2655,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
}
-int iwlagn_mac_start(struct ieee80211_hw *hw)
+static int iwlagn_mac_start(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
int ret;
@@ -3123,37 +2666,23 @@ int iwlagn_mac_start(struct ieee80211_hw *hw)
mutex_lock(&priv->mutex);
ret = __iwl_up(priv);
mutex_unlock(&priv->mutex);
-
if (ret)
return ret;
- if (iwl_is_rfkill(priv))
- goto out;
-
IWL_DEBUG_INFO(priv, "Start UP work done.\n");
- /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from
- * mac80211 will not be run successfully. */
- ret = wait_event_interruptible_timeout(priv->wait_command_queue,
- test_bit(STATUS_READY, &priv->status),
- UCODE_READY_TIMEOUT);
- if (!ret) {
- if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_ERR(priv, "START_ALIVE timeout after %dms.\n",
- jiffies_to_msecs(UCODE_READY_TIMEOUT));
- return -ETIMEDOUT;
- }
- }
+ /* Now we should be done, and the READY bit should be set. */
+ if (WARN_ON(!test_bit(STATUS_READY, &priv->status)))
+ ret = -EIO;
iwlagn_led_enable(priv);
-out:
priv->is_open = 1;
IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
}
-void iwlagn_mac_stop(struct ieee80211_hw *hw)
+static void iwlagn_mac_stop(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
@@ -3176,7 +2705,7 @@ void iwlagn_mac_stop(struct ieee80211_hw *hw)
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct iwl_priv *priv = hw->priv;
@@ -3191,11 +2720,11 @@ void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
IWL_DEBUG_MACDUMP(priv, "leave\n");
}
-void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_key_conf *keyconf,
- struct ieee80211_sta *sta,
- u32 iv32, u16 *phase1key)
+static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_key_conf *keyconf,
+ struct ieee80211_sta *sta,
+ u32 iv32, u16 *phase1key)
{
struct iwl_priv *priv = hw->priv;
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -3208,9 +2737,10 @@ void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- struct ieee80211_vif *vif, struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key)
+static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
{
struct iwl_priv *priv = hw->priv;
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -3221,7 +2751,7 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
IWL_DEBUG_MAC80211(priv, "enter\n");
- if (priv->cfg->mod_params->sw_crypto) {
+ if (iwlagn_mod_params.sw_crypto) {
IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
return -EOPNOTSUPP;
}
@@ -3285,11 +2815,11 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return ret;
}
-int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- enum ieee80211_ampdu_mlme_action action,
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
- u8 buf_size)
+static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+ u8 buf_size)
{
struct iwl_priv *priv = hw->priv;
int ret = -EINVAL;
@@ -3348,6 +2878,10 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
}
break;
case IEEE80211_AMPDU_TX_OPERATIONAL:
+ buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF);
+
+ iwlagn_txq_agg_queue_setup(priv, sta, tid, buf_size);
+
/*
* If the limit is 0, then it wasn't initialised yet,
* use the default. We can do that since we take the
@@ -3392,9 +2926,9 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
return ret;
}
-int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
{
struct iwl_priv *priv = hw->priv;
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
@@ -3435,8 +2969,8 @@ int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
return 0;
}
-void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
- struct ieee80211_channel_switch *ch_switch)
+static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
+ struct ieee80211_channel_switch *ch_switch)
{
struct iwl_priv *priv = hw->priv;
const struct iwl_channel_info *ch_info;
@@ -3457,21 +2991,22 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(priv, "enter\n");
+ mutex_lock(&priv->mutex);
+
if (iwl_is_rfkill(priv))
- goto out_exit;
+ goto out;
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
test_bit(STATUS_SCANNING, &priv->status))
- goto out_exit;
+ goto out;
if (!iwl_is_associated_ctx(ctx))
- goto out_exit;
+ goto out;
/* channel switch in progress */
if (priv->switch_rxon.switch_in_progress == true)
- goto out_exit;
+ goto out;
- mutex_lock(&priv->mutex);
if (priv->cfg->ops->lib->set_channel_switch) {
ch = channel->hw_value;
@@ -3527,16 +3062,15 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
}
out:
mutex_unlock(&priv->mutex);
-out_exit:
if (!priv->switch_rxon.switch_in_progress)
ieee80211_chswitch_done(ctx->vif, false);
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-void iwlagn_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags,
- u64 multicast)
+static void iwlagn_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ u64 multicast)
{
struct iwl_priv *priv = hw->priv;
__le32 filter_or = 0, filter_nand = 0;
@@ -3583,7 +3117,7 @@ void iwlagn_configure_filter(struct ieee80211_hw *hw,
FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
}
-void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
+static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
{
struct iwl_priv *priv = hw->priv;
@@ -3729,8 +3263,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush);
INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency);
INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config);
- INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
- INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
INIT_DELAYED_WORK(&priv->_agn.hw_roc_work, iwlagn_bg_roc_done);
iwl_setup_scan_deferred_work(priv);
@@ -3750,12 +3282,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
priv->watchdog.data = (unsigned long)priv;
priv->watchdog.function = iwl_bg_watchdog;
- if (!priv->cfg->base_params->use_isr_legacy)
- tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
- iwl_irq_tasklet, (unsigned long)priv);
- else
- tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
- iwl_irq_tasklet_legacy, (unsigned long)priv);
+ tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+ iwl_irq_tasklet, (unsigned long)priv);
}
static void iwl_cancel_deferred_work(struct iwl_priv *priv)
@@ -3763,8 +3291,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
if (priv->cfg->ops->lib->cancel_deferred_work)
priv->cfg->ops->lib->cancel_deferred_work(priv);
- cancel_delayed_work_sync(&priv->init_alive_start);
- cancel_delayed_work(&priv->alive_start);
cancel_work_sync(&priv->run_time_calib_work);
cancel_work_sync(&priv->beacon_update);
@@ -3805,10 +3331,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
spin_lock_init(&priv->sta_lock);
spin_lock_init(&priv->hcmd_lock);
- INIT_LIST_HEAD(&priv->free_frames);
-
mutex_init(&priv->mutex);
- mutex_init(&priv->sync_cmd_mutex);
priv->ieee_channels = NULL;
priv->ieee_rates = NULL;
@@ -3845,12 +3368,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF;
}
- /* Set the tx_power_user_lmt to the lowest power level
- * this value will get overwritten by channel max power avg
- * from eeprom */
- priv->tx_power_user_lmt = IWLAGN_TX_POWER_TARGET_POWER_MIN;
- priv->tx_power_next = IWLAGN_TX_POWER_TARGET_POWER_MIN;
-
ret = iwl_init_channel_map(priv);
if (ret) {
IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
@@ -3905,28 +3422,30 @@ struct ieee80211_ops iwlagn_hw_ops = {
.cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel,
.offchannel_tx = iwl_mac_offchannel_tx,
.offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait,
+ CFG80211_TESTMODE_CMD(iwl_testmode_cmd)
};
-static void iwl_hw_detect(struct iwl_priv *priv)
+static u32 iwl_hw_detect(struct iwl_priv *priv)
{
- priv->hw_rev = _iwl_read32(priv, CSR_HW_REV);
- priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG);
- priv->rev_id = priv->pci_dev->revision;
- IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id);
+ u8 rev_id;
+
+ pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
+ IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
+ return iwl_read32(priv, CSR_HW_REV);
}
static int iwl_set_hw_params(struct iwl_priv *priv)
{
priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
- if (priv->cfg->mod_params->amsdu_size_8K)
+ if (iwlagn_mod_params.amsdu_size_8K)
priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K);
else
priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K);
priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL;
- if (priv->cfg->mod_params->disable_11n)
+ if (iwlagn_mod_params.disable_11n)
priv->cfg->sku &= ~IWL_SKU_N;
/* Device-specific setup */
@@ -3955,6 +3474,28 @@ static const u8 iwlagn_pan_ac_to_queue[] = {
7, 6, 5, 4,
};
+/* This function both allocates and initializes hw and priv. */
+static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg)
+{
+ struct iwl_priv *priv;
+ /* mac80211 allocates memory for this device instance, including
+ * space for this driver's private structure */
+ struct ieee80211_hw *hw;
+
+ hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwlagn_hw_ops);
+ if (hw == NULL) {
+ pr_err("%s: Can not allocate network device\n",
+ cfg->name);
+ goto out;
+ }
+
+ priv = hw->priv;
+ priv->hw = hw;
+
+out:
+ return hw;
+}
+
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int err = 0, i;
@@ -3963,19 +3504,12 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
unsigned long flags;
u16 pci_cmd, num_mac;
+ u32 hw_rev;
/************************
* 1. Allocating HW data
************************/
- /* Disabling hardware scan means that mac80211 will perform scans
- * "the hard way", rather than using device's scan. */
- if (cfg->mod_params->disable_hw_scan) {
- dev_printk(KERN_DEBUG, &(pdev->dev),
- "sw scan support is deprecated\n");
- iwlagn_hw_ops.hw_scan = NULL;
- }
-
hw = iwl_alloc_all(cfg);
if (!hw) {
err = -ENOMEM;
@@ -3984,6 +3518,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
priv = hw->priv;
/* At this point both hw and priv are allocated. */
+ priv->ucode_type = UCODE_SUBTYPE_NONE_LOADED;
+
/*
* The default context is always valid,
* more may be discovered when firmware
@@ -4116,16 +3652,15 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
*/
iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
- iwl_hw_detect(priv);
+ hw_rev = iwl_hw_detect(priv);
IWL_INFO(priv, "Detected %s, REV=0x%X\n",
- priv->cfg->name, priv->hw_rev);
+ priv->cfg->name, hw_rev);
/* We disable the RETRY_TIMEOUT register (0x41) to keep
* PCI Tx retries from interfering with C3 CPU state */
pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
- iwl_prepare_card_hw(priv);
- if (!priv->hw_ready) {
+ if (iwl_prepare_card_hw(priv)) {
IWL_WARN(priv, "Failed, HW not ready\n");
goto out_iounmap;
}
@@ -4134,7 +3669,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* 4. Read EEPROM
*****************/
/* Read the EEPROM */
- err = iwl_eeprom_init(priv);
+ err = iwl_eeprom_init(priv, hw_rev);
if (err) {
IWL_ERR(priv, "Unable to init EEPROM\n");
goto out_iounmap;
@@ -4186,10 +3721,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_enable_msi(priv->pci_dev);
- if (priv->cfg->ops->lib->isr_ops.alloc)
- priv->cfg->ops->lib->isr_ops.alloc(priv);
+ iwl_alloc_isr_ict(priv);
- err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr,
+ err = request_irq(priv->pci_dev->irq, iwl_isr_ict,
IRQF_SHARED, DRV_NAME, priv);
if (err) {
IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
@@ -4198,6 +3732,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iwl_setup_deferred_work(priv);
iwl_setup_rx_handlers(priv);
+ iwl_testmode_init(priv);
/*********************************************
* 8. Enable interrupts and read RFKILL state
@@ -4236,8 +3771,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
free_irq(priv->pci_dev->irq, priv);
- if (priv->cfg->ops->lib->isr_ops.free)
- priv->cfg->ops->lib->isr_ops.free(priv);
+ iwl_free_isr_ict(priv);
out_disable_msi:
pci_disable_msi(priv->pci_dev);
iwl_uninit_drv(priv);
@@ -4283,17 +3817,9 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
if (priv->mac80211_registered) {
ieee80211_unregister_hw(priv->hw);
priv->mac80211_registered = 0;
- } else {
- iwl_down(priv);
}
- /*
- * Make sure device is reset to low power before unloading driver.
- * This may be redundant with iwl_down(), but there are paths to
- * run iwl_down() without calling apm_ops.stop(), and there are
- * paths to avoid running iwl_down() at all before leaving driver.
- * This (inexpensive) call *makes sure* device is reset.
- */
+ /* Reset to low power before unloading driver. */
iwl_apm_stop(priv);
iwl_tt_exit(priv);
@@ -4335,8 +3861,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
iwl_uninit_drv(priv);
- if (priv->cfg->ops->lib->isr_ops.free)
- priv->cfg->ops->lib->isr_ops.free(priv);
+ iwl_free_isr_ict(priv);
dev_kfree_skb(priv->beacon_skb);
@@ -4521,21 +4046,21 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)},
{IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)},
-/* 200 Series */
- {IWL_PCI_DEVICE(0x0894, 0x0022, iwl200_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0895, 0x0222, iwl200_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0894, 0x0422, iwl200_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0894, 0x0026, iwl200_bg_cfg)},
- {IWL_PCI_DEVICE(0x0895, 0x0226, iwl200_bg_cfg)},
- {IWL_PCI_DEVICE(0x0894, 0x0426, iwl200_bg_cfg)},
-
-/* 230 Series */
- {IWL_PCI_DEVICE(0x0892, 0x0062, iwl230_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0893, 0x0262, iwl230_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0892, 0x0462, iwl230_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0892, 0x0066, iwl230_bg_cfg)},
- {IWL_PCI_DEVICE(0x0893, 0x0266, iwl230_bg_cfg)},
- {IWL_PCI_DEVICE(0x0892, 0x0466, iwl230_bg_cfg)},
+/* 105 Series */
+ {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)},
+
+/* 135 Series */
+ {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0892, 0x0066, iwl135_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0893, 0x0266, iwl135_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0892, 0x0466, iwl135_bg_cfg)},
{0}
};
@@ -4585,43 +4110,21 @@ module_exit(iwl_exit);
module_init(iwl_init);
#ifdef CONFIG_IWLWIFI_DEBUG
-module_param_named(debug50, iwl_debug_level, uint, S_IRUGO);
-MODULE_PARM_DESC(debug50, "50XX debug output mask (deprecated)");
module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "debug output mask");
#endif
-module_param_named(swcrypto50, iwlagn_mod_params.sw_crypto, bool, S_IRUGO);
-MODULE_PARM_DESC(swcrypto50,
- "using crypto in software (default 0 [hardware]) (deprecated)");
module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO);
MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
-module_param_named(queues_num50,
- iwlagn_mod_params.num_of_queues, int, S_IRUGO);
-MODULE_PARM_DESC(queues_num50,
- "number of hw queues in 50xx series (deprecated)");
module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO);
MODULE_PARM_DESC(queues_num, "number of hw queues.");
-module_param_named(11n_disable50, iwlagn_mod_params.disable_11n, int, S_IRUGO);
-MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality (deprecated)");
module_param_named(11n_disable, iwlagn_mod_params.disable_11n, int, S_IRUGO);
MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
-module_param_named(amsdu_size_8K50, iwlagn_mod_params.amsdu_size_8K,
- int, S_IRUGO);
-MODULE_PARM_DESC(amsdu_size_8K50,
- "enable 8K amsdu size in 50XX series (deprecated)");
module_param_named(amsdu_size_8K, iwlagn_mod_params.amsdu_size_8K,
int, S_IRUGO);
MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
-module_param_named(fw_restart50, iwlagn_mod_params.restart_fw, int, S_IRUGO);
-MODULE_PARM_DESC(fw_restart50,
- "restart firmware in case of error (deprecated)");
module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO);
MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
-module_param_named(
- disable_hw_scan, iwlagn_mod_params.disable_hw_scan, int, S_IRUGO);
-MODULE_PARM_DESC(disable_hw_scan,
- "disable hardware scanning (default 0) (deprecated)");
module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int,
S_IRUGO);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 20f8e418899..fe33fe8aa41 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -66,7 +66,6 @@
#include "iwl-dev.h"
/* configuration for the _agn devices */
-extern struct iwl_cfg iwl4965_agn_cfg;
extern struct iwl_cfg iwl5300_agn_cfg;
extern struct iwl_cfg iwl5100_agn_cfg;
extern struct iwl_cfg iwl5350_agn_cfg;
@@ -103,10 +102,10 @@ extern struct iwl_cfg iwl2030_2bg_cfg;
extern struct iwl_cfg iwl6035_2agn_cfg;
extern struct iwl_cfg iwl6035_2abg_cfg;
extern struct iwl_cfg iwl6035_2bg_cfg;
-extern struct iwl_cfg iwl200_bg_cfg;
-extern struct iwl_cfg iwl200_bgn_cfg;
-extern struct iwl_cfg iwl230_bg_cfg;
-extern struct iwl_cfg iwl230_bgn_cfg;
+extern struct iwl_cfg iwl105_bg_cfg;
+extern struct iwl_cfg iwl105_bgn_cfg;
+extern struct iwl_cfg iwl135_bg_cfg;
+extern struct iwl_cfg iwl135_bgn_cfg;
extern struct iwl_mod_params iwlagn_mod_params;
extern struct iwl_hcmd_ops iwlagn_hcmd;
@@ -114,7 +113,6 @@ extern struct iwl_hcmd_ops iwlagn_bt_hcmd;
extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
extern struct ieee80211_ops iwlagn_hw_ops;
-extern struct ieee80211_ops iwl4965_hw_ops;
int iwl_reset_ict(struct iwl_priv *priv);
void iwl_disable_ict(struct iwl_priv *priv);
@@ -122,21 +120,25 @@ int iwl_alloc_isr_ict(struct iwl_priv *priv);
void iwl_free_isr_ict(struct iwl_priv *priv);
irqreturn_t iwl_isr_ict(int irq, void *data);
+/* call this function to flush any scheduled tasklet */
+static inline void iwl_synchronize_irq(struct iwl_priv *priv)
+{
+ /* wait to make sure we flush pending tasklet*/
+ synchronize_irq(priv->pci_dev->irq);
+ tasklet_kill(&priv->irq_tasklet);
+}
+
+int iwl_prepare_card_hw(struct iwl_priv *priv);
+
+int iwlagn_start_device(struct iwl_priv *priv);
+void iwlagn_stop_device(struct iwl_priv *priv);
+
/* tx queue */
void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
int txq_id, u32 index);
void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
struct iwl_tx_queue *txq,
int tx_fifo_id, int scd_retry);
-void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
- struct iwl_tx_queue *txq,
- u16 byte_cnt);
-void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
- struct iwl_tx_queue *txq);
-int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
- int tx_fifo, int sta_id, int tid, u16 ssn_idx);
-int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
- u16 ssn_idx, u8 tx_fifo);
void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask);
void iwl_free_tfds_in_queue(struct iwl_priv *priv,
int sta_id, int tid, int freed);
@@ -151,16 +153,14 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
u32 changes);
/* uCode */
-int iwlagn_load_ucode(struct iwl_priv *priv);
void iwlagn_rx_calib_result(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
-void iwlagn_rx_calib_complete(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb);
-void iwlagn_init_alive_start(struct iwl_priv *priv);
-int iwlagn_alive_notify(struct iwl_priv *priv);
-int iwl_verify_ucode(struct iwl_priv *priv);
-void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
+int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
void iwlagn_send_prio_tbl(struct iwl_priv *priv);
+int iwlagn_run_init_ucode(struct iwl_priv *priv);
+int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
+ struct fw_img *image,
+ int subtype, int alternate_subtype);
/* lib */
void iwl_check_abort_status(struct iwl_priv *priv,
@@ -179,8 +179,6 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv);
int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv);
int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
-void iwl_dump_csr(struct iwl_priv *priv);
-int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
/* rx */
void iwlagn_rx_queue_restock(struct iwl_priv *priv);
@@ -206,6 +204,9 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid, u16 *ssn);
int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid);
+void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv,
+ struct ieee80211_sta *sta,
+ int tid, int frame_limit);
int iwlagn_txq_check_empty(struct iwl_priv *priv,
int sta_id, u8 tid, int txq_id);
void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
@@ -225,6 +226,7 @@ static inline u32 iwl_tx_status_to_mac80211(u32 status)
case TX_STATUS_DIRECT_DONE:
return IEEE80211_TX_STAT_ACK;
case TX_STATUS_FAIL_DEST_PS:
+ case TX_STATUS_FAIL_PASSIVE_NO_RX:
return IEEE80211_TX_STAT_TX_FILTERED;
default:
return 0;
@@ -249,8 +251,6 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add);
/* hcmd */
-int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
- struct iwl_rxon_context *ctx);
int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
@@ -311,7 +311,7 @@ static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
{
- return le32_to_cpu(rate_n_flags) & 0xFF;
+ return le32_to_cpu(rate_n_flags) & RATE_MCS_RATE_MSK;
}
static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
@@ -322,50 +322,39 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
/* eeprom */
void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv);
void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
-int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
-void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
/* notification wait support */
void __acquires(wait_entry)
iwlagn_init_notification_wait(struct iwl_priv *priv,
struct iwl_notification_wait *wait_entry,
+ u8 cmd,
void (*fn)(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt),
- u8 cmd);
-signed long __releases(wait_entry)
+ struct iwl_rx_packet *pkt,
+ void *data),
+ void *fn_data);
+int __must_check __releases(wait_entry)
iwlagn_wait_notification(struct iwl_priv *priv,
struct iwl_notification_wait *wait_entry,
unsigned long timeout);
void __releases(wait_entry)
iwlagn_remove_notification(struct iwl_priv *priv,
struct iwl_notification_wait *wait_entry);
-
-/* mac80211 handlers (for 4965) */
-void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
-int iwlagn_mac_start(struct ieee80211_hw *hw);
-void iwlagn_mac_stop(struct ieee80211_hw *hw);
-void iwlagn_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags,
- u64 multicast);
-int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- struct ieee80211_vif *vif, struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key);
-void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_key_conf *keyconf,
- struct ieee80211_sta *sta,
- u32 iv32, u16 *phase1key);
-int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- enum ieee80211_ampdu_mlme_action action,
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
- u8 buf_size);
-int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
-void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
- struct ieee80211_channel_switch *ch_switch);
-void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop);
+extern int iwlagn_init_alive_start(struct iwl_priv *priv);
+extern int iwl_alive_start(struct iwl_priv *priv);
+/* svtool */
+#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
+extern int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len);
+extern void iwl_testmode_init(struct iwl_priv *priv);
+#else
+static inline
+int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
+{
+ return -ENOSYS;
+}
+static inline
+void iwl_testmode_init(struct iwl_priv *priv)
+{
+}
+#endif
#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index ca42ffa63ed..5fdad653211 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -103,9 +103,7 @@ enum {
REPLY_WEPKEY = 0x20,
/* 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, /* for 4965 and up */
@@ -229,7 +227,7 @@ struct iwl_cmd_header {
* 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
+ * example, uCode issues REPLY_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:
@@ -249,36 +247,6 @@ struct iwl_cmd_header {
/**
- * 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 */
-} __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;
-} __packed;
-
-/**
* iwlagn rate_n_flags bit fields
*
* rate_n_flags format is used in following iwlagn commands:
@@ -324,6 +292,8 @@ struct iwl3945_power_per_rate {
#define RATE_MCS_SPATIAL_MSK 0x18
#define RATE_MCS_HT_DUP_POS 5
#define RATE_MCS_HT_DUP_MSK 0x20
+/* Both legacy and HT use bits 7:0 as the CCK/OFDM rate or HT MCS */
+#define RATE_MCS_RATE_MSK 0xff
/* Bit 8: (1) HT format, (0) legacy format in bits 7:0 */
#define RATE_MCS_FLAGS_POS 8
@@ -375,30 +345,6 @@ struct iwl3945_power_per_rate {
#define IWL_PWR_CCK_ENTRIES 2
/**
- * 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
@@ -410,15 +356,6 @@ struct tx_power_dual_stream {
} __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];
-} __packed;
-
-/**
* Command REPLY_TX_POWER_DBM_CMD = 0x98
* struct iwlagn_tx_power_dbm_cmd
*/
@@ -449,55 +386,18 @@ struct iwl_tx_ant_config_cmd {
*****************************************************************************/
#define UCODE_VALID_OK 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 verse.
- *
- * 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 iwl_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 HT40 */
- __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 */
-} __packed;
+enum iwlagn_ucode_subtype {
+ UCODE_SUBTYPE_REGULAR = 0,
+ UCODE_SUBTYPE_REGULAR_NEW = 1,
+ UCODE_SUBTYPE_INIT = 9,
+ /*
+ * Not a valid subtype, the ucode has just a u8, so
+ * we can use something > 0xff for this value.
+ */
+ UCODE_SUBTYPE_NONE_LOADED = 0x100,
+};
/**
* REPLY_ALIVE = 0x1 (response only, not a command)
@@ -533,49 +433,61 @@ struct iwl_init_alive_resp {
*
* 2) error_event_table_ptr indicates base of the error log. This contains
* information about any uCode error that occurs. For agn, 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
- * __le32 gp1; GP1 timer register
- * __le32 gp2; GP2 timer register
- * __le32 gp3; GP3 timer register
- * __le32 ucode_ver; uCode version
- * __le32 hw_ver; HW Silicon version
- * __le32 brd_ver; HW board version
- * __le32 log_pc; log program counter
- * __le32 frame_ptr; frame pointer
- * __le32 stack_ptr; stack pointer
- * __le32 hcmd; last host command
- * __le32 isr0; isr status register LMPM_NIC_ISR0: rxtx_flag
- * __le32 isr1; isr status register LMPM_NIC_ISR1: host_flag
- * __le32 isr2; isr status register LMPM_NIC_ISR2: enc_flag
- * __le32 isr3; isr status register LMPM_NIC_ISR3: time_flag
- * __le32 isr4; isr status register LMPM_NIC_ISR4: wico interrupt
- * __le32 isr_pref; isr status register LMPM_NIC_PREF_STAT
- * __le32 wait_event; wait event() caller address
- * __le32 l2p_control; L2pControlField
- * __le32 l2p_duration; L2pDurationField
- * __le32 l2p_mhvalid; L2pMhValidBits
- * __le32 l2p_addr_match; L2pAddrMatchStat
- * __le32 lmpm_pmg_sel; indicate which clocks are turned on (LMPM_PMG_SEL)
- * __le32 u_timestamp; indicate when the date and time of the compilation
- * __le32 reserved;
+ * of the error log is defined by struct iwl_error_event_table.
*
* The Linux driver can print both logs to the system log when a uCode error
* occurs.
*/
+
+/*
+ * Note: This structure is read from the device with IO accesses,
+ * and the reading already does the endian conversion. As it is
+ * read with u32-sized accesses, any members with a different size
+ * need to be ordered correctly though!
+ */
+struct iwl_error_event_table {
+ u32 valid; /* (nonzero) valid, (0) log is empty */
+ u32 error_id; /* type of error */
+ u32 pc; /* program counter */
+ u32 blink1; /* branch link */
+ u32 blink2; /* branch link */
+ u32 ilink1; /* interrupt link */
+ u32 ilink2; /* interrupt link */
+ u32 data1; /* error-specific data */
+ u32 data2; /* error-specific data */
+ u32 line; /* source code line of error */
+ u32 bcon_time; /* beacon timer */
+ u32 tsf_low; /* network timestamp function timer */
+ u32 tsf_hi; /* network timestamp function timer */
+ u32 gp1; /* GP1 timer register */
+ u32 gp2; /* GP2 timer register */
+ u32 gp3; /* GP3 timer register */
+ u32 ucode_ver; /* uCode version */
+ u32 hw_ver; /* HW Silicon version */
+ u32 brd_ver; /* HW board version */
+ u32 log_pc; /* log program counter */
+ u32 frame_ptr; /* frame pointer */
+ u32 stack_ptr; /* stack pointer */
+ u32 hcmd; /* last host command header */
+#if 0
+ /* no need to read the remainder, we don't use the values */
+ u32 isr0; /* isr status register LMPM_NIC_ISR0: rxtx_flag */
+ u32 isr1; /* isr status register LMPM_NIC_ISR1: host_flag */
+ u32 isr2; /* isr status register LMPM_NIC_ISR2: enc_flag */
+ u32 isr3; /* isr status register LMPM_NIC_ISR3: time_flag */
+ u32 isr4; /* isr status register LMPM_NIC_ISR4: wico interrupt */
+ u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */
+ u32 wait_event; /* wait event() caller address */
+ u32 l2p_control; /* L2pControlField */
+ u32 l2p_duration; /* L2pDurationField */
+ u32 l2p_mhvalid; /* L2pMhValidBits */
+ u32 l2p_addr_match; /* L2pAddrMatchStat */
+ u32 lmpm_pmg_sel; /* indicate which clocks are turned on (LMPM_PMG_SEL) */
+ u32 u_timestamp; /* indicate when the date and time of the compilation */
+ u32 flow_handler; /* FH read/write pointers, RX credit */
+#endif
+} __packed;
+
struct iwl_alive_resp {
u8 ucode_minor;
u8 ucode_major;
@@ -722,46 +634,6 @@ enum {
* 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;
-} __packed;
-
-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;
-} __packed;
-
-/* 5000 HW just extend this command */
struct iwl_rxon_cmd {
u8 node_addr[6];
__le16 reserved1;
@@ -789,26 +661,7 @@ struct iwl_rxon_cmd {
/*
* 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;
-} __packed;
-
-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;
-} __packed;
-
-struct iwl5000_rxon_assoc_cmd {
+struct iwl_rxon_assoc_cmd {
__le32 flags;
__le32 filter_flags;
u8 ofdm_basic_rates;
@@ -843,26 +696,6 @@ struct iwl_rxon_time_cmd {
/*
* 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];
-} __packed;
-
-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;
-} __packed;
-
/**
* struct iwl5000_channel_switch_cmd
* @band: 0- 5.2GHz, 1- 2.4GHz
@@ -976,15 +809,10 @@ struct iwl_qosparam_cmd {
#define IWL_AP_ID 0
#define IWL_AP_ID_PAN 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 IWLAGN_PAN_BCAST_ID 14
#define IWLAGN_BROADCAST_ID 15
#define IWLAGN_STATION_COUNT 16
-#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/
#define IWL_INVALID_STATION 255
#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2)
@@ -1032,16 +860,6 @@ struct iwl_qosparam_cmd {
* 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 */
- u8 key_offset;
- u8 reserved2;
- u8 key[16]; /* 16-byte unicast decryption key */
-} __packed;
-
/* agn */
struct iwl_keyinfo {
__le16 key_flags;
@@ -1083,7 +901,6 @@ struct sta_id_modify {
* with info on security keys, aggregation parameters, and Tx rates for
* initial Tx attempt and any retries (agn devices 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.
@@ -1103,72 +920,6 @@ struct sta_id_modify {
* 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 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 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;
-} __packed;
-
-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;
-
- /*
- * Number of packets OK to transmit to station even though
- * it is asleep -- used to synchronise PS-poll and u-APSD
- * responses while ucode keeps track of STA sleep state.
- */
- __le16 sleep_tx_count;
-
- __le16 reserved2;
-} __packed;
-
-/* agn */
struct iwl_addsta_cmd {
u8 mode; /* 1: modify existing, 0: add new station */
u8 reserved[3];
@@ -1337,62 +1088,6 @@ struct iwl_wep_cmd {
#define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800)
-struct iwl3945_rx_frame_stats {
- u8 phy_count;
- u8 id;
- u8 rssi;
- u8 agc;
- __le16 sig_avg;
- __le16 noise_diff;
- u8 payload[0];
-} __packed;
-
-struct iwl3945_rx_frame_hdr {
- __le16 channel;
- __le16 phy_flags;
- u8 reserved1;
- u8 rate;
- __le16 len;
- u8 payload[0];
-} __packed;
-
-struct iwl3945_rx_frame_end {
- __le32 status;
- __le64 timestamp;
- __le32 beacon_timestamp;
-} __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;
-} __packed;
-
-#define IWL39_RX_FRAME_SIZE (4 + sizeof(struct iwl3945_rx_frame))
-
-/* Fixed (non-configurable) rx data from phy */
-
-#define IWL49_RX_RES_PHY_CNT 14
-#define IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET (4)
-#define IWL49_RX_PHY_FLAGS_ANTENNAE_MASK (0x70)
-#define IWL49_AGC_DB_MASK (0x3f80) /* MASK(7,13) */
-#define IWL49_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];
-} __packed;
-
-
#define IWLAGN_RX_RES_PHY_CNT 8
#define IWLAGN_RX_RES_AGC_IDX 1
#define IWLAGN_RX_RES_RSSI_AB_IDX 2
@@ -1576,80 +1271,6 @@ struct iwl_rx_mpdu_res_start {
* 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];
-} __packed;
-
-/*
- * 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 */
-} __packed;
-
-
/*
* 4965 uCode updates these Tx attempt count values in host DRAM.
* Used for managing Tx retries when expecting block-acks.
@@ -1740,54 +1361,6 @@ struct iwl_tx_cmd {
struct ieee80211_hdr hdr[0];
} __packed;
-/* TX command response is sent after *3945* 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_3945_STATUS_SUCCESS = 0x01,
- TX_3945_STATUS_DIRECT_DONE = 0x02,
- TX_3945_STATUS_FAIL_SHORT_LIMIT = 0x82,
- TX_3945_STATUS_FAIL_LONG_LIMIT = 0x83,
- TX_3945_STATUS_FAIL_FIFO_UNDERRUN = 0x84,
- TX_3945_STATUS_FAIL_MGMNT_ABORT = 0x85,
- TX_3945_STATUS_FAIL_NEXT_FRAG = 0x86,
- TX_3945_STATUS_FAIL_LIFE_EXPIRE = 0x87,
- TX_3945_STATUS_FAIL_DEST_PS = 0x88,
- TX_3945_STATUS_FAIL_ABORTED = 0x89,
- TX_3945_STATUS_FAIL_BT_RETRY = 0x8a,
- TX_3945_STATUS_FAIL_STA_INVALID = 0x8b,
- TX_3945_STATUS_FAIL_FRAG_DROPPED = 0x8c,
- TX_3945_STATUS_FAIL_TID_DISABLE = 0x8d,
- TX_3945_STATUS_FAIL_FRAME_FLUSHED = 0x8e,
- TX_3945_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f,
- TX_3945_STATUS_FAIL_TX_LOCKED = 0x90,
- TX_3945_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91,
-};
-
/*
* TX command response is sent after *agn* transmission attempts.
*
@@ -1905,43 +1478,6 @@ struct agg_tx_status {
__le16 sequence;
} __packed;
-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!)
- */
- union {
- __le32 status;
- struct agg_tx_status agg_status[0]; /* for each agg frame */
- } u;
-} __packed;
-
/*
* definitions for initial rate index field
* bits [3:0] initial rate index
@@ -2030,51 +1566,7 @@ struct iwl_compressed_ba_resp {
/*
* REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response)
*
- * See details under "TXPOWER" in iwl-4965-hw.h.
- */
-
-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];
-} __packed;
-
-struct iwl4965_txpowertable_cmd {
- u8 band; /* 0: 5 GHz, 1: 2.4 GHz */
- u8 reserved;
- __le16 channel;
- struct iwl4965_tx_power_db tx_power;
-} __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_info {
- __le16 rate_n_flags;
- u8 try_cnt;
- u8 next_rate_index;
-} __packed;
-
-struct iwl3945_rate_scaling_cmd {
- u8 table_id;
- u8 reserved[3];
- struct iwl3945_rate_scaling_info table[IWL_MAX_RATES];
-} __packed;
-
/*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */
#define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1 << 0)
@@ -2130,7 +1622,7 @@ struct iwl_link_qual_general_params {
#define LINK_QUAL_AGG_DISABLE_START_MAX (255)
#define LINK_QUAL_AGG_DISABLE_START_MIN (0)
-#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (31)
+#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63)
#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63)
#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0)
@@ -2696,14 +2188,6 @@ struct iwl_spectrum_notification {
#define IWL_POWER_BT_SCO_ENA cpu_to_le16(BIT(8))
#define IWL_POWER_ADVANCE_PM_ENA_MSK cpu_to_le16(BIT(9))
-struct iwl3945_powertable_cmd {
- __le16 flags;
- u8 reserved[2];
- __le32 rx_data_timeout;
- __le32 tx_data_timeout;
- __le32 sleep_interval[IWL_POWER_VEC_SIZE];
-} __packed;
-
struct iwl_powertable_cmd {
__le16 flags;
u8 keep_alive_seconds; /* 3945 reserved */
@@ -2806,25 +2290,6 @@ struct iwl_ct_kill_throttling_config {
* active_dwell < max_out_time
*/
-/* FIXME: rename to AP1, remove tpc */
-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 */
-} __packed;
-
-/* set number of direct probes u8 type */
-#define IWL39_SCAN_PROBE_MASK(n) ((BIT(n) | (BIT(n) - BIT(1))))
-
struct iwl_scan_channel {
/*
* type is defined as:
@@ -2920,50 +2385,6 @@ struct iwl_ssid_ie {
* struct iwl_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 iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_3945];
-
- /*
- * 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];
-} __packed;
-
enum iwl_scan_flags {
/* BIT(0) currently unused */
IWL_SCAN_FLAGS_ACTION_FRAME_TX = BIT(1),
@@ -3090,20 +2511,6 @@ enum iwl_ibss_manager {
* 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;
-} __packed;
-
-struct iwl4965_beacon_notif {
- struct iwl4965_tx_resp beacon_notify_hdr;
- __le32 low_tsf;
- __le32 high_tsf;
- __le32 ibss_mgr_status;
-} __packed;
-
struct iwlagn_beacon_notif {
struct iwlagn_tx_resp beacon_notify_hdr;
__le32 low_tsf;
@@ -3115,14 +2522,6 @@ struct iwlagn_beacon_notif {
* 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 */
-} __packed;
-
struct iwl_tx_beacon_cmd {
struct iwl_tx_cmd tx;
__le16 tim_idx;
@@ -3159,53 +2558,6 @@ struct rate_histogram {
/* statistics command response */
-struct iwl39_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;
-} __packed;
-
-struct iwl39_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 */
-} __packed;
-
-struct iwl39_statistics_rx {
- struct iwl39_statistics_rx_phy ofdm;
- struct iwl39_statistics_rx_phy cck;
- struct iwl39_statistics_rx_non_phy general;
-} __packed;
-
-struct iwl39_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;
-} __packed;
-
struct statistics_dbg {
__le32 burst_check;
__le32 burst_count;
@@ -3213,23 +2565,6 @@ struct statistics_dbg {
__le32 reserved[3];
} __packed;
-struct iwl39_statistics_div {
- __le32 tx_on_a;
- __le32 tx_on_b;
- __le32 exec_time;
- __le32 probe_time;
-} __packed;
-
-struct iwl39_statistics_general {
- __le32 temperature;
- struct statistics_dbg dbg;
- __le32 sleep_time;
- __le32 slots_out;
- __le32 slots_idle;
- __le32 ttl_timestamp;
- struct iwl39_statistics_div div;
-} __packed;
-
struct statistics_rx_phy {
__le32 ina_cnt;
__le32 fina_cnt;
@@ -3471,13 +2806,6 @@ struct iwl_statistics_cmd {
#define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2)
#define STATISTICS_REPLY_FLG_HT40_MODE_MSK cpu_to_le32(0x8)
-struct iwl3945_notif_statistics {
- __le32 flag;
- struct iwl39_statistics_rx rx;
- struct iwl39_statistics_tx tx;
- struct iwl39_statistics_general general;
-} __packed;
-
struct iwl_notif_statistics {
__le32 flag;
struct statistics_rx rx;
@@ -4451,10 +3779,6 @@ struct iwl_rx_packet {
__le32 len_n_flags;
struct iwl_cmd_header hdr;
union {
- struct iwl3945_rx_frame rx_frame;
- struct iwl3945_tx_resp tx_resp;
- struct iwl3945_beacon_notif beacon_status;
-
struct iwl_alive_resp alive_frame;
struct iwl_spectrum_notification spectrum_notif;
struct iwl_csa_notification csa_notif;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index bafbe57c960..4653deada05 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -41,6 +41,7 @@
#include "iwl-power.h"
#include "iwl-sta.h"
#include "iwl-helpers.h"
+#include "iwl-agn.h"
/*
@@ -67,30 +68,6 @@ u32 iwl_debug_level;
const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-
-/* This function both allocates and initializes hw and priv. */
-struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg)
-{
- struct iwl_priv *priv;
- /* mac80211 allocates memory for this device instance, including
- * space for this driver's private structure */
- struct ieee80211_hw *hw;
-
- hw = ieee80211_alloc_hw(sizeof(struct iwl_priv),
- cfg->ops->ieee80211_ops);
- if (hw == NULL) {
- pr_err("%s: Can not allocate network device\n",
- cfg->name);
- goto out;
- }
-
- priv = hw->priv;
- priv->hw = hw;
-
-out:
- return hw;
-}
-
#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
@@ -118,7 +95,7 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
max_bit_rate = MAX_BIT_RATE_40_MHZ;
}
- if (priv->cfg->mod_params->amsdu_size_8K)
+ if (iwlagn_mod_params.amsdu_size_8K)
ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
@@ -159,6 +136,7 @@ int iwlcore_init_geos(struct iwl_priv *priv)
struct ieee80211_channel *geo_ch;
struct ieee80211_rate *rates;
int i = 0;
+ s8 max_tx_power = IWLAGN_TX_POWER_TARGET_POWER_MIN;
if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
@@ -232,8 +210,8 @@ int iwlcore_init_geos(struct iwl_priv *priv)
geo_ch->flags |= ch->ht40_extension_channel;
- if (ch->max_power_avg > priv->tx_power_device_lmt)
- priv->tx_power_device_lmt = ch->max_power_avg;
+ if (ch->max_power_avg > max_tx_power)
+ max_tx_power = ch->max_power_avg;
} else {
geo_ch->flags |= IEEE80211_CHAN_DISABLED;
}
@@ -246,6 +224,10 @@ int iwlcore_init_geos(struct iwl_priv *priv)
geo_ch->flags);
}
+ priv->tx_power_device_lmt = max_tx_power;
+ priv->tx_power_user_lmt = max_tx_power;
+ priv->tx_power_next = max_tx_power;
+
if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
priv->cfg->sku & IWL_SKU_A) {
IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
@@ -434,72 +416,72 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
struct iwl_rxon_cmd *rxon = &ctx->staging;
- bool error = false;
+ u32 errors = 0;
if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) {
IWL_WARN(priv, "check 2.4G: wrong narrow\n");
- error = true;
+ errors |= BIT(0);
}
if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) {
IWL_WARN(priv, "check 2.4G: wrong radar\n");
- error = true;
+ errors |= BIT(1);
}
} else {
if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) {
IWL_WARN(priv, "check 5.2G: not short slot!\n");
- error = true;
+ errors |= BIT(2);
}
if (rxon->flags & RXON_FLG_CCK_MSK) {
IWL_WARN(priv, "check 5.2G: CCK!\n");
- error = true;
+ errors |= BIT(3);
}
}
if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) {
IWL_WARN(priv, "mac/bssid mcast!\n");
- error = true;
+ errors |= BIT(4);
}
/* make sure basic rates 6Mbps and 1Mbps are supported */
if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 &&
(rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) {
IWL_WARN(priv, "neither 1 nor 6 are basic\n");
- error = true;
+ errors |= BIT(5);
}
if (le16_to_cpu(rxon->assoc_id) > 2007) {
IWL_WARN(priv, "aid > 2007\n");
- error = true;
+ errors |= BIT(6);
}
if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
== (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) {
IWL_WARN(priv, "CCK and short slot\n");
- error = true;
+ errors |= BIT(7);
}
if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
== (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) {
IWL_WARN(priv, "CCK and auto detect");
- error = true;
+ errors |= BIT(8);
}
if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
RXON_FLG_TGG_PROTECT_MSK)) ==
RXON_FLG_TGG_PROTECT_MSK) {
IWL_WARN(priv, "TGg but no auto-detect\n");
- error = true;
+ errors |= BIT(9);
}
- if (error)
- IWL_WARN(priv, "Tuning to channel %d\n",
- le16_to_cpu(rxon->channel));
-
- if (error) {
- IWL_ERR(priv, "Invalid RXON\n");
- return -EINVAL;
+ if (rxon->channel == 0) {
+ IWL_WARN(priv, "zero channel is invalid\n");
+ errors |= BIT(10);
}
- return 0;
+
+ WARN(errors, "Invalid RXON (%#x), channel %d",
+ errors, le16_to_cpu(rxon->channel));
+
+ return errors ? -EINVAL : 0;
}
/**
@@ -890,10 +872,21 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv,
IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
}
#endif
-/**
- * iwl_irq_handle_error - called for HW or SW error interrupt from card
- */
-void iwl_irq_handle_error(struct iwl_priv *priv)
+
+static void iwlagn_abort_notification_waits(struct iwl_priv *priv)
+{
+ unsigned long flags;
+ struct iwl_notification_wait *wait_entry;
+
+ spin_lock_irqsave(&priv->_agn.notif_wait_lock, flags);
+ list_for_each_entry(wait_entry, &priv->_agn.notif_waits, list)
+ wait_entry->aborted = true;
+ spin_unlock_irqrestore(&priv->_agn.notif_wait_lock, flags);
+
+ wake_up_all(&priv->_agn.notif_waitq);
+}
+
+void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
{
unsigned int reload_msec;
unsigned long reload_jiffies;
@@ -904,18 +897,64 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
/* Cancel currently queued command. */
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+ iwlagn_abort_notification_waits(priv);
+
+ /* Keep the restart process from trying to send host
+ * commands by clearing the ready bit */
+ clear_bit(STATUS_READY, &priv->status);
+
+ wake_up_interruptible(&priv->wait_command_queue);
+
+ if (!ondemand) {
+ /*
+ * If firmware keep reloading, then it indicate something
+ * serious wrong and firmware having problem to recover
+ * from it. Instead of keep trying which will fill the syslog
+ * and hang the system, let's just stop it
+ */
+ reload_jiffies = jiffies;
+ reload_msec = jiffies_to_msecs((long) reload_jiffies -
+ (long) priv->reload_jiffies);
+ priv->reload_jiffies = reload_jiffies;
+ if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
+ priv->reload_count++;
+ if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
+ IWL_ERR(priv, "BUG_ON, Stop restarting\n");
+ return;
+ }
+ } else
+ priv->reload_count = 0;
+ }
+
+ if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+ if (iwlagn_mod_params.restart_fw) {
+ IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
+ "Restarting adapter due to uCode error.\n");
+ queue_work(priv->workqueue, &priv->restart);
+ } else
+ IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
+ "Detected FW error, but not restarting\n");
+ }
+}
+
+/**
+ * iwl_irq_handle_error - called for HW or SW error interrupt from card
+ */
+void iwl_irq_handle_error(struct iwl_priv *priv)
+{
/* W/A for WiFi/WiMAX coex and WiMAX own the RF */
if (priv->cfg->internal_wimax_coex &&
(!(iwl_read_prph(priv, APMG_CLK_CTRL_REG) &
APMS_CLK_VAL_MRB_FUNC_MODE) ||
(iwl_read_prph(priv, APMG_PS_CTRL_REG) &
APMG_PS_CTRL_VAL_RESET_REQ))) {
- wake_up_interruptible(&priv->wait_command_queue);
/*
- *Keep the restart process from trying to send host
- * commands by clearing the INIT status bit
+ * Keep the restart process from trying to send host
+ * commands by clearing the ready bit.
*/
clear_bit(STATUS_READY, &priv->status);
+ clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+ wake_up_interruptible(&priv->wait_command_queue);
IWL_ERR(priv, "RF is used by WiMAX\n");
return;
}
@@ -923,50 +962,17 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
IWL_ERR(priv, "Loaded firmware version: %s\n",
priv->hw->wiphy->fw_version);
- priv->cfg->ops->lib->dump_nic_error_log(priv);
- if (priv->cfg->ops->lib->dump_csr)
- priv->cfg->ops->lib->dump_csr(priv);
- if (priv->cfg->ops->lib->dump_fh)
- priv->cfg->ops->lib->dump_fh(priv, NULL, false);
- priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false);
+ iwl_dump_nic_error_log(priv);
+ iwl_dump_csr(priv);
+ iwl_dump_fh(priv, NULL, false);
+ iwl_dump_nic_event_log(priv, false, NULL, false);
#ifdef CONFIG_IWLWIFI_DEBUG
if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
iwl_print_rx_config_cmd(priv,
&priv->contexts[IWL_RXON_CTX_BSS]);
#endif
- wake_up_interruptible(&priv->wait_command_queue);
-
- /* Keep the restart process from trying to send host
- * commands by clearing the INIT status bit */
- clear_bit(STATUS_READY, &priv->status);
-
- /*
- * If firmware keep reloading, then it indicate something
- * serious wrong and firmware having problem to recover
- * from it. Instead of keep trying which will fill the syslog
- * and hang the system, let's just stop it
- */
- reload_jiffies = jiffies;
- reload_msec = jiffies_to_msecs((long) reload_jiffies -
- (long) priv->reload_jiffies);
- priv->reload_jiffies = reload_jiffies;
- if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
- priv->reload_count++;
- if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
- IWL_ERR(priv, "BUG_ON, Stop restarting\n");
- return;
- }
- } else
- priv->reload_count = 0;
-
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
- "Restarting adapter due to uCode error.\n");
-
- if (priv->cfg->mod_params->restart_fw)
- queue_work(priv->workqueue, &priv->restart);
- }
+ iwlagn_fw_error(priv, false);
}
static int iwl_apm_stop_master(struct iwl_priv *priv)
@@ -990,6 +996,8 @@ void iwl_apm_stop(struct iwl_priv *priv)
{
IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");
+ clear_bit(STATUS_DEVICE_ENABLED, &priv->status);
+
/* Stop device's DMA activity */
iwl_apm_stop_master(priv);
@@ -1040,7 +1048,6 @@ int iwl_apm_init(struct iwl_priv *priv)
/*
* Enable HAP INTA (interrupt from management bus) to
* wake device's PCI Express link L1a -> L0s
- * NOTE: This is no-op for 3945 (non-existent bit)
*/
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
@@ -1053,20 +1060,18 @@ int iwl_apm_init(struct iwl_priv *priv)
* If not (unlikely), enable L0S, so there is at least some
* power savings, even without L1.
*/
- if (priv->cfg->base_params->set_l0s) {
- lctl = iwl_pcie_link_ctl(priv);
- if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
- PCI_CFG_LINK_CTRL_VAL_L1_EN) {
- /* L1-ASPM enabled; disable(!) L0S */
- iwl_set_bit(priv, CSR_GIO_REG,
- CSR_GIO_REG_VAL_L0S_ENABLED);
- IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n");
- } else {
- /* L1-ASPM disabled; enable(!) L0S */
- iwl_clear_bit(priv, CSR_GIO_REG,
- CSR_GIO_REG_VAL_L0S_ENABLED);
- IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n");
- }
+ lctl = iwl_pcie_link_ctl(priv);
+ if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
+ PCI_CFG_LINK_CTRL_VAL_L1_EN) {
+ /* L1-ASPM enabled; disable(!) L0S */
+ iwl_set_bit(priv, CSR_GIO_REG,
+ CSR_GIO_REG_VAL_L0S_ENABLED);
+ IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n");
+ } else {
+ /* L1-ASPM disabled; enable(!) L0S */
+ iwl_clear_bit(priv, CSR_GIO_REG,
+ CSR_GIO_REG_VAL_L0S_ENABLED);
+ IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n");
}
/* Configure analog phase-lock-loop before activating to D0A */
@@ -1094,27 +1099,21 @@ int iwl_apm_init(struct iwl_priv *priv)
}
/*
- * Enable DMA and BSM (if used) clocks, wait for them to stabilize.
- * BSM (Boostrap State Machine) is only in 3945 and 4965;
- * later devices (i.e. 5000 and later) have non-volatile SRAM,
- * and don't need BSM to restore data after power-saving sleep.
+ * Enable DMA clock and wait for it to stabilize.
*
* Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
* do not disable clocks. This preserves any hardware bits already
* set by default in "CLK_CTRL_REG" after reset.
*/
- if (priv->cfg->base_params->use_bsm)
- iwl_write_prph(priv, APMG_CLK_EN_REG,
- APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT);
- else
- iwl_write_prph(priv, APMG_CLK_EN_REG,
- APMG_CLK_VAL_DMA_CLK_RQT);
+ iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
udelay(20);
/* Disable L1-Active */
iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+ set_bit(STATUS_DEVICE_ENABLED, &priv->status);
+
out:
return ret;
}
@@ -1430,7 +1429,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
iwl_teardown_interface(priv, vif, false);
- memset(priv->bssid, 0, ETH_ALEN);
mutex_unlock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -1750,21 +1748,13 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
* detect failure), then fw_restart module parameter
* need to be check before performing firmware reload
*/
- if (!external && !priv->cfg->mod_params->restart_fw) {
+ if (!external && !iwlagn_mod_params.restart_fw) {
IWL_DEBUG_INFO(priv, "Cancel firmware reload based on "
"module parameter setting\n");
break;
}
IWL_ERR(priv, "On demand firmware reload\n");
- /* Set the FW error flag -- cleared on iwl_down */
- set_bit(STATUS_FW_ERROR, &priv->status);
- wake_up_interruptible(&priv->wait_command_queue);
- /*
- * Keep the restart process from trying to send host
- * commands by clearing the INIT status bit
- */
- clear_bit(STATUS_READY, &priv->status);
- queue_work(priv->workqueue, &priv->restart);
+ iwlagn_fw_error(priv, true);
break;
}
return 0;
@@ -1775,6 +1765,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
{
struct iwl_priv *priv = hw->priv;
struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+ struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS];
struct iwl_rxon_context *tmp;
u32 interface_modes;
int err;
@@ -1783,6 +1774,15 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mutex_lock(&priv->mutex);
+ if (!ctx->vif || !iwl_is_ready_rf(priv)) {
+ /*
+ * Huh? But wait ... this can maybe happen when
+ * we're in the middle of a firmware restart!
+ */
+ err = -EBUSY;
+ goto out;
+ }
+
interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes;
if (!(interface_modes & BIT(newtype))) {
@@ -1790,6 +1790,19 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
goto out;
}
+ /*
+ * Refuse a change that should be done by moving from the PAN
+ * context to the BSS context instead, if the BSS context is
+ * available and can support the new interface type.
+ */
+ if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif &&
+ (bss_ctx->interface_modes & BIT(newtype) ||
+ bss_ctx->exclusive_interface_modes & BIT(newtype))) {
+ BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
+ err = -EBUSY;
+ goto out;
+ }
+
if (ctx->exclusive_interface_modes & BIT(newtype)) {
for_each_context(priv, tmp) {
if (ctx == tmp)
@@ -1810,6 +1823,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
/* success */
iwl_teardown_interface(priv, vif, true);
vif->type = newtype;
+ vif->p2p = newp2p;
err = iwl_setup_interface(priv, ctx);
WARN_ON(err);
/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index b316d833d9a..5b5b0cce4a5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -73,7 +73,7 @@ struct iwl_cmd;
#define IWLWIFI_VERSION "in-tree:"
-#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation"
+#define DRV_COPYRIGHT "Copyright(c) 2003-2011 Intel Corporation"
#define DRV_AUTHOR "<ilw@linux.intel.com>"
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -90,7 +90,6 @@ struct iwl_cmd;
#define IWL_CMD(x) case x: return #x
struct iwl_hcmd_ops {
- int (*rxon_assoc)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
void (*set_rxon_chain)(struct iwl_priv *priv,
struct iwl_rxon_context *ctx);
@@ -100,7 +99,6 @@ struct iwl_hcmd_ops {
};
struct iwl_hcmd_utils_ops {
- u16 (*get_hcmd_size)(u8 cmd_id, u16 len);
u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data);
void (*gain_computation)(struct iwl_priv *priv,
u32 *average_noise,
@@ -122,46 +120,14 @@ struct iwl_apm_ops {
void (*config)(struct iwl_priv *priv);
};
-struct iwl_isr_ops {
- irqreturn_t (*isr) (int irq, void *data);
- void (*free)(struct iwl_priv *priv);
- int (*alloc)(struct iwl_priv *priv);
- int (*reset)(struct iwl_priv *priv);
- void (*disable)(struct iwl_priv *priv);
-};
-
-struct iwl_debugfs_ops {
- ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
- ssize_t (*tx_stats_read)(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
- ssize_t (*general_stats_read)(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
- ssize_t (*bt_stats_read)(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
- ssize_t (*reply_tx_error)(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-};
-
struct iwl_temp_ops {
void (*temperature)(struct iwl_priv *priv);
};
-struct iwl_tt_ops {
- bool (*lower_power_detection)(struct iwl_priv *priv);
- u8 (*tt_power_mode)(struct iwl_priv *priv);
- bool (*ct_kill_check)(struct iwl_priv *priv);
-};
-
struct iwl_lib_ops {
/* set hw dependent parameters */
int (*set_hw_params)(struct iwl_priv *priv);
/* Handling TX */
- void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv,
- struct iwl_tx_queue *txq,
- u16 byte_cnt);
- void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv,
- struct iwl_tx_queue *txq);
void (*txq_set_sched)(struct iwl_priv *priv, u32 mask);
int (*txq_attach_buf_to_tfd)(struct iwl_priv *priv,
struct iwl_tx_queue *txq,
@@ -171,30 +137,14 @@ struct iwl_lib_ops {
struct iwl_tx_queue *txq);
int (*txq_init)(struct iwl_priv *priv,
struct iwl_tx_queue *txq);
- /* aggregations */
- int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo,
- int sta_id, int tid, u16 ssn_idx);
- int (*txq_agg_disable)(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx,
- u8 tx_fifo);
/* setup Rx handler */
void (*rx_handler_setup)(struct iwl_priv *priv);
/* setup deferred work */
void (*setup_deferred_work)(struct iwl_priv *priv);
/* cancel deferred work */
void (*cancel_deferred_work)(struct iwl_priv *priv);
- /* alive notification after init uCode load */
- void (*init_alive_start)(struct iwl_priv *priv);
- /* alive notification */
- int (*alive_notify)(struct iwl_priv *priv);
/* check validity of rtc data address */
int (*is_valid_rtc_data_addr)(u32 addr);
- /* 1st ucode load */
- int (*load_ucode)(struct iwl_priv *priv);
- int (*dump_nic_event_log)(struct iwl_priv *priv,
- bool full_log, char **buf, bool display);
- void (*dump_nic_error_log)(struct iwl_priv *priv);
- void (*dump_csr)(struct iwl_priv *priv);
- int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display);
int (*set_channel_switch)(struct iwl_priv *priv,
struct ieee80211_channel_switch *ch_switch);
/* power management */
@@ -204,9 +154,6 @@ struct iwl_lib_ops {
int (*send_tx_power) (struct iwl_priv *priv);
void (*update_chain_flags)(struct iwl_priv *priv);
- /* isr */
- struct iwl_isr_ops isr_ops;
-
/* eeprom operations (as defined in iwl-eeprom.h) */
struct iwl_eeprom_ops eeprom_ops;
@@ -216,14 +163,6 @@ struct iwl_lib_ops {
int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
- struct iwl_debugfs_ops debugfs_ops;
-
- /* thermal throttling */
- struct iwl_tt_ops tt_ops;
-};
-
-struct iwl_led_ops {
- int (*cmd)(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd);
};
/* NIC specific ops */
@@ -231,28 +170,15 @@ struct iwl_nic_ops {
void (*additional_nic_config)(struct iwl_priv *priv);
};
-struct iwl_legacy_ops {
- void (*post_associate)(struct iwl_priv *priv);
- void (*config_ap)(struct iwl_priv *priv);
- /* station management */
- int (*update_bcast_stations)(struct iwl_priv *priv);
- int (*manage_ibss_station)(struct iwl_priv *priv,
- struct ieee80211_vif *vif, bool add);
-};
-
struct iwl_ops {
const struct iwl_lib_ops *lib;
const struct iwl_hcmd_ops *hcmd;
const struct iwl_hcmd_utils_ops *utils;
- const struct iwl_led_ops *led;
const struct iwl_nic_ops *nic;
- const struct iwl_legacy_ops *legacy;
- const struct ieee80211_ops *ieee80211_ops;
};
struct iwl_mod_params {
int sw_crypto; /* def: 0 = using hardware encryption */
- int disable_hw_scan; /* def: 0 = use h/w scan */
int num_of_queues; /* def: HW dependent */
int disable_11n; /* def: 0 = 11n capabilities enabled */
int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */
@@ -278,16 +204,7 @@ struct iwl_mod_params {
* @wd_timeout: TX queues watchdog timeout
* @temperature_kelvin: temperature report by uCode in kelvin
* @max_event_log_size: size of event log buffer size for ucode event logging
- * @tx_power_by_driver: tx power calibration performed by driver
- * instead of uCode
- * @ucode_tracing: support ucode continuous tracing
- * @sensitivity_calib_by_driver: driver has the capability to perform
- * sensitivity calibration operation
- * @chain_noise_calib_by_driver: driver has the capability to perform
- * chain noise calibration operation
* @shadow_reg_enable: HW shadhow register bit
- * @no_agg_framecnt_info: uCode do not provide aggregation frame count
- * information
*/
struct iwl_base_params {
int eeprom_size;
@@ -295,14 +212,10 @@ struct iwl_base_params {
int num_of_ampdu_queues;/* def: HW dependent */
/* for iwl_apm_init() */
u32 pll_cfg_val;
- bool set_l0s;
- bool use_bsm;
- bool use_isr_legacy;
const u16 max_ll_items;
const bool shadow_ram_support;
u16 led_compensation;
- const bool broken_powersave;
int chain_noise_num_beacons;
bool adv_thermal_throttle;
bool support_ct_kill_exit;
@@ -312,18 +225,12 @@ struct iwl_base_params {
unsigned int wd_timeout;
bool temperature_kelvin;
u32 max_event_log_size;
- const bool tx_power_by_driver;
- const bool ucode_tracing;
- const bool sensitivity_calib_by_driver;
- const bool chain_noise_calib_by_driver;
const bool shadow_reg_enable;
- const bool no_agg_framecnt_info;
};
/*
* @advanced_bt_coexist: support advanced bt coexist
* @bt_init_traffic_load: specify initial bt traffic load
* @bt_prio_boost: default bt priority boost value
- * @bt_statistics: use BT version of statistics notification
* @agg_time_limit: maximum number of uSec in aggregation
* @ampdu_factor: Maximum A-MPDU length factor
* @ampdu_density: Minimum A-MPDU spacing
@@ -333,7 +240,6 @@ struct iwl_bt_params {
bool advanced_bt_coexist;
u8 bt_init_traffic_load;
u8 bt_prio_boost;
- const bool bt_statistics;
u16 agg_time_limit;
u8 ampdu_factor;
u8 ampdu_density;
@@ -364,6 +270,7 @@ struct iwl_ht_params {
* @rx_with_siso_diversity: 1x1 device with rx antenna diversity
* @internal_wimax_coex: internal wifi/wimax combo device
* @iq_invert: I/Q inversion
+ * @disable_otp_refresh: disable OTP refresh current limit
*
* We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the
@@ -398,8 +305,6 @@ struct iwl_cfg {
u16 eeprom_ver;
u16 eeprom_calib_ver;
const struct iwl_ops *ops;
- /* module based parameters which can be set from modprobe cmd */
- const struct iwl_mod_params *mod_params;
/* params not likely to change within a device family */
struct iwl_base_params *base_params;
/* params likely to change within a device family */
@@ -414,13 +319,13 @@ struct iwl_cfg {
const bool rx_with_siso_diversity;
const bool internal_wimax_coex;
const bool iq_invert;
+ const bool disable_otp_refresh;
};
/***************************
* L i b *
***************************/
-struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg);
int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw);
@@ -625,6 +530,8 @@ extern const struct dev_pm_ops iwl_pm_ops;
void iwl_dump_nic_error_log(struct iwl_priv *priv);
int iwl_dump_nic_event_log(struct iwl_priv *priv,
bool full_log, char **buf, bool display);
+void iwl_dump_csr(struct iwl_priv *priv);
+int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
#ifdef CONFIG_IWLWIFI_DEBUG
void iwl_print_rx_config_cmd(struct iwl_priv *priv,
struct iwl_rxon_context *ctx);
@@ -662,6 +569,7 @@ void iwlcore_free_geos(struct iwl_priv *priv);
#define STATUS_SCAN_HW 15
#define STATUS_POWER_PMI 16
#define STATUS_FW_ERROR 17
+#define STATUS_DEVICE_ENABLED 18
static inline int iwl_is_ready(struct iwl_priv *priv)
@@ -714,11 +622,6 @@ void iwl_apm_stop(struct iwl_priv *priv);
int iwl_apm_init(struct iwl_priv *priv);
int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
-static inline int iwl_send_rxon_assoc(struct iwl_priv *priv,
- struct iwl_rxon_context *ctx)
-{
- return priv->cfg->ops->hcmd->rxon_assoc(priv, ctx);
-}
static inline int iwlcore_commit_rxon(struct iwl_priv *priv,
struct iwl_rxon_context *ctx)
{
@@ -736,12 +639,10 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv)
priv->cfg->bt_params->advanced_bt_coexist;
}
-static inline bool iwl_bt_statistics(struct iwl_priv *priv)
-{
- return priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics;
-}
-
extern bool bt_coex_active;
extern bool bt_siso_mode;
+
+void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand);
+
#endif /* __iwl_core_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index f52bc040bcb..5ab90ba7a02 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -155,18 +155,10 @@
#define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250)
/* Bits for CSR_HW_IF_CONFIG_REG */
-#define CSR49_HW_IF_CONFIG_REG_BIT_4965_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 CSR39_HW_IF_CONFIG_REG_BIT_3945_MB (0x00000100)
-#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MM (0x00000200)
-#define CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC (0x00000400)
-#define CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE (0x00000800)
-#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000)
-#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000)
-
#define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000)
#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000)
#define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY (0x00400000) /* PCI_OWN_SEM */
@@ -186,7 +178,7 @@
#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_SW_RX (1 << 3) /* Rx, command responses */
#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 */
@@ -202,29 +194,17 @@
/* 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 CSR39_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 CSR39_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 CSR39_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \
- CSR39_FH_INT_BIT_RX_CHNL2 | \
- CSR_FH_INT_BIT_RX_CHNL1 | \
- CSR_FH_INT_BIT_RX_CHNL0)
-
-
-#define CSR39_FH_INT_TX_MASK (CSR39_FH_INT_BIT_TX_CHNL6 | \
- CSR_FH_INT_BIT_TX_CHNL1 | \
- CSR_FH_INT_BIT_TX_CHNL0)
-
-#define CSR49_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_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \
+ CSR_FH_INT_BIT_RX_CHNL1 | \
+ CSR_FH_INT_BIT_RX_CHNL0)
-#define CSR49_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \
- CSR_FH_INT_BIT_TX_CHNL0)
+#define CSR_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \
+ CSR_FH_INT_BIT_TX_CHNL0)
/* GPIO */
#define CSR_GPIO_IN_BIT_AUX_POWER (0x00000200)
@@ -268,7 +248,7 @@
* Indicates MAC (ucode processor, etc.) is powered up and can run.
* Internal resources are accessible.
* NOTE: This does not indicate that the processor is actually running.
- * NOTE: This does not indicate that 4965 or 3945 has completed
+ * NOTE: This does not indicate that device has completed
* init or post-power-down restore of internal SRAM memory.
* Use CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP as indication that
* SRAM is restored and uCode is in normal operation mode.
@@ -291,8 +271,6 @@
/* HW REV */
#define CSR_HW_REV_TYPE_MSK (0x00001F0)
-#define CSR_HW_REV_TYPE_3945 (0x00000D0)
-#define CSR_HW_REV_TYPE_4965 (0x0000000)
#define CSR_HW_REV_TYPE_5300 (0x0000020)
#define CSR_HW_REV_TYPE_5350 (0x0000030)
#define CSR_HW_REV_TYPE_5100 (0x0000050)
@@ -363,7 +341,7 @@
* 0: MAC_SLEEP
* uCode sets this when preparing a power-saving power-down.
* uCode resets this when power-up is complete and SRAM is sane.
- * NOTE: 3945/4965 saves internal SRAM data to host when powering down,
+ * NOTE: device saves internal SRAM data to host when powering down,
* and must restore this data after powering back up.
* MAC_SLEEP is the best indication that restore is complete.
* Later devices (5xxx/6xxx/1xxx) use non-volatile SRAM, and
@@ -394,7 +372,6 @@
#define CSR_LED_REG_TRUN_OFF (0x38)
/* ANA_PLL */
-#define CSR39_ANA_PLL_CFG_VAL (0x01000000)
#define CSR50_ANA_PLL_CFG_VAL (0x00880300)
/* HPET MEM debug */
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index ebdea3be3ef..2824ccbcc1f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project.
*
@@ -146,7 +146,6 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
#define IWL_DL_RX (1 << 24)
#define IWL_DL_ISR (1 << 25)
#define IWL_DL_HT (1 << 26)
-#define IWL_DL_IO (1 << 27)
/* 0xF0000000 - 0x10000000 */
#define IWL_DL_11H (1 << 28)
#define IWL_DL_STATS (1 << 29)
@@ -174,7 +173,6 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a)
#define IWL_DEBUG_AP(p, f, a...) IWL_DEBUG(p, IWL_DL_AP, f, ## a)
#define IWL_DEBUG_TXPOWER(p, f, a...) IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a)
-#define IWL_DEBUG_IO(p, f, a...) IWL_DEBUG(p, IWL_DL_IO, f, ## a)
#define IWL_DEBUG_RATE(p, f, a...) IWL_DEBUG(p, IWL_DL_RATE, f, ## a)
#define IWL_DEBUG_RATE_LIMIT(p, f, a...) \
IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 8842411f1cf..0e6a04b739a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -39,6 +39,7 @@
#include "iwl-debug.h"
#include "iwl-core.h"
#include "iwl-io.h"
+#include "iwl-agn.h"
/* create and remove of files */
#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
@@ -226,10 +227,10 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
/* default is to dump the entire data segment */
if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
priv->dbgfs_sram_offset = 0x800000;
- if (priv->ucode_type == UCODE_INIT)
- priv->dbgfs_sram_len = priv->ucode_init_data.len;
+ if (priv->ucode_type == UCODE_SUBTYPE_INIT)
+ priv->dbgfs_sram_len = priv->ucode_init.data.len;
else
- priv->dbgfs_sram_len = priv->ucode_data.len;
+ priv->dbgfs_sram_len = priv->ucode_rt.data.len;
}
len = priv->dbgfs_sram_len;
@@ -437,8 +438,7 @@ static ssize_t iwl_dbgfs_log_event_read(struct file *file,
int pos = 0;
ssize_t ret = -ENOMEM;
- ret = pos = priv->cfg->ops->lib->dump_nic_event_log(
- priv, true, &buf, true);
+ ret = pos = iwl_dump_nic_event_log(priv, true, &buf, true);
if (buf) {
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
kfree(buf);
@@ -462,8 +462,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file,
if (sscanf(buf, "%d", &event_log_flag) != 1)
return -EFAULT;
if (event_log_flag == 1)
- priv->cfg->ops->lib->dump_nic_event_log(priv, true,
- NULL, false);
+ iwl_dump_nic_event_log(priv, true, NULL, false);
return count;
}
@@ -1039,13 +1038,463 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
+static const char *fmt_value = " %-30s %10u\n";
+static const char *fmt_hex = " %-30s 0x%02X\n";
+static const char *fmt_table = " %-30s %10u %10u %10u %10u\n";
+static const char *fmt_header =
+ "%-32s current cumulative delta max\n";
+
+static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
+{
+ int p = 0;
+ u32 flag;
+
+ flag = le32_to_cpu(priv->statistics.flag);
+
+ p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
+ if (flag & UCODE_STATISTICS_CLEAR_MSK)
+ p += scnprintf(buf + p, bufsz - p,
+ "\tStatistics have been cleared\n");
+ p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
+ (flag & UCODE_STATISTICS_FREQUENCY_MSK)
+ ? "2.4 GHz" : "5.2 GHz");
+ p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
+ (flag & UCODE_STATISTICS_NARROW_BAND_MSK)
+ ? "enabled" : "disabled");
+
+ return p;
+}
+
static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
- return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file,
- user_buf, count, ppos);
+ int pos = 0;
+ char *buf;
+ int bufsz = sizeof(struct statistics_rx_phy) * 40 +
+ sizeof(struct statistics_rx_non_phy) * 40 +
+ sizeof(struct statistics_rx_ht_phy) * 40 + 400;
+ ssize_t ret;
+ struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
+ struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
+ struct statistics_rx_non_phy *general, *accum_general;
+ struct statistics_rx_non_phy *delta_general, *max_general;
+ struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
+
+ if (!iwl_is_alive(priv))
+ return -EAGAIN;
+
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ /*
+ * the statistic information display here is based on
+ * the last statistics notification from uCode
+ * might not reflect the current uCode activity
+ */
+ ofdm = &priv->statistics.rx_ofdm;
+ cck = &priv->statistics.rx_cck;
+ general = &priv->statistics.rx_non_phy;
+ ht = &priv->statistics.rx_ofdm_ht;
+ accum_ofdm = &priv->accum_stats.rx_ofdm;
+ accum_cck = &priv->accum_stats.rx_cck;
+ accum_general = &priv->accum_stats.rx_non_phy;
+ accum_ht = &priv->accum_stats.rx_ofdm_ht;
+ delta_ofdm = &priv->delta_stats.rx_ofdm;
+ delta_cck = &priv->delta_stats.rx_cck;
+ delta_general = &priv->delta_stats.rx_non_phy;
+ delta_ht = &priv->delta_stats.rx_ofdm_ht;
+ max_ofdm = &priv->max_delta_stats.rx_ofdm;
+ max_cck = &priv->max_delta_stats.rx_cck;
+ max_general = &priv->max_delta_stats.rx_non_phy;
+ max_ht = &priv->max_delta_stats.rx_ofdm_ht;
+
+ pos += iwl_statistics_flag(priv, buf, bufsz);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_Rx - OFDM:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "ina_cnt:",
+ le32_to_cpu(ofdm->ina_cnt),
+ accum_ofdm->ina_cnt,
+ delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_cnt:",
+ le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
+ delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "plcp_err:",
+ le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
+ delta_ofdm->plcp_err, max_ofdm->plcp_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_err:",
+ le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
+ delta_ofdm->crc32_err, max_ofdm->crc32_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "overrun_err:",
+ le32_to_cpu(ofdm->overrun_err),
+ accum_ofdm->overrun_err, delta_ofdm->overrun_err,
+ max_ofdm->overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "early_overrun_err:",
+ le32_to_cpu(ofdm->early_overrun_err),
+ accum_ofdm->early_overrun_err,
+ delta_ofdm->early_overrun_err,
+ max_ofdm->early_overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_good:",
+ le32_to_cpu(ofdm->crc32_good),
+ accum_ofdm->crc32_good, delta_ofdm->crc32_good,
+ max_ofdm->crc32_good);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "false_alarm_cnt:",
+ le32_to_cpu(ofdm->false_alarm_cnt),
+ accum_ofdm->false_alarm_cnt,
+ delta_ofdm->false_alarm_cnt,
+ max_ofdm->false_alarm_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_sync_err_cnt:",
+ le32_to_cpu(ofdm->fina_sync_err_cnt),
+ accum_ofdm->fina_sync_err_cnt,
+ delta_ofdm->fina_sync_err_cnt,
+ max_ofdm->fina_sync_err_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sfd_timeout:",
+ le32_to_cpu(ofdm->sfd_timeout),
+ accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout,
+ max_ofdm->sfd_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_timeout:",
+ le32_to_cpu(ofdm->fina_timeout),
+ accum_ofdm->fina_timeout, delta_ofdm->fina_timeout,
+ max_ofdm->fina_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "unresponded_rts:",
+ le32_to_cpu(ofdm->unresponded_rts),
+ accum_ofdm->unresponded_rts,
+ delta_ofdm->unresponded_rts,
+ max_ofdm->unresponded_rts);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "rxe_frame_lmt_ovrun:",
+ le32_to_cpu(ofdm->rxe_frame_limit_overrun),
+ accum_ofdm->rxe_frame_limit_overrun,
+ delta_ofdm->rxe_frame_limit_overrun,
+ max_ofdm->rxe_frame_limit_overrun);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_ack_cnt:",
+ le32_to_cpu(ofdm->sent_ack_cnt),
+ accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt,
+ max_ofdm->sent_ack_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_cts_cnt:",
+ le32_to_cpu(ofdm->sent_cts_cnt),
+ accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt,
+ max_ofdm->sent_cts_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_ba_rsp_cnt:",
+ le32_to_cpu(ofdm->sent_ba_rsp_cnt),
+ accum_ofdm->sent_ba_rsp_cnt,
+ delta_ofdm->sent_ba_rsp_cnt,
+ max_ofdm->sent_ba_rsp_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "dsp_self_kill:",
+ le32_to_cpu(ofdm->dsp_self_kill),
+ accum_ofdm->dsp_self_kill,
+ delta_ofdm->dsp_self_kill,
+ max_ofdm->dsp_self_kill);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "mh_format_err:",
+ le32_to_cpu(ofdm->mh_format_err),
+ accum_ofdm->mh_format_err,
+ delta_ofdm->mh_format_err,
+ max_ofdm->mh_format_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "re_acq_main_rssi_sum:",
+ le32_to_cpu(ofdm->re_acq_main_rssi_sum),
+ accum_ofdm->re_acq_main_rssi_sum,
+ delta_ofdm->re_acq_main_rssi_sum,
+ max_ofdm->re_acq_main_rssi_sum);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_Rx - CCK:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "ina_cnt:",
+ le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
+ delta_cck->ina_cnt, max_cck->ina_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_cnt:",
+ le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
+ delta_cck->fina_cnt, max_cck->fina_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "plcp_err:",
+ le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
+ delta_cck->plcp_err, max_cck->plcp_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_err:",
+ le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
+ delta_cck->crc32_err, max_cck->crc32_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "overrun_err:",
+ le32_to_cpu(cck->overrun_err),
+ accum_cck->overrun_err, delta_cck->overrun_err,
+ max_cck->overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "early_overrun_err:",
+ le32_to_cpu(cck->early_overrun_err),
+ accum_cck->early_overrun_err,
+ delta_cck->early_overrun_err,
+ max_cck->early_overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_good:",
+ le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
+ delta_cck->crc32_good, max_cck->crc32_good);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "false_alarm_cnt:",
+ le32_to_cpu(cck->false_alarm_cnt),
+ accum_cck->false_alarm_cnt,
+ delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_sync_err_cnt:",
+ le32_to_cpu(cck->fina_sync_err_cnt),
+ accum_cck->fina_sync_err_cnt,
+ delta_cck->fina_sync_err_cnt,
+ max_cck->fina_sync_err_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sfd_timeout:",
+ le32_to_cpu(cck->sfd_timeout),
+ accum_cck->sfd_timeout, delta_cck->sfd_timeout,
+ max_cck->sfd_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_timeout:",
+ le32_to_cpu(cck->fina_timeout),
+ accum_cck->fina_timeout, delta_cck->fina_timeout,
+ max_cck->fina_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "unresponded_rts:",
+ le32_to_cpu(cck->unresponded_rts),
+ accum_cck->unresponded_rts, delta_cck->unresponded_rts,
+ max_cck->unresponded_rts);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "rxe_frame_lmt_ovrun:",
+ le32_to_cpu(cck->rxe_frame_limit_overrun),
+ accum_cck->rxe_frame_limit_overrun,
+ delta_cck->rxe_frame_limit_overrun,
+ max_cck->rxe_frame_limit_overrun);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_ack_cnt:",
+ le32_to_cpu(cck->sent_ack_cnt),
+ accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt,
+ max_cck->sent_ack_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_cts_cnt:",
+ le32_to_cpu(cck->sent_cts_cnt),
+ accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt,
+ max_cck->sent_cts_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_ba_rsp_cnt:",
+ le32_to_cpu(cck->sent_ba_rsp_cnt),
+ accum_cck->sent_ba_rsp_cnt,
+ delta_cck->sent_ba_rsp_cnt,
+ max_cck->sent_ba_rsp_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "dsp_self_kill:",
+ le32_to_cpu(cck->dsp_self_kill),
+ accum_cck->dsp_self_kill, delta_cck->dsp_self_kill,
+ max_cck->dsp_self_kill);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "mh_format_err:",
+ le32_to_cpu(cck->mh_format_err),
+ accum_cck->mh_format_err, delta_cck->mh_format_err,
+ max_cck->mh_format_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "re_acq_main_rssi_sum:",
+ le32_to_cpu(cck->re_acq_main_rssi_sum),
+ accum_cck->re_acq_main_rssi_sum,
+ delta_cck->re_acq_main_rssi_sum,
+ max_cck->re_acq_main_rssi_sum);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_Rx - GENERAL:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "bogus_cts:",
+ le32_to_cpu(general->bogus_cts),
+ accum_general->bogus_cts, delta_general->bogus_cts,
+ max_general->bogus_cts);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "bogus_ack:",
+ le32_to_cpu(general->bogus_ack),
+ accum_general->bogus_ack, delta_general->bogus_ack,
+ max_general->bogus_ack);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "non_bssid_frames:",
+ le32_to_cpu(general->non_bssid_frames),
+ accum_general->non_bssid_frames,
+ delta_general->non_bssid_frames,
+ max_general->non_bssid_frames);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "filtered_frames:",
+ le32_to_cpu(general->filtered_frames),
+ accum_general->filtered_frames,
+ delta_general->filtered_frames,
+ max_general->filtered_frames);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "non_channel_beacons:",
+ le32_to_cpu(general->non_channel_beacons),
+ accum_general->non_channel_beacons,
+ delta_general->non_channel_beacons,
+ max_general->non_channel_beacons);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "channel_beacons:",
+ le32_to_cpu(general->channel_beacons),
+ accum_general->channel_beacons,
+ delta_general->channel_beacons,
+ max_general->channel_beacons);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "num_missed_bcon:",
+ le32_to_cpu(general->num_missed_bcon),
+ accum_general->num_missed_bcon,
+ delta_general->num_missed_bcon,
+ max_general->num_missed_bcon);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "adc_rx_saturation_time:",
+ le32_to_cpu(general->adc_rx_saturation_time),
+ accum_general->adc_rx_saturation_time,
+ delta_general->adc_rx_saturation_time,
+ max_general->adc_rx_saturation_time);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "ina_detect_search_tm:",
+ le32_to_cpu(general->ina_detection_search_time),
+ accum_general->ina_detection_search_time,
+ delta_general->ina_detection_search_time,
+ max_general->ina_detection_search_time);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_silence_rssi_a:",
+ le32_to_cpu(general->beacon_silence_rssi_a),
+ accum_general->beacon_silence_rssi_a,
+ delta_general->beacon_silence_rssi_a,
+ max_general->beacon_silence_rssi_a);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_silence_rssi_b:",
+ le32_to_cpu(general->beacon_silence_rssi_b),
+ accum_general->beacon_silence_rssi_b,
+ delta_general->beacon_silence_rssi_b,
+ max_general->beacon_silence_rssi_b);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_silence_rssi_c:",
+ le32_to_cpu(general->beacon_silence_rssi_c),
+ accum_general->beacon_silence_rssi_c,
+ delta_general->beacon_silence_rssi_c,
+ max_general->beacon_silence_rssi_c);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "interference_data_flag:",
+ le32_to_cpu(general->interference_data_flag),
+ accum_general->interference_data_flag,
+ delta_general->interference_data_flag,
+ max_general->interference_data_flag);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "channel_load:",
+ le32_to_cpu(general->channel_load),
+ accum_general->channel_load,
+ delta_general->channel_load,
+ max_general->channel_load);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "dsp_false_alarms:",
+ le32_to_cpu(general->dsp_false_alarms),
+ accum_general->dsp_false_alarms,
+ delta_general->dsp_false_alarms,
+ max_general->dsp_false_alarms);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_rssi_a:",
+ le32_to_cpu(general->beacon_rssi_a),
+ accum_general->beacon_rssi_a,
+ delta_general->beacon_rssi_a,
+ max_general->beacon_rssi_a);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_rssi_b:",
+ le32_to_cpu(general->beacon_rssi_b),
+ accum_general->beacon_rssi_b,
+ delta_general->beacon_rssi_b,
+ max_general->beacon_rssi_b);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_rssi_c:",
+ le32_to_cpu(general->beacon_rssi_c),
+ accum_general->beacon_rssi_c,
+ delta_general->beacon_rssi_c,
+ max_general->beacon_rssi_c);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_energy_a:",
+ le32_to_cpu(general->beacon_energy_a),
+ accum_general->beacon_energy_a,
+ delta_general->beacon_energy_a,
+ max_general->beacon_energy_a);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_energy_b:",
+ le32_to_cpu(general->beacon_energy_b),
+ accum_general->beacon_energy_b,
+ delta_general->beacon_energy_b,
+ max_general->beacon_energy_b);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_energy_c:",
+ le32_to_cpu(general->beacon_energy_c),
+ accum_general->beacon_energy_c,
+ delta_general->beacon_energy_c,
+ max_general->beacon_energy_c);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_Rx - OFDM_HT:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "plcp_err:",
+ le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
+ delta_ht->plcp_err, max_ht->plcp_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "overrun_err:",
+ le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
+ delta_ht->overrun_err, max_ht->overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "early_overrun_err:",
+ le32_to_cpu(ht->early_overrun_err),
+ accum_ht->early_overrun_err,
+ delta_ht->early_overrun_err,
+ max_ht->early_overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_good:",
+ le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
+ delta_ht->crc32_good, max_ht->crc32_good);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_err:",
+ le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
+ delta_ht->crc32_err, max_ht->crc32_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "mh_format_err:",
+ le32_to_cpu(ht->mh_format_err),
+ accum_ht->mh_format_err,
+ delta_ht->mh_format_err, max_ht->mh_format_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg_crc32_good:",
+ le32_to_cpu(ht->agg_crc32_good),
+ accum_ht->agg_crc32_good,
+ delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg_mpdu_cnt:",
+ le32_to_cpu(ht->agg_mpdu_cnt),
+ accum_ht->agg_mpdu_cnt,
+ delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg_cnt:",
+ le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
+ delta_ht->agg_cnt, max_ht->agg_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "unsupport_mcs:",
+ le32_to_cpu(ht->unsupport_mcs),
+ accum_ht->unsupport_mcs,
+ delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
}
static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
@@ -1053,8 +1502,190 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
- return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file,
- user_buf, count, ppos);
+ int pos = 0;
+ char *buf;
+ int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
+ ssize_t ret;
+ struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
+
+ if (!iwl_is_alive(priv))
+ return -EAGAIN;
+
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ /* the statistic information display here is based on
+ * the last statistics notification from uCode
+ * might not reflect the current uCode activity
+ */
+ tx = &priv->statistics.tx;
+ accum_tx = &priv->accum_stats.tx;
+ delta_tx = &priv->delta_stats.tx;
+ max_tx = &priv->max_delta_stats.tx;
+
+ pos += iwl_statistics_flag(priv, buf, bufsz);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_Tx:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "preamble:",
+ le32_to_cpu(tx->preamble_cnt),
+ accum_tx->preamble_cnt,
+ delta_tx->preamble_cnt, max_tx->preamble_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "rx_detected_cnt:",
+ le32_to_cpu(tx->rx_detected_cnt),
+ accum_tx->rx_detected_cnt,
+ delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "bt_prio_defer_cnt:",
+ le32_to_cpu(tx->bt_prio_defer_cnt),
+ accum_tx->bt_prio_defer_cnt,
+ delta_tx->bt_prio_defer_cnt,
+ max_tx->bt_prio_defer_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "bt_prio_kill_cnt:",
+ le32_to_cpu(tx->bt_prio_kill_cnt),
+ accum_tx->bt_prio_kill_cnt,
+ delta_tx->bt_prio_kill_cnt,
+ max_tx->bt_prio_kill_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "few_bytes_cnt:",
+ le32_to_cpu(tx->few_bytes_cnt),
+ accum_tx->few_bytes_cnt,
+ delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "cts_timeout:",
+ le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
+ delta_tx->cts_timeout, max_tx->cts_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "ack_timeout:",
+ le32_to_cpu(tx->ack_timeout),
+ accum_tx->ack_timeout,
+ delta_tx->ack_timeout, max_tx->ack_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "expected_ack_cnt:",
+ le32_to_cpu(tx->expected_ack_cnt),
+ accum_tx->expected_ack_cnt,
+ delta_tx->expected_ack_cnt,
+ max_tx->expected_ack_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "actual_ack_cnt:",
+ le32_to_cpu(tx->actual_ack_cnt),
+ accum_tx->actual_ack_cnt,
+ delta_tx->actual_ack_cnt,
+ max_tx->actual_ack_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "dump_msdu_cnt:",
+ le32_to_cpu(tx->dump_msdu_cnt),
+ accum_tx->dump_msdu_cnt,
+ delta_tx->dump_msdu_cnt,
+ max_tx->dump_msdu_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "abort_nxt_frame_mismatch:",
+ le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
+ accum_tx->burst_abort_next_frame_mismatch_cnt,
+ delta_tx->burst_abort_next_frame_mismatch_cnt,
+ max_tx->burst_abort_next_frame_mismatch_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "abort_missing_nxt_frame:",
+ le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
+ accum_tx->burst_abort_missing_next_frame_cnt,
+ delta_tx->burst_abort_missing_next_frame_cnt,
+ max_tx->burst_abort_missing_next_frame_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "cts_timeout_collision:",
+ le32_to_cpu(tx->cts_timeout_collision),
+ accum_tx->cts_timeout_collision,
+ delta_tx->cts_timeout_collision,
+ max_tx->cts_timeout_collision);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "ack_ba_timeout_collision:",
+ le32_to_cpu(tx->ack_or_ba_timeout_collision),
+ accum_tx->ack_or_ba_timeout_collision,
+ delta_tx->ack_or_ba_timeout_collision,
+ max_tx->ack_or_ba_timeout_collision);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg ba_timeout:",
+ le32_to_cpu(tx->agg.ba_timeout),
+ accum_tx->agg.ba_timeout,
+ delta_tx->agg.ba_timeout,
+ max_tx->agg.ba_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg ba_resched_frames:",
+ le32_to_cpu(tx->agg.ba_reschedule_frames),
+ accum_tx->agg.ba_reschedule_frames,
+ delta_tx->agg.ba_reschedule_frames,
+ max_tx->agg.ba_reschedule_frames);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg scd_query_agg_frame:",
+ le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
+ accum_tx->agg.scd_query_agg_frame_cnt,
+ delta_tx->agg.scd_query_agg_frame_cnt,
+ max_tx->agg.scd_query_agg_frame_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg scd_query_no_agg:",
+ le32_to_cpu(tx->agg.scd_query_no_agg),
+ accum_tx->agg.scd_query_no_agg,
+ delta_tx->agg.scd_query_no_agg,
+ max_tx->agg.scd_query_no_agg);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg scd_query_agg:",
+ le32_to_cpu(tx->agg.scd_query_agg),
+ accum_tx->agg.scd_query_agg,
+ delta_tx->agg.scd_query_agg,
+ max_tx->agg.scd_query_agg);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg scd_query_mismatch:",
+ le32_to_cpu(tx->agg.scd_query_mismatch),
+ accum_tx->agg.scd_query_mismatch,
+ delta_tx->agg.scd_query_mismatch,
+ max_tx->agg.scd_query_mismatch);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg frame_not_ready:",
+ le32_to_cpu(tx->agg.frame_not_ready),
+ accum_tx->agg.frame_not_ready,
+ delta_tx->agg.frame_not_ready,
+ max_tx->agg.frame_not_ready);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg underrun:",
+ le32_to_cpu(tx->agg.underrun),
+ accum_tx->agg.underrun,
+ delta_tx->agg.underrun, max_tx->agg.underrun);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg bt_prio_kill:",
+ le32_to_cpu(tx->agg.bt_prio_kill),
+ accum_tx->agg.bt_prio_kill,
+ delta_tx->agg.bt_prio_kill,
+ max_tx->agg.bt_prio_kill);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg rx_ba_rsp_cnt:",
+ le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
+ accum_tx->agg.rx_ba_rsp_cnt,
+ delta_tx->agg.rx_ba_rsp_cnt,
+ max_tx->agg.rx_ba_rsp_cnt);
+
+ if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "tx power: (1/2 dB step)\n");
+ if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_hex, "antenna A:",
+ tx->tx_power.ant_a);
+ if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_hex, "antenna B:",
+ tx->tx_power.ant_b);
+ if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_hex, "antenna C:",
+ tx->tx_power.ant_c);
+ }
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
}
static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
@@ -1062,8 +1693,347 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
- return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file,
- user_buf, count, ppos);
+ int pos = 0;
+ char *buf;
+ int bufsz = sizeof(struct statistics_general) * 10 + 300;
+ ssize_t ret;
+ struct statistics_general_common *general, *accum_general;
+ struct statistics_general_common *delta_general, *max_general;
+ struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
+ struct statistics_div *div, *accum_div, *delta_div, *max_div;
+
+ if (!iwl_is_alive(priv))
+ return -EAGAIN;
+
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ /* the statistic information display here is based on
+ * the last statistics notification from uCode
+ * might not reflect the current uCode activity
+ */
+ general = &priv->statistics.common;
+ dbg = &priv->statistics.common.dbg;
+ div = &priv->statistics.common.div;
+ accum_general = &priv->accum_stats.common;
+ accum_dbg = &priv->accum_stats.common.dbg;
+ accum_div = &priv->accum_stats.common.div;
+ delta_general = &priv->delta_stats.common;
+ max_general = &priv->max_delta_stats.common;
+ delta_dbg = &priv->delta_stats.common.dbg;
+ max_dbg = &priv->max_delta_stats.common.dbg;
+ delta_div = &priv->delta_stats.common.div;
+ max_div = &priv->max_delta_stats.common.div;
+
+ pos += iwl_statistics_flag(priv, buf, bufsz);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_General:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_value, "temperature:",
+ le32_to_cpu(general->temperature));
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_value, "temperature_m:",
+ le32_to_cpu(general->temperature_m));
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_value, "ttl_timestamp:",
+ le32_to_cpu(general->ttl_timestamp));
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "burst_check:",
+ le32_to_cpu(dbg->burst_check),
+ accum_dbg->burst_check,
+ delta_dbg->burst_check, max_dbg->burst_check);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "burst_count:",
+ le32_to_cpu(dbg->burst_count),
+ accum_dbg->burst_count,
+ delta_dbg->burst_count, max_dbg->burst_count);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "wait_for_silence_timeout_count:",
+ le32_to_cpu(dbg->wait_for_silence_timeout_cnt),
+ accum_dbg->wait_for_silence_timeout_cnt,
+ delta_dbg->wait_for_silence_timeout_cnt,
+ max_dbg->wait_for_silence_timeout_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sleep_time:",
+ le32_to_cpu(general->sleep_time),
+ accum_general->sleep_time,
+ delta_general->sleep_time, max_general->sleep_time);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "slots_out:",
+ le32_to_cpu(general->slots_out),
+ accum_general->slots_out,
+ delta_general->slots_out, max_general->slots_out);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "slots_idle:",
+ le32_to_cpu(general->slots_idle),
+ accum_general->slots_idle,
+ delta_general->slots_idle, max_general->slots_idle);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "tx_on_a:",
+ le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
+ delta_div->tx_on_a, max_div->tx_on_a);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "tx_on_b:",
+ le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
+ delta_div->tx_on_b, max_div->tx_on_b);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "exec_time:",
+ le32_to_cpu(div->exec_time), accum_div->exec_time,
+ delta_div->exec_time, max_div->exec_time);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "probe_time:",
+ le32_to_cpu(div->probe_time), accum_div->probe_time,
+ delta_div->probe_time, max_div->probe_time);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "rx_enable_counter:",
+ le32_to_cpu(general->rx_enable_counter),
+ accum_general->rx_enable_counter,
+ delta_general->rx_enable_counter,
+ max_general->rx_enable_counter);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "num_of_sos_states:",
+ le32_to_cpu(general->num_of_sos_states),
+ accum_general->num_of_sos_states,
+ delta_general->num_of_sos_states,
+ max_general->num_of_sos_states);
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
+}
+
+static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+ int pos = 0;
+ char *buf;
+ int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200;
+ ssize_t ret;
+ struct statistics_bt_activity *bt, *accum_bt;
+
+ if (!iwl_is_alive(priv))
+ return -EAGAIN;
+
+ if (!priv->bt_enable_flag)
+ return -EINVAL;
+
+ /* make request to uCode to retrieve statistics information */
+ mutex_lock(&priv->mutex);
+ ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
+ mutex_unlock(&priv->mutex);
+
+ if (ret) {
+ IWL_ERR(priv,
+ "Error sending statistics request: %zd\n", ret);
+ return -EAGAIN;
+ }
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ /*
+ * the statistic information display here is based on
+ * the last statistics notification from uCode
+ * might not reflect the current uCode activity
+ */
+ bt = &priv->statistics.bt_activity;
+ accum_bt = &priv->accum_stats.bt_activity;
+
+ pos += iwl_statistics_flag(priv, buf, bufsz);
+ pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\t\t\tcurrent\t\t\taccumulative\n");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->hi_priority_tx_req_cnt),
+ accum_bt->hi_priority_tx_req_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->hi_priority_tx_denied_cnt),
+ accum_bt->hi_priority_tx_denied_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->lo_priority_tx_req_cnt),
+ accum_bt->lo_priority_tx_req_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->lo_priority_tx_denied_cnt),
+ accum_bt->lo_priority_tx_denied_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->hi_priority_rx_req_cnt),
+ accum_bt->hi_priority_rx_req_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->hi_priority_rx_denied_cnt),
+ accum_bt->hi_priority_rx_denied_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->lo_priority_rx_req_cnt),
+ accum_bt->lo_priority_rx_req_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->lo_priority_rx_denied_cnt),
+ accum_bt->lo_priority_rx_denied_cnt);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "(rx)num_bt_kills:\t\t%u\t\t\t%u\n",
+ le32_to_cpu(priv->statistics.num_bt_kills),
+ priv->statistics.accum_num_bt_kills);
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
+}
+
+static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+ int pos = 0;
+ char *buf;
+ int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) +
+ (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200;
+ ssize_t ret;
+
+ if (!iwl_is_alive(priv))
+ return -EAGAIN;
+
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n");
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY),
+ priv->_agn.reply_tx_stats.pp_delay);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES),
+ priv->_agn.reply_tx_stats.pp_few_bytes);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO),
+ priv->_agn.reply_tx_stats.pp_bt_prio);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD),
+ priv->_agn.reply_tx_stats.pp_quiet_period);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK),
+ priv->_agn.reply_tx_stats.pp_calc_ttak);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_tx_fail_reason(
+ TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY),
+ priv->_agn.reply_tx_stats.int_crossed_retry);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT),
+ priv->_agn.reply_tx_stats.short_limit);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT),
+ priv->_agn.reply_tx_stats.long_limit);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN),
+ priv->_agn.reply_tx_stats.fifo_underrun);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW),
+ priv->_agn.reply_tx_stats.drain_flow);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH),
+ priv->_agn.reply_tx_stats.rfkill_flush);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE),
+ priv->_agn.reply_tx_stats.life_expire);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS),
+ priv->_agn.reply_tx_stats.dest_ps);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED),
+ priv->_agn.reply_tx_stats.host_abort);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY),
+ priv->_agn.reply_tx_stats.pp_delay);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID),
+ priv->_agn.reply_tx_stats.sta_invalid);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED),
+ priv->_agn.reply_tx_stats.frag_drop);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE),
+ priv->_agn.reply_tx_stats.tid_disable);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED),
+ priv->_agn.reply_tx_stats.fifo_flush);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_tx_fail_reason(
+ TX_STATUS_FAIL_INSUFFICIENT_CF_POLL),
+ priv->_agn.reply_tx_stats.insuff_cf_poll);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX),
+ priv->_agn.reply_tx_stats.fail_hw_drop);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_tx_fail_reason(
+ TX_STATUS_FAIL_NO_BEACON_ON_RADAR),
+ priv->_agn.reply_tx_stats.sta_color_mismatch);
+ pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
+ priv->_agn.reply_tx_stats.unknown);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\nStatistics_Agg_TX_Error:\n");
+
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK),
+ priv->_agn.reply_agg_tx_stats.underrun);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK),
+ priv->_agn.reply_agg_tx_stats.bt_prio);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK),
+ priv->_agn.reply_agg_tx_stats.few_bytes);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK),
+ priv->_agn.reply_agg_tx_stats.abort);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(
+ AGG_TX_STATE_LAST_SENT_TTL_MSK),
+ priv->_agn.reply_agg_tx_stats.last_sent_ttl);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(
+ AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK),
+ priv->_agn.reply_agg_tx_stats.last_sent_try);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(
+ AGG_TX_STATE_LAST_SENT_BT_KILL_MSK),
+ priv->_agn.reply_agg_tx_stats.last_sent_bt_kill);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK),
+ priv->_agn.reply_agg_tx_stats.scd_query);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(
+ AGG_TX_STATE_TEST_BAD_CRC32_MSK),
+ priv->_agn.reply_agg_tx_stats.bad_crc32);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK),
+ priv->_agn.reply_agg_tx_stats.response);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK),
+ priv->_agn.reply_agg_tx_stats.dump_tx);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK),
+ priv->_agn.reply_agg_tx_stats.delay_tx);
+ pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
+ priv->_agn.reply_agg_tx_stats.unknown);
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
}
static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
@@ -1268,8 +2238,7 @@ static ssize_t iwl_dbgfs_csr_write(struct file *file,
if (sscanf(buf, "%d", &csr) != 1)
return -EFAULT;
- if (priv->cfg->ops->lib->dump_csr)
- priv->cfg->ops->lib->dump_csr(priv);
+ iwl_dump_csr(priv);
return count;
}
@@ -1359,13 +2328,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
int pos = 0;
ssize_t ret = -EFAULT;
- if (priv->cfg->ops->lib->dump_fh) {
- ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true);
- if (buf) {
- ret = simple_read_from_buffer(user_buf,
- count, ppos, buf, pos);
- kfree(buf);
- }
+ ret = pos = iwl_dump_fh(priv, &buf, true);
+ if (buf) {
+ ret = simple_read_from_buffer(user_buf,
+ count, ppos, buf, pos);
+ kfree(buf);
}
return ret;
@@ -1531,16 +2498,6 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
return count;
}
-static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
-
- return priv->cfg->ops->lib->debugfs_ops.bt_stats_read(file,
- user_buf, count, ppos);
-}
-
static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos) {
@@ -1572,12 +2529,10 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
int pos = 0;
char buf[200];
const size_t bufsz = sizeof(buf);
- ssize_t ret;
if (!priv->bt_enable_flag) {
pos += scnprintf(buf + pos, bufsz - pos, "BT coex disabled\n");
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- return ret;
+ return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
pos += scnprintf(buf + pos, bufsz - pos, "BT enable flag: 0x%x\n",
priv->bt_enable_flag);
@@ -1608,8 +2563,7 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
break;
}
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- return ret;
+ return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
static ssize_t iwl_dbgfs_protection_mode_read(struct file *file,
@@ -1658,18 +2612,6 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
return count;
}
-static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = file->private_data;
-
- if (priv->cfg->ops->lib->debugfs_ops.reply_tx_error)
- return priv->cfg->ops->lib->debugfs_ops.reply_tx_error(
- file, user_buf, count, ppos);
- else
- return -ENODATA;
-}
DEBUGFS_READ_FILE_OPS(rx_statistics);
DEBUGFS_READ_FILE_OPS(tx_statistics);
DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1731,11 +2673,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
- if (!priv->cfg->base_params->broken_powersave) {
- DEBUGFS_ADD_FILE(sleep_level_override, dir_data,
- S_IWUSR | S_IRUSR);
- DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
- }
+ DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR);
+ DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
@@ -1758,29 +2697,20 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR);
- if (priv->cfg->base_params->sensitivity_calib_by_driver)
- DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
- if (priv->cfg->base_params->chain_noise_calib_by_driver)
- DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
- if (priv->cfg->base_params->ucode_tracing)
- DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
- if (iwl_bt_statistics(priv))
- DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
+ DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
+ DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
+ DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
+ DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
if (iwl_advanced_bt_coexist(priv))
DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
- if (priv->cfg->base_params->sensitivity_calib_by_driver)
- DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
- &priv->disable_sens_cal);
- if (priv->cfg->base_params->chain_noise_calib_by_driver)
- DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
- &priv->disable_chain_noise_cal);
- if (priv->cfg->base_params->tx_power_by_driver)
- DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
- &priv->disable_tx_power_cal);
+ DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
+ &priv->disable_sens_cal);
+ DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
+ &priv->disable_chain_noise_cal);
return 0;
err:
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 68b953f2bdc..214e4658c49 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -26,7 +26,6 @@
/*
* Please use this file (iwl-dev.h) for driver implementation definitions.
* Please use iwl-commands.h for uCode API definitions.
- * Please use iwl-4965-hw.h for hardware-related definitions.
*/
#ifndef __iwl_dev_h__
@@ -179,53 +178,12 @@ struct iwl_tx_queue {
#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;
-};
-
-#define IWL4965_MAX_RATE (33)
-
-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];
-};
-
-/* 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!
*/
struct iwl_channel_info {
- struct iwl4965_channel_tgd_info tgd;
- struct iwl4965_channel_tgh_info tgh;
struct iwl_eeprom_channel eeprom; /* EEPROM regulatory limit */
struct iwl_eeprom_channel ht40_eeprom; /* EEPROM regulatory limit for
* HT40 channel */
@@ -245,14 +203,6 @@ struct iwl_channel_info {
s8 ht40_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */
u8 ht40_flags; /* flags copied from EEPROM */
u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */
-
- /* 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];
};
#define IWL_TX_FIFO_BK 0 /* shared */
@@ -288,15 +238,6 @@ struct iwl_channel_info {
#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_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
@@ -309,6 +250,7 @@ enum {
CMD_SIZE_HUGE = (1 << 0),
CMD_ASYNC = (1 << 1),
CMD_WANT_SKB = (1 << 2),
+ CMD_MAPPED = (1 << 3),
};
#define DEF_CMD_PAYLOAD_SIZE 320
@@ -416,6 +358,7 @@ struct iwl_ht_agg {
#define IWL_EMPTYING_HW_QUEUE_ADDBA 2
#define IWL_EMPTYING_HW_QUEUE_DELBA 3
u8 state;
+ u8 tx_fifo;
};
@@ -499,9 +442,6 @@ struct iwl_station_priv_common {
* When mac80211 creates a station it reserves some space (hw->sta_data_size)
* in the structure for use by driver. This structure is places in that
* space.
- *
- * The common struct MUST be first because it is shared between
- * 3945 and agn!
*/
struct iwl_station_priv {
struct iwl_station_priv_common common;
@@ -530,6 +470,10 @@ struct fw_desc {
u32 len; /* bytes */
};
+struct fw_img {
+ struct fw_desc code, data;
+};
+
/* v1/v2 uCode file layout */
struct iwl_ucode_header {
__le32 ver; /* major/minor/API/serial */
@@ -586,6 +530,22 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13,
IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14,
IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15,
+ /* 16 and 17 reserved for future use */
+ IWL_UCODE_TLV_FLAGS = 18,
+};
+
+/**
+ * enum iwl_ucode_tlv_flag - ucode API flags
+ * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
+ * was a separate TLV but moved here to save space.
+ * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
+ * treats good CRC threshold as a boolean
+ * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
+ */
+enum iwl_ucode_tlv_flag {
+ IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
+ IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1),
+ IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
};
struct iwl_ucode_tlv {
@@ -619,14 +579,6 @@ struct iwl_tlv_ucode_header {
u8 data[0];
};
-struct iwl4965_ibss_seq {
- u8 mac[ETH_ALEN];
- u16 seq_num;
- u16 frag_num;
- unsigned long packet_time;
- struct list_head list;
-};
-
struct iwl_sensitivity_ranges {
u16 min_nrg_cck;
u16 max_nrg_cck;
@@ -700,7 +652,6 @@ struct iwl_hw_params {
u8 max_beacon_itrvl; /* in 1024 ms */
u32 max_inst_size;
u32 max_data_size;
- u32 max_bsm_size;
u32 ct_kill_threshold; /* value in hw-dependent units */
u32 ct_kill_exit_threshold; /* value in hw-dependent units */
/* for 1000, 6000 series and up */
@@ -722,8 +673,6 @@ struct iwl_hw_params {
* Naming convention --
* iwl_ <-- Is part of iwlwifi
* iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX)
- * iwl4965_bg_ <-- Called from work queue context
- * iwl4965_mac_ <-- mac80211 callback
*
****************************************************************************/
extern void iwl_update_chain_flags(struct iwl_priv *priv);
@@ -772,7 +721,6 @@ struct iwl_dma_ptr {
/* Sensitivity and chain noise calibration */
#define INITIALIZATION_VALUE 0xFFFF
-#define IWL4965_CAL_NUM_BEACONS 20
#define IWL_CAL_NUM_BEACONS 16
#define MAXIMUM_ALLOWED_PATHLOSS 15
@@ -806,24 +754,19 @@ struct iwl_dma_ptr {
#define NRG_NUM_PREV_STAT_L 20
#define NUM_RX_CHAINS 3
-enum iwl4965_false_alarm_state {
+enum iwlagn_false_alarm_state {
IWL_FA_TOO_MANY = 0,
IWL_FA_TOO_FEW = 1,
IWL_FA_GOOD_RANGE = 2,
};
-enum iwl4965_chain_noise_state {
+enum iwlagn_chain_noise_state {
IWL_CHAIN_NOISE_ALIVE = 0, /* must be 0 */
IWL_CHAIN_NOISE_ACCUMULATE,
IWL_CHAIN_NOISE_CALIBRATED,
IWL_CHAIN_NOISE_DONE,
};
-enum iwl4965_calib_enabled_state {
- IWL_CALIB_DISABLED = 0, /* must be 0 */
- IWL_CALIB_ENABLED = 1,
-};
-
/*
* enum iwl_calib
@@ -847,12 +790,6 @@ struct iwl_calib_result {
size_t buf_len;
};
-enum ucode_type {
- UCODE_NONE = 0,
- UCODE_INIT,
- UCODE_RT
-};
-
/* Sensitivity calib data */
struct iwl_sensitivity_data {
u32 auto_corr_ofdm;
@@ -1131,12 +1068,6 @@ struct iwl_force_reset {
/* extend beacon time format bit shifting */
/*
- * for _3945 devices
- * bits 31:24 - extended
- * bits 23:0 - interval
- */
-#define IWL3945_EXT_BEACON_TIME_POS 24
-/*
* for _agn devices
* bits 31:22 - extended
* bits 21:0 - interval
@@ -1164,10 +1095,12 @@ struct iwl_force_reset {
struct iwl_notification_wait {
struct list_head list;
- void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt);
+ void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt,
+ void *data);
+ void *fn_data;
u8 cmd;
- bool triggered;
+ bool triggered, aborted;
};
enum iwl_rxon_context_id {
@@ -1228,6 +1161,8 @@ struct iwl_rxon_context {
bool enabled, is_40mhz;
u8 extension_chan_offset;
} ht;
+
+ bool last_tx_rejected;
};
enum iwl_scan_type {
@@ -1244,13 +1179,10 @@ struct iwl_priv {
struct ieee80211_rate *ieee_rates;
struct iwl_cfg *cfg;
- /* temporary frame storage list */
- struct list_head free_frames;
- int frames_count;
-
enum ieee80211_band band;
- int alloc_rxb_page;
+ void (*pre_rx_handler)(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
@@ -1305,16 +1237,12 @@ struct iwl_priv {
spinlock_t hcmd_lock; /* protect hcmd */
spinlock_t reg_lock; /* protect hw register access */
struct mutex mutex;
- struct mutex sync_cmd_mutex; /* enable serialization of sync commands */
/* basic pci-network driver stuff */
struct pci_dev *pci_dev;
/* pci hardware address support */
void __iomem *hw_base;
- u32 hw_rev;
- u32 hw_wa_rev;
- u8 rev_id;
/* microcode/device supports multiple contexts */
u8 valid_contexts;
@@ -1325,6 +1253,8 @@ struct iwl_priv {
/* max number of station keys */
u8 sta_key_max_num;
+ bool new_scan_threshold_behaviour;
+
/* EEPROM MAC addresses */
struct mac_address addresses[2];
@@ -1332,13 +1262,10 @@ struct iwl_priv {
int fw_index; /* firmware we're trying to load */
u32 ucode_ver; /* version of ucode, copy of
iwl_ucode.ver */
- 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 */
- enum ucode_type ucode_type;
+ struct fw_img ucode_rt;
+ struct fw_img ucode_init;
+
+ enum iwlagn_ucode_subtype ucode_type;
u8 ucode_write_complete; /* the image write is complete */
char firmware_name[25];
@@ -1346,10 +1273,10 @@ struct iwl_priv {
struct iwl_switch_rxon switch_rxon;
- /* 1st responses from initialize and runtime uCode images.
- * _agn's initialize alive response contains some calibration data. */
- struct iwl_init_alive_resp card_alive_init;
- struct iwl_alive_resp card_alive;
+ struct {
+ u32 error_event_table;
+ u32 log_event_table;
+ } device_pointers;
u16 active_rate;
@@ -1390,15 +1317,12 @@ struct iwl_priv {
struct iwl_power_mgr power_data;
struct iwl_tt_mgmt thermal_throttle;
- /* context information */
- u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */
-
/* station table variables */
/* Note: if lock and sta_lock are needed, lock must be acquired first */
spinlock_t sta_lock;
int num_stations;
- struct iwl_station_entry stations[IWL_STATION_COUNT];
+ struct iwl_station_entry stations[IWLAGN_STATION_COUNT];
unsigned long ucode_key_table;
/* queue refcounts */
@@ -1422,101 +1346,81 @@ struct iwl_priv {
/* Last Rx'd beacon timestamp */
u64 timestamp;
- union {
-#if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE)
- struct {
- void *shared_virt;
- dma_addr_t shared_phys;
-
- struct delayed_work thermal_periodic;
- struct delayed_work rfkill_poll;
-
- struct iwl3945_notif_statistics statistics;
+ struct {
+ __le32 flag;
+ struct statistics_general_common common;
+ struct statistics_rx_non_phy rx_non_phy;
+ struct statistics_rx_phy rx_ofdm;
+ struct statistics_rx_ht_phy rx_ofdm_ht;
+ struct statistics_rx_phy rx_cck;
+ struct statistics_tx tx;
#ifdef CONFIG_IWLWIFI_DEBUGFS
- struct iwl3945_notif_statistics accum_statistics;
- struct iwl3945_notif_statistics delta_statistics;
- struct iwl3945_notif_statistics max_delta;
-#endif
-
- u32 sta_supp_rates;
- int last_rx_rssi; /* From Rx packet statistics */
-
- /* Rx'd packet timing information */
- u32 last_beacon_time;
- u64 last_tsf;
-
- /*
- * each calibration channel group in the
- * EEPROM has a derived clip setting for
- * each rate.
- */
- const struct iwl3945_clip_group clip_groups[5];
-
- } _3945;
+ struct statistics_bt_activity bt_activity;
+ __le32 num_bt_kills, accum_num_bt_kills;
#endif
-#if defined(CONFIG_IWLAGN) || defined(CONFIG_IWLAGN_MODULE)
- struct {
- /* INT ICT Table */
- __le32 *ict_tbl;
- void *ict_tbl_vir;
- dma_addr_t ict_tbl_dma;
- dma_addr_t aligned_ict_tbl_dma;
- int ict_index;
- u32 inta;
- bool use_ict;
- /*
- * reporting the number of tids has AGG on. 0 means
- * no AGGREGATION
- */
- u8 agg_tids_count;
-
- struct iwl_rx_phy_res last_phy_res;
- bool last_phy_res_valid;
-
- struct completion firmware_loading_complete;
-
- u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
- u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
-
- /*
- * chain noise reset and gain commands are the
- * two extra calibration commands follows the standard
- * phy calibration commands
- */
- u8 phy_calib_chain_noise_reset_cmd;
- u8 phy_calib_chain_noise_gain_cmd;
-
- struct iwl_notif_statistics statistics;
- struct iwl_bt_notif_statistics statistics_bt;
- /* counts reply_tx error */
- struct reply_tx_error_statistics reply_tx_stats;
- struct reply_agg_tx_error_statistics reply_agg_tx_stats;
+ } statistics;
#ifdef CONFIG_IWLWIFI_DEBUGFS
- struct iwl_notif_statistics accum_statistics;
- struct iwl_notif_statistics delta_statistics;
- struct iwl_notif_statistics max_delta;
- struct iwl_bt_notif_statistics accum_statistics_bt;
- struct iwl_bt_notif_statistics delta_statistics_bt;
- struct iwl_bt_notif_statistics max_delta_bt;
+ struct {
+ struct statistics_general_common common;
+ struct statistics_rx_non_phy rx_non_phy;
+ struct statistics_rx_phy rx_ofdm;
+ struct statistics_rx_ht_phy rx_ofdm_ht;
+ struct statistics_rx_phy rx_cck;
+ struct statistics_tx tx;
+ struct statistics_bt_activity bt_activity;
+ } accum_stats, delta_stats, max_delta_stats;
#endif
- /* notification wait support */
- struct list_head notif_waits;
- spinlock_t notif_wait_lock;
- wait_queue_head_t notif_waitq;
-
- /* remain-on-channel offload support */
- struct ieee80211_channel *hw_roc_channel;
- struct delayed_work hw_roc_work;
- enum nl80211_channel_type hw_roc_chantype;
- int hw_roc_duration;
-
- struct sk_buff *offchan_tx_skb;
- int offchan_tx_timeout;
- struct ieee80211_channel *offchan_tx_chan;
- } _agn;
-#endif
- };
+ struct {
+ /* INT ICT Table */
+ __le32 *ict_tbl;
+ void *ict_tbl_vir;
+ dma_addr_t ict_tbl_dma;
+ dma_addr_t aligned_ict_tbl_dma;
+ int ict_index;
+ u32 inta;
+ bool use_ict;
+ /*
+ * reporting the number of tids has AGG on. 0 means
+ * no AGGREGATION
+ */
+ u8 agg_tids_count;
+
+ struct iwl_rx_phy_res last_phy_res;
+ bool last_phy_res_valid;
+
+ struct completion firmware_loading_complete;
+
+ u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
+ u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
+
+ /*
+ * chain noise reset and gain commands are the
+ * two extra calibration commands follows the standard
+ * phy calibration commands
+ */
+ u8 phy_calib_chain_noise_reset_cmd;
+ u8 phy_calib_chain_noise_gain_cmd;
+
+ /* counts reply_tx error */
+ struct reply_tx_error_statistics reply_tx_stats;
+ struct reply_agg_tx_error_statistics reply_agg_tx_stats;
+ /* notification wait support */
+ struct list_head notif_waits;
+ spinlock_t notif_wait_lock;
+ wait_queue_head_t notif_waitq;
+
+ /* remain-on-channel offload support */
+ struct ieee80211_channel *hw_roc_channel;
+ struct delayed_work hw_roc_work;
+ enum nl80211_channel_type hw_roc_chantype;
+ int hw_roc_duration;
+ bool hw_roc_setup;
+
+ struct sk_buff *offchan_tx_skb;
+ int offchan_tx_timeout;
+ struct ieee80211_channel *offchan_tx_chan;
+ } _agn;
/* bt coex */
u8 bt_enable_flag;
@@ -1559,8 +1463,6 @@ struct iwl_priv {
struct tasklet_struct irq_tasklet;
- struct delayed_work init_alive_start;
- struct delayed_work alive_start;
struct delayed_work scan_check;
/* TX Power */
@@ -1589,12 +1491,10 @@ struct iwl_priv {
struct work_struct txpower_work;
u32 disable_sens_cal;
u32 disable_chain_noise_cal;
- u32 disable_tx_power_cal;
struct work_struct run_time_calib_work;
struct timer_list statistics_periodic;
struct timer_list ucode_trace;
struct timer_list watchdog;
- bool hw_ready;
struct iwl_event_log event_log;
@@ -1658,21 +1558,24 @@ iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif)
ctx < &priv->contexts[NUM_IWL_RXON_CTX]; ctx++) \
if (priv->valid_contexts & BIT(ctx->ctxid))
-static inline int iwl_is_associated(struct iwl_priv *priv,
- enum iwl_rxon_context_id ctxid)
+static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx)
{
- return (priv->contexts[ctxid].active.filter_flags &
- RXON_FILTER_ASSOC_MSK) ? 1 : 0;
+ return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
}
-static inline int iwl_is_any_associated(struct iwl_priv *priv)
+static inline int iwl_is_associated(struct iwl_priv *priv,
+ enum iwl_rxon_context_id ctxid)
{
- return iwl_is_associated(priv, IWL_RXON_CTX_BSS);
+ return iwl_is_associated_ctx(&priv->contexts[ctxid]);
}
-static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx)
+static inline int iwl_is_any_associated(struct iwl_priv *priv)
{
- return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
+ struct iwl_rxon_context *ctx;
+ for_each_context(priv, ctx)
+ if (iwl_is_associated_ctx(ctx))
+ return true;
+ return false;
}
static inline int is_channel_valid(const struct iwl_channel_info *ch_info)
@@ -1710,12 +1613,10 @@ static inline int is_channel_ibss(const struct iwl_channel_info *ch)
static inline void __iwl_free_pages(struct iwl_priv *priv, struct page *page)
{
__free_pages(page, priv->hw_params.rx_page_order);
- priv->alloc_rxb_page--;
}
static inline void iwl_free_pages(struct iwl_priv *priv, unsigned long page)
{
free_pages(page, priv->hw_params.rx_page_order);
- priv->alloc_rxb_page--;
}
#endif /* __iwl_dev_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index 4a487639d93..a635a7e7544 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2009 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009 - 2011 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
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 4cf864c664e..f00172cb8a6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2009 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009 - 2011 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
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 833194a2c63..c8397962632 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -142,6 +142,45 @@ static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */
*
******************************************************************************/
+/*
+ * 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.
+ */
+static int iwl_eeprom_acquire_semaphore(struct iwl_priv *priv)
+{
+ u16 count;
+ int ret;
+
+ for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
+ /* Request semaphore */
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+
+ /* See if we got it */
+ ret = iwl_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 (ret >= 0) {
+ IWL_DEBUG_EEPROM(priv,
+ "Acquired semaphore after %d tries.\n",
+ count+1);
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static void iwl_eeprom_release_semaphore(struct iwl_priv *priv)
+{
+ iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+
+}
+
static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
{
u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK;
@@ -188,18 +227,16 @@ static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode)
CSR_OTP_GP_REG_OTP_ACCESS_MODE);
}
-static int iwlcore_get_nvm_type(struct iwl_priv *priv)
+static int iwlcore_get_nvm_type(struct iwl_priv *priv, u32 hw_rev)
{
u32 otpgp;
int nvm_type;
/* OTP only valid for CP/PP and after */
- switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+ switch (hw_rev & CSR_HW_REV_TYPE_MSK) {
case CSR_HW_REV_TYPE_NONE:
IWL_ERR(priv, "Unknown hardware type\n");
return -ENOENT;
- case CSR_HW_REV_TYPE_3945:
- case CSR_HW_REV_TYPE_4965:
case CSR_HW_REV_TYPE_5300:
case CSR_HW_REV_TYPE_5350:
case CSR_HW_REV_TYPE_5100:
@@ -217,26 +254,20 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv)
return nvm_type;
}
-const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
-{
- BUG_ON(offset >= priv->cfg->base_params->eeprom_size);
- return &priv->eeprom[offset];
-}
-
static int iwl_init_otp_access(struct iwl_priv *priv)
{
int ret;
/* Enable 40MHz radio clock */
- _iwl_write32(priv, CSR_GP_CNTRL,
- _iwl_read32(priv, CSR_GP_CNTRL) |
- CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ iwl_write32(priv, CSR_GP_CNTRL,
+ iwl_read32(priv, CSR_GP_CNTRL) |
+ CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
/* wait for clock to be ready */
ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- 25000);
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+ 25000);
if (ret < 0)
IWL_ERR(priv, "Time out access OTP\n");
else {
@@ -263,17 +294,17 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_dat
u32 r;
u32 otpgp;
- _iwl_write32(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
+ iwl_write32(priv, CSR_EEPROM_REG,
+ CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
ret = iwl_poll_bit(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_READ_VALID_MSK,
- CSR_EEPROM_REG_READ_VALID_MSK,
- IWL_EEPROM_ACCESS_TIMEOUT);
+ CSR_EEPROM_REG_READ_VALID_MSK,
+ CSR_EEPROM_REG_READ_VALID_MSK,
+ IWL_EEPROM_ACCESS_TIMEOUT);
if (ret < 0) {
IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
return ret;
}
- r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
+ r = iwl_read32(priv, CSR_EEPROM_REG);
/* check for ECC errors: */
otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
@@ -396,7 +427,7 @@ u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
*
* NOTE: This routine uses the non-debug IO access functions.
*/
-int iwl_eeprom_init(struct iwl_priv *priv)
+int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
{
__le16 *e;
u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
@@ -406,7 +437,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
u16 validblockaddr = 0;
u16 cache_addr = 0;
- priv->nvm_device_type = iwlcore_get_nvm_type(priv);
+ priv->nvm_device_type = iwlcore_get_nvm_type(priv, hw_rev);
if (priv->nvm_device_type == -ENOENT)
return -ENOENT;
/* allocate eeprom */
@@ -429,7 +460,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
}
/* Make sure driver (instead of uCode) is allowed to read EEPROM */
- ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv);
+ ret = iwl_eeprom_acquire_semaphore(priv);
if (ret < 0) {
IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
ret = -ENOENT;
@@ -444,9 +475,9 @@ int iwl_eeprom_init(struct iwl_priv *priv)
ret = -ENOENT;
goto done;
}
- _iwl_write32(priv, CSR_EEPROM_GP,
- iwl_read32(priv, CSR_EEPROM_GP) &
- ~CSR_EEPROM_GP_IF_OWNER_MSK);
+ iwl_write32(priv, CSR_EEPROM_GP,
+ iwl_read32(priv, CSR_EEPROM_GP) &
+ ~CSR_EEPROM_GP_IF_OWNER_MSK);
iwl_set_bit(priv, CSR_OTP_GP_REG,
CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
@@ -473,8 +504,8 @@ int iwl_eeprom_init(struct iwl_priv *priv)
for (addr = 0; addr < sz; addr += sizeof(u16)) {
u32 r;
- _iwl_write32(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
+ iwl_write32(priv, CSR_EEPROM_REG,
+ CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
ret = iwl_poll_bit(priv, CSR_EEPROM_REG,
CSR_EEPROM_REG_READ_VALID_MSK,
@@ -484,7 +515,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
goto done;
}
- r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
+ r = iwl_read32(priv, CSR_EEPROM_REG);
e[addr / 2] = cpu_to_le16(r >> 16);
}
}
@@ -496,7 +527,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
ret = 0;
done:
- priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv);
+ iwl_eeprom_release_semaphore(priv);
err:
if (ret)
@@ -719,13 +750,6 @@ int iwl_init_channel_map(struct iwl_priv *priv)
flags & EEPROM_CHANNEL_RADAR))
? "" : "not ");
- /* Set the tx_power_user_lmt to the highest power
- * supported by any channel */
- if (eeprom_ch_info[ch].max_power_avg >
- priv->tx_power_user_lmt)
- priv->tx_power_user_lmt =
- eeprom_ch_info[ch].max_power_avg;
-
ch_info++;
}
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 20b66469d68..c960c6fa009 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -110,10 +110,6 @@ enum {
};
/* SKU Capabilities */
-/* 3945 only */
-#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0)
-#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1)
-
/* 5000 and up */
#define EEPROM_SKU_CAP_BAND_POS (4)
#define EEPROM_SKU_CAP_BAND_SELECTION \
@@ -168,28 +164,6 @@ struct iwl_eeprom_enhanced_txpwr {
s8 mimo3_max;
} __packed;
-/* 3945 Specific */
-#define EEPROM_3945_EEPROM_VERSION (0x2f)
-
-/* 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 Specific */
-/* 4965 driver does not work with txpower calibration version < 5 */
-#define EEPROM_4965_TX_POWER_VERSION (5)
-#define EEPROM_4965_EEPROM_VERSION (0x2f)
-#define EEPROM_4965_CALIB_VERSION_OFFSET (2*0xB6) /* 2 bytes */
-#define EEPROM_4965_CALIB_TXPOWER_OFFSET (2*0xE8) /* 48 bytes */
-#define EEPROM_4965_BOARD_REVISION (2*0x4F) /* 2 bytes */
-#define EEPROM_4965_BOARD_PBA (2*0x56+1) /* 9 bytes */
-
/* 5000 Specific */
#define EEPROM_5000_TX_POWER_VERSION (4)
#define EEPROM_5000_EEPROM_VERSION (0x11A)
@@ -282,90 +256,6 @@ struct iwl_eeprom_enhanced_txpwr {
/* 2.4 GHz */
extern const u8 iwl_eeprom_band_1[14];
-/*
- * 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 iwl_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) */
-} __packed;
-
-
-/*
- * 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 iwl_eeprom_calib_ch_info {
- u8 ch_num;
- struct iwl_eeprom_calib_measure
- measurements[EEPROM_TX_POWER_TX_CHAINS]
- [EEPROM_TX_POWER_MEASUREMENTS];
-} __packed;
-
-/*
- * 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 iwl_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 iwl_eeprom_calib_ch_info ch1;
- struct iwl_eeprom_calib_ch_info ch2;
-} __packed;
-
-
-/*
- * 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 iwl_eeprom_calib_subband_info contains range of channels
- * (0 if unused) for each set of data.
- */
-struct iwl_eeprom_calib_info {
- u8 saturation_power24; /* half-dBm (e.g. "34" = 17 dBm) */
- u8 saturation_power52; /* half-dBm */
- __le16 voltage; /* signed */
- struct iwl_eeprom_calib_subband_info
- band_info[EEPROM_TX_POWER_BANDS];
-} __packed;
-
-
#define ADDRESS_MSK 0x0000FFFF
#define INDIRECT_TYPE_MSK 0x000F0000
#define INDIRECT_HOST 0x00010000
@@ -398,103 +288,24 @@ struct iwl_eeprom_calib_info {
#define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */
#define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
-#define EEPROM_3945_RF_CFG_TYPE_MAX 0x0
-#define EEPROM_4965_RF_CFG_TYPE_MAX 0x1
-
-/* Radio Config for 5000 and up */
-#define EEPROM_RF_CONFIG_TYPE_R3x3 0x0
-#define EEPROM_RF_CONFIG_TYPE_R2x2 0x1
-#define EEPROM_RF_CONFIG_TYPE_R1x2 0x2
#define EEPROM_RF_CONFIG_TYPE_MAX 0x3
-/*
- * Per-channel regulatory data.
- *
- * Each channel that *might* be supported by iwl 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. HT40 (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_SKU_ID (2*0x60) /* 4 bytes */
-#define EEPROM_REGULATORY_BAND_1 (2*0x62) /* 2 bytes */
-#define EEPROM_REGULATORY_BAND_1_CHANNELS (2*0x63) /* 28 bytes */
-
-/*
- * 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 */
-#define EEPROM_REGULATORY_BAND_2_CHANNELS (2*0x72) /* 26 bytes */
-
-/*
- * 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 */
-#define EEPROM_REGULATORY_BAND_3_CHANNELS (2*0x80) /* 24 bytes */
-
-/*
- * 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 */
-#define EEPROM_REGULATORY_BAND_4_CHANNELS (2*0x8D) /* 22 bytes */
-
-/*
- * 5.7 GHz channels 145, 149, 153, 157, 161, 165
- * (5725-5825MHz)
- */
-#define EEPROM_REGULATORY_BAND_5 (2*0x98) /* 2 bytes */
-#define EEPROM_REGULATORY_BAND_5_CHANNELS (2*0x99) /* 12 bytes */
-
-/*
- * 2.4 GHz HT40 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 HT40 channel is centered 4 channels (20 MHz) away
- * from the lower half; e.g. the upper half of HT40 channel 1 is channel 5,
- * and the overall HT40 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 HT40 channel.
- *
- * NOTE: 4965 does not support HT40 channels on 2.4 GHz.
- */
-#define EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS (2*0xA0) /* 14 bytes */
-
-/*
- * 5.2 GHz HT40 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_4965_REGULATORY_BAND_52_HT40_CHANNELS (2*0xA8) /* 22 bytes */
-
#define EEPROM_REGULATORY_BAND_NO_HT40 (0)
struct iwl_eeprom_ops {
const u32 regulatory_bands[7];
- int (*acquire_semaphore) (struct iwl_priv *priv);
- void (*release_semaphore) (struct iwl_priv *priv);
- u16 (*calib_version) (struct iwl_priv *priv);
const u8* (*query_addr) (const struct iwl_priv *priv, size_t offset);
void (*update_enhanced_txpower) (struct iwl_priv *priv);
};
-int iwl_eeprom_init(struct iwl_priv *priv);
+int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev);
void iwl_eeprom_free(struct iwl_priv *priv);
int iwl_eeprom_check_version(struct iwl_priv *priv);
int iwl_eeprom_check_sku(struct iwl_priv *priv);
const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
int iwlcore_eeprom_verify_signature(struct iwl_priv *priv);
u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset);
-const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
int iwl_init_channel_map(struct iwl_priv *priv);
void iwl_free_channel_map(struct iwl_priv *priv);
const struct iwl_channel_info *iwl_get_channel_info(
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index 474009a244d..6dfa806aefe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -77,14 +77,14 @@
/**
* Keep-Warm (KW) buffer base address.
*
- * Driver must allocate a 4KByte buffer that is used by 4965 for keeping the
+ * Driver must allocate a 4KByte buffer that is 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
+ * DRAM access when doing 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 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
+ * of the buffer, which must be 4K aligned. Once this is set up, the device
* automatically invokes keep-warm accesses when normal accesses might not
* be sufficient to maintain fast DRAM response.
*
@@ -97,7 +97,7 @@
/**
* TFD Circular Buffers Base (CBBC) addresses
*
- * 4965 has 16 base pointer registers, one for each of 16 host-DRAM-resident
+ * Device 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
@@ -116,16 +116,16 @@
/**
* Rx SRAM Control and Status Registers (RSCSR)
*
- * These registers provide handshake between driver and 4965 for the Rx queue
+ * These registers provide handshake between driver and device 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
+ * sent from 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:
+ * physical address of each into device 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).
@@ -140,20 +140,20 @@
* 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
+ * 2) Rx status buffer, 8 bytes, in which uCode 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):
+ * by driver:
* 31-12: Not used by driver
* 11- 0: Index of last filled Rx buffer descriptor
- * (4965 writes, driver reads this value)
+ * (device writes, driver reads this value)
*
- * As the driver prepares Receive Buffers (RBs) for 4965 to fill, driver must
+ * As the driver prepares Receive Buffers (RBs) for device to fill, driver must
* enter pointers to these RBs into contiguous RBD circular buffer entries,
- * and update the 4965's "write" index register,
+ * and update the device's "write" index register,
* FH_RSCSR_CHNL0_RBDCB_WPTR_REG.
*
* This "write" index corresponds to the *next* RBD that the driver will make
@@ -162,12 +162,12 @@
* 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.
+ * NOTE: DEVICE EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8.
*
- * As the 4965 fills RBs (referenced from contiguous RBDs within the circular
+ * As the device 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.
+ * read this "read" index from DRAM after receiving an Rx interrupt from device
*
* 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
@@ -176,7 +176,7 @@
* 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.
+ * If read index == write index, device 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
@@ -303,7 +303,7 @@
/**
* Transmit DMA Channel Control/Status Registers (TCSR)
*
- * 4965 has one configuration register for each of 8 Tx DMA/FIFO channels
+ * Device 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.
*
@@ -326,7 +326,6 @@
#define FH_TCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xE60)
/* Find Control/Status reg for given Tx DMA/FIFO channel */
-#define FH49_TCSR_CHNL_NUM (7)
#define FH50_TCSR_CHNL_NUM (8)
/* TCSR: tx_config register values */
@@ -424,7 +423,6 @@
#define RX_LOW_WATERMARK 8
/* Size of one Rx buffer in host DRAM */
-#define IWL_RX_BUF_SIZE_3K (3 * 1000) /* 3945 only */
#define IWL_RX_BUF_SIZE_4K (4 * 1024)
#define IWL_RX_BUF_SIZE_8K (8 * 1024)
@@ -443,7 +441,7 @@ struct iwl_rb_status {
__le16 closed_fr_num;
__le16 finished_rb_num;
__le16 finished_fr_nam;
- __le32 __unused; /* 3945 only */
+ __le32 __unused;
} __packed;
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 02499f68468..8f0beb992cc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -51,9 +51,7 @@ const char *get_cmd_string(u8 cmd)
IWL_CMD(REPLY_REMOVE_ALL_STA);
IWL_CMD(REPLY_TXFIFO_FLUSH);
IWL_CMD(REPLY_WEPKEY);
- IWL_CMD(REPLY_3945_RX);
IWL_CMD(REPLY_TX);
- IWL_CMD(REPLY_RATE_SCALE);
IWL_CMD(REPLY_LEDS_CMD);
IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
IWL_CMD(COEX_PRIORITY_TABLE_CMD);
@@ -145,10 +143,12 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
{
int ret;
- BUG_ON(!(cmd->flags & CMD_ASYNC));
+ if (WARN_ON(!(cmd->flags & CMD_ASYNC)))
+ return -EINVAL;
/* An asynchronous command can not expect an SKB to be set. */
- BUG_ON(cmd->flags & CMD_WANT_SKB);
+ if (WARN_ON(cmd->flags & CMD_WANT_SKB))
+ return -EINVAL;
/* Assign a generic callback if one is not provided */
if (!cmd->callback)
@@ -171,14 +171,15 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
int cmd_idx;
int ret;
- BUG_ON(cmd->flags & CMD_ASYNC);
+ if (WARN_ON(cmd->flags & CMD_ASYNC))
+ return -EINVAL;
/* A synchronous command can not have a callback set. */
- BUG_ON(cmd->callback);
+ if (WARN_ON(cmd->callback))
+ return -EINVAL;
IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",
get_cmd_string(cmd->id));
- mutex_lock(&priv->sync_cmd_mutex);
set_bit(STATUS_HCMD_ACTIVE, &priv->status);
IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n",
@@ -189,7 +190,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
ret = cmd_idx;
IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
get_cmd_string(cmd->id), ret);
- goto out;
+ return ret;
}
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
@@ -229,8 +230,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
goto cancel;
}
- ret = 0;
- goto out;
+ return 0;
cancel:
if (cmd->flags & CMD_WANT_SKB) {
@@ -248,8 +248,7 @@ fail:
iwl_free_pages(priv, cmd->reply_page);
cmd->reply_page = 0;
}
-out:
- mutex_unlock(&priv->sync_cmd_mutex);
+
return ret;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 8821f088ba7..41207a3645b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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.
@@ -64,30 +64,6 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd)
return --index & (n_bd - 1);
}
-/* 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)
- dma_free_coherent(&pci_dev->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)
-{
- if (!desc->len) {
- desc->v_addr = NULL;
- return -EINVAL;
- }
-
- desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len,
- &desc->p_addr, GFP_KERNEL);
- return (desc->v_addr != NULL) ? 0 : -ENOMEM;
-}
-
/*
* we have 8 bits used like this:
*
@@ -131,6 +107,19 @@ static inline void iwl_stop_queue(struct iwl_priv *priv,
ieee80211_stop_queue(priv->hw, ac);
}
+static inline void iwl_wake_any_queue(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ u8 ac;
+
+ for (ac = 0; ac < AC_NUM; ac++) {
+ IWL_DEBUG_INFO(priv, "Queue Status: Q[%d] %s\n",
+ ac, (atomic_read(&priv->queue_stop_count[ac]) > 0)
+ ? "stopped" : "awake");
+ iwl_wake_queue(priv, &priv->txq[ctx->ac_to_queue[ac]]);
+ }
+}
+
#define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue
#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
new file mode 100644
index 00000000000..aa4a9067445
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -0,0 +1,294 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2011 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:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include "iwl-io.h"
+
+#define IWL_POLL_INTERVAL 10 /* microseconds */
+
+static inline void __iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+ iwl_write32(priv, reg, iwl_read32(priv, reg) | mask);
+}
+
+static inline void __iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+ iwl_write32(priv, reg, iwl_read32(priv, reg) & ~mask);
+}
+
+void iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ __iwl_set_bit(priv, reg, mask);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+void iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ __iwl_clear_bit(priv, reg, mask);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+int iwl_poll_bit(struct iwl_priv *priv, u32 addr,
+ u32 bits, u32 mask, int timeout)
+{
+ int t = 0;
+
+ do {
+ if ((iwl_read32(priv, addr) & mask) == (bits & mask))
+ return t;
+ udelay(IWL_POLL_INTERVAL);
+ t += IWL_POLL_INTERVAL;
+ } while (t < timeout);
+
+ return -ETIMEDOUT;
+}
+
+int iwl_grab_nic_access_silent(struct iwl_priv *priv)
+{
+ int ret;
+
+ lockdep_assert_held(&priv->reg_lock);
+
+ /* this bit wakes up the NIC */
+ __iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+
+ /*
+ * These bits say the device is running, and should keep running for
+ * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
+ * but they do not indicate that embedded SRAM is restored yet;
+ * 3945 and 4965 have volatile SRAM, and must save/restore contents
+ * to/from host DRAM when sleeping/waking for power-saving.
+ * Each direction takes approximately 1/4 millisecond; with this
+ * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
+ * series of register accesses are expected (e.g. reading Event Log),
+ * to keep device from sleeping.
+ *
+ * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
+ * SRAM is okay/restored. We don't check that here because this call
+ * is just for hardware register access; but GP1 MAC_SLEEP check is a
+ * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
+ *
+ * 5000 series and later (including 1000 series) have non-volatile SRAM,
+ * and do not save/restore SRAM when power cycling.
+ */
+ ret = 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), 15000);
+ if (ret < 0) {
+ iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int iwl_grab_nic_access(struct iwl_priv *priv)
+{
+ int ret = iwl_grab_nic_access_silent(priv);
+ if (ret) {
+ u32 val = iwl_read32(priv, CSR_GP_CNTRL);
+ IWL_ERR(priv,
+ "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
+ }
+
+ return ret;
+}
+
+void iwl_release_nic_access(struct iwl_priv *priv)
+{
+ lockdep_assert_held(&priv->reg_lock);
+ __iwl_clear_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+}
+
+u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
+{
+ u32 value;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ iwl_grab_nic_access(priv);
+ value = iwl_read32(priv, reg);
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+
+ return value;
+}
+
+void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ if (!iwl_grab_nic_access(priv)) {
+ iwl_write32(priv, reg, value);
+ iwl_release_nic_access(priv);
+ }
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask,
+ int timeout)
+{
+ int t = 0;
+
+ do {
+ if ((iwl_read_direct32(priv, addr) & mask) == mask)
+ return t;
+ udelay(IWL_POLL_INTERVAL);
+ t += IWL_POLL_INTERVAL;
+ } while (t < timeout);
+
+ return -ETIMEDOUT;
+}
+
+static inline u32 __iwl_read_prph(struct iwl_priv *priv, u32 reg)
+{
+ iwl_write32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
+ rmb();
+ return iwl_read32(priv, HBUS_TARG_PRPH_RDAT);
+}
+
+static inline void __iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
+{
+ iwl_write32(priv, HBUS_TARG_PRPH_WADDR,
+ ((addr & 0x0000FFFF) | (3 << 24)));
+ wmb();
+ iwl_write32(priv, HBUS_TARG_PRPH_WDAT, val);
+}
+
+u32 iwl_read_prph(struct iwl_priv *priv, u32 reg)
+{
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ iwl_grab_nic_access(priv);
+ val = __iwl_read_prph(priv, reg);
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+ return val;
+}
+
+void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ if (!iwl_grab_nic_access(priv)) {
+ __iwl_write_prph(priv, addr, val);
+ iwl_release_nic_access(priv);
+ }
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ iwl_grab_nic_access(priv);
+ __iwl_write_prph(priv, reg, __iwl_read_prph(priv, reg) | mask);
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
+ u32 bits, u32 mask)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ iwl_grab_nic_access(priv);
+ __iwl_write_prph(priv, reg,
+ (__iwl_read_prph(priv, reg) & mask) | bits);
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ iwl_grab_nic_access(priv);
+ val = __iwl_read_prph(priv, reg);
+ __iwl_write_prph(priv, reg, (val & ~mask));
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+void _iwl_read_targ_mem_words(struct iwl_priv *priv, u32 addr,
+ void *buf, int words)
+{
+ unsigned long flags;
+ int offs;
+ u32 *vals = buf;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ iwl_grab_nic_access(priv);
+
+ iwl_write32(priv, HBUS_TARG_MEM_RADDR, addr);
+ rmb();
+
+ for (offs = 0; offs < words; offs++)
+ vals[offs] = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
+
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
+{
+ u32 value;
+
+ _iwl_read_targ_mem_words(priv, addr, &value, 1);
+
+ return value;
+}
+
+void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ if (!iwl_grab_nic_access(priv)) {
+ iwl_write32(priv, HBUS_TARG_MEM_WADDR, addr);
+ wmb();
+ iwl_write32(priv, HBUS_TARG_MEM_WDAT, val);
+ iwl_release_nic_access(priv);
+ }
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 0203a3bbf87..869edc580ec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project.
*
@@ -35,494 +35,58 @@
#include "iwl-debug.h"
#include "iwl-devtrace.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 and caller function name are 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 name and __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_direct32 calls the non-check version of
- * _iwl_read32.)
- *
- * These declarations are *extremely* useful in quickly isolating code deltas
- * which result in misconfiguration 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.
- *
- */
-
-static inline void _iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val)
+static inline void iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val)
{
trace_iwlwifi_dev_iowrite8(priv, ofs, val);
iowrite8(val, priv->hw_base + ofs);
}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_write8(const char *f, u32 l, struct iwl_priv *priv,
- u32 ofs, u8 val)
-{
- IWL_DEBUG_IO(priv, "write8(0x%08X, 0x%02X) - %s %d\n", ofs, val, f, l);
- _iwl_write8(priv, ofs, val);
-}
-#define iwl_write8(priv, ofs, val) \
- __iwl_write8(__FILE__, __LINE__, priv, ofs, val)
-#else
-#define iwl_write8(priv, ofs, val) _iwl_write8(priv, ofs, val)
-#endif
-
-
-static inline void _iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val)
+static inline void iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val)
{
trace_iwlwifi_dev_iowrite32(priv, ofs, val);
iowrite32(val, priv->hw_base + ofs);
}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv,
- u32 ofs, u32 val)
-{
- IWL_DEBUG_IO(priv, "write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
- _iwl_write32(priv, ofs, val);
-}
-#define iwl_write32(priv, ofs, val) \
- __iwl_write32(__FILE__, __LINE__, priv, ofs, val)
-#else
-#define iwl_write32(priv, ofs, val) _iwl_write32(priv, ofs, val)
-#endif
-
-static inline u32 _iwl_read32(struct iwl_priv *priv, u32 ofs)
+static inline u32 iwl_read32(struct iwl_priv *priv, u32 ofs)
{
u32 val = ioread32(priv->hw_base + ofs);
trace_iwlwifi_dev_ioread32(priv, ofs, val);
return val;
}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs)
-{
- IWL_DEBUG_IO(priv, "read_direct32(0x%08X) - %s %d\n", ofs, f, l);
- return _iwl_read32(priv, ofs);
-}
-#define iwl_read32(priv, ofs) __iwl_read32(__FILE__, __LINE__, priv, ofs)
-#else
-#define iwl_read32(p, o) _iwl_read32(p, o)
-#endif
-
-#define IWL_POLL_INTERVAL 10 /* microseconds */
-static inline int _iwl_poll_bit(struct iwl_priv *priv, u32 addr,
- u32 bits, u32 mask, int timeout)
-{
- int t = 0;
-
- do {
- if ((_iwl_read32(priv, addr) & mask) == (bits & mask))
- return t;
- udelay(IWL_POLL_INTERVAL);
- t += IWL_POLL_INTERVAL;
- } while (t < 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 ret = _iwl_poll_bit(priv, addr, bits, mask, timeout);
- IWL_DEBUG_IO(priv, "poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
- addr, bits, mask,
- unlikely(ret == -ETIMEDOUT) ? "timeout" : "", f, l);
- return ret;
-}
-#define iwl_poll_bit(priv, addr, bits, mask, timeout) \
- __iwl_poll_bit(__FILE__, __LINE__, priv, 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(priv, "set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
- _iwl_write32(priv, reg, val);
-}
-static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&p->reg_lock, reg_flags);
- __iwl_set_bit(__FILE__, __LINE__, p, r, m);
- spin_unlock_irqrestore(&p->reg_lock, reg_flags);
-}
-#else
-static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&p->reg_lock, reg_flags);
- _iwl_set_bit(p, r, m);
- spin_unlock_irqrestore(&p->reg_lock, reg_flags);
-}
-#endif
-
-static inline void _iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
-{
- _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(priv, "clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
- _iwl_write32(priv, reg, val);
-}
-static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&p->reg_lock, reg_flags);
- __iwl_clear_bit(__FILE__, __LINE__, p, r, m);
- spin_unlock_irqrestore(&p->reg_lock, reg_flags);
-}
-#else
-static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&p->reg_lock, reg_flags);
- _iwl_clear_bit(p, r, m);
- spin_unlock_irqrestore(&p->reg_lock, reg_flags);
-}
-#endif
-
-static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
-{
- int ret;
- u32 val;
-
- /* this bit wakes up the NIC */
- _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-
- /*
- * These bits say the device is running, and should keep running for
- * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
- * but they do not indicate that embedded SRAM is restored yet;
- * 3945 and 4965 have volatile SRAM, and must save/restore contents
- * to/from host DRAM when sleeping/waking for power-saving.
- * Each direction takes approximately 1/4 millisecond; with this
- * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
- * series of register accesses are expected (e.g. reading Event Log),
- * to keep device from sleeping.
- *
- * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
- * SRAM is okay/restored. We don't check that here because this call
- * is just for hardware register access; but GP1 MAC_SLEEP check is a
- * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
- *
- * 5000 series and later (including 1000 series) have non-volatile SRAM,
- * and do not save/restore SRAM when power cycling.
- */
- ret = _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), 15000);
- if (ret < 0) {
- val = _iwl_read32(priv, CSR_GP_CNTRL);
- IWL_ERR(priv, "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
- _iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
- return -EIO;
- }
-
- return 0;
-}
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline int __iwl_grab_nic_access(const char *f, u32 l,
- struct iwl_priv *priv)
-{
- IWL_DEBUG_IO(priv, "grabbing nic access - %s %d\n", f, l);
- return _iwl_grab_nic_access(priv);
-}
-#define iwl_grab_nic_access(priv) \
- __iwl_grab_nic_access(__FILE__, __LINE__, priv)
-#else
-#define iwl_grab_nic_access(priv) \
- _iwl_grab_nic_access(priv)
-#endif
-
-static inline void _iwl_release_nic_access(struct iwl_priv *priv)
-{
- _iwl_clear_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_release_nic_access(const char *f, u32 l,
- struct iwl_priv *priv)
-{
-
- IWL_DEBUG_IO(priv, "releasing nic access - %s %d\n", f, l);
- _iwl_release_nic_access(priv);
-}
-#define iwl_release_nic_access(priv) \
- __iwl_release_nic_access(__FILE__, __LINE__, priv)
-#else
-#define iwl_release_nic_access(priv) \
- _iwl_release_nic_access(priv)
-#endif
-
-static inline u32 _iwl_read_direct32(struct iwl_priv *priv, u32 reg)
-{
- return _iwl_read32(priv, reg);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline u32 __iwl_read_direct32(const char *f, u32 l,
- struct iwl_priv *priv, u32 reg)
-{
- u32 value = _iwl_read_direct32(priv, reg);
- IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d\n", reg, value,
- f, l);
- return value;
-}
-static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
-{
- u32 value;
- unsigned long reg_flags;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- iwl_grab_nic_access(priv);
- value = __iwl_read_direct32(__FILE__, __LINE__, priv, reg);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
- return value;
-}
-
-#else
-static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
-{
- u32 value;
- unsigned long reg_flags;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- iwl_grab_nic_access(priv);
- value = _iwl_read_direct32(priv, reg);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
- return value;
-
-}
-#endif
-
-static inline void _iwl_write_direct32(struct iwl_priv *priv,
- u32 reg, u32 value)
-{
- _iwl_write32(priv, reg, value);
-}
-static inline void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- if (!iwl_grab_nic_access(priv)) {
- _iwl_write_direct32(priv, reg, value);
- iwl_release_nic_access(priv);
- }
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
-
-static inline void iwl_write_reg_buf(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_direct32(priv, reg, *values);
- }
-}
-
-static inline int _iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr,
- u32 mask, int timeout)
-{
- int t = 0;
-
- do {
- if ((iwl_read_direct32(priv, addr) & mask) == mask)
- return t;
- udelay(IWL_POLL_INTERVAL);
- t += IWL_POLL_INTERVAL;
- } while (t < timeout);
-
- return -ETIMEDOUT;
-}
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline int __iwl_poll_direct_bit(const char *f, u32 l,
- struct iwl_priv *priv,
- u32 addr, u32 mask, int timeout)
-{
- int ret = _iwl_poll_direct_bit(priv, addr, mask, timeout);
-
- if (unlikely(ret == -ETIMEDOUT))
- IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) - "
- "timedout - %s %d\n", addr, mask, f, l);
- else
- IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
- "- %s %d\n", addr, mask, ret, f, l);
- return ret;
-}
-#define iwl_poll_direct_bit(priv, addr, mask, timeout) \
- __iwl_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout)
-#else
-#define iwl_poll_direct_bit _iwl_poll_direct_bit
-#endif
-
-static inline u32 _iwl_read_prph(struct iwl_priv *priv, u32 reg)
-{
- _iwl_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
- rmb();
- return _iwl_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
-}
-static inline u32 iwl_read_prph(struct iwl_priv *priv, u32 reg)
-{
- unsigned long reg_flags;
- u32 val;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- iwl_grab_nic_access(priv);
- val = _iwl_read_prph(priv, reg);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
- return val;
-}
-
-static inline void _iwl_write_prph(struct iwl_priv *priv,
- u32 addr, u32 val)
-{
- _iwl_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
- ((addr & 0x0000FFFF) | (3 << 24)));
- wmb();
- _iwl_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
-}
-
-static inline void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- if (!iwl_grab_nic_access(priv)) {
- _iwl_write_prph(priv, addr, val);
- iwl_release_nic_access(priv);
- }
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
-
-#define _iwl_set_bits_prph(priv, reg, mask) \
- _iwl_write_prph(priv, reg, (_iwl_read_prph(priv, reg) | mask))
-
-static inline void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- iwl_grab_nic_access(priv);
- _iwl_set_bits_prph(priv, reg, mask);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
-
-#define _iwl_set_bits_mask_prph(priv, reg, bits, mask) \
- _iwl_write_prph(priv, reg, ((_iwl_read_prph(priv, reg) & mask) | bits))
+void iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask);
+void iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask);
-static inline void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
- u32 bits, u32 mask)
-{
- unsigned long reg_flags;
+int iwl_poll_bit(struct iwl_priv *priv, u32 addr,
+ u32 bits, u32 mask, int timeout);
+int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask,
+ int timeout);
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- iwl_grab_nic_access(priv);
- _iwl_set_bits_mask_prph(priv, reg, bits, mask);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
+int iwl_grab_nic_access_silent(struct iwl_priv *priv);
+int iwl_grab_nic_access(struct iwl_priv *priv);
+void iwl_release_nic_access(struct iwl_priv *priv);
-static inline void iwl_clear_bits_prph(struct iwl_priv
- *priv, u32 reg, u32 mask)
-{
- unsigned long reg_flags;
- u32 val;
+u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg);
+void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value);
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- iwl_grab_nic_access(priv);
- val = _iwl_read_prph(priv, reg);
- _iwl_write_prph(priv, reg, (val & ~mask));
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
-
-static inline u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
-{
- unsigned long reg_flags;
- u32 value;
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- iwl_grab_nic_access(priv);
+u32 iwl_read_prph(struct iwl_priv *priv, u32 reg);
+void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val);
+void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask);
+void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
+ u32 bits, u32 mask);
+void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask);
- _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
- rmb();
- value = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+void _iwl_read_targ_mem_words(struct iwl_priv *priv, u32 addr,
+ void *buf, int words);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
- return value;
-}
+#define iwl_read_targ_mem_words(priv, addr, buf, bufsize) \
+ do { \
+ BUILD_BUG_ON((bufsize) % sizeof(u32)); \
+ _iwl_read_targ_mem_words(priv, addr, buf, \
+ (bufsize) / sizeof(u32));\
+ } while (0)
-static inline void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- if (!iwl_grab_nic_access(priv)) {
- _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
- wmb();
- _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
- iwl_release_nic_access(priv);
- }
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
-
-static inline void iwl_write_targ_mem_buf(struct iwl_priv *priv, u32 addr,
- u32 len, u32 *values)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- if (!iwl_grab_nic_access(priv)) {
- _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
- wmb();
- for (; 0 < len; len -= sizeof(u32), values++)
- _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
-
- iwl_release_nic_access(priv);
- }
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
+u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr);
+void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val);
#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index d7f2a0bb32c..439187f903c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -48,8 +48,21 @@ module_param(led_mode, int, S_IRUGO);
MODULE_PARM_DESC(led_mode, "0=system default, "
"1=On(RF On)/Off(RF Off), 2=blinking");
+/* Throughput OFF time(ms) ON time (ms)
+ * >300 25 25
+ * >200 to 300 40 40
+ * >100 to 200 55 55
+ * >70 to 100 65 65
+ * >50 to 70 75 75
+ * >20 to 50 85 85
+ * >10 to 20 95 95
+ * >5 to 10 110 110
+ * >1 to 5 130 130
+ * >0 to 1 167 167
+ * <=0 SOLID ON
+ */
static const struct ieee80211_tpt_blink iwl_blink[] = {
- { .throughput = 0 * 1024 - 1, .blink_time = 334 },
+ { .throughput = 0, .blink_time = 334 },
{ .throughput = 1 * 1024 - 1, .blink_time = 260 },
{ .throughput = 5 * 1024 - 1, .blink_time = 220 },
{ .throughput = 10 * 1024 - 1, .blink_time = 190 },
@@ -61,10 +74,16 @@ static const struct ieee80211_tpt_blink iwl_blink[] = {
{ .throughput = 300 * 1024 - 1, .blink_time = 50 },
};
+/* Set led register off */
+void iwlagn_led_enable(struct iwl_priv *priv)
+{
+ iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
+}
+
/*
* Adjust led blink rate to compensate on a MAC Clock difference on every HW
- * Led blink rate analysis showed an average deviation of 0% on 3945,
- * 5% on 4965 HW and 20% on 5000 series and up.
+ * Led blink rate analysis showed an average deviation of 20% on 5000 series
+ * and up.
* Need to compensate on the led on/off time per HW according to the deviation
* to achieve the desired led frequency
* The calculation is: (100-averageDeviation)/100 * blinkTime
@@ -84,6 +103,24 @@ static inline u8 iwl_blink_compensation(struct iwl_priv *priv,
return (u8)((time * compensation) >> 6);
}
+static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
+{
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_LEDS_CMD,
+ .len = sizeof(struct iwl_led_cmd),
+ .data = led_cmd,
+ .flags = CMD_ASYNC,
+ .callback = NULL,
+ };
+ u32 reg;
+
+ reg = iwl_read32(priv, CSR_LED_REG);
+ if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
+ iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
+
+ return iwl_send_cmd(priv, &cmd);
+}
+
/* Set led pattern command */
static int iwl_led_cmd(struct iwl_priv *priv,
unsigned long on,
@@ -101,6 +138,11 @@ static int iwl_led_cmd(struct iwl_priv *priv,
if (priv->blink_on == on && priv->blink_off == off)
return 0;
+ if (off == 0) {
+ /* led is SOLID_ON */
+ on = IWL_LED_SOLID;
+ }
+
IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n",
priv->cfg->base_params->led_compensation);
led_cmd.on = iwl_blink_compensation(priv, on,
@@ -108,7 +150,7 @@ static int iwl_led_cmd(struct iwl_priv *priv,
led_cmd.off = iwl_blink_compensation(priv, off,
priv->cfg->base_params->led_compensation);
- ret = priv->cfg->ops->led->cmd(priv, &led_cmd);
+ ret = iwl_send_led_cmd(priv, &led_cmd);
if (!ret) {
priv->blink_on = on;
priv->blink_off = off;
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index 101eef12b3b..1c93dfef693 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -50,6 +50,7 @@ enum iwl_led_mode {
IWL_LED_BLINK,
};
+void iwlagn_led_enable(struct iwl_priv *priv);
void iwl_leds_init(struct iwl_priv *priv);
void iwl_leds_exit(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 576795e2c75..595c930b28a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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.
@@ -188,9 +188,10 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
table = range_0;
}
- BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM);
-
- *cmd = table[lvl].cmd;
+ if (WARN_ON(lvl < 0 || lvl >= IWL_POWER_NUM))
+ memset(cmd, 0, sizeof(*cmd));
+ else
+ *cmd = table[lvl].cmd;
if (period == 0) {
skip = 0;
@@ -354,16 +355,12 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
dtimper = priv->hw->conf.ps_dtim_period ?: 1;
- if (priv->cfg->base_params->broken_powersave)
- iwl_power_sleep_cam_cmd(priv, cmd);
- else if (priv->hw->conf.flags & IEEE80211_CONF_IDLE)
+ if (priv->hw->conf.flags & IEEE80211_CONF_IDLE)
iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20);
- else if (priv->cfg->ops->lib->tt_ops.lower_power_detection &&
- priv->cfg->ops->lib->tt_ops.tt_power_mode &&
- priv->cfg->ops->lib->tt_ops.lower_power_detection(priv)) {
+ else if (iwl_tt_is_low_power_state(priv)) {
/* in thermal throttling low power state */
iwl_static_sleep_cmd(priv, cmd,
- priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), dtimper);
+ iwl_tt_current_power_mode(priv), dtimper);
} else if (!enabled)
iwl_power_sleep_cam_cmd(priv, cmd);
else if (priv->power_data.debug_sleep_level_override >= 0)
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index fe012032c28..59635d784e2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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.
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 86f5123bccd..f00d188b2cf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -91,7 +91,6 @@
#define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000)
#define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000)
#define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN (0x00000000)
-#define APMG_PS_CTRL_VAL_PWR_SRC_MAX (0x01000000) /* 3945 only */
#define APMG_PS_CTRL_VAL_PWR_SRC_VAUX (0x02000000)
#define APMG_SVR_VOLTAGE_CONFIG_BIT_MSK (0x000001E0) /* bit 8:5 */
#define APMG_SVR_DIGITAL_VOLTAGE_1_32 (0x00000060)
@@ -99,152 +98,6 @@
#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
/**
- * BSM (Bootstrap State Machine)
- *
- * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program
- * in special SRAM that does not power down when the embedded control
- * processor is sleeping (e.g. for periodic power-saving shutdowns of radio).
- *
- * When powering back up after sleeps (or during initial uCode load), the BSM
- * internally loads the short bootstrap program from the special SRAM into the
- * embedded processor's instruction SRAM, and starts the processor so it runs
- * the bootstrap program.
- *
- * This bootstrap program loads (via PCI busmaster DMA) instructions and data
- * images for a uCode program from host DRAM locations. The host driver
- * indicates DRAM locations and sizes for instruction and data images via the
- * four BSM_DRAM_* registers. Once the bootstrap program loads the new program,
- * the new program starts automatically.
- *
- * The uCode used for open-source drivers includes two programs:
- *
- * 1) Initialization -- performs hardware calibration and sets up some
- * internal data, then notifies host via "initialize alive" notification
- * (struct iwl_init_alive_resp) that it has completed all of its work.
- * After signal from host, it then loads and starts the runtime program.
- * The initialization program must be used when initially setting up the
- * NIC after loading the driver.
- *
- * 2) Runtime/Protocol -- performs all normal runtime operations. This
- * notifies host via "alive" notification (struct iwl_alive_resp) that it
- * is ready to be used.
- *
- * When initializing the NIC, the host driver does the following procedure:
- *
- * 1) Load bootstrap program (instructions only, no data image for bootstrap)
- * into bootstrap memory. Use dword writes starting at BSM_SRAM_LOWER_BOUND
- *
- * 2) Point (via BSM_DRAM_*) to the "initialize" uCode data and instruction
- * images in host DRAM.
- *
- * 3) Set up BSM to copy from BSM SRAM into uCode instruction SRAM when asked:
- * BSM_WR_MEM_SRC_REG = 0
- * BSM_WR_MEM_DST_REG = RTC_INST_LOWER_BOUND
- * BSM_WR_MEM_DWCOUNT_REG = # dwords in bootstrap instruction image
- *
- * 4) Load bootstrap into instruction SRAM:
- * BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START
- *
- * 5) Wait for load completion:
- * Poll BSM_WR_CTRL_REG for BSM_WR_CTRL_REG_BIT_START = 0
- *
- * 6) Enable future boot loads whenever NIC's power management triggers it:
- * BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START_EN
- *
- * 7) Start the NIC by removing all reset bits:
- * CSR_RESET = 0
- *
- * The bootstrap uCode (already in instruction SRAM) loads initialization
- * uCode. Initialization uCode performs data initialization, sends
- * "initialize alive" notification to host, and waits for a signal from
- * host to load runtime code.
- *
- * 4) Point (via BSM_DRAM_*) to the "runtime" uCode data and instruction
- * images in host DRAM. The last register loaded must be the instruction
- * byte count register ("1" in MSbit tells initialization uCode to load
- * the runtime uCode):
- * BSM_DRAM_INST_BYTECOUNT_REG = byte count | BSM_DRAM_INST_LOAD
- *
- * 5) Wait for "alive" notification, then issue normal runtime commands.
- *
- * Data caching during power-downs:
- *
- * Just before the embedded controller powers down (e.g for automatic
- * power-saving modes, or for RFKILL), uCode stores (via PCI busmaster DMA)
- * a current snapshot of the embedded processor's data SRAM into host DRAM.
- * This caches the data while the embedded processor's memory is powered down.
- * Location and size are controlled by BSM_DRAM_DATA_* registers.
- *
- * NOTE: Instruction SRAM does not need to be saved, since that doesn't
- * change during operation; the original image (from uCode distribution
- * file) can be used for reload.
- *
- * When powering back up, the BSM loads the bootstrap program. Bootstrap looks
- * at the BSM_DRAM_* registers, which now point to the runtime instruction
- * image and the cached (modified) runtime data (*not* the initialization
- * uCode). Bootstrap reloads these runtime images into SRAM, and restarts the
- * uCode from where it left off before the power-down.
- *
- * NOTE: Initialization uCode does *not* run as part of the save/restore
- * procedure.
- *
- * This save/restore method is mostly for autonomous power management during
- * normal operation (result of POWER_TABLE_CMD). Platform suspend/resume and
- * RFKILL should use complete restarts (with total re-initialization) of uCode,
- * allowing total shutdown (including BSM memory).
- *
- * Note that, during normal operation, the host DRAM that held the initial
- * startup data for the runtime code is now being used as a backup data cache
- * for modified data! If you need to completely re-initialize the NIC, make
- * sure that you use the runtime data image from the uCode distribution file,
- * not the modified/saved runtime data. You may want to store a separate
- * "clean" runtime data image in DRAM to avoid disk reads of distribution file.
- */
-
-/* BSM bit fields */
-#define BSM_WR_CTRL_REG_BIT_START (0x80000000) /* start boot load now */
-#define BSM_WR_CTRL_REG_BIT_START_EN (0x40000000) /* enable boot after pwrup*/
-#define BSM_DRAM_INST_LOAD (0x80000000) /* start program load now */
-
-/* BSM addresses */
-#define BSM_BASE (PRPH_BASE + 0x3400)
-#define BSM_END (PRPH_BASE + 0x3800)
-
-#define BSM_WR_CTRL_REG (BSM_BASE + 0x000) /* ctl and status */
-#define BSM_WR_MEM_SRC_REG (BSM_BASE + 0x004) /* source in BSM mem */
-#define BSM_WR_MEM_DST_REG (BSM_BASE + 0x008) /* dest in SRAM mem */
-#define BSM_WR_DWCOUNT_REG (BSM_BASE + 0x00C) /* bytes */
-#define BSM_WR_STATUS_REG (BSM_BASE + 0x010) /* bit 0: 1 == done */
-
-/*
- * Pointers and size regs for bootstrap load and data SRAM save/restore.
- * NOTE: 3945 pointers use bits 31:0 of DRAM address.
- * 4965 pointers use bits 35:4 of DRAM address.
- */
-#define BSM_DRAM_INST_PTR_REG (BSM_BASE + 0x090)
-#define BSM_DRAM_INST_BYTECOUNT_REG (BSM_BASE + 0x094)
-#define BSM_DRAM_DATA_PTR_REG (BSM_BASE + 0x098)
-#define BSM_DRAM_DATA_BYTECOUNT_REG (BSM_BASE + 0x09C)
-
-/*
- * BSM special memory, stays powered on during power-save sleeps.
- * Read/write, address range from LOWER_BOUND to (LOWER_BOUND + SIZE -1)
- */
-#define BSM_SRAM_LOWER_BOUND (PRPH_BASE + 0x3800)
-#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)
-
-/**
* Tx Scheduler
*
* The Tx Scheduler selects the next frame to be transmitted, choosing TFDs
@@ -254,17 +107,7 @@
* 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 FIFOs have dedicated purposes. For 4965, they are used as follows
- * (cf. default_queue_to_tx_fifo in iwl-4965.c):
- *
- * 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 -- unused (HCCA)
- * 6 -- unused (HCCA)
- * 7 -- not used by driver (device-internal only)
+ * Tx DMA FIFOs have dedicated purposes.
*
* For 5000 series and up, they are used differently
* (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c):
@@ -298,7 +141,7 @@
* 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.
+ * 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.
@@ -311,7 +154,7 @@
*
* Driver controls scheduler operation via 3 means:
* 1) Scheduler registers
- * 2) Shared scheduler data base in internal 4956 SRAM
+ * 2) Shared scheduler data base in internal SRAM
* 3) Shared data in host DRAM
*
* Initialization:
@@ -330,201 +173,10 @@
* 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
- * IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) values.
*/
#define SCD_WIN_SIZE 64
#define SCD_FRAME_LIMIT 64
-/* SCD registers are internal, must be accessed via HBUS_TARG_PRPH regs */
-#define IWL49_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 IWL49_SCD_SRAM_BASE_ADDR (IWL49_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 IWL49_SCD_EMPTY_BITS (IWL49_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 IWL49_SCD_DRAM_BASE_ADDR (IWL49_SCD_START_OFFSET + 0x10)
-
-/*
- * 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 IWL49_SCD_TXFACT (IWL49_SCD_START_OFFSET + 0x1c)
-/*
- * 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 IWL49_SCD_QUEUE_WRPTR(x) (IWL49_SCD_START_OFFSET + 0x24 + (x) * 4)
-
-/*
- * 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 IWL49_SCD_QUEUE_RDPTR(x) (IWL49_SCD_START_OFFSET + 0x64 + (x) * 4)
-
-/*
- * 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 IWL49_SCD_QUEUECHAIN_SEL (IWL49_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 IWL49_SCD_INTERRUPT_MASK (IWL49_SCD_START_OFFSET + 0xe4)
-
-/*
- * 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 IWL49_SCD_QUEUE_STATUS_BITS(x)\
- (IWL49_SCD_START_OFFSET + 0x104 + (x) * 4)
-
-/* Bit field positions */
-#define IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE (0)
-#define IWL49_SCD_QUEUE_STTS_REG_POS_TXF (1)
-#define IWL49_SCD_QUEUE_STTS_REG_POS_WSL (5)
-#define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK (8)
-
-/* Write masks */
-#define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (10)
-#define IWL49_SCD_QUEUE_STTS_REG_MSK (0x0007FC00)
-
-/**
- * 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 IWL49_SCD_CONTEXT_DATA_OFFSET 0x380
-#define IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) \
- (IWL49_SCD_CONTEXT_DATA_OFFSET + ((x) * 8))
-
-#define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS (0)
-#define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK (0x0000007F)
-#define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)
-#define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000)
-
-/*
- * 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 IWL49_SCD_TX_STTS_BITMAP_OFFSET 0x400
-
-/*
- * 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 IWL49_SCD_TRANSLATE_TBL_OFFSET 0x500
-
-/* Find translation table dword to read/write for given queue */
-#define IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
- ((IWL49_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffffffc)
-
#define IWL_SCD_TXFIFO_POS_TID (0)
#define IWL_SCD_TXFIFO_POS_RA (4)
#define IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF)
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 6f9a2fa0476..0053e9ea902 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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.
@@ -225,55 +225,6 @@ err_bd:
*
******************************************************************************/
-static void iwl_rx_reply_alive(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
-{
- struct iwl_rx_packet *pkt = rxb_addr(rxb);
- struct iwl_alive_resp *palive;
- struct delayed_work *pwork;
-
- palive = &pkt->u.alive_frame;
-
- IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
- "0x%01X 0x%01X\n",
- palive->is_valid, palive->ver_type,
- palive->ver_subtype);
-
- if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
- IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
- memcpy(&priv->card_alive_init,
- &pkt->u.alive_frame,
- sizeof(struct iwl_init_alive_resp));
- pwork = &priv->init_alive_start;
- } else {
- IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
- memcpy(&priv->card_alive, &pkt->u.alive_frame,
- sizeof(struct iwl_alive_resp));
- pwork = &priv->alive_start;
- }
-
- /* We delay the ALIVE response by 5ms to
- * give the HW RF Kill time to activate... */
- if (palive->is_valid == UCODE_VALID_OK)
- queue_delayed_work(priv->workqueue, pwork,
- msecs_to_jiffies(5));
- else {
- IWL_WARN(priv, "%s uCode did not respond OK.\n",
- (palive->ver_subtype == INITIALIZE_SUBTYPE) ?
- "init" : "runtime");
- /*
- * If fail to load init uCode,
- * let's try to load the init uCode again.
- * We should not get into this situation, but if it
- * does happen, we should not move on and loading "runtime"
- * without proper calibrate the device.
- */
- if (palive->ver_subtype == INITIALIZE_SUBTYPE)
- priv->ucode_type = UCODE_NONE;
- queue_work(priv->workqueue, &priv->restart);
- }
-}
-
static void iwl_rx_reply_error(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
@@ -390,21 +341,16 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv,
* the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
* operation state.
*/
-static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt)
+static bool iwl_good_ack_health(struct iwl_priv *priv,
+ struct statistics_tx *cur)
{
int actual_delta, expected_delta, ba_timeout_delta;
- struct statistics_tx *cur, *old;
+ struct statistics_tx *old;
if (priv->_agn.agg_tids_count)
return true;
- if (iwl_bt_statistics(priv)) {
- cur = &pkt->u.stats_bt.tx;
- old = &priv->_agn.statistics_bt.tx;
- } else {
- cur = &pkt->u.stats.tx;
- old = &priv->_agn.statistics.tx;
- }
+ old = &priv->statistics.tx;
actual_delta = le32_to_cpu(cur->actual_ack_cnt) -
le32_to_cpu(old->actual_ack_cnt);
@@ -430,10 +376,10 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt
* DEBUG is not, these will just compile out.
*/
IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n",
- priv->_agn.delta_statistics.tx.rx_detected_cnt);
+ priv->delta_stats.tx.rx_detected_cnt);
IWL_DEBUG_RADIO(priv,
"ack_or_ba_timeout_collision delta %d\n",
- priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision);
+ priv->delta_stats.tx.ack_or_ba_timeout_collision);
#endif
if (ba_timeout_delta >= BA_TIMEOUT_MAX)
@@ -450,7 +396,9 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt
* to improve the throughput.
*/
static bool iwl_good_plcp_health(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt, unsigned int msecs)
+ struct statistics_rx_phy *cur_ofdm,
+ struct statistics_rx_ht_phy *cur_ofdm_ht,
+ unsigned int msecs)
{
int delta;
int threshold = priv->cfg->base_params->plcp_delta_threshold;
@@ -460,29 +408,12 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv,
return true;
}
- if (iwl_bt_statistics(priv)) {
- struct statistics_rx_bt *cur, *old;
-
- cur = &pkt->u.stats_bt.rx;
- old = &priv->_agn.statistics_bt.rx;
+ delta = le32_to_cpu(cur_ofdm->plcp_err) -
+ le32_to_cpu(priv->statistics.rx_ofdm.plcp_err) +
+ le32_to_cpu(cur_ofdm_ht->plcp_err) -
+ le32_to_cpu(priv->statistics.rx_ofdm_ht.plcp_err);
- delta = le32_to_cpu(cur->ofdm.plcp_err) -
- le32_to_cpu(old->ofdm.plcp_err) +
- le32_to_cpu(cur->ofdm_ht.plcp_err) -
- le32_to_cpu(old->ofdm_ht.plcp_err);
- } else {
- struct statistics_rx *cur, *old;
-
- cur = &pkt->u.stats.rx;
- old = &priv->_agn.statistics.rx;
-
- delta = le32_to_cpu(cur->ofdm.plcp_err) -
- le32_to_cpu(old->ofdm.plcp_err) +
- le32_to_cpu(cur->ofdm_ht.plcp_err) -
- le32_to_cpu(old->ofdm_ht.plcp_err);
- }
-
- /* Can be negative if firmware reseted statistics */
+ /* Can be negative if firmware reset statistics */
if (delta <= 0)
return true;
@@ -497,44 +428,35 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv,
}
static void iwl_recover_from_statistics(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt)
+ struct statistics_rx_phy *cur_ofdm,
+ struct statistics_rx_ht_phy *cur_ofdm_ht,
+ struct statistics_tx *tx,
+ unsigned long stamp)
{
- const struct iwl_mod_params *mod_params = priv->cfg->mod_params;
unsigned int msecs;
- unsigned long stamp;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- stamp = jiffies;
msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies);
/* Only gather statistics and update time stamp when not associated */
if (!iwl_is_any_associated(priv))
- goto out;
+ return;
/* Do not check/recover when do not have enough statistics data */
if (msecs < 99)
return;
- if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) {
+ if (iwlagn_mod_params.ack_check && !iwl_good_ack_health(priv, tx)) {
IWL_ERR(priv, "low ack count detected, restart firmware\n");
if (!iwl_force_reset(priv, IWL_FW_RESET, false))
return;
}
- if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt, msecs))
+ if (iwlagn_mod_params.plcp_check &&
+ !iwl_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
iwl_force_reset(priv, IWL_RF_RESET, false);
-
-out:
- if (iwl_bt_statistics(priv))
- memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt,
- sizeof(priv->_agn.statistics_bt));
- else
- memcpy(&priv->_agn.statistics, &pkt->u.stats,
- sizeof(priv->_agn.statistics));
-
- priv->rx_statistics_jiffies = stamp;
}
/* Calculate noise level, based on measurements during network silence just
@@ -548,10 +470,8 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
int bcn_silence_a, bcn_silence_b, bcn_silence_c;
int last_rx_noise;
- if (iwl_bt_statistics(priv))
- rx_info = &(priv->_agn.statistics_bt.rx.general.common);
- else
- rx_info = &(priv->_agn.statistics.rx.general);
+ rx_info = &priv->statistics.rx_non_phy;
+
bcn_silence_a =
le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
bcn_silence_b =
@@ -583,105 +503,153 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
last_rx_noise);
}
+#ifdef CONFIG_IWLWIFI_DEBUGFS
/*
* based on the assumption of all statistics counter are in DWORD
* FIXME: This function is for debugging, do not deal with
* the case of counters roll-over.
*/
-static void iwl_accumulative_statistics(struct iwl_priv *priv,
- __le32 *stats)
+static void accum_stats(__le32 *prev, __le32 *cur, __le32 *delta,
+ __le32 *max_delta, __le32 *accum, int size)
{
-#ifdef CONFIG_IWLWIFI_DEBUGFS
- int i, size;
- __le32 *prev_stats;
- u32 *accum_stats;
- u32 *delta, *max_delta;
- struct statistics_general_common *general, *accum_general;
- struct statistics_tx *tx, *accum_tx;
-
- if (iwl_bt_statistics(priv)) {
- prev_stats = (__le32 *)&priv->_agn.statistics_bt;
- accum_stats = (u32 *)&priv->_agn.accum_statistics_bt;
- size = sizeof(struct iwl_bt_notif_statistics);
- general = &priv->_agn.statistics_bt.general.common;
- accum_general = &priv->_agn.accum_statistics_bt.general.common;
- tx = &priv->_agn.statistics_bt.tx;
- accum_tx = &priv->_agn.accum_statistics_bt.tx;
- delta = (u32 *)&priv->_agn.delta_statistics_bt;
- max_delta = (u32 *)&priv->_agn.max_delta_bt;
- } else {
- prev_stats = (__le32 *)&priv->_agn.statistics;
- accum_stats = (u32 *)&priv->_agn.accum_statistics;
- size = sizeof(struct iwl_notif_statistics);
- general = &priv->_agn.statistics.general.common;
- accum_general = &priv->_agn.accum_statistics.general.common;
- tx = &priv->_agn.statistics.tx;
- accum_tx = &priv->_agn.accum_statistics.tx;
- delta = (u32 *)&priv->_agn.delta_statistics;
- max_delta = (u32 *)&priv->_agn.max_delta;
- }
- for (i = sizeof(__le32); i < size;
- i += sizeof(__le32), stats++, prev_stats++, delta++,
- max_delta++, accum_stats++) {
- if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
- *delta = (le32_to_cpu(*stats) -
- le32_to_cpu(*prev_stats));
- *accum_stats += *delta;
- if (*delta > *max_delta)
+ int i;
+
+ for (i = 0;
+ i < size / sizeof(__le32);
+ i++, prev++, cur++, delta++, max_delta++, accum++) {
+ if (le32_to_cpu(*cur) > le32_to_cpu(*prev)) {
+ *delta = cpu_to_le32(
+ le32_to_cpu(*cur) - le32_to_cpu(*prev));
+ le32_add_cpu(accum, le32_to_cpu(*delta));
+ if (le32_to_cpu(*delta) > le32_to_cpu(*max_delta))
*max_delta = *delta;
}
}
+}
- /* reset accumulative statistics for "no-counter" type statistics */
- accum_general->temperature = general->temperature;
- accum_general->temperature_m = general->temperature_m;
- accum_general->ttl_timestamp = general->ttl_timestamp;
- accum_tx->tx_power.ant_a = tx->tx_power.ant_a;
- accum_tx->tx_power.ant_b = tx->tx_power.ant_b;
- accum_tx->tx_power.ant_c = tx->tx_power.ant_c;
-#endif
+static void
+iwl_accumulative_statistics(struct iwl_priv *priv,
+ struct statistics_general_common *common,
+ struct statistics_rx_non_phy *rx_non_phy,
+ struct statistics_rx_phy *rx_ofdm,
+ struct statistics_rx_ht_phy *rx_ofdm_ht,
+ struct statistics_rx_phy *rx_cck,
+ struct statistics_tx *tx,
+ struct statistics_bt_activity *bt_activity)
+{
+#define ACCUM(_name) \
+ accum_stats((__le32 *)&priv->statistics._name, \
+ (__le32 *)_name, \
+ (__le32 *)&priv->delta_stats._name, \
+ (__le32 *)&priv->max_delta_stats._name, \
+ (__le32 *)&priv->accum_stats._name, \
+ sizeof(*_name));
+
+ ACCUM(common);
+ ACCUM(rx_non_phy);
+ ACCUM(rx_ofdm);
+ ACCUM(rx_ofdm_ht);
+ ACCUM(rx_cck);
+ ACCUM(tx);
+ if (bt_activity)
+ ACCUM(bt_activity);
+#undef ACCUM
+}
+#else
+static inline void
+iwl_accumulative_statistics(struct iwl_priv *priv,
+ struct statistics_general_common *common,
+ struct statistics_rx_non_phy *rx_non_phy,
+ struct statistics_rx_phy *rx_ofdm,
+ struct statistics_rx_ht_phy *rx_ofdm_ht,
+ struct statistics_rx_phy *rx_cck,
+ struct statistics_tx *tx,
+ struct statistics_bt_activity *bt_activity)
+{
}
+#endif
static void iwl_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
+ unsigned long stamp = jiffies;
const int reg_recalib_period = 60;
int change;
struct iwl_rx_packet *pkt = rxb_addr(rxb);
+ u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+ __le32 *flag;
+ struct statistics_general_common *common;
+ struct statistics_rx_non_phy *rx_non_phy;
+ struct statistics_rx_phy *rx_ofdm;
+ struct statistics_rx_ht_phy *rx_ofdm_ht;
+ struct statistics_rx_phy *rx_cck;
+ struct statistics_tx *tx;
+ struct statistics_bt_activity *bt_activity;
+
+ len -= sizeof(struct iwl_cmd_header); /* skip header */
+
+ IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n",
+ len);
+
+ if (len == sizeof(struct iwl_bt_notif_statistics)) {
+ struct iwl_bt_notif_statistics *stats;
+ stats = &pkt->u.stats_bt;
+ flag = &stats->flag;
+ common = &stats->general.common;
+ rx_non_phy = &stats->rx.general.common;
+ rx_ofdm = &stats->rx.ofdm;
+ rx_ofdm_ht = &stats->rx.ofdm_ht;
+ rx_cck = &stats->rx.cck;
+ tx = &stats->tx;
+ bt_activity = &stats->general.activity;
- if (iwl_bt_statistics(priv)) {
- IWL_DEBUG_RX(priv,
- "Statistics notification received (%d vs %d).\n",
- (int)sizeof(struct iwl_bt_notif_statistics),
- le32_to_cpu(pkt->len_n_flags) &
- FH_RSCSR_FRAME_SIZE_MSK);
-
- change = ((priv->_agn.statistics_bt.general.common.temperature !=
- pkt->u.stats_bt.general.common.temperature) ||
- ((priv->_agn.statistics_bt.flag &
- STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
- (pkt->u.stats_bt.flag &
- STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
-
- iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt);
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+ /* handle this exception directly */
+ priv->statistics.num_bt_kills = stats->rx.general.num_bt_kills;
+ le32_add_cpu(&priv->statistics.accum_num_bt_kills,
+ le32_to_cpu(stats->rx.general.num_bt_kills));
+#endif
+ } else if (len == sizeof(struct iwl_notif_statistics)) {
+ struct iwl_notif_statistics *stats;
+ stats = &pkt->u.stats;
+ flag = &stats->flag;
+ common = &stats->general.common;
+ rx_non_phy = &stats->rx.general;
+ rx_ofdm = &stats->rx.ofdm;
+ rx_ofdm_ht = &stats->rx.ofdm_ht;
+ rx_cck = &stats->rx.cck;
+ tx = &stats->tx;
+ bt_activity = NULL;
} else {
- IWL_DEBUG_RX(priv,
- "Statistics notification received (%d vs %d).\n",
- (int)sizeof(struct iwl_notif_statistics),
- le32_to_cpu(pkt->len_n_flags) &
- FH_RSCSR_FRAME_SIZE_MSK);
-
- change = ((priv->_agn.statistics.general.common.temperature !=
- pkt->u.stats.general.common.temperature) ||
- ((priv->_agn.statistics.flag &
- STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
- (pkt->u.stats.flag &
- STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
-
- iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
+ WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n",
+ len, sizeof(struct iwl_bt_notif_statistics),
+ sizeof(struct iwl_notif_statistics));
+ return;
}
- iwl_recover_from_statistics(priv, pkt);
+ change = common->temperature != priv->statistics.common.temperature ||
+ (*flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
+ (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK);
+
+ iwl_accumulative_statistics(priv, common, rx_non_phy, rx_ofdm,
+ rx_ofdm_ht, rx_cck, tx, bt_activity);
+
+ iwl_recover_from_statistics(priv, rx_ofdm, rx_ofdm_ht, tx, stamp);
+
+ priv->statistics.flag = *flag;
+ memcpy(&priv->statistics.common, common, sizeof(*common));
+ memcpy(&priv->statistics.rx_non_phy, rx_non_phy, sizeof(*rx_non_phy));
+ memcpy(&priv->statistics.rx_ofdm, rx_ofdm, sizeof(*rx_ofdm));
+ memcpy(&priv->statistics.rx_ofdm_ht, rx_ofdm_ht, sizeof(*rx_ofdm_ht));
+ memcpy(&priv->statistics.rx_cck, rx_cck, sizeof(*rx_cck));
+ memcpy(&priv->statistics.tx, tx, sizeof(*tx));
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+ if (bt_activity)
+ memcpy(&priv->statistics.bt_activity, bt_activity,
+ sizeof(*bt_activity));
+#endif
+
+ priv->rx_statistics_jiffies = stamp;
set_bit(STATUS_STATISTICS, &priv->status);
@@ -708,18 +676,12 @@ static void iwl_rx_reply_statistics(struct iwl_priv *priv,
if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
#ifdef CONFIG_IWLWIFI_DEBUGFS
- memset(&priv->_agn.accum_statistics, 0,
- sizeof(struct iwl_notif_statistics));
- memset(&priv->_agn.delta_statistics, 0,
- sizeof(struct iwl_notif_statistics));
- memset(&priv->_agn.max_delta, 0,
- sizeof(struct iwl_notif_statistics));
- memset(&priv->_agn.accum_statistics_bt, 0,
- sizeof(struct iwl_bt_notif_statistics));
- memset(&priv->_agn.delta_statistics_bt, 0,
- sizeof(struct iwl_bt_notif_statistics));
- memset(&priv->_agn.max_delta_bt, 0,
- sizeof(struct iwl_bt_notif_statistics));
+ memset(&priv->accum_stats, 0,
+ sizeof(priv->accum_stats));
+ memset(&priv->delta_stats, 0,
+ sizeof(priv->delta_stats));
+ memset(&priv->max_delta_stats, 0,
+ sizeof(priv->max_delta_stats));
#endif
IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
}
@@ -873,6 +835,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
{
struct sk_buff *skb;
__le16 fc = hdr->frame_control;
+ struct iwl_rxon_context *ctx;
/* We only process data packets if the interface is open */
if (unlikely(!priv->is_open)) {
@@ -882,7 +845,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
}
/* In case of HW accelerated crypto and bad decryption, drop */
- if (!priv->cfg->mod_params->sw_crypto &&
+ if (!iwlagn_mod_params.sw_crypto &&
iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
return;
@@ -895,10 +858,29 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
iwl_update_stats(priv, false, fc, len);
+
+ /*
+ * Wake any queues that were stopped due to a passive channel tx
+ * failure. This can happen because the regulatory enforcement in
+ * the device waits for a beacon before allowing transmission,
+ * sometimes even after already having transmitted frames for the
+ * association because the new RXON may reset the information.
+ */
+ if (unlikely(ieee80211_is_beacon(fc))) {
+ for_each_context(priv, ctx) {
+ if (!ctx->last_tx_rejected)
+ continue;
+ if (compare_ether_addr(hdr->addr3,
+ ctx->active.bssid_addr))
+ continue;
+ ctx->last_tx_rejected = false;
+ iwl_wake_any_queue(priv, ctx);
+ }
+ }
+
memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
ieee80211_rx(priv->hw, skb);
- priv->alloc_rxb_page--;
rxb->page = NULL;
}
@@ -1093,7 +1075,6 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
handlers = priv->rx_handlers;
- handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
handlers[REPLY_ERROR] = iwl_rx_reply_error;
handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
handlers[SPECTRUM_MEASURE_NOTIFICATION] = iwl_rx_spectrum_measure_notif;
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 914c77e4458..d60d630cb93 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
deleted file mode 100644
index c4ca0b5d77d..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ieee80211 subsystem header files.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl_spectrum_h__
-#define __iwl_spectrum_h__
-enum { /* ieee80211_basic_report.map */
- IEEE80211_BASIC_MAP_BSS = (1 << 0),
- IEEE80211_BASIC_MAP_OFDM = (1 << 1),
- IEEE80211_BASIC_MAP_UNIDENTIFIED = (1 << 2),
- IEEE80211_BASIC_MAP_RADAR = (1 << 3),
- IEEE80211_BASIC_MAP_UNMEASURED = (1 << 4),
- /* Bits 5-7 are reserved */
-
-};
-struct ieee80211_basic_report {
- u8 channel;
- __le64 start_time;
- __le16 duration;
- u8 map;
-} __packed;
-
-enum { /* ieee80211_measurement_request.mode */
- /* Bit 0 is reserved */
- IEEE80211_MEASUREMENT_ENABLE = (1 << 1),
- IEEE80211_MEASUREMENT_REQUEST = (1 << 2),
- IEEE80211_MEASUREMENT_REPORT = (1 << 3),
- /* Bits 4-7 are reserved */
-};
-
-enum {
- IEEE80211_REPORT_BASIC = 0, /* required */
- IEEE80211_REPORT_CCA = 1, /* optional */
- IEEE80211_REPORT_RPI = 2, /* optional */
- /* 3-255 reserved */
-};
-
-struct ieee80211_measurement_params {
- u8 channel;
- __le64 start_time;
- __le16 duration;
-} __packed;
-
-struct ieee80211_info_element {
- u8 id;
- u8 len;
- u8 data[0];
-} __packed;
-
-struct ieee80211_measurement_request {
- struct ieee80211_info_element ie;
- u8 token;
- u8 mode;
- u8 type;
- struct ieee80211_measurement_params params[0];
-} __packed;
-
-struct ieee80211_measurement_report {
- struct ieee80211_info_element ie;
- u8 token;
- u8 mode;
- u8 type;
- union {
- struct ieee80211_basic_report basic[0];
- } u;
-} __packed;
-
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index bc90a12408a..3c8cebde16c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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.
@@ -233,7 +233,6 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
struct iwl_station_entry *station;
int i;
u8 sta_id = IWL_INVALID_STATION;
- u16 rate;
if (is_ap)
sta_id = ctx->ap_sta_id;
@@ -306,12 +305,6 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
*/
iwl_set_ht_add_station(priv, sta_id, sta, ctx);
- /* 3945 only */
- rate = (priv->band == IEEE80211_BAND_5GHZ) ?
- IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP;
- /* Turn on both antennas for the station... */
- station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK);
-
return sta_id;
}
@@ -501,7 +494,8 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
priv->num_stations--;
- BUG_ON(priv->num_stations < 0);
+ if (WARN_ON(priv->num_stations < 0))
+ priv->num_stations = 0;
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -686,7 +680,8 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
priv->num_stations--;
- BUG_ON(priv->num_stations < 0);
+ if (WARN_ON(priv->num_stations < 0))
+ priv->num_stations = 0;
kfree(priv->stations[i].lq);
priv->stations[i].lq = NULL;
}
@@ -782,7 +777,8 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
iwl_dump_lq_cmd(priv, lq);
- BUG_ON(init && (cmd.flags & CMD_ASYNC));
+ if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))
+ return -EINVAL;
if (is_lq_table_valid(priv, ctx, lq))
ret = iwl_send_cmd(priv, &cmd);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 206f1e1a0ca..ff64027ff4c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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.
diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c
new file mode 100644
index 00000000000..89b6696622c
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c
@@ -0,0 +1,469 @@
+/******************************************************************************
+ *
+ * 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) 2010 - 2011 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:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010 - 2011 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.
+ *
+ *****************************************************************************/
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <net/net_namespace.h>
+#include <linux/netdevice.h>
+#include <net/cfg80211.h>
+#include <net/mac80211.h>
+#include <net/netlink.h>
+
+
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-debug.h"
+#include "iwl-fh.h"
+#include "iwl-io.h"
+#include "iwl-agn.h"
+#include "iwl-testmode.h"
+
+
+/* The TLVs used in the gnl message policy between the kernel module and
+ * user space application. iwl_testmode_gnl_msg_policy is to be carried
+ * through the NL80211_CMD_TESTMODE channel regulated by nl80211.
+ * See iwl-testmode.h
+ */
+static
+struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
+ [IWL_TM_ATTR_COMMAND] = { .type = NLA_U32, },
+
+ [IWL_TM_ATTR_UCODE_CMD_ID] = { .type = NLA_U8, },
+ [IWL_TM_ATTR_UCODE_CMD_DATA] = { .type = NLA_UNSPEC, },
+
+ [IWL_TM_ATTR_REG_OFFSET] = { .type = NLA_U32, },
+ [IWL_TM_ATTR_REG_VALUE8] = { .type = NLA_U8, },
+ [IWL_TM_ATTR_REG_VALUE32] = { .type = NLA_U32, },
+
+ [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, },
+ [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, },
+};
+
+/*
+ * See the struct iwl_rx_packet in iwl-commands.h for the format of the
+ * received events from the device
+ */
+static inline int get_event_length(struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = rxb_addr(rxb);
+ if (pkt)
+ return le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+ else
+ return 0;
+}
+
+
+/*
+ * This function multicasts the spontaneous messages from the device to the
+ * user space. It is invoked whenever there is a received messages
+ * from the device. This function is called within the ISR of the rx handlers
+ * in iwlagn driver.
+ *
+ * The parsing of the message content is left to the user space application,
+ * The message content is treated as unattacked raw data and is encapsulated
+ * with IWL_TM_ATTR_UCODE_RX_PKT multicasting to the user space.
+ *
+ * @priv: the instance of iwlwifi device
+ * @rxb: pointer to rx data content received by the ISR
+ *
+ * See the message policies and TLVs in iwl_testmode_gnl_msg_policy[].
+ * For the messages multicasting to the user application, the mandatory
+ * TLV fields are :
+ * IWL_TM_ATTR_COMMAND must be IWL_TM_CMD_DEV2APP_UCODE_RX_PKT
+ * IWL_TM_ATTR_UCODE_RX_PKT for carrying the message content
+ */
+
+static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct ieee80211_hw *hw = priv->hw;
+ struct sk_buff *skb;
+ void *data;
+ int length;
+
+ data = (void *)rxb_addr(rxb);
+ length = get_event_length(rxb);
+
+ if (!data || length == 0)
+ return;
+
+ skb = cfg80211_testmode_alloc_event_skb(hw->wiphy, 20 + length,
+ GFP_ATOMIC);
+ if (skb == NULL) {
+ IWL_DEBUG_INFO(priv,
+ "Run out of memory for messages to user space ?\n");
+ return;
+ }
+ NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
+ NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data);
+ cfg80211_testmode_event(skb, GFP_ATOMIC);
+ return;
+
+nla_put_failure:
+ kfree_skb(skb);
+ IWL_DEBUG_INFO(priv, "Ouch, overran buffer, check allocation!\n");
+}
+
+void iwl_testmode_init(struct iwl_priv *priv)
+{
+ priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
+}
+
+/*
+ * This function handles the user application commands to the ucode.
+ *
+ * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_CMD_ID and
+ * IWL_TM_ATTR_UCODE_CMD_DATA and calls to the handler to send the
+ * host command to the ucode.
+ *
+ * If any mandatory field is missing, -ENOMSG is replied to the user space
+ * application; otherwise, the actual execution result of the host command to
+ * ucode is replied.
+ *
+ * @hw: ieee80211_hw object that represents the device
+ * @tb: gnl message fields from the user space
+ */
+static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
+{
+ struct iwl_priv *priv = hw->priv;
+ struct iwl_host_cmd cmd;
+
+ memset(&cmd, 0, sizeof(struct iwl_host_cmd));
+
+ if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] ||
+ !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) {
+ IWL_DEBUG_INFO(priv,
+ "Error finding ucode command mandatory fields\n");
+ return -ENOMSG;
+ }
+
+ cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
+ cmd.data = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
+ cmd.len = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
+ IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
+ " len %d\n", cmd.id, cmd.flags, cmd.len);
+ /* ok, let's submit the command to ucode */
+ return iwl_send_cmd(priv, &cmd);
+}
+
+
+/*
+ * This function handles the user application commands for register access.
+ *
+ * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
+ * handlers respectively.
+ *
+ * If it's an unknown commdn ID, -ENOSYS is returned; or -ENOMSG if the
+ * mandatory fields(IWL_TM_ATTR_REG_OFFSET,IWL_TM_ATTR_REG_VALUE32,
+ * IWL_TM_ATTR_REG_VALUE8) are missing; Otherwise 0 is replied indicating
+ * the success of the command execution.
+ *
+ * If IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_READ32, the register read
+ * value is returned with IWL_TM_ATTR_REG_VALUE32.
+ *
+ * @hw: ieee80211_hw object that represents the device
+ * @tb: gnl message fields from the user space
+ */
+static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
+{
+ struct iwl_priv *priv = hw->priv;
+ u32 ofs, val32;
+ u8 val8;
+ struct sk_buff *skb;
+ int status = 0;
+
+ if (!tb[IWL_TM_ATTR_REG_OFFSET]) {
+ IWL_DEBUG_INFO(priv, "Error finding register offset\n");
+ return -ENOMSG;
+ }
+ ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
+ IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs);
+
+ switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
+ case IWL_TM_CMD_APP2DEV_REG_READ32:
+ val32 = iwl_read32(priv, ofs);
+ IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
+
+ skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
+ if (!skb) {
+ IWL_DEBUG_INFO(priv, "Error allocating memory\n");
+ return -ENOMEM;
+ }
+ NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32);
+ status = cfg80211_testmode_reply(skb);
+ if (status < 0)
+ IWL_DEBUG_INFO(priv,
+ "Error sending msg : %d\n", status);
+ break;
+ case IWL_TM_CMD_APP2DEV_REG_WRITE32:
+ if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
+ IWL_DEBUG_INFO(priv,
+ "Error finding value to write\n");
+ return -ENOMSG;
+ } else {
+ val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
+ IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
+ iwl_write32(priv, ofs, val32);
+ }
+ break;
+ case IWL_TM_CMD_APP2DEV_REG_WRITE8:
+ if (!tb[IWL_TM_ATTR_REG_VALUE8]) {
+ IWL_DEBUG_INFO(priv, "Error finding value to write\n");
+ return -ENOMSG;
+ } else {
+ val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]);
+ IWL_INFO(priv, "8bit value to write 0x%x\n", val8);
+ iwl_write8(priv, ofs, val8);
+ }
+ break;
+ default:
+ IWL_DEBUG_INFO(priv, "Unknown testmode register command ID\n");
+ return -ENOSYS;
+ }
+
+ return status;
+
+nla_put_failure:
+ kfree_skb(skb);
+ return -EMSGSIZE;
+}
+
+
+static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
+{
+ struct iwl_notification_wait calib_wait;
+ int ret;
+
+ iwlagn_init_notification_wait(priv, &calib_wait,
+ CALIBRATION_COMPLETE_NOTIFICATION,
+ NULL, NULL);
+ ret = iwlagn_init_alive_start(priv);
+ if (ret) {
+ IWL_DEBUG_INFO(priv,
+ "Error configuring init calibration: %d\n", ret);
+ goto cfg_init_calib_error;
+ }
+
+ ret = iwlagn_wait_notification(priv, &calib_wait, 2 * HZ);
+ if (ret)
+ IWL_DEBUG_INFO(priv, "Error detecting"
+ " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret);
+ return ret;
+
+cfg_init_calib_error:
+ iwlagn_remove_notification(priv, &calib_wait);
+ return ret;
+}
+
+/*
+ * This function handles the user application commands for driver.
+ *
+ * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
+ * handlers respectively.
+ *
+ * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
+ * value of the actual command execution is replied to the user application.
+ *
+ * If there's any message responding to the user space, IWL_TM_ATTR_SYNC_RSP
+ * is used for carry the message while IWL_TM_ATTR_COMMAND must set to
+ * IWL_TM_CMD_DEV2APP_SYNC_RSP.
+ *
+ * @hw: ieee80211_hw object that represents the device
+ * @tb: gnl message fields from the user space
+ */
+static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
+{
+ struct iwl_priv *priv = hw->priv;
+ struct sk_buff *skb;
+ unsigned char *rsp_data_ptr = NULL;
+ int status = 0, rsp_data_len = 0;
+
+ switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
+ case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
+ rsp_data_ptr = (unsigned char *)priv->cfg->name;
+ rsp_data_len = strlen(priv->cfg->name);
+ skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
+ rsp_data_len + 20);
+ if (!skb) {
+ IWL_DEBUG_INFO(priv,
+ "Error allocating memory\n");
+ return -ENOMEM;
+ }
+ NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
+ IWL_TM_CMD_DEV2APP_SYNC_RSP);
+ NLA_PUT(skb, IWL_TM_ATTR_SYNC_RSP,
+ rsp_data_len, rsp_data_ptr);
+ status = cfg80211_testmode_reply(skb);
+ if (status < 0)
+ IWL_DEBUG_INFO(priv, "Error sending msg : %d\n",
+ status);
+ break;
+
+ case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
+ status = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init,
+ UCODE_SUBTYPE_INIT, -1);
+ if (status)
+ IWL_DEBUG_INFO(priv,
+ "Error loading init ucode: %d\n", status);
+ break;
+
+ case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
+ iwl_testmode_cfg_init_calib(priv);
+ iwlagn_stop_device(priv);
+ break;
+
+ case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
+ status = iwlagn_load_ucode_wait_alive(priv,
+ &priv->ucode_rt,
+ UCODE_SUBTYPE_REGULAR,
+ UCODE_SUBTYPE_REGULAR_NEW);
+ if (status) {
+ IWL_DEBUG_INFO(priv,
+ "Error loading runtime ucode: %d\n", status);
+ break;
+ }
+ status = iwl_alive_start(priv);
+ if (status)
+ IWL_DEBUG_INFO(priv,
+ "Error starting the device: %d\n", status);
+ break;
+
+ default:
+ IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n");
+ return -ENOSYS;
+ }
+ return status;
+
+nla_put_failure:
+ kfree_skb(skb);
+ return -EMSGSIZE;
+}
+
+/* The testmode gnl message handler that takes the gnl message from the
+ * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
+ * invoke the corresponding handlers.
+ *
+ * This function is invoked when there is user space application sending
+ * gnl message through the testmode tunnel NL80211_CMD_TESTMODE regulated
+ * by nl80211.
+ *
+ * It retrieves the mandatory field, IWL_TM_ATTR_COMMAND, before
+ * dispatching it to the corresponding handler.
+ *
+ * If IWL_TM_ATTR_COMMAND is missing, -ENOMSG is replied to user application;
+ * -ENOSYS is replied to the user application if the command is unknown;
+ * Otherwise, the command is dispatched to the respective handler.
+ *
+ * @hw: ieee80211_hw object that represents the device
+ * @data: pointer to user space message
+ * @len: length in byte of @data
+ */
+int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
+{
+ struct nlattr *tb[IWL_TM_ATTR_MAX - 1];
+ struct iwl_priv *priv = hw->priv;
+ int result;
+
+ result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
+ iwl_testmode_gnl_msg_policy);
+ if (result != 0) {
+ IWL_DEBUG_INFO(priv,
+ "Error parsing the gnl message : %d\n", result);
+ return result;
+ }
+
+ /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
+ if (!tb[IWL_TM_ATTR_COMMAND]) {
+ IWL_DEBUG_INFO(priv, "Error finding testmode command type\n");
+ return -ENOMSG;
+ }
+ /* in case multiple accesses to the device happens */
+ mutex_lock(&priv->mutex);
+
+ switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
+ case IWL_TM_CMD_APP2DEV_UCODE:
+ IWL_DEBUG_INFO(priv, "testmode cmd to uCode\n");
+ result = iwl_testmode_ucode(hw, tb);
+ break;
+ case IWL_TM_CMD_APP2DEV_REG_READ32:
+ case IWL_TM_CMD_APP2DEV_REG_WRITE32:
+ case IWL_TM_CMD_APP2DEV_REG_WRITE8:
+ IWL_DEBUG_INFO(priv, "testmode cmd to register\n");
+ result = iwl_testmode_reg(hw, tb);
+ break;
+ case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
+ case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
+ case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
+ case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
+ IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
+ result = iwl_testmode_driver(hw, tb);
+ break;
+ default:
+ IWL_DEBUG_INFO(priv, "Unknown testmode command\n");
+ result = -ENOSYS;
+ break;
+ }
+
+ mutex_unlock(&priv->mutex);
+ return result;
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h
new file mode 100644
index 00000000000..31f8949f280
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h
@@ -0,0 +1,151 @@
+/******************************************************************************
+ *
+ * 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) 2010 - 2011 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:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010 - 2011 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_TESTMODE_H__
+#define __IWL_TESTMODE_H__
+
+#include <linux/types.h>
+
+
+/* Commands from user space to kernel space(IWL_TM_CMD_ID_APP2DEV_XX) and
+ * from and kernel space to user space(IWL_TM_CMD_ID_DEV2APP_XX).
+ * The command ID is carried with IWL_TM_ATTR_COMMAND. There are three types of
+ * of command from user space and two types of command from kernel space.
+ * See below.
+ */
+enum iwl_tm_cmd_t {
+ /* commands from user application to the uCode,
+ * the actual uCode host command ID is carried with
+ * IWL_TM_ATTR_UCODE_CMD_ID */
+ IWL_TM_CMD_APP2DEV_UCODE = 1,
+
+ /* commands from user applicaiton to access register */
+ IWL_TM_CMD_APP2DEV_REG_READ32,
+ IWL_TM_CMD_APP2DEV_REG_WRITE32,
+ IWL_TM_CMD_APP2DEV_REG_WRITE8,
+
+ /* commands fom user space for pure driver level operations */
+ IWL_TM_CMD_APP2DEV_GET_DEVICENAME,
+ IWL_TM_CMD_APP2DEV_LOAD_INIT_FW,
+ IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB,
+ IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW,
+ /* if there is other new command for the driver layer operation,
+ * append them here */
+
+
+ /* commands from kernel space to carry the synchronous response
+ * to user application */
+ IWL_TM_CMD_DEV2APP_SYNC_RSP,
+
+ /* commands from kernel space to multicast the spontaneous messages
+ * to user application */
+ IWL_TM_CMD_DEV2APP_UCODE_RX_PKT,
+ IWL_TM_CMD_MAX,
+};
+
+enum iwl_tm_attr_t {
+ IWL_TM_ATTR_NOT_APPLICABLE = 0,
+
+ /* From user space to kernel space:
+ * the command either destines to ucode, driver, or register;
+ * See enum iwl_tm_cmd_t.
+ *
+ * From kernel space to user space:
+ * the command either carries synchronous response,
+ * or the spontaneous message multicast from the device;
+ * See enum iwl_tm_cmd_t. */
+ IWL_TM_ATTR_COMMAND,
+
+ /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE,
+ * The mandatory fields are :
+ * IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID;
+ * IWL_TM_ATTR_COMMAND_FLAG for the flags of the commands;
+ * The optional fields are:
+ * IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload
+ * to the ucode */
+ IWL_TM_ATTR_UCODE_CMD_ID,
+ IWL_TM_ATTR_UCODE_CMD_DATA,
+
+ /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_XXX,
+ * The mandatory fields are:
+ * IWL_TM_ATTR_REG_OFFSET for the offset of the target register;
+ * IWL_TM_ATTR_REG_VALUE8 or IWL_TM_ATTR_REG_VALUE32 for value */
+ IWL_TM_ATTR_REG_OFFSET,
+ IWL_TM_ATTR_REG_VALUE8,
+ IWL_TM_ATTR_REG_VALUE32,
+
+ /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_SYNC_RSP,
+ * The mandatory fields are:
+ * IWL_TM_ATTR_SYNC_RSP for the data content responding to the user
+ * application command */
+ IWL_TM_ATTR_SYNC_RSP,
+ /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_UCODE_RX_PKT,
+ * The mandatory fields are:
+ * IWL_TM_ATTR_UCODE_RX_PKT for the data content multicast to the user
+ * application */
+ IWL_TM_ATTR_UCODE_RX_PKT,
+
+ IWL_TM_ATTR_MAX,
+};
+
+
+#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 277c9175dcf..e69597ea43e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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.
@@ -149,32 +149,31 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv)
struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
struct iwl_queue *q = &txq->q;
int i;
- bool huge = false;
if (q->n_bd == 0)
return;
while (q->read_ptr != q->write_ptr) {
- /* we have no way to tell if it is a huge cmd ATM */
i = get_cmd_index(q, q->read_ptr, 0);
- if (txq->meta[i].flags & CMD_SIZE_HUGE)
- huge = true;
- else
+ if (txq->meta[i].flags & CMD_MAPPED) {
pci_unmap_single(priv->pci_dev,
dma_unmap_addr(&txq->meta[i], mapping),
dma_unmap_len(&txq->meta[i], len),
PCI_DMA_BIDIRECTIONAL);
+ txq->meta[i].flags = 0;
+ }
- q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
+ q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
}
- if (huge) {
- i = q->n_window;
+ i = q->n_window;
+ if (txq->meta[i].flags & CMD_MAPPED) {
pci_unmap_single(priv->pci_dev,
dma_unmap_addr(&txq->meta[i], mapping),
dma_unmap_len(&txq->meta[i], len),
PCI_DMA_BIDIRECTIONAL);
+ txq->meta[i].flags = 0;
}
}
@@ -233,7 +232,6 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
* reclaiming packets (on 'tx done IRQ), if free space become > high mark,
* Tx queue resumed.
*
- * See more detailed info in iwl-4965-hw.h.
***************************************************/
int iwl_queue_space(const struct iwl_queue *q)
@@ -265,11 +263,13 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
/* count must be power-of-two size, otherwise iwl_queue_inc_wrap
* and iwl_queue_dec_wrap are broken. */
- BUG_ON(!is_power_of_2(count));
+ if (WARN_ON(!is_power_of_2(count)))
+ return -EINVAL;
/* slots_num must be power-of-two size, otherwise
* get_cmd_index is broken. */
- BUG_ON(!is_power_of_2(slots_num));
+ if (WARN_ON(!is_power_of_2(slots_num)))
+ return -EINVAL;
q->low_mark = q->n_window / 4;
if (q->low_mark < 4)
@@ -386,7 +386,9 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
/* Initialize queue's high/low-water marks, and head/tail indexes */
- iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+ ret = iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+ if (ret)
+ return ret;
/* Tell device where to find queue */
priv->cfg->ops->lib->txq_init(priv, txq);
@@ -440,22 +442,25 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
struct iwl_cmd_meta *out_meta;
dma_addr_t phys_addr;
unsigned long flags;
- int len;
u32 idx;
u16 fix_size;
bool is_ct_kill = false;
- cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len);
fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
- /* If any of the command structures end up being larger than
+ /*
+ * If any of the command structures end up being larger than
* the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then
* we will need to increase the size of the TFD entries
* Also, check to see if command buffer should not exceed the size
- * of device_cmd and max_cmd_size. */
- BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
- !(cmd->flags & CMD_SIZE_HUGE));
- BUG_ON(fix_size > IWL_MAX_CMD_SIZE);
+ * of device_cmd and max_cmd_size.
+ */
+ if (WARN_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
+ !(cmd->flags & CMD_SIZE_HUGE)))
+ return -EINVAL;
+
+ if (WARN_ON(fix_size > IWL_MAX_CMD_SIZE))
+ return -EINVAL;
if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) {
IWL_WARN(priv, "Not sending command - %s KILL\n",
@@ -463,35 +468,38 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
return -EIO;
}
+ /*
+ * As we only have a single huge buffer, check that the command
+ * is synchronous (otherwise buffers could end up being reused).
+ */
+
+ if (WARN_ON((cmd->flags & CMD_ASYNC) && (cmd->flags & CMD_SIZE_HUGE)))
+ return -EINVAL;
+
+ spin_lock_irqsave(&priv->hcmd_lock, flags);
+
if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
+ spin_unlock_irqrestore(&priv->hcmd_lock, flags);
+
IWL_ERR(priv, "No space in command queue\n");
- if (priv->cfg->ops->lib->tt_ops.ct_kill_check) {
- is_ct_kill =
- priv->cfg->ops->lib->tt_ops.ct_kill_check(priv);
- }
+ is_ct_kill = iwl_check_for_ct_kill(priv);
if (!is_ct_kill) {
IWL_ERR(priv, "Restarting adapter due to queue full\n");
- queue_work(priv->workqueue, &priv->restart);
+ iwlagn_fw_error(priv, false);
}
return -ENOSPC;
}
- spin_lock_irqsave(&priv->hcmd_lock, flags);
-
- /* If this is a huge cmd, mark the huge flag also on the meta.flags
- * of the _original_ cmd. This is used for DMA mapping clean up.
- */
- if (cmd->flags & CMD_SIZE_HUGE) {
- idx = get_cmd_index(q, q->write_ptr, 0);
- txq->meta[idx].flags = CMD_SIZE_HUGE;
- }
-
idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
out_cmd = txq->cmd[idx];
out_meta = &txq->meta[idx];
+ if (WARN_ON(out_meta->flags & CMD_MAPPED)) {
+ spin_unlock_irqrestore(&priv->hcmd_lock, flags);
+ return -ENOSPC;
+ }
+
memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */
- out_meta->flags = cmd->flags;
if (cmd->flags & CMD_WANT_SKB)
out_meta->source = cmd;
if (cmd->flags & CMD_ASYNC)
@@ -508,9 +516,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
INDEX_TO_SEQ(q->write_ptr));
if (cmd->flags & CMD_SIZE_HUGE)
out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
- len = sizeof(struct iwl_device_cmd);
- if (idx == TFD_CMD_SLOTS)
- len = IWL_MAX_CMD_SIZE;
#ifdef CONFIG_IWLWIFI_DEBUG
switch (out_cmd->hdr.cmd) {
@@ -532,17 +537,20 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
q->write_ptr, idx, priv->cmd_queue);
}
#endif
- txq->need_update = 1;
-
- if (priv->cfg->ops->lib->txq_update_byte_cnt_tbl)
- /* Set up entry in queue's byte count circular buffer */
- priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
-
phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr,
fix_size, PCI_DMA_BIDIRECTIONAL);
+ if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) {
+ idx = -ENOMEM;
+ goto out;
+ }
+
dma_unmap_addr_set(out_meta, mapping, phys_addr);
dma_unmap_len_set(out_meta, len, fix_size);
+ out_meta->flags = cmd->flags | CMD_MAPPED;
+
+ txq->need_update = 1;
+
trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags);
priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
@@ -553,6 +561,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
iwl_txq_update_write_ptr(priv, txq);
+ out:
spin_unlock_irqrestore(&priv->hcmd_lock, flags);
return idx;
}
@@ -584,7 +593,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
if (nfreed++ > 0) {
IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", idx,
q->write_ptr, q->read_ptr);
- queue_work(priv->workqueue, &priv->restart);
+ iwlagn_fw_error(priv, false);
}
}
@@ -609,6 +618,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
struct iwl_device_cmd *cmd;
struct iwl_cmd_meta *meta;
struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
+ unsigned long flags;
/* 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
@@ -622,14 +632,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
return;
}
- /* If this is a huge cmd, clear the huge flag on the meta.flags
- * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap
- * the DMA buffer for the scan (huge) command.
- */
- if (huge) {
- cmd_index = get_cmd_index(&txq->q, index, 0);
- txq->meta[cmd_index].flags = 0;
- }
cmd_index = get_cmd_index(&txq->q, index, huge);
cmd = txq->cmd[cmd_index];
meta = &txq->meta[cmd_index];
@@ -646,6 +648,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
} else if (meta->callback)
meta->callback(priv, cmd, pkt);
+ spin_lock_irqsave(&priv->hcmd_lock, flags);
+
iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
if (!(meta->flags & CMD_ASYNC)) {
@@ -654,5 +658,9 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
get_cmd_string(cmd->hdr.cmd));
wake_up_interruptible(&priv->wait_command_queue);
}
+
+ /* Mark as unmapped */
meta->flags = 0;
+
+ spin_unlock_irqrestore(&priv->hcmd_lock, flags);
}
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 9a57cf6a488..5665a1a9b99 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -1576,7 +1576,8 @@ static void iwm_rx_process_amsdu(struct iwm_priv *iwm, struct sk_buff *skb)
IWM_HEXDUMP(iwm, DBG, RX, "A-MSDU: ", skb->data, skb->len);
__skb_queue_head_init(&list);
- ieee80211_amsdu_to_8023s(skb, &list, ndev->dev_addr, wdev->iftype, 0);
+ ieee80211_amsdu_to_8023s(skb, &list, ndev->dev_addr, wdev->iftype, 0,
+ true);
while ((frame = __skb_dequeue(&list))) {
ndev->stats.rx_packets++;
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 5caa2ac14d6..5d637af2d7c 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -6,6 +6,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/slab.h>
@@ -122,8 +124,10 @@ static u8 lbs_auth_to_authtype(enum nl80211_auth_type auth_type)
}
-/* Various firmware commands need the list of supported rates, but with
- the hight-bit set for basic rates */
+/*
+ * Various firmware commands need the list of supported rates, but with
+ * the hight-bit set for basic rates
+ */
static int lbs_add_rates(u8 *rates)
{
size_t i;
@@ -425,7 +429,7 @@ static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len)
return ie_len + 2;
}
-/***************************************************************************
+/*
* Set Channel
*/
@@ -452,7 +456,7 @@ static int lbs_cfg_set_channel(struct wiphy *wiphy,
-/***************************************************************************
+/*
* Scanning
*/
@@ -538,8 +542,10 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
goto done;
}
- /* Validity check: the TLV holds TSF values with 8 bytes each, so
- * the size in the TLV must match the nr_sets value */
+ /*
+ * Validity check: the TLV holds TSF values with 8 bytes each, so
+ * the size in the TLV must match the nr_sets value
+ */
i = get_unaligned_le16(tsfdesc);
tsfdesc += 2;
if (i / 8 != scanresp->nr_sets) {
@@ -581,8 +587,10 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
/* To find out the channel, we must parse the IEs */
ie = pos;
- /* 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon
- interval, capabilities */
+ /*
+ * 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon
+ * interval, capabilities
+ */
ielen = left = len - (6 + 1 + 8 + 2 + 2);
while (left >= 2) {
u8 id, elen;
@@ -790,7 +798,7 @@ static int lbs_cfg_scan(struct wiphy *wiphy,
-/***************************************************************************
+/*
* Events
*/
@@ -825,7 +833,7 @@ void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event)
-/***************************************************************************
+/*
* Connect/disconnect
*/
@@ -950,8 +958,10 @@ static int lbs_enable_rsn(struct lbs_private *priv, int enable)
* Set WPA/WPA key material
*/
-/* like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we
- * get rid of WEXT, this should go into host.h */
+/*
+ * like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we
+ * get rid of WEXT, this should go into host.h
+ */
struct cmd_key_material {
struct cmd_header hdr;
@@ -1314,8 +1324,8 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
sme->ssid, sme->ssid_len,
WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
if (!bss) {
- lbs_pr_err("assoc: bss %pM not in scan results\n",
- sme->bssid);
+ wiphy_err(wiphy, "assoc: bss %pM not in scan results\n",
+ sme->bssid);
ret = -ENOENT;
goto done;
}
@@ -1372,8 +1382,8 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
lbs_enable_rsn(priv, sme->crypto.cipher_group != 0);
break;
default:
- lbs_pr_err("unsupported cipher group 0x%x\n",
- sme->crypto.cipher_group);
+ wiphy_err(wiphy, "unsupported cipher group 0x%x\n",
+ sme->crypto.cipher_group);
ret = -ENOTSUPP;
goto done;
}
@@ -1491,7 +1501,7 @@ static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
params->key, params->key_len);
break;
default:
- lbs_pr_err("unhandled cipher 0x%x\n", params->cipher);
+ wiphy_err(wiphy, "unhandled cipher 0x%x\n", params->cipher);
ret = -ENOTSUPP;
break;
}
@@ -1536,7 +1546,7 @@ static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev,
}
-/***************************************************************************
+/*
* Get station
*/
@@ -1581,7 +1591,7 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
-/***************************************************************************
+/*
* "Site survey", here just current channel and noise level
*/
@@ -1614,7 +1624,7 @@ static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev,
-/***************************************************************************
+/*
* Change interface
*/
@@ -1656,11 +1666,12 @@ static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev,
-/***************************************************************************
+/*
* IBSS (Ad-Hoc)
*/
-/* The firmware needs the following bits masked out of the beacon-derived
+/*
+ * The firmware needs the following bits masked out of the beacon-derived
* capability field when associating/joining to a BSS:
* 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused)
*/
@@ -1999,7 +2010,7 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
-/***************************************************************************
+/*
* Initialization
*/
@@ -2118,13 +2129,13 @@ int lbs_cfg_register(struct lbs_private *priv)
ret = wiphy_register(wdev->wiphy);
if (ret < 0)
- lbs_pr_err("cannot register wiphy device\n");
+ pr_err("cannot register wiphy device\n");
priv->wiphy_registered = true;
ret = register_netdev(priv->dev);
if (ret)
- lbs_pr_err("cannot register network device\n");
+ pr_err("cannot register network device\n");
INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index f3ac62431a3..84566db486d 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1,7 +1,7 @@
-/**
- * This file contains the handling of command.
- * It prepares command and sends it to firmware when it is ready.
- */
+/*
+ * This file contains the handling of command.
+ * It prepares command and sends it to firmware when it is ready.
+ */
#include <linux/kfifo.h>
#include <linux/sched.h>
@@ -16,14 +16,14 @@
#define CAL_RSSI(snr, nf) ((s32)((s32)(snr) + CAL_NF(nf)))
/**
- * @brief Simple callback that copies response back into command
+ * lbs_cmd_copyback - 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
+ * @priv: A pointer to &struct lbs_private structure
+ * @extra: A pointer to the original command structure for which
+ * 'resp' is a response
+ * @resp: A pointer to the command response
*
- * @return 0 on success, error on failure
+ * returns: 0 on success, error on failure
*/
int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
struct cmd_header *resp)
@@ -38,15 +38,15 @@ int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
/**
- * @brief Simple callback that ignores the result. Use this if
- * you just want to send a command to the hardware, but don't
+ * lbs_cmd_async_callback - Simple callback that ignores the result.
+ * Use this if you just want to send a command to the hardware, but don't
* care for the result.
*
- * @param priv ignored
- * @param extra ignored
- * @param resp ignored
+ * @priv: ignored
+ * @extra: ignored
+ * @resp: ignored
*
- * @return 0 for success
+ * returns: 0 for success
*/
static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra,
struct cmd_header *resp)
@@ -56,10 +56,11 @@ static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra,
/**
- * @brief Checks whether a command is allowed in Power Save mode
+ * is_command_allowed_in_ps - tests if a command is allowed in Power Save mode
+ *
+ * @cmd: the command ID
*
- * @param command the command ID
- * @return 1 if allowed, 0 if not allowed
+ * returns: 1 if allowed, 0 if not allowed
*/
static u8 is_command_allowed_in_ps(u16 cmd)
{
@@ -75,11 +76,12 @@ static u8 is_command_allowed_in_ps(u16 cmd)
}
/**
- * @brief Updates the hardware details like MAC address and regulatory region
+ * lbs_update_hw_spec - Updates the hardware details like MAC address
+ * and regulatory region
*
- * @param priv A pointer to struct lbs_private structure
+ * @priv: A pointer to &struct lbs_private structure
*
- * @return 0 on success, error on failure
+ * returns: 0 on success, error on failure
*/
int lbs_update_hw_spec(struct lbs_private *priv)
{
@@ -108,7 +110,7 @@ int lbs_update_hw_spec(struct lbs_private *priv)
* CF card firmware 5.0.16p0: cap 0x00000303
* USB dongle firmware 5.110.17p2: cap 0x00000303
*/
- lbs_pr_info("%pM, fw %u.%u.%up%u, cap 0x%08x\n",
+ netdev_info(priv->dev, "%pM, fw %u.%u.%up%u, cap 0x%08x\n",
cmd.permanentaddr,
priv->fwrelease >> 24 & 0xff,
priv->fwrelease >> 16 & 0xff,
@@ -139,7 +141,8 @@ int lbs_update_hw_spec(struct lbs_private *priv)
/* 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");
+ netdev_info(priv->dev,
+ "unidentified region code; using the default (USA)\n");
}
if (priv->current_addr[0] == 0xff)
@@ -209,7 +212,7 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
(uint8_t *)&cmd_config.wol_conf,
sizeof(struct wol_config));
} else {
- lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
+ netdev_info(priv->dev, "HOST_SLEEP_CFG failed %d\n", ret);
}
return ret;
@@ -217,14 +220,14 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
/**
- * @brief Sets the Power Save mode
+ * lbs_set_ps_mode - Sets the Power Save mode
*
- * @param priv A pointer to struct lbs_private structure
- * @param cmd_action The Power Save operation (PS_MODE_ACTION_ENTER_PS or
+ * @priv: A pointer to &struct lbs_private structure
+ * @cmd_action: The Power Save operation (PS_MODE_ACTION_ENTER_PS or
* PS_MODE_ACTION_EXIT_PS)
- * @param block Whether to block on a response or not
+ * @block: Whether to block on a response or not
*
- * @return 0 on success, error on failure
+ * returns: 0 on success, error on failure
*/
int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block)
{
@@ -312,7 +315,7 @@ static int lbs_wait_for_ds_awake(struct lbs_private *priv)
if (priv->is_deep_sleep) {
if (!wait_event_interruptible_timeout(priv->ds_awake_q,
!priv->is_deep_sleep, (10 * HZ))) {
- lbs_pr_err("ds_awake_q: timer expired\n");
+ netdev_err(priv->dev, "ds_awake_q: timer expired\n");
ret = -1;
}
}
@@ -337,7 +340,7 @@ int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep)
netif_carrier_off(priv->dev);
}
} else {
- lbs_pr_err("deep sleep: already enabled\n");
+ netdev_err(priv->dev, "deep sleep: already enabled\n");
}
} else {
if (priv->is_deep_sleep) {
@@ -347,8 +350,8 @@ int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep)
if (!ret) {
ret = lbs_wait_for_ds_awake(priv);
if (ret)
- lbs_pr_err("deep sleep: wakeup"
- "failed\n");
+ netdev_err(priv->dev,
+ "deep sleep: wakeup failed\n");
}
}
}
@@ -382,8 +385,9 @@ int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep)
ret = lbs_host_sleep_cfg(priv, priv->wol_criteria,
(struct wol_config *)NULL);
if (ret) {
- lbs_pr_info("Host sleep configuration failed: "
- "%d\n", ret);
+ netdev_info(priv->dev,
+ "Host sleep configuration failed: %d\n",
+ ret);
return ret;
}
if (priv->psstate == PS_STATE_FULL_POWER) {
@@ -393,19 +397,21 @@ int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep)
sizeof(cmd),
lbs_ret_host_sleep_activate, 0);
if (ret)
- lbs_pr_info("HOST_SLEEP_ACTIVATE "
- "failed: %d\n", ret);
+ netdev_info(priv->dev,
+ "HOST_SLEEP_ACTIVATE failed: %d\n",
+ ret);
}
if (!wait_event_interruptible_timeout(
priv->host_sleep_q,
priv->is_host_sleep_activated,
(10 * HZ))) {
- lbs_pr_err("host_sleep_q: timer expired\n");
+ netdev_err(priv->dev,
+ "host_sleep_q: timer expired\n");
ret = -1;
}
} else {
- lbs_pr_err("host sleep: already enabled\n");
+ netdev_err(priv->dev, "host sleep: already enabled\n");
}
} else {
if (priv->is_host_sleep_activated)
@@ -417,13 +423,13 @@ int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep)
}
/**
- * @brief Set an SNMP MIB value
+ * lbs_set_snmp_mib - Set an SNMP MIB value
*
- * @param priv A pointer to struct lbs_private structure
- * @param oid The OID to set in the firmware
- * @param val Value to set the OID to
+ * @priv: A pointer to &struct lbs_private structure
+ * @oid: The OID to set in the firmware
+ * @val: Value to set the OID to
*
- * @return 0 on success, error on failure
+ * returns: 0 on success, error on failure
*/
int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val)
{
@@ -467,13 +473,13 @@ out:
}
/**
- * @brief Get an SNMP MIB value
+ * lbs_get_snmp_mib - Get an SNMP MIB value
*
- * @param priv A pointer to struct lbs_private structure
- * @param oid The OID to retrieve from the firmware
- * @param out_val Location for the returned value
+ * @priv: A pointer to &struct lbs_private structure
+ * @oid: The OID to retrieve from the firmware
+ * @out_val: Location for the returned value
*
- * @return 0 on success, error on failure
+ * returns: 0 on success, error on failure
*/
int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val)
{
@@ -510,14 +516,14 @@ out:
}
/**
- * @brief Get the min, max, and current TX power
+ * lbs_get_tx_power - Get the min, max, and current TX power
*
- * @param priv A pointer to struct lbs_private structure
- * @param curlevel Current power level in dBm
- * @param minlevel Minimum supported power level in dBm (optional)
- * @param maxlevel Maximum supported power level in dBm (optional)
+ * @priv: A pointer to &struct lbs_private structure
+ * @curlevel: Current power level in dBm
+ * @minlevel: Minimum supported power level in dBm (optional)
+ * @maxlevel: Maximum supported power level in dBm (optional)
*
- * @return 0 on success, error on failure
+ * returns: 0 on success, error on failure
*/
int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
s16 *maxlevel)
@@ -545,12 +551,12 @@ int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
}
/**
- * @brief Set the TX power
+ * lbs_set_tx_power - Set the TX power
*
- * @param priv A pointer to struct lbs_private structure
- * @param dbm The desired power level in dBm
+ * @priv: A pointer to &struct lbs_private structure
+ * @dbm: The desired power level in dBm
*
- * @return 0 on success, error on failure
+ * returns: 0 on success, error on failure
*/
int lbs_set_tx_power(struct lbs_private *priv, s16 dbm)
{
@@ -573,12 +579,13 @@ int lbs_set_tx_power(struct lbs_private *priv, s16 dbm)
}
/**
- * @brief Enable or disable monitor mode (only implemented on OLPC usb8388 FW)
+ * lbs_set_monitor_mode - Enable or disable monitor mode
+ * (only implemented on OLPC usb8388 FW)
*
- * @param priv A pointer to struct lbs_private structure
- * @param enable 1 to enable monitor mode, 0 to disable
+ * @priv: A pointer to &struct lbs_private structure
+ * @enable: 1 to enable monitor mode, 0 to disable
*
- * @return 0 on success, error on failure
+ * returns: 0 on success, error on failure
*/
int lbs_set_monitor_mode(struct lbs_private *priv, int enable)
{
@@ -604,11 +611,11 @@ int lbs_set_monitor_mode(struct lbs_private *priv, int enable)
}
/**
- * @brief Get the radio channel
+ * lbs_get_channel - Get the radio channel
*
- * @param priv A pointer to struct lbs_private structure
+ * @priv: A pointer to &struct lbs_private structure
*
- * @return The channel on success, error on failure
+ * returns: The channel on success, error on failure
*/
static int lbs_get_channel(struct lbs_private *priv)
{
@@ -650,12 +657,12 @@ int lbs_update_channel(struct lbs_private *priv)
}
/**
- * @brief Set the radio channel
+ * lbs_set_channel - 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
+ * @priv: A pointer to &struct lbs_private structure
+ * @channel: The desired channel, or 0 to clear a locked channel
*
- * @return 0 on success, error on failure
+ * returns: 0 on success, error on failure
*/
int lbs_set_channel(struct lbs_private *priv, u8 channel)
{
@@ -686,12 +693,13 @@ out:
}
/**
- * @brief Get current RSSI and noise floor
+ * lbs_get_rssi - Get current RSSI and noise floor
*
- * @param priv A pointer to struct lbs_private structure
- * @param rssi On successful return, signal level in mBm
+ * @priv: A pointer to &struct lbs_private structure
+ * @rssi: On successful return, signal level in mBm
+ * @nf: On successful return, Noise floor
*
- * @return The channel on success, error on failure
+ * returns: The channel on success, error on failure
*/
int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf)
{
@@ -719,13 +727,14 @@ int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf)
}
/**
- * @brief Send regulatory and 802.11d domain information to the firmware
+ * lbs_set_11d_domain_info - Send regulatory and 802.11d domain information
+ * to the firmware
*
- * @param priv pointer to struct lbs_private
- * @param request cfg80211 regulatory request structure
- * @param bands the device's supported bands and channels
+ * @priv: pointer to &struct lbs_private
+ * @request: cfg80211 regulatory request structure
+ * @bands: the device's supported bands and channels
*
- * @return 0 on success, error code on failure
+ * returns: 0 on success, error code on failure
*/
int lbs_set_11d_domain_info(struct lbs_private *priv,
struct regulatory_request *request,
@@ -842,15 +851,15 @@ int lbs_set_11d_domain_info(struct lbs_private *priv,
}
/**
- * @brief Read a MAC, Baseband, or RF register
+ * lbs_get_reg - Read a MAC, Baseband, or RF register
*
- * @param priv pointer to struct lbs_private
- * @param cmd register command, one of CMD_MAC_REG_ACCESS,
- * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
- * @param offset byte offset of the register to get
- * @param value on success, the value of the register at 'offset'
+ * @priv: pointer to &struct lbs_private
+ * @reg: register command, one of CMD_MAC_REG_ACCESS,
+ * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
+ * @offset: byte offset of the register to get
+ * @value: on success, the value of the register at 'offset'
*
- * @return 0 on success, error code on failure
+ * returns: 0 on success, error code on failure
*/
int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value)
{
@@ -886,15 +895,15 @@ out:
}
/**
- * @brief Write a MAC, Baseband, or RF register
+ * lbs_set_reg - Write a MAC, Baseband, or RF register
*
- * @param priv pointer to struct lbs_private
- * @param cmd register command, one of CMD_MAC_REG_ACCESS,
- * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
- * @param offset byte offset of the register to set
- * @param value the value to write to the register at 'offset'
+ * @priv: pointer to &struct lbs_private
+ * @reg: register command, one of CMD_MAC_REG_ACCESS,
+ * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
+ * @offset: byte offset of the register to set
+ * @value: the value to write to the register at 'offset'
*
- * @return 0 on success, error code on failure
+ * returns: 0 on success, error code on failure
*/
int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value)
{
@@ -1002,7 +1011,8 @@ static void lbs_submit_command(struct lbs_private *priv,
ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
if (ret) {
- lbs_pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
+ netdev_info(priv->dev, "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/4;
@@ -1023,7 +1033,7 @@ static void lbs_submit_command(struct lbs_private *priv,
lbs_deb_leave(LBS_DEB_HOST);
}
-/**
+/*
* This function inserts command node to cmdfreeq
* after cleans it. Requires priv->driver_lock held.
*/
@@ -1125,11 +1135,12 @@ void lbs_set_mac_control(struct lbs_private *priv)
}
/**
- * @brief This function allocates the command buffer and link
- * it to command free queue.
+ * lbs_allocate_cmd_buffer - allocates the command buffer and links
+ * it to command free queue
+ *
+ * @priv: A pointer to &struct lbs_private structure
*
- * @param priv A pointer to struct lbs_private structure
- * @return 0 or -1
+ * returns: 0 for success or -1 on error
*/
int lbs_allocate_cmd_buffer(struct lbs_private *priv)
{
@@ -1171,10 +1182,11 @@ done:
}
/**
- * @brief This function frees the command buffer.
+ * lbs_free_cmd_buffer - free the command buffer
*
- * @param priv A pointer to struct lbs_private structure
- * @return 0 or -1
+ * @priv: A pointer to &struct lbs_private structure
+ *
+ * returns: 0 for success
*/
int lbs_free_cmd_buffer(struct lbs_private *priv)
{
@@ -1211,11 +1223,13 @@ done:
}
/**
- * @brief This function gets a free command node if available in
- * command free queue.
+ * lbs_get_free_cmd_node - gets a free command node if available in
+ * command free queue
+ *
+ * @priv: A pointer to &struct lbs_private structure
*
- * @param priv A pointer to struct lbs_private structure
- * @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
+ * returns: A pointer to &cmd_ctrl_node structure on success
+ * or %NULL on error
*/
static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv)
{
@@ -1245,12 +1259,12 @@ static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv)
}
/**
- * @brief This function executes next command in command
- * pending queue. It will put firmware back to PS mode
- * if applicable.
+ * lbs_execute_next_command - execute next command in command
+ * pending queue. Will put firmware back to PS mode if applicable.
*
- * @param priv A pointer to struct lbs_private structure
- * @return 0 or -1
+ * @priv: A pointer to &struct lbs_private structure
+ *
+ * returns: 0 on success or -1 on error
*/
int lbs_execute_next_command(struct lbs_private *priv)
{
@@ -1267,7 +1281,8 @@ int lbs_execute_next_command(struct lbs_private *priv)
spin_lock_irqsave(&priv->driver_lock, flags);
if (priv->cur_cmd) {
- lbs_pr_alert( "EXEC_NEXT_CMD: already processing command!\n");
+ netdev_alert(priv->dev,
+ "EXEC_NEXT_CMD: already processing command!\n");
spin_unlock_irqrestore(&priv->driver_lock, flags);
ret = -1;
goto done;
@@ -1431,7 +1446,7 @@ static void lbs_send_confirmsleep(struct lbs_private *priv)
ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep,
sizeof(confirm_sleep));
if (ret) {
- lbs_pr_alert("confirm_sleep failed\n");
+ netdev_alert(priv->dev, "confirm_sleep failed\n");
goto out;
}
@@ -1456,12 +1471,12 @@ out:
}
/**
- * @brief This function checks condition and prepares to
- * send sleep confirm command to firmware if ok.
+ * lbs_ps_confirm_sleep - checks condition and prepares to
+ * send sleep confirm command to firmware if ok
+ *
+ * @priv: A pointer to &struct lbs_private structure
*
- * @param priv A pointer to struct lbs_private structure
- * @param psmode Power Saving mode
- * @return n/a
+ * returns: n/a
*/
void lbs_ps_confirm_sleep(struct lbs_private *priv)
{
@@ -1501,16 +1516,16 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv)
/**
- * @brief Configures the transmission power control functionality.
+ * lbs_set_tpc_cfg - Configures the transmission power control functionality
*
- * @param priv A pointer to struct lbs_private structure
- * @param enable Transmission power control enable
- * @param p0 Power level when link quality is good (dBm).
- * @param p1 Power level when link quality is fair (dBm).
- * @param p2 Power level when link quality is poor (dBm).
- * @param usesnr Use Signal to Noise Ratio in TPC
+ * @priv: A pointer to &struct lbs_private structure
+ * @enable: Transmission power control enable
+ * @p0: Power level when link quality is good (dBm).
+ * @p1: Power level when link quality is fair (dBm).
+ * @p2: Power level when link quality is poor (dBm).
+ * @usesnr: Use Signal to Noise Ratio in TPC
*
- * @return 0 on success
+ * returns: 0 on success
*/
int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
int8_t p2, int usesnr)
@@ -1533,15 +1548,15 @@ int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
}
/**
- * @brief Configures the power adaptation settings.
+ * lbs_set_power_adapt_cfg - Configures the power adaptation settings
*
- * @param priv A pointer to struct lbs_private structure
- * @param enable Power adaptation enable
- * @param p0 Power level for 1, 2, 5.5 and 11 Mbps (dBm).
- * @param p1 Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm).
- * @param p2 Power level for 48 and 54 Mbps (dBm).
+ * @priv: A pointer to &struct lbs_private structure
+ * @enable: Power adaptation enable
+ * @p0: Power level for 1, 2, 5.5 and 11 Mbps (dBm).
+ * @p1: Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm).
+ * @p2: Power level for 48 and 54 Mbps (dBm).
*
- * @return 0 on Success
+ * returns: 0 on Success
*/
int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
@@ -1657,7 +1672,7 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
spin_lock_irqsave(&priv->driver_lock, flags);
ret = cmdnode->result;
if (ret)
- lbs_pr_info("PREP_CMD: command 0x%04x failed: %d\n",
+ netdev_info(priv->dev, "PREP_CMD: command 0x%04x failed: %d\n",
command, ret);
__lbs_cleanup_and_insert_cmd(priv, cmdnode);
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 5e95da9dcc2..207fc361db8 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -1,7 +1,8 @@
-/**
- * This file contains the handling of command
- * responses as well as events generated by firmware.
- */
+/*
+ * This file contains the handling of command
+ * responses as well as events generated by firmware.
+ */
+
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/sched.h>
@@ -12,12 +13,13 @@
#include "cmd.h"
/**
- * @brief This function handles disconnect event. it
- * reports disconnect to upper layer, clean tx/rx packets,
- * reset link state etc.
+ * lbs_mac_event_disconnected - handles disconnect event. It
+ * reports disconnect to upper layer, clean tx/rx packets,
+ * reset link state etc.
+ *
+ * @priv: A pointer to struct lbs_private structure
*
- * @param priv A pointer to struct lbs_private structure
- * @return n/a
+ * returns: n/a
*/
void lbs_mac_event_disconnected(struct lbs_private *priv)
{
@@ -84,15 +86,18 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
lbs_deb_hex(LBS_DEB_CMD, "CMD_RESP", (void *) resp, len);
if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) {
- lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n",
- le16_to_cpu(resp->seqnum), le16_to_cpu(priv->cur_cmd->cmdbuf->seqnum));
+ netdev_info(priv->dev,
+ "Received CMD_RESP with invalid sequence %d (expected %d)\n",
+ le16_to_cpu(resp->seqnum),
+ le16_to_cpu(priv->cur_cmd->cmdbuf->seqnum));
spin_unlock_irqrestore(&priv->driver_lock, flags);
ret = -1;
goto done;
}
if (respcmd != CMD_RET(curcmd) &&
respcmd != CMD_RET_802_11_ASSOCIATE && curcmd != CMD_802_11_ASSOCIATE) {
- lbs_pr_info("Invalid CMD_RESP %x to command %x!\n", respcmd, curcmd);
+ netdev_info(priv->dev, "Invalid CMD_RESP %x to command %x!\n",
+ respcmd, curcmd);
spin_unlock_irqrestore(&priv->driver_lock, flags);
ret = -1;
goto done;
@@ -101,7 +106,8 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
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",
+ netdev_info(priv->dev,
+ "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;
@@ -313,28 +319,28 @@ int lbs_process_event(struct lbs_private *priv, u32 event)
lbs_deb_cmd("EVENT: ADHOC beacon lost\n");
break;
case MACREG_INT_CODE_RSSI_LOW:
- lbs_pr_alert("EVENT: rssi low\n");
+ netdev_alert(priv->dev, "EVENT: rssi low\n");
break;
case MACREG_INT_CODE_SNR_LOW:
- lbs_pr_alert("EVENT: snr low\n");
+ netdev_alert(priv->dev, "EVENT: snr low\n");
break;
case MACREG_INT_CODE_MAX_FAIL:
- lbs_pr_alert("EVENT: max fail\n");
+ netdev_alert(priv->dev, "EVENT: max fail\n");
break;
case MACREG_INT_CODE_RSSI_HIGH:
- lbs_pr_alert("EVENT: rssi high\n");
+ netdev_alert(priv->dev, "EVENT: rssi high\n");
break;
case MACREG_INT_CODE_SNR_HIGH:
- lbs_pr_alert("EVENT: snr high\n");
+ netdev_alert(priv->dev, "EVENT: snr high\n");
break;
case MACREG_INT_CODE_MESH_AUTO_STARTED:
/* Ignore spurious autostart events */
- lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n");
+ netdev_info(priv->dev, "EVENT: MESH_AUTO_STARTED (ignoring)\n");
break;
default:
- lbs_pr_alert("EVENT: unknown event id %d\n", event);
+ netdev_alert(priv->dev, "EVENT: unknown event id %d\n", event);
break;
}
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index fbf3b0332bb..23250f62176 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -151,13 +151,14 @@ static ssize_t lbs_host_sleep_write(struct file *file,
ret = lbs_set_host_sleep(priv, 0);
else if (host_sleep == 1) {
if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
- lbs_pr_info("wake parameters not configured");
+ netdev_info(priv->dev,
+ "wake parameters not configured\n");
ret = -EINVAL;
goto out_unlock;
}
ret = lbs_set_host_sleep(priv, 1);
} else {
- lbs_pr_err("invalid option\n");
+ netdev_err(priv->dev, "invalid option\n");
ret = -EINVAL;
}
@@ -849,15 +850,14 @@ static struct debug_data items[] = {
static int num_of_items = ARRAY_SIZE(items);
/**
- * @brief proc read function
+ * lbs_debugfs_read - proc read function
*
- * @param page pointer to buffer
- * @param s read data starting position
- * @param off offset
- * @param cnt counter
- * @param eof end of file flag
- * @param data data to output
- * @return number of output data
+ * @file: file to read
+ * @userbuf: pointer to buffer
+ * @count: number of bytes to read
+ * @ppos: read data starting position
+ *
+ * returns: amount of data read or negative error code
*/
static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
@@ -897,13 +897,14 @@ static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf,
}
/**
- * @brief proc write function
+ * lbs_debugfs_write - proc write function
+ *
+ * @f: file pointer
+ * @buf: pointer to data buffer
+ * @cnt: data number to write
+ * @ppos: file position
*
- * @param f file pointer
- * @param buf pointer to data buffer
- * @param cnt data number to write
- * @param data data to write
- * @return number of data
+ * returns: amount of data written
*/
static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf,
size_t cnt, loff_t *ppos)
@@ -966,11 +967,11 @@ static const struct file_operations lbs_debug_fops = {
};
/**
- * @brief create debug proc file
+ * lbs_debug_init - create debug proc file
+ *
+ * @priv: pointer to &struct lbs_private
*
- * @param priv pointer struct lbs_private
- * @param dev pointer net_device
- * @return N/A
+ * returns: N/A
*/
static void lbs_debug_init(struct lbs_private *priv)
{
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index 2ae752d1006..da0b05bb89f 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -1,8 +1,8 @@
-/**
- * This file contains declaration referring to
- * functions defined in other source files
- */
+/*
+ * This file contains declaration referring to
+ * functions defined in other source files
+ */
#ifndef _LBS_DECL_H_
#define _LBS_DECL_H_
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index d00c728cec4..ab966f08024 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -1,7 +1,7 @@
-/**
- * This header file contains global constant/enum definitions,
- * global variable declaration.
- */
+/*
+ * This header file contains global constant/enum definitions,
+ * global variable declaration.
+ */
#ifndef _LBS_DEFS_H_
#define _LBS_DEFS_H_
@@ -89,13 +89,6 @@ do { if ((lbs_debug & (grp)) == (grp)) \
#define lbs_deb_spi(fmt, args...) LBS_DEB_LL(LBS_DEB_SPI, " spi", fmt, ##args)
#define lbs_deb_cfg80211(fmt, args...) LBS_DEB_LL(LBS_DEB_CFG80211, " cfg80211", fmt, ##args)
-#define lbs_pr_info(format, args...) \
- printk(KERN_INFO DRV_NAME": " format, ## args)
-#define lbs_pr_err(format, args...) \
- printk(KERN_ERR DRV_NAME": " format, ## args)
-#define lbs_pr_alert(format, args...) \
- printk(KERN_ALERT DRV_NAME": " format, ## args)
-
#ifdef DEBUG
static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, int len)
{
@@ -123,19 +116,19 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
-/** Buffer Constants */
+/* Buffer Constants */
/* The size of SQ memory PPA, DPA are 8 DWORDs, that keep the physical
-* addresses of TxPD buffers. Station has only 8 TxPD available, Whereas
-* driver has more local TxPDs. Each TxPD on the host memory is associated
-* with a Tx control node. The driver maintains 8 RxPD descriptors for
-* station firmware to store Rx packet information.
-*
-* Current version of MAC has a 32x6 multicast address buffer.
-*
-* 802.11b can have up to 14 channels, the driver keeps the
-* BSSID(MAC address) of each APs or Ad hoc stations it has sensed.
-*/
+ * addresses of TxPD buffers. Station has only 8 TxPD available, Whereas
+ * driver has more local TxPDs. Each TxPD on the host memory is associated
+ * with a Tx control node. The driver maintains 8 RxPD descriptors for
+ * station firmware to store Rx packet information.
+ *
+ * Current version of MAC has a 32x6 multicast address buffer.
+ *
+ * 802.11b can have up to 14 channels, the driver keeps the
+ * BSSID(MAC address) of each APs or Ad hoc stations it has sensed.
+ */
#define MRVDRV_MAX_MULTICAST_LIST_SIZE 32
#define LBS_NUM_CMD_BUFFERS 10
@@ -166,7 +159,7 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
#define WOL_RESULT_NOSPC_ERR 1
#define WOL_RESULT_EEXIST_ERR 2
-/** Misc constants */
+/* Misc constants */
/* This section defines 802.11 specific contants */
#define MRVDRV_MAX_BSS_DESCRIPTS 16
@@ -183,7 +176,8 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
#define MARVELL_MESH_IE_LENGTH 9
-/* Values used to populate the struct mrvl_mesh_ie. The only time you need this
+/*
+ * Values used to populate the struct mrvl_mesh_ie. The only time you need this
* is when enabling the mesh using CMD_MESH_CONFIG.
*/
#define MARVELL_MESH_IE_TYPE 4
@@ -193,7 +187,7 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
#define MARVELL_MESH_METRIC_ID 0
#define MARVELL_MESH_CAPABILITY 0
-/** INT status Bit Definition*/
+/* INT status Bit Definition */
#define MRVDRV_TX_DNLD_RDY 0x0001
#define MRVDRV_RX_UPLD_RDY 0x0002
#define MRVDRV_CMD_DNLD_RDY 0x0004
@@ -208,59 +202,63 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
#define TPC_DEFAULT_P1 10
#define TPC_DEFAULT_P2 13
-/** TxPD status */
+/* TxPD status */
-/* Station firmware use TxPD status field to report final Tx transmit
-* result, Bit masks are used to present combined situations.
-*/
+/*
+ * Station firmware use TxPD status field to report final Tx transmit
+ * result, Bit masks are used to present combined situations.
+ */
#define MRVDRV_TxPD_POWER_MGMT_NULL_PACKET 0x01
#define MRVDRV_TxPD_POWER_MGMT_LAST_PACKET 0x08
-/** Tx mesh flag */
-/* Currently we are using normal WDS flag as mesh flag.
+/* Tx mesh flag */
+/*
+ * Currently we are using normal WDS flag as mesh flag.
* TODO: change to proper mesh flag when MAC understands it.
*/
#define TxPD_CONTROL_WDS_FRAME (1<<17)
#define TxPD_MESH_FRAME TxPD_CONTROL_WDS_FRAME
-/** Mesh interface ID */
+/* Mesh interface ID */
#define MESH_IFACE_ID 0x0001
-/** Mesh id should be in bits 14-13-12 */
+/* Mesh id should be in bits 14-13-12 */
#define MESH_IFACE_BIT_OFFSET 0x000c
-/** Mesh enable bit in FW capability */
+/* Mesh enable bit in FW capability */
#define MESH_CAPINFO_ENABLE_MASK (1<<16)
-/** FW definition from Marvell v4 */
+/* FW definition from Marvell v4 */
#define MRVL_FW_V4 (0x04)
-/** FW definition from Marvell v5 */
+/* FW definition from Marvell v5 */
#define MRVL_FW_V5 (0x05)
-/** FW definition from Marvell v10 */
+/* FW definition from Marvell v10 */
#define MRVL_FW_V10 (0x0a)
-/** FW major revision definition */
+/* FW major revision definition */
#define MRVL_FW_MAJOR_REV(x) ((x)>>24)
-/** RxPD status */
+/* RxPD status */
#define MRVDRV_RXPD_STATUS_OK 0x0001
-/** RxPD status - Received packet types */
-/** Rx mesh flag */
-/* Currently we are using normal WDS flag as mesh flag.
+/* RxPD status - Received packet types */
+/* Rx mesh flag */
+/*
+ * Currently we are using normal WDS flag as mesh flag.
* TODO: change to proper mesh flag when MAC understands it.
*/
#define RxPD_CONTROL_WDS_FRAME (0x40)
#define RxPD_MESH_FRAME RxPD_CONTROL_WDS_FRAME
-/** RSSI-related defines */
-/* RSSI constants are used to implement 802.11 RSSI threshold
-* indication. if the Rx packet signal got too weak for 5 consecutive
-* times, miniport driver (driver) will report this event to wrapper
-*/
+/* RSSI-related defines */
+/*
+ * RSSI constants are used to implement 802.11 RSSI threshold
+ * indication. if the Rx packet signal got too weak for 5 consecutive
+ * times, miniport driver (driver) will report this event to wrapper
+ */
#define MRVDRV_NF_DEFAULT_SCAN_VALUE (-96)
-/** RTS/FRAG related defines */
+/* RTS/FRAG related defines */
#define MRVDRV_RTS_MIN_VALUE 0
#define MRVDRV_RTS_MAX_VALUE 2347
#define MRVDRV_FRAG_MIN_VALUE 256
@@ -300,36 +298,36 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
#define MAX_LEDS 8
-/** Global Variable Declaration */
+/* Global Variable Declaration */
extern const char lbs_driver_version[];
extern u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE];
-/** ENUM definition*/
-/** SNRNF_TYPE */
+/* ENUM definition */
+/* SNRNF_TYPE */
enum SNRNF_TYPE {
TYPE_BEACON = 0,
TYPE_RXPD,
MAX_TYPE_B
};
-/** SNRNF_DATA*/
+/* SNRNF_DATA */
enum SNRNF_DATA {
TYPE_NOAVG = 0,
TYPE_AVG,
MAX_TYPE_AVG
};
-/** LBS_802_11_POWER_MODE */
+/* 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 */
+ /* not a real mode, defined as an upper bound */
LBS802_11POWEMODEMAX
};
-/** PS_STATE */
+/* PS_STATE */
enum PS_STATE {
PS_STATE_FULL_POWER,
PS_STATE_AWAKE,
@@ -337,7 +335,7 @@ enum PS_STATE {
PS_STATE_SLEEP
};
-/** DNLD_STATE */
+/* DNLD_STATE */
enum DNLD_STATE {
DNLD_RES_RECEIVED,
DNLD_DATA_SENT,
@@ -345,19 +343,19 @@ enum DNLD_STATE {
DNLD_BOOTCMD_SENT,
};
-/** LBS_MEDIA_STATE */
+/* LBS_MEDIA_STATE */
enum LBS_MEDIA_STATE {
LBS_CONNECTED,
LBS_DISCONNECTED
};
-/** LBS_802_11_PRIVACY_FILTER */
+/* LBS_802_11_PRIVACY_FILTER */
enum LBS_802_11_PRIVACY_FILTER {
LBS802_11PRIVFILTERACCEPTALL,
LBS802_11PRIVFILTER8021XWEP
};
-/** mv_ms_type */
+/* mv_ms_type */
enum mv_ms_type {
MVMS_DAT = 0,
MVMS_CMD = 1,
@@ -365,14 +363,14 @@ enum mv_ms_type {
MVMS_EVENT
};
-/** KEY_TYPE_ID */
+/* KEY_TYPE_ID */
enum KEY_TYPE_ID {
KEY_TYPE_ID_WEP = 0,
KEY_TYPE_ID_TKIP,
KEY_TYPE_ID_AES
};
-/** KEY_INFO_WPA (applies to both TKIP and AES/CCMP) */
+/* KEY_INFO_WPA (applies to both TKIP and AES/CCMP) */
enum KEY_INFO_WPA {
KEY_INFO_WPA_MCAST = 0x01,
KEY_INFO_WPA_UNICAST = 0x02,
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index bc461eb3966..76d018beebf 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -1,8 +1,8 @@
-/**
- * This file contains definitions and data structures specific
- * to Marvell 802.11 NIC. It contains the Device Information
- * structure struct lbs_private..
- */
+/*
+ * This file contains definitions and data structures specific
+ * to Marvell 802.11 NIC. It contains the Device Information
+ * structure struct lbs_private..
+ */
#ifndef _LBS_DEV_H_
#define _LBS_DEV_H_
@@ -12,7 +12,7 @@
#include <linux/kfifo.h>
-/** sleep_params */
+/* sleep_params */
struct sleep_params {
uint16_t sp_error;
uint16_t sp_offset;
@@ -23,7 +23,7 @@ struct sleep_params {
};
-/** Private structure for the MV device */
+/* Private structure for the MV device */
struct lbs_private {
/* Basic networking */
@@ -125,12 +125,12 @@ struct lbs_private {
/* Events sent from hardware to driver */
struct kfifo event_fifo;
- /** thread to service interrupts */
+ /* thread to service interrupts */
struct task_struct *main_thread;
wait_queue_head_t waitq;
struct workqueue_struct *work_thread;
- /** Encryption stuff */
+ /* Encryption stuff */
u8 authtype_auto;
u8 wep_tx_key;
u8 wep_key[4][WLAN_KEY_LEN_WEP104];
@@ -162,7 +162,7 @@ struct lbs_private {
s16 txpower_min;
s16 txpower_max;
- /** Scanning */
+ /* Scanning */
struct delayed_work scan_work;
int scan_channel;
/* Queue of things waiting for scan completion */
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 50193aac679..29dbce4a9f8 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -20,7 +20,8 @@ static void lbs_ethtool_get_drvinfo(struct net_device *dev,
strcpy(info->version, lbs_driver_version);
}
-/* All 8388 parts have 16KiB EEPROM size at the time of writing.
+/*
+ * All 8388 parts have 16KiB EEPROM size at the time of writing.
* In case that changes this needs fixing.
*/
#define LBS_EEPROM_LEN 16384
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index 6cb6935ee4a..2e2dbfa2ee5 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -1,7 +1,7 @@
-/**
- * This file function prototypes, data structure
- * and definitions for all the host/station commands
- */
+/*
+ * This file function prototypes, data structure
+ * and definitions for all the host/station commands
+ */
#ifndef _LBS_HOST_H_
#define _LBS_HOST_H_
@@ -13,9 +13,10 @@
#define CMD_OPTION_WAITFORRSP 0x0002
-/** Host command IDs */
+/* Host command IDs */
-/* Return command are almost always the same as the host command, but with
+/*
+ * Return command are almost always the same as the host command, but with
* bit 15 set high. There are a few exceptions, though...
*/
#define CMD_RET(cmd) (0x8000 | cmd)
@@ -251,7 +252,7 @@ enum cmd_mesh_config_types {
CMD_TYPE_MESH_GET_MESH_IE, /* GET_DEFAULTS is superset of GET_MESHIE */
};
-/** Card Event definition */
+/* Card Event definition */
#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
@@ -624,12 +625,14 @@ struct cmd_ds_802_11_rf_channel {
struct cmd_ds_802_11_rssi {
struct cmd_header hdr;
- /* request: number of beacons (N) to average the SNR and NF over
+ /*
+ * request: number of beacons (N) to average the SNR and NF over
* response: SNR of most recent beacon
*/
__le16 n_or_snr;
- /* The following fields are only set in the response.
+ /*
+ * The following fields are only set in the response.
* In the request these are reserved and should be set to 0.
*/
__le16 nf; /* most recent beacon noise floor */
@@ -680,14 +683,16 @@ struct cmd_ds_802_11_ps_mode {
__le16 action;
- /* Interval for keepalive in PS mode:
+ /*
+ * Interval for keepalive in PS mode:
* 0x0000 = don't change
* 0x001E = firmware default
* 0xFFFF = disable
*/
__le16 nullpktinterval;
- /* Number of DTIM intervals to wake up for:
+ /*
+ * Number of DTIM intervals to wake up for:
* 0 = don't change
* 1 = firmware default
* 5 = max
@@ -697,7 +702,8 @@ struct cmd_ds_802_11_ps_mode {
__le16 reserved;
__le16 locallisteninterval;
- /* AdHoc awake period (FW v9+ only):
+ /*
+ * AdHoc awake period (FW v9+ only):
* 0 = don't change
* 1 = always awake (IEEE standard behavior)
* 2 - 31 = sleep for (n - 1) periods and awake for 1 period
@@ -771,7 +777,8 @@ struct adhoc_bssdesc {
__le16 capability;
u8 rates[MAX_RATES];
- /* DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the
+ /*
+ * DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the
* Adhoc join command and will cause a binary layout mismatch with
* the firmware
*/
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 8712cb213f2..63ed5798365 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -21,6 +21,8 @@
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
@@ -312,7 +314,8 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
#define CF8385_MANFID 0x02df
#define CF8385_CARDID 0x8103
-/* FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when
+/*
+ * FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when
* that gets fixed. Currently there's no way to access it from the probe hook.
*/
static inline u32 get_model(u16 manf_id, u16 card_id)
@@ -361,7 +364,7 @@ static int if_cs_send_cmd(struct lbs_private *priv, u8 *buf, u16 nb)
if (status & IF_CS_BIT_COMMAND)
break;
if (++loops > 100) {
- lbs_pr_err("card not ready for commands\n");
+ netdev_err(priv->dev, "card not ready for commands\n");
goto done;
}
mdelay(1);
@@ -431,14 +434,16 @@ static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len)
/* is hardware ready? */
status = if_cs_read16(priv->card, IF_CS_CARD_STATUS);
if ((status & IF_CS_BIT_RESP) == 0) {
- lbs_pr_err("no cmd response in card\n");
+ netdev_err(priv->dev, "no cmd response in card\n");
*len = 0;
goto out;
}
*len = if_cs_read16(priv->card, IF_CS_RESP_LEN);
if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) {
- lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len);
+ netdev_err(priv->dev,
+ "card cmd buffer has invalid # of bytes (%d)\n",
+ *len);
goto out;
}
@@ -472,7 +477,9 @@ static struct sk_buff *if_cs_receive_data(struct lbs_private *priv)
len = if_cs_read16(priv->card, IF_CS_READ_LEN);
if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
- lbs_pr_err("card data buffer has invalid # of bytes (%d)\n", len);
+ netdev_err(priv->dev,
+ "card data buffer has invalid # of bytes (%d)\n",
+ len);
priv->dev->stats.rx_dropped++;
goto dat_err;
}
@@ -621,8 +628,10 @@ static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw)
if (remain < count)
count = remain;
- /* "write the number of bytes to be sent to the I/O Command
- * write length register" */
+ /*
+ * "write the number of bytes to be sent to the I/O Command
+ * write length register"
+ */
if_cs_write16(card, IF_CS_CMD_LEN, count);
/* "write this to I/O Command port register as 16 bit writes */
@@ -631,21 +640,27 @@ static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw)
&fw->data[sent],
count >> 1);
- /* "Assert the download over interrupt command in the Host
- * status register" */
+ /*
+ * "Assert the download over interrupt command in the Host
+ * status register"
+ */
if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND);
- /* "Assert the download over interrupt command in the Card
- * interrupt case register" */
+ /*
+ * "Assert the download over interrupt command in the Card
+ * interrupt case register"
+ */
if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND);
- /* "The host polls the Card Status register ... for 50 ms before
- declaring a failure */
+ /*
+ * "The host polls the Card Status register ... for 50 ms before
+ * declaring a failure"
+ */
ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS,
IF_CS_BIT_COMMAND);
if (ret < 0) {
- lbs_pr_err("can't download helper at 0x%x, ret %d\n",
- sent, ret);
+ pr_err("can't download helper at 0x%x, ret %d\n",
+ sent, ret);
goto done;
}
@@ -675,7 +690,7 @@ static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw)
ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW,
IF_CS_SQ_HELPER_OK);
if (ret < 0) {
- lbs_pr_err("helper firmware doesn't answer\n");
+ pr_err("helper firmware doesn't answer\n");
goto done;
}
@@ -683,13 +698,13 @@ static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw)
len = if_cs_read16(card, IF_CS_SQ_READ_LOW);
if (len & 1) {
retry++;
- lbs_pr_info("odd, need to retry this firmware block\n");
+ pr_info("odd, need to retry this firmware block\n");
} else {
retry = 0;
}
if (retry > 20) {
- lbs_pr_err("could not download firmware\n");
+ pr_err("could not download firmware\n");
ret = -ENODEV;
goto done;
}
@@ -709,14 +724,14 @@ static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw)
ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS,
IF_CS_BIT_COMMAND);
if (ret < 0) {
- lbs_pr_err("can't download firmware at 0x%x\n", sent);
+ pr_err("can't download firmware at 0x%x\n", sent);
goto done;
}
}
ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a);
if (ret < 0)
- lbs_pr_err("firmware download failed\n");
+ pr_err("firmware download failed\n");
done:
lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
@@ -750,7 +765,8 @@ static int if_cs_host_to_card(struct lbs_private *priv,
ret = if_cs_send_cmd(priv, buf, nb);
break;
default:
- lbs_pr_err("%s: unsupported type %d\n", __func__, type);
+ netdev_err(priv->dev, "%s: unsupported type %d\n",
+ __func__, type);
}
lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
@@ -779,7 +795,7 @@ static int if_cs_ioprobe(struct pcmcia_device *p_dev, void *priv_data)
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
if (p_dev->resource[1]->end) {
- lbs_pr_err("wrong CIS (check number of IO windows)\n");
+ pr_err("wrong CIS (check number of IO windows)\n");
return -ENODEV;
}
@@ -800,7 +816,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
card = kzalloc(sizeof(struct if_cs_card), GFP_KERNEL);
if (!card) {
- lbs_pr_err("error in kzalloc\n");
+ pr_err("error in kzalloc\n");
goto out;
}
card->p_dev = p_dev;
@@ -809,7 +825,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) {
- lbs_pr_err("error in pcmcia_loop_config\n");
+ pr_err("error in pcmcia_loop_config\n");
goto out1;
}
@@ -825,14 +841,14 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
card->iobase = ioport_map(p_dev->resource[0]->start,
resource_size(p_dev->resource[0]));
if (!card->iobase) {
- lbs_pr_err("error in ioport_map\n");
+ pr_err("error in ioport_map\n");
ret = -EIO;
goto out1;
}
ret = pcmcia_enable_device(p_dev);
if (ret) {
- lbs_pr_err("error in pcmcia_enable_device\n");
+ pr_err("error in pcmcia_enable_device\n");
goto out2;
}
@@ -841,14 +857,14 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
/*
* Most of the libertas cards can do unaligned register access, but some
- * weird ones can not. That's especially true for the CF8305 card.
+ * weird ones cannot. That's especially true for the CF8305 card.
*/
card->align_regs = 0;
card->model = get_model(p_dev->manf_id, p_dev->card_id);
if (card->model == MODEL_UNKNOWN) {
- lbs_pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n",
- p_dev->manf_id, p_dev->card_id);
+ pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n",
+ p_dev->manf_id, p_dev->card_id);
goto out2;
}
@@ -857,20 +873,20 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
if (card->model == MODEL_8305) {
card->align_regs = 1;
if (prod_id < IF_CS_CF8305_B1_REV) {
- lbs_pr_err("8305 rev B0 and older are not supported\n");
+ pr_err("8305 rev B0 and older are not supported\n");
ret = -ENODEV;
goto out2;
}
}
if ((card->model == MODEL_8381) && prod_id < IF_CS_CF8381_B3_REV) {
- lbs_pr_err("8381 rev B2 and older are not supported\n");
+ pr_err("8381 rev B2 and older are not supported\n");
ret = -ENODEV;
goto out2;
}
if ((card->model == MODEL_8385) && prod_id < IF_CS_CF8385_B1_REV) {
- lbs_pr_err("8385 rev B0 and older are not supported\n");
+ pr_err("8385 rev B0 and older are not supported\n");
ret = -ENODEV;
goto out2;
}
@@ -878,7 +894,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
ret = lbs_get_firmware(&p_dev->dev, NULL, NULL, card->model,
&fw_table[0], &helper, &mainfw);
if (ret) {
- lbs_pr_err("failed to find firmware (%d)\n", ret);
+ pr_err("failed to find firmware (%d)\n", ret);
goto out2;
}
@@ -909,18 +925,20 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
ret = request_irq(p_dev->irq, if_cs_interrupt,
IRQF_SHARED, DRV_NAME, card);
if (ret) {
- lbs_pr_err("error in request_irq\n");
+ pr_err("error in request_irq\n");
goto out3;
}
- /* Clear any interrupt cause that happened while sending
- * firmware/initializing card */
+ /*
+ * Clear any interrupt cause that happened while sending
+ * firmware/initializing card
+ */
if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK);
if_cs_enable_ints(card);
/* And finally bring the card up */
if (lbs_start_card(priv) != 0) {
- lbs_pr_err("could not activate card\n");
+ pr_err("could not activate card\n");
goto out3;
}
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index b4de0ca10fe..a7b5cb0c275 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -26,6 +26,8 @@
* if_sdio_card_to_host() to pad the data.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
@@ -409,7 +411,7 @@ static int if_sdio_card_to_host(struct if_sdio_card *card)
out:
if (ret)
- lbs_pr_err("problem fetching packet from firmware\n");
+ pr_err("problem fetching packet from firmware\n");
lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
@@ -446,7 +448,7 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
}
if (ret)
- lbs_pr_err("error %d sending packet to firmware\n", ret);
+ pr_err("error %d sending packet to firmware\n", ret);
sdio_release_host(card->func);
@@ -555,7 +557,7 @@ release:
out:
if (ret)
- lbs_pr_err("failed to load helper firmware\n");
+ pr_err("failed to load helper firmware\n");
lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
return ret;
@@ -669,7 +671,7 @@ release:
out:
if (ret)
- lbs_pr_err("failed to load firmware\n");
+ pr_err("failed to load firmware\n");
lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
return ret;
@@ -723,7 +725,7 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name,
card->model, &fw_table[0], &helper, &mainfw);
if (ret) {
- lbs_pr_err("failed to find firmware (%d)\n", ret);
+ pr_err("failed to find firmware (%d)\n", ret);
goto out;
}
@@ -849,7 +851,7 @@ static int if_sdio_enter_deep_sleep(struct lbs_private *priv)
ret = __lbs_cmd(priv, CMD_802_11_DEEP_SLEEP, &cmd, sizeof(cmd),
lbs_cmd_copyback, (unsigned long) &cmd);
if (ret)
- lbs_pr_err("DEEP_SLEEP cmd failed\n");
+ netdev_err(priv->dev, "DEEP_SLEEP cmd failed\n");
mdelay(200);
return ret;
@@ -865,7 +867,7 @@ static int if_sdio_exit_deep_sleep(struct lbs_private *priv)
sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret);
if (ret)
- lbs_pr_err("sdio_writeb failed!\n");
+ netdev_err(priv->dev, "sdio_writeb failed!\n");
sdio_release_host(card->func);
lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
@@ -882,7 +884,7 @@ static int if_sdio_reset_deep_sleep_wakeup(struct lbs_private *priv)
sdio_writeb(card->func, 0, CONFIGURATION_REG, &ret);
if (ret)
- lbs_pr_err("sdio_writeb failed!\n");
+ netdev_err(priv->dev, "sdio_writeb failed!\n");
sdio_release_host(card->func);
lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
@@ -961,7 +963,7 @@ static int if_sdio_probe(struct sdio_func *func,
}
if (i == func->card->num_info) {
- lbs_pr_err("unable to identify card model\n");
+ pr_err("unable to identify card model\n");
return -ENODEV;
}
@@ -995,7 +997,7 @@ static int if_sdio_probe(struct sdio_func *func,
break;
}
if (i == ARRAY_SIZE(fw_table)) {
- lbs_pr_err("unknown card model 0x%x\n", card->model);
+ pr_err("unknown card model 0x%x\n", card->model);
ret = -ENODEV;
goto free;
}
@@ -1101,7 +1103,7 @@ static int if_sdio_probe(struct sdio_func *func,
lbs_deb_sdio("send function INIT command\n");
if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),
lbs_cmd_copyback, (unsigned long) &cmd))
- lbs_pr_alert("CMD_FUNC_INIT cmd failed\n");
+ netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n");
}
ret = lbs_start_card(priv);
@@ -1163,7 +1165,7 @@ static void if_sdio_remove(struct sdio_func *func)
if (__lbs_cmd(card->priv, CMD_FUNC_SHUTDOWN,
&cmd, sizeof(cmd), lbs_cmd_copyback,
(unsigned long) &cmd))
- lbs_pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n");
+ pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n");
}
@@ -1202,20 +1204,19 @@ static int if_sdio_suspend(struct device *dev)
mmc_pm_flag_t flags = sdio_get_host_pm_caps(func);
- lbs_pr_info("%s: suspend: PM flags = 0x%x\n",
- sdio_func_id(func), flags);
+ dev_info(dev, "%s: suspend: PM flags = 0x%x\n",
+ sdio_func_id(func), flags);
/* If we aren't being asked to wake on anything, we should bail out
* and let the SD stack power down the card.
*/
if (card->priv->wol_criteria == EHS_REMOVE_WAKEUP) {
- lbs_pr_info("Suspend without wake params -- "
- "powering down card.");
+ dev_info(dev, "Suspend without wake params -- powering down card\n");
return -ENOSYS;
}
if (!(flags & MMC_PM_KEEP_POWER)) {
- lbs_pr_err("%s: cannot remain alive while host is suspended\n",
+ dev_err(dev, "%s: cannot remain alive while host is suspended\n",
sdio_func_id(func));
return -ENOSYS;
}
@@ -1237,7 +1238,7 @@ static int if_sdio_resume(struct device *dev)
struct if_sdio_card *card = sdio_get_drvdata(func);
int ret;
- lbs_pr_info("%s: resume: we're back\n", sdio_func_id(func));
+ dev_info(dev, "%s: resume: we're back\n", sdio_func_id(func));
ret = lbs_resume(card->priv);
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index f6c2cd665f4..463352c890d 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -17,6 +17,8 @@
* (at your option) any later version.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/moduleparam.h>
#include <linux/firmware.h>
#include <linux/jiffies.h>
@@ -57,6 +59,7 @@ struct if_spi_card {
/* Handles all SPI communication (except for FW load) */
struct workqueue_struct *workqueue;
struct work_struct packet_work;
+ struct work_struct resume_work;
u8 cmd_buffer[IF_SPI_CMD_BUF_SIZE];
@@ -68,6 +71,9 @@ struct if_spi_card {
/* Protects cmd_packet_list and data_packet_list */
spinlock_t buffer_lock;
+
+ /* True is card suspended */
+ u8 suspended;
};
static void free_if_spi_card(struct if_spi_card *card)
@@ -139,8 +145,10 @@ static void spu_transaction_finish(struct if_spi_card *card)
card->prev_xfer_time = jiffies;
}
-/* Write out a byte buffer to an SPI register,
- * using a series of 16-bit transfers. */
+/*
+ * Write out a byte buffer to an SPI register,
+ * using a series of 16-bit transfers.
+ */
static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
{
int err = 0;
@@ -204,8 +212,10 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
struct spi_transfer dummy_trans;
struct spi_transfer data_trans;
- /* You must take an even number of bytes from the SPU, even if you
- * don't care about the last one. */
+ /*
+ * You must take an even number of bytes from the SPU, even if you
+ * don't care about the last one.
+ */
BUG_ON(len & 0x1);
spu_transaction_init(card);
@@ -254,8 +264,10 @@ static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)
return ret;
}
-/* Read 32 bits from an SPI register.
- * The low 16 bits are read first. */
+/*
+ * Read 32 bits from an SPI register.
+ * The low 16 bits are read first.
+ */
static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)
{
__le32 buf;
@@ -267,13 +279,15 @@ static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)
return err;
}
-/* Keep reading 16 bits from an SPI register until you get the correct result.
+/*
+ * Keep reading 16 bits from an SPI register until you get the correct result.
*
* If mask = 0, the correct result is any non-zero number.
* If mask != 0, the correct result is any number where
* number & target_mask == target
*
- * Returns -ETIMEDOUT if a second passes without the correct result. */
+ * Returns -ETIMEDOUT if a second passes without the correct result.
+ */
static int spu_wait_for_u16(struct if_spi_card *card, u16 reg,
u16 target_mask, u16 target)
{
@@ -293,16 +307,17 @@ static int spu_wait_for_u16(struct if_spi_card *card, u16 reg,
}
udelay(100);
if (time_after(jiffies, timeout)) {
- lbs_pr_err("%s: timeout with val=%02x, "
- "target_mask=%02x, target=%02x\n",
+ pr_err("%s: timeout with val=%02x, target_mask=%02x, target=%02x\n",
__func__, val, target_mask, target);
return -ETIMEDOUT;
}
}
}
-/* Read 16 bits from an SPI register until you receive a specific value.
- * Returns -ETIMEDOUT if a 4 tries pass without success. */
+/*
+ * Read 16 bits from an SPI register until you receive a specific value.
+ * Returns -ETIMEDOUT if a 4 tries pass without success.
+ */
static int spu_wait_for_u32(struct if_spi_card *card, u32 reg, u32 target)
{
int err, try;
@@ -324,8 +339,10 @@ static int spu_set_interrupt_mode(struct if_spi_card *card,
{
int err = 0;
- /* We can suppress a host interrupt by clearing the appropriate
- * bit in the "host interrupt status mask" register */
+ /*
+ * We can suppress a host interrupt by clearing the appropriate
+ * bit in the "host interrupt status mask" register
+ */
if (suppress_host_int) {
err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0);
if (err)
@@ -341,10 +358,12 @@ static int spu_set_interrupt_mode(struct if_spi_card *card,
return err;
}
- /* If auto-interrupts are on, the completion of certain transactions
+ /*
+ * If auto-interrupts are on, the completion of certain transactions
* will trigger an interrupt automatically. If auto-interrupts
* are off, we need to set the "Card Interrupt Cause" register to
- * trigger a card interrupt. */
+ * trigger a card interrupt.
+ */
if (auto_int) {
err = spu_write_u16(card, IF_SPI_HOST_INT_CTRL_REG,
IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO |
@@ -387,7 +406,7 @@ static int spu_set_bus_mode(struct if_spi_card *card, u16 mode)
if (err)
return err;
if ((rval & 0xF) != mode) {
- lbs_pr_err("Can't read bus mode register.\n");
+ pr_err("Can't read bus mode register\n");
return -EIO;
}
return 0;
@@ -398,8 +417,10 @@ static int spu_init(struct if_spi_card *card, int use_dummy_writes)
int err = 0;
u32 delay;
- /* We have to start up in timed delay mode so that we can safely
- * read the Delay Read Register. */
+ /*
+ * We have to start up in timed delay mode so that we can safely
+ * read the Delay Read Register.
+ */
card->use_dummy_writes = 0;
err = spu_set_bus_mode(card,
IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING |
@@ -455,8 +476,10 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card,
/* Load helper firmware image */
while (bytes_remaining > 0) {
- /* Scratch pad 1 should contain the number of bytes we
- * want to download to the firmware */
+ /*
+ * Scratch pad 1 should contain the number of bytes we
+ * want to download to the firmware
+ */
err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG,
HELPER_FW_LOAD_CHUNK_SZ);
if (err)
@@ -468,8 +491,10 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card,
if (err)
goto out;
- /* Feed the data into the command read/write port reg
- * in chunks of 64 bytes */
+ /*
+ * Feed the data into the command read/write port reg
+ * in chunks of 64 bytes
+ */
memset(temp, 0, sizeof(temp));
memcpy(temp, fw,
min(bytes_remaining, HELPER_FW_LOAD_CHUNK_SZ));
@@ -491,9 +516,11 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card,
fw += HELPER_FW_LOAD_CHUNK_SZ;
}
- /* Once the helper / single stage firmware download is complete,
+ /*
+ * Once the helper / single stage firmware download is complete,
* write 0 to scratch pad 1 and interrupt the
- * bootloader. This completes the helper download. */
+ * bootloader. This completes the helper download.
+ */
err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK);
if (err)
goto out;
@@ -508,26 +535,30 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card,
out:
if (err)
- lbs_pr_err("failed to load helper firmware (err=%d)\n", err);
+ pr_err("failed to load helper firmware (err=%d)\n", err);
lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
return err;
}
-/* Returns the length of the next packet the firmware expects us to send
- * Sets crc_err if the previous transfer had a CRC error. */
+/*
+ * Returns the length of the next packet the firmware expects us to send.
+ * Sets crc_err if the previous transfer had a CRC error.
+ */
static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
int *crc_err)
{
u16 len;
int err = 0;
- /* wait until the host interrupt status register indicates
- * that we are ready to download */
+ /*
+ * wait until the host interrupt status register indicates
+ * that we are ready to download
+ */
err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG,
IF_SPI_HIST_CMD_DOWNLOAD_RDY,
IF_SPI_HIST_CMD_DOWNLOAD_RDY);
if (err) {
- lbs_pr_err("timed out waiting for host_int_status\n");
+ pr_err("timed out waiting for host_int_status\n");
return err;
}
@@ -537,9 +568,8 @@ static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
return err;
if (len > IF_SPI_CMD_BUF_SIZE) {
- lbs_pr_err("firmware load device requested a larger "
- "tranfer than we are prepared to "
- "handle. (len = %d)\n", len);
+ pr_err("firmware load device requested a larger transfer than we are prepared to handle (len = %d)\n",
+ len);
return -EIO;
}
if (len & 0x1) {
@@ -555,6 +585,7 @@ static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
static int if_spi_prog_main_firmware(struct if_spi_card *card,
const struct firmware *firmware)
{
+ struct lbs_private *priv = card->priv;
int len, prev_len;
int bytes, crc_err = 0, err = 0;
const u8 *fw;
@@ -568,8 +599,9 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card,
err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0);
if (err) {
- lbs_pr_err("%s: timed out waiting for initial "
- "scratch reg = 0\n", __func__);
+ netdev_err(priv->dev,
+ "%s: timed out waiting for initial scratch reg = 0\n",
+ __func__);
goto out;
}
@@ -583,17 +615,18 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card,
goto out;
}
if (bytes < 0) {
- /* If there are no more bytes left, we would normally
- * expect to have terminated with len = 0 */
- lbs_pr_err("Firmware load wants more bytes "
- "than we have to offer.\n");
+ /*
+ * If there are no more bytes left, we would normally
+ * expect to have terminated with len = 0
+ */
+ netdev_err(priv->dev,
+ "Firmware load wants more bytes than we have to offer.\n");
break;
}
if (crc_err) {
/* Previous transfer failed. */
if (++num_crc_errs > MAX_MAIN_FW_LOAD_CRC_ERR) {
- lbs_pr_err("Too many CRC errors encountered "
- "in firmware load.\n");
+ pr_err("Too many CRC errors encountered in firmware load.\n");
err = -EIO;
goto out;
}
@@ -622,21 +655,20 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card,
prev_len = len;
}
if (bytes > prev_len) {
- lbs_pr_err("firmware load wants fewer bytes than "
- "we have to offer.\n");
+ pr_err("firmware load wants fewer bytes than we have to offer\n");
}
/* Confirm firmware download */
err = spu_wait_for_u32(card, IF_SPI_SCRATCH_4_REG,
SUCCESSFUL_FW_DOWNLOAD_MAGIC);
if (err) {
- lbs_pr_err("failed to confirm the firmware download\n");
+ pr_err("failed to confirm the firmware download\n");
goto out;
}
out:
if (err)
- lbs_pr_err("failed to load firmware (err=%d)\n", err);
+ pr_err("failed to load firmware (err=%d)\n", err);
lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
return err;
}
@@ -656,14 +688,18 @@ static int if_spi_c2h_cmd(struct if_spi_card *card)
u16 len;
u8 i;
- /* We need a buffer big enough to handle whatever people send to
- * hw_host_to_card */
+ /*
+ * We need a buffer big enough to handle whatever people send to
+ * hw_host_to_card
+ */
BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_CMD_BUFFER_SIZE);
BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_UPLD_SIZE);
- /* It's just annoying if the buffer size isn't a multiple of 4, because
- * then we might have len < IF_SPI_CMD_BUF_SIZE but
- * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE */
+ /*
+ * It's just annoying if the buffer size isn't a multiple of 4, because
+ * then we might have len < IF_SPI_CMD_BUF_SIZE but
+ * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE
+ */
BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE % 4 != 0);
lbs_deb_enter(LBS_DEB_SPI);
@@ -673,13 +709,13 @@ static int if_spi_c2h_cmd(struct if_spi_card *card)
if (err)
goto out;
if (!len) {
- lbs_pr_err("%s: error: card has no data for host\n",
+ netdev_err(priv->dev, "%s: error: card has no data for host\n",
__func__);
err = -EINVAL;
goto out;
} else if (len > IF_SPI_CMD_BUF_SIZE) {
- lbs_pr_err("%s: error: response packet too large: "
- "%d bytes, but maximum is %d\n",
+ netdev_err(priv->dev,
+ "%s: error: response packet too large: %d bytes, but maximum is %d\n",
__func__, len, IF_SPI_CMD_BUF_SIZE);
err = -EINVAL;
goto out;
@@ -701,7 +737,7 @@ static int if_spi_c2h_cmd(struct if_spi_card *card)
out:
if (err)
- lbs_pr_err("%s: err=%d\n", __func__, err);
+ netdev_err(priv->dev, "%s: err=%d\n", __func__, err);
lbs_deb_leave(LBS_DEB_SPI);
return err;
}
@@ -709,6 +745,7 @@ out:
/* Move data from the card to the host */
static int if_spi_c2h_data(struct if_spi_card *card)
{
+ struct lbs_private *priv = card->priv;
struct sk_buff *skb;
char *data;
u16 len;
@@ -721,13 +758,13 @@ static int if_spi_c2h_data(struct if_spi_card *card)
if (err)
goto out;
if (!len) {
- lbs_pr_err("%s: error: card has no data for host\n",
+ netdev_err(priv->dev, "%s: error: card has no data for host\n",
__func__);
err = -EINVAL;
goto out;
} else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
- lbs_pr_err("%s: error: card has %d bytes of data, but "
- "our maximum skb size is %zu\n",
+ netdev_err(priv->dev,
+ "%s: error: card has %d bytes of data, but our maximum skb size is %zu\n",
__func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
err = -EINVAL;
goto out;
@@ -759,7 +796,7 @@ free_skb:
dev_kfree_skb(skb);
out:
if (err)
- lbs_pr_err("%s: err=%d\n", __func__, err);
+ netdev_err(priv->dev, "%s: err=%d\n", __func__, err);
lbs_deb_leave(LBS_DEB_SPI);
return err;
}
@@ -768,6 +805,7 @@ out:
static void if_spi_h2c(struct if_spi_card *card,
struct if_spi_packet *packet, int type)
{
+ struct lbs_private *priv = card->priv;
int err = 0;
u16 int_type, port_reg;
@@ -781,7 +819,8 @@ static void if_spi_h2c(struct if_spi_card *card,
port_reg = IF_SPI_CMD_RDWRPORT_REG;
break;
default:
- lbs_pr_err("can't transfer buffer of type %d\n", type);
+ netdev_err(priv->dev, "can't transfer buffer of type %d\n",
+ type);
err = -EINVAL;
goto out;
}
@@ -795,7 +834,7 @@ out:
kfree(packet);
if (err)
- lbs_pr_err("%s: error %d\n", __func__, err);
+ netdev_err(priv->dev, "%s: error %d\n", __func__, err);
}
/* Inform the host about a card event */
@@ -819,7 +858,7 @@ static void if_spi_e2h(struct if_spi_card *card)
lbs_queue_event(priv, cause & 0xff);
out:
if (err)
- lbs_pr_err("%s: error %d\n", __func__, err);
+ netdev_err(priv->dev, "%s: error %d\n", __func__, err);
}
static void if_spi_host_to_card_worker(struct work_struct *work)
@@ -829,17 +868,21 @@ static void if_spi_host_to_card_worker(struct work_struct *work)
u16 hiStatus;
unsigned long flags;
struct if_spi_packet *packet;
+ struct lbs_private *priv;
card = container_of(work, struct if_spi_card, packet_work);
+ priv = card->priv;
lbs_deb_enter(LBS_DEB_SPI);
- /* Read the host interrupt status register to see what we
- * can do. */
+ /*
+ * Read the host interrupt status register to see what we
+ * can do.
+ */
err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG,
&hiStatus);
if (err) {
- lbs_pr_err("I/O error\n");
+ netdev_err(priv->dev, "I/O error\n");
goto err;
}
@@ -854,12 +897,15 @@ static void if_spi_host_to_card_worker(struct work_struct *work)
goto err;
}
- /* workaround: in PS mode, the card does not set the Command
- * Download Ready bit, but it sets TX Download Ready. */
+ /*
+ * workaround: in PS mode, the card does not set the Command
+ * Download Ready bit, but it sets TX Download Ready.
+ */
if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY ||
(card->priv->psstate != PS_STATE_FULL_POWER &&
(hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) {
- /* This means two things. First of all,
+ /*
+ * This means two things. First of all,
* if there was a previous command sent, the card has
* successfully received it.
* Secondly, it is now ready to download another
@@ -867,8 +913,7 @@ static void if_spi_host_to_card_worker(struct work_struct *work)
*/
lbs_host_to_card_done(card->priv);
- /* Do we have any command packets from the host to
- * send? */
+ /* Do we have any command packets from the host to send? */
packet = NULL;
spin_lock_irqsave(&card->buffer_lock, flags);
if (!list_empty(&card->cmd_packet_list)) {
@@ -882,8 +927,7 @@ static void if_spi_host_to_card_worker(struct work_struct *work)
if_spi_h2c(card, packet, MVMS_CMD);
}
if (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY) {
- /* Do we have any data packets from the host to
- * send? */
+ /* Do we have any data packets from the host to send? */
packet = NULL;
spin_lock_irqsave(&card->buffer_lock, flags);
if (!list_empty(&card->data_packet_list)) {
@@ -901,7 +945,7 @@ static void if_spi_host_to_card_worker(struct work_struct *work)
err:
if (err)
- lbs_pr_err("%s: got error %d\n", __func__, err);
+ netdev_err(priv->dev, "%s: got error %d\n", __func__, err);
lbs_deb_leave(LBS_DEB_SPI);
}
@@ -910,7 +954,8 @@ err:
* Host to Card
*
* Called from Libertas to transfer some data to the WLAN device
- * We can't sleep here. */
+ * We can't sleep here.
+ */
static int if_spi_host_to_card(struct lbs_private *priv,
u8 type, u8 *buf, u16 nb)
{
@@ -923,7 +968,8 @@ static int if_spi_host_to_card(struct lbs_private *priv,
lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb);
if (nb == 0) {
- lbs_pr_err("%s: invalid size requested: %d\n", __func__, nb);
+ netdev_err(priv->dev, "%s: invalid size requested: %d\n",
+ __func__, nb);
err = -EINVAL;
goto out;
}
@@ -951,7 +997,8 @@ static int if_spi_host_to_card(struct lbs_private *priv,
spin_unlock_irqrestore(&card->buffer_lock, flags);
break;
default:
- lbs_pr_err("can't transfer buffer of type %d", type);
+ netdev_err(priv->dev, "can't transfer buffer of type %d\n",
+ type);
err = -EINVAL;
break;
}
@@ -984,6 +1031,7 @@ static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id)
static int if_spi_init_card(struct if_spi_card *card)
{
+ struct lbs_private *priv = card->priv;
struct spi_device *spi = card->spi;
int err, i;
u32 scratch;
@@ -1012,8 +1060,8 @@ static int if_spi_init_card(struct if_spi_card *card)
break;
}
if (i == ARRAY_SIZE(fw_table)) {
- lbs_pr_err("Unsupported chip_id: 0x%02x\n",
- card->card_id);
+ netdev_err(priv->dev, "Unsupported chip_id: 0x%02x\n",
+ card->card_id);
err = -ENODEV;
goto out;
}
@@ -1022,7 +1070,8 @@ static int if_spi_init_card(struct if_spi_card *card)
card->card_id, &fw_table[0], &helper,
&mainfw);
if (err) {
- lbs_pr_err("failed to find firmware (%d)\n", err);
+ netdev_err(priv->dev, "failed to find firmware (%d)\n",
+ err);
goto out;
}
@@ -1057,6 +1106,28 @@ out:
return err;
}
+static void if_spi_resume_worker(struct work_struct *work)
+{
+ struct if_spi_card *card;
+
+ card = container_of(work, struct if_spi_card, resume_work);
+
+ if (card->suspended) {
+ if (card->pdata->setup)
+ card->pdata->setup(card->spi);
+
+ /* Init card ... */
+ if_spi_init_card(card);
+
+ enable_irq(card->spi->irq);
+
+ /* And resume it ... */
+ lbs_resume(card->priv);
+
+ card->suspended = 0;
+ }
+}
+
static int __devinit if_spi_probe(struct spi_device *spi)
{
struct if_spi_card *card;
@@ -1099,14 +1170,17 @@ static int __devinit if_spi_probe(struct spi_device *spi)
if (err)
goto free_card;
- /* Register our card with libertas.
- * This will call alloc_etherdev */
+ /*
+ * Register our card with libertas.
+ * This will call alloc_etherdev.
+ */
priv = lbs_add_card(card, &spi->dev);
if (!priv) {
err = -ENOMEM;
goto free_card;
}
card->priv = priv;
+ priv->setup_fw_on_resume = 1;
priv->card = card;
priv->hw_host_to_card = if_spi_host_to_card;
priv->enter_deep_sleep = NULL;
@@ -1117,17 +1191,20 @@ static int __devinit if_spi_probe(struct spi_device *spi)
/* Initialize interrupt handling stuff. */
card->workqueue = create_workqueue("libertas_spi");
INIT_WORK(&card->packet_work, if_spi_host_to_card_worker);
+ INIT_WORK(&card->resume_work, if_spi_resume_worker);
err = request_irq(spi->irq, if_spi_host_interrupt,
IRQF_TRIGGER_FALLING, "libertas_spi", card);
if (err) {
- lbs_pr_err("can't get host irq line-- request_irq failed\n");
+ pr_err("can't get host irq line-- request_irq failed\n");
goto terminate_workqueue;
}
- /* Start the card.
+ /*
+ * Start the card.
* This will call register_netdev, and we'll start
- * getting interrupts... */
+ * getting interrupts...
+ */
err = lbs_start_card(priv);
if (err)
goto release_irq;
@@ -1161,6 +1238,8 @@ static int __devexit libertas_spi_remove(struct spi_device *spi)
lbs_deb_spi("libertas_spi_remove\n");
lbs_deb_enter(LBS_DEB_SPI);
+ cancel_work_sync(&card->resume_work);
+
lbs_stop_card(priv);
lbs_remove_card(priv); /* will call free_netdev */
@@ -1174,6 +1253,40 @@ static int __devexit libertas_spi_remove(struct spi_device *spi)
return 0;
}
+static int if_spi_suspend(struct device *dev)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct if_spi_card *card = spi_get_drvdata(spi);
+
+ if (!card->suspended) {
+ lbs_suspend(card->priv);
+ flush_workqueue(card->workqueue);
+ disable_irq(spi->irq);
+
+ if (card->pdata->teardown)
+ card->pdata->teardown(spi);
+ card->suspended = 1;
+ }
+
+ return 0;
+}
+
+static int if_spi_resume(struct device *dev)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct if_spi_card *card = spi_get_drvdata(spi);
+
+ /* Schedule delayed work */
+ schedule_work(&card->resume_work);
+
+ return 0;
+}
+
+static const struct dev_pm_ops if_spi_pm_ops = {
+ .suspend = if_spi_suspend,
+ .resume = if_spi_resume,
+};
+
static struct spi_driver libertas_spi_driver = {
.probe = if_spi_probe,
.remove = __devexit_p(libertas_spi_remove),
@@ -1181,6 +1294,7 @@ static struct spi_driver libertas_spi_driver = {
.name = "libertas_spi",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
+ .pm = &if_spi_pm_ops,
},
};
diff --git a/drivers/net/wireless/libertas/if_spi.h b/drivers/net/wireless/libertas/if_spi.h
index d2ac1dcd7e2..e450e31fd11 100644
--- a/drivers/net/wireless/libertas/if_spi.h
+++ b/drivers/net/wireless/libertas/if_spi.h
@@ -86,34 +86,34 @@
#define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dc) (dc & 0x000000ff)
/***************** IF_SPI_HOST_INT_CTRL_REG *****************/
-/** Host Interrupt Control bit : Wake up */
+/* Host Interrupt Control bit : Wake up */
#define IF_SPI_HICT_WAKE_UP (1<<0)
-/** Host Interrupt Control bit : WLAN ready */
+/* Host Interrupt Control bit : WLAN ready */
#define IF_SPI_HICT_WLAN_READY (1<<1)
/*#define IF_SPI_HICT_FIFO_FIRST_HALF_EMPTY (1<<2) */
/*#define IF_SPI_HICT_FIFO_SECOND_HALF_EMPTY (1<<3) */
/*#define IF_SPI_HICT_IRQSRC_WLAN (1<<4) */
-/** Host Interrupt Control bit : Tx auto download */
+/* Host Interrupt Control bit : Tx auto download */
#define IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO (1<<5)
-/** Host Interrupt Control bit : Rx auto upload */
+/* Host Interrupt Control bit : Rx auto upload */
#define IF_SPI_HICT_RX_UPLOAD_OVER_AUTO (1<<6)
-/** Host Interrupt Control bit : Command auto download */
+/* Host Interrupt Control bit : Command auto download */
#define IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO (1<<7)
-/** Host Interrupt Control bit : Command auto upload */
+/* Host Interrupt Control bit : Command auto upload */
#define IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO (1<<8)
/***************** IF_SPI_CARD_INT_CAUSE_REG *****************/
-/** Card Interrupt Case bit : Tx download over */
+/* Card Interrupt Case bit : Tx download over */
#define IF_SPI_CIC_TX_DOWNLOAD_OVER (1<<0)
-/** Card Interrupt Case bit : Rx upload over */
+/* Card Interrupt Case bit : Rx upload over */
#define IF_SPI_CIC_RX_UPLOAD_OVER (1<<1)
-/** Card Interrupt Case bit : Command download over */
+/* Card Interrupt Case bit : Command download over */
#define IF_SPI_CIC_CMD_DOWNLOAD_OVER (1<<2)
-/** Card Interrupt Case bit : Host event */
+/* Card Interrupt Case bit : Host event */
#define IF_SPI_CIC_HOST_EVENT (1<<3)
-/** Card Interrupt Case bit : Command upload over */
+/* Card Interrupt Case bit : Command upload over */
#define IF_SPI_CIC_CMD_UPLOAD_OVER (1<<4)
-/** Card Interrupt Case bit : Power down */
+/* Card Interrupt Case bit : Power down */
#define IF_SPI_CIC_POWER_DOWN (1<<5)
/***************** IF_SPI_CARD_INT_STATUS_REG *****************/
@@ -138,51 +138,51 @@
#define IF_SPI_HICU_CMD_RD_FIFO_UNDERFLOW (1<<10)
/***************** IF_SPI_HOST_INT_STATUS_REG *****************/
-/** Host Interrupt Status bit : Tx download ready */
+/* Host Interrupt Status bit : Tx download ready */
#define IF_SPI_HIST_TX_DOWNLOAD_RDY (1<<0)
-/** Host Interrupt Status bit : Rx upload ready */
+/* Host Interrupt Status bit : Rx upload ready */
#define IF_SPI_HIST_RX_UPLOAD_RDY (1<<1)
-/** Host Interrupt Status bit : Command download ready */
+/* Host Interrupt Status bit : Command download ready */
#define IF_SPI_HIST_CMD_DOWNLOAD_RDY (1<<2)
-/** Host Interrupt Status bit : Card event */
+/* Host Interrupt Status bit : Card event */
#define IF_SPI_HIST_CARD_EVENT (1<<3)
-/** Host Interrupt Status bit : Command upload ready */
+/* Host Interrupt Status bit : Command upload ready */
#define IF_SPI_HIST_CMD_UPLOAD_RDY (1<<4)
-/** Host Interrupt Status bit : I/O write FIFO overflow */
+/* Host Interrupt Status bit : I/O write FIFO overflow */
#define IF_SPI_HIST_IO_WR_FIFO_OVERFLOW (1<<5)
-/** Host Interrupt Status bit : I/O read FIFO underflow */
+/* Host Interrupt Status bit : I/O read FIFO underflow */
#define IF_SPI_HIST_IO_RD_FIFO_UNDRFLOW (1<<6)
-/** Host Interrupt Status bit : Data write FIFO overflow */
+/* Host Interrupt Status bit : Data write FIFO overflow */
#define IF_SPI_HIST_DATA_WR_FIFO_OVERFLOW (1<<7)
-/** Host Interrupt Status bit : Data read FIFO underflow */
+/* Host Interrupt Status bit : Data read FIFO underflow */
#define IF_SPI_HIST_DATA_RD_FIFO_UNDERFLOW (1<<8)
-/** Host Interrupt Status bit : Command write FIFO overflow */
+/* Host Interrupt Status bit : Command write FIFO overflow */
#define IF_SPI_HIST_CMD_WR_FIFO_OVERFLOW (1<<9)
-/** Host Interrupt Status bit : Command read FIFO underflow */
+/* Host Interrupt Status bit : Command read FIFO underflow */
#define IF_SPI_HIST_CMD_RD_FIFO_UNDERFLOW (1<<10)
/***************** IF_SPI_HOST_INT_STATUS_MASK_REG *****************/
-/** Host Interrupt Status Mask bit : Tx download ready */
+/* Host Interrupt Status Mask bit : Tx download ready */
#define IF_SPI_HISM_TX_DOWNLOAD_RDY (1<<0)
-/** Host Interrupt Status Mask bit : Rx upload ready */
+/* Host Interrupt Status Mask bit : Rx upload ready */
#define IF_SPI_HISM_RX_UPLOAD_RDY (1<<1)
-/** Host Interrupt Status Mask bit : Command download ready */
+/* Host Interrupt Status Mask bit : Command download ready */
#define IF_SPI_HISM_CMD_DOWNLOAD_RDY (1<<2)
-/** Host Interrupt Status Mask bit : Card event */
+/* Host Interrupt Status Mask bit : Card event */
#define IF_SPI_HISM_CARDEVENT (1<<3)
-/** Host Interrupt Status Mask bit : Command upload ready */
+/* Host Interrupt Status Mask bit : Command upload ready */
#define IF_SPI_HISM_CMD_UPLOAD_RDY (1<<4)
-/** Host Interrupt Status Mask bit : I/O write FIFO overflow */
+/* Host Interrupt Status Mask bit : I/O write FIFO overflow */
#define IF_SPI_HISM_IO_WR_FIFO_OVERFLOW (1<<5)
-/** Host Interrupt Status Mask bit : I/O read FIFO underflow */
+/* Host Interrupt Status Mask bit : I/O read FIFO underflow */
#define IF_SPI_HISM_IO_RD_FIFO_UNDERFLOW (1<<6)
-/** Host Interrupt Status Mask bit : Data write FIFO overflow */
+/* Host Interrupt Status Mask bit : Data write FIFO overflow */
#define IF_SPI_HISM_DATA_WR_FIFO_OVERFLOW (1<<7)
-/** Host Interrupt Status Mask bit : Data write FIFO underflow */
+/* Host Interrupt Status Mask bit : Data write FIFO underflow */
#define IF_SPI_HISM_DATA_RD_FIFO_UNDERFLOW (1<<8)
-/** Host Interrupt Status Mask bit : Command write FIFO overflow */
+/* Host Interrupt Status Mask bit : Command write FIFO overflow */
#define IF_SPI_HISM_CMD_WR_FIFO_OVERFLOW (1<<9)
-/** Host Interrupt Status Mask bit : Command write FIFO underflow */
+/* Host Interrupt Status Mask bit : Command write FIFO underflow */
#define IF_SPI_HISM_CMD_RD_FIFO_UNDERFLOW (1<<10)
/***************** IF_SPI_SPU_BUS_MODE_REG *****************/
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 6524c70363d..b5acc393a65 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -1,6 +1,9 @@
-/**
- * This file contains functions used in USB interface module.
- */
+/*
+ * This file contains functions used in USB interface module.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
@@ -66,7 +69,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp);
/* sysfs hooks */
-/**
+/*
* Set function to write firmware to device's persistent memory
*/
static ssize_t if_usb_firmware_set(struct device *dev,
@@ -85,7 +88,7 @@ static ssize_t if_usb_firmware_set(struct device *dev,
return ret;
}
-/**
+/*
* lbs_flash_fw attribute to be exported per ethX interface through sysfs
* (/sys/class/net/ethX/lbs_flash_fw). Use this like so to write firmware to
* the device's persistent memory:
@@ -94,7 +97,14 @@ static ssize_t if_usb_firmware_set(struct device *dev,
static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set);
/**
- * Set function to write firmware to device's persistent memory
+ * if_usb_boot2_set - write firmware to device's persistent memory
+ *
+ * @dev: target device
+ * @attr: device attributes
+ * @buf: firmware buffer to write
+ * @count: number of bytes to write
+ *
+ * returns: number of bytes written or negative error code
*/
static ssize_t if_usb_boot2_set(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
@@ -112,7 +122,7 @@ static ssize_t if_usb_boot2_set(struct device *dev,
return ret;
}
-/**
+/*
* lbs_flash_boot2 attribute to be exported per ethX interface through sysfs
* (/sys/class/net/ethX/lbs_flash_boot2). Use this like so to write firmware
* to the device's persistent memory:
@@ -121,9 +131,10 @@ static ssize_t if_usb_boot2_set(struct device *dev,
static DEVICE_ATTR(lbs_flash_boot2, 0200, NULL, if_usb_boot2_set);
/**
- * @brief call back function to handle the status of the URB
- * @param urb pointer to urb structure
- * @return N/A
+ * if_usb_write_bulk_callback - callback function to handle the status
+ * of the URB
+ * @urb: pointer to &urb structure
+ * returns: N/A
*/
static void if_usb_write_bulk_callback(struct urb *urb)
{
@@ -145,14 +156,14 @@ static void if_usb_write_bulk_callback(struct urb *urb)
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);
+ pr_info("URB in failure status: %d\n", urb->status);
}
}
/**
- * @brief free tx/rx urb, skb and rx buffer
- * @param cardp pointer if_usb_card
- * @return N/A
+ * if_usb_free - free tx/rx urb, skb and rx buffer
+ * @cardp: pointer to &if_usb_card
+ * returns: N/A
*/
static void if_usb_free(struct if_usb_card *cardp)
{
@@ -195,7 +206,7 @@ static void if_usb_setup_firmware(struct lbs_private *priv)
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");
+ netdev_info(priv->dev, "Firmware does not seem to support PS mode\n");
priv->fwcapinfo &= ~FW_CAPINFO_PS;
} else {
if (le16_to_cpu(wake_method.method) == CMD_WAKE_METHOD_COMMAND_INT) {
@@ -204,7 +215,8 @@ static void if_usb_setup_firmware(struct lbs_private *priv)
/* The versions which boot up this way don't seem to
work even if we set it to the command interrupt */
priv->fwcapinfo &= ~FW_CAPINFO_PS;
- lbs_pr_info("Firmware doesn't wake via command interrupt; disabling PS mode\n");
+ netdev_info(priv->dev,
+ "Firmware doesn't wake via command interrupt; disabling PS mode\n");
}
}
}
@@ -216,7 +228,7 @@ static void if_usb_fw_timeo(unsigned long priv)
if (cardp->fwdnldover) {
lbs_deb_usb("Download complete, no event. Assuming success\n");
} else {
- lbs_pr_err("Download timed out\n");
+ pr_err("Download timed out\n");
cardp->surprise_removed = 1;
}
wake_up(&cardp->fw_wq);
@@ -231,10 +243,10 @@ static void if_usb_reset_olpc_card(struct lbs_private *priv)
#endif
/**
- * @brief sets the configuration values
- * @param ifnum interface number
- * @param id pointer to usb_device_id
- * @return 0 on success, error code on failure
+ * if_usb_probe - sets the configuration values
+ * @intf: &usb_interface pointer
+ * @id: pointer to usb_device_id
+ * returns: 0 on success, error code on failure
*/
static int if_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
@@ -250,7 +262,7 @@ static int if_usb_probe(struct usb_interface *intf,
cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL);
if (!cardp) {
- lbs_pr_err("Out of memory allocating private data.\n");
+ pr_err("Out of memory allocating private data\n");
goto error;
}
@@ -340,10 +352,12 @@ static int if_usb_probe(struct usb_interface *intf,
usb_set_intfdata(intf, cardp);
if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_fw))
- lbs_pr_err("cannot register lbs_flash_fw attribute\n");
+ netdev_err(priv->dev,
+ "cannot register lbs_flash_fw attribute\n");
if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2))
- lbs_pr_err("cannot register lbs_flash_boot2 attribute\n");
+ netdev_err(priv->dev,
+ "cannot register lbs_flash_boot2 attribute\n");
/*
* EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
@@ -366,9 +380,9 @@ error:
}
/**
- * @brief free resource and cleanup
- * @param intf USB interface structure
- * @return N/A
+ * if_usb_disconnect - free resource and cleanup
+ * @intf: USB interface structure
+ * returns: N/A
*/
static void if_usb_disconnect(struct usb_interface *intf)
{
@@ -398,9 +412,9 @@ static void if_usb_disconnect(struct usb_interface *intf)
}
/**
- * @brief This function download FW
- * @param priv pointer to struct lbs_private
- * @return 0
+ * if_usb_send_fw_pkt - download FW
+ * @cardp: pointer to &struct if_usb_card
+ * returns: 0
*/
static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
{
@@ -486,11 +500,11 @@ static int if_usb_reset_device(struct if_usb_card *cardp)
}
/**
- * @brief This function transfer the data to the device.
- * @param priv pointer to struct lbs_private
- * @param payload pointer to payload data
- * @param nb data length
- * @return 0 or -1
+ * usb_tx_block - transfer the data to the device
+ * @cardp: pointer to &struct if_usb_card
+ * @payload: pointer to payload data
+ * @nb: data length
+ * returns: 0 for success or negative error code
*/
static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb)
{
@@ -528,7 +542,7 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
int ret = -1;
if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) {
- lbs_pr_err("No free skb\n");
+ pr_err("No free skb\n");
goto rx_ret;
}
@@ -587,7 +601,7 @@ static void if_usb_receive_fwload(struct urb *urb)
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");
+ pr_info("Firmware ready event received\n");
wake_up(&cardp->fw_wq);
} else {
lbs_deb_usb("Waiting for confirmation; got %x %x\n",
@@ -614,20 +628,20 @@ static void if_usb_receive_fwload(struct urb *urb)
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");
+ pr_info("Firmware already seems alive; resetting\n");
cardp->bootcmdresp = -1;
} else {
- lbs_pr_info("boot cmd response wrong magic number (0x%x)\n",
+ 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) &&
(bootcmdresp.cmd != BOOT_CMD_UPDATE_FW) &&
(bootcmdresp.cmd != BOOT_CMD_UPDATE_BOOT2)) {
- lbs_pr_info("boot cmd response cmd_tag error (%d)\n",
- bootcmdresp.cmd);
+ 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);
+ pr_info("boot cmd response result error (%d)\n",
+ bootcmdresp.result);
} else {
cardp->bootcmdresp = 1;
lbs_deb_usbd(&cardp->udev->dev,
@@ -727,11 +741,11 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
}
/**
- * @brief This function reads of the packet into the upload buff,
- * wake up the main thread and initialise the Rx callack.
+ * if_usb_receive - read the packet into the upload buffer,
+ * wake up the main thread and initialise the Rx callack
*
- * @param urb pointer to struct urb
- * @return N/A
+ * @urb: pointer to &struct urb
+ * returns: N/A
*/
static void if_usb_receive(struct urb *urb)
{
@@ -802,12 +816,12 @@ rx_exit:
}
/**
- * @brief This function downloads data to FW
- * @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
+ * if_usb_host_to_card - downloads data to FW
+ * @priv: pointer to &struct lbs_private structure
+ * @type: type of data
+ * @payload: pointer to data buffer
+ * @nb: number of bytes
+ * returns: 0 for success or negative error code
*/
static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
uint8_t *payload, uint16_t nb)
@@ -831,10 +845,11 @@ static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
}
/**
- * @brief This function issues Boot command to the Boot2 code
- * @param ivalue 1:Boot from FW by USB-Download
- * 2:Boot from FW in EEPROM
- * @return 0
+ * if_usb_issue_boot_command - issues Boot command to the Boot2 code
+ * @cardp: pointer to &if_usb_card
+ * @ivalue: 1:Boot from FW by USB-Download
+ * 2:Boot from FW in EEPROM
+ * returns: 0 for success or negative error code
*/
static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue)
{
@@ -853,11 +868,11 @@ static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue)
/**
- * @brief This function checks the validity of Boot2/FW image.
+ * check_fwfile_format - check the validity of Boot2/FW image
*
- * @param data pointer to image
- * len image length
- * @return 0 or -1
+ * @data: pointer to image
+ * @totlen: image length
+ * returns: 0 (good) or 1 (failure)
*/
static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
{
@@ -892,7 +907,7 @@ static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
} while (!exit);
if (ret)
- lbs_pr_err("firmware file format check FAIL\n");
+ pr_err("firmware file format check FAIL\n");
else
lbs_deb_fw("firmware file format check PASS\n");
@@ -901,13 +916,13 @@ static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
/**
-* @brief This function programs the firmware subject to cmd
+* if_usb_prog_firmware - programs the firmware subject to cmd
*
-* @param cardp the if_usb_card descriptor
-* fwname firmware or boot2 image file name
-* cmd either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW,
-* or BOOT_CMD_UPDATE_BOOT2.
-* @return 0 or error code
+* @cardp: the if_usb_card descriptor
+* @fwname: firmware or boot2 image file name
+* @cmd: either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW,
+* or BOOT_CMD_UPDATE_BOOT2.
+* returns: 0 or error code
*/
static int if_usb_prog_firmware(struct if_usb_card *cardp,
const char *fwname, int cmd)
@@ -989,7 +1004,7 @@ static int __if_usb_prog_firmware(struct if_usb_card *cardp,
ret = get_fw(cardp, fwname);
if (ret) {
- lbs_pr_err("failed to find firmware (%d)\n", ret);
+ pr_err("failed to find firmware (%d)\n", ret);
goto done;
}
@@ -1064,13 +1079,13 @@ restart:
usb_kill_urb(cardp->rx_urb);
if (!cardp->fwdnldover) {
- lbs_pr_info("failed to load fw, resetting device!\n");
+ pr_info("failed to load fw, resetting device!\n");
if (--reset_count >= 0) {
if_usb_reset_device(cardp);
goto restart;
}
- lbs_pr_info("FW download failure, time = %d ms\n", i * 100);
+ pr_info("FW download failure, time = %d ms\n", i * 100);
ret = -EIO;
goto release_fw;
}
diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h
index d819e7e3c9a..6e42eac331d 100644
--- a/drivers/net/wireless/libertas/if_usb.h
+++ b/drivers/net/wireless/libertas/if_usb.h
@@ -6,9 +6,9 @@
struct lbs_private;
-/**
- * This file contains definition for USB interface.
- */
+/*
+ * This file contains definition for USB interface.
+ */
#define CMD_TYPE_REQUEST 0xF00DFACE
#define CMD_TYPE_DATA 0xBEADC0DE
#define CMD_TYPE_INDICATION 0xBEEFFACE
@@ -40,7 +40,7 @@ struct bootcmdresp
uint8_t pad[2];
};
-/** USB card description structure*/
+/* USB card description structure*/
struct if_usb_card {
struct usb_device *udev;
uint32_t model; /* MODEL_* */
@@ -77,7 +77,7 @@ struct if_usb_card {
__le16 boot2_version;
};
-/** fwheader */
+/* fwheader */
struct fwheader {
__le32 dnldcmd;
__le32 baseaddr;
@@ -86,14 +86,14 @@ struct fwheader {
};
#define FW_MAX_DATA_BLK_SIZE 600
-/** FWData */
+/* FWData */
struct fwdata {
struct fwheader hdr;
__le32 seqnum;
uint8_t data[0];
};
-/** fwsyncheader */
+/* fwsyncheader */
struct fwsyncheader {
__le32 cmd;
__le32 seqnum;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index ca8149cd5bd..8c40949cb07 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1,8 +1,10 @@
-/**
- * This file contains the major functions in WLAN
- * driver. It includes init, exit, open, close and main
- * thread etc..
- */
+/*
+ * This file contains the major functions in WLAN
+ * driver. It includes init, exit, open, close and main
+ * thread etc..
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/moduleparam.h>
#include <linux/delay.h>
@@ -34,19 +36,25 @@ unsigned int lbs_debug;
EXPORT_SYMBOL_GPL(lbs_debug);
module_param_named(libertas_debug, lbs_debug, int, 0644);
+unsigned int lbs_disablemesh;
+EXPORT_SYMBOL_GPL(lbs_disablemesh);
+module_param_named(libertas_disablemesh, lbs_disablemesh, int, 0644);
-/* This global structure is used to send the confirm_sleep command as
- * fast as possible down to the firmware. */
+
+/*
+ * This global structure is used to send the confirm_sleep command as
+ * fast as possible down to the firmware.
+ */
struct cmd_confirm_sleep confirm_sleep;
-/**
+/*
* the table to keep region code
*/
u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
{ 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
-/**
+/*
* FW rate table. FW refers to rates by their index in this table, not by the
* rate value itself. Values of 0x00 are
* reserved positions.
@@ -57,10 +65,10 @@ static u8 fw_data_rates[MAX_RATES] =
};
/**
- * @brief use index to get the data rate
+ * lbs_fw_index_to_data_rate - use index to get the data rate
*
- * @param idx The index of data rate
- * @return data rate or 0
+ * @idx: The index of data rate
+ * returns: data rate or 0
*/
u32 lbs_fw_index_to_data_rate(u8 idx)
{
@@ -70,10 +78,10 @@ u32 lbs_fw_index_to_data_rate(u8 idx)
}
/**
- * @brief use rate to get the index
+ * lbs_data_rate_to_fw_index - use rate to get the index
*
- * @param rate data rate
- * @return index or 0
+ * @rate: data rate
+ * returns: index or 0
*/
u8 lbs_data_rate_to_fw_index(u32 rate)
{
@@ -91,10 +99,10 @@ u8 lbs_data_rate_to_fw_index(u32 rate)
/**
- * @brief This function opens the ethX interface
+ * lbs_dev_open - open the ethX interface
*
- * @param dev A pointer to net_device structure
- * @return 0 or -EBUSY if monitor mode active
+ * @dev: A pointer to &net_device structure
+ * returns: 0 or -EBUSY if monitor mode active
*/
static int lbs_dev_open(struct net_device *dev)
{
@@ -120,10 +128,10 @@ static int lbs_dev_open(struct net_device *dev)
}
/**
- * @brief This function closes the ethX interface
+ * lbs_eth_stop - close the ethX interface
*
- * @param dev A pointer to net_device structure
- * @return 0
+ * @dev: A pointer to &net_device structure
+ * returns: 0
*/
static int lbs_eth_stop(struct net_device *dev)
{
@@ -147,28 +155,6 @@ static int lbs_eth_stop(struct net_device *dev)
return 0;
}
-static void lbs_tx_timeout(struct net_device *dev)
-{
- struct lbs_private *priv = dev->ml_priv;
-
- lbs_deb_enter(LBS_DEB_TX);
-
- lbs_pr_err("tx watch dog timeout\n");
-
- dev->trans_start = jiffies; /* prevent tx timeout */
-
- if (priv->currenttxskb)
- lbs_send_tx_feedback(priv, 0);
-
- /* XX: Shouldn't we also call into the hw-specific driver
- to kick it somehow? */
- lbs_host_to_card_done(priv);
-
- /* FIXME: reset the card */
-
- lbs_deb_leave(LBS_DEB_TX);
-}
-
void lbs_host_to_card_done(struct lbs_private *priv)
{
unsigned long flags;
@@ -336,12 +322,12 @@ void lbs_set_multicast_list(struct net_device *dev)
}
/**
- * @brief This function handles the major jobs in the LBS driver.
+ * lbs_thread - 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 lbs_thread structure
- * @return 0
+ * @data: A pointer to &lbs_thread structure
+ * returns: 0
*/
static int lbs_thread(void *data)
{
@@ -462,8 +448,8 @@ static int lbs_thread(void *data)
if (priv->cmd_timed_out && priv->cur_cmd) {
struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
- lbs_pr_info("Timeout submitting command 0x%04x\n",
- le16_to_cpu(cmdnode->cmdbuf->command));
+ netdev_info(dev, "Timeout submitting command 0x%04x\n",
+ le16_to_cpu(cmdnode->cmdbuf->command));
lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
if (priv->reset_card)
priv->reset_card(priv);
@@ -490,8 +476,8 @@ static int lbs_thread(void *data)
* after firmware fixes it
*/
priv->psstate = PS_STATE_AWAKE;
- lbs_pr_alert("ignore PS_SleepConfirm in "
- "non-connected state\n");
+ netdev_alert(dev,
+ "ignore PS_SleepConfirm in non-connected state\n");
}
}
@@ -540,11 +526,11 @@ static int lbs_thread(void *data)
}
/**
- * @brief This function gets the HW spec from the firmware and sets
- * some basic parameters.
+ * lbs_setup_firmware - gets the HW spec from the firmware and sets
+ * some basic parameters
*
- * @param priv A pointer to struct lbs_private structure
- * @return 0 or -1
+ * @priv: A pointer to &struct lbs_private structure
+ * returns: 0 or -1
*/
static int lbs_setup_firmware(struct lbs_private *priv)
{
@@ -585,7 +571,8 @@ int lbs_suspend(struct lbs_private *priv)
if (priv->is_deep_sleep) {
ret = lbs_set_deep_sleep(priv, 0);
if (ret) {
- lbs_pr_err("deep sleep cancellation failed: %d\n", ret);
+ netdev_err(priv->dev,
+ "deep sleep cancellation failed: %d\n", ret);
return ret;
}
priv->deep_sleep_required = 1;
@@ -618,7 +605,8 @@ int lbs_resume(struct lbs_private *priv)
priv->deep_sleep_required = 0;
ret = lbs_set_deep_sleep(priv, 1);
if (ret)
- lbs_pr_err("deep sleep activation failed: %d\n", ret);
+ netdev_err(priv->dev,
+ "deep sleep activation failed: %d\n", ret);
}
if (priv->setup_fw_on_resume)
@@ -630,8 +618,10 @@ int lbs_resume(struct lbs_private *priv)
EXPORT_SYMBOL_GPL(lbs_resume);
/**
- * This function handles the timeout of command sending.
- * It will re-send the same command again.
+ * lbs_cmd_timeout_handler - handles the timeout of command sending.
+ * It will re-send the same command again.
+ *
+ * @data: &struct lbs_private pointer
*/
static void lbs_cmd_timeout_handler(unsigned long data)
{
@@ -644,8 +634,8 @@ static void lbs_cmd_timeout_handler(unsigned long data)
if (!priv->cur_cmd)
goto out;
- lbs_pr_info("command 0x%04x timed out\n",
- le16_to_cpu(priv->cur_cmd->cmdbuf->command));
+ netdev_info(priv->dev, "command 0x%04x timed out\n",
+ le16_to_cpu(priv->cur_cmd->cmdbuf->command));
priv->cmd_timed_out = 1;
wake_up_interruptible(&priv->waitq);
@@ -655,8 +645,10 @@ out:
}
/**
- * This function put the device back to deep sleep mode when timer expires
- * and no activity (command, event, data etc.) is detected.
+ * auto_deepsleep_timer_fn - put the device back to deep sleep mode when
+ * timer expires and no activity (command, event, data etc.) is detected.
+ * @data: &struct lbs_private pointer
+ * returns: N/A
*/
static void auto_deepsleep_timer_fn(unsigned long data)
{
@@ -748,7 +740,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
/* Allocate the command buffers */
if (lbs_allocate_cmd_buffer(priv)) {
- lbs_pr_err("Out of memory allocating command buffers\n");
+ pr_err("Out of memory allocating command buffers\n");
ret = -ENOMEM;
goto out;
}
@@ -758,7 +750,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
/* Create the event FIFO */
ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
if (ret) {
- lbs_pr_err("Out of memory allocating event FIFO buffer\n");
+ pr_err("Out of memory allocating event FIFO buffer\n");
goto out;
}
@@ -785,18 +777,18 @@ static const struct net_device_ops lbs_netdev_ops = {
.ndo_stop = lbs_eth_stop,
.ndo_start_xmit = lbs_hard_start_xmit,
.ndo_set_mac_address = lbs_set_mac_address,
- .ndo_tx_timeout = lbs_tx_timeout,
.ndo_set_multicast_list = lbs_set_multicast_list,
.ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
};
/**
- * @brief This function adds the card. it will probe the
+ * lbs_add_card - adds the card. It will probe the
* card, allocate the lbs_priv and initialize the device.
*
- * @param card A pointer to card
- * @return A pointer to struct lbs_private structure
+ * @card: A pointer to card
+ * @dmdev: A pointer to &struct device
+ * returns: A pointer to &struct lbs_private structure
*/
struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
{
@@ -809,7 +801,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
/* Allocate an Ethernet device and register it */
wdev = lbs_cfg_alloc(dmdev);
if (IS_ERR(wdev)) {
- lbs_pr_err("cfg80211 init failed\n");
+ pr_err("cfg80211 init failed\n");
goto done;
}
@@ -818,7 +810,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
priv->wdev = wdev;
if (lbs_init_adapter(priv)) {
- lbs_pr_err("failed to initialize adapter structure.\n");
+ pr_err("failed to initialize adapter structure\n");
goto err_wdev;
}
@@ -950,17 +942,20 @@ int lbs_start_card(struct lbs_private *priv)
goto done;
if (lbs_cfg_register(priv)) {
- lbs_pr_err("cannot register device\n");
+ pr_err("cannot register device\n");
goto done;
}
lbs_update_channel(priv);
- lbs_init_mesh(priv);
+ if (!lbs_disablemesh)
+ lbs_init_mesh(priv);
+ else
+ pr_info("%s: mesh disabled\n", dev->name);
lbs_debugfs_init_one(priv, dev);
- lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);
+ netdev_info(dev, "Marvell WLAN 802.11 adapter\n");
ret = 0;
@@ -1057,19 +1052,19 @@ void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx)
EXPORT_SYMBOL_GPL(lbs_notify_command_response);
/**
- * @brief Retrieves two-stage firmware
+ * lbs_get_firmware - Retrieves two-stage firmware
*
- * @param dev A pointer to device structure
- * @param user_helper User-defined helper firmware file
- * @param user_mainfw User-defined main firmware file
- * @param card_model Bus-specific card model ID used to filter firmware table
- * elements
- * @param fw_table Table of firmware file names and device model numbers
- * terminated by an entry with a NULL helper name
- * @param helper On success, the helper firmware; caller must free
- * @param mainfw On success, the main firmware; caller must free
+ * @dev: A pointer to &device structure
+ * @user_helper: User-defined helper firmware file
+ * @user_mainfw: User-defined main firmware file
+ * @card_model: Bus-specific card model ID used to filter firmware table
+ * elements
+ * @fw_table: Table of firmware file names and device model numbers
+ * terminated by an entry with a NULL helper name
+ * @helper: On success, the helper firmware; caller must free
+ * @mainfw: On success, the main firmware; caller must free
*
- * @return 0 on success, non-zero on failure
+ * returns: 0 on success, non-zero on failure
*/
int lbs_get_firmware(struct device *dev, const char *user_helper,
const char *user_mainfw, u32 card_model,
@@ -1087,16 +1082,16 @@ int lbs_get_firmware(struct device *dev, const char *user_helper,
if (user_helper) {
ret = request_firmware(helper, user_helper, dev);
if (ret) {
- lbs_pr_err("couldn't find helper firmware %s",
- user_helper);
+ dev_err(dev, "couldn't find helper firmware %s\n",
+ user_helper);
goto fail;
}
}
if (user_mainfw) {
ret = request_firmware(mainfw, user_mainfw, dev);
if (ret) {
- lbs_pr_err("couldn't find main firmware %s",
- user_mainfw);
+ dev_err(dev, "couldn't find main firmware %s\n",
+ user_mainfw);
goto fail;
}
}
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c
index 9d097b9c800..24cf06680c6 100644
--- a/drivers/net/wireless/libertas/mesh.c
+++ b/drivers/net/wireless/libertas/mesh.c
@@ -1,3 +1,5 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/delay.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
@@ -16,12 +18,15 @@
* Mesh sysfs support
*/
-/**
+/*
* Attributes exported through sysfs
*/
/**
- * @brief Get function for sysfs attribute anycast_mask
+ * lbs_anycast_get - Get function for sysfs attribute anycast_mask
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
*/
static ssize_t lbs_anycast_get(struct device *dev,
struct device_attribute *attr, char * buf)
@@ -40,7 +45,11 @@ static ssize_t lbs_anycast_get(struct device *dev,
}
/**
- * @brief Set function for sysfs attribute anycast_mask
+ * lbs_anycast_set - Set function for sysfs attribute anycast_mask
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
*/
static ssize_t lbs_anycast_set(struct device *dev,
struct device_attribute *attr, const char * buf, size_t count)
@@ -62,7 +71,10 @@ static ssize_t lbs_anycast_set(struct device *dev,
}
/**
- * @brief Get function for sysfs attribute prb_rsp_limit
+ * lbs_prb_rsp_limit_get - Get function for sysfs attribute prb_rsp_limit
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
*/
static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -85,7 +97,11 @@ static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
}
/**
- * @brief Set function for sysfs attribute prb_rsp_limit
+ * lbs_prb_rsp_limit_set - Set function for sysfs attribute prb_rsp_limit
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
*/
static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
@@ -114,7 +130,10 @@ static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
}
/**
- * Get function for sysfs attribute mesh
+ * lbs_mesh_get - Get function for sysfs attribute mesh
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
*/
static ssize_t lbs_mesh_get(struct device *dev,
struct device_attribute *attr, char * buf)
@@ -124,7 +143,11 @@ static ssize_t lbs_mesh_get(struct device *dev,
}
/**
- * Set function for sysfs attribute mesh
+ * lbs_mesh_set - Set function for sysfs attribute mesh
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
*/
static ssize_t lbs_mesh_set(struct device *dev,
struct device_attribute *attr, const char * buf, size_t count)
@@ -151,19 +174,19 @@ static ssize_t lbs_mesh_set(struct device *dev,
return count;
}
-/**
+/*
* 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);
-/**
+/*
* 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);
-/**
+/*
* prb_rsp_limit attribute to be exported per mshX interface
* through sysfs (/sys/class/net/mshX/prb_rsp_limit)
*/
@@ -246,7 +269,7 @@ int lbs_init_mesh(struct lbs_private *priv)
lbs_add_mesh(priv);
if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
- lbs_pr_err("cannot register lbs_mesh attribute\n");
+ netdev_err(dev, "cannot register lbs_mesh attribute\n");
ret = 1;
}
@@ -274,10 +297,10 @@ int lbs_deinit_mesh(struct lbs_private *priv)
/**
- * @brief This function closes the mshX interface
+ * lbs_mesh_stop - close the mshX interface
*
- * @param dev A pointer to net_device structure
- * @return 0
+ * @dev: A pointer to &net_device structure
+ * returns: 0
*/
static int lbs_mesh_stop(struct net_device *dev)
{
@@ -301,10 +324,10 @@ static int lbs_mesh_stop(struct net_device *dev)
}
/**
- * @brief This function opens the mshX interface
+ * lbs_mesh_dev_open - open the mshX interface
*
- * @param dev A pointer to net_device structure
- * @return 0 or -EBUSY if monitor mode active
+ * @dev: A pointer to &net_device structure
+ * returns: 0 or -EBUSY if monitor mode active
*/
static int lbs_mesh_dev_open(struct net_device *dev)
{
@@ -342,10 +365,10 @@ static const struct net_device_ops mesh_netdev_ops = {
};
/**
- * @brief This function adds mshX interface
+ * lbs_add_mesh - add mshX interface
*
- * @param priv A pointer to the struct lbs_private structure
- * @return 0 if successful, -X otherwise
+ * @priv: A pointer to the &struct lbs_private structure
+ * returns: 0 if successful, -X otherwise
*/
int lbs_add_mesh(struct lbs_private *priv)
{
@@ -374,7 +397,7 @@ int lbs_add_mesh(struct lbs_private *priv)
/* Register virtual mesh interface */
ret = register_netdev(mesh_dev);
if (ret) {
- lbs_pr_err("cannot register mshX virtual interface\n");
+ pr_err("cannot register mshX virtual interface\n");
goto err_free;
}
@@ -456,13 +479,13 @@ void lbs_mesh_set_txpd(struct lbs_private *priv,
*/
/**
- * @brief Add or delete Mesh Blinding Table entries
+ * lbs_mesh_bt_add_del - Add or delete Mesh Blinding Table entries
*
- * @param priv A pointer to struct lbs_private structure
- * @param add TRUE to add the entry, FALSE to delete it
- * @param addr1 Destination address to blind or unblind
+ * @priv: A pointer to &struct lbs_private structure
+ * @add: TRUE to add the entry, FALSE to delete it
+ * @addr1: Destination address to blind or unblind
*
- * @return 0 on success, error on failure
+ * returns: 0 on success, error on failure
*/
int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1)
{
@@ -493,11 +516,11 @@ int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1)
}
/**
- * @brief Reset/clear the mesh blinding table
+ * lbs_mesh_bt_reset - Reset/clear the mesh blinding table
*
- * @param priv A pointer to struct lbs_private structure
+ * @priv: A pointer to &struct lbs_private structure
*
- * @return 0 on success, error on failure
+ * returns: 0 on success, error on failure
*/
int lbs_mesh_bt_reset(struct lbs_private *priv)
{
@@ -517,17 +540,18 @@ int lbs_mesh_bt_reset(struct lbs_private *priv)
}
/**
- * @brief Gets the inverted status of the mesh blinding table
+ * lbs_mesh_bt_get_inverted - Gets the inverted status of the mesh
+ * blinding table
*
- * Normally the firmware "blinds" or ignores traffic from mesh nodes in the
- * table, but an inverted table allows *only* traffic from nodes listed in
- * the table.
+ * Normally the firmware "blinds" or ignores traffic from mesh nodes in the
+ * table, but an inverted table allows *only* traffic from nodes listed in
+ * the table.
*
- * @param priv A pointer to struct lbs_private structure
- * @param invert On success, TRUE if the blinding table is inverted,
- * FALSE if it is not inverted
+ * @priv: A pointer to &struct lbs_private structure
+ * @inverted: On success, TRUE if the blinding table is inverted,
+ * FALSE if it is not inverted
*
- * @return 0 on success, error on failure
+ * returns: 0 on success, error on failure
*/
int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted)
{
@@ -551,18 +575,19 @@ int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted)
}
/**
- * @brief Sets the inverted status of the mesh blinding table
+ * lbs_mesh_bt_set_inverted - Sets the inverted status of the mesh
+ * blinding table
*
- * Normally the firmware "blinds" or ignores traffic from mesh nodes in the
- * table, but an inverted table allows *only* traffic from nodes listed in
- * the table.
+ * Normally the firmware "blinds" or ignores traffic from mesh nodes in the
+ * table, but an inverted table allows *only* traffic from nodes listed in
+ * the table.
*
- * @param priv A pointer to struct lbs_private structure
- * @param invert TRUE to invert the blinding table (only traffic from
- * listed nodes allowed), FALSE to return it
- * to normal state (listed nodes ignored)
+ * @priv: A pointer to &struct lbs_private structure
+ * @inverted: TRUE to invert the blinding table (only traffic from
+ * listed nodes allowed), FALSE to return it
+ * to normal state (listed nodes ignored)
*
- * @return 0 on success, error on failure
+ * returns: 0 on success, error on failure
*/
int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted)
{
@@ -583,13 +608,13 @@ int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted)
}
/**
- * @brief List an entry in the mesh blinding table
+ * lbs_mesh_bt_get_entry - List an entry in the mesh blinding table
*
- * @param priv A pointer to struct lbs_private structure
- * @param id The ID of the entry to list
- * @param addr1 MAC address associated with the table entry
+ * @priv: A pointer to &struct lbs_private structure
+ * @id: The ID of the entry to list
+ * @addr1: MAC address associated with the table entry
*
- * @return 0 on success, error on failure
+ * returns: 0 on success, error on failure
*/
int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1)
{
@@ -614,14 +639,14 @@ int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1)
}
/**
- * @brief Access the mesh forwarding table
+ * lbs_cmd_fwt_access - Access the mesh forwarding table
*
- * @param priv A pointer to struct lbs_private structure
- * @param cmd_action The forwarding table action to perform
- * @param cmd The pre-filled FWT_ACCESS command
+ * @priv: A pointer to &struct lbs_private structure
+ * @cmd_action: The forwarding table action to perform
+ * @cmd: The pre-filled FWT_ACCESS command
*
- * @return 0 on success and 'cmd' will be filled with the
- * firmware's response
+ * returns: 0 on success and 'cmd' will be filled with the
+ * firmware's response
*/
int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action,
struct cmd_ds_fwt_access *cmd)
@@ -774,7 +799,10 @@ static int mesh_get_default_parameters(struct device *dev,
}
/**
- * @brief Get function for sysfs attribute bootflag
+ * bootflag_get - Get function for sysfs attribute bootflag
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
*/
static ssize_t bootflag_get(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -791,7 +819,11 @@ static ssize_t bootflag_get(struct device *dev,
}
/**
- * @brief Set function for sysfs attribute bootflag
+ * bootflag_set - Set function for sysfs attribute bootflag
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
*/
static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
@@ -817,7 +849,10 @@ static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
}
/**
- * @brief Get function for sysfs attribute boottime
+ * boottime_get - Get function for sysfs attribute boottime
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
*/
static ssize_t boottime_get(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -834,7 +869,11 @@ static ssize_t boottime_get(struct device *dev,
}
/**
- * @brief Set function for sysfs attribute boottime
+ * boottime_set - Set function for sysfs attribute boottime
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
*/
static ssize_t boottime_set(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
@@ -869,7 +908,10 @@ static ssize_t boottime_set(struct device *dev,
}
/**
- * @brief Get function for sysfs attribute channel
+ * channel_get - Get function for sysfs attribute channel
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
*/
static ssize_t channel_get(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -886,7 +928,11 @@ static ssize_t channel_get(struct device *dev,
}
/**
- * @brief Set function for sysfs attribute channel
+ * channel_set - Set function for sysfs attribute channel
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
*/
static ssize_t channel_set(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
@@ -912,7 +958,10 @@ static ssize_t channel_set(struct device *dev, struct device_attribute *attr,
}
/**
- * @brief Get function for sysfs attribute mesh_id
+ * mesh_id_get - Get function for sysfs attribute mesh_id
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
*/
static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -926,7 +975,7 @@ static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
return ret;
if (defs.meshie.val.mesh_id_len > IEEE80211_MAX_SSID_LEN) {
- lbs_pr_err("inconsistent mesh ID length");
+ dev_err(dev, "inconsistent mesh ID length\n");
defs.meshie.val.mesh_id_len = IEEE80211_MAX_SSID_LEN;
}
@@ -938,7 +987,11 @@ static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
}
/**
- * @brief Set function for sysfs attribute mesh_id
+ * mesh_id_set - Set function for sysfs attribute mesh_id
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
*/
static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
@@ -980,7 +1033,10 @@ static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
}
/**
- * @brief Get function for sysfs attribute protocol_id
+ * protocol_id_get - Get function for sysfs attribute protocol_id
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
*/
static ssize_t protocol_id_get(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -997,7 +1053,11 @@ static ssize_t protocol_id_get(struct device *dev,
}
/**
- * @brief Set function for sysfs attribute protocol_id
+ * protocol_id_set - Set function for sysfs attribute protocol_id
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
*/
static ssize_t protocol_id_set(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
@@ -1034,7 +1094,10 @@ static ssize_t protocol_id_set(struct device *dev,
}
/**
- * @brief Get function for sysfs attribute metric_id
+ * metric_id_get - Get function for sysfs attribute metric_id
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
*/
static ssize_t metric_id_get(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -1051,7 +1114,11 @@ static ssize_t metric_id_get(struct device *dev,
}
/**
- * @brief Set function for sysfs attribute metric_id
+ * metric_id_set - Set function for sysfs attribute metric_id
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
*/
static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
@@ -1088,7 +1155,10 @@ static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
}
/**
- * @brief Get function for sysfs attribute capability
+ * capability_get - Get function for sysfs attribute capability
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
*/
static ssize_t capability_get(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -1105,7 +1175,11 @@ static ssize_t capability_get(struct device *dev,
}
/**
- * @brief Set function for sysfs attribute capability
+ * capability_set - Set function for sysfs attribute capability
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
*/
static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
diff --git a/drivers/net/wireless/libertas/mesh.h b/drivers/net/wireless/libertas/mesh.h
index afb2e8dead3..ee95c73ed5f 100644
--- a/drivers/net/wireless/libertas/mesh.h
+++ b/drivers/net/wireless/libertas/mesh.h
@@ -1,6 +1,6 @@
-/**
- * Contains all definitions needed for the Libertas' MESH implementation.
- */
+/*
+ * Contains all definitions needed for the Libertas' MESH implementation.
+ */
#ifndef _LBS_MESH_H_
#define _LBS_MESH_H_
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index a2b1df21d28..fdb0448301a 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -1,6 +1,9 @@
-/**
- * This file contains the handling of RX in wlan driver.
- */
+/*
+ * This file contains the handling of RX in wlan driver.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/etherdevice.h>
#include <linux/slab.h>
#include <linux/types.h>
@@ -40,12 +43,12 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
struct sk_buff *skb);
/**
- * @brief This function processes received packet and forwards it
- * to kernel/upper layer
+ * lbs_process_rxed_packet - processes received packet and forwards it
+ * to kernel/upper layer
*
- * @param priv A pointer to struct lbs_private
- * @param skb A pointer to skb which includes the received packet
- * @return 0 or -1
+ * @priv: A pointer to &struct lbs_private
+ * @skb: A pointer to skb which includes the received packet
+ * returns: 0 or -1
*/
int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
{
@@ -156,11 +159,11 @@ done:
EXPORT_SYMBOL_GPL(lbs_process_rxed_packet);
/**
- * @brief This function converts Tx/Rx rates from the Marvell WLAN format
- * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s)
+ * convert_mv_rate_to_radiotap - converts Tx/Rx rates from Marvell WLAN format
+ * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s)
*
- * @param rate Input rate
- * @return Output Rate (0 if invalid)
+ * @rate: Input rate
+ * returns: Output Rate (0 if invalid)
*/
static u8 convert_mv_rate_to_radiotap(u8 rate)
{
@@ -191,17 +194,17 @@ static u8 convert_mv_rate_to_radiotap(u8 rate)
case 12: /* 54 Mbps */
return 108;
}
- lbs_pr_alert("Invalid Marvell WLAN rate %i\n", rate);
+ pr_alert("Invalid Marvell WLAN rate %i\n", rate);
return 0;
}
/**
- * @brief This function processes a received 802.11 packet and forwards it
- * to kernel/upper layer
+ * process_rxed_802_11_packet - processes a received 802.11 packet and forwards
+ * it to kernel/upper layer
*
- * @param priv A pointer to struct lbs_private
- * @param skb A pointer to skb which includes the received packet
- * @return 0 or -1
+ * @priv: A pointer to &struct lbs_private
+ * @skb: A pointer to skb which includes the received packet
+ * returns: 0 or -1
*/
static int process_rxed_802_11_packet(struct lbs_private *priv,
struct sk_buff *skb)
@@ -248,7 +251,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
/* 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__);
+ netdev_alert(dev, "%s: couldn't pskb_expand_head\n", __func__);
ret = -ENOMEM;
kfree_skb(skb);
goto done;
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index 8000ca6165d..bbb95f88dc0 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -1,6 +1,6 @@
-/**
- * This file contains the handling of TX in wlan driver.
- */
+/*
+ * This file contains the handling of TX in wlan driver.
+ */
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/sched.h>
@@ -13,11 +13,11 @@
#include "dev.h"
/**
- * @brief This function converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE
- * units (500 Kb/s) into Marvell WLAN format (see Table 8 in Section 3.2.1)
+ * convert_radiotap_rate_to_mv - converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE
+ * units (500 Kb/s) into Marvell WLAN format (see Table 8 in Section 3.2.1)
*
- * @param rate Input rate
- * @return Output Rate (0 if invalid)
+ * @rate: Input rate
+ * returns: Output Rate (0 if invalid)
*/
static u32 convert_radiotap_rate_to_mv(u8 rate)
{
@@ -51,12 +51,12 @@ static u32 convert_radiotap_rate_to_mv(u8 rate)
}
/**
- * @brief This function checks the conditions and sends packet to IF
- * layer if everything is ok.
+ * lbs_hard_start_xmit - checks the conditions and sends packet to IF
+ * layer if everything is ok
*
- * @param priv A pointer to struct lbs_private structure
- * @param skb A pointer to skb which includes TX packet
- * @return 0 or -1
+ * @skb: A pointer to skb which includes TX packet
+ * @dev: A pointer to the &struct net_device
+ * returns: 0 or -1
*/
netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
@@ -168,13 +168,13 @@ netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
/**
- * @brief This function sends to the host the last transmitted packet,
- * filling the radiotap headers with transmission information.
+ * lbs_send_tx_feedback - sends to the host the last transmitted packet,
+ * filling the radiotap headers with transmission information.
*
- * @param priv A pointer to struct lbs_private structure
- * @param status A 32 bit value containing transmission status.
+ * @priv: A pointer to &struct lbs_private structure
+ * @try_count: A 32-bit value containing transmission retry status.
*
- * @returns void
+ * returns: void
*/
void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count)
{
diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h
index 462fbb4cb74..cf1d9b047ee 100644
--- a/drivers/net/wireless/libertas/types.h
+++ b/drivers/net/wireless/libertas/types.h
@@ -1,6 +1,6 @@
-/**
- * This header file contains definition for global types
- */
+/*
+ * This header file contains definition for global types
+ */
#ifndef _LBS_TYPES_H_
#define _LBS_TYPES_H_
@@ -54,7 +54,7 @@ union ieee_phy_param_set {
struct ieee_ie_ds_param_set ds;
} __packed;
-/** TLV type ID definition */
+/* TLV type ID definition */
#define PROPRIETARY_TLV_BASE_ID 0x0100
/* Terminating TLV type */
@@ -96,7 +96,7 @@ union ieee_phy_param_set {
#define TLV_TYPE_MESH_ID (PROPRIETARY_TLV_BASE_ID + 37)
#define TLV_TYPE_OLD_MESH_ID (PROPRIETARY_TLV_BASE_ID + 291)
-/** TLV related data structures*/
+/* TLV related data structures */
struct mrvl_ie_header {
__le16 type;
__le16 len;
@@ -177,7 +177,7 @@ struct mrvl_ie_auth_type {
__le16 auth;
} __packed;
-/** Local Power capability */
+/* Local Power capability */
struct mrvl_ie_power_capability {
struct mrvl_ie_header header;
s8 minpower;
@@ -235,9 +235,11 @@ struct mrvl_ie_ledbhv {
struct led_bhv ledbhv[1];
} __packed;
-/* Meant to be packed as the value member of a struct ieee80211_info_element.
+/*
+ * Meant to be packed as the value member of a struct ieee80211_info_element.
* Note that the len member of the ieee80211_info_element varies depending on
- * the mesh_id_len */
+ * the mesh_id_len
+ */
struct mrvl_meshie_val {
uint8_t oui[3];
uint8_t type;
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index f4f4257a9d6..9d4a40ee16c 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1515,19 +1515,10 @@ static int __init init_mac80211_hwsim(void)
if (hwsim_mon == NULL)
goto failed;
- rtnl_lock();
-
- err = dev_alloc_name(hwsim_mon, hwsim_mon->name);
+ err = register_netdev(hwsim_mon);
if (err < 0)
goto failed_mon;
-
- err = register_netdevice(hwsim_mon);
- if (err < 0)
- goto failed_mon;
-
- rtnl_unlock();
-
return 0;
failed_mon:
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
new file mode 100644
index 00000000000..916183d3900
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -0,0 +1,744 @@
+/*
+ * Marvell Wireless LAN device driver: 802.11n
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+/*
+ * Fills HT capability information field, AMPDU Parameters field, HT extended
+ * capability field, and supported MCS set fields.
+ *
+ * HT capability information field, AMPDU Parameters field, supported MCS set
+ * fields are retrieved from cfg80211 stack
+ *
+ * RD responder bit to set to clear in the extended capability header.
+ */
+void
+mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type,
+ struct mwifiex_ie_types_htcap *ht_cap)
+{
+ uint16_t ht_ext_cap = le16_to_cpu(ht_cap->ht_cap.extended_ht_cap_info);
+ struct ieee80211_supported_band *sband =
+ priv->wdev->wiphy->bands[radio_type];
+
+ ht_cap->ht_cap.ampdu_params_info =
+ (sband->ht_cap.ampdu_factor &
+ IEEE80211_HT_AMPDU_PARM_FACTOR)|
+ ((sband->ht_cap.ampdu_density <<
+ IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT) &
+ IEEE80211_HT_AMPDU_PARM_DENSITY);
+
+ memcpy((u8 *) &ht_cap->ht_cap.mcs, &sband->ht_cap.mcs,
+ sizeof(sband->ht_cap.mcs));
+
+ if (priv->bss_mode == NL80211_IFTYPE_STATION ||
+ (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
+ /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
+ SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask);
+
+ /* Clear RD responder bit */
+ ht_ext_cap &= ~IEEE80211_HT_EXT_CAP_RD_RESPONDER;
+
+ ht_cap->ht_cap.cap_info = cpu_to_le16(sband->ht_cap.cap);
+ ht_cap->ht_cap.extended_ht_cap_info = cpu_to_le16(ht_ext_cap);
+}
+
+/*
+ * This function returns the pointer to an entry in BA Stream
+ * table which matches the requested BA status.
+ */
+static struct mwifiex_tx_ba_stream_tbl *
+mwifiex_11n_get_tx_ba_stream_status(struct mwifiex_private *priv,
+ enum mwifiex_ba_status ba_status)
+{
+ struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
+ if (tx_ba_tsr_tbl->ba_status == ba_status) {
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock,
+ flags);
+ return tx_ba_tsr_tbl;
+ }
+ }
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
+ return NULL;
+}
+
+/*
+ * This function handles the command response of delete a block
+ * ack request.
+ *
+ * The function checks the response success status and takes action
+ * accordingly (send an add BA request in case of success, or recreate
+ * the deleted stream in case of failure, if the add BA was also
+ * initiated by us).
+ */
+int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ int tid;
+ struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl;
+ struct host_cmd_ds_11n_delba *del_ba =
+ (struct host_cmd_ds_11n_delba *) &resp->params.del_ba;
+ uint16_t del_ba_param_set = le16_to_cpu(del_ba->del_ba_param_set);
+
+ tid = del_ba_param_set >> DELBA_TID_POS;
+ if (del_ba->del_result == BA_RESULT_SUCCESS) {
+ mwifiex_11n_delete_ba_stream_tbl(priv, tid,
+ del_ba->peer_mac_addr, TYPE_DELBA_SENT,
+ INITIATOR_BIT(del_ba_param_set));
+
+ tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv,
+ BA_STREAM_SETUP_INPROGRESS);
+ if (tx_ba_tbl)
+ mwifiex_send_addba(priv, tx_ba_tbl->tid,
+ tx_ba_tbl->ra);
+ } else { /*
+ * In case of failure, recreate the deleted stream in case
+ * we initiated the ADDBA
+ */
+ if (INITIATOR_BIT(del_ba_param_set)) {
+ mwifiex_11n_create_tx_ba_stream_tbl(priv,
+ del_ba->peer_mac_addr, tid,
+ BA_STREAM_SETUP_INPROGRESS);
+
+ tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv,
+ BA_STREAM_SETUP_INPROGRESS);
+ if (tx_ba_tbl)
+ mwifiex_11n_delete_ba_stream_tbl(priv,
+ tx_ba_tbl->tid, tx_ba_tbl->ra,
+ TYPE_DELBA_SENT, true);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of add a block
+ * ack request.
+ *
+ * Handling includes changing the header fields to CPU formats, checking
+ * the response success status and taking actions accordingly (delete the
+ * BA stream table in case of failure).
+ */
+int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ int tid;
+ struct host_cmd_ds_11n_addba_rsp *add_ba_rsp =
+ (struct host_cmd_ds_11n_addba_rsp *) &resp->params.add_ba_rsp;
+ struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl;
+
+ add_ba_rsp->ssn = cpu_to_le16((le16_to_cpu(add_ba_rsp->ssn))
+ & SSN_MASK);
+
+ tid = (le16_to_cpu(add_ba_rsp->block_ack_param_set)
+ & IEEE80211_ADDBA_PARAM_TID_MASK)
+ >> BLOCKACKPARAM_TID_POS;
+ if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) {
+ tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid,
+ add_ba_rsp->peer_mac_addr);
+ if (tx_ba_tbl) {
+ dev_dbg(priv->adapter->dev, "info: BA stream complete\n");
+ tx_ba_tbl->ba_status = BA_STREAM_SETUP_COMPLETE;
+ } else {
+ dev_err(priv->adapter->dev, "BA stream not created\n");
+ }
+ } else {
+ mwifiex_11n_delete_ba_stream_tbl(priv, tid,
+ add_ba_rsp->peer_mac_addr,
+ TYPE_DELBA_SENT, true);
+ if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT)
+ priv->aggr_prio_tbl[tid].ampdu_ap =
+ BA_STREAM_NOT_ALLOWED;
+ }
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of 11n configuration request.
+ *
+ * Handling includes changing the header fields into CPU format.
+ */
+int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf)
+{
+ struct mwifiex_ds_11n_tx_cfg *tx_cfg;
+ struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg;
+
+ if (data_buf) {
+ tx_cfg = (struct mwifiex_ds_11n_tx_cfg *) data_buf;
+ tx_cfg->tx_htcap = le16_to_cpu(htcfg->ht_tx_cap);
+ tx_cfg->tx_htinfo = le16_to_cpu(htcfg->ht_tx_info);
+ }
+ return 0;
+}
+
+/*
+ * This function prepares command of reconfigure Tx buffer.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting Tx buffer size (for SET only)
+ * - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd, int cmd_action,
+ void *data_buf)
+{
+ struct host_cmd_ds_txbuf_cfg *tx_buf = &cmd->params.tx_buf;
+ u16 action = (u16) cmd_action;
+ u16 buf_size = *((u16 *) data_buf);
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_RECONFIGURE_TX_BUFF);
+ cmd->size =
+ cpu_to_le16(sizeof(struct host_cmd_ds_txbuf_cfg) + S_DS_GEN);
+ tx_buf->action = cpu_to_le16(action);
+ switch (action) {
+ case HostCmd_ACT_GEN_SET:
+ dev_dbg(priv->adapter->dev, "cmd: set tx_buf=%d\n", buf_size);
+ tx_buf->buff_size = cpu_to_le16(buf_size);
+ break;
+ case HostCmd_ACT_GEN_GET:
+ default:
+ tx_buf->buff_size = 0;
+ break;
+ }
+ return 0;
+}
+
+/*
+ * This function prepares command of AMSDU aggregation control.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting AMSDU control parameters (for SET only)
+ * - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
+ int cmd_action, void *data_buf)
+{
+ struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl =
+ &cmd->params.amsdu_aggr_ctrl;
+ u16 action = (u16) cmd_action;
+ struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl =
+ (struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf;
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_AMSDU_AGGR_CTRL);
+ cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_amsdu_aggr_ctrl)
+ + S_DS_GEN);
+ amsdu_ctrl->action = cpu_to_le16(action);
+ switch (action) {
+ case HostCmd_ACT_GEN_SET:
+ amsdu_ctrl->enable = cpu_to_le16(aa_ctrl->enable);
+ amsdu_ctrl->curr_buf_size = 0;
+ break;
+ case HostCmd_ACT_GEN_GET:
+ default:
+ amsdu_ctrl->curr_buf_size = 0;
+ break;
+ }
+ return 0;
+}
+
+/*
+ * This function handles the command response of AMSDU aggregation
+ * control request.
+ *
+ * Handling includes changing the header fields into CPU format.
+ */
+int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp,
+ void *data_buf)
+{
+ struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl;
+ struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl =
+ &resp->params.amsdu_aggr_ctrl;
+
+ if (data_buf) {
+ amsdu_aggr_ctrl =
+ (struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf;
+ amsdu_aggr_ctrl->enable = le16_to_cpu(amsdu_ctrl->enable);
+ amsdu_aggr_ctrl->curr_buf_size =
+ le16_to_cpu(amsdu_ctrl->curr_buf_size);
+ }
+ return 0;
+}
+
+/*
+ * This function prepares 11n configuration command.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting HT Tx capability and HT Tx information fields
+ * - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd,
+ u16 cmd_action, void *data_buf)
+{
+ struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg;
+ struct mwifiex_ds_11n_tx_cfg *txcfg =
+ (struct mwifiex_ds_11n_tx_cfg *) data_buf;
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_11N_CFG);
+ cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_11n_cfg) + S_DS_GEN);
+ htcfg->action = cpu_to_le16(cmd_action);
+ htcfg->ht_tx_cap = cpu_to_le16(txcfg->tx_htcap);
+ htcfg->ht_tx_info = cpu_to_le16(txcfg->tx_htinfo);
+ return 0;
+}
+
+/*
+ * This function appends an 11n TLV to a buffer.
+ *
+ * Buffer allocation is responsibility of the calling
+ * function. No size validation is made here.
+ *
+ * The function fills up the following sections, if applicable -
+ * - HT capability IE
+ * - HT information IE (with channel list)
+ * - 20/40 BSS Coexistence IE
+ * - HT Extended Capabilities IE
+ */
+int
+mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc,
+ u8 **buffer)
+{
+ struct mwifiex_ie_types_htcap *ht_cap;
+ struct mwifiex_ie_types_htinfo *ht_info;
+ struct mwifiex_ie_types_chan_list_param_set *chan_list;
+ struct mwifiex_ie_types_2040bssco *bss_co_2040;
+ struct mwifiex_ie_types_extcap *ext_cap;
+ int ret_len = 0;
+ struct ieee80211_supported_band *sband;
+ u8 radio_type;
+
+ if (!buffer || !*buffer)
+ return ret_len;
+
+ radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
+ sband = priv->wdev->wiphy->bands[radio_type];
+
+ if (bss_desc->bcn_ht_cap) {
+ ht_cap = (struct mwifiex_ie_types_htcap *) *buffer;
+ memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
+ ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
+ ht_cap->header.len =
+ cpu_to_le16(sizeof(struct ieee80211_ht_cap));
+ memcpy((u8 *) ht_cap + sizeof(struct mwifiex_ie_types_header),
+ (u8 *) bss_desc->bcn_ht_cap +
+ sizeof(struct ieee_types_header),
+ le16_to_cpu(ht_cap->header.len));
+
+ mwifiex_fill_cap_info(priv, radio_type, ht_cap);
+
+ *buffer += sizeof(struct mwifiex_ie_types_htcap);
+ ret_len += sizeof(struct mwifiex_ie_types_htcap);
+ }
+
+ if (bss_desc->bcn_ht_info) {
+ if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
+ ht_info = (struct mwifiex_ie_types_htinfo *) *buffer;
+ memset(ht_info, 0,
+ sizeof(struct mwifiex_ie_types_htinfo));
+ ht_info->header.type =
+ cpu_to_le16(WLAN_EID_HT_INFORMATION);
+ ht_info->header.len =
+ cpu_to_le16(sizeof(struct ieee80211_ht_info));
+
+ memcpy((u8 *) ht_info +
+ sizeof(struct mwifiex_ie_types_header),
+ (u8 *) bss_desc->bcn_ht_info +
+ sizeof(struct ieee_types_header),
+ le16_to_cpu(ht_info->header.len));
+
+ if (!(sband->ht_cap.cap &
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40))
+ ht_info->ht_info.ht_param &=
+ ~(IEEE80211_HT_PARAM_CHAN_WIDTH_ANY |
+ IEEE80211_HT_PARAM_CHA_SEC_OFFSET);
+
+ *buffer += sizeof(struct mwifiex_ie_types_htinfo);
+ ret_len += sizeof(struct mwifiex_ie_types_htinfo);
+ }
+
+ chan_list =
+ (struct mwifiex_ie_types_chan_list_param_set *) *buffer;
+ memset(chan_list, 0,
+ sizeof(struct mwifiex_ie_types_chan_list_param_set));
+ chan_list->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
+ chan_list->header.len = cpu_to_le16(
+ sizeof(struct mwifiex_ie_types_chan_list_param_set) -
+ sizeof(struct mwifiex_ie_types_header));
+ chan_list->chan_scan_param[0].chan_number =
+ bss_desc->bcn_ht_info->control_chan;
+ chan_list->chan_scan_param[0].radio_type =
+ mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
+
+ if ((sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+ && (bss_desc->bcn_ht_info->ht_param &
+ IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
+ SET_SECONDARYCHAN(chan_list->chan_scan_param[0].
+ radio_type,
+ (bss_desc->bcn_ht_info->ht_param &
+ IEEE80211_HT_PARAM_CHA_SEC_OFFSET));
+
+ *buffer += sizeof(struct mwifiex_ie_types_chan_list_param_set);
+ ret_len += sizeof(struct mwifiex_ie_types_chan_list_param_set);
+ }
+
+ if (bss_desc->bcn_bss_co_2040) {
+ bss_co_2040 = (struct mwifiex_ie_types_2040bssco *) *buffer;
+ memset(bss_co_2040, 0,
+ sizeof(struct mwifiex_ie_types_2040bssco));
+ bss_co_2040->header.type = cpu_to_le16(WLAN_EID_BSS_COEX_2040);
+ bss_co_2040->header.len =
+ cpu_to_le16(sizeof(bss_co_2040->bss_co_2040));
+
+ memcpy((u8 *) bss_co_2040 +
+ sizeof(struct mwifiex_ie_types_header),
+ (u8 *) bss_desc->bcn_bss_co_2040 +
+ sizeof(struct ieee_types_header),
+ le16_to_cpu(bss_co_2040->header.len));
+
+ *buffer += sizeof(struct mwifiex_ie_types_2040bssco);
+ ret_len += sizeof(struct mwifiex_ie_types_2040bssco);
+ }
+
+ if (bss_desc->bcn_ext_cap) {
+ ext_cap = (struct mwifiex_ie_types_extcap *) *buffer;
+ memset(ext_cap, 0, sizeof(struct mwifiex_ie_types_extcap));
+ ext_cap->header.type = cpu_to_le16(WLAN_EID_EXT_CAPABILITY);
+ ext_cap->header.len = cpu_to_le16(sizeof(ext_cap->ext_cap));
+
+ memcpy((u8 *) ext_cap +
+ sizeof(struct mwifiex_ie_types_header),
+ (u8 *) bss_desc->bcn_ext_cap +
+ sizeof(struct ieee_types_header),
+ le16_to_cpu(ext_cap->header.len));
+
+ *buffer += sizeof(struct mwifiex_ie_types_extcap);
+ ret_len += sizeof(struct mwifiex_ie_types_extcap);
+ }
+
+ return ret_len;
+}
+
+/*
+ * This function reconfigures the Tx buffer size in firmware.
+ *
+ * This function prepares a firmware command and issues it, if
+ * the current Tx buffer size is different from the one requested.
+ * Maximum configurable Tx buffer size is limited by the HT capability
+ * field value.
+ */
+void
+mwifiex_cfg_tx_buf(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc)
+{
+ u16 max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_2K;
+ u16 tx_buf, curr_tx_buf_size = 0;
+
+ if (bss_desc->bcn_ht_cap) {
+ if (le16_to_cpu(bss_desc->bcn_ht_cap->cap_info) &
+ IEEE80211_HT_CAP_MAX_AMSDU)
+ max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_8K;
+ else
+ max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_4K;
+ }
+
+ tx_buf = min(priv->adapter->max_tx_buf_size, max_amsdu);
+
+ dev_dbg(priv->adapter->dev, "info: max_amsdu=%d, max_tx_buf=%d\n",
+ max_amsdu, priv->adapter->max_tx_buf_size);
+
+ if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_2K)
+ curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
+ else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_4K)
+ curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;
+ else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_8K)
+ curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_8K;
+ if (curr_tx_buf_size != tx_buf)
+ mwifiex_send_cmd_async(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
+ HostCmd_ACT_GEN_SET, 0, &tx_buf);
+}
+
+/*
+ * This function checks if the given pointer is valid entry of
+ * Tx BA Stream table.
+ */
+static int mwifiex_is_tx_ba_stream_ptr_valid(struct mwifiex_private *priv,
+ struct mwifiex_tx_ba_stream_tbl *tx_tbl_ptr)
+{
+ struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
+
+ list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
+ if (tx_ba_tsr_tbl == tx_tbl_ptr)
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * This function deletes the given entry in Tx BA Stream table.
+ *
+ * The function also performs a validity check on the supplied
+ * pointer before trying to delete.
+ */
+void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
+ struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl)
+{
+ if (!tx_ba_tsr_tbl &&
+ mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl))
+ return;
+
+ dev_dbg(priv->adapter->dev, "info: tx_ba_tsr_tbl %p\n", tx_ba_tsr_tbl);
+
+ list_del(&tx_ba_tsr_tbl->list);
+
+ kfree(tx_ba_tsr_tbl);
+}
+
+/*
+ * This function deletes all the entries in Tx BA Stream table.
+ */
+void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv)
+{
+ int i;
+ struct mwifiex_tx_ba_stream_tbl *del_tbl_ptr, *tmp_node;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ list_for_each_entry_safe(del_tbl_ptr, tmp_node,
+ &priv->tx_ba_stream_tbl_ptr, list)
+ mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, del_tbl_ptr);
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
+
+ INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
+
+ for (i = 0; i < MAX_NUM_TID; ++i)
+ priv->aggr_prio_tbl[i].ampdu_ap =
+ priv->aggr_prio_tbl[i].ampdu_user;
+}
+
+/*
+ * This function returns the pointer to an entry in BA Stream
+ * table which matches the given RA/TID pair.
+ */
+struct mwifiex_tx_ba_stream_tbl *
+mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
+ int tid, u8 *ra)
+{
+ struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
+ if ((!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN))
+ && (tx_ba_tsr_tbl->tid == tid)) {
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock,
+ flags);
+ return tx_ba_tsr_tbl;
+ }
+ }
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
+ return NULL;
+}
+
+/*
+ * This function creates an entry in Tx BA stream table for the
+ * given RA/TID pair.
+ */
+void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv,
+ u8 *ra, int tid,
+ enum mwifiex_ba_status ba_status)
+{
+ struct mwifiex_tx_ba_stream_tbl *new_node;
+ unsigned long flags;
+
+ if (!mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ra)) {
+ new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl),
+ GFP_ATOMIC);
+ if (!new_node) {
+ dev_err(priv->adapter->dev,
+ "%s: failed to alloc new_node\n", __func__);
+ return;
+ }
+
+ INIT_LIST_HEAD(&new_node->list);
+
+ new_node->tid = tid;
+ new_node->ba_status = ba_status;
+ memcpy(new_node->ra, ra, ETH_ALEN);
+
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ list_add_tail(&new_node->list, &priv->tx_ba_stream_tbl_ptr);
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
+ }
+}
+
+/*
+ * This function sends an add BA request to the given TID/RA pair.
+ */
+int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
+{
+ struct host_cmd_ds_11n_addba_req add_ba_req;
+ static u8 dialog_tok;
+ int ret;
+
+ dev_dbg(priv->adapter->dev, "cmd: %s: tid %d\n", __func__, tid);
+
+ add_ba_req.block_ack_param_set = cpu_to_le16(
+ (u16) ((tid << BLOCKACKPARAM_TID_POS) |
+ (priv->add_ba_param.
+ tx_win_size << BLOCKACKPARAM_WINSIZE_POS) |
+ IMMEDIATE_BLOCK_ACK));
+ add_ba_req.block_ack_tmo = cpu_to_le16((u16)priv->add_ba_param.timeout);
+
+ ++dialog_tok;
+
+ if (dialog_tok == 0)
+ dialog_tok = 1;
+
+ add_ba_req.dialog_token = dialog_tok;
+ memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN);
+
+ /* We don't wait for the response of this command */
+ ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_REQ,
+ 0, 0, &add_ba_req);
+
+ return ret;
+}
+
+/*
+ * This function sends a delete BA request to the given TID/RA pair.
+ */
+int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
+ int initiator)
+{
+ struct host_cmd_ds_11n_delba delba;
+ int ret;
+ uint16_t del_ba_param_set;
+
+ memset(&delba, 0, sizeof(delba));
+ delba.del_ba_param_set = cpu_to_le16(tid << DELBA_TID_POS);
+
+ del_ba_param_set = le16_to_cpu(delba.del_ba_param_set);
+ if (initiator)
+ del_ba_param_set |= IEEE80211_DELBA_PARAM_INITIATOR_MASK;
+ else
+ del_ba_param_set &= ~IEEE80211_DELBA_PARAM_INITIATOR_MASK;
+
+ memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN);
+
+ /* We don't wait for the response of this command */
+ ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA,
+ HostCmd_ACT_GEN_SET, 0, &delba);
+
+ return ret;
+}
+
+/*
+ * This function handles the command response of a delete BA request.
+ */
+void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba)
+{
+ struct host_cmd_ds_11n_delba *cmd_del_ba =
+ (struct host_cmd_ds_11n_delba *) del_ba;
+ uint16_t del_ba_param_set = le16_to_cpu(cmd_del_ba->del_ba_param_set);
+ int tid;
+
+ tid = del_ba_param_set >> DELBA_TID_POS;
+
+ mwifiex_11n_delete_ba_stream_tbl(priv, tid, cmd_del_ba->peer_mac_addr,
+ TYPE_DELBA_RECEIVE,
+ INITIATOR_BIT(del_ba_param_set));
+}
+
+/*
+ * This function retrieves the Rx reordering table.
+ */
+int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv,
+ struct mwifiex_ds_rx_reorder_tbl *buf)
+{
+ int i;
+ struct mwifiex_ds_rx_reorder_tbl *rx_reo_tbl = buf;
+ struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr;
+ int count = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ list_for_each_entry(rx_reorder_tbl_ptr, &priv->rx_reorder_tbl_ptr,
+ list) {
+ rx_reo_tbl->tid = (u16) rx_reorder_tbl_ptr->tid;
+ memcpy(rx_reo_tbl->ta, rx_reorder_tbl_ptr->ta, ETH_ALEN);
+ rx_reo_tbl->start_win = rx_reorder_tbl_ptr->start_win;
+ rx_reo_tbl->win_size = rx_reorder_tbl_ptr->win_size;
+ for (i = 0; i < rx_reorder_tbl_ptr->win_size; ++i) {
+ if (rx_reorder_tbl_ptr->rx_reorder_ptr[i])
+ rx_reo_tbl->buffer[i] = true;
+ else
+ rx_reo_tbl->buffer[i] = false;
+ }
+ rx_reo_tbl++;
+ count++;
+
+ if (count >= MWIFIEX_MAX_RX_BASTREAM_SUPPORTED)
+ break;
+ }
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
+
+ return count;
+}
+
+/*
+ * This function retrieves the Tx BA stream table.
+ */
+int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
+ struct mwifiex_ds_tx_ba_stream_tbl *buf)
+{
+ struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
+ struct mwifiex_ds_tx_ba_stream_tbl *rx_reo_tbl = buf;
+ int count = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
+ rx_reo_tbl->tid = (u16) tx_ba_tsr_tbl->tid;
+ dev_dbg(priv->adapter->dev, "data: %s tid=%d\n",
+ __func__, rx_reo_tbl->tid);
+ memcpy(rx_reo_tbl->ra, tx_ba_tsr_tbl->ra, ETH_ALEN);
+ rx_reo_tbl++;
+ count++;
+ if (count >= MWIFIEX_MAX_TX_BASTREAM_SUPPORTED)
+ break;
+ }
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
+
+ return count;
+}
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
new file mode 100644
index 00000000000..a4390a1a2a9
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -0,0 +1,161 @@
+/*
+ * Marvell Wireless LAN device driver: 802.11n
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_11N_H_
+#define _MWIFIEX_11N_H_
+
+#include "11n_aggr.h"
+#include "11n_rxreorder.h"
+#include "wmm.h"
+
+int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp);
+int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp);
+int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp,
+ void *data_buf);
+int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd,
+ u16 cmd_action, void *data_buf);
+
+int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc,
+ u8 **buffer);
+void mwifiex_cfg_tx_buf(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc);
+void mwifiex_fill_cap_info(struct mwifiex_private *, u8 radio_type,
+ struct mwifiex_ie_types_htcap *);
+int mwifiex_set_get_11n_htcap_cfg(struct mwifiex_private *priv,
+ u16 action, int *htcap_cfg);
+void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
+ struct mwifiex_tx_ba_stream_tbl
+ *tx_tbl);
+void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv);
+struct mwifiex_tx_ba_stream_tbl *mwifiex_11n_get_tx_ba_stream_tbl(struct
+ mwifiex_private
+ *priv, int tid,
+ u8 *ra);
+void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, u8 *ra,
+ int tid,
+ enum mwifiex_ba_status ba_status);
+int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac);
+int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
+ int initiator);
+void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba);
+int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv,
+ struct mwifiex_ds_rx_reorder_tbl *buf);
+int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
+ struct mwifiex_ds_tx_ba_stream_tbl *buf);
+int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp,
+ void *data_buf);
+int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ int cmd_action, void *data_buf);
+int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
+ int cmd_action, void *data_buf);
+
+/*
+ * This function checks whether AMPDU is allowed or not for a particular TID.
+ */
+static inline u8
+mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, int tid)
+{
+ return ((priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED)
+ ? true : false);
+}
+
+/*
+ * This function checks whether AMSDU is allowed or not for a particular TID.
+ */
+static inline u8
+mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid)
+{
+ return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED)
+ && ((priv->is_data_rate_auto)
+ || !((priv->bitmap_rates[2]) & 0x03)))
+ ? true : false);
+}
+
+/*
+ * This function checks whether a space is available for new BA stream or not.
+ */
+static inline u8 mwifiex_space_avail_for_new_ba_stream(
+ struct mwifiex_adapter *adapter)
+{
+ struct mwifiex_private *priv;
+ u8 i;
+ u32 ba_stream_num = 0;
+
+ for (i = 0; i < adapter->priv_num; i++) {
+ priv = adapter->priv[i];
+ if (priv)
+ ba_stream_num += mwifiex_wmm_list_len(
+ (struct list_head *)
+ &priv->tx_ba_stream_tbl_ptr);
+ }
+
+ return ((ba_stream_num <
+ MWIFIEX_MAX_TX_BASTREAM_SUPPORTED) ? true : false);
+}
+
+/*
+ * This function finds the correct Tx BA stream to delete.
+ *
+ * Upon successfully locating, both the TID and the RA are returned.
+ */
+static inline u8
+mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid,
+ int *ptid, u8 *ra)
+{
+ int tid;
+ u8 ret = false;
+ struct mwifiex_tx_ba_stream_tbl *tx_tbl;
+ unsigned long flags;
+
+ tid = priv->aggr_prio_tbl[ptr_tid].ampdu_user;
+
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ list_for_each_entry(tx_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
+ if (tid > priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user) {
+ tid = priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user;
+ *ptid = tx_tbl->tid;
+ memcpy(ra, tx_tbl->ra, ETH_ALEN);
+ ret = true;
+ }
+ }
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
+
+ return ret;
+}
+
+/*
+ * This function checks whether BA stream is set up or not.
+ */
+static inline int
+mwifiex_is_ba_stream_setup(struct mwifiex_private *priv,
+ struct mwifiex_ra_list_tbl *ptr, int tid)
+{
+ struct mwifiex_tx_ba_stream_tbl *tx_tbl;
+
+ tx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ptr->ra);
+ if (tx_tbl && IS_BASTREAM_SETUP(tx_tbl))
+ return true;
+
+ return false;
+}
+#endif /* !_MWIFIEX_11N_H_ */
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
new file mode 100644
index 00000000000..d3d5e0853c4
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -0,0 +1,298 @@
+/*
+ * Marvell Wireless LAN device driver: 802.11n Aggregation
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+#include "11n_aggr.h"
+
+/*
+ * Creates an AMSDU subframe for aggregation into one AMSDU packet.
+ *
+ * The resultant AMSDU subframe format is -
+ *
+ * +---- ~ -----+---- ~ ------+---- ~ -----+----- ~ -----+---- ~ -----+
+ * | DA | SA | Length | SNAP header | MSDU |
+ * | data[0..5] | data[6..11] | | | data[14..] |
+ * +---- ~ -----+---- ~ ------+---- ~ -----+----- ~ -----+---- ~ -----+
+ * <--6-bytes--> <--6-bytes--> <--2-bytes--><--8-bytes--> <--n-bytes-->
+ *
+ * This function also computes the amount of padding required to make the
+ * buffer length multiple of 4 bytes.
+ *
+ * Data => |DA|SA|SNAP-TYPE|........ .|
+ * MSDU => |DA|SA|Length|SNAP|...... ..|
+ */
+static int
+mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr,
+ struct sk_buff *skb_src, int *pad)
+
+{
+ int dt_offset;
+ struct rfc_1042_hdr snap = {
+ 0xaa, /* LLC DSAP */
+ 0xaa, /* LLC SSAP */
+ 0x03, /* LLC CTRL */
+ {0x00, 0x00, 0x00}, /* SNAP OUI */
+ 0x0000 /* SNAP type */
+ /*
+ * This field will be overwritten
+ * later with ethertype
+ */
+ };
+ struct tx_packet_hdr *tx_header;
+
+ skb_put(skb_aggr, sizeof(*tx_header));
+
+ tx_header = (struct tx_packet_hdr *) skb_aggr->data;
+
+ /* Copy DA and SA */
+ dt_offset = 2 * ETH_ALEN;
+ memcpy(&tx_header->eth803_hdr, skb_src->data, dt_offset);
+
+ /* Copy SNAP header */
+ snap.snap_type = *(u16 *) ((u8 *)skb_src->data + dt_offset);
+ dt_offset += sizeof(u16);
+
+ memcpy(&tx_header->rfc1042_hdr, &snap, sizeof(struct rfc_1042_hdr));
+
+ skb_pull(skb_src, dt_offset);
+
+ /* Update Length field */
+ tx_header->eth803_hdr.h_proto = htons(skb_src->len + LLC_SNAP_LEN);
+
+ /* Add payload */
+ skb_put(skb_aggr, skb_src->len);
+ memcpy(skb_aggr->data + sizeof(*tx_header), skb_src->data,
+ skb_src->len);
+ *pad = (((skb_src->len + LLC_SNAP_LEN) & 3)) ? (4 - (((skb_src->len +
+ LLC_SNAP_LEN)) & 3)) : 0;
+ skb_put(skb_aggr, *pad);
+
+ return skb_aggr->len + *pad;
+}
+
+/*
+ * Adds TxPD to AMSDU header.
+ *
+ * Each AMSDU packet will contain one TxPD at the beginning,
+ * followed by multiple AMSDU subframes.
+ */
+static void
+mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
+ struct sk_buff *skb)
+{
+ struct txpd *local_tx_pd;
+
+ skb_push(skb, sizeof(*local_tx_pd));
+
+ local_tx_pd = (struct txpd *) skb->data;
+ memset(local_tx_pd, 0, sizeof(struct txpd));
+
+ /* Original priority has been overwritten */
+ local_tx_pd->priority = (u8) skb->priority;
+ local_tx_pd->pkt_delay_2ms =
+ mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
+ local_tx_pd->bss_num = priv->bss_num;
+ local_tx_pd->bss_type = priv->bss_type;
+ /* Always zero as the data is followed by struct txpd */
+ local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
+ local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU);
+ local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len -
+ sizeof(*local_tx_pd));
+
+ if (local_tx_pd->tx_control == 0)
+ /* TxCtrl set by user or default */
+ local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl);
+
+ if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
+ (priv->adapter->pps_uapsd_mode)) {
+ if (true == mwifiex_check_last_packet_indication(priv)) {
+ priv->adapter->tx_lock_flag = true;
+ local_tx_pd->flags =
+ MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET;
+ }
+ }
+}
+
+/*
+ * Create aggregated packet.
+ *
+ * This function creates an aggregated MSDU packet, by combining buffers
+ * from the RA list. Each individual buffer is encapsulated as an AMSDU
+ * subframe and all such subframes are concatenated together to form the
+ * AMSDU packet.
+ *
+ * A TxPD is also added to the front of the resultant AMSDU packets for
+ * transmission. The resultant packets format is -
+ *
+ * +---- ~ ----+------ ~ ------+------ ~ ------+-..-+------ ~ ------+
+ * | TxPD |AMSDU sub-frame|AMSDU sub-frame| .. |AMSDU sub-frame|
+ * | | 1 | 2 | .. | n |
+ * +---- ~ ----+------ ~ ------+------ ~ ------+ .. +------ ~ ------+
+ */
+int
+mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
+ struct mwifiex_ra_list_tbl *pra_list, int headroom,
+ int ptrindex, unsigned long ra_list_flags)
+ __releases(&priv->wmm.ra_list_spinlock)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct sk_buff *skb_aggr, *skb_src;
+ struct mwifiex_txinfo *tx_info_aggr, *tx_info_src;
+ int pad = 0, ret;
+ struct mwifiex_tx_param tx_param;
+ struct txpd *ptx_pd = NULL;
+
+ if (skb_queue_empty(&pra_list->skb_head)) {
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ return 0;
+ }
+ skb_src = skb_peek(&pra_list->skb_head);
+ tx_info_src = MWIFIEX_SKB_TXCB(skb_src);
+ skb_aggr = dev_alloc_skb(adapter->tx_buf_size);
+ if (!skb_aggr) {
+ dev_err(adapter->dev, "%s: alloc skb_aggr\n", __func__);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ return -1;
+ }
+ skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
+ tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr);
+
+ tx_info_aggr->bss_index = tx_info_src->bss_index;
+ skb_aggr->priority = skb_src->priority;
+
+ while (skb_src && ((skb_headroom(skb_aggr) + skb_src->len
+ + LLC_SNAP_LEN)
+ <= adapter->tx_buf_size)) {
+
+ if (!skb_queue_empty(&pra_list->skb_head))
+ skb_src = skb_dequeue(&pra_list->skb_head);
+ else
+ skb_src = NULL;
+
+ if (skb_src)
+ pra_list->total_pkts_size -= skb_src->len;
+
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad);
+
+ mwifiex_write_data_complete(adapter, skb_src, 0);
+
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+ if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ return -1;
+ }
+
+ if (!skb_queue_empty(&pra_list->skb_head))
+ skb_src = skb_peek(&pra_list->skb_head);
+ else
+ skb_src = NULL;
+ }
+
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+ /* Last AMSDU packet does not need padding */
+ skb_trim(skb_aggr, skb_aggr->len - pad);
+
+ /* Form AMSDU */
+ mwifiex_11n_form_amsdu_txpd(priv, skb_aggr);
+ if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
+ ptx_pd = (struct txpd *)skb_aggr->data;
+
+ skb_push(skb_aggr, headroom);
+
+ tx_param.next_pkt_len = ((pra_list->total_pkts_size) ?
+ (((pra_list->total_pkts_size) >
+ adapter->tx_buf_size) ? adapter->
+ tx_buf_size : pra_list->total_pkts_size +
+ LLC_SNAP_LEN + sizeof(struct txpd)) : 0);
+ ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
+ skb_aggr->data,
+ skb_aggr->len, &tx_param);
+ switch (ret) {
+ case -EBUSY:
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+ if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ mwifiex_write_data_complete(adapter, skb_aggr, -1);
+ return -1;
+ }
+ if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
+ (adapter->pps_uapsd_mode) &&
+ (adapter->tx_lock_flag)) {
+ priv->adapter->tx_lock_flag = false;
+ if (ptx_pd)
+ ptx_pd->flags = 0;
+ }
+
+ skb_queue_tail(&pra_list->skb_head, skb_aggr);
+
+ pra_list->total_pkts_size += skb_aggr->len;
+
+ tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
+ break;
+ case -1:
+ adapter->data_sent = false;
+ dev_err(adapter->dev, "%s: host_to_card failed: %#x\n",
+ __func__, ret);
+ adapter->dbg.num_tx_host_to_card_failure++;
+ mwifiex_write_data_complete(adapter, skb_aggr, ret);
+ return 0;
+ case -EINPROGRESS:
+ adapter->data_sent = false;
+ break;
+ case 0:
+ mwifiex_write_data_complete(adapter, skb_aggr, ret);
+ break;
+ default:
+ break;
+ }
+ if (ret != -EBUSY) {
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+ if (mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
+ priv->wmm.packets_out[ptrindex]++;
+ priv->wmm.tid_tbl_ptr[ptrindex].ra_list_curr = pra_list;
+ }
+ /* Now bss_prio_cur pointer points to next node */
+ adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
+ list_first_entry(
+ &adapter->bss_prio_tbl[priv->bss_priority]
+ .bss_prio_cur->list,
+ struct mwifiex_bss_prio_node, list);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ }
+
+ return 0;
+}
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.h b/drivers/net/wireless/mwifiex/11n_aggr.h
new file mode 100644
index 00000000000..9c6dca7ab02
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11n_aggr.h
@@ -0,0 +1,32 @@
+/*
+ * Marvell Wireless LAN device driver: 802.11n Aggregation
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_11N_AGGR_H_
+#define _MWIFIEX_11N_AGGR_H_
+
+#define PKT_TYPE_AMSDU 0xE6
+
+int mwifiex_11n_deaggregate_pkt(struct mwifiex_private *priv,
+ struct sk_buff *skb);
+int mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
+ struct mwifiex_ra_list_tbl *ptr, int headroom,
+ int ptr_index, unsigned long flags)
+ __releases(&priv->wmm.ra_list_spinlock);
+
+#endif /* !_MWIFIEX_11N_AGGR_H_ */
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
new file mode 100644
index 00000000000..e5dfdc39a92
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -0,0 +1,616 @@
+/*
+ * Marvell Wireless LAN device driver: 802.11n RX Re-ordering
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+#include "11n_rxreorder.h"
+
+/*
+ * This function dispatches all packets in the Rx reorder table.
+ *
+ * There could be holes in the buffer, which are skipped by the function.
+ * Since the buffer is linear, the function uses rotation to simulate
+ * circular buffer.
+ */
+static int
+mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
+ struct mwifiex_rx_reorder_tbl
+ *rx_reor_tbl_ptr, int start_win)
+{
+ int no_pkt_to_send, i;
+ void *rx_tmp_ptr;
+ unsigned long flags;
+
+ no_pkt_to_send = (start_win > rx_reor_tbl_ptr->start_win) ?
+ min((start_win - rx_reor_tbl_ptr->start_win),
+ rx_reor_tbl_ptr->win_size) : rx_reor_tbl_ptr->win_size;
+
+ for (i = 0; i < no_pkt_to_send; ++i) {
+ spin_lock_irqsave(&priv->rx_pkt_lock, flags);
+ rx_tmp_ptr = NULL;
+ if (rx_reor_tbl_ptr->rx_reorder_ptr[i]) {
+ rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i];
+ rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL;
+ }
+ spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
+ if (rx_tmp_ptr)
+ mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr);
+ }
+
+ spin_lock_irqsave(&priv->rx_pkt_lock, flags);
+ /*
+ * We don't have a circular buffer, hence use rotation to simulate
+ * circular buffer
+ */
+ for (i = 0; i < rx_reor_tbl_ptr->win_size - no_pkt_to_send; ++i) {
+ rx_reor_tbl_ptr->rx_reorder_ptr[i] =
+ rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i];
+ rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i] = NULL;
+ }
+
+ rx_reor_tbl_ptr->start_win = start_win;
+ spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
+
+ return 0;
+}
+
+/*
+ * This function dispatches all packets in the Rx reorder table until
+ * a hole is found.
+ *
+ * The start window is adjusted automatically when a hole is located.
+ * Since the buffer is linear, the function uses rotation to simulate
+ * circular buffer.
+ */
+static int
+mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
+ struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr)
+{
+ int i, j, xchg;
+ void *rx_tmp_ptr;
+ unsigned long flags;
+
+ for (i = 0; i < rx_reor_tbl_ptr->win_size; ++i) {
+ spin_lock_irqsave(&priv->rx_pkt_lock, flags);
+ if (!rx_reor_tbl_ptr->rx_reorder_ptr[i]) {
+ spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
+ break;
+ }
+ rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i];
+ rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL;
+ spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
+ mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr);
+ }
+
+ spin_lock_irqsave(&priv->rx_pkt_lock, flags);
+ /*
+ * We don't have a circular buffer, hence use rotation to simulate
+ * circular buffer
+ */
+ if (i > 0) {
+ xchg = rx_reor_tbl_ptr->win_size - i;
+ for (j = 0; j < xchg; ++j) {
+ rx_reor_tbl_ptr->rx_reorder_ptr[j] =
+ rx_reor_tbl_ptr->rx_reorder_ptr[i + j];
+ rx_reor_tbl_ptr->rx_reorder_ptr[i + j] = NULL;
+ }
+ }
+ rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i)
+ &(MAX_TID_VALUE - 1);
+ spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
+ return 0;
+}
+
+/*
+ * This function deletes the Rx reorder table and frees the memory.
+ *
+ * The function stops the associated timer and dispatches all the
+ * pending packets in the Rx reorder table before deletion.
+ */
+static void
+mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv,
+ struct mwifiex_rx_reorder_tbl
+ *rx_reor_tbl_ptr)
+{
+ unsigned long flags;
+
+ if (!rx_reor_tbl_ptr)
+ return;
+
+ mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr,
+ (rx_reor_tbl_ptr->start_win +
+ rx_reor_tbl_ptr->win_size)
+ &(MAX_TID_VALUE - 1));
+
+ del_timer(&rx_reor_tbl_ptr->timer_context.timer);
+
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ list_del(&rx_reor_tbl_ptr->list);
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
+
+ kfree(rx_reor_tbl_ptr->rx_reorder_ptr);
+ kfree(rx_reor_tbl_ptr);
+}
+
+/*
+ * This function returns the pointer to an entry in Rx reordering
+ * table which matches the given TA/TID pair.
+ */
+static struct mwifiex_rx_reorder_tbl *
+mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta)
+{
+ struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ list_for_each_entry(rx_reor_tbl_ptr, &priv->rx_reorder_tbl_ptr, list) {
+ if ((!memcmp(rx_reor_tbl_ptr->ta, ta, ETH_ALEN))
+ && (rx_reor_tbl_ptr->tid == tid)) {
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
+ flags);
+ return rx_reor_tbl_ptr;
+ }
+ }
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
+
+ return NULL;
+}
+
+/*
+ * This function finds the last sequence number used in the packets
+ * buffered in Rx reordering table.
+ */
+static int
+mwifiex_11n_find_last_seq_num(struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr)
+{
+ int i;
+
+ for (i = (rx_reorder_tbl_ptr->win_size - 1); i >= 0; --i)
+ if (rx_reorder_tbl_ptr->rx_reorder_ptr[i])
+ return i;
+
+ return -1;
+}
+
+/*
+ * This function flushes all the packets in Rx reordering table.
+ *
+ * The function checks if any packets are currently buffered in the
+ * table or not. In case there are packets available, it dispatches
+ * them and then dumps the Rx reordering table.
+ */
+static void
+mwifiex_flush_data(unsigned long context)
+{
+ struct reorder_tmr_cnxt *reorder_cnxt =
+ (struct reorder_tmr_cnxt *) context;
+ int start_win;
+
+ start_win = mwifiex_11n_find_last_seq_num(reorder_cnxt->ptr);
+ if (start_win >= 0) {
+ dev_dbg(reorder_cnxt->priv->adapter->dev,
+ "info: flush data %d\n", start_win);
+ mwifiex_11n_dispatch_pkt_until_start_win(reorder_cnxt->priv,
+ reorder_cnxt->ptr,
+ ((reorder_cnxt->ptr->start_win +
+ start_win + 1) & (MAX_TID_VALUE - 1)));
+ }
+}
+
+/*
+ * This function creates an entry in Rx reordering table for the
+ * given TA/TID.
+ *
+ * The function also initializes the entry with sequence number, window
+ * size as well as initializes the timer.
+ *
+ * If the received TA/TID pair is already present, all the packets are
+ * dispatched and the window size is moved until the SSN.
+ */
+static void
+mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
+ int tid, int win_size, int seq_num)
+{
+ int i;
+ struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr, *new_node;
+ u16 last_seq = 0;
+ unsigned long flags;
+
+ /*
+ * If we get a TID, ta pair which is already present dispatch all the
+ * the packets and move the window size until the ssn
+ */
+ rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta);
+ if (rx_reor_tbl_ptr) {
+ mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr,
+ seq_num);
+ return;
+ }
+ /* if !rx_reor_tbl_ptr then create one */
+ new_node = kzalloc(sizeof(struct mwifiex_rx_reorder_tbl), GFP_KERNEL);
+ if (!new_node) {
+ dev_err(priv->adapter->dev, "%s: failed to alloc new_node\n",
+ __func__);
+ return;
+ }
+
+ INIT_LIST_HEAD(&new_node->list);
+ new_node->tid = tid;
+ memcpy(new_node->ta, ta, ETH_ALEN);
+ new_node->start_win = seq_num;
+ if (mwifiex_queuing_ra_based(priv))
+ /* TODO for adhoc */
+ dev_dbg(priv->adapter->dev,
+ "info: ADHOC:last_seq=%d start_win=%d\n",
+ last_seq, new_node->start_win);
+ else
+ last_seq = priv->rx_seq[tid];
+
+ if (last_seq >= new_node->start_win)
+ new_node->start_win = last_seq + 1;
+
+ new_node->win_size = win_size;
+
+ new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size,
+ GFP_KERNEL);
+ if (!new_node->rx_reorder_ptr) {
+ kfree((u8 *) new_node);
+ dev_err(priv->adapter->dev,
+ "%s: failed to alloc reorder_ptr\n", __func__);
+ return;
+ }
+
+ new_node->timer_context.ptr = new_node;
+ new_node->timer_context.priv = priv;
+
+ init_timer(&new_node->timer_context.timer);
+ new_node->timer_context.timer.function = mwifiex_flush_data;
+ new_node->timer_context.timer.data =
+ (unsigned long) &new_node->timer_context;
+
+ for (i = 0; i < win_size; ++i)
+ new_node->rx_reorder_ptr[i] = NULL;
+
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ list_add_tail(&new_node->list, &priv->rx_reorder_tbl_ptr);
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
+}
+
+/*
+ * This function prepares command for adding a BA request.
+ *
+ * Preparation includes -
+ * - Setting command ID and proper size
+ * - Setting add BA request buffer
+ * - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf)
+{
+ struct host_cmd_ds_11n_addba_req *add_ba_req =
+ (struct host_cmd_ds_11n_addba_req *)
+ &cmd->params.add_ba_req;
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_REQ);
+ cmd->size = cpu_to_le16(sizeof(*add_ba_req) + S_DS_GEN);
+ memcpy(add_ba_req, data_buf, sizeof(*add_ba_req));
+
+ return 0;
+}
+
+/*
+ * This function prepares command for adding a BA response.
+ *
+ * Preparation includes -
+ * - Setting command ID and proper size
+ * - Setting add BA response buffer
+ * - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ void *data_buf)
+{
+ struct host_cmd_ds_11n_addba_rsp *add_ba_rsp =
+ (struct host_cmd_ds_11n_addba_rsp *)
+ &cmd->params.add_ba_rsp;
+ struct host_cmd_ds_11n_addba_req *cmd_addba_req =
+ (struct host_cmd_ds_11n_addba_req *) data_buf;
+ u8 tid;
+ int win_size;
+ uint16_t block_ack_param_set;
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_RSP);
+ cmd->size = cpu_to_le16(sizeof(*add_ba_rsp) + S_DS_GEN);
+
+ memcpy(add_ba_rsp->peer_mac_addr, cmd_addba_req->peer_mac_addr,
+ ETH_ALEN);
+ add_ba_rsp->dialog_token = cmd_addba_req->dialog_token;
+ add_ba_rsp->block_ack_tmo = cmd_addba_req->block_ack_tmo;
+ add_ba_rsp->ssn = cmd_addba_req->ssn;
+
+ block_ack_param_set = le16_to_cpu(cmd_addba_req->block_ack_param_set);
+ tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK)
+ >> BLOCKACKPARAM_TID_POS;
+ add_ba_rsp->status_code = cpu_to_le16(ADDBA_RSP_STATUS_ACCEPT);
+ block_ack_param_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
+ /* We donot support AMSDU inside AMPDU, hence reset the bit */
+ block_ack_param_set &= ~BLOCKACKPARAM_AMSDU_SUPP_MASK;
+ block_ack_param_set |= (priv->add_ba_param.rx_win_size <<
+ BLOCKACKPARAM_WINSIZE_POS);
+ add_ba_rsp->block_ack_param_set = cpu_to_le16(block_ack_param_set);
+ win_size = (le16_to_cpu(add_ba_rsp->block_ack_param_set)
+ & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK)
+ >> BLOCKACKPARAM_WINSIZE_POS;
+ cmd_addba_req->block_ack_param_set = cpu_to_le16(block_ack_param_set);
+
+ mwifiex_11n_create_rx_reorder_tbl(priv, cmd_addba_req->peer_mac_addr,
+ tid, win_size, le16_to_cpu(cmd_addba_req->ssn));
+ return 0;
+}
+
+/*
+ * This function prepares command for deleting a BA request.
+ *
+ * Preparation includes -
+ * - Setting command ID and proper size
+ * - Setting del BA request buffer
+ * - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, void *data_buf)
+{
+ struct host_cmd_ds_11n_delba *del_ba = (struct host_cmd_ds_11n_delba *)
+ &cmd->params.del_ba;
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_11N_DELBA);
+ cmd->size = cpu_to_le16(sizeof(*del_ba) + S_DS_GEN);
+ memcpy(del_ba, data_buf, sizeof(*del_ba));
+
+ return 0;
+}
+
+/*
+ * This function identifies if Rx reordering is needed for a received packet.
+ *
+ * In case reordering is required, the function will do the reordering
+ * before sending it to kernel.
+ *
+ * The Rx reorder table is checked first with the received TID/TA pair. If
+ * not found, the received packet is dispatched immediately. But if found,
+ * the packet is reordered and all the packets in the updated Rx reordering
+ * table is dispatched until a hole is found.
+ *
+ * For sequence number less than the starting window, the packet is dropped.
+ */
+int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
+ u16 seq_num, u16 tid,
+ u8 *ta, u8 pkt_type, void *payload)
+{
+ struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
+ int start_win, end_win, win_size, ret;
+ u16 pkt_index;
+
+ rx_reor_tbl_ptr =
+ mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv,
+ tid, ta);
+ if (!rx_reor_tbl_ptr) {
+ if (pkt_type != PKT_TYPE_BAR)
+ mwifiex_process_rx_packet(priv->adapter, payload);
+ return 0;
+ }
+ start_win = rx_reor_tbl_ptr->start_win;
+ win_size = rx_reor_tbl_ptr->win_size;
+ end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1);
+ del_timer(&rx_reor_tbl_ptr->timer_context.timer);
+ mod_timer(&rx_reor_tbl_ptr->timer_context.timer, jiffies
+ + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000);
+
+ /*
+ * If seq_num is less then starting win then ignore and drop the
+ * packet
+ */
+ if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {/* Wrap */
+ if (seq_num >= ((start_win + (TWOPOW11)) & (MAX_TID_VALUE - 1))
+ && (seq_num < start_win))
+ return -1;
+ } else if ((seq_num < start_win)
+ || (seq_num > (start_win + (TWOPOW11)))) {
+ return -1;
+ }
+
+ /*
+ * If this packet is a BAR we adjust seq_num as
+ * WinStart = seq_num
+ */
+ if (pkt_type == PKT_TYPE_BAR)
+ seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1);
+
+ if (((end_win < start_win)
+ && (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win)))
+ && (seq_num > end_win)) || ((end_win > start_win)
+ && ((seq_num > end_win) || (seq_num < start_win)))) {
+ end_win = seq_num;
+ if (((seq_num - win_size) + 1) >= 0)
+ start_win = (end_win - win_size) + 1;
+ else
+ start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1;
+ ret = mwifiex_11n_dispatch_pkt_until_start_win(priv,
+ rx_reor_tbl_ptr, start_win);
+
+ if (ret)
+ return ret;
+ }
+
+ if (pkt_type != PKT_TYPE_BAR) {
+ if (seq_num >= start_win)
+ pkt_index = seq_num - start_win;
+ else
+ pkt_index = (seq_num+MAX_TID_VALUE) - start_win;
+
+ if (rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index])
+ return -1;
+
+ rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index] = payload;
+ }
+
+ /*
+ * Dispatch all packets sequentially from start_win until a
+ * hole is found and adjust the start_win appropriately
+ */
+ ret = mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr);
+
+ return ret;
+}
+
+/*
+ * This function deletes an entry for a given TID/TA pair.
+ *
+ * The TID/TA are taken from del BA event body.
+ */
+void
+mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid,
+ u8 *peer_mac, u8 type, int initiator)
+{
+ struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
+ struct mwifiex_tx_ba_stream_tbl *ptx_tbl;
+ u8 cleanup_rx_reorder_tbl;
+ unsigned long flags;
+
+ if (type == TYPE_DELBA_RECEIVE)
+ cleanup_rx_reorder_tbl = (initiator) ? true : false;
+ else
+ cleanup_rx_reorder_tbl = (initiator) ? false : true;
+
+ dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d, "
+ "initiator=%d\n", peer_mac, tid, initiator);
+
+ if (cleanup_rx_reorder_tbl) {
+ rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid,
+ peer_mac);
+ if (!rx_reor_tbl_ptr) {
+ dev_dbg(priv->adapter->dev,
+ "event: TID, TA not found in table\n");
+ return;
+ }
+ mwifiex_11n_delete_rx_reorder_tbl_entry(priv, rx_reor_tbl_ptr);
+ } else {
+ ptx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, peer_mac);
+ if (!ptx_tbl) {
+ dev_dbg(priv->adapter->dev,
+ "event: TID, RA not found in table\n");
+ return;
+ }
+
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, ptx_tbl);
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
+ }
+}
+
+/*
+ * This function handles the command response of an add BA response.
+ *
+ * Handling includes changing the header fields into CPU format and
+ * creating the stream, provided the add BA is accepted.
+ */
+int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ struct host_cmd_ds_11n_addba_rsp *add_ba_rsp =
+ (struct host_cmd_ds_11n_addba_rsp *)
+ &resp->params.add_ba_rsp;
+ int tid, win_size;
+ struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
+ uint16_t block_ack_param_set;
+
+ block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set);
+
+ tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK)
+ >> BLOCKACKPARAM_TID_POS;
+ /*
+ * Check if we had rejected the ADDBA, if yes then do not create
+ * the stream
+ */
+ if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) {
+ win_size = (block_ack_param_set &
+ IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK)
+ >> BLOCKACKPARAM_WINSIZE_POS;
+
+ dev_dbg(priv->adapter->dev, "cmd: ADDBA RSP: %pM"
+ " tid=%d ssn=%d win_size=%d\n",
+ add_ba_rsp->peer_mac_addr,
+ tid, add_ba_rsp->ssn, win_size);
+ } else {
+ dev_err(priv->adapter->dev, "ADDBA RSP: failed %pM tid=%d)\n",
+ add_ba_rsp->peer_mac_addr, tid);
+
+ rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv,
+ tid, add_ba_rsp->peer_mac_addr);
+ if (rx_reor_tbl_ptr)
+ mwifiex_11n_delete_rx_reorder_tbl_entry(priv,
+ rx_reor_tbl_ptr);
+ }
+
+ return 0;
+}
+
+/*
+ * This function handles BA stream timeout event by preparing and sending
+ * a command to the firmware.
+ */
+void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv,
+ struct host_cmd_ds_11n_batimeout *event)
+{
+ struct host_cmd_ds_11n_delba delba;
+
+ memset(&delba, 0, sizeof(struct host_cmd_ds_11n_delba));
+ memcpy(delba.peer_mac_addr, event->peer_mac_addr, ETH_ALEN);
+
+ delba.del_ba_param_set |=
+ cpu_to_le16((u16) event->tid << DELBA_TID_POS);
+ delba.del_ba_param_set |= cpu_to_le16(
+ (u16) event->origninator << DELBA_INITIATOR_POS);
+ delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT);
+ mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, 0, 0, &delba);
+}
+
+/*
+ * This function cleans up the Rx reorder table by deleting all the entries
+ * and re-initializing.
+ */
+void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
+{
+ struct mwifiex_rx_reorder_tbl *del_tbl_ptr, *tmp_node;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ list_for_each_entry_safe(del_tbl_ptr, tmp_node,
+ &priv->rx_reorder_tbl_ptr, list) {
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
+ mwifiex_11n_delete_rx_reorder_tbl_entry(priv, del_tbl_ptr);
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ }
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
+
+ INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
+ memset(priv->rx_seq, 0, sizeof(priv->rx_seq));
+}
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h
new file mode 100644
index 00000000000..f3ca8c8c18f
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h
@@ -0,0 +1,65 @@
+/*
+ * Marvell Wireless LAN device driver: 802.11n RX Re-ordering
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_11N_RXREORDER_H_
+#define _MWIFIEX_11N_RXREORDER_H_
+
+#define MIN_FLUSH_TIMER_MS 50
+
+#define PKT_TYPE_BAR 0xE7
+#define MAX_TID_VALUE (2 << 11)
+#define TWOPOW11 (2 << 10)
+
+#define BLOCKACKPARAM_TID_POS 2
+#define BLOCKACKPARAM_AMSDU_SUPP_MASK 0x1
+#define BLOCKACKPARAM_WINSIZE_POS 6
+#define DELBA_TID_POS 12
+#define DELBA_INITIATOR_POS 11
+#define TYPE_DELBA_SENT 1
+#define TYPE_DELBA_RECEIVE 2
+#define IMMEDIATE_BLOCK_ACK 0x2
+
+#define ADDBA_RSP_STATUS_ACCEPT 0
+
+int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *,
+ u16 seqNum,
+ u16 tid, u8 *ta,
+ u8 pkttype, void *payload);
+void mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int Tid,
+ u8 *PeerMACAddr, u8 type,
+ int initiator);
+void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv,
+ struct host_cmd_ds_11n_batimeout *event);
+int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
+ struct host_cmd_ds_command
+ *resp);
+int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd,
+ void *data_buf);
+int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv,
+ struct host_cmd_ds_command
+ *cmd, void *data_buf);
+int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd,
+ void *data_buf);
+void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv);
+struct mwifiex_rx_reorder_tbl *mwifiex_11n_get_rxreorder_tbl(struct
+ mwifiex_private
+ *priv, int tid,
+ u8 *ta);
+
+#endif /* _MWIFIEX_11N_RXREORDER_H_ */
diff --git a/drivers/net/wireless/mwifiex/Kconfig b/drivers/net/wireless/mwifiex/Kconfig
new file mode 100644
index 00000000000..86962920cef
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/Kconfig
@@ -0,0 +1,21 @@
+config MWIFIEX
+ tristate "Marvell WiFi-Ex Driver"
+ depends on CFG80211
+ select LIB80211
+ ---help---
+ This adds support for wireless adapters based on Marvell
+ 802.11n chipsets.
+
+ If you choose to build it as a module, it will be called
+ mwifiex.
+
+config MWIFIEX_SDIO
+ tristate "Marvell WiFi-Ex Driver for SD8787"
+ depends on MWIFIEX && MMC
+ select FW_LOADER
+ ---help---
+ This adds support for wireless adapters based on Marvell
+ 8787 chipset with SDIO interface.
+
+ If you choose to build it as a module, it will be called
+ mwifiex_sdio.
diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile
new file mode 100644
index 00000000000..42cb733ea33
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/Makefile
@@ -0,0 +1,41 @@
+#
+# Copyright (C) 2011, Marvell International Ltd.
+#
+# This software file (the "File") is distributed by Marvell International
+# Ltd. under the terms of the GNU General Public License Version 2, June 1991
+# (the "License"). You may use, redistribute and/or modify this File in
+# accordance with the terms and conditions of the License, a copy of which
+# is available by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+# worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+#
+# THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+# ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+# this warranty disclaimer.
+
+
+mwifiex-y += main.o
+mwifiex-y += init.o
+mwifiex-y += cfp.o
+mwifiex-y += cmdevt.o
+mwifiex-y += util.o
+mwifiex-y += txrx.o
+mwifiex-y += wmm.o
+mwifiex-y += 11n.o
+mwifiex-y += 11n_aggr.o
+mwifiex-y += 11n_rxreorder.o
+mwifiex-y += scan.o
+mwifiex-y += join.o
+mwifiex-y += sta_ioctl.o
+mwifiex-y += sta_cmd.o
+mwifiex-y += sta_cmdresp.o
+mwifiex-y += sta_event.o
+mwifiex-y += sta_tx.o
+mwifiex-y += sta_rx.o
+mwifiex-y += cfg80211.o
+mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o
+obj-$(CONFIG_MWIFIEX) += mwifiex.o
+
+mwifiex_sdio-y += sdio.o
+obj-$(CONFIG_MWIFIEX_SDIO) += mwifiex_sdio.o
diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README
new file mode 100644
index 00000000000..b55badef466
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/README
@@ -0,0 +1,204 @@
+# Copyright (C) 2011, Marvell International Ltd.
+#
+# This software file (the "File") is distributed by Marvell International
+# Ltd. under the terms of the GNU General Public License Version 2, June 1991
+# (the "License"). You may use, redistribute and/or modify this File in
+# accordance with the terms and conditions of the License, a copy of which
+# is available by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+# worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+#
+# THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+# ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+# this warranty disclaimer.
+
+
+===============================================================================
+ U S E R M A N U A L
+
+1) FOR DRIVER INSTALL
+
+ a) Copy sd8787.bin to /lib/firmware/mrvl/ directory,
+ create the directory if it doesn't exist.
+ b) Install WLAN driver,
+ insmod mwifiex.ko
+ c) Uninstall WLAN driver,
+ ifconfig mlanX down
+ rmmod mwifiex
+
+
+2) FOR DRIVER CONFIGURATION AND INFO
+ The configurations can be done either using the 'iw' user space
+ utility or debugfs.
+
+ a) 'iw' utility commands
+
+ Following are some useful iw commands:-
+
+iw dev mlan0 scan
+
+ This command will trigger a scan.
+ The command will then display the scan table entries
+
+iw dev mlan0 connect -w <SSID> [<freq in MHz>] [<bssid>] [key 0:abcde d:1123456789a]
+ The above command can be used to connect to an AP with a particular SSID.
+ Ap's operating frequency can be specified or even the bssid. If the AP is using
+ WEP encryption, wep keys can be specified in the command.
+ Note: Every time before connecting to an AP scan command (iw dev mlan0 scan) should be used by user.
+
+iw dev mlan0 disconnect
+ This command will be used to disconnect from an AP.
+
+
+iw dev mlan0 ibss join <SSID> <freq in MHz> [fixed-freq] [fixed-bssid] [key 0:abcde]
+ The command will be used to join or create an ibss. Optionally, operating frequency,
+ bssid and the security related parameters can be specified while joining/creating
+ and ibss.
+
+iw dev mlan0 ibss leave
+ The command will be used to leave an ibss network.
+
+iw dev mlan0 link
+ The command will be used to get the connection status. The command will return parameters
+ such as SSID, operating frequency, rx/tx packets, signal strength, tx bitrate.
+
+ Apart from the iw utility all standard configurations using the 'iwconfig' utility are also supported.
+
+ b) Debugfs interface
+
+ The debugfs interface can be used for configurations and for getting
+ some useful information from the driver.
+ The section below explains the configurations that can be
+ done.
+
+ Mount debugfs to /debugfs mount point:
+
+ mkdir /debugfs
+ mount -t debugfs debugfs /debugfs
+
+ The information is provided in /debugfs/mwifiex/mlanX/:
+
+iw reg set <country code>
+ The command will be used to change the regulatory domain.
+
+iw reg get
+ The command will be used to get current regulatory domain.
+
+info
+ This command is used to get driver info.
+
+ Usage:
+ cat info
+
+ driver_name = "mwifiex"
+ driver_version = <driver_name, driver_version, (firmware_version)>
+ interface_name = "mlanX"
+ bss_mode = "Ad-hoc" | "Managed" | "Auto" | "Unknown"
+ media_state = "Disconnected" | "Connected"
+ mac_address = <6-byte adapter MAC address>
+ multicase_count = <multicast address count>
+ essid = <current SSID>
+ bssid = <current BSSID>
+ channel = <current channel>
+ region_code = <current region code>
+ multicasr_address[n] = <multicast address>
+ num_tx_bytes = <number of bytes sent to device>
+ num_rx_bytes = <number of bytes received from device and sent to kernel>
+ num_tx_pkts = <number of packets sent to device>
+ num_rx_pkts = <number of packets received from device and sent to kernel>
+ num_tx_pkts_dropped = <number of Tx packets dropped by driver>
+ num_rx_pkts_dropped = <number of Rx packets dropped by driver>
+ num_tx_pkts_err = <number of Tx packets failed to send to device>
+ num_rx_pkts_err = <number of Rx packets failed to receive from device>
+ carrier "on" | "off"
+ tx queue "stopped" | "started"
+
+ The following debug info are provided in /debugfs/mwifiex/mlanX/debug:
+
+ int_counter = <interrupt count, cleared when interrupt handled>
+ wmm_ac_vo = <number of packets sent to device from WMM AcVo queue>
+ wmm_ac_vi = <number of packets sent to device from WMM AcVi queue>
+ wmm_ac_be = <number of packets sent to device from WMM AcBE queue>
+ wmm_ac_bk = <number of packets sent to device from WMM AcBK queue>
+ max_tx_buf_size = <maximum Tx buffer size>
+ tx_buf_size = <current Tx buffer size>
+ curr_tx_buf_size = <current Tx buffer size>
+ ps_mode = <0/1, CAM mode/PS mode>
+ ps_state = <0/1/2/3, full power state/awake state/pre-sleep state/sleep state>
+ is_deep_sleep = <0/1, not deep sleep state/deep sleep state>
+ wakeup_dev_req = <0/1, wakeup device not required/required>
+ wakeup_tries = <wakeup device count, cleared when device awake>
+ hs_configured = <0/1, host sleep not configured/configured>
+ hs_activated = <0/1, extended host sleep not activated/activated>
+ num_tx_timeout = <number of Tx timeout>
+ num_cmd_timeout = <number of timeout commands>
+ timeout_cmd_id = <command id of the last timeout command>
+ timeout_cmd_act = <command action of the last timeout command>
+ last_cmd_id = <command id of the last several commands sent to device>
+ last_cmd_act = <command action of the last several commands sent to device>
+ last_cmd_index = <0 based last command index>
+ last_cmd_resp_id = <command id of the last several command responses received from device>
+ last_cmd_resp_index = <0 based last command response index>
+ last_event = <event id of the last several events received from device>
+ last_event_index = <0 based last event index>
+ num_cmd_h2c_fail = <number of commands failed to send to device>
+ num_cmd_sleep_cfm_fail = <number of sleep confirm failed to send to device>
+ num_tx_h2c_fail = <number of data packets failed to send to device>
+ num_evt_deauth = <number of deauthenticated events received from device>
+ num_evt_disassoc = <number of disassociated events received from device>
+ num_evt_link_lost = <number of link lost events received from device>
+ num_cmd_deauth = <number of deauthenticate commands sent to device>
+ num_cmd_assoc_ok = <number of associate commands with success return>
+ num_cmd_assoc_fail = <number of associate commands with failure return>
+ cmd_sent = <0/1, send command resources available/sending command to device>
+ data_sent = <0/1, send data resources available/sending data to device>
+ mp_rd_bitmap = <SDIO multi-port read bitmap>
+ mp_wr_bitmap = <SDIO multi-port write bitmap>
+ cmd_resp_received = <0/1, no cmd response to process/response received and yet to process>
+ event_received = <0/1, no event to process/event received and yet to process>
+ cmd_pending = <number of cmd pending>
+ tx_pending = <number of Tx packet pending>
+ rx_pending = <number of Rx packet pending>
+
+
+3) FOR DRIVER CONFIGURATION
+
+regrdwr
+ This command is used to read/write the adapter register.
+
+ Usage:
+ echo " <type> <offset> [value]" > regrdwr
+ cat regrdwr
+
+ where the parameters are,
+ <type>: 1:MAC/SOC, 2:BBP, 3:RF, 4:PMIC, 5:CAU
+ <offset>: offset of register
+ [value]: value to be written
+
+ Examples:
+ echo "1 0xa060" > regrdwr : Read the MAC register
+ echo "1 0xa060 0x12" > regrdwr : Write the MAC register
+ echo "1 0xa794 0x80000000" > regrdwr
+ : Write 0x80000000 to MAC register
+rdeeprom
+ This command is used to read the EEPROM contents of the card.
+
+ Usage:
+ echo "<offset> <length>" > rdeeprom
+ cat rdeeprom
+
+ where the parameters are,
+ <offset>: multiples of 4
+ <length>: 4-20, multiples of 4
+
+ Example:
+ echo "0 20" > rdeeprom : Read 20 bytes of EEPROM data from offset 0
+
+getlog
+ This command is used to get the statistics available in the station.
+ Usage:
+
+ cat getlog
+
+===============================================================================
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
new file mode 100644
index 00000000000..660831ce293
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -0,0 +1,1417 @@
+/*
+ * Marvell Wireless LAN device driver: CFG80211
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "cfg80211.h"
+#include "main.h"
+
+/*
+ * This function maps the nl802.11 channel type into driver channel type.
+ *
+ * The mapping is as follows -
+ * NL80211_CHAN_NO_HT -> NO_SEC_CHANNEL
+ * NL80211_CHAN_HT20 -> NO_SEC_CHANNEL
+ * NL80211_CHAN_HT40PLUS -> SEC_CHANNEL_ABOVE
+ * NL80211_CHAN_HT40MINUS -> SEC_CHANNEL_BELOW
+ * Others -> NO_SEC_CHANNEL
+ */
+static int
+mwifiex_cfg80211_channel_type_to_mwifiex_channels(enum nl80211_channel_type
+ channel_type)
+{
+ switch (channel_type) {
+ case NL80211_CHAN_NO_HT:
+ case NL80211_CHAN_HT20:
+ return NO_SEC_CHANNEL;
+ case NL80211_CHAN_HT40PLUS:
+ return SEC_CHANNEL_ABOVE;
+ case NL80211_CHAN_HT40MINUS:
+ return SEC_CHANNEL_BELOW;
+ default:
+ return NO_SEC_CHANNEL;
+ }
+}
+
+/*
+ * This function maps the driver channel type into nl802.11 channel type.
+ *
+ * The mapping is as follows -
+ * NO_SEC_CHANNEL -> NL80211_CHAN_HT20
+ * SEC_CHANNEL_ABOVE -> NL80211_CHAN_HT40PLUS
+ * SEC_CHANNEL_BELOW -> NL80211_CHAN_HT40MINUS
+ * Others -> NL80211_CHAN_HT20
+ */
+static enum nl80211_channel_type
+mwifiex_channels_to_cfg80211_channel_type(int channel_type)
+{
+ switch (channel_type) {
+ case NO_SEC_CHANNEL:
+ return NL80211_CHAN_HT20;
+ case SEC_CHANNEL_ABOVE:
+ return NL80211_CHAN_HT40PLUS;
+ case SEC_CHANNEL_BELOW:
+ return NL80211_CHAN_HT40MINUS;
+ default:
+ return NL80211_CHAN_HT20;
+ }
+}
+
+/*
+ * This function checks whether WEP is set.
+ */
+static int
+mwifiex_is_alg_wep(u32 cipher)
+{
+ switch (cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * This function retrieves the private structure from kernel wiphy structure.
+ */
+static void *mwifiex_cfg80211_get_priv(struct wiphy *wiphy)
+{
+ return (void *) (*(unsigned long *) wiphy_priv(wiphy));
+}
+
+/*
+ * CFG802.11 operation handler to delete a network key.
+ */
+static int
+mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
+ u8 key_index, bool pairwise, const u8 *mac_addr)
+{
+ struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+
+ if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) {
+ wiphy_err(wiphy, "deleting the crypto keys\n");
+ return -EFAULT;
+ }
+
+ wiphy_dbg(wiphy, "info: crypto keys deleted\n");
+ return 0;
+}
+
+/*
+ * CFG802.11 operation handler to set Tx power.
+ */
+static int
+mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy,
+ enum nl80211_tx_power_setting type,
+ int dbm)
+{
+ struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+ struct mwifiex_power_cfg power_cfg;
+
+ if (type == NL80211_TX_POWER_FIXED) {
+ power_cfg.is_power_auto = 0;
+ power_cfg.power_level = dbm;
+ } else {
+ power_cfg.is_power_auto = 1;
+ }
+
+ return mwifiex_set_tx_power(priv, &power_cfg);
+}
+
+/*
+ * CFG802.11 operation handler to set Power Save option.
+ *
+ * The timeout value, if provided, is currently ignored.
+ */
+static int
+mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+ struct net_device *dev,
+ bool enabled, int timeout)
+{
+ struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+ u32 ps_mode;
+
+ if (timeout)
+ wiphy_dbg(wiphy,
+ "info: ignoring the timeout value"
+ " for IEEE power save\n");
+
+ ps_mode = enabled;
+
+ return mwifiex_drv_set_power(priv, &ps_mode);
+}
+
+/*
+ * CFG802.11 operation handler to set the default network key.
+ */
+static int
+mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
+ u8 key_index, bool unicast,
+ bool multicast)
+{
+ struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+
+ /* Return if WEP key not configured */
+ if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED)
+ return 0;
+
+ if (mwifiex_set_encode(priv, NULL, 0, key_index, 0)) {
+ wiphy_err(wiphy, "set default Tx key index\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+/*
+ * CFG802.11 operation handler to add a network key.
+ */
+static int
+mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
+ u8 key_index, bool pairwise, const u8 *mac_addr,
+ struct key_params *params)
+{
+ struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+
+ if (mwifiex_set_encode(priv, params->key, params->key_len,
+ key_index, 0)) {
+ wiphy_err(wiphy, "crypto keys added\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+/*
+ * This function sends domain information to the firmware.
+ *
+ * The following information are passed to the firmware -
+ * - Country codes
+ * - Sub bands (first channel, number of channels, maximum Tx power)
+ */
+static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
+{
+ u8 no_of_triplet = 0;
+ struct ieee80211_country_ie_triplet *t;
+ u8 no_of_parsed_chan = 0;
+ u8 first_chan = 0, next_chan = 0, max_pwr = 0;
+ u8 i, flag = 0;
+ enum ieee80211_band band;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *ch;
+ struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg;
+
+ /* Set country code */
+ domain_info->country_code[0] = priv->country_code[0];
+ domain_info->country_code[1] = priv->country_code[1];
+ domain_info->country_code[2] = ' ';
+
+ band = mwifiex_band_to_radio_type(adapter->config_bands);
+ if (!wiphy->bands[band]) {
+ wiphy_err(wiphy, "11D: setting domain info in FW\n");
+ return -1;
+ }
+
+ sband = wiphy->bands[band];
+
+ for (i = 0; i < sband->n_channels ; i++) {
+ ch = &sband->channels[i];
+ if (ch->flags & IEEE80211_CHAN_DISABLED)
+ continue;
+
+ if (!flag) {
+ flag = 1;
+ first_chan = (u32) ch->hw_value;
+ next_chan = first_chan;
+ max_pwr = ch->max_power;
+ no_of_parsed_chan = 1;
+ continue;
+ }
+
+ if (ch->hw_value == next_chan + 1 &&
+ ch->max_power == max_pwr) {
+ next_chan++;
+ no_of_parsed_chan++;
+ } else {
+ t = &domain_info->triplet[no_of_triplet];
+ t->chans.first_channel = first_chan;
+ t->chans.num_channels = no_of_parsed_chan;
+ t->chans.max_power = max_pwr;
+ no_of_triplet++;
+ first_chan = (u32) ch->hw_value;
+ next_chan = first_chan;
+ max_pwr = ch->max_power;
+ no_of_parsed_chan = 1;
+ }
+ }
+
+ if (flag) {
+ t = &domain_info->triplet[no_of_triplet];
+ t->chans.first_channel = first_chan;
+ t->chans.num_channels = no_of_parsed_chan;
+ t->chans.max_power = max_pwr;
+ no_of_triplet++;
+ }
+
+ domain_info->no_of_triplet = no_of_triplet;
+
+ if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
+ HostCmd_ACT_GEN_SET, 0, NULL)) {
+ wiphy_err(wiphy, "11D: setting domain info in FW\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * CFG802.11 regulatory domain callback function.
+ *
+ * This function is called when the regulatory domain is changed due to the
+ * following reasons -
+ * - Set by driver
+ * - Set by system core
+ * - Set by user
+ * - Set bt Country IE
+ */
+static int mwifiex_reg_notifier(struct wiphy *wiphy,
+ struct regulatory_request *request)
+{
+ struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+
+ wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for domain"
+ " %c%c\n", request->alpha2[0], request->alpha2[1]);
+
+ memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2));
+
+ switch (request->initiator) {
+ case NL80211_REGDOM_SET_BY_DRIVER:
+ case NL80211_REGDOM_SET_BY_CORE:
+ case NL80211_REGDOM_SET_BY_USER:
+ break;
+ /* Todo: apply driver specific changes in channel flags based
+ on the request initiator if necessary. */
+ case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+ break;
+ }
+ mwifiex_send_domain_info_cmd_fw(wiphy);
+
+ return 0;
+}
+
+/*
+ * This function sets the RF channel.
+ *
+ * This function creates multiple IOCTL requests, populates them accordingly
+ * and issues them to set the band/channel and frequency.
+ */
+static int
+mwifiex_set_rf_channel(struct mwifiex_private *priv,
+ struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type)
+{
+ struct mwifiex_chan_freq_power cfp;
+ struct mwifiex_ds_band_cfg band_cfg;
+ u32 config_bands = 0;
+ struct wiphy *wiphy = priv->wdev->wiphy;
+
+ if (chan) {
+ memset(&band_cfg, 0, sizeof(band_cfg));
+ /* Set appropriate bands */
+ if (chan->band == IEEE80211_BAND_2GHZ)
+ config_bands = BAND_B | BAND_G | BAND_GN;
+ else
+ config_bands = BAND_AN | BAND_A;
+ if (priv->bss_mode == NL80211_IFTYPE_STATION
+ || priv->bss_mode == NL80211_IFTYPE_UNSPECIFIED) {
+ band_cfg.config_bands = config_bands;
+ } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
+ band_cfg.config_bands = config_bands;
+ band_cfg.adhoc_start_band = config_bands;
+ }
+
+ band_cfg.sec_chan_offset =
+ mwifiex_cfg80211_channel_type_to_mwifiex_channels
+ (channel_type);
+
+ if (mwifiex_set_radio_band_cfg(priv, &band_cfg))
+ return -EFAULT;
+
+ mwifiex_send_domain_info_cmd_fw(wiphy);
+ }
+
+ wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and "
+ "mode %d\n", config_bands, band_cfg.sec_chan_offset,
+ priv->bss_mode);
+ if (!chan)
+ return 0;
+
+ memset(&cfp, 0, sizeof(cfp));
+ cfp.freq = chan->center_freq;
+ cfp.channel = ieee80211_frequency_to_channel(chan->center_freq);
+
+ if (mwifiex_bss_set_channel(priv, &cfp))
+ return -EFAULT;
+
+ return mwifiex_drv_change_adhoc_chan(priv, cfp.channel);
+}
+
+/*
+ * CFG802.11 operation handler to set channel.
+ *
+ * This function can only be used when station is not connected.
+ */
+static int
+mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
+ struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type)
+{
+ struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+
+ if (priv->media_connected) {
+ wiphy_err(wiphy, "This setting is valid only when station "
+ "is not connected\n");
+ return -EINVAL;
+ }
+
+ return mwifiex_set_rf_channel(priv, chan, channel_type);
+}
+
+/*
+ * This function sets the fragmentation threshold.
+ *
+ * The fragmentation threshold value must lie between MWIFIEX_FRAG_MIN_VALUE
+ * and MWIFIEX_FRAG_MAX_VALUE.
+ */
+static int
+mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
+{
+ int ret;
+
+ if (frag_thr < MWIFIEX_FRAG_MIN_VALUE
+ || frag_thr > MWIFIEX_FRAG_MAX_VALUE)
+ return -EINVAL;
+
+ /* Send request to firmware */
+ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
+ HostCmd_ACT_GEN_SET, FRAG_THRESH_I,
+ &frag_thr);
+
+ return ret;
+}
+
+/*
+ * This function sets the RTS threshold.
+
+ * The rts value must lie between MWIFIEX_RTS_MIN_VALUE
+ * and MWIFIEX_RTS_MAX_VALUE.
+ */
+static int
+mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr)
+{
+ if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE)
+ rts_thr = MWIFIEX_RTS_MAX_VALUE;
+
+ return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
+ HostCmd_ACT_GEN_SET, RTS_THRESH_I,
+ &rts_thr);
+}
+
+/*
+ * CFG802.11 operation handler to set wiphy parameters.
+ *
+ * This function can be used to set the RTS threshold and the
+ * Fragmentation threshold of the driver.
+ */
+static int
+mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+ struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+ int ret = 0;
+
+ if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
+ ret = mwifiex_set_rts(priv, wiphy->rts_threshold);
+ if (ret)
+ return ret;
+ }
+
+ if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
+ ret = mwifiex_set_frag(priv, wiphy->frag_threshold);
+
+ return ret;
+}
+
+/*
+ * CFG802.11 operation handler to change interface type.
+ */
+static int
+mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
+ struct net_device *dev,
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params)
+{
+ int ret;
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+
+ if (priv->bss_mode == type) {
+ wiphy_warn(wiphy, "already set to required type\n");
+ return 0;
+ }
+
+ priv->bss_mode = type;
+
+ switch (type) {
+ case NL80211_IFTYPE_ADHOC:
+ dev->ieee80211_ptr->iftype = NL80211_IFTYPE_ADHOC;
+ wiphy_dbg(wiphy, "info: setting interface type to adhoc\n");
+ break;
+ case NL80211_IFTYPE_STATION:
+ dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
+ wiphy_dbg(wiphy, "info: setting interface type to managed\n");
+ break;
+ case NL80211_IFTYPE_UNSPECIFIED:
+ dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
+ wiphy_dbg(wiphy, "info: setting interface type to auto\n");
+ return 0;
+ default:
+ wiphy_err(wiphy, "unknown interface type: %d\n", type);
+ return -EINVAL;
+ }
+
+ mwifiex_deauthenticate(priv, NULL);
+
+ priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
+
+ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE,
+ HostCmd_ACT_GEN_SET, 0, NULL);
+
+ return ret;
+}
+
+/*
+ * This function dumps the station information on a buffer.
+ *
+ * The following information are shown -
+ * - Total bytes transmitted
+ * - Total bytes received
+ * - Total packets transmitted
+ * - Total packets received
+ * - Signal quality level
+ * - Transmission rate
+ */
+static int
+mwifiex_dump_station_info(struct mwifiex_private *priv,
+ struct station_info *sinfo)
+{
+ struct mwifiex_ds_get_signal signal;
+ struct mwifiex_rate_cfg rate;
+ int ret = 0;
+
+ sinfo->filled = STATION_INFO_RX_BYTES | STATION_INFO_TX_BYTES |
+ STATION_INFO_RX_PACKETS |
+ STATION_INFO_TX_PACKETS
+ | STATION_INFO_SIGNAL | STATION_INFO_TX_BITRATE;
+
+ /* Get signal information from the firmware */
+ memset(&signal, 0, sizeof(struct mwifiex_ds_get_signal));
+ if (mwifiex_get_signal_info(priv, &signal)) {
+ dev_err(priv->adapter->dev, "getting signal information\n");
+ ret = -EFAULT;
+ }
+
+ if (mwifiex_drv_get_data_rate(priv, &rate)) {
+ dev_err(priv->adapter->dev, "getting data rate\n");
+ ret = -EFAULT;
+ }
+
+ sinfo->rx_bytes = priv->stats.rx_bytes;
+ sinfo->tx_bytes = priv->stats.tx_bytes;
+ sinfo->rx_packets = priv->stats.rx_packets;
+ sinfo->tx_packets = priv->stats.tx_packets;
+ sinfo->signal = priv->w_stats.qual.level;
+ sinfo->txrate.legacy = rate.rate;
+
+ return ret;
+}
+
+/*
+ * CFG802.11 operation handler to get station information.
+ *
+ * This function only works in connected mode, and dumps the
+ * requested station information, if available.
+ */
+static int
+mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
+ u8 *mac, struct station_info *sinfo)
+{
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+
+ mwifiex_dump_station_info(priv, sinfo);
+
+ if (!priv->media_connected)
+ return -ENOENT;
+ if (memcmp(mac, priv->cfg_bssid, ETH_ALEN))
+ return -ENOENT;
+
+ return mwifiex_dump_station_info(priv, sinfo);
+}
+
+/* Supported rates to be advertised to the cfg80211 */
+
+static struct ieee80211_rate mwifiex_rates[] = {
+ {.bitrate = 10, .hw_value = 2, },
+ {.bitrate = 20, .hw_value = 4, },
+ {.bitrate = 55, .hw_value = 11, },
+ {.bitrate = 110, .hw_value = 22, },
+ {.bitrate = 220, .hw_value = 44, },
+ {.bitrate = 60, .hw_value = 12, },
+ {.bitrate = 90, .hw_value = 18, },
+ {.bitrate = 120, .hw_value = 24, },
+ {.bitrate = 180, .hw_value = 36, },
+ {.bitrate = 240, .hw_value = 48, },
+ {.bitrate = 360, .hw_value = 72, },
+ {.bitrate = 480, .hw_value = 96, },
+ {.bitrate = 540, .hw_value = 108, },
+ {.bitrate = 720, .hw_value = 144, },
+};
+
+/* Channel definitions to be advertised to cfg80211 */
+
+static struct ieee80211_channel mwifiex_channels_2ghz[] = {
+ {.center_freq = 2412, .hw_value = 1, },
+ {.center_freq = 2417, .hw_value = 2, },
+ {.center_freq = 2422, .hw_value = 3, },
+ {.center_freq = 2427, .hw_value = 4, },
+ {.center_freq = 2432, .hw_value = 5, },
+ {.center_freq = 2437, .hw_value = 6, },
+ {.center_freq = 2442, .hw_value = 7, },
+ {.center_freq = 2447, .hw_value = 8, },
+ {.center_freq = 2452, .hw_value = 9, },
+ {.center_freq = 2457, .hw_value = 10, },
+ {.center_freq = 2462, .hw_value = 11, },
+ {.center_freq = 2467, .hw_value = 12, },
+ {.center_freq = 2472, .hw_value = 13, },
+ {.center_freq = 2484, .hw_value = 14, },
+};
+
+static struct ieee80211_supported_band mwifiex_band_2ghz = {
+ .channels = mwifiex_channels_2ghz,
+ .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz),
+ .bitrates = mwifiex_rates,
+ .n_bitrates = 14,
+};
+
+static struct ieee80211_channel mwifiex_channels_5ghz[] = {
+ {.center_freq = 5040, .hw_value = 8, },
+ {.center_freq = 5060, .hw_value = 12, },
+ {.center_freq = 5080, .hw_value = 16, },
+ {.center_freq = 5170, .hw_value = 34, },
+ {.center_freq = 5190, .hw_value = 38, },
+ {.center_freq = 5210, .hw_value = 42, },
+ {.center_freq = 5230, .hw_value = 46, },
+ {.center_freq = 5180, .hw_value = 36, },
+ {.center_freq = 5200, .hw_value = 40, },
+ {.center_freq = 5220, .hw_value = 44, },
+ {.center_freq = 5240, .hw_value = 48, },
+ {.center_freq = 5260, .hw_value = 52, },
+ {.center_freq = 5280, .hw_value = 56, },
+ {.center_freq = 5300, .hw_value = 60, },
+ {.center_freq = 5320, .hw_value = 64, },
+ {.center_freq = 5500, .hw_value = 100, },
+ {.center_freq = 5520, .hw_value = 104, },
+ {.center_freq = 5540, .hw_value = 108, },
+ {.center_freq = 5560, .hw_value = 112, },
+ {.center_freq = 5580, .hw_value = 116, },
+ {.center_freq = 5600, .hw_value = 120, },
+ {.center_freq = 5620, .hw_value = 124, },
+ {.center_freq = 5640, .hw_value = 128, },
+ {.center_freq = 5660, .hw_value = 132, },
+ {.center_freq = 5680, .hw_value = 136, },
+ {.center_freq = 5700, .hw_value = 140, },
+ {.center_freq = 5745, .hw_value = 149, },
+ {.center_freq = 5765, .hw_value = 153, },
+ {.center_freq = 5785, .hw_value = 157, },
+ {.center_freq = 5805, .hw_value = 161, },
+ {.center_freq = 5825, .hw_value = 165, },
+};
+
+static struct ieee80211_supported_band mwifiex_band_5ghz = {
+ .channels = mwifiex_channels_5ghz,
+ .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz),
+ .bitrates = mwifiex_rates - 4,
+ .n_bitrates = ARRAY_SIZE(mwifiex_rates) + 4,
+};
+
+
+/* Supported crypto cipher suits to be advertised to cfg80211 */
+
+static const u32 mwifiex_cipher_suites[] = {
+ WLAN_CIPHER_SUITE_WEP40,
+ WLAN_CIPHER_SUITE_WEP104,
+ WLAN_CIPHER_SUITE_TKIP,
+ WLAN_CIPHER_SUITE_CCMP,
+};
+
+/*
+ * CFG802.11 operation handler for disconnection request.
+ *
+ * This function does not work when there is already a disconnection
+ * procedure going on.
+ */
+static int
+mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
+ u16 reason_code)
+{
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+
+ if (priv->disconnect)
+ return -EBUSY;
+
+ priv->disconnect = 1;
+ if (mwifiex_deauthenticate(priv, NULL))
+ return -EFAULT;
+
+ wiphy_dbg(wiphy, "info: successfully disconnected from %pM:"
+ " reason code %d\n", priv->cfg_bssid, reason_code);
+
+ queue_work(priv->workqueue, &priv->cfg_workqueue);
+
+ return 0;
+}
+
+/*
+ * This function informs the CFG802.11 subsystem of a new IBSS.
+ *
+ * The following information are sent to the CFG802.11 subsystem
+ * to register the new IBSS. If we do not register the new IBSS,
+ * a kernel panic will result.
+ * - SSID
+ * - SSID length
+ * - BSSID
+ * - Channel
+ */
+static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
+{
+ struct ieee80211_channel *chan;
+ struct mwifiex_bss_info bss_info;
+ int ie_len;
+ u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)];
+
+ if (mwifiex_get_bss_info(priv, &bss_info))
+ return -1;
+
+ ie_buf[0] = WLAN_EID_SSID;
+ ie_buf[1] = bss_info.ssid.ssid_len;
+
+ memcpy(&ie_buf[sizeof(struct ieee_types_header)],
+ &bss_info.ssid.ssid,
+ bss_info.ssid.ssid_len);
+ ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
+
+ chan = __ieee80211_get_channel(priv->wdev->wiphy,
+ ieee80211_channel_to_frequency(bss_info.bss_chan,
+ priv->curr_bss_params.band));
+
+ cfg80211_inform_bss(priv->wdev->wiphy, chan,
+ bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
+ 0, ie_buf, ie_len, 0, GFP_KERNEL);
+ memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN);
+
+ return 0;
+}
+
+/*
+ * This function informs the CFG802.11 subsystem of a new BSS connection.
+ *
+ * The following information are sent to the CFG802.11 subsystem
+ * to register the new BSS connection. If we do not register the new BSS,
+ * a kernel panic will result.
+ * - MAC address
+ * - Capabilities
+ * - Beacon period
+ * - RSSI value
+ * - Channel
+ * - Supported rates IE
+ * - Extended capabilities IE
+ * - DS parameter set IE
+ * - HT Capability IE
+ * - Vendor Specific IE (221)
+ * - WPA IE
+ * - RSN IE
+ */
+static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv,
+ struct mwifiex_802_11_ssid *ssid)
+{
+ struct mwifiex_bssdescriptor *scan_table;
+ int i, j;
+ struct ieee80211_channel *chan;
+ u8 *ie, *ie_buf;
+ u32 ie_len;
+ u8 *beacon;
+ int beacon_size;
+ u8 element_id, element_len;
+
+#define MAX_IE_BUF 2048
+ ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL);
+ if (!ie_buf) {
+ dev_err(priv->adapter->dev, "%s: failed to alloc ie_buf\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ scan_table = priv->adapter->scan_table;
+ for (i = 0; i < priv->adapter->num_in_scan_table; i++) {
+ if (ssid) {
+ /* Inform specific BSS only */
+ if (memcmp(ssid->ssid, scan_table[i].ssid.ssid,
+ ssid->ssid_len))
+ continue;
+ }
+ memset(ie_buf, 0, MAX_IE_BUF);
+ ie_buf[0] = WLAN_EID_SSID;
+ ie_buf[1] = scan_table[i].ssid.ssid_len;
+ memcpy(&ie_buf[sizeof(struct ieee_types_header)],
+ scan_table[i].ssid.ssid, ie_buf[1]);
+
+ ie = ie_buf + ie_buf[1] + sizeof(struct ieee_types_header);
+ ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
+
+ ie[0] = WLAN_EID_SUPP_RATES;
+
+ for (j = 0; j < sizeof(scan_table[i].supported_rates); j++) {
+ if (!scan_table[i].supported_rates[j])
+ break;
+ else
+ ie[j + sizeof(struct ieee_types_header)] =
+ scan_table[i].supported_rates[j];
+ }
+
+ ie[1] = j;
+ ie_len += ie[1] + sizeof(struct ieee_types_header);
+
+ beacon = scan_table[i].beacon_buf;
+ beacon_size = scan_table[i].beacon_buf_size;
+
+ /* Skip time stamp, beacon interval and capability */
+
+ if (beacon) {
+ beacon += sizeof(scan_table[i].beacon_period)
+ + sizeof(scan_table[i].time_stamp) +
+ +sizeof(scan_table[i].cap_info_bitmap);
+
+ beacon_size -= sizeof(scan_table[i].beacon_period)
+ + sizeof(scan_table[i].time_stamp)
+ + sizeof(scan_table[i].cap_info_bitmap);
+ }
+
+ while (beacon_size >= sizeof(struct ieee_types_header)) {
+ ie = ie_buf + ie_len;
+ element_id = *beacon;
+ element_len = *(beacon + 1);
+ if (beacon_size < (int) element_len +
+ sizeof(struct ieee_types_header)) {
+ dev_err(priv->adapter->dev, "%s: in processing"
+ " IE, bytes left < IE length\n",
+ __func__);
+ break;
+ }
+ switch (element_id) {
+ case WLAN_EID_EXT_CAPABILITY:
+ case WLAN_EID_DS_PARAMS:
+ case WLAN_EID_HT_CAPABILITY:
+ case WLAN_EID_VENDOR_SPECIFIC:
+ case WLAN_EID_RSN:
+ case WLAN_EID_BSS_AC_ACCESS_DELAY:
+ ie[0] = element_id;
+ ie[1] = element_len;
+ memcpy(&ie[sizeof(struct ieee_types_header)],
+ (u8 *) beacon
+ + sizeof(struct ieee_types_header),
+ element_len);
+ ie_len += ie[1] +
+ sizeof(struct ieee_types_header);
+ break;
+ default:
+ break;
+ }
+ beacon += element_len +
+ sizeof(struct ieee_types_header);
+ beacon_size -= element_len +
+ sizeof(struct ieee_types_header);
+ }
+ chan = ieee80211_get_channel(priv->wdev->wiphy,
+ scan_table[i].freq);
+ cfg80211_inform_bss(priv->wdev->wiphy, chan,
+ scan_table[i].mac_address,
+ 0, scan_table[i].cap_info_bitmap,
+ scan_table[i].beacon_period,
+ ie_buf, ie_len,
+ scan_table[i].rssi, GFP_KERNEL);
+ }
+
+ kfree(ie_buf);
+ return 0;
+}
+
+/*
+ * This function connects with a BSS.
+ *
+ * This function handles both Infra and Ad-Hoc modes. It also performs
+ * validity checking on the provided parameters, disconnects from the
+ * current BSS (if any), sets up the association/scan parameters,
+ * including security settings, and performs specific SSID scan before
+ * trying to connect.
+ *
+ * For Infra mode, the function returns failure if the specified SSID
+ * is not found in scan table. However, for Ad-Hoc mode, it can create
+ * the IBSS if it does not exist. On successful completion in either case,
+ * the function notifies the CFG802.11 subsystem of the new BSS connection,
+ * otherwise the kernel will panic.
+ */
+static int
+mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
+ u8 *bssid, int mode, struct ieee80211_channel *channel,
+ struct cfg80211_connect_params *sme, bool privacy)
+{
+ struct mwifiex_802_11_ssid req_ssid;
+ struct mwifiex_ssid_bssid ssid_bssid;
+ int ret, auth_type = 0;
+
+ memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid));
+ memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
+
+ req_ssid.ssid_len = ssid_len;
+ if (ssid_len > IEEE80211_MAX_SSID_LEN) {
+ dev_err(priv->adapter->dev, "invalid SSID - aborting\n");
+ return -EINVAL;
+ }
+
+ memcpy(req_ssid.ssid, ssid, ssid_len);
+ if (!req_ssid.ssid_len || req_ssid.ssid[0] < 0x20) {
+ dev_err(priv->adapter->dev, "invalid SSID - aborting\n");
+ return -EINVAL;
+ }
+
+ /* disconnect before try to associate */
+ mwifiex_deauthenticate(priv, NULL);
+
+ if (channel)
+ ret = mwifiex_set_rf_channel(priv, channel,
+ mwifiex_channels_to_cfg80211_channel_type
+ (priv->adapter->chan_offset));
+
+ ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); /* Disable keys */
+
+ if (mode == NL80211_IFTYPE_ADHOC) {
+ /* "privacy" is set only for ad-hoc mode */
+ if (privacy) {
+ /*
+ * Keep WLAN_CIPHER_SUITE_WEP104 for now so that
+ * the firmware can find a matching network from the
+ * scan. The cfg80211 does not give us the encryption
+ * mode at this stage so just setting it to WEP here.
+ */
+ priv->sec_info.encryption_mode =
+ WLAN_CIPHER_SUITE_WEP104;
+ priv->sec_info.authentication_mode =
+ NL80211_AUTHTYPE_OPEN_SYSTEM;
+ }
+
+ goto done;
+ }
+
+ /* Now handle infra mode. "sme" is valid for infra mode only */
+ if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC
+ || sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
+ auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
+ else if (sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
+ auth_type = NL80211_AUTHTYPE_SHARED_KEY;
+
+ if (sme->crypto.n_ciphers_pairwise) {
+ priv->sec_info.encryption_mode =
+ sme->crypto.ciphers_pairwise[0];
+ priv->sec_info.authentication_mode = auth_type;
+ }
+
+ if (sme->crypto.cipher_group) {
+ priv->sec_info.encryption_mode = sme->crypto.cipher_group;
+ priv->sec_info.authentication_mode = auth_type;
+ }
+ if (sme->ie)
+ ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len);
+
+ if (sme->key) {
+ if (mwifiex_is_alg_wep(0) | mwifiex_is_alg_wep(0)) {
+ dev_dbg(priv->adapter->dev,
+ "info: setting wep encryption"
+ " with key len %d\n", sme->key_len);
+ ret = mwifiex_set_encode(priv, sme->key, sme->key_len,
+ sme->key_idx, 0);
+ }
+ }
+done:
+ /* Do specific SSID scanning */
+ if (mwifiex_request_scan(priv, &req_ssid)) {
+ dev_err(priv->adapter->dev, "scan error\n");
+ return -EFAULT;
+ }
+
+
+ memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid));
+
+ if (mode != NL80211_IFTYPE_ADHOC) {
+ if (mwifiex_find_best_bss(priv, &ssid_bssid))
+ return -EFAULT;
+ /* Inform the BSS information to kernel, otherwise
+ * kernel will give a panic after successful assoc */
+ if (mwifiex_inform_bss_from_scan_result(priv, &req_ssid))
+ return -EFAULT;
+ }
+
+ dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n",
+ (char *) req_ssid.ssid, ssid_bssid.bssid);
+
+ memcpy(&priv->cfg_bssid, ssid_bssid.bssid, 6);
+
+ /* Connect to BSS by ESSID */
+ memset(&ssid_bssid.bssid, 0, ETH_ALEN);
+
+ if (!netif_queue_stopped(priv->netdev))
+ netif_stop_queue(priv->netdev);
+
+ if (mwifiex_bss_start(priv, &ssid_bssid))
+ return -EFAULT;
+
+ if (mode == NL80211_IFTYPE_ADHOC) {
+ /* Inform the BSS information to kernel, otherwise
+ * kernel will give a panic after successful assoc */
+ if (mwifiex_cfg80211_inform_ibss_bss(priv))
+ return -EFAULT;
+ }
+
+ return ret;
+}
+
+/*
+ * CFG802.11 operation handler for association request.
+ *
+ * This function does not work when the current mode is set to Ad-Hoc, or
+ * when there is already an association procedure going on. The given BSS
+ * information is used to associate.
+ */
+static int
+mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_connect_params *sme)
+{
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+ int ret = 0;
+
+ if (priv->assoc_request)
+ return -EBUSY;
+
+ if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
+ wiphy_err(wiphy, "received infra assoc request "
+ "when station is in ibss mode\n");
+ goto done;
+ }
+
+ priv->assoc_request = -EINPROGRESS;
+
+ wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
+ (char *) sme->ssid, sme->bssid);
+
+ ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
+ priv->bss_mode, sme->channel, sme, 0);
+
+ priv->assoc_request = 1;
+done:
+ priv->assoc_result = ret;
+ queue_work(priv->workqueue, &priv->cfg_workqueue);
+ return ret;
+}
+
+/*
+ * CFG802.11 operation handler to join an IBSS.
+ *
+ * This function does not work in any mode other than Ad-Hoc, or if
+ * a join operation is already in progress.
+ */
+static int
+mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_ibss_params *params)
+{
+ struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+ int ret = 0;
+
+ if (priv->ibss_join_request)
+ return -EBUSY;
+
+ if (priv->bss_mode != NL80211_IFTYPE_ADHOC) {
+ wiphy_err(wiphy, "request to join ibss received "
+ "when station is not in ibss mode\n");
+ goto done;
+ }
+
+ priv->ibss_join_request = -EINPROGRESS;
+
+ wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n",
+ (char *) params->ssid, params->bssid);
+
+ ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
+ params->bssid, priv->bss_mode,
+ params->channel, NULL, params->privacy);
+
+ priv->ibss_join_request = 1;
+done:
+ priv->ibss_join_result = ret;
+ queue_work(priv->workqueue, &priv->cfg_workqueue);
+ return ret;
+}
+
+/*
+ * CFG802.11 operation handler to leave an IBSS.
+ *
+ * This function does not work if a leave operation is
+ * already in progress.
+ */
+static int
+mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+{
+ struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+
+ if (priv->disconnect)
+ return -EBUSY;
+
+ priv->disconnect = 1;
+
+ wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
+ priv->cfg_bssid);
+ if (mwifiex_deauthenticate(priv, NULL))
+ return -EFAULT;
+
+ queue_work(priv->workqueue, &priv->cfg_workqueue);
+
+ return 0;
+}
+
+/*
+ * CFG802.11 operation handler for scan request.
+ *
+ * This function issues a scan request to the firmware based upon
+ * the user specified scan configuration. On successfull completion,
+ * it also informs the results.
+ */
+static int
+mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_scan_request *request)
+{
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+
+ wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);
+
+ if (priv->scan_request && priv->scan_request != request)
+ return -EBUSY;
+
+ priv->scan_request = request;
+
+ queue_work(priv->workqueue, &priv->cfg_workqueue);
+ return 0;
+}
+
+/*
+ * This function sets up the CFG802.11 specific HT capability fields
+ * with default values.
+ *
+ * The following default values are set -
+ * - HT Supported = True
+ * - Maximum AMPDU length factor = IEEE80211_HT_MAX_AMPDU_64K
+ * - Minimum AMPDU spacing = IEEE80211_HT_MPDU_DENSITY_NONE
+ * - HT Capabilities supported by firmware
+ * - MCS information, Rx mask = 0xff
+ * - MCD information, Tx parameters = IEEE80211_HT_MCS_TX_DEFINED (0x01)
+ */
+static void
+mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
+ struct mwifiex_private *priv)
+{
+ int rx_mcs_supp;
+ struct ieee80211_mcs_info mcs_set;
+ u8 *mcs = (u8 *)&mcs_set;
+ struct mwifiex_adapter *adapter = priv->adapter;
+
+ ht_info->ht_supported = true;
+ ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+ ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
+
+ memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
+
+ /* Fill HT capability information */
+ if (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
+ ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ else
+ ht_info->cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+
+ if (ISSUPP_SHORTGI20(adapter->hw_dot_11n_dev_cap))
+ ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
+ else
+ ht_info->cap &= ~IEEE80211_HT_CAP_SGI_20;
+
+ if (ISSUPP_SHORTGI40(adapter->hw_dot_11n_dev_cap))
+ ht_info->cap |= IEEE80211_HT_CAP_SGI_40;
+ else
+ ht_info->cap &= ~IEEE80211_HT_CAP_SGI_40;
+
+ if (ISSUPP_RXSTBC(adapter->hw_dot_11n_dev_cap))
+ ht_info->cap |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT;
+ else
+ ht_info->cap &= ~(3 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
+
+ if (ISSUPP_TXSTBC(adapter->hw_dot_11n_dev_cap))
+ ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
+ else
+ ht_info->cap &= ~IEEE80211_HT_CAP_TX_STBC;
+
+ ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
+ ht_info->cap |= IEEE80211_HT_CAP_SM_PS;
+
+ rx_mcs_supp = GET_RXMCSSUPP(adapter->hw_dev_mcs_support);
+ /* Set MCS for 1x1 */
+ memset(mcs, 0xff, rx_mcs_supp);
+ /* Clear all the other values */
+ memset(&mcs[rx_mcs_supp], 0,
+ sizeof(struct ieee80211_mcs_info) - rx_mcs_supp);
+ if (priv->bss_mode == NL80211_IFTYPE_STATION ||
+ ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
+ /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
+ SETHT_MCS32(mcs_set.rx_mask);
+
+ memcpy((u8 *) &ht_info->mcs, mcs, sizeof(struct ieee80211_mcs_info));
+
+ ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+}
+
+/* station cfg80211 operations */
+static struct cfg80211_ops mwifiex_cfg80211_ops = {
+ .change_virtual_intf = mwifiex_cfg80211_change_virtual_intf,
+ .scan = mwifiex_cfg80211_scan,
+ .connect = mwifiex_cfg80211_connect,
+ .disconnect = mwifiex_cfg80211_disconnect,
+ .get_station = mwifiex_cfg80211_get_station,
+ .set_wiphy_params = mwifiex_cfg80211_set_wiphy_params,
+ .set_channel = mwifiex_cfg80211_set_channel,
+ .join_ibss = mwifiex_cfg80211_join_ibss,
+ .leave_ibss = mwifiex_cfg80211_leave_ibss,
+ .add_key = mwifiex_cfg80211_add_key,
+ .del_key = mwifiex_cfg80211_del_key,
+ .set_default_key = mwifiex_cfg80211_set_default_key,
+ .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt,
+ .set_tx_power = mwifiex_cfg80211_set_tx_power,
+};
+
+/*
+ * This function registers the device with CFG802.11 subsystem.
+ *
+ * The function creates the wireless device/wiphy, populates it with
+ * default parameters and handler function pointers, and finally
+ * registers the device.
+ */
+int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac,
+ struct mwifiex_private *priv)
+{
+ int ret;
+ void *wdev_priv;
+ struct wireless_dev *wdev;
+
+ wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
+ if (!wdev) {
+ dev_err(priv->adapter->dev, "%s: allocating wireless device\n",
+ __func__);
+ return -ENOMEM;
+ }
+ wdev->wiphy =
+ wiphy_new(&mwifiex_cfg80211_ops,
+ sizeof(struct mwifiex_private *));
+ if (!wdev->wiphy) {
+ kfree(wdev);
+ return -ENOMEM;
+ }
+ wdev->iftype = NL80211_IFTYPE_STATION;
+ wdev->wiphy->max_scan_ssids = 10;
+ wdev->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
+
+ wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz;
+ mwifiex_setup_ht_caps(
+ &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv);
+
+ if (priv->adapter->config_bands & BAND_A) {
+ wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz;
+ mwifiex_setup_ht_caps(
+ &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv);
+ } else {
+ wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
+ }
+
+ /* Initialize cipher suits */
+ wdev->wiphy->cipher_suites = mwifiex_cipher_suites;
+ wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
+
+ memcpy(wdev->wiphy->perm_addr, mac, 6);
+ wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+
+ /* We are using custom domains */
+ wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+
+ wdev->wiphy->reg_notifier = mwifiex_reg_notifier;
+
+ /* Set struct mwifiex_private pointer in wiphy_priv */
+ wdev_priv = wiphy_priv(wdev->wiphy);
+
+ *(unsigned long *) wdev_priv = (unsigned long) priv;
+
+ ret = wiphy_register(wdev->wiphy);
+ if (ret < 0) {
+ dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n",
+ __func__);
+ wiphy_free(wdev->wiphy);
+ kfree(wdev);
+ return ret;
+ } else {
+ dev_dbg(priv->adapter->dev,
+ "info: successfully registered wiphy device\n");
+ }
+
+ dev_net_set(dev, wiphy_net(wdev->wiphy));
+ dev->ieee80211_ptr = wdev;
+ memcpy(dev->dev_addr, wdev->wiphy->perm_addr, 6);
+ memcpy(dev->perm_addr, wdev->wiphy->perm_addr, 6);
+ SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
+ priv->wdev = wdev;
+
+ dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
+ dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT;
+ dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN;
+
+ return ret;
+}
+
+/*
+ * This function handles the result of different pending network operations.
+ *
+ * The following operations are handled and CFG802.11 subsystem is
+ * notified accordingly -
+ * - Scan request completion
+ * - Association request completion
+ * - IBSS join request completion
+ * - Disconnect request completion
+ */
+void
+mwifiex_cfg80211_results(struct work_struct *work)
+{
+ struct mwifiex_private *priv =
+ container_of(work, struct mwifiex_private, cfg_workqueue);
+ struct mwifiex_user_scan_cfg *scan_req;
+ int ret = 0, i;
+ struct ieee80211_channel *chan;
+
+ if (priv->scan_request) {
+ scan_req = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
+ GFP_KERNEL);
+ if (!scan_req) {
+ dev_err(priv->adapter->dev, "failed to alloc "
+ "scan_req\n");
+ return;
+ }
+ for (i = 0; i < priv->scan_request->n_ssids; i++) {
+ memcpy(scan_req->ssid_list[i].ssid,
+ priv->scan_request->ssids[i].ssid,
+ priv->scan_request->ssids[i].ssid_len);
+ scan_req->ssid_list[i].max_len =
+ priv->scan_request->ssids[i].ssid_len;
+ }
+ for (i = 0; i < priv->scan_request->n_channels; i++) {
+ chan = priv->scan_request->channels[i];
+ scan_req->chan_list[i].chan_number = chan->hw_value;
+ scan_req->chan_list[i].radio_type = chan->band;
+ if (chan->flags & IEEE80211_CHAN_DISABLED)
+ scan_req->chan_list[i].scan_type =
+ MWIFIEX_SCAN_TYPE_PASSIVE;
+ else
+ scan_req->chan_list[i].scan_type =
+ MWIFIEX_SCAN_TYPE_ACTIVE;
+ scan_req->chan_list[i].scan_time = 0;
+ }
+ if (mwifiex_set_user_scan_ioctl(priv, scan_req)) {
+ ret = -EFAULT;
+ goto done;
+ }
+ if (mwifiex_inform_bss_from_scan_result(priv, NULL))
+ ret = -EFAULT;
+done:
+ priv->scan_result_status = ret;
+ dev_dbg(priv->adapter->dev, "info: %s: sending scan results\n",
+ __func__);
+ cfg80211_scan_done(priv->scan_request,
+ (priv->scan_result_status < 0));
+ priv->scan_request = NULL;
+ kfree(scan_req);
+ }
+
+ if (priv->assoc_request == 1) {
+ if (!priv->assoc_result) {
+ cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
+ NULL, 0, NULL, 0,
+ WLAN_STATUS_SUCCESS,
+ GFP_KERNEL);
+ dev_dbg(priv->adapter->dev,
+ "info: associated to bssid %pM successfully\n",
+ priv->cfg_bssid);
+ } else {
+ dev_dbg(priv->adapter->dev,
+ "info: association to bssid %pM failed\n",
+ priv->cfg_bssid);
+ memset(priv->cfg_bssid, 0, ETH_ALEN);
+ }
+ priv->assoc_request = 0;
+ priv->assoc_result = 0;
+ }
+
+ if (priv->ibss_join_request == 1) {
+ if (!priv->ibss_join_result) {
+ cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
+ GFP_KERNEL);
+ dev_dbg(priv->adapter->dev,
+ "info: joined/created adhoc network with bssid"
+ " %pM successfully\n", priv->cfg_bssid);
+ } else {
+ dev_dbg(priv->adapter->dev,
+ "info: failed creating/joining adhoc network\n");
+ }
+ priv->ibss_join_request = 0;
+ priv->ibss_join_result = 0;
+ }
+
+ if (priv->disconnect) {
+ memset(priv->cfg_bssid, 0, ETH_ALEN);
+ priv->disconnect = 0;
+ }
+}
diff --git a/drivers/net/wireless/mwifiex/cfg80211.h b/drivers/net/wireless/mwifiex/cfg80211.h
new file mode 100644
index 00000000000..c4db8f36aa1
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/cfg80211.h
@@ -0,0 +1,31 @@
+/*
+ * Marvell Wireless LAN device driver: CFG80211
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef __MWIFIEX_CFG80211__
+#define __MWIFIEX_CFG80211__
+
+#include <net/cfg80211.h>
+
+#include "main.h"
+
+int mwifiex_register_cfg80211(struct net_device *, u8 *,
+ struct mwifiex_private *);
+
+void mwifiex_cfg80211_results(struct work_struct *work);
+#endif
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
new file mode 100644
index 00000000000..d0cada5a29a
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -0,0 +1,360 @@
+/*
+ * Marvell Wireless LAN device driver: Channel, Frequence and Power
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "cfg80211.h"
+
+/* 100mW */
+#define MWIFIEX_TX_PWR_DEFAULT 20
+/* 100mW */
+#define MWIFIEX_TX_PWR_US_DEFAULT 20
+/* 50mW */
+#define MWIFIEX_TX_PWR_JP_DEFAULT 16
+/* 100mW */
+#define MWIFIEX_TX_PWR_FR_100MW 20
+/* 10mW */
+#define MWIFIEX_TX_PWR_FR_10MW 10
+/* 100mW */
+#define MWIFIEX_TX_PWR_EMEA_DEFAULT 20
+
+static u8 adhoc_rates_b[B_SUPPORTED_RATES] = { 0x82, 0x84, 0x8b, 0x96, 0 };
+
+static u8 adhoc_rates_g[G_SUPPORTED_RATES] = { 0x8c, 0x12, 0x98, 0x24,
+ 0xb0, 0x48, 0x60, 0x6c, 0 };
+
+static u8 adhoc_rates_bg[BG_SUPPORTED_RATES] = { 0x82, 0x84, 0x8b, 0x96,
+ 0x0c, 0x12, 0x18, 0x24,
+ 0x30, 0x48, 0x60, 0x6c, 0 };
+
+static u8 adhoc_rates_a[A_SUPPORTED_RATES] = { 0x8c, 0x12, 0x98, 0x24,
+ 0xb0, 0x48, 0x60, 0x6c, 0 };
+u8 supported_rates_a[A_SUPPORTED_RATES] = { 0x0c, 0x12, 0x18, 0x24,
+ 0xb0, 0x48, 0x60, 0x6c, 0 };
+static u16 mwifiex_data_rates[MWIFIEX_SUPPORTED_RATES_EXT] = { 0x02, 0x04,
+ 0x0B, 0x16, 0x00, 0x0C, 0x12, 0x18,
+ 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90,
+ 0x0D, 0x1A, 0x27, 0x34, 0x4E, 0x68,
+ 0x75, 0x82, 0x0C, 0x1B, 0x36, 0x51,
+ 0x6C, 0xA2, 0xD8, 0xF3, 0x10E, 0x00 };
+
+u8 supported_rates_b[B_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x16, 0 };
+
+u8 supported_rates_g[G_SUPPORTED_RATES] = { 0x0c, 0x12, 0x18, 0x24,
+ 0x30, 0x48, 0x60, 0x6c, 0 };
+
+u8 supported_rates_bg[BG_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x0c,
+ 0x12, 0x16, 0x18, 0x24, 0x30, 0x48,
+ 0x60, 0x6c, 0 };
+
+u16 region_code_index[MWIFIEX_MAX_REGION_CODE] = { 0x10, 0x20, 0x30,
+ 0x32, 0x40, 0x41, 0xff };
+
+u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 };
+
+/*
+ * This function maps an index in supported rates table into
+ * the corresponding data rate.
+ */
+u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info)
+{
+ u16 mcs_rate[4][8] = {
+ {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e}
+ , /* LG 40M */
+ {0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c}
+ , /* SG 40M */
+ {0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82}
+ , /* LG 20M */
+ {0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90}
+ }; /* SG 20M */
+
+ u32 rate;
+
+ if (ht_info & BIT(0)) {
+ if (index == MWIFIEX_RATE_BITMAP_MCS0) {
+ if (ht_info & BIT(2))
+ rate = 0x0D; /* MCS 32 SGI rate */
+ else
+ rate = 0x0C; /* MCS 32 LGI rate */
+ } else if (index < 8) {
+ if (ht_info & BIT(1)) {
+ if (ht_info & BIT(2))
+ /* SGI, 40M */
+ rate = mcs_rate[1][index];
+ else
+ /* LGI, 40M */
+ rate = mcs_rate[0][index];
+ } else {
+ if (ht_info & BIT(2))
+ /* SGI, 20M */
+ rate = mcs_rate[3][index];
+ else
+ /* LGI, 20M */
+ rate = mcs_rate[2][index];
+ }
+ } else
+ rate = mwifiex_data_rates[0];
+ } else {
+ if (index >= MWIFIEX_SUPPORTED_RATES_EXT)
+ index = 0;
+ rate = mwifiex_data_rates[index];
+ }
+ return rate;
+}
+
+/*
+ * This function maps a data rate value into corresponding index in supported
+ * rates table.
+ */
+u8 mwifiex_data_rate_to_index(u32 rate)
+{
+ u16 *ptr;
+
+ if (rate) {
+ ptr = memchr(mwifiex_data_rates, rate,
+ sizeof(mwifiex_data_rates));
+ if (ptr)
+ return (u8) (ptr - mwifiex_data_rates);
+ }
+ return 0;
+}
+
+/*
+ * This function returns the current active data rates.
+ *
+ * The result may vary depending upon connection status.
+ */
+u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates)
+{
+ if (!priv->media_connected)
+ return mwifiex_get_supported_rates(priv, rates);
+ else
+ return mwifiex_copy_rates(rates, 0,
+ priv->curr_bss_params.data_rates,
+ priv->curr_bss_params.num_of_rates);
+}
+
+/*
+ * This function locates the Channel-Frequency-Power triplet based upon
+ * band and channel parameters.
+ */
+struct mwifiex_chan_freq_power *
+mwifiex_get_cfp_by_band_and_channel_from_cfg80211(struct mwifiex_private
+ *priv, u8 band, u16 channel)
+{
+ struct mwifiex_chan_freq_power *cfp = NULL;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *ch;
+ int i;
+
+ if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG)
+ sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ];
+ else
+ sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ];
+
+ if (!sband) {
+ dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
+ " & channel %d\n", __func__, band, channel);
+ return cfp;
+ }
+
+ for (i = 0; i < sband->n_channels; i++) {
+ ch = &sband->channels[i];
+ if (((ch->hw_value == channel) ||
+ (channel == FIRST_VALID_CHANNEL))
+ && !(ch->flags & IEEE80211_CHAN_DISABLED)) {
+ priv->cfp.channel = channel;
+ priv->cfp.freq = ch->center_freq;
+ priv->cfp.max_tx_power = ch->max_power;
+ cfp = &priv->cfp;
+ break;
+ }
+ }
+ if (i == sband->n_channels)
+ dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
+ " & channel %d\n", __func__, band, channel);
+
+ return cfp;
+}
+
+/*
+ * This function locates the Channel-Frequency-Power triplet based upon
+ * band and frequency parameters.
+ */
+struct mwifiex_chan_freq_power *
+mwifiex_get_cfp_by_band_and_freq_from_cfg80211(struct mwifiex_private *priv,
+ u8 band, u32 freq)
+{
+ struct mwifiex_chan_freq_power *cfp = NULL;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *ch;
+ int i;
+
+ if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG)
+ sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ];
+ else
+ sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ];
+
+ if (!sband) {
+ dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
+ " & freq %d\n", __func__, band, freq);
+ return cfp;
+ }
+
+ for (i = 0; i < sband->n_channels; i++) {
+ ch = &sband->channels[i];
+ if ((ch->center_freq == freq) &&
+ !(ch->flags & IEEE80211_CHAN_DISABLED)) {
+ priv->cfp.channel = ch->hw_value;
+ priv->cfp.freq = freq;
+ priv->cfp.max_tx_power = ch->max_power;
+ cfp = &priv->cfp;
+ break;
+ }
+ }
+ if (i == sband->n_channels)
+ dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
+ " & freq %d\n", __func__, band, freq);
+
+ return cfp;
+}
+
+/*
+ * This function checks if the data rate is set to auto.
+ */
+u8
+mwifiex_is_rate_auto(struct mwifiex_private *priv)
+{
+ u32 i;
+ int rate_num = 0;
+
+ for (i = 0; i < ARRAY_SIZE(priv->bitmap_rates); i++)
+ if (priv->bitmap_rates[i])
+ rate_num++;
+
+ if (rate_num > 1)
+ return true;
+ else
+ return false;
+}
+
+/*
+ * This function converts rate bitmap into rate index.
+ */
+int mwifiex_get_rate_index(u16 *rate_bitmap, int size)
+{
+ int i;
+
+ for (i = 0; i < size * 8; i++)
+ if (rate_bitmap[i / 16] & (1 << (i % 16)))
+ return i;
+
+ return 0;
+}
+
+/*
+ * This function gets the supported data rates.
+ *
+ * The function works in both Ad-Hoc and infra mode by printing the
+ * band and returning the data rates.
+ */
+u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
+{
+ u32 k = 0;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+ switch (adapter->config_bands) {
+ case BAND_B:
+ dev_dbg(adapter->dev, "info: infra band=%d "
+ "supported_rates_b\n", adapter->config_bands);
+ k = mwifiex_copy_rates(rates, k, supported_rates_b,
+ sizeof(supported_rates_b));
+ break;
+ case BAND_G:
+ case BAND_G | BAND_GN:
+ dev_dbg(adapter->dev, "info: infra band=%d "
+ "supported_rates_g\n", adapter->config_bands);
+ k = mwifiex_copy_rates(rates, k, supported_rates_g,
+ sizeof(supported_rates_g));
+ break;
+ case BAND_B | BAND_G:
+ case BAND_A | BAND_B | BAND_G:
+ case BAND_A | BAND_B:
+ case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN:
+ case BAND_B | BAND_G | BAND_GN:
+ dev_dbg(adapter->dev, "info: infra band=%d "
+ "supported_rates_bg\n", adapter->config_bands);
+ k = mwifiex_copy_rates(rates, k, supported_rates_bg,
+ sizeof(supported_rates_bg));
+ break;
+ case BAND_A:
+ case BAND_A | BAND_G:
+ dev_dbg(adapter->dev, "info: infra band=%d "
+ "supported_rates_a\n", adapter->config_bands);
+ k = mwifiex_copy_rates(rates, k, supported_rates_a,
+ sizeof(supported_rates_a));
+ break;
+ case BAND_A | BAND_AN:
+ case BAND_A | BAND_G | BAND_AN | BAND_GN:
+ dev_dbg(adapter->dev, "info: infra band=%d "
+ "supported_rates_a\n", adapter->config_bands);
+ k = mwifiex_copy_rates(rates, k, supported_rates_a,
+ sizeof(supported_rates_a));
+ break;
+ case BAND_GN:
+ dev_dbg(adapter->dev, "info: infra band=%d "
+ "supported_rates_n\n", adapter->config_bands);
+ k = mwifiex_copy_rates(rates, k, supported_rates_n,
+ sizeof(supported_rates_n));
+ break;
+ }
+ } else {
+ /* Ad-hoc mode */
+ switch (adapter->adhoc_start_band) {
+ case BAND_B:
+ dev_dbg(adapter->dev, "info: adhoc B\n");
+ k = mwifiex_copy_rates(rates, k, adhoc_rates_b,
+ sizeof(adhoc_rates_b));
+ break;
+ case BAND_G:
+ case BAND_G | BAND_GN:
+ dev_dbg(adapter->dev, "info: adhoc G only\n");
+ k = mwifiex_copy_rates(rates, k, adhoc_rates_g,
+ sizeof(adhoc_rates_g));
+ break;
+ case BAND_B | BAND_G:
+ case BAND_B | BAND_G | BAND_GN:
+ dev_dbg(adapter->dev, "info: adhoc BG\n");
+ k = mwifiex_copy_rates(rates, k, adhoc_rates_bg,
+ sizeof(adhoc_rates_bg));
+ break;
+ case BAND_A:
+ case BAND_A | BAND_AN:
+ dev_dbg(adapter->dev, "info: adhoc A\n");
+ k = mwifiex_copy_rates(rates, k, adhoc_rates_a,
+ sizeof(adhoc_rates_a));
+ break;
+ }
+ }
+
+ return k;
+}
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
new file mode 100644
index 00000000000..cd89fed206a
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -0,0 +1,1414 @@
+/*
+ * Marvell Wireless LAN device driver: commands and events
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+/*
+ * This function initializes a command node.
+ *
+ * The actual allocation of the node is not done by this function. It only
+ * initiates a node by filling it with default parameters. Similarly,
+ * allocation of the different buffers used (IOCTL buffer, data buffer) are
+ * not done by this function either.
+ */
+static void
+mwifiex_init_cmd_node(struct mwifiex_private *priv,
+ struct cmd_ctrl_node *cmd_node,
+ u32 cmd_oid, void *data_buf)
+{
+ cmd_node->priv = priv;
+ cmd_node->cmd_oid = cmd_oid;
+ cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required;
+ priv->adapter->cmd_wait_q_required = false;
+ cmd_node->data_buf = data_buf;
+ cmd_node->cmd_skb = cmd_node->skb;
+}
+
+/*
+ * This function returns a command node from the free queue depending upon
+ * availability.
+ */
+static struct cmd_ctrl_node *
+mwifiex_get_cmd_node(struct mwifiex_adapter *adapter)
+{
+ struct cmd_ctrl_node *cmd_node;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->cmd_free_q_lock, flags);
+ if (list_empty(&adapter->cmd_free_q)) {
+ dev_err(adapter->dev, "GET_CMD_NODE: cmd node not available\n");
+ spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
+ return NULL;
+ }
+ cmd_node = list_first_entry(&adapter->cmd_free_q,
+ struct cmd_ctrl_node, list);
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
+
+ return cmd_node;
+}
+
+/*
+ * This function cleans up a command node.
+ *
+ * The function resets the fields including the buffer pointers.
+ * This function does not try to free the buffers. They must be
+ * freed before calling this function.
+ *
+ * This function will however call the receive completion callback
+ * in case a response buffer is still available before resetting
+ * the pointer.
+ */
+static void
+mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter,
+ struct cmd_ctrl_node *cmd_node)
+{
+ cmd_node->cmd_oid = 0;
+ cmd_node->cmd_flag = 0;
+ cmd_node->data_buf = NULL;
+ cmd_node->wait_q_enabled = false;
+
+ if (cmd_node->resp_skb) {
+ dev_kfree_skb_any(cmd_node->resp_skb);
+ cmd_node->resp_skb = NULL;
+ }
+}
+
+/*
+ * This function sends a host command to the firmware.
+ *
+ * The function copies the host command into the driver command
+ * buffer, which will be transferred to the firmware later by the
+ * main thread.
+ */
+static int mwifiex_cmd_host_cmd(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd, void *data_buf)
+{
+ struct mwifiex_ds_misc_cmd *pcmd_ptr =
+ (struct mwifiex_ds_misc_cmd *) data_buf;
+
+ /* Copy the HOST command to command buffer */
+ memcpy((void *) cmd, pcmd_ptr->cmd, pcmd_ptr->len);
+ dev_dbg(priv->adapter->dev, "cmd: host cmd size = %d\n", pcmd_ptr->len);
+ return 0;
+}
+
+/*
+ * This function downloads a command to the firmware.
+ *
+ * The function performs sanity tests, sets the command sequence
+ * number and size, converts the header fields to CPU format before
+ * sending. Afterwards, it logs the command ID and action for debugging
+ * and sets up the command timeout timer.
+ */
+static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
+ struct cmd_ctrl_node *cmd_node)
+{
+
+ struct mwifiex_adapter *adapter = priv->adapter;
+ int ret;
+ struct host_cmd_ds_command *host_cmd;
+ uint16_t cmd_code;
+ uint16_t cmd_size;
+ struct timeval tstamp;
+ unsigned long flags;
+
+ if (!adapter || !cmd_node)
+ return -1;
+
+ host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
+
+ /* Sanity test */
+ if (host_cmd == NULL || host_cmd->size == 0) {
+ dev_err(adapter->dev, "DNLD_CMD: host_cmd is null"
+ " or cmd size is 0, not sending\n");
+ if (cmd_node->wait_q_enabled)
+ adapter->cmd_wait_q.status = -1;
+ mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+ return -1;
+ }
+
+ /* Set command sequence number */
+ adapter->seq_num++;
+ host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO
+ (adapter->seq_num, cmd_node->priv->bss_num,
+ cmd_node->priv->bss_type));
+
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ adapter->curr_cmd = cmd_node;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+
+ cmd_code = le16_to_cpu(host_cmd->command);
+ cmd_size = le16_to_cpu(host_cmd->size);
+
+ skb_trim(cmd_node->cmd_skb, cmd_size);
+
+ do_gettimeofday(&tstamp);
+ dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d,"
+ " seqno %#x\n",
+ tstamp.tv_sec, tstamp.tv_usec, cmd_code,
+ le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size,
+ le16_to_cpu(host_cmd->seq_num));
+
+ skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN);
+
+ ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD,
+ cmd_node->cmd_skb->data,
+ cmd_node->cmd_skb->len, NULL);
+
+ skb_pull(cmd_node->cmd_skb, INTF_HEADER_LEN);
+
+ if (ret == -1) {
+ dev_err(adapter->dev, "DNLD_CMD: host to card failed\n");
+ if (cmd_node->wait_q_enabled)
+ adapter->cmd_wait_q.status = -1;
+ mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
+
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ adapter->curr_cmd = NULL;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+
+ adapter->dbg.num_cmd_host_to_card_failure++;
+ return -1;
+ }
+
+ /* Save the last command id and action to debug log */
+ adapter->dbg.last_cmd_index =
+ (adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM;
+ adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index] = cmd_code;
+ adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index] =
+ le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN));
+
+ /* Clear BSS_NO_BITS from HostCmd */
+ cmd_code &= HostCmd_CMD_ID_MASK;
+
+ /* Setup the timer after transmit command */
+ mod_timer(&adapter->cmd_timer,
+ jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000);
+
+ return 0;
+}
+
+/*
+ * This function downloads a sleep confirm command to the firmware.
+ *
+ * The function performs sanity tests, sets the command sequence
+ * number and size, converts the header fields to CPU format before
+ * sending.
+ *
+ * No responses are needed for sleep confirm command.
+ */
+static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
+{
+ int ret;
+ struct mwifiex_private *priv;
+ struct mwifiex_opt_sleep_confirm *sleep_cfm_buf =
+ (struct mwifiex_opt_sleep_confirm *)
+ adapter->sleep_cfm->data;
+ priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+
+ sleep_cfm_buf->seq_num =
+ cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO
+ (adapter->seq_num, priv->bss_num,
+ priv->bss_type)));
+ adapter->seq_num++;
+
+ skb_push(adapter->sleep_cfm, INTF_HEADER_LEN);
+ ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD,
+ adapter->sleep_cfm->data,
+ adapter->sleep_cfm->len, NULL);
+ skb_pull(adapter->sleep_cfm, INTF_HEADER_LEN);
+
+ if (ret == -1) {
+ dev_err(adapter->dev, "SLEEP_CFM: failed\n");
+ adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure++;
+ return -1;
+ }
+ if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY))
+ == MWIFIEX_BSS_ROLE_STA) {
+ if (!sleep_cfm_buf->resp_ctrl)
+ /* Response is not needed for sleep
+ confirm command */
+ adapter->ps_state = PS_STATE_SLEEP;
+ else
+ adapter->ps_state = PS_STATE_SLEEP_CFM;
+
+ if (!sleep_cfm_buf->resp_ctrl
+ && (adapter->is_hs_configured
+ && !adapter->sleep_period.period)) {
+ adapter->pm_wakeup_card_req = true;
+ mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
+ MWIFIEX_BSS_ROLE_STA), true);
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * This function allocates the command buffers and links them to
+ * the command free queue.
+ *
+ * The driver uses a pre allocated number of command buffers, which
+ * are created at driver initializations and freed at driver cleanup.
+ * Every command needs to obtain a command buffer from this pool before
+ * it can be issued. The command free queue lists the command buffers
+ * currently free to use, while the command pending queue lists the
+ * command buffers already in use and awaiting handling. Command buffers
+ * are returned to the free queue after use.
+ */
+int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter)
+{
+ struct cmd_ctrl_node *cmd_array;
+ u32 buf_size;
+ u32 i;
+
+ /* Allocate and initialize struct cmd_ctrl_node */
+ buf_size = sizeof(struct cmd_ctrl_node) * MWIFIEX_NUM_OF_CMD_BUFFER;
+ cmd_array = kzalloc(buf_size, GFP_KERNEL);
+ if (!cmd_array) {
+ dev_err(adapter->dev, "%s: failed to alloc cmd_array\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ adapter->cmd_pool = cmd_array;
+ memset(adapter->cmd_pool, 0, buf_size);
+
+ /* Allocate and initialize command buffers */
+ for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++) {
+ cmd_array[i].skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER);
+ if (!cmd_array[i].skb) {
+ dev_err(adapter->dev, "ALLOC_CMD_BUF: out of memory\n");
+ return -1;
+ }
+ }
+
+ for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++)
+ mwifiex_insert_cmd_to_free_q(adapter, &cmd_array[i]);
+
+ return 0;
+}
+
+/*
+ * This function frees the command buffers.
+ *
+ * The function calls the completion callback for all the command
+ * buffers that still have response buffers associated with them.
+ */
+int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter)
+{
+ struct cmd_ctrl_node *cmd_array;
+ u32 i;
+
+ /* Need to check if cmd pool is allocated or not */
+ if (!adapter->cmd_pool) {
+ dev_dbg(adapter->dev, "info: FREE_CMD_BUF: cmd_pool is null\n");
+ return 0;
+ }
+
+ cmd_array = adapter->cmd_pool;
+
+ /* Release shared memory buffers */
+ for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++) {
+ if (cmd_array[i].skb) {
+ dev_dbg(adapter->dev, "cmd: free cmd buffer %d\n", i);
+ dev_kfree_skb_any(cmd_array[i].skb);
+ }
+ if (!cmd_array[i].resp_skb)
+ continue;
+ dev_kfree_skb_any(cmd_array[i].resp_skb);
+ }
+ /* Release struct cmd_ctrl_node */
+ if (adapter->cmd_pool) {
+ dev_dbg(adapter->dev, "cmd: free cmd pool\n");
+ kfree(adapter->cmd_pool);
+ adapter->cmd_pool = NULL;
+ }
+
+ return 0;
+}
+
+/*
+ * This function handles events generated by firmware.
+ *
+ * Event body of events received from firmware are not used (though they are
+ * saved), only the event ID is used. Some events are re-invoked by
+ * the driver, with a new event body.
+ *
+ * After processing, the function calls the completion callback
+ * for cleanup.
+ */
+int mwifiex_process_event(struct mwifiex_adapter *adapter)
+{
+ int ret;
+ struct mwifiex_private *priv =
+ mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+ struct sk_buff *skb = adapter->event_skb;
+ u32 eventcause = adapter->event_cause;
+ struct timeval tstamp;
+ struct mwifiex_rxinfo *rx_info;
+
+ /* Save the last event to debug log */
+ adapter->dbg.last_event_index =
+ (adapter->dbg.last_event_index + 1) % DBG_CMD_NUM;
+ adapter->dbg.last_event[adapter->dbg.last_event_index] =
+ (u16) eventcause;
+
+ /* Get BSS number and corresponding priv */
+ priv = mwifiex_get_priv_by_id(adapter, EVENT_GET_BSS_NUM(eventcause),
+ EVENT_GET_BSS_TYPE(eventcause));
+ if (!priv)
+ priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+ /* Clear BSS_NO_BITS from event */
+ eventcause &= EVENT_ID_MASK;
+ adapter->event_cause = eventcause;
+
+ if (skb) {
+ rx_info = MWIFIEX_SKB_RXCB(skb);
+ rx_info->bss_index = priv->bss_index;
+ }
+
+ if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) {
+ do_gettimeofday(&tstamp);
+ dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n",
+ tstamp.tv_sec, tstamp.tv_usec, eventcause);
+ }
+
+ ret = mwifiex_process_sta_event(priv);
+
+ adapter->event_cause = 0;
+ adapter->event_skb = NULL;
+
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
+/*
+ * This function is used to send synchronous command to the firmware.
+ *
+ * it allocates a wait queue for the command and wait for the command
+ * response.
+ */
+int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
+ u16 cmd_action, u32 cmd_oid, void *data_buf)
+{
+ int ret = 0;
+ struct mwifiex_adapter *adapter = priv->adapter;
+
+ adapter->cmd_wait_q_required = true;
+ adapter->cmd_wait_q.condition = false;
+
+ ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid,
+ data_buf);
+ if (!ret)
+ ret = mwifiex_wait_queue_complete(adapter);
+
+ return ret;
+}
+
+
+/*
+ * This function prepares a command and asynchronously send it to the firmware.
+ *
+ * Preparation includes -
+ * - Sanity tests to make sure the card is still present or the FW
+ * is not reset
+ * - Getting a new command node from the command free queue
+ * - Initializing the command node for default parameters
+ * - Fill up the non-default parameters and buffer pointers
+ * - Add the command to pending queue
+ */
+int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
+ u16 cmd_action, u32 cmd_oid, void *data_buf)
+{
+ int ret;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct cmd_ctrl_node *cmd_node;
+ struct host_cmd_ds_command *cmd_ptr;
+
+ if (!adapter) {
+ pr_err("PREP_CMD: adapter is NULL\n");
+ return -1;
+ }
+
+ if (adapter->is_suspended) {
+ dev_err(adapter->dev, "PREP_CMD: device in suspended state\n");
+ return -1;
+ }
+
+ if (adapter->surprise_removed) {
+ dev_err(adapter->dev, "PREP_CMD: card is removed\n");
+ return -1;
+ }
+
+ if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET) {
+ if (cmd_no != HostCmd_CMD_FUNC_INIT) {
+ dev_err(adapter->dev, "PREP_CMD: FW in reset state\n");
+ return -1;
+ }
+ }
+
+ /* Get a new command node */
+ cmd_node = mwifiex_get_cmd_node(adapter);
+
+ if (!cmd_node) {
+ dev_err(adapter->dev, "PREP_CMD: no free cmd node\n");
+ return -1;
+ }
+
+ /* Initialize the command node */
+ mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf);
+
+ if (!cmd_node->cmd_skb) {
+ dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n");
+ return -1;
+ }
+
+ memset(skb_put(cmd_node->cmd_skb, sizeof(struct host_cmd_ds_command)),
+ 0, sizeof(struct host_cmd_ds_command));
+
+ cmd_ptr = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
+ cmd_ptr->command = cpu_to_le16(cmd_no);
+ cmd_ptr->result = 0;
+
+ /* Prepare command */
+ if (cmd_no) {
+ ret = mwifiex_sta_prepare_cmd(priv, cmd_no, cmd_action,
+ cmd_oid, data_buf, cmd_ptr);
+ } else {
+ ret = mwifiex_cmd_host_cmd(priv, cmd_ptr, data_buf);
+ cmd_node->cmd_flag |= CMD_F_HOSTCMD;
+ }
+
+ /* Return error, since the command preparation failed */
+ if (ret) {
+ dev_err(adapter->dev, "PREP_CMD: cmd %#x preparation failed\n",
+ cmd_no);
+ mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+ return -1;
+ }
+
+ /* Send command */
+ if (cmd_no == HostCmd_CMD_802_11_SCAN)
+ mwifiex_queue_scan_cmd(priv, cmd_node);
+ else
+ mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
+
+ return ret;
+}
+
+/*
+ * This function returns a command to the command free queue.
+ *
+ * The function also calls the completion callback if required, before
+ * cleaning the command node and re-inserting it into the free queue.
+ */
+void
+mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
+ struct cmd_ctrl_node *cmd_node)
+{
+ unsigned long flags;
+
+ if (!cmd_node)
+ return;
+
+ if (cmd_node->wait_q_enabled)
+ mwifiex_complete_cmd(adapter);
+ /* Clean the node */
+ mwifiex_clean_cmd_node(adapter, cmd_node);
+
+ /* Insert node into cmd_free_q */
+ spin_lock_irqsave(&adapter->cmd_free_q_lock, flags);
+ list_add_tail(&cmd_node->list, &adapter->cmd_free_q);
+ spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
+}
+
+/*
+ * This function queues a command to the command pending queue.
+ *
+ * This in effect adds the command to the command list to be executed.
+ * Exit PS command is handled specially, by placing it always to the
+ * front of the command queue.
+ */
+void
+mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
+ struct cmd_ctrl_node *cmd_node, u32 add_tail)
+{
+ struct host_cmd_ds_command *host_cmd = NULL;
+ u16 command;
+ unsigned long flags;
+
+ host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
+ if (!host_cmd) {
+ dev_err(adapter->dev, "QUEUE_CMD: host_cmd is NULL\n");
+ return;
+ }
+
+ command = le16_to_cpu(host_cmd->command);
+
+ /* Exit_PS command needs to be queued in the header always. */
+ if (command == HostCmd_CMD_802_11_PS_MODE_ENH) {
+ struct host_cmd_ds_802_11_ps_mode_enh *pm =
+ &host_cmd->params.psmode_enh;
+ if ((le16_to_cpu(pm->action) == DIS_PS)
+ || (le16_to_cpu(pm->action) == DIS_AUTO_PS)) {
+ if (adapter->ps_state != PS_STATE_AWAKE)
+ add_tail = false;
+ }
+ }
+
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+ if (add_tail)
+ list_add_tail(&cmd_node->list, &adapter->cmd_pending_q);
+ else
+ list_add(&cmd_node->list, &adapter->cmd_pending_q);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
+ dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x is queued\n", command);
+}
+
+/*
+ * This function executes the next command in command pending queue.
+ *
+ * This function will fail if a command is already in processing stage,
+ * otherwise it will dequeue the first command from the command pending
+ * queue and send to the firmware.
+ *
+ * If the device is currently in host sleep mode, any commands, except the
+ * host sleep configuration command will de-activate the host sleep. For PS
+ * mode, the function will put the firmware back to sleep if applicable.
+ */
+int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter)
+{
+ struct mwifiex_private *priv;
+ struct cmd_ctrl_node *cmd_node;
+ int ret = 0;
+ struct host_cmd_ds_command *host_cmd;
+ unsigned long cmd_flags;
+ unsigned long cmd_pending_q_flags;
+
+ /* Check if already in processing */
+ if (adapter->curr_cmd) {
+ dev_err(adapter->dev, "EXEC_NEXT_CMD: cmd in processing\n");
+ return -1;
+ }
+
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
+ /* Check if any command is pending */
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags);
+ if (list_empty(&adapter->cmd_pending_q)) {
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+ cmd_pending_q_flags);
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
+ return 0;
+ }
+ cmd_node = list_first_entry(&adapter->cmd_pending_q,
+ struct cmd_ctrl_node, list);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+ cmd_pending_q_flags);
+
+ host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
+ priv = cmd_node->priv;
+
+ if (adapter->ps_state != PS_STATE_AWAKE) {
+ dev_err(adapter->dev, "%s: cannot send cmd in sleep state,"
+ " this should not happen\n", __func__);
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
+ return ret;
+ }
+
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags);
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+ cmd_pending_q_flags);
+
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
+ ret = mwifiex_dnld_cmd_to_fw(priv, cmd_node);
+ priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+ /* Any command sent to the firmware when host is in sleep
+ * mode should de-configure host sleep. We should skip the
+ * host sleep configuration command itself though
+ */
+ if (priv && (host_cmd->command !=
+ cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH))) {
+ if (adapter->hs_activated) {
+ adapter->is_hs_configured = false;
+ mwifiex_hs_activated_event(priv, false);
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * This function handles the command response.
+ *
+ * After processing, the function cleans the command node and puts
+ * it back to the command free queue.
+ */
+int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
+{
+ struct host_cmd_ds_command *resp;
+ struct mwifiex_private *priv =
+ mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+ int ret = 0;
+ uint16_t orig_cmdresp_no;
+ uint16_t cmdresp_no;
+ uint16_t cmdresp_result;
+ struct timeval tstamp;
+ unsigned long flags;
+
+ /* Now we got response from FW, cancel the command timer */
+ del_timer(&adapter->cmd_timer);
+
+ if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) {
+ resp = (struct host_cmd_ds_command *) adapter->upld_buf;
+ dev_err(adapter->dev, "CMD_RESP: NULL curr_cmd, %#x\n",
+ le16_to_cpu(resp->command));
+ return -1;
+ }
+
+ adapter->num_cmd_timeout = 0;
+
+ resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data;
+ if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) {
+ dev_err(adapter->dev, "CMD_RESP: %#x been canceled\n",
+ le16_to_cpu(resp->command));
+ mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ adapter->curr_cmd = NULL;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+ return -1;
+ }
+
+ if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
+ /* Copy original response back to response buffer */
+ struct mwifiex_ds_misc_cmd *hostcmd = NULL;
+ uint16_t size = le16_to_cpu(resp->size);
+ dev_dbg(adapter->dev, "info: host cmd resp size = %d\n", size);
+ size = min_t(u16, size, MWIFIEX_SIZE_OF_CMD_BUFFER);
+ if (adapter->curr_cmd->data_buf) {
+ hostcmd = (struct mwifiex_ds_misc_cmd *)
+ adapter->curr_cmd->data_buf;
+ hostcmd->len = size;
+ memcpy(hostcmd->cmd, (void *) resp, size);
+ }
+ }
+ orig_cmdresp_no = le16_to_cpu(resp->command);
+
+ /* Get BSS number and corresponding priv */
+ priv = mwifiex_get_priv_by_id(adapter,
+ HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)),
+ HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num)));
+ if (!priv)
+ priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+ /* Clear RET_BIT from HostCmd */
+ resp->command = cpu_to_le16(orig_cmdresp_no & HostCmd_CMD_ID_MASK);
+
+ cmdresp_no = le16_to_cpu(resp->command);
+ cmdresp_result = le16_to_cpu(resp->result);
+
+ /* Save the last command response to debug log */
+ adapter->dbg.last_cmd_resp_index =
+ (adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM;
+ adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] =
+ orig_cmdresp_no;
+
+ do_gettimeofday(&tstamp);
+ dev_dbg(adapter->dev, "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d,"
+ " len %d, seqno 0x%x\n",
+ tstamp.tv_sec, tstamp.tv_usec, orig_cmdresp_no, cmdresp_result,
+ le16_to_cpu(resp->size), le16_to_cpu(resp->seq_num));
+
+ if (!(orig_cmdresp_no & HostCmd_RET_BIT)) {
+ dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n");
+ if (adapter->curr_cmd->wait_q_enabled)
+ adapter->cmd_wait_q.status = -1;
+
+ mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ adapter->curr_cmd = NULL;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+ return -1;
+ }
+
+ if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
+ adapter->curr_cmd->cmd_flag &= ~CMD_F_HOSTCMD;
+ if ((cmdresp_result == HostCmd_RESULT_OK)
+ && (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH))
+ ret = mwifiex_ret_802_11_hs_cfg(priv, resp);
+ } else {
+ /* handle response */
+ ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp);
+ }
+
+ /* Check init command response */
+ if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) {
+ if (ret == -1) {
+ dev_err(adapter->dev, "%s: cmd %#x failed during "
+ "initialization\n", __func__, cmdresp_no);
+ mwifiex_init_fw_complete(adapter);
+ return -1;
+ } else if (adapter->last_init_cmd == cmdresp_no)
+ adapter->hw_status = MWIFIEX_HW_STATUS_INIT_DONE;
+ }
+
+ if (adapter->curr_cmd) {
+ if (adapter->curr_cmd->wait_q_enabled && (!ret))
+ adapter->cmd_wait_q.status = 0;
+ else if (adapter->curr_cmd->wait_q_enabled && (ret == -1))
+ adapter->cmd_wait_q.status = -1;
+
+ /* Clean up and put current command back to cmd_free_q */
+ mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
+
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ adapter->curr_cmd = NULL;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+ }
+
+ return ret;
+}
+
+/*
+ * This function handles the timeout of command sending.
+ *
+ * It will re-send the same command again.
+ */
+void
+mwifiex_cmd_timeout_func(unsigned long function_context)
+{
+ struct mwifiex_adapter *adapter =
+ (struct mwifiex_adapter *) function_context;
+ struct cmd_ctrl_node *cmd_node;
+ struct timeval tstamp;
+
+ adapter->num_cmd_timeout++;
+ adapter->dbg.num_cmd_timeout++;
+ if (!adapter->curr_cmd) {
+ dev_dbg(adapter->dev, "cmd: empty curr_cmd\n");
+ return;
+ }
+ cmd_node = adapter->curr_cmd;
+ if (cmd_node->wait_q_enabled)
+ adapter->cmd_wait_q.status = -ETIMEDOUT;
+
+ if (cmd_node) {
+ adapter->dbg.timeout_cmd_id =
+ adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index];
+ adapter->dbg.timeout_cmd_act =
+ adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index];
+ do_gettimeofday(&tstamp);
+ dev_err(adapter->dev, "%s: Timeout cmd id (%lu.%lu) = %#x,"
+ " act = %#x\n", __func__,
+ tstamp.tv_sec, tstamp.tv_usec,
+ adapter->dbg.timeout_cmd_id,
+ adapter->dbg.timeout_cmd_act);
+
+ dev_err(adapter->dev, "num_data_h2c_failure = %d\n",
+ adapter->dbg.num_tx_host_to_card_failure);
+ dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n",
+ adapter->dbg.num_cmd_host_to_card_failure);
+
+ dev_err(adapter->dev, "num_cmd_timeout = %d\n",
+ adapter->dbg.num_cmd_timeout);
+ dev_err(adapter->dev, "num_tx_timeout = %d\n",
+ adapter->dbg.num_tx_timeout);
+
+ dev_err(adapter->dev, "last_cmd_index = %d\n",
+ adapter->dbg.last_cmd_index);
+ print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET,
+ adapter->dbg.last_cmd_id, DBG_CMD_NUM);
+ print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET,
+ adapter->dbg.last_cmd_act, DBG_CMD_NUM);
+
+ dev_err(adapter->dev, "last_cmd_resp_index = %d\n",
+ adapter->dbg.last_cmd_resp_index);
+ print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET,
+ adapter->dbg.last_cmd_resp_id, DBG_CMD_NUM);
+
+ dev_err(adapter->dev, "last_event_index = %d\n",
+ adapter->dbg.last_event_index);
+ print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET,
+ adapter->dbg.last_event, DBG_CMD_NUM);
+
+ dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n",
+ adapter->data_sent, adapter->cmd_sent);
+
+ dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n",
+ adapter->ps_mode, adapter->ps_state);
+ }
+ if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
+ mwifiex_init_fw_complete(adapter);
+}
+
+/*
+ * This function cancels all the pending commands.
+ *
+ * The current command, all commands in command pending queue and all scan
+ * commands in scan pending queue are cancelled. All the completion callbacks
+ * are called with failure status to ensure cleanup.
+ */
+void
+mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
+{
+ struct cmd_ctrl_node *cmd_node = NULL, *tmp_node;
+ unsigned long flags;
+
+ /* Cancel current cmd */
+ if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) {
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ adapter->curr_cmd->wait_q_enabled = false;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+ adapter->cmd_wait_q.status = -1;
+ mwifiex_complete_cmd(adapter);
+ }
+ /* Cancel all pending command */
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+ list_for_each_entry_safe(cmd_node, tmp_node,
+ &adapter->cmd_pending_q, list) {
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
+ if (cmd_node->wait_q_enabled) {
+ adapter->cmd_wait_q.status = -1;
+ mwifiex_complete_cmd(adapter);
+ cmd_node->wait_q_enabled = false;
+ }
+ mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+ }
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
+ /* Cancel all pending scan command */
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ list_for_each_entry_safe(cmd_node, tmp_node,
+ &adapter->scan_pending_q, list) {
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
+ cmd_node->wait_q_enabled = false;
+ mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ }
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ adapter->scan_processing = false;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+}
+
+/*
+ * This function cancels all pending commands that matches with
+ * the given IOCTL request.
+ *
+ * Both the current command buffer and the pending command queue are
+ * searched for matching IOCTL request. The completion callback of
+ * the matched command is called with failure status to ensure cleanup.
+ * In case of scan commands, all pending commands in scan pending queue
+ * are cancelled.
+ */
+void
+mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
+{
+ struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
+ unsigned long cmd_flags;
+ unsigned long cmd_pending_q_flags;
+ unsigned long scan_pending_q_flags;
+ uint16_t cancel_scan_cmd = false;
+
+ if ((adapter->curr_cmd) &&
+ (adapter->curr_cmd->wait_q_enabled)) {
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
+ cmd_node = adapter->curr_cmd;
+ cmd_node->wait_q_enabled = false;
+ cmd_node->cmd_flag |= CMD_F_CANCELED;
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock,
+ cmd_pending_q_flags);
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+ cmd_pending_q_flags);
+ mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
+ }
+
+ /* Cancel all pending scan command */
+ spin_lock_irqsave(&adapter->scan_pending_q_lock,
+ scan_pending_q_flags);
+ list_for_each_entry_safe(cmd_node, tmp_node,
+ &adapter->scan_pending_q, list) {
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+ scan_pending_q_flags);
+ cmd_node->wait_q_enabled = false;
+ mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+ spin_lock_irqsave(&adapter->scan_pending_q_lock,
+ scan_pending_q_flags);
+ cancel_scan_cmd = true;
+ }
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+ scan_pending_q_flags);
+
+ if (cancel_scan_cmd) {
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
+ adapter->scan_processing = false;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
+ }
+ adapter->cmd_wait_q.status = -1;
+ mwifiex_complete_cmd(adapter);
+}
+
+/*
+ * This function sends the sleep confirm command to firmware, if
+ * possible.
+ *
+ * The sleep confirm command cannot be issued if command response,
+ * data response or event response is awaiting handling, or if we
+ * are in the middle of sending a command, or expecting a command
+ * response.
+ */
+void
+mwifiex_check_ps_cond(struct mwifiex_adapter *adapter)
+{
+ if (!adapter->cmd_sent &&
+ !adapter->curr_cmd && !IS_CARD_RX_RCVD(adapter))
+ mwifiex_dnld_sleep_confirm_cmd(adapter);
+ else
+ dev_dbg(adapter->dev,
+ "cmd: Delay Sleep Confirm (%s%s%s)\n",
+ (adapter->cmd_sent) ? "D" : "",
+ (adapter->curr_cmd) ? "C" : "",
+ (IS_CARD_RX_RCVD(adapter)) ? "R" : "");
+}
+
+/*
+ * This function sends a Host Sleep activated event to applications.
+ *
+ * This event is generated by the driver, with a blank event body.
+ */
+void
+mwifiex_hs_activated_event(struct mwifiex_private *priv, u8 activated)
+{
+ if (activated) {
+ if (priv->adapter->is_hs_configured) {
+ priv->adapter->hs_activated = true;
+ dev_dbg(priv->adapter->dev, "event: hs_activated\n");
+ priv->adapter->hs_activate_wait_q_woken = true;
+ wake_up_interruptible(
+ &priv->adapter->hs_activate_wait_q);
+ } else {
+ dev_dbg(priv->adapter->dev, "event: HS not configured\n");
+ }
+ } else {
+ dev_dbg(priv->adapter->dev, "event: hs_deactivated\n");
+ priv->adapter->hs_activated = false;
+ }
+}
+
+/*
+ * This function handles the command response of a Host Sleep configuration
+ * command.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and setting the current host sleep activation status in driver.
+ *
+ * In case host sleep status change, the function generates an event to
+ * notify the applications.
+ */
+int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct host_cmd_ds_802_11_hs_cfg_enh *phs_cfg =
+ &resp->params.opt_hs_cfg;
+ uint32_t conditions = le32_to_cpu(phs_cfg->params.hs_config.conditions);
+
+ if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE)) {
+ mwifiex_hs_activated_event(priv, true);
+ return 0;
+ } else {
+ dev_dbg(adapter->dev, "cmd: CMD_RESP: HS_CFG cmd reply"
+ " result=%#x, conditions=0x%x gpio=0x%x gap=0x%x\n",
+ resp->result, conditions,
+ phs_cfg->params.hs_config.gpio,
+ phs_cfg->params.hs_config.gap);
+ }
+ if (conditions != HOST_SLEEP_CFG_CANCEL) {
+ adapter->is_hs_configured = true;
+ } else {
+ adapter->is_hs_configured = false;
+ if (adapter->hs_activated)
+ mwifiex_hs_activated_event(priv, false);
+ }
+
+ return 0;
+}
+
+/*
+ * This function wakes up the adapter and generates a Host Sleep
+ * cancel event on receiving the power up interrupt.
+ */
+void
+mwifiex_process_hs_config(struct mwifiex_adapter *adapter)
+{
+ dev_dbg(adapter->dev, "info: %s: auto cancelling host sleep"
+ " since there is interrupt from the firmware\n", __func__);
+
+ adapter->if_ops.wakeup(adapter);
+ adapter->hs_activated = false;
+ adapter->is_hs_configured = false;
+ mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
+ MWIFIEX_BSS_ROLE_ANY), false);
+}
+
+/*
+ * This function handles the command response of a sleep confirm command.
+ *
+ * The function sets the card state to SLEEP if the response indicates success.
+ */
+void
+mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter,
+ u8 *pbuf, u32 upld_len)
+{
+ struct host_cmd_ds_command *cmd = (struct host_cmd_ds_command *) pbuf;
+ struct mwifiex_private *priv =
+ mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+ uint16_t result = le16_to_cpu(cmd->result);
+ uint16_t command = le16_to_cpu(cmd->command);
+ uint16_t seq_num = le16_to_cpu(cmd->seq_num);
+
+ if (!upld_len) {
+ dev_err(adapter->dev, "%s: cmd size is 0\n", __func__);
+ return;
+ }
+
+ /* Get BSS number and corresponding priv */
+ priv = mwifiex_get_priv_by_id(adapter, HostCmd_GET_BSS_NO(seq_num),
+ HostCmd_GET_BSS_TYPE(seq_num));
+ if (!priv)
+ priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+
+ /* Update sequence number */
+ seq_num = HostCmd_GET_SEQ_NO(seq_num);
+ /* Clear RET_BIT from HostCmd */
+ command &= HostCmd_CMD_ID_MASK;
+
+ if (command != HostCmd_CMD_802_11_PS_MODE_ENH) {
+ dev_err(adapter->dev, "%s: received unexpected response for"
+ " cmd %x, result = %x\n", __func__, command, result);
+ return;
+ }
+
+ if (result) {
+ dev_err(adapter->dev, "%s: sleep confirm cmd failed\n",
+ __func__);
+ adapter->pm_wakeup_card_req = false;
+ adapter->ps_state = PS_STATE_AWAKE;
+ return;
+ }
+ adapter->pm_wakeup_card_req = true;
+ if (adapter->is_hs_configured)
+ mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
+ MWIFIEX_BSS_ROLE_ANY), true);
+ adapter->ps_state = PS_STATE_SLEEP;
+ cmd->command = cpu_to_le16(command);
+ cmd->seq_num = cpu_to_le16(seq_num);
+}
+EXPORT_SYMBOL_GPL(mwifiex_process_sleep_confirm_resp);
+
+/*
+ * This function prepares an enhanced power mode command.
+ *
+ * This function can be used to disable power save or to configure
+ * power save with auto PS or STA PS or auto deep sleep.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting Power Save bitmap, PS parameters TLV, PS mode TLV,
+ * auto deep sleep TLV (as required)
+ * - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ u16 cmd_action, uint16_t ps_bitmap,
+ void *data_buf)
+{
+ struct host_cmd_ds_802_11_ps_mode_enh *psmode_enh =
+ &cmd->params.psmode_enh;
+ u8 *tlv;
+ u16 cmd_size = 0;
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
+ if (cmd_action == DIS_AUTO_PS) {
+ psmode_enh->action = cpu_to_le16(DIS_AUTO_PS);
+ psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
+ cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) +
+ sizeof(psmode_enh->params.ps_bitmap));
+ } else if (cmd_action == GET_PS) {
+ psmode_enh->action = cpu_to_le16(GET_PS);
+ psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
+ cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) +
+ sizeof(psmode_enh->params.ps_bitmap));
+ } else if (cmd_action == EN_AUTO_PS) {
+ psmode_enh->action = cpu_to_le16(EN_AUTO_PS);
+ psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
+ cmd_size = S_DS_GEN + sizeof(psmode_enh->action) +
+ sizeof(psmode_enh->params.ps_bitmap);
+ tlv = (u8 *) cmd + cmd_size;
+ if (ps_bitmap & BITMAP_STA_PS) {
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct mwifiex_ie_types_ps_param *ps_tlv =
+ (struct mwifiex_ie_types_ps_param *) tlv;
+ struct mwifiex_ps_param *ps_mode = &ps_tlv->param;
+ ps_tlv->header.type = cpu_to_le16(TLV_TYPE_PS_PARAM);
+ ps_tlv->header.len = cpu_to_le16(sizeof(*ps_tlv) -
+ sizeof(struct mwifiex_ie_types_header));
+ cmd_size += sizeof(*ps_tlv);
+ tlv += sizeof(*ps_tlv);
+ dev_dbg(adapter->dev, "cmd: PS Command: Enter PS\n");
+ ps_mode->null_pkt_interval =
+ cpu_to_le16(adapter->null_pkt_interval);
+ ps_mode->multiple_dtims =
+ cpu_to_le16(adapter->multiple_dtim);
+ ps_mode->bcn_miss_timeout =
+ cpu_to_le16(adapter->bcn_miss_time_out);
+ ps_mode->local_listen_interval =
+ cpu_to_le16(adapter->local_listen_interval);
+ ps_mode->adhoc_wake_period =
+ cpu_to_le16(adapter->adhoc_awake_period);
+ ps_mode->delay_to_ps =
+ cpu_to_le16(adapter->delay_to_ps);
+ ps_mode->mode =
+ cpu_to_le16(adapter->enhanced_ps_mode);
+
+ }
+ if (ps_bitmap & BITMAP_AUTO_DS) {
+ struct mwifiex_ie_types_auto_ds_param *auto_ds_tlv =
+ (struct mwifiex_ie_types_auto_ds_param *) tlv;
+ u16 idletime = 0;
+
+ auto_ds_tlv->header.type =
+ cpu_to_le16(TLV_TYPE_AUTO_DS_PARAM);
+ auto_ds_tlv->header.len =
+ cpu_to_le16(sizeof(*auto_ds_tlv) -
+ sizeof(struct mwifiex_ie_types_header));
+ cmd_size += sizeof(*auto_ds_tlv);
+ tlv += sizeof(*auto_ds_tlv);
+ if (data_buf)
+ idletime = ((struct mwifiex_ds_auto_ds *)
+ data_buf)->idle_time;
+ dev_dbg(priv->adapter->dev,
+ "cmd: PS Command: Enter Auto Deep Sleep\n");
+ auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime);
+ }
+ cmd->size = cpu_to_le16(cmd_size);
+ }
+ return 0;
+}
+
+/*
+ * This function handles the command response of an enhanced power mode
+ * command.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and setting the current enhanced power mode in driver.
+ */
+int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp,
+ void *data_buf)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct host_cmd_ds_802_11_ps_mode_enh *ps_mode =
+ &resp->params.psmode_enh;
+ uint16_t action = le16_to_cpu(ps_mode->action);
+ uint16_t ps_bitmap = le16_to_cpu(ps_mode->params.ps_bitmap);
+ uint16_t auto_ps_bitmap =
+ le16_to_cpu(ps_mode->params.ps_bitmap);
+
+ dev_dbg(adapter->dev, "info: %s: PS_MODE cmd reply result=%#x action=%#X\n",
+ __func__, resp->result, action);
+ if (action == EN_AUTO_PS) {
+ if (auto_ps_bitmap & BITMAP_AUTO_DS) {
+ dev_dbg(adapter->dev, "cmd: Enabled auto deep sleep\n");
+ priv->adapter->is_deep_sleep = true;
+ }
+ if (auto_ps_bitmap & BITMAP_STA_PS) {
+ dev_dbg(adapter->dev, "cmd: Enabled STA power save\n");
+ if (adapter->sleep_period.period)
+ dev_dbg(adapter->dev, "cmd: set to uapsd/pps mode\n");
+ }
+ } else if (action == DIS_AUTO_PS) {
+ if (ps_bitmap & BITMAP_AUTO_DS) {
+ priv->adapter->is_deep_sleep = false;
+ dev_dbg(adapter->dev, "cmd: Disabled auto deep sleep\n");
+ }
+ if (ps_bitmap & BITMAP_STA_PS) {
+ dev_dbg(adapter->dev, "cmd: Disabled STA power save\n");
+ if (adapter->sleep_period.period) {
+ adapter->delay_null_pkt = false;
+ adapter->tx_lock_flag = false;
+ adapter->pps_uapsd_mode = false;
+ }
+ }
+ } else if (action == GET_PS) {
+ if (ps_bitmap & BITMAP_STA_PS)
+ adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
+ else
+ adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
+
+ dev_dbg(adapter->dev, "cmd: ps_bitmap=%#x\n", ps_bitmap);
+
+ if (data_buf) {
+ /* This section is for get power save mode */
+ struct mwifiex_ds_pm_cfg *pm_cfg =
+ (struct mwifiex_ds_pm_cfg *)data_buf;
+ if (ps_bitmap & BITMAP_STA_PS)
+ pm_cfg->param.ps_mode = 1;
+ else
+ pm_cfg->param.ps_mode = 0;
+ }
+ }
+ return 0;
+}
+
+/*
+ * This function prepares command to get hardware specifications.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting permanent address parameter
+ * - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_get_hw_spec(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd)
+{
+ struct host_cmd_ds_get_hw_spec *hw_spec = &cmd->params.hw_spec;
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_GET_HW_SPEC);
+ cmd->size =
+ cpu_to_le16(sizeof(struct host_cmd_ds_get_hw_spec) + S_DS_GEN);
+ memcpy(hw_spec->permanent_addr, priv->curr_addr, ETH_ALEN);
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of get hardware
+ * specifications.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and saving/updating the following parameters in driver -
+ * - Firmware capability information
+ * - Firmware band settings
+ * - Ad-hoc start band and channel
+ * - Ad-hoc 11n activation status
+ * - Firmware release number
+ * - Number of antennas
+ * - Hardware address
+ * - Hardware interface version
+ * - Firmware version
+ * - Region code
+ * - 11n capabilities
+ * - MCS support fields
+ * - MP end port
+ */
+int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ struct host_cmd_ds_get_hw_spec *hw_spec = &resp->params.hw_spec;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ int i;
+
+ adapter->fw_cap_info = le32_to_cpu(hw_spec->fw_cap_info);
+
+ if (IS_SUPPORT_MULTI_BANDS(adapter))
+ adapter->fw_bands = (u8) GET_FW_DEFAULT_BANDS(adapter);
+ else
+ adapter->fw_bands = BAND_B;
+
+ adapter->config_bands = adapter->fw_bands;
+
+ if (adapter->fw_bands & BAND_A) {
+ if (adapter->fw_bands & BAND_GN) {
+ adapter->config_bands |= BAND_AN;
+ adapter->fw_bands |= BAND_AN;
+ }
+ if (adapter->fw_bands & BAND_AN) {
+ adapter->adhoc_start_band = BAND_A | BAND_AN;
+ adapter->adhoc_11n_enabled = true;
+ } else {
+ adapter->adhoc_start_band = BAND_A;
+ }
+ priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL_A;
+ } else if (adapter->fw_bands & BAND_GN) {
+ adapter->adhoc_start_band = BAND_G | BAND_B | BAND_GN;
+ priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
+ adapter->adhoc_11n_enabled = true;
+ } else if (adapter->fw_bands & BAND_G) {
+ adapter->adhoc_start_band = BAND_G | BAND_B;
+ priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
+ } else if (adapter->fw_bands & BAND_B) {
+ adapter->adhoc_start_band = BAND_B;
+ priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
+ }
+
+ adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number);
+ adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna);
+
+ dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n",
+ adapter->fw_release_number);
+ dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n",
+ hw_spec->permanent_addr);
+ dev_dbg(adapter->dev, "info: GET_HW_SPEC: hw_if_version=%#x version=%#x\n",
+ le16_to_cpu(hw_spec->hw_if_version),
+ le16_to_cpu(hw_spec->version));
+
+ if (priv->curr_addr[0] == 0xff)
+ memmove(priv->curr_addr, hw_spec->permanent_addr, ETH_ALEN);
+
+ adapter->region_code = le16_to_cpu(hw_spec->region_code);
+
+ for (i = 0; i < MWIFIEX_MAX_REGION_CODE; i++)
+ /* Use the region code to search for the index */
+ if (adapter->region_code == region_code_index[i])
+ break;
+
+ /* If it's unidentified region code, use the default (USA) */
+ if (i >= MWIFIEX_MAX_REGION_CODE) {
+ adapter->region_code = 0x10;
+ dev_dbg(adapter->dev, "cmd: unknown region code, use default (USA)\n");
+ }
+
+ adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap);
+ adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support;
+
+ if (adapter->if_ops.update_mp_end_port)
+ adapter->if_ops.update_mp_end_port(adapter,
+ le16_to_cpu(hw_spec->mp_end_port));
+
+ return 0;
+}
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
new file mode 100644
index 00000000000..46d65e02c7b
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -0,0 +1,770 @@
+/*
+ * Marvell Wireless LAN device driver: debugfs
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include <linux/debugfs.h>
+
+#include "main.h"
+#include "11n.h"
+
+
+static struct dentry *mwifiex_dfs_dir;
+
+static char *bss_modes[] = {
+ "Unknown",
+ "Managed",
+ "Ad-hoc",
+ "Auto"
+};
+
+/* size/addr for mwifiex_debug_info */
+#define item_size(n) (FIELD_SIZEOF(struct mwifiex_debug_info, n))
+#define item_addr(n) (offsetof(struct mwifiex_debug_info, n))
+
+/* size/addr for struct mwifiex_adapter */
+#define adapter_item_size(n) (FIELD_SIZEOF(struct mwifiex_adapter, n))
+#define adapter_item_addr(n) (offsetof(struct mwifiex_adapter, n))
+
+struct mwifiex_debug_data {
+ char name[32]; /* variable/array name */
+ u32 size; /* size of the variable/array */
+ size_t addr; /* address of the variable/array */
+ int num; /* number of variables in an array */
+};
+
+static struct mwifiex_debug_data items[] = {
+ {"int_counter", item_size(int_counter),
+ item_addr(int_counter), 1},
+ {"wmm_ac_vo", item_size(packets_out[WMM_AC_VO]),
+ item_addr(packets_out[WMM_AC_VO]), 1},
+ {"wmm_ac_vi", item_size(packets_out[WMM_AC_VI]),
+ item_addr(packets_out[WMM_AC_VI]), 1},
+ {"wmm_ac_be", item_size(packets_out[WMM_AC_BE]),
+ item_addr(packets_out[WMM_AC_BE]), 1},
+ {"wmm_ac_bk", item_size(packets_out[WMM_AC_BK]),
+ item_addr(packets_out[WMM_AC_BK]), 1},
+ {"max_tx_buf_size", item_size(max_tx_buf_size),
+ item_addr(max_tx_buf_size), 1},
+ {"tx_buf_size", item_size(tx_buf_size),
+ item_addr(tx_buf_size), 1},
+ {"curr_tx_buf_size", item_size(curr_tx_buf_size),
+ item_addr(curr_tx_buf_size), 1},
+ {"ps_mode", item_size(ps_mode),
+ item_addr(ps_mode), 1},
+ {"ps_state", item_size(ps_state),
+ item_addr(ps_state), 1},
+ {"is_deep_sleep", item_size(is_deep_sleep),
+ item_addr(is_deep_sleep), 1},
+ {"wakeup_dev_req", item_size(pm_wakeup_card_req),
+ item_addr(pm_wakeup_card_req), 1},
+ {"wakeup_tries", item_size(pm_wakeup_fw_try),
+ item_addr(pm_wakeup_fw_try), 1},
+ {"hs_configured", item_size(is_hs_configured),
+ item_addr(is_hs_configured), 1},
+ {"hs_activated", item_size(hs_activated),
+ item_addr(hs_activated), 1},
+ {"num_tx_timeout", item_size(num_tx_timeout),
+ item_addr(num_tx_timeout), 1},
+ {"num_cmd_timeout", item_size(num_cmd_timeout),
+ item_addr(num_cmd_timeout), 1},
+ {"timeout_cmd_id", item_size(timeout_cmd_id),
+ item_addr(timeout_cmd_id), 1},
+ {"timeout_cmd_act", item_size(timeout_cmd_act),
+ item_addr(timeout_cmd_act), 1},
+ {"last_cmd_id", item_size(last_cmd_id),
+ item_addr(last_cmd_id), DBG_CMD_NUM},
+ {"last_cmd_act", item_size(last_cmd_act),
+ item_addr(last_cmd_act), DBG_CMD_NUM},
+ {"last_cmd_index", item_size(last_cmd_index),
+ item_addr(last_cmd_index), 1},
+ {"last_cmd_resp_id", item_size(last_cmd_resp_id),
+ item_addr(last_cmd_resp_id), DBG_CMD_NUM},
+ {"last_cmd_resp_index", item_size(last_cmd_resp_index),
+ item_addr(last_cmd_resp_index), 1},
+ {"last_event", item_size(last_event),
+ item_addr(last_event), DBG_CMD_NUM},
+ {"last_event_index", item_size(last_event_index),
+ item_addr(last_event_index), 1},
+ {"num_cmd_h2c_fail", item_size(num_cmd_host_to_card_failure),
+ item_addr(num_cmd_host_to_card_failure), 1},
+ {"num_cmd_sleep_cfm_fail",
+ item_size(num_cmd_sleep_cfm_host_to_card_failure),
+ item_addr(num_cmd_sleep_cfm_host_to_card_failure), 1},
+ {"num_tx_h2c_fail", item_size(num_tx_host_to_card_failure),
+ item_addr(num_tx_host_to_card_failure), 1},
+ {"num_evt_deauth", item_size(num_event_deauth),
+ item_addr(num_event_deauth), 1},
+ {"num_evt_disassoc", item_size(num_event_disassoc),
+ item_addr(num_event_disassoc), 1},
+ {"num_evt_link_lost", item_size(num_event_link_lost),
+ item_addr(num_event_link_lost), 1},
+ {"num_cmd_deauth", item_size(num_cmd_deauth),
+ item_addr(num_cmd_deauth), 1},
+ {"num_cmd_assoc_ok", item_size(num_cmd_assoc_success),
+ item_addr(num_cmd_assoc_success), 1},
+ {"num_cmd_assoc_fail", item_size(num_cmd_assoc_failure),
+ item_addr(num_cmd_assoc_failure), 1},
+ {"cmd_sent", item_size(cmd_sent),
+ item_addr(cmd_sent), 1},
+ {"data_sent", item_size(data_sent),
+ item_addr(data_sent), 1},
+ {"cmd_resp_received", item_size(cmd_resp_received),
+ item_addr(cmd_resp_received), 1},
+ {"event_received", item_size(event_received),
+ item_addr(event_received), 1},
+
+ /* variables defined in struct mwifiex_adapter */
+ {"cmd_pending", adapter_item_size(cmd_pending),
+ adapter_item_addr(cmd_pending), 1},
+ {"tx_pending", adapter_item_size(tx_pending),
+ adapter_item_addr(tx_pending), 1},
+ {"rx_pending", adapter_item_size(rx_pending),
+ adapter_item_addr(rx_pending), 1},
+};
+
+static int num_of_items = ARRAY_SIZE(items);
+
+/*
+ * Generic proc file open handler.
+ *
+ * This function is called every time a file is accessed for read or write.
+ */
+static int
+mwifiex_open_generic(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+/*
+ * Proc info file read handler.
+ *
+ * This function is called when the 'info' file is opened for reading.
+ * It prints the following driver related information -
+ * - Driver name
+ * - Driver version
+ * - Driver extended version
+ * - Interface name
+ * - BSS mode
+ * - Media state (connected or disconnected)
+ * - MAC address
+ * - Total number of Tx bytes
+ * - Total number of Rx bytes
+ * - Total number of Tx packets
+ * - Total number of Rx packets
+ * - Total number of dropped Tx packets
+ * - Total number of dropped Rx packets
+ * - Total number of corrupted Tx packets
+ * - Total number of corrupted Rx packets
+ * - Carrier status (on or off)
+ * - Tx queue status (started or stopped)
+ *
+ * For STA mode drivers, it also prints the following extra -
+ * - ESSID
+ * - BSSID
+ * - Channel
+ * - Region code
+ * - Multicast count
+ * - Multicast addresses
+ */
+static ssize_t
+mwifiex_info_read(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct mwifiex_private *priv =
+ (struct mwifiex_private *) file->private_data;
+ struct net_device *netdev = priv->netdev;
+ struct netdev_hw_addr *ha;
+ unsigned long page = get_zeroed_page(GFP_KERNEL);
+ char *p = (char *) page, fmt[64];
+ struct mwifiex_bss_info info;
+ ssize_t ret;
+ int i = 0;
+
+ if (!p)
+ return -ENOMEM;
+
+ memset(&info, 0, sizeof(info));
+ ret = mwifiex_get_bss_info(priv, &info);
+ if (ret)
+ goto free_and_exit;
+
+ mwifiex_drv_get_driver_version(priv->adapter, fmt, sizeof(fmt) - 1);
+
+ if (!priv->version_str[0])
+ mwifiex_get_ver_ext(priv);
+
+ p += sprintf(p, "driver_name = " "\"mwifiex\"\n");
+ p += sprintf(p, "driver_version = %s", fmt);
+ p += sprintf(p, "\nverext = %s", priv->version_str);
+ p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name);
+ p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);
+ p += sprintf(p, "media_state=\"%s\"\n",
+ (!priv->media_connected ? "Disconnected" : "Connected"));
+ p += sprintf(p, "mac_address=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
+ netdev->dev_addr[0], netdev->dev_addr[1],
+ netdev->dev_addr[2], netdev->dev_addr[3],
+ netdev->dev_addr[4], netdev->dev_addr[5]);
+
+ if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
+ p += sprintf(p, "multicast_count=\"%d\"\n",
+ netdev_mc_count(netdev));
+ p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid);
+ p += sprintf(p, "bssid=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
+ info.bssid[0], info.bssid[1],
+ info.bssid[2], info.bssid[3],
+ info.bssid[4], info.bssid[5]);
+ p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan);
+ p += sprintf(p, "region_code = \"%02x\"\n", info.region_code);
+
+ netdev_for_each_mc_addr(ha, netdev)
+ p += sprintf(p, "multicast_address[%d]="
+ "\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", i++,
+ ha->addr[0], ha->addr[1],
+ ha->addr[2], ha->addr[3],
+ ha->addr[4], ha->addr[5]);
+ }
+
+ p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes);
+ p += sprintf(p, "num_rx_bytes = %lu\n", priv->stats.rx_bytes);
+ p += sprintf(p, "num_tx_pkts = %lu\n", priv->stats.tx_packets);
+ p += sprintf(p, "num_rx_pkts = %lu\n", priv->stats.rx_packets);
+ p += sprintf(p, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped);
+ p += sprintf(p, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped);
+ p += sprintf(p, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors);
+ p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors);
+ p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev))
+ ? "on" : "off"));
+ p += sprintf(p, "tx queue %s\n", ((netif_queue_stopped(priv->netdev))
+ ? "stopped" : "started"));
+
+ ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
+ (unsigned long) p - page);
+
+free_and_exit:
+ free_page(page);
+ return ret;
+}
+
+/*
+ * Proc getlog file read handler.
+ *
+ * This function is called when the 'getlog' file is opened for reading
+ * It prints the following log information -
+ * - Number of multicast Tx frames
+ * - Number of failed packets
+ * - Number of Tx retries
+ * - Number of multicast Tx retries
+ * - Number of duplicate frames
+ * - Number of RTS successes
+ * - Number of RTS failures
+ * - Number of ACK failures
+ * - Number of fragmented Rx frames
+ * - Number of multicast Rx frames
+ * - Number of FCS errors
+ * - Number of Tx frames
+ * - WEP ICV error counts
+ */
+static ssize_t
+mwifiex_getlog_read(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct mwifiex_private *priv =
+ (struct mwifiex_private *) file->private_data;
+ unsigned long page = get_zeroed_page(GFP_KERNEL);
+ char *p = (char *) page;
+ ssize_t ret;
+ struct mwifiex_ds_get_stats stats;
+
+ if (!p)
+ return -ENOMEM;
+
+ memset(&stats, 0, sizeof(stats));
+ ret = mwifiex_get_stats_info(priv, &stats);
+ if (ret)
+ goto free_and_exit;
+
+ p += sprintf(p, "\n"
+ "mcasttxframe %u\n"
+ "failed %u\n"
+ "retry %u\n"
+ "multiretry %u\n"
+ "framedup %u\n"
+ "rtssuccess %u\n"
+ "rtsfailure %u\n"
+ "ackfailure %u\n"
+ "rxfrag %u\n"
+ "mcastrxframe %u\n"
+ "fcserror %u\n"
+ "txframe %u\n"
+ "wepicverrcnt-1 %u\n"
+ "wepicverrcnt-2 %u\n"
+ "wepicverrcnt-3 %u\n"
+ "wepicverrcnt-4 %u\n",
+ stats.mcast_tx_frame,
+ stats.failed,
+ stats.retry,
+ stats.multi_retry,
+ stats.frame_dup,
+ stats.rts_success,
+ stats.rts_failure,
+ stats.ack_failure,
+ stats.rx_frag,
+ stats.mcast_rx_frame,
+ stats.fcs_error,
+ stats.tx_frame,
+ stats.wep_icv_error[0],
+ stats.wep_icv_error[1],
+ stats.wep_icv_error[2],
+ stats.wep_icv_error[3]);
+
+
+ ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
+ (unsigned long) p - page);
+
+free_and_exit:
+ free_page(page);
+ return ret;
+}
+
+static struct mwifiex_debug_info info;
+
+/*
+ * Proc debug file read handler.
+ *
+ * This function is called when the 'debug' file is opened for reading
+ * It prints the following log information -
+ * - Interrupt count
+ * - WMM AC VO packets count
+ * - WMM AC VI packets count
+ * - WMM AC BE packets count
+ * - WMM AC BK packets count
+ * - Maximum Tx buffer size
+ * - Tx buffer size
+ * - Current Tx buffer size
+ * - Power Save mode
+ * - Power Save state
+ * - Deep Sleep status
+ * - Device wakeup required status
+ * - Number of wakeup tries
+ * - Host Sleep configured status
+ * - Host Sleep activated status
+ * - Number of Tx timeouts
+ * - Number of command timeouts
+ * - Last timed out command ID
+ * - Last timed out command action
+ * - Last command ID
+ * - Last command action
+ * - Last command index
+ * - Last command response ID
+ * - Last command response index
+ * - Last event
+ * - Last event index
+ * - Number of host to card command failures
+ * - Number of sleep confirm command failures
+ * - Number of host to card data failure
+ * - Number of deauthentication events
+ * - Number of disassociation events
+ * - Number of link lost events
+ * - Number of deauthentication commands
+ * - Number of association success commands
+ * - Number of association failure commands
+ * - Number of commands sent
+ * - Number of data packets sent
+ * - Number of command responses received
+ * - Number of events received
+ * - Tx BA stream table (TID, RA)
+ * - Rx reorder table (TID, TA, Start window, Window size, Buffer)
+ */
+static ssize_t
+mwifiex_debug_read(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct mwifiex_private *priv =
+ (struct mwifiex_private *) file->private_data;
+ struct mwifiex_debug_data *d = &items[0];
+ unsigned long page = get_zeroed_page(GFP_KERNEL);
+ char *p = (char *) page;
+ ssize_t ret;
+ size_t size, addr;
+ long val;
+ int i, j;
+
+ if (!p)
+ return -ENOMEM;
+
+ ret = mwifiex_get_debug_info(priv, &info);
+ if (ret)
+ goto free_and_exit;
+
+ for (i = 0; i < num_of_items; i++) {
+ p += sprintf(p, "%s=", d[i].name);
+
+ size = d[i].size / d[i].num;
+
+ if (i < (num_of_items - 3))
+ addr = d[i].addr + (size_t) &info;
+ else /* The last 3 items are struct mwifiex_adapter variables */
+ addr = d[i].addr + (size_t) priv->adapter;
+
+ for (j = 0; j < d[i].num; j++) {
+ switch (size) {
+ case 1:
+ val = *((u8 *) addr);
+ break;
+ case 2:
+ val = *((u16 *) addr);
+ break;
+ case 4:
+ val = *((u32 *) addr);
+ break;
+ case 8:
+ val = *((long long *) addr);
+ break;
+ default:
+ val = -1;
+ break;
+ }
+
+ p += sprintf(p, "%#lx ", val);
+ addr += size;
+ }
+
+ p += sprintf(p, "\n");
+ }
+
+ if (info.tx_tbl_num) {
+ p += sprintf(p, "Tx BA stream table:\n");
+ for (i = 0; i < info.tx_tbl_num; i++)
+ p += sprintf(p, "tid = %d, "
+ "ra = %02x:%02x:%02x:%02x:%02x:%02x\n",
+ info.tx_tbl[i].tid, info.tx_tbl[i].ra[0],
+ info.tx_tbl[i].ra[1], info.tx_tbl[i].ra[2],
+ info.tx_tbl[i].ra[3], info.tx_tbl[i].ra[4],
+ info.tx_tbl[i].ra[5]);
+ }
+
+ if (info.rx_tbl_num) {
+ p += sprintf(p, "Rx reorder table:\n");
+ for (i = 0; i < info.rx_tbl_num; i++) {
+
+ p += sprintf(p, "tid = %d, "
+ "ta = %02x:%02x:%02x:%02x:%02x:%02x, "
+ "start_win = %d, "
+ "win_size = %d, buffer: ",
+ info.rx_tbl[i].tid,
+ info.rx_tbl[i].ta[0], info.rx_tbl[i].ta[1],
+ info.rx_tbl[i].ta[2], info.rx_tbl[i].ta[3],
+ info.rx_tbl[i].ta[4], info.rx_tbl[i].ta[5],
+ info.rx_tbl[i].start_win,
+ info.rx_tbl[i].win_size);
+
+ for (j = 0; j < info.rx_tbl[i].win_size; j++)
+ p += sprintf(p, "%c ",
+ info.rx_tbl[i].buffer[j] ?
+ '1' : '0');
+
+ p += sprintf(p, "\n");
+ }
+ }
+
+ ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
+ (unsigned long) p - page);
+
+free_and_exit:
+ free_page(page);
+ return ret;
+}
+
+static u32 saved_reg_type, saved_reg_offset, saved_reg_value;
+
+/*
+ * Proc regrdwr file write handler.
+ *
+ * This function is called when the 'regrdwr' file is opened for writing
+ *
+ * This function can be used to write to a register.
+ */
+static ssize_t
+mwifiex_regrdwr_write(struct file *file,
+ const char __user *ubuf, size_t count, loff_t *ppos)
+{
+ unsigned long addr = get_zeroed_page(GFP_KERNEL);
+ char *buf = (char *) addr;
+ size_t buf_size = min(count, (size_t) (PAGE_SIZE - 1));
+ int ret;
+ u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX;
+
+ if (!buf)
+ return -ENOMEM;
+
+
+ if (copy_from_user(buf, ubuf, buf_size)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ sscanf(buf, "%u %x %x", &reg_type, &reg_offset, &reg_value);
+
+ if (reg_type == 0 || reg_offset == 0) {
+ ret = -EINVAL;
+ goto done;
+ } else {
+ saved_reg_type = reg_type;
+ saved_reg_offset = reg_offset;
+ saved_reg_value = reg_value;
+ ret = count;
+ }
+done:
+ free_page(addr);
+ return ret;
+}
+
+/*
+ * Proc regrdwr file read handler.
+ *
+ * This function is called when the 'regrdwr' file is opened for reading
+ *
+ * This function can be used to read from a register.
+ */
+static ssize_t
+mwifiex_regrdwr_read(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct mwifiex_private *priv =
+ (struct mwifiex_private *) file->private_data;
+ unsigned long addr = get_zeroed_page(GFP_KERNEL);
+ char *buf = (char *) addr;
+ int pos = 0, ret = 0;
+ u32 reg_value;
+
+ if (!buf)
+ return -ENOMEM;
+
+ if (!saved_reg_type) {
+ /* No command has been given */
+ pos += snprintf(buf, PAGE_SIZE, "0");
+ goto done;
+ }
+ /* Set command has been given */
+ if (saved_reg_value != UINT_MAX) {
+ ret = mwifiex_reg_write(priv, saved_reg_type, saved_reg_offset,
+ saved_reg_value);
+
+ pos += snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n",
+ saved_reg_type, saved_reg_offset,
+ saved_reg_value);
+
+ ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
+
+ goto done;
+ }
+ /* Get command has been given */
+ ret = mwifiex_reg_read(priv, saved_reg_type,
+ saved_reg_offset, &reg_value);
+ if (ret) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ pos += snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", saved_reg_type,
+ saved_reg_offset, reg_value);
+
+ ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
+
+done:
+ free_page(addr);
+ return ret;
+}
+
+static u32 saved_offset = -1, saved_bytes = -1;
+
+/*
+ * Proc rdeeprom file write handler.
+ *
+ * This function is called when the 'rdeeprom' file is opened for writing
+ *
+ * This function can be used to write to a RDEEPROM location.
+ */
+static ssize_t
+mwifiex_rdeeprom_write(struct file *file,
+ const char __user *ubuf, size_t count, loff_t *ppos)
+{
+ unsigned long addr = get_zeroed_page(GFP_KERNEL);
+ char *buf = (char *) addr;
+ size_t buf_size = min(count, (size_t) (PAGE_SIZE - 1));
+ int ret = 0;
+ int offset = -1, bytes = -1;
+
+ if (!buf)
+ return -ENOMEM;
+
+
+ if (copy_from_user(buf, ubuf, buf_size)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ sscanf(buf, "%d %d", &offset, &bytes);
+
+ if (offset == -1 || bytes == -1) {
+ ret = -EINVAL;
+ goto done;
+ } else {
+ saved_offset = offset;
+ saved_bytes = bytes;
+ ret = count;
+ }
+done:
+ free_page(addr);
+ return ret;
+}
+
+/*
+ * Proc rdeeprom read write handler.
+ *
+ * This function is called when the 'rdeeprom' file is opened for reading
+ *
+ * This function can be used to read from a RDEEPROM location.
+ */
+static ssize_t
+mwifiex_rdeeprom_read(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct mwifiex_private *priv =
+ (struct mwifiex_private *) file->private_data;
+ unsigned long addr = get_zeroed_page(GFP_KERNEL);
+ char *buf = (char *) addr;
+ int pos = 0, ret = 0, i;
+ u8 value[MAX_EEPROM_DATA];
+
+ if (!buf)
+ return -ENOMEM;
+
+ if (saved_offset == -1) {
+ /* No command has been given */
+ pos += snprintf(buf, PAGE_SIZE, "0");
+ goto done;
+ }
+
+ /* Get command has been given */
+ ret = mwifiex_eeprom_read(priv, (u16) saved_offset,
+ (u16) saved_bytes, value);
+ if (ret) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ pos += snprintf(buf, PAGE_SIZE, "%d %d ", saved_offset, saved_bytes);
+
+ for (i = 0; i < saved_bytes; i++)
+ pos += snprintf(buf + strlen(buf), PAGE_SIZE, "%d ", value[i]);
+
+ ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
+
+done:
+ free_page(addr);
+ return ret;
+}
+
+
+#define MWIFIEX_DFS_ADD_FILE(name) do { \
+ if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir, \
+ priv, &mwifiex_dfs_##name##_fops)) \
+ return; \
+} while (0);
+
+#define MWIFIEX_DFS_FILE_OPS(name) \
+static const struct file_operations mwifiex_dfs_##name##_fops = { \
+ .read = mwifiex_##name##_read, \
+ .write = mwifiex_##name##_write, \
+ .open = mwifiex_open_generic, \
+};
+
+#define MWIFIEX_DFS_FILE_READ_OPS(name) \
+static const struct file_operations mwifiex_dfs_##name##_fops = { \
+ .read = mwifiex_##name##_read, \
+ .open = mwifiex_open_generic, \
+};
+
+#define MWIFIEX_DFS_FILE_WRITE_OPS(name) \
+static const struct file_operations mwifiex_dfs_##name##_fops = { \
+ .write = mwifiex_##name##_write, \
+ .open = mwifiex_open_generic, \
+};
+
+
+MWIFIEX_DFS_FILE_READ_OPS(info);
+MWIFIEX_DFS_FILE_READ_OPS(debug);
+MWIFIEX_DFS_FILE_READ_OPS(getlog);
+MWIFIEX_DFS_FILE_OPS(regrdwr);
+MWIFIEX_DFS_FILE_OPS(rdeeprom);
+
+/*
+ * This function creates the debug FS directory structure and the files.
+ */
+void
+mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
+{
+ if (!mwifiex_dfs_dir || !priv)
+ return;
+
+ priv->dfs_dev_dir = debugfs_create_dir(priv->netdev->name,
+ mwifiex_dfs_dir);
+
+ if (!priv->dfs_dev_dir)
+ return;
+
+ MWIFIEX_DFS_ADD_FILE(info);
+ MWIFIEX_DFS_ADD_FILE(debug);
+ MWIFIEX_DFS_ADD_FILE(getlog);
+ MWIFIEX_DFS_ADD_FILE(regrdwr);
+ MWIFIEX_DFS_ADD_FILE(rdeeprom);
+}
+
+/*
+ * This function removes the debug FS directory structure and the files.
+ */
+void
+mwifiex_dev_debugfs_remove(struct mwifiex_private *priv)
+{
+ if (!priv)
+ return;
+
+ debugfs_remove_recursive(priv->dfs_dev_dir);
+}
+
+/*
+ * This function creates the top level proc directory.
+ */
+void
+mwifiex_debugfs_init(void)
+{
+ if (!mwifiex_dfs_dir)
+ mwifiex_dfs_dir = debugfs_create_dir("mwifiex", NULL);
+}
+
+/*
+ * This function removes the top level proc directory.
+ */
+void
+mwifiex_debugfs_remove(void)
+{
+ if (mwifiex_dfs_dir)
+ debugfs_remove(mwifiex_dfs_dir);
+}
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
new file mode 100644
index 00000000000..0e90b0986ed
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -0,0 +1,129 @@
+/*
+ * Marvell Wireless LAN device driver: generic data structures and APIs
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_DECL_H_
+#define _MWIFIEX_DECL_H_
+
+#undef pr_fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/wait.h>
+#include <linux/timer.h>
+#include <linux/ieee80211.h>
+
+
+#define MWIFIEX_MAX_BSS_NUM (1)
+
+#define MWIFIEX_MIN_DATA_HEADER_LEN 32 /* (sizeof(mwifiex_txpd)) */
+
+#define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2
+#define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16
+
+#define MWIFIEX_AMPDU_DEF_TXWINSIZE 32
+#define MWIFIEX_AMPDU_DEF_RXWINSIZE 16
+#define MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT 0xffff
+
+#define MWIFIEX_RATE_INDEX_HRDSSS0 0
+#define MWIFIEX_RATE_INDEX_HRDSSS3 3
+#define MWIFIEX_RATE_INDEX_OFDM0 4
+#define MWIFIEX_RATE_INDEX_OFDM7 11
+#define MWIFIEX_RATE_INDEX_MCS0 12
+
+#define MWIFIEX_RATE_BITMAP_OFDM0 16
+#define MWIFIEX_RATE_BITMAP_OFDM7 23
+#define MWIFIEX_RATE_BITMAP_MCS0 32
+#define MWIFIEX_RATE_BITMAP_MCS127 159
+
+#define MWIFIEX_RX_DATA_BUF_SIZE (4 * 1024)
+
+#define MWIFIEX_RTS_MIN_VALUE (0)
+#define MWIFIEX_RTS_MAX_VALUE (2347)
+#define MWIFIEX_FRAG_MIN_VALUE (256)
+#define MWIFIEX_FRAG_MAX_VALUE (2346)
+
+#define MWIFIEX_SDIO_BLOCK_SIZE 256
+
+#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0)
+
+enum mwifiex_bss_type {
+ MWIFIEX_BSS_TYPE_STA = 0,
+ MWIFIEX_BSS_TYPE_UAP = 1,
+ MWIFIEX_BSS_TYPE_ANY = 0xff,
+};
+
+enum mwifiex_bss_role {
+ MWIFIEX_BSS_ROLE_STA = 0,
+ MWIFIEX_BSS_ROLE_UAP = 1,
+ MWIFIEX_BSS_ROLE_ANY = 0xff,
+};
+
+#define BSS_ROLE_BIT_MASK BIT(0)
+
+#define GET_BSS_ROLE(priv) ((priv)->bss_role & BSS_ROLE_BIT_MASK)
+
+enum mwifiex_data_frame_type {
+ MWIFIEX_DATA_FRAME_TYPE_ETH_II = 0,
+ MWIFIEX_DATA_FRAME_TYPE_802_11,
+};
+
+struct mwifiex_fw_image {
+ u8 *helper_buf;
+ u32 helper_len;
+ u8 *fw_buf;
+ u32 fw_len;
+};
+
+struct mwifiex_802_11_ssid {
+ u32 ssid_len;
+ u8 ssid[IEEE80211_MAX_SSID_LEN];
+};
+
+struct mwifiex_wait_queue {
+ wait_queue_head_t wait;
+ u16 condition;
+ int status;
+};
+
+struct mwifiex_rxinfo {
+ u8 bss_index;
+ struct sk_buff *parent;
+ u8 use_count;
+};
+
+struct mwifiex_txinfo {
+ u32 status_code;
+ u8 flags;
+ u8 bss_index;
+};
+
+struct mwifiex_bss_attr {
+ u8 bss_type;
+ u8 frame_type;
+ u8 active;
+ u8 bss_priority;
+ u8 bss_num;
+};
+
+enum mwifiex_wmm_ac_e {
+ WMM_AC_BK,
+ WMM_AC_BE,
+ WMM_AC_VI,
+ WMM_AC_VO
+} __packed;
+#endif /* !_MWIFIEX_DECL_H_ */
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
new file mode 100644
index 00000000000..afdd145dff0
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -0,0 +1,1187 @@
+/*
+ * Marvell Wireless LAN device driver: Firmware specific macros & structures
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_FW_H_
+#define _MWIFIEX_FW_H_
+
+#include <linux/if_ether.h>
+
+
+#define INTF_HEADER_LEN 4
+
+struct rfc_1042_hdr {
+ u8 llc_dsap;
+ u8 llc_ssap;
+ u8 llc_ctrl;
+ u8 snap_oui[3];
+ u16 snap_type;
+};
+
+struct rx_packet_hdr {
+ struct ethhdr eth803_hdr;
+ struct rfc_1042_hdr rfc1042_hdr;
+};
+
+struct tx_packet_hdr {
+ struct ethhdr eth803_hdr;
+ struct rfc_1042_hdr rfc1042_hdr;
+};
+
+#define B_SUPPORTED_RATES 5
+#define G_SUPPORTED_RATES 9
+#define BG_SUPPORTED_RATES 13
+#define A_SUPPORTED_RATES 9
+#define HOSTCMD_SUPPORTED_RATES 14
+#define N_SUPPORTED_RATES 3
+#define ALL_802_11_BANDS (BAND_A | BAND_B | BAND_G | BAND_GN)
+
+#define FW_MULTI_BANDS_SUPPORT (BIT(8) | BIT(9) | BIT(10) | BIT(11))
+#define IS_SUPPORT_MULTI_BANDS(adapter) \
+ (adapter->fw_cap_info & FW_MULTI_BANDS_SUPPORT)
+#define GET_FW_DEFAULT_BANDS(adapter) \
+ ((adapter->fw_cap_info >> 8) & ALL_802_11_BANDS)
+
+extern u8 supported_rates_b[B_SUPPORTED_RATES];
+extern u8 supported_rates_g[G_SUPPORTED_RATES];
+extern u8 supported_rates_bg[BG_SUPPORTED_RATES];
+extern u8 supported_rates_a[A_SUPPORTED_RATES];
+extern u8 supported_rates_n[N_SUPPORTED_RATES];
+
+#define HostCmd_WEP_KEY_INDEX_MASK 0x3fff
+
+#define KEY_INFO_ENABLED 0x01
+enum KEY_TYPE_ID {
+ KEY_TYPE_ID_WEP = 0,
+ KEY_TYPE_ID_TKIP,
+ KEY_TYPE_ID_AES,
+ KEY_TYPE_ID_WAPI,
+};
+#define KEY_MCAST BIT(0)
+#define KEY_UNICAST BIT(1)
+#define KEY_ENABLED BIT(2)
+
+#define WAPI_KEY_LEN 50
+
+#define MAX_POLL_TRIES 100
+
+#define MAX_MULTI_INTERFACE_POLL_TRIES 1000
+
+#define MAX_FIRMWARE_POLL_TRIES 100
+
+#define FIRMWARE_READY 0xfedc
+
+enum MWIFIEX_802_11_PRIVACY_FILTER {
+ MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL,
+ MWIFIEX_802_11_PRIV_FILTER_8021X_WEP
+};
+
+enum MWIFIEX_802_11_WEP_STATUS {
+ MWIFIEX_802_11_WEP_ENABLED,
+ MWIFIEX_802_11_WEP_DISABLED,
+};
+
+#define CAL_SNR(RSSI, NF) ((s16)((s16)(RSSI)-(s16)(NF)))
+
+#define PROPRIETARY_TLV_BASE_ID 0x0100
+#define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0)
+#define TLV_TYPE_CHANLIST (PROPRIETARY_TLV_BASE_ID + 1)
+#define TLV_TYPE_NUMPROBES (PROPRIETARY_TLV_BASE_ID + 2)
+#define TLV_TYPE_PASSTHROUGH (PROPRIETARY_TLV_BASE_ID + 10)
+#define TLV_TYPE_WMMQSTATUS (PROPRIETARY_TLV_BASE_ID + 16)
+#define TLV_TYPE_WILDCARDSSID (PROPRIETARY_TLV_BASE_ID + 18)
+#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19)
+#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31)
+#define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42)
+#define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82)
+#define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83)
+#define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84)
+#define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94)
+#define TLV_TYPE_AUTO_DS_PARAM (PROPRIETARY_TLV_BASE_ID + 113)
+#define TLV_TYPE_PS_PARAM (PROPRIETARY_TLV_BASE_ID + 114)
+
+#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048
+
+#define SSN_MASK 0xfff0
+
+#define BA_RESULT_SUCCESS 0x0
+#define BA_RESULT_TIMEOUT 0x2
+
+#define IS_BASTREAM_SETUP(ptr) (ptr->ba_status)
+
+#define BA_STREAM_NOT_ALLOWED 0xff
+
+#define IS_11N_ENABLED(priv) ((priv->adapter->config_bands & BAND_GN || \
+ priv->adapter->config_bands & BAND_AN) \
+ && priv->curr_bss_params.bss_descriptor.bcn_ht_cap)
+#define INITIATOR_BIT(DelBAParamSet) (((DelBAParamSet) &\
+ BIT(DELBA_INITIATOR_POS)) >> DELBA_INITIATOR_POS)
+
+#define MWIFIEX_TX_DATA_BUF_SIZE_4K 4096
+#define MWIFIEX_TX_DATA_BUF_SIZE_8K 8192
+
+#define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11))
+
+/* dev_cap bitmap
+ * BIT
+ * 0-16 reserved
+ * 17 IEEE80211_HT_CAP_SUP_WIDTH_20_40
+ * 18-22 reserved
+ * 23 IEEE80211_HT_CAP_SGI_20
+ * 24 IEEE80211_HT_CAP_SGI_40
+ * 25 IEEE80211_HT_CAP_TX_STBC
+ * 26 IEEE80211_HT_CAP_RX_STBC
+ * 27-28 reserved
+ * 29 IEEE80211_HT_CAP_GRN_FLD
+ * 30-31 reserved
+ */
+#define ISSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap & BIT(17))
+#define ISSUPP_SHORTGI20(Dot11nDevCap) (Dot11nDevCap & BIT(23))
+#define ISSUPP_SHORTGI40(Dot11nDevCap) (Dot11nDevCap & BIT(24))
+#define ISSUPP_TXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(25))
+#define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(26))
+#define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29))
+
+#define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f)
+#define SETHT_MCS32(x) (x[4] |= 1)
+
+#define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4))
+
+#define LLC_SNAP_LEN 8
+
+#define MOD_CLASS_HR_DSSS 0x03
+#define MOD_CLASS_OFDM 0x07
+#define MOD_CLASS_HT 0x08
+#define HT_BW_20 0
+#define HT_BW_40 1
+
+#define HostCmd_CMD_GET_HW_SPEC 0x0003
+#define HostCmd_CMD_802_11_SCAN 0x0006
+#define HostCmd_CMD_802_11_GET_LOG 0x000b
+#define HostCmd_CMD_MAC_MULTICAST_ADR 0x0010
+#define HostCmd_CMD_802_11_EEPROM_ACCESS 0x0059
+#define HostCmd_CMD_802_11_ASSOCIATE 0x0012
+#define HostCmd_CMD_802_11_SNMP_MIB 0x0016
+#define HostCmd_CMD_MAC_REG_ACCESS 0x0019
+#define HostCmd_CMD_BBP_REG_ACCESS 0x001a
+#define HostCmd_CMD_RF_REG_ACCESS 0x001b
+#define HostCmd_CMD_PMIC_REG_ACCESS 0x00ad
+#define HostCmd_CMD_802_11_RF_CHANNEL 0x001d
+#define HostCmd_CMD_802_11_DEAUTHENTICATE 0x0024
+#define HostCmd_CMD_MAC_CONTROL 0x0028
+#define HostCmd_CMD_802_11_AD_HOC_START 0x002b
+#define HostCmd_CMD_802_11_AD_HOC_JOIN 0x002c
+#define HostCmd_CMD_802_11_AD_HOC_STOP 0x0040
+#define HostCmd_CMD_802_11_MAC_ADDRESS 0x004D
+#define HostCmd_CMD_802_11D_DOMAIN_INFO 0x005b
+#define HostCmd_CMD_802_11_KEY_MATERIAL 0x005e
+#define HostCmd_CMD_802_11_BG_SCAN_QUERY 0x006c
+#define HostCmd_CMD_WMM_GET_STATUS 0x0071
+#define HostCmd_CMD_802_11_TX_RATE_QUERY 0x007f
+#define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS 0x0083
+#define HostCmd_CMD_VERSION_EXT 0x0097
+#define HostCmd_CMD_RSSI_INFO 0x00a4
+#define HostCmd_CMD_FUNC_INIT 0x00a9
+#define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa
+#define HostCmd_CMD_11N_CFG 0x00cd
+#define HostCmd_CMD_11N_ADDBA_REQ 0x00ce
+#define HostCmd_CMD_11N_ADDBA_RSP 0x00cf
+#define HostCmd_CMD_11N_DELBA 0x00d0
+#define HostCmd_CMD_RECONFIGURE_TX_BUFF 0x00d9
+#define HostCmd_CMD_AMSDU_AGGR_CTRL 0x00df
+#define HostCmd_CMD_TXPWR_CFG 0x00d1
+#define HostCmd_CMD_TX_RATE_CFG 0x00d6
+#define HostCmd_CMD_802_11_PS_MODE_ENH 0x00e4
+#define HostCmd_CMD_802_11_HS_CFG_ENH 0x00e5
+#define HostCmd_CMD_CAU_REG_ACCESS 0x00ed
+#define HostCmd_CMD_SET_BSS_MODE 0x00f7
+
+
+enum ENH_PS_MODES {
+ EN_PS = 1,
+ DIS_PS = 2,
+ EN_AUTO_DS = 3,
+ DIS_AUTO_DS = 4,
+ SLEEP_CONFIRM = 5,
+ GET_PS = 0,
+ EN_AUTO_PS = 0xff,
+ DIS_AUTO_PS = 0xfe,
+};
+
+#define HostCmd_RET_BIT 0x8000
+#define HostCmd_ACT_GEN_GET 0x0000
+#define HostCmd_ACT_GEN_SET 0x0001
+#define HostCmd_RESULT_OK 0x0000
+
+#define HostCmd_ACT_MAC_RX_ON 0x0001
+#define HostCmd_ACT_MAC_TX_ON 0x0002
+#define HostCmd_ACT_MAC_WEP_ENABLE 0x0008
+#define HostCmd_ACT_MAC_ETHERNETII_ENABLE 0x0010
+#define HostCmd_ACT_MAC_PROMISCUOUS_ENABLE 0x0080
+#define HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE 0x0100
+#define HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON 0x2000
+
+#define HostCmd_BSS_MODE_IBSS 0x0002
+#define HostCmd_BSS_MODE_ANY 0x0003
+
+#define HostCmd_SCAN_RADIO_TYPE_BG 0
+#define HostCmd_SCAN_RADIO_TYPE_A 1
+
+#define HOST_SLEEP_CFG_CANCEL 0xffffffff
+#define HOST_SLEEP_CFG_COND_DEF 0x0000000f
+#define HOST_SLEEP_CFG_GPIO_DEF 0xff
+#define HOST_SLEEP_CFG_GAP_DEF 0
+
+#define CMD_F_HOSTCMD (1 << 0)
+#define CMD_F_CANCELED (1 << 1)
+
+#define HostCmd_CMD_ID_MASK 0x0fff
+
+#define HostCmd_SEQ_NUM_MASK 0x00ff
+
+#define HostCmd_BSS_NUM_MASK 0x0f00
+
+#define HostCmd_BSS_TYPE_MASK 0xf000
+
+#define HostCmd_SET_SEQ_NO_BSS_INFO(seq, num, type) { \
+ (((seq) & 0x00ff) | \
+ (((num) & 0x000f) << 8)) | \
+ (((type) & 0x000f) << 12); }
+
+#define HostCmd_GET_SEQ_NO(seq) \
+ ((seq) & HostCmd_SEQ_NUM_MASK)
+
+#define HostCmd_GET_BSS_NO(seq) \
+ (((seq) & HostCmd_BSS_NUM_MASK) >> 8)
+
+#define HostCmd_GET_BSS_TYPE(seq) \
+ (((seq) & HostCmd_BSS_TYPE_MASK) >> 12)
+
+#define EVENT_DUMMY_HOST_WAKEUP_SIGNAL 0x00000001
+#define EVENT_LINK_LOST 0x00000003
+#define EVENT_LINK_SENSED 0x00000004
+#define EVENT_MIB_CHANGED 0x00000006
+#define EVENT_INIT_DONE 0x00000007
+#define EVENT_DEAUTHENTICATED 0x00000008
+#define EVENT_DISASSOCIATED 0x00000009
+#define EVENT_PS_AWAKE 0x0000000a
+#define EVENT_PS_SLEEP 0x0000000b
+#define EVENT_MIC_ERR_MULTICAST 0x0000000d
+#define EVENT_MIC_ERR_UNICAST 0x0000000e
+#define EVENT_DEEP_SLEEP_AWAKE 0x00000010
+#define EVENT_ADHOC_BCN_LOST 0x00000011
+
+#define EVENT_WMM_STATUS_CHANGE 0x00000017
+#define EVENT_BG_SCAN_REPORT 0x00000018
+#define EVENT_RSSI_LOW 0x00000019
+#define EVENT_SNR_LOW 0x0000001a
+#define EVENT_MAX_FAIL 0x0000001b
+#define EVENT_RSSI_HIGH 0x0000001c
+#define EVENT_SNR_HIGH 0x0000001d
+#define EVENT_IBSS_COALESCED 0x0000001e
+#define EVENT_DATA_RSSI_LOW 0x00000024
+#define EVENT_DATA_SNR_LOW 0x00000025
+#define EVENT_DATA_RSSI_HIGH 0x00000026
+#define EVENT_DATA_SNR_HIGH 0x00000027
+#define EVENT_LINK_QUALITY 0x00000028
+#define EVENT_PORT_RELEASE 0x0000002b
+#define EVENT_PRE_BEACON_LOST 0x00000031
+#define EVENT_ADDBA 0x00000033
+#define EVENT_DELBA 0x00000034
+#define EVENT_BA_STREAM_TIEMOUT 0x00000037
+#define EVENT_AMSDU_AGGR_CTRL 0x00000042
+#define EVENT_WEP_ICV_ERR 0x00000046
+#define EVENT_HS_ACT_REQ 0x00000047
+#define EVENT_BW_CHANGE 0x00000048
+
+#define EVENT_HOSTWAKE_STAIE 0x0000004d
+
+#define EVENT_ID_MASK 0xffff
+#define BSS_NUM_MASK 0xf
+
+#define EVENT_GET_BSS_NUM(event_cause) \
+ (((event_cause) >> 16) & BSS_NUM_MASK)
+
+#define EVENT_GET_BSS_TYPE(event_cause) \
+ (((event_cause) >> 24) & 0x00ff)
+
+struct mwifiex_ie_types_header {
+ __le16 type;
+ __le16 len;
+} __packed;
+
+struct mwifiex_ie_types_data {
+ struct mwifiex_ie_types_header header;
+ u8 data[1];
+} __packed;
+
+#define MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET 0x01
+#define MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET 0x08
+
+struct txpd {
+ u8 bss_type;
+ u8 bss_num;
+ __le16 tx_pkt_length;
+ __le16 tx_pkt_offset;
+ __le16 tx_pkt_type;
+ __le32 tx_control;
+ u8 priority;
+ u8 flags;
+ u8 pkt_delay_2ms;
+ u8 reserved1;
+} __packed;
+
+struct rxpd {
+ u8 bss_type;
+ u8 bss_num;
+ u16 rx_pkt_length;
+ u16 rx_pkt_offset;
+ u16 rx_pkt_type;
+ u16 seq_num;
+ u8 priority;
+ u8 rx_rate;
+ s8 snr;
+ s8 nf;
+ /* Ht Info [Bit 0] RxRate format: LG=0, HT=1
+ * [Bit 1] HT Bandwidth: BW20 = 0, BW40 = 1
+ * [Bit 2] HT Guard Interval: LGI = 0, SGI = 1 */
+ u8 ht_info;
+ u8 reserved;
+} __packed;
+
+enum mwifiex_chan_scan_mode_bitmasks {
+ MWIFIEX_PASSIVE_SCAN = BIT(0),
+ MWIFIEX_DISABLE_CHAN_FILT = BIT(1),
+};
+
+#define SECOND_CHANNEL_BELOW 0x30
+#define SECOND_CHANNEL_ABOVE 0x10
+struct mwifiex_chan_scan_param_set {
+ u8 radio_type;
+ u8 chan_number;
+ u8 chan_scan_mode_bitmap;
+ __le16 min_scan_time;
+ __le16 max_scan_time;
+} __packed;
+
+struct mwifiex_ie_types_chan_list_param_set {
+ struct mwifiex_ie_types_header header;
+ struct mwifiex_chan_scan_param_set chan_scan_param[1];
+} __packed;
+
+struct chan_band_param_set {
+ u8 radio_type;
+ u8 chan_number;
+};
+
+struct mwifiex_ie_types_chan_band_list_param_set {
+ struct mwifiex_ie_types_header header;
+ struct chan_band_param_set chan_band_param[1];
+} __packed;
+
+struct mwifiex_ie_types_rates_param_set {
+ struct mwifiex_ie_types_header header;
+ u8 rates[1];
+} __packed;
+
+struct mwifiex_ie_types_ssid_param_set {
+ struct mwifiex_ie_types_header header;
+ u8 ssid[1];
+} __packed;
+
+struct mwifiex_ie_types_num_probes {
+ struct mwifiex_ie_types_header header;
+ __le16 num_probes;
+} __packed;
+
+struct mwifiex_ie_types_wildcard_ssid_params {
+ struct mwifiex_ie_types_header header;
+ u8 max_ssid_length;
+ u8 ssid[1];
+} __packed;
+
+#define TSF_DATA_SIZE 8
+struct mwifiex_ie_types_tsf_timestamp {
+ struct mwifiex_ie_types_header header;
+ u8 tsf_data[1];
+} __packed;
+
+struct mwifiex_cf_param_set {
+ u8 cfp_cnt;
+ u8 cfp_period;
+ u16 cfp_max_duration;
+ u16 cfp_duration_remaining;
+} __packed;
+
+struct mwifiex_ibss_param_set {
+ u16 atim_window;
+} __packed;
+
+struct mwifiex_ie_types_ss_param_set {
+ struct mwifiex_ie_types_header header;
+ union {
+ struct mwifiex_cf_param_set cf_param_set[1];
+ struct mwifiex_ibss_param_set ibss_param_set[1];
+ } cf_ibss;
+} __packed;
+
+struct mwifiex_fh_param_set {
+ u16 dwell_time;
+ u8 hop_set;
+ u8 hop_pattern;
+ u8 hop_index;
+} __packed;
+
+struct mwifiex_ds_param_set {
+ u8 current_chan;
+} __packed;
+
+struct mwifiex_ie_types_phy_param_set {
+ struct mwifiex_ie_types_header header;
+ union {
+ struct mwifiex_fh_param_set fh_param_set[1];
+ struct mwifiex_ds_param_set ds_param_set[1];
+ } fh_ds;
+} __packed;
+
+struct mwifiex_ie_types_auth_type {
+ struct mwifiex_ie_types_header header;
+ __le16 auth_type;
+} __packed;
+
+struct mwifiex_ie_types_vendor_param_set {
+ struct mwifiex_ie_types_header header;
+ u8 ie[MWIFIEX_MAX_VSIE_LEN];
+};
+
+struct mwifiex_ie_types_rsn_param_set {
+ struct mwifiex_ie_types_header header;
+ u8 rsn_ie[1];
+} __packed;
+
+#define KEYPARAMSET_FIXED_LEN 6
+
+struct mwifiex_ie_type_key_param_set {
+ __le16 type;
+ __le16 length;
+ __le16 key_type_id;
+ __le16 key_info;
+ __le16 key_len;
+ u8 key[50];
+} __packed;
+
+struct host_cmd_ds_802_11_key_material {
+ __le16 action;
+ struct mwifiex_ie_type_key_param_set key_param_set;
+} __packed;
+
+struct host_cmd_ds_gen {
+ u16 command;
+ u16 size;
+ u16 seq_num;
+ u16 result;
+};
+
+#define S_DS_GEN sizeof(struct host_cmd_ds_gen)
+
+enum sleep_resp_ctrl {
+ RESP_NOT_NEEDED = 0,
+ RESP_NEEDED,
+};
+
+struct mwifiex_ps_param {
+ __le16 null_pkt_interval;
+ __le16 multiple_dtims;
+ __le16 bcn_miss_timeout;
+ __le16 local_listen_interval;
+ __le16 adhoc_wake_period;
+ __le16 mode;
+ __le16 delay_to_ps;
+};
+
+#define BITMAP_AUTO_DS 0x01
+#define BITMAP_STA_PS 0x10
+
+struct mwifiex_ie_types_auto_ds_param {
+ struct mwifiex_ie_types_header header;
+ __le16 deep_sleep_timeout;
+} __packed;
+
+struct mwifiex_ie_types_ps_param {
+ struct mwifiex_ie_types_header header;
+ struct mwifiex_ps_param param;
+} __packed;
+
+struct host_cmd_ds_802_11_ps_mode_enh {
+ __le16 action;
+
+ union {
+ struct mwifiex_ps_param opt_ps;
+ __le16 ps_bitmap;
+ } params;
+} __packed;
+
+struct host_cmd_ds_get_hw_spec {
+ __le16 hw_if_version;
+ __le16 version;
+ __le16 reserved;
+ __le16 num_of_mcast_adr;
+ u8 permanent_addr[ETH_ALEN];
+ __le16 region_code;
+ __le16 number_of_antenna;
+ __le32 fw_release_number;
+ __le32 reserved_1;
+ __le32 reserved_2;
+ __le32 reserved_3;
+ __le32 fw_cap_info;
+ __le32 dot_11n_dev_cap;
+ u8 dev_mcs_support;
+ __le16 mp_end_port; /* SDIO only, reserved for other interfacces */
+ __le16 reserved_4;
+} __packed;
+
+struct host_cmd_ds_802_11_rssi_info {
+ __le16 action;
+ __le16 ndata;
+ __le16 nbcn;
+ __le16 reserved[9];
+ long long reserved_1;
+};
+
+struct host_cmd_ds_802_11_rssi_info_rsp {
+ __le16 action;
+ __le16 ndata;
+ __le16 nbcn;
+ __le16 data_rssi_last;
+ __le16 data_nf_last;
+ __le16 data_rssi_avg;
+ __le16 data_nf_avg;
+ __le16 bcn_rssi_last;
+ __le16 bcn_nf_last;
+ __le16 bcn_rssi_avg;
+ __le16 bcn_nf_avg;
+ long long tsf_bcn;
+};
+
+struct host_cmd_ds_802_11_mac_address {
+ __le16 action;
+ u8 mac_addr[ETH_ALEN];
+};
+
+struct host_cmd_ds_mac_control {
+ __le16 action;
+ __le16 reserved;
+};
+
+struct host_cmd_ds_mac_multicast_adr {
+ __le16 action;
+ __le16 num_of_adrs;
+ u8 mac_list[MWIFIEX_MAX_MULTICAST_LIST_SIZE][ETH_ALEN];
+} __packed;
+
+struct host_cmd_ds_802_11_deauthenticate {
+ u8 mac_addr[ETH_ALEN];
+ __le16 reason_code;
+} __packed;
+
+struct host_cmd_ds_802_11_associate {
+ u8 peer_sta_addr[ETH_ALEN];
+ __le16 cap_info_bitmap;
+ __le16 listen_interval;
+ __le16 beacon_period;
+ u8 dtim_period;
+} __packed;
+
+struct ieee_types_assoc_rsp {
+ __le16 cap_info_bitmap;
+ __le16 status_code;
+ __le16 a_id;
+ u8 ie_buffer[1];
+} __packed;
+
+struct host_cmd_ds_802_11_associate_rsp {
+ struct ieee_types_assoc_rsp assoc_rsp;
+} __packed;
+
+struct ieee_types_cf_param_set {
+ u8 element_id;
+ u8 len;
+ u8 cfp_cnt;
+ u8 cfp_period;
+ u16 cfp_max_duration;
+ u16 cfp_duration_remaining;
+} __packed;
+
+struct ieee_types_ibss_param_set {
+ u8 element_id;
+ u8 len;
+ __le16 atim_window;
+} __packed;
+
+union ieee_types_ss_param_set {
+ struct ieee_types_cf_param_set cf_param_set;
+ struct ieee_types_ibss_param_set ibss_param_set;
+} __packed;
+
+struct ieee_types_fh_param_set {
+ u8 element_id;
+ u8 len;
+ __le16 dwell_time;
+ u8 hop_set;
+ u8 hop_pattern;
+ u8 hop_index;
+} __packed;
+
+struct ieee_types_ds_param_set {
+ u8 element_id;
+ u8 len;
+ u8 current_chan;
+} __packed;
+
+union ieee_types_phy_param_set {
+ struct ieee_types_fh_param_set fh_param_set;
+ struct ieee_types_ds_param_set ds_param_set;
+} __packed;
+
+struct host_cmd_ds_802_11_ad_hoc_start {
+ u8 ssid[IEEE80211_MAX_SSID_LEN];
+ u8 bss_mode;
+ __le16 beacon_period;
+ u8 dtim_period;
+ union ieee_types_ss_param_set ss_param_set;
+ union ieee_types_phy_param_set phy_param_set;
+ u16 reserved1;
+ __le16 cap_info_bitmap;
+ u8 DataRate[HOSTCMD_SUPPORTED_RATES];
+} __packed;
+
+struct host_cmd_ds_802_11_ad_hoc_result {
+ u8 pad[3];
+ u8 bssid[ETH_ALEN];
+} __packed;
+
+struct adhoc_bss_desc {
+ u8 bssid[ETH_ALEN];
+ u8 ssid[IEEE80211_MAX_SSID_LEN];
+ u8 bss_mode;
+ __le16 beacon_period;
+ u8 dtim_period;
+ u8 time_stamp[8];
+ u8 local_time[8];
+ union ieee_types_phy_param_set phy_param_set;
+ union ieee_types_ss_param_set ss_param_set;
+ __le16 cap_info_bitmap;
+ u8 data_rates[HOSTCMD_SUPPORTED_RATES];
+
+ /*
+ * DO NOT ADD ANY FIELDS TO THIS STRUCTURE.
+ * It is used in the Adhoc join command and will cause a
+ * binary layout mismatch with the firmware
+ */
+} __packed;
+
+struct host_cmd_ds_802_11_ad_hoc_join {
+ struct adhoc_bss_desc bss_descriptor;
+ u16 reserved1;
+ u16 reserved2;
+} __packed;
+
+struct host_cmd_ds_802_11_get_log {
+ __le32 mcast_tx_frame;
+ __le32 failed;
+ __le32 retry;
+ __le32 multi_retry;
+ __le32 frame_dup;
+ __le32 rts_success;
+ __le32 rts_failure;
+ __le32 ack_failure;
+ __le32 rx_frag;
+ __le32 mcast_rx_frame;
+ __le32 fcs_error;
+ __le32 tx_frame;
+ __le32 reserved;
+ __le32 wep_icv_err_cnt[4];
+};
+
+struct host_cmd_ds_tx_rate_query {
+ u8 tx_rate;
+ /* Ht Info [Bit 0] RxRate format: LG=0, HT=1
+ * [Bit 1] HT Bandwidth: BW20 = 0, BW40 = 1
+ * [Bit 2] HT Guard Interval: LGI = 0, SGI = 1 */
+ u8 ht_info;
+} __packed;
+
+enum Host_Sleep_Action {
+ HS_CONFIGURE = 0x0001,
+ HS_ACTIVATE = 0x0002,
+};
+
+struct mwifiex_hs_config_param {
+ __le32 conditions;
+ u8 gpio;
+ u8 gap;
+} __packed;
+
+struct hs_activate_param {
+ u16 resp_ctrl;
+} __packed;
+
+struct host_cmd_ds_802_11_hs_cfg_enh {
+ __le16 action;
+
+ union {
+ struct mwifiex_hs_config_param hs_config;
+ struct hs_activate_param hs_activate;
+ } params;
+} __packed;
+
+enum SNMP_MIB_INDEX {
+ OP_RATE_SET_I = 1,
+ DTIM_PERIOD_I = 3,
+ RTS_THRESH_I = 5,
+ SHORT_RETRY_LIM_I = 6,
+ LONG_RETRY_LIM_I = 7,
+ FRAG_THRESH_I = 8,
+ DOT11D_I = 9,
+};
+
+#define MAX_SNMP_BUF_SIZE 128
+
+struct host_cmd_ds_802_11_snmp_mib {
+ __le16 query_type;
+ __le16 oid;
+ __le16 buf_size;
+ u8 value[1];
+} __packed;
+
+struct mwifiex_rate_scope {
+ __le16 type;
+ __le16 length;
+ __le16 hr_dsss_rate_bitmap;
+ __le16 ofdm_rate_bitmap;
+ __le16 ht_mcs_rate_bitmap[8];
+} __packed;
+
+struct mwifiex_rate_drop_pattern {
+ __le16 type;
+ __le16 length;
+ __le32 rate_drop_mode;
+} __packed;
+
+struct host_cmd_ds_tx_rate_cfg {
+ __le16 action;
+ __le16 cfg_index;
+} __packed;
+
+struct mwifiex_power_group {
+ u8 modulation_class;
+ u8 first_rate_code;
+ u8 last_rate_code;
+ s8 power_step;
+ s8 power_min;
+ s8 power_max;
+ u8 ht_bandwidth;
+ u8 reserved;
+} __packed;
+
+struct mwifiex_types_power_group {
+ u16 type;
+ u16 length;
+} __packed;
+
+struct host_cmd_ds_txpwr_cfg {
+ __le16 action;
+ __le16 cfg_index;
+ __le32 mode;
+} __packed;
+
+#define MWIFIEX_USER_SCAN_CHAN_MAX 50
+
+#define MWIFIEX_MAX_SSID_LIST_LENGTH 10
+
+struct mwifiex_scan_cmd_config {
+ /*
+ * BSS mode to be sent in the firmware command
+ */
+ u8 bss_mode;
+
+ /* Specific BSSID used to filter scan results in the firmware */
+ u8 specific_bssid[ETH_ALEN];
+
+ /* Length of TLVs sent in command starting at tlvBuffer */
+ u32 tlv_buf_len;
+
+ /*
+ * SSID TLV(s) and ChanList TLVs to be sent in the firmware command
+ *
+ * TLV_TYPE_CHANLIST, mwifiex_ie_types_chan_list_param_set
+ * WLAN_EID_SSID, mwifiex_ie_types_ssid_param_set
+ */
+ u8 tlv_buf[1]; /* SSID TLV(s) and ChanList TLVs are stored
+ here */
+} __packed;
+
+struct mwifiex_user_scan_chan {
+ u8 chan_number;
+ u8 radio_type;
+ u8 scan_type;
+ u8 reserved;
+ u32 scan_time;
+} __packed;
+
+struct mwifiex_user_scan_ssid {
+ u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
+ u8 max_len;
+} __packed;
+
+struct mwifiex_user_scan_cfg {
+ /*
+ * Flag set to keep the previous scan table intact
+ *
+ * If set, the scan results will accumulate, replacing any previous
+ * matched entries for a BSS with the new scan data
+ */
+ u8 keep_previous_scan;
+ /*
+ * BSS mode to be sent in the firmware command
+ */
+ u8 bss_mode;
+ /* Configure the number of probe requests for active chan scans */
+ u8 num_probes;
+ u8 reserved;
+ /* BSSID filter sent in the firmware command to limit the results */
+ u8 specific_bssid[ETH_ALEN];
+ /* SSID filter list used in the to limit the scan results */
+ struct mwifiex_user_scan_ssid ssid_list[MWIFIEX_MAX_SSID_LIST_LENGTH];
+ /* Variable number (fixed maximum) of channels to scan up */
+ struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX];
+} __packed;
+
+struct ie_body {
+ u8 grp_key_oui[4];
+ u8 ptk_cnt[2];
+ u8 ptk_body[4];
+} __packed;
+
+struct host_cmd_ds_802_11_scan {
+ u8 bss_mode;
+ u8 bssid[ETH_ALEN];
+ u8 tlv_buffer[1];
+} __packed;
+
+struct host_cmd_ds_802_11_scan_rsp {
+ __le16 bss_descript_size;
+ u8 number_of_sets;
+ u8 bss_desc_and_tlv_buffer[1];
+} __packed;
+
+struct host_cmd_ds_802_11_bg_scan_query {
+ u8 flush;
+} __packed;
+
+struct host_cmd_ds_802_11_bg_scan_query_rsp {
+ u32 report_condition;
+ struct host_cmd_ds_802_11_scan_rsp scan_resp;
+} __packed;
+
+struct mwifiex_ietypes_domain_param_set {
+ struct mwifiex_ie_types_header header;
+ u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
+ struct ieee80211_country_ie_triplet triplet[1];
+} __packed;
+
+struct host_cmd_ds_802_11d_domain_info {
+ __le16 action;
+ struct mwifiex_ietypes_domain_param_set domain;
+} __packed;
+
+struct host_cmd_ds_802_11d_domain_info_rsp {
+ __le16 action;
+ struct mwifiex_ietypes_domain_param_set domain;
+} __packed;
+
+struct host_cmd_ds_11n_addba_req {
+ u8 add_req_result;
+ u8 peer_mac_addr[ETH_ALEN];
+ u8 dialog_token;
+ __le16 block_ack_param_set;
+ __le16 block_ack_tmo;
+ __le16 ssn;
+} __packed;
+
+struct host_cmd_ds_11n_addba_rsp {
+ u8 add_rsp_result;
+ u8 peer_mac_addr[ETH_ALEN];
+ u8 dialog_token;
+ __le16 status_code;
+ __le16 block_ack_param_set;
+ __le16 block_ack_tmo;
+ __le16 ssn;
+} __packed;
+
+struct host_cmd_ds_11n_delba {
+ u8 del_result;
+ u8 peer_mac_addr[ETH_ALEN];
+ __le16 del_ba_param_set;
+ __le16 reason_code;
+ u8 reserved;
+} __packed;
+
+struct host_cmd_ds_11n_batimeout {
+ u8 tid;
+ u8 peer_mac_addr[ETH_ALEN];
+ u8 origninator;
+} __packed;
+
+struct host_cmd_ds_11n_cfg {
+ __le16 action;
+ __le16 ht_tx_cap;
+ __le16 ht_tx_info;
+} __packed;
+
+struct host_cmd_ds_txbuf_cfg {
+ __le16 action;
+ __le16 buff_size;
+ __le16 mp_end_port; /* SDIO only, reserved for other interfacces */
+ __le16 reserved3;
+} __packed;
+
+struct host_cmd_ds_amsdu_aggr_ctrl {
+ __le16 action;
+ __le16 enable;
+ __le16 curr_buf_size;
+} __packed;
+
+struct mwifiex_ie_types_wmm_param_set {
+ struct mwifiex_ie_types_header header;
+ u8 wmm_ie[1];
+};
+
+struct mwifiex_ie_types_wmm_queue_status {
+ struct mwifiex_ie_types_header header;
+ u8 queue_index;
+ u8 disabled;
+ u16 medium_time;
+ u8 flow_required;
+ u8 flow_created;
+ u32 reserved;
+};
+
+struct ieee_types_vendor_header {
+ u8 element_id;
+ u8 len;
+ u8 oui[3];
+ u8 oui_type;
+ u8 oui_subtype;
+ u8 version;
+} __packed;
+
+struct ieee_types_wmm_ac_parameters {
+ u8 aci_aifsn_bitmap;
+ u8 ecw_bitmap;
+ __le16 tx_op_limit;
+} __packed;
+
+struct ieee_types_wmm_parameter {
+ /*
+ * WMM Parameter IE - Vendor Specific Header:
+ * element_id [221/0xdd]
+ * Len [24]
+ * Oui [00:50:f2]
+ * OuiType [2]
+ * OuiSubType [1]
+ * Version [1]
+ */
+ struct ieee_types_vendor_header vend_hdr;
+ u8 qos_info_bitmap;
+ u8 reserved;
+ struct ieee_types_wmm_ac_parameters ac_params[IEEE80211_MAX_QUEUES];
+} __packed;
+
+struct ieee_types_wmm_info {
+
+ /*
+ * WMM Info IE - Vendor Specific Header:
+ * element_id [221/0xdd]
+ * Len [7]
+ * Oui [00:50:f2]
+ * OuiType [2]
+ * OuiSubType [0]
+ * Version [1]
+ */
+ struct ieee_types_vendor_header vend_hdr;
+
+ u8 qos_info_bitmap;
+} __packed;
+
+struct host_cmd_ds_wmm_get_status {
+ u8 queue_status_tlv[sizeof(struct mwifiex_ie_types_wmm_queue_status) *
+ IEEE80211_MAX_QUEUES];
+ u8 wmm_param_tlv[sizeof(struct ieee_types_wmm_parameter) + 2];
+} __packed;
+
+struct mwifiex_wmm_ac_status {
+ u8 disabled;
+ u8 flow_required;
+ u8 flow_created;
+};
+
+struct mwifiex_ie_types_htcap {
+ struct mwifiex_ie_types_header header;
+ struct ieee80211_ht_cap ht_cap;
+} __packed;
+
+struct mwifiex_ie_types_htinfo {
+ struct mwifiex_ie_types_header header;
+ struct ieee80211_ht_info ht_info;
+} __packed;
+
+struct mwifiex_ie_types_2040bssco {
+ struct mwifiex_ie_types_header header;
+ u8 bss_co_2040;
+} __packed;
+
+struct mwifiex_ie_types_extcap {
+ struct mwifiex_ie_types_header header;
+ u8 ext_cap;
+} __packed;
+
+struct host_cmd_ds_mac_reg_access {
+ __le16 action;
+ __le16 offset;
+ __le32 value;
+} __packed;
+
+struct host_cmd_ds_bbp_reg_access {
+ __le16 action;
+ __le16 offset;
+ u8 value;
+ u8 reserved[3];
+} __packed;
+
+struct host_cmd_ds_rf_reg_access {
+ __le16 action;
+ __le16 offset;
+ u8 value;
+ u8 reserved[3];
+} __packed;
+
+struct host_cmd_ds_pmic_reg_access {
+ __le16 action;
+ __le16 offset;
+ u8 value;
+ u8 reserved[3];
+} __packed;
+
+struct host_cmd_ds_802_11_eeprom_access {
+ __le16 action;
+
+ __le16 offset;
+ __le16 byte_count;
+ u8 value;
+} __packed;
+
+struct host_cmd_ds_802_11_rf_channel {
+ __le16 action;
+ __le16 current_channel;
+ __le16 rf_type;
+ __le16 reserved;
+ u8 reserved_1[32];
+} __packed;
+
+struct host_cmd_ds_version_ext {
+ u8 version_str_sel;
+ char version_str[128];
+} __packed;
+
+struct host_cmd_ds_802_11_ibss_status {
+ __le16 action;
+ __le16 enable;
+ u8 bssid[ETH_ALEN];
+ __le16 beacon_interval;
+ __le16 atim_window;
+ __le16 use_g_rate_protect;
+} __packed;
+
+#define CONNECTION_TYPE_INFRA 0
+#define CONNECTION_TYPE_ADHOC 1
+
+struct host_cmd_ds_set_bss_mode {
+ u8 con_type;
+} __packed;
+
+struct host_cmd_ds_command {
+ __le16 command;
+ __le16 size;
+ __le16 seq_num;
+ __le16 result;
+ union {
+ struct host_cmd_ds_get_hw_spec hw_spec;
+ struct host_cmd_ds_mac_control mac_ctrl;
+ struct host_cmd_ds_802_11_mac_address mac_addr;
+ struct host_cmd_ds_mac_multicast_adr mc_addr;
+ struct host_cmd_ds_802_11_get_log get_log;
+ struct host_cmd_ds_802_11_rssi_info rssi_info;
+ struct host_cmd_ds_802_11_rssi_info_rsp rssi_info_rsp;
+ struct host_cmd_ds_802_11_snmp_mib smib;
+ struct host_cmd_ds_802_11_rf_channel rf_channel;
+ struct host_cmd_ds_tx_rate_query tx_rate;
+ struct host_cmd_ds_tx_rate_cfg tx_rate_cfg;
+ struct host_cmd_ds_txpwr_cfg txp_cfg;
+ struct host_cmd_ds_802_11_ps_mode_enh psmode_enh;
+ struct host_cmd_ds_802_11_hs_cfg_enh opt_hs_cfg;
+ struct host_cmd_ds_802_11_scan scan;
+ struct host_cmd_ds_802_11_scan_rsp scan_resp;
+ struct host_cmd_ds_802_11_bg_scan_query bg_scan_query;
+ struct host_cmd_ds_802_11_bg_scan_query_rsp bg_scan_query_resp;
+ struct host_cmd_ds_802_11_associate associate;
+ struct host_cmd_ds_802_11_associate_rsp associate_rsp;
+ struct host_cmd_ds_802_11_deauthenticate deauth;
+ struct host_cmd_ds_802_11_ad_hoc_start adhoc_start;
+ struct host_cmd_ds_802_11_ad_hoc_result adhoc_result;
+ struct host_cmd_ds_802_11_ad_hoc_join adhoc_join;
+ struct host_cmd_ds_802_11d_domain_info domain_info;
+ struct host_cmd_ds_802_11d_domain_info_rsp domain_info_resp;
+ struct host_cmd_ds_11n_addba_req add_ba_req;
+ struct host_cmd_ds_11n_addba_rsp add_ba_rsp;
+ struct host_cmd_ds_11n_delba del_ba;
+ struct host_cmd_ds_txbuf_cfg tx_buf;
+ struct host_cmd_ds_amsdu_aggr_ctrl amsdu_aggr_ctrl;
+ struct host_cmd_ds_11n_cfg htcfg;
+ struct host_cmd_ds_wmm_get_status get_wmm_status;
+ struct host_cmd_ds_802_11_key_material key_material;
+ struct host_cmd_ds_version_ext verext;
+ struct host_cmd_ds_802_11_ibss_status ibss_coalescing;
+ struct host_cmd_ds_mac_reg_access mac_reg;
+ struct host_cmd_ds_bbp_reg_access bbp_reg;
+ struct host_cmd_ds_rf_reg_access rf_reg;
+ struct host_cmd_ds_pmic_reg_access pmic_reg;
+ struct host_cmd_ds_set_bss_mode bss_mode;
+ struct host_cmd_ds_802_11_eeprom_access eeprom;
+ } params;
+} __packed;
+
+struct mwifiex_opt_sleep_confirm {
+ __le16 command;
+ __le16 size;
+ __le16 seq_num;
+ __le16 result;
+ __le16 action;
+ __le16 resp_ctrl;
+} __packed;
+#endif /* !_MWIFIEX_FW_H_ */
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
new file mode 100644
index 00000000000..3f1559e6132
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -0,0 +1,645 @@
+/*
+ * Marvell Wireless LAN device driver: HW/FW Initialization
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+/*
+ * This function adds a BSS priority table to the table list.
+ *
+ * The function allocates a new BSS priority table node and adds it to
+ * the end of BSS priority table list, kept in driver memory.
+ */
+static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct mwifiex_bss_prio_node *bss_prio;
+ unsigned long flags;
+
+ bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL);
+ if (!bss_prio) {
+ dev_err(adapter->dev, "%s: failed to alloc bss_prio\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ bss_prio->priv = priv;
+ INIT_LIST_HEAD(&bss_prio->list);
+ if (!adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur)
+ adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
+ bss_prio;
+
+ spin_lock_irqsave(&adapter->bss_prio_tbl[priv->bss_priority]
+ .bss_prio_lock, flags);
+ list_add_tail(&bss_prio->list,
+ &adapter->bss_prio_tbl[priv->bss_priority]
+ .bss_prio_head);
+ spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority]
+ .bss_prio_lock, flags);
+
+ return 0;
+}
+
+/*
+ * This function initializes the private structure and sets default
+ * values to the members.
+ *
+ * Additionally, it also initializes all the locks and sets up all the
+ * lists.
+ */
+static int mwifiex_init_priv(struct mwifiex_private *priv)
+{
+ u32 i;
+
+ priv->media_connected = false;
+ memset(priv->curr_addr, 0xff, ETH_ALEN);
+
+ priv->pkt_tx_ctrl = 0;
+ priv->bss_mode = NL80211_IFTYPE_STATION;
+ priv->data_rate = 0; /* Initially indicate the rate as auto */
+ priv->is_data_rate_auto = true;
+ priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
+ priv->data_avg_factor = DEFAULT_DATA_AVG_FACTOR;
+
+ priv->sec_info.wep_status = MWIFIEX_802_11_WEP_DISABLED;
+ priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
+ priv->sec_info.encryption_mode = 0;
+ for (i = 0; i < ARRAY_SIZE(priv->wep_key); i++)
+ memset(&priv->wep_key[i], 0, sizeof(struct mwifiex_wep_key));
+ priv->wep_key_curr_index = 0;
+ priv->curr_pkt_filter = HostCmd_ACT_MAC_RX_ON | HostCmd_ACT_MAC_TX_ON |
+ HostCmd_ACT_MAC_ETHERNETII_ENABLE;
+
+ priv->beacon_period = 100; /* beacon interval */ ;
+ priv->attempted_bss_desc = NULL;
+ memset(&priv->curr_bss_params, 0, sizeof(priv->curr_bss_params));
+ priv->listen_interval = MWIFIEX_DEFAULT_LISTEN_INTERVAL;
+
+ memset(&priv->prev_ssid, 0, sizeof(priv->prev_ssid));
+ memset(&priv->prev_bssid, 0, sizeof(priv->prev_bssid));
+ memset(&priv->assoc_rsp_buf, 0, sizeof(priv->assoc_rsp_buf));
+ priv->assoc_rsp_size = 0;
+ priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
+ priv->atim_window = 0;
+ priv->adhoc_state = ADHOC_IDLE;
+ priv->tx_power_level = 0;
+ priv->max_tx_power_level = 0;
+ priv->min_tx_power_level = 0;
+ priv->tx_rate = 0;
+ priv->rxpd_htinfo = 0;
+ priv->rxpd_rate = 0;
+ priv->rate_bitmap = 0;
+ priv->data_rssi_last = 0;
+ priv->data_rssi_avg = 0;
+ priv->data_nf_avg = 0;
+ priv->data_nf_last = 0;
+ priv->bcn_rssi_last = 0;
+ priv->bcn_rssi_avg = 0;
+ priv->bcn_nf_avg = 0;
+ priv->bcn_nf_last = 0;
+ memset(&priv->wpa_ie, 0, sizeof(priv->wpa_ie));
+ memset(&priv->aes_key, 0, sizeof(priv->aes_key));
+ priv->wpa_ie_len = 0;
+ priv->wpa_is_gtk_set = false;
+
+ memset(&priv->assoc_tlv_buf, 0, sizeof(priv->assoc_tlv_buf));
+ priv->assoc_tlv_buf_len = 0;
+ memset(&priv->wps, 0, sizeof(priv->wps));
+ memset(&priv->gen_ie_buf, 0, sizeof(priv->gen_ie_buf));
+ priv->gen_ie_buf_len = 0;
+ memset(priv->vs_ie, 0, sizeof(priv->vs_ie));
+
+ priv->wmm_required = true;
+ priv->wmm_enabled = false;
+ priv->wmm_qosinfo = 0;
+ priv->curr_bcn_buf = NULL;
+ priv->curr_bcn_size = 0;
+
+ priv->scan_block = false;
+
+ return mwifiex_add_bss_prio_tbl(priv);
+}
+
+/*
+ * This function allocates buffers for members of the adapter
+ * structure.
+ *
+ * The memory allocated includes scan table, command buffers, and
+ * sleep confirm command buffer. In addition, the queues are
+ * also initialized.
+ */
+static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter)
+{
+ int ret;
+ u32 buf_size;
+ struct mwifiex_bssdescriptor *temp_scan_table;
+
+ /* Allocate buffer to store the BSSID list */
+ buf_size = sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP;
+ temp_scan_table = kzalloc(buf_size, GFP_KERNEL);
+ if (!temp_scan_table) {
+ dev_err(adapter->dev, "%s: failed to alloc temp_scan_table\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ adapter->scan_table = temp_scan_table;
+
+ /* Allocate command buffer */
+ ret = mwifiex_alloc_cmd_buffer(adapter);
+ if (ret) {
+ dev_err(adapter->dev, "%s: failed to alloc cmd buffer\n",
+ __func__);
+ return -1;
+ }
+
+ adapter->sleep_cfm =
+ dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm)
+ + INTF_HEADER_LEN);
+
+ if (!adapter->sleep_cfm) {
+ dev_err(adapter->dev, "%s: failed to alloc sleep cfm"
+ " cmd buffer\n", __func__);
+ return -1;
+ }
+ skb_reserve(adapter->sleep_cfm, INTF_HEADER_LEN);
+
+ return 0;
+}
+
+/*
+ * This function initializes the adapter structure and sets default
+ * values to the members of adapter.
+ *
+ * This also initializes the WMM related parameters in the driver private
+ * structures.
+ */
+static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
+{
+ struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = NULL;
+
+ skb_put(adapter->sleep_cfm, sizeof(struct mwifiex_opt_sleep_confirm));
+ sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *)
+ (adapter->sleep_cfm->data);
+
+ adapter->cmd_sent = false;
+ adapter->data_sent = true;
+ adapter->cmd_resp_received = false;
+ adapter->event_received = false;
+ adapter->data_received = false;
+
+ adapter->surprise_removed = false;
+
+ adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
+
+ adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
+ adapter->ps_state = PS_STATE_AWAKE;
+ adapter->need_to_wakeup = false;
+
+ adapter->scan_mode = HostCmd_BSS_MODE_ANY;
+ adapter->specific_scan_time = MWIFIEX_SPECIFIC_SCAN_CHAN_TIME;
+ adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME;
+ adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME;
+
+ adapter->num_in_scan_table = 0;
+ memset(adapter->scan_table, 0,
+ (sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP));
+ adapter->scan_probes = 1;
+
+ memset(adapter->bcn_buf, 0, sizeof(adapter->bcn_buf));
+ adapter->bcn_buf_end = adapter->bcn_buf;
+
+ adapter->multiple_dtim = 1;
+
+ adapter->local_listen_interval = 0; /* default value in firmware
+ will be used */
+
+ adapter->is_deep_sleep = false;
+
+ adapter->delay_null_pkt = false;
+ adapter->delay_to_ps = 1000;
+ adapter->enhanced_ps_mode = PS_MODE_AUTO;
+
+ adapter->gen_null_pkt = false; /* Disable NULL Pkg generation by
+ default */
+ adapter->pps_uapsd_mode = false; /* Disable pps/uapsd mode by
+ default */
+ adapter->pm_wakeup_card_req = false;
+
+ adapter->pm_wakeup_fw_try = false;
+
+ adapter->max_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
+ adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
+ adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
+
+ adapter->is_hs_configured = false;
+ adapter->hs_cfg.conditions = cpu_to_le32(HOST_SLEEP_CFG_COND_DEF);
+ adapter->hs_cfg.gpio = HOST_SLEEP_CFG_GPIO_DEF;
+ adapter->hs_cfg.gap = HOST_SLEEP_CFG_GAP_DEF;
+ adapter->hs_activated = false;
+
+ memset(adapter->event_body, 0, sizeof(adapter->event_body));
+ adapter->hw_dot_11n_dev_cap = 0;
+ adapter->hw_dev_mcs_support = 0;
+ adapter->chan_offset = 0;
+ adapter->adhoc_11n_enabled = false;
+
+ mwifiex_wmm_init(adapter);
+
+ if (adapter->sleep_cfm) {
+ memset(sleep_cfm_buf, 0, adapter->sleep_cfm->len);
+ sleep_cfm_buf->command =
+ cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
+ sleep_cfm_buf->size =
+ cpu_to_le16(adapter->sleep_cfm->len);
+ sleep_cfm_buf->result = 0;
+ sleep_cfm_buf->action = cpu_to_le16(SLEEP_CONFIRM);
+ sleep_cfm_buf->resp_ctrl = cpu_to_le16(RESP_NEEDED);
+ }
+ memset(&adapter->sleep_params, 0, sizeof(adapter->sleep_params));
+ memset(&adapter->sleep_period, 0, sizeof(adapter->sleep_period));
+ adapter->tx_lock_flag = false;
+ adapter->null_pkt_interval = 0;
+ adapter->fw_bands = 0;
+ adapter->config_bands = 0;
+ adapter->adhoc_start_band = 0;
+ adapter->scan_channels = NULL;
+ adapter->fw_release_number = 0;
+ adapter->fw_cap_info = 0;
+ memset(&adapter->upld_buf, 0, sizeof(adapter->upld_buf));
+ adapter->event_cause = 0;
+ adapter->region_code = 0;
+ adapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT;
+ adapter->adhoc_awake_period = 0;
+ memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
+ adapter->arp_filter_size = 0;
+}
+
+/*
+ * This function frees the adapter structure.
+ *
+ * The freeing operation is done recursively, by canceling all
+ * pending commands, freeing the member buffers previously
+ * allocated (command buffers, scan table buffer, sleep confirm
+ * command buffer), stopping the timers and calling the cleanup
+ * routines for every interface, before the actual adapter
+ * structure is freed.
+ */
+static void
+mwifiex_free_adapter(struct mwifiex_adapter *adapter)
+{
+ if (!adapter) {
+ pr_err("%s: adapter is NULL\n", __func__);
+ return;
+ }
+
+ mwifiex_cancel_all_pending_cmd(adapter);
+
+ /* Free lock variables */
+ mwifiex_free_lock_list(adapter);
+
+ /* Free command buffer */
+ dev_dbg(adapter->dev, "info: free cmd buffer\n");
+ mwifiex_free_cmd_buffer(adapter);
+
+ del_timer(&adapter->cmd_timer);
+
+ dev_dbg(adapter->dev, "info: free scan table\n");
+ kfree(adapter->scan_table);
+ adapter->scan_table = NULL;
+
+ adapter->if_ops.cleanup_if(adapter);
+
+ dev_kfree_skb_any(adapter->sleep_cfm);
+}
+
+/*
+ * This function intializes the lock variables and
+ * the list heads.
+ */
+int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
+{
+ struct mwifiex_private *priv;
+ s32 i, j;
+
+ spin_lock_init(&adapter->mwifiex_lock);
+ spin_lock_init(&adapter->int_lock);
+ spin_lock_init(&adapter->main_proc_lock);
+ spin_lock_init(&adapter->mwifiex_cmd_lock);
+ for (i = 0; i < adapter->priv_num; i++) {
+ if (adapter->priv[i]) {
+ priv = adapter->priv[i];
+ spin_lock_init(&priv->rx_pkt_lock);
+ spin_lock_init(&priv->wmm.ra_list_spinlock);
+ spin_lock_init(&priv->curr_bcn_buf_lock);
+ }
+ }
+
+ /* Initialize cmd_free_q */
+ INIT_LIST_HEAD(&adapter->cmd_free_q);
+ /* Initialize cmd_pending_q */
+ INIT_LIST_HEAD(&adapter->cmd_pending_q);
+ /* Initialize scan_pending_q */
+ INIT_LIST_HEAD(&adapter->scan_pending_q);
+
+ spin_lock_init(&adapter->cmd_free_q_lock);
+ spin_lock_init(&adapter->cmd_pending_q_lock);
+ spin_lock_init(&adapter->scan_pending_q_lock);
+
+ for (i = 0; i < adapter->priv_num; ++i) {
+ INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head);
+ adapter->bss_prio_tbl[i].bss_prio_cur = NULL;
+ spin_lock_init(&adapter->bss_prio_tbl[i].bss_prio_lock);
+ }
+
+ for (i = 0; i < adapter->priv_num; i++) {
+ if (!adapter->priv[i])
+ continue;
+ priv = adapter->priv[i];
+ for (j = 0; j < MAX_NUM_TID; ++j) {
+ INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[j].ra_list);
+ spin_lock_init(&priv->wmm.tid_tbl_ptr[j].tid_tbl_lock);
+ }
+ INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
+ INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
+
+ spin_lock_init(&priv->tx_ba_stream_tbl_lock);
+ spin_lock_init(&priv->rx_reorder_tbl_lock);
+ }
+
+ return 0;
+}
+
+/*
+ * This function releases the lock variables and frees the locks and
+ * associated locks.
+ */
+void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
+{
+ struct mwifiex_private *priv;
+ s32 i, j;
+
+ /* Free lists */
+ list_del(&adapter->cmd_free_q);
+ list_del(&adapter->cmd_pending_q);
+ list_del(&adapter->scan_pending_q);
+
+ for (i = 0; i < adapter->priv_num; i++)
+ list_del(&adapter->bss_prio_tbl[i].bss_prio_head);
+
+ for (i = 0; i < adapter->priv_num; i++) {
+ if (adapter->priv[i]) {
+ priv = adapter->priv[i];
+ for (j = 0; j < MAX_NUM_TID; ++j)
+ list_del(&priv->wmm.tid_tbl_ptr[j].ra_list);
+ list_del(&priv->tx_ba_stream_tbl_ptr);
+ list_del(&priv->rx_reorder_tbl_ptr);
+ }
+ }
+}
+
+/*
+ * This function initializes the firmware.
+ *
+ * The following operations are performed sequentially -
+ * - Allocate adapter structure
+ * - Initialize the adapter structure
+ * - Initialize the private structure
+ * - Add BSS priority tables to the adapter structure
+ * - For each interface, send the init commands to firmware
+ * - Send the first command in command pending queue, if available
+ */
+int mwifiex_init_fw(struct mwifiex_adapter *adapter)
+{
+ int ret;
+ struct mwifiex_private *priv;
+ u8 i, first_sta = true;
+ int is_cmd_pend_q_empty;
+ unsigned long flags;
+
+ adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
+
+ /* Allocate memory for member of adapter structure */
+ ret = mwifiex_allocate_adapter(adapter);
+ if (ret)
+ return -1;
+
+ /* Initialize adapter structure */
+ mwifiex_init_adapter(adapter);
+
+ for (i = 0; i < adapter->priv_num; i++) {
+ if (adapter->priv[i]) {
+ priv = adapter->priv[i];
+
+ /* Initialize private structure */
+ ret = mwifiex_init_priv(priv);
+ if (ret)
+ return -1;
+ }
+ }
+ for (i = 0; i < adapter->priv_num; i++) {
+ if (adapter->priv[i]) {
+ ret = mwifiex_sta_init_cmd(adapter->priv[i], first_sta);
+ if (ret == -1)
+ return -1;
+
+ first_sta = false;
+ }
+ }
+
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+ is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+ if (!is_cmd_pend_q_empty) {
+ /* Send the first command in queue and return */
+ if (mwifiex_main_process(adapter) != -1)
+ ret = -EINPROGRESS;
+ } else {
+ adapter->hw_status = MWIFIEX_HW_STATUS_READY;
+ }
+
+ return ret;
+}
+
+/*
+ * This function deletes the BSS priority tables.
+ *
+ * The function traverses through all the allocated BSS priority nodes
+ * in every BSS priority table and frees them.
+ */
+static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
+{
+ int i;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct mwifiex_bss_prio_node *bssprio_node, *tmp_node, **cur;
+ struct list_head *head;
+ spinlock_t *lock;
+ unsigned long flags;
+
+ for (i = 0; i < adapter->priv_num; ++i) {
+ head = &adapter->bss_prio_tbl[i].bss_prio_head;
+ cur = &adapter->bss_prio_tbl[i].bss_prio_cur;
+ lock = &adapter->bss_prio_tbl[i].bss_prio_lock;
+ dev_dbg(adapter->dev, "info: delete BSS priority table,"
+ " index = %d, i = %d, head = %p, cur = %p\n",
+ priv->bss_index, i, head, *cur);
+ if (*cur) {
+ spin_lock_irqsave(lock, flags);
+ if (list_empty(head)) {
+ spin_unlock_irqrestore(lock, flags);
+ continue;
+ }
+ bssprio_node = list_first_entry(head,
+ struct mwifiex_bss_prio_node, list);
+ spin_unlock_irqrestore(lock, flags);
+
+ list_for_each_entry_safe(bssprio_node, tmp_node, head,
+ list) {
+ if (bssprio_node->priv == priv) {
+ dev_dbg(adapter->dev, "info: Delete "
+ "node %p, next = %p\n",
+ bssprio_node, tmp_node);
+ spin_lock_irqsave(lock, flags);
+ list_del(&bssprio_node->list);
+ spin_unlock_irqrestore(lock, flags);
+ kfree(bssprio_node);
+ }
+ }
+ *cur = (struct mwifiex_bss_prio_node *)head;
+ }
+ }
+}
+
+/*
+ * This function is used to shutdown the driver.
+ *
+ * The following operations are performed sequentially -
+ * - Check if already shut down
+ * - Make sure the main process has stopped
+ * - Clean up the Tx and Rx queues
+ * - Delete BSS priority tables
+ * - Free the adapter
+ * - Notify completion
+ */
+int
+mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
+{
+ int ret = -EINPROGRESS;
+ struct mwifiex_private *priv;
+ s32 i;
+ unsigned long flags;
+
+ /* mwifiex already shutdown */
+ if (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)
+ return 0;
+
+ adapter->hw_status = MWIFIEX_HW_STATUS_CLOSING;
+ /* wait for mwifiex_process to complete */
+ if (adapter->mwifiex_processing) {
+ dev_warn(adapter->dev, "main process is still running\n");
+ return ret;
+ }
+
+ /* shut down mwifiex */
+ dev_dbg(adapter->dev, "info: shutdown mwifiex...\n");
+
+ /* Clean up Tx/Rx queues and delete BSS priority table */
+ for (i = 0; i < adapter->priv_num; i++) {
+ if (adapter->priv[i]) {
+ priv = adapter->priv[i];
+
+ mwifiex_clean_txrx(priv);
+ mwifiex_delete_bss_prio_tbl(priv);
+ }
+ }
+
+ spin_lock_irqsave(&adapter->mwifiex_lock, flags);
+
+ /* Free adapter structure */
+ mwifiex_free_adapter(adapter);
+
+ spin_unlock_irqrestore(&adapter->mwifiex_lock, flags);
+
+ /* Notify completion */
+ ret = mwifiex_shutdown_fw_complete(adapter);
+
+ return ret;
+}
+
+/*
+ * This function downloads the firmware to the card.
+ *
+ * The actual download is preceded by two sanity checks -
+ * - Check if firmware is already running
+ * - Check if the interface is the winner to download the firmware
+ *
+ * ...and followed by another -
+ * - Check if the firmware is downloaded successfully
+ *
+ * After download is successfully completed, the host interrupts are enabled.
+ */
+int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
+ struct mwifiex_fw_image *pmfw)
+{
+ int ret, winner;
+ u32 poll_num = 1;
+
+ /* Check if firmware is already running */
+ ret = adapter->if_ops.check_fw_status(adapter, poll_num, &winner);
+ if (!ret) {
+ dev_notice(adapter->dev,
+ "WLAN FW already running! Skip FW download\n");
+ goto done;
+ }
+ poll_num = MAX_FIRMWARE_POLL_TRIES;
+
+ /* Check if we are the winner for downloading FW */
+ if (!winner) {
+ dev_notice(adapter->dev,
+ "Other interface already running!"
+ " Skip FW download\n");
+ poll_num = MAX_MULTI_INTERFACE_POLL_TRIES;
+ goto poll_fw;
+ }
+ if (pmfw) {
+ /* Download firmware with helper */
+ ret = adapter->if_ops.prog_fw(adapter, pmfw);
+ if (ret) {
+ dev_err(adapter->dev, "prog_fw failed ret=%#x\n", ret);
+ return ret;
+ }
+ }
+
+poll_fw:
+ /* Check if the firmware is downloaded successfully or not */
+ ret = adapter->if_ops.check_fw_status(adapter, poll_num, NULL);
+ if (ret) {
+ dev_err(adapter->dev, "FW failed to be active in time\n");
+ return -1;
+ }
+done:
+ /* re-enable host interrupt for mwifiex after fw dnld is successful */
+ adapter->if_ops.enable_int(adapter);
+ return ret;
+}
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
new file mode 100644
index 00000000000..7c1c5ee40eb
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -0,0 +1,331 @@
+/*
+ * Marvell Wireless LAN device driver: ioctl data structures & APIs
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_IOCTL_H_
+#define _MWIFIEX_IOCTL_H_
+
+#include <net/mac80211.h>
+
+enum {
+ MWIFIEX_SCAN_TYPE_UNCHANGED = 0,
+ MWIFIEX_SCAN_TYPE_ACTIVE,
+ MWIFIEX_SCAN_TYPE_PASSIVE
+};
+
+struct mwifiex_user_scan {
+ u32 scan_cfg_len;
+ u8 scan_cfg_buf[1];
+};
+
+#define MWIFIEX_PROMISC_MODE 1
+#define MWIFIEX_MULTICAST_MODE 2
+#define MWIFIEX_ALL_MULTI_MODE 4
+#define MWIFIEX_MAX_MULTICAST_LIST_SIZE 32
+
+struct mwifiex_multicast_list {
+ u32 mode;
+ u32 num_multicast_addr;
+ u8 mac_list[MWIFIEX_MAX_MULTICAST_LIST_SIZE][ETH_ALEN];
+};
+
+struct mwifiex_chan_freq {
+ u32 channel;
+ u32 freq;
+};
+
+struct mwifiex_ssid_bssid {
+ struct mwifiex_802_11_ssid ssid;
+ u8 bssid[ETH_ALEN];
+};
+
+enum {
+ BAND_B = 1,
+ BAND_G = 2,
+ BAND_A = 4,
+ BAND_GN = 8,
+ BAND_AN = 16,
+};
+
+#define NO_SEC_CHANNEL 0
+#define SEC_CHANNEL_ABOVE 1
+#define SEC_CHANNEL_BELOW 3
+
+struct mwifiex_ds_band_cfg {
+ u32 config_bands;
+ u32 adhoc_start_band;
+ u32 adhoc_channel;
+ u32 sec_chan_offset;
+};
+
+enum {
+ ADHOC_IDLE,
+ ADHOC_STARTED,
+ ADHOC_JOINED,
+ ADHOC_COALESCED
+};
+
+struct mwifiex_ds_get_stats {
+ u32 mcast_tx_frame;
+ u32 failed;
+ u32 retry;
+ u32 multi_retry;
+ u32 frame_dup;
+ u32 rts_success;
+ u32 rts_failure;
+ u32 ack_failure;
+ u32 rx_frag;
+ u32 mcast_rx_frame;
+ u32 fcs_error;
+ u32 tx_frame;
+ u32 wep_icv_error[4];
+};
+
+#define BCN_RSSI_AVG_MASK 0x00000002
+#define BCN_NF_AVG_MASK 0x00000200
+#define ALL_RSSI_INFO_MASK 0x00000fff
+
+struct mwifiex_ds_get_signal {
+ /*
+ * Bit0: Last Beacon RSSI, Bit1: Average Beacon RSSI,
+ * Bit2: Last Data RSSI, Bit3: Average Data RSSI,
+ * Bit4: Last Beacon SNR, Bit5: Average Beacon SNR,
+ * Bit6: Last Data SNR, Bit7: Average Data SNR,
+ * Bit8: Last Beacon NF, Bit9: Average Beacon NF,
+ * Bit10: Last Data NF, Bit11: Average Data NF
+ */
+ u16 selector;
+ s16 bcn_rssi_last;
+ s16 bcn_rssi_avg;
+ s16 data_rssi_last;
+ s16 data_rssi_avg;
+ s16 bcn_snr_last;
+ s16 bcn_snr_avg;
+ s16 data_snr_last;
+ s16 data_snr_avg;
+ s16 bcn_nf_last;
+ s16 bcn_nf_avg;
+ s16 data_nf_last;
+ s16 data_nf_avg;
+};
+
+#define MWIFIEX_MAX_VER_STR_LEN 128
+
+struct mwifiex_ver_ext {
+ u32 version_str_sel;
+ char version_str[MWIFIEX_MAX_VER_STR_LEN];
+};
+
+struct mwifiex_bss_info {
+ u32 bss_mode;
+ struct mwifiex_802_11_ssid ssid;
+ u32 scan_table_idx;
+ u32 bss_chan;
+ u32 region_code;
+ u32 media_connected;
+ u32 max_power_level;
+ u32 min_power_level;
+ u32 adhoc_state;
+ signed int bcn_nf_last;
+ u32 wep_status;
+ u32 is_hs_configured;
+ u32 is_deep_sleep;
+ u8 bssid[ETH_ALEN];
+};
+
+#define MAX_NUM_TID 8
+
+#define MAX_RX_WINSIZE 64
+
+struct mwifiex_ds_rx_reorder_tbl {
+ u16 tid;
+ u8 ta[ETH_ALEN];
+ u32 start_win;
+ u32 win_size;
+ u32 buffer[MAX_RX_WINSIZE];
+};
+
+struct mwifiex_ds_tx_ba_stream_tbl {
+ u16 tid;
+ u8 ra[ETH_ALEN];
+};
+
+#define DBG_CMD_NUM 5
+
+struct mwifiex_debug_info {
+ u32 int_counter;
+ u32 packets_out[MAX_NUM_TID];
+ u32 max_tx_buf_size;
+ u32 tx_buf_size;
+ u32 curr_tx_buf_size;
+ u32 tx_tbl_num;
+ struct mwifiex_ds_tx_ba_stream_tbl
+ tx_tbl[MWIFIEX_MAX_TX_BASTREAM_SUPPORTED];
+ u32 rx_tbl_num;
+ struct mwifiex_ds_rx_reorder_tbl rx_tbl
+ [MWIFIEX_MAX_RX_BASTREAM_SUPPORTED];
+ u16 ps_mode;
+ u32 ps_state;
+ u8 is_deep_sleep;
+ u8 pm_wakeup_card_req;
+ u32 pm_wakeup_fw_try;
+ u8 is_hs_configured;
+ u8 hs_activated;
+ u32 num_cmd_host_to_card_failure;
+ u32 num_cmd_sleep_cfm_host_to_card_failure;
+ u32 num_tx_host_to_card_failure;
+ u32 num_event_deauth;
+ u32 num_event_disassoc;
+ u32 num_event_link_lost;
+ u32 num_cmd_deauth;
+ u32 num_cmd_assoc_success;
+ u32 num_cmd_assoc_failure;
+ u32 num_tx_timeout;
+ u32 num_cmd_timeout;
+ u16 timeout_cmd_id;
+ u16 timeout_cmd_act;
+ u16 last_cmd_id[DBG_CMD_NUM];
+ u16 last_cmd_act[DBG_CMD_NUM];
+ u16 last_cmd_index;
+ u16 last_cmd_resp_id[DBG_CMD_NUM];
+ u16 last_cmd_resp_index;
+ u16 last_event[DBG_CMD_NUM];
+ u16 last_event_index;
+ u8 data_sent;
+ u8 cmd_sent;
+ u8 cmd_resp_received;
+ u8 event_received;
+};
+
+#define MWIFIEX_KEY_INDEX_UNICAST 0x40000000
+#define WAPI_RXPN_LEN 16
+
+struct mwifiex_ds_encrypt_key {
+ u32 key_disable;
+ u32 key_index;
+ u32 key_len;
+ u8 key_material[WLAN_MAX_KEY_LEN];
+ u8 mac_addr[ETH_ALEN];
+ u32 is_wapi_key;
+ u8 wapi_rxpn[WAPI_RXPN_LEN];
+};
+
+struct mwifiex_rate_cfg {
+ u32 action;
+ u32 is_rate_auto;
+ u32 rate;
+};
+
+struct mwifiex_power_cfg {
+ u32 is_power_auto;
+ u32 power_level;
+};
+
+struct mwifiex_ds_hs_cfg {
+ u32 is_invoke_hostcmd;
+ /* Bit0: non-unicast data
+ * Bit1: unicast data
+ * Bit2: mac events
+ * Bit3: magic packet
+ */
+ u32 conditions;
+ u32 gpio;
+ u32 gap;
+};
+
+#define DEEP_SLEEP_ON 1
+#define DEEP_SLEEP_IDLE_TIME 100
+#define PS_MODE_AUTO 1
+
+struct mwifiex_ds_auto_ds {
+ u16 auto_ds;
+ u16 idle_time;
+};
+
+struct mwifiex_ds_pm_cfg {
+ union {
+ u32 ps_mode;
+ struct mwifiex_ds_hs_cfg hs_cfg;
+ struct mwifiex_ds_auto_ds auto_deep_sleep;
+ u32 sleep_period;
+ } param;
+};
+
+struct mwifiex_ds_11n_tx_cfg {
+ u16 tx_htcap;
+ u16 tx_htinfo;
+};
+
+struct mwifiex_ds_11n_amsdu_aggr_ctrl {
+ u16 enable;
+ u16 curr_buf_size;
+};
+
+#define MWIFIEX_NUM_OF_CMD_BUFFER 20
+#define MWIFIEX_SIZE_OF_CMD_BUFFER 2048
+
+enum {
+ MWIFIEX_IE_TYPE_GEN_IE = 0,
+ MWIFIEX_IE_TYPE_ARP_FILTER,
+};
+
+enum {
+ MWIFIEX_REG_MAC = 1,
+ MWIFIEX_REG_BBP,
+ MWIFIEX_REG_RF,
+ MWIFIEX_REG_PMIC,
+ MWIFIEX_REG_CAU,
+};
+
+struct mwifiex_ds_reg_rw {
+ __le32 type;
+ __le32 offset;
+ __le32 value;
+};
+
+#define MAX_EEPROM_DATA 256
+
+struct mwifiex_ds_read_eeprom {
+ __le16 offset;
+ __le16 byte_count;
+ u8 value[MAX_EEPROM_DATA];
+};
+
+struct mwifiex_ds_misc_gen_ie {
+ u32 type;
+ u32 len;
+ u8 ie_data[IW_CUSTOM_MAX];
+};
+
+struct mwifiex_ds_misc_cmd {
+ u32 len;
+ u8 cmd[MWIFIEX_SIZE_OF_CMD_BUFFER];
+};
+
+#define MWIFIEX_MAX_VSIE_LEN (256)
+#define MWIFIEX_MAX_VSIE_NUM (8)
+#define MWIFIEX_VSIE_MASK_SCAN 0x01
+#define MWIFIEX_VSIE_MASK_ASSOC 0x02
+#define MWIFIEX_VSIE_MASK_ADHOC 0x04
+
+enum {
+ MWIFIEX_FUNC_INIT = 1,
+ MWIFIEX_FUNC_SHUTDOWN,
+};
+
+#endif /* !_MWIFIEX_IOCTL_H_ */
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
new file mode 100644
index 00000000000..5eab3dc29b1
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -0,0 +1,1423 @@
+/*
+ * Marvell Wireless LAN device driver: association and ad-hoc start/join
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+#define CAPINFO_MASK (~(BIT(15) | BIT(14) | BIT(12) | BIT(11) | BIT(9)))
+
+/*
+ * Append a generic IE as a pass through TLV to a TLV buffer.
+ *
+ * This function is called from the network join command preparation routine.
+ *
+ * If the IE buffer has been setup by the application, this routine appends
+ * the buffer as a pass through TLV type to the request.
+ */
+static int
+mwifiex_cmd_append_generic_ie(struct mwifiex_private *priv, u8 **buffer)
+{
+ int ret_len = 0;
+ struct mwifiex_ie_types_header ie_header;
+
+ /* Null Checks */
+ if (!buffer)
+ return 0;
+ if (!(*buffer))
+ return 0;
+
+ /*
+ * If there is a generic ie buffer setup, append it to the return
+ * parameter buffer pointer.
+ */
+ if (priv->gen_ie_buf_len) {
+ dev_dbg(priv->adapter->dev, "info: %s: append generic %d to %p\n",
+ __func__, priv->gen_ie_buf_len, *buffer);
+
+ /* Wrap the generic IE buffer with a pass through TLV type */
+ ie_header.type = cpu_to_le16(TLV_TYPE_PASSTHROUGH);
+ ie_header.len = cpu_to_le16(priv->gen_ie_buf_len);
+ memcpy(*buffer, &ie_header, sizeof(ie_header));
+
+ /* Increment the return size and the return buffer pointer
+ param */
+ *buffer += sizeof(ie_header);
+ ret_len += sizeof(ie_header);
+
+ /* Copy the generic IE buffer to the output buffer, advance
+ pointer */
+ memcpy(*buffer, priv->gen_ie_buf, priv->gen_ie_buf_len);
+
+ /* Increment the return size and the return buffer pointer
+ param */
+ *buffer += priv->gen_ie_buf_len;
+ ret_len += priv->gen_ie_buf_len;
+
+ /* Reset the generic IE buffer */
+ priv->gen_ie_buf_len = 0;
+ }
+
+ /* return the length appended to the buffer */
+ return ret_len;
+}
+
+/*
+ * Append TSF tracking info from the scan table for the target AP.
+ *
+ * This function is called from the network join command preparation routine.
+ *
+ * The TSF table TSF sent to the firmware contains two TSF values:
+ * - The TSF of the target AP from its previous beacon/probe response
+ * - The TSF timestamp of our local MAC at the time we observed the
+ * beacon/probe response.
+ *
+ * The firmware uses the timestamp values to set an initial TSF value
+ * in the MAC for the new association after a reassociation attempt.
+ */
+static int
+mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer,
+ struct mwifiex_bssdescriptor *bss_desc)
+{
+ struct mwifiex_ie_types_tsf_timestamp tsf_tlv;
+ __le64 tsf_val;
+
+ /* Null Checks */
+ if (buffer == NULL)
+ return 0;
+ if (*buffer == NULL)
+ return 0;
+
+ memset(&tsf_tlv, 0x00, sizeof(struct mwifiex_ie_types_tsf_timestamp));
+
+ tsf_tlv.header.type = cpu_to_le16(TLV_TYPE_TSFTIMESTAMP);
+ tsf_tlv.header.len = cpu_to_le16(2 * sizeof(tsf_val));
+
+ memcpy(*buffer, &tsf_tlv, sizeof(tsf_tlv.header));
+ *buffer += sizeof(tsf_tlv.header);
+
+ /* TSF at the time when beacon/probe_response was received */
+ tsf_val = cpu_to_le64(bss_desc->network_tsf);
+ memcpy(*buffer, &tsf_val, sizeof(tsf_val));
+ *buffer += sizeof(tsf_val);
+
+ memcpy(&tsf_val, bss_desc->time_stamp, sizeof(tsf_val));
+
+ dev_dbg(priv->adapter->dev, "info: %s: TSF offset calc: %016llx - "
+ "%016llx\n", __func__, tsf_val, bss_desc->network_tsf);
+
+ memcpy(*buffer, &tsf_val, sizeof(tsf_val));
+ *buffer += sizeof(tsf_val);
+
+ return sizeof(tsf_tlv.header) + (2 * sizeof(tsf_val));
+}
+
+/*
+ * This function finds out the common rates between rate1 and rate2.
+ *
+ * It will fill common rates in rate1 as output if found.
+ *
+ * NOTE: Setting the MSB of the basic rates needs to be taken
+ * care of, either before or after calling this function.
+ */
+static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1,
+ u32 rate1_size, u8 *rate2, u32 rate2_size)
+{
+ int ret;
+ u8 *ptr = rate1, *tmp;
+ u32 i, j;
+
+ tmp = kmalloc(rate1_size, GFP_KERNEL);
+ if (!tmp) {
+ dev_err(priv->adapter->dev, "failed to alloc tmp buf\n");
+ return -ENOMEM;
+ }
+
+ memcpy(tmp, rate1, rate1_size);
+ memset(rate1, 0, rate1_size);
+
+ for (i = 0; rate2[i] && i < rate2_size; i++) {
+ for (j = 0; tmp[j] && j < rate1_size; j++) {
+ /* Check common rate, excluding the bit for
+ basic rate */
+ if ((rate2[i] & 0x7F) == (tmp[j] & 0x7F)) {
+ *rate1++ = tmp[j];
+ break;
+ }
+ }
+ }
+
+ dev_dbg(priv->adapter->dev, "info: Tx data rate set to %#x\n",
+ priv->data_rate);
+
+ if (!priv->is_data_rate_auto) {
+ while (*ptr) {
+ if ((*ptr & 0x7f) == priv->data_rate) {
+ ret = 0;
+ goto done;
+ }
+ ptr++;
+ }
+ dev_err(priv->adapter->dev, "previously set fixed data rate %#x"
+ " is not compatible with the network\n",
+ priv->data_rate);
+
+ ret = -1;
+ goto done;
+ }
+
+ ret = 0;
+done:
+ kfree(tmp);
+ return ret;
+}
+
+/*
+ * This function creates the intersection of the rates supported by a
+ * target BSS and our adapter settings for use in an assoc/join command.
+ */
+static int
+mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc,
+ u8 *out_rates, u32 *out_rates_size)
+{
+ u8 card_rates[MWIFIEX_SUPPORTED_RATES];
+ u32 card_rates_size;
+
+ /* Copy AP supported rates */
+ memcpy(out_rates, bss_desc->supported_rates, MWIFIEX_SUPPORTED_RATES);
+ /* Get the STA supported rates */
+ card_rates_size = mwifiex_get_active_data_rates(priv, card_rates);
+ /* Get the common rates between AP and STA supported rates */
+ if (mwifiex_get_common_rates(priv, out_rates, MWIFIEX_SUPPORTED_RATES,
+ card_rates, card_rates_size)) {
+ *out_rates_size = 0;
+ dev_err(priv->adapter->dev, "%s: cannot get common rates\n",
+ __func__);
+ return -1;
+ }
+
+ *out_rates_size =
+ min_t(size_t, strlen(out_rates), MWIFIEX_SUPPORTED_RATES);
+
+ return 0;
+}
+
+/*
+ * This function updates the scan entry TSF timestamps to reflect
+ * a new association.
+ */
+static void
+mwifiex_update_tsf_timestamps(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *new_bss_desc)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ u32 table_idx;
+ long long new_tsf_base;
+ signed long long tsf_delta;
+
+ memcpy(&new_tsf_base, new_bss_desc->time_stamp, sizeof(new_tsf_base));
+
+ tsf_delta = new_tsf_base - new_bss_desc->network_tsf;
+
+ dev_dbg(adapter->dev, "info: TSF: update TSF timestamps, "
+ "0x%016llx -> 0x%016llx\n",
+ new_bss_desc->network_tsf, new_tsf_base);
+
+ for (table_idx = 0; table_idx < adapter->num_in_scan_table;
+ table_idx++)
+ adapter->scan_table[table_idx].network_tsf += tsf_delta;
+}
+
+/*
+ * This function appends a WAPI IE.
+ *
+ * This function is called from the network join command preparation routine.
+ *
+ * If the IE buffer has been setup by the application, this routine appends
+ * the buffer as a WAPI TLV type to the request.
+ */
+static int
+mwifiex_cmd_append_wapi_ie(struct mwifiex_private *priv, u8 **buffer)
+{
+ int retLen = 0;
+ struct mwifiex_ie_types_header ie_header;
+
+ /* Null Checks */
+ if (buffer == NULL)
+ return 0;
+ if (*buffer == NULL)
+ return 0;
+
+ /*
+ * If there is a wapi ie buffer setup, append it to the return
+ * parameter buffer pointer.
+ */
+ if (priv->wapi_ie_len) {
+ dev_dbg(priv->adapter->dev, "cmd: append wapi ie %d to %p\n",
+ priv->wapi_ie_len, *buffer);
+
+ /* Wrap the generic IE buffer with a pass through TLV type */
+ ie_header.type = cpu_to_le16(TLV_TYPE_WAPI_IE);
+ ie_header.len = cpu_to_le16(priv->wapi_ie_len);
+ memcpy(*buffer, &ie_header, sizeof(ie_header));
+
+ /* Increment the return size and the return buffer pointer
+ param */
+ *buffer += sizeof(ie_header);
+ retLen += sizeof(ie_header);
+
+ /* Copy the wapi IE buffer to the output buffer, advance
+ pointer */
+ memcpy(*buffer, priv->wapi_ie, priv->wapi_ie_len);
+
+ /* Increment the return size and the return buffer pointer
+ param */
+ *buffer += priv->wapi_ie_len;
+ retLen += priv->wapi_ie_len;
+
+ }
+ /* return the length appended to the buffer */
+ return retLen;
+}
+
+/*
+ * This function appends rsn ie tlv for wpa/wpa2 security modes.
+ * It is called from the network join command preparation routine.
+ */
+static int mwifiex_append_rsn_ie_wpa_wpa2(struct mwifiex_private *priv,
+ u8 **buffer)
+{
+ struct mwifiex_ie_types_rsn_param_set *rsn_ie_tlv;
+ int rsn_ie_len;
+
+ if (!buffer || !(*buffer))
+ return 0;
+
+ rsn_ie_tlv = (struct mwifiex_ie_types_rsn_param_set *) (*buffer);
+ rsn_ie_tlv->header.type = cpu_to_le16((u16) priv->wpa_ie[0]);
+ rsn_ie_tlv->header.type = cpu_to_le16(
+ le16_to_cpu(rsn_ie_tlv->header.type) & 0x00FF);
+ rsn_ie_tlv->header.len = cpu_to_le16((u16) priv->wpa_ie[1]);
+ rsn_ie_tlv->header.len = cpu_to_le16(le16_to_cpu(rsn_ie_tlv->header.len)
+ & 0x00FF);
+ if (le16_to_cpu(rsn_ie_tlv->header.len) <= (sizeof(priv->wpa_ie) - 2))
+ memcpy(rsn_ie_tlv->rsn_ie, &priv->wpa_ie[2],
+ le16_to_cpu(rsn_ie_tlv->header.len));
+ else
+ return -1;
+
+ rsn_ie_len = sizeof(rsn_ie_tlv->header) +
+ le16_to_cpu(rsn_ie_tlv->header.len);
+ *buffer += rsn_ie_len;
+
+ return rsn_ie_len;
+}
+
+/*
+ * This function prepares command for association.
+ *
+ * This sets the following parameters -
+ * - Peer MAC address
+ * - Listen interval
+ * - Beacon interval
+ * - Capability information
+ *
+ * ...and the following TLVs, as required -
+ * - SSID TLV
+ * - PHY TLV
+ * - SS TLV
+ * - Rates TLV
+ * - Authentication TLV
+ * - Channel TLV
+ * - WPA/WPA2 IE
+ * - 11n TLV
+ * - Vendor specific TLV
+ * - WMM TLV
+ * - WAPI IE
+ * - Generic IE
+ * - TSF TLV
+ *
+ * Preparation also includes -
+ * - Setting command ID and proper size
+ * - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ void *data_buf)
+{
+ struct host_cmd_ds_802_11_associate *assoc = &cmd->params.associate;
+ struct mwifiex_bssdescriptor *bss_desc;
+ struct mwifiex_ie_types_ssid_param_set *ssid_tlv;
+ struct mwifiex_ie_types_phy_param_set *phy_tlv;
+ struct mwifiex_ie_types_ss_param_set *ss_tlv;
+ struct mwifiex_ie_types_rates_param_set *rates_tlv;
+ struct mwifiex_ie_types_auth_type *auth_tlv;
+ struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
+ u8 rates[MWIFIEX_SUPPORTED_RATES];
+ u32 rates_size;
+ u16 tmp_cap;
+ u8 *pos;
+ int rsn_ie_len = 0;
+
+ bss_desc = (struct mwifiex_bssdescriptor *) data_buf;
+ pos = (u8 *) assoc;
+
+ mwifiex_cfg_tx_buf(priv, bss_desc);
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11_ASSOCIATE);
+
+ /* Save so we know which BSS Desc to use in the response handler */
+ priv->attempted_bss_desc = bss_desc;
+
+ memcpy(assoc->peer_sta_addr,
+ bss_desc->mac_address, sizeof(assoc->peer_sta_addr));
+ pos += sizeof(assoc->peer_sta_addr);
+
+ /* Set the listen interval */
+ assoc->listen_interval = cpu_to_le16(priv->listen_interval);
+ /* Set the beacon period */
+ assoc->beacon_period = cpu_to_le16(bss_desc->beacon_period);
+
+ pos += sizeof(assoc->cap_info_bitmap);
+ pos += sizeof(assoc->listen_interval);
+ pos += sizeof(assoc->beacon_period);
+ pos += sizeof(assoc->dtim_period);
+
+ ssid_tlv = (struct mwifiex_ie_types_ssid_param_set *) pos;
+ ssid_tlv->header.type = cpu_to_le16(WLAN_EID_SSID);
+ ssid_tlv->header.len = cpu_to_le16((u16) bss_desc->ssid.ssid_len);
+ memcpy(ssid_tlv->ssid, bss_desc->ssid.ssid,
+ le16_to_cpu(ssid_tlv->header.len));
+ pos += sizeof(ssid_tlv->header) + le16_to_cpu(ssid_tlv->header.len);
+
+ phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos;
+ phy_tlv->header.type = cpu_to_le16(WLAN_EID_DS_PARAMS);
+ phy_tlv->header.len = cpu_to_le16(sizeof(phy_tlv->fh_ds.ds_param_set));
+ memcpy(&phy_tlv->fh_ds.ds_param_set,
+ &bss_desc->phy_param_set.ds_param_set.current_chan,
+ sizeof(phy_tlv->fh_ds.ds_param_set));
+ pos += sizeof(phy_tlv->header) + le16_to_cpu(phy_tlv->header.len);
+
+ ss_tlv = (struct mwifiex_ie_types_ss_param_set *) pos;
+ ss_tlv->header.type = cpu_to_le16(WLAN_EID_CF_PARAMS);
+ ss_tlv->header.len = cpu_to_le16(sizeof(ss_tlv->cf_ibss.cf_param_set));
+ pos += sizeof(ss_tlv->header) + le16_to_cpu(ss_tlv->header.len);
+
+ /* Get the common rates supported between the driver and the BSS Desc */
+ if (mwifiex_setup_rates_from_bssdesc
+ (priv, bss_desc, rates, &rates_size))
+ return -1;
+
+ /* Save the data rates into Current BSS state structure */
+ priv->curr_bss_params.num_of_rates = rates_size;
+ memcpy(&priv->curr_bss_params.data_rates, rates, rates_size);
+
+ /* Setup the Rates TLV in the association command */
+ rates_tlv = (struct mwifiex_ie_types_rates_param_set *) pos;
+ rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
+ rates_tlv->header.len = cpu_to_le16((u16) rates_size);
+ memcpy(rates_tlv->rates, rates, rates_size);
+ pos += sizeof(rates_tlv->header) + rates_size;
+ dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: rates size = %d\n",
+ rates_size);
+
+ /* Add the Authentication type to be used for Auth frames */
+ auth_tlv = (struct mwifiex_ie_types_auth_type *) pos;
+ auth_tlv->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
+ auth_tlv->header.len = cpu_to_le16(sizeof(auth_tlv->auth_type));
+ if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED)
+ auth_tlv->auth_type = cpu_to_le16(
+ (u16) priv->sec_info.authentication_mode);
+ else
+ auth_tlv->auth_type = cpu_to_le16(NL80211_AUTHTYPE_OPEN_SYSTEM);
+
+ pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len);
+
+ if (IS_SUPPORT_MULTI_BANDS(priv->adapter)
+ && !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info)
+ && (!bss_desc->disable_11n)
+ && (priv->adapter->config_bands & BAND_GN
+ || priv->adapter->config_bands & BAND_AN)
+ && (bss_desc->bcn_ht_cap)
+ )
+ ) {
+ /* Append a channel TLV for the channel the attempted AP was
+ found on */
+ chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
+ chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
+ chan_tlv->header.len =
+ cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
+
+ memset(chan_tlv->chan_scan_param, 0x00,
+ sizeof(struct mwifiex_chan_scan_param_set));
+ chan_tlv->chan_scan_param[0].chan_number =
+ (bss_desc->phy_param_set.ds_param_set.current_chan);
+ dev_dbg(priv->adapter->dev, "info: Assoc: TLV Chan = %d\n",
+ chan_tlv->chan_scan_param[0].chan_number);
+
+ chan_tlv->chan_scan_param[0].radio_type =
+ mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
+
+ dev_dbg(priv->adapter->dev, "info: Assoc: TLV Band = %d\n",
+ chan_tlv->chan_scan_param[0].radio_type);
+ pos += sizeof(chan_tlv->header) +
+ sizeof(struct mwifiex_chan_scan_param_set);
+ }
+
+ if (!priv->wps.session_enable) {
+ if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
+ rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
+
+ if (rsn_ie_len == -1)
+ return -1;
+ }
+
+ if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info)
+ && (!bss_desc->disable_11n)
+ && (priv->adapter->config_bands & BAND_GN
+ || priv->adapter->config_bands & BAND_AN))
+ mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos);
+
+ /* Append vendor specific IE TLV */
+ mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_ASSOC, &pos);
+
+ mwifiex_wmm_process_association_req(priv, &pos, &bss_desc->wmm_ie,
+ bss_desc->bcn_ht_cap);
+ if (priv->sec_info.wapi_enabled && priv->wapi_ie_len)
+ mwifiex_cmd_append_wapi_ie(priv, &pos);
+
+
+ mwifiex_cmd_append_generic_ie(priv, &pos);
+
+ mwifiex_cmd_append_tsf_tlv(priv, &pos, bss_desc);
+
+ cmd->size = cpu_to_le16((u16) (pos - (u8 *) assoc) + S_DS_GEN);
+
+ /* Set the Capability info at last */
+ tmp_cap = bss_desc->cap_info_bitmap;
+
+ if (priv->adapter->config_bands == BAND_B)
+ tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
+
+ tmp_cap &= CAPINFO_MASK;
+ dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
+ tmp_cap, CAPINFO_MASK);
+ assoc->cap_info_bitmap = cpu_to_le16(tmp_cap);
+
+ return 0;
+}
+
+/*
+ * Association firmware command response handler
+ *
+ * The response buffer for the association command has the following
+ * memory layout.
+ *
+ * For cases where an association response was not received (indicated
+ * by the CapInfo and AId field):
+ *
+ * .------------------------------------------------------------.
+ * | Header(4 * sizeof(t_u16)): Standard command response hdr |
+ * .------------------------------------------------------------.
+ * | cap_info/Error Return(t_u16): |
+ * | 0xFFFF(-1): Internal error |
+ * | 0xFFFE(-2): Authentication unhandled message |
+ * | 0xFFFD(-3): Authentication refused |
+ * | 0xFFFC(-4): Timeout waiting for AP response |
+ * .------------------------------------------------------------.
+ * | status_code(t_u16): |
+ * | If cap_info is -1: |
+ * | An internal firmware failure prevented the |
+ * | command from being processed. The status_code |
+ * | will be set to 1. |
+ * | |
+ * | If cap_info is -2: |
+ * | An authentication frame was received but was |
+ * | not handled by the firmware. IEEE Status |
+ * | code for the failure is returned. |
+ * | |
+ * | If cap_info is -3: |
+ * | An authentication frame was received and the |
+ * | status_code is the IEEE Status reported in the |
+ * | response. |
+ * | |
+ * | If cap_info is -4: |
+ * | (1) Association response timeout |
+ * | (2) Authentication response timeout |
+ * .------------------------------------------------------------.
+ * | a_id(t_u16): 0xFFFF |
+ * .------------------------------------------------------------.
+ *
+ *
+ * For cases where an association response was received, the IEEE
+ * standard association response frame is returned:
+ *
+ * .------------------------------------------------------------.
+ * | Header(4 * sizeof(t_u16)): Standard command response hdr |
+ * .------------------------------------------------------------.
+ * | cap_info(t_u16): IEEE Capability |
+ * .------------------------------------------------------------.
+ * | status_code(t_u16): IEEE Status Code |
+ * .------------------------------------------------------------.
+ * | a_id(t_u16): IEEE Association ID |
+ * .------------------------------------------------------------.
+ * | IEEE IEs(variable): Any received IEs comprising the |
+ * | remaining portion of a received |
+ * | association response frame. |
+ * .------------------------------------------------------------.
+ *
+ * For simplistic handling, the status_code field can be used to determine
+ * an association success (0) or failure (non-zero).
+ */
+int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ int ret = 0;
+ struct ieee_types_assoc_rsp *assoc_rsp;
+ struct mwifiex_bssdescriptor *bss_desc;
+ u8 enable_data = true;
+
+ assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params;
+
+ priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN,
+ sizeof(priv->assoc_rsp_buf));
+
+ memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size);
+
+ if (le16_to_cpu(assoc_rsp->status_code)) {
+ priv->adapter->dbg.num_cmd_assoc_failure++;
+ dev_err(priv->adapter->dev, "ASSOC_RESP: association failed, "
+ "status code = %d, error = 0x%x, a_id = 0x%x\n",
+ le16_to_cpu(assoc_rsp->status_code),
+ le16_to_cpu(assoc_rsp->cap_info_bitmap),
+ le16_to_cpu(assoc_rsp->a_id));
+
+ ret = -1;
+ goto done;
+ }
+
+ /* Send a Media Connected event, according to the Spec */
+ priv->media_connected = true;
+
+ priv->adapter->ps_state = PS_STATE_AWAKE;
+ priv->adapter->pps_uapsd_mode = false;
+ priv->adapter->tx_lock_flag = false;
+
+ /* Set the attempted BSSID Index to current */
+ bss_desc = priv->attempted_bss_desc;
+
+ dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: %s\n",
+ bss_desc->ssid.ssid);
+
+ /* Make a copy of current BSSID descriptor */
+ memcpy(&priv->curr_bss_params.bss_descriptor,
+ bss_desc, sizeof(struct mwifiex_bssdescriptor));
+
+ /* Update curr_bss_params */
+ priv->curr_bss_params.bss_descriptor.channel
+ = bss_desc->phy_param_set.ds_param_set.current_chan;
+
+ priv->curr_bss_params.band = (u8) bss_desc->bss_band;
+
+ /*
+ * Adjust the timestamps in the scan table to be relative to the newly
+ * associated AP's TSF
+ */
+ mwifiex_update_tsf_timestamps(priv, bss_desc);
+
+ if (bss_desc->wmm_ie.vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC)
+ priv->curr_bss_params.wmm_enabled = true;
+ else
+ priv->curr_bss_params.wmm_enabled = false;
+
+ if ((priv->wmm_required || bss_desc->bcn_ht_cap)
+ && priv->curr_bss_params.wmm_enabled)
+ priv->wmm_enabled = true;
+ else
+ priv->wmm_enabled = false;
+
+ priv->curr_bss_params.wmm_uapsd_enabled = false;
+
+ if (priv->wmm_enabled)
+ priv->curr_bss_params.wmm_uapsd_enabled
+ = ((bss_desc->wmm_ie.qos_info_bitmap &
+ IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) ? 1 : 0);
+
+ dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: curr_pkt_filter is %#x\n",
+ priv->curr_pkt_filter);
+ if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
+ priv->wpa_is_gtk_set = false;
+
+ if (priv->wmm_enabled) {
+ /* Don't re-enable carrier until we get the WMM_GET_STATUS
+ event */
+ enable_data = false;
+ } else {
+ /* Since WMM is not enabled, setup the queues with the
+ defaults */
+ mwifiex_wmm_setup_queue_priorities(priv, NULL);
+ mwifiex_wmm_setup_ac_downgrade(priv);
+ }
+
+ if (enable_data)
+ dev_dbg(priv->adapter->dev,
+ "info: post association, re-enabling data flow\n");
+
+ /* Reset SNR/NF/RSSI values */
+ priv->data_rssi_last = 0;
+ priv->data_nf_last = 0;
+ priv->data_rssi_avg = 0;
+ priv->data_nf_avg = 0;
+ priv->bcn_rssi_last = 0;
+ priv->bcn_nf_last = 0;
+ priv->bcn_rssi_avg = 0;
+ priv->bcn_nf_avg = 0;
+ priv->rxpd_rate = 0;
+ priv->rxpd_htinfo = 0;
+
+ mwifiex_save_curr_bcn(priv);
+
+ priv->adapter->dbg.num_cmd_assoc_success++;
+
+ dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: associated\n");
+
+ /* Add the ra_list here for infra mode as there will be only 1 ra
+ always */
+ mwifiex_ralist_add(priv,
+ priv->curr_bss_params.bss_descriptor.mac_address);
+
+ if (!netif_carrier_ok(priv->netdev))
+ netif_carrier_on(priv->netdev);
+ if (netif_queue_stopped(priv->netdev))
+ netif_wake_queue(priv->netdev);
+
+ if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
+ priv->scan_block = true;
+
+done:
+ /* Need to indicate IOCTL complete */
+ if (adapter->curr_cmd->wait_q_enabled) {
+ if (ret)
+ adapter->cmd_wait_q.status = -1;
+ else
+ adapter->cmd_wait_q.status = 0;
+ }
+
+ return ret;
+}
+
+/*
+ * This function prepares command for ad-hoc start.
+ *
+ * Driver will fill up SSID, BSS mode, IBSS parameters, physical
+ * parameters, probe delay, and capability information. Firmware
+ * will fill up beacon period, basic rates and operational rates.
+ *
+ * In addition, the following TLVs are added -
+ * - Channel TLV
+ * - Vendor specific IE
+ * - WPA/WPA2 IE
+ * - HT Capabilities IE
+ * - HT Information IE
+ *
+ * Preparation also includes -
+ * - Setting command ID and proper size
+ * - Ensuring correct endian-ness
+ */
+int
+mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd, void *data_buf)
+{
+ int rsn_ie_len = 0;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct host_cmd_ds_802_11_ad_hoc_start *adhoc_start =
+ &cmd->params.adhoc_start;
+ struct mwifiex_bssdescriptor *bss_desc;
+ u32 cmd_append_size = 0;
+ u32 i;
+ u16 tmp_cap;
+ uint16_t ht_cap_info;
+ struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
+
+ struct mwifiex_ie_types_htcap *ht_cap;
+ struct mwifiex_ie_types_htinfo *ht_info;
+ u8 *pos = (u8 *) adhoc_start +
+ sizeof(struct host_cmd_ds_802_11_ad_hoc_start);
+
+ if (!adapter)
+ return -1;
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_START);
+
+ bss_desc = &priv->curr_bss_params.bss_descriptor;
+ priv->attempted_bss_desc = bss_desc;
+
+ /*
+ * Fill in the parameters for 2 data structures:
+ * 1. struct host_cmd_ds_802_11_ad_hoc_start command
+ * 2. bss_desc
+ * Driver will fill up SSID, bss_mode,IBSS param, Physical Param,
+ * probe delay, and Cap info.
+ * Firmware will fill up beacon period, Basic rates
+ * and operational rates.
+ */
+
+ memset(adhoc_start->ssid, 0, IEEE80211_MAX_SSID_LEN);
+
+ memcpy(adhoc_start->ssid,
+ ((struct mwifiex_802_11_ssid *) data_buf)->ssid,
+ ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len);
+
+ dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n",
+ adhoc_start->ssid);
+
+ memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN);
+ memcpy(bss_desc->ssid.ssid,
+ ((struct mwifiex_802_11_ssid *) data_buf)->ssid,
+ ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len);
+
+ bss_desc->ssid.ssid_len =
+ ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len;
+
+ /* Set the BSS mode */
+ adhoc_start->bss_mode = HostCmd_BSS_MODE_IBSS;
+ bss_desc->bss_mode = NL80211_IFTYPE_ADHOC;
+ adhoc_start->beacon_period = cpu_to_le16(priv->beacon_period);
+ bss_desc->beacon_period = priv->beacon_period;
+
+ /* Set Physical param set */
+/* Parameter IE Id */
+#define DS_PARA_IE_ID 3
+/* Parameter IE length */
+#define DS_PARA_IE_LEN 1
+
+ adhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID;
+ adhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN;
+
+ if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211
+ (priv, adapter->adhoc_start_band, (u16)
+ priv->adhoc_channel)) {
+ struct mwifiex_chan_freq_power *cfp;
+ cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv,
+ adapter->adhoc_start_band, FIRST_VALID_CHANNEL);
+ if (cfp)
+ priv->adhoc_channel = (u8) cfp->channel;
+ }
+
+ if (!priv->adhoc_channel) {
+ dev_err(adapter->dev, "ADHOC_S_CMD: adhoc_channel cannot be 0\n");
+ return -1;
+ }
+
+ dev_dbg(adapter->dev, "info: ADHOC_S_CMD: creating ADHOC on channel %d\n",
+ priv->adhoc_channel);
+
+ priv->curr_bss_params.bss_descriptor.channel = priv->adhoc_channel;
+ priv->curr_bss_params.band = adapter->adhoc_start_band;
+
+ bss_desc->channel = priv->adhoc_channel;
+ adhoc_start->phy_param_set.ds_param_set.current_chan =
+ priv->adhoc_channel;
+
+ memcpy(&bss_desc->phy_param_set, &adhoc_start->phy_param_set,
+ sizeof(union ieee_types_phy_param_set));
+
+ /* Set IBSS param set */
+/* IBSS parameter IE Id */
+#define IBSS_PARA_IE_ID 6
+/* IBSS parameter IE length */
+#define IBSS_PARA_IE_LEN 2
+
+ adhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID;
+ adhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN;
+ adhoc_start->ss_param_set.ibss_param_set.atim_window
+ = cpu_to_le16(priv->atim_window);
+ memcpy(&bss_desc->ss_param_set, &adhoc_start->ss_param_set,
+ sizeof(union ieee_types_ss_param_set));
+
+ /* Set Capability info */
+ bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_IBSS;
+ tmp_cap = le16_to_cpu(adhoc_start->cap_info_bitmap);
+ tmp_cap &= ~WLAN_CAPABILITY_ESS;
+ tmp_cap |= WLAN_CAPABILITY_IBSS;
+
+ /* Set up privacy in bss_desc */
+ if (priv->sec_info.encryption_mode) {
+ /* Ad-Hoc capability privacy on */
+ dev_dbg(adapter->dev,
+ "info: ADHOC_S_CMD: wep_status set privacy to WEP\n");
+ bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
+ tmp_cap |= WLAN_CAPABILITY_PRIVACY;
+ } else {
+ dev_dbg(adapter->dev, "info: ADHOC_S_CMD: wep_status NOT set,"
+ " setting privacy to ACCEPT ALL\n");
+ bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL;
+ }
+
+ memset(adhoc_start->DataRate, 0, sizeof(adhoc_start->DataRate));
+ mwifiex_get_active_data_rates(priv, adhoc_start->DataRate);
+ if ((adapter->adhoc_start_band & BAND_G) &&
+ (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) {
+ if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
+ HostCmd_ACT_GEN_SET, 0,
+ &priv->curr_pkt_filter)) {
+ dev_err(adapter->dev,
+ "ADHOC_S_CMD: G Protection config failed\n");
+ return -1;
+ }
+ }
+ /* Find the last non zero */
+ for (i = 0; i < sizeof(adhoc_start->DataRate) &&
+ adhoc_start->DataRate[i];
+ i++)
+ ;
+
+ priv->curr_bss_params.num_of_rates = i;
+
+ /* Copy the ad-hoc creating rates into Current BSS rate structure */
+ memcpy(&priv->curr_bss_params.data_rates,
+ &adhoc_start->DataRate, priv->curr_bss_params.num_of_rates);
+
+ dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n",
+ adhoc_start->DataRate[0], adhoc_start->DataRate[1],
+ adhoc_start->DataRate[2], adhoc_start->DataRate[3]);
+
+ dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n");
+
+ if (IS_SUPPORT_MULTI_BANDS(adapter)) {
+ /* Append a channel TLV */
+ chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
+ chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
+ chan_tlv->header.len =
+ cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
+
+ memset(chan_tlv->chan_scan_param, 0x00,
+ sizeof(struct mwifiex_chan_scan_param_set));
+ chan_tlv->chan_scan_param[0].chan_number =
+ (u8) priv->curr_bss_params.bss_descriptor.channel;
+
+ dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Chan = %d\n",
+ chan_tlv->chan_scan_param[0].chan_number);
+
+ chan_tlv->chan_scan_param[0].radio_type
+ = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
+ if (adapter->adhoc_start_band & BAND_GN
+ || adapter->adhoc_start_band & BAND_AN) {
+ if (adapter->chan_offset == SEC_CHANNEL_ABOVE)
+ chan_tlv->chan_scan_param[0].radio_type |=
+ SECOND_CHANNEL_ABOVE;
+ else if (adapter->chan_offset == SEC_CHANNEL_BELOW)
+ chan_tlv->chan_scan_param[0].radio_type |=
+ SECOND_CHANNEL_BELOW;
+ }
+ dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Band = %d\n",
+ chan_tlv->chan_scan_param[0].radio_type);
+ pos += sizeof(chan_tlv->header) +
+ sizeof(struct mwifiex_chan_scan_param_set);
+ cmd_append_size +=
+ sizeof(chan_tlv->header) +
+ sizeof(struct mwifiex_chan_scan_param_set);
+ }
+
+ /* Append vendor specific IE TLV */
+ cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
+ MWIFIEX_VSIE_MASK_ADHOC, &pos);
+
+ if (priv->sec_info.wpa_enabled) {
+ rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
+ if (rsn_ie_len == -1)
+ return -1;
+ cmd_append_size += rsn_ie_len;
+ }
+
+ if (adapter->adhoc_11n_enabled) {
+ {
+ ht_cap = (struct mwifiex_ie_types_htcap *) pos;
+ memset(ht_cap, 0,
+ sizeof(struct mwifiex_ie_types_htcap));
+ ht_cap->header.type =
+ cpu_to_le16(WLAN_EID_HT_CAPABILITY);
+ ht_cap->header.len =
+ cpu_to_le16(sizeof(struct ieee80211_ht_cap));
+ ht_cap_info = le16_to_cpu(ht_cap->ht_cap.cap_info);
+
+ ht_cap_info |= IEEE80211_HT_CAP_SGI_20;
+ if (adapter->chan_offset) {
+ ht_cap_info |= IEEE80211_HT_CAP_SGI_40;
+ ht_cap_info |= IEEE80211_HT_CAP_DSSSCCK40;
+ ht_cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask);
+ }
+
+ ht_cap->ht_cap.ampdu_params_info
+ = IEEE80211_HT_MAX_AMPDU_64K;
+ ht_cap->ht_cap.mcs.rx_mask[0] = 0xff;
+ pos += sizeof(struct mwifiex_ie_types_htcap);
+ cmd_append_size +=
+ sizeof(struct mwifiex_ie_types_htcap);
+ }
+ {
+ ht_info = (struct mwifiex_ie_types_htinfo *) pos;
+ memset(ht_info, 0,
+ sizeof(struct mwifiex_ie_types_htinfo));
+ ht_info->header.type =
+ cpu_to_le16(WLAN_EID_HT_INFORMATION);
+ ht_info->header.len =
+ cpu_to_le16(sizeof(struct ieee80211_ht_info));
+ ht_info->ht_info.control_chan =
+ (u8) priv->curr_bss_params.bss_descriptor.
+ channel;
+ if (adapter->chan_offset) {
+ ht_info->ht_info.ht_param =
+ adapter->chan_offset;
+ ht_info->ht_info.ht_param |=
+ IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
+ }
+ ht_info->ht_info.operation_mode =
+ cpu_to_le16(IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+ ht_info->ht_info.basic_set[0] = 0xff;
+ pos += sizeof(struct mwifiex_ie_types_htinfo);
+ cmd_append_size +=
+ sizeof(struct mwifiex_ie_types_htinfo);
+ }
+ }
+
+ cmd->size = cpu_to_le16((u16)
+ (sizeof(struct host_cmd_ds_802_11_ad_hoc_start)
+ + S_DS_GEN + cmd_append_size));
+
+ if (adapter->adhoc_start_band == BAND_B)
+ tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
+ else
+ tmp_cap |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
+
+ adhoc_start->cap_info_bitmap = cpu_to_le16(tmp_cap);
+
+ return 0;
+}
+
+/*
+ * This function prepares command for ad-hoc join.
+ *
+ * Most of the parameters are set up by copying from the target BSS descriptor
+ * from the scan response.
+ *
+ * In addition, the following TLVs are added -
+ * - Channel TLV
+ * - Vendor specific IE
+ * - WPA/WPA2 IE
+ * - 11n IE
+ *
+ * Preparation also includes -
+ * - Setting command ID and proper size
+ * - Ensuring correct endian-ness
+ */
+int
+mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd, void *data_buf)
+{
+ int rsn_ie_len = 0;
+ struct host_cmd_ds_802_11_ad_hoc_join *adhoc_join =
+ &cmd->params.adhoc_join;
+ struct mwifiex_bssdescriptor *bss_desc =
+ (struct mwifiex_bssdescriptor *) data_buf;
+ struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
+ u32 cmd_append_size = 0;
+ u16 tmp_cap;
+ u32 i, rates_size = 0;
+ u16 curr_pkt_filter;
+ u8 *pos =
+ (u8 *) adhoc_join +
+ sizeof(struct host_cmd_ds_802_11_ad_hoc_join);
+
+/* Use G protection */
+#define USE_G_PROTECTION 0x02
+ if (bss_desc->erp_flags & USE_G_PROTECTION) {
+ curr_pkt_filter =
+ priv->
+ curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON;
+
+ if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
+ HostCmd_ACT_GEN_SET, 0,
+ &curr_pkt_filter)) {
+ dev_err(priv->adapter->dev,
+ "ADHOC_J_CMD: G Protection config failed\n");
+ return -1;
+ }
+ }
+
+ priv->attempted_bss_desc = bss_desc;
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_JOIN);
+
+ adhoc_join->bss_descriptor.bss_mode = HostCmd_BSS_MODE_IBSS;
+
+ adhoc_join->bss_descriptor.beacon_period
+ = cpu_to_le16(bss_desc->beacon_period);
+
+ memcpy(&adhoc_join->bss_descriptor.bssid,
+ &bss_desc->mac_address, ETH_ALEN);
+
+ memcpy(&adhoc_join->bss_descriptor.ssid,
+ &bss_desc->ssid.ssid, bss_desc->ssid.ssid_len);
+
+ memcpy(&adhoc_join->bss_descriptor.phy_param_set,
+ &bss_desc->phy_param_set,
+ sizeof(union ieee_types_phy_param_set));
+
+ memcpy(&adhoc_join->bss_descriptor.ss_param_set,
+ &bss_desc->ss_param_set, sizeof(union ieee_types_ss_param_set));
+
+ tmp_cap = bss_desc->cap_info_bitmap;
+
+ tmp_cap &= CAPINFO_MASK;
+
+ dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: tmp_cap=%4X"
+ " CAPINFO_MASK=%4lX\n", tmp_cap, CAPINFO_MASK);
+
+ /* Information on BSSID descriptor passed to FW */
+ dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID = %pM, SSID = %s\n",
+ adhoc_join->bss_descriptor.bssid,
+ adhoc_join->bss_descriptor.ssid);
+
+ for (i = 0; bss_desc->supported_rates[i] &&
+ i < MWIFIEX_SUPPORTED_RATES;
+ i++)
+ ;
+ rates_size = i;
+
+ /* Copy Data Rates from the Rates recorded in scan response */
+ memset(adhoc_join->bss_descriptor.data_rates, 0,
+ sizeof(adhoc_join->bss_descriptor.data_rates));
+ memcpy(adhoc_join->bss_descriptor.data_rates,
+ bss_desc->supported_rates, rates_size);
+
+ /* Copy the adhoc join rates into Current BSS state structure */
+ priv->curr_bss_params.num_of_rates = rates_size;
+ memcpy(&priv->curr_bss_params.data_rates, bss_desc->supported_rates,
+ rates_size);
+
+ /* Copy the channel information */
+ priv->curr_bss_params.bss_descriptor.channel = bss_desc->channel;
+ priv->curr_bss_params.band = (u8) bss_desc->bss_band;
+
+ if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED
+ || priv->sec_info.wpa_enabled)
+ tmp_cap |= WLAN_CAPABILITY_PRIVACY;
+
+ if (IS_SUPPORT_MULTI_BANDS(priv->adapter)) {
+ /* Append a channel TLV */
+ chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
+ chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
+ chan_tlv->header.len =
+ cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
+
+ memset(chan_tlv->chan_scan_param, 0x00,
+ sizeof(struct mwifiex_chan_scan_param_set));
+ chan_tlv->chan_scan_param[0].chan_number =
+ (bss_desc->phy_param_set.ds_param_set.current_chan);
+ dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan = %d\n",
+ chan_tlv->chan_scan_param[0].chan_number);
+
+ chan_tlv->chan_scan_param[0].radio_type =
+ mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
+
+ dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band = %d\n",
+ chan_tlv->chan_scan_param[0].radio_type);
+ pos += sizeof(chan_tlv->header) +
+ sizeof(struct mwifiex_chan_scan_param_set);
+ cmd_append_size += sizeof(chan_tlv->header) +
+ sizeof(struct mwifiex_chan_scan_param_set);
+ }
+
+ if (priv->sec_info.wpa_enabled)
+ rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
+ if (rsn_ie_len == -1)
+ return -1;
+ cmd_append_size += rsn_ie_len;
+
+ if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info))
+ cmd_append_size += mwifiex_cmd_append_11n_tlv(priv,
+ bss_desc, &pos);
+
+ /* Append vendor specific IE TLV */
+ cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
+ MWIFIEX_VSIE_MASK_ADHOC, &pos);
+
+ cmd->size = cpu_to_le16((u16)
+ (sizeof(struct host_cmd_ds_802_11_ad_hoc_join)
+ + S_DS_GEN + cmd_append_size));
+
+ adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap);
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of ad-hoc start and
+ * ad-hoc join.
+ *
+ * The function generates a device-connected event to notify
+ * the applications, in case of successful ad-hoc start/join, and
+ * saves the beacon buffer.
+ */
+int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ int ret = 0;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result;
+ struct mwifiex_bssdescriptor *bss_desc;
+
+ adhoc_result = &resp->params.adhoc_result;
+
+ bss_desc = priv->attempted_bss_desc;
+
+ /* Join result code 0 --> SUCCESS */
+ if (le16_to_cpu(resp->result)) {
+ dev_err(priv->adapter->dev, "ADHOC_RESP: failed\n");
+ if (priv->media_connected)
+ mwifiex_reset_connect_state(priv);
+
+ memset(&priv->curr_bss_params.bss_descriptor,
+ 0x00, sizeof(struct mwifiex_bssdescriptor));
+
+ ret = -1;
+ goto done;
+ }
+
+ /* Send a Media Connected event, according to the Spec */
+ priv->media_connected = true;
+
+ if (le16_to_cpu(resp->command) == HostCmd_CMD_802_11_AD_HOC_START) {
+ dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n",
+ bss_desc->ssid.ssid);
+
+ /* Update the created network descriptor with the new BSSID */
+ memcpy(bss_desc->mac_address,
+ adhoc_result->bssid, ETH_ALEN);
+
+ priv->adhoc_state = ADHOC_STARTED;
+ } else {
+ /*
+ * Now the join cmd should be successful.
+ * If BSSID has changed use SSID to compare instead of BSSID
+ */
+ dev_dbg(priv->adapter->dev, "info: ADHOC_J_RESP %s\n",
+ bss_desc->ssid.ssid);
+
+ /*
+ * Make a copy of current BSSID descriptor, only needed for
+ * join since the current descriptor is already being used
+ * for adhoc start
+ */
+ memcpy(&priv->curr_bss_params.bss_descriptor,
+ bss_desc, sizeof(struct mwifiex_bssdescriptor));
+
+ priv->adhoc_state = ADHOC_JOINED;
+ }
+
+ dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: channel = %d\n",
+ priv->adhoc_channel);
+ dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: BSSID = %pM\n",
+ priv->curr_bss_params.bss_descriptor.mac_address);
+
+ if (!netif_carrier_ok(priv->netdev))
+ netif_carrier_on(priv->netdev);
+ if (netif_queue_stopped(priv->netdev))
+ netif_wake_queue(priv->netdev);
+
+ mwifiex_save_curr_bcn(priv);
+
+done:
+ /* Need to indicate IOCTL complete */
+ if (adapter->curr_cmd->wait_q_enabled) {
+ if (ret)
+ adapter->cmd_wait_q.status = -1;
+ else
+ adapter->cmd_wait_q.status = 0;
+
+ }
+
+ return ret;
+}
+
+/*
+ * This function associates to a specific BSS discovered in a scan.
+ *
+ * It clears any past association response stored for application
+ * retrieval and calls the command preparation routine to send the
+ * command to firmware.
+ */
+int mwifiex_associate(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc)
+{
+ u8 current_bssid[ETH_ALEN];
+
+ /* Return error if the adapter or table entry is not marked as infra */
+ if ((priv->bss_mode != NL80211_IFTYPE_STATION) ||
+ (bss_desc->bss_mode != NL80211_IFTYPE_STATION))
+ return -1;
+
+ memcpy(&current_bssid,
+ &priv->curr_bss_params.bss_descriptor.mac_address,
+ sizeof(current_bssid));
+
+ /* Clear any past association response stored for application
+ retrieval */
+ priv->assoc_rsp_size = 0;
+
+ return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_ASSOCIATE,
+ HostCmd_ACT_GEN_SET, 0, bss_desc);
+}
+
+/*
+ * This function starts an ad-hoc network.
+ *
+ * It calls the command preparation routine to send the command to firmware.
+ */
+int
+mwifiex_adhoc_start(struct mwifiex_private *priv,
+ struct mwifiex_802_11_ssid *adhoc_ssid)
+{
+ dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n",
+ priv->adhoc_channel);
+ dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n",
+ priv->curr_bss_params.bss_descriptor.channel);
+ dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n",
+ priv->curr_bss_params.band);
+
+ return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START,
+ HostCmd_ACT_GEN_SET, 0, adhoc_ssid);
+}
+
+/*
+ * This function joins an ad-hoc network found in a previous scan.
+ *
+ * It calls the command preparation routine to send the command to firmware,
+ * if already not connected to the requested SSID.
+ */
+int mwifiex_adhoc_join(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc)
+{
+ dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n",
+ priv->curr_bss_params.bss_descriptor.ssid.ssid);
+ dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n",
+ priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
+ dev_dbg(priv->adapter->dev, "info: adhoc join: ssid =%s\n",
+ bss_desc->ssid.ssid);
+ dev_dbg(priv->adapter->dev, "info: adhoc join: ssid_len =%u\n",
+ bss_desc->ssid.ssid_len);
+
+ /* Check if the requested SSID is already joined */
+ if (priv->curr_bss_params.bss_descriptor.ssid.ssid_len &&
+ !mwifiex_ssid_cmp(&bss_desc->ssid,
+ &priv->curr_bss_params.bss_descriptor.ssid) &&
+ (priv->curr_bss_params.bss_descriptor.bss_mode ==
+ NL80211_IFTYPE_ADHOC)) {
+ dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: new ad-hoc SSID"
+ " is the same as current; not attempting to re-join\n");
+ return -1;
+ }
+
+ dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n",
+ priv->curr_bss_params.bss_descriptor.channel);
+ dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n",
+ priv->curr_bss_params.band);
+
+ return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN,
+ HostCmd_ACT_GEN_SET, 0, bss_desc);
+}
+
+/*
+ * This function deauthenticates/disconnects from infra network by sending
+ * deauthentication request.
+ */
+static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac)
+{
+ u8 mac_address[ETH_ALEN];
+ int ret;
+ u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+
+ if (mac) {
+ if (!memcmp(mac, zero_mac, sizeof(zero_mac)))
+ memcpy((u8 *) &mac_address,
+ (u8 *) &priv->curr_bss_params.bss_descriptor.
+ mac_address, ETH_ALEN);
+ else
+ memcpy((u8 *) &mac_address, (u8 *) mac, ETH_ALEN);
+ } else {
+ memcpy((u8 *) &mac_address, (u8 *) &priv->curr_bss_params.
+ bss_descriptor.mac_address, ETH_ALEN);
+ }
+
+ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
+ HostCmd_ACT_GEN_SET, 0, &mac_address);
+
+ return ret;
+}
+
+/*
+ * This function deauthenticates/disconnects from a BSS.
+ *
+ * In case of infra made, it sends deauthentication request, and
+ * in case of ad-hoc mode, a stop network request is sent to the firmware.
+ */
+int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
+{
+ int ret = 0;
+
+ if (priv->media_connected) {
+ if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+ ret = mwifiex_deauthenticate_infra(priv, mac);
+ } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
+ ret = mwifiex_send_cmd_sync(priv,
+ HostCmd_CMD_802_11_AD_HOC_STOP,
+ HostCmd_ACT_GEN_SET, 0, NULL);
+ }
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(mwifiex_deauthenticate);
+
+/*
+ * This function converts band to radio type used in channel TLV.
+ */
+u8
+mwifiex_band_to_radio_type(u8 band)
+{
+ switch (band) {
+ case BAND_A:
+ case BAND_AN:
+ case BAND_A | BAND_AN:
+ return HostCmd_SCAN_RADIO_TYPE_A;
+ case BAND_B:
+ case BAND_G:
+ case BAND_B | BAND_G:
+ default:
+ return HostCmd_SCAN_RADIO_TYPE_BG;
+ }
+}
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
new file mode 100644
index 00000000000..f0582259c93
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -0,0 +1,1055 @@
+/*
+ * Marvell Wireless LAN device driver: major functions
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "main.h"
+#include "wmm.h"
+#include "cfg80211.h"
+#include "11n.h"
+
+#define VERSION "1.0"
+
+const char driver_version[] = "mwifiex " VERSION " (%s) ";
+
+struct mwifiex_adapter *g_adapter;
+EXPORT_SYMBOL_GPL(g_adapter);
+
+static struct mwifiex_bss_attr mwifiex_bss_sta[] = {
+ {MWIFIEX_BSS_TYPE_STA, MWIFIEX_DATA_FRAME_TYPE_ETH_II, true, 0, 0},
+};
+
+static int drv_mode = DRV_MODE_STA;
+
+static char fw_name[32] = DEFAULT_FW_NAME;
+
+/* Supported drv_mode table */
+static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = {
+ {
+ .drv_mode = DRV_MODE_STA,
+ .intf_num = ARRAY_SIZE(mwifiex_bss_sta),
+ .bss_attr = mwifiex_bss_sta,
+ },
+};
+
+/*
+ * This function registers the device and performs all the necessary
+ * initializations.
+ *
+ * The following initialization operations are performed -
+ * - Allocate adapter structure
+ * - Save interface specific operations table in adapter
+ * - Call interface specific initialization routine
+ * - Allocate private structures
+ * - Set default adapter structure parameters
+ * - Initialize locks
+ *
+ * In case of any errors during inittialization, this function also ensures
+ * proper cleanup before exiting.
+ */
+static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
+ struct mwifiex_drv_mode *drv_mode_ptr)
+{
+ struct mwifiex_adapter *adapter;
+ int i;
+
+ adapter = kzalloc(sizeof(struct mwifiex_adapter), GFP_KERNEL);
+ if (!adapter)
+ return -ENOMEM;
+
+ g_adapter = adapter;
+ adapter->card = card;
+
+ /* Save interface specific operations in adapter */
+ memmove(&adapter->if_ops, if_ops, sizeof(struct mwifiex_if_ops));
+
+ /* card specific initialization has been deferred until now .. */
+ if (adapter->if_ops.init_if(adapter))
+ goto error;
+
+ adapter->priv_num = 0;
+ for (i = 0; i < drv_mode_ptr->intf_num; i++) {
+ adapter->priv[i] = NULL;
+
+ if (!drv_mode_ptr->bss_attr[i].active)
+ continue;
+
+ /* Allocate memory for private structure */
+ adapter->priv[i] = kzalloc(sizeof(struct mwifiex_private),
+ GFP_KERNEL);
+ if (!adapter->priv[i]) {
+ dev_err(adapter->dev, "%s: failed to alloc priv[%d]\n",
+ __func__, i);
+ goto error;
+ }
+
+ adapter->priv_num++;
+ adapter->priv[i]->adapter = adapter;
+ /* Save bss_type, frame_type & bss_priority */
+ adapter->priv[i]->bss_type = drv_mode_ptr->bss_attr[i].bss_type;
+ adapter->priv[i]->frame_type =
+ drv_mode_ptr->bss_attr[i].frame_type;
+ adapter->priv[i]->bss_priority =
+ drv_mode_ptr->bss_attr[i].bss_priority;
+
+ if (drv_mode_ptr->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_STA)
+ adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_STA;
+ else if (drv_mode_ptr->bss_attr[i].bss_type ==
+ MWIFIEX_BSS_TYPE_UAP)
+ adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_UAP;
+
+ /* Save bss_index & bss_num */
+ adapter->priv[i]->bss_index = i;
+ adapter->priv[i]->bss_num = drv_mode_ptr->bss_attr[i].bss_num;
+ }
+ adapter->drv_mode = drv_mode_ptr;
+
+ if (mwifiex_init_lock_list(adapter))
+ goto error;
+
+ init_timer(&adapter->cmd_timer);
+ adapter->cmd_timer.function = mwifiex_cmd_timeout_func;
+ adapter->cmd_timer.data = (unsigned long) adapter;
+
+ return 0;
+
+error:
+ dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n");
+
+ mwifiex_free_lock_list(adapter);
+ for (i = 0; i < drv_mode_ptr->intf_num; i++)
+ kfree(adapter->priv[i]);
+ kfree(adapter);
+
+ return -1;
+}
+
+/*
+ * This function unregisters the device and performs all the necessary
+ * cleanups.
+ *
+ * The following cleanup operations are performed -
+ * - Free the timers
+ * - Free beacon buffers
+ * - Free private structures
+ * - Free adapter structure
+ */
+static int mwifiex_unregister(struct mwifiex_adapter *adapter)
+{
+ s32 i;
+
+ del_timer(&adapter->cmd_timer);
+
+ /* Free private structures */
+ for (i = 0; i < adapter->priv_num; i++) {
+ if (adapter->priv[i]) {
+ mwifiex_free_curr_bcn(adapter->priv[i]);
+ kfree(adapter->priv[i]);
+ }
+ }
+
+ kfree(adapter);
+ return 0;
+}
+
+/*
+ * The main process.
+ *
+ * This function is the main procedure of the driver and handles various driver
+ * operations. It runs in a loop and provides the core functionalities.
+ *
+ * The main responsibilities of this function are -
+ * - Ensure concurrency control
+ * - Handle pending interrupts and call interrupt handlers
+ * - Wake up the card if required
+ * - Handle command responses and call response handlers
+ * - Handle events and call event handlers
+ * - Execute pending commands
+ * - Transmit pending data packets
+ */
+int mwifiex_main_process(struct mwifiex_adapter *adapter)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->main_proc_lock, flags);
+
+ /* Check if already processing */
+ if (adapter->mwifiex_processing) {
+ spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
+ goto exit_main_proc;
+ } else {
+ adapter->mwifiex_processing = true;
+ spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
+ }
+process_start:
+ do {
+ if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) ||
+ (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
+ break;
+
+ /* Handle pending interrupt if any */
+ if (adapter->int_status) {
+ if (adapter->hs_activated)
+ mwifiex_process_hs_config(adapter);
+ adapter->if_ops.process_int_status(adapter);
+ }
+
+ /* Need to wake up the card ? */
+ if ((adapter->ps_state == PS_STATE_SLEEP) &&
+ (adapter->pm_wakeup_card_req &&
+ !adapter->pm_wakeup_fw_try) &&
+ (is_command_pending(adapter)
+ || !mwifiex_wmm_lists_empty(adapter))) {
+ adapter->pm_wakeup_fw_try = true;
+ adapter->if_ops.wakeup(adapter);
+ continue;
+ }
+ if (IS_CARD_RX_RCVD(adapter)) {
+ adapter->pm_wakeup_fw_try = false;
+ if (adapter->ps_state == PS_STATE_SLEEP)
+ adapter->ps_state = PS_STATE_AWAKE;
+ } else {
+ /* We have tried to wakeup the card already */
+ if (adapter->pm_wakeup_fw_try)
+ break;
+ if (adapter->ps_state != PS_STATE_AWAKE ||
+ adapter->tx_lock_flag)
+ break;
+
+ if (adapter->scan_processing || adapter->data_sent
+ || mwifiex_wmm_lists_empty(adapter)) {
+ if (adapter->cmd_sent || adapter->curr_cmd
+ || (!is_command_pending(adapter)))
+ break;
+ }
+ }
+
+ /* Check for Cmd Resp */
+ if (adapter->cmd_resp_received) {
+ adapter->cmd_resp_received = false;
+ mwifiex_process_cmdresp(adapter);
+
+ /* call mwifiex back when init_fw is done */
+ if (adapter->hw_status == MWIFIEX_HW_STATUS_INIT_DONE) {
+ adapter->hw_status = MWIFIEX_HW_STATUS_READY;
+ mwifiex_init_fw_complete(adapter);
+ }
+ }
+
+ /* Check for event */
+ if (adapter->event_received) {
+ adapter->event_received = false;
+ mwifiex_process_event(adapter);
+ }
+
+ /* Check if we need to confirm Sleep Request
+ received previously */
+ if (adapter->ps_state == PS_STATE_PRE_SLEEP) {
+ if (!adapter->cmd_sent && !adapter->curr_cmd)
+ mwifiex_check_ps_cond(adapter);
+ }
+
+ /* * The ps_state may have been changed during processing of
+ * Sleep Request event.
+ */
+ if ((adapter->ps_state == PS_STATE_SLEEP)
+ || (adapter->ps_state == PS_STATE_PRE_SLEEP)
+ || (adapter->ps_state == PS_STATE_SLEEP_CFM)
+ || adapter->tx_lock_flag)
+ continue;
+
+ if (!adapter->cmd_sent && !adapter->curr_cmd) {
+ if (mwifiex_exec_next_cmd(adapter) == -1) {
+ ret = -1;
+ break;
+ }
+ }
+
+ if (!adapter->scan_processing && !adapter->data_sent &&
+ !mwifiex_wmm_lists_empty(adapter)) {
+ mwifiex_wmm_process_tx(adapter);
+ if (adapter->hs_activated) {
+ adapter->is_hs_configured = false;
+ mwifiex_hs_activated_event
+ (mwifiex_get_priv
+ (adapter, MWIFIEX_BSS_ROLE_ANY),
+ false);
+ }
+ }
+
+ if (adapter->delay_null_pkt && !adapter->cmd_sent &&
+ !adapter->curr_cmd && !is_command_pending(adapter)
+ && mwifiex_wmm_lists_empty(adapter)) {
+ if (!mwifiex_send_null_packet
+ (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
+ MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
+ MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) {
+ adapter->delay_null_pkt = false;
+ adapter->ps_state = PS_STATE_SLEEP;
+ }
+ break;
+ }
+ } while (true);
+
+ if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter))
+ goto process_start;
+
+ spin_lock_irqsave(&adapter->main_proc_lock, flags);
+ adapter->mwifiex_processing = false;
+ spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
+
+exit_main_proc:
+ if (adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING)
+ mwifiex_shutdown_drv(adapter);
+ return ret;
+}
+
+/*
+ * This function initializes the software.
+ *
+ * The main work includes allocating and initializing the adapter structure
+ * and initializing the private structures.
+ */
+static int
+mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops)
+{
+ int i;
+ struct mwifiex_drv_mode *drv_mode_ptr;
+
+ /* find mwifiex_drv_mode entry from mwifiex_drv_mode_tbl */
+ drv_mode_ptr = NULL;
+ for (i = 0; i < ARRAY_SIZE(mwifiex_drv_mode_tbl); i++) {
+ if (mwifiex_drv_mode_tbl[i].drv_mode == drv_mode) {
+ drv_mode_ptr = &mwifiex_drv_mode_tbl[i];
+ break;
+ }
+ }
+
+ if (!drv_mode_ptr) {
+ pr_err("invalid drv_mode=%d\n", drv_mode);
+ return -1;
+ }
+
+ if (mwifiex_register(card, if_ops, drv_mode_ptr))
+ return -1;
+
+ return 0;
+}
+
+/*
+ * This function frees the adapter structure.
+ *
+ * Additionally, this closes the netlink socket, frees the timers
+ * and private structures.
+ */
+static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
+{
+ if (!adapter) {
+ pr_err("%s: adapter is NULL\n", __func__);
+ return;
+ }
+
+ mwifiex_unregister(adapter);
+ pr_debug("info: %s: free adapter\n", __func__);
+}
+
+/*
+ * This function initializes the hardware and firmware.
+ *
+ * The main initialization steps followed are -
+ * - Download the correct firmware to card
+ * - Allocate and initialize the adapter structure
+ * - Initialize the private structures
+ * - Issue the init commands to firmware
+ */
+static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
+{
+ int ret, err;
+ struct mwifiex_fw_image fw;
+
+ memset(&fw, 0, sizeof(struct mwifiex_fw_image));
+
+ switch (adapter->revision_id) {
+ case SD8787_W0:
+ case SD8787_W1:
+ strcpy(fw_name, SD8787_W1_FW_NAME);
+ break;
+ case SD8787_A0:
+ case SD8787_A1:
+ strcpy(fw_name, SD8787_AX_FW_NAME);
+ break;
+ default:
+ break;
+ }
+
+ err = request_firmware(&adapter->firmware, fw_name, adapter->dev);
+ if (err < 0) {
+ dev_err(adapter->dev, "request_firmware() returned"
+ " error code %#x\n", err);
+ ret = -1;
+ goto done;
+ }
+ fw.fw_buf = (u8 *) adapter->firmware->data;
+ fw.fw_len = adapter->firmware->size;
+
+ ret = mwifiex_dnld_fw(adapter, &fw);
+ if (ret == -1)
+ goto done;
+
+ dev_notice(adapter->dev, "WLAN FW is active\n");
+
+ adapter->init_wait_q_woken = false;
+ ret = mwifiex_init_fw(adapter);
+ if (ret == -1) {
+ goto done;
+ } else if (!ret) {
+ adapter->hw_status = MWIFIEX_HW_STATUS_READY;
+ goto done;
+ }
+ /* Wait for mwifiex_init to complete */
+ wait_event_interruptible(adapter->init_wait_q,
+ adapter->init_wait_q_woken);
+ if (adapter->hw_status != MWIFIEX_HW_STATUS_READY) {
+ ret = -1;
+ goto done;
+ }
+ ret = 0;
+
+done:
+ if (adapter->firmware)
+ release_firmware(adapter->firmware);
+ if (ret)
+ ret = -1;
+ return ret;
+}
+
+/*
+ * This function fills a driver buffer.
+ *
+ * The function associates a given SKB with the provided driver buffer
+ * and also updates some of the SKB parameters, including IP header,
+ * priority and timestamp.
+ */
+static void
+mwifiex_fill_buffer(struct sk_buff *skb)
+{
+ struct ethhdr *eth;
+ struct iphdr *iph;
+ struct timeval tv;
+ u8 tid = 0;
+
+ eth = (struct ethhdr *) skb->data;
+ switch (eth->h_proto) {
+ case __constant_htons(ETH_P_IP):
+ iph = ip_hdr(skb);
+ tid = IPTOS_PREC(iph->tos);
+ pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n",
+ eth->h_proto, tid, skb->priority);
+ break;
+ case __constant_htons(ETH_P_ARP):
+ pr_debug("data: ARP packet: %04x\n", eth->h_proto);
+ default:
+ break;
+ }
+/* Offset for TOS field in the IP header */
+#define IPTOS_OFFSET 5
+ tid = (tid >> IPTOS_OFFSET);
+ skb->priority = tid;
+ /* Record the current time the packet was queued; used to
+ determine the amount of time the packet was queued in
+ the driver before it was sent to the firmware.
+ The delay is then sent along with the packet to the
+ firmware for aggregate delay calculation for stats and
+ MSDU lifetime expiry.
+ */
+ do_gettimeofday(&tv);
+ skb->tstamp = timeval_to_ktime(tv);
+}
+
+/*
+ * CFG802.11 network device handler for open.
+ *
+ * Starts the data queue.
+ */
+static int
+mwifiex_open(struct net_device *dev)
+{
+ netif_start_queue(dev);
+ return 0;
+}
+
+/*
+ * CFG802.11 network device handler for close.
+ */
+static int
+mwifiex_close(struct net_device *dev)
+{
+ return 0;
+}
+
+/*
+ * CFG802.11 network device handler for data transmission.
+ */
+static int
+mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+ struct sk_buff *new_skb;
+ struct mwifiex_txinfo *tx_info;
+
+ dev_dbg(priv->adapter->dev, "data: %lu BSS(%d): Data <= kernel\n",
+ jiffies, priv->bss_index);
+
+ if (priv->adapter->surprise_removed) {
+ kfree_skb(skb);
+ priv->stats.tx_dropped++;
+ return 0;
+ }
+ if (!skb->len || (skb->len > ETH_FRAME_LEN)) {
+ dev_err(priv->adapter->dev, "Tx: bad skb len %d\n", skb->len);
+ kfree_skb(skb);
+ priv->stats.tx_dropped++;
+ return 0;
+ }
+ if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) {
+ dev_dbg(priv->adapter->dev,
+ "data: Tx: insufficient skb headroom %d\n",
+ skb_headroom(skb));
+ /* Insufficient skb headroom - allocate a new skb */
+ new_skb =
+ skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
+ if (unlikely(!new_skb)) {
+ dev_err(priv->adapter->dev, "Tx: cannot alloca new_skb\n");
+ kfree_skb(skb);
+ priv->stats.tx_dropped++;
+ return 0;
+ }
+ kfree_skb(skb);
+ skb = new_skb;
+ dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n",
+ skb_headroom(skb));
+ }
+
+ tx_info = MWIFIEX_SKB_TXCB(skb);
+ tx_info->bss_index = priv->bss_index;
+ mwifiex_fill_buffer(skb);
+
+ mwifiex_wmm_add_buf_txqueue(priv->adapter, skb);
+ atomic_inc(&priv->adapter->tx_pending);
+
+ if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
+ netif_stop_queue(priv->netdev);
+ dev->trans_start = jiffies;
+ }
+
+ queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
+
+ return 0;
+}
+
+/*
+ * CFG802.11 network device handler for setting MAC address.
+ */
+static int
+mwifiex_set_mac_address(struct net_device *dev, void *addr)
+{
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+ struct sockaddr *hw_addr = (struct sockaddr *) addr;
+ int ret;
+
+ memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
+
+ /* Send request to firmware */
+ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
+ HostCmd_ACT_GEN_SET, 0, NULL);
+
+ if (!ret)
+ memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
+ else
+ dev_err(priv->adapter->dev, "set mac address failed: ret=%d"
+ "\n", ret);
+
+ memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
+
+ return ret;
+}
+
+/*
+ * CFG802.11 network device handler for setting multicast list.
+ */
+static void mwifiex_set_multicast_list(struct net_device *dev)
+{
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+ struct mwifiex_multicast_list mcast_list;
+
+ if (dev->flags & IFF_PROMISC) {
+ mcast_list.mode = MWIFIEX_PROMISC_MODE;
+ } else if (dev->flags & IFF_ALLMULTI ||
+ netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) {
+ mcast_list.mode = MWIFIEX_ALL_MULTI_MODE;
+ } else {
+ mcast_list.mode = MWIFIEX_MULTICAST_MODE;
+ if (netdev_mc_count(dev))
+ mcast_list.num_multicast_addr =
+ mwifiex_copy_mcast_addr(&mcast_list, dev);
+ }
+ mwifiex_request_set_multicast_list(priv, &mcast_list);
+}
+
+/*
+ * CFG802.11 network device handler for transmission timeout.
+ */
+static void
+mwifiex_tx_timeout(struct net_device *dev)
+{
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+
+ dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_index=%d\n",
+ jiffies, priv->bss_index);
+ dev->trans_start = jiffies;
+ priv->num_tx_timeout++;
+}
+
+/*
+ * CFG802.11 network device handler for statistics retrieval.
+ */
+static struct net_device_stats *mwifiex_get_stats(struct net_device *dev)
+{
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+
+ return &priv->stats;
+}
+
+/* Network device handlers */
+static const struct net_device_ops mwifiex_netdev_ops = {
+ .ndo_open = mwifiex_open,
+ .ndo_stop = mwifiex_close,
+ .ndo_start_xmit = mwifiex_hard_start_xmit,
+ .ndo_set_mac_address = mwifiex_set_mac_address,
+ .ndo_tx_timeout = mwifiex_tx_timeout,
+ .ndo_get_stats = mwifiex_get_stats,
+ .ndo_set_multicast_list = mwifiex_set_multicast_list,
+};
+
+/*
+ * This function initializes the private structure parameters.
+ *
+ * The following wait queues are initialized -
+ * - IOCTL wait queue
+ * - Command wait queue
+ * - Statistics wait queue
+ *
+ * ...and the following default parameters are set -
+ * - Current key index : Set to 0
+ * - Rate index : Set to auto
+ * - Media connected : Set to disconnected
+ * - Adhoc link sensed : Set to false
+ * - Nick name : Set to null
+ * - Number of Tx timeout : Set to 0
+ * - Device address : Set to current address
+ *
+ * In addition, the CFG80211 work queue is also created.
+ */
+static void
+mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev)
+{
+ dev->netdev_ops = &mwifiex_netdev_ops;
+ /* Initialize private structure */
+ priv->current_key_index = 0;
+ priv->media_connected = false;
+ memset(&priv->nick_name, 0, sizeof(priv->nick_name));
+ priv->num_tx_timeout = 0;
+ priv->workqueue = create_singlethread_workqueue("cfg80211_wq");
+ INIT_WORK(&priv->cfg_workqueue, mwifiex_cfg80211_results);
+ memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
+}
+
+/*
+ * This function adds a new logical interface.
+ *
+ * It allocates, initializes and registers the interface by performing
+ * the following opearations -
+ * - Allocate a new net device structure
+ * - Assign device name
+ * - Register the new device with CFG80211 subsystem
+ * - Initialize semaphore and private structure
+ * - Register the new device with kernel
+ * - Create the complete debug FS structure if configured
+ */
+static struct mwifiex_private *mwifiex_add_interface(
+ struct mwifiex_adapter *adapter,
+ u8 bss_index, u8 bss_type)
+{
+ struct net_device *dev;
+ struct mwifiex_private *priv;
+ void *mdev_priv;
+
+ dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), "mlan%d",
+ ether_setup, 1);
+ if (!dev) {
+ dev_err(adapter->dev, "no memory available for netdevice\n");
+ goto error;
+ }
+
+ if (mwifiex_register_cfg80211(dev, adapter->priv[bss_index]->curr_addr,
+ adapter->priv[bss_index]) != 0) {
+ dev_err(adapter->dev, "cannot register netdevice with cfg80211\n");
+ goto error;
+ }
+ /* Save the priv pointer in netdev */
+ priv = adapter->priv[bss_index];
+ mdev_priv = netdev_priv(dev);
+ *((unsigned long *) mdev_priv) = (unsigned long) priv;
+
+ priv->netdev = dev;
+
+ sema_init(&priv->async_sem, 1);
+ priv->scan_pending_on_block = false;
+
+ mwifiex_init_priv_params(priv, dev);
+
+ SET_NETDEV_DEV(dev, adapter->dev);
+
+ /* Register network device */
+ if (register_netdev(dev)) {
+ dev_err(adapter->dev, "cannot register virtual network device\n");
+ goto error;
+ }
+
+ dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name);
+#ifdef CONFIG_DEBUG_FS
+ mwifiex_dev_debugfs_init(priv);
+#endif
+ return priv;
+error:
+ if (dev)
+ free_netdev(dev);
+ return NULL;
+}
+
+/*
+ * This function removes a logical interface.
+ *
+ * It deregisters, resets and frees the interface by performing
+ * the following operations -
+ * - Disconnect the device if connected, send wireless event to
+ * notify applications.
+ * - Remove the debug FS structure if configured
+ * - Unregister the device from kernel
+ * - Free the net device structure
+ * - Cancel all works and destroy work queue
+ * - Unregister and free the wireless device from CFG80211 subsystem
+ */
+static void
+mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index)
+{
+ struct net_device *dev;
+ struct mwifiex_private *priv = adapter->priv[bss_index];
+
+ if (!priv)
+ return;
+ dev = priv->netdev;
+
+ if (priv->media_connected)
+ priv->media_connected = false;
+
+#ifdef CONFIG_DEBUG_FS
+ mwifiex_dev_debugfs_remove(priv);
+#endif
+ /* Last reference is our one */
+ dev_dbg(adapter->dev, "info: %s: refcnt = %d\n",
+ dev->name, netdev_refcnt_read(dev));
+
+ if (dev->reg_state == NETREG_REGISTERED)
+ unregister_netdev(dev);
+
+ /* Clear the priv in adapter */
+ priv->netdev = NULL;
+ if (dev)
+ free_netdev(dev);
+
+ cancel_work_sync(&priv->cfg_workqueue);
+ flush_workqueue(priv->workqueue);
+ destroy_workqueue(priv->workqueue);
+ wiphy_unregister(priv->wdev->wiphy);
+ wiphy_free(priv->wdev->wiphy);
+ kfree(priv->wdev);
+}
+
+/*
+ * This function check if command is pending.
+ */
+int is_command_pending(struct mwifiex_adapter *adapter)
+{
+ unsigned long flags;
+ int is_cmd_pend_q_empty;
+
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+ is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
+ return !is_cmd_pend_q_empty;
+}
+
+/*
+ * This function returns the correct private structure pointer based
+ * upon the BSS number.
+ */
+struct mwifiex_private *
+mwifiex_bss_index_to_priv(struct mwifiex_adapter *adapter, u8 bss_index)
+{
+ if (!adapter || (bss_index >= adapter->priv_num))
+ return NULL;
+ return adapter->priv[bss_index];
+}
+
+/*
+ * This is the main work queue function.
+ *
+ * It handles the main process, which in turn handles the complete
+ * driver operations.
+ */
+static void mwifiex_main_work_queue(struct work_struct *work)
+{
+ struct mwifiex_adapter *adapter =
+ container_of(work, struct mwifiex_adapter, main_work);
+
+ if (adapter->surprise_removed)
+ return;
+ mwifiex_main_process(adapter);
+}
+
+/*
+ * This function cancels all works in the queue and destroys
+ * the main workqueue.
+ */
+static void
+mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
+{
+ flush_workqueue(adapter->workqueue);
+ destroy_workqueue(adapter->workqueue);
+ adapter->workqueue = NULL;
+}
+
+/*
+ * This function adds the card.
+ *
+ * This function follows the following major steps to set up the device -
+ * - Initialize software. This includes probing the card, registering
+ * the interface operations table, and allocating/initializing the
+ * adapter structure
+ * - Set up the netlink socket
+ * - Create and start the main work queue
+ * - Register the device
+ * - Initialize firmware and hardware
+ * - Add logical interfaces
+ */
+int
+mwifiex_add_card(void *card, struct semaphore *sem,
+ struct mwifiex_if_ops *if_ops)
+{
+ int i;
+ struct mwifiex_adapter *adapter;
+
+ if (down_interruptible(sem))
+ goto exit_sem_err;
+
+ if (mwifiex_init_sw(card, if_ops)) {
+ pr_err("%s: software init failed\n", __func__);
+ goto err_init_sw;
+ }
+
+ adapter = g_adapter;
+
+ adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
+ adapter->surprise_removed = false;
+ init_waitqueue_head(&adapter->init_wait_q);
+ adapter->is_suspended = false;
+ adapter->hs_activated = false;
+ init_waitqueue_head(&adapter->hs_activate_wait_q);
+ adapter->cmd_wait_q_required = false;
+ init_waitqueue_head(&adapter->cmd_wait_q.wait);
+ adapter->cmd_wait_q.condition = false;
+ adapter->cmd_wait_q.status = 0;
+
+ adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE");
+ if (!adapter->workqueue)
+ goto err_kmalloc;
+
+ INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
+
+ /* Register the device. Fill up the private data structure with relevant
+ information from the card and request for the required IRQ. */
+ if (adapter->if_ops.register_dev(adapter)) {
+ pr_err("%s: failed to register mwifiex device\n", __func__);
+ goto err_registerdev;
+ }
+
+ if (mwifiex_init_hw_fw(adapter)) {
+ pr_err("%s: firmware init failed\n", __func__);
+ goto err_init_fw;
+ }
+
+ /* Add interfaces */
+ for (i = 0; i < adapter->drv_mode->intf_num; i++) {
+ if (!mwifiex_add_interface(adapter, i,
+ adapter->drv_mode->bss_attr[i].bss_type)) {
+ goto err_add_intf;
+ }
+ }
+
+ up(sem);
+
+ return 0;
+
+err_add_intf:
+ for (i = 0; i < adapter->priv_num; i++)
+ mwifiex_remove_interface(adapter, i);
+err_init_fw:
+ pr_debug("info: %s: unregister device\n", __func__);
+ adapter->if_ops.unregister_dev(adapter);
+err_registerdev:
+ adapter->surprise_removed = true;
+ mwifiex_terminate_workqueue(adapter);
+err_kmalloc:
+ if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
+ (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
+ pr_debug("info: %s: shutdown mwifiex\n", __func__);
+ adapter->init_wait_q_woken = false;
+
+ if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
+ wait_event_interruptible(adapter->init_wait_q,
+ adapter->init_wait_q_woken);
+ }
+
+ mwifiex_free_adapter(adapter);
+
+err_init_sw:
+ up(sem);
+
+exit_sem_err:
+ return -1;
+}
+EXPORT_SYMBOL_GPL(mwifiex_add_card);
+
+/*
+ * This function removes the card.
+ *
+ * This function follows the following major steps to remove the device -
+ * - Stop data traffic
+ * - Shutdown firmware
+ * - Remove the logical interfaces
+ * - Terminate the work queue
+ * - Unregister the device
+ * - Free the adapter structure
+ */
+int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
+{
+ struct mwifiex_private *priv = NULL;
+ int i;
+
+ if (down_interruptible(sem))
+ goto exit_sem_err;
+
+ if (!adapter)
+ goto exit_remove;
+
+ adapter->surprise_removed = true;
+
+ /* Stop data */
+ for (i = 0; i < adapter->priv_num; i++) {
+ priv = adapter->priv[i];
+ if (priv) {
+ if (!netif_queue_stopped(priv->netdev))
+ netif_stop_queue(priv->netdev);
+ if (netif_carrier_ok(priv->netdev))
+ netif_carrier_off(priv->netdev);
+ }
+ }
+
+ dev_dbg(adapter->dev, "cmd: calling mwifiex_shutdown_drv...\n");
+ adapter->init_wait_q_woken = false;
+
+ if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
+ wait_event_interruptible(adapter->init_wait_q,
+ adapter->init_wait_q_woken);
+ dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n");
+ if (atomic_read(&adapter->rx_pending) ||
+ atomic_read(&adapter->tx_pending) ||
+ atomic_read(&adapter->cmd_pending)) {
+ dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, "
+ "cmd_pending=%d\n",
+ atomic_read(&adapter->rx_pending),
+ atomic_read(&adapter->tx_pending),
+ atomic_read(&adapter->cmd_pending));
+ }
+
+ /* Remove interface */
+ for (i = 0; i < adapter->priv_num; i++)
+ mwifiex_remove_interface(adapter, i);
+
+ mwifiex_terminate_workqueue(adapter);
+
+ /* Unregister device */
+ dev_dbg(adapter->dev, "info: unregister device\n");
+ adapter->if_ops.unregister_dev(adapter);
+ /* Free adapter structure */
+ dev_dbg(adapter->dev, "info: free adapter\n");
+ mwifiex_free_adapter(adapter);
+
+exit_remove:
+ up(sem);
+exit_sem_err:
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mwifiex_remove_card);
+
+/*
+ * This function initializes the module.
+ *
+ * The debug FS is also initialized if configured.
+ */
+static int
+mwifiex_init_module(void)
+{
+#ifdef CONFIG_DEBUG_FS
+ mwifiex_debugfs_init();
+#endif
+ return 0;
+}
+
+/*
+ * This function cleans up the module.
+ *
+ * The debug FS is removed if available.
+ */
+static void
+mwifiex_cleanup_module(void)
+{
+#ifdef CONFIG_DEBUG_FS
+ mwifiex_debugfs_remove();
+#endif
+}
+
+module_init(mwifiex_init_module);
+module_exit(mwifiex_cleanup_module);
+
+MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_DESCRIPTION("Marvell WiFi-Ex Driver version " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
new file mode 100644
index 00000000000..672701dc272
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -0,0 +1,1004 @@
+/*
+ * Marvell Wireless LAN device driver: major data structures and prototypes
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_MAIN_H_
+#define _MWIFIEX_MAIN_H_
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+#include <linux/ip.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <net/sock.h>
+#include <net/lib80211.h>
+#include <linux/firmware.h>
+#include <linux/ctype.h>
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+
+extern const char driver_version[];
+extern struct mwifiex_adapter *g_adapter;
+
+enum {
+ MWIFIEX_ASYNC_CMD,
+ MWIFIEX_SYNC_CMD
+};
+
+#define DRV_MODE_STA 0x1
+
+#define SD8787_W0 0x30
+#define SD8787_W1 0x31
+#define SD8787_A0 0x40
+#define SD8787_A1 0x41
+
+#define DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin"
+#define SD8787_W1_FW_NAME "mrvl/sd8787_uapsta_w1.bin"
+#define SD8787_AX_FW_NAME "mrvl/sd8787_uapsta.bin"
+
+struct mwifiex_drv_mode {
+ u16 drv_mode;
+ u16 intf_num;
+ struct mwifiex_bss_attr *bss_attr;
+};
+
+
+#define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ)
+
+#define MWIFIEX_TIMER_10S 10000
+#define MWIFIEX_TIMER_1S 1000
+
+#define MAX_TX_PENDING 60
+
+#define MWIFIEX_UPLD_SIZE (2312)
+
+#define MAX_EVENT_SIZE 1024
+
+#define ARP_FILTER_MAX_BUF_SIZE 68
+
+#define MWIFIEX_KEY_BUFFER_SIZE 16
+#define MWIFIEX_DEFAULT_LISTEN_INTERVAL 10
+#define MWIFIEX_MAX_REGION_CODE 7
+
+#define DEFAULT_BCN_AVG_FACTOR 8
+#define DEFAULT_DATA_AVG_FACTOR 8
+
+#define FIRST_VALID_CHANNEL 0xff
+#define DEFAULT_AD_HOC_CHANNEL 6
+#define DEFAULT_AD_HOC_CHANNEL_A 36
+
+#define DEFAULT_BCN_MISS_TIMEOUT 5
+
+#define MAX_SCAN_BEACON_BUFFER 8000
+
+#define SCAN_BEACON_ENTRY_PAD 6
+
+#define MWIFIEX_PASSIVE_SCAN_CHAN_TIME 200
+#define MWIFIEX_ACTIVE_SCAN_CHAN_TIME 200
+#define MWIFIEX_SPECIFIC_SCAN_CHAN_TIME 110
+
+#define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI)))
+
+#define MWIFIEX_MAX_TOTAL_SCAN_TIME (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S)
+
+#define RSN_GTK_OUI_OFFSET 2
+
+#define MWIFIEX_OUI_NOT_PRESENT 0
+#define MWIFIEX_OUI_PRESENT 1
+
+#define IS_CARD_RX_RCVD(adapter) (adapter->cmd_resp_received || \
+ adapter->event_received || \
+ adapter->data_received)
+
+#define MWIFIEX_TYPE_CMD 1
+#define MWIFIEX_TYPE_DATA 0
+#define MWIFIEX_TYPE_EVENT 3
+
+#define DBG_CMD_NUM 5
+
+#define MAX_BITMAP_RATES_SIZE 10
+
+#define MAX_CHANNEL_BAND_BG 14
+
+#define MAX_FREQUENCY_BAND_BG 2484
+
+struct mwifiex_dbg {
+ u32 num_cmd_host_to_card_failure;
+ u32 num_cmd_sleep_cfm_host_to_card_failure;
+ u32 num_tx_host_to_card_failure;
+ u32 num_event_deauth;
+ u32 num_event_disassoc;
+ u32 num_event_link_lost;
+ u32 num_cmd_deauth;
+ u32 num_cmd_assoc_success;
+ u32 num_cmd_assoc_failure;
+ u32 num_tx_timeout;
+ u32 num_cmd_timeout;
+ u16 timeout_cmd_id;
+ u16 timeout_cmd_act;
+ u16 last_cmd_id[DBG_CMD_NUM];
+ u16 last_cmd_act[DBG_CMD_NUM];
+ u16 last_cmd_index;
+ u16 last_cmd_resp_id[DBG_CMD_NUM];
+ u16 last_cmd_resp_index;
+ u16 last_event[DBG_CMD_NUM];
+ u16 last_event_index;
+};
+
+enum MWIFIEX_HARDWARE_STATUS {
+ MWIFIEX_HW_STATUS_READY,
+ MWIFIEX_HW_STATUS_INITIALIZING,
+ MWIFIEX_HW_STATUS_FW_READY,
+ MWIFIEX_HW_STATUS_INIT_DONE,
+ MWIFIEX_HW_STATUS_RESET,
+ MWIFIEX_HW_STATUS_CLOSING,
+ MWIFIEX_HW_STATUS_NOT_READY
+};
+
+enum MWIFIEX_802_11_POWER_MODE {
+ MWIFIEX_802_11_POWER_MODE_CAM,
+ MWIFIEX_802_11_POWER_MODE_PSP
+};
+
+struct mwifiex_tx_param {
+ u32 next_pkt_len;
+};
+
+enum MWIFIEX_PS_STATE {
+ PS_STATE_AWAKE,
+ PS_STATE_PRE_SLEEP,
+ PS_STATE_SLEEP_CFM,
+ PS_STATE_SLEEP
+};
+
+struct mwifiex_add_ba_param {
+ u32 tx_win_size;
+ u32 rx_win_size;
+ u32 timeout;
+};
+
+struct mwifiex_tx_aggr {
+ u8 ampdu_user;
+ u8 ampdu_ap;
+ u8 amsdu;
+};
+
+struct mwifiex_ra_list_tbl {
+ struct list_head list;
+ struct sk_buff_head skb_head;
+ u8 ra[ETH_ALEN];
+ u32 total_pkts_size;
+ u32 is_11n_enabled;
+};
+
+struct mwifiex_tid_tbl {
+ struct list_head ra_list;
+ /* spin lock for tid table */
+ spinlock_t tid_tbl_lock;
+ struct mwifiex_ra_list_tbl *ra_list_curr;
+};
+
+#define WMM_HIGHEST_PRIORITY 7
+#define HIGH_PRIO_TID 7
+#define LOW_PRIO_TID 0
+
+struct mwifiex_wmm_desc {
+ struct mwifiex_tid_tbl tid_tbl_ptr[MAX_NUM_TID];
+ u32 packets_out[MAX_NUM_TID];
+ /* spin lock to protect ra_list */
+ spinlock_t ra_list_spinlock;
+ struct mwifiex_wmm_ac_status ac_status[IEEE80211_MAX_QUEUES];
+ enum mwifiex_wmm_ac_e ac_down_graded_vals[IEEE80211_MAX_QUEUES];
+ u32 drv_pkt_delay_max;
+ u8 queue_priority[IEEE80211_MAX_QUEUES];
+ u32 user_pri_pkt_tx_ctrl[WMM_HIGHEST_PRIORITY + 1]; /* UP: 0 to 7 */
+
+};
+
+struct mwifiex_802_11_security {
+ u8 wpa_enabled;
+ u8 wpa2_enabled;
+ u8 wapi_enabled;
+ u8 wapi_key_on;
+ enum MWIFIEX_802_11_WEP_STATUS wep_status;
+ u32 authentication_mode;
+ u32 encryption_mode;
+};
+
+struct ieee_types_header {
+ u8 element_id;
+ u8 len;
+} __packed;
+
+struct ieee_obss_scan_param {
+ u16 obss_scan_passive_dwell;
+ u16 obss_scan_active_dwell;
+ u16 bss_chan_width_trigger_scan_int;
+ u16 obss_scan_passive_total;
+ u16 obss_scan_active_total;
+ u16 bss_width_chan_trans_delay;
+ u16 obss_scan_active_threshold;
+} __packed;
+
+struct ieee_types_obss_scan_param {
+ struct ieee_types_header ieee_hdr;
+ struct ieee_obss_scan_param obss_scan;
+} __packed;
+
+#define MWIFIEX_SUPPORTED_RATES 14
+
+#define MWIFIEX_SUPPORTED_RATES_EXT 32
+
+#define IEEE_MAX_IE_SIZE 256
+
+struct ieee_types_vendor_specific {
+ struct ieee_types_vendor_header vend_hdr;
+ u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_vendor_header)];
+} __packed;
+
+struct ieee_types_generic {
+ struct ieee_types_header ieee_hdr;
+ u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_header)];
+} __packed;
+
+struct mwifiex_bssdescriptor {
+ u8 mac_address[ETH_ALEN];
+ struct mwifiex_802_11_ssid ssid;
+ u32 privacy;
+ s32 rssi;
+ u32 channel;
+ u32 freq;
+ u16 beacon_period;
+ u8 erp_flags;
+ u32 bss_mode;
+ u8 supported_rates[MWIFIEX_SUPPORTED_RATES];
+ u8 data_rates[MWIFIEX_SUPPORTED_RATES];
+ /* Network band.
+ * BAND_B(0x01): 'b' band
+ * BAND_G(0x02): 'g' band
+ * BAND_A(0X04): 'a' band
+ */
+ u16 bss_band;
+ u64 network_tsf;
+ u8 time_stamp[8];
+ union ieee_types_phy_param_set phy_param_set;
+ union ieee_types_ss_param_set ss_param_set;
+ u16 cap_info_bitmap;
+ struct ieee_types_wmm_parameter wmm_ie;
+ u8 disable_11n;
+ struct ieee80211_ht_cap *bcn_ht_cap;
+ u16 ht_cap_offset;
+ struct ieee80211_ht_info *bcn_ht_info;
+ u16 ht_info_offset;
+ u8 *bcn_bss_co_2040;
+ u16 bss_co_2040_offset;
+ u8 *bcn_ext_cap;
+ u16 ext_cap_offset;
+ struct ieee_types_obss_scan_param *bcn_obss_scan;
+ u16 overlap_bss_offset;
+ struct ieee_types_vendor_specific *bcn_wpa_ie;
+ u16 wpa_offset;
+ struct ieee_types_generic *bcn_rsn_ie;
+ u16 rsn_offset;
+ struct ieee_types_generic *bcn_wapi_ie;
+ u16 wapi_offset;
+ u8 *beacon_buf;
+ u32 beacon_buf_size;
+ u32 beacon_buf_size_max;
+
+};
+
+struct mwifiex_current_bss_params {
+ struct mwifiex_bssdescriptor bss_descriptor;
+ u8 wmm_enabled;
+ u8 wmm_uapsd_enabled;
+ u8 band;
+ u32 num_of_rates;
+ u8 data_rates[MWIFIEX_SUPPORTED_RATES];
+};
+
+struct mwifiex_sleep_params {
+ u16 sp_error;
+ u16 sp_offset;
+ u16 sp_stable_time;
+ u8 sp_cal_control;
+ u8 sp_ext_sleep_clk;
+ u16 sp_reserved;
+};
+
+struct mwifiex_sleep_period {
+ u16 period;
+ u16 reserved;
+};
+
+struct mwifiex_wep_key {
+ u32 length;
+ u32 key_index;
+ u32 key_length;
+ u8 key_material[MWIFIEX_KEY_BUFFER_SIZE];
+};
+
+#define MAX_REGION_CHANNEL_NUM 2
+
+struct mwifiex_chan_freq_power {
+ u16 channel;
+ u32 freq;
+ u16 max_tx_power;
+ u8 unsupported;
+};
+
+enum state_11d_t {
+ DISABLE_11D = 0,
+ ENABLE_11D = 1,
+};
+
+#define MWIFIEX_MAX_TRIPLET_802_11D 83
+
+struct mwifiex_802_11d_domain_reg {
+ u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
+ u8 no_of_triplet;
+ struct ieee80211_country_ie_triplet
+ triplet[MWIFIEX_MAX_TRIPLET_802_11D];
+};
+
+struct mwifiex_vendor_spec_cfg_ie {
+ u16 mask;
+ u16 flag;
+ u8 ie[MWIFIEX_MAX_VSIE_LEN];
+};
+
+struct wps {
+ u8 session_enable;
+};
+
+struct mwifiex_adapter;
+struct mwifiex_private;
+
+struct mwifiex_private {
+ struct mwifiex_adapter *adapter;
+ u8 bss_index;
+ u8 bss_type;
+ u8 bss_role;
+ u8 bss_priority;
+ u8 bss_num;
+ u8 frame_type;
+ u8 curr_addr[ETH_ALEN];
+ u8 media_connected;
+ u32 num_tx_timeout;
+ struct net_device *netdev;
+ struct net_device_stats stats;
+ u16 curr_pkt_filter;
+ u32 bss_mode;
+ u32 pkt_tx_ctrl;
+ u16 tx_power_level;
+ u8 max_tx_power_level;
+ u8 min_tx_power_level;
+ u8 tx_rate;
+ u8 tx_htinfo;
+ u8 rxpd_htinfo;
+ u8 rxpd_rate;
+ u16 rate_bitmap;
+ u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
+ u32 data_rate;
+ u8 is_data_rate_auto;
+ u16 bcn_avg_factor;
+ u16 data_avg_factor;
+ s16 data_rssi_last;
+ s16 data_nf_last;
+ s16 data_rssi_avg;
+ s16 data_nf_avg;
+ s16 bcn_rssi_last;
+ s16 bcn_nf_last;
+ s16 bcn_rssi_avg;
+ s16 bcn_nf_avg;
+ struct mwifiex_bssdescriptor *attempted_bss_desc;
+ struct mwifiex_802_11_ssid prev_ssid;
+ u8 prev_bssid[ETH_ALEN];
+ struct mwifiex_current_bss_params curr_bss_params;
+ u16 beacon_period;
+ u16 listen_interval;
+ u16 atim_window;
+ u8 adhoc_channel;
+ u8 adhoc_is_link_sensed;
+ u8 adhoc_state;
+ struct mwifiex_802_11_security sec_info;
+ struct mwifiex_wep_key wep_key[NUM_WEP_KEYS];
+ u16 wep_key_curr_index;
+ u8 wpa_ie[256];
+ u8 wpa_ie_len;
+ u8 wpa_is_gtk_set;
+ struct host_cmd_ds_802_11_key_material aes_key;
+ u8 wapi_ie[256];
+ u8 wapi_ie_len;
+ u8 wmm_required;
+ u8 wmm_enabled;
+ u8 wmm_qosinfo;
+ struct mwifiex_wmm_desc wmm;
+ struct list_head tx_ba_stream_tbl_ptr;
+ /* spin lock for tx_ba_stream_tbl_ptr queue */
+ spinlock_t tx_ba_stream_tbl_lock;
+ struct mwifiex_tx_aggr aggr_prio_tbl[MAX_NUM_TID];
+ struct mwifiex_add_ba_param add_ba_param;
+ u16 rx_seq[MAX_NUM_TID];
+ struct list_head rx_reorder_tbl_ptr;
+ /* spin lock for rx_reorder_tbl_ptr queue */
+ spinlock_t rx_reorder_tbl_lock;
+ /* spin lock for Rx packets */
+ spinlock_t rx_pkt_lock;
+
+#define MWIFIEX_ASSOC_RSP_BUF_SIZE 500
+ u8 assoc_rsp_buf[MWIFIEX_ASSOC_RSP_BUF_SIZE];
+ u32 assoc_rsp_size;
+
+#define MWIFIEX_GENIE_BUF_SIZE 256
+ u8 gen_ie_buf[MWIFIEX_GENIE_BUF_SIZE];
+ u8 gen_ie_buf_len;
+
+ struct mwifiex_vendor_spec_cfg_ie vs_ie[MWIFIEX_MAX_VSIE_NUM];
+
+#define MWIFIEX_ASSOC_TLV_BUF_SIZE 256
+ u8 assoc_tlv_buf[MWIFIEX_ASSOC_TLV_BUF_SIZE];
+ u8 assoc_tlv_buf_len;
+
+ u8 *curr_bcn_buf;
+ u32 curr_bcn_size;
+ /* spin lock for beacon buffer */
+ spinlock_t curr_bcn_buf_lock;
+ struct wireless_dev *wdev;
+ struct mwifiex_chan_freq_power cfp;
+ char version_str[128];
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *dfs_dev_dir;
+#endif
+ u8 nick_name[16];
+ struct iw_statistics w_stats;
+ u16 current_key_index;
+ struct semaphore async_sem;
+ u8 scan_pending_on_block;
+ u8 report_scan_result;
+ struct cfg80211_scan_request *scan_request;
+ int scan_result_status;
+ int assoc_request;
+ u16 assoc_result;
+ int ibss_join_request;
+ u16 ibss_join_result;
+ bool disconnect;
+ u8 cfg_bssid[6];
+ struct workqueue_struct *workqueue;
+ struct work_struct cfg_workqueue;
+ u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
+ struct wps wps;
+ u8 scan_block;
+};
+
+enum mwifiex_ba_status {
+ BA_STREAM_NOT_SETUP = 0,
+ BA_STREAM_SETUP_INPROGRESS,
+ BA_STREAM_SETUP_COMPLETE
+};
+
+struct mwifiex_tx_ba_stream_tbl {
+ struct list_head list;
+ int tid;
+ u8 ra[ETH_ALEN];
+ enum mwifiex_ba_status ba_status;
+};
+
+struct mwifiex_rx_reorder_tbl;
+
+struct reorder_tmr_cnxt {
+ struct timer_list timer;
+ struct mwifiex_rx_reorder_tbl *ptr;
+ struct mwifiex_private *priv;
+};
+
+struct mwifiex_rx_reorder_tbl {
+ struct list_head list;
+ int tid;
+ u8 ta[ETH_ALEN];
+ int start_win;
+ int win_size;
+ void **rx_reorder_ptr;
+ struct reorder_tmr_cnxt timer_context;
+};
+
+struct mwifiex_bss_prio_node {
+ struct list_head list;
+ struct mwifiex_private *priv;
+};
+
+struct mwifiex_bss_prio_tbl {
+ struct list_head bss_prio_head;
+ /* spin lock for bss priority */
+ spinlock_t bss_prio_lock;
+ struct mwifiex_bss_prio_node *bss_prio_cur;
+};
+
+struct cmd_ctrl_node {
+ struct list_head list;
+ struct mwifiex_private *priv;
+ u32 cmd_oid;
+ u32 cmd_flag;
+ struct sk_buff *cmd_skb;
+ struct sk_buff *resp_skb;
+ void *data_buf;
+ u32 wait_q_enabled;
+ struct sk_buff *skb;
+};
+
+struct mwifiex_if_ops {
+ int (*init_if) (struct mwifiex_adapter *);
+ void (*cleanup_if) (struct mwifiex_adapter *);
+ int (*check_fw_status) (struct mwifiex_adapter *, u32, int *);
+ int (*prog_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *);
+ int (*register_dev) (struct mwifiex_adapter *);
+ void (*unregister_dev) (struct mwifiex_adapter *);
+ int (*enable_int) (struct mwifiex_adapter *);
+ int (*process_int_status) (struct mwifiex_adapter *);
+ int (*host_to_card) (struct mwifiex_adapter *, u8,
+ u8 *payload, u32 pkt_len,
+ struct mwifiex_tx_param *);
+ int (*wakeup) (struct mwifiex_adapter *);
+ int (*wakeup_complete) (struct mwifiex_adapter *);
+
+ void (*update_mp_end_port) (struct mwifiex_adapter *, u16);
+ void (*cleanup_mpa_buf) (struct mwifiex_adapter *);
+};
+
+struct mwifiex_adapter {
+ struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM];
+ u8 priv_num;
+ struct mwifiex_drv_mode *drv_mode;
+ const struct firmware *firmware;
+ struct device *dev;
+ bool surprise_removed;
+ u32 fw_release_number;
+ u32 revision_id;
+ u16 init_wait_q_woken;
+ wait_queue_head_t init_wait_q;
+ void *card;
+ struct mwifiex_if_ops if_ops;
+ atomic_t rx_pending;
+ atomic_t tx_pending;
+ atomic_t cmd_pending;
+ struct workqueue_struct *workqueue;
+ struct work_struct main_work;
+ struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM];
+ /* spin lock for init/shutdown */
+ spinlock_t mwifiex_lock;
+ /* spin lock for main process */
+ spinlock_t main_proc_lock;
+ u32 mwifiex_processing;
+ u16 max_tx_buf_size;
+ u16 tx_buf_size;
+ u16 curr_tx_buf_size;
+ u32 ioport;
+ enum MWIFIEX_HARDWARE_STATUS hw_status;
+ u16 number_of_antenna;
+ u32 fw_cap_info;
+ /* spin lock for interrupt handling */
+ spinlock_t int_lock;
+ u8 int_status;
+ u32 event_cause;
+ struct sk_buff *event_skb;
+ u8 upld_buf[MWIFIEX_UPLD_SIZE];
+ u8 data_sent;
+ u8 cmd_sent;
+ u8 cmd_resp_received;
+ u8 event_received;
+ u8 data_received;
+ u16 seq_num;
+ struct cmd_ctrl_node *cmd_pool;
+ struct cmd_ctrl_node *curr_cmd;
+ /* spin lock for command */
+ spinlock_t mwifiex_cmd_lock;
+ u32 num_cmd_timeout;
+ u16 last_init_cmd;
+ struct timer_list cmd_timer;
+ struct list_head cmd_free_q;
+ /* spin lock for cmd_free_q */
+ spinlock_t cmd_free_q_lock;
+ struct list_head cmd_pending_q;
+ /* spin lock for cmd_pending_q */
+ spinlock_t cmd_pending_q_lock;
+ struct list_head scan_pending_q;
+ /* spin lock for scan_pending_q */
+ spinlock_t scan_pending_q_lock;
+ u32 scan_processing;
+ u16 region_code;
+ struct mwifiex_802_11d_domain_reg domain_reg;
+ struct mwifiex_bssdescriptor *scan_table;
+ u32 num_in_scan_table;
+ u16 scan_probes;
+ u32 scan_mode;
+ u16 specific_scan_time;
+ u16 active_scan_time;
+ u16 passive_scan_time;
+ u8 bcn_buf[MAX_SCAN_BEACON_BUFFER];
+ u8 *bcn_buf_end;
+ u8 fw_bands;
+ u8 adhoc_start_band;
+ u8 config_bands;
+ struct mwifiex_chan_scan_param_set *scan_channels;
+ u8 tx_lock_flag;
+ struct mwifiex_sleep_params sleep_params;
+ struct mwifiex_sleep_period sleep_period;
+ u16 ps_mode;
+ u32 ps_state;
+ u8 need_to_wakeup;
+ u16 multiple_dtim;
+ u16 local_listen_interval;
+ u16 null_pkt_interval;
+ struct sk_buff *sleep_cfm;
+ u16 bcn_miss_time_out;
+ u16 adhoc_awake_period;
+ u8 is_deep_sleep;
+ u8 delay_null_pkt;
+ u16 delay_to_ps;
+ u16 enhanced_ps_mode;
+ u8 pm_wakeup_card_req;
+ u16 gen_null_pkt;
+ u16 pps_uapsd_mode;
+ u32 pm_wakeup_fw_try;
+ u8 is_hs_configured;
+ struct mwifiex_hs_config_param hs_cfg;
+ u8 hs_activated;
+ u16 hs_activate_wait_q_woken;
+ wait_queue_head_t hs_activate_wait_q;
+ bool is_suspended;
+ u8 event_body[MAX_EVENT_SIZE];
+ u32 hw_dot_11n_dev_cap;
+ u8 hw_dev_mcs_support;
+ u8 adhoc_11n_enabled;
+ u8 chan_offset;
+ struct mwifiex_dbg dbg;
+ u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE];
+ u32 arp_filter_size;
+ u16 cmd_wait_q_required;
+ struct mwifiex_wait_queue cmd_wait_q;
+};
+
+int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
+void mwifiex_free_lock_list(struct mwifiex_adapter *adapter);
+
+int mwifiex_init_fw(struct mwifiex_adapter *adapter);
+
+int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter);
+
+int mwifiex_shutdown_drv(struct mwifiex_adapter *adapter);
+
+int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter);
+
+int mwifiex_dnld_fw(struct mwifiex_adapter *, struct mwifiex_fw_image *);
+
+int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb);
+
+int mwifiex_process_event(struct mwifiex_adapter *adapter);
+
+int mwifiex_complete_cmd(struct mwifiex_adapter *adapter);
+
+int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
+ u16 cmd_action, u32 cmd_oid, void *data_buf);
+
+int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
+ u16 cmd_action, u32 cmd_oid, void *data_buf);
+
+void mwifiex_cmd_timeout_func(unsigned long function_context);
+
+int mwifiex_get_debug_info(struct mwifiex_private *,
+ struct mwifiex_debug_info *);
+
+int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter);
+int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter);
+void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter);
+void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter);
+
+void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
+ struct cmd_ctrl_node *cmd_node);
+
+void mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
+ struct cmd_ctrl_node *cmd_node,
+ u32 addtail);
+
+int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter);
+int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter);
+int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
+ struct sk_buff *skb);
+int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
+ struct mwifiex_tx_param *tx_param);
+int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags);
+int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
+ struct sk_buff *skb, int status);
+int mwifiex_recv_packet_complete(struct mwifiex_adapter *,
+ struct sk_buff *skb, int status);
+void mwifiex_clean_txrx(struct mwifiex_private *priv);
+u8 mwifiex_check_last_packet_indication(struct mwifiex_private *priv);
+void mwifiex_check_ps_cond(struct mwifiex_adapter *adapter);
+void mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *, u8 *,
+ u32);
+int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ u16 cmd_action, uint16_t ps_bitmap,
+ void *data_buf);
+int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp,
+ void *data_buf);
+void mwifiex_process_hs_config(struct mwifiex_adapter *adapter);
+void mwifiex_hs_activated_event(struct mwifiex_private *priv,
+ u8 activated);
+int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp);
+int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter,
+ struct sk_buff *skb);
+int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no,
+ u16 cmd_action, u32 cmd_oid,
+ void *data_buf, void *cmd_buf);
+int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no,
+ void *cmd_buf);
+int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *,
+ struct sk_buff *skb);
+int mwifiex_process_sta_event(struct mwifiex_private *);
+void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb);
+int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta);
+int mwifiex_scan_networks(struct mwifiex_private *priv,
+ const struct mwifiex_user_scan_cfg *user_scan_in);
+int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd,
+ void *data_buf);
+void mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
+ struct cmd_ctrl_node *cmd_node);
+int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp);
+s32 mwifiex_find_ssid_in_list(struct mwifiex_private *priv,
+ struct mwifiex_802_11_ssid *ssid, u8 *bssid,
+ u32 mode);
+s32 mwifiex_find_bssid_in_list(struct mwifiex_private *priv, u8 *bssid,
+ u32 mode);
+int mwifiex_find_best_network(struct mwifiex_private *priv,
+ struct mwifiex_ssid_bssid *req_ssid_bssid);
+s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
+ struct mwifiex_802_11_ssid *ssid2);
+int mwifiex_associate(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc);
+int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
+ struct host_cmd_ds_command
+ *cmd, void *data_buf);
+int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp);
+void mwifiex_reset_connect_state(struct mwifiex_private *priv);
+void mwifiex_2040_coex_event(struct mwifiex_private *priv);
+u8 mwifiex_band_to_radio_type(u8 band);
+int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac);
+int mwifiex_adhoc_start(struct mwifiex_private *priv,
+ struct mwifiex_802_11_ssid *adhoc_ssid);
+int mwifiex_adhoc_join(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc);
+int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ void *data_buf);
+int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ void *data_buf);
+int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp);
+int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd);
+struct mwifiex_chan_freq_power *
+ mwifiex_get_cfp_by_band_and_channel_from_cfg80211(
+ struct mwifiex_private *priv,
+ u8 band, u16 channel);
+struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211(
+ struct mwifiex_private *priv,
+ u8 band, u32 freq);
+u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info);
+u32 mwifiex_find_freq_from_band_chan(u8, u8);
+int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask,
+ u8 **buffer);
+u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv,
+ u8 *rates);
+u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates);
+u8 mwifiex_data_rate_to_index(u32 rate);
+u8 mwifiex_is_rate_auto(struct mwifiex_private *priv);
+int mwifiex_get_rate_index(u16 *rateBitmap, int size);
+extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE];
+void mwifiex_save_curr_bcn(struct mwifiex_private *priv);
+void mwifiex_free_curr_bcn(struct mwifiex_private *priv);
+int mwifiex_cmd_get_hw_spec(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd);
+int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp);
+int is_command_pending(struct mwifiex_adapter *adapter);
+
+/*
+ * This function checks if the queuing is RA based or not.
+ */
+static inline u8
+mwifiex_queuing_ra_based(struct mwifiex_private *priv)
+{
+ /*
+ * Currently we assume if we are in Infra, then DA=RA. This might not be
+ * true in the future
+ */
+ if ((priv->bss_mode == NL80211_IFTYPE_STATION) &&
+ (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA))
+ return false;
+
+ return true;
+}
+
+/*
+ * This function copies rates.
+ */
+static inline u32
+mwifiex_copy_rates(u8 *dest, u32 pos, u8 *src, int len)
+{
+ int i;
+
+ for (i = 0; i < len && src[i]; i++, pos++) {
+ if (pos >= MWIFIEX_SUPPORTED_RATES)
+ break;
+ dest[pos] = src[i];
+ }
+
+ return pos;
+}
+
+/*
+ * This function returns the correct private structure pointer based
+ * upon the BSS type and BSS number.
+ */
+static inline struct mwifiex_private *
+mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter,
+ u8 bss_num, u8 bss_type)
+{
+ int i;
+
+ for (i = 0; i < adapter->priv_num; i++) {
+ if (adapter->priv[i]) {
+ if ((adapter->priv[i]->bss_num == bss_num)
+ && (adapter->priv[i]->bss_type == bss_type))
+ break;
+ }
+ }
+ return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
+}
+
+/*
+ * This function returns the first available private structure pointer
+ * based upon the BSS role.
+ */
+static inline struct mwifiex_private *
+mwifiex_get_priv(struct mwifiex_adapter *adapter,
+ enum mwifiex_bss_role bss_role)
+{
+ int i;
+
+ for (i = 0; i < adapter->priv_num; i++) {
+ if (adapter->priv[i]) {
+ if (bss_role == MWIFIEX_BSS_ROLE_ANY ||
+ GET_BSS_ROLE(adapter->priv[i]) == bss_role)
+ break;
+ }
+ }
+
+ return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
+}
+
+/*
+ * This function returns the driver private structure of a network device.
+ */
+static inline struct mwifiex_private *
+mwifiex_netdev_get_priv(struct net_device *dev)
+{
+ return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev));
+}
+
+struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter
+ *adapter, u8 bss_index);
+int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
+ u32 func_init_shutdown);
+int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *);
+int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *);
+
+void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version,
+ int maxlen);
+int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
+ struct mwifiex_multicast_list *mcast_list);
+int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
+ struct net_device *dev);
+int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter);
+int mwifiex_bss_start(struct mwifiex_private *priv,
+ struct mwifiex_ssid_bssid *ssid_bssid);
+int mwifiex_set_hs_params(struct mwifiex_private *priv,
+ u16 action, int cmd_type,
+ struct mwifiex_ds_hs_cfg *hscfg);
+int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type);
+int mwifiex_enable_hs(struct mwifiex_adapter *adapter);
+int mwifiex_get_signal_info(struct mwifiex_private *priv,
+ struct mwifiex_ds_get_signal *signal);
+int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
+ struct mwifiex_rate_cfg *rate);
+int mwifiex_find_best_bss(struct mwifiex_private *priv,
+ struct mwifiex_ssid_bssid *ssid_bssid);
+int mwifiex_request_scan(struct mwifiex_private *priv,
+ struct mwifiex_802_11_ssid *req_ssid);
+int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
+ struct mwifiex_user_scan_cfg *scan_req);
+int mwifiex_change_adhoc_chan(struct mwifiex_private *priv, int channel);
+int mwifiex_set_radio(struct mwifiex_private *priv, u8 option);
+
+int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel);
+
+int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
+ int key_len, u8 key_index, int disable);
+
+int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len);
+
+int mwifiex_get_ver_ext(struct mwifiex_private *priv);
+
+int mwifiex_get_stats_info(struct mwifiex_private *priv,
+ struct mwifiex_ds_get_stats *log);
+
+int mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type,
+ u32 reg_offset, u32 reg_value);
+
+int mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type,
+ u32 reg_offset, u32 *value);
+
+int mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes,
+ u8 *value);
+
+int mwifiex_set_11n_httx_cfg(struct mwifiex_private *priv, int data);
+
+int mwifiex_get_11n_httx_cfg(struct mwifiex_private *priv, int *data);
+
+int mwifiex_set_tx_rate_cfg(struct mwifiex_private *priv, int tx_rate_index);
+
+int mwifiex_get_tx_rate_cfg(struct mwifiex_private *priv, int *tx_rate_index);
+
+int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode);
+
+int mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter,
+ char *version, int max_len);
+
+int mwifiex_set_tx_power(struct mwifiex_private *priv,
+ struct mwifiex_power_cfg *power_cfg);
+
+int mwifiex_main_process(struct mwifiex_adapter *);
+
+int mwifiex_bss_set_channel(struct mwifiex_private *,
+ struct mwifiex_chan_freq_power *cfp);
+int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *,
+ struct mwifiex_ssid_bssid *);
+int mwifiex_set_radio_band_cfg(struct mwifiex_private *,
+ struct mwifiex_ds_band_cfg *);
+int mwifiex_get_bss_info(struct mwifiex_private *,
+ struct mwifiex_bss_info *);
+
+#ifdef CONFIG_DEBUG_FS
+void mwifiex_debugfs_init(void);
+void mwifiex_debugfs_remove(void);
+
+void mwifiex_dev_debugfs_init(struct mwifiex_private *priv);
+void mwifiex_dev_debugfs_remove(struct mwifiex_private *priv);
+#endif
+#endif /* !_MWIFIEX_MAIN_H_ */
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
new file mode 100644
index 00000000000..5c22860fb40
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -0,0 +1,3025 @@
+/*
+ * Marvell Wireless LAN device driver: scan ioctl and command handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "11n.h"
+#include "cfg80211.h"
+
+/* The maximum number of channels the firmware can scan per command */
+#define MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN 14
+
+#define MWIFIEX_CHANNELS_PER_SCAN_CMD 4
+
+/* Memory needed to store a max sized Channel List TLV for a firmware scan */
+#define CHAN_TLV_MAX_SIZE (sizeof(struct mwifiex_ie_types_header) \
+ + (MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN \
+ *sizeof(struct mwifiex_chan_scan_param_set)))
+
+/* Memory needed to store supported rate */
+#define RATE_TLV_MAX_SIZE (sizeof(struct mwifiex_ie_types_rates_param_set) \
+ + HOSTCMD_SUPPORTED_RATES)
+
+/* Memory needed to store a max number/size WildCard SSID TLV for a firmware
+ scan */
+#define WILDCARD_SSID_TLV_MAX_SIZE \
+ (MWIFIEX_MAX_SSID_LIST_LENGTH * \
+ (sizeof(struct mwifiex_ie_types_wildcard_ssid_params) \
+ + IEEE80211_MAX_SSID_LEN))
+
+/* Maximum memory needed for a mwifiex_scan_cmd_config with all TLVs at max */
+#define MAX_SCAN_CFG_ALLOC (sizeof(struct mwifiex_scan_cmd_config) \
+ + sizeof(struct mwifiex_ie_types_num_probes) \
+ + sizeof(struct mwifiex_ie_types_htcap) \
+ + CHAN_TLV_MAX_SIZE \
+ + RATE_TLV_MAX_SIZE \
+ + WILDCARD_SSID_TLV_MAX_SIZE)
+
+
+union mwifiex_scan_cmd_config_tlv {
+ /* Scan configuration (variable length) */
+ struct mwifiex_scan_cmd_config config;
+ /* Max allocated block */
+ u8 config_alloc_buf[MAX_SCAN_CFG_ALLOC];
+};
+
+enum cipher_suite {
+ CIPHER_SUITE_TKIP,
+ CIPHER_SUITE_CCMP,
+ CIPHER_SUITE_MAX
+};
+static u8 mwifiex_wpa_oui[CIPHER_SUITE_MAX][4] = {
+ { 0x00, 0x50, 0xf2, 0x02 }, /* TKIP */
+ { 0x00, 0x50, 0xf2, 0x04 }, /* AES */
+};
+static u8 mwifiex_rsn_oui[CIPHER_SUITE_MAX][4] = {
+ { 0x00, 0x0f, 0xac, 0x02 }, /* TKIP */
+ { 0x00, 0x0f, 0xac, 0x04 }, /* AES */
+};
+
+/*
+ * This function parses a given IE for a given OUI.
+ *
+ * This is used to parse a WPA/RSN IE to find if it has
+ * a given oui in PTK.
+ */
+static u8
+mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui)
+{
+ u8 count;
+
+ count = iebody->ptk_cnt[0];
+
+ /* There could be multiple OUIs for PTK hence
+ 1) Take the length.
+ 2) Check all the OUIs for AES.
+ 3) If one of them is AES then pass success. */
+ while (count) {
+ if (!memcmp(iebody->ptk_body, oui, sizeof(iebody->ptk_body)))
+ return MWIFIEX_OUI_PRESENT;
+
+ --count;
+ if (count)
+ iebody = (struct ie_body *) ((u8 *) iebody +
+ sizeof(iebody->ptk_body));
+ }
+
+ pr_debug("info: %s: OUI is not found in PTK\n", __func__);
+ return MWIFIEX_OUI_NOT_PRESENT;
+}
+
+/*
+ * This function checks if a given OUI is present in a RSN IE.
+ *
+ * The function first checks if a RSN IE is present or not in the
+ * BSS descriptor. It tries to locate the OUI only if such an IE is
+ * present.
+ */
+static u8
+mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
+{
+ u8 *oui;
+ struct ie_body *iebody;
+ u8 ret = MWIFIEX_OUI_NOT_PRESENT;
+
+ if (((bss_desc->bcn_rsn_ie) && ((*(bss_desc->bcn_rsn_ie)).
+ ieee_hdr.element_id == WLAN_EID_RSN))) {
+ iebody = (struct ie_body *)
+ (((u8 *) bss_desc->bcn_rsn_ie->data) +
+ RSN_GTK_OUI_OFFSET);
+ oui = &mwifiex_rsn_oui[cipher][0];
+ ret = mwifiex_search_oui_in_ie(iebody, oui);
+ if (ret)
+ return ret;
+ }
+ return ret;
+}
+
+/*
+ * This function checks if a given OUI is present in a WPA IE.
+ *
+ * The function first checks if a WPA IE is present or not in the
+ * BSS descriptor. It tries to locate the OUI only if such an IE is
+ * present.
+ */
+static u8
+mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
+{
+ u8 *oui;
+ struct ie_body *iebody;
+ u8 ret = MWIFIEX_OUI_NOT_PRESENT;
+
+ if (((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)).
+ vend_hdr.element_id == WLAN_EID_WPA))) {
+ iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data;
+ oui = &mwifiex_wpa_oui[cipher][0];
+ ret = mwifiex_search_oui_in_ie(iebody, oui);
+ if (ret)
+ return ret;
+ }
+ return ret;
+}
+
+/*
+ * This function compares two SSIDs and checks if they match.
+ */
+s32
+mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
+ struct mwifiex_802_11_ssid *ssid2)
+{
+ if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len))
+ return -1;
+ return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssid_len);
+}
+
+/*
+ * Sends IOCTL request to get the best BSS.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int mwifiex_find_best_bss(struct mwifiex_private *priv,
+ struct mwifiex_ssid_bssid *ssid_bssid)
+{
+ struct mwifiex_ssid_bssid tmp_ssid_bssid;
+ u8 *mac;
+
+ if (!ssid_bssid)
+ return -1;
+
+ memcpy(&tmp_ssid_bssid, ssid_bssid,
+ sizeof(struct mwifiex_ssid_bssid));
+
+ if (!mwifiex_bss_ioctl_find_bss(priv, &tmp_ssid_bssid)) {
+ memcpy(ssid_bssid, &tmp_ssid_bssid,
+ sizeof(struct mwifiex_ssid_bssid));
+ mac = (u8 *) &ssid_bssid->bssid;
+ dev_dbg(priv->adapter->dev, "cmd: found network: ssid=%s,"
+ " %pM\n", ssid_bssid->ssid.ssid, mac);
+ return 0;
+ }
+
+ return -1;
+}
+
+/*
+ * Sends IOCTL request to start a scan with user configurations.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ *
+ * Upon completion, it also generates a wireless event to notify
+ * applications.
+ */
+int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
+ struct mwifiex_user_scan_cfg *scan_req)
+{
+ int status;
+
+ priv->adapter->cmd_wait_q.condition = false;
+
+ status = mwifiex_scan_networks(priv, scan_req);
+ if (!status)
+ status = mwifiex_wait_queue_complete(priv->adapter);
+
+ return status;
+}
+
+/*
+ * This function checks if wapi is enabled in driver and scanned network is
+ * compatible with it.
+ */
+static bool
+mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc)
+{
+ if (priv->sec_info.wapi_enabled &&
+ (bss_desc->bcn_wapi_ie &&
+ ((*(bss_desc->bcn_wapi_ie)).ieee_hdr.element_id ==
+ WLAN_EID_BSS_AC_ACCESS_DELAY))) {
+ return true;
+ }
+ return false;
+}
+
+/*
+ * This function checks if driver is configured with no security mode and
+ * scanned network is compatible with it.
+ */
+static bool
+mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc)
+{
+ if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
+ && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
+ && ((!bss_desc->bcn_wpa_ie) ||
+ ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id !=
+ WLAN_EID_WPA))
+ && ((!bss_desc->bcn_rsn_ie) ||
+ ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id !=
+ WLAN_EID_RSN))
+ && !priv->sec_info.encryption_mode
+ && !bss_desc->privacy) {
+ return true;
+ }
+ return false;
+}
+
+/*
+ * This function checks if static WEP is enabled in driver and scanned network
+ * is compatible with it.
+ */
+static bool
+mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc)
+{
+ if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED
+ && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
+ && bss_desc->privacy) {
+ return true;
+ }
+ return false;
+}
+
+/*
+ * This function checks if wpa is enabled in driver and scanned network is
+ * compatible with it.
+ */
+static bool
+mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc,
+ int index)
+{
+ if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
+ && priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
+ && ((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)).vend_hdr.
+ element_id == WLAN_EID_WPA))
+ /*
+ * Privacy bit may NOT be set in some APs like
+ * LinkSys WRT54G && bss_desc->privacy
+ */
+ ) {
+ dev_dbg(priv->adapter->dev, "info: %s: WPA: index=%d"
+ " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
+ "EncMode=%#x privacy=%#x\n", __func__, index,
+ (bss_desc->bcn_wpa_ie) ?
+ (*(bss_desc->bcn_wpa_ie)).
+ vend_hdr.element_id : 0,
+ (bss_desc->bcn_rsn_ie) ?
+ (*(bss_desc->bcn_rsn_ie)).
+ ieee_hdr.element_id : 0,
+ (priv->sec_info.wep_status ==
+ MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d",
+ (priv->sec_info.wpa_enabled) ? "e" : "d",
+ (priv->sec_info.wpa2_enabled) ? "e" : "d",
+ priv->sec_info.encryption_mode,
+ bss_desc->privacy);
+ return true;
+ }
+ return false;
+}
+
+/*
+ * This function checks if wpa2 is enabled in driver and scanned network is
+ * compatible with it.
+ */
+static bool
+mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc,
+ int index)
+{
+ if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
+ && !priv->sec_info.wpa_enabled && priv->sec_info.wpa2_enabled
+ && ((bss_desc->bcn_rsn_ie) && ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
+ element_id == WLAN_EID_RSN))
+ /*
+ * Privacy bit may NOT be set in some APs like
+ * LinkSys WRT54G && bss_desc->privacy
+ */
+ ) {
+ dev_dbg(priv->adapter->dev, "info: %s: WPA2: index=%d"
+ " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
+ "EncMode=%#x privacy=%#x\n", __func__, index,
+ (bss_desc->bcn_wpa_ie) ?
+ (*(bss_desc->bcn_wpa_ie)).
+ vend_hdr.element_id : 0,
+ (bss_desc->bcn_rsn_ie) ?
+ (*(bss_desc->bcn_rsn_ie)).
+ ieee_hdr.element_id : 0,
+ (priv->sec_info.wep_status ==
+ MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d",
+ (priv->sec_info.wpa_enabled) ? "e" : "d",
+ (priv->sec_info.wpa2_enabled) ? "e" : "d",
+ priv->sec_info.encryption_mode,
+ bss_desc->privacy);
+ return true;
+ }
+ return false;
+}
+
+/*
+ * This function checks if adhoc AES is enabled in driver and scanned network is
+ * compatible with it.
+ */
+static bool
+mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc)
+{
+ if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
+ && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
+ && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr.
+ element_id != WLAN_EID_WPA))
+ && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
+ element_id != WLAN_EID_RSN))
+ && !priv->sec_info.encryption_mode
+ && bss_desc->privacy) {
+ return true;
+ }
+ return false;
+}
+
+/*
+ * This function checks if dynamic WEP is enabled in driver and scanned network
+ * is compatible with it.
+ */
+static bool
+mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv,
+ struct mwifiex_bssdescriptor *bss_desc,
+ int index)
+{
+ if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
+ && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
+ && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr.
+ element_id != WLAN_EID_WPA))
+ && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
+ element_id != WLAN_EID_RSN))
+ && priv->sec_info.encryption_mode
+ && bss_desc->privacy) {
+ dev_dbg(priv->adapter->dev, "info: %s: dynamic "
+ "WEP: index=%d wpa_ie=%#x wpa2_ie=%#x "
+ "EncMode=%#x privacy=%#x\n",
+ __func__, index,
+ (bss_desc->bcn_wpa_ie) ?
+ (*(bss_desc->bcn_wpa_ie)).
+ vend_hdr.element_id : 0,
+ (bss_desc->bcn_rsn_ie) ?
+ (*(bss_desc->bcn_rsn_ie)).
+ ieee_hdr.element_id : 0,
+ priv->sec_info.encryption_mode,
+ bss_desc->privacy);
+ return true;
+ }
+ return false;
+}
+
+/*
+ * This function checks if a scanned network is compatible with the driver
+ * settings.
+ *
+ * WEP WPA WPA2 ad-hoc encrypt Network
+ * enabled enabled enabled AES mode Privacy WPA WPA2 Compatible
+ * 0 0 0 0 NONE 0 0 0 yes No security
+ * 0 1 0 0 x 1x 1 x yes WPA (disable
+ * HT if no AES)
+ * 0 0 1 0 x 1x x 1 yes WPA2 (disable
+ * HT if no AES)
+ * 0 0 0 1 NONE 1 0 0 yes Ad-hoc AES
+ * 1 0 0 0 NONE 1 0 0 yes Static WEP
+ * (disable HT)
+ * 0 0 0 0 !=NONE 1 0 0 yes Dynamic WEP
+ *
+ * Compatibility is not matched while roaming, except for mode.
+ */
+static s32
+mwifiex_is_network_compatible(struct mwifiex_private *priv, u32 index, u32 mode)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct mwifiex_bssdescriptor *bss_desc;
+
+ bss_desc = &adapter->scan_table[index];
+ bss_desc->disable_11n = false;
+
+ /* Don't check for compatibility if roaming */
+ if (priv->media_connected && (priv->bss_mode == NL80211_IFTYPE_STATION)
+ && (bss_desc->bss_mode == NL80211_IFTYPE_STATION))
+ return index;
+
+ if (priv->wps.session_enable) {
+ dev_dbg(adapter->dev,
+ "info: return success directly in WPS period\n");
+ return index;
+ }
+
+ if (mwifiex_is_network_compatible_for_wapi(priv, bss_desc)) {
+ dev_dbg(adapter->dev, "info: return success for WAPI AP\n");
+ return index;
+ }
+
+ if (bss_desc->bss_mode == mode) {
+ if (mwifiex_is_network_compatible_for_no_sec(priv, bss_desc)) {
+ /* No security */
+ return index;
+ } else if (mwifiex_is_network_compatible_for_static_wep(priv,
+ bss_desc)) {
+ /* Static WEP enabled */
+ dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n");
+ bss_desc->disable_11n = true;
+ return index;
+ } else if (mwifiex_is_network_compatible_for_wpa(priv, bss_desc,
+ index)) {
+ /* WPA enabled */
+ if (((priv->adapter->config_bands & BAND_GN
+ || priv->adapter->config_bands & BAND_AN)
+ && bss_desc->bcn_ht_cap)
+ && !mwifiex_is_wpa_oui_present(bss_desc,
+ CIPHER_SUITE_CCMP)) {
+
+ if (mwifiex_is_wpa_oui_present(bss_desc,
+ CIPHER_SUITE_TKIP)) {
+ dev_dbg(adapter->dev,
+ "info: Disable 11n if AES "
+ "is not supported by AP\n");
+ bss_desc->disable_11n = true;
+ } else {
+ return -1;
+ }
+ }
+ return index;
+ } else if (mwifiex_is_network_compatible_for_wpa2(priv,
+ bss_desc, index)) {
+ /* WPA2 enabled */
+ if (((priv->adapter->config_bands & BAND_GN
+ || priv->adapter->config_bands & BAND_AN)
+ && bss_desc->bcn_ht_cap)
+ && !mwifiex_is_rsn_oui_present(bss_desc,
+ CIPHER_SUITE_CCMP)) {
+
+ if (mwifiex_is_rsn_oui_present(bss_desc,
+ CIPHER_SUITE_TKIP)) {
+ dev_dbg(adapter->dev,
+ "info: Disable 11n if AES "
+ "is not supported by AP\n");
+ bss_desc->disable_11n = true;
+ } else {
+ return -1;
+ }
+ }
+ return index;
+ } else if (mwifiex_is_network_compatible_for_adhoc_aes(priv,
+ bss_desc)) {
+ /* Ad-hoc AES enabled */
+ return index;
+ } else if (mwifiex_is_network_compatible_for_dynamic_wep(priv,
+ bss_desc, index)) {
+ /* Dynamic WEP enabled */
+ return index;
+ }
+
+ /* Security doesn't match */
+ dev_dbg(adapter->dev, "info: %s: failed: index=%d "
+ "wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode"
+ "=%#x privacy=%#x\n",
+ __func__, index,
+ (bss_desc->bcn_wpa_ie) ?
+ (*(bss_desc->bcn_wpa_ie)).vend_hdr.
+ element_id : 0,
+ (bss_desc->bcn_rsn_ie) ?
+ (*(bss_desc->bcn_rsn_ie)).ieee_hdr.
+ element_id : 0,
+ (priv->sec_info.wep_status ==
+ MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d",
+ (priv->sec_info.wpa_enabled) ? "e" : "d",
+ (priv->sec_info.wpa2_enabled) ? "e" : "d",
+ priv->sec_info.encryption_mode, bss_desc->privacy);
+ return -1;
+ }
+
+ /* Mode doesn't match */
+ return -1;
+}
+
+/*
+ * This function finds the best SSID in the scan list.
+ *
+ * It searches the scan table for the best SSID that also matches the current
+ * adapter network preference (mode, security etc.).
+ */
+static s32
+mwifiex_find_best_network_in_list(struct mwifiex_private *priv)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ u32 mode = priv->bss_mode;
+ s32 best_net = -1;
+ s32 best_rssi = 0;
+ u32 i;
+
+ dev_dbg(adapter->dev, "info: num of BSSIDs = %d\n",
+ adapter->num_in_scan_table);
+
+ for (i = 0; i < adapter->num_in_scan_table; i++) {
+ switch (mode) {
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_ADHOC:
+ if (mwifiex_is_network_compatible(priv, i, mode) >= 0) {
+ if (SCAN_RSSI(adapter->scan_table[i].rssi) >
+ best_rssi) {
+ best_rssi = SCAN_RSSI(adapter->
+ scan_table[i].rssi);
+ best_net = i;
+ }
+ }
+ break;
+ case NL80211_IFTYPE_UNSPECIFIED:
+ default:
+ if (SCAN_RSSI(adapter->scan_table[i].rssi) >
+ best_rssi) {
+ best_rssi = SCAN_RSSI(adapter->scan_table[i].
+ rssi);
+ best_net = i;
+ }
+ break;
+ }
+ }
+
+ return best_net;
+}
+
+/*
+ * This function creates a channel list for the driver to scan, based
+ * on region/band information.
+ *
+ * This routine is used for any scan that is not provided with a
+ * specific channel list to scan.
+ */
+static void
+mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
+ const struct mwifiex_user_scan_cfg
+ *user_scan_in,
+ struct mwifiex_chan_scan_param_set
+ *scan_chan_list,
+ u8 filtered_scan)
+{
+ enum ieee80211_band band;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *ch;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ int chan_idx = 0, i;
+ u8 scan_type;
+
+ for (band = 0; (band < IEEE80211_NUM_BANDS) ; band++) {
+
+ if (!priv->wdev->wiphy->bands[band])
+ continue;
+
+ sband = priv->wdev->wiphy->bands[band];
+
+ for (i = 0; (i < sband->n_channels) ; i++, chan_idx++) {
+ ch = &sband->channels[i];
+ if (ch->flags & IEEE80211_CHAN_DISABLED)
+ continue;
+ scan_chan_list[chan_idx].radio_type = band;
+ scan_type = ch->flags & IEEE80211_CHAN_PASSIVE_SCAN;
+ if (user_scan_in &&
+ user_scan_in->chan_list[0].scan_time)
+ scan_chan_list[chan_idx].max_scan_time =
+ cpu_to_le16((u16) user_scan_in->
+ chan_list[0].scan_time);
+ else if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
+ scan_chan_list[chan_idx].max_scan_time =
+ cpu_to_le16(adapter->passive_scan_time);
+ else
+ scan_chan_list[chan_idx].max_scan_time =
+ cpu_to_le16(adapter->active_scan_time);
+ if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
+ scan_chan_list[chan_idx].chan_scan_mode_bitmap
+ |= MWIFIEX_PASSIVE_SCAN;
+ else
+ scan_chan_list[chan_idx].chan_scan_mode_bitmap
+ &= ~MWIFIEX_PASSIVE_SCAN;
+ scan_chan_list[chan_idx].chan_number =
+ (u32) ch->hw_value;
+ if (filtered_scan) {
+ scan_chan_list[chan_idx].max_scan_time =
+ cpu_to_le16(adapter->specific_scan_time);
+ scan_chan_list[chan_idx].chan_scan_mode_bitmap
+ |= MWIFIEX_DISABLE_CHAN_FILT;
+ }
+ }
+
+ }
+}
+
+/*
+ * This function constructs and sends multiple scan config commands to
+ * the firmware.
+ *
+ * Previous routines in the code flow have created a scan command configuration
+ * with any requested TLVs. This function splits the channel TLV into maximum
+ * channels supported per scan lists and sends the portion of the channel TLV,
+ * along with the other TLVs, to the firmware.
+ */
+static int
+mwifiex_scan_channel_list(struct mwifiex_private *priv,
+ u32 max_chan_per_scan, u8 filtered_scan,
+ struct mwifiex_scan_cmd_config *scan_cfg_out,
+ struct mwifiex_ie_types_chan_list_param_set
+ *chan_tlv_out,
+ struct mwifiex_chan_scan_param_set *scan_chan_list)
+{
+ int ret = 0;
+ struct mwifiex_chan_scan_param_set *tmp_chan_list;
+ struct mwifiex_chan_scan_param_set *start_chan;
+
+ u32 tlv_idx;
+ u32 total_scan_time;
+ u32 done_early;
+
+ if (!scan_cfg_out || !chan_tlv_out || !scan_chan_list) {
+ dev_dbg(priv->adapter->dev,
+ "info: Scan: Null detect: %p, %p, %p\n",
+ scan_cfg_out, chan_tlv_out, scan_chan_list);
+ return -1;
+ }
+
+ chan_tlv_out->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
+
+ /* Set the temp channel struct pointer to the start of the desired
+ list */
+ tmp_chan_list = scan_chan_list;
+
+ /* Loop through the desired channel list, sending a new firmware scan
+ commands for each max_chan_per_scan channels (or for 1,6,11
+ individually if configured accordingly) */
+ while (tmp_chan_list->chan_number) {
+
+ tlv_idx = 0;
+ total_scan_time = 0;
+ chan_tlv_out->header.len = 0;
+ start_chan = tmp_chan_list;
+ done_early = false;
+
+ /*
+ * Construct the Channel TLV for the scan command. Continue to
+ * insert channel TLVs until:
+ * - the tlv_idx hits the maximum configured per scan command
+ * - the next channel to insert is 0 (end of desired channel
+ * list)
+ * - done_early is set (controlling individual scanning of
+ * 1,6,11)
+ */
+ while (tlv_idx < max_chan_per_scan
+ && tmp_chan_list->chan_number && !done_early) {
+
+ dev_dbg(priv->adapter->dev,
+ "info: Scan: Chan(%3d), Radio(%d),"
+ " Mode(%d, %d), Dur(%d)\n",
+ tmp_chan_list->chan_number,
+ tmp_chan_list->radio_type,
+ tmp_chan_list->chan_scan_mode_bitmap
+ & MWIFIEX_PASSIVE_SCAN,
+ (tmp_chan_list->chan_scan_mode_bitmap
+ & MWIFIEX_DISABLE_CHAN_FILT) >> 1,
+ le16_to_cpu(tmp_chan_list->max_scan_time));
+
+ /* Copy the current channel TLV to the command being
+ prepared */
+ memcpy(chan_tlv_out->chan_scan_param + tlv_idx,
+ tmp_chan_list,
+ sizeof(chan_tlv_out->chan_scan_param));
+
+ /* Increment the TLV header length by the size
+ appended */
+ chan_tlv_out->header.len =
+ cpu_to_le16(le16_to_cpu(chan_tlv_out->header.len) +
+ (sizeof(chan_tlv_out->chan_scan_param)));
+
+ /*
+ * 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.
+ */
+ scan_cfg_out->tlv_buf_len = (u32) ((u8 *) chan_tlv_out -
+ scan_cfg_out->tlv_buf);
+
+ /* Add the size of the channel tlv header and the data
+ length */
+ scan_cfg_out->tlv_buf_len +=
+ (sizeof(chan_tlv_out->header)
+ + le16_to_cpu(chan_tlv_out->header.len));
+
+ /* Increment the index to the channel tlv we are
+ constructing */
+ tlv_idx++;
+
+ /* Count the total scan time per command */
+ total_scan_time +=
+ le16_to_cpu(tmp_chan_list->max_scan_time);
+
+ done_early = false;
+
+ /* 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 (!filtered_scan && (tmp_chan_list->chan_number == 1
+ || tmp_chan_list->chan_number == 6
+ || tmp_chan_list->chan_number == 11))
+ done_early = true;
+
+ /* Increment the tmp pointer to the next channel to
+ be scanned */
+ tmp_chan_list++;
+
+ /* 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 (!filtered_scan && (tmp_chan_list->chan_number == 1
+ || tmp_chan_list->chan_number == 6
+ || tmp_chan_list->chan_number == 11))
+ done_early = true;
+ }
+
+ /* The total scan time should be less than scan command timeout
+ value */
+ if (total_scan_time > MWIFIEX_MAX_TOTAL_SCAN_TIME) {
+ dev_err(priv->adapter->dev, "total scan time %dms"
+ " is over limit (%dms), scan skipped\n",
+ total_scan_time, MWIFIEX_MAX_TOTAL_SCAN_TIME);
+ ret = -1;
+ break;
+ }
+
+ priv->adapter->scan_channels = start_chan;
+
+ /* Send the scan command to the firmware with the specified
+ cfg */
+ ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SCAN,
+ HostCmd_ACT_GEN_SET, 0,
+ scan_cfg_out);
+ if (ret)
+ break;
+ }
+
+ if (ret)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * This function constructs a scan command configuration structure to use
+ * in scan commands.
+ *
+ * Application layer or other functions can invoke network scanning
+ * with a scan configuration supplied in a user scan configuration structure.
+ * This structure is used as the basis of one or many scan command configuration
+ * commands that are sent to the command processing module and eventually to the
+ * firmware.
+ *
+ * This function creates a scan command configuration structure 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, the filter is disabled/cleared.
+ * If the number of probes is not set, adapter default setting is used.
+ */
+static void
+mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
+ const struct mwifiex_user_scan_cfg *user_scan_in,
+ struct mwifiex_scan_cmd_config *scan_cfg_out,
+ struct mwifiex_ie_types_chan_list_param_set
+ **chan_list_out,
+ struct mwifiex_chan_scan_param_set
+ *scan_chan_list,
+ u8 *max_chan_per_scan, u8 *filtered_scan,
+ u8 *scan_current_only)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct mwifiex_ie_types_num_probes *num_probes_tlv;
+ struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
+ struct mwifiex_ie_types_rates_param_set *rates_tlv;
+ const u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+ u8 *tlv_pos;
+ u32 num_probes;
+ u32 ssid_len;
+ u32 chan_idx;
+ u32 scan_type;
+ u16 scan_dur;
+ u8 channel;
+ u8 radio_type;
+ u32 ssid_idx;
+ u8 ssid_filter;
+ u8 rates[MWIFIEX_SUPPORTED_RATES];
+ u32 rates_size;
+ struct mwifiex_ie_types_htcap *ht_cap;
+
+ /* The tlv_buf_len 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 *chan_list_out. The difference
+ between the *chan_list_out and the tlv_buf start will be used to
+ calculate the size of anything we add in this routine. */
+ scan_cfg_out->tlv_buf_len = 0;
+
+ /* Running tlv pointer. Assigned to chan_list_out at end of function
+ so later routines know where channels can be added to the command
+ buf */
+ tlv_pos = scan_cfg_out->tlv_buf;
+
+ /* Initialize the scan as un-filtered; the flag is later set to TRUE
+ below if a SSID or BSSID filter is sent in the command */
+ *filtered_scan = false;
+
+ /* 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. */
+ *scan_current_only = false;
+
+ if (user_scan_in) {
+
+ /* Default the ssid_filter flag to TRUE, set false under
+ certain wildcard conditions and qualified by the existence
+ of an SSID list before marking the scan as filtered */
+ ssid_filter = true;
+
+ /* Set the BSS type scan filter, use Adapter setting if
+ unset */
+ scan_cfg_out->bss_mode =
+ (user_scan_in->bss_mode ? (u8) user_scan_in->
+ bss_mode : (u8) adapter->scan_mode);
+
+ /* Set the number of probes to send, use Adapter setting
+ if unset */
+ num_probes =
+ (user_scan_in->num_probes ? user_scan_in->
+ num_probes : adapter->scan_probes);
+
+ /*
+ * Set the BSSID filter to the incoming configuration,
+ * if non-zero. If not set, it will remain disabled
+ * (all zeros).
+ */
+ memcpy(scan_cfg_out->specific_bssid,
+ user_scan_in->specific_bssid,
+ sizeof(scan_cfg_out->specific_bssid));
+
+ for (ssid_idx = 0;
+ ((ssid_idx < ARRAY_SIZE(user_scan_in->ssid_list))
+ && (*user_scan_in->ssid_list[ssid_idx].ssid
+ || user_scan_in->ssid_list[ssid_idx].max_len));
+ ssid_idx++) {
+
+ ssid_len = strlen(user_scan_in->ssid_list[ssid_idx].
+ ssid) + 1;
+
+ wildcard_ssid_tlv =
+ (struct mwifiex_ie_types_wildcard_ssid_params *)
+ tlv_pos;
+ wildcard_ssid_tlv->header.type =
+ cpu_to_le16(TLV_TYPE_WILDCARDSSID);
+ wildcard_ssid_tlv->header.len = cpu_to_le16(
+ (u16) (ssid_len + sizeof(wildcard_ssid_tlv->
+ max_ssid_length)));
+ wildcard_ssid_tlv->max_ssid_length =
+ user_scan_in->ssid_list[ssid_idx].max_len;
+
+ memcpy(wildcard_ssid_tlv->ssid,
+ user_scan_in->ssid_list[ssid_idx].ssid,
+ ssid_len);
+
+ tlv_pos += (sizeof(wildcard_ssid_tlv->header)
+ + le16_to_cpu(wildcard_ssid_tlv->header.len));
+
+ dev_dbg(adapter->dev, "info: scan: ssid_list[%d]: %s, %d\n",
+ ssid_idx, wildcard_ssid_tlv->ssid,
+ wildcard_ssid_tlv->max_ssid_length);
+
+ /* Empty wildcard ssid with a maxlen will match many or
+ potentially all SSIDs (maxlen == 32), therefore do
+ not treat the scan as
+ filtered. */
+ if (!ssid_len && wildcard_ssid_tlv->max_ssid_length)
+ ssid_filter = false;
+
+ }
+
+ /*
+ * 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 ((ssid_idx && ssid_filter)
+ || memcmp(scan_cfg_out->specific_bssid, &zero_mac,
+ sizeof(zero_mac)))
+ *filtered_scan = true;
+ } else {
+ scan_cfg_out->bss_mode = (u8) adapter->scan_mode;
+ num_probes = adapter->scan_probes;
+ }
+
+ /*
+ * If a specific BSSID or SSID is used, the number of channels in the
+ * scan command will be increased to the absolute maximum.
+ */
+ if (*filtered_scan)
+ *max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN;
+ else
+ *max_chan_per_scan = MWIFIEX_CHANNELS_PER_SCAN_CMD;
+
+ /* If the input config or adapter has the number of Probes set,
+ add tlv */
+ if (num_probes) {
+
+ dev_dbg(adapter->dev, "info: scan: num_probes = %d\n",
+ num_probes);
+
+ num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos;
+ num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES);
+ num_probes_tlv->header.len =
+ cpu_to_le16(sizeof(num_probes_tlv->num_probes));
+ num_probes_tlv->num_probes = cpu_to_le16((u16) num_probes);
+
+ tlv_pos += sizeof(num_probes_tlv->header) +
+ le16_to_cpu(num_probes_tlv->header.len);
+
+ }
+
+ /* Append rates tlv */
+ memset(rates, 0, sizeof(rates));
+
+ rates_size = mwifiex_get_supported_rates(priv, rates);
+
+ rates_tlv = (struct mwifiex_ie_types_rates_param_set *) tlv_pos;
+ rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
+ rates_tlv->header.len = cpu_to_le16((u16) rates_size);
+ memcpy(rates_tlv->rates, rates, rates_size);
+ tlv_pos += sizeof(rates_tlv->header) + rates_size;
+
+ dev_dbg(adapter->dev, "info: SCAN_CMD: Rates size = %d\n", rates_size);
+
+ if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info)
+ && (priv->adapter->config_bands & BAND_GN
+ || priv->adapter->config_bands & BAND_AN)) {
+ ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos;
+ memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
+ ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
+ ht_cap->header.len =
+ cpu_to_le16(sizeof(struct ieee80211_ht_cap));
+ radio_type =
+ mwifiex_band_to_radio_type(priv->adapter->config_bands);
+ mwifiex_fill_cap_info(priv, radio_type, ht_cap);
+ tlv_pos += sizeof(struct mwifiex_ie_types_htcap);
+ }
+
+ /* Append vendor specific IE TLV */
+ mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_SCAN, &tlv_pos);
+
+ /*
+ * Set the output for the channel TLV to the address in the tlv buffer
+ * past any TLVs that were added in this function (SSID, num_probes).
+ * Channel TLVs will be added past this for each scan command,
+ * preserving the TLVs that were previously added.
+ */
+ *chan_list_out =
+ (struct mwifiex_ie_types_chan_list_param_set *) tlv_pos;
+
+ if (user_scan_in && user_scan_in->chan_list[0].chan_number) {
+
+ dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n");
+
+ for (chan_idx = 0;
+ chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX
+ && user_scan_in->chan_list[chan_idx].chan_number;
+ chan_idx++) {
+
+ channel = user_scan_in->chan_list[chan_idx].chan_number;
+ (scan_chan_list + chan_idx)->chan_number = channel;
+
+ radio_type =
+ user_scan_in->chan_list[chan_idx].radio_type;
+ (scan_chan_list + chan_idx)->radio_type = radio_type;
+
+ scan_type = user_scan_in->chan_list[chan_idx].scan_type;
+
+ if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
+ (scan_chan_list +
+ chan_idx)->chan_scan_mode_bitmap
+ |= MWIFIEX_PASSIVE_SCAN;
+ else
+ (scan_chan_list +
+ chan_idx)->chan_scan_mode_bitmap
+ &= ~MWIFIEX_PASSIVE_SCAN;
+
+ if (user_scan_in->chan_list[chan_idx].scan_time) {
+ scan_dur = (u16) user_scan_in->
+ chan_list[chan_idx].scan_time;
+ } else {
+ if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
+ scan_dur = adapter->passive_scan_time;
+ else if (*filtered_scan)
+ scan_dur = adapter->specific_scan_time;
+ else
+ scan_dur = adapter->active_scan_time;
+ }
+
+ (scan_chan_list + chan_idx)->min_scan_time =
+ cpu_to_le16(scan_dur);
+ (scan_chan_list + chan_idx)->max_scan_time =
+ cpu_to_le16(scan_dur);
+ }
+
+ /* Check if we are only scanning the current channel */
+ if ((chan_idx == 1)
+ && (user_scan_in->chan_list[0].chan_number
+ == priv->curr_bss_params.bss_descriptor.channel)) {
+ *scan_current_only = true;
+ dev_dbg(adapter->dev,
+ "info: Scan: Scanning current channel only\n");
+ }
+
+ } else {
+ dev_dbg(adapter->dev,
+ "info: Scan: Creating full region channel list\n");
+ mwifiex_scan_create_channel_list(priv, user_scan_in,
+ scan_chan_list,
+ *filtered_scan);
+ }
+}
+
+/*
+ * This function inspects the scan response buffer for pointers to
+ * expected TLVs.
+ *
+ * TLVs can be included at the end of the scan response BSS information.
+ *
+ * Data in the buffer is parsed pointers to TLVs that can potentially
+ * be passed back in the response.
+ */
+static void
+mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter,
+ struct mwifiex_ie_types_data *tlv,
+ u32 tlv_buf_size, u32 req_tlv_type,
+ struct mwifiex_ie_types_data **tlv_data)
+{
+ struct mwifiex_ie_types_data *current_tlv;
+ u32 tlv_buf_left;
+ u32 tlv_type;
+ u32 tlv_len;
+
+ current_tlv = tlv;
+ tlv_buf_left = tlv_buf_size;
+ *tlv_data = NULL;
+
+ dev_dbg(adapter->dev, "info: SCAN_RESP: tlv_buf_size = %d\n",
+ tlv_buf_size);
+
+ while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) {
+
+ tlv_type = le16_to_cpu(current_tlv->header.type);
+ tlv_len = le16_to_cpu(current_tlv->header.len);
+
+ if (sizeof(tlv->header) + tlv_len > tlv_buf_left) {
+ dev_err(adapter->dev, "SCAN_RESP: TLV buffer corrupt\n");
+ break;
+ }
+
+ if (req_tlv_type == tlv_type) {
+ switch (tlv_type) {
+ case TLV_TYPE_TSFTIMESTAMP:
+ dev_dbg(adapter->dev, "info: SCAN_RESP: TSF "
+ "timestamp TLV, len = %d\n", tlv_len);
+ *tlv_data = (struct mwifiex_ie_types_data *)
+ current_tlv;
+ break;
+ case TLV_TYPE_CHANNELBANDLIST:
+ dev_dbg(adapter->dev, "info: SCAN_RESP: channel"
+ " band list TLV, len = %d\n", tlv_len);
+ *tlv_data = (struct mwifiex_ie_types_data *)
+ current_tlv;
+ break;
+ default:
+ dev_err(adapter->dev,
+ "SCAN_RESP: unhandled TLV = %d\n",
+ tlv_type);
+ /* Give up, this seems corrupted */
+ return;
+ }
+ }
+
+ if (*tlv_data)
+ break;
+
+
+ tlv_buf_left -= (sizeof(tlv->header) + tlv_len);
+ current_tlv =
+ (struct mwifiex_ie_types_data *) (current_tlv->data +
+ tlv_len);
+
+ } /* while */
+}
+
+/*
+ * This function interprets a BSS scan response returned from the firmware.
+ *
+ * The various fixed fields and IEs are parsed and passed back for a BSS
+ * probe response or beacon from scan command. Information is recorded as
+ * needed in the scan table for that entry.
+ *
+ * The following IE types are recognized and parsed -
+ * - SSID
+ * - Supported rates
+ * - FH parameters set
+ * - DS parameters set
+ * - CF parameters set
+ * - IBSS parameters set
+ * - ERP information
+ * - Extended supported rates
+ * - Vendor specific (221)
+ * - RSN IE
+ * - WAPI IE
+ * - HT capability
+ * - HT operation
+ * - BSS Coexistence 20/40
+ * - Extended capability
+ * - Overlapping BSS scan parameters
+ */
+static int
+mwifiex_interpret_bss_desc_with_ie(struct mwifiex_adapter *adapter,
+ struct mwifiex_bssdescriptor *bss_entry,
+ u8 **beacon_info, u32 *bytes_left)
+{
+ int ret = 0;
+ u8 element_id;
+ struct ieee_types_fh_param_set *fh_param_set;
+ struct ieee_types_ds_param_set *ds_param_set;
+ struct ieee_types_cf_param_set *cf_param_set;
+ struct ieee_types_ibss_param_set *ibss_param_set;
+ __le16 beacon_interval;
+ __le16 capabilities;
+ u8 *current_ptr;
+ u8 *rate;
+ u8 element_len;
+ u16 total_ie_len;
+ u8 bytes_to_copy;
+ u8 rate_size;
+ u16 beacon_size;
+ u8 found_data_rate_ie;
+ u32 bytes_left_for_current_beacon;
+ struct ieee_types_vendor_specific *vendor_ie;
+ const u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 };
+ const u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 };
+
+ found_data_rate_ie = false;
+ rate_size = 0;
+ beacon_size = 0;
+
+ if (*bytes_left >= sizeof(beacon_size)) {
+ /* Extract & convert beacon size from the command buffer */
+ memcpy(&beacon_size, *beacon_info, sizeof(beacon_size));
+ *bytes_left -= sizeof(beacon_size);
+ *beacon_info += sizeof(beacon_size);
+ }
+
+ if (!beacon_size || beacon_size > *bytes_left) {
+ *beacon_info += *bytes_left;
+ *bytes_left = 0;
+ return -1;
+ }
+
+ /* Initialize the current working beacon pointer for this BSS
+ iteration */
+ current_ptr = *beacon_info;
+
+ /* Advance the return beacon pointer past the current beacon */
+ *beacon_info += beacon_size;
+ *bytes_left -= beacon_size;
+
+ bytes_left_for_current_beacon = beacon_size;
+
+ memcpy(bss_entry->mac_address, current_ptr, ETH_ALEN);
+ dev_dbg(adapter->dev, "info: InterpretIE: AP MAC Addr: %pM\n",
+ bss_entry->mac_address);
+
+ current_ptr += ETH_ALEN;
+ bytes_left_for_current_beacon -= ETH_ALEN;
+
+ if (bytes_left_for_current_beacon < 12) {
+ dev_err(adapter->dev, "InterpretIE: not enough bytes left\n");
+ return -1;
+ }
+
+ /*
+ * Next 4 fields are RSSI, time stamp, beacon interval,
+ * and capability information
+ */
+
+ /* RSSI is 1 byte long */
+ bss_entry->rssi = (s32) (*current_ptr);
+ dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", *current_ptr);
+ current_ptr += 1;
+ bytes_left_for_current_beacon -= 1;
+
+ /*
+ * The RSSI is not part of the beacon/probe response. After we have
+ * advanced current_ptr past the RSSI field, save the remaining
+ * data for use at the application layer
+ */
+ bss_entry->beacon_buf = current_ptr;
+ bss_entry->beacon_buf_size = bytes_left_for_current_beacon;
+
+ /* Time stamp is 8 bytes long */
+ memcpy(bss_entry->time_stamp, current_ptr, 8);
+ current_ptr += 8;
+ bytes_left_for_current_beacon -= 8;
+
+ /* Beacon interval is 2 bytes long */
+ memcpy(&beacon_interval, current_ptr, 2);
+ bss_entry->beacon_period = le16_to_cpu(beacon_interval);
+ current_ptr += 2;
+ bytes_left_for_current_beacon -= 2;
+
+ /* Capability information is 2 bytes long */
+ memcpy(&capabilities, current_ptr, 2);
+ dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n",
+ capabilities);
+ bss_entry->cap_info_bitmap = le16_to_cpu(capabilities);
+ current_ptr += 2;
+ bytes_left_for_current_beacon -= 2;
+
+ /* Rest of the current buffer are IE's */
+ dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP = %d\n",
+ bytes_left_for_current_beacon);
+
+ if (bss_entry->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) {
+ dev_dbg(adapter->dev, "info: InterpretIE: AP WEP enabled\n");
+ bss_entry->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
+ } else {
+ bss_entry->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL;
+ }
+
+ if (bss_entry->cap_info_bitmap & WLAN_CAPABILITY_IBSS)
+ bss_entry->bss_mode = NL80211_IFTYPE_ADHOC;
+ else
+ bss_entry->bss_mode = NL80211_IFTYPE_STATION;
+
+
+ /* Process variable IE */
+ while (bytes_left_for_current_beacon >= 2) {
+ element_id = *current_ptr;
+ element_len = *(current_ptr + 1);
+ total_ie_len = element_len + sizeof(struct ieee_types_header);
+
+ if (bytes_left_for_current_beacon < total_ie_len) {
+ dev_err(adapter->dev, "err: InterpretIE: in processing"
+ " IE, bytes left < IE length\n");
+ bytes_left_for_current_beacon = 0;
+ ret = -1;
+ continue;
+ }
+ switch (element_id) {
+ case WLAN_EID_SSID:
+ bss_entry->ssid.ssid_len = element_len;
+ memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
+ element_len);
+ dev_dbg(adapter->dev, "info: InterpretIE: ssid: %-32s\n",
+ bss_entry->ssid.ssid);
+ break;
+
+ case WLAN_EID_SUPP_RATES:
+ memcpy(bss_entry->data_rates, current_ptr + 2,
+ element_len);
+ memcpy(bss_entry->supported_rates, current_ptr + 2,
+ element_len);
+ rate_size = element_len;
+ found_data_rate_ie = true;
+ break;
+
+ case WLAN_EID_FH_PARAMS:
+ fh_param_set =
+ (struct ieee_types_fh_param_set *) current_ptr;
+ memcpy(&bss_entry->phy_param_set.fh_param_set,
+ fh_param_set,
+ sizeof(struct ieee_types_fh_param_set));
+ break;
+
+ case WLAN_EID_DS_PARAMS:
+ ds_param_set =
+ (struct ieee_types_ds_param_set *) current_ptr;
+
+ bss_entry->channel = ds_param_set->current_chan;
+
+ memcpy(&bss_entry->phy_param_set.ds_param_set,
+ ds_param_set,
+ sizeof(struct ieee_types_ds_param_set));
+ break;
+
+ case WLAN_EID_CF_PARAMS:
+ cf_param_set =
+ (struct ieee_types_cf_param_set *) current_ptr;
+ memcpy(&bss_entry->ss_param_set.cf_param_set,
+ cf_param_set,
+ sizeof(struct ieee_types_cf_param_set));
+ break;
+
+ case WLAN_EID_IBSS_PARAMS:
+ ibss_param_set =
+ (struct ieee_types_ibss_param_set *)
+ current_ptr;
+ memcpy(&bss_entry->ss_param_set.ibss_param_set,
+ ibss_param_set,
+ sizeof(struct ieee_types_ibss_param_set));
+ break;
+
+ case WLAN_EID_ERP_INFO:
+ bss_entry->erp_flags = *(current_ptr + 2);
+ break;
+
+ case WLAN_EID_EXT_SUPP_RATES:
+ /*
+ * Only process extended supported rate
+ * if data rate is already found.
+ * Data rate IE should come before
+ * extended supported rate IE
+ */
+ if (found_data_rate_ie) {
+ if ((element_len + rate_size) >
+ MWIFIEX_SUPPORTED_RATES)
+ bytes_to_copy =
+ (MWIFIEX_SUPPORTED_RATES -
+ rate_size);
+ else
+ bytes_to_copy = element_len;
+
+ rate = (u8 *) bss_entry->data_rates;
+ rate += rate_size;
+ memcpy(rate, current_ptr + 2, bytes_to_copy);
+
+ rate = (u8 *) bss_entry->supported_rates;
+ rate += rate_size;
+ memcpy(rate, current_ptr + 2, bytes_to_copy);
+ }
+ break;
+
+ case WLAN_EID_VENDOR_SPECIFIC:
+ vendor_ie = (struct ieee_types_vendor_specific *)
+ current_ptr;
+
+ if (!memcmp
+ (vendor_ie->vend_hdr.oui, wpa_oui,
+ sizeof(wpa_oui))) {
+ bss_entry->bcn_wpa_ie =
+ (struct ieee_types_vendor_specific *)
+ current_ptr;
+ bss_entry->wpa_offset = (u16) (current_ptr -
+ bss_entry->beacon_buf);
+ } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui,
+ sizeof(wmm_oui))) {
+ if (total_ie_len ==
+ sizeof(struct ieee_types_wmm_parameter)
+ || total_ie_len ==
+ sizeof(struct ieee_types_wmm_info))
+ /*
+ * Only accept and copy the WMM IE if
+ * it matches the size expected for the
+ * WMM Info IE or the WMM Parameter IE.
+ */
+ memcpy((u8 *) &bss_entry->wmm_ie,
+ current_ptr, total_ie_len);
+ }
+ break;
+ case WLAN_EID_RSN:
+ bss_entry->bcn_rsn_ie =
+ (struct ieee_types_generic *) current_ptr;
+ bss_entry->rsn_offset = (u16) (current_ptr -
+ bss_entry->beacon_buf);
+ break;
+ case WLAN_EID_BSS_AC_ACCESS_DELAY:
+ bss_entry->bcn_wapi_ie =
+ (struct ieee_types_generic *) current_ptr;
+ bss_entry->wapi_offset = (u16) (current_ptr -
+ bss_entry->beacon_buf);
+ break;
+ case WLAN_EID_HT_CAPABILITY:
+ bss_entry->bcn_ht_cap = (struct ieee80211_ht_cap *)
+ (current_ptr +
+ sizeof(struct ieee_types_header));
+ bss_entry->ht_cap_offset = (u16) (current_ptr +
+ sizeof(struct ieee_types_header) -
+ bss_entry->beacon_buf);
+ break;
+ case WLAN_EID_HT_INFORMATION:
+ bss_entry->bcn_ht_info = (struct ieee80211_ht_info *)
+ (current_ptr +
+ sizeof(struct ieee_types_header));
+ bss_entry->ht_info_offset = (u16) (current_ptr +
+ sizeof(struct ieee_types_header) -
+ bss_entry->beacon_buf);
+ break;
+ case WLAN_EID_BSS_COEX_2040:
+ bss_entry->bcn_bss_co_2040 = (u8 *) (current_ptr +
+ sizeof(struct ieee_types_header));
+ bss_entry->bss_co_2040_offset = (u16) (current_ptr +
+ sizeof(struct ieee_types_header) -
+ bss_entry->beacon_buf);
+ break;
+ case WLAN_EID_EXT_CAPABILITY:
+ bss_entry->bcn_ext_cap = (u8 *) (current_ptr +
+ sizeof(struct ieee_types_header));
+ bss_entry->ext_cap_offset = (u16) (current_ptr +
+ sizeof(struct ieee_types_header) -
+ bss_entry->beacon_buf);
+ break;
+ case WLAN_EID_OVERLAP_BSS_SCAN_PARAM:
+ bss_entry->bcn_obss_scan =
+ (struct ieee_types_obss_scan_param *)
+ current_ptr;
+ bss_entry->overlap_bss_offset = (u16) (current_ptr -
+ bss_entry->beacon_buf);
+ break;
+ default:
+ break;
+ }
+
+ current_ptr += element_len + 2;
+
+ /* Need to account for IE ID and IE Len */
+ bytes_left_for_current_beacon -= (element_len + 2);
+
+ } /* while (bytes_left_for_current_beacon > 2) */
+ return ret;
+}
+
+/*
+ * This function adjusts the pointers used in beacon buffers to reflect
+ * shifts.
+ *
+ * The memory allocated for beacon buffers is of fixed sizes where all the
+ * saved beacons must be stored. New beacons are added in the free portion
+ * of this memory, space permitting; while duplicate beacon buffers are
+ * placed at the same start location. However, since duplicate beacon
+ * buffers may not match the size of the old one, all the following buffers
+ * in the memory must be shifted to either make space, or to fill up freed
+ * up space.
+ *
+ * This function is used to update the beacon buffer pointers that are past
+ * an existing beacon buffer that is updated with a new one of different
+ * size. The pointers are shifted by a fixed amount, either forward or
+ * backward.
+ *
+ * the following pointers in every affected beacon buffers are changed, if
+ * present -
+ * - WPA IE pointer
+ * - RSN IE pointer
+ * - WAPI IE pointer
+ * - HT capability IE pointer
+ * - HT information IE pointer
+ * - BSS coexistence 20/40 IE pointer
+ * - Extended capability IE pointer
+ * - Overlapping BSS scan parameter IE pointer
+ */
+static void
+mwifiex_adjust_beacon_buffer_ptrs(struct mwifiex_private *priv, u8 advance,
+ u8 *bcn_store, u32 rem_bcn_size,
+ u32 num_of_ent)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ u32 adj_idx;
+ for (adj_idx = 0; adj_idx < num_of_ent; adj_idx++) {
+ if (adapter->scan_table[adj_idx].beacon_buf > bcn_store) {
+
+ if (advance)
+ adapter->scan_table[adj_idx].beacon_buf +=
+ rem_bcn_size;
+ else
+ adapter->scan_table[adj_idx].beacon_buf -=
+ rem_bcn_size;
+
+ if (adapter->scan_table[adj_idx].bcn_wpa_ie)
+ adapter->scan_table[adj_idx].bcn_wpa_ie =
+ (struct ieee_types_vendor_specific *)
+ (adapter->scan_table[adj_idx].beacon_buf +
+ adapter->scan_table[adj_idx].wpa_offset);
+ if (adapter->scan_table[adj_idx].bcn_rsn_ie)
+ adapter->scan_table[adj_idx].bcn_rsn_ie =
+ (struct ieee_types_generic *)
+ (adapter->scan_table[adj_idx].beacon_buf +
+ adapter->scan_table[adj_idx].rsn_offset);
+ if (adapter->scan_table[adj_idx].bcn_wapi_ie)
+ adapter->scan_table[adj_idx].bcn_wapi_ie =
+ (struct ieee_types_generic *)
+ (adapter->scan_table[adj_idx].beacon_buf +
+ adapter->scan_table[adj_idx].wapi_offset);
+ if (adapter->scan_table[adj_idx].bcn_ht_cap)
+ adapter->scan_table[adj_idx].bcn_ht_cap =
+ (struct ieee80211_ht_cap *)
+ (adapter->scan_table[adj_idx].beacon_buf +
+ adapter->scan_table[adj_idx].ht_cap_offset);
+
+ if (adapter->scan_table[adj_idx].bcn_ht_info)
+ adapter->scan_table[adj_idx].bcn_ht_info =
+ (struct ieee80211_ht_info *)
+ (adapter->scan_table[adj_idx].beacon_buf +
+ adapter->scan_table[adj_idx].ht_info_offset);
+ if (adapter->scan_table[adj_idx].bcn_bss_co_2040)
+ adapter->scan_table[adj_idx].bcn_bss_co_2040 =
+ (u8 *)
+ (adapter->scan_table[adj_idx].beacon_buf +
+ adapter->scan_table[adj_idx].bss_co_2040_offset);
+ if (adapter->scan_table[adj_idx].bcn_ext_cap)
+ adapter->scan_table[adj_idx].bcn_ext_cap =
+ (u8 *)
+ (adapter->scan_table[adj_idx].beacon_buf +
+ adapter->scan_table[adj_idx].ext_cap_offset);
+ if (adapter->scan_table[adj_idx].bcn_obss_scan)
+ adapter->scan_table[adj_idx].bcn_obss_scan =
+ (struct ieee_types_obss_scan_param *)
+ (adapter->scan_table[adj_idx].beacon_buf +
+ adapter->scan_table[adj_idx].overlap_bss_offset);
+ }
+ }
+}
+
+/*
+ * This function updates the pointers used in beacon buffer for given bss
+ * descriptor to reflect shifts
+ *
+ * Following pointers are updated
+ * - WPA IE pointer
+ * - RSN IE pointer
+ * - WAPI IE pointer
+ * - HT capability IE pointer
+ * - HT information IE pointer
+ * - BSS coexistence 20/40 IE pointer
+ * - Extended capability IE pointer
+ * - Overlapping BSS scan parameter IE pointer
+ */
+static void
+mwifiex_update_beacon_buffer_ptrs(struct mwifiex_bssdescriptor *beacon)
+{
+ if (beacon->bcn_wpa_ie)
+ beacon->bcn_wpa_ie = (struct ieee_types_vendor_specific *)
+ (beacon->beacon_buf + beacon->wpa_offset);
+ if (beacon->bcn_rsn_ie)
+ beacon->bcn_rsn_ie = (struct ieee_types_generic *)
+ (beacon->beacon_buf + beacon->rsn_offset);
+ if (beacon->bcn_wapi_ie)
+ beacon->bcn_wapi_ie = (struct ieee_types_generic *)
+ (beacon->beacon_buf + beacon->wapi_offset);
+ if (beacon->bcn_ht_cap)
+ beacon->bcn_ht_cap = (struct ieee80211_ht_cap *)
+ (beacon->beacon_buf + beacon->ht_cap_offset);
+ if (beacon->bcn_ht_info)
+ beacon->bcn_ht_info = (struct ieee80211_ht_info *)
+ (beacon->beacon_buf + beacon->ht_info_offset);
+ if (beacon->bcn_bss_co_2040)
+ beacon->bcn_bss_co_2040 = (u8 *) (beacon->beacon_buf +
+ beacon->bss_co_2040_offset);
+ if (beacon->bcn_ext_cap)
+ beacon->bcn_ext_cap = (u8 *) (beacon->beacon_buf +
+ beacon->ext_cap_offset);
+ if (beacon->bcn_obss_scan)
+ beacon->bcn_obss_scan = (struct ieee_types_obss_scan_param *)
+ (beacon->beacon_buf + beacon->overlap_bss_offset);
+}
+
+/*
+ * This function stores a beacon or probe response for a BSS returned
+ * in the scan.
+ *
+ * This stores a new scan response or an update for a previous scan response.
+ * New entries need to verify that they do not exceed the total amount of
+ * memory allocated for the table.
+ *
+ * Replacement entries need to take into consideration the amount of space
+ * currently allocated for the beacon/probe response and adjust the entry
+ * as needed.
+ *
+ * A small amount of extra pad (SCAN_BEACON_ENTRY_PAD) is generally reserved
+ * for an entry in case it is a beacon since a probe response for the
+ * network will by larger per the standard. This helps to reduce the
+ * amount of memory copying to fit a new probe response into an entry
+ * already occupied by a network's previously stored beacon.
+ */
+static void
+mwifiex_ret_802_11_scan_store_beacon(struct mwifiex_private *priv,
+ u32 beacon_idx, u32 num_of_ent,
+ struct mwifiex_bssdescriptor *new_beacon)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ u8 *bcn_store;
+ u32 new_bcn_size;
+ u32 old_bcn_size;
+ u32 bcn_space;
+
+ if (adapter->scan_table[beacon_idx].beacon_buf) {
+
+ new_bcn_size = new_beacon->beacon_buf_size;
+ old_bcn_size = adapter->scan_table[beacon_idx].beacon_buf_size;
+ bcn_space = adapter->scan_table[beacon_idx].beacon_buf_size_max;
+ bcn_store = adapter->scan_table[beacon_idx].beacon_buf;
+
+ /* Set the max to be the same as current entry unless changed
+ below */
+ new_beacon->beacon_buf_size_max = bcn_space;
+ if (new_bcn_size == old_bcn_size) {
+ /*
+ * Beacon is the same size as the previous entry.
+ * Replace the previous contents with the scan result
+ */
+ memcpy(bcn_store, new_beacon->beacon_buf,
+ new_beacon->beacon_buf_size);
+
+ } else if (new_bcn_size <= bcn_space) {
+ /*
+ * New beacon size will fit in the amount of space
+ * we have previously allocated for it
+ */
+
+ /* Copy the new beacon buffer entry over the old one */
+ memcpy(bcn_store, new_beacon->beacon_buf, new_bcn_size);
+
+ /*
+ * If the old beacon size was less than the maximum
+ * we had alloted for the entry, and the new entry
+ * is even smaller, reset the max size to the old
+ * beacon entry and compress the storage space
+ * (leaving a new pad space of (old_bcn_size -
+ * new_bcn_size).
+ */
+ if (old_bcn_size < bcn_space
+ && new_bcn_size <= old_bcn_size) {
+ /*
+ * Old Beacon size is smaller than the alloted
+ * storage size. Shrink the alloted storage
+ * space.
+ */
+ dev_dbg(adapter->dev, "info: AppControl:"
+ " smaller duplicate beacon "
+ "(%d), old = %d, new = %d, space = %d,"
+ "left = %d\n",
+ beacon_idx, old_bcn_size, new_bcn_size,
+ bcn_space,
+ (int)(sizeof(adapter->bcn_buf) -
+ (adapter->bcn_buf_end -
+ adapter->bcn_buf)));
+
+ /*
+ * memmove (since the memory overlaps) the
+ * data after the beacon we just stored to the
+ * end of the current beacon. This cleans up
+ * any unused space the old larger beacon was
+ * using in the buffer
+ */
+ memmove(bcn_store + old_bcn_size,
+ bcn_store + bcn_space,
+ adapter->bcn_buf_end - (bcn_store +
+ bcn_space));
+
+ /*
+ * Decrement the end pointer by the difference
+ * between the old larger size and the new
+ * smaller size since we are using less space
+ * due to the new beacon being smaller
+ */
+ adapter->bcn_buf_end -=
+ (bcn_space - old_bcn_size);
+
+ /* Set the maximum storage size to the old
+ beacon size */
+ new_beacon->beacon_buf_size_max = old_bcn_size;
+
+ /* Adjust beacon buffer pointers that are past
+ the current */
+ mwifiex_adjust_beacon_buffer_ptrs(priv, 0,
+ bcn_store, (bcn_space - old_bcn_size),
+ num_of_ent);
+ }
+ } else if (adapter->bcn_buf_end + (new_bcn_size - bcn_space)
+ < (adapter->bcn_buf + sizeof(adapter->bcn_buf))) {
+ /*
+ * Beacon is larger than space previously allocated
+ * (bcn_space) and there is enough space left in the
+ * beaconBuffer to store the additional data
+ */
+ dev_dbg(adapter->dev, "info: AppControl:"
+ " larger duplicate beacon (%d), "
+ "old = %d, new = %d, space = %d, left = %d\n",
+ beacon_idx, old_bcn_size, new_bcn_size,
+ bcn_space,
+ (int)(sizeof(adapter->bcn_buf) -
+ (adapter->bcn_buf_end -
+ adapter->bcn_buf)));
+
+ /*
+ * memmove (since the memory overlaps) the data
+ * after the beacon we just stored to the end of
+ * the current beacon. This moves the data for
+ * the beacons after this further in memory to
+ * make space for the new larger beacon we are
+ * about to copy in.
+ */
+ memmove(bcn_store + new_bcn_size,
+ bcn_store + bcn_space,
+ adapter->bcn_buf_end - (bcn_store + bcn_space));
+
+ /* Copy the new beacon buffer entry over the old one */
+ memcpy(bcn_store, new_beacon->beacon_buf, new_bcn_size);
+
+ /* Move the beacon end pointer by the amount of new
+ beacon data we are adding */
+ adapter->bcn_buf_end += (new_bcn_size - bcn_space);
+
+ /*
+ * This entry is bigger than the alloted max space
+ * previously reserved. Increase the max space to
+ * be equal to the new beacon size
+ */
+ new_beacon->beacon_buf_size_max = new_bcn_size;
+
+ /* Adjust beacon buffer pointers that are past the
+ current */
+ mwifiex_adjust_beacon_buffer_ptrs(priv, 1, bcn_store,
+ (new_bcn_size - bcn_space),
+ num_of_ent);
+ } else {
+ /*
+ * Beacon is larger than the previously allocated space,
+ * but there is not enough free space to store the
+ * additional data.
+ */
+ dev_err(adapter->dev, "AppControl: larger duplicate "
+ " beacon (%d), old = %d new = %d, space = %d,"
+ " left = %d\n", beacon_idx, old_bcn_size,
+ new_bcn_size, bcn_space,
+ (int)(sizeof(adapter->bcn_buf) -
+ (adapter->bcn_buf_end - adapter->bcn_buf)));
+
+ /* Storage failure, keep old beacon intact */
+ new_beacon->beacon_buf_size = old_bcn_size;
+ if (new_beacon->bcn_wpa_ie)
+ new_beacon->wpa_offset =
+ adapter->scan_table[beacon_idx].
+ wpa_offset;
+ if (new_beacon->bcn_rsn_ie)
+ new_beacon->rsn_offset =
+ adapter->scan_table[beacon_idx].
+ rsn_offset;
+ if (new_beacon->bcn_wapi_ie)
+ new_beacon->wapi_offset =
+ adapter->scan_table[beacon_idx].
+ wapi_offset;
+ if (new_beacon->bcn_ht_cap)
+ new_beacon->ht_cap_offset =
+ adapter->scan_table[beacon_idx].
+ ht_cap_offset;
+ if (new_beacon->bcn_ht_info)
+ new_beacon->ht_info_offset =
+ adapter->scan_table[beacon_idx].
+ ht_info_offset;
+ if (new_beacon->bcn_bss_co_2040)
+ new_beacon->bss_co_2040_offset =
+ adapter->scan_table[beacon_idx].
+ bss_co_2040_offset;
+ if (new_beacon->bcn_ext_cap)
+ new_beacon->ext_cap_offset =
+ adapter->scan_table[beacon_idx].
+ ext_cap_offset;
+ if (new_beacon->bcn_obss_scan)
+ new_beacon->overlap_bss_offset =
+ adapter->scan_table[beacon_idx].
+ overlap_bss_offset;
+ }
+ /* Point the new entry to its permanent storage space */
+ new_beacon->beacon_buf = bcn_store;
+ mwifiex_update_beacon_buffer_ptrs(new_beacon);
+ } else {
+ /*
+ * No existing beacon data exists for this entry, check to see
+ * if we can fit it in the remaining space
+ */
+ if (adapter->bcn_buf_end + new_beacon->beacon_buf_size +
+ SCAN_BEACON_ENTRY_PAD < (adapter->bcn_buf +
+ sizeof(adapter->bcn_buf))) {
+
+ /*
+ * Copy the beacon buffer data from the local entry to
+ * the adapter dev struct buffer space used to store
+ * the raw beacon data for each entry in the scan table
+ */
+ memcpy(adapter->bcn_buf_end, new_beacon->beacon_buf,
+ new_beacon->beacon_buf_size);
+
+ /* Update the beacon ptr to point to the table save
+ area */
+ new_beacon->beacon_buf = adapter->bcn_buf_end;
+ new_beacon->beacon_buf_size_max =
+ (new_beacon->beacon_buf_size +
+ SCAN_BEACON_ENTRY_PAD);
+
+ mwifiex_update_beacon_buffer_ptrs(new_beacon);
+
+ /* Increment the end pointer by the size reserved */
+ adapter->bcn_buf_end += new_beacon->beacon_buf_size_max;
+
+ dev_dbg(adapter->dev, "info: AppControl: beacon[%02d]"
+ " sz=%03d, used = %04d, left = %04d\n",
+ beacon_idx,
+ new_beacon->beacon_buf_size,
+ (int)(adapter->bcn_buf_end - adapter->bcn_buf),
+ (int)(sizeof(adapter->bcn_buf) -
+ (adapter->bcn_buf_end -
+ adapter->bcn_buf)));
+ } else {
+ /* No space for new beacon */
+ dev_dbg(adapter->dev, "info: AppControl: no space for"
+ " beacon (%d): %pM sz=%03d, left=%03d\n",
+ beacon_idx, new_beacon->mac_address,
+ new_beacon->beacon_buf_size,
+ (int)(sizeof(adapter->bcn_buf) -
+ (adapter->bcn_buf_end -
+ adapter->bcn_buf)));
+
+ /* Storage failure; clear storage records for this
+ bcn */
+ new_beacon->beacon_buf = NULL;
+ new_beacon->beacon_buf_size = 0;
+ new_beacon->beacon_buf_size_max = 0;
+ new_beacon->bcn_wpa_ie = NULL;
+ new_beacon->wpa_offset = 0;
+ new_beacon->bcn_rsn_ie = NULL;
+ new_beacon->rsn_offset = 0;
+ new_beacon->bcn_wapi_ie = NULL;
+ new_beacon->wapi_offset = 0;
+ new_beacon->bcn_ht_cap = NULL;
+ new_beacon->ht_cap_offset = 0;
+ new_beacon->bcn_ht_info = NULL;
+ new_beacon->ht_info_offset = 0;
+ new_beacon->bcn_bss_co_2040 = NULL;
+ new_beacon->bss_co_2040_offset = 0;
+ new_beacon->bcn_ext_cap = NULL;
+ new_beacon->ext_cap_offset = 0;
+ new_beacon->bcn_obss_scan = NULL;
+ new_beacon->overlap_bss_offset = 0;
+ }
+ }
+}
+
+/*
+ * This function restores a beacon buffer of the current BSS descriptor.
+ */
+static void mwifiex_restore_curr_bcn(struct mwifiex_private *priv)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct mwifiex_bssdescriptor *curr_bss =
+ &priv->curr_bss_params.bss_descriptor;
+ unsigned long flags;
+
+ if (priv->curr_bcn_buf &&
+ ((adapter->bcn_buf_end + priv->curr_bcn_size) <
+ (adapter->bcn_buf + sizeof(adapter->bcn_buf)))) {
+ spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags);
+
+ /* restore the current beacon buffer */
+ memcpy(adapter->bcn_buf_end, priv->curr_bcn_buf,
+ priv->curr_bcn_size);
+ curr_bss->beacon_buf = adapter->bcn_buf_end;
+ curr_bss->beacon_buf_size = priv->curr_bcn_size;
+ adapter->bcn_buf_end += priv->curr_bcn_size;
+
+ /* adjust the pointers in the current BSS descriptor */
+ if (curr_bss->bcn_wpa_ie)
+ curr_bss->bcn_wpa_ie =
+ (struct ieee_types_vendor_specific *)
+ (curr_bss->beacon_buf +
+ curr_bss->wpa_offset);
+
+ if (curr_bss->bcn_rsn_ie)
+ curr_bss->bcn_rsn_ie = (struct ieee_types_generic *)
+ (curr_bss->beacon_buf +
+ curr_bss->rsn_offset);
+
+ if (curr_bss->bcn_ht_cap)
+ curr_bss->bcn_ht_cap = (struct ieee80211_ht_cap *)
+ (curr_bss->beacon_buf +
+ curr_bss->ht_cap_offset);
+
+ if (curr_bss->bcn_ht_info)
+ curr_bss->bcn_ht_info = (struct ieee80211_ht_info *)
+ (curr_bss->beacon_buf +
+ curr_bss->ht_info_offset);
+
+ if (curr_bss->bcn_bss_co_2040)
+ curr_bss->bcn_bss_co_2040 =
+ (u8 *) (curr_bss->beacon_buf +
+ curr_bss->bss_co_2040_offset);
+
+ if (curr_bss->bcn_ext_cap)
+ curr_bss->bcn_ext_cap = (u8 *) (curr_bss->beacon_buf +
+ curr_bss->ext_cap_offset);
+
+ if (curr_bss->bcn_obss_scan)
+ curr_bss->bcn_obss_scan =
+ (struct ieee_types_obss_scan_param *)
+ (curr_bss->beacon_buf +
+ curr_bss->overlap_bss_offset);
+
+ spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
+
+ dev_dbg(adapter->dev, "info: current beacon restored %d\n",
+ priv->curr_bcn_size);
+ } else {
+ dev_warn(adapter->dev,
+ "curr_bcn_buf not saved or bcn_buf has no space\n");
+ }
+}
+
+/*
+ * This function post processes the scan table after a new scan command has
+ * completed.
+ *
+ * It inspects each entry of the scan table and tries to find an entry that
+ * matches with our current associated/joined network from the scan. If
+ * one is found, the stored copy of the BSS descriptor of our current network
+ * is updated.
+ *
+ * It also debug dumps the current scan table contents after processing is over.
+ */
+static void
+mwifiex_process_scan_results(struct mwifiex_private *priv)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ s32 j;
+ u32 i;
+ unsigned long flags;
+
+ if (priv->media_connected) {
+
+ j = mwifiex_find_ssid_in_list(priv, &priv->curr_bss_params.
+ bss_descriptor.ssid,
+ priv->curr_bss_params.
+ bss_descriptor.mac_address,
+ priv->bss_mode);
+
+ if (j >= 0) {
+ spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags);
+ priv->curr_bss_params.bss_descriptor.bcn_wpa_ie = NULL;
+ priv->curr_bss_params.bss_descriptor.wpa_offset = 0;
+ priv->curr_bss_params.bss_descriptor.bcn_rsn_ie = NULL;
+ priv->curr_bss_params.bss_descriptor.rsn_offset = 0;
+ priv->curr_bss_params.bss_descriptor.bcn_wapi_ie = NULL;
+ priv->curr_bss_params.bss_descriptor.wapi_offset = 0;
+ priv->curr_bss_params.bss_descriptor.bcn_ht_cap = NULL;
+ priv->curr_bss_params.bss_descriptor.ht_cap_offset =
+ 0;
+ priv->curr_bss_params.bss_descriptor.bcn_ht_info = NULL;
+ priv->curr_bss_params.bss_descriptor.ht_info_offset =
+ 0;
+ priv->curr_bss_params.bss_descriptor.bcn_bss_co_2040 =
+ NULL;
+ priv->curr_bss_params.bss_descriptor.
+ bss_co_2040_offset = 0;
+ priv->curr_bss_params.bss_descriptor.bcn_ext_cap = NULL;
+ priv->curr_bss_params.bss_descriptor.ext_cap_offset = 0;
+ priv->curr_bss_params.bss_descriptor.
+ bcn_obss_scan = NULL;
+ priv->curr_bss_params.bss_descriptor.
+ overlap_bss_offset = 0;
+ priv->curr_bss_params.bss_descriptor.beacon_buf = NULL;
+ priv->curr_bss_params.bss_descriptor.beacon_buf_size =
+ 0;
+ priv->curr_bss_params.bss_descriptor.
+ beacon_buf_size_max = 0;
+
+ dev_dbg(adapter->dev, "info: Found current ssid/bssid"
+ " in list @ index #%d\n", j);
+ /* Make a copy of current BSSID descriptor */
+ memcpy(&priv->curr_bss_params.bss_descriptor,
+ &adapter->scan_table[j],
+ sizeof(priv->curr_bss_params.bss_descriptor));
+
+ mwifiex_save_curr_bcn(priv);
+ spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
+
+ } else {
+ mwifiex_restore_curr_bcn(priv);
+ }
+ }
+
+ for (i = 0; i < adapter->num_in_scan_table; i++)
+ dev_dbg(adapter->dev, "info: scan:(%02d) %pM "
+ "RSSI[%03d], SSID[%s]\n",
+ i, adapter->scan_table[i].mac_address,
+ (s32) adapter->scan_table[i].rssi,
+ adapter->scan_table[i].ssid.ssid);
+}
+
+/*
+ * This function converts radio type scan parameter to a band configuration
+ * to be used in join command.
+ */
+static u8
+mwifiex_radio_type_to_band(u8 radio_type)
+{
+ switch (radio_type) {
+ case HostCmd_SCAN_RADIO_TYPE_A:
+ return BAND_A;
+ case HostCmd_SCAN_RADIO_TYPE_BG:
+ default:
+ return BAND_G;
+ }
+}
+
+/*
+ * This function deletes a specific indexed entry from the scan table.
+ *
+ * This also compacts the remaining entries and adjusts any buffering
+ * of beacon/probe response data if needed.
+ */
+static void
+mwifiex_scan_delete_table_entry(struct mwifiex_private *priv, s32 table_idx)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ u32 del_idx;
+ u32 beacon_buf_adj;
+ u8 *beacon_buf;
+
+ /*
+ * Shift the saved beacon buffer data for the scan table back over the
+ * entry being removed. Update the end of buffer pointer. Save the
+ * deleted buffer allocation size for pointer adjustments for entries
+ * compacted after the deleted index.
+ */
+ beacon_buf_adj = adapter->scan_table[table_idx].beacon_buf_size_max;
+
+ dev_dbg(adapter->dev, "info: Scan: Delete Entry %d, beacon buffer "
+ "removal = %d bytes\n", table_idx, beacon_buf_adj);
+
+ /* Check if the table entry had storage allocated for its beacon */
+ if (beacon_buf_adj) {
+ beacon_buf = adapter->scan_table[table_idx].beacon_buf;
+
+ /*
+ * Remove the entry's buffer space, decrement the table end
+ * pointer by the amount we are removing
+ */
+ adapter->bcn_buf_end -= beacon_buf_adj;
+
+ dev_dbg(adapter->dev, "info: scan: delete entry %d,"
+ " compact data: %p <- %p (sz = %d)\n",
+ table_idx, beacon_buf,
+ beacon_buf + beacon_buf_adj,
+ (int)(adapter->bcn_buf_end - beacon_buf));
+
+ /*
+ * Compact data storage. Copy all data after the deleted
+ * entry's end address (beacon_buf + beacon_buf_adj) back
+ * to the original start address (beacon_buf).
+ *
+ * Scan table entries affected by the move will have their
+ * entry pointer adjusted below.
+ *
+ * Use memmove since the dest/src memory regions overlap.
+ */
+ memmove(beacon_buf, beacon_buf + beacon_buf_adj,
+ adapter->bcn_buf_end - beacon_buf);
+ }
+
+ dev_dbg(adapter->dev,
+ "info: Scan: Delete Entry %d, num_in_scan_table = %d\n",
+ table_idx, adapter->num_in_scan_table);
+
+ /* Shift all of the entries after the table_idx back by one, compacting
+ the table and removing the requested entry */
+ for (del_idx = table_idx; (del_idx + 1) < adapter->num_in_scan_table;
+ del_idx++) {
+ /* Copy the next entry over this one */
+ memcpy(adapter->scan_table + del_idx,
+ adapter->scan_table + del_idx + 1,
+ sizeof(struct mwifiex_bssdescriptor));
+
+ /*
+ * Adjust this entry's pointer to its beacon buffer based on
+ * the removed/compacted entry from the deleted index. Don't
+ * decrement if the buffer pointer is NULL (no data stored for
+ * this entry).
+ */
+ if (adapter->scan_table[del_idx].beacon_buf) {
+ adapter->scan_table[del_idx].beacon_buf -=
+ beacon_buf_adj;
+ if (adapter->scan_table[del_idx].bcn_wpa_ie)
+ adapter->scan_table[del_idx].bcn_wpa_ie =
+ (struct ieee_types_vendor_specific *)
+ (adapter->scan_table[del_idx].
+ beacon_buf +
+ adapter->scan_table[del_idx].
+ wpa_offset);
+ if (adapter->scan_table[del_idx].bcn_rsn_ie)
+ adapter->scan_table[del_idx].bcn_rsn_ie =
+ (struct ieee_types_generic *)
+ (adapter->scan_table[del_idx].
+ beacon_buf +
+ adapter->scan_table[del_idx].
+ rsn_offset);
+ if (adapter->scan_table[del_idx].bcn_wapi_ie)
+ adapter->scan_table[del_idx].bcn_wapi_ie =
+ (struct ieee_types_generic *)
+ (adapter->scan_table[del_idx].beacon_buf
+ + adapter->scan_table[del_idx].
+ wapi_offset);
+ if (adapter->scan_table[del_idx].bcn_ht_cap)
+ adapter->scan_table[del_idx].bcn_ht_cap =
+ (struct ieee80211_ht_cap *)
+ (adapter->scan_table[del_idx].beacon_buf
+ + adapter->scan_table[del_idx].
+ ht_cap_offset);
+
+ if (adapter->scan_table[del_idx].bcn_ht_info)
+ adapter->scan_table[del_idx].bcn_ht_info =
+ (struct ieee80211_ht_info *)
+ (adapter->scan_table[del_idx].beacon_buf
+ + adapter->scan_table[del_idx].
+ ht_info_offset);
+ if (adapter->scan_table[del_idx].bcn_bss_co_2040)
+ adapter->scan_table[del_idx].bcn_bss_co_2040 =
+ (u8 *)
+ (adapter->scan_table[del_idx].beacon_buf
+ + adapter->scan_table[del_idx].
+ bss_co_2040_offset);
+ if (adapter->scan_table[del_idx].bcn_ext_cap)
+ adapter->scan_table[del_idx].bcn_ext_cap =
+ (u8 *)
+ (adapter->scan_table[del_idx].beacon_buf
+ + adapter->scan_table[del_idx].
+ ext_cap_offset);
+ if (adapter->scan_table[del_idx].bcn_obss_scan)
+ adapter->scan_table[del_idx].
+ bcn_obss_scan =
+ (struct ieee_types_obss_scan_param *)
+ (adapter->scan_table[del_idx].beacon_buf
+ + adapter->scan_table[del_idx].
+ overlap_bss_offset);
+ }
+ }
+
+ /* The last entry is invalid now that it has been deleted or moved
+ back */
+ memset(adapter->scan_table + adapter->num_in_scan_table - 1,
+ 0x00, sizeof(struct mwifiex_bssdescriptor));
+
+ adapter->num_in_scan_table--;
+}
+
+/*
+ * This function deletes all occurrences of a given SSID from the scan table.
+ *
+ * This iterates through the scan table and deletes all entries that match
+ * the given SSID. It also compacts the remaining scan table entries.
+ */
+static int
+mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv,
+ struct mwifiex_802_11_ssid *del_ssid)
+{
+ s32 table_idx = -1;
+
+ dev_dbg(priv->adapter->dev, "info: scan: delete ssid entry: %-32s\n",
+ del_ssid->ssid);
+
+ /* If the requested SSID is found in the table, delete it. Then keep
+ searching the table for multiple entires for the SSID until no
+ more are found */
+ while ((table_idx = mwifiex_find_ssid_in_list(priv, del_ssid, NULL,
+ NL80211_IFTYPE_UNSPECIFIED)) >= 0) {
+ dev_dbg(priv->adapter->dev,
+ "info: Scan: Delete SSID Entry: Found Idx = %d\n",
+ table_idx);
+ mwifiex_scan_delete_table_entry(priv, table_idx);
+ }
+
+ return table_idx == -1 ? -1 : 0;
+}
+
+/*
+ * This is an internal function used to start a scan based on an input
+ * configuration.
+ *
+ * This uses the input user scan configuration information when provided in
+ * order to send the appropriate scan commands to firmware to populate or
+ * update the internal driver scan table.
+ */
+int mwifiex_scan_networks(struct mwifiex_private *priv,
+ const struct mwifiex_user_scan_cfg *user_scan_in)
+{
+ int ret = 0;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct cmd_ctrl_node *cmd_node;
+ union mwifiex_scan_cmd_config_tlv *scan_cfg_out;
+ struct mwifiex_ie_types_chan_list_param_set *chan_list_out;
+ u32 buf_size;
+ struct mwifiex_chan_scan_param_set *scan_chan_list;
+ u8 keep_previous_scan;
+ u8 filtered_scan;
+ u8 scan_current_chan_only;
+ u8 max_chan_per_scan;
+ unsigned long flags;
+
+ if (adapter->scan_processing) {
+ dev_dbg(adapter->dev, "cmd: Scan already in process...\n");
+ return ret;
+ }
+
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ adapter->scan_processing = true;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+
+ if (priv->scan_block) {
+ dev_dbg(adapter->dev,
+ "cmd: Scan is blocked during association...\n");
+ return ret;
+ }
+
+ scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv),
+ GFP_KERNEL);
+ if (!scan_cfg_out) {
+ dev_err(adapter->dev, "failed to alloc scan_cfg_out\n");
+ return -ENOMEM;
+ }
+
+ buf_size = sizeof(struct mwifiex_chan_scan_param_set) *
+ MWIFIEX_USER_SCAN_CHAN_MAX;
+ scan_chan_list = kzalloc(buf_size, GFP_KERNEL);
+ if (!scan_chan_list) {
+ dev_err(adapter->dev, "failed to alloc scan_chan_list\n");
+ kfree(scan_cfg_out);
+ return -ENOMEM;
+ }
+
+ keep_previous_scan = false;
+
+ mwifiex_scan_setup_scan_config(priv, user_scan_in,
+ &scan_cfg_out->config, &chan_list_out,
+ scan_chan_list, &max_chan_per_scan,
+ &filtered_scan, &scan_current_chan_only);
+
+ if (user_scan_in)
+ keep_previous_scan = user_scan_in->keep_previous_scan;
+
+
+ if (!keep_previous_scan) {
+ memset(adapter->scan_table, 0x00,
+ sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP);
+ adapter->num_in_scan_table = 0;
+ adapter->bcn_buf_end = adapter->bcn_buf;
+ }
+
+ ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan,
+ &scan_cfg_out->config, chan_list_out,
+ scan_chan_list);
+
+ /* Get scan command from scan_pending_q and put to cmd_pending_q */
+ if (!ret) {
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ if (!list_empty(&adapter->scan_pending_q)) {
+ cmd_node = list_first_entry(&adapter->scan_pending_q,
+ struct cmd_ctrl_node, list);
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+ flags);
+ mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
+ true);
+ } else {
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+ flags);
+ }
+ } else {
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ adapter->scan_processing = true;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+ }
+
+ kfree(scan_cfg_out);
+ kfree(scan_chan_list);
+ return ret;
+}
+
+/*
+ * This function prepares a scan command to be sent to the firmware.
+ *
+ * This uses the scan command configuration sent to the command processing
+ * module in command preparation stage to configure a scan command structure
+ * to send to firmware.
+ *
+ * The fixed fields specifying the BSS type and BSSID filters as well as a
+ * variable number/length of TLVs are sent in the command to firmware.
+ *
+ * Preparation also includes -
+ * - Setting command ID, and proper size
+ * - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, void *data_buf)
+{
+ struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan;
+ struct mwifiex_scan_cmd_config *scan_cfg;
+
+ scan_cfg = (struct mwifiex_scan_cmd_config *) data_buf;
+
+ /* Set fixed field variables in scan command */
+ scan_cmd->bss_mode = scan_cfg->bss_mode;
+ memcpy(scan_cmd->bssid, scan_cfg->specific_bssid,
+ sizeof(scan_cmd->bssid));
+ memcpy(scan_cmd->tlv_buffer, scan_cfg->tlv_buf, scan_cfg->tlv_buf_len);
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SCAN);
+
+ /* Size is equal to the sizeof(fixed portions) + the TLV len + header */
+ cmd->size = cpu_to_le16((u16) (sizeof(scan_cmd->bss_mode)
+ + sizeof(scan_cmd->bssid)
+ + scan_cfg->tlv_buf_len + S_DS_GEN));
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of scan.
+ *
+ * The response buffer for the scan command has the following
+ * memory layout:
+ *
+ * .-------------------------------------------------------------.
+ * | Header (4 * sizeof(t_u16)): Standard command response hdr |
+ * .-------------------------------------------------------------.
+ * | BufSize (t_u16) : sizeof the BSS Description data |
+ * .-------------------------------------------------------------.
+ * | NumOfSet (t_u8) : Number of BSS Descs returned |
+ * .-------------------------------------------------------------.
+ * | BSSDescription data (variable, size given in BufSize) |
+ * .-------------------------------------------------------------.
+ * | TLV data (variable, size calculated using Header->Size, |
+ * | BufSize and sizeof the fixed fields above) |
+ * .-------------------------------------------------------------.
+ */
+int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ int ret = 0;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct cmd_ctrl_node *cmd_node;
+ struct host_cmd_ds_802_11_scan_rsp *scan_rsp;
+ struct mwifiex_bssdescriptor *bss_new_entry = NULL;
+ struct mwifiex_ie_types_data *tlv_data;
+ struct mwifiex_ie_types_tsf_timestamp *tsf_tlv;
+ u8 *bss_info;
+ u32 scan_resp_size;
+ u32 bytes_left;
+ u32 num_in_table;
+ u32 bss_idx;
+ u32 idx;
+ u32 tlv_buf_size;
+ long long tsf_val;
+ struct mwifiex_chan_freq_power *cfp;
+ struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv;
+ struct chan_band_param_set *chan_band;
+ u8 band;
+ u8 is_bgscan_resp;
+ unsigned long flags;
+
+ is_bgscan_resp = (le16_to_cpu(resp->command)
+ == HostCmd_CMD_802_11_BG_SCAN_QUERY);
+ if (is_bgscan_resp)
+ scan_rsp = &resp->params.bg_scan_query_resp.scan_resp;
+ else
+ scan_rsp = &resp->params.scan_resp;
+
+
+ if (scan_rsp->number_of_sets > IW_MAX_AP) {
+ dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n",
+ scan_rsp->number_of_sets);
+ ret = -1;
+ goto done;
+ }
+
+ bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
+ dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n",
+ bytes_left);
+
+ scan_resp_size = le16_to_cpu(resp->size);
+
+ dev_dbg(adapter->dev,
+ "info: SCAN_RESP: returned %d APs before parsing\n",
+ scan_rsp->number_of_sets);
+
+ num_in_table = adapter->num_in_scan_table;
+ bss_info = scan_rsp->bss_desc_and_tlv_buffer;
+
+ /*
+ * The size of the TLV buffer is equal to the entire command response
+ * size (scan_resp_size) minus the fixed fields (sizeof()'s), the
+ * BSS Descriptions (bss_descript_size as bytesLef) and the command
+ * response header (S_DS_GEN)
+ */
+ tlv_buf_size = scan_resp_size - (bytes_left
+ + sizeof(scan_rsp->bss_descript_size)
+ + sizeof(scan_rsp->number_of_sets)
+ + S_DS_GEN);
+
+ tlv_data = (struct mwifiex_ie_types_data *) (scan_rsp->
+ bss_desc_and_tlv_buffer +
+ bytes_left);
+
+ /* Search the TLV buffer space in the scan response for any valid
+ TLVs */
+ mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size,
+ TLV_TYPE_TSFTIMESTAMP,
+ (struct mwifiex_ie_types_data **)
+ &tsf_tlv);
+
+ /* Search the TLV buffer space in the scan response for any valid
+ TLVs */
+ mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size,
+ TLV_TYPE_CHANNELBANDLIST,
+ (struct mwifiex_ie_types_data **)
+ &chan_band_tlv);
+
+ /*
+ * Process each scan response returned (scan_rsp->number_of_sets).
+ * Save the information in the bss_new_entry and then insert into the
+ * driver scan table either as an update to an existing entry
+ * or as an addition at the end of the table
+ */
+ bss_new_entry = kzalloc(sizeof(struct mwifiex_bssdescriptor),
+ GFP_KERNEL);
+ if (!bss_new_entry) {
+ dev_err(adapter->dev, " failed to alloc bss_new_entry\n");
+ return -ENOMEM;
+ }
+
+ for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) {
+ /* Zero out the bss_new_entry we are about to store info in */
+ memset(bss_new_entry, 0x00,
+ sizeof(struct mwifiex_bssdescriptor));
+
+ if (mwifiex_interpret_bss_desc_with_ie(adapter, bss_new_entry,
+ &bss_info,
+ &bytes_left)) {
+ /* Error parsing/interpreting scan response, skipped */
+ dev_err(adapter->dev, "SCAN_RESP: "
+ "mwifiex_interpret_bss_desc_with_ie "
+ "returned ERROR\n");
+ continue;
+ }
+
+ /* Process the data fields and IEs returned for this BSS */
+ dev_dbg(adapter->dev, "info: SCAN_RESP: BSSID = %pM\n",
+ bss_new_entry->mac_address);
+
+ /* Search the scan table for the same bssid */
+ for (bss_idx = 0; bss_idx < num_in_table; bss_idx++) {
+ if (memcmp(bss_new_entry->mac_address,
+ adapter->scan_table[bss_idx].mac_address,
+ sizeof(bss_new_entry->mac_address))) {
+ continue;
+ }
+ /*
+ * If the SSID matches as well, it is a
+ * duplicate of this entry. Keep the bss_idx
+ * set to this entry so we replace the old
+ * contents in the table
+ */
+ if ((bss_new_entry->ssid.ssid_len
+ == adapter->scan_table[bss_idx]. ssid.ssid_len)
+ && (!memcmp(bss_new_entry->ssid.ssid,
+ adapter->scan_table[bss_idx].ssid.ssid,
+ bss_new_entry->ssid.ssid_len))) {
+ dev_dbg(adapter->dev, "info: SCAN_RESP:"
+ " duplicate of index: %d\n", bss_idx);
+ break;
+ }
+ }
+ /*
+ * If the bss_idx is equal to the number of entries in
+ * the table, the new entry was not a duplicate; append
+ * it to the scan table
+ */
+ if (bss_idx == num_in_table) {
+ /* Range check the bss_idx, keep it limited to
+ the last entry */
+ if (bss_idx == IW_MAX_AP)
+ bss_idx--;
+ else
+ num_in_table++;
+ }
+
+ /*
+ * Save the beacon/probe response returned for later application
+ * retrieval. Duplicate beacon/probe responses are updated if
+ * possible
+ */
+ mwifiex_ret_802_11_scan_store_beacon(priv, bss_idx,
+ num_in_table, bss_new_entry);
+ /*
+ * If the TSF TLV was appended to the scan results, save this
+ * entry's TSF value in the networkTSF field.The networkTSF is
+ * the firmware's TSF value at the time the beacon or probe
+ * response was received.
+ */
+ if (tsf_tlv) {
+ memcpy(&tsf_val, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE]
+ , sizeof(tsf_val));
+ memcpy(&bss_new_entry->network_tsf, &tsf_val,
+ sizeof(bss_new_entry->network_tsf));
+ }
+ band = BAND_G;
+ if (chan_band_tlv) {
+ chan_band = &chan_band_tlv->chan_band_param[idx];
+ band = mwifiex_radio_type_to_band(chan_band->radio_type
+ & (BIT(0) | BIT(1)));
+ }
+
+ /* Save the band designation for this entry for use in join */
+ bss_new_entry->bss_band = band;
+ cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv,
+ (u8) bss_new_entry->bss_band,
+ (u16)bss_new_entry->channel);
+
+ if (cfp)
+ bss_new_entry->freq = cfp->freq;
+ else
+ bss_new_entry->freq = 0;
+
+ /* Copy the locally created bss_new_entry to the scan table */
+ memcpy(&adapter->scan_table[bss_idx], bss_new_entry,
+ sizeof(adapter->scan_table[bss_idx]));
+
+ }
+
+ dev_dbg(adapter->dev,
+ "info: SCAN_RESP: Scanned %2d APs, %d valid, %d total\n",
+ scan_rsp->number_of_sets,
+ num_in_table - adapter->num_in_scan_table, num_in_table);
+
+ /* Update the total number of BSSIDs in the scan table */
+ adapter->num_in_scan_table = num_in_table;
+
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ if (list_empty(&adapter->scan_pending_q)) {
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ adapter->scan_processing = false;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+ /*
+ * Process the resulting scan table:
+ * - Remove any bad ssids
+ * - Update our current BSS information from scan data
+ */
+ mwifiex_process_scan_results(priv);
+
+ /* Need to indicate IOCTL complete */
+ if (adapter->curr_cmd->wait_q_enabled) {
+ adapter->cmd_wait_q.status = 0;
+ mwifiex_complete_cmd(adapter);
+ }
+ if (priv->report_scan_result)
+ priv->report_scan_result = false;
+ if (priv->scan_pending_on_block) {
+ priv->scan_pending_on_block = false;
+ up(&priv->async_sem);
+ }
+
+ } else {
+ /* Get scan command from scan_pending_q and put to
+ cmd_pending_q */
+ cmd_node = list_first_entry(&adapter->scan_pending_q,
+ struct cmd_ctrl_node, list);
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
+ mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
+ }
+
+done:
+ kfree((u8 *) bss_new_entry);
+ return ret;
+}
+
+/*
+ * This function prepares command for background scan query.
+ *
+ * Preparation includes -
+ * - Setting command ID and proper size
+ * - Setting background scan flush parameter
+ * - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd)
+{
+ struct host_cmd_ds_802_11_bg_scan_query *bg_query =
+ &cmd->params.bg_scan_query;
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11_BG_SCAN_QUERY);
+ cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_bg_scan_query)
+ + S_DS_GEN);
+
+ bg_query->flush = 1;
+
+ return 0;
+}
+
+/*
+ * This function finds a SSID in the scan table.
+ *
+ * A BSSID may optionally be provided to qualify the SSID.
+ * For non-Auto mode, further check is made to make sure the
+ * BSS found in the scan table is compatible with the current
+ * settings of the driver.
+ */
+s32
+mwifiex_find_ssid_in_list(struct mwifiex_private *priv,
+ struct mwifiex_802_11_ssid *ssid, u8 *bssid,
+ u32 mode)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ s32 net = -1, j;
+ u8 best_rssi = 0;
+ u32 i;
+
+ dev_dbg(adapter->dev, "info: num of entries in table = %d\n",
+ adapter->num_in_scan_table);
+
+ /*
+ * Loop through the table until the maximum is reached or until a match
+ * is found based on the bssid field comparison
+ */
+ for (i = 0;
+ i < adapter->num_in_scan_table && (!bssid || (bssid && net < 0));
+ i++) {
+ if (!mwifiex_ssid_cmp(&adapter->scan_table[i].ssid, ssid) &&
+ (!bssid
+ || !memcmp(adapter->scan_table[i].mac_address, bssid,
+ ETH_ALEN))
+ &&
+ (mwifiex_get_cfp_by_band_and_channel_from_cfg80211
+ (priv, (u8) adapter->scan_table[i].bss_band,
+ (u16) adapter->scan_table[i].channel))) {
+ switch (mode) {
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_ADHOC:
+ j = mwifiex_is_network_compatible(priv, i,
+ mode);
+
+ if (j >= 0) {
+ if (SCAN_RSSI
+ (adapter->scan_table[i].rssi) >
+ best_rssi) {
+ best_rssi = SCAN_RSSI(adapter->
+ scan_table
+ [i].rssi);
+ net = i;
+ }
+ } else {
+ if (net == -1)
+ net = j;
+ }
+ break;
+ case NL80211_IFTYPE_UNSPECIFIED:
+ default:
+ /*
+ * Do not check compatibility if the mode
+ * requested is Auto/Unknown. Allows generic
+ * find to work without verifying against the
+ * Adapter security settings
+ */
+ if (SCAN_RSSI(adapter->scan_table[i].rssi) >
+ best_rssi) {
+ best_rssi = SCAN_RSSI(adapter->
+ scan_table[i].rssi);
+ net = i;
+ }
+ break;
+ }
+ }
+ }
+
+ return net;
+}
+
+/*
+ * This function finds a specific compatible BSSID in the scan list.
+ *
+ * This function loops through the scan table looking for a compatible
+ * match. If a BSSID matches, but the BSS is found to be not compatible
+ * the function ignores it and continues to search through the rest of
+ * the entries in case there is an AP with multiple SSIDs assigned to
+ * the same BSSID.
+ */
+s32
+mwifiex_find_bssid_in_list(struct mwifiex_private *priv, u8 *bssid,
+ u32 mode)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ s32 net = -1;
+ u32 i;
+
+ if (!bssid)
+ return -1;
+
+ dev_dbg(adapter->dev, "info: FindBSSID: Num of BSSIDs = %d\n",
+ adapter->num_in_scan_table);
+
+ /*
+ * Look through the scan table for a compatible match. The ret return
+ * variable will be equal to the index in the scan table (greater
+ * than zero) if the network is compatible. The loop will continue
+ * past a matched bssid that is not compatible in case there is an
+ * AP with multiple SSIDs assigned to the same BSSID
+ */
+ for (i = 0; net < 0 && i < adapter->num_in_scan_table; i++) {
+ if (!memcmp
+ (adapter->scan_table[i].mac_address, bssid, ETH_ALEN)
+ && mwifiex_get_cfp_by_band_and_channel_from_cfg80211
+ (priv,
+ (u8) adapter->
+ scan_table[i].
+ bss_band,
+ (u16) adapter->
+ scan_table[i].
+ channel)) {
+ switch (mode) {
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_ADHOC:
+ net = mwifiex_is_network_compatible(priv, i,
+ mode);
+ break;
+ default:
+ net = i;
+ break;
+ }
+ }
+ }
+
+ return net;
+}
+
+/*
+ * This function inserts scan command node to the scan pending queue.
+ */
+void
+mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
+ struct cmd_ctrl_node *cmd_node)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ unsigned long flags;
+
+ cmd_node->wait_q_enabled = true;
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ list_add_tail(&cmd_node->list, &adapter->scan_pending_q);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+}
+
+/*
+ * This function finds an AP with specific ssid in the scan list.
+ */
+int mwifiex_find_best_network(struct mwifiex_private *priv,
+ struct mwifiex_ssid_bssid *req_ssid_bssid)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct mwifiex_bssdescriptor *req_bss;
+ s32 i;
+
+ memset(req_ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
+
+ i = mwifiex_find_best_network_in_list(priv);
+
+ if (i >= 0) {
+ req_bss = &adapter->scan_table[i];
+ memcpy(&req_ssid_bssid->ssid, &req_bss->ssid,
+ sizeof(struct mwifiex_802_11_ssid));
+ memcpy((u8 *) &req_ssid_bssid->bssid,
+ (u8 *) &req_bss->mac_address, ETH_ALEN);
+
+ /* Make sure we are in the right mode */
+ if (priv->bss_mode == NL80211_IFTYPE_UNSPECIFIED)
+ priv->bss_mode = req_bss->bss_mode;
+ }
+
+ if (!req_ssid_bssid->ssid.ssid_len)
+ return -1;
+
+ dev_dbg(adapter->dev, "info: Best network found = [%s], "
+ "[%pM]\n", req_ssid_bssid->ssid.ssid,
+ req_ssid_bssid->bssid);
+
+ return 0;
+}
+
+/*
+ * This function sends a scan command for all available channels to the
+ * firmware, filtered on a specific SSID.
+ */
+static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
+ struct mwifiex_802_11_ssid *req_ssid)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ int ret = 0;
+ struct mwifiex_user_scan_cfg *scan_cfg;
+
+ if (!req_ssid)
+ return -1;
+
+ if (adapter->scan_processing) {
+ dev_dbg(adapter->dev, "cmd: Scan already in process...\n");
+ return ret;
+ }
+
+ if (priv->scan_block) {
+ dev_dbg(adapter->dev,
+ "cmd: Scan is blocked during association...\n");
+ return ret;
+ }
+
+ mwifiex_scan_delete_ssid_table_entry(priv, req_ssid);
+
+ scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL);
+ if (!scan_cfg) {
+ dev_err(adapter->dev, "failed to alloc scan_cfg\n");
+ return -ENOMEM;
+ }
+
+ memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid,
+ req_ssid->ssid_len);
+ scan_cfg->keep_previous_scan = true;
+
+ ret = mwifiex_scan_networks(priv, scan_cfg);
+
+ kfree(scan_cfg);
+ return ret;
+}
+
+/*
+ * Sends IOCTL request to start a scan.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ *
+ * Scan command can be issued for both normal scan and specific SSID
+ * scan, depending upon whether an SSID is provided or not.
+ */
+int mwifiex_request_scan(struct mwifiex_private *priv,
+ struct mwifiex_802_11_ssid *req_ssid)
+{
+ int ret;
+
+ if (down_interruptible(&priv->async_sem)) {
+ dev_err(priv->adapter->dev, "%s: acquire semaphore\n",
+ __func__);
+ return -1;
+ }
+ priv->scan_pending_on_block = true;
+
+ priv->adapter->cmd_wait_q.condition = false;
+
+ if (req_ssid && req_ssid->ssid_len != 0)
+ /* Specific SSID scan */
+ ret = mwifiex_scan_specific_ssid(priv, req_ssid);
+ else
+ /* Normal scan */
+ ret = mwifiex_scan_networks(priv, NULL);
+
+ if (!ret)
+ ret = mwifiex_wait_queue_complete(priv->adapter);
+
+ if (ret == -1) {
+ priv->scan_pending_on_block = false;
+ up(&priv->async_sem);
+ }
+
+ return ret;
+}
+
+/*
+ * This function appends the vendor specific IE TLV to a buffer.
+ */
+int
+mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv,
+ u16 vsie_mask, u8 **buffer)
+{
+ int id, ret_len = 0;
+ struct mwifiex_ie_types_vendor_param_set *vs_param_set;
+
+ if (!buffer)
+ return 0;
+ if (!(*buffer))
+ return 0;
+
+ /*
+ * Traverse through the saved vendor specific IE array and append
+ * the selected(scan/assoc/adhoc) IE as TLV to the command
+ */
+ for (id = 0; id < MWIFIEX_MAX_VSIE_NUM; id++) {
+ if (priv->vs_ie[id].mask & vsie_mask) {
+ vs_param_set =
+ (struct mwifiex_ie_types_vendor_param_set *)
+ *buffer;
+ vs_param_set->header.type =
+ cpu_to_le16(TLV_TYPE_PASSTHROUGH);
+ vs_param_set->header.len =
+ cpu_to_le16((((u16) priv->vs_ie[id].ie[1])
+ & 0x00FF) + 2);
+ memcpy(vs_param_set->ie, priv->vs_ie[id].ie,
+ le16_to_cpu(vs_param_set->header.len));
+ *buffer += le16_to_cpu(vs_param_set->header.len) +
+ sizeof(struct mwifiex_ie_types_header);
+ ret_len += le16_to_cpu(vs_param_set->header.len) +
+ sizeof(struct mwifiex_ie_types_header);
+ }
+ }
+ return ret_len;
+}
+
+/*
+ * This function saves a beacon buffer of the current BSS descriptor.
+ *
+ * The current beacon buffer is saved so that it can be restored in the
+ * following cases that makes the beacon buffer not to contain the current
+ * ssid's beacon buffer.
+ * - The current ssid was not found somehow in the last scan.
+ * - The current ssid was the last entry of the scan table and overloaded.
+ */
+void
+mwifiex_save_curr_bcn(struct mwifiex_private *priv)
+{
+ struct mwifiex_bssdescriptor *curr_bss =
+ &priv->curr_bss_params.bss_descriptor;
+
+ if (!curr_bss->beacon_buf_size)
+ return;
+
+ /* allocate beacon buffer at 1st time; or if it's size has changed */
+ if (!priv->curr_bcn_buf ||
+ priv->curr_bcn_size != curr_bss->beacon_buf_size) {
+ priv->curr_bcn_size = curr_bss->beacon_buf_size;
+
+ kfree(priv->curr_bcn_buf);
+ priv->curr_bcn_buf = kzalloc(curr_bss->beacon_buf_size,
+ GFP_KERNEL);
+ if (!priv->curr_bcn_buf) {
+ dev_err(priv->adapter->dev,
+ "failed to alloc curr_bcn_buf\n");
+ return;
+ }
+ }
+
+ memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf,
+ curr_bss->beacon_buf_size);
+ dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n",
+ priv->curr_bcn_size);
+}
+
+/*
+ * This function frees the current BSS descriptor beacon buffer.
+ */
+void
+mwifiex_free_curr_bcn(struct mwifiex_private *priv)
+{
+ kfree(priv->curr_bcn_buf);
+ priv->curr_bcn_buf = NULL;
+}
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
new file mode 100644
index 00000000000..d425dbd91d1
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -0,0 +1,1754 @@
+/*
+ * Marvell Wireless LAN device driver: SDIO specific handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include <linux/firmware.h>
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+#include "sdio.h"
+
+
+#define SDIO_VERSION "1.0"
+
+static struct mwifiex_if_ops sdio_ops;
+
+static struct semaphore add_remove_card_sem;
+
+/*
+ * SDIO probe.
+ *
+ * This function probes an mwifiex device and registers it. It allocates
+ * the card structure, enables SDIO function number and initiates the
+ * device registration and initialization procedure by adding a logical
+ * interface.
+ */
+static int
+mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
+{
+ int ret;
+ struct sdio_mmc_card *card = NULL;
+
+ pr_debug("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n",
+ func->vendor, func->device, func->class, func->num);
+
+ card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL);
+ if (!card) {
+ pr_err("%s: failed to alloc memory\n", __func__);
+ return -ENOMEM;
+ }
+
+ card->func = func;
+
+ func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+
+ sdio_claim_host(func);
+ ret = sdio_enable_func(func);
+ sdio_release_host(func);
+
+ if (ret) {
+ pr_err("%s: failed to enable function\n", __func__);
+ kfree(card);
+ return -EIO;
+ }
+
+ if (mwifiex_add_card(card, &add_remove_card_sem, &sdio_ops)) {
+ pr_err("%s: add card failed\n", __func__);
+ kfree(card);
+ sdio_claim_host(func);
+ ret = sdio_disable_func(func);
+ sdio_release_host(func);
+ ret = -1;
+ }
+
+ return ret;
+}
+
+/*
+ * SDIO remove.
+ *
+ * This function removes the interface and frees up the card structure.
+ */
+static void
+mwifiex_sdio_remove(struct sdio_func *func)
+{
+ struct sdio_mmc_card *card;
+
+ pr_debug("info: SDIO func num=%d\n", func->num);
+
+ if (func) {
+ card = sdio_get_drvdata(func);
+ if (card) {
+ mwifiex_remove_card(card->adapter,
+ &add_remove_card_sem);
+ kfree(card);
+ }
+ }
+}
+
+/*
+ * SDIO suspend.
+ *
+ * Kernel needs to suspend all functions separately. Therefore all
+ * registered functions must have drivers with suspend and resume
+ * methods. Failing that the kernel simply removes the whole card.
+ *
+ * If already not suspended, this function allocates and sends a host
+ * sleep activate request to the firmware and turns off the traffic.
+ */
+static int mwifiex_sdio_suspend(struct device *dev)
+{
+ struct sdio_func *func = dev_to_sdio_func(dev);
+ struct sdio_mmc_card *card;
+ struct mwifiex_adapter *adapter;
+ mmc_pm_flag_t pm_flag = 0;
+ int hs_actived = 0;
+ int i;
+ int ret = 0;
+
+ if (func) {
+ pm_flag = sdio_get_host_pm_caps(func);
+ pr_debug("cmd: %s: suspend: PM flag = 0x%x\n",
+ sdio_func_id(func), pm_flag);
+ if (!(pm_flag & MMC_PM_KEEP_POWER)) {
+ pr_err("%s: cannot remain alive while host is"
+ " suspended\n", sdio_func_id(func));
+ return -ENOSYS;
+ }
+
+ card = sdio_get_drvdata(func);
+ if (!card || !card->adapter) {
+ pr_err("suspend: invalid card or adapter\n");
+ return 0;
+ }
+ } else {
+ pr_err("suspend: sdio_func is not specified\n");
+ return 0;
+ }
+
+ adapter = card->adapter;
+
+ /* Enable the Host Sleep */
+ hs_actived = mwifiex_enable_hs(adapter);
+ if (hs_actived) {
+ pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n");
+ ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+ }
+
+ /* Indicate device suspended */
+ adapter->is_suspended = true;
+
+ for (i = 0; i < adapter->priv_num; i++)
+ netif_carrier_off(adapter->priv[i]->netdev);
+
+ return ret;
+}
+
+/*
+ * SDIO resume.
+ *
+ * Kernel needs to suspend all functions separately. Therefore all
+ * registered functions must have drivers with suspend and resume
+ * methods. Failing that the kernel simply removes the whole card.
+ *
+ * If already not resumed, this function turns on the traffic and
+ * sends a host sleep cancel request to the firmware.
+ */
+static int mwifiex_sdio_resume(struct device *dev)
+{
+ struct sdio_func *func = dev_to_sdio_func(dev);
+ struct sdio_mmc_card *card;
+ struct mwifiex_adapter *adapter;
+ mmc_pm_flag_t pm_flag = 0;
+ int i;
+
+ if (func) {
+ pm_flag = sdio_get_host_pm_caps(func);
+ card = sdio_get_drvdata(func);
+ if (!card || !card->adapter) {
+ pr_err("resume: invalid card or adapter\n");
+ return 0;
+ }
+ } else {
+ pr_err("resume: sdio_func is not specified\n");
+ return 0;
+ }
+
+ adapter = card->adapter;
+
+ if (!adapter->is_suspended) {
+ dev_warn(adapter->dev, "device already resumed\n");
+ return 0;
+ }
+
+ adapter->is_suspended = false;
+
+ for (i = 0; i < adapter->priv_num; i++)
+ if (adapter->priv[i]->media_connected)
+ netif_carrier_on(adapter->priv[i]->netdev);
+
+ /* Disable Host Sleep */
+ mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
+ MWIFIEX_ASYNC_CMD);
+
+ return 0;
+}
+
+/* Device ID for SD8787 */
+#define SDIO_DEVICE_ID_MARVELL_8787 (0x9119)
+
+/* WLAN IDs */
+static const struct sdio_device_id mwifiex_ids[] = {
+ {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787)},
+ {},
+};
+
+MODULE_DEVICE_TABLE(sdio, mwifiex_ids);
+
+static const struct dev_pm_ops mwifiex_sdio_pm_ops = {
+ .suspend = mwifiex_sdio_suspend,
+ .resume = mwifiex_sdio_resume,
+};
+
+static struct sdio_driver mwifiex_sdio = {
+ .name = "mwifiex_sdio",
+ .id_table = mwifiex_ids,
+ .probe = mwifiex_sdio_probe,
+ .remove = mwifiex_sdio_remove,
+ .drv = {
+ .owner = THIS_MODULE,
+ .pm = &mwifiex_sdio_pm_ops,
+ }
+};
+
+/*
+ * This function writes data into SDIO card register.
+ */
+static int
+mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u32 data)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ int ret = -1;
+
+ sdio_claim_host(card->func);
+ sdio_writeb(card->func, (u8) data, reg, &ret);
+ sdio_release_host(card->func);
+
+ return ret;
+}
+
+/*
+ * This function reads data from SDIO card register.
+ */
+static int
+mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u32 *data)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ int ret = -1;
+ u8 val;
+
+ sdio_claim_host(card->func);
+ val = sdio_readb(card->func, reg, &ret);
+ sdio_release_host(card->func);
+
+ *data = val;
+
+ return ret;
+}
+
+/*
+ * This function writes multiple data into SDIO card memory.
+ *
+ * This does not work in suspended mode.
+ */
+static int
+mwifiex_write_data_sync(struct mwifiex_adapter *adapter,
+ u8 *buffer, u32 pkt_len, u32 port)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ int ret = -1;
+ u8 blk_mode =
+ (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE;
+ u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;
+ u32 blk_cnt =
+ (blk_mode ==
+ BLOCK_MODE) ? (pkt_len /
+ MWIFIEX_SDIO_BLOCK_SIZE) : pkt_len;
+ u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK);
+
+ if (adapter->is_suspended) {
+ dev_err(adapter->dev,
+ "%s: not allowed while suspended\n", __func__);
+ return -1;
+ }
+
+ sdio_claim_host(card->func);
+
+ if (!sdio_writesb(card->func, ioport, buffer, blk_cnt * blk_size))
+ ret = 0;
+
+ sdio_release_host(card->func);
+
+ return ret;
+}
+
+/*
+ * This function reads multiple data from SDIO card memory.
+ */
+static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer,
+ u32 len, u32 port, u8 claim)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ int ret = -1;
+ u8 blk_mode =
+ (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE;
+ u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;
+ u32 blk_cnt =
+ (blk_mode ==
+ BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) : len;
+ u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK);
+
+ if (claim)
+ sdio_claim_host(card->func);
+
+ if (!sdio_readsb(card->func, buffer, ioport, blk_cnt * blk_size))
+ ret = 0;
+
+ if (claim)
+ sdio_release_host(card->func);
+
+ return ret;
+}
+
+/*
+ * This function wakes up the card.
+ *
+ * A host power up command is written to the card configuration
+ * register to wake up the card.
+ */
+static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
+{
+ dev_dbg(adapter->dev, "event: wakeup device...\n");
+
+ return mwifiex_write_reg(adapter, CONFIGURATION_REG, HOST_POWER_UP);
+}
+
+/*
+ * This function is called after the card has woken up.
+ *
+ * The card configuration register is reset.
+ */
+static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
+{
+ dev_dbg(adapter->dev, "cmd: wakeup device completed\n");
+
+ return mwifiex_write_reg(adapter, CONFIGURATION_REG, 0);
+}
+
+/*
+ * This function initializes the IO ports.
+ *
+ * The following operations are performed -
+ * - Read the IO ports (0, 1 and 2)
+ * - Set host interrupt Reset-To-Read to clear
+ * - Set auto re-enable interrupt
+ */
+static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter)
+{
+ u32 reg;
+
+ adapter->ioport = 0;
+
+ /* Read the IO port */
+ if (!mwifiex_read_reg(adapter, IO_PORT_0_REG, &reg))
+ adapter->ioport |= (reg & 0xff);
+ else
+ return -1;
+
+ if (!mwifiex_read_reg(adapter, IO_PORT_1_REG, &reg))
+ adapter->ioport |= ((reg & 0xff) << 8);
+ else
+ return -1;
+
+ if (!mwifiex_read_reg(adapter, IO_PORT_2_REG, &reg))
+ adapter->ioport |= ((reg & 0xff) << 16);
+ else
+ return -1;
+
+ pr_debug("info: SDIO FUNC1 IO port: %#x\n", adapter->ioport);
+
+ /* Set Host interrupt reset to read to clear */
+ if (!mwifiex_read_reg(adapter, HOST_INT_RSR_REG, &reg))
+ mwifiex_write_reg(adapter, HOST_INT_RSR_REG,
+ reg | SDIO_INT_MASK);
+ else
+ return -1;
+
+ /* Dnld/Upld ready set to auto reset */
+ if (!mwifiex_read_reg(adapter, CARD_MISC_CFG_REG, &reg))
+ mwifiex_write_reg(adapter, CARD_MISC_CFG_REG,
+ reg | AUTO_RE_ENABLE_INT);
+ else
+ return -1;
+
+ return 0;
+}
+
+/*
+ * This function sends data to the card.
+ */
+static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter,
+ u8 *payload, u32 pkt_len, u32 port)
+{
+ u32 i = 0;
+ int ret;
+
+ do {
+ ret = mwifiex_write_data_sync(adapter, payload, pkt_len, port);
+ if (ret) {
+ i++;
+ dev_err(adapter->dev, "host_to_card, write iomem"
+ " (%d) failed: %d\n", i, ret);
+ if (mwifiex_write_reg(adapter,
+ CONFIGURATION_REG, 0x04))
+ dev_err(adapter->dev, "write CFG reg failed\n");
+
+ ret = -1;
+ if (i > MAX_WRITE_IOMEM_RETRY)
+ return ret;
+ }
+ } while (ret == -1);
+
+ return ret;
+}
+
+/*
+ * This function gets the read port.
+ *
+ * If control port bit is set in MP read bitmap, the control port
+ * is returned, otherwise the current read port is returned and
+ * the value is increased (provided it does not reach the maximum
+ * limit, in which case it is reset to 1)
+ */
+static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ u16 rd_bitmap = card->mp_rd_bitmap;
+
+ dev_dbg(adapter->dev, "data: mp_rd_bitmap=0x%04x\n", rd_bitmap);
+
+ if (!(rd_bitmap & (CTRL_PORT_MASK | DATA_PORT_MASK)))
+ return -1;
+
+ if (card->mp_rd_bitmap & CTRL_PORT_MASK) {
+ card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK);
+ *port = CTRL_PORT;
+ dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n",
+ *port, card->mp_rd_bitmap);
+ } else {
+ if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) {
+ card->mp_rd_bitmap &=
+ (u16) (~(1 << card->curr_rd_port));
+ *port = card->curr_rd_port;
+
+ if (++card->curr_rd_port == MAX_PORT)
+ card->curr_rd_port = 1;
+ } else {
+ return -1;
+ }
+
+ dev_dbg(adapter->dev,
+ "data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n",
+ *port, rd_bitmap, card->mp_rd_bitmap);
+ }
+ return 0;
+}
+
+/*
+ * This function gets the write port for data.
+ *
+ * The current write port is returned if available and the value is
+ * increased (provided it does not reach the maximum limit, in which
+ * case it is reset to 1)
+ */
+static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ u16 wr_bitmap = card->mp_wr_bitmap;
+
+ dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%04x\n", wr_bitmap);
+
+ if (!(wr_bitmap & card->mp_data_port_mask))
+ return -1;
+
+ if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) {
+ card->mp_wr_bitmap &= (u16) (~(1 << card->curr_wr_port));
+ *port = card->curr_wr_port;
+ if (++card->curr_wr_port == card->mp_end_port)
+ card->curr_wr_port = 1;
+ } else {
+ adapter->data_sent = true;
+ return -EBUSY;
+ }
+
+ if (*port == CTRL_PORT) {
+ dev_err(adapter->dev, "invalid data port=%d cur port=%d"
+ " mp_wr_bitmap=0x%04x -> 0x%04x\n",
+ *port, card->curr_wr_port, wr_bitmap,
+ card->mp_wr_bitmap);
+ return -1;
+ }
+
+ dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n",
+ *port, wr_bitmap, card->mp_wr_bitmap);
+
+ return 0;
+}
+
+/*
+ * This function polls the card status.
+ */
+static int
+mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)
+{
+ u32 tries;
+ u32 cs;
+
+ for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
+ if (mwifiex_read_reg(adapter, CARD_STATUS_REG, &cs))
+ break;
+ else if ((cs & bits) == bits)
+ return 0;
+
+ udelay(10);
+ }
+
+ dev_err(adapter->dev, "poll card status failed, tries = %d\n",
+ tries);
+ return -1;
+}
+
+/*
+ * This function reads the firmware status.
+ */
+static int
+mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
+{
+ u32 fws0, fws1;
+
+ if (mwifiex_read_reg(adapter, CARD_FW_STATUS0_REG, &fws0))
+ return -1;
+
+ if (mwifiex_read_reg(adapter, CARD_FW_STATUS1_REG, &fws1))
+ return -1;
+
+ *dat = (u16) ((fws1 << 8) | fws0);
+
+ return 0;
+}
+
+/*
+ * This function disables the host interrupt.
+ *
+ * The host interrupt mask is read, the disable bit is reset and
+ * written back to the card host interrupt mask register.
+ */
+static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
+{
+ u32 host_int_mask;
+
+ /* Read back the host_int_mask register */
+ if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask))
+ return -1;
+
+ /* Update with the mask and write back to the register */
+ host_int_mask &= ~HOST_INT_DISABLE;
+
+ if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, host_int_mask)) {
+ dev_err(adapter->dev, "disable host interrupt failed\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * This function enables the host interrupt.
+ *
+ * The host interrupt enable mask is written to the card
+ * host interrupt mask register.
+ */
+static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter)
+{
+ /* Simply write the mask to the register */
+ if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, HOST_INT_ENABLE)) {
+ dev_err(adapter->dev, "enable host interrupt failed\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * This function sends a data buffer to the card.
+ */
+static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter,
+ u32 *type, u8 *buffer,
+ u32 npayload, u32 ioport)
+{
+ int ret;
+ u32 nb;
+
+ if (!buffer) {
+ dev_err(adapter->dev, "%s: buffer is NULL\n", __func__);
+ return -1;
+ }
+
+ ret = mwifiex_read_data_sync(adapter, buffer, npayload, ioport, 1);
+
+ if (ret) {
+ dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__,
+ ret);
+ return -1;
+ }
+
+ nb = le16_to_cpu(*(__le16 *) (buffer));
+ if (nb > npayload) {
+ dev_err(adapter->dev, "%s: invalid packet, nb=%d, npayload=%d\n",
+ __func__, nb, npayload);
+ return -1;
+ }
+
+ *type = le16_to_cpu(*(__le16 *) (buffer + 2));
+
+ return ret;
+}
+
+/*
+ * This function downloads the firmware to the card.
+ *
+ * Firmware is downloaded to the card in blocks. Every block download
+ * is tested for CRC errors, and retried a number of times before
+ * returning failure.
+ */
+static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
+ struct mwifiex_fw_image *fw)
+{
+ int ret;
+ u8 *firmware = fw->fw_buf;
+ u32 firmware_len = fw->fw_len;
+ u32 offset = 0;
+ u32 base0, base1;
+ u8 *fwbuf;
+ u16 len = 0;
+ u32 txlen, tx_blocks = 0, tries;
+ u32 i = 0;
+
+ if (!firmware_len) {
+ dev_err(adapter->dev, "firmware image not found!"
+ " Terminating download\n");
+ return -1;
+ }
+
+ dev_dbg(adapter->dev, "info: downloading FW image (%d bytes)\n",
+ firmware_len);
+
+ /* Assume that the allocated buffer is 8-byte aligned */
+ fwbuf = kzalloc(MWIFIEX_UPLD_SIZE, GFP_KERNEL);
+ if (!fwbuf) {
+ dev_err(adapter->dev, "unable to alloc buffer for firmware."
+ " Terminating download\n");
+ return -ENOMEM;
+ }
+
+ /* Perform firmware data transfer */
+ do {
+ /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY
+ bits */
+ ret = mwifiex_sdio_poll_card_status(adapter, CARD_IO_READY |
+ DN_LD_CARD_RDY);
+ if (ret) {
+ dev_err(adapter->dev, "FW download with helper:"
+ " poll status timeout @ %d\n", offset);
+ goto done;
+ }
+
+ /* More data? */
+ if (offset >= firmware_len)
+ break;
+
+ for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
+ ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0,
+ &base0);
+ if (ret) {
+ dev_err(adapter->dev, "dev BASE0 register read"
+ " failed: base0=0x%04X(%d). Terminating "
+ "download\n", base0, base0);
+ goto done;
+ }
+ ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1,
+ &base1);
+ if (ret) {
+ dev_err(adapter->dev, "dev BASE1 register read"
+ " failed: base1=0x%04X(%d). Terminating "
+ "download\n", base1, base1);
+ goto done;
+ }
+ len = (u16) (((base1 & 0xff) << 8) | (base0 & 0xff));
+
+ if (len)
+ break;
+
+ udelay(10);
+ }
+
+ if (!len) {
+ break;
+ } else if (len > MWIFIEX_UPLD_SIZE) {
+ dev_err(adapter->dev, "FW download failed @ %d,"
+ " invalid length %d\n", offset, len);
+ ret = -1;
+ goto done;
+ }
+
+ txlen = len;
+
+ if (len & BIT(0)) {
+ i++;
+ if (i > MAX_WRITE_IOMEM_RETRY) {
+ dev_err(adapter->dev, "FW download failed @"
+ " %d, over max retry count\n", offset);
+ ret = -1;
+ goto done;
+ }
+ dev_err(adapter->dev, "CRC indicated by the helper:"
+ " len = 0x%04X, txlen = %d\n", len, txlen);
+ len &= ~BIT(0);
+ /* Setting this to 0 to resend from same offset */
+ txlen = 0;
+ } else {
+ i = 0;
+
+ /* Set blocksize to transfer - checking for last
+ block */
+ if (firmware_len - offset < txlen)
+ txlen = firmware_len - offset;
+
+ tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE -
+ 1) / MWIFIEX_SDIO_BLOCK_SIZE;
+
+ /* Copy payload to buffer */
+ memmove(fwbuf, &firmware[offset], txlen);
+ }
+
+ ret = mwifiex_write_data_sync(adapter, fwbuf, tx_blocks *
+ MWIFIEX_SDIO_BLOCK_SIZE,
+ adapter->ioport);
+ if (ret) {
+ dev_err(adapter->dev, "FW download, write iomem (%d)"
+ " failed @ %d\n", i, offset);
+ if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04))
+ dev_err(adapter->dev, "write CFG reg failed\n");
+
+ ret = -1;
+ goto done;
+ }
+
+ offset += txlen;
+ } while (true);
+
+ dev_dbg(adapter->dev, "info: FW download over, size %d bytes\n",
+ offset);
+
+ ret = 0;
+done:
+ kfree(fwbuf);
+ return ret;
+}
+
+/*
+ * This function checks the firmware status in card.
+ *
+ * The winner interface is also determined by this function.
+ */
+static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
+ u32 poll_num, int *winner)
+{
+ int ret = 0;
+ u16 firmware_stat;
+ u32 tries;
+ u32 winner_status;
+
+ /* Wait for firmware initialization event */
+ for (tries = 0; tries < poll_num; tries++) {
+ ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat);
+ if (ret)
+ continue;
+ if (firmware_stat == FIRMWARE_READY) {
+ ret = 0;
+ break;
+ } else {
+ mdelay(100);
+ ret = -1;
+ }
+ }
+
+ if (winner && ret) {
+ if (mwifiex_read_reg
+ (adapter, CARD_FW_STATUS0_REG, &winner_status))
+ winner_status = 0;
+
+ if (winner_status)
+ *winner = 0;
+ else
+ *winner = 1;
+ }
+ return ret;
+}
+
+/*
+ * This function reads the interrupt status from card.
+ */
+static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ u32 sdio_ireg;
+ unsigned long flags;
+
+ if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS,
+ REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK,
+ 0)) {
+ dev_err(adapter->dev, "read mp_regs failed\n");
+ return;
+ }
+
+ sdio_ireg = card->mp_regs[HOST_INTSTATUS_REG];
+ if (sdio_ireg) {
+ /*
+ * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
+ * Clear the interrupt status register
+ */
+ dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg);
+ spin_lock_irqsave(&adapter->int_lock, flags);
+ adapter->int_status |= sdio_ireg;
+ spin_unlock_irqrestore(&adapter->int_lock, flags);
+ }
+}
+
+/*
+ * SDIO interrupt handler.
+ *
+ * This function reads the interrupt status from firmware and assigns
+ * the main process in workqueue which will handle the interrupt.
+ */
+static void
+mwifiex_sdio_interrupt(struct sdio_func *func)
+{
+ struct mwifiex_adapter *adapter;
+ struct sdio_mmc_card *card;
+
+ card = sdio_get_drvdata(func);
+ if (!card || !card->adapter) {
+ pr_debug("int: func=%p card=%p adapter=%p\n",
+ func, card, card ? card->adapter : NULL);
+ return;
+ }
+ adapter = card->adapter;
+
+ if (adapter->surprise_removed)
+ return;
+
+ if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)
+ adapter->ps_state = PS_STATE_AWAKE;
+
+ mwifiex_interrupt_status(adapter);
+ queue_work(adapter->workqueue, &adapter->main_work);
+}
+
+/*
+ * This function decodes a received packet.
+ *
+ * Based on the type, the packet is treated as either a data, or
+ * a command response, or an event, and the correct handler
+ * function is invoked.
+ */
+static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
+ struct sk_buff *skb, u32 upld_typ)
+{
+ u8 *cmd_buf;
+
+ skb_pull(skb, INTF_HEADER_LEN);
+
+ switch (upld_typ) {
+ case MWIFIEX_TYPE_DATA:
+ dev_dbg(adapter->dev, "info: --- Rx: Data packet ---\n");
+ mwifiex_handle_rx_packet(adapter, skb);
+ break;
+
+ case MWIFIEX_TYPE_CMD:
+ dev_dbg(adapter->dev, "info: --- Rx: Cmd Response ---\n");
+ /* take care of curr_cmd = NULL case */
+ if (!adapter->curr_cmd) {
+ cmd_buf = adapter->upld_buf;
+
+ if (adapter->ps_state == PS_STATE_SLEEP_CFM)
+ mwifiex_process_sleep_confirm_resp(adapter,
+ skb->data, skb->len);
+
+ memcpy(cmd_buf, skb->data, min_t(u32,
+ MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
+
+ dev_kfree_skb_any(skb);
+ } else {
+ adapter->cmd_resp_received = true;
+ adapter->curr_cmd->resp_skb = skb;
+ }
+ break;
+
+ case MWIFIEX_TYPE_EVENT:
+ dev_dbg(adapter->dev, "info: --- Rx: Event ---\n");
+ adapter->event_cause = *(u32 *) skb->data;
+
+ skb_pull(skb, MWIFIEX_EVENT_HEADER_LEN);
+
+ if ((skb->len > 0) && (skb->len < MAX_EVENT_SIZE))
+ memcpy(adapter->event_body, skb->data, skb->len);
+
+ /* event cause has been saved to adapter->event_cause */
+ adapter->event_received = true;
+ adapter->event_skb = skb;
+
+ break;
+
+ default:
+ dev_err(adapter->dev, "unknown upload type %#x\n", upld_typ);
+ dev_kfree_skb_any(skb);
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * This function transfers received packets from card to driver, performing
+ * aggregation if required.
+ *
+ * For data received on control port, or if aggregation is disabled, the
+ * received buffers are uploaded as separate packets. However, if aggregation
+ * is enabled and required, the buffers are copied onto an aggregation buffer,
+ * provided there is space left, processed and finally uploaded.
+ */
+static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
+ struct sk_buff *skb, u8 port)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ s32 f_do_rx_aggr = 0;
+ s32 f_do_rx_cur = 0;
+ s32 f_aggr_cur = 0;
+ struct sk_buff *skb_deaggr;
+ u32 pind;
+ u32 pkt_len, pkt_type = 0;
+ u8 *curr_ptr;
+ u32 rx_len = skb->len;
+
+ if (port == CTRL_PORT) {
+ /* Read the command Resp without aggr */
+ dev_dbg(adapter->dev, "info: %s: no aggregation for cmd "
+ "response\n", __func__);
+
+ f_do_rx_cur = 1;
+ goto rx_curr_single;
+ }
+
+ if (!card->mpa_rx.enabled) {
+ dev_dbg(adapter->dev, "info: %s: rx aggregation disabled\n",
+ __func__);
+
+ f_do_rx_cur = 1;
+ goto rx_curr_single;
+ }
+
+ if (card->mp_rd_bitmap & (~((u16) CTRL_PORT_MASK))) {
+ /* Some more data RX pending */
+ dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__);
+
+ if (MP_RX_AGGR_IN_PROGRESS(card)) {
+ if (MP_RX_AGGR_BUF_HAS_ROOM(card, skb->len)) {
+ f_aggr_cur = 1;
+ } else {
+ /* No room in Aggr buf, do rx aggr now */
+ f_do_rx_aggr = 1;
+ f_do_rx_cur = 1;
+ }
+ } else {
+ /* Rx aggr not in progress */
+ f_aggr_cur = 1;
+ }
+
+ } else {
+ /* No more data RX pending */
+ dev_dbg(adapter->dev, "info: %s: last packet\n", __func__);
+
+ if (MP_RX_AGGR_IN_PROGRESS(card)) {
+ f_do_rx_aggr = 1;
+ if (MP_RX_AGGR_BUF_HAS_ROOM(card, skb->len))
+ f_aggr_cur = 1;
+ else
+ /* No room in Aggr buf, do rx aggr now */
+ f_do_rx_cur = 1;
+ } else {
+ f_do_rx_cur = 1;
+ }
+ }
+
+ if (f_aggr_cur) {
+ dev_dbg(adapter->dev, "info: current packet aggregation\n");
+ /* Curr pkt can be aggregated */
+ MP_RX_AGGR_SETUP(card, skb, port);
+
+ if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) ||
+ MP_RX_AGGR_PORT_LIMIT_REACHED(card)) {
+ dev_dbg(adapter->dev, "info: %s: aggregated packet "
+ "limit reached\n", __func__);
+ /* No more pkts allowed in Aggr buf, rx it */
+ f_do_rx_aggr = 1;
+ }
+ }
+
+ if (f_do_rx_aggr) {
+ /* do aggr RX now */
+ dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n",
+ card->mpa_rx.pkt_cnt);
+
+ if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf,
+ card->mpa_rx.buf_len,
+ (adapter->ioport | 0x1000 |
+ (card->mpa_rx.ports << 4)) +
+ card->mpa_rx.start_port, 1))
+ return -1;
+
+ curr_ptr = card->mpa_rx.buf;
+
+ for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) {
+
+ /* get curr PKT len & type */
+ pkt_len = *(u16 *) &curr_ptr[0];
+ pkt_type = *(u16 *) &curr_ptr[2];
+
+ /* copy pkt to deaggr buf */
+ skb_deaggr = card->mpa_rx.skb_arr[pind];
+
+ if ((pkt_type == MWIFIEX_TYPE_DATA) && (pkt_len <=
+ card->mpa_rx.len_arr[pind])) {
+
+ memcpy(skb_deaggr->data, curr_ptr, pkt_len);
+
+ skb_trim(skb_deaggr, pkt_len);
+
+ /* Process de-aggr packet */
+ mwifiex_decode_rx_packet(adapter, skb_deaggr,
+ pkt_type);
+ } else {
+ dev_err(adapter->dev, "wrong aggr pkt:"
+ " type=%d len=%d max_len=%d\n",
+ pkt_type, pkt_len,
+ card->mpa_rx.len_arr[pind]);
+ dev_kfree_skb_any(skb_deaggr);
+ }
+ curr_ptr += card->mpa_rx.len_arr[pind];
+ }
+ MP_RX_AGGR_BUF_RESET(card);
+ }
+
+rx_curr_single:
+ if (f_do_rx_cur) {
+ dev_dbg(adapter->dev, "info: RX: port: %d, rx_len: %d\n",
+ port, rx_len);
+
+ if (mwifiex_sdio_card_to_host(adapter, &pkt_type,
+ skb->data, skb->len,
+ adapter->ioport + port))
+ return -1;
+
+ mwifiex_decode_rx_packet(adapter, skb, pkt_type);
+ }
+
+ return 0;
+}
+
+/*
+ * This function checks the current interrupt status.
+ *
+ * The following interrupts are checked and handled by this function -
+ * - Data sent
+ * - Command sent
+ * - Packets received
+ *
+ * Since the firmware does not generate download ready interrupt if the
+ * port updated is command port only, command sent interrupt checking
+ * should be done manually, and for every SDIO interrupt.
+ *
+ * In case of Rx packets received, the packets are uploaded from card to
+ * host and processed accordingly.
+ */
+static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ int ret = 0;
+ u8 sdio_ireg;
+ struct sk_buff *skb;
+ u8 port = CTRL_PORT;
+ u32 len_reg_l, len_reg_u;
+ u32 rx_blocks;
+ u16 rx_len;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->int_lock, flags);
+ sdio_ireg = adapter->int_status;
+ adapter->int_status = 0;
+ spin_unlock_irqrestore(&adapter->int_lock, flags);
+
+ if (!sdio_ireg)
+ return ret;
+
+ if (sdio_ireg & DN_LD_HOST_INT_STATUS) {
+ card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8;
+ card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L];
+ dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n",
+ card->mp_wr_bitmap);
+ if (adapter->data_sent &&
+ (card->mp_wr_bitmap & card->mp_data_port_mask)) {
+ dev_dbg(adapter->dev,
+ "info: <--- Tx DONE Interrupt --->\n");
+ adapter->data_sent = false;
+ }
+ }
+
+ /* As firmware will not generate download ready interrupt if the port
+ updated is command port only, cmd_sent should be done for any SDIO
+ interrupt. */
+ if (adapter->cmd_sent) {
+ /* Check if firmware has attach buffer at command port and
+ update just that in wr_bit_map. */
+ card->mp_wr_bitmap |=
+ (u16) card->mp_regs[WR_BITMAP_L] & CTRL_PORT_MASK;
+ if (card->mp_wr_bitmap & CTRL_PORT_MASK)
+ adapter->cmd_sent = false;
+ }
+
+ dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
+ adapter->cmd_sent, adapter->data_sent);
+ if (sdio_ireg & UP_LD_HOST_INT_STATUS) {
+ card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8;
+ card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L];
+ dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n",
+ card->mp_rd_bitmap);
+
+ while (true) {
+ ret = mwifiex_get_rd_port(adapter, &port);
+ if (ret) {
+ dev_dbg(adapter->dev,
+ "info: no more rd_port available\n");
+ break;
+ }
+ len_reg_l = RD_LEN_P0_L + (port << 1);
+ len_reg_u = RD_LEN_P0_U + (port << 1);
+ rx_len = ((u16) card->mp_regs[len_reg_u]) << 8;
+ rx_len |= (u16) card->mp_regs[len_reg_l];
+ dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n",
+ port, rx_len);
+ rx_blocks =
+ (rx_len + MWIFIEX_SDIO_BLOCK_SIZE -
+ 1) / MWIFIEX_SDIO_BLOCK_SIZE;
+ if (rx_len <= INTF_HEADER_LEN
+ || (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >
+ MWIFIEX_RX_DATA_BUF_SIZE) {
+ dev_err(adapter->dev, "invalid rx_len=%d\n",
+ rx_len);
+ return -1;
+ }
+ rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
+
+ skb = dev_alloc_skb(rx_len);
+
+ if (!skb) {
+ dev_err(adapter->dev, "%s: failed to alloc skb",
+ __func__);
+ return -1;
+ }
+
+ skb_put(skb, rx_len);
+
+ dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n",
+ rx_len, skb->len);
+
+ if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb,
+ port)) {
+ u32 cr = 0;
+
+ dev_err(adapter->dev, "card_to_host_mpa failed:"
+ " int status=%#x\n", sdio_ireg);
+ if (mwifiex_read_reg(adapter,
+ CONFIGURATION_REG, &cr))
+ dev_err(adapter->dev,
+ "read CFG reg failed\n");
+
+ dev_dbg(adapter->dev,
+ "info: CFG reg val = %d\n", cr);
+ if (mwifiex_write_reg(adapter,
+ CONFIGURATION_REG,
+ (cr | 0x04)))
+ dev_err(adapter->dev,
+ "write CFG reg failed\n");
+
+ dev_dbg(adapter->dev, "info: write success\n");
+ if (mwifiex_read_reg(adapter,
+ CONFIGURATION_REG, &cr))
+ dev_err(adapter->dev,
+ "read CFG reg failed\n");
+
+ dev_dbg(adapter->dev,
+ "info: CFG reg val =%x\n", cr);
+ dev_kfree_skb_any(skb);
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * This function aggregates transmission buffers in driver and downloads
+ * the aggregated packet to card.
+ *
+ * The individual packets are aggregated by copying into an aggregation
+ * buffer and then downloaded to the card. Previous unsent packets in the
+ * aggregation buffer are pre-copied first before new packets are added.
+ * Aggregation is done till there is space left in the aggregation buffer,
+ * or till new packets are available.
+ *
+ * The function will only download the packet to the card when aggregation
+ * stops, otherwise it will just aggregate the packet in aggregation buffer
+ * and return.
+ */
+static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
+ u8 *payload, u32 pkt_len, u8 port,
+ u32 next_pkt_len)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ int ret = 0;
+ s32 f_send_aggr_buf = 0;
+ s32 f_send_cur_buf = 0;
+ s32 f_precopy_cur_buf = 0;
+ s32 f_postcopy_cur_buf = 0;
+
+ if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) {
+ dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n",
+ __func__);
+
+ f_send_cur_buf = 1;
+ goto tx_curr_single;
+ }
+
+ if (next_pkt_len) {
+ /* More pkt in TX queue */
+ dev_dbg(adapter->dev, "info: %s: more packets in queue.\n",
+ __func__);
+
+ if (MP_TX_AGGR_IN_PROGRESS(card)) {
+ if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) &&
+ MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) {
+ f_precopy_cur_buf = 1;
+
+ if (!(card->mp_wr_bitmap &
+ (1 << card->curr_wr_port))
+ || !MP_TX_AGGR_BUF_HAS_ROOM(
+ card, next_pkt_len))
+ f_send_aggr_buf = 1;
+ } else {
+ /* No room in Aggr buf, send it */
+ f_send_aggr_buf = 1;
+
+ if (MP_TX_AGGR_PORT_LIMIT_REACHED(card) ||
+ !(card->mp_wr_bitmap &
+ (1 << card->curr_wr_port)))
+ f_send_cur_buf = 1;
+ else
+ f_postcopy_cur_buf = 1;
+ }
+ } else {
+ if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)
+ && (card->mp_wr_bitmap & (1 << card->curr_wr_port)))
+ f_precopy_cur_buf = 1;
+ else
+ f_send_cur_buf = 1;
+ }
+ } else {
+ /* Last pkt in TX queue */
+ dev_dbg(adapter->dev, "info: %s: Last packet in Tx Queue.\n",
+ __func__);
+
+ if (MP_TX_AGGR_IN_PROGRESS(card)) {
+ /* some packs in Aggr buf already */
+ f_send_aggr_buf = 1;
+
+ if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len))
+ f_precopy_cur_buf = 1;
+ else
+ /* No room in Aggr buf, send it */
+ f_send_cur_buf = 1;
+ } else {
+ f_send_cur_buf = 1;
+ }
+ }
+
+ if (f_precopy_cur_buf) {
+ dev_dbg(adapter->dev, "data: %s: precopy current buffer\n",
+ __func__);
+ MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);
+
+ if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) ||
+ MP_TX_AGGR_PORT_LIMIT_REACHED(card))
+ /* No more pkts allowed in Aggr buf, send it */
+ f_send_aggr_buf = 1;
+ }
+
+ if (f_send_aggr_buf) {
+ dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n",
+ __func__,
+ card->mpa_tx.start_port, card->mpa_tx.ports);
+ ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf,
+ card->mpa_tx.buf_len,
+ (adapter->ioport | 0x1000 |
+ (card->mpa_tx.ports << 4)) +
+ card->mpa_tx.start_port);
+
+ MP_TX_AGGR_BUF_RESET(card);
+ }
+
+tx_curr_single:
+ if (f_send_cur_buf) {
+ dev_dbg(adapter->dev, "data: %s: send current buffer %d\n",
+ __func__, port);
+ ret = mwifiex_write_data_to_card(adapter, payload, pkt_len,
+ adapter->ioport + port);
+ }
+
+ if (f_postcopy_cur_buf) {
+ dev_dbg(adapter->dev, "data: %s: postcopy current buffer\n",
+ __func__);
+ MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);
+ }
+
+ return ret;
+}
+
+/*
+ * This function downloads data from driver to card.
+ *
+ * Both commands and data packets are transferred to the card by this
+ * function.
+ *
+ * This function adds the SDIO specific header to the front of the buffer
+ * before transferring. The header contains the length of the packet and
+ * the type. The firmware handles the packets based upon this set type.
+ */
+static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
+ u8 type, u8 *payload, u32 pkt_len,
+ struct mwifiex_tx_param *tx_param)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ int ret;
+ u32 buf_block_len;
+ u32 blk_size;
+ u8 port = CTRL_PORT;
+
+ /* Allocate buffer and copy payload */
+ blk_size = MWIFIEX_SDIO_BLOCK_SIZE;
+ buf_block_len = (pkt_len + blk_size - 1) / blk_size;
+ *(u16 *) &payload[0] = (u16) pkt_len;
+ *(u16 *) &payload[2] = type;
+
+ /*
+ * This is SDIO specific header
+ * u16 length,
+ * u16 type (MWIFIEX_TYPE_DATA = 0, MWIFIEX_TYPE_CMD = 1,
+ * MWIFIEX_TYPE_EVENT = 3)
+ */
+ if (type == MWIFIEX_TYPE_DATA) {
+ ret = mwifiex_get_wr_port_data(adapter, &port);
+ if (ret) {
+ dev_err(adapter->dev, "%s: no wr_port available\n",
+ __func__);
+ return ret;
+ }
+ } else {
+ adapter->cmd_sent = true;
+ /* Type must be MWIFIEX_TYPE_CMD */
+
+ if (pkt_len <= INTF_HEADER_LEN ||
+ pkt_len > MWIFIEX_UPLD_SIZE)
+ dev_err(adapter->dev, "%s: payload=%p, nb=%d\n",
+ __func__, payload, pkt_len);
+ }
+
+ /* Transfer data to card */
+ pkt_len = buf_block_len * blk_size;
+
+ if (tx_param)
+ ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len,
+ port, tx_param->next_pkt_len);
+ else
+ ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len,
+ port, 0);
+
+ if (ret) {
+ if (type == MWIFIEX_TYPE_CMD)
+ adapter->cmd_sent = false;
+ if (type == MWIFIEX_TYPE_DATA)
+ adapter->data_sent = false;
+ } else {
+ if (type == MWIFIEX_TYPE_DATA) {
+ if (!(card->mp_wr_bitmap & (1 << card->curr_wr_port)))
+ adapter->data_sent = true;
+ else
+ adapter->data_sent = false;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * This function allocates the MPA Tx and Rx buffers.
+ */
+static int mwifiex_alloc_sdio_mpa_buffers(struct mwifiex_adapter *adapter,
+ u32 mpa_tx_buf_size, u32 mpa_rx_buf_size)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ int ret = 0;
+
+ card->mpa_tx.buf = kzalloc(mpa_tx_buf_size, GFP_KERNEL);
+ if (!card->mpa_tx.buf) {
+ dev_err(adapter->dev, "could not alloc buffer for MP-A TX\n");
+ ret = -1;
+ goto error;
+ }
+
+ card->mpa_tx.buf_size = mpa_tx_buf_size;
+
+ card->mpa_rx.buf = kzalloc(mpa_rx_buf_size, GFP_KERNEL);
+ if (!card->mpa_rx.buf) {
+ dev_err(adapter->dev, "could not alloc buffer for MP-A RX\n");
+ ret = -1;
+ goto error;
+ }
+
+ card->mpa_rx.buf_size = mpa_rx_buf_size;
+
+error:
+ if (ret) {
+ kfree(card->mpa_tx.buf);
+ kfree(card->mpa_rx.buf);
+ }
+
+ return ret;
+}
+
+/*
+ * This function unregisters the SDIO device.
+ *
+ * The SDIO IRQ is released, the function is disabled and driver
+ * data is set to null.
+ */
+static void
+mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
+{
+ struct sdio_mmc_card *card = adapter->card;
+
+ if (adapter->card) {
+ /* Release the SDIO IRQ */
+ sdio_claim_host(card->func);
+ sdio_release_irq(card->func);
+ sdio_disable_func(card->func);
+ sdio_release_host(card->func);
+ sdio_set_drvdata(card->func, NULL);
+ }
+}
+
+/*
+ * This function registers the SDIO device.
+ *
+ * SDIO IRQ is claimed, block size is set and driver data is initialized.
+ */
+static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
+{
+ int ret = 0;
+ struct sdio_mmc_card *card = adapter->card;
+ struct sdio_func *func = card->func;
+
+ /* save adapter pointer in card */
+ card->adapter = adapter;
+
+ sdio_claim_host(func);
+
+ /* Request the SDIO IRQ */
+ ret = sdio_claim_irq(func, mwifiex_sdio_interrupt);
+ if (ret) {
+ pr_err("claim irq failed: ret=%d\n", ret);
+ goto disable_func;
+ }
+
+ /* Set block size */
+ ret = sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE);
+ if (ret) {
+ pr_err("cannot set SDIO block size\n");
+ ret = -1;
+ goto release_irq;
+ }
+
+ sdio_release_host(func);
+ sdio_set_drvdata(func, card);
+
+ adapter->dev = &func->dev;
+
+ return 0;
+
+release_irq:
+ sdio_release_irq(func);
+disable_func:
+ sdio_disable_func(func);
+ sdio_release_host(func);
+ adapter->card = NULL;
+
+ return -1;
+}
+
+/*
+ * This function initializes the SDIO driver.
+ *
+ * The following initializations steps are followed -
+ * - Read the Host interrupt status register to acknowledge
+ * the first interrupt got from bootloader
+ * - Disable host interrupt mask register
+ * - Get SDIO port
+ * - Get revision ID
+ * - Initialize SDIO variables in card
+ * - Allocate MP registers
+ * - Allocate MPA Tx and Rx buffers
+ */
+static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ int ret;
+ u32 sdio_ireg;
+
+ /*
+ * Read the HOST_INT_STATUS_REG for ACK the first interrupt got
+ * from the bootloader. If we don't do this we get a interrupt
+ * as soon as we register the irq.
+ */
+ mwifiex_read_reg(adapter, HOST_INTSTATUS_REG, &sdio_ireg);
+
+ /* Disable host interrupt mask register for SDIO */
+ mwifiex_sdio_disable_host_int(adapter);
+
+ /* Get SDIO ioport */
+ mwifiex_init_sdio_ioport(adapter);
+
+ /* Get revision ID */
+#define REV_ID_REG 0x5c
+ mwifiex_read_reg(adapter, REV_ID_REG, &adapter->revision_id);
+
+ /* Initialize SDIO variables in card */
+ card->mp_rd_bitmap = 0;
+ card->mp_wr_bitmap = 0;
+ card->curr_rd_port = 1;
+ card->curr_wr_port = 1;
+
+ card->mp_data_port_mask = DATA_PORT_MASK;
+
+ card->mpa_tx.buf_len = 0;
+ card->mpa_tx.pkt_cnt = 0;
+ card->mpa_tx.start_port = 0;
+
+ card->mpa_tx.enabled = 0;
+ card->mpa_tx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT;
+
+ card->mpa_rx.buf_len = 0;
+ card->mpa_rx.pkt_cnt = 0;
+ card->mpa_rx.start_port = 0;
+
+ card->mpa_rx.enabled = 0;
+ card->mpa_rx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT;
+
+ /* Allocate buffers for SDIO MP-A */
+ card->mp_regs = kzalloc(MAX_MP_REGS, GFP_KERNEL);
+ if (!card->mp_regs) {
+ dev_err(adapter->dev, "failed to alloc mp_regs\n");
+ return -ENOMEM;
+ }
+
+ ret = mwifiex_alloc_sdio_mpa_buffers(adapter,
+ SDIO_MP_TX_AGGR_DEF_BUF_SIZE,
+ SDIO_MP_RX_AGGR_DEF_BUF_SIZE);
+ if (ret) {
+ dev_err(adapter->dev, "failed to alloc sdio mp-a buffers\n");
+ kfree(card->mp_regs);
+ return -1;
+ }
+
+ return ret;
+}
+
+/*
+ * This function resets the MPA Tx and Rx buffers.
+ */
+static void mwifiex_cleanup_mpa_buf(struct mwifiex_adapter *adapter)
+{
+ struct sdio_mmc_card *card = adapter->card;
+
+ MP_TX_AGGR_BUF_RESET(card);
+ MP_RX_AGGR_BUF_RESET(card);
+}
+
+/*
+ * This function cleans up the allocated card buffers.
+ *
+ * The following are freed by this function -
+ * - MP registers
+ * - MPA Tx buffer
+ * - MPA Rx buffer
+ */
+static void mwifiex_cleanup_sdio(struct mwifiex_adapter *adapter)
+{
+ struct sdio_mmc_card *card = adapter->card;
+
+ kfree(card->mp_regs);
+ kfree(card->mpa_tx.buf);
+ kfree(card->mpa_rx.buf);
+}
+
+/*
+ * This function updates the MP end port in card.
+ */
+static void
+mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ int i;
+
+ card->mp_end_port = port;
+
+ card->mp_data_port_mask = DATA_PORT_MASK;
+
+ for (i = 1; i <= MAX_PORT - card->mp_end_port; i++)
+ card->mp_data_port_mask &= ~(1 << (MAX_PORT - i));
+
+ card->curr_wr_port = 1;
+
+ dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n",
+ port, card->mp_data_port_mask);
+}
+
+static struct mwifiex_if_ops sdio_ops = {
+ .init_if = mwifiex_init_sdio,
+ .cleanup_if = mwifiex_cleanup_sdio,
+ .check_fw_status = mwifiex_check_fw_status,
+ .prog_fw = mwifiex_prog_fw_w_helper,
+ .register_dev = mwifiex_register_dev,
+ .unregister_dev = mwifiex_unregister_dev,
+ .enable_int = mwifiex_sdio_enable_host_int,
+ .process_int_status = mwifiex_process_int_status,
+ .host_to_card = mwifiex_sdio_host_to_card,
+ .wakeup = mwifiex_pm_wakeup_card,
+ .wakeup_complete = mwifiex_pm_wakeup_card_complete,
+
+ /* SDIO specific */
+ .update_mp_end_port = mwifiex_update_mp_end_port,
+ .cleanup_mpa_buf = mwifiex_cleanup_mpa_buf,
+};
+
+/*
+ * This function initializes the SDIO driver.
+ *
+ * This initiates the semaphore and registers the device with
+ * SDIO bus.
+ */
+static int
+mwifiex_sdio_init_module(void)
+{
+ sema_init(&add_remove_card_sem, 1);
+
+ return sdio_register_driver(&mwifiex_sdio);
+}
+
+/*
+ * This function cleans up the SDIO driver.
+ *
+ * The following major steps are followed for cleanup -
+ * - Resume the device if its suspended
+ * - Disconnect the device if connected
+ * - Shutdown the firmware
+ * - Unregister the device from SDIO bus.
+ */
+static void
+mwifiex_sdio_cleanup_module(void)
+{
+ struct mwifiex_adapter *adapter = g_adapter;
+ int i;
+
+ if (down_interruptible(&add_remove_card_sem))
+ goto exit_sem_err;
+
+ if (!adapter || !adapter->priv_num)
+ goto exit;
+
+ if (adapter->is_suspended)
+ mwifiex_sdio_resume(adapter->dev);
+
+ for (i = 0; i < adapter->priv_num; i++)
+ if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) &&
+ adapter->priv[i]->media_connected)
+ mwifiex_deauthenticate(adapter->priv[i], NULL);
+
+ if (!adapter->surprise_removed)
+ mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
+ MWIFIEX_BSS_ROLE_ANY),
+ MWIFIEX_FUNC_SHUTDOWN);
+
+exit:
+ up(&add_remove_card_sem);
+
+exit_sem_err:
+ sdio_unregister_driver(&mwifiex_sdio);
+}
+
+module_init(mwifiex_sdio_init_module);
+module_exit(mwifiex_sdio_cleanup_module);
+
+MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION);
+MODULE_VERSION(SDIO_VERSION);
+MODULE_LICENSE("GPL v2");
+MODULE_FIRMWARE("sd8787.bin");
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
new file mode 100644
index 00000000000..a0e9bc5253e
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -0,0 +1,305 @@
+/*
+ * Marvell Wireless LAN device driver: SDIO specific definitions
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_SDIO_H
+#define _MWIFIEX_SDIO_H
+
+
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/card.h>
+
+#include "main.h"
+
+#define BLOCK_MODE 1
+#define BYTE_MODE 0
+
+#define REG_PORT 0
+#define RD_BITMAP_L 0x04
+#define RD_BITMAP_U 0x05
+#define WR_BITMAP_L 0x06
+#define WR_BITMAP_U 0x07
+#define RD_LEN_P0_L 0x08
+#define RD_LEN_P0_U 0x09
+
+#define MWIFIEX_SDIO_IO_PORT_MASK 0xfffff
+
+#define MWIFIEX_SDIO_BYTE_MODE_MASK 0x80000000
+
+#define CTRL_PORT 0
+#define CTRL_PORT_MASK 0x0001
+#define DATA_PORT_MASK 0xfffe
+
+#define MAX_MP_REGS 64
+#define MAX_PORT 16
+
+#define SDIO_MP_AGGR_DEF_PKT_LIMIT 8
+
+#define SDIO_MP_TX_AGGR_DEF_BUF_SIZE (4096) /* 4K */
+
+/* Multi port RX aggregation buffer size */
+#define SDIO_MP_RX_AGGR_DEF_BUF_SIZE (4096) /* 4K */
+
+/* Misc. Config Register : Auto Re-enable interrupts */
+#define AUTO_RE_ENABLE_INT BIT(4)
+
+/* Host Control Registers */
+/* Host Control Registers : I/O port 0 */
+#define IO_PORT_0_REG 0x78
+/* Host Control Registers : I/O port 1 */
+#define IO_PORT_1_REG 0x79
+/* Host Control Registers : I/O port 2 */
+#define IO_PORT_2_REG 0x7A
+
+/* Host Control Registers : Configuration */
+#define CONFIGURATION_REG 0x00
+/* Host Control Registers : Host without Command 53 finish host*/
+#define HOST_TO_CARD_EVENT (0x1U << 3)
+/* Host Control Registers : Host without Command 53 finish host */
+#define HOST_WO_CMD53_FINISH_HOST (0x1U << 2)
+/* Host Control Registers : Host power up */
+#define HOST_POWER_UP (0x1U << 1)
+/* Host Control Registers : Host power down */
+#define HOST_POWER_DOWN (0x1U << 0)
+
+/* Host Control Registers : Host interrupt mask */
+#define HOST_INT_MASK_REG 0x02
+/* Host Control Registers : Upload host interrupt mask */
+#define UP_LD_HOST_INT_MASK (0x1U)
+/* Host Control Registers : Download host interrupt mask */
+#define DN_LD_HOST_INT_MASK (0x2U)
+/* Enable Host interrupt mask */
+#define HOST_INT_ENABLE (UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK)
+/* Disable Host interrupt mask */
+#define HOST_INT_DISABLE 0xff
+
+/* Host Control Registers : Host interrupt status */
+#define HOST_INTSTATUS_REG 0x03
+/* Host Control Registers : Upload host interrupt status */
+#define UP_LD_HOST_INT_STATUS (0x1U)
+/* Host Control Registers : Download host interrupt status */
+#define DN_LD_HOST_INT_STATUS (0x2U)
+
+/* Host Control Registers : Host interrupt RSR */
+#define HOST_INT_RSR_REG 0x01
+/* Host Control Registers : Upload host interrupt RSR */
+#define UP_LD_HOST_INT_RSR (0x1U)
+#define SDIO_INT_MASK 0x3F
+
+/* Host Control Registers : Host interrupt status */
+#define HOST_INT_STATUS_REG 0x28
+/* Host Control Registers : Upload CRC error */
+#define UP_LD_CRC_ERR (0x1U << 2)
+/* Host Control Registers : Upload restart */
+#define UP_LD_RESTART (0x1U << 1)
+/* Host Control Registers : Download restart */
+#define DN_LD_RESTART (0x1U << 0)
+
+/* Card Control Registers : Card status register */
+#define CARD_STATUS_REG 0x30
+/* Card Control Registers : Card I/O ready */
+#define CARD_IO_READY (0x1U << 3)
+/* Card Control Registers : CIS card ready */
+#define CIS_CARD_RDY (0x1U << 2)
+/* Card Control Registers : Upload card ready */
+#define UP_LD_CARD_RDY (0x1U << 1)
+/* Card Control Registers : Download card ready */
+#define DN_LD_CARD_RDY (0x1U << 0)
+
+/* Card Control Registers : Host interrupt mask register */
+#define HOST_INTERRUPT_MASK_REG 0x34
+/* Card Control Registers : Host power interrupt mask */
+#define HOST_POWER_INT_MASK (0x1U << 3)
+/* Card Control Registers : Abort card interrupt mask */
+#define ABORT_CARD_INT_MASK (0x1U << 2)
+/* Card Control Registers : Upload card interrupt mask */
+#define UP_LD_CARD_INT_MASK (0x1U << 1)
+/* Card Control Registers : Download card interrupt mask */
+#define DN_LD_CARD_INT_MASK (0x1U << 0)
+
+/* Card Control Registers : Card interrupt status register */
+#define CARD_INTERRUPT_STATUS_REG 0x38
+/* Card Control Registers : Power up interrupt */
+#define POWER_UP_INT (0x1U << 4)
+/* Card Control Registers : Power down interrupt */
+#define POWER_DOWN_INT (0x1U << 3)
+
+/* Card Control Registers : Card interrupt RSR register */
+#define CARD_INTERRUPT_RSR_REG 0x3c
+/* Card Control Registers : Power up RSR */
+#define POWER_UP_RSR (0x1U << 4)
+/* Card Control Registers : Power down RSR */
+#define POWER_DOWN_RSR (0x1U << 3)
+
+/* Card Control Registers : Miscellaneous Configuration Register */
+#define CARD_MISC_CFG_REG 0x6C
+
+/* Host F1 read base 0 */
+#define HOST_F1_RD_BASE_0 0x0040
+/* Host F1 read base 1 */
+#define HOST_F1_RD_BASE_1 0x0041
+/* Host F1 card ready */
+#define HOST_F1_CARD_RDY 0x0020
+
+/* Firmware status 0 register */
+#define CARD_FW_STATUS0_REG 0x60
+/* Firmware status 1 register */
+#define CARD_FW_STATUS1_REG 0x61
+/* Rx length register */
+#define CARD_RX_LEN_REG 0x62
+/* Rx unit register */
+#define CARD_RX_UNIT_REG 0x63
+
+/* Event header Len*/
+#define MWIFIEX_EVENT_HEADER_LEN 8
+
+/* Max retry number of CMD53 write */
+#define MAX_WRITE_IOMEM_RETRY 2
+
+/* SDIO Tx aggregation in progress ? */
+#define MP_TX_AGGR_IN_PROGRESS(a) (a->mpa_tx.pkt_cnt > 0)
+
+/* SDIO Tx aggregation buffer room for next packet ? */
+#define MP_TX_AGGR_BUF_HAS_ROOM(a, len) ((a->mpa_tx.buf_len+len) \
+ <= a->mpa_tx.buf_size)
+
+/* Copy current packet (SDIO Tx aggregation buffer) to SDIO buffer */
+#define MP_TX_AGGR_BUF_PUT(a, payload, pkt_len, port) do { \
+ memmove(&a->mpa_tx.buf[a->mpa_tx.buf_len], \
+ payload, pkt_len); \
+ a->mpa_tx.buf_len += pkt_len; \
+ if (!a->mpa_tx.pkt_cnt) \
+ a->mpa_tx.start_port = port; \
+ if (a->mpa_tx.start_port <= port) \
+ a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt)); \
+ else \
+ a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt+1+(MAX_PORT - \
+ a->mp_end_port))); \
+ a->mpa_tx.pkt_cnt++; \
+} while (0);
+
+/* SDIO Tx aggregation limit ? */
+#define MP_TX_AGGR_PKT_LIMIT_REACHED(a) \
+ (a->mpa_tx.pkt_cnt == a->mpa_tx.pkt_aggr_limit)
+
+/* SDIO Tx aggregation port limit ? */
+#define MP_TX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_wr_port < \
+ a->mpa_tx.start_port) && (((MAX_PORT - \
+ a->mpa_tx.start_port) + a->curr_wr_port) >= \
+ SDIO_MP_AGGR_DEF_PKT_LIMIT))
+
+/* Reset SDIO Tx aggregation buffer parameters */
+#define MP_TX_AGGR_BUF_RESET(a) do { \
+ a->mpa_tx.pkt_cnt = 0; \
+ a->mpa_tx.buf_len = 0; \
+ a->mpa_tx.ports = 0; \
+ a->mpa_tx.start_port = 0; \
+} while (0);
+
+/* SDIO Rx aggregation limit ? */
+#define MP_RX_AGGR_PKT_LIMIT_REACHED(a) \
+ (a->mpa_rx.pkt_cnt == a->mpa_rx.pkt_aggr_limit)
+
+/* SDIO Tx aggregation port limit ? */
+#define MP_RX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_rd_port < \
+ a->mpa_rx.start_port) && (((MAX_PORT - \
+ a->mpa_rx.start_port) + a->curr_rd_port) >= \
+ SDIO_MP_AGGR_DEF_PKT_LIMIT))
+
+/* SDIO Rx aggregation in progress ? */
+#define MP_RX_AGGR_IN_PROGRESS(a) (a->mpa_rx.pkt_cnt > 0)
+
+/* SDIO Rx aggregation buffer room for next packet ? */
+#define MP_RX_AGGR_BUF_HAS_ROOM(a, rx_len) \
+ ((a->mpa_rx.buf_len+rx_len) <= a->mpa_rx.buf_size)
+
+/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */
+#define MP_RX_AGGR_SETUP(a, skb, port) do { \
+ a->mpa_rx.buf_len += skb->len; \
+ if (!a->mpa_rx.pkt_cnt) \
+ a->mpa_rx.start_port = port; \
+ if (a->mpa_rx.start_port <= port) \
+ a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt)); \
+ else \
+ a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt+1)); \
+ a->mpa_rx.skb_arr[a->mpa_rx.pkt_cnt] = skb; \
+ a->mpa_rx.len_arr[a->mpa_rx.pkt_cnt] = skb->len; \
+ a->mpa_rx.pkt_cnt++; \
+} while (0);
+
+/* Reset SDIO Rx aggregation buffer parameters */
+#define MP_RX_AGGR_BUF_RESET(a) do { \
+ a->mpa_rx.pkt_cnt = 0; \
+ a->mpa_rx.buf_len = 0; \
+ a->mpa_rx.ports = 0; \
+ a->mpa_rx.start_port = 0; \
+} while (0);
+
+
+/* data structure for SDIO MPA TX */
+struct mwifiex_sdio_mpa_tx {
+ /* multiport tx aggregation buffer pointer */
+ u8 *buf;
+ u32 buf_len;
+ u32 pkt_cnt;
+ u16 ports;
+ u16 start_port;
+ u8 enabled;
+ u32 buf_size;
+ u32 pkt_aggr_limit;
+};
+
+struct mwifiex_sdio_mpa_rx {
+ u8 *buf;
+ u32 buf_len;
+ u32 pkt_cnt;
+ u16 ports;
+ u16 start_port;
+
+ struct sk_buff *skb_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT];
+ u32 len_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT];
+
+ u8 enabled;
+ u32 buf_size;
+ u32 pkt_aggr_limit;
+};
+
+int mwifiex_bus_register(void);
+void mwifiex_bus_unregister(void);
+
+struct sdio_mmc_card {
+ struct sdio_func *func;
+ struct mwifiex_adapter *adapter;
+
+ u16 mp_rd_bitmap;
+ u16 mp_wr_bitmap;
+
+ u16 mp_end_port;
+ u16 mp_data_port_mask;
+
+ u8 curr_rd_port;
+ u8 curr_wr_port;
+
+ u8 *mp_regs;
+
+ struct mwifiex_sdio_mpa_tx mpa_tx;
+ struct mwifiex_sdio_mpa_rx mpa_rx;
+};
+#endif /* _MWIFIEX_SDIO_H */
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
new file mode 100644
index 00000000000..8af3a78d272
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -0,0 +1,1219 @@
+/*
+ * Marvell Wireless LAN device driver: station command handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+/*
+ * This function prepares command to set/get RSSI information.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting data/beacon average factors
+ * - Resetting SNR/NF/RSSI values in private structure
+ * - Ensuring correct endian-ness
+ */
+static int
+mwifiex_cmd_802_11_rssi_info(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd, u16 cmd_action)
+{
+ cmd->command = cpu_to_le16(HostCmd_CMD_RSSI_INFO);
+ cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_rssi_info) +
+ S_DS_GEN);
+ cmd->params.rssi_info.action = cpu_to_le16(cmd_action);
+ cmd->params.rssi_info.ndata = cpu_to_le16(priv->data_avg_factor);
+ cmd->params.rssi_info.nbcn = cpu_to_le16(priv->bcn_avg_factor);
+
+ /* Reset SNR/NF/RSSI values in private structure */
+ priv->data_rssi_last = 0;
+ priv->data_nf_last = 0;
+ priv->data_rssi_avg = 0;
+ priv->data_nf_avg = 0;
+ priv->bcn_rssi_last = 0;
+ priv->bcn_nf_last = 0;
+ priv->bcn_rssi_avg = 0;
+ priv->bcn_nf_avg = 0;
+
+ return 0;
+}
+
+/*
+ * This function prepares command to set MAC control.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_mac_control(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ u16 cmd_action, void *data_buf)
+{
+ struct host_cmd_ds_mac_control *mac_ctrl = &cmd->params.mac_ctrl;
+ u16 action = *((u16 *) data_buf);
+
+ if (cmd_action != HostCmd_ACT_GEN_SET) {
+ dev_err(priv->adapter->dev,
+ "mac_control: only support set cmd\n");
+ return -1;
+ }
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_MAC_CONTROL);
+ cmd->size =
+ cpu_to_le16(sizeof(struct host_cmd_ds_mac_control) + S_DS_GEN);
+ mac_ctrl->action = cpu_to_le16(action);
+
+ return 0;
+}
+
+/*
+ * This function prepares command to set/get SNMP MIB.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting SNMP MIB OID number and value
+ * (as required)
+ * - Ensuring correct endian-ness
+ *
+ * The following SNMP MIB OIDs are supported -
+ * - FRAG_THRESH_I : Fragmentation threshold
+ * - RTS_THRESH_I : RTS threshold
+ * - SHORT_RETRY_LIM_I : Short retry limit
+ * - DOT11D_I : 11d support
+ */
+static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ u16 cmd_action, u32 cmd_oid,
+ void *data_buf)
+{
+ struct host_cmd_ds_802_11_snmp_mib *snmp_mib = &cmd->params.smib;
+ u32 ul_temp;
+
+ dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
+ cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib)
+ - 1 + S_DS_GEN);
+
+ if (cmd_action == HostCmd_ACT_GEN_GET) {
+ snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_GET);
+ snmp_mib->buf_size = cpu_to_le16(MAX_SNMP_BUF_SIZE);
+ cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
+ + MAX_SNMP_BUF_SIZE);
+ }
+
+ switch (cmd_oid) {
+ case FRAG_THRESH_I:
+ snmp_mib->oid = cpu_to_le16((u16) FRAG_THRESH_I);
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
+ snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
+ ul_temp = *((u32 *) data_buf);
+ *((__le16 *) (snmp_mib->value)) =
+ cpu_to_le16((u16) ul_temp);
+ cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
+ + sizeof(u16));
+ }
+ break;
+ case RTS_THRESH_I:
+ snmp_mib->oid = cpu_to_le16((u16) RTS_THRESH_I);
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
+ snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
+ ul_temp = *((u32 *) data_buf);
+ *(__le16 *) (snmp_mib->value) =
+ cpu_to_le16((u16) ul_temp);
+ cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
+ + sizeof(u16));
+ }
+ break;
+
+ case SHORT_RETRY_LIM_I:
+ snmp_mib->oid = cpu_to_le16((u16) SHORT_RETRY_LIM_I);
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
+ snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
+ ul_temp = (*(u32 *) data_buf);
+ *((__le16 *) (snmp_mib->value)) =
+ cpu_to_le16((u16) ul_temp);
+ cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
+ + sizeof(u16));
+ }
+ break;
+ case DOT11D_I:
+ snmp_mib->oid = cpu_to_le16((u16) DOT11D_I);
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
+ snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
+ ul_temp = *(u32 *) data_buf;
+ *((__le16 *) (snmp_mib->value)) =
+ cpu_to_le16((u16) ul_temp);
+ cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
+ + sizeof(u16));
+ }
+ break;
+ default:
+ break;
+ }
+ dev_dbg(priv->adapter->dev,
+ "cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x,"
+ " Value=0x%x\n",
+ cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size),
+ le16_to_cpu(*(__le16 *) snmp_mib->value));
+ return 0;
+}
+
+/*
+ * This function prepares command to get log.
+ *
+ * Preparation includes -
+ * - Setting command ID and proper size
+ * - Ensuring correct endian-ness
+ */
+static int
+mwifiex_cmd_802_11_get_log(struct host_cmd_ds_command *cmd)
+{
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11_GET_LOG);
+ cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_get_log) +
+ S_DS_GEN);
+ return 0;
+}
+
+/*
+ * This function prepares command to set/get Tx data rate configuration.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting configuration index, rate scope and rate drop pattern
+ * parameters (as required)
+ * - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ u16 cmd_action, void *data_buf)
+{
+ struct host_cmd_ds_tx_rate_cfg *rate_cfg = &cmd->params.tx_rate_cfg;
+ struct mwifiex_rate_scope *rate_scope;
+ struct mwifiex_rate_drop_pattern *rate_drop;
+ u16 *pbitmap_rates = (u16 *) data_buf;
+
+ u32 i;
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_TX_RATE_CFG);
+
+ rate_cfg->action = cpu_to_le16(cmd_action);
+ rate_cfg->cfg_index = 0;
+
+ rate_scope = (struct mwifiex_rate_scope *) ((u8 *) rate_cfg +
+ sizeof(struct host_cmd_ds_tx_rate_cfg));
+ rate_scope->type = cpu_to_le16(TLV_TYPE_RATE_SCOPE);
+ rate_scope->length = cpu_to_le16(sizeof(struct mwifiex_rate_scope) -
+ sizeof(struct mwifiex_ie_types_header));
+ if (pbitmap_rates != NULL) {
+ rate_scope->hr_dsss_rate_bitmap = cpu_to_le16(pbitmap_rates[0]);
+ rate_scope->ofdm_rate_bitmap = cpu_to_le16(pbitmap_rates[1]);
+ for (i = 0;
+ i < sizeof(rate_scope->ht_mcs_rate_bitmap) / sizeof(u16);
+ i++)
+ rate_scope->ht_mcs_rate_bitmap[i] =
+ cpu_to_le16(pbitmap_rates[2 + i]);
+ } else {
+ rate_scope->hr_dsss_rate_bitmap =
+ cpu_to_le16(priv->bitmap_rates[0]);
+ rate_scope->ofdm_rate_bitmap =
+ cpu_to_le16(priv->bitmap_rates[1]);
+ for (i = 0;
+ i < sizeof(rate_scope->ht_mcs_rate_bitmap) / sizeof(u16);
+ i++)
+ rate_scope->ht_mcs_rate_bitmap[i] =
+ cpu_to_le16(priv->bitmap_rates[2 + i]);
+ }
+
+ rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope +
+ sizeof(struct mwifiex_rate_scope));
+ rate_drop->type = cpu_to_le16(TLV_TYPE_RATE_DROP_CONTROL);
+ rate_drop->length = cpu_to_le16(sizeof(rate_drop->rate_drop_mode));
+ rate_drop->rate_drop_mode = 0;
+
+ cmd->size =
+ cpu_to_le16(S_DS_GEN + sizeof(struct host_cmd_ds_tx_rate_cfg) +
+ sizeof(struct mwifiex_rate_scope) +
+ sizeof(struct mwifiex_rate_drop_pattern));
+
+ return 0;
+}
+
+/*
+ * This function prepares command to set/get Tx power configuration.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting Tx power mode, power group TLV
+ * (as required)
+ * - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd,
+ u16 cmd_action, void *data_buf)
+{
+ struct mwifiex_types_power_group *pg_tlv;
+ struct host_cmd_ds_txpwr_cfg *txp;
+ struct host_cmd_ds_txpwr_cfg *cmd_txp_cfg = &cmd->params.txp_cfg;
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_TXPWR_CFG);
+ cmd->size =
+ cpu_to_le16(S_DS_GEN + sizeof(struct host_cmd_ds_txpwr_cfg));
+ switch (cmd_action) {
+ case HostCmd_ACT_GEN_SET:
+ txp = (struct host_cmd_ds_txpwr_cfg *) data_buf;
+ if (txp->mode) {
+ pg_tlv = (struct mwifiex_types_power_group
+ *) ((unsigned long) data_buf +
+ sizeof(struct host_cmd_ds_txpwr_cfg));
+ memmove(cmd_txp_cfg, data_buf,
+ sizeof(struct host_cmd_ds_txpwr_cfg) +
+ sizeof(struct mwifiex_types_power_group) +
+ pg_tlv->length);
+
+ pg_tlv = (struct mwifiex_types_power_group *) ((u8 *)
+ cmd_txp_cfg +
+ sizeof(struct host_cmd_ds_txpwr_cfg));
+ cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) +
+ sizeof(struct mwifiex_types_power_group) +
+ pg_tlv->length);
+ } else {
+ memmove(cmd_txp_cfg, data_buf,
+ sizeof(struct host_cmd_ds_txpwr_cfg));
+ }
+ cmd_txp_cfg->action = cpu_to_le16(cmd_action);
+ break;
+ case HostCmd_ACT_GEN_GET:
+ cmd_txp_cfg->action = cpu_to_le16(cmd_action);
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * This function prepares command to set Host Sleep configuration.
+ *
+ * Preparation includes -
+ * - Setting command ID and proper size
+ * - Setting Host Sleep action, conditions, ARP filters
+ * (as required)
+ * - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ u16 cmd_action,
+ struct mwifiex_hs_config_param *data_buf)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct host_cmd_ds_802_11_hs_cfg_enh *hs_cfg = &cmd->params.opt_hs_cfg;
+ u16 hs_activate = false;
+
+ if (data_buf == NULL)
+ /* New Activate command */
+ hs_activate = true;
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH);
+
+ if (!hs_activate &&
+ (data_buf->conditions
+ != cpu_to_le32(HOST_SLEEP_CFG_CANCEL))
+ && ((adapter->arp_filter_size > 0)
+ && (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) {
+ dev_dbg(adapter->dev,
+ "cmd: Attach %d bytes ArpFilter to HSCfg cmd\n",
+ adapter->arp_filter_size);
+ memcpy(((u8 *) hs_cfg) +
+ sizeof(struct host_cmd_ds_802_11_hs_cfg_enh),
+ adapter->arp_filter, adapter->arp_filter_size);
+ cmd->size = cpu_to_le16(adapter->arp_filter_size +
+ sizeof(struct host_cmd_ds_802_11_hs_cfg_enh)
+ + S_DS_GEN);
+ } else {
+ cmd->size = cpu_to_le16(S_DS_GEN + sizeof(struct
+ host_cmd_ds_802_11_hs_cfg_enh));
+ }
+ if (hs_activate) {
+ hs_cfg->action = cpu_to_le16(HS_ACTIVATE);
+ hs_cfg->params.hs_activate.resp_ctrl = RESP_NEEDED;
+ } else {
+ hs_cfg->action = cpu_to_le16(HS_CONFIGURE);
+ hs_cfg->params.hs_config.conditions = data_buf->conditions;
+ hs_cfg->params.hs_config.gpio = data_buf->gpio;
+ hs_cfg->params.hs_config.gap = data_buf->gap;
+ dev_dbg(adapter->dev,
+ "cmd: HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x\n",
+ hs_cfg->params.hs_config.conditions,
+ hs_cfg->params.hs_config.gpio,
+ hs_cfg->params.hs_config.gap);
+ }
+
+ return 0;
+}
+
+/*
+ * This function prepares command to set/get MAC address.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting MAC address (for SET only)
+ * - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_802_11_mac_address(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ u16 cmd_action)
+{
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11_MAC_ADDRESS);
+ cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_mac_address) +
+ S_DS_GEN);
+ cmd->result = 0;
+
+ cmd->params.mac_addr.action = cpu_to_le16(cmd_action);
+
+ if (cmd_action == HostCmd_ACT_GEN_SET)
+ memcpy(cmd->params.mac_addr.mac_addr, priv->curr_addr,
+ ETH_ALEN);
+ return 0;
+}
+
+/*
+ * This function prepares command to set MAC multicast address.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting MAC multicast address
+ * - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd,
+ u16 cmd_action, void *data_buf)
+{
+ struct mwifiex_multicast_list *mcast_list =
+ (struct mwifiex_multicast_list *) data_buf;
+ struct host_cmd_ds_mac_multicast_adr *mcast_addr = &cmd->params.mc_addr;
+
+ cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_mac_multicast_adr) +
+ S_DS_GEN);
+ cmd->command = cpu_to_le16(HostCmd_CMD_MAC_MULTICAST_ADR);
+
+ mcast_addr->action = cpu_to_le16(cmd_action);
+ mcast_addr->num_of_adrs =
+ cpu_to_le16((u16) mcast_list->num_multicast_addr);
+ memcpy(mcast_addr->mac_list, mcast_list->mac_list,
+ mcast_list->num_multicast_addr * ETH_ALEN);
+
+ return 0;
+}
+
+/*
+ * This function prepares command to deauthenticate.
+ *
+ * Preparation includes -
+ * - Setting command ID and proper size
+ * - Setting AP MAC address and reason code
+ * - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ void *data_buf)
+{
+ struct host_cmd_ds_802_11_deauthenticate *deauth = &cmd->params.deauth;
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11_DEAUTHENTICATE);
+ cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_deauthenticate)
+ + S_DS_GEN);
+
+ /* Set AP MAC address */
+ memcpy(deauth->mac_addr, (u8 *) data_buf, ETH_ALEN);
+
+ dev_dbg(priv->adapter->dev, "cmd: Deauth: %pM\n", deauth->mac_addr);
+
+ deauth->reason_code = cpu_to_le16(WLAN_REASON_DEAUTH_LEAVING);
+
+ return 0;
+}
+
+/*
+ * This function prepares command to stop Ad-Hoc network.
+ *
+ * Preparation includes -
+ * - Setting command ID and proper size
+ * - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_802_11_ad_hoc_stop(struct host_cmd_ds_command *cmd)
+{
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP);
+ cmd->size = cpu_to_le16(S_DS_GEN);
+ return 0;
+}
+
+/*
+ * This function sets WEP key(s) to key parameter TLV(s).
+ *
+ * Multi-key parameter TLVs are supported, so we can send multiple
+ * WEP keys in a single buffer.
+ */
+static int
+mwifiex_set_keyparamset_wep(struct mwifiex_private *priv,
+ struct mwifiex_ie_type_key_param_set *key_param_set,
+ u16 *key_param_len)
+{
+ int cur_key_param_len;
+ u8 i;
+
+ /* Multi-key_param_set TLV is supported */
+ for (i = 0; i < NUM_WEP_KEYS; i++) {
+ if ((priv->wep_key[i].key_length == WLAN_KEY_LEN_WEP40) ||
+ (priv->wep_key[i].key_length == WLAN_KEY_LEN_WEP104)) {
+ key_param_set->type =
+ cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+/* Key_param_set WEP fixed length */
+#define KEYPARAMSET_WEP_FIXED_LEN 8
+ key_param_set->length = cpu_to_le16((u16)
+ (priv->wep_key[i].
+ key_length +
+ KEYPARAMSET_WEP_FIXED_LEN));
+ key_param_set->key_type_id =
+ cpu_to_le16(KEY_TYPE_ID_WEP);
+ key_param_set->key_info =
+ cpu_to_le16(KEY_ENABLED | KEY_UNICAST |
+ KEY_MCAST);
+ key_param_set->key_len =
+ cpu_to_le16(priv->wep_key[i].key_length);
+ /* Set WEP key index */
+ key_param_set->key[0] = i;
+ /* Set default Tx key flag */
+ if (i ==
+ (priv->
+ wep_key_curr_index & HostCmd_WEP_KEY_INDEX_MASK))
+ key_param_set->key[1] = 1;
+ else
+ key_param_set->key[1] = 0;
+ memmove(&key_param_set->key[2],
+ priv->wep_key[i].key_material,
+ priv->wep_key[i].key_length);
+
+ cur_key_param_len = priv->wep_key[i].key_length +
+ KEYPARAMSET_WEP_FIXED_LEN +
+ sizeof(struct mwifiex_ie_types_header);
+ *key_param_len += (u16) cur_key_param_len;
+ key_param_set =
+ (struct mwifiex_ie_type_key_param_set *)
+ ((u8 *)key_param_set +
+ cur_key_param_len);
+ } else if (!priv->wep_key[i].key_length) {
+ continue;
+ } else {
+ dev_err(priv->adapter->dev,
+ "key%d Length = %d is incorrect\n",
+ (i + 1), priv->wep_key[i].key_length);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * This function prepares command to set/get/reset network key(s).
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting WEP keys, WAPI keys or WPA keys along with required
+ * encryption (TKIP, AES) (as required)
+ * - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ u16 cmd_action,
+ u32 cmd_oid, void *data_buf)
+{
+ struct host_cmd_ds_802_11_key_material *key_material =
+ &cmd->params.key_material;
+ struct mwifiex_ds_encrypt_key *enc_key =
+ (struct mwifiex_ds_encrypt_key *) data_buf;
+ u16 key_param_len = 0;
+ int ret = 0;
+ const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
+ key_material->action = cpu_to_le16(cmd_action);
+
+ if (cmd_action == HostCmd_ACT_GEN_GET) {
+ cmd->size =
+ cpu_to_le16(sizeof(key_material->action) + S_DS_GEN);
+ return ret;
+ }
+
+ if (!enc_key) {
+ memset(&key_material->key_param_set, 0,
+ (NUM_WEP_KEYS *
+ sizeof(struct mwifiex_ie_type_key_param_set)));
+ ret = mwifiex_set_keyparamset_wep(priv,
+ &key_material->key_param_set,
+ &key_param_len);
+ cmd->size = cpu_to_le16(key_param_len +
+ sizeof(key_material->action) + S_DS_GEN);
+ return ret;
+ } else
+ memset(&key_material->key_param_set, 0,
+ sizeof(struct mwifiex_ie_type_key_param_set));
+ if (enc_key->is_wapi_key) {
+ dev_dbg(priv->adapter->dev, "info: Set WAPI Key\n");
+ key_material->key_param_set.key_type_id =
+ cpu_to_le16(KEY_TYPE_ID_WAPI);
+ if (cmd_oid == KEY_INFO_ENABLED)
+ key_material->key_param_set.key_info =
+ cpu_to_le16(KEY_ENABLED);
+ else
+ key_material->key_param_set.key_info =
+ cpu_to_le16(!KEY_ENABLED);
+
+ key_material->key_param_set.key[0] = enc_key->key_index;
+ if (!priv->sec_info.wapi_key_on)
+ key_material->key_param_set.key[1] = 1;
+ else
+ /* set 0 when re-key */
+ key_material->key_param_set.key[1] = 0;
+
+ if (0 != memcmp(enc_key->mac_addr, bc_mac, sizeof(bc_mac))) {
+ /* WAPI pairwise key: unicast */
+ key_material->key_param_set.key_info |=
+ cpu_to_le16(KEY_UNICAST);
+ } else { /* WAPI group key: multicast */
+ key_material->key_param_set.key_info |=
+ cpu_to_le16(KEY_MCAST);
+ priv->sec_info.wapi_key_on = true;
+ }
+
+ key_material->key_param_set.type =
+ cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+ key_material->key_param_set.key_len =
+ cpu_to_le16(WAPI_KEY_LEN);
+ memcpy(&key_material->key_param_set.key[2],
+ enc_key->key_material, enc_key->key_len);
+ memcpy(&key_material->key_param_set.key[2 + enc_key->key_len],
+ enc_key->wapi_rxpn, WAPI_RXPN_LEN);
+ key_material->key_param_set.length =
+ cpu_to_le16(WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN);
+
+ key_param_len = (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) +
+ sizeof(struct mwifiex_ie_types_header);
+ cmd->size = cpu_to_le16(key_param_len +
+ sizeof(key_material->action) + S_DS_GEN);
+ return ret;
+ }
+ if (enc_key->key_len == WLAN_KEY_LEN_CCMP) {
+ dev_dbg(priv->adapter->dev, "cmd: WPA_AES\n");
+ key_material->key_param_set.key_type_id =
+ cpu_to_le16(KEY_TYPE_ID_AES);
+ if (cmd_oid == KEY_INFO_ENABLED)
+ key_material->key_param_set.key_info =
+ cpu_to_le16(KEY_ENABLED);
+ else
+ key_material->key_param_set.key_info =
+ cpu_to_le16(!KEY_ENABLED);
+
+ if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
+ /* AES pairwise key: unicast */
+ key_material->key_param_set.key_info |=
+ cpu_to_le16(KEY_UNICAST);
+ else /* AES group key: multicast */
+ key_material->key_param_set.key_info |=
+ cpu_to_le16(KEY_MCAST);
+ } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) {
+ dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n");
+ key_material->key_param_set.key_type_id =
+ cpu_to_le16(KEY_TYPE_ID_TKIP);
+ key_material->key_param_set.key_info =
+ cpu_to_le16(KEY_ENABLED);
+
+ if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
+ /* TKIP pairwise key: unicast */
+ key_material->key_param_set.key_info |=
+ cpu_to_le16(KEY_UNICAST);
+ else /* TKIP group key: multicast */
+ key_material->key_param_set.key_info |=
+ cpu_to_le16(KEY_MCAST);
+ }
+
+ if (key_material->key_param_set.key_type_id) {
+ key_material->key_param_set.type =
+ cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+ key_material->key_param_set.key_len =
+ cpu_to_le16((u16) enc_key->key_len);
+ memcpy(key_material->key_param_set.key, enc_key->key_material,
+ enc_key->key_len);
+ key_material->key_param_set.length =
+ cpu_to_le16((u16) enc_key->key_len +
+ KEYPARAMSET_FIXED_LEN);
+
+ key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN)
+ + sizeof(struct mwifiex_ie_types_header);
+
+ cmd->size = cpu_to_le16(key_param_len +
+ sizeof(key_material->action) + S_DS_GEN);
+ }
+
+ return ret;
+}
+
+/*
+ * This function prepares command to set/get 11d domain information.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting domain information fields (for SET only)
+ * - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ u16 cmd_action)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct host_cmd_ds_802_11d_domain_info *domain_info =
+ &cmd->params.domain_info;
+ struct mwifiex_ietypes_domain_param_set *domain =
+ &domain_info->domain;
+ u8 no_of_triplet = adapter->domain_reg.no_of_triplet;
+
+ dev_dbg(adapter->dev, "info: 11D: no_of_triplet=0x%x\n", no_of_triplet);
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11D_DOMAIN_INFO);
+ domain_info->action = cpu_to_le16(cmd_action);
+ if (cmd_action == HostCmd_ACT_GEN_GET) {
+ cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN);
+ return 0;
+ }
+
+ /* Set domain info fields */
+ domain->header.type = cpu_to_le16(WLAN_EID_COUNTRY);
+ memcpy(domain->country_code, adapter->domain_reg.country_code,
+ sizeof(domain->country_code));
+
+ domain->header.len = cpu_to_le16((no_of_triplet *
+ sizeof(struct ieee80211_country_ie_triplet)) +
+ sizeof(domain->country_code));
+
+ if (no_of_triplet) {
+ memcpy(domain->triplet, adapter->domain_reg.triplet,
+ no_of_triplet *
+ sizeof(struct ieee80211_country_ie_triplet));
+
+ cmd->size = cpu_to_le16(sizeof(domain_info->action) +
+ le16_to_cpu(domain->header.len) +
+ sizeof(struct mwifiex_ie_types_header)
+ + S_DS_GEN);
+ } else {
+ cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN);
+ }
+
+ return 0;
+}
+
+/*
+ * This function prepares command to set/get RF channel.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting RF type and current RF channel (for SET only)
+ * - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ u16 cmd_action, void *data_buf)
+{
+ struct host_cmd_ds_802_11_rf_channel *rf_chan =
+ &cmd->params.rf_channel;
+ uint16_t rf_type = le16_to_cpu(rf_chan->rf_type);
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11_RF_CHANNEL);
+ cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_rf_channel)
+ + S_DS_GEN);
+
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ if ((priv->adapter->adhoc_start_band & BAND_A)
+ || (priv->adapter->adhoc_start_band & BAND_AN))
+ rf_chan->rf_type =
+ cpu_to_le16(HostCmd_SCAN_RADIO_TYPE_A);
+
+ rf_type = le16_to_cpu(rf_chan->rf_type);
+ SET_SECONDARYCHAN(rf_type, priv->adapter->chan_offset);
+ rf_chan->current_channel = cpu_to_le16(*((u16 *) data_buf));
+ }
+ rf_chan->action = cpu_to_le16(cmd_action);
+ return 0;
+}
+
+/*
+ * This function prepares command to set/get IBSS coalescing status.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting status to enable or disable (for SET only)
+ * - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd,
+ u16 cmd_action, void *data_buf)
+{
+ struct host_cmd_ds_802_11_ibss_status *ibss_coal =
+ &(cmd->params.ibss_coalescing);
+ u16 enable = 0;
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_802_11_IBSS_COALESCING_STATUS);
+ cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_ibss_status) +
+ S_DS_GEN);
+ cmd->result = 0;
+ ibss_coal->action = cpu_to_le16(cmd_action);
+
+ switch (cmd_action) {
+ case HostCmd_ACT_GEN_SET:
+ if (data_buf != NULL)
+ enable = *(u16 *) data_buf;
+ ibss_coal->enable = cpu_to_le16(enable);
+ break;
+
+ /* In other case.. Nothing to do */
+ case HostCmd_ACT_GEN_GET:
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * This function prepares command to set/get register value.
+ *
+ * Preparation includes -
+ * - Setting command ID, action and proper size
+ * - Setting register offset (for both GET and SET) and
+ * register value (for SET only)
+ * - Ensuring correct endian-ness
+ *
+ * The following type of registers can be accessed with this function -
+ * - MAC register
+ * - BBP register
+ * - RF register
+ * - PMIC register
+ * - CAU register
+ * - EEPROM
+ */
+static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
+ u16 cmd_action, void *data_buf)
+{
+ struct mwifiex_ds_reg_rw *reg_rw;
+
+ reg_rw = (struct mwifiex_ds_reg_rw *) data_buf;
+ switch (le16_to_cpu(cmd->command)) {
+ case HostCmd_CMD_MAC_REG_ACCESS:
+ {
+ struct host_cmd_ds_mac_reg_access *mac_reg;
+
+ cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN);
+ mac_reg = (struct host_cmd_ds_mac_reg_access *) &cmd->
+ params.mac_reg;
+ mac_reg->action = cpu_to_le16(cmd_action);
+ mac_reg->offset =
+ cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
+ mac_reg->value = reg_rw->value;
+ break;
+ }
+ case HostCmd_CMD_BBP_REG_ACCESS:
+ {
+ struct host_cmd_ds_bbp_reg_access *bbp_reg;
+
+ cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN);
+ bbp_reg = (struct host_cmd_ds_bbp_reg_access *) &cmd->
+ params.bbp_reg;
+ bbp_reg->action = cpu_to_le16(cmd_action);
+ bbp_reg->offset =
+ cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
+ bbp_reg->value = (u8) le32_to_cpu(reg_rw->value);
+ break;
+ }
+ case HostCmd_CMD_RF_REG_ACCESS:
+ {
+ struct host_cmd_ds_rf_reg_access *rf_reg;
+
+ cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN);
+ rf_reg = (struct host_cmd_ds_rf_reg_access *) &cmd->
+ params.rf_reg;
+ rf_reg->action = cpu_to_le16(cmd_action);
+ rf_reg->offset =
+ cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
+ rf_reg->value = (u8) le32_to_cpu(reg_rw->value);
+ break;
+ }
+ case HostCmd_CMD_PMIC_REG_ACCESS:
+ {
+ struct host_cmd_ds_pmic_reg_access *pmic_reg;
+
+ cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN);
+ pmic_reg = (struct host_cmd_ds_pmic_reg_access *) &cmd->
+ params.pmic_reg;
+ pmic_reg->action = cpu_to_le16(cmd_action);
+ pmic_reg->offset =
+ cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
+ pmic_reg->value = (u8) le32_to_cpu(reg_rw->value);
+ break;
+ }
+ case HostCmd_CMD_CAU_REG_ACCESS:
+ {
+ struct host_cmd_ds_rf_reg_access *cau_reg;
+
+ cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN);
+ cau_reg = (struct host_cmd_ds_rf_reg_access *) &cmd->
+ params.rf_reg;
+ cau_reg->action = cpu_to_le16(cmd_action);
+ cau_reg->offset =
+ cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
+ cau_reg->value = (u8) le32_to_cpu(reg_rw->value);
+ break;
+ }
+ case HostCmd_CMD_802_11_EEPROM_ACCESS:
+ {
+ struct mwifiex_ds_read_eeprom *rd_eeprom =
+ (struct mwifiex_ds_read_eeprom *) data_buf;
+ struct host_cmd_ds_802_11_eeprom_access *cmd_eeprom =
+ (struct host_cmd_ds_802_11_eeprom_access *)
+ &cmd->params.eeprom;
+
+ cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN);
+ cmd_eeprom->action = cpu_to_le16(cmd_action);
+ cmd_eeprom->offset = rd_eeprom->offset;
+ cmd_eeprom->byte_count = rd_eeprom->byte_count;
+ cmd_eeprom->value = 0;
+ break;
+ }
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * This function prepares the commands before sending them to the firmware.
+ *
+ * This is a generic function which calls specific command preparation
+ * routines based upon the command number.
+ */
+int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
+ u16 cmd_action, u32 cmd_oid,
+ void *data_buf, void *cmd_buf)
+{
+ struct host_cmd_ds_command *cmd_ptr =
+ (struct host_cmd_ds_command *) cmd_buf;
+ int ret = 0;
+
+ /* Prepare command */
+ switch (cmd_no) {
+ case HostCmd_CMD_GET_HW_SPEC:
+ ret = mwifiex_cmd_get_hw_spec(priv, cmd_ptr);
+ break;
+ case HostCmd_CMD_MAC_CONTROL:
+ ret = mwifiex_cmd_mac_control(priv, cmd_ptr, cmd_action,
+ data_buf);
+ break;
+ case HostCmd_CMD_802_11_MAC_ADDRESS:
+ ret = mwifiex_cmd_802_11_mac_address(priv, cmd_ptr,
+ cmd_action);
+ break;
+ case HostCmd_CMD_MAC_MULTICAST_ADR:
+ ret = mwifiex_cmd_mac_multicast_adr(cmd_ptr, cmd_action,
+ data_buf);
+ break;
+ case HostCmd_CMD_TX_RATE_CFG:
+ ret = mwifiex_cmd_tx_rate_cfg(priv, cmd_ptr, cmd_action,
+ data_buf);
+ break;
+ case HostCmd_CMD_TXPWR_CFG:
+ ret = mwifiex_cmd_tx_power_cfg(cmd_ptr, cmd_action,
+ data_buf);
+ break;
+ case HostCmd_CMD_802_11_PS_MODE_ENH:
+ ret = mwifiex_cmd_enh_power_mode(priv, cmd_ptr, cmd_action,
+ (uint16_t)cmd_oid, data_buf);
+ break;
+ case HostCmd_CMD_802_11_HS_CFG_ENH:
+ ret = mwifiex_cmd_802_11_hs_cfg(priv, cmd_ptr, cmd_action,
+ (struct mwifiex_hs_config_param *) data_buf);
+ break;
+ case HostCmd_CMD_802_11_SCAN:
+ ret = mwifiex_cmd_802_11_scan(cmd_ptr, data_buf);
+ break;
+ case HostCmd_CMD_802_11_BG_SCAN_QUERY:
+ ret = mwifiex_cmd_802_11_bg_scan_query(cmd_ptr);
+ break;
+ case HostCmd_CMD_802_11_ASSOCIATE:
+ ret = mwifiex_cmd_802_11_associate(priv, cmd_ptr, data_buf);
+ break;
+ case HostCmd_CMD_802_11_DEAUTHENTICATE:
+ ret = mwifiex_cmd_802_11_deauthenticate(priv, cmd_ptr,
+ data_buf);
+ break;
+ case HostCmd_CMD_802_11_AD_HOC_START:
+ ret = mwifiex_cmd_802_11_ad_hoc_start(priv, cmd_ptr,
+ data_buf);
+ break;
+ case HostCmd_CMD_802_11_GET_LOG:
+ ret = mwifiex_cmd_802_11_get_log(cmd_ptr);
+ break;
+ case HostCmd_CMD_802_11_AD_HOC_JOIN:
+ ret = mwifiex_cmd_802_11_ad_hoc_join(priv, cmd_ptr,
+ data_buf);
+ break;
+ case HostCmd_CMD_802_11_AD_HOC_STOP:
+ ret = mwifiex_cmd_802_11_ad_hoc_stop(cmd_ptr);
+ break;
+ case HostCmd_CMD_RSSI_INFO:
+ ret = mwifiex_cmd_802_11_rssi_info(priv, cmd_ptr, cmd_action);
+ break;
+ case HostCmd_CMD_802_11_SNMP_MIB:
+ ret = mwifiex_cmd_802_11_snmp_mib(priv, cmd_ptr, cmd_action,
+ cmd_oid, data_buf);
+ break;
+ case HostCmd_CMD_802_11_TX_RATE_QUERY:
+ cmd_ptr->command =
+ cpu_to_le16(HostCmd_CMD_802_11_TX_RATE_QUERY);
+ cmd_ptr->size =
+ cpu_to_le16(sizeof(struct host_cmd_ds_tx_rate_query) +
+ S_DS_GEN);
+ priv->tx_rate = 0;
+ ret = 0;
+ break;
+ case HostCmd_CMD_VERSION_EXT:
+ cmd_ptr->command = cpu_to_le16(cmd_no);
+ cmd_ptr->params.verext.version_str_sel =
+ (u8) (*((u32 *) data_buf));
+ memcpy(&cmd_ptr->params, data_buf,
+ sizeof(struct host_cmd_ds_version_ext));
+ cmd_ptr->size =
+ cpu_to_le16(sizeof(struct host_cmd_ds_version_ext) +
+ S_DS_GEN);
+ ret = 0;
+ break;
+ case HostCmd_CMD_802_11_RF_CHANNEL:
+ ret = mwifiex_cmd_802_11_rf_channel(priv, cmd_ptr, cmd_action,
+ data_buf);
+ break;
+ case HostCmd_CMD_FUNC_INIT:
+ if (priv->adapter->hw_status == MWIFIEX_HW_STATUS_RESET)
+ priv->adapter->hw_status = MWIFIEX_HW_STATUS_READY;
+ cmd_ptr->command = cpu_to_le16(cmd_no);
+ cmd_ptr->size = cpu_to_le16(S_DS_GEN);
+ break;
+ case HostCmd_CMD_FUNC_SHUTDOWN:
+ priv->adapter->hw_status = MWIFIEX_HW_STATUS_RESET;
+ cmd_ptr->command = cpu_to_le16(cmd_no);
+ cmd_ptr->size = cpu_to_le16(S_DS_GEN);
+ break;
+ case HostCmd_CMD_11N_ADDBA_REQ:
+ ret = mwifiex_cmd_11n_addba_req(cmd_ptr, data_buf);
+ break;
+ case HostCmd_CMD_11N_DELBA:
+ ret = mwifiex_cmd_11n_delba(cmd_ptr, data_buf);
+ break;
+ case HostCmd_CMD_11N_ADDBA_RSP:
+ ret = mwifiex_cmd_11n_addba_rsp_gen(priv, cmd_ptr, data_buf);
+ break;
+ case HostCmd_CMD_802_11_KEY_MATERIAL:
+ ret = mwifiex_cmd_802_11_key_material(priv, cmd_ptr,
+ cmd_action, cmd_oid,
+ data_buf);
+ break;
+ case HostCmd_CMD_802_11D_DOMAIN_INFO:
+ ret = mwifiex_cmd_802_11d_domain_info(priv, cmd_ptr,
+ cmd_action);
+ break;
+ case HostCmd_CMD_RECONFIGURE_TX_BUFF:
+ ret = mwifiex_cmd_recfg_tx_buf(priv, cmd_ptr, cmd_action,
+ data_buf);
+ break;
+ case HostCmd_CMD_AMSDU_AGGR_CTRL:
+ ret = mwifiex_cmd_amsdu_aggr_ctrl(cmd_ptr, cmd_action,
+ data_buf);
+ break;
+ case HostCmd_CMD_11N_CFG:
+ ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action,
+ data_buf);
+ break;
+ case HostCmd_CMD_WMM_GET_STATUS:
+ dev_dbg(priv->adapter->dev,
+ "cmd: WMM: WMM_GET_STATUS cmd sent\n");
+ cmd_ptr->command = cpu_to_le16(HostCmd_CMD_WMM_GET_STATUS);
+ cmd_ptr->size =
+ cpu_to_le16(sizeof(struct host_cmd_ds_wmm_get_status) +
+ S_DS_GEN);
+ ret = 0;
+ break;
+ case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
+ ret = mwifiex_cmd_ibss_coalescing_status(cmd_ptr, cmd_action,
+ data_buf);
+ break;
+ case HostCmd_CMD_MAC_REG_ACCESS:
+ case HostCmd_CMD_BBP_REG_ACCESS:
+ case HostCmd_CMD_RF_REG_ACCESS:
+ case HostCmd_CMD_PMIC_REG_ACCESS:
+ case HostCmd_CMD_CAU_REG_ACCESS:
+ case HostCmd_CMD_802_11_EEPROM_ACCESS:
+ ret = mwifiex_cmd_reg_access(cmd_ptr, cmd_action, data_buf);
+ break;
+ case HostCmd_CMD_SET_BSS_MODE:
+ cmd_ptr->command = cpu_to_le16(cmd_no);
+ if (priv->bss_mode == NL80211_IFTYPE_ADHOC)
+ cmd_ptr->params.bss_mode.con_type =
+ CONNECTION_TYPE_ADHOC;
+ else if (priv->bss_mode == NL80211_IFTYPE_STATION)
+ cmd_ptr->params.bss_mode.con_type =
+ CONNECTION_TYPE_INFRA;
+ cmd_ptr->size = cpu_to_le16(sizeof(struct
+ host_cmd_ds_set_bss_mode) + S_DS_GEN);
+ ret = 0;
+ break;
+ default:
+ dev_err(priv->adapter->dev,
+ "PREP_CMD: unknown cmd- %#x\n", cmd_no);
+ ret = -1;
+ break;
+ }
+ return ret;
+}
+
+/*
+ * This function issues commands to initialize firmware.
+ *
+ * This is called after firmware download to bring the card to
+ * working state.
+ *
+ * The following commands are issued sequentially -
+ * - Function init (for first interface only)
+ * - Read MAC address (for first interface only)
+ * - Reconfigure Tx buffer size (for first interface only)
+ * - Enable auto deep sleep (for first interface only)
+ * - Get Tx rate
+ * - Get Tx power
+ * - Set IBSS coalescing status
+ * - Set AMSDU aggregation control
+ * - Set 11d control
+ * - Set MAC control (this must be the last command to initialize firmware)
+ */
+int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
+{
+ int ret;
+ u16 enable = true;
+ struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
+ struct mwifiex_ds_auto_ds auto_ds;
+ enum state_11d_t state_11d;
+
+ if (first_sta) {
+
+ ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_FUNC_INIT,
+ HostCmd_ACT_GEN_SET, 0, NULL);
+ if (ret)
+ return -1;
+ /* Read MAC address from HW */
+ ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_GET_HW_SPEC,
+ HostCmd_ACT_GEN_GET, 0, NULL);
+ if (ret)
+ return -1;
+
+ /* Reconfigure tx buf size */
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_RECONFIGURE_TX_BUFF,
+ HostCmd_ACT_GEN_SET, 0,
+ &priv->adapter->tx_buf_size);
+ if (ret)
+ return -1;
+
+ /* Enable IEEE PS by default */
+ priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_802_11_PS_MODE_ENH,
+ EN_AUTO_PS, BITMAP_STA_PS, NULL);
+ if (ret)
+ return -1;
+ }
+
+ /* get tx rate */
+ ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TX_RATE_CFG,
+ HostCmd_ACT_GEN_GET, 0, NULL);
+ if (ret)
+ return -1;
+ priv->data_rate = 0;
+
+ /* get tx power */
+ ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TXPWR_CFG,
+ HostCmd_ACT_GEN_GET, 0, NULL);
+ if (ret)
+ return -1;
+
+ /* set ibss coalescing_status */
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
+ HostCmd_ACT_GEN_SET, 0, &enable);
+ if (ret)
+ return -1;
+
+ memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
+ amsdu_aggr_ctrl.enable = true;
+ /* Send request to firmware */
+ ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_AMSDU_AGGR_CTRL,
+ HostCmd_ACT_GEN_SET, 0,
+ (void *) &amsdu_aggr_ctrl);
+ if (ret)
+ return -1;
+ /* MAC Control must be the last command in init_fw */
+ /* set MAC Control */
+ ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
+ HostCmd_ACT_GEN_SET, 0,
+ &priv->curr_pkt_filter);
+ if (ret)
+ return -1;
+
+ if (first_sta) {
+ /* Enable auto deep sleep */
+ auto_ds.auto_ds = DEEP_SLEEP_ON;
+ auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME;
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_802_11_PS_MODE_ENH,
+ EN_AUTO_PS, BITMAP_AUTO_DS,
+ &auto_ds);
+ if (ret)
+ return -1;
+ }
+
+ /* Send cmd to FW to enable/disable 11D function */
+ state_11d = ENABLE_11D;
+ ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SNMP_MIB,
+ HostCmd_ACT_GEN_SET, DOT11D_I, &state_11d);
+ if (ret)
+ dev_err(priv->adapter->dev, "11D: failed to enable 11D\n");
+
+ /* set last_init_cmd */
+ priv->adapter->last_init_cmd = HostCmd_CMD_802_11_SNMP_MIB;
+ ret = -EINPROGRESS;
+
+ return ret;
+}
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
new file mode 100644
index 00000000000..d08f76429a0
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -0,0 +1,972 @@
+/*
+ * Marvell Wireless LAN device driver: station command response handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+
+/*
+ * This function handles the command response error case.
+ *
+ * For scan response error, the function cancels all the pending
+ * scan commands and generates an event to inform the applications
+ * of the scan completion.
+ *
+ * For Power Save command failure, we do not retry enter PS
+ * command in case of Ad-hoc mode.
+ *
+ * For all other response errors, the current command buffer is freed
+ * and returned to the free command queue.
+ */
+static void
+mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ struct cmd_ctrl_node *cmd_node = NULL, *tmp_node;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct host_cmd_ds_802_11_ps_mode_enh *pm;
+ unsigned long flags;
+
+ dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n",
+ resp->command, resp->result);
+
+ if (adapter->curr_cmd->wait_q_enabled)
+ adapter->cmd_wait_q.status = -1;
+
+ switch (le16_to_cpu(resp->command)) {
+ case HostCmd_CMD_802_11_PS_MODE_ENH:
+ pm = &resp->params.psmode_enh;
+ dev_err(adapter->dev, "PS_MODE_ENH cmd failed: "
+ "result=0x%x action=0x%X\n",
+ resp->result, le16_to_cpu(pm->action));
+ /* We do not re-try enter-ps command in ad-hoc mode. */
+ if (le16_to_cpu(pm->action) == EN_AUTO_PS &&
+ (le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) &&
+ priv->bss_mode == NL80211_IFTYPE_ADHOC)
+ adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
+
+ break;
+ case HostCmd_CMD_802_11_SCAN:
+ /* Cancel all pending scan command */
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ list_for_each_entry_safe(cmd_node, tmp_node,
+ &adapter->scan_pending_q, list) {
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+ flags);
+ mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ }
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ adapter->scan_processing = false;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+ if (priv->report_scan_result)
+ priv->report_scan_result = false;
+ if (priv->scan_pending_on_block) {
+ priv->scan_pending_on_block = false;
+ up(&priv->async_sem);
+ }
+ break;
+
+ case HostCmd_CMD_MAC_CONTROL:
+ break;
+
+ default:
+ break;
+ }
+ /* Handling errors here */
+ mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
+
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ adapter->curr_cmd = NULL;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+}
+
+/*
+ * This function handles the command response of get RSSI info.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and saving the following parameters in driver -
+ * - Last data and beacon RSSI value
+ * - Average data and beacon RSSI value
+ * - Last data and beacon NF value
+ * - Average data and beacon NF value
+ *
+ * The parameters are send to the application as well, along with
+ * calculated SNR values.
+ */
+static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp,
+ void *data_buf)
+{
+ struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp =
+ &resp->params.rssi_info_rsp;
+ struct mwifiex_ds_get_signal *signal;
+
+ priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last);
+ priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last);
+
+ priv->data_rssi_avg = le16_to_cpu(rssi_info_rsp->data_rssi_avg);
+ priv->data_nf_avg = le16_to_cpu(rssi_info_rsp->data_nf_avg);
+
+ priv->bcn_rssi_last = le16_to_cpu(rssi_info_rsp->bcn_rssi_last);
+ priv->bcn_nf_last = le16_to_cpu(rssi_info_rsp->bcn_nf_last);
+
+ priv->bcn_rssi_avg = le16_to_cpu(rssi_info_rsp->bcn_rssi_avg);
+ priv->bcn_nf_avg = le16_to_cpu(rssi_info_rsp->bcn_nf_avg);
+
+ /* Need to indicate IOCTL complete */
+ if (data_buf) {
+ signal = (struct mwifiex_ds_get_signal *) data_buf;
+ memset(signal, 0, sizeof(struct mwifiex_ds_get_signal));
+
+ signal->selector = ALL_RSSI_INFO_MASK;
+
+ /* RSSI */
+ signal->bcn_rssi_last = priv->bcn_rssi_last;
+ signal->bcn_rssi_avg = priv->bcn_rssi_avg;
+ signal->data_rssi_last = priv->data_rssi_last;
+ signal->data_rssi_avg = priv->data_rssi_avg;
+
+ /* SNR */
+ signal->bcn_snr_last =
+ CAL_SNR(priv->bcn_rssi_last, priv->bcn_nf_last);
+ signal->bcn_snr_avg =
+ CAL_SNR(priv->bcn_rssi_avg, priv->bcn_nf_avg);
+ signal->data_snr_last =
+ CAL_SNR(priv->data_rssi_last, priv->data_nf_last);
+ signal->data_snr_avg =
+ CAL_SNR(priv->data_rssi_avg, priv->data_nf_avg);
+
+ /* NF */
+ signal->bcn_nf_last = priv->bcn_nf_last;
+ signal->bcn_nf_avg = priv->bcn_nf_avg;
+ signal->data_nf_last = priv->data_nf_last;
+ signal->data_nf_avg = priv->data_nf_avg;
+ }
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of set/get SNMP
+ * MIB parameters.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and saving the parameter in driver.
+ *
+ * The following parameters are supported -
+ * - Fragmentation threshold
+ * - RTS threshold
+ * - Short retry limit
+ */
+static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp,
+ void *data_buf)
+{
+ struct host_cmd_ds_802_11_snmp_mib *smib = &resp->params.smib;
+ u16 oid = le16_to_cpu(smib->oid);
+ u16 query_type = le16_to_cpu(smib->query_type);
+ u32 ul_temp;
+
+ dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x,"
+ " query_type = %#x, buf size = %#x\n",
+ oid, query_type, le16_to_cpu(smib->buf_size));
+ if (query_type == HostCmd_ACT_GEN_GET) {
+ ul_temp = le16_to_cpu(*((__le16 *) (smib->value)));
+ if (data_buf)
+ *(u32 *)data_buf = ul_temp;
+ switch (oid) {
+ case FRAG_THRESH_I:
+ dev_dbg(priv->adapter->dev,
+ "info: SNMP_RESP: FragThsd =%u\n", ul_temp);
+ break;
+ case RTS_THRESH_I:
+ dev_dbg(priv->adapter->dev,
+ "info: SNMP_RESP: RTSThsd =%u\n", ul_temp);
+ break;
+ case SHORT_RETRY_LIM_I:
+ dev_dbg(priv->adapter->dev,
+ "info: SNMP_RESP: TxRetryCount=%u\n", ul_temp);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of get log request
+ *
+ * Handling includes changing the header fields into CPU format
+ * and sending the received parameters to application.
+ */
+static int mwifiex_ret_get_log(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp,
+ void *data_buf)
+{
+ struct host_cmd_ds_802_11_get_log *get_log =
+ (struct host_cmd_ds_802_11_get_log *) &resp->params.get_log;
+ struct mwifiex_ds_get_stats *stats;
+
+ if (data_buf) {
+ stats = (struct mwifiex_ds_get_stats *) data_buf;
+ stats->mcast_tx_frame = le32_to_cpu(get_log->mcast_tx_frame);
+ stats->failed = le32_to_cpu(get_log->failed);
+ stats->retry = le32_to_cpu(get_log->retry);
+ stats->multi_retry = le32_to_cpu(get_log->multi_retry);
+ stats->frame_dup = le32_to_cpu(get_log->frame_dup);
+ stats->rts_success = le32_to_cpu(get_log->rts_success);
+ stats->rts_failure = le32_to_cpu(get_log->rts_failure);
+ stats->ack_failure = le32_to_cpu(get_log->ack_failure);
+ stats->rx_frag = le32_to_cpu(get_log->rx_frag);
+ stats->mcast_rx_frame = le32_to_cpu(get_log->mcast_rx_frame);
+ stats->fcs_error = le32_to_cpu(get_log->fcs_error);
+ stats->tx_frame = le32_to_cpu(get_log->tx_frame);
+ stats->wep_icv_error[0] =
+ le32_to_cpu(get_log->wep_icv_err_cnt[0]);
+ stats->wep_icv_error[1] =
+ le32_to_cpu(get_log->wep_icv_err_cnt[1]);
+ stats->wep_icv_error[2] =
+ le32_to_cpu(get_log->wep_icv_err_cnt[2]);
+ stats->wep_icv_error[3] =
+ le32_to_cpu(get_log->wep_icv_err_cnt[3]);
+ }
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of set/get Tx rate
+ * configurations.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and saving the following parameters in driver -
+ * - DSSS rate bitmap
+ * - OFDM rate bitmap
+ * - HT MCS rate bitmaps
+ *
+ * Based on the new rate bitmaps, the function re-evaluates if
+ * auto data rate has been activated. If not, it sends another
+ * query to the firmware to get the current Tx data rate and updates
+ * the driver value.
+ */
+static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp,
+ void *data_buf)
+{
+ struct mwifiex_rate_cfg *ds_rate;
+ struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg;
+ struct mwifiex_rate_scope *rate_scope;
+ struct mwifiex_ie_types_header *head;
+ u16 tlv, tlv_buf_len;
+ u8 *tlv_buf;
+ u32 i;
+ int ret = 0;
+
+ tlv_buf = (u8 *) ((u8 *) rate_cfg) +
+ sizeof(struct host_cmd_ds_tx_rate_cfg);
+ tlv_buf_len = *(u16 *) (tlv_buf + sizeof(u16));
+
+ while (tlv_buf && tlv_buf_len > 0) {
+ tlv = (*tlv_buf);
+ tlv = tlv | (*(tlv_buf + 1) << 8);
+
+ switch (tlv) {
+ case TLV_TYPE_RATE_SCOPE:
+ rate_scope = (struct mwifiex_rate_scope *) tlv_buf;
+ priv->bitmap_rates[0] =
+ le16_to_cpu(rate_scope->hr_dsss_rate_bitmap);
+ priv->bitmap_rates[1] =
+ le16_to_cpu(rate_scope->ofdm_rate_bitmap);
+ for (i = 0;
+ i <
+ sizeof(rate_scope->ht_mcs_rate_bitmap) /
+ sizeof(u16); i++)
+ priv->bitmap_rates[2 + i] =
+ le16_to_cpu(rate_scope->
+ ht_mcs_rate_bitmap[i]);
+ break;
+ /* Add RATE_DROP tlv here */
+ }
+
+ head = (struct mwifiex_ie_types_header *) tlv_buf;
+ tlv_buf += le16_to_cpu(head->len) + sizeof(*head);
+ tlv_buf_len -= le16_to_cpu(head->len);
+ }
+
+ priv->is_data_rate_auto = mwifiex_is_rate_auto(priv);
+
+ if (priv->is_data_rate_auto)
+ priv->data_rate = 0;
+ else
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_802_11_TX_RATE_QUERY,
+ HostCmd_ACT_GEN_GET, 0, NULL);
+
+ if (data_buf) {
+ ds_rate = (struct mwifiex_rate_cfg *) data_buf;
+ if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) {
+ if (priv->is_data_rate_auto) {
+ ds_rate->is_rate_auto = 1;
+ } else {
+ ds_rate->rate = mwifiex_get_rate_index(priv->
+ bitmap_rates,
+ sizeof(priv->
+ bitmap_rates));
+ if (ds_rate->rate >=
+ MWIFIEX_RATE_BITMAP_OFDM0
+ && ds_rate->rate <=
+ MWIFIEX_RATE_BITMAP_OFDM7)
+ ds_rate->rate -=
+ (MWIFIEX_RATE_BITMAP_OFDM0 -
+ MWIFIEX_RATE_INDEX_OFDM0);
+ if (ds_rate->rate >=
+ MWIFIEX_RATE_BITMAP_MCS0
+ && ds_rate->rate <=
+ MWIFIEX_RATE_BITMAP_MCS127)
+ ds_rate->rate -=
+ (MWIFIEX_RATE_BITMAP_MCS0 -
+ MWIFIEX_RATE_INDEX_MCS0);
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * This function handles the command response of get Tx power level.
+ *
+ * Handling includes saving the maximum and minimum Tx power levels
+ * in driver, as well as sending the values to user.
+ */
+static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf)
+{
+ int length, max_power = -1, min_power = -1;
+ struct mwifiex_types_power_group *pg_tlv_hdr;
+ struct mwifiex_power_group *pg;
+
+ if (data_buf) {
+ pg_tlv_hdr =
+ (struct mwifiex_types_power_group *) ((u8 *) data_buf
+ + sizeof(struct host_cmd_ds_txpwr_cfg));
+ pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr +
+ sizeof(struct mwifiex_types_power_group));
+ length = pg_tlv_hdr->length;
+ if (length > 0) {
+ max_power = pg->power_max;
+ min_power = pg->power_min;
+ length -= sizeof(struct mwifiex_power_group);
+ }
+ while (length) {
+ pg++;
+ if (max_power < pg->power_max)
+ max_power = pg->power_max;
+
+ if (min_power > pg->power_min)
+ min_power = pg->power_min;
+
+ length -= sizeof(struct mwifiex_power_group);
+ }
+ if (pg_tlv_hdr->length > 0) {
+ priv->min_tx_power_level = (u8) min_power;
+ priv->max_tx_power_level = (u8) max_power;
+ }
+ } else {
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of set/get Tx power
+ * configurations.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and saving the current Tx power level in driver.
+ */
+static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp,
+ void *data_buf)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct host_cmd_ds_txpwr_cfg *txp_cfg = &resp->params.txp_cfg;
+ struct mwifiex_types_power_group *pg_tlv_hdr;
+ struct mwifiex_power_group *pg;
+ u16 action = le16_to_cpu(txp_cfg->action);
+
+ switch (action) {
+ case HostCmd_ACT_GEN_GET:
+ {
+ pg_tlv_hdr =
+ (struct mwifiex_types_power_group *) ((u8 *)
+ txp_cfg +
+ sizeof
+ (struct
+ host_cmd_ds_txpwr_cfg));
+ pg = (struct mwifiex_power_group *) ((u8 *)
+ pg_tlv_hdr +
+ sizeof(struct
+ mwifiex_types_power_group));
+ if (adapter->hw_status ==
+ MWIFIEX_HW_STATUS_INITIALIZING)
+ mwifiex_get_power_level(priv, txp_cfg);
+ priv->tx_power_level = (u16) pg->power_min;
+ break;
+ }
+ case HostCmd_ACT_GEN_SET:
+ if (le32_to_cpu(txp_cfg->mode)) {
+ pg_tlv_hdr =
+ (struct mwifiex_types_power_group *) ((u8 *)
+ txp_cfg +
+ sizeof
+ (struct
+ host_cmd_ds_txpwr_cfg));
+ pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr
+ +
+ sizeof(struct
+ mwifiex_types_power_group));
+ if (pg->power_max == pg->power_min)
+ priv->tx_power_level = (u16) pg->power_min;
+ }
+ break;
+ default:
+ dev_err(adapter->dev, "CMD_RESP: unknown cmd action %d\n",
+ action);
+ return 0;
+ }
+ dev_dbg(adapter->dev,
+ "info: Current TxPower Level = %d, Max Power=%d, Min Power=%d\n",
+ priv->tx_power_level, priv->max_tx_power_level,
+ priv->min_tx_power_level);
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of set/get MAC address.
+ *
+ * Handling includes saving the MAC address in driver.
+ */
+static int mwifiex_ret_802_11_mac_address(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ struct host_cmd_ds_802_11_mac_address *cmd_mac_addr =
+ &resp->params.mac_addr;
+
+ memcpy(priv->curr_addr, cmd_mac_addr->mac_addr, ETH_ALEN);
+
+ dev_dbg(priv->adapter->dev,
+ "info: set mac address: %pM\n", priv->curr_addr);
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of set/get MAC multicast
+ * address.
+ */
+static int mwifiex_ret_mac_multicast_adr(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ return 0;
+}
+
+/*
+ * This function handles the command response of get Tx rate query.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and saving the Tx rate and HT information parameters in driver.
+ *
+ * Both rate configuration and current data rate can be retrieved
+ * with this request.
+ */
+static int mwifiex_ret_802_11_tx_rate_query(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ priv->tx_rate = resp->params.tx_rate.tx_rate;
+ priv->tx_htinfo = resp->params.tx_rate.ht_info;
+ if (!priv->is_data_rate_auto)
+ priv->data_rate =
+ mwifiex_index_to_data_rate(priv->tx_rate,
+ priv->tx_htinfo);
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of a deauthenticate
+ * command.
+ *
+ * If the deauthenticated MAC matches the current BSS MAC, the connection
+ * state is reset.
+ */
+static int mwifiex_ret_802_11_deauthenticate(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+
+ adapter->dbg.num_cmd_deauth++;
+ if (!memcmp(resp->params.deauth.mac_addr,
+ &priv->curr_bss_params.bss_descriptor.mac_address,
+ sizeof(resp->params.deauth.mac_addr)))
+ mwifiex_reset_connect_state(priv);
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of ad-hoc stop.
+ *
+ * The function resets the connection state in driver.
+ */
+static int mwifiex_ret_802_11_ad_hoc_stop(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ mwifiex_reset_connect_state(priv);
+ return 0;
+}
+
+/*
+ * This function handles the command response of set/get key material.
+ *
+ * Handling includes updating the driver parameters to reflect the
+ * changes.
+ */
+static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ struct host_cmd_ds_802_11_key_material *key =
+ &resp->params.key_material;
+
+ if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) {
+ if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) {
+ dev_dbg(priv->adapter->dev, "info: key: GTK is set\n");
+ priv->wpa_is_gtk_set = true;
+ priv->scan_block = false;
+ }
+ }
+
+ memset(priv->aes_key.key_param_set.key, 0,
+ sizeof(key->key_param_set.key));
+ priv->aes_key.key_param_set.key_len = key->key_param_set.key_len;
+ memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key,
+ le16_to_cpu(priv->aes_key.key_param_set.key_len));
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of get 11d domain information.
+ */
+static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ struct host_cmd_ds_802_11d_domain_info_rsp *domain_info =
+ &resp->params.domain_info_resp;
+ struct mwifiex_ietypes_domain_param_set *domain = &domain_info->domain;
+ u16 action = le16_to_cpu(domain_info->action);
+ u8 no_of_triplet;
+
+ no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) -
+ IEEE80211_COUNTRY_STRING_LEN) /
+ sizeof(struct ieee80211_country_ie_triplet));
+
+ dev_dbg(priv->adapter->dev, "info: 11D Domain Info Resp:"
+ " no_of_triplet=%d\n", no_of_triplet);
+
+ if (no_of_triplet > MWIFIEX_MAX_TRIPLET_802_11D) {
+ dev_warn(priv->adapter->dev,
+ "11D: invalid number of triplets %d "
+ "returned!!\n", no_of_triplet);
+ return -1;
+ }
+
+ switch (action) {
+ case HostCmd_ACT_GEN_SET: /* Proc Set Action */
+ break;
+ case HostCmd_ACT_GEN_GET:
+ break;
+ default:
+ dev_err(priv->adapter->dev,
+ "11D: invalid action:%d\n", domain_info->action);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of get RF channel.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and saving the new channel in driver.
+ */
+static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp,
+ void *data_buf)
+{
+ struct host_cmd_ds_802_11_rf_channel *rf_channel =
+ &resp->params.rf_channel;
+ u16 new_channel = le16_to_cpu(rf_channel->current_channel);
+
+ if (priv->curr_bss_params.bss_descriptor.channel != new_channel) {
+ dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n",
+ priv->curr_bss_params.bss_descriptor.channel,
+ new_channel);
+ /* Update the channel again */
+ priv->curr_bss_params.bss_descriptor.channel = new_channel;
+ }
+ if (data_buf)
+ *((u16 *)data_buf) = new_channel;
+
+ return 0;
+}
+
+/*
+ * This function handles the command response of get extended version.
+ *
+ * Handling includes forming the extended version string and sending it
+ * to application.
+ */
+static int mwifiex_ret_ver_ext(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp,
+ void *data_buf)
+{
+ struct host_cmd_ds_version_ext *ver_ext = &resp->params.verext;
+ struct host_cmd_ds_version_ext *version_ext;
+
+ if (data_buf) {
+ version_ext = (struct host_cmd_ds_version_ext *)data_buf;
+ version_ext->version_str_sel = ver_ext->version_str_sel;
+ memcpy(version_ext->version_str, ver_ext->version_str,
+ sizeof(char) * 128);
+ memcpy(priv->version_str, ver_ext->version_str, 128);
+ }
+ return 0;
+}
+
+/*
+ * This function handles the command response of register access.
+ *
+ * The register value and offset are returned to the user. For EEPROM
+ * access, the byte count is also returned.
+ */
+static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp,
+ void *data_buf)
+{
+ struct mwifiex_ds_reg_rw *reg_rw;
+ struct mwifiex_ds_read_eeprom *eeprom;
+
+ if (data_buf) {
+ reg_rw = (struct mwifiex_ds_reg_rw *) data_buf;
+ eeprom = (struct mwifiex_ds_read_eeprom *) data_buf;
+ switch (type) {
+ case HostCmd_CMD_MAC_REG_ACCESS:
+ {
+ struct host_cmd_ds_mac_reg_access *reg;
+ reg = (struct host_cmd_ds_mac_reg_access *)
+ &resp->params.mac_reg;
+ reg_rw->offset = cpu_to_le32(
+ (u32) le16_to_cpu(reg->offset));
+ reg_rw->value = reg->value;
+ break;
+ }
+ case HostCmd_CMD_BBP_REG_ACCESS:
+ {
+ struct host_cmd_ds_bbp_reg_access *reg;
+ reg = (struct host_cmd_ds_bbp_reg_access *)
+ &resp->params.bbp_reg;
+ reg_rw->offset = cpu_to_le32(
+ (u32) le16_to_cpu(reg->offset));
+ reg_rw->value = cpu_to_le32((u32) reg->value);
+ break;
+ }
+
+ case HostCmd_CMD_RF_REG_ACCESS:
+ {
+ struct host_cmd_ds_rf_reg_access *reg;
+ reg = (struct host_cmd_ds_rf_reg_access *)
+ &resp->params.rf_reg;
+ reg_rw->offset = cpu_to_le32(
+ (u32) le16_to_cpu(reg->offset));
+ reg_rw->value = cpu_to_le32((u32) reg->value);
+ break;
+ }
+ case HostCmd_CMD_PMIC_REG_ACCESS:
+ {
+ struct host_cmd_ds_pmic_reg_access *reg;
+ reg = (struct host_cmd_ds_pmic_reg_access *)
+ &resp->params.pmic_reg;
+ reg_rw->offset = cpu_to_le32(
+ (u32) le16_to_cpu(reg->offset));
+ reg_rw->value = cpu_to_le32((u32) reg->value);
+ break;
+ }
+ case HostCmd_CMD_CAU_REG_ACCESS:
+ {
+ struct host_cmd_ds_rf_reg_access *reg;
+ reg = (struct host_cmd_ds_rf_reg_access *)
+ &resp->params.rf_reg;
+ reg_rw->offset = cpu_to_le32(
+ (u32) le16_to_cpu(reg->offset));
+ reg_rw->value = cpu_to_le32((u32) reg->value);
+ break;
+ }
+ case HostCmd_CMD_802_11_EEPROM_ACCESS:
+ {
+ struct host_cmd_ds_802_11_eeprom_access
+ *cmd_eeprom =
+ (struct host_cmd_ds_802_11_eeprom_access
+ *) &resp->params.eeprom;
+ pr_debug("info: EEPROM read len=%x\n",
+ cmd_eeprom->byte_count);
+ if (le16_to_cpu(eeprom->byte_count) <
+ le16_to_cpu(
+ cmd_eeprom->byte_count)) {
+ eeprom->byte_count = cpu_to_le16(0);
+ pr_debug("info: EEPROM read "
+ "length is too big\n");
+ return -1;
+ }
+ eeprom->offset = cmd_eeprom->offset;
+ eeprom->byte_count = cmd_eeprom->byte_count;
+ if (le16_to_cpu(eeprom->byte_count) > 0)
+ memcpy(&eeprom->value,
+ &cmd_eeprom->value,
+ le16_to_cpu(eeprom->byte_count));
+
+ break;
+ }
+ default:
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * This function handles the command response of get IBSS coalescing status.
+ *
+ * If the received BSSID is different than the current one, the current BSSID,
+ * beacon interval, ATIM window and ERP information are updated, along with
+ * changing the ad-hoc state accordingly.
+ */
+static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ struct host_cmd_ds_802_11_ibss_status *ibss_coal_resp =
+ &(resp->params.ibss_coalescing);
+ u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+
+ if (le16_to_cpu(ibss_coal_resp->action) == HostCmd_ACT_GEN_SET)
+ return 0;
+
+ dev_dbg(priv->adapter->dev,
+ "info: new BSSID %pM\n", ibss_coal_resp->bssid);
+
+ /* If rsp has NULL BSSID, Just return..... No Action */
+ if (!memcmp(ibss_coal_resp->bssid, zero_mac, ETH_ALEN)) {
+ dev_warn(priv->adapter->dev, "new BSSID is NULL\n");
+ return 0;
+ }
+
+ /* If BSSID is diff, modify current BSS parameters */
+ if (memcmp(priv->curr_bss_params.bss_descriptor.mac_address,
+ ibss_coal_resp->bssid, ETH_ALEN)) {
+ /* BSSID */
+ memcpy(priv->curr_bss_params.bss_descriptor.mac_address,
+ ibss_coal_resp->bssid, ETH_ALEN);
+
+ /* Beacon Interval */
+ priv->curr_bss_params.bss_descriptor.beacon_period
+ = le16_to_cpu(ibss_coal_resp->beacon_interval);
+
+ /* ERP Information */
+ priv->curr_bss_params.bss_descriptor.erp_flags =
+ (u8) le16_to_cpu(ibss_coal_resp->use_g_rate_protect);
+
+ priv->adhoc_state = ADHOC_COALESCED;
+ }
+
+ return 0;
+}
+
+/*
+ * This function handles the command responses.
+ *
+ * This is a generic function, which calls command specific
+ * response handlers based on the command ID.
+ */
+int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv,
+ u16 cmdresp_no, void *cmd_buf)
+{
+ int ret = 0;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct host_cmd_ds_command *resp =
+ (struct host_cmd_ds_command *) cmd_buf;
+ void *data_buf = adapter->curr_cmd->data_buf;
+
+ /* If the command is not successful, cleanup and return failure */
+ if (resp->result != HostCmd_RESULT_OK) {
+ mwifiex_process_cmdresp_error(priv, resp);
+ return -1;
+ }
+ /* Command successful, handle response */
+ switch (cmdresp_no) {
+ case HostCmd_CMD_GET_HW_SPEC:
+ ret = mwifiex_ret_get_hw_spec(priv, resp);
+ break;
+ case HostCmd_CMD_MAC_CONTROL:
+ break;
+ case HostCmd_CMD_802_11_MAC_ADDRESS:
+ ret = mwifiex_ret_802_11_mac_address(priv, resp);
+ break;
+ case HostCmd_CMD_MAC_MULTICAST_ADR:
+ ret = mwifiex_ret_mac_multicast_adr(priv, resp);
+ break;
+ case HostCmd_CMD_TX_RATE_CFG:
+ ret = mwifiex_ret_tx_rate_cfg(priv, resp, data_buf);
+ break;
+ case HostCmd_CMD_802_11_SCAN:
+ ret = mwifiex_ret_802_11_scan(priv, resp);
+ adapter->curr_cmd->wait_q_enabled = false;
+ break;
+ case HostCmd_CMD_802_11_BG_SCAN_QUERY:
+ ret = mwifiex_ret_802_11_scan(priv, resp);
+ dev_dbg(adapter->dev,
+ "info: CMD_RESP: BG_SCAN result is ready!\n");
+ break;
+ case HostCmd_CMD_TXPWR_CFG:
+ ret = mwifiex_ret_tx_power_cfg(priv, resp, data_buf);
+ break;
+ case HostCmd_CMD_802_11_PS_MODE_ENH:
+ ret = mwifiex_ret_enh_power_mode(priv, resp, data_buf);
+ break;
+ case HostCmd_CMD_802_11_HS_CFG_ENH:
+ ret = mwifiex_ret_802_11_hs_cfg(priv, resp);
+ break;
+ case HostCmd_CMD_802_11_ASSOCIATE:
+ ret = mwifiex_ret_802_11_associate(priv, resp);
+ break;
+ case HostCmd_CMD_802_11_DEAUTHENTICATE:
+ ret = mwifiex_ret_802_11_deauthenticate(priv, resp);
+ break;
+ case HostCmd_CMD_802_11_AD_HOC_START:
+ case HostCmd_CMD_802_11_AD_HOC_JOIN:
+ ret = mwifiex_ret_802_11_ad_hoc(priv, resp);
+ break;
+ case HostCmd_CMD_802_11_AD_HOC_STOP:
+ ret = mwifiex_ret_802_11_ad_hoc_stop(priv, resp);
+ break;
+ case HostCmd_CMD_802_11_GET_LOG:
+ ret = mwifiex_ret_get_log(priv, resp, data_buf);
+ break;
+ case HostCmd_CMD_RSSI_INFO:
+ ret = mwifiex_ret_802_11_rssi_info(priv, resp, data_buf);
+ break;
+ case HostCmd_CMD_802_11_SNMP_MIB:
+ ret = mwifiex_ret_802_11_snmp_mib(priv, resp, data_buf);
+ break;
+ case HostCmd_CMD_802_11_TX_RATE_QUERY:
+ ret = mwifiex_ret_802_11_tx_rate_query(priv, resp);
+ break;
+ case HostCmd_CMD_802_11_RF_CHANNEL:
+ ret = mwifiex_ret_802_11_rf_channel(priv, resp, data_buf);
+ break;
+ case HostCmd_CMD_VERSION_EXT:
+ ret = mwifiex_ret_ver_ext(priv, resp, data_buf);
+ break;
+ case HostCmd_CMD_FUNC_INIT:
+ case HostCmd_CMD_FUNC_SHUTDOWN:
+ break;
+ case HostCmd_CMD_802_11_KEY_MATERIAL:
+ ret = mwifiex_ret_802_11_key_material(priv, resp);
+ break;
+ case HostCmd_CMD_802_11D_DOMAIN_INFO:
+ ret = mwifiex_ret_802_11d_domain_info(priv, resp);
+ break;
+ case HostCmd_CMD_11N_ADDBA_REQ:
+ ret = mwifiex_ret_11n_addba_req(priv, resp);
+ break;
+ case HostCmd_CMD_11N_DELBA:
+ ret = mwifiex_ret_11n_delba(priv, resp);
+ break;
+ case HostCmd_CMD_11N_ADDBA_RSP:
+ ret = mwifiex_ret_11n_addba_resp(priv, resp);
+ break;
+ case HostCmd_CMD_RECONFIGURE_TX_BUFF:
+ adapter->tx_buf_size = (u16) le16_to_cpu(resp->params.
+ tx_buf.buff_size);
+ adapter->tx_buf_size = (adapter->tx_buf_size /
+ MWIFIEX_SDIO_BLOCK_SIZE) *
+ MWIFIEX_SDIO_BLOCK_SIZE;
+ adapter->curr_tx_buf_size = adapter->tx_buf_size;
+ dev_dbg(adapter->dev,
+ "cmd: max_tx_buf_size=%d, tx_buf_size=%d\n",
+ adapter->max_tx_buf_size, adapter->tx_buf_size);
+
+ if (adapter->if_ops.update_mp_end_port)
+ adapter->if_ops.update_mp_end_port(adapter,
+ le16_to_cpu(resp->
+ params.
+ tx_buf.
+ mp_end_port));
+ break;
+ case HostCmd_CMD_AMSDU_AGGR_CTRL:
+ ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf);
+ break;
+ case HostCmd_CMD_WMM_GET_STATUS:
+ ret = mwifiex_ret_wmm_get_status(priv, resp);
+ break;
+ case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
+ ret = mwifiex_ret_ibss_coalescing_status(priv, resp);
+ break;
+ case HostCmd_CMD_MAC_REG_ACCESS:
+ case HostCmd_CMD_BBP_REG_ACCESS:
+ case HostCmd_CMD_RF_REG_ACCESS:
+ case HostCmd_CMD_PMIC_REG_ACCESS:
+ case HostCmd_CMD_CAU_REG_ACCESS:
+ case HostCmd_CMD_802_11_EEPROM_ACCESS:
+ ret = mwifiex_ret_reg_access(cmdresp_no, resp, data_buf);
+ break;
+ case HostCmd_CMD_SET_BSS_MODE:
+ break;
+ case HostCmd_CMD_11N_CFG:
+ ret = mwifiex_ret_11n_cfg(resp, data_buf);
+ break;
+ default:
+ dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
+ resp->command);
+ break;
+ }
+
+ return ret;
+}
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
new file mode 100644
index 00000000000..fc265cab090
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -0,0 +1,406 @@
+/*
+ * Marvell Wireless LAN device driver: station event handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+/*
+ * This function resets the connection state.
+ *
+ * The function is invoked after receiving a disconnect event from firmware,
+ * and performs the following actions -
+ * - Set media status to disconnected
+ * - Clean up Tx and Rx packets
+ * - Resets SNR/NF/RSSI value in driver
+ * - Resets security configurations in driver
+ * - Enables auto data rate
+ * - Saves the previous SSID and BSSID so that they can
+ * be used for re-association, if required
+ * - Erases current SSID and BSSID information
+ * - Sends a disconnect event to upper layers/applications.
+ */
+void
+mwifiex_reset_connect_state(struct mwifiex_private *priv)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+
+ if (!priv->media_connected)
+ return;
+
+ dev_dbg(adapter->dev, "info: handles disconnect event\n");
+
+ priv->media_connected = false;
+
+ priv->scan_block = false;
+
+ /* Free Tx and Rx packets, report disconnect to upper layer */
+ mwifiex_clean_txrx(priv);
+
+ /* Reset SNR/NF/RSSI values */
+ priv->data_rssi_last = 0;
+ priv->data_nf_last = 0;
+ priv->data_rssi_avg = 0;
+ priv->data_nf_avg = 0;
+ priv->bcn_rssi_last = 0;
+ priv->bcn_nf_last = 0;
+ priv->bcn_rssi_avg = 0;
+ priv->bcn_nf_avg = 0;
+ priv->rxpd_rate = 0;
+ priv->rxpd_htinfo = 0;
+ priv->sec_info.wpa_enabled = false;
+ priv->sec_info.wpa2_enabled = false;
+ priv->wpa_ie_len = 0;
+
+ priv->sec_info.wapi_enabled = false;
+ priv->wapi_ie_len = 0;
+ priv->sec_info.wapi_key_on = false;
+
+ priv->sec_info.encryption_mode = 0;
+
+ /* Enable auto data rate */
+ priv->is_data_rate_auto = true;
+ priv->data_rate = 0;
+
+ if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
+ priv->adhoc_state = ADHOC_IDLE;
+ priv->adhoc_is_link_sensed = false;
+ }
+
+ /*
+ * Memorize the previous SSID and BSSID so
+ * it could be used for re-assoc
+ */
+
+ dev_dbg(adapter->dev, "info: previous SSID=%s, SSID len=%u\n",
+ priv->prev_ssid.ssid, priv->prev_ssid.ssid_len);
+
+ dev_dbg(adapter->dev, "info: current SSID=%s, SSID len=%u\n",
+ priv->curr_bss_params.bss_descriptor.ssid.ssid,
+ priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
+
+ memcpy(&priv->prev_ssid,
+ &priv->curr_bss_params.bss_descriptor.ssid,
+ sizeof(struct mwifiex_802_11_ssid));
+
+ memcpy(priv->prev_bssid,
+ priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN);
+
+ /* Need to erase the current SSID and BSSID info */
+ memset(&priv->curr_bss_params, 0x00, sizeof(priv->curr_bss_params));
+
+ adapter->tx_lock_flag = false;
+ adapter->pps_uapsd_mode = false;
+
+ if (adapter->num_cmd_timeout && adapter->curr_cmd)
+ return;
+ priv->media_connected = false;
+ if (!priv->disconnect) {
+ priv->disconnect = 1;
+ dev_dbg(adapter->dev, "info: successfully disconnected from"
+ " %pM: reason code %d\n", priv->cfg_bssid,
+ WLAN_REASON_DEAUTH_LEAVING);
+ cfg80211_disconnected(priv->netdev,
+ WLAN_REASON_DEAUTH_LEAVING, NULL, 0,
+ GFP_KERNEL);
+ queue_work(priv->workqueue, &priv->cfg_workqueue);
+ }
+ if (!netif_queue_stopped(priv->netdev))
+ netif_stop_queue(priv->netdev);
+ if (netif_carrier_ok(priv->netdev))
+ netif_carrier_off(priv->netdev);
+ /* Reset wireless stats signal info */
+ priv->w_stats.qual.level = 0;
+ priv->w_stats.qual.noise = 0;
+}
+
+/*
+ * This function handles events generated by firmware.
+ *
+ * This is a generic function and handles all events.
+ *
+ * Event specific routines are called by this function based
+ * upon the generated event cause.
+ *
+ * For the following events, the function just forwards them to upper
+ * layers, optionally recording the change -
+ * - EVENT_LINK_SENSED
+ * - EVENT_MIC_ERR_UNICAST
+ * - EVENT_MIC_ERR_MULTICAST
+ * - EVENT_PORT_RELEASE
+ * - EVENT_RSSI_LOW
+ * - EVENT_SNR_LOW
+ * - EVENT_MAX_FAIL
+ * - EVENT_RSSI_HIGH
+ * - EVENT_SNR_HIGH
+ * - EVENT_DATA_RSSI_LOW
+ * - EVENT_DATA_SNR_LOW
+ * - EVENT_DATA_RSSI_HIGH
+ * - EVENT_DATA_SNR_HIGH
+ * - EVENT_LINK_QUALITY
+ * - EVENT_PRE_BEACON_LOST
+ * - EVENT_IBSS_COALESCED
+ * - EVENT_WEP_ICV_ERR
+ * - EVENT_BW_CHANGE
+ * - EVENT_HOSTWAKE_STAIE
+ *
+ * For the following events, no action is taken -
+ * - EVENT_MIB_CHANGED
+ * - EVENT_INIT_DONE
+ * - EVENT_DUMMY_HOST_WAKEUP_SIGNAL
+ *
+ * Rest of the supported events requires driver handling -
+ * - EVENT_DEAUTHENTICATED
+ * - EVENT_DISASSOCIATED
+ * - EVENT_LINK_LOST
+ * - EVENT_PS_SLEEP
+ * - EVENT_PS_AWAKE
+ * - EVENT_DEEP_SLEEP_AWAKE
+ * - EVENT_HS_ACT_REQ
+ * - EVENT_ADHOC_BCN_LOST
+ * - EVENT_BG_SCAN_REPORT
+ * - EVENT_WMM_STATUS_CHANGE
+ * - EVENT_ADDBA
+ * - EVENT_DELBA
+ * - EVENT_BA_STREAM_TIEMOUT
+ * - EVENT_AMSDU_AGGR_CTRL
+ */
+int mwifiex_process_sta_event(struct mwifiex_private *priv)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ int ret = 0;
+ u32 eventcause = adapter->event_cause;
+
+ switch (eventcause) {
+ case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
+ dev_err(adapter->dev, "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL,"
+ " ignoring it\n");
+ break;
+ case EVENT_LINK_SENSED:
+ dev_dbg(adapter->dev, "event: LINK_SENSED\n");
+ if (!netif_carrier_ok(priv->netdev))
+ netif_carrier_on(priv->netdev);
+ if (netif_queue_stopped(priv->netdev))
+ netif_wake_queue(priv->netdev);
+ break;
+
+ case EVENT_DEAUTHENTICATED:
+ dev_dbg(adapter->dev, "event: Deauthenticated\n");
+ adapter->dbg.num_event_deauth++;
+ if (priv->media_connected)
+ mwifiex_reset_connect_state(priv);
+ break;
+
+ case EVENT_DISASSOCIATED:
+ dev_dbg(adapter->dev, "event: Disassociated\n");
+ adapter->dbg.num_event_disassoc++;
+ if (priv->media_connected)
+ mwifiex_reset_connect_state(priv);
+ break;
+
+ case EVENT_LINK_LOST:
+ dev_dbg(adapter->dev, "event: Link lost\n");
+ adapter->dbg.num_event_link_lost++;
+ if (priv->media_connected)
+ mwifiex_reset_connect_state(priv);
+ break;
+
+ case EVENT_PS_SLEEP:
+ dev_dbg(adapter->dev, "info: EVENT: SLEEP\n");
+
+ adapter->ps_state = PS_STATE_PRE_SLEEP;
+
+ mwifiex_check_ps_cond(adapter);
+ break;
+
+ case EVENT_PS_AWAKE:
+ dev_dbg(adapter->dev, "info: EVENT: AWAKE\n");
+ if (!adapter->pps_uapsd_mode &&
+ priv->media_connected &&
+ adapter->sleep_period.period) {
+ adapter->pps_uapsd_mode = true;
+ dev_dbg(adapter->dev,
+ "event: PPS/UAPSD mode activated\n");
+ }
+ adapter->tx_lock_flag = false;
+ if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
+ if (mwifiex_check_last_packet_indication(priv)) {
+ if (!adapter->data_sent) {
+ if (!mwifiex_send_null_packet(priv,
+ MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET
+ |
+ MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET))
+ adapter->ps_state =
+ PS_STATE_SLEEP;
+ return 0;
+ }
+ }
+ }
+ adapter->ps_state = PS_STATE_AWAKE;
+ adapter->pm_wakeup_card_req = false;
+ adapter->pm_wakeup_fw_try = false;
+
+ break;
+
+ case EVENT_DEEP_SLEEP_AWAKE:
+ adapter->if_ops.wakeup_complete(adapter);
+ dev_dbg(adapter->dev, "event: DS_AWAKE\n");
+ if (adapter->is_deep_sleep)
+ adapter->is_deep_sleep = false;
+ break;
+
+ case EVENT_HS_ACT_REQ:
+ dev_dbg(adapter->dev, "event: HS_ACT_REQ\n");
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_802_11_HS_CFG_ENH,
+ 0, 0, NULL);
+ break;
+
+ case EVENT_MIC_ERR_UNICAST:
+ dev_dbg(adapter->dev, "event: UNICAST MIC ERROR\n");
+ break;
+
+ case EVENT_MIC_ERR_MULTICAST:
+ dev_dbg(adapter->dev, "event: MULTICAST MIC ERROR\n");
+ break;
+ case EVENT_MIB_CHANGED:
+ case EVENT_INIT_DONE:
+ break;
+
+ case EVENT_ADHOC_BCN_LOST:
+ dev_dbg(adapter->dev, "event: ADHOC_BCN_LOST\n");
+ priv->adhoc_is_link_sensed = false;
+ mwifiex_clean_txrx(priv);
+ if (!netif_queue_stopped(priv->netdev))
+ netif_stop_queue(priv->netdev);
+ if (netif_carrier_ok(priv->netdev))
+ netif_carrier_off(priv->netdev);
+ break;
+
+ case EVENT_BG_SCAN_REPORT:
+ dev_dbg(adapter->dev, "event: BGS_REPORT\n");
+ /* Clear the previous scan result */
+ memset(adapter->scan_table, 0x00,
+ sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP);
+ adapter->num_in_scan_table = 0;
+ adapter->bcn_buf_end = adapter->bcn_buf;
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_802_11_BG_SCAN_QUERY,
+ HostCmd_ACT_GEN_GET, 0, NULL);
+ break;
+
+ case EVENT_PORT_RELEASE:
+ dev_dbg(adapter->dev, "event: PORT RELEASE\n");
+ break;
+
+ case EVENT_WMM_STATUS_CHANGE:
+ dev_dbg(adapter->dev, "event: WMM status changed\n");
+ ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_WMM_GET_STATUS,
+ 0, 0, NULL);
+ break;
+
+ case EVENT_RSSI_LOW:
+ dev_dbg(adapter->dev, "event: Beacon RSSI_LOW\n");
+ break;
+ case EVENT_SNR_LOW:
+ dev_dbg(adapter->dev, "event: Beacon SNR_LOW\n");
+ break;
+ case EVENT_MAX_FAIL:
+ dev_dbg(adapter->dev, "event: MAX_FAIL\n");
+ break;
+ case EVENT_RSSI_HIGH:
+ dev_dbg(adapter->dev, "event: Beacon RSSI_HIGH\n");
+ break;
+ case EVENT_SNR_HIGH:
+ dev_dbg(adapter->dev, "event: Beacon SNR_HIGH\n");
+ break;
+ case EVENT_DATA_RSSI_LOW:
+ dev_dbg(adapter->dev, "event: Data RSSI_LOW\n");
+ break;
+ case EVENT_DATA_SNR_LOW:
+ dev_dbg(adapter->dev, "event: Data SNR_LOW\n");
+ break;
+ case EVENT_DATA_RSSI_HIGH:
+ dev_dbg(adapter->dev, "event: Data RSSI_HIGH\n");
+ break;
+ case EVENT_DATA_SNR_HIGH:
+ dev_dbg(adapter->dev, "event: Data SNR_HIGH\n");
+ break;
+ case EVENT_LINK_QUALITY:
+ dev_dbg(adapter->dev, "event: Link Quality\n");
+ break;
+ case EVENT_PRE_BEACON_LOST:
+ dev_dbg(adapter->dev, "event: Pre-Beacon Lost\n");
+ break;
+ case EVENT_IBSS_COALESCED:
+ dev_dbg(adapter->dev, "event: IBSS_COALESCED\n");
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
+ HostCmd_ACT_GEN_GET, 0, NULL);
+ break;
+ case EVENT_ADDBA:
+ dev_dbg(adapter->dev, "event: ADDBA Request\n");
+ mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_RSP,
+ HostCmd_ACT_GEN_SET, 0,
+ adapter->event_body);
+ break;
+ case EVENT_DELBA:
+ dev_dbg(adapter->dev, "event: DELBA Request\n");
+ mwifiex_11n_delete_ba_stream(priv, adapter->event_body);
+ break;
+ case EVENT_BA_STREAM_TIEMOUT:
+ dev_dbg(adapter->dev, "event: BA Stream timeout\n");
+ mwifiex_11n_ba_stream_timeout(priv,
+ (struct host_cmd_ds_11n_batimeout
+ *)
+ adapter->event_body);
+ break;
+ case EVENT_AMSDU_AGGR_CTRL:
+ dev_dbg(adapter->dev, "event: AMSDU_AGGR_CTRL %d\n",
+ *(u16 *) adapter->event_body);
+ adapter->tx_buf_size =
+ min(adapter->curr_tx_buf_size,
+ le16_to_cpu(*(__le16 *) adapter->event_body));
+ dev_dbg(adapter->dev, "event: tx_buf_size %d\n",
+ adapter->tx_buf_size);
+ break;
+
+ case EVENT_WEP_ICV_ERR:
+ dev_dbg(adapter->dev, "event: WEP ICV error\n");
+ break;
+
+ case EVENT_BW_CHANGE:
+ dev_dbg(adapter->dev, "event: BW Change\n");
+ break;
+
+ case EVENT_HOSTWAKE_STAIE:
+ dev_dbg(adapter->dev, "event: HOSTWAKE_STAIE %d\n", eventcause);
+ break;
+ default:
+ dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
+ eventcause);
+ break;
+ }
+
+ return ret;
+}
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
new file mode 100644
index 00000000000..d05907d0503
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -0,0 +1,1593 @@
+/*
+ * Marvell Wireless LAN device driver: functions for station ioctl
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+#include "cfg80211.h"
+
+/*
+ * Copies the multicast address list from device to driver.
+ *
+ * This function does not validate the destination memory for
+ * size, and the calling function must ensure enough memory is
+ * available.
+ */
+int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
+ struct net_device *dev)
+{
+ int i = 0;
+ struct netdev_hw_addr *ha;
+
+ netdev_for_each_mc_addr(ha, dev)
+ memcpy(&mlist->mac_list[i++], ha->addr, ETH_ALEN);
+
+ return i;
+}
+
+/*
+ * Wait queue completion handler.
+ *
+ * This function waits on a cmd wait queue. It also cancels the pending
+ * request after waking up, in case of errors.
+ */
+int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
+{
+ bool cancel_flag = false;
+ int status = adapter->cmd_wait_q.status;
+
+ dev_dbg(adapter->dev, "cmd pending\n");
+ atomic_inc(&adapter->cmd_pending);
+
+ /* Status pending, wake up main process */
+ queue_work(adapter->workqueue, &adapter->main_work);
+
+ /* Wait for completion */
+ wait_event_interruptible(adapter->cmd_wait_q.wait,
+ adapter->cmd_wait_q.condition);
+ if (!adapter->cmd_wait_q.condition)
+ cancel_flag = true;
+
+ if (cancel_flag) {
+ mwifiex_cancel_pending_ioctl(adapter);
+ dev_dbg(adapter->dev, "cmd cancel\n");
+ }
+ adapter->cmd_wait_q.status = 0;
+
+ return status;
+}
+
+/*
+ * This function prepares the correct firmware command and
+ * issues it to set the multicast list.
+ *
+ * This function can be used to enable promiscuous mode, or enable all
+ * multicast packets, or to enable selective multicast.
+ */
+int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
+ struct mwifiex_multicast_list *mcast_list)
+{
+ int ret = 0;
+ u16 old_pkt_filter;
+
+ old_pkt_filter = priv->curr_pkt_filter;
+
+ if (mcast_list->mode == MWIFIEX_PROMISC_MODE) {
+ dev_dbg(priv->adapter->dev, "info: Enable Promiscuous mode\n");
+ priv->curr_pkt_filter |= HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
+ priv->curr_pkt_filter &=
+ ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
+ } else {
+ /* Multicast */
+ priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
+ if (mcast_list->mode == MWIFIEX_MULTICAST_MODE) {
+ dev_dbg(priv->adapter->dev,
+ "info: Enabling All Multicast!\n");
+ priv->curr_pkt_filter |=
+ HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
+ } else {
+ priv->curr_pkt_filter &=
+ ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
+ if (mcast_list->num_multicast_addr) {
+ dev_dbg(priv->adapter->dev,
+ "info: Set multicast list=%d\n",
+ mcast_list->num_multicast_addr);
+ /* Set multicast addresses to firmware */
+ if (old_pkt_filter == priv->curr_pkt_filter) {
+ /* Send request to firmware */
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_MAC_MULTICAST_ADR,
+ HostCmd_ACT_GEN_SET, 0,
+ mcast_list);
+ } else {
+ /* Send request to firmware */
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_MAC_MULTICAST_ADR,
+ HostCmd_ACT_GEN_SET, 0,
+ mcast_list);
+ }
+ }
+ }
+ }
+ dev_dbg(priv->adapter->dev,
+ "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n",
+ old_pkt_filter, priv->curr_pkt_filter);
+ if (old_pkt_filter != priv->curr_pkt_filter) {
+ ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
+ HostCmd_ACT_GEN_SET,
+ 0, &priv->curr_pkt_filter);
+ }
+
+ return ret;
+}
+
+/*
+ * In Ad-Hoc mode, the IBSS is created if not found in scan list.
+ * In both Ad-Hoc and infra mode, an deauthentication is performed
+ * first.
+ */
+int mwifiex_bss_start(struct mwifiex_private *priv,
+ struct mwifiex_ssid_bssid *ssid_bssid)
+{
+ int ret;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ s32 i = -1;
+
+ priv->scan_block = false;
+ if (!ssid_bssid)
+ return -1;
+
+ if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+ /* Infra mode */
+ ret = mwifiex_deauthenticate(priv, NULL);
+ if (ret)
+ return ret;
+
+ /* Search for the requested SSID in the scan table */
+ if (ssid_bssid->ssid.ssid_len)
+ i = mwifiex_find_ssid_in_list(priv, &ssid_bssid->ssid,
+ NULL, NL80211_IFTYPE_STATION);
+ else
+ i = mwifiex_find_bssid_in_list(priv,
+ (u8 *) &ssid_bssid->bssid,
+ NL80211_IFTYPE_STATION);
+ if (i < 0)
+ return -1;
+
+ dev_dbg(adapter->dev,
+ "info: SSID found in scan list ... associating...\n");
+
+ /* Clear any past association response stored for
+ * application retrieval */
+ priv->assoc_rsp_size = 0;
+ ret = mwifiex_associate(priv, &adapter->scan_table[i]);
+ if (ret)
+ return ret;
+ } else {
+ /* Adhoc mode */
+ /* If the requested SSID matches current SSID, return */
+ if (ssid_bssid->ssid.ssid_len &&
+ (!mwifiex_ssid_cmp
+ (&priv->curr_bss_params.bss_descriptor.ssid,
+ &ssid_bssid->ssid)))
+ return 0;
+
+ /* Exit Adhoc mode first */
+ dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n");
+ ret = mwifiex_deauthenticate(priv, NULL);
+ if (ret)
+ return ret;
+
+ priv->adhoc_is_link_sensed = false;
+
+ /* Search for the requested network in the scan table */
+ if (ssid_bssid->ssid.ssid_len)
+ i = mwifiex_find_ssid_in_list(priv,
+ &ssid_bssid->ssid, NULL,
+ NL80211_IFTYPE_ADHOC);
+ else
+ i = mwifiex_find_bssid_in_list(priv,
+ (u8 *)&ssid_bssid->bssid,
+ NL80211_IFTYPE_ADHOC);
+
+ if (i >= 0) {
+ dev_dbg(adapter->dev, "info: network found in scan"
+ " list. Joining...\n");
+ ret = mwifiex_adhoc_join(priv, &adapter->scan_table[i]);
+ if (ret)
+ return ret;
+ } else {
+ dev_dbg(adapter->dev, "info: Network not found in "
+ "the list, creating adhoc with ssid = %s\n",
+ ssid_bssid->ssid.ssid);
+ ret = mwifiex_adhoc_start(priv, &ssid_bssid->ssid);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * IOCTL request handler to set host sleep configuration.
+ *
+ * This function prepares the correct firmware command and
+ * issues it.
+ */
+int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
+ int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg)
+
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ int status = 0;
+ u32 prev_cond = 0;
+
+ if (!hs_cfg)
+ return -ENOMEM;
+
+ switch (action) {
+ case HostCmd_ACT_GEN_SET:
+ if (adapter->pps_uapsd_mode) {
+ dev_dbg(adapter->dev, "info: Host Sleep IOCTL"
+ " is blocked in UAPSD/PPS mode\n");
+ status = -1;
+ break;
+ }
+ if (hs_cfg->is_invoke_hostcmd) {
+ if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) {
+ if (!adapter->is_hs_configured)
+ /* Already cancelled */
+ break;
+ /* Save previous condition */
+ prev_cond = le32_to_cpu(adapter->hs_cfg
+ .conditions);
+ adapter->hs_cfg.conditions =
+ cpu_to_le32(hs_cfg->conditions);
+ } else if (hs_cfg->conditions) {
+ adapter->hs_cfg.conditions =
+ cpu_to_le32(hs_cfg->conditions);
+ adapter->hs_cfg.gpio = (u8)hs_cfg->gpio;
+ if (hs_cfg->gap)
+ adapter->hs_cfg.gap = (u8)hs_cfg->gap;
+ } else if (adapter->hs_cfg.conditions ==
+ cpu_to_le32(
+ HOST_SLEEP_CFG_CANCEL)) {
+ /* Return failure if no parameters for HS
+ enable */
+ status = -1;
+ break;
+ }
+ if (cmd_type == MWIFIEX_SYNC_CMD)
+ status = mwifiex_send_cmd_sync(priv,
+ HostCmd_CMD_802_11_HS_CFG_ENH,
+ HostCmd_ACT_GEN_SET, 0,
+ &adapter->hs_cfg);
+ else
+ status = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_802_11_HS_CFG_ENH,
+ HostCmd_ACT_GEN_SET, 0,
+ &adapter->hs_cfg);
+ if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL)
+ /* Restore previous condition */
+ adapter->hs_cfg.conditions =
+ cpu_to_le32(prev_cond);
+ } else {
+ adapter->hs_cfg.conditions =
+ cpu_to_le32(hs_cfg->conditions);
+ adapter->hs_cfg.gpio = (u8)hs_cfg->gpio;
+ adapter->hs_cfg.gap = (u8)hs_cfg->gap;
+ }
+ break;
+ case HostCmd_ACT_GEN_GET:
+ hs_cfg->conditions = le32_to_cpu(adapter->hs_cfg.conditions);
+ hs_cfg->gpio = adapter->hs_cfg.gpio;
+ hs_cfg->gap = adapter->hs_cfg.gap;
+ break;
+ default:
+ status = -1;
+ break;
+ }
+
+ return status;
+}
+
+/*
+ * Sends IOCTL request to cancel the existing Host Sleep configuration.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type)
+{
+ struct mwifiex_ds_hs_cfg hscfg;
+
+ hscfg.conditions = HOST_SLEEP_CFG_CANCEL;
+ hscfg.is_invoke_hostcmd = true;
+
+ return mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
+ cmd_type, &hscfg);
+}
+EXPORT_SYMBOL_GPL(mwifiex_cancel_hs);
+
+/*
+ * Sends IOCTL request to cancel the existing Host Sleep configuration.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
+{
+ struct mwifiex_ds_hs_cfg hscfg;
+
+ if (adapter->hs_activated) {
+ dev_dbg(adapter->dev, "cmd: HS Already actived\n");
+ return true;
+ }
+
+ adapter->hs_activate_wait_q_woken = false;
+
+ memset(&hscfg, 0, sizeof(struct mwifiex_hs_config_param));
+ hscfg.is_invoke_hostcmd = true;
+
+ if (mwifiex_set_hs_params(mwifiex_get_priv(adapter,
+ MWIFIEX_BSS_ROLE_STA),
+ HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD,
+ &hscfg)) {
+ dev_err(adapter->dev, "IOCTL request HS enable failed\n");
+ return false;
+ }
+
+ wait_event_interruptible(adapter->hs_activate_wait_q,
+ adapter->hs_activate_wait_q_woken);
+
+ return true;
+}
+EXPORT_SYMBOL_GPL(mwifiex_enable_hs);
+
+/*
+ * IOCTL request handler to get BSS information.
+ *
+ * This function collates the information from different driver structures
+ * to send to the user.
+ */
+int mwifiex_get_bss_info(struct mwifiex_private *priv,
+ struct mwifiex_bss_info *info)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct mwifiex_bssdescriptor *bss_desc;
+ s32 tbl_idx;
+
+ if (!info)
+ return -1;
+
+ bss_desc = &priv->curr_bss_params.bss_descriptor;
+
+ info->bss_mode = priv->bss_mode;
+
+ memcpy(&info->ssid, &bss_desc->ssid,
+ sizeof(struct mwifiex_802_11_ssid));
+
+ memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN);
+
+ info->bss_chan = bss_desc->channel;
+
+ info->region_code = adapter->region_code;
+
+ /* Scan table index if connected */
+ info->scan_table_idx = 0;
+ if (priv->media_connected) {
+ tbl_idx =
+ mwifiex_find_ssid_in_list(priv, &bss_desc->ssid,
+ bss_desc->mac_address,
+ priv->bss_mode);
+ if (tbl_idx >= 0)
+ info->scan_table_idx = tbl_idx;
+ }
+
+ info->media_connected = priv->media_connected;
+
+ info->max_power_level = priv->max_tx_power_level;
+ info->min_power_level = priv->min_tx_power_level;
+
+ info->adhoc_state = priv->adhoc_state;
+
+ info->bcn_nf_last = priv->bcn_nf_last;
+
+ if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED)
+ info->wep_status = true;
+ else
+ info->wep_status = false;
+
+ info->is_hs_configured = adapter->is_hs_configured;
+ info->is_deep_sleep = adapter->is_deep_sleep;
+
+ return 0;
+}
+
+/*
+ * The function sets band configurations.
+ *
+ * it performs extra checks to make sure the Ad-Hoc
+ * band and channel are compatible. Otherwise it returns an error.
+ *
+ */
+int mwifiex_set_radio_band_cfg(struct mwifiex_private *priv,
+ struct mwifiex_ds_band_cfg *radio_cfg)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ u8 infra_band, adhoc_band;
+ u32 adhoc_channel;
+
+ infra_band = (u8) radio_cfg->config_bands;
+ adhoc_band = (u8) radio_cfg->adhoc_start_band;
+ adhoc_channel = radio_cfg->adhoc_channel;
+
+ /* SET Infra band */
+ if ((infra_band | adapter->fw_bands) & ~adapter->fw_bands)
+ return -1;
+
+ adapter->config_bands = infra_band;
+
+ /* SET Ad-hoc Band */
+ if ((adhoc_band | adapter->fw_bands) & ~adapter->fw_bands)
+ return -1;
+
+ if (adhoc_band)
+ adapter->adhoc_start_band = adhoc_band;
+ adapter->chan_offset = (u8) radio_cfg->sec_chan_offset;
+ /*
+ * If no adhoc_channel is supplied verify if the existing adhoc
+ * channel compiles with new adhoc_band
+ */
+ if (!adhoc_channel) {
+ if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211
+ (priv, adapter->adhoc_start_band,
+ priv->adhoc_channel)) {
+ /* Pass back the default channel */
+ radio_cfg->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
+ if ((adapter->adhoc_start_band & BAND_A)
+ || (adapter->adhoc_start_band & BAND_AN))
+ radio_cfg->adhoc_channel =
+ DEFAULT_AD_HOC_CHANNEL_A;
+ }
+ } else { /* Retrurn error if adhoc_band and
+ adhoc_channel combination is invalid */
+ if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211
+ (priv, adapter->adhoc_start_band, (u16) adhoc_channel))
+ return -1;
+ priv->adhoc_channel = (u8) adhoc_channel;
+ }
+ if ((adhoc_band & BAND_GN) || (adhoc_band & BAND_AN))
+ adapter->adhoc_11n_enabled = true;
+ else
+ adapter->adhoc_11n_enabled = false;
+
+ return 0;
+}
+
+/*
+ * IOCTL request handler to set/get active channel.
+ *
+ * This function performs validity checking on channel/frequency
+ * compatibility and returns failure if not valid.
+ */
+int mwifiex_bss_set_channel(struct mwifiex_private *priv,
+ struct mwifiex_chan_freq_power *chan)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct mwifiex_chan_freq_power *cfp = NULL;
+
+ if (!chan)
+ return -1;
+
+ if (!chan->channel && !chan->freq)
+ return -1;
+ if (adapter->adhoc_start_band & BAND_AN)
+ adapter->adhoc_start_band = BAND_G | BAND_B | BAND_GN;
+ else if (adapter->adhoc_start_band & BAND_A)
+ adapter->adhoc_start_band = BAND_G | BAND_B;
+ if (chan->channel) {
+ if (chan->channel <= MAX_CHANNEL_BAND_BG)
+ cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211
+ (priv, 0, (u16) chan->channel);
+ if (!cfp) {
+ cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211
+ (priv, BAND_A, (u16) chan->channel);
+ if (cfp) {
+ if (adapter->adhoc_11n_enabled)
+ adapter->adhoc_start_band = BAND_A
+ | BAND_AN;
+ else
+ adapter->adhoc_start_band = BAND_A;
+ }
+ }
+ } else {
+ if (chan->freq <= MAX_FREQUENCY_BAND_BG)
+ cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211(
+ priv, 0, chan->freq);
+ if (!cfp) {
+ cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211
+ (priv, BAND_A, chan->freq);
+ if (cfp) {
+ if (adapter->adhoc_11n_enabled)
+ adapter->adhoc_start_band = BAND_A
+ | BAND_AN;
+ else
+ adapter->adhoc_start_band = BAND_A;
+ }
+ }
+ }
+ if (!cfp || !cfp->channel) {
+ dev_err(adapter->dev, "invalid channel/freq\n");
+ return -1;
+ }
+ priv->adhoc_channel = (u8) cfp->channel;
+ chan->channel = cfp->channel;
+ chan->freq = cfp->freq;
+
+ return 0;
+}
+
+/*
+ * IOCTL request handler to set/get Ad-Hoc channel.
+ *
+ * This function prepares the correct firmware command and
+ * issues it to set or get the ad-hoc channel.
+ */
+static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv,
+ u16 action, u16 *channel)
+{
+ if (action == HostCmd_ACT_GEN_GET) {
+ if (!priv->media_connected) {
+ *channel = priv->adhoc_channel;
+ return 0;
+ }
+ } else {
+ priv->adhoc_channel = (u8) *channel;
+ }
+
+ return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL,
+ action, 0, channel);
+}
+
+/*
+ * IOCTL request handler to find a particular BSS.
+ *
+ * The BSS can be searched with either a BSSID or a SSID. If none of
+ * these are provided, just the best BSS (best RSSI) is returned.
+ */
+int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv,
+ struct mwifiex_ssid_bssid *ssid_bssid)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct mwifiex_bssdescriptor *bss_desc;
+ u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+ u8 mac[ETH_ALEN];
+ int i = 0;
+
+ if (memcmp(ssid_bssid->bssid, zero_mac, sizeof(zero_mac))) {
+ i = mwifiex_find_bssid_in_list(priv,
+ (u8 *) ssid_bssid->bssid,
+ priv->bss_mode);
+ if (i < 0) {
+ memcpy(mac, ssid_bssid->bssid, sizeof(mac));
+ dev_err(adapter->dev, "cannot find bssid %pM\n", mac);
+ return -1;
+ }
+ bss_desc = &adapter->scan_table[i];
+ memcpy(&ssid_bssid->ssid, &bss_desc->ssid,
+ sizeof(struct mwifiex_802_11_ssid));
+ } else if (ssid_bssid->ssid.ssid_len) {
+ i = mwifiex_find_ssid_in_list(priv, &ssid_bssid->ssid, NULL,
+ priv->bss_mode);
+ if (i < 0) {
+ dev_err(adapter->dev, "cannot find ssid %s\n",
+ ssid_bssid->ssid.ssid);
+ return -1;
+ }
+ bss_desc = &adapter->scan_table[i];
+ memcpy(ssid_bssid->bssid, bss_desc->mac_address, ETH_ALEN);
+ } else {
+ return mwifiex_find_best_network(priv, ssid_bssid);
+ }
+
+ return 0;
+}
+
+/*
+ * IOCTL request handler to change Ad-Hoc channel.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ *
+ * The function follows the following steps to perform the change -
+ * - Get current IBSS information
+ * - Get current channel
+ * - If no change is required, return
+ * - If not connected, change channel and return
+ * - If connected,
+ * - Disconnect
+ * - Change channel
+ * - Perform specific SSID scan with same SSID
+ * - Start/Join the IBSS
+ */
+int
+mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
+{
+ int ret;
+ struct mwifiex_bss_info bss_info;
+ struct mwifiex_ssid_bssid ssid_bssid;
+ u16 curr_chan = 0;
+
+ memset(&bss_info, 0, sizeof(bss_info));
+
+ /* Get BSS information */
+ if (mwifiex_get_bss_info(priv, &bss_info))
+ return -1;
+
+ /* Get current channel */
+ ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_GET,
+ &curr_chan);
+
+ if (curr_chan == channel) {
+ ret = 0;
+ goto done;
+ }
+ dev_dbg(priv->adapter->dev, "cmd: updating channel from %d to %d\n",
+ curr_chan, channel);
+
+ if (!bss_info.media_connected) {
+ ret = 0;
+ goto done;
+ }
+
+ /* Do disonnect */
+ memset(&ssid_bssid, 0, ETH_ALEN);
+ ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid);
+
+ ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET,
+ (u16 *) &channel);
+
+ /* Do specific SSID scanning */
+ if (mwifiex_request_scan(priv, &bss_info.ssid)) {
+ ret = -1;
+ goto done;
+ }
+ /* Start/Join Adhoc network */
+ memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
+ memcpy(&ssid_bssid.ssid, &bss_info.ssid,
+ sizeof(struct mwifiex_802_11_ssid));
+
+ ret = mwifiex_bss_start(priv, &ssid_bssid);
+done:
+ return ret;
+}
+
+/*
+ * IOCTL request handler to get rate.
+ *
+ * This function prepares the correct firmware command and
+ * issues it to get the current rate if it is connected,
+ * otherwise, the function returns the lowest supported rate
+ * for the band.
+ */
+static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv,
+ struct mwifiex_rate_cfg *rate_cfg)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+
+ rate_cfg->is_rate_auto = priv->is_data_rate_auto;
+ if (!priv->media_connected) {
+ switch (adapter->config_bands) {
+ case BAND_B:
+ /* Return the lowest supported rate for B band */
+ rate_cfg->rate = supported_rates_b[0] & 0x7f;
+ break;
+ case BAND_G:
+ case BAND_G | BAND_GN:
+ /* Return the lowest supported rate for G band */
+ rate_cfg->rate = supported_rates_g[0] & 0x7f;
+ break;
+ case BAND_B | BAND_G:
+ case BAND_A | BAND_B | BAND_G:
+ case BAND_A | BAND_B:
+ case BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN:
+ case BAND_B | BAND_G | BAND_GN:
+ /* Return the lowest supported rate for BG band */
+ rate_cfg->rate = supported_rates_bg[0] & 0x7f;
+ break;
+ case BAND_A:
+ case BAND_A | BAND_G:
+ case BAND_A | BAND_G | BAND_AN | BAND_GN:
+ case BAND_A | BAND_AN:
+ /* Return the lowest supported rate for A band */
+ rate_cfg->rate = supported_rates_a[0] & 0x7f;
+ break;
+ case BAND_GN:
+ /* Return the lowest supported rate for N band */
+ rate_cfg->rate = supported_rates_n[0] & 0x7f;
+ break;
+ default:
+ dev_warn(adapter->dev, "invalid band %#x\n",
+ adapter->config_bands);
+ break;
+ }
+ } else {
+ return mwifiex_send_cmd_sync(priv,
+ HostCmd_CMD_802_11_TX_RATE_QUERY,
+ HostCmd_ACT_GEN_GET, 0, NULL);
+ }
+
+ return 0;
+}
+
+/*
+ * IOCTL request handler to set rate.
+ *
+ * This function prepares the correct firmware command and
+ * issues it to set the current rate.
+ *
+ * The function also performs validation checking on the supplied value.
+ */
+static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv,
+ struct mwifiex_rate_cfg *rate_cfg)
+{
+ u8 rates[MWIFIEX_SUPPORTED_RATES];
+ u8 *rate;
+ int rate_index, ret;
+ u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
+ u32 i;
+ struct mwifiex_adapter *adapter = priv->adapter;
+
+ if (rate_cfg->is_rate_auto) {
+ memset(bitmap_rates, 0, sizeof(bitmap_rates));
+ /* Support all HR/DSSS rates */
+ bitmap_rates[0] = 0x000F;
+ /* Support all OFDM rates */
+ bitmap_rates[1] = 0x00FF;
+ /* Support all HT-MCSs rate */
+ for (i = 0; i < ARRAY_SIZE(priv->bitmap_rates) - 3; i++)
+ bitmap_rates[i + 2] = 0xFFFF;
+ bitmap_rates[9] = 0x3FFF;
+ } else {
+ memset(rates, 0, sizeof(rates));
+ mwifiex_get_active_data_rates(priv, rates);
+ rate = rates;
+ for (i = 0; (rate[i] && i < MWIFIEX_SUPPORTED_RATES); i++) {
+ dev_dbg(adapter->dev, "info: rate=%#x wanted=%#x\n",
+ rate[i], rate_cfg->rate);
+ if ((rate[i] & 0x7f) == (rate_cfg->rate & 0x7f))
+ break;
+ }
+ if (!rate[i] || (i == MWIFIEX_SUPPORTED_RATES)) {
+ dev_err(adapter->dev, "fixed data rate %#x is out "
+ "of range\n", rate_cfg->rate);
+ return -1;
+ }
+ memset(bitmap_rates, 0, sizeof(bitmap_rates));
+
+ rate_index = mwifiex_data_rate_to_index(rate_cfg->rate);
+
+ /* Only allow b/g rates to be set */
+ if (rate_index >= MWIFIEX_RATE_INDEX_HRDSSS0 &&
+ rate_index <= MWIFIEX_RATE_INDEX_HRDSSS3) {
+ bitmap_rates[0] = 1 << rate_index;
+ } else {
+ rate_index -= 1; /* There is a 0x00 in the table */
+ if (rate_index >= MWIFIEX_RATE_INDEX_OFDM0 &&
+ rate_index <= MWIFIEX_RATE_INDEX_OFDM7)
+ bitmap_rates[1] = 1 << (rate_index -
+ MWIFIEX_RATE_INDEX_OFDM0);
+ }
+ }
+
+ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG,
+ HostCmd_ACT_GEN_SET, 0, bitmap_rates);
+
+ return ret;
+}
+
+/*
+ * IOCTL request handler to set/get rate.
+ *
+ * This function can be used to set/get either the rate value or the
+ * rate index.
+ */
+static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv,
+ struct mwifiex_rate_cfg *rate_cfg)
+{
+ int status;
+
+ if (!rate_cfg)
+ return -1;
+
+ if (rate_cfg->action == HostCmd_ACT_GEN_GET)
+ status = mwifiex_rate_ioctl_get_rate_value(priv, rate_cfg);
+ else
+ status = mwifiex_rate_ioctl_set_rate_value(priv, rate_cfg);
+
+ return status;
+}
+
+/*
+ * Sends IOCTL request to get the data rate.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
+ struct mwifiex_rate_cfg *rate)
+{
+ int ret;
+
+ memset(rate, 0, sizeof(struct mwifiex_rate_cfg));
+ rate->action = HostCmd_ACT_GEN_GET;
+ ret = mwifiex_rate_ioctl_cfg(priv, rate);
+
+ if (!ret) {
+ if (rate && rate->is_rate_auto)
+ rate->rate = mwifiex_index_to_data_rate(priv->tx_rate,
+ priv->tx_htinfo);
+ else if (rate)
+ rate->rate = priv->data_rate;
+ } else {
+ ret = -1;
+ }
+
+ return ret;
+}
+
+/*
+ * IOCTL request handler to set tx power configuration.
+ *
+ * This function prepares the correct firmware command and
+ * issues it.
+ *
+ * For non-auto power mode, all the following power groups are set -
+ * - Modulation class HR/DSSS
+ * - Modulation class OFDM
+ * - Modulation class HTBW20
+ * - Modulation class HTBW40
+ */
+int mwifiex_set_tx_power(struct mwifiex_private *priv,
+ struct mwifiex_power_cfg *power_cfg)
+{
+ int ret;
+ struct host_cmd_ds_txpwr_cfg *txp_cfg;
+ struct mwifiex_types_power_group *pg_tlv;
+ struct mwifiex_power_group *pg;
+ u8 *buf;
+ u16 dbm = 0;
+
+ if (!power_cfg->is_power_auto) {
+ dbm = (u16) power_cfg->power_level;
+ if ((dbm < priv->min_tx_power_level) ||
+ (dbm > priv->max_tx_power_level)) {
+ dev_err(priv->adapter->dev, "txpower value %d dBm"
+ " is out of range (%d dBm-%d dBm)\n",
+ dbm, priv->min_tx_power_level,
+ priv->max_tx_power_level);
+ return -1;
+ }
+ }
+ buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL);
+ if (!buf) {
+ dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ txp_cfg = (struct host_cmd_ds_txpwr_cfg *) buf;
+ txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
+ if (!power_cfg->is_power_auto) {
+ txp_cfg->mode = cpu_to_le32(1);
+ pg_tlv = (struct mwifiex_types_power_group *) (buf +
+ sizeof(struct host_cmd_ds_txpwr_cfg));
+ pg_tlv->type = TLV_TYPE_POWER_GROUP;
+ pg_tlv->length = 4 * sizeof(struct mwifiex_power_group);
+ pg = (struct mwifiex_power_group *) (buf +
+ sizeof(struct host_cmd_ds_txpwr_cfg) +
+ sizeof(struct mwifiex_types_power_group));
+ /* Power group for modulation class HR/DSSS */
+ pg->first_rate_code = 0x00;
+ pg->last_rate_code = 0x03;
+ pg->modulation_class = MOD_CLASS_HR_DSSS;
+ pg->power_step = 0;
+ pg->power_min = (s8) dbm;
+ pg->power_max = (s8) dbm;
+ pg++;
+ /* Power group for modulation class OFDM */
+ pg->first_rate_code = 0x00;
+ pg->last_rate_code = 0x07;
+ pg->modulation_class = MOD_CLASS_OFDM;
+ pg->power_step = 0;
+ pg->power_min = (s8) dbm;
+ pg->power_max = (s8) dbm;
+ pg++;
+ /* Power group for modulation class HTBW20 */
+ pg->first_rate_code = 0x00;
+ pg->last_rate_code = 0x20;
+ pg->modulation_class = MOD_CLASS_HT;
+ pg->power_step = 0;
+ pg->power_min = (s8) dbm;
+ pg->power_max = (s8) dbm;
+ pg->ht_bandwidth = HT_BW_20;
+ pg++;
+ /* Power group for modulation class HTBW40 */
+ pg->first_rate_code = 0x00;
+ pg->last_rate_code = 0x20;
+ pg->modulation_class = MOD_CLASS_HT;
+ pg->power_step = 0;
+ pg->power_min = (s8) dbm;
+ pg->power_max = (s8) dbm;
+ pg->ht_bandwidth = HT_BW_40;
+ }
+ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TXPWR_CFG,
+ HostCmd_ACT_GEN_SET, 0, buf);
+
+ kfree(buf);
+ return ret;
+}
+
+/*
+ * IOCTL request handler to get power save mode.
+ *
+ * This function prepares the correct firmware command and
+ * issues it.
+ */
+int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode)
+{
+ int ret;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ u16 sub_cmd;
+
+ if (*ps_mode)
+ adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
+ else
+ adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
+ sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS;
+ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
+ sub_cmd, BITMAP_STA_PS, NULL);
+ if ((!ret) && (sub_cmd == DIS_AUTO_PS))
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS,
+ 0, NULL);
+
+ return ret;
+}
+
+/*
+ * IOCTL request handler to set/reset WPA IE.
+ *
+ * The supplied WPA IE is treated as a opaque buffer. Only the first field
+ * is checked to determine WPA version. If buffer length is zero, the existing
+ * WPA IE is reset.
+ */
+static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv,
+ u8 *ie_data_ptr, u16 ie_len)
+{
+ if (ie_len) {
+ if (ie_len > sizeof(priv->wpa_ie)) {
+ dev_err(priv->adapter->dev,
+ "failed to copy WPA IE, too big\n");
+ return -1;
+ }
+ memcpy(priv->wpa_ie, ie_data_ptr, ie_len);
+ priv->wpa_ie_len = (u8) ie_len;
+ dev_dbg(priv->adapter->dev, "cmd: Set Wpa_ie_len=%d IE=%#x\n",
+ priv->wpa_ie_len, priv->wpa_ie[0]);
+
+ if (priv->wpa_ie[0] == WLAN_EID_WPA) {
+ priv->sec_info.wpa_enabled = true;
+ } else if (priv->wpa_ie[0] == WLAN_EID_RSN) {
+ priv->sec_info.wpa2_enabled = true;
+ } else {
+ priv->sec_info.wpa_enabled = false;
+ priv->sec_info.wpa2_enabled = false;
+ }
+ } else {
+ memset(priv->wpa_ie, 0, sizeof(priv->wpa_ie));
+ priv->wpa_ie_len = 0;
+ dev_dbg(priv->adapter->dev, "info: reset wpa_ie_len=%d IE=%#x\n",
+ priv->wpa_ie_len, priv->wpa_ie[0]);
+ priv->sec_info.wpa_enabled = false;
+ priv->sec_info.wpa2_enabled = false;
+ }
+
+ return 0;
+}
+
+/*
+ * IOCTL request handler to set/reset WAPI IE.
+ *
+ * The supplied WAPI IE is treated as a opaque buffer. Only the first field
+ * is checked to internally enable WAPI. If buffer length is zero, the existing
+ * WAPI IE is reset.
+ */
+static int mwifiex_set_wapi_ie(struct mwifiex_private *priv,
+ u8 *ie_data_ptr, u16 ie_len)
+{
+ if (ie_len) {
+ if (ie_len > sizeof(priv->wapi_ie)) {
+ dev_dbg(priv->adapter->dev,
+ "info: failed to copy WAPI IE, too big\n");
+ return -1;
+ }
+ memcpy(priv->wapi_ie, ie_data_ptr, ie_len);
+ priv->wapi_ie_len = ie_len;
+ dev_dbg(priv->adapter->dev, "cmd: Set wapi_ie_len=%d IE=%#x\n",
+ priv->wapi_ie_len, priv->wapi_ie[0]);
+
+ if (priv->wapi_ie[0] == WLAN_EID_BSS_AC_ACCESS_DELAY)
+ priv->sec_info.wapi_enabled = true;
+ } else {
+ memset(priv->wapi_ie, 0, sizeof(priv->wapi_ie));
+ priv->wapi_ie_len = ie_len;
+ dev_dbg(priv->adapter->dev,
+ "info: Reset wapi_ie_len=%d IE=%#x\n",
+ priv->wapi_ie_len, priv->wapi_ie[0]);
+ priv->sec_info.wapi_enabled = false;
+ }
+ return 0;
+}
+
+/*
+ * IOCTL request handler to set WAPI key.
+ *
+ * This function prepares the correct firmware command and
+ * issues it.
+ */
+static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv,
+ struct mwifiex_ds_encrypt_key *encrypt_key)
+{
+
+ return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
+ HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
+ encrypt_key);
+}
+
+/*
+ * IOCTL request handler to set WEP network key.
+ *
+ * This function prepares the correct firmware command and
+ * issues it, after validation checks.
+ */
+static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
+ struct mwifiex_ds_encrypt_key *encrypt_key)
+{
+ int ret;
+ struct mwifiex_wep_key *wep_key;
+ int index;
+
+ if (priv->wep_key_curr_index >= NUM_WEP_KEYS)
+ priv->wep_key_curr_index = 0;
+ wep_key = &priv->wep_key[priv->wep_key_curr_index];
+ index = encrypt_key->key_index;
+ if (encrypt_key->key_disable) {
+ priv->sec_info.wep_status = MWIFIEX_802_11_WEP_DISABLED;
+ } else if (!encrypt_key->key_len) {
+ /* Copy the required key as the current key */
+ wep_key = &priv->wep_key[index];
+ if (!wep_key->key_length) {
+ dev_err(priv->adapter->dev,
+ "key not set, so cannot enable it\n");
+ return -1;
+ }
+ priv->wep_key_curr_index = (u16) index;
+ priv->sec_info.wep_status = MWIFIEX_802_11_WEP_ENABLED;
+ } else {
+ wep_key = &priv->wep_key[index];
+ memset(wep_key, 0, sizeof(struct mwifiex_wep_key));
+ /* Copy the key in the driver */
+ memcpy(wep_key->key_material,
+ encrypt_key->key_material,
+ encrypt_key->key_len);
+ wep_key->key_index = index;
+ wep_key->key_length = encrypt_key->key_len;
+ priv->sec_info.wep_status = MWIFIEX_802_11_WEP_ENABLED;
+ }
+ if (wep_key->key_length) {
+ /* Send request to firmware */
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_802_11_KEY_MATERIAL,
+ HostCmd_ACT_GEN_SET, 0, NULL);
+ if (ret)
+ return ret;
+ }
+ if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED)
+ priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
+ else
+ priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
+
+ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL,
+ HostCmd_ACT_GEN_SET, 0,
+ &priv->curr_pkt_filter);
+
+ return ret;
+}
+
+/*
+ * IOCTL request handler to set WPA key.
+ *
+ * This function prepares the correct firmware command and
+ * issues it, after validation checks.
+ *
+ * Current driver only supports key length of up to 32 bytes.
+ *
+ * This function can also be used to disable a currently set key.
+ */
+static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv,
+ struct mwifiex_ds_encrypt_key *encrypt_key)
+{
+ int ret;
+ u8 remove_key = false;
+ struct host_cmd_ds_802_11_key_material *ibss_key;
+
+ /* Current driver only supports key length of up to 32 bytes */
+ if (encrypt_key->key_len > WLAN_MAX_KEY_LEN) {
+ dev_err(priv->adapter->dev, "key length too long\n");
+ return -1;
+ }
+
+ if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
+ /*
+ * IBSS/WPA-None uses only one key (Group) for both receiving
+ * and sending unicast and multicast packets.
+ */
+ /* Send the key as PTK to firmware */
+ encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_802_11_KEY_MATERIAL,
+ HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
+ encrypt_key);
+ if (ret)
+ return ret;
+
+ ibss_key = &priv->aes_key;
+ memset(ibss_key, 0,
+ sizeof(struct host_cmd_ds_802_11_key_material));
+ /* Copy the key in the driver */
+ memcpy(ibss_key->key_param_set.key, encrypt_key->key_material,
+ encrypt_key->key_len);
+ memcpy(&ibss_key->key_param_set.key_len, &encrypt_key->key_len,
+ sizeof(ibss_key->key_param_set.key_len));
+ ibss_key->key_param_set.key_type_id
+ = cpu_to_le16(KEY_TYPE_ID_TKIP);
+ ibss_key->key_param_set.key_info = cpu_to_le16(KEY_ENABLED);
+
+ /* Send the key as GTK to firmware */
+ encrypt_key->key_index = ~MWIFIEX_KEY_INDEX_UNICAST;
+ }
+
+ if (!encrypt_key->key_index)
+ encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
+
+ if (remove_key)
+ ret = mwifiex_send_cmd_sync(priv,
+ HostCmd_CMD_802_11_KEY_MATERIAL,
+ HostCmd_ACT_GEN_SET, !(KEY_INFO_ENABLED),
+ encrypt_key);
+ else
+ ret = mwifiex_send_cmd_sync(priv,
+ HostCmd_CMD_802_11_KEY_MATERIAL,
+ HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
+ encrypt_key);
+
+ return ret;
+}
+
+/*
+ * IOCTL request handler to set/get network keys.
+ *
+ * This is a generic key handling function which supports WEP, WPA
+ * and WAPI.
+ */
+static int
+mwifiex_sec_ioctl_encrypt_key(struct mwifiex_private *priv,
+ struct mwifiex_ds_encrypt_key *encrypt_key)
+{
+ int status;
+
+ if (encrypt_key->is_wapi_key)
+ status = mwifiex_sec_ioctl_set_wapi_key(priv, encrypt_key);
+ else if (encrypt_key->key_len > WLAN_KEY_LEN_WEP104)
+ status = mwifiex_sec_ioctl_set_wpa_key(priv, encrypt_key);
+ else
+ status = mwifiex_sec_ioctl_set_wep_key(priv, encrypt_key);
+ return status;
+}
+
+/*
+ * This function returns the driver version.
+ */
+int
+mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version,
+ int max_len)
+{
+ union {
+ u32 l;
+ u8 c[4];
+ } ver;
+ char fw_ver[32];
+
+ ver.l = adapter->fw_release_number;
+ sprintf(fw_ver, "%u.%u.%u.p%u", ver.c[2], ver.c[1], ver.c[0], ver.c[3]);
+
+ snprintf(version, max_len, driver_version, fw_ver);
+
+ dev_dbg(adapter->dev, "info: MWIFIEX VERSION: %s\n", version);
+
+ return 0;
+}
+
+/*
+ * Sends IOCTL request to get signal information.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int mwifiex_get_signal_info(struct mwifiex_private *priv,
+ struct mwifiex_ds_get_signal *signal)
+{
+ int status;
+
+ signal->selector = ALL_RSSI_INFO_MASK;
+
+ /* Signal info can be obtained only if connected */
+ if (!priv->media_connected) {
+ dev_dbg(priv->adapter->dev,
+ "info: Can not get signal in disconnected state\n");
+ return -1;
+ }
+
+ status = mwifiex_send_cmd_sync(priv, HostCmd_CMD_RSSI_INFO,
+ HostCmd_ACT_GEN_GET, 0, signal);
+
+ if (!status) {
+ if (signal->selector & BCN_RSSI_AVG_MASK)
+ priv->w_stats.qual.level = signal->bcn_rssi_avg;
+ if (signal->selector & BCN_NF_AVG_MASK)
+ priv->w_stats.qual.noise = signal->bcn_nf_avg;
+ }
+
+ return status;
+}
+
+/*
+ * Sends IOCTL request to set encoding parameters.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
+ int key_len, u8 key_index, int disable)
+{
+ struct mwifiex_ds_encrypt_key encrypt_key;
+
+ memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key));
+ encrypt_key.key_len = key_len;
+ if (!disable) {
+ encrypt_key.key_index = key_index;
+ if (key_len)
+ memcpy(encrypt_key.key_material, key, key_len);
+ } else {
+ encrypt_key.key_disable = true;
+ }
+
+ return mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key);
+}
+
+/*
+ * Sends IOCTL request to get extended version.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int
+mwifiex_get_ver_ext(struct mwifiex_private *priv)
+{
+ struct mwifiex_ver_ext ver_ext;
+
+ memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext));
+ if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT,
+ HostCmd_ACT_GEN_GET, 0, &ver_ext))
+ return -1;
+
+ return 0;
+}
+
+/*
+ * Sends IOCTL request to get statistics information.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int
+mwifiex_get_stats_info(struct mwifiex_private *priv,
+ struct mwifiex_ds_get_stats *log)
+{
+ int ret;
+
+ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG,
+ HostCmd_ACT_GEN_GET, 0, log);
+
+ if (!ret) {
+ priv->w_stats.discard.fragment = log->fcs_error;
+ priv->w_stats.discard.retries = log->retry;
+ priv->w_stats.discard.misc = log->ack_failure;
+ }
+
+ return ret;
+}
+
+/*
+ * IOCTL request handler to read/write register.
+ *
+ * This function prepares the correct firmware command and
+ * issues it.
+ *
+ * Access to the following registers are supported -
+ * - MAC
+ * - BBP
+ * - RF
+ * - PMIC
+ * - CAU
+ */
+static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv,
+ struct mwifiex_ds_reg_rw *reg_rw,
+ u16 action)
+{
+ u16 cmd_no;
+
+ switch (le32_to_cpu(reg_rw->type)) {
+ case MWIFIEX_REG_MAC:
+ cmd_no = HostCmd_CMD_MAC_REG_ACCESS;
+ break;
+ case MWIFIEX_REG_BBP:
+ cmd_no = HostCmd_CMD_BBP_REG_ACCESS;
+ break;
+ case MWIFIEX_REG_RF:
+ cmd_no = HostCmd_CMD_RF_REG_ACCESS;
+ break;
+ case MWIFIEX_REG_PMIC:
+ cmd_no = HostCmd_CMD_PMIC_REG_ACCESS;
+ break;
+ case MWIFIEX_REG_CAU:
+ cmd_no = HostCmd_CMD_CAU_REG_ACCESS;
+ break;
+ default:
+ return -1;
+ }
+
+ return mwifiex_send_cmd_sync(priv, cmd_no, action, 0, reg_rw);
+
+}
+
+/*
+ * Sends IOCTL request to write to a register.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int
+mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type,
+ u32 reg_offset, u32 reg_value)
+{
+ struct mwifiex_ds_reg_rw reg_rw;
+
+ reg_rw.type = cpu_to_le32(reg_type);
+ reg_rw.offset = cpu_to_le32(reg_offset);
+ reg_rw.value = cpu_to_le32(reg_value);
+
+ return mwifiex_reg_mem_ioctl_reg_rw(priv, &reg_rw, HostCmd_ACT_GEN_SET);
+}
+
+/*
+ * Sends IOCTL request to read from a register.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int
+mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type,
+ u32 reg_offset, u32 *value)
+{
+ int ret;
+ struct mwifiex_ds_reg_rw reg_rw;
+
+ reg_rw.type = cpu_to_le32(reg_type);
+ reg_rw.offset = cpu_to_le32(reg_offset);
+ ret = mwifiex_reg_mem_ioctl_reg_rw(priv, &reg_rw, HostCmd_ACT_GEN_GET);
+
+ if (ret)
+ goto done;
+
+ *value = le32_to_cpu(reg_rw.value);
+
+done:
+ return ret;
+}
+
+/*
+ * Sends IOCTL request to read from EEPROM.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int
+mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes,
+ u8 *value)
+{
+ int ret;
+ struct mwifiex_ds_read_eeprom rd_eeprom;
+
+ rd_eeprom.offset = cpu_to_le16((u16) offset);
+ rd_eeprom.byte_count = cpu_to_le16((u16) bytes);
+
+ /* Send request to firmware */
+ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_EEPROM_ACCESS,
+ HostCmd_ACT_GEN_GET, 0, &rd_eeprom);
+
+ if (!ret)
+ memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA);
+ return ret;
+}
+
+/*
+ * This function sets a generic IE. In addition to generic IE, it can
+ * also handle WPA, WPA2 and WAPI IEs.
+ */
+static int
+mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
+ u16 ie_len)
+{
+ int ret = 0;
+ struct ieee_types_vendor_header *pvendor_ie;
+ const u8 wpa_oui[] = { 0x00, 0x50, 0xf2, 0x01 };
+ const u8 wps_oui[] = { 0x00, 0x50, 0xf2, 0x04 };
+
+ /* If the passed length is zero, reset the buffer */
+ if (!ie_len) {
+ priv->gen_ie_buf_len = 0;
+ priv->wps.session_enable = false;
+
+ return 0;
+ } else if (!ie_data_ptr) {
+ return -1;
+ }
+ pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr;
+ /* Test to see if it is a WPA IE, if not, then it is a gen IE */
+ if (((pvendor_ie->element_id == WLAN_EID_WPA)
+ && (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui))))
+ || (pvendor_ie->element_id == WLAN_EID_RSN)) {
+
+ /* IE is a WPA/WPA2 IE so call set_wpa function */
+ ret = mwifiex_set_wpa_ie_helper(priv, ie_data_ptr, ie_len);
+ priv->wps.session_enable = false;
+
+ return ret;
+ } else if (pvendor_ie->element_id == WLAN_EID_BSS_AC_ACCESS_DELAY) {
+ /* IE is a WAPI IE so call set_wapi function */
+ ret = mwifiex_set_wapi_ie(priv, ie_data_ptr, ie_len);
+
+ return ret;
+ }
+ /*
+ * Verify that the passed length is not larger than the
+ * available space remaining in the buffer
+ */
+ if (ie_len < (sizeof(priv->gen_ie_buf) - priv->gen_ie_buf_len)) {
+
+ /* Test to see if it is a WPS IE, if so, enable
+ * wps session flag
+ */
+ pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr;
+ if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC)
+ && (!memcmp(pvendor_ie->oui, wps_oui,
+ sizeof(wps_oui)))) {
+ priv->wps.session_enable = true;
+ dev_dbg(priv->adapter->dev,
+ "info: WPS Session Enabled.\n");
+ }
+
+ /* Append the passed data to the end of the
+ genIeBuffer */
+ memcpy(priv->gen_ie_buf + priv->gen_ie_buf_len, ie_data_ptr,
+ ie_len);
+ /* Increment the stored buffer length by the
+ size passed */
+ priv->gen_ie_buf_len += ie_len;
+ } else {
+ /* Passed data does not fit in the remaining
+ buffer space */
+ ret = -1;
+ }
+
+ /* Return 0, or -1 for error case */
+ return ret;
+}
+
+/*
+ * IOCTL request handler to set/get generic IE.
+ *
+ * In addition to various generic IEs, this function can also be
+ * used to set the ARP filter.
+ */
+static int mwifiex_misc_ioctl_gen_ie(struct mwifiex_private *priv,
+ struct mwifiex_ds_misc_gen_ie *gen_ie,
+ u16 action)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+
+ switch (gen_ie->type) {
+ case MWIFIEX_IE_TYPE_GEN_IE:
+ if (action == HostCmd_ACT_GEN_GET) {
+ gen_ie->len = priv->wpa_ie_len;
+ memcpy(gen_ie->ie_data, priv->wpa_ie, gen_ie->len);
+ } else {
+ mwifiex_set_gen_ie_helper(priv, gen_ie->ie_data,
+ (u16) gen_ie->len);
+ }
+ break;
+ case MWIFIEX_IE_TYPE_ARP_FILTER:
+ memset(adapter->arp_filter, 0, sizeof(adapter->arp_filter));
+ if (gen_ie->len > ARP_FILTER_MAX_BUF_SIZE) {
+ adapter->arp_filter_size = 0;
+ dev_err(adapter->dev, "invalid ARP filter size\n");
+ return -1;
+ } else {
+ memcpy(adapter->arp_filter, gen_ie->ie_data,
+ gen_ie->len);
+ adapter->arp_filter_size = gen_ie->len;
+ }
+ break;
+ default:
+ dev_err(adapter->dev, "invalid IE type\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Sends IOCTL request to set a generic IE.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int
+mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len)
+{
+ struct mwifiex_ds_misc_gen_ie gen_ie;
+
+ if (ie_len > IW_CUSTOM_MAX)
+ return -EFAULT;
+
+ gen_ie.type = MWIFIEX_IE_TYPE_GEN_IE;
+ gen_ie.len = ie_len;
+ memcpy(gen_ie.ie_data, ie, ie_len);
+ if (mwifiex_misc_ioctl_gen_ie(priv, &gen_ie, HostCmd_ACT_GEN_SET))
+ return -EFAULT;
+
+ return 0;
+}
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c
new file mode 100644
index 00000000000..1fdddece747
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sta_rx.c
@@ -0,0 +1,200 @@
+/*
+ * Marvell Wireless LAN device driver: station RX data handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "11n_aggr.h"
+#include "11n_rxreorder.h"
+
+/*
+ * This function processes the received packet and forwards it
+ * to kernel/upper layer.
+ *
+ * This function parses through the received packet and determines
+ * if it is a debug packet or normal packet.
+ *
+ * For non-debug packets, the function chops off unnecessary leading
+ * header bytes, reconstructs the packet as an ethernet frame or
+ * 802.2/llc/snap frame as required, and sends it to kernel/upper layer.
+ *
+ * The completion callback is called after processing in complete.
+ */
+int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter,
+ struct sk_buff *skb)
+{
+ int ret;
+ struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
+ struct mwifiex_private *priv = adapter->priv[rx_info->bss_index];
+ struct rx_packet_hdr *rx_pkt_hdr;
+ struct rxpd *local_rx_pd;
+ int hdr_chop;
+ struct ethhdr *eth_hdr;
+ u8 rfc1042_eth_hdr[ETH_ALEN] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+
+ local_rx_pd = (struct rxpd *) (skb->data);
+
+ rx_pkt_hdr = (struct rx_packet_hdr *) ((u8 *) local_rx_pd +
+ local_rx_pd->rx_pkt_offset);
+
+ if (!memcmp(&rx_pkt_hdr->rfc1042_hdr,
+ rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr))) {
+ /*
+ * Replace the 803 header and rfc1042 header (llc/snap) with an
+ * EthernetII header, keep the src/dst and snap_type
+ * (ethertype).
+ * The firmware only passes up SNAP frames converting
+ * all RX Data from 802.11 to 802.2/LLC/SNAP frames.
+ * To create the Ethernet II, just move the src, dst address
+ * right before the snap_type.
+ */
+ eth_hdr = (struct ethhdr *)
+ ((u8 *) &rx_pkt_hdr->eth803_hdr
+ + sizeof(rx_pkt_hdr->eth803_hdr) +
+ sizeof(rx_pkt_hdr->rfc1042_hdr)
+ - sizeof(rx_pkt_hdr->eth803_hdr.h_dest)
+ - sizeof(rx_pkt_hdr->eth803_hdr.h_source)
+ - sizeof(rx_pkt_hdr->rfc1042_hdr.snap_type));
+
+ memcpy(eth_hdr->h_source, rx_pkt_hdr->eth803_hdr.h_source,
+ sizeof(eth_hdr->h_source));
+ memcpy(eth_hdr->h_dest, rx_pkt_hdr->eth803_hdr.h_dest,
+ sizeof(eth_hdr->h_dest));
+
+ /* Chop off the rxpd + the excess memory from the 802.2/llc/snap
+ header that was removed. */
+ hdr_chop = (u8 *) eth_hdr - (u8 *) local_rx_pd;
+ } else {
+ /* Chop off the rxpd */
+ hdr_chop = (u8 *) &rx_pkt_hdr->eth803_hdr -
+ (u8 *) local_rx_pd;
+ }
+
+ /* Chop off the leading header bytes so the it points to the start of
+ either the reconstructed EthII frame or the 802.2/llc/snap frame */
+ skb_pull(skb, hdr_chop);
+
+ priv->rxpd_rate = local_rx_pd->rx_rate;
+
+ priv->rxpd_htinfo = local_rx_pd->ht_info;
+
+ ret = mwifiex_recv_packet(adapter, skb);
+ if (ret == -1)
+ dev_err(adapter->dev, "recv packet failed\n");
+
+ return ret;
+}
+
+/*
+ * This function processes the received buffer.
+ *
+ * The function looks into the RxPD and performs sanity tests on the
+ * received buffer to ensure its a valid packet, before processing it
+ * further. If the packet is determined to be aggregated, it is
+ * de-aggregated accordingly. Non-unicast packets are sent directly to
+ * the kernel/upper layers. Unicast packets are handed over to the
+ * Rx reordering routine if 11n is enabled.
+ *
+ * The completion callback is called after processing in complete.
+ */
+int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
+ struct sk_buff *skb)
+{
+ int ret = 0;
+ struct rxpd *local_rx_pd;
+ struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
+ struct rx_packet_hdr *rx_pkt_hdr;
+ u8 ta[ETH_ALEN];
+ u16 rx_pkt_type;
+ struct mwifiex_private *priv = adapter->priv[rx_info->bss_index];
+
+ local_rx_pd = (struct rxpd *) (skb->data);
+ rx_pkt_type = local_rx_pd->rx_pkt_type;
+
+ rx_pkt_hdr = (struct rx_packet_hdr *) ((u8 *) local_rx_pd +
+ local_rx_pd->rx_pkt_offset);
+
+ if ((local_rx_pd->rx_pkt_offset + local_rx_pd->rx_pkt_length) >
+ (u16) skb->len) {
+ dev_err(adapter->dev, "wrong rx packet: len=%d,"
+ " rx_pkt_offset=%d, rx_pkt_length=%d\n", skb->len,
+ local_rx_pd->rx_pkt_offset, local_rx_pd->rx_pkt_length);
+ priv->stats.rx_dropped++;
+ dev_kfree_skb_any(skb);
+ return ret;
+ }
+
+ if (local_rx_pd->rx_pkt_type == PKT_TYPE_AMSDU) {
+ struct sk_buff_head list;
+ struct sk_buff *rx_skb;
+
+ __skb_queue_head_init(&list);
+
+ skb_pull(skb, local_rx_pd->rx_pkt_offset);
+ skb_trim(skb, local_rx_pd->rx_pkt_length);
+
+ ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
+ priv->wdev->iftype, 0, false);
+
+ while (!skb_queue_empty(&list)) {
+ rx_skb = __skb_dequeue(&list);
+ ret = mwifiex_recv_packet(adapter, rx_skb);
+ if (ret == -1)
+ dev_err(adapter->dev, "Rx of A-MSDU failed");
+ }
+ return 0;
+ }
+
+ /*
+ * If the packet is not an unicast packet then send the packet
+ * directly to os. Don't pass thru rx reordering
+ */
+ if (!IS_11N_ENABLED(priv) ||
+ memcmp(priv->curr_addr, rx_pkt_hdr->eth803_hdr.h_dest, ETH_ALEN)) {
+ mwifiex_process_rx_packet(adapter, skb);
+ return ret;
+ }
+
+ if (mwifiex_queuing_ra_based(priv)) {
+ memcpy(ta, rx_pkt_hdr->eth803_hdr.h_source, ETH_ALEN);
+ } else {
+ if (rx_pkt_type != PKT_TYPE_BAR)
+ priv->rx_seq[local_rx_pd->priority] =
+ local_rx_pd->seq_num;
+ memcpy(ta, priv->curr_bss_params.bss_descriptor.mac_address,
+ ETH_ALEN);
+ }
+
+ /* Reorder and send to OS */
+ ret = mwifiex_11n_rx_reorder_pkt(priv, local_rx_pd->seq_num,
+ local_rx_pd->priority, ta,
+ (u8) local_rx_pd->rx_pkt_type,
+ (void *) skb);
+
+ if (ret || (rx_pkt_type == PKT_TYPE_BAR)) {
+ if (priv && (ret == -1))
+ priv->stats.rx_dropped++;
+
+ dev_kfree_skb_any(skb);
+ }
+
+ return ret;
+}
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
new file mode 100644
index 00000000000..fa6221bc910
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -0,0 +1,198 @@
+/*
+ * Marvell Wireless LAN device driver: station TX data handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+
+/*
+ * This function fills the TxPD for tx packets.
+ *
+ * The Tx buffer received by this function should already have the
+ * header space allocated for TxPD.
+ *
+ * This function inserts the TxPD in between interface header and actual
+ * data and adjusts the buffer pointers accordingly.
+ *
+ * The following TxPD fields are set by this function, as required -
+ * - BSS number
+ * - Tx packet length and offset
+ * - Priority
+ * - Packet delay
+ * - Priority specific Tx control
+ * - Flags
+ */
+void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
+ struct sk_buff *skb)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct txpd *local_tx_pd;
+ struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
+
+ if (!skb->len) {
+ dev_err(adapter->dev, "Tx: bad packet length: %d\n",
+ skb->len);
+ tx_info->status_code = -1;
+ return skb->data;
+ }
+
+ BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN));
+ skb_push(skb, sizeof(*local_tx_pd));
+
+ local_tx_pd = (struct txpd *) skb->data;
+ memset(local_tx_pd, 0, sizeof(struct txpd));
+ local_tx_pd->bss_num = priv->bss_num;
+ local_tx_pd->bss_type = priv->bss_type;
+ local_tx_pd->tx_pkt_length = cpu_to_le16((u16) (skb->len -
+ sizeof(struct txpd)));
+
+ local_tx_pd->priority = (u8) skb->priority;
+ local_tx_pd->pkt_delay_2ms =
+ mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
+
+ if (local_tx_pd->priority <
+ ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl))
+ /*
+ * Set the priority specific tx_control field, setting of 0 will
+ * cause the default value to be used later in this function
+ */
+ local_tx_pd->tx_control =
+ cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[local_tx_pd->
+ priority]);
+
+ if (adapter->pps_uapsd_mode) {
+ if (mwifiex_check_last_packet_indication(priv)) {
+ adapter->tx_lock_flag = true;
+ local_tx_pd->flags =
+ MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET;
+ }
+ }
+
+ /* Offset of actual data */
+ local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
+
+ /* make space for INTF_HEADER_LEN */
+ skb_push(skb, INTF_HEADER_LEN);
+
+ if (!local_tx_pd->tx_control)
+ /* TxCtrl set by user or default */
+ local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl);
+
+ return skb->data;
+}
+
+/*
+ * This function tells firmware to send a NULL data packet.
+ *
+ * The function creates a NULL data packet with TxPD and sends to the
+ * firmware for transmission, with highest priority setting.
+ */
+int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct txpd *local_tx_pd;
+/* sizeof(struct txpd) + Interface specific header */
+#define NULL_PACKET_HDR 64
+ u32 data_len = NULL_PACKET_HDR;
+ struct sk_buff *skb;
+ int ret;
+ struct mwifiex_txinfo *tx_info = NULL;
+
+ if (adapter->surprise_removed)
+ return -1;
+
+ if (!priv->media_connected)
+ return -1;
+
+ if (adapter->data_sent)
+ return -1;
+
+ skb = dev_alloc_skb(data_len);
+ if (!skb)
+ return -1;
+
+ tx_info = MWIFIEX_SKB_TXCB(skb);
+ tx_info->bss_index = priv->bss_index;
+ skb_reserve(skb, sizeof(struct txpd) + INTF_HEADER_LEN);
+ skb_push(skb, sizeof(struct txpd));
+
+ local_tx_pd = (struct txpd *) skb->data;
+ local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl);
+ local_tx_pd->flags = flags;
+ local_tx_pd->priority = WMM_HIGHEST_PRIORITY;
+ local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
+ local_tx_pd->bss_num = priv->bss_num;
+ local_tx_pd->bss_type = priv->bss_type;
+
+ skb_push(skb, INTF_HEADER_LEN);
+
+ ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
+ skb->data, skb->len, NULL);
+ switch (ret) {
+ case -EBUSY:
+ adapter->data_sent = true;
+ /* Fall through FAILURE handling */
+ case -1:
+ dev_kfree_skb_any(skb);
+ dev_err(adapter->dev, "%s: host_to_card failed: ret=%d\n",
+ __func__, ret);
+ adapter->dbg.num_tx_host_to_card_failure++;
+ break;
+ case 0:
+ dev_kfree_skb_any(skb);
+ dev_dbg(adapter->dev, "data: %s: host_to_card succeeded\n",
+ __func__);
+ adapter->tx_lock_flag = true;
+ break;
+ case -EINPROGRESS:
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+/*
+ * This function checks if we need to send last packet indication.
+ */
+u8
+mwifiex_check_last_packet_indication(struct mwifiex_private *priv)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ u8 ret = false;
+
+ if (!adapter->sleep_period.period)
+ return ret;
+ if (mwifiex_wmm_lists_empty(adapter))
+ ret = true;
+
+ if (ret && !adapter->cmd_sent && !adapter->curr_cmd
+ && !is_command_pending(adapter)) {
+ adapter->delay_null_pkt = false;
+ ret = true;
+ } else {
+ ret = false;
+ adapter->delay_null_pkt = true;
+ }
+ return ret;
+}
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
new file mode 100644
index 00000000000..210120889df
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -0,0 +1,200 @@
+/*
+ * Marvell Wireless LAN device driver: generic TX/RX data handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+
+/*
+ * This function processes the received buffer.
+ *
+ * Main responsibility of this function is to parse the RxPD to
+ * identify the correct interface this packet is headed for and
+ * forwarding it to the associated handling function, where the
+ * packet will be further processed and sent to kernel/upper layer
+ * if required.
+ */
+int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
+ struct sk_buff *skb)
+{
+ struct mwifiex_private *priv =
+ mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+ struct rxpd *local_rx_pd;
+ struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
+
+ local_rx_pd = (struct rxpd *) (skb->data);
+ /* Get the BSS number from rxpd, get corresponding priv */
+ priv = mwifiex_get_priv_by_id(adapter, local_rx_pd->bss_num &
+ BSS_NUM_MASK, local_rx_pd->bss_type);
+ if (!priv)
+ priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+
+ rx_info->bss_index = priv->bss_index;
+
+ return mwifiex_process_sta_rx_packet(adapter, skb);
+}
+EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet);
+
+/*
+ * This function sends a packet to device.
+ *
+ * It processes the packet to add the TxPD, checks condition and
+ * sends the processed packet to firmware for transmission.
+ *
+ * On successful completion, the function calls the completion callback
+ * and logs the time.
+ */
+int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
+ struct mwifiex_tx_param *tx_param)
+{
+ int ret = -1;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ u8 *head_ptr;
+ struct txpd *local_tx_pd = NULL;
+
+ head_ptr = (u8 *) mwifiex_process_sta_txpd(priv, skb);
+ if (head_ptr) {
+ if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
+ local_tx_pd =
+ (struct txpd *) (head_ptr + INTF_HEADER_LEN);
+
+ ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
+ skb->data, skb->len, tx_param);
+ }
+
+ switch (ret) {
+ case -EBUSY:
+ if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
+ (adapter->pps_uapsd_mode) &&
+ (adapter->tx_lock_flag)) {
+ priv->adapter->tx_lock_flag = false;
+ local_tx_pd->flags = 0;
+ }
+ dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
+ break;
+ case -1:
+ adapter->data_sent = false;
+ dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n",
+ ret);
+ adapter->dbg.num_tx_host_to_card_failure++;
+ mwifiex_write_data_complete(adapter, skb, ret);
+ break;
+ case -EINPROGRESS:
+ adapter->data_sent = false;
+ break;
+ case 0:
+ mwifiex_write_data_complete(adapter, skb, ret);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+/*
+ * Packet send completion callback handler.
+ *
+ * It either frees the buffer directly or forwards it to another
+ * completion callback which checks conditions, updates statistics,
+ * wakes up stalled traffic queue if required, and then frees the buffer.
+ */
+int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
+ struct sk_buff *skb, int status)
+{
+ struct mwifiex_private *priv, *tpriv;
+ struct mwifiex_txinfo *tx_info;
+ int i;
+
+ if (!skb)
+ return 0;
+
+ tx_info = MWIFIEX_SKB_TXCB(skb);
+ priv = mwifiex_bss_index_to_priv(adapter, tx_info->bss_index);
+ if (!priv)
+ goto done;
+
+ priv->netdev->trans_start = jiffies;
+ if (!status) {
+ priv->stats.tx_packets++;
+ priv->stats.tx_bytes += skb->len;
+ } else {
+ priv->stats.tx_errors++;
+ }
+ atomic_dec(&adapter->tx_pending);
+
+ for (i = 0; i < adapter->priv_num; i++) {
+
+ tpriv = adapter->priv[i];
+
+ if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA)
+ && (tpriv->media_connected)) {
+ if (netif_queue_stopped(tpriv->netdev))
+ netif_wake_queue(tpriv->netdev);
+ }
+ }
+done:
+ dev_kfree_skb_any(skb);
+
+ return 0;
+}
+
+/*
+ * Packet receive completion callback handler.
+ *
+ * This function calls another completion callback handler which
+ * updates the statistics, and optionally updates the parent buffer
+ * use count before freeing the received packet.
+ */
+int mwifiex_recv_packet_complete(struct mwifiex_adapter *adapter,
+ struct sk_buff *skb, int status)
+{
+ struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
+ struct mwifiex_rxinfo *rx_info_parent;
+ struct mwifiex_private *priv;
+ struct sk_buff *skb_parent;
+ unsigned long flags;
+
+ priv = adapter->priv[rx_info->bss_index];
+
+ if (priv && (status == -1))
+ priv->stats.rx_dropped++;
+
+ if (rx_info->parent) {
+ skb_parent = rx_info->parent;
+ rx_info_parent = MWIFIEX_SKB_RXCB(skb_parent);
+
+ spin_lock_irqsave(&priv->rx_pkt_lock, flags);
+ --rx_info_parent->use_count;
+
+ if (!rx_info_parent->use_count) {
+ spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
+ dev_kfree_skb_any(skb_parent);
+ } else {
+ spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
+ }
+ } else {
+ dev_kfree_skb_any(skb);
+ }
+
+ return 0;
+}
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
new file mode 100644
index 00000000000..d41291529bc
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -0,0 +1,202 @@
+/*
+ * Marvell Wireless LAN device driver: utility functions
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+/*
+ * Firmware initialization complete callback handler.
+ *
+ * This function wakes up the function waiting on the init
+ * wait queue for the firmware initialization to complete.
+ */
+int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter)
+{
+
+ adapter->init_wait_q_woken = true;
+ wake_up_interruptible(&adapter->init_wait_q);
+ return 0;
+}
+
+/*
+ * Firmware shutdown complete callback handler.
+ *
+ * This function sets the hardware status to not ready and wakes up
+ * the function waiting on the init wait queue for the firmware
+ * shutdown to complete.
+ */
+int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter)
+{
+ adapter->hw_status = MWIFIEX_HW_STATUS_NOT_READY;
+ adapter->init_wait_q_woken = true;
+ wake_up_interruptible(&adapter->init_wait_q);
+ return 0;
+}
+
+/*
+ * This function sends init/shutdown command
+ * to firmware.
+ */
+int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
+ u32 func_init_shutdown)
+{
+ u16 cmd;
+
+ if (func_init_shutdown == MWIFIEX_FUNC_INIT) {
+ cmd = HostCmd_CMD_FUNC_INIT;
+ } else if (func_init_shutdown == MWIFIEX_FUNC_SHUTDOWN) {
+ cmd = HostCmd_CMD_FUNC_SHUTDOWN;
+ } else {
+ dev_err(priv->adapter->dev, "unsupported parameter\n");
+ return -1;
+ }
+
+ return mwifiex_send_cmd_sync(priv, cmd, HostCmd_ACT_GEN_SET, 0, NULL);
+}
+EXPORT_SYMBOL_GPL(mwifiex_init_shutdown_fw);
+
+/*
+ * IOCTL request handler to set/get debug information.
+ *
+ * This function collates/sets the information from/to different driver
+ * structures.
+ */
+int mwifiex_get_debug_info(struct mwifiex_private *priv,
+ struct mwifiex_debug_info *info)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+
+ if (info) {
+ memcpy(info->packets_out,
+ priv->wmm.packets_out,
+ sizeof(priv->wmm.packets_out));
+ info->max_tx_buf_size = (u32) adapter->max_tx_buf_size;
+ info->tx_buf_size = (u32) adapter->tx_buf_size;
+ info->rx_tbl_num = mwifiex_get_rx_reorder_tbl(
+ priv, info->rx_tbl);
+ info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl(
+ priv, info->tx_tbl);
+ info->ps_mode = adapter->ps_mode;
+ info->ps_state = adapter->ps_state;
+ info->is_deep_sleep = adapter->is_deep_sleep;
+ info->pm_wakeup_card_req = adapter->pm_wakeup_card_req;
+ info->pm_wakeup_fw_try = adapter->pm_wakeup_fw_try;
+ info->is_hs_configured = adapter->is_hs_configured;
+ info->hs_activated = adapter->hs_activated;
+ info->num_cmd_host_to_card_failure
+ = adapter->dbg.num_cmd_host_to_card_failure;
+ info->num_cmd_sleep_cfm_host_to_card_failure
+ = adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure;
+ info->num_tx_host_to_card_failure
+ = adapter->dbg.num_tx_host_to_card_failure;
+ info->num_event_deauth = adapter->dbg.num_event_deauth;
+ info->num_event_disassoc = adapter->dbg.num_event_disassoc;
+ info->num_event_link_lost = adapter->dbg.num_event_link_lost;
+ info->num_cmd_deauth = adapter->dbg.num_cmd_deauth;
+ info->num_cmd_assoc_success =
+ adapter->dbg.num_cmd_assoc_success;
+ info->num_cmd_assoc_failure =
+ adapter->dbg.num_cmd_assoc_failure;
+ info->num_tx_timeout = adapter->dbg.num_tx_timeout;
+ info->num_cmd_timeout = adapter->dbg.num_cmd_timeout;
+ info->timeout_cmd_id = adapter->dbg.timeout_cmd_id;
+ info->timeout_cmd_act = adapter->dbg.timeout_cmd_act;
+ memcpy(info->last_cmd_id, adapter->dbg.last_cmd_id,
+ sizeof(adapter->dbg.last_cmd_id));
+ memcpy(info->last_cmd_act, adapter->dbg.last_cmd_act,
+ sizeof(adapter->dbg.last_cmd_act));
+ info->last_cmd_index = adapter->dbg.last_cmd_index;
+ memcpy(info->last_cmd_resp_id, adapter->dbg.last_cmd_resp_id,
+ sizeof(adapter->dbg.last_cmd_resp_id));
+ info->last_cmd_resp_index = adapter->dbg.last_cmd_resp_index;
+ memcpy(info->last_event, adapter->dbg.last_event,
+ sizeof(adapter->dbg.last_event));
+ info->last_event_index = adapter->dbg.last_event_index;
+ info->data_sent = adapter->data_sent;
+ info->cmd_sent = adapter->cmd_sent;
+ info->cmd_resp_received = adapter->cmd_resp_received;
+ }
+
+ return 0;
+}
+
+/*
+ * This function processes the received packet before sending it to the
+ * kernel.
+ *
+ * It extracts the SKB from the received buffer and sends it to kernel.
+ * In case the received buffer does not contain the data in SKB format,
+ * the function creates a blank SKB, fills it with the data from the
+ * received buffer and then sends this new SKB to the kernel.
+ */
+int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb)
+{
+ struct mwifiex_rxinfo *rx_info;
+ struct mwifiex_private *priv;
+
+ if (!skb)
+ return -1;
+
+ rx_info = MWIFIEX_SKB_RXCB(skb);
+ priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index);
+ if (!priv)
+ return -1;
+
+ skb->dev = priv->netdev;
+ skb->protocol = eth_type_trans(skb, priv->netdev);
+ skb->ip_summed = CHECKSUM_NONE;
+ priv->stats.rx_bytes += skb->len;
+ priv->stats.rx_packets++;
+ if (in_interrupt())
+ netif_rx(skb);
+ else
+ netif_rx_ni(skb);
+
+ return 0;
+}
+
+/*
+ * IOCTL completion callback handler.
+ *
+ * This function is called when a pending IOCTL is completed.
+ *
+ * If work queue support is enabled, the function wakes up the
+ * corresponding waiting function. Otherwise, it processes the
+ * IOCTL response and frees the response buffer.
+ */
+int mwifiex_complete_cmd(struct mwifiex_adapter *adapter)
+{
+ atomic_dec(&adapter->cmd_pending);
+ dev_dbg(adapter->dev, "cmd completed: status=%d\n",
+ adapter->cmd_wait_q.status);
+
+ adapter->cmd_wait_q.condition = true;
+
+ if (adapter->cmd_wait_q.status == -ETIMEDOUT)
+ dev_err(adapter->dev, "cmd timeout\n");
+ else
+ wake_up_interruptible(&adapter->cmd_wait_q.wait);
+
+ return 0;
+}
diff --git a/drivers/net/wireless/mwifiex/util.h b/drivers/net/wireless/mwifiex/util.h
new file mode 100644
index 00000000000..9506afc6c0e
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/util.h
@@ -0,0 +1,32 @@
+/*
+ * Marvell Wireless LAN device driver: utility functions
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_UTIL_H_
+#define _MWIFIEX_UTIL_H_
+
+static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb)
+{
+ return (struct mwifiex_rxinfo *)skb->cb;
+}
+
+static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb)
+{
+ return (struct mwifiex_txinfo *)skb->cb;
+}
+#endif /* !_MWIFIEX_UTIL_H_ */
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
new file mode 100644
index 00000000000..faa09e32902
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -0,0 +1,1231 @@
+/*
+ * Marvell Wireless LAN device driver: WMM
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+
+/* Maximum value FW can accept for driver delay in packet transmission */
+#define DRV_PKT_DELAY_TO_FW_MAX 512
+
+
+#define WMM_QUEUED_PACKET_LOWER_LIMIT 180
+
+#define WMM_QUEUED_PACKET_UPPER_LIMIT 200
+
+/* Offset for TOS field in the IP header */
+#define IPTOS_OFFSET 5
+
+/* WMM information IE */
+static const u8 wmm_info_ie[] = { WLAN_EID_VENDOR_SPECIFIC, 0x07,
+ 0x00, 0x50, 0xf2, 0x02,
+ 0x00, 0x01, 0x00
+};
+
+static const u8 wmm_aci_to_qidx_map[] = { WMM_AC_BE,
+ WMM_AC_BK,
+ WMM_AC_VI,
+ WMM_AC_VO
+};
+
+static u8 tos_to_tid[] = {
+ /* TID DSCP_P2 DSCP_P1 DSCP_P0 WMM_AC */
+ 0x01, /* 0 1 0 AC_BK */
+ 0x02, /* 0 0 0 AC_BK */
+ 0x00, /* 0 0 1 AC_BE */
+ 0x03, /* 0 1 1 AC_BE */
+ 0x04, /* 1 0 0 AC_VI */
+ 0x05, /* 1 0 1 AC_VI */
+ 0x06, /* 1 1 0 AC_VO */
+ 0x07 /* 1 1 1 AC_VO */
+};
+
+/*
+ * This table inverses the tos_to_tid operation to get a priority
+ * which is in sequential order, and can be compared.
+ * Use this to compare the priority of two different TIDs.
+ */
+static u8 tos_to_tid_inv[] = {
+ 0x02, /* from tos_to_tid[2] = 0 */
+ 0x00, /* from tos_to_tid[0] = 1 */
+ 0x01, /* from tos_to_tid[1] = 2 */
+ 0x03,
+ 0x04,
+ 0x05,
+ 0x06,
+ 0x07};
+
+static u8 ac_to_tid[4][2] = { {1, 2}, {0, 3}, {4, 5}, {6, 7} };
+
+/*
+ * This function debug prints the priority parameters for a WMM AC.
+ */
+static void
+mwifiex_wmm_ac_debug_print(const struct ieee_types_wmm_ac_parameters *ac_param)
+{
+ const char *ac_str[] = { "BK", "BE", "VI", "VO" };
+
+ pr_debug("info: WMM AC_%s: ACI=%d, ACM=%d, Aifsn=%d, "
+ "EcwMin=%d, EcwMax=%d, TxopLimit=%d\n",
+ ac_str[wmm_aci_to_qidx_map[(ac_param->aci_aifsn_bitmap
+ & MWIFIEX_ACI) >> 5]],
+ (ac_param->aci_aifsn_bitmap & MWIFIEX_ACI) >> 5,
+ (ac_param->aci_aifsn_bitmap & MWIFIEX_ACM) >> 4,
+ ac_param->aci_aifsn_bitmap & MWIFIEX_AIFSN,
+ ac_param->ecw_bitmap & MWIFIEX_ECW_MIN,
+ (ac_param->ecw_bitmap & MWIFIEX_ECW_MAX) >> 4,
+ le16_to_cpu(ac_param->tx_op_limit));
+}
+
+/*
+ * This function allocates a route address list.
+ *
+ * The function also initializes the list with the provided RA.
+ */
+static struct mwifiex_ra_list_tbl *
+mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra)
+{
+ struct mwifiex_ra_list_tbl *ra_list;
+
+ ra_list = kzalloc(sizeof(struct mwifiex_ra_list_tbl), GFP_ATOMIC);
+
+ if (!ra_list) {
+ dev_err(adapter->dev, "%s: failed to alloc ra_list\n",
+ __func__);
+ return NULL;
+ }
+ INIT_LIST_HEAD(&ra_list->list);
+ skb_queue_head_init(&ra_list->skb_head);
+
+ memcpy(ra_list->ra, ra, ETH_ALEN);
+
+ ra_list->total_pkts_size = 0;
+
+ dev_dbg(adapter->dev, "info: allocated ra_list %p\n", ra_list);
+
+ return ra_list;
+}
+
+/*
+ * This function allocates and adds a RA list for all TIDs
+ * with the given RA.
+ */
+void
+mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra)
+{
+ int i;
+ struct mwifiex_ra_list_tbl *ra_list;
+ struct mwifiex_adapter *adapter = priv->adapter;
+
+ for (i = 0; i < MAX_NUM_TID; ++i) {
+ ra_list = mwifiex_wmm_allocate_ralist_node(adapter, ra);
+ dev_dbg(adapter->dev, "info: created ra_list %p\n", ra_list);
+
+ if (!ra_list)
+ break;
+
+ if (!mwifiex_queuing_ra_based(priv))
+ ra_list->is_11n_enabled = IS_11N_ENABLED(priv);
+ else
+ ra_list->is_11n_enabled = false;
+
+ dev_dbg(adapter->dev, "data: ralist %p: is_11n_enabled=%d\n",
+ ra_list, ra_list->is_11n_enabled);
+
+ list_add_tail(&ra_list->list,
+ &priv->wmm.tid_tbl_ptr[i].ra_list);
+
+ if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr)
+ priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list;
+ }
+}
+
+/*
+ * This function sets the WMM queue priorities to their default values.
+ */
+static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv)
+{
+ /* Default queue priorities: VO->VI->BE->BK */
+ priv->wmm.queue_priority[0] = WMM_AC_VO;
+ priv->wmm.queue_priority[1] = WMM_AC_VI;
+ priv->wmm.queue_priority[2] = WMM_AC_BE;
+ priv->wmm.queue_priority[3] = WMM_AC_BK;
+}
+
+/*
+ * This function map ACs to TIDs.
+ */
+static void
+mwifiex_wmm_queue_priorities_tid(u8 queue_priority[])
+{
+ int i;
+
+ for (i = 0; i < 4; ++i) {
+ tos_to_tid[7 - (i * 2)] = ac_to_tid[queue_priority[i]][1];
+ tos_to_tid[6 - (i * 2)] = ac_to_tid[queue_priority[i]][0];
+ }
+}
+
+/*
+ * This function initializes WMM priority queues.
+ */
+void
+mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv,
+ struct ieee_types_wmm_parameter *wmm_ie)
+{
+ u16 cw_min, avg_back_off, tmp[4];
+ u32 i, j, num_ac;
+ u8 ac_idx;
+
+ if (!wmm_ie || !priv->wmm_enabled) {
+ /* WMM is not enabled, just set the defaults and return */
+ mwifiex_wmm_default_queue_priorities(priv);
+ return;
+ }
+
+ dev_dbg(priv->adapter->dev, "info: WMM Parameter IE: version=%d, "
+ "qos_info Parameter Set Count=%d, Reserved=%#x\n",
+ wmm_ie->vend_hdr.version, wmm_ie->qos_info_bitmap &
+ IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK,
+ wmm_ie->reserved);
+
+ for (num_ac = 0; num_ac < ARRAY_SIZE(wmm_ie->ac_params); num_ac++) {
+ cw_min = (1 << (wmm_ie->ac_params[num_ac].ecw_bitmap &
+ MWIFIEX_ECW_MIN)) - 1;
+ avg_back_off = (cw_min >> 1) +
+ (wmm_ie->ac_params[num_ac].aci_aifsn_bitmap &
+ MWIFIEX_AIFSN);
+
+ ac_idx = wmm_aci_to_qidx_map[(wmm_ie->ac_params[num_ac].
+ aci_aifsn_bitmap &
+ MWIFIEX_ACI) >> 5];
+ priv->wmm.queue_priority[ac_idx] = ac_idx;
+ tmp[ac_idx] = avg_back_off;
+
+ dev_dbg(priv->adapter->dev, "info: WMM: CWmax=%d CWmin=%d Avg Back-off=%d\n",
+ (1 << ((wmm_ie->ac_params[num_ac].ecw_bitmap &
+ MWIFIEX_ECW_MAX) >> 4)) - 1,
+ cw_min, avg_back_off);
+ mwifiex_wmm_ac_debug_print(&wmm_ie->ac_params[num_ac]);
+ }
+
+ /* Bubble sort */
+ for (i = 0; i < num_ac; i++) {
+ for (j = 1; j < num_ac - i; j++) {
+ if (tmp[j - 1] > tmp[j]) {
+ swap(tmp[j - 1], tmp[j]);
+ swap(priv->wmm.queue_priority[j - 1],
+ priv->wmm.queue_priority[j]);
+ } else if (tmp[j - 1] == tmp[j]) {
+ if (priv->wmm.queue_priority[j - 1]
+ < priv->wmm.queue_priority[j])
+ swap(priv->wmm.queue_priority[j - 1],
+ priv->wmm.queue_priority[j]);
+ }
+ }
+ }
+
+ mwifiex_wmm_queue_priorities_tid(priv->wmm.queue_priority);
+}
+
+/*
+ * This function evaluates whether or not an AC is to be downgraded.
+ *
+ * In case the AC is not enabled, the highest AC is returned that is
+ * enabled and does not require admission control.
+ */
+static enum mwifiex_wmm_ac_e
+mwifiex_wmm_eval_downgrade_ac(struct mwifiex_private *priv,
+ enum mwifiex_wmm_ac_e eval_ac)
+{
+ int down_ac;
+ enum mwifiex_wmm_ac_e ret_ac;
+ struct mwifiex_wmm_ac_status *ac_status;
+
+ ac_status = &priv->wmm.ac_status[eval_ac];
+
+ if (!ac_status->disabled)
+ /* Okay to use this AC, its enabled */
+ return eval_ac;
+
+ /* Setup a default return value of the lowest priority */
+ ret_ac = WMM_AC_BK;
+
+ /*
+ * Find the highest AC that is enabled and does not require
+ * admission control. The spec disallows downgrading to an AC,
+ * which is enabled due to a completed admission control.
+ * Unadmitted traffic is not to be sent on an AC with admitted
+ * traffic.
+ */
+ for (down_ac = WMM_AC_BK; down_ac < eval_ac; down_ac++) {
+ ac_status = &priv->wmm.ac_status[down_ac];
+
+ if (!ac_status->disabled && !ac_status->flow_required)
+ /* AC is enabled and does not require admission
+ control */
+ ret_ac = (enum mwifiex_wmm_ac_e) down_ac;
+ }
+
+ return ret_ac;
+}
+
+/*
+ * This function downgrades WMM priority queue.
+ */
+void
+mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv)
+{
+ int ac_val;
+
+ dev_dbg(priv->adapter->dev, "info: WMM: AC Priorities:"
+ "BK(0), BE(1), VI(2), VO(3)\n");
+
+ if (!priv->wmm_enabled) {
+ /* WMM is not enabled, default priorities */
+ for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++)
+ priv->wmm.ac_down_graded_vals[ac_val] =
+ (enum mwifiex_wmm_ac_e) ac_val;
+ } else {
+ for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) {
+ priv->wmm.ac_down_graded_vals[ac_val]
+ = mwifiex_wmm_eval_downgrade_ac(priv,
+ (enum mwifiex_wmm_ac_e) ac_val);
+ dev_dbg(priv->adapter->dev, "info: WMM: AC PRIO %d maps to %d\n",
+ ac_val, priv->wmm.ac_down_graded_vals[ac_val]);
+ }
+ }
+}
+
+/*
+ * This function converts the IP TOS field to an WMM AC
+ * Queue assignment.
+ */
+static enum mwifiex_wmm_ac_e
+mwifiex_wmm_convert_tos_to_ac(struct mwifiex_adapter *adapter, u32 tos)
+{
+ /* Map of TOS UP values to WMM AC */
+ const enum mwifiex_wmm_ac_e tos_to_ac[] = { WMM_AC_BE,
+ WMM_AC_BK,
+ WMM_AC_BK,
+ WMM_AC_BE,
+ WMM_AC_VI,
+ WMM_AC_VI,
+ WMM_AC_VO,
+ WMM_AC_VO
+ };
+
+ if (tos >= ARRAY_SIZE(tos_to_ac))
+ return WMM_AC_BE;
+
+ return tos_to_ac[tos];
+}
+
+/*
+ * This function evaluates a given TID and downgrades it to a lower
+ * TID if the WMM Parameter IE received from the AP indicates that the
+ * AP is disabled (due to call admission control (ACM bit). Mapping
+ * of TID to AC is taken care of internally.
+ */
+static u8
+mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid)
+{
+ enum mwifiex_wmm_ac_e ac, ac_down;
+ u8 new_tid;
+
+ ac = mwifiex_wmm_convert_tos_to_ac(priv->adapter, tid);
+ ac_down = priv->wmm.ac_down_graded_vals[ac];
+
+ /* Send the index to tid array, picking from the array will be
+ * taken care by dequeuing function
+ */
+ new_tid = ac_to_tid[ac_down][tid % 2];
+
+ return new_tid;
+}
+
+/*
+ * This function initializes the WMM state information and the
+ * WMM data path queues.
+ */
+void
+mwifiex_wmm_init(struct mwifiex_adapter *adapter)
+{
+ int i, j;
+ struct mwifiex_private *priv;
+
+ for (j = 0; j < adapter->priv_num; ++j) {
+ priv = adapter->priv[j];
+ if (!priv)
+ continue;
+
+ for (i = 0; i < MAX_NUM_TID; ++i) {
+ priv->aggr_prio_tbl[i].amsdu = tos_to_tid_inv[i];
+ priv->aggr_prio_tbl[i].ampdu_ap = tos_to_tid_inv[i];
+ priv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i];
+ priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL;
+ }
+
+ priv->aggr_prio_tbl[6].amsdu
+ = priv->aggr_prio_tbl[6].ampdu_ap
+ = priv->aggr_prio_tbl[6].ampdu_user
+ = BA_STREAM_NOT_ALLOWED;
+
+ priv->aggr_prio_tbl[7].amsdu = priv->aggr_prio_tbl[7].ampdu_ap
+ = priv->aggr_prio_tbl[7].ampdu_user
+ = BA_STREAM_NOT_ALLOWED;
+
+ priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT;
+ priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE;
+ priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE;
+ }
+}
+
+/*
+ * This function checks if WMM Tx queue is empty.
+ */
+int
+mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter)
+{
+ int i, j;
+ struct mwifiex_private *priv;
+
+ for (j = 0; j < adapter->priv_num; ++j) {
+ priv = adapter->priv[j];
+ if (priv) {
+ for (i = 0; i < MAX_NUM_TID; i++)
+ if (!mwifiex_wmm_is_ra_list_empty(
+ &priv->wmm.tid_tbl_ptr[i].ra_list))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/*
+ * This function deletes all packets in an RA list node.
+ *
+ * The packet sent completion callback handler are called with
+ * status failure, after they are dequeued to ensure proper
+ * cleanup. The RA list node itself is freed at the end.
+ */
+static void
+mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv,
+ struct mwifiex_ra_list_tbl *ra_list)
+{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct sk_buff *skb, *tmp;
+
+ skb_queue_walk_safe(&ra_list->skb_head, skb, tmp)
+ mwifiex_write_data_complete(adapter, skb, -1);
+}
+
+/*
+ * This function deletes all packets in an RA list.
+ *
+ * Each nodes in the RA list are freed individually first, and then
+ * the RA list itself is freed.
+ */
+static void
+mwifiex_wmm_del_pkts_in_ralist(struct mwifiex_private *priv,
+ struct list_head *ra_list_head)
+{
+ struct mwifiex_ra_list_tbl *ra_list;
+
+ list_for_each_entry(ra_list, ra_list_head, list)
+ mwifiex_wmm_del_pkts_in_ralist_node(priv, ra_list);
+}
+
+/*
+ * This function deletes all packets in all RA lists.
+ */
+static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv)
+{
+ int i;
+
+ for (i = 0; i < MAX_NUM_TID; i++)
+ mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i].
+ ra_list);
+}
+
+/*
+ * This function deletes all route addresses from all RA lists.
+ */
+static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv)
+{
+ struct mwifiex_ra_list_tbl *ra_list, *tmp_node;
+ int i;
+
+ for (i = 0; i < MAX_NUM_TID; ++i) {
+ dev_dbg(priv->adapter->dev,
+ "info: ra_list: freeing buf for tid %d\n", i);
+ list_for_each_entry_safe(ra_list, tmp_node,
+ &priv->wmm.tid_tbl_ptr[i].ra_list, list) {
+ list_del(&ra_list->list);
+ kfree(ra_list);
+ }
+
+ INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[i].ra_list);
+
+ priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL;
+ }
+}
+
+/*
+ * This function cleans up the Tx and Rx queues.
+ *
+ * Cleanup includes -
+ * - All packets in RA lists
+ * - All entries in Rx reorder table
+ * - All entries in Tx BA stream table
+ * - MPA buffer (if required)
+ * - All RA lists
+ */
+void
+mwifiex_clean_txrx(struct mwifiex_private *priv)
+{
+ unsigned long flags;
+
+ mwifiex_11n_cleanup_reorder_tbl(priv);
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
+
+ mwifiex_wmm_cleanup_queues(priv);
+ mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
+
+ if (priv->adapter->if_ops.cleanup_mpa_buf)
+ priv->adapter->if_ops.cleanup_mpa_buf(priv->adapter);
+
+ mwifiex_wmm_delete_all_ralist(priv);
+ memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid));
+
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+}
+
+/*
+ * This function retrieves a particular RA list node, matching with the
+ * given TID and RA address.
+ */
+static struct mwifiex_ra_list_tbl *
+mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid,
+ u8 *ra_addr)
+{
+ struct mwifiex_ra_list_tbl *ra_list;
+
+ list_for_each_entry(ra_list, &priv->wmm.tid_tbl_ptr[tid].ra_list,
+ list) {
+ if (!memcmp(ra_list->ra, ra_addr, ETH_ALEN))
+ return ra_list;
+ }
+
+ return NULL;
+}
+
+/*
+ * This function retrieves an RA list node for a given TID and
+ * RA address pair.
+ *
+ * If no such node is found, a new node is added first and then
+ * retrieved.
+ */
+static struct mwifiex_ra_list_tbl *
+mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, u8 *ra_addr)
+{
+ struct mwifiex_ra_list_tbl *ra_list;
+
+ ra_list = mwifiex_wmm_get_ralist_node(priv, tid, ra_addr);
+ if (ra_list)
+ return ra_list;
+ mwifiex_ralist_add(priv, ra_addr);
+
+ return mwifiex_wmm_get_ralist_node(priv, tid, ra_addr);
+}
+
+/*
+ * This function checks if a particular RA list node exists in a given TID
+ * table index.
+ */
+int
+mwifiex_is_ralist_valid(struct mwifiex_private *priv,
+ struct mwifiex_ra_list_tbl *ra_list, int ptr_index)
+{
+ struct mwifiex_ra_list_tbl *rlist;
+
+ list_for_each_entry(rlist, &priv->wmm.tid_tbl_ptr[ptr_index].ra_list,
+ list) {
+ if (rlist == ra_list)
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * This function adds a packet to WMM queue.
+ *
+ * In disconnected state the packet is immediately dropped and the
+ * packet send completion callback is called with status failure.
+ *
+ * Otherwise, the correct RA list node is located and the packet
+ * is queued at the list tail.
+ */
+void
+mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
+ struct sk_buff *skb)
+{
+ struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
+ struct mwifiex_private *priv = adapter->priv[tx_info->bss_index];
+ u32 tid;
+ struct mwifiex_ra_list_tbl *ra_list;
+ u8 ra[ETH_ALEN], tid_down;
+ unsigned long flags;
+
+ if (!priv->media_connected) {
+ dev_dbg(adapter->dev, "data: drop packet in disconnect\n");
+ mwifiex_write_data_complete(adapter, skb, -1);
+ return;
+ }
+
+ tid = skb->priority;
+
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
+
+ tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
+
+ /* In case of infra as we have already created the list during
+ association we just don't have to call get_queue_raptr, we will
+ have only 1 raptr for a tid in case of infra */
+ if (!mwifiex_queuing_ra_based(priv)) {
+ if (!list_empty(&priv->wmm.tid_tbl_ptr[tid_down].ra_list))
+ ra_list = list_first_entry(
+ &priv->wmm.tid_tbl_ptr[tid_down].ra_list,
+ struct mwifiex_ra_list_tbl, list);
+ else
+ ra_list = NULL;
+ } else {
+ memcpy(ra, skb->data, ETH_ALEN);
+ ra_list = mwifiex_wmm_get_queue_raptr(priv, tid_down, ra);
+ }
+
+ if (!ra_list) {
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+ mwifiex_write_data_complete(adapter, skb, -1);
+ return;
+ }
+
+ skb_queue_tail(&ra_list->skb_head, skb);
+
+ ra_list->total_pkts_size += skb->len;
+
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+}
+
+/*
+ * This function processes the get WMM status command response from firmware.
+ *
+ * The response may contain multiple TLVs -
+ * - AC Queue status TLVs
+ * - Current WMM Parameter IE TLV
+ * - Admission Control action frame TLVs
+ *
+ * This function parses the TLVs and then calls further specific functions
+ * to process any changes in the queue prioritize or state.
+ */
+int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
+ const struct host_cmd_ds_command *resp)
+{
+ u8 *curr = (u8 *) &resp->params.get_wmm_status;
+ uint16_t resp_len = le16_to_cpu(resp->size), tlv_len;
+ int valid = true;
+
+ struct mwifiex_ie_types_data *tlv_hdr;
+ struct mwifiex_ie_types_wmm_queue_status *tlv_wmm_qstatus;
+ struct ieee_types_wmm_parameter *wmm_param_ie = NULL;
+ struct mwifiex_wmm_ac_status *ac_status;
+
+ dev_dbg(priv->adapter->dev, "info: WMM: WMM_GET_STATUS cmdresp received: %d\n",
+ resp_len);
+
+ while ((resp_len >= sizeof(tlv_hdr->header)) && valid) {
+ tlv_hdr = (struct mwifiex_ie_types_data *) curr;
+ tlv_len = le16_to_cpu(tlv_hdr->header.len);
+
+ switch (le16_to_cpu(tlv_hdr->header.type)) {
+ case TLV_TYPE_WMMQSTATUS:
+ tlv_wmm_qstatus =
+ (struct mwifiex_ie_types_wmm_queue_status *)
+ tlv_hdr;
+ dev_dbg(priv->adapter->dev,
+ "info: CMD_RESP: WMM_GET_STATUS:"
+ " QSTATUS TLV: %d, %d, %d\n",
+ tlv_wmm_qstatus->queue_index,
+ tlv_wmm_qstatus->flow_required,
+ tlv_wmm_qstatus->disabled);
+
+ ac_status = &priv->wmm.ac_status[tlv_wmm_qstatus->
+ queue_index];
+ ac_status->disabled = tlv_wmm_qstatus->disabled;
+ ac_status->flow_required =
+ tlv_wmm_qstatus->flow_required;
+ ac_status->flow_created = tlv_wmm_qstatus->flow_created;
+ break;
+
+ case WLAN_EID_VENDOR_SPECIFIC:
+ /*
+ * Point the regular IEEE IE 2 bytes into the Marvell IE
+ * and setup the IEEE IE type and length byte fields
+ */
+
+ wmm_param_ie =
+ (struct ieee_types_wmm_parameter *) (curr +
+ 2);
+ wmm_param_ie->vend_hdr.len = (u8) tlv_len;
+ wmm_param_ie->vend_hdr.element_id =
+ WLAN_EID_VENDOR_SPECIFIC;
+
+ dev_dbg(priv->adapter->dev,
+ "info: CMD_RESP: WMM_GET_STATUS:"
+ " WMM Parameter Set Count: %d\n",
+ wmm_param_ie->qos_info_bitmap &
+ IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK);
+
+ memcpy((u8 *) &priv->curr_bss_params.bss_descriptor.
+ wmm_ie, wmm_param_ie,
+ wmm_param_ie->vend_hdr.len + 2);
+
+ break;
+
+ default:
+ valid = false;
+ break;
+ }
+
+ curr += (tlv_len + sizeof(tlv_hdr->header));
+ resp_len -= (tlv_len + sizeof(tlv_hdr->header));
+ }
+
+ mwifiex_wmm_setup_queue_priorities(priv, wmm_param_ie);
+ mwifiex_wmm_setup_ac_downgrade(priv);
+
+ return 0;
+}
+
+/*
+ * Callback handler from the command module to allow insertion of a WMM TLV.
+ *
+ * If the BSS we are associating to supports WMM, this function adds the
+ * required WMM Information IE to the association request command buffer in
+ * the form of a Marvell extended IEEE IE.
+ */
+u32
+mwifiex_wmm_process_association_req(struct mwifiex_private *priv,
+ u8 **assoc_buf,
+ struct ieee_types_wmm_parameter *wmm_ie,
+ struct ieee80211_ht_cap *ht_cap)
+{
+ struct mwifiex_ie_types_wmm_param_set *wmm_tlv;
+ u32 ret_len = 0;
+
+ /* Null checks */
+ if (!assoc_buf)
+ return 0;
+ if (!(*assoc_buf))
+ return 0;
+
+ if (!wmm_ie)
+ return 0;
+
+ dev_dbg(priv->adapter->dev, "info: WMM: process assoc req:"
+ "bss->wmmIe=0x%x\n",
+ wmm_ie->vend_hdr.element_id);
+
+ if ((priv->wmm_required
+ || (ht_cap && (priv->adapter->config_bands & BAND_GN
+ || priv->adapter->config_bands & BAND_AN))
+ )
+ && wmm_ie->vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) {
+ wmm_tlv = (struct mwifiex_ie_types_wmm_param_set *) *assoc_buf;
+ wmm_tlv->header.type = cpu_to_le16((u16) wmm_info_ie[0]);
+ wmm_tlv->header.len = cpu_to_le16((u16) wmm_info_ie[1]);
+ memcpy(wmm_tlv->wmm_ie, &wmm_info_ie[2],
+ le16_to_cpu(wmm_tlv->header.len));
+ if (wmm_ie->qos_info_bitmap & IEEE80211_WMM_IE_AP_QOSINFO_UAPSD)
+ memcpy((u8 *) (wmm_tlv->wmm_ie
+ + le16_to_cpu(wmm_tlv->header.len)
+ - sizeof(priv->wmm_qosinfo)),
+ &priv->wmm_qosinfo,
+ sizeof(priv->wmm_qosinfo));
+
+ ret_len = sizeof(wmm_tlv->header)
+ + le16_to_cpu(wmm_tlv->header.len);
+
+ *assoc_buf += ret_len;
+ }
+
+ return ret_len;
+}
+
+/*
+ * This function computes the time delay in the driver queues for a
+ * given packet.
+ *
+ * When the packet is received at the OS/Driver interface, the current
+ * time is set in the packet structure. The difference between the present
+ * time and that received time is computed in this function and limited
+ * based on pre-compiled limits in the driver.
+ */
+u8
+mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv,
+ const struct sk_buff *skb)
+{
+ u8 ret_val;
+ struct timeval out_tstamp, in_tstamp;
+ u32 queue_delay;
+
+ do_gettimeofday(&out_tstamp);
+ in_tstamp = ktime_to_timeval(skb->tstamp);
+
+ queue_delay = (out_tstamp.tv_sec - in_tstamp.tv_sec) * 1000;
+ queue_delay += (out_tstamp.tv_usec - in_tstamp.tv_usec) / 1000;
+
+ /*
+ * Queue delay is passed as a uint8 in units of 2ms (ms shifted
+ * by 1). Min value (other than 0) is therefore 2ms, max is 510ms.
+ *
+ * Pass max value if queue_delay is beyond the uint8 range
+ */
+ ret_val = (u8) (min(queue_delay, priv->wmm.drv_pkt_delay_max) >> 1);
+
+ dev_dbg(priv->adapter->dev, "data: WMM: Pkt Delay: %d ms,"
+ " %d ms sent to FW\n", queue_delay, ret_val);
+
+ return ret_val;
+}
+
+/*
+ * This function retrieves the highest priority RA list table pointer.
+ */
+static struct mwifiex_ra_list_tbl *
+mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
+ struct mwifiex_private **priv, int *tid)
+{
+ struct mwifiex_private *priv_tmp;
+ struct mwifiex_ra_list_tbl *ptr, *head;
+ struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head;
+ struct mwifiex_tid_tbl *tid_ptr;
+ int is_list_empty;
+ unsigned long flags;
+ int i, j;
+
+ for (j = adapter->priv_num - 1; j >= 0; --j) {
+ spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock,
+ flags);
+ is_list_empty = list_empty(&adapter->bss_prio_tbl[j]
+ .bss_prio_head);
+ spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock,
+ flags);
+ if (is_list_empty)
+ continue;
+
+ if (adapter->bss_prio_tbl[j].bss_prio_cur ==
+ (struct mwifiex_bss_prio_node *)
+ &adapter->bss_prio_tbl[j].bss_prio_head) {
+ bssprio_node =
+ list_first_entry(&adapter->bss_prio_tbl[j]
+ .bss_prio_head,
+ struct mwifiex_bss_prio_node,
+ list);
+ bssprio_head = bssprio_node;
+ } else {
+ bssprio_node = adapter->bss_prio_tbl[j].bss_prio_cur;
+ bssprio_head = bssprio_node;
+ }
+
+ do {
+ priv_tmp = bssprio_node->priv;
+
+ for (i = HIGH_PRIO_TID; i >= LOW_PRIO_TID; --i) {
+
+ tid_ptr = &(priv_tmp)->wmm.
+ tid_tbl_ptr[tos_to_tid[i]];
+
+ spin_lock_irqsave(&tid_ptr->tid_tbl_lock,
+ flags);
+ is_list_empty =
+ list_empty(&adapter->bss_prio_tbl[j]
+ .bss_prio_head);
+ spin_unlock_irqrestore(&tid_ptr->tid_tbl_lock,
+ flags);
+ if (is_list_empty)
+ continue;
+
+ /*
+ * Always choose the next ra we transmitted
+ * last time, this way we pick the ra's in
+ * round robin fashion.
+ */
+ ptr = list_first_entry(
+ &tid_ptr->ra_list_curr->list,
+ struct mwifiex_ra_list_tbl,
+ list);
+
+ head = ptr;
+ if (ptr == (struct mwifiex_ra_list_tbl *)
+ &tid_ptr->ra_list) {
+ /* Get next ra */
+ ptr = list_first_entry(&ptr->list,
+ struct mwifiex_ra_list_tbl, list);
+ head = ptr;
+ }
+
+ do {
+ is_list_empty =
+ skb_queue_empty(&ptr->skb_head);
+ if (!is_list_empty) {
+ *priv = priv_tmp;
+ *tid = tos_to_tid[i];
+ return ptr;
+ }
+ /* Get next ra */
+ ptr = list_first_entry(&ptr->list,
+ struct mwifiex_ra_list_tbl,
+ list);
+ if (ptr ==
+ (struct mwifiex_ra_list_tbl *)
+ &tid_ptr->ra_list)
+ ptr = list_first_entry(
+ &ptr->list,
+ struct mwifiex_ra_list_tbl,
+ list);
+ } while (ptr != head);
+ }
+
+ /* Get next bss priority node */
+ bssprio_node = list_first_entry(&bssprio_node->list,
+ struct mwifiex_bss_prio_node,
+ list);
+
+ if (bssprio_node ==
+ (struct mwifiex_bss_prio_node *)
+ &adapter->bss_prio_tbl[j].bss_prio_head)
+ /* Get next bss priority node */
+ bssprio_node = list_first_entry(
+ &bssprio_node->list,
+ struct mwifiex_bss_prio_node,
+ list);
+ } while (bssprio_node != bssprio_head);
+ }
+ return NULL;
+}
+
+/*
+ * This function gets the number of packets in the Tx queue of a
+ * particular RA list.
+ */
+static int
+mwifiex_num_pkts_in_txq(struct mwifiex_private *priv,
+ struct mwifiex_ra_list_tbl *ptr, int max_buf_size)
+{
+ int count = 0, total_size = 0;
+ struct sk_buff *skb, *tmp;
+
+ skb_queue_walk_safe(&ptr->skb_head, skb, tmp) {
+ total_size += skb->len;
+ if (total_size < max_buf_size)
+ ++count;
+ else
+ break;
+ }
+
+ return count;
+}
+
+/*
+ * This function sends a single packet to firmware for transmission.
+ */
+static void
+mwifiex_send_single_packet(struct mwifiex_private *priv,
+ struct mwifiex_ra_list_tbl *ptr, int ptr_index,
+ unsigned long ra_list_flags)
+ __releases(&priv->wmm.ra_list_spinlock)
+{
+ struct sk_buff *skb, *skb_next;
+ struct mwifiex_tx_param tx_param;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct mwifiex_txinfo *tx_info;
+
+ if (skb_queue_empty(&ptr->skb_head)) {
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ dev_dbg(adapter->dev, "data: nothing to send\n");
+ return;
+ }
+
+ skb = skb_dequeue(&ptr->skb_head);
+
+ tx_info = MWIFIEX_SKB_TXCB(skb);
+ dev_dbg(adapter->dev, "data: dequeuing the packet %p %p\n", ptr, skb);
+
+ ptr->total_pkts_size -= skb->len;
+
+ if (!skb_queue_empty(&ptr->skb_head))
+ skb_next = skb_peek(&ptr->skb_head);
+ else
+ skb_next = NULL;
+
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+ tx_param.next_pkt_len = ((skb_next) ? skb_next->len +
+ sizeof(struct txpd) : 0);
+
+ if (mwifiex_process_tx(priv, skb, &tx_param) == -EBUSY) {
+ /* Queue the packet back at the head */
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+ if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ mwifiex_write_data_complete(adapter, skb, -1);
+ return;
+ }
+
+ skb_queue_tail(&ptr->skb_head, skb);
+
+ ptr->total_pkts_size += skb->len;
+ tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ } else {
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+ if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+ priv->wmm.packets_out[ptr_index]++;
+ priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr;
+ }
+ adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
+ list_first_entry(
+ &adapter->bss_prio_tbl[priv->bss_priority]
+ .bss_prio_cur->list,
+ struct mwifiex_bss_prio_node,
+ list);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ }
+}
+
+/*
+ * This function checks if the first packet in the given RA list
+ * is already processed or not.
+ */
+static int
+mwifiex_is_ptr_processed(struct mwifiex_private *priv,
+ struct mwifiex_ra_list_tbl *ptr)
+{
+ struct sk_buff *skb;
+ struct mwifiex_txinfo *tx_info;
+
+ if (skb_queue_empty(&ptr->skb_head))
+ return false;
+
+ skb = skb_peek(&ptr->skb_head);
+
+ tx_info = MWIFIEX_SKB_TXCB(skb);
+ if (tx_info->flags & MWIFIEX_BUF_FLAG_REQUEUED_PKT)
+ return true;
+
+ return false;
+}
+
+/*
+ * This function sends a single processed packet to firmware for
+ * transmission.
+ */
+static void
+mwifiex_send_processed_packet(struct mwifiex_private *priv,
+ struct mwifiex_ra_list_tbl *ptr, int ptr_index,
+ unsigned long ra_list_flags)
+ __releases(&priv->wmm.ra_list_spinlock)
+{
+ struct mwifiex_tx_param tx_param;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ int ret = -1;
+ struct sk_buff *skb, *skb_next;
+ struct mwifiex_txinfo *tx_info;
+
+ if (skb_queue_empty(&ptr->skb_head)) {
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ return;
+ }
+
+ skb = skb_dequeue(&ptr->skb_head);
+
+ if (!skb_queue_empty(&ptr->skb_head))
+ skb_next = skb_peek(&ptr->skb_head);
+ else
+ skb_next = NULL;
+
+ tx_info = MWIFIEX_SKB_TXCB(skb);
+
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
+ tx_param.next_pkt_len =
+ ((skb_next) ? skb_next->len +
+ sizeof(struct txpd) : 0);
+ ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
+ skb->data, skb->len, &tx_param);
+ switch (ret) {
+ case -EBUSY:
+ dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+ if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ mwifiex_write_data_complete(adapter, skb, -1);
+ return;
+ }
+
+ skb_queue_tail(&ptr->skb_head, skb);
+
+ tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ break;
+ case -1:
+ adapter->data_sent = false;
+ dev_err(adapter->dev, "host_to_card failed: %#x\n", ret);
+ adapter->dbg.num_tx_host_to_card_failure++;
+ mwifiex_write_data_complete(adapter, skb, ret);
+ break;
+ case -EINPROGRESS:
+ adapter->data_sent = false;
+ default:
+ break;
+ }
+ if (ret != -EBUSY) {
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+ if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+ priv->wmm.packets_out[ptr_index]++;
+ priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr;
+ }
+ adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
+ list_first_entry(
+ &adapter->bss_prio_tbl[priv->bss_priority]
+ .bss_prio_cur->list,
+ struct mwifiex_bss_prio_node,
+ list);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ }
+}
+
+/*
+ * This function dequeues a packet from the highest priority list
+ * and transmits it.
+ */
+static int
+mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
+{
+ struct mwifiex_ra_list_tbl *ptr;
+ struct mwifiex_private *priv = NULL;
+ int ptr_index = 0;
+ u8 ra[ETH_ALEN];
+ int tid_del = 0, tid = 0;
+ unsigned long flags;
+
+ ptr = mwifiex_wmm_get_highest_priolist_ptr(adapter, &priv, &ptr_index);
+ if (!ptr)
+ return -1;
+
+ tid = mwifiex_get_tid(ptr);
+
+ dev_dbg(adapter->dev, "data: tid=%d\n", tid);
+
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
+ if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+ return -1;
+ }
+
+ if (mwifiex_is_ptr_processed(priv, ptr)) {
+ mwifiex_send_processed_packet(priv, ptr, ptr_index, flags);
+ /* ra_list_spinlock has been freed in
+ mwifiex_send_processed_packet() */
+ return 0;
+ }
+
+ if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid)
+ || ((priv->sec_info.wpa_enabled
+ || priv->sec_info.wpa2_enabled) && !priv->wpa_is_gtk_set)
+ ) {
+ mwifiex_send_single_packet(priv, ptr, ptr_index, flags);
+ /* ra_list_spinlock has been freed in
+ mwifiex_send_single_packet() */
+ } else {
+ if (mwifiex_is_ampdu_allowed(priv, tid)) {
+ if (mwifiex_space_avail_for_new_ba_stream(adapter)) {
+ mwifiex_11n_create_tx_ba_stream_tbl(priv,
+ ptr->ra, tid,
+ BA_STREAM_SETUP_INPROGRESS);
+ mwifiex_send_addba(priv, tid, ptr->ra);
+ } else if (mwifiex_find_stream_to_delete
+ (priv, tid, &tid_del, ra)) {
+ mwifiex_11n_create_tx_ba_stream_tbl(priv,
+ ptr->ra, tid,
+ BA_STREAM_SETUP_INPROGRESS);
+ mwifiex_send_delba(priv, tid_del, ra, 1);
+ }
+ }
+/* Minimum number of AMSDU */
+#define MIN_NUM_AMSDU 2
+ if (mwifiex_is_amsdu_allowed(priv, tid) &&
+ (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >=
+ MIN_NUM_AMSDU))
+ mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN,
+ ptr_index, flags);
+ /* ra_list_spinlock has been freed in
+ mwifiex_11n_aggregate_pkt() */
+ else
+ mwifiex_send_single_packet(priv, ptr, ptr_index, flags);
+ /* ra_list_spinlock has been freed in
+ mwifiex_send_single_packet() */
+ }
+ return 0;
+}
+
+/*
+ * This function transmits the highest priority packet awaiting in the
+ * WMM Queues.
+ */
+void
+mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter)
+{
+ do {
+ /* Check if busy */
+ if (adapter->data_sent || adapter->tx_lock_flag)
+ break;
+
+ if (mwifiex_dequeue_tx_packet(adapter))
+ break;
+ } while (true);
+}
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
new file mode 100644
index 00000000000..fcea1f68792
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -0,0 +1,110 @@
+/*
+ * Marvell Wireless LAN device driver: WMM
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_WMM_H_
+#define _MWIFIEX_WMM_H_
+
+enum ieee_types_wmm_aciaifsn_bitmasks {
+ MWIFIEX_AIFSN = (BIT(0) | BIT(1) | BIT(2) | BIT(3)),
+ MWIFIEX_ACM = BIT(4),
+ MWIFIEX_ACI = (BIT(5) | BIT(6)),
+};
+
+enum ieee_types_wmm_ecw_bitmasks {
+ MWIFIEX_ECW_MIN = (BIT(0) | BIT(1) | BIT(2) | BIT(3)),
+ MWIFIEX_ECW_MAX = (BIT(4) | BIT(5) | BIT(6) | BIT(7)),
+};
+
+/*
+ * This function retrieves the TID of the given RA list.
+ */
+static inline int
+mwifiex_get_tid(struct mwifiex_ra_list_tbl *ptr)
+{
+ struct sk_buff *skb;
+
+ if (skb_queue_empty(&ptr->skb_head))
+ return 0;
+
+ skb = skb_peek(&ptr->skb_head);
+
+ return skb->priority;
+}
+
+/*
+ * This function gets the length of a list.
+ */
+static inline int
+mwifiex_wmm_list_len(struct list_head *head)
+{
+ struct list_head *pos;
+ int count = 0;
+
+ list_for_each(pos, head)
+ ++count;
+
+ return count;
+}
+
+/*
+ * This function checks if a RA list is empty or not.
+ */
+static inline u8
+mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead)
+{
+ struct mwifiex_ra_list_tbl *ra_list;
+ int is_list_empty;
+
+ list_for_each_entry(ra_list, ra_list_hhead, list) {
+ is_list_empty = skb_queue_empty(&ra_list->skb_head);
+ if (!is_list_empty)
+ return false;
+ }
+
+ return true;
+}
+
+void mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
+ struct sk_buff *skb);
+void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra);
+
+int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter);
+void mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter);
+int mwifiex_is_ralist_valid(struct mwifiex_private *priv,
+ struct mwifiex_ra_list_tbl *ra_list, int tid);
+
+u8 mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv,
+ const struct sk_buff *skb);
+void mwifiex_wmm_init(struct mwifiex_adapter *adapter);
+
+extern u32 mwifiex_wmm_process_association_req(struct mwifiex_private *priv,
+ u8 **assoc_buf,
+ struct ieee_types_wmm_parameter
+ *wmmie,
+ struct ieee80211_ht_cap
+ *htcap);
+
+void mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv,
+ struct ieee_types_wmm_parameter
+ *wmm_ie);
+void mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv);
+extern int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
+ const struct host_cmd_ds_command *resp);
+
+#endif /* !_MWIFIEX_WMM_H_ */
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index c1ceb4b2397..32261189bce 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -63,6 +63,7 @@ MODULE_PARM_DESC(ap_mode_default,
#define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL 0x00000c38
#define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK 0x00000c3c
#define MWL8K_A2H_INT_DUMMY (1 << 20)
+#define MWL8K_A2H_INT_BA_WATCHDOG (1 << 14)
#define MWL8K_A2H_INT_CHNL_SWITCHED (1 << 11)
#define MWL8K_A2H_INT_QUEUE_EMPTY (1 << 10)
#define MWL8K_A2H_INT_RADAR_DETECT (1 << 7)
@@ -73,6 +74,14 @@ MODULE_PARM_DESC(ap_mode_default,
#define MWL8K_A2H_INT_RX_READY (1 << 1)
#define MWL8K_A2H_INT_TX_DONE (1 << 0)
+/* HW micro second timer register
+ * located at offset 0xA600. This
+ * will be used to timestamp tx
+ * packets.
+ */
+
+#define MWL8K_HW_TIMER_REGISTER 0x0000a600
+
#define MWL8K_A2H_EVENTS (MWL8K_A2H_INT_DUMMY | \
MWL8K_A2H_INT_CHNL_SWITCHED | \
MWL8K_A2H_INT_QUEUE_EMPTY | \
@@ -82,10 +91,14 @@ MODULE_PARM_DESC(ap_mode_default,
MWL8K_A2H_INT_MAC_EVENT | \
MWL8K_A2H_INT_OPC_DONE | \
MWL8K_A2H_INT_RX_READY | \
- MWL8K_A2H_INT_TX_DONE)
+ MWL8K_A2H_INT_TX_DONE | \
+ MWL8K_A2H_INT_BA_WATCHDOG)
#define MWL8K_RX_QUEUES 1
-#define MWL8K_TX_QUEUES 4
+#define MWL8K_TX_WMM_QUEUES 4
+#define MWL8K_MAX_AMPDU_QUEUES 8
+#define MWL8K_MAX_TX_QUEUES (MWL8K_TX_WMM_QUEUES + MWL8K_MAX_AMPDU_QUEUES)
+#define mwl8k_tx_queues(priv) (MWL8K_TX_WMM_QUEUES + (priv)->num_ampdu_queues)
struct rxd_ops {
int rxd_size;
@@ -134,6 +147,21 @@ struct mwl8k_tx_queue {
struct sk_buff **skb;
};
+enum {
+ AMPDU_NO_STREAM,
+ AMPDU_STREAM_NEW,
+ AMPDU_STREAM_IN_PROGRESS,
+ AMPDU_STREAM_ACTIVE,
+};
+
+struct mwl8k_ampdu_stream {
+ struct ieee80211_sta *sta;
+ u8 tid;
+ u8 state;
+ u8 idx;
+ u8 txq_idx; /* index of this stream in priv->txq */
+};
+
struct mwl8k_priv {
struct ieee80211_hw *hw;
struct pci_dev *pdev;
@@ -160,6 +188,12 @@ struct mwl8k_priv {
u32 ap_macids_supported;
u32 sta_macids_supported;
+ /* Ampdu stream information */
+ u8 num_ampdu_queues;
+ spinlock_t stream_lock;
+ struct mwl8k_ampdu_stream ampdu[MWL8K_MAX_AMPDU_QUEUES];
+ struct work_struct watchdog_ba_handle;
+
/* firmware access */
struct mutex fw_mutex;
struct task_struct *fw_mutex_owner;
@@ -191,7 +225,8 @@ struct mwl8k_priv {
int pending_tx_pkts;
struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
- struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES];
+ struct mwl8k_tx_queue txq[MWL8K_MAX_TX_QUEUES];
+ u32 txq_offset[MWL8K_MAX_TX_QUEUES];
bool radio_on;
bool radio_short_preamble;
@@ -224,7 +259,7 @@ struct mwl8k_priv {
* preserve the queue configurations so they can be restored if/when
* the firmware image is swapped.
*/
- struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_QUEUES];
+ struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_WMM_QUEUES];
/* async firmware loading state */
unsigned fw_state;
@@ -262,9 +297,17 @@ struct mwl8k_vif {
#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
#define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8))
+struct tx_traffic_info {
+ u32 start_time;
+ u32 pkts;
+};
+
+#define MWL8K_MAX_TID 8
struct mwl8k_sta {
/* Index into station database. Returned by UPDATE_STADB. */
u8 peer_id;
+ u8 is_ampdu_allowed;
+ struct tx_traffic_info tx_stats[MWL8K_MAX_TID];
};
#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
@@ -352,10 +395,12 @@ static const struct ieee80211_rate mwl8k_rates_50[] = {
#define MWL8K_CMD_ENABLE_SNIFFER 0x0150
#define MWL8K_CMD_SET_MAC_ADDR 0x0202 /* per-vif */
#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203
+#define MWL8K_CMD_GET_WATCHDOG_BITMAP 0x0205
#define MWL8K_CMD_BSS_START 0x1100 /* per-vif */
#define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */
#define MWL8K_CMD_UPDATE_ENCRYPTION 0x1122 /* per-vif */
#define MWL8K_CMD_UPDATE_STADB 0x1123
+#define MWL8K_CMD_BASTREAM 0x1125
static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
{
@@ -395,6 +440,8 @@ static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
MWL8K_CMDNAME(SET_NEW_STN);
MWL8K_CMDNAME(UPDATE_ENCRYPTION);
MWL8K_CMDNAME(UPDATE_STADB);
+ MWL8K_CMDNAME(BASTREAM);
+ MWL8K_CMDNAME(GET_WATCHDOG_BITMAP);
default:
snprintf(buf, bufsize, "0x%x", cmd);
}
@@ -669,7 +716,7 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw)
"helper image\n", pci_name(priv->pdev));
return rc;
}
- msleep(5);
+ msleep(20);
rc = mwl8k_feed_fw_image(priv, fw->data, fw->size);
} else {
@@ -734,8 +781,11 @@ static inline void mwl8k_remove_dma_header(struct sk_buff *skb, __le16 qos)
skb_pull(skb, sizeof(*tr) - hdrlen);
}
+#define REDUCED_TX_HEADROOM 8
+
static void
-mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad)
+mwl8k_add_dma_header(struct mwl8k_priv *priv, struct sk_buff *skb,
+ int head_pad, int tail_pad)
{
struct ieee80211_hdr *wh;
int hdrlen;
@@ -751,7 +801,23 @@ mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad)
wh = (struct ieee80211_hdr *)skb->data;
hdrlen = ieee80211_hdrlen(wh->frame_control);
- reqd_hdrlen = sizeof(*tr);
+
+ /*
+ * Check if skb_resize is required because of
+ * tx_headroom adjustment.
+ */
+ if (priv->ap_fw && (hdrlen < (sizeof(struct ieee80211_cts)
+ + REDUCED_TX_HEADROOM))) {
+ if (pskb_expand_head(skb, REDUCED_TX_HEADROOM, 0, GFP_ATOMIC)) {
+
+ wiphy_err(priv->hw->wiphy,
+ "Failed to reallocate TX buffer\n");
+ return;
+ }
+ skb->truesize += REDUCED_TX_HEADROOM;
+ }
+
+ reqd_hdrlen = sizeof(*tr) + head_pad;
if (hdrlen != reqd_hdrlen)
skb_push(skb, reqd_hdrlen - hdrlen);
@@ -773,12 +839,14 @@ mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad)
tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad);
}
-static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
+static void mwl8k_encapsulate_tx_frame(struct mwl8k_priv *priv,
+ struct sk_buff *skb)
{
struct ieee80211_hdr *wh;
struct ieee80211_tx_info *tx_info;
struct ieee80211_key_conf *key_conf;
int data_pad;
+ int head_pad = 0;
wh = (struct ieee80211_hdr *)skb->data;
@@ -790,9 +858,7 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
/*
* Make sure the packet header is in the DMA header format (4-address
- * without QoS), the necessary crypto padding between the header and the
- * payload has already been provided by mac80211, but it doesn't add tail
- * padding when HW crypto is enabled.
+ * without QoS), and add head & tail padding when HW crypto is enabled.
*
* We have the following trailer padding requirements:
* - WEP: 4 trailer bytes (ICV)
@@ -801,6 +867,7 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
*/
data_pad = 0;
if (key_conf != NULL) {
+ head_pad = key_conf->iv_len;
switch (key_conf->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
@@ -814,7 +881,7 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
break;
}
}
- mwl8k_add_dma_header(skb, data_pad);
+ mwl8k_add_dma_header(priv, skb, head_pad, data_pad);
}
/*
@@ -1127,6 +1194,9 @@ static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index)
struct mwl8k_rx_queue *rxq = priv->rxq + index;
int i;
+ if (rxq->rxd == NULL)
+ return;
+
for (i = 0; i < MWL8K_RX_DESCS; i++) {
if (rxq->buf[i].skb != NULL) {
pci_unmap_single(priv->pdev,
@@ -1319,7 +1389,7 @@ struct mwl8k_tx_desc {
__le16 pkt_len;
__u8 dest_MAC_addr[ETH_ALEN];
__le32 next_txd_phys_addr;
- __le32 reserved;
+ __le32 timestamp;
__le16 rate_info;
__u8 peer_id;
__u8 tx_frag_cnt;
@@ -1383,7 +1453,7 @@ static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw)
struct mwl8k_priv *priv = hw->priv;
int i;
- for (i = 0; i < MWL8K_TX_QUEUES; i++) {
+ for (i = 0; i < mwl8k_tx_queues(priv); i++) {
struct mwl8k_tx_queue *txq = priv->txq + i;
int fw_owned = 0;
int drv_owned = 0;
@@ -1452,9 +1522,8 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
if (timeout) {
WARN_ON(priv->pending_tx_pkts);
- if (retry) {
+ if (retry)
wiphy_notice(hw->wiphy, "tx rings drained\n");
- }
break;
}
@@ -1484,6 +1553,41 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
MWL8K_TXD_STATUS_OK_RETRY | \
MWL8K_TXD_STATUS_OK_MORE_RETRY))
+static int mwl8k_tid_queue_mapping(u8 tid)
+{
+ BUG_ON(tid > 7);
+
+ switch (tid) {
+ case 0:
+ case 3:
+ return IEEE80211_AC_BE;
+ break;
+ case 1:
+ case 2:
+ return IEEE80211_AC_BK;
+ break;
+ case 4:
+ case 5:
+ return IEEE80211_AC_VI;
+ break;
+ case 6:
+ case 7:
+ return IEEE80211_AC_VO;
+ break;
+ default:
+ return -1;
+ break;
+ }
+}
+
+/* The firmware will fill in the rate information
+ * for each packet that gets queued in the hardware
+ * and these macros will interpret that info.
+ */
+
+#define RI_FORMAT(a) (a & 0x0001)
+#define RI_RATE_ID_MCS(a) ((a & 0x01f8) >> 3)
+
static int
mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
{
@@ -1500,6 +1604,10 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
struct sk_buff *skb;
struct ieee80211_tx_info *info;
u32 status;
+ struct ieee80211_sta *sta;
+ struct mwl8k_sta *sta_info = NULL;
+ u16 rate_info;
+ struct ieee80211_hdr *wh;
tx = txq->head;
tx_desc = txq->txd + tx;
@@ -1528,18 +1636,40 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
mwl8k_remove_dma_header(skb, tx_desc->qos_control);
+ wh = (struct ieee80211_hdr *) skb->data;
+
/* Mark descriptor as unused */
tx_desc->pkt_phys_addr = 0;
tx_desc->pkt_len = 0;
info = IEEE80211_SKB_CB(skb);
+ if (ieee80211_is_data(wh->frame_control)) {
+ sta = info->control.sta;
+ if (sta) {
+ sta_info = MWL8K_STA(sta);
+ BUG_ON(sta_info == NULL);
+ rate_info = le16_to_cpu(tx_desc->rate_info);
+ /* If rate is < 6.5 Mpbs for an ht station
+ * do not form an ampdu. If the station is a
+ * legacy station (format = 0), do not form an
+ * ampdu
+ */
+ if (RI_RATE_ID_MCS(rate_info) < 1 ||
+ RI_FORMAT(rate_info) == 0) {
+ sta_info->is_ampdu_allowed = false;
+ } else {
+ sta_info->is_ampdu_allowed = true;
+ }
+ }
+ }
+
ieee80211_tx_info_clear_status(info);
/* Rate control is happening in the firmware.
* Ensure no tx rate is being reported.
*/
- info->status.rates[0].idx = -1;
- info->status.rates[0].count = 1;
+ info->status.rates[0].idx = -1;
+ info->status.rates[0].count = 1;
if (MWL8K_TXD_SUCCESS(status))
info->flags |= IEEE80211_TX_STAT_ACK;
@@ -1549,9 +1679,6 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
processed++;
}
- if (processed && priv->radio_on && !mutex_is_locked(&priv->fw_mutex))
- ieee80211_wake_queue(hw, index);
-
return processed;
}
@@ -1561,6 +1688,9 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
struct mwl8k_priv *priv = hw->priv;
struct mwl8k_tx_queue *txq = priv->txq + index;
+ if (txq->txd == NULL)
+ return;
+
mwl8k_txq_reclaim(hw, index, INT_MAX, 1);
kfree(txq->skb);
@@ -1572,12 +1702,116 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
txq->txd = NULL;
}
+/* caller must hold priv->stream_lock when calling the stream functions */
+static struct mwl8k_ampdu_stream *
+mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid)
+{
+ struct mwl8k_ampdu_stream *stream;
+ struct mwl8k_priv *priv = hw->priv;
+ int i;
+
+ for (i = 0; i < priv->num_ampdu_queues; i++) {
+ stream = &priv->ampdu[i];
+ if (stream->state == AMPDU_NO_STREAM) {
+ stream->sta = sta;
+ stream->state = AMPDU_STREAM_NEW;
+ stream->tid = tid;
+ stream->idx = i;
+ stream->txq_idx = MWL8K_TX_WMM_QUEUES + i;
+ wiphy_debug(hw->wiphy, "Added a new stream for %pM %d",
+ sta->addr, tid);
+ return stream;
+ }
+ }
+ return NULL;
+}
+
+static int
+mwl8k_start_stream(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
+{
+ int ret;
+
+ /* if the stream has already been started, don't start it again */
+ if (stream->state != AMPDU_STREAM_NEW)
+ return 0;
+ ret = ieee80211_start_tx_ba_session(stream->sta, stream->tid, 0);
+ if (ret)
+ wiphy_debug(hw->wiphy, "Failed to start stream for %pM %d: "
+ "%d\n", stream->sta->addr, stream->tid, ret);
+ else
+ wiphy_debug(hw->wiphy, "Started stream for %pM %d\n",
+ stream->sta->addr, stream->tid);
+ return ret;
+}
+
+static void
+mwl8k_remove_stream(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
+{
+ wiphy_debug(hw->wiphy, "Remove stream for %pM %d\n", stream->sta->addr,
+ stream->tid);
+ memset(stream, 0, sizeof(*stream));
+}
+
+static struct mwl8k_ampdu_stream *
+mwl8k_lookup_stream(struct ieee80211_hw *hw, u8 *addr, u8 tid)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ int i;
+
+ for (i = 0 ; i < priv->num_ampdu_queues; i++) {
+ struct mwl8k_ampdu_stream *stream;
+ stream = &priv->ampdu[i];
+ if (stream->state == AMPDU_NO_STREAM)
+ continue;
+ if (!memcmp(stream->sta->addr, addr, ETH_ALEN) &&
+ stream->tid == tid)
+ return stream;
+ }
+ return NULL;
+}
+
+#define MWL8K_AMPDU_PACKET_THRESHOLD 64
+static inline bool mwl8k_ampdu_allowed(struct ieee80211_sta *sta, u8 tid)
+{
+ struct mwl8k_sta *sta_info = MWL8K_STA(sta);
+ struct tx_traffic_info *tx_stats;
+
+ BUG_ON(tid >= MWL8K_MAX_TID);
+ tx_stats = &sta_info->tx_stats[tid];
+
+ return sta_info->is_ampdu_allowed &&
+ tx_stats->pkts > MWL8K_AMPDU_PACKET_THRESHOLD;
+}
+
+static inline void mwl8k_tx_count_packet(struct ieee80211_sta *sta, u8 tid)
+{
+ struct mwl8k_sta *sta_info = MWL8K_STA(sta);
+ struct tx_traffic_info *tx_stats;
+
+ BUG_ON(tid >= MWL8K_MAX_TID);
+ tx_stats = &sta_info->tx_stats[tid];
+
+ if (tx_stats->start_time == 0)
+ tx_stats->start_time = jiffies;
+
+ /* reset the packet count after each second elapses. If the number of
+ * packets ever exceeds the ampdu_min_traffic threshold, we will allow
+ * an ampdu stream to be started.
+ */
+ if (jiffies - tx_stats->start_time > HZ) {
+ tx_stats->pkts = 0;
+ tx_stats->start_time = 0;
+ } else
+ tx_stats->pkts++;
+}
+
static void
mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
{
struct mwl8k_priv *priv = hw->priv;
struct ieee80211_tx_info *tx_info;
struct mwl8k_vif *mwl8k_vif;
+ struct ieee80211_sta *sta;
struct ieee80211_hdr *wh;
struct mwl8k_tx_queue *txq;
struct mwl8k_tx_desc *tx;
@@ -1585,6 +1819,12 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
u32 txstatus;
u8 txdatarate;
u16 qos;
+ int txpriority;
+ u8 tid = 0;
+ struct mwl8k_ampdu_stream *stream = NULL;
+ bool start_ba_session = false;
+ bool mgmtframe = false;
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
wh = (struct ieee80211_hdr *)skb->data;
if (ieee80211_is_data_qos(wh->frame_control))
@@ -1592,14 +1832,18 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
else
qos = 0;
+ if (ieee80211_is_mgmt(wh->frame_control))
+ mgmtframe = true;
+
if (priv->ap_fw)
- mwl8k_encapsulate_tx_frame(skb);
+ mwl8k_encapsulate_tx_frame(priv, skb);
else
- mwl8k_add_dma_header(skb, 0);
+ mwl8k_add_dma_header(priv, skb, 0, 0);
wh = &((struct mwl8k_dma_data *)skb->data)->wh;
tx_info = IEEE80211_SKB_CB(skb);
+ sta = tx_info->control.sta;
mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
@@ -1627,12 +1871,91 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
qos |= MWL8K_QOS_ACK_POLICY_NORMAL;
}
+ /* Queue ADDBA request in the respective data queue. While setting up
+ * the ampdu stream, mac80211 queues further packets for that
+ * particular ra/tid pair. However, packets piled up in the hardware
+ * for that ra/tid pair will still go out. ADDBA request and the
+ * related data packets going out from different queues asynchronously
+ * will cause a shift in the receiver window which might result in
+ * ampdu packets getting dropped at the receiver after the stream has
+ * been setup.
+ */
+ if (unlikely(ieee80211_is_action(wh->frame_control) &&
+ mgmt->u.action.category == WLAN_CATEGORY_BACK &&
+ mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ &&
+ priv->ap_fw)) {
+ u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
+ tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
+ index = mwl8k_tid_queue_mapping(tid);
+ }
+
+ txpriority = index;
+
+ if (ieee80211_is_data_qos(wh->frame_control) &&
+ skb->protocol != cpu_to_be16(ETH_P_PAE) &&
+ sta->ht_cap.ht_supported && priv->ap_fw) {
+ tid = qos & 0xf;
+ mwl8k_tx_count_packet(sta, tid);
+ spin_lock(&priv->stream_lock);
+ stream = mwl8k_lookup_stream(hw, sta->addr, tid);
+ if (stream != NULL) {
+ if (stream->state == AMPDU_STREAM_ACTIVE) {
+ txpriority = stream->txq_idx;
+ index = stream->txq_idx;
+ } else if (stream->state == AMPDU_STREAM_NEW) {
+ /* We get here if the driver sends us packets
+ * after we've initiated a stream, but before
+ * our ampdu_action routine has been called
+ * with IEEE80211_AMPDU_TX_START to get the SSN
+ * for the ADDBA request. So this packet can
+ * go out with no risk of sequence number
+ * mismatch. No special handling is required.
+ */
+ } else {
+ /* Drop packets that would go out after the
+ * ADDBA request was sent but before the ADDBA
+ * response is received. If we don't do this,
+ * the recipient would probably receive it
+ * after the ADDBA request with SSN 0. This
+ * will cause the recipient's BA receive window
+ * to shift, which would cause the subsequent
+ * packets in the BA stream to be discarded.
+ * mac80211 queues our packets for us in this
+ * case, so this is really just a safety check.
+ */
+ wiphy_warn(hw->wiphy,
+ "Cannot send packet while ADDBA "
+ "dialog is underway.\n");
+ spin_unlock(&priv->stream_lock);
+ dev_kfree_skb(skb);
+ return;
+ }
+ } else {
+ /* Defer calling mwl8k_start_stream so that the current
+ * skb can go out before the ADDBA request. This
+ * prevents sequence number mismatch at the recepient
+ * as described above.
+ */
+ if (mwl8k_ampdu_allowed(sta, tid)) {
+ stream = mwl8k_add_stream(hw, sta, tid);
+ if (stream != NULL)
+ start_ba_session = true;
+ }
+ }
+ spin_unlock(&priv->stream_lock);
+ }
+
dma = pci_map_single(priv->pdev, skb->data,
skb->len, PCI_DMA_TODEVICE);
if (pci_dma_mapping_error(priv->pdev, dma)) {
wiphy_debug(hw->wiphy,
"failed to dma map skb, dropping TX frame.\n");
+ if (start_ba_session) {
+ spin_lock(&priv->stream_lock);
+ mwl8k_remove_stream(hw, stream);
+ spin_unlock(&priv->stream_lock);
+ }
dev_kfree_skb(skb);
return;
}
@@ -1641,12 +1964,34 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
txq = priv->txq + index;
+ /* Mgmt frames that go out frequently are probe
+ * responses. Other mgmt frames got out relatively
+ * infrequently. Hence reserve 2 buffers so that
+ * other mgmt frames do not get dropped due to an
+ * already queued probe response in one of the
+ * reserved buffers.
+ */
+
+ if (txq->len >= MWL8K_TX_DESCS - 2) {
+ if (mgmtframe == false ||
+ txq->len == MWL8K_TX_DESCS) {
+ if (start_ba_session) {
+ spin_lock(&priv->stream_lock);
+ mwl8k_remove_stream(hw, stream);
+ spin_unlock(&priv->stream_lock);
+ }
+ spin_unlock_bh(&priv->tx_lock);
+ dev_kfree_skb(skb);
+ return;
+ }
+ }
+
BUG_ON(txq->skb[txq->tail] != NULL);
txq->skb[txq->tail] = skb;
tx = txq->txd + txq->tail;
tx->data_rate = txdatarate;
- tx->tx_priority = index;
+ tx->tx_priority = txpriority;
tx->qos_control = cpu_to_le16(qos);
tx->pkt_phys_addr = cpu_to_le32(dma);
tx->pkt_len = cpu_to_le16(skb->len);
@@ -1655,6 +2000,11 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id;
else
tx->peer_id = 0;
+
+ if (priv->ap_fw)
+ tx->timestamp = cpu_to_le32(ioread32(priv->regs +
+ MWL8K_HW_TIMER_REGISTER));
+
wmb();
tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
@@ -1665,12 +2015,17 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
if (txq->tail == MWL8K_TX_DESCS)
txq->tail = 0;
- if (txq->head == txq->tail)
- ieee80211_stop_queue(hw, index);
-
mwl8k_tx_start(priv);
spin_unlock_bh(&priv->tx_lock);
+
+ /* Initiate the ampdu session here */
+ if (start_ba_session) {
+ spin_lock(&priv->stream_lock);
+ if (mwl8k_start_stream(hw, stream))
+ mwl8k_remove_stream(hw, stream);
+ spin_unlock(&priv->stream_lock);
+ }
}
@@ -1868,7 +2223,7 @@ struct mwl8k_cmd_get_hw_spec_sta {
__u8 mcs_bitmap[16];
__le32 rx_queue_ptr;
__le32 num_tx_queues;
- __le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
+ __le32 tx_queue_ptrs[MWL8K_TX_WMM_QUEUES];
__le32 caps2;
__le32 num_tx_desc_per_queue;
__le32 total_rxd;
@@ -1974,8 +2329,8 @@ static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
- cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
- for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv));
+ for (i = 0; i < mwl8k_tx_queues(priv); i++)
cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
@@ -2017,13 +2372,16 @@ struct mwl8k_cmd_get_hw_spec_ap {
__le32 wcbbase2;
__le32 wcbbase3;
__le32 fw_api_version;
+ __le32 caps;
+ __le32 num_of_ampdu_queues;
+ __le32 wcbbase_ampdu[MWL8K_MAX_AMPDU_QUEUES];
} __packed;
static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
{
struct mwl8k_priv *priv = hw->priv;
struct mwl8k_cmd_get_hw_spec_ap *cmd;
- int rc;
+ int rc, i;
u32 api_version;
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -2055,27 +2413,31 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
priv->fw_rev = le32_to_cpu(cmd->fw_rev);
priv->hw_rev = cmd->hw_rev;
- mwl8k_setup_2ghz_band(hw);
+ mwl8k_set_caps(hw, le32_to_cpu(cmd->caps));
priv->ap_macids_supported = 0x000000ff;
priv->sta_macids_supported = 0x00000000;
-
- off = le32_to_cpu(cmd->wcbbase0) & 0xffff;
- iowrite32(priv->txq[0].txd_dma, priv->sram + off);
-
+ priv->num_ampdu_queues = le32_to_cpu(cmd->num_of_ampdu_queues);
+ if (priv->num_ampdu_queues > MWL8K_MAX_AMPDU_QUEUES) {
+ wiphy_warn(hw->wiphy, "fw reported %d ampdu queues"
+ " but we only support %d.\n",
+ priv->num_ampdu_queues,
+ MWL8K_MAX_AMPDU_QUEUES);
+ priv->num_ampdu_queues = MWL8K_MAX_AMPDU_QUEUES;
+ }
off = le32_to_cpu(cmd->rxwrptr) & 0xffff;
iowrite32(priv->rxq[0].rxd_dma, priv->sram + off);
off = le32_to_cpu(cmd->rxrdptr) & 0xffff;
iowrite32(priv->rxq[0].rxd_dma, priv->sram + off);
- off = le32_to_cpu(cmd->wcbbase1) & 0xffff;
- iowrite32(priv->txq[1].txd_dma, priv->sram + off);
+ priv->txq_offset[0] = le32_to_cpu(cmd->wcbbase0) & 0xffff;
+ priv->txq_offset[1] = le32_to_cpu(cmd->wcbbase1) & 0xffff;
+ priv->txq_offset[2] = le32_to_cpu(cmd->wcbbase2) & 0xffff;
+ priv->txq_offset[3] = le32_to_cpu(cmd->wcbbase3) & 0xffff;
- off = le32_to_cpu(cmd->wcbbase2) & 0xffff;
- iowrite32(priv->txq[2].txd_dma, priv->sram + off);
-
- off = le32_to_cpu(cmd->wcbbase3) & 0xffff;
- iowrite32(priv->txq[3].txd_dma, priv->sram + off);
+ for (i = 0; i < priv->num_ampdu_queues; i++)
+ priv->txq_offset[i + MWL8K_TX_WMM_QUEUES] =
+ le32_to_cpu(cmd->wcbbase_ampdu[i]) & 0xffff;
}
done:
@@ -2098,12 +2460,20 @@ struct mwl8k_cmd_set_hw_spec {
__le32 caps;
__le32 rx_queue_ptr;
__le32 num_tx_queues;
- __le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
+ __le32 tx_queue_ptrs[MWL8K_MAX_TX_QUEUES];
__le32 flags;
__le32 num_tx_desc_per_queue;
__le32 total_rxd;
} __packed;
+/* If enabled, MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY will cause
+ * packets to expire 500 ms after the timestamp in the tx descriptor. That is,
+ * the packets that are queued for more than 500ms, will be dropped in the
+ * hardware. This helps minimizing the issues caused due to head-of-line
+ * blocking where a slow client can hog the bandwidth and affect traffic to a
+ * faster client.
+ */
+#define MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY 0x00000400
#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080
#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020
#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010
@@ -2124,7 +2494,7 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
- cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
+ cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv));
/*
* Mac80211 stack has Q0 as highest priority and Q3 as lowest in
@@ -2132,14 +2502,15 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
* in that order. Map Q3 of mac80211 to Q0 of firmware so that the
* priority is interpreted the right way in firmware.
*/
- for (i = 0; i < MWL8K_TX_QUEUES; i++) {
- int j = MWL8K_TX_QUEUES - 1 - i;
+ for (i = 0; i < mwl8k_tx_queues(priv); i++) {
+ int j = mwl8k_tx_queues(priv) - 1 - i;
cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[j].txd_dma);
}
cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT |
MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP |
- MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON);
+ MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON |
+ MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY);
cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
@@ -2356,7 +2727,7 @@ struct mwl8k_cmd_tx_power {
__le16 bw;
__le16 sub_ch;
__le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
-} __attribute__((packed));
+} __packed;
static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw,
struct ieee80211_conf *conf,
@@ -3123,6 +3494,65 @@ static int mwl8k_cmd_set_rateadapt_mode(struct ieee80211_hw *hw, __u16 mode)
}
/*
+ * CMD_GET_WATCHDOG_BITMAP.
+ */
+struct mwl8k_cmd_get_watchdog_bitmap {
+ struct mwl8k_cmd_pkt header;
+ u8 bitmap;
+} __packed;
+
+static int mwl8k_cmd_get_watchdog_bitmap(struct ieee80211_hw *hw, u8 *bitmap)
+{
+ struct mwl8k_cmd_get_watchdog_bitmap *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_WATCHDOG_BITMAP);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ if (!rc)
+ *bitmap = cmd->bitmap;
+
+ kfree(cmd);
+
+ return rc;
+}
+
+#define INVALID_BA 0xAA
+static void mwl8k_watchdog_ba_events(struct work_struct *work)
+{
+ int rc;
+ u8 bitmap = 0, stream_index;
+ struct mwl8k_ampdu_stream *streams;
+ struct mwl8k_priv *priv =
+ container_of(work, struct mwl8k_priv, watchdog_ba_handle);
+
+ rc = mwl8k_cmd_get_watchdog_bitmap(priv->hw, &bitmap);
+ if (rc)
+ return;
+
+ if (bitmap == INVALID_BA)
+ return;
+
+ /* the bitmap is the hw queue number. Map it to the ampdu queue. */
+ stream_index = bitmap - MWL8K_TX_WMM_QUEUES;
+
+ BUG_ON(stream_index >= priv->num_ampdu_queues);
+
+ streams = &priv->ampdu[stream_index];
+
+ if (streams->state == AMPDU_STREAM_ACTIVE)
+ ieee80211_stop_tx_ba_session(streams->sta, streams->tid);
+
+ return;
+}
+
+
+/*
* CMD_BSS_START.
*/
struct mwl8k_cmd_bss_start {
@@ -3151,6 +3581,152 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
}
/*
+ * CMD_BASTREAM.
+ */
+
+/*
+ * UPSTREAM is tx direction
+ */
+#define BASTREAM_FLAG_DIRECTION_UPSTREAM 0x00
+#define BASTREAM_FLAG_IMMEDIATE_TYPE 0x01
+
+enum ba_stream_action_type {
+ MWL8K_BA_CREATE,
+ MWL8K_BA_UPDATE,
+ MWL8K_BA_DESTROY,
+ MWL8K_BA_FLUSH,
+ MWL8K_BA_CHECK,
+};
+
+
+struct mwl8k_create_ba_stream {
+ __le32 flags;
+ __le32 idle_thrs;
+ __le32 bar_thrs;
+ __le32 window_size;
+ u8 peer_mac_addr[6];
+ u8 dialog_token;
+ u8 tid;
+ u8 queue_id;
+ u8 param_info;
+ __le32 ba_context;
+ u8 reset_seq_no_flag;
+ __le16 curr_seq_no;
+ u8 sta_src_mac_addr[6];
+} __packed;
+
+struct mwl8k_destroy_ba_stream {
+ __le32 flags;
+ __le32 ba_context;
+} __packed;
+
+struct mwl8k_cmd_bastream {
+ struct mwl8k_cmd_pkt header;
+ __le32 action;
+ union {
+ struct mwl8k_create_ba_stream create_params;
+ struct mwl8k_destroy_ba_stream destroy_params;
+ };
+} __packed;
+
+static int
+mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
+{
+ struct mwl8k_cmd_bastream *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ cmd->action = cpu_to_le32(MWL8K_BA_CHECK);
+
+ cmd->create_params.queue_id = stream->idx;
+ memcpy(&cmd->create_params.peer_mac_addr[0], stream->sta->addr,
+ ETH_ALEN);
+ cmd->create_params.tid = stream->tid;
+
+ cmd->create_params.flags =
+ cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE) |
+ cpu_to_le32(BASTREAM_FLAG_DIRECTION_UPSTREAM);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+
+ kfree(cmd);
+
+ return rc;
+}
+
+static int
+mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream,
+ u8 buf_size)
+{
+ struct mwl8k_cmd_bastream *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ cmd->action = cpu_to_le32(MWL8K_BA_CREATE);
+
+ cmd->create_params.bar_thrs = cpu_to_le32((u32)buf_size);
+ cmd->create_params.window_size = cpu_to_le32((u32)buf_size);
+ cmd->create_params.queue_id = stream->idx;
+
+ memcpy(cmd->create_params.peer_mac_addr, stream->sta->addr, ETH_ALEN);
+ cmd->create_params.tid = stream->tid;
+ cmd->create_params.curr_seq_no = cpu_to_le16(0);
+ cmd->create_params.reset_seq_no_flag = 1;
+
+ cmd->create_params.param_info =
+ (stream->sta->ht_cap.ampdu_factor &
+ IEEE80211_HT_AMPDU_PARM_FACTOR) |
+ ((stream->sta->ht_cap.ampdu_density << 2) &
+ IEEE80211_HT_AMPDU_PARM_DENSITY);
+
+ cmd->create_params.flags =
+ cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE |
+ BASTREAM_FLAG_DIRECTION_UPSTREAM);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+
+ wiphy_debug(hw->wiphy, "Created a BA stream for %pM : tid %d\n",
+ stream->sta->addr, stream->tid);
+ kfree(cmd);
+
+ return rc;
+}
+
+static void mwl8k_destroy_ba(struct ieee80211_hw *hw,
+ struct mwl8k_ampdu_stream *stream)
+{
+ struct mwl8k_cmd_bastream *cmd;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le32(MWL8K_BA_DESTROY);
+
+ cmd->destroy_params.ba_context = cpu_to_le32(stream->idx);
+ mwl8k_post_cmd(hw, &cmd->header);
+
+ wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", stream->idx);
+
+ kfree(cmd);
+}
+
+/*
* CMD_SET_NEW_STN.
*/
struct mwl8k_cmd_set_new_stn {
@@ -3274,7 +3850,7 @@ struct mwl8k_cmd_update_encryption {
__u8 mac_addr[6];
__u8 encr_type;
-} __attribute__((packed));
+} __packed;
struct mwl8k_cmd_set_key {
struct mwl8k_cmd_pkt header;
@@ -3294,7 +3870,7 @@ struct mwl8k_cmd_set_key {
__le16 tkip_tsc_low;
__le32 tkip_tsc_high;
__u8 mac_addr[6];
-} __attribute__((packed));
+} __packed;
enum {
MWL8K_ENCR_ENABLE,
@@ -3422,7 +3998,7 @@ static int mwl8k_cmd_encryption_set_key(struct ieee80211_hw *hw,
mwl8k_vif->wep_key_conf[idx].enabled = 1;
}
- keymlen = 0;
+ keymlen = key->keylen;
action = MWL8K_ENCR_SET_KEY;
break;
case WLAN_CIPHER_SUITE_TKIP:
@@ -3496,7 +4072,6 @@ static int mwl8k_set_key(struct ieee80211_hw *hw,
addr = sta->addr;
if (cmd_param == SET_KEY) {
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
rc = mwl8k_cmd_encryption_set_key(hw, vif, addr, key);
if (rc)
goto out;
@@ -3671,6 +4246,11 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
tasklet_schedule(&priv->poll_rx_task);
}
+ if (status & MWL8K_A2H_INT_BA_WATCHDOG) {
+ status &= ~MWL8K_A2H_INT_BA_WATCHDOG;
+ ieee80211_queue_work(hw, &priv->watchdog_ba_handle);
+ }
+
if (status)
iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
@@ -3699,7 +4279,7 @@ static void mwl8k_tx_poll(unsigned long data)
spin_lock_bh(&priv->tx_lock);
- for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ for (i = 0; i < mwl8k_tx_queues(priv); i++)
limit -= mwl8k_txq_reclaim(hw, i, limit, 0);
if (!priv->pending_tx_pkts && priv->tx_wait != NULL) {
@@ -3774,6 +4354,8 @@ static int mwl8k_start(struct ieee80211_hw *hw)
/* Enable interrupts */
iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+ iowrite32(MWL8K_A2H_EVENTS,
+ priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
rc = mwl8k_fw_lock(hw);
if (!rc) {
@@ -3829,6 +4411,7 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
/* Stop finalize join worker */
cancel_work_sync(&priv->finalize_join_worker);
+ cancel_work_sync(&priv->watchdog_ba_handle);
if (priv->beacon_skb != NULL)
dev_kfree_skb(priv->beacon_skb);
@@ -3837,7 +4420,7 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
tasklet_disable(&priv->poll_rx_task);
/* Return all skbs to mac80211 */
- for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ for (i = 0; i < mwl8k_tx_queues(priv); i++)
mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
}
@@ -3958,9 +4541,12 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
conf->power_level = 18;
if (priv->ap_fw) {
- rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level);
- if (rc)
- goto out;
+
+ if (conf->flags & IEEE80211_CONF_CHANGE_POWER) {
+ rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level);
+ if (rc)
+ goto out;
+ }
rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x3);
if (rc)
@@ -3987,7 +4573,7 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *info, u32 changed)
{
struct mwl8k_priv *priv = hw->priv;
- u32 ap_legacy_rates;
+ u32 ap_legacy_rates = 0;
u8 ap_mcs_rates[16];
int rc;
@@ -4312,6 +4898,8 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw,
ret = mwl8k_cmd_update_stadb_add(hw, vif, sta);
if (ret >= 0) {
MWL8K_STA(sta)->peer_id = ret;
+ if (sta->ht_cap.ht_supported)
+ MWL8K_STA(sta)->is_ampdu_allowed = true;
ret = 0;
}
@@ -4335,14 +4923,14 @@ static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
rc = mwl8k_fw_lock(hw);
if (!rc) {
- BUG_ON(queue > MWL8K_TX_QUEUES - 1);
+ BUG_ON(queue > MWL8K_TX_WMM_QUEUES - 1);
memcpy(&priv->wmm_params[queue], params, sizeof(*params));
if (!priv->wmm_enabled)
rc = mwl8k_cmd_set_wmm_mode(hw, 1);
if (!rc) {
- int q = MWL8K_TX_QUEUES - 1 - queue;
+ int q = MWL8K_TX_WMM_QUEUES - 1 - queue;
rc = mwl8k_cmd_set_edca_params(hw, q,
params->cw_min,
params->cw_max,
@@ -4378,21 +4966,118 @@ static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx,
return 0;
}
+#define MAX_AMPDU_ATTEMPTS 5
+
static int
mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
enum ieee80211_ampdu_mlme_action action,
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
u8 buf_size)
{
+
+ int i, rc = 0;
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_ampdu_stream *stream;
+ u8 *addr = sta->addr;
+
+ if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
+ return -ENOTSUPP;
+
+ spin_lock(&priv->stream_lock);
+ stream = mwl8k_lookup_stream(hw, addr, tid);
+
switch (action) {
case IEEE80211_AMPDU_RX_START:
case IEEE80211_AMPDU_RX_STOP:
- if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
- return -ENOTSUPP;
- return 0;
+ break;
+ case IEEE80211_AMPDU_TX_START:
+ /* By the time we get here the hw queues may contain outgoing
+ * packets for this RA/TID that are not part of this BA
+ * session. The hw will assign sequence numbers to these
+ * packets as they go out. So if we query the hw for its next
+ * sequence number and use that for the SSN here, it may end up
+ * being wrong, which will lead to sequence number mismatch at
+ * the recipient. To avoid this, we reset the sequence number
+ * to O for the first MPDU in this BA stream.
+ */
+ *ssn = 0;
+ if (stream == NULL) {
+ /* This means that somebody outside this driver called
+ * ieee80211_start_tx_ba_session. This is unexpected
+ * because we do our own rate control. Just warn and
+ * move on.
+ */
+ wiphy_warn(hw->wiphy, "Unexpected call to %s. "
+ "Proceeding anyway.\n", __func__);
+ stream = mwl8k_add_stream(hw, sta, tid);
+ }
+ if (stream == NULL) {
+ wiphy_debug(hw->wiphy, "no free AMPDU streams\n");
+ rc = -EBUSY;
+ break;
+ }
+ stream->state = AMPDU_STREAM_IN_PROGRESS;
+
+ /* Release the lock before we do the time consuming stuff */
+ spin_unlock(&priv->stream_lock);
+ for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) {
+ rc = mwl8k_check_ba(hw, stream);
+
+ if (!rc)
+ break;
+ /*
+ * HW queues take time to be flushed, give them
+ * sufficient time
+ */
+
+ msleep(1000);
+ }
+ spin_lock(&priv->stream_lock);
+ if (rc) {
+ wiphy_err(hw->wiphy, "Stream for tid %d busy after %d"
+ " attempts\n", tid, MAX_AMPDU_ATTEMPTS);
+ mwl8k_remove_stream(hw, stream);
+ rc = -EBUSY;
+ break;
+ }
+ ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid);
+ break;
+ case IEEE80211_AMPDU_TX_STOP:
+ if (stream == NULL)
+ break;
+ if (stream->state == AMPDU_STREAM_ACTIVE) {
+ spin_unlock(&priv->stream_lock);
+ mwl8k_destroy_ba(hw, stream);
+ spin_lock(&priv->stream_lock);
+ }
+ mwl8k_remove_stream(hw, stream);
+ ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid);
+ break;
+ case IEEE80211_AMPDU_TX_OPERATIONAL:
+ BUG_ON(stream == NULL);
+ BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS);
+ spin_unlock(&priv->stream_lock);
+ rc = mwl8k_create_ba(hw, stream, buf_size);
+ spin_lock(&priv->stream_lock);
+ if (!rc)
+ stream->state = AMPDU_STREAM_ACTIVE;
+ else {
+ spin_unlock(&priv->stream_lock);
+ mwl8k_destroy_ba(hw, stream);
+ spin_lock(&priv->stream_lock);
+ wiphy_debug(hw->wiphy,
+ "Failed adding stream for sta %pM tid %d\n",
+ addr, tid);
+ mwl8k_remove_stream(hw, stream);
+ }
+ break;
+
default:
- return -ENOTSUPP;
+ rc = -ENOTSUPP;
}
+
+ spin_unlock(&priv->stream_lock);
+ return rc;
}
static const struct ieee80211_ops mwl8k_ops = {
@@ -4441,7 +5126,7 @@ enum {
MWL8366,
};
-#define MWL8K_8366_AP_FW_API 1
+#define MWL8K_8366_AP_FW_API 2
#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
@@ -4607,6 +5292,23 @@ static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image,
return rc;
}
+static int mwl8k_init_txqs(struct ieee80211_hw *hw)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ int rc = 0;
+ int i;
+
+ for (i = 0; i < mwl8k_tx_queues(priv); i++) {
+ rc = mwl8k_txq_init(hw, i);
+ if (rc)
+ break;
+ if (priv->ap_fw)
+ iowrite32(priv->txq[i].txd_dma,
+ priv->sram + priv->txq_offset[i]);
+ }
+ return rc;
+}
+
/* initialize hw after successfully loading a firmware image */
static int mwl8k_probe_hw(struct ieee80211_hw *hw)
{
@@ -4634,17 +5336,26 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
goto err_stop_firmware;
rxq_refill(hw, 0, INT_MAX);
- for (i = 0; i < MWL8K_TX_QUEUES; i++) {
- rc = mwl8k_txq_init(hw, i);
+ /* For the sta firmware, we need to know the dma addresses of tx queues
+ * before sending MWL8K_CMD_GET_HW_SPEC. So we must initialize them
+ * prior to issuing this command. But for the AP case, we learn the
+ * total number of queues from the result CMD_GET_HW_SPEC, so for this
+ * case we must initialize the tx queues after.
+ */
+ priv->num_ampdu_queues = 0;
+ if (!priv->ap_fw) {
+ rc = mwl8k_init_txqs(hw);
if (rc)
goto err_free_queues;
}
iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
- iowrite32(MWL8K_A2H_INT_TX_DONE | MWL8K_A2H_INT_RX_READY,
+ iowrite32(MWL8K_A2H_INT_TX_DONE|MWL8K_A2H_INT_RX_READY|
+ MWL8K_A2H_INT_BA_WATCHDOG,
priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
- iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
+ iowrite32(MWL8K_A2H_INT_OPC_DONE,
+ priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
IRQF_SHARED, MWL8K_NAME, hw);
@@ -4653,6 +5364,8 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
goto err_free_queues;
}
+ memset(priv->ampdu, 0, sizeof(priv->ampdu));
+
/*
* Temporarily enable interrupts. Initial firmware host
* commands use interrupts and avoid polling. Disable
@@ -4664,6 +5377,8 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
if (priv->ap_fw) {
rc = mwl8k_cmd_get_hw_spec_ap(hw);
if (!rc)
+ rc = mwl8k_init_txqs(hw);
+ if (!rc)
rc = mwl8k_cmd_set_hw_spec(hw);
} else {
rc = mwl8k_cmd_get_hw_spec_sta(hw);
@@ -4705,7 +5420,7 @@ err_free_irq:
free_irq(priv->pdev->irq, hw);
err_free_queues:
- for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ for (i = 0; i < mwl8k_tx_queues(priv); i++)
mwl8k_txq_deinit(hw, i);
mwl8k_rxq_deinit(hw, 0);
@@ -4727,7 +5442,7 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image)
mwl8k_stop(hw);
mwl8k_rxq_deinit(hw, 0);
- for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ for (i = 0; i < mwl8k_tx_queues(priv); i++)
mwl8k_txq_deinit(hw, i);
rc = mwl8k_init_firmware(hw, fw_image, false);
@@ -4746,7 +5461,7 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image)
if (rc)
goto fail;
- for (i = 0; i < MWL8K_TX_QUEUES; i++) {
+ for (i = 0; i < MWL8K_TX_WMM_QUEUES; i++) {
rc = mwl8k_conf_tx(hw, i, &priv->wmm_params[i]);
if (rc)
goto fail;
@@ -4778,9 +5493,11 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
hw->extra_tx_headroom =
sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts);
+ hw->extra_tx_headroom -= priv->ap_fw ? REDUCED_TX_HEADROOM : 0;
+
hw->channel_change_time = 10;
- hw->queues = MWL8K_TX_QUEUES;
+ hw->queues = MWL8K_TX_WMM_QUEUES;
/* Set rssi values to dBm */
hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL;
@@ -4796,6 +5513,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
/* Finalize join worker */
INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
+ /* Handle watchdog ba events */
+ INIT_WORK(&priv->watchdog_ba_handle, mwl8k_watchdog_ba_events);
/* TX reclaim and RX tasklets. */
tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
@@ -4815,6 +5534,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
spin_lock_init(&priv->tx_lock);
+ spin_lock_init(&priv->stream_lock);
+
priv->tx_wait = NULL;
rc = mwl8k_probe_hw(hw);
@@ -4836,7 +5557,7 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
return 0;
err_unprobe_hw:
- for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ for (i = 0; i < mwl8k_tx_queues(priv); i++)
mwl8k_txq_deinit(hw, i);
mwl8k_rxq_deinit(hw, 0);
@@ -4995,10 +5716,10 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
mwl8k_hw_reset(priv);
/* Return all skbs to mac80211 */
- for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ for (i = 0; i < mwl8k_tx_queues(priv); i++)
mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
- for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ for (i = 0; i < mwl8k_tx_queues(priv); i++)
mwl8k_txq_deinit(hw, i);
mwl8k_rxq_deinit(hw, 0);
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index 13d750da930..54cc0bba66b 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -491,7 +491,7 @@ static int p54_parse_rssical(struct ieee80211_hw *dev,
struct pda_rssi_cal_entry *cal = (void *) &data[offset];
for (i = 0; i < entries; i++) {
- u16 freq;
+ u16 freq = 0;
switch (i) {
case IEEE80211_BAND_2GHZ:
freq = 2437;
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c
index 2fab7d20ffc..b6a061cbbde 100644
--- a/drivers/net/wireless/p54/fwio.c
+++ b/drivers/net/wireless/p54/fwio.c
@@ -727,3 +727,34 @@ int p54_fetch_statistics(struct p54_common *priv)
p54_tx(priv, skb);
return 0;
}
+
+int p54_set_groupfilter(struct p54_common *priv)
+{
+ struct p54_group_address_table *grp;
+ struct sk_buff *skb;
+ bool on = false;
+
+ skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*grp),
+ P54_CONTROL_TYPE_GROUP_ADDRESS_TABLE, GFP_KERNEL);
+ if (!skb)
+ return -ENOMEM;
+
+ grp = (struct p54_group_address_table *)skb_put(skb, sizeof(*grp));
+
+ on = !(priv->filter_flags & FIF_ALLMULTI) &&
+ (priv->mc_maclist_num > 0 &&
+ priv->mc_maclist_num <= MC_FILTER_ADDRESS_NUM);
+
+ if (on) {
+ grp->filter_enable = cpu_to_le16(1);
+ grp->num_address = cpu_to_le16(priv->mc_maclist_num);
+ memcpy(grp->mac_list, priv->mc_maclist, sizeof(grp->mac_list));
+ } else {
+ grp->filter_enable = cpu_to_le16(0);
+ grp->num_address = cpu_to_le16(0);
+ memset(grp->mac_list, 0, sizeof(grp->mac_list));
+ }
+
+ p54_tx(priv, skb);
+ return 0;
+}
diff --git a/drivers/net/wireless/p54/lmac.h b/drivers/net/wireless/p54/lmac.h
index eb581abc107..3d8d622bec5 100644
--- a/drivers/net/wireless/p54/lmac.h
+++ b/drivers/net/wireless/p54/lmac.h
@@ -540,6 +540,7 @@ int p54_update_beacon_tim(struct p54_common *priv, u16 aid, bool set);
int p54_setup_mac(struct p54_common *priv);
int p54_set_ps(struct p54_common *priv);
int p54_fetch_statistics(struct p54_common *priv);
+int p54_set_groupfilter(struct p54_common *priv);
/* e/v DCF setup */
int p54_set_edcf(struct p54_common *priv);
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index a946991989c..a5a6d9e647b 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -308,6 +308,31 @@ out:
return ret;
}
+static u64 p54_prepare_multicast(struct ieee80211_hw *dev,
+ struct netdev_hw_addr_list *mc_list)
+{
+ struct p54_common *priv = dev->priv;
+ struct netdev_hw_addr *ha;
+ int i;
+
+ BUILD_BUG_ON(ARRAY_SIZE(priv->mc_maclist) !=
+ ARRAY_SIZE(((struct p54_group_address_table *)NULL)->mac_list));
+ /*
+ * The first entry is reserved for the global broadcast MAC.
+ * Otherwise the firmware will drop it and ARP will no longer work.
+ */
+ i = 1;
+ priv->mc_maclist_num = netdev_hw_addr_list_count(mc_list) + i;
+ netdev_hw_addr_list_for_each(ha, mc_list) {
+ memcpy(&priv->mc_maclist[i], ha->addr, ETH_ALEN);
+ i++;
+ if (i >= ARRAY_SIZE(priv->mc_maclist))
+ break;
+ }
+
+ return 1; /* update */
+}
+
static void p54_configure_filter(struct ieee80211_hw *dev,
unsigned int changed_flags,
unsigned int *total_flags,
@@ -316,12 +341,16 @@ static void p54_configure_filter(struct ieee80211_hw *dev,
struct p54_common *priv = dev->priv;
*total_flags &= FIF_PROMISC_IN_BSS |
+ FIF_ALLMULTI |
FIF_OTHER_BSS;
priv->filter_flags = *total_flags;
if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS))
p54_setup_mac(priv);
+
+ if (changed_flags & FIF_ALLMULTI || multicast)
+ p54_set_groupfilter(priv);
}
static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue,
@@ -591,6 +620,7 @@ static const struct ieee80211_ops p54_ops = {
.config = p54_config,
.flush = p54_flush,
.bss_info_changed = p54_bss_info_changed,
+ .prepare_multicast = p54_prepare_multicast,
.configure_filter = p54_configure_filter,
.conf_tx = p54_conf_tx,
.get_stats = p54_get_stats,
@@ -660,6 +690,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
init_completion(&priv->beacon_comp);
INIT_DELAYED_WORK(&priv->work, p54_work);
+ memset(&priv->mc_maclist[0], ~0, ETH_ALEN);
return dev;
}
EXPORT_SYMBOL_GPL(p54_init_common);
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index 50730fc23fe..799d05e1259 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -211,8 +211,10 @@ struct p54_common {
/* BBP/MAC state */
u8 mac_addr[ETH_ALEN];
u8 bssid[ETH_ALEN];
+ u8 mc_maclist[4][ETH_ALEN];
u16 wakeup_timer;
unsigned int filter_flags;
+ int mc_maclist_num;
int mode;
u32 tsf_low32, tsf_high32;
u32 basic_rate_mask;
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index 0494d7b102d..1b753173680 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -331,10 +331,9 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
struct p54p_ring_control *ring_control = priv->ring_control;
struct p54p_desc *desc;
dma_addr_t mapping;
- u32 device_idx, idx, i;
+ u32 idx, i;
spin_lock_irqsave(&priv->lock, flags);
- 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);
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index f630552427b..9def1e5369a 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -59,7 +59,6 @@ config RT2800PCI
select RT2800_LIB
select RT2X00_LIB_PCI if PCI
select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X
- select RT2X00_LIB_HT
select RT2X00_LIB_FIRMWARE
select RT2X00_LIB_CRYPTO
select CRC_CCITT
@@ -74,17 +73,13 @@ config RT2800PCI
if RT2800PCI
config RT2800PCI_RT33XX
- bool "rt2800pci - Include support for rt33xx devices (EXPERIMENTAL)"
- depends on EXPERIMENTAL
- default n
+ bool "rt2800pci - Include support for rt33xx devices"
+ default y
---help---
This adds support for rt33xx wireless chipset family to the
rt2800pci driver.
Supported chips: RT3390
- Support for these devices is non-functional at the moment and is
- intended for testers and developers.
-
config RT2800PCI_RT35XX
bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)"
depends on EXPERIMENTAL
@@ -98,17 +93,14 @@ config RT2800PCI_RT35XX
intended for testers and developers.
config RT2800PCI_RT53XX
- bool "rt2800-pci - Include support for rt53xx devices (EXPERIMENTAL)"
+ bool "rt2800pci - Include support for rt53xx devices (EXPERIMENTAL)"
depends on EXPERIMENTAL
- default n
+ default y
---help---
This adds support for rt53xx wireless chipset family to the
rt2800pci driver.
Supported chips: RT5390
- Support for these devices is non-functional at the moment and is
- intended for testers and developers.
-
endif
config RT2500USB
@@ -140,7 +132,6 @@ config RT2800USB
depends on USB
select RT2800_LIB
select RT2X00_LIB_USB
- select RT2X00_LIB_HT
select RT2X00_LIB_FIRMWARE
select RT2X00_LIB_CRYPTO
select CRC_CCITT
@@ -153,17 +144,13 @@ config RT2800USB
if RT2800USB
config RT2800USB_RT33XX
- bool "rt2800usb - Include support for rt33xx devices (EXPERIMENTAL)"
- depends on EXPERIMENTAL
- default n
+ bool "rt2800usb - Include support for rt33xx devices"
+ default y
---help---
This adds support for rt33xx wireless chipset family to the
rt2800usb driver.
Supported chips: RT3370
- Support for these devices is non-functional at the moment and is
- intended for testers and developers.
-
config RT2800USB_RT35XX
bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)"
depends on EXPERIMENTAL
@@ -176,6 +163,15 @@ config RT2800USB_RT35XX
Support for these devices is non-functional at the moment and is
intended for testers and developers.
+config RT2800USB_RT53XX
+ bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ default y
+ ---help---
+ This adds support for rt53xx wireless chipset family to the
+ rt2800pci driver.
+ Supported chips: RT5370
+
config RT2800USB_UNKNOWN
bool "rt2800usb - Include support for unknown (USB) devices"
default n
@@ -207,9 +203,6 @@ config RT2X00_LIB_USB
config RT2X00_LIB
tristate
-config RT2X00_LIB_HT
- boolean
-
config RT2X00_LIB_FIRMWARE
boolean
select FW_LOADER
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile
index 97133985829..349d5b8284a 100644
--- a/drivers/net/wireless/rt2x00/Makefile
+++ b/drivers/net/wireless/rt2x00/Makefile
@@ -7,7 +7,6 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS) += rt2x00debug.o
rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o
rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o
rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o
-rt2x00lib-$(CONFIG_RT2X00_LIB_HT) += rt2x00ht.o
obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o
obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 329f3283697..937f9e8bf05 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1314,8 +1314,8 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev,
}
}
-static void rt2400pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
- struct rt2x00_field32 irq_field)
+static inline void rt2400pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_field32 irq_field)
{
u32 reg;
@@ -1368,8 +1368,10 @@ static void rt2400pci_tbtt_tasklet(unsigned long data)
static void rt2400pci_rxdone_tasklet(unsigned long data)
{
struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
- rt2x00pci_rxdone(rt2x00dev);
- rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
+ if (rt2x00pci_rxdone(rt2x00dev))
+ tasklet_schedule(&rt2x00dev->rxdone_tasklet);
+ else
+ rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
}
static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance)
@@ -1534,13 +1536,13 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
* Detect if this device has an hardware controlled radio.
*/
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
- __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
/*
* Check if the BBP tuning should be enabled.
*/
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_AGCVGC_TUNING))
- __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
return 0;
}
@@ -1638,9 +1640,9 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* This device requires the atim queue and DMA-mapped skbs.
*/
- __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags);
+ __set_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags);
/*
* Set the rssi offset.
@@ -1718,6 +1720,9 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
.tx_last_beacon = rt2400pci_tx_last_beacon,
.rfkill_poll = rt2x00mac_rfkill_poll,
.flush = rt2x00mac_flush,
+ .set_antenna = rt2x00mac_set_antenna,
+ .get_antenna = rt2x00mac_get_antenna,
+ .get_ringparam = rt2x00mac_get_ringparam,
};
static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
@@ -1738,6 +1743,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
.start_queue = rt2400pci_start_queue,
.kick_queue = rt2400pci_kick_queue,
.stop_queue = rt2400pci_stop_queue,
+ .flush_queue = rt2x00pci_flush_queue,
.write_tx_desc = rt2400pci_write_tx_desc,
.write_beacon = rt2400pci_write_beacon,
.fill_rxdone = rt2400pci_fill_rxdone,
@@ -1799,10 +1805,11 @@ static const struct rt2x00_ops rt2400pci_ops = {
* RT2400pci module information.
*/
static DEFINE_PCI_DEVICE_TABLE(rt2400pci_device_table) = {
- { PCI_DEVICE(0x1814, 0x0101), PCI_DEVICE_DATA(&rt2400pci_ops) },
+ { PCI_DEVICE(0x1814, 0x0101) },
{ 0, }
};
+
MODULE_AUTHOR(DRV_PROJECT);
MODULE_VERSION(DRV_VERSION);
MODULE_DESCRIPTION("Ralink RT2400 PCI & PCMCIA Wireless LAN driver.");
@@ -1810,10 +1817,16 @@ MODULE_SUPPORTED_DEVICE("Ralink RT2460 PCI & PCMCIA chipset based cards");
MODULE_DEVICE_TABLE(pci, rt2400pci_device_table);
MODULE_LICENSE("GPL");
+static int rt2400pci_probe(struct pci_dev *pci_dev,
+ const struct pci_device_id *id)
+{
+ return rt2x00pci_probe(pci_dev, &rt2400pci_ops);
+}
+
static struct pci_driver rt2400pci_driver = {
.name = KBUILD_MODNAME,
.id_table = rt2400pci_device_table,
- .probe = rt2x00pci_probe,
+ .probe = rt2400pci_probe,
.remove = __devexit_p(rt2x00pci_remove),
.suspend = rt2x00pci_suspend,
.resume = rt2x00pci_resume,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 58277878889..d27d7b8ba3b 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1446,8 +1446,8 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev,
}
}
-static void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
- struct rt2x00_field32 irq_field)
+static inline void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_field32 irq_field)
{
u32 reg;
@@ -1500,8 +1500,10 @@ static void rt2500pci_tbtt_tasklet(unsigned long data)
static void rt2500pci_rxdone_tasklet(unsigned long data)
{
struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
- rt2x00pci_rxdone(rt2x00dev);
- rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
+ if (rt2x00pci_rxdone(rt2x00dev))
+ tasklet_schedule(&rt2x00dev->rxdone_tasklet);
+ else
+ rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
}
static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance)
@@ -1685,14 +1687,14 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
* Detect if this device has an hardware controlled radio.
*/
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
- __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
/*
* Check if the BBP tuning should be enabled.
*/
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
if (!rt2x00_get_field16(eeprom, EEPROM_NIC_DYN_BBP_TUNE))
- __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
/*
* Read the RSSI <-> dBm offset information.
@@ -1956,9 +1958,9 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* This device requires the atim queue and DMA-mapped skbs.
*/
- __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags);
+ __set_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags);
/*
* Set the rssi offset.
@@ -2011,6 +2013,9 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
.tx_last_beacon = rt2500pci_tx_last_beacon,
.rfkill_poll = rt2x00mac_rfkill_poll,
.flush = rt2x00mac_flush,
+ .set_antenna = rt2x00mac_set_antenna,
+ .get_antenna = rt2x00mac_get_antenna,
+ .get_ringparam = rt2x00mac_get_ringparam,
};
static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
@@ -2031,6 +2036,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
.start_queue = rt2500pci_start_queue,
.kick_queue = rt2500pci_kick_queue,
.stop_queue = rt2500pci_stop_queue,
+ .flush_queue = rt2x00pci_flush_queue,
.write_tx_desc = rt2500pci_write_tx_desc,
.write_beacon = rt2500pci_write_beacon,
.fill_rxdone = rt2500pci_fill_rxdone,
@@ -2092,7 +2098,7 @@ static const struct rt2x00_ops rt2500pci_ops = {
* RT2500pci module information.
*/
static DEFINE_PCI_DEVICE_TABLE(rt2500pci_device_table) = {
- { PCI_DEVICE(0x1814, 0x0201), PCI_DEVICE_DATA(&rt2500pci_ops) },
+ { PCI_DEVICE(0x1814, 0x0201) },
{ 0, }
};
@@ -2103,10 +2109,16 @@ MODULE_SUPPORTED_DEVICE("Ralink RT2560 PCI & PCMCIA chipset based cards");
MODULE_DEVICE_TABLE(pci, rt2500pci_device_table);
MODULE_LICENSE("GPL");
+static int rt2500pci_probe(struct pci_dev *pci_dev,
+ const struct pci_device_id *id)
+{
+ return rt2x00pci_probe(pci_dev, &rt2500pci_ops);
+}
+
static struct pci_driver rt2500pci_driver = {
.name = KBUILD_MODNAME,
.id_table = rt2500pci_device_table,
- .probe = rt2x00pci_probe,
+ .probe = rt2500pci_probe,
.remove = __devexit_p(rt2x00pci_remove),
.suspend = rt2x00pci_suspend,
.resume = rt2x00pci_resume,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 979fe6596a2..15237c27548 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1519,7 +1519,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
* Detect if this device has an hardware controlled radio.
*/
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
- __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
/*
* Read the RSSI <-> dBm offset information.
@@ -1790,14 +1790,14 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* This device requires the atim queue
*/
- __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags);
+ __set_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags);
if (!modparam_nohwcrypt) {
- __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_COPY_IV, &rt2x00dev->cap_flags);
}
- __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags);
+ __set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags);
/*
* Set the rssi offset.
@@ -1824,6 +1824,9 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
.conf_tx = rt2x00mac_conf_tx,
.rfkill_poll = rt2x00mac_rfkill_poll,
.flush = rt2x00mac_flush,
+ .set_antenna = rt2x00mac_set_antenna,
+ .get_antenna = rt2x00mac_get_antenna,
+ .get_ringparam = rt2x00mac_get_ringparam,
};
static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
@@ -1905,58 +1908,54 @@ static const struct rt2x00_ops rt2500usb_ops = {
*/
static struct usb_device_id rt2500usb_device_table[] = {
/* ASUS */
- { USB_DEVICE(0x0b05, 0x1706), USB_DEVICE_DATA(&rt2500usb_ops) },
- { USB_DEVICE(0x0b05, 0x1707), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x0b05, 0x1706) },
+ { USB_DEVICE(0x0b05, 0x1707) },
/* Belkin */
- { USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt2500usb_ops) },
- { USB_DEVICE(0x050d, 0x7051), USB_DEVICE_DATA(&rt2500usb_ops) },
- { USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x050d, 0x7050) },
+ { USB_DEVICE(0x050d, 0x7051) },
/* Cisco Systems */
- { USB_DEVICE(0x13b1, 0x000d), USB_DEVICE_DATA(&rt2500usb_ops) },
- { USB_DEVICE(0x13b1, 0x0011), USB_DEVICE_DATA(&rt2500usb_ops) },
- { USB_DEVICE(0x13b1, 0x001a), USB_DEVICE_DATA(&rt2500usb_ops) },
- /* CNet */
- { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x13b1, 0x000d) },
+ { USB_DEVICE(0x13b1, 0x0011) },
+ { USB_DEVICE(0x13b1, 0x001a) },
/* Conceptronic */
- { USB_DEVICE(0x14b2, 0x3c02), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c02) },
/* D-LINK */
- { USB_DEVICE(0x2001, 0x3c00), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x2001, 0x3c00) },
/* Gigabyte */
- { USB_DEVICE(0x1044, 0x8001), USB_DEVICE_DATA(&rt2500usb_ops) },
- { USB_DEVICE(0x1044, 0x8007), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x1044, 0x8001) },
+ { USB_DEVICE(0x1044, 0x8007) },
/* Hercules */
- { USB_DEVICE(0x06f8, 0xe000), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x06f8, 0xe000) },
/* Melco */
- { USB_DEVICE(0x0411, 0x005e), USB_DEVICE_DATA(&rt2500usb_ops) },
- { USB_DEVICE(0x0411, 0x0066), USB_DEVICE_DATA(&rt2500usb_ops) },
- { USB_DEVICE(0x0411, 0x0067), USB_DEVICE_DATA(&rt2500usb_ops) },
- { USB_DEVICE(0x0411, 0x008b), USB_DEVICE_DATA(&rt2500usb_ops) },
- { USB_DEVICE(0x0411, 0x0097), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x0411, 0x005e) },
+ { USB_DEVICE(0x0411, 0x0066) },
+ { USB_DEVICE(0x0411, 0x0067) },
+ { USB_DEVICE(0x0411, 0x008b) },
+ { USB_DEVICE(0x0411, 0x0097) },
/* MSI */
- { USB_DEVICE(0x0db0, 0x6861), USB_DEVICE_DATA(&rt2500usb_ops) },
- { USB_DEVICE(0x0db0, 0x6865), USB_DEVICE_DATA(&rt2500usb_ops) },
- { USB_DEVICE(0x0db0, 0x6869), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x0db0, 0x6861) },
+ { USB_DEVICE(0x0db0, 0x6865) },
+ { USB_DEVICE(0x0db0, 0x6869) },
/* Ralink */
- { USB_DEVICE(0x148f, 0x1706), USB_DEVICE_DATA(&rt2500usb_ops) },
- { USB_DEVICE(0x148f, 0x2570), USB_DEVICE_DATA(&rt2500usb_ops) },
- { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt2500usb_ops) },
- { USB_DEVICE(0x148f, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x148f, 0x1706) },
+ { USB_DEVICE(0x148f, 0x2570) },
+ { USB_DEVICE(0x148f, 0x9020) },
/* Sagem */
- { USB_DEVICE(0x079b, 0x004b), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x079b, 0x004b) },
/* Siemens */
- { USB_DEVICE(0x0681, 0x3c06), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x0681, 0x3c06) },
/* SMC */
- { USB_DEVICE(0x0707, 0xee13), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x0707, 0xee13) },
/* Spairon */
- { USB_DEVICE(0x114b, 0x0110), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x114b, 0x0110) },
/* SURECOM */
- { USB_DEVICE(0x0769, 0x11f3), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x0769, 0x11f3) },
/* Trust */
- { USB_DEVICE(0x0eb0, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x0eb0, 0x9020) },
/* VTech */
- { USB_DEVICE(0x0f88, 0x3012), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x0f88, 0x3012) },
/* Zinwell */
- { USB_DEVICE(0x5a57, 0x0260), USB_DEVICE_DATA(&rt2500usb_ops) },
+ { USB_DEVICE(0x5a57, 0x0260) },
{ 0, }
};
@@ -1967,10 +1966,16 @@ MODULE_SUPPORTED_DEVICE("Ralink RT2570 USB chipset based cards");
MODULE_DEVICE_TABLE(usb, rt2500usb_device_table);
MODULE_LICENSE("GPL");
+static int rt2500usb_probe(struct usb_interface *usb_intf,
+ const struct usb_device_id *id)
+{
+ return rt2x00usb_probe(usb_intf, &rt2500usb_ops);
+}
+
static struct usb_driver rt2500usb_driver = {
.name = KBUILD_MODNAME,
.id_table = rt2500usb_device_table,
- .probe = rt2x00usb_probe,
+ .probe = rt2500usb_probe,
.disconnect = rt2x00usb_disconnect,
.suspend = rt2x00usb_suspend,
.resume = rt2x00usb_resume,
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 8fbc5fa965e..f67bc9b31b2 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -51,6 +51,7 @@
* RF3320 2.4G 1T1R(RT3350/RT3370/RT3390)
* RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
* RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
+ * RF5370 2.4G 1T1R
* RF5390 2.4G 1T1R
*/
#define RF2820 0x0001
@@ -66,6 +67,7 @@
#define RF3320 0x000b
#define RF3322 0x000c
#define RF3853 0x000d
+#define RF5370 0x5370
#define RF5390 0x5390
/*
@@ -2104,6 +2106,59 @@ struct mac_iveiv_entry {
#define EEPROM_TXPOWER_BG_2 FIELD16(0xff00)
/*
+ * EEPROM temperature compensation boundaries 802.11BG
+ * MINUS4: If the actual TSSI is below this boundary, tx power needs to be
+ * reduced by (agc_step * -4)
+ * MINUS3: If the actual TSSI is below this boundary, tx power needs to be
+ * reduced by (agc_step * -3)
+ */
+#define EEPROM_TSSI_BOUND_BG1 0x0037
+#define EEPROM_TSSI_BOUND_BG1_MINUS4 FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_BG1_MINUS3 FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11BG
+ * MINUS2: If the actual TSSI is below this boundary, tx power needs to be
+ * reduced by (agc_step * -2)
+ * MINUS1: If the actual TSSI is below this boundary, tx power needs to be
+ * reduced by (agc_step * -1)
+ */
+#define EEPROM_TSSI_BOUND_BG2 0x0038
+#define EEPROM_TSSI_BOUND_BG2_MINUS2 FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_BG2_MINUS1 FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11BG
+ * REF: Reference TSSI value, no tx power changes needed
+ * PLUS1: If the actual TSSI is above this boundary, tx power needs to be
+ * increased by (agc_step * 1)
+ */
+#define EEPROM_TSSI_BOUND_BG3 0x0039
+#define EEPROM_TSSI_BOUND_BG3_REF FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_BG3_PLUS1 FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11BG
+ * PLUS2: If the actual TSSI is above this boundary, tx power needs to be
+ * increased by (agc_step * 2)
+ * PLUS3: If the actual TSSI is above this boundary, tx power needs to be
+ * increased by (agc_step * 3)
+ */
+#define EEPROM_TSSI_BOUND_BG4 0x003a
+#define EEPROM_TSSI_BOUND_BG4_PLUS2 FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_BG4_PLUS3 FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11BG
+ * PLUS4: If the actual TSSI is above this boundary, tx power needs to be
+ * increased by (agc_step * 4)
+ * AGC_STEP: Temperature compensation step.
+ */
+#define EEPROM_TSSI_BOUND_BG5 0x003b
+#define EEPROM_TSSI_BOUND_BG5_PLUS4 FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_BG5_AGC_STEP FIELD16(0xff00)
+
+/*
* EEPROM TXPOWER 802.11A
*/
#define EEPROM_TXPOWER_A1 0x003c
@@ -2113,6 +2168,59 @@ struct mac_iveiv_entry {
#define EEPROM_TXPOWER_A_2 FIELD16(0xff00)
/*
+ * EEPROM temperature compensation boundaries 802.11A
+ * MINUS4: If the actual TSSI is below this boundary, tx power needs to be
+ * reduced by (agc_step * -4)
+ * MINUS3: If the actual TSSI is below this boundary, tx power needs to be
+ * reduced by (agc_step * -3)
+ */
+#define EEPROM_TSSI_BOUND_A1 0x006a
+#define EEPROM_TSSI_BOUND_A1_MINUS4 FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_A1_MINUS3 FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11A
+ * MINUS2: If the actual TSSI is below this boundary, tx power needs to be
+ * reduced by (agc_step * -2)
+ * MINUS1: If the actual TSSI is below this boundary, tx power needs to be
+ * reduced by (agc_step * -1)
+ */
+#define EEPROM_TSSI_BOUND_A2 0x006b
+#define EEPROM_TSSI_BOUND_A2_MINUS2 FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_A2_MINUS1 FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11A
+ * REF: Reference TSSI value, no tx power changes needed
+ * PLUS1: If the actual TSSI is above this boundary, tx power needs to be
+ * increased by (agc_step * 1)
+ */
+#define EEPROM_TSSI_BOUND_A3 0x006c
+#define EEPROM_TSSI_BOUND_A3_REF FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_A3_PLUS1 FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11A
+ * PLUS2: If the actual TSSI is above this boundary, tx power needs to be
+ * increased by (agc_step * 2)
+ * PLUS3: If the actual TSSI is above this boundary, tx power needs to be
+ * increased by (agc_step * 3)
+ */
+#define EEPROM_TSSI_BOUND_A4 0x006d
+#define EEPROM_TSSI_BOUND_A4_PLUS2 FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_A4_PLUS3 FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11A
+ * PLUS4: If the actual TSSI is above this boundary, tx power needs to be
+ * increased by (agc_step * 4)
+ * AGC_STEP: Temperature compensation step.
+ */
+#define EEPROM_TSSI_BOUND_A5 0x006e
+#define EEPROM_TSSI_BOUND_A5_PLUS4 FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_A5_AGC_STEP FIELD16(0xff00)
+
+/*
* EEPROM TXPOWER by rate: tx power per tx rate for HT20 mode
*/
#define EEPROM_TXPOWER_BYRATE 0x006f
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index dbf74d07d94..2a6aa85cc6c 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -687,6 +687,9 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
mcs = real_mcs;
}
+ if (aggr == 1 || ampdu == 1)
+ __set_bit(TXDONE_AMPDU, &txdesc.flags);
+
/*
* Ralink has a retry mechanism using a global fallback
* table. We setup this fallback table to try the immediate
@@ -727,34 +730,20 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
struct data_queue *queue;
struct queue_entry *entry;
u32 reg;
- u8 pid;
- int i;
+ u8 qid;
- /*
- * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO
- * at most X times and also stop processing once the TX_STA_FIFO_VALID
- * flag is not set anymore.
- *
- * The legacy drivers use X=TX_RING_SIZE but state in a comment
- * that the TX_STA_FIFO stack has a size of 16. We stick to our
- * tx ring size for now.
- */
- for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
- rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg);
- if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
- break;
+ while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
- /*
- * Skip this entry when it contains an invalid
- * queue identication number.
+ /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
+ * qid is guaranteed to be one of the TX QIDs
*/
- pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
- if (pid >= QID_RX)
- continue;
-
- queue = rt2x00queue_get_tx_queue(rt2x00dev, pid);
- if (unlikely(!queue))
+ qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
+ queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
+ if (unlikely(!queue)) {
+ WARNING(rt2x00dev, "Got TX status for an unavailable "
+ "queue %u, dropping\n", qid);
continue;
+ }
/*
* Inside each queue, we process each entry in a chronological
@@ -946,25 +935,49 @@ static void rt2800_brightness_set(struct led_classdev *led_cdev,
unsigned int ledmode =
rt2x00_get_field16(led->rt2x00dev->led_mcu_reg,
EEPROM_FREQ_LED_MODE);
+ u32 reg;
- if (led->type == LED_TYPE_RADIO) {
- rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
- enabled ? 0x20 : 0);
- } else if (led->type == LED_TYPE_ASSOC) {
- rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
- enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20);
- } else if (led->type == LED_TYPE_QUALITY) {
- /*
- * The brightness is divided into 6 levels (0 - 5),
- * The specs tell us the following levels:
- * 0, 1 ,3, 7, 15, 31
- * to determine the level in a simple way we can simply
- * work with bitshifting:
- * (1 << level) - 1
- */
- rt2800_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff,
- (1 << brightness / (LED_FULL / 6)) - 1,
- polarity);
+ /* Check for SoC (SOC devices don't support MCU requests) */
+ if (rt2x00_is_soc(led->rt2x00dev)) {
+ rt2800_register_read(led->rt2x00dev, LED_CFG, &reg);
+
+ /* Set LED Polarity */
+ rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, polarity);
+
+ /* Set LED Mode */
+ if (led->type == LED_TYPE_RADIO) {
+ rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE,
+ enabled ? 3 : 0);
+ } else if (led->type == LED_TYPE_ASSOC) {
+ rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE,
+ enabled ? 3 : 0);
+ } else if (led->type == LED_TYPE_QUALITY) {
+ rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE,
+ enabled ? 3 : 0);
+ }
+
+ rt2800_register_write(led->rt2x00dev, LED_CFG, reg);
+
+ } else {
+ if (led->type == LED_TYPE_RADIO) {
+ rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
+ enabled ? 0x20 : 0);
+ } else if (led->type == LED_TYPE_ASSOC) {
+ rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
+ enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20);
+ } else if (led->type == LED_TYPE_QUALITY) {
+ /*
+ * The brightness is divided into 6 levels (0 - 5),
+ * The specs tell us the following levels:
+ * 0, 1 ,3, 7, 15, 31
+ * to determine the level in a simple way we can simply
+ * work with bitshifting:
+ * (1 << level) - 1
+ */
+ rt2800_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff,
+ (1 << brightness / (LED_FULL / 6)) - 1,
+ polarity);
+ }
}
}
@@ -1218,6 +1231,25 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, conf->sync);
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+ if (conf->sync == TSF_SYNC_AP_NONE) {
+ /*
+ * Tune beacon queue transmit parameters for AP mode
+ */
+ rt2800_register_read(rt2x00dev, TBTT_SYNC_CFG, &reg);
+ rt2x00_set_field32(&reg, TBTT_SYNC_CFG_BCN_CWMIN, 0);
+ rt2x00_set_field32(&reg, TBTT_SYNC_CFG_BCN_AIFSN, 1);
+ rt2x00_set_field32(&reg, TBTT_SYNC_CFG_BCN_EXP_WIN, 32);
+ rt2x00_set_field32(&reg, TBTT_SYNC_CFG_TBTT_ADJUST, 0);
+ rt2800_register_write(rt2x00dev, TBTT_SYNC_CFG, reg);
+ } else {
+ rt2800_register_read(rt2x00dev, TBTT_SYNC_CFG, &reg);
+ rt2x00_set_field32(&reg, TBTT_SYNC_CFG_BCN_CWMIN, 4);
+ rt2x00_set_field32(&reg, TBTT_SYNC_CFG_BCN_AIFSN, 2);
+ rt2x00_set_field32(&reg, TBTT_SYNC_CFG_BCN_EXP_WIN, 32);
+ rt2x00_set_field32(&reg, TBTT_SYNC_CFG_TBTT_ADJUST, 16);
+ rt2800_register_write(rt2x00dev, TBTT_SYNC_CFG, reg);
+ }
}
if (flags & CONFIG_UPDATE_MAC) {
@@ -1608,7 +1640,6 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
struct channel_info *info)
{
u8 rfcsr;
- u16 eeprom;
rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3);
@@ -1638,11 +1669,10 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
if (rf->channel <= 14) {
int idx = rf->channel-1;
- if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) {
+ if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
/* r55/r59 value array of channel 1~14 */
static const char r55_bt_rev[] = {0x83, 0x83,
@@ -1721,7 +1751,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
rt2x00_rf(rt2x00dev, RF3052) ||
rt2x00_rf(rt2x00dev, RF3320))
rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
- else if (rt2x00_rf(rt2x00dev, RF5390))
+ else if (rt2x00_rf(rt2x00dev, RF5370) ||
+ rt2x00_rf(rt2x00dev, RF5390))
rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info);
else
rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
@@ -1736,8 +1767,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
if (rf->channel <= 14) {
if (!rt2x00_rt(rt2x00dev, RT5390)) {
- if (test_bit(CONFIG_EXTERNAL_LNA_BG,
- &rt2x00dev->flags)) {
+ if (test_bit(CAPABILITY_EXTERNAL_LNA_BG,
+ &rt2x00dev->cap_flags)) {
rt2800_bbp_write(rt2x00dev, 82, 0x62);
rt2800_bbp_write(rt2x00dev, 75, 0x46);
} else {
@@ -1748,7 +1779,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
} else {
rt2800_bbp_write(rt2x00dev, 82, 0xf2);
- if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
+ if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags))
rt2800_bbp_write(rt2x00dev, 75, 0x46);
else
rt2800_bbp_write(rt2x00dev, 75, 0x50);
@@ -1813,17 +1844,131 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &reg);
}
+static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev)
+{
+ u8 tssi_bounds[9];
+ u8 current_tssi;
+ u16 eeprom;
+ u8 step;
+ int i;
+
+ /*
+ * Read TSSI boundaries for temperature compensation from
+ * the EEPROM.
+ *
+ * Array idx 0 1 2 3 4 5 6 7 8
+ * Matching Delta value -4 -3 -2 -1 0 +1 +2 +3 +4
+ * Example TSSI bounds 0xF0 0xD0 0xB5 0xA0 0x88 0x45 0x25 0x15 0x00
+ */
+ if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG1, &eeprom);
+ tssi_bounds[0] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_BG1_MINUS4);
+ tssi_bounds[1] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_BG1_MINUS3);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG2, &eeprom);
+ tssi_bounds[2] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_BG2_MINUS2);
+ tssi_bounds[3] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_BG2_MINUS1);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG3, &eeprom);
+ tssi_bounds[4] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_BG3_REF);
+ tssi_bounds[5] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_BG3_PLUS1);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG4, &eeprom);
+ tssi_bounds[6] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_BG4_PLUS2);
+ tssi_bounds[7] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_BG4_PLUS3);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG5, &eeprom);
+ tssi_bounds[8] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_BG5_PLUS4);
+
+ step = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_BG5_AGC_STEP);
+ } else {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A1, &eeprom);
+ tssi_bounds[0] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_A1_MINUS4);
+ tssi_bounds[1] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_A1_MINUS3);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A2, &eeprom);
+ tssi_bounds[2] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_A2_MINUS2);
+ tssi_bounds[3] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_A2_MINUS1);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A3, &eeprom);
+ tssi_bounds[4] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_A3_REF);
+ tssi_bounds[5] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_A3_PLUS1);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A4, &eeprom);
+ tssi_bounds[6] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_A4_PLUS2);
+ tssi_bounds[7] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_A4_PLUS3);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A5, &eeprom);
+ tssi_bounds[8] = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_A5_PLUS4);
+
+ step = rt2x00_get_field16(eeprom,
+ EEPROM_TSSI_BOUND_A5_AGC_STEP);
+ }
+
+ /*
+ * Check if temperature compensation is supported.
+ */
+ if (tssi_bounds[4] == 0xff)
+ return 0;
+
+ /*
+ * Read current TSSI (BBP 49).
+ */
+ rt2800_bbp_read(rt2x00dev, 49, &current_tssi);
+
+ /*
+ * Compare TSSI value (BBP49) with the compensation boundaries
+ * from the EEPROM and increase or decrease tx power.
+ */
+ for (i = 0; i <= 3; i++) {
+ if (current_tssi > tssi_bounds[i])
+ break;
+ }
+
+ if (i == 4) {
+ for (i = 8; i >= 5; i--) {
+ if (current_tssi < tssi_bounds[i])
+ break;
+ }
+ }
+
+ return (i - 4) * step;
+}
+
static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev,
enum ieee80211_band band)
{
u16 eeprom;
u8 comp_en;
u8 comp_type;
- int comp_value;
+ int comp_value = 0;
rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom);
- if (eeprom == 0xffff)
+ /*
+ * HT40 compensation not required.
+ */
+ if (eeprom == 0xffff ||
+ !test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
return 0;
if (band == IEEE80211_BAND_2GHZ) {
@@ -1853,11 +1998,9 @@ static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev,
return comp_value;
}
-static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev,
- int is_rate_b,
- enum ieee80211_band band,
- int power_level,
- u8 txpower)
+static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
+ enum ieee80211_band band, int power_level,
+ u8 txpower, int delta)
{
u32 reg;
u16 eeprom;
@@ -1865,15 +2008,11 @@ static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev,
u8 eirp_txpower;
u8 eirp_txpower_criterion;
u8 reg_limit;
- int bw_comp = 0;
if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b))
return txpower;
- if (test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
- bw_comp = rt2800_get_txpower_bw_comp(rt2x00dev, band);
-
- if (test_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags)) {
+ if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) {
/*
* Check if eirp txpower exceed txpower_limit.
* We use OFDM 6M as criterion and its eirp txpower
@@ -1895,18 +2034,19 @@ static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev,
EEPROM_EIRP_MAX_TX_POWER_5GHZ);
eirp_txpower = eirp_txpower_criterion + (txpower - criterion) +
- (is_rate_b ? 4 : 0) + bw_comp;
+ (is_rate_b ? 4 : 0) + delta;
reg_limit = (eirp_txpower > power_level) ?
(eirp_txpower - power_level) : 0;
} else
reg_limit = 0;
- return txpower + bw_comp - reg_limit;
+ return txpower + delta - reg_limit;
}
static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_conf *conf)
+ enum ieee80211_band band,
+ int power_level)
{
u8 txpower;
u16 eeprom;
@@ -1914,8 +2054,17 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
u32 reg;
u8 r1;
u32 offset;
- enum ieee80211_band band = conf->channel->band;
- int power_level = conf->power_level;
+ int delta;
+
+ /*
+ * Calculate HT40 compensation delta
+ */
+ delta = rt2800_get_txpower_bw_comp(rt2x00dev, band);
+
+ /*
+ * calculate temperature compensation delta
+ */
+ delta += rt2800_get_gain_calibration_delta(rt2x00dev);
/*
* set to normal bbp tx power control mode: +/- 0dBm
@@ -1944,8 +2093,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE0);
- txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
- power_level, txpower);
+ txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+ power_level, txpower, delta);
rt2x00_set_field32(&reg, TX_PWR_CFG_RATE0, txpower);
/*
@@ -1955,8 +2104,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE1);
- txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
- power_level, txpower);
+ txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+ power_level, txpower, delta);
rt2x00_set_field32(&reg, TX_PWR_CFG_RATE1, txpower);
/*
@@ -1966,8 +2115,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE2);
- txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
- power_level, txpower);
+ txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+ power_level, txpower, delta);
rt2x00_set_field32(&reg, TX_PWR_CFG_RATE2, txpower);
/*
@@ -1977,8 +2126,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE3);
- txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
- power_level, txpower);
+ txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+ power_level, txpower, delta);
rt2x00_set_field32(&reg, TX_PWR_CFG_RATE3, txpower);
/* read the next four txpower values */
@@ -1993,8 +2142,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE0);
- txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
- power_level, txpower);
+ txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+ power_level, txpower, delta);
rt2x00_set_field32(&reg, TX_PWR_CFG_RATE4, txpower);
/*
@@ -2004,8 +2153,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE1);
- txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
- power_level, txpower);
+ txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+ power_level, txpower, delta);
rt2x00_set_field32(&reg, TX_PWR_CFG_RATE5, txpower);
/*
@@ -2015,8 +2164,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE2);
- txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
- power_level, txpower);
+ txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+ power_level, txpower, delta);
rt2x00_set_field32(&reg, TX_PWR_CFG_RATE6, txpower);
/*
@@ -2026,8 +2175,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE3);
- txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
- power_level, txpower);
+ txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+ power_level, txpower, delta);
rt2x00_set_field32(&reg, TX_PWR_CFG_RATE7, txpower);
rt2800_register_write(rt2x00dev, offset, reg);
@@ -2037,6 +2186,13 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
}
}
+void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev)
+{
+ rt2800_config_txpower(rt2x00dev, rt2x00dev->curr_band,
+ rt2x00dev->tx_power);
+}
+EXPORT_SYMBOL_GPL(rt2800_gain_calibration);
+
static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf)
{
@@ -2090,10 +2246,12 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev,
if (flags & IEEE80211_CONF_CHANGE_CHANNEL) {
rt2800_config_channel(rt2x00dev, libconf->conf,
&libconf->rf, &libconf->channel);
- rt2800_config_txpower(rt2x00dev, libconf->conf);
+ rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band,
+ libconf->conf->power_level);
}
if (flags & IEEE80211_CONF_CHANGE_POWER)
- rt2800_config_txpower(rt2x00dev, libconf->conf);
+ rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band,
+ libconf->conf->power_level);
if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
rt2800_config_retry_limit(rt2x00dev, libconf);
if (flags & IEEE80211_CONF_CHANGE_PS)
@@ -2254,7 +2412,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
} else if (rt2800_is_305x_soc(rt2x00dev)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
- rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000001f);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000030);
} else if (rt2x00_rt(rt2x00dev, RT5390)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
@@ -2758,8 +2916,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
ant = (div_mode == 3) ? 1 : 0;
/* check if this is a Bluetooth combo card */
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
- if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) {
+ if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
u32 reg;
rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
@@ -3155,8 +3312,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
- if (!test_bit(CONFIG_EXTERNAL_LNA_BG,
- &rt2x00dev->flags))
+ if (!test_bit(CAPABILITY_EXTERNAL_LNA_BG,
+ &rt2x00dev->cap_flags))
rt2x00_set_field8(&rfcsr, RFCSR17_R, 1);
}
rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom);
@@ -3530,6 +3687,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
!rt2x00_rf(rt2x00dev, RF3022) &&
!rt2x00_rf(rt2x00dev, RF3052) &&
!rt2x00_rf(rt2x00dev, RF3320) &&
+ !rt2x00_rf(rt2x00dev, RF5370) &&
!rt2x00_rf(rt2x00dev, RF5390)) {
ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
return -ENODEV;
@@ -3568,26 +3726,30 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
}
/*
- * Read frequency offset and RF programming sequence.
+ * Determine external LNA informations.
*/
- rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
- rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
-
- /*
- * Read external LNA informations.
- */
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
-
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G))
- __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G))
- __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags);
/*
* Detect if this device has an hardware controlled radio.
*/
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_HW_RADIO))
- __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
+
+ /*
+ * Detect if this device has Bluetooth co-existence.
+ */
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST))
+ __set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags);
+
+ /*
+ * Read frequency offset and RF programming sequence.
+ */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
+ rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
/*
* Store led settings, for correct led behaviour.
@@ -3597,7 +3759,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &rt2x00dev->led_mcu_reg);
+ rt2x00dev->led_mcu_reg = eeprom;
#endif /* CONFIG_RT2X00_LIB_LEDS */
/*
@@ -3607,7 +3769,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
if (rt2x00_get_field16(eeprom, EEPROM_EIRP_MAX_TX_POWER_2GHZ) <
EIRP_MAX_TX_POWER_LIMIT)
- __set_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags);
return 0;
}
@@ -3828,6 +3990,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
rt2x00_rf(rt2x00dev, RF3021) ||
rt2x00_rf(rt2x00dev, RF3022) ||
rt2x00_rf(rt2x00dev, RF3320) ||
+ rt2x00_rf(rt2x00dev, RF5370) ||
rt2x00_rf(rt2x00dev, RF5390)) {
spec->num_channels = 14;
spec->channels = rf_vals_3x;
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 0c92d86a36f..f2d15941c71 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -181,6 +181,7 @@ void rt2800_link_stats(struct rt2x00_dev *rt2x00dev, struct link_qual *qual);
void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual);
void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
const u32 count);
+void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev);
int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev);
void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 808073aa9dc..cc4a54f571b 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -66,7 +66,7 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
return;
for (i = 0; i < 200; i++) {
- rt2800_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg);
+ rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg);
if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) ||
(rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) ||
@@ -80,8 +80,8 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
if (i == 200)
ERROR(rt2x00dev, "MCU request failed, no response from hardware\n");
- rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
- rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+ rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+ rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
}
#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
@@ -105,7 +105,7 @@ static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
struct rt2x00_dev *rt2x00dev = eeprom->data;
u32 reg;
- rt2800_register_read(rt2x00dev, E2PROM_CSR, &reg);
+ rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, &reg);
eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN);
eeprom->reg_data_out = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_OUT);
@@ -127,7 +127,7 @@ static void rt2800pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
rt2x00_set_field32(&reg, E2PROM_CSR_CHIP_SELECT,
!!eeprom->reg_chip_select);
- rt2800_register_write(rt2x00dev, E2PROM_CSR, reg);
+ rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg);
}
static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev)
@@ -135,7 +135,7 @@ static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev)
struct eeprom_93cx6 eeprom;
u32 reg;
- rt2800_register_read(rt2x00dev, E2PROM_CSR, &reg);
+ rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, &reg);
eeprom.data = rt2x00dev;
eeprom.register_read = rt2800pci_eepromregister_read;
@@ -195,9 +195,9 @@ static void rt2800pci_start_queue(struct data_queue *queue)
switch (queue->qid) {
case QID_RX:
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+ rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
break;
case QID_BEACON:
/*
@@ -207,15 +207,15 @@ static void rt2800pci_start_queue(struct data_queue *queue)
tasklet_enable(&rt2x00dev->tbtt_tasklet);
tasklet_enable(&rt2x00dev->pretbtt_tasklet);
- rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg);
- rt2800_register_read(rt2x00dev, INT_TIMER_EN, &reg);
+ rt2x00pci_register_read(rt2x00dev, INT_TIMER_EN, &reg);
rt2x00_set_field32(&reg, INT_TIMER_EN_PRE_TBTT_TIMER, 1);
- rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg);
+ rt2x00pci_register_write(rt2x00dev, INT_TIMER_EN, reg);
break;
default:
break;
@@ -233,11 +233,13 @@ static void rt2800pci_kick_queue(struct data_queue *queue)
case QID_AC_BE:
case QID_AC_BK:
entry = rt2x00queue_get_entry(queue, Q_INDEX);
- rt2800_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), entry->entry_idx);
+ rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX(queue->qid),
+ entry->entry_idx);
break;
case QID_MGMT:
entry = rt2x00queue_get_entry(queue, Q_INDEX);
- rt2800_register_write(rt2x00dev, TX_CTX_IDX(5), entry->entry_idx);
+ rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX(5),
+ entry->entry_idx);
break;
default:
break;
@@ -251,20 +253,20 @@ static void rt2800pci_stop_queue(struct data_queue *queue)
switch (queue->qid) {
case QID_RX:
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+ rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
break;
case QID_BEACON:
- rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg);
- rt2800_register_read(rt2x00dev, INT_TIMER_EN, &reg);
+ rt2x00pci_register_read(rt2x00dev, INT_TIMER_EN, &reg);
rt2x00_set_field32(&reg, INT_TIMER_EN_PRE_TBTT_TIMER, 0);
- rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg);
+ rt2x00pci_register_write(rt2x00dev, INT_TIMER_EN, reg);
/*
* Wait for tbtt tasklets to finish.
@@ -295,19 +297,19 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev,
*/
reg = 0;
rt2x00_set_field32(&reg, PBF_SYS_CTRL_HOST_RAM_WRITE, 1);
- rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
+ rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
/*
* Write firmware to device.
*/
- rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
- data, len);
+ rt2x00pci_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
+ data, len);
- rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000);
- rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001);
+ rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000);
+ rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001);
- rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
- rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+ rt2x00pci_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+ rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
return 0;
}
@@ -351,7 +353,7 @@ static void rt2800pci_clear_entry(struct queue_entry *entry)
* Set RX IDX in register to inform hardware that we have
* handled this entry and it is available for reuse again.
*/
- rt2800_register_write(rt2x00dev, RX_CRX_IDX,
+ rt2x00pci_register_write(rt2x00dev, RX_CRX_IDX,
entry->entry_idx);
} else {
rt2x00_desc_read(entry_priv->desc, 1, &word);
@@ -369,45 +371,51 @@ static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev)
* Initialize registers.
*/
entry_priv = rt2x00dev->tx[0].entries[0].priv_data;
- rt2800_register_write(rt2x00dev, TX_BASE_PTR0, entry_priv->desc_dma);
- rt2800_register_write(rt2x00dev, TX_MAX_CNT0, rt2x00dev->tx[0].limit);
- rt2800_register_write(rt2x00dev, TX_CTX_IDX0, 0);
- rt2800_register_write(rt2x00dev, TX_DTX_IDX0, 0);
+ rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR0, entry_priv->desc_dma);
+ rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT0,
+ rt2x00dev->tx[0].limit);
+ rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX0, 0);
+ rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX0, 0);
entry_priv = rt2x00dev->tx[1].entries[0].priv_data;
- rt2800_register_write(rt2x00dev, TX_BASE_PTR1, entry_priv->desc_dma);
- rt2800_register_write(rt2x00dev, TX_MAX_CNT1, rt2x00dev->tx[1].limit);
- rt2800_register_write(rt2x00dev, TX_CTX_IDX1, 0);
- rt2800_register_write(rt2x00dev, TX_DTX_IDX1, 0);
+ rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR1, entry_priv->desc_dma);
+ rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT1,
+ rt2x00dev->tx[1].limit);
+ rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX1, 0);
+ rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX1, 0);
entry_priv = rt2x00dev->tx[2].entries[0].priv_data;
- rt2800_register_write(rt2x00dev, TX_BASE_PTR2, entry_priv->desc_dma);
- rt2800_register_write(rt2x00dev, TX_MAX_CNT2, rt2x00dev->tx[2].limit);
- rt2800_register_write(rt2x00dev, TX_CTX_IDX2, 0);
- rt2800_register_write(rt2x00dev, TX_DTX_IDX2, 0);
+ rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR2, entry_priv->desc_dma);
+ rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT2,
+ rt2x00dev->tx[2].limit);
+ rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX2, 0);
+ rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX2, 0);
entry_priv = rt2x00dev->tx[3].entries[0].priv_data;
- rt2800_register_write(rt2x00dev, TX_BASE_PTR3, entry_priv->desc_dma);
- rt2800_register_write(rt2x00dev, TX_MAX_CNT3, rt2x00dev->tx[3].limit);
- rt2800_register_write(rt2x00dev, TX_CTX_IDX3, 0);
- rt2800_register_write(rt2x00dev, TX_DTX_IDX3, 0);
+ rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR3, entry_priv->desc_dma);
+ rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT3,
+ rt2x00dev->tx[3].limit);
+ rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX3, 0);
+ rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX3, 0);
entry_priv = rt2x00dev->rx->entries[0].priv_data;
- rt2800_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma);
- rt2800_register_write(rt2x00dev, RX_MAX_CNT, rt2x00dev->rx[0].limit);
- rt2800_register_write(rt2x00dev, RX_CRX_IDX, rt2x00dev->rx[0].limit - 1);
- rt2800_register_write(rt2x00dev, RX_DRX_IDX, 0);
+ rt2x00pci_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma);
+ rt2x00pci_register_write(rt2x00dev, RX_MAX_CNT,
+ rt2x00dev->rx[0].limit);
+ rt2x00pci_register_write(rt2x00dev, RX_CRX_IDX,
+ rt2x00dev->rx[0].limit - 1);
+ rt2x00pci_register_write(rt2x00dev, RX_DRX_IDX, 0);
/*
* Enable global DMA configuration
*/
- rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+ rt2x00pci_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
- rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+ rt2x00pci_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
- rt2800_register_write(rt2x00dev, DELAY_INT_CFG, 0);
+ rt2x00pci_register_write(rt2x00dev, DELAY_INT_CFG, 0);
return 0;
}
@@ -427,8 +435,8 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
* should clear the register to assure a clean state.
*/
if (state == STATE_RADIO_IRQ_ON) {
- rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
- rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
+ rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
+ rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
/*
* Enable tasklets. The beacon related tasklets are
@@ -440,7 +448,7 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
}
spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags);
- rt2800_register_read(rt2x00dev, INT_MASK_CSR, &reg);
+ rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, &reg);
rt2x00_set_field32(&reg, INT_MASK_CSR_RXDELAYINT, 0);
rt2x00_set_field32(&reg, INT_MASK_CSR_TXDELAYINT, 0);
rt2x00_set_field32(&reg, INT_MASK_CSR_RX_DONE, mask);
@@ -459,7 +467,7 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, INT_MASK_CSR_GPTIMER, 0);
rt2x00_set_field32(&reg, INT_MASK_CSR_RX_COHERENT, 0);
rt2x00_set_field32(&reg, INT_MASK_CSR_TX_COHERENT, 0);
- rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
+ rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg);
spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags);
if (state == STATE_RADIO_IRQ_OFF) {
@@ -480,7 +488,7 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
/*
* Reset DMA indexes
*/
- rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
+ rt2x00pci_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
@@ -488,26 +496,26 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
- rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
+ rt2x00pci_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
- rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
- rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
+ rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
+ rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
if (rt2x00_rt(rt2x00dev, RT5390)) {
- rt2800_register_read(rt2x00dev, AUX_CTRL, &reg);
+ rt2x00pci_register_read(rt2x00dev, AUX_CTRL, &reg);
rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);
- rt2800_register_write(rt2x00dev, AUX_CTRL, reg);
+ rt2x00pci_register_write(rt2x00dev, AUX_CTRL, reg);
}
- rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
+ rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+ rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+ rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
return 0;
}
@@ -525,8 +533,8 @@ static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev)
{
if (rt2x00_is_soc(rt2x00dev)) {
rt2800_disable_radio(rt2x00dev);
- rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0);
- rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0);
+ rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0);
+ rt2x00pci_register_write(rt2x00dev, TX_PIN_CFG, 0);
}
}
@@ -537,8 +545,10 @@ static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0x02);
rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKUP);
} else if (state == STATE_SLEEP) {
- rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, 0xffffffff);
- rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, 0xffffffff);
+ rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS,
+ 0xffffffff);
+ rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID,
+ 0xffffffff);
rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0x01, 0xff, 0x01);
}
@@ -717,12 +727,13 @@ static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev)
rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
}
-static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
+static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue;
struct queue_entry *entry;
u32 status;
u8 qid;
+ int max_tx_done = 16;
while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) {
qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE);
@@ -759,11 +770,16 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
rt2800_txdone_entry(entry, status);
+
+ if (--max_tx_done == 0)
+ break;
}
+
+ return !max_tx_done;
}
-static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
- struct rt2x00_field32 irq_field)
+static inline void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_field32 irq_field)
{
u32 reg;
@@ -772,15 +788,17 @@ static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
* access needs locking.
*/
spin_lock_irq(&rt2x00dev->irqmask_lock);
- rt2800_register_read(rt2x00dev, INT_MASK_CSR, &reg);
+ rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, &reg);
rt2x00_set_field32(&reg, irq_field, 1);
- rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
+ rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg);
spin_unlock_irq(&rt2x00dev->irqmask_lock);
}
static void rt2800pci_txstatus_tasklet(unsigned long data)
{
- rt2800pci_txdone((struct rt2x00_dev *)data);
+ struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
+ if (rt2800pci_txdone(rt2x00dev))
+ tasklet_schedule(&rt2x00dev->txstatus_tasklet);
/*
* No need to enable the tx status interrupt here as we always
@@ -806,8 +824,10 @@ static void rt2800pci_tbtt_tasklet(unsigned long data)
static void rt2800pci_rxdone_tasklet(unsigned long data)
{
struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
- rt2x00pci_rxdone(rt2x00dev);
- rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE);
+ if (rt2x00pci_rxdone(rt2x00dev))
+ tasklet_schedule(&rt2x00dev->rxdone_tasklet);
+ else
+ rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE);
}
static void rt2800pci_autowake_tasklet(unsigned long data)
@@ -841,7 +861,7 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
* need to lock the kfifo.
*/
for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
- rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status);
+ rt2x00pci_register_read(rt2x00dev, TX_STA_FIFO, &status);
if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
break;
@@ -863,8 +883,8 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
u32 reg, mask;
/* Read status and ACK all interrupts */
- rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
- rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
+ rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
+ rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
if (!reg)
return IRQ_NONE;
@@ -904,9 +924,9 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
* the tasklet will reenable the appropriate interrupts.
*/
spin_lock(&rt2x00dev->irqmask_lock);
- rt2800_register_read(rt2x00dev, INT_MASK_CSR, &reg);
+ rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, &reg);
reg &= mask;
- rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
+ rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg);
spin_unlock(&rt2x00dev->irqmask_lock);
return IRQ_HANDLED;
@@ -956,28 +976,28 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
* This device has multiple filters for control frames
* and has a separate filter for PS Poll frames.
*/
- __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
- __set_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);
+ __set_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags);
/*
* This device has a pre tbtt interrupt and thus fetches
* a new beacon directly prior to transmission.
*/
- __set_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_PRE_TBTT_INTERRUPT, &rt2x00dev->cap_flags);
/*
* This device requires firmware.
*/
if (!rt2x00_is_soc(rt2x00dev))
- __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags);
+ __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags);
if (!modparam_nohwcrypt)
- __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
- __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
+ __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags);
/*
* Set the rssi offset.
@@ -1008,6 +1028,7 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = {
.ampdu_action = rt2800_ampdu_action,
.flush = rt2x00mac_flush,
.get_survey = rt2800_get_survey,
+ .get_ringparam = rt2x00mac_get_ringparam,
};
static const struct rt2800_ops rt2800pci_rt2800_ops = {
@@ -1043,9 +1064,11 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
.link_stats = rt2800_link_stats,
.reset_tuner = rt2800_reset_tuner,
.link_tuner = rt2800_link_tuner,
+ .gain_calibration = rt2800_gain_calibration,
.start_queue = rt2800pci_start_queue,
.kick_queue = rt2800pci_kick_queue,
.stop_queue = rt2800pci_stop_queue,
+ .flush_queue = rt2x00pci_flush_queue,
.write_tx_desc = rt2800pci_write_tx_desc,
.write_tx_data = rt2800_write_tx_data,
.write_beacon = rt2800_write_beacon,
@@ -1105,36 +1128,36 @@ static const struct rt2x00_ops rt2800pci_ops = {
*/
#ifdef CONFIG_PCI
static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
- { PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1814, 0x0701), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1814, 0x0781), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1432, 0x7708), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1432, 0x7727), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1432, 0x7728), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1432, 0x7738), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1432, 0x7748), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1432, 0x7758), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1432, 0x7768), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1462, 0x891a), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) },
+ { PCI_DEVICE(0x1814, 0x0601) },
+ { PCI_DEVICE(0x1814, 0x0681) },
+ { PCI_DEVICE(0x1814, 0x0701) },
+ { PCI_DEVICE(0x1814, 0x0781) },
+ { PCI_DEVICE(0x1814, 0x3090) },
+ { PCI_DEVICE(0x1814, 0x3091) },
+ { PCI_DEVICE(0x1814, 0x3092) },
+ { PCI_DEVICE(0x1432, 0x7708) },
+ { PCI_DEVICE(0x1432, 0x7727) },
+ { PCI_DEVICE(0x1432, 0x7728) },
+ { PCI_DEVICE(0x1432, 0x7738) },
+ { PCI_DEVICE(0x1432, 0x7748) },
+ { PCI_DEVICE(0x1432, 0x7758) },
+ { PCI_DEVICE(0x1432, 0x7768) },
+ { PCI_DEVICE(0x1462, 0x891a) },
+ { PCI_DEVICE(0x1a3b, 0x1059) },
#ifdef CONFIG_RT2800PCI_RT33XX
- { PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) },
+ { PCI_DEVICE(0x1814, 0x3390) },
#endif
#ifdef CONFIG_RT2800PCI_RT35XX
- { PCI_DEVICE(0x1432, 0x7711), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1432, 0x7722), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1814, 0x3593), PCI_DEVICE_DATA(&rt2800pci_ops) },
+ { PCI_DEVICE(0x1432, 0x7711) },
+ { PCI_DEVICE(0x1432, 0x7722) },
+ { PCI_DEVICE(0x1814, 0x3060) },
+ { PCI_DEVICE(0x1814, 0x3062) },
+ { PCI_DEVICE(0x1814, 0x3562) },
+ { PCI_DEVICE(0x1814, 0x3592) },
+ { PCI_DEVICE(0x1814, 0x3593) },
#endif
#ifdef CONFIG_RT2800PCI_RT53XX
- { PCI_DEVICE(0x1814, 0x5390), PCI_DEVICE_DATA(&rt2800pci_ops) },
+ { PCI_DEVICE(0x1814, 0x5390) },
#endif
{ 0, }
};
@@ -1170,10 +1193,16 @@ static struct platform_driver rt2800soc_driver = {
#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
#ifdef CONFIG_PCI
+static int rt2800pci_probe(struct pci_dev *pci_dev,
+ const struct pci_device_id *id)
+{
+ return rt2x00pci_probe(pci_dev, &rt2800pci_ops);
+}
+
static struct pci_driver rt2800pci_driver = {
.name = KBUILD_MODNAME,
.id_table = rt2800pci_device_table,
- .probe = rt2x00pci_probe,
+ .probe = rt2800pci_probe,
.remove = __devexit_p(rt2x00pci_remove),
.suspend = rt2x00pci_suspend,
.resume = rt2x00pci_resume,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 37509d01991..ba82c972703 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -59,16 +59,16 @@ static void rt2800usb_start_queue(struct data_queue *queue)
switch (queue->qid) {
case QID_RX:
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
break;
case QID_BEACON:
- rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
break;
default:
break;
@@ -82,16 +82,16 @@ static void rt2800usb_stop_queue(struct data_queue *queue)
switch (queue->qid) {
case QID_RX:
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
break;
case QID_BEACON:
- rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
break;
default:
break;
@@ -99,6 +99,63 @@ static void rt2800usb_stop_queue(struct data_queue *queue)
}
/*
+ * test if there is an entry in any TX queue for which DMA is done
+ * but the TX status has not been returned yet
+ */
+static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue;
+
+ tx_queue_for_each(rt2x00dev, queue) {
+ if (rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE) !=
+ rt2x00queue_get_entry(queue, Q_INDEX_DONE))
+ return true;
+ }
+ return false;
+}
+
+static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
+ int urb_status, u32 tx_status)
+{
+ if (urb_status) {
+ WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status);
+ return false;
+ }
+
+ /* try to read all TX_STA_FIFO entries before scheduling txdone_work */
+ if (rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID)) {
+ if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) {
+ WARNING(rt2x00dev, "TX status FIFO overrun, "
+ "drop tx status report.\n");
+ queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
+ } else
+ return true;
+ } else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) {
+ queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
+ } else if (rt2800usb_txstatus_pending(rt2x00dev)) {
+ mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2));
+ }
+
+ return false;
+}
+
+static void rt2800usb_tx_dma_done(struct queue_entry *entry)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+
+ rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO,
+ rt2800usb_tx_sta_fifo_read_completed);
+}
+
+static void rt2800usb_tx_sta_fifo_timeout(unsigned long data)
+{
+ struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
+
+ rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO,
+ rt2800usb_tx_sta_fifo_read_completed);
+}
+
+/*
* Firmware functions
*/
static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
@@ -129,11 +186,11 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
/*
* Write firmware to device.
*/
- rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
- data + offset, length);
+ rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
+ data + offset, length);
- rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
- rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
/*
* Send firmware request to device to load firmware,
@@ -148,7 +205,7 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
}
msleep(10);
- rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
return 0;
}
@@ -166,22 +223,22 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
if (rt2800_wait_csr_ready(rt2x00dev))
return -EBUSY;
- rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
- rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
+ rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+ rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
- rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
+ rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
- rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
+ rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
USB_MODE_RESET, REGISTER_TIMEOUT);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
return 0;
}
@@ -193,7 +250,7 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev)))
return -EIO;
- rt2800_register_read(rt2x00dev, USB_DMA_CFG, &reg);
+ rt2x00usb_register_read(rt2x00dev, USB_DMA_CFG, &reg);
rt2x00_set_field32(&reg, USB_DMA_CFG_PHY_CLEAR, 0);
rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN, 0);
rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128);
@@ -206,7 +263,7 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
/ 1024) - 3);
rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1);
rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
- rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg);
+ rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, reg);
return rt2800_enable_radio(rt2x00dev);
}
@@ -282,12 +339,12 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev)
unsigned int i;
u32 reg;
- rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
+ rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) {
WARNING(rt2x00dev, "TX HW queue 0 timed out,"
" invoke forced kick\n");
- rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40012);
+ rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40012);
for (i = 0; i < 10; i++) {
udelay(10);
@@ -295,15 +352,15 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev)
break;
}
- rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
+ rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006);
}
- rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
+ rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) {
WARNING(rt2x00dev, "TX HW queue 1 timed out,"
" invoke forced kick\n");
- rt2800_register_write(rt2x00dev, PBF_CFG, 0xf4000a);
+ rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf4000a);
for (i = 0; i < 10; i++) {
udelay(10);
@@ -311,7 +368,7 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev)
break;
}
- rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
+ rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006);
}
rt2x00usb_watchdog(rt2x00dev);
@@ -420,13 +477,24 @@ static void rt2800usb_work_txdone(struct work_struct *work)
while (!rt2x00queue_empty(queue)) {
entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
- if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
- !test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
+ if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ break;
+ if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
+ rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
+ else if (rt2x00queue_status_timeout(entry))
+ rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
+ else
break;
-
- rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
}
}
+
+ /*
+ * The hw may delay sending the packet after DMA complete
+ * if the medium is busy, thus the TX_STA_FIFO entry is
+ * also delayed -> use a timer to retrieve it.
+ */
+ if (rt2800usb_txstatus_pending(rt2x00dev))
+ mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2));
}
/*
@@ -553,19 +621,24 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
* This device has multiple filters for control frames
* and has a separate filter for PS Poll frames.
*/
- __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
- __set_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);
+ __set_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags);
/*
* This device requires firmware.
*/
- __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
+ __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags);
if (!modparam_nohwcrypt)
- __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
- __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
- __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
+ __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags);
+
+ setup_timer(&rt2x00dev->txstatus_timer,
+ rt2800usb_tx_sta_fifo_timeout,
+ (unsigned long) rt2x00dev);
/*
* Set the rssi offset.
@@ -602,6 +675,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = {
.ampdu_action = rt2800_ampdu_action,
.flush = rt2x00mac_flush,
.get_survey = rt2800_get_survey,
+ .get_ringparam = rt2x00mac_get_ringparam,
};
static const struct rt2800_ops rt2800usb_rt2800_ops = {
@@ -630,11 +704,13 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
.link_stats = rt2800_link_stats,
.reset_tuner = rt2800_reset_tuner,
.link_tuner = rt2800_link_tuner,
+ .gain_calibration = rt2800_gain_calibration,
.watchdog = rt2800usb_watchdog,
.start_queue = rt2800usb_start_queue,
.kick_queue = rt2x00usb_kick_queue,
.stop_queue = rt2800usb_stop_queue,
.flush_queue = rt2x00usb_flush_queue,
+ .tx_dma_done = rt2800usb_tx_dma_done,
.write_tx_desc = rt2800usb_write_tx_desc,
.write_tx_data = rt2800usb_write_tx_data,
.write_beacon = rt2800_write_beacon,
@@ -695,294 +771,340 @@ static const struct rt2x00_ops rt2800usb_ops = {
*/
static struct usb_device_id rt2800usb_device_table[] = {
/* Abocom */
- { USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07b8, 0x2870) },
+ { USB_DEVICE(0x07b8, 0x2770) },
+ { USB_DEVICE(0x07b8, 0x3070) },
+ { USB_DEVICE(0x07b8, 0x3071) },
+ { USB_DEVICE(0x07b8, 0x3072) },
+ { USB_DEVICE(0x1482, 0x3c09) },
/* AirTies */
- { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1eda, 0x2012) },
+ { USB_DEVICE(0x1eda, 0x2310) },
/* Allwin */
- { USB_DEVICE(0x8516, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x8516, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x8516, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x8516, 0x2070) },
+ { USB_DEVICE(0x8516, 0x2770) },
+ { USB_DEVICE(0x8516, 0x2870) },
+ { USB_DEVICE(0x8516, 0x3070) },
+ { USB_DEVICE(0x8516, 0x3071) },
+ { USB_DEVICE(0x8516, 0x3072) },
+ /* Alpha Networks */
+ { USB_DEVICE(0x14b2, 0x3c06) },
+ { USB_DEVICE(0x14b2, 0x3c07) },
+ { USB_DEVICE(0x14b2, 0x3c09) },
+ { USB_DEVICE(0x14b2, 0x3c12) },
+ { USB_DEVICE(0x14b2, 0x3c23) },
+ { USB_DEVICE(0x14b2, 0x3c25) },
+ { USB_DEVICE(0x14b2, 0x3c27) },
+ { USB_DEVICE(0x14b2, 0x3c28) },
+ { USB_DEVICE(0x14b2, 0x3c2c) },
/* Amit */
- { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x15c5, 0x0008) },
/* Askey */
- { USB_DEVICE(0x1690, 0x0740), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1690, 0x0740) },
/* ASUS */
- { USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1761, 0x0b05), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0b05, 0x1731) },
+ { USB_DEVICE(0x0b05, 0x1732) },
+ { USB_DEVICE(0x0b05, 0x1742) },
+ { USB_DEVICE(0x0b05, 0x1784) },
+ { USB_DEVICE(0x1761, 0x0b05) },
/* AzureWave */
- { USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x13d3, 0x3307), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x13d3, 0x3321), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3247) },
+ { USB_DEVICE(0x13d3, 0x3273) },
+ { USB_DEVICE(0x13d3, 0x3305) },
+ { USB_DEVICE(0x13d3, 0x3307) },
+ { USB_DEVICE(0x13d3, 0x3321) },
/* Belkin */
- { USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x050d, 0x815c), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x050d, 0x825b), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x050d, 0x935a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x050d, 0x935b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x050d, 0x8053) },
+ { USB_DEVICE(0x050d, 0x805c) },
+ { USB_DEVICE(0x050d, 0x815c) },
+ { USB_DEVICE(0x050d, 0x825b) },
+ { USB_DEVICE(0x050d, 0x935a) },
+ { USB_DEVICE(0x050d, 0x935b) },
/* Buffalo */
- { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0411, 0x016f), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Conceptronic */
- { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0411, 0x00e8) },
+ { USB_DEVICE(0x0411, 0x016f) },
+ { USB_DEVICE(0x0411, 0x01a2) },
/* Corega */
- { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07aa, 0x002f) },
+ { USB_DEVICE(0x07aa, 0x003c) },
+ { USB_DEVICE(0x07aa, 0x003f) },
+ { USB_DEVICE(0x18c5, 0x0012) },
/* D-Link */
- { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c09) },
+ { USB_DEVICE(0x07d1, 0x3c0a) },
+ { USB_DEVICE(0x07d1, 0x3c0d) },
+ { USB_DEVICE(0x07d1, 0x3c0e) },
+ { USB_DEVICE(0x07d1, 0x3c0f) },
+ { USB_DEVICE(0x07d1, 0x3c11) },
+ { USB_DEVICE(0x07d1, 0x3c16) },
/* Draytek */
- { USB_DEVICE(0x07fa, 0x7712), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07fa, 0x7712) },
/* Edimax */
- { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x7392, 0x7711) },
+ { USB_DEVICE(0x7392, 0x7717) },
+ { USB_DEVICE(0x7392, 0x7718) },
/* Encore */
- { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x203d, 0x1480) },
+ { USB_DEVICE(0x203d, 0x14a9) },
/* EnGenius */
- { USB_DEVICE(0x1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9701) },
+ { USB_DEVICE(0x1740, 0x9702) },
+ { USB_DEVICE(0x1740, 0x9703) },
+ { USB_DEVICE(0x1740, 0x9705) },
+ { USB_DEVICE(0x1740, 0x9706) },
+ { USB_DEVICE(0x1740, 0x9707) },
+ { USB_DEVICE(0x1740, 0x9708) },
+ { USB_DEVICE(0x1740, 0x9709) },
+ /* Gemtek */
+ { USB_DEVICE(0x15a9, 0x0012) },
/* Gigabyte */
- { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1044, 0x800b) },
+ { USB_DEVICE(0x1044, 0x800d) },
/* Hawking */
- { USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0e66, 0x0013), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0e66, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0e66, 0x0018), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0e66, 0x0001) },
+ { USB_DEVICE(0x0e66, 0x0003) },
+ { USB_DEVICE(0x0e66, 0x0009) },
+ { USB_DEVICE(0x0e66, 0x000b) },
+ { USB_DEVICE(0x0e66, 0x0013) },
+ { USB_DEVICE(0x0e66, 0x0017) },
+ { USB_DEVICE(0x0e66, 0x0018) },
/* I-O DATA */
- { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x04bb, 0x0945) },
+ { USB_DEVICE(0x04bb, 0x0947) },
+ { USB_DEVICE(0x04bb, 0x0948) },
/* Linksys */
- { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13b1, 0x0031) },
+ { USB_DEVICE(0x1737, 0x0070) },
+ { USB_DEVICE(0x1737, 0x0071) },
/* Logitec */
- { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0789, 0x0166), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0789, 0x0162) },
+ { USB_DEVICE(0x0789, 0x0163) },
+ { USB_DEVICE(0x0789, 0x0164) },
+ { USB_DEVICE(0x0789, 0x0166) },
/* Motorola */
- { USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x100d, 0x9031) },
/* MSI */
- { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x822b), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x822c), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x871a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x871b), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x871c), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x3820) },
+ { USB_DEVICE(0x0db0, 0x3821) },
+ { USB_DEVICE(0x0db0, 0x3822) },
+ { USB_DEVICE(0x0db0, 0x3870) },
+ { USB_DEVICE(0x0db0, 0x3871) },
+ { USB_DEVICE(0x0db0, 0x6899) },
+ { USB_DEVICE(0x0db0, 0x821a) },
+ { USB_DEVICE(0x0db0, 0x822a) },
+ { USB_DEVICE(0x0db0, 0x822b) },
+ { USB_DEVICE(0x0db0, 0x822c) },
+ { USB_DEVICE(0x0db0, 0x870a) },
+ { USB_DEVICE(0x0db0, 0x871a) },
+ { USB_DEVICE(0x0db0, 0x871b) },
+ { USB_DEVICE(0x0db0, 0x871c) },
+ { USB_DEVICE(0x0db0, 0x899a) },
/* Para */
- { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x20b8, 0x8888) },
/* Pegatron */
- { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1d4d, 0x0011), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1d4d, 0x000c) },
+ { USB_DEVICE(0x1d4d, 0x000e) },
+ { USB_DEVICE(0x1d4d, 0x0011) },
/* Philips */
- { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0471, 0x200f) },
/* Planex */
- { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x2019, 0xab25) },
+ { USB_DEVICE(0x2019, 0xed06) },
/* Quanta */
- { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1a32, 0x0304) },
/* Ralink */
- { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x2070) },
+ { USB_DEVICE(0x148f, 0x2770) },
+ { USB_DEVICE(0x148f, 0x2870) },
+ { USB_DEVICE(0x148f, 0x3070) },
+ { USB_DEVICE(0x148f, 0x3071) },
+ { USB_DEVICE(0x148f, 0x3072) },
/* Samsung */
- { USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x04e8, 0x2018) },
/* Siemens */
- { USB_DEVICE(0x129b, 0x1828), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x129b, 0x1828) },
/* Sitecom */
- { USB_DEVICE(0x0df6, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x002b), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x002c), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x002d), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0017) },
+ { USB_DEVICE(0x0df6, 0x002b) },
+ { USB_DEVICE(0x0df6, 0x002c) },
+ { USB_DEVICE(0x0df6, 0x002d) },
+ { USB_DEVICE(0x0df6, 0x0039) },
+ { USB_DEVICE(0x0df6, 0x003b) },
+ { USB_DEVICE(0x0df6, 0x003d) },
+ { USB_DEVICE(0x0df6, 0x003e) },
+ { USB_DEVICE(0x0df6, 0x003f) },
+ { USB_DEVICE(0x0df6, 0x0040) },
+ { USB_DEVICE(0x0df6, 0x0042) },
+ { USB_DEVICE(0x0df6, 0x0047) },
+ { USB_DEVICE(0x0df6, 0x0048) },
+ { USB_DEVICE(0x0df6, 0x0051) },
+ { USB_DEVICE(0x0df6, 0x005f) },
/* SMC */
- { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0xa703), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0x6618) },
+ { USB_DEVICE(0x083a, 0x7511) },
+ { USB_DEVICE(0x083a, 0x7512) },
+ { USB_DEVICE(0x083a, 0x7522) },
+ { USB_DEVICE(0x083a, 0x8522) },
+ { USB_DEVICE(0x083a, 0xa618) },
+ { USB_DEVICE(0x083a, 0xa701) },
+ { USB_DEVICE(0x083a, 0xa702) },
+ { USB_DEVICE(0x083a, 0xa703) },
+ { USB_DEVICE(0x083a, 0xb522) },
/* Sparklan */
- { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x15a9, 0x0006) },
/* Sweex */
- { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* U-Media*/
- { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x177f, 0x0302) },
+ /* U-Media */
+ { USB_DEVICE(0x157e, 0x300e) },
+ { USB_DEVICE(0x157e, 0x3013) },
/* ZCOM */
- { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0cde, 0x0022) },
+ { USB_DEVICE(0x0cde, 0x0025) },
/* Zinwell */
- { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x5a57, 0x0280) },
+ { USB_DEVICE(0x5a57, 0x0282) },
+ { USB_DEVICE(0x5a57, 0x0283) },
+ { USB_DEVICE(0x5a57, 0x5257) },
/* Zyxel */
- { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0586, 0x3416) },
+ { USB_DEVICE(0x0586, 0x3418) },
+ { USB_DEVICE(0x0586, 0x341e) },
+ { USB_DEVICE(0x0586, 0x343e) },
#ifdef CONFIG_RT2800USB_RT33XX
/* Ralink */
- { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3370) },
+ { USB_DEVICE(0x148f, 0x8070) },
/* Sitecom */
- { USB_DEVICE(0x0df6, 0x0050), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0050) },
#endif
#ifdef CONFIG_RT2800USB_RT35XX
/* Allwin */
- { USB_DEVICE(0x8516, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x8516, 0x3572) },
/* Askey */
- { USB_DEVICE(0x1690, 0x0744), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1690, 0x0744) },
/* Cisco */
- { USB_DEVICE(0x167b, 0x4001), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x167b, 0x4001) },
/* EnGenius */
- { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9801) },
/* I-O DATA */
- { USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x04bb, 0x0944) },
+ /* Linksys */
+ { USB_DEVICE(0x13b1, 0x002f) },
+ { USB_DEVICE(0x1737, 0x0079) },
/* Ralink */
- { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3572) },
/* Sitecom */
- { USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0041) },
/* Toshiba */
- { USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0930, 0x0a07) },
/* Zinwell */
- { USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x5a57, 0x0284) },
+#endif
+#ifdef CONFIG_RT2800USB_RT53XX
+ /* Azurewave */
+ { USB_DEVICE(0x13d3, 0x3329) },
+ { USB_DEVICE(0x13d3, 0x3365) },
+ /* Ralink */
+ { USB_DEVICE(0x148f, 0x5370) },
+ { USB_DEVICE(0x148f, 0x5372) },
#endif
#ifdef CONFIG_RT2800USB_UNKNOWN
/*
* Unclear what kind of devices these are (they aren't supported by the
* vendor linux driver).
*/
+ /* Abocom */
+ { USB_DEVICE(0x07b8, 0x3073) },
+ { USB_DEVICE(0x07b8, 0x3074) },
+ /* Alpha Networks */
+ { USB_DEVICE(0x14b2, 0x3c08) },
+ { USB_DEVICE(0x14b2, 0x3c11) },
/* Amigo */
- { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0e0b, 0x9031) },
+ { USB_DEVICE(0x0e0b, 0x9041) },
/* ASUS */
- { USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0b05, 0x1790), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0b05, 0x166a) },
+ { USB_DEVICE(0x0b05, 0x1760) },
+ { USB_DEVICE(0x0b05, 0x1761) },
+ { USB_DEVICE(0x0b05, 0x1790) },
+ { USB_DEVICE(0x0b05, 0x179d) },
/* AzureWave */
- { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x13d3, 0x3322), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3262) },
+ { USB_DEVICE(0x13d3, 0x3284) },
+ { USB_DEVICE(0x13d3, 0x3322) },
/* Belkin */
- { USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x050d, 0x1003) },
+ { USB_DEVICE(0x050d, 0x825a) },
/* Buffalo */
- { USB_DEVICE(0x0411, 0x012e), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0411, 0x0148), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0411, 0x0150), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0411, 0x015d), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Conceptronic */
- { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0411, 0x012e) },
+ { USB_DEVICE(0x0411, 0x0148) },
+ { USB_DEVICE(0x0411, 0x0150) },
+ { USB_DEVICE(0x0411, 0x015d) },
/* Corega */
- { USB_DEVICE(0x07aa, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07aa, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x18c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07aa, 0x0041) },
+ { USB_DEVICE(0x07aa, 0x0042) },
+ { USB_DEVICE(0x18c5, 0x0008) },
/* D-Link */
- { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c17), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0b) },
+ { USB_DEVICE(0x07d1, 0x3c13) },
+ { USB_DEVICE(0x07d1, 0x3c15) },
+ { USB_DEVICE(0x07d1, 0x3c17) },
+ { USB_DEVICE(0x2001, 0x3c17) },
/* Edimax */
- { USB_DEVICE(0x7392, 0x4085), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x7392, 0x4085) },
+ { USB_DEVICE(0x7392, 0x7722) },
/* Encore */
- { USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x203d, 0x14a1) },
/* Gemtek */
- { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x15a9, 0x0010) },
/* Gigabyte */
- { USB_DEVICE(0x1044, 0x800c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1044, 0x800c) },
+ /* Huawei */
+ { USB_DEVICE(0x148f, 0xf101) },
+ /* I-O DATA */
+ { USB_DEVICE(0x04bb, 0x094b) },
/* LevelOne */
- { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x0605) },
+ { USB_DEVICE(0x1740, 0x0615) },
/* Linksys */
- { USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1737, 0x0078), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1737, 0x0077) },
+ { USB_DEVICE(0x1737, 0x0078) },
+ /* Logitec */
+ { USB_DEVICE(0x0789, 0x0168) },
+ { USB_DEVICE(0x0789, 0x0169) },
/* Motorola */
- { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x100d, 0x9032) },
/* Ovislink */
- { USB_DEVICE(0x1b75, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1b75, 0x3071) },
+ { USB_DEVICE(0x1b75, 0x3072) },
/* Pegatron */
- { USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1d4d, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x05a6, 0x0101) },
+ { USB_DEVICE(0x1d4d, 0x0002) },
+ { USB_DEVICE(0x1d4d, 0x0010) },
/* Planex */
- { USB_DEVICE(0x2019, 0x5201), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x2019, 0x5201) },
+ { USB_DEVICE(0x2019, 0xab24) },
/* Qcom */
- { USB_DEVICE(0x18e8, 0x6259), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x18e8, 0x6259) },
+ /* RadioShack */
+ { USB_DEVICE(0x08b9, 0x1197) },
+ /* Sitecom */
+ { USB_DEVICE(0x0df6, 0x003c) },
+ { USB_DEVICE(0x0df6, 0x004a) },
+ { USB_DEVICE(0x0df6, 0x004d) },
+ { USB_DEVICE(0x0df6, 0x0053) },
+ { USB_DEVICE(0x0df6, 0x0060) },
+ { USB_DEVICE(0x0df6, 0x0062) },
/* SMC */
- { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0xd522), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0xf511), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0xa512) },
+ { USB_DEVICE(0x083a, 0xc522) },
+ { USB_DEVICE(0x083a, 0xd522) },
+ { USB_DEVICE(0x083a, 0xf511) },
/* Sweex */
- { USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x177f, 0x0153) },
+ { USB_DEVICE(0x177f, 0x0313) },
/* Zyxel */
- { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0586, 0x341a) },
#endif
{ 0, }
};
@@ -995,10 +1117,16 @@ MODULE_DEVICE_TABLE(usb, rt2800usb_device_table);
MODULE_FIRMWARE(FIRMWARE_RT2870);
MODULE_LICENSE("GPL");
+static int rt2800usb_probe(struct usb_interface *usb_intf,
+ const struct usb_device_id *id)
+{
+ return rt2x00usb_probe(usb_intf, &rt2800usb_ops);
+}
+
static struct usb_driver rt2800usb_driver = {
.name = KBUILD_MODNAME,
.id_table = rt2800usb_device_table,
- .probe = rt2x00usb_probe,
+ .probe = rt2800usb_probe,
.disconnect = rt2x00usb_disconnect,
.suspend = rt2x00usb_suspend,
.resume = rt2x00usb_resume,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 7f10239f56a..c446db69bd3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -37,6 +37,7 @@
#include <linux/etherdevice.h>
#include <linux/input-polldev.h>
#include <linux/kfifo.h>
+#include <linux/timer.h>
#include <net/mac80211.h>
@@ -348,6 +349,11 @@ struct link {
* to bring the device/driver back into the desired state.
*/
struct delayed_work watchdog_work;
+
+ /*
+ * Work structure for scheduling periodic AGC adjustments.
+ */
+ struct delayed_work agc_work;
};
enum rt2x00_delayed_flags {
@@ -556,6 +562,7 @@ struct rt2x00lib_ops {
struct link_qual *qual);
void (*link_tuner) (struct rt2x00_dev *rt2x00dev,
struct link_qual *qual, const u32 count);
+ void (*gain_calibration) (struct rt2x00_dev *rt2x00dev);
/*
* Data queue handlers.
@@ -564,7 +571,8 @@ struct rt2x00lib_ops {
void (*start_queue) (struct data_queue *queue);
void (*kick_queue) (struct data_queue *queue);
void (*stop_queue) (struct data_queue *queue);
- void (*flush_queue) (struct data_queue *queue);
+ void (*flush_queue) (struct data_queue *queue, bool drop);
+ void (*tx_dma_done) (struct queue_entry *entry);
/*
* TX control handlers
@@ -637,11 +645,11 @@ struct rt2x00_ops {
};
/*
- * rt2x00 device flags
+ * rt2x00 state flags
*/
-enum rt2x00_flags {
+enum rt2x00_state_flags {
/*
- * Device state flags
+ * Device flags
*/
DEVICE_STATE_PRESENT,
DEVICE_STATE_REGISTERED_HW,
@@ -651,40 +659,47 @@ enum rt2x00_flags {
DEVICE_STATE_SCANNING,
/*
- * Driver requirements
- */
- DRIVER_REQUIRE_FIRMWARE,
- DRIVER_REQUIRE_BEACON_GUARD,
- DRIVER_REQUIRE_ATIM_QUEUE,
- DRIVER_REQUIRE_DMA,
- DRIVER_REQUIRE_COPY_IV,
- DRIVER_REQUIRE_L2PAD,
- DRIVER_REQUIRE_TXSTATUS_FIFO,
- DRIVER_REQUIRE_TASKLET_CONTEXT,
- DRIVER_REQUIRE_SW_SEQNO,
- DRIVER_REQUIRE_HT_TX_DESC,
-
- /*
- * Driver features
- */
- CONFIG_SUPPORT_HW_BUTTON,
- CONFIG_SUPPORT_HW_CRYPTO,
- CONFIG_SUPPORT_POWER_LIMIT,
- DRIVER_SUPPORT_CONTROL_FILTERS,
- DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL,
- DRIVER_SUPPORT_PRE_TBTT_INTERRUPT,
- DRIVER_SUPPORT_LINK_TUNING,
- DRIVER_SUPPORT_WATCHDOG,
-
- /*
* Driver configuration
*/
- CONFIG_FRAME_TYPE,
- CONFIG_RF_SEQUENCE,
- CONFIG_EXTERNAL_LNA_A,
- CONFIG_EXTERNAL_LNA_BG,
- CONFIG_DOUBLE_ANTENNA,
CONFIG_CHANNEL_HT40,
+ CONFIG_POWERSAVING,
+};
+
+/*
+ * rt2x00 capability flags
+ */
+enum rt2x00_capability_flags {
+ /*
+ * Requirements
+ */
+ REQUIRE_FIRMWARE,
+ REQUIRE_BEACON_GUARD,
+ REQUIRE_ATIM_QUEUE,
+ REQUIRE_DMA,
+ REQUIRE_COPY_IV,
+ REQUIRE_L2PAD,
+ REQUIRE_TXSTATUS_FIFO,
+ REQUIRE_TASKLET_CONTEXT,
+ REQUIRE_SW_SEQNO,
+ REQUIRE_HT_TX_DESC,
+ REQUIRE_PS_AUTOWAKE,
+
+ /*
+ * Capabilities
+ */
+ CAPABILITY_HW_BUTTON,
+ CAPABILITY_HW_CRYPTO,
+ CAPABILITY_POWER_LIMIT,
+ CAPABILITY_CONTROL_FILTERS,
+ CAPABILITY_CONTROL_FILTER_PSPOLL,
+ CAPABILITY_PRE_TBTT_INTERRUPT,
+ CAPABILITY_LINK_TUNING,
+ CAPABILITY_FRAME_TYPE,
+ CAPABILITY_RF_SEQUENCE,
+ CAPABILITY_EXTERNAL_LNA_A,
+ CAPABILITY_EXTERNAL_LNA_BG,
+ CAPABILITY_DOUBLE_ANTENNA,
+ CAPABILITY_BT_COEXIST,
};
/*
@@ -733,13 +748,20 @@ struct rt2x00_dev {
#endif /* CONFIG_RT2X00_LIB_LEDS */
/*
- * Device flags.
- * In these flags the current status and some
- * of the device capabilities are stored.
+ * Device state flags.
+ * In these flags the current status is stored.
+ * Access to these flags should occur atomically.
*/
unsigned long flags;
/*
+ * Device capabiltiy flags.
+ * In these flags the device/driver capabilities are stored.
+ * Access to these flags should occur non-atomically.
+ */
+ unsigned long cap_flags;
+
+ /*
* Device information, Bus IRQ and name (PCI, SoC)
*/
int irq;
@@ -855,10 +877,20 @@ struct rt2x00_dev {
u8 calibration[2];
/*
+ * Association id.
+ */
+ u16 aid;
+
+ /*
* Beacon interval.
*/
u16 beacon_int;
+ /**
+ * Timestamp of last received beacon
+ */
+ unsigned long last_beacon;
+
/*
* Low level statistics which will have
* to be kept up to date while device is running.
@@ -887,6 +919,11 @@ struct rt2x00_dev {
struct work_struct txdone_work;
/*
+ * Powersaving work
+ */
+ struct delayed_work autowakeup_work;
+
+ /*
* Data queue arrays for RX, TX, Beacon and ATIM.
*/
unsigned int data_queues;
@@ -906,6 +943,11 @@ struct rt2x00_dev {
DECLARE_KFIFO_PTR(txstatus_fifo, u32);
/*
+ * Timer to ensure tx status reports are read (rt2800usb).
+ */
+ struct timer_list txstatus_timer;
+
+ /*
* Tasklet for processing tx status reports (rt2800pci).
*/
struct tasklet_struct txstatus_tasklet;
@@ -1230,6 +1272,10 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop);
+int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
+int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
+void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
+ u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
/*
* Driver allocation handlers.
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 9416e36de29..555180d8f4a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -100,6 +100,10 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
erp.basic_rates = bss_conf->basic_rates;
erp.beacon_int = bss_conf->beacon_int;
+ /* Update the AID, this is needed for dynamic PS support */
+ rt2x00dev->aid = bss_conf->assoc ? bss_conf->aid : 0;
+ rt2x00dev->last_beacon = bss_conf->timestamp;
+
/* Update global beacon interval time, this is needed for PS support */
rt2x00dev->beacon_int = bss_conf->beacon_int;
@@ -109,15 +113,6 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed);
}
-static inline
-enum antenna rt2x00lib_config_antenna_check(enum antenna current_ant,
- enum antenna default_ant)
-{
- if (current_ant != ANTENNA_SW_DIVERSITY)
- return current_ant;
- return (default_ant != ANTENNA_SW_DIVERSITY) ? default_ant : ANTENNA_B;
-}
-
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
struct antenna_setup config)
{
@@ -126,19 +121,35 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
struct antenna_setup *active = &rt2x00dev->link.ant.active;
/*
- * Failsafe: Make sure we are not sending the
- * ANTENNA_SW_DIVERSITY state to the driver.
- * If that happens, fallback to hardware defaults,
- * or our own default.
+ * When the caller tries to send the SW diversity,
+ * we must update the ANTENNA_RX_DIVERSITY flag to
+ * enable the antenna diversity in the link tuner.
+ *
+ * Secondly, we must guarentee we never send the
+ * software antenna diversity command to the driver.
*/
- if (!(ant->flags & ANTENNA_RX_DIVERSITY))
- config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx);
- else if (config.rx == ANTENNA_SW_DIVERSITY)
+ if (!(ant->flags & ANTENNA_RX_DIVERSITY)) {
+ if (config.rx == ANTENNA_SW_DIVERSITY) {
+ ant->flags |= ANTENNA_RX_DIVERSITY;
+
+ if (def->rx == ANTENNA_SW_DIVERSITY)
+ config.rx = ANTENNA_B;
+ else
+ config.rx = def->rx;
+ }
+ } else if (config.rx == ANTENNA_SW_DIVERSITY)
config.rx = active->rx;
- if (!(ant->flags & ANTENNA_TX_DIVERSITY))
- config.tx = rt2x00lib_config_antenna_check(config.tx, def->tx);
- else if (config.tx == ANTENNA_SW_DIVERSITY)
+ if (!(ant->flags & ANTENNA_TX_DIVERSITY)) {
+ if (config.tx == ANTENNA_SW_DIVERSITY) {
+ ant->flags |= ANTENNA_TX_DIVERSITY;
+
+ if (def->tx == ANTENNA_SW_DIVERSITY)
+ config.tx = ANTENNA_B;
+ else
+ config.tx = def->tx;
+ }
+ } else if (config.tx == ANTENNA_SW_DIVERSITY)
config.tx = active->tx;
/*
@@ -163,12 +174,43 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
rt2x00queue_start_queue(rt2x00dev->rx);
}
+static u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf)
+{
+ struct hw_mode_spec *spec = &rt2x00dev->spec;
+ int center_channel;
+ u16 i;
+
+ /*
+ * Initialize center channel to current channel.
+ */
+ center_channel = spec->channels[conf->channel->hw_value].channel;
+
+ /*
+ * Adjust center channel to HT40+ and HT40- operation.
+ */
+ if (conf_is_ht40_plus(conf))
+ center_channel += 2;
+ else if (conf_is_ht40_minus(conf))
+ center_channel -= (center_channel == 14) ? 1 : 2;
+
+ for (i = 0; i < spec->num_channels; i++)
+ if (spec->channels[i].channel == center_channel)
+ return i;
+
+ WARN_ON(1);
+ return conf->channel->hw_value;
+}
+
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf,
unsigned int ieee80211_flags)
{
struct rt2x00lib_conf libconf;
u16 hw_value;
+ u16 autowake_timeout;
+ u16 beacon_int;
+ u16 beacon_diff;
memset(&libconf, 0, sizeof(libconf));
@@ -176,10 +218,10 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) {
if (conf_is_ht40(conf)) {
- __set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
+ set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
hw_value = rt2x00ht_center_channel(rt2x00dev, conf);
} else {
- __clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
+ clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
hw_value = conf->channel->hw_value;
}
@@ -192,6 +234,10 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
sizeof(libconf.channel));
}
+ if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) &&
+ (ieee80211_flags & IEEE80211_CONF_CHANGE_PS))
+ cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
+
/*
* Start configuration.
*/
@@ -204,6 +250,26 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL)
rt2x00link_reset_tuner(rt2x00dev, false);
+ if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) &&
+ (ieee80211_flags & IEEE80211_CONF_CHANGE_PS) &&
+ (conf->flags & IEEE80211_CONF_PS)) {
+ beacon_diff = (long)jiffies - (long)rt2x00dev->last_beacon;
+ beacon_int = msecs_to_jiffies(rt2x00dev->beacon_int);
+
+ if (beacon_diff > beacon_int)
+ beacon_diff = 0;
+
+ autowake_timeout = (conf->max_sleep_period * beacon_int) - beacon_diff;
+ queue_delayed_work(rt2x00dev->workqueue,
+ &rt2x00dev->autowakeup_work,
+ autowake_timeout - 15);
+ }
+
+ if (conf->flags & IEEE80211_CONF_PS)
+ set_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
+ else
+ clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
+
rt2x00dev->curr_band = conf->channel->band;
rt2x00dev->curr_freq = conf->channel->center_freq;
rt2x00dev->tx_power = conf->power_level;
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index 3f5688fbf3f..1bb9d46077f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -52,7 +52,7 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
- if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) || !hw_key)
+ if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags) || !hw_key)
return;
__set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags);
@@ -80,7 +80,7 @@ unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
struct ieee80211_key_conf *key = tx_info->control.hw_key;
unsigned int overhead = 0;
- if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) || !key)
+ if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags) || !key)
return overhead;
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index c92db326474..78787fcc919 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -63,7 +63,8 @@ struct rt2x00debug_intf {
* - driver folder
* - driver file
* - chipset file
- * - device flags file
+ * - device state flags file
+ * - device capability flags file
* - register folder
* - csr offset/value files
* - eeprom offset/value files
@@ -78,6 +79,7 @@ struct rt2x00debug_intf {
struct dentry *driver_entry;
struct dentry *chipset_entry;
struct dentry *dev_flags;
+ struct dentry *cap_flags;
struct dentry *register_folder;
struct dentry *csr_off_entry;
struct dentry *csr_val_entry;
@@ -553,6 +555,35 @@ static const struct file_operations rt2x00debug_fop_dev_flags = {
.llseek = default_llseek,
};
+static ssize_t rt2x00debug_read_cap_flags(struct file *file,
+ char __user *buf,
+ size_t length,
+ loff_t *offset)
+{
+ struct rt2x00debug_intf *intf = file->private_data;
+ char line[16];
+ size_t size;
+
+ if (*offset)
+ return 0;
+
+ size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->cap_flags);
+
+ if (copy_to_user(buf, line, size))
+ return -EFAULT;
+
+ *offset += size;
+ return size;
+}
+
+static const struct file_operations rt2x00debug_fop_cap_flags = {
+ .owner = THIS_MODULE,
+ .read = rt2x00debug_read_cap_flags,
+ .open = rt2x00debug_file_open,
+ .release = rt2x00debug_file_release,
+ .llseek = default_llseek,
+};
+
static struct dentry *rt2x00debug_create_file_driver(const char *name,
struct rt2x00debug_intf
*intf,
@@ -568,7 +599,6 @@ static struct dentry *rt2x00debug_create_file_driver(const char *name,
blob->data = data;
data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name);
data += sprintf(data, "version:\t%s\n", DRV_VERSION);
- data += sprintf(data, "compiled:\t%s %s\n", __DATE__, __TIME__);
blob->size = strlen(blob->data);
return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
@@ -653,6 +683,12 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
if (IS_ERR(intf->dev_flags) || !intf->dev_flags)
goto exit;
+ intf->cap_flags = debugfs_create_file("cap_flags", S_IRUSR,
+ intf->driver_folder, intf,
+ &rt2x00debug_fop_cap_flags);
+ if (IS_ERR(intf->cap_flags) || !intf->cap_flags)
+ goto exit;
+
intf->register_folder =
debugfs_create_dir("register", intf->driver_folder);
if (IS_ERR(intf->register_folder) || !intf->register_folder)
@@ -706,7 +742,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
intf, &rt2x00debug_fop_queue_stats);
#ifdef CONFIG_RT2X00_LIB_CRYPTO
- if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
+ if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags))
intf->crypto_stats_entry =
debugfs_create_file("crypto", S_IRUGO, intf->queue_folder,
intf, &rt2x00debug_fop_crypto_stats);
@@ -744,6 +780,7 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
debugfs_remove(intf->csr_off_entry);
debugfs_remove(intf->register_folder);
debugfs_remove(intf->dev_flags);
+ debugfs_remove(intf->cap_flags);
debugfs_remove(intf->chipset_entry);
debugfs_remove(intf->driver_entry);
debugfs_remove(intf->driver_folder);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 84eb6ad3637..c018d67aab8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -27,6 +27,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
+#include <linux/log2.h>
#include "rt2x00.h"
#include "rt2x00lib.h"
@@ -70,6 +71,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
*/
rt2x00queue_start_queues(rt2x00dev);
rt2x00link_start_tuner(rt2x00dev);
+ rt2x00link_start_agc(rt2x00dev);
/*
* Start watchdog monitoring.
@@ -92,6 +94,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
/*
* Stop all queues
*/
+ rt2x00link_stop_agc(rt2x00dev);
rt2x00link_stop_tuner(rt2x00dev);
rt2x00queue_stop_queues(rt2x00dev);
rt2x00queue_flush_queues(rt2x00dev, true);
@@ -138,6 +141,16 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work)
rt2x00dev);
}
+static void rt2x00lib_autowakeup(struct work_struct *work)
+{
+ struct rt2x00_dev *rt2x00dev =
+ container_of(work, struct rt2x00_dev, autowakeup_work.work);
+
+ if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE))
+ ERROR(rt2x00dev, "Device failed to wakeup.\n");
+ clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
+}
+
/*
* Interrupt context handlers.
*/
@@ -197,7 +210,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
* here as they will fetch the next beacon directly prior to
* transmission.
*/
- if (test_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags))
+ if (test_bit(CAPABILITY_PRE_TBTT_INTERRUPT, &rt2x00dev->cap_flags))
return;
/* fetch next beacon */
@@ -222,7 +235,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);
void rt2x00lib_dmastart(struct queue_entry *entry)
{
set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
- rt2x00queue_index_inc(entry->queue, Q_INDEX);
+ rt2x00queue_index_inc(entry, Q_INDEX);
}
EXPORT_SYMBOL_GPL(rt2x00lib_dmastart);
@@ -230,7 +243,7 @@ void rt2x00lib_dmadone(struct queue_entry *entry)
{
set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags);
clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
- rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
+ rt2x00queue_index_inc(entry, Q_INDEX_DMA_DONE);
}
EXPORT_SYMBOL_GPL(rt2x00lib_dmadone);
@@ -268,7 +281,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
/*
* Remove L2 padding which was added during
*/
- if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
+ if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags))
rt2x00queue_remove_l2pad(entry->skb, header_length);
/*
@@ -277,7 +290,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
* mac80211 will expect the same data to be present it the
* frame as it was passed to us.
*/
- if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
+ if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags))
rt2x00crypto_tx_insert_iv(entry->skb, header_length);
/*
@@ -350,10 +363,14 @@ void rt2x00lib_txdone(struct queue_entry *entry,
* which would allow the rc algorithm to better decide on
* which rates are suitable.
*/
- if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+ if (test_bit(TXDONE_AMPDU, &txdesc->flags) ||
+ tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
tx_info->status.ampdu_len = 1;
tx_info->status.ampdu_ack_len = success ? 1 : 0;
+
+ if (!success)
+ tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
}
if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
@@ -370,7 +387,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
* send the status report back.
*/
if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) {
- if (test_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags))
+ if (test_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags))
ieee80211_tx_status(rt2x00dev->hw, entry->skb);
else
ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb);
@@ -385,7 +402,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
rt2x00dev->ops->lib->clear_entry(entry);
- rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
+ rt2x00queue_index_inc(entry, Q_INDEX_DONE);
/*
* If the data queue was below the threshold before the txdone
@@ -409,6 +426,77 @@ void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status)
}
EXPORT_SYMBOL_GPL(rt2x00lib_txdone_noinfo);
+static u8 *rt2x00lib_find_ie(u8 *data, unsigned int len, u8 ie)
+{
+ struct ieee80211_mgmt *mgmt = (void *)data;
+ u8 *pos, *end;
+
+ pos = (u8 *)mgmt->u.beacon.variable;
+ end = data + len;
+ while (pos < end) {
+ if (pos + 2 + pos[1] > end)
+ return NULL;
+
+ if (pos[0] == ie)
+ return pos;
+
+ pos += 2 + pos[1];
+ }
+
+ return NULL;
+}
+
+static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,
+ struct sk_buff *skb,
+ struct rxdone_entry_desc *rxdesc)
+{
+ struct ieee80211_hdr *hdr = (void *) skb->data;
+ struct ieee80211_tim_ie *tim_ie;
+ u8 *tim;
+ u8 tim_len;
+ bool cam;
+
+ /* If this is not a beacon, or if mac80211 has no powersaving
+ * configured, or if the device is already in powersaving mode
+ * we can exit now. */
+ if (likely(!ieee80211_is_beacon(hdr->frame_control) ||
+ !(rt2x00dev->hw->conf.flags & IEEE80211_CONF_PS)))
+ return;
+
+ /* min. beacon length + FCS_LEN */
+ if (skb->len <= 40 + FCS_LEN)
+ return;
+
+ /* and only beacons from the associated BSSID, please */
+ if (!(rxdesc->dev_flags & RXDONE_MY_BSS) ||
+ !rt2x00dev->aid)
+ return;
+
+ rt2x00dev->last_beacon = jiffies;
+
+ tim = rt2x00lib_find_ie(skb->data, skb->len - FCS_LEN, WLAN_EID_TIM);
+ if (!tim)
+ return;
+
+ if (tim[1] < sizeof(*tim_ie))
+ return;
+
+ tim_len = tim[1];
+ tim_ie = (struct ieee80211_tim_ie *) &tim[2];
+
+ /* Check whenever the PHY can be turned off again. */
+
+ /* 1. What about buffered unicast traffic for our AID? */
+ cam = ieee80211_check_tim(tim_ie, tim_len, rt2x00dev->aid);
+
+ /* 2. Maybe the AP wants to send multicast/broadcast data? */
+ cam |= (tim_ie->bitmap_ctrl & 0x01);
+
+ if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags))
+ rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf,
+ IEEE80211_CONF_CHANGE_PS);
+}
+
static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
struct rxdone_entry_desc *rxdesc)
{
@@ -511,8 +599,6 @@ void rt2x00lib_rxdone(struct queue_entry *entry)
(rxdesc.size > header_length) &&
(rxdesc.dev_flags & RXDONE_L2PAD))
rt2x00queue_remove_l2pad(entry->skb, header_length);
- else
- rt2x00queue_align_payload(entry->skb, header_length);
/* Trim buffer to correct size */
skb_trim(entry->skb, rxdesc.size);
@@ -526,6 +612,12 @@ void rt2x00lib_rxdone(struct queue_entry *entry)
rxdesc.flags |= RX_FLAG_HT;
/*
+ * Check if this is a beacon, and more frames have been
+ * buffered while we were in powersaving mode.
+ */
+ rt2x00lib_rxdone_check_ps(rt2x00dev, entry->skb, &rxdesc);
+
+ /*
* Update extra components
*/
rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc);
@@ -554,7 +646,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry)
submit_entry:
entry->flags = 0;
- rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
+ rt2x00queue_index_inc(entry, Q_INDEX_DONE);
if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
rt2x00dev->ops->lib->clear_entry(entry);
@@ -801,23 +893,28 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* Take TX headroom required for alignment into account.
*/
- if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
+ if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags))
rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE;
- else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
+ else if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags))
rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE;
/*
* Allocate tx status FIFO for driver use.
*/
- if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags)) {
+ if (test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags)) {
/*
- * Allocate txstatus fifo and tasklet, we use a size of 512
- * for the kfifo which is big enough to store 512/4=128 tx
- * status reports. In the worst case (tx status for all tx
- * queues gets reported before we've got a chance to handle
- * them) 24*4=384 tx status reports need to be cached.
+ * Allocate the txstatus fifo. In the worst case the tx
+ * status fifo has to hold the tx status of all entries
+ * in all tx queues. Hence, calculate the kfifo size as
+ * tx_queues * entry_num and round up to the nearest
+ * power of 2.
*/
- status = kfifo_alloc(&rt2x00dev->txstatus_fifo, 512,
+ int kfifo_size =
+ roundup_pow_of_two(rt2x00dev->ops->tx_queues *
+ rt2x00dev->ops->tx->entry_num *
+ sizeof(u32));
+
+ status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size,
GFP_KERNEL);
if (status)
return status;
@@ -1007,6 +1104,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
}
INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
+ INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
/*
* Let the driver probe the device to detect the capabilities.
@@ -1063,6 +1161,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
*/
cancel_work_sync(&rt2x00dev->intf_work);
if (rt2x00_is_usb(rt2x00dev)) {
+ del_timer_sync(&rt2x00dev->txstatus_timer);
cancel_work_sync(&rt2x00dev->rxdone_work);
cancel_work_sync(&rt2x00dev->txdone_work);
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c
index be0ff78c1b1..f316aad3061 100644
--- a/drivers/net/wireless/rt2x00/rt2x00firmware.c
+++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c
@@ -99,7 +99,7 @@ int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev)
{
int retval;
- if (!test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags))
+ if (!test_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags))
return 0;
if (!rt2x00dev->fw) {
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
deleted file mode 100644
index ae1219dffaa..00000000000
--- a/drivers/net/wireless/rt2x00/rt2x00ht.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
- <http://rt2x00.serialmonkey.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the
- Free Software Foundation, Inc.,
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*
- Module: rt2x00lib
- Abstract: rt2x00 HT specific routines.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "rt2x00.h"
-#include "rt2x00lib.h"
-
-void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
- struct txentry_desc *txdesc,
- const struct rt2x00_rate *hwrate)
-{
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
- struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
-
- if (tx_info->control.sta)
- txdesc->u.ht.mpdu_density =
- tx_info->control.sta->ht_cap.ampdu_density;
-
- txdesc->u.ht.ba_size = 7; /* FIXME: What value is needed? */
-
- txdesc->u.ht.stbc =
- (tx_info->flags & IEEE80211_TX_CTL_STBC) >> IEEE80211_TX_CTL_STBC_SHIFT;
-
- /*
- * If IEEE80211_TX_RC_MCS is set txrate->idx just contains the
- * mcs rate to be used
- */
- if (txrate->flags & IEEE80211_TX_RC_MCS) {
- txdesc->u.ht.mcs = txrate->idx;
-
- /*
- * MIMO PS should be set to 1 for STA's using dynamic SM PS
- * when using more then one tx stream (>MCS7).
- */
- if (tx_info->control.sta && txdesc->u.ht.mcs > 7 &&
- ((tx_info->control.sta->ht_cap.cap &
- IEEE80211_HT_CAP_SM_PS) >>
- IEEE80211_HT_CAP_SM_PS_SHIFT) ==
- WLAN_HT_CAP_SM_PS_DYNAMIC)
- __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags);
- } else {
- txdesc->u.ht.mcs = rt2x00_get_rate_mcs(hwrate->mcs);
- if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
- txdesc->u.ht.mcs |= 0x08;
- }
-
- /*
- * This frame is eligible for an AMPDU, however, don't aggregate
- * frames that are intended to probe a specific tx rate.
- */
- if (tx_info->flags & IEEE80211_TX_CTL_AMPDU &&
- !(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE))
- __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags);
-
- /*
- * Set 40Mhz mode if necessary (for legacy rates this will
- * duplicate the frame to both channels).
- */
- if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH ||
- txrate->flags & IEEE80211_TX_RC_DUP_DATA)
- __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags);
- if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
- __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags);
-
- /*
- * Determine IFS values
- * - Use TXOP_BACKOFF for management frames
- * - Use TXOP_SIFS for fragment bursts
- * - Use TXOP_HTTXOP for everything else
- *
- * Note: rt2800 devices won't use CTS protection (if used)
- * for frames not transmitted with TXOP_HTTXOP
- */
- if (ieee80211_is_mgmt(hdr->frame_control))
- txdesc->u.ht.txop = TXOP_BACKOFF;
- else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT))
- txdesc->u.ht.txop = TXOP_SIFS;
- else
- txdesc->u.ht.txop = TXOP_HTTXOP;
-}
-
-u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_conf *conf)
-{
- struct hw_mode_spec *spec = &rt2x00dev->spec;
- int center_channel;
- u16 i;
-
- /*
- * Initialize center channel to current channel.
- */
- center_channel = spec->channels[conf->channel->hw_value].channel;
-
- /*
- * Adjust center channel to HT40+ and HT40- operation.
- */
- if (conf_is_ht40_plus(conf))
- center_channel += 2;
- else if (conf_is_ht40_minus(conf))
- center_channel -= (center_channel == 14) ? 1 : 2;
-
- for (i = 0; i < spec->num_channels; i++)
- if (spec->channels[i].channel == center_channel)
- return i;
-
- WARN_ON(1);
- return conf->channel->hw_value;
-}
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 2d94cbaf5f4..322cc4f3de5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -32,6 +32,7 @@
*/
#define WATCHDOG_INTERVAL round_jiffies_relative(HZ)
#define LINK_TUNE_INTERVAL round_jiffies_relative(HZ)
+#define AGC_INTERVAL round_jiffies_relative(4 * HZ)
/*
* rt2x00_rate: Per rate device information
@@ -119,16 +120,6 @@ void rt2x00queue_free_skb(struct queue_entry *entry);
void rt2x00queue_align_frame(struct sk_buff *skb);
/**
- * rt2x00queue_align_payload - Align 802.11 payload to 4-byte boundary
- * @skb: The skb to align
- * @header_length: Length of 802.11 header
- *
- * Align the 802.11 payload to a 4-byte boundary, this could
- * mean the header is not aligned properly though.
- */
-void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length);
-
-/**
* rt2x00queue_insert_l2pad - Align 802.11 header & payload to 4-byte boundary
* @skb: The skb to align
* @header_length: Length of 802.11 header
@@ -184,14 +175,14 @@ int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev,
/**
* rt2x00queue_index_inc - Index incrementation function
- * @queue: Queue (&struct data_queue) to perform the action on.
+ * @entry: Queue entry (&struct queue_entry) to perform the action on.
* @index: Index type (&enum queue_index) to perform the action on.
*
- * This function will increase the requested index on the queue,
+ * This function will increase the requested index on the entry's queue,
* it will grab the appropriate locks and handle queue overflow events by
* resetting the index to the start of the queue.
*/
-void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
+void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index);
/**
* rt2x00queue_init_queues - Initialize all data queues
@@ -281,6 +272,18 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev);
void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev);
/**
+ * rt2x00link_start_agc - Start periodic gain calibration
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ */
+void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev);
+
+/**
+ * rt2x00link_stop_agc - Stop periodic gain calibration
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ */
+void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev);
+
+/**
* rt2x00link_register - Initialize link tuning & watchdog functionality
* @rt2x00dev: Pointer to &struct rt2x00_dev.
*
@@ -385,41 +388,17 @@ static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
#endif /* CONFIG_RT2X00_LIB_CRYPTO */
/*
- * HT handlers.
- */
-#ifdef CONFIG_RT2X00_LIB_HT
-void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
- struct txentry_desc *txdesc,
- const struct rt2x00_rate *hwrate);
-
-u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_conf *conf);
-#else
-static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
- struct txentry_desc *txdesc,
- const struct rt2x00_rate *hwrate)
-{
-}
-
-static inline u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_conf *conf)
-{
- return conf->channel->hw_value;
-}
-#endif /* CONFIG_RT2X00_LIB_HT */
-
-/*
* RFkill handlers.
*/
static inline void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
{
- if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
+ if (test_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags))
wiphy_rfkill_start_polling(rt2x00dev->hw->wiphy);
}
static inline void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
{
- if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
+ if (test_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags))
wiphy_rfkill_stop_polling(rt2x00dev->hw->wiphy);
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index 29abfdeb0b6..ea10b0068f8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -192,17 +192,7 @@ static bool rt2x00lib_antenna_diversity(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.
*/
- ant->flags &= ~ANTENNA_RX_DIVERSITY;
- ant->flags &= ~ANTENNA_TX_DIVERSITY;
-
- if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
- ant->flags |= ANTENNA_RX_DIVERSITY;
- if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
- ant->flags |= ANTENNA_TX_DIVERSITY;
-
if (!(ant->flags & ANTENNA_RX_DIVERSITY) &&
!(ant->flags & ANTENNA_TX_DIVERSITY)) {
ant->flags = 0;
@@ -383,7 +373,7 @@ static void rt2x00link_tuner(struct work_struct *work)
* do not support link tuning at all, while other devices can disable
* the feature from the EEPROM.
*/
- if (test_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags))
+ if (test_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags))
rt2x00dev->ops->lib->link_tuner(rt2x00dev, qual, link->count);
/*
@@ -413,12 +403,11 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev)
{
struct link *link = &rt2x00dev->link;
- if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
- !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags))
- return;
-
- ieee80211_queue_delayed_work(rt2x00dev->hw,
- &link->watchdog_work, WATCHDOG_INTERVAL);
+ if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
+ rt2x00dev->ops->lib->watchdog)
+ ieee80211_queue_delayed_work(rt2x00dev->hw,
+ &link->watchdog_work,
+ WATCHDOG_INTERVAL);
}
void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev)
@@ -447,8 +436,46 @@ static void rt2x00link_watchdog(struct work_struct *work)
WATCHDOG_INTERVAL);
}
+void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev)
+{
+ struct link *link = &rt2x00dev->link;
+
+ if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
+ rt2x00dev->ops->lib->gain_calibration)
+ ieee80211_queue_delayed_work(rt2x00dev->hw,
+ &link->agc_work,
+ AGC_INTERVAL);
+}
+
+void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev)
+{
+ cancel_delayed_work_sync(&rt2x00dev->link.agc_work);
+}
+
+static void rt2x00link_agc(struct work_struct *work)
+{
+ struct rt2x00_dev *rt2x00dev =
+ container_of(work, struct rt2x00_dev, link.agc_work.work);
+ struct link *link = &rt2x00dev->link;
+
+ /*
+ * When the radio is shutting down we should
+ * immediately cease the watchdog monitoring.
+ */
+ if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+ return;
+
+ rt2x00dev->ops->lib->gain_calibration(rt2x00dev);
+
+ if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+ ieee80211_queue_delayed_work(rt2x00dev->hw,
+ &link->agc_work,
+ AGC_INTERVAL);
+}
+
void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
{
+ INIT_DELAYED_WORK(&rt2x00dev->link.agc_work, rt2x00link_agc);
INIT_DELAYED_WORK(&rt2x00dev->link.watchdog_work, rt2x00link_watchdog);
INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner);
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 661c6baad2b..93bec140e59 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -119,7 +119,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
* Use the ATIM queue if appropriate and present.
*/
if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM &&
- test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags))
+ test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags))
qid = QID_ATIM;
queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
@@ -158,7 +158,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return;
exit_fail:
- ieee80211_stop_queue(rt2x00dev->hw, qid);
+ rt2x00queue_pause_queue(queue);
dev_kfree_skb_any(skb);
}
EXPORT_SYMBOL_GPL(rt2x00mac_tx);
@@ -411,11 +411,11 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
* of different types, but has no a separate filter for PS Poll frames,
* FIF_CONTROL flag implies FIF_PSPOLL.
*/
- if (!test_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags)) {
+ if (!test_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags)) {
if (*total_flags & FIF_CONTROL || *total_flags & FIF_PSPOLL)
*total_flags |= FIF_CONTROL | FIF_PSPOLL;
}
- if (!test_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags)) {
+ if (!test_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags)) {
if (*total_flags & FIF_CONTROL)
*total_flags |= FIF_PSPOLL;
}
@@ -496,7 +496,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
return 0;
- else if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
+ else if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags))
return -EOPNOTSUPP;
else if (key->keylen > 32)
return -ENOSPC;
@@ -562,7 +562,7 @@ EXPORT_SYMBOL_GPL(rt2x00mac_set_key);
void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
- __set_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags);
+ set_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags);
rt2x00link_stop_tuner(rt2x00dev);
}
EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_start);
@@ -570,7 +570,7 @@ EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_start);
void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
- __clear_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags);
+ clear_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags);
rt2x00link_start_tuner(rt2x00dev);
}
EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_complete);
@@ -737,3 +737,84 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop)
rt2x00queue_flush_queue(queue, drop);
}
EXPORT_SYMBOL_GPL(rt2x00mac_flush);
+
+int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct link_ant *ant = &rt2x00dev->link.ant;
+ struct antenna_setup *def = &rt2x00dev->default_ant;
+ struct antenna_setup setup;
+
+ // The antenna value is not supposed to be 0,
+ // or exceed the maximum number of antenna's.
+ if (!tx_ant || (tx_ant & ~3) || !rx_ant || (rx_ant & ~3))
+ return -EINVAL;
+
+ // When the client tried to configure the antenna to or from
+ // diversity mode, we must reset the default antenna as well
+ // as that controls the diversity switch.
+ if (ant->flags & ANTENNA_TX_DIVERSITY && tx_ant != 3)
+ ant->flags &= ~ANTENNA_TX_DIVERSITY;
+ if (ant->flags & ANTENNA_RX_DIVERSITY && rx_ant != 3)
+ ant->flags &= ~ANTENNA_RX_DIVERSITY;
+
+ // If diversity is being enabled, check if we need hardware
+ // or software diversity. In the latter case, reset the value,
+ // and make sure we update the antenna flags to have the
+ // link tuner pick up the diversity tuning.
+ if (tx_ant == 3 && def->tx == ANTENNA_SW_DIVERSITY) {
+ tx_ant = ANTENNA_SW_DIVERSITY;
+ ant->flags |= ANTENNA_TX_DIVERSITY;
+ }
+
+ if (rx_ant == 3 && def->rx == ANTENNA_SW_DIVERSITY) {
+ rx_ant = ANTENNA_SW_DIVERSITY;
+ ant->flags |= ANTENNA_RX_DIVERSITY;
+ }
+
+ setup.tx = tx_ant;
+ setup.rx = rx_ant;
+
+ rt2x00lib_config_antenna(rt2x00dev, setup);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_set_antenna);
+
+int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct link_ant *ant = &rt2x00dev->link.ant;
+ struct antenna_setup *active = &rt2x00dev->link.ant.active;
+
+ // When software diversity is active, we must report this to the
+ // client and not the current active antenna state.
+ if (ant->flags & ANTENNA_TX_DIVERSITY)
+ *tx_ant = ANTENNA_HW_DIVERSITY;
+ else
+ *tx_ant = active->tx;
+
+ if (ant->flags & ANTENNA_RX_DIVERSITY)
+ *rx_ant = ANTENNA_HW_DIVERSITY;
+ else
+ *rx_ant = active->rx;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_get_antenna);
+
+void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
+ u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct data_queue *queue;
+
+ tx_queue_for_each(rt2x00dev, queue) {
+ *tx += queue->length;
+ *tx_max += queue->limit;
+ }
+
+ *rx = rt2x00dev->rx->length;
+ *rx_max = rt2x00dev->rx->limit;
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_get_ringparam);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 4dd82b0b052..17148bb2442 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -60,14 +60,15 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
}
EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read);
-void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
+bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue = rt2x00dev->rx;
struct queue_entry *entry;
struct queue_entry_priv_pci *entry_priv;
struct skb_frame_desc *skbdesc;
+ int max_rx = 16;
- while (1) {
+ while (--max_rx) {
entry = rt2x00queue_get_entry(queue, Q_INDEX);
entry_priv = entry->priv_data;
@@ -93,9 +94,20 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
*/
rt2x00lib_rxdone(entry);
}
+
+ return !max_rx;
}
EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
+void rt2x00pci_flush_queue(struct data_queue *queue, bool drop)
+{
+ unsigned int i;
+
+ for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++)
+ msleep(10);
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue);
+
/*
* Device initialization handlers.
*/
@@ -239,9 +251,8 @@ exit:
return -ENOMEM;
}
-int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
+int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
{
- struct rt2x00_ops *ops = (struct rt2x00_ops *)id->driver_data;
struct ieee80211_hw *hw;
struct rt2x00_dev *rt2x00dev;
int retval;
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 746ce8fe8cf..e2c99f2b9a1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -101,8 +101,21 @@ struct queue_entry_priv_pci {
/**
* rt2x00pci_rxdone - Handle RX done events
* @rt2x00dev: Device pointer, see &struct rt2x00_dev.
+ *
+ * Returns true if there are still rx frames pending and false if all
+ * pending rx frames were processed.
+ */
+bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
+
+/**
+ * rt2x00pci_flush_queue - Flush data queue
+ * @queue: Data queue to stop
+ * @drop: True to drop all pending frames.
+ *
+ * This will wait for a maximum of 100ms, waiting for the queues
+ * to become empty.
*/
-void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
+void rt2x00pci_flush_queue(struct data_queue *queue, bool drop);
/*
* Device initialization handlers.
@@ -113,7 +126,7 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev);
/*
* PCI driver handlers.
*/
-int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id);
+int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops);
void rt2x00pci_remove(struct pci_dev *pci_dev);
#ifdef CONFIG_PM
int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 4358051bfe1..ab8c16f8bca 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -60,7 +60,7 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry)
* at least 8 bytes bytes available in headroom for IV/EIV
* and 8 bytes for ICV data as tailroon.
*/
- if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
+ if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) {
head_size += 8;
tail_size += 8;
}
@@ -86,7 +86,7 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry)
memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->entry = entry;
- if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) {
+ if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) {
skbdesc->skb_dma = dma_map_single(rt2x00dev->dev,
skb->data,
skb->len,
@@ -148,19 +148,6 @@ void rt2x00queue_align_frame(struct sk_buff *skb)
skb_trim(skb, frame_length);
}
-void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length)
-{
- unsigned int frame_length = skb->len;
- unsigned int align = ALIGN_SIZE(skb, header_length);
-
- if (!align)
- return;
-
- skb_push(skb, align);
- memmove(skb->data, skb->data + align, frame_length);
- skb_trim(skb, frame_length);
-}
-
void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
{
unsigned int payload_length = skb->len - header_length;
@@ -226,7 +213,7 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
__set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
- if (!test_bit(DRIVER_REQUIRE_SW_SEQNO, &entry->queue->rt2x00dev->flags))
+ if (!test_bit(REQUIRE_SW_SEQNO, &entry->queue->rt2x00dev->cap_flags))
return;
/*
@@ -315,6 +302,85 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry,
}
}
+static void rt2x00queue_create_tx_descriptor_ht(struct queue_entry *entry,
+ struct txentry_desc *txdesc,
+ const struct rt2x00_rate *hwrate)
+{
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+ struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
+
+ if (tx_info->control.sta)
+ txdesc->u.ht.mpdu_density =
+ tx_info->control.sta->ht_cap.ampdu_density;
+
+ txdesc->u.ht.ba_size = 7; /* FIXME: What value is needed? */
+
+ /*
+ * Only one STBC stream is supported for now.
+ */
+ if (tx_info->flags & IEEE80211_TX_CTL_STBC)
+ txdesc->u.ht.stbc = 1;
+
+ /*
+ * If IEEE80211_TX_RC_MCS is set txrate->idx just contains the
+ * mcs rate to be used
+ */
+ if (txrate->flags & IEEE80211_TX_RC_MCS) {
+ txdesc->u.ht.mcs = txrate->idx;
+
+ /*
+ * MIMO PS should be set to 1 for STA's using dynamic SM PS
+ * when using more then one tx stream (>MCS7).
+ */
+ if (tx_info->control.sta && txdesc->u.ht.mcs > 7 &&
+ ((tx_info->control.sta->ht_cap.cap &
+ IEEE80211_HT_CAP_SM_PS) >>
+ IEEE80211_HT_CAP_SM_PS_SHIFT) ==
+ WLAN_HT_CAP_SM_PS_DYNAMIC)
+ __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags);
+ } else {
+ txdesc->u.ht.mcs = rt2x00_get_rate_mcs(hwrate->mcs);
+ if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ txdesc->u.ht.mcs |= 0x08;
+ }
+
+ /*
+ * This frame is eligible for an AMPDU, however, don't aggregate
+ * frames that are intended to probe a specific tx rate.
+ */
+ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU &&
+ !(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE))
+ __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags);
+
+ /*
+ * Set 40Mhz mode if necessary (for legacy rates this will
+ * duplicate the frame to both channels).
+ */
+ if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH ||
+ txrate->flags & IEEE80211_TX_RC_DUP_DATA)
+ __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags);
+ if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
+ __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags);
+
+ /*
+ * Determine IFS values
+ * - Use TXOP_BACKOFF for management frames except beacons
+ * - Use TXOP_SIFS for fragment bursts
+ * - Use TXOP_HTTXOP for everything else
+ *
+ * Note: rt2800 devices won't use CTS protection (if used)
+ * for frames not transmitted with TXOP_HTTXOP
+ */
+ if (ieee80211_is_mgmt(hdr->frame_control) &&
+ !ieee80211_is_beacon(hdr->frame_control))
+ txdesc->u.ht.txop = TXOP_BACKOFF;
+ else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT))
+ txdesc->u.ht.txop = TXOP_SIFS;
+ else
+ txdesc->u.ht.txop = TXOP_HTTXOP;
+}
+
static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
@@ -409,8 +475,8 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
rt2x00crypto_create_tx_descriptor(entry, txdesc);
rt2x00queue_create_tx_descriptor_seq(entry, txdesc);
- if (test_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags))
- rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate);
+ if (test_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags))
+ rt2x00queue_create_tx_descriptor_ht(entry, txdesc, hwrate);
else
rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate);
}
@@ -449,7 +515,7 @@ static int rt2x00queue_write_tx_data(struct queue_entry *entry,
/*
* Map the skb to DMA.
*/
- if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
+ if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags))
rt2x00queue_map_txskb(entry);
return 0;
@@ -495,8 +561,11 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
struct skb_frame_desc *skbdesc;
u8 rate_idx, rate_flags;
- if (unlikely(rt2x00queue_full(queue)))
+ if (unlikely(rt2x00queue_full(queue))) {
+ ERROR(queue->rt2x00dev,
+ "Dropping frame due to full tx queue %d.\n", queue->qid);
return -ENOBUFS;
+ }
if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA,
&entry->flags))) {
@@ -539,7 +608,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
*/
if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
- if (test_bit(DRIVER_REQUIRE_COPY_IV, &queue->rt2x00dev->flags))
+ if (test_bit(REQUIRE_COPY_IV, &queue->rt2x00dev->cap_flags))
rt2x00crypto_tx_copy_iv(skb, &txdesc);
else
rt2x00crypto_tx_remove_iv(skb, &txdesc);
@@ -553,9 +622,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
* PCI and USB devices, while header alignment only is valid
* for PCI devices.
*/
- if (test_bit(DRIVER_REQUIRE_L2PAD, &queue->rt2x00dev->flags))
+ if (test_bit(REQUIRE_L2PAD, &queue->rt2x00dev->cap_flags))
rt2x00queue_insert_l2pad(entry->skb, txdesc.header_length);
- else if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags))
+ else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags))
rt2x00queue_align_frame(entry->skb);
/*
@@ -571,7 +640,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
set_bit(ENTRY_DATA_PENDING, &entry->flags);
- rt2x00queue_index_inc(queue, Q_INDEX);
+ rt2x00queue_index_inc(entry, Q_INDEX);
rt2x00queue_write_tx_descriptor(entry, &txdesc);
rt2x00queue_kick_tx_queue(queue, &txdesc);
@@ -660,10 +729,12 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
return ret;
}
-void rt2x00queue_for_each_entry(struct data_queue *queue,
+bool rt2x00queue_for_each_entry(struct data_queue *queue,
enum queue_index start,
enum queue_index end,
- void (*fn)(struct queue_entry *entry))
+ void *data,
+ bool (*fn)(struct queue_entry *entry,
+ void *data))
{
unsigned long irqflags;
unsigned int index_start;
@@ -674,7 +745,7 @@ void rt2x00queue_for_each_entry(struct data_queue *queue,
ERROR(queue->rt2x00dev,
"Entry requested from invalid index range (%d - %d)\n",
start, end);
- return;
+ return true;
}
/*
@@ -693,15 +764,23 @@ void rt2x00queue_for_each_entry(struct data_queue *queue,
* send out all frames in the correct order.
*/
if (index_start < index_end) {
- for (i = index_start; i < index_end; i++)
- fn(&queue->entries[i]);
+ for (i = index_start; i < index_end; i++) {
+ if (fn(&queue->entries[i], data))
+ return true;
+ }
} else {
- for (i = index_start; i < queue->limit; i++)
- fn(&queue->entries[i]);
+ for (i = index_start; i < queue->limit; i++) {
+ if (fn(&queue->entries[i], data))
+ return true;
+ }
- for (i = 0; i < index_end; i++)
- fn(&queue->entries[i]);
+ for (i = 0; i < index_end; i++) {
+ if (fn(&queue->entries[i], data))
+ return true;
+ }
}
+
+ return false;
}
EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry);
@@ -727,8 +806,9 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
}
EXPORT_SYMBOL_GPL(rt2x00queue_get_entry);
-void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
+void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index)
{
+ struct data_queue *queue = entry->queue;
unsigned long irqflags;
if (unlikely(index >= Q_INDEX_MAX)) {
@@ -743,7 +823,7 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
if (queue->index[index] >= queue->limit)
queue->index[index] = 0;
- queue->last_action[index] = jiffies;
+ entry->last_action = jiffies;
if (index == Q_INDEX) {
queue->length++;
@@ -848,7 +928,6 @@ EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue);
void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
{
- unsigned int i;
bool started;
bool tx_queue =
(queue->qid == QID_AC_VO) ||
@@ -883,20 +962,12 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
}
/*
- * Check if driver supports flushing, we can only guarantee
- * full support for flushing if the driver is able
- * to cancel all pending frames (drop = true).
- */
- if (drop && queue->rt2x00dev->ops->lib->flush_queue)
- queue->rt2x00dev->ops->lib->flush_queue(queue);
-
- /*
- * When we don't want to drop any frames, or when
- * the driver doesn't fully flush the queue correcly,
- * we must wait for the queue to become empty.
+ * Check if driver supports flushing, if that is the case we can
+ * defer the flushing to the driver. Otherwise we must use the
+ * alternative which just waits for the queue to become empty.
*/
- for (i = 0; !rt2x00queue_empty(queue) && i < 100; i++)
- msleep(10);
+ if (likely(queue->rt2x00dev->ops->lib->flush_queue))
+ queue->rt2x00dev->ops->lib->flush_queue(queue, drop);
/*
* The queue flush has failed...
@@ -969,10 +1040,8 @@ static void rt2x00queue_reset(struct data_queue *queue)
queue->count = 0;
queue->length = 0;
- for (i = 0; i < Q_INDEX_MAX; i++) {
+ for (i = 0; i < Q_INDEX_MAX; i++)
queue->index[i] = 0;
- queue->last_action[i] = jiffies;
- }
spin_unlock_irqrestore(&queue->index_lock, irqflags);
}
@@ -1079,7 +1148,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev)
if (status)
goto exit;
- if (test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) {
+ if (test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags)) {
status = rt2x00queue_alloc_entries(rt2x00dev->atim,
rt2x00dev->ops->atim);
if (status)
@@ -1131,7 +1200,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
struct data_queue *queue;
enum data_queue_qid qid;
unsigned int req_atim =
- !!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
+ !!test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags);
/*
* We need the following queues:
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 217861f8d95..167d45873dc 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -217,6 +217,7 @@ enum txdone_entry_desc_flags {
TXDONE_FALLBACK,
TXDONE_FAILURE,
TXDONE_EXCESSIVE_RETRY,
+ TXDONE_AMPDU,
};
/**
@@ -363,6 +364,7 @@ enum queue_entry_flags {
* struct queue_entry: Entry inside the &struct data_queue
*
* @flags: Entry flags, see &enum queue_entry_flags.
+ * @last_action: Timestamp of last change.
* @queue: The data queue (&struct data_queue) to which this entry belongs.
* @skb: The buffer which is currently being transmitted (for TX queue),
* or used to directly receive data in (for RX queue).
@@ -372,6 +374,7 @@ enum queue_entry_flags {
*/
struct queue_entry {
unsigned long flags;
+ unsigned long last_action;
struct data_queue *queue;
@@ -462,7 +465,6 @@ struct data_queue {
unsigned short threshold;
unsigned short length;
unsigned short index[Q_INDEX_MAX];
- unsigned long last_action[Q_INDEX_MAX];
unsigned short txop;
unsigned short aifs;
@@ -579,16 +581,22 @@ struct data_queue_desc {
* @queue: Pointer to @data_queue
* @start: &enum queue_index Pointer to start index
* @end: &enum queue_index Pointer to end index
+ * @data: Data to pass to the callback function
* @fn: The function to call for each &struct queue_entry
*
* This will walk through all entries in the queue, in chronological
* order. This means it will start at the current @start pointer
* and will walk through the queue until it reaches the @end pointer.
+ *
+ * If fn returns true for an entry rt2x00queue_for_each_entry will stop
+ * processing and return true as well.
*/
-void rt2x00queue_for_each_entry(struct data_queue *queue,
+bool rt2x00queue_for_each_entry(struct data_queue *queue,
enum queue_index start,
enum queue_index end,
- void (*fn)(struct queue_entry *entry));
+ void *data,
+ bool (*fn)(struct queue_entry *entry,
+ void *data));
/**
* rt2x00queue_empty - Check if the queue is empty.
@@ -628,22 +636,24 @@ static inline int rt2x00queue_threshold(struct data_queue *queue)
/**
* rt2x00queue_status_timeout - Check if a timeout occurred for STATUS reports
- * @queue: Queue to check.
+ * @entry: Queue entry to check.
*/
-static inline int rt2x00queue_status_timeout(struct data_queue *queue)
+static inline int rt2x00queue_status_timeout(struct queue_entry *entry)
{
- return time_after(queue->last_action[Q_INDEX_DMA_DONE],
- queue->last_action[Q_INDEX_DONE] + (HZ / 10));
+ if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
+ return false;
+ return time_after(jiffies, entry->last_action + msecs_to_jiffies(100));
}
/**
- * rt2x00queue_timeout - Check if a timeout occurred for DMA transfers
- * @queue: Queue to check.
+ * rt2x00queue_dma_timeout - Check if a timeout occurred for DMA transfers
+ * @entry: Queue entry to check.
*/
-static inline int rt2x00queue_dma_timeout(struct data_queue *queue)
+static inline int rt2x00queue_dma_timeout(struct queue_entry *entry)
{
- return time_after(queue->last_action[Q_INDEX],
- queue->last_action[Q_INDEX_DMA_DONE] + (HZ / 10));
+ if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ return false;
+ return time_after(jiffies, entry->last_action + msecs_to_jiffies(100));
}
/**
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 36f388f97d6..8f90f626807 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -165,6 +165,59 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev,
}
EXPORT_SYMBOL_GPL(rt2x00usb_regbusy_read);
+
+struct rt2x00_async_read_data {
+ __le32 reg;
+ struct usb_ctrlrequest cr;
+ struct rt2x00_dev *rt2x00dev;
+ bool (*callback)(struct rt2x00_dev *, int, u32);
+};
+
+static void rt2x00usb_register_read_async_cb(struct urb *urb)
+{
+ struct rt2x00_async_read_data *rd = urb->context;
+ if (rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg))) {
+ if (usb_submit_urb(urb, GFP_ATOMIC) < 0)
+ kfree(rd);
+ } else
+ kfree(rd);
+}
+
+void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ bool (*callback)(struct rt2x00_dev*, int, u32))
+{
+ struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
+ struct urb *urb;
+ struct rt2x00_async_read_data *rd;
+
+ rd = kmalloc(sizeof(*rd), GFP_ATOMIC);
+ if (!rd)
+ return;
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ kfree(rd);
+ return;
+ }
+
+ rd->rt2x00dev = rt2x00dev;
+ rd->callback = callback;
+ rd->cr.bRequestType = USB_VENDOR_REQUEST_IN;
+ rd->cr.bRequest = USB_MULTI_READ;
+ rd->cr.wValue = 0;
+ rd->cr.wIndex = cpu_to_le16(offset);
+ rd->cr.wLength = cpu_to_le16(sizeof(u32));
+
+ usb_fill_control_urb(urb, usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+ (unsigned char *)(&rd->cr), &rd->reg, sizeof(rd->reg),
+ rt2x00usb_register_read_async_cb, rd);
+ if (usb_submit_urb(urb, GFP_ATOMIC) < 0)
+ kfree(rd);
+ usb_free_urb(urb);
+}
+EXPORT_SYMBOL_GPL(rt2x00usb_register_read_async);
+
/*
* TX data handlers.
*/
@@ -212,6 +265,9 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
return;
+ if (rt2x00dev->ops->lib->tx_dma_done)
+ rt2x00dev->ops->lib->tx_dma_done(entry);
+
/*
* Report the frame as DMA done
*/
@@ -227,10 +283,12 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
* Schedule the delayed work for reading the TX status
* from the device.
*/
- queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
+ if (!test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags) ||
+ !kfifo_is_empty(&rt2x00dev->txstatus_fifo))
+ queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
}
-static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
+static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void* data)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
@@ -240,7 +298,7 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) ||
test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
- return;
+ return false;
/*
* USB devices cannot blindly pass the skb->len as the
@@ -261,6 +319,8 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
rt2x00lib_dmadone(entry);
}
+
+ return false;
}
/*
@@ -323,7 +383,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work);
}
-static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
+static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void* data)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
@@ -332,7 +392,7 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
- return;
+ return false;
rt2x00lib_dmastart(entry);
@@ -348,6 +408,8 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
rt2x00lib_dmadone(entry);
}
+
+ return false;
}
void rt2x00usb_kick_queue(struct data_queue *queue)
@@ -358,12 +420,18 @@ void rt2x00usb_kick_queue(struct data_queue *queue)
case QID_AC_BE:
case QID_AC_BK:
if (!rt2x00queue_empty(queue))
- rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
+ rt2x00queue_for_each_entry(queue,
+ Q_INDEX_DONE,
+ Q_INDEX,
+ NULL,
rt2x00usb_kick_tx_entry);
break;
case QID_RX:
if (!rt2x00queue_full(queue))
- rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
+ rt2x00queue_for_each_entry(queue,
+ Q_INDEX_DONE,
+ Q_INDEX,
+ NULL,
rt2x00usb_kick_rx_entry);
break;
default:
@@ -372,14 +440,14 @@ void rt2x00usb_kick_queue(struct data_queue *queue)
}
EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue);
-static void rt2x00usb_flush_entry(struct queue_entry *entry)
+static bool rt2x00usb_flush_entry(struct queue_entry *entry, void* data)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
- return;
+ return false;
usb_kill_urb(entry_priv->urb);
@@ -387,17 +455,20 @@ static void rt2x00usb_flush_entry(struct queue_entry *entry)
* Kill guardian urb (if required by driver).
*/
if ((entry->queue->qid == QID_BEACON) &&
- (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
+ (test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags)))
usb_kill_urb(bcn_priv->guardian_urb);
+
+ return false;
}
-void rt2x00usb_flush_queue(struct data_queue *queue)
+void rt2x00usb_flush_queue(struct data_queue *queue, bool drop)
{
struct work_struct *completion;
unsigned int i;
- rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
- rt2x00usb_flush_entry);
+ if (drop)
+ rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL,
+ rt2x00usb_flush_entry);
/*
* Obtain the queue completion handler
@@ -416,7 +487,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue)
return;
}
- for (i = 0; i < 20; i++) {
+ for (i = 0; i < 10; i++) {
/*
* Check if the driver is already done, otherwise we
* have to sleep a little while to give the driver/hw
@@ -456,15 +527,31 @@ static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)
queue_work(queue->rt2x00dev->workqueue, &queue->rt2x00dev->txdone_work);
}
+static int rt2x00usb_status_timeout(struct data_queue *queue)
+{
+ struct queue_entry *entry;
+
+ entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
+ return rt2x00queue_status_timeout(entry);
+}
+
+static int rt2x00usb_dma_timeout(struct data_queue *queue)
+{
+ struct queue_entry *entry;
+
+ entry = rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE);
+ return rt2x00queue_dma_timeout(entry);
+}
+
void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue;
tx_queue_for_each(rt2x00dev, queue) {
if (!rt2x00queue_empty(queue)) {
- if (rt2x00queue_dma_timeout(queue))
+ if (rt2x00usb_dma_timeout(queue))
rt2x00usb_watchdog_tx_dma(queue);
- if (rt2x00queue_status_timeout(queue))
+ if (rt2x00usb_status_timeout(queue))
rt2x00usb_watchdog_tx_status(queue);
}
}
@@ -489,7 +576,7 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
entry->flags = 0;
if (entry->queue->qid == QID_RX)
- rt2x00usb_kick_rx_entry(entry);
+ rt2x00usb_kick_rx_entry(entry, NULL);
}
EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
@@ -583,7 +670,7 @@ static int rt2x00usb_alloc_entries(struct data_queue *queue)
* then we are done.
*/
if (queue->qid != QID_BEACON ||
- !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
+ !test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags))
return 0;
for (i = 0; i < queue->limit; i++) {
@@ -618,7 +705,7 @@ static void rt2x00usb_free_entries(struct data_queue *queue)
* then we are done.
*/
if (queue->qid != QID_BEACON ||
- !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
+ !test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags))
return;
for (i = 0; i < queue->limit; i++) {
@@ -707,10 +794,9 @@ exit:
}
int rt2x00usb_probe(struct usb_interface *usb_intf,
- const struct usb_device_id *id)
+ const struct rt2x00_ops *ops)
{
struct usb_device *usb_dev = interface_to_usbdev(usb_intf);
- struct rt2x00_ops *ops = (struct rt2x00_ops *)id->driver_info;
struct ieee80211_hw *hw;
struct rt2x00_dev *rt2x00dev;
int retval;
@@ -735,6 +821,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone);
INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone);
+ init_timer(&rt2x00dev->txstatus_timer);
retval = rt2x00usb_alloc_reg(rt2x00dev);
if (retval)
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index e11c759ac9e..323ca7b2b09 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -35,12 +35,6 @@
})
/*
- * This variable should be used with the
- * usb_driver structure initialization.
- */
-#define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops)
-
-/*
* For USB vendor requests we need to pass a timeout
* time in ms, for this we use the REGISTER_TIMEOUT,
* however when loading firmware a higher value is
@@ -345,6 +339,23 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev,
const struct rt2x00_field32 field,
u32 *reg);
+/**
+ * rt2x00usb_register_read_async - Asynchronously read 32bit register word
+ * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
+ * @offset: Register offset
+ * @callback: Functon to call when read completes.
+ *
+ * Submit a control URB to read a 32bit register. This safe to
+ * be called from atomic context. The callback will be called
+ * when the URB completes. Otherwise the function is similar
+ * to rt2x00usb_register_read().
+ * When the callback function returns false, the memory will be cleaned up,
+ * when it returns true, the urb will be fired again.
+ */
+void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ bool (*callback)(struct rt2x00_dev*, int, u32));
+
/*
* Radio handlers
*/
@@ -389,11 +400,13 @@ void rt2x00usb_kick_queue(struct data_queue *queue);
/**
* rt2x00usb_flush_queue - Flush data queue
* @queue: Data queue to stop
+ * @drop: True to drop all pending frames.
*
- * This will walk through all entries of the queue and kill all
- * URB's which were send to the device.
+ * This will walk through all entries of the queue and will optionally
+ * kill all URB's which were send to the device, or at least wait until
+ * they have been returned from the device..
*/
-void rt2x00usb_flush_queue(struct data_queue *queue);
+void rt2x00usb_flush_queue(struct data_queue *queue, bool drop);
/**
* rt2x00usb_watchdog - Watchdog for USB communication
@@ -416,7 +429,7 @@ void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev);
* USB driver handlers.
*/
int rt2x00usb_probe(struct usb_interface *usb_intf,
- const struct usb_device_id *id);
+ const struct rt2x00_ops *ops);
void rt2x00usb_disconnect(struct usb_interface *usb_intf);
#ifdef CONFIG_PM
int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 77e8113b91e..9d35ec16a3a 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -683,7 +683,7 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, rt2x00_rf(rt2x00dev, RF2529));
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
- !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
+ !test_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags));
/*
* Configure the RX antenna.
@@ -811,10 +811,10 @@ static void rt61pci_config_ant(struct rt2x00_dev *rt2x00dev,
if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
sel = antenna_sel_a;
- lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
+ lna = test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags);
} else {
sel = antenna_sel_bg;
- lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+ lna = test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags);
}
for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
@@ -834,7 +834,7 @@ static void rt61pci_config_ant(struct rt2x00_dev *rt2x00dev,
else if (rt2x00_rf(rt2x00dev, RF2527))
rt61pci_config_antenna_2x(rt2x00dev, ant);
else if (rt2x00_rf(rt2x00dev, RF2529)) {
- if (test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags))
+ if (test_bit(CAPABILITY_DOUBLE_ANTENNA, &rt2x00dev->cap_flags))
rt61pci_config_antenna_2x(rt2x00dev, ant);
else
rt61pci_config_antenna_2529(rt2x00dev, ant);
@@ -848,13 +848,13 @@ static void rt61pci_config_lna_gain(struct rt2x00_dev *rt2x00dev,
short lna_gain = 0;
if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) {
- if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
+ if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags))
lna_gain += 14;
rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1);
} else {
- if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
+ if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags))
lna_gain += 14;
rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom);
@@ -1050,14 +1050,14 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev,
if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
low_bound = 0x28;
up_bound = 0x48;
- if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
+ if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) {
low_bound += 0x10;
up_bound += 0x10;
}
} else {
low_bound = 0x20;
up_bound = 0x40;
- if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
+ if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) {
low_bound += 0x10;
up_bound += 0x10;
}
@@ -2260,8 +2260,8 @@ static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev)
rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
}
-static void rt61pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
- struct rt2x00_field32 irq_field)
+static inline void rt61pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_field32 irq_field)
{
u32 reg;
@@ -2313,8 +2313,10 @@ static void rt61pci_tbtt_tasklet(unsigned long data)
static void rt61pci_rxdone_tasklet(unsigned long data)
{
struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
- rt2x00pci_rxdone(rt2x00dev);
- rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE);
+ if (rt2x00pci_rxdone(rt2x00dev))
+ rt2x00pci_rxdone(rt2x00dev);
+ else
+ rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE);
}
static void rt61pci_autowake_tasklet(unsigned long data)
@@ -2535,7 +2537,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
* Determine number of antennas.
*/
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2)
- __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_DOUBLE_ANTENNA, &rt2x00dev->cap_flags);
/*
* Identify default antenna configuration.
@@ -2549,20 +2551,20 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
* Read the Frame type.
*/
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE))
- __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags);
/*
* Detect if this device has a hardware controlled radio.
*/
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
- __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
/*
* Read frequency offset and RF programming sequence.
*/
rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_FREQ_SEQ))
- __set_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_RF_SEQUENCE, &rt2x00dev->cap_flags);
rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
@@ -2572,9 +2574,9 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A))
- __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
- __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags);
/*
* When working with a RF2529 chip without double antenna,
@@ -2582,7 +2584,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
* eeprom word.
*/
if (rt2x00_rf(rt2x00dev, RF2529) &&
- !test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) {
+ !test_bit(CAPABILITY_DOUBLE_ANTENNA, &rt2x00dev->cap_flags)) {
rt2x00dev->default_ant.rx =
ANTENNA_A + rt2x00_get_field16(eeprom, EEPROM_NIC_RX_FIXED);
rt2x00dev->default_ant.tx =
@@ -2797,7 +2799,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
spec->supported_bands = SUPPORT_BAND_2GHZ;
spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
- if (!test_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags)) {
+ if (!test_bit(CAPABILITY_RF_SEQUENCE, &rt2x00dev->cap_flags)) {
spec->num_channels = 14;
spec->channels = rf_vals_noseq;
} else {
@@ -2867,16 +2869,16 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
* This device has multiple filters for control frames,
* but has no a separate filter for PS Poll frames.
*/
- __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);
/*
* This device requires firmware and DMA mapped skbs.
*/
- __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
+ __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags);
if (!modparam_nohwcrypt)
- __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
- __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
+ __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
/*
* Set the rssi offset.
@@ -2977,6 +2979,9 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
.get_tsf = rt61pci_get_tsf,
.rfkill_poll = rt2x00mac_rfkill_poll,
.flush = rt2x00mac_flush,
+ .set_antenna = rt2x00mac_set_antenna,
+ .get_antenna = rt2x00mac_get_antenna,
+ .get_ringparam = rt2x00mac_get_ringparam,
};
static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
@@ -3001,6 +3006,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
.start_queue = rt61pci_start_queue,
.kick_queue = rt61pci_kick_queue,
.stop_queue = rt61pci_stop_queue,
+ .flush_queue = rt2x00pci_flush_queue,
.write_tx_desc = rt61pci_write_tx_desc,
.write_beacon = rt61pci_write_beacon,
.clear_beacon = rt61pci_clear_beacon,
@@ -3058,11 +3064,11 @@ static const struct rt2x00_ops rt61pci_ops = {
*/
static DEFINE_PCI_DEVICE_TABLE(rt61pci_device_table) = {
/* RT2561s */
- { PCI_DEVICE(0x1814, 0x0301), PCI_DEVICE_DATA(&rt61pci_ops) },
+ { PCI_DEVICE(0x1814, 0x0301) },
/* RT2561 v2 */
- { PCI_DEVICE(0x1814, 0x0302), PCI_DEVICE_DATA(&rt61pci_ops) },
+ { PCI_DEVICE(0x1814, 0x0302) },
/* RT2661 */
- { PCI_DEVICE(0x1814, 0x0401), PCI_DEVICE_DATA(&rt61pci_ops) },
+ { PCI_DEVICE(0x1814, 0x0401) },
{ 0, }
};
@@ -3077,10 +3083,16 @@ MODULE_FIRMWARE(FIRMWARE_RT2561s);
MODULE_FIRMWARE(FIRMWARE_RT2661);
MODULE_LICENSE("GPL");
+static int rt61pci_probe(struct pci_dev *pci_dev,
+ const struct pci_device_id *id)
+{
+ return rt2x00pci_probe(pci_dev, &rt61pci_ops);
+}
+
static struct pci_driver rt61pci_driver = {
.name = KBUILD_MODNAME,
.id_table = rt61pci_device_table,
- .probe = rt2x00pci_probe,
+ .probe = rt61pci_probe,
.remove = __devexit_p(rt2x00pci_remove),
.suspend = rt2x00pci_suspend,
.resume = rt2x00pci_resume,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 02f1148c577..ad20953cbf0 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -595,7 +595,7 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
switch (ant->rx) {
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
- temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)
+ temp = !test_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags)
&& (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp);
break;
@@ -636,7 +636,7 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
- !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
+ !test_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags));
/*
* Configure the RX antenna.
@@ -709,10 +709,10 @@ static void rt73usb_config_ant(struct rt2x00_dev *rt2x00dev,
if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
sel = antenna_sel_a;
- lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
+ lna = test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags);
} else {
sel = antenna_sel_bg;
- lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+ lna = test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags);
}
for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
@@ -740,7 +740,7 @@ static void rt73usb_config_lna_gain(struct rt2x00_dev *rt2x00dev,
short lna_gain = 0;
if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) {
- if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
+ if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags))
lna_gain += 14;
rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
@@ -930,7 +930,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev,
low_bound = 0x28;
up_bound = 0x48;
- if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
+ if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) {
low_bound += 0x10;
up_bound += 0x10;
}
@@ -946,7 +946,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev,
up_bound = 0x1c;
}
- if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
+ if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) {
low_bound += 0x14;
up_bound += 0x10;
}
@@ -1661,7 +1661,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
}
if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
- if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
+ if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) {
if (lna == 3 || lna == 2)
offset += 10;
} else {
@@ -1899,13 +1899,13 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
* Read the Frame type.
*/
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE))
- __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags);
/*
* Detect if this device has an hardware controlled radio.
*/
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
- __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
/*
* Read frequency offset.
@@ -1919,8 +1919,8 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA)) {
- __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
- __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags);
+ __set_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags);
}
/*
@@ -2200,16 +2200,16 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
* This device has multiple filters for control frames,
* but has no a separate filter for PS Poll frames.
*/
- __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);
/*
* This device requires firmware.
*/
- __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
+ __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
if (!modparam_nohwcrypt)
- __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
- __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
- __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags);
+ __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
+ __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags);
/*
* Set the rssi offset.
@@ -2311,6 +2311,9 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
.get_tsf = rt73usb_get_tsf,
.rfkill_poll = rt2x00mac_rfkill_poll,
.flush = rt2x00mac_flush,
+ .set_antenna = rt2x00mac_set_antenna,
+ .get_antenna = rt2x00mac_get_antenna,
+ .get_ringparam = rt2x00mac_get_ringparam,
};
static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
@@ -2389,114 +2392,113 @@ static const struct rt2x00_ops rt73usb_ops = {
*/
static struct usb_device_id rt73usb_device_table[] = {
/* AboCom */
- { USB_DEVICE(0x07b8, 0xb21b), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x07b8, 0xb21c), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x07b8, 0xb21d), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x07b8, 0xb21e), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x07b8, 0xb21f), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x07b8, 0xb21b) },
+ { USB_DEVICE(0x07b8, 0xb21c) },
+ { USB_DEVICE(0x07b8, 0xb21d) },
+ { USB_DEVICE(0x07b8, 0xb21e) },
+ { USB_DEVICE(0x07b8, 0xb21f) },
/* AL */
- { USB_DEVICE(0x14b2, 0x3c10), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c10) },
/* Amigo */
- { USB_DEVICE(0x148f, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0eb0, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x148f, 0x9021) },
+ { USB_DEVICE(0x0eb0, 0x9021) },
/* AMIT */
- { USB_DEVICE(0x18c5, 0x0002), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x18c5, 0x0002) },
/* Askey */
- { USB_DEVICE(0x1690, 0x0722), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x1690, 0x0722) },
/* ASUS */
- { USB_DEVICE(0x0b05, 0x1723), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0b05, 0x1724), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x0b05, 0x1723) },
+ { USB_DEVICE(0x0b05, 0x1724) },
/* Belkin */
- { USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x050d, 0x905b), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x050d, 0x905c), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x050d, 0x705a) },
+ { USB_DEVICE(0x050d, 0x905b) },
+ { USB_DEVICE(0x050d, 0x905c) },
/* Billionton */
- { USB_DEVICE(0x1631, 0xc019), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x08dd, 0x0120), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x1631, 0xc019) },
+ { USB_DEVICE(0x08dd, 0x0120) },
/* Buffalo */
- { USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0411, 0x00d9), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0411, 0x0137), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x0411, 0x00d8) },
+ { USB_DEVICE(0x0411, 0x00d9) },
+ { USB_DEVICE(0x0411, 0x00f4) },
+ { USB_DEVICE(0x0411, 0x0116) },
+ { USB_DEVICE(0x0411, 0x0119) },
+ { USB_DEVICE(0x0411, 0x0137) },
/* CEIVA */
- { USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x178d, 0x02be) },
/* CNet */
- { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x1371, 0x9022) },
+ { USB_DEVICE(0x1371, 0x9032) },
/* Conceptronic */
- { USB_DEVICE(0x14b2, 0x3c22), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c22) },
/* Corega */
- { USB_DEVICE(0x07aa, 0x002e), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x07aa, 0x002e) },
/* D-Link */
- { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c06), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c03) },
+ { USB_DEVICE(0x07d1, 0x3c04) },
+ { USB_DEVICE(0x07d1, 0x3c06) },
+ { USB_DEVICE(0x07d1, 0x3c07) },
/* Edimax */
- { USB_DEVICE(0x7392, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x7392, 0x7618), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x7392, 0x7318) },
+ { USB_DEVICE(0x7392, 0x7618) },
/* EnGenius */
- { USB_DEVICE(0x1740, 0x3701), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x1740, 0x3701) },
/* Gemtek */
- { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x15a9, 0x0004) },
/* Gigabyte */
- { USB_DEVICE(0x1044, 0x8008), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x1044, 0x800a), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x1044, 0x8008) },
+ { USB_DEVICE(0x1044, 0x800a) },
/* Huawei-3Com */
- { USB_DEVICE(0x1472, 0x0009), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x1472, 0x0009) },
/* Hercules */
- { USB_DEVICE(0x06f8, 0xe002), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x06f8, 0xe010), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x06f8, 0xe020), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x06f8, 0xe002) },
+ { USB_DEVICE(0x06f8, 0xe010) },
+ { USB_DEVICE(0x06f8, 0xe020) },
/* Linksys */
- { USB_DEVICE(0x13b1, 0x0020), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x13b1, 0x0028), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x13b1, 0x0020) },
+ { USB_DEVICE(0x13b1, 0x0023) },
+ { USB_DEVICE(0x13b1, 0x0028) },
/* MSI */
- { USB_DEVICE(0x0db0, 0x4600), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0db0, 0xa861), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0db0, 0xa874), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x0db0, 0x4600) },
+ { USB_DEVICE(0x0db0, 0x6877) },
+ { USB_DEVICE(0x0db0, 0x6874) },
+ { USB_DEVICE(0x0db0, 0xa861) },
+ { USB_DEVICE(0x0db0, 0xa874) },
/* Ovislink */
- { USB_DEVICE(0x1b75, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x1b75, 0x7318) },
/* Ralink */
- { USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0812, 0x3101), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x04bb, 0x093d) },
+ { USB_DEVICE(0x148f, 0x2573) },
+ { USB_DEVICE(0x148f, 0x2671) },
+ { USB_DEVICE(0x0812, 0x3101) },
/* Qcom */
- { USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x18e8, 0x6238), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x18e8, 0x6196) },
+ { USB_DEVICE(0x18e8, 0x6229) },
+ { USB_DEVICE(0x18e8, 0x6238) },
/* Samsung */
- { USB_DEVICE(0x04e8, 0x4471), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x04e8, 0x4471) },
/* Senao */
- { USB_DEVICE(0x1740, 0x7100), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x1740, 0x7100) },
/* Sitecom */
- { USB_DEVICE(0x0df6, 0x0024), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0df6, 0x0027), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0df6, 0x002f), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0df6, 0x90ac), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0024) },
+ { USB_DEVICE(0x0df6, 0x0027) },
+ { USB_DEVICE(0x0df6, 0x002f) },
+ { USB_DEVICE(0x0df6, 0x90ac) },
+ { USB_DEVICE(0x0df6, 0x9712) },
/* Surecom */
- { USB_DEVICE(0x0769, 0x31f3), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x0769, 0x31f3) },
/* Tilgin */
- { USB_DEVICE(0x6933, 0x5001), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x6933, 0x5001) },
/* Philips */
- { USB_DEVICE(0x0471, 0x200a), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x0471, 0x200a) },
/* Planex */
- { USB_DEVICE(0x2019, 0xab01), USB_DEVICE_DATA(&rt73usb_ops) },
- { USB_DEVICE(0x2019, 0xab50), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x2019, 0xab01) },
+ { USB_DEVICE(0x2019, 0xab50) },
/* WideTell */
- { USB_DEVICE(0x7167, 0x3840), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x7167, 0x3840) },
/* Zcom */
- { USB_DEVICE(0x0cde, 0x001c), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x0cde, 0x001c) },
/* ZyXEL */
- { USB_DEVICE(0x0586, 0x3415), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x0586, 0x3415) },
{ 0, }
};
@@ -2508,10 +2510,16 @@ MODULE_DEVICE_TABLE(usb, rt73usb_device_table);
MODULE_FIRMWARE(FIRMWARE_RT2571);
MODULE_LICENSE("GPL");
+static int rt73usb_probe(struct usb_interface *usb_intf,
+ const struct usb_device_id *id)
+{
+ return rt2x00usb_probe(usb_intf, &rt73usb_ops);
+}
+
static struct usb_driver rt73usb_driver = {
.name = KBUILD_MODNAME,
.id_table = rt73usb_device_table,
- .probe = rt2x00usb_probe,
+ .probe = rt73usb_probe,
.disconnect = rt2x00usb_disconnect,
.suspend = rt2x00usb_suspend,
.resume = rt2x00usb_resume,
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig
index ce49e0ce7ca..5aee8b22d74 100644
--- a/drivers/net/wireless/rtlwifi/Kconfig
+++ b/drivers/net/wireless/rtlwifi/Kconfig
@@ -10,6 +10,17 @@ config RTL8192CE
If you choose to build it as a module, it will be called rtl8192ce
+config RTL8192SE
+ tristate "Realtek RTL8192SE/RTL8191SE PCIe Wireless Network Adapter"
+ depends on MAC80211 && EXPERIMENTAL
+ select FW_LOADER
+ select RTLWIFI
+ ---help---
+ This is the driver for Realtek RTL8192SE/RTL8191SE 802.11n PCIe
+ wireless network adapters.
+
+ If you choose to build it as a module, it will be called rtl8192se
+
config RTL8192CU
tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter"
depends on MAC80211 && USB && EXPERIMENTAL
@@ -24,10 +35,10 @@ config RTL8192CU
config RTLWIFI
tristate
- depends on RTL8192CE || RTL8192CU
+ depends on RTL8192CE || RTL8192CU || RTL8192SE
default m
config RTL8192C_COMMON
tristate
- depends on RTL8192CE || RTL8192CU
+ depends on RTL8192CE || RTL8192CU || RTL8192SE
default m
diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile
index ec9393f2479..7acce83c378 100644
--- a/drivers/net/wireless/rtlwifi/Makefile
+++ b/drivers/net/wireless/rtlwifi/Makefile
@@ -22,5 +22,6 @@ endif
obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/
obj-$(CONFIG_RTL8192CE) += rtl8192ce/
obj-$(CONFIG_RTL8192CU) += rtl8192cu/
+obj-$(CONFIG_RTL8192SE) += rtl8192se/
ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 0d7d93e1d39..ccb6da38fe2 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -50,8 +50,9 @@
*3) functions called by core.c
*4) wq & timer callback functions
*5) frame process functions
- *6) sysfs functions
- *7) ...
+ *6) IOT functions
+ *7) sysfs functions
+ *8) ...
*/
/*********************************************************
@@ -59,7 +60,7 @@
* mac80211 init functions
*
*********************************************************/
-static struct ieee80211_channel rtl_channeltable[] = {
+static struct ieee80211_channel rtl_channeltable_2g[] = {
{.center_freq = 2412, .hw_value = 1,},
{.center_freq = 2417, .hw_value = 2,},
{.center_freq = 2422, .hw_value = 3,},
@@ -76,7 +77,34 @@ static struct ieee80211_channel rtl_channeltable[] = {
{.center_freq = 2484, .hw_value = 14,},
};
-static struct ieee80211_rate rtl_ratetable[] = {
+static struct ieee80211_channel rtl_channeltable_5g[] = {
+ {.center_freq = 5180, .hw_value = 36,},
+ {.center_freq = 5200, .hw_value = 40,},
+ {.center_freq = 5220, .hw_value = 44,},
+ {.center_freq = 5240, .hw_value = 48,},
+ {.center_freq = 5260, .hw_value = 52,},
+ {.center_freq = 5280, .hw_value = 56,},
+ {.center_freq = 5300, .hw_value = 60,},
+ {.center_freq = 5320, .hw_value = 64,},
+ {.center_freq = 5500, .hw_value = 100,},
+ {.center_freq = 5520, .hw_value = 104,},
+ {.center_freq = 5540, .hw_value = 108,},
+ {.center_freq = 5560, .hw_value = 112,},
+ {.center_freq = 5580, .hw_value = 116,},
+ {.center_freq = 5600, .hw_value = 120,},
+ {.center_freq = 5620, .hw_value = 124,},
+ {.center_freq = 5640, .hw_value = 128,},
+ {.center_freq = 5660, .hw_value = 132,},
+ {.center_freq = 5680, .hw_value = 136,},
+ {.center_freq = 5700, .hw_value = 140,},
+ {.center_freq = 5745, .hw_value = 149,},
+ {.center_freq = 5765, .hw_value = 153,},
+ {.center_freq = 5785, .hw_value = 157,},
+ {.center_freq = 5805, .hw_value = 161,},
+ {.center_freq = 5825, .hw_value = 165,},
+};
+
+static struct ieee80211_rate rtl_ratetable_2g[] = {
{.bitrate = 10, .hw_value = 0x00,},
{.bitrate = 20, .hw_value = 0x01,},
{.bitrate = 55, .hw_value = 0x02,},
@@ -91,18 +119,57 @@ static struct ieee80211_rate rtl_ratetable[] = {
{.bitrate = 540, .hw_value = 0x0b,},
};
+static struct ieee80211_rate rtl_ratetable_5g[] = {
+ {.bitrate = 60, .hw_value = 0x04,},
+ {.bitrate = 90, .hw_value = 0x05,},
+ {.bitrate = 120, .hw_value = 0x06,},
+ {.bitrate = 180, .hw_value = 0x07,},
+ {.bitrate = 240, .hw_value = 0x08,},
+ {.bitrate = 360, .hw_value = 0x09,},
+ {.bitrate = 480, .hw_value = 0x0a,},
+ {.bitrate = 540, .hw_value = 0x0b,},
+};
+
static const struct ieee80211_supported_band rtl_band_2ghz = {
.band = IEEE80211_BAND_2GHZ,
- .channels = rtl_channeltable,
- .n_channels = ARRAY_SIZE(rtl_channeltable),
+ .channels = rtl_channeltable_2g,
+ .n_channels = ARRAY_SIZE(rtl_channeltable_2g),
- .bitrates = rtl_ratetable,
- .n_bitrates = ARRAY_SIZE(rtl_ratetable),
+ .bitrates = rtl_ratetable_2g,
+ .n_bitrates = ARRAY_SIZE(rtl_ratetable_2g),
.ht_cap = {0},
};
+static struct ieee80211_supported_band rtl_band_5ghz = {
+ .band = IEEE80211_BAND_5GHZ,
+
+ .channels = rtl_channeltable_5g,
+ .n_channels = ARRAY_SIZE(rtl_channeltable_5g),
+
+ .bitrates = rtl_ratetable_5g,
+ .n_bitrates = ARRAY_SIZE(rtl_ratetable_5g),
+
+ .ht_cap = {0},
+};
+
+static const u8 tid_to_ac[] = {
+ 2, /* IEEE80211_AC_BE */
+ 3, /* IEEE80211_AC_BK */
+ 3, /* IEEE80211_AC_BK */
+ 2, /* IEEE80211_AC_BE */
+ 1, /* IEEE80211_AC_VI */
+ 1, /* IEEE80211_AC_VI */
+ 0, /* IEEE80211_AC_VO */
+ 0, /* IEEE80211_AC_VO */
+};
+
+u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid)
+{
+ return tid_to_ac[tid];
+}
+
static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
struct ieee80211_sta_ht_cap *ht_cap)
{
@@ -115,6 +182,9 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
IEEE80211_HT_CAP_SGI_20 |
IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
+ if (rtlpriv->rtlhal.disable_amsdu_8k)
+ ht_cap->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
+
/*
*Maximum length of AMPDU that the STA can receive.
*Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
@@ -159,37 +229,99 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
static void _rtl_init_mac80211(struct ieee80211_hw *hw)
{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
struct ieee80211_supported_band *sband;
- /* <1> use mac->bands as mem for hw->wiphy->bands */
- sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);
- /*
- * <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
- * to default value(1T1R)
- */
- memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz,
- sizeof(struct ieee80211_supported_band));
+ if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY && rtlhal->bandset ==
+ BAND_ON_BOTH) {
+ /* 1: 2.4 G bands */
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);
+
+ /* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
+ * to default value(1T1R) */
+ memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz,
+ sizeof(struct ieee80211_supported_band));
- /* <3> init ht cap base on ant_num */
- _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
- /* <4> set mac->sband to wiphy->sband */
- hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+ /* 2: 5 G bands */
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]);
+
+ /* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ]
+ * to default value(1T1R) */
+ memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), &rtl_band_5ghz,
+ sizeof(struct ieee80211_supported_band));
+
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
+ } else {
+ if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);
+
+ /* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
+ * to default value(1T1R) */
+ memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]),
+ &rtl_band_2ghz,
+ sizeof(struct ieee80211_supported_band));
+
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+ } else if (rtlhal->current_bandtype == BAND_ON_5G) {
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]);
+
+ /* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ]
+ * to default value(1T1R) */
+ memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]),
+ &rtl_band_5ghz,
+ sizeof(struct ieee80211_supported_band));
+
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
+ } else {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
+ ("Err BAND %d\n",
+ rtlhal->current_bandtype));
+ }
+ }
/* <5> set hw caps */
hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_AMPDU_AGGREGATION | /*PS*/
- /*IEEE80211_HW_SUPPORTS_PS | */
- /*IEEE80211_HW_PS_NULLFUNC_STACK | */
- /*IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */
+ IEEE80211_HW_BEACON_FILTER |
+ IEEE80211_HW_AMPDU_AGGREGATION |
IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0;
+ /* swlps or hwlps has been set in diff chip in init_sw_vars */
+ if (rtlpriv->psc.swctrl_lps)
+ hw->flags |= IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK |
+ /* IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */
+ 0;
+
hw->wiphy->interface_modes =
- BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC);
hw->wiphy->rts_threshold = 2347;
@@ -199,9 +331,10 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)
/* TODO: Correct this value for our hw */
/* TODO: define these hard code value */
hw->channel_change_time = 100;
- hw->max_listen_interval = 5;
+ hw->max_listen_interval = 10;
hw->max_rate_tries = 4;
/* hw->max_rates = 1; */
+ hw->sta_data_size = sizeof(struct rtl_sta_info);
/* <6> mac address */
if (is_valid_ether_addr(rtlefuse->dev_addr)) {
@@ -230,6 +363,10 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
(void *)rtl_watchdog_wq_callback);
INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
(void *)rtl_ips_nic_off_wq_callback);
+ INIT_DELAYED_WORK(&rtlpriv->works.ps_work,
+ (void *)rtl_swlps_wq_callback);
+ INIT_DELAYED_WORK(&rtlpriv->works.ps_rfon_wq,
+ (void *)rtl_swlps_rfon_wq_callback);
}
@@ -241,6 +378,8 @@ void rtl_deinit_deferred_work(struct ieee80211_hw *hw)
cancel_delayed_work(&rtlpriv->works.watchdog_wq);
cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq);
+ cancel_delayed_work(&rtlpriv->works.ps_work);
+ cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
}
void rtl_init_rfkill(struct ieee80211_hw *hw)
@@ -251,14 +390,16 @@ void rtl_init_rfkill(struct ieee80211_hw *hw)
bool blocked;
u8 valid = 0;
- radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
+ /*set init state to on */
+ rtlpriv->rfkill.rfkill_state = 1;
+ wiphy_rfkill_set_hw_state(hw->wiphy, 0);
- /*set init state to that of switch */
- rtlpriv->rfkill.rfkill_state = radio_state;
- printk(KERN_INFO "rtlwifi: wireless switch is %s\n",
- rtlpriv->rfkill.rfkill_state ? "on" : "off");
+ radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
if (valid) {
+ printk(KERN_INFO "rtlwifi: wireless switch is %s\n",
+ rtlpriv->rfkill.rfkill_state ? "on" : "off");
+
rtlpriv->rfkill.rfkill_state = radio_state;
blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
@@ -308,6 +449,8 @@ int rtl_init_core(struct ieee80211_hw *hw)
spin_lock_init(&rtlpriv->locks.rf_ps_lock);
spin_lock_init(&rtlpriv->locks.rf_lock);
spin_lock_init(&rtlpriv->locks.lps_lock);
+ spin_lock_init(&rtlpriv->locks.waitq_lock);
+ spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock);
rtlmac->link_state = MAC80211_NOLINK;
@@ -327,12 +470,6 @@ void rtl_init_rx_config(struct ieee80211_hw *hw)
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));
- rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MGT_FILTER,
- (u8 *) (&mac->rx_mgt_filter));
- rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CTRL_FILTER,
- (u8 *) (&mac->rx_ctrl_filter));
- rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_DATA_FILTER,
- (u8 *) (&mac->rx_data_filter));
}
/*********************************************************
@@ -359,28 +496,40 @@ static void _rtl_qurey_shortpreamble_mode(struct ieee80211_hw *hw,
}
static void _rtl_query_shortgi(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
struct rtl_tcb_desc *tcb_desc,
struct ieee80211_tx_info *info)
{
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
u8 rate_flag = info->control.rates[0].flags;
-
+ u8 sgi_40 = 0, sgi_20 = 0, bw_40 = 0;
tcb_desc->use_shortgi = false;
- if (!mac->ht_enable)
+ if (sta == NULL)
+ return;
+
+ sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
+ sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20;
+
+ if (!(sta->ht_cap.ht_supported))
return;
- if (!mac->sgi_40 && !mac->sgi_20)
+ if (!sgi_40 && !sgi_20)
return;
- if ((mac->bw_40 == true) && mac->sgi_40)
+ if (mac->opmode == NL80211_IFTYPE_STATION)
+ bw_40 = mac->bw_40;
+ else if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC)
+ bw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+
+ if ((bw_40 == true) && sgi_40)
tcb_desc->use_shortgi = true;
- else if ((mac->bw_40 == false) && mac->sgi_20)
+ else if ((bw_40 == false) && sgi_20)
tcb_desc->use_shortgi = true;
if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI))
tcb_desc->use_shortgi = false;
-
}
static void _rtl_query_protection_mode(struct ieee80211_hw *hw,
@@ -408,19 +557,25 @@ static void _rtl_query_protection_mode(struct ieee80211_hw *hw,
tcb_desc->rts_enable = true;
tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
}
-
}
static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
struct rtl_tcb_desc *tcb_desc)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_sta_info *sta_entry = NULL;
+ u8 ratr_index = 7;
+ if (sta) {
+ sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+ ratr_index = sta_entry->ratr_index;
+ }
if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) {
- if (mac->opmode == NL80211_IFTYPE_STATION)
+ if (mac->opmode == NL80211_IFTYPE_STATION) {
tcb_desc->ratr_index = 0;
- else if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+ } else if (mac->opmode == NL80211_IFTYPE_ADHOC) {
if (tcb_desc->multicast || tcb_desc->broadcast) {
tcb_desc->hw_rate =
rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M];
@@ -428,36 +583,61 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
} else {
/* TODO */
}
+ tcb_desc->ratr_index = ratr_index;
+ } else if (mac->opmode == NL80211_IFTYPE_AP) {
+ tcb_desc->ratr_index = ratr_index;
}
}
if (rtlpriv->dm.useramask) {
/* TODO we will differentiate adhoc and station futrue */
- tcb_desc->mac_id = 0;
-
- if ((mac->mode == WIRELESS_MODE_N_24G) ||
- (mac->mode == WIRELESS_MODE_N_5G)) {
- tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB;
- } else if (mac->mode & WIRELESS_MODE_G) {
- tcb_desc->ratr_index = RATR_INX_WIRELESS_GB;
- } else if (mac->mode & WIRELESS_MODE_B) {
- tcb_desc->ratr_index = RATR_INX_WIRELESS_B;
+ if (mac->opmode == NL80211_IFTYPE_STATION) {
+ tcb_desc->mac_id = 0;
+
+ if (mac->mode == WIRELESS_MODE_N_24G)
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB;
+ else if (mac->mode == WIRELESS_MODE_N_5G)
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_NG;
+ else if (mac->mode & WIRELESS_MODE_G)
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_GB;
+ else if (mac->mode & WIRELESS_MODE_B)
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_B;
+ else if (mac->mode & WIRELESS_MODE_A)
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_G;
+ } else if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC) {
+ if (NULL != sta) {
+ if (sta->aid > 0)
+ tcb_desc->mac_id = sta->aid + 1;
+ else
+ tcb_desc->mac_id = 1;
+ } else {
+ tcb_desc->mac_id = 0;
+ }
}
}
}
static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
struct rtl_tcb_desc *tcb_desc)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
tcb_desc->packet_bw = false;
-
- if (!mac->bw_40 || !mac->ht_enable)
+ if (!sta)
return;
-
+ if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC) {
+ if (!(sta->ht_cap.ht_supported) ||
+ !(sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
+ return;
+ } else if (mac->opmode == NL80211_IFTYPE_STATION) {
+ if (!mac->bw_40 || !(sta->ht_cap.ht_supported))
+ return;
+ }
if (tcb_desc->multicast || tcb_desc->broadcast)
return;
@@ -484,22 +664,21 @@ static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw)
void rtl_get_tcb_desc(struct ieee80211_hw *hw,
struct ieee80211_tx_info *info,
+ struct ieee80211_sta *sta,
struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
+ struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
struct ieee80211_rate *txrate;
__le16 fc = hdr->frame_control;
- memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+ txrate = ieee80211_get_tx_rate(hw, info);
+ tcb_desc->hw_rate = txrate->hw_value;
if (ieee80211_is_data(fc)) {
- txrate = ieee80211_get_tx_rate(hw, info);
- tcb_desc->hw_rate = txrate->hw_value;
-
/*
- *we set data rate RTL_RC_CCK_RATE1M
+ *we set data rate INX 0
*in rtl_rc.c if skb is special data or
*mgt which need low data rate.
*/
@@ -508,12 +687,11 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,
*So tcb_desc->hw_rate is just used for
*special data and mgt frames
*/
- if (tcb_desc->hw_rate < rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M]) {
+ if (info->control.rates[0].idx == 0 &&
+ ieee80211_is_nullfunc(fc)) {
tcb_desc->use_driver_rate = true;
- tcb_desc->ratr_index = 7;
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_MC;
- tcb_desc->hw_rate =
- rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
tcb_desc->disable_ratefallback = 1;
} else {
/*
@@ -523,7 +701,7 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,
*and N rate will all be controlled by FW
*when tcb_desc->use_driver_rate = false
*/
- if (rtlmac->ht_enable) {
+ if (sta && (sta->ht_cap.ht_supported)) {
tcb_desc->hw_rate = _rtl_get_highest_n_rate(hw);
} else {
if (rtlmac->mode == WIRELESS_MODE_B) {
@@ -541,43 +719,25 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,
else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
tcb_desc->broadcast = 1;
- _rtl_txrate_selectmode(hw, tcb_desc);
- _rtl_query_bandwidth_mode(hw, tcb_desc);
+ _rtl_txrate_selectmode(hw, sta, tcb_desc);
+ _rtl_query_bandwidth_mode(hw, sta, tcb_desc);
_rtl_qurey_shortpreamble_mode(hw, tcb_desc, info);
- _rtl_query_shortgi(hw, tcb_desc, info);
+ _rtl_query_shortgi(hw, sta, tcb_desc, info);
_rtl_query_protection_mode(hw, tcb_desc, info);
} else {
tcb_desc->use_driver_rate = true;
- tcb_desc->ratr_index = 7;
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_MC;
tcb_desc->disable_ratefallback = 1;
tcb_desc->mac_id = 0;
-
- tcb_desc->hw_rate = rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
+ tcb_desc->packet_bw = false;
}
}
EXPORT_SYMBOL(rtl_get_tcb_desc);
-bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
- struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
- __le16 fc = hdr->frame_control;
-
- if (ieee80211_is_auth(fc)) {
- RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
- rtl_ips_nic_on(hw);
-
- mac->link_state = MAC80211_LINKING;
- }
-
- return true;
-}
-
bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
{
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
+ struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
struct rtl_priv *rtlpriv = rtl_priv(hw);
__le16 fc = hdr->frame_control;
u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN));
@@ -622,22 +782,20 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
- __le16 fc = hdr->frame_control;
+ __le16 fc = rtl_get_fc(skb);
u16 ether_type;
u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb);
const struct iphdr *ip;
if (!ieee80211_is_data(fc))
- goto end;
+ return false;
- if (ieee80211_is_nullfunc(fc))
- return true;
ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len +
SNAP_SIZE + PROTOC_TYPE_SIZE);
ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE);
+ /* ether_type = ntohs(ether_type); */
if (ETH_P_IP == ether_type) {
if (IPPROTO_UDP == ip->protocol) {
@@ -686,7 +844,6 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
return true;
}
-end:
return false;
}
@@ -695,61 +852,92 @@ end:
* functions called by core.c
*
*********************************************************/
-int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, u16 tid, u16 *ssn)
+int rtl_tx_agg_start(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_tid_data *tid_data;
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_sta_info *sta_entry = NULL;
- RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
- ("on ra = %pM tid = %d\n", ra, tid));
+ if (sta == NULL)
+ return -EINVAL;
if (unlikely(tid >= MAX_TID_COUNT))
return -EINVAL;
- if (mac->tids[tid].agg.agg_state != RTL_AGG_OFF) {
- RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
- ("Start AGG when state is not RTL_AGG_OFF !\n"));
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ if (!sta_entry)
return -ENXIO;
- }
-
- tid_data = &mac->tids[tid];
- *ssn = SEQ_TO_SN(tid_data->seq_number);
+ tid_data = &sta_entry->tids[tid];
RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
- ("HW queue is empty tid:%d\n", tid));
- tid_data->agg.agg_state = RTL_AGG_ON;
+ ("on ra = %pM tid = %d seq:%d\n", sta->addr, tid,
+ tid_data->seq_number));
+
+ *ssn = tid_data->seq_number;
+ tid_data->agg.agg_state = RTL_AGG_START;
- ieee80211_start_tx_ba_cb_irqsafe(mac->vif, ra, tid);
+ ieee80211_start_tx_ba_cb_irqsafe(mac->vif, sta->addr, tid);
return 0;
}
-int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 * ra, u16 tid)
+int rtl_tx_agg_stop(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u16 tid)
{
- int ssn = -1;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_tid_data *tid_data;
+ struct rtl_sta_info *sta_entry = NULL;
+
+ if (sta == NULL)
+ return -EINVAL;
- if (!ra) {
+ if (!sta->addr) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n"));
return -EINVAL;
}
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
+ ("on ra = %pM tid = %d\n", sta->addr, tid));
+
if (unlikely(tid >= MAX_TID_COUNT))
return -EINVAL;
- if (mac->tids[tid].agg.agg_state != RTL_AGG_ON)
- RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
- ("Stopping AGG while state not ON or starting\n"));
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ tid_data = &sta_entry->tids[tid];
+ sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP;
+
+ ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, sta->addr, tid);
- tid_data = &mac->tids[tid];
- ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
+ return 0;
+}
- mac->tids[tid].agg.agg_state = RTL_AGG_OFF;
+int rtl_tx_agg_oper(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u16 tid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tid_data *tid_data;
+ struct rtl_sta_info *sta_entry = NULL;
- ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, ra, tid);
+ if (sta == NULL)
+ return -EINVAL;
+
+ if (!sta->addr) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n"));
+ return -EINVAL;
+ }
+
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
+ ("on ra = %pM tid = %d\n", sta->addr, tid));
+
+ if (unlikely(tid >= MAX_TID_COUNT))
+ return -EINVAL;
+
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ tid_data = &sta_entry->tids[tid];
+ sta_entry->tids[tid].agg.agg_state = RTL_AGG_OPERATIONAL;
return 0;
}
@@ -768,18 +956,16 @@ void rtl_watchdog_wq_callback(void *data)
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-
bool busytraffic = false;
bool higher_busytraffic = false;
bool higher_busyrxtraffic = false;
- bool higher_busytxtraffic = false;
-
- u8 idx = 0;
+ u8 idx, tid;
u32 rx_cnt_inp4eriod = 0;
u32 tx_cnt_inp4eriod = 0;
u32 aver_rx_cnt_inperiod = 0;
u32 aver_tx_cnt_inperiod = 0;
-
+ u32 aver_tidtx_inperiod[MAX_TID_COUNT] = {0};
+ u32 tidtx_inp4eriod[MAX_TID_COUNT] = {0};
bool enter_ps = false;
if (is_hal_stop(rtlhal))
@@ -793,9 +979,6 @@ void rtl_watchdog_wq_callback(void *data)
mac->cnt_after_linked = 0;
}
- /* <2> DM */
- rtlpriv->cfg->ops->dm_watchdog(hw);
-
/*
*<3> to check if traffic busy, if
* busytraffic we don't change channel
@@ -834,8 +1017,27 @@ void rtl_watchdog_wq_callback(void *data)
/* Extremely high Rx data. */
if (aver_rx_cnt_inperiod > 5000)
higher_busyrxtraffic = true;
+ }
+
+ /* check every tid's tx traffic */
+ for (tid = 0; tid <= 7; tid++) {
+ for (idx = 0; idx <= 2; idx++)
+ rtlpriv->link_info.tidtx_in4period[tid][idx] =
+ rtlpriv->link_info.tidtx_in4period[tid]
+ [idx + 1];
+ rtlpriv->link_info.tidtx_in4period[tid][3] =
+ rtlpriv->link_info.tidtx_inperiod[tid];
+
+ for (idx = 0; idx <= 3; idx++)
+ tidtx_inp4eriod[tid] +=
+ rtlpriv->link_info.tidtx_in4period[tid][idx];
+ aver_tidtx_inperiod[tid] = tidtx_inp4eriod[tid] / 4;
+ if (aver_tidtx_inperiod[tid] > 5000)
+ rtlpriv->link_info.higher_busytxtraffic[tid] =
+ true;
else
- higher_busytxtraffic = false;
+ rtlpriv->link_info.higher_busytxtraffic[tid] =
+ false;
}
if (((rtlpriv->link_info.num_rx_inperiod +
@@ -854,11 +1056,15 @@ void rtl_watchdog_wq_callback(void *data)
rtlpriv->link_info.num_rx_inperiod = 0;
rtlpriv->link_info.num_tx_inperiod = 0;
+ for (tid = 0; tid <= 7; tid++)
+ rtlpriv->link_info.tidtx_inperiod[tid] = 0;
rtlpriv->link_info.busytraffic = busytraffic;
rtlpriv->link_info.higher_busytraffic = higher_busytraffic;
rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic;
+ /* <3> DM */
+ rtlpriv->cfg->ops->dm_watchdog(hw);
}
void rtl_watch_dog_timer_callback(unsigned long data)
@@ -875,6 +1081,268 @@ void rtl_watch_dog_timer_callback(unsigned long data)
/*********************************************************
*
+ * frame process functions
+ *
+ *********************************************************/
+u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie)
+{
+ struct ieee80211_mgmt *mgmt = (void *)data;
+ u8 *pos, *end;
+
+ pos = (u8 *)mgmt->u.beacon.variable;
+ end = data + len;
+ while (pos < end) {
+ if (pos + 2 + pos[1] > end)
+ return NULL;
+
+ if (pos[0] == ie)
+ return pos;
+
+ pos += 2 + pos[1];
+ }
+ return NULL;
+}
+
+/* when we use 2 rx ants we send IEEE80211_SMPS_OFF */
+/* when we use 1 rx ant we send IEEE80211_SMPS_STATIC */
+static struct sk_buff *rtl_make_smps_action(struct ieee80211_hw *hw,
+ enum ieee80211_smps_mode smps, u8 *da, u8 *bssid)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct sk_buff *skb;
+ struct ieee80211_mgmt *action_frame;
+
+ /* 27 = header + category + action + smps mode */
+ skb = dev_alloc_skb(27 + hw->extra_tx_headroom);
+ if (!skb)
+ return NULL;
+
+ skb_reserve(skb, hw->extra_tx_headroom);
+ action_frame = (void *)skb_put(skb, 27);
+ memset(action_frame, 0, 27);
+ memcpy(action_frame->da, da, ETH_ALEN);
+ memcpy(action_frame->sa, rtlefuse->dev_addr, ETH_ALEN);
+ memcpy(action_frame->bssid, bssid, ETH_ALEN);
+ action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ACTION);
+ action_frame->u.action.category = WLAN_CATEGORY_HT;
+ action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS;
+ switch (smps) {
+ case IEEE80211_SMPS_AUTOMATIC:/* 0 */
+ case IEEE80211_SMPS_NUM_MODES:/* 4 */
+ WARN_ON(1);
+ case IEEE80211_SMPS_OFF:/* 1 */ /*MIMO_PS_NOLIMIT*/
+ action_frame->u.action.u.ht_smps.smps_control =
+ WLAN_HT_SMPS_CONTROL_DISABLED;/* 0 */
+ break;
+ case IEEE80211_SMPS_STATIC:/* 2 */ /*MIMO_PS_STATIC*/
+ action_frame->u.action.u.ht_smps.smps_control =
+ WLAN_HT_SMPS_CONTROL_STATIC;/* 1 */
+ break;
+ case IEEE80211_SMPS_DYNAMIC:/* 3 */ /*MIMO_PS_DYNAMIC*/
+ action_frame->u.action.u.ht_smps.smps_control =
+ WLAN_HT_SMPS_CONTROL_DYNAMIC;/* 3 */
+ break;
+ }
+
+ return skb;
+}
+
+int rtl_send_smps_action(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u8 *da, u8 *bssid,
+ enum ieee80211_smps_mode smps)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct sk_buff *skb = rtl_make_smps_action(hw, smps, da, bssid);
+ struct rtl_tcb_desc tcb_desc;
+ memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+
+ if (rtlpriv->mac80211.act_scanning)
+ goto err_free;
+
+ if (!sta)
+ goto err_free;
+
+ if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
+ goto err_free;
+
+ if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
+ goto err_free;
+
+ /* this is a type = mgmt * stype = action frame */
+ if (skb) {
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct rtl_sta_info *sta_entry =
+ (struct rtl_sta_info *) sta->drv_priv;
+ sta_entry->mimo_ps = smps;
+ rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
+
+ info->control.rates[0].idx = 0;
+ info->control.sta = sta;
+ info->band = hw->conf.channel->band;
+ rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);
+ }
+err_free:
+ return 0;
+}
+
+/*********************************************************
+ *
+ * IOT functions
+ *
+ *********************************************************/
+static bool rtl_chk_vendor_ouisub(struct ieee80211_hw *hw,
+ struct octet_string vendor_ie)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ bool matched = false;
+ static u8 athcap_1[] = { 0x00, 0x03, 0x7F };
+ static u8 athcap_2[] = { 0x00, 0x13, 0x74 };
+ static u8 broadcap_1[] = { 0x00, 0x10, 0x18 };
+ static u8 broadcap_2[] = { 0x00, 0x0a, 0xf7 };
+ static u8 broadcap_3[] = { 0x00, 0x05, 0xb5 };
+ static u8 racap[] = { 0x00, 0x0c, 0x43 };
+ static u8 ciscocap[] = { 0x00, 0x40, 0x96 };
+ static u8 marvcap[] = { 0x00, 0x50, 0x43 };
+
+ if (memcmp(vendor_ie.octet, athcap_1, 3) == 0 ||
+ memcmp(vendor_ie.octet, athcap_2, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_ATH;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, broadcap_1, 3) == 0 ||
+ memcmp(vendor_ie.octet, broadcap_2, 3) == 0 ||
+ memcmp(vendor_ie.octet, broadcap_3, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_BROAD;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, racap, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_RAL;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, ciscocap, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_CISCO;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, marvcap, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_MARV;
+ matched = true;
+ }
+
+ return matched;
+}
+
+static bool rtl_find_221_ie(struct ieee80211_hw *hw, u8 *data,
+ unsigned int len)
+{
+ struct ieee80211_mgmt *mgmt = (void *)data;
+ struct octet_string vendor_ie;
+ u8 *pos, *end;
+
+ pos = (u8 *)mgmt->u.beacon.variable;
+ end = data + len;
+ while (pos < end) {
+ if (pos[0] == 221) {
+ vendor_ie.length = pos[1];
+ vendor_ie.octet = &pos[2];
+ if (rtl_chk_vendor_ouisub(hw, vendor_ie))
+ return true;
+ }
+
+ if (pos + 2 + pos[1] > end)
+ return false;
+
+ pos += 2 + pos[1];
+ }
+ return false;
+}
+
+void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct ieee80211_hdr *hdr = (void *)data;
+ u32 vendor = PEER_UNKNOWN;
+
+ static u8 ap3_1[3] = { 0x00, 0x14, 0xbf };
+ static u8 ap3_2[3] = { 0x00, 0x1a, 0x70 };
+ static u8 ap3_3[3] = { 0x00, 0x1d, 0x7e };
+ static u8 ap4_1[3] = { 0x00, 0x90, 0xcc };
+ static u8 ap4_2[3] = { 0x00, 0x0e, 0x2e };
+ static u8 ap4_3[3] = { 0x00, 0x18, 0x02 };
+ static u8 ap4_4[3] = { 0x00, 0x17, 0x3f };
+ static u8 ap4_5[3] = { 0x00, 0x1c, 0xdf };
+ static u8 ap5_1[3] = { 0x00, 0x1c, 0xf0 };
+ static u8 ap5_2[3] = { 0x00, 0x21, 0x91 };
+ static u8 ap5_3[3] = { 0x00, 0x24, 0x01 };
+ static u8 ap5_4[3] = { 0x00, 0x15, 0xe9 };
+ static u8 ap5_5[3] = { 0x00, 0x17, 0x9A };
+ static u8 ap5_6[3] = { 0x00, 0x18, 0xE7 };
+ static u8 ap6_1[3] = { 0x00, 0x17, 0x94 };
+ static u8 ap7_1[3] = { 0x00, 0x14, 0xa4 };
+
+ if (mac->opmode != NL80211_IFTYPE_STATION)
+ return;
+
+ if (mac->link_state == MAC80211_NOLINK) {
+ mac->vendor = PEER_UNKNOWN;
+ return;
+ }
+
+ if (mac->cnt_after_linked > 2)
+ return;
+
+ /* check if this really is a beacon */
+ if (!ieee80211_is_beacon(hdr->frame_control))
+ return;
+
+ /* min. beacon length + FCS_LEN */
+ if (len <= 40 + FCS_LEN)
+ return;
+
+ /* and only beacons from the associated BSSID, please */
+ if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
+ return;
+
+ if (rtl_find_221_ie(hw, data, len))
+ vendor = mac->vendor;
+
+ if ((memcmp(mac->bssid, ap5_1, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_2, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_3, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_4, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_5, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_6, 3) == 0) ||
+ vendor == PEER_ATH) {
+ vendor = PEER_ATH;
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ath find\n"));
+ } else if ((memcmp(mac->bssid, ap4_4, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_5, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_1, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_2, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_3, 3) == 0) ||
+ vendor == PEER_RAL) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ral findn\n"));
+ vendor = PEER_RAL;
+ } else if (memcmp(mac->bssid, ap6_1, 3) == 0 ||
+ vendor == PEER_CISCO) {
+ vendor = PEER_CISCO;
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>cisco find\n"));
+ } else if ((memcmp(mac->bssid, ap3_1, 3) == 0) ||
+ (memcmp(mac->bssid, ap3_2, 3) == 0) ||
+ (memcmp(mac->bssid, ap3_3, 3) == 0) ||
+ vendor == PEER_BROAD) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>broad find\n"));
+ vendor = PEER_BROAD;
+ } else if (memcmp(mac->bssid, ap7_1, 3) == 0 ||
+ vendor == PEER_MARV) {
+ vendor = PEER_MARV;
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>marv find\n"));
+ }
+
+ mac->vendor = vendor;
+}
+
+/*********************************************************
+ *
* sysfs functions
*
*********************************************************/
@@ -940,12 +1408,13 @@ static int __init rtl_core_module_init(void)
if (rtl_rate_control_register())
printk(KERN_ERR "rtlwifi: Unable to register rtl_rc,"
"use default RC !!\n");
+
return 0;
}
static void __exit rtl_core_module_exit(void)
{
- /*RC*/
+ /*RC*/
rtl_rate_control_unregister();
}
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h
index 043045342bc..a91f3eee59c 100644
--- a/drivers/net/wireless/rtlwifi/base.h
+++ b/drivers/net/wireless/rtlwifi/base.h
@@ -24,13 +24,26 @@
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
+ *
*****************************************************************************/
#ifndef __RTL_BASE_H__
#define __RTL_BASE_H__
+enum ap_peer {
+ PEER_UNKNOWN = 0,
+ PEER_RTL = 1,
+ PEER_RTL_92SE = 2,
+ PEER_BROAD = 3,
+ PEER_RAL = 4,
+ PEER_ATH = 5,
+ PEER_CISCO = 6,
+ PEER_MARV = 7,
+ PEER_AIRGO = 9,
+ PEER_MAX = 10,
+} ;
+
#define RTL_DUMMY_OFFSET 0
-#define RTL_RX_DESC_SIZE 24
#define RTL_DUMMY_UNIT 8
#define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT)
#define RTL_TX_DESC_SIZE 32
@@ -53,6 +66,14 @@
#define FRAME_OFFSET_SEQUENCE 22
#define FRAME_OFFSET_ADDRESS4 24
+#define SET_80211_HDR_FRAME_CONTROL(_hdr, _val) \
+ WRITEEF2BYTE(_hdr, _val)
+#define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val) \
+ WRITEEF1BYTE(_hdr, _val)
+#define SET_80211_HDR_PWR_MGNT(_hdr, _val) \
+ SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val)
+#define SET_80211_HDR_TO_DS(_hdr, _val) \
+ SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val)
#define SET_80211_PS_POLL_AID(_hdr, _val) \
(*(u16 *)((u8 *)(_hdr) + 2) = le16_to_cpu(_val))
@@ -64,11 +85,27 @@
#define SET_80211_HDR_DURATION(_hdr, _val) \
(*(u16 *)((u8 *)(_hdr) + FRAME_OFFSET_DURATION) = le16_to_cpu(_val))
#define SET_80211_HDR_ADDRESS1(_hdr, _val) \
- memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val), ETH_ALEN)
+ CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8 *)(_val))
#define SET_80211_HDR_ADDRESS2(_hdr, _val) \
- memcpy((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val), ETH_ALEN)
+ CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS2, (u8 *)(_val))
#define SET_80211_HDR_ADDRESS3(_hdr, _val) \
- memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val), ETH_ALEN)
+ CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val))
+#define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val) \
+ WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val)
+
+#define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val) \
+ WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val)
+#define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \
+ WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val)
+#define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \
+ WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val)
+#define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) \
+ READEF2BYTE(((u8 *)(__phdr)) + 34)
+#define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
+ WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val)
+#define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
+ SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \
+ (GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val))))
int rtl_init_core(struct ieee80211_hw *hw);
void rtl_deinit_core(struct ieee80211_hw *hw);
@@ -80,18 +117,27 @@ void rtl_watch_dog_timer_callback(unsigned long data);
void rtl_deinit_deferred_work(struct ieee80211_hw *hw);
bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
-bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
void rtl_watch_dog_timer_callback(unsigned long data);
-int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra,
+int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
u16 tid, u16 *ssn);
-int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 *ra, u16 tid);
+int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ u16 tid);
+int rtl_tx_agg_oper(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ u16 tid);
void rtl_watchdog_wq_callback(void *data);
void rtl_get_tcb_desc(struct ieee80211_hw *hw,
struct ieee80211_tx_info *info,
+ struct ieee80211_sta *sta,
struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc);
+int rtl_send_smps_action(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u8 *da, u8 *bssid,
+ enum ieee80211_smps_mode smps);
+u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie);
+void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len);
+u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid);
extern struct attribute_group rtl_attribute_group;
#endif
diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c
index 52c9c1367ca..7295af0536b 100644
--- a/drivers/net/wireless/rtlwifi/cam.c
+++ b/drivers/net/wireless/rtlwifi/cam.c
@@ -23,6 +23,8 @@
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
*****************************************************************************/
#include "wifi.h"
@@ -49,7 +51,7 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
u32 target_content = 0;
u8 entry_i;
- RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
("key_cont_128:\n %x:%x:%x:%x:%x:%x\n",
key_cont_128[0], key_cont_128[1],
key_cont_128[2], key_cont_128[3],
@@ -68,15 +70,13 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
target_command);
- RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
- ("rtl_cam_program_entry(): "
- "WRITE %x: %x\n",
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ ("WRITE %x: %x\n",
rtlpriv->cfg->maps[WCAMI], target_content));
- RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
("The Key ID is %d\n", entry_no));
- RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
- ("rtl_cam_program_entry(): "
- "WRITE %x: %x\n",
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ ("WRITE %x: %x\n",
rtlpriv->cfg->maps[RWCAM], target_command));
} else if (entry_i == 1) {
@@ -91,12 +91,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
target_command);
- RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
- ("rtl_cam_program_entry(): WRITE A4: %x\n",
- target_content));
- RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
- ("rtl_cam_program_entry(): WRITE A0: %x\n",
- target_command));
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ ("WRITE A4: %x\n", target_content));
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ ("WRITE A0: %x\n", target_command));
} else {
@@ -113,16 +111,14 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
target_command);
udelay(100);
- RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
- ("rtl_cam_program_entry(): WRITE A4: %x\n",
- target_content));
- RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
- ("rtl_cam_program_entry(): WRITE A0: %x\n",
- target_command));
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ ("WRITE A4: %x\n", target_content));
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ ("WRITE A0: %x\n", target_command));
}
}
- RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
("after set key, usconfig:%x\n", us_config));
}
@@ -289,3 +285,71 @@ void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index)
}
EXPORT_SYMBOL(rtl_cam_empty_entry);
+
+u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> 4;
+ u8 entry_idx = 0;
+ u8 i, *addr;
+
+ if (NULL == sta_addr) {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
+ ("sta_addr is NULL.\n"));
+ return TOTAL_CAM_ENTRY;
+ }
+ /* Does STA already exist? */
+ for (i = 4; i < TOTAL_CAM_ENTRY; i++) {
+ addr = rtlpriv->sec.hwsec_cam_sta_addr[i];
+ if (memcmp(addr, sta_addr, ETH_ALEN) == 0)
+ return i;
+ }
+ /* Get a free CAM entry. */
+ for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) {
+ if ((bitmap & BIT(0)) == 0) {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
+ ("-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n",
+ rtlpriv->sec.hwsec_cam_bitmap, entry_idx));
+ rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx;
+ memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx],
+ sta_addr, ETH_ALEN);
+ return entry_idx;
+ }
+ bitmap = bitmap >> 1;
+ }
+ return TOTAL_CAM_ENTRY;
+}
+EXPORT_SYMBOL(rtl_cam_get_free_entry);
+
+void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 bitmap;
+ u8 i, *addr;
+
+ if (NULL == sta_addr) {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
+ ("sta_addr is NULL.\n"));
+ }
+
+ if ((sta_addr[0]|sta_addr[1]|sta_addr[2]|sta_addr[3]|\
+ sta_addr[4]|sta_addr[5]) == 0) {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
+ ("sta_addr is 00:00:00:00:00:00.\n"));
+ return;
+ }
+ /* Does STA already exist? */
+ for (i = 4; i < TOTAL_CAM_ENTRY; i++) {
+ addr = rtlpriv->sec.hwsec_cam_sta_addr[i];
+ bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> i;
+ if (((bitmap & BIT(0)) == BIT(0)) &&
+ (memcmp(addr, sta_addr, ETH_ALEN) == 0)) {
+ /* Remove from HW Security CAM */
+ memset(rtlpriv->sec.hwsec_cam_sta_addr[i], 0, ETH_ALEN);
+ rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i);
+ printk(KERN_INFO "&&&&&&&&&del entry %d\n", i);
+ }
+ }
+ return;
+}
+EXPORT_SYMBOL(rtl_cam_del_entry);
diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/rtlwifi/cam.h
index dd82f057d53..c62da4eefc7 100644
--- a/drivers/net/wireless/rtlwifi/cam.h
+++ b/drivers/net/wireless/rtlwifi/cam.h
@@ -23,12 +23,13 @@
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
*****************************************************************************/
#ifndef __RTL_CAM_H_
#define __RTL_CAM_H_
-#define TOTAL_CAM_ENTRY 32
#define CAM_CONTENT_COUNT 8
#define CFG_DEFAULT_KEY BIT(5)
@@ -49,5 +50,7 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index);
void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index);
void rtl_cam_reset_sec_info(struct ieee80211_hw *hw);
+u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr);
+void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr);
#endif
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index e4f4aee8f29..fc89cd8c832 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -24,6 +24,7 @@
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
+ *
*****************************************************************************/
#include "wifi.h"
@@ -35,7 +36,7 @@
/*mutex for start & stop is must here. */
static int rtl_op_start(struct ieee80211_hw *hw)
{
- int err = 0;
+ int err;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
@@ -45,10 +46,8 @@ static int rtl_op_start(struct ieee80211_hw *hw)
return 0;
mutex_lock(&rtlpriv->locks.conf_mutex);
err = rtlpriv->intf_ops->adapter_start(hw);
- if (err)
- goto out;
- rtl_watch_dog_timer_callback((unsigned long)hw);
-out:
+ if (!err)
+ rtl_watch_dog_timer_callback((unsigned long)hw);
mutex_unlock(&rtlpriv->locks.conf_mutex);
return err;
}
@@ -72,6 +71,7 @@ static void rtl_op_stop(struct ieee80211_hw *hw)
mac->link_state = MAC80211_NOLINK;
memset(mac->bssid, 0, 6);
+ mac->vendor = PEER_UNKNOWN;
/*reset sec info */
rtl_cam_reset_sec_info(hw);
@@ -87,6 +87,8 @@ static void rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_tcb_desc tcb_desc;
+ memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
goto err_free;
@@ -94,8 +96,8 @@ static void rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
goto err_free;
-
- rtlpriv->intf_ops->adapter_tx(hw, skb);
+ if (!rtlpriv->intf_ops->waitq_insert(hw, skb))
+ rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);
return;
@@ -136,10 +138,26 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
mac->link_state = MAC80211_LINKED;
rtlpriv->cfg->ops->set_bcn_reg(hw);
+ if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
+ mac->basic_rates = 0xfff;
+ else
+ mac->basic_rates = 0xff0;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+ (u8 *) (&mac->basic_rates));
+
break;
case NL80211_IFTYPE_AP:
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
("NL80211_IFTYPE_AP\n"));
+
+ mac->link_state = MAC80211_LINKED;
+ rtlpriv->cfg->ops->set_bcn_reg(hw);
+ if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
+ mac->basic_rates = 0xfff;
+ else
+ mac->basic_rates = 0xff0;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+ (u8 *) (&mac->basic_rates));
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
@@ -186,13 +204,12 @@ static void rtl_op_remove_interface(struct ieee80211_hw *hw,
mac->vif = NULL;
mac->link_state = MAC80211_NOLINK;
memset(mac->bssid, 0, 6);
+ mac->vendor = PEER_UNKNOWN;
mac->opmode = NL80211_IFTYPE_UNSPECIFIED;
rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
-
mutex_unlock(&rtlpriv->locks.conf_mutex);
}
-
static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -224,10 +241,25 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
/*For LPS */
if (changed & IEEE80211_CONF_CHANGE_PS) {
- if (conf->flags & IEEE80211_CONF_PS)
- rtl_lps_enter(hw);
- else
- rtl_lps_leave(hw);
+ cancel_delayed_work(&rtlpriv->works.ps_work);
+ cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
+ if (conf->flags & IEEE80211_CONF_PS) {
+ rtlpriv->psc.sw_ps_enabled = true;
+ /* sleep here is must, or we may recv the beacon and
+ * cause mac80211 into wrong ps state, this will cause
+ * power save nullfunc send fail, and further cause
+ * pkt loss, So sleep must quickly but not immediatly
+ * because that will cause nullfunc send by mac80211
+ * fail, and cause pkt loss, we have tested that 5mA
+ * is worked very well */
+ if (!rtlpriv->psc.multi_buffered)
+ queue_delayed_work(rtlpriv->works.rtl_wq,
+ &rtlpriv->works.ps_work,
+ MSECS(5));
+ } else {
+ rtl_swlps_rf_awake(hw);
+ rtlpriv->psc.sw_ps_enabled = false;
+ }
}
if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
@@ -259,7 +291,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
case NL80211_CHAN_NO_HT:
/* SC */
mac->cur_40_prime_sc =
- PRIME_CHNL_OFFSET_DONT_CARE;
+ PRIME_CHNL_OFFSET_DONT_CARE;
rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20;
mac->bw_40 = false;
break;
@@ -267,7 +299,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
/* SC */
mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER;
rtlphy->current_chan_bw =
- HT_CHANNEL_WIDTH_20_40;
+ HT_CHANNEL_WIDTH_20_40;
mac->bw_40 = true;
/*wide channel */
@@ -278,7 +310,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
/* SC */
mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER;
rtlphy->current_chan_bw =
- HT_CHANNEL_WIDTH_20_40;
+ HT_CHANNEL_WIDTH_20_40;
mac->bw_40 = true;
/*wide channel */
@@ -288,16 +320,29 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
default:
mac->bw_40 = false;
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
- ("switch case not processed\n"));
+ ("switch case not processed\n"));
break;
}
if (wide_chan <= 0)
wide_chan = 1;
+
+ /* In scanning, before we go offchannel we may send a ps=1 null
+ * to AP, and then we may send a ps = 0 null to AP quickly, but
+ * first null may have caused AP to put lots of packet to hw tx
+ * buffer. These packets must be tx'd before we go off channel
+ * so we must delay more time to let AP flush these packets
+ * before going offchannel, or dis-association or delete BA will
+ * happen by AP
+ */
+ if (rtlpriv->mac80211.offchan_deley) {
+ rtlpriv->mac80211.offchan_deley = false;
+ mdelay(50);
+ }
rtlphy->current_channel = wide_chan;
- rtlpriv->cfg->ops->set_channel_access(hw);
rtlpriv->cfg->ops->switch_channel(hw);
+ rtlpriv->cfg->ops->set_channel_access(hw);
rtlpriv->cfg->ops->set_bw_mode(hw,
hw->conf.channel_type);
}
@@ -345,27 +390,28 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,
}
}
- if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
- /*
- *TODO: BIT(5) is probe response BIT(8) is beacon
- *TODO: Use define for BIT(5) and BIT(8)
- */
- if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
- mac->rx_mgt_filter |= (BIT(5) | BIT(8));
- else
- mac->rx_mgt_filter &= ~(BIT(5) | BIT(8));
+ /* if ssid not set to hw don't check bssid
+ * here just used for linked scanning, & linked
+ * and nolink check bssid is set in set network_type */
+ if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) &&
+ (mac->link_state >= MAC80211_LINKED)) {
+ if (mac->opmode != NL80211_IFTYPE_AP) {
+ if (*new_flags & FIF_BCN_PRBRESP_PROMISC) {
+ rtlpriv->cfg->ops->set_chk_bssid(hw, false);
+ } else {
+ rtlpriv->cfg->ops->set_chk_bssid(hw, true);
+ }
+ }
}
if (changed_flags & FIF_CONTROL) {
if (*new_flags & FIF_CONTROL) {
mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];
- mac->rx_ctrl_filter |= RTL_SUPPORTED_CTRL_FILTER;
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
("Enable receive control frame.\n"));
} else {
mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];
- mac->rx_ctrl_filter &= ~RTL_SUPPORTED_CTRL_FILTER;
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
("Disable receive control frame.\n"));
}
@@ -382,14 +428,54 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,
("Disable receive other BSS's frame.\n"));
}
}
-
- rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));
- rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MGT_FILTER,
- (u8 *) (&mac->rx_mgt_filter));
- rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CTRL_FILTER,
- (u8 *) (&mac->rx_ctrl_filter));
}
+static int rtl_op_sta_add(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_sta_info *sta_entry;
+
+ if (sta) {
+ sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+ if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+ sta_entry->wireless_mode = WIRELESS_MODE_G;
+ if (sta->supp_rates[0] <= 0xf)
+ sta_entry->wireless_mode = WIRELESS_MODE_B;
+ if (sta->ht_cap.ht_supported == true)
+ sta_entry->wireless_mode = WIRELESS_MODE_N_24G;
+ } else if (rtlhal->current_bandtype == BAND_ON_5G) {
+ sta_entry->wireless_mode = WIRELESS_MODE_A;
+ if (sta->ht_cap.ht_supported == true)
+ sta_entry->wireless_mode = WIRELESS_MODE_N_24G;
+ }
+
+ /* I found some times mac80211 give wrong supp_rates for adhoc*/
+ if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
+ sta_entry->wireless_mode = WIRELESS_MODE_G;
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ ("Add sta addr is "MAC_FMT"\n", MAC_ARG(sta->addr)));
+ rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
+ }
+ return 0;
+}
+static int rtl_op_sta_remove(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_sta_info *sta_entry;
+ if (sta) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ ("Remove sta addr is "MAC_FMT"\n", MAC_ARG(sta->addr)));
+ sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+ sta_entry->wireless_mode = 0;
+ sta_entry->ratr_index = 0;
+ }
+ return 0;
+}
static int _rtl_get_hal_qnum(u16 queue)
{
int qnum;
@@ -446,19 +532,18 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss_conf, u32 changed)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct ieee80211_sta *sta = NULL;
mutex_lock(&rtlpriv->locks.conf_mutex);
-
if ((vif->type == NL80211_IFTYPE_ADHOC) ||
(vif->type == NL80211_IFTYPE_AP) ||
(vif->type == NL80211_IFTYPE_MESH_POINT)) {
-
if ((changed & BSS_CHANGED_BEACON) ||
(changed & BSS_CHANGED_BEACON_ENABLED &&
bss_conf->enable_beacon)) {
-
if (mac->beacon_enabled == 0) {
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
("BSS_CHANGED_BEACON_ENABLED\n"));
@@ -470,8 +555,13 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
rtlpriv->cfg->maps
[RTL_IBSS_INT_MASKS],
0);
+
+ if (rtlpriv->cfg->ops->linked_set_reg)
+ rtlpriv->cfg->ops->linked_set_reg(hw);
}
- } else {
+ }
+ if ((changed & BSS_CHANGED_BEACON_ENABLED &&
+ !bss_conf->enable_beacon)) {
if (mac->beacon_enabled == 1) {
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
("ADHOC DISABLE BEACON\n"));
@@ -482,7 +572,6 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
[RTL_IBSS_INT_MASKS]);
}
}
-
if (changed & BSS_CHANGED_BEACON_INT) {
RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE,
("BSS_CHANGED_BEACON_INT\n"));
@@ -494,11 +583,25 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
/*TODO: reference to enum ieee80211_bss_change */
if (changed & BSS_CHANGED_ASSOC) {
if (bss_conf->assoc) {
+ /* we should reset all sec info & cam
+ * before set cam after linked, we should not
+ * reset in disassoc, that will cause tkip->wep
+ * fail because some flag will be wrong */
+ /* reset sec info */
+ rtl_cam_reset_sec_info(hw);
+ /* reset cam to fix wep fail issue
+ * when change from wpa to wep */
+ rtl_cam_reset_all_entry(hw);
+
mac->link_state = MAC80211_LINKED;
mac->cnt_after_linked = 0;
mac->assoc_id = bss_conf->aid;
memcpy(mac->bssid, bss_conf->bssid, 6);
+ if (rtlpriv->cfg->ops->linked_set_reg)
+ rtlpriv->cfg->ops->linked_set_reg(hw);
+ if (mac->opmode == NL80211_IFTYPE_STATION && sta)
+ rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
("BSS_CHANGED_ASSOC\n"));
} else {
@@ -507,9 +610,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
mac->link_state = MAC80211_NOLINK;
memset(mac->bssid, 0, 6);
-
- /* reset sec info */
- rtl_cam_reset_sec_info(hw);
+ mac->vendor = PEER_UNKNOWN;
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
("BSS_CHANGED_UN_ASSOC\n"));
@@ -546,14 +647,10 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_HT) {
- struct ieee80211_sta *sta = NULL;
-
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
("BSS_CHANGED_HT\n"));
-
rcu_read_lock();
- sta = ieee80211_find_sta(mac->vif, mac->bssid);
-
+ sta = get_sta(hw, vif, (u8 *)bss_conf->bssid);
if (sta) {
if (sta->ht_cap.ampdu_density >
mac->current_ampdu_density)
@@ -575,9 +672,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_BSSID) {
- struct ieee80211_sta *sta = NULL;
u32 basic_rates;
- u8 i;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID,
(u8 *) bss_conf->bssid);
@@ -585,96 +680,65 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
(MAC_FMT "\n", MAC_ARG(bss_conf->bssid)));
+ mac->vendor = PEER_UNKNOWN;
memcpy(mac->bssid, bss_conf->bssid, 6);
- if (is_valid_ether_addr(bss_conf->bssid)) {
- switch (vif->type) {
- case NL80211_IFTYPE_UNSPECIFIED:
- break;
- case NL80211_IFTYPE_ADHOC:
- break;
- case NL80211_IFTYPE_STATION:
- break;
- case NL80211_IFTYPE_AP:
- break;
- default:
- RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
- ("switch case not process\n"));
- break;
- }
- rtlpriv->cfg->ops->set_network_type(hw, vif->type);
- } else
- rtlpriv->cfg->ops->set_network_type(hw,
- NL80211_IFTYPE_UNSPECIFIED);
-
- memset(mac->mcs, 0, 16);
- mac->ht_enable = false;
- mac->sgi_40 = false;
- mac->sgi_20 = false;
-
- if (!bss_conf->use_short_slot)
- mac->mode = WIRELESS_MODE_B;
- else
- mac->mode = WIRELESS_MODE_G;
+ rtlpriv->cfg->ops->set_network_type(hw, vif->type);
rcu_read_lock();
- sta = ieee80211_find_sta(mac->vif, mac->bssid);
+ sta = get_sta(hw, vif, (u8 *)bss_conf->bssid);
+ if (!sta) {
+ rcu_read_unlock();
+ goto out;
+ }
- if (sta) {
- if (sta->ht_cap.ht_supported) {
+ if (rtlhal->current_bandtype == BAND_ON_5G) {
+ mac->mode = WIRELESS_MODE_A;
+ } else {
+ if (sta->supp_rates[0] <= 0xf)
+ mac->mode = WIRELESS_MODE_B;
+ else
+ mac->mode = WIRELESS_MODE_G;
+ }
+
+ if (sta->ht_cap.ht_supported) {
+ if (rtlhal->current_bandtype == BAND_ON_2_4G)
mac->mode = WIRELESS_MODE_N_24G;
- mac->ht_enable = true;
- }
+ else
+ mac->mode = WIRELESS_MODE_N_5G;
+ }
- if (mac->ht_enable) {
- u16 ht_cap = sta->ht_cap.cap;
- memcpy(mac->mcs, (u8 *) (&sta->ht_cap.mcs), 16);
-
- for (i = 0; i < 16; i++)
- RT_TRACE(rtlpriv, COMP_MAC80211,
- DBG_LOUD, ("%x ",
- mac->mcs[i]));
- RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
- ("\n"));
-
- if (ht_cap & IEEE80211_HT_CAP_SGI_40)
- mac->sgi_40 = true;
-
- if (ht_cap & IEEE80211_HT_CAP_SGI_20)
- mac->sgi_20 = true;
-
- /*
- * for cisco 1252 bw20 it's wrong
- * if (ht_cap &
- * IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
- * mac->bw_40 = true;
- * }
- */
- }
+ /* just station need it, because ibss & ap mode will
+ * set in sta_add, and will be NULL here */
+ if (mac->opmode == NL80211_IFTYPE_STATION) {
+ struct rtl_sta_info *sta_entry;
+ sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+ sta_entry->wireless_mode = mac->mode;
+ }
+
+ if (sta->ht_cap.ht_supported) {
+ mac->ht_enable = true;
+
+ /*
+ * for cisco 1252 bw20 it's wrong
+ * if (ht_cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
+ * mac->bw_40 = true;
+ * }
+ * */
}
- rcu_read_unlock();
- /*mac80211 just give us CCK rates any time
- *So we add G rate in basic rates when
- not in B mode*/
if (changed & BSS_CHANGED_BASIC_RATES) {
- if (mac->mode == WIRELESS_MODE_B)
- basic_rates = bss_conf->basic_rates | 0x00f;
+ /* for 5G must << RATE_6M_INDEX=4,
+ * because 5G have no cck rate*/
+ if (rtlhal->current_bandtype == BAND_ON_5G)
+ basic_rates = sta->supp_rates[1] << 4;
else
- basic_rates = bss_conf->basic_rates | 0xff0;
-
- if (!vif)
- goto out;
+ basic_rates = sta->supp_rates[0];
mac->basic_rates = basic_rates;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
(u8 *) (&basic_rates));
-
- if (rtlpriv->dm.useramask)
- rtlpriv->cfg->ops->update_rate_mask(hw, 0);
- else
- rtlpriv->cfg->ops->update_rate_table(hw);
-
}
+ rcu_read_unlock();
}
/*
@@ -760,16 +824,17 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
case IEEE80211_AMPDU_TX_START:
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
("IEEE80211_AMPDU_TX_START: TID:%d\n", tid));
- return rtl_tx_agg_start(hw, sta->addr, tid, ssn);
+ return rtl_tx_agg_start(hw, sta, tid, ssn);
break;
case IEEE80211_AMPDU_TX_STOP:
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid));
- return rtl_tx_agg_stop(hw, sta->addr, tid);
+ return rtl_tx_agg_stop(hw, sta, tid);
break;
case IEEE80211_AMPDU_TX_OPERATIONAL:
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid));
+ rtl_tx_agg_oper(hw, sta, tid);
break;
case IEEE80211_AMPDU_RX_START:
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
@@ -799,8 +864,12 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw)
if (mac->link_state == MAC80211_LINKED) {
rtl_lps_leave(hw);
mac->link_state = MAC80211_LINKED_SCANNING;
- } else
+ } else {
rtl_ips_nic_on(hw);
+ }
+
+ /* Dual mac */
+ rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;
rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY);
rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP);
@@ -812,22 +881,19 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw)
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n"));
-
- rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);
mac->act_scanning = false;
+ /* Dual mac */
+ rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;
+
if (mac->link_state == MAC80211_LINKED_SCANNING) {
mac->link_state = MAC80211_LINKED;
-
- /* fix fwlps issue */
- rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
-
- if (rtlpriv->dm.useramask)
- rtlpriv->cfg->ops->update_rate_mask(hw, 0);
- else
- rtlpriv->cfg->ops->update_rate_table(hw);
-
+ if (mac->opmode == NL80211_IFTYPE_STATION) {
+ /* fix fwlps issue */
+ rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
+ }
}
+ rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);
}
static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -858,49 +924,73 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
rtl_ips_nic_on(hw);
mutex_lock(&rtlpriv->locks.conf_mutex);
/* <1> get encryption alg */
+
switch (key->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
key_type = WEP40_ENCRYPTION;
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n"));
- rtlpriv->sec.use_defaultkey = true;
break;
case WLAN_CIPHER_SUITE_WEP104:
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
("alg:WEP104\n"));
key_type = WEP104_ENCRYPTION;
- rtlpriv->sec.use_defaultkey = true;
break;
case WLAN_CIPHER_SUITE_TKIP:
key_type = TKIP_ENCRYPTION;
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n"));
- if (mac->opmode == NL80211_IFTYPE_ADHOC)
- rtlpriv->sec.use_defaultkey = true;
break;
case WLAN_CIPHER_SUITE_CCMP:
key_type = AESCCMP_ENCRYPTION;
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n"));
- if (mac->opmode == NL80211_IFTYPE_ADHOC)
- rtlpriv->sec.use_defaultkey = true;
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("alg_err:%x!!!!:\n", key->cipher));
goto out_unlock;
}
+ if (key_type == WEP40_ENCRYPTION ||
+ key_type == WEP104_ENCRYPTION ||
+ mac->opmode == NL80211_IFTYPE_ADHOC)
+ rtlpriv->sec.use_defaultkey = true;
+
/* <2> get key_idx */
key_idx = (u8) (key->keyidx);
if (key_idx > 3)
goto out_unlock;
/* <3> if pairwise key enable_hw_sec */
group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE);
- if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) ||
- rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) {
- if (rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION &&
- (key_type == WEP40_ENCRYPTION ||
- key_type == WEP104_ENCRYPTION))
- wep_only = true;
- rtlpriv->sec.pairwise_enc_algorithm = key_type;
- rtlpriv->cfg->ops->enable_hw_sec(hw);
+
+ /* wep always be group key, but there are two conditions:
+ * 1) wep only: is just for wep enc, in this condition
+ * rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION
+ * will be true & enable_hw_sec will be set when wep
+ * ke setting.
+ * 2) wep(group) + AES(pairwise): some AP like cisco
+ * may use it, in this condition enable_hw_sec will not
+ * be set when wep key setting */
+ /* we must reset sec_info after lingked before set key,
+ * or some flag will be wrong*/
+ if (mac->opmode == NL80211_IFTYPE_AP) {
+ if (!group_key || key_type == WEP40_ENCRYPTION ||
+ key_type == WEP104_ENCRYPTION) {
+ if (group_key)
+ wep_only = true;
+ rtlpriv->cfg->ops->enable_hw_sec(hw);
+ }
+ } else {
+ if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) ||
+ rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) {
+ if (rtlpriv->sec.pairwise_enc_algorithm ==
+ NO_ENCRYPTION &&
+ (key_type == WEP40_ENCRYPTION ||
+ key_type == WEP104_ENCRYPTION))
+ wep_only = true;
+ rtlpriv->sec.pairwise_enc_algorithm = key_type;
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1"
+ " TKIP:2 AES:4 WEP104:5)\n", key_type));
+ rtlpriv->cfg->ops->enable_hw_sec(hw);
+ }
}
/* <4> set key based on cmd */
switch (cmd) {
@@ -932,6 +1022,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (!sta) {
RT_ASSERT(false, ("pairwise key withnot"
"mac_addr\n"));
+
err = -EOPNOTSUPP;
goto out_unlock;
}
@@ -959,6 +1050,10 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
("disable key delete one entry\n"));
/*set local buf about wep key. */
+ if (mac->opmode == NL80211_IFTYPE_AP) {
+ if (sta)
+ rtl_cam_del_entry(hw, sta->addr);
+ }
memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen);
rtlpriv->sec.key_len[key_idx] = 0;
memcpy(mac_addr, zero_addr, ETH_ALEN);
@@ -1011,6 +1106,18 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
mutex_unlock(&rtlpriv->locks.conf_mutex);
}
+/* this function is called by mac80211 to flush tx buffer
+ * before switch channle or power save, or tx buffer packet
+ * maybe send after offchannel or rf sleep, this may cause
+ * dis-association by AP */
+static void rtl_op_flush(struct ieee80211_hw *hw, bool drop)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (rtlpriv->intf_ops->flush)
+ rtlpriv->intf_ops->flush(hw, drop);
+}
+
const struct ieee80211_ops rtl_ops = {
.start = rtl_op_start,
.stop = rtl_op_stop,
@@ -1019,6 +1126,8 @@ const struct ieee80211_ops rtl_ops = {
.remove_interface = rtl_op_remove_interface,
.config = rtl_op_config,
.configure_filter = rtl_op_configure_filter,
+ .sta_add = rtl_op_sta_add,
+ .sta_remove = rtl_op_sta_remove,
.set_key = rtl_op_set_key,
.conf_tx = rtl_op_conf_tx,
.bss_info_changed = rtl_op_bss_info_changed,
@@ -1030,4 +1139,5 @@ const struct ieee80211_ops rtl_ops = {
.sw_scan_start = rtl_op_sw_scan_start,
.sw_scan_complete = rtl_op_sw_scan_complete,
.rfkill_poll = rtl_op_rfkill_poll,
+ .flush = rtl_op_flush,
};
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h
index 0ef31c3c619..4b247db2861 100644
--- a/drivers/net/wireless/rtlwifi/core.h
+++ b/drivers/net/wireless/rtlwifi/core.h
@@ -24,6 +24,7 @@
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
+ *
*****************************************************************************/
#ifndef __RTL_CORE_H__
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c
index 590f14f45a8..50de6f5d8a5 100644
--- a/drivers/net/wireless/rtlwifi/efuse.c
+++ b/drivers/net/wireless/rtlwifi/efuse.c
@@ -52,8 +52,6 @@ static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = {
{11, 0, 0, 28}
};
-static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset,
- u8 *pbuf);
static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset,
u8 *value);
static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset,
@@ -79,7 +77,7 @@ static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata,
u8 *targetdata);
static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
u16 efuse_addr, u8 word_en, u8 *data);
-static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite,
+static void efuse_power_switch(struct ieee80211_hw *hw, u8 write,
u8 pwrstate);
static u16 efuse_get_current_size(struct ieee80211_hw *hw);
static u8 efuse_calculate_word_cnts(u8 word_en);
@@ -115,8 +113,10 @@ u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address)
u8 bytetemp;
u8 temp;
u32 k = 0;
+ const u32 efuse_len =
+ rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
- if (address < EFUSE_REAL_CONTENT_LEN) {
+ if (address < efuse_len) {
temp = address & 0xFF;
rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
temp);
@@ -158,11 +158,13 @@ void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)
u8 bytetemp;
u8 temp;
u32 k = 0;
+ const u32 efuse_len =
+ rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
("Addr=%x Data =%x\n", address, value));
- if (address < EFUSE_REAL_CONTENT_LEN) {
+ if (address < efuse_len) {
rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value);
temp = address & 0xFF;
@@ -198,7 +200,7 @@ void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)
}
-static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
+void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 value32;
@@ -233,26 +235,45 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
- u8 efuse_tbl[EFUSE_MAP_LEN];
+ u8 *efuse_tbl;
u8 rtemp8[1];
u16 efuse_addr = 0;
u8 offset, wren;
u16 i;
u16 j;
- u16 efuse_word[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT];
+ const u16 efuse_max_section =
+ rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP];
+ const u32 efuse_len =
+ rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
+ u16 **efuse_word;
u16 efuse_utilized = 0;
u8 efuse_usage;
- if ((_offset + _size_byte) > EFUSE_MAP_LEN) {
+ if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) {
RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
("read_efuse(): Invalid offset(%#x) with read "
"bytes(%#x)!!\n", _offset, _size_byte));
return;
}
- for (i = 0; i < EFUSE_MAX_SECTION; i++)
+ /* allocate memory for efuse_tbl and efuse_word */
+ efuse_tbl = kmalloc(rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE] *
+ sizeof(u8), GFP_ATOMIC);
+ if (!efuse_tbl)
+ return;
+ efuse_word = kmalloc(EFUSE_MAX_WORD_UNIT * sizeof(u16 *), GFP_ATOMIC);
+ if (!efuse_word)
+ goto done;
+ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
+ efuse_word[i] = kmalloc(efuse_max_section * sizeof(u16),
+ GFP_ATOMIC);
+ if (!efuse_word[i])
+ goto done;
+ }
+
+ for (i = 0; i < efuse_max_section; i++)
for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
- efuse_word[i][j] = 0xFFFF;
+ efuse_word[j][i] = 0xFFFF;
read_efuse_byte(hw, efuse_addr, rtemp8);
if (*rtemp8 != 0xFF) {
@@ -262,10 +283,10 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
efuse_addr++;
}
- while ((*rtemp8 != 0xFF) && (efuse_addr < EFUSE_REAL_CONTENT_LEN)) {
+ while ((*rtemp8 != 0xFF) && (efuse_addr < efuse_len)) {
offset = ((*rtemp8 >> 4) & 0x0f);
- if (offset < EFUSE_MAX_SECTION) {
+ if (offset < efuse_max_section) {
wren = (*rtemp8 & 0x0f);
RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
("offset-%d Worden=%x\n", offset, wren));
@@ -279,9 +300,10 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
read_efuse_byte(hw, efuse_addr, rtemp8);
efuse_addr++;
efuse_utilized++;
- efuse_word[offset][i] = (*rtemp8 & 0xff);
+ efuse_word[i][offset] =
+ (*rtemp8 & 0xff);
- if (efuse_addr >= EFUSE_REAL_CONTENT_LEN)
+ if (efuse_addr >= efuse_len)
break;
RTPRINT(rtlpriv, FEEPROM,
@@ -291,10 +313,10 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
read_efuse_byte(hw, efuse_addr, rtemp8);
efuse_addr++;
efuse_utilized++;
- efuse_word[offset][i] |=
+ efuse_word[i][offset] |=
(((u16)*rtemp8 << 8) & 0xff00);
- if (efuse_addr >= EFUSE_REAL_CONTENT_LEN)
+ if (efuse_addr >= efuse_len)
break;
}
@@ -305,18 +327,18 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
("Addr=%d\n", efuse_addr));
read_efuse_byte(hw, efuse_addr, rtemp8);
- if (*rtemp8 != 0xFF && (efuse_addr < 512)) {
+ if (*rtemp8 != 0xFF && (efuse_addr < efuse_len)) {
efuse_utilized++;
efuse_addr++;
}
}
- for (i = 0; i < EFUSE_MAX_SECTION; i++) {
+ for (i = 0; i < efuse_max_section; i++) {
for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
efuse_tbl[(i * 8) + (j * 2)] =
- (efuse_word[i][j] & 0xff);
+ (efuse_word[j][i] & 0xff);
efuse_tbl[(i * 8) + ((j * 2) + 1)] =
- ((efuse_word[i][j] >> 8) & 0xff);
+ ((efuse_word[j][i] >> 8) & 0xff);
}
}
@@ -324,12 +346,17 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
pbuf[i] = efuse_tbl[_offset + i];
rtlefuse->efuse_usedbytes = efuse_utilized;
- efuse_usage = (u8)((efuse_utilized * 100) / EFUSE_REAL_CONTENT_LEN);
+ efuse_usage = (u8) ((efuse_utilized * 100) / efuse_len);
rtlefuse->efuse_usedpercentage = efuse_usage;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES,
(u8 *)&efuse_utilized);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE,
(u8 *)&efuse_usage);
+done:
+ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++)
+ kfree(efuse_word[i]);
+ kfree(efuse_word);
+ kfree(efuse_tbl);
}
bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
@@ -338,11 +365,11 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u8 section_idx, i, Base;
u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used;
- bool bwordchanged, bresult = true;
+ bool wordchanged, result = true;
for (section_idx = 0; section_idx < 16; section_idx++) {
Base = section_idx * 8;
- bwordchanged = false;
+ wordchanged = false;
for (i = 0; i < 8; i = i + 2) {
if ((rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i] !=
@@ -351,11 +378,11 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i +
1])) {
words_need++;
- bwordchanged = true;
+ wordchanged = true;
}
}
- if (bwordchanged == true)
+ if (wordchanged == true)
hdr_num++;
}
@@ -364,14 +391,14 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
if ((totalbytes + efuse_used) >=
(EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))
- bresult = false;
+ result = false;
RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
("efuse_shadow_update_chk(): totalbytes(%#x), "
"hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
totalbytes, hdr_num, words_need, efuse_used));
- return bresult;
+ return result;
}
void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
@@ -394,7 +421,7 @@ void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset,
else if (type == 2)
efuse_shadow_write_2byte(hw, offset, (u16) value);
else if (type == 4)
- efuse_shadow_write_4byte(hw, offset, (u32) value);
+ efuse_shadow_write_4byte(hw, offset, value);
}
@@ -478,9 +505,10 @@ void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw)
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
- if (rtlefuse->autoload_failflag == true) {
- memset(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 0xFF, 128);
- } else
+ if (rtlefuse->autoload_failflag == true)
+ memset(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 0xFF,
+ rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
+ else
efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
@@ -572,7 +600,7 @@ static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 tmpidx = 0;
- int bresult;
+ int result;
rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
(u8) (addr & 0xff));
@@ -592,19 +620,18 @@ static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data)
if (tmpidx < 100) {
*data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
- bresult = true;
+ result = true;
} else {
*data = 0xff;
- bresult = false;
+ result = false;
}
- return bresult;
+ return result;
}
static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 tmpidx = 0;
- bool bresult;
RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
("Addr = %x Data=%x\n", addr, data));
@@ -626,17 +653,16 @@ static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)
}
if (tmpidx < 100)
- bresult = true;
- else
- bresult = false;
+ return true;
- return bresult;
+ return false;
}
static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse)
{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
efuse_power_switch(hw, false, true);
- read_efuse(hw, 0, 128, efuse);
+ read_efuse(hw, 0, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], efuse);
efuse_power_switch(hw, false, false);
}
@@ -644,7 +670,7 @@ static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
u8 efuse_data, u8 offset, u8 *tmpdata,
u8 *readstate)
{
- bool bdataempty = true;
+ bool dataempty = true;
u8 hoffset;
u8 tmpidx;
u8 hworden;
@@ -660,13 +686,13 @@ static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
&efuse_data)) {
tmpdata[tmpidx] = efuse_data;
if (efuse_data != 0xff)
- bdataempty = true;
+ dataempty = true;
}
}
- if (bdataempty == true)
+ if (dataempty == true) {
*readstate = PG_STATE_DATA;
- else {
+ } else {
*efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
*readstate = PG_STATE_HEADER;
}
@@ -680,12 +706,9 @@ static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
{
u8 readstate = PG_STATE_HEADER;
-
- bool bcontinual = true;
-
+ bool continual = true;
u8 efuse_data, word_cnts = 0;
u16 efuse_addr = 0;
- u8 hworden = 0;
u8 tmpdata[8];
if (data == NULL)
@@ -696,7 +719,7 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
memset(data, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
memset(tmpdata, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
- while (bcontinual && (efuse_addr < EFUSE_MAX_SIZE)) {
+ while (continual && (efuse_addr < EFUSE_MAX_SIZE)) {
if (readstate & PG_STATE_HEADER) {
if (efuse_one_byte_read(hw, efuse_addr, &efuse_data)
&& (efuse_data != 0xFF))
@@ -705,9 +728,9 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
offset, tmpdata,
&readstate);
else
- bcontinual = false;
+ continual = false;
} else if (readstate & PG_STATE_DATA) {
- efuse_word_enable_data_read(hworden, tmpdata, data);
+ efuse_word_enable_data_read(0, tmpdata, data);
efuse_addr = efuse_addr + (word_cnts * 2) + 1;
readstate = PG_STATE_HEADER;
}
@@ -725,13 +748,13 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
}
static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
- u8 efuse_data, u8 offset, int *bcontinual,
+ u8 efuse_data, u8 offset, int *continual,
u8 *write_state, struct pgpkt_struct *target_pkt,
- int *repeat_times, int *bresult, u8 word_en)
+ int *repeat_times, int *result, u8 word_en)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct pgpkt_struct tmp_pkt;
- int bdataempty = true;
+ bool dataempty = true;
u8 originaldata[8 * sizeof(u8)];
u8 badworden = 0x0F;
u8 match_word_en, tmp_word_en;
@@ -751,10 +774,10 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
u16 address = *efuse_addr + 1 + tmpindex;
if (efuse_one_byte_read(hw, address,
&efuse_data) && (efuse_data != 0xFF))
- bdataempty = false;
+ dataempty = false;
}
- if (bdataempty == false) {
+ if (dataempty == false) {
*efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
*write_state = PG_STATE_HEADER;
} else {
@@ -799,24 +822,25 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
tmp_word_en &= (~BIT(1));
if ((target_pkt->word_en & BIT(2)) ^
- (match_word_en & BIT(2)))
+ (match_word_en & BIT(2)))
tmp_word_en &= (~BIT(2));
if ((target_pkt->word_en & BIT(3)) ^
- (match_word_en & BIT(3)))
+ (match_word_en & BIT(3)))
tmp_word_en &= (~BIT(3));
if ((tmp_word_en & 0x0F) != 0x0F) {
*efuse_addr = efuse_get_current_size(hw);
target_pkt->offset = offset;
target_pkt->word_en = tmp_word_en;
- } else
- *bcontinual = false;
+ } else {
+ *continual = false;
+ }
*write_state = PG_STATE_HEADER;
*repeat_times += 1;
if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
- *bcontinual = false;
- *bresult = false;
+ *continual = false;
+ *result = false;
}
} else {
*efuse_addr += (2 * tmp_word_cnts) + 1;
@@ -830,9 +854,9 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
}
static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
- int *bcontinual, u8 *write_state,
+ int *continual, u8 *write_state,
struct pgpkt_struct target_pkt,
- int *repeat_times, int *bresult)
+ int *repeat_times, int *result)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct pgpkt_struct tmp_pkt;
@@ -846,14 +870,14 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
efuse_one_byte_write(hw, *efuse_addr, pg_header);
efuse_one_byte_read(hw, *efuse_addr, &tmp_header);
- if (tmp_header == pg_header)
+ if (tmp_header == pg_header) {
*write_state = PG_STATE_DATA;
- else if (tmp_header == 0xFF) {
+ } else if (tmp_header == 0xFF) {
*write_state = PG_STATE_HEADER;
*repeat_times += 1;
if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
- *bcontinual = false;
- *bresult = false;
+ *continual = false;
+ *result = false;
}
} else {
tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
@@ -875,17 +899,19 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
reorg_worden,
originaldata);
*efuse_addr = efuse_get_current_size(hw);
- } else
+ } else {
*efuse_addr = *efuse_addr + (tmp_word_cnts * 2)
+ 1;
- } else
+ }
+ } else {
*efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
+ }
*write_state = PG_STATE_HEADER;
*repeat_times += 1;
if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
- *bcontinual = false;
- *bresult = false;
+ *continual = false;
+ *result = false;
}
RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
@@ -899,7 +925,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct pgpkt_struct target_pkt;
u8 write_state = PG_STATE_HEADER;
- int bcontinual = true, bdataempty = true, bresult = true;
+ int continual = true, dataempty = true, result = true;
u16 efuse_addr = 0;
u8 efuse_data;
u8 target_word_cnts = 0;
@@ -923,11 +949,11 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n"));
- while (bcontinual && (efuse_addr <
+ while (continual && (efuse_addr <
(EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) {
if (write_state == PG_STATE_HEADER) {
- bdataempty = true;
+ dataempty = true;
badworden = 0x0F;
RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
("efuse PG_STATE_HEADER\n"));
@@ -936,32 +962,30 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
(efuse_data != 0xFF))
efuse_write_data_case1(hw, &efuse_addr,
efuse_data, offset,
- &bcontinual,
+ &continual,
&write_state, &target_pkt,
- &repeat_times, &bresult,
+ &repeat_times, &result,
word_en);
else
efuse_write_data_case2(hw, &efuse_addr,
- &bcontinual,
+ &continual,
&write_state,
target_pkt,
&repeat_times,
- &bresult);
+ &result);
} else if (write_state == PG_STATE_DATA) {
RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
("efuse PG_STATE_DATA\n"));
- badworden = 0x0f;
badworden =
efuse_word_enable_data_write(hw, efuse_addr + 1,
target_pkt.word_en,
target_pkt.data);
if ((badworden & 0x0F) == 0x0F) {
- bcontinual = false;
+ continual = false;
} else {
- efuse_addr =
- efuse_addr + (2 * target_word_cnts) + 1;
+ efuse_addr += (2 * target_word_cnts) + 1;
target_pkt.offset = offset;
target_pkt.word_en = badworden;
@@ -971,8 +995,8 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
write_state = PG_STATE_HEADER;
repeat_times++;
if (repeat_times > EFUSE_REPEAT_THRESHOLD_) {
- bcontinual = false;
- bresult = false;
+ continual = false;
+ result = false;
}
RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
("efuse PG_STATE_HEADER-3\n"));
@@ -1072,13 +1096,15 @@ static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
return badworden;
}
-static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate)
+static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u8 tempval;
u16 tmpV16;
- if (pwrstate == true) {
+ if (pwrstate && (rtlhal->hw_type !=
+ HARDWARE_TYPE_RTL8192SE)) {
tmpV16 = rtl_read_word(rtlpriv,
rtlpriv->cfg->maps[SYS_ISO_CTRL]);
if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) {
@@ -1106,20 +1132,29 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate)
}
}
- if (pwrstate == true) {
- if (bwrite == true) {
+ if (pwrstate) {
+ if (write) {
tempval = rtl_read_byte(rtlpriv,
rtlpriv->cfg->maps[EFUSE_TEST] +
3);
- tempval &= 0x0F;
- tempval |= (VOLTAGE_V25 << 4);
+
+ if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) {
+ tempval &= 0x0F;
+ tempval |= (VOLTAGE_V25 << 4);
+ }
+
rtl_write_byte(rtlpriv,
rtlpriv->cfg->maps[EFUSE_TEST] + 3,
(tempval | 0x80));
}
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
+ 0x03);
+ }
+
} else {
- if (bwrite == true) {
+ if (write) {
tempval = rtl_read_byte(rtlpriv,
rtlpriv->cfg->maps[EFUSE_TEST] +
3);
@@ -1128,18 +1163,23 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate)
(tempval & 0x7F));
}
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
+ 0x02);
+ }
+
}
}
static u16 efuse_get_current_size(struct ieee80211_hw *hw)
{
- int bcontinual = true;
+ int continual = true;
u16 efuse_addr = 0;
u8 hoffset, hworden;
u8 efuse_data, word_cnts;
- while (bcontinual && efuse_one_byte_read(hw, efuse_addr, &efuse_data)
+ while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data)
&& (efuse_addr < EFUSE_MAX_SIZE)) {
if (efuse_data != 0xFF) {
hoffset = (efuse_data >> 4) & 0x0F;
@@ -1147,7 +1187,7 @@ static u16 efuse_get_current_size(struct ieee80211_hw *hw)
word_cnts = efuse_calculate_word_cnts(hworden);
efuse_addr = efuse_addr + (word_cnts * 2) + 1;
} else {
- bcontinual = false;
+ continual = false;
}
}
diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h
index 47774dd4c2a..164dabaa761 100644
--- a/drivers/net/wireless/rtlwifi/efuse.h
+++ b/drivers/net/wireless/rtlwifi/efuse.h
@@ -30,9 +30,10 @@
#ifndef __RTL_EFUSE_H_
#define __RTL_EFUSE_H_
+#define EFUSE_IC_ID_OFFSET 506
+
#define EFUSE_REAL_CONTENT_LEN 512
#define EFUSE_MAP_LEN 128
-#define EFUSE_MAX_SECTION 16
#define EFUSE_MAX_WORD_UNIT 4
#define EFUSE_INIT_MAP 0
@@ -52,6 +53,7 @@
#define _PRE_EXECUTE_READ_CMD_
#define EFUSE_REPEAT_THRESHOLD_ 3
+#define EFUSE_ERROE_HANDLE 1
struct efuse_map {
u8 offset;
@@ -103,6 +105,7 @@ struct efuse_priv {
u8 tx_power_g[14];
};
+extern void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf);
extern void efuse_initialize(struct ieee80211_hw *hw);
extern u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address);
extern void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value);
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 5938f6ee21e..a4095284543 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -32,6 +32,7 @@
#include "pci.h"
#include "base.h"
#include "ps.h"
+#include "efuse.h"
static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {
INTEL_VENDOR_ID,
@@ -40,6 +41,31 @@ static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {
SIS_VENDOR_ID
};
+static const u8 ac_to_hwq[] = {
+ VO_QUEUE,
+ VI_QUEUE,
+ BE_QUEUE,
+ BK_QUEUE
+};
+
+static u8 _rtl_mac_to_hwqueue(struct ieee80211_hw *hw,
+ struct sk_buff *skb)
+{
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ __le16 fc = rtl_get_fc(skb);
+ u8 queue_index = skb_get_queue_mapping(skb);
+
+ if (unlikely(ieee80211_is_beacon(fc)))
+ return BEACON_QUEUE;
+ if (ieee80211_is_mgmt(fc))
+ return MGNT_QUEUE;
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE)
+ if (ieee80211_is_nullfunc(fc))
+ return HIGH_QUEUE;
+
+ return ac_to_hwq[queue_index];
+}
+
/* Update PCI dependent default settings*/
static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
{
@@ -48,6 +74,7 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
+ u8 init_aspm;
ppsc->reg_rfps_level = 0;
ppsc->support_aspm = 0;
@@ -125,7 +152,7 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
bool support_backdoor = true;
ppsc->support_aspm = support_aspm;
- /*if(priv->oem_id == RT_CID_TOSHIBA &&
+ /*if (priv->oem_id == RT_CID_TOSHIBA &&
!priv->ndis_adapter.amd_l1_patch)
support_backdoor = false; */
@@ -145,6 +172,13 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
("switch case not process\n"));
break;
}
+
+ /* toshiba aspm issue, toshiba will set aspm selfly
+ * so we should not set aspm in driver */
+ pci_read_config_byte(rtlpci->pdev, 0x80, &init_aspm);
+ if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8192SE &&
+ init_aspm == 0x43)
+ ppsc->support_aspm = false;
}
static bool _rtl_pci_platform_switch_device_pci_aspm(
@@ -152,28 +186,28 @@ static bool _rtl_pci_platform_switch_device_pci_aspm(
u8 value)
{
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
- bool bresult = false;
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
- value |= 0x40;
+ if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE)
+ value |= 0x40;
pci_write_config_byte(rtlpci->pdev, 0x80, value);
- return bresult;
+ return false;
}
/*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/
static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
{
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
- u8 buffer;
- bool bresult = false;
-
- buffer = value;
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
pci_write_config_byte(rtlpci->pdev, 0x81, value);
- bresult = true;
- return bresult;
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE)
+ udelay(100);
+
+ return true;
}
/*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/
@@ -191,6 +225,10 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter.
pcibridge_linkctrlreg;
u16 aspmlevel = 0;
+ u8 tmp_u1b = 0;
+
+ if (!ppsc->support_aspm)
+ return;
if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
@@ -204,11 +242,8 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
_rtl_pci_switch_clk_req(hw, 0x0);
}
- if (1) {
- /*for promising device will in L0 state after an I/O. */
- u8 tmp_u1b;
- pci_read_config_byte(rtlpci->pdev, 0x80, &tmp_u1b);
- }
+ /*for promising device will in L0 state after an I/O. */
+ pci_read_config_byte(rtlpci->pdev, 0x80, &tmp_u1b);
/*Set corresponding value. */
aspmlevel |= BIT(0) | BIT(1);
@@ -224,7 +259,6 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, pcibridge_linkctrlreg);
udelay(50);
-
}
/*
@@ -249,6 +283,9 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
u8 u_pcibridge_aspmsetting;
u8 u_device_aspmsetting;
+ if (!ppsc->support_aspm)
+ return;
+
if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
("PCI(Bridge) UNKNOWN.\n"));
@@ -293,7 +330,7 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0);
RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ);
}
- udelay(200);
+ udelay(100);
}
static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw)
@@ -330,13 +367,13 @@ static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw)
u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset;
u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
u8 linkctrl_reg;
- u8 num4bBytes;
+ u8 num4bbytes;
- num4bBytes = (capabilityoffset + 0x10) / 4;
+ num4bbytes = (capabilityoffset + 0x10) / 4;
/*Read Link Control Register */
rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
- pcicfg_addrport + (num4bBytes << 2));
+ pcicfg_addrport + (num4bbytes << 2));
rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &linkctrl_reg);
pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg;
@@ -369,7 +406,7 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev,
pci_write_config_byte(pdev, 0x70f, tmp);
}
-static void _rtl_pci_initialize_adapter_common(struct ieee80211_hw *hw)
+static void rtl_pci_init_aspm(struct ieee80211_hw *hw)
{
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
@@ -383,52 +420,6 @@ static void _rtl_pci_initialize_adapter_common(struct ieee80211_hw *hw)
}
-static void rtl_pci_init_aspm(struct ieee80211_hw *hw)
-{
- struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-
- /*close ASPM for AMD defaultly */
- rtlpci->const_amdpci_aspm = 0;
-
- /*
- * ASPM PS mode.
- * 0 - Disable ASPM,
- * 1 - Enable ASPM without Clock Req,
- * 2 - Enable ASPM with Clock Req,
- * 3 - Always Enable ASPM with Clock Req,
- * 4 - Always Enable ASPM without Clock Req.
- * set defult to RTL8192CE:3 RTL8192E:2
- * */
- rtlpci->const_pci_aspm = 3;
-
- /*Setting for PCI-E device */
- rtlpci->const_devicepci_aspm_setting = 0x03;
-
- /*Setting for PCI-E bridge */
- rtlpci->const_hostpci_aspm_setting = 0x02;
-
- /*
- * In Hw/Sw Radio Off situation.
- * 0 - Default,
- * 1 - From ASPM setting without low Mac Pwr,
- * 2 - From ASPM setting with low Mac Pwr,
- * 3 - Bus D3
- * set default to RTL8192CE:0 RTL8192SE:2
- */
- rtlpci->const_hwsw_rfoff_d3 = 0;
-
- /*
- * This setting works for those device with
- * backdoor ASPM setting such as EPHY setting.
- * 0 - Not support ASPM,
- * 1 - Support ASPM,
- * 2 - According to chipset.
- */
- rtlpci->const_support_pciaspm = 1;
-
- _rtl_pci_initialize_adapter_common(hw);
-}
-
static void _rtl_pci_io_handler_init(struct device *dev,
struct ieee80211_hw *hw)
{
@@ -450,6 +441,90 @@ static void _rtl_pci_io_handler_release(struct ieee80211_hw *hw)
{
}
+static bool _rtl_update_earlymode_info(struct ieee80211_hw *hw,
+ struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc, u8 tid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ u8 additionlen = FCS_LEN;
+ struct sk_buff *next_skb;
+
+ /* here open is 4, wep/tkip is 8, aes is 12*/
+ if (info->control.hw_key)
+ additionlen += info->control.hw_key->icv_len;
+
+ /* The most skb num is 6 */
+ tcb_desc->empkt_num = 0;
+ spin_lock_bh(&rtlpriv->locks.waitq_lock);
+ skb_queue_walk(&rtlpriv->mac80211.skb_waitq[tid], next_skb) {
+ struct ieee80211_tx_info *next_info;
+
+ next_info = IEEE80211_SKB_CB(next_skb);
+ if (next_info->flags & IEEE80211_TX_CTL_AMPDU) {
+ tcb_desc->empkt_len[tcb_desc->empkt_num] =
+ next_skb->len + additionlen;
+ tcb_desc->empkt_num++;
+ } else {
+ break;
+ }
+
+ if (skb_queue_is_last(&rtlpriv->mac80211.skb_waitq[tid],
+ next_skb))
+ break;
+
+ if (tcb_desc->empkt_num >= 5)
+ break;
+ }
+ spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+
+ return true;
+}
+
+/* just for early mode now */
+static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct sk_buff *skb = NULL;
+ struct ieee80211_tx_info *info = NULL;
+ int tid; /* should be int */
+
+ if (!rtlpriv->rtlhal.earlymode_enable)
+ return;
+
+ /* we juse use em for BE/BK/VI/VO */
+ for (tid = 7; tid >= 0; tid--) {
+ u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(hw, tid)];
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
+ while (!mac->act_scanning &&
+ rtlpriv->psc.rfpwr_state == ERFON) {
+ struct rtl_tcb_desc tcb_desc;
+ memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+
+ spin_lock_bh(&rtlpriv->locks.waitq_lock);
+ if (!skb_queue_empty(&mac->skb_waitq[tid]) &&
+ (ring->entries - skb_queue_len(&ring->queue) > 5)) {
+ skb = skb_dequeue(&mac->skb_waitq[tid]);
+ } else {
+ spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+ break;
+ }
+ spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+
+ /* Some macaddr can't do early mode. like
+ * multicast/broadcast/no_qos data */
+ info = IEEE80211_SKB_CB(skb);
+ if (info->flags & IEEE80211_TX_CTL_AMPDU)
+ _rtl_update_earlymode_info(hw, skb,
+ &tcb_desc, tid);
+
+ rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);
+ }
+ }
+}
+
+
static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -461,6 +536,8 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
struct rtl_tx_desc *entry = &ring->desc[ring->idx];
struct sk_buff *skb;
struct ieee80211_tx_info *info;
+ __le16 fc;
+ u8 tid;
u8 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) entry, true,
HW_DESC_OWN);
@@ -481,6 +558,10 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
HW_DESC_TXBUFF_ADDR),
skb->len, PCI_DMA_TODEVICE);
+ /* remove early mode header */
+ if (rtlpriv->rtlhal.earlymode_enable)
+ skb_pull(skb, EM_HDR_LEN);
+
RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE,
("new ring->idx:%d, "
"free: skb_queue_len:%d, free: seq:%x\n",
@@ -488,6 +569,30 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
skb_queue_len(&ring->queue),
*(u16 *) (skb->data + 22)));
+ if (prio == TXCMD_QUEUE) {
+ dev_kfree_skb(skb);
+ goto tx_status_ok;
+
+ }
+
+ /* for sw LPS, just after NULL skb send out, we can
+ * sure AP kown we are sleeped, our we should not let
+ * rf to sleep*/
+ fc = rtl_get_fc(skb);
+ if (ieee80211_is_nullfunc(fc)) {
+ if (ieee80211_has_pm(fc)) {
+ rtlpriv->mac80211.offchan_deley = true;
+ rtlpriv->psc.state_inap = 1;
+ } else {
+ rtlpriv->psc.state_inap = 0;
+ }
+ }
+
+ /* update tid tx pkt num */
+ tid = rtl_get_tid(skb);
+ if (tid <= 7)
+ rtlpriv->link_info.tidtx_inperiod[tid]++;
+
info = IEEE80211_SKB_CB(skb);
ieee80211_tx_info_clear_status(info);
@@ -510,7 +615,7 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
skb_get_queue_mapping
(skb));
}
-
+tx_status_ok:
skb = NULL;
}
@@ -582,23 +687,21 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
*skb_trim(skb, skb->len - 4);
*/
- hdr = (struct ieee80211_hdr *)(skb->data);
- fc = hdr->frame_control;
+ hdr = rtl_get_hdr(skb);
+ fc = rtl_get_fc(skb);
- if (!stats.crc) {
+ if (!stats.crc || !stats.hwerror) {
memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
sizeof(rx_status));
- if (is_broadcast_ether_addr(hdr->addr1))
+ if (is_broadcast_ether_addr(hdr->addr1)) {
;/*TODO*/
- else {
- if (is_multicast_ether_addr(hdr->addr1))
- ;/*TODO*/
- else {
- unicast = true;
- rtlpriv->stats.rxbytesunicast +=
- skb->len;
- }
+ } else if (is_multicast_ether_addr(hdr->addr1)) {
+ ;/*TODO*/
+ } else {
+ unicast = true;
+ rtlpriv->stats.rxbytesunicast +=
+ skb->len;
}
rtl_is_special_data(hw, skb, false);
@@ -612,28 +715,38 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
num_rx_inperiod++;
}
- if (unlikely(!rtl_action_proc(hw, skb,
- false))) {
+ /* for sw lps */
+ rtl_swlps_beacon(hw, (void *)skb->data,
+ skb->len);
+ rtl_recognize_peer(hw, (void *)skb->data,
+ skb->len);
+ if ((rtlpriv->mac80211.opmode ==
+ NL80211_IFTYPE_AP) &&
+ (rtlpriv->rtlhal.current_bandtype ==
+ BAND_ON_2_4G) &&
+ (ieee80211_is_beacon(fc) ||
+ ieee80211_is_probe_resp(fc))) {
dev_kfree_skb_any(skb);
} else {
- struct sk_buff *uskb = NULL;
- u8 *pdata;
- uskb = dev_alloc_skb(skb->len + 128);
- if (!uskb) {
- RT_TRACE(rtlpriv,
- (COMP_INTR | COMP_RECV),
- DBG_EMERG,
- ("can't alloc rx skb\n"));
- goto done;
+ if (unlikely(!rtl_action_proc(hw, skb,
+ false))) {
+ dev_kfree_skb_any(skb);
+ } else {
+ struct sk_buff *uskb = NULL;
+ u8 *pdata;
+ uskb = dev_alloc_skb(skb->len
+ + 128);
+ memcpy(IEEE80211_SKB_RXCB(uskb),
+ &rx_status,
+ sizeof(rx_status));
+ pdata = (u8 *)skb_put(uskb,
+ skb->len);
+ memcpy(pdata, skb->data,
+ skb->len);
+ dev_kfree_skb_any(skb);
+
+ ieee80211_rx_irqsafe(hw, uskb);
}
- memcpy(IEEE80211_SKB_RXCB(uskb),
- &rx_status,
- sizeof(rx_status));
- pdata = (u8 *)skb_put(uskb, skb->len);
- memcpy(pdata, skb->data, skb->len);
- dev_kfree_skb_any(skb);
-
- ieee80211_rx_irqsafe(hw, uskb);
}
} else {
dev_kfree_skb_any(skb);
@@ -648,7 +761,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
if (unlikely(!new_skb)) {
RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
- DBG_EMERG,
+ DBG_DMESG,
("can't alloc skb for rx\n"));
goto done;
}
@@ -666,7 +779,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
}
done:
- bufferaddress = (u32)(*((dma_addr_t *) skb->cb));
+ bufferaddress = (*((dma_addr_t *)skb->cb));
tmp_one = 1;
rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false,
HW_DESC_RXBUFF_ADDR,
@@ -695,6 +808,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
struct ieee80211_hw *hw = dev_id;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
unsigned long flags;
u32 inta = 0;
u32 intb = 0;
@@ -781,23 +895,36 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
_rtl_pci_tx_isr(hw, VO_QUEUE);
}
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_COMDOK]) {
+ rtlpriv->link_info.num_tx_inperiod++;
+
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ ("CMD TX OK interrupt!\n"));
+ _rtl_pci_tx_isr(hw, TXCMD_QUEUE);
+ }
+ }
+
/*<2> Rx related */
if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) {
RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n"));
- tasklet_schedule(&rtlpriv->works.irq_tasklet);
+ _rtl_pci_rx_interrupt(hw);
}
if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
("rx descriptor unavailable!\n"));
- tasklet_schedule(&rtlpriv->works.irq_tasklet);
+ _rtl_pci_rx_interrupt(hw);
}
if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("rx overflow !\n"));
- tasklet_schedule(&rtlpriv->works.irq_tasklet);
+ _rtl_pci_rx_interrupt(hw);
}
+ if (rtlpriv->rtlhal.earlymode_enable)
+ tasklet_schedule(&rtlpriv->works.irq_tasklet);
+
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
return IRQ_HANDLED;
@@ -808,7 +935,7 @@ done:
static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw)
{
- _rtl_pci_rx_interrupt(hw);
+ _rtl_pci_tx_chk_waitq(hw);
}
static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
@@ -816,14 +943,15 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
- struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
+ struct rtl8192_tx_ring *ring = NULL;
struct ieee80211_hdr *hdr = NULL;
struct ieee80211_tx_info *info = NULL;
struct sk_buff *pskb = NULL;
struct rtl_tx_desc *pdesc = NULL;
- unsigned int queue_index;
+ struct rtl_tcb_desc tcb_desc;
u8 temp_one = 1;
+ memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
ring = &rtlpci->tx_ring[BEACON_QUEUE];
pskb = __skb_dequeue(&ring->queue);
if (pskb)
@@ -833,14 +961,11 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
pskb = ieee80211_beacon_get(hw, mac->vif);
if (pskb == NULL)
return;
- hdr = (struct ieee80211_hdr *)(pskb->data);
+ hdr = rtl_get_hdr(pskb);
info = IEEE80211_SKB_CB(pskb);
-
- queue_index = BEACON_QUEUE;
-
pdesc = &ring->desc[0];
rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc,
- info, pskb, queue_index);
+ info, pskb, BEACON_QUEUE, &tcb_desc);
__skb_queue_tail(&ring->queue, pskb);
@@ -882,7 +1007,6 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw,
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
- struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
rtlpci->up_first_time = true;
rtlpci->being_init_adapter = false;
@@ -890,31 +1014,20 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw,
rtlhal->hw = hw;
rtlpci->pdev = pdev;
- ppsc->inactiveps = false;
- ppsc->leisure_ps = true;
- ppsc->fwctrl_lps = true;
- ppsc->reg_fwctrl_lps = 3;
- ppsc->reg_max_lps_awakeintvl = 5;
-
- if (ppsc->reg_fwctrl_lps == 1)
- ppsc->fwctrl_psmode = FW_PS_MIN_MODE;
- else if (ppsc->reg_fwctrl_lps == 2)
- ppsc->fwctrl_psmode = FW_PS_MAX_MODE;
- else if (ppsc->reg_fwctrl_lps == 3)
- ppsc->fwctrl_psmode = FW_PS_DTIM_MODE;
-
/*Tx/Rx related var */
_rtl_pci_init_trx_var(hw);
- /*IBSS*/ mac->beacon_interval = 100;
+ /*IBSS*/ mac->beacon_interval = 100;
- /*AMPDU*/ mac->min_space_cfg = 0;
+ /*AMPDU*/
+ mac->min_space_cfg = 0;
mac->max_mss_density = 0;
/*set sane AMPDU defaults */
mac->current_ampdu_density = 7;
mac->current_ampdu_factor = 3;
- /*QOS*/ rtlpci->acm_method = eAcmWay2_SW;
+ /*QOS*/
+ rtlpci->acm_method = eAcmWay2_SW;
/*task */
tasklet_init(&rtlpriv->works.irq_tasklet,
@@ -955,7 +1068,8 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
("queue:%d, ring_addr:%p\n", prio, ring));
for (i = 0; i < entries; i++) {
- nextdescaddress = (u32) dma + ((i + 1) % entries) *
+ nextdescaddress = (u32) dma +
+ ((i + 1) % entries) *
sizeof(*ring);
rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]),
@@ -1020,7 +1134,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)
rtlpci->rxbuffersize,
PCI_DMA_FROMDEVICE);
- bufferaddress = (u32)(*((dma_addr_t *)skb->cb));
+ bufferaddress = (*((dma_addr_t *)skb->cb));
rtlpriv->cfg->ops->set_desc((u8 *)entry, false,
HW_DESC_RXBUFF_ADDR,
(u8 *)&bufferaddress);
@@ -1203,72 +1317,73 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
return 0;
}
-static unsigned int _rtl_mac_to_hwqueue(__le16 fc,
- unsigned int mac80211_queue_index)
+static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw,
+ struct sk_buff *skb)
{
- unsigned int hw_queue_index;
-
- if (unlikely(ieee80211_is_beacon(fc))) {
- hw_queue_index = BEACON_QUEUE;
- goto out;
- }
-
- if (ieee80211_is_mgmt(fc)) {
- hw_queue_index = MGNT_QUEUE;
- goto out;
- }
-
- switch (mac80211_queue_index) {
- case 0:
- hw_queue_index = VO_QUEUE;
- break;
- case 1:
- hw_queue_index = VI_QUEUE;
- break;
- case 2:
- hw_queue_index = BE_QUEUE;;
- break;
- case 3:
- hw_queue_index = BK_QUEUE;
- break;
- default:
- hw_queue_index = BE_QUEUE;
- RT_ASSERT(false, ("QSLT_BE queue, skb_queue:%d\n",
- mac80211_queue_index));
- break;
- }
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_sta *sta = info->control.sta;
+ struct rtl_sta_info *sta_entry = NULL;
+ u8 tid = rtl_get_tid(skb);
+
+ if (!sta)
+ return false;
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+
+ if (!rtlpriv->rtlhal.earlymode_enable)
+ return false;
+ if (sta_entry->tids[tid].agg.agg_state != RTL_AGG_OPERATIONAL)
+ return false;
+ if (_rtl_mac_to_hwqueue(hw, skb) > VO_QUEUE)
+ return false;
+ if (tid > 7)
+ return false;
+
+ /* maybe every tid should be checked */
+ if (!rtlpriv->link_info.higher_busytxtraffic[tid])
+ return false;
+
+ spin_lock_bh(&rtlpriv->locks.waitq_lock);
+ skb_queue_tail(&rtlpriv->mac80211.skb_waitq[tid], skb);
+ spin_unlock_bh(&rtlpriv->locks.waitq_lock);
-out:
- return hw_queue_index;
+ return true;
}
-static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct rtl_tcb_desc *ptcb_desc)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_sta_info *sta_entry = NULL;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_sta *sta = info->control.sta;
struct rtl8192_tx_ring *ring;
struct rtl_tx_desc *pdesc;
u8 idx;
- unsigned int queue_index, hw_queue;
+ u8 hw_queue = _rtl_mac_to_hwqueue(hw, skb);
unsigned long flags;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
- __le16 fc = hdr->frame_control;
+ struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
+ __le16 fc = rtl_get_fc(skb);
u8 *pda_addr = hdr->addr1;
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
/*ssn */
- u8 *qc = NULL;
u8 tid = 0;
u16 seq_number = 0;
u8 own;
u8 temp_one = 1;
- if (ieee80211_is_mgmt(fc))
- rtl_tx_mgmt_proc(hw, skb);
- rtl_action_proc(hw, skb, true);
+ if (ieee80211_is_auth(fc)) {
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
+ rtl_ips_nic_on(hw);
+ }
+
+ if (rtlpriv->psc.sw_ps_enabled) {
+ if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) &&
+ !ieee80211_has_pm(fc))
+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
+ }
- queue_index = skb_get_queue_mapping(skb);
- hw_queue = _rtl_mac_to_hwqueue(fc, queue_index);
+ rtl_action_proc(hw, skb, true);
if (is_multicast_ether_addr(pda_addr))
rtlpriv->stats.txbytesmulticast += skb->len;
@@ -1278,7 +1393,6 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
rtlpriv->stats.txbytesunicast += skb->len;
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
-
ring = &rtlpci->tx_ring[hw_queue];
if (hw_queue != BEACON_QUEUE)
idx = (ring->idx + skb_queue_len(&ring->queue)) %
@@ -1301,43 +1415,30 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return skb->len;
}
- /*
- *if(ieee80211_is_nullfunc(fc)) {
- * spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
- * return 1;
- *}
- */
-
if (ieee80211_is_data_qos(fc)) {
- qc = ieee80211_get_qos_ctl(hdr);
- tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
-
- seq_number = mac->tids[tid].seq_number;
- seq_number &= IEEE80211_SCTL_SEQ;
- /*
- *hdr->seq_ctrl = hdr->seq_ctrl &
- *cpu_to_le16(IEEE80211_SCTL_FRAG);
- *hdr->seq_ctrl |= cpu_to_le16(seq_number);
- */
-
- seq_number += 1;
+ tid = rtl_get_tid(skb);
+ if (sta) {
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ seq_number = (le16_to_cpu(hdr->seq_ctrl) &
+ IEEE80211_SCTL_SEQ) >> 4;
+ seq_number += 1;
+
+ if (!ieee80211_has_morefrags(hdr->frame_control))
+ sta_entry->tids[tid].seq_number = seq_number;
+ }
}
if (ieee80211_is_data(fc))
rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX);
- rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc,
- info, skb, hw_queue);
+ rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc,
+ info, skb, hw_queue, ptcb_desc);
__skb_queue_tail(&ring->queue, skb);
- rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true,
+ rtlpriv->cfg->ops->set_desc((u8 *)pdesc, true,
HW_DESC_OWN, (u8 *)&temp_one);
- if (!ieee80211_has_morefrags(hdr->frame_control)) {
- if (qc)
- mac->tids[tid].seq_number = seq_number;
- }
if ((ring->entries - skb_queue_len(&ring->queue)) < 2 &&
hw_queue != BEACON_QUEUE) {
@@ -1359,6 +1460,35 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return 0;
}
+static void rtl_pci_flush(struct ieee80211_hw *hw, bool drop)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ u16 i = 0;
+ int queue_id;
+ struct rtl8192_tx_ring *ring;
+
+ for (queue_id = RTL_PCI_MAX_TX_QUEUE_COUNT - 1; queue_id >= 0;) {
+ u32 queue_len;
+ ring = &pcipriv->dev.tx_ring[queue_id];
+ queue_len = skb_queue_len(&ring->queue);
+ if (queue_len == 0 || queue_id == BEACON_QUEUE ||
+ queue_id == TXCMD_QUEUE) {
+ queue_id--;
+ continue;
+ } else {
+ msleep(20);
+ i++;
+ }
+
+ /* we just wait 1s for all queues */
+ if (rtlpriv->psc.rfpwr_state == ERFOFF ||
+ is_hal_stop(rtlhal) || i >= 200)
+ return;
+ }
+}
+
static void rtl_pci_deinit(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1477,11 +1607,14 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
struct pci_dev *bridge_pdev = pdev->bus->self;
u16 venderid;
u16 deviceid;
+ u8 revisionid;
u16 irqline;
u8 tmp;
+ pcipriv->ndis_adapter.pcibridge_vendor = PCI_BRIDGE_VENDOR_UNKNOWN;
venderid = pdev->vendor;
deviceid = pdev->device;
+ pci_read_config_byte(pdev, 0x8, &revisionid);
pci_read_config_word(pdev, 0x3C, &irqline);
if (deviceid == RTL_PCI_8192_DID ||
@@ -1492,7 +1625,7 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
deviceid == RTL_PCI_8173_DID ||
deviceid == RTL_PCI_8172_DID ||
deviceid == RTL_PCI_8171_DID) {
- switch (pdev->revision) {
+ switch (revisionid) {
case RTL_PCI_REVISION_ID_8192PCIE:
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
("8192 PCI-E is found - "
@@ -1521,6 +1654,12 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
("8192C PCI-E is found - "
"vid/did=%x/%x\n", venderid, deviceid));
+ } else if (deviceid == RTL_PCI_8192DE_DID ||
+ deviceid == RTL_PCI_8192DE_DID2) {
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ ("8192D PCI-E is found - "
+ "vid/did=%x/%x\n", venderid, deviceid));
} else {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
("Err: Unknown device -"
@@ -1529,6 +1668,25 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE;
}
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) {
+ if (revisionid == 0 || revisionid == 1) {
+ if (revisionid == 0) {
+ RT_TRACE(rtlpriv, COMP_INIT,
+ DBG_LOUD, ("Find 92DE MAC0.\n"));
+ rtlhal->interfaceindex = 0;
+ } else if (revisionid == 1) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("Find 92DE MAC1.\n"));
+ rtlhal->interfaceindex = 1;
+ }
+ } else {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("Unknown device - "
+ "VendorID/DeviceID=%x/%x, Revision=%x\n",
+ venderid, deviceid, revisionid));
+ rtlhal->interfaceindex = 0;
+ }
+ }
/*find bus info */
pcipriv->ndis_adapter.busnumber = pdev->bus->number;
pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn);
@@ -1554,12 +1712,12 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
PCI_SLOT(bridge_pdev->devfn);
pcipriv->ndis_adapter.pcibridge_funcnum =
PCI_FUNC(bridge_pdev->devfn);
- pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
- pci_pcie_cap(bridge_pdev);
pcipriv->ndis_adapter.pcicfg_addrport =
(pcipriv->ndis_adapter.pcibridge_busnum << 16) |
(pcipriv->ndis_adapter.pcibridge_devnum << 11) |
(pcipriv->ndis_adapter.pcibridge_funcnum << 8) | (1 << 31);
+ pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
+ pci_pcie_cap(bridge_pdev);
pcipriv->ndis_adapter.num4bytes =
(pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4;
@@ -1642,6 +1800,11 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
pcipriv = (void *)rtlpriv->priv;
pcipriv->dev.pdev = pdev;
+ /* init cfg & intf_ops */
+ rtlpriv->rtlhal.interface = INTF_PCI;
+ rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
+ rtlpriv->intf_ops = &rtl_pci_ops;
+
/*
*init dbgp flags before all
*other functions, because we will
@@ -1659,13 +1822,14 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
return err;
}
- pmem_start = pci_resource_start(pdev, 2);
- pmem_len = pci_resource_len(pdev, 2);
- pmem_flags = pci_resource_flags(pdev, 2);
+ pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id);
+ pmem_len = pci_resource_len(pdev, rtlpriv->cfg->bar_id);
+ pmem_flags = pci_resource_flags(pdev, rtlpriv->cfg->bar_id);
/*shared mem start */
rtlpriv->io.pci_mem_start =
- (unsigned long)pci_iomap(pdev, 2, pmem_len);
+ (unsigned long)pci_iomap(pdev,
+ rtlpriv->cfg->bar_id, pmem_len);
if (rtlpriv->io.pci_mem_start == 0) {
RT_ASSERT(false, ("Can't map PCI mem\n"));
goto fail2;
@@ -1684,11 +1848,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
pci_write_config_byte(pdev, 0x04, 0x06);
pci_write_config_byte(pdev, 0x04, 0x07);
- /* init cfg & intf_ops */
- rtlpriv->rtlhal.interface = INTF_PCI;
- rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
- rtlpriv->intf_ops = &rtl_pci_ops;
-
/* find adapter */
_rtl_pci_find_adapter(pdev, hw);
@@ -1806,7 +1965,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
rtl_pci_deinit(hw);
rtl_deinit_core(hw);
- rtlpriv->cfg->ops->deinit_sw_leds(hw);
_rtl_pci_io_handler_release(hw);
rtlpriv->cfg->ops->deinit_sw_vars(hw);
@@ -1821,6 +1979,9 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
}
pci_disable_device(pdev);
+
+ rtl_pci_disable_aspm(hw);
+
pci_set_drvdata(pdev, NULL);
ieee80211_free_hw(hw);
@@ -1844,10 +2005,15 @@ no need to call hw_disable here.
****************************************/
int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->cfg->ops->hw_suspend(hw);
+ rtl_deinit_rfkill(hw);
+
pci_save_state(pdev);
pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
-
return 0;
}
EXPORT_SYMBOL(rtl_pci_suspend);
@@ -1855,6 +2021,8 @@ EXPORT_SYMBOL(rtl_pci_suspend);
int rtl_pci_resume(struct pci_dev *pdev)
{
int ret;
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
pci_set_power_state(pdev, PCI_D0);
ret = pci_enable_device(pdev);
@@ -1865,15 +2033,20 @@ int rtl_pci_resume(struct pci_dev *pdev)
pci_restore_state(pdev);
+ rtlpriv->cfg->ops->hw_resume(hw);
+ rtl_init_rfkill(hw);
return 0;
}
EXPORT_SYMBOL(rtl_pci_resume);
struct rtl_intf_ops rtl_pci_ops = {
+ .read_efuse_byte = read_efuse_byte,
.adapter_start = rtl_pci_start,
.adapter_stop = rtl_pci_stop,
.adapter_tx = rtl_pci_tx,
+ .flush = rtl_pci_flush,
.reset_trx_ring = rtl_pci_reset_trx_ring,
+ .waitq_insert = rtl_pci_tx_chk_waitq_insert,
.disable_aspm = rtl_pci_disable_aspm,
.enable_aspm = rtl_pci_enable_aspm,
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h
index 0caa8142972..671b1f5aa0c 100644
--- a/drivers/net/wireless/rtlwifi/pci.h
+++ b/drivers/net/wireless/rtlwifi/pci.h
@@ -102,8 +102,8 @@
#define RTL_PCI_8191CE_DID 0x8177 /*8192ce */
#define RTL_PCI_8188CE_DID 0x8176 /*8192ce */
#define RTL_PCI_8192CU_DID 0x8191 /*8192ce */
-#define RTL_PCI_8192DE_DID 0x092D /*8192ce */
-#define RTL_PCI_8192DU_DID 0x092D /*8192ce */
+#define RTL_PCI_8192DE_DID 0x8193 /*8192de */
+#define RTL_PCI_8192DE_DID2 0x002B /*92DE*/
/*8192 support 16 pages of IO registers*/
#define RTL_MEM_MAPPED_IO_RANGE_8190PCI 0x1000
@@ -129,6 +129,11 @@ enum pci_bridge_vendor {
PCI_BRIDGE_VENDOR_MAX,
};
+struct rtl_pci_capabilities_header {
+ u8 capability_id;
+ u8 next;
+};
+
struct rtl_rx_desc {
u32 dword[8];
} __packed;
@@ -161,7 +166,9 @@ struct rtl_pci {
bool driver_is_goingto_unload;
bool up_first_time;
+ bool first_init;
bool being_init_adapter;
+ bool init_ready;
bool irq_enabled;
/*Tx */
@@ -192,11 +199,14 @@ struct rtl_pci {
u8 const_devicepci_aspm_setting;
/*If it supports ASPM, Offset[560h] = 0x40,
otherwise Offset[560h] = 0x00. */
- bool b_support_aspm;
- bool b_support_backdoor;
+ bool support_aspm;
+ bool support_backdoor;
/*QOS & EDCA */
enum acm_method acm_method;
+
+ u16 shortretry_limit;
+ u16 longretry_limit;
};
struct mp_adapter {
@@ -227,6 +237,7 @@ struct rtl_pci_priv {
struct rtl_pci dev;
struct mp_adapter ndis_adapter;
struct rtl_led_ctl ledctl;
+ struct bt_coexist_info bt_coexist;
};
#define rtl_pcipriv(hw) (((struct rtl_pci_priv *)(rtl_priv(hw))->priv))
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c
index 6b7e217b6b8..2bb71195e97 100644
--- a/drivers/net/wireless/rtlwifi/ps.c
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -36,7 +36,6 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
- bool init_status = true;
/*<1> reset trx ring */
if (rtlhal->interface == INTF_PCI)
@@ -49,7 +48,6 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
/*<2> Enable Adapter */
rtlpriv->cfg->ops->hw_init(hw);
RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
- /*init_status = false; */
/*<3> Enable Interrupt */
rtlpriv->cfg->ops->enable_interrupt(hw);
@@ -57,13 +55,12 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
/*<enable timer> */
rtl_watch_dog_timer_callback((unsigned long)hw);
- return init_status;
+ return true;
}
EXPORT_SYMBOL(rtl_ps_enable_nic);
bool rtl_ps_disable_nic(struct ieee80211_hw *hw)
{
- bool status = true;
struct rtl_priv *rtlpriv = rtl_priv(hw);
/*<1> Stop all timer */
@@ -75,7 +72,7 @@ bool rtl_ps_disable_nic(struct ieee80211_hw *hw)
/*<3> Disable Adapter */
rtlpriv->cfg->ops->hw_disable(hw);
- return status;
+ return true;
}
EXPORT_SYMBOL(rtl_ps_disable_nic);
@@ -193,12 +190,13 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
ppsc->swrf_processing = true;
- if (ppsc->inactive_pwrstate == ERFON && rtlhal->interface == INTF_PCI) {
+ if (ppsc->inactive_pwrstate == ERFOFF &&
+ rtlhal->interface == INTF_PCI) {
if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
- RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM) &&
+ RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&
rtlhal->interface == INTF_PCI) {
rtlpriv->intf_ops->disable_aspm(hw);
- RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
+ RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
}
}
@@ -207,9 +205,10 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
if (ppsc->inactive_pwrstate == ERFOFF &&
rtlhal->interface == INTF_PCI) {
- if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) {
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
+ !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
rtlpriv->intf_ops->enable_aspm(hw);
- RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
+ RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
}
}
@@ -233,6 +232,9 @@ void rtl_ips_nic_off_wq_callback(void *data)
return;
}
+ if (mac->link_state > MAC80211_NOLINK)
+ return;
+
if (is_hal_stop(rtlhal))
return;
@@ -284,10 +286,14 @@ void rtl_ips_nic_off(struct ieee80211_hw *hw)
void rtl_ips_nic_on(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
enum rf_pwrstate rtstate;
unsigned long flags;
+ if (mac->opmode != NL80211_IFTYPE_STATION)
+ return;
+
spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags);
if (ppsc->inactiveps) {
@@ -370,8 +376,7 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
* mode and set RPWM to turn RF on.
*/
- if ((ppsc->fwctrl_lps) && (ppsc->leisure_ps) &&
- ppsc->report_linked) {
+ if ((ppsc->fwctrl_lps) && ppsc->report_linked) {
bool fw_current_inps;
if (ppsc->dot11_psmode == EACTIVE) {
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
@@ -425,7 +430,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
struct rtl_priv *rtlpriv = rtl_priv(hw);
unsigned long flag;
- if (!(ppsc->fwctrl_lps && ppsc->leisure_ps))
+ if (!ppsc->fwctrl_lps)
return;
if (rtlpriv->sec.being_setkey)
@@ -446,17 +451,16 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
- if (ppsc->leisure_ps) {
- /* Idle for a while if we connect to AP a while ago. */
- if (mac->cnt_after_linked >= 2) {
- if (ppsc->dot11_psmode == EACTIVE) {
- RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ /* Idle for a while if we connect to AP a while ago. */
+ if (mac->cnt_after_linked >= 2) {
+ if (ppsc->dot11_psmode == EACTIVE) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
("Enter 802.11 power save mode...\n"));
- rtl_lps_set_psmode(hw, EAUTOPS);
- }
+ rtl_lps_set_psmode(hw, EAUTOPS);
}
}
+
spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
}
@@ -470,17 +474,17 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
- if (ppsc->fwctrl_lps && ppsc->leisure_ps) {
+ if (ppsc->fwctrl_lps) {
if (ppsc->dot11_psmode != EACTIVE) {
/*FIX ME */
rtlpriv->cfg->ops->enable_interrupt(hw);
if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
- RT_IN_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM) &&
+ RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&
rtlhal->interface == INTF_PCI) {
rtlpriv->intf_ops->disable_aspm(hw);
- RT_CLEAR_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM);
+ RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
}
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
@@ -491,3 +495,214 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
}
spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
}
+
+/* For sw LPS*/
+void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct ieee80211_hdr *hdr = (void *) data;
+ struct ieee80211_tim_ie *tim_ie;
+ u8 *tim;
+ u8 tim_len;
+ bool u_buffed;
+ bool m_buffed;
+
+ if (mac->opmode != NL80211_IFTYPE_STATION)
+ return;
+
+ if (!rtlpriv->psc.swctrl_lps)
+ return;
+
+ if (rtlpriv->mac80211.link_state != MAC80211_LINKED)
+ return;
+
+ if (!rtlpriv->psc.sw_ps_enabled)
+ return;
+
+ if (rtlpriv->psc.fwctrl_lps)
+ return;
+
+ if (likely(!(hw->conf.flags & IEEE80211_CONF_PS)))
+ return;
+
+ /* check if this really is a beacon */
+ if (!ieee80211_is_beacon(hdr->frame_control))
+ return;
+
+ /* min. beacon length + FCS_LEN */
+ if (len <= 40 + FCS_LEN)
+ return;
+
+ /* and only beacons from the associated BSSID, please */
+ if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
+ return;
+
+ rtlpriv->psc.last_beacon = jiffies;
+
+ tim = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_TIM);
+ if (!tim)
+ return;
+
+ if (tim[1] < sizeof(*tim_ie))
+ return;
+
+ tim_len = tim[1];
+ tim_ie = (struct ieee80211_tim_ie *) &tim[2];
+
+ if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period))
+ rtlpriv->psc.dtim_counter = tim_ie->dtim_count;
+
+ /* Check whenever the PHY can be turned off again. */
+
+ /* 1. What about buffered unicast traffic for our AID? */
+ u_buffed = ieee80211_check_tim(tim_ie, tim_len,
+ rtlpriv->mac80211.assoc_id);
+
+ /* 2. Maybe the AP wants to send multicast/broadcast data? */
+ m_buffed = tim_ie->bitmap_ctrl & 0x01;
+ rtlpriv->psc.multi_buffered = m_buffed;
+
+ /* unicast will process by mac80211 through
+ * set ~IEEE80211_CONF_PS, So we just check
+ * multicast frames here */
+ if (!m_buffed) {
+ /* back to low-power land. and delay is
+ * prevent null power save frame tx fail */
+ queue_delayed_work(rtlpriv->works.rtl_wq,
+ &rtlpriv->works.ps_work, MSECS(5));
+ } else {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("u_bufferd: %x, "
+ "m_buffered: %x\n", u_buffed, m_buffed));
+ }
+}
+
+void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ unsigned long flag;
+
+ if (!rtlpriv->psc.swctrl_lps)
+ return;
+ if (mac->link_state != MAC80211_LINKED)
+ return;
+
+ if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
+ RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
+ rtlpriv->intf_ops->disable_aspm(hw);
+ RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+ }
+
+ spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+ rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false);
+ spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+}
+
+void rtl_swlps_rfon_wq_callback(void *data)
+{
+ struct rtl_works *rtlworks =
+ container_of_dwork_rtl(data, struct rtl_works, ps_rfon_wq);
+ struct ieee80211_hw *hw = rtlworks->hw;
+
+ rtl_swlps_rf_awake(hw);
+}
+
+void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ unsigned long flag;
+ u8 sleep_intv;
+
+ if (!rtlpriv->psc.sw_ps_enabled)
+ return;
+
+ if ((rtlpriv->sec.being_setkey) ||
+ (mac->opmode == NL80211_IFTYPE_ADHOC))
+ return;
+
+ /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
+ if ((mac->link_state != MAC80211_LINKED) || (mac->cnt_after_linked < 5))
+ return;
+
+ if (rtlpriv->link_info.busytraffic)
+ return;
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+ if (rtlpriv->psc.rfchange_inprogress) {
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+ return;
+ }
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+
+ spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+ rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS, false);
+ spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
+ !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
+ rtlpriv->intf_ops->enable_aspm(hw);
+ RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+ }
+
+ /* here is power save alg, when this beacon is DTIM
+ * we will set sleep time to dtim_period * n;
+ * when this beacon is not DTIM, we will set sleep
+ * time to sleep_intv = rtlpriv->psc.dtim_counter or
+ * MAX_SW_LPS_SLEEP_INTV(default set to 5) */
+
+ if (rtlpriv->psc.dtim_counter == 0) {
+ if (hw->conf.ps_dtim_period == 1)
+ sleep_intv = hw->conf.ps_dtim_period * 2;
+ else
+ sleep_intv = hw->conf.ps_dtim_period;
+ } else {
+ sleep_intv = rtlpriv->psc.dtim_counter;
+ }
+
+ if (sleep_intv > MAX_SW_LPS_SLEEP_INTV)
+ sleep_intv = MAX_SW_LPS_SLEEP_INTV;
+
+ /* this print should always be dtim_conter = 0 &
+ * sleep = dtim_period, that meaons, we should
+ * awake before every dtim */
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+ ("dtim_counter:%x will sleep :%d"
+ " beacon_intv\n", rtlpriv->psc.dtim_counter, sleep_intv));
+
+ /* we tested that 40ms is enough for sw & hw sw delay */
+ queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq,
+ MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40));
+}
+
+
+void rtl_swlps_wq_callback(void *data)
+{
+ struct rtl_works *rtlworks = container_of_dwork_rtl(data,
+ struct rtl_works,
+ ps_work);
+ struct ieee80211_hw *hw = rtlworks->hw;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ bool ps = false;
+
+ ps = (hw->conf.flags & IEEE80211_CONF_PS);
+
+ /* we can sleep after ps null send ok */
+ if (rtlpriv->psc.state_inap) {
+ rtl_swlps_rf_sleep(hw);
+
+ if (rtlpriv->psc.state && !ps) {
+ rtlpriv->psc.sleep_ms = jiffies_to_msecs(jiffies -
+ rtlpriv->psc.last_action);
+ }
+
+ if (ps)
+ rtlpriv->psc.last_slept = jiffies;
+
+ rtlpriv->psc.last_action = jiffies;
+ rtlpriv->psc.state = ps;
+ }
+}
diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h
index ae56da801a2..e3bf8984037 100644
--- a/drivers/net/wireless/rtlwifi/ps.h
+++ b/drivers/net/wireless/rtlwifi/ps.h
@@ -30,6 +30,8 @@
#ifndef __REALTEK_RTL_PCI_PS_H__
#define __REALTEK_RTL_PCI_PS_H__
+#define MAX_SW_LPS_SLEEP_INTV 5
+
bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
enum rf_pwrstate state_toset, u32 changesource,
bool protect_or_not);
@@ -40,4 +42,11 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw);
void rtl_ips_nic_off_wq_callback(void *data);
void rtl_lps_enter(struct ieee80211_hw *hw);
void rtl_lps_leave(struct ieee80211_hw *hw);
+
+void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len);
+void rtl_swlps_wq_callback(void *data);
+void rtl_swlps_rfon_wq_callback(void *data);
+void rtl_swlps_rf_awake(struct ieee80211_hw *hw);
+void rtl_swlps_rf_sleep(struct ieee80211_hw *hw);
+
#endif
diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c
index 91634107434..30da68a7778 100644
--- a/drivers/net/wireless/rtlwifi/rc.c
+++ b/drivers/net/wireless/rtlwifi/rc.c
@@ -38,17 +38,14 @@
*CCK11M or OFDM_54M based on wireless mode.
*/
static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,
+ struct ieee80211_sta *sta,
struct sk_buff *skb, bool not_data)
{
struct rtl_mac *rtlmac = rtl_mac(rtlpriv);
-
- /*
- *mgt use 1M, although we have check it
- *before this function use rate_control_send_low,
- *we still check it here
- */
- if (not_data)
- return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_sta_info *sta_entry = NULL;
+ u8 wireless_mode = 0;
/*
*this rate is no use for true rate, firmware
@@ -57,35 +54,78 @@ static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,
*2.in rtl_get_tcb_desc when we check rate is
* 1M we will not use FW rate but user rate.
*/
- if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true)) {
- return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
+ if (rtlmac->opmode == NL80211_IFTYPE_AP ||
+ rtlmac->opmode == NL80211_IFTYPE_ADHOC) {
+ if (sta) {
+ sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+ wireless_mode = sta_entry->wireless_mode;
+ } else {
+ return 0;
+ }
+ } else {
+ wireless_mode = rtlmac->mode;
+ }
+
+ if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true) ||
+ not_data) {
+ return 0;
} else {
- if (rtlmac->mode == WIRELESS_MODE_B)
- return rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M];
- else
- return rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M];
+ if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+ if (wireless_mode == WIRELESS_MODE_B) {
+ return B_MODE_MAX_RIX;
+ } else if (wireless_mode == WIRELESS_MODE_G) {
+ return G_MODE_MAX_RIX;
+ } else {
+ if (get_rf_type(rtlphy) != RF_2T2R)
+ return N_MODE_MCS7_RIX;
+ else
+ return N_MODE_MCS15_RIX;
+ }
+ } else {
+ if (wireless_mode == WIRELESS_MODE_A) {
+ return A_MODE_MAX_RIX;
+ } else {
+ if (get_rf_type(rtlphy) != RF_2T2R)
+ return N_MODE_MCS7_RIX;
+ else
+ return N_MODE_MCS15_RIX;
+ }
+ }
}
}
static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv,
+ struct ieee80211_sta *sta,
struct ieee80211_tx_rate *rate,
struct ieee80211_tx_rate_control *txrc,
- u8 tries, u8 rix, int rtsctsenable,
+ u8 tries, char rix, int rtsctsenable,
bool not_data)
{
struct rtl_mac *mac = rtl_mac(rtlpriv);
+ u8 sgi_20 = 0, sgi_40 = 0;
+ if (sta) {
+ sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20;
+ sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
+ }
rate->count = tries;
- rate->idx = (rix > 0x2) ? rix : 0x2;
+ rate->idx = rix >= 0x00 ? rix : 0x00;
if (!not_data) {
if (txrc->short_preamble)
rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
- if (mac->bw_40)
- rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
- if (mac->sgi_20 || mac->sgi_40)
+ if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC) {
+ if (sta && (sta->ht_cap.cap &
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40))
+ rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+ } else {
+ if (mac->bw_40)
+ rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+ }
+ if (sgi_20 || sgi_40)
rate->flags |= IEEE80211_TX_RC_SHORT_GI;
- if (mac->ht_enable)
+ if (sta && sta->ht_cap.ht_supported)
rate->flags |= IEEE80211_TX_RC_MCS;
}
}
@@ -97,39 +137,39 @@ static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta,
struct sk_buff *skb = txrc->skb;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rates = tx_info->control.rates;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- __le16 fc = hdr->frame_control;
+ __le16 fc = rtl_get_fc(skb);
u8 try_per_rate, i, rix;
bool not_data = !ieee80211_is_data(fc);
if (rate_control_send_low(sta, priv_sta, txrc))
return;
- rix = _rtl_rc_get_highest_rix(rtlpriv, skb, not_data);
-
+ rix = _rtl_rc_get_highest_rix(rtlpriv, sta, skb, not_data);
try_per_rate = 1;
- _rtl_rc_rate_set_series(rtlpriv, &rates[0], txrc,
+ _rtl_rc_rate_set_series(rtlpriv, sta, &rates[0], txrc,
try_per_rate, rix, 1, not_data);
if (!not_data) {
for (i = 1; i < 4; i++)
- _rtl_rc_rate_set_series(rtlpriv, &rates[i],
+ _rtl_rc_rate_set_series(rtlpriv, sta, &rates[i],
txrc, i, (rix - i), 1,
not_data);
}
}
-static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, u16 tid)
+static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv,
+ struct rtl_sta_info *sta_entry, u16 tid)
{
struct rtl_mac *mac = rtl_mac(rtlpriv);
if (mac->act_scanning)
return false;
- if (mac->cnt_after_linked < 3)
+ if (mac->opmode == NL80211_IFTYPE_STATION &&
+ mac->cnt_after_linked < 3)
return false;
- if (mac->tids[tid].agg.agg_state == RTL_AGG_OFF)
+ if (sta_entry->tids[tid].agg.agg_state == RTL_AGG_STOP)
return true;
return false;
@@ -143,11 +183,9 @@ static void rtl_tx_status(void *ppriv,
{
struct rtl_priv *rtlpriv = ppriv;
struct rtl_mac *mac = rtl_mac(rtlpriv);
- struct ieee80211_hdr *hdr;
- __le16 fc;
-
- hdr = (struct ieee80211_hdr *)skb->data;
- fc = hdr->frame_control;
+ struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
+ __le16 fc = rtl_get_fc(skb);
+ struct rtl_sta_info *sta_entry;
if (!priv_sta || !ieee80211_is_data(fc))
return;
@@ -159,17 +197,21 @@ static void rtl_tx_status(void *ppriv,
|| is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
return;
- /* Check if aggregation has to be enabled for this tid */
- if (conf_is_ht(&mac->hw->conf) &&
- !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
- if (ieee80211_is_data_qos(fc)) {
- u8 *qc, tid;
-
- qc = ieee80211_get_qos_ctl(hdr);
- tid = qc[0] & 0xf;
-
- if (_rtl_tx_aggr_check(rtlpriv, tid))
- ieee80211_start_tx_ba_session(sta, tid, 5000);
+ if (sta) {
+ /* Check if aggregation has to be enabled for this tid */
+ sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+ if ((sta->ht_cap.ht_supported == true) &&
+ !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
+ if (ieee80211_is_data_qos(fc)) {
+ u8 tid = rtl_get_tid(skb);
+ if (_rtl_tx_aggr_check(rtlpriv, sta_entry,
+ tid)) {
+ sta_entry->tids[tid].agg.agg_state =
+ RTL_AGG_PROGRESS;
+ ieee80211_start_tx_ba_session(sta,
+ tid, 5000);
+ }
+ }
}
}
}
@@ -178,43 +220,6 @@ static void rtl_rate_init(void *ppriv,
struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta)
{
- struct rtl_priv *rtlpriv = ppriv;
- struct rtl_mac *mac = rtl_mac(rtlpriv);
- u8 is_ht = conf_is_ht(&mac->hw->conf);
-
- if ((mac->opmode == NL80211_IFTYPE_STATION) ||
- (mac->opmode == NL80211_IFTYPE_MESH_POINT) ||
- (mac->opmode == NL80211_IFTYPE_ADHOC)) {
-
- switch (sband->band) {
- case IEEE80211_BAND_2GHZ:
- rtlpriv->rate_priv->cur_ratetab_idx =
- RATR_INX_WIRELESS_G;
- if (is_ht)
- rtlpriv->rate_priv->cur_ratetab_idx =
- RATR_INX_WIRELESS_NGB;
- break;
- case IEEE80211_BAND_5GHZ:
- rtlpriv->rate_priv->cur_ratetab_idx =
- RATR_INX_WIRELESS_A;
- if (is_ht)
- rtlpriv->rate_priv->cur_ratetab_idx =
- RATR_INX_WIRELESS_NGB;
- break;
- default:
- RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
- ("Invalid band\n"));
- rtlpriv->rate_priv->cur_ratetab_idx =
- RATR_INX_WIRELESS_NGB;
- break;
- }
-
- RT_TRACE(rtlpriv, COMP_RATE, DBG_DMESG,
- ("Choosing rate table index: %d\n",
- rtlpriv->rate_priv->cur_ratetab_idx));
-
- }
-
}
static void rtl_rate_update(void *ppriv,
@@ -223,49 +228,6 @@ static void rtl_rate_update(void *ppriv,
u32 changed,
enum nl80211_channel_type oper_chan_type)
{
- struct rtl_priv *rtlpriv = ppriv;
- struct rtl_mac *mac = rtl_mac(rtlpriv);
- struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
- bool oper_cw40 = false, oper_sgi40;
- bool local_cw40 = mac->bw_40;
- bool local_sgi40 = mac->sgi_40;
- u8 is_ht = conf_is_ht(&mac->hw->conf);
-
- if (changed & IEEE80211_RC_HT_CHANGED) {
- if (mac->opmode != NL80211_IFTYPE_STATION)
- return;
-
- if (rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
- rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
- oper_cw40 = true;
-
- oper_sgi40 = mac->sgi_40;
-
- if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) {
- switch (sband->band) {
- case IEEE80211_BAND_2GHZ:
- rtlpriv->rate_priv->cur_ratetab_idx =
- RATR_INX_WIRELESS_G;
- if (is_ht)
- rtlpriv->rate_priv->cur_ratetab_idx =
- RATR_INX_WIRELESS_NGB;
- break;
- case IEEE80211_BAND_5GHZ:
- rtlpriv->rate_priv->cur_ratetab_idx =
- RATR_INX_WIRELESS_A;
- if (is_ht)
- rtlpriv->rate_priv->cur_ratetab_idx =
- RATR_INX_WIRELESS_NGB;
- break;
- default:
- RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
- ("Invalid band\n"));
- rtlpriv->rate_priv->cur_ratetab_idx =
- RATR_INX_WIRELESS_NGB;
- break;
- }
- }
- }
}
static void *rtl_rate_alloc(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/rtlwifi/rc.h b/drivers/net/wireless/rtlwifi/rc.h
index b4667c035f0..4afa2c20adc 100644
--- a/drivers/net/wireless/rtlwifi/rc.h
+++ b/drivers/net/wireless/rtlwifi/rc.h
@@ -30,8 +30,15 @@
#ifndef __RTL_RC_H__
#define __RTL_RC_H__
+#define B_MODE_MAX_RIX 3
+#define G_MODE_MAX_RIX 11
+#define A_MODE_MAX_RIX 7
+
+/* in mac80211 mcs0-mcs15 is idx0-idx15*/
+#define N_MODE_MCS7_RIX 7
+#define N_MODE_MCS15_RIX 15
+
struct rtl_rate_priv {
- u8 cur_ratetab_idx;
u8 ht_cap;
};
diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c
index d26f957981a..8f6718f163e 100644
--- a/drivers/net/wireless/rtlwifi/regd.c
+++ b/drivers/net/wireless/rtlwifi/regd.c
@@ -66,31 +66,83 @@ static struct country_code_to_enum_rd allCountries[] = {
NL80211_RRF_PASSIVE_SCAN | \
NL80211_RRF_NO_OFDM)
+/* 5G chan 36 - chan 64*/
+#define RTL819x_5GHZ_5150_5350 \
+ REG_RULE(5150-10, 5350+10, 40, 0, 30, \
+ NL80211_RRF_PASSIVE_SCAN | \
+ NL80211_RRF_NO_IBSS)
+
+/* 5G chan 100 - chan 165*/
+#define RTL819x_5GHZ_5470_5850 \
+ REG_RULE(5470-10, 5850+10, 40, 0, 30, \
+ NL80211_RRF_PASSIVE_SCAN | \
+ NL80211_RRF_NO_IBSS)
+
+/* 5G chan 149 - chan 165*/
+#define RTL819x_5GHZ_5725_5850 \
+ REG_RULE(5725-10, 5850+10, 40, 0, 30, \
+ NL80211_RRF_PASSIVE_SCAN | \
+ NL80211_RRF_NO_IBSS)
+
+#define RTL819x_5GHZ_ALL \
+ (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850)
+
static const struct ieee80211_regdomain rtl_regdom_11 = {
.n_reg_rules = 1,
.alpha2 = "99",
.reg_rules = {
RTL819x_2GHZ_CH01_11,
- }
+ }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_12_13 = {
+ .n_reg_rules = 2,
+ .alpha2 = "99",
+ .reg_rules = {
+ RTL819x_2GHZ_CH01_11,
+ RTL819x_2GHZ_CH12_13,
+ }
};
-static const struct ieee80211_regdomain rtl_regdom_global = {
+static const struct ieee80211_regdomain rtl_regdom_no_midband = {
.n_reg_rules = 3,
.alpha2 = "99",
.reg_rules = {
RTL819x_2GHZ_CH01_11,
- RTL819x_2GHZ_CH12_13,
- RTL819x_2GHZ_CH14,
- }
+ RTL819x_5GHZ_5150_5350,
+ RTL819x_5GHZ_5725_5850,
+ }
};
-static const struct ieee80211_regdomain rtl_regdom_world = {
- .n_reg_rules = 2,
+static const struct ieee80211_regdomain rtl_regdom_60_64 = {
+ .n_reg_rules = 3,
.alpha2 = "99",
.reg_rules = {
RTL819x_2GHZ_CH01_11,
- RTL819x_2GHZ_CH12_13,
- }
+ RTL819x_2GHZ_CH12_13,
+ RTL819x_5GHZ_5725_5850,
+ }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_14_60_64 = {
+ .n_reg_rules = 4,
+ .alpha2 = "99",
+ .reg_rules = {
+ RTL819x_2GHZ_CH01_11,
+ RTL819x_2GHZ_CH12_13,
+ RTL819x_2GHZ_CH14,
+ RTL819x_5GHZ_5725_5850,
+ }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_14 = {
+ .n_reg_rules = 3,
+ .alpha2 = "99",
+ .reg_rules = {
+ RTL819x_2GHZ_CH01_11,
+ RTL819x_2GHZ_CH12_13,
+ RTL819x_2GHZ_CH14,
+ }
};
static bool _rtl_is_radar_freq(u16 center_freq)
@@ -162,6 +214,8 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,
u32 bandwidth = 0;
int r;
+ if (!wiphy->bands[IEEE80211_BAND_2GHZ])
+ return;
sband = wiphy->bands[IEEE80211_BAND_2GHZ];
/*
@@ -292,25 +346,26 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select(
{
switch (reg->country_code) {
case COUNTRY_CODE_FCC:
+ return &rtl_regdom_no_midband;
case COUNTRY_CODE_IC:
return &rtl_regdom_11;
case COUNTRY_CODE_ETSI:
+ case COUNTRY_CODE_TELEC_NETGEAR:
+ return &rtl_regdom_60_64;
case COUNTRY_CODE_SPAIN:
case COUNTRY_CODE_FRANCE:
case COUNTRY_CODE_ISRAEL:
- case COUNTRY_CODE_TELEC_NETGEAR:
- return &rtl_regdom_world;
+ case COUNTRY_CODE_WORLD_WIDE_13:
+ return &rtl_regdom_12_13;
case COUNTRY_CODE_MKK:
case COUNTRY_CODE_MKK1:
case COUNTRY_CODE_TELEC:
case COUNTRY_CODE_MIC:
- return &rtl_regdom_global;
+ return &rtl_regdom_14_60_64;
case COUNTRY_CODE_GLOBAL_DOMAIN:
- return &rtl_regdom_global;
- case COUNTRY_CODE_WORLD_WIDE_13:
- return &rtl_regdom_world;
+ return &rtl_regdom_14;
default:
- return &rtl_regdom_world;
+ return &rtl_regdom_no_midband;
}
}
@@ -323,9 +378,11 @@ static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,
const struct ieee80211_regdomain *regd;
wiphy->reg_notifier = reg_notifier;
+
wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY;
wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS;
+
regd = _rtl_regdomain_select(reg);
wiphy_apply_custom_regulatory(wiphy, regd);
_rtl_reg_apply_radar_flags(wiphy);
@@ -355,8 +412,8 @@ int rtl_regd_init(struct ieee80211_hw *hw,
if (wiphy == NULL || &rtlpriv->regd == NULL)
return -EINVAL;
- /* force the channel plan to world wide 13 */
- rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13;
+ /* init country_code from efuse channel plan */
+ rtlpriv->regd.country_code = rtlpriv->efuse.channel_plan;
RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
(KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n",
@@ -373,8 +430,8 @@ int rtl_regd_init(struct ieee80211_hw *hw,
country = _rtl_regd_find_country(rtlpriv->regd.country_code);
if (country) {
- rtlpriv->regd.alpha2[0] = country->isoName[0];
- rtlpriv->regd.alpha2[1] = country->isoName[1];
+ rtlpriv->regd.alpha2[0] = country->iso_name[0];
+ rtlpriv->regd.alpha2[1] = country->iso_name[1];
} else {
rtlpriv->regd.alpha2[0] = '0';
rtlpriv->regd.alpha2[1] = '0';
diff --git a/drivers/net/wireless/rtlwifi/regd.h b/drivers/net/wireless/rtlwifi/regd.h
index 4cdbc4ae76d..d23118938fa 100644
--- a/drivers/net/wireless/rtlwifi/regd.h
+++ b/drivers/net/wireless/rtlwifi/regd.h
@@ -32,7 +32,7 @@
struct country_code_to_enum_rd {
u16 countrycode;
- const char *isoName;
+ const char *iso_name;
};
enum country_code_type_t {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
index bb023274414..97183829b9b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
@@ -28,10 +28,26 @@
*****************************************************************************/
#include "dm_common.h"
+#include "phy_common.h"
+#include "../pci.h"
+#include "../base.h"
struct dig_t dm_digtable;
static struct ps_t dm_pstable;
+#define BT_RSSI_STATE_NORMAL_POWER BIT_OFFSET_LEN_MASK_32(0, 1)
+#define BT_RSSI_STATE_AMDPU_OFF BIT_OFFSET_LEN_MASK_32(1, 1)
+#define BT_RSSI_STATE_SPECIAL_LOW BIT_OFFSET_LEN_MASK_32(2, 1)
+#define BT_RSSI_STATE_BG_EDCA_LOW BIT_OFFSET_LEN_MASK_32(3, 1)
+#define BT_RSSI_STATE_TXPOWER_LOW BIT_OFFSET_LEN_MASK_32(4, 1)
+
+#define RTLPRIV (struct rtl_priv *)
+#define GET_UNDECORATED_AVERAGE_RSSI(_priv) \
+ ((RTLPRIV(_priv))->mac80211.opmode == \
+ NL80211_IFTYPE_ADHOC) ? \
+ ((RTLPRIV(_priv))->dm.entry_min_undecoratedsmoothed_pwdb) : \
+ ((RTLPRIV(_priv))->dm.undecorated_smoothed_pwdb)
+
static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
0x7f8001fe,
0x788001e2,
@@ -304,7 +320,7 @@ static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
{
- static u8 binitialized; /* initialized to false */
+ static u8 initialized; /* initialized to false */
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
@@ -315,11 +331,11 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
if ((multi_sta == false) || (dm_digtable.cursta_connectctate !=
DIG_STA_DISCONNECT)) {
- binitialized = false;
+ initialized = false;
dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
return;
- } else if (binitialized == false) {
- binitialized = true;
+ } else if (initialized == false) {
+ initialized = true;
dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
dm_digtable.cur_igvalue = 0x20;
rtl92c_dm_write_dig(hw);
@@ -461,10 +477,7 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
if (mac->act_scanning == true)
return;
- if ((mac->link_state > MAC80211_NOLINK) &&
- (mac->link_state < MAC80211_LINKED))
- dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT;
- else if (mac->link_state >= MAC80211_LINKED)
+ if (mac->link_state >= MAC80211_LINKED)
dm_digtable.cursta_connectctate = DIG_STA_CONNECT;
else
dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT;
@@ -562,23 +575,42 @@ EXPORT_SYMBOL(rtl92c_dm_init_edca_turbo);
static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
static u64 last_txok_cnt;
static u64 last_rxok_cnt;
- u64 cur_txok_cnt;
- u64 cur_rxok_cnt;
+ static u32 last_bt_edca_ul;
+ static u32 last_bt_edca_dl;
+ u64 cur_txok_cnt = 0;
+ u64 cur_rxok_cnt = 0;
u32 edca_be_ul = 0x5ea42b;
u32 edca_be_dl = 0x5ea42b;
+ bool bt_change_edca = false;
- if (mac->opmode == NL80211_IFTYPE_ADHOC)
- goto dm_checkedcaturbo_exit;
+ if ((last_bt_edca_ul != rtlpcipriv->bt_coexist.bt_edca_ul) ||
+ (last_bt_edca_dl != rtlpcipriv->bt_coexist.bt_edca_dl)) {
+ rtlpriv->dm.current_turbo_edca = false;
+ last_bt_edca_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
+ last_bt_edca_dl = rtlpcipriv->bt_coexist.bt_edca_dl;
+ }
+
+ if (rtlpcipriv->bt_coexist.bt_edca_ul != 0) {
+ edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
+ bt_change_edca = true;
+ }
+
+ if (rtlpcipriv->bt_coexist.bt_edca_dl != 0) {
+ edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_dl;
+ bt_change_edca = true;
+ }
if (mac->link_state != MAC80211_LINKED) {
rtlpriv->dm.current_turbo_edca = false;
return;
}
- if (!mac->ht_enable) { /*FIX MERGE */
+ if ((!mac->ht_enable) && (!rtlpcipriv->bt_coexist.bt_coexistence)) {
if (!(edca_be_ul & 0xffff0000))
edca_be_ul |= 0x005e0000;
@@ -586,10 +618,12 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw)
edca_be_dl |= 0x005e0000;
}
- if ((!rtlpriv->dm.is_any_nonbepkts) &&
- (!rtlpriv->dm.disable_framebursting)) {
+ if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) &&
+ (!rtlpriv->dm.disable_framebursting))) {
+
cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
+
if (cur_rxok_cnt > 4 * cur_txok_cnt) {
if (!rtlpriv->dm.is_cur_rdlstate ||
!rtlpriv->dm.current_turbo_edca) {
@@ -618,7 +652,6 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw)
}
}
-dm_checkedcaturbo_exit:
rtlpriv->dm.is_any_nonbepkts = false;
last_txok_cnt = rtlpriv->stats.txbytesunicast;
last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
@@ -633,14 +666,14 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u8 thermalvalue, delta, delta_lck, delta_iqk;
long ele_a, ele_d, temp_cck, val_x, value32;
- long val_y, ele_c;
- u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old;
+ long val_y, ele_c = 0;
+ u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0;
int i;
bool is2t = IS_92C_SERIAL(rtlhal->version);
u8 txpwr_level[2] = {0, 0};
u8 ofdm_min_index = 6, rf;
- rtlpriv->dm.txpower_trackingInit = true;
+ rtlpriv->dm.txpower_trackinginit = true;
RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
("rtl92c_dm_txpower_tracking_callback_thermalmeter\n"));
@@ -683,7 +716,6 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
if (ele_d == (ofdmswing_table[i] &
MASKOFDM_D)) {
- ofdm_index_old[1] = (u8) i;
RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
DBG_LOUD,
@@ -1062,7 +1094,7 @@ static void rtl92c_dm_initialize_txpower_tracking_thermalmeter(
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtlpriv->dm.txpower_tracking = true;
- rtlpriv->dm.txpower_trackingInit = false;
+ rtlpriv->dm.txpower_trackinginit = false;
RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
("pMgntInfo->txpower_tracking = %d\n",
@@ -1132,6 +1164,7 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rate_adaptive *p_ra = &(rtlpriv->ra);
u32 low_rssithresh_for_ra, high_rssithresh_for_ra;
+ struct ieee80211_sta *sta = NULL;
if (is_hal_stop(rtlhal)) {
RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
@@ -1145,8 +1178,8 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
return;
}
- if (mac->link_state == MAC80211_LINKED) {
-
+ if (mac->link_state == MAC80211_LINKED &&
+ mac->opmode == NL80211_IFTYPE_STATION) {
switch (p_ra->pre_ratr_state) {
case DM_RATR_STA_HIGH:
high_rssithresh_for_ra = 50;
@@ -1185,10 +1218,13 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
("PreState = %d, CurState = %d\n",
p_ra->pre_ratr_state, p_ra->ratr_state));
- rtlpriv->cfg->ops->update_rate_mask(hw,
+ rcu_read_lock();
+ sta = ieee80211_find_sta(mac->vif, mac->bssid);
+ rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
p_ra->ratr_state);
p_ra->pre_ratr_state = p_ra->ratr_state;
+ rcu_read_unlock();
}
}
}
@@ -1202,51 +1238,6 @@ static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
dm_pstable.rssi_val_min = 0;
}
-static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw)
-{
- struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct rtl_phy *rtlphy = &(rtlpriv->phy);
-
- if (dm_pstable.rssi_val_min != 0) {
- if (dm_pstable.pre_ccastate == CCA_2R) {
- if (dm_pstable.rssi_val_min >= 35)
- dm_pstable.cur_ccasate = CCA_1R;
- else
- dm_pstable.cur_ccasate = CCA_2R;
- } else {
- if (dm_pstable.rssi_val_min <= 30)
- dm_pstable.cur_ccasate = CCA_2R;
- else
- dm_pstable.cur_ccasate = CCA_1R;
- }
- } else {
- dm_pstable.cur_ccasate = CCA_MAX;
- }
-
- if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) {
- if (dm_pstable.cur_ccasate == CCA_1R) {
- if (get_rf_type(rtlphy) == RF_2T2R) {
- rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
- MASKBYTE0, 0x13);
- rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20);
- } else {
- rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
- MASKBYTE0, 0x23);
- rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c);
- }
- } else {
- rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0,
- 0x33);
- rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63);
- }
- dm_pstable.pre_ccastate = dm_pstable.cur_ccasate;
- }
-
- RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n",
- (dm_pstable.cur_ccasate ==
- 0) ? "1RCCA" : "2RCCA"));
-}
-
void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
{
static u8 initialize;
@@ -1352,7 +1343,9 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
}
if (IS_92C_SERIAL(rtlhal->version))
- rtl92c_dm_1r_cca(hw);
+ ;/* rtl92c_dm_1r_cca(hw); */
+ else
+ rtl92c_dm_rf_saving(hw, false);
}
void rtl92c_dm_init(struct ieee80211_hw *hw)
@@ -1369,6 +1362,84 @@ void rtl92c_dm_init(struct ieee80211_hw *hw)
}
EXPORT_SYMBOL(rtl92c_dm_init);
+void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ long undecorated_smoothed_pwdb;
+
+ if (!rtlpriv->dm.dynamic_txpower_enable)
+ return;
+
+ if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
+ rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
+ return;
+ }
+
+ if ((mac->link_state < MAC80211_LINKED) &&
+ (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
+ ("Not connected to any\n"));
+
+ rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
+
+ rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
+ return;
+ }
+
+ if (mac->link_state >= MAC80211_LINKED) {
+ if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+ undecorated_smoothed_pwdb =
+ rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("AP Client PWDB = 0x%lx\n",
+ undecorated_smoothed_pwdb));
+ } else {
+ undecorated_smoothed_pwdb =
+ rtlpriv->dm.undecorated_smoothed_pwdb;
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("STA Default Port PWDB = 0x%lx\n",
+ undecorated_smoothed_pwdb));
+ }
+ } else {
+ undecorated_smoothed_pwdb =
+ rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("AP Ext Port PWDB = 0x%lx\n",
+ undecorated_smoothed_pwdb));
+ }
+
+ if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
+ rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"));
+ } else if ((undecorated_smoothed_pwdb <
+ (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
+ (undecorated_smoothed_pwdb >=
+ TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
+
+ rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"));
+ } else if (undecorated_smoothed_pwdb <
+ (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
+ rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("TXHIGHPWRLEVEL_NORMAL\n"));
+ }
+
+ if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("PHY_SetTxPowerLevel8192S() Channel = %d\n",
+ rtlphy->current_channel));
+ rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
+ }
+
+ rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
+}
+
void rtl92c_dm_watchdog(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1388,11 +1459,321 @@ void rtl92c_dm_watchdog(struct ieee80211_hw *hw)
rtl92c_dm_dig(hw);
rtl92c_dm_false_alarm_counter_statistics(hw);
rtl92c_dm_dynamic_bb_powersaving(hw);
- rtlpriv->cfg->ops->dm_dynamic_txpower(hw);
+ rtl92c_dm_dynamic_txpower(hw);
rtl92c_dm_check_txpower_tracking(hw);
rtl92c_dm_refresh_rate_adaptive_mask(hw);
+ rtl92c_dm_bt_coexist(hw);
rtl92c_dm_check_edca_turbo(hw);
-
}
}
EXPORT_SYMBOL(rtl92c_dm_watchdog);
+
+u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+ long undecorated_smoothed_pwdb;
+ u8 curr_bt_rssi_state = 0x00;
+
+ if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
+ undecorated_smoothed_pwdb =
+ GET_UNDECORATED_AVERAGE_RSSI(rtlpriv);
+ } else {
+ if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)
+ undecorated_smoothed_pwdb = 100;
+ else
+ undecorated_smoothed_pwdb =
+ rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+ }
+
+ /* Check RSSI to determine HighPower/NormalPower state for
+ * BT coexistence. */
+ if (undecorated_smoothed_pwdb >= 67)
+ curr_bt_rssi_state &= (~BT_RSSI_STATE_NORMAL_POWER);
+ else if (undecorated_smoothed_pwdb < 62)
+ curr_bt_rssi_state |= BT_RSSI_STATE_NORMAL_POWER;
+
+ /* Check RSSI to determine AMPDU setting for BT coexistence. */
+ if (undecorated_smoothed_pwdb >= 40)
+ curr_bt_rssi_state &= (~BT_RSSI_STATE_AMDPU_OFF);
+ else if (undecorated_smoothed_pwdb <= 32)
+ curr_bt_rssi_state |= BT_RSSI_STATE_AMDPU_OFF;
+
+ /* Marked RSSI state. It will be used to determine BT coexistence
+ * setting later. */
+ if (undecorated_smoothed_pwdb < 35)
+ curr_bt_rssi_state |= BT_RSSI_STATE_SPECIAL_LOW;
+ else
+ curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW);
+
+ /* Set Tx Power according to BT status. */
+ if (undecorated_smoothed_pwdb >= 30)
+ curr_bt_rssi_state |= BT_RSSI_STATE_TXPOWER_LOW;
+ else if (undecorated_smoothed_pwdb < 25)
+ curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW);
+
+ /* Check BT state related to BT_Idle in B/G mode. */
+ if (undecorated_smoothed_pwdb < 15)
+ curr_bt_rssi_state |= BT_RSSI_STATE_BG_EDCA_LOW;
+ else
+ curr_bt_rssi_state &= (~BT_RSSI_STATE_BG_EDCA_LOW);
+
+ if (curr_bt_rssi_state != rtlpcipriv->bt_coexist.bt_rssi_state) {
+ rtlpcipriv->bt_coexist.bt_rssi_state = curr_bt_rssi_state;
+ return true;
+ } else {
+ return false;
+ }
+}
+EXPORT_SYMBOL(rtl92c_bt_rssi_state_change);
+
+static bool rtl92c_bt_state_change(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+ u32 polling, ratio_tx, ratio_pri;
+ u32 bt_tx, bt_pri;
+ u8 bt_state;
+ u8 cur_service_type;
+
+ if (rtlpriv->mac80211.link_state < MAC80211_LINKED)
+ return false;
+
+ bt_state = rtl_read_byte(rtlpriv, 0x4fd);
+ bt_tx = rtl_read_dword(rtlpriv, 0x488);
+ bt_tx = bt_tx & 0x00ffffff;
+ bt_pri = rtl_read_dword(rtlpriv, 0x48c);
+ bt_pri = bt_pri & 0x00ffffff;
+ polling = rtl_read_dword(rtlpriv, 0x490);
+
+ if (bt_tx == 0xffffffff && bt_pri == 0xffffffff &&
+ polling == 0xffffffff && bt_state == 0xff)
+ return false;
+
+ bt_state &= BIT_OFFSET_LEN_MASK_32(0, 1);
+ if (bt_state != rtlpcipriv->bt_coexist.bt_cur_state) {
+ rtlpcipriv->bt_coexist.bt_cur_state = bt_state;
+
+ if (rtlpcipriv->bt_coexist.reg_bt_sco == 3) {
+ rtlpcipriv->bt_coexist.bt_service = BT_IDLE;
+
+ bt_state = bt_state |
+ ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ?
+ 0 : BIT_OFFSET_LEN_MASK_32(1, 1)) |
+ BIT_OFFSET_LEN_MASK_32(2, 1);
+ rtl_write_byte(rtlpriv, 0x4fd, bt_state);
+ }
+ return true;
+ }
+
+ ratio_tx = bt_tx * 1000 / polling;
+ ratio_pri = bt_pri * 1000 / polling;
+ rtlpcipriv->bt_coexist.ratio_tx = ratio_tx;
+ rtlpcipriv->bt_coexist.ratio_pri = ratio_pri;
+
+ if (bt_state && rtlpcipriv->bt_coexist.reg_bt_sco == 3) {
+
+ if ((ratio_tx < 30) && (ratio_pri < 30))
+ cur_service_type = BT_IDLE;
+ else if ((ratio_pri > 110) && (ratio_pri < 250))
+ cur_service_type = BT_SCO;
+ else if ((ratio_tx >= 200) && (ratio_pri >= 200))
+ cur_service_type = BT_BUSY;
+ else if ((ratio_tx >= 350) && (ratio_tx < 500))
+ cur_service_type = BT_OTHERBUSY;
+ else if (ratio_tx >= 500)
+ cur_service_type = BT_PAN;
+ else
+ cur_service_type = BT_OTHER_ACTION;
+
+ if (cur_service_type != rtlpcipriv->bt_coexist.bt_service) {
+ rtlpcipriv->bt_coexist.bt_service = cur_service_type;
+ bt_state = bt_state |
+ ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ?
+ 0 : BIT_OFFSET_LEN_MASK_32(1, 1)) |
+ ((rtlpcipriv->bt_coexist.bt_service != BT_IDLE) ?
+ 0 : BIT_OFFSET_LEN_MASK_32(2, 1));
+
+ /* Add interrupt migration when bt is not ini
+ * idle state (no traffic). */
+ if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) {
+ rtl_write_word(rtlpriv, 0x504, 0x0ccc);
+ rtl_write_byte(rtlpriv, 0x506, 0x54);
+ rtl_write_byte(rtlpriv, 0x507, 0x54);
+ } else {
+ rtl_write_byte(rtlpriv, 0x506, 0x00);
+ rtl_write_byte(rtlpriv, 0x507, 0x00);
+ }
+
+ rtl_write_byte(rtlpriv, 0x4fd, bt_state);
+ return true;
+ }
+ }
+
+ return false;
+
+}
+
+static bool rtl92c_bt_wifi_connect_change(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ static bool media_connect;
+
+ if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
+ media_connect = false;
+ } else {
+ if (!media_connect) {
+ media_connect = true;
+ return true;
+ }
+ media_connect = true;
+ }
+
+ return false;
+}
+
+static void rtl92c_bt_set_normal(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+
+ if (rtlpcipriv->bt_coexist.bt_service == BT_OTHERBUSY) {
+ rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea72b;
+ rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea72b;
+ } else if (rtlpcipriv->bt_coexist.bt_service == BT_BUSY) {
+ rtlpcipriv->bt_coexist.bt_edca_ul = 0x5eb82f;
+ rtlpcipriv->bt_coexist.bt_edca_dl = 0x5eb82f;
+ } else if (rtlpcipriv->bt_coexist.bt_service == BT_SCO) {
+ if (rtlpcipriv->bt_coexist.ratio_tx > 160) {
+ rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea72f;
+ rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea72f;
+ } else {
+ rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea32b;
+ rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea42b;
+ }
+ } else {
+ rtlpcipriv->bt_coexist.bt_edca_ul = 0;
+ rtlpcipriv->bt_coexist.bt_edca_dl = 0;
+ }
+
+ if ((rtlpcipriv->bt_coexist.bt_service != BT_IDLE) &&
+ (rtlpriv->mac80211.mode == WIRELESS_MODE_G ||
+ (rtlpriv->mac80211.mode == (WIRELESS_MODE_G | WIRELESS_MODE_B))) &&
+ (rtlpcipriv->bt_coexist.bt_rssi_state &
+ BT_RSSI_STATE_BG_EDCA_LOW)) {
+ rtlpcipriv->bt_coexist.bt_edca_ul = 0x5eb82b;
+ rtlpcipriv->bt_coexist.bt_edca_dl = 0x5eb82b;
+ }
+}
+
+static void rtl92c_bt_ant_isolation(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+
+ /* Only enable HW BT coexist when BT in "Busy" state. */
+ if (rtlpriv->mac80211.vendor == PEER_CISCO &&
+ rtlpcipriv->bt_coexist.bt_service == BT_OTHER_ACTION) {
+ rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
+ } else {
+ if ((rtlpcipriv->bt_coexist.bt_service == BT_BUSY) &&
+ (rtlpcipriv->bt_coexist.bt_rssi_state &
+ BT_RSSI_STATE_NORMAL_POWER)) {
+ rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
+ } else if ((rtlpcipriv->bt_coexist.bt_service ==
+ BT_OTHER_ACTION) && (rtlpriv->mac80211.mode <
+ WIRELESS_MODE_N_24G) &&
+ (rtlpcipriv->bt_coexist.bt_rssi_state &
+ BT_RSSI_STATE_SPECIAL_LOW)) {
+ rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
+ } else if (rtlpcipriv->bt_coexist.bt_service == BT_PAN) {
+ rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00);
+ } else {
+ rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00);
+ }
+ }
+
+ if (rtlpcipriv->bt_coexist.bt_service == BT_PAN)
+ rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x10100);
+ else
+ rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x0);
+
+ if (rtlpcipriv->bt_coexist.bt_rssi_state &
+ BT_RSSI_STATE_NORMAL_POWER) {
+ rtl92c_bt_set_normal(hw);
+ } else {
+ rtlpcipriv->bt_coexist.bt_edca_ul = 0;
+ rtlpcipriv->bt_coexist.bt_edca_dl = 0;
+ }
+
+ if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) {
+ rtlpriv->cfg->ops->set_rfreg(hw,
+ RF90_PATH_A,
+ 0x1e,
+ 0xf0, 0xf);
+ } else {
+ rtlpriv->cfg->ops->set_rfreg(hw,
+ RF90_PATH_A, 0x1e, 0xf0,
+ rtlpcipriv->bt_coexist.bt_rfreg_origin_1e);
+ }
+
+ if (!rtlpriv->dm.dynamic_txpower_enable) {
+ if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) {
+ if (rtlpcipriv->bt_coexist.bt_rssi_state &
+ BT_RSSI_STATE_TXPOWER_LOW) {
+ rtlpriv->dm.dynamic_txhighpower_lvl =
+ TXHIGHPWRLEVEL_BT2;
+ } else {
+ rtlpriv->dm.dynamic_txhighpower_lvl =
+ TXHIGHPWRLEVEL_BT1;
+ }
+ } else {
+ rtlpriv->dm.dynamic_txhighpower_lvl =
+ TXHIGHPWRLEVEL_NORMAL;
+ }
+ rtl92c_phy_set_txpower_level(hw,
+ rtlpriv->phy.current_channel);
+ }
+}
+
+static void rtl92c_check_bt_change(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+ if (rtlpcipriv->bt_coexist.bt_cur_state) {
+ if (rtlpcipriv->bt_coexist.bt_ant_isolation)
+ rtl92c_bt_ant_isolation(hw);
+ } else {
+ rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00);
+ rtlpriv->cfg->ops->set_rfreg(hw, RF90_PATH_A, 0x1e, 0xf0,
+ rtlpcipriv->bt_coexist.bt_rfreg_origin_1e);
+
+ rtlpcipriv->bt_coexist.bt_edca_ul = 0;
+ rtlpcipriv->bt_coexist.bt_edca_dl = 0;
+ }
+}
+
+void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw)
+{
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+ bool wifi_connect_change;
+ bool bt_state_change;
+ bool rssi_state_change;
+
+ if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
+ (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) {
+
+ wifi_connect_change = rtl92c_bt_wifi_connect_change(hw);
+ bt_state_change = rtl92c_bt_state_change(hw);
+ rssi_state_change = rtl92c_bt_rssi_state_change(hw);
+
+ if (wifi_connect_change || bt_state_change || rssi_state_change)
+ rtl92c_check_bt_change(hw);
+ }
+}
+EXPORT_SYMBOL(rtl92c_dm_bt_coexist);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
index b9cbb0a3c03..b9736d3e9a3 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
@@ -200,5 +200,7 @@ void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal);
void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery);
+void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw);
+void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw);
#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
index 28a6ce3bc23..50303e1adff 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
@@ -171,7 +171,6 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw,
static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
- int err = -EIO;
u32 counter = 0;
u32 value32;
@@ -184,7 +183,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
value32));
- goto exit;
+ return -EIO;
}
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
@@ -204,8 +203,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
("Polling FW ready success!!"
" REG_MCUFWDL:0x%08x .\n",
value32));
- err = 0;
- goto exit;
+ return 0;
}
mdelay(FW_8192C_POLLING_DELAY);
@@ -214,9 +212,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32));
-
-exit:
- return err;
+ return -EIO;
}
int rtl92c_download_fw(struct ieee80211_hw *hw)
@@ -226,32 +222,16 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
struct rtl92c_firmware_header *pfwheader;
u8 *pfwdata;
u32 fwsize;
- int err;
enum version_8192c version = rtlhal->version;
- const struct firmware *firmware;
- printk(KERN_INFO "rtl8192cu: Loading firmware file %s\n",
+ printk(KERN_INFO "rtl8192c: Loading firmware file %s\n",
rtlpriv->cfg->fw_name);
- err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
- rtlpriv->io.dev);
- if (err) {
- printk(KERN_ERR "rtl8192cu: Firmware loading failed\n");
- return 1;
- }
-
- if (firmware->size > 0x4000) {
- RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
- ("Firmware is too big!\n"));
- release_firmware(firmware);
+ if (!rtlhal->pfirmware)
return 1;
- }
-
- memcpy(rtlhal->pfirmware, firmware->data, firmware->size);
- fwsize = firmware->size;
- release_firmware(firmware);
pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
pfwdata = (u8 *) rtlhal->pfirmware;
+ fwsize = rtlhal->fwsize;
if (IS_FW_HEADER_EXIST(pfwheader)) {
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
@@ -267,8 +247,7 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
_rtl92c_write_fw(hw, version, pfwdata, fwsize);
_rtl92c_enable_fw_download(hw, false);
- err = _rtl92c_fw_free_to_go(hw);
- if (err) {
+ if (_rtl92c_fw_free_to_go(hw)) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("Firmware is not ready to run!\n"));
} else {
@@ -300,10 +279,9 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u8 boxnum;
- u16 box_reg, box_extreg;
+ u16 box_reg = 0, box_extreg = 0;
u8 u1b_tmp;
bool isfw_read = false;
- u8 buf_index = 0;
bool bwrite_sucess = false;
u8 wait_h2c_limmit = 100;
u8 wait_writeh2c_limmit = 100;
@@ -414,7 +392,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
case 1:
boxcontent[0] &= ~(BIT(7));
memcpy((u8 *) (boxcontent) + 1,
- p_cmdbuffer + buf_index, 1);
+ p_cmdbuffer, 1);
for (idx = 0; idx < 4; idx++) {
rtl_write_byte(rtlpriv, box_reg + idx,
@@ -424,7 +402,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
case 2:
boxcontent[0] &= ~(BIT(7));
memcpy((u8 *) (boxcontent) + 1,
- p_cmdbuffer + buf_index, 2);
+ p_cmdbuffer, 2);
for (idx = 0; idx < 4; idx++) {
rtl_write_byte(rtlpriv, box_reg + idx,
@@ -434,7 +412,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
case 3:
boxcontent[0] &= ~(BIT(7));
memcpy((u8 *) (boxcontent) + 1,
- p_cmdbuffer + buf_index, 3);
+ p_cmdbuffer, 3);
for (idx = 0; idx < 4; idx++) {
rtl_write_byte(rtlpriv, box_reg + idx,
@@ -444,9 +422,9 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
case 4:
boxcontent[0] |= (BIT(7));
memcpy((u8 *) (boxextcontent),
- p_cmdbuffer + buf_index, 2);
+ p_cmdbuffer, 2);
memcpy((u8 *) (boxcontent) + 1,
- p_cmdbuffer + buf_index + 2, 2);
+ p_cmdbuffer + 2, 2);
for (idx = 0; idx < 2; idx++) {
rtl_write_byte(rtlpriv, box_extreg + idx,
@@ -461,9 +439,9 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
case 5:
boxcontent[0] |= (BIT(7));
memcpy((u8 *) (boxextcontent),
- p_cmdbuffer + buf_index, 2);
+ p_cmdbuffer, 2);
memcpy((u8 *) (boxcontent) + 1,
- p_cmdbuffer + buf_index + 2, 3);
+ p_cmdbuffer + 2, 3);
for (idx = 0; idx < 2; idx++) {
rtl_write_byte(rtlpriv, box_extreg + idx,
@@ -561,6 +539,39 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
}
EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd);
+static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
+ struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl8192_tx_ring *ring;
+ struct rtl_tx_desc *pdesc;
+ u8 own;
+ unsigned long flags;
+ struct sk_buff *pskb = NULL;
+
+ ring = &rtlpci->tx_ring[BEACON_QUEUE];
+
+ pskb = __skb_dequeue(&ring->queue);
+ if (pskb)
+ kfree_skb(pskb);
+
+ spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+
+ pdesc = &ring->desc[0];
+ own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
+
+ rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
+
+ __skb_queue_tail(&ring->queue, skb);
+
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+ rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
+
+ return true;
+}
+
#define BEACON_PG 0 /*->1*/
#define PSPOLL_PG 2
#define NULL_PG 3
@@ -678,7 +689,7 @@ static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
-void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
+void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
@@ -687,12 +698,12 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
u32 totalpacketlen;
bool rtstatus;
u8 u1RsvdPageLoc[3] = {0};
- bool b_dlok = false;
+ bool dlok = false;
u8 *beacon;
- u8 *p_pspoll;
+ u8 *pspoll;
u8 *nullfunc;
- u8 *p_probersp;
+ u8 *probersp;
/*---------------------------------------------------------
(1) beacon
---------------------------------------------------------*/
@@ -703,10 +714,10 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
/*-------------------------------------------------------
(2) ps-poll
--------------------------------------------------------*/
- p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
- SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
- SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
- SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
+ pspoll = &reserved_page_packet[PSPOLL_PG * 128];
+ SET_80211_PS_POLL_AID(pspoll, (mac->assoc_id | 0xc000));
+ SET_80211_PS_POLL_BSSID(pspoll, mac->bssid);
+ SET_80211_PS_POLL_TA(pspoll, mac->mac_addr);
SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
@@ -723,10 +734,10 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
/*---------------------------------------------------------
(4) probe response
----------------------------------------------------------*/
- p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
- SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
- SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
- SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
+ probersp = &reserved_page_packet[PROBERSP_PG * 128];
+ SET_80211_HDR_ADDRESS1(probersp, mac->bssid);
+ SET_80211_HDR_ADDRESS2(probersp, mac->mac_addr);
+ SET_80211_HDR_ADDRESS3(probersp, mac->bssid);
SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
@@ -744,12 +755,12 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
memcpy((u8 *) skb_put(skb, totalpacketlen),
&reserved_page_packet, totalpacketlen);
- rtstatus = rtlpriv->cfg->ops->cmd_send_packet(hw, skb);
+ rtstatus = _rtl92c_cmd_send_packet(hw, skb);
if (rtstatus)
- b_dlok = true;
+ dlok = true;
- if (b_dlok) {
+ if (dlok) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
("Set RSVD page location to Fw.\n"));
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
index 3db33bd1466..3d5823c1262 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
@@ -27,8 +27,8 @@
*
*****************************************************************************/
-#ifndef __RTL92C__FW__H__
-#define __RTL92C__FW__H__
+#ifndef __RTL92C__FW__COMMON__H__
+#define __RTL92C__FW__COMMON__H__
#define FW_8192C_SIZE 0x3000
#define FW_8192C_START_ADDRESS 0x1000
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
index a7022827839..c5424cad43c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
@@ -78,27 +78,29 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
" data(%#x)\n", regaddr, bitmask,
data));
+
}
EXPORT_SYMBOL(rtl92c_phy_set_bb_reg);
u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
- enum radio_path rfpath, u32 offset)
+ enum radio_path rfpath, u32 offset)
{
RT_ASSERT(false, ("deprecated!\n"));
return 0;
+
}
EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_read);
void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
- enum radio_path rfpath, u32 offset,
- u32 data)
+ enum radio_path rfpath, u32 offset,
+ u32 data)
{
RT_ASSERT(false, ("deprecated!\n"));
}
EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write);
u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
- enum radio_path rfpath, u32 offset)
+ enum radio_path rfpath, u32 offset)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -149,8 +151,8 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read);
void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
- enum radio_path rfpath, u32 offset,
- u32 data)
+ enum radio_path rfpath, u32 offset,
+ u32 data)
{
u32 data_and_addr;
u32 newoffset;
@@ -197,6 +199,7 @@ static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw)
rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
}
+
bool rtl92c_phy_rf_config(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -241,13 +244,14 @@ bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
RFPGA0_XA_HSSIPARAMETER2,
0x200));
+
return true;
}
EXPORT_SYMBOL(_rtl92c_phy_bb8192c_config_parafile);
void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
- u32 regaddr, u32 bitmask,
- u32 data)
+ u32 regaddr, u32 bitmask,
+ u32 data)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -317,61 +321,48 @@ void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
}
if (regaddr == RTXAGC_B_RATE54_24) {
rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data;
-
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
rtlphy->pwrgroup_cnt,
rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9]));
}
-
if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data;
-
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
rtlphy->pwrgroup_cnt,
rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14]));
}
-
if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data;
-
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
rtlphy->pwrgroup_cnt,
rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15]));
}
-
if (regaddr == RTXAGC_B_MCS03_MCS00) {
rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data;
-
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
rtlphy->pwrgroup_cnt,
rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10]));
}
-
if (regaddr == RTXAGC_B_MCS07_MCS04) {
rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data;
-
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
rtlphy->pwrgroup_cnt,
rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11]));
}
-
if (regaddr == RTXAGC_B_MCS11_MCS08) {
rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data;
-
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
rtlphy->pwrgroup_cnt,
rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12]));
}
-
if (regaddr == RTXAGC_B_MCS15_MCS12) {
rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data;
-
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
rtlphy->pwrgroup_cnt,
@@ -583,6 +574,7 @@ static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw,
rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
+
}
void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
@@ -611,7 +603,6 @@ bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u8 idx;
u8 rf_path;
-
u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw,
WIRELESS_MODE_B,
power_indbm);
@@ -639,11 +630,6 @@ bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
}
EXPORT_SYMBOL(rtl92c_phy_update_txpower_dbm);
-void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval)
-{
-}
-EXPORT_SYMBOL(rtl92c_phy_set_beacon_hw_reg);
-
u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
enum wireless_mode wirelessmode,
long power_indbm)
@@ -741,9 +727,9 @@ void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
if (rtlphy->set_bwmode_inprogress)
return;
rtlphy->set_bwmode_inprogress = true;
- if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
- rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw);
- else {
+ if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
+ rtlphy->set_bwmode_inprogress = false;
+ } else {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
("FALSE driver sleep or unload\n"));
rtlphy->set_bwmode_inprogress = false;
@@ -773,8 +759,9 @@ void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw)
mdelay(delay);
else
continue;
- } else
+ } else {
rtlphy->sw_chnl_inprogress = false;
+ }
break;
} while (true);
RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
@@ -811,9 +798,32 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw)
}
EXPORT_SYMBOL(rtl92c_phy_sw_chnl);
-static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
- u8 channel, u8 *stage, u8 *step,
- u32 *delay)
+static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
+ u32 cmdtableidx, u32 cmdtablesz,
+ enum swchnlcmd_id cmdid,
+ u32 para1, u32 para2, u32 msdelay)
+{
+ struct swchnlcmd *pcmd;
+
+ if (cmdtable == NULL) {
+ RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
+ return false;
+ }
+
+ if (cmdtableidx >= cmdtablesz)
+ return false;
+
+ pcmd = cmdtable + cmdtableidx;
+ pcmd->cmdid = cmdid;
+ pcmd->para1 = para1;
+ pcmd->para2 = para2;
+ pcmd->msdelay = msdelay;
+ return true;
+}
+
+bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
+ u8 channel, u8 *stage, u8 *step,
+ u32 *delay)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -917,29 +927,6 @@ static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
return false;
}
-static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
- u32 cmdtableidx, u32 cmdtablesz,
- enum swchnlcmd_id cmdid,
- u32 para1, u32 para2, u32 msdelay)
-{
- struct swchnlcmd *pcmd;
-
- if (cmdtable == NULL) {
- RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
- return false;
- }
-
- if (cmdtableidx >= cmdtablesz)
- return false;
-
- pcmd = cmdtable + cmdtableidx;
- pcmd->cmdid = cmdid;
- pcmd->para1 = para1;
- pcmd->para2 = para2;
- pcmd->msdelay = msdelay;
- return true;
-}
-
bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath)
{
return true;
@@ -1002,13 +989,13 @@ static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw)
reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
+
if (!(reg_eac & BIT(31)) &&
(((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
(((reg_ebc & 0x03FF0000) >> 16) != 0x42))
result |= 0x01;
else
return result;
-
if (!(reg_eac & BIT(30)) &&
(((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
(((reg_ecc & 0x03FF0000) >> 16) != 0x36))
@@ -1023,9 +1010,9 @@ static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
u32 oldval_0, x, tx0_a, reg;
long y, tx0_c;
- if (final_candidate == 0xFF)
+ if (final_candidate == 0xFF) {
return;
- else if (iqk_ok) {
+ } else if (iqk_ok) {
oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
MASKDWORD) >> 22) & 0x3FF;
x = result[final_candidate][0];
@@ -1063,9 +1050,9 @@ static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
u32 oldval_1, x, tx1_a, reg;
long y, tx1_c;
- if (final_candidate == 0xFF)
+ if (final_candidate == 0xFF) {
return;
- else if (iqk_ok) {
+ } else if (iqk_ok) {
oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
MASKDWORD) >> 22) & 0x3FF;
x = result[final_candidate][4];
@@ -1282,6 +1269,7 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
RFPGA0_XA_HSSIPARAMETER1,
BIT(8));
}
+
if (!rtlphy->rfpi_enable)
_rtl92c_phy_pi_mode_switch(hw, true);
if (t == 0) {
@@ -1317,9 +1305,10 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
0x3FF0000) >> 16;
break;
} else if (i == (retrycount - 1) && patha_ok == 0x01)
+
result[t][0] = (rtl_get_bbreg(hw, 0xe94,
MASKDWORD) & 0x3FF0000) >>
- 16;
+ 16;
result[t][1] =
(rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
@@ -1375,8 +1364,7 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,
char delta, bool is2t)
{
- /* This routine is deliberately dummied out for later fixes */
-#if 0
+#if 0 /* This routine is deliberately dummied out for later fixes */
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
@@ -1434,7 +1422,7 @@ static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,
0x04db25a4, 0x0b1b25a4
};
- u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c };
+ const u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c };
u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 };
@@ -1463,13 +1451,15 @@ static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,
0x00050006
};
- const u32 apk_result[PATH_NUM][APK_BB_REG_NUM];
+ u32 apk_result[PATH_NUM][APK_BB_REG_NUM];
long bb_offset, delta_v, delta_offset;
if (!is2t)
pathbound = 1;
+ return;
+
for (index = 0; index < PATH_NUM; index++) {
apk_offset[index] = apk_normal_offset[index];
apk_value[index] = apk_normal_value[index];
@@ -1730,8 +1720,7 @@ static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,
0x08));
}
-
- rtlphy->apk_done = true;
+ rtlphy->b_apk_done = true;
#endif
}
@@ -1758,6 +1747,7 @@ static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw,
rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
}
+
}
#undef IQK_ADDA_REG_NUM
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
index 53ffb098158..9a264c0d612 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
@@ -27,8 +27,8 @@
*
*****************************************************************************/
-#ifndef __RTL92C_PHY_H__
-#define __RTL92C_PHY_H__
+#ifndef __RTL92C_PHY_COMMON_H__
+#define __RTL92C_PHY_COMMON_H__
#define MAX_PRECMD_CNT 16
#define MAX_RFDEPENDCMD_CNT 16
@@ -39,6 +39,7 @@
#define RT_CANNOT_IO(hw) false
#define HIGHPOWER_RADIOA_ARRAYLEN 22
+#define IQK_ADDA_REG_NUM 16
#define MAX_TOLERANCE 5
#define IQK_DELAY_TIME 1
@@ -56,6 +57,7 @@
#define IQK_ADDA_REG_NUM 16
#define IQK_MAC_REG_NUM 4
+#define IQK_DELAY_TIME 1
#define RF90_PATH_MAX 2
#define CT_OFFSET_MAC_ADDR 0X16
@@ -77,6 +79,7 @@
#define RTL92C_MAX_PATH_NUM 2
#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255
+
enum swchnlcmd_id {
CMDID_END,
CMDID_SET_TXPOWEROWER_LEVEL,
@@ -184,45 +187,41 @@ struct tx_power_struct {
u32 mcs_original_offset[4][16];
};
-extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw,
+u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw,
u32 regaddr, u32 bitmask);
-extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
+void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
u32 regaddr, u32 bitmask, u32 data);
-extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
+u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr,
u32 bitmask);
-extern void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw,
- enum radio_path rfpath, u32 regaddr,
- u32 bitmask, u32 data);
-extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw);
-extern bool rtl92c_phy_bb_config(struct ieee80211_hw *hw);
-extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw);
-extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
+bool rtl92c_phy_mac_config(struct ieee80211_hw *hw);
+bool rtl92c_phy_bb_config(struct ieee80211_hw *hw);
+bool rtl92c_phy_rf_config(struct ieee80211_hw *hw);
+bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
-extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
-extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,
+void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
+void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,
long *powerlevel);
-extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
-extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,
+void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
+bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,
long power_indbm);
-extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw,
+void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw,
u8 operation);
-extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
-extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
+void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
enum nl80211_channel_type ch_type);
-extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
-extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw);
-extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
-extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw,
+void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
+u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw);
+void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
+void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw,
u16 beaconinterval);
void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
-extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,
+bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,
u32 rfpath);
-extern bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
+bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state);
void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw);
void rtl92c_phy_set_io(struct ieee80211_hw *hw);
@@ -235,12 +234,25 @@ u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
enum wireless_mode wirelessmode,
long power_indbm);
void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
-static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
- u32 cmdtableidx, u32 cmdtablesz,
- enum swchnlcmd_id cmdid, u32 para1,
- u32 para2, u32 msdelay);
-static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
- u8 channel, u8 *stage, u8 *step,
- u32 *delay);
+void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw);
+bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
+ u8 channel, u8 *stage, u8 *step,
+ u32 *delay);
+u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw);
+u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 offset);
+void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 offset,
+ u32 data);
+u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 offset);
+void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 offset,
+ u32 data);
+bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
+void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
+ u32 regaddr, u32 bitmask,
+ u32 data);
+bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
index 2f577c8828f..35ff7df41a1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
@@ -121,19 +121,6 @@
#define CHIP_92C 0x01
#define CHIP_88C 0x00
-/* Add vendor information into chip version definition.
- * Add UMC B-Cut and RTL8723 chip info definition.
- *
- * BIT 7 Reserved
- * BIT 6 UMC BCut
- * BIT 5 Manufacturer(TSMC/UMC)
- * BIT 4 TEST/NORMAL
- * BIT 3 8723 Version
- * BIT 2 8723?
- * BIT 1 1T2R?
- * BIT 0 88C/92C
-*/
-
enum version_8192c {
VERSION_A_CHIP_92C = 0x01,
VERSION_A_CHIP_88C = 0x00,
@@ -280,20 +267,6 @@ struct h2c_cmd_8192c {
u8 *p_cmdbuffer;
};
-static inline u8 _rtl92c_get_chnl_group(u8 chnl)
-{
- u8 group = 0;
-
- if (chnl < 3)
- group = 0;
- else if (chnl < 9)
- group = 1;
- else
- group = 2;
-
- return group;
-}
-
/* NOTE: reference to rtl8192c_rates struct */
static inline int _rtl92c_rate_mapping(struct ieee80211_hw *hw, bool isHT,
u8 desc_rate, bool first_ampdu)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
index 7d76504df4d..2df33e53e15 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
@@ -29,10 +29,12 @@
#include "../wifi.h"
#include "../base.h"
+#include "../pci.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "dm.h"
+#include "../rtl8192c/fw_common.h"
void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw)
{
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
index 36302ebae4a..07dd9552e82 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
@@ -192,6 +192,7 @@ void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw);
void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw);
void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal);
+void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw);
void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw);
#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
index 05477f465a7..4a56138eb33 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -30,12 +30,14 @@
#include "../wifi.h"
#include "../efuse.h"
#include "../base.h"
+#include "../regd.h"
#include "../cam.h"
#include "../ps.h"
#include "../pci.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
+#include "../rtl8192c/fw_common.h"
#include "dm.h"
#include "led.h"
#include "hw.h"
@@ -137,15 +139,6 @@ void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
break;
}
- case HW_VAR_MGT_FILTER:
- *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP0);
- break;
- case HW_VAR_CTRL_FILTER:
- *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP1);
- break;
- case HW_VAR_DATA_FILTER:
- *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2);
- break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("switch case not process\n"));
@@ -156,6 +149,7 @@ void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
@@ -178,7 +172,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
rate_cfg |= 0x01;
rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff);
rtl_write_byte(rtlpriv, REG_RRSR + 1,
- (rate_cfg >> 8)&0xff);
+ (rate_cfg >> 8) & 0xff);
while (rate_cfg > 0x1) {
rate_cfg = (rate_cfg >> 1);
rate_index++;
@@ -276,13 +270,19 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
break;
}
case HW_VAR_AMPDU_FACTOR:{
- u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 };
+ u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9};
+ u8 regtoset_bt[4] = {0x31, 0x74, 0x42, 0x97};
u8 factor_toset;
u8 *p_regtoset = NULL;
u8 index = 0;
- p_regtoset = regtoset_normal;
+ if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
+ (rtlpcipriv->bt_coexist.bt_coexist_type ==
+ BT_CSR_BC4))
+ p_regtoset = regtoset_bt;
+ else
+ p_regtoset = regtoset_normal;
factor_toset = *((u8 *) val);
if (factor_toset <= 3) {
@@ -317,45 +317,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
}
case HW_VAR_AC_PARAM:{
u8 e_aci = *((u8 *) val);
- u32 u4b_ac_param;
- u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min);
- u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max);
- u16 tx_op = le16_to_cpu(mac->ac[e_aci].tx_op);
-
- u4b_ac_param = (u32) mac->ac[e_aci].aifs;
- u4b_ac_param |= ((u32)cw_min
- & 0xF) << AC_PARAM_ECW_MIN_OFFSET;
- u4b_ac_param |= ((u32)cw_max &
- 0xF) << AC_PARAM_ECW_MAX_OFFSET;
- u4b_ac_param |= (u32)tx_op << AC_PARAM_TXOP_OFFSET;
-
- RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
- ("queue:%x, ac_param:%x\n", e_aci,
- u4b_ac_param));
-
- switch (e_aci) {
- case AC1_BK:
- rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM,
- u4b_ac_param);
- break;
- case AC0_BE:
- rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM,
- u4b_ac_param);
- break;
- case AC2_VI:
- rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM,
- u4b_ac_param);
- break;
- case AC3_VO:
- rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM,
- u4b_ac_param);
- break;
- default:
- RT_ASSERT(false,
- ("SetHwReg8185(): invalid aci: %d !\n",
- e_aci));
- break;
- }
+ rtl92c_dm_init_edca_turbo(hw);
if (rtlpci->acm_method != eAcmWay2_SW)
rtlpriv->cfg->ops->set_hw_reg(hw,
@@ -526,9 +488,6 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
case HW_VAR_CORRECT_TSF:{
u8 btype_ibss = ((u8 *) (val))[0];
- /*btype_ibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ?
- 1 : 0;*/
-
if (btype_ibss == true)
_rtl92ce_stop_tx_beacon(hw);
@@ -537,7 +496,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
rtl_write_dword(rtlpriv, REG_TSFTR,
(u32) (mac->tsf & 0xffffffff));
rtl_write_dword(rtlpriv, REG_TSFTR + 4,
- (u32) ((mac->tsf >> 32)&0xffffffff));
+ (u32) ((mac->tsf >> 32) & 0xffffffff));
_rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0);
@@ -547,15 +506,6 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
break;
}
- case HW_VAR_MGT_FILTER:
- rtl_write_word(rtlpriv, REG_RXFLTMAP0, *(u16 *) val);
- break;
- case HW_VAR_CTRL_FILTER:
- rtl_write_word(rtlpriv, REG_RXFLTMAP1, *(u16 *) val);
- break;
- case HW_VAR_DATA_FILTER:
- rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *) val);
- break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "
"not process\n"));
@@ -679,12 +629,12 @@ static void _rtl92ce_gen_refresh_led_state(struct ieee80211_hw *hw)
rtl92ce_sw_led_on(hw, pLed0);
else
rtl92ce_sw_led_off(hw, pLed0);
-
}
static bool _rtl92ce_init_mac(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
@@ -693,9 +643,22 @@ static bool _rtl92ce_init_mac(struct ieee80211_hw *hw)
u16 retry;
rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
+ if (rtlpcipriv->bt_coexist.bt_coexistence) {
+ u32 value32;
+ value32 = rtl_read_dword(rtlpriv, REG_APS_FSMCO);
+ value32 |= (SOP_ABG | SOP_AMB | XOP_BTCK);
+ rtl_write_dword(rtlpriv, REG_APS_FSMCO, value32);
+ }
rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0F);
+ if (rtlpcipriv->bt_coexist.bt_coexistence) {
+ u32 u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL);
+
+ u4b_tmp &= (~0x00024800);
+ rtl_write_dword(rtlpriv, REG_AFE_XTAL_CTRL, u4b_tmp);
+ }
+
bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) | BIT(0);
udelay(2);
@@ -726,6 +689,11 @@ static bool _rtl92ce_init_mac(struct ieee80211_hw *hw)
rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x82);
udelay(2);
+ if (rtlpcipriv->bt_coexist.bt_coexistence) {
+ bytetmp = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2) & 0xfd;
+ rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, bytetmp);
+ }
+
rtl_write_word(rtlpriv, REG_CR, 0x2ff);
if (_rtl92ce_llt_table_init(hw) == false)
@@ -793,6 +761,7 @@ static void _rtl92ce_hw_configure(struct ieee80211_hw *hw)
{
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
u8 reg_bw_opmode;
u32 reg_ratr, reg_prsr;
@@ -824,7 +793,11 @@ static void _rtl92ce_hw_configure(struct ieee80211_hw *hw)
rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
- rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841);
+ if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
+ (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4))
+ rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x97427431);
+ else
+ rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841);
rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2);
@@ -840,11 +813,20 @@ static void _rtl92ce_hw_configure(struct ieee80211_hw *hw)
rtl_write_byte(rtlpriv, REG_PIFS, 0x1C);
rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
- rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
-
- rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
+ if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
+ (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) {
+ rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
+ rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0402);
+ } else {
+ rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
+ rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
+ }
- rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666);
+ if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
+ (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4))
+ rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666);
+ else
+ rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666);
rtl_write_byte(rtlpriv, REG_ACKTO, 0x40);
@@ -948,8 +930,8 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
}
rtlhal->last_hmeboxnum = 0;
- rtl92ce_phy_mac_config(hw);
- rtl92ce_phy_bb_config(hw);
+ rtl92c_phy_mac_config(hw);
+ rtl92c_phy_bb_config(hw);
rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
rtl92c_phy_rf_config(hw);
rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
@@ -962,15 +944,20 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
_rtl92ce_hw_configure(hw);
rtl_cam_reset_all_entry(hw);
rtl92ce_enable_hw_security_config(hw);
+
ppsc->rfpwr_state = ERFON;
+
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
_rtl92ce_enable_aspm_back_door(hw);
rtlpriv->intf_ops->enable_aspm(hw);
+
+ rtl8192ce_bt_hw_init(hw);
+
if (ppsc->rfpwr_state == ERFON) {
rtl92c_phy_set_rfpath_switch(hw, 1);
- if (iqk_initialized)
+ if (iqk_initialized) {
rtl92c_phy_iq_calibrate(hw, true);
- else {
+ } else {
rtl92c_phy_iq_calibrate(hw, false);
iqk_initialized = true;
}
@@ -1128,75 +1115,62 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,
return 0;
}
-static void _rtl92ce_set_check_bssid(struct ieee80211_hw *hw,
- enum nl80211_iftype type)
+void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);
- u8 filterout_non_associated_bssid = false;
- switch (type) {
- case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_STATION:
- filterout_non_associated_bssid = true;
- break;
- case NL80211_IFTYPE_UNSPECIFIED:
- case NL80211_IFTYPE_AP:
- default:
- break;
- }
+ if (rtlpriv->psc.rfpwr_state != ERFON)
+ return;
- if (filterout_non_associated_bssid == true) {
+ if (check_bssid == true) {
reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
(u8 *) (&reg_rcr));
_rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4));
- } else if (filterout_non_associated_bssid == false) {
+ } else if (check_bssid == false) {
reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
_rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0);
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_RCR, (u8 *) (&reg_rcr));
}
+
}
int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
if (_rtl92ce_set_media_status(hw, type))
return -EOPNOTSUPP;
- _rtl92ce_set_check_bssid(hw, type);
+
+ if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
+ if (type != NL80211_IFTYPE_AP)
+ rtl92ce_set_check_bssid(hw, true);
+ } else {
+ rtl92ce_set_check_bssid(hw, false);
+ }
+
return 0;
}
+/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */
void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
- u32 u4b_ac_param;
- u16 cw_min = le16_to_cpu(mac->ac[aci].cw_min);
- u16 cw_max = le16_to_cpu(mac->ac[aci].cw_max);
- u16 tx_op = le16_to_cpu(mac->ac[aci].tx_op);
-
rtl92c_dm_init_edca_turbo(hw);
- u4b_ac_param = (u32) mac->ac[aci].aifs;
- u4b_ac_param |= (u32) ((cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET);
- u4b_ac_param |= (u32) ((cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET);
- u4b_ac_param |= (u32) (tx_op << AC_PARAM_TXOP_OFFSET);
- RT_TRACE(rtlpriv, COMP_QOS, DBG_DMESG,
- ("queue:%x, ac_param:%x aifs:%x cwmin:%x cwmax:%x txop:%x\n",
- aci, u4b_ac_param, mac->ac[aci].aifs, cw_min,
- cw_max, tx_op));
switch (aci) {
case AC1_BK:
- rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param);
+ rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
break;
case AC0_BE:
- rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param);
+ /* rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); */
break;
case AC2_VI:
- rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, u4b_ac_param);
+ rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
break;
case AC3_VO:
- rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param);
+ rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
break;
default:
RT_ASSERT(false, ("invalid aci: %d !\n", aci));
@@ -1227,8 +1201,10 @@ void rtl92ce_disable_interrupt(struct ieee80211_hw *hw)
static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u8 u1b_tmp;
+ u32 u4b_tmp;
rtlpriv->intf_ops->enable_aspm(hw);
rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
@@ -1243,13 +1219,27 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)
rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00000000);
u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL);
- rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00FF0000 |
- (u1b_tmp << 8));
+ if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
+ ((rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) ||
+ (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC8))) {
+ rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00F30000 |
+ (u1b_tmp << 8));
+ } else {
+ rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00FF0000 |
+ (u1b_tmp << 8));
+ }
rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790);
rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080);
rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80);
rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23);
- rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e);
+ if (rtlpcipriv->bt_coexist.bt_coexistence) {
+ u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL);
+ u4b_tmp |= 0x03824800;
+ rtl_write_dword(rtlpriv, REG_AFE_XTAL_CTRL, u4b_tmp);
+ } else {
+ rtl_write_dword(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e);
+ }
+
rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10);
}
@@ -1327,6 +1317,7 @@ void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,
RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr));
+
if (add_msr)
rtlpci->irq_mask[0] |= add_msr;
if (rm_msr)
@@ -1582,7 +1573,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
("RTL819X Not boot from eeprom, check it !!"));
}
- RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"),
+ RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
hwinfo, HWSET_MAX_SIZE);
eeprom_id = *((u16 *)&hwinfo[0]);
@@ -1610,6 +1601,10 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
rtlefuse->autoload_failflag,
hwinfo);
+ rtl8192ce_read_bt_coexist_info_from_hwpg(hw,
+ rtlefuse->autoload_failflag,
+ hwinfo);
+
rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
rtlefuse->txpwr_fromeprom = true;
@@ -1618,6 +1613,9 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid));
+ /* set channel paln to world wide 13 */
+ rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
+
if (rtlhal->oem_id == RT_CID_DEFAULT) {
switch (rtlefuse->eeprom_oemid) {
case EEPROM_CID_DEFAULT:
@@ -1701,30 +1699,36 @@ void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw)
} else {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));
}
-
_rtl92ce_hal_customized_behavior(hw);
}
-void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw)
+static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-
- u32 ratr_value = (u32) mac->basic_rates;
- u8 *mcsrate = mac->mcs;
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ u32 ratr_value;
u8 ratr_index = 0;
u8 nmode = mac->ht_enable;
- u8 mimo_ps = 1;
+ u8 mimo_ps = IEEE80211_SMPS_OFF;
u16 shortgi_rate;
u32 tmp_ratr_value;
u8 curtxbw_40mhz = mac->bw_40;
- u8 curshortgi_40mhz = mac->sgi_40;
- u8 curshortgi_20mhz = mac->sgi_20;
+ u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+ 1 : 0;
+ u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+ 1 : 0;
enum wireless_mode wirelessmode = mac->mode;
- ratr_value |= ((*(u16 *) (mcsrate))) << 12;
-
+ if (rtlhal->current_bandtype == BAND_ON_5G)
+ ratr_value = sta->supp_rates[1] << 4;
+ else
+ ratr_value = sta->supp_rates[0];
+ ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+ sta->ht_cap.mcs.rx_mask[0] << 12);
switch (wirelessmode) {
case WIRELESS_MODE_B:
if (ratr_value & 0x0000000c)
@@ -1738,7 +1742,7 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw)
case WIRELESS_MODE_N_24G:
case WIRELESS_MODE_N_5G:
nmode = 1;
- if (mimo_ps == 0) {
+ if (mimo_ps == IEEE80211_SMPS_STATIC) {
ratr_value &= 0x0007F005;
} else {
u32 ratr_mask;
@@ -1761,10 +1765,19 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw)
break;
}
- ratr_value &= 0x0FFFFFFF;
+ if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
+ (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) &&
+ (rtlpcipriv->bt_coexist.bt_cur_state) &&
+ (rtlpcipriv->bt_coexist.bt_ant_isolation) &&
+ ((rtlpcipriv->bt_coexist.bt_service == BT_SCO) ||
+ (rtlpcipriv->bt_coexist.bt_service == BT_BUSY)))
+ ratr_value &= 0x0fffcfc0;
+ else
+ ratr_value &= 0x0FFFFFFF;
- if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || (!curtxbw_40mhz &&
- curshortgi_20mhz))) {
+ if (nmode && ((curtxbw_40mhz &&
+ curshortgi_40mhz) || (!curtxbw_40mhz &&
+ curshortgi_20mhz))) {
ratr_value |= 0x10000000;
tmp_ratr_value = (ratr_value >> 12);
@@ -1784,24 +1797,42 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw)
("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)));
}
-void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
+static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u8 rssi_level)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
- u32 ratr_bitmap = (u32) mac->basic_rates;
- u8 *p_mcsrate = mac->mcs;
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_sta_info *sta_entry = NULL;
+ u32 ratr_bitmap;
u8 ratr_index;
- u8 curtxbw_40mhz = mac->bw_40;
- u8 curshortgi_40mhz = mac->sgi_40;
- u8 curshortgi_20mhz = mac->sgi_20;
- enum wireless_mode wirelessmode = mac->mode;
+ u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+ ? 1 : 0;
+ u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+ 1 : 0;
+ u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+ 1 : 0;
+ enum wireless_mode wirelessmode = 0;
bool shortgi = false;
u8 rate_mask[5];
u8 macid = 0;
- u8 mimops = 1;
-
- ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12);
+ u8 mimo_ps = IEEE80211_SMPS_OFF;
+
+ sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+ wirelessmode = sta_entry->wireless_mode;
+ if (mac->opmode == NL80211_IFTYPE_STATION)
+ curtxbw_40mhz = mac->bw_40;
+ else if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC)
+ macid = sta->aid + 1;
+
+ if (rtlhal->current_bandtype == BAND_ON_5G)
+ ratr_bitmap = sta->supp_rates[1] << 4;
+ else
+ ratr_bitmap = sta->supp_rates[0];
+ ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+ sta->ht_cap.mcs.rx_mask[0] << 12);
switch (wirelessmode) {
case WIRELESS_MODE_B:
ratr_index = RATR_INX_WIRELESS_B;
@@ -1828,7 +1859,7 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
case WIRELESS_MODE_N_5G:
ratr_index = RATR_INX_WIRELESS_NGB;
- if (mimops == 0) {
+ if (mimo_ps == IEEE80211_SMPS_STATIC) {
if (rssi_level == 1)
ratr_bitmap &= 0x00070000;
else if (rssi_level == 2)
@@ -1892,8 +1923,8 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
}
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
("ratr_bitmap :%x\n", ratr_bitmap));
- *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
- (ratr_index << 28);
+ *(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) |
+ (ratr_index << 28));
rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, "
"ratr_val:%x, %x:%x:%x:%x:%x\n",
@@ -1902,6 +1933,20 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
rate_mask[2], rate_mask[3],
rate_mask[4]));
rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
+
+ if (macid != 0)
+ sta_entry->ratr_index = ratr_index;
+}
+
+void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u8 rssi_level)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (rtlpriv->dm.useramask)
+ rtl92ce_update_hal_rate_mask(hw, sta, rssi_level);
+ else
+ rtl92ce_update_hal_rate_table(hw, sta);
}
void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw)
@@ -1919,7 +1964,7 @@ void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw)
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
}
-bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
+bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
@@ -1929,7 +1974,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
bool actuallyset = false;
unsigned long flag;
- if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter))
+ if (rtlpci->being_init_adapter)
return false;
if (ppsc->swrf_processing)
@@ -1946,12 +1991,6 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
cur_rfstate = ppsc->rfpwr_state;
- if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
- RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) {
- rtlpriv->intf_ops->disable_aspm(hw);
- RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
- }
-
rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv,
REG_MAC_PINMUX_CFG)&~(BIT(3)));
@@ -1976,38 +2015,13 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
}
if (actuallyset) {
- if (e_rfpowerstate_toset == ERFON) {
- if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
- RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) {
- rtlpriv->intf_ops->disable_aspm(hw);
- RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
- }
- }
-
spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
ppsc->rfchange_inprogress = false;
spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
-
- if (e_rfpowerstate_toset == ERFOFF) {
- if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) {
- rtlpriv->intf_ops->enable_aspm(hw);
- RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
- }
- }
-
- } else if (e_rfpowerstate_toset == ERFOFF || cur_rfstate == ERFOFF) {
+ } else {
if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
- if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) {
- rtlpriv->intf_ops->enable_aspm(hw);
- RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
- }
-
- spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
- ppsc->rfchange_inprogress = false;
- spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
- } else {
spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
ppsc->rfchange_inprogress = false;
spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
@@ -2086,15 +2100,31 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
macaddr = cam_const_broad;
entry_id = key_index;
} else {
+ if (mac->opmode == NL80211_IFTYPE_AP) {
+ entry_id = rtl_cam_get_free_entry(hw,
+ p_macaddr);
+ if (entry_id >= TOTAL_CAM_ENTRY) {
+ RT_TRACE(rtlpriv, COMP_SEC,
+ DBG_EMERG,
+ ("Can not find free hw"
+ " security cam entry\n"));
+ return;
+ }
+ } else {
+ entry_id = CAM_PAIRWISE_KEY_POSITION;
+ }
+
key_index = PAIRWISE_KEYIDX;
- entry_id = CAM_PAIRWISE_KEY_POSITION;
is_pairwise = true;
}
}
if (rtlpriv->sec.key_len[key_index] == 0) {
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
- ("delete one entry\n"));
+ ("delete one entry, entry_id is %d\n",
+ entry_id));
+ if (mac->opmode == NL80211_IFTYPE_AP)
+ rtl_cam_del_entry(hw, p_macaddr);
rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
} else {
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
@@ -2146,3 +2176,132 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
}
}
}
+
+static void rtl8192ce_bt_var_init(struct ieee80211_hw *hw)
+{
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+ rtlpcipriv->bt_coexist.bt_coexistence =
+ rtlpcipriv->bt_coexist.eeprom_bt_coexist;
+ rtlpcipriv->bt_coexist.bt_ant_num =
+ rtlpcipriv->bt_coexist.eeprom_bt_ant_num;
+ rtlpcipriv->bt_coexist.bt_coexist_type =
+ rtlpcipriv->bt_coexist.eeprom_bt_type;
+
+ if (rtlpcipriv->bt_coexist.reg_bt_iso == 2)
+ rtlpcipriv->bt_coexist.bt_ant_isolation =
+ rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation;
+ else
+ rtlpcipriv->bt_coexist.bt_ant_isolation =
+ rtlpcipriv->bt_coexist.reg_bt_iso;
+
+ rtlpcipriv->bt_coexist.bt_radio_shared_type =
+ rtlpcipriv->bt_coexist.eeprom_bt_radio_shared;
+
+ if (rtlpcipriv->bt_coexist.bt_coexistence) {
+
+ if (rtlpcipriv->bt_coexist.reg_bt_sco == 1)
+ rtlpcipriv->bt_coexist.bt_service = BT_OTHER_ACTION;
+ else if (rtlpcipriv->bt_coexist.reg_bt_sco == 2)
+ rtlpcipriv->bt_coexist.bt_service = BT_SCO;
+ else if (rtlpcipriv->bt_coexist.reg_bt_sco == 4)
+ rtlpcipriv->bt_coexist.bt_service = BT_BUSY;
+ else if (rtlpcipriv->bt_coexist.reg_bt_sco == 5)
+ rtlpcipriv->bt_coexist.bt_service = BT_OTHERBUSY;
+ else
+ rtlpcipriv->bt_coexist.bt_service = BT_IDLE;
+
+ rtlpcipriv->bt_coexist.bt_edca_ul = 0;
+ rtlpcipriv->bt_coexist.bt_edca_dl = 0;
+ rtlpcipriv->bt_coexist.bt_rssi_state = 0xff;
+ }
+}
+
+void rtl8192ce_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
+ bool auto_load_fail, u8 *hwinfo)
+{
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+ u8 value;
+
+ if (!auto_load_fail) {
+ rtlpcipriv->bt_coexist.eeprom_bt_coexist =
+ ((hwinfo[RF_OPTION1] & 0xe0) >> 5);
+ value = hwinfo[RF_OPTION4];
+ rtlpcipriv->bt_coexist.eeprom_bt_type = ((value & 0xe) >> 1);
+ rtlpcipriv->bt_coexist.eeprom_bt_ant_num = (value & 0x1);
+ rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation =
+ ((value & 0x10) >> 4);
+ rtlpcipriv->bt_coexist.eeprom_bt_radio_shared =
+ ((value & 0x20) >> 5);
+ } else {
+ rtlpcipriv->bt_coexist.eeprom_bt_coexist = 0;
+ rtlpcipriv->bt_coexist.eeprom_bt_type = BT_2WIRE;
+ rtlpcipriv->bt_coexist.eeprom_bt_ant_num = ANT_X2;
+ rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation = 0;
+ rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = BT_RADIO_SHARED;
+ }
+
+ rtl8192ce_bt_var_init(hw);
+}
+
+void rtl8192ce_bt_reg_init(struct ieee80211_hw *hw)
+{
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+ /* 0:Low, 1:High, 2:From Efuse. */
+ rtlpcipriv->bt_coexist.reg_bt_iso = 2;
+ /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
+ rtlpcipriv->bt_coexist.reg_bt_sco = 3;
+ /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
+ rtlpcipriv->bt_coexist.reg_bt_sco = 0;
+}
+
+
+void rtl8192ce_bt_hw_init(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+ u8 u1_tmp;
+
+ if (rtlpcipriv->bt_coexist.bt_coexistence &&
+ ((rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) ||
+ rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC8)) {
+
+ if (rtlpcipriv->bt_coexist.bt_ant_isolation)
+ rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
+
+ u1_tmp = rtl_read_byte(rtlpriv, 0x4fd) &
+ BIT_OFFSET_LEN_MASK_32(0, 1);
+ u1_tmp = u1_tmp |
+ ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ?
+ 0 : BIT_OFFSET_LEN_MASK_32(1, 1)) |
+ ((rtlpcipriv->bt_coexist.bt_service == BT_SCO) ?
+ 0 : BIT_OFFSET_LEN_MASK_32(2, 1));
+ rtl_write_byte(rtlpriv, 0x4fd, u1_tmp);
+
+ rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+4, 0xaaaa9aaa);
+ rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+8, 0xffbd0040);
+ rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+0xc, 0x40000010);
+
+ /* Config to 1T1R. */
+ if (rtlphy->rf_type == RF_1T1R) {
+ u1_tmp = rtl_read_byte(rtlpriv, ROFDM0_TRXPATHENABLE);
+ u1_tmp &= ~(BIT_OFFSET_LEN_MASK_32(1, 1));
+ rtl_write_byte(rtlpriv, ROFDM0_TRXPATHENABLE, u1_tmp);
+
+ u1_tmp = rtl_read_byte(rtlpriv, ROFDM1_TRXPATHENABLE);
+ u1_tmp &= ~(BIT_OFFSET_LEN_MASK_32(1, 1));
+ rtl_write_byte(rtlpriv, ROFDM1_TRXPATHENABLE, u1_tmp);
+ }
+ }
+}
+
+void rtl92ce_suspend(struct ieee80211_hw *hw)
+{
+}
+
+void rtl92ce_resume(struct ieee80211_hw *hw)
+{
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
index a3dfdb63516..07dbe3e340a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
@@ -30,7 +30,18 @@
#ifndef __RTL92CE_HW_H__
#define __RTL92CE_HW_H__
-#define H2C_RA_MASK 6
+static inline u8 _rtl92c_get_chnl_group(u8 chnl)
+{
+ u8 group;
+
+ if (chnl < 3)
+ group = 0;
+ else if (chnl < 9)
+ group = 1;
+ else
+ group = 2;
+ return group;
+}
void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw);
@@ -41,28 +52,27 @@ void rtl92ce_card_disable(struct ieee80211_hw *hw);
void rtl92ce_enable_interrupt(struct ieee80211_hw *hw);
void rtl92ce_disable_interrupt(struct ieee80211_hw *hw);
int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
+void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci);
void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw);
void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw);
void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,
u32 add_msr, u32 rm_msr);
void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
-void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw);
-void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level);
+void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u8 rssi_level);
void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw);
bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw);
void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
u8 *p_macaddr, bool is_group, u8 enc_algo,
bool is_wepkey, bool clear_all);
-bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
-void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
-void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
-void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
-int rtl92c_download_fw(struct ieee80211_hw *hw);
-void rtl92c_firmware_selfreset(struct ieee80211_hw *hw);
-void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
- u8 element_id, u32 cmd_len, u8 *p_cmdbuffer);
-bool rtl92ce_phy_mac_config(struct ieee80211_hw *hw);
+
+void rtl8192ce_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
+ bool autoload_fail, u8 *hwinfo);
+void rtl8192ce_bt_reg_init(struct ieee80211_hw *hw);
+void rtl8192ce_bt_hw_init(struct ieee80211_hw *hw);
+void rtl92ce_suspend(struct ieee80211_hw *hw);
+void rtl92ce_resume(struct ieee80211_hw *hw);
#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
index 7b1da8d7508..9dd1ed7b642 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
@@ -32,6 +32,14 @@
#include "reg.h"
#include "led.h"
+static void _rtl92ce_init_led(struct ieee80211_hw *hw,
+ struct rtl_led *pled, enum rtl_led_pin ledpin)
+{
+ pled->hw = hw;
+ pled->ledpin = ledpin;
+ pled->ledon = false;
+}
+
void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
{
u8 ledcfg;
@@ -97,13 +105,12 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
void rtl92ce_init_sw_leds(struct ieee80211_hw *hw)
{
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);
+ _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);
}
-void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw)
-{
-}
-
-void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
+static void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
enum led_ctl_mode ledaction)
{
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
@@ -138,7 +145,7 @@ void rtl92ce_led_control(struct ieee80211_hw *hw,
ledaction == LED_CTL_POWER_ON)) {
return;
}
- RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n",
+ RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d.\n",
ledaction));
_rtl92ce_sw_led_control(hw, ledaction);
}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h
index 10da3018f4b..7dfccea2095 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h
@@ -31,11 +31,8 @@
#define __RTL92CE_LED_H__
void rtl92ce_init_sw_leds(struct ieee80211_hw *hw);
-void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw);
void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
-void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
- enum led_ctl_mode ledaction);
#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
index d0541e8c601..73ae8a43184 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
@@ -38,7 +38,9 @@
#include "dm.h"
#include "table.h"
-u32 rtl92ce_phy_query_rf_reg(struct ieee80211_hw *hw,
+static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
+
+u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr, u32 bitmask)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -73,9 +75,47 @@ u32 rtl92ce_phy_query_rf_reg(struct ieee80211_hw *hw,
return readback_value;
}
+bool rtl92c_phy_mac_config(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ bool is92c = IS_92C_SERIAL(rtlhal->version);
+ bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw);
+
+ if (is92c)
+ rtl_write_byte(rtlpriv, 0x14, 0x71);
+ return rtstatus;
+}
+
+bool rtl92c_phy_bb_config(struct ieee80211_hw *hw)
+{
+ bool rtstatus = true;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u16 regval;
+ u32 regvaldw;
+ u8 reg_hwparafile = 1;
+
+ _rtl92c_phy_init_bb_rf_register_definition(hw);
+ regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
+ rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
+ regval | BIT(13) | BIT(0) | BIT(1));
+ rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
+ rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
+ rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
+ FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
+ FEN_BB_GLB_RSTn | FEN_BBRSTB);
+ rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
+ regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
+ rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
+ if (reg_hwparafile == 1)
+ rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
+ return rtstatus;
+}
+
void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
- enum radio_path rfpath,
- u32 regaddr, u32 bitmask, u32 data)
+ enum radio_path rfpath,
+ u32 regaddr, u32 bitmask, u32 data)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -121,45 +161,7 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
bitmask, data, rfpath));
}
-bool rtl92ce_phy_mac_config(struct ieee80211_hw *hw)
-{
- struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
- bool is92c = IS_92C_SERIAL(rtlhal->version);
- bool rtstatus = _rtl92ce_phy_config_mac_with_headerfile(hw);
-
- if (is92c)
- rtl_write_byte(rtlpriv, 0x14, 0x71);
- return rtstatus;
-}
-
-bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw)
-{
- bool rtstatus = true;
- struct rtl_priv *rtlpriv = rtl_priv(hw);
- u16 regval;
- u32 regvaldw;
- u8 reg_hwparafile = 1;
-
- _rtl92c_phy_init_bb_rf_register_definition(hw);
- regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
- rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
- regval | BIT(13) | BIT(0) | BIT(1));
- rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
- rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
- rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
- rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
- FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
- FEN_BB_GLB_RSTn | FEN_BBRSTB);
- rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
- regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
- rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
- if (reg_hwparafile == 1)
- rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
- return rtstatus;
-}
-
-bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
+static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 i;
@@ -177,7 +179,7 @@ bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
}
bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
- u8 configtype)
+ u8 configtype)
{
int i;
u32 *phy_regarray_table;
@@ -236,7 +238,7 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
}
bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
- u8 configtype)
+ u8 configtype)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
int i;
@@ -274,7 +276,7 @@ bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
return true;
}
-bool rtl92ce_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
+bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath)
{
@@ -364,74 +366,6 @@ bool rtl92ce_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
return true;
}
-void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
-{
- struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
- struct rtl_phy *rtlphy = &(rtlpriv->phy);
- struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
- u8 reg_bw_opmode;
- u8 reg_prsr_rsc;
-
- RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
- ("Switch to %s bandwidth\n",
- rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
- "20MHz" : "40MHz"))
-
- if (is_hal_stop(rtlhal))
- return;
-
- reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
- reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
-
- switch (rtlphy->current_chan_bw) {
- case HT_CHANNEL_WIDTH_20:
- reg_bw_opmode |= BW_OPMODE_20MHZ;
- rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
- break;
-
- case HT_CHANNEL_WIDTH_20_40:
- reg_bw_opmode &= ~BW_OPMODE_20MHZ;
- rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
-
- reg_prsr_rsc =
- (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
- rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
- break;
-
- default:
- RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
- ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
- break;
- }
-
- switch (rtlphy->current_chan_bw) {
- case HT_CHANNEL_WIDTH_20:
- rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
- rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
- rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
- break;
- case HT_CHANNEL_WIDTH_20_40:
- rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
- rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
- rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
- (mac->cur_40_prime_sc >> 1));
- rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
- rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
- rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
- (mac->cur_40_prime_sc ==
- HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
- break;
- default:
- RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
- ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
- break;
- }
- rtl92c_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
- rtlphy->set_bwmode_inprogress = false;
- RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
-}
-
void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
{
u8 tmpreg;
@@ -477,6 +411,36 @@ void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
}
}
+static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw)
+{
+ u32 u4b_tmp;
+ u8 delay = 5;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
+ rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
+ u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
+ while (u4b_tmp != 0 && delay > 0) {
+ rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
+ rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
+ u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
+ delay--;
+ }
+ if (delay == 0) {
+ rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
+ rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
+ ("Switch RF timeout !!!.\n"));
+ return;
+ }
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
+ rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
+}
+
static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state)
{
@@ -523,33 +487,6 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
break;
}
case ERFOFF:{
- for (queue_id = 0, i = 0;
- queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
- ring = &pcipriv->dev.tx_ring[queue_id];
- if (skb_queue_len(&ring->queue) == 0 ||
- queue_id == BEACON_QUEUE) {
- queue_id++;
- continue;
- } else {
- RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
- ("eRf Off/Sleep: %d times "
- "TcbBusyQueue[%d] "
- "=%d before doze!\n", (i + 1),
- queue_id,
- skb_queue_len(&ring->queue)));
- udelay(10);
- i++;
- }
- if (i >= MAX_DOZE_WAITING_TIMES_9x) {
- RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
- ("\nERFOFF: %d times "
- "TcbBusyQueue[%d] = %d !\n",
- MAX_DOZE_WAITING_TIMES_9x,
- queue_id,
- skb_queue_len(&ring->queue)));
- break;
- }
- }
if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
("IPS Set eRf nic disable\n"));
@@ -581,6 +518,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
"TcbBusyQueue[%d] =%d before "
"doze!\n", (i + 1), queue_id,
skb_queue_len(&ring->queue)));
+
udelay(10);
i++;
}
@@ -599,7 +537,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
jiffies_to_msecs(jiffies -
ppsc->last_awake_jiffies)));
ppsc->last_sleep_jiffies = jiffies;
- _rtl92c_phy_set_rf_sleep(hw);
+ _rtl92ce_phy_set_rf_sleep(hw);
break;
}
default:
@@ -614,10 +552,11 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
return bresult;
}
-bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
+bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state)
{
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
bool bresult = false;
if (rfpwr_state == ppsc->rfpwr_state)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
index a37267e3fc2..ad580852cc7 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
@@ -39,6 +39,7 @@
#define RT_CANNOT_IO(hw) false
#define HIGHPOWER_RADIOA_ARRAYLEN 22
+#define IQK_ADDA_REG_NUM 16
#define MAX_TOLERANCE 5
#define IQK_DELAY_TIME 1
@@ -56,6 +57,8 @@
#define IQK_ADDA_REG_NUM 16
#define IQK_MAC_REG_NUM 4
+#define IQK_DELAY_TIME 1
+
#define RF90_PATH_MAX 2
#define CT_OFFSET_MAC_ADDR 0X16
@@ -76,7 +79,7 @@
#define CT_OFFSET_CUSTOMER_ID 0x7F
#define RTL92C_MAX_PATH_NUM 2
-#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255
+
enum swchnlcmd_id {
CMDID_END,
CMDID_SET_TXPOWEROWER_LEVEL,
@@ -184,43 +187,44 @@ struct tx_power_struct {
u32 mcs_original_offset[4][16];
};
-extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw,
+bool rtl92c_phy_bb_config(struct ieee80211_hw *hw);
+u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw,
u32 regaddr, u32 bitmask);
-extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
+void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
u32 regaddr, u32 bitmask, u32 data);
-extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
+u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr,
u32 bitmask);
extern void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
- enum radio_path rfpath, u32 regaddr,
- u32 bitmask, u32 data);
-extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw);
+ enum radio_path rfpath, u32 regaddr,
+ u32 bitmask, u32 data);
+bool rtl92c_phy_mac_config(struct ieee80211_hw *hw);
bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw);
-extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw);
-extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
+bool rtl92c_phy_rf_config(struct ieee80211_hw *hw);
+bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
-extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
-extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,
+void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
+void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,
long *powerlevel);
-extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
-extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,
+void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
+bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,
long power_indbm);
-extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw,
+void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw,
u8 operation);
-extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
-extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
+void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
enum nl80211_channel_type ch_type);
-extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
-extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw);
-extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
-extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw,
+void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
+u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw);
+void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
+void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw,
u16 beaconinterval);
void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
+void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t);
void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
-extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,
+bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,
u32 rfpath);
bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
@@ -237,9 +241,6 @@ u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask);
void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 offset,
u32 data);
-void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
- u32 regaddr, u32 bitmask,
- u32 data);
void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 offset,
u32 data);
@@ -250,5 +251,11 @@ bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw);
+bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
+ enum rf_pwrstate rfpwr_state);
+bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
+ u8 configtype);
+bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
+ u8 configtype);
#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
index b0868a61384..598cecc63f4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
@@ -72,6 +72,7 @@
#define REG_GPIO_IO_SEL_2 0x0062
/* RTL8723 WIFI/BT/GPS Multi-Function control source. */
#define REG_MULTI_FUNC_CTRL 0x0068
+
#define REG_MCUFWDL 0x0080
#define REG_HMEBOX_EXT_0 0x0088
@@ -542,7 +543,7 @@
#define IMR_OCPINT BIT(1)
#define IMR_WLANOFF BIT(0)
-#define HWSET_MAX_SIZE 128
+#define EFUSE_REAL_CONTENT_LEN 512
#define EEPROM_DEFAULT_TSSI 0x0
#define EEPROM_DEFAULT_TXPOWERDIFF 0x0
@@ -656,6 +657,7 @@
#define STOPBE BIT(1)
#define STOPBK BIT(0)
+#define RCR_APPFCS BIT(31)
#define RCR_APP_FCS BIT(31)
#define RCR_APP_MIC BIT(30)
#define RCR_APP_ICV BIT(29)
@@ -688,6 +690,7 @@
#define REG_USB_INFO 0xFE17
#define REG_USB_SPECIAL_OPTION 0xFE55
+
#define REG_USB_DMA_AGG_TO 0xFE5B
#define REG_USB_AGG_TO 0xFE5C
#define REG_USB_AGG_TH 0xFE5D
@@ -775,7 +778,6 @@
#define BOOT_FROM_EEPROM BIT(4)
#define EEPROM_EN BIT(5)
-#define EEPROMSEL BOOT_FROM_EEPROM
#define AFE_BGEN BIT(0)
#define AFE_MBEN BIT(1)
@@ -901,28 +903,7 @@
#define BD_PKG_SEL BIT(25)
#define BD_HCI_SEL BIT(26)
#define TYPE_ID BIT(27)
-
-/* REG_GPIO_OUTSTS (For RTL8723 only) */
-#define EFS_HCI_SEL (BIT(0)|BIT(1))
-#define PAD_HCI_SEL (BIT(2)|BIT(3))
-#define HCI_SEL (BIT(4)|BIT(5))
-#define PKG_SEL_HCI BIT(6)
-#define FEN_GPS BIT(7)
-#define FEN_BT BIT(8)
-#define FEN_WL BIT(9)
-#define FEN_PCI BIT(10)
-#define FEN_USB BIT(11)
-#define BTRF_HWPDN_N BIT(12)
-#define WLRF_HWPDN_N BIT(13)
-#define PDN_BT_N BIT(14)
-#define PDN_GPS_N BIT(15)
-#define BT_CTL_HWPDN BIT(16)
-#define GPS_CTL_HWPDN BIT(17)
-#define PPHY_SUSB BIT(20)
-#define UPHY_SUSB BIT(21)
-#define PCI_SUSEN BIT(22)
-#define USB_SUSEN BIT(23)
-#define RF_RL_ID (BIT(31) | BIT(30) | BIT(29) | BIT(28))
+#define RF_RL_ID (BIT(31) | BIT(30) | BIT(29) | BIT(28))
#define CHIP_VER_RTL_MASK 0xF000
#define CHIP_VER_RTL_SHIFT 12
@@ -1077,6 +1058,7 @@
#define _RARF_RC8(x) (((x) & 0x1F) << 24)
#define AC_PARAM_TXOP_OFFSET 16
+#define AC_PARAM_TXOP_LIMIT_OFFSET 16
#define AC_PARAM_ECW_MAX_OFFSET 12
#define AC_PARAM_ECW_MIN_OFFSET 8
#define AC_PARAM_AIFS_OFFSET 0
@@ -1221,33 +1203,11 @@
#define EPROM_CMD_CONFIG 0x3
#define EPROM_CMD_LOAD 1
-#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE
+#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE
-#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2)
-
-/* REG_MULTI_FUNC_CTRL(For RTL8723 Only) */
-/* Enable GPIO[9] as WiFi HW PDn source */
#define WL_HWPDN_EN BIT(0)
-/* WiFi HW PDn polarity control */
-#define WL_HWPDN_SL BIT(1)
-/* WiFi function enable */
-#define WL_FUNC_EN BIT(2)
-/* Enable GPIO[9] as WiFi RF HW PDn source */
-#define WL_HWROF_EN BIT(3)
-/* Enable GPIO[11] as BT HW PDn source */
-#define BT_HWPDN_EN BIT(16)
-/* BT HW PDn polarity control */
-#define BT_HWPDN_SL BIT(17)
-/* BT function enable */
-#define BT_FUNC_EN BIT(18)
-/* Enable GPIO[11] as BT/GPS RF HW PDn source */
-#define BT_HWROF_EN BIT(19)
-/* Enable GPIO[10] as GPS HW PDn source */
-#define GPS_HWPDN_EN BIT(20)
-/* GPS HW PDn polarity control */
-#define GPS_HWPDN_SL BIT(21)
-/* GPS function enable */
-#define GPS_FUNC_EN BIT(22)
+
+#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2)
#define RPMAC_RESET 0x100
#define RPMAC_TXSTART 0x104
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
index 669b1168dbe..90d0f2cf3b2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
@@ -34,9 +34,9 @@
#include "rf.h"
#include "dm.h"
-static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw);
+static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw);
-void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
+void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -62,7 +62,7 @@ void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
}
void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
- u8 *ppowerlevel)
+ u8 *ppowerlevel)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -128,8 +128,7 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
tmpval = tx_agc[RF90_PATH_A] >> 8;
- if (mac->mode == WIRELESS_MODE_B)
- tmpval = tmpval & 0xff00ffff;
+ tmpval = tmpval & 0xff00ffff;
rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
@@ -202,7 +201,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
- u8 i, chnlgroup, pwr_diff_limit[4];
+ u8 i, chnlgroup = 0, pwr_diff_limit[4];
u32 writeVal, customer_limit, rf;
for (rf = 0; rf < 2; rf++) {
@@ -440,16 +439,17 @@ bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw)
else
rtlphy->num_total_rfpath = 2;
- return _rtl92c_phy_rf6052_config_parafile(hw);
+ return _rtl92ce_phy_rf6052_config_parafile(hw);
+
}
-static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
+static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
- u32 u4_regvalue;
+ u32 u4_regvalue = 0;
u8 rfpath;
- bool rtstatus;
+ bool rtstatus = true;
struct bb_reg_def *pphyreg;
for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
@@ -484,12 +484,12 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
switch (rfpath) {
case RF90_PATH_A:
- rtstatus = rtl92ce_phy_config_rf_with_headerfile(hw,
- (enum radio_path) rfpath);
+ rtstatus = rtl92c_phy_config_rf_with_headerfile(hw,
+ (enum radio_path)rfpath);
break;
case RF90_PATH_B:
- rtstatus = rtl92ce_phy_config_rf_with_headerfile(hw,
- (enum radio_path) rfpath);
+ rtstatus = rtl92c_phy_config_rf_with_headerfile(hw,
+ (enum radio_path)rfpath);
break;
case RF90_PATH_C:
break;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
index 3aa520c1c17..39ff0368598 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
@@ -34,14 +34,11 @@
#define RF6052_MAX_REG 0x3F
#define RF6052_MAX_PATH 2
-extern void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
- u8 bandwidth);
-extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
- u8 *ppowerlevel);
-extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
- u8 *ppowerlevel, u8 channel);
-bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw);
-bool rtl92ce_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
- enum radio_path rfpath);
-
+extern void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
+ u8 bandwidth);
+extern void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
+ u8 *ppowerlevel);
+extern void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
+ u8 *ppowerlevel, u8 channel);
+extern bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw);
#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
index b1cc4d44f53..390bbb5ee11 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -42,10 +42,58 @@
#include "trx.h"
#include "led.h"
+static void rtl92c_init_aspm_vars(struct ieee80211_hw *hw)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ /*close ASPM for AMD defaultly */
+ rtlpci->const_amdpci_aspm = 0;
+
+ /*
+ * ASPM PS mode.
+ * 0 - Disable ASPM,
+ * 1 - Enable ASPM without Clock Req,
+ * 2 - Enable ASPM with Clock Req,
+ * 3 - Alwyas Enable ASPM with Clock Req,
+ * 4 - Always Enable ASPM without Clock Req.
+ * set defult to RTL8192CE:3 RTL8192E:2
+ * */
+ rtlpci->const_pci_aspm = 3;
+
+ /*Setting for PCI-E device */
+ rtlpci->const_devicepci_aspm_setting = 0x03;
+
+ /*Setting for PCI-E bridge */
+ rtlpci->const_hostpci_aspm_setting = 0x02;
+
+ /*
+ * In Hw/Sw Radio Off situation.
+ * 0 - Default,
+ * 1 - From ASPM setting without low Mac Pwr,
+ * 2 - From ASPM setting with low Mac Pwr,
+ * 3 - Bus D3
+ * set default to RTL8192CE:0 RTL8192SE:2
+ */
+ rtlpci->const_hwsw_rfoff_d3 = 0;
+
+ /*
+ * This setting works for those device with
+ * backdoor ASPM setting such as EPHY setting.
+ * 0 - Not support ASPM,
+ * 1 - Support ASPM,
+ * 2 - According to chipset.
+ */
+ rtlpci->const_support_pciaspm = 1;
+}
+
int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
{
+ int err;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ const struct firmware *firmware;
+
+ rtl8192ce_bt_reg_init(hw);
rtlpriv->dm.dm_initialgain_enable = 1;
rtlpriv->dm.dm_flag = 0;
@@ -53,7 +101,12 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
rtlpriv->dm.thermalvalue = 0;
rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13);
- rtlpci->receive_config = (RCR_APP_FCS |
+ /* compatible 5G band 88ce just 2.4G band & smsp */
+ rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
+ rtlpriv->rtlhal.bandset = BAND_ON_2_4G;
+ rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
+
+ rtlpci->receive_config = (RCR_APPFCS |
RCR_AMF |
RCR_ADF |
RCR_APP_MIC |
@@ -76,13 +129,49 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0);
- rtlpriv->rtlhal.pfirmware = (u8 *) vmalloc(0x4000);
+ /* for LPS & IPS */
+ rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
+ rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
+ rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
+ rtlpriv->psc.reg_fwctrl_lps = 3;
+ rtlpriv->psc.reg_max_lps_awakeintvl = 5;
+ /* for ASPM, you can close aspm through
+ * set const_support_pciaspm = 0 */
+ rtl92c_init_aspm_vars(hw);
+
+ if (rtlpriv->psc.reg_fwctrl_lps == 1)
+ rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
+ else if (rtlpriv->psc.reg_fwctrl_lps == 2)
+ rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
+ else if (rtlpriv->psc.reg_fwctrl_lps == 3)
+ rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
+
+ /* for firmware buf */
+ rtlpriv->rtlhal.pfirmware = vzalloc(0x4000);
if (!rtlpriv->rtlhal.pfirmware) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("Can't alloc buffer for fw.\n"));
return 1;
}
+ /* request fw */
+ err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
+ rtlpriv->io.dev);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Failed to request firmware!\n"));
+ return 1;
+ }
+ if (firmware->size > 0x4000) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Firmware is too big!\n"));
+ release_firmware(firmware);
+ return 1;
+ }
+ memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
+ rtlpriv->rtlhal.fwsize = firmware->size;
+ release_firmware(firmware);
+
return 0;
}
@@ -103,17 +192,19 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = {
.interrupt_recognized = rtl92ce_interrupt_recognized,
.hw_init = rtl92ce_hw_init,
.hw_disable = rtl92ce_card_disable,
+ .hw_suspend = rtl92ce_suspend,
+ .hw_resume = rtl92ce_resume,
.enable_interrupt = rtl92ce_enable_interrupt,
.disable_interrupt = rtl92ce_disable_interrupt,
.set_network_type = rtl92ce_set_network_type,
+ .set_chk_bssid = rtl92ce_set_check_bssid,
.set_qos = rtl92ce_set_qos,
.set_bcn_reg = rtl92ce_set_beacon_related_registers,
.set_bcn_intv = rtl92ce_set_beacon_interval,
.update_interrupt_mask = rtl92ce_update_interrupt_mask,
.get_hw_reg = rtl92ce_get_hw_reg,
.set_hw_reg = rtl92ce_set_hw_reg,
- .update_rate_table = rtl92ce_update_hal_rate_table,
- .update_rate_mask = rtl92ce_update_hal_rate_mask,
+ .update_rate_tbl = rtl92ce_update_hal_rate_tbl,
.fill_tx_desc = rtl92ce_tx_fill_desc,
.fill_tx_cmddesc = rtl92ce_tx_fill_cmddesc,
.query_rx_desc = rtl92ce_rx_query_desc,
@@ -123,7 +214,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = {
.switch_channel = rtl92c_phy_sw_chnl,
.dm_watchdog = rtl92c_dm_watchdog,
.scan_operation_backup = rtl92c_phy_scan_operation_backup,
- .set_rf_power_state = rtl92ce_phy_set_rf_power_state,
+ .set_rf_power_state = rtl92c_phy_set_rf_power_state,
.led_control = rtl92ce_led_control,
.set_desc = rtl92ce_set_desc,
.get_desc = rtl92ce_get_desc,
@@ -131,27 +222,29 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = {
.enable_hw_sec = rtl92ce_enable_hw_security_config,
.set_key = rtl92ce_set_key,
.init_sw_leds = rtl92ce_init_sw_leds,
- .deinit_sw_leds = rtl92ce_deinit_sw_leds,
.get_bbreg = rtl92c_phy_query_bb_reg,
.set_bbreg = rtl92c_phy_set_bb_reg,
- .get_rfreg = rtl92ce_phy_query_rf_reg,
.set_rfreg = rtl92ce_phy_set_rf_reg,
- .cmd_send_packet = _rtl92c_cmd_send_packet,
+ .get_rfreg = rtl92c_phy_query_rf_reg,
.phy_rf6052_config = rtl92ce_phy_rf6052_config,
.phy_rf6052_set_cck_txpower = rtl92ce_phy_rf6052_set_cck_txpower,
.phy_rf6052_set_ofdm_txpower = rtl92ce_phy_rf6052_set_ofdm_txpower,
.config_bb_with_headerfile = _rtl92ce_phy_config_bb_with_headerfile,
.config_bb_with_pgheaderfile = _rtl92ce_phy_config_bb_with_pgheaderfile,
.phy_lc_calibrate = _rtl92ce_phy_lc_calibrate,
- .phy_set_bw_mode_callback = rtl92ce_phy_set_bw_mode_callback,
.dm_dynamic_txpower = rtl92ce_dm_dynamic_txpower,
};
static struct rtl_mod_params rtl92ce_mod_params = {
- .sw_crypto = 0,
+ .sw_crypto = false,
+ .inactiveps = true,
+ .swctrl_lps = false,
+ .fwctrl_lps = true,
};
static struct rtl_hal_cfg rtl92ce_hal_cfg = {
+ .bar_id = 2,
+ .write_readback = true,
.name = "rtl92c_pci",
.fw_name = "rtlwifi/rtl8192cfw.bin",
.ops = &rtl8192ce_hal_ops,
@@ -175,6 +268,8 @@ static struct rtl_hal_cfg rtl92ce_hal_cfg = {
.maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
.maps[EFUSE_ANA8M] = EFUSE_ANA8M,
.maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
+ .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
+ .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
.maps[RWCAM] = REG_CAMCMD,
.maps[WCAMI] = REG_CAMWRITE,
@@ -239,7 +334,7 @@ static struct rtl_hal_cfg rtl92ce_hal_cfg = {
.maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15,
};
-static struct pci_device_id rtl92ce_pci_ids[] __devinitdata = {
+DEFINE_PCI_DEVICE_TABLE(rtl92ce_pci_ids) = {
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8191, rtl92ce_hal_cfg)},
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8178, rtl92ce_hal_cfg)},
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8177, rtl92ce_hal_cfg)},
@@ -257,7 +352,13 @@ MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless");
MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin");
module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444);
+module_param_named(ips, rtl92ce_mod_params.inactiveps, bool, 0444);
+module_param_named(swlps, rtl92ce_mod_params.swctrl_lps, bool, 0444);
+module_param_named(fwlps, rtl92ce_mod_params.fwctrl_lps, bool, 0444);
MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n");
+MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n");
+MODULE_PARM_DESC(fwlps, "using linked fw control power save "
+ "(default 1 is open)\n");
static struct pci_driver rtl92ce_driver = {
.name = KBUILD_MODNAME,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
index 36e657668c1..b7dc3263e43 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
@@ -33,19 +33,9 @@
int rtl92c_init_sw_vars(struct ieee80211_hw *hw);
void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw);
void rtl92c_init_var_map(struct ieee80211_hw *hw);
-bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
- struct sk_buff *skb);
-void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
- u8 *ppowerlevel);
-void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
- u8 *ppowerlevel, u8 channel);
bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
- u8 configtype);
+ u8 configtype);
bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
- u8 configtype);
-void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t);
-u32 rtl92ce_phy_query_rf_reg(struct ieee80211_hw *hw,
- enum radio_path rfpath, u32 regaddr, u32 bitmask);
-void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
+ u8 configtype);
#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
index aa2b5815600..54b2bd53d36 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -36,42 +36,16 @@
#include "trx.h"
#include "led.h"
-static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(__le16 fc,
- unsigned int
- skb_queue)
+static u8 _rtl92ce_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
{
- enum rtl_desc_qsel qsel;
+ __le16 fc = rtl_get_fc(skb);
- if (unlikely(ieee80211_is_beacon(fc))) {
- qsel = QSLT_BEACON;
- return qsel;
- }
-
- if (ieee80211_is_mgmt(fc)) {
- qsel = QSLT_MGNT;
- return qsel;
- }
+ if (unlikely(ieee80211_is_beacon(fc)))
+ return QSLT_BEACON;
+ if (ieee80211_is_mgmt(fc))
+ return QSLT_MGNT;
- switch (skb_queue) {
- case VO_QUEUE:
- qsel = QSLT_VO;
- break;
- case VI_QUEUE:
- qsel = QSLT_VI;
- break;
- case BE_QUEUE:
- qsel = QSLT_BE;
- break;
- case BK_QUEUE:
- qsel = QSLT_BK;
- break;
- default:
- qsel = QSLT_BE;
- RT_ASSERT(false, ("BE queue, skb_queue:%d,"
- " set qsel = 0x%X\n", skb_queue, QSLT_BE));
- break;
- }
- return qsel;
+ return skb->priority;
}
static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu)
@@ -255,6 +229,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
u8 evm, pwdb_all, rf_rx_num = 0;
u8 i, max_spatial_stream;
u32 rssi, total_rssi = 0;
+ bool in_powersavemode = false;
bool is_cck_rate;
is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
@@ -270,9 +245,13 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
u8 report, cck_highpwr;
cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
- cck_highpwr = (u8) rtl_get_bbreg(hw,
- RFPGA0_XA_HSSIPARAMETER2,
- BIT(9));
+ if (!in_powersavemode)
+ cck_highpwr = (u8) rtl_get_bbreg(hw,
+ RFPGA0_XA_HSSIPARAMETER2,
+ BIT(9));
+ else
+ cck_highpwr = false;
+
if (!cck_highpwr) {
u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
report = cck_buf->cck_agc_rpt & 0xc0;
@@ -398,6 +377,7 @@ static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw,
if (rtlpriv->stats.ui_rssi.total_num++ >=
PHY_RSSI_SLID_WIN_MAX) {
+
rtlpriv->stats.ui_rssi.total_num =
PHY_RSSI_SLID_WIN_MAX;
last_rssi =
@@ -424,10 +404,6 @@ static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw,
if (!pstats->is_cck && pstats->packet_toself) {
for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
rfpath++) {
-
- if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath))
- continue;
-
if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
rtlpriv->stats.rx_rssi_percentage[rfpath] =
pstats->rx_mimo_signalstrength[rfpath];
@@ -723,7 +699,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc_tx,
struct ieee80211_tx_info *info, struct sk_buff *skb,
- unsigned int queue_index)
+ u8 hw_queue, struct rtl_tcb_desc *tcb_desc)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
@@ -732,16 +708,9 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
bool defaultadapter = true;
struct ieee80211_sta *sta;
u8 *pdesc = (u8 *) pdesc_tx;
- struct rtl_tcb_desc tcb_desc;
- u8 *qc = ieee80211_get_qos_ctl(hdr);
- u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
u16 seq_number;
__le16 fc = hdr->frame_control;
- u8 rate_flag = info->control.rates[0].flags;
-
- enum rtl_desc_qsel fw_qsel =
- _rtl92ce_map_hwqueue_to_fwqueue(fc, queue_index);
-
+ u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue);
bool firstseg = ((hdr->seq_ctrl &
cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
@@ -751,56 +720,68 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
dma_addr_t mapping = pci_map_single(rtlpci->pdev,
skb->data, skb->len,
PCI_DMA_TODEVICE);
+ u8 bw_40 = 0;
+
+ rcu_read_lock();
+ sta = get_sta(hw, mac->vif, mac->bssid);
+ if (mac->opmode == NL80211_IFTYPE_STATION) {
+ bw_40 = mac->bw_40;
+ } else if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC) {
+ if (sta)
+ bw_40 = sta->ht_cap.cap &
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ }
seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
- rtl_get_tcb_desc(hw, info, skb, &tcb_desc);
+ rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
+ if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
+ firstseg = true;
+ lastseg = true;
+ }
if (firstseg) {
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
- SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate);
+ SET_TX_DESC_TX_RATE(pdesc, tcb_desc->hw_rate);
- if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble)
+ if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
- if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&
- info->flags & IEEE80211_TX_CTL_AMPDU) {
+ if (info->flags & IEEE80211_TX_CTL_AMPDU) {
SET_TX_DESC_AGG_BREAK(pdesc, 1);
SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
}
SET_TX_DESC_SEQ(pdesc, seq_number);
- SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.rts_enable &&
- !tcb_desc.
+ SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc->rts_enable &&
+ !tcb_desc->
cts_enable) ? 1 : 0));
SET_TX_DESC_HW_RTS_ENABLE(pdesc,
- ((tcb_desc.rts_enable
- || tcb_desc.cts_enable) ? 1 : 0));
- SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.cts_enable) ? 1 : 0));
- SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.rts_stbc) ? 1 : 0));
+ ((tcb_desc->rts_enable
+ || tcb_desc->cts_enable) ? 1 : 0));
+ SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc->cts_enable) ? 1 : 0));
+ SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc->rts_stbc) ? 1 : 0));
- SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate);
+ SET_TX_DESC_RTS_RATE(pdesc, tcb_desc->rts_rate);
SET_TX_DESC_RTS_BW(pdesc, 0);
- SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc);
+ SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc);
SET_TX_DESC_RTS_SHORT(pdesc,
- ((tcb_desc.rts_rate <= DESC92C_RATE54M) ?
- (tcb_desc.rts_use_shortpreamble ? 1 : 0)
- : (tcb_desc.rts_use_shortgi ? 1 : 0)));
+ ((tcb_desc->rts_rate <= DESC92C_RATE54M) ?
+ (tcb_desc->rts_use_shortpreamble ? 1 : 0)
+ : (tcb_desc->rts_use_shortgi ? 1 : 0)));
- if (mac->bw_40) {
- if (tcb_desc.packet_bw) {
+ if (bw_40) {
+ if (tcb_desc->packet_bw) {
SET_TX_DESC_DATA_BW(pdesc, 1);
SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
} else {
SET_TX_DESC_DATA_BW(pdesc, 0);
-
- if (rate_flag & IEEE80211_TX_RC_DUP_DATA) {
- SET_TX_DESC_TX_SUB_CARRIER(pdesc,
- mac->cur_40_prime_sc);
- }
+ SET_TX_DESC_TX_SUB_CARRIER(pdesc,
+ mac->cur_40_prime_sc);
}
} else {
SET_TX_DESC_DATA_BW(pdesc, 0);
@@ -810,13 +791,10 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
SET_TX_DESC_LINIP(pdesc, 0);
SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
- rcu_read_lock();
- sta = ieee80211_find_sta(mac->vif, mac->bssid);
if (sta) {
u8 ampdu_density = sta->ht_cap.ampdu_density;
SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
}
- rcu_read_unlock();
if (info->control.hw_key) {
struct ieee80211_key_conf *keyconf =
@@ -844,7 +822,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
SET_TX_DESC_DISABLE_FB(pdesc, 0);
- SET_TX_DESC_USE_RATE(pdesc, tcb_desc.use_driver_rate ? 1 : 0);
+ SET_TX_DESC_USE_RATE(pdesc, tcb_desc->use_driver_rate ? 1 : 0);
if (ieee80211_is_data_qos(fc)) {
if (mac->rdg_en) {
@@ -855,24 +833,24 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
}
}
}
+ rcu_read_unlock();
SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
- SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
if (rtlpriv->dm.useramask) {
- SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index);
- SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id);
+ SET_TX_DESC_RATE_ID(pdesc, tcb_desc->ratr_index);
+ SET_TX_DESC_MACID(pdesc, tcb_desc->mac_id);
} else {
- SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc.ratr_index);
- SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index);
+ SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc->ratr_index);
+ SET_TX_DESC_MACID(pdesc, tcb_desc->ratr_index);
}
- if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps &&
- ppsc->fwctrl_lps) {
+ if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
SET_TX_DESC_HWSEQ_EN(pdesc, 1);
SET_TX_DESC_PKT_ID(pdesc, 8);
@@ -923,7 +901,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
- SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
SET_TX_DESC_RATE_ID(pdesc, 7);
SET_TX_DESC_MACID(pdesc, 0);
@@ -1021,7 +999,7 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
return ret;
}
-void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue)
+void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (hw_queue == BEACON_QUEUE) {
@@ -1032,35 +1010,3 @@ void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue)
}
}
-bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
- struct sk_buff *skb)
-{
- struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
- struct rtl8192_tx_ring *ring;
- struct rtl_tx_desc *pdesc;
- u8 own;
- unsigned long flags;
- struct sk_buff *pskb = NULL;
-
- ring = &rtlpci->tx_ring[BEACON_QUEUE];
-
- spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
-
- pskb = __skb_dequeue(&ring->queue);
- if (pskb)
- kfree_skb(pskb);
-
- pdesc = &ring->desc[0];
- own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
-
- rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
-
- __skb_queue_tail(&ring->queue, skb);
-
- spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
-
- rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
-
- return true;
-}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
index 803adcc80c9..0f117713750 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
@@ -532,9 +532,9 @@
#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
do { \
if (_size > TX_DESC_NEXT_DESC_OFFSET) \
- memset((void *)__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
+ memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
else \
- memset((void *)__pdesc, 0, _size); \
+ memset(__pdesc, 0, _size); \
} while (0);
#define RX_HAL_IS_CCK_RATE(_pdesc)\
@@ -724,17 +724,16 @@ struct rx_desc_92c {
void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr,
u8 *pdesc, struct ieee80211_tx_info *info,
- struct sk_buff *skb, unsigned int qsel);
+ struct sk_buff *skb, u8 hw_queue,
+ struct rtl_tcb_desc *ptcb_desc);
bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
struct rtl_stats *stats,
struct ieee80211_rx_status *rx_status,
u8 *pdesc, struct sk_buff *skb);
void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val);
u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name);
-void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue);
+void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
bool b_firstseg, bool b_lastseg,
struct sk_buff *skb);
-bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb);
-
#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 9444e76838c..52e2af58c1e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -39,6 +39,7 @@
#include "mac.h"
#include "dm.h"
#include "hw.h"
+#include "../rtl8192ce/hw.h"
#include "trx.h"
#include "led.h"
#include "table.h"
@@ -605,10 +606,10 @@ void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw)
if (!IS_NORMAL_CHIP(rtlhal->version))
return;
tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
- rtlefuse->epromtype = (tmp_u1b & EEPROMSEL) ?
+ rtlefuse->epromtype = (tmp_u1b & BOOT_FROM_EEPROM) ?
EEPROM_93C46 : EEPROM_BOOT_EFUSE;
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from %s\n",
- (tmp_u1b & EEPROMSEL) ? "EERROM" : "EFUSE"));
+ (tmp_u1b & BOOT_FROM_EEPROM) ? "EERROM" : "EFUSE"));
rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true;
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload %s\n",
(tmp_u1b & EEPROM_EN) ? "OK!!" : "ERR!!"));
@@ -921,7 +922,7 @@ static void _rtl92cu_init_chipT_queue_priority(struct ieee80211_hw *hw,
u8 out_ep_num,
u8 queue_sel)
{
- u8 hq_sele;
+ u8 hq_sele = 0;
struct rtl_priv *rtlpriv = rtl_priv(hw);
switch (out_ep_num) {
@@ -977,7 +978,7 @@ static void _rtl92cu_init_wmac_setting(struct ieee80211_hw *hw)
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
- mac->rx_conf = (RCR_APM | RCR_AM | RCR_ADF | RCR_AB | RCR_APP_FCS |
+ mac->rx_conf = (RCR_APM | RCR_AM | RCR_ADF | RCR_AB | RCR_APPFCS |
RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL |
RCR_APP_MIC | RCR_APP_PHYSTS | RCR_ACRC32);
rtl_write_dword(rtlpriv, REG_RCR, mac->rx_conf);
@@ -2182,7 +2183,9 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
}
}
-void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw)
+void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ u8 rssi_level)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
index 62af555bb61..32f85cba106 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
@@ -98,13 +98,14 @@ void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw,
u32 add_msr, u32 rm_msr);
void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
-void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw);
+void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ u8 rssi_level);
void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level);
void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw);
bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid);
void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
-u8 _rtl92c_get_chnl_group(u8 chnl);
int rtl92c_download_fw(struct ieee80211_hw *hw);
void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
index 4e020e654e6..9a3d0239e27 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
@@ -38,7 +38,7 @@
#include "table.h"
u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
- enum radio_path rfpath, u32 regaddr, u32 bitmask)
+ enum radio_path rfpath, u32 regaddr, u32 bitmask)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 original_value, readback_value, bitshift;
@@ -64,8 +64,8 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
}
void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw,
- enum radio_path rfpath,
- u32 regaddr, u32 bitmask, u32 data)
+ enum radio_path rfpath,
+ u32 regaddr, u32 bitmask, u32 data)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -163,7 +163,7 @@ bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
}
bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
- u8 configtype)
+ u8 configtype)
{
int i;
u32 *phy_regarray_table;
@@ -223,7 +223,7 @@ bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
}
bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
- u8 configtype)
+ u8 configtype)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -459,7 +459,7 @@ void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
}
}
-bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
+static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -595,7 +595,7 @@ bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
}
bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
- enum rf_pwrstate rfpwr_state)
+ enum rf_pwrstate rfpwr_state)
{
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
bool bresult = false;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h
index 06299559ab6..ff81a61729d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h
@@ -34,3 +34,17 @@ bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath);
void rtl92c_phy_set_io(struct ieee80211_hw *hw);
bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw);
+u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 regaddr, u32 bitmask);
+void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw,
+ enum radio_path rfpath,
+ u32 regaddr, u32 bitmask, u32 data);
+bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw);
+bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
+ u8 configtype);
+void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t);
+bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
+ u8 configtype);
+void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
+bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
+ enum rf_pwrstate rfpwr_state);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
index 1c79c226f14..c7576ec4744 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
@@ -62,7 +62,7 @@ void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
}
void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
- u8 *ppowerlevel)
+ u8 *ppowerlevel)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -389,7 +389,7 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,
}
void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
- u8 *ppowerlevel, u8 channel)
+ u8 *ppowerlevel, u8 channel)
{
u32 writeVal[2], powerBase0[2], powerBase1[2];
u8 index = 0;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
index 86c2728cfa0..500a2094b6b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
@@ -43,5 +43,9 @@ extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
bool rtl92cu_phy_rf6052_config(struct ieee80211_hw *hw);
bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
+void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
+ u8 *ppowerlevel);
+void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
+ u8 *ppowerlevel, u8 channel);
#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index 71244a38d49..bee7c1480f6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -94,7 +94,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
.update_interrupt_mask = rtl92cu_update_interrupt_mask,
.get_hw_reg = rtl92cu_get_hw_reg,
.set_hw_reg = rtl92cu_set_hw_reg,
- .update_rate_table = rtl92cu_update_hal_rate_table,
+ .update_rate_tbl = rtl92cu_update_hal_rate_table,
.update_rate_mask = rtl92cu_update_hal_rate_mask,
.fill_tx_desc = rtl92cu_tx_fill_desc,
.fill_fake_txdesc = rtl92cu_fill_fake_txdesc,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index d0b0d43b9a6..3a92ba3c4a1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -372,7 +372,7 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
__le16 fc;
struct ieee80211_hdr *hdr;
- memset(rx_status, 0, sizeof(rx_status));
+ memset(rx_status, 0, sizeof(*rx_status));
rxdesc = skb->data;
skb_len = skb->len;
drvinfo_len = (GET_RX_DESC_DRVINFO_SIZE(rxdesc) * RTL_RX_DRV_INFO_UNIT);
@@ -434,7 +434,7 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
"0x%02X\n", fc, (u32)hdr->addr1[0], (u32)hdr->addr1[1],
(u32)hdr->addr1[2], (u32)hdr->addr1[3], (u32)hdr->addr1[4],
(u32)hdr->addr1[5]));
- memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+ memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
ieee80211_rx_irqsafe(hw, skb);
}
@@ -498,14 +498,14 @@ static void _rtl_tx_desc_checksum(u8 *txdesc)
void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc_tx,
struct ieee80211_tx_info *info, struct sk_buff *skb,
- unsigned int queue_index)
+ u8 queue_index,
+ struct rtl_tcb_desc *tcb_desc)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
bool defaultadapter = true;
- struct ieee80211_sta *sta;
- struct rtl_tcb_desc tcb_desc;
+ struct ieee80211_sta *sta = info->control.sta = info->control.sta;
u8 *qc = ieee80211_get_qos_ctl(hdr);
u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
u16 seq_number;
@@ -517,15 +517,15 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
u8 *txdesc;
seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
- rtl_get_tcb_desc(hw, info, skb, &tcb_desc);
+ rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
txdesc = (u8 *)skb_push(skb, RTL_TX_HEADER_SIZE);
memset(txdesc, 0, RTL_TX_HEADER_SIZE);
SET_TX_DESC_PKT_SIZE(txdesc, pktlen);
SET_TX_DESC_LINIP(txdesc, 0);
SET_TX_DESC_PKT_OFFSET(txdesc, RTL_DUMMY_OFFSET);
SET_TX_DESC_OFFSET(txdesc, RTL_TX_HEADER_SIZE);
- SET_TX_DESC_TX_RATE(txdesc, tcb_desc.hw_rate);
- if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble)
+ SET_TX_DESC_TX_RATE(txdesc, tcb_desc->hw_rate);
+ if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
SET_TX_DESC_DATA_SHORTGI(txdesc, 1);
if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&
info->flags & IEEE80211_TX_CTL_AMPDU) {
@@ -535,21 +535,21 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
SET_TX_DESC_AGG_BREAK(txdesc, 1);
}
SET_TX_DESC_SEQ(txdesc, seq_number);
- SET_TX_DESC_RTS_ENABLE(txdesc, ((tcb_desc.rts_enable &&
- !tcb_desc.cts_enable) ? 1 : 0));
- SET_TX_DESC_HW_RTS_ENABLE(txdesc, ((tcb_desc.rts_enable ||
- tcb_desc.cts_enable) ? 1 : 0));
- SET_TX_DESC_CTS2SELF(txdesc, ((tcb_desc.cts_enable) ? 1 : 0));
- SET_TX_DESC_RTS_STBC(txdesc, ((tcb_desc.rts_stbc) ? 1 : 0));
- SET_TX_DESC_RTS_RATE(txdesc, tcb_desc.rts_rate);
+ SET_TX_DESC_RTS_ENABLE(txdesc, ((tcb_desc->rts_enable &&
+ !tcb_desc->cts_enable) ? 1 : 0));
+ SET_TX_DESC_HW_RTS_ENABLE(txdesc, ((tcb_desc->rts_enable ||
+ tcb_desc->cts_enable) ? 1 : 0));
+ SET_TX_DESC_CTS2SELF(txdesc, ((tcb_desc->cts_enable) ? 1 : 0));
+ SET_TX_DESC_RTS_STBC(txdesc, ((tcb_desc->rts_stbc) ? 1 : 0));
+ SET_TX_DESC_RTS_RATE(txdesc, tcb_desc->rts_rate);
SET_TX_DESC_RTS_BW(txdesc, 0);
- SET_TX_DESC_RTS_SC(txdesc, tcb_desc.rts_sc);
+ SET_TX_DESC_RTS_SC(txdesc, tcb_desc->rts_sc);
SET_TX_DESC_RTS_SHORT(txdesc,
- ((tcb_desc.rts_rate <= DESC92C_RATE54M) ?
- (tcb_desc.rts_use_shortpreamble ? 1 : 0)
- : (tcb_desc.rts_use_shortgi ? 1 : 0)));
+ ((tcb_desc->rts_rate <= DESC92C_RATE54M) ?
+ (tcb_desc->rts_use_shortpreamble ? 1 : 0)
+ : (tcb_desc->rts_use_shortgi ? 1 : 0)));
if (mac->bw_40) {
- if (tcb_desc.packet_bw) {
+ if (tcb_desc->packet_bw) {
SET_TX_DESC_DATA_BW(txdesc, 1);
SET_TX_DESC_DATA_SC(txdesc, 3);
} else {
@@ -590,7 +590,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
SET_TX_DESC_DATA_RATE_FB_LIMIT(txdesc, 0x1F);
SET_TX_DESC_RTS_RATE_FB_LIMIT(txdesc, 0xF);
SET_TX_DESC_DISABLE_FB(txdesc, 0);
- SET_TX_DESC_USE_RATE(txdesc, tcb_desc.use_driver_rate ? 1 : 0);
+ SET_TX_DESC_USE_RATE(txdesc, tcb_desc->use_driver_rate ? 1 : 0);
if (ieee80211_is_data_qos(fc)) {
if (mac->rdg_en) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
@@ -600,11 +600,11 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
}
}
if (rtlpriv->dm.useramask) {
- SET_TX_DESC_RATE_ID(txdesc, tcb_desc.ratr_index);
- SET_TX_DESC_MACID(txdesc, tcb_desc.mac_id);
+ SET_TX_DESC_RATE_ID(txdesc, tcb_desc->ratr_index);
+ SET_TX_DESC_MACID(txdesc, tcb_desc->mac_id);
} else {
- SET_TX_DESC_RATE_ID(txdesc, 0xC + tcb_desc.ratr_index);
- SET_TX_DESC_MACID(txdesc, tcb_desc.ratr_index);
+ SET_TX_DESC_RATE_ID(txdesc, 0xC + tcb_desc->ratr_index);
+ SET_TX_DESC_MACID(txdesc, tcb_desc->ratr_index);
}
if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps &&
ppsc->fwctrl_lps) {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
index b396d46edbb..53de5f66e24 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
@@ -37,6 +37,8 @@
#define RTL92C_SIZE_MAX_RX_BUFFER 15360 /* 8192 */
#define RX_DRV_INFO_SIZE_UNIT 8
+#define RTL_AGG_ON 1
+
enum usb_rx_agg_mode {
USB_RX_AGG_DISABLE,
USB_RX_AGG_DMA,
@@ -419,7 +421,8 @@ struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *,
void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc_tx,
struct ieee80211_tx_info *info, struct sk_buff *skb,
- unsigned int queue_index);
+ u8 queue_index,
+ struct rtl_tcb_desc *tcb_desc);
void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc,
u32 buffer_len, bool bIsPsPoll);
void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/Makefile b/drivers/net/wireless/rtlwifi/rtl8192se/Makefile
new file mode 100644
index 00000000000..b7eb13819cb
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/Makefile
@@ -0,0 +1,15 @@
+rtl8192se-objs := \
+ dm.o \
+ fw.o \
+ hw.o \
+ led.o \
+ phy.o \
+ rf.o \
+ sw.o \
+ table.o \
+ trx.o
+
+obj-$(CONFIG_RTL8192SE) += rtl8192se.o
+
+ccflags-y += -D__CHECK_ENDIAN__
+
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
new file mode 100644
index 00000000000..69828f2b3fa
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
@@ -0,0 +1,598 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __REALTEK_92S_DEF_H__
+#define __REALTEK_92S_DEF_H__
+
+#define RX_MPDU_QUEUE 0
+#define RX_CMD_QUEUE 1
+#define RX_MAX_QUEUE 2
+
+#define DESC92S_RATE1M 0x00
+#define DESC92S_RATE2M 0x01
+#define DESC92S_RATE5_5M 0x02
+#define DESC92S_RATE11M 0x03
+#define DESC92S_RATE6M 0x04
+#define DESC92S_RATE9M 0x05
+#define DESC92S_RATE12M 0x06
+#define DESC92S_RATE18M 0x07
+#define DESC92S_RATE24M 0x08
+#define DESC92S_RATE36M 0x09
+#define DESC92S_RATE48M 0x0a
+#define DESC92S_RATE54M 0x0b
+#define DESC92S_RATEMCS0 0x0c
+#define DESC92S_RATEMCS1 0x0d
+#define DESC92S_RATEMCS2 0x0e
+#define DESC92S_RATEMCS3 0x0f
+#define DESC92S_RATEMCS4 0x10
+#define DESC92S_RATEMCS5 0x11
+#define DESC92S_RATEMCS6 0x12
+#define DESC92S_RATEMCS7 0x13
+#define DESC92S_RATEMCS8 0x14
+#define DESC92S_RATEMCS9 0x15
+#define DESC92S_RATEMCS10 0x16
+#define DESC92S_RATEMCS11 0x17
+#define DESC92S_RATEMCS12 0x18
+#define DESC92S_RATEMCS13 0x19
+#define DESC92S_RATEMCS14 0x1a
+#define DESC92S_RATEMCS15 0x1b
+#define DESC92S_RATEMCS15_SG 0x1c
+#define DESC92S_RATEMCS32 0x20
+
+#define SHORT_SLOT_TIME 9
+#define NON_SHORT_SLOT_TIME 20
+
+/* Rx smooth factor */
+#define RX_SMOOTH_FACTOR 20
+
+/* Queue Select Value in TxDesc */
+#define QSLT_BK 0x2
+#define QSLT_BE 0x0
+#define QSLT_VI 0x5
+#define QSLT_VO 0x6
+#define QSLT_BEACON 0x10
+#define QSLT_HIGH 0x11
+#define QSLT_MGNT 0x12
+#define QSLT_CMD 0x13
+
+#define PHY_RSSI_SLID_WIN_MAX 100
+#define PHY_LINKQUALITY_SLID_WIN_MAX 20
+#define PHY_BEACON_RSSI_SLID_WIN_MAX 10
+
+/* Tx Desc */
+#define TX_DESC_SIZE_RTL8192S (16 * 4)
+#define TX_CMDDESC_SIZE_RTL8192S (16 * 4)
+
+/* Define a macro that takes a le32 word, converts it to host ordering,
+ * right shifts by a specified count, creates a mask of the specified
+ * bit count, and extracts that number of bits.
+ */
+
+#define SHIFT_AND_MASK_LE(__pdesc, __shift, __mask) \
+ ((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \
+ BIT_LEN_MASK_32(__mask))
+
+/* Define a macro that clears a bit field in an le32 word and
+ * sets the specified value into that bit field. The resulting
+ * value remains in le32 ordering; however, it is properly converted
+ * to host ordering for the clear and set operations before conversion
+ * back to le32.
+ */
+
+#define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val) \
+ (*(__le32 *)(__pdesc) = \
+ (cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) & \
+ (~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) | \
+ (((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift)))));
+
+/* macros to read/write various fields in RX or TX descriptors */
+
+/* Dword 0 */
+#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 0, 16, __val)
+#define SET_TX_DESC_OFFSET(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 16, 8, __val)
+#define SET_TX_DESC_TYPE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 24, 2, __val)
+#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 26, 1, __val)
+#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 27, 1, __val)
+#define SET_TX_DESC_LINIP(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 28, 1, __val)
+#define SET_TX_DESC_AMSDU(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 29, 1, __val)
+#define SET_TX_DESC_GREEN_FIELD(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val)
+#define SET_TX_DESC_OWN(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val)
+
+#define GET_TX_DESC_OWN(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc, 31, 1)
+
+/* Dword 1 */
+#define SET_TX_DESC_MACID(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 0, 5, __val)
+#define SET_TX_DESC_MORE_DATA(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 5, 1, __val)
+#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 6, 1, __val)
+#define SET_TX_DESC_PIFS(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 7, 1, __val)
+#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 8, 5, __val)
+#define SET_TX_DESC_ACK_POLICY(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 13, 2, __val)
+#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 15, 1, __val)
+#define SET_TX_DESC_NON_QOS(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 16, 1, __val)
+#define SET_TX_DESC_KEY_ID(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 17, 2, __val)
+#define SET_TX_DESC_OUI(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 19, 1, __val)
+#define SET_TX_DESC_PKT_TYPE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 20, 1, __val)
+#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 21, 1, __val)
+#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 22, 2, __val)
+#define SET_TX_DESC_WDS(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 24, 1, __val)
+#define SET_TX_DESC_HTC(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 25, 1, __val)
+#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 26, 5, __val)
+#define SET_TX_DESC_HWPC(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 27, 1, __val)
+
+/* Dword 2 */
+#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 8, 0, 6, __val)
+#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 8, 6, 1, __val)
+#define SET_TX_DESC_TSFL(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 8, 7, 5, __val)
+#define SET_TX_DESC_RTS_RETRY_COUNT(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 8, 12, 6, __val)
+#define SET_TX_DESC_DATA_RETRY_COUNT(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 8, 18, 6, __val)
+#define SET_TX_DESC_RSVD_MACID(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(((__pdesc) + 8), 24, 5, __val)
+#define SET_TX_DESC_AGG_ENABLE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 8, 29, 1, __val)
+#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 8, 30, 1, __val)
+#define SET_TX_DESC_OWN_MAC(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 8, 31, 1, __val)
+
+/* Dword 3 */
+#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 0, 8, __val)
+#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 8, 8, __val)
+#define SET_TX_DESC_SEQ(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 16, 12, __val)
+#define SET_TX_DESC_FRAG(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 28, 4, __val)
+
+/* Dword 4 */
+#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 0, 6, __val)
+#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 6, 1, __val)
+#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 7, 4, __val)
+#define SET_TX_DESC_CTS_ENABLE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 11, 1, __val)
+#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 12, 1, __val)
+#define SET_TX_DESC_RA_BRSR_ID(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 13, 3, __val)
+#define SET_TX_DESC_TXHT(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 16, 1, __val)
+#define SET_TX_DESC_TX_SHORT(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 17, 1, __val)
+#define SET_TX_DESC_TX_BANDWIDTH(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 18, 1, __val)
+#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 19, 2, __val)
+#define SET_TX_DESC_TX_STBC(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 21, 2, __val)
+#define SET_TX_DESC_TX_REVERSE_DIRECTION(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 23, 1, __val)
+#define SET_TX_DESC_RTS_HT(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 24, 1, __val)
+#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 25, 1, __val)
+#define SET_TX_DESC_RTS_BANDWIDTH(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 26, 1, __val)
+#define SET_TX_DESC_RTS_SUB_CARRIER(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 27, 2, __val)
+#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 29, 2, __val)
+#define SET_TX_DESC_USER_RATE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 31, 1, __val)
+
+/* Dword 5 */
+#define SET_TX_DESC_PACKET_ID(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 20, 0, 9, __val)
+#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 20, 9, 6, __val)
+#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 20, 15, 1, __val)
+#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 20, 16, 5, __val)
+#define SET_TX_DESC_TX_AGC(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 20, 21, 11, __val)
+
+/* Dword 6 */
+#define SET_TX_DESC_IP_CHECK_SUM(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 24, 0, 16, __val)
+#define SET_TX_DESC_TCP_CHECK_SUM(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 24, 16, 16, __val)
+
+/* Dword 7 */
+#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 28, 0, 16, __val)
+#define SET_TX_DESC_IP_HEADER_OFFSET(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 28, 16, 8, __val)
+#define SET_TX_DESC_TCP_ENABLE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 28, 31, 1, __val)
+
+/* Dword 8 */
+#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 32, 0, 32, __val)
+#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 32, 0, 32)
+
+/* Dword 9 */
+#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 36, 0, 32, __val)
+
+/* Because the PCI Tx descriptors are chaied at the
+ * initialization and all the NextDescAddresses in
+ * these descriptors cannot not be cleared (,or
+ * driver/HW cannot find the next descriptor), the
+ * offset 36 (NextDescAddresses) is reserved when
+ * the desc is cleared. */
+#define TX_DESC_NEXT_DESC_OFFSET 36
+#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
+do { \
+ if (_size > TX_DESC_NEXT_DESC_OFFSET) \
+ memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
+ else \
+ memset(__pdesc, 0, _size); \
+} while (0);
+
+/* Rx Desc */
+#define RX_STATUS_DESC_SIZE 24
+#define RX_DRV_INFO_SIZE_UNIT 8
+
+/* DWORD 0 */
+#define SET_RX_STATUS_DESC_PKT_LEN(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 0, 14, __val)
+#define SET_RX_STATUS_DESC_CRC32(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 14, 1, __val)
+#define SET_RX_STATUS_DESC_ICV(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 15, 1, __val)
+#define SET_RX_STATUS_DESC_DRVINFO_SIZE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 16, 4, __val)
+#define SET_RX_STATUS_DESC_SECURITY(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 20, 3, __val)
+#define SET_RX_STATUS_DESC_QOS(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 23, 1, __val)
+#define SET_RX_STATUS_DESC_SHIFT(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 24, 2, __val)
+#define SET_RX_STATUS_DESC_PHY_STATUS(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 26, 1, __val)
+#define SET_RX_STATUS_DESC_SWDEC(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 27, 1, __val)
+#define SET_RX_STATUS_DESC_LAST_SEG(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 28, 1, __val)
+#define SET_RX_STATUS_DESC_FIRST_SEG(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 29, 1, __val)
+#define SET_RX_STATUS_DESC_EOR(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val)
+#define SET_RX_STATUS_DESC_OWN(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val)
+
+#define GET_RX_STATUS_DESC_PKT_LEN(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc, 0, 14)
+#define GET_RX_STATUS_DESC_CRC32(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc, 14, 1)
+#define GET_RX_STATUS_DESC_ICV(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc, 15, 1)
+#define GET_RX_STATUS_DESC_DRVINFO_SIZE(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc, 16, 4)
+#define GET_RX_STATUS_DESC_SECURITY(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc, 20, 3)
+#define GET_RX_STATUS_DESC_QOS(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc, 23, 1)
+#define GET_RX_STATUS_DESC_SHIFT(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc, 24, 2)
+#define GET_RX_STATUS_DESC_PHY_STATUS(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc, 26, 1)
+#define GET_RX_STATUS_DESC_SWDEC(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc, 27, 1)
+#define GET_RX_STATUS_DESC_LAST_SEG(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc, 28, 1)
+#define GET_RX_STATUS_DESC_FIRST_SEG(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc, 29, 1)
+#define GET_RX_STATUS_DESC_EOR(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc, 30, 1)
+#define GET_RX_STATUS_DESC_OWN(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc, 31, 1)
+
+/* DWORD 1 */
+#define SET_RX_STATUS_DESC_MACID(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 0, 5, __val)
+#define SET_RX_STATUS_DESC_TID(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 5, 4, __val)
+#define SET_RX_STATUS_DESC_PAGGR(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 14, 1, __val)
+#define SET_RX_STATUS_DESC_FAGGR(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 15, 1, __val)
+#define SET_RX_STATUS_DESC_A1_FIT(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 16, 4, __val)
+#define SET_RX_STATUS_DESC_A2_FIT(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 20, 4, __val)
+#define SET_RX_STATUS_DESC_PAM(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 24, 1, __val)
+#define SET_RX_STATUS_DESC_PWR(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 25, 1, __val)
+#define SET_RX_STATUS_DESC_MOREDATA(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 26, 1, __val)
+#define SET_RX_STATUS_DESC_MOREFRAG(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 27, 1, __val)
+#define SET_RX_STATUS_DESC_TYPE(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 28, 2, __val)
+#define SET_RX_STATUS_DESC_MC(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 30, 1, __val)
+#define SET_RX_STATUS_DESC_BC(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 4, 31, 1, __val)
+
+#define GET_RX_STATUS_DEC_MACID(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 4, 0, 5)
+#define GET_RX_STATUS_DESC_TID(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 4, 5, 4)
+#define GET_RX_STATUS_DESC_PAGGR(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 4, 14, 1)
+#define GET_RX_STATUS_DESC_FAGGR(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 4, 15, 1)
+#define GET_RX_STATUS_DESC_A1_FIT(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 4, 16, 4)
+#define GET_RX_STATUS_DESC_A2_FIT(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 4, 20, 4)
+#define GET_RX_STATUS_DESC_PAM(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 4, 24, 1)
+#define GET_RX_STATUS_DESC_PWR(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 4, 25, 1)
+#define GET_RX_STATUS_DESC_MORE_DATA(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 4, 26, 1)
+#define GET_RX_STATUS_DESC_MORE_FRAG(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 4, 27, 1)
+#define GET_RX_STATUS_DESC_TYPE(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 4, 28, 2)
+#define GET_RX_STATUS_DESC_MC(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 4, 30, 1)
+#define GET_RX_STATUS_DESC_BC(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 4, 31, 1)
+
+/* DWORD 2 */
+#define SET_RX_STATUS_DESC_SEQ(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 8, 0, 12, __val)
+#define SET_RX_STATUS_DESC_FRAG(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 8, 12, 4, __val)
+#define SET_RX_STATUS_DESC_NEXT_PKTLEN(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 8, 16, 8, __val)
+#define SET_RX_STATUS_DESC_NEXT_IND(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 8, 30, 1, __val)
+
+#define GET_RX_STATUS_DESC_SEQ(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 8, 0, 12)
+#define GET_RX_STATUS_DESC_FRAG(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 8, 12, 4)
+#define GET_RX_STATUS_DESC_NEXT_PKTLEN(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 8, 16, 8)
+#define GET_RX_STATUS_DESC_NEXT_IND(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 8, 30, 1)
+
+/* DWORD 3 */
+#define SET_RX_STATUS_DESC_RX_MCS(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 0, 6, __val)
+#define SET_RX_STATUS_DESC_RX_HT(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 6, 1, __val)
+#define SET_RX_STATUS_DESC_AMSDU(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 7, 1, __val)
+#define SET_RX_STATUS_DESC_SPLCP(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 8, 1, __val)
+#define SET_RX_STATUS_DESC_BW(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 9, 1, __val)
+#define SET_RX_STATUS_DESC_HTC(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 10, 1, __val)
+#define SET_RX_STATUS_DESC_TCP_CHK_RPT(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 11, 1, __val)
+#define SET_RX_STATUS_DESC_IP_CHK_RPT(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 12, 1, __val)
+#define SET_RX_STATUS_DESC_TCP_CHK_VALID(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 13, 1, __val)
+#define SET_RX_STATUS_DESC_HWPC_ERR(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 14, 1, __val)
+#define SET_RX_STATUS_DESC_HWPC_IND(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 15, 1, __val)
+#define SET_RX_STATUS_DESC_IV0(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 12, 16, 16, __val)
+
+#define GET_RX_STATUS_DESC_RX_MCS(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 12, 0, 6)
+#define GET_RX_STATUS_DESC_RX_HT(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 12, 6, 1)
+#define GET_RX_STATUS_DESC_AMSDU(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 12, 7, 1)
+#define GET_RX_STATUS_DESC_SPLCP(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 12, 8, 1)
+#define GET_RX_STATUS_DESC_BW(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 12, 9, 1)
+#define GET_RX_STATUS_DESC_HTC(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 12, 10, 1)
+#define GET_RX_STATUS_DESC_TCP_CHK_RPT(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 12, 11, 1)
+#define GET_RX_STATUS_DESC_IP_CHK_RPT(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 12, 12, 1)
+#define GET_RX_STATUS_DESC_TCP_CHK_VALID(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 12, 13, 1)
+#define GET_RX_STATUS_DESC_HWPC_ERR(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 12, 14, 1)
+#define GET_RX_STATUS_DESC_HWPC_IND(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 12, 15, 1)
+#define GET_RX_STATUS_DESC_IV0(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 12, 16, 16)
+
+/* DWORD 4 */
+#define SET_RX_STATUS_DESC_IV1(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 16, 0, 32, __val)
+#define GET_RX_STATUS_DESC_IV1(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 16, 0, 32)
+
+/* DWORD 5 */
+#define SET_RX_STATUS_DESC_TSFL(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 20, 0, 32, __val)
+#define GET_RX_STATUS_DESC_TSFL(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 20, 0, 32)
+
+/* DWORD 6 */
+#define SET_RX_STATUS__DESC_BUFF_ADDR(__pdesc, __val) \
+ SET_BITS_OFFSET_LE(__pdesc + 24, 0, 32, __val)
+
+#define RX_HAL_IS_CCK_RATE(_pdesc)\
+ (GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE1M || \
+ GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE2M || \
+ GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE5_5M ||\
+ GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE11M)
+
+enum rf_optype {
+ RF_OP_BY_SW_3WIRE = 0,
+ RF_OP_BY_FW,
+ RF_OP_MAX
+};
+
+enum ic_inferiority {
+ IC_INFERIORITY_A = 0,
+ IC_INFERIORITY_B = 1,
+};
+
+enum fwcmd_iotype {
+ /* For DIG DM */
+ FW_CMD_DIG_ENABLE = 0,
+ FW_CMD_DIG_DISABLE = 1,
+ FW_CMD_DIG_HALT = 2,
+ FW_CMD_DIG_RESUME = 3,
+ /* For High Power DM */
+ FW_CMD_HIGH_PWR_ENABLE = 4,
+ FW_CMD_HIGH_PWR_DISABLE = 5,
+ /* For Rate adaptive DM */
+ FW_CMD_RA_RESET = 6,
+ FW_CMD_RA_ACTIVE = 7,
+ FW_CMD_RA_REFRESH_N = 8,
+ FW_CMD_RA_REFRESH_BG = 9,
+ FW_CMD_RA_INIT = 10,
+ /* For FW supported IQK */
+ FW_CMD_IQK_INIT = 11,
+ /* Tx power tracking switch,
+ * MP driver only */
+ FW_CMD_TXPWR_TRACK_ENABLE = 12,
+ /* Tx power tracking switch,
+ * MP driver only */
+ FW_CMD_TXPWR_TRACK_DISABLE = 13,
+ /* Tx power tracking with thermal
+ * indication, for Normal driver */
+ FW_CMD_TXPWR_TRACK_THERMAL = 14,
+ FW_CMD_PAUSE_DM_BY_SCAN = 15,
+ FW_CMD_RESUME_DM_BY_SCAN = 16,
+ FW_CMD_RA_REFRESH_N_COMB = 17,
+ FW_CMD_RA_REFRESH_BG_COMB = 18,
+ FW_CMD_ANTENNA_SW_ENABLE = 19,
+ FW_CMD_ANTENNA_SW_DISABLE = 20,
+ /* Tx Status report for CCX from FW */
+ FW_CMD_TX_FEEDBACK_CCX_ENABLE = 21,
+ /* Indifate firmware that driver
+ * enters LPS, For PS-Poll issue */
+ FW_CMD_LPS_ENTER = 22,
+ /* Indicate firmware that driver
+ * leave LPS*/
+ FW_CMD_LPS_LEAVE = 23,
+ /* Set DIG mode to signal strength */
+ FW_CMD_DIG_MODE_SS = 24,
+ /* Set DIG mode to false alarm. */
+ FW_CMD_DIG_MODE_FA = 25,
+ FW_CMD_ADD_A2_ENTRY = 26,
+ FW_CMD_CTRL_DM_BY_DRIVER = 27,
+ FW_CMD_CTRL_DM_BY_DRIVER_NEW = 28,
+ FW_CMD_PAPE_CONTROL = 29,
+ FW_CMD_IQK_ENABLE = 30,
+};
+
+/*
+ * Driver info contain PHY status
+ * and other variabel size info
+ * PHY Status content as below
+ */
+struct rx_fwinfo {
+ /* DWORD 0 */
+ u8 gain_trsw[4];
+ /* DWORD 1 */
+ u8 pwdb_all;
+ u8 cfosho[4];
+ /* DWORD 2 */
+ u8 cfotail[4];
+ /* DWORD 3 */
+ s8 rxevm[2];
+ s8 rxsnr[4];
+ /* DWORD 4 */
+ u8 pdsnr[2];
+ /* DWORD 5 */
+ u8 csi_current[2];
+ u8 csi_target[2];
+ /* DWORD 6 */
+ u8 sigevm;
+ u8 max_ex_pwr;
+ u8 ex_intf_flag:1;
+ u8 sgi_en:1;
+ u8 rxsc:2;
+ u8 reserve:4;
+};
+
+struct phy_sts_cck_8192s_t {
+ u8 adc_pwdb_x[4];
+ u8 sq_rpt;
+ u8 cck_agc_rpt;
+};
+
+#endif
+
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
new file mode 100644
index 00000000000..da86db86fa4
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
@@ -0,0 +1,733 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "fw.h"
+
+struct dig_t digtable;
+static const u32 edca_setting_dl[PEER_MAX] = {
+ 0xa44f, /* 0 UNKNOWN */
+ 0x5ea44f, /* 1 REALTEK_90 */
+ 0x5ea44f, /* 2 REALTEK_92SE */
+ 0xa630, /* 3 BROAD */
+ 0xa44f, /* 4 RAL */
+ 0xa630, /* 5 ATH */
+ 0xa630, /* 6 CISCO */
+ 0xa42b, /* 7 MARV */
+};
+
+static const u32 edca_setting_dl_gmode[PEER_MAX] = {
+ 0x4322, /* 0 UNKNOWN */
+ 0xa44f, /* 1 REALTEK_90 */
+ 0x5ea44f, /* 2 REALTEK_92SE */
+ 0xa42b, /* 3 BROAD */
+ 0x5e4322, /* 4 RAL */
+ 0x4322, /* 5 ATH */
+ 0xa430, /* 6 CISCO */
+ 0x5ea44f, /* 7 MARV */
+};
+
+static const u32 edca_setting_ul[PEER_MAX] = {
+ 0x5e4322, /* 0 UNKNOWN */
+ 0xa44f, /* 1 REALTEK_90 */
+ 0x5ea44f, /* 2 REALTEK_92SE */
+ 0x5ea322, /* 3 BROAD */
+ 0x5ea422, /* 4 RAL */
+ 0x5ea322, /* 5 ATH */
+ 0x3ea44f, /* 6 CISCO */
+ 0x5ea44f, /* 7 MARV */
+};
+
+static void _rtl92s_dm_check_edca_turbo(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ static u64 last_txok_cnt;
+ static u64 last_rxok_cnt;
+ u64 cur_txok_cnt = 0;
+ u64 cur_rxok_cnt = 0;
+
+ u32 edca_be_ul = edca_setting_ul[mac->vendor];
+ u32 edca_be_dl = edca_setting_dl[mac->vendor];
+ u32 edca_gmode = edca_setting_dl_gmode[mac->vendor];
+
+ if (mac->link_state != MAC80211_LINKED) {
+ rtlpriv->dm.current_turbo_edca = false;
+ goto dm_checkedcaturbo_exit;
+ }
+
+ if ((!rtlpriv->dm.is_any_nonbepkts) &&
+ (!rtlpriv->dm.disable_framebursting)) {
+ cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
+ cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
+
+ if (rtlpriv->phy.rf_type == RF_1T2R) {
+ if (cur_txok_cnt > 4 * cur_rxok_cnt) {
+ /* Uplink TP is present. */
+ if (rtlpriv->dm.is_cur_rdlstate ||
+ !rtlpriv->dm.current_turbo_edca) {
+ rtl_write_dword(rtlpriv, EDCAPARA_BE,
+ edca_be_ul);
+ rtlpriv->dm.is_cur_rdlstate = false;
+ }
+ } else {/* Balance TP is present. */
+ if (!rtlpriv->dm.is_cur_rdlstate ||
+ !rtlpriv->dm.current_turbo_edca) {
+ if (mac->mode == WIRELESS_MODE_G ||
+ mac->mode == WIRELESS_MODE_B)
+ rtl_write_dword(rtlpriv,
+ EDCAPARA_BE,
+ edca_gmode);
+ else
+ rtl_write_dword(rtlpriv,
+ EDCAPARA_BE,
+ edca_be_dl);
+ rtlpriv->dm.is_cur_rdlstate = true;
+ }
+ }
+ rtlpriv->dm.current_turbo_edca = true;
+ } else {
+ if (cur_rxok_cnt > 4 * cur_txok_cnt) {
+ if (!rtlpriv->dm.is_cur_rdlstate ||
+ !rtlpriv->dm.current_turbo_edca) {
+ if (mac->mode == WIRELESS_MODE_G ||
+ mac->mode == WIRELESS_MODE_B)
+ rtl_write_dword(rtlpriv,
+ EDCAPARA_BE,
+ edca_gmode);
+ else
+ rtl_write_dword(rtlpriv,
+ EDCAPARA_BE,
+ edca_be_dl);
+ rtlpriv->dm.is_cur_rdlstate = true;
+ }
+ } else {
+ if (rtlpriv->dm.is_cur_rdlstate ||
+ !rtlpriv->dm.current_turbo_edca) {
+ rtl_write_dword(rtlpriv, EDCAPARA_BE,
+ edca_be_ul);
+ rtlpriv->dm.is_cur_rdlstate = false;
+ }
+ }
+ rtlpriv->dm.current_turbo_edca = true;
+ }
+ } else {
+ if (rtlpriv->dm.current_turbo_edca) {
+ u8 tmp = AC0_BE;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
+ (u8 *)(&tmp));
+ rtlpriv->dm.current_turbo_edca = false;
+ }
+ }
+
+dm_checkedcaturbo_exit:
+ rtlpriv->dm.is_any_nonbepkts = false;
+ last_txok_cnt = rtlpriv->stats.txbytesunicast;
+ last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
+}
+
+static void _rtl92s_dm_txpowertracking_callback_thermalmeter(
+ struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 thermalvalue = 0;
+
+ rtlpriv->dm.txpower_trackinginit = true;
+
+ thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
+
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+ ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
+ "eeprom_thermalmeter 0x%x\n", thermalvalue,
+ rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter));
+
+ if (thermalvalue) {
+ rtlpriv->dm.thermalvalue = thermalvalue;
+ rtl92s_phy_set_fw_cmd(hw, FW_CMD_TXPWR_TRACK_THERMAL);
+ }
+
+ rtlpriv->dm.txpowercount = 0;
+}
+
+static void _rtl92s_dm_check_txpowertracking_thermalmeter(
+ struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ static u8 tm_trigger;
+ u8 tx_power_checkcnt = 5;
+
+ /* 2T2R TP issue */
+ if (rtlphy->rf_type == RF_2T2R)
+ return;
+
+ if (!rtlpriv->dm.txpower_tracking)
+ return;
+
+ if (rtlpriv->dm.txpowercount <= tx_power_checkcnt) {
+ rtlpriv->dm.txpowercount++;
+ return;
+ }
+
+ if (!tm_trigger) {
+ rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER,
+ RFREG_OFFSET_MASK, 0x60);
+ tm_trigger = 1;
+ } else {
+ _rtl92s_dm_txpowertracking_callback_thermalmeter(hw);
+ tm_trigger = 0;
+ }
+}
+
+static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rate_adaptive *ra = &(rtlpriv->ra);
+
+ u32 low_rssi_thresh = 0;
+ u32 middle_rssi_thresh = 0;
+ u32 high_rssi_thresh = 0;
+ u8 rssi_level;
+ struct ieee80211_sta *sta = NULL;
+
+ if (is_hal_stop(rtlhal))
+ return;
+
+ if (!rtlpriv->dm.useramask)
+ return;
+
+ if (!rtlpriv->dm.inform_fw_driverctrldm) {
+ rtl92s_phy_set_fw_cmd(hw, FW_CMD_CTRL_DM_BY_DRIVER);
+ rtlpriv->dm.inform_fw_driverctrldm = true;
+ }
+
+ rcu_read_lock();
+ if (mac->opmode == NL80211_IFTYPE_STATION)
+ sta = get_sta(hw, mac->vif, mac->bssid);
+ if ((mac->link_state == MAC80211_LINKED) &&
+ (mac->opmode == NL80211_IFTYPE_STATION)) {
+ switch (ra->pre_ratr_state) {
+ case DM_RATR_STA_HIGH:
+ high_rssi_thresh = 40;
+ middle_rssi_thresh = 30;
+ low_rssi_thresh = 20;
+ break;
+ case DM_RATR_STA_MIDDLE:
+ high_rssi_thresh = 44;
+ middle_rssi_thresh = 30;
+ low_rssi_thresh = 20;
+ break;
+ case DM_RATR_STA_LOW:
+ high_rssi_thresh = 44;
+ middle_rssi_thresh = 34;
+ low_rssi_thresh = 20;
+ break;
+ case DM_RATR_STA_ULTRALOW:
+ high_rssi_thresh = 44;
+ middle_rssi_thresh = 34;
+ low_rssi_thresh = 24;
+ break;
+ default:
+ high_rssi_thresh = 44;
+ middle_rssi_thresh = 34;
+ low_rssi_thresh = 24;
+ break;
+ }
+
+ if (rtlpriv->dm.undecorated_smoothed_pwdb >
+ (long)high_rssi_thresh) {
+ ra->ratr_state = DM_RATR_STA_HIGH;
+ rssi_level = 1;
+ } else if (rtlpriv->dm.undecorated_smoothed_pwdb >
+ (long)middle_rssi_thresh) {
+ ra->ratr_state = DM_RATR_STA_LOW;
+ rssi_level = 3;
+ } else if (rtlpriv->dm.undecorated_smoothed_pwdb >
+ (long)low_rssi_thresh) {
+ ra->ratr_state = DM_RATR_STA_LOW;
+ rssi_level = 5;
+ } else {
+ ra->ratr_state = DM_RATR_STA_ULTRALOW;
+ rssi_level = 6;
+ }
+
+ if (ra->pre_ratr_state != ra->ratr_state) {
+ RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, ("RSSI = %ld "
+ "RSSI_LEVEL = %d PreState = %d, CurState = %d\n",
+ rtlpriv->dm.undecorated_smoothed_pwdb,
+ ra->ratr_state,
+ ra->pre_ratr_state, ra->ratr_state));
+
+ rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
+ ra->ratr_state);
+ ra->pre_ratr_state = ra->ratr_state;
+ }
+ }
+ rcu_read_unlock();
+}
+
+static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ bool current_mrc;
+ bool enable_mrc = true;
+ long tmpentry_maxpwdb = 0;
+ u8 rssi_a = 0;
+ u8 rssi_b = 0;
+
+ if (is_hal_stop(rtlhal))
+ return;
+
+ if ((rtlphy->rf_type == RF_1T1R) || (rtlphy->rf_type == RF_2T2R))
+ return;
+
+ rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MRC, (u8 *)(&current_mrc));
+
+ if (mac->link_state >= MAC80211_LINKED) {
+ if (rtlpriv->dm.undecorated_smoothed_pwdb > tmpentry_maxpwdb) {
+ rssi_a = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_A];
+ rssi_b = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_B];
+ }
+ }
+
+ /* MRC settings would NOT affect TP on Wireless B mode. */
+ if (mac->mode != WIRELESS_MODE_B) {
+ if ((rssi_a == 0) && (rssi_b == 0)) {
+ enable_mrc = true;
+ } else if (rssi_b > 30) {
+ /* Turn on B-Path */
+ enable_mrc = true;
+ } else if (rssi_b < 5) {
+ /* Turn off B-path */
+ enable_mrc = false;
+ /* Take care of RSSI differentiation. */
+ } else if (rssi_a > 15 && (rssi_a >= rssi_b)) {
+ if ((rssi_a - rssi_b) > 15)
+ /* Turn off B-path */
+ enable_mrc = false;
+ else if ((rssi_a - rssi_b) < 10)
+ /* Turn on B-Path */
+ enable_mrc = true;
+ else
+ enable_mrc = current_mrc;
+ } else {
+ /* Turn on B-Path */
+ enable_mrc = true;
+ }
+ }
+
+ /* Update MRC settings if needed. */
+ if (enable_mrc != current_mrc)
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC,
+ (u8 *)&enable_mrc);
+
+}
+
+void rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->dm.current_turbo_edca = false;
+ rtlpriv->dm.is_any_nonbepkts = false;
+ rtlpriv->dm.is_cur_rdlstate = false;
+}
+
+static void _rtl92s_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rate_adaptive *ra = &(rtlpriv->ra);
+
+ ra->ratr_state = DM_RATR_STA_MAX;
+ ra->pre_ratr_state = DM_RATR_STA_MAX;
+
+ if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
+ rtlpriv->dm.useramask = true;
+ else
+ rtlpriv->dm.useramask = false;
+
+ rtlpriv->dm.useramask = false;
+ rtlpriv->dm.inform_fw_driverctrldm = false;
+}
+
+static void _rtl92s_dm_init_txpowertracking_thermalmeter(
+ struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->dm.txpower_tracking = true;
+ rtlpriv->dm.txpowercount = 0;
+ rtlpriv->dm.txpower_trackinginit = false;
+}
+
+static void _rtl92s_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
+ u32 ret_value;
+
+ ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
+ falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
+
+ ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
+ falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
+ falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
+ ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
+ falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
+
+ falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
+ falsealm_cnt->cnt_rate_illegal + falsealm_cnt->cnt_crc8_fail +
+ falsealm_cnt->cnt_mcs_fail;
+
+ /* read CCK false alarm */
+ ret_value = rtl_get_bbreg(hw, 0xc64, MASKDWORD);
+ falsealm_cnt->cnt_cck_fail = (ret_value & 0xffff);
+ falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail +
+ falsealm_cnt->cnt_cck_fail;
+}
+
+static void rtl92s_backoff_enable_flag(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
+
+ if (falsealm_cnt->cnt_all > digtable.fa_highthresh) {
+ if ((digtable.backoff_val - 6) <
+ digtable.backoffval_range_min)
+ digtable.backoff_val = digtable.backoffval_range_min;
+ else
+ digtable.backoff_val -= 6;
+ } else if (falsealm_cnt->cnt_all < digtable.fa_lowthresh) {
+ if ((digtable.backoff_val + 6) >
+ digtable.backoffval_range_max)
+ digtable.backoff_val =
+ digtable.backoffval_range_max;
+ else
+ digtable.backoff_val += 6;
+ }
+}
+
+static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
+ static u8 initialized, force_write;
+ u8 initial_gain = 0;
+
+ if ((digtable.pre_sta_connectstate == digtable.cur_sta_connectstate) ||
+ (digtable.cur_sta_connectstate == DIG_STA_BEFORE_CONNECT)) {
+ if (digtable.cur_sta_connectstate == DIG_STA_BEFORE_CONNECT) {
+ if (rtlpriv->psc.rfpwr_state != ERFON)
+ return;
+
+ if (digtable.backoff_enable_flag == true)
+ rtl92s_backoff_enable_flag(hw);
+ else
+ digtable.backoff_val = DM_DIG_BACKOFF;
+
+ if ((digtable.rssi_val + 10 - digtable.backoff_val) >
+ digtable.rx_gain_range_max)
+ digtable.cur_igvalue =
+ digtable.rx_gain_range_max;
+ else if ((digtable.rssi_val + 10 - digtable.backoff_val)
+ < digtable.rx_gain_range_min)
+ digtable.cur_igvalue =
+ digtable.rx_gain_range_min;
+ else
+ digtable.cur_igvalue = digtable.rssi_val + 10 -
+ digtable.backoff_val;
+
+ if (falsealm_cnt->cnt_all > 10000)
+ digtable.cur_igvalue =
+ (digtable.cur_igvalue > 0x33) ?
+ digtable.cur_igvalue : 0x33;
+
+ if (falsealm_cnt->cnt_all > 16000)
+ digtable.cur_igvalue =
+ digtable.rx_gain_range_max;
+ /* connected -> connected or disconnected -> disconnected */
+ } else {
+ /* Firmware control DIG, do nothing in driver dm */
+ return;
+ }
+ /* disconnected -> connected or connected ->
+ * disconnected or beforeconnect->(dis)connected */
+ } else {
+ /* Enable FW DIG */
+ digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
+ rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_ENABLE);
+
+ digtable.backoff_val = DM_DIG_BACKOFF;
+ digtable.cur_igvalue = rtlpriv->phy.default_initialgain[0];
+ digtable.pre_igvalue = 0;
+ return;
+ }
+
+ /* Forced writing to prevent from fw-dig overwriting. */
+ if (digtable.pre_igvalue != rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1,
+ MASKBYTE0))
+ force_write = 1;
+
+ if ((digtable.pre_igvalue != digtable.cur_igvalue) ||
+ !initialized || force_write) {
+ /* Disable FW DIG */
+ rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_DISABLE);
+
+ initial_gain = (u8)digtable.cur_igvalue;
+
+ /* Set initial gain. */
+ rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, initial_gain);
+ rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, initial_gain);
+ digtable.pre_igvalue = digtable.cur_igvalue;
+ initialized = 1;
+ force_write = 0;
+ }
+}
+
+static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (rtlpriv->mac80211.act_scanning)
+ return;
+
+ /* Decide the current status and if modify initial gain or not */
+ if (rtlpriv->mac80211.link_state >= MAC80211_LINKED ||
+ rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
+ digtable.cur_sta_connectstate = DIG_STA_CONNECT;
+ else
+ digtable.cur_sta_connectstate = DIG_STA_DISCONNECT;
+
+ digtable.rssi_val = rtlpriv->dm.undecorated_smoothed_pwdb;
+
+ /* Change dig mode to rssi */
+ if (digtable.cur_sta_connectstate != DIG_STA_DISCONNECT) {
+ if (digtable.dig_twoport_algorithm ==
+ DIG_TWO_PORT_ALGO_FALSE_ALARM) {
+ digtable.dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
+ rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_MODE_SS);
+ }
+ }
+
+ _rtl92s_dm_false_alarm_counter_statistics(hw);
+ _rtl92s_dm_initial_gain_sta_beforeconnect(hw);
+
+ digtable.pre_sta_connectstate = digtable.cur_sta_connectstate;
+}
+
+static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ /* 2T2R TP issue */
+ if (rtlphy->rf_type == RF_2T2R)
+ return;
+
+ if (!rtlpriv->dm.dm_initialgain_enable)
+ return;
+
+ if (digtable.dig_enable_flag == false)
+ return;
+
+ _rtl92s_dm_ctrl_initgain_bytwoport(hw);
+}
+
+static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ long undecorated_smoothed_pwdb;
+ long txpwr_threshold_lv1, txpwr_threshold_lv2;
+
+ /* 2T2R TP issue */
+ if (rtlphy->rf_type == RF_2T2R)
+ return;
+
+ if (!rtlpriv->dm.dynamic_txpower_enable ||
+ rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
+ rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
+ return;
+ }
+
+ if ((mac->link_state < MAC80211_LINKED) &&
+ (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
+ ("Not connected to any\n"));
+
+ rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
+
+ rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
+ return;
+ }
+
+ if (mac->link_state >= MAC80211_LINKED) {
+ if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+ undecorated_smoothed_pwdb =
+ rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("AP Client PWDB = 0x%lx\n",
+ undecorated_smoothed_pwdb));
+ } else {
+ undecorated_smoothed_pwdb =
+ rtlpriv->dm.undecorated_smoothed_pwdb;
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("STA Default Port PWDB = 0x%lx\n",
+ undecorated_smoothed_pwdb));
+ }
+ } else {
+ undecorated_smoothed_pwdb =
+ rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("AP Ext Port PWDB = 0x%lx\n",
+ undecorated_smoothed_pwdb));
+ }
+
+ txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2;
+ txpwr_threshold_lv1 = TX_POWER_NEAR_FIELD_THRESH_LVL1;
+
+ if (rtl_get_bbreg(hw, 0xc90, MASKBYTE0) == 1)
+ rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
+ else if (undecorated_smoothed_pwdb >= txpwr_threshold_lv2)
+ rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL2;
+ else if ((undecorated_smoothed_pwdb < (txpwr_threshold_lv2 - 3)) &&
+ (undecorated_smoothed_pwdb >= txpwr_threshold_lv1))
+ rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL1;
+ else if (undecorated_smoothed_pwdb < (txpwr_threshold_lv1 - 3))
+ rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
+
+ if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl))
+ rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
+
+ rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
+}
+
+static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ /* Disable DIG scheme now.*/
+ digtable.dig_enable_flag = true;
+ digtable.backoff_enable_flag = true;
+
+ if ((rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) &&
+ (hal_get_firmwareversion(rtlpriv) >= 0x3c))
+ digtable.dig_algorithm = DIG_ALGO_BY_TOW_PORT;
+ else
+ digtable.dig_algorithm =
+ DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM;
+
+ digtable.dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
+ digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
+ /* off=by real rssi value, on=by digtable.rssi_val for new dig */
+ digtable.dig_dbgmode = DM_DBG_OFF;
+ digtable.dig_slgorithm_switch = 0;
+
+ /* 2007/10/04 MH Define init gain threshol. */
+ digtable.dig_state = DM_STA_DIG_MAX;
+ digtable.dig_highpwrstate = DM_STA_DIG_MAX;
+
+ digtable.cur_sta_connectstate = DIG_STA_DISCONNECT;
+ digtable.pre_sta_connectstate = DIG_STA_DISCONNECT;
+ digtable.cur_ap_connectstate = DIG_AP_DISCONNECT;
+ digtable.pre_ap_connectstate = DIG_AP_DISCONNECT;
+
+ digtable.rssi_lowthresh = DM_DIG_THRESH_LOW;
+ digtable.rssi_highthresh = DM_DIG_THRESH_HIGH;
+
+ digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
+ digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
+
+ digtable.rssi_highpower_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
+ digtable.rssi_highpower_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
+
+ /* for dig debug rssi value */
+ digtable.rssi_val = 50;
+ digtable.backoff_val = DM_DIG_BACKOFF;
+ digtable.rx_gain_range_max = DM_DIG_MAX;
+
+ digtable.rx_gain_range_min = DM_DIG_MIN;
+
+ digtable.backoffval_range_max = DM_DIG_BACKOFF_MAX;
+ digtable.backoffval_range_min = DM_DIG_BACKOFF_MIN;
+}
+
+static void _rtl92s_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if ((hal_get_firmwareversion(rtlpriv) >= 60) &&
+ (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER))
+ rtlpriv->dm.dynamic_txpower_enable = true;
+ else
+ rtlpriv->dm.dynamic_txpower_enable = false;
+
+ rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
+ rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
+}
+
+void rtl92s_dm_init(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
+ rtlpriv->dm.undecorated_smoothed_pwdb = -1;
+
+ _rtl92s_dm_init_dynamic_txpower(hw);
+ rtl92s_dm_init_edca_turbo(hw);
+ _rtl92s_dm_init_rate_adaptive_mask(hw);
+ _rtl92s_dm_init_txpowertracking_thermalmeter(hw);
+ _rtl92s_dm_init_dig(hw);
+
+ rtl_write_dword(rtlpriv, WFM5, FW_CCA_CHK_ENABLE);
+}
+
+void rtl92s_dm_watchdog(struct ieee80211_hw *hw)
+{
+ _rtl92s_dm_check_edca_turbo(hw);
+ _rtl92s_dm_check_txpowertracking_thermalmeter(hw);
+ _rtl92s_dm_ctrl_initgain_byrssi(hw);
+ _rtl92s_dm_dynamic_txpower(hw);
+ _rtl92s_dm_refresh_rateadaptive_mask(hw);
+ _rtl92s_dm_switch_baseband_mrc(hw);
+}
+
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.h b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h
new file mode 100644
index 00000000000..9051a556acc
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h
@@ -0,0 +1,164 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __RTL_92S_DM_H__
+#define __RTL_92S_DM_H__
+
+struct dig_t {
+ u8 dig_enable_flag;
+ u8 dig_algorithm;
+ u8 dig_twoport_algorithm;
+ u8 dig_ext_port_stage;
+ u8 dig_dbgmode;
+ u8 dig_slgorithm_switch;
+
+ long rssi_lowthresh;
+ long rssi_highthresh;
+
+ u32 fa_lowthresh;
+ u32 fa_highthresh;
+
+ long rssi_highpower_lowthresh;
+ long rssi_highpower_highthresh;
+
+ u8 dig_state;
+ u8 dig_highpwrstate;
+ u8 cur_sta_connectstate;
+ u8 pre_sta_connectstate;
+ u8 cur_ap_connectstate;
+ u8 pre_ap_connectstate;
+
+ u8 cur_pd_thstate;
+ u8 pre_pd_thstate;
+ u8 cur_cs_ratiostate;
+ u8 pre_cs_ratiostate;
+
+ u32 pre_igvalue;
+ u32 cur_igvalue;
+
+ u8 backoff_enable_flag;
+ char backoff_val;
+ char backoffval_range_max;
+ char backoffval_range_min;
+ u8 rx_gain_range_max;
+ u8 rx_gain_range_min;
+
+ long rssi_val;
+};
+
+enum dm_dig_alg {
+ DIG_ALGO_BY_FALSE_ALARM = 0,
+ DIG_ALGO_BY_RSSI = 1,
+ DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM = 2,
+ DIG_ALGO_BY_TOW_PORT = 3,
+ DIG_ALGO_MAX
+};
+
+enum dm_dig_two_port_alg {
+ DIG_TWO_PORT_ALGO_RSSI = 0,
+ DIG_TWO_PORT_ALGO_FALSE_ALARM = 1,
+};
+
+enum dm_dig_dbg {
+ DM_DBG_OFF = 0,
+ DM_DBG_ON = 1,
+ DM_DBG_MAX
+};
+
+enum dm_dig_sta {
+ DM_STA_DIG_OFF = 0,
+ DM_STA_DIG_ON,
+ DM_STA_DIG_MAX
+};
+
+enum dm_dig_connect {
+ DIG_STA_DISCONNECT = 0,
+ DIG_STA_CONNECT = 1,
+ DIG_STA_BEFORE_CONNECT = 2,
+ DIG_AP_DISCONNECT = 3,
+ DIG_AP_CONNECT = 4,
+ DIG_AP_ADD_STATION = 5,
+ DIG_CONNECT_MAX
+};
+
+enum dm_dig_ext_port_alg {
+ DIG_EXT_PORT_STAGE_0 = 0,
+ DIG_EXT_PORT_STAGE_1 = 1,
+ DIG_EXT_PORT_STAGE_2 = 2,
+ DIG_EXT_PORT_STAGE_3 = 3,
+ DIG_EXT_PORT_STAGE_MAX = 4,
+};
+
+enum dm_ratr_sta {
+ DM_RATR_STA_HIGH = 0,
+ DM_RATR_STA_MIDDLEHIGH = 1,
+ DM_RATR_STA_MIDDLE = 2,
+ DM_RATR_STA_MIDDLELOW = 3,
+ DM_RATR_STA_LOW = 4,
+ DM_RATR_STA_ULTRALOW = 5,
+ DM_RATR_STA_MAX
+};
+
+#define DM_TYPE_BYFW 0
+#define DM_TYPE_BYDRIVER 1
+
+#define TX_HIGH_PWR_LEVEL_NORMAL 0
+#define TX_HIGH_PWR_LEVEL_LEVEL1 1
+#define TX_HIGH_PWR_LEVEL_LEVEL2 2
+
+#define HAL_DM_DIG_DISABLE BIT(0) /* Disable Dig */
+#define HAL_DM_HIPWR_DISABLE BIT(1) /* Disable High Power */
+
+#define TX_HIGHPWR_LEVEL_NORMAL 0
+#define TX_HIGHPWR_LEVEL_NORMAL1 1
+#define TX_HIGHPWR_LEVEL_NORMAL2 2
+
+#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
+#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
+
+#define DM_DIG_THRESH_HIGH 40
+#define DM_DIG_THRESH_LOW 35
+#define DM_FALSEALARM_THRESH_LOW 40
+#define DM_FALSEALARM_THRESH_HIGH 1000
+#define DM_DIG_HIGH_PWR_THRESH_HIGH 75
+#define DM_DIG_HIGH_PWR_THRESH_LOW 70
+#define DM_DIG_BACKOFF 12
+#define DM_DIG_MAX 0x3e
+#define DM_DIG_MIN 0x1c
+#define DM_DIG_MIN_Netcore 0x12
+#define DM_DIG_BACKOFF_MAX 12
+#define DM_DIG_BACKOFF_MIN -4
+
+extern struct dig_t digtable;
+
+void rtl92s_dm_watchdog(struct ieee80211_hw *hw);
+void rtl92s_dm_init(struct ieee80211_hw *hw);
+void rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw);
+
+#endif
+
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
new file mode 100644
index 00000000000..3b5af0113d7
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
@@ -0,0 +1,654 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "fw.h"
+
+static void _rtl92s_fw_set_rqpn(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtl_write_dword(rtlpriv, RQPN, 0xffffffff);
+ rtl_write_dword(rtlpriv, RQPN + 4, 0xffffffff);
+ rtl_write_byte(rtlpriv, RQPN + 8, 0xff);
+ rtl_write_byte(rtlpriv, RQPN + 0xB, 0x80);
+}
+
+static bool _rtl92s_firmware_enable_cpu(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 ichecktime = 200;
+ u16 tmpu2b;
+ u8 tmpu1b, cpustatus = 0;
+
+ _rtl92s_fw_set_rqpn(hw);
+
+ /* Enable CPU. */
+ tmpu1b = rtl_read_byte(rtlpriv, SYS_CLKR);
+ /* AFE source */
+ rtl_write_byte(rtlpriv, SYS_CLKR, (tmpu1b | SYS_CPU_CLKSEL));
+
+ tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
+ rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | FEN_CPUEN));
+
+ /* Polling IMEM Ready after CPU has refilled. */
+ do {
+ cpustatus = rtl_read_byte(rtlpriv, TCR);
+ if (cpustatus & IMEM_RDY) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("IMEM Ready after CPU has refilled.\n"));
+ break;
+ }
+
+ udelay(100);
+ } while (ichecktime--);
+
+ if (!(cpustatus & IMEM_RDY))
+ return false;
+
+ return true;
+}
+
+static enum fw_status _rtl92s_firmware_get_nextstatus(
+ enum fw_status fw_currentstatus)
+{
+ enum fw_status next_fwstatus = 0;
+
+ switch (fw_currentstatus) {
+ case FW_STATUS_INIT:
+ next_fwstatus = FW_STATUS_LOAD_IMEM;
+ break;
+ case FW_STATUS_LOAD_IMEM:
+ next_fwstatus = FW_STATUS_LOAD_EMEM;
+ break;
+ case FW_STATUS_LOAD_EMEM:
+ next_fwstatus = FW_STATUS_LOAD_DMEM;
+ break;
+ case FW_STATUS_LOAD_DMEM:
+ next_fwstatus = FW_STATUS_READY;
+ break;
+ default:
+ break;
+ }
+
+ return next_fwstatus;
+}
+
+static u8 _rtl92s_firmware_header_map_rftype(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ switch (rtlphy->rf_type) {
+ case RF_1T1R:
+ return 0x11;
+ break;
+ case RF_1T2R:
+ return 0x12;
+ break;
+ case RF_2T2R:
+ return 0x22;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
+ ("Unknown RF type(%x)\n",
+ rtlphy->rf_type));
+ break;
+ }
+ return 0x22;
+}
+
+static void _rtl92s_firmwareheader_priveupdate(struct ieee80211_hw *hw,
+ struct fw_priv *pfw_priv)
+{
+ /* Update RF types for RATR settings. */
+ pfw_priv->rf_config = _rtl92s_firmware_header_map_rftype(hw);
+}
+
+
+
+static bool _rtl92s_cmd_send_packet(struct ieee80211_hw *hw,
+ struct sk_buff *skb, u8 last)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl8192_tx_ring *ring;
+ struct rtl_tx_desc *pdesc;
+ unsigned long flags;
+ u8 idx = 0;
+
+ ring = &rtlpci->tx_ring[TXCMD_QUEUE];
+
+ spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+
+ idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
+ pdesc = &ring->desc[idx];
+ rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
+ __skb_queue_tail(&ring->queue, skb);
+
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+ return true;
+}
+
+static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw,
+ u8 *code_virtual_address, u32 buffer_len)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct sk_buff *skb;
+ struct rtl_tcb_desc *tcb_desc;
+ unsigned char *seg_ptr;
+ u16 frag_threshold = MAX_FIRMWARE_CODE_SIZE;
+ u16 frag_length, frag_offset = 0;
+ u16 extra_descoffset = 0;
+ u8 last_inipkt = 0;
+
+ _rtl92s_fw_set_rqpn(hw);
+
+ if (buffer_len >= MAX_FIRMWARE_CODE_SIZE) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Size over FIRMWARE_CODE_SIZE!\n"));
+
+ return false;
+ }
+
+ extra_descoffset = 0;
+
+ do {
+ if ((buffer_len - frag_offset) > frag_threshold) {
+ frag_length = frag_threshold + extra_descoffset;
+ } else {
+ frag_length = (u16)(buffer_len - frag_offset +
+ extra_descoffset);
+ last_inipkt = 1;
+ }
+
+ /* Allocate skb buffer to contain firmware */
+ /* info and tx descriptor info. */
+ skb = dev_alloc_skb(frag_length);
+ skb_reserve(skb, extra_descoffset);
+ seg_ptr = (u8 *)skb_put(skb, (u32)(frag_length -
+ extra_descoffset));
+ memcpy(seg_ptr, code_virtual_address + frag_offset,
+ (u32)(frag_length - extra_descoffset));
+
+ tcb_desc = (struct rtl_tcb_desc *)(skb->cb);
+ tcb_desc->queue_index = TXCMD_QUEUE;
+ tcb_desc->cmd_or_init = DESC_PACKET_TYPE_INIT;
+ tcb_desc->last_inipkt = last_inipkt;
+
+ _rtl92s_cmd_send_packet(hw, skb, last_inipkt);
+
+ frag_offset += (frag_length - extra_descoffset);
+
+ } while (frag_offset < buffer_len);
+
+ rtl_write_byte(rtlpriv, TP_POLL, TPPOLL_CQ);
+
+ return true ;
+}
+
+static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
+ u8 loadfw_status)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rt_firmware *firmware = (struct rt_firmware *)rtlhal->pfirmware;
+ u32 tmpu4b;
+ u8 cpustatus = 0;
+ short pollingcnt = 1000;
+ bool rtstatus = true;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("LoadStaus(%d)\n",
+ loadfw_status));
+
+ firmware->fwstatus = (enum fw_status)loadfw_status;
+
+ switch (loadfw_status) {
+ case FW_STATUS_LOAD_IMEM:
+ /* Polling IMEM code done. */
+ do {
+ cpustatus = rtl_read_byte(rtlpriv, TCR);
+ if (cpustatus & IMEM_CODE_DONE)
+ break;
+ udelay(5);
+ } while (pollingcnt--);
+
+ if (!(cpustatus & IMEM_CHK_RPT) || (pollingcnt <= 0)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("FW_STATUS_LOAD_IMEM"
+ " FAIL CPU, Status=%x\r\n", cpustatus));
+ goto status_check_fail;
+ }
+ break;
+
+ case FW_STATUS_LOAD_EMEM:
+ /* Check Put Code OK and Turn On CPU */
+ /* Polling EMEM code done. */
+ do {
+ cpustatus = rtl_read_byte(rtlpriv, TCR);
+ if (cpustatus & EMEM_CODE_DONE)
+ break;
+ udelay(5);
+ } while (pollingcnt--);
+
+ if (!(cpustatus & EMEM_CHK_RPT) || (pollingcnt <= 0)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("FW_STATUS_LOAD_EMEM"
+ " FAIL CPU, Status=%x\r\n", cpustatus));
+ goto status_check_fail;
+ }
+
+ /* Turn On CPU */
+ rtstatus = _rtl92s_firmware_enable_cpu(hw);
+ if (rtstatus != true) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Enable CPU fail!\n"));
+ goto status_check_fail;
+ }
+ break;
+
+ case FW_STATUS_LOAD_DMEM:
+ /* Polling DMEM code done */
+ do {
+ cpustatus = rtl_read_byte(rtlpriv, TCR);
+ if (cpustatus & DMEM_CODE_DONE)
+ break;
+ udelay(5);
+ } while (pollingcnt--);
+
+ if (!(cpustatus & DMEM_CODE_DONE) || (pollingcnt <= 0)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Polling DMEM code done"
+ " fail ! cpustatus(%#x)\n", cpustatus));
+ goto status_check_fail;
+ }
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("DMEM code download success,"
+ " cpustatus(%#x)\n", cpustatus));
+
+ /* Prevent Delay too much and being scheduled out */
+ /* Polling Load Firmware ready */
+ pollingcnt = 2000;
+ do {
+ cpustatus = rtl_read_byte(rtlpriv, TCR);
+ if (cpustatus & FWRDY)
+ break;
+ udelay(40);
+ } while (pollingcnt--);
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("Polling Load Firmware ready,"
+ " cpustatus(%x)\n", cpustatus));
+
+ if (((cpustatus & LOAD_FW_READY) != LOAD_FW_READY) ||
+ (pollingcnt <= 0)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Polling Load Firmware"
+ " ready fail ! cpustatus(%x)\n", cpustatus));
+ goto status_check_fail;
+ }
+
+ /* If right here, we can set TCR/RCR to desired value */
+ /* and config MAC lookback mode to normal mode */
+ tmpu4b = rtl_read_dword(rtlpriv, TCR);
+ rtl_write_dword(rtlpriv, TCR, (tmpu4b & (~TCR_ICV)));
+
+ tmpu4b = rtl_read_dword(rtlpriv, RCR);
+ rtl_write_dword(rtlpriv, RCR, (tmpu4b | RCR_APPFCS |
+ RCR_APP_ICV | RCR_APP_MIC));
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("Current RCR settings(%#x)\n", tmpu4b));
+
+ /* Set to normal mode. */
+ rtl_write_byte(rtlpriv, LBKMD_SEL, LBK_NORMAL);
+ break;
+
+ default:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
+ ("Unknown status check!\n"));
+ rtstatus = false;
+ break;
+ }
+
+status_check_fail:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("loadfw_status(%d), "
+ "rtstatus(%x)\n", loadfw_status, rtstatus));
+ return rtstatus;
+}
+
+int rtl92s_download_fw(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rt_firmware *firmware = NULL;
+ struct fw_hdr *pfwheader;
+ struct fw_priv *pfw_priv = NULL;
+ u8 *puc_mappedfile = NULL;
+ u32 ul_filelength = 0;
+ u32 file_length = 0;
+ u8 fwhdr_size = RT_8192S_FIRMWARE_HDR_SIZE;
+ u8 fwstatus = FW_STATUS_INIT;
+ bool rtstatus = true;
+
+ if (!rtlhal->pfirmware)
+ return 1;
+
+ firmware = (struct rt_firmware *)rtlhal->pfirmware;
+ firmware->fwstatus = FW_STATUS_INIT;
+
+ puc_mappedfile = firmware->sz_fw_tmpbuffer;
+ file_length = firmware->sz_fw_tmpbufferlen;
+
+ /* 1. Retrieve FW header. */
+ firmware->pfwheader = (struct fw_hdr *) puc_mappedfile;
+ pfwheader = firmware->pfwheader;
+ firmware->firmwareversion = byte(pfwheader->version, 0);
+ firmware->pfwheader->fwpriv.hci_sel = 1;/* pcie */
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("signature:%x, version:"
+ "%x, size:%x,"
+ "imemsize:%x, sram size:%x\n", pfwheader->signature,
+ pfwheader->version, pfwheader->dmem_size,
+ pfwheader->img_imem_size, pfwheader->img_sram_size));
+
+ /* 2. Retrieve IMEM image. */
+ if ((pfwheader->img_imem_size == 0) || (pfwheader->img_imem_size >
+ sizeof(firmware->fw_imem))) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("memory for data image is less than IMEM required\n"));
+ goto fail;
+ } else {
+ puc_mappedfile += fwhdr_size;
+
+ memcpy(firmware->fw_imem, puc_mappedfile,
+ pfwheader->img_imem_size);
+ firmware->fw_imem_len = pfwheader->img_imem_size;
+ }
+
+ /* 3. Retriecve EMEM image. */
+ if (pfwheader->img_sram_size > sizeof(firmware->fw_emem)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("memory for data image is less than EMEM required\n"));
+ goto fail;
+ } else {
+ puc_mappedfile += firmware->fw_imem_len;
+
+ memcpy(firmware->fw_emem, puc_mappedfile,
+ pfwheader->img_sram_size);
+ firmware->fw_emem_len = pfwheader->img_sram_size;
+ }
+
+ /* 4. download fw now */
+ fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus);
+ while (fwstatus != FW_STATUS_READY) {
+ /* Image buffer redirection. */
+ switch (fwstatus) {
+ case FW_STATUS_LOAD_IMEM:
+ puc_mappedfile = firmware->fw_imem;
+ ul_filelength = firmware->fw_imem_len;
+ break;
+ case FW_STATUS_LOAD_EMEM:
+ puc_mappedfile = firmware->fw_emem;
+ ul_filelength = firmware->fw_emem_len;
+ break;
+ case FW_STATUS_LOAD_DMEM:
+ /* Partial update the content of header private. */
+ pfwheader = firmware->pfwheader;
+ pfw_priv = &pfwheader->fwpriv;
+ _rtl92s_firmwareheader_priveupdate(hw, pfw_priv);
+ puc_mappedfile = (u8 *)(firmware->pfwheader) +
+ RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE;
+ ul_filelength = fwhdr_size -
+ RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Unexpected Download step!!\n"));
+ goto fail;
+ break;
+ }
+
+ /* <2> Download image file */
+ rtstatus = _rtl92s_firmware_downloadcode(hw, puc_mappedfile,
+ ul_filelength);
+
+ if (rtstatus != true) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n"));
+ goto fail;
+ }
+
+ /* <3> Check whether load FW process is ready */
+ rtstatus = _rtl92s_firmware_checkready(hw, fwstatus);
+ if (rtstatus != true) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n"));
+ goto fail;
+ }
+
+ fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus);
+ }
+
+ return rtstatus;
+fail:
+ return 0;
+}
+
+static u32 _rtl92s_fill_h2c_cmd(struct sk_buff *skb, u32 h2cbufferlen,
+ u32 cmd_num, u32 *pelement_id, u32 *pcmd_len,
+ u8 **pcmb_buffer, u8 *cmd_start_seq)
+{
+ u32 totallen = 0, len = 0, tx_desclen = 0;
+ u32 pre_continueoffset = 0;
+ u8 *ph2c_buffer;
+ u8 i = 0;
+
+ do {
+ /* 8 - Byte aligment */
+ len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8);
+
+ /* Buffer length is not enough */
+ if (h2cbufferlen < totallen + len + tx_desclen)
+ break;
+
+ /* Clear content */
+ ph2c_buffer = (u8 *)skb_put(skb, (u32)len);
+ memset((ph2c_buffer + totallen + tx_desclen), 0, len);
+
+ /* CMD len */
+ SET_BITS_TO_LE_4BYTE((ph2c_buffer + totallen + tx_desclen),
+ 0, 16, pcmd_len[i]);
+
+ /* CMD ID */
+ SET_BITS_TO_LE_4BYTE((ph2c_buffer + totallen + tx_desclen),
+ 16, 8, pelement_id[i]);
+
+ /* CMD Sequence */
+ *cmd_start_seq = *cmd_start_seq % 0x80;
+ SET_BITS_TO_LE_4BYTE((ph2c_buffer + totallen + tx_desclen),
+ 24, 7, *cmd_start_seq);
+ ++*cmd_start_seq;
+
+ /* Copy memory */
+ memcpy((ph2c_buffer + totallen + tx_desclen +
+ H2C_TX_CMD_HDR_LEN), pcmb_buffer[i], pcmd_len[i]);
+
+ /* CMD continue */
+ /* set the continue in prevoius cmd. */
+ if (i < cmd_num - 1)
+ SET_BITS_TO_LE_4BYTE((ph2c_buffer + pre_continueoffset),
+ 31, 1, 1);
+
+ pre_continueoffset = totallen;
+
+ totallen += len;
+ } while (++i < cmd_num);
+
+ return totallen;
+}
+
+static u32 _rtl92s_get_h2c_cmdlen(u32 h2cbufferlen, u32 cmd_num, u32 *pcmd_len)
+{
+ u32 totallen = 0, len = 0, tx_desclen = 0;
+ u8 i = 0;
+
+ do {
+ /* 8 - Byte aligment */
+ len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8);
+
+ /* Buffer length is not enough */
+ if (h2cbufferlen < totallen + len + tx_desclen)
+ break;
+
+ totallen += len;
+ } while (++i < cmd_num);
+
+ return totallen + tx_desclen;
+}
+
+static bool _rtl92s_firmware_set_h2c_cmd(struct ieee80211_hw *hw, u8 h2c_cmd,
+ u8 *pcmd_buffer)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_tcb_desc *cb_desc;
+ struct sk_buff *skb;
+ u32 element_id = 0;
+ u32 cmd_len = 0;
+ u32 len;
+
+ switch (h2c_cmd) {
+ case FW_H2C_SETPWRMODE:
+ element_id = H2C_SETPWRMODE_CMD ;
+ cmd_len = sizeof(struct h2c_set_pwrmode_parm);
+ break;
+ case FW_H2C_JOINBSSRPT:
+ element_id = H2C_JOINBSSRPT_CMD;
+ cmd_len = sizeof(struct h2c_joinbss_rpt_parm);
+ break;
+ case FW_H2C_WOWLAN_UPDATE_GTK:
+ element_id = H2C_WOWLAN_UPDATE_GTK_CMD;
+ cmd_len = sizeof(struct h2c_wpa_two_way_parm);
+ break;
+ case FW_H2C_WOWLAN_UPDATE_IV:
+ element_id = H2C_WOWLAN_UPDATE_IV_CMD;
+ cmd_len = sizeof(unsigned long long);
+ break;
+ case FW_H2C_WOWLAN_OFFLOAD:
+ element_id = H2C_WOWLAN_FW_OFFLOAD;
+ cmd_len = sizeof(u8);
+ break;
+ default:
+ break;
+ }
+
+ len = _rtl92s_get_h2c_cmdlen(MAX_TRANSMIT_BUFFER_SIZE, 1, &cmd_len);
+ skb = dev_alloc_skb(len);
+ cb_desc = (struct rtl_tcb_desc *)(skb->cb);
+ cb_desc->queue_index = TXCMD_QUEUE;
+ cb_desc->cmd_or_init = DESC_PACKET_TYPE_NORMAL;
+ cb_desc->last_inipkt = false;
+
+ _rtl92s_fill_h2c_cmd(skb, MAX_TRANSMIT_BUFFER_SIZE, 1, &element_id,
+ &cmd_len, &pcmd_buffer, &rtlhal->h2c_txcmd_seq);
+ _rtl92s_cmd_send_packet(hw, skb, false);
+ rtlpriv->cfg->ops->tx_polling(hw, TXCMD_QUEUE);
+
+ return true;
+}
+
+void rtl92s_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 Mode)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct h2c_set_pwrmode_parm pwrmode;
+ u16 max_wakeup_period = 0;
+
+ pwrmode.mode = Mode;
+ pwrmode.flag_low_traffic_en = 0;
+ pwrmode.flag_lpnav_en = 0;
+ pwrmode.flag_rf_low_snr_en = 0;
+ pwrmode.flag_dps_en = 0;
+ pwrmode.bcn_rx_en = 0;
+ pwrmode.bcn_to = 0;
+ SET_BITS_TO_LE_2BYTE((u8 *)(&pwrmode) + 8, 0, 16,
+ mac->vif->bss_conf.beacon_int);
+ pwrmode.app_itv = 0;
+ pwrmode.awake_bcn_itvl = ppsc->reg_max_lps_awakeintvl;
+ pwrmode.smart_ps = 1;
+ pwrmode.bcn_pass_period = 10;
+
+ /* Set beacon pass count */
+ if (pwrmode.mode == FW_PS_MIN_MODE)
+ max_wakeup_period = mac->vif->bss_conf.beacon_int;
+ else if (pwrmode.mode == FW_PS_MAX_MODE)
+ max_wakeup_period = mac->vif->bss_conf.beacon_int *
+ mac->vif->bss_conf.dtim_period;
+
+ if (max_wakeup_period >= 500)
+ pwrmode.bcn_pass_cnt = 1;
+ else if ((max_wakeup_period >= 300) && (max_wakeup_period < 500))
+ pwrmode.bcn_pass_cnt = 2;
+ else if ((max_wakeup_period >= 200) && (max_wakeup_period < 300))
+ pwrmode.bcn_pass_cnt = 3;
+ else if ((max_wakeup_period >= 20) && (max_wakeup_period < 200))
+ pwrmode.bcn_pass_cnt = 5;
+ else
+ pwrmode.bcn_pass_cnt = 1;
+
+ _rtl92s_firmware_set_h2c_cmd(hw, FW_H2C_SETPWRMODE, (u8 *)&pwrmode);
+
+}
+
+void rtl92s_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw,
+ u8 mstatus, u8 ps_qosinfo)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct h2c_joinbss_rpt_parm joinbss_rpt;
+
+ joinbss_rpt.opmode = mstatus;
+ joinbss_rpt.ps_qos_info = ps_qosinfo;
+ joinbss_rpt.bssid[0] = mac->bssid[0];
+ joinbss_rpt.bssid[1] = mac->bssid[1];
+ joinbss_rpt.bssid[2] = mac->bssid[2];
+ joinbss_rpt.bssid[3] = mac->bssid[3];
+ joinbss_rpt.bssid[4] = mac->bssid[4];
+ joinbss_rpt.bssid[5] = mac->bssid[5];
+ SET_BITS_TO_LE_2BYTE((u8 *)(&joinbss_rpt) + 8, 0, 16,
+ mac->vif->bss_conf.beacon_int);
+ SET_BITS_TO_LE_2BYTE((u8 *)(&joinbss_rpt) + 10, 0, 16, mac->assoc_id);
+
+ _rtl92s_firmware_set_h2c_cmd(hw, FW_H2C_JOINBSSRPT, (u8 *)&joinbss_rpt);
+}
+
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.h b/drivers/net/wireless/rtlwifi/rtl8192se/fw.h
new file mode 100644
index 00000000000..74cc503efe8
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.h
@@ -0,0 +1,375 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __REALTEK_FIRMWARE92S_H__
+#define __REALTEK_FIRMWARE92S_H__
+
+#define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000
+#define RTL8190_CPU_START_OFFSET 0x80
+/* Firmware Local buffer size. 64k */
+#define MAX_FIRMWARE_CODE_SIZE 0xFF00
+
+#define RT_8192S_FIRMWARE_HDR_SIZE 80
+#define RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE 32
+
+/* support till 64 bit bus width OS */
+#define MAX_DEV_ADDR_SIZE 8
+#define MAX_FIRMWARE_INFORMATION_SIZE 32
+#define MAX_802_11_HEADER_LENGTH (40 + \
+ MAX_FIRMWARE_INFORMATION_SIZE)
+#define ENCRYPTION_MAX_OVERHEAD 128
+#define MAX_FRAGMENT_COUNT 8
+#define MAX_TRANSMIT_BUFFER_SIZE (1600 + \
+ (MAX_802_11_HEADER_LENGTH + \
+ ENCRYPTION_MAX_OVERHEAD) *\
+ MAX_FRAGMENT_COUNT)
+
+#define H2C_TX_CMD_HDR_LEN 8
+
+/* The following DM control code are for Reg0x364, */
+#define FW_DIG_ENABLE_CTL BIT(0)
+#define FW_HIGH_PWR_ENABLE_CTL BIT(1)
+#define FW_SS_CTL BIT(2)
+#define FW_RA_INIT_CTL BIT(3)
+#define FW_RA_BG_CTL BIT(4)
+#define FW_RA_N_CTL BIT(5)
+#define FW_PWR_TRK_CTL BIT(6)
+#define FW_IQK_CTL BIT(7)
+#define FW_FA_CTL BIT(8)
+#define FW_DRIVER_CTRL_DM_CTL BIT(9)
+#define FW_PAPE_CTL_BY_SW_HW BIT(10)
+#define FW_DISABLE_ALL_DM 0
+#define FW_PWR_TRK_PARAM_CLR 0x0000ffff
+#define FW_RA_PARAM_CLR 0xffff0000
+
+enum desc_packet_type {
+ DESC_PACKET_TYPE_INIT = 0,
+ DESC_PACKET_TYPE_NORMAL = 1,
+};
+
+/* 8-bytes alignment required */
+struct fw_priv {
+ /* --- long word 0 ---- */
+ /* 0x12: CE product, 0x92: IT product */
+ u8 signature_0;
+ /* 0x87: CE product, 0x81: IT product */
+ u8 signature_1;
+ /* 0x81: PCI-AP, 01:PCIe, 02: 92S-U,
+ * 0x82: USB-AP, 0x12: 72S-U, 03:SDIO */
+ u8 hci_sel;
+ /* the same value as reigster value */
+ u8 chip_version;
+ /* customer ID low byte */
+ u8 customer_id_0;
+ /* customer ID high byte */
+ u8 customer_id_1;
+ /* 0x11: 1T1R, 0x12: 1T2R,
+ * 0x92: 1T2R turbo, 0x22: 2T2R */
+ u8 rf_config;
+ /* 4: 4EP, 6: 6EP, 11: 11EP */
+ u8 usb_ep_num;
+
+ /* --- long word 1 ---- */
+ /* regulatory class bit map 0 */
+ u8 regulatory_class_0;
+ /* regulatory class bit map 1 */
+ u8 regulatory_class_1;
+ /* regulatory class bit map 2 */
+ u8 regulatory_class_2;
+ /* regulatory class bit map 3 */
+ u8 regulatory_class_3;
+ /* 0:SWSI, 1:HWSI, 2:HWPI */
+ u8 rfintfs;
+ u8 def_nettype;
+ u8 rsvd010;
+ u8 rsvd011;
+
+ /* --- long word 2 ---- */
+ /* 0x00: normal, 0x03: MACLBK, 0x01: PHYLBK */
+ u8 lbk_mode;
+ /* 1: for MP use, 0: for normal
+ * driver (to be discussed) */
+ u8 mp_mode;
+ u8 rsvd020;
+ u8 rsvd021;
+ u8 rsvd022;
+ u8 rsvd023;
+ u8 rsvd024;
+ u8 rsvd025;
+
+ /* --- long word 3 ---- */
+ /* QoS enable */
+ u8 qos_en;
+ /* 40MHz BW enable */
+ /* 4181 convert AMSDU to AMPDU, 0: disable */
+ u8 bw_40mhz_en;
+ u8 amsdu2ampdu_en;
+ /* 11n AMPDU enable */
+ u8 ampdu_en;
+ /* FW offloads, 0: driver handles */
+ u8 rate_control_offload;
+ /* FW offloads, 0: driver handles */
+ u8 aggregation_offload;
+ u8 rsvd030;
+ u8 rsvd031;
+
+ /* --- long word 4 ---- */
+ /* 1. FW offloads, 0: driver handles */
+ u8 beacon_offload;
+ /* 2. FW offloads, 0: driver handles */
+ u8 mlme_offload;
+ /* 3. FW offloads, 0: driver handles */
+ u8 hwpc_offload;
+ /* 4. FW offloads, 0: driver handles */
+ u8 tcp_checksum_offload;
+ /* 5. FW offloads, 0: driver handles */
+ u8 tcp_offload;
+ /* 6. FW offloads, 0: driver handles */
+ u8 ps_control_offload;
+ /* 7. FW offloads, 0: driver handles */
+ u8 wwlan_offload;
+ u8 rsvd040;
+
+ /* --- long word 5 ---- */
+ /* tcp tx packet length low byte */
+ u8 tcp_tx_frame_len_L;
+ /* tcp tx packet length high byte */
+ u8 tcp_tx_frame_len_H;
+ /* tcp rx packet length low byte */
+ u8 tcp_rx_frame_len_L;
+ /* tcp rx packet length high byte */
+ u8 tcp_rx_frame_len_H;
+ u8 rsvd050;
+ u8 rsvd051;
+ u8 rsvd052;
+ u8 rsvd053;
+};
+
+/* 8-byte alinment required */
+struct fw_hdr {
+
+ /* --- LONG WORD 0 ---- */
+ u16 signature;
+ /* 0x8000 ~ 0x8FFF for FPGA version,
+ * 0x0000 ~ 0x7FFF for ASIC version, */
+ u16 version;
+ /* define the size of boot loader */
+ u32 dmem_size;
+
+
+ /* --- LONG WORD 1 ---- */
+ /* define the size of FW in IMEM */
+ u32 img_imem_size;
+ /* define the size of FW in SRAM */
+ u32 img_sram_size;
+
+ /* --- LONG WORD 2 ---- */
+ /* define the size of DMEM variable */
+ u32 fw_priv_size;
+ u32 rsvd0;
+
+ /* --- LONG WORD 3 ---- */
+ u32 rsvd1;
+ u32 rsvd2;
+
+ struct fw_priv fwpriv;
+
+} ;
+
+enum fw_status {
+ FW_STATUS_INIT = 0,
+ FW_STATUS_LOAD_IMEM = 1,
+ FW_STATUS_LOAD_EMEM = 2,
+ FW_STATUS_LOAD_DMEM = 3,
+ FW_STATUS_READY = 4,
+};
+
+struct rt_firmware {
+ struct fw_hdr *pfwheader;
+ enum fw_status fwstatus;
+ u16 firmwareversion;
+ u8 fw_imem[RTL8190_MAX_FIRMWARE_CODE_SIZE];
+ u8 fw_emem[RTL8190_MAX_FIRMWARE_CODE_SIZE];
+ u32 fw_imem_len;
+ u32 fw_emem_len;
+ u8 sz_fw_tmpbuffer[164000];
+ u32 sz_fw_tmpbufferlen;
+ u16 cmdpacket_fragthresold;
+};
+
+struct h2c_set_pwrmode_parm {
+ u8 mode;
+ u8 flag_low_traffic_en;
+ u8 flag_lpnav_en;
+ u8 flag_rf_low_snr_en;
+ /* 1: dps, 0: 32k */
+ u8 flag_dps_en;
+ u8 bcn_rx_en;
+ u8 bcn_pass_cnt;
+ /* beacon TO (ms). ¡§=0¡¨ no limit. */
+ u8 bcn_to;
+ u16 bcn_itv;
+ /* only for VOIP mode. */
+ u8 app_itv;
+ u8 awake_bcn_itvl;
+ u8 smart_ps;
+ /* unit: 100 ms */
+ u8 bcn_pass_period;
+};
+
+struct h2c_joinbss_rpt_parm {
+ u8 opmode;
+ u8 ps_qos_info;
+ u8 bssid[6];
+ u16 bcnitv;
+ u16 aid;
+} ;
+
+struct h2c_wpa_ptk {
+ /* EAPOL-Key Key Confirmation Key (KCK) */
+ u8 kck[16];
+ /* EAPOL-Key Key Encryption Key (KEK) */
+ u8 kek[16];
+ /* Temporal Key 1 (TK1) */
+ u8 tk1[16];
+ union {
+ /* Temporal Key 2 (TK2) */
+ u8 tk2[16];
+ struct {
+ u8 tx_mic_key[8];
+ u8 rx_mic_key[8];
+ } athu;
+ } u;
+};
+
+struct h2c_wpa_two_way_parm {
+ /* algorithm TKIP or AES */
+ u8 pairwise_en_alg;
+ u8 group_en_alg;
+ struct h2c_wpa_ptk wpa_ptk_value;
+} ;
+
+enum h2c_cmd {
+ FW_H2C_SETPWRMODE = 0,
+ FW_H2C_JOINBSSRPT = 1,
+ FW_H2C_WOWLAN_UPDATE_GTK = 2,
+ FW_H2C_WOWLAN_UPDATE_IV = 3,
+ FW_H2C_WOWLAN_OFFLOAD = 4,
+};
+
+enum fw_h2c_cmd {
+ H2C_READ_MACREG_CMD, /*0*/
+ H2C_WRITE_MACREG_CMD,
+ H2C_READBB_CMD,
+ H2C_WRITEBB_CMD,
+ H2C_READRF_CMD,
+ H2C_WRITERF_CMD, /*5*/
+ H2C_READ_EEPROM_CMD,
+ H2C_WRITE_EEPROM_CMD,
+ H2C_READ_EFUSE_CMD,
+ H2C_WRITE_EFUSE_CMD,
+ H2C_READ_CAM_CMD, /*10*/
+ H2C_WRITE_CAM_CMD,
+ H2C_SETBCNITV_CMD,
+ H2C_SETMBIDCFG_CMD,
+ H2C_JOINBSS_CMD,
+ H2C_DISCONNECT_CMD, /*15*/
+ H2C_CREATEBSS_CMD,
+ H2C_SETOPMode_CMD,
+ H2C_SITESURVEY_CMD,
+ H2C_SETAUTH_CMD,
+ H2C_SETKEY_CMD, /*20*/
+ H2C_SETSTAKEY_CMD,
+ H2C_SETASSOCSTA_CMD,
+ H2C_DELASSOCSTA_CMD,
+ H2C_SETSTAPWRSTATE_CMD,
+ H2C_SETBASICRATE_CMD, /*25*/
+ H2C_GETBASICRATE_CMD,
+ H2C_SETDATARATE_CMD,
+ H2C_GETDATARATE_CMD,
+ H2C_SETPHYINFO_CMD,
+ H2C_GETPHYINFO_CMD, /*30*/
+ H2C_SETPHY_CMD,
+ H2C_GETPHY_CMD,
+ H2C_READRSSI_CMD,
+ H2C_READGAIN_CMD,
+ H2C_SETATIM_CMD, /*35*/
+ H2C_SETPWRMODE_CMD,
+ H2C_JOINBSSRPT_CMD,
+ H2C_SETRATABLE_CMD,
+ H2C_GETRATABLE_CMD,
+ H2C_GETCCXREPORT_CMD, /*40*/
+ H2C_GETDTMREPORT_CMD,
+ H2C_GETTXRATESTATICS_CMD,
+ H2C_SETUSBSUSPEND_CMD,
+ H2C_SETH2CLBK_CMD,
+ H2C_TMP1, /*45*/
+ H2C_WOWLAN_UPDATE_GTK_CMD,
+ H2C_WOWLAN_FW_OFFLOAD,
+ H2C_TMP2,
+ H2C_TMP3,
+ H2C_WOWLAN_UPDATE_IV_CMD, /*50*/
+ H2C_TMP4,
+ MAX_H2CCMD /*52*/
+};
+
+/* The following macros are used for FW
+ * CMD map and parameter updated. */
+#define FW_CMD_IO_CLR(rtlpriv, _Bit) \
+ do { \
+ udelay(1000); \
+ rtlpriv->rtlhal.fwcmd_iomap &= (~_Bit); \
+ } while (0);
+
+#define FW_CMD_IO_UPDATE(rtlpriv, _val) \
+ rtlpriv->rtlhal.fwcmd_iomap = _val;
+
+#define FW_CMD_IO_SET(rtlpriv, _val) \
+ do { \
+ rtl_write_word(rtlpriv, LBUS_MON_ADDR, (u16)_val); \
+ FW_CMD_IO_UPDATE(rtlpriv, _val); \
+ } while (0);
+
+#define FW_CMD_PARA_SET(rtlpriv, _val) \
+ do { \
+ rtl_write_dword(rtlpriv, LBUS_ADDR_MASK, _val); \
+ rtlpriv->rtlhal.fwcmd_ioparam = _val; \
+ } while (0);
+
+#define FW_CMD_IO_QUERY(rtlpriv) \
+ (u16)(rtlpriv->rtlhal.fwcmd_iomap)
+#define FW_CMD_IO_PARA_QUERY(rtlpriv) \
+ ((u32)(rtlpriv->rtlhal.fwcmd_ioparam))
+
+int rtl92s_download_fw(struct ieee80211_hw *hw);
+void rtl92s_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
+void rtl92s_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw,
+ u8 mstatus, u8 ps_qosinfo);
+
+#endif
+
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
new file mode 100644
index 00000000000..2e9005d0454
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
@@ -0,0 +1,2512 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../efuse.h"
+#include "../base.h"
+#include "../regd.h"
+#include "../cam.h"
+#include "../ps.h"
+#include "../pci.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "fw.h"
+#include "led.h"
+#include "hw.h"
+
+void rtl92se_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ switch (variable) {
+ case HW_VAR_RCR: {
+ *((u32 *) (val)) = rtlpci->receive_config;
+ break;
+ }
+ case HW_VAR_RF_STATE: {
+ *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
+ break;
+ }
+ case HW_VAR_FW_PSMODE_STATUS: {
+ *((bool *) (val)) = ppsc->fw_current_inpsmode;
+ break;
+ }
+ case HW_VAR_CORRECT_TSF: {
+ u64 tsf;
+ u32 *ptsf_low = (u32 *)&tsf;
+ u32 *ptsf_high = ((u32 *)&tsf) + 1;
+
+ *ptsf_high = rtl_read_dword(rtlpriv, (TSFR + 4));
+ *ptsf_low = rtl_read_dword(rtlpriv, TSFR);
+
+ *((u64 *) (val)) = tsf;
+
+ break;
+ }
+ case HW_VAR_MRC: {
+ *((bool *)(val)) = rtlpriv->dm.current_mrc_switch;
+ break;
+ }
+ default: {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+ }
+}
+
+void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ switch (variable) {
+ case HW_VAR_ETHER_ADDR:{
+ rtl_write_dword(rtlpriv, IDR0, ((u32 *)(val))[0]);
+ rtl_write_word(rtlpriv, IDR4, ((u16 *)(val + 4))[0]);
+ break;
+ }
+ case HW_VAR_BASIC_RATE:{
+ u16 rate_cfg = ((u16 *) val)[0];
+ u8 rate_index = 0;
+
+ if (rtlhal->version == VERSION_8192S_ACUT)
+ rate_cfg = rate_cfg & 0x150;
+ else
+ rate_cfg = rate_cfg & 0x15f;
+
+ rate_cfg |= 0x01;
+
+ rtl_write_byte(rtlpriv, RRSR, rate_cfg & 0xff);
+ rtl_write_byte(rtlpriv, RRSR + 1,
+ (rate_cfg >> 8) & 0xff);
+
+ while (rate_cfg > 0x1) {
+ rate_cfg = (rate_cfg >> 1);
+ rate_index++;
+ }
+ rtl_write_byte(rtlpriv, INIRTSMCS_SEL, rate_index);
+
+ break;
+ }
+ case HW_VAR_BSSID:{
+ rtl_write_dword(rtlpriv, BSSIDR, ((u32 *)(val))[0]);
+ rtl_write_word(rtlpriv, BSSIDR + 4,
+ ((u16 *)(val + 4))[0]);
+ break;
+ }
+ case HW_VAR_SIFS:{
+ rtl_write_byte(rtlpriv, SIFS_OFDM, val[0]);
+ rtl_write_byte(rtlpriv, SIFS_OFDM + 1, val[1]);
+ break;
+ }
+ case HW_VAR_SLOT_TIME:{
+ u8 e_aci;
+
+ RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+ ("HW_VAR_SLOT_TIME %x\n", val[0]));
+
+ rtl_write_byte(rtlpriv, SLOT_TIME, val[0]);
+
+ for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_AC_PARAM,
+ (u8 *)(&e_aci));
+ }
+ break;
+ }
+ case HW_VAR_ACK_PREAMBLE:{
+ u8 reg_tmp;
+ u8 short_preamble = (bool) (*(u8 *) val);
+ reg_tmp = (mac->cur_40_prime_sc) << 5;
+ if (short_preamble)
+ reg_tmp |= 0x80;
+
+ rtl_write_byte(rtlpriv, RRSR + 2, reg_tmp);
+ break;
+ }
+ case HW_VAR_AMPDU_MIN_SPACE:{
+ u8 min_spacing_to_set;
+ u8 sec_min_space;
+
+ min_spacing_to_set = *((u8 *)val);
+ if (min_spacing_to_set <= 7) {
+ if (rtlpriv->sec.pairwise_enc_algorithm ==
+ NO_ENCRYPTION)
+ sec_min_space = 0;
+ else
+ sec_min_space = 1;
+
+ if (min_spacing_to_set < sec_min_space)
+ min_spacing_to_set = sec_min_space;
+ if (min_spacing_to_set > 5)
+ min_spacing_to_set = 5;
+
+ mac->min_space_cfg =
+ ((mac->min_space_cfg & 0xf8) |
+ min_spacing_to_set);
+
+ *val = min_spacing_to_set;
+
+ RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+ ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
+ mac->min_space_cfg));
+
+ rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE,
+ mac->min_space_cfg);
+ }
+ break;
+ }
+ case HW_VAR_SHORTGI_DENSITY:{
+ u8 density_to_set;
+
+ density_to_set = *((u8 *) val);
+ mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg;
+ mac->min_space_cfg |= (density_to_set << 3);
+
+ RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+ ("Set HW_VAR_SHORTGI_DENSITY: %#x\n",
+ mac->min_space_cfg));
+
+ rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE,
+ mac->min_space_cfg);
+
+ break;
+ }
+ case HW_VAR_AMPDU_FACTOR:{
+ u8 factor_toset;
+ u8 regtoset;
+ u8 factorlevel[18] = {
+ 2, 4, 4, 7, 7, 13, 13,
+ 13, 2, 7, 7, 13, 13,
+ 15, 15, 15, 15, 0};
+ u8 index = 0;
+
+ factor_toset = *((u8 *) val);
+ if (factor_toset <= 3) {
+ factor_toset = (1 << (factor_toset + 2));
+ if (factor_toset > 0xf)
+ factor_toset = 0xf;
+
+ for (index = 0; index < 17; index++) {
+ if (factorlevel[index] > factor_toset)
+ factorlevel[index] =
+ factor_toset;
+ }
+
+ for (index = 0; index < 8; index++) {
+ regtoset = ((factorlevel[index * 2]) |
+ (factorlevel[index *
+ 2 + 1] << 4));
+ rtl_write_byte(rtlpriv,
+ AGGLEN_LMT_L + index,
+ regtoset);
+ }
+
+ regtoset = ((factorlevel[16]) |
+ (factorlevel[17] << 4));
+ rtl_write_byte(rtlpriv, AGGLEN_LMT_H, regtoset);
+
+ RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+ ("Set HW_VAR_AMPDU_FACTOR: %#x\n",
+ factor_toset));
+ }
+ break;
+ }
+ case HW_VAR_AC_PARAM:{
+ u8 e_aci = *((u8 *) val);
+ rtl92s_dm_init_edca_turbo(hw);
+
+ if (rtlpci->acm_method != eAcmWay2_SW)
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_ACM_CTRL,
+ (u8 *)(&e_aci));
+ break;
+ }
+ case HW_VAR_ACM_CTRL:{
+ u8 e_aci = *((u8 *) val);
+ union aci_aifsn *p_aci_aifsn = (union aci_aifsn *)(&(
+ mac->ac[0].aifs));
+ u8 acm = p_aci_aifsn->f.acm;
+ u8 acm_ctrl = rtl_read_byte(rtlpriv, AcmHwCtrl);
+
+ acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ?
+ 0x0 : 0x1);
+
+ if (acm) {
+ switch (e_aci) {
+ case AC0_BE:
+ acm_ctrl |= AcmHw_BeqEn;
+ break;
+ case AC2_VI:
+ acm_ctrl |= AcmHw_ViqEn;
+ break;
+ case AC3_VO:
+ acm_ctrl |= AcmHw_VoqEn;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("HW_VAR_ACM_CTRL acm set "
+ "failed: eACI is %d\n", acm));
+ break;
+ }
+ } else {
+ switch (e_aci) {
+ case AC0_BE:
+ acm_ctrl &= (~AcmHw_BeqEn);
+ break;
+ case AC2_VI:
+ acm_ctrl &= (~AcmHw_ViqEn);
+ break;
+ case AC3_VO:
+ acm_ctrl &= (~AcmHw_BeqEn);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+ }
+
+ RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
+ ("HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl));
+ rtl_write_byte(rtlpriv, AcmHwCtrl, acm_ctrl);
+ break;
+ }
+ case HW_VAR_RCR:{
+ rtl_write_dword(rtlpriv, RCR, ((u32 *) (val))[0]);
+ rtlpci->receive_config = ((u32 *) (val))[0];
+ break;
+ }
+ case HW_VAR_RETRY_LIMIT:{
+ u8 retry_limit = ((u8 *) (val))[0];
+
+ rtl_write_word(rtlpriv, RETRY_LIMIT,
+ retry_limit << RETRY_LIMIT_SHORT_SHIFT |
+ retry_limit << RETRY_LIMIT_LONG_SHIFT);
+ break;
+ }
+ case HW_VAR_DUAL_TSF_RST: {
+ break;
+ }
+ case HW_VAR_EFUSE_BYTES: {
+ rtlefuse->efuse_usedbytes = *((u16 *) val);
+ break;
+ }
+ case HW_VAR_EFUSE_USAGE: {
+ rtlefuse->efuse_usedpercentage = *((u8 *) val);
+ break;
+ }
+ case HW_VAR_IO_CMD: {
+ break;
+ }
+ case HW_VAR_WPA_CONFIG: {
+ rtl_write_byte(rtlpriv, REG_SECR, *((u8 *) val));
+ break;
+ }
+ case HW_VAR_SET_RPWM:{
+ break;
+ }
+ case HW_VAR_H2C_FW_PWRMODE:{
+ break;
+ }
+ case HW_VAR_FW_PSMODE_STATUS: {
+ ppsc->fw_current_inpsmode = *((bool *) val);
+ break;
+ }
+ case HW_VAR_H2C_FW_JOINBSSRPT:{
+ break;
+ }
+ case HW_VAR_AID:{
+ break;
+ }
+ case HW_VAR_CORRECT_TSF:{
+ break;
+ }
+ case HW_VAR_MRC: {
+ bool bmrc_toset = *((bool *)val);
+ u8 u1bdata = 0;
+
+ if (bmrc_toset) {
+ rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
+ MASKBYTE0, 0x33);
+ u1bdata = (u8)rtl_get_bbreg(hw,
+ ROFDM1_TRXPATHENABLE,
+ MASKBYTE0);
+ rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE,
+ MASKBYTE0,
+ ((u1bdata & 0xf0) | 0x03));
+ u1bdata = (u8)rtl_get_bbreg(hw,
+ ROFDM0_TRXPATHENABLE,
+ MASKBYTE1);
+ rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
+ MASKBYTE1,
+ (u1bdata | 0x04));
+
+ /* Update current settings. */
+ rtlpriv->dm.current_mrc_switch = bmrc_toset;
+ } else {
+ rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
+ MASKBYTE0, 0x13);
+ u1bdata = (u8)rtl_get_bbreg(hw,
+ ROFDM1_TRXPATHENABLE,
+ MASKBYTE0);
+ rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE,
+ MASKBYTE0,
+ ((u1bdata & 0xf0) | 0x01));
+ u1bdata = (u8)rtl_get_bbreg(hw,
+ ROFDM0_TRXPATHENABLE,
+ MASKBYTE1);
+ rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
+ MASKBYTE1, (u1bdata & 0xfb));
+
+ /* Update current settings. */
+ rtlpriv->dm.current_mrc_switch = bmrc_toset;
+ }
+
+ break;
+ }
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+
+}
+
+void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 sec_reg_value = 0x0;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("PairwiseEncAlgorithm = %d "
+ "GroupEncAlgorithm = %d\n",
+ rtlpriv->sec.pairwise_enc_algorithm,
+ rtlpriv->sec.group_enc_algorithm));
+
+ if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("not open hw encryption\n"));
+ return;
+ }
+
+ sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE;
+
+ if (rtlpriv->sec.use_defaultkey) {
+ sec_reg_value |= SCR_TXUSEDK;
+ sec_reg_value |= SCR_RXUSEDK;
+ }
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, ("The SECR-value %x\n",
+ sec_reg_value));
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
+
+}
+
+static u8 _rtl92ce_halset_sysclk(struct ieee80211_hw *hw, u8 data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 waitcount = 100;
+ bool bresult = false;
+ u8 tmpvalue;
+
+ rtl_write_byte(rtlpriv, SYS_CLKR + 1, data);
+
+ /* Wait the MAC synchronized. */
+ udelay(400);
+
+ /* Check if it is set ready. */
+ tmpvalue = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
+ bresult = ((tmpvalue & BIT(7)) == (data & BIT(7)));
+
+ if ((data & (BIT(6) | BIT(7))) == false) {
+ waitcount = 100;
+ tmpvalue = 0;
+
+ while (1) {
+ waitcount--;
+
+ tmpvalue = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
+ if ((tmpvalue & BIT(6)))
+ break;
+
+ printk(KERN_ERR "wait for BIT(6) return value %x\n",
+ tmpvalue);
+ if (waitcount == 0)
+ break;
+
+ udelay(10);
+ }
+
+ if (waitcount == 0)
+ bresult = false;
+ else
+ bresult = true;
+ }
+
+ return bresult;
+}
+
+void rtl8192se_gpiobit3_cfg_inputmode(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 u1tmp;
+
+ /* The following config GPIO function */
+ rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO));
+ u1tmp = rtl_read_byte(rtlpriv, GPIO_IO_SEL);
+
+ /* config GPIO3 to input */
+ u1tmp &= HAL_8192S_HW_GPIO_OFF_MASK;
+ rtl_write_byte(rtlpriv, GPIO_IO_SEL, u1tmp);
+
+}
+
+static u8 _rtl92se_rf_onoff_detect(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 u1tmp;
+ u8 retval = ERFON;
+
+ /* The following config GPIO function */
+ rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO));
+ u1tmp = rtl_read_byte(rtlpriv, GPIO_IO_SEL);
+
+ /* config GPIO3 to input */
+ u1tmp &= HAL_8192S_HW_GPIO_OFF_MASK;
+ rtl_write_byte(rtlpriv, GPIO_IO_SEL, u1tmp);
+
+ /* On some of the platform, driver cannot read correct
+ * value without delay between Write_GPIO_SEL and Read_GPIO_IN */
+ mdelay(10);
+
+ /* check GPIO3 */
+ u1tmp = rtl_read_byte(rtlpriv, GPIO_IN);
+ retval = (u1tmp & HAL_8192S_HW_GPIO_OFF_BIT) ? ERFON : ERFOFF;
+
+ return retval;
+}
+
+static void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ u8 i;
+ u8 tmpu1b;
+ u16 tmpu2b;
+ u8 pollingcnt = 20;
+
+ if (rtlpci->first_init) {
+ /* Reset PCIE Digital */
+ tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
+ tmpu1b &= 0xFE;
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b);
+ udelay(1);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b | BIT(0));
+ }
+
+ /* Switch to SW IO control */
+ tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
+ if (tmpu1b & BIT(7)) {
+ tmpu1b &= ~(BIT(6) | BIT(7));
+
+ /* Set failed, return to prevent hang. */
+ if (!_rtl92ce_halset_sysclk(hw, tmpu1b))
+ return;
+ }
+
+ rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x0);
+ udelay(50);
+ rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34);
+ udelay(50);
+
+ /* Clear FW RPWM for FW control LPS.*/
+ rtl_write_byte(rtlpriv, RPWM, 0x0);
+
+ /* Reset MAC-IO and CPU and Core Digital BIT(10)/11/15 */
+ tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
+ tmpu1b &= 0x73;
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b);
+ /* wait for BIT 10/11/15 to pull high automatically!! */
+ mdelay(1);
+
+ rtl_write_byte(rtlpriv, CMDR, 0);
+ rtl_write_byte(rtlpriv, TCR, 0);
+
+ /* Data sheet not define 0x562!!! Copy from WMAC!!!!! */
+ tmpu1b = rtl_read_byte(rtlpriv, 0x562);
+ tmpu1b |= 0x08;
+ rtl_write_byte(rtlpriv, 0x562, tmpu1b);
+ tmpu1b &= ~(BIT(3));
+ rtl_write_byte(rtlpriv, 0x562, tmpu1b);
+
+ /* Enable AFE clock source */
+ tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL);
+ rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, (tmpu1b | 0x01));
+ /* Delay 1.5ms */
+ mdelay(2);
+ tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL + 1);
+ rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, (tmpu1b & 0xfb));
+
+ /* Enable AFE Macro Block's Bandgap */
+ tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
+ rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | BIT(0)));
+ mdelay(1);
+
+ /* Enable AFE Mbias */
+ tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
+ rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | 0x02));
+ mdelay(1);
+
+ /* Enable LDOA15 block */
+ tmpu1b = rtl_read_byte(rtlpriv, LDOA15_CTRL);
+ rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0)));
+
+ /* Set Digital Vdd to Retention isolation Path. */
+ tmpu2b = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL);
+ rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, (tmpu2b | BIT(11)));
+
+ /* For warm reboot NIC disappera bug. */
+ tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
+ rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(13)));
+
+ rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x68);
+
+ /* Enable AFE PLL Macro Block */
+ /* We need to delay 100u before enabling PLL. */
+ udelay(200);
+ tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL);
+ rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4)));
+
+ /* for divider reset */
+ udelay(100);
+ rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) |
+ BIT(4) | BIT(6)));
+ udelay(10);
+ rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4)));
+ udelay(10);
+
+ /* Enable MAC 80MHZ clock */
+ tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL + 1);
+ rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, (tmpu1b | BIT(0)));
+ mdelay(1);
+
+ /* Release isolation AFE PLL & MD */
+ rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xA6);
+
+ /* Enable MAC clock */
+ tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
+ rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11)));
+
+ /* Enable Core digital and enable IOREG R/W */
+ tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
+ rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11)));
+
+ tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b & ~(BIT(7)));
+
+ /* enable REG_EN */
+ rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15)));
+
+ /* Switch the control path. */
+ tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
+ rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b & (~BIT(2))));
+
+ tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
+ tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6)));
+ if (!_rtl92ce_halset_sysclk(hw, tmpu1b))
+ return; /* Set failed, return to prevent hang. */
+
+ rtl_write_word(rtlpriv, CMDR, 0x07FC);
+
+ /* MH We must enable the section of code to prevent load IMEM fail. */
+ /* Load MAC register from WMAc temporarily We simulate macreg. */
+ /* txt HW will provide MAC txt later */
+ rtl_write_byte(rtlpriv, 0x6, 0x30);
+ rtl_write_byte(rtlpriv, 0x49, 0xf0);
+
+ rtl_write_byte(rtlpriv, 0x4b, 0x81);
+
+ rtl_write_byte(rtlpriv, 0xb5, 0x21);
+
+ rtl_write_byte(rtlpriv, 0xdc, 0xff);
+ rtl_write_byte(rtlpriv, 0xdd, 0xff);
+ rtl_write_byte(rtlpriv, 0xde, 0xff);
+ rtl_write_byte(rtlpriv, 0xdf, 0xff);
+
+ rtl_write_byte(rtlpriv, 0x11a, 0x00);
+ rtl_write_byte(rtlpriv, 0x11b, 0x00);
+
+ for (i = 0; i < 32; i++)
+ rtl_write_byte(rtlpriv, INIMCS_SEL + i, 0x1b);
+
+ rtl_write_byte(rtlpriv, 0x236, 0xff);
+
+ rtl_write_byte(rtlpriv, 0x503, 0x22);
+
+ if (ppsc->support_aspm && !ppsc->support_backdoor)
+ rtl_write_byte(rtlpriv, 0x560, 0x40);
+ else
+ rtl_write_byte(rtlpriv, 0x560, 0x00);
+
+ rtl_write_byte(rtlpriv, DBG_PORT, 0x91);
+
+ /* Set RX Desc Address */
+ rtl_write_dword(rtlpriv, RDQDA, rtlpci->rx_ring[RX_MPDU_QUEUE].dma);
+ rtl_write_dword(rtlpriv, RCDA, rtlpci->rx_ring[RX_CMD_QUEUE].dma);
+
+ /* Set TX Desc Address */
+ rtl_write_dword(rtlpriv, TBKDA, rtlpci->tx_ring[BK_QUEUE].dma);
+ rtl_write_dword(rtlpriv, TBEDA, rtlpci->tx_ring[BE_QUEUE].dma);
+ rtl_write_dword(rtlpriv, TVIDA, rtlpci->tx_ring[VI_QUEUE].dma);
+ rtl_write_dword(rtlpriv, TVODA, rtlpci->tx_ring[VO_QUEUE].dma);
+ rtl_write_dword(rtlpriv, TBDA, rtlpci->tx_ring[BEACON_QUEUE].dma);
+ rtl_write_dword(rtlpriv, TCDA, rtlpci->tx_ring[TXCMD_QUEUE].dma);
+ rtl_write_dword(rtlpriv, TMDA, rtlpci->tx_ring[MGNT_QUEUE].dma);
+ rtl_write_dword(rtlpriv, THPDA, rtlpci->tx_ring[HIGH_QUEUE].dma);
+ rtl_write_dword(rtlpriv, HDA, rtlpci->tx_ring[HCCA_QUEUE].dma);
+
+ rtl_write_word(rtlpriv, CMDR, 0x37FC);
+
+ /* To make sure that TxDMA can ready to download FW. */
+ /* We should reset TxDMA if IMEM RPT was not ready. */
+ do {
+ tmpu1b = rtl_read_byte(rtlpriv, TCR);
+ if ((tmpu1b & TXDMA_INIT_VALUE) == TXDMA_INIT_VALUE)
+ break;
+
+ udelay(5);
+ } while (pollingcnt--);
+
+ if (pollingcnt <= 0) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Polling TXDMA_INIT_VALUE "
+ "timeout!! Current TCR(%#x)\n", tmpu1b));
+ tmpu1b = rtl_read_byte(rtlpriv, CMDR);
+ rtl_write_byte(rtlpriv, CMDR, tmpu1b & (~TXDMA_EN));
+ udelay(2);
+ /* Reset TxDMA */
+ rtl_write_byte(rtlpriv, CMDR, tmpu1b | TXDMA_EN);
+ }
+
+ /* After MACIO reset,we must refresh LED state. */
+ if ((ppsc->rfoff_reason == RF_CHANGE_BY_IPS) ||
+ (ppsc->rfoff_reason == 0)) {
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
+ enum rf_pwrstate rfpwr_state_toset;
+ rfpwr_state_toset = _rtl92se_rf_onoff_detect(hw);
+
+ if (rfpwr_state_toset == ERFON)
+ rtl92se_sw_led_on(hw, pLed0);
+ }
+}
+
+static void _rtl92se_macconfig_after_fwdownload(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u8 i;
+ u16 tmpu2b;
+
+ /* 1. System Configure Register (Offset: 0x0000 - 0x003F) */
+
+ /* 2. Command Control Register (Offset: 0x0040 - 0x004F) */
+ /* Turn on 0x40 Command register */
+ rtl_write_word(rtlpriv, CMDR, (BBRSTN | BB_GLB_RSTN |
+ SCHEDULE_EN | MACRXEN | MACTXEN | DDMA_EN | FW2HW_EN |
+ RXDMA_EN | TXDMA_EN | HCI_RXDMA_EN | HCI_TXDMA_EN));
+
+ /* Set TCR TX DMA pre 2 FULL enable bit */
+ rtl_write_dword(rtlpriv, TCR, rtl_read_dword(rtlpriv, TCR) |
+ TXDMAPRE2FULL);
+
+ /* Set RCR */
+ rtl_write_dword(rtlpriv, RCR, rtlpci->receive_config);
+
+ /* 3. MACID Setting Register (Offset: 0x0050 - 0x007F) */
+
+ /* 4. Timing Control Register (Offset: 0x0080 - 0x009F) */
+ /* Set CCK/OFDM SIFS */
+ /* CCK SIFS shall always be 10us. */
+ rtl_write_word(rtlpriv, SIFS_CCK, 0x0a0a);
+ rtl_write_word(rtlpriv, SIFS_OFDM, 0x1010);
+
+ /* Set AckTimeout */
+ rtl_write_byte(rtlpriv, ACK_TIMEOUT, 0x40);
+
+ /* Beacon related */
+ rtl_write_word(rtlpriv, BCN_INTERVAL, 100);
+ rtl_write_word(rtlpriv, ATIMWND, 2);
+
+ /* 5. FIFO Control Register (Offset: 0x00A0 - 0x015F) */
+ /* 5.1 Initialize Number of Reserved Pages in Firmware Queue */
+ /* Firmware allocate now, associate with FW internal setting.!!! */
+
+ /* 5.2 Setting TX/RX page size 0/1/2/3/4=64/128/256/512/1024 */
+ /* 5.3 Set driver info, we only accept PHY status now. */
+ /* 5.4 Set RXDMA arbitration to control RXDMA/MAC/FW R/W for RXFIFO */
+ rtl_write_byte(rtlpriv, RXDMA, rtl_read_byte(rtlpriv, RXDMA) | BIT(6));
+
+ /* 6. Adaptive Control Register (Offset: 0x0160 - 0x01CF) */
+ /* Set RRSR to all legacy rate and HT rate
+ * CCK rate is supported by default.
+ * CCK rate will be filtered out only when associated
+ * AP does not support it.
+ * Only enable ACK rate to OFDM 24M
+ * Disable RRSR for CCK rate in A-Cut */
+
+ if (rtlhal->version == VERSION_8192S_ACUT)
+ rtl_write_byte(rtlpriv, RRSR, 0xf0);
+ else if (rtlhal->version == VERSION_8192S_BCUT)
+ rtl_write_byte(rtlpriv, RRSR, 0xff);
+ rtl_write_byte(rtlpriv, RRSR + 1, 0x01);
+ rtl_write_byte(rtlpriv, RRSR + 2, 0x00);
+
+ /* A-Cut IC do not support CCK rate. We forbid ARFR to */
+ /* fallback to CCK rate */
+ for (i = 0; i < 8; i++) {
+ /*Disable RRSR for CCK rate in A-Cut */
+ if (rtlhal->version == VERSION_8192S_ACUT)
+ rtl_write_dword(rtlpriv, ARFR0 + i * 4, 0x1f0ff0f0);
+ }
+
+ /* Different rate use different AMPDU size */
+ /* MCS32/ MCS15_SG use max AMPDU size 15*2=30K */
+ rtl_write_byte(rtlpriv, AGGLEN_LMT_H, 0x0f);
+ /* MCS0/1/2/3 use max AMPDU size 4*2=8K */
+ rtl_write_word(rtlpriv, AGGLEN_LMT_L, 0x7442);
+ /* MCS4/5 use max AMPDU size 8*2=16K 6/7 use 10*2=20K */
+ rtl_write_word(rtlpriv, AGGLEN_LMT_L + 2, 0xddd7);
+ /* MCS8/9 use max AMPDU size 8*2=16K 10/11 use 10*2=20K */
+ rtl_write_word(rtlpriv, AGGLEN_LMT_L + 4, 0xd772);
+ /* MCS12/13/14/15 use max AMPDU size 15*2=30K */
+ rtl_write_word(rtlpriv, AGGLEN_LMT_L + 6, 0xfffd);
+
+ /* Set Data / Response auto rate fallack retry count */
+ rtl_write_dword(rtlpriv, DARFRC, 0x04010000);
+ rtl_write_dword(rtlpriv, DARFRC + 4, 0x09070605);
+ rtl_write_dword(rtlpriv, RARFRC, 0x04010000);
+ rtl_write_dword(rtlpriv, RARFRC + 4, 0x09070605);
+
+ /* 7. EDCA Setting Register (Offset: 0x01D0 - 0x01FF) */
+ /* Set all rate to support SG */
+ rtl_write_word(rtlpriv, SG_RATE, 0xFFFF);
+
+ /* 8. WMAC, BA, and CCX related Register (Offset: 0x0200 - 0x023F) */
+ /* Set NAV protection length */
+ rtl_write_word(rtlpriv, NAV_PROT_LEN, 0x0080);
+ /* CF-END Threshold */
+ rtl_write_byte(rtlpriv, CFEND_TH, 0xFF);
+ /* Set AMPDU minimum space */
+ rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, 0x07);
+ /* Set TXOP stall control for several queue/HI/BCN/MGT/ */
+ rtl_write_byte(rtlpriv, TXOP_STALL_CTRL, 0x00);
+
+ /* 9. Security Control Register (Offset: 0x0240 - 0x025F) */
+ /* 10. Power Save Control Register (Offset: 0x0260 - 0x02DF) */
+ /* 11. General Purpose Register (Offset: 0x02E0 - 0x02FF) */
+ /* 12. Host Interrupt Status Register (Offset: 0x0300 - 0x030F) */
+ /* 13. Test Mode and Debug Control Register (Offset: 0x0310 - 0x034F) */
+
+ /* 14. Set driver info, we only accept PHY status now. */
+ rtl_write_byte(rtlpriv, RXDRVINFO_SZ, 4);
+
+ /* 15. For EEPROM R/W Workaround */
+ /* 16. For EFUSE to share REG_SYS_FUNC_EN with EEPROM!!! */
+ tmpu2b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, tmpu2b | BIT(13));
+ tmpu2b = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL);
+ rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, tmpu2b & (~BIT(8)));
+
+ /* 17. For EFUSE */
+ /* We may R/W EFUSE in EEPROM mode */
+ if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
+ u8 tempval;
+
+ tempval = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL + 1);
+ tempval &= 0xFE;
+ rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, tempval);
+
+ /* Change Program timing */
+ rtl_write_byte(rtlpriv, REG_EFUSE_CTRL + 3, 0x72);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("EFUSE CONFIG OK\n"));
+ }
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n"));
+
+}
+
+static void _rtl92se_hw_configure(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ u8 reg_bw_opmode = 0;
+ u32 reg_ratr = 0, reg_rrsr = 0;
+ u8 regtmp = 0;
+
+ reg_bw_opmode = BW_OPMODE_20MHZ;
+ reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS |
+ RATE_ALL_OFDM_2SS;
+ reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+
+ regtmp = rtl_read_byte(rtlpriv, INIRTSMCS_SEL);
+ reg_rrsr = ((reg_rrsr & 0x000fffff) << 8) | regtmp;
+ rtl_write_dword(rtlpriv, INIRTSMCS_SEL, reg_rrsr);
+ rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
+
+ /* Set Retry Limit here */
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
+ (u8 *)(&rtlpci->shortretry_limit));
+
+ rtl_write_byte(rtlpriv, MLT, 0x8f);
+
+ /* For Min Spacing configuration. */
+ switch (rtlphy->rf_type) {
+ case RF_1T2R:
+ case RF_1T1R:
+ rtlhal->minspace_cfg = (MAX_MSS_DENSITY_1T << 3);
+ break;
+ case RF_2T2R:
+ case RF_2T2R_GREEN:
+ rtlhal->minspace_cfg = (MAX_MSS_DENSITY_2T << 3);
+ break;
+ }
+ rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, rtlhal->minspace_cfg);
+}
+
+int rtl92se_hw_init(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 tmp_byte = 0;
+
+ bool rtstatus = true;
+ u8 tmp_u1b;
+ int err = false;
+ u8 i;
+ int wdcapra_add[] = {
+ EDCAPARA_BE, EDCAPARA_BK,
+ EDCAPARA_VI, EDCAPARA_VO};
+ u8 secr_value = 0x0;
+
+ rtlpci->being_init_adapter = true;
+
+ rtlpriv->intf_ops->disable_aspm(hw);
+
+ /* 1. MAC Initialize */
+ /* Before FW download, we have to set some MAC register */
+ _rtl92se_macconfig_before_fwdownload(hw);
+
+ rtlhal->version = (enum version_8192s)((rtl_read_dword(rtlpriv,
+ PMC_FSM) >> 16) & 0xF);
+
+ rtl8192se_gpiobit3_cfg_inputmode(hw);
+
+ /* 2. download firmware */
+ rtstatus = rtl92s_download_fw(hw);
+ if (!rtstatus) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("Failed to download FW. "
+ "Init HW without FW now.., Please copy FW into"
+ "/lib/firmware/rtlwifi\n"));
+ rtlhal->fw_ready = false;
+ } else {
+ rtlhal->fw_ready = true;
+ }
+
+ /* After FW download, we have to reset MAC register */
+ _rtl92se_macconfig_after_fwdownload(hw);
+
+ /*Retrieve default FW Cmd IO map. */
+ rtlhal->fwcmd_iomap = rtl_read_word(rtlpriv, LBUS_MON_ADDR);
+ rtlhal->fwcmd_ioparam = rtl_read_dword(rtlpriv, LBUS_ADDR_MASK);
+
+ /* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */
+ if (rtl92s_phy_mac_config(hw) != true) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("MAC Config failed\n"));
+ return rtstatus;
+ }
+
+ /* Make sure BB/RF write OK. We should prevent enter IPS. radio off. */
+ /* We must set flag avoid BB/RF config period later!! */
+ rtl_write_dword(rtlpriv, CMDR, 0x37FC);
+
+ /* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */
+ if (rtl92s_phy_bb_config(hw) != true) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("BB Config failed\n"));
+ return rtstatus;
+ }
+
+ /* 5. Initiailze RF RAIO_A.txt RF RAIO_B.txt */
+ /* Before initalizing RF. We can not use FW to do RF-R/W. */
+
+ rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
+
+ /* RF Power Save */
+#if 0
+ /* H/W or S/W RF OFF before sleep. */
+ if (rtlpriv->psc.rfoff_reason > RF_CHANGE_BY_PS) {
+ u32 rfoffreason = rtlpriv->psc.rfoff_reason;
+
+ rtlpriv->psc.rfoff_reason = RF_CHANGE_BY_INIT;
+ rtlpriv->psc.rfpwr_state = ERFON;
+ rtl_ps_set_rf_state(hw, ERFOFF, rfoffreason, true);
+ } else {
+ /* gpio radio on/off is out of adapter start */
+ if (rtlpriv->psc.hwradiooff == false) {
+ rtlpriv->psc.rfpwr_state = ERFON;
+ rtlpriv->psc.rfoff_reason = 0;
+ }
+ }
+#endif
+
+ /* Before RF-R/W we must execute the IO from Scott's suggestion. */
+ rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, 0xDB);
+ if (rtlhal->version == VERSION_8192S_ACUT)
+ rtl_write_byte(rtlpriv, SPS1_CTRL + 3, 0x07);
+ else
+ rtl_write_byte(rtlpriv, RF_CTRL, 0x07);
+
+ if (rtl92s_phy_rf_config(hw) != true) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("RF Config failed\n"));
+ return rtstatus;
+ }
+
+ /* After read predefined TXT, we must set BB/MAC/RF
+ * register as our requirement */
+
+ rtlphy->rfreg_chnlval[0] = rtl92s_phy_query_rf_reg(hw,
+ (enum radio_path)0,
+ RF_CHNLBW,
+ RFREG_OFFSET_MASK);
+ rtlphy->rfreg_chnlval[1] = rtl92s_phy_query_rf_reg(hw,
+ (enum radio_path)1,
+ RF_CHNLBW,
+ RFREG_OFFSET_MASK);
+
+ /*---- Set CCK and OFDM Block "ON"----*/
+ rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
+ rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
+
+ /*3 Set Hardware(Do nothing now) */
+ _rtl92se_hw_configure(hw);
+
+ /* Read EEPROM TX power index and PHY_REG_PG.txt to capture correct */
+ /* TX power index for different rate set. */
+ /* Get original hw reg values */
+ rtl92s_phy_get_hw_reg_originalvalue(hw);
+ /* Write correct tx power index */
+ rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
+
+ /* We must set MAC address after firmware download. */
+ for (i = 0; i < 6; i++)
+ rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]);
+
+ /* EEPROM R/W workaround */
+ tmp_u1b = rtl_read_byte(rtlpriv, MAC_PINMUX_CFG);
+ rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, tmp_u1b & (~BIT(3)));
+
+ rtl_write_byte(rtlpriv, 0x4d, 0x0);
+
+ if (hal_get_firmwareversion(rtlpriv) >= 0x49) {
+ tmp_byte = rtl_read_byte(rtlpriv, FW_RSVD_PG_CRTL) & (~BIT(4));
+ tmp_byte = tmp_byte | BIT(5);
+ rtl_write_byte(rtlpriv, FW_RSVD_PG_CRTL, tmp_byte);
+ rtl_write_dword(rtlpriv, TXDESC_MSK, 0xFFFFCFFF);
+ }
+
+ /* We enable high power and RA related mechanism after NIC
+ * initialized. */
+ rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_INIT);
+
+ /* Add to prevent ASPM bug. */
+ /* Always enable hst and NIC clock request. */
+ rtl92s_phy_switch_ephy_parameter(hw);
+
+ /* Security related
+ * 1. Clear all H/W keys.
+ * 2. Enable H/W encryption/decryption. */
+ rtl_cam_reset_all_entry(hw);
+ secr_value |= SCR_TXENCENABLE;
+ secr_value |= SCR_RXENCENABLE;
+ secr_value |= SCR_NOSKMC;
+ rtl_write_byte(rtlpriv, REG_SECR, secr_value);
+
+ for (i = 0; i < 4; i++)
+ rtl_write_dword(rtlpriv, wdcapra_add[i], 0x5e4322);
+
+ if (rtlphy->rf_type == RF_1T2R) {
+ bool mrc2set = true;
+ /* Turn on B-Path */
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC, (u8 *)&mrc2set);
+ }
+
+ rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON);
+ rtl92s_dm_init(hw);
+ rtlpci->being_init_adapter = false;
+
+ return err;
+}
+
+void rtl92se_set_mac_addr(struct rtl_io *io, const u8 * addr)
+{
+}
+
+void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u32 reg_rcr = rtlpci->receive_config;
+
+ if (rtlpriv->psc.rfpwr_state != ERFON)
+ return;
+
+ if (check_bssid == true) {
+ reg_rcr |= (RCR_CBSSID);
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
+ } else if (check_bssid == false) {
+ reg_rcr &= (~RCR_CBSSID);
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
+ }
+
+}
+
+static int _rtl92se_set_media_status(struct ieee80211_hw *hw,
+ enum nl80211_iftype type)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 bt_msr = rtl_read_byte(rtlpriv, MSR);
+ enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
+ u32 temp;
+ bt_msr &= ~MSR_LINK_MASK;
+
+ switch (type) {
+ case NL80211_IFTYPE_UNSPECIFIED:
+ bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT);
+ ledaction = LED_CTL_LINK;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Set Network type to NO LINK!\n"));
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ bt_msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Set Network type to Ad Hoc!\n"));
+ break;
+ case NL80211_IFTYPE_STATION:
+ bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT);
+ ledaction = LED_CTL_LINK;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Set Network type to STA!\n"));
+ break;
+ case NL80211_IFTYPE_AP:
+ bt_msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Set Network type to AP!\n"));
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Network type %d not support!\n", type));
+ return 1;
+ break;
+
+ }
+
+ rtl_write_byte(rtlpriv, (MSR), bt_msr);
+
+ temp = rtl_read_dword(rtlpriv, TCR);
+ rtl_write_dword(rtlpriv, TCR, temp & (~BIT(8)));
+ rtl_write_dword(rtlpriv, TCR, temp | BIT(8));
+
+
+ return 0;
+}
+
+/* HW_VAR_MEDIA_STATUS & HW_VAR_CECHK_BSSID */
+int rtl92se_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (_rtl92se_set_media_status(hw, type))
+ return -EOPNOTSUPP;
+
+ if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
+ if (type != NL80211_IFTYPE_AP)
+ rtl92se_set_check_bssid(hw, true);
+ } else {
+ rtl92se_set_check_bssid(hw, false);
+ }
+
+ return 0;
+}
+
+/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */
+void rtl92se_set_qos(struct ieee80211_hw *hw, int aci)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ rtl92s_dm_init_edca_turbo(hw);
+
+ switch (aci) {
+ case AC1_BK:
+ rtl_write_dword(rtlpriv, EDCAPARA_BK, 0xa44f);
+ break;
+ case AC0_BE:
+ /* rtl_write_dword(rtlpriv, EDCAPARA_BE, u4b_ac_param); */
+ break;
+ case AC2_VI:
+ rtl_write_dword(rtlpriv, EDCAPARA_VI, 0x5e4322);
+ break;
+ case AC3_VO:
+ rtl_write_dword(rtlpriv, EDCAPARA_VO, 0x2f3222);
+ break;
+ default:
+ RT_ASSERT(false, ("invalid aci: %d !\n", aci));
+ break;
+ }
+}
+
+void rtl92se_enable_interrupt(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ rtl_write_dword(rtlpriv, INTA_MASK, rtlpci->irq_mask[0]);
+ /* Support Bit 32-37(Assign as Bit 0-5) interrupt setting now */
+ rtl_write_dword(rtlpriv, INTA_MASK + 4, rtlpci->irq_mask[1] & 0x3F);
+
+ rtlpci->irq_enabled = true;
+}
+
+void rtl92se_disable_interrupt(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ rtl_write_dword(rtlpriv, INTA_MASK, 0);
+ rtl_write_dword(rtlpriv, INTA_MASK + 4, 0);
+
+ rtlpci->irq_enabled = false;
+}
+
+
+static u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 waitcnt = 100;
+ bool result = false;
+ u8 tmp;
+
+ rtl_write_byte(rtlpriv, SYS_CLKR + 1, data);
+
+ /* Wait the MAC synchronized. */
+ udelay(400);
+
+ /* Check if it is set ready. */
+ tmp = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
+ result = ((tmp & BIT(7)) == (data & BIT(7)));
+
+ if ((data & (BIT(6) | BIT(7))) == false) {
+ waitcnt = 100;
+ tmp = 0;
+
+ while (1) {
+ waitcnt--;
+ tmp = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
+
+ if ((tmp & BIT(6)))
+ break;
+
+ printk(KERN_ERR "wait for BIT(6) return value %x\n",
+ tmp);
+
+ if (waitcnt == 0)
+ break;
+ udelay(10);
+ }
+
+ if (waitcnt == 0)
+ result = false;
+ else
+ result = true;
+ }
+
+ return result;
+}
+
+static void _rtl92s_phy_set_rfhalt(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ u8 u1btmp;
+
+ if (rtlhal->driver_going2unload)
+ rtl_write_byte(rtlpriv, 0x560, 0x0);
+
+ /* Power save for BB/RF */
+ u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL);
+ u1btmp |= BIT(0);
+ rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp);
+ rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0);
+ rtl_write_byte(rtlpriv, TXPAUSE, 0xFF);
+ rtl_write_word(rtlpriv, CMDR, 0x57FC);
+ udelay(100);
+ rtl_write_word(rtlpriv, CMDR, 0x77FC);
+ rtl_write_byte(rtlpriv, PHY_CCA, 0x0);
+ udelay(10);
+ rtl_write_word(rtlpriv, CMDR, 0x37FC);
+ udelay(10);
+ rtl_write_word(rtlpriv, CMDR, 0x77FC);
+ udelay(10);
+ rtl_write_word(rtlpriv, CMDR, 0x57FC);
+ rtl_write_word(rtlpriv, CMDR, 0x0000);
+
+ if (rtlhal->driver_going2unload) {
+ u1btmp = rtl_read_byte(rtlpriv, (REG_SYS_FUNC_EN + 1));
+ u1btmp &= ~(BIT(0));
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1btmp);
+ }
+
+ u1btmp = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
+
+ /* Add description. After switch control path. register
+ * after page1 will be invisible. We can not do any IO
+ * for register>0x40. After resume&MACIO reset, we need
+ * to remember previous reg content. */
+ if (u1btmp & BIT(7)) {
+ u1btmp &= ~(BIT(6) | BIT(7));
+ if (!_rtl92s_set_sysclk(hw, u1btmp)) {
+ printk(KERN_ERR "Switch ctrl path fail\n");
+ return;
+ }
+ }
+
+ /* Power save for MAC */
+ if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS &&
+ !rtlhal->driver_going2unload) {
+ /* enable LED function */
+ rtl_write_byte(rtlpriv, 0x03, 0xF9);
+ /* SW/HW radio off or halt adapter!! For example S3/S4 */
+ } else {
+ /* LED function disable. Power range is about 8mA now. */
+ /* if write 0xF1 disconnet_pci power
+ * ifconfig wlan0 down power are both high 35:70 */
+ /* if write oxF9 disconnet_pci power
+ * ifconfig wlan0 down power are both low 12:45*/
+ rtl_write_byte(rtlpriv, 0x03, 0xF9);
+ }
+
+ rtl_write_byte(rtlpriv, SYS_CLKR + 1, 0x70);
+ rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, 0x68);
+ rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x00);
+ rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34);
+ rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, 0x0E);
+ RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+
+}
+
+static void _rtl92se_gen_refreshledstate(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
+
+ if (rtlpci->up_first_time == 1)
+ return;
+
+ if (rtlpriv->psc.rfoff_reason == RF_CHANGE_BY_IPS)
+ rtl92se_sw_led_on(hw, pLed0);
+ else
+ rtl92se_sw_led_off(hw, pLed0);
+}
+
+
+static void _rtl92se_power_domain_init(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u16 tmpu2b;
+ u8 tmpu1b;
+
+ rtlpriv->psc.pwrdomain_protect = true;
+
+ tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
+ if (tmpu1b & BIT(7)) {
+ tmpu1b &= ~(BIT(6) | BIT(7));
+ if (!_rtl92s_set_sysclk(hw, tmpu1b)) {
+ rtlpriv->psc.pwrdomain_protect = false;
+ return;
+ }
+ }
+
+ rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x0);
+ rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34);
+
+ /* Reset MAC-IO and CPU and Core Digital BIT10/11/15 */
+ tmpu1b = rtl_read_byte(rtlpriv, SYS_FUNC_EN + 1);
+
+ /* If IPS we need to turn LED on. So we not
+ * not disable BIT 3/7 of reg3. */
+ if (rtlpriv->psc.rfoff_reason & (RF_CHANGE_BY_IPS | RF_CHANGE_BY_HW))
+ tmpu1b &= 0xFB;
+ else
+ tmpu1b &= 0x73;
+
+ rtl_write_byte(rtlpriv, SYS_FUNC_EN + 1, tmpu1b);
+ /* wait for BIT 10/11/15 to pull high automatically!! */
+ mdelay(1);
+
+ rtl_write_byte(rtlpriv, CMDR, 0);
+ rtl_write_byte(rtlpriv, TCR, 0);
+
+ /* Data sheet not define 0x562!!! Copy from WMAC!!!!! */
+ tmpu1b = rtl_read_byte(rtlpriv, 0x562);
+ tmpu1b |= 0x08;
+ rtl_write_byte(rtlpriv, 0x562, tmpu1b);
+ tmpu1b &= ~(BIT(3));
+ rtl_write_byte(rtlpriv, 0x562, tmpu1b);
+
+ /* Enable AFE clock source */
+ tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL);
+ rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, (tmpu1b | 0x01));
+ /* Delay 1.5ms */
+ udelay(1500);
+ tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL + 1);
+ rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, (tmpu1b & 0xfb));
+
+ /* Enable AFE Macro Block's Bandgap */
+ tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
+ rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | BIT(0)));
+ mdelay(1);
+
+ /* Enable AFE Mbias */
+ tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
+ rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | 0x02));
+ mdelay(1);
+
+ /* Enable LDOA15 block */
+ tmpu1b = rtl_read_byte(rtlpriv, LDOA15_CTRL);
+ rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0)));
+
+ /* Set Digital Vdd to Retention isolation Path. */
+ tmpu2b = rtl_read_word(rtlpriv, SYS_ISO_CTRL);
+ rtl_write_word(rtlpriv, SYS_ISO_CTRL, (tmpu2b | BIT(11)));
+
+
+ /* For warm reboot NIC disappera bug. */
+ tmpu2b = rtl_read_word(rtlpriv, SYS_FUNC_EN);
+ rtl_write_word(rtlpriv, SYS_FUNC_EN, (tmpu2b | BIT(13)));
+
+ rtl_write_byte(rtlpriv, SYS_ISO_CTRL + 1, 0x68);
+
+ /* Enable AFE PLL Macro Block */
+ tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL);
+ rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4)));
+ /* Enable MAC 80MHZ clock */
+ tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL + 1);
+ rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, (tmpu1b | BIT(0)));
+ mdelay(1);
+
+ /* Release isolation AFE PLL & MD */
+ rtl_write_byte(rtlpriv, SYS_ISO_CTRL, 0xA6);
+
+ /* Enable MAC clock */
+ tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
+ rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11)));
+
+ /* Enable Core digital and enable IOREG R/W */
+ tmpu2b = rtl_read_word(rtlpriv, SYS_FUNC_EN);
+ rtl_write_word(rtlpriv, SYS_FUNC_EN, (tmpu2b | BIT(11)));
+ /* enable REG_EN */
+ rtl_write_word(rtlpriv, SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15)));
+
+ /* Switch the control path. */
+ tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
+ rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b & (~BIT(2))));
+
+ tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
+ tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6)));
+ if (!_rtl92s_set_sysclk(hw, tmpu1b)) {
+ rtlpriv->psc.pwrdomain_protect = false;
+ return;
+ }
+
+ rtl_write_word(rtlpriv, CMDR, 0x37FC);
+
+ /* After MACIO reset,we must refresh LED state. */
+ _rtl92se_gen_refreshledstate(hw);
+
+ rtlpriv->psc.pwrdomain_protect = false;
+}
+
+void rtl92se_card_disable(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ enum nl80211_iftype opmode;
+ u8 wait = 30;
+
+ rtlpriv->intf_ops->enable_aspm(hw);
+
+ if (rtlpci->driver_is_goingto_unload ||
+ ppsc->rfoff_reason > RF_CHANGE_BY_PS)
+ rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
+
+ /* we should chnge GPIO to input mode
+ * this will drop away current about 25mA*/
+ rtl8192se_gpiobit3_cfg_inputmode(hw);
+
+ /* this is very important for ips power save */
+ while (wait-- >= 10 && rtlpriv->psc.pwrdomain_protect) {
+ if (rtlpriv->psc.pwrdomain_protect)
+ mdelay(20);
+ else
+ break;
+ }
+
+ mac->link_state = MAC80211_NOLINK;
+ opmode = NL80211_IFTYPE_UNSPECIFIED;
+ _rtl92se_set_media_status(hw, opmode);
+
+ _rtl92s_phy_set_rfhalt(hw);
+ udelay(100);
+}
+
+void rtl92se_interrupt_recognized(struct ieee80211_hw *hw, u32 *p_inta,
+ u32 *p_intb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
+ rtl_write_dword(rtlpriv, ISR, *p_inta);
+
+ *p_intb = rtl_read_dword(rtlpriv, ISR + 4) & rtlpci->irq_mask[1];
+ rtl_write_dword(rtlpriv, ISR + 4, *p_intb);
+}
+
+void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u16 bcntime_cfg = 0;
+ u16 bcn_cw = 6, bcn_ifs = 0xf;
+ u16 atim_window = 2;
+
+ /* ATIM Window (in unit of TU). */
+ rtl_write_word(rtlpriv, ATIMWND, atim_window);
+
+ /* Beacon interval (in unit of TU). */
+ rtl_write_word(rtlpriv, BCN_INTERVAL, mac->beacon_interval);
+
+ /* DrvErlyInt (in unit of TU). (Time to send
+ * interrupt to notify driver to change
+ * beacon content) */
+ rtl_write_word(rtlpriv, BCN_DRV_EARLY_INT, 10 << 4);
+
+ /* BcnDMATIM(in unit of us). Indicates the
+ * time before TBTT to perform beacon queue DMA */
+ rtl_write_word(rtlpriv, BCN_DMATIME, 256);
+
+ /* Force beacon frame transmission even
+ * after receiving beacon frame from
+ * other ad hoc STA */
+ rtl_write_byte(rtlpriv, BCN_ERR_THRESH, 100);
+
+ /* Beacon Time Configuration */
+ if (mac->opmode == NL80211_IFTYPE_ADHOC)
+ bcntime_cfg |= (bcn_cw << BCN_TCFG_CW_SHIFT);
+
+ /* TODO: bcn_ifs may required to be changed on ASIC */
+ bcntime_cfg |= bcn_ifs << BCN_TCFG_IFS;
+
+ /*for beacon changed */
+ rtl92s_phy_set_beacon_hwreg(hw, mac->beacon_interval);
+}
+
+void rtl92se_set_beacon_interval(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u16 bcn_interval = mac->beacon_interval;
+
+ /* Beacon interval (in unit of TU). */
+ rtl_write_word(rtlpriv, BCN_INTERVAL, bcn_interval);
+ /* 2008.10.24 added by tynli for beacon changed. */
+ rtl92s_phy_set_beacon_hwreg(hw, bcn_interval);
+}
+
+void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw,
+ u32 add_msr, u32 rm_msr)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
+ ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr));
+
+ if (add_msr)
+ rtlpci->irq_mask[0] |= add_msr;
+
+ if (rm_msr)
+ rtlpci->irq_mask[0] &= (~rm_msr);
+
+ rtl92se_disable_interrupt(hw);
+ rtl92se_enable_interrupt(hw);
+}
+
+static void _rtl8192se_get_IC_Inferiority(struct ieee80211_hw *hw)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ u8 efuse_id;
+
+ rtlhal->ic_class = IC_INFERIORITY_A;
+
+ /* Only retrieving while using EFUSE. */
+ if ((rtlefuse->epromtype == EEPROM_BOOT_EFUSE) &&
+ !rtlefuse->autoload_failflag) {
+ efuse_id = efuse_read_1byte(hw, EFUSE_IC_ID_OFFSET);
+
+ if (efuse_id == 0xfe)
+ rtlhal->ic_class = IC_INFERIORITY_B;
+ }
+}
+
+static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ u16 i, usvalue;
+ u16 eeprom_id;
+ u8 tempval;
+ u8 hwinfo[HWSET_MAX_SIZE_92S];
+ u8 rf_path, index;
+
+ if (rtlefuse->epromtype == EEPROM_93C46) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("RTL819X Not boot from eeprom, check it !!"));
+ } else if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
+ rtl_efuse_shadow_map_update(hw);
+
+ memcpy((void *)hwinfo, (void *)
+ &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
+ HWSET_MAX_SIZE_92S);
+ }
+
+ RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
+ hwinfo, HWSET_MAX_SIZE_92S);
+
+ eeprom_id = *((u16 *)&hwinfo[0]);
+ if (eeprom_id != RTL8190_EEPROM_ID) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
+ rtlefuse->autoload_failflag = true;
+ } else {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+ rtlefuse->autoload_failflag = false;
+ }
+
+ if (rtlefuse->autoload_failflag == true)
+ return;
+
+ _rtl8192se_get_IC_Inferiority(hw);
+
+ /* Read IC Version && Channel Plan */
+ /* VID, DID SE 0xA-D */
+ rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
+ rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID];
+ rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID];
+ rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID];
+ rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("EEPROMId = 0x%4x\n", eeprom_id));
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid));
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did));
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid));
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid));
+
+ for (i = 0; i < 6; i += 2) {
+ usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
+ *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
+ }
+
+ for (i = 0; i < 6; i++)
+ rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]);
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ (MAC_FMT "\n", MAC_ARG(rtlefuse->dev_addr)));
+
+ /* Get Tx Power Level by Channel */
+ /* Read Tx power of Channel 1 ~ 14 from EEPROM. */
+ /* 92S suupport RF A & B */
+ for (rf_path = 0; rf_path < 2; rf_path++) {
+ for (i = 0; i < 3; i++) {
+ /* Read CCK RF A & B Tx power */
+ rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][i] =
+ hwinfo[EEPROM_TXPOWERBASE + rf_path * 3 + i];
+
+ /* Read OFDM RF A & B Tx power for 1T */
+ rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] =
+ hwinfo[EEPROM_TXPOWERBASE + 6 + rf_path * 3 + i];
+
+ /* Read OFDM RF A & B Tx power for 2T */
+ rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]
+ = hwinfo[EEPROM_TXPOWERBASE + 12 +
+ rf_path * 3 + i];
+ }
+ }
+
+ for (rf_path = 0; rf_path < 2; rf_path++)
+ for (i = 0; i < 3; i++)
+ RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
+ ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path,
+ i, rtlefuse->eeprom_chnlarea_txpwr_cck
+ [rf_path][i]));
+ for (rf_path = 0; rf_path < 2; rf_path++)
+ for (i = 0; i < 3; i++)
+ RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
+ ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
+ rf_path, i,
+ rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
+ [rf_path][i]));
+ for (rf_path = 0; rf_path < 2; rf_path++)
+ for (i = 0; i < 3; i++)
+ RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
+ ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
+ rf_path, i,
+ rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif
+ [rf_path][i]));
+
+ for (rf_path = 0; rf_path < 2; rf_path++) {
+
+ /* Assign dedicated channel tx power */
+ for (i = 0; i < 14; i++) {
+ /* channel 1~3 use the same Tx Power Level. */
+ if (i < 3)
+ index = 0;
+ /* Channel 4-8 */
+ else if (i < 8)
+ index = 1;
+ /* Channel 9-14 */
+ else
+ index = 2;
+
+ /* Record A & B CCK /OFDM - 1T/2T Channel area
+ * tx power */
+ rtlefuse->txpwrlevel_cck[rf_path][i] =
+ rtlefuse->eeprom_chnlarea_txpwr_cck
+ [rf_path][index];
+ rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
+ rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
+ [rf_path][index];
+ rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =
+ rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif
+ [rf_path][index];
+ }
+
+ for (i = 0; i < 14; i++) {
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = "
+ "[0x%x / 0x%x / 0x%x]\n", rf_path, i,
+ rtlefuse->txpwrlevel_cck[rf_path][i],
+ rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
+ rtlefuse->txpwrlevel_ht40_2s[rf_path][i]));
+ }
+ }
+
+ for (rf_path = 0; rf_path < 2; rf_path++) {
+ for (i = 0; i < 3; i++) {
+ /* Read Power diff limit. */
+ rtlefuse->eeprom_pwrgroup[rf_path][i] =
+ hwinfo[EEPROM_TXPWRGROUP + rf_path * 3 + i];
+ }
+ }
+
+ for (rf_path = 0; rf_path < 2; rf_path++) {
+ /* Fill Pwr group */
+ for (i = 0; i < 14; i++) {
+ /* Chanel 1-3 */
+ if (i < 3)
+ index = 0;
+ /* Channel 4-8 */
+ else if (i < 8)
+ index = 1;
+ /* Channel 9-13 */
+ else
+ index = 2;
+
+ rtlefuse->pwrgroup_ht20[rf_path][i] =
+ (rtlefuse->eeprom_pwrgroup[rf_path][index] &
+ 0xf);
+ rtlefuse->pwrgroup_ht40[rf_path][i] =
+ ((rtlefuse->eeprom_pwrgroup[rf_path][index] &
+ 0xf0) >> 4);
+
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("RF-%d pwrgroup_ht20[%d] = 0x%x\n",
+ rf_path, i,
+ rtlefuse->pwrgroup_ht20[rf_path][i]));
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("RF-%d pwrgroup_ht40[%d] = 0x%x\n",
+ rf_path, i,
+ rtlefuse->pwrgroup_ht40[rf_path][i]));
+ }
+ }
+
+ for (i = 0; i < 14; i++) {
+ /* Read tx power difference between HT OFDM 20/40 MHZ */
+ /* channel 1-3 */
+ if (i < 3)
+ index = 0;
+ /* Channel 4-8 */
+ else if (i < 8)
+ index = 1;
+ /* Channel 9-14 */
+ else
+ index = 2;
+
+ tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_HT20_DIFF +
+ index]) & 0xff;
+ rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF);
+ rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] =
+ ((tempval >> 4) & 0xF);
+
+ /* Read OFDM<->HT tx power diff */
+ /* Channel 1-3 */
+ if (i < 3)
+ index = 0;
+ /* Channel 4-8 */
+ else if (i < 8)
+ index = 0x11;
+ /* Channel 9-14 */
+ else
+ index = 1;
+
+ tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF + index])
+ & 0xff;
+ rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] =
+ (tempval & 0xF);
+ rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] =
+ ((tempval >> 4) & 0xF);
+
+ tempval = (*(u8 *)&hwinfo[TX_PWR_SAFETY_CHK]);
+ rtlefuse->txpwr_safetyflag = (tempval & 0x01);
+ }
+
+ rtlefuse->eeprom_regulatory = 0;
+ if (rtlefuse->eeprom_version >= 2) {
+ /* BIT(0)~2 */
+ if (rtlefuse->eeprom_version >= 4)
+ rtlefuse->eeprom_regulatory =
+ (hwinfo[EEPROM_REGULATORY] & 0x7);
+ else /* BIT(0) */
+ rtlefuse->eeprom_regulatory =
+ (hwinfo[EEPROM_REGULATORY] & 0x1);
+ }
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory));
+
+ for (i = 0; i < 14; i++)
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i,
+ rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]));
+ for (i = 0; i < 14; i++)
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i,
+ rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]));
+ for (i = 0; i < 14; i++)
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i,
+ rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]));
+ for (i = 0; i < 14; i++)
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i,
+ rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]));
+
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPwrSafetyFlag = %d\n",
+ rtlefuse->txpwr_safetyflag));
+
+ /* Read RF-indication and Tx Power gain
+ * index diff of legacy to HT OFDM rate. */
+ tempval = (*(u8 *)&hwinfo[EEPROM_RFIND_POWERDIFF]) & 0xff;
+ rtlefuse->eeprom_txpowerdiff = tempval;
+ rtlefuse->legacy_httxpowerdiff =
+ rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0];
+
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPowerDiff = %#x\n",
+ rtlefuse->eeprom_txpowerdiff));
+
+ /* Get TSSI value for each path. */
+ usvalue = *(u16 *)&hwinfo[EEPROM_TSSI_A];
+ rtlefuse->eeprom_tssi[RF90_PATH_A] = (u8)((usvalue & 0xff00) >> 8);
+ usvalue = *(u8 *)&hwinfo[EEPROM_TSSI_B];
+ rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff);
+
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TSSI_A = 0x%x, TSSI_B = 0x%x\n",
+ rtlefuse->eeprom_tssi[RF90_PATH_A],
+ rtlefuse->eeprom_tssi[RF90_PATH_B]));
+
+ /* Read antenna tx power offset of B/C/D to A from EEPROM */
+ /* and read ThermalMeter from EEPROM */
+ tempval = *(u8 *)&hwinfo[EEPROM_THERMALMETER];
+ rtlefuse->eeprom_thermalmeter = tempval;
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("thermalmeter = 0x%x\n",
+ rtlefuse->eeprom_thermalmeter));
+
+ /* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */
+ rtlefuse->thermalmeter[0] = (rtlefuse->eeprom_thermalmeter & 0x1f);
+ rtlefuse->tssi_13dbm = rtlefuse->eeprom_thermalmeter * 100;
+
+ /* Read CrystalCap from EEPROM */
+ tempval = (*(u8 *)&hwinfo[EEPROM_CRYSTALCAP]) >> 4;
+ rtlefuse->eeprom_crystalcap = tempval;
+ /* CrystalCap, BIT(12)~15 */
+ rtlefuse->crystalcap = rtlefuse->eeprom_crystalcap;
+
+ /* Read IC Version && Channel Plan */
+ /* Version ID, Channel plan */
+ rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
+ rtlefuse->txpwr_fromeprom = true;
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("EEPROM ChannelPlan = 0x%4x\n",
+ rtlefuse->eeprom_channelplan));
+
+ /* Read Customer ID or Board Type!!! */
+ tempval = *(u8 *)&hwinfo[EEPROM_BOARDTYPE];
+ /* Change RF type definition */
+ if (tempval == 0)
+ rtlphy->rf_type = RF_2T2R;
+ else if (tempval == 1)
+ rtlphy->rf_type = RF_1T2R;
+ else if (tempval == 2)
+ rtlphy->rf_type = RF_1T2R;
+ else if (tempval == 3)
+ rtlphy->rf_type = RF_1T1R;
+
+ /* 1T2R but 1SS (1x1 receive combining) */
+ rtlefuse->b1x1_recvcombine = false;
+ if (rtlphy->rf_type == RF_1T2R) {
+ tempval = rtl_read_byte(rtlpriv, 0x07);
+ if (!(tempval & BIT(0))) {
+ rtlefuse->b1x1_recvcombine = true;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("RF_TYPE=1T2R but only 1SS\n"));
+ }
+ }
+ rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine;
+ rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMID];
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("EEPROM Customer ID: 0x%2x",
+ rtlefuse->eeprom_oemid));
+
+ /* set channel paln to world wide 13 */
+ rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
+}
+
+void rtl92se_read_eeprom_info(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 tmp_u1b = 0;
+
+ tmp_u1b = rtl_read_byte(rtlpriv, EPROM_CMD);
+
+ if (tmp_u1b & BIT(4)) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n"));
+ rtlefuse->epromtype = EEPROM_93C46;
+ } else {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n"));
+ rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
+ }
+
+ if (tmp_u1b & BIT(5)) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+ rtlefuse->autoload_failflag = false;
+ _rtl92se_read_adapter_info(hw);
+ } else {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));
+ rtlefuse->autoload_failflag = true;
+ }
+}
+
+static void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ u32 ratr_value;
+ u8 ratr_index = 0;
+ u8 nmode = mac->ht_enable;
+ u8 mimo_ps = IEEE80211_SMPS_OFF;
+ u16 shortgi_rate = 0;
+ u32 tmp_ratr_value = 0;
+ u8 curtxbw_40mhz = mac->bw_40;
+ u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+ 1 : 0;
+ u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+ 1 : 0;
+ enum wireless_mode wirelessmode = mac->mode;
+
+ if (rtlhal->current_bandtype == BAND_ON_5G)
+ ratr_value = sta->supp_rates[1] << 4;
+ else
+ ratr_value = sta->supp_rates[0];
+ ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+ sta->ht_cap.mcs.rx_mask[0] << 12);
+ switch (wirelessmode) {
+ case WIRELESS_MODE_B:
+ ratr_value &= 0x0000000D;
+ break;
+ case WIRELESS_MODE_G:
+ ratr_value &= 0x00000FF5;
+ break;
+ case WIRELESS_MODE_N_24G:
+ case WIRELESS_MODE_N_5G:
+ nmode = 1;
+ if (mimo_ps == IEEE80211_SMPS_STATIC) {
+ ratr_value &= 0x0007F005;
+ } else {
+ u32 ratr_mask;
+
+ if (get_rf_type(rtlphy) == RF_1T2R ||
+ get_rf_type(rtlphy) == RF_1T1R) {
+ if (curtxbw_40mhz)
+ ratr_mask = 0x000ff015;
+ else
+ ratr_mask = 0x000ff005;
+ } else {
+ if (curtxbw_40mhz)
+ ratr_mask = 0x0f0ff015;
+ else
+ ratr_mask = 0x0f0ff005;
+ }
+
+ ratr_value &= ratr_mask;
+ }
+ break;
+ default:
+ if (rtlphy->rf_type == RF_1T2R)
+ ratr_value &= 0x000ff0ff;
+ else
+ ratr_value &= 0x0f0ff0ff;
+
+ break;
+ }
+
+ if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT)
+ ratr_value &= 0x0FFFFFFF;
+ else if (rtlpriv->rtlhal.version == VERSION_8192S_ACUT)
+ ratr_value &= 0x0FFFFFF0;
+
+ if (nmode && ((curtxbw_40mhz &&
+ curshortgi_40mhz) || (!curtxbw_40mhz &&
+ curshortgi_20mhz))) {
+
+ ratr_value |= 0x10000000;
+ tmp_ratr_value = (ratr_value >> 12);
+
+ for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
+ if ((1 << shortgi_rate) & tmp_ratr_value)
+ break;
+ }
+
+ shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
+ (shortgi_rate << 4) | (shortgi_rate);
+
+ rtl_write_byte(rtlpriv, SG_RATE, shortgi_rate);
+ }
+
+ rtl_write_dword(rtlpriv, ARFR0 + ratr_index * 4, ratr_value);
+ if (ratr_value & 0xfffff000)
+ rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_N);
+ else
+ rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_BG);
+
+ RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
+ ("%x\n", rtl_read_dword(rtlpriv, ARFR0)));
+}
+
+static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ u8 rssi_level)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_sta_info *sta_entry = NULL;
+ u32 ratr_bitmap;
+ u8 ratr_index = 0;
+ u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+ ? 1 : 0;
+ u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+ 1 : 0;
+ u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+ 1 : 0;
+ enum wireless_mode wirelessmode = 0;
+ bool shortgi = false;
+ u32 ratr_value = 0;
+ u8 shortgi_rate = 0;
+ u32 mask = 0;
+ u32 band = 0;
+ bool bmulticast = false;
+ u8 macid = 0;
+ u8 mimo_ps = IEEE80211_SMPS_OFF;
+
+ sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+ wirelessmode = sta_entry->wireless_mode;
+ if (mac->opmode == NL80211_IFTYPE_STATION)
+ curtxbw_40mhz = mac->bw_40;
+ else if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC)
+ macid = sta->aid + 1;
+
+ if (rtlhal->current_bandtype == BAND_ON_5G)
+ ratr_bitmap = sta->supp_rates[1] << 4;
+ else
+ ratr_bitmap = sta->supp_rates[0];
+ ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+ sta->ht_cap.mcs.rx_mask[0] << 12);
+ switch (wirelessmode) {
+ case WIRELESS_MODE_B:
+ band |= WIRELESS_11B;
+ ratr_index = RATR_INX_WIRELESS_B;
+ if (ratr_bitmap & 0x0000000c)
+ ratr_bitmap &= 0x0000000d;
+ else
+ ratr_bitmap &= 0x0000000f;
+ break;
+ case WIRELESS_MODE_G:
+ band |= (WIRELESS_11G | WIRELESS_11B);
+ ratr_index = RATR_INX_WIRELESS_GB;
+
+ if (rssi_level == 1)
+ ratr_bitmap &= 0x00000f00;
+ else if (rssi_level == 2)
+ ratr_bitmap &= 0x00000ff0;
+ else
+ ratr_bitmap &= 0x00000ff5;
+ break;
+ case WIRELESS_MODE_A:
+ band |= WIRELESS_11A;
+ ratr_index = RATR_INX_WIRELESS_A;
+ ratr_bitmap &= 0x00000ff0;
+ break;
+ case WIRELESS_MODE_N_24G:
+ case WIRELESS_MODE_N_5G:
+ band |= (WIRELESS_11N | WIRELESS_11G | WIRELESS_11B);
+ ratr_index = RATR_INX_WIRELESS_NGB;
+
+ if (mimo_ps == IEEE80211_SMPS_STATIC) {
+ if (rssi_level == 1)
+ ratr_bitmap &= 0x00070000;
+ else if (rssi_level == 2)
+ ratr_bitmap &= 0x0007f000;
+ else
+ ratr_bitmap &= 0x0007f005;
+ } else {
+ if (rtlphy->rf_type == RF_1T2R ||
+ rtlphy->rf_type == RF_1T1R) {
+ if (rssi_level == 1) {
+ ratr_bitmap &= 0x000f0000;
+ } else if (rssi_level == 3) {
+ ratr_bitmap &= 0x000fc000;
+ } else if (rssi_level == 5) {
+ ratr_bitmap &= 0x000ff000;
+ } else {
+ if (curtxbw_40mhz)
+ ratr_bitmap &= 0x000ff015;
+ else
+ ratr_bitmap &= 0x000ff005;
+ }
+ } else {
+ if (rssi_level == 1) {
+ ratr_bitmap &= 0x0f8f0000;
+ } else if (rssi_level == 3) {
+ ratr_bitmap &= 0x0f8fc000;
+ } else if (rssi_level == 5) {
+ ratr_bitmap &= 0x0f8ff000;
+ } else {
+ if (curtxbw_40mhz)
+ ratr_bitmap &= 0x0f8ff015;
+ else
+ ratr_bitmap &= 0x0f8ff005;
+ }
+ }
+ }
+
+ if ((curtxbw_40mhz && curshortgi_40mhz) ||
+ (!curtxbw_40mhz && curshortgi_20mhz)) {
+ if (macid == 0)
+ shortgi = true;
+ else if (macid == 1)
+ shortgi = false;
+ }
+ break;
+ default:
+ band |= (WIRELESS_11N | WIRELESS_11G | WIRELESS_11B);
+ ratr_index = RATR_INX_WIRELESS_NGB;
+
+ if (rtlphy->rf_type == RF_1T2R)
+ ratr_bitmap &= 0x000ff0ff;
+ else
+ ratr_bitmap &= 0x0f8ff0ff;
+ break;
+ }
+
+ if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT)
+ ratr_bitmap &= 0x0FFFFFFF;
+ else if (rtlpriv->rtlhal.version == VERSION_8192S_ACUT)
+ ratr_bitmap &= 0x0FFFFFF0;
+
+ if (shortgi) {
+ ratr_bitmap |= 0x10000000;
+ /* Get MAX MCS available. */
+ ratr_value = (ratr_bitmap >> 12);
+ for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
+ if ((1 << shortgi_rate) & ratr_value)
+ break;
+ }
+
+ shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
+ (shortgi_rate << 4) | (shortgi_rate);
+ rtl_write_byte(rtlpriv, SG_RATE, shortgi_rate);
+ }
+
+ mask |= (bmulticast ? 1 : 0) << 9 | (macid & 0x1f) << 4 | (band & 0xf);
+
+ RT_TRACE(rtlpriv, COMP_RATR, DBG_TRACE, ("mask = %x, bitmap = %x\n",
+ mask, ratr_bitmap));
+ rtl_write_dword(rtlpriv, 0x2c4, ratr_bitmap);
+ rtl_write_dword(rtlpriv, WFM5, (FW_RA_UPDATE_MASK | (mask << 8)));
+
+ if (macid != 0)
+ sta_entry->ratr_index = ratr_index;
+}
+
+void rtl92se_update_hal_rate_tbl(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u8 rssi_level)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (rtlpriv->dm.useramask)
+ rtl92se_update_hal_rate_mask(hw, sta, rssi_level);
+ else
+ rtl92se_update_hal_rate_table(hw, sta);
+}
+
+void rtl92se_update_channel_access_setting(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u16 sifs_timer;
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
+ (u8 *)&mac->slot_time);
+ sifs_timer = 0x0e0e;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
+
+}
+
+/* this ifunction is for RFKILL, it's different with windows,
+ * because UI will disable wireless when GPIO Radio Off.
+ * And here we not check or Disable/Enable ASPM like windows*/
+bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ enum rf_pwrstate rfpwr_toset, cur_rfstate;
+ unsigned long flag = 0;
+ bool actuallyset = false;
+ bool turnonbypowerdomain = false;
+
+ /* just 8191se can check gpio before firstup, 92c/92d have fixed it */
+ if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter))
+ return false;
+
+ if (ppsc->swrf_processing)
+ return false;
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+ if (ppsc->rfchange_inprogress) {
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+ return false;
+ } else {
+ ppsc->rfchange_inprogress = true;
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+ }
+
+ cur_rfstate = ppsc->rfpwr_state;
+
+ /* because after _rtl92s_phy_set_rfhalt, all power
+ * closed, so we must open some power for GPIO check,
+ * or we will always check GPIO RFOFF here,
+ * And we should close power after GPIO check */
+ if (RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
+ _rtl92se_power_domain_init(hw);
+ turnonbypowerdomain = true;
+ }
+
+ rfpwr_toset = _rtl92se_rf_onoff_detect(hw);
+
+ if ((ppsc->hwradiooff == true) && (rfpwr_toset == ERFON)) {
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ ("RFKILL-HW Radio ON, RF ON\n"));
+
+ rfpwr_toset = ERFON;
+ ppsc->hwradiooff = false;
+ actuallyset = true;
+ } else if ((ppsc->hwradiooff == false) && (rfpwr_toset == ERFOFF)) {
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ ("RFKILL-HW Radio OFF, RF OFF\n"));
+
+ rfpwr_toset = ERFOFF;
+ ppsc->hwradiooff = true;
+ actuallyset = true;
+ }
+
+ if (actuallyset) {
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+ ppsc->rfchange_inprogress = false;
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+
+ /* this not include ifconfig wlan0 down case */
+ /* } else if (rfpwr_toset == ERFOFF || cur_rfstate == ERFOFF) { */
+ } else {
+ /* because power_domain_init may be happen when
+ * _rtl92s_phy_set_rfhalt, this will open some powers
+ * and cause current increasing about 40 mA for ips,
+ * rfoff and ifconfig down, so we set
+ * _rtl92s_phy_set_rfhalt again here */
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC &&
+ turnonbypowerdomain) {
+ _rtl92s_phy_set_rfhalt(hw);
+ RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+ }
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+ ppsc->rfchange_inprogress = false;
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+ }
+
+ *valid = 1;
+ return !ppsc->hwradiooff;
+
+}
+
+/* Is_wepkey just used for WEP used as group & pairwise key
+ * if pairwise is AES ang group is WEP Is_wepkey == false.*/
+void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
+ bool is_group, u8 enc_algo, bool is_wepkey, bool clear_all)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 *macaddr = p_macaddr;
+
+ u32 entry_id = 0;
+ bool is_pairwise = false;
+
+ static u8 cam_const_addr[4][6] = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
+ };
+ static u8 cam_const_broad[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
+
+ if (clear_all) {
+ u8 idx = 0;
+ u8 cam_offset = 0;
+ u8 clear_number = 5;
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n"));
+
+ for (idx = 0; idx < clear_number; idx++) {
+ rtl_cam_mark_invalid(hw, cam_offset + idx);
+ rtl_cam_empty_entry(hw, cam_offset + idx);
+
+ if (idx < 5) {
+ memset(rtlpriv->sec.key_buf[idx], 0,
+ MAX_KEY_LEN);
+ rtlpriv->sec.key_len[idx] = 0;
+ }
+ }
+
+ } else {
+ switch (enc_algo) {
+ case WEP40_ENCRYPTION:
+ enc_algo = CAM_WEP40;
+ break;
+ case WEP104_ENCRYPTION:
+ enc_algo = CAM_WEP104;
+ break;
+ case TKIP_ENCRYPTION:
+ enc_algo = CAM_TKIP;
+ break;
+ case AESCCMP_ENCRYPTION:
+ enc_algo = CAM_AES;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ enc_algo = CAM_TKIP;
+ break;
+ }
+
+ if (is_wepkey || rtlpriv->sec.use_defaultkey) {
+ macaddr = cam_const_addr[key_index];
+ entry_id = key_index;
+ } else {
+ if (is_group) {
+ macaddr = cam_const_broad;
+ entry_id = key_index;
+ } else {
+ if (mac->opmode == NL80211_IFTYPE_AP) {
+ entry_id = rtl_cam_get_free_entry(hw,
+ p_macaddr);
+ if (entry_id >= TOTAL_CAM_ENTRY) {
+ RT_TRACE(rtlpriv,
+ COMP_SEC, DBG_EMERG,
+ ("Can not find free hw"
+ " security cam entry\n"));
+ return;
+ }
+ } else {
+ entry_id = CAM_PAIRWISE_KEY_POSITION;
+ }
+
+ key_index = PAIRWISE_KEYIDX;
+ is_pairwise = true;
+ }
+ }
+
+ if (rtlpriv->sec.key_len[key_index] == 0) {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("delete one entry, entry_id is %d\n",
+ entry_id));
+ if (mac->opmode == NL80211_IFTYPE_AP)
+ rtl_cam_del_entry(hw, p_macaddr);
+ rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
+ } else {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ ("The insert KEY length is %d\n",
+ rtlpriv->sec.key_len[PAIRWISE_KEYIDX]));
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ ("The insert KEY is %x %x\n",
+ rtlpriv->sec.key_buf[0][0],
+ rtlpriv->sec.key_buf[0][1]));
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("add one entry\n"));
+ if (is_pairwise) {
+ RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
+ "Pairwiase Key content :",
+ rtlpriv->sec.pairwise_key,
+ rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("set Pairwiase key\n"));
+
+ rtl_cam_add_one_entry(hw, macaddr, key_index,
+ entry_id, enc_algo,
+ CAM_CONFIG_NO_USEDK,
+ rtlpriv->sec.key_buf[key_index]);
+ } else {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("set group key\n"));
+
+ if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+ rtl_cam_add_one_entry(hw,
+ rtlefuse->dev_addr,
+ PAIRWISE_KEYIDX,
+ CAM_PAIRWISE_KEY_POSITION,
+ enc_algo, CAM_CONFIG_NO_USEDK,
+ rtlpriv->sec.key_buf[entry_id]);
+ }
+
+ rtl_cam_add_one_entry(hw, macaddr, key_index,
+ entry_id, enc_algo,
+ CAM_CONFIG_NO_USEDK,
+ rtlpriv->sec.key_buf[entry_id]);
+ }
+
+ }
+ }
+}
+
+void rtl92se_suspend(struct ieee80211_hw *hw)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ rtlpci->up_first_time = true;
+}
+
+void rtl92se_resume(struct ieee80211_hw *hw)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u32 val;
+
+ pci_read_config_dword(rtlpci->pdev, 0x40, &val);
+ if ((val & 0x0000ff00) != 0)
+ pci_write_config_dword(rtlpci->pdev, 0x40,
+ val & 0xffff00ff);
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h
new file mode 100644
index 00000000000..6160a9bfe98
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h
@@ -0,0 +1,79 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __REALTEK_PCI92SE_HW_H__
+#define __REALTEK_PCI92SE_HW_H__
+
+#define MSR_LINK_MANAGED 2
+#define MSR_LINK_NONE 0
+#define MSR_LINK_SHIFT 0
+#define MSR_LINK_ADHOC 1
+#define MSR_LINK_MASTER 3
+
+enum WIRELESS_NETWORK_TYPE {
+ WIRELESS_11B = 1,
+ WIRELESS_11G = 2,
+ WIRELESS_11A = 4,
+ WIRELESS_11N = 8
+};
+
+void rtl92se_get_hw_reg(struct ieee80211_hw *hw,
+ u8 variable, u8 *val);
+void rtl92se_read_eeprom_info(struct ieee80211_hw *hw);
+void rtl92se_interrupt_recognized(struct ieee80211_hw *hw,
+ u32 *inta, u32 *intb);
+int rtl92se_hw_init(struct ieee80211_hw *hw);
+void rtl92se_card_disable(struct ieee80211_hw *hw);
+void rtl92se_enable_interrupt(struct ieee80211_hw *hw);
+void rtl92se_disable_interrupt(struct ieee80211_hw *hw);
+int rtl92se_set_network_type(struct ieee80211_hw *hw,
+ enum nl80211_iftype type);
+void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
+void rtl92se_set_mac_addr(struct rtl_io *io, const u8 * addr);
+void rtl92se_set_qos(struct ieee80211_hw *hw, int aci);
+void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw);
+void rtl92se_set_beacon_interval(struct ieee80211_hw *hw);
+void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw,
+ u32 add_msr, u32 rm_msr);
+void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable,
+ u8 *val);
+void rtl92se_update_hal_rate_tbl(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u8 rssi_level);
+void rtl92se_update_channel_access_setting(struct ieee80211_hw *hw);
+bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw,
+ u8 *valid);
+void rtl8192se_gpiobit3_cfg_inputmode(struct ieee80211_hw *hw);
+void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw);
+void rtl92se_set_key(struct ieee80211_hw *hw,
+ u32 key_index, u8 *macaddr, bool is_group,
+ u8 enc_algo, bool is_wepkey, bool clear_all);
+void rtl92se_suspend(struct ieee80211_hw *hw);
+void rtl92se_resume(struct ieee80211_hw *hw);
+
+#endif
+
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/rtlwifi/rtl8192se/led.c
new file mode 100644
index 00000000000..6d4f6661668
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.c
@@ -0,0 +1,149 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "reg.h"
+#include "led.h"
+
+static void _rtl92se_init_led(struct ieee80211_hw *hw,
+ struct rtl_led *pled, enum rtl_led_pin ledpin)
+{
+ pled->hw = hw;
+ pled->ledpin = ledpin;
+ pled->ledon = false;
+}
+
+void rtl92se_init_sw_leds(struct ieee80211_hw *hw)
+{
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ _rtl92se_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);
+ _rtl92se_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);
+}
+
+void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
+{
+ u8 ledcfg;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
+ ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin));
+
+ ledcfg = rtl_read_byte(rtlpriv, LEDCFG);
+
+ switch (pled->ledpin) {
+ case LED_PIN_GPIO0:
+ break;
+ case LED_PIN_LED0:
+ rtl_write_byte(rtlpriv, LEDCFG, ledcfg & 0xf0);
+ break;
+ case LED_PIN_LED1:
+ rtl_write_byte(rtlpriv, LEDCFG, ledcfg & 0x0f);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+ pled->ledon = true;
+}
+
+void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ u8 ledcfg;
+
+ RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
+ ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin));
+
+ ledcfg = rtl_read_byte(rtlpriv, LEDCFG);
+
+ switch (pled->ledpin) {
+ case LED_PIN_GPIO0:
+ break;
+ case LED_PIN_LED0:
+ ledcfg &= 0xf0;
+ if (pcipriv->ledctl.led_opendrain == true)
+ rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(1)));
+ else
+ rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(3)));
+ break;
+ case LED_PIN_LED1:
+ ledcfg &= 0x0f;
+ rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(3)));
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+ pled->ledon = false;
+}
+
+static void _rtl92se_sw_led_control(struct ieee80211_hw *hw,
+ enum led_ctl_mode ledaction)
+{
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
+ switch (ledaction) {
+ case LED_CTL_POWER_ON:
+ case LED_CTL_LINK:
+ case LED_CTL_NO_LINK:
+ rtl92se_sw_led_on(hw, pLed0);
+ break;
+ case LED_CTL_POWER_OFF:
+ rtl92se_sw_led_off(hw, pLed0);
+ break;
+ default:
+ break;
+ }
+}
+
+void rtl92se_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
+ (ledaction == LED_CTL_TX ||
+ ledaction == LED_CTL_RX ||
+ ledaction == LED_CTL_SITE_SURVEY ||
+ ledaction == LED_CTL_LINK ||
+ ledaction == LED_CTL_NO_LINK ||
+ ledaction == LED_CTL_START_TO_LINK ||
+ ledaction == LED_CTL_POWER_ON)) {
+ return;
+ }
+ RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n",
+ ledaction));
+
+ _rtl92se_sw_led_control(hw, ledaction);
+}
+
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.h b/drivers/net/wireless/rtlwifi/rtl8192se/led.h
new file mode 100644
index 00000000000..8cce3870af3
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.h
@@ -0,0 +1,37 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __REALTEK_PCI92SE_LED_H__
+#define __REALTEK_PCI92SE_LED_H__
+
+void rtl92se_init_sw_leds(struct ieee80211_hw *hw);
+void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
+void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
+void rtl92se_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c
new file mode 100644
index 00000000000..63b45e60a95
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c
@@ -0,0 +1,1740 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "../ps.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "rf.h"
+#include "dm.h"
+#include "fw.h"
+#include "hw.h"
+#include "table.h"
+
+static u32 _rtl92s_phy_calculate_bit_shift(u32 bitmask)
+{
+ u32 i;
+
+ for (i = 0; i <= 31; i++) {
+ if (((bitmask >> i) & 0x1) == 1)
+ break;
+ }
+
+ return i;
+}
+
+u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 returnvalue = 0, originalvalue, bitshift;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)\n",
+ regaddr, bitmask));
+
+ originalvalue = rtl_read_dword(rtlpriv, regaddr);
+ bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
+ returnvalue = (originalvalue & bitmask) >> bitshift;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+ ("BBR MASK=0x%x Addr[0x%x]=0x%x\n",
+ bitmask, regaddr, originalvalue));
+
+ return returnvalue;
+
+}
+
+void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
+ u32 data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 originalvalue, bitshift;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
+ " data(%#x)\n", regaddr, bitmask, data));
+
+ if (bitmask != MASKDWORD) {
+ originalvalue = rtl_read_dword(rtlpriv, regaddr);
+ bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
+ data = ((originalvalue & (~bitmask)) | (data << bitshift));
+ }
+
+ rtl_write_dword(rtlpriv, regaddr, data);
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
+ " data(%#x)\n", regaddr, bitmask, data));
+
+}
+
+static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 offset)
+{
+
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
+ u32 newoffset;
+ u32 tmplong, tmplong2;
+ u8 rfpi_enable = 0;
+ u32 retvalue = 0;
+
+ offset &= 0x3f;
+ newoffset = offset;
+
+ tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
+
+ if (rfpath == RF90_PATH_A)
+ tmplong2 = tmplong;
+ else
+ tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
+
+ tmplong2 = (tmplong2 & (~BLSSI_READADDRESS)) | (newoffset << 23) |
+ BLSSI_READEDGE;
+
+ rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
+ tmplong & (~BLSSI_READEDGE));
+
+ mdelay(1);
+
+ rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
+ mdelay(1);
+
+ rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, tmplong |
+ BLSSI_READEDGE);
+ mdelay(1);
+
+ if (rfpath == RF90_PATH_A)
+ rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
+ BIT(8));
+ else if (rfpath == RF90_PATH_B)
+ rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
+ BIT(8));
+
+ if (rfpi_enable)
+ retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi,
+ BLSSI_READBACK_DATA);
+ else
+ retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
+ BLSSI_READBACK_DATA);
+
+ retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
+ BLSSI_READBACK_DATA);
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n",
+ rfpath, pphyreg->rflssi_readback, retvalue));
+
+ return retvalue;
+
+}
+
+static void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 offset,
+ u32 data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
+ u32 data_and_addr = 0;
+ u32 newoffset;
+
+ offset &= 0x3f;
+ newoffset = offset;
+
+ data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
+ rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
+ rfpath, pphyreg->rf3wire_offset, data_and_addr));
+}
+
+
+u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
+ u32 regaddr, u32 bitmask)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 original_value, readback_value, bitshift;
+ unsigned long flags;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
+ "bitmask(%#x)\n", regaddr, rfpath, bitmask));
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+
+ original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr);
+
+ bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
+ readback_value = (original_value & bitmask) >> bitshift;
+
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
+ "bitmask(%#x), original_value(%#x)\n", regaddr, rfpath,
+ bitmask, original_value));
+
+ return readback_value;
+}
+
+void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
+ u32 regaddr, u32 bitmask, u32 data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ u32 original_value, bitshift;
+ unsigned long flags;
+
+ if (!((rtlphy->rf_pathmap >> rfpath) & 0x1))
+ return;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
+ " data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath));
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+
+ if (bitmask != RFREG_OFFSET_MASK) {
+ original_value = _rtl92s_phy_rf_serial_read(hw, rfpath,
+ regaddr);
+ bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
+ data = ((original_value & (~bitmask)) | (data << bitshift));
+ }
+
+ _rtl92s_phy_rf_serial_write(hw, rfpath, regaddr, data);
+
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x), "
+ "data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath));
+
+}
+
+void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw,
+ u8 operation)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ if (!is_hal_stop(rtlhal)) {
+ switch (operation) {
+ case SCAN_OPT_BACKUP:
+ rtl92s_phy_set_fw_cmd(hw, FW_CMD_PAUSE_DM_BY_SCAN);
+ break;
+ case SCAN_OPT_RESTORE:
+ rtl92s_phy_set_fw_cmd(hw, FW_CMD_RESUME_DM_BY_SCAN);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Unknown operation.\n"));
+ break;
+ }
+ }
+}
+
+void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
+ enum nl80211_channel_type ch_type)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u8 reg_bw_opmode;
+ u8 reg_prsr_rsc;
+
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n",
+ rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
+ "20MHz" : "40MHz"));
+
+ if (rtlphy->set_bwmode_inprogress)
+ return;
+ if (is_hal_stop(rtlhal))
+ return;
+
+ rtlphy->set_bwmode_inprogress = true;
+
+ reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE);
+ reg_prsr_rsc = rtl_read_byte(rtlpriv, RRSR + 2);
+
+ switch (rtlphy->current_chan_bw) {
+ case HT_CHANNEL_WIDTH_20:
+ reg_bw_opmode |= BW_OPMODE_20MHZ;
+ rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
+ break;
+ case HT_CHANNEL_WIDTH_20_40:
+ reg_bw_opmode &= ~BW_OPMODE_20MHZ;
+ rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("unknown bandwidth: %#X\n",
+ rtlphy->current_chan_bw));
+ break;
+ }
+
+ switch (rtlphy->current_chan_bw) {
+ case HT_CHANNEL_WIDTH_20:
+ rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
+ rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
+
+ if (rtlhal->version >= VERSION_8192S_BCUT)
+ rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x58);
+ break;
+ case HT_CHANNEL_WIDTH_20_40:
+ rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
+ rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
+
+ rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
+ (mac->cur_40_prime_sc >> 1));
+ rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
+
+ if (rtlhal->version >= VERSION_8192S_BCUT)
+ rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x18);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+ break;
+ }
+
+ rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
+ rtlphy->set_bwmode_inprogress = false;
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+}
+
+static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
+ u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid,
+ u32 para1, u32 para2, u32 msdelay)
+{
+ struct swchnlcmd *pcmd;
+
+ if (cmdtable == NULL) {
+ RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
+ return false;
+ }
+
+ if (cmdtableidx >= cmdtablesz)
+ return false;
+
+ pcmd = cmdtable + cmdtableidx;
+ pcmd->cmdid = cmdid;
+ pcmd->para1 = para1;
+ pcmd->para2 = para2;
+ pcmd->msdelay = msdelay;
+
+ return true;
+}
+
+static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
+ u8 channel, u8 *stage, u8 *step, u32 *delay)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
+ u32 precommoncmdcnt;
+ struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
+ u32 postcommoncmdcnt;
+ struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
+ u32 rfdependcmdcnt;
+ struct swchnlcmd *currentcmd = NULL;
+ u8 rfpath;
+ u8 num_total_rfpath = rtlphy->num_total_rfpath;
+
+ precommoncmdcnt = 0;
+ _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
+ MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
+ _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
+ MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
+
+ postcommoncmdcnt = 0;
+
+ _rtl92s_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
+ MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
+
+ rfdependcmdcnt = 0;
+
+ RT_ASSERT((channel >= 1 && channel <= 14),
+ ("illegal channel for Zebra: %d\n", channel));
+
+ _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
+ MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
+ RF_CHNLBW, channel, 10);
+
+ _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
+ MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0);
+
+ do {
+ switch (*stage) {
+ case 0:
+ currentcmd = &precommoncmd[*step];
+ break;
+ case 1:
+ currentcmd = &rfdependcmd[*step];
+ break;
+ case 2:
+ currentcmd = &postcommoncmd[*step];
+ break;
+ }
+
+ if (currentcmd->cmdid == CMDID_END) {
+ if ((*stage) == 2) {
+ return true;
+ } else {
+ (*stage)++;
+ (*step) = 0;
+ continue;
+ }
+ }
+
+ switch (currentcmd->cmdid) {
+ case CMDID_SET_TXPOWEROWER_LEVEL:
+ rtl92s_phy_set_txpower(hw, channel);
+ break;
+ case CMDID_WRITEPORT_ULONG:
+ rtl_write_dword(rtlpriv, currentcmd->para1,
+ currentcmd->para2);
+ break;
+ case CMDID_WRITEPORT_USHORT:
+ rtl_write_word(rtlpriv, currentcmd->para1,
+ (u16)currentcmd->para2);
+ break;
+ case CMDID_WRITEPORT_UCHAR:
+ rtl_write_byte(rtlpriv, currentcmd->para1,
+ (u8)currentcmd->para2);
+ break;
+ case CMDID_RF_WRITEREG:
+ for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
+ rtlphy->rfreg_chnlval[rfpath] =
+ ((rtlphy->rfreg_chnlval[rfpath] &
+ 0xfffffc00) | currentcmd->para2);
+ rtl_set_rfreg(hw, (enum radio_path)rfpath,
+ currentcmd->para1,
+ RFREG_OFFSET_MASK,
+ rtlphy->rfreg_chnlval[rfpath]);
+ }
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+
+ break;
+ } while (true);
+
+ (*delay) = currentcmd->msdelay;
+ (*step)++;
+ return false;
+}
+
+u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ u32 delay;
+ bool ret;
+
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
+ ("switch to channel%d\n",
+ rtlphy->current_channel));
+
+ if (rtlphy->sw_chnl_inprogress)
+ return 0;
+
+ if (rtlphy->set_bwmode_inprogress)
+ return 0;
+
+ if (is_hal_stop(rtlhal))
+ return 0;
+
+ rtlphy->sw_chnl_inprogress = true;
+ rtlphy->sw_chnl_stage = 0;
+ rtlphy->sw_chnl_step = 0;
+
+ do {
+ if (!rtlphy->sw_chnl_inprogress)
+ break;
+
+ ret = _rtl92s_phy_sw_chnl_step_by_step(hw,
+ rtlphy->current_channel,
+ &rtlphy->sw_chnl_stage,
+ &rtlphy->sw_chnl_step, &delay);
+ if (!ret) {
+ if (delay > 0)
+ mdelay(delay);
+ else
+ continue;
+ } else {
+ rtlphy->sw_chnl_inprogress = false;
+ }
+ break;
+ } while (true);
+
+ rtlphy->sw_chnl_inprogress = false;
+
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+
+ return 1;
+}
+
+static void _rtl92se_phy_set_rf_sleep(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 u1btmp;
+
+ u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL);
+ u1btmp |= BIT(0);
+
+ rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp);
+ rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0);
+ rtl_write_byte(rtlpriv, TXPAUSE, 0xFF);
+ rtl_write_word(rtlpriv, CMDR, 0x57FC);
+ udelay(100);
+
+ rtl_write_word(rtlpriv, CMDR, 0x77FC);
+ rtl_write_byte(rtlpriv, PHY_CCA, 0x0);
+ udelay(10);
+
+ rtl_write_word(rtlpriv, CMDR, 0x37FC);
+ udelay(10);
+
+ rtl_write_word(rtlpriv, CMDR, 0x77FC);
+ udelay(10);
+
+ rtl_write_word(rtlpriv, CMDR, 0x57FC);
+
+ /* we should chnge GPIO to input mode
+ * this will drop away current about 25mA*/
+ rtl8192se_gpiobit3_cfg_inputmode(hw);
+}
+
+bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
+ enum rf_pwrstate rfpwr_state)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ bool bresult = true;
+ u8 i, queue_id;
+ struct rtl8192_tx_ring *ring = NULL;
+
+ if (rfpwr_state == ppsc->rfpwr_state)
+ return false;
+
+ ppsc->set_rfpowerstate_inprogress = true;
+
+ switch (rfpwr_state) {
+ case ERFON:{
+ if ((ppsc->rfpwr_state == ERFOFF) &&
+ RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
+
+ bool rtstatus;
+ u32 InitializeCount = 0;
+ do {
+ InitializeCount++;
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ ("IPS Set eRf nic enable\n"));
+ rtstatus = rtl_ps_enable_nic(hw);
+ } while ((rtstatus != true) &&
+ (InitializeCount < 10));
+
+ RT_CLEAR_PS_LEVEL(ppsc,
+ RT_RF_OFF_LEVL_HALT_NIC);
+ } else {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+ ("awake, sleeped:%d ms "
+ "state_inap:%x\n",
+ jiffies_to_msecs(jiffies -
+ ppsc->last_sleep_jiffies),
+ rtlpriv->psc.state_inap));
+ ppsc->last_awake_jiffies = jiffies;
+ rtl_write_word(rtlpriv, CMDR, 0x37FC);
+ rtl_write_byte(rtlpriv, TXPAUSE, 0x00);
+ rtl_write_byte(rtlpriv, PHY_CCA, 0x3);
+ }
+
+ if (mac->link_state == MAC80211_LINKED)
+ rtlpriv->cfg->ops->led_control(hw,
+ LED_CTL_LINK);
+ else
+ rtlpriv->cfg->ops->led_control(hw,
+ LED_CTL_NO_LINK);
+ break;
+ }
+ case ERFOFF:{
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ ("IPS Set eRf nic disable\n"));
+ rtl_ps_disable_nic(hw);
+ RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+ } else {
+ if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
+ rtlpriv->cfg->ops->led_control(hw,
+ LED_CTL_NO_LINK);
+ else
+ rtlpriv->cfg->ops->led_control(hw,
+ LED_CTL_POWER_OFF);
+ }
+ break;
+ }
+ case ERFSLEEP:
+ if (ppsc->rfpwr_state == ERFOFF)
+ break;
+
+ for (queue_id = 0, i = 0;
+ queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
+ ring = &pcipriv->dev.tx_ring[queue_id];
+ if (skb_queue_len(&ring->queue) == 0 ||
+ queue_id == BEACON_QUEUE) {
+ queue_id++;
+ continue;
+ } else {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("eRf Off/Sleep: "
+ "%d times TcbBusyQueue[%d] = "
+ "%d before doze!\n",
+ (i + 1), queue_id,
+ skb_queue_len(&ring->queue)));
+
+ udelay(10);
+ i++;
+ }
+
+ if (i >= MAX_DOZE_WAITING_TIMES_9x) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("\nERFOFF: %d times"
+ "TcbBusyQueue[%d] = %d !\n",
+ MAX_DOZE_WAITING_TIMES_9x,
+ queue_id,
+ skb_queue_len(&ring->queue)));
+ break;
+ }
+ }
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+ ("Set ERFSLEEP awaked:%d ms\n",
+ jiffies_to_msecs(jiffies -
+ ppsc->last_awake_jiffies)));
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+ ("sleep awaked:%d ms "
+ "state_inap:%x\n", jiffies_to_msecs(jiffies -
+ ppsc->last_awake_jiffies),
+ rtlpriv->psc.state_inap));
+ ppsc->last_sleep_jiffies = jiffies;
+ _rtl92se_phy_set_rf_sleep(hw);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ bresult = false;
+ break;
+ }
+
+ if (bresult)
+ ppsc->rfpwr_state = rfpwr_state;
+
+ ppsc->set_rfpowerstate_inprogress = false;
+
+ return bresult;
+}
+
+static bool _rtl92s_phy_config_rfpa_bias_current(struct ieee80211_hw *hw,
+ enum radio_path rfpath)
+{
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ bool rtstatus = true;
+ u32 tmpval = 0;
+
+ /* If inferiority IC, we have to increase the PA bias current */
+ if (rtlhal->ic_class != IC_INFERIORITY_A) {
+ tmpval = rtl92s_phy_query_rf_reg(hw, rfpath, RF_IPA, 0xf);
+ rtl92s_phy_set_rf_reg(hw, rfpath, RF_IPA, 0xf, tmpval + 1);
+ }
+
+ return rtstatus;
+}
+
+static void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
+ u32 reg_addr, u32 bitmask, u32 data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ if (reg_addr == RTXAGC_RATE18_06)
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
+ data;
+ if (reg_addr == RTXAGC_RATE54_24)
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
+ data;
+ if (reg_addr == RTXAGC_CCK_MCS32)
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
+ data;
+ if (reg_addr == RTXAGC_MCS03_MCS00)
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
+ data;
+ if (reg_addr == RTXAGC_MCS07_MCS04)
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
+ data;
+ if (reg_addr == RTXAGC_MCS11_MCS08)
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
+ data;
+ if (reg_addr == RTXAGC_MCS15_MCS12) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
+ data;
+ rtlphy->pwrgroup_cnt++;
+ }
+}
+
+static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ /*RF Interface Sowrtware Control */
+ rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
+ rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
+ rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
+ rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
+
+ /* RF Interface Readback Value */
+ rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
+ rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
+ rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
+ rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
+
+ /* RF Interface Output (and Enable) */
+ rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
+ rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
+ rtlphy->phyreg_def[RF90_PATH_C].rfintfo = RFPGA0_XC_RFINTERFACEOE;
+ rtlphy->phyreg_def[RF90_PATH_D].rfintfo = RFPGA0_XD_RFINTERFACEOE;
+
+ /* RF Interface (Output and) Enable */
+ rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
+ rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
+ rtlphy->phyreg_def[RF90_PATH_C].rfintfe = RFPGA0_XC_RFINTERFACEOE;
+ rtlphy->phyreg_def[RF90_PATH_D].rfintfe = RFPGA0_XD_RFINTERFACEOE;
+
+ /* Addr of LSSI. Wirte RF register by driver */
+ rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
+ RFPGA0_XA_LSSIPARAMETER;
+ rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
+ RFPGA0_XB_LSSIPARAMETER;
+ rtlphy->phyreg_def[RF90_PATH_C].rf3wire_offset =
+ RFPGA0_XC_LSSIPARAMETER;
+ rtlphy->phyreg_def[RF90_PATH_D].rf3wire_offset =
+ RFPGA0_XD_LSSIPARAMETER;
+
+ /* RF parameter */
+ rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER;
+ rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER;
+ rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER;
+ rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER;
+
+ /* Tx AGC Gain Stage (same for all path. Should we remove this?) */
+ rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+ rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+ rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+ rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+
+ /* Tranceiver A~D HSSI Parameter-1 */
+ rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
+ rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
+ rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para1 = RFPGA0_XC_HSSIPARAMETER1;
+ rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para1 = RFPGA0_XD_HSSIPARAMETER1;
+
+ /* Tranceiver A~D HSSI Parameter-2 */
+ rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
+ rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
+ rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para2 = RFPGA0_XC_HSSIPARAMETER2;
+ rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2;
+
+ /* RF switch Control */
+ rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control =
+ RFPGA0_XAB_SWITCHCONTROL;
+ rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control =
+ RFPGA0_XAB_SWITCHCONTROL;
+ rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control =
+ RFPGA0_XCD_SWITCHCONTROL;
+ rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control =
+ RFPGA0_XCD_SWITCHCONTROL;
+
+ /* AGC control 1 */
+ rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
+ rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
+ rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
+ rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
+
+ /* AGC control 2 */
+ rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
+ rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
+ rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
+ rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
+
+ /* RX AFE control 1 */
+ rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance =
+ ROFDM0_XARXIQIMBALANCE;
+ rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance =
+ ROFDM0_XBRXIQIMBALANCE;
+ rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance =
+ ROFDM0_XCRXIQIMBALANCE;
+ rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance =
+ ROFDM0_XDRXIQIMBALANCE;
+
+ /* RX AFE control 1 */
+ rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
+ rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
+ rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
+ rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
+
+ /* Tx AFE control 1 */
+ rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance =
+ ROFDM0_XATXIQIMBALANCE;
+ rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance =
+ ROFDM0_XBTXIQIMBALANCE;
+ rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance =
+ ROFDM0_XCTXIQIMBALANCE;
+ rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance =
+ ROFDM0_XDTXIQIMBALANCE;
+
+ /* Tx AFE control 2 */
+ rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
+ rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
+ rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
+ rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
+
+ /* Tranceiver LSSI Readback */
+ rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback =
+ RFPGA0_XA_LSSIREADBACK;
+ rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback =
+ RFPGA0_XB_LSSIREADBACK;
+ rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback =
+ RFPGA0_XC_LSSIREADBACK;
+ rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback =
+ RFPGA0_XD_LSSIREADBACK;
+
+ /* Tranceiver LSSI Readback PI mode */
+ rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi =
+ TRANSCEIVERA_HSPI_READBACK;
+ rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi =
+ TRANSCEIVERB_HSPI_READBACK;
+}
+
+
+static bool _rtl92s_phy_config_bb(struct ieee80211_hw *hw, u8 configtype)
+{
+ int i;
+ u32 *phy_reg_table;
+ u32 *agc_table;
+ u16 phy_reg_len, agc_len;
+
+ agc_len = AGCTAB_ARRAYLENGTH;
+ agc_table = rtl8192seagctab_array;
+ /* Default RF_type: 2T2R */
+ phy_reg_len = PHY_REG_2T2RARRAYLENGTH;
+ phy_reg_table = rtl8192sephy_reg_2t2rarray;
+
+ if (configtype == BASEBAND_CONFIG_PHY_REG) {
+ for (i = 0; i < phy_reg_len; i = i + 2) {
+ if (phy_reg_table[i] == 0xfe)
+ mdelay(50);
+ else if (phy_reg_table[i] == 0xfd)
+ mdelay(5);
+ else if (phy_reg_table[i] == 0xfc)
+ mdelay(1);
+ else if (phy_reg_table[i] == 0xfb)
+ udelay(50);
+ else if (phy_reg_table[i] == 0xfa)
+ udelay(5);
+ else if (phy_reg_table[i] == 0xf9)
+ udelay(1);
+
+ /* Add delay for ECS T20 & LG malow platform, */
+ udelay(1);
+
+ rtl92s_phy_set_bb_reg(hw, phy_reg_table[i], MASKDWORD,
+ phy_reg_table[i + 1]);
+ }
+ } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
+ for (i = 0; i < agc_len; i = i + 2) {
+ rtl92s_phy_set_bb_reg(hw, agc_table[i], MASKDWORD,
+ agc_table[i + 1]);
+
+ /* Add delay for ECS T20 & LG malow platform */
+ udelay(1);
+ }
+ }
+
+ return true;
+}
+
+static bool _rtl92s_phy_set_bb_to_diff_rf(struct ieee80211_hw *hw,
+ u8 configtype)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ u32 *phy_regarray2xtxr_table;
+ u16 phy_regarray2xtxr_len;
+ int i;
+
+ if (rtlphy->rf_type == RF_1T1R) {
+ phy_regarray2xtxr_table = rtl8192sephy_changeto_1t1rarray;
+ phy_regarray2xtxr_len = PHY_CHANGETO_1T1RARRAYLENGTH;
+ } else if (rtlphy->rf_type == RF_1T2R) {
+ phy_regarray2xtxr_table = rtl8192sephy_changeto_1t2rarray;
+ phy_regarray2xtxr_len = PHY_CHANGETO_1T2RARRAYLENGTH;
+ } else {
+ return false;
+ }
+
+ if (configtype == BASEBAND_CONFIG_PHY_REG) {
+ for (i = 0; i < phy_regarray2xtxr_len; i = i + 3) {
+ if (phy_regarray2xtxr_table[i] == 0xfe)
+ mdelay(50);
+ else if (phy_regarray2xtxr_table[i] == 0xfd)
+ mdelay(5);
+ else if (phy_regarray2xtxr_table[i] == 0xfc)
+ mdelay(1);
+ else if (phy_regarray2xtxr_table[i] == 0xfb)
+ udelay(50);
+ else if (phy_regarray2xtxr_table[i] == 0xfa)
+ udelay(5);
+ else if (phy_regarray2xtxr_table[i] == 0xf9)
+ udelay(1);
+
+ rtl92s_phy_set_bb_reg(hw, phy_regarray2xtxr_table[i],
+ phy_regarray2xtxr_table[i + 1],
+ phy_regarray2xtxr_table[i + 2]);
+ }
+ }
+
+ return true;
+}
+
+static bool _rtl92s_phy_config_bb_with_pg(struct ieee80211_hw *hw,
+ u8 configtype)
+{
+ int i;
+ u32 *phy_table_pg;
+ u16 phy_pg_len;
+
+ phy_pg_len = PHY_REG_ARRAY_PGLENGTH;
+ phy_table_pg = rtl8192sephy_reg_array_pg;
+
+ if (configtype == BASEBAND_CONFIG_PHY_REG) {
+ for (i = 0; i < phy_pg_len; i = i + 3) {
+ if (phy_table_pg[i] == 0xfe)
+ mdelay(50);
+ else if (phy_table_pg[i] == 0xfd)
+ mdelay(5);
+ else if (phy_table_pg[i] == 0xfc)
+ mdelay(1);
+ else if (phy_table_pg[i] == 0xfb)
+ udelay(50);
+ else if (phy_table_pg[i] == 0xfa)
+ udelay(5);
+ else if (phy_table_pg[i] == 0xf9)
+ udelay(1);
+
+ _rtl92s_store_pwrindex_diffrate_offset(hw,
+ phy_table_pg[i],
+ phy_table_pg[i + 1],
+ phy_table_pg[i + 2]);
+ rtl92s_phy_set_bb_reg(hw, phy_table_pg[i],
+ phy_table_pg[i + 1],
+ phy_table_pg[i + 2]);
+ }
+ }
+
+ return true;
+}
+
+static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ bool rtstatus = true;
+
+ /* 1. Read PHY_REG.TXT BB INIT!! */
+ /* We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R */
+ if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_2T2R ||
+ rtlphy->rf_type == RF_1T1R || rtlphy->rf_type == RF_2T2R_GREEN) {
+ rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_PHY_REG);
+
+ if (rtlphy->rf_type != RF_2T2R &&
+ rtlphy->rf_type != RF_2T2R_GREEN)
+ /* so we should reconfig BB reg with the right
+ * PHY parameters. */
+ rtstatus = _rtl92s_phy_set_bb_to_diff_rf(hw,
+ BASEBAND_CONFIG_PHY_REG);
+ } else {
+ rtstatus = false;
+ }
+
+ if (rtstatus != true) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
+ ("Write BB Reg Fail!!"));
+ goto phy_BB8190_Config_ParaFile_Fail;
+ }
+
+ /* 2. If EEPROM or EFUSE autoload OK, We must config by
+ * PHY_REG_PG.txt */
+ if (rtlefuse->autoload_failflag == false) {
+ rtlphy->pwrgroup_cnt = 0;
+
+ rtstatus = _rtl92s_phy_config_bb_with_pg(hw,
+ BASEBAND_CONFIG_PHY_REG);
+ }
+ if (rtstatus != true) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
+ ("_rtl92s_phy_bb_config_parafile(): "
+ "BB_PG Reg Fail!!"));
+ goto phy_BB8190_Config_ParaFile_Fail;
+ }
+
+ /* 3. BB AGC table Initialization */
+ rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB);
+
+ if (rtstatus != true) {
+ printk(KERN_ERR "_rtl92s_phy_bb_config_parafile(): "
+ "AGC Table Fail\n");
+ goto phy_BB8190_Config_ParaFile_Fail;
+ }
+
+ /* Check if the CCK HighPower is turned ON. */
+ /* This is used to calculate PWDB. */
+ rtlphy->cck_high_power = (bool)(rtl92s_phy_query_bb_reg(hw,
+ RFPGA0_XA_HSSIPARAMETER2, 0x200));
+
+phy_BB8190_Config_ParaFile_Fail:
+ return rtstatus;
+}
+
+u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ int i;
+ bool rtstatus = true;
+ u32 *radio_a_table;
+ u32 *radio_b_table;
+ u16 radio_a_tblen, radio_b_tblen;
+
+ radio_a_tblen = RADIOA_1T_ARRAYLENGTH;
+ radio_a_table = rtl8192seradioa_1t_array;
+
+ /* Using Green mode array table for RF_2T2R_GREEN */
+ if (rtlphy->rf_type == RF_2T2R_GREEN) {
+ radio_b_table = rtl8192seradiob_gm_array;
+ radio_b_tblen = RADIOB_GM_ARRAYLENGTH;
+ } else {
+ radio_b_table = rtl8192seradiob_array;
+ radio_b_tblen = RADIOB_ARRAYLENGTH;
+ }
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Radio No %x\n", rfpath));
+ rtstatus = true;
+
+ switch (rfpath) {
+ case RF90_PATH_A:
+ for (i = 0; i < radio_a_tblen; i = i + 2) {
+ if (radio_a_table[i] == 0xfe)
+ /* Delay specific ms. Only RF configuration
+ * requires delay. */
+ mdelay(50);
+ else if (radio_a_table[i] == 0xfd)
+ mdelay(5);
+ else if (radio_a_table[i] == 0xfc)
+ mdelay(1);
+ else if (radio_a_table[i] == 0xfb)
+ udelay(50);
+ else if (radio_a_table[i] == 0xfa)
+ udelay(5);
+ else if (radio_a_table[i] == 0xf9)
+ udelay(1);
+ else
+ rtl92s_phy_set_rf_reg(hw, rfpath,
+ radio_a_table[i],
+ MASK20BITS,
+ radio_a_table[i + 1]);
+
+ /* Add delay for ECS T20 & LG malow platform */
+ udelay(1);
+ }
+
+ /* PA Bias current for inferiority IC */
+ _rtl92s_phy_config_rfpa_bias_current(hw, rfpath);
+ break;
+ case RF90_PATH_B:
+ for (i = 0; i < radio_b_tblen; i = i + 2) {
+ if (radio_b_table[i] == 0xfe)
+ /* Delay specific ms. Only RF configuration
+ * requires delay.*/
+ mdelay(50);
+ else if (radio_b_table[i] == 0xfd)
+ mdelay(5);
+ else if (radio_b_table[i] == 0xfc)
+ mdelay(1);
+ else if (radio_b_table[i] == 0xfb)
+ udelay(50);
+ else if (radio_b_table[i] == 0xfa)
+ udelay(5);
+ else if (radio_b_table[i] == 0xf9)
+ udelay(1);
+ else
+ rtl92s_phy_set_rf_reg(hw, rfpath,
+ radio_b_table[i],
+ MASK20BITS,
+ radio_b_table[i + 1]);
+
+ /* Add delay for ECS T20 & LG malow platform */
+ udelay(1);
+ }
+ break;
+ case RF90_PATH_C:
+ ;
+ break;
+ case RF90_PATH_D:
+ ;
+ break;
+ default:
+ break;
+ }
+
+ return rtstatus;
+}
+
+
+bool rtl92s_phy_mac_config(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 i;
+ u32 arraylength;
+ u32 *ptraArray;
+
+ arraylength = MAC_2T_ARRAYLENGTH;
+ ptraArray = rtl8192semac_2t_array;
+
+ for (i = 0; i < arraylength; i = i + 2)
+ rtl_write_byte(rtlpriv, ptraArray[i], (u8)ptraArray[i + 1]);
+
+ return true;
+}
+
+
+bool rtl92s_phy_bb_config(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ bool rtstatus = true;
+ u8 pathmap, index, rf_num = 0;
+ u8 path1, path2;
+
+ _rtl92s_phy_init_register_definition(hw);
+
+ /* Config BB and AGC */
+ rtstatus = _rtl92s_phy_bb_config_parafile(hw);
+
+
+ /* Check BB/RF confiuration setting. */
+ /* We only need to configure RF which is turned on. */
+ path1 = (u8)(rtl92s_phy_query_bb_reg(hw, RFPGA0_TXINFO, 0xf));
+ mdelay(10);
+ path2 = (u8)(rtl92s_phy_query_bb_reg(hw, ROFDM0_TRXPATHENABLE, 0xf));
+ pathmap = path1 | path2;
+
+ rtlphy->rf_pathmap = pathmap;
+ for (index = 0; index < 4; index++) {
+ if ((pathmap >> index) & 0x1)
+ rf_num++;
+ }
+
+ if ((rtlphy->rf_type == RF_1T1R && rf_num != 1) ||
+ (rtlphy->rf_type == RF_1T2R && rf_num != 2) ||
+ (rtlphy->rf_type == RF_2T2R && rf_num != 2) ||
+ (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
+ ("RF_Type(%x) does not match "
+ "RF_Num(%x)!!\n", rtlphy->rf_type, rf_num));
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
+ ("path1 0x%x, path2 0x%x, pathmap "
+ "0x%x\n", path1, path2, pathmap));
+ }
+
+ return rtstatus;
+}
+
+bool rtl92s_phy_rf_config(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ /* Initialize general global value */
+ if (rtlphy->rf_type == RF_1T1R)
+ rtlphy->num_total_rfpath = 1;
+ else
+ rtlphy->num_total_rfpath = 2;
+
+ /* Config BB and RF */
+ return rtl92s_phy_rf6052_config(hw);
+}
+
+void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ /* read rx initial gain */
+ rtlphy->default_initialgain[0] = rtl_get_bbreg(hw,
+ ROFDM0_XAAGCCORE1, MASKBYTE0);
+ rtlphy->default_initialgain[1] = rtl_get_bbreg(hw,
+ ROFDM0_XBAGCCORE1, MASKBYTE0);
+ rtlphy->default_initialgain[2] = rtl_get_bbreg(hw,
+ ROFDM0_XCAGCCORE1, MASKBYTE0);
+ rtlphy->default_initialgain[3] = rtl_get_bbreg(hw,
+ ROFDM0_XDAGCCORE1, MASKBYTE0);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Default initial gain "
+ "(c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n",
+ rtlphy->default_initialgain[0],
+ rtlphy->default_initialgain[1],
+ rtlphy->default_initialgain[2],
+ rtlphy->default_initialgain[3]));
+
+ /* read framesync */
+ rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0);
+ rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
+ MASKDWORD);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("Default framesync (0x%x) = 0x%x\n",
+ ROFDM0_RXDETECTOR3, rtlphy->framesync));
+
+}
+
+static void _rtl92s_phy_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
+ u8 *cckpowerlevel, u8 *ofdmpowerLevel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 index = (channel - 1);
+
+ /* 1. CCK */
+ /* RF-A */
+ cckpowerlevel[0] = rtlefuse->txpwrlevel_cck[0][index];
+ /* RF-B */
+ cckpowerlevel[1] = rtlefuse->txpwrlevel_cck[1][index];
+
+ /* 2. OFDM for 1T or 2T */
+ if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) {
+ /* Read HT 40 OFDM TX power */
+ ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_1s[0][index];
+ ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_1s[1][index];
+ } else if (rtlphy->rf_type == RF_2T2R) {
+ /* Read HT 40 OFDM TX power */
+ ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_2s[0][index];
+ ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_2s[1][index];
+ }
+}
+
+static void _rtl92s_phy_ccxpower_indexcheck(struct ieee80211_hw *hw,
+ u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
+ rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
+}
+
+void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ /* [0]:RF-A, [1]:RF-B */
+ u8 cckpowerlevel[2], ofdmpowerLevel[2];
+
+ if (rtlefuse->txpwr_fromeprom == false)
+ return;
+
+ /* Mainly we use RF-A Tx Power to write the Tx Power registers,
+ * but the RF-B Tx Power must be calculated by the antenna diff.
+ * So we have to rewrite Antenna gain offset register here.
+ * Please refer to BB register 0x80c
+ * 1. For CCK.
+ * 2. For OFDM 1T or 2T */
+ _rtl92s_phy_get_txpower_index(hw, channel, &cckpowerlevel[0],
+ &ofdmpowerLevel[0]);
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("Channel-%d, cckPowerLevel (A / B) = "
+ "0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n",
+ channel, cckpowerlevel[0], cckpowerlevel[1],
+ ofdmpowerLevel[0], ofdmpowerLevel[1]));
+
+ _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0],
+ &ofdmpowerLevel[0]);
+
+ rtl92s_phy_rf6052_set_ccktxpower(hw, cckpowerlevel[0]);
+ rtl92s_phy_rf6052_set_ofdmtxpower(hw, &ofdmpowerLevel[0], channel);
+
+}
+
+void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u16 pollingcnt = 10000;
+ u32 tmpvalue;
+
+ /* Make sure that CMD IO has be accepted by FW. */
+ do {
+ udelay(10);
+
+ tmpvalue = rtl_read_dword(rtlpriv, WFM5);
+ if (tmpvalue == 0)
+ break;
+ } while (--pollingcnt);
+
+ if (pollingcnt == 0)
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Set FW Cmd fail!!\n"));
+}
+
+
+static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ u32 input, current_aid = 0;
+
+ if (is_hal_stop(rtlhal))
+ return;
+
+ /* We re-map RA related CMD IO to combinational ones */
+ /* if FW version is v.52 or later. */
+ switch (rtlhal->current_fwcmd_io) {
+ case FW_CMD_RA_REFRESH_N:
+ rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_N_COMB;
+ break;
+ case FW_CMD_RA_REFRESH_BG:
+ rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_BG_COMB;
+ break;
+ default:
+ break;
+ }
+
+ switch (rtlhal->current_fwcmd_io) {
+ case FW_CMD_RA_RESET:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+ ("FW_CMD_RA_RESET\n"));
+ rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET);
+ rtl92s_phy_chk_fwcmd_iodone(hw);
+ break;
+ case FW_CMD_RA_ACTIVE:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+ ("FW_CMD_RA_ACTIVE\n"));
+ rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE);
+ rtl92s_phy_chk_fwcmd_iodone(hw);
+ break;
+ case FW_CMD_RA_REFRESH_N:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+ ("FW_CMD_RA_REFRESH_N\n"));
+ input = FW_RA_REFRESH;
+ rtl_write_dword(rtlpriv, WFM5, input);
+ rtl92s_phy_chk_fwcmd_iodone(hw);
+ rtl_write_dword(rtlpriv, WFM5, FW_RA_ENABLE_RSSI_MASK);
+ rtl92s_phy_chk_fwcmd_iodone(hw);
+ break;
+ case FW_CMD_RA_REFRESH_BG:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+ ("FW_CMD_RA_REFRESH_BG\n"));
+ rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH);
+ rtl92s_phy_chk_fwcmd_iodone(hw);
+ rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK);
+ rtl92s_phy_chk_fwcmd_iodone(hw);
+ break;
+ case FW_CMD_RA_REFRESH_N_COMB:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+ ("FW_CMD_RA_REFRESH_N_COMB\n"));
+ input = FW_RA_IOT_N_COMB;
+ rtl_write_dword(rtlpriv, WFM5, input);
+ rtl92s_phy_chk_fwcmd_iodone(hw);
+ break;
+ case FW_CMD_RA_REFRESH_BG_COMB:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+ ("FW_CMD_RA_REFRESH_BG_COMB\n"));
+ input = FW_RA_IOT_BG_COMB;
+ rtl_write_dword(rtlpriv, WFM5, input);
+ rtl92s_phy_chk_fwcmd_iodone(hw);
+ break;
+ case FW_CMD_IQK_ENABLE:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+ ("FW_CMD_IQK_ENABLE\n"));
+ rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE);
+ rtl92s_phy_chk_fwcmd_iodone(hw);
+ break;
+ case FW_CMD_PAUSE_DM_BY_SCAN:
+ /* Lower initial gain */
+ rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
+ rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
+ /* CCA threshold */
+ rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
+ break;
+ case FW_CMD_RESUME_DM_BY_SCAN:
+ /* CCA threshold */
+ rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
+ rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
+ break;
+ case FW_CMD_HIGH_PWR_DISABLE:
+ if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE)
+ break;
+
+ /* Lower initial gain */
+ rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
+ rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
+ /* CCA threshold */
+ rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
+ break;
+ case FW_CMD_HIGH_PWR_ENABLE:
+ if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
+ (rtlpriv->dm.dynamic_txpower_enable == true))
+ break;
+
+ /* CCA threshold */
+ rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
+ break;
+ case FW_CMD_LPS_ENTER:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+ ("FW_CMD_LPS_ENTER\n"));
+ current_aid = rtlpriv->mac80211.assoc_id;
+ rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER |
+ ((current_aid | 0xc000) << 8)));
+ rtl92s_phy_chk_fwcmd_iodone(hw);
+ /* FW set TXOP disable here, so disable EDCA
+ * turbo mode until driver leave LPS */
+ break;
+ case FW_CMD_LPS_LEAVE:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+ ("FW_CMD_LPS_LEAVE\n"));
+ rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE);
+ rtl92s_phy_chk_fwcmd_iodone(hw);
+ break;
+ case FW_CMD_ADD_A2_ENTRY:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+ ("FW_CMD_ADD_A2_ENTRY\n"));
+ rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY);
+ rtl92s_phy_chk_fwcmd_iodone(hw);
+ break;
+ case FW_CMD_CTRL_DM_BY_DRIVER:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ ("FW_CMD_CTRL_DM_BY_DRIVER\n"));
+ rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER);
+ rtl92s_phy_chk_fwcmd_iodone(hw);
+ break;
+
+ default:
+ break;
+ }
+
+ rtl92s_phy_chk_fwcmd_iodone(hw);
+
+ /* Clear FW CMD operation flag. */
+ rtlhal->set_fwcmd_inprogress = false;
+}
+
+bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u32 fw_param = FW_CMD_IO_PARA_QUERY(rtlpriv);
+ u16 fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv);
+ bool bPostProcessing = false;
+
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ ("Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n",
+ fw_cmdio, rtlhal->set_fwcmd_inprogress));
+
+ do {
+ /* We re-map to combined FW CMD ones if firmware version */
+ /* is v.53 or later. */
+ switch (fw_cmdio) {
+ case FW_CMD_RA_REFRESH_N:
+ fw_cmdio = FW_CMD_RA_REFRESH_N_COMB;
+ break;
+ case FW_CMD_RA_REFRESH_BG:
+ fw_cmdio = FW_CMD_RA_REFRESH_BG_COMB;
+ break;
+ default:
+ break;
+ }
+
+ /* If firmware version is v.62 or later,
+ * use FW_CMD_IO_SET for FW_CMD_CTRL_DM_BY_DRIVER */
+ if (hal_get_firmwareversion(rtlpriv) >= 0x3E) {
+ if (fw_cmdio == FW_CMD_CTRL_DM_BY_DRIVER)
+ fw_cmdio = FW_CMD_CTRL_DM_BY_DRIVER_NEW;
+ }
+
+
+ /* We shall revise all FW Cmd IO into Reg0x364
+ * DM map table in the future. */
+ switch (fw_cmdio) {
+ case FW_CMD_RA_INIT:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("RA init!!\n"));
+ fw_cmdmap |= FW_RA_INIT_CTL;
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+ /* Clear control flag to sync with FW. */
+ FW_CMD_IO_CLR(rtlpriv, FW_RA_INIT_CTL);
+ break;
+ case FW_CMD_DIG_DISABLE:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ ("Set DIG disable!!\n"));
+ fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+ break;
+ case FW_CMD_DIG_ENABLE:
+ case FW_CMD_DIG_RESUME:
+ if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) {
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ ("Set DIG enable or resume!!\n"));
+ fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL);
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+ }
+ break;
+ case FW_CMD_DIG_HALT:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ ("Set DIG halt!!\n"));
+ fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL);
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+ break;
+ case FW_CMD_TXPWR_TRACK_THERMAL: {
+ u8 thermalval = 0;
+ fw_cmdmap |= FW_PWR_TRK_CTL;
+
+ /* Clear FW parameter in terms of thermal parts. */
+ fw_param &= FW_PWR_TRK_PARAM_CLR;
+
+ thermalval = rtlpriv->dm.thermalvalue;
+ fw_param |= ((thermalval << 24) |
+ (rtlefuse->thermalmeter[0] << 16));
+
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ ("Set TxPwr tracking!! "
+ "FwCmdMap(%#x), FwParam(%#x)\n",
+ fw_cmdmap, fw_param));
+
+ FW_CMD_PARA_SET(rtlpriv, fw_param);
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+
+ /* Clear control flag to sync with FW. */
+ FW_CMD_IO_CLR(rtlpriv, FW_PWR_TRK_CTL);
+ }
+ break;
+ /* The following FW CMDs are only compatible to
+ * v.53 or later. */
+ case FW_CMD_RA_REFRESH_N_COMB:
+ fw_cmdmap |= FW_RA_N_CTL;
+
+ /* Clear RA BG mode control. */
+ fw_cmdmap &= ~(FW_RA_BG_CTL | FW_RA_INIT_CTL);
+
+ /* Clear FW parameter in terms of RA parts. */
+ fw_param &= FW_RA_PARAM_CLR;
+
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ ("[FW CMD] [New Version] "
+ "Set RA/IOT Comb in n mode!! FwCmdMap(%#x), "
+ "FwParam(%#x)\n", fw_cmdmap, fw_param));
+
+ FW_CMD_PARA_SET(rtlpriv, fw_param);
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+
+ /* Clear control flag to sync with FW. */
+ FW_CMD_IO_CLR(rtlpriv, FW_RA_N_CTL);
+ break;
+ case FW_CMD_RA_REFRESH_BG_COMB:
+ fw_cmdmap |= FW_RA_BG_CTL;
+
+ /* Clear RA n-mode control. */
+ fw_cmdmap &= ~(FW_RA_N_CTL | FW_RA_INIT_CTL);
+ /* Clear FW parameter in terms of RA parts. */
+ fw_param &= FW_RA_PARAM_CLR;
+
+ FW_CMD_PARA_SET(rtlpriv, fw_param);
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+
+ /* Clear control flag to sync with FW. */
+ FW_CMD_IO_CLR(rtlpriv, FW_RA_BG_CTL);
+ break;
+ case FW_CMD_IQK_ENABLE:
+ fw_cmdmap |= FW_IQK_CTL;
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+ /* Clear control flag to sync with FW. */
+ FW_CMD_IO_CLR(rtlpriv, FW_IQK_CTL);
+ break;
+ /* The following FW CMD is compatible to v.62 or later. */
+ case FW_CMD_CTRL_DM_BY_DRIVER_NEW:
+ fw_cmdmap |= FW_DRIVER_CTRL_DM_CTL;
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+ break;
+ /* The followed FW Cmds needs post-processing later. */
+ case FW_CMD_RESUME_DM_BY_SCAN:
+ fw_cmdmap |= (FW_DIG_ENABLE_CTL |
+ FW_HIGH_PWR_ENABLE_CTL |
+ FW_SS_CTL);
+
+ if (rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE ||
+ !digtable.dig_enable_flag)
+ fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
+
+ if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
+ (rtlpriv->dm.dynamic_txpower_enable == true))
+ fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
+
+ if ((digtable.dig_ext_port_stage ==
+ DIG_EXT_PORT_STAGE_0) ||
+ (digtable.dig_ext_port_stage ==
+ DIG_EXT_PORT_STAGE_1))
+ fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
+
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+ bPostProcessing = true;
+ break;
+ case FW_CMD_PAUSE_DM_BY_SCAN:
+ fw_cmdmap &= ~(FW_DIG_ENABLE_CTL |
+ FW_HIGH_PWR_ENABLE_CTL |
+ FW_SS_CTL);
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+ bPostProcessing = true;
+ break;
+ case FW_CMD_HIGH_PWR_DISABLE:
+ fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+ bPostProcessing = true;
+ break;
+ case FW_CMD_HIGH_PWR_ENABLE:
+ if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) &&
+ (rtlpriv->dm.dynamic_txpower_enable != true)) {
+ fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL |
+ FW_SS_CTL);
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+ bPostProcessing = true;
+ }
+ break;
+ case FW_CMD_DIG_MODE_FA:
+ fw_cmdmap |= FW_FA_CTL;
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+ break;
+ case FW_CMD_DIG_MODE_SS:
+ fw_cmdmap &= ~FW_FA_CTL;
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+ break;
+ case FW_CMD_PAPE_CONTROL:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ ("[FW CMD] Set PAPE Control\n"));
+ fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW;
+
+ FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+ break;
+ default:
+ /* Pass to original FW CMD processing callback
+ * routine. */
+ bPostProcessing = true;
+ break;
+ }
+ } while (false);
+
+ /* We shall post processing these FW CMD if
+ * variable bPostProcessing is set. */
+ if (bPostProcessing && !rtlhal->set_fwcmd_inprogress) {
+ rtlhal->set_fwcmd_inprogress = true;
+ /* Update current FW Cmd for callback use. */
+ rtlhal->current_fwcmd_io = fw_cmdio;
+ } else {
+ return false;
+ }
+
+ _rtl92s_phy_set_fwcmd_io(hw);
+ return true;
+}
+
+static void _rtl92s_phy_check_ephy_switchready(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 delay = 100;
+ u8 regu1;
+
+ regu1 = rtl_read_byte(rtlpriv, 0x554);
+ while ((regu1 & BIT(5)) && (delay > 0)) {
+ regu1 = rtl_read_byte(rtlpriv, 0x554);
+ delay--;
+ /* We delay only 50us to prevent
+ * being scheduled out. */
+ udelay(50);
+ }
+}
+
+void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ /* The way to be capable to switch clock request
+ * when the PG setting does not support clock request.
+ * This is the backdoor solution to switch clock
+ * request before ASPM or D3. */
+ rtl_write_dword(rtlpriv, 0x540, 0x73c11);
+ rtl_write_dword(rtlpriv, 0x548, 0x2407c);
+
+ /* Switch EPHY parameter!!!! */
+ rtl_write_word(rtlpriv, 0x550, 0x1000);
+ rtl_write_byte(rtlpriv, 0x554, 0x20);
+ _rtl92s_phy_check_ephy_switchready(hw);
+
+ rtl_write_word(rtlpriv, 0x550, 0xa0eb);
+ rtl_write_byte(rtlpriv, 0x554, 0x3e);
+ _rtl92s_phy_check_ephy_switchready(hw);
+
+ rtl_write_word(rtlpriv, 0x550, 0xff80);
+ rtl_write_byte(rtlpriv, 0x554, 0x39);
+ _rtl92s_phy_check_ephy_switchready(hw);
+
+ /* Delay L1 enter time */
+ if (ppsc->support_aspm && !ppsc->support_backdoor)
+ rtl_write_byte(rtlpriv, 0x560, 0x40);
+ else
+ rtl_write_byte(rtlpriv, 0x560, 0x00);
+
+}
+
+void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 BeaconInterval)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ rtl_write_dword(rtlpriv, WFM5, 0xF1000000 | (BeaconInterval << 8));
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.h b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h
new file mode 100644
index 00000000000..37e504af644
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h
@@ -0,0 +1,101 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __RTL92S_PHY_H__
+#define __RTL92S_PHY_H__
+
+#define MAX_TXPWR_IDX_NMODE_92S 63
+#define MAX_DOZE_WAITING_TIMES_9x 64
+
+/* Channel switch:The size of
+ * command tables for switch channel */
+#define MAX_PRECMD_CNT 16
+#define MAX_RFDEPENDCMD_CNT 16
+#define MAX_POSTCMD_CNT 16
+
+#define RF90_PATH_MAX 4
+
+enum version_8192s {
+ VERSION_8192S_ACUT,
+ VERSION_8192S_BCUT,
+ VERSION_8192S_CCUT
+};
+
+enum swchnlcmd_id {
+ CMDID_END,
+ CMDID_SET_TXPOWEROWER_LEVEL,
+ CMDID_BBREGWRITE10,
+ CMDID_WRITEPORT_ULONG,
+ CMDID_WRITEPORT_USHORT,
+ CMDID_WRITEPORT_UCHAR,
+ CMDID_RF_WRITEREG,
+};
+
+struct swchnlcmd {
+ enum swchnlcmd_id cmdid;
+ u32 para1;
+ u32 para2;
+ u32 msdelay;
+};
+
+enum baseband_config_type {
+ /* Radio Path A */
+ BASEBAND_CONFIG_PHY_REG = 0,
+ /* Radio Path B */
+ BASEBAND_CONFIG_AGC_TAB = 1,
+};
+
+#define hal_get_firmwareversion(rtlpriv) \
+ (((struct rt_firmware *)(rtlpriv->rtlhal.pfirmware))->firmwareversion)
+
+u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask);
+void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
+ u32 data);
+void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
+u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
+ u32 regaddr, u32 bitmask);
+void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
+ u32 regaddr, u32 bitmask, u32 data);
+void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
+ enum nl80211_channel_type ch_type);
+u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw);
+bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
+ enum rf_pwrstate rfpower_state);
+bool rtl92s_phy_mac_config(struct ieee80211_hw *hw);
+void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw);
+bool rtl92s_phy_bb_config(struct ieee80211_hw *hw);
+bool rtl92s_phy_rf_config(struct ieee80211_hw *hw);
+void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
+void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel);
+bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fwcmd_io);
+void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw);
+void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 beaconinterval);
+u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath) ;
+
+#endif
+
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h
new file mode 100644
index 00000000000..0116eaddbfa
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h
@@ -0,0 +1,1188 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __REALTEK_92S_REG_H__
+#define __REALTEK_92S_REG_H__
+
+/* 1. System Configuration Registers */
+#define REG_SYS_ISO_CTRL 0x0000
+#define REG_SYS_FUNC_EN 0x0002
+#define PMC_FSM 0x0004
+#define SYS_CLKR 0x0008
+#define EPROM_CMD 0x000A
+#define EE_VPD 0x000C
+#define AFE_MISC 0x0010
+#define SPS0_CTRL 0x0011
+#define SPS1_CTRL 0x0018
+#define RF_CTRL 0x001F
+#define LDOA15_CTRL 0x0020
+#define LDOV12D_CTRL 0x0021
+#define LDOHCI12_CTRL 0x0022
+#define LDO_USB_SDIO 0x0023
+#define LPLDO_CTRL 0x0024
+#define AFE_XTAL_CTRL 0x0026
+#define AFE_PLL_CTRL 0x0028
+#define REG_EFUSE_CTRL 0x0030
+#define REG_EFUSE_TEST 0x0034
+#define PWR_DATA 0x0038
+#define DBG_PORT 0x003A
+#define DPS_TIMER 0x003C
+#define RCLK_MON 0x003E
+
+/* 2. Command Control Registers */
+#define CMDR 0x0040
+#define TXPAUSE 0x0042
+#define LBKMD_SEL 0x0043
+#define TCR 0x0044
+#define RCR 0x0048
+#define MSR 0x004C
+#define SYSF_CFG 0x004D
+#define RX_PKY_LIMIT 0x004E
+#define MBIDCTRL 0x004F
+
+/* 3. MACID Setting Registers */
+#define MACIDR 0x0050
+#define MACIDR0 0x0050
+#define MACIDR4 0x0054
+#define BSSIDR 0x0058
+#define HWVID 0x005E
+#define MAR 0x0060
+#define MBIDCAMCONTENT 0x0068
+#define MBIDCAMCFG 0x0070
+#define BUILDTIME 0x0074
+#define BUILDUSER 0x0078
+
+#define IDR0 MACIDR0
+#define IDR4 MACIDR4
+
+/* 4. Timing Control Registers */
+#define TSFR 0x0080
+#define SLOT_TIME 0x0089
+#define USTIME 0x008A
+#define SIFS_CCK 0x008C
+#define SIFS_OFDM 0x008E
+#define PIFS_TIME 0x0090
+#define ACK_TIMEOUT 0x0091
+#define EIFSTR 0x0092
+#define BCN_INTERVAL 0x0094
+#define ATIMWND 0x0096
+#define BCN_DRV_EARLY_INT 0x0098
+#define BCN_DMATIME 0x009A
+#define BCN_ERR_THRESH 0x009C
+#define MLT 0x009D
+#define RSVD_MAC_TUNE_US 0x009E
+
+/* 5. FIFO Control Registers */
+#define RQPN 0x00A0
+#define RQPN1 0x00A0
+#define RQPN2 0x00A1
+#define RQPN3 0x00A2
+#define RQPN4 0x00A3
+#define RQPN5 0x00A4
+#define RQPN6 0x00A5
+#define RQPN7 0x00A6
+#define RQPN8 0x00A7
+#define RQPN9 0x00A8
+#define RQPN10 0x00A9
+#define LD_RQPN 0x00AB
+#define RXFF_BNDY 0x00AC
+#define RXRPT_BNDY 0x00B0
+#define TXPKTBUF_PGBNDY 0x00B4
+#define PBP 0x00B5
+#define RXDRVINFO_SZ 0x00B6
+#define TXFF_STATUS 0x00B7
+#define RXFF_STATUS 0x00B8
+#define TXFF_EMPTY_TH 0x00B9
+#define SDIO_RX_BLKSZ 0x00BC
+#define RXDMA 0x00BD
+#define RXPKT_NUM 0x00BE
+#define C2HCMD_UDT_SIZE 0x00C0
+#define C2HCMD_UDT_ADDR 0x00C2
+#define FIFOPAGE1 0x00C4
+#define FIFOPAGE2 0x00C8
+#define FIFOPAGE3 0x00CC
+#define FIFOPAGE4 0x00D0
+#define FIFOPAGE5 0x00D4
+#define FW_RSVD_PG_CRTL 0x00D8
+#define RXDMA_AGG_PG_TH 0x00D9
+#define TXDESC_MSK 0x00DC
+#define TXRPTFF_RDPTR 0x00E0
+#define TXRPTFF_WTPTR 0x00E4
+#define C2HFF_RDPTR 0x00E8
+#define C2HFF_WTPTR 0x00EC
+#define RXFF0_RDPTR 0x00F0
+#define RXFF0_WTPTR 0x00F4
+#define RXFF1_RDPTR 0x00F8
+#define RXFF1_WTPTR 0x00FC
+#define RXRPT0_RDPTR 0x0100
+#define RXRPT0_WTPTR 0x0104
+#define RXRPT1_RDPTR 0x0108
+#define RXRPT1_WTPTR 0x010C
+#define RX0_UDT_SIZE 0x0110
+#define RX1PKTNUM 0x0114
+#define RXFILTERMAP 0x0116
+#define RXFILTERMAP_GP1 0x0118
+#define RXFILTERMAP_GP2 0x011A
+#define RXFILTERMAP_GP3 0x011C
+#define BCNQ_CTRL 0x0120
+#define MGTQ_CTRL 0x0124
+#define HIQ_CTRL 0x0128
+#define VOTID7_CTRL 0x012c
+#define VOTID6_CTRL 0x0130
+#define VITID5_CTRL 0x0134
+#define VITID4_CTRL 0x0138
+#define BETID3_CTRL 0x013c
+#define BETID0_CTRL 0x0140
+#define BKTID2_CTRL 0x0144
+#define BKTID1_CTRL 0x0148
+#define CMDQ_CTRL 0x014c
+#define TXPKT_NUM_CTRL 0x0150
+#define TXQ_PGADD 0x0152
+#define TXFF_PG_NUM 0x0154
+#define TRXDMA_STATUS 0x0156
+
+/* 6. Adaptive Control Registers */
+#define INIMCS_SEL 0x0160
+#define TX_RATE_REG INIMCS_SEL
+#define INIRTSMCS_SEL 0x0180
+#define RRSR 0x0181
+#define ARFR0 0x0184
+#define ARFR1 0x0188
+#define ARFR2 0x018C
+#define ARFR3 0x0190
+#define ARFR4 0x0194
+#define ARFR5 0x0198
+#define ARFR6 0x019C
+#define ARFR7 0x01A0
+#define AGGLEN_LMT_H 0x01A7
+#define AGGLEN_LMT_L 0x01A8
+#define DARFRC 0x01B0
+#define RARFRC 0x01B8
+#define MCS_TXAGC 0x01C0
+#define CCK_TXAGC 0x01C8
+
+/* 7. EDCA Setting Registers */
+#define EDCAPARA_VO 0x01D0
+#define EDCAPARA_VI 0x01D4
+#define EDCAPARA_BE 0x01D8
+#define EDCAPARA_BK 0x01DC
+#define BCNTCFG 0x01E0
+#define CWRR 0x01E2
+#define ACMAVG 0x01E4
+#define AcmHwCtrl 0x01E7
+#define VO_ADMTM 0x01E8
+#define VI_ADMTM 0x01EC
+#define BE_ADMTM 0x01F0
+#define RETRY_LIMIT 0x01F4
+#define SG_RATE 0x01F6
+
+/* 8. WMAC, BA and CCX related Register. */
+#define NAV_CTRL 0x0200
+#define BW_OPMODE 0x0203
+#define BACAMCMD 0x0204
+#define BACAMCONTENT 0x0208
+
+/* the 0x2xx register WMAC definition */
+#define LBDLY 0x0210
+#define FWDLY 0x0211
+#define HWPC_RX_CTRL 0x0218
+#define MQIR 0x0220
+#define MAIR 0x0222
+#define MSIR 0x0224
+#define CLM_RESULT 0x0227
+#define NHM_RPI_CNT 0x0228
+#define RXERR_RPT 0x0230
+#define NAV_PROT_LEN 0x0234
+#define CFEND_TH 0x0236
+#define AMPDU_MIN_SPACE 0x0237
+#define TXOP_STALL_CTRL 0x0238
+
+/* 9. Security Control Registers */
+#define REG_RWCAM 0x0240
+#define REG_WCAMI 0x0244
+#define REG_RCAMO 0x0248
+#define REG_CAMDBG 0x024C
+#define REG_SECR 0x0250
+
+/* 10. Power Save Control Registers */
+#define WOW_CTRL 0x0260
+#define PSSTATUS 0x0261
+#define PSSWITCH 0x0262
+#define MIMOPS_WAIT_PERIOD 0x0263
+#define LPNAV_CTRL 0x0264
+#define WFM0 0x0270
+#define WFM1 0x0280
+#define WFM2 0x0290
+#define WFM3 0x02A0
+#define WFM4 0x02B0
+#define WFM5 0x02C0
+#define WFCRC 0x02D0
+#define FW_RPT_REG 0x02c4
+
+/* 11. General Purpose Registers */
+#define PSTIME 0x02E0
+#define TIMER0 0x02E4
+#define TIMER1 0x02E8
+#define GPIO_CTRL 0x02EC
+#define GPIO_IN 0x02EC
+#define GPIO_OUT 0x02ED
+#define GPIO_IO_SEL 0x02EE
+#define GPIO_MOD 0x02EF
+#define GPIO_INTCTRL 0x02F0
+#define MAC_PINMUX_CFG 0x02F1
+#define LEDCFG 0x02F2
+#define PHY_REG 0x02F3
+#define PHY_REG_DATA 0x02F4
+#define REG_EFUSE_CLK 0x02F8
+
+/* 12. Host Interrupt Status Registers */
+#define INTA_MASK 0x0300
+#define ISR 0x0308
+
+/* 13. Test Mode and Debug Control Registers */
+#define DBG_PORT_SWITCH 0x003A
+#define BIST 0x0310
+#define DBS 0x0314
+#define CPUINST 0x0318
+#define CPUCAUSE 0x031C
+#define LBUS_ERR_ADDR 0x0320
+#define LBUS_ERR_CMD 0x0324
+#define LBUS_ERR_DATA_L 0x0328
+#define LBUS_ERR_DATA_H 0x032C
+#define LX_EXCEPTION_ADDR 0x0330
+#define WDG_CTRL 0x0334
+#define INTMTU 0x0338
+#define INTM 0x033A
+#define FDLOCKTURN0 0x033C
+#define FDLOCKTURN1 0x033D
+#define TRXPKTBUF_DBG_DATA 0x0340
+#define TRXPKTBUF_DBG_CTRL 0x0348
+#define DPLL 0x034A
+#define CBUS_ERR_ADDR 0x0350
+#define CBUS_ERR_CMD 0x0354
+#define CBUS_ERR_DATA_L 0x0358
+#define CBUS_ERR_DATA_H 0x035C
+#define USB_SIE_INTF_ADDR 0x0360
+#define USB_SIE_INTF_WD 0x0361
+#define USB_SIE_INTF_RD 0x0362
+#define USB_SIE_INTF_CTRL 0x0363
+#define LBUS_MON_ADDR 0x0364
+#define LBUS_ADDR_MASK 0x0368
+
+/* Boundary is 0x37F */
+
+/* 14. PCIE config register */
+#define TP_POLL 0x0500
+#define PM_CTRL 0x0502
+#define PCIF 0x0503
+
+#define THPDA 0x0514
+#define TMDA 0x0518
+#define TCDA 0x051C
+#define HDA 0x0520
+#define TVODA 0x0524
+#define TVIDA 0x0528
+#define TBEDA 0x052C
+#define TBKDA 0x0530
+#define TBDA 0x0534
+#define RCDA 0x0538
+#define RDQDA 0x053C
+#define DBI_WDATA 0x0540
+#define DBI_RDATA 0x0544
+#define DBI_CTRL 0x0548
+#define MDIO_DATA 0x0550
+#define MDIO_CTRL 0x0554
+#define PCI_RPWM 0x0561
+#define PCI_CPWM 0x0563
+
+/* Config register (Offset 0x800-) */
+#define PHY_CCA 0x803
+
+/* Min Spacing related settings. */
+#define MAX_MSS_DENSITY_2T 0x13
+#define MAX_MSS_DENSITY_1T 0x0A
+
+/* Rx DMA Control related settings */
+#define RXDMA_AGG_EN BIT(7)
+
+#define RPWM PCI_RPWM
+
+/* Regsiter Bit and Content definition */
+
+#define ISO_MD2PP BIT(0)
+#define ISO_PA2PCIE BIT(3)
+#define ISO_PLL2MD BIT(4)
+#define ISO_PWC_DV2RP BIT(11)
+#define ISO_PWC_RV2RP BIT(12)
+
+
+#define FEN_MREGEN BIT(15)
+#define FEN_DCORE BIT(11)
+#define FEN_CPUEN BIT(10)
+
+#define PAD_HWPD_IDN BIT(22)
+
+#define SYS_CLKSEL_80M BIT(0)
+#define SYS_PS_CLKSEL BIT(1)
+#define SYS_CPU_CLKSEL BIT(2)
+#define SYS_MAC_CLK_EN BIT(11)
+#define SYS_SWHW_SEL BIT(14)
+#define SYS_FWHW_SEL BIT(15)
+
+#define CmdEEPROM_En BIT(5)
+#define CmdEERPOMSEL BIT(4)
+#define Cmd9346CR_9356SEL BIT(4)
+
+#define AFE_MBEN BIT(1)
+#define AFE_BGEN BIT(0)
+
+#define SPS1_SWEN BIT(1)
+#define SPS1_LDEN BIT(0)
+
+#define RF_EN BIT(0)
+#define RF_RSTB BIT(1)
+#define RF_SDMRSTB BIT(2)
+
+#define LDA15_EN BIT(0)
+
+#define LDV12_EN BIT(0)
+#define LDV12_SDBY BIT(1)
+
+#define XTAL_GATE_AFE BIT(10)
+
+#define APLL_EN BIT(0)
+
+#define AFR_CardBEn BIT(0)
+#define AFR_CLKRUN_SEL BIT(1)
+#define AFR_FuncRegEn BIT(2)
+
+#define APSDOFF_STATUS BIT(15)
+#define APSDOFF BIT(14)
+#define BBRSTN BIT(13)
+#define BB_GLB_RSTN BIT(12)
+#define SCHEDULE_EN BIT(10)
+#define MACRXEN BIT(9)
+#define MACTXEN BIT(8)
+#define DDMA_EN BIT(7)
+#define FW2HW_EN BIT(6)
+#define RXDMA_EN BIT(5)
+#define TXDMA_EN BIT(4)
+#define HCI_RXDMA_EN BIT(3)
+#define HCI_TXDMA_EN BIT(2)
+
+#define StopHCCA BIT(6)
+#define StopHigh BIT(5)
+#define StopMgt BIT(4)
+#define StopVO BIT(3)
+#define StopVI BIT(2)
+#define StopBE BIT(1)
+#define StopBK BIT(0)
+
+#define LBK_NORMAL 0x00
+#define LBK_MAC_LB (BIT(0) | BIT(1) | BIT(3))
+#define LBK_MAC_DLB (BIT(0) | BIT(1))
+#define LBK_DMA_LB (BIT(0) | BIT(1) | BIT(2))
+
+#define TCP_OFDL_EN BIT(25)
+#define HWPC_TX_EN BIT(24)
+#define TXDMAPRE2FULL BIT(23)
+#define DISCW BIT(20)
+#define TCRICV BIT(19)
+#define CfendForm BIT(17)
+#define TCRCRC BIT(16)
+#define FAKE_IMEM_EN BIT(15)
+#define TSFRST BIT(9)
+#define TSFEN BIT(8)
+#define FWALLRDY (BIT(0) | BIT(1) | BIT(2) | \
+ BIT(3) | BIT(4) | BIT(5) | \
+ BIT(6) | BIT(7))
+#define FWRDY BIT(7)
+#define BASECHG BIT(6)
+#define IMEM BIT(5)
+#define DMEM_CODE_DONE BIT(4)
+#define EXT_IMEM_CHK_RPT BIT(3)
+#define EXT_IMEM_CODE_DONE BIT(2)
+#define IMEM_CHK_RPT BIT(1)
+#define IMEM_CODE_DONE BIT(0)
+#define IMEM_CODE_DONE BIT(0)
+#define IMEM_CHK_RPT BIT(1)
+#define EMEM_CODE_DONE BIT(2)
+#define EMEM_CHK_RPT BIT(3)
+#define DMEM_CODE_DONE BIT(4)
+#define IMEM_RDY BIT(5)
+#define BASECHG BIT(6)
+#define FWRDY BIT(7)
+#define LOAD_FW_READY (IMEM_CODE_DONE | \
+ IMEM_CHK_RPT | \
+ EMEM_CODE_DONE | \
+ EMEM_CHK_RPT | \
+ DMEM_CODE_DONE | \
+ IMEM_RDY | \
+ BASECHG | \
+ FWRDY)
+#define TCR_TSFEN BIT(8)
+#define TCR_TSFRST BIT(9)
+#define TCR_FAKE_IMEM_EN BIT(15)
+#define TCR_CRC BIT(16)
+#define TCR_ICV BIT(19)
+#define TCR_DISCW BIT(20)
+#define TCR_HWPC_TX_EN BIT(24)
+#define TCR_TCP_OFDL_EN BIT(25)
+#define TXDMA_INIT_VALUE (IMEM_CHK_RPT | \
+ EXT_IMEM_CHK_RPT)
+
+#define RCR_APPFCS BIT(31)
+#define RCR_DIS_ENC_2BYTE BIT(30)
+#define RCR_DIS_AES_2BYTE BIT(29)
+#define RCR_HTC_LOC_CTRL BIT(28)
+#define RCR_ENMBID BIT(27)
+#define RCR_RX_TCPOFDL_EN BIT(26)
+#define RCR_APP_PHYST_RXFF BIT(25)
+#define RCR_APP_PHYST_STAFF BIT(24)
+#define RCR_CBSSID BIT(23)
+#define RCR_APWRMGT BIT(22)
+#define RCR_ADD3 BIT(21)
+#define RCR_AMF BIT(20)
+#define RCR_ACF BIT(19)
+#define RCR_ADF BIT(18)
+#define RCR_APP_MIC BIT(17)
+#define RCR_APP_ICV BIT(16)
+#define RCR_RXFTH BIT(13)
+#define RCR_AICV BIT(12)
+#define RCR_RXDESC_LK_EN BIT(11)
+#define RCR_APP_BA_SSN BIT(6)
+#define RCR_ACRC32 BIT(5)
+#define RCR_RXSHFT_EN BIT(4)
+#define RCR_AB BIT(3)
+#define RCR_AM BIT(2)
+#define RCR_APM BIT(1)
+#define RCR_AAP BIT(0)
+#define RCR_MXDMA_OFFSET 8
+#define RCR_FIFO_OFFSET 13
+
+
+#define MSR_LINK_MASK ((1 << 0) | (1 << 1))
+#define MSR_LINK_MANAGED 2
+#define MSR_LINK_NONE 0
+#define MSR_LINK_SHIFT 0
+#define MSR_LINK_ADHOC 1
+#define MSR_LINK_MASTER 3
+#define MSR_NOLINK 0x00
+#define MSR_ADHOC 0x01
+#define MSR_INFRA 0x02
+#define MSR_AP 0x03
+
+#define ENUART BIT(7)
+#define ENJTAG BIT(3)
+#define BTMODE (BIT(2) | BIT(1))
+#define ENBT BIT(0)
+
+#define ENMBID BIT(7)
+#define BCNUM (BIT(6) | BIT(5) | BIT(4))
+
+#define USTIME_EDCA 0xFF00
+#define USTIME_TSF 0x00FF
+
+#define SIFS_TRX 0xFF00
+#define SIFS_CTX 0x00FF
+
+#define ENSWBCN BIT(15)
+#define DRVERLY_TU 0x0FF0
+#define DRVERLY_US 0x000F
+#define BCN_TCFG_CW_SHIFT 8
+#define BCN_TCFG_IFS 0
+
+#define RRSR_RSC_OFFSET 21
+#define RRSR_SHORT_OFFSET 23
+#define RRSR_RSC_BW_40M 0x600000
+#define RRSR_RSC_UPSUBCHNL 0x400000
+#define RRSR_RSC_LOWSUBCHNL 0x200000
+#define RRSR_SHORT 0x800000
+#define RRSR_1M BIT(0)
+#define RRSR_2M BIT(1)
+#define RRSR_5_5M BIT(2)
+#define RRSR_11M BIT(3)
+#define RRSR_6M BIT(4)
+#define RRSR_9M BIT(5)
+#define RRSR_12M BIT(6)
+#define RRSR_18M BIT(7)
+#define RRSR_24M BIT(8)
+#define RRSR_36M BIT(9)
+#define RRSR_48M BIT(10)
+#define RRSR_54M BIT(11)
+#define RRSR_MCS0 BIT(12)
+#define RRSR_MCS1 BIT(13)
+#define RRSR_MCS2 BIT(14)
+#define RRSR_MCS3 BIT(15)
+#define RRSR_MCS4 BIT(16)
+#define RRSR_MCS5 BIT(17)
+#define RRSR_MCS6 BIT(18)
+#define RRSR_MCS7 BIT(19)
+#define BRSR_AckShortPmb BIT(23)
+
+#define RATR_1M 0x00000001
+#define RATR_2M 0x00000002
+#define RATR_55M 0x00000004
+#define RATR_11M 0x00000008
+#define RATR_6M 0x00000010
+#define RATR_9M 0x00000020
+#define RATR_12M 0x00000040
+#define RATR_18M 0x00000080
+#define RATR_24M 0x00000100
+#define RATR_36M 0x00000200
+#define RATR_48M 0x00000400
+#define RATR_54M 0x00000800
+#define RATR_MCS0 0x00001000
+#define RATR_MCS1 0x00002000
+#define RATR_MCS2 0x00004000
+#define RATR_MCS3 0x00008000
+#define RATR_MCS4 0x00010000
+#define RATR_MCS5 0x00020000
+#define RATR_MCS6 0x00040000
+#define RATR_MCS7 0x00080000
+#define RATR_MCS8 0x00100000
+#define RATR_MCS9 0x00200000
+#define RATR_MCS10 0x00400000
+#define RATR_MCS11 0x00800000
+#define RATR_MCS12 0x01000000
+#define RATR_MCS13 0x02000000
+#define RATR_MCS14 0x04000000
+#define RATR_MCS15 0x08000000
+
+#define RATE_ALL_CCK (RATR_1M | RATR_2M | \
+ RATR_55M | RATR_11M)
+#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | \
+ RATR_12M | RATR_18M | \
+ RATR_24M | RATR_36M | \
+ RATR_48M | RATR_54M)
+#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | \
+ RATR_MCS2 | RATR_MCS3 | \
+ RATR_MCS4 | RATR_MCS5 | \
+ RATR_MCS6 | RATR_MCS7)
+#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | \
+ RATR_MCS10 | RATR_MCS11 | \
+ RATR_MCS12 | RATR_MCS13 | \
+ RATR_MCS14 | RATR_MCS15)
+
+#define AC_PARAM_TXOP_LIMIT_OFFSET 16
+#define AC_PARAM_ECW_MAX_OFFSET 12
+#define AC_PARAM_ECW_MIN_OFFSET 8
+#define AC_PARAM_AIFS_OFFSET 0
+
+#define AcmHw_HwEn BIT(0)
+#define AcmHw_BeqEn BIT(1)
+#define AcmHw_ViqEn BIT(2)
+#define AcmHw_VoqEn BIT(3)
+#define AcmHw_BeqStatus BIT(4)
+#define AcmHw_ViqStatus BIT(5)
+#define AcmHw_VoqStatus BIT(6)
+
+#define RETRY_LIMIT_SHORT_SHIFT 8
+#define RETRY_LIMIT_LONG_SHIFT 0
+
+#define NAV_UPPER_EN BIT(16)
+#define NAV_UPPER 0xFF00
+#define NAV_RTSRST 0xFF
+
+#define BW_OPMODE_20MHZ BIT(2)
+#define BW_OPMODE_5G BIT(1)
+#define BW_OPMODE_11J BIT(0)
+
+#define RXERR_RPT_RST BIT(27)
+#define RXERR_OFDM_PPDU 0
+#define RXERR_OFDM_FALSE_ALARM 1
+#define RXERR_OFDM_MPDU_OK 2
+#define RXERR_OFDM_MPDU_FAIL 3
+#define RXERR_CCK_PPDU 4
+#define RXERR_CCK_FALSE_ALARM 5
+#define RXERR_CCK_MPDU_OK 6
+#define RXERR_CCK_MPDU_FAIL 7
+#define RXERR_HT_PPDU 8
+#define RXERR_HT_FALSE_ALARM 9
+#define RXERR_HT_MPDU_TOTAL 10
+#define RXERR_HT_MPDU_OK 11
+#define RXERR_HT_MPDU_FAIL 12
+#define RXERR_RX_FULL_DROP 15
+
+#define SCR_TXUSEDK BIT(0)
+#define SCR_RXUSEDK BIT(1)
+#define SCR_TXENCENABLE BIT(2)
+#define SCR_RXENCENABLE BIT(3)
+#define SCR_SKBYA2 BIT(4)
+#define SCR_NOSKMC BIT(5)
+
+#define CAM_VALID BIT(15)
+#define CAM_NOTVALID 0x0000
+#define CAM_USEDK BIT(5)
+
+#define CAM_NONE 0x0
+#define CAM_WEP40 0x01
+#define CAM_TKIP 0x02
+#define CAM_AES 0x04
+#define CAM_WEP104 0x05
+
+#define TOTAL_CAM_ENTRY 32
+#define HALF_CAM_ENTRY 16
+
+#define CAM_WRITE BIT(16)
+#define CAM_READ 0x00000000
+#define CAM_POLLINIG BIT(31)
+
+#define WOW_PMEN BIT(0)
+#define WOW_WOMEN BIT(1)
+#define WOW_MAGIC BIT(2)
+#define WOW_UWF BIT(3)
+
+#define GPIOMUX_EN BIT(3)
+#define GPIOSEL_GPIO 0
+#define GPIOSEL_PHYDBG 1
+#define GPIOSEL_BT 2
+#define GPIOSEL_WLANDBG 3
+#define GPIOSEL_GPIO_MASK (~(BIT(0)|BIT(1)))
+
+#define HST_RDBUSY BIT(0)
+#define CPU_WTBUSY BIT(1)
+
+#define IMR8190_DISABLED 0x0
+#define IMR_CPUERR BIT(5)
+#define IMR_ATIMEND BIT(4)
+#define IMR_TBDOK BIT(3)
+#define IMR_TBDER BIT(2)
+#define IMR_BCNDMAINT8 BIT(1)
+#define IMR_BCNDMAINT7 BIT(0)
+#define IMR_BCNDMAINT6 BIT(31)
+#define IMR_BCNDMAINT5 BIT(30)
+#define IMR_BCNDMAINT4 BIT(29)
+#define IMR_BCNDMAINT3 BIT(28)
+#define IMR_BCNDMAINT2 BIT(27)
+#define IMR_BCNDMAINT1 BIT(26)
+#define IMR_BCNDOK8 BIT(25)
+#define IMR_BCNDOK7 BIT(24)
+#define IMR_BCNDOK6 BIT(23)
+#define IMR_BCNDOK5 BIT(22)
+#define IMR_BCNDOK4 BIT(21)
+#define IMR_BCNDOK3 BIT(20)
+#define IMR_BCNDOK2 BIT(19)
+#define IMR_BCNDOK1 BIT(18)
+#define IMR_TIMEOUT2 BIT(17)
+#define IMR_TIMEOUT1 BIT(16)
+#define IMR_TXFOVW BIT(15)
+#define IMR_PSTIMEOUT BIT(14)
+#define IMR_BCNINT BIT(13)
+#define IMR_RXFOVW BIT(12)
+#define IMR_RDU BIT(11)
+#define IMR_RXCMDOK BIT(10)
+#define IMR_BDOK BIT(9)
+#define IMR_HIGHDOK BIT(8)
+#define IMR_COMDOK BIT(7)
+#define IMR_MGNTDOK BIT(6)
+#define IMR_HCCADOK BIT(5)
+#define IMR_BKDOK BIT(4)
+#define IMR_BEDOK BIT(3)
+#define IMR_VIDOK BIT(2)
+#define IMR_VODOK BIT(1)
+#define IMR_ROK BIT(0)
+
+#define TPPOLL_BKQ BIT(0)
+#define TPPOLL_BEQ BIT(1)
+#define TPPOLL_VIQ BIT(2)
+#define TPPOLL_VOQ BIT(3)
+#define TPPOLL_BQ BIT(4)
+#define TPPOLL_CQ BIT(5)
+#define TPPOLL_MQ BIT(6)
+#define TPPOLL_HQ BIT(7)
+#define TPPOLL_HCCAQ BIT(8)
+#define TPPOLL_STOPBK BIT(9)
+#define TPPOLL_STOPBE BIT(10)
+#define TPPOLL_STOPVI BIT(11)
+#define TPPOLL_STOPVO BIT(12)
+#define TPPOLL_STOPMGT BIT(13)
+#define TPPOLL_STOPHIGH BIT(14)
+#define TPPOLL_STOPHCCA BIT(15)
+#define TPPOLL_SHIFT 8
+
+#define CCX_CMD_CLM_ENABLE BIT(0)
+#define CCX_CMD_NHM_ENABLE BIT(1)
+#define CCX_CMD_FUNCTION_ENABLE BIT(8)
+#define CCX_CMD_IGNORE_CCA BIT(9)
+#define CCX_CMD_IGNORE_TXON BIT(10)
+#define CCX_CLM_RESULT_READY BIT(16)
+#define CCX_NHM_RESULT_READY BIT(16)
+#define CCX_CMD_RESET 0x0
+
+
+#define HWSET_MAX_SIZE_92S 128
+#define EFUSE_MAX_SECTION 16
+#define EFUSE_REAL_CONTENT_LEN 512
+
+#define RTL8190_EEPROM_ID 0x8129
+#define EEPROM_HPON 0x02
+#define EEPROM_CLK 0x06
+#define EEPROM_TESTR 0x08
+
+#define EEPROM_VID 0x0A
+#define EEPROM_DID 0x0C
+#define EEPROM_SVID 0x0E
+#define EEPROM_SMID 0x10
+
+#define EEPROM_MAC_ADDR 0x12
+#define EEPROM_NODE_ADDRESS_BYTE_0 0x12
+
+#define EEPROM_PWDIFF 0x54
+
+#define EEPROM_TXPOWERBASE 0x50
+#define EEPROM_TX_PWR_INDEX_RANGE 28
+
+#define EEPROM_TX_PWR_HT20_DIFF 0x62
+#define DEFAULT_HT20_TXPWR_DIFF 2
+#define EEPROM_TX_PWR_OFDM_DIFF 0x65
+
+#define EEPROM_TXPWRGROUP 0x67
+#define EEPROM_REGULATORY 0x6D
+
+#define TX_PWR_SAFETY_CHK 0x6D
+#define EEPROM_TXPWINDEX_CCK_24G 0x5D
+#define EEPROM_TXPWINDEX_OFDM_24G 0x6B
+#define EEPROM_HT2T_CH1_A 0x6c
+#define EEPROM_HT2T_CH7_A 0x6d
+#define EEPROM_HT2T_CH13_A 0x6e
+#define EEPROM_HT2T_CH1_B 0x6f
+#define EEPROM_HT2T_CH7_B 0x70
+#define EEPROM_HT2T_CH13_B 0x71
+
+#define EEPROM_TSSI_A 0x74
+#define EEPROM_TSSI_B 0x75
+
+#define EEPROM_RFIND_POWERDIFF 0x76
+#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
+
+#define EEPROM_THERMALMETER 0x77
+#define EEPROM_BLUETOOTH_COEXIST 0x78
+#define EEPROM_BLUETOOTH_TYPE 0x4f
+
+#define EEPROM_OPTIONAL 0x78
+#define EEPROM_WOWLAN 0x78
+
+#define EEPROM_CRYSTALCAP 0x79
+#define EEPROM_CHANNELPLAN 0x7B
+#define EEPROM_VERSION 0x7C
+#define EEPROM_CUSTOMID 0x7A
+#define EEPROM_BOARDTYPE 0x7E
+
+#define EEPROM_CHANNEL_PLAN_FCC 0x0
+#define EEPROM_CHANNEL_PLAN_IC 0x1
+#define EEPROM_CHANNEL_PLAN_ETSI 0x2
+#define EEPROM_CHANNEL_PLAN_SPAIN 0x3
+#define EEPROM_CHANNEL_PLAN_FRANCE 0x4
+#define EEPROM_CHANNEL_PLAN_MKK 0x5
+#define EEPROM_CHANNEL_PLAN_MKK1 0x6
+#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7
+#define EEPROM_CHANNEL_PLAN_TELEC 0x8
+#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9
+#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA
+#define EEPROM_CHANNEL_PLAN_NCC 0xB
+#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
+
+#define FW_DIG_DISABLE 0xfd00cc00
+#define FW_DIG_ENABLE 0xfd000000
+#define FW_DIG_HALT 0xfd000001
+#define FW_DIG_RESUME 0xfd000002
+#define FW_HIGH_PWR_DISABLE 0xfd000008
+#define FW_HIGH_PWR_ENABLE 0xfd000009
+#define FW_ADD_A2_ENTRY 0xfd000016
+#define FW_TXPWR_TRACK_ENABLE 0xfd000017
+#define FW_TXPWR_TRACK_DISABLE 0xfd000018
+#define FW_TXPWR_TRACK_THERMAL 0xfd000019
+#define FW_TXANT_SWITCH_ENABLE 0xfd000023
+#define FW_TXANT_SWITCH_DISABLE 0xfd000024
+#define FW_RA_INIT 0xfd000026
+#define FW_CTRL_DM_BY_DRIVER 0Xfd00002a
+#define FW_RA_IOT_BG_COMB 0xfd000030
+#define FW_RA_IOT_N_COMB 0xfd000031
+#define FW_RA_REFRESH 0xfd0000a0
+#define FW_RA_UPDATE_MASK 0xfd0000a2
+#define FW_RA_DISABLE 0xfd0000a4
+#define FW_RA_ACTIVE 0xfd0000a6
+#define FW_RA_DISABLE_RSSI_MASK 0xfd0000ac
+#define FW_RA_ENABLE_RSSI_MASK 0xfd0000ad
+#define FW_RA_RESET 0xfd0000af
+#define FW_DM_DISABLE 0xfd00aa00
+#define FW_IQK_ENABLE 0xf0000020
+#define FW_IQK_SUCCESS 0x0000dddd
+#define FW_IQK_FAIL 0x0000ffff
+#define FW_OP_FAILURE 0xffffffff
+#define FW_TX_FEEDBACK_NONE 0xfb000000
+#define FW_TX_FEEDBACK_DTM_ENABLE (FW_TX_FEEDBACK_NONE | 0x1)
+#define FW_TX_FEEDBACK_CCX_ENABL (FW_TX_FEEDBACK_NONE | 0x2)
+#define FW_BB_RESET_ENABLE 0xff00000d
+#define FW_BB_RESET_DISABLE 0xff00000e
+#define FW_CCA_CHK_ENABLE 0xff000011
+#define FW_CCK_RESET_CNT 0xff000013
+#define FW_LPS_ENTER 0xfe000010
+#define FW_LPS_LEAVE 0xfe000011
+#define FW_INDIRECT_READ 0xf2000000
+#define FW_INDIRECT_WRITE 0xf2000001
+#define FW_CHAN_SET 0xf3000001
+
+#define RFPC 0x5F
+#define RCR_9356SEL BIT(6)
+#define TCR_LRL_OFFSET 0
+#define TCR_SRL_OFFSET 8
+#define TCR_MXDMA_OFFSET 21
+#define TCR_SAT BIT(24)
+#define RCR_MXDMA_OFFSET 8
+#define RCR_FIFO_OFFSET 13
+#define RCR_OnlyErlPkt BIT(31)
+#define CWR 0xDC
+#define RETRYCTR 0xDE
+
+#define CPU_GEN_SYSTEM_RESET 0x00000001
+
+#define CCX_COMMAND_REG 0x890
+#define CLM_PERIOD_REG 0x894
+#define NHM_PERIOD_REG 0x896
+
+#define NHM_THRESHOLD0 0x898
+#define NHM_THRESHOLD1 0x899
+#define NHM_THRESHOLD2 0x89A
+#define NHM_THRESHOLD3 0x89B
+#define NHM_THRESHOLD4 0x89C
+#define NHM_THRESHOLD5 0x89D
+#define NHM_THRESHOLD6 0x89E
+#define CLM_RESULT_REG 0x8D0
+#define NHM_RESULT_REG 0x8D4
+#define NHM_RPI_COUNTER0 0x8D8
+#define NHM_RPI_COUNTER1 0x8D9
+#define NHM_RPI_COUNTER2 0x8DA
+#define NHM_RPI_COUNTER3 0x8DB
+#define NHM_RPI_COUNTER4 0x8DC
+#define NHM_RPI_COUNTER5 0x8DD
+#define NHM_RPI_COUNTER6 0x8DE
+#define NHM_RPI_COUNTER7 0x8DF
+
+#define HAL_8192S_HW_GPIO_OFF_BIT BIT(3)
+#define HAL_8192S_HW_GPIO_OFF_MASK 0xF7
+#define HAL_8192S_HW_GPIO_WPS_BIT BIT(4)
+
+#define RPMAC_RESET 0x100
+#define RPMAC_TXSTART 0x104
+#define RPMAC_TXLEGACYSIG 0x108
+#define RPMAC_TXHTSIG1 0x10c
+#define RPMAC_TXHTSIG2 0x110
+#define RPMAC_PHYDEBUG 0x114
+#define RPMAC_TXPACKETNNM 0x118
+#define RPMAC_TXIDLE 0x11c
+#define RPMAC_TXMACHEADER0 0x120
+#define RPMAC_TXMACHEADER1 0x124
+#define RPMAC_TXMACHEADER2 0x128
+#define RPMAC_TXMACHEADER3 0x12c
+#define RPMAC_TXMACHEADER4 0x130
+#define RPMAC_TXMACHEADER5 0x134
+#define RPMAC_TXDATATYPE 0x138
+#define RPMAC_TXRANDOMSEED 0x13c
+#define RPMAC_CCKPLCPPREAMBLE 0x140
+#define RPMAC_CCKPLCPHEADER 0x144
+#define RPMAC_CCKCRC16 0x148
+#define RPMAC_OFDMRXCRC32OK 0x170
+#define RPMAC_OFDMRXCRC32ER 0x174
+#define RPMAC_OFDMRXPARITYER 0x178
+#define RPMAC_OFDMRXCRC8ER 0x17c
+#define RPMAC_CCKCRXRC16ER 0x180
+#define RPMAC_CCKCRXRC32ER 0x184
+#define RPMAC_CCKCRXRC32OK 0x188
+#define RPMAC_TXSTATUS 0x18c
+
+#define RF_BB_CMD_ADDR 0x02c0
+#define RF_BB_CMD_DATA 0x02c4
+
+#define RFPGA0_RFMOD 0x800
+
+#define RFPGA0_TXINFO 0x804
+#define RFPGA0_PSDFUNCTION 0x808
+
+#define RFPGA0_TXGAINSTAGE 0x80c
+
+#define RFPGA0_RFTIMING1 0x810
+#define RFPGA0_RFTIMING2 0x814
+#define RFPGA0_XA_HSSIPARAMETER1 0x820
+#define RFPGA0_XA_HSSIPARAMETER2 0x824
+#define RFPGA0_XB_HSSIPARAMETER1 0x828
+#define RFPGA0_XB_HSSIPARAMETER2 0x82c
+#define RFPGA0_XC_HSSIPARAMETER1 0x830
+#define RFPGA0_XC_HSSIPARAMETER2 0x834
+#define RFPGA0_XD_HSSIPARAMETER1 0x838
+#define RFPGA0_XD_HSSIPARAMETER2 0x83c
+#define RFPGA0_XA_LSSIPARAMETER 0x840
+#define RFPGA0_XB_LSSIPARAMETER 0x844
+#define RFPGA0_XC_LSSIPARAMETER 0x848
+#define RFPGA0_XD_LSSIPARAMETER 0x84c
+
+#define RFPGA0_RFWAKEUP_PARAMETER 0x850
+#define RFPGA0_RFSLEEPUP_PARAMETER 0x854
+
+#define RFPGA0_XAB_SWITCHCONTROL 0x858
+#define RFPGA0_XCD_SWITCHCONTROL 0x85c
+
+#define RFPGA0_XA_RFINTERFACEOE 0x860
+#define RFPGA0_XB_RFINTERFACEOE 0x864
+#define RFPGA0_XC_RFINTERFACEOE 0x868
+#define RFPGA0_XD_RFINTERFACEOE 0x86c
+
+#define RFPGA0_XAB_RFINTERFACESW 0x870
+#define RFPGA0_XCD_RFINTERFACESW 0x874
+
+#define RFPGA0_XAB_RFPARAMETER 0x878
+#define RFPGA0_XCD_RFPARAMETER 0x87c
+
+#define RFPGA0_ANALOGPARAMETER1 0x880
+#define RFPGA0_ANALOGPARAMETER2 0x884
+#define RFPGA0_ANALOGPARAMETER3 0x888
+#define RFPGA0_ANALOGPARAMETER4 0x88c
+
+#define RFPGA0_XA_LSSIREADBACK 0x8a0
+#define RFPGA0_XB_LSSIREADBACK 0x8a4
+#define RFPGA0_XC_LSSIREADBACK 0x8a8
+#define RFPGA0_XD_LSSIREADBACK 0x8ac
+
+#define RFPGA0_PSDREPORT 0x8b4
+#define TRANSCEIVERA_HSPI_READBACK 0x8b8
+#define TRANSCEIVERB_HSPI_READBACK 0x8bc
+#define RFPGA0_XAB_RFINTERFACERB 0x8e0
+#define RFPGA0_XCD_RFINTERFACERB 0x8e4
+#define RFPGA1_RFMOD 0x900
+
+#define RFPGA1_TXBLOCK 0x904
+#define RFPGA1_DEBUGSELECT 0x908
+#define RFPGA1_TXINFO 0x90c
+
+#define RCCK0_SYSTEM 0xa00
+
+#define RCCK0_AFESETTING 0xa04
+#define RCCK0_CCA 0xa08
+
+#define RCCK0_RXAGC1 0xa0c
+#define RCCK0_RXAGC2 0xa10
+
+#define RCCK0_RXHP 0xa14
+
+#define RCCK0_DSPPARAMETER1 0xa18
+#define RCCK0_DSPPARAMETER2 0xa1c
+
+#define RCCK0_TXFILTER1 0xa20
+#define RCCK0_TXFILTER2 0xa24
+#define RCCK0_DEBUGPORT 0xa28
+#define RCCK0_FALSEALARMREPORT 0xa2c
+#define RCCK0_TRSSIREPORT 0xa50
+#define RCCK0_RXREPORT 0xa54
+#define RCCK0_FACOUNTERLOWER 0xa5c
+#define RCCK0_FACOUNTERUPPER 0xa58
+
+#define ROFDM0_LSTF 0xc00
+
+#define ROFDM0_TRXPATHENABLE 0xc04
+#define ROFDM0_TRMUXPAR 0xc08
+#define ROFDM0_TRSWISOLATION 0xc0c
+
+#define ROFDM0_XARXAFE 0xc10
+#define ROFDM0_XARXIQIMBALANCE 0xc14
+#define ROFDM0_XBRXAFE 0xc18
+#define ROFDM0_XBRXIQIMBALANCE 0xc1c
+#define ROFDM0_XCRXAFE 0xc20
+#define ROFDM0_XCRXIQIMBALANCE 0xc24
+#define ROFDM0_XDRXAFE 0xc28
+#define ROFDM0_XDRXIQIMBALANCE 0xc2c
+
+#define ROFDM0_RXDETECTOR1 0xc30
+#define ROFDM0_RXDETECTOR2 0xc34
+#define ROFDM0_RXDETECTOR3 0xc38
+#define ROFDM0_RXDETECTOR4 0xc3c
+
+#define ROFDM0_RXDSP 0xc40
+#define ROFDM0_CFO_AND_DAGC 0xc44
+#define ROFDM0_CCADROP_THRESHOLD 0xc48
+#define ROFDM0_ECCA_THRESHOLD 0xc4c
+
+#define ROFDM0_XAAGCCORE1 0xc50
+#define ROFDM0_XAAGCCORE2 0xc54
+#define ROFDM0_XBAGCCORE1 0xc58
+#define ROFDM0_XBAGCCORE2 0xc5c
+#define ROFDM0_XCAGCCORE1 0xc60
+#define ROFDM0_XCAGCCORE2 0xc64
+#define ROFDM0_XDAGCCORE1 0xc68
+#define ROFDM0_XDAGCCORE2 0xc6c
+
+#define ROFDM0_AGCPARAMETER1 0xc70
+#define ROFDM0_AGCPARAMETER2 0xc74
+#define ROFDM0_AGCRSSITABLE 0xc78
+#define ROFDM0_HTSTFAGC 0xc7c
+
+#define ROFDM0_XATXIQIMBALANCE 0xc80
+#define ROFDM0_XATXAFE 0xc84
+#define ROFDM0_XBTXIQIMBALANCE 0xc88
+#define ROFDM0_XBTXAFE 0xc8c
+#define ROFDM0_XCTXIQIMBALANCE 0xc90
+#define ROFDM0_XCTXAFE 0xc94
+#define ROFDM0_XDTXIQIMBALANCE 0xc98
+#define ROFDM0_XDTXAFE 0xc9c
+
+#define ROFDM0_RXHP_PARAMETER 0xce0
+#define ROFDM0_TXPSEUDO_NOISE_WGT 0xce4
+#define ROFDM0_FRAME_SYNC 0xcf0
+#define ROFDM0_DFSREPORT 0xcf4
+#define ROFDM0_TXCOEFF1 0xca4
+#define ROFDM0_TXCOEFF2 0xca8
+#define ROFDM0_TXCOEFF3 0xcac
+#define ROFDM0_TXCOEFF4 0xcb0
+#define ROFDM0_TXCOEFF5 0xcb4
+#define ROFDM0_TXCOEFF6 0xcb8
+
+
+#define ROFDM1_LSTF 0xd00
+#define ROFDM1_TRXPATHENABLE 0xd04
+
+#define ROFDM1_CFO 0xd08
+#define ROFDM1_CSI1 0xd10
+#define ROFDM1_SBD 0xd14
+#define ROFDM1_CSI2 0xd18
+#define ROFDM1_CFOTRACKING 0xd2c
+#define ROFDM1_TRXMESAURE1 0xd34
+#define ROFDM1_INTF_DET 0xd3c
+#define ROFDM1_PSEUDO_NOISESTATEAB 0xd50
+#define ROFDM1_PSEUDO_NOISESTATECD 0xd54
+#define ROFDM1_RX_PSEUDO_NOISE_WGT 0xd58
+
+#define ROFDM_PHYCOUNTER1 0xda0
+#define ROFDM_PHYCOUNTER2 0xda4
+#define ROFDM_PHYCOUNTER3 0xda8
+
+#define ROFDM_SHORT_CFOAB 0xdac
+#define ROFDM_SHORT_CFOCD 0xdb0
+#define ROFDM_LONG_CFOAB 0xdb4
+#define ROFDM_LONG_CFOCD 0xdb8
+#define ROFDM_TAIL_CFOAB 0xdbc
+#define ROFDM_TAIL_CFOCD 0xdc0
+#define ROFDM_PW_MEASURE1 0xdc4
+#define ROFDM_PW_MEASURE2 0xdc8
+#define ROFDM_BW_REPORT 0xdcc
+#define ROFDM_AGC_REPORT 0xdd0
+#define ROFDM_RXSNR 0xdd4
+#define ROFDM_RXEVMCSI 0xdd8
+#define ROFDM_SIG_REPORT 0xddc
+
+
+#define RTXAGC_RATE18_06 0xe00
+#define RTXAGC_RATE54_24 0xe04
+#define RTXAGC_CCK_MCS32 0xe08
+#define RTXAGC_MCS03_MCS00 0xe10
+#define RTXAGC_MCS07_MCS04 0xe14
+#define RTXAGC_MCS11_MCS08 0xe18
+#define RTXAGC_MCS15_MCS12 0xe1c
+
+
+#define RF_AC 0x00
+#define RF_IQADJ_G1 0x01
+#define RF_IQADJ_G2 0x02
+#define RF_POW_TRSW 0x05
+#define RF_GAIN_RX 0x06
+#define RF_GAIN_TX 0x07
+#define RF_TXM_IDAC 0x08
+#define RF_BS_IQGEN 0x0F
+
+#define RF_MODE1 0x10
+#define RF_MODE2 0x11
+#define RF_RX_AGC_HP 0x12
+#define RF_TX_AGC 0x13
+#define RF_BIAS 0x14
+#define RF_IPA 0x15
+#define RF_POW_ABILITY 0x17
+#define RF_MODE_AG 0x18
+#define RF_CHANNEL 0x18
+#define RF_CHNLBW 0x18
+#define RF_TOP 0x19
+#define RF_RX_G1 0x1A
+#define RF_RX_G2 0x1B
+#define RF_RX_BB2 0x1C
+#define RF_RX_BB1 0x1D
+#define RF_RCK1 0x1E
+#define RF_RCK2 0x1F
+
+#define RF_TX_G1 0x20
+#define RF_TX_G2 0x21
+#define RF_TX_G3 0x22
+#define RF_TX_BB1 0x23
+#define RF_T_METER 0x24
+#define RF_SYN_G1 0x25
+#define RF_SYN_G2 0x26
+#define RF_SYN_G3 0x27
+#define RF_SYN_G4 0x28
+#define RF_SYN_G5 0x29
+#define RF_SYN_G6 0x2A
+#define RF_SYN_G7 0x2B
+#define RF_SYN_G8 0x2C
+
+#define RF_RCK_OS 0x30
+#define RF_TXPA_G1 0x31
+#define RF_TXPA_G2 0x32
+#define RF_TXPA_G3 0x33
+
+#define BRFMOD 0x1
+#define BCCKEN 0x1000000
+#define BOFDMEN 0x2000000
+
+#define BXBTXAGC 0xf00
+#define BXCTXAGC 0xf000
+#define BXDTXAGC 0xf0000
+
+#define B3WIRE_DATALENGTH 0x800
+#define B3WIRE_ADDRESSLENGTH 0x400
+
+#define BRFSI_RFENV 0x10
+
+#define BLSSI_READADDRESS 0x7f800000
+#define BLSSI_READEDGE 0x80000000
+#define BLSSI_READBACK_DATA 0xfffff
+
+#define BADCLKPHASE 0x4000000
+
+#define BCCK_SIDEBAND 0x10
+
+#define BTX_AGCRATECCK 0x7f00
+
+#define MASKBYTE0 0xff
+#define MASKBYTE1 0xff00
+#define MASKBYTE2 0xff0000
+#define MASKBYTE3 0xff000000
+#define MASKHWORD 0xffff0000
+#define MASKLWORD 0x0000ffff
+#define MASKDWORD 0xffffffff
+
+#define MAKS12BITS 0xfffff
+#define MASK20BITS 0xfffff
+#define RFREG_OFFSET_MASK 0xfffff
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c
new file mode 100644
index 00000000000..1d3a4833039
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c
@@ -0,0 +1,546 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "rf.h"
+#include "dm.h"
+
+
+static void _rtl92s_get_powerbase(struct ieee80211_hw *hw, u8 *p_pwrlevel,
+ u8 chnl, u32 *ofdmbase, u32 *mcsbase,
+ u8 *p_final_pwridx)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u32 pwrbase0, pwrbase1;
+ u8 legacy_pwrdiff = 0, ht20_pwrdiff = 0;
+ u8 i, pwrlevel[4];
+
+ for (i = 0; i < 2; i++)
+ pwrlevel[i] = p_pwrlevel[i];
+
+ /* We only care about the path A for legacy. */
+ if (rtlefuse->eeprom_version < 2) {
+ pwrbase0 = pwrlevel[0] + (rtlefuse->legacy_httxpowerdiff & 0xf);
+ } else if (rtlefuse->eeprom_version >= 2) {
+ legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff
+ [RF90_PATH_A][chnl - 1];
+
+ /* For legacy OFDM, tx pwr always > HT OFDM pwr.
+ * We do not care Path B
+ * legacy OFDM pwr diff. NO BB register
+ * to notify HW. */
+ pwrbase0 = pwrlevel[0] + legacy_pwrdiff;
+ }
+
+ pwrbase0 = (pwrbase0 << 24) | (pwrbase0 << 16) | (pwrbase0 << 8) |
+ pwrbase0;
+ *ofdmbase = pwrbase0;
+
+ /* MCS rates */
+ if (rtlefuse->eeprom_version >= 2) {
+ /* Check HT20 to HT40 diff */
+ if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
+ for (i = 0; i < 2; i++) {
+ /* rf-A, rf-B */
+ /* HT 20<->40 pwr diff */
+ ht20_pwrdiff = rtlefuse->txpwr_ht20diff
+ [i][chnl - 1];
+
+ if (ht20_pwrdiff < 8) /* 0~+7 */
+ pwrlevel[i] += ht20_pwrdiff;
+ else /* index8-15=-8~-1 */
+ pwrlevel[i] -= (16 - ht20_pwrdiff);
+ }
+ }
+ }
+
+ /* use index of rf-A */
+ pwrbase1 = pwrlevel[0];
+ pwrbase1 = (pwrbase1 << 24) | (pwrbase1 << 16) | (pwrbase1 << 8) |
+ pwrbase1;
+ *mcsbase = pwrbase1;
+
+ /* The following is for Antenna
+ * diff from Ant-B to Ant-A */
+ p_final_pwridx[0] = pwrlevel[0];
+ p_final_pwridx[1] = pwrlevel[1];
+
+ switch (rtlefuse->eeprom_regulatory) {
+ case 3:
+ /* The following is for calculation
+ * of the power diff for Ant-B to Ant-A. */
+ if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+ p_final_pwridx[0] += rtlefuse->pwrgroup_ht40
+ [RF90_PATH_A][
+ chnl - 1];
+ p_final_pwridx[1] += rtlefuse->pwrgroup_ht40
+ [RF90_PATH_B][
+ chnl - 1];
+ } else {
+ p_final_pwridx[0] += rtlefuse->pwrgroup_ht20
+ [RF90_PATH_A][
+ chnl - 1];
+ p_final_pwridx[1] += rtlefuse->pwrgroup_ht20
+ [RF90_PATH_B][
+ chnl - 1];
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("40MHz finalpwr_idx "
+ "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0],
+ p_final_pwridx[1]));
+ } else {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("20MHz finalpwr_idx "
+ "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0],
+ p_final_pwridx[1]));
+ }
+}
+
+static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw,
+ u8 *p_final_pwridx)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ char ant_pwr_diff = 0;
+ u32 u4reg_val = 0;
+
+ if (rtlphy->rf_type == RF_2T2R) {
+ ant_pwr_diff = p_final_pwridx[1] - p_final_pwridx[0];
+
+ /* range is from 7~-8,
+ * index = 0x0~0xf */
+ if (ant_pwr_diff > 7)
+ ant_pwr_diff = 7;
+ if (ant_pwr_diff < -8)
+ ant_pwr_diff = -8;
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("Antenna Diff from RF-B "
+ "to RF-A = %d (0x%x)\n", ant_pwr_diff,
+ ant_pwr_diff & 0xf));
+
+ ant_pwr_diff &= 0xf;
+ }
+
+ /* Antenna TX power difference */
+ rtlefuse->antenna_txpwdiff[2] = 0;/* RF-D, don't care */
+ rtlefuse->antenna_txpwdiff[1] = 0;/* RF-C, don't care */
+ rtlefuse->antenna_txpwdiff[0] = (u8)(ant_pwr_diff); /* RF-B */
+
+ u4reg_val = rtlefuse->antenna_txpwdiff[2] << 8 |
+ rtlefuse->antenna_txpwdiff[1] << 4 |
+ rtlefuse->antenna_txpwdiff[0];
+
+ rtl_set_bbreg(hw, RFPGA0_TXGAINSTAGE, (BXBTXAGC | BXCTXAGC | BXDTXAGC),
+ u4reg_val);
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("Write BCD-Diff(0x%x) = 0x%x\n",
+ RFPGA0_TXGAINSTAGE, u4reg_val));
+}
+
+static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
+ u8 chnl, u8 index,
+ u32 pwrbase0,
+ u32 pwrbase1,
+ u32 *p_outwrite_val)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 i, chnlgroup, pwrdiff_limit[4];
+ u32 writeval, customer_limit;
+
+ /* Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate */
+ switch (rtlefuse->eeprom_regulatory) {
+ case 0:
+ /* Realtek better performance increase power diff
+ * defined by Realtek for large power */
+ chnlgroup = 0;
+
+ writeval = rtlphy->mcs_txpwrlevel_origoffset
+ [chnlgroup][index] +
+ ((index < 2) ? pwrbase0 : pwrbase1);
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("RTK better performance, "
+ "writeval = 0x%x\n", writeval));
+ break;
+ case 1:
+ /* Realtek regulatory increase power diff defined
+ * by Realtek for regulatory */
+ if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+ writeval = ((index < 2) ? pwrbase0 : pwrbase1);
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("Realtek regulatory, "
+ "40MHz, writeval = 0x%x\n", writeval));
+ } else {
+ if (rtlphy->pwrgroup_cnt == 1)
+ chnlgroup = 0;
+
+ if (rtlphy->pwrgroup_cnt >= 3) {
+ if (chnl <= 3)
+ chnlgroup = 0;
+ else if (chnl >= 4 && chnl <= 8)
+ chnlgroup = 1;
+ else if (chnl > 8)
+ chnlgroup = 2;
+ if (rtlphy->pwrgroup_cnt == 4)
+ chnlgroup++;
+ }
+
+ writeval = rtlphy->mcs_txpwrlevel_origoffset
+ [chnlgroup][index]
+ + ((index < 2) ?
+ pwrbase0 : pwrbase1);
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("Realtek regulatory, "
+ "20MHz, writeval = 0x%x\n", writeval));
+ }
+ break;
+ case 2:
+ /* Better regulatory don't increase any power diff */
+ writeval = ((index < 2) ? pwrbase0 : pwrbase1);
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("Better regulatory, "
+ "writeval = 0x%x\n", writeval));
+ break;
+ case 3:
+ /* Customer defined power diff. increase power diff
+ defined by customer. */
+ chnlgroup = 0;
+
+ if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("customer's limit, 40MHz = 0x%x\n",
+ rtlefuse->pwrgroup_ht40
+ [RF90_PATH_A][chnl - 1]));
+ } else {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("customer's limit, 20MHz = 0x%x\n",
+ rtlefuse->pwrgroup_ht20
+ [RF90_PATH_A][chnl - 1]));
+ }
+
+ for (i = 0; i < 4; i++) {
+ pwrdiff_limit[i] =
+ (u8)((rtlphy->mcs_txpwrlevel_origoffset
+ [chnlgroup][index] & (0x7f << (i * 8)))
+ >> (i * 8));
+
+ if (rtlphy->current_chan_bw ==
+ HT_CHANNEL_WIDTH_20_40) {
+ if (pwrdiff_limit[i] >
+ rtlefuse->pwrgroup_ht40
+ [RF90_PATH_A][chnl - 1]) {
+ pwrdiff_limit[i] =
+ rtlefuse->pwrgroup_ht20
+ [RF90_PATH_A][chnl - 1];
+ }
+ } else {
+ if (pwrdiff_limit[i] >
+ rtlefuse->pwrgroup_ht20
+ [RF90_PATH_A][chnl - 1]) {
+ pwrdiff_limit[i] =
+ rtlefuse->pwrgroup_ht20
+ [RF90_PATH_A][chnl - 1];
+ }
+ }
+ }
+
+ customer_limit = (pwrdiff_limit[3] << 24) |
+ (pwrdiff_limit[2] << 16) |
+ (pwrdiff_limit[1] << 8) |
+ (pwrdiff_limit[0]);
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("Customer's limit = 0x%x\n",
+ customer_limit));
+
+ writeval = customer_limit + ((index < 2) ?
+ pwrbase0 : pwrbase1);
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("Customer, writeval = "
+ "0x%x\n", writeval));
+ break;
+ default:
+ chnlgroup = 0;
+ writeval = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index] +
+ ((index < 2) ? pwrbase0 : pwrbase1);
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("RTK better performance, "
+ "writeval = 0x%x\n", writeval));
+ break;
+ }
+
+ if (rtlpriv->dm.dynamic_txhighpower_lvl == TX_HIGH_PWR_LEVEL_LEVEL1)
+ writeval = 0x10101010;
+ else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
+ TX_HIGH_PWR_LEVEL_LEVEL2)
+ writeval = 0x0;
+
+ *p_outwrite_val = writeval;
+
+}
+
+static void _rtl92s_write_ofdm_powerreg(struct ieee80211_hw *hw,
+ u8 index, u32 val)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u16 regoffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
+ u8 i, rfa_pwr[4];
+ u8 rfa_lower_bound = 0, rfa_upper_bound = 0, rf_pwr_diff = 0;
+ u32 writeval = val;
+
+ /* If path A and Path B coexist, we must limit Path A tx power.
+ * Protect Path B pwr over or under flow. We need to calculate
+ * upper and lower bound of path A tx power. */
+ if (rtlphy->rf_type == RF_2T2R) {
+ rf_pwr_diff = rtlefuse->antenna_txpwdiff[0];
+
+ /* Diff=-8~-1 */
+ if (rf_pwr_diff >= 8) {
+ /* Prevent underflow!! */
+ rfa_lower_bound = 0x10 - rf_pwr_diff;
+ /* if (rf_pwr_diff >= 0) Diff = 0-7 */
+ } else {
+ rfa_upper_bound = RF6052_MAX_TX_PWR - rf_pwr_diff;
+ }
+ }
+
+ for (i = 0; i < 4; i++) {
+ rfa_pwr[i] = (u8)((writeval & (0x7f << (i * 8))) >> (i * 8));
+ if (rfa_pwr[i] > RF6052_MAX_TX_PWR)
+ rfa_pwr[i] = RF6052_MAX_TX_PWR;
+
+ /* If path A and Path B coexist, we must limit Path A tx power.
+ * Protect Path B pwr over or under flow. We need to calculate
+ * upper and lower bound of path A tx power. */
+ if (rtlphy->rf_type == RF_2T2R) {
+ /* Diff=-8~-1 */
+ if (rf_pwr_diff >= 8) {
+ /* Prevent underflow!! */
+ if (rfa_pwr[i] < rfa_lower_bound)
+ rfa_pwr[i] = rfa_lower_bound;
+ /* Diff = 0-7 */
+ } else if (rf_pwr_diff >= 1) {
+ /* Prevent overflow */
+ if (rfa_pwr[i] > rfa_upper_bound)
+ rfa_pwr[i] = rfa_upper_bound;
+ }
+ }
+
+ }
+
+ writeval = (rfa_pwr[3] << 24) | (rfa_pwr[2] << 16) | (rfa_pwr[1] << 8) |
+ rfa_pwr[0];
+
+ rtl_set_bbreg(hw, regoffset[index], 0x7f7f7f7f, writeval);
+}
+
+void rtl92s_phy_rf6052_set_ofdmtxpower(struct ieee80211_hw *hw,
+ u8 *p_pwrlevel, u8 chnl)
+{
+ u32 writeval, pwrbase0, pwrbase1;
+ u8 index = 0;
+ u8 finalpwr_idx[4];
+
+ _rtl92s_get_powerbase(hw, p_pwrlevel, chnl, &pwrbase0, &pwrbase1,
+ &finalpwr_idx[0]);
+ _rtl92s_set_antennadiff(hw, &finalpwr_idx[0]);
+
+ for (index = 0; index < 6; index++) {
+ _rtl92s_get_txpower_writeval_byregulatory(hw, chnl, index,
+ pwrbase0, pwrbase1, &writeval);
+
+ _rtl92s_write_ofdm_powerreg(hw, index, writeval);
+ }
+}
+
+void rtl92s_phy_rf6052_set_ccktxpower(struct ieee80211_hw *hw, u8 pwrlevel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u32 txagc = 0;
+ bool dont_inc_cck_or_turboscanoff = false;
+
+ if (((rtlefuse->eeprom_version >= 2) &&
+ (rtlefuse->txpwr_safetyflag == 1)) ||
+ ((rtlefuse->eeprom_version >= 2) &&
+ (rtlefuse->eeprom_regulatory != 0)))
+ dont_inc_cck_or_turboscanoff = true;
+
+ if (mac->act_scanning == true) {
+ txagc = 0x3f;
+ if (dont_inc_cck_or_turboscanoff)
+ txagc = pwrlevel;
+ } else {
+ txagc = pwrlevel;
+
+ if (rtlpriv->dm.dynamic_txhighpower_lvl ==
+ TX_HIGH_PWR_LEVEL_LEVEL1)
+ txagc = 0x10;
+ else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
+ TX_HIGH_PWR_LEVEL_LEVEL2)
+ txagc = 0x0;
+ }
+
+ if (txagc > RF6052_MAX_TX_PWR)
+ txagc = RF6052_MAX_TX_PWR;
+
+ rtl_set_bbreg(hw, RTXAGC_CCK_MCS32, BTX_AGCRATECCK, txagc);
+
+}
+
+bool rtl92s_phy_rf6052_config(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ u32 u4reg_val = 0;
+ u8 rfpath;
+ bool rtstatus = true;
+ struct bb_reg_def *pphyreg;
+
+ /* Initialize RF */
+ for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
+
+ pphyreg = &rtlphy->phyreg_def[rfpath];
+
+ /* Store original RFENV control type */
+ switch (rfpath) {
+ case RF90_PATH_A:
+ case RF90_PATH_C:
+ u4reg_val = rtl92s_phy_query_bb_reg(hw,
+ pphyreg->rfintfs,
+ BRFSI_RFENV);
+ break;
+ case RF90_PATH_B:
+ case RF90_PATH_D:
+ u4reg_val = rtl92s_phy_query_bb_reg(hw,
+ pphyreg->rfintfs,
+ BRFSI_RFENV << 16);
+ break;
+ }
+
+ /* Set RF_ENV enable */
+ rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfe,
+ BRFSI_RFENV << 16, 0x1);
+
+ /* Set RF_ENV output high */
+ rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
+
+ /* Set bit number of Address and Data for RF register */
+ rtl92s_phy_set_bb_reg(hw, pphyreg->rfhssi_para2,
+ B3WIRE_ADDRESSLENGTH, 0x0);
+ rtl92s_phy_set_bb_reg(hw, pphyreg->rfhssi_para2,
+ B3WIRE_DATALENGTH, 0x0);
+
+ /* Initialize RF fom connfiguration file */
+ switch (rfpath) {
+ case RF90_PATH_A:
+ rtstatus = rtl92s_phy_config_rf(hw,
+ (enum radio_path)rfpath);
+ break;
+ case RF90_PATH_B:
+ rtstatus = rtl92s_phy_config_rf(hw,
+ (enum radio_path)rfpath);
+ break;
+ case RF90_PATH_C:
+ break;
+ case RF90_PATH_D:
+ break;
+ }
+
+ /* Restore RFENV control type */
+ switch (rfpath) {
+ case RF90_PATH_A:
+ case RF90_PATH_C:
+ rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfs, BRFSI_RFENV,
+ u4reg_val);
+ break;
+ case RF90_PATH_B:
+ case RF90_PATH_D:
+ rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfs,
+ BRFSI_RFENV << 16,
+ u4reg_val);
+ break;
+ }
+
+ if (rtstatus != true) {
+ printk(KERN_ERR "Radio[%d] Fail!!", rfpath);
+ goto fail;
+ }
+
+ }
+
+ return rtstatus;
+
+fail:
+ return rtstatus;
+}
+
+void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ switch (bandwidth) {
+ case HT_CHANNEL_WIDTH_20:
+ rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
+ 0xfffff3ff) | 0x0400);
+ rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
+ rtlphy->rfreg_chnlval[0]);
+ break;
+ case HT_CHANNEL_WIDTH_20_40:
+ rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
+ 0xfffff3ff));
+ rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
+ rtlphy->rfreg_chnlval[0]);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("unknown bandwidth: %#X\n",
+ bandwidth));
+ break;
+ }
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.h b/drivers/net/wireless/rtlwifi/rtl8192se/rf.h
new file mode 100644
index 00000000000..3843baa1a87
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.h
@@ -0,0 +1,43 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __INC_RTL92S_RF_H
+#define __INC_RTL92S_RF_H
+
+#define RF6052_MAX_TX_PWR 0x3F
+
+void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
+ u8 bandwidth);
+bool rtl92s_phy_rf6052_config(struct ieee80211_hw *hw) ;
+void rtl92s_phy_rf6052_set_ccktxpower(struct ieee80211_hw *hw,
+ u8 powerlevel);
+void rtl92s_phy_rf6052_set_ofdmtxpower(struct ieee80211_hw *hw,
+ u8 *p_pwrlevel, u8 chnl);
+
+#endif
+
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
new file mode 100644
index 00000000000..1c6cb1d7d66
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
@@ -0,0 +1,423 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include <linux/vmalloc.h>
+
+#include "../wifi.h"
+#include "../core.h"
+#include "../pci.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "fw.h"
+#include "hw.h"
+#include "sw.h"
+#include "trx.h"
+#include "led.h"
+
+static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ /*close ASPM for AMD defaultly */
+ rtlpci->const_amdpci_aspm = 0;
+
+ /*
+ * ASPM PS mode.
+ * 0 - Disable ASPM,
+ * 1 - Enable ASPM without Clock Req,
+ * 2 - Enable ASPM with Clock Req,
+ * 3 - Alwyas Enable ASPM with Clock Req,
+ * 4 - Always Enable ASPM without Clock Req.
+ * set defult to RTL8192CE:3 RTL8192E:2
+ * */
+ rtlpci->const_pci_aspm = 2;
+
+ /*Setting for PCI-E device */
+ rtlpci->const_devicepci_aspm_setting = 0x03;
+
+ /*Setting for PCI-E bridge */
+ rtlpci->const_hostpci_aspm_setting = 0x02;
+
+ /*
+ * In Hw/Sw Radio Off situation.
+ * 0 - Default,
+ * 1 - From ASPM setting without low Mac Pwr,
+ * 2 - From ASPM setting with low Mac Pwr,
+ * 3 - Bus D3
+ * set default to RTL8192CE:0 RTL8192SE:2
+ */
+ rtlpci->const_hwsw_rfoff_d3 = 2;
+
+ /*
+ * This setting works for those device with
+ * backdoor ASPM setting such as EPHY setting.
+ * 0 - Not support ASPM,
+ * 1 - Support ASPM,
+ * 2 - According to chipset.
+ */
+ rtlpci->const_support_pciaspm = 2;
+}
+
+static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ const struct firmware *firmware;
+ struct rt_firmware *pfirmware = NULL;
+ int err = 0;
+ u16 earlyrxthreshold = 7;
+
+ rtlpriv->dm.dm_initialgain_enable = 1;
+ rtlpriv->dm.dm_flag = 0;
+ rtlpriv->dm.disable_framebursting = 0;
+ rtlpriv->dm.thermalvalue = 0;
+ rtlpriv->dm.useramask = true;
+
+ /* compatible 5G band 91se just 2.4G band & smsp */
+ rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
+ rtlpriv->rtlhal.bandset = BAND_ON_2_4G;
+ rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
+
+ rtlpci->transmit_config = 0;
+
+ rtlpci->receive_config =
+ RCR_APPFCS |
+ RCR_APWRMGT |
+ /*RCR_ADD3 |*/
+ RCR_AMF |
+ RCR_ADF |
+ RCR_APP_MIC |
+ RCR_APP_ICV |
+ RCR_AICV |
+ /* Accept ICV error, CRC32 Error */
+ RCR_ACRC32 |
+ RCR_AB |
+ /* Accept Broadcast, Multicast */
+ RCR_AM |
+ /* Accept Physical match */
+ RCR_APM |
+ /* Accept Destination Address packets */
+ /*RCR_AAP |*/
+ RCR_APP_PHYST_STAFF |
+ /* Accept PHY status */
+ RCR_APP_PHYST_RXFF |
+ (earlyrxthreshold << RCR_FIFO_OFFSET);
+
+ rtlpci->irq_mask[0] = (u32)
+ (IMR_ROK |
+ IMR_VODOK |
+ IMR_VIDOK |
+ IMR_BEDOK |
+ IMR_BKDOK |
+ IMR_HCCADOK |
+ IMR_MGNTDOK |
+ IMR_COMDOK |
+ IMR_HIGHDOK |
+ IMR_BDOK |
+ IMR_RXCMDOK |
+ /*IMR_TIMEOUT0 |*/
+ IMR_RDU |
+ IMR_RXFOVW |
+ IMR_BCNINT
+ /*| IMR_TXFOVW*/
+ /*| IMR_TBDOK |
+ IMR_TBDER*/);
+
+ rtlpci->irq_mask[1] = (u32) 0;
+
+ rtlpci->shortretry_limit = 0x30;
+ rtlpci->longretry_limit = 0x30;
+
+ rtlpci->first_init = true;
+
+ /* for LPS & IPS */
+ rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
+ rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
+ rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
+ rtlpriv->psc.reg_fwctrl_lps = 3;
+ rtlpriv->psc.reg_max_lps_awakeintvl = 5;
+ /* for ASPM, you can close aspm through
+ * set const_support_pciaspm = 0 */
+ rtl92s_init_aspm_vars(hw);
+
+ if (rtlpriv->psc.reg_fwctrl_lps == 1)
+ rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
+ else if (rtlpriv->psc.reg_fwctrl_lps == 2)
+ rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
+ else if (rtlpriv->psc.reg_fwctrl_lps == 3)
+ rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
+
+ /* for firmware buf */
+ rtlpriv->rtlhal.pfirmware = vzalloc(sizeof(struct rt_firmware));
+ if (!rtlpriv->rtlhal.pfirmware) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Can't alloc buffer for fw.\n"));
+ return 1;
+ }
+
+ printk(KERN_INFO "rtl8192se: Driver for Realtek RTL8192SE/RTL8191SE\n"
+ " Loading firmware %s\n", rtlpriv->cfg->fw_name);
+ /* request fw */
+ err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
+ rtlpriv->io.dev);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Failed to request firmware!\n"));
+ return 1;
+ }
+ if (firmware->size > sizeof(struct rt_firmware)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Firmware is too big!\n"));
+ release_firmware(firmware);
+ return 1;
+ }
+
+ pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
+ memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
+ pfirmware->sz_fw_tmpbufferlen = firmware->size;
+ release_firmware(firmware);
+
+ return err;
+}
+
+static void rtl92s_deinit_sw_vars(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (rtlpriv->rtlhal.pfirmware) {
+ vfree(rtlpriv->rtlhal.pfirmware);
+ rtlpriv->rtlhal.pfirmware = NULL;
+ }
+}
+
+static struct rtl_hal_ops rtl8192se_hal_ops = {
+ .init_sw_vars = rtl92s_init_sw_vars,
+ .deinit_sw_vars = rtl92s_deinit_sw_vars,
+ .read_eeprom_info = rtl92se_read_eeprom_info,
+ .interrupt_recognized = rtl92se_interrupt_recognized,
+ .hw_init = rtl92se_hw_init,
+ .hw_disable = rtl92se_card_disable,
+ .hw_suspend = rtl92se_suspend,
+ .hw_resume = rtl92se_resume,
+ .enable_interrupt = rtl92se_enable_interrupt,
+ .disable_interrupt = rtl92se_disable_interrupt,
+ .set_network_type = rtl92se_set_network_type,
+ .set_chk_bssid = rtl92se_set_check_bssid,
+ .set_qos = rtl92se_set_qos,
+ .set_bcn_reg = rtl92se_set_beacon_related_registers,
+ .set_bcn_intv = rtl92se_set_beacon_interval,
+ .update_interrupt_mask = rtl92se_update_interrupt_mask,
+ .get_hw_reg = rtl92se_get_hw_reg,
+ .set_hw_reg = rtl92se_set_hw_reg,
+ .update_rate_tbl = rtl92se_update_hal_rate_tbl,
+ .fill_tx_desc = rtl92se_tx_fill_desc,
+ .fill_tx_cmddesc = rtl92se_tx_fill_cmddesc,
+ .query_rx_desc = rtl92se_rx_query_desc,
+ .set_channel_access = rtl92se_update_channel_access_setting,
+ .radio_onoff_checking = rtl92se_gpio_radio_on_off_checking,
+ .set_bw_mode = rtl92s_phy_set_bw_mode,
+ .switch_channel = rtl92s_phy_sw_chnl,
+ .dm_watchdog = rtl92s_dm_watchdog,
+ .scan_operation_backup = rtl92s_phy_scan_operation_backup,
+ .set_rf_power_state = rtl92s_phy_set_rf_power_state,
+ .led_control = rtl92se_led_control,
+ .set_desc = rtl92se_set_desc,
+ .get_desc = rtl92se_get_desc,
+ .tx_polling = rtl92se_tx_polling,
+ .enable_hw_sec = rtl92se_enable_hw_security_config,
+ .set_key = rtl92se_set_key,
+ .init_sw_leds = rtl92se_init_sw_leds,
+ .get_bbreg = rtl92s_phy_query_bb_reg,
+ .set_bbreg = rtl92s_phy_set_bb_reg,
+ .get_rfreg = rtl92s_phy_query_rf_reg,
+ .set_rfreg = rtl92s_phy_set_rf_reg,
+};
+
+static struct rtl_mod_params rtl92se_mod_params = {
+ .sw_crypto = false,
+ .inactiveps = true,
+ .swctrl_lps = true,
+ .fwctrl_lps = false,
+};
+
+/* Because memory R/W bursting will cause system hang/crash
+ * for 92se, so we don't read back after every write action */
+static struct rtl_hal_cfg rtl92se_hal_cfg = {
+ .bar_id = 1,
+ .write_readback = false,
+ .name = "rtl92s_pci",
+ .fw_name = "rtlwifi/rtl8192sefw.bin",
+ .ops = &rtl8192se_hal_ops,
+ .mod_params = &rtl92se_mod_params,
+
+ .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
+ .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
+ .maps[SYS_CLK] = SYS_CLKR,
+ .maps[MAC_RCR_AM] = RCR_AM,
+ .maps[MAC_RCR_AB] = RCR_AB,
+ .maps[MAC_RCR_ACRC32] = RCR_ACRC32,
+ .maps[MAC_RCR_ACF] = RCR_ACF,
+ .maps[MAC_RCR_AAP] = RCR_AAP,
+
+ .maps[EFUSE_TEST] = REG_EFUSE_TEST,
+ .maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
+ .maps[EFUSE_CLK] = REG_EFUSE_CLK,
+ .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
+ .maps[EFUSE_PWC_EV12V] = 0, /* nouse for 8192se */
+ .maps[EFUSE_FEN_ELDR] = 0, /* nouse for 8192se */
+ .maps[EFUSE_LOADER_CLK_EN] = 0,/* nouse for 8192se */
+ .maps[EFUSE_ANA8M] = EFUSE_ANA8M,
+ .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE_92S,
+ .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
+ .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
+
+ .maps[RWCAM] = REG_RWCAM,
+ .maps[WCAMI] = REG_WCAMI,
+ .maps[RCAMO] = REG_RCAMO,
+ .maps[CAMDBG] = REG_CAMDBG,
+ .maps[SECR] = REG_SECR,
+ .maps[SEC_CAM_NONE] = CAM_NONE,
+ .maps[SEC_CAM_WEP40] = CAM_WEP40,
+ .maps[SEC_CAM_TKIP] = CAM_TKIP,
+ .maps[SEC_CAM_AES] = CAM_AES,
+ .maps[SEC_CAM_WEP104] = CAM_WEP104,
+
+ .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
+ .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
+ .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
+ .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
+ .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
+ .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
+ .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,
+ .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
+ .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
+ .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
+ .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
+ .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
+ .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
+ .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
+ .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,
+ .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,
+
+ .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
+ .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
+ .maps[RTL_IMR_BcnInt] = IMR_BCNINT,
+ .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
+ .maps[RTL_IMR_RDU] = IMR_RDU,
+ .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
+ .maps[RTL_IMR_BDOK] = IMR_BDOK,
+ .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
+ .maps[RTL_IMR_TBDER] = IMR_TBDER,
+ .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
+ .maps[RTL_IMR_COMDOK] = IMR_COMDOK,
+ .maps[RTL_IMR_TBDOK] = IMR_TBDOK,
+ .maps[RTL_IMR_BKDOK] = IMR_BKDOK,
+ .maps[RTL_IMR_BEDOK] = IMR_BEDOK,
+ .maps[RTL_IMR_VIDOK] = IMR_VIDOK,
+ .maps[RTL_IMR_VODOK] = IMR_VODOK,
+ .maps[RTL_IMR_ROK] = IMR_ROK,
+ .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
+
+ .maps[RTL_RC_CCK_RATE1M] = DESC92S_RATE1M,
+ .maps[RTL_RC_CCK_RATE2M] = DESC92S_RATE2M,
+ .maps[RTL_RC_CCK_RATE5_5M] = DESC92S_RATE5_5M,
+ .maps[RTL_RC_CCK_RATE11M] = DESC92S_RATE11M,
+ .maps[RTL_RC_OFDM_RATE6M] = DESC92S_RATE6M,
+ .maps[RTL_RC_OFDM_RATE9M] = DESC92S_RATE9M,
+ .maps[RTL_RC_OFDM_RATE12M] = DESC92S_RATE12M,
+ .maps[RTL_RC_OFDM_RATE18M] = DESC92S_RATE18M,
+ .maps[RTL_RC_OFDM_RATE24M] = DESC92S_RATE24M,
+ .maps[RTL_RC_OFDM_RATE36M] = DESC92S_RATE36M,
+ .maps[RTL_RC_OFDM_RATE48M] = DESC92S_RATE48M,
+ .maps[RTL_RC_OFDM_RATE54M] = DESC92S_RATE54M,
+
+ .maps[RTL_RC_HT_RATEMCS7] = DESC92S_RATEMCS7,
+ .maps[RTL_RC_HT_RATEMCS15] = DESC92S_RATEMCS15,
+};
+
+static struct pci_device_id rtl92se_pci_ids[] __devinitdata = {
+ {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8192, rtl92se_hal_cfg)},
+ {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8171, rtl92se_hal_cfg)},
+ {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8172, rtl92se_hal_cfg)},
+ {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8173, rtl92se_hal_cfg)},
+ {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8174, rtl92se_hal_cfg)},
+ {},
+};
+
+MODULE_DEVICE_TABLE(pci, rtl92se_pci_ids);
+
+MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
+MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek 8192S/8191S 802.11n PCI wireless");
+MODULE_FIRMWARE("rtlwifi/rtl8192sefw.bin");
+
+module_param_named(swenc, rtl92se_mod_params.sw_crypto, bool, 0444);
+module_param_named(ips, rtl92se_mod_params.inactiveps, bool, 0444);
+module_param_named(swlps, rtl92se_mod_params.swctrl_lps, bool, 0444);
+module_param_named(fwlps, rtl92se_mod_params.fwctrl_lps, bool, 0444);
+MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n");
+MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n");
+MODULE_PARM_DESC(swlps, "using linked sw control power save (default 1 is "
+ "open)\n");
+
+
+static struct pci_driver rtl92se_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = rtl92se_pci_ids,
+ .probe = rtl_pci_probe,
+ .remove = rtl_pci_disconnect,
+
+#ifdef CONFIG_PM
+ .suspend = rtl_pci_suspend,
+ .resume = rtl_pci_resume,
+#endif
+
+};
+
+static int __init rtl92se_module_init(void)
+{
+ int ret = 0;
+
+ ret = pci_register_driver(&rtl92se_driver);
+ if (ret)
+ RT_ASSERT(false, (": No device found\n"));
+
+ return ret;
+}
+
+static void __exit rtl92se_module_exit(void)
+{
+ pci_unregister_driver(&rtl92se_driver);
+}
+
+module_init(rtl92se_module_init);
+module_exit(rtl92se_module_exit);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.h b/drivers/net/wireless/rtlwifi/rtl8192se/sw.h
index 96f323dc5dd..fc4eb285a0a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-led.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009-2010 Realtek Corporation.
*
* 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
@@ -19,15 +19,18 @@
* file called LICENSE.
*
* Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
*
*****************************************************************************/
+#ifndef __REALTEK_PCI92SE_SW_H__
+#define __REALTEK_PCI92SE_SW_H__
-#ifndef __iwl_agn_led_h__
-#define __iwl_agn_led_h__
+#define EFUSE_MAX_SECTION 16
-extern const struct iwl_led_ops iwlagn_led_ops;
-void iwlagn_led_enable(struct iwl_priv *priv);
+int rtl92se_init_sw(struct ieee80211_hw *hw);
+void rtl92se_deinit_sw(struct ieee80211_hw *hw);
+void rtl92se_init_var_map(struct ieee80211_hw *hw);
-#endif /* __iwl_agn_led_h__ */
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.c b/drivers/net/wireless/rtlwifi/rtl8192se/table.c
new file mode 100644
index 00000000000..154185b3969
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/table.c
@@ -0,0 +1,634 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ * Created on 2010/ 5/18, 1:41
+ *****************************************************************************/
+
+#include "table.h"
+
+u32 rtl8192sephy_reg_2t2rarray[PHY_REG_2T2RARRAYLENGTH] = {
+ 0x01c, 0x07000000,
+ 0x800, 0x00040000,
+ 0x804, 0x00008003,
+ 0x808, 0x0000fc00,
+ 0x80c, 0x0000000a,
+ 0x810, 0x10005088,
+ 0x814, 0x020c3d10,
+ 0x818, 0x00200185,
+ 0x81c, 0x00000000,
+ 0x820, 0x01000000,
+ 0x824, 0x00390004,
+ 0x828, 0x01000000,
+ 0x82c, 0x00390004,
+ 0x830, 0x00000004,
+ 0x834, 0x00690200,
+ 0x838, 0x00000004,
+ 0x83c, 0x00690200,
+ 0x840, 0x00010000,
+ 0x844, 0x00010000,
+ 0x848, 0x00000000,
+ 0x84c, 0x00000000,
+ 0x850, 0x00000000,
+ 0x854, 0x00000000,
+ 0x858, 0x48484848,
+ 0x85c, 0x65a965a9,
+ 0x860, 0x0f7f0130,
+ 0x864, 0x0f7f0130,
+ 0x868, 0x0f7f0130,
+ 0x86c, 0x0f7f0130,
+ 0x870, 0x03000700,
+ 0x874, 0x03000300,
+ 0x878, 0x00020002,
+ 0x87c, 0x004f0201,
+ 0x880, 0xa8300ac1,
+ 0x884, 0x00000058,
+ 0x888, 0x00000008,
+ 0x88c, 0x00000004,
+ 0x890, 0x00000000,
+ 0x894, 0xfffffffe,
+ 0x898, 0x40302010,
+ 0x89c, 0x00706050,
+ 0x8b0, 0x00000000,
+ 0x8e0, 0x00000000,
+ 0x8e4, 0x00000000,
+ 0xe00, 0x30333333,
+ 0xe04, 0x2a2d2e2f,
+ 0xe08, 0x00003232,
+ 0xe10, 0x30333333,
+ 0xe14, 0x2a2d2e2f,
+ 0xe18, 0x30333333,
+ 0xe1c, 0x2a2d2e2f,
+ 0xe30, 0x01007c00,
+ 0xe34, 0x01004800,
+ 0xe38, 0x1000dc1f,
+ 0xe3c, 0x10008c1f,
+ 0xe40, 0x021400a0,
+ 0xe44, 0x281600a0,
+ 0xe48, 0xf8000001,
+ 0xe4c, 0x00002910,
+ 0xe50, 0x01007c00,
+ 0xe54, 0x01004800,
+ 0xe58, 0x1000dc1f,
+ 0xe5c, 0x10008c1f,
+ 0xe60, 0x021400a0,
+ 0xe64, 0x281600a0,
+ 0xe6c, 0x00002910,
+ 0xe70, 0x31ed92fb,
+ 0xe74, 0x361536fb,
+ 0xe78, 0x361536fb,
+ 0xe7c, 0x361536fb,
+ 0xe80, 0x361536fb,
+ 0xe84, 0x000d92fb,
+ 0xe88, 0x000d92fb,
+ 0xe8c, 0x31ed92fb,
+ 0xed0, 0x31ed92fb,
+ 0xed4, 0x31ed92fb,
+ 0xed8, 0x000d92fb,
+ 0xedc, 0x000d92fb,
+ 0xee0, 0x000d92fb,
+ 0xee4, 0x015e5448,
+ 0xee8, 0x21555448,
+ 0x900, 0x00000000,
+ 0x904, 0x00000023,
+ 0x908, 0x00000000,
+ 0x90c, 0x01121313,
+ 0xa00, 0x00d047c8,
+ 0xa04, 0x80ff0008,
+ 0xa08, 0x8ccd8300,
+ 0xa0c, 0x2e62120f,
+ 0xa10, 0x9500bb78,
+ 0xa14, 0x11144028,
+ 0xa18, 0x00881117,
+ 0xa1c, 0x89140f00,
+ 0xa20, 0x1a1b0000,
+ 0xa24, 0x090e1317,
+ 0xa28, 0x00000204,
+ 0xa2c, 0x10d30000,
+ 0xc00, 0x40071d40,
+ 0xc04, 0x00a05633,
+ 0xc08, 0x000000e4,
+ 0xc0c, 0x6c6c6c6c,
+ 0xc10, 0x08800000,
+ 0xc14, 0x40000100,
+ 0xc18, 0x08000000,
+ 0xc1c, 0x40000100,
+ 0xc20, 0x08000000,
+ 0xc24, 0x40000100,
+ 0xc28, 0x08000000,
+ 0xc2c, 0x40000100,
+ 0xc30, 0x6de9ac44,
+ 0xc34, 0x469652cf,
+ 0xc38, 0x49795994,
+ 0xc3c, 0x0a979764,
+ 0xc40, 0x1f7c403f,
+ 0xc44, 0x000100b7,
+ 0xc48, 0xec020000,
+ 0xc4c, 0x007f037f,
+ 0xc50, 0x69543420,
+ 0xc54, 0x433c0094,
+ 0xc58, 0x69543420,
+ 0xc5c, 0x433c0094,
+ 0xc60, 0x69543420,
+ 0xc64, 0x433c0094,
+ 0xc68, 0x69543420,
+ 0xc6c, 0x433c0094,
+ 0xc70, 0x2c7f000d,
+ 0xc74, 0x0186155b,
+ 0xc78, 0x0000001f,
+ 0xc7c, 0x00b91612,
+ 0xc80, 0x40000100,
+ 0xc84, 0x20f60000,
+ 0xc88, 0x20000080,
+ 0xc8c, 0x20200000,
+ 0xc90, 0x40000100,
+ 0xc94, 0x00000000,
+ 0xc98, 0x40000100,
+ 0xc9c, 0x00000000,
+ 0xca0, 0x00492492,
+ 0xca4, 0x00000000,
+ 0xca8, 0x00000000,
+ 0xcac, 0x00000000,
+ 0xcb0, 0x00000000,
+ 0xcb4, 0x00000000,
+ 0xcb8, 0x00000000,
+ 0xcbc, 0x28000000,
+ 0xcc0, 0x00000000,
+ 0xcc4, 0x00000000,
+ 0xcc8, 0x00000000,
+ 0xccc, 0x00000000,
+ 0xcd0, 0x00000000,
+ 0xcd4, 0x00000000,
+ 0xcd8, 0x64b22427,
+ 0xcdc, 0x00766932,
+ 0xce0, 0x00222222,
+ 0xce4, 0x00000000,
+ 0xce8, 0x37644302,
+ 0xcec, 0x2f97d40c,
+ 0xd00, 0x00000750,
+ 0xd04, 0x00000403,
+ 0xd08, 0x0000907f,
+ 0xd0c, 0x00000001,
+ 0xd10, 0xa0633333,
+ 0xd14, 0x33333c63,
+ 0xd18, 0x6a8f5b6b,
+ 0xd1c, 0x00000000,
+ 0xd20, 0x00000000,
+ 0xd24, 0x00000000,
+ 0xd28, 0x00000000,
+ 0xd2c, 0xcc979975,
+ 0xd30, 0x00000000,
+ 0xd34, 0x00000000,
+ 0xd38, 0x00000000,
+ 0xd3c, 0x00027293,
+ 0xd40, 0x00000000,
+ 0xd44, 0x00000000,
+ 0xd48, 0x00000000,
+ 0xd50, 0x6437140a,
+ 0xd54, 0x024dbd02,
+ 0xd58, 0x00000000,
+ 0xd5c, 0x30032064,
+ 0xd60, 0x4653de68,
+ 0xd64, 0x00518a3c,
+ 0xd68, 0x00002101,
+ 0xf14, 0x00000003,
+ 0xf4c, 0x00000000,
+ 0xf00, 0x00000300,
+};
+
+u32 rtl8192sephy_changeto_1t1rarray[PHY_CHANGETO_1T1RARRAYLENGTH] = {
+ 0x844, 0xffffffff, 0x00010000,
+ 0x804, 0x0000000f, 0x00000001,
+ 0x824, 0x00f0000f, 0x00300004,
+ 0x82c, 0x00f0000f, 0x00100002,
+ 0x870, 0x04000000, 0x00000001,
+ 0x864, 0x00000400, 0x00000000,
+ 0x878, 0x000f000f, 0x00000002,
+ 0xe74, 0x0f000000, 0x00000002,
+ 0xe78, 0x0f000000, 0x00000002,
+ 0xe7c, 0x0f000000, 0x00000002,
+ 0xe80, 0x0f000000, 0x00000002,
+ 0x90c, 0x000000ff, 0x00000011,
+ 0xc04, 0x000000ff, 0x00000011,
+ 0xd04, 0x0000000f, 0x00000001,
+ 0x1f4, 0xffff0000, 0x00007777,
+ 0x234, 0xf8000000, 0x0000000a,
+};
+
+u32 rtl8192sephy_changeto_1t2rarray[PHY_CHANGETO_1T2RARRAYLENGTH] = {
+ 0x804, 0x0000000f, 0x00000003,
+ 0x824, 0x00f0000f, 0x00300004,
+ 0x82c, 0x00f0000f, 0x00300002,
+ 0x870, 0x04000000, 0x00000001,
+ 0x864, 0x00000400, 0x00000000,
+ 0x878, 0x000f000f, 0x00000002,
+ 0xe74, 0x0f000000, 0x00000002,
+ 0xe78, 0x0f000000, 0x00000002,
+ 0xe7c, 0x0f000000, 0x00000002,
+ 0xe80, 0x0f000000, 0x00000002,
+ 0x90c, 0x000000ff, 0x00000011,
+ 0xc04, 0x000000ff, 0x00000033,
+ 0xd04, 0x0000000f, 0x00000003,
+ 0x1f4, 0xffff0000, 0x00007777,
+ 0x234, 0xf8000000, 0x0000000a,
+};
+
+u32 rtl8192sephy_reg_array_pg[PHY_REG_ARRAY_PGLENGTH] = {
+ 0xe00, 0xffffffff, 0x06090909,
+ 0xe04, 0xffffffff, 0x00030406,
+ 0xe08, 0x0000ff00, 0x00000000,
+ 0xe10, 0xffffffff, 0x0a0c0d0e,
+ 0xe14, 0xffffffff, 0x04070809,
+ 0xe18, 0xffffffff, 0x0a0c0d0e,
+ 0xe1c, 0xffffffff, 0x04070809,
+ 0xe00, 0xffffffff, 0x04040404,
+ 0xe04, 0xffffffff, 0x00020204,
+ 0xe08, 0x0000ff00, 0x00000000,
+ 0xe10, 0xffffffff, 0x02040404,
+ 0xe14, 0xffffffff, 0x00000002,
+ 0xe18, 0xffffffff, 0x02040404,
+ 0xe1c, 0xffffffff, 0x00000002,
+ 0xe00, 0xffffffff, 0x04040404,
+ 0xe04, 0xffffffff, 0x00020204,
+ 0xe08, 0x0000ff00, 0x00000000,
+ 0xe10, 0xffffffff, 0x02040404,
+ 0xe14, 0xffffffff, 0x00000002,
+ 0xe18, 0xffffffff, 0x02040404,
+ 0xe1c, 0xffffffff, 0x00000002,
+ 0xe00, 0xffffffff, 0x02020202,
+ 0xe04, 0xffffffff, 0x00020202,
+ 0xe08, 0x0000ff00, 0x00000000,
+ 0xe10, 0xffffffff, 0x02020202,
+ 0xe14, 0xffffffff, 0x00000002,
+ 0xe18, 0xffffffff, 0x02020202,
+ 0xe1c, 0xffffffff, 0x00000002,
+};
+
+u32 rtl8192seradioa_1t_array[RADIOA_1T_ARRAYLENGTH] = {
+ 0x000, 0x00030159,
+ 0x001, 0x00030250,
+ 0x002, 0x00010000,
+ 0x010, 0x0008000f,
+ 0x011, 0x000231fc,
+ 0x010, 0x000c000f,
+ 0x011, 0x0003f9f8,
+ 0x010, 0x0002000f,
+ 0x011, 0x00020101,
+ 0x014, 0x0001093e,
+ 0x014, 0x0009093e,
+ 0x015, 0x0000f8f4,
+ 0x017, 0x000f6500,
+ 0x01a, 0x00013056,
+ 0x01b, 0x00060000,
+ 0x01c, 0x00000300,
+ 0x01e, 0x00031059,
+ 0x021, 0x00054000,
+ 0x022, 0x0000083c,
+ 0x023, 0x00001558,
+ 0x024, 0x00000060,
+ 0x025, 0x00022583,
+ 0x026, 0x0000f200,
+ 0x027, 0x000eacf1,
+ 0x028, 0x0009bd54,
+ 0x029, 0x00004582,
+ 0x02a, 0x00000001,
+ 0x02b, 0x00021334,
+ 0x02a, 0x00000000,
+ 0x02b, 0x0000000a,
+ 0x02a, 0x00000001,
+ 0x02b, 0x00000808,
+ 0x02b, 0x00053333,
+ 0x02c, 0x0000000c,
+ 0x02a, 0x00000002,
+ 0x02b, 0x00000808,
+ 0x02b, 0x0005b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000003,
+ 0x02b, 0x00000808,
+ 0x02b, 0x00063333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000004,
+ 0x02b, 0x00000808,
+ 0x02b, 0x0006b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000005,
+ 0x02b, 0x00000709,
+ 0x02b, 0x00053333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000006,
+ 0x02b, 0x00000709,
+ 0x02b, 0x0005b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000007,
+ 0x02b, 0x00000709,
+ 0x02b, 0x00063333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000008,
+ 0x02b, 0x00000709,
+ 0x02b, 0x0006b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000009,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x00053333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x0000000a,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x0005b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x0000000b,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x00063333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x0000000c,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x0006b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x0000000d,
+ 0x02b, 0x0000050b,
+ 0x02b, 0x00053333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x0000000e,
+ 0x02b, 0x0000050b,
+ 0x02b, 0x00066623,
+ 0x02c, 0x0000001a,
+ 0x02a, 0x000e4000,
+ 0x030, 0x00020000,
+ 0x031, 0x000b9631,
+ 0x032, 0x0000130d,
+ 0x033, 0x00000187,
+ 0x013, 0x00019e6c,
+ 0x013, 0x00015e94,
+ 0x000, 0x00010159,
+ 0x018, 0x0000f401,
+ 0x0fe, 0x00000000,
+ 0x01e, 0x0003105b,
+ 0x0fe, 0x00000000,
+ 0x000, 0x00030159,
+ 0x010, 0x0004000f,
+ 0x011, 0x000203f9,
+};
+
+u32 rtl8192seradiob_array[RADIOB_ARRAYLENGTH] = {
+ 0x000, 0x00030159,
+ 0x001, 0x00001041,
+ 0x002, 0x00011000,
+ 0x005, 0x00080fc0,
+ 0x007, 0x000fc803,
+ 0x013, 0x00017cb0,
+ 0x013, 0x00011cc0,
+ 0x013, 0x0000dc60,
+ 0x013, 0x00008c60,
+ 0x013, 0x00004450,
+ 0x013, 0x00000020,
+};
+
+u32 rtl8192seradiob_gm_array[RADIOB_GM_ARRAYLENGTH] = {
+ 0x000, 0x00030159,
+ 0x001, 0x00001041,
+ 0x002, 0x00011000,
+ 0x005, 0x00080fc0,
+ 0x007, 0x000fc803,
+};
+
+u32 rtl8192semac_2t_array[MAC_2T_ARRAYLENGTH] = {
+ 0x020, 0x00000035,
+ 0x048, 0x0000000e,
+ 0x049, 0x000000f0,
+ 0x04a, 0x00000077,
+ 0x04b, 0x00000083,
+ 0x0b5, 0x00000021,
+ 0x0dc, 0x000000ff,
+ 0x0dd, 0x000000ff,
+ 0x0de, 0x000000ff,
+ 0x0df, 0x000000ff,
+ 0x116, 0x00000000,
+ 0x117, 0x00000000,
+ 0x118, 0x00000000,
+ 0x119, 0x00000000,
+ 0x11a, 0x00000000,
+ 0x11b, 0x00000000,
+ 0x11c, 0x00000000,
+ 0x11d, 0x00000000,
+ 0x160, 0x0000000b,
+ 0x161, 0x0000000b,
+ 0x162, 0x0000000b,
+ 0x163, 0x0000000b,
+ 0x164, 0x0000000b,
+ 0x165, 0x0000000b,
+ 0x166, 0x0000000b,
+ 0x167, 0x0000000b,
+ 0x168, 0x0000000b,
+ 0x169, 0x0000000b,
+ 0x16a, 0x0000000b,
+ 0x16b, 0x0000000b,
+ 0x16c, 0x0000000b,
+ 0x16d, 0x0000000b,
+ 0x16e, 0x0000000b,
+ 0x16f, 0x0000000b,
+ 0x170, 0x0000000b,
+ 0x171, 0x0000000b,
+ 0x172, 0x0000000b,
+ 0x173, 0x0000000b,
+ 0x174, 0x0000000b,
+ 0x175, 0x0000000b,
+ 0x176, 0x0000000b,
+ 0x177, 0x0000000b,
+ 0x178, 0x0000000b,
+ 0x179, 0x0000000b,
+ 0x17a, 0x0000000b,
+ 0x17b, 0x0000000b,
+ 0x17c, 0x0000000b,
+ 0x17d, 0x0000000b,
+ 0x17e, 0x0000000b,
+ 0x17f, 0x0000000b,
+ 0x236, 0x0000000c,
+ 0x503, 0x00000022,
+ 0x560, 0x00000000,
+};
+
+u32 rtl8192seagctab_array[AGCTAB_ARRAYLENGTH] = {
+ 0xc78, 0x7f000001,
+ 0xc78, 0x7f010001,
+ 0xc78, 0x7e020001,
+ 0xc78, 0x7d030001,
+ 0xc78, 0x7c040001,
+ 0xc78, 0x7b050001,
+ 0xc78, 0x7a060001,
+ 0xc78, 0x79070001,
+ 0xc78, 0x78080001,
+ 0xc78, 0x77090001,
+ 0xc78, 0x760a0001,
+ 0xc78, 0x750b0001,
+ 0xc78, 0x740c0001,
+ 0xc78, 0x730d0001,
+ 0xc78, 0x720e0001,
+ 0xc78, 0x710f0001,
+ 0xc78, 0x70100001,
+ 0xc78, 0x6f110001,
+ 0xc78, 0x6f120001,
+ 0xc78, 0x6e130001,
+ 0xc78, 0x6d140001,
+ 0xc78, 0x6d150001,
+ 0xc78, 0x6c160001,
+ 0xc78, 0x6b170001,
+ 0xc78, 0x6a180001,
+ 0xc78, 0x6a190001,
+ 0xc78, 0x691a0001,
+ 0xc78, 0x681b0001,
+ 0xc78, 0x671c0001,
+ 0xc78, 0x661d0001,
+ 0xc78, 0x651e0001,
+ 0xc78, 0x641f0001,
+ 0xc78, 0x63200001,
+ 0xc78, 0x4c210001,
+ 0xc78, 0x4b220001,
+ 0xc78, 0x4a230001,
+ 0xc78, 0x49240001,
+ 0xc78, 0x48250001,
+ 0xc78, 0x47260001,
+ 0xc78, 0x46270001,
+ 0xc78, 0x45280001,
+ 0xc78, 0x44290001,
+ 0xc78, 0x2c2a0001,
+ 0xc78, 0x2b2b0001,
+ 0xc78, 0x2a2c0001,
+ 0xc78, 0x292d0001,
+ 0xc78, 0x282e0001,
+ 0xc78, 0x272f0001,
+ 0xc78, 0x26300001,
+ 0xc78, 0x25310001,
+ 0xc78, 0x24320001,
+ 0xc78, 0x23330001,
+ 0xc78, 0x22340001,
+ 0xc78, 0x09350001,
+ 0xc78, 0x08360001,
+ 0xc78, 0x07370001,
+ 0xc78, 0x06380001,
+ 0xc78, 0x05390001,
+ 0xc78, 0x043a0001,
+ 0xc78, 0x033b0001,
+ 0xc78, 0x023c0001,
+ 0xc78, 0x013d0001,
+ 0xc78, 0x003e0001,
+ 0xc78, 0x003f0001,
+ 0xc78, 0x7f400001,
+ 0xc78, 0x7f410001,
+ 0xc78, 0x7e420001,
+ 0xc78, 0x7d430001,
+ 0xc78, 0x7c440001,
+ 0xc78, 0x7b450001,
+ 0xc78, 0x7a460001,
+ 0xc78, 0x79470001,
+ 0xc78, 0x78480001,
+ 0xc78, 0x77490001,
+ 0xc78, 0x764a0001,
+ 0xc78, 0x754b0001,
+ 0xc78, 0x744c0001,
+ 0xc78, 0x734d0001,
+ 0xc78, 0x724e0001,
+ 0xc78, 0x714f0001,
+ 0xc78, 0x70500001,
+ 0xc78, 0x6f510001,
+ 0xc78, 0x6f520001,
+ 0xc78, 0x6e530001,
+ 0xc78, 0x6d540001,
+ 0xc78, 0x6d550001,
+ 0xc78, 0x6c560001,
+ 0xc78, 0x6b570001,
+ 0xc78, 0x6a580001,
+ 0xc78, 0x6a590001,
+ 0xc78, 0x695a0001,
+ 0xc78, 0x685b0001,
+ 0xc78, 0x675c0001,
+ 0xc78, 0x665d0001,
+ 0xc78, 0x655e0001,
+ 0xc78, 0x645f0001,
+ 0xc78, 0x63600001,
+ 0xc78, 0x4c610001,
+ 0xc78, 0x4b620001,
+ 0xc78, 0x4a630001,
+ 0xc78, 0x49640001,
+ 0xc78, 0x48650001,
+ 0xc78, 0x47660001,
+ 0xc78, 0x46670001,
+ 0xc78, 0x45680001,
+ 0xc78, 0x44690001,
+ 0xc78, 0x2c6a0001,
+ 0xc78, 0x2b6b0001,
+ 0xc78, 0x2a6c0001,
+ 0xc78, 0x296d0001,
+ 0xc78, 0x286e0001,
+ 0xc78, 0x276f0001,
+ 0xc78, 0x26700001,
+ 0xc78, 0x25710001,
+ 0xc78, 0x24720001,
+ 0xc78, 0x23730001,
+ 0xc78, 0x22740001,
+ 0xc78, 0x09750001,
+ 0xc78, 0x08760001,
+ 0xc78, 0x07770001,
+ 0xc78, 0x06780001,
+ 0xc78, 0x05790001,
+ 0xc78, 0x047a0001,
+ 0xc78, 0x037b0001,
+ 0xc78, 0x027c0001,
+ 0xc78, 0x017d0001,
+ 0xc78, 0x007e0001,
+ 0xc78, 0x007f0001,
+ 0xc78, 0x3000001e,
+ 0xc78, 0x3001001e,
+ 0xc78, 0x3002001e,
+ 0xc78, 0x3003001e,
+ 0xc78, 0x3004001e,
+ 0xc78, 0x3405001e,
+ 0xc78, 0x3806001e,
+ 0xc78, 0x3e07001e,
+ 0xc78, 0x3e08001e,
+ 0xc78, 0x4409001e,
+ 0xc78, 0x460a001e,
+ 0xc78, 0x480b001e,
+ 0xc78, 0x480c001e,
+ 0xc78, 0x4e0d001e,
+ 0xc78, 0x560e001e,
+ 0xc78, 0x5a0f001e,
+ 0xc78, 0x5e10001e,
+ 0xc78, 0x6211001e,
+ 0xc78, 0x6c12001e,
+ 0xc78, 0x7213001e,
+ 0xc78, 0x7214001e,
+ 0xc78, 0x7215001e,
+ 0xc78, 0x7216001e,
+ 0xc78, 0x7217001e,
+ 0xc78, 0x7218001e,
+ 0xc78, 0x7219001e,
+ 0xc78, 0x721a001e,
+ 0xc78, 0x721b001e,
+ 0xc78, 0x721c001e,
+ 0xc78, 0x721d001e,
+ 0xc78, 0x721e001e,
+ 0xc78, 0x721f001e,
+};
+
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.h b/drivers/net/wireless/rtlwifi/rtl8192se/table.h
new file mode 100644
index 00000000000..b4ed6d951eb
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/table.h
@@ -0,0 +1,49 @@
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+#ifndef __INC_HAL8192SE_FW_IMG_H
+#define __INC_HAL8192SE_FW_IMG_H
+
+#include <linux/types.h>
+
+/*Created on 2010/ 4/12, 5:56*/
+
+#define PHY_REG_2T2RARRAYLENGTH 372
+extern u32 rtl8192sephy_reg_2t2rarray[PHY_REG_2T2RARRAYLENGTH];
+#define PHY_CHANGETO_1T1RARRAYLENGTH 48
+extern u32 rtl8192sephy_changeto_1t1rarray[PHY_CHANGETO_1T1RARRAYLENGTH];
+#define PHY_CHANGETO_1T2RARRAYLENGTH 45
+extern u32 rtl8192sephy_changeto_1t2rarray[PHY_CHANGETO_1T2RARRAYLENGTH];
+#define PHY_REG_ARRAY_PGLENGTH 84
+extern u32 rtl8192sephy_reg_array_pg[PHY_REG_ARRAY_PGLENGTH];
+#define RADIOA_1T_ARRAYLENGTH 202
+extern u32 rtl8192seradioa_1t_array[RADIOA_1T_ARRAYLENGTH];
+#define RADIOB_ARRAYLENGTH 22
+extern u32 rtl8192seradiob_array[RADIOB_ARRAYLENGTH];
+#define RADIOB_GM_ARRAYLENGTH 10
+extern u32 rtl8192seradiob_gm_array[RADIOB_GM_ARRAYLENGTH];
+#define MAC_2T_ARRAYLENGTH 106
+extern u32 rtl8192semac_2t_array[MAC_2T_ARRAYLENGTH];
+#define AGCTAB_ARRAYLENGTH 320
+extern u32 rtl8192seagctab_array[AGCTAB_ARRAYLENGTH];
+
+#endif
+
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
new file mode 100644
index 00000000000..5cf442373d4
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -0,0 +1,976 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "fw.h"
+#include "trx.h"
+#include "led.h"
+
+static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 skb_queue)
+{
+ __le16 fc = rtl_get_fc(skb);
+
+ if (unlikely(ieee80211_is_beacon(fc)))
+ return QSLT_BEACON;
+ if (ieee80211_is_mgmt(fc))
+ return QSLT_MGNT;
+ if (ieee80211_is_nullfunc(fc))
+ return QSLT_HIGH;
+
+ return skb->priority;
+}
+
+static int _rtl92se_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu)
+{
+ int rate_idx = 0;
+
+ if (first_ampdu) {
+ if (false == isht) {
+ switch (desc_rate) {
+ case DESC92S_RATE1M:
+ rate_idx = 0;
+ break;
+ case DESC92S_RATE2M:
+ rate_idx = 1;
+ break;
+ case DESC92S_RATE5_5M:
+ rate_idx = 2;
+ break;
+ case DESC92S_RATE11M:
+ rate_idx = 3;
+ break;
+ case DESC92S_RATE6M:
+ rate_idx = 4;
+ break;
+ case DESC92S_RATE9M:
+ rate_idx = 5;
+ break;
+ case DESC92S_RATE12M:
+ rate_idx = 6;
+ break;
+ case DESC92S_RATE18M:
+ rate_idx = 7;
+ break;
+ case DESC92S_RATE24M:
+ rate_idx = 8;
+ break;
+ case DESC92S_RATE36M:
+ rate_idx = 9;
+ break;
+ case DESC92S_RATE48M:
+ rate_idx = 10;
+ break;
+ case DESC92S_RATE54M:
+ rate_idx = 11;
+ break;
+ default:
+ rate_idx = 0;
+ break;
+ }
+ } else {
+ rate_idx = 11;
+ }
+
+ return rate_idx;
+ }
+
+ switch (desc_rate) {
+ case DESC92S_RATE1M:
+ rate_idx = 0;
+ break;
+ case DESC92S_RATE2M:
+ rate_idx = 1;
+ break;
+ case DESC92S_RATE5_5M:
+ rate_idx = 2;
+ break;
+ case DESC92S_RATE11M:
+ rate_idx = 3;
+ break;
+ case DESC92S_RATE6M:
+ rate_idx = 4;
+ break;
+ case DESC92S_RATE9M:
+ rate_idx = 5;
+ break;
+ case DESC92S_RATE12M:
+ rate_idx = 6;
+ break;
+ case DESC92S_RATE18M:
+ rate_idx = 7;
+ break;
+ case DESC92S_RATE24M:
+ rate_idx = 8;
+ break;
+ case DESC92S_RATE36M:
+ rate_idx = 9;
+ break;
+ case DESC92S_RATE48M:
+ rate_idx = 10;
+ break;
+ case DESC92S_RATE54M:
+ rate_idx = 11;
+ break;
+ default:
+ rate_idx = 11;
+ break;
+ }
+ return rate_idx;
+}
+
+static u8 _rtl92s_query_rxpwrpercentage(char antpower)
+{
+ if ((antpower <= -100) || (antpower >= 20))
+ return 0;
+ else if (antpower >= 0)
+ return 100;
+ else
+ return 100 + antpower;
+}
+
+static u8 _rtl92s_evm_db_to_percentage(char value)
+{
+ char ret_val;
+ ret_val = value;
+
+ if (ret_val >= 0)
+ ret_val = 0;
+
+ if (ret_val <= -33)
+ ret_val = -33;
+
+ ret_val = 0 - ret_val;
+ ret_val *= 3;
+
+ if (ret_val == 99)
+ ret_val = 100;
+
+ return ret_val;
+}
+
+static long _rtl92se_translate_todbm(struct ieee80211_hw *hw,
+ u8 signal_strength_index)
+{
+ long signal_power;
+
+ signal_power = (long)((signal_strength_index + 1) >> 1);
+ signal_power -= 95;
+ return signal_power;
+}
+
+static long _rtl92se_signal_scale_mapping(struct ieee80211_hw *hw,
+ long currsig)
+{
+ long retsig = 0;
+
+ /* Step 1. Scale mapping. */
+ if (currsig > 47)
+ retsig = 100;
+ else if (currsig > 14 && currsig <= 47)
+ retsig = 100 - ((47 - currsig) * 3) / 2;
+ else if (currsig > 2 && currsig <= 14)
+ retsig = 48 - ((14 - currsig) * 15) / 7;
+ else if (currsig >= 0)
+ retsig = currsig * 9 + 1;
+
+ return retsig;
+}
+
+
+static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
+ struct rtl_stats *pstats, u8 *pdesc,
+ struct rx_fwinfo *p_drvinfo,
+ bool packet_match_bssid,
+ bool packet_toself,
+ bool packet_beacon)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct phy_sts_cck_8192s_t *cck_buf;
+ s8 rx_pwr_all = 0, rx_pwr[4];
+ u8 rf_rx_num = 0, evm, pwdb_all;
+ u8 i, max_spatial_stream;
+ u32 rssi, total_rssi = 0;
+ bool in_powersavemode = false;
+ bool is_cck_rate;
+
+ is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
+ pstats->packet_matchbssid = packet_match_bssid;
+ pstats->packet_toself = packet_toself;
+ pstats->is_cck = is_cck_rate;
+ pstats->packet_beacon = packet_beacon;
+ pstats->is_cck = is_cck_rate;
+ pstats->rx_mimo_signalquality[0] = -1;
+ pstats->rx_mimo_signalquality[1] = -1;
+
+ if (is_cck_rate) {
+ u8 report, cck_highpwr;
+ cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
+
+ if (!in_powersavemode)
+ cck_highpwr = (u8) rtl_get_bbreg(hw,
+ RFPGA0_XA_HSSIPARAMETER2,
+ 0x200);
+ else
+ cck_highpwr = false;
+
+ if (!cck_highpwr) {
+ u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
+ report = cck_buf->cck_agc_rpt & 0xc0;
+ report = report >> 6;
+ switch (report) {
+ case 0x3:
+ rx_pwr_all = -40 - (cck_agc_rpt & 0x3e);
+ break;
+ case 0x2:
+ rx_pwr_all = -20 - (cck_agc_rpt & 0x3e);
+ break;
+ case 0x1:
+ rx_pwr_all = -2 - (cck_agc_rpt & 0x3e);
+ break;
+ case 0x0:
+ rx_pwr_all = 14 - (cck_agc_rpt & 0x3e);
+ break;
+ }
+ } else {
+ u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
+ report = p_drvinfo->cfosho[0] & 0x60;
+ report = report >> 5;
+ switch (report) {
+ case 0x3:
+ rx_pwr_all = -40 - ((cck_agc_rpt & 0x1f) << 1);
+ break;
+ case 0x2:
+ rx_pwr_all = -20 - ((cck_agc_rpt & 0x1f) << 1);
+ break;
+ case 0x1:
+ rx_pwr_all = -2 - ((cck_agc_rpt & 0x1f) << 1);
+ break;
+ case 0x0:
+ rx_pwr_all = 14 - ((cck_agc_rpt & 0x1f) << 1);
+ break;
+ }
+ }
+
+ pwdb_all = _rtl92s_query_rxpwrpercentage(rx_pwr_all);
+
+ /* CCK gain is smaller than OFDM/MCS gain, */
+ /* so we add gain diff by experiences, the val is 6 */
+ pwdb_all += 6;
+ if (pwdb_all > 100)
+ pwdb_all = 100;
+ /* modify the offset to make the same gain index with OFDM. */
+ if (pwdb_all > 34 && pwdb_all <= 42)
+ pwdb_all -= 2;
+ else if (pwdb_all > 26 && pwdb_all <= 34)
+ pwdb_all -= 6;
+ else if (pwdb_all > 14 && pwdb_all <= 26)
+ pwdb_all -= 8;
+ else if (pwdb_all > 4 && pwdb_all <= 14)
+ pwdb_all -= 4;
+
+ pstats->rx_pwdb_all = pwdb_all;
+ pstats->recvsignalpower = rx_pwr_all;
+
+ if (packet_match_bssid) {
+ u8 sq;
+ if (pstats->rx_pwdb_all > 40) {
+ sq = 100;
+ } else {
+ sq = cck_buf->sq_rpt;
+ if (sq > 64)
+ sq = 0;
+ else if (sq < 20)
+ sq = 100;
+ else
+ sq = ((64 - sq) * 100) / 44;
+ }
+
+ pstats->signalquality = sq;
+ pstats->rx_mimo_signalquality[0] = sq;
+ pstats->rx_mimo_signalquality[1] = -1;
+ }
+ } else {
+ rtlpriv->dm.rfpath_rxenable[0] =
+ rtlpriv->dm.rfpath_rxenable[1] = true;
+ for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
+ if (rtlpriv->dm.rfpath_rxenable[i])
+ rf_rx_num++;
+
+ rx_pwr[i] = ((p_drvinfo->gain_trsw[i] &
+ 0x3f) * 2) - 110;
+ rssi = _rtl92s_query_rxpwrpercentage(rx_pwr[i]);
+ total_rssi += rssi;
+ rtlpriv->stats.rx_snr_db[i] =
+ (long)(p_drvinfo->rxsnr[i] / 2);
+
+ if (packet_match_bssid)
+ pstats->rx_mimo_signalstrength[i] = (u8) rssi;
+ }
+
+ rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
+ pwdb_all = _rtl92s_query_rxpwrpercentage(rx_pwr_all);
+ pstats->rx_pwdb_all = pwdb_all;
+ pstats->rxpower = rx_pwr_all;
+ pstats->recvsignalpower = rx_pwr_all;
+
+ if (GET_RX_STATUS_DESC_RX_HT(pdesc) &&
+ GET_RX_STATUS_DESC_RX_MCS(pdesc) >= DESC92S_RATEMCS8 &&
+ GET_RX_STATUS_DESC_RX_MCS(pdesc) <= DESC92S_RATEMCS15)
+ max_spatial_stream = 2;
+ else
+ max_spatial_stream = 1;
+
+ for (i = 0; i < max_spatial_stream; i++) {
+ evm = _rtl92s_evm_db_to_percentage(p_drvinfo->rxevm[i]);
+
+ if (packet_match_bssid) {
+ if (i == 0)
+ pstats->signalquality = (u8)(evm &
+ 0xff);
+ pstats->rx_mimo_signalquality[i] =
+ (u8) (evm & 0xff);
+ }
+ }
+ }
+
+ if (is_cck_rate)
+ pstats->signalstrength = (u8)(_rtl92se_signal_scale_mapping(hw,
+ pwdb_all));
+ else if (rf_rx_num != 0)
+ pstats->signalstrength = (u8) (_rtl92se_signal_scale_mapping(hw,
+ total_rssi /= rf_rx_num));
+}
+
+static void _rtl92se_process_ui_rssi(struct ieee80211_hw *hw,
+ struct rtl_stats *pstats)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ u8 rfpath;
+ u32 last_rssi, tmpval;
+
+ if (pstats->packet_toself || pstats->packet_beacon) {
+ rtlpriv->stats.rssi_calculate_cnt++;
+
+ if (rtlpriv->stats.ui_rssi.total_num++ >=
+ PHY_RSSI_SLID_WIN_MAX) {
+ rtlpriv->stats.ui_rssi.total_num =
+ PHY_RSSI_SLID_WIN_MAX;
+ last_rssi = rtlpriv->stats.ui_rssi.elements[
+ rtlpriv->stats.ui_rssi.index];
+ rtlpriv->stats.ui_rssi.total_val -= last_rssi;
+ }
+
+ rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
+ rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++]
+ = pstats->signalstrength;
+
+ if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
+ rtlpriv->stats.ui_rssi.index = 0;
+
+ tmpval = rtlpriv->stats.ui_rssi.total_val /
+ rtlpriv->stats.ui_rssi.total_num;
+ rtlpriv->stats.signal_strength = _rtl92se_translate_todbm(hw,
+ (u8) tmpval);
+ pstats->rssi = rtlpriv->stats.signal_strength;
+ }
+
+ if (!pstats->is_cck && pstats->packet_toself) {
+ for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
+ rfpath++) {
+ if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
+ rtlpriv->stats.rx_rssi_percentage[rfpath] =
+ pstats->rx_mimo_signalstrength[rfpath];
+
+ }
+
+ if (pstats->rx_mimo_signalstrength[rfpath] >
+ rtlpriv->stats.rx_rssi_percentage[rfpath]) {
+ rtlpriv->stats.rx_rssi_percentage[rfpath] =
+ ((rtlpriv->stats.rx_rssi_percentage[rfpath]
+ * (RX_SMOOTH_FACTOR - 1)) +
+ (pstats->rx_mimo_signalstrength[rfpath])) /
+ (RX_SMOOTH_FACTOR);
+
+ rtlpriv->stats.rx_rssi_percentage[rfpath] =
+ rtlpriv->stats.rx_rssi_percentage[rfpath]
+ + 1;
+ } else {
+ rtlpriv->stats.rx_rssi_percentage[rfpath] =
+ ((rtlpriv->stats.rx_rssi_percentage[rfpath]
+ * (RX_SMOOTH_FACTOR - 1)) +
+ (pstats->rx_mimo_signalstrength[rfpath])) /
+ (RX_SMOOTH_FACTOR);
+ }
+
+ }
+ }
+}
+
+static void _rtl92se_update_rxsignalstatistics(struct ieee80211_hw *hw,
+ struct rtl_stats *pstats)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int weighting = 0;
+
+ if (rtlpriv->stats.recv_signal_power == 0)
+ rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
+
+ if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
+ weighting = 5;
+ else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
+ weighting = (-5);
+
+ rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * 5
+ + pstats->recvsignalpower +
+ weighting) / 6;
+}
+
+static void _rtl92se_process_pwdb(struct ieee80211_hw *hw,
+ struct rtl_stats *pstats)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ long undec_sm_pwdb = 0;
+
+ if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+ return;
+ } else {
+ undec_sm_pwdb =
+ rtlpriv->dm.undecorated_smoothed_pwdb;
+ }
+
+ if (pstats->packet_toself || pstats->packet_beacon) {
+ if (undec_sm_pwdb < 0)
+ undec_sm_pwdb = pstats->rx_pwdb_all;
+
+ if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) {
+ undec_sm_pwdb =
+ (((undec_sm_pwdb) *
+ (RX_SMOOTH_FACTOR - 1)) +
+ (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
+
+ undec_sm_pwdb = undec_sm_pwdb + 1;
+ } else {
+ undec_sm_pwdb = (((undec_sm_pwdb) *
+ (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) /
+ (RX_SMOOTH_FACTOR);
+ }
+
+ rtlpriv->dm.undecorated_smoothed_pwdb = undec_sm_pwdb;
+ _rtl92se_update_rxsignalstatistics(hw, pstats);
+ }
+}
+
+static void rtl_92s_process_streams(struct ieee80211_hw *hw,
+ struct rtl_stats *pstats)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 stream;
+
+ for (stream = 0; stream < 2; stream++) {
+ if (pstats->rx_mimo_signalquality[stream] != -1) {
+ if (rtlpriv->stats.rx_evm_percentage[stream] == 0) {
+ rtlpriv->stats.rx_evm_percentage[stream] =
+ pstats->rx_mimo_signalquality[stream];
+ }
+
+ rtlpriv->stats.rx_evm_percentage[stream] =
+ ((rtlpriv->stats.rx_evm_percentage[stream] *
+ (RX_SMOOTH_FACTOR - 1)) +
+ (pstats->rx_mimo_signalquality[stream] *
+ 1)) / (RX_SMOOTH_FACTOR);
+ }
+ }
+}
+
+static void _rtl92se_process_ui_link_quality(struct ieee80211_hw *hw,
+ struct rtl_stats *pstats)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 last_evm = 0, tmpval;
+
+ if (pstats->signalquality != 0) {
+ if (pstats->packet_toself || pstats->packet_beacon) {
+
+ if (rtlpriv->stats.ui_link_quality.total_num++ >=
+ PHY_LINKQUALITY_SLID_WIN_MAX) {
+ rtlpriv->stats.ui_link_quality.total_num =
+ PHY_LINKQUALITY_SLID_WIN_MAX;
+ last_evm =
+ rtlpriv->stats.ui_link_quality.elements[
+ rtlpriv->stats.ui_link_quality.index];
+ rtlpriv->stats.ui_link_quality.total_val -=
+ last_evm;
+ }
+
+ rtlpriv->stats.ui_link_quality.total_val +=
+ pstats->signalquality;
+ rtlpriv->stats.ui_link_quality.elements[
+ rtlpriv->stats.ui_link_quality.index++] =
+ pstats->signalquality;
+
+ if (rtlpriv->stats.ui_link_quality.index >=
+ PHY_LINKQUALITY_SLID_WIN_MAX)
+ rtlpriv->stats.ui_link_quality.index = 0;
+
+ tmpval = rtlpriv->stats.ui_link_quality.total_val /
+ rtlpriv->stats.ui_link_quality.total_num;
+ rtlpriv->stats.signal_quality = tmpval;
+
+ rtlpriv->stats.last_sigstrength_inpercent = tmpval;
+
+ rtl_92s_process_streams(hw, pstats);
+
+ }
+ }
+}
+
+static void _rtl92se_process_phyinfo(struct ieee80211_hw *hw,
+ u8 *buffer,
+ struct rtl_stats *pcurrent_stats)
+{
+
+ if (!pcurrent_stats->packet_matchbssid &&
+ !pcurrent_stats->packet_beacon)
+ return;
+
+ _rtl92se_process_ui_rssi(hw, pcurrent_stats);
+ _rtl92se_process_pwdb(hw, pcurrent_stats);
+ _rtl92se_process_ui_link_quality(hw, pcurrent_stats);
+}
+
+static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw,
+ struct sk_buff *skb, struct rtl_stats *pstats,
+ u8 *pdesc, struct rx_fwinfo *p_drvinfo)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+ struct ieee80211_hdr *hdr;
+ u8 *tmp_buf;
+ u8 *praddr;
+ u8 *psaddr;
+ __le16 fc;
+ u16 type, cfc;
+ bool packet_matchbssid, packet_toself, packet_beacon;
+
+ tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
+
+ hdr = (struct ieee80211_hdr *)tmp_buf;
+ fc = hdr->frame_control;
+ cfc = le16_to_cpu(fc);
+ type = WLAN_FC_GET_TYPE(fc);
+ praddr = hdr->addr1;
+ psaddr = hdr->addr2;
+
+ packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
+ (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ?
+ hdr->addr1 : (cfc & IEEE80211_FCTL_FROMDS) ?
+ hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) &&
+ (!pstats->crc) && (!pstats->icv));
+
+ packet_toself = packet_matchbssid &&
+ (!compare_ether_addr(praddr, rtlefuse->dev_addr));
+
+ if (ieee80211_is_beacon(fc))
+ packet_beacon = true;
+
+ _rtl92se_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
+ packet_matchbssid, packet_toself, packet_beacon);
+ _rtl92se_process_phyinfo(hw, tmp_buf, pstats);
+}
+
+bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
+ struct ieee80211_rx_status *rx_status, u8 *pdesc,
+ struct sk_buff *skb)
+{
+ struct rx_fwinfo *p_drvinfo;
+ u32 phystatus = (u32)GET_RX_STATUS_DESC_PHY_STATUS(pdesc);
+
+ stats->length = (u16)GET_RX_STATUS_DESC_PKT_LEN(pdesc);
+ stats->rx_drvinfo_size = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE(pdesc) * 8;
+ stats->rx_bufshift = (u8)(GET_RX_STATUS_DESC_SHIFT(pdesc) & 0x03);
+ stats->icv = (u16)GET_RX_STATUS_DESC_ICV(pdesc);
+ stats->crc = (u16)GET_RX_STATUS_DESC_CRC32(pdesc);
+ stats->hwerror = (u16)(stats->crc | stats->icv);
+ stats->decrypted = !GET_RX_STATUS_DESC_SWDEC(pdesc);
+
+ stats->rate = (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc);
+ stats->shortpreamble = (u16)GET_RX_STATUS_DESC_SPLCP(pdesc);
+ stats->isampdu = (bool)(GET_RX_STATUS_DESC_PAGGR(pdesc) == 1);
+ stats->timestamp_low = GET_RX_STATUS_DESC_TSFL(pdesc);
+ stats->rx_is40Mhzpacket = (bool)GET_RX_STATUS_DESC_BW(pdesc);
+
+ if (stats->hwerror)
+ return false;
+
+ rx_status->freq = hw->conf.channel->center_freq;
+ rx_status->band = hw->conf.channel->band;
+
+ if (GET_RX_STATUS_DESC_CRC32(pdesc))
+ rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
+ if (!GET_RX_STATUS_DESC_SWDEC(pdesc))
+ rx_status->flag |= RX_FLAG_DECRYPTED;
+
+ if (GET_RX_STATUS_DESC_BW(pdesc))
+ rx_status->flag |= RX_FLAG_40MHZ;
+
+ if (GET_RX_STATUS_DESC_RX_HT(pdesc))
+ rx_status->flag |= RX_FLAG_HT;
+
+ rx_status->flag |= RX_FLAG_MACTIME_MPDU;
+
+ if (stats->decrypted)
+ rx_status->flag |= RX_FLAG_DECRYPTED;
+
+ rx_status->rate_idx = _rtl92se_rate_mapping((bool)
+ GET_RX_STATUS_DESC_RX_HT(pdesc),
+ (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc),
+ (bool)GET_RX_STATUS_DESC_PAGGR(pdesc));
+
+
+ rx_status->mactime = GET_RX_STATUS_DESC_TSFL(pdesc);
+ if (phystatus == true) {
+ p_drvinfo = (struct rx_fwinfo *)(skb->data +
+ stats->rx_bufshift);
+ _rtl92se_translate_rx_signal_stuff(hw, skb, stats, pdesc,
+ p_drvinfo);
+ }
+
+ /*rx_status->qual = stats->signal; */
+ rx_status->signal = stats->rssi + 10;
+ /*rx_status->noise = -stats->noise; */
+
+ return true;
+}
+
+void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
+ struct ieee80211_hdr *hdr, u8 *pdesc_tx,
+ struct ieee80211_tx_info *info, struct sk_buff *skb,
+ u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct ieee80211_sta *sta = info->control.sta;
+ u8 *pdesc = (u8 *) pdesc_tx;
+ u16 seq_number;
+ __le16 fc = hdr->frame_control;
+ u8 reserved_macid = 0;
+ u8 fw_qsel = _rtl92se_map_hwqueue_to_fwqueue(skb, hw_queue);
+ bool firstseg = (!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)));
+ bool lastseg = (!(hdr->frame_control &
+ cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)));
+ dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
+ PCI_DMA_TODEVICE);
+ u8 bw_40 = 0;
+
+ if (mac->opmode == NL80211_IFTYPE_STATION) {
+ bw_40 = mac->bw_40;
+ } else if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC) {
+ if (sta)
+ bw_40 = sta->ht_cap.cap &
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ }
+
+ seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
+
+ rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
+
+ CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE_RTL8192S);
+
+ if (firstseg) {
+ if (rtlpriv->dm.useramask) {
+ /* set txdesc macId */
+ if (ptcb_desc->mac_id < 32) {
+ SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
+ reserved_macid |= ptcb_desc->mac_id;
+ }
+ }
+ SET_TX_DESC_RSVD_MACID(pdesc, reserved_macid);
+
+ SET_TX_DESC_TXHT(pdesc, ((ptcb_desc->hw_rate >=
+ DESC92S_RATEMCS0) ? 1 : 0));
+
+ if (rtlhal->version == VERSION_8192S_ACUT) {
+ if (ptcb_desc->hw_rate == DESC92S_RATE1M ||
+ ptcb_desc->hw_rate == DESC92S_RATE2M ||
+ ptcb_desc->hw_rate == DESC92S_RATE5_5M ||
+ ptcb_desc->hw_rate == DESC92S_RATE11M) {
+ ptcb_desc->hw_rate = DESC92S_RATE12M;
+ }
+ }
+
+ SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
+
+ if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble)
+ SET_TX_DESC_TX_SHORT(pdesc, 0);
+
+ /* Aggregation related */
+ if (info->flags & IEEE80211_TX_CTL_AMPDU)
+ SET_TX_DESC_AGG_ENABLE(pdesc, 1);
+
+ /* For AMPDU, we must insert SSN into TX_DESC */
+ SET_TX_DESC_SEQ(pdesc, seq_number);
+
+ /* Protection mode related */
+ /* For 92S, if RTS/CTS are set, HW will execute RTS. */
+ /* We choose only one protection mode to execute */
+ SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
+ !ptcb_desc->cts_enable) ? 1 : 0));
+ SET_TX_DESC_CTS_ENABLE(pdesc, ((ptcb_desc->cts_enable) ?
+ 1 : 0));
+ SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0));
+
+ SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
+ SET_TX_DESC_RTS_BANDWIDTH(pdesc, 0);
+ SET_TX_DESC_RTS_SUB_CARRIER(pdesc, ptcb_desc->rts_sc);
+ SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <=
+ DESC92S_RATE54M) ?
+ (ptcb_desc->rts_use_shortpreamble ? 1 : 0)
+ : (ptcb_desc->rts_use_shortgi ? 1 : 0)));
+
+
+ /* Set Bandwidth and sub-channel settings. */
+ if (bw_40) {
+ if (ptcb_desc->packet_bw) {
+ SET_TX_DESC_TX_BANDWIDTH(pdesc, 1);
+ /* use duplicated mode */
+ SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
+ } else {
+ SET_TX_DESC_TX_BANDWIDTH(pdesc, 0);
+ SET_TX_DESC_TX_SUB_CARRIER(pdesc,
+ mac->cur_40_prime_sc);
+ }
+ } else {
+ SET_TX_DESC_TX_BANDWIDTH(pdesc, 0);
+ SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
+ }
+
+ /* 3 Fill necessary field in First Descriptor */
+ /*DWORD 0*/
+ SET_TX_DESC_LINIP(pdesc, 0);
+ SET_TX_DESC_OFFSET(pdesc, 32);
+ SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
+
+ /*DWORD 1*/
+ SET_TX_DESC_RA_BRSR_ID(pdesc, ptcb_desc->ratr_index);
+
+ /* Fill security related */
+ if (info->control.hw_key) {
+ struct ieee80211_key_conf *keyconf;
+
+ keyconf = info->control.hw_key;
+ switch (keyconf->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ SET_TX_DESC_SEC_TYPE(pdesc, 0x2);
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
+ break;
+ default:
+ SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
+ break;
+
+ }
+ }
+
+ /* Set Packet ID */
+ SET_TX_DESC_PACKET_ID(pdesc, 0);
+
+ /* We will assign magement queue to BK. */
+ SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
+
+ /* Alwasy enable all rate fallback range */
+ SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
+
+ /* Fix: I don't kown why hw use 6.5M to tx when set it */
+ SET_TX_DESC_USER_RATE(pdesc,
+ ptcb_desc->use_driver_rate ? 1 : 0);
+
+ /* Set NON_QOS bit. */
+ if (!ieee80211_is_data_qos(fc))
+ SET_TX_DESC_NON_QOS(pdesc, 1);
+
+ }
+
+ /* Fill fields that are required to be initialized
+ * in all of the descriptors */
+ /*DWORD 0 */
+ SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
+ SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
+
+ /* DWORD 7 */
+ SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
+
+ /* DOWRD 8 */
+ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
+}
+
+void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
+ bool firstseg, bool lastseg, struct sk_buff *skb)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_tcb_desc *tcb_desc = (struct rtl_tcb_desc *)(skb->cb);
+
+ dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
+ PCI_DMA_TODEVICE);
+
+ /* Clear all status */
+ CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_CMDDESC_SIZE_RTL8192S);
+
+ /* This bit indicate this packet is used for FW download. */
+ if (tcb_desc->cmd_or_init == DESC_PACKET_TYPE_INIT) {
+ /* For firmware downlaod we only need to set LINIP */
+ SET_TX_DESC_LINIP(pdesc, tcb_desc->last_inipkt);
+
+ /* 92SE must set as 1 for firmware download HW DMA error */
+ SET_TX_DESC_FIRST_SEG(pdesc, 1);
+ SET_TX_DESC_LAST_SEG(pdesc, 1);
+
+ /* 92SE need not to set TX packet size when firmware download */
+ SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
+ SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
+ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+
+ SET_TX_DESC_OWN(pdesc, 1);
+ } else { /* H2C Command Desc format (Host TXCMD) */
+ /* 92SE must set as 1 for firmware download HW DMA error */
+ SET_TX_DESC_FIRST_SEG(pdesc, 1);
+ SET_TX_DESC_LAST_SEG(pdesc, 1);
+
+ SET_TX_DESC_OFFSET(pdesc, 0x20);
+
+ /* Buffer size + command header */
+ SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
+ /* Fixed queue of H2C command */
+ SET_TX_DESC_QUEUE_SEL(pdesc, 0x13);
+
+ SET_BITS_TO_LE_4BYTE(skb->data, 24, 7, rtlhal->h2c_txcmd_seq);
+
+ SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
+ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+
+ SET_TX_DESC_OWN(pdesc, 1);
+
+ }
+}
+
+void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
+{
+ if (istx == true) {
+ switch (desc_name) {
+ case HW_DESC_OWN:
+ SET_TX_DESC_OWN(pdesc, 1);
+ break;
+ case HW_DESC_TX_NEXTDESC_ADDR:
+ SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
+ break;
+ default:
+ RT_ASSERT(false, ("ERR txdesc :%d not process\n",
+ desc_name));
+ break;
+ }
+ } else {
+ switch (desc_name) {
+ case HW_DESC_RXOWN:
+ SET_RX_STATUS_DESC_OWN(pdesc, 1);
+ break;
+ case HW_DESC_RXBUFF_ADDR:
+ SET_RX_STATUS__DESC_BUFF_ADDR(pdesc, *(u32 *) val);
+ break;
+ case HW_DESC_RXPKT_LEN:
+ SET_RX_STATUS_DESC_PKT_LEN(pdesc, *(u32 *) val);
+ break;
+ case HW_DESC_RXERO:
+ SET_RX_STATUS_DESC_EOR(pdesc, 1);
+ break;
+ default:
+ RT_ASSERT(false, ("ERR rxdesc :%d not process\n",
+ desc_name));
+ break;
+ }
+ }
+}
+
+u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name)
+{
+ u32 ret = 0;
+
+ if (istx == true) {
+ switch (desc_name) {
+ case HW_DESC_OWN:
+ ret = GET_TX_DESC_OWN(desc);
+ break;
+ case HW_DESC_TXBUFF_ADDR:
+ ret = GET_TX_DESC_TX_BUFFER_ADDRESS(desc);
+ break;
+ default:
+ RT_ASSERT(false, ("ERR txdesc :%d not process\n",
+ desc_name));
+ break;
+ }
+ } else {
+ switch (desc_name) {
+ case HW_DESC_OWN:
+ ret = GET_RX_STATUS_DESC_OWN(desc);
+ break;
+ case HW_DESC_RXPKT_LEN:
+ ret = GET_RX_STATUS_DESC_PKT_LEN(desc);
+ break;
+ default:
+ RT_ASSERT(false, ("ERR rxdesc :%d not process\n",
+ desc_name));
+ break;
+ }
+ }
+ return ret;
+}
+
+void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ rtl_write_word(rtlpriv, TP_POLL, BIT(0) << (hw_queue));
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h
new file mode 100644
index 00000000000..05862c51b86
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h
@@ -0,0 +1,45 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __REALTEK_PCI92SE_TRX_H__
+#define __REALTEK_PCI92SE_TRX_H__
+
+void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
+ u8 *pdesc, struct ieee80211_tx_info *info,
+ struct sk_buff *skb, u8 hw_queue,
+ struct rtl_tcb_desc *ptcb_desc);
+void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, bool firstseg,
+ bool lastseg, struct sk_buff *skb);
+bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
+ struct ieee80211_rx_status *rx_status, u8 *pdesc,
+ struct sk_buff *skb);
+void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val);
+u32 rtl92se_get_desc(u8 *pdesc, bool istx, u8 desc_name);
+void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index f5d85735d64..a9367eba1ea 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -852,6 +852,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb,
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct rtl_tx_desc *pdesc = NULL;
+ struct rtl_tcb_desc tcb_desc;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
u8 *pda_addr = hdr->addr1;
@@ -860,8 +861,17 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb,
u8 tid = 0;
u16 seq_number = 0;
- if (ieee80211_is_mgmt(fc))
- rtl_tx_mgmt_proc(hw, skb);
+ if (ieee80211_is_auth(fc)) {
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
+ rtl_ips_nic_on(hw);
+ }
+
+ if (rtlpriv->psc.sw_ps_enabled) {
+ if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) &&
+ !ieee80211_has_pm(fc))
+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
+ }
+
rtl_action_proc(hw, skb, true);
if (is_multicast_ether_addr(pda_addr))
rtlpriv->stats.txbytesmulticast += skb->len;
@@ -878,7 +888,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb,
seq_number <<= 4;
}
rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, info, skb,
- hw_queue);
+ hw_queue, &tcb_desc);
if (!ieee80211_has_morefrags(hdr->frame_control)) {
if (qc)
mac->tids[tid].seq_number = seq_number;
@@ -887,7 +897,8 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb,
rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX);
}
-static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct rtl_tcb_desc *dummy)
{
struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h
index abadfe918d3..d2a63fb3e1e 100644
--- a/drivers/net/wireless/rtlwifi/usb.h
+++ b/drivers/net/wireless/rtlwifi/usb.h
@@ -31,6 +31,8 @@
#include <linux/usb.h>
#include <linux/skbuff.h>
+#define RTL_RX_DESC_SIZE 24
+
#define RTL_USB_DEVICE(vend, prod, cfg) \
.match_flags = USB_DEVICE_ID_MATCH_DEVICE, \
.idVendor = (vend), \
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 07db95ff9bc..693395ee98f 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -68,6 +68,8 @@
#define QBSS_LOAD_SIZE 5
#define MAX_WMMELE_LENGTH 64
+#define TOTAL_CAM_ENTRY 32
+
/*slot time for 11g. */
#define RTL_SLOT_TIME_9 9
#define RTL_SLOT_TIME_20 20
@@ -94,8 +96,10 @@
#define CHANNEL_GROUP_MAX_5G 9
#define CHANNEL_MAX_NUMBER_2G 14
#define AVG_THERMAL_NUM 8
+#define MAX_TID_COUNT 9
/* for early mode */
+#define FCS_LEN 4
#define EM_HDR_LEN 8
enum intf_type {
INTF_PCI = 0,
@@ -159,6 +163,8 @@ enum hardware_type {
(IS_HARDWARE_TYPE_8192DE(rtlhal) || IS_HARDWARE_TYPE_8192DU(rtlhal))
#define IS_HARDWARE_TYPE_8723(rtlhal) \
(IS_HARDWARE_TYPE_8723E(rtlhal) || IS_HARDWARE_TYPE_8723U(rtlhal))
+#define IS_HARDWARE_TYPE_8723U(rtlhal) \
+ (rtlhal->hw_type == HARDWARE_TYPE_RTL8723U)
enum scan_operation_backup_opt {
SCAN_OPT_BACKUP = 0,
@@ -297,6 +303,9 @@ enum hw_variables {
HW_VAR_DATA_FILTER,
};
+#define HWSET_MAX_SIZE 128
+#define EFUSE_MAX_SECTION 16
+
enum _RT_MEDIA_STATUS {
RT_MEDIA_DISCONNECT = 0,
RT_MEDIA_CONNECT = 1
@@ -766,7 +775,7 @@ struct rtl_rfkill {
#define IQK_MATRIX_REG_NUM 8
#define IQK_MATRIX_SETTINGS_NUM (1 + 24 + 21)
struct iqk_matrix_regs {
- bool b_iqk_done;
+ bool iqk_done;
long value[1][IQK_MATRIX_REG_NUM];
};
@@ -843,6 +852,7 @@ struct rtl_phy {
bool apk_done;
u32 reg_rf3c[2]; /* pathA / pathB */
+ /* bfsync */
u8 framesync;
u32 framesync_c34;
@@ -852,6 +862,10 @@ struct rtl_phy {
};
#define MAX_TID_COUNT 9
+#define RTL_AGG_STOP 0
+#define RTL_AGG_PROGRESS 1
+#define RTL_AGG_START 2
+#define RTL_AGG_OPERATIONAL 3
#define RTL_AGG_OFF 0
#define RTL_AGG_ON 1
#define RTL_AGG_EMPTYING_HW_QUEUE_ADDBA 2
@@ -871,6 +885,13 @@ struct rtl_tid_data {
struct rtl_ht_agg agg;
};
+struct rtl_sta_info {
+ u8 ratr_index;
+ u8 wireless_mode;
+ u8 mimo_ps;
+ struct rtl_tid_data tids[MAX_TID_COUNT];
+} __packed;
+
struct rtl_priv;
struct rtl_io {
struct device *dev;
@@ -894,6 +915,7 @@ struct rtl_io {
u32(*read32_sync) (struct rtl_priv *rtlpriv, u32 addr);
int (*readN_sync) (struct rtl_priv *rtlpriv, u32 addr, u16 len,
u8 *pdata);
+
};
struct rtl_mac {
@@ -916,6 +938,8 @@ struct rtl_mac {
int n_channels;
int n_bitrates;
+ bool offchan_deley;
+
/*filters */
u32 rx_conf;
u16 rx_mgt_filter;
@@ -1032,7 +1056,9 @@ struct rtl_security {
enum rt_enc_alg pairwise_enc_algorithm;
/*Encryption Algorithm for Brocast/Multicast */
enum rt_enc_alg group_enc_algorithm;
-
+ /*Cam Entry Bitmap */
+ u32 hwsec_cam_bitmap;
+ u8 hwsec_cam_sta_addr[TOTAL_CAM_ENTRY][ETH_ALEN];
/*local Key buffer, indx 0 is for
pairwise key 1-4 is for agoup key. */
u8 key_buf[KEY_BUF_SIZE][MAX_KEY_LEN];
@@ -1053,7 +1079,7 @@ struct rtl_dm {
bool current_turbo_edca;
bool is_any_nonbepkts; /*out dm */
bool is_cur_rdlstate;
- bool txpower_trackingInit;
+ bool txpower_trackinginit;
bool disable_framebursting;
bool cck_inch14;
bool txpower_tracking;
@@ -1079,7 +1105,6 @@ struct rtl_dm {
bool disable_tx_int;
char ofdm_index[2];
char cck_index;
- u8 power_index_backup[6];
};
#define EFUSE_MAX_LOGICAL_SIZE 256
@@ -1175,6 +1200,7 @@ struct rtl_ps_ctl {
* otherwise Offset[560h] = 0x00.
* */
bool support_aspm;
+
bool support_backdoor;
/*for LPS */
@@ -1201,7 +1227,6 @@ struct rtl_ps_ctl {
/*just for PCIE ASPM */
u8 const_amdpci_aspm;
-
bool pwrdown_mode;
enum rf_pwrstate inactive_pwrstate;
@@ -1282,6 +1307,10 @@ struct rt_link_detect {
bool busytraffic;
bool higher_busytraffic;
bool higher_busyrxtraffic;
+
+ u32 tidtx_in4period[MAX_TID_COUNT][4];
+ u32 tidtx_inperiod[MAX_TID_COUNT];
+ bool higher_busytxtraffic[MAX_TID_COUNT];
};
struct rtl_tcb_desc {
@@ -1344,13 +1373,15 @@ struct rtl_hal_ops {
u32 add_msr, u32 rm_msr);
void (*get_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val);
void (*set_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val);
- void (*update_rate_table) (struct ieee80211_hw *hw);
+ void (*update_rate_tbl) (struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u8 rssi_level);
void (*update_rate_mask) (struct ieee80211_hw *hw, u8 rssi_level);
void (*fill_tx_desc) (struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc_tx,
struct ieee80211_tx_info *info,
- struct sk_buff *skb, unsigned int queue_index);
- void (*fill_fake_txdesc) (struct ieee80211_hw *hw, u8 * pDesc,
+ struct sk_buff *skb, u8 hw_queue,
+ struct rtl_tcb_desc *ptcb_desc);
+ void (*fill_fake_txdesc) (struct ieee80211_hw *hw, u8 *pDesc,
u32 buffer_len, bool bIsPsPoll);
void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc,
bool firstseg, bool lastseg,
@@ -1370,10 +1401,10 @@ struct rtl_hal_ops {
enum led_ctl_mode ledaction);
void (*set_desc) (u8 *pdesc, bool istx, u8 desc_name, u8 *val);
u32 (*get_desc) (u8 *pdesc, bool istx, u8 desc_name);
- void (*tx_polling) (struct ieee80211_hw *hw, unsigned int hw_queue);
+ void (*tx_polling) (struct ieee80211_hw *hw, u8 hw_queue);
void (*enable_hw_sec) (struct ieee80211_hw *hw);
void (*set_key) (struct ieee80211_hw *hw, u32 key_index,
- u8 *p_macaddr, bool is_group, u8 enc_algo,
+ u8 *macaddr, bool is_group, u8 enc_algo,
bool is_wepkey, bool clear_all);
void (*init_sw_leds) (struct ieee80211_hw *hw);
void (*deinit_sw_leds) (struct ieee80211_hw *hw);
@@ -1384,6 +1415,7 @@ struct rtl_hal_ops {
u32 regaddr, u32 bitmask);
void (*set_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath,
u32 regaddr, u32 bitmask, u32 data);
+ void (*linked_set_reg) (struct ieee80211_hw *hw);
bool (*phy_rf6052_config) (struct ieee80211_hw *hw);
void (*phy_rf6052_set_cck_txpower) (struct ieee80211_hw *hw,
u8 *powerlevel);
@@ -1404,7 +1436,9 @@ struct rtl_intf_ops {
int (*adapter_start) (struct ieee80211_hw *hw);
void (*adapter_stop) (struct ieee80211_hw *hw);
- int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb);
+ int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct rtl_tcb_desc *ptcb_desc);
+ void (*flush)(struct ieee80211_hw *hw, bool drop);
int (*reset_trx_ring) (struct ieee80211_hw *hw);
bool (*waitq_insert) (struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -1418,6 +1452,15 @@ struct rtl_intf_ops {
struct rtl_mod_params {
/* default: 0 = using hardware encryption */
int sw_crypto;
+
+ /* default: 1 = using no linked power save */
+ bool inactiveps;
+
+ /* default: 1 = using linked sw power save */
+ bool swctrl_lps;
+
+ /* default: 1 = using linked fw power save */
+ bool fwctrl_lps;
};
struct rtl_hal_usbint_cfg {
@@ -1445,6 +1488,7 @@ struct rtl_hal_usbint_cfg {
struct rtl_hal_cfg {
u8 bar_id;
+ bool write_readback;
char *name;
char *fw_name;
struct rtl_hal_ops *ops;
@@ -1469,7 +1513,6 @@ struct rtl_locks {
spinlock_t rf_lock;
spinlock_t lps_lock;
spinlock_t waitq_lock;
- spinlock_t tx_urb_lock;
/*Dual mac*/
spinlock_t cck_and_rw_pagea_lock;
@@ -1621,19 +1664,19 @@ struct bt_coexist_info {
u32 bt_edca_ul;
u32 bt_edca_dl;
- bool b_init_set;
- bool b_bt_busy_traffic;
- bool b_bt_traffic_mode_set;
- bool b_bt_non_traffic_mode_set;
+ bool init_set;
+ bool bt_busy_traffic;
+ bool bt_traffic_mode_set;
+ bool bt_non_traffic_mode_set;
- bool b_fw_coexist_all_off;
- bool b_sw_coexist_all_off;
+ bool fw_coexist_all_off;
+ bool sw_coexist_all_off;
u32 current_state;
u32 previous_state;
u8 bt_pre_rssi_state;
- u8 b_reg_bt_iso;
- u8 b_reg_bt_sco;
+ u8 reg_bt_iso;
+ u8 reg_bt_sco;
};
@@ -1653,13 +1696,23 @@ struct bt_coexist_info {
#define EF4BYTE(_val) \
(le32_to_cpu(_val))
+/* Read data from memory */
+#define READEF1BYTE(_ptr) \
+ EF1BYTE(*((u8 *)(_ptr)))
/* Read le16 data from memory and convert to host ordering */
#define READEF2BYTE(_ptr) \
EF2BYTE(*((u16 *)(_ptr)))
+#define READEF4BYTE(_ptr) \
+ EF4BYTE(*((u32 *)(_ptr)))
+/* Write data to memory */
+#define WRITEEF1BYTE(_ptr, _val) \
+ (*((u8 *)(_ptr))) = EF1BYTE(_val)
/* Write le16 data to memory in host ordering */
#define WRITEEF2BYTE(_ptr, _val) \
(*((u16 *)(_ptr))) = EF2BYTE(_val)
+#define WRITEEF4BYTE(_ptr, _val) \
+ (*((u16 *)(_ptr))) = EF2BYTE(_val)
/* Create a bit mask
* Examples:
@@ -1698,6 +1751,25 @@ struct bt_coexist_info {
#define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \
(EF1BYTE(*((u8 *)(__pstart))))
+/*Description:
+Translate subfield (continuous bits in little-endian) of 4-byte
+value to host byte ordering.*/
+#define LE_BITS_TO_4BYTE(__pstart, __bitoffset, __bitlen) \
+ ( \
+ (LE_P4BYTE_TO_HOST_4BYTE(__pstart) >> (__bitoffset)) & \
+ BIT_LEN_MASK_32(__bitlen) \
+ )
+#define LE_BITS_TO_2BYTE(__pstart, __bitoffset, __bitlen) \
+ ( \
+ (LE_P2BYTE_TO_HOST_2BYTE(__pstart) >> (__bitoffset)) & \
+ BIT_LEN_MASK_16(__bitlen) \
+ )
+#define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \
+ ( \
+ (LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset)) & \
+ BIT_LEN_MASK_8(__bitlen) \
+ )
+
/* Description:
* Mask subfield (continuous bits in little-endian) of 4-byte value
* and return the result in 4-byte value in host byte ordering.
@@ -1721,6 +1793,18 @@ struct bt_coexist_info {
/* Description:
* Set subfield of little-endian 4-byte value to specified value.
*/
+#define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \
+ *((u32 *)(__pstart)) = EF4BYTE \
+ ( \
+ LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \
+ ((((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset)) \
+ );
+#define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \
+ *((u16 *)(__pstart)) = EF2BYTE \
+ ( \
+ LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \
+ ((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \
+ );
#define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \
*((u8 *)(__pstart)) = EF1BYTE \
( \
@@ -1728,12 +1812,16 @@ struct bt_coexist_info {
((((u8)__val) & BIT_LEN_MASK_8(__bitlen)) << (__bitoffset)) \
);
+#define N_BYTE_ALIGMENT(__value, __aligment) ((__aligment == 1) ? \
+ (__value) : (((__value + __aligment - 1) / __aligment) * __aligment))
+
/****************************************
mem access macro define end
****************************************/
#define byte(x, n) ((x >> (8 * n)) & 0xff)
+#define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC)
#define RTL_WATCH_DOG_TIME 2000
#define MSECS(t) msecs_to_jiffies(t)
#define WLAN_FC_GET_VERS(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_VERS)
@@ -1768,6 +1856,15 @@ struct bt_coexist_info {
#define container_of_dwork_rtl(x, y, z) \
container_of(container_of(x, struct delayed_work, work), y, z)
+#define FILL_OCTET_STRING(_os, _octet, _len) \
+ (_os).octet = (u8 *)(_octet); \
+ (_os).length = (_len);
+
+#define CP_MACADDR(des, src) \
+ ((des)[0] = (src)[0], (des)[1] = (src)[1],\
+ (des)[2] = (src)[2], (des)[3] = (src)[3],\
+ (des)[4] = (src)[4], (des)[5] = (src)[5])
+
static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr)
{
return rtlpriv->io.read8_sync(rtlpriv, addr);
@@ -1786,17 +1883,26 @@ static inline u32 rtl_read_dword(struct rtl_priv *rtlpriv, u32 addr)
static inline void rtl_write_byte(struct rtl_priv *rtlpriv, u32 addr, u8 val8)
{
rtlpriv->io.write8_async(rtlpriv, addr, val8);
+
+ if (rtlpriv->cfg->write_readback)
+ rtlpriv->io.read8_sync(rtlpriv, addr);
}
static inline void rtl_write_word(struct rtl_priv *rtlpriv, u32 addr, u16 val16)
{
rtlpriv->io.write16_async(rtlpriv, addr, val16);
+
+ if (rtlpriv->cfg->write_readback)
+ rtlpriv->io.read16_sync(rtlpriv, addr);
}
static inline void rtl_write_dword(struct rtl_priv *rtlpriv,
u32 addr, u32 val32)
{
rtlpriv->io.write32_async(rtlpriv, addr, val32);
+
+ if (rtlpriv->cfg->write_readback)
+ rtlpriv->io.read32_sync(rtlpriv, addr);
}
static inline u32 rtl_get_bbreg(struct ieee80211_hw *hw,
@@ -1855,4 +1961,31 @@ static inline u8 get_rf_type(struct rtl_phy *rtlphy)
return rtlphy->rf_type;
}
+static inline struct ieee80211_hdr *rtl_get_hdr(struct sk_buff *skb)
+{
+ return (struct ieee80211_hdr *)(skb->data);
+}
+
+static inline __le16 rtl_get_fc(struct sk_buff *skb)
+{
+ return rtl_get_hdr(skb)->frame_control;
+}
+
+static inline u16 rtl_get_tid_h(struct ieee80211_hdr *hdr)
+{
+ return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
+}
+
+static inline u16 rtl_get_tid(struct sk_buff *skb)
+{
+ return rtl_get_tid_h(rtl_get_hdr(skb));
+}
+
+static inline struct ieee80211_sta *get_sta(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ u8 *bssid)
+{
+ return ieee80211_find_sta(vif, bssid);
+}
+
#endif
diff --git a/drivers/net/wireless/wl1251/cmd.h b/drivers/net/wireless/wl1251/cmd.h
index e5c74c63137..79ca5273c9e 100644
--- a/drivers/net/wireless/wl1251/cmd.h
+++ b/drivers/net/wireless/wl1251/cmd.h
@@ -313,8 +313,8 @@ struct wl1251_cmd_vbm_update {
} __packed;
enum wl1251_cmd_ps_mode {
- STATION_ACTIVE_MODE,
- STATION_POWER_SAVE_MODE
+ CHIP_ACTIVE_MODE,
+ CHIP_POWER_SAVE_MODE
};
struct wl1251_cmd_ps_params {
diff --git a/drivers/net/wireless/wl1251/event.c b/drivers/net/wireless/wl1251/event.c
index dfc4579acb0..9f15ccaf8f0 100644
--- a/drivers/net/wireless/wl1251/event.c
+++ b/drivers/net/wireless/wl1251/event.c
@@ -68,14 +68,16 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
if (vector & BSS_LOSE_EVENT_ID) {
wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
- if (wl->psm_requested && wl->psm) {
+ if (wl->psm_requested &&
+ wl->station_mode != STATION_ACTIVE_MODE) {
ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
if (ret < 0)
return ret;
}
}
- if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && wl->psm) {
+ if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID &&
+ wl->station_mode != STATION_ACTIVE_MODE) {
wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
/* indicate to the stack, that beacons have been lost */
diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c
index 12c9e635a6d..a14a48c99cd 100644
--- a/drivers/net/wireless/wl1251/main.c
+++ b/drivers/net/wireless/wl1251/main.c
@@ -497,7 +497,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
wl->rx_last_id = 0;
wl->next_tx_complete = 0;
wl->elp = false;
- wl->psm = 0;
+ wl->station_mode = STATION_ACTIVE_MODE;
wl->tx_queue_stopped = false;
wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
wl->rssi_thold = 0;
@@ -632,13 +632,29 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
wl->psm_requested = false;
- if (wl->psm) {
+ if (wl->station_mode != STATION_ACTIVE_MODE) {
ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
if (ret < 0)
goto out_sleep;
}
}
+ if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+ if (conf->flags & IEEE80211_CONF_IDLE) {
+ ret = wl1251_ps_set_mode(wl, STATION_IDLE);
+ if (ret < 0)
+ goto out_sleep;
+ } else {
+ ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
+ if (ret < 0)
+ goto out_sleep;
+ ret = wl1251_join(wl, wl->bss_type, wl->channel,
+ wl->beacon_int, wl->dtim_period);
+ if (ret < 0)
+ goto out_sleep;
+ }
+ }
+
if (conf->power_level != wl->power_level) {
ret = wl1251_acx_tx_power(wl, conf->power_level);
if (ret < 0)
@@ -1384,7 +1400,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
wl->elp = false;
- wl->psm = 0;
+ wl->station_mode = STATION_ACTIVE_MODE;
wl->psm_requested = false;
wl->tx_queue_stopped = false;
wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
diff --git a/drivers/net/wireless/wl1251/ps.c b/drivers/net/wireless/wl1251/ps.c
index 9cc514703d2..db719f7d269 100644
--- a/drivers/net/wireless/wl1251/ps.c
+++ b/drivers/net/wireless/wl1251/ps.c
@@ -39,7 +39,7 @@ void wl1251_elp_work(struct work_struct *work)
mutex_lock(&wl->mutex);
- if (wl->elp || !wl->psm)
+ if (wl->elp || wl->station_mode == STATION_ACTIVE_MODE)
goto out;
wl1251_debug(DEBUG_PSM, "chip to elp");
@@ -57,7 +57,7 @@ void wl1251_ps_elp_sleep(struct wl1251 *wl)
{
unsigned long delay;
- if (wl->psm) {
+ if (wl->station_mode != STATION_ACTIVE_MODE) {
delay = msecs_to_jiffies(ELP_ENTRY_DELAY);
ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay);
}
@@ -104,7 +104,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
return 0;
}
-int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
+int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_station_mode mode)
{
int ret;
@@ -128,15 +128,24 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
if (ret < 0)
return ret;
- ret = wl1251_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
+ ret = wl1251_cmd_ps_mode(wl, CHIP_POWER_SAVE_MODE);
if (ret < 0)
return ret;
ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP);
if (ret < 0)
return ret;
+ break;
+ case STATION_IDLE:
+ wl1251_debug(DEBUG_PSM, "entering idle");
- wl->psm = 1;
+ ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP);
+ if (ret < 0)
+ return ret;
+
+ ret = wl1251_cmd_template_set(wl, CMD_DISCONNECT, NULL, 0);
+ if (ret < 0)
+ return ret;
break;
case STATION_ACTIVE_MODE:
default:
@@ -163,13 +172,13 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
if (ret < 0)
return ret;
- ret = wl1251_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
+ ret = wl1251_cmd_ps_mode(wl, CHIP_ACTIVE_MODE);
if (ret < 0)
return ret;
- wl->psm = 0;
break;
}
+ wl->station_mode = mode;
return ret;
}
diff --git a/drivers/net/wireless/wl1251/ps.h b/drivers/net/wireless/wl1251/ps.h
index 55c3dda75e6..75efad246d6 100644
--- a/drivers/net/wireless/wl1251/ps.h
+++ b/drivers/net/wireless/wl1251/ps.h
@@ -26,7 +26,7 @@
#include "wl1251.h"
#include "acx.h"
-int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode);
+int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_station_mode mode);
void wl1251_ps_elp_sleep(struct wl1251 *wl);
int wl1251_ps_elp_wakeup(struct wl1251 *wl);
void wl1251_elp_work(struct work_struct *work);
diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h
index bb23cd522b2..a77f1bbbed0 100644
--- a/drivers/net/wireless/wl1251/wl1251.h
+++ b/drivers/net/wireless/wl1251/wl1251.h
@@ -129,6 +129,12 @@ enum wl1251_partition_type {
PART_TABLE_LEN
};
+enum wl1251_station_mode {
+ STATION_ACTIVE_MODE,
+ STATION_POWER_SAVE_MODE,
+ STATION_IDLE,
+};
+
struct wl1251_partition {
u32 size;
u32 start;
@@ -358,8 +364,7 @@ struct wl1251 {
struct delayed_work elp_work;
- /* we can be in psm, but not in elp, we have to differentiate */
- bool psm;
+ enum wl1251_station_mode station_mode;
/* PSM mode requested */
bool psm_requested;
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index 692ebff38fc..35ce7b0f4a6 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -3,7 +3,7 @@ menuconfig WL12XX_MENU
depends on MAC80211 && EXPERIMENTAL
---help---
This will enable TI wl12xx driver support for the following chips:
- wl1271 and wl1273.
+ wl1271, wl1273, wl1281 and wl1283.
The drivers make use of the mac80211 stack.
config WL12XX
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index a3db755ceed..c6ee530e5bf 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -325,12 +325,19 @@ out:
return ret;
}
-int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
+int wl1271_acx_rts_threshold(struct wl1271 *wl, u32 rts_threshold)
{
struct acx_rts_threshold *rts;
int ret;
- wl1271_debug(DEBUG_ACX, "acx rts threshold");
+ /*
+ * If the RTS threshold is not configured or out of range, use the
+ * default value.
+ */
+ if (rts_threshold > IEEE80211_MAX_RTS_THRESHOLD)
+ rts_threshold = wl->conf.rx.rts_threshold;
+
+ wl1271_debug(DEBUG_ACX, "acx rts threshold: %d", rts_threshold);
rts = kzalloc(sizeof(*rts), GFP_KERNEL);
if (!rts) {
@@ -338,7 +345,7 @@ int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
goto out;
}
- rts->threshold = cpu_to_le16(rts_threshold);
+ rts->threshold = cpu_to_le16((u16)rts_threshold);
ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
if (ret < 0) {
@@ -540,13 +547,13 @@ out:
return ret;
}
-int wl1271_acx_sg_cfg(struct wl1271 *wl)
+int wl1271_acx_sta_sg_cfg(struct wl1271 *wl)
{
- struct acx_bt_wlan_coex_param *param;
+ struct acx_sta_bt_wlan_coex_param *param;
struct conf_sg_settings *c = &wl->conf.sg;
int i, ret;
- wl1271_debug(DEBUG_ACX, "acx sg cfg");
+ wl1271_debug(DEBUG_ACX, "acx sg sta cfg");
param = kzalloc(sizeof(*param), GFP_KERNEL);
if (!param) {
@@ -555,8 +562,38 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl)
}
/* BT-WLAN coext parameters */
- for (i = 0; i < CONF_SG_PARAMS_MAX; i++)
- param->params[i] = cpu_to_le32(c->params[i]);
+ for (i = 0; i < CONF_SG_STA_PARAMS_MAX; i++)
+ param->params[i] = cpu_to_le32(c->sta_params[i]);
+ param->param_idx = CONF_SG_PARAMS_ALL;
+
+ ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
+ if (ret < 0) {
+ wl1271_warning("failed to set sg config: %d", ret);
+ goto out;
+ }
+
+out:
+ kfree(param);
+ return ret;
+}
+
+int wl1271_acx_ap_sg_cfg(struct wl1271 *wl)
+{
+ struct acx_ap_bt_wlan_coex_param *param;
+ struct conf_sg_settings *c = &wl->conf.sg;
+ int i, ret;
+
+ wl1271_debug(DEBUG_ACX, "acx sg ap cfg");
+
+ param = kzalloc(sizeof(*param), GFP_KERNEL);
+ if (!param) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* BT-WLAN coext parameters */
+ for (i = 0; i < CONF_SG_AP_PARAMS_MAX; i++)
+ param->params[i] = cpu_to_le32(c->ap_params[i]);
param->param_idx = CONF_SG_PARAMS_ALL;
ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
@@ -804,7 +841,8 @@ int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c,
struct acx_ap_rate_policy *acx;
int ret = 0;
- wl1271_debug(DEBUG_ACX, "acx ap rate policy");
+ wl1271_debug(DEBUG_ACX, "acx ap rate policy %d rates 0x%x",
+ idx, c->enabled_rates);
acx = kzalloc(sizeof(*acx), GFP_KERNEL);
if (!acx) {
@@ -898,12 +936,19 @@ out:
return ret;
}
-int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold)
+int wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold)
{
struct acx_frag_threshold *acx;
int ret = 0;
- wl1271_debug(DEBUG_ACX, "acx frag threshold");
+ /*
+ * If the fragmentation is not configured or out of range, use the
+ * default value.
+ */
+ if (frag_threshold > IEEE80211_MAX_FRAG_THRESHOLD)
+ frag_threshold = wl->conf.tx.frag_threshold;
+
+ wl1271_debug(DEBUG_ACX, "acx frag threshold: %d", frag_threshold);
acx = kzalloc(sizeof(*acx), GFP_KERNEL);
@@ -912,7 +957,7 @@ int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold)
goto out;
}
- acx->frag_threshold = cpu_to_le16(frag_threshold);
+ acx->frag_threshold = cpu_to_le16((u16)frag_threshold);
ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
if (ret < 0) {
wl1271_warning("Setting of frag threshold failed: %d", ret);
@@ -954,6 +999,7 @@ out:
int wl1271_acx_ap_mem_cfg(struct wl1271 *wl)
{
struct wl1271_acx_ap_config_memory *mem_conf;
+ struct conf_memory_settings *mem;
int ret;
wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
@@ -964,11 +1010,21 @@ int wl1271_acx_ap_mem_cfg(struct wl1271 *wl)
goto out;
}
+ if (wl->chip.id == CHIP_ID_1283_PG20)
+ /*
+ * FIXME: The 128x AP FW does not yet support dynamic memory.
+ * Use the base memory configuration for 128x for now. This
+ * should be fine tuned in the future.
+ */
+ mem = &wl->conf.mem_wl128x;
+ else
+ mem = &wl->conf.mem_wl127x;
+
/* memory config */
- mem_conf->num_stations = wl->conf.mem.num_stations;
- mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num;
- mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num;
- mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles;
+ mem_conf->num_stations = mem->num_stations;
+ mem_conf->rx_mem_block_num = mem->rx_block_num;
+ mem_conf->tx_min_mem_block_num = mem->tx_min_block_num;
+ mem_conf->num_ssid_profiles = mem->ssid_profiles;
mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
@@ -986,6 +1042,7 @@ out:
int wl1271_acx_sta_mem_cfg(struct wl1271 *wl)
{
struct wl1271_acx_sta_config_memory *mem_conf;
+ struct conf_memory_settings *mem;
int ret;
wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
@@ -996,16 +1053,21 @@ int wl1271_acx_sta_mem_cfg(struct wl1271 *wl)
goto out;
}
+ if (wl->chip.id == CHIP_ID_1283_PG20)
+ mem = &wl->conf.mem_wl128x;
+ else
+ mem = &wl->conf.mem_wl127x;
+
/* memory config */
- mem_conf->num_stations = wl->conf.mem.num_stations;
- mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num;
- mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num;
- mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles;
+ mem_conf->num_stations = mem->num_stations;
+ mem_conf->rx_mem_block_num = mem->rx_block_num;
+ mem_conf->tx_min_mem_block_num = mem->tx_min_block_num;
+ mem_conf->num_ssid_profiles = mem->ssid_profiles;
mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
- mem_conf->dyn_mem_enable = wl->conf.mem.dynamic_memory;
- mem_conf->tx_free_req = wl->conf.mem.min_req_tx_blocks;
- mem_conf->rx_free_req = wl->conf.mem.min_req_rx_blocks;
- mem_conf->tx_min = wl->conf.mem.tx_min;
+ mem_conf->dyn_mem_enable = mem->dynamic_memory;
+ mem_conf->tx_free_req = mem->min_req_tx_blocks;
+ mem_conf->rx_free_req = mem->min_req_rx_blocks;
+ mem_conf->tx_min = mem->tx_min;
ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
sizeof(*mem_conf));
@@ -1019,6 +1081,32 @@ out:
return ret;
}
+int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap)
+{
+ struct wl1271_acx_host_config_bitmap *bitmap_conf;
+ int ret;
+
+ bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL);
+ if (!bitmap_conf) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap);
+
+ ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP,
+ bitmap_conf, sizeof(*bitmap_conf));
+ if (ret < 0) {
+ wl1271_warning("wl1271 bitmap config opt failed: %d", ret);
+ goto out;
+ }
+
+out:
+ kfree(bitmap_conf);
+
+ return ret;
+}
+
int wl1271_acx_init_mem_config(struct wl1271 *wl)
{
int ret;
@@ -1567,3 +1655,68 @@ out:
kfree(acx);
return ret;
}
+
+int wl1271_acx_set_ap_beacon_filter(struct wl1271 *wl, bool enable)
+{
+ struct acx_ap_beacon_filter *acx = NULL;
+ int ret;
+
+ wl1271_debug(DEBUG_ACX, "acx set ap beacon filter: %d", enable);
+
+ acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+ if (!acx)
+ return -ENOMEM;
+
+ acx->enable = enable ? 1 : 0;
+
+ ret = wl1271_cmd_configure(wl, ACX_AP_BEACON_FILTER_OPT,
+ acx, sizeof(*acx));
+ if (ret < 0) {
+ wl1271_warning("acx set ap beacon filter failed: %d", ret);
+ goto out;
+ }
+
+out:
+ kfree(acx);
+ return ret;
+}
+
+int wl1271_acx_fm_coex(struct wl1271 *wl)
+{
+ struct wl1271_acx_fm_coex *acx;
+ int ret;
+
+ wl1271_debug(DEBUG_ACX, "acx fm coex setting");
+
+ acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+ if (!acx) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ acx->enable = wl->conf.fm_coex.enable;
+ acx->swallow_period = wl->conf.fm_coex.swallow_period;
+ acx->n_divider_fref_set_1 = wl->conf.fm_coex.n_divider_fref_set_1;
+ acx->n_divider_fref_set_2 = wl->conf.fm_coex.n_divider_fref_set_2;
+ acx->m_divider_fref_set_1 =
+ cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_1);
+ acx->m_divider_fref_set_2 =
+ cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_2);
+ acx->coex_pll_stabilization_time =
+ cpu_to_le32(wl->conf.fm_coex.coex_pll_stabilization_time);
+ acx->ldo_stabilization_time =
+ cpu_to_le16(wl->conf.fm_coex.ldo_stabilization_time);
+ acx->fm_disturbed_band_margin =
+ wl->conf.fm_coex.fm_disturbed_band_margin;
+ acx->swallow_clk_diff = wl->conf.fm_coex.swallow_clk_diff;
+
+ ret = wl1271_cmd_configure(wl, ACX_FM_COEX_CFG, acx, sizeof(*acx));
+ if (ret < 0) {
+ wl1271_warning("acx fm coex setting failed: %d", ret);
+ goto out;
+ }
+
+out:
+ kfree(acx);
+ return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index dd19b01d807..9a895e3cc61 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -303,7 +303,6 @@ struct acx_beacon_filter_option {
struct acx_header header;
u8 enable;
-
/*
* The number of beacons without the unicast TIM
* bit set that the firmware buffers before
@@ -370,14 +369,23 @@ struct acx_bt_wlan_coex {
u8 pad[3];
} __packed;
-struct acx_bt_wlan_coex_param {
+struct acx_sta_bt_wlan_coex_param {
struct acx_header header;
- __le32 params[CONF_SG_PARAMS_MAX];
+ __le32 params[CONF_SG_STA_PARAMS_MAX];
u8 param_idx;
u8 padding[3];
} __packed;
+struct acx_ap_bt_wlan_coex_param {
+ struct acx_header header;
+
+ __le32 params[CONF_SG_AP_PARAMS_MAX];
+ u8 param_idx;
+ u8 padding[3];
+} __packed;
+
+
struct acx_dco_itrim_params {
struct acx_header header;
@@ -939,6 +947,16 @@ struct wl1271_acx_keep_alive_config {
u8 padding;
} __packed;
+#define HOST_IF_CFG_RX_FIFO_ENABLE BIT(0)
+#define HOST_IF_CFG_TX_EXTRA_BLKS_SWAP BIT(1)
+#define HOST_IF_CFG_TX_PAD_TO_SDIO_BLK BIT(3)
+
+struct wl1271_acx_host_config_bitmap {
+ struct acx_header header;
+
+ __le32 host_cfg_bitmap;
+} __packed;
+
enum {
WL1271_ACX_TRIG_TYPE_LEVEL = 0,
WL1271_ACX_TRIG_TYPE_EDGE,
@@ -1162,6 +1180,72 @@ struct wl1271_acx_inconnection_sta {
u8 padding1[2];
} __packed;
+struct acx_ap_beacon_filter {
+ struct acx_header header;
+
+ u8 enable;
+ u8 pad[3];
+} __packed;
+
+/*
+ * ACX_FM_COEX_CFG
+ * set the FM co-existence parameters.
+ */
+struct wl1271_acx_fm_coex {
+ struct acx_header header;
+ /* enable(1) / disable(0) the FM Coex feature */
+ u8 enable;
+ /*
+ * Swallow period used in COEX PLL swallowing mechanism.
+ * 0xFF = use FW default
+ */
+ u8 swallow_period;
+ /*
+ * The N divider used in COEX PLL swallowing mechanism for Fref of
+ * 38.4/19.2 Mhz. 0xFF = use FW default
+ */
+ u8 n_divider_fref_set_1;
+ /*
+ * The N divider used in COEX PLL swallowing mechanism for Fref of
+ * 26/52 Mhz. 0xFF = use FW default
+ */
+ u8 n_divider_fref_set_2;
+ /*
+ * The M divider used in COEX PLL swallowing mechanism for Fref of
+ * 38.4/19.2 Mhz. 0xFFFF = use FW default
+ */
+ __le16 m_divider_fref_set_1;
+ /*
+ * The M divider used in COEX PLL swallowing mechanism for Fref of
+ * 26/52 Mhz. 0xFFFF = use FW default
+ */
+ __le16 m_divider_fref_set_2;
+ /*
+ * The time duration in uSec required for COEX PLL to stabilize.
+ * 0xFFFFFFFF = use FW default
+ */
+ __le32 coex_pll_stabilization_time;
+ /*
+ * The time duration in uSec required for LDO to stabilize.
+ * 0xFFFFFFFF = use FW default
+ */
+ __le16 ldo_stabilization_time;
+ /*
+ * The disturbed frequency band margin around the disturbed frequency
+ * center (single sided).
+ * For example, if 2 is configured, the following channels will be
+ * considered disturbed channel:
+ * 80 +- 0.1 MHz, 91 +- 0.1 MHz, 98 +- 0.1 MHz, 102 +- 0.1 MH
+ * 0xFF = use FW default
+ */
+ u8 fm_disturbed_band_margin;
+ /*
+ * The swallow clock difference of the swallowing mechanism.
+ * 0xFF = use FW default
+ */
+ u8 swallow_clk_diff;
+} __packed;
+
enum {
ACX_WAKE_UP_CONDITIONS = 0x0002,
ACX_MEM_CFG = 0x0003,
@@ -1180,6 +1264,7 @@ enum {
ACX_TID_CFG = 0x001A,
ACX_PS_RX_STREAMING = 0x001B,
ACX_BEACON_FILTER_OPT = 0x001F,
+ ACX_AP_BEACON_FILTER_OPT = 0x0020,
ACX_NOISE_HIST = 0x0021,
ACX_HDK_VERSION = 0x0022, /* ??? */
ACX_PD_THRESHOLD = 0x0023,
@@ -1191,6 +1276,7 @@ enum {
ACX_BCN_DTIM_OPTIONS = 0x0031,
ACX_SG_ENABLE = 0x0032,
ACX_SG_CFG = 0x0033,
+ ACX_FM_COEX_CFG = 0x0034,
ACX_BEACON_FILTER_TABLE = 0x0038,
ACX_ARP_IP_FILTER = 0x0039,
ACX_ROAMING_STATISTICS_TBL = 0x003B,
@@ -1247,13 +1333,14 @@ int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time);
int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable,
void *mc_list, u32 mc_list_len);
int wl1271_acx_service_period_timeout(struct wl1271 *wl);
-int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold);
+int wl1271_acx_rts_threshold(struct wl1271 *wl, u32 rts_threshold);
int wl1271_acx_dco_itrim_params(struct wl1271 *wl);
int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter);
int wl1271_acx_beacon_filter_table(struct wl1271 *wl);
int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable);
int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable);
-int wl1271_acx_sg_cfg(struct wl1271 *wl);
+int wl1271_acx_sta_sg_cfg(struct wl1271 *wl);
+int wl1271_acx_ap_sg_cfg(struct wl1271 *wl);
int wl1271_acx_cca_threshold(struct wl1271 *wl);
int wl1271_acx_bcn_dtim_options(struct wl1271 *wl);
int wl1271_acx_aid(struct wl1271 *wl, u16 aid);
@@ -1270,11 +1357,12 @@ int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max,
int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
u8 tsid, u8 ps_scheme, u8 ack_policy,
u32 apsd_conf0, u32 apsd_conf1);
-int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold);
+int wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold);
int wl1271_acx_tx_config_options(struct wl1271 *wl);
int wl1271_acx_ap_mem_cfg(struct wl1271 *wl);
int wl1271_acx_sta_mem_cfg(struct wl1271 *wl);
int wl1271_acx_init_mem_config(struct wl1271 *wl);
+int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap);
int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
int wl1271_acx_smart_reflex(struct wl1271 *wl);
int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable);
@@ -1299,5 +1387,7 @@ int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
int wl1271_acx_max_tx_retry(struct wl1271 *wl);
int wl1271_acx_config_ps(struct wl1271 *wl);
int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
+int wl1271_acx_set_ap_beacon_filter(struct wl1271 *wl, bool enable);
+int wl1271_acx_fm_coex(struct wl1271 *wl);
#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
index 6934dffd517..b07f8b7e5f1 100644
--- a/drivers/net/wireless/wl12xx/boot.c
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -22,6 +22,7 @@
*/
#include <linux/slab.h>
+#include <linux/wl12xx.h>
#include "acx.h"
#include "reg.h"
@@ -243,33 +244,57 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
if (wl->nvs == NULL)
return -ENODEV;
- /*
- * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band
- * configurations) can be removed when those NVS files stop floating
- * around.
- */
- if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
- wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
- /* for now 11a is unsupported in AP mode */
- if (wl->bss_type != BSS_TYPE_AP_BSS &&
- wl->nvs->general_params.dual_mode_select)
- wl->enable_11a = true;
- }
+ if (wl->chip.id == CHIP_ID_1283_PG20) {
+ struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
+
+ if (wl->nvs_len == sizeof(struct wl128x_nvs_file)) {
+ if (nvs->general_params.dual_mode_select)
+ wl->enable_11a = true;
+ } else {
+ wl1271_error("nvs size is not as expected: %zu != %zu",
+ wl->nvs_len,
+ sizeof(struct wl128x_nvs_file));
+ kfree(wl->nvs);
+ wl->nvs = NULL;
+ wl->nvs_len = 0;
+ return -EILSEQ;
+ }
- if (wl->nvs_len != sizeof(struct wl1271_nvs_file) &&
- (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
- wl->enable_11a)) {
- wl1271_error("nvs size is not as expected: %zu != %zu",
- wl->nvs_len, sizeof(struct wl1271_nvs_file));
- kfree(wl->nvs);
- wl->nvs = NULL;
- wl->nvs_len = 0;
- return -EILSEQ;
- }
+ /* only the first part of the NVS needs to be uploaded */
+ nvs_len = sizeof(nvs->nvs);
+ nvs_ptr = (u8 *)nvs->nvs;
+
+ } else {
+ struct wl1271_nvs_file *nvs =
+ (struct wl1271_nvs_file *)wl->nvs;
+ /*
+ * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz
+ * band configurations) can be removed when those NVS files stop
+ * floating around.
+ */
+ if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
+ wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
+ /* for now 11a is unsupported in AP mode */
+ if (wl->bss_type != BSS_TYPE_AP_BSS &&
+ nvs->general_params.dual_mode_select)
+ wl->enable_11a = true;
+ }
- /* only the first part of the NVS needs to be uploaded */
- nvs_len = sizeof(wl->nvs->nvs);
- nvs_ptr = (u8 *)wl->nvs->nvs;
+ if (wl->nvs_len != sizeof(struct wl1271_nvs_file) &&
+ (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
+ wl->enable_11a)) {
+ wl1271_error("nvs size is not as expected: %zu != %zu",
+ wl->nvs_len, sizeof(struct wl1271_nvs_file));
+ kfree(wl->nvs);
+ wl->nvs = NULL;
+ wl->nvs_len = 0;
+ return -EILSEQ;
+ }
+
+ /* only the first part of the NVS needs to be uploaded */
+ nvs_len = sizeof(nvs->nvs);
+ nvs_ptr = (u8 *) nvs->nvs;
+ }
/* update current MAC address to NVS */
nvs_ptr[11] = wl->mac_addr[0];
@@ -319,10 +344,13 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
/*
* We've reached the first zero length, the first NVS table
* is located at an aligned offset which is at least 7 bytes further.
+ * NOTE: The wl->nvs->nvs element must be first, in order to
+ * simplify the casting, we assume it is at the beginning of
+ * the wl->nvs structure.
*/
- nvs_ptr = (u8 *)wl->nvs->nvs +
- ALIGN(nvs_ptr - (u8 *)wl->nvs->nvs + 7, 4);
- nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs;
+ nvs_ptr = (u8 *)wl->nvs +
+ ALIGN(nvs_ptr - (u8 *)wl->nvs + 7, 4);
+ nvs_len -= nvs_ptr - (u8 *)wl->nvs;
/* Now we must set the partition correctly */
wl1271_set_partition(wl, &part_table[PART_WORK]);
@@ -450,10 +478,14 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
DISCONNECT_EVENT_COMPLETE_ID |
RSSI_SNR_TRIGGER_0_EVENT_ID |
PSPOLL_DELIVERY_FAILURE_EVENT_ID |
- SOFT_GEMINI_SENSE_EVENT_ID;
+ SOFT_GEMINI_SENSE_EVENT_ID |
+ PERIODIC_SCAN_REPORT_EVENT_ID |
+ PERIODIC_SCAN_COMPLETE_EVENT_ID;
if (wl->bss_type == BSS_TYPE_AP_BSS)
wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID;
+ else
+ wl->event_mask |= DUMMY_PACKET_EVENT_ID;
ret = wl1271_event_unmask(wl);
if (ret < 0) {
@@ -493,24 +525,159 @@ static void wl1271_boot_hw_version(struct wl1271 *wl)
wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION;
}
-/* uploads NVS and firmware */
-int wl1271_load_firmware(struct wl1271 *wl)
+static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
{
- int ret = 0;
- u32 tmp, clk, pause;
+ u16 spare_reg;
+
+ /* Mask bits [2] & [8:4] in the sys_clk_cfg register */
+ spare_reg = wl1271_top_reg_read(wl, WL_SPARE_REG);
+ if (spare_reg == 0xFFFF)
+ return -EFAULT;
+ spare_reg |= (BIT(3) | BIT(5) | BIT(6));
+ wl1271_top_reg_write(wl, WL_SPARE_REG, spare_reg);
+
+ /* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */
+ wl1271_top_reg_write(wl, SYS_CLK_CFG_REG,
+ WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);
+
+ /* Delay execution for 15msec, to let the HW settle */
+ mdelay(15);
+
+ return 0;
+}
+
+static bool wl128x_is_tcxo_valid(struct wl1271 *wl)
+{
+ u16 tcxo_detection;
+
+ tcxo_detection = wl1271_top_reg_read(wl, TCXO_CLK_DETECT_REG);
+ if (tcxo_detection & TCXO_DET_FAILED)
+ return false;
+
+ return true;
+}
+
+static bool wl128x_is_fref_valid(struct wl1271 *wl)
+{
+ u16 fref_detection;
+
+ fref_detection = wl1271_top_reg_read(wl, FREF_CLK_DETECT_REG);
+ if (fref_detection & FREF_CLK_DETECT_FAIL)
+ return false;
+
+ return true;
+}
+
+static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl)
+{
+ wl1271_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
+ wl1271_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
+ wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, MCS_PLL_CONFIG_REG_VAL);
+
+ return 0;
+}
+
+static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
+{
+ u16 spare_reg;
+ u16 pll_config;
+ u8 input_freq;
+
+ /* Mask bits [3:1] in the sys_clk_cfg register */
+ spare_reg = wl1271_top_reg_read(wl, WL_SPARE_REG);
+ if (spare_reg == 0xFFFF)
+ return -EFAULT;
+ spare_reg |= BIT(2);
+ wl1271_top_reg_write(wl, WL_SPARE_REG, spare_reg);
+
+ /* Handle special cases of the TCXO clock */
+ if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_8 ||
+ wl->tcxo_clock == WL12XX_TCXOCLOCK_33_6)
+ return wl128x_manually_configure_mcs_pll(wl);
+
+ /* Set the input frequency according to the selected clock source */
+ input_freq = (clk & 1) + 1;
+
+ pll_config = wl1271_top_reg_read(wl, MCS_PLL_CONFIG_REG);
+ if (pll_config == 0xFFFF)
+ return -EFAULT;
+ pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT);
+ pll_config |= MCS_PLL_ENABLE_HP;
+ wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config);
+
+ return 0;
+}
+
+/*
+ * WL128x has two clocks input - TCXO and FREF.
+ * TCXO is the main clock of the device, while FREF is used to sync
+ * between the GPS and the cellular modem.
+ * In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used
+ * as the WLAN/BT main clock.
+ */
+static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
+{
+ u16 sys_clk_cfg;
+
+ /* For XTAL-only modes, FREF will be used after switching from TCXO */
+ if (wl->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
+ wl->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
+ if (!wl128x_switch_tcxo_to_fref(wl))
+ return -EINVAL;
+ goto fref_clk;
+ }
+
+ /* Query the HW, to determine which clock source we should use */
+ sys_clk_cfg = wl1271_top_reg_read(wl, SYS_CLK_CFG_REG);
+ if (sys_clk_cfg == 0xFFFF)
+ return -EINVAL;
+ if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF)
+ goto fref_clk;
+
+ /* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */
+ if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_368 ||
+ wl->tcxo_clock == WL12XX_TCXOCLOCK_32_736) {
+ if (!wl128x_switch_tcxo_to_fref(wl))
+ return -EINVAL;
+ goto fref_clk;
+ }
+
+ /* TCXO clock is selected */
+ if (!wl128x_is_tcxo_valid(wl))
+ return -EINVAL;
+ *selected_clock = wl->tcxo_clock;
+ goto config_mcs_pll;
+
+fref_clk:
+ /* FREF clock is selected */
+ if (!wl128x_is_fref_valid(wl))
+ return -EINVAL;
+ *selected_clock = wl->ref_clock;
+
+config_mcs_pll:
+ return wl128x_configure_mcs_pll(wl, *selected_clock);
+}
+
+static int wl127x_boot_clk(struct wl1271 *wl)
+{
+ u32 pause;
+ u32 clk;
wl1271_boot_hw_version(wl);
- if (wl->ref_clock == 0 || wl->ref_clock == 2 || wl->ref_clock == 4)
+ if (wl->ref_clock == CONF_REF_CLK_19_2_E ||
+ wl->ref_clock == CONF_REF_CLK_38_4_E ||
+ wl->ref_clock == CONF_REF_CLK_38_4_M_XTAL)
/* ref clk: 19.2/38.4/38.4-XTAL */
clk = 0x3;
- else if (wl->ref_clock == 1 || wl->ref_clock == 3)
+ else if (wl->ref_clock == CONF_REF_CLK_26_E ||
+ wl->ref_clock == CONF_REF_CLK_52_E)
/* ref clk: 26/52 */
clk = 0x5;
else
return -EINVAL;
- if (wl->ref_clock != 0) {
+ if (wl->ref_clock != CONF_REF_CLK_19_2_E) {
u16 val;
/* Set clock type (open drain) */
val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
@@ -540,6 +707,26 @@ int wl1271_load_firmware(struct wl1271 *wl)
pause |= WU_COUNTER_PAUSE_VAL;
wl1271_write32(wl, WU_COUNTER_PAUSE, pause);
+ return 0;
+}
+
+/* uploads NVS and firmware */
+int wl1271_load_firmware(struct wl1271 *wl)
+{
+ int ret = 0;
+ u32 tmp, clk;
+ int selected_clock = -1;
+
+ if (wl->chip.id == CHIP_ID_1283_PG20) {
+ ret = wl128x_boot_clk(wl, &selected_clock);
+ if (ret < 0)
+ goto out;
+ } else {
+ ret = wl127x_boot_clk(wl);
+ if (ret < 0)
+ goto out;
+ }
+
/* Continue the ELP wake up sequence */
wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
udelay(500);
@@ -555,7 +742,12 @@ int wl1271_load_firmware(struct wl1271 *wl)
wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
- clk |= (wl->ref_clock << 1) << 4;
+ if (wl->chip.id == CHIP_ID_1283_PG20) {
+ clk |= ((selected_clock & 0x3) << 1) << 4;
+ } else {
+ clk |= (wl->ref_clock << 1) << 4;
+ }
+
wl1271_write32(wl, DRPW_SCRATCH_START, clk);
wl1271_set_partition(wl, &part_table[PART_WORK]);
@@ -585,16 +777,12 @@ int wl1271_load_firmware(struct wl1271 *wl)
/* 6. read the EEPROM parameters */
tmp = wl1271_read32(wl, SCR_PAD2);
- ret = wl1271_boot_write_irq_polarity(wl);
- if (ret < 0)
- goto out;
-
- wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
- WL1271_ACX_ALL_EVENTS_VECTOR);
-
/* WL1271: The reference driver skips steps 7 to 10 (jumps directly
* to upload_fw) */
+ if (wl->chip.id == CHIP_ID_1283_PG20)
+ wl1271_top_reg_write(wl, SDIO_IO_DS, wl->conf.hci_io_ds);
+
ret = wl1271_boot_upload_firmware(wl);
if (ret < 0)
goto out;
@@ -618,6 +806,13 @@ int wl1271_boot(struct wl1271 *wl)
if (ret < 0)
goto out;
+ ret = wl1271_boot_write_irq_polarity(wl);
+ if (ret < 0)
+ goto out;
+
+ wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
+ WL1271_ACX_ALL_EVENTS_VECTOR);
+
/* Enable firmware interrupts now */
wl1271_boot_enable_interrupts(wl);
diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h
index 17229b86fc7..e8f8255bbab 100644
--- a/drivers/net/wireless/wl12xx/boot.h
+++ b/drivers/net/wireless/wl12xx/boot.h
@@ -74,4 +74,56 @@ struct wl1271_static_data {
#define FREF_CLK_POLARITY_BITS 0xfffff8ff
#define CLK_REQ_OUTN_SEL 0x700
+/* PLL configuration algorithm for wl128x */
+#define SYS_CLK_CFG_REG 0x2200
+/* Bit[0] - 0-TCXO, 1-FREF */
+#define MCS_PLL_CLK_SEL_FREF BIT(0)
+/* Bit[3:2] - 01-TCXO, 10-FREF */
+#define WL_CLK_REQ_TYPE_FREF BIT(3)
+#define WL_CLK_REQ_TYPE_PG2 (BIT(3) | BIT(2))
+/* Bit[4] - 0-TCXO, 1-FREF */
+#define PRCM_CM_EN_MUX_WLAN_FREF BIT(4)
+
+#define TCXO_ILOAD_INT_REG 0x2264
+#define TCXO_CLK_DETECT_REG 0x2266
+
+#define TCXO_DET_FAILED BIT(4)
+
+#define FREF_ILOAD_INT_REG 0x2084
+#define FREF_CLK_DETECT_REG 0x2086
+#define FREF_CLK_DETECT_FAIL BIT(4)
+
+/* Use this reg for masking during driver access */
+#define WL_SPARE_REG 0x2320
+#define WL_SPARE_VAL BIT(2)
+/* Bit[6:5:3] - mask wl write SYS_CLK_CFG[8:5:2:4] */
+#define WL_SPARE_MASK_8526 (BIT(6) | BIT(5) | BIT(3))
+
+#define PLL_LOCK_COUNTERS_REG 0xD8C
+#define PLL_LOCK_COUNTERS_COEX 0x0F
+#define PLL_LOCK_COUNTERS_MCS 0xF0
+#define MCS_PLL_OVERRIDE_REG 0xD90
+#define MCS_PLL_CONFIG_REG 0xD92
+#define MCS_SEL_IN_FREQ_MASK 0x0070
+#define MCS_SEL_IN_FREQ_SHIFT 4
+#define MCS_PLL_CONFIG_REG_VAL 0x73
+#define MCS_PLL_ENABLE_HP (BIT(0) | BIT(1))
+
+#define MCS_PLL_M_REG 0xD94
+#define MCS_PLL_N_REG 0xD96
+#define MCS_PLL_M_REG_VAL 0xC8
+#define MCS_PLL_N_REG_VAL 0x07
+
+#define SDIO_IO_DS 0xd14
+
+/* SDIO/wSPI DS configuration values */
+enum {
+ HCI_IO_DS_8MA = 0,
+ HCI_IO_DS_4MA = 1, /* default */
+ HCI_IO_DS_6MA = 2,
+ HCI_IO_DS_2MA = 3,
+};
+
+/* end PLL configuration algorithm for wl128x */
+
#endif
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 96324336f93..42935ac7266 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -76,7 +76,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
if (time_after(jiffies, timeout)) {
wl1271_error("command complete timeout");
ret = -ETIMEDOUT;
- goto out;
+ goto fail;
}
poll_count++;
@@ -96,21 +96,67 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
status = le16_to_cpu(cmd->status);
if (status != CMD_STATUS_SUCCESS) {
wl1271_error("command execute failure %d", status);
- ieee80211_queue_work(wl->hw, &wl->recovery_work);
ret = -EIO;
+ goto fail;
}
wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
WL1271_ACX_INTR_CMD_COMPLETE);
+ return 0;
-out:
+fail:
+ WARN_ON(1);
+ ieee80211_queue_work(wl->hw, &wl->recovery_work);
return ret;
}
int wl1271_cmd_general_parms(struct wl1271 *wl)
{
struct wl1271_general_parms_cmd *gen_parms;
- struct wl1271_ini_general_params *gp = &wl->nvs->general_params;
+ struct wl1271_ini_general_params *gp =
+ &((struct wl1271_nvs_file *)wl->nvs)->general_params;
+ bool answer = false;
+ int ret;
+
+ if (!wl->nvs)
+ return -ENODEV;
+
+ gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
+ if (!gen_parms)
+ return -ENOMEM;
+
+ gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
+
+ memcpy(&gen_parms->general_params, gp, sizeof(*gp));
+
+ if (gp->tx_bip_fem_auto_detect)
+ answer = true;
+
+ /* Override the REF CLK from the NVS with the one from platform data */
+ gen_parms->general_params.ref_clock = wl->ref_clock;
+
+ ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
+ if (ret < 0) {
+ wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
+ goto out;
+ }
+
+ gp->tx_bip_fem_manufacturer =
+ gen_parms->general_params.tx_bip_fem_manufacturer;
+
+ wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
+ answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
+
+out:
+ kfree(gen_parms);
+ return ret;
+}
+
+int wl128x_cmd_general_parms(struct wl1271 *wl)
+{
+ struct wl128x_general_parms_cmd *gen_parms;
+ struct wl128x_ini_general_params *gp =
+ &((struct wl128x_nvs_file *)wl->nvs)->general_params;
bool answer = false;
int ret;
@@ -128,6 +174,10 @@ int wl1271_cmd_general_parms(struct wl1271 *wl)
if (gp->tx_bip_fem_auto_detect)
answer = true;
+ /* Replace REF and TCXO CLKs with the ones from platform data */
+ gen_parms->general_params.ref_clock = wl->ref_clock;
+ gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock;
+
ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
if (ret < 0) {
wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
@@ -147,8 +197,9 @@ out:
int wl1271_cmd_radio_parms(struct wl1271 *wl)
{
+ struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs;
struct wl1271_radio_parms_cmd *radio_parms;
- struct wl1271_ini_general_params *gp = &wl->nvs->general_params;
+ struct wl1271_ini_general_params *gp = &nvs->general_params;
int ret;
if (!wl->nvs)
@@ -161,18 +212,18 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
/* 2.4GHz parameters */
- memcpy(&radio_parms->static_params_2, &wl->nvs->stat_radio_params_2,
+ memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
sizeof(struct wl1271_ini_band_params_2));
memcpy(&radio_parms->dyn_params_2,
- &wl->nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
+ &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
sizeof(struct wl1271_ini_fem_params_2));
/* 5GHz parameters */
memcpy(&radio_parms->static_params_5,
- &wl->nvs->stat_radio_params_5,
+ &nvs->stat_radio_params_5,
sizeof(struct wl1271_ini_band_params_5));
memcpy(&radio_parms->dyn_params_5,
- &wl->nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
+ &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
sizeof(struct wl1271_ini_fem_params_5));
wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
@@ -186,6 +237,50 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
return ret;
}
+int wl128x_cmd_radio_parms(struct wl1271 *wl)
+{
+ struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
+ struct wl128x_radio_parms_cmd *radio_parms;
+ struct wl128x_ini_general_params *gp = &nvs->general_params;
+ int ret;
+
+ if (!wl->nvs)
+ return -ENODEV;
+
+ radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
+ if (!radio_parms)
+ return -ENOMEM;
+
+ radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
+
+ /* 2.4GHz parameters */
+ memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
+ sizeof(struct wl128x_ini_band_params_2));
+ memcpy(&radio_parms->dyn_params_2,
+ &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
+ sizeof(struct wl128x_ini_fem_params_2));
+
+ /* 5GHz parameters */
+ memcpy(&radio_parms->static_params_5,
+ &nvs->stat_radio_params_5,
+ sizeof(struct wl128x_ini_band_params_5));
+ memcpy(&radio_parms->dyn_params_5,
+ &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
+ sizeof(struct wl128x_ini_fem_params_5));
+
+ radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options;
+
+ wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
+ radio_parms, sizeof(*radio_parms));
+
+ ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
+ if (ret < 0)
+ wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
+
+ kfree(radio_parms);
+ return ret;
+}
+
int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
{
struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
index 54c12e71417..5cac95d9480 100644
--- a/drivers/net/wireless/wl12xx/cmd.h
+++ b/drivers/net/wireless/wl12xx/cmd.h
@@ -32,7 +32,9 @@ struct acx_header;
int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
size_t res_len);
int wl1271_cmd_general_parms(struct wl1271 *wl);
+int wl128x_cmd_general_parms(struct wl1271 *wl);
int wl1271_cmd_radio_parms(struct wl1271 *wl);
+int wl128x_cmd_radio_parms(struct wl1271 *wl);
int wl1271_cmd_ext_radio_parms(struct wl1271 *wl);
int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type);
int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
@@ -415,6 +417,21 @@ struct wl1271_general_parms_cmd {
u8 padding[3];
} __packed;
+struct wl128x_general_parms_cmd {
+ struct wl1271_cmd_header header;
+
+ struct wl1271_cmd_test_header test;
+
+ struct wl128x_ini_general_params general_params;
+
+ u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
+ u8 sr_sen_n_p;
+ u8 sr_sen_n_p_gain;
+ u8 sr_sen_nrn;
+ u8 sr_sen_prn;
+ u8 padding[3];
+} __packed;
+
struct wl1271_radio_parms_cmd {
struct wl1271_cmd_header header;
@@ -431,6 +448,23 @@ struct wl1271_radio_parms_cmd {
u8 padding3[2];
} __packed;
+struct wl128x_radio_parms_cmd {
+ struct wl1271_cmd_header header;
+
+ struct wl1271_cmd_test_header test;
+
+ /* Static radio parameters */
+ struct wl128x_ini_band_params_2 static_params_2;
+ struct wl128x_ini_band_params_5 static_params_5;
+
+ u8 fem_vendor_and_options;
+
+ /* Dynamic radio parameters */
+ struct wl128x_ini_fem_params_2 dyn_params_2;
+ u8 padding2;
+ struct wl128x_ini_fem_params_5 dyn_params_5;
+} __packed;
+
struct wl1271_ext_radio_parms_cmd {
struct wl1271_cmd_header header;
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h
index 8a8323896ee..1ab6c86aac4 100644
--- a/drivers/net/wireless/wl12xx/conf.h
+++ b/drivers/net/wireless/wl12xx/conf.h
@@ -396,12 +396,43 @@ enum {
CONF_SG_TEMP_PARAM_3,
CONF_SG_TEMP_PARAM_4,
CONF_SG_TEMP_PARAM_5,
- CONF_SG_PARAMS_MAX,
+
+ /*
+ * AP beacon miss
+ *
+ * Range: 0 - 255
+ */
+ CONF_SG_AP_BEACON_MISS_TX,
+
+ /*
+ * AP RX window length
+ *
+ * Range: 0 - 50
+ */
+ CONF_SG_RX_WINDOW_LENGTH,
+
+ /*
+ * AP connection protection time
+ *
+ * Range: 0 - 5000
+ */
+ CONF_SG_AP_CONNECTION_PROTECTION_TIME,
+
+ CONF_SG_TEMP_PARAM_6,
+ CONF_SG_TEMP_PARAM_7,
+ CONF_SG_TEMP_PARAM_8,
+ CONF_SG_TEMP_PARAM_9,
+ CONF_SG_TEMP_PARAM_10,
+
+ CONF_SG_STA_PARAMS_MAX = CONF_SG_TEMP_PARAM_5 + 1,
+ CONF_SG_AP_PARAMS_MAX = CONF_SG_TEMP_PARAM_10 + 1,
+
CONF_SG_PARAMS_ALL = 0xff
};
struct conf_sg_settings {
- u32 params[CONF_SG_PARAMS_MAX];
+ u32 sta_params[CONF_SG_STA_PARAMS_MAX];
+ u32 ap_params[CONF_SG_AP_PARAMS_MAX];
u8 state;
};
@@ -509,6 +540,12 @@ struct conf_rx_settings {
CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS | \
CONF_HW_BIT_RATE_54MBPS)
+#define CONF_TX_OFDM_RATES (CONF_HW_BIT_RATE_6MBPS | \
+ CONF_HW_BIT_RATE_12MBPS | CONF_HW_BIT_RATE_24MBPS | \
+ CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS | \
+ CONF_HW_BIT_RATE_54MBPS)
+
+
/*
* Default rates for management traffic when operating in AP mode. This
* should be configured according to the basic rate set of the AP
@@ -516,6 +553,13 @@ struct conf_rx_settings {
#define CONF_TX_AP_DEFAULT_MGMT_RATES (CONF_HW_BIT_RATE_1MBPS | \
CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS)
+/*
+ * Default rates for working as IBSS. use 11b rates
+ */
+#define CONF_TX_IBSS_DEFAULT_RATES (CONF_HW_BIT_RATE_1MBPS | \
+ CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \
+ CONF_HW_BIT_RATE_11MBPS);
+
struct conf_tx_rate_class {
/*
@@ -667,22 +711,6 @@ struct conf_tx_settings {
struct conf_tx_ac_category ac_conf[CONF_TX_MAX_AC_COUNT];
/*
- * Configuration for rate classes in AP-mode. These rate classes
- * are for the AC TX queues
- */
- struct conf_tx_rate_class ap_rc_conf[CONF_TX_MAX_AC_COUNT];
-
- /*
- * Management TX rate class for AP-mode.
- */
- struct conf_tx_rate_class ap_mgmt_conf;
-
- /*
- * Broadcast TX rate class for AP-mode.
- */
- struct conf_tx_rate_class ap_bcst_conf;
-
- /*
* AP-mode - allow this number of TX retries to a station before an
* event is triggered from FW.
*/
@@ -1004,7 +1032,9 @@ enum {
CONF_REF_CLK_19_2_E,
CONF_REF_CLK_26_E,
CONF_REF_CLK_38_4_E,
- CONF_REF_CLK_52_E
+ CONF_REF_CLK_52_E,
+ CONF_REF_CLK_38_4_M_XTAL,
+ CONF_REF_CLK_26_M_XTAL,
};
enum single_dual_band_enum {
@@ -1018,15 +1048,6 @@ enum single_dual_band_enum {
#define CONF_NUMBER_OF_CHANNELS_2_4 14
#define CONF_NUMBER_OF_CHANNELS_5 35
-struct conf_radio_parms {
- /*
- * FEM parameter set to use
- *
- * Range: 0 or 1
- */
- u8 fem;
-};
-
struct conf_itrim_settings {
/* enable dco itrim */
u8 enable;
@@ -1126,6 +1147,26 @@ struct conf_scan_settings {
};
+struct conf_sched_scan_settings {
+ /* minimum time to wait on the channel for active scans (in TUs) */
+ u16 min_dwell_time_active;
+
+ /* maximum time to wait on the channel for active scans (in TUs) */
+ u16 max_dwell_time_active;
+
+ /* time to wait on the channel for passive scans (in TUs) */
+ u32 dwell_time_passive;
+
+ /* number of probe requests to send on each channel in active scans */
+ u8 num_probe_reqs;
+
+ /* RSSI threshold to be used for filtering */
+ s8 rssi_threshold;
+
+ /* SNR threshold to be used for filtering */
+ s8 snr_threshold;
+};
+
/* these are number of channels on the band divided by two, rounded up */
#define CONF_TX_PWR_COMPENSATION_LEN_2 7
#define CONF_TX_PWR_COMPENSATION_LEN_5 18
@@ -1191,6 +1232,19 @@ struct conf_memory_settings {
u8 tx_min;
};
+struct conf_fm_coex {
+ u8 enable;
+ u8 swallow_period;
+ u8 n_divider_fref_set_1;
+ u8 n_divider_fref_set_2;
+ u16 m_divider_fref_set_1;
+ u16 m_divider_fref_set_2;
+ u32 coex_pll_stabilization_time;
+ u16 ldo_stabilization_time;
+ u8 fm_disturbed_band_margin;
+ u8 swallow_clk_diff;
+};
+
struct conf_drv_settings {
struct conf_sg_settings sg;
struct conf_rx_settings rx;
@@ -1200,9 +1254,13 @@ struct conf_drv_settings {
struct conf_pm_config_settings pm_config;
struct conf_roam_trigger_settings roam_trigger;
struct conf_scan_settings scan;
+ struct conf_sched_scan_settings sched_scan;
struct conf_rf_settings rf;
struct conf_ht_setting ht;
- struct conf_memory_settings mem;
+ struct conf_memory_settings mem_wl127x;
+ struct conf_memory_settings mem_wl128x;
+ struct conf_fm_coex fm_coex;
+ u8 hci_io_ds;
};
#endif
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 8e75b09723b..f1f8df9b6cd 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -267,7 +267,7 @@ static ssize_t gpio_power_write(struct file *file,
}
buf[len] = '\0';
- ret = strict_strtoul(buf, 0, &value);
+ ret = kstrtoul(buf, 0, &value);
if (ret < 0) {
wl1271_warning("illegal value in gpio_power");
return -EINVAL;
@@ -291,6 +291,242 @@ static const struct file_operations gpio_power_ops = {
.llseek = default_llseek,
};
+static ssize_t start_recovery_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1271 *wl = file->private_data;
+
+ mutex_lock(&wl->mutex);
+ ieee80211_queue_work(wl->hw, &wl->recovery_work);
+ mutex_unlock(&wl->mutex);
+
+ return count;
+}
+
+static const struct file_operations start_recovery_ops = {
+ .write = start_recovery_write,
+ .open = wl1271_open_file_generic,
+ .llseek = default_llseek,
+};
+
+static ssize_t driver_state_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1271 *wl = file->private_data;
+ int res = 0;
+ char buf[1024];
+
+ mutex_lock(&wl->mutex);
+
+#define DRIVER_STATE_PRINT(x, fmt) \
+ (res += scnprintf(buf + res, sizeof(buf) - res,\
+ #x " = " fmt "\n", wl->x))
+
+#define DRIVER_STATE_PRINT_LONG(x) DRIVER_STATE_PRINT(x, "%ld")
+#define DRIVER_STATE_PRINT_INT(x) DRIVER_STATE_PRINT(x, "%d")
+#define DRIVER_STATE_PRINT_STR(x) DRIVER_STATE_PRINT(x, "%s")
+#define DRIVER_STATE_PRINT_LHEX(x) DRIVER_STATE_PRINT(x, "0x%lx")
+#define DRIVER_STATE_PRINT_HEX(x) DRIVER_STATE_PRINT(x, "0x%x")
+
+ DRIVER_STATE_PRINT_INT(tx_blocks_available);
+ DRIVER_STATE_PRINT_INT(tx_allocated_blocks);
+ DRIVER_STATE_PRINT_INT(tx_frames_cnt);
+ DRIVER_STATE_PRINT_LHEX(tx_frames_map[0]);
+ DRIVER_STATE_PRINT_INT(tx_queue_count);
+ DRIVER_STATE_PRINT_INT(tx_packets_count);
+ DRIVER_STATE_PRINT_INT(tx_results_count);
+ DRIVER_STATE_PRINT_LHEX(flags);
+ DRIVER_STATE_PRINT_INT(tx_blocks_freed[0]);
+ DRIVER_STATE_PRINT_INT(tx_blocks_freed[1]);
+ DRIVER_STATE_PRINT_INT(tx_blocks_freed[2]);
+ DRIVER_STATE_PRINT_INT(tx_blocks_freed[3]);
+ DRIVER_STATE_PRINT_INT(tx_security_last_seq);
+ DRIVER_STATE_PRINT_INT(rx_counter);
+ DRIVER_STATE_PRINT_INT(session_counter);
+ DRIVER_STATE_PRINT_INT(state);
+ DRIVER_STATE_PRINT_INT(bss_type);
+ DRIVER_STATE_PRINT_INT(channel);
+ DRIVER_STATE_PRINT_HEX(rate_set);
+ DRIVER_STATE_PRINT_HEX(basic_rate_set);
+ DRIVER_STATE_PRINT_HEX(basic_rate);
+ DRIVER_STATE_PRINT_INT(band);
+ DRIVER_STATE_PRINT_INT(beacon_int);
+ DRIVER_STATE_PRINT_INT(psm_entry_retry);
+ DRIVER_STATE_PRINT_INT(ps_poll_failures);
+ DRIVER_STATE_PRINT_HEX(filters);
+ DRIVER_STATE_PRINT_HEX(rx_config);
+ DRIVER_STATE_PRINT_HEX(rx_filter);
+ DRIVER_STATE_PRINT_INT(power_level);
+ DRIVER_STATE_PRINT_INT(rssi_thold);
+ DRIVER_STATE_PRINT_INT(last_rssi_event);
+ DRIVER_STATE_PRINT_INT(sg_enabled);
+ DRIVER_STATE_PRINT_INT(enable_11a);
+ DRIVER_STATE_PRINT_INT(noise);
+ DRIVER_STATE_PRINT_LHEX(ap_hlid_map[0]);
+ DRIVER_STATE_PRINT_INT(last_tx_hlid);
+ DRIVER_STATE_PRINT_INT(ba_support);
+ DRIVER_STATE_PRINT_HEX(ba_rx_bitmap);
+ DRIVER_STATE_PRINT_HEX(ap_fw_ps_map);
+ DRIVER_STATE_PRINT_LHEX(ap_ps_map);
+ DRIVER_STATE_PRINT_HEX(quirks);
+ DRIVER_STATE_PRINT_HEX(irq);
+ DRIVER_STATE_PRINT_HEX(ref_clock);
+ DRIVER_STATE_PRINT_HEX(tcxo_clock);
+ DRIVER_STATE_PRINT_HEX(hw_pg_ver);
+ DRIVER_STATE_PRINT_HEX(platform_quirks);
+ DRIVER_STATE_PRINT_HEX(chip.id);
+ DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
+ DRIVER_STATE_PRINT_INT(sched_scanning);
+
+#undef DRIVER_STATE_PRINT_INT
+#undef DRIVER_STATE_PRINT_LONG
+#undef DRIVER_STATE_PRINT_HEX
+#undef DRIVER_STATE_PRINT_LHEX
+#undef DRIVER_STATE_PRINT_STR
+#undef DRIVER_STATE_PRINT
+
+ mutex_unlock(&wl->mutex);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, res);
+}
+
+static const struct file_operations driver_state_ops = {
+ .read = driver_state_read,
+ .open = wl1271_open_file_generic,
+ .llseek = default_llseek,
+};
+
+static ssize_t dtim_interval_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1271 *wl = file->private_data;
+ u8 value;
+
+ if (wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_DTIM ||
+ wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_N_DTIM)
+ value = wl->conf.conn.listen_interval;
+ else
+ value = 0;
+
+ return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value);
+}
+
+static ssize_t dtim_interval_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1271 *wl = file->private_data;
+ char buf[10];
+ size_t len;
+ unsigned long value;
+ int ret;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+ buf[len] = '\0';
+
+ ret = kstrtoul(buf, 0, &value);
+ if (ret < 0) {
+ wl1271_warning("illegal value for dtim_interval");
+ return -EINVAL;
+ }
+
+ if (value < 1 || value > 10) {
+ wl1271_warning("dtim value is not in valid range");
+ return -ERANGE;
+ }
+
+ mutex_lock(&wl->mutex);
+
+ wl->conf.conn.listen_interval = value;
+ /* for some reason there are different event types for 1 and >1 */
+ if (value == 1)
+ wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_DTIM;
+ else
+ wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM;
+
+ /*
+ * we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only
+ * take effect on the next time we enter psm.
+ */
+ mutex_unlock(&wl->mutex);
+ return count;
+}
+
+static const struct file_operations dtim_interval_ops = {
+ .read = dtim_interval_read,
+ .write = dtim_interval_write,
+ .open = wl1271_open_file_generic,
+ .llseek = default_llseek,
+};
+
+static ssize_t beacon_interval_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1271 *wl = file->private_data;
+ u8 value;
+
+ if (wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_BEACON ||
+ wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_N_BEACONS)
+ value = wl->conf.conn.listen_interval;
+ else
+ value = 0;
+
+ return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value);
+}
+
+static ssize_t beacon_interval_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1271 *wl = file->private_data;
+ char buf[10];
+ size_t len;
+ unsigned long value;
+ int ret;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+ buf[len] = '\0';
+
+ ret = kstrtoul(buf, 0, &value);
+ if (ret < 0) {
+ wl1271_warning("illegal value for beacon_interval");
+ return -EINVAL;
+ }
+
+ if (value < 1 || value > 255) {
+ wl1271_warning("beacon interval value is not in valid range");
+ return -ERANGE;
+ }
+
+ mutex_lock(&wl->mutex);
+
+ wl->conf.conn.listen_interval = value;
+ /* for some reason there are different event types for 1 and >1 */
+ if (value == 1)
+ wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_BEACON;
+ else
+ wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_N_BEACONS;
+
+ /*
+ * we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only
+ * take effect on the next time we enter psm.
+ */
+ mutex_unlock(&wl->mutex);
+ return count;
+}
+
+static const struct file_operations beacon_interval_ops = {
+ .read = beacon_interval_read,
+ .write = beacon_interval_write,
+ .open = wl1271_open_file_generic,
+ .llseek = default_llseek,
+};
+
static int wl1271_debugfs_add_files(struct wl1271 *wl,
struct dentry *rootdir)
{
@@ -399,6 +635,10 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl,
DEBUGFS_ADD(excessive_retries, rootdir);
DEBUGFS_ADD(gpio_power, rootdir);
+ DEBUGFS_ADD(start_recovery, rootdir);
+ DEBUGFS_ADD(driver_state, rootdir);
+ DEBUGFS_ADD(dtim_interval, rootdir);
+ DEBUGFS_ADD(beacon_interval, rootdir);
return 0;
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c
index 1b170c5cc59..c3c554cd658 100644
--- a/drivers/net/wireless/wl12xx/event.c
+++ b/drivers/net/wireless/wl12xx/event.c
@@ -33,6 +33,7 @@ void wl1271_pspoll_work(struct work_struct *work)
{
struct delayed_work *dwork;
struct wl1271 *wl;
+ int ret;
dwork = container_of(work, struct delayed_work, work);
wl = container_of(dwork, struct wl1271, pspoll_work);
@@ -55,8 +56,13 @@ void wl1271_pspoll_work(struct work_struct *work)
* delivery failure occurred, and no-one changed state since, so
* we should go back to powersave.
*/
+ ret = wl1271_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out;
+
wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, wl->basic_rate, true);
+ wl1271_ps_elp_sleep(wl);
out:
mutex_unlock(&wl->mutex);
};
@@ -132,8 +138,10 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
if (ret < 0)
break;
- /* go to extremely low power mode */
- wl1271_ps_elp_sleep(wl);
+ if (wl->ps_compl) {
+ complete(wl->ps_compl);
+ wl->ps_compl = NULL;
+ }
break;
default:
break;
@@ -187,6 +195,22 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
wl1271_scan_stm(wl);
}
+ if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) {
+ wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_REPORT_EVENT "
+ "(status 0x%0x)", mbox->scheduled_scan_status);
+
+ wl1271_scan_sched_scan_results(wl);
+ }
+
+ if (vector & PERIODIC_SCAN_COMPLETE_EVENT_ID) {
+ wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_COMPLETE_EVENT "
+ "(status 0x%0x)", mbox->scheduled_scan_status);
+ if (wl->sched_scanning) {
+ wl1271_scan_sched_scan_stop(wl);
+ ieee80211_sched_scan_stopped(wl->hw);
+ }
+ }
+
/* disable dynamic PS when requested by the firmware */
if (vector & SOFT_GEMINI_SENSE_EVENT_ID &&
wl->bss_type == BSS_TYPE_STA_BSS) {
@@ -228,6 +252,12 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
wl1271_event_rssi_trigger(wl, mbox);
}
+ if ((vector & DUMMY_PACKET_EVENT_ID) && !is_ap) {
+ wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID");
+ if (wl->vif)
+ wl1271_tx_dummy_packet(wl);
+ }
+
if (wl->vif && beacon_loss)
ieee80211_connection_loss(wl->vif);
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h
index 0e80886f303..b6cf06e565a 100644
--- a/drivers/net/wireless/wl12xx/event.h
+++ b/drivers/net/wireless/wl12xx/event.h
@@ -59,7 +59,10 @@ enum {
BSS_LOSE_EVENT_ID = BIT(18),
REGAINED_BSS_EVENT_ID = BIT(19),
ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(20),
- STA_REMOVE_COMPLETE_EVENT_ID = BIT(21), /* AP */
+ /* STA: dummy paket for dynamic mem blocks */
+ DUMMY_PACKET_EVENT_ID = BIT(21),
+ /* AP: STA remove complete */
+ STA_REMOVE_COMPLETE_EVENT_ID = BIT(21),
SOFT_GEMINI_SENSE_EVENT_ID = BIT(22),
SOFT_GEMINI_PREDICTION_EVENT_ID = BIT(23),
SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24),
diff --git a/drivers/net/wireless/wl12xx/ini.h b/drivers/net/wireless/wl12xx/ini.h
index c330a2583df..1420c842b8f 100644
--- a/drivers/net/wireless/wl12xx/ini.h
+++ b/drivers/net/wireless/wl12xx/ini.h
@@ -41,6 +41,28 @@ struct wl1271_ini_general_params {
u8 srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM];
} __packed;
+#define WL128X_INI_MAX_SETTINGS_PARAM 4
+
+struct wl128x_ini_general_params {
+ u8 ref_clock;
+ u8 settling_time;
+ u8 clk_valid_on_wakeup;
+ u8 tcxo_ref_clock;
+ u8 tcxo_settling_time;
+ u8 tcxo_valid_on_wakeup;
+ u8 tcxo_ldo_voltage;
+ u8 xtal_itrim_val;
+ u8 platform_conf;
+ u8 dual_mode_select;
+ u8 tx_bip_fem_auto_detect;
+ u8 tx_bip_fem_manufacturer;
+ u8 general_settings[WL128X_INI_MAX_SETTINGS_PARAM];
+ u8 sr_state;
+ u8 srf1[WL1271_INI_MAX_SMART_REFLEX_PARAM];
+ u8 srf2[WL1271_INI_MAX_SMART_REFLEX_PARAM];
+ u8 srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM];
+} __packed;
+
#define WL1271_INI_RSSI_PROCESS_COMPENS_SIZE 15
struct wl1271_ini_band_params_2 {
@@ -49,9 +71,16 @@ struct wl1271_ini_band_params_2 {
u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
} __packed;
-#define WL1271_INI_RATE_GROUP_COUNT 6
#define WL1271_INI_CHANNEL_COUNT_2 14
+struct wl128x_ini_band_params_2 {
+ u8 rx_trace_insertion_loss;
+ u8 tx_trace_loss[WL1271_INI_CHANNEL_COUNT_2];
+ u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
+} __packed;
+
+#define WL1271_INI_RATE_GROUP_COUNT 6
+
struct wl1271_ini_fem_params_2 {
__le16 tx_bip_ref_pd_voltage;
u8 tx_bip_ref_power;
@@ -68,6 +97,28 @@ struct wl1271_ini_fem_params_2 {
u8 normal_to_degraded_high_thr;
} __packed;
+#define WL128X_INI_RATE_GROUP_COUNT 7
+/* low and high temperatures */
+#define WL128X_INI_PD_VS_TEMPERATURE_RANGES 2
+
+struct wl128x_ini_fem_params_2 {
+ __le16 tx_bip_ref_pd_voltage;
+ u8 tx_bip_ref_power;
+ u8 tx_bip_ref_offset;
+ u8 tx_per_rate_pwr_limits_normal[WL128X_INI_RATE_GROUP_COUNT];
+ u8 tx_per_rate_pwr_limits_degraded[WL128X_INI_RATE_GROUP_COUNT];
+ u8 tx_per_rate_pwr_limits_extreme[WL128X_INI_RATE_GROUP_COUNT];
+ u8 tx_per_chan_pwr_limits_11b[WL1271_INI_CHANNEL_COUNT_2];
+ u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_2];
+ u8 tx_pd_vs_rate_offsets[WL128X_INI_RATE_GROUP_COUNT];
+ u8 tx_ibias[WL128X_INI_RATE_GROUP_COUNT + 1];
+ u8 tx_pd_vs_chan_offsets[WL1271_INI_CHANNEL_COUNT_2];
+ u8 tx_pd_vs_temperature[WL128X_INI_PD_VS_TEMPERATURE_RANGES];
+ u8 rx_fem_insertion_loss;
+ u8 degraded_low_to_normal_thr;
+ u8 normal_to_degraded_high_thr;
+} __packed;
+
#define WL1271_INI_CHANNEL_COUNT_5 35
#define WL1271_INI_SUB_BAND_COUNT_5 7
@@ -77,6 +128,12 @@ struct wl1271_ini_band_params_5 {
u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
} __packed;
+struct wl128x_ini_band_params_5 {
+ u8 rx_trace_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5];
+ u8 tx_trace_loss[WL1271_INI_CHANNEL_COUNT_5];
+ u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
+} __packed;
+
struct wl1271_ini_fem_params_5 {
__le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5];
u8 tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5];
@@ -92,6 +149,23 @@ struct wl1271_ini_fem_params_5 {
u8 normal_to_degraded_high_thr;
} __packed;
+struct wl128x_ini_fem_params_5 {
+ __le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5];
+ u8 tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5];
+ u8 tx_bip_ref_offset[WL1271_INI_SUB_BAND_COUNT_5];
+ u8 tx_per_rate_pwr_limits_normal[WL128X_INI_RATE_GROUP_COUNT];
+ u8 tx_per_rate_pwr_limits_degraded[WL128X_INI_RATE_GROUP_COUNT];
+ u8 tx_per_rate_pwr_limits_extreme[WL128X_INI_RATE_GROUP_COUNT];
+ u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_5];
+ u8 tx_pd_vs_rate_offsets[WL128X_INI_RATE_GROUP_COUNT];
+ u8 tx_ibias[WL128X_INI_RATE_GROUP_COUNT];
+ u8 tx_pd_vs_chan_offsets[WL1271_INI_CHANNEL_COUNT_5];
+ u8 tx_pd_vs_temperature[WL1271_INI_SUB_BAND_COUNT_5 *
+ WL128X_INI_PD_VS_TEMPERATURE_RANGES];
+ u8 rx_fem_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5];
+ u8 degraded_low_to_normal_thr;
+ u8 normal_to_degraded_high_thr;
+} __packed;
/* NVS data structure */
#define WL1271_INI_NVS_SECTION_SIZE 468
@@ -100,7 +174,7 @@ struct wl1271_ini_fem_params_5 {
#define WL1271_INI_LEGACY_NVS_FILE_SIZE 800
struct wl1271_nvs_file {
- /* NVS section */
+ /* NVS section - must be first! */
u8 nvs[WL1271_INI_NVS_SECTION_SIZE];
/* INI section */
@@ -120,4 +194,24 @@ struct wl1271_nvs_file {
} dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT];
} __packed;
+struct wl128x_nvs_file {
+ /* NVS section - must be first! */
+ u8 nvs[WL1271_INI_NVS_SECTION_SIZE];
+
+ /* INI section */
+ struct wl128x_ini_general_params general_params;
+ u8 fem_vendor_and_options;
+ struct wl128x_ini_band_params_2 stat_radio_params_2;
+ u8 padding2;
+ struct {
+ struct wl128x_ini_fem_params_2 params;
+ u8 padding;
+ } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT];
+ struct wl128x_ini_band_params_5 stat_radio_params_5;
+ u8 padding3;
+ struct {
+ struct wl128x_ini_fem_params_5 params;
+ u8 padding;
+ } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT];
+} __packed;
#endif
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
index 6072fe45713..a8f4f156c05 100644
--- a/drivers/net/wireless/wl12xx/init.c
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -31,6 +31,7 @@
#include "cmd.h"
#include "reg.h"
#include "tx.h"
+#include "io.h"
int wl1271_sta_init_templates_config(struct wl1271 *wl)
{
@@ -257,7 +258,7 @@ int wl1271_init_phy_config(struct wl1271 *wl)
if (ret < 0)
return ret;
- ret = wl1271_acx_rts_threshold(wl, wl->conf.rx.rts_threshold);
+ ret = wl1271_acx_rts_threshold(wl, wl->hw->wiphy->rts_threshold);
if (ret < 0)
return ret;
@@ -284,7 +285,10 @@ int wl1271_init_pta(struct wl1271 *wl)
{
int ret;
- ret = wl1271_acx_sg_cfg(wl);
+ if (wl->bss_type == BSS_TYPE_AP_BSS)
+ ret = wl1271_acx_ap_sg_cfg(wl);
+ else
+ ret = wl1271_acx_sta_sg_cfg(wl);
if (ret < 0)
return ret;
@@ -321,9 +325,11 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
{
int ret;
- ret = wl1271_cmd_ext_radio_parms(wl);
- if (ret < 0)
- return ret;
+ if (wl->chip.id != CHIP_ID_1283_PG20) {
+ ret = wl1271_cmd_ext_radio_parms(wl);
+ if (ret < 0)
+ return ret;
+ }
/* PS config */
ret = wl1271_acx_config_ps(wl);
@@ -348,8 +354,8 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
if (ret < 0)
return ret;
- /* Bluetooth WLAN coexistence */
- ret = wl1271_init_pta(wl);
+ /* FM WLAN coexistence */
+ ret = wl1271_acx_fm_coex(wl);
if (ret < 0)
return ret;
@@ -407,7 +413,7 @@ static int wl1271_sta_hw_init_post_mem(struct wl1271 *wl)
static int wl1271_ap_hw_init(struct wl1271 *wl)
{
- int ret, i;
+ int ret;
ret = wl1271_ap_init_templates_config(wl);
if (ret < 0)
@@ -418,23 +424,7 @@ static int wl1271_ap_hw_init(struct wl1271 *wl)
if (ret < 0)
return ret;
- /* Configure initial TX rate classes */
- for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
- ret = wl1271_acx_ap_rate_policy(wl,
- &wl->conf.tx.ap_rc_conf[i], i);
- if (ret < 0)
- return ret;
- }
-
- ret = wl1271_acx_ap_rate_policy(wl,
- &wl->conf.tx.ap_mgmt_conf,
- ACX_TX_AP_MODE_MGMT_RATE);
- if (ret < 0)
- return ret;
-
- ret = wl1271_acx_ap_rate_policy(wl,
- &wl->conf.tx.ap_bcst_conf,
- ACX_TX_AP_MODE_BCST_RATE);
+ ret = wl1271_init_ap_rates(wl);
if (ret < 0)
return ret;
@@ -449,7 +439,7 @@ static int wl1271_ap_hw_init(struct wl1271 *wl)
return 0;
}
-static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
+int wl1271_ap_init_templates(struct wl1271 *wl)
{
int ret;
@@ -465,6 +455,70 @@ static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
if (ret < 0)
return ret;
+ /*
+ * when operating as AP we want to receive external beacons for
+ * configuring ERP protection.
+ */
+ ret = wl1271_acx_set_ap_beacon_filter(wl, false);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
+{
+ return wl1271_ap_init_templates(wl);
+}
+
+int wl1271_init_ap_rates(struct wl1271 *wl)
+{
+ int i, ret;
+ struct conf_tx_rate_class rc;
+ u32 supported_rates;
+
+ wl1271_debug(DEBUG_AP, "AP basic rate set: 0x%x", wl->basic_rate_set);
+
+ if (wl->basic_rate_set == 0)
+ return -EINVAL;
+
+ rc.enabled_rates = wl->basic_rate_set;
+ rc.long_retry_limit = 10;
+ rc.short_retry_limit = 10;
+ rc.aflags = 0;
+ ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_MGMT_RATE);
+ if (ret < 0)
+ return ret;
+
+ /* use the min basic rate for AP broadcast/multicast */
+ rc.enabled_rates = wl1271_tx_min_rate_get(wl);
+ rc.short_retry_limit = 10;
+ rc.long_retry_limit = 10;
+ rc.aflags = 0;
+ ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_BCST_RATE);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * If the basic rates contain OFDM rates, use OFDM only
+ * rates for unicast TX as well. Else use all supported rates.
+ */
+ if ((wl->basic_rate_set & CONF_TX_OFDM_RATES))
+ supported_rates = CONF_TX_OFDM_RATES;
+ else
+ supported_rates = CONF_TX_AP_ENABLED_RATES;
+
+ /* configure unicast TX rate classes */
+ for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
+ rc.enabled_rates = supported_rates;
+ rc.short_retry_limit = 10;
+ rc.long_retry_limit = 10;
+ rc.aflags = 0;
+ ret = wl1271_acx_ap_rate_policy(wl, &rc, i);
+ if (ret < 0)
+ return ret;
+ }
+
return 0;
}
@@ -504,6 +558,27 @@ static int wl1271_set_ba_policies(struct wl1271 *wl)
return ret;
}
+int wl1271_chip_specific_init(struct wl1271 *wl)
+{
+ int ret = 0;
+
+ if (wl->chip.id == CHIP_ID_1283_PG20) {
+ u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
+
+ if (wl->quirks & WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT)
+ /* Enable SDIO padding */
+ host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
+
+ /* Must be before wl1271_acx_init_mem_config() */
+ ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
+ if (ret < 0)
+ goto out;
+ }
+out:
+ return ret;
+}
+
+
int wl1271_hw_init(struct wl1271 *wl)
{
struct conf_tx_ac_category *conf_ac;
@@ -511,11 +586,22 @@ int wl1271_hw_init(struct wl1271 *wl)
int ret, i;
bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS);
- ret = wl1271_cmd_general_parms(wl);
+ if (wl->chip.id == CHIP_ID_1283_PG20)
+ ret = wl128x_cmd_general_parms(wl);
+ else
+ ret = wl1271_cmd_general_parms(wl);
+ if (ret < 0)
+ return ret;
+
+ if (wl->chip.id == CHIP_ID_1283_PG20)
+ ret = wl128x_cmd_radio_parms(wl);
+ else
+ ret = wl1271_cmd_radio_parms(wl);
if (ret < 0)
return ret;
- ret = wl1271_cmd_radio_parms(wl);
+ /* Chip-specific init */
+ ret = wl1271_chip_specific_init(wl);
if (ret < 0)
return ret;
@@ -528,6 +614,11 @@ int wl1271_hw_init(struct wl1271 *wl)
if (ret < 0)
return ret;
+ /* Bluetooth WLAN coexistence */
+ ret = wl1271_init_pta(wl);
+ if (ret < 0)
+ return ret;
+
/* Default memory configuration */
ret = wl1271_acx_init_mem_config(wl);
if (ret < 0)
@@ -567,7 +658,7 @@ int wl1271_hw_init(struct wl1271 *wl)
goto out_free_memmap;
/* Default fragmentation threshold */
- ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold);
+ ret = wl1271_acx_frag_threshold(wl, wl->hw->wiphy->frag_threshold);
if (ret < 0)
goto out_free_memmap;
diff --git a/drivers/net/wireless/wl12xx/init.h b/drivers/net/wireless/wl12xx/init.h
index 3a8bd3f426d..3a3c230fd29 100644
--- a/drivers/net/wireless/wl12xx/init.h
+++ b/drivers/net/wireless/wl12xx/init.h
@@ -31,6 +31,9 @@ int wl1271_sta_init_templates_config(struct wl1271 *wl);
int wl1271_init_phy_config(struct wl1271 *wl);
int wl1271_init_pta(struct wl1271 *wl);
int wl1271_init_energy_detection(struct wl1271 *wl);
+int wl1271_chip_specific_init(struct wl1271 *wl);
int wl1271_hw_init(struct wl1271 *wl);
+int wl1271_init_ap_rates(struct wl1271 *wl);
+int wl1271_ap_init_templates(struct wl1271 *wl);
#endif
diff --git a/drivers/net/wireless/wl12xx/io.c b/drivers/net/wireless/wl12xx/io.c
index d557f73e7c1..da5c1ad942a 100644
--- a/drivers/net/wireless/wl12xx/io.c
+++ b/drivers/net/wireless/wl12xx/io.c
@@ -29,6 +29,7 @@
#include "wl12xx.h"
#include "wl12xx_80211.h"
#include "io.h"
+#include "tx.h"
#define OCP_CMD_LOOP 32
@@ -43,6 +44,16 @@
#define OCP_STATUS_REQ_FAILED 0x20000
#define OCP_STATUS_RESP_ERROR 0x30000
+bool wl1271_set_block_size(struct wl1271 *wl)
+{
+ if (wl->if_ops->set_block_size) {
+ wl->if_ops->set_block_size(wl, WL12XX_BUS_BLOCK_SIZE);
+ return true;
+ }
+
+ return false;
+}
+
void wl1271_disable_interrupts(struct wl1271 *wl)
{
wl->if_ops->disable_irq(wl);
diff --git a/drivers/net/wireless/wl12xx/io.h b/drivers/net/wireless/wl12xx/io.h
index 00c771ea70b..beed621a8ae 100644
--- a/drivers/net/wireless/wl12xx/io.h
+++ b/drivers/net/wireless/wl12xx/io.h
@@ -169,5 +169,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl);
struct ieee80211_hw *wl1271_alloc_hw(void);
int wl1271_free_hw(struct wl1271 *wl);
irqreturn_t wl1271_irq(int irq, void *data);
+bool wl1271_set_block_size(struct wl1271 *wl);
+int wl1271_tx_dummy_packet(struct wl1271 *wl);
+void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters);
#endif
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 8b3c8d196b0..bc00e52f644 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -30,6 +30,7 @@
#include <linux/vmalloc.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/wl12xx.h>
#include "wl12xx.h"
#include "wl12xx_80211.h"
@@ -50,11 +51,11 @@
static struct conf_drv_settings default_conf = {
.sg = {
- .params = {
+ .sta_params = {
[CONF_SG_BT_PER_THRESHOLD] = 7500,
[CONF_SG_HV3_MAX_OVERRIDE] = 0,
[CONF_SG_BT_NFS_SAMPLE_INTERVAL] = 400,
- [CONF_SG_BT_LOAD_RATIO] = 50,
+ [CONF_SG_BT_LOAD_RATIO] = 200,
[CONF_SG_AUTO_PS_MODE] = 1,
[CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
[CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
@@ -100,6 +101,61 @@ static struct conf_drv_settings default_conf = {
[CONF_SG_DHCP_TIME] = 5000,
[CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
},
+ .ap_params = {
+ [CONF_SG_BT_PER_THRESHOLD] = 7500,
+ [CONF_SG_HV3_MAX_OVERRIDE] = 0,
+ [CONF_SG_BT_NFS_SAMPLE_INTERVAL] = 400,
+ [CONF_SG_BT_LOAD_RATIO] = 50,
+ [CONF_SG_AUTO_PS_MODE] = 1,
+ [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
+ [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
+ [CONF_SG_ANTENNA_CONFIGURATION] = 0,
+ [CONF_SG_BEACON_MISS_PERCENT] = 60,
+ [CONF_SG_RATE_ADAPT_THRESH] = 64,
+ [CONF_SG_RATE_ADAPT_SNR] = 1,
+ [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR] = 10,
+ [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR] = 25,
+ [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR] = 25,
+ [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR] = 20,
+ [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR] = 25,
+ [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR] = 25,
+ [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR] = 7,
+ [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR] = 25,
+ [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR] = 25,
+ [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR] = 8,
+ [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR] = 25,
+ [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR] = 25,
+ [CONF_SG_RXT] = 1200,
+ [CONF_SG_TXT] = 1000,
+ [CONF_SG_ADAPTIVE_RXT_TXT] = 1,
+ [CONF_SG_PS_POLL_TIMEOUT] = 10,
+ [CONF_SG_UPSD_TIMEOUT] = 10,
+ [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR] = 7,
+ [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR] = 15,
+ [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR] = 15,
+ [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR] = 8,
+ [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR] = 20,
+ [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR] = 15,
+ [CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR] = 20,
+ [CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR] = 50,
+ [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR] = 10,
+ [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
+ [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP] = 800,
+ [CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME] = 75,
+ [CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME] = 15,
+ [CONF_SG_HV3_MAX_SERVED] = 6,
+ [CONF_SG_DHCP_TIME] = 5000,
+ [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
+ [CONF_SG_TEMP_PARAM_1] = 0,
+ [CONF_SG_TEMP_PARAM_2] = 0,
+ [CONF_SG_TEMP_PARAM_3] = 0,
+ [CONF_SG_TEMP_PARAM_4] = 0,
+ [CONF_SG_TEMP_PARAM_5] = 0,
+ [CONF_SG_AP_BEACON_MISS_TX] = 3,
+ [CONF_SG_RX_WINDOW_LENGTH] = 6,
+ [CONF_SG_AP_CONNECTION_PROTECTION_TIME] = 50,
+ [CONF_SG_TEMP_PARAM_6] = 1,
+ },
.state = CONF_SG_PROTECTIVE,
},
.rx = {
@@ -107,7 +163,7 @@ static struct conf_drv_settings default_conf = {
.packet_detection_threshold = 0,
.ps_poll_timeout = 15,
.upsd_timeout = 15,
- .rts_threshold = 2347,
+ .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD,
.rx_cca_threshold = 0,
.irq_blk_threshold = 0xFFFF,
.irq_pkt_threshold = 0,
@@ -153,44 +209,6 @@ static struct conf_drv_settings default_conf = {
.tx_op_limit = 1504,
},
},
- .ap_rc_conf = {
- [0] = {
- .enabled_rates = CONF_TX_AP_ENABLED_RATES,
- .short_retry_limit = 10,
- .long_retry_limit = 10,
- .aflags = 0,
- },
- [1] = {
- .enabled_rates = CONF_TX_AP_ENABLED_RATES,
- .short_retry_limit = 10,
- .long_retry_limit = 10,
- .aflags = 0,
- },
- [2] = {
- .enabled_rates = CONF_TX_AP_ENABLED_RATES,
- .short_retry_limit = 10,
- .long_retry_limit = 10,
- .aflags = 0,
- },
- [3] = {
- .enabled_rates = CONF_TX_AP_ENABLED_RATES,
- .short_retry_limit = 10,
- .long_retry_limit = 10,
- .aflags = 0,
- },
- },
- .ap_mgmt_conf = {
- .enabled_rates = CONF_TX_AP_DEFAULT_MGMT_RATES,
- .short_retry_limit = 10,
- .long_retry_limit = 10,
- .aflags = 0,
- },
- .ap_bcst_conf = {
- .enabled_rates = CONF_HW_BIT_RATE_1MBPS,
- .short_retry_limit = 10,
- .long_retry_limit = 10,
- .aflags = 0,
- },
.ap_max_tx_retries = 100,
.tid_conf_count = 4,
.tid_conf = {
@@ -239,12 +257,16 @@ static struct conf_drv_settings default_conf = {
.wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
.listen_interval = 1,
.bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
- .bcn_filt_ie_count = 1,
+ .bcn_filt_ie_count = 2,
.bcn_filt_ie = {
[0] = {
.ie = WLAN_EID_CHANNEL_SWITCH,
.rule = CONF_BCN_RULE_PASS_ON_APPEARANCE,
- }
+ },
+ [1] = {
+ .ie = WLAN_EID_HT_INFORMATION,
+ .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
+ },
},
.synch_fail_thold = 10,
.bss_lose_timeout = 100,
@@ -254,9 +276,9 @@ static struct conf_drv_settings default_conf = {
.ps_poll_threshold = 10,
.ps_poll_recovery_period = 700,
.bet_enable = CONF_BET_MODE_ENABLE,
- .bet_max_consecutive = 10,
+ .bet_max_consecutive = 50,
.psm_entry_retries = 5,
- .psm_exit_retries = 255,
+ .psm_exit_retries = 16,
.psm_entry_nullfunc_retries = 3,
.psm_entry_hangover_period = 1,
.keep_alive_interval = 55000,
@@ -284,6 +306,15 @@ static struct conf_drv_settings default_conf = {
.max_dwell_time_passive = 100000,
.num_probe_reqs = 2,
},
+ .sched_scan = {
+ /* sched_scan requires dwell times in TU instead of TU/1000 */
+ .min_dwell_time_active = 8,
+ .max_dwell_time_active = 30,
+ .dwell_time_passive = 100,
+ .num_probe_reqs = 2,
+ .rssi_threshold = -90,
+ .snr_threshold = 0,
+ },
.rf = {
.tx_per_channel_power_compensation_2 = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -298,19 +329,43 @@ static struct conf_drv_settings default_conf = {
.tx_ba_win_size = 64,
.inactivity_timeout = 10000,
},
- .mem = {
+ .mem_wl127x = {
.num_stations = 1,
.ssid_profiles = 1,
.rx_block_num = 70,
.tx_min_block_num = 40,
- .dynamic_memory = 0,
+ .dynamic_memory = 1,
.min_req_tx_blocks = 100,
.min_req_rx_blocks = 22,
.tx_min = 27,
- }
+ },
+ .mem_wl128x = {
+ .num_stations = 1,
+ .ssid_profiles = 1,
+ .rx_block_num = 40,
+ .tx_min_block_num = 40,
+ .dynamic_memory = 1,
+ .min_req_tx_blocks = 45,
+ .min_req_rx_blocks = 22,
+ .tx_min = 27,
+ },
+ .fm_coex = {
+ .enable = true,
+ .swallow_period = 5,
+ .n_divider_fref_set_1 = 0xff, /* default */
+ .n_divider_fref_set_2 = 12,
+ .m_divider_fref_set_1 = 148,
+ .m_divider_fref_set_2 = 0xffff, /* default */
+ .coex_pll_stabilization_time = 0xffffffff, /* default */
+ .ldo_stabilization_time = 0xffff, /* default */
+ .fm_disturbed_band_margin = 0xff, /* default */
+ .swallow_clk_diff = 0xff, /* default */
+ },
+ .hci_io_ds = HCI_IO_DS_6MA,
};
-static void __wl1271_op_remove_interface(struct wl1271 *wl);
+static void __wl1271_op_remove_interface(struct wl1271 *wl,
+ bool reset_tx_queues);
static void wl1271_free_ap_keys(struct wl1271 *wl);
@@ -329,6 +384,7 @@ static struct platform_device wl1271_device = {
},
};
+static DEFINE_MUTEX(wl_list_mutex);
static LIST_HEAD(wl_list);
static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
@@ -359,10 +415,12 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
return NOTIFY_DONE;
wl_temp = hw->priv;
+ mutex_lock(&wl_list_mutex);
list_for_each_entry(wl, &wl_list, list) {
if (wl == wl_temp)
break;
}
+ mutex_unlock(&wl_list_mutex);
if (wl != wl_temp)
return NOTIFY_DONE;
@@ -438,15 +496,30 @@ static int wl1271_plt_init(struct wl1271 *wl)
struct conf_tx_tid *conf_tid;
int ret, i;
- ret = wl1271_cmd_general_parms(wl);
+ if (wl->chip.id == CHIP_ID_1283_PG20)
+ ret = wl128x_cmd_general_parms(wl);
+ else
+ ret = wl1271_cmd_general_parms(wl);
+ if (ret < 0)
+ return ret;
+
+ if (wl->chip.id == CHIP_ID_1283_PG20)
+ ret = wl128x_cmd_radio_parms(wl);
+ else
+ ret = wl1271_cmd_radio_parms(wl);
if (ret < 0)
return ret;
- ret = wl1271_cmd_radio_parms(wl);
+ if (wl->chip.id != CHIP_ID_1283_PG20) {
+ ret = wl1271_cmd_ext_radio_parms(wl);
+ if (ret < 0)
+ return ret;
+ }
if (ret < 0)
return ret;
- ret = wl1271_cmd_ext_radio_parms(wl);
+ /* Chip-specific initializations */
+ ret = wl1271_chip_specific_init(wl);
if (ret < 0)
return ret;
@@ -477,6 +550,11 @@ static int wl1271_plt_init(struct wl1271 *wl)
if (ret < 0)
goto out_free_memmap;
+ /* FM WLAN coexistence */
+ ret = wl1271_acx_fm_coex(wl);
+ if (ret < 0)
+ goto out_free_memmap;
+
/* Energy detection */
ret = wl1271_init_energy_detection(wl);
if (ret < 0)
@@ -593,15 +671,17 @@ static void wl1271_fw_status(struct wl1271 *wl,
{
struct wl1271_fw_common_status *status = &full_status->common;
struct timespec ts;
- u32 total = 0;
+ u32 old_tx_blk_count = wl->tx_blocks_available;
+ u32 freed_blocks = 0;
int i;
- if (wl->bss_type == BSS_TYPE_AP_BSS)
+ if (wl->bss_type == BSS_TYPE_AP_BSS) {
wl1271_raw_read(wl, FW_STATUS_ADDR, status,
sizeof(struct wl1271_fw_ap_status), false);
- else
+ } else {
wl1271_raw_read(wl, FW_STATUS_ADDR, status,
sizeof(struct wl1271_fw_sta_status), false);
+ }
wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
"drv_rx_counter = %d, tx_results_counter = %d)",
@@ -612,22 +692,37 @@ static void wl1271_fw_status(struct wl1271 *wl,
/* update number of available TX blocks */
for (i = 0; i < NUM_TX_QUEUES; i++) {
- u32 cnt = le32_to_cpu(status->tx_released_blks[i]) -
- wl->tx_blocks_freed[i];
+ freed_blocks += le32_to_cpu(status->tx_released_blks[i]) -
+ wl->tx_blocks_freed[i];
wl->tx_blocks_freed[i] =
le32_to_cpu(status->tx_released_blks[i]);
- wl->tx_blocks_available += cnt;
- total += cnt;
}
- /* if more blocks are available now, tx work can be scheduled */
- if (total)
- clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
+ wl->tx_allocated_blocks -= freed_blocks;
- /* for AP update num of allocated TX blocks per link and ps status */
- if (wl->bss_type == BSS_TYPE_AP_BSS)
+ if (wl->bss_type == BSS_TYPE_AP_BSS) {
+ /* Update num of allocated TX blocks per link and ps status */
wl1271_irq_update_links_status(wl, &full_status->ap);
+ wl->tx_blocks_available += freed_blocks;
+ } else {
+ int avail = full_status->sta.tx_total - wl->tx_allocated_blocks;
+
+ /*
+ * The FW might change the total number of TX memblocks before
+ * we get a notification about blocks being released. Thus, the
+ * available blocks calculation might yield a temporary result
+ * which is lower than the actual available blocks. Keeping in
+ * mind that only blocks that were allocated can be moved from
+ * TX to RX, tx_blocks_available should never decrease here.
+ */
+ wl->tx_blocks_available = max((int)wl->tx_blocks_available,
+ avail);
+ }
+
+ /* if more blocks are available now, tx work can be scheduled */
+ if (wl->tx_blocks_available > old_tx_blk_count)
+ clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
/* update the host-chipset time offset */
getnstimeofday(&ts);
@@ -674,6 +769,13 @@ irqreturn_t wl1271_irq(int irq, void *cookie)
set_bit(WL1271_FLAG_TX_PENDING, &wl->flags);
cancel_work_sync(&wl->tx_work);
+ /*
+ * In case edge triggered interrupt must be used, we cannot iterate
+ * more than once without introducing race conditions with the hardirq.
+ */
+ if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
+ loopcount = 1;
+
mutex_lock(&wl->mutex);
wl1271_debug(DEBUG_IRQ, "IRQ work");
@@ -785,11 +887,17 @@ static int wl1271_fetch_firmware(struct wl1271 *wl)
switch (wl->bss_type) {
case BSS_TYPE_AP_BSS:
- fw_name = WL1271_AP_FW_NAME;
+ if (wl->chip.id == CHIP_ID_1283_PG20)
+ fw_name = WL128X_AP_FW_NAME;
+ else
+ fw_name = WL127X_AP_FW_NAME;
break;
case BSS_TYPE_IBSS:
case BSS_TYPE_STA_BSS:
- fw_name = WL1271_FW_NAME;
+ if (wl->chip.id == CHIP_ID_1283_PG20)
+ fw_name = WL128X_FW_NAME;
+ else
+ fw_name = WL1271_FW_NAME;
break;
default:
wl1271_error("no compatible firmware for bss_type %d",
@@ -838,14 +946,14 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
const struct firmware *fw;
int ret;
- ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl));
+ ret = request_firmware(&fw, WL12XX_NVS_NAME, wl1271_wl_to_dev(wl));
if (ret < 0) {
wl1271_error("could not get nvs file: %d", ret);
return ret;
}
- wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL);
+ wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL);
if (!wl->nvs) {
wl1271_error("could not allocate memory for the nvs file");
@@ -871,15 +979,30 @@ static void wl1271_recovery_work(struct work_struct *work)
if (wl->state != WL1271_STATE_ON)
goto out;
- wl1271_info("Hardware recovery in progress.");
+ wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x",
+ wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4));
if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
ieee80211_connection_loss(wl->vif);
+ /* Prevent spurious TX during FW restart */
+ ieee80211_stop_queues(wl->hw);
+
+ if (wl->sched_scanning) {
+ ieee80211_sched_scan_stopped(wl->hw);
+ wl->sched_scanning = false;
+ }
+
/* reboot the chipset */
- __wl1271_op_remove_interface(wl);
+ __wl1271_op_remove_interface(wl, false);
ieee80211_restart_hw(wl->hw);
+ /*
+ * Its safe to enable TX now - the queues are stopped after a request
+ * to restart the HW.
+ */
+ ieee80211_wake_queues(wl->hw);
+
out:
mutex_unlock(&wl->mutex);
}
@@ -950,10 +1073,25 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
wl->chip.id);
+ /* end-of-transaction flag should be set in wl127x AP mode */
+ if (wl->bss_type == BSS_TYPE_AP_BSS)
+ wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION;
+
ret = wl1271_setup(wl);
if (ret < 0)
goto out;
break;
+ case CHIP_ID_1283_PG20:
+ wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
+ wl->chip.id);
+
+ ret = wl1271_setup(wl);
+ if (ret < 0)
+ goto out;
+ if (wl1271_set_block_size(wl))
+ wl->quirks |= WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT;
+ break;
+ case CHIP_ID_1283_PG10:
default:
wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
ret = -ENODEV;
@@ -978,6 +1116,24 @@ out:
return ret;
}
+static unsigned int wl1271_get_fw_ver_quirks(struct wl1271 *wl)
+{
+ unsigned int quirks = 0;
+ unsigned int *fw_ver = wl->chip.fw_ver;
+
+ /* Only for wl127x */
+ if ((fw_ver[FW_VER_CHIP] == FW_VER_CHIP_WL127X) &&
+ /* Check STA version */
+ (((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) &&
+ (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_1_SPARE_STA_MIN)) ||
+ /* Check AP version */
+ ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP) &&
+ (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_1_SPARE_AP_MIN))))
+ quirks |= WL12XX_QUIRK_USE_2_SPARE_BLOCKS;
+
+ return quirks;
+}
+
int wl1271_plt_start(struct wl1271 *wl)
{
int retries = WL1271_BOOT_RETRIES;
@@ -1013,6 +1169,9 @@ int wl1271_plt_start(struct wl1271 *wl)
wl->state = WL1271_STATE_PLT;
wl1271_notice("firmware booted in PLT mode (%s)",
wl->chip.fw_ver_str);
+
+ /* Check if any quirks are needed with older fw versions */
+ wl->quirks |= wl1271_get_fw_ver_quirks(wl);
goto out;
irq_disable:
@@ -1040,7 +1199,7 @@ out:
return ret;
}
-int __wl1271_plt_stop(struct wl1271 *wl)
+static int __wl1271_plt_stop(struct wl1271 *wl)
{
int ret = 0;
@@ -1124,10 +1283,219 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
spin_unlock_irqrestore(&wl->wl_lock, flags);
}
+int wl1271_tx_dummy_packet(struct wl1271 *wl)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&wl->wl_lock, flags);
+ set_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags);
+ wl->tx_queue_count++;
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
+
+ /* The FW is low on RX memory blocks, so send the dummy packet asap */
+ if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags))
+ wl1271_tx_work_locked(wl);
+
+ /*
+ * If the FW TX is busy, TX work will be scheduled by the threaded
+ * interrupt handler function
+ */
+ return 0;
+}
+
+/*
+ * The size of the dummy packet should be at least 1400 bytes. However, in
+ * order to minimize the number of bus transactions, aligning it to 512 bytes
+ * boundaries could be beneficial, performance wise
+ */
+#define TOTAL_TX_DUMMY_PACKET_SIZE (ALIGN(1400, 512))
+
+static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
+{
+ struct sk_buff *skb;
+ struct ieee80211_hdr_3addr *hdr;
+ unsigned int dummy_packet_size;
+
+ dummy_packet_size = TOTAL_TX_DUMMY_PACKET_SIZE -
+ sizeof(struct wl1271_tx_hw_descr) - sizeof(*hdr);
+
+ skb = dev_alloc_skb(TOTAL_TX_DUMMY_PACKET_SIZE);
+ if (!skb) {
+ wl1271_warning("Failed to allocate a dummy packet skb");
+ return NULL;
+ }
+
+ skb_reserve(skb, sizeof(struct wl1271_tx_hw_descr));
+
+ hdr = (struct ieee80211_hdr_3addr *) skb_put(skb, sizeof(*hdr));
+ memset(hdr, 0, sizeof(*hdr));
+ hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
+ IEEE80211_STYPE_NULLFUNC |
+ IEEE80211_FCTL_TODS);
+
+ memset(skb_put(skb, dummy_packet_size), 0, dummy_packet_size);
+
+ /* Dummy packets require the TID to be management */
+ skb->priority = WL1271_TID_MGMT;
+
+ /* Initialize all fields that might be used */
+ skb_set_queue_mapping(skb, 0);
+ memset(IEEE80211_SKB_CB(skb), 0, sizeof(struct ieee80211_tx_info));
+
+ return skb;
+}
+
+
static struct notifier_block wl1271_dev_notifier = {
.notifier_call = wl1271_dev_notify,
};
+#ifdef CONFIG_PM
+static int wl1271_configure_suspend(struct wl1271 *wl)
+{
+ int ret;
+
+ if (wl->bss_type != BSS_TYPE_STA_BSS)
+ return 0;
+
+ mutex_lock(&wl->mutex);
+
+ ret = wl1271_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out_unlock;
+
+ /* enter psm if needed*/
+ if (!test_bit(WL1271_FLAG_PSM, &wl->flags)) {
+ DECLARE_COMPLETION_ONSTACK(compl);
+
+ wl->ps_compl = &compl;
+ ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
+ wl->basic_rate, true);
+ if (ret < 0)
+ goto out_sleep;
+
+ /* we must unlock here so we will be able to get events */
+ wl1271_ps_elp_sleep(wl);
+ mutex_unlock(&wl->mutex);
+
+ ret = wait_for_completion_timeout(
+ &compl, msecs_to_jiffies(WL1271_PS_COMPLETE_TIMEOUT));
+ if (ret <= 0) {
+ wl1271_warning("couldn't enter ps mode!");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ /* take mutex again, and wakeup */
+ mutex_lock(&wl->mutex);
+
+ ret = wl1271_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out_unlock;
+ }
+out_sleep:
+ wl1271_ps_elp_sleep(wl);
+out_unlock:
+ mutex_unlock(&wl->mutex);
+out:
+ return ret;
+
+}
+
+static void wl1271_configure_resume(struct wl1271 *wl)
+{
+ int ret;
+
+ if (wl->bss_type != BSS_TYPE_STA_BSS)
+ return;
+
+ mutex_lock(&wl->mutex);
+ ret = wl1271_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out;
+
+ /* exit psm if it wasn't configured */
+ if (!test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags))
+ wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
+ wl->basic_rate, true);
+
+ wl1271_ps_elp_sleep(wl);
+out:
+ mutex_unlock(&wl->mutex);
+}
+
+static int wl1271_op_suspend(struct ieee80211_hw *hw,
+ struct cfg80211_wowlan *wow)
+{
+ struct wl1271 *wl = hw->priv;
+ wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow);
+ wl->wow_enabled = !!wow;
+ if (wl->wow_enabled) {
+ int ret;
+ ret = wl1271_configure_suspend(wl);
+ if (ret < 0) {
+ wl1271_warning("couldn't prepare device to suspend");
+ return ret;
+ }
+ /* flush any remaining work */
+ wl1271_debug(DEBUG_MAC80211, "flushing remaining works");
+ flush_delayed_work(&wl->scan_complete_work);
+
+ /*
+ * disable and re-enable interrupts in order to flush
+ * the threaded_irq
+ */
+ wl1271_disable_interrupts(wl);
+
+ /*
+ * set suspended flag to avoid triggering a new threaded_irq
+ * work. no need for spinlock as interrupts are disabled.
+ */
+ set_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
+
+ wl1271_enable_interrupts(wl);
+ flush_work(&wl->tx_work);
+ flush_delayed_work(&wl->pspoll_work);
+ flush_delayed_work(&wl->elp_work);
+ }
+ return 0;
+}
+
+static int wl1271_op_resume(struct ieee80211_hw *hw)
+{
+ struct wl1271 *wl = hw->priv;
+ wl1271_debug(DEBUG_MAC80211, "mac80211 resume wow=%d",
+ wl->wow_enabled);
+
+ /*
+ * re-enable irq_work enqueuing, and call irq_work directly if
+ * there is a pending work.
+ */
+ if (wl->wow_enabled) {
+ struct wl1271 *wl = hw->priv;
+ unsigned long flags;
+ bool run_irq_work = false;
+
+ spin_lock_irqsave(&wl->wl_lock, flags);
+ clear_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
+ if (test_and_clear_bit(WL1271_FLAG_PENDING_WORK, &wl->flags))
+ run_irq_work = true;
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
+
+ if (run_irq_work) {
+ wl1271_debug(DEBUG_MAC80211,
+ "run postponed irq_work directly");
+ wl1271_irq(0, wl);
+ wl1271_enable_interrupts(wl);
+ }
+
+ wl1271_configure_resume(wl);
+ }
+
+ return 0;
+}
+#endif
+
static int wl1271_op_start(struct ieee80211_hw *hw)
{
wl1271_debug(DEBUG_MAC80211, "mac80211 start");
@@ -1174,6 +1542,16 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
goto out;
}
+ /*
+ * in some very corner case HW recovery scenarios its possible to
+ * get here before __wl1271_op_remove_interface is complete, so
+ * opt out if that is the case.
+ */
+ if (test_bit(WL1271_FLAG_IF_INITIALIZED, &wl->flags)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
switch (vif->type) {
case NL80211_IFTYPE_STATION:
wl->bss_type = BSS_TYPE_STA_BSS;
@@ -1242,6 +1620,7 @@ power_off:
wl->vif = vif;
wl->state = WL1271_STATE_ON;
+ set_bit(WL1271_FLAG_IF_INITIALIZED, &wl->flags);
wl1271_info("firmware booted (%s)", wl->chip.fw_ver_str);
/* update hw/fw version info in wiphy struct */
@@ -1249,6 +1628,9 @@ power_off:
strncpy(wiphy->fw_version, wl->chip.fw_ver_str,
sizeof(wiphy->fw_version));
+ /* Check if any quirks are needed with older fw versions */
+ wl->quirks |= wl1271_get_fw_ver_quirks(wl);
+
/*
* Now we know if 11a is supported (info from the NVS), so disable
* 11a channels if not supported
@@ -1262,23 +1644,30 @@ power_off:
out:
mutex_unlock(&wl->mutex);
+ mutex_lock(&wl_list_mutex);
if (!ret)
list_add(&wl->list, &wl_list);
+ mutex_unlock(&wl_list_mutex);
return ret;
}
-static void __wl1271_op_remove_interface(struct wl1271 *wl)
+static void __wl1271_op_remove_interface(struct wl1271 *wl,
+ bool reset_tx_queues)
{
int i;
wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
+ /* because of hardware recovery, we may get here twice */
+ if (wl->state != WL1271_STATE_ON)
+ return;
+
wl1271_info("down");
+ mutex_lock(&wl_list_mutex);
list_del(&wl->list);
-
- WARN_ON(wl->state != WL1271_STATE_ON);
+ mutex_unlock(&wl_list_mutex);
/* enable dyn ps just in case (if left on due to fw crash etc) */
if (wl->bss_type == BSS_TYPE_STA_BSS)
@@ -1286,12 +1675,15 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
if (wl->scan.state != WL1271_SCAN_STATE_IDLE) {
wl->scan.state = WL1271_SCAN_STATE_IDLE;
- kfree(wl->scan.scanned_ch);
- wl->scan.scanned_ch = NULL;
+ memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
wl->scan.req = NULL;
ieee80211_scan_completed(wl->hw, true);
}
+ /*
+ * this must be before the cancel_work calls below, so that the work
+ * functions don't perform further work.
+ */
wl->state = WL1271_STATE_OFF;
mutex_unlock(&wl->mutex);
@@ -1307,7 +1699,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
mutex_lock(&wl->mutex);
/* let's notify MAC80211 about the remaining pending TX frames */
- wl1271_tx_reset(wl);
+ wl1271_tx_reset(wl, reset_tx_queues);
wl1271_power_off(wl);
memset(wl->bssid, 0, ETH_ALEN);
@@ -1321,6 +1713,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
wl->psm_entry_retry = 0;
wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
wl->tx_blocks_available = 0;
+ wl->tx_allocated_blocks = 0;
wl->tx_results_count = 0;
wl->tx_packets_count = 0;
wl->tx_security_last_seq = 0;
@@ -1328,13 +1721,20 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
wl->time_offset = 0;
wl->session_counter = 0;
wl->rate_set = CONF_TX_RATE_MASK_BASIC;
- wl->flags = 0;
wl->vif = NULL;
wl->filters = 0;
wl1271_free_ap_keys(wl);
memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map));
wl->ap_fw_ps_map = 0;
wl->ap_ps_map = 0;
+ wl->sched_scanning = false;
+
+ /*
+ * this is performed after the cancel_work calls and the associated
+ * mutex_lock, so that wl1271_op_add_interface does not accidentally
+ * get executed before all these vars have been reset.
+ */
+ wl->flags = 0;
for (i = 0; i < NUM_TX_QUEUES; i++)
wl->tx_blocks_freed[i] = 0;
@@ -1361,14 +1761,14 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
*/
if (wl->vif) {
WARN_ON(wl->vif != vif);
- __wl1271_op_remove_interface(wl);
+ __wl1271_op_remove_interface(wl, true);
}
mutex_unlock(&wl->mutex);
cancel_work_sync(&wl->recovery_work);
}
-static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters)
+void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters)
{
wl1271_set_default_filters(wl);
@@ -1431,10 +1831,10 @@ static int wl1271_join(struct wl1271 *wl, bool set_assoc)
* One of the side effects of the JOIN command is that is clears
* WPA/WPA2 keys from the chipset. Performing a JOIN while associated
* to a WPA/WPA2 access point will therefore kill the data-path.
- * Currently there is no supported scenario for JOIN during
- * association - if it becomes a supported scenario, the WPA/WPA2 keys
- * must be handled somehow.
- *
+ * Currently the only valid scenario for JOIN during association
+ * is on roaming, in which case we will also be given new keys.
+ * Keep the below message for now, unless it starts bothering
+ * users who really like to roam a lot :)
*/
if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
wl1271_info("JOIN while associated.");
@@ -1490,7 +1890,7 @@ static int wl1271_unjoin(struct wl1271 *wl)
clear_bit(WL1271_FLAG_JOINED, &wl->flags);
memset(wl->bssid, 0, ETH_ALEN);
- /* stop filterting packets based on bssid */
+ /* stop filtering packets based on bssid */
wl1271_configure_filters(wl, FIF_OTHER_BSS);
out:
@@ -1530,6 +1930,13 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle)
wl->session_counter++;
if (wl->session_counter >= SESSION_COUNTER_MAX)
wl->session_counter = 0;
+
+ /* The current firmware only supports sched_scan in idle */
+ if (wl->sched_scanning) {
+ wl1271_scan_sched_scan_stop(wl);
+ ieee80211_sched_scan_stopped(wl->hw);
+ }
+
ret = wl1271_dummy_join(wl);
if (ret < 0)
goto out;
@@ -1569,7 +1976,12 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&wl->mutex);
if (unlikely(wl->state == WL1271_STATE_OFF)) {
- ret = -EAGAIN;
+ /* we support configuring the channel and band while off */
+ if ((changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
+ wl->band = conf->channel->band;
+ wl->channel = channel;
+ }
+
goto out;
}
@@ -2077,6 +2489,60 @@ out:
return ret;
}
+static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct cfg80211_sched_scan_request *req,
+ struct ieee80211_sched_scan_ies *ies)
+{
+ struct wl1271 *wl = hw->priv;
+ int ret;
+
+ wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_start");
+
+ mutex_lock(&wl->mutex);
+
+ ret = wl1271_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out;
+
+ ret = wl1271_scan_sched_scan_config(wl, req, ies);
+ if (ret < 0)
+ goto out_sleep;
+
+ ret = wl1271_scan_sched_scan_start(wl);
+ if (ret < 0)
+ goto out_sleep;
+
+ wl->sched_scanning = true;
+
+out_sleep:
+ wl1271_ps_elp_sleep(wl);
+out:
+ mutex_unlock(&wl->mutex);
+ return ret;
+}
+
+static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct wl1271 *wl = hw->priv;
+ int ret;
+
+ wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_stop");
+
+ mutex_lock(&wl->mutex);
+
+ ret = wl1271_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out;
+
+ wl1271_scan_sched_scan_stop(wl);
+
+ wl1271_ps_elp_sleep(wl);
+out:
+ mutex_unlock(&wl->mutex);
+}
+
static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
{
struct wl1271 *wl = hw->priv;
@@ -2093,7 +2559,7 @@ static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
if (ret < 0)
goto out;
- ret = wl1271_acx_frag_threshold(wl, (u16)value);
+ ret = wl1271_acx_frag_threshold(wl, value);
if (ret < 0)
wl1271_warning("wl1271_op_set_frag_threshold failed: %d", ret);
@@ -2121,7 +2587,7 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
if (ret < 0)
goto out;
- ret = wl1271_acx_rts_threshold(wl, (u16) value);
+ ret = wl1271_acx_rts_threshold(wl, value);
if (ret < 0)
wl1271_warning("wl1271_op_set_rts_threshold failed: %d", ret);
@@ -2136,20 +2602,24 @@ out:
static int wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *skb,
int offset)
{
- u8 *ptr = skb->data + offset;
+ u8 ssid_len;
+ const u8 *ptr = cfg80211_find_ie(WLAN_EID_SSID, skb->data + offset,
+ skb->len - offset);
- /* find the location of the ssid in the beacon */
- while (ptr < skb->data + skb->len) {
- if (ptr[0] == WLAN_EID_SSID) {
- wl->ssid_len = ptr[1];
- memcpy(wl->ssid, ptr+2, wl->ssid_len);
- return 0;
- }
- ptr += (ptr[1] + 2);
+ if (!ptr) {
+ wl1271_error("No SSID in IEs!");
+ return -ENOENT;
}
- wl1271_error("No SSID in IEs!\n");
- return -ENOENT;
+ ssid_len = ptr[1];
+ if (ssid_len > IEEE80211_MAX_SSID_LEN) {
+ wl1271_error("SSID is too long!");
+ return -EINVAL;
+ }
+
+ wl->ssid_len = ssid_len;
+ memcpy(wl->ssid, ptr+2, ssid_len);
+ return 0;
}
static int wl1271_bss_erp_info_changed(struct wl1271 *wl,
@@ -2264,24 +2734,19 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
if ((changed & BSS_CHANGED_BASIC_RATES)) {
u32 rates = bss_conf->basic_rates;
- struct conf_tx_rate_class mgmt_rc;
wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates);
wl->basic_rate = wl1271_tx_min_rate_get(wl);
- wl1271_debug(DEBUG_AP, "basic rates: 0x%x",
- wl->basic_rate_set);
-
- /* update the AP management rate policy with the new rates */
- mgmt_rc.enabled_rates = wl->basic_rate_set;
- mgmt_rc.long_retry_limit = 10;
- mgmt_rc.short_retry_limit = 10;
- mgmt_rc.aflags = 0;
- ret = wl1271_acx_ap_rate_policy(wl, &mgmt_rc,
- ACX_TX_AP_MODE_MGMT_RATE);
+
+ ret = wl1271_init_ap_rates(wl);
if (ret < 0) {
- wl1271_error("AP mgmt policy change failed %d", ret);
+ wl1271_error("AP rate policy change failed %d", ret);
goto out;
}
+
+ ret = wl1271_ap_init_templates(wl);
+ if (ret < 0)
+ goto out;
}
ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, changed);
@@ -2314,6 +2779,24 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
}
}
+ if (changed & BSS_CHANGED_IBSS) {
+ wl1271_debug(DEBUG_ADHOC, "ibss_joined: %d",
+ bss_conf->ibss_joined);
+
+ if (bss_conf->ibss_joined) {
+ u32 rates = bss_conf->basic_rates;
+ wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl,
+ rates);
+ wl->basic_rate = wl1271_tx_min_rate_get(wl);
+
+ /* by default, use 11b rates */
+ wl->rate_set = CONF_TX_IBSS_DEFAULT_RATES;
+ ret = wl1271_acx_sta_rate_policies(wl);
+ if (ret < 0)
+ goto out;
+ }
+ }
+
ret = wl1271_bss_erp_info_changed(wl, bss_conf, changed);
if (ret < 0)
goto out;
@@ -2503,8 +2986,10 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
}
} else {
/* use defaults when not associated */
+ bool was_assoc =
+ !!test_and_clear_bit(WL1271_FLAG_STA_ASSOCIATED,
+ &wl->flags);
clear_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags);
- clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
wl->aid = 0;
/* free probe-request template */
@@ -2530,8 +3015,10 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
goto out;
/* restore the bssid filter and go to dummy bssid */
- wl1271_unjoin(wl);
- wl1271_dummy_join(wl);
+ if (was_assoc) {
+ wl1271_unjoin(wl);
+ wl1271_dummy_join(wl);
+ }
}
}
@@ -2650,32 +3137,31 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
conf_tid->ack_policy = CONF_ACK_POLICY_LEGACY;
conf_tid->apsd_conf[0] = 0;
conf_tid->apsd_conf[1] = 0;
- } else {
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
+ goto out;
+ }
- /*
- * the txop is confed in units of 32us by the mac80211,
- * we need us
- */
- ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue),
- params->cw_min, params->cw_max,
- params->aifs, params->txop << 5);
- if (ret < 0)
- goto out_sleep;
+ ret = wl1271_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out;
- ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue),
- CONF_CHANNEL_TYPE_EDCF,
- wl1271_tx_get_queue(queue),
- ps_scheme, CONF_ACK_POLICY_LEGACY,
- 0, 0);
- if (ret < 0)
- goto out_sleep;
+ /*
+ * the txop is confed in units of 32us by the mac80211,
+ * we need us
+ */
+ ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue),
+ params->cw_min, params->cw_max,
+ params->aifs, params->txop << 5);
+ if (ret < 0)
+ goto out_sleep;
+
+ ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue),
+ CONF_CHANNEL_TYPE_EDCF,
+ wl1271_tx_get_queue(queue),
+ ps_scheme, CONF_ACK_POLICY_LEGACY,
+ 0, 0);
out_sleep:
- wl1271_ps_elp_sleep(wl);
- }
+ wl1271_ps_elp_sleep(wl);
out:
mutex_unlock(&wl->mutex);
@@ -2847,10 +3333,11 @@ out:
return ret;
}
-int wl1271_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- enum ieee80211_ampdu_mlme_action action,
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
- u8 buf_size)
+static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+ u8 buf_size)
{
struct wl1271 *wl = hw->priv;
int ret;
@@ -2907,6 +3394,28 @@ out:
return ret;
}
+static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
+{
+ struct wl1271 *wl = hw->priv;
+ bool ret = false;
+
+ mutex_lock(&wl->mutex);
+
+ if (unlikely(wl->state == WL1271_STATE_OFF))
+ goto out;
+
+ /* packets are considered pending if in the TX queue or the FW */
+ ret = (wl->tx_queue_count > 0) || (wl->tx_frames_cnt > 0);
+
+ /* the above is appropriate for STA mode for PS purposes */
+ WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
+
+out:
+ mutex_unlock(&wl->mutex);
+
+ return ret;
+}
+
/* can't be const, mac80211 writes to this */
static struct ieee80211_rate wl1271_rates[] = {
{ .bitrate = 10,
@@ -3003,7 +3512,8 @@ static const u8 wl1271_rate_to_idx_2ghz[] = {
#ifdef CONFIG_WL12XX_HT
#define WL12XX_HT_CAP { \
- .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20, \
+ .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | \
+ (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT), \
.ht_supported = true, \
.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K, \
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \
@@ -3142,12 +3652,18 @@ static const struct ieee80211_ops wl1271_ops = {
.stop = wl1271_op_stop,
.add_interface = wl1271_op_add_interface,
.remove_interface = wl1271_op_remove_interface,
+#ifdef CONFIG_PM
+ .suspend = wl1271_op_suspend,
+ .resume = wl1271_op_resume,
+#endif
.config = wl1271_op_config,
.prepare_multicast = wl1271_op_prepare_multicast,
.configure_filter = wl1271_op_configure_filter,
.tx = wl1271_op_tx,
.set_key = wl1271_op_set_key,
.hw_scan = wl1271_op_hw_scan,
+ .sched_scan_start = wl1271_op_sched_scan_start,
+ .sched_scan_stop = wl1271_op_sched_scan_stop,
.bss_info_changed = wl1271_op_bss_info_changed,
.set_frag_threshold = wl1271_op_set_frag_threshold,
.set_rts_threshold = wl1271_op_set_rts_threshold,
@@ -3157,6 +3673,7 @@ static const struct ieee80211_ops wl1271_ops = {
.sta_add = wl1271_op_sta_add,
.sta_remove = wl1271_op_sta_remove,
.ampdu_action = wl1271_op_ampdu_action,
+ .tx_frames_pending = wl1271_tx_frames_pending,
CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
};
@@ -3207,8 +3724,7 @@ static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev,
unsigned long res;
int ret;
- ret = strict_strtoul(buf, 10, &res);
-
+ ret = kstrtoul(buf, 10, &res);
if (ret < 0) {
wl1271_warning("incorrect value written to bt_coex_mode");
return count;
@@ -3273,7 +3789,11 @@ int wl1271_register_hw(struct wl1271 *wl)
ret = wl1271_fetch_nvs(wl);
if (ret == 0) {
- u8 *nvs_ptr = (u8 *)wl->nvs->nvs;
+ /* NOTE: The wl->nvs->nvs element must be first, in
+ * order to simplify the casting, we assume it is at
+ * the beginning of the wl->nvs structure.
+ */
+ u8 *nvs_ptr = (u8 *)wl->nvs;
wl->mac_addr[0] = nvs_ptr[11];
wl->mac_addr[1] = nvs_ptr[10];
@@ -3342,6 +3862,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
IEEE80211_HW_CONNECTION_MONITOR |
IEEE80211_HW_SUPPORTS_CQM_RSSI |
IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+ IEEE80211_HW_SPECTRUM_MGMT |
IEEE80211_HW_AP_LINK_PS;
wl->hw->wiphy->cipher_suites = cipher_suites;
@@ -3358,6 +3879,10 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE -
sizeof(struct ieee80211_header);
+ /* make sure all our channels fit in the scanned_ch bitmask */
+ BUILD_BUG_ON(ARRAY_SIZE(wl1271_channels) +
+ ARRAY_SIZE(wl1271_channels_5ghz) >
+ WL1271_MAX_CHANNELS);
/*
* We keep local copies of the band structs because we need to
* modify them on a per-device basis.
@@ -3458,6 +3983,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl->ap_ps_map = 0;
wl->ap_fw_ps_map = 0;
wl->quirks = 0;
+ wl->platform_quirks = 0;
+ wl->sched_scanning = false;
memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
@@ -3478,11 +4005,17 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
goto err_hw;
}
+ wl->dummy_packet = wl12xx_alloc_dummy_packet(wl);
+ if (!wl->dummy_packet) {
+ ret = -ENOMEM;
+ goto err_aggr;
+ }
+
/* Register platform device */
ret = platform_device_register(wl->plat_dev);
if (ret) {
wl1271_error("couldn't register platform device");
- goto err_aggr;
+ goto err_dummy_packet;
}
dev_set_drvdata(&wl->plat_dev->dev, wl);
@@ -3508,6 +4041,9 @@ err_bt_coex_state:
err_platform:
platform_device_unregister(wl->plat_dev);
+err_dummy_packet:
+ dev_kfree_skb(wl->dummy_packet);
+
err_aggr:
free_pages((unsigned long)wl->aggr_buf, order);
@@ -3527,6 +4063,7 @@ EXPORT_SYMBOL_GPL(wl1271_alloc_hw);
int wl1271_free_hw(struct wl1271 *wl)
{
platform_device_unregister(wl->plat_dev);
+ dev_kfree_skb(wl->dummy_packet);
free_pages((unsigned long)wl->aggr_buf,
get_order(WL1271_AGGR_BUFFER_SIZE));
kfree(wl->plat_dev);
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
index 971f13e792d..b59b67711a1 100644
--- a/drivers/net/wireless/wl12xx/ps.c
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -43,6 +43,10 @@ void wl1271_elp_work(struct work_struct *work)
if (unlikely(wl->state == WL1271_STATE_OFF))
goto out;
+ /* our work might have been already cancelled */
+ if (unlikely(!test_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags)))
+ goto out;
+
if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) ||
(!test_bit(WL1271_FLAG_PSM, &wl->flags) &&
!test_bit(WL1271_FLAG_IDLE, &wl->flags)))
@@ -61,12 +65,16 @@ out:
/* Routines to toggle sleep mode while in ELP */
void wl1271_ps_elp_sleep(struct wl1271 *wl)
{
- if (test_bit(WL1271_FLAG_PSM, &wl->flags) ||
- test_bit(WL1271_FLAG_IDLE, &wl->flags)) {
- cancel_delayed_work(&wl->elp_work);
- ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
- msecs_to_jiffies(ELP_ENTRY_DELAY));
- }
+ /* we shouldn't get consecutive sleep requests */
+ if (WARN_ON(test_and_set_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags)))
+ return;
+
+ if (!test_bit(WL1271_FLAG_PSM, &wl->flags) &&
+ !test_bit(WL1271_FLAG_IDLE, &wl->flags))
+ return;
+
+ ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
+ msecs_to_jiffies(ELP_ENTRY_DELAY));
}
int wl1271_ps_elp_wakeup(struct wl1271 *wl)
@@ -77,6 +85,16 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl)
u32 start_time = jiffies;
bool pending = false;
+ /*
+ * we might try to wake up even if we didn't go to sleep
+ * before (e.g. on boot)
+ */
+ if (!test_and_clear_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags))
+ return 0;
+
+ /* don't cancel_sync as it might contend for a mutex and deadlock */
+ cancel_delayed_work(&wl->elp_work);
+
if (!test_bit(WL1271_FLAG_IN_ELP, &wl->flags))
return 0;
@@ -149,9 +167,6 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
case STATION_ACTIVE_MODE:
default:
wl1271_debug(DEBUG_PSM, "leaving psm");
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- return ret;
/* disable beacon early termination */
ret = wl1271_acx_bet_enable(wl, false);
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h
index c41bd0a711b..25eb9bc9b62 100644
--- a/drivers/net/wireless/wl12xx/ps.h
+++ b/drivers/net/wireless/wl12xx/ps.h
@@ -35,4 +35,6 @@ void wl1271_elp_work(struct work_struct *work);
void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues);
void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid);
+#define WL1271_PS_COMPLETE_TIMEOUT 500
+
#endif /* __WL1271_PS_H__ */
diff --git a/drivers/net/wireless/wl12xx/reg.h b/drivers/net/wireless/wl12xx/reg.h
index 99096077152..440a4ee9cb4 100644
--- a/drivers/net/wireless/wl12xx/reg.h
+++ b/drivers/net/wireless/wl12xx/reg.h
@@ -207,6 +207,8 @@
#define CHIP_ID_1271_PG10 (0x4030101)
#define CHIP_ID_1271_PG20 (0x4030111)
+#define CHIP_ID_1283_PG10 (0x05030101)
+#define CHIP_ID_1283_PG20 (0x05030111)
#define ENABLE (REGISTERS_BASE + 0x5450)
@@ -452,24 +454,11 @@
#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200
#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400
-/*
- * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile
- * for platforms using active high interrupt level
- */
-#ifdef USE_ACTIVE_HIGH
#define HI_CFG_DEF_VAL \
(HI_CFG_UART_ENABLE | \
HI_CFG_RST232_ENABLE | \
HI_CFG_CLOCK_REQ_SELECT | \
HI_CFG_HOST_INT_ENABLE)
-#else
-#define HI_CFG_DEF_VAL \
- (HI_CFG_UART_ENABLE | \
- HI_CFG_RST232_ENABLE | \
- HI_CFG_CLOCK_REQ_SELECT | \
- HI_CFG_HOST_INT_ENABLE)
-
-#endif
#define REF_FREQ_19_2 0
#define REF_FREQ_26_0 1
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
index 919b59f0030..70091035e01 100644
--- a/drivers/net/wireless/wl12xx/rx.c
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -48,18 +48,14 @@ static void wl1271_rx_status(struct wl1271 *wl,
struct ieee80211_rx_status *status,
u8 beacon)
{
- enum ieee80211_band desc_band;
-
memset(status, 0, sizeof(struct ieee80211_rx_status));
- status->band = wl->band;
-
if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == WL1271_RX_DESC_BAND_BG)
- desc_band = IEEE80211_BAND_2GHZ;
+ status->band = IEEE80211_BAND_2GHZ;
else
- desc_band = IEEE80211_BAND_5GHZ;
+ status->band = IEEE80211_BAND_5GHZ;
- status->rate_idx = wl1271_rate_to_idx(desc->rate, desc_band);
+ status->rate_idx = wl1271_rate_to_idx(desc->rate, status->band);
#ifdef CONFIG_WL12XX_HT
/* 11n support */
@@ -76,15 +72,19 @@ static void wl1271_rx_status(struct wl1271 *wl,
*/
wl->noise = desc->rssi - (desc->snr >> 1);
- status->freq = ieee80211_channel_to_frequency(desc->channel, desc_band);
+ status->freq = ieee80211_channel_to_frequency(desc->channel,
+ status->band);
if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
- status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
+ u8 desc_err_code = desc->status & WL1271_RX_DESC_STATUS_MASK;
+
+ status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED |
+ RX_FLAG_DECRYPTED;
- if (likely(!(desc->status & WL1271_RX_DESC_DECRYPT_FAIL)))
- status->flag |= RX_FLAG_DECRYPTED;
- if (unlikely(desc->status & WL1271_RX_DESC_MIC_FAIL))
+ if (unlikely(desc_err_code == WL1271_RX_DESC_MIC_FAIL)) {
status->flag |= RX_FLAG_MMIC_ERROR;
+ wl1271_warning("Michael MIC error");
+ }
}
}
@@ -103,6 +103,25 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
if (unlikely(wl->state == WL1271_STATE_PLT))
return -EINVAL;
+ /* the data read starts with the descriptor */
+ desc = (struct wl1271_rx_descriptor *) data;
+
+ switch (desc->status & WL1271_RX_DESC_STATUS_MASK) {
+ /* discard corrupted packets */
+ case WL1271_RX_DESC_DRIVER_RX_Q_FAIL:
+ case WL1271_RX_DESC_DECRYPT_FAIL:
+ wl1271_warning("corrupted packet in RX with status: 0x%x",
+ desc->status & WL1271_RX_DESC_STATUS_MASK);
+ return -EINVAL;
+ case WL1271_RX_DESC_SUCCESS:
+ case WL1271_RX_DESC_MIC_FAIL:
+ break;
+ default:
+ wl1271_error("invalid RX descriptor status: 0x%x",
+ desc->status & WL1271_RX_DESC_STATUS_MASK);
+ return -EINVAL;
+ }
+
skb = __dev_alloc_skb(length, GFP_KERNEL);
if (!skb) {
wl1271_error("Couldn't allocate RX frame");
@@ -112,9 +131,6 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
buf = skb_put(skb, length);
memcpy(buf, data, length);
- /* the data read starts with the descriptor */
- desc = (struct wl1271_rx_descriptor *) buf;
-
/* now we pull the descriptor out of the buffer */
skb_pull(skb, sizeof(*desc));
@@ -124,7 +140,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon);
- wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
+ wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb,
+ skb->len - desc->pad_len,
beacon ? "beacon" : "");
skb_trim(skb, skb->len - desc->pad_len);
@@ -163,18 +180,25 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
break;
}
- /*
- * Choose the block we want to read
- * For aggregated packets, only the first memory block should
- * be retrieved. The FW takes care of the rest.
- */
- mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter);
- wl->rx_mem_pool_addr.addr = (mem_block << 8) +
- le32_to_cpu(wl_mem_map->packet_memory_pool_start);
- wl->rx_mem_pool_addr.addr_extra =
- wl->rx_mem_pool_addr.addr + 4;
- wl1271_write(wl, WL1271_SLV_REG_DATA, &wl->rx_mem_pool_addr,
- sizeof(wl->rx_mem_pool_addr), false);
+ if (wl->chip.id != CHIP_ID_1283_PG20) {
+ /*
+ * Choose the block we want to read
+ * For aggregated packets, only the first memory block
+ * should be retrieved. The FW takes care of the rest.
+ */
+ mem_block = wl1271_rx_get_mem_block(status,
+ drv_rx_counter);
+
+ wl->rx_mem_pool_addr.addr = (mem_block << 8) +
+ le32_to_cpu(wl_mem_map->packet_memory_pool_start);
+
+ wl->rx_mem_pool_addr.addr_extra =
+ wl->rx_mem_pool_addr.addr + 4;
+
+ wl1271_write(wl, WL1271_SLV_REG_DATA,
+ &wl->rx_mem_pool_addr,
+ sizeof(wl->rx_mem_pool_addr), false);
+ }
/* Read all available packets at once */
wl1271_read(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c
index 420653a2859..f37e5a39197 100644
--- a/drivers/net/wireless/wl12xx/scan.c
+++ b/drivers/net/wireless/wl12xx/scan.c
@@ -48,8 +48,7 @@ void wl1271_scan_complete_work(struct work_struct *work)
goto out;
wl->scan.state = WL1271_SCAN_STATE_IDLE;
- kfree(wl->scan.scanned_ch);
- wl->scan.scanned_ch = NULL;
+ memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
wl->scan.req = NULL;
ieee80211_scan_completed(wl->hw, false);
@@ -87,7 +86,7 @@ static int wl1271_get_scan_channels(struct wl1271 *wl,
flags = req->channels[i]->flags;
- if (!wl->scan.scanned_ch[i] &&
+ if (!test_bit(i, wl->scan.scanned_ch) &&
!(flags & IEEE80211_CHAN_DISABLED) &&
((!!(flags & IEEE80211_CHAN_PASSIVE_SCAN)) == passive) &&
(req->channels[i]->band == band)) {
@@ -124,7 +123,7 @@ static int wl1271_get_scan_channels(struct wl1271 *wl,
memset(&channels[j].bssid_msb, 0xff, 2);
/* Mark the channels we already used */
- wl->scan.scanned_ch[i] = true;
+ set_bit(i, wl->scan.scanned_ch);
j++;
}
@@ -291,6 +290,12 @@ void wl1271_scan_stm(struct wl1271 *wl)
int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
struct cfg80211_scan_request *req)
{
+ /*
+ * cfg80211 should guarantee that we don't get more channels
+ * than what we have registered.
+ */
+ BUG_ON(req->n_channels > WL1271_MAX_CHANNELS);
+
if (wl->scan.state != WL1271_SCAN_STATE_IDLE)
return -EBUSY;
@@ -304,10 +309,8 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
}
wl->scan.req = req;
+ memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
- wl->scan.scanned_ch = kcalloc(req->n_channels,
- sizeof(*wl->scan.scanned_ch),
- GFP_KERNEL);
/* we assume failure so that timeout scenarios are handled correctly */
wl->scan.failed = true;
ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
@@ -317,3 +320,246 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
return 0;
}
+
+static int
+wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
+ struct cfg80211_sched_scan_request *req,
+ struct conn_scan_ch_params *channels,
+ u32 band, bool radar, bool passive,
+ int start)
+{
+ struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
+ int i, j;
+ u32 flags;
+
+ for (i = 0, j = start;
+ i < req->n_channels && j < MAX_CHANNELS_ALL_BANDS;
+ i++) {
+ flags = req->channels[i]->flags;
+
+ if (!(flags & IEEE80211_CHAN_DISABLED) &&
+ ((flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive) &&
+ ((flags & IEEE80211_CHAN_RADAR) == radar) &&
+ (req->channels[i]->band == band)) {
+ wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
+ req->channels[i]->band,
+ req->channels[i]->center_freq);
+ wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X",
+ req->channels[i]->hw_value,
+ req->channels[i]->flags);
+ wl1271_debug(DEBUG_SCAN, "max_power %d",
+ req->channels[i]->max_power);
+
+ if (flags & IEEE80211_CHAN_PASSIVE_SCAN) {
+ channels[j].passive_duration =
+ cpu_to_le16(c->dwell_time_passive);
+ } else {
+ channels[j].min_duration =
+ cpu_to_le16(c->min_dwell_time_active);
+ channels[j].max_duration =
+ cpu_to_le16(c->max_dwell_time_active);
+ }
+ channels[j].tx_power_att = req->channels[j]->max_power;
+ channels[j].channel = req->channels[i]->hw_value;
+
+ j++;
+ }
+ }
+
+ return j - start;
+}
+
+static int
+wl1271_scan_sched_scan_channels(struct wl1271 *wl,
+ struct cfg80211_sched_scan_request *req,
+ struct wl1271_cmd_sched_scan_config *cfg)
+{
+ int idx = 0;
+
+ cfg->passive[0] =
+ wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
+ IEEE80211_BAND_2GHZ,
+ false, true, idx);
+ idx += cfg->passive[0];
+
+ cfg->active[0] =
+ wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
+ IEEE80211_BAND_2GHZ,
+ false, false, idx);
+ idx += cfg->active[0];
+
+ cfg->passive[1] =
+ wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
+ IEEE80211_BAND_5GHZ,
+ false, true, idx);
+ idx += cfg->passive[1];
+
+ cfg->active[1] =
+ wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
+ IEEE80211_BAND_5GHZ,
+ false, false, 14);
+ idx += cfg->active[1];
+
+ cfg->dfs =
+ wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
+ IEEE80211_BAND_5GHZ,
+ true, false, idx);
+ idx += cfg->dfs;
+
+ wl1271_debug(DEBUG_SCAN, " 2.4GHz: active %d passive %d",
+ cfg->active[0], cfg->passive[0]);
+ wl1271_debug(DEBUG_SCAN, " 5GHz: active %d passive %d",
+ cfg->active[1], cfg->passive[1]);
+
+ return idx;
+}
+
+int wl1271_scan_sched_scan_config(struct wl1271 *wl,
+ struct cfg80211_sched_scan_request *req,
+ struct ieee80211_sched_scan_ies *ies)
+{
+ struct wl1271_cmd_sched_scan_config *cfg = NULL;
+ struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
+ int i, total_channels, ret;
+
+ wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config");
+
+ cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+ if (!cfg)
+ return -ENOMEM;
+
+ cfg->rssi_threshold = c->rssi_threshold;
+ cfg->snr_threshold = c->snr_threshold;
+ cfg->n_probe_reqs = c->num_probe_reqs;
+ /* cycles set to 0 it means infinite (until manually stopped) */
+ cfg->cycles = 0;
+ /* report APs when at least 1 is found */
+ cfg->report_after = 1;
+ /* don't stop scanning automatically when something is found */
+ cfg->terminate = 0;
+ cfg->tag = WL1271_SCAN_DEFAULT_TAG;
+ /* don't filter on BSS type */
+ cfg->bss_type = SCAN_BSS_TYPE_ANY;
+ /* currently NL80211 supports only a single interval */
+ for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++)
+ cfg->intervals[i] = cpu_to_le32(req->interval);
+
+ if (req->ssids[0].ssid_len && req->ssids[0].ssid) {
+ cfg->filter_type = SCAN_SSID_FILTER_SPECIFIC;
+ cfg->ssid_len = req->ssids[0].ssid_len;
+ memcpy(cfg->ssid, req->ssids[0].ssid,
+ req->ssids[0].ssid_len);
+ } else {
+ cfg->filter_type = SCAN_SSID_FILTER_ANY;
+ cfg->ssid_len = 0;
+ }
+
+ total_channels = wl1271_scan_sched_scan_channels(wl, req, cfg);
+ if (total_channels == 0) {
+ wl1271_error("scan channel list is empty");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (cfg->active[0]) {
+ ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid,
+ req->ssids[0].ssid_len,
+ ies->ie[IEEE80211_BAND_2GHZ],
+ ies->len[IEEE80211_BAND_2GHZ],
+ IEEE80211_BAND_2GHZ);
+ if (ret < 0) {
+ wl1271_error("2.4GHz PROBE request template failed");
+ goto out;
+ }
+ }
+
+ if (cfg->active[1]) {
+ ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid,
+ req->ssids[0].ssid_len,
+ ies->ie[IEEE80211_BAND_5GHZ],
+ ies->len[IEEE80211_BAND_5GHZ],
+ IEEE80211_BAND_5GHZ);
+ if (ret < 0) {
+ wl1271_error("5GHz PROBE request template failed");
+ goto out;
+ }
+ }
+
+ wl1271_dump(DEBUG_SCAN, "SCAN_CFG: ", cfg, sizeof(*cfg));
+
+ ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_CFG, cfg,
+ sizeof(*cfg), 0);
+ if (ret < 0) {
+ wl1271_error("SCAN configuration failed");
+ goto out;
+ }
+out:
+ kfree(cfg);
+ return ret;
+}
+
+int wl1271_scan_sched_scan_start(struct wl1271 *wl)
+{
+ struct wl1271_cmd_sched_scan_start *start;
+ int ret = 0;
+
+ wl1271_debug(DEBUG_CMD, "cmd periodic scan start");
+
+ if (wl->bss_type != BSS_TYPE_STA_BSS)
+ return -EOPNOTSUPP;
+
+ if (!test_bit(WL1271_FLAG_IDLE, &wl->flags))
+ return -EBUSY;
+
+ start = kzalloc(sizeof(*start), GFP_KERNEL);
+ if (!start)
+ return -ENOMEM;
+
+ start->tag = WL1271_SCAN_DEFAULT_TAG;
+
+ ret = wl1271_cmd_send(wl, CMD_START_PERIODIC_SCAN, start,
+ sizeof(*start), 0);
+ if (ret < 0) {
+ wl1271_error("failed to send scan start command");
+ goto out_free;
+ }
+
+out_free:
+ kfree(start);
+ return ret;
+}
+
+void wl1271_scan_sched_scan_results(struct wl1271 *wl)
+{
+ wl1271_debug(DEBUG_SCAN, "got periodic scan results");
+
+ ieee80211_sched_scan_results(wl->hw);
+}
+
+void wl1271_scan_sched_scan_stop(struct wl1271 *wl)
+{
+ struct wl1271_cmd_sched_scan_stop *stop;
+ int ret = 0;
+
+ wl1271_debug(DEBUG_CMD, "cmd periodic scan stop");
+
+ /* FIXME: what to do if alloc'ing to stop fails? */
+ stop = kzalloc(sizeof(*stop), GFP_KERNEL);
+ if (!stop) {
+ wl1271_error("failed to alloc memory to send sched scan stop");
+ return;
+ }
+
+ stop->tag = WL1271_SCAN_DEFAULT_TAG;
+
+ ret = wl1271_cmd_send(wl, CMD_STOP_PERIODIC_SCAN, stop,
+ sizeof(*stop), 0);
+ if (ret < 0) {
+ wl1271_error("failed to send sched scan stop command");
+ goto out_free;
+ }
+ wl->sched_scanning = false;
+
+out_free:
+ kfree(stop);
+}
diff --git a/drivers/net/wireless/wl12xx/scan.h b/drivers/net/wireless/wl12xx/scan.h
index 421a750add5..c83319579ca 100644
--- a/drivers/net/wireless/wl12xx/scan.h
+++ b/drivers/net/wireless/wl12xx/scan.h
@@ -33,6 +33,12 @@ int wl1271_scan_build_probe_req(struct wl1271 *wl,
const u8 *ie, size_t ie_len, u8 band);
void wl1271_scan_stm(struct wl1271 *wl);
void wl1271_scan_complete_work(struct work_struct *work);
+int wl1271_scan_sched_scan_config(struct wl1271 *wl,
+ struct cfg80211_sched_scan_request *req,
+ struct ieee80211_sched_scan_ies *ies);
+int wl1271_scan_sched_scan_start(struct wl1271 *wl);
+void wl1271_scan_sched_scan_stop(struct wl1271 *wl);
+void wl1271_scan_sched_scan_results(struct wl1271 *wl);
#define WL1271_SCAN_MAX_CHANNELS 24
#define WL1271_SCAN_DEFAULT_TAG 1
@@ -106,4 +112,112 @@ struct wl1271_cmd_trigger_scan_to {
__le32 timeout;
} __packed;
+#define MAX_CHANNELS_ALL_BANDS 41
+#define SCAN_MAX_CYCLE_INTERVALS 16
+#define SCAN_MAX_BANDS 3
+
+enum {
+ SCAN_CHANNEL_TYPE_2GHZ_PASSIVE,
+ SCAN_CHANNEL_TYPE_2GHZ_ACTIVE,
+ SCAN_CHANNEL_TYPE_5GHZ_PASSIVE,
+ SCAN_CHANNEL_TYPE_5GHZ_ACTIVE,
+ SCAN_CHANNEL_TYPE_5GHZ_DFS,
+};
+
+enum {
+ SCAN_SSID_FILTER_ANY = 0,
+ SCAN_SSID_FILTER_SPECIFIC = 1,
+ SCAN_SSID_FILTER_LIST = 2,
+ SCAN_SSID_FILTER_DISABLED = 3
+};
+
+enum {
+ SCAN_BSS_TYPE_INDEPENDENT,
+ SCAN_BSS_TYPE_INFRASTRUCTURE,
+ SCAN_BSS_TYPE_ANY,
+};
+
+struct conn_scan_ch_params {
+ __le16 min_duration;
+ __le16 max_duration;
+ __le16 passive_duration;
+
+ u8 channel;
+ u8 tx_power_att;
+
+ /* bit 0: DFS channel; bit 1: DFS enabled */
+ u8 flags;
+
+ u8 padding[3];
+} __packed;
+
+struct wl1271_cmd_sched_scan_config {
+ struct wl1271_cmd_header header;
+
+ __le32 intervals[SCAN_MAX_CYCLE_INTERVALS];
+
+ s8 rssi_threshold; /* for filtering (in dBm) */
+ s8 snr_threshold; /* for filtering (in dB) */
+
+ u8 cycles; /* maximum number of scan cycles */
+ u8 report_after; /* report when this number of results are received */
+ u8 terminate; /* stop scanning after reporting */
+
+ u8 tag;
+ u8 bss_type; /* for filtering */
+ u8 filter_type;
+
+ u8 ssid_len; /* For SCAN_SSID_FILTER_SPECIFIC */
+ u8 ssid[IW_ESSID_MAX_SIZE];
+
+ u8 n_probe_reqs; /* Number of probes requests per channel */
+
+ u8 passive[SCAN_MAX_BANDS];
+ u8 active[SCAN_MAX_BANDS];
+
+ u8 dfs;
+
+ u8 padding[3];
+
+ struct conn_scan_ch_params channels[MAX_CHANNELS_ALL_BANDS];
+} __packed;
+
+
+#define SCHED_SCAN_MAX_SSIDS 8
+
+enum {
+ SCAN_SSID_TYPE_PUBLIC = 0,
+ SCAN_SSID_TYPE_HIDDEN = 1,
+};
+
+struct wl1271_ssid {
+ u8 type;
+ u8 len;
+ u8 ssid[IW_ESSID_MAX_SIZE];
+ /* u8 padding[2]; */
+} __packed;
+
+struct wl1271_cmd_sched_scan_ssid_list {
+ struct wl1271_cmd_header header;
+
+ u8 n_ssids;
+ struct wl1271_ssid ssids[SCHED_SCAN_MAX_SSIDS];
+ u8 padding[3];
+} __packed;
+
+struct wl1271_cmd_sched_scan_start {
+ struct wl1271_cmd_header header;
+
+ u8 tag;
+ u8 padding[3];
+} __packed;
+
+struct wl1271_cmd_sched_scan_stop {
+ struct wl1271_cmd_header header;
+
+ u8 tag;
+ u8 padding[3];
+} __packed;
+
+
#endif /* __WL1271_SCAN_H__ */
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c
index b1c7d031c39..536e5065454 100644
--- a/drivers/net/wireless/wl12xx/sdio.c
+++ b/drivers/net/wireless/wl12xx/sdio.c
@@ -51,6 +51,13 @@ static const struct sdio_device_id wl1271_devices[] = {
};
MODULE_DEVICE_TABLE(sdio, wl1271_devices);
+static void wl1271_sdio_set_block_size(struct wl1271 *wl, unsigned int blksz)
+{
+ sdio_claim_host(wl->if_priv);
+ sdio_set_block_size(wl->if_priv, blksz);
+ sdio_release_host(wl->if_priv);
+}
+
static inline struct sdio_func *wl_to_func(struct wl1271 *wl)
{
return wl->if_priv;
@@ -75,6 +82,16 @@ static irqreturn_t wl1271_hardirq(int irq, void *cookie)
complete(wl->elp_compl);
wl->elp_compl = NULL;
}
+
+ if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) {
+ /* don't enqueue a work right now. mark it as pending */
+ set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags);
+ wl1271_debug(DEBUG_IRQ, "should not enqueue work");
+ disable_irq_nosync(wl->irq);
+ pm_wakeup_event(wl1271_sdio_wl_to_dev(wl), 0);
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
+ return IRQ_HANDLED;
+ }
spin_unlock_irqrestore(&wl->wl_lock, flags);
return IRQ_WAKE_THREAD;
@@ -203,7 +220,8 @@ static struct wl1271_if_operations sdio_ops = {
.power = wl1271_sdio_set_power,
.dev = wl1271_sdio_wl_to_dev,
.enable_irq = wl1271_sdio_enable_interrupts,
- .disable_irq = wl1271_sdio_disable_interrupts
+ .disable_irq = wl1271_sdio_disable_interrupts,
+ .set_block_size = wl1271_sdio_set_block_size,
};
static int __devinit wl1271_probe(struct sdio_func *func,
@@ -212,6 +230,8 @@ static int __devinit wl1271_probe(struct sdio_func *func,
struct ieee80211_hw *hw;
const struct wl12xx_platform_data *wlan_data;
struct wl1271 *wl;
+ unsigned long irqflags;
+ mmc_pm_flag_t mmcflags;
int ret;
/* We are only able to handle the wlan function */
@@ -230,6 +250,9 @@ static int __devinit wl1271_probe(struct sdio_func *func,
/* Grab access to FN0 for ELP reg. */
func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
+ /* Use block mode for transferring over one block size of data */
+ func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+
wlan_data = wl12xx_get_platform_data();
if (IS_ERR(wlan_data)) {
ret = PTR_ERR(wlan_data);
@@ -239,17 +262,34 @@ static int __devinit wl1271_probe(struct sdio_func *func,
wl->irq = wlan_data->irq;
wl->ref_clock = wlan_data->board_ref_clock;
+ wl->tcxo_clock = wlan_data->board_tcxo_clock;
+ wl->platform_quirks = wlan_data->platform_quirks;
+
+ if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
+ irqflags = IRQF_TRIGGER_RISING;
+ else
+ irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq,
- IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ irqflags,
DRIVER_NAME, wl);
if (ret < 0) {
wl1271_error("request_irq() failed: %d", ret);
goto out_free;
}
+ enable_irq_wake(wl->irq);
+ device_init_wakeup(wl1271_sdio_wl_to_dev(wl), 1);
+
disable_irq(wl->irq);
+ /* if sdio can keep power while host is suspended, enable wow */
+ mmcflags = sdio_get_host_pm_caps(func);
+ wl1271_debug(DEBUG_SDIO, "sdio PM caps = 0x%x", mmcflags);
+
+ if (mmcflags & MMC_PM_KEEP_POWER)
+ hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;
+
ret = wl1271_init_ieee80211(wl);
if (ret)
goto out_irq;
@@ -284,19 +324,61 @@ static void __devexit wl1271_remove(struct sdio_func *func)
pm_runtime_get_noresume(&func->dev);
wl1271_unregister_hw(wl);
+ device_init_wakeup(wl1271_sdio_wl_to_dev(wl), 0);
+ disable_irq_wake(wl->irq);
free_irq(wl->irq, wl);
wl1271_free_hw(wl);
}
+#ifdef CONFIG_PM
static int wl1271_suspend(struct device *dev)
{
/* Tell MMC/SDIO core it's OK to power down the card
* (if it isn't already), but not to remove it completely */
- return 0;
+ struct sdio_func *func = dev_to_sdio_func(dev);
+ struct wl1271 *wl = sdio_get_drvdata(func);
+ mmc_pm_flag_t sdio_flags;
+ int ret = 0;
+
+ wl1271_debug(DEBUG_MAC80211, "wl1271 suspend. wow_enabled: %d",
+ wl->wow_enabled);
+
+ /* check whether sdio should keep power */
+ if (wl->wow_enabled) {
+ sdio_flags = sdio_get_host_pm_caps(func);
+
+ if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
+ wl1271_error("can't keep power while host "
+ "is suspended");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* keep power while host suspended */
+ ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+ if (ret) {
+ wl1271_error("error while trying to keep power");
+ goto out;
+ }
+
+ /* release host */
+ sdio_release_host(func);
+ }
+out:
+ return ret;
}
static int wl1271_resume(struct device *dev)
{
+ struct sdio_func *func = dev_to_sdio_func(dev);
+ struct wl1271 *wl = sdio_get_drvdata(func);
+
+ wl1271_debug(DEBUG_MAC80211, "wl1271 resume");
+ if (wl->wow_enabled) {
+ /* claim back host */
+ sdio_claim_host(func);
+ }
+
return 0;
}
@@ -304,15 +386,18 @@ static const struct dev_pm_ops wl1271_sdio_pm_ops = {
.suspend = wl1271_suspend,
.resume = wl1271_resume,
};
+#endif
static struct sdio_driver wl1271_sdio_driver = {
.name = "wl1271_sdio",
.id_table = wl1271_devices,
.probe = wl1271_probe,
.remove = __devexit_p(wl1271_remove),
+#ifdef CONFIG_PM
.drv = {
.pm = &wl1271_sdio_pm_ops,
},
+#endif
};
static int __init wl1271_init(void)
@@ -343,4 +428,6 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
MODULE_FIRMWARE(WL1271_FW_NAME);
-MODULE_FIRMWARE(WL1271_AP_FW_NAME);
+MODULE_FIRMWARE(WL128X_FW_NAME);
+MODULE_FIRMWARE(WL127X_AP_FW_NAME);
+MODULE_FIRMWARE(WL128X_AP_FW_NAME);
diff --git a/drivers/net/wireless/wl12xx/sdio_test.c b/drivers/net/wireless/wl12xx/sdio_test.c
index 9fcbd3dd849..f2891539287 100644
--- a/drivers/net/wireless/wl12xx/sdio_test.c
+++ b/drivers/net/wireless/wl12xx/sdio_test.c
@@ -189,7 +189,12 @@ static int wl1271_fetch_firmware(struct wl1271 *wl)
const struct firmware *fw;
int ret;
- ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl));
+ if (wl->chip.id == CHIP_ID_1283_PG20)
+ ret = request_firmware(&fw, WL128X_FW_NAME,
+ wl1271_wl_to_dev(wl));
+ else
+ ret = request_firmware(&fw, WL1271_FW_NAME,
+ wl1271_wl_to_dev(wl));
if (ret < 0) {
wl1271_error("could not get firmware: %d", ret);
@@ -227,14 +232,14 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
const struct firmware *fw;
int ret;
- ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl));
+ ret = request_firmware(&fw, WL12XX_NVS_NAME, wl1271_wl_to_dev(wl));
if (ret < 0) {
wl1271_error("could not get nvs file: %d", ret);
return ret;
}
- wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL);
+ wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL);
if (!wl->nvs) {
wl1271_error("could not allocate memory for the nvs file");
@@ -288,6 +293,11 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
wl1271_notice("chip id 0x%x (1271 PG20)",
wl->chip.id);
break;
+ case CHIP_ID_1283_PG20:
+ wl1271_notice("chip id 0x%x (1283 PG20)",
+ wl->chip.id);
+ break;
+ case CHIP_ID_1283_PG10:
default:
wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
return -ENODEV;
@@ -407,6 +417,9 @@ static int __devinit wl1271_probe(struct sdio_func *func,
/* Grab access to FN0 for ELP reg. */
func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
+ /* Use block mode for transferring over one block size of data */
+ func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+
wlan_data = wl12xx_get_platform_data();
if (IS_ERR(wlan_data)) {
ret = PTR_ERR(wlan_data);
@@ -416,6 +429,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,
wl->irq = wlan_data->irq;
wl->ref_clock = wlan_data->board_ref_clock;
+ wl->tcxo_clock = wlan_data->board_tcxo_clock;
sdio_set_drvdata(func, wl_test);
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c
index ffc745b17f4..51662bb6801 100644
--- a/drivers/net/wireless/wl12xx/spi.c
+++ b/drivers/net/wireless/wl12xx/spi.c
@@ -355,7 +355,8 @@ static struct wl1271_if_operations spi_ops = {
.power = wl1271_spi_set_power,
.dev = wl1271_spi_wl_to_dev,
.enable_irq = wl1271_spi_enable_interrupts,
- .disable_irq = wl1271_spi_disable_interrupts
+ .disable_irq = wl1271_spi_disable_interrupts,
+ .set_block_size = NULL,
};
static int __devinit wl1271_probe(struct spi_device *spi)
@@ -363,6 +364,7 @@ static int __devinit wl1271_probe(struct spi_device *spi)
struct wl12xx_platform_data *pdata;
struct ieee80211_hw *hw;
struct wl1271 *wl;
+ unsigned long irqflags;
int ret;
pdata = spi->dev.platform_data;
@@ -400,6 +402,13 @@ static int __devinit wl1271_probe(struct spi_device *spi)
}
wl->ref_clock = pdata->board_ref_clock;
+ wl->tcxo_clock = pdata->board_tcxo_clock;
+ wl->platform_quirks = pdata->platform_quirks;
+
+ if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
+ irqflags = IRQF_TRIGGER_RISING;
+ else
+ irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
wl->irq = spi->irq;
if (wl->irq < 0) {
@@ -409,7 +418,7 @@ static int __devinit wl1271_probe(struct spi_device *spi)
}
ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq,
- IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ irqflags,
DRIVER_NAME, wl);
if (ret < 0) {
wl1271_error("request_irq() failed: %d", ret);
@@ -490,5 +499,7 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
MODULE_FIRMWARE(WL1271_FW_NAME);
-MODULE_FIRMWARE(WL1271_AP_FW_NAME);
+MODULE_FIRMWARE(WL128X_FW_NAME);
+MODULE_FIRMWARE(WL127X_AP_FW_NAME);
+MODULE_FIRMWARE(WL128X_AP_FW_NAME);
MODULE_ALIAS("spi:wl1271");
diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c
index 6ec06a4a4c6..da351d7cd1f 100644
--- a/drivers/net/wireless/wl12xx/testmode.c
+++ b/drivers/net/wireless/wl12xx/testmode.c
@@ -27,6 +27,7 @@
#include "wl12xx.h"
#include "acx.h"
+#include "reg.h"
#define WL1271_TM_MAX_DATA_LENGTH 1024
@@ -204,7 +205,10 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
kfree(wl->nvs);
- if (len != sizeof(struct wl1271_nvs_file))
+ if ((wl->chip.id == CHIP_ID_1283_PG20) &&
+ (len != sizeof(struct wl128x_nvs_file)))
+ return -EINVAL;
+ else if (len != sizeof(struct wl1271_nvs_file))
return -EINVAL;
wl->nvs = kzalloc(len, GFP_KERNEL);
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index 5e9ef7d53e7..ca3ab1c1ace 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -65,11 +65,36 @@ static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb)
static void wl1271_free_tx_id(struct wl1271 *wl, int id)
{
if (__test_and_clear_bit(id, wl->tx_frames_map)) {
+ if (unlikely(wl->tx_frames_cnt == ACX_TX_DESCRIPTORS))
+ clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
+
wl->tx_frames[id] = NULL;
wl->tx_frames_cnt--;
}
}
+static int wl1271_tx_update_filters(struct wl1271 *wl,
+ struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr;
+
+ hdr = (struct ieee80211_hdr *)(skb->data +
+ sizeof(struct wl1271_tx_hw_descr));
+
+ /*
+ * stop bssid-based filtering before transmitting authentication
+ * requests. this way the hw will never drop authentication
+ * responses coming from BSSIDs it isn't familiar with (e.g. on
+ * roaming)
+ */
+ if (!ieee80211_is_auth(hdr->frame_control))
+ return 0;
+
+ wl1271_configure_filters(wl, FIF_OTHER_BSS);
+
+ return wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter);
+}
+
static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl,
struct sk_buff *skb)
{
@@ -127,13 +152,29 @@ u8 wl1271_tx_get_hlid(struct sk_buff *skb)
}
}
+static unsigned int wl12xx_calc_packet_alignment(struct wl1271 *wl,
+ unsigned int packet_length)
+{
+ if (wl->quirks & WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT)
+ return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE);
+ else
+ return ALIGN(packet_length, WL1271_TX_ALIGN_TO);
+}
+
static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
u32 buf_offset, u8 hlid)
{
struct wl1271_tx_hw_descr *desc;
u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
+ u32 len;
u32 total_blocks;
int id, ret = -EBUSY;
+ u32 spare_blocks;
+
+ if (unlikely(wl->quirks & WL12XX_QUIRK_USE_2_SPARE_BLOCKS))
+ spare_blocks = 2;
+ else
+ spare_blocks = 1;
if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE)
return -EAGAIN;
@@ -145,17 +186,27 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
/* approximate the number of blocks required for this packet
in the firmware */
- total_blocks = total_len + TX_HW_BLOCK_SIZE - 1;
- total_blocks = total_blocks / TX_HW_BLOCK_SIZE + TX_HW_BLOCK_SPARE;
+ len = wl12xx_calc_packet_alignment(wl, total_len);
+
+ total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE +
+ spare_blocks;
+
if (total_blocks <= wl->tx_blocks_available) {
desc = (struct wl1271_tx_hw_descr *)skb_push(
skb, total_len - skb->len);
- desc->extra_mem_blocks = TX_HW_BLOCK_SPARE;
- desc->total_mem_blocks = total_blocks;
+ /* HW descriptor fields change between wl127x and wl128x */
+ if (wl->chip.id == CHIP_ID_1283_PG20) {
+ desc->wl128x_mem.total_mem_blocks = total_blocks;
+ } else {
+ desc->wl127x_mem.extra_blocks = spare_blocks;
+ desc->wl127x_mem.total_mem_blocks = total_blocks;
+ }
+
desc->id = id;
wl->tx_blocks_available -= total_blocks;
+ wl->tx_allocated_blocks += total_blocks;
if (wl->bss_type == BSS_TYPE_AP_BSS)
wl->links[hlid].allocated_blks += total_blocks;
@@ -172,13 +223,18 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
return ret;
}
+static bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb)
+{
+ return wl->dummy_packet == skb;
+}
+
static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
u32 extra, struct ieee80211_tx_info *control,
u8 hlid)
{
struct timespec ts;
struct wl1271_tx_hw_descr *desc;
- int pad, ac, rate_idx;
+ int aligned_len, ac, rate_idx;
s64 hosttime;
u16 tx_attr;
@@ -202,12 +258,25 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
else
desc->life_time = cpu_to_le16(TX_HW_AP_MODE_PKT_LIFETIME_TU);
- /* configure the tx attributes */
- tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
-
- /* queue (we use same identifiers for tid's and ac's */
+ /* queue */
ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
- desc->tid = ac;
+ desc->tid = skb->priority;
+
+ if (wl12xx_is_dummy_packet(wl, skb)) {
+ /*
+ * FW expects the dummy packet to have an invalid session id -
+ * any session id that is different than the one set in the join
+ */
+ tx_attr = ((~wl->session_counter) <<
+ TX_HW_ATTR_OFST_SESSION_COUNTER) &
+ TX_HW_ATTR_SESSION_COUNTER;
+
+ tx_attr |= TX_HW_ATTR_TX_DUMMY_REQ;
+ } else {
+ /* configure the tx attributes */
+ tx_attr =
+ wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
+ }
if (wl->bss_type != BSS_TYPE_AP_BSS) {
desc->aid = hlid;
@@ -237,20 +306,37 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY;
desc->reserved = 0;
- /* align the length (and store in terms of words) */
- pad = ALIGN(skb->len, WL1271_TX_ALIGN_TO);
- desc->length = cpu_to_le16(pad >> 2);
+ aligned_len = wl12xx_calc_packet_alignment(wl, skb->len);
- /* calculate number of padding bytes */
- pad = pad - skb->len;
- tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD;
+ if (wl->chip.id == CHIP_ID_1283_PG20) {
+ desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
+ desc->length = cpu_to_le16(aligned_len >> 2);
- desc->tx_attr = cpu_to_le16(tx_attr);
+ wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d "
+ "tx_attr: 0x%x len: %d life: %d mem: %d",
+ desc->hlid, tx_attr,
+ le16_to_cpu(desc->length),
+ le16_to_cpu(desc->life_time),
+ desc->wl128x_mem.total_mem_blocks);
+ } else {
+ int pad;
- wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d hlid: %d "
- "tx_attr: 0x%x len: %d life: %d mem: %d", pad, desc->hlid,
- le16_to_cpu(desc->tx_attr), le16_to_cpu(desc->length),
- le16_to_cpu(desc->life_time), desc->total_mem_blocks);
+ /* Store the aligned length in terms of words */
+ desc->length = cpu_to_le16(aligned_len >> 2);
+
+ /* calculate number of padding bytes */
+ pad = aligned_len - skb->len;
+ tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD;
+
+ wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d hlid: %d "
+ "tx_attr: 0x%x len: %d life: %d mem: %d", pad,
+ desc->hlid, tx_attr,
+ le16_to_cpu(desc->length),
+ le16_to_cpu(desc->life_time),
+ desc->wl127x_mem.total_mem_blocks);
+ }
+
+ desc->tx_attr = cpu_to_le16(tx_attr);
}
/* caller must hold wl->mutex */
@@ -300,19 +386,29 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
if (wl->bss_type == BSS_TYPE_AP_BSS) {
wl1271_tx_ap_update_inconnection_sta(wl, skb);
wl1271_tx_regulate_link(wl, hlid);
+ } else {
+ wl1271_tx_update_filters(wl, skb);
}
wl1271_tx_fill_hdr(wl, skb, extra, info, hlid);
/*
- * The length of each packet is stored in terms of words. Thus, we must
- * pad the skb data to make sure its length is aligned.
- * The number of padding bytes is computed and set in wl1271_tx_fill_hdr
+ * The length of each packet is stored in terms of
+ * words. Thus, we must pad the skb data to make sure its
+ * length is aligned. The number of padding bytes is computed
+ * and set in wl1271_tx_fill_hdr.
+ * In special cases, we want to align to a specific block size
+ * (eg. for wl128x with SDIO we align to 256).
*/
- total_len = ALIGN(skb->len, WL1271_TX_ALIGN_TO);
+ total_len = wl12xx_calc_packet_alignment(wl, skb->len);
+
memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len);
memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len);
+ /* Revert side effects in the dummy packet skb, so it can be reused */
+ if (wl12xx_is_dummy_packet(wl, skb))
+ skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
+
return total_len;
}
@@ -425,10 +521,23 @@ out:
static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
{
+ unsigned long flags;
+ struct sk_buff *skb = NULL;
+
if (wl->bss_type == BSS_TYPE_AP_BSS)
- return wl1271_ap_skb_dequeue(wl);
+ skb = wl1271_ap_skb_dequeue(wl);
+ else
+ skb = wl1271_sta_skb_dequeue(wl);
- return wl1271_sta_skb_dequeue(wl);
+ if (!skb &&
+ test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) {
+ skb = wl->dummy_packet;
+ spin_lock_irqsave(&wl->wl_lock, flags);
+ wl->tx_queue_count--;
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
+ }
+
+ return skb;
}
static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb)
@@ -436,7 +545,9 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb)
unsigned long flags;
int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
- if (wl->bss_type == BSS_TYPE_AP_BSS) {
+ if (wl12xx_is_dummy_packet(wl, skb)) {
+ set_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags);
+ } else if (wl->bss_type == BSS_TYPE_AP_BSS) {
u8 hlid = wl1271_tx_get_hlid(skb);
skb_queue_head(&wl->links[hlid].tx_queue[q], skb);
@@ -454,22 +565,14 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb)
void wl1271_tx_work_locked(struct wl1271 *wl)
{
struct sk_buff *skb;
- bool woken_up = false;
u32 buf_offset = 0;
bool sent_packets = false;
int ret;
if (unlikely(wl->state == WL1271_STATE_OFF))
- goto out;
+ return;
while ((skb = wl1271_skb_dequeue(wl))) {
- if (!woken_up) {
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out_ack;
- woken_up = true;
- }
-
ret = wl1271_prepare_tx_frame(wl, skb, buf_offset);
if (ret == -EAGAIN) {
/*
@@ -516,18 +619,22 @@ out_ack:
wl1271_handle_tx_low_watermark(wl);
}
-
-out:
- if (woken_up)
- wl1271_ps_elp_sleep(wl);
}
void wl1271_tx_work(struct work_struct *work)
{
struct wl1271 *wl = container_of(work, struct wl1271, tx_work);
+ int ret;
mutex_lock(&wl->mutex);
+ ret = wl1271_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out;
+
wl1271_tx_work_locked(wl);
+
+ wl1271_ps_elp_sleep(wl);
+out:
mutex_unlock(&wl->mutex);
}
@@ -549,6 +656,11 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
skb = wl->tx_frames[id];
info = IEEE80211_SKB_CB(skb);
+ if (wl12xx_is_dummy_packet(wl, skb)) {
+ wl1271_free_tx_id(wl, id);
+ return;
+ }
+
/* update the TX status info */
if (result->status == TX_SUCCESS) {
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
@@ -657,8 +769,8 @@ void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
wl1271_handle_tx_low_watermark(wl);
}
-/* caller must hold wl->mutex */
-void wl1271_tx_reset(struct wl1271 *wl)
+/* caller must hold wl->mutex and TX must be stopped */
+void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
{
int i;
struct sk_buff *skb;
@@ -678,10 +790,13 @@ void wl1271_tx_reset(struct wl1271 *wl)
while ((skb = skb_dequeue(&wl->tx_queue[i]))) {
wl1271_debug(DEBUG_TX, "freeing skb 0x%p",
skb);
- info = IEEE80211_SKB_CB(skb);
- info->status.rates[0].idx = -1;
- info->status.rates[0].count = 0;
- ieee80211_tx_status(wl->hw, skb);
+
+ if (!wl12xx_is_dummy_packet(wl, skb)) {
+ info = IEEE80211_SKB_CB(skb);
+ info->status.rates[0].idx = -1;
+ info->status.rates[0].count = 0;
+ ieee80211_tx_status(wl->hw, skb);
+ }
}
}
}
@@ -691,8 +806,10 @@ void wl1271_tx_reset(struct wl1271 *wl)
/*
* Make sure the driver is at a consistent state, in case this
* function is called from a context other than interface removal.
+ * This call will always wake the TX queues.
*/
- wl1271_handle_tx_low_watermark(wl);
+ if (reset_tx_queues)
+ wl1271_handle_tx_low_watermark(wl);
for (i = 0; i < ACX_TX_DESCRIPTORS; i++) {
if (wl->tx_frames[i] == NULL)
@@ -702,21 +819,27 @@ void wl1271_tx_reset(struct wl1271 *wl)
wl1271_free_tx_id(wl, i);
wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
- /* Remove private headers before passing the skb to mac80211 */
- info = IEEE80211_SKB_CB(skb);
- skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
- if (info->control.hw_key &&
- info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
- int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
- memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data,
- hdrlen);
- skb_pull(skb, WL1271_TKIP_IV_SPACE);
- }
+ if (!wl12xx_is_dummy_packet(wl, skb)) {
+ /*
+ * Remove private headers before passing the skb to
+ * mac80211
+ */
+ info = IEEE80211_SKB_CB(skb);
+ skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
+ if (info->control.hw_key &&
+ info->control.hw_key->cipher ==
+ WLAN_CIPHER_SUITE_TKIP) {
+ int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+ memmove(skb->data + WL1271_TKIP_IV_SPACE,
+ skb->data, hdrlen);
+ skb_pull(skb, WL1271_TKIP_IV_SPACE);
+ }
- info->status.rates[0].idx = -1;
- info->status.rates[0].count = 0;
+ info->status.rates[0].idx = -1;
+ info->status.rates[0].count = 0;
- ieee80211_tx_status(wl->hw, skb);
+ ieee80211_tx_status(wl->hw, skb);
+ }
}
}
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h
index 02f07fa66e8..832f9258d67 100644
--- a/drivers/net/wireless/wl12xx/tx.h
+++ b/drivers/net/wireless/wl12xx/tx.h
@@ -25,7 +25,6 @@
#ifndef __TX_H__
#define __TX_H__
-#define TX_HW_BLOCK_SPARE 2
#define TX_HW_BLOCK_SIZE 252
#define TX_HW_MGMT_PKT_LIFETIME_TU 2000
@@ -41,6 +40,7 @@
BIT(8) | BIT(9))
#define TX_HW_ATTR_LAST_WORD_PAD (BIT(10) | BIT(11))
#define TX_HW_ATTR_TX_CMPLT_REQ BIT(12)
+#define TX_HW_ATTR_TX_DUMMY_REQ BIT(13)
#define TX_HW_ATTR_OFST_SAVE_RETRIES 0
#define TX_HW_ATTR_OFST_HEADER_PAD 1
@@ -55,20 +55,60 @@
#define WL1271_TX_ALIGN_TO 4
#define WL1271_TKIP_IV_SPACE 4
+/* Used for management frames and dummy packets */
+#define WL1271_TID_MGMT 7
+
+struct wl127x_tx_mem {
+ /*
+ * Number of extra memory blocks to allocate for this packet
+ * in addition to the number of blocks derived from the packet
+ * length.
+ */
+ u8 extra_blocks;
+ /*
+ * Total number of memory blocks allocated by the host for
+ * this packet. Must be equal or greater than the actual
+ * blocks number allocated by HW.
+ */
+ u8 total_mem_blocks;
+} __packed;
+
+struct wl128x_tx_mem {
+ /*
+ * Total number of memory blocks allocated by the host for
+ * this packet.
+ */
+ u8 total_mem_blocks;
+ /*
+ * Number of extra bytes, at the end of the frame. the host
+ * uses this padding to complete each frame to integer number
+ * of SDIO blocks.
+ */
+ u8 extra_bytes;
+} __packed;
+
+/*
+ * On wl128x based devices, when TX packets are aggregated, each packet
+ * size must be aligned to the SDIO block size. The maximum block size
+ * is bounded by the type of the padded bytes field that is sent to the
+ * FW. Currently the type is u8, so the maximum block size is 256 bytes.
+ */
+#define WL12XX_BUS_BLOCK_SIZE min(512u, \
+ (1u << (8 * sizeof(((struct wl128x_tx_mem *) 0)->extra_bytes))))
+
struct wl1271_tx_hw_descr {
/* Length of packet in words, including descriptor+header+data */
__le16 length;
- /* Number of extra memory blocks to allocate for this packet in
- addition to the number of blocks derived from the packet length */
- u8 extra_mem_blocks;
- /* Total number of memory blocks allocated by the host for this packet.
- Must be equal or greater than the actual blocks number allocated by
- HW!! */
- u8 total_mem_blocks;
+ union {
+ struct wl127x_tx_mem wl127x_mem;
+ struct wl128x_tx_mem wl128x_mem;
+ } __packed;
/* Device time (in us) when the packet arrived to the driver */
__le32 start_time;
- /* Max delay in TUs until transmission. The last device time the
- packet can be transmitted is: startTime+(1024*LifeTime) */
+ /*
+ * Max delay in TUs until transmission. The last device time the
+ * packet can be transmitted is: start_time + (1024 * life_time)
+ */
__le16 life_time;
/* Bitwise fields - see TX_ATTR... definitions above. */
__le16 tx_attr;
@@ -145,7 +185,7 @@ static inline int wl1271_tx_get_queue(int queue)
void wl1271_tx_work(struct work_struct *work);
void wl1271_tx_work_locked(struct wl1271 *wl);
void wl1271_tx_complete(struct wl1271 *wl);
-void wl1271_tx_reset(struct wl1271 *wl);
+void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues);
void wl1271_tx_flush(struct wl1271 *wl);
u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set);
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 86be83e25ec..fbe8f46d123 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -131,9 +131,16 @@ extern u32 wl12xx_debug_level;
#define WL1271_FW_NAME "ti-connectivity/wl1271-fw-2.bin"
-#define WL1271_AP_FW_NAME "ti-connectivity/wl1271-fw-ap.bin"
+#define WL128X_FW_NAME "ti-connectivity/wl128x-fw.bin"
+#define WL127X_AP_FW_NAME "ti-connectivity/wl1271-fw-ap.bin"
+#define WL128X_AP_FW_NAME "ti-connectivity/wl128x-fw-ap.bin"
-#define WL1271_NVS_NAME "ti-connectivity/wl1271-nvs.bin"
+/*
+ * wl127x and wl128x are using the same NVS file name. However, the
+ * ini parameters between them are different. The driver validates
+ * the correct NVS size in wl1271_boot_upload_nvs().
+ */
+#define WL12XX_NVS_NAME "ti-connectivity/wl1271-nvs.bin"
#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff))
@@ -200,13 +207,29 @@ struct wl1271_partition_set {
struct wl1271;
-#define WL12XX_NUM_FW_VER 5
+enum {
+ FW_VER_CHIP,
+ FW_VER_IF_TYPE,
+ FW_VER_MAJOR,
+ FW_VER_SUBTYPE,
+ FW_VER_MINOR,
+
+ NUM_FW_VER
+};
+
+#define FW_VER_CHIP_WL127X 6
+#define FW_VER_CHIP_WL128X 7
+
+#define FW_VER_IF_TYPE_STA 1
+#define FW_VER_IF_TYPE_AP 2
+
+#define FW_VER_MINOR_1_SPARE_STA_MIN 58
+#define FW_VER_MINOR_1_SPARE_AP_MIN 47
-/* FIXME: I'm not sure about this structure name */
struct wl1271_chip {
u32 id;
char fw_ver_str[ETHTOOL_BUSINFO_LEN];
- unsigned int fw_ver[WL12XX_NUM_FW_VER];
+ unsigned int fw_ver[NUM_FW_VER];
};
struct wl1271_stats {
@@ -261,6 +284,8 @@ struct wl1271_fw_sta_status {
u8 tx_total;
u8 reserved1;
__le16 reserved2;
+ /* Total structure size is 68 bytes */
+ u32 padding;
} __packed;
struct wl1271_fw_full_status {
@@ -277,9 +302,10 @@ struct wl1271_rx_mem_pool_addr {
u32 addr_extra;
};
+#define WL1271_MAX_CHANNELS 64
struct wl1271_scan {
struct cfg80211_scan_request *req;
- bool *scanned_ch;
+ unsigned long scanned_ch[BITS_TO_LONGS(WL1271_MAX_CHANNELS)];
bool failed;
u8 state;
u8 ssid[IW_ESSID_MAX_SIZE+1];
@@ -297,6 +323,7 @@ struct wl1271_if_operations {
struct device* (*dev)(struct wl1271 *wl);
void (*enable_irq)(struct wl1271 *wl);
void (*disable_irq)(struct wl1271 *wl);
+ void (*set_block_size) (struct wl1271 *wl, unsigned int blksz);
};
#define MAX_NUM_KEYS 14
@@ -319,15 +346,19 @@ enum wl12xx_flags {
WL1271_FLAG_TX_QUEUE_STOPPED,
WL1271_FLAG_TX_PENDING,
WL1271_FLAG_IN_ELP,
+ WL1271_FLAG_ELP_REQUESTED,
WL1271_FLAG_PSM,
WL1271_FLAG_PSM_REQUESTED,
WL1271_FLAG_IRQ_RUNNING,
WL1271_FLAG_IDLE,
- WL1271_FLAG_IDLE_REQUESTED,
WL1271_FLAG_PSPOLL_FAILURE,
WL1271_FLAG_STA_STATE_SENT,
WL1271_FLAG_FW_TX_BUSY,
- WL1271_FLAG_AP_STARTED
+ WL1271_FLAG_AP_STARTED,
+ WL1271_FLAG_IF_INITIALIZED,
+ WL1271_FLAG_DUMMY_PACKET_PENDING,
+ WL1271_FLAG_SUSPENDED,
+ WL1271_FLAG_PENDING_WORK,
};
struct wl1271_link {
@@ -371,7 +402,7 @@ struct wl1271 {
u8 *fw;
size_t fw_len;
u8 fw_bss_type;
- struct wl1271_nvs_file *nvs;
+ void *nvs;
size_t nvs_len;
s8 hw_pg_ver;
@@ -389,6 +420,7 @@ struct wl1271 {
/* Accounting for allocated / available TX blocks on HW */
u32 tx_blocks_freed[NUM_TX_QUEUES];
u32 tx_blocks_available;
+ u32 tx_allocated_blocks;
u32 tx_results_count;
/* Transmitted TX packets counter for chipset interface */
@@ -430,6 +462,9 @@ struct wl1271 {
/* Intermediate buffer, used for packet aggregation */
u8 *aggr_buf;
+ /* Reusable dummy packet template */
+ struct sk_buff *dummy_packet;
+
/* Network stack work */
struct work_struct netstack_work;
@@ -446,6 +481,8 @@ struct wl1271 {
struct wl1271_scan scan;
struct delayed_work scan_complete_work;
+ bool sched_scanning;
+
/* probe-req template for the current AP */
struct sk_buff *probereq;
@@ -476,6 +513,7 @@ struct wl1271 {
unsigned int rx_filter;
struct completion *elp_compl;
+ struct completion *ps_compl;
struct delayed_work elp_work;
struct delayed_work pspoll_work;
@@ -527,6 +565,14 @@ struct wl1271 {
bool ba_support;
u8 ba_rx_bitmap;
+ int tcxo_clock;
+
+ /*
+ * wowlan trigger was configured during suspend.
+ * (currently, only "ANY" trigger is supported)
+ */
+ bool wow_enabled;
+
/*
* AP-mode - links indexed by HLID. The global and broadcast links
* are always active.
@@ -544,6 +590,9 @@ struct wl1271 {
/* Quirks of specific hardware revisions */
unsigned int quirks;
+
+ /* Platform limitations */
+ unsigned int platform_quirks;
};
struct wl1271_station {
@@ -576,6 +625,15 @@ int wl1271_plt_stop(struct wl1271 *wl);
/* Quirks */
/* Each RX/TX transaction requires an end-of-transaction transfer */
-#define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0)
+#define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0)
+
+/*
+ * Older firmwares use 2 spare TX blocks
+ * (for STA < 6.1.3.50.58 or for AP < 6.2.0.0.47)
+ */
+#define WL12XX_QUIRK_USE_2_SPARE_BLOCKS BIT(1)
+
+/* WL128X requires aggregated packets to be aligned to the SDIO block size */
+#define WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT BIT(2)
#endif
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index a73a305d3cb..ff306d763e3 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -557,7 +557,7 @@ int zd_chip_unlock_phy_regs(struct zd_chip *chip)
return r;
}
-/* CR157 can be optionally patched by the EEPROM for original ZD1211 */
+/* ZD_CR157 can be optionally patched by the EEPROM for original ZD1211 */
static int patch_cr157(struct zd_chip *chip)
{
int r;
@@ -571,7 +571,7 @@ static int patch_cr157(struct zd_chip *chip)
return r;
dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value >> 8);
- return zd_iowrite32_locked(chip, value >> 8, CR157);
+ return zd_iowrite32_locked(chip, value >> 8, ZD_CR157);
}
/*
@@ -593,8 +593,8 @@ static int patch_6m_band_edge(struct zd_chip *chip, u8 channel)
int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel)
{
struct zd_ioreq16 ioreqs[] = {
- { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
- { CR47, 0x1e },
+ { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
+ { ZD_CR47, 0x1e },
};
/* FIXME: Channel 11 is not the edge for all regulatory domains. */
@@ -608,69 +608,69 @@ int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel)
static int zd1211_hw_reset_phy(struct zd_chip *chip)
{
static const struct zd_ioreq16 ioreqs[] = {
- { CR0, 0x0a }, { CR1, 0x06 }, { CR2, 0x26 },
- { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xa0 },
- { CR10, 0x81 }, { CR11, 0x00 }, { CR12, 0x7f },
- { CR13, 0x8c }, { CR14, 0x80 }, { CR15, 0x3d },
- { CR16, 0x20 }, { CR17, 0x1e }, { CR18, 0x0a },
- { CR19, 0x48 }, { CR20, 0x0c }, { CR21, 0x0c },
- { CR22, 0x23 }, { CR23, 0x90 }, { CR24, 0x14 },
- { CR25, 0x40 }, { CR26, 0x10 }, { CR27, 0x19 },
- { CR28, 0x7f }, { CR29, 0x80 }, { CR30, 0x4b },
- { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 },
- { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 },
- { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c },
- { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 },
- { CR43, 0x10 }, { CR44, 0x12 }, { CR46, 0xff },
- { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b },
- { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 },
- { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 },
- { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff },
- { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 },
- { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 },
- { CR79, 0x68 }, { CR80, 0x64 }, { CR81, 0x64 },
- { CR82, 0x00 }, { CR83, 0x00 }, { CR84, 0x00 },
- { CR85, 0x02 }, { CR86, 0x00 }, { CR87, 0x00 },
- { CR88, 0xff }, { CR89, 0xfc }, { CR90, 0x00 },
- { CR91, 0x00 }, { CR92, 0x00 }, { CR93, 0x08 },
- { CR94, 0x00 }, { CR95, 0x00 }, { CR96, 0xff },
- { CR97, 0xe7 }, { CR98, 0x00 }, { CR99, 0x00 },
- { CR100, 0x00 }, { CR101, 0xae }, { CR102, 0x02 },
- { CR103, 0x00 }, { CR104, 0x03 }, { CR105, 0x65 },
- { CR106, 0x04 }, { CR107, 0x00 }, { CR108, 0x0a },
- { CR109, 0xaa }, { CR110, 0xaa }, { CR111, 0x25 },
- { CR112, 0x25 }, { CR113, 0x00 }, { CR119, 0x1e },
- { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
+ { ZD_CR0, 0x0a }, { ZD_CR1, 0x06 }, { ZD_CR2, 0x26 },
+ { ZD_CR3, 0x38 }, { ZD_CR4, 0x80 }, { ZD_CR9, 0xa0 },
+ { ZD_CR10, 0x81 }, { ZD_CR11, 0x00 }, { ZD_CR12, 0x7f },
+ { ZD_CR13, 0x8c }, { ZD_CR14, 0x80 }, { ZD_CR15, 0x3d },
+ { ZD_CR16, 0x20 }, { ZD_CR17, 0x1e }, { ZD_CR18, 0x0a },
+ { ZD_CR19, 0x48 }, { ZD_CR20, 0x0c }, { ZD_CR21, 0x0c },
+ { ZD_CR22, 0x23 }, { ZD_CR23, 0x90 }, { ZD_CR24, 0x14 },
+ { ZD_CR25, 0x40 }, { ZD_CR26, 0x10 }, { ZD_CR27, 0x19 },
+ { ZD_CR28, 0x7f }, { ZD_CR29, 0x80 }, { ZD_CR30, 0x4b },
+ { ZD_CR31, 0x60 }, { ZD_CR32, 0x43 }, { ZD_CR33, 0x08 },
+ { ZD_CR34, 0x06 }, { ZD_CR35, 0x0a }, { ZD_CR36, 0x00 },
+ { ZD_CR37, 0x00 }, { ZD_CR38, 0x38 }, { ZD_CR39, 0x0c },
+ { ZD_CR40, 0x84 }, { ZD_CR41, 0x2a }, { ZD_CR42, 0x80 },
+ { ZD_CR43, 0x10 }, { ZD_CR44, 0x12 }, { ZD_CR46, 0xff },
+ { ZD_CR47, 0x1E }, { ZD_CR48, 0x26 }, { ZD_CR49, 0x5b },
+ { ZD_CR64, 0xd0 }, { ZD_CR65, 0x04 }, { ZD_CR66, 0x58 },
+ { ZD_CR67, 0xc9 }, { ZD_CR68, 0x88 }, { ZD_CR69, 0x41 },
+ { ZD_CR70, 0x23 }, { ZD_CR71, 0x10 }, { ZD_CR72, 0xff },
+ { ZD_CR73, 0x32 }, { ZD_CR74, 0x30 }, { ZD_CR75, 0x65 },
+ { ZD_CR76, 0x41 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x30 },
+ { ZD_CR79, 0x68 }, { ZD_CR80, 0x64 }, { ZD_CR81, 0x64 },
+ { ZD_CR82, 0x00 }, { ZD_CR83, 0x00 }, { ZD_CR84, 0x00 },
+ { ZD_CR85, 0x02 }, { ZD_CR86, 0x00 }, { ZD_CR87, 0x00 },
+ { ZD_CR88, 0xff }, { ZD_CR89, 0xfc }, { ZD_CR90, 0x00 },
+ { ZD_CR91, 0x00 }, { ZD_CR92, 0x00 }, { ZD_CR93, 0x08 },
+ { ZD_CR94, 0x00 }, { ZD_CR95, 0x00 }, { ZD_CR96, 0xff },
+ { ZD_CR97, 0xe7 }, { ZD_CR98, 0x00 }, { ZD_CR99, 0x00 },
+ { ZD_CR100, 0x00 }, { ZD_CR101, 0xae }, { ZD_CR102, 0x02 },
+ { ZD_CR103, 0x00 }, { ZD_CR104, 0x03 }, { ZD_CR105, 0x65 },
+ { ZD_CR106, 0x04 }, { ZD_CR107, 0x00 }, { ZD_CR108, 0x0a },
+ { ZD_CR109, 0xaa }, { ZD_CR110, 0xaa }, { ZD_CR111, 0x25 },
+ { ZD_CR112, 0x25 }, { ZD_CR113, 0x00 }, { ZD_CR119, 0x1e },
+ { ZD_CR125, 0x90 }, { ZD_CR126, 0x00 }, { ZD_CR127, 0x00 },
{ },
- { CR5, 0x00 }, { CR6, 0x00 }, { CR7, 0x00 },
- { CR8, 0x00 }, { CR9, 0x20 }, { CR12, 0xf0 },
- { CR20, 0x0e }, { CR21, 0x0e }, { CR27, 0x10 },
- { CR44, 0x33 }, { CR47, 0x1E }, { CR83, 0x24 },
- { CR84, 0x04 }, { CR85, 0x00 }, { CR86, 0x0C },
- { CR87, 0x12 }, { CR88, 0x0C }, { CR89, 0x00 },
- { CR90, 0x10 }, { CR91, 0x08 }, { CR93, 0x00 },
- { CR94, 0x01 }, { CR95, 0x00 }, { CR96, 0x50 },
- { CR97, 0x37 }, { CR98, 0x35 }, { CR101, 0x13 },
- { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
- { CR105, 0x12 }, { CR109, 0x27 }, { CR110, 0x27 },
- { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
- { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
- { CR117, 0xfc }, { CR118, 0xfa }, { CR120, 0x4f },
- { CR125, 0xaa }, { CR127, 0x03 }, { CR128, 0x14 },
- { CR129, 0x12 }, { CR130, 0x10 }, { CR131, 0x0C },
- { CR136, 0xdf }, { CR137, 0x40 }, { CR138, 0xa0 },
- { CR139, 0xb0 }, { CR140, 0x99 }, { CR141, 0x82 },
- { CR142, 0x54 }, { CR143, 0x1c }, { CR144, 0x6c },
- { CR147, 0x07 }, { CR148, 0x4c }, { CR149, 0x50 },
- { CR150, 0x0e }, { CR151, 0x18 }, { CR160, 0xfe },
- { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa },
- { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe },
- { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba },
- { CR170, 0xba }, { CR171, 0xba },
- /* Note: CR204 must lead the CR203 */
- { CR204, 0x7d },
+ { ZD_CR5, 0x00 }, { ZD_CR6, 0x00 }, { ZD_CR7, 0x00 },
+ { ZD_CR8, 0x00 }, { ZD_CR9, 0x20 }, { ZD_CR12, 0xf0 },
+ { ZD_CR20, 0x0e }, { ZD_CR21, 0x0e }, { ZD_CR27, 0x10 },
+ { ZD_CR44, 0x33 }, { ZD_CR47, 0x1E }, { ZD_CR83, 0x24 },
+ { ZD_CR84, 0x04 }, { ZD_CR85, 0x00 }, { ZD_CR86, 0x0C },
+ { ZD_CR87, 0x12 }, { ZD_CR88, 0x0C }, { ZD_CR89, 0x00 },
+ { ZD_CR90, 0x10 }, { ZD_CR91, 0x08 }, { ZD_CR93, 0x00 },
+ { ZD_CR94, 0x01 }, { ZD_CR95, 0x00 }, { ZD_CR96, 0x50 },
+ { ZD_CR97, 0x37 }, { ZD_CR98, 0x35 }, { ZD_CR101, 0x13 },
+ { ZD_CR102, 0x27 }, { ZD_CR103, 0x27 }, { ZD_CR104, 0x18 },
+ { ZD_CR105, 0x12 }, { ZD_CR109, 0x27 }, { ZD_CR110, 0x27 },
+ { ZD_CR111, 0x27 }, { ZD_CR112, 0x27 }, { ZD_CR113, 0x27 },
+ { ZD_CR114, 0x27 }, { ZD_CR115, 0x26 }, { ZD_CR116, 0x24 },
+ { ZD_CR117, 0xfc }, { ZD_CR118, 0xfa }, { ZD_CR120, 0x4f },
+ { ZD_CR125, 0xaa }, { ZD_CR127, 0x03 }, { ZD_CR128, 0x14 },
+ { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, { ZD_CR131, 0x0C },
+ { ZD_CR136, 0xdf }, { ZD_CR137, 0x40 }, { ZD_CR138, 0xa0 },
+ { ZD_CR139, 0xb0 }, { ZD_CR140, 0x99 }, { ZD_CR141, 0x82 },
+ { ZD_CR142, 0x54 }, { ZD_CR143, 0x1c }, { ZD_CR144, 0x6c },
+ { ZD_CR147, 0x07 }, { ZD_CR148, 0x4c }, { ZD_CR149, 0x50 },
+ { ZD_CR150, 0x0e }, { ZD_CR151, 0x18 }, { ZD_CR160, 0xfe },
+ { ZD_CR161, 0xee }, { ZD_CR162, 0xaa }, { ZD_CR163, 0xfa },
+ { ZD_CR164, 0xfa }, { ZD_CR165, 0xea }, { ZD_CR166, 0xbe },
+ { ZD_CR167, 0xbe }, { ZD_CR168, 0x6a }, { ZD_CR169, 0xba },
+ { ZD_CR170, 0xba }, { ZD_CR171, 0xba },
+ /* Note: ZD_CR204 must lead the ZD_CR203 */
+ { ZD_CR204, 0x7d },
{ },
- { CR203, 0x30 },
+ { ZD_CR203, 0x30 },
};
int r, t;
@@ -697,62 +697,62 @@ out:
static int zd1211b_hw_reset_phy(struct zd_chip *chip)
{
static const struct zd_ioreq16 ioreqs[] = {
- { CR0, 0x14 }, { CR1, 0x06 }, { CR2, 0x26 },
- { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xe0 },
- { CR10, 0x81 },
- /* power control { { CR11, 1 << 6 }, */
- { CR11, 0x00 },
- { CR12, 0xf0 }, { CR13, 0x8c }, { CR14, 0x80 },
- { CR15, 0x3d }, { CR16, 0x20 }, { CR17, 0x1e },
- { CR18, 0x0a }, { CR19, 0x48 },
- { CR20, 0x10 }, /* Org:0x0E, ComTrend:RalLink AP */
- { CR21, 0x0e }, { CR22, 0x23 }, { CR23, 0x90 },
- { CR24, 0x14 }, { CR25, 0x40 }, { CR26, 0x10 },
- { CR27, 0x10 }, { CR28, 0x7f }, { CR29, 0x80 },
- { CR30, 0x4b }, /* ASIC/FWT, no jointly decoder */
- { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 },
- { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 },
- { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c },
- { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 },
- { CR43, 0x10 }, { CR44, 0x33 }, { CR46, 0xff },
- { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b },
- { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 },
- { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 },
- { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff },
- { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 },
- { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 },
- { CR79, 0xf0 }, { CR80, 0x64 }, { CR81, 0x64 },
- { CR82, 0x00 }, { CR83, 0x24 }, { CR84, 0x04 },
- { CR85, 0x00 }, { CR86, 0x0c }, { CR87, 0x12 },
- { CR88, 0x0c }, { CR89, 0x00 }, { CR90, 0x58 },
- { CR91, 0x04 }, { CR92, 0x00 }, { CR93, 0x00 },
- { CR94, 0x01 },
- { CR95, 0x20 }, /* ZD1211B */
- { CR96, 0x50 }, { CR97, 0x37 }, { CR98, 0x35 },
- { CR99, 0x00 }, { CR100, 0x01 }, { CR101, 0x13 },
- { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
- { CR105, 0x12 }, { CR106, 0x04 }, { CR107, 0x00 },
- { CR108, 0x0a }, { CR109, 0x27 }, { CR110, 0x27 },
- { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
- { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
- { CR117, 0xfc }, { CR118, 0xfa }, { CR119, 0x1e },
- { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
- { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
- { CR131, 0x0c }, { CR136, 0xdf }, { CR137, 0xa0 },
- { CR138, 0xa8 }, { CR139, 0xb4 }, { CR140, 0x98 },
- { CR141, 0x82 }, { CR142, 0x53 }, { CR143, 0x1c },
- { CR144, 0x6c }, { CR147, 0x07 }, { CR148, 0x40 },
- { CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */
- { CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */
- { CR151, 0x18 }, { CR159, 0x70 }, { CR160, 0xfe },
- { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa },
- { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe },
- { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba },
- { CR170, 0xba }, { CR171, 0xba },
- /* Note: CR204 must lead the CR203 */
- { CR204, 0x7d },
+ { ZD_CR0, 0x14 }, { ZD_CR1, 0x06 }, { ZD_CR2, 0x26 },
+ { ZD_CR3, 0x38 }, { ZD_CR4, 0x80 }, { ZD_CR9, 0xe0 },
+ { ZD_CR10, 0x81 },
+ /* power control { { ZD_CR11, 1 << 6 }, */
+ { ZD_CR11, 0x00 },
+ { ZD_CR12, 0xf0 }, { ZD_CR13, 0x8c }, { ZD_CR14, 0x80 },
+ { ZD_CR15, 0x3d }, { ZD_CR16, 0x20 }, { ZD_CR17, 0x1e },
+ { ZD_CR18, 0x0a }, { ZD_CR19, 0x48 },
+ { ZD_CR20, 0x10 }, /* Org:0x0E, ComTrend:RalLink AP */
+ { ZD_CR21, 0x0e }, { ZD_CR22, 0x23 }, { ZD_CR23, 0x90 },
+ { ZD_CR24, 0x14 }, { ZD_CR25, 0x40 }, { ZD_CR26, 0x10 },
+ { ZD_CR27, 0x10 }, { ZD_CR28, 0x7f }, { ZD_CR29, 0x80 },
+ { ZD_CR30, 0x4b }, /* ASIC/FWT, no jointly decoder */
+ { ZD_CR31, 0x60 }, { ZD_CR32, 0x43 }, { ZD_CR33, 0x08 },
+ { ZD_CR34, 0x06 }, { ZD_CR35, 0x0a }, { ZD_CR36, 0x00 },
+ { ZD_CR37, 0x00 }, { ZD_CR38, 0x38 }, { ZD_CR39, 0x0c },
+ { ZD_CR40, 0x84 }, { ZD_CR41, 0x2a }, { ZD_CR42, 0x80 },
+ { ZD_CR43, 0x10 }, { ZD_CR44, 0x33 }, { ZD_CR46, 0xff },
+ { ZD_CR47, 0x1E }, { ZD_CR48, 0x26 }, { ZD_CR49, 0x5b },
+ { ZD_CR64, 0xd0 }, { ZD_CR65, 0x04 }, { ZD_CR66, 0x58 },
+ { ZD_CR67, 0xc9 }, { ZD_CR68, 0x88 }, { ZD_CR69, 0x41 },
+ { ZD_CR70, 0x23 }, { ZD_CR71, 0x10 }, { ZD_CR72, 0xff },
+ { ZD_CR73, 0x32 }, { ZD_CR74, 0x30 }, { ZD_CR75, 0x65 },
+ { ZD_CR76, 0x41 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x30 },
+ { ZD_CR79, 0xf0 }, { ZD_CR80, 0x64 }, { ZD_CR81, 0x64 },
+ { ZD_CR82, 0x00 }, { ZD_CR83, 0x24 }, { ZD_CR84, 0x04 },
+ { ZD_CR85, 0x00 }, { ZD_CR86, 0x0c }, { ZD_CR87, 0x12 },
+ { ZD_CR88, 0x0c }, { ZD_CR89, 0x00 }, { ZD_CR90, 0x58 },
+ { ZD_CR91, 0x04 }, { ZD_CR92, 0x00 }, { ZD_CR93, 0x00 },
+ { ZD_CR94, 0x01 },
+ { ZD_CR95, 0x20 }, /* ZD1211B */
+ { ZD_CR96, 0x50 }, { ZD_CR97, 0x37 }, { ZD_CR98, 0x35 },
+ { ZD_CR99, 0x00 }, { ZD_CR100, 0x01 }, { ZD_CR101, 0x13 },
+ { ZD_CR102, 0x27 }, { ZD_CR103, 0x27 }, { ZD_CR104, 0x18 },
+ { ZD_CR105, 0x12 }, { ZD_CR106, 0x04 }, { ZD_CR107, 0x00 },
+ { ZD_CR108, 0x0a }, { ZD_CR109, 0x27 }, { ZD_CR110, 0x27 },
+ { ZD_CR111, 0x27 }, { ZD_CR112, 0x27 }, { ZD_CR113, 0x27 },
+ { ZD_CR114, 0x27 }, { ZD_CR115, 0x26 }, { ZD_CR116, 0x24 },
+ { ZD_CR117, 0xfc }, { ZD_CR118, 0xfa }, { ZD_CR119, 0x1e },
+ { ZD_CR125, 0x90 }, { ZD_CR126, 0x00 }, { ZD_CR127, 0x00 },
+ { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
+ { ZD_CR131, 0x0c }, { ZD_CR136, 0xdf }, { ZD_CR137, 0xa0 },
+ { ZD_CR138, 0xa8 }, { ZD_CR139, 0xb4 }, { ZD_CR140, 0x98 },
+ { ZD_CR141, 0x82 }, { ZD_CR142, 0x53 }, { ZD_CR143, 0x1c },
+ { ZD_CR144, 0x6c }, { ZD_CR147, 0x07 }, { ZD_CR148, 0x40 },
+ { ZD_CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */
+ { ZD_CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */
+ { ZD_CR151, 0x18 }, { ZD_CR159, 0x70 }, { ZD_CR160, 0xfe },
+ { ZD_CR161, 0xee }, { ZD_CR162, 0xaa }, { ZD_CR163, 0xfa },
+ { ZD_CR164, 0xfa }, { ZD_CR165, 0xea }, { ZD_CR166, 0xbe },
+ { ZD_CR167, 0xbe }, { ZD_CR168, 0x6a }, { ZD_CR169, 0xba },
+ { ZD_CR170, 0xba }, { ZD_CR171, 0xba },
+ /* Note: ZD_CR204 must lead the ZD_CR203 */
+ { ZD_CR204, 0x7d },
{},
- { CR203, 0x30 },
+ { ZD_CR203, 0x30 },
};
int r, t;
@@ -1200,24 +1200,24 @@ out:
static int update_pwr_int(struct zd_chip *chip, u8 channel)
{
u8 value = chip->pwr_int_values[channel - 1];
- return zd_iowrite16_locked(chip, value, CR31);
+ return zd_iowrite16_locked(chip, value, ZD_CR31);
}
static int update_pwr_cal(struct zd_chip *chip, u8 channel)
{
u8 value = chip->pwr_cal_values[channel-1];
- return zd_iowrite16_locked(chip, value, CR68);
+ return zd_iowrite16_locked(chip, value, ZD_CR68);
}
static int update_ofdm_cal(struct zd_chip *chip, u8 channel)
{
struct zd_ioreq16 ioreqs[3];
- ioreqs[0].addr = CR67;
+ ioreqs[0].addr = ZD_CR67;
ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1];
- ioreqs[1].addr = CR66;
+ ioreqs[1].addr = ZD_CR66;
ioreqs[1].value = chip->ofdm_cal_values[OFDM_48M_INDEX][channel-1];
- ioreqs[2].addr = CR65;
+ ioreqs[2].addr = ZD_CR65;
ioreqs[2].value = chip->ofdm_cal_values[OFDM_54M_INDEX][channel-1];
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -1236,9 +1236,9 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip,
return r;
if (zd_chip_is_zd1211b(chip)) {
static const struct zd_ioreq16 ioreqs[] = {
- { CR69, 0x28 },
+ { ZD_CR69, 0x28 },
{},
- { CR69, 0x2a },
+ { ZD_CR69, 0x2a },
};
r = update_ofdm_cal(chip, channel);
@@ -1269,7 +1269,7 @@ static int patch_cck_gain(struct zd_chip *chip)
if (r)
return r;
dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff);
- return zd_iowrite16_locked(chip, value & 0xff, CR47);
+ return zd_iowrite16_locked(chip, value & 0xff, ZD_CR47);
}
int zd_chip_set_channel(struct zd_chip *chip, u8 channel)
@@ -1505,9 +1505,9 @@ int zd_rfwritev_locked(struct zd_chip *chip,
int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value)
{
const struct zd_ioreq16 ioreqs[] = {
- { CR244, (value >> 16) & 0xff },
- { CR243, (value >> 8) & 0xff },
- { CR242, value & 0xff },
+ { ZD_CR244, (value >> 16) & 0xff },
+ { ZD_CR243, (value >> 8) & 0xff },
+ { ZD_CR242, value & 0xff },
};
ZD_ASSERT(mutex_is_locked(&chip->mutex));
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index 14e4402a611..4be7c3b5b26 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -61,277 +61,288 @@ enum {
#define FWRAW_DATA(offset) ((zd_addr_t)(FW_START + (offset)))
/* 8-bit hardware registers */
-#define CR0 CTL_REG(0x0000)
-#define CR1 CTL_REG(0x0004)
-#define CR2 CTL_REG(0x0008)
-#define CR3 CTL_REG(0x000C)
+#define ZD_CR0 CTL_REG(0x0000)
+#define ZD_CR1 CTL_REG(0x0004)
+#define ZD_CR2 CTL_REG(0x0008)
+#define ZD_CR3 CTL_REG(0x000C)
-#define CR5 CTL_REG(0x0010)
+#define ZD_CR5 CTL_REG(0x0010)
/* bit 5: if set short preamble used
* bit 6: filter band - Japan channel 14 on, else off
*/
-#define CR6 CTL_REG(0x0014)
-#define CR7 CTL_REG(0x0018)
-#define CR8 CTL_REG(0x001C)
+#define ZD_CR6 CTL_REG(0x0014)
+#define ZD_CR7 CTL_REG(0x0018)
+#define ZD_CR8 CTL_REG(0x001C)
-#define CR4 CTL_REG(0x0020)
+#define ZD_CR4 CTL_REG(0x0020)
-#define CR9 CTL_REG(0x0024)
-/* bit 2: antenna switch (together with CR10) */
-#define CR10 CTL_REG(0x0028)
-/* bit 1: antenna switch (together with CR9)
- * RF2959 controls with CR11 radion on and off
+#define ZD_CR9 CTL_REG(0x0024)
+/* bit 2: antenna switch (together with ZD_CR10) */
+#define ZD_CR10 CTL_REG(0x0028)
+/* bit 1: antenna switch (together with ZD_CR9)
+ * RF2959 controls with ZD_CR11 radion on and off
*/
-#define CR11 CTL_REG(0x002C)
+#define ZD_CR11 CTL_REG(0x002C)
/* bit 6: TX power control for OFDM
- * RF2959 controls with CR10 radio on and off
+ * RF2959 controls with ZD_CR10 radio on and off
*/
-#define CR12 CTL_REG(0x0030)
-#define CR13 CTL_REG(0x0034)
-#define CR14 CTL_REG(0x0038)
-#define CR15 CTL_REG(0x003C)
-#define CR16 CTL_REG(0x0040)
-#define CR17 CTL_REG(0x0044)
-#define CR18 CTL_REG(0x0048)
-#define CR19 CTL_REG(0x004C)
-#define CR20 CTL_REG(0x0050)
-#define CR21 CTL_REG(0x0054)
-#define CR22 CTL_REG(0x0058)
-#define CR23 CTL_REG(0x005C)
-#define CR24 CTL_REG(0x0060) /* CCA threshold */
-#define CR25 CTL_REG(0x0064)
-#define CR26 CTL_REG(0x0068)
-#define CR27 CTL_REG(0x006C)
-#define CR28 CTL_REG(0x0070)
-#define CR29 CTL_REG(0x0074)
-#define CR30 CTL_REG(0x0078)
-#define CR31 CTL_REG(0x007C) /* TX power control for RF in CCK mode */
-#define CR32 CTL_REG(0x0080)
-#define CR33 CTL_REG(0x0084)
-#define CR34 CTL_REG(0x0088)
-#define CR35 CTL_REG(0x008C)
-#define CR36 CTL_REG(0x0090)
-#define CR37 CTL_REG(0x0094)
-#define CR38 CTL_REG(0x0098)
-#define CR39 CTL_REG(0x009C)
-#define CR40 CTL_REG(0x00A0)
-#define CR41 CTL_REG(0x00A4)
-#define CR42 CTL_REG(0x00A8)
-#define CR43 CTL_REG(0x00AC)
-#define CR44 CTL_REG(0x00B0)
-#define CR45 CTL_REG(0x00B4)
-#define CR46 CTL_REG(0x00B8)
-#define CR47 CTL_REG(0x00BC) /* CCK baseband gain
- * (patch value might be in EEPROM)
- */
-#define CR48 CTL_REG(0x00C0)
-#define CR49 CTL_REG(0x00C4)
-#define CR50 CTL_REG(0x00C8)
-#define CR51 CTL_REG(0x00CC) /* TX power control for RF in 6-36M modes */
-#define CR52 CTL_REG(0x00D0) /* TX power control for RF in 48M mode */
-#define CR53 CTL_REG(0x00D4) /* TX power control for RF in 54M mode */
-#define CR54 CTL_REG(0x00D8)
-#define CR55 CTL_REG(0x00DC)
-#define CR56 CTL_REG(0x00E0)
-#define CR57 CTL_REG(0x00E4)
-#define CR58 CTL_REG(0x00E8)
-#define CR59 CTL_REG(0x00EC)
-#define CR60 CTL_REG(0x00F0)
-#define CR61 CTL_REG(0x00F4)
-#define CR62 CTL_REG(0x00F8)
-#define CR63 CTL_REG(0x00FC)
-#define CR64 CTL_REG(0x0100)
-#define CR65 CTL_REG(0x0104) /* OFDM 54M calibration */
-#define CR66 CTL_REG(0x0108) /* OFDM 48M calibration */
-#define CR67 CTL_REG(0x010C) /* OFDM 36M calibration */
-#define CR68 CTL_REG(0x0110) /* CCK calibration */
-#define CR69 CTL_REG(0x0114)
-#define CR70 CTL_REG(0x0118)
-#define CR71 CTL_REG(0x011C)
-#define CR72 CTL_REG(0x0120)
-#define CR73 CTL_REG(0x0124)
-#define CR74 CTL_REG(0x0128)
-#define CR75 CTL_REG(0x012C)
-#define CR76 CTL_REG(0x0130)
-#define CR77 CTL_REG(0x0134)
-#define CR78 CTL_REG(0x0138)
-#define CR79 CTL_REG(0x013C)
-#define CR80 CTL_REG(0x0140)
-#define CR81 CTL_REG(0x0144)
-#define CR82 CTL_REG(0x0148)
-#define CR83 CTL_REG(0x014C)
-#define CR84 CTL_REG(0x0150)
-#define CR85 CTL_REG(0x0154)
-#define CR86 CTL_REG(0x0158)
-#define CR87 CTL_REG(0x015C)
-#define CR88 CTL_REG(0x0160)
-#define CR89 CTL_REG(0x0164)
-#define CR90 CTL_REG(0x0168)
-#define CR91 CTL_REG(0x016C)
-#define CR92 CTL_REG(0x0170)
-#define CR93 CTL_REG(0x0174)
-#define CR94 CTL_REG(0x0178)
-#define CR95 CTL_REG(0x017C)
-#define CR96 CTL_REG(0x0180)
-#define CR97 CTL_REG(0x0184)
-#define CR98 CTL_REG(0x0188)
-#define CR99 CTL_REG(0x018C)
-#define CR100 CTL_REG(0x0190)
-#define CR101 CTL_REG(0x0194)
-#define CR102 CTL_REG(0x0198)
-#define CR103 CTL_REG(0x019C)
-#define CR104 CTL_REG(0x01A0)
-#define CR105 CTL_REG(0x01A4)
-#define CR106 CTL_REG(0x01A8)
-#define CR107 CTL_REG(0x01AC)
-#define CR108 CTL_REG(0x01B0)
-#define CR109 CTL_REG(0x01B4)
-#define CR110 CTL_REG(0x01B8)
-#define CR111 CTL_REG(0x01BC)
-#define CR112 CTL_REG(0x01C0)
-#define CR113 CTL_REG(0x01C4)
-#define CR114 CTL_REG(0x01C8)
-#define CR115 CTL_REG(0x01CC)
-#define CR116 CTL_REG(0x01D0)
-#define CR117 CTL_REG(0x01D4)
-#define CR118 CTL_REG(0x01D8)
-#define CR119 CTL_REG(0x01DC)
-#define CR120 CTL_REG(0x01E0)
-#define CR121 CTL_REG(0x01E4)
-#define CR122 CTL_REG(0x01E8)
-#define CR123 CTL_REG(0x01EC)
-#define CR124 CTL_REG(0x01F0)
-#define CR125 CTL_REG(0x01F4)
-#define CR126 CTL_REG(0x01F8)
-#define CR127 CTL_REG(0x01FC)
-#define CR128 CTL_REG(0x0200)
-#define CR129 CTL_REG(0x0204)
-#define CR130 CTL_REG(0x0208)
-#define CR131 CTL_REG(0x020C)
-#define CR132 CTL_REG(0x0210)
-#define CR133 CTL_REG(0x0214)
-#define CR134 CTL_REG(0x0218)
-#define CR135 CTL_REG(0x021C)
-#define CR136 CTL_REG(0x0220)
-#define CR137 CTL_REG(0x0224)
-#define CR138 CTL_REG(0x0228)
-#define CR139 CTL_REG(0x022C)
-#define CR140 CTL_REG(0x0230)
-#define CR141 CTL_REG(0x0234)
-#define CR142 CTL_REG(0x0238)
-#define CR143 CTL_REG(0x023C)
-#define CR144 CTL_REG(0x0240)
-#define CR145 CTL_REG(0x0244)
-#define CR146 CTL_REG(0x0248)
-#define CR147 CTL_REG(0x024C)
-#define CR148 CTL_REG(0x0250)
-#define CR149 CTL_REG(0x0254)
-#define CR150 CTL_REG(0x0258)
-#define CR151 CTL_REG(0x025C)
-#define CR152 CTL_REG(0x0260)
-#define CR153 CTL_REG(0x0264)
-#define CR154 CTL_REG(0x0268)
-#define CR155 CTL_REG(0x026C)
-#define CR156 CTL_REG(0x0270)
-#define CR157 CTL_REG(0x0274)
-#define CR158 CTL_REG(0x0278)
-#define CR159 CTL_REG(0x027C)
-#define CR160 CTL_REG(0x0280)
-#define CR161 CTL_REG(0x0284)
-#define CR162 CTL_REG(0x0288)
-#define CR163 CTL_REG(0x028C)
-#define CR164 CTL_REG(0x0290)
-#define CR165 CTL_REG(0x0294)
-#define CR166 CTL_REG(0x0298)
-#define CR167 CTL_REG(0x029C)
-#define CR168 CTL_REG(0x02A0)
-#define CR169 CTL_REG(0x02A4)
-#define CR170 CTL_REG(0x02A8)
-#define CR171 CTL_REG(0x02AC)
-#define CR172 CTL_REG(0x02B0)
-#define CR173 CTL_REG(0x02B4)
-#define CR174 CTL_REG(0x02B8)
-#define CR175 CTL_REG(0x02BC)
-#define CR176 CTL_REG(0x02C0)
-#define CR177 CTL_REG(0x02C4)
-#define CR178 CTL_REG(0x02C8)
-#define CR179 CTL_REG(0x02CC)
-#define CR180 CTL_REG(0x02D0)
-#define CR181 CTL_REG(0x02D4)
-#define CR182 CTL_REG(0x02D8)
-#define CR183 CTL_REG(0x02DC)
-#define CR184 CTL_REG(0x02E0)
-#define CR185 CTL_REG(0x02E4)
-#define CR186 CTL_REG(0x02E8)
-#define CR187 CTL_REG(0x02EC)
-#define CR188 CTL_REG(0x02F0)
-#define CR189 CTL_REG(0x02F4)
-#define CR190 CTL_REG(0x02F8)
-#define CR191 CTL_REG(0x02FC)
-#define CR192 CTL_REG(0x0300)
-#define CR193 CTL_REG(0x0304)
-#define CR194 CTL_REG(0x0308)
-#define CR195 CTL_REG(0x030C)
-#define CR196 CTL_REG(0x0310)
-#define CR197 CTL_REG(0x0314)
-#define CR198 CTL_REG(0x0318)
-#define CR199 CTL_REG(0x031C)
-#define CR200 CTL_REG(0x0320)
-#define CR201 CTL_REG(0x0324)
-#define CR202 CTL_REG(0x0328)
-#define CR203 CTL_REG(0x032C) /* I2C bus template value & flash control */
-#define CR204 CTL_REG(0x0330)
-#define CR205 CTL_REG(0x0334)
-#define CR206 CTL_REG(0x0338)
-#define CR207 CTL_REG(0x033C)
-#define CR208 CTL_REG(0x0340)
-#define CR209 CTL_REG(0x0344)
-#define CR210 CTL_REG(0x0348)
-#define CR211 CTL_REG(0x034C)
-#define CR212 CTL_REG(0x0350)
-#define CR213 CTL_REG(0x0354)
-#define CR214 CTL_REG(0x0358)
-#define CR215 CTL_REG(0x035C)
-#define CR216 CTL_REG(0x0360)
-#define CR217 CTL_REG(0x0364)
-#define CR218 CTL_REG(0x0368)
-#define CR219 CTL_REG(0x036C)
-#define CR220 CTL_REG(0x0370)
-#define CR221 CTL_REG(0x0374)
-#define CR222 CTL_REG(0x0378)
-#define CR223 CTL_REG(0x037C)
-#define CR224 CTL_REG(0x0380)
-#define CR225 CTL_REG(0x0384)
-#define CR226 CTL_REG(0x0388)
-#define CR227 CTL_REG(0x038C)
-#define CR228 CTL_REG(0x0390)
-#define CR229 CTL_REG(0x0394)
-#define CR230 CTL_REG(0x0398)
-#define CR231 CTL_REG(0x039C)
-#define CR232 CTL_REG(0x03A0)
-#define CR233 CTL_REG(0x03A4)
-#define CR234 CTL_REG(0x03A8)
-#define CR235 CTL_REG(0x03AC)
-#define CR236 CTL_REG(0x03B0)
-
-#define CR240 CTL_REG(0x03C0)
-/* bit 7: host-controlled RF register writes
- * CR241-CR245: for hardware controlled writing of RF bits, not needed for
- * USB
+#define ZD_CR12 CTL_REG(0x0030)
+#define ZD_CR13 CTL_REG(0x0034)
+#define ZD_CR14 CTL_REG(0x0038)
+#define ZD_CR15 CTL_REG(0x003C)
+#define ZD_CR16 CTL_REG(0x0040)
+#define ZD_CR17 CTL_REG(0x0044)
+#define ZD_CR18 CTL_REG(0x0048)
+#define ZD_CR19 CTL_REG(0x004C)
+#define ZD_CR20 CTL_REG(0x0050)
+#define ZD_CR21 CTL_REG(0x0054)
+#define ZD_CR22 CTL_REG(0x0058)
+#define ZD_CR23 CTL_REG(0x005C)
+#define ZD_CR24 CTL_REG(0x0060) /* CCA threshold */
+#define ZD_CR25 CTL_REG(0x0064)
+#define ZD_CR26 CTL_REG(0x0068)
+#define ZD_CR27 CTL_REG(0x006C)
+#define ZD_CR28 CTL_REG(0x0070)
+#define ZD_CR29 CTL_REG(0x0074)
+#define ZD_CR30 CTL_REG(0x0078)
+#define ZD_CR31 CTL_REG(0x007C) /* TX power control for RF in
+ * CCK mode
+ */
+#define ZD_CR32 CTL_REG(0x0080)
+#define ZD_CR33 CTL_REG(0x0084)
+#define ZD_CR34 CTL_REG(0x0088)
+#define ZD_CR35 CTL_REG(0x008C)
+#define ZD_CR36 CTL_REG(0x0090)
+#define ZD_CR37 CTL_REG(0x0094)
+#define ZD_CR38 CTL_REG(0x0098)
+#define ZD_CR39 CTL_REG(0x009C)
+#define ZD_CR40 CTL_REG(0x00A0)
+#define ZD_CR41 CTL_REG(0x00A4)
+#define ZD_CR42 CTL_REG(0x00A8)
+#define ZD_CR43 CTL_REG(0x00AC)
+#define ZD_CR44 CTL_REG(0x00B0)
+#define ZD_CR45 CTL_REG(0x00B4)
+#define ZD_CR46 CTL_REG(0x00B8)
+#define ZD_CR47 CTL_REG(0x00BC) /* CCK baseband gain
+ * (patch value might be in EEPROM)
+ */
+#define ZD_CR48 CTL_REG(0x00C0)
+#define ZD_CR49 CTL_REG(0x00C4)
+#define ZD_CR50 CTL_REG(0x00C8)
+#define ZD_CR51 CTL_REG(0x00CC) /* TX power control for RF in
+ * 6-36M modes
+ */
+#define ZD_CR52 CTL_REG(0x00D0) /* TX power control for RF in
+ * 48M mode
+ */
+#define ZD_CR53 CTL_REG(0x00D4) /* TX power control for RF in
+ * 54M mode
+ */
+#define ZD_CR54 CTL_REG(0x00D8)
+#define ZD_CR55 CTL_REG(0x00DC)
+#define ZD_CR56 CTL_REG(0x00E0)
+#define ZD_CR57 CTL_REG(0x00E4)
+#define ZD_CR58 CTL_REG(0x00E8)
+#define ZD_CR59 CTL_REG(0x00EC)
+#define ZD_CR60 CTL_REG(0x00F0)
+#define ZD_CR61 CTL_REG(0x00F4)
+#define ZD_CR62 CTL_REG(0x00F8)
+#define ZD_CR63 CTL_REG(0x00FC)
+#define ZD_CR64 CTL_REG(0x0100)
+#define ZD_CR65 CTL_REG(0x0104) /* OFDM 54M calibration */
+#define ZD_CR66 CTL_REG(0x0108) /* OFDM 48M calibration */
+#define ZD_CR67 CTL_REG(0x010C) /* OFDM 36M calibration */
+#define ZD_CR68 CTL_REG(0x0110) /* CCK calibration */
+#define ZD_CR69 CTL_REG(0x0114)
+#define ZD_CR70 CTL_REG(0x0118)
+#define ZD_CR71 CTL_REG(0x011C)
+#define ZD_CR72 CTL_REG(0x0120)
+#define ZD_CR73 CTL_REG(0x0124)
+#define ZD_CR74 CTL_REG(0x0128)
+#define ZD_CR75 CTL_REG(0x012C)
+#define ZD_CR76 CTL_REG(0x0130)
+#define ZD_CR77 CTL_REG(0x0134)
+#define ZD_CR78 CTL_REG(0x0138)
+#define ZD_CR79 CTL_REG(0x013C)
+#define ZD_CR80 CTL_REG(0x0140)
+#define ZD_CR81 CTL_REG(0x0144)
+#define ZD_CR82 CTL_REG(0x0148)
+#define ZD_CR83 CTL_REG(0x014C)
+#define ZD_CR84 CTL_REG(0x0150)
+#define ZD_CR85 CTL_REG(0x0154)
+#define ZD_CR86 CTL_REG(0x0158)
+#define ZD_CR87 CTL_REG(0x015C)
+#define ZD_CR88 CTL_REG(0x0160)
+#define ZD_CR89 CTL_REG(0x0164)
+#define ZD_CR90 CTL_REG(0x0168)
+#define ZD_CR91 CTL_REG(0x016C)
+#define ZD_CR92 CTL_REG(0x0170)
+#define ZD_CR93 CTL_REG(0x0174)
+#define ZD_CR94 CTL_REG(0x0178)
+#define ZD_CR95 CTL_REG(0x017C)
+#define ZD_CR96 CTL_REG(0x0180)
+#define ZD_CR97 CTL_REG(0x0184)
+#define ZD_CR98 CTL_REG(0x0188)
+#define ZD_CR99 CTL_REG(0x018C)
+#define ZD_CR100 CTL_REG(0x0190)
+#define ZD_CR101 CTL_REG(0x0194)
+#define ZD_CR102 CTL_REG(0x0198)
+#define ZD_CR103 CTL_REG(0x019C)
+#define ZD_CR104 CTL_REG(0x01A0)
+#define ZD_CR105 CTL_REG(0x01A4)
+#define ZD_CR106 CTL_REG(0x01A8)
+#define ZD_CR107 CTL_REG(0x01AC)
+#define ZD_CR108 CTL_REG(0x01B0)
+#define ZD_CR109 CTL_REG(0x01B4)
+#define ZD_CR110 CTL_REG(0x01B8)
+#define ZD_CR111 CTL_REG(0x01BC)
+#define ZD_CR112 CTL_REG(0x01C0)
+#define ZD_CR113 CTL_REG(0x01C4)
+#define ZD_CR114 CTL_REG(0x01C8)
+#define ZD_CR115 CTL_REG(0x01CC)
+#define ZD_CR116 CTL_REG(0x01D0)
+#define ZD_CR117 CTL_REG(0x01D4)
+#define ZD_CR118 CTL_REG(0x01D8)
+#define ZD_CR119 CTL_REG(0x01DC)
+#define ZD_CR120 CTL_REG(0x01E0)
+#define ZD_CR121 CTL_REG(0x01E4)
+#define ZD_CR122 CTL_REG(0x01E8)
+#define ZD_CR123 CTL_REG(0x01EC)
+#define ZD_CR124 CTL_REG(0x01F0)
+#define ZD_CR125 CTL_REG(0x01F4)
+#define ZD_CR126 CTL_REG(0x01F8)
+#define ZD_CR127 CTL_REG(0x01FC)
+#define ZD_CR128 CTL_REG(0x0200)
+#define ZD_CR129 CTL_REG(0x0204)
+#define ZD_CR130 CTL_REG(0x0208)
+#define ZD_CR131 CTL_REG(0x020C)
+#define ZD_CR132 CTL_REG(0x0210)
+#define ZD_CR133 CTL_REG(0x0214)
+#define ZD_CR134 CTL_REG(0x0218)
+#define ZD_CR135 CTL_REG(0x021C)
+#define ZD_CR136 CTL_REG(0x0220)
+#define ZD_CR137 CTL_REG(0x0224)
+#define ZD_CR138 CTL_REG(0x0228)
+#define ZD_CR139 CTL_REG(0x022C)
+#define ZD_CR140 CTL_REG(0x0230)
+#define ZD_CR141 CTL_REG(0x0234)
+#define ZD_CR142 CTL_REG(0x0238)
+#define ZD_CR143 CTL_REG(0x023C)
+#define ZD_CR144 CTL_REG(0x0240)
+#define ZD_CR145 CTL_REG(0x0244)
+#define ZD_CR146 CTL_REG(0x0248)
+#define ZD_CR147 CTL_REG(0x024C)
+#define ZD_CR148 CTL_REG(0x0250)
+#define ZD_CR149 CTL_REG(0x0254)
+#define ZD_CR150 CTL_REG(0x0258)
+#define ZD_CR151 CTL_REG(0x025C)
+#define ZD_CR152 CTL_REG(0x0260)
+#define ZD_CR153 CTL_REG(0x0264)
+#define ZD_CR154 CTL_REG(0x0268)
+#define ZD_CR155 CTL_REG(0x026C)
+#define ZD_CR156 CTL_REG(0x0270)
+#define ZD_CR157 CTL_REG(0x0274)
+#define ZD_CR158 CTL_REG(0x0278)
+#define ZD_CR159 CTL_REG(0x027C)
+#define ZD_CR160 CTL_REG(0x0280)
+#define ZD_CR161 CTL_REG(0x0284)
+#define ZD_CR162 CTL_REG(0x0288)
+#define ZD_CR163 CTL_REG(0x028C)
+#define ZD_CR164 CTL_REG(0x0290)
+#define ZD_CR165 CTL_REG(0x0294)
+#define ZD_CR166 CTL_REG(0x0298)
+#define ZD_CR167 CTL_REG(0x029C)
+#define ZD_CR168 CTL_REG(0x02A0)
+#define ZD_CR169 CTL_REG(0x02A4)
+#define ZD_CR170 CTL_REG(0x02A8)
+#define ZD_CR171 CTL_REG(0x02AC)
+#define ZD_CR172 CTL_REG(0x02B0)
+#define ZD_CR173 CTL_REG(0x02B4)
+#define ZD_CR174 CTL_REG(0x02B8)
+#define ZD_CR175 CTL_REG(0x02BC)
+#define ZD_CR176 CTL_REG(0x02C0)
+#define ZD_CR177 CTL_REG(0x02C4)
+#define ZD_CR178 CTL_REG(0x02C8)
+#define ZD_CR179 CTL_REG(0x02CC)
+#define ZD_CR180 CTL_REG(0x02D0)
+#define ZD_CR181 CTL_REG(0x02D4)
+#define ZD_CR182 CTL_REG(0x02D8)
+#define ZD_CR183 CTL_REG(0x02DC)
+#define ZD_CR184 CTL_REG(0x02E0)
+#define ZD_CR185 CTL_REG(0x02E4)
+#define ZD_CR186 CTL_REG(0x02E8)
+#define ZD_CR187 CTL_REG(0x02EC)
+#define ZD_CR188 CTL_REG(0x02F0)
+#define ZD_CR189 CTL_REG(0x02F4)
+#define ZD_CR190 CTL_REG(0x02F8)
+#define ZD_CR191 CTL_REG(0x02FC)
+#define ZD_CR192 CTL_REG(0x0300)
+#define ZD_CR193 CTL_REG(0x0304)
+#define ZD_CR194 CTL_REG(0x0308)
+#define ZD_CR195 CTL_REG(0x030C)
+#define ZD_CR196 CTL_REG(0x0310)
+#define ZD_CR197 CTL_REG(0x0314)
+#define ZD_CR198 CTL_REG(0x0318)
+#define ZD_CR199 CTL_REG(0x031C)
+#define ZD_CR200 CTL_REG(0x0320)
+#define ZD_CR201 CTL_REG(0x0324)
+#define ZD_CR202 CTL_REG(0x0328)
+#define ZD_CR203 CTL_REG(0x032C) /* I2C bus template value & flash
+ * control
+ */
+#define ZD_CR204 CTL_REG(0x0330)
+#define ZD_CR205 CTL_REG(0x0334)
+#define ZD_CR206 CTL_REG(0x0338)
+#define ZD_CR207 CTL_REG(0x033C)
+#define ZD_CR208 CTL_REG(0x0340)
+#define ZD_CR209 CTL_REG(0x0344)
+#define ZD_CR210 CTL_REG(0x0348)
+#define ZD_CR211 CTL_REG(0x034C)
+#define ZD_CR212 CTL_REG(0x0350)
+#define ZD_CR213 CTL_REG(0x0354)
+#define ZD_CR214 CTL_REG(0x0358)
+#define ZD_CR215 CTL_REG(0x035C)
+#define ZD_CR216 CTL_REG(0x0360)
+#define ZD_CR217 CTL_REG(0x0364)
+#define ZD_CR218 CTL_REG(0x0368)
+#define ZD_CR219 CTL_REG(0x036C)
+#define ZD_CR220 CTL_REG(0x0370)
+#define ZD_CR221 CTL_REG(0x0374)
+#define ZD_CR222 CTL_REG(0x0378)
+#define ZD_CR223 CTL_REG(0x037C)
+#define ZD_CR224 CTL_REG(0x0380)
+#define ZD_CR225 CTL_REG(0x0384)
+#define ZD_CR226 CTL_REG(0x0388)
+#define ZD_CR227 CTL_REG(0x038C)
+#define ZD_CR228 CTL_REG(0x0390)
+#define ZD_CR229 CTL_REG(0x0394)
+#define ZD_CR230 CTL_REG(0x0398)
+#define ZD_CR231 CTL_REG(0x039C)
+#define ZD_CR232 CTL_REG(0x03A0)
+#define ZD_CR233 CTL_REG(0x03A4)
+#define ZD_CR234 CTL_REG(0x03A8)
+#define ZD_CR235 CTL_REG(0x03AC)
+#define ZD_CR236 CTL_REG(0x03B0)
+
+#define ZD_CR240 CTL_REG(0x03C0)
+/* bit 7: host-controlled RF register writes
+ * ZD_CR241-ZD_CR245: for hardware controlled writing of RF bits, not needed for
+ * USB
*/
-#define CR241 CTL_REG(0x03C4)
-#define CR242 CTL_REG(0x03C8)
-#define CR243 CTL_REG(0x03CC)
-#define CR244 CTL_REG(0x03D0)
-#define CR245 CTL_REG(0x03D4)
-
-#define CR251 CTL_REG(0x03EC) /* only used for activation and deactivation of
- * Airoha RFs AL2230 and AL7230B
- */
-#define CR252 CTL_REG(0x03F0)
-#define CR253 CTL_REG(0x03F4)
-#define CR254 CTL_REG(0x03F8)
-#define CR255 CTL_REG(0x03FC)
+#define ZD_CR241 CTL_REG(0x03C4)
+#define ZD_CR242 CTL_REG(0x03C8)
+#define ZD_CR243 CTL_REG(0x03CC)
+#define ZD_CR244 CTL_REG(0x03D0)
+#define ZD_CR245 CTL_REG(0x03D4)
+
+#define ZD_CR251 CTL_REG(0x03EC) /* only used for activation and
+ * deactivation of Airoha RFs AL2230
+ * and AL7230B
+ */
+#define ZD_CR252 CTL_REG(0x03F0)
+#define ZD_CR253 CTL_REG(0x03F4)
+#define ZD_CR254 CTL_REG(0x03F8)
+#define ZD_CR255 CTL_REG(0x03FC)
#define CR_MAX_PHY_REG 255
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h
index 79dc1035592..725b7c99b23 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.h
+++ b/drivers/net/wireless/zd1211rw/zd_rf.h
@@ -55,7 +55,7 @@ struct zd_rf {
* defaults to 1 (yes) */
u8 update_channel_int:1;
- /* whether CR47 should be patched from the EEPROM, if the appropriate
+ /* whether ZD_CR47 should be patched from the EEPROM, if the appropriate
* flag is set in the POD. The vendor driver suggests that this should
* be done for all RF's, but a bug in their code prevents but their
* HW_OverWritePhyRegFromE2P() routine from ever taking effect. */
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
index 74a8f7a5559..12babcb633c 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
@@ -61,31 +61,31 @@ static const u32 zd1211b_al2230_table[][3] = {
};
static const struct zd_ioreq16 zd1211b_ioreqs_shared_1[] = {
- { CR240, 0x57 }, { CR9, 0xe0 },
+ { ZD_CR240, 0x57 }, { ZD_CR9, 0xe0 },
};
static const struct zd_ioreq16 ioreqs_init_al2230s[] = {
- { CR47, 0x1e }, /* MARK_002 */
- { CR106, 0x22 },
- { CR107, 0x2a }, /* MARK_002 */
- { CR109, 0x13 }, /* MARK_002 */
- { CR118, 0xf8 }, /* MARK_002 */
- { CR119, 0x12 }, { CR122, 0xe0 },
- { CR128, 0x10 }, /* MARK_001 from 0xe->0x10 */
- { CR129, 0x0e }, /* MARK_001 from 0xd->0x0e */
- { CR130, 0x10 }, /* MARK_001 from 0xb->0x0d */
+ { ZD_CR47, 0x1e }, /* MARK_002 */
+ { ZD_CR106, 0x22 },
+ { ZD_CR107, 0x2a }, /* MARK_002 */
+ { ZD_CR109, 0x13 }, /* MARK_002 */
+ { ZD_CR118, 0xf8 }, /* MARK_002 */
+ { ZD_CR119, 0x12 }, { ZD_CR122, 0xe0 },
+ { ZD_CR128, 0x10 }, /* MARK_001 from 0xe->0x10 */
+ { ZD_CR129, 0x0e }, /* MARK_001 from 0xd->0x0e */
+ { ZD_CR130, 0x10 }, /* MARK_001 from 0xb->0x0d */
};
static int zd1211b_al2230_finalize_rf(struct zd_chip *chip)
{
int r;
static const struct zd_ioreq16 ioreqs[] = {
- { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 },
- { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 },
- { CR203, 0x06 },
+ { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 },
+ { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 },
+ { ZD_CR203, 0x06 },
{ },
- { CR240, 0x80 },
+ { ZD_CR240, 0x80 },
};
r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -94,12 +94,12 @@ static int zd1211b_al2230_finalize_rf(struct zd_chip *chip)
/* related to antenna selection? */
if (chip->new_phy_layout) {
- r = zd_iowrite16_locked(chip, 0xe1, CR9);
+ r = zd_iowrite16_locked(chip, 0xe1, ZD_CR9);
if (r)
return r;
}
- return zd_iowrite16_locked(chip, 0x06, CR203);
+ return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
}
static int zd1211_al2230_init_hw(struct zd_rf *rf)
@@ -108,40 +108,40 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs_init[] = {
- { CR15, 0x20 }, { CR23, 0x40 }, { CR24, 0x20 },
- { CR26, 0x11 }, { CR28, 0x3e }, { CR29, 0x00 },
- { CR44, 0x33 }, { CR106, 0x2a }, { CR107, 0x1a },
- { CR109, 0x09 }, { CR110, 0x27 }, { CR111, 0x2b },
- { CR112, 0x2b }, { CR119, 0x0a }, { CR10, 0x89 },
+ { ZD_CR15, 0x20 }, { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 },
+ { ZD_CR26, 0x11 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
+ { ZD_CR44, 0x33 }, { ZD_CR106, 0x2a }, { ZD_CR107, 0x1a },
+ { ZD_CR109, 0x09 }, { ZD_CR110, 0x27 }, { ZD_CR111, 0x2b },
+ { ZD_CR112, 0x2b }, { ZD_CR119, 0x0a }, { ZD_CR10, 0x89 },
/* for newest (3rd cut) AL2300 */
- { CR17, 0x28 },
- { CR26, 0x93 }, { CR34, 0x30 },
+ { ZD_CR17, 0x28 },
+ { ZD_CR26, 0x93 }, { ZD_CR34, 0x30 },
/* for newest (3rd cut) AL2300 */
- { CR35, 0x3e },
- { CR41, 0x24 }, { CR44, 0x32 },
+ { ZD_CR35, 0x3e },
+ { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
/* for newest (3rd cut) AL2300 */
- { CR46, 0x96 },
- { CR47, 0x1e }, { CR79, 0x58 }, { CR80, 0x30 },
- { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 },
- { CR92, 0x0a }, { CR99, 0x28 }, { CR100, 0x00 },
- { CR101, 0x13 }, { CR102, 0x27 }, { CR106, 0x24 },
- { CR107, 0x2a }, { CR109, 0x09 }, { CR110, 0x13 },
- { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 },
- { CR114, 0x27 },
+ { ZD_CR46, 0x96 },
+ { ZD_CR47, 0x1e }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 },
+ { ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 },
+ { ZD_CR92, 0x0a }, { ZD_CR99, 0x28 }, { ZD_CR100, 0x00 },
+ { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, { ZD_CR106, 0x24 },
+ { ZD_CR107, 0x2a }, { ZD_CR109, 0x09 }, { ZD_CR110, 0x13 },
+ { ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
+ { ZD_CR114, 0x27 },
/* for newest (3rd cut) AL2300 */
- { CR115, 0x24 },
- { CR116, 0x24 }, { CR117, 0xf4 }, { CR118, 0xfc },
- { CR119, 0x10 }, { CR120, 0x4f }, { CR121, 0x77 },
- { CR122, 0xe0 }, { CR137, 0x88 }, { CR252, 0xff },
- { CR253, 0xff },
+ { ZD_CR115, 0x24 },
+ { ZD_CR116, 0x24 }, { ZD_CR117, 0xf4 }, { ZD_CR118, 0xfc },
+ { ZD_CR119, 0x10 }, { ZD_CR120, 0x4f }, { ZD_CR121, 0x77 },
+ { ZD_CR122, 0xe0 }, { ZD_CR137, 0x88 }, { ZD_CR252, 0xff },
+ { ZD_CR253, 0xff },
};
static const struct zd_ioreq16 ioreqs_pll[] = {
/* shdnb(PLL_ON)=0 */
- { CR251, 0x2f },
+ { ZD_CR251, 0x2f },
/* shdnb(PLL_ON)=1 */
- { CR251, 0x3f },
- { CR138, 0x28 }, { CR203, 0x06 },
+ { ZD_CR251, 0x3f },
+ { ZD_CR138, 0x28 }, { ZD_CR203, 0x06 },
};
static const u32 rv1[] = {
@@ -161,7 +161,7 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
0x0805b6,
0x011687,
0x000688,
- 0x0403b9, /* external control TX power (CR31) */
+ 0x0403b9, /* external control TX power (ZD_CR31) */
0x00dbba,
0x00099b,
0x0bdffc,
@@ -221,52 +221,54 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs1[] = {
- { CR10, 0x89 }, { CR15, 0x20 },
- { CR17, 0x2B }, /* for newest(3rd cut) AL2230 */
- { CR23, 0x40 }, { CR24, 0x20 }, { CR26, 0x93 },
- { CR28, 0x3e }, { CR29, 0x00 },
- { CR33, 0x28 }, /* 5621 */
- { CR34, 0x30 },
- { CR35, 0x3e }, /* for newest(3rd cut) AL2230 */
- { CR41, 0x24 }, { CR44, 0x32 },
- { CR46, 0x99 }, /* for newest(3rd cut) AL2230 */
- { CR47, 0x1e },
+ { ZD_CR10, 0x89 }, { ZD_CR15, 0x20 },
+ { ZD_CR17, 0x2B }, /* for newest(3rd cut) AL2230 */
+ { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 },
+ { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
+ { ZD_CR33, 0x28 }, /* 5621 */
+ { ZD_CR34, 0x30 },
+ { ZD_CR35, 0x3e }, /* for newest(3rd cut) AL2230 */
+ { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
+ { ZD_CR46, 0x99 }, /* for newest(3rd cut) AL2230 */
+ { ZD_CR47, 0x1e },
/* ZD1211B 05.06.10 */
- { CR48, 0x06 }, { CR49, 0xf9 }, { CR51, 0x01 },
- { CR52, 0x80 }, { CR53, 0x7e }, { CR65, 0x00 },
- { CR66, 0x00 }, { CR67, 0x00 }, { CR68, 0x00 },
- { CR69, 0x28 },
-
- { CR79, 0x58 }, { CR80, 0x30 }, { CR81, 0x30 },
- { CR87, 0x0a }, { CR89, 0x04 },
- { CR91, 0x00 }, /* 5621 */
- { CR92, 0x0a },
- { CR98, 0x8d }, /* 4804, for 1212 new algorithm */
- { CR99, 0x00 }, /* 5621 */
- { CR101, 0x13 }, { CR102, 0x27 },
- { CR106, 0x24 }, /* for newest(3rd cut) AL2230 */
- { CR107, 0x2a },
- { CR109, 0x13 }, /* 4804, for 1212 new algorithm */
- { CR110, 0x1f }, /* 4804, for 1212 new algorithm */
- { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 },
- { CR114, 0x27 },
- { CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut) AL2230 */
- { CR116, 0x24 },
- { CR117, 0xfa }, /* for 1211b */
- { CR118, 0xfa }, /* for 1211b */
- { CR119, 0x10 },
- { CR120, 0x4f },
- { CR121, 0x6c }, /* for 1211b */
- { CR122, 0xfc }, /* E0->FC at 4902 */
- { CR123, 0x57 }, /* 5623 */
- { CR125, 0xad }, /* 4804, for 1212 new algorithm */
- { CR126, 0x6c }, /* 5614 */
- { CR127, 0x03 }, /* 4804, for 1212 new algorithm */
- { CR137, 0x50 }, /* 5614 */
- { CR138, 0xa8 },
- { CR144, 0xac }, /* 5621 */
- { CR150, 0x0d }, { CR252, 0x34 }, { CR253, 0x34 },
+ { ZD_CR48, 0x06 }, { ZD_CR49, 0xf9 }, { ZD_CR51, 0x01 },
+ { ZD_CR52, 0x80 }, { ZD_CR53, 0x7e }, { ZD_CR65, 0x00 },
+ { ZD_CR66, 0x00 }, { ZD_CR67, 0x00 }, { ZD_CR68, 0x00 },
+ { ZD_CR69, 0x28 },
+
+ { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 },
+ { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 },
+ { ZD_CR91, 0x00 }, /* 5621 */
+ { ZD_CR92, 0x0a },
+ { ZD_CR98, 0x8d }, /* 4804, for 1212 new algorithm */
+ { ZD_CR99, 0x00 }, /* 5621 */
+ { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 },
+ { ZD_CR106, 0x24 }, /* for newest(3rd cut) AL2230 */
+ { ZD_CR107, 0x2a },
+ { ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */
+ { ZD_CR110, 0x1f }, /* 4804, for 1212 new algorithm */
+ { ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
+ { ZD_CR114, 0x27 },
+ { ZD_CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut)
+ * AL2230
+ */
+ { ZD_CR116, 0x24 },
+ { ZD_CR117, 0xfa }, /* for 1211b */
+ { ZD_CR118, 0xfa }, /* for 1211b */
+ { ZD_CR119, 0x10 },
+ { ZD_CR120, 0x4f },
+ { ZD_CR121, 0x6c }, /* for 1211b */
+ { ZD_CR122, 0xfc }, /* E0->FC at 4902 */
+ { ZD_CR123, 0x57 }, /* 5623 */
+ { ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */
+ { ZD_CR126, 0x6c }, /* 5614 */
+ { ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */
+ { ZD_CR137, 0x50 }, /* 5614 */
+ { ZD_CR138, 0xa8 },
+ { ZD_CR144, 0xac }, /* 5621 */
+ { ZD_CR150, 0x0d }, { ZD_CR252, 0x34 }, { ZD_CR253, 0x34 },
};
static const u32 rv1[] = {
@@ -284,7 +286,7 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
0x6da010, /* Reg6 update for MP versio */
0xe36280, /* Modified by jxiao for Bor-Chin on 2004/08/02 */
0x116000,
- 0x9dc020, /* External control TX power (CR31) */
+ 0x9dc020, /* External control TX power (ZD_CR31) */
0x5ddb00, /* RegA update for MP version */
0xd99000, /* RegB update for MP version */
0x3ffbd0, /* RegC update for MP version */
@@ -295,8 +297,8 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
};
static const struct zd_ioreq16 ioreqs2[] = {
- { CR251, 0x2f }, /* shdnb(PLL_ON)=0 */
- { CR251, 0x7f }, /* shdnb(PLL_ON)=1 */
+ { ZD_CR251, 0x2f }, /* shdnb(PLL_ON)=0 */
+ { ZD_CR251, 0x7f }, /* shdnb(PLL_ON)=1 */
};
static const u32 rv3[] = {
@@ -308,7 +310,7 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
static const struct zd_ioreq16 ioreqs3[] = {
/* related to 6M band edge patching, happens unconditionally */
- { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
+ { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
};
r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1,
@@ -361,8 +363,8 @@ static int zd1211_al2230_set_channel(struct zd_rf *rf, u8 channel)
const u32 *rv = zd1211_al2230_table[channel-1];
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs[] = {
- { CR138, 0x28 },
- { CR203, 0x06 },
+ { ZD_CR138, 0x28 },
+ { ZD_CR203, 0x06 },
};
r = zd_rfwritev_locked(chip, rv, 3, RF_RV_BITS);
@@ -393,8 +395,8 @@ static int zd1211_al2230_switch_radio_on(struct zd_rf *rf)
{
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs[] = {
- { CR11, 0x00 },
- { CR251, 0x3f },
+ { ZD_CR11, 0x00 },
+ { ZD_CR251, 0x3f },
};
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -404,8 +406,8 @@ static int zd1211b_al2230_switch_radio_on(struct zd_rf *rf)
{
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs[] = {
- { CR11, 0x00 },
- { CR251, 0x7f },
+ { ZD_CR11, 0x00 },
+ { ZD_CR251, 0x7f },
};
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -415,8 +417,8 @@ static int al2230_switch_radio_off(struct zd_rf *rf)
{
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs[] = {
- { CR11, 0x04 },
- { CR251, 0x2f },
+ { ZD_CR11, 0x04 },
+ { ZD_CR251, 0x2f },
};
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
index 65095d661e6..385c670d129 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
@@ -68,19 +68,19 @@ static const u32 rv_init2[] = {
};
static const struct zd_ioreq16 ioreqs_sw[] = {
- { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
- { CR38, 0x38 }, { CR136, 0xdf },
+ { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
+ { ZD_CR38, 0x38 }, { ZD_CR136, 0xdf },
};
static int zd1211b_al7230b_finalize(struct zd_chip *chip)
{
int r;
static const struct zd_ioreq16 ioreqs[] = {
- { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 },
- { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 },
- { CR203, 0x04 },
+ { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 },
+ { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 },
+ { ZD_CR203, 0x04 },
{ },
- { CR240, 0x80 },
+ { ZD_CR240, 0x80 },
};
r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -89,12 +89,12 @@ static int zd1211b_al7230b_finalize(struct zd_chip *chip)
if (chip->new_phy_layout) {
/* antenna selection? */
- r = zd_iowrite16_locked(chip, 0xe5, CR9);
+ r = zd_iowrite16_locked(chip, 0xe5, ZD_CR9);
if (r)
return r;
}
- return zd_iowrite16_locked(chip, 0x04, CR203);
+ return zd_iowrite16_locked(chip, 0x04, ZD_CR203);
}
static int zd1211_al7230b_init_hw(struct zd_rf *rf)
@@ -106,66 +106,66 @@ static int zd1211_al7230b_init_hw(struct zd_rf *rf)
* specified */
static const struct zd_ioreq16 ioreqs_1[] = {
/* This one is 7230-specific, and happens before the rest */
- { CR240, 0x57 },
+ { ZD_CR240, 0x57 },
{ },
- { CR15, 0x20 }, { CR23, 0x40 }, { CR24, 0x20 },
- { CR26, 0x11 }, { CR28, 0x3e }, { CR29, 0x00 },
- { CR44, 0x33 },
+ { ZD_CR15, 0x20 }, { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 },
+ { ZD_CR26, 0x11 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
+ { ZD_CR44, 0x33 },
/* This value is different for 7230 (was: 0x2a) */
- { CR106, 0x22 },
- { CR107, 0x1a }, { CR109, 0x09 }, { CR110, 0x27 },
- { CR111, 0x2b }, { CR112, 0x2b }, { CR119, 0x0a },
+ { ZD_CR106, 0x22 },
+ { ZD_CR107, 0x1a }, { ZD_CR109, 0x09 }, { ZD_CR110, 0x27 },
+ { ZD_CR111, 0x2b }, { ZD_CR112, 0x2b }, { ZD_CR119, 0x0a },
/* This happened further down in AL2230,
* and the value changed (was: 0xe0) */
- { CR122, 0xfc },
- { CR10, 0x89 },
+ { ZD_CR122, 0xfc },
+ { ZD_CR10, 0x89 },
/* for newest (3rd cut) AL2300 */
- { CR17, 0x28 },
- { CR26, 0x93 }, { CR34, 0x30 },
+ { ZD_CR17, 0x28 },
+ { ZD_CR26, 0x93 }, { ZD_CR34, 0x30 },
/* for newest (3rd cut) AL2300 */
- { CR35, 0x3e },
- { CR41, 0x24 }, { CR44, 0x32 },
+ { ZD_CR35, 0x3e },
+ { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
/* for newest (3rd cut) AL2300 */
- { CR46, 0x96 },
- { CR47, 0x1e }, { CR79, 0x58 }, { CR80, 0x30 },
- { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 },
- { CR92, 0x0a }, { CR99, 0x28 },
+ { ZD_CR46, 0x96 },
+ { ZD_CR47, 0x1e }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 },
+ { ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 },
+ { ZD_CR92, 0x0a }, { ZD_CR99, 0x28 },
/* This value is different for 7230 (was: 0x00) */
- { CR100, 0x02 },
- { CR101, 0x13 }, { CR102, 0x27 },
+ { ZD_CR100, 0x02 },
+ { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 },
/* This value is different for 7230 (was: 0x24) */
- { CR106, 0x22 },
+ { ZD_CR106, 0x22 },
/* This value is different for 7230 (was: 0x2a) */
- { CR107, 0x3f },
- { CR109, 0x09 },
+ { ZD_CR107, 0x3f },
+ { ZD_CR109, 0x09 },
/* This value is different for 7230 (was: 0x13) */
- { CR110, 0x1f },
- { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 },
- { CR114, 0x27 },
+ { ZD_CR110, 0x1f },
+ { ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
+ { ZD_CR114, 0x27 },
/* for newest (3rd cut) AL2300 */
- { CR115, 0x24 },
+ { ZD_CR115, 0x24 },
/* This value is different for 7230 (was: 0x24) */
- { CR116, 0x3f },
+ { ZD_CR116, 0x3f },
/* This value is different for 7230 (was: 0xf4) */
- { CR117, 0xfa },
- { CR118, 0xfc }, { CR119, 0x10 }, { CR120, 0x4f },
- { CR121, 0x77 }, { CR137, 0x88 },
+ { ZD_CR117, 0xfa },
+ { ZD_CR118, 0xfc }, { ZD_CR119, 0x10 }, { ZD_CR120, 0x4f },
+ { ZD_CR121, 0x77 }, { ZD_CR137, 0x88 },
/* This one is 7230-specific */
- { CR138, 0xa8 },
+ { ZD_CR138, 0xa8 },
/* This value is different for 7230 (was: 0xff) */
- { CR252, 0x34 },
+ { ZD_CR252, 0x34 },
/* This value is different for 7230 (was: 0xff) */
- { CR253, 0x34 },
+ { ZD_CR253, 0x34 },
/* PLL_OFF */
- { CR251, 0x2f },
+ { ZD_CR251, 0x2f },
};
static const struct zd_ioreq16 ioreqs_2[] = {
- { CR251, 0x3f }, /* PLL_ON */
- { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
- { CR38, 0x38 }, { CR136, 0xdf },
+ { ZD_CR251, 0x3f }, /* PLL_ON */
+ { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
+ { ZD_CR38, 0x38 }, { ZD_CR136, 0xdf },
};
r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
@@ -192,10 +192,10 @@ static int zd1211_al7230b_init_hw(struct zd_rf *rf)
if (r)
return r;
- r = zd_iowrite16_locked(chip, 0x06, CR203);
+ r = zd_iowrite16_locked(chip, 0x06, ZD_CR203);
if (r)
return r;
- r = zd_iowrite16_locked(chip, 0x80, CR240);
+ r = zd_iowrite16_locked(chip, 0x80, ZD_CR240);
if (r)
return r;
@@ -208,79 +208,79 @@ static int zd1211b_al7230b_init_hw(struct zd_rf *rf)
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs_1[] = {
- { CR240, 0x57 }, { CR9, 0x9 },
+ { ZD_CR240, 0x57 }, { ZD_CR9, 0x9 },
{ },
- { CR10, 0x8b }, { CR15, 0x20 },
- { CR17, 0x2B }, /* for newest (3rd cut) AL2230 */
- { CR20, 0x10 }, /* 4N25->Stone Request */
- { CR23, 0x40 }, { CR24, 0x20 }, { CR26, 0x93 },
- { CR28, 0x3e }, { CR29, 0x00 },
- { CR33, 0x28 }, /* 5613 */
- { CR34, 0x30 },
- { CR35, 0x3e }, /* for newest (3rd cut) AL2230 */
- { CR41, 0x24 }, { CR44, 0x32 },
- { CR46, 0x99 }, /* for newest (3rd cut) AL2230 */
- { CR47, 0x1e },
+ { ZD_CR10, 0x8b }, { ZD_CR15, 0x20 },
+ { ZD_CR17, 0x2B }, /* for newest (3rd cut) AL2230 */
+ { ZD_CR20, 0x10 }, /* 4N25->Stone Request */
+ { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 },
+ { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
+ { ZD_CR33, 0x28 }, /* 5613 */
+ { ZD_CR34, 0x30 },
+ { ZD_CR35, 0x3e }, /* for newest (3rd cut) AL2230 */
+ { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
+ { ZD_CR46, 0x99 }, /* for newest (3rd cut) AL2230 */
+ { ZD_CR47, 0x1e },
/* ZD1215 5610 */
- { CR48, 0x00 }, { CR49, 0x00 }, { CR51, 0x01 },
- { CR52, 0x80 }, { CR53, 0x7e }, { CR65, 0x00 },
- { CR66, 0x00 }, { CR67, 0x00 }, { CR68, 0x00 },
- { CR69, 0x28 },
-
- { CR79, 0x58 }, { CR80, 0x30 }, { CR81, 0x30 },
- { CR87, 0x0A }, { CR89, 0x04 },
- { CR90, 0x58 }, /* 5112 */
- { CR91, 0x00 }, /* 5613 */
- { CR92, 0x0a },
- { CR98, 0x8d }, /* 4804, for 1212 new algorithm */
- { CR99, 0x00 }, { CR100, 0x02 }, { CR101, 0x13 },
- { CR102, 0x27 },
- { CR106, 0x20 }, /* change to 0x24 for AL7230B */
- { CR109, 0x13 }, /* 4804, for 1212 new algorithm */
- { CR112, 0x1f },
+ { ZD_CR48, 0x00 }, { ZD_CR49, 0x00 }, { ZD_CR51, 0x01 },
+ { ZD_CR52, 0x80 }, { ZD_CR53, 0x7e }, { ZD_CR65, 0x00 },
+ { ZD_CR66, 0x00 }, { ZD_CR67, 0x00 }, { ZD_CR68, 0x00 },
+ { ZD_CR69, 0x28 },
+
+ { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 },
+ { ZD_CR87, 0x0A }, { ZD_CR89, 0x04 },
+ { ZD_CR90, 0x58 }, /* 5112 */
+ { ZD_CR91, 0x00 }, /* 5613 */
+ { ZD_CR92, 0x0a },
+ { ZD_CR98, 0x8d }, /* 4804, for 1212 new algorithm */
+ { ZD_CR99, 0x00 }, { ZD_CR100, 0x02 }, { ZD_CR101, 0x13 },
+ { ZD_CR102, 0x27 },
+ { ZD_CR106, 0x20 }, /* change to 0x24 for AL7230B */
+ { ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */
+ { ZD_CR112, 0x1f },
};
static const struct zd_ioreq16 ioreqs_new_phy[] = {
- { CR107, 0x28 },
- { CR110, 0x1f }, /* 5127, 0x13->0x1f */
- { CR111, 0x1f }, /* 0x13 to 0x1f for AL7230B */
- { CR116, 0x2a }, { CR118, 0xfa }, { CR119, 0x12 },
- { CR121, 0x6c }, /* 5613 */
+ { ZD_CR107, 0x28 },
+ { ZD_CR110, 0x1f }, /* 5127, 0x13->0x1f */
+ { ZD_CR111, 0x1f }, /* 0x13 to 0x1f for AL7230B */
+ { ZD_CR116, 0x2a }, { ZD_CR118, 0xfa }, { ZD_CR119, 0x12 },
+ { ZD_CR121, 0x6c }, /* 5613 */
};
static const struct zd_ioreq16 ioreqs_old_phy[] = {
- { CR107, 0x24 },
- { CR110, 0x13 }, /* 5127, 0x13->0x1f */
- { CR111, 0x13 }, /* 0x13 to 0x1f for AL7230B */
- { CR116, 0x24 }, { CR118, 0xfc }, { CR119, 0x11 },
- { CR121, 0x6a }, /* 5613 */
+ { ZD_CR107, 0x24 },
+ { ZD_CR110, 0x13 }, /* 5127, 0x13->0x1f */
+ { ZD_CR111, 0x13 }, /* 0x13 to 0x1f for AL7230B */
+ { ZD_CR116, 0x24 }, { ZD_CR118, 0xfc }, { ZD_CR119, 0x11 },
+ { ZD_CR121, 0x6a }, /* 5613 */
};
static const struct zd_ioreq16 ioreqs_2[] = {
- { CR113, 0x27 }, { CR114, 0x27 }, { CR115, 0x24 },
- { CR117, 0xfa }, { CR120, 0x4f },
- { CR122, 0xfc }, /* E0->FCh at 4901 */
- { CR123, 0x57 }, /* 5613 */
- { CR125, 0xad }, /* 4804, for 1212 new algorithm */
- { CR126, 0x6c }, /* 5613 */
- { CR127, 0x03 }, /* 4804, for 1212 new algorithm */
- { CR130, 0x10 },
- { CR131, 0x00 }, /* 5112 */
- { CR137, 0x50 }, /* 5613 */
- { CR138, 0xa8 }, /* 5112 */
- { CR144, 0xac }, /* 5613 */
- { CR148, 0x40 }, /* 5112 */
- { CR149, 0x40 }, /* 4O07, 50->40 */
- { CR150, 0x1a }, /* 5112, 0C->1A */
- { CR252, 0x34 }, { CR253, 0x34 },
- { CR251, 0x2f }, /* PLL_OFF */
+ { ZD_CR113, 0x27 }, { ZD_CR114, 0x27 }, { ZD_CR115, 0x24 },
+ { ZD_CR117, 0xfa }, { ZD_CR120, 0x4f },
+ { ZD_CR122, 0xfc }, /* E0->FCh at 4901 */
+ { ZD_CR123, 0x57 }, /* 5613 */
+ { ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */
+ { ZD_CR126, 0x6c }, /* 5613 */
+ { ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */
+ { ZD_CR130, 0x10 },
+ { ZD_CR131, 0x00 }, /* 5112 */
+ { ZD_CR137, 0x50 }, /* 5613 */
+ { ZD_CR138, 0xa8 }, /* 5112 */
+ { ZD_CR144, 0xac }, /* 5613 */
+ { ZD_CR148, 0x40 }, /* 5112 */
+ { ZD_CR149, 0x40 }, /* 4O07, 50->40 */
+ { ZD_CR150, 0x1a }, /* 5112, 0C->1A */
+ { ZD_CR252, 0x34 }, { ZD_CR253, 0x34 },
+ { ZD_CR251, 0x2f }, /* PLL_OFF */
};
static const struct zd_ioreq16 ioreqs_3[] = {
- { CR251, 0x7f }, /* PLL_ON */
- { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
- { CR38, 0x38 }, { CR136, 0xdf },
+ { ZD_CR251, 0x7f }, /* PLL_ON */
+ { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
+ { ZD_CR38, 0x38 }, { ZD_CR136, 0xdf },
};
r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
@@ -331,16 +331,16 @@ static int zd1211_al7230b_set_channel(struct zd_rf *rf, u8 channel)
static const struct zd_ioreq16 ioreqs[] = {
/* PLL_ON */
- { CR251, 0x3f },
- { CR203, 0x06 }, { CR240, 0x08 },
+ { ZD_CR251, 0x3f },
+ { ZD_CR203, 0x06 }, { ZD_CR240, 0x08 },
};
- r = zd_iowrite16_locked(chip, 0x57, CR240);
+ r = zd_iowrite16_locked(chip, 0x57, ZD_CR240);
if (r)
return r;
/* PLL_OFF */
- r = zd_iowrite16_locked(chip, 0x2f, CR251);
+ r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251);
if (r)
return r;
@@ -376,15 +376,15 @@ static int zd1211b_al7230b_set_channel(struct zd_rf *rf, u8 channel)
const u32 *rv = chan_rv[channel-1];
struct zd_chip *chip = zd_rf_to_chip(rf);
- r = zd_iowrite16_locked(chip, 0x57, CR240);
+ r = zd_iowrite16_locked(chip, 0x57, ZD_CR240);
if (r)
return r;
- r = zd_iowrite16_locked(chip, 0xe4, CR9);
+ r = zd_iowrite16_locked(chip, 0xe4, ZD_CR9);
if (r)
return r;
/* PLL_OFF */
- r = zd_iowrite16_locked(chip, 0x2f, CR251);
+ r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251);
if (r)
return r;
r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
@@ -410,7 +410,7 @@ static int zd1211b_al7230b_set_channel(struct zd_rf *rf, u8 channel)
if (r)
return r;
- r = zd_iowrite16_locked(chip, 0x7f, CR251);
+ r = zd_iowrite16_locked(chip, 0x7f, ZD_CR251);
if (r)
return r;
@@ -421,8 +421,8 @@ static int zd1211_al7230b_switch_radio_on(struct zd_rf *rf)
{
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs[] = {
- { CR11, 0x00 },
- { CR251, 0x3f },
+ { ZD_CR11, 0x00 },
+ { ZD_CR251, 0x3f },
};
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -432,8 +432,8 @@ static int zd1211b_al7230b_switch_radio_on(struct zd_rf *rf)
{
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs[] = {
- { CR11, 0x00 },
- { CR251, 0x7f },
+ { ZD_CR11, 0x00 },
+ { ZD_CR251, 0x7f },
};
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -443,8 +443,8 @@ static int al7230b_switch_radio_off(struct zd_rf *rf)
{
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs[] = {
- { CR11, 0x04 },
- { CR251, 0x2f },
+ { ZD_CR11, 0x04 },
+ { ZD_CR251, 0x2f },
};
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -456,7 +456,7 @@ static int zd1211b_al7230b_patch_6m(struct zd_rf *rf, u8 channel)
{
struct zd_chip *chip = zd_rf_to_chip(rf);
struct zd_ioreq16 ioreqs[] = {
- { CR128, 0x14 }, { CR129, 0x12 },
+ { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 },
};
/* FIXME: Channel 11 is not the edge for all regulatory domains. */
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
index e36117486c9..784d9ccb8fe 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
@@ -152,44 +152,44 @@ static int rf2959_init_hw(struct zd_rf *rf)
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs[] = {
- { CR2, 0x1E }, { CR9, 0x20 }, { CR10, 0x89 },
- { CR11, 0x00 }, { CR15, 0xD0 }, { CR17, 0x68 },
- { CR19, 0x4a }, { CR20, 0x0c }, { CR21, 0x0E },
- { CR23, 0x48 },
+ { ZD_CR2, 0x1E }, { ZD_CR9, 0x20 }, { ZD_CR10, 0x89 },
+ { ZD_CR11, 0x00 }, { ZD_CR15, 0xD0 }, { ZD_CR17, 0x68 },
+ { ZD_CR19, 0x4a }, { ZD_CR20, 0x0c }, { ZD_CR21, 0x0E },
+ { ZD_CR23, 0x48 },
/* normal size for cca threshold */
- { CR24, 0x14 },
- /* { CR24, 0x20 }, */
- { CR26, 0x90 }, { CR27, 0x30 }, { CR29, 0x20 },
- { CR31, 0xb2 }, { CR32, 0x43 }, { CR33, 0x28 },
- { CR38, 0x30 }, { CR34, 0x0f }, { CR35, 0xF0 },
- { CR41, 0x2a }, { CR46, 0x7F }, { CR47, 0x1E },
- { CR51, 0xc5 }, { CR52, 0xc5 }, { CR53, 0xc5 },
- { CR79, 0x58 }, { CR80, 0x30 }, { CR81, 0x30 },
- { CR82, 0x00 }, { CR83, 0x24 }, { CR84, 0x04 },
- { CR85, 0x00 }, { CR86, 0x10 }, { CR87, 0x2A },
- { CR88, 0x10 }, { CR89, 0x24 }, { CR90, 0x18 },
- /* { CR91, 0x18 }, */
+ { ZD_CR24, 0x14 },
+ /* { ZD_CR24, 0x20 }, */
+ { ZD_CR26, 0x90 }, { ZD_CR27, 0x30 }, { ZD_CR29, 0x20 },
+ { ZD_CR31, 0xb2 }, { ZD_CR32, 0x43 }, { ZD_CR33, 0x28 },
+ { ZD_CR38, 0x30 }, { ZD_CR34, 0x0f }, { ZD_CR35, 0xF0 },
+ { ZD_CR41, 0x2a }, { ZD_CR46, 0x7F }, { ZD_CR47, 0x1E },
+ { ZD_CR51, 0xc5 }, { ZD_CR52, 0xc5 }, { ZD_CR53, 0xc5 },
+ { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 },
+ { ZD_CR82, 0x00 }, { ZD_CR83, 0x24 }, { ZD_CR84, 0x04 },
+ { ZD_CR85, 0x00 }, { ZD_CR86, 0x10 }, { ZD_CR87, 0x2A },
+ { ZD_CR88, 0x10 }, { ZD_CR89, 0x24 }, { ZD_CR90, 0x18 },
+ /* { ZD_CR91, 0x18 }, */
/* should solve continuous CTS frame problems */
- { CR91, 0x00 },
- { CR92, 0x0a }, { CR93, 0x00 }, { CR94, 0x01 },
- { CR95, 0x00 }, { CR96, 0x40 }, { CR97, 0x37 },
- { CR98, 0x05 }, { CR99, 0x28 }, { CR100, 0x00 },
- { CR101, 0x13 }, { CR102, 0x27 }, { CR103, 0x27 },
- { CR104, 0x18 }, { CR105, 0x12 },
+ { ZD_CR91, 0x00 },
+ { ZD_CR92, 0x0a }, { ZD_CR93, 0x00 }, { ZD_CR94, 0x01 },
+ { ZD_CR95, 0x00 }, { ZD_CR96, 0x40 }, { ZD_CR97, 0x37 },
+ { ZD_CR98, 0x05 }, { ZD_CR99, 0x28 }, { ZD_CR100, 0x00 },
+ { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, { ZD_CR103, 0x27 },
+ { ZD_CR104, 0x18 }, { ZD_CR105, 0x12 },
/* normal size */
- { CR106, 0x1a },
- /* { CR106, 0x22 }, */
- { CR107, 0x24 }, { CR108, 0x0a }, { CR109, 0x13 },
- { CR110, 0x2F }, { CR111, 0x27 }, { CR112, 0x27 },
- { CR113, 0x27 }, { CR114, 0x27 }, { CR115, 0x40 },
- { CR116, 0x40 }, { CR117, 0xF0 }, { CR118, 0xF0 },
- { CR119, 0x16 },
+ { ZD_CR106, 0x1a },
+ /* { ZD_CR106, 0x22 }, */
+ { ZD_CR107, 0x24 }, { ZD_CR108, 0x0a }, { ZD_CR109, 0x13 },
+ { ZD_CR110, 0x2F }, { ZD_CR111, 0x27 }, { ZD_CR112, 0x27 },
+ { ZD_CR113, 0x27 }, { ZD_CR114, 0x27 }, { ZD_CR115, 0x40 },
+ { ZD_CR116, 0x40 }, { ZD_CR117, 0xF0 }, { ZD_CR118, 0xF0 },
+ { ZD_CR119, 0x16 },
/* no TX continuation */
- { CR122, 0x00 },
- /* { CR122, 0xff }, */
- { CR127, 0x03 }, { CR131, 0x08 }, { CR138, 0x28 },
- { CR148, 0x44 }, { CR150, 0x10 }, { CR169, 0xBB },
- { CR170, 0xBB },
+ { ZD_CR122, 0x00 },
+ /* { ZD_CR122, 0xff }, */
+ { ZD_CR127, 0x03 }, { ZD_CR131, 0x08 }, { ZD_CR138, 0x28 },
+ { ZD_CR148, 0x44 }, { ZD_CR150, 0x10 }, { ZD_CR169, 0xBB },
+ { ZD_CR170, 0xBB },
};
static const u32 rv[] = {
@@ -210,7 +210,7 @@ static int rf2959_init_hw(struct zd_rf *rf)
*/
0x294128, /* internal power */
/* 0x28252c, */ /* External control TX power */
- /* CR31_CCK, CR51_6-36M, CR52_48M, CR53_54M */
+ /* ZD_CR31_CCK, ZD_CR51_6-36M, ZD_CR52_48M, ZD_CR53_54M */
0x2c0000,
0x300000,
0x340000, /* REG13(0xD) */
@@ -245,8 +245,8 @@ static int rf2959_set_channel(struct zd_rf *rf, u8 channel)
static int rf2959_switch_radio_on(struct zd_rf *rf)
{
static const struct zd_ioreq16 ioreqs[] = {
- { CR10, 0x89 },
- { CR11, 0x00 },
+ { ZD_CR10, 0x89 },
+ { ZD_CR11, 0x00 },
};
struct zd_chip *chip = zd_rf_to_chip(rf);
@@ -256,8 +256,8 @@ static int rf2959_switch_radio_on(struct zd_rf *rf)
static int rf2959_switch_radio_off(struct zd_rf *rf)
{
static const struct zd_ioreq16 ioreqs[] = {
- { CR10, 0x15 },
- { CR11, 0x81 },
+ { ZD_CR10, 0x15 },
+ { ZD_CR11, 0x81 },
};
struct zd_chip *chip = zd_rf_to_chip(rf);
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
index ba0a0ccb1fa..c4d324e19c2 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
@@ -314,42 +314,44 @@ static int uw2453_init_hw(struct zd_rf *rf)
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs[] = {
- { CR10, 0x89 }, { CR15, 0x20 },
- { CR17, 0x28 }, /* 6112 no change */
- { CR23, 0x38 }, { CR24, 0x20 }, { CR26, 0x93 },
- { CR27, 0x15 }, { CR28, 0x3e }, { CR29, 0x00 },
- { CR33, 0x28 }, { CR34, 0x30 },
- { CR35, 0x43 }, /* 6112 3e->43 */
- { CR41, 0x24 }, { CR44, 0x32 },
- { CR46, 0x92 }, /* 6112 96->92 */
- { CR47, 0x1e },
- { CR48, 0x04 }, /* 5602 Roger */
- { CR49, 0xfa }, { CR79, 0x58 }, { CR80, 0x30 },
- { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 },
- { CR91, 0x00 }, { CR92, 0x0a }, { CR98, 0x8d },
- { CR99, 0x28 }, { CR100, 0x02 },
- { CR101, 0x09 }, /* 6112 13->1f 6220 1f->13 6407 13->9 */
- { CR102, 0x27 },
- { CR106, 0x1c }, /* 5d07 5112 1f->1c 6220 1c->1f 6221 1f->1c */
- { CR107, 0x1c }, /* 6220 1c->1a 5221 1a->1c */
- { CR109, 0x13 },
- { CR110, 0x1f }, /* 6112 13->1f 6221 1f->13 6407 13->0x09 */
- { CR111, 0x13 }, { CR112, 0x1f }, { CR113, 0x27 },
- { CR114, 0x23 }, /* 6221 27->23 */
- { CR115, 0x24 }, /* 6112 24->1c 6220 1c->24 */
- { CR116, 0x24 }, /* 6220 1c->24 */
- { CR117, 0xfa }, /* 6112 fa->f8 6220 f8->f4 6220 f4->fa */
- { CR118, 0xf0 }, /* 5d07 6112 f0->f2 6220 f2->f0 */
- { CR119, 0x1a }, /* 6112 1a->10 6220 10->14 6220 14->1a */
- { CR120, 0x4f },
- { CR121, 0x1f }, /* 6220 4f->1f */
- { CR122, 0xf0 }, { CR123, 0x57 }, { CR125, 0xad },
- { CR126, 0x6c }, { CR127, 0x03 },
- { CR128, 0x14 }, /* 6302 12->11 */
- { CR129, 0x12 }, /* 6301 10->0f */
- { CR130, 0x10 }, { CR137, 0x50 }, { CR138, 0xa8 },
- { CR144, 0xac }, { CR146, 0x20 }, { CR252, 0xff },
- { CR253, 0xff },
+ { ZD_CR10, 0x89 }, { ZD_CR15, 0x20 },
+ { ZD_CR17, 0x28 }, /* 6112 no change */
+ { ZD_CR23, 0x38 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 },
+ { ZD_CR27, 0x15 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
+ { ZD_CR33, 0x28 }, { ZD_CR34, 0x30 },
+ { ZD_CR35, 0x43 }, /* 6112 3e->43 */
+ { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
+ { ZD_CR46, 0x92 }, /* 6112 96->92 */
+ { ZD_CR47, 0x1e },
+ { ZD_CR48, 0x04 }, /* 5602 Roger */
+ { ZD_CR49, 0xfa }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 },
+ { ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 },
+ { ZD_CR91, 0x00 }, { ZD_CR92, 0x0a }, { ZD_CR98, 0x8d },
+ { ZD_CR99, 0x28 }, { ZD_CR100, 0x02 },
+ { ZD_CR101, 0x09 }, /* 6112 13->1f 6220 1f->13 6407 13->9 */
+ { ZD_CR102, 0x27 },
+ { ZD_CR106, 0x1c }, /* 5d07 5112 1f->1c 6220 1c->1f
+ * 6221 1f->1c
+ */
+ { ZD_CR107, 0x1c }, /* 6220 1c->1a 5221 1a->1c */
+ { ZD_CR109, 0x13 },
+ { ZD_CR110, 0x1f }, /* 6112 13->1f 6221 1f->13 6407 13->0x09 */
+ { ZD_CR111, 0x13 }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
+ { ZD_CR114, 0x23 }, /* 6221 27->23 */
+ { ZD_CR115, 0x24 }, /* 6112 24->1c 6220 1c->24 */
+ { ZD_CR116, 0x24 }, /* 6220 1c->24 */
+ { ZD_CR117, 0xfa }, /* 6112 fa->f8 6220 f8->f4 6220 f4->fa */
+ { ZD_CR118, 0xf0 }, /* 5d07 6112 f0->f2 6220 f2->f0 */
+ { ZD_CR119, 0x1a }, /* 6112 1a->10 6220 10->14 6220 14->1a */
+ { ZD_CR120, 0x4f },
+ { ZD_CR121, 0x1f }, /* 6220 4f->1f */
+ { ZD_CR122, 0xf0 }, { ZD_CR123, 0x57 }, { ZD_CR125, 0xad },
+ { ZD_CR126, 0x6c }, { ZD_CR127, 0x03 },
+ { ZD_CR128, 0x14 }, /* 6302 12->11 */
+ { ZD_CR129, 0x12 }, /* 6301 10->0f */
+ { ZD_CR130, 0x10 }, { ZD_CR137, 0x50 }, { ZD_CR138, 0xa8 },
+ { ZD_CR144, 0xac }, { ZD_CR146, 0x20 }, { ZD_CR252, 0xff },
+ { ZD_CR253, 0xff },
};
static const u32 rv[] = {
@@ -433,7 +435,7 @@ static int uw2453_init_hw(struct zd_rf *rf)
* the one that produced a lock. */
UW2453_PRIV(rf)->config = found_config + 1;
- return zd_iowrite16_locked(chip, 0x06, CR203);
+ return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
}
static int uw2453_set_channel(struct zd_rf *rf, u8 channel)
@@ -445,8 +447,8 @@ static int uw2453_set_channel(struct zd_rf *rf, u8 channel)
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs[] = {
- { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 },
- { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 },
+ { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 },
+ { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 },
};
r = uw2453_synth_set_channel(chip, channel, autocal);
@@ -474,7 +476,7 @@ static int uw2453_set_channel(struct zd_rf *rf, u8 channel)
if (r)
return r;
- return zd_iowrite16_locked(chip, 0x06, CR203);
+ return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
}
static int uw2453_switch_radio_on(struct zd_rf *rf)
@@ -482,7 +484,7 @@ static int uw2453_switch_radio_on(struct zd_rf *rf)
int r;
struct zd_chip *chip = zd_rf_to_chip(rf);
struct zd_ioreq16 ioreqs[] = {
- { CR11, 0x00 }, { CR251, 0x3f },
+ { ZD_CR11, 0x00 }, { ZD_CR251, 0x3f },
};
/* enter RXTX mode */
@@ -501,7 +503,7 @@ static int uw2453_switch_radio_off(struct zd_rf *rf)
int r;
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs[] = {
- { CR11, 0x04 }, { CR251, 0x2f },
+ { ZD_CR11, 0x04 }, { ZD_CR251, 0x2f },
};
/* enter IDLE mode */
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index ab607bbd629..0e819943b9e 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -1893,10 +1893,10 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits)
dev_dbg_f(zd_usb_dev(usb), "value %#09x bits %d\n", value, bits);
- r = zd_usb_ioread16(usb, &bit_value_template, CR203);
+ r = zd_usb_ioread16(usb, &bit_value_template, ZD_CR203);
if (r) {
dev_dbg_f(zd_usb_dev(usb),
- "error %d: Couldn't read CR203\n", r);
+ "error %d: Couldn't read ZD_CR203\n", r);
return r;
}
bit_value_template &= ~(RF_IF_LE|RF_CLK|RF_DATA);
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h
index 325d0f98925..bf942843b73 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.h
+++ b/drivers/net/wireless/zd1211rw/zd_usb.h
@@ -109,7 +109,7 @@ struct usb_req_rfwrite {
__le16 bits;
/* RF2595: 24 */
__le16 bit_values[0];
- /* (CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */
+ /* (ZD_CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */
} __packed;
/* USB interrupt */
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
index 5d7bbf2b2ee..161f207786a 100644
--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -73,9 +73,6 @@ struct xenvif {
struct vm_struct *tx_comms_area;
struct vm_struct *rx_comms_area;
- /* Flags that must not be set in dev->features */
- u32 features_disabled;
-
/* Frontend feature information. */
u8 can_sg:1;
u8 gso:1;
@@ -109,8 +106,8 @@ struct xenvif {
wait_queue_head_t waiting_to_free;
};
-#define XEN_NETIF_TX_RING_SIZE __RING_SIZE((struct xen_netif_tx_sring *)0, PAGE_SIZE)
-#define XEN_NETIF_RX_RING_SIZE __RING_SIZE((struct xen_netif_rx_sring *)0, PAGE_SIZE)
+#define XEN_NETIF_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE)
+#define XEN_NETIF_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE)
struct xenvif *xenvif_alloc(struct device *parent,
domid_t domid,
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index de569cc19da..0ca86f9ec4e 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -165,69 +165,18 @@ static int xenvif_change_mtu(struct net_device *dev, int mtu)
return 0;
}
-static void xenvif_set_features(struct xenvif *vif)
-{
- struct net_device *dev = vif->dev;
- u32 features = dev->features;
-
- if (vif->can_sg)
- features |= NETIF_F_SG;
- if (vif->gso || vif->gso_prefix)
- features |= NETIF_F_TSO;
- if (vif->csum)
- features |= NETIF_F_IP_CSUM;
-
- features &= ~(vif->features_disabled);
-
- if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN)
- dev->mtu = ETH_DATA_LEN;
-
- dev->features = features;
-}
-
-static int xenvif_set_tx_csum(struct net_device *dev, u32 data)
-{
- struct xenvif *vif = netdev_priv(dev);
- if (data) {
- if (!vif->csum)
- return -EOPNOTSUPP;
- vif->features_disabled &= ~NETIF_F_IP_CSUM;
- } else {
- vif->features_disabled |= NETIF_F_IP_CSUM;
- }
-
- xenvif_set_features(vif);
- return 0;
-}
-
-static int xenvif_set_sg(struct net_device *dev, u32 data)
+static u32 xenvif_fix_features(struct net_device *dev, u32 features)
{
struct xenvif *vif = netdev_priv(dev);
- if (data) {
- if (!vif->can_sg)
- return -EOPNOTSUPP;
- vif->features_disabled &= ~NETIF_F_SG;
- } else {
- vif->features_disabled |= NETIF_F_SG;
- }
- xenvif_set_features(vif);
- return 0;
-}
+ if (!vif->can_sg)
+ features &= ~NETIF_F_SG;
+ if (!vif->gso && !vif->gso_prefix)
+ features &= ~NETIF_F_TSO;
+ if (!vif->csum)
+ features &= ~NETIF_F_IP_CSUM;
-static int xenvif_set_tso(struct net_device *dev, u32 data)
-{
- struct xenvif *vif = netdev_priv(dev);
- if (data) {
- if (!vif->gso && !vif->gso_prefix)
- return -EOPNOTSUPP;
- vif->features_disabled &= ~NETIF_F_TSO;
- } else {
- vif->features_disabled |= NETIF_F_TSO;
- }
-
- xenvif_set_features(vif);
- return 0;
+ return features;
}
static const struct xenvif_stat {
@@ -274,12 +223,6 @@ static void xenvif_get_strings(struct net_device *dev, u32 stringset, u8 * data)
}
static struct ethtool_ops xenvif_ethtool_ops = {
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = xenvif_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = xenvif_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = xenvif_set_tso,
.get_link = ethtool_op_get_link,
.get_sset_count = xenvif_get_sset_count,
@@ -293,6 +236,7 @@ static struct net_device_ops xenvif_netdev_ops = {
.ndo_open = xenvif_open,
.ndo_stop = xenvif_close,
.ndo_change_mtu = xenvif_change_mtu,
+ .ndo_fix_features = xenvif_fix_features,
};
struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
@@ -331,7 +275,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
vif->credit_timeout.expires = jiffies;
dev->netdev_ops = &xenvif_netdev_ops;
- xenvif_set_features(vif);
+ dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
+ dev->features = dev->hw_features;
SET_ETHTOOL_OPS(dev, &xenvif_ethtool_ops);
dev->tx_queue_len = XENVIF_QUEUE_LENGTH;
@@ -367,8 +312,6 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
if (vif->irq)
return 0;
- xenvif_set_features(vif);
-
err = xen_netbk_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref);
if (err < 0)
goto err;
@@ -384,9 +327,12 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
xenvif_get(vif);
rtnl_lock();
- netif_carrier_on(vif->dev);
if (netif_running(vif->dev))
xenvif_up(vif);
+ if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN)
+ dev_set_mtu(vif->dev, ETH_DATA_LEN);
+ netdev_update_features(vif->dev);
+ netif_carrier_on(vif->dev);
rtnl_unlock();
return 0;
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index 22b8c350599..1ce729d6af7 100644
--- a/drivers/net/xen-netback/xenbus.c
+++ b/drivers/net/xen-netback/xenbus.c
@@ -26,7 +26,7 @@ struct backend_info {
struct xenvif *vif;
enum xenbus_state frontend_state;
struct xenbus_watch hotplug_status_watch;
- int have_hotplug_status_watch:1;
+ u8 have_hotplug_status_watch:1;
};
static int connect_rings(struct backend_info *);
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 5c8d9c385be..db9a763aaa7 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1140,6 +1140,42 @@ static void xennet_uninit(struct net_device *dev)
gnttab_free_grant_references(np->gref_rx_head);
}
+static u32 xennet_fix_features(struct net_device *dev, u32 features)
+{
+ struct netfront_info *np = netdev_priv(dev);
+ int val;
+
+ if (features & NETIF_F_SG) {
+ if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg",
+ "%d", &val) < 0)
+ val = 0;
+
+ if (!val)
+ features &= ~NETIF_F_SG;
+ }
+
+ if (features & NETIF_F_TSO) {
+ if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
+ "feature-gso-tcpv4", "%d", &val) < 0)
+ val = 0;
+
+ if (!val)
+ features &= ~NETIF_F_TSO;
+ }
+
+ return features;
+}
+
+static int xennet_set_features(struct net_device *dev, u32 features)
+{
+ if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN) {
+ netdev_info(dev, "Reducing MTU because no SG offload");
+ dev->mtu = ETH_DATA_LEN;
+ }
+
+ return 0;
+}
+
static const struct net_device_ops xennet_netdev_ops = {
.ndo_open = xennet_open,
.ndo_uninit = xennet_uninit,
@@ -1148,6 +1184,8 @@ static const struct net_device_ops xennet_netdev_ops = {
.ndo_change_mtu = xennet_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_fix_features = xennet_fix_features,
+ .ndo_set_features = xennet_set_features,
};
static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev)
@@ -1209,7 +1247,17 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev
netdev->netdev_ops = &xennet_netdev_ops;
netif_napi_add(netdev, &np->napi, xennet_poll, 64);
- netdev->features = NETIF_F_IP_CSUM;
+ netdev->features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
+ NETIF_F_GSO_ROBUST;
+ netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO;
+
+ /*
+ * Assume that all hw features are available for now. This set
+ * will be adjusted by the call to netdev_update_features() in
+ * xennet_connect() which is the earliest point where we can
+ * negotiate with the backend regarding supported features.
+ */
+ netdev->features |= netdev->hw_features;
SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops);
SET_NETDEV_DEV(netdev, &dev->dev);
@@ -1416,8 +1464,7 @@ static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info)
goto fail;
err = bind_evtchn_to_irqhandler(info->evtchn, xennet_interrupt,
- IRQF_SAMPLE_RANDOM, netdev->name,
- netdev);
+ 0, netdev->name, netdev);
if (err < 0)
goto fail;
netdev->irq = err;
@@ -1510,54 +1557,6 @@ again:
return err;
}
-static int xennet_set_sg(struct net_device *dev, u32 data)
-{
- if (data) {
- struct netfront_info *np = netdev_priv(dev);
- int val;
-
- if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg",
- "%d", &val) < 0)
- val = 0;
- if (!val)
- return -ENOSYS;
- } else if (dev->mtu > ETH_DATA_LEN)
- dev->mtu = ETH_DATA_LEN;
-
- return ethtool_op_set_sg(dev, data);
-}
-
-static int xennet_set_tso(struct net_device *dev, u32 data)
-{
- if (data) {
- struct netfront_info *np = netdev_priv(dev);
- int val;
-
- if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
- "feature-gso-tcpv4", "%d", &val) < 0)
- val = 0;
- if (!val)
- return -ENOSYS;
- }
-
- return ethtool_op_set_tso(dev, data);
-}
-
-static void xennet_set_features(struct net_device *dev)
-{
- /* Turn off all GSO bits except ROBUST. */
- dev->features &= ~NETIF_F_GSO_MASK;
- dev->features |= NETIF_F_GSO_ROBUST;
- xennet_set_sg(dev, 0);
-
- /* We need checksum offload to enable scatter/gather and TSO. */
- if (!(dev->features & NETIF_F_IP_CSUM))
- return;
-
- if (!xennet_set_sg(dev, 1))
- xennet_set_tso(dev, 1);
-}
-
static int xennet_connect(struct net_device *dev)
{
struct netfront_info *np = netdev_priv(dev);
@@ -1582,7 +1581,7 @@ static int xennet_connect(struct net_device *dev)
if (err)
return err;
- xennet_set_features(dev);
+ netdev_update_features(dev);
spin_lock_bh(&np->rx_lock);
spin_lock_irq(&np->tx_lock);
@@ -1710,9 +1709,6 @@ static void xennet_get_strings(struct net_device *dev, u32 stringset, u8 * data)
static const struct ethtool_ops xennet_ethtool_ops =
{
- .set_tx_csum = ethtool_op_set_tx_csum,
- .set_sg = xennet_set_sg,
- .set_tso = xennet_set_tso,
.get_link = ethtool_op_get_link,
.get_sset_count = xennet_get_sset_count,
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index da8aa75bb20..f1fa2483ae6 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -845,12 +845,10 @@ claw_irq_tasklet ( unsigned long data )
{
struct chbk * p_ch;
struct net_device *dev;
- struct claw_privbk * privptr;
p_ch = (struct chbk *) data;
dev = (struct net_device *)p_ch->ndev;
CLAW_DBF_TEXT(4, trace, "IRQtask");
- privptr = (struct claw_privbk *)dev->ml_priv;
unpack_read(dev);
clear_bit(CLAW_BH_ACTIVE, (void *)&p_ch->flag_a);
CLAW_DBF_TEXT(4, trace, "TskletXt");
@@ -1026,7 +1024,6 @@ claw_write_next ( struct chbk * p_ch )
struct net_device *dev;
struct claw_privbk *privptr=NULL;
struct sk_buff *pk_skb;
- int rc;
CLAW_DBF_TEXT(4, trace, "claw_wrt");
if (p_ch->claw_state == CLAW_STOP)
@@ -1038,7 +1035,7 @@ claw_write_next ( struct chbk * p_ch )
!skb_queue_empty(&p_ch->collect_queue)) {
pk_skb = claw_pack_skb(privptr);
while (pk_skb != NULL) {
- rc = claw_hw_tx( pk_skb, dev,1);
+ claw_hw_tx(pk_skb, dev, 1);
if (privptr->write_free_count > 0) {
pk_skb = claw_pack_skb(privptr);
} else
@@ -1322,15 +1319,12 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
unsigned char *pDataAddress;
struct endccw *pEnd;
struct ccw1 tempCCW;
- struct chbk *p_ch;
struct claw_env *p_env;
- int lock;
struct clawph *pk_head;
struct chbk *ch;
CLAW_DBF_TEXT(4, trace, "hw_tx");
privptr = (struct claw_privbk *)(dev->ml_priv);
- p_ch = (struct chbk *)&privptr->channel[WRITE_CHANNEL];
p_env =privptr->p_env;
claw_free_wrt_buf(dev); /* Clean up free chain if posible */
/* scan the write queue to free any completed write packets */
@@ -1511,12 +1505,6 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
} /* endif (p_first_ccw!=NULL) */
dev_kfree_skb_any(skb);
- if (linkid==0) {
- lock=LOCK_NO;
- }
- else {
- lock=LOCK_YES;
- }
claw_strt_out_IO(dev );
/* if write free count is zero , set NOBUFFER */
if (privptr->write_free_count==0) {
@@ -2821,15 +2809,11 @@ claw_free_wrt_buf( struct net_device *dev )
{
struct claw_privbk *privptr = (struct claw_privbk *)dev->ml_priv;
- struct ccwbk*p_first_ccw;
- struct ccwbk*p_last_ccw;
struct ccwbk*p_this_ccw;
struct ccwbk*p_next_ccw;
CLAW_DBF_TEXT(4, trace, "freewrtb");
/* scan the write queue to free any completed write packets */
- p_first_ccw=NULL;
- p_last_ccw=NULL;
p_this_ccw=privptr->p_write_active_first;
while ( (p_this_ccw!=NULL) && (p_this_ccw->header.flag!=CLAW_PENDING))
{
@@ -3072,7 +3056,7 @@ claw_shutdown_device(struct ccwgroup_device *cgdev)
{
struct claw_privbk *priv;
struct net_device *ndev;
- int ret;
+ int ret = 0;
CLAW_DBF_TEXT_(2, setup, "%s", dev_name(&cgdev->dev));
priv = dev_get_drvdata(&cgdev->dev);
@@ -3095,7 +3079,7 @@ claw_shutdown_device(struct ccwgroup_device *cgdev)
}
ccw_device_set_offline(cgdev->cdev[1]);
ccw_device_set_offline(cgdev->cdev[0]);
- return 0;
+ return ret;
}
static void
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index c189296763a..426787efc49 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -672,7 +672,6 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
int ccw_idx;
unsigned long hi;
unsigned long saveflags = 0; /* avoids compiler warning */
- __u16 block_len;
CTCM_PR_DEBUG("Enter %s: %s, cp=%i ch=0x%p id=%s state=%s\n",
__func__, dev->name, smp_processor_id(), ch,
@@ -719,7 +718,6 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
*/
atomic_inc(&skb->users);
- block_len = skb->len + TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
/*
* IDAL support in CTCM is broken, so we have to
* care about skb's above 2G ourselves.
diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c
index b64881f33f2..da4c747335e 100644
--- a/drivers/s390/net/ctcm_mpc.c
+++ b/drivers/s390/net/ctcm_mpc.c
@@ -653,7 +653,6 @@ static void ctcmpc_send_sweep_resp(struct channel *rch)
struct net_device *dev = rch->netdev;
struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
- int rc = 0;
struct th_sweep *header;
struct sk_buff *sweep_skb;
struct channel *ch = priv->channel[CTCM_WRITE];
@@ -665,16 +664,14 @@ static void ctcmpc_send_sweep_resp(struct channel *rch)
CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
"%s(%s): sweep_skb allocation ERROR\n",
CTCM_FUNTAIL, rch->id);
- rc = -ENOMEM;
- goto done;
+ goto done;
}
header = kmalloc(sizeof(struct th_sweep), gfp_type());
if (!header) {
dev_kfree_skb_any(sweep_skb);
- rc = -ENOMEM;
- goto done;
+ goto done;
}
header->th.th_seg = 0x00 ;
@@ -1370,8 +1367,7 @@ static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
struct net_device *dev = arg;
struct ctcm_priv *priv;
struct mpc_group *grp;
- int rc = 0;
- struct channel *wch, *rch;
+ struct channel *wch;
BUG_ON(dev == NULL);
CTCM_PR_DEBUG("Enter %s: %s\n", __func__, dev->name);
@@ -1396,7 +1392,6 @@ static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
fsm_deltimer(&priv->restart_timer);
wch = priv->channel[CTCM_WRITE];
- rch = priv->channel[CTCM_READ];
switch (grp->saved_state) {
case MPCG_STATE_RESET:
@@ -1435,7 +1430,7 @@ static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
if (grp->send_qllc_disc == 1) {
grp->send_qllc_disc = 0;
- rc = mpc_send_qllc_discontact(dev);
+ mpc_send_qllc_discontact(dev);
}
/* DO NOT issue DEV_EVENT_STOP directly out of this code */
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 49d1cfc3217..c3b8064a102 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -1483,7 +1483,6 @@ lcs_tasklet(unsigned long data)
struct lcs_channel *channel;
struct lcs_buffer *iob;
int buf_idx;
- int rc;
channel = (struct lcs_channel *) data;
LCS_DBF_TEXT_(5, trace, "tlet%s", dev_name(&channel->ccwdev->dev));
@@ -1500,14 +1499,11 @@ lcs_tasklet(unsigned long data)
channel->buf_idx = buf_idx;
if (channel->state == LCS_CH_STATE_STOPPED)
- // FIXME: what if rc != 0 ??
- rc = lcs_start_channel(channel);
+ lcs_start_channel(channel);
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
if (channel->state == LCS_CH_STATE_SUSPENDED &&
- channel->iob[channel->io_idx].state == LCS_BUF_STATE_READY) {
- // FIXME: what if rc != 0 ??
- rc = __lcs_resume_channel(channel);
- }
+ channel->iob[channel->io_idx].state == LCS_BUF_STATE_READY)
+ __lcs_resume_channel(channel);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
/* Something happened on the channel. Wake up waiters. */
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index b6a6356d09b..3251333a23d 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1994,8 +1994,6 @@ static struct net_device *netiucv_init_netdevice(char *username)
netiucv_setup_netdevice);
if (!dev)
return NULL;
- if (dev_alloc_name(dev, dev->name) < 0)
- goto out_netdev;
privptr = netdev_priv(dev);
privptr->fsm = init_fsm("netiucvdev", dev_state_names,
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index af3f7b09564..55c6aa1c970 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -407,12 +407,6 @@ struct qeth_qdio_q {
int next_buf_to_init;
} __attribute__ ((aligned(256)));
-/* possible types of qeth large_send support */
-enum qeth_large_send_types {
- QETH_LARGE_SEND_NO,
- QETH_LARGE_SEND_TSO,
-};
-
struct qeth_qdio_out_buffer {
struct qdio_buffer *buffer;
atomic_t state;
@@ -637,6 +631,8 @@ struct qeth_card_info {
__u32 csum_mask;
__u32 tx_csum_mask;
enum qeth_ipa_promisc_modes promisc_mode;
+ __u32 diagass_support;
+ __u32 hwtrap;
};
struct qeth_card_options {
@@ -645,13 +641,11 @@ struct qeth_card_options {
struct qeth_ipa_info adp; /*Adapter parameters*/
struct qeth_routing_info route6;
struct qeth_ipa_info ipa6;
- enum qeth_checksum_types checksum_type;
int broadcast_mode;
int macaddr_mode;
int fake_broadcast;
int add_hhlen;
int layer2;
- enum qeth_large_send_types large_send;
int performance_stats;
int rx_sg_cb;
enum qeth_ipa_isolation_modes isolation;
@@ -760,6 +754,14 @@ struct qeth_card_list_struct {
rwlock_t rwlock;
};
+struct qeth_trap_id {
+ __u16 lparnr;
+ char vmname[8];
+ __u8 chpid;
+ __u8 ssid;
+ __u16 devno;
+} __packed;
+
/*some helper functions*/
#define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "")
@@ -794,6 +796,12 @@ static inline void qeth_put_buffer_pool_entry(struct qeth_card *card,
list_add_tail(&entry->list, &card->qdio.in_buf_pool.entry_list);
}
+static inline int qeth_is_diagass_supported(struct qeth_card *card,
+ enum qeth_diags_cmds cmd)
+{
+ return card->info.diagass_support & (__u32)cmd;
+}
+
extern struct ccwgroup_driver qeth_l2_ccwgroup_driver;
extern struct ccwgroup_driver qeth_l3_ccwgroup_driver;
const char *qeth_get_cardname_short(struct qeth_card *);
@@ -879,6 +887,8 @@ void qeth_dbf_longtext(debug_info_t *id, int level, char *text, ...);
int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *);
int qeth_set_access_ctrl_online(struct qeth_card *card);
int qeth_hdr_chk_and_bounce(struct sk_buff *, int);
+int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action);
+int qeth_query_ipassists(struct qeth_card *, enum qeth_prot_versions prot);
/* exports for OSN */
int qeth_osn_assist(struct net_device *, void *, int);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 85cc53117ea..503678a3098 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -24,6 +24,7 @@
#include <asm/ebcdic.h>
#include <asm/io.h>
+#include <asm/sysinfo.h>
#include "qeth_core.h"
@@ -349,6 +350,8 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
card->info.chpid);
netif_carrier_on(card->dev);
card->lan_online = 1;
+ if (card->info.hwtrap)
+ card->info.hwtrap = 2;
qeth_schedule_recovery(card);
return NULL;
case IPA_CMD_MODCCID:
@@ -1039,7 +1042,6 @@ static void qeth_set_intial_options(struct qeth_card *card)
{
card->options.route4.type = NO_ROUTER;
card->options.route6.type = NO_ROUTER;
- card->options.checksum_type = QETH_CHECKSUM_DEFAULT;
card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
card->options.macaddr_mode = QETH_TR_MACADDR_NONCANONICAL;
card->options.fake_broadcast = 0;
@@ -2574,6 +2576,142 @@ int qeth_query_setadapterparms(struct qeth_card *card)
}
EXPORT_SYMBOL_GPL(qeth_query_setadapterparms);
+static int qeth_query_ipassists_cb(struct qeth_card *card,
+ struct qeth_reply *reply, unsigned long data)
+{
+ struct qeth_ipa_cmd *cmd;
+
+ QETH_DBF_TEXT(SETUP, 2, "qipasscb");
+
+ cmd = (struct qeth_ipa_cmd *) data;
+ if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
+ card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
+ card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
+ } else {
+ card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
+ card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
+ }
+ QETH_DBF_TEXT(SETUP, 2, "suppenbl");
+ QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_supported);
+ QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_enabled);
+ return 0;
+}
+
+int qeth_query_ipassists(struct qeth_card *card, enum qeth_prot_versions prot)
+{
+ int rc;
+ struct qeth_cmd_buffer *iob;
+
+ QETH_DBF_TEXT_(SETUP, 2, "qipassi%i", prot);
+ iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot);
+ rc = qeth_send_ipa_cmd(card, iob, qeth_query_ipassists_cb, NULL);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(qeth_query_ipassists);
+
+static int qeth_query_setdiagass_cb(struct qeth_card *card,
+ struct qeth_reply *reply, unsigned long data)
+{
+ struct qeth_ipa_cmd *cmd;
+ __u16 rc;
+
+ cmd = (struct qeth_ipa_cmd *)data;
+ rc = cmd->hdr.return_code;
+ if (rc)
+ QETH_CARD_TEXT_(card, 2, "diagq:%x", rc);
+ else
+ card->info.diagass_support = cmd->data.diagass.ext;
+ return 0;
+}
+
+static int qeth_query_setdiagass(struct qeth_card *card)
+{
+ struct qeth_cmd_buffer *iob;
+ struct qeth_ipa_cmd *cmd;
+
+ QETH_DBF_TEXT(SETUP, 2, "qdiagass");
+ iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
+ cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
+ cmd->data.diagass.subcmd_len = 16;
+ cmd->data.diagass.subcmd = QETH_DIAGS_CMD_QUERY;
+ return qeth_send_ipa_cmd(card, iob, qeth_query_setdiagass_cb, NULL);
+}
+
+static void qeth_get_trap_id(struct qeth_card *card, struct qeth_trap_id *tid)
+{
+ unsigned long info = get_zeroed_page(GFP_KERNEL);
+ struct sysinfo_2_2_2 *info222 = (struct sysinfo_2_2_2 *)info;
+ struct sysinfo_3_2_2 *info322 = (struct sysinfo_3_2_2 *)info;
+ struct ccw_dev_id ccwid;
+ int level, rc;
+
+ tid->chpid = card->info.chpid;
+ ccw_device_get_id(CARD_RDEV(card), &ccwid);
+ tid->ssid = ccwid.ssid;
+ tid->devno = ccwid.devno;
+ if (!info)
+ return;
+
+ rc = stsi(NULL, 0, 0, 0);
+ if (rc == -ENOSYS)
+ level = rc;
+ else
+ level = (((unsigned int) rc) >> 28);
+
+ if ((level >= 2) && (stsi(info222, 2, 2, 2) != -ENOSYS))
+ tid->lparnr = info222->lpar_number;
+
+ if ((level >= 3) && (stsi(info322, 3, 2, 2) != -ENOSYS)) {
+ EBCASC(info322->vm[0].name, sizeof(info322->vm[0].name));
+ memcpy(tid->vmname, info322->vm[0].name, sizeof(tid->vmname));
+ }
+ free_page(info);
+ return;
+}
+
+static int qeth_hw_trap_cb(struct qeth_card *card,
+ struct qeth_reply *reply, unsigned long data)
+{
+ struct qeth_ipa_cmd *cmd;
+ __u16 rc;
+
+ cmd = (struct qeth_ipa_cmd *)data;
+ rc = cmd->hdr.return_code;
+ if (rc)
+ QETH_CARD_TEXT_(card, 2, "trapc:%x", rc);
+ return 0;
+}
+
+int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action)
+{
+ struct qeth_cmd_buffer *iob;
+ struct qeth_ipa_cmd *cmd;
+
+ QETH_DBF_TEXT(SETUP, 2, "diagtrap");
+ iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
+ cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
+ cmd->data.diagass.subcmd_len = 80;
+ cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRAP;
+ cmd->data.diagass.type = 1;
+ cmd->data.diagass.action = action;
+ switch (action) {
+ case QETH_DIAGS_TRAP_ARM:
+ cmd->data.diagass.options = 0x0003;
+ cmd->data.diagass.ext = 0x00010000 +
+ sizeof(struct qeth_trap_id);
+ qeth_get_trap_id(card,
+ (struct qeth_trap_id *)cmd->data.diagass.cdata);
+ break;
+ case QETH_DIAGS_TRAP_DISARM:
+ cmd->data.diagass.options = 0x0001;
+ break;
+ case QETH_DIAGS_TRAP_CAPTURE:
+ break;
+ }
+ return qeth_send_ipa_cmd(card, iob, qeth_hw_trap_cb, NULL);
+}
+EXPORT_SYMBOL_GPL(qeth_hw_trap);
+
int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf,
unsigned int qdio_error, const char *dbftext)
{
@@ -3903,6 +4041,7 @@ MODULE_DEVICE_TABLE(ccw, qeth_ids);
static struct ccw_driver qeth_ccw_driver = {
.driver = {
+ .owner = THIS_MODULE,
.name = "qeth",
},
.ids = qeth_ids,
@@ -3984,6 +4123,15 @@ retriable:
QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
goto out;
}
+
+ card->options.ipa4.supported_funcs = 0;
+ card->options.adp.supported_funcs = 0;
+ card->info.diagass_support = 0;
+ qeth_query_ipassists(card, QETH_PROT_IPV4);
+ if (qeth_is_supported(card, IPA_SETADAPTERPARMS))
+ qeth_query_setadapterparms(card);
+ if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST))
+ qeth_query_setdiagass(card);
return 0;
out:
dev_warn(&card->gdev->dev, "The qeth device driver failed to recover "
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index 07d588867b5..e5a9d1c0383 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -80,14 +80,6 @@ enum qeth_tr_broadcast_modes {
QETH_TR_BROADCAST_LOCAL = 1,
};
-/* these values match CHECKSUM_* in include/linux/skbuff.h */
-enum qeth_checksum_types {
- SW_CHECKSUMMING = 0, /* TODO: set to bit flag used in IPA Command */
- HW_CHECKSUMMING = 1,
- NO_CHECKSUMMING = 2,
-};
-#define QETH_CHECKSUM_DEFAULT SW_CHECKSUMMING
-
/*
* Routing stuff
*/
@@ -456,6 +448,12 @@ enum qeth_diags_trace_cmds {
QETH_DIAGS_CMD_TRACE_QUERY = 0x0010,
};
+enum qeth_diags_trap_action {
+ QETH_DIAGS_TRAP_ARM = 0x01,
+ QETH_DIAGS_TRAP_DISARM = 0x02,
+ QETH_DIAGS_TRAP_CAPTURE = 0x04,
+};
+
struct qeth_ipacmd_diagass {
__u32 host_tod2;
__u32:32;
@@ -465,7 +463,8 @@ struct qeth_ipacmd_diagass {
__u8 type;
__u8 action;
__u16 options;
- __u32:32;
+ __u32 ext;
+ __u8 cdata[64];
} __attribute__ ((packed));
/* Header for each IPA command */
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index b5e967cf7e2..0a8e86c1b0e 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -530,6 +530,66 @@ out:
static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
qeth_dev_isolation_store);
+static ssize_t qeth_hw_trap_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct qeth_card *card = dev_get_drvdata(dev);
+
+ if (!card)
+ return -EINVAL;
+ if (card->info.hwtrap)
+ return snprintf(buf, 5, "arm\n");
+ else
+ return snprintf(buf, 8, "disarm\n");
+}
+
+static ssize_t qeth_hw_trap_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct qeth_card *card = dev_get_drvdata(dev);
+ int rc = 0;
+ char *tmp, *curtoken;
+ int state = 0;
+ curtoken = (char *)buf;
+
+ if (!card)
+ return -EINVAL;
+
+ mutex_lock(&card->conf_mutex);
+ if (card->state == CARD_STATE_SOFTSETUP || card->state == CARD_STATE_UP)
+ state = 1;
+ tmp = strsep(&curtoken, "\n");
+
+ if (!strcmp(tmp, "arm") && !card->info.hwtrap) {
+ if (state) {
+ if (qeth_is_diagass_supported(card,
+ QETH_DIAGS_CMD_TRAP)) {
+ rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM);
+ if (!rc)
+ card->info.hwtrap = 1;
+ } else
+ rc = -EINVAL;
+ } else
+ card->info.hwtrap = 1;
+ } else if (!strcmp(tmp, "disarm") && card->info.hwtrap) {
+ if (state) {
+ rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
+ if (!rc)
+ card->info.hwtrap = 0;
+ } else
+ card->info.hwtrap = 0;
+ } else if (!strcmp(tmp, "trap") && state && card->info.hwtrap)
+ rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_CAPTURE);
+ else
+ rc = -EINVAL;
+
+ mutex_unlock(&card->conf_mutex);
+ return rc ? rc : count;
+}
+
+static DEVICE_ATTR(hw_trap, 0644, qeth_hw_trap_show,
+ qeth_hw_trap_store);
+
static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value)
{
@@ -653,6 +713,7 @@ static struct attribute *qeth_device_attrs[] = {
&dev_attr_performance_stats.attr,
&dev_attr_layer2.attr,
&dev_attr_isolation.attr,
+ &dev_attr_hw_trap.attr,
NULL,
};
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 6fbaacb2194..b70b47fbd6c 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -420,10 +420,7 @@ static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
case QETH_HEADER_TYPE_LAYER2:
skb->pkt_type = PACKET_HOST;
skb->protocol = eth_type_trans(skb, skb->dev);
- if (card->options.checksum_type == NO_CHECKSUMMING)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
- skb->ip_summed = CHECKSUM_NONE;
+ skb->ip_summed = CHECKSUM_NONE;
if (skb->protocol == htons(ETH_P_802_2))
*((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
len = skb->len;
@@ -879,6 +876,7 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
INIT_LIST_HEAD(&card->vid_list);
INIT_LIST_HEAD(&card->mc_list);
card->options.layer2 = 1;
+ card->info.hwtrap = 0;
card->discipline.start_poll = qeth_qdio_start_poll;
card->discipline.input_handler = (qdio_handler_t *)
qeth_qdio_input_handler;
@@ -997,6 +995,13 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
if (card->info.type != QETH_CARD_TYPE_OSN)
qeth_l2_send_setmac(card, &card->dev->dev_addr[0]);
+ if (qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP)) {
+ if (card->info.hwtrap &&
+ qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM))
+ card->info.hwtrap = 0;
+ } else
+ card->info.hwtrap = 0;
+
card->state = CARD_STATE_HARDSETUP;
memset(&card->rx, 0, sizeof(struct qeth_rx));
qeth_print_status_message(card);
@@ -1095,6 +1100,10 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev,
if (card->dev && netif_carrier_ok(card->dev))
netif_carrier_off(card->dev);
recover_flag = card->state;
+ if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) {
+ qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
+ card->info.hwtrap = 1;
+ }
qeth_l2_stop_card(card, recovery_mode);
rc = ccw_device_set_offline(CARD_DDEV(card));
rc2 = ccw_device_set_offline(CARD_WDEV(card));
@@ -1160,6 +1169,8 @@ static void __exit qeth_l2_exit(void)
static void qeth_l2_shutdown(struct ccwgroup_device *gdev)
{
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
+ if ((gdev->state == CCWGROUP_ONLINE) && card->info.hwtrap)
+ qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
qeth_qdio_clear_card(card, 0);
qeth_clear_qdio_buffers(card);
}
@@ -1175,6 +1186,8 @@ static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev)
if (gdev->state == CCWGROUP_OFFLINE)
return 0;
if (card->state == CARD_STATE_UP) {
+ if (card->info.hwtrap)
+ qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
__qeth_l2_set_offline(card->gdev, 1);
} else
__qeth_l2_set_offline(card->gdev, 0);
diff --git a/drivers/s390/net/qeth_l3.h b/drivers/s390/net/qeth_l3.h
index e705b27ec7d..14a43aeb0c2 100644
--- a/drivers/s390/net/qeth_l3.h
+++ b/drivers/s390/net/qeth_l3.h
@@ -62,8 +62,6 @@ void qeth_l3_del_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *);
int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions,
const u8 *);
-int qeth_l3_set_large_send(struct qeth_card *, enum qeth_large_send_types);
-int qeth_l3_set_rx_csum(struct qeth_card *, enum qeth_checksum_types);
int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *, struct qeth_ipaddr *);
#endif /* __QETH_L3_H__ */
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 142e5f6ef4f..fd69da3fa6b 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -43,33 +43,6 @@ static int qeth_l3_deregister_addr_entry(struct qeth_card *,
static int __qeth_l3_set_online(struct ccwgroup_device *, int);
static int __qeth_l3_set_offline(struct ccwgroup_device *, int);
-int qeth_l3_set_large_send(struct qeth_card *card,
- enum qeth_large_send_types type)
-{
- int rc = 0;
-
- card->options.large_send = type;
- if (card->dev == NULL)
- return 0;
-
- if (card->options.large_send == QETH_LARGE_SEND_TSO) {
- if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
- card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
- NETIF_F_IP_CSUM;
- } else {
- card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
- NETIF_F_IP_CSUM);
- card->options.large_send = QETH_LARGE_SEND_NO;
- rc = -EOPNOTSUPP;
- }
- } else {
- card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
- NETIF_F_IP_CSUM);
- card->options.large_send = QETH_LARGE_SEND_NO;
- }
- return rc;
-}
-
static int qeth_l3_isxdigit(char *buf)
{
while (*buf) {
@@ -1304,39 +1277,6 @@ static int qeth_l3_start_ipa_multicast(struct qeth_card *card)
return rc;
}
-static int qeth_l3_query_ipassists_cb(struct qeth_card *card,
- struct qeth_reply *reply, unsigned long data)
-{
- struct qeth_ipa_cmd *cmd;
-
- QETH_DBF_TEXT(SETUP, 2, "qipasscb");
-
- cmd = (struct qeth_ipa_cmd *) data;
- if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
- card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
- card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
- } else {
- card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
- card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
- }
- QETH_DBF_TEXT(SETUP, 2, "suppenbl");
- QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_supported);
- QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_enabled);
- return 0;
-}
-
-static int qeth_l3_query_ipassists(struct qeth_card *card,
- enum qeth_prot_versions prot)
-{
- int rc;
- struct qeth_cmd_buffer *iob;
-
- QETH_DBF_TEXT_(SETUP, 2, "qipassi%i", prot);
- iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot);
- rc = qeth_send_ipa_cmd(card, iob, qeth_l3_query_ipassists_cb, NULL);
- return rc;
-}
-
#ifdef CONFIG_QETH_IPV6
static int qeth_l3_softsetup_ipv6(struct qeth_card *card)
{
@@ -1347,7 +1287,7 @@ static int qeth_l3_softsetup_ipv6(struct qeth_card *card)
if (card->info.type == QETH_CARD_TYPE_IQD)
goto out;
- rc = qeth_l3_query_ipassists(card, QETH_PROT_IPV6);
+ rc = qeth_query_ipassists(card, QETH_PROT_IPV6);
if (rc) {
dev_err(&card->gdev->dev,
"Activating IPv6 support for %s failed\n",
@@ -1472,68 +1412,38 @@ static int qeth_l3_send_checksum_command(struct qeth_card *card)
return 0;
}
-int qeth_l3_set_rx_csum(struct qeth_card *card,
- enum qeth_checksum_types csum_type)
+int qeth_l3_set_rx_csum(struct qeth_card *card, int on)
{
int rc = 0;
- if (card->options.checksum_type == HW_CHECKSUMMING) {
- if ((csum_type != HW_CHECKSUMMING) &&
- (card->state != CARD_STATE_DOWN)) {
- rc = qeth_l3_send_simple_setassparms(card,
- IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0);
- if (rc)
- return -EIO;
- }
+ if (on) {
+ rc = qeth_l3_send_checksum_command(card);
+ if (rc)
+ return -EIO;
+ dev_info(&card->gdev->dev,
+ "HW Checksumming (inbound) enabled\n");
} else {
- if (csum_type == HW_CHECKSUMMING) {
- if (card->state != CARD_STATE_DOWN) {
- if (!qeth_is_supported(card,
- IPA_INBOUND_CHECKSUM))
- return -EPERM;
- rc = qeth_l3_send_checksum_command(card);
- if (rc)
- return -EIO;
- }
- }
+ rc = qeth_l3_send_simple_setassparms(card,
+ IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0);
+ if (rc)
+ return -EIO;
}
- card->options.checksum_type = csum_type;
- return rc;
+
+ return 0;
}
static int qeth_l3_start_ipa_checksum(struct qeth_card *card)
{
- int rc = 0;
-
QETH_CARD_TEXT(card, 3, "strtcsum");
- if (card->options.checksum_type == NO_CHECKSUMMING) {
- dev_info(&card->gdev->dev,
- "Using no checksumming on %s.\n",
- QETH_CARD_IFNAME(card));
- return 0;
- }
- if (card->options.checksum_type == SW_CHECKSUMMING) {
- dev_info(&card->gdev->dev,
- "Using SW checksumming on %s.\n",
- QETH_CARD_IFNAME(card));
- return 0;
- }
- if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM)) {
- dev_info(&card->gdev->dev,
- "Inbound HW Checksumming not "
- "supported on %s,\ncontinuing "
- "using Inbound SW Checksumming\n",
- QETH_CARD_IFNAME(card));
- card->options.checksum_type = SW_CHECKSUMMING;
- return 0;
+ if (card->dev->features & NETIF_F_RXCSUM) {
+ rtnl_lock();
+ /* force set_features call */
+ card->dev->features &= ~NETIF_F_RXCSUM;
+ netdev_update_features(card->dev);
+ rtnl_unlock();
}
- rc = qeth_l3_send_checksum_command(card);
- if (!rc)
- dev_info(&card->gdev->dev,
- "HW Checksumming (inbound) enabled\n");
-
- return rc;
+ return 0;
}
static int qeth_l3_start_ipa_tx_checksum(struct qeth_card *card)
@@ -1580,10 +1490,8 @@ static int qeth_l3_start_ipa_tso(struct qeth_card *card)
dev_info(&card->gdev->dev,
"Outbound TSO enabled\n");
}
- if (rc && (card->options.large_send == QETH_LARGE_SEND_TSO)) {
- card->options.large_send = QETH_LARGE_SEND_NO;
- card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG);
- }
+ if (rc)
+ card->dev->features &= ~NETIF_F_TSO;
return rc;
}
@@ -2064,14 +1972,7 @@ static inline int qeth_l3_rebuild_skb(struct qeth_card *card,
is_vlan = 1;
}
- switch (card->options.checksum_type) {
- case SW_CHECKSUMMING:
- skb->ip_summed = CHECKSUM_NONE;
- break;
- case NO_CHECKSUMMING:
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- break;
- case HW_CHECKSUMMING:
+ if (card->dev->features & NETIF_F_RXCSUM) {
if ((hdr->hdr.l3.ext_flags &
(QETH_HDR_EXT_CSUM_HDR_REQ |
QETH_HDR_EXT_CSUM_TRANSP_REQ)) ==
@@ -2080,7 +1981,8 @@ static inline int qeth_l3_rebuild_skb(struct qeth_card *card,
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
skb->ip_summed = CHECKSUM_NONE;
- }
+ } else
+ skb->ip_summed = CHECKSUM_NONE;
return is_vlan;
}
@@ -3024,7 +2926,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct qeth_qdio_out_q *queue = card->qdio.out_qs
[qeth_get_priority_queue(card, skb, ipv, cast_type)];
int tx_bytes = skb->len;
- enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
+ bool large_send;
int data_offset = -1;
int nr_frags;
@@ -3046,8 +2948,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
card->perf_stats.outbound_start_time = qeth_get_micros();
}
- if (skb_is_gso(skb))
- large_send = card->options.large_send;
+ large_send = skb_is_gso(skb);
if ((card->info.type == QETH_CARD_TYPE_IQD) && (!large_send) &&
(skb_shinfo(skb)->nr_frags == 0)) {
@@ -3096,7 +2997,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* fix hardware limitation: as long as we do not have sbal
* chaining we can not send long frag lists
*/
- if (large_send == QETH_LARGE_SEND_TSO) {
+ if (large_send) {
if (qeth_l3_tso_elements(new_skb) + 1 > 16) {
if (skb_linearize(new_skb))
goto tx_drop;
@@ -3105,8 +3006,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
- if ((large_send == QETH_LARGE_SEND_TSO) &&
- (cast_type == RTN_UNSPEC)) {
+ if (large_send && (cast_type == RTN_UNSPEC)) {
hdr = (struct qeth_hdr *)skb_push(new_skb,
sizeof(struct qeth_hdr_tso));
memset(hdr, 0, sizeof(struct qeth_hdr_tso));
@@ -3141,7 +3041,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (card->info.type != QETH_CARD_TYPE_IQD) {
int len;
- if (large_send == QETH_LARGE_SEND_TSO)
+ if (large_send)
len = ((unsigned long)tcp_hdr(new_skb) +
tcp_hdr(new_skb)->doff * 4) -
(unsigned long)new_skb->data;
@@ -3162,7 +3062,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (new_skb != skb)
dev_kfree_skb_any(skb);
if (card->options.performance_stats) {
- if (large_send != QETH_LARGE_SEND_NO) {
+ if (large_send) {
card->perf_stats.large_send_bytes += tx_bytes;
card->perf_stats.large_send_cnt++;
}
@@ -3248,65 +3148,42 @@ static int qeth_l3_stop(struct net_device *dev)
return 0;
}
-static u32 qeth_l3_ethtool_get_rx_csum(struct net_device *dev)
+static u32 qeth_l3_fix_features(struct net_device *dev, u32 features)
{
struct qeth_card *card = dev->ml_priv;
- return (card->options.checksum_type == HW_CHECKSUMMING);
-}
-
-static int qeth_l3_ethtool_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct qeth_card *card = dev->ml_priv;
- enum qeth_checksum_types csum_type;
-
- if (data)
- csum_type = HW_CHECKSUMMING;
- else
- csum_type = SW_CHECKSUMMING;
+ if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
+ features &= ~NETIF_F_IP_CSUM;
+ if (!qeth_is_supported(card, IPA_OUTBOUND_TSO))
+ features &= ~NETIF_F_TSO;
+ if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
+ features &= ~NETIF_F_RXCSUM;
- return qeth_l3_set_rx_csum(card, csum_type);
+ return features;
}
-static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data)
+static int qeth_l3_set_features(struct net_device *dev, u32 features)
{
struct qeth_card *card = dev->ml_priv;
- int rc = 0;
+ u32 changed = dev->features ^ features;
+ int err;
- if (data) {
- rc = qeth_l3_set_large_send(card, QETH_LARGE_SEND_TSO);
- } else {
- dev->features &= ~NETIF_F_TSO;
- card->options.large_send = QETH_LARGE_SEND_NO;
- }
- return rc;
-}
+ if (!(changed & NETIF_F_RXCSUM))
+ return 0;
-static int qeth_l3_ethtool_set_tx_csum(struct net_device *dev, u32 data)
-{
- struct qeth_card *card = dev->ml_priv;
+ if (card->state == CARD_STATE_DOWN ||
+ card->state == CARD_STATE_RECOVER)
+ return 0;
- if (data) {
- if (qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
- dev->features |= NETIF_F_IP_CSUM;
- else
- return -EPERM;
- } else
- dev->features &= ~NETIF_F_IP_CSUM;
+ err = qeth_l3_set_rx_csum(card, features & NETIF_F_RXCSUM);
+ if (err)
+ dev->features = features ^ NETIF_F_RXCSUM;
- return 0;
+ return err;
}
static const struct ethtool_ops qeth_l3_ethtool_ops = {
.get_link = ethtool_op_get_link,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = qeth_l3_ethtool_set_tx_csum,
- .get_rx_csum = qeth_l3_ethtool_get_rx_csum,
- .set_rx_csum = qeth_l3_ethtool_set_rx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = qeth_l3_ethtool_set_tso,
.get_strings = qeth_core_get_strings,
.get_ethtool_stats = qeth_core_get_ethtool_stats,
.get_sset_count = qeth_core_get_sset_count,
@@ -3347,6 +3224,8 @@ static const struct net_device_ops qeth_l3_netdev_ops = {
.ndo_set_multicast_list = qeth_l3_set_multicast_list,
.ndo_do_ioctl = qeth_l3_do_ioctl,
.ndo_change_mtu = qeth_change_mtu,
+ .ndo_fix_features = qeth_l3_fix_features,
+ .ndo_set_features = qeth_l3_set_features,
.ndo_vlan_rx_register = qeth_l3_vlan_rx_register,
.ndo_vlan_rx_add_vid = qeth_l3_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = qeth_l3_vlan_rx_kill_vid,
@@ -3362,6 +3241,8 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = {
.ndo_set_multicast_list = qeth_l3_set_multicast_list,
.ndo_do_ioctl = qeth_l3_do_ioctl,
.ndo_change_mtu = qeth_change_mtu,
+ .ndo_fix_features = qeth_l3_fix_features,
+ .ndo_set_features = qeth_l3_set_features,
.ndo_vlan_rx_register = qeth_l3_vlan_rx_register,
.ndo_vlan_rx_add_vid = qeth_l3_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = qeth_l3_vlan_rx_kill_vid,
@@ -3392,8 +3273,12 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
card->dev->dev_id = card->info.unique_id &
0xffff;
- if (!card->info.guestlan)
- card->dev->features |= NETIF_F_GRO;
+ if (!card->info.guestlan) {
+ card->dev->hw_features = NETIF_F_SG |
+ NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
+ NETIF_F_TSO;
+ card->dev->features = NETIF_F_RXCSUM;
+ }
}
} else if (card->info.type == QETH_CARD_TYPE_IQD) {
card->dev = alloc_netdev(0, "hsi%d", ether_setup);
@@ -3426,15 +3311,13 @@ static int qeth_l3_probe_device(struct ccwgroup_device *gdev)
qeth_l3_create_device_attributes(&gdev->dev);
card->options.layer2 = 0;
+ card->info.hwtrap = 0;
card->discipline.start_poll = qeth_qdio_start_poll;
card->discipline.input_handler = (qdio_handler_t *)
qeth_qdio_input_handler;
card->discipline.output_handler = (qdio_handler_t *)
qeth_qdio_output_handler;
card->discipline.recover = qeth_l3_recover;
- if ((card->info.type == QETH_CARD_TYPE_OSD) ||
- (card->info.type == QETH_CARD_TYPE_OSX))
- card->options.checksum_type = HW_CHECKSUMMING;
return 0;
}
@@ -3480,13 +3363,18 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
goto out_remove;
}
- qeth_l3_query_ipassists(card, QETH_PROT_IPV4);
-
if (!card->dev && qeth_l3_setup_netdev(card)) {
rc = -ENODEV;
goto out_remove;
}
+ if (qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP)) {
+ if (card->info.hwtrap &&
+ qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM))
+ card->info.hwtrap = 0;
+ } else
+ card->info.hwtrap = 0;
+
card->state = CARD_STATE_HARDSETUP;
memset(&card->rx, 0, sizeof(struct qeth_rx));
qeth_print_status_message(card);
@@ -3516,7 +3404,6 @@ contin:
rc = qeth_l3_start_ipassists(card);
if (rc)
QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
- qeth_l3_set_large_send(card, card->options.large_send);
rc = qeth_l3_setrouting_v4(card);
if (rc)
QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc);
@@ -3589,6 +3476,10 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev,
if (card->dev && netif_carrier_ok(card->dev))
netif_carrier_off(card->dev);
recover_flag = card->state;
+ if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) {
+ qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
+ card->info.hwtrap = 1;
+ }
qeth_l3_stop_card(card, recovery_mode);
rc = ccw_device_set_offline(CARD_DDEV(card));
rc2 = ccw_device_set_offline(CARD_WDEV(card));
@@ -3644,6 +3535,8 @@ static int qeth_l3_recover(void *ptr)
static void qeth_l3_shutdown(struct ccwgroup_device *gdev)
{
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
+ if ((gdev->state == CCWGROUP_ONLINE) && card->info.hwtrap)
+ qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
qeth_qdio_clear_card(card, 0);
qeth_clear_qdio_buffers(card);
}
@@ -3659,6 +3552,8 @@ static int qeth_l3_pm_suspend(struct ccwgroup_device *gdev)
if (gdev->state == CCWGROUP_OFFLINE)
return 0;
if (card->state == CARD_STATE_UP) {
+ if (card->info.hwtrap)
+ qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
__qeth_l3_set_offline(card->gdev, 1);
} else
__qeth_l3_set_offline(card->gdev, 0);
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c
index 67cfa68dcf1..cd99210296e 100644
--- a/drivers/s390/net/qeth_l3_sys.c
+++ b/drivers/s390/net/qeth_l3_sys.c
@@ -15,16 +15,6 @@
#define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
-static const char *qeth_l3_get_checksum_str(struct qeth_card *card)
-{
- if (card->options.checksum_type == SW_CHECKSUMMING)
- return "sw";
- else if (card->options.checksum_type == HW_CHECKSUMMING)
- return "hw";
- else
- return "no";
-}
-
static ssize_t qeth_l3_dev_route_show(struct qeth_card *card,
struct qeth_routing_info *route, char *buf)
{
@@ -295,51 +285,6 @@ out:
static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show,
qeth_l3_dev_canonical_macaddr_store);
-static ssize_t qeth_l3_dev_checksum_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct qeth_card *card = dev_get_drvdata(dev);
-
- if (!card)
- return -EINVAL;
-
- return sprintf(buf, "%s checksumming\n",
- qeth_l3_get_checksum_str(card));
-}
-
-static ssize_t qeth_l3_dev_checksum_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct qeth_card *card = dev_get_drvdata(dev);
- enum qeth_checksum_types csum_type;
- char *tmp;
- int rc = 0;
-
- if (!card)
- return -EINVAL;
-
- mutex_lock(&card->conf_mutex);
- tmp = strsep((char **) &buf, "\n");
- if (!strcmp(tmp, "sw_checksumming"))
- csum_type = SW_CHECKSUMMING;
- else if (!strcmp(tmp, "hw_checksumming"))
- csum_type = HW_CHECKSUMMING;
- else if (!strcmp(tmp, "no_checksumming"))
- csum_type = NO_CHECKSUMMING;
- else {
- rc = -EINVAL;
- goto out;
- }
-
- rc = qeth_l3_set_rx_csum(card, csum_type);
-out:
- mutex_unlock(&card->conf_mutex);
- return rc ? rc : count;
-}
-
-static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
- qeth_l3_dev_checksum_store);
-
static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -402,61 +347,13 @@ out:
static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
qeth_l3_dev_sniffer_store);
-static ssize_t qeth_l3_dev_large_send_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct qeth_card *card = dev_get_drvdata(dev);
-
- if (!card)
- return -EINVAL;
-
- switch (card->options.large_send) {
- case QETH_LARGE_SEND_NO:
- return sprintf(buf, "%s\n", "no");
- case QETH_LARGE_SEND_TSO:
- return sprintf(buf, "%s\n", "TSO");
- default:
- return sprintf(buf, "%s\n", "N/A");
- }
-}
-
-static ssize_t qeth_l3_dev_large_send_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct qeth_card *card = dev_get_drvdata(dev);
- enum qeth_large_send_types type;
- int rc = 0;
- char *tmp;
-
- if (!card)
- return -EINVAL;
- tmp = strsep((char **) &buf, "\n");
- if (!strcmp(tmp, "no"))
- type = QETH_LARGE_SEND_NO;
- else if (!strcmp(tmp, "TSO"))
- type = QETH_LARGE_SEND_TSO;
- else
- return -EINVAL;
-
- mutex_lock(&card->conf_mutex);
- if (card->options.large_send != type)
- rc = qeth_l3_set_large_send(card, type);
- mutex_unlock(&card->conf_mutex);
- return rc ? rc : count;
-}
-
-static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show,
- qeth_l3_dev_large_send_store);
-
static struct attribute *qeth_l3_device_attrs[] = {
&dev_attr_route4.attr,
&dev_attr_route6.attr,
&dev_attr_fake_broadcast.attr,
&dev_attr_broadcast_mode.attr,
&dev_attr_canonical_macaddr.attr,
- &dev_attr_checksumming.attr,
&dev_attr_sniffer.attr,
- &dev_attr_large_send.attr,
NULL,
};
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index 66236567668..ab255fbc7f3 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
@@ -664,7 +664,7 @@ static void bnx2fc_link_speed_update(struct fc_lport *lport)
struct fcoe_port *port = lport_priv(lport);
struct bnx2fc_hba *hba = port->priv;
struct net_device *netdev = hba->netdev;
- struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+ struct ethtool_cmd ecmd;
if (!dev_ethtool_get_settings(netdev, &ecmd)) {
lport->link_supported_speeds &=
@@ -675,12 +675,15 @@ static void bnx2fc_link_speed_update(struct fc_lport *lport)
if (ecmd.supported & SUPPORTED_10000baseT_Full)
lport->link_supported_speeds |= FC_PORTSPEED_10GBIT;
- if (ecmd.speed == SPEED_1000)
+ switch (ethtool_cmd_speed(&ecmd)) {
+ case SPEED_1000:
lport->link_speed = FC_PORTSPEED_1GBIT;
- if (ecmd.speed == SPEED_10000)
+ break;
+ case SPEED_10000:
lport->link_speed = FC_PORTSPEED_10GBIT;
+ break;
+ }
}
- return;
}
static int bnx2fc_link_ok(struct fc_lport *lport)
{
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index de764ea7419..a2a9c7c6c64 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -450,12 +450,13 @@ static struct cxgbi_sock *cxgbi_sock_create(struct cxgbi_device *cdev)
return csk;
}
-static struct rtable *find_route_ipv4(__be32 saddr, __be32 daddr,
+static struct rtable *find_route_ipv4(struct flowi4 *fl4,
+ __be32 saddr, __be32 daddr,
__be16 sport, __be16 dport, u8 tos)
{
struct rtable *rt;
- rt = ip_route_output_ports(&init_net, NULL, daddr, saddr,
+ rt = ip_route_output_ports(&init_net, fl4, NULL, daddr, saddr,
dport, sport, IPPROTO_TCP, tos, 0);
if (IS_ERR(rt))
return NULL;
@@ -470,6 +471,7 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
struct net_device *ndev;
struct cxgbi_device *cdev;
struct rtable *rt = NULL;
+ struct flowi4 fl4;
struct cxgbi_sock *csk = NULL;
unsigned int mtu = 0;
int port = 0xFFFF;
@@ -482,7 +484,7 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
goto err_out;
}
- rt = find_route_ipv4(0, daddr->sin_addr.s_addr, 0, daddr->sin_port, 0);
+ rt = find_route_ipv4(&fl4, 0, daddr->sin_addr.s_addr, 0, daddr->sin_port, 0);
if (!rt) {
pr_info("no route to ipv4 0x%x, port %u.\n",
daddr->sin_addr.s_addr, daddr->sin_port);
@@ -531,7 +533,7 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
csk->daddr.sin_addr.s_addr = daddr->sin_addr.s_addr;
csk->daddr.sin_port = daddr->sin_port;
csk->daddr.sin_family = daddr->sin_family;
- csk->saddr.sin_addr.s_addr = rt->rt_src;
+ csk->saddr.sin_addr.s_addr = fl4.saddr;
return csk;
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 5d3700dc6f8..cc23bd9480b 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -1952,7 +1952,7 @@ out_nodev:
int fcoe_link_speed_update(struct fc_lport *lport)
{
struct net_device *netdev = fcoe_netdev(lport);
- struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+ struct ethtool_cmd ecmd;
if (!dev_ethtool_get_settings(netdev, &ecmd)) {
lport->link_supported_speeds &=
@@ -1963,11 +1963,14 @@ int fcoe_link_speed_update(struct fc_lport *lport)
if (ecmd.supported & SUPPORTED_10000baseT_Full)
lport->link_supported_speeds |=
FC_PORTSPEED_10GBIT;
- if (ecmd.speed == SPEED_1000)
+ switch (ethtool_cmd_speed(&ecmd)) {
+ case SPEED_1000:
lport->link_speed = FC_PORTSPEED_1GBIT;
- if (ecmd.speed == SPEED_10000)
+ break;
+ case SPEED_10000:
lport->link_speed = FC_PORTSPEED_10GBIT;
-
+ break;
+ }
return 0;
}
return -1;
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index 7c031fdc820..06d15b6f221 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -46,40 +46,66 @@ void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc,
if (!ccdev)
return;
bus = ccdev->bus;
+
+ /* We support SLOW only on 6..9 */
+ if (ccdev->id.revision >= 10 && mode == SSB_CLKMODE_SLOW)
+ mode = SSB_CLKMODE_DYNAMIC;
+
+ if (cc->capabilities & SSB_CHIPCO_CAP_PMU)
+ return; /* PMU controls clockmode, separated function needed */
+ SSB_WARN_ON(ccdev->id.revision >= 20);
+
/* chipcommon cores prior to rev6 don't support dynamic clock control */
if (ccdev->id.revision < 6)
return;
- /* chipcommon cores rev10 are a whole new ball game */
+
+ /* ChipCommon cores rev10+ need testing */
if (ccdev->id.revision >= 10)
return;
+
if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
return;
switch (mode) {
- case SSB_CLKMODE_SLOW:
+ case SSB_CLKMODE_SLOW: /* For revs 6..9 only */
tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW;
chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
break;
case SSB_CLKMODE_FAST:
- ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
- tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
- tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
- tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
- chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
+ if (ccdev->id.revision < 10) {
+ ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
+ tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
+ tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
+ chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
+ } else {
+ chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
+ (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) |
+ SSB_CHIPCO_SYSCLKCTL_FORCEHT));
+ /* udelay(150); TODO: not available in early init */
+ }
break;
case SSB_CLKMODE_DYNAMIC:
- tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
- tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
- tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
- tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
- if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
- tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
- chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
-
- /* for dynamic control, we have to release our xtal_pu "force on" */
- if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
- ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
+ if (ccdev->id.revision < 10) {
+ tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
+ if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) !=
+ SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
+ tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
+ chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
+
+ /* For dynamic control, we have to release our xtal_pu
+ * "force on" */
+ if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
+ ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
+ } else {
+ chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
+ (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) &
+ ~SSB_CHIPCO_SYSCLKCTL_FORCEHT));
+ }
break;
default:
SSB_WARN_ON(1);
@@ -260,6 +286,12 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc)
if (cc->dev->id.revision >= 11)
cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
+
+ if (cc->dev->id.revision >= 20) {
+ chipco_write32(cc, SSB_CHIPCO_GPIOPULLUP, 0);
+ chipco_write32(cc, SSB_CHIPCO_GPIOPULLDOWN, 0);
+ }
+
ssb_pmu_init(cc);
chipco_powercontrol_init(cc);
ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c
index 5732bb2c357..305ade7825f 100644
--- a/drivers/ssb/driver_chipcommon_pmu.c
+++ b/drivers/ssb/driver_chipcommon_pmu.c
@@ -423,6 +423,8 @@ static void ssb_pmu_resources_init(struct ssb_chipcommon *cc)
switch (bus->chip_id) {
case 0x4312:
+ min_msk = 0xCBB;
+ break;
case 0x4322:
/* We keep the default settings:
* min_msk = 0xCBB
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c
index 0e8d3522461..82feb348c8b 100644
--- a/drivers/ssb/driver_pcicore.c
+++ b/drivers/ssb/driver_pcicore.c
@@ -15,6 +15,11 @@
#include "ssb_private.h"
+static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address);
+static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data);
+static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address);
+static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
+ u8 address, u16 data);
static inline
u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset)
@@ -403,6 +408,107 @@ static int pcicore_is_in_hostmode(struct ssb_pcicore *pc)
}
#endif /* CONFIG_SSB_PCICORE_HOSTMODE */
+/**************************************************
+ * Workarounds.
+ **************************************************/
+
+static void ssb_pcicore_fix_sprom_core_index(struct ssb_pcicore *pc)
+{
+ u16 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(0));
+ if (((tmp & 0xF000) >> 12) != pc->dev->core_index) {
+ tmp &= ~0xF000;
+ tmp |= (pc->dev->core_index << 12);
+ pcicore_write16(pc, SSB_PCICORE_SPROM(0), tmp);
+ }
+}
+
+static u8 ssb_pcicore_polarity_workaround(struct ssb_pcicore *pc)
+{
+ return (ssb_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
+}
+
+static void ssb_pcicore_serdes_workaround(struct ssb_pcicore *pc)
+{
+ const u8 serdes_pll_device = 0x1D;
+ const u8 serdes_rx_device = 0x1F;
+ u16 tmp;
+
+ ssb_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
+ ssb_pcicore_polarity_workaround(pc));
+ tmp = ssb_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
+ if (tmp & 0x4000)
+ ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
+}
+
+static void ssb_pcicore_pci_setup_workarounds(struct ssb_pcicore *pc)
+{
+ struct ssb_device *pdev = pc->dev;
+ struct ssb_bus *bus = pdev->bus;
+ u32 tmp;
+
+ tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
+ tmp |= SSB_PCICORE_SBTOPCI_PREF;
+ tmp |= SSB_PCICORE_SBTOPCI_BURST;
+ pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
+
+ if (pdev->id.revision < 5) {
+ tmp = ssb_read32(pdev, SSB_IMCFGLO);
+ tmp &= ~SSB_IMCFGLO_SERTO;
+ tmp |= 2;
+ tmp &= ~SSB_IMCFGLO_REQTO;
+ tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
+ ssb_write32(pdev, SSB_IMCFGLO, tmp);
+ ssb_commit_settings(bus);
+ } else if (pdev->id.revision >= 11) {
+ tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
+ tmp |= SSB_PCICORE_SBTOPCI_MRM;
+ pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
+ }
+}
+
+static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc)
+{
+ u32 tmp;
+ u8 rev = pc->dev->id.revision;
+
+ if (rev == 0 || rev == 1) {
+ /* TLP Workaround register. */
+ tmp = ssb_pcie_read(pc, 0x4);
+ tmp |= 0x8;
+ ssb_pcie_write(pc, 0x4, tmp);
+ }
+ if (rev == 1) {
+ /* DLLP Link Control register. */
+ tmp = ssb_pcie_read(pc, 0x100);
+ tmp |= 0x40;
+ ssb_pcie_write(pc, 0x100, tmp);
+ }
+
+ if (rev == 0) {
+ const u8 serdes_rx_device = 0x1F;
+
+ ssb_pcie_mdio_write(pc, serdes_rx_device,
+ 2 /* Timer */, 0x8128);
+ ssb_pcie_mdio_write(pc, serdes_rx_device,
+ 6 /* CDR */, 0x0100);
+ ssb_pcie_mdio_write(pc, serdes_rx_device,
+ 7 /* CDR BW */, 0x1466);
+ } else if (rev == 3 || rev == 4 || rev == 5) {
+ /* TODO: DLLP Power Management Threshold */
+ ssb_pcicore_serdes_workaround(pc);
+ /* TODO: ASPM */
+ } else if (rev == 7) {
+ /* TODO: No PLL down */
+ }
+
+ if (rev >= 6) {
+ /* Miscellaneous Configuration Fixup */
+ tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(5));
+ if (!(tmp & 0x8000))
+ pcicore_write16(pc, SSB_PCICORE_SPROM(5),
+ tmp | 0x8000);
+ }
+}
/**************************************************
* Generic and Clientmode operation code.
@@ -417,14 +523,14 @@ static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
void ssb_pcicore_init(struct ssb_pcicore *pc)
{
struct ssb_device *dev = pc->dev;
- struct ssb_bus *bus;
if (!dev)
return;
- bus = dev->bus;
if (!ssb_device_is_enabled(dev))
ssb_device_enable(dev, 0);
+ ssb_pcicore_fix_sprom_core_index(pc);
+
#ifdef CONFIG_SSB_PCICORE_HOSTMODE
pc->hostmode = pcicore_is_in_hostmode(pc);
if (pc->hostmode)
@@ -432,6 +538,11 @@ void ssb_pcicore_init(struct ssb_pcicore *pc)
#endif /* CONFIG_SSB_PCICORE_HOSTMODE */
if (!pc->hostmode)
ssb_pcicore_init_clientmode(pc);
+
+ /* Additional always once-executed workarounds */
+ ssb_pcicore_serdes_workaround(pc);
+ /* TODO: ASPM */
+ /* TODO: Clock Request Update */
}
static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address)
@@ -446,58 +557,104 @@ static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data)
pcicore_write32(pc, 0x134, data);
}
-static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
- u8 address, u16 data)
+static void ssb_pcie_mdio_set_phy(struct ssb_pcicore *pc, u8 phy)
{
const u16 mdio_control = 0x128;
const u16 mdio_data = 0x12C;
u32 v;
int i;
+ v = (1 << 30); /* Start of Transaction */
+ v |= (1 << 28); /* Write Transaction */
+ v |= (1 << 17); /* Turnaround */
+ v |= (0x1F << 18);
+ v |= (phy << 4);
+ pcicore_write32(pc, mdio_data, v);
+
+ udelay(10);
+ for (i = 0; i < 200; i++) {
+ v = pcicore_read32(pc, mdio_control);
+ if (v & 0x100 /* Trans complete */)
+ break;
+ msleep(1);
+ }
+}
+
+static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address)
+{
+ const u16 mdio_control = 0x128;
+ const u16 mdio_data = 0x12C;
+ int max_retries = 10;
+ u16 ret = 0;
+ u32 v;
+ int i;
+
v = 0x80; /* Enable Preamble Sequence */
v |= 0x2; /* MDIO Clock Divisor */
pcicore_write32(pc, mdio_control, v);
+ if (pc->dev->id.revision >= 10) {
+ max_retries = 200;
+ ssb_pcie_mdio_set_phy(pc, device);
+ }
+
v = (1 << 30); /* Start of Transaction */
- v |= (1 << 28); /* Write Transaction */
+ v |= (1 << 29); /* Read Transaction */
v |= (1 << 17); /* Turnaround */
- v |= (u32)device << 22;
+ if (pc->dev->id.revision < 10)
+ v |= (u32)device << 22;
v |= (u32)address << 18;
- v |= data;
pcicore_write32(pc, mdio_data, v);
/* Wait for the device to complete the transaction */
udelay(10);
- for (i = 0; i < 10; i++) {
+ for (i = 0; i < max_retries; i++) {
v = pcicore_read32(pc, mdio_control);
- if (v & 0x100 /* Trans complete */)
+ if (v & 0x100 /* Trans complete */) {
+ udelay(10);
+ ret = pcicore_read32(pc, mdio_data);
break;
+ }
msleep(1);
}
pcicore_write32(pc, mdio_control, 0);
+ return ret;
}
-static void ssb_broadcast_value(struct ssb_device *dev,
- u32 address, u32 data)
+static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
+ u8 address, u16 data)
{
- /* This is used for both, PCI and ChipCommon core, so be careful. */
- BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
- BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
-
- ssb_write32(dev, SSB_PCICORE_BCAST_ADDR, address);
- ssb_read32(dev, SSB_PCICORE_BCAST_ADDR); /* flush */
- ssb_write32(dev, SSB_PCICORE_BCAST_DATA, data);
- ssb_read32(dev, SSB_PCICORE_BCAST_DATA); /* flush */
-}
+ const u16 mdio_control = 0x128;
+ const u16 mdio_data = 0x12C;
+ int max_retries = 10;
+ u32 v;
+ int i;
-static void ssb_commit_settings(struct ssb_bus *bus)
-{
- struct ssb_device *dev;
+ v = 0x80; /* Enable Preamble Sequence */
+ v |= 0x2; /* MDIO Clock Divisor */
+ pcicore_write32(pc, mdio_control, v);
- dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
- if (WARN_ON(!dev))
- return;
- /* This forces an update of the cached registers. */
- ssb_broadcast_value(dev, 0xFD8, 0);
+ if (pc->dev->id.revision >= 10) {
+ max_retries = 200;
+ ssb_pcie_mdio_set_phy(pc, device);
+ }
+
+ v = (1 << 30); /* Start of Transaction */
+ v |= (1 << 28); /* Write Transaction */
+ v |= (1 << 17); /* Turnaround */
+ if (pc->dev->id.revision < 10)
+ v |= (u32)device << 22;
+ v |= (u32)address << 18;
+ v |= data;
+ pcicore_write32(pc, mdio_data, v);
+ /* Wait for the device to complete the transaction */
+ udelay(10);
+ for (i = 0; i < max_retries; i++) {
+ v = pcicore_read32(pc, mdio_control);
+ if (v & 0x100 /* Trans complete */)
+ break;
+ msleep(1);
+ }
+ pcicore_write32(pc, mdio_control, 0);
}
int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
@@ -550,48 +707,10 @@ int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
if (pc->setup_done)
goto out;
if (pdev->id.coreid == SSB_DEV_PCI) {
- tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
- tmp |= SSB_PCICORE_SBTOPCI_PREF;
- tmp |= SSB_PCICORE_SBTOPCI_BURST;
- pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
-
- if (pdev->id.revision < 5) {
- tmp = ssb_read32(pdev, SSB_IMCFGLO);
- tmp &= ~SSB_IMCFGLO_SERTO;
- tmp |= 2;
- tmp &= ~SSB_IMCFGLO_REQTO;
- tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
- ssb_write32(pdev, SSB_IMCFGLO, tmp);
- ssb_commit_settings(bus);
- } else if (pdev->id.revision >= 11) {
- tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
- tmp |= SSB_PCICORE_SBTOPCI_MRM;
- pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
- }
+ ssb_pcicore_pci_setup_workarounds(pc);
} else {
WARN_ON(pdev->id.coreid != SSB_DEV_PCIE);
- //TODO: Better make defines for all these magic PCIE values.
- if ((pdev->id.revision == 0) || (pdev->id.revision == 1)) {
- /* TLP Workaround register. */
- tmp = ssb_pcie_read(pc, 0x4);
- tmp |= 0x8;
- ssb_pcie_write(pc, 0x4, tmp);
- }
- if (pdev->id.revision == 0) {
- const u8 serdes_rx_device = 0x1F;
-
- ssb_pcie_mdio_write(pc, serdes_rx_device,
- 2 /* Timer */, 0x8128);
- ssb_pcie_mdio_write(pc, serdes_rx_device,
- 6 /* CDR */, 0x0100);
- ssb_pcie_mdio_write(pc, serdes_rx_device,
- 7 /* CDR BW */, 0x1466);
- } else if (pdev->id.revision == 1) {
- /* DLLP Link Control register. */
- tmp = ssb_pcie_read(pc, 0x100);
- tmp |= 0x40;
- ssb_pcie_write(pc, 0x100, tmp);
- }
+ ssb_pcicore_pcie_setup_workarounds(pc);
}
pc->setup_done = 1;
out:
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index e05ba6eefc7..f8a13f86321 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -1117,23 +1117,22 @@ 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. */
+ /* The REJECT bit seems to be different for Backplane rev 2.3 */
switch (rev) {
case SSB_IDLOW_SSBREV_22:
- return SSB_TMSLOW_REJECT_22;
+ case SSB_IDLOW_SSBREV_24:
+ case SSB_IDLOW_SSBREV_26:
+ return SSB_TMSLOW_REJECT;
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_25: /* TODO - find the proper REJECT bit */
case SSB_IDLOW_SSBREV_27: /* same here */
- return SSB_TMSLOW_REJECT_23; /* this is a guess */
+ return SSB_TMSLOW_REJECT; /* 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);
+ return (SSB_TMSLOW_REJECT | SSB_TMSLOW_REJECT_23);
}
int ssb_device_is_enabled(struct ssb_device *dev)
@@ -1309,20 +1308,20 @@ EXPORT_SYMBOL(ssb_bus_may_powerdown);
int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl)
{
- struct ssb_chipcommon *cc;
int err;
enum ssb_clkmode mode;
err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
if (err)
goto error;
- cc = &bus->chipco;
- mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
- ssb_chipco_set_clockmode(cc, mode);
#ifdef CONFIG_SSB_DEBUG
bus->powered_up = 1;
#endif
+
+ mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
+ ssb_chipco_set_clockmode(&bus->chipco, mode);
+
return 0;
error:
ssb_printk(KERN_ERR PFX "Bus powerup failed\n");
@@ -1330,6 +1329,37 @@ error:
}
EXPORT_SYMBOL(ssb_bus_powerup);
+static void ssb_broadcast_value(struct ssb_device *dev,
+ u32 address, u32 data)
+{
+#ifdef CONFIG_SSB_DRIVER_PCICORE
+ /* This is used for both, PCI and ChipCommon core, so be careful. */
+ BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
+ BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
+#endif
+
+ ssb_write32(dev, SSB_CHIPCO_BCAST_ADDR, address);
+ ssb_read32(dev, SSB_CHIPCO_BCAST_ADDR); /* flush */
+ ssb_write32(dev, SSB_CHIPCO_BCAST_DATA, data);
+ ssb_read32(dev, SSB_CHIPCO_BCAST_DATA); /* flush */
+}
+
+void ssb_commit_settings(struct ssb_bus *bus)
+{
+ struct ssb_device *dev;
+
+#ifdef CONFIG_SSB_DRIVER_PCICORE
+ dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
+#else
+ dev = bus->chipco.dev;
+#endif
+ if (WARN_ON(!dev))
+ return;
+ /* This forces an update of the cached registers. */
+ ssb_broadcast_value(dev, 0xFD8, 0);
+}
+EXPORT_SYMBOL(ssb_commit_settings);
+
u32 ssb_admatch_base(u32 adm)
{
u32 base = 0;
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
index 29884c00c4d..45e5babd396 100644
--- a/drivers/ssb/scan.c
+++ b/drivers/ssb/scan.c
@@ -258,7 +258,10 @@ static int we_support_multiple_80211_cores(struct ssb_bus *bus)
#ifdef CONFIG_SSB_PCIHOST
if (bus->bustype == SSB_BUSTYPE_PCI) {
if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
- bus->host_pci->device == 0x4324)
+ ((bus->host_pci->device == 0x4313) ||
+ (bus->host_pci->device == 0x431A) ||
+ (bus->host_pci->device == 0x4321) ||
+ (bus->host_pci->device == 0x4324)))
return 1;
}
#endif /* CONFIG_SSB_PCIHOST */
@@ -307,7 +310,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
} else {
if (bus->bustype == SSB_BUSTYPE_PCI) {
bus->chip_id = pcidev_to_chipid(bus->host_pci);
- pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
+ pci_read_config_byte(bus->host_pci, PCI_REVISION_ID,
&bus->chip_rev);
bus->chip_package = 0;
} else {
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c
index 33973568214..aaa81883f0a 100644
--- a/drivers/staging/hv/netvsc_drv.c
+++ b/drivers/staging/hv/netvsc_drv.c
@@ -317,8 +317,6 @@ static void netvsc_get_drvinfo(struct net_device *net,
static const struct ethtool_ops ethtool_ops = {
.get_drvinfo = netvsc_get_drvinfo,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
.get_link = ethtool_op_get_link,
};
@@ -406,6 +404,7 @@ static int netvsc_probe(struct device *device)
net->netdev_ops = &device_ops;
/* TODO: Add GSO and Checksum offload */
+ net->hw_features = NETIF_F_SG;
net->features = NETIF_F_SG;
SET_ETHTOOL_OPS(net, &ethtool_ops);
diff --git a/firmware/Makefile b/firmware/Makefile
index 0384afa93de..0d15a3d113a 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -32,9 +32,9 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \
adaptec/starfire_tx.bin
fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin
fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw
-fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.2.5.0.fw \
- bnx2x/bnx2x-e1h-6.2.5.0.fw \
- bnx2x/bnx2x-e2-6.2.5.0.fw
+fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.2.9.0.fw \
+ bnx2x/bnx2x-e1h-6.2.9.0.fw \
+ bnx2x/bnx2x-e2-6.2.9.0.fw
fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.2.1a.fw \
bnx2/bnx2-rv2p-09-6.0.17.fw \
bnx2/bnx2-rv2p-09ax-6.0.17.fw \
diff --git a/firmware/WHENCE b/firmware/WHENCE
index 76404f9ce74..182ecb6c275 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -679,14 +679,15 @@ Found in hex form in kernel source.
Driver: bnx2x: Broadcom Everest
-File: bnx2x/bnx2x-e1-5.2.13.0.fw
-File: bnx2x/bnx2x-e1h-5.2.13.0.fw
+File: bnx2x/bnx2x-e1-6.2.9.0.fw
+File: bnx2x/bnx2x-e1h-6.2.9.0.fw
+File: bnx2x/bnx2x-e2-6.2.9.0.fw
License:
- Copyright (c) 2007-2010 Broadcom Corporation
+ Copyright (c) 2007-2011 Broadcom Corporation
This file contains firmware data derived from proprietary unpublished
- source code, Copyright (c) 2007-2009 Broadcom Corporation.
+ source code, Copyright (c) 2007-2011 Broadcom Corporation.
Permission is hereby granted for the distribution of this firmware data
in hexadecimal or equivalent format, provided this copyright notice is
diff --git a/firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex b/firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex
deleted file mode 100644
index 1b535827a74..00000000000
--- a/firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex
+++ /dev/null
@@ -1,9483 +0,0 @@
-:1000000000003BB0000000680000070C00003C202E
-:1000100000001AF8000043300000007C00005E3051
-:1000200000007A2C00005EB0000000B00000D8E0B4
-:10003000000080200000D99800000088000159C00D
-:100040000000398800015A5000000090000193E040
-:100050000000ABFC0001947800000FFC0002407827
-:100060000000000400025078020400480000000F65
-:100070000204005400000045020400580000000083
-:100080000204005C0000000602040070000000048E
-:1000900002040078000000000204007C1217000037
-:1000A00002040080221700000204008432170000BE
-:1000B00006040088000000050204009C12150000E0
-:1000C000020400A022150000020400A43215000062
-:1000D000060400A800000004020400B8021000009A
-:1000E000020400BC00100000020400C01010000058
-:1000F000020400C420100000020400C830100000F8
-:10010000060400CC00000004020400DC0010000023
-:10011000020400E012140000020400E422140000B3
-:10012000020400E832140000060400EC00000004A1
-:100130000104012400000000010401280000000067
-:100140000104012C00000000010401300000000047
-:1001500002040004000000FF02040008000000FF89
-:100160000204000C000000FF02040010000000FF69
-:1001700002040014000000FF02040018000000FF49
-:100180000204001C000000FF02040020000000FF29
-:10019000020400240000003E0204002800000000C9
-:1001A0000204002C0000003F020400300000003F69
-:1001B000020400340000003F020400380000000088
-:1001C0000204003C0000003F020400400000003F29
-:1001D000020400440000003F020420080000021155
-:1001E0000204200C0000020002042010000002049F
-:1001F00002042014000002190204201C0000FFFF6A
-:10020000020420200000FFFF020420240000FFFF62
-:10021000020420280000FFFF0604203800000080B0
-:100220000204223807FFFFFF0204223C0000003FC7
-:100230000204224007FFFFFF020422440000000FD7
-:1002400001042248000000000104224C00000000CC
-:1002500001042250000000000104225400000000AC
-:1002600001042258000000000104225C000000008C
-:10027000010422600000000001042264000000006C
-:1002800001042268000000000104226C000000004C
-:10029000010422700000000001042274000000002C
-:1002A00001042278000000000104227C000000000C
-:1002B000020424BC000000010C042000000003E83C
-:1002C0000A042000000000010B0420000000000AC6
-:1002D0000605400000000D0002050044000000205B
-:1002E00002050048000000320205009002150020BF
-:1002F000020500940215002002050098000000305D
-:100300000205009C08100000020500A00000003358
-:10031000020500A400000030020500A80000003122
-:10032000020500AC00000002020500B0000000055C
-:10033000020500B400000006020500B8000000023B
-:10034000020500BC00000002020500C00000000021
-:10035000020500C400000005020500C800000002FC
-:10036000020500CC00000002020500D000000002DF
-:10037000020500D400000001020501140000000184
-:100380000205011C0000000102050120000000021E
-:1003900002050204000000010205020C00000040FA
-:1003A00002050210000000400205021C00000020AF
-:1003B00002050220000000130205022400000020B4
-:1003C000060502400000000A04050280002000002B
-:1003D000020500500000000702050054000000075D
-:1003E00002050058000000000205005C0000000843
-:1003F0000605006000000004020500D800000006A9
-:10040000020500E00000000D020500E40000002DE0
-:10041000020500E800000000020500EC00000020DA
-:10042000020500F000000000020500F400000020BA
-:10043000020500F800000000020500FC000000209A
-:100440000205000400000001020500080000000190
-:100450000205000C00000001020500100000000170
-:100460000205001400000001020500180000000150
-:100470000205001C00000001020500200000000130
-:100480000205002400000001020500280000000110
-:100490000205002C000000010205003000000001F0
-:1004A00002050034000000010205003800000001D0
-:1004B0000205003C000000010205004000000001B0
-:1004C0000406100002000020020600DC000000010B
-:1004D000010600D80000000004060200000302200C
-:1004E000020600DC0000000002060068000000B800
-:1004F0000206007800000114010600B800000000A8
-:10050000010600C8000000000206006C000000B8F0
-:100510000206007C00000114010600BC000000007F
-:10052000010600CC0000000007180400007B00005A
-:100530000818076000140223071C00002A040000AA
-:10054000071C800032110A82071D00001E0C1707CD
-:10055000081D4550575602250118000000000000F4
-:10056000011800040000000001180008000000004D
-:100570000118000C0000000001180010000000002D
-:100580000118001400000000021800200000000103
-:1005900002180024000000020218002800000003D6
-:1005A0000218002C000000000218003000000004B7
-:1005B000021800340000000102180038000000009A
-:1005C0000218003C00000001021800400000000476
-:1005D000021800440000000002180048000000015A
-:1005E0000218004C00000003021800500000000038
-:1005F0000218005400000001021800580000000416
-:100600000218005C000000000218006000000001F9
-:1006100002180064000000030218006800000000D7
-:100620000218006C000000010218007000000004B5
-:100630000218007400000000021800780000000496
-:100640000218007C00000003061800800000000271
-:10065000021800A400003FFF021800A8000003FFDA
-:1006600002180224000000000218023400000000FA
-:100670000218024C00000000021802E4000000FF13
-:100680000618100000000400021B8BC000000001CF
-:10069000021B800000000034021B80400000001894
-:1006A000021B80800000000C021B80C000000020A4
-:1006B0000C1B83000007A1200A1B830000000138E7
-:1006C0000B1B8300000013880A1B834000000000FE
-:1006D0000C1B8340000001F40B1B8340000000054D
-:1006E000021B83800007A120021B83C0000001F4CD
-:1006F000061A100000000273041A19CC0001022728
-:10070000061A2008000000C8061A20000000000297
-:10071000041A499800040228061A2E280000000234
-:10072000061A2E2000000002061A0800000000022F
-:10073000061A080800000004061A08180000000243
-:10074000041A08B00002022C061A2FD0000000067E
-:10075000041A2FE80002022E041A2FC000040230EF
-:10076000041A300000010234061A300400000003AD
-:10077000041A301000010235061A3014000000037C
-:10078000041A302000010236061A3024000000034B
-:10079000041A303000010237061A3034000000031A
-:1007A000041A304000010238061A304400000003E9
-:1007B000041A305000010239061A305400000003B8
-:1007C000041A30600001023A061A30640000000387
-:1007D000041A30700001023B061A30740000000356
-:1007E000041A30800001023C061A30840000000325
-:1007F000041A30900001023D061A309400000003F4
-:10080000041A30A00001023E061A30A400000003C2
-:10081000041A30B00001023F061A30B40000000391
-:10082000041A30C000010240061A30C40000000360
-:10083000041A30D000010241061A30D4000000032F
-:10084000041A30E000010242061A30E400000003FE
-:10085000041A30F000010243061A30F400000003CD
-:10086000041A310000010244061A3104000000039A
-:10087000041A311000010245061A31140000000369
-:10088000041A312000010246061A31240000000338
-:10089000041A313000010247061A31340000000307
-:1008A000041A314000010248061A314400000003D6
-:1008B000041A315000010249061A315400000003A5
-:1008C000041A31600001024A061A31640000000374
-:1008D000041A31700001024B061A31740000000343
-:1008E000041A31800001024C061A31840000000312
-:1008F000041A31900001024D061A319400000003E1
-:10090000041A31A00001024E061A31A400000003AF
-:10091000041A31B00001024F061A31B4000000037E
-:10092000041A31C000010250061A31C4000000034D
-:10093000041A31D000010251061A31D4000000031C
-:10094000041A31E000010252061A31E400000003EB
-:10095000041A31F000010253061A31F400000003BA
-:10096000041A320000010254061A32040000000387
-:10097000041A321000010255061A32140000000356
-:10098000041A322000010256061A32240000000325
-:10099000041A323000010257061A323400000003F4
-:1009A000041A324000010258061A324400000003C3
-:1009B000041A325000010259061A32540000000392
-:1009C000041A32600001025A061A32640000000361
-:1009D000041A32700001025B061A32740000000330
-:1009E000041A32800001025C061A328400000003FF
-:1009F000041A32900001025D061A329400000003CE
-:100A0000041A32A00001025E061A32A4000000039C
-:100A1000041A32B00001025F061A32B4000000036B
-:100A2000041A32C000010260061A32C4000000033A
-:100A3000041A32D000010261061A32D40000000309
-:100A4000041A32E000010262061A32E400000003D8
-:100A5000041A32F000010263061A32F400000003A7
-:100A6000041A330000010264061A33040000000374
-:100A7000041A331000010265061A33140000000343
-:100A8000041A332000010266061A33240000000312
-:100A9000041A333000010267061A333400000003E1
-:100AA000041A334000010268061A334400000003B0
-:100AB000041A335000010269061A3354000000037F
-:100AC000041A33600001026A061A3364000000034E
-:100AD000041A33700001026B061A3374000000031D
-:100AE000041A33800001026C061A338400000003EC
-:100AF000041A33900001026D061A339400000003BB
-:100B0000041A33A00001026E061A33A40000000389
-:100B1000041A33B00001026F061A33B40000000358
-:100B2000041A33C000010270061A33C40000000327
-:100B3000041A33D000010271061A33D400000003F6
-:100B4000041A33E000010272061A33E400000003C5
-:100B5000041A33F000010273061A33F40000000394
-:100B6000041A340000010274061A34040000000361
-:100B7000041A341000010275061A34140000000330
-:100B8000041A342000010276061A342400000003FF
-:100B9000041A343000010277061A343400000003CE
-:100BA000041A344000010278061A3444000000039D
-:100BB000041A345000010279061A3454000000036C
-:100BC000041A34600001027A061A3464000000033B
-:100BD000041A34700001027B061A3474000000030A
-:100BE000041A34800001027C061A348400000003D9
-:100BF000041A34900001027D061A349400000003A8
-:100C0000041A34A00001027E061A34A40000000376
-:100C1000041A34B00001027F061A34B40000000345
-:100C2000041A34C000010280061A34C40000000314
-:100C3000041A34D000010281061A34D400000003E3
-:100C4000041A34E000010282061A34E400000003B2
-:100C5000041A34F000010283061A34F40000000381
-:100C6000041A350000010284061A3504000000034E
-:100C7000041A351000010285061A3514000000031D
-:100C8000041A352000010286061A352400000003EC
-:100C9000041A353000010287061A353400000003BB
-:100CA000041A354000010288061A3544000000038A
-:100CB000041A355000010289061A35540000000359
-:100CC000041A35600001028A061A35640000000328
-:100CD000041A35700001028B061A357400000003F7
-:100CE000041A35800001028C061A358400000003C6
-:100CF000041A35900001028D061A35940000000395
-:100D0000041A35A00001028E061A35A40000000363
-:100D1000041A35B00001028F061A35B40000000332
-:100D2000041A35C000010290061A35C40000000301
-:100D3000041A35D000010291061A35D400000003D0
-:100D4000041A35E000010292061A35E4000000039F
-:100D5000041A35F000010293061A35F4000000036E
-:100D6000041A360000010294061A3604000000033B
-:100D7000041A361000010295061A3614000000030A
-:100D8000041A362000010296061A362400000003D9
-:100D9000041A363000010297061A363400000003A8
-:100DA000041A364000010298061A36440000000377
-:100DB000041A365000010299061A36540000000346
-:100DC000041A36600001029A061A36640000000315
-:100DD000041A36700001029B061A367400000003E4
-:100DE000041A36800001029C061A368400000003B3
-:100DF000041A36900001029D061A36940000000382
-:100E0000041A36A00001029E061A36A40000000350
-:100E1000041A36B00001029F061A36B4000000031F
-:100E2000041A36C0000102A0061A36C400000003EE
-:100E3000041A36D0000102A1061A36D400000003BD
-:100E4000041A36E0000102A2061A36E4000000038C
-:100E5000041A36F0000102A3061A36F4000000035B
-:100E6000041A3700000102A4061A37040000000328
-:100E7000041A3710000102A5061A371400000003F7
-:100E8000041A3720000102A6061A372400000003C6
-:100E9000041A3730000102A7061A37340000000395
-:100EA000041A3740000102A8061A37440000000364
-:100EB000041A3750000102A9061A37540000000333
-:100EC000041A3760000102AA061A37640000000302
-:100ED000041A3770000102AB061A377400000003D1
-:100EE000041A3780000102AC061A378400000003A0
-:100EF000041A3790000102AD061A3794000000036F
-:100F0000041A37A0000102AE061A37A4000000033D
-:100F1000041A37B0000102AF061A37B4000000030C
-:100F2000041A37C0000102B0061A37C400000003DB
-:100F3000041A37D0000102B1061A37D400000003AA
-:100F4000041A37E0000102B2061A37E40000000379
-:100F5000041A37F0000102B3061A37F40000000348
-:100F6000041A3800000102B4061A38040000000315
-:100F7000041A3810000102B5061A381400000003E4
-:100F8000041A3820000102B6061A382400000003B3
-:100F9000041A3830000102B7061A38340000000382
-:100FA000041A3840000102B8061A38440000000351
-:100FB000041A3850000102B9061A38540000000320
-:100FC000041A3860000102BA061A386400000003EF
-:100FD000041A3870000102BB061A387400000003BE
-:100FE000041A3880000102BC061A3884000000038D
-:100FF000041A3890000102BD061A3894000000035C
-:10100000041A38A0000102BE061A38A4000000032A
-:10101000041A38B0000102BF061A38B400000003F9
-:10102000041A38C0000102C0061A38C400000003C8
-:10103000041A38D0000102C1061A38D40000000397
-:10104000041A38E0000102C2061A38E40000000366
-:10105000041A38F0000102C3061A38F40000000335
-:10106000041A3900000102C4061A39040000000302
-:10107000041A3910000102C5061A391400000003D1
-:10108000041A3920000102C6061A392400000003A0
-:10109000041A3930000102C7061A3934000000036F
-:1010A000041A3940000102C8061A3944000000033E
-:1010B000041A3950000102C9061A3954000000030D
-:1010C000041A3960000102CA061A396400000003DC
-:1010D000041A3970000102CB061A397400000003AB
-:1010E000041A3980000102CC061A3984000000037A
-:1010F000041A3990000102CD061A39940000000349
-:10110000041A39A0000102CE061A39A40000000317
-:10111000041A39B0000102CF061A39B400000003E6
-:10112000041A39C0000102D0061A39C400000003B5
-:10113000041A39D0000102D1061A39D40000000384
-:10114000041A39E0000102D2061A39E40000000353
-:10115000041A39F0000102D3061A39F40000000322
-:10116000041A3A00000102D4061A3A0400000003EF
-:10117000041A3A10000102D5061A3A1400000003BE
-:10118000041A3A20000102D6061A3A24000000038D
-:10119000041A3A30000102D7061A3A34000000035C
-:1011A000041A3A40000102D8061A3A44000000032B
-:1011B000041A3A50000102D9061A3A5400000003FA
-:1011C000041A3A60000102DA061A3A6400000003C9
-:1011D000041A3A70000102DB061A3A740000000398
-:1011E000041A3A80000102DC061A3A840000000367
-:1011F000041A3A90000102DD061A3A940000000336
-:10120000041A3AA0000102DE061A3AA40000000304
-:10121000041A3AB0000102DF061A3AB400000003D3
-:10122000041A3AC0000102E0061A3AC400000003A2
-:10123000041A3AD0000102E1061A3AD40000000371
-:10124000041A3AE0000102E2061A3AE40000000340
-:10125000041A3AF0000102E3061A3AF4000000030F
-:10126000041A3B00000102E4061A3B0400000003DC
-:10127000041A3B10000102E5061A3B1400000003AB
-:10128000041A3B20000102E6061A3B24000000037A
-:10129000041A3B30000102E7061A3B340000000349
-:1012A000041A3B40000102E8061A3B440000000318
-:1012B000041A3B50000102E9061A3B5400000003E7
-:1012C000041A3B60000102EA061A3B6400000003B6
-:1012D000041A3B70000102EB061A3B740000000385
-:1012E000041A3B80000102EC061A3B840000000354
-:1012F000041A3B90000102ED061A3B940000000323
-:10130000041A3BA0000102EE061A3BA400000003F1
-:10131000041A3BB0000102EF061A3BB400000003C0
-:10132000041A3BC0000102F0061A3BC4000000038F
-:10133000041A3BD0000102F1061A3BD4000000035E
-:10134000041A3BE0000102F2061A3BE4000000032D
-:10135000041A3BF0000102F3061A3BF400000003FC
-:10136000041A3C00000102F4061A3C0400000003C9
-:10137000041A3C10000102F5061A3C140000000398
-:10138000041A3C20000102F6061A3C240000000367
-:10139000041A3C30000102F7061A3C340000000336
-:1013A000041A3C40000102F8061A3C440000000305
-:1013B000041A3C50000102F9061A3C5400000003D4
-:1013C000041A3C60000102FA061A3C6400000003A3
-:1013D000041A3C70000102FB061A3C740000000372
-:1013E000041A3C80000102FC061A3C840000000341
-:1013F000041A3C90000102FD061A3C940000000310
-:10140000041A3CA0000102FE061A3CA400000003DE
-:10141000041A3CB0000102FF061A3CB400000003AD
-:10142000041A3CC000010300061A3CC4000000037B
-:10143000041A3CD000010301061A3CD4000000034A
-:10144000041A3CE000010302061A3CE40000000319
-:10145000041A3CF000010303061A3CF400000003E8
-:10146000041A3D0000010304061A3D0400000003B5
-:10147000041A3D1000010305061A3D140000000384
-:10148000041A3D2000010306061A3D240000000353
-:10149000041A3D3000010307061A3D340000000322
-:1014A000041A3D4000010308061A3D4400000003F1
-:1014B000041A3D5000010309061A3D5400000003C0
-:1014C000041A3D600001030A061A3D64000000038F
-:1014D000041A3D700001030B061A3D74000000035E
-:1014E000041A3D800001030C061A3D84000000032D
-:1014F000041A3D900001030D061A3D9400000003FC
-:10150000041A3DA00001030E061A3DA400000003CA
-:10151000041A3DB00001030F061A3DB40000000399
-:10152000041A3DC000010310061A3DC40000000368
-:10153000041A3DD000010311061A3DD40000000337
-:10154000041A3DE000010312061A3DE40000000306
-:10155000041A3DF000010313061A3DF400000003D5
-:10156000041A3E0000010314061A3E0400000003A2
-:10157000041A3E1000010315061A3E140000000371
-:10158000041A3E2000010316061A3E240000000340
-:10159000041A3E3000010317061A3E34000000030F
-:1015A000041A3E4000010318061A3E4400000003DE
-:1015B000041A3E5000010319061A3E5400000003AD
-:1015C000041A3E600001031A061A3E64000000037C
-:1015D000041A3E700001031B061A3E74000000034B
-:1015E000041A3E800001031C061A3E84000000031A
-:1015F000041A3E900001031D061A3E9400000003E9
-:10160000041A3EA00001031E061A3EA400000003B7
-:10161000041A3EB00001031F061A3EB40000000386
-:10162000041A3EC000010320061A3EC40000000355
-:10163000041A3ED000010321061A3ED40000000324
-:10164000041A3EE000010322061A3EE400000003F3
-:10165000041A3EF000010323061A3EF400000003C2
-:10166000041A3F0000010324061A3F04000000038F
-:10167000041A3F1000010325061A3F14000000035E
-:10168000041A3F2000010326061A3F24000000032D
-:10169000041A3F3000010327061A3F3400000003FC
-:1016A000041A3F4000010328061A3F4400000003CB
-:1016B000041A3F5000010329061A3F54000000039A
-:1016C000041A3F600001032A061A3F640000000369
-:1016D000041A3F700001032B061A3F740000000338
-:1016E000041A3F800001032C061A3F840000000307
-:1016F000041A3F900001032D061A3F9400000003D6
-:10170000041A3FA00001032E061A3FA400000003A4
-:10171000041A3FB00001032F061A3FB40000000373
-:10172000041A3FC000010330061A3FC40000000342
-:10173000041A3FD000010331061A3FD40000000311
-:10174000041A3FE000010332061A3FE400000007DC
-:10175000041A4CB000080333061A400000000124AC
-:10176000021A492000000000061A2500000000109F
-:10177000061A258000000012061A09C00000004861
-:10178000061A080000000002061A082000000012D5
-:10179000041A2FB00002033B041A4CF00002033D70
-:1017A000061A500000000004061A449000000124AC
-:1017B000021A492400000000061A2540000000100B
-:1017C000061A25C800000012061A0AE000000048A8
-:1017D000061A081000000002061A0868000000122D
-:1017E000041A2FB80002033F041A4CF80002034108
-:1017F000061A5010000000040200A468000AFFDC72
-:101800000200A280000000010200A294071D29111D
-:101810000200A298000000000200A29C009C042488
-:101820000200A2A0000000000200A2A40000020921
-:101830000200A4FCFF000000020100B4000000014F
-:10184000020100B800000001020100DC00000001FC
-:10185000020101000000000102010104000000017A
-:101860000201007C0030000002010084000000281A
-:101870000201008C000000000201013000000004A1
-:101880000201025C000000010201032800000000C8
-:101890000201055400000030020100C400000001F4
-:1018A000020100CC00000001020100F8000000016C
-:1018B000020100F000000001020100800030000081
-:1018C00002010088000000280201009000000000D2
-:1018D0000201013400000004020102DC00000001EA
-:1018E0000201032C0000000002010564000000302A
-:1018F000020100C800000001020100D00000000148
-:10190000020100FC00000001020100F400000001DF
-:10191000020C100000000028020C200800000A1130
-:10192000020C200C00000A00020C201000000A0427
-:10193000020C201C0000FFFF020C20200000FFFF13
-:10194000020C20240000FFFF020C20280000FFFFF3
-:10195000020C203800000020020C203C0000002176
-:10196000020C204000000022020C20440000002352
-:10197000020C204800000024020C204C000000252E
-:10198000020C205000000026020C2054000000270A
-:10199000020C205800000028020C205C00000029E6
-:1019A000020C20600000002A020C20640000002BC2
-:1019B000020C20680000002C020C206C0000002D9E
-:1019C000020C20700000002E020C20740000002F7A
-:1019D000020C207800000010060C207C0000004F54
-:1019E000020C21B800000001020C21BC0000000123
-:1019F000020C21C000000001020C21C40000000103
-:101A0000020C21C800000001020C21CC00000001E2
-:101A1000020C21D000000001020C21D400000001C2
-:101A2000020C21D800000001020C21DC00000001A2
-:101A3000020C21E000000001020C21E40000000182
-:101A4000020C21E800000001020C21EC0000000162
-:101A5000020C21F000000001020C21F40000000142
-:101A6000020C21F800000001060C21FC0000000F10
-:101A7000020C223807FFFFFF020C223C0000003F4F
-:101A8000020C224007FFFFFF020C22440000000F5F
-:101A9000010C224800000000010C224C0000000054
-:101AA000010C225000000000010C22540000000034
-:101AB000010C225800000000010C225C0000000014
-:101AC000010C226000000000010C226400000000F4
-:101AD000010C226800000000010C226C00000000D4
-:101AE000010C227000000000010C227400000000B4
-:101AF000010C227800000000010C227C0000000094
-:101B0000020C24BC000000010C0C2000000003E8C3
-:101B10000A0C2000000000010B0C20000000000A4D
-:101B2000020C400800000562020C400C0000055148
-:101B3000020C401000000555020C40140000057214
-:101B4000020C401C0000FFFF020C40200000FFFFC1
-:101B5000020C40240000FFFF020C40280000FFFFA1
-:101B6000020C403800000046020C403C0000000C13
-:101B7000060C40400000005E020C41B8000000016D
-:101B8000060C41BC0000001F020C423807FFFFFF9B
-:101B9000020C423C0000003F020C424007FFFFFFE6
-:101BA000020C42440000000F010C424800000000FB
-:101BB000010C424C00000000010C425000000000EB
-:101BC000010C425400000000010C425800000000CB
-:101BD000010C425C00000000010C426000000000AB
-:101BE000010C426400000000010C4268000000008B
-:101BF000010C426C00000000010C4270000000006B
-:101C0000010C427400000000010C4278000000004A
-:101C1000010C427C00000000010C4280000000002A
-:101C2000020C44C0000000010C0C4000000003E85E
-:101C30000A0C4000000000010B0C40000000000AEC
-:101C4000060D400000000A00020D004400000032B2
-:101C5000020D008C02150020020D009002150020DC
-:101C6000020D009408100000020D009800000033DF
-:101C7000020D009C00000002020D00A00000000008
-:101C8000020D00A400000005020D00A800000005E0
-:101C9000060D00AC00000002020D00B400000002BE
-:101CA000020D00B800000003020D00BC000000029D
-:101CB000020D00C000000001020D00C8000000027B
-:101CC000020D00CC00000002020D015C00000001CA
-:101CD000020D016400000001020D01680000000215
-:101CE000020D020400000001020D020C00000020A1
-:101CF000020D021000000040020D0214000000401E
-:101D0000020D022000000003020D02240000001852
-:101D1000060D028000000012040D030000180343AA
-:101D2000060D03600000000C020D004C00000001D5
-:101D3000020D005000000002020D005400000000DF
-:101D4000020D005800000008060D005C00000004B1
-:101D5000020D00C400000004020D0114000000097F
-:101D6000020D011800000029020D011C0000000AEC
-:101D7000020D01200000002A020D012400000000D5
-:101D8000020D012800000020020D012C00000000BF
-:101D9000020D013000000020020D0134000000009F
-:101DA000020D013800000020020D013C000000007F
-:101DB000020D014000000020020D0144000000005F
-:101DC000020D014800000020020D00040000000187
-:101DD000020D000800000001020D000C00000001CF
-:101DE000020D001000000001020D001400000001AF
-:101DF000020D001800000001020D001C000000018F
-:101E0000020D002000000001020D0024000000016E
-:101E1000020D002800000001020D002C000000014E
-:101E2000020D003000000001020D0034000000012E
-:101E3000020D003800000001020D003C000000010E
-:101E4000060E200000000800020E004C00000032C8
-:101E5000020E009402150020020E009802150020C8
-:101E6000020E009C00000030020E00A008100000CE
-:101E7000020E00A400000033020E00A80000003093
-:101E8000020E00AC00000031020E00B000000002A3
-:101E9000020E00B400000004020E00B800000000B2
-:101EA000020E00BC00000002020E00C00000000292
-:101EB000020E00C400000000020E00C80000000274
-:101EC000020E00CC00000007020E00D0000000024D
-:101ED000020E00D400000002020E00D80000000133
-:101EE000020E014400000001020E014C000000013E
-:101EF000020E015000000002020E02040000000168
-:101F0000020E020C00000040020E02100000004011
-:101F1000020E021C00000004020E0220000000203D
-:101F2000020E02240000000E020E02280000001B18
-:101F3000060E030000000012040E0280001B035B6B
-:101F4000060E02EC00000005020E00540000000C1A
-:101F5000020E00580000000C020E005C00000000A1
-:101F6000020E006000000010060E00640000000475
-:101F7000020E00DC00000003020E01100000000F42
-:101F8000020E01140000002F020E011800000000D4
-:101F9000020E011C00000020020E000400000001DF
-:101FA000020E000800000001020E000C00000001FB
-:101FB000020E001000000001020E001400000001DB
-:101FC000020E001800000001020E001C00000001BB
-:101FD000020E002000000001020E0024000000019B
-:101FE000020E002800000001020E002C000000017B
-:101FF000020E003000000001020E0034000000015B
-:10200000020E003800000001020E003C000000013A
-:10201000020E004000000001020E0044000000011A
-:102020000730040000AF0000083007680013037693
-:1020300007340000331C00000734800032780CC8DD
-:10204000073500001A801967083539B058CA037877
-:10205000013000000000000001300004000000001A
-:1020600001300008000000000130000C00000000FA
-:1020700001300010000000000130001400000000DA
-:1020800002300020000000010230002400000002A5
-:1020900002300028000000030230002C0000000085
-:1020A0000230003000000004023000340000000163
-:1020B00002300038000000000230003C0000000147
-:1020C0000230004000000004023000440000000024
-:1020D00002300048000000010230004C0000000304
-:1020E00002300050000000000230005400000001E7
-:1020F00002300058000000040230005C00000000C4
-:1021000002300060000000010230006400000003A3
-:1021100002300068000000000230006C0000000186
-:102120000230007000000004023000740000000063
-:1021300002300078000000040230007C0000000340
-:102140000630008000000002023000A400003FFFC3
-:10215000023000A8000003FF02300224000000004B
-:1021600002300234000000000230024C0000000087
-:10217000023002E40000FFFF0630200000000800EB
-:1021800002338BC000000001023380000000001AFF
-:10219000023380400000004E0233808000000010B7
-:1021A000023380C0000000200C3383000007A12010
-:1021B0000A338300000001380B33830000001388CA
-:1021C0000A338340000000000C338340000001F418
-:1021D0000B33834000000005023383800007A120F9
-:1021E000023383C0000001F406322A88000000C2D6
-:1021F00006322008000000C806322000000000025D
-:10220000063223E80000004004322E580004037A0E
-:10221000063250A000000004063250B80000000250
-:102220000632508000000006043250980002037EFF
-:10223000063250000000002006323000000004008A
-:1022400006321C0000000004043218300002038033
-:10225000063224E8000000B402322DB00000000075
-:1022600006324000000000B40632300000000020BA
-:10227000063231000000002006323200000000204B
-:102280000632330000000020063234000000002037
-:102290000632350000000020063236000000002023
-:1022A000063237000000002006323800000000200F
-:1022B000063239000000002006323A0000000020FB
-:1022C00006323B000000002006323C0000000020E7
-:1022D00006323D000000002006323E0000000020D3
-:1022E00006323F000000002006321C1000000002F1
-:1022F000063245A000000024063227B8000000B4D2
-:1023000002322DB400000000063242D0000000B4BA
-:1023100006323080000000200632318000000020AC
-:102320000632328000000020063233800000002098
-:102330000632348000000020063235800000002084
-:102340000632368000000020063237800000002070
-:10235000063238800000002006323980000000205C
-:1023600006323A800000002006323B800000002048
-:1023700006323C800000002006323D800000002034
-:1023800006323E800000002006323F800000002020
-:1023900006321C20000000020632463000000024F5
-:1023A0000720040000870000082007800010038237
-:1023B000072400003165000007248000081D0C5A26
-:1023C00008248EB06C9003840120000000000000FF
-:1023D00001200004000000000120000800000000AF
-:1023E0000120000C0000000001200010000000008F
-:1023F0000120001400000000022000200000000165
-:102400000220002400000002022000280000000337
-:102410000220002C00000000022000300000000418
-:1024200002200034000000010220003800000000FB
-:102430000220003C000000010220004000000004D7
-:1024400002200044000000000220004800000001BB
-:102450000220004C00000003022000500000000099
-:102460000220005400000001022000580000000477
-:102470000220005C0000000002200060000000015B
-:102480000220006400000003022000680000000039
-:102490000220006C00000001022000700000000417
-:1024A00002200074000000000220007800000004F8
-:1024B0000220007C000000030620008000000002D3
-:1024C000022000A400003FFF022000A8000003FF3C
-:1024D000022002240000000002200234000000005C
-:1024E0000220024C00000000022002E40000FFFF76
-:1024F000062020000000080002238BC0000000011D
-:10250000022380000000001002238040000000121F
-:102510000223808000000030022380C00000000EF3
-:102520000C2383000007A1200A2383000000013848
-:102530000B238300000013880A238340000000005F
-:102540000C238340000001F40B23834000000005AE
-:10255000022383800007A120022383C0000001F42E
-:10256000062250000000004206222008000000C899
-:10257000062220000000000206224000000000C6E3
-:1025800004224318000503860622432C0000000B9A
-:10259000042243580005038B0622436C0000000B05
-:1025A0000422439800050390062243AC0000000B70
-:1025B000042243D800050395062243EC0000000BDB
-:1025C000042244180005039A0622442C0000000B44
-:1025D000042244580005039F0622446C0000000BAF
-:1025E00004224498000503A4062244AC0000000B1A
-:1025F000042244D8000503A9062244EC0000000B85
-:1026000004224518000503AE0622452C0000000BED
-:1026100004224558000503B30622456C0000000B58
-:1026200004224598000503B8062245AC0000000BC3
-:10263000042245D8000503BD062245EC0000000B2E
-:1026400004224618000503C20622462C0000000B97
-:1026500004224658000503C70622466C0000000B02
-:1026600004224698000503CC062246AC0000000B6D
-:10267000042246D8000503D1062246EC0000000BD8
-:1026800004224718000503D60622472C0000000B41
-:1026900004224758000503DB0622476C0000000BAC
-:1026A00004224798000503E0062247AC0000000B17
-:1026B000042247D8000503E5062247EC0000000B82
-:1026C00004224818000503EA0622482C0000000BEB
-:1026D00004224858000503EF0622486C0000000B56
-:1026E00004224898000503F4062248AC0000000BC1
-:1026F000042248D8000503F9062248EC0000000B2C
-:1027000004224918000503FE0622492C0000000B94
-:1027100004224958000504030622496C0000000BFE
-:102720000422499800050408062249AC0000000B69
-:10273000042249D80005040D062249EC0000000BD4
-:1027400004224A180005041206224A2C0000000B3D
-:1027500004224A580005041706224A6C0000000BA8
-:1027600004224A980005041C06224AAC0000000B13
-:1027700004224AD80005042106224AEC0000000584
-:1027800006224B000000001704224B5C00010426C7
-:1027900006224B600000000304224B6C000104275A
-:1027A000062238000000004006223000000002002F
-:1027B000042251C00004042806221000000000C0BA
-:1027C000062215C00000024004221EC80008042C86
-:1027D0000622390000000008022251180000000003
-:1027E000062251D00000000606221300000000025D
-:1027F00006221410000000300622392000000008D4
-:102800000222511C00000000062251E800000006D0
-:102810000622130800000002062214D00000003037
-:102820000216100000000028021700080000000235
-:102830000217002C000000030217003C00000004F7
-:1028400002170044000000000217004800000002C8
-:102850000217004C0000009002170050000000908A
-:102860000217005400800090021700580810000062
-:10287000021700600000008A021700640000008058
-:1028800002170068000000810217006C0000008041
-:10289000021700700000000602170078000007D041
-:1028A0000217007C0000076C02170038007C10043F
-:1028B000021700040000000F06164024000000026A
-:1028C000021640700000001C0216420800000001C1
-:1028D0000216421000000001021642200000000112
-:1028E00002164228000000010216423000000001DA
-:1028F000021642380000000102164260000000018A
-:102900000C16401C0003D0900A16401C0000009CCE
-:102910000B16401C000009C40216403000000008DD
-:10292000021640340000000C02164038000000106F
-:102930000216404400000020021640000000000182
-:10294000021640D8000000010216400800000001F5
-:102950000216400C000000010216401000000001A9
-:10296000021642400000000002164248000000002B
-:1029700006164270000000020216425000000000DD
-:1029800002164258000000000616428000000002B5
-:1029900002166008000006140216600C0000060013
-:1029A00002166010000006040216601C0000FFFF03
-:1029B000021660200000FFFF021660240000FFFFE7
-:1029C000021660280000FFFF021660380000002099
-:1029D0000216603C00000020061660400000000265
-:1029E00002166048000000230216604C000000241C
-:1029F00002166050000000250216605400000026F8
-:102A000002166058000000270216605C00000029D2
-:102A1000021660600000002A021660640000002BAD
-:102A2000021660680000002C0216606C0000002D89
-:102A30000616607000000012021660B80000000167
-:102A4000021660BC00000001061660C00000003ED7
-:102A5000021661B800000001061661BC0000001FEC
-:102A60000216623807FFFFFF0216623C0000003FBB
-:102A70000216624007FFFFFF021662440000000FCB
-:102A800001166248000000000116624C00000000C0
-:102A900001166250000000000116625400000000A0
-:102AA00001166258000000000116625C0000000080
-:102AB0000116626000000000011662640000000060
-:102AC00001166268000000000116626C0000000040
-:102AD0000116627000000000011662740000000020
-:102AE00001166278000000000116627C0000000000
-:102AF000021664BC000000010C166000000003E830
-:102B00000A166000000000010B1660000000000AB9
-:102B100002168040000000060216804400000005F6
-:102B2000021680480000000A0216804C00000005D2
-:102B30000216805400000002021680CC000000043F
-:102B4000021680D000000004021680D400000004A9
-:102B5000021680D800000004021680DC0000000489
-:102B6000021680E000000004021680E40000000469
-:102B7000021680E800000004021688040000000429
-:102B8000021680300000007C021680340000003DF8
-:102B9000021680380000003F0216803C0000009CB6
-:102BA000021680F000000007061680F40000000501
-:102BB0000216880C010101010216810800000000C4
-:102BC0000216810C000000040216811000000004AF
-:102BD0000216811400000002021688100801200469
-:102BE00002168118000000050216811C0000000575
-:102BF0000216812000000005021681240000000555
-:102C00000216882C200810010216812800000008F6
-:102C10000216812C00000006021681300000000719
-:102C200002168134000000000216883001010120E4
-:102C300006168138000000040216883401010101E3
-:102C400006168148000000040216883801010101BF
-:102C500006168158000000040216883C010101019B
-:102C6000061681680000000302168174000000014E
-:102C7000021688400101010102168178000000015E
-:102C80000216817C00000001021681800000000114
-:102C9000021681840000000102168844010101012E
-:102CA00002168188000000010216818C00000004D9
-:102CB00002168190000000040216819400000002B8
-:102CC00002168848080120040216819800000005B9
-:102CD0000216819C00000005021681A0000000057C
-:102CE000021681A4000000050216881420081001B5
-:102CF000021681A800000008021681AC0000000640
-:102D0000021681B000000007021681B40000000125
-:102D10000216881801010120021681B80000000186
-:102D2000021681BC00000001021681C000000001F3
-:102D3000021681C4000000010216881C0101010175
-:102D4000021681C800000001021681CC00000001BB
-:102D5000021681D000000001021681D4000000019B
-:102D60000216882001010101021681D8000000012D
-:102D7000021681DC00000001021681E00000000163
-:102D8000021681E4000000010216882401010101FD
-:102D9000021681E800000001021681EC000000012B
-:102DA000021681F0000000010216882801010101CD
-:102DB00002168240FFFF003F061682440000000218
-:102DC0000216824CFFFF003F0216825000000100F5
-:102DD000021682540000010006168258000000020C
-:102DE00002168260000000C002168264000000C06B
-:102DF0000216826800001E000216826C00001E008F
-:102E0000021682700000400002168274000040002A
-:102E100002168278000080000216827C000080008A
-:102E2000021682800000200002168284000020002A
-:102E30000616828800000007021682A40000000126
-:102E4000061682A80000000A021681F400000C0891
-:102E5000021681F800000040021681FC000001000B
-:102E600002168200000000200216820400000017F3
-:102E700002168208000000800216820C0000020088
-:102E8000021682100000000002168218FFFF01FFE8
-:102E900002168214FFFF01FF0216823C000000139D
-:102EA000021680900000013F021680600000014081
-:102EB00002168064000001400616806800000002CF
-:102EC00002168070000000C0061680740000000723
-:102ED0000216809C00000048021680A000000048F6
-:102EE000061680A400000002021680AC0000004814
-:102EF000061680B00000000702168238000080002D
-:102F000002168234000025E40216809400007FFF40
-:102F100002168220000000070216821C0000000733
-:102F2000021682280000000002168224FFFFFFFF25
-:102F300002168230000000000216822CFFFFFFFF05
-:102F4000021680EC000000FF0214000000000001E7
-:102F50000214000C000000010214004000000001F7
-:102F60000214004400007FFF0214000C0000000067
-:102F700002140000000000000214006C00000000B9
-:102F800002140004000000010214003000000001DF
-:102F900002140004000000000214005C00000000A5
-:102FA00002140008000000010214003400000001B7
-:102FB000021400080000000002140060000000007D
-:102FC00006028000000020000202005800000032CB
-:102FD000020200A003150020020200A40315002035
-:102FE000020200A801000030020200AC081000003C
-:102FF000020200B000000033020200B40000003002
-:10300000020200B800000031020200BC0000000310
-:10301000020200C000000006020200C4000000031B
-:10302000020200C800000003020200CC00000002FF
-:10303000020200D000000000020200D400000002E2
-:10304000020200DC00000000020200E000000006B6
-:10305000020200E400000004020200E80000000296
-:10306000020200EC00000002020200F00000000179
-:10307000020200FC00000006020201200000000025
-:103080000202013400000002020201B0000000014F
-:103090000202020C00000001020202140000000102
-:1030A00002020218000000020202040400000001F3
-:1030B0000202040C00000040020204100000004064
-:1030C0000202041C00000004020204200000002090
-:1030D0000202042400000002020204280000001F73
-:1030E00006020500000000120402048000200434DF
-:1030F000020200600000000F0202006400000007EE
-:1031000002020068000000000202006C0000000ED5
-:103110000602007000000004020200F40000000437
-:103120000202000400000001020200080000000189
-:103130000202000C00000001020200100000000169
-:103140000202001400000001020200180000000149
-:103150000202001C00000001020200200000000129
-:103160000202002400000001020200280000000109
-:103170000202002C000000010202003000000001E9
-:1031800002020034000000010202003800000001C9
-:103190000202003C000000010202004000000001A9
-:1031A0000202004400000001020200480000000189
-:1031B0000202004C00000001020200500000000169
-:1031C00002020108000000C802020118000000020B
-:1031D000020201C400000000020201CC0000000055
-:1031E000020201D400000002020201DC0000000221
-:1031F000020201E4000000FF020201EC000000FFF7
-:103200000202010C000000C80202011C00000002C2
-:10321000020201C800000000020201D0000000000C
-:10322000020201D800000002020201E000000002D8
-:10323000020201E8000000FF020201F0000000FFAE
-:1032400007280400008D00000828076800130454B4
-:10325000072C000034090000072C800038990D036A
-:10326000072D0000390C1B2A072D80000641296E0E
-:10327000082D8AB04EAA0456012800000000000064
-:1032800001280004000000000128000800000000E0
-:103290000128000C000000000128001000000000C0
-:1032A0000128001400000000022800200000000196
-:1032B0000228002400000002022800280000000369
-:1032C0000228002C0000000002280030000000044A
-:1032D000022800340000000102280038000000002D
-:1032E0000228003C00000001022800400000000409
-:1032F00002280044000000000228004800000001ED
-:103300000228004C000000030228005000000000CA
-:1033100002280054000000010228005800000004A8
-:103320000228005C0000000002280060000000018C
-:10333000022800640000000302280068000000006A
-:103340000228006C00000001022800700000000448
-:103350000228007400000000022800780000000429
-:103360000228007C00000003062800800000000204
-:10337000022800A400003FFF022800A8000003FF6D
-:10338000022802240000000002280234000000008D
-:103390000228024C00000000022802E40000FFFFA7
-:1033A0000628200000000800022B8BC0000000014E
-:1033B000022B800000000000022B8040000000185B
-:1033C000022B80800000000C022B80C000000066F1
-:1033D0000C2B83000007A1200A2B8300000001387A
-:1033E0000B2B8300000013880A2B83400000000091
-:1033F0000C2B8340000001F40B2B834000000005E0
-:10340000022B83800007A120022B83C0000001F45F
-:10341000062A3D4800000004042A3D5800020458D2
-:10342000062A3D6000000006062A30000000004821
-:10343000062A2008000000C8062A2000000000021A
-:10344000062A31280000008E062A33680000000397
-:10345000042A33740001045A062A3A780000000254
-:10346000042A3A800002045B042A3A700002045DD8
-:10347000042A3E280002045F042A3EB000040461CE
-:10348000042A250000020465062A25080000010020
-:10349000062A297000000004042A29600004046739
-:1034A000042A2F480002046B062A3378000000D853
-:1034B000022A3A3800000000062A3A88000000324A
-:1034C000042A3D880010046D062A502000000002E6
-:1034D000062A503000000002062A500000000002B8
-:1034E000062A501000000002022A50B80000000115
-:1034F000062A50480000000E042A3D780002047D90
-:10350000062A3C1800000026022A50400000000055
-:10351000062A36D8000000D8022A3A3C00000000F3
-:10352000062A3B5000000032042A3DC80010047FE8
-:10353000062A502800000002062A50380000000227
-:10354000062A500800000002062A50180000000257
-:10355000022A50BC00000001062A50800000000E24
-:10356000042A3D800002048F062A3CB00000002699
-:10357000022A504400000000021010080000000160
-:103580000210101000000264021010000003D000AE
-:10359000021010040000003D091018000200049100
-:1035A00009101100001006910610114000000008DB
-:1035B00009101160000806A1061011800000000229
-:1035C00009101188000606A9061011A000000018B5
-:1035D000021010100000000006102400000000E09F
-:1035E0000210201C0000000002102020000000013A
-:1035F000021020C0000000010210200400000001A1
-:10360000021020080000000109103C00000506AF70
-:1036100009103C20000506B409103800000506B961
-:1036200002104028000000100210404400003FFF3C
-:103630000210405800280000021040840084924A82
-:1036400006104C000000010002104058000000006D
-:103650000610806800000004021080000000108046
-:1036600006108028000000020210803800000010C0
-:10367000021080400000FFFF021080440000FFFFA6
-:1036800002108050000000000210810000000000C5
-:10369000061081200000000202108008000002B520
-:1036A0000210801000000000061082000000004A96
-:1036B000021081080001FFFF061081400000000297
-:1036C0000210800000001A80061090000000002404
-:1036D000061091200000004A061093700000004A76
-:1036E000061095C00000004A0210800400001080FF
-:1036F00006108030000000020210803C0000001024
-:10370000021080480000FFFF0210804C0000FFFF05
-:10371000021080540000000002108104000000002C
-:1037200006108128000000020210800C000002B583
-:103730000210801400000000061084000000004AFF
-:103740000210810C0001FFFF0610814800000002FA
-:103750000210800400001A800610909000000024DF
-:10376000061092480000004A061094980000004A93
-:10377000061096E80000004A0212049000E383401D
-:103780000212051400003C10021205200000000285
-:1037900002120494FFFFFFFF02120498FFFFFFFFD5
-:1037A0000212049CFFFFFFFF021204A0FFFFFFFFB5
-:1037B000021204A4FFFFFFFF021204A8FFFFFFFF95
-:1037C000021204ACFFFFFFFF021204B0FFFFFFFF75
-:1037D000021204B8FFFFFFFF021204BCFFFFFFFF4D
-:1037E000021204C0FFFFFFFF021204C4FFFFFFFF2D
-:1037F000021204C8FFFFFFFF021204CCFFFFFFFF0D
-:10380000021204D0FFFFFFFF021204DCFFFFFFFFE4
-:10381000021204E0FFFFFFFF021204E4FFFFFFFFBC
-:10382000021204E8FFFFFFFF021204ECFFFFFFFF9C
-:10383000021204F0FFFFFFFF021204F4FFFFFFFF7C
-:10384000021204F8FFFFFFFF021204FCFFFFFFFF5C
-:1038500002120500FFFFFFFF02120504FFFFFFFF3A
-:1038600002120508FFFFFFFF0212050CFFFFFFFF1A
-:1038700002120510FFFFFFFF021204D4FFFF3330D6
-:10388000021204D8FFFF3340021204B4F0003000EB
-:1038900002120390000000080212039C00000008BE
-:1038A000061203A000000002021203BC0000000484
-:1038B000021203C400000004021203D00000000042
-:1038C000021203DC000000000212036C0000000181
-:1038D000021203680000003F021201BC0000004019
-:1038E000021201C000001808021201C400000803FF
-:1038F000021201C800000803021201CC00000040BF
-:10390000021201D000000003021201D400000803DB
-:10391000021201D800000803021201DC00000803B3
-:10392000021201E000010003021201E4000008039A
-:10393000021201E800000803021201EC000000037B
-:10394000021201F000000003021201F40000000363
-:10395000021201F800000003021201FC0000000343
-:103960000212020000000003021202040000000321
-:1039700002120208000000030212020C0000000301
-:1039800002120210000000030212021400000003E1
-:1039900002120218000000030212021C00000003C1
-:1039A00002120220000000030212022400000003A1
-:1039B00002120228000024030212022C0000002F31
-:1039C0000212023000000009021202340000001945
-:1039D00002120238000001840212023C000001833E
-:1039E0000212024000000306021202440000001905
-:1039F00002120248000000060212024C00000306F8
-:103A000002120250000003060212025400000306D4
-:103A10000212025800000C860212025C000003062B
-:103A20000212026000000306021202640000000697
-:103A300002120268000000060212026C000000067A
-:103A4000021202700000000602120274000000065A
-:103A500002120278000000060212027C000000063A
-:103A6000021202800000000602120284000000061A
-:103A700002120288000000060212028C00000006FA
-:103A800002120290000000060212029400000006DA
-:103A900002120298000000060212029C00000006BA
-:103AA000021202A000000306021202A4000000138A
-:103AB000021202A800000006021202B00000100468
-:103AC000021202B400001004021203240010644029
-:103AD0000212032800106440021201B0000000012D
-:103AE0000600A000000000160200A06CBF5C0000F1
-:103AF0000200A070FFF51FEF0200A0740000FFFF9E
-:103B00000200A078F00003E00200A07C00000000AA
-:103B10000200A0800000A0000600A08400000005B4
-:103B20000200A0980FE000000600A09C0000001416
-:103B30000200A0EC555400000200A0F05555555568
-:103B40000200A0F4000055550200A0F8F0000000AB
-:103B50000200A0FC555400000200A1005555555527
-:103B60000200A104000055550200A108F000000069
-:103B70000600A22C000000040200A0600000030761
-:103B80000200A10CBF5C00000200A110FFF51FEFB6
-:103B90000200A1140000FFFF0200A118F00003E0E2
-:103BA0000200A11C000000000200A1200000A000F3
-:103BB0000600A124000000050200A1380FE000006B
-:103BC0000600A13C000000140200A18C5554000026
-:103BD0000200A190555555550200A194000055557D
-:103BE0000200A198F00000000200A19C55540000C2
-:103BF0000200A1A0555555550200A1A4000055553D
-:103C00000200A1A8F00000000600A23C0000000491
-:103C10000200A06400000307000000000000000094
-:103C20000000002E00000000000000000000000066
-:103C30000000000000000000000000000000000084
-:103C40000000000000000000000000000000000074
-:103C50000000000000000000000000000000000064
-:103C60000000000000000000000000000000000054
-:103C70000000000000000000002E004D00000000C9
-:103C80000000000000000000000000000000000034
-:103C90000000000000000000000000000000000024
-:103CA00000000000004D008B00000000000000003C
-:103CB0000000000000000000000000000000000004
-:103CC00000000000000000000000000000000000F4
-:103CD000008B009000900094009400980000000079
-:103CE00000000000000000000000000000000000D4
-:103CF000000000000000000000000000009802DE4C
-:103D000002DE02E802E802F200000000000000000B
-:103D100000000000000000000000000000000000A3
-:103D20000000000000000000000000000000000093
-:103D30000000000000000000000000000000000083
-:103D40000000000000000000000000000000000073
-:103D50000000000000000000000000000000000063
-:103D60000000000000000000000000000000000053
-:103D70000000000000000000000000000000000043
-:103D80000000000000000000000000000000000033
-:103D90000000000000000000000000000000000023
-:103DA0000000000000000000000000000000000013
-:103DB0000000000000000000000000000000000003
-:103DC00000000000000000000000000000000000F3
-:103DD000000000000000000002F202FA00000000F3
-:103DE00000000000000000000000000000000000D3
-:103DF00000000000000000000000000000000000C3
-:103E000000000000000000000000000000000000B2
-:103E100000000000000000000000000000000000A2
-:103E20000000000000000000000000000000000092
-:103E300002FA02FF02FF030A030A03150000000052
-:103E40000000000000000000000000000000000072
-:103E50000000000000000000000000000000000062
-:103E60000000000000000000000000000000000052
-:103E70000000000000000000000000000000000042
-:103E80000000000000000000031503160000000001
-:103E90000000000000000000000000000000000022
-:103EA0000000000000000000000000000000000012
-:103EB000000000000316035700000000000000008F
-:103EC00000000000000000000000000000000000F2
-:103ED00000000000000000000000000000000000E2
-:103EE0000357037B000000000000000000000000FA
-:103EF00000000000000000000000000000000000C2
-:103F0000000000000000000000000000037B03BB75
-:103F100000000000000000000000000000000000A1
-:103F20000000000000000000000000000000000091
-:103F3000000000000000000003BB03F700000000C9
-:103F40000000000000000000000000000000000071
-:103F50000000000000000000000000000000000061
-:103F60000000000003F7043D043D045204520467BE
-:103F70000000000000000000000000000000000041
-:103F80000000000000000000000000000000000031
-:103F9000046704ED04ED04F204F204F700000000ED
-:103FA0000000000000000000000000000000000011
-:103FB00000000000000000000000000004F704F80A
-:103FC00000000000000000000000000000000000F1
-:103FD00000000000000000000000000000000000E1
-:103FE000000000000000000004F8050A00000000C6
-:103FF00000000000000000000000000000000000C1
-:1040000000000000000000000000000000000000B0
-:1040100000000000050A051F051F052205220525D1
-:104020000000000000000000000000000000000090
-:104030000000000000000000000000000000000080
-:1040400005250555000000000000000000000000EC
-:104050000000000000000000000000000000000060
-:10406000000000000000000000000000055505DC15
-:104070000000000000000000000000000000000040
-:104080000000000000000000000000000000000030
-:10409000000000000000000005DC05E305E305E783
-:1040A00005E705EB00000000000000000000000034
-:1040B0000000000000000000000000000000000000
-:1040C0000000000005EB062B062B06330633063BEB
-:1040D00000000000000000000000000000000000E0
-:1040E00000000000000000000000000000000000D0
-:1040F000063B068806880695069506A20000000085
-:1041000000000000000000000000000000000000AF
-:1041100000000000000000000000000006A206AE43
-:10412000000000000000000000000000000000008F
-:10413000000000000000000000000000000000007F
-:10414000000000000000000006AE06B40000000001
-:10415000000000000000000000000000000000005F
-:10416000000000000000000000000000000000004F
-:104170000000000006B406B70000000000000000C8
-:10418000000000000000000000000000000000002F
-:10419000000000000000000000000000000000001F
-:1041A00006B706BD0000000000000000000000008F
-:1041B00000000000000000000000000000000000FF
-:1041C00000000000000000000000000006BD06BE68
-:1041D00006BE06D006D006E2000000000000000087
-:1041E00000000000000000000000000000000000CF
-:1041F000000000000000000006E2074F0000000081
-:1042000000000000000000000000000000000000AE
-:10421000000000000000000000000000000000009E
-:1042200000000000074F0750075007630763077639
-:10423000000000000000000000000000000000007E
-:10424000000000000000000000000000000000006E
-:10425000000000000000000000000000000000005E
-:10426000000000000000000000000000000000004E
-:10427000000000000000000000000000000000003E
-:10428000000000000000000000000000000000002E
-:10429000000000000000000000000000000000001E
-:1042A000000000000000000000000000000000000E
-:1042B00000000000000000000000000000000000FE
-:1042C00000000000000000000000000000000000EE
-:1042D00000000000000000000000000000000000DE
-:1042E00000000000000000000000000000000000CE
-:1042F00000000000000000000000000000000000BE
-:1043000000000000000000000000000000000000AD
-:10431000000000000000000000000000000000009D
-:10432000000000000000000000000000000000008D
-:1043300000010000000204C00003098000040E40D8
-:1043400000051300000617C000071C80000821406C
-:1043500000092600000A2AC0000B2F80000C344000
-:10436000000D3900000E3DC0000F42800010474094
-:1043700000114C00001250C00013558000145A4028
-:1043800000155F00001663C00017688000186D40BC
-:1043900000197200001A76C0001B7B80001C804050
-:1043A000001D8500001E89C0001F8E800000934004
-:1043B00000002000000040000000600000008000BD
-:1043C0000000A0000000C0000000E00000010000AC
-:1043D0000001200000014000000160000001800099
-:1043E0000001A0000001C0000001E0000002000088
-:1043F0000002200000024000000260000002800075
-:104400000002A0000002C0000002E0000003000063
-:104410000003200000034000000360000003800050
-:104420000003A0000003C0000003E000000400003F
-:10443000000420000004400000046000000480002C
-:104440000004A0000004C0000004E000000500001B
-:104450000005200000054000000560000005800008
-:104460000005A0000005C0000005E00000060000F7
-:1044700000062000000640000006600000068000E4
-:104480000006A0000006C0000006E00000070000D3
-:1044900000072000000740000007600000078000C0
-:1044A0000007A0000007C0000007E00000080000AF
-:1044B000000820000008400000086000000880009C
-:1044C0000008A0000008C0000008E000000900008B
-:1044D0000009200000094000000960000009800078
-:1044E0000009A0000009C0000009E000000A000067
-:1044F000000A2000000A4000000A6000000A800054
-:10450000000AA000000AC000000AE000000B000042
-:10451000000B2000000B4000000B6000000B80002F
-:10452000000BA000000BC000000BE000000C00001E
-:10453000000C2000000C4000000C6000000C80000B
-:10454000000CA000000CC000000CE000000D0000FA
-:10455000000D2000000D4000000D6000000D8000E7
-:10456000000DA000000DC000000DE000000E0000D6
-:10457000000E2000000E4000000E6000000E8000C3
-:10458000000EA000000EC000000EE000000F0000B2
-:10459000000F2000000F4000000F6000000F80009F
-:1045A000000FA000000FC000000FE000001000008E
-:1045B000001020000010400000106000001080007B
-:1045C0000010A0000010C0000010E000001100006A
-:1045D0000011200000114000001160000011800057
-:1045E0000011A0000011C0000011E0000012000046
-:1045F0000012200000124000001260000012800033
-:104600000012A0000012C0000012E0000013000021
-:10461000001320000013400000136000001380000E
-:104620000013A0000013C0000013E00000140000FD
-:1046300000142000001440000014600000148000EA
-:104640000014A0000014C0000014E00000150000D9
-:1046500000152000001540000015600000158000C6
-:104660000015A0000015C0000015E00000160000B5
-:1046700000162000001640000016600000168000A2
-:104680000016A0000016C0000016E0000017000091
-:10469000001720000017400000176000001780007E
-:1046A0000017A0000017C0000017E000001800006D
-:1046B000001820000018400000186000001880005A
-:1046C0000018A0000018C0000018E0000019000049
-:1046D0000019200000194000001960000019800036
-:1046E0000019A0000019C0000019E000001A000025
-:1046F000001A2000001A4000001A6000001A800012
-:10470000001AA000001AC000001AE000001B000000
-:10471000001B2000001B4000001B6000001B8000ED
-:10472000001BA000001BC000001BE000001C0000DC
-:10473000001C2000001C4000001C6000001C8000C9
-:10474000001CA000001CC000001CE000001D0000B8
-:10475000001D2000001D4000001D6000001D8000A5
-:10476000001DA000001DC000001DE000001E000094
-:10477000001E2000001E4000001E6000001E800081
-:10478000001EA000001EC000001EE000001F000070
-:10479000001F2000001F4000001F6000001F80005D
-:1047A000001FA000001FC000001FE000002000004C
-:1047B0000020200000204000002060000020800039
-:1047C0000020A0000020C0000020E0000021000028
-:1047D0000021200000214000002160000021800015
-:1047E0000021A0000021C0000021E0000022000004
-:1047F00000222000002240000022600000228000F1
-:104800000022A0000022C0000022E00000230000DF
-:1048100000232000002340000023600000238000CC
-:104820000023A0000023C0000023E00000240000BB
-:1048300000242000002440000024600000248000A8
-:104840000024A0000024C0000024E0000025000097
-:104850000025200000254000002560000025800084
-:104860000025A0000025C0000025E0000026000073
-:104870000026200000264000002660000026800060
-:104880000026A0000026C0000026E000002700004F
-:10489000002720000027400000276000002780003C
-:1048A0000027A0000027C0000027E000002800002B
-:1048B0000028200000284000002860000028800018
-:1048C0000028A0000028C0000028E0000029000007
-:1048D00000292000002940000029600000298000F4
-:1048E0000029A0000029C0000029E000002A0000E3
-:1048F000002A2000002A4000002A6000002A8000D0
-:10490000002AA000002AC000002AE000002B0000BE
-:10491000002B2000002B4000002B6000002B8000AB
-:10492000002BA000002BC000002BE000002C00009A
-:10493000002C2000002C4000002C6000002C800087
-:10494000002CA000002CC000002CE000002D000076
-:10495000002D2000002D4000002D6000002D800063
-:10496000002DA000002DC000002DE000002E000052
-:10497000002E2000002E4000002E6000002E80003F
-:10498000002EA000002EC000002EE000002F00002E
-:10499000002F2000002F4000002F6000002F80001B
-:1049A000002FA000002FC000002FE000003000000A
-:1049B00000302000003040000030600000308000F7
-:1049C0000030A0000030C0000030E00000310000E6
-:1049D00000312000003140000031600000318000D3
-:1049E0000031A0000031C0000031E00000320000C2
-:1049F00000322000003240000032600000328000AF
-:104A00000032A0000032C0000032E000003300009D
-:104A1000003320000033400000336000003380008A
-:104A20000033A0000033C0000033E0000034000079
-:104A30000034200000344000003460000034800066
-:104A40000034A0000034C0000034E0000035000055
-:104A50000035200000354000003560000035800042
-:104A60000035A0000035C0000035E0000036000031
-:104A7000003620000036400000366000003680001E
-:104A80000036A0000036C0000036E000003700000D
-:104A900000372000003740000037600000378000FA
-:104AA0000037A0000037C0000037E00000380000E9
-:104AB00000382000003840000038600000388000D6
-:104AC0000038A0000038C0000038E00000390000C5
-:104AD00000392000003940000039600000398000B2
-:104AE0000039A0000039C0000039E000003A0000A1
-:104AF000003A2000003A4000003A6000003A80008E
-:104B0000003AA000003AC000003AE000003B00007C
-:104B1000003B2000003B4000003B6000003B800069
-:104B2000003BA000003BC000003BE000003C000058
-:104B3000003C2000003C4000003C6000003C800045
-:104B4000003CA000003CC000003CE000003D000034
-:104B5000003D2000003D4000003D6000003D800021
-:104B6000003DA000003DC000003DE000003E000010
-:104B7000003E2000003E4000003E6000003E8000FD
-:104B8000003EA000003EC000003EE000003F0000EC
-:104B9000003F2000003F4000003F6000003F8000D9
-:104BA000003FA000003FC000003FE000003FE001E8
-:104BB00000000000000001FF0000020000007FF87C
-:104BC00000007FF80000016A0000150000000001ED
-:104BD0000000FF00000000000000FF0000000000D7
-:104BE00000000000140AFF000000000100000000A7
-:104BF00000201001000000000100860000000100FC
-:104C00000000860200008604000086060000860878
-:104C10000000860A0000860C0000860E0000861048
-:104C20000000861200008614000086160000861818
-:104C30000000861A0000861C0000861E00008620E8
-:104C400000008622000086240000862600008628B8
-:104C50000000862A0000862C0000862E0000863088
-:104C60000000863200008634000086360000863858
-:104C70000000863A0000863C0000863E0000864028
-:104C800000008642000086440000864600008648F8
-:104C90000000864A0000864C0000864E00008650C8
-:104CA0000000865200008654000086560000865898
-:104CB0000000865A0000865C0000865E0000866068
-:104CC0000000866200008664000086660000866838
-:104CD0000000866A0000866C0000866E0000867008
-:104CE00000008672000086740000867600008678D8
-:104CF0000000867A0000867C0000867E00008680A8
-:104D00000000868200008684000086860000868877
-:104D10000000868A0000868C0000868E0000869047
-:104D20000000869200008694000086960000869817
-:104D30000000869A0000869C0000869E000086A0E7
-:104D4000000086A2000086A4000086A6000086A8B7
-:104D5000000086AA000086AC000086AE000086B087
-:104D6000000086B2000086B4000086B6000086B857
-:104D7000000086BA000086BC000086BE000086C027
-:104D8000000086C2000086C4000086C6000086C8F7
-:104D9000000086CA000086CC000086CE000086D0C7
-:104DA000000086D2000086D4000086D6000086D897
-:104DB000000086DA000086DC000086DE000086E067
-:104DC000000086E2000086E4000086E6000086E837
-:104DD000000086EA000086EC000086EE000086F007
-:104DE000000086F2000086F4000086F6000086F8D7
-:104DF000000086FA000086FC000086FE00008700A6
-:104E00000000870200008704000087060000870872
-:104E10000000870A0000870C0000870E0000871042
-:104E20000000871200008714000087160000871812
-:104E30000000871A0000871C0000871E00008720E2
-:104E400000008722000087240000872600008728B2
-:104E50000000872A0000872C0000872E0000873082
-:104E60000000873200008734000087360000873852
-:104E70000000873A0000873C0000873E0000874022
-:104E800000008742000087440000874600008748F2
-:104E90000000874A0000874C0000874E00008750C2
-:104EA0000000875200008754000087560000875892
-:104EB0000000875A0000875C0000875E0000876062
-:104EC0000000876200008764000087660000876832
-:104ED0000000876A0000876C0000876E0000877002
-:104EE00000008772000087740000877600008778D2
-:104EF0000000877A0000877C0000877E00008780A2
-:104F00000000878200008784000087860000878871
-:104F10000000878A0000878C0000878E0000879041
-:104F20000000879200008794000087960000879811
-:104F30000000879A0000879C0000879E000087A0E1
-:104F4000000087A2000087A4000087A6000087A8B1
-:104F5000000087AA000087AC000087AE000087B081
-:104F6000000087B2000087B4000087B6000087B851
-:104F7000000087BA000087BC000087BE000087C021
-:104F8000000087C2000087C4000087C6000087C8F1
-:104F9000000087CA000087CC000087CE000087D0C1
-:104FA000000087D2000087D4000087D6000087D891
-:104FB000000087DA000087DC000087DE000087E061
-:104FC000000087E2000087E4000087E6000087E831
-:104FD000000087EA000087EC000087EE000087F001
-:104FE000000087F2000087F4000087F6000087F8D1
-:104FF000000087FA000087FC000087FEFFFFFFFF2C
-:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
-:10501000FFFFFFFFFFFFFFFFFFFFFFFF0000000399
-:1050200000BEBC20000000000000000500000003DE
-:1050300000BEBC20000000000000000500002000B1
-:10504000000040C000006180000082400000A3001A
-:105050000000C3C00000E4800001054000012600FC
-:10506000000146C000016780000188400001A900DE
-:105070000001C9C00001EA8000020B4000022C00C0
-:1050800000024CC000026D8000028E400002AF00A2
-:105090000002CFC00002F08000001140000080003C
-:1050A000000103800001870000020A8000028E00D8
-:1050B00000031180000395000004188000049C0088
-:1050C00000051F800005A300000626800006AA0038
-:1050D00000072D800007B100000834800008B800E8
-:1050E00000093B800009BF00000A4280000AC60098
-:1050F000000B4980000BCD00000C5080000CD40048
-:10510000000D578000005B0000007FF800007FF872
-:1051100000000166000015000000FF000000000014
-:105120000000FF0000000000000019000000000067
-:1051300000000000FFFFFFFF00007FF800007FF885
-:1051400000000361000015000000FF000FFFFFFFDB
-:105150000000FF000FFFFFFF000000FF0000FF0046
-:105160000FFFFFFF0000FF000FFFFFFF000000FF29
-:105170000000FF000FFFFFFF0000FF000FFFFFFF19
-:10518000000000FF0000FF000FFFFFFF0000FF0016
-:105190000FFFFFFF000000FF0000FF000FFFFFFFF9
-:1051A0000000FF000FFFFFFF000000FF0000FF00F6
-:1051B0000FFFFFFF0000FF000FFFFFFF000000FFD9
-:1051C0000000FF000FFFFFFF0000FF000FFFFFFFC9
-:1051D000000000FF0000FF000FFFFFFF0000FF00C6
-:1051E0000FFFFFFF000000FF0000FF000FFFFFFFA9
-:1051F0000000FF000FFFFFFF000000FF0000FF00A6
-:105200000FFFFFFF0000FF000FFFFFFF000000FF88
-:105210000000FF000FFFFFFF0000FF000FFFFFFF78
-:10522000000000FF0000FF000FFFFFFF0000FF0075
-:105230000FFFFFFF000000FF0000FF000FFFFFFF58
-:105240000000FF000FFFFFFF000000FF0000FF0055
-:105250000FFFFFFF0000FF000FFFFFFF000000FF38
-:105260000000FF000FFFFFFF0000FF000FFFFFFF28
-:10527000000000FF0000FF000FFFFFFF0000FF0025
-:105280000FFFFFFF000000FF0000FF000FFFFFFF08
-:105290000000FF000FFFFFFF000000FF0000FF0005
-:1052A0000FFFFFFF0000FF000FFFFFFF000000FFE8
-:1052B0000000FF000FFFFFFF0000FF000FFFFFFFD8
-:1052C000000000FF0000FF000FFFFFFF0000FF00D5
-:1052D0000FFFFFFF000000FF0000FF000FFFFFFFB8
-:1052E0000000FF000FFFFFFF000000FF0000FF00B5
-:1052F0000FFFFFFF0000FF000FFFFFFF000000FF98
-:105300000000FF000FFFFFFF0000FF000FFFFFFF87
-:10531000000000FF0000FF000FFFFFFF0000FF0084
-:105320000FFFFFFF000000FF0000FF000FFFFFFF67
-:105330000000FF000FFFFFFF000000FF0000FF0064
-:105340000FFFFFFF0000FF000FFFFFFF000000FF47
-:105350000000FF000FFFFFFF0000FF000FFFFFFF37
-:10536000000000FF0000FF000FFFFFFF0000FF0034
-:105370000FFFFFFF000000FF0000FF000FFFFFFF17
-:105380000000FF000FFFFFFF000000FF0000FF0014
-:105390000FFFFFFF0000FF000FFFFFFF000000FFF7
-:1053A0000000FF000FFFFFFF0000FF000FFFFFFFE7
-:1053B000000000FF0000FF000FFFFFFF0000FF00E4
-:1053C0000FFFFFFF000000FF000000FF000000FFD4
-:1053D0000000FF00000000000000FF0000000000CF
-:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
-:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
-:1054000000001000000020800000310000004180FA
-:1054100000005200000062800000730000008380E2
-:10542000000094000000A4800000B5000000C580CA
-:105430000000D6000000E6800000F70000010780B1
-:105440000001180000012880000139000001498096
-:1054500000015A0000016A8000017B0000018B807E
-:1054600000019C000001AC800001BD000001CD8066
-:105470000001DE000001EE8000000F0000000000CF
-:1054800000007FF800007FF80000021D00001500FA
-:1054900010000000000028AD00010001FFFFFFFF29
-:1054A000FFFFFFFF00050206CCCCCCC17058103CBA
-:1054B000000000000000FF00000000000000FF00EE
-:1054C000000000000000000000000001CCCC020140
-:1054D000CCCCCCCCCCCC0201CCCCCCCC00000000D1
-:1054E000FFFFFFFF0000FFFF000000000000FFFFC4
-:1054F000000000000000FFFF000000000000FFFFB0
-:10550000000000000000FFFF000000000000FFFF9F
-:10551000000000000000FFFF000000000000FFFF8F
-:1055200000000000000E0000011600D60000FFFF82
-:10553000000000000000FFFF000000000000FFFF6F
-:10554000000000000000FFFF000000000000FFFF5F
-:10555000000000000000FFFF000000000000FFFF4F
-:10556000000000000000FFFF0000000000720000CB
-:10557000012300F3FFFFFFF3318FFFFF0C30C30C5B
-:10558000C30C30C3CF3CF300F3CF3CF30000CF3C5F
-:10559000CDCDCDCDFFFFFFF130EFFFFF0C30C30CC1
-:1055A000C30C30C3CF3CF300F3CF3CF30001CF3C3E
-:1055B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2C
-:1055C000C30C30C3CF3CF300F3CF3CF30002CF3C1D
-:1055D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C2
-:1055E000C30C30C3CF300014F3CF3CF30004CF3CE6
-:1055F000CDCDCDCDFFFFFFF2304FFFFF0C30C30C00
-:10560000C30C30C3CF3CF300F3CF3CF30008CF3CD6
-:10561000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF7
-:10562000C30C30C3CF3CF300F3CF3CF30010CF3CAE
-:10563000CDCDCDCDFFFFFFF731EFFFFF0C30C30C19
-:10564000C30C30C3CF3CF300F3CF3CF30020CF3C7E
-:10565000CDCDCDCDFFFFFFF5302FFFFF0C30C30CBC
-:10566000C30C30C3CF3CF300F3CF3CF30040CF3C3E
-:10567000CDCDCDCDFFFFFFF3318FFFFF0C30C30C3D
-:10568000C30C30C3CF3CF300F3CF3CF30000CF3C5E
-:10569000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9F
-:1056A000C30C30C3CF3CF300F3CF3CF30001CF3C3D
-:1056B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2B
-:1056C000C30C30C3CF3CF300F3CF3CF30002CF3C1C
-:1056D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C1
-:1056E000C30C30C3CF300014F3CF3CF30004CF3CE5
-:1056F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFF
-:10570000C30C30C3CF3CF300F3CF3CF30008CF3CD5
-:10571000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF6
-:10572000C30C30C3CF3CF300F3CF3CF30010CF3CAD
-:10573000CDCDCDCDFFFFFFF730EFFFFF0C30C30C19
-:10574000C30C30C3CF3CF300F3CF3CF30020CF3C7D
-:10575000CDCDCDCDFFFFFFF5304FFFFF0C30C30C9B
-:10576000C30C30C3CF3CF300F3CF3CF30040CF3C3D
-:10577000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CF1
-:10578000C30C30C3CF3CF3CCF3CF3CF30000CF3C91
-:10579000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CD1
-:1057A000C30C30C3CF3CF3CCF3CF3CF30001CF3C70
-:1057B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CB1
-:1057C000C30C30C3CF3CF3CCF3CF3CF30002CF3C4F
-:1057D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C91
-:1057E000C30C30C3CF3CF3CCF3CF3CF30004CF3C2D
-:1057F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C71
-:10580000C30C30C3CF3CF3CCF3CF3CF30008CF3C08
-:10581000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C50
-:10582000C30C30C3CF3CF3CCF3CF3CF30010CF3CE0
-:10583000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C30
-:10584000C30C30C3CF3CF3CCF3CF3CF30020CF3CB0
-:10585000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C10
-:10586000C30C30C3CF3CF3CCF3CF3CF30040CF3C70
-:10587000CDCDCDCDFFFFFFF3320FFFFF0C30C30CBA
-:10588000C30C30C3CF3CF300F3CF3CF30000CF3C5C
-:10589000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9D
-:1058A000C30C30C3CF3CF300F3CF3CF30001CF3C3B
-:1058B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C29
-:1058C000C30C30C3CF3CF300F3CF3CF30002CF3C1A
-:1058D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BF
-:1058E000C30C30C3CF300014F3CF3CF30004CF3CE3
-:1058F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFD
-:10590000C30C30C3CF3CF300F3CF3CF30008CF3CD3
-:10591000CDCDCDCDFFFFFF8A042FFFFF0C30C30C90
-:10592000C30C30C3CF3CC000F3CF3CF30010CF3CDE
-:10593000CDCDCDCDFFFFFF9705CFFFFF0C30C30CC2
-:10594000C30C30C3CF3CC000F3CF3CF30020CF3CAE
-:10595000CDCDCDCDFFFFFFF5310FFFFF0C30C30CD8
-:10596000C30C30C3CF3CF300F3CF3CF30040CF3C3B
-:10597000CDCDCDCDFFFFFFF3300FFFFF0C30C30CBB
-:10598000C30C30C3CF3CF300F3CF3CF30000CF3C5B
-:10599000CDCDCDCDFFFFFFF1300FFFFF0C30C30C9D
-:1059A000C30C30C3CF3CF300F3CF3CF30001CF3C3A
-:1059B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C28
-:1059C000C30C30C3CF3CF300F3CF3CF30002CF3C19
-:1059D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BE
-:1059E000C30C30C3CF300014F3CF3CF30004CF3CE2
-:1059F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFC
-:105A0000C30C30C3CF3CF300F3CF3CF30008CF3CD2
-:105A1000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF3
-:105A2000C30C30C3CF3CF300F3CF3CF30010CF3CAA
-:105A3000CDCDCDCDFFFFFF97040FFFFF0C30C30C82
-:105A4000C30C30C3CF3CC000F3CF3CF30020CF3CAD
-:105A5000CDCDCDCDFFFFFFF5300FFFFF0C30C30CD8
-:105A6000C30C30C3CF3CF300F3CF3CF30040CF3C3A
-:105A7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEE
-:105A8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8E
-:105A9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCE
-:105AA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6D
-:105AB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAE
-:105AC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4C
-:105AD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8E
-:105AE000C30C30C3CF3CF3CCF3CF3CF30004CF3C2A
-:105AF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6E
-:105B0000C30C30C3CF3CF3CCF3CF3CF30008CF3C05
-:105B1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4D
-:105B2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDD
-:105B3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2D
-:105B4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAD
-:105B5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0D
-:105B6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6D
-:105B7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CED
-:105B8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8D
-:105B9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCD
-:105BA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6C
-:105BB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAD
-:105BC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4B
-:105BD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8D
-:105BE000C30C30C3CF3CF3CCF3CF3CF30004CF3C29
-:105BF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6D
-:105C0000C30C30C3CF3CF3CCF3CF3CF30008CF3C04
-:105C1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4C
-:105C2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDC
-:105C3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2C
-:105C4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAC
-:105C5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0C
-:105C6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6C
-:105C7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEC
-:105C8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8C
-:105C9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCC
-:105CA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6B
-:105CB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAC
-:105CC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4A
-:105CD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8C
-:105CE000C30C30C3CF3CF3CCF3CF3CF30004CF3C28
-:105CF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6C
-:105D0000C30C30C3CF3CF3CCF3CF3CF30008CF3C03
-:105D1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4B
-:105D2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDB
-:105D3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2B
-:105D4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAB
-:105D5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0B
-:105D6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6B
-:105D7000CDCDCDCD000C0000000700C00002813069
-:105D8000000B81580002021000010230000F024097
-:105D900000010330000C0000000800C00002814038
-:105DA000000B81680002022000010240000702503F
-:105DB000000202C000100000000801000002818003
-:105DC000000B81A80002026000018280000E829810
-:105DD0000008038000028000000B8028000200E021
-:105DE000000101000000811000000118CCCCCCCCD7
-:105DF000CCCCCCCCCCCCCCCCCCCCCCCC00002000F3
-:105E0000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCD2
-:105E100000002000CCCCCCCCCCCCCCCCCCCCCCCCD2
-:105E2000CCCCCCCC00002000000000000000000022
-:105E30001F8B080000000000000BFB51CFC0F003D7
-:105E40008ABB5819180238107C7AE0A58C94E9DFD7
-:105E5000C8CCC0B00388AF02F17E66D2F5B34A2346
-:105E6000D8F7241818182419184E893130EC9244A8
-:105E700088E702D5084A3130DC858A0500D967A554
-:105E8000E81B4EA39836F8BB3A2AFF912A84CE87A6
-:105E900089A3C93F86CA6F5480D03FD5B19BBB0947
-:105EA0002A0F00FE694F6760030000000000000039
-:105EB0001F8B080000000000000BED7D0B7854D50F
-:105EC000B9E8DACFD933994C7642422610700703ED
-:105ED000040D30208FA85427E1D1E0E5E8F0462EEC
-:105EE000CA80AF0892448D356D39373B6412020287
-:105EF0008ECAA1B4A53A207AA247DBD4464B7BF5E3
-:105F0000DC206A73DAD37B9152A52DB6413D281669
-:105F100068F49403BDD796BBFE7FAD3DD97B672661
-:105F20000F5FDF395F1B3EDD597BAFBDD6BFFEF78C
-:105F3000FAFF7FEDA8A242D44B08B9083FD712B2AE
-:105F40004E2084E4F55EADFB448B56935C42AA82FE
-:105F5000AAB1953E5B2F858DC669F4FE2562E809DE
-:105F600002F7C7CD21930851E0BD0242A6C2FFA6A9
-:105F70001322E7B40E8FFAE93D6955165CADF1AC1A
-:105F80006B954C883E159E6F1B97EA7972FE84D202
-:105F9000D3AD11FCB9388690FAE337CE7FC56AD30A
-:105FA000FF4692CCDC9397D35F6692991725423EC9
-:105FB0002A5C94D569A41FEF83862E5D1E4BC8F919
-:105FC0008615F35F19DBF7F97A89D4B697F6BD7FAA
-:105FD00015D1102F4433D5C8C4DE75AF27A4D39391
-:105FE00043C8E6C24D6CBDB9145957D2FB6DFFA230
-:105FF000CB25BD70AE9769BFA97DD7438889E35A89
-:10600000E324DF4F7439DE77BF971C8FBF4F64FAEC
-:106010006F0621D885AE7FBA10BD16EE7B0A1799A0
-:1060200023687BFD33E5245A9A1EFE24BD3E21FCE5
-:10603000D67B69E9C8FB7DB4BFA985D0F74EAAF12C
-:10604000EBAFA27CF4DEF7A5D026E0A33DE3E7901A
-:1060500000BD4F181F59743AB5BF69782AFE4847EA
-:10606000A7BF275EE43F8BBFAAC455599DE493F3B5
-:10607000D71DC05F1936FE6A5FDCEF789F94BF6260
-:106080006EFEE2F838DDCED64F760F6374E1F4721F
-:10609000D3272D5D3EE97B7DF9690BE0D5D3BED8D2
-:1060A0001C4152F01387D7A2D7A78577203E222420
-:1060B0008E74262422C1FCBDF7D935A3CC1080CF25
-:1060C00068F330AC23C8A622C15B5BEE16299C01A5
-:1060D00092681D5744DBDD6B1600DC81E3F34F81D2
-:1060E0003C34872AB4D974BDFA34E3A179F49A51C7
-:1060F000AA0BB09EAD44042540C7AB36CB4B815EA6
-:1061000004DB4F9BB7844DC0030913329C90FBF80E
-:106110009A08110D99B655F8754CAA75A8A493E183
-:1061200043B8E8E9FB7EBAF5ABBDEF918B45F0FFD4
-:106130007B08AC6FA0F74894BD67D27F80EF1CD777
-:1061400038FA1CDAB6F17D80D8DAF4F951F805F1A5
-:106150007DF717325F36D9A719543FA825A29E8034
-:10616000FEC4C896693BA3922A22781E24072945BB
-:1061700006A44B332195EDC08FA49D2C9CD80BDF3A
-:106180002922E07A0A6EDFB9A685AAAE7365FE10F1
-:10619000F079502764584EDFF56C6BA08C3CDED64E
-:1061A0000E3D87FC1FA37C3486BE6F86983DDC5A6B
-:1061B000F2B21EB5C977862070BE74F30731E419B8
-:1061C0002066C02AF45A2286BD814FCF1FB20B8FA2
-:1061D00083E50F7FD4461F32747A05B9DF3058FE4D
-:1061E000F8B4F35974ED2B578D165D3542E9B0A51F
-:1061F00078514AFF233D5DF711E89F5142C289144F
-:10620000EF8D12042E07A643DFE095D2474A92F79E
-:106210005E07BDA4FC192BF6F6830F29D7890F6BF7
-:106220005C6FBD64BC4B5522917511C653613CCA6D
-:10623000A75B820F9B84CAC339E06D8A0F293EA5F4
-:1062400013DAA498201FD29F4E81B6BDC170622B75
-:10625000F24102E962C1E73144077EE55C9FA34D4C
-:106260005698821D7E6FBD8A70A8E823D071743A5B
-:10627000204585EC279DC0B716BF021B5CBC14DA15
-:106280005F77F041AB3195A4A283C5AF8056C6AF0E
-:106290005F1F9C7E71CFB7C409EFA0DFF3CBC64967
-:1062A0009B1D4AFF9E4C4E5AF4A148AC82016C7C67
-:1062B000B059210784C98434152E23517A77333C91
-:1062C000A276AC05AE05E01F4E45BD40DA0419E0EC
-:1062D000B4EC2A09E660BFE98281E3895A2DEA1508
-:1062E000C91F66F6953F4F0F179B7FB8110FEB1430
-:1062F000BFF9241E16297DA8AE0C7512D09B610231
-:106300007C40428C2F24EEA75BEFC7383F7BC951FE
-:106310007C9F6A5753477BE694E3B9127D48C7D9FF
-:106320005242121EA4535C83B65C2213D81750FD50
-:10633000E42FA0FDB32CF697168400FE2C6E5FC9E7
-:106340002CCEDF02D56714CFFE694EF9F6B9E45FB3
-:10635000E6F6B88F3E4BB39FB0AE6EFFED3181FBDA
-:106360006F19C48FF4E6EF137F6A7FD5F2DB2CBC84
-:10637000E68904F1497EAA249E28E26BA3ED7BDE28
-:10638000CA4EC0BACD8AC89A668A07F36D21D40472
-:10639000F494C33D59F4F9C92725DC2FE52DABBF93
-:1063A00004E6DBDE608E2DB6F983DBE55A0DF04D99
-:1063B000F942B3DB8B1B48F405C1B6FFF2045BC6A0
-:1063C000160F43FE7BBBBB044C8580FCE7F5C78200
-:1063D000AF825CF2FB49FCD8DB52DF766E3EE1F621
-:1063E000F286F2309DB71574D7087C6C0A149ED6DD
-:1063F00002D6FE49E3F072B09FAD99ACFD51E33B8C
-:10640000E146E48BA816A1F7EA09C74B17C50BD2E2
-:10641000DFC8B7DB57F7D5BDFE1DB2EE033EDBEBA1
-:10642000CFB9AE04EC67991802B4EF8D1DD1D7D85F
-:10643000F0F14D4FC51B808F91242110A05F2C17C8
-:10644000E5C7F2E780F1A05DC0E5A9901CC67EA378
-:10645000233DE50ADC5AA1BF0CD796E073D9284F3B
-:10646000648E7E12E55F122E5E3E78794FB7DE8035
-:106470004022A9FCF9FBA51C94ABC034BA6E875E20
-:106480002FD4911FF9B85F031A81FEC8A6304D06BC
-:106490003D125F114931DE4F0411FB69600FAEA060
-:1064A00068285C56F66F74BD9A169EF22A85CB93C7
-:1064B000EB0F990836B3130697014FBC5103FC92BA
-:1064C000A31201F9D70AC391DB804F49242CD0FBDA
-:1064D0005A301CDA6AF45D9F4A987DC8A1D78B4C6C
-:1064E000BE09F4BF274FC7FE04EC85B5AE31009757
-:1064F0008A707D06F4CE15A70F4CE711A4BD1C8C45
-:10650000593A7A7FD6744EF7BE9BBE0181C9D7FD3A
-:106510004DE7C32695A796E3822881528C17235D09
-:10652000344E97F34A5403BF71CB5745B28FB61F11
-:10653000ADEFDF4F89819FE2B1D94D9DD16FE45D11
-:10654000FA5460A174EFEDBA4BAC4CA4E0A74A91A9
-:10655000E9FD2D773D1C1F0BF47CC5B9DF53568533
-:10656000D12FA5FBBE4AA087F59EB798D927B29F29
-:10657000AE87F657B83F723E6F511649318F75DDC1
-:10658000E382BF90E23995DCDC2771FF6A271BDFCD
-:10659000F277CE17F43FBE859F0B9522395C8A6453
-:1065A000F59152BE188AF7C2A4DF9D876D0F7F94C4
-:1065B000A8157D04EC5E6167395C15D2D3087CBAFE
-:1065C0004B2455A9E05B2B89085F61986E3DA8DEDE
-:1065D0002F3445D04CE45EC9C0FBF9AB6A0F2A9456
-:1065E0002EADA34808CCCC25301EE8D5835EB49FE1
-:1065F0006A2E4978A99E7EADE82B26D865BD908489
-:106600000116BD16F69CF43F6A5F0DFA5CD9183589
-:1066100011AE6004F708878A9621BD5BA87FE76109
-:106620000B71F0538B297602DFC6E9F8E00FC68DB7
-:106630000A94D773416AF9E1E7630ABFB5DFB8147A
-:10664000E242949400E70419E1A423317AEA0C2F82
-:106650002377CF229DD4EEB466EF427930AF242861
-:10666000AF32396C0A6067E48429527863554C1F55
-:1066700028B971C16EC7F690E88376BE91F54EF4E5
-:10668000FF5AFF2CAD4885D76A91E9B7FBB83E3C6D
-:10669000AFB4CF477FA399CA4751DFFE614E876FE2
-:1066A000C7163D381EF519B34BD6F32EC170C43151
-:1066B000475E50713D6EBF661EF76B5A0AA95F8335
-:1066C000F24E16801F93C1F9A305B0479F7BB249D4
-:1066D000C2A47064803F43FD1252CAFC128DFE03B7
-:1066E000FD97BFC2E9CF785C7E4B3A7FE66B42E410
-:1066F00007A8EFA8AA02F8770BF1F9E300DF057409
-:106700003F69F45D7717DF4FCE95B615B550B81ECB
-:10671000CB151DFC309ACBCB63C43C71913E8F17D7
-:106720008A06C01DAF17711DE70CE6B79377BD0E43
-:106730003BD16C2ED2884DFFECE0F2B4AD4173C872
-:10674000ADFBEA57E3D1480ABDA573FA64CC0A63EE
-:10675000FCC31F4A20FD619DA9FCF4074A2BB4FE2F
-:10676000F49F5CA2AE41FC15569C92E15AE6DE2FE6
-:10677000A51ED77D25763F534ADF6FB0D72D144F26
-:106780006F2B0E7FBC53827D9749D0FFF386A8A95B
-:106790000AC0551F0EF07B4354DCE0DA5D5E09F75A
-:1067A0008D59110DE4C8B2CFDE50642BDCCFFA92C4
-:1067B000BC05E8E52D174589D24F934D9263939B15
-:1067C000A970D3C6DF99545DDAF1A145BF52097EA5
-:1067D0002A2914C9580AC7E68F1B343B9DBAE836EC
-:1067E00084ED5B9D7C13AFEF5FCF7E5ABEF8B96836
-:1067F000C5439CF4C21F7B3C84D33949FF3E718D55
-:10680000FF1CF4D638FD0C4ABF4D06D093E90BBAF5
-:10681000F142FF21AE996168C70D43346D7AEC6394
-:106820003107F1205F90512FED5ED312067AE974A3
-:106830000C202DBD8653D9ED2E4145B9A27AE32A0D
-:10684000693A2A6401E29F73A58D48EFC728BD41CC
-:106850008F3D466ABB2EE6F6CABF1655D18FEF6A4A
-:1068600034CB1B8B87A237297CD4AF237B98FF7254
-:1068700089E5BFFC3DE59341F82BE7A9D1E0F6D8C7
-:106880000B7C25775396A670156E6476137CB51C29
-:10689000DA36A8DDEB147AF9D1C3E7514A1387C77A
-:1068A00023BD9DF6E9B1C297050FD8B76266DF54E4
-:1068B000B3330C7A26504CED1341FBB31AF033A2DC
-:1068C000245E0EED91BBE7E13ABE0D7EA81FEC0BF6
-:1068D000417C7C534C349A9466BE70A4539460FF00
-:1068E0004C707F67D1CF3D2FB57A484F5FB6B81750
-:1068F000E814A83D0CCBB4DBBD6A29AFD71E8E28A7
-:10690000E94475EBF617D2FA097F96F87E6C666358
-:1069100098B647C1AFD49FDC293EDE08FBB188277B
-:106920005C8F7477ED239271281EEF5E5B6609958C
-:10693000B1FC37749E3BBB140A00013F40B2C781D3
-:10694000EE04BB44F5CD5A6ED76E2591003C3C4316
-:10695000448CAF9D21470257D8F870A7A4B2795A4A
-:1069600095B7217E6FC5776F8BB3B6A57FEED8ED57
-:106970006CDF4E160D87F8EDED3B155CFF9DAE7D8F
-:106980006B4CD271DC3B486D0BE0A15921E827AC80
-:10699000D5890CF1D80D3FFCCE0CD8277C9BDB951C
-:1069A0000F287F1936FDB3CE9F50613FFB4EC715B0
-:1069B000CBAE26F07EA26504ECCBB3494A3B7A4BC2
-:1069C000AB13BE81E077C34BC8A67EE190DB849415
-:1069D000F1C3A724C11137ACD70293206872DECB74
-:1069E000AE6605D31FE66FBD8926F0132583F7AF8A
-:1069F0009DCCF21CB533E13AD07B3FE3FEE850DF9B
-:106A00003B9CE6BD0D5AB70AFC5F239B9582D81BC1
-:106A1000AFD294DAF04890E303E59D2389A35FEBBE
-:106A200020FB558AFDF473C37B4AD74C71725FB863
-:106A30006F20D1B740EECE8BD16A8C1370B83D80F9
-:106A40006709AE32D213E3274530AFBF55C882384D
-:106A50004A07FA275E4376D0BBC6D203542F41DCE7
-:106A600027A3C4F9DC1D57E949D2B513E50B43A2AE
-:106A7000744901CDDF2981BF58269F4EF6A7F355F3
-:106A8000C3BA266327D42F755CBF5413E3C159D30F
-:106A900050BE305E57377F8C0970D4E51921D30082
-:106AA000351A0AE3182EBEAAB92090846DFF5D2323
-:106AB000F7A8204735547FDBEFDF1364F1E4747AE5
-:106AC0005B219AE12F01BF56443C493A6DDBD6FD6C
-:106AD000515CA86C67FBAAAC25FDEC8BEF09B27882
-:106AE000F1DA2D63B358DCC5A9AFCE72FBF0936722
-:106AF0001E57BB41CF3C7DE27A58E7FAFF29118D42
-:106B0000CE7BF6994CD2897623A182DD58D721A578
-:106B1000B4878434B1FCF9F732915EEB9EF324160E
-:106B2000D0F7D7BDF0CE2442E13BBBA9E7B591E059
-:106B30004F3F2DB0B8B8D93D6931BDBF4E26AB53DC
-:106B4000C55926C86C1F72FA47192B407E85B6833B
-:106B500037E3B8EDCB15B0AB563F4356905F693F76
-:106B6000B4DBE6534262AC900A3E968F38FD94C087
-:106B7000E03BA0E0FE6F5DDB5E354AE1A869FB10FB
-:106B8000F5C5ECEF3D1B003CD41C901C7E5C4D9B7E
-:106B9000D4E99984D713708538AB3003F884F34B6C
-:106BA000C7068CAF56B73FF0A11480F79D7A8BE2F1
-:106BB00025D409787D530A2D80F60FFE316050549C
-:106BC0007D70F88900E0958EBB46CD8238BE93BFBC
-:106BD00061FC0B397DC7A39C8EF9DE9AF62D6C3EC5
-:106BE000975EFC007E29E81B878DC8CE3C3A691B66
-:106BF0005C9E77FDB3E71E35E97CA79FFBFDA326CE
-:106C000085FBAEBFFCFBA35F07B9FC67AF0E7ABD87
-:106C1000E6E95F06888D0FD7C92C7E707614DD42B9
-:106C2000D17E677FE549804370F6A5F7461B74BDAA
-:106C300067BFFFA7E106ED5FF7D2DC7C587FDDF38D
-:106C4000B3F3FBF363804F131E3B5C091CDF38205A
-:106C50003067E1457E75D1E550C7A1D100E7996362
-:106C60001EDC9FD5D07BF553814E1BD0CE427B23BB
-:106C7000C56FF5339B3F04FDD017CFE64811835F06
-:106C8000540D0681CEEFCC437A911EB48FEEFE35C3
-:106C900047291D27A7A7DB39F2B10A7AAEE6992D5D
-:106CA0006C3E17DDCEC02F57F6A5DB6617DDCE9103
-:106CB000BB1E2B80C46BC730471EC1BAF6C6CF239C
-:106CC00059917EF48325FF03E115F32C14AEA572D0
-:106CD000F81B32C8D1731949BA2E00BA3E7B6E3404
-:106CE000A17CF1BED27333D8839E973CFA3E7A7F63
-:106CF000DD4B6FA25C9D7DFE75D5403B46FC02F5E9
-:106D00002BCF92E4CF61F033AB99CF496AF6677627
-:106D10007A02BDF4A94E2CAC340278FF04DE4F3069
-:106D20007EAF4E1C5C22A4A0D7EBF218A6FF13790D
-:106D300088970DFB7FA312BF938E4219D0F1C43CFC
-:106D4000B89F8E8ED6FA7558FF4C1B3DF7333975B8
-:106D5000F7AFA6F208F62E49D784F02649219767A7
-:106D6000F77A64B07767C1AF4A993765FECC50F3C4
-:106D70002B3F939DF557C9FC0AC7437AFE60F23D4D
-:106D8000D0FA868ABF1FC9068EEBC6E3E98F53EBA4
-:106D9000FBF7B8BEA82666E5884BFBFA2132899836
-:106DA000238B7AE13D0D1B54CA7FA79F96301ED4DA
-:106DB000D27E08F5B65B4F54A7896F5E90999F50BD
-:106DC0007DE0E024D067A75FFE11F267F53327541A
-:106DD0008817BFD6F603B5BBB4571EC01E246CF689
-:106DE000E0F4770F4E627A808E9F824E8AC2C6AFE1
-:106DF00079D1397ECD331F3AC65F6FB6A37F30D0CD
-:106E00003C1FC8E1E5B0DE0F0E2B04F4E807ED529D
-:106E1000652ABFF6036E0F2D3CB5BC3EEF379007D9
-:106E20009B76C46780DDECD814CEDF0EFEDA1185C8
-:106E300080DE2672F8F71EDAEE78DD67407EBAE370
-:106E4000C832C9B0ED437FE8C2E7CCA3E6EC4C3AC8
-:106E5000DECCEEC8347051DD7AA3EC38DD57D9F8BA
-:106E6000A0EEF5CA7CD0F7B00F35C6C37CA120ECEC
-:106E700073A5C0BC4A96BF16756F4A7BCDC653FC3E
-:106E8000118C5729BA988C91C1B82349A211E2AB51
-:106E9000C4EF77E727229A3D0FB5E2F041D862E6CA
-:106EA0002E7EB100C60990987E12FD4F12BAD88F7F
-:106EB000FFE5CE4758F84CCA5F9AFC44867E73F0D3
-:106EC00020E93B5EDF3C4C5483F8768B7F6D6B9101
-:106ED0002D0FD312EC938799AB503CB40A2465BCB8
-:106EE00076BC52315FC9C3DD7134D5F39B1426578C
-:106EF000D792EE7BD7009C1196CF99E5C2D79738F1
-:106F0000BEFE79325D3855A1E5E05951FCCE5E12E6
-:106F10008E29F4FEDC553D97BF8CDD793EC71C2FD2
-:106F20005ECC183CFE869AB78B7816DDAE0C226FCD
-:106F3000972E7FDC0B87C9F7E3398E3CC6A1B7EEED
-:106F4000D7BA31CF50DB5A648BFB0DEFF49230E6A9
-:106F5000F10CF40F8777DEF9CDDB20EE9C5B18F2A5
-:106F600092BEE3C817AEC6B89195CF970BC39D10DC
-:106F7000EF9775A35CC279968721BFB0D960F9827B
-:106F8000CDC1FEE37A339468B382F1A86B705C5193
-:106F9000E3F507835CE737160710CF018A67907720
-:106FA000DCFFC0FA8E0B3C6FDE6D4A903F3C918D4A
-:106FB000F982804C4A201E705EF08536613EC19990
-:106FC000374FC7BFDB6513F3E6AD469FBCF97714B7
-:106FD0005BBE414B9337D7FC4B306FAE119BBF5B11
-:106FE000D4DBAF57EE5C7973180BE332DB67435C9D
-:106FF000A6399B38F2E6CD20F85711F29C72F56C59
-:10700000AC3BF3F2E7E6ACD9617B9B1C7F19DB3C20
-:10701000FEF4C7E6739BA07FEE48528B756A7284BC
-:107020002CB5E9C1F71416A7DDA0847FA8D8EB8E94
-:10703000383F58F99F436FBD877C05D73114AFCDDA
-:1070400094AF3CC857A7885DAF5A578B7F9A8DFE87
-:10705000F942BD3005E366C976D044BE0804A3E119
-:10706000708AF7267998DC5BF306CAA81EA5F2A6FB
-:107070001811CC47A93ADDF01A83873F1D5C169F93
-:10708000361B63581D944EB07E2FFD3AA6B13826AC
-:1070900044B8285CBB6EBC3DD49F9F63AD73861221
-:1070A0003E69C77BEE25A9EB77AB55B6EEE6C82A5D
-:1070B000965FAF72E653217D6D8FB34E17A2FFAE80
-:1070C000609C90E553452DC2F323A6151F0F26E3C0
-:1070D000E106D419DE65823E5456B59B025C7359B5
-:1070E0003E25578B7EACD8EC83AC7733B975E5077A
-:1070F000E74AA787845FAB2E6E6B838E7EFA9686F7
-:1071000020B6373718786D6908E37D371D9B8D975A
-:1071100083B7605D9A0FE3B2E9C67FB02184E3C410
-:107120001ACAD8783C6F4E486613F0952A5AF23244
-:107130000CDB7E893F370B9A40FEB60BECF9352D00
-:1071400097A2BC59FCB3C3E83F2E2D2566201F0C27
-:1071500075FCBEFCFA135C67F32C3FEAD781E42888
-:10716000AB93CD3BD87994A4BD60F3EC98A5E13CFA
-:107170003B72079827CEE619187E86AF6D074F61E0
-:107180001D8242F9015494A28753D7E97179EB3BF0
-:107190008E07F57C7390D585A9C5FE3028FF6683E0
-:1071A000E71B0B59BE512D195E01F7D5D065582745
-:1071B000AE96FA319FA7160FBF05DADB0E6ED12B04
-:1071C000C07E148A21AF0176BB9BC8B9283618BF90
-:1071D000558B4B6E83FE3AC83185639487EDB7D4E7
-:1071E000E2ABEE80F70F4E79CD68A2FD9B0B7D21BF
-:1071F0000FC85BB7ECE0FF41EB8942671E8DC854B6
-:107200005F50FDB56DCAED25289F9AAD4E3245BD44
-:10721000A04D6F6C506D7A4325734CC0433ABD430B
-:10722000EDEF7D6A5EDF71ACF73728917A15F54294
-:107230008438EBDD53E7B32D7A809B05F948399804
-:10724000ACD35B5030BC37BF6DD5E9B9F3DA71FA16
-:107250002F555EDB5D7FFE59D5E9ED5493757AA31A
-:10726000A04EEFC70A0975425EFE9752689FD197FC
-:10727000EFDCE3B9CF5B50FF47837D4E3AB9FC9911
-:10728000EACC9F16445D74BFD5EB98EF159097D26A
-:1072900081F5CBC82AE738A36A9D75B597D4E7383E
-:1072A000DA45E60847FF4B5BC7389E8F8D5FE6786F
-:1072B0003E7EF754477B42E22A47FFCBDB2A1CED98
-:1072C00089EDD739FA4F3EB0C8D19ED2B9D2D1FF9D
-:1072D0008AAEB58EE7D30FAF733C9F79EC1E47FBA8
-:1072E000CAEEAF39FAD753774805B9CDE575C8B9B5
-:1072F000F9A23D4FDB9A47ED12DDE7EFC8A30C83FF
-:10730000F16F56D7A5B2C7C9BCA1FB3DD950C33A4E
-:10731000E6FDC7CD812B91EBD09ECAC6F00A03EFE4
-:10732000CF98075732CD595FAB1AAC3E19F671CEE4
-:107330007A01679DB12A6DC33C9DE7F897BB8449EC
-:107340007DE9AA163AE560B075CA8AE17A6F88725B
-:1073500071DE928B51542E30FEF6B184E75AE6640A
-:10736000A27F61DB4F211EADFDD4351A89818B6967
-:10737000C945F9AA9E91AF62376B1FE51187521775
-:1073800067C95FC0A6F761BF62E999E6B2C1E95774
-:10739000297185C39F745F9B02EBD2E9C7028FCD31
-:1073A000BF77EBC7194AA4109E6B72D824B6780D2C
-:1073B000A9551C700F16CE4F6A07EEA20C4752E873
-:1073C0007195D462DD55CB8A300601481D71F0E914
-:1073D000CEC5FFA30CC6A57EE10CE73A995FE8F69F
-:1073E000A7A97E437F7A07F5A7D1DEB9F423D55349
-:1073F00026AFFF32981FC1F4A17B9D9F971FFD6FA1
-:10740000E0ACF643AF4051A812F787792281FD61C5
-:10741000F3AC4810E27356DDBCF55EABE7521C27B7
-:1074200096AB8A10BF8C75CDC5787D9316D5589EC6
-:10743000388AE334658B7AAA3AB13A0FCB176BF5E9
-:107440000F8CDDDF4FDC45534934553C6DA787E594
-:107450008362FADA2EB0A39979AA017BEED683A7CC
-:1074600022104792CB641DF6EB8402F38E2DBF47AA
-:107470004814E34C5A5044BBABD5EFC0F90782F730
-:10748000668FC0CF7D6CE9175EAF9A3AEE920EDE42
-:107490002D00EFB481E1F502BC4530FF369CBFC63C
-:1074A00063A4C4BF42C295B3816E27BE1CC1742BB6
-:1074B000651B908F1D656C5F4E0D8183BFAD7D0E8A
-:1074C000E5EF873D7958BF8A7C6D9D73B8D1A3E302
-:1074D0003C165D49610EC63502D1D8D862CA6F9993
-:1074E00051B69FEFD54F8C8F329530817896EC173F
-:1074F000313FA8F27888D5EF0F1C9F4DB3BA915E4B
-:107500009BAF94C926A1B7CE3A5648D735B9775D17
-:10751000FFC793CDF893CFEB234BB2B02E457A261D
-:10752000D89FDEF6717CB9F5F7F73C5C7F179002C7
-:10753000A6BF4B9743BE3BDD386E3FA69EC77987FB
-:107540005E5FCFCF17F8EFE982389315E723C16963
-:1075500029E3F2BD7865F9CA5EFA2E373A29FDE4CF
-:10756000E953314F6E9D57A0EACC592FCCE96BD12E
-:10757000D58AA393208B1F5974F626F1B9A75F7C97
-:107580007A415EAEE88BCF5F7978BEE1BF183E5F8F
-:10759000019F865E3333D9F97472E8AB04F35285E8
-:1075A0004E39B4DEB3F8DDBDFE3FFD17E5276BFDB8
-:1075B000163FA4EF6FA6DCD758F9D54CCE6F1A9CB6
-:1075C000B2A28AE7D5B2B75B2F85FD6BD08FFBBE29
-:1075D000CCB2189EEF5588A9835EC8B4F635FCBCC2
-:1075E0009155AFE42B75FA659A6BFFA2F2BAA83EEB
-:1075F000E76DB9FFE63E4795C4AF8B5E93B534F9AE
-:10760000B1419E3FDAC5F3750575F146D80F17DC19
-:10761000CAEAFDF7286435D4578EA832455F2EE4B8
-:107620006F8ABE9F41D75FF0E2438D238124B71A52
-:1076300045E0663CA3190E3B5C7057BCDCC79E4F0F
-:1076400081719ED298DE2DA88CE339E7A6E7C76743
-:10765000819FF0CA5BCB75880F7C945B8CFBA73352
-:107660002F78C2A0FFCFE4902AAC0B7B61E66BE0E1
-:10767000C7FFBEA12B47B6F1C999EFBE3E43A14457
-:107680003AF3DCEB33642456C231FF868BBF98019A
-:10769000709B15A4A416F277BA4A60DC1A8DE5CB6C
-:1076A000AC7A9F5DC3D516B8FED49BCDE289F9E2D2
-:1076B0000E68D743400CFC061ECFBFFAB4B11CEADB
-:1076C0002FB3BB1401EAF11E124CD34FAFE74F3C6E
-:1076D00024809FA576D6429885DE0F1D02949B6379
-:1076E000D9BEE47C112929A27ADF77B8763CFAD397
-:1076F000AE7A278BFFE5D904F37D3D376A09B0D711
-:10770000DB65E31BABC07EAF92B11E67BB7C18E5A7
-:10771000C24DC7E3DE31CEFA5C1E8F3EF4D61DF1BA
-:1077200072FAFE3D5344E457FF8929592485FC6EC3
-:107730006F28C3F903056F579603581FD3BB337ADD
-:10774000F7497E999859D4442A45A2A950BCF8CB50
-:107750000879DBC6772D2209EBF4F90B0D04C7E994
-:1077600068D0F0DAD6A08F2DA61B836F3504F1BA4E
-:10777000B3C1C0EBC30D25F8FCC1869043EE61BEDA
-:10778000B74B783B85BFF2795D1F68A0F3DAE0D88C
-:1077900035914A3DA5D72E9E8F7AA0746AD6DA7E9F
-:1077A000E2607B1ABA86CD19CB9105F5A675FADE93
-:1077B000ADFDC0BFA75158BD08FC9ABBE5C83ED47B
-:1077C0008FD1824536FD48FDB6024259F1DE961151
-:1077D00073E614A03CA2BC4C3B1C457FBC20181790
-:1077E000208E587094DDB7CE5B20BDA8A0FD307709
-:1077F0008EA080DE2C25ED00965A1A2515B4FFCCFC
-:10780000BC25E5709F4C74DE9FA132F986712BE890
-:1078100075B616F991361DBED3B1DB7C96AEE78FF7
-:107820001D1E03F23C0FBEFC2715F605B15FA91A19
-:10783000F831052F9EC0BA8798D0AD4265EC71AD86
-:107840007A8E4CF50C6E0631BE4A150BE59318E89E
-:10785000588C7FF6C4E6F8E1BC4BF494BDFF2E5F74
-:10786000F46E7E7224AC05291F25F317EB6361BA11
-:10787000E97C81E72F8E6BEB626621B469FF29AC4E
-:107880001DA3EFBF901D1D296643D14555ACEB4BA1
-:10789000D0B6FA57C5A0DEF64DAE77883F5A04F24F
-:1078A000966CEBB49D696BCBAC4D3476B5D6BBE131
-:1078B000D09F5E033D57FDA2D00EA051BDC7F07F03
-:1078C000E021ACBB6D6BE8D2630AA7BF45072A92E3
-:1078D000138204EBE9D484901843F5C704FE7D8A33
-:1078E000826961A311F46B420981DE0CF998DF38DB
-:1078F0002141C7B1C9D58434DF41C1BC2FD0711B30
-:10790000AB1B76F3D7B35E961FA827E656C88391C4
-:1079100067141DF3913C4E79DAB2737CBF7A979766
-:1079200035954DA6EF32D03F6B648C83AD2F8A978F
-:10793000AB749EF53F2A0A51CB0A7925AC6B589F50
-:10794000DD3E7C2ACB4B39DA0FF13ADA60B6990D7D
-:10795000E707AA0F3C341AEA02AA49FCE6AF01BCC9
-:10796000FFCAF28FA70E5E9975356D6FA06D88BF47
-:107970006EE8785D8DD27EC338DCD51D53AE83F5BD
-:10798000556F138958C4E4333C9EE2391CBF4CA6A2
-:107990007C72CDD69173BD94CE4F8D09EB22E583D9
-:1079A00095BE71CD1AB4557D02C8CD4ADFC466E0DC
-:1079B000ABF513F9F71AC8C457C332AF97A27C319D
-:1079C0006C4B430CEA13F6AFACBC0ECCEC7091C917
-:1079D0002D6544CC1F4AD931CC5BFCA1999D7781A0
-:1079E00094FE464A87629974C9F4BA4B65F4335BD6
-:1079F000648C17D3FBADCA54A04B3C8CE72B5A992F
-:107A0000DE1FFBA207E3CEC5B5E13BD12FD04B7102
-:107A10009F329A247F302F7D09FC46C719AF93729D
-:107A20003887F0632F8B1716AF58B61EDE93329748
-:107A3000F8705F2EB17350E4DB2C4EBD4B4CB46B31
-:107A400020E78162A4EFAE00E30BF3E152E48BFD8B
-:107A500062C56577435C5258B3F55F80AED9C50403
-:107A6000E80AF7EFA1F7F7737A4AD9211DE8B79F23
-:107A7000D33396104DA88FB1EEBF20ACBD13E46D8B
-:107A80009DF7F9391AC5EB704F383E8CD2E14EEFB5
-:107A9000F3B16001D2618C46F17EE7968E98368A0A
-:107AA0008ED3181EA1DBDAE3FF4CBD11CC4F76A0BC
-:107AB0003CCBD90FAF0379A7CF5FD1E83A9FCAE19A
-:107AC000FA823F2F1E93D41F61426D8DD4D8AB4FE5
-:107AD000346A1F8A6DFDE7507DF0E4A3AC8EFD7A19
-:107AE0003A1FC83B5D07E67F7B26C809A8CFF25145
-:107AF00058C06FF14D1C83F57974DD04FC929E89AA
-:107B000032DA592B8EED9920627C09FA033FF84650
-:107B1000B1FE545022A037E54219F7ABB2B4273C6E
-:107B2000C180F031CBEB0AFA423CB7EA2DB1E571E6
-:107B3000496F1D30B68BF033378EF6584F7781483A
-:107B4000FDCADCE30B85D174BC3BBCDCDFCEA5FEFB
-:107B500036BDBFDECBF4D2FD11F3CB10E220467769
-:107B600001EA2712990AD7FC9B8AF3A3FDD8A5BE88
-:107B70007E7537FA0F3BFCA9CF694EF7B1FD7C93B8
-:107B8000FF880EFC564FA8FC835CE88CDF2CFD615F
-:107B90009D4F70D7135BFA44C9666BAC9B5F910F26
-:107BA0007A40E6F549B21ED2A1BEB23C731AFA7D04
-:107BB0004F7A99DE930E5E79039CD350FF95E5854D
-:107BC000F678A3184FEA2920EDC0AF72304CECF9DB
-:107BD0005F4B1FB43468787D62EAB80A909327A699
-:107BE0000EAFD0A90C1C9AF4E32EC8339DDBC3E47E
-:107BF000F7DCE1DBF0FCE33993C59B80AD302ED997
-:107C0000F9089ED77D5C8E3C8875B5501F4141DADE
-:107C100096EDACDF2AE67831B97E6A56D8F3CD0D01
-:107C20002C7EAC5EB81CE35A2AD7E39EE8AD786E92
-:107C3000C3436D199CAFD48869B2EF1D303C688591
-:107C4000CEEF61A81726E1FBA697C58FAC7A117716
-:107C50005D8805CF0C0E4FDF73194E7A58FB2F8BC2
-:107C60000ED6FB7542385FEF876F6A2E4824618B12
-:107C70007FF4D677AB78FF2CD4C567411D4F347E97
-:107C80007511C84102F7475E7F1D21FCFB4AC8A75A
-:107C900041B9C75E879EE1AA8BEF232F86B3EDAE75
-:107CA0008B580FCCC1EBF8B09E5526DF1428BDCF02
-:107CB00064FC7606F8B535543D681020924D1DE6FB
-:107CC0003FCBFD7DF9C5BBC3230D1B9F0B86639F77
-:107CD000507D6021C6116AF6FBB1DEBF1AF4DF6485
-:107CE00038376076791CE705C29D509FA71C60E37A
-:107CF0003D09F0D0FB7FD4AB0A60DDC761FF93077D
-:107D0000F6242AB1432F87110F316FF818D1993E0D
-:107D100093294FC4B22D7D561D830DC32E9538FC7B
-:107D2000A55D3EDEF655C762A5BDF51FC7B5FF8749
-:107D3000FACDAAEF38AEFD07FA43BBD47827E83B6B
-:107D4000F3058F01F68BBE8FE777CD952568076227
-:107D5000456404E0E1956C15F55CEC79CF3ED07399
-:107D6000B3B5E89B9A6DDF7026FB8DD1B0FF4A3129
-:107D70009EE9186FD4D0C6A3F377005EADE7AF6479
-:107D8000EFC2738BF43D03F386858747AFA1EDE126
-:107D90002F78F0DC90B5DF74F3653E97AF16D77996
-:107DA0004015E4CD0FFAB616E5CC1374E6C12CB934
-:107DB000532F4C70E4039E043B4BE9A7CA51085172
-:107DC000D2E7A5F8DCE47CD6C2EB11D2CF93936660
-:107DD0009E2B509ED3CF3383CB3BE1722CEBC9EF6C
-:107DE000C2F4736ED09D2771EB29EB6AE9A96F711C
-:107DF000FE9449F40A1F9D675DA27D9E0FDF8E4EA3
-:107E0000023FF8038D9D832A697BE86530CFDFF45C
-:107E100084EFF74EC7735FFFE4CD1BBA3CACF4119F
-:107E20005E97D9470F31FFEA56E6AFD6CD9F8AFE5F
-:107E30005DDDF631BAFD9CA2FB5A7521C3A1878690
-:107E4000790DFEBD3D13F551D585003EFFECE6F3FF
-:107E50003ACEAFF49DCF8FCFADF9EE72E9D943930F
-:107E60007EBA0BCEB9D77D5F113DB679EABECFEBB6
-:107E7000FFBD54EF3AE53D0CF22E1791647D17E8F3
-:107E8000876DAAD50E37CF99057EAD4D3F9481FF02
-:107E9000D5FB3E7CE76E9B8FF7372B53F7CF70F502
-:107EA0001F638DBF10FBBBE149EA1FD88FD1FEF2E3
-:107EB0009F3D167CA8BF1E125DE3E558F3DF88E303
-:107EC000597EF7456DEDABA60C7C1A2F87FD53CF7D
-:107ED0006DC480EF4F3C2E877C213BDF6A8C5FAB0B
-:107EE0002E5CEAA0772FDEC739EEBFD71074D4EB33
-:107EF000DE11ADC33AED8B3CFE54453D737C6FCF34
-:107F000048479DEEDFE0F8A4705C9D068E6BBE6076
-:107F1000388A1CF2D90B47B1E3FE278563A1C6F46A
-:107F2000D7727E9DABB373B3730D21D4446FCDA5CF
-:107F3000F7BD94D7BF4CAF1ABDCE9589E9C7EFA264
-:107F400026587FDA86FDFD0D7FBEF7DD6B315115BA
-:107F500074D41548BCCEDBAD77E09C37AB77D31C2F
-:107F6000DF87B3AE3E89D56BBAEF7FE86378F9C699
-:107F7000E5D504FC69EAABA73CB7B6CB2FF0EF7DA3
-:107F80000645479C9BB7AD3ADFCF0A2E3983CDF724
-:107F90008DCBAF2710D79573537FDFEEA09FC1DF46
-:107FA000A285B14E3CA6F7FF5D9A4F0ACFF0243C64
-:107FB000D7209EA43478AAB5E0D1595EB025F8F94F
-:107FC000C0539261D1AD7FFC6CE570930B97201F7D
-:107FD000499C4E2DB07F4BD1DFCA7FB4689F2FFCE8
-:107FE000E141D2F7B98C2F86BE8B0649DF622E079E
-:107FF0002DFAE70BCFAD8384E73A8BDF8261A4D7FC
-:10800000E705CF570609CF318B5EC6E78B9FD62495
-:10801000FFF70FCF5F38DCF9192C0ED252C2CE9386
-:10802000F8A4C88345C2C072E12B76EEB3B5429F77
-:10803000B3CEE65D67DD57BA75FE9AAF339D3CADB2
-:1080400054127940BF630D2C1EF006DF9FFCBAAAC4
-:108050002913E3F3AE795A82FB32FB8BDBFCF72A60
-:10806000E7B9DC81E4785206CBFFDC1875BEB77C3B
-:108070004586AB8ECCC47E16FED28DF7D782B73044
-:1080800024310781378AAFACA27EF60D9F35BED270
-:10809000C9DD50F115D38786AF81E4FD2B43C4972A
-:1080A00025AF7FADF8CA077C4DFF1B7F0D165F8B98
-:1080B000FE268F43C2D7AD439547EED7FEB5E26BA0
-:1080C000B0F2E8DEB7D1FD5DA8BFEF0B7CD6F87348
-:1080D000CFFF69F1688DB732CD3E2F1D3E0782C3B9
-:1080E000BA7EE81B245EDDFBCF2F1AAFAEF93F3519
-:1080F0005EF97843C6EB007058577990F26DF975C8
-:108100006D6AEAEF888ECB64DF711B2FD41E990F46
-:10811000F9E3BF93303F7D64CF9C0DF67AA071994F
-:10812000CCDF3E52397B03C44FCF4532B0F6ECA8CA
-:1081300018FAF934C82B2F62EFB9C73FC2F1E5C96D
-:10814000CCB6E2BF7940D7A391C5FDCA23A9B4AD8F
-:108150000BF34636FA4A7DF17D8418DBA7411E6297
-:10816000416A382C3AA79B77A8F43D1A797C48FAE3
-:1081700067A0F5FE877FCC20F54F02FBE592E4DF98
-:10818000DDB90CF0D926B27AB8E370AB00BEEB468D
-:10819000B0D3F215F97B814E7767B2FC61876A6CC8
-:1081A00080FC8967F182073229DD8E2ECD16ECE73F
-:1081B0002FE764B2FDD78C55A9F75D0B391FF4BECC
-:1081C0002F90F129F83BCCFB2D5DC5BE3F46E4F076
-:1081D000A845B673A7EB5DCFFBD0233380701C4D51
-:1081E00073EE7F017F7FF992FEDF27B5ECFB3E94B3
-:1081F000EF46D9CFBD26F98CCBC7197F746926BD50
-:10820000BE2144BF731FF0D1043F3B37249322A803
-:10821000BFB2C6C99549A74AF1FEAE628C82BC6660
-:108220008A716ECE9C9E7E9C7478B5D663CD03A277
-:1082300008DFE999ABB138E2B43021B3207EE80918
-:10824000DDCDF2878C0F72781DE2CCDA8C4423EC02
-:108250007B65BA4E1BBC1DFF77F67F83E71D474445
-:108260001DCFB7BBF030907E68CA64F9E45C29BAD0
-:10827000C90B7993D542CAEFD86DCC647FEF6852B1
-:1082800066B25E0AE719B733AAC0F72F96C92CFF6A
-:10829000454874D442DBFC9338BFB9DFCB9558BD59
-:1082A000117993C973DBBE75A352C9CF2FB89C4E09
-:1082B000CA2C71D4392E89DCAD807C2E59B0503156
-:1082C000FCF0DCC0F1977238DAD4E8A829FE5E3CF5
-:1082D000A5D5431C3F1DC7A24DF0DD8FD5F502D6B5
-:1082E00009946E647CB77AE3417103BDEEE5F2B7A1
-:1082F0001068601BEFBB9CAE6DFB7CA301FEB664F7
-:10830000FE860E4CE1B87937C17CC893DB4FB7408D
-:108310003EA45B203C7F726325D43574F3FAB69794
-:10832000E9F346C0DF9C3C94EF711B3FAC03FDDCDE
-:10833000A1123C2FF3BB2D9E049C27B0F825A92742
-:10834000369E6F80FAE147D4CE89C037794DB5F7B4
-:10835000A5CA9FBEC4E9F0477F242B951F685D2DF9
-:108360007D6EF55B241B4AAAFE8B2B5D768DC33D8B
-:10837000CCD37986A4C86326F930D1BF9FF64BAE23
-:10838000C77FE1CAF32E39963ACEF82BCEBF6D895E
-:108390008AF568B74C0F9E43B1E0B1F0956B323C63
-:1083A0002D5B2239F4EDEA05192EBF87E1F5068F22
-:1083B000F128ACE3917D3F9D88E7A85CF6C1274595
-:1083C00055787E07E954404FBC2F19787DA3C1F939
-:1083D000775EDE20D1EDD3C17ED64B29E5EA8F9CB6
-:1083E0007FDE5871CB52843F26E900FF8955C3AE2A
-:1083F0002F03FDB24209C177D34FC4EECDBCCDB639
-:10840000FEA45FE382EBD755B7F46BB796AF70D29B
-:10841000AD4D657E81791D93C33B298FCE42FEEA27
-:10842000DE3E93CE7F249133652BEB4EE0EF4C2D57
-:10843000E6BFBF2F4677CCA4FAE694C8F224E657ED
-:1084400098DE58B233D20CA9D353F557BCD44DFBA8
-:1084500079038CEF7E5BDFBF7D74F3D3B89D4E7FD5
-:108460006FC631A2C2FBD1BAD4F6E0DB7A06FF7B3D
-:1084700062A1D1A05F6EDA98BADFFF0266A6F09C17
-:10848000FA8B54952A3E7995CEE05D1D49FDFE5547
-:108490007A267B0E7629059ECF0532B89ED3478378
-:1084A0009E5E9D06DE0F030184F79DE6FB6F823A18
-:1084B00090F75DDF817F27C0F8E26080F1F7A97D4A
-:1084C0002B953CA0538BA0033FBC9D1D9A00FCB68E
-:1084D000267602CFBB1CE0787ED3179912980EF255
-:1084E000B2686E1EA54BC72A12128CF4FAFFCA009E
-:1084F000F31B7279BC96DABF77C1FED157DF45FF17
-:10850000430E8FBE71222B81823AF053A2B90EEB3B
-:108510000CF7F9585D29094DB7FBF15FE6709CDA5D
-:108520003F347A2F8DB8FCA03EFE5FBC1AE7DD9F7A
-:10853000A1435DCA914AA9F35A0AE4C9FD19F87D1D
-:108540005CB75CA49B7FA87EE0A9FD43F303075AB8
-:10855000F78640D1A0FCC073958FEC980672A4C634
-:1085600027A5D2BF969E3ECAE3EF6EFEB1AE5FE591
-:108570007CF47EA27FB8EED8ED84E7A65A273C961D
-:10858000BCBC9F68F2AD013C91CE8976BF94CC997A
-:108590003E809D65F9A974706E77E909E03CA0C33F
-:1085A0009D5CDFFCB6FE91809D0EEEF59F12F9FEFC
-:1085B000E05156973B36B2A622CFE8E5CF6F7D4E0D
-:1085C0007C69D919F738FFD9F9D0B27303F1616E1C
-:1085D0009A3CCE2438E84CDF5F23EB2AE4EB2705F6
-:1085E0000CD626FA3C38AA45CA78DD283146C3F9AC
-:1085F000AF53FB7CF8F7A1CCAD9EC4582A02EFEF35
-:10860000BB7A827D3DBFE27CBA7A49367E7EE27DCE
-:1086100031343F1FEBCE24FC8EDB1BC772E641FBDF
-:1086200091C32268687253DD1A09D6F74680ED3B84
-:10863000576F7C1DFDC1A1F2F9EA5AA7FDBF8AAFB1
-:1086400023E967C93DD3807FD2E1E1358E87A591CB
-:108650008573413FDFB251407DFB1318872EE4162E
-:10866000398C7A9BC4987D241AC50735212760115F
-:10867000808F7FE0DFAD9223AAFD9CDC6DDBEE9F57
-:108680000BFEA15B5E5664313EAEC86276E14D5F83
-:10869000F40FA0EF2DFDFCB6507B309F76D918D09B
-:1086A000ADEF04A39C5AEBD9C8E1A27EDAB3F8FD82
-:1086B00062BE3ED2E3E237315EFD63C07F85867ED7
-:1086C00081CF43F53ED4453FEEC33A2A4BAE2C7FD3
-:1086D000C7FDFE3239EAF01B33B38A1CFEBBDB0F49
-:1086E000F99BBD48DDFF8AAC2FD65E5C9BF5D9D8DF
-:1086F0008B619CCFDC762329D72DEC3CC889631F86
-:10870000CD4D25D7914F08875B9EDFDFE763DF4DB7
-:10871000BE2613F54EEF7E2A3F01FB65B75CC07E97
-:108720000ABEFBF1C8BE9F4D84BADE13DBEFBF2942
-:10873000153D67E9CC6F22DDF98E78DEDA00C1FAEB
-:108740006F42E77BC236BEF55E525E06885F2E5BE7
-:108750007925EE27DF5879F5E835A57DF7157DFAFF
-:108760000BD17F580AF336F2FDF40E4FD5BE54FB01
-:10877000408ED7BE7162A77FBF746379336CA9370F
-:10878000655CF3A5688AF993FB9A8DA9E3710F7272
-:108790003D95DCD798745F43F1D1BD4A0A944DEB07
-:1087A000DDD7749B9FCFBEE677A4E7E73351FE5336
-:1087B000C3F73D8BBFD4E88E2B297CA7E8FEC70406
-:1087C000F911E97BC02FDF4ABD5F7B9CBFF7BB8DF2
-:1087D00043D457C79CFB9974F2F7BDCF48FEDAD457
-:1087E0009E51A0077EB7F7E3B7EE87F5ECF521BE03
-:1087F000DDE3447489EF2F7CC8B7967DEE5099FE77
-:10880000FFDDDF8DC0BF9BED960F42E2D75F459F36
-:108810001FDF274E81EF2CB6EDCBA84AB5CF59AF5D
-:108820000B3CBEE48CF710EEDF2DE5FCA6EF7BBA27
-:10883000D61E8F7E93EB2B2B0EF0BFB3989D5DB2AF
-:1088400060A10AF19EDB92F126829B15FDB2C2BDAA
-:10885000F0FD8B5FF2F35CE6DACC94E7E37EC3F1E4
-:108860003B501C62C52A679C60C982FEEDCDC9449D
-:10887000EABA2C8B9FD3CD3754FBD296185A5E6C34
-:10888000A0758ED007675F9692DA2F41BC631909F5
-:1088900029705D426A27FE98A2F2E4EEC508CF2F48
-:1088A000ADBF7FFCF1BD13ED7ECCFF0710F667274F
-:1088B00000800000000000001F8B08000000000086
-:1088C000000BDD7D0B7854459670DDBEFD4AD24924
-:1088D0003A9DEEBC091D020818620742001FD02114
-:1088E0004482B2DA810041519A87184948A2E2CA0B
-:1088F000FEBA438720467466C2AA8CBFE3B80D82D5
-:10890000EB286AA2D1418CD8A0F8D8D59DA0AE8B17
-:10891000B3E846C7415E4322A32BB3CB0CFF39A774
-:10892000AAD2F7DE744370C7FDF6FBE338D7BAB7B7
-:108930009EE77D4E9DAAB63915C63C8C7D5B73FBC8
-:108940005F4D628CFDABB579BCD3C1D859FC9B1E81
-:108950007DFECB3AC6221731F6E13A3B8BD8A01CFC
-:1089600036558563D4FB53AA8931E8E85FE1C14AF3
-:10897000190B2D50C33B94C1F5B2705CACB7785E57
-:108980006A30463FF2B9A04665113BA3BFB3F06F12
-:10899000CD9C245DF922A753F4D39A182C62EC885D
-:1089A0001CF7513EEE91307F2FFBBB488C7B247C23
-:1089B000EE716F7E04C61D131DE78666FDB8BD2CE3
-:1089C000B48AB9619C70A2734701C3FF8CD8264456
-:1089D000DBEF759A08AEEC48A689653076876C1B8C
-:1089E00067BC0F057C8DF56BCC7E8B161FB7A77A05
-:1089F00069FEB25C33473F4F6F8A938FCB9CF981FE
-:108A000064C68E6E4BF4133CA6258747C13C2BED04
-:108A10002CE480793EF8E4C59FB1118C2D13F8AF9A
-:108A2000097C6D41781C35F5DF938CEBFAC0E4DCF2
-:108A30000143951DF45BB4F0BB2B85C3EFE8F673DF
-:108A4000C3EFAE143ECF7955FAF9CD3F98A82B1B52
-:108A5000D7FBEF7F7BEF04ECF7DFFFF63B8BB6FF36
-:108A600005A77359243D5A5E52ABF8C34583C77DB1
-:108A700029D53A24B8BF6480E392D3F9D4BF5B65AB
-:108A8000CD1D31D655EEB453FDF981728B07E0B997
-:108A9000FC6EC5A74017339CBC9FE566E6EF80F9E6
-:108AA00030B337BF1AE0EE696DBE2310A39FFF23DA
-:108AB000E0FD8D23901A8BCFE4F363410FB2DE0209
-:108AC00073D012ABFEC25A3D7C7B19AB8A35FF1FB7
-:108AD0003B395F0E951EE5F8C6FA439DC7DD820E51
-:108AE000D36D91DF33155E9C807ECA2E605C437D22
-:108AF000E3B8F73BF5F8338E7FF4CF6A5D2C38BCD2
-:108B000026F83F1800FA89F93D99BE7FC0DA1B7735
-:108B1000137F27F9762018B62FFF09A09DAD9C7D05
-:108B2000C75BF09A25A614D0FA16070E5412BB9D07
-:108B300079B018F1FE6DD5833F2985A91DB5065B77
-:108B400093A1C1D1F58A2FE41D3CCE07B84E90A366
-:108B50001FA13CBD08FB639C6E67C2FF65333646B0
-:108B6000F5D7A3506177D9BC3B347CEB5EFBDD3A93
-:108B700056CCD853D6C0FA64783FFAEEAFD73094CB
-:108B8000792C4CF3FEC2E2BB85E0CD18F1FDA16D5E
-:108B90008EAD9BA05E6A0A97938CF9F203E335725F
-:108BA000C2ECA4F250F1F3611CFC5CA89C92EB8C2B
-:108BB000370E409EE6377786A34D4965ACCBEABDBC
-:108BC00009D7D33F3BC1B90D5038D7EABF1AE1F3FB
-:108BD000C10193A9A580BA35239DCEE343B0826B32
-:108BE0000AEE1F578AF2C7E24F80A954431B36157D
-:108BF000E868862384FD957E38E719C4CF83B536AF
-:108C0000AF8AFD4DF37EAA4279EE5536EF7AE8AF92
-:108C1000AC67C45E37F43F7F8EE264D07EE6EC51F1
-:108C20009E5E585FD25AE8270747B8B7AAC2CCD889
-:108C3000D3F89F97323E6180C55C45965F6C9B0977
-:108C4000F2609CA7CBE40050AF4C7BB1CD0EFDDEB3
-:108C5000D312C872A6C1D236DFD7661FC658468661
-:108C6000BF67BA8FB1D99BEFAFB25F01EB7C54B451
-:108C70000F3DD0E6CF63EC5553B04081EFCD9B77ED
-:108C80005499015EEE4239FE2B6DFECB613D57DDFE
-:108C9000B2630DF4BF25ED9FAACC38EFC572FC9EE0
-:108CA000AA8A9130FFCB65F95FEC385F77926C0F41
-:108CB000F39DC298654474FEE62C18DF25CB9F54C3
-:108CC000CD84F13F2E6FAE30C3F8C7D2FEBDAD6884
-:108CD0002C6393E7943BFD50EEDBFC1F5549809FCE
-:108CE0002E06740AE53F6C3E4DF377AB26DE7FE837
-:108CF0008F34BFB2C5A171F85D617F6AAB8275AF79
-:108D0000B6F7BE85E4DAB43664CF4091A4703AB1C8
-:108D10005B9AFDB9003BCBAEF2482E4DA79DD36BBD
-:108D20005E643CEAB181F218288FD794B378B96BAE
-:108D30003D5B124BDE76BAB81EEE4A8CFDBD228D2D
-:108D4000CB03801BE993D483CCBF33865E1997E6AF
-:108D5000A07EF627B290DD15E5B76B8187A7005F8F
-:108D6000323B9FA7EC6790FE48E3729F85AE75216A
-:108D7000DFCCC12E60E9853E258474CD9A93C2A3D1
-:108D8000907658C43C0FF5876AA2F97A5465493544
-:108D9000F49791C8829DF0F4A4332A437B7FA723E4
-:108DA000DADF7B82EE2B0B03DBB1BFCACCEC92D6B1
-:108DB00082683F30EF0DF609BA799BA7B8F0FBDC6B
-:108DC000925B8B34F02CE2EB003AA07630CC33D3BC
-:108DD000810FBA7AC68DD804F3FB06E5AE27BAAE8A
-:108DE000B29EB91606F5B6B8843CF1F2F69E0A2E8C
-:108DF0007FFA6F4D0A6F43FEB4FB4A104FB2DD0D90
-:108E000002EE15F7CEF919D66BE8B1301BD45BD35F
-:108E1000599EC9CEA1171B4E5FC6C213356573C4D8
-:108E20008A72A7E1F4347A5F71EF7B56E453ECC7A2
-:108E30000BEB5A93E0CFF421DC5A63E39FB1169A0F
-:108E400047C3E934169AA87DCFE114EDDF4DDFCF9B
-:108E5000B7AE687F2A0BA79FAB3F2B7D1F80BB5906
-:108E6000C0DD1A7B9E1B04FD20BC4D1AFA9A2FE828
-:108E70000DA49F1FE5E1A16B8AB6A1BC8F8EBB9E9E
-:108E8000FAEF32031ED10EEC49F4A25D5C66E6F205
-:108E9000B3ACC7E50C2951FA907421F1DAE56A2EDA
-:108EA000A7F5562BCE6D0583E775BF9C97D0A79984
-:108EB0008B83EA52CDFC243F40FF5DA2FFD229C440
-:108EC0003FBFE0F4027C7303F22FDA2DB80E5F642B
-:108ED000FCDCE4C1F33F0DE4854FC02387FF5F391D
-:108EE000C2A80724DC06C33FF73CF8CCA7EF653DDA
-:108EF000FBACB8CE86387CFB802B85DA651E8CA453
-:108F000078A1DE19617774754C4CB80CF9628E89C2
-:108F1000A108C375A3BD5A36206FAF7C7706C8DBA6
-:108F2000CC8132C85B2FE26140FE46ECF668FD1F43
-:108F3000B9AE9CBD01E4B5DB06F82F223BD4CE349C
-:108F4000FEC4EE346EBF4D09B29876CBDFB9927590
-:108F500072ECFFAEAD60BF85F599D3B8DE9FD21B32
-:108F600052102F92AF8D72EA13C18F1F8BE7FFBC97
-:108F70009C52CE23A7AA859CE2EFF783998FF53206
-:108F80003222E315D089CBDE9D380AFD99DBB2543D
-:108F9000EF97C057F314DFB067A1DF1ABBF79E64E9
-:108FA0006F944E6A98DDEB40B883D17416F5FE9C41
-:108FB000042AE31FDA25A7DA154E87CC9B5A333EE5
-:108FC000BE1C92F3B82DCB4AE32DBB6F546A503BC5
-:108FD0003FA127AEB5459E658583F95C9661FEABE2
-:108FE0004DAAE6BB83EBB3B1C9FE6FD2D00E555884
-:108FF0002DCDC7602F3904DF19EDA587B16F0FFDA7
-:109000002F62233E3691739AD9660B33DE24847E19
-:109010006A660713FC1A313568E8C0EECAA3792CDA
-:109020005E081F2F01A6B4BF71C9971A3E7A07E7E1
-:10903000437A213209F934C1C57476DE623590A7CE
-:10904000A0DD9A69F3A19C013C111CF62730730244
-:109050008CFB363C116F95EAAD7B2D6EA403C5D712
-:109060004AD0DF2AFC5616417D73EDF424B25BD959
-:1090700099DB4756033C3C499C6EA11FBBE8C74E99
-:109080007422E4DEAFF3C76E43FD24E5A7C4033BBF
-:10909000A3527FF2FB7EA53ACF09E5FD9E8B4A5A8B
-:1090A00015BDFD83F650D47E4ABF6F16F0E3E4AAE7
-:1090B0008E880958A825E4997D27D4AF4CE26B1E11
-:1090C000E9E27A707F41484DC1FE46C13AE0D55B86
-:1090D00089C1A26647141F60E304117F1956783ACC
-:1090E000387FE0739F8BF3D99C748E942DE9BC9CE0
-:1090F00091C2EB1BE9ED49F17D95C2F1BBA99CCB77
-:109100000963BDE92EDEDF6A7BA82A6384D6BE0A26
-:1091100030A44333E37696DF25E8A482C3ABE2DED6
-:10912000C5A9A837BFED999FCA8AA272F41E25E887
-:10913000F441FD7B2C819F52BCE35F5486FE883551
-:109140002DE87441BDF4A4D8FEF24D621EE9E84F4B
-:1091500043BD9F087FC772FA62F2B317BAB83C4B9F
-:10916000C9AA21798E30F4A29FC2FA434E0DFE5255
-:10917000A798747E83E57431B5BF70BBA1248EDDE2
-:1091800050AAB31BE4B846FBE1D37559347FD9FE2E
-:1091900086AC8F2A99A6FE8DACF71EECEFC635B9CA
-:1091A000BA38513CBBE32E011FB4134231E765D5F9
-:1091B000BDFF14FCC49076FC237CFCE8B849C06871
-:1091C000D171FD2EFFDD2EE2A7CB9D872F864702B2
-:1091D000BC5749DF90DC07BDE4DFEA207D5485F20F
-:1091E0005AFA47C8F7CE54A4F1F20DAE491AFD2839
-:1091F000DA19E5D09F453CE3CF4E6EFFA51E94F6ED
-:1092000062A25751A2FA66B0BE127AC62017CF6783
-:109210005F03BD86B4FADFD8EF53AEEF6B5716C6C7
-:10922000A18FD1FF237665D9E541753CCACD2A854A
-:109230008D82C7E4997A3DDFEDE2FE47B72B49A75F
-:10924000E7E72ED6D78B60BD49F84C1A92BFA2D55E
-:10925000438A8AF28EF7D728E8A1E0D807562FC8AC
-:10926000DFFF1276D017E9FEB791AE3624A614A31D
-:109270007ED8FAA78A315B61DEFDEF5B7CDBB0BB99
-:109280005D9C3ECA17AD6935C37B4B87E2B4318D17
-:10929000DE5ADB79C90A58EF0792FEDD7C1D0DEE20
-:1092A0008875248C9BD3C0C7CFEBD8AB9835F22DF3
-:1092B000AF8ED73BE4B2E8F45EAF287F26FD0F16F1
-:1092C0006EA92CC5FA7EF326107D391D0AC583735D
-:1092D0009A01004007393EDEBFC31756961745D79F
-:1092E000D966AA2E42BDD09691E443BD30D61D3C2E
-:1092F0008CF4DF70281241304D3ED46346FBAEC281
-:10930000EDFF0ADFCB757A55670ECAD5A4437C7E84
-:10931000ED067A070B59D0F9362E6F55F60E437CC1
-:10932000A0EC80F132D68F21BD24EB67B8849EC8B3
-:1093300060C117C8AE626D8CF0C5681D19EB47930C
-:109340007D2FF119B5A3C64E403BAAF0818879194B
-:10935000B4DBFD58ECF8BC45E81158074BF744D78F
-:10936000118F2FA41E93F52C71FC6849EF4955B15C
-:10937000ED53D000F4BD7C91FB3A5C77C3062BB370
-:109380002951F857B803E9389F9C8EAD0AC246D2DE
-:10939000D706D7D34A2EACEFF65B985365F1E7DBDF
-:1093A000B0F6C54B5668FC2DE89FF0B1D5CAEAB4BB
-:1093B000FA54FA1317A773FD73A73B3002C76DDC8D
-:1093C000B5D98AF8BD65FBE7566DBC7BD03A8608F7
-:1093D0002FA58EFB290DB5F630AEB37C9199F057D1
-:1093E000BFC11A4679D4B0B33362427BFA6EE6430A
-:1093F0007E6FE8E87C2B07E092DBE09FA47AA3FD78
-:10940000E53684159C4F0610610FF979112BEA6738
-:10941000235DA33D8C76C95B099CDF4F943B420AD8
-:10942000C0EF8425D880F54E6427F942055178BFF6
-:10943000DD39EB1D05583AF9055B049F6DA66D59A2
-:1094400076A8D736CEEA433AAA700767A5037C5CB4
-:10945000E64017B64F7327FB5AA0ADD7C626907EBD
-:109460001E221C261BE861F2DD9C4FFE263D45DADC
-:109470007B13500E2D4D4F96F612C9A7B72C7C1DAD
-:109480001B189FEF3E977F01D1ABD345E3E63444F1
-:1094900014B4F78DE346E9C9BFF842E81BEC3C2B56
-:1094A000CAF57A2167CA176D577EABA1837A3064FB
-:1094B000905E72766E55D00F84EF2D956EAACF6CAC
-:1094C000286776F2FD887AF87E9346AEC875C49018
-:1094D0002FB7217C1D877ADEE4F22542F427E76B63
-:1094E000C4E78FD2B91D77259805F4DE1A1AE385F3
-:1094F000FEDE1A9148FD497E37F2E78F049DE7D4DE
-:109500006E57306EE04EE276A39C9FACF745FA8C26
-:10951000F5389FC9553D0487D5B566C29B9C4FA5BC
-:10952000353012FDAF76D1DFBE859F597BA1FCD0CF
-:10953000AF0E103DAE6E57FCE417B41FB0CEC7F8A7
-:109540005CE8972AC663AFE62609DBF2D201D22394
-:109550005777F138C1EAAE4EF37247944E0B8EED59
-:10956000BB11E96C75878D2528883FBE5E239D82DF
-:109570007C21BA67212BED67817C0C913C65C1028F
-:10958000F447A4FCDD27EC4BE6E0EF9F10F396FDDB
-:1095900046E56602D17BC1B109FBEC00CFD53EC5E3
-:1095A00007A612D8DBBC1EF41F21F9CBD808F4CBD8
-:1095B00064FF46F8FD5AC8D518787E3E3D861E9158
-:1095C0007AB5E0F1190C9F127F660177D9EF9E748E
-:1095D000BE9FB527DD4CFD6F28E7F1EB0D16AE3FC2
-:1095E00036B4D8C3C8D76FA75DF98E520C707259C4
-:1095F00023F8DC6F5AD680DFF7E7F079B499D68F7D
-:1096000069E6FAEBF574C25F0AE3F289CBA3875EE1
-:10961000E4F2A421E4203FB12158B382F61FDC0913
-:109620003EB4F759F04DEBFCE4283D18F1EB7D61B9
-:10963000AFD50BDFAFEEE07C10855B5847B720E776
-:1096400008EFFB5C723F2258807005FFBD05E30CFC
-:10965000D27F4F591C08257B07F36BBAF0DF27092F
-:10966000FFDD32C5FE17F5DFEBD7FE5336965765A3
-:10967000BD4B4FC92FE027EAF8EA84F0DB0E08BCA7
-:10968000FF41D04B7D6907F143FD97CDC4478E2A3A
-:109690002E4F1C87F47290B11F8BF53F40FD54266E
-:1096A000755CA9A23FFCF78AB395C59FF7CD4AF335
-:1096B0003F4F45BC74AAB42FC5CE80555F06704D90
-:1096C000103010F52C6E1EF73EF1142002F9D2DC9A
-:1096D0006C3D97FD7BBE7E59E42305F15D2F607DD7
-:1096E0006267C5D4DF613CF1A954DF2858FAF19DC7
-:1096F000F3FEE677D0FEC4F6E93ED4D3EED600D131
-:109700004FBF27C1877143B70A962DD0434BC71B64
-:109710002997E1BED833974C40B999E7E67C79ECBC
-:1097200045752DC267FD3F3C3F0DBFD7879574B48B
-:109730001B4F3CF5F77F46BD58B7BD093D0DD6FA26
-:10974000CCEB64879BC25BF9FBA752C9BE3CFAC451
-:10975000E66908F7D68E56FA7EEC89AD54DEF70F2F
-:10976000CFEFF94FB43702293EAC77ECC5CD3FFAC5
-:109770004FA4F39A141FAEA32168E6FBB692BE8DE8
-:1097800072AB732FF1A9A497AB51EF229C6AB9FC7D
-:1097900091F4FC85D8575A56E1684379F6C5A6E49A
-:1097A000BA58F144BF582FC65C488ED52A144F6B67
-:1097B00003AAC1B8465B229B82CFA4A2883517C6F4
-:1097C00059B8B8731AD93DA1CF5762FD79BB12D8E9
-:1097D000268ABF61F016EC7F2275C6C683183C0C42
-:1097E0007E32F4BEFD2CD8D71F5B309643FDE9ECEA
-:1097F000FF796DEFFE11E5688DBD77AFC71B7DDF8B
-:1098000026E234509FF44ED99AD8F1D02AB743D0EB
-:109810002DD79B395DD5795E921336DF288D5D3A61
-:10982000EC60F32610432CA7AEE74A5CC75563965D
-:109830004E24BAC0381FEA9F9083FA5F8D714AE0C8
-:10984000B3456ECE4F194EE6BE14C6AF3433B703E0
-:109850009F8C7D642139B283FA05FB83EC2AEFEB00
-:109860000B77A03DB2C512CC9E84FDB409BDB59D59
-:10987000CF1BDA3B71BF14FA735E3A81FAE9B1B8D3
-:10988000A87D88B79FB5BD4589CE1728351FF51629
-:10989000F657EA403D13AA25FC78ADB4AE635825CF
-:1098A0009BD65D7CC3F828FF1AE33B28CF701FF8D6
-:1098B0004E77F96DEE49D1A78CFB18E1F9327E871E
-:1098C000757FEBF6D3933D95AED32BF1EC957D0BE5
-:1098D0004F72FDFBEAE7246F1A918E71FCE0973A14
-:1098E000FDBB5CD2F12B9F131D2FDFC5F56FE3AEDF
-:1098F000122BD2EDF1757EF65B30401BC53EEB16A8
-:10990000A57725C5795E497062FCEEA4D037F50FC6
-:109910007C7E18F74747ECCA26BFFEE42B09B5D872
-:10992000CF7E9389E0B97FDBC55B5B15ED3CB93F2A
-:10993000007630916A23D8A9DC0E5EB119FDB3D54B
-:1099400075CC87FCDF68A09FC65D07885EA41D5CA0
-:10995000F0F8DC15DCFE4CF025A0FF3693DBA30C01
-:10996000EC51AC9F3633DC6225FA2A2943FADAB788
-:1099700070CF46D4E38D339913FBDF32CCFF4A2EF0
-:10998000AD476198CFB2C5D23EC30CEDB7547A9DB6
-:10999000004980DB76B27BD918ABD0732BC85E6EE2
-:1099A000CCBADE477C669407AFB490DDD5E84DA411
-:1099B000F95CBD4BB98DDB230EC6E7AF107D5E1D94
-:1099C000BE2C8CFBCABF17F093703C69E9B911E15A
-:1099D00071F2252044F87EF54C4EAF69333B488E3A
-:1099E000BCFDCA2CD2E3922E935FB6913E77999D2F
-:1099F0008A8FF4DA3C9B16AFED16AE97D2849E297F
-:109A00007C80E33722F82922F440C46DD5C75B9CE3
-:109A1000A162D4BBBF17F8273182F25DC893D52B62
-:109A200022C44F0D3B797F6E9BBFE4760DFDBA2BB0
-:109A3000B85E94717FDC07A88E212F7EE7E6FAB12D
-:109A4000E0F1659BD15EBE0AF08E2A25678C90A35B
-:109A5000401708B79CBA00D1C155EE9B7D6A01ED55
-:109A60001F909FD8DF6265B1E23C47851CF5A407D3
-:109A70004A31DEECC94C263BC7A3969B12B05D89E8
-:109A8000E2DBE6A5FD4DB2F3FA3DD9BE6D3A7E0F9D
-:109A9000949AA0DE918C648EE7F0AFCD73C7231F3C
-:109AA0007AA59FAEB3FB06FBDBDC6E9CD31E2A4679
-:109AB0003F44EE5F4838845B126BB5F2B34FC02170
-:109AC0003C96C7F3C1BE7750FCDA09E3A05FBFED57
-:109AD000B227B85FDF4AE31F74F3784625AC0FED79
-:109AE000364F61600DD7A7C9BE58F0B853E079DF93
-:109AF000C21B4BD0AF6CAC71F890DF1E7A55594643
-:109B0000F48CC141F4B7832B080F0CF080FCC082A9
-:109B1000DC2F6D6C0E8463D37B35F15F23F29F42A3
-:109B2000F44EF176A0F730A777AEFFA4DF8FF2B145
-:109B30003AC67EA8942F8DD6DED148C7921F1AA7A9
-:109B4000F58E46B80D559E9CB400FF23FF001C9077
-:109B50007F24BF24EFE67CB2A9C55B8EDF37553288
-:109B600067AB461F19FD259C27FA9D52AE8F7507DE
-:109B70000A3D1807304536621E8594C38DBBEF1B26
-:109B80001D2BCF4DCA61BB99CB377B3829DCAAA1ED
-:109B90002FDCDB4B9E404FCADB495A1B3B2E52E663
-:109BA000718878FDD0F222325097A3BCD996144622
-:109BB0007925E344C67EC778145D3C46FA2DB8BFCC
-:109BC00080F5E77A38BD547AB89CB85E3CE5FC2550
-:109BD000FD7B4DC1CF319F289EFE92EDFE52712B31
-:109BE000398ED4A346FCCBFD115C4F7551FC7AED48
-:109BF0007BB97C32D2E372C1275E5C2BD47B4EEC06
-:109C0000670DC62FEF87D59A75F96F6DA6CEBA5836
-:109C1000F12FB9BFC11E320F29BF6EEF3A9E47F533
-:109C20009CC8A7658BCDBA7C2A87CFDB82F1D3197C
-:109C3000F6821295C6E571ACE469EC6BD4C3C5BB82
-:109C4000DAC7609E9227A0DF1FC9AC4DD4ED3F64F8
-:109C5000075DBA726E5D8EAEFEB0E611BAEFC3D785
-:109C60008ED37D2F084DD0950BDB2ED5D51FD53E3D
-:109C7000439F8FFBC855BAFA63C37375E54D2D1D1D
-:109C8000B588978B9FBA4ED76E86D9692E01B88E4C
-:109C9000EF58A6CF1333C033F5CF6A4C3A7CD2537A
-:109CA00040789D61D6E70B5FB24B0F0F4C8BC3FE24
-:109CB0008A99E86FDA9109E7CA632D66E66F7A65DB
-:109CC000FB82C1F4C0ECBDBE400C3F53D2B92C1B8B
-:109CD000F7B1A4FCB850FA8B374F497FF1BEC78368
-:109CE000DBBB1EB90FC3E16219804BADEF5C70B1F5
-:109CF0009C0F2E0CE092FCFDE162EC6F7D5223E59F
-:109D0000037F84058D7DDC2BF84896178452B91E9D
-:109D10000ACC3B8F1DCDE3C0411BDF9F347EB7676C
-:109D200070B9361AE640F019225F7F26F070281EBF
-:109D30005FAFFD7A7F26CAEF2A467EB3B3B9E56BE3
-:109D4000D45B4BCC1186F4FF9058CF169117FAC80C
-:109D50003A27F5F3A8D87F7C6C9D97DE3FBE6E0C4A
-:109D60003DC3EB7CF47EDBBA29F4DC0EF61C3E9F8F
-:109D70005C5745CFA7D605A8DED3EB6AE9B9735D7A
-:109D800090CF6B10BE5819D93981F498F1D2A52122
-:109D9000754878626A5E4C7D19B71F75F139F3C852
-:109DA000D71E5A34FB4D0DFF666524BB0F630EE3CF
-:109DB000643619F733CFD7FEBB75B5B3DF1C3574E6
-:109DC0003E92F4C4CEA48F8EC5D741913FF9BB8794
-:109DD000CF6E0A15C5875794CE62C3A9C67E3207D7
-:109DE0009DF562B41934ED0F1AF8B826981AD36E9F
-:109DF000A811F4596BE3FBEF8B0CFCFD92F8FE52BB
-:109E000006D7779FC49133576798A43F6FA1FDC0D1
-:109E1000417CF7932B62C1777F8657C7C78B820639
-:109E2000BC1AFAF9C4D23ECC1783CFCED78F5C9F31
-:109E3000B1DDC3195C6EBDF8FF297F7E725332F924
-:109E40000F08378F66FD9FDC94541B2B2EF35A06A8
-:109E5000DF0705EB9C15B8C8D40F59D1561CC3BCFD
-:109E60007C9F77A413E343320F203EBD9A298E4492
-:109E7000305407C315F0E1B51642FFE68171226642
-:109E80001CC7678AEA59CCA9619A731EEA607A8076
-:109E9000F6212BE5EFF4E6D0BEFF05D213531F1BCE
-:109EA00075AE7DBA41ED2F50CEECF881E58CE473B0
-:109EB00076E6C151B1F4642D8E7D29AC63CBD4FB21
-:109EC00049CE9CA7DF0B855FADDA4BFBD64386DF1F
-:109ED0002EF790E2526BED29C50CFCBAEF12F83365
-:109EE0003483F1F3589F2584D1CE3F20E6098EFFBD
-:109EF00025DCAF6E9E8CCF7FCE0A7C9801ED975902
-:109F0000B99F383EC3FF119613C53EB035D3BA1181
-:109F10009FCCC9D7718958C74693371FD7F1A5E29F
-:109F20001B8B7E8AD314F6E1338545C6F3BCBB7028
-:109F300010FDB3F48B13BDE8DF268E66AC87E2E13B
-:109F4000BE048C9B5993FAFF7124F2FBEB268C30F4
-:109F5000B2E79D7CBECF3F924BFB2AE801A17C2853
-:109F6000C6F730F54D688743FB6B59F018CEEFA864
-:109F7000D31E32C1BC8A677FE1C27CA8E7BB67D031
-:109F80003E42E4293564C5730B3D27FEEE6AE8EFD7
-:109F9000921E0BC59B2F612AC9F37A337B00F926E9
-:109FA0001E3C8FFF75ECFCAE2B32B9DC93795BC69F
-:109FB000EF79E2FBF13879C48E4CAE17647E8C45A4
-:109FC000E6C778FCE7CC8FB118F2632CE600C37DBE
-:109FD00060CB407ECC6246F931D08F363FE6F88CBC
-:109FE000D8F3708B79584E27C5E93785DE1F1F716E
-:109FF000EE755A4E27E8F2ACA3ED1DF43E5E7ECE20
-:10A000007831FEF138F9496307FACF66A1746D3BE8
-:10A010002F9FF7C03879F4DD62C8F3897EE7F93DF8
-:10A020001BD2389DECCD72BA9742D74B59AF05E998
-:10A030007489C36DC1F85180F93AE9DC8ED9D2DF59
-:10A040002BF96E04D6337F8176B609242DDAD94BED
-:10A05000D65ABEE8D5C8A96ABFBECCB0BE46EE6E21
-:10A06000CA6234DFC4716328AFEF14F3A63ACF217C
-:10A070003717DB55BB59B3DE4371EC865B05FC0E2D
-:10A0800065C786DF7599DCEE88771EE2D6CC14DDD5
-:10A0900039BDDB9DE7969708DF60BAB67F231EDCEB
-:10A0A000F4FD7C70F6E0E61AC6D1CA159EBFFF1714
-:10A0B00087779A3857C5CF05580C79E89BB2B8FC1A
-:10A0C0008BCE9BE7A17FE40CDC9E8972D1EC1DADA9
-:10A0D0003D07D065F6274D80E72121778C70D99D0B
-:10A0E000C9ED37E3BABB443E7DA2CA9A3B35F0378F
-:10A0F000AEF73941E7B2FE060BDFBF82BF801DF02D
-:10A100007203E372EFE1CC11222F3CCD8CF270315F
-:10A11000EF82DDE07C8BF693249C07C14FC0DD0805
-:10A12000C700F3DE8879DBE783674796FF6184CB5E
-:10A13000D203895694FF37DAFBF7A38FDADB63FA91
-:10A1400078243C3F778C3CBC9DE1FEDB9897F7C1BF
-:10A1500033658A8FE751B09964EF28A15CF5ECC5AF
-:10A1600043B77736A604C7207F7C29F2AEA53EDA36
-:10A1700098736C34E6CF7B5DE5ABB23C1477F7A700
-:10A18000231DBD66E374F408F404E5A63D63B7A29D
-:10A190009E79302B5887F5641E1FF3F78FC63C84D9
-:10A1A0000B8513FC59908ECE07A7273219E1E75093
-:10A1B0004A6C3AF94D1C3A31F2079D2F2BFDE1F81C
-:10A1C00043C253EE5BC8F9D565713A944F093763C2
-:10A1D000FE505D9649D4E3F9880F660508CE7DC32D
-:10A1E000BE3E9C00733F64C8F792CF93421E9D6FA2
-:10A1F000FD12DE3F941C3E94187B7EA6ACA1E1E7E5
-:10A20000879A5FBD9C5F71ECF965660D0D7E01D686
-:10A21000FF59DA0FA0C700CFF58867B6A19FE4E326
-:10A220002157EC79960D799E41CB0FA16F257DB317
-:10A23000D0D23ADAAFCF4A8CB95FBF00FC27F47FA7
-:10A240008CFBF6727F1EE407ADB7C6DE7F633AE291
-:10A250007DA65877068BA4E17EE61E1BC5FF8DEB1D
-:10A26000BF42D011C0AB82E035A79FE2188746C736
-:10A27000960B15C6FA6D7C9C78E70BAECE528674B1
-:10A28000BE80950629FE576E774454C0C36D021FE9
-:10A29000D6DC553EB40FCBB3DE3B88EB04F89F18F9
-:10A2A00080A7269FEFD8BA779C232DF1E576BDFADB
-:10A2B0004259738CF5043DC11BB3347E50FD53EFFE
-:10A2C0003A476AF0359EF59AF8F9E87E93CE2FCE9C
-:10A2D0006417E41757639F988FE00A903E40FD8013
-:10A2E0007A67E3EEA925884CB433309FA73F3991B4
-:10A2F000E4686BCEA563BC1A7886B2A47DA9C6B10A
-:10A300001BFF7BF9FF51BB49D1D9AFD1FECDF45E24
-:10A31000E2A7DCF18F31F111F4F8EF213DE6F26FA5
-:10A32000C4A7117EA17B2F4FA3F30508BFE9D1FE7F
-:10A3300006F01F07CF1D1E7F3BF6D720CED1283257
-:10A340008F6F205E61761EB647E13D54BC248A784B
-:10A350001AD80D8F211D586D821F9983CE874BBB54
-:10A360008519EC1B3686FBB73764BDF7478CF76C55
-:10A370004CE12CBBF14709E4072E519C565C37D8C1
-:10A380001F9FFE1CEA0759E4D3BBC83F9476469250
-:10A390007A3669E8F394FEF2F9F2A9F7A13D06F3E3
-:10A3A000996172D0FEE63E585F36C88D1956FE2C74
-:10A3B0009F055405FDCD50F3BA7B615EDFB2338952
-:10A3C00057C0F3A78CC361CD81DFB9D01F9D61B6A3
-:10A3D0001CD3CA2D63BCE38DAC6437E151C43BBED2
-:10A3E00065737E7D31C2E57217C1A5F8959999DA3A
-:10A3F00078CB40BC43AC635E682997A7063927E554
-:10A4000099C9CEEF11617EE6756650DC88C33DA424
-:10A41000303394AF90657452A07CB9409282ED6164
-:10A42000DD5788275B16CC423983693C381E787F1C
-:10A4300059F86C9DEAF3E273BA1230F3798479DE4D
-:10A44000216BCEC3FA267BAFCACFE7C10C32B0BDB9
-:10A450001C8F9793457943CDA91B6FF20E8E633005
-:10A460004732D9BD5631AFA34E47C804EF6D8EC8F1
-:10A4700051CA4F154F63BCE33B532884F9D977AADF
-:10A48000619A6F128B447A303E61071098288EF0E3
-:10A4900007E403F06E1A719E09CE5391BB18E6399A
-:10A4A000FA152CA71BF491C7B186F29E3D01B3416A
-:10A4B0000F0515E49BCC5AE37BBD7EB2B343741EFB
-:10A4C000488904B2CEA69F3F5E638CD35866701451
-:10A4D000F7DFC2EDDE8F13793B4917E9D95CFF3610
-:10A4E000BAAC8CF25D32EC76B4DB4F261FC12397F9
-:10A4F000A837DA506FD82D7E8287D41FABBB6E652C
-:10A50000889FC65DD50CE5E86F14BEFF19BA41A15E
-:10A510003C05796F436D117B1F5AB2A6EC1134CE06
-:10A52000FC7782373440B9E63D363E02F54AA6074D
-:10A530002AF17E96D6F1CCB71ECAAD09C1675FC2BB
-:10A54000F51C50A99F26712E963167FD4EE87FEBD2
-:10A5500075C37C9B704915FD1B310FA8FF3EE6C4F7
-:10A56000BC9141747A06D607F87F02CB30EFA6156E
-:10A57000C15FDC01F5B3DF633EAA23BEA32F82785F
-:10A5800053043DE0FBE9F0BE49D04D61B7C2F7EF9F
-:10A59000DD36CA9F600733895FE6DBF9384DDDE5BC
-:10A5A000D74E827915F64C24321E09F531BF093396
-:10A5B0000C787E1D237FD9587F24D6F752B48AE7C2
-:10A5C000D5E458E9FE2326E4DC6403BF5D16A57FCD
-:10A5D000FA5E22CA4D421FE9F804FB01FFDC5FC6A8
-:10A5E000B7F3A99D9BF3838FC93FCEB797B2E81FFE
-:10A5F000F65B111D87E4EF4CF16DFFA2D994D73DB6
-:10A60000D91CD98B7C7D9978968827F2B51DE0B846
-:10A61000D0DCBCDF03EB495BCB7C2D38CA626F2BEF
-:10A62000F657CA022AC2B9CC795F2BCE6FEAE20391
-:10A63000E9485F4F6617123D5D6EF715260089B435
-:10A640004EF1F99CF0AA76B14270995F6B0F63FEF0
-:10A65000DAFC81FB7A82050B806F160615718E3E3F
-:10A6600058B058138F95797D0B6CE047C7DA77CED9
-:10A67000E67A5CB66F12E74EE4F76DD90E9E5F99ED
-:10A680007D655336E557F07C67E0FBDBB22745E597
-:10A69000088C4BF928F398DF82EB9A27F856F2FDE5
-:10A6A0007CFFED64B7CE0FE8EDCFDF281CDFA145BE
-:10A6B0000AD9830B6BCF6D9FB664CBFDDE3C27C5FB
-:10A6C000B799D4479CAEA4DC9E8B7A1CE56D15E847
-:10A6D0006D8D7DBCF8CE3369D42EF3C9D56787471D
-:10A6E000CFB93419CEB9348A732E4DBB5A2C1948C0
-:10A6F000EFE29C4B53F7E71BB5F97D124E83CFB9C0
-:10A70000F4535EE3026B782F9EFF59B00AD608F52A
-:10A71000DF10E722DEC4731113A274947C5D4284BF
-:10A72000E7CDF9297F2FCF99E4C37C9336D304CAB0
-:10A73000176A4B49F669F37336B53457623D99276A
-:10A7400024CFB52C88B31FFC9C906B5B149EAF1577
-:10A750005A6427787B5476507B4EDF5318A03CB95F
-:10A76000A66C2F8DB345C41130AF74223CC3608EEC
-:10A77000717CF1F646F900FD6DC0FE2A0A7D941F3A
-:10A780005391CAF3CC3CE98192DB8AA2FDD674F3E3
-:10A79000BCBC9AC0D76FF1FCDAEA5284A7519E4B39
-:10A7A000FA32CA75A0BF7D488FDF99B8DE89CAF733
-:10A7B000C0A29BA0BFBEF7AD943FC7EEF62B1668B4
-:10A7C000F7E2BB4E1F9EA7DB501EA8AEA4EF663A71
-:10A7D000EF9751CB2236F85EFA9E751BE6EDD5B1A8
-:10A7E000762BF65767D05BAB1C6F5A913F576DB70E
-:10A7F00044E99161BEA1AF10055DC3CE41710F92D6
-:10A800003F522E19E9988DD4CB9F12296F412E709B
-:10A810007DB598EB39F6A482F19FBEE423AAF09FA0
-:10A8200049DE4D9242CA20E72775BF4DF6CA3490E3
-:10A830000FE89F29582EA6FA5406F93906F3472F38
-:10A840006389445F83EC0431AFD28179737B48CA5A
-:10A85000C5F2298CE17D06122F300ED1B3DCAF9BFF
-:10A8600084F7F0C0F33231EE9D267F5144413CB174
-:10A87000B0A910ED8820D93B46FBA7CCDE9C6487AD
-:10A88000F54D61ED241727EF7F93E424E0F92CCAFE
-:10A8900099D798C4B3CF8E72A61213FF547CEAF1F5
-:10A8A00034CBF19019E1342BCB888F9019E13ADB4E
-:10A8B0003B084F744EC01F074F7E2947985E8E1489
-:10A8C000B033FC5CF27D6FDD817EEFF9EC900F3DE3
-:10A8D000C1AC1C929F7A7B245E5E5D418EE382F266
-:10A8E000EAFA2CDC4FB894F5AEDCA90CA68B93FBEE
-:10A8F000D7AA591AFA9174B95BE4D92BAF8BBCDD96
-:10A90000D264D27351BDC8F15F264A97225D69F0C7
-:10A910007FC5AE84880AF45622DA5F8AF43021AA11
-:10A9200017232687D70AE36E547C6D6A0CBC67B880
-:10A93000BCA4FF269AFC2AD953CC978E7806BC4F2C
-:10A9400043784DB177B49A619E87ADBE9FA3BF5245
-:10A95000CEBC84F772837EA970D498913F2BEC46CD
-:10A96000FCFA09EF95CE41EF4DDF07EFC311EF522F
-:10A970007F0CC1FE04BC2FCC89B15F180FEFC1EF73
-:10A98000897723BE25DF7726382B1C18D7ADE3F94E
-:10A99000C413DF1FD98AE58CD50574CEA533CDF756
-:10A9A000067D6FE6DF4B7BFC2ADE9F58B806BE4370
-:10A9B000B9B3205081E5A6B50AC9CB491F055BB1E3
-:10A9C0003CF26EFEBD647DF31B780F595388B7DFF0
-:10A9D0007D7423DD2711DE28DA97B75760B9A98D7A
-:10A9E000B7FF2AD91E42FFBAEC60B815DF8F7D8011
-:10A9F000CF43DA75D3059D752A2FBC41EDDA79BBBB
-:10AA00009BDFB227927C1276DA34B1CEE98FF175F2
-:10AA1000BA7F7B559517E8F0A6FE9005E9E0B0A94E
-:10AA2000A18CE4651C7FAB5C69CFC3E72C900B8CD9
-:10AA3000F00DF43982E79B6E83211ECBE17686CC44
-:10AA4000D3C47CF16A0DBE1ECBE17127592FC3C55B
-:10AA5000785EF1A3C964B7CA3CD2C8CF98827100AE
-:10AA60005C23E9D73879A5B30A9B495FCE1A2EF348
-:10AA7000497BCDCB60DC92B37FB832967FFD8418E2
-:10AA8000F788C87F97EFEBC20526F43F3A9178E844
-:10AA90001EB3DAF7D12EE94C63BA7B423A0B78B990
-:10AAA000F3D19A1FB7E5017C4DCDE6100AFD7C85F8
-:10AAB000EE3DB9A68745525306CF7F96994578DE7D
-:10AAC000039FFFCA56EBB64D1A3B7DBE141B978FF2
-:10AAD000223D5223F024E5C57C812FE0EFDDC8DF65
-:10AAE0000BECCD64172E12F2FD1616A638C52D06F6
-:10AAF000FEAE777CF399C984F1303D1FAF86E970D3
-:10AB0000BDD0FFF82700FFBA47929DA8E75777E826
-:10AB1000EBD53DF2FE416E5FE9F9BC4EF27958CFBC
-:10AB2000E76038703EFFD938DA7F91E7FA12ECFD22
-:10AB30009F855874BD03FADDC07F0978CE6F0CFA8B
-:10AB40002D269E5F28CA72DC53ED5C0F87400F0BE9
-:10AB50003F8744EDA943B3C3480F25827F251F9744
-:10AB6000087D3E485F5719FD9887883F268A928462
-:10AB7000BBD4CFD00FE967796E10F4F2FB7EF2EF11
-:10AB8000C1FFC4798ED3F3CB2605E47341D45F01B2
-:10AB9000BC7D8D7803796CE7718A7686F22CAEDD08
-:10ABA000EF5813D3EE074947FB0083EDFD88CE8EA7
-:10ABB00037E22B9E5D3F80AF04B09792D08F67C481
-:10ABC0001FFF88CF21E475809C76E4C690D3D67DA4
-:10ABD000BC5EFFD6048A17C8F8B8E437258FDBD5EA
-:10ABE000EF66F95DB9B8FF20FA3F74EB2CDAAFFEDF
-:10ABF00086F969BF1AF38D7263E44BE07EF5064D6A
-:10AC00009CF4505AECB8F5F05CCEEF4B72F9BAC632
-:10AC10007BFC5E1CEF8895C7C58F248A670ADF57C7
-:10AC2000B83897C7B9978867B9781E1179D8475C43
-:10AC3000FA78BAAC5721C6F9729DDDBE412357BCE4
-:10AC40003FB335A3BEF2148ABCF5359C5EFB5E496A
-:10AC5000DBAABDAFED9ADCF22508474FA1DF9A8D44
-:10AC6000719657B85E6834F75A31BFE41A77702A84
-:10AC70007E6FF432FF0BD88FB7D73A0FE0DC27F6A0
-:10AC8000E9FB2CDCDFE84BE04F39AF6B72AB97E0B0
-:10AC90007AFB6EED25F93050AEEE25FEBF2637402B
-:10ACA000E3F6CD97DF45F9C7BCCC847F582EF882F8
-:10ACB000E2BC31E2BA83E3B8FAFB679AACB1F7972A
-:10ACC000595EB22E3E7B43378F1BDE68671B73E1F4
-:10ACD000FB92EE4CF21FEA5242A39D14C7FBEFC554
-:10ACE0005DFB86F5D0BA3695F7E73F5A4AFBB814B4
-:10ACF000F759DDFD36C9B9D5924FBAF47C522FF021
-:10AD00007BBEFD0F635C7C08FCB32616FFBC8CFA8F
-:10AD1000C91285FF6D220FA9526DA8C0B8D0A91520
-:10AD20008CCEBFDEF6AE4AF474DBB30ADD0721ED4C
-:10AD3000B3D502BEF1D683E707BC1AF981E707BC99
-:10AD40001AFF0CCF0F68CB787E405B1FCF0F68BF18
-:10AD5000E3F901ED773C3FA02D97B0E5AD18676BA7
-:10AD60006A63CEB0979F27D0B6C7F304DA329E2726
-:10AD7000D0B6C7F304DAF229C6E178EA3195E2F4F5
-:10AD800078AE40DBFEE677276621DD7425F03C32A5
-:10AD900016F2F714015C5608B8E079036D7FC753CB
-:10ADA000AE7C8701DDADE85939079F97EC5AA5EBDA
-:10ADB000AF5E6D203A64ED5CEE36C33F243FD52292
-:10ADC00015E7F1ED2E85A517E0FDE106FDD9BD796A
-:10ADD000238A9E5BC2FAF7F54C13AF2D181C977FA0
-:10ADE0003957E421E6B01C6D9C264A070E5F04D754
-:10ADF000FF91EA8B450725ECA2548ACFBCA362ECF5
-:10AE0000817DC59AB75CAE68E2F70678D8B2F4F4F3
-:10AE100090E0D5D343D2183D3D24FBF4F4903A455D
-:10AE20004F0F69FE71E7846F7A959E3E8CF09D020C
-:10AE3000FF207C27E0CD9018578275629CF72F0584
-:10AE4000DF2F72C5BE8780EFB7ECF20A87973ED737
-:10AE5000D8CBA2F649E93BCDB4496B8C7B4A384A42
-:10AE60003B41C62F2731EEA7DBF1BC6521DA01DCBF
-:10AE70007F43FD8F7C7ED8CAFD36A420949337B1E2
-:10AE800020C9A39B0CFAFF66C74356D4FF83D60B99
-:10AE90001617DE1B685C2FDA514C134F32EA7FA580
-:10AEA0005B892417E372BBA55C0E9E2563C7AF0CBC
-:10AEB000455EFCDEE1B7E579681C662FD3C57B6390
-:10AEC000DA73721E122E727C1B6B56B3909EC718DB
-:10AED000ED2FBDBF2CFD6BEA54138F96FEB1F44FDE
-:10AEE0008C7056871790DD35D129FDE29EEBF1BDC0
-:10AEF000F4878D7EE8F9F6A5E68594DE9F1744ED8C
-:10AF0000C92BC4739E8817C1B27EFB6FD0F872C57F
-:10AF10003B0CC79BBBFB220FD2CB46A59919E6770A
-:10AF2000F055E84735F5A7F3F84B50B75FF5B6D2C3
-:10AF30004BF35EC0FCF7E0B351C4D31ABBDEA67D71
-:10AF4000D4C62E1E2F60BBF47831DAFBAB5887B520
-:10AF500040196CEF37B01EEACF68DF0FA293F3E819
-:10AF6000F18E3C79DF16CF1760422ED50978C5F3F4
-:10AF70000BCC08E0A9D1FB3B811FE6E54D8AE6D169
-:10AF800066B8C08F51310FC36B8D9527C5F0721510
-:10AF9000B049973B6A484E2C6F1B1497B0123FB5CF
-:10AFA0009F7B7DD20EB81F7C377C96E67979DC20BA
-:10AFB00071CE3B7EFC5CDA93AF3DFFD164E5E70EDA
-:10AFC00059B3FE7CFEDA3C933C3FA50E65FD83E160
-:10AFD000FAFDF2F265FE01C0EF2E2DFCE43E825C2C
-:10AFE000CFEF27F53C89F1433579A61DFD5AAF2BEC
-:10AFF000D882F5871DEC3DACA03C7378293FE4E492
-:10B00000AEA31FA3FF2ED7C758EF16BCDFB66E97AF
-:10B010004AFE60DDAE37C82E8AEFEFB50FDCA32005
-:10B02000F6377E126B5E32AFB9522D4AEDD5D8E9B4
-:10B030004B851F307978E0216C57FA615E0ACED7D4
-:10B0400032A283EEC5EABF83DBC16E95CD44F881A1
-:10B05000DEE37ADF61A67D077752484D413B6E29DA
-:10B06000E3F7D0F99A7D482AEAB0228AD366DCA1B8
-:10B0700006D0FEFE74CDF2343CAF9C91BC22AD10E4
-:10B080009ED36DFC5E9A0CC514E0E74E97A5E13D9A
-:10B090002037D8F8BE7CC15F27450A81DF5EB7F252
-:10B0A000FB46DD4941BABFA03F4DA5F91C5B074BEC
-:10B0B0001B85FB1EDF4CC47B0772CE3826E07CB2BA
-:10B0C000C5BD163FCAE3F7DC1C7FF6BB89E8AFAA13
-:10B0D000671D74BE5DD29FBB30B6BFB242C0A3D164
-:10B0E000C3F3DE4F0AFBF190D86F9579F06BC43E45
-:10B0F000E0A1D103F78379302FA431C19FBA10E3C7
-:10B10000110754CA6BFFC6E94F4D23BB99E7B3AF94
-:10B1100011F6C34991F7B966F68C4CF42FE2E54B72
-:10B120001FC8E376EF0F755FA5CC3F8D0B873433D7
-:10B13000335F42F72E05CE55EFD53FAB31E1795A5B
-:10B140007C8F9737DF97A7E8F2E21B312F1E5EADA9
-:10B1500079A53C939D235FBA11EF23D7E4D7A09F35
-:10B1600086EB6BC4FBC8E99ED213744F07F683F7D6
-:10B17000869DEFDEC815621E8D984F9EAE7DCFF97D
-:10B1800039DABF9BBE3F2DE0F6F43BA6AA6D31E64F
-:10B1900099378CCBA7711E7300F7252F8EF07B3F5C
-:10B1A000E3D593E7B8E3CDAB6B46EF8D386FCCCFEB
-:10B1B0008C355ECA304E2772BE5DAEDE9501BE9FF5
-:10B1C00037BA3A595376F6E7CFD5C8D7D9023F5D9B
-:10B1D00057F5E6D37D00B3B9FF1A0FCF65E66605D4
-:10B1E000E190E00A06D11E91F715E37DC63CCF231E
-:10B1F000744E7C47E1ACEACE1F0C86B395BECBFE05
-:10B20000A4DC39FA884A72E7E807821F99DFA19423
-:10B21000A1BEE27C7594F1B8EED176FEFB1FCB8225
-:10B22000A02B407E2CDD5E3F070F1FAFDC3171236A
-:10B230008A7F7C7F37C89FA5598C4D83E7B20DFA72
-:10B24000FDB16FD903A4E7563C60D467012BCAD97E
-:10B25000950FE9EBD7B107BE46FBA0CE60F76608B5
-:10B26000BD6BB47F670C13F66F192BBB90734E8FB9
-:10B2700030FFEC61A4FFF97EDB24B19F6EACFFBC14
-:10B2800097D3C36D3BFE60C59F048AD7EF319017FB
-:10B2900023A1DF13EB9CF45C32CC5F330CDA350D69
-:10B2A0000B2EC471FA0E70389F6A38B592E2D2B58F
-:10B2B000DC0EB0E1252BF09FB6EBEDE447DF8BF71A
-:10B2C0008C019C6D366E5F48BB4A556F57F1275B0A
-:10B2D000A6FE6E451AAECFFDCCAC2AF43F3CCF247F
-:10B2E000F9111F9BCAFD2528BF37553B689F78ABD6
-:10B2F00089DF4368B7F1FDB9F0D353F7613878645B
-:10B30000C7E619E86738BBF746302ED166E2FBAFD7
-:10B310006DD398B8C79A8FD7D45DDD89F3CAAF01D2
-:10B32000790FFD6D2AF0973835FD33612F350A5CB2
-:10B33000F4BD76D14FF1DEAB9FBF43E62AAC730478
-:10B34000C5BFC6314E3732BF847E1B43132F3A012F
-:10B35000FA8769CE3F8FEB50229614BA5F8FE2D8FE
-:10B360000DEB2319D7A3FEFC25DFAF95F373BF9E2A
-:10B370003D03E3FD529F5E8FF96D18071676EF22AD
-:10B3800026FFF87E41ADA0EB45C2DEBD3E89C37904
-:10B3900019F3D1F9ABEBEC2C05E3CBD757744CA2E6
-:10B3A000FBAFEB2D6968AFC8B8773CBCC78BCF3417
-:10B3B0003E99CCEFCB51FA476327C73006521ACDDE
-:10B3C000B737F6B36398E0E7D1C24E1BC9FCB8CFDC
-:10B3D000D2B8E722CAC7B725F27D35906F76C4EBA5
-:10B3E0007ED4E7B0EE5B5E4D88F07DE3B0B81787A2
-:10B3F00085683F664F26ED2BB80BFDB4EF7ED2D2A9
-:10B400009B4FF200E49702BA73CFB04FAE31E3FD29
-:10B410002039604741F9F82F0E5F83BFCFD238A2A1
-:10B420007725DE179EFEF8595E1ED77B18CBC31E0C
-:10B430004FBC96CA137A57AA509EF278D6B5D41E3E
-:10B440001D2820ACCAC7875F8BE7FC8E89F825F3DF
-:10B45000F5D23D418DBB2F3269E38325F95C4E1F48
-:10B460004BE0F58E15B0257311DE637A476B7F379D
-:10B47000C1932FED526E97C975CA762C2B76FFEFCC
-:10B480000B3D708BB8DF677A126B4BE0FB1521B474
-:10B49000AFDEECBE88E0F2C2309780572FDDDB28AC
-:10B4A000FB319EEF97E3AE42BD8D72DDA23F4FF4BC
-:10B4B0001BA12F609C0D344E91BF04EFE5699C9B4E
-:10B4C000578278037C9905BECCDC0FDC4A78C67EB7
-:10B4D000D38A498F4CC43CB137CF40FD82E8BC8D44
-:10B4E000F471588C734B2BDF67EA4F2B243A9A9EEA
-:10B4F000C4ED3F560AF003393645C0AD245F9CE3E6
-:10B5000019C043A642FDB70AF8E5F1FA17BADED32F
-:10B510003FD07A3578F263DEF19BBBC6129EA60C53
-:10B52000D0C1665D3FC75A0CEDA6F0BC94465721CA
-:10B53000B5BB57DCB32FEF2DC67605D06E7A45FF2D
-:10B5400044E407796F1B0B4D2367BD41488B817B1A
-:10B55000D83A787E0A1BE9E7F711CD9D532AD6E742
-:10B5600014EB736AEFA51BE0C38FFAF36B34F75249
-:10B57000CBF703701FE8AF6882E84FC7CFB1FA433B
-:10B58000BE88878F71F97F617CC8791AE0390067BE
-:10B59000C3FC243C918FA95D919E9FE43C87E59B71
-:10B5A00084BF6DE0E782EF399EC8EF5FFD37221F51
-:10B5B000D2ABA7E7D55D0526DC3F95EDDA3A5A0216
-:10B5C00028E765BCDBD6551D42FDD7D45D4E799B7F
-:10B5D000AB7FF5ECCB2168BFEAF987533099F6A829
-:10B5E000B93D03EDDC861DF7A4F871BFC41C4A41C8
-:10B5F000F97934AC56C53A0F181278907654A3D026
-:10B6000037C79EBEFF1A84C77FECB038518F363DD6
-:10B61000658BD8280E720BD95150FE9C97EFFD1AFE
-:10B62000FDD2A65D7A3B69D53F3C9CE1257A0AE5CF
-:10B630009AF08C0B8BE43278366EB7F8226E1E4F80
-:10B6400084615813EBDF88F333B6C7799C06BC37A7
-:10B6500075A84BF13CAFF13B4812B2C39ABAEE2742
-:10B66000BBAB491B67003CD4C5B1BB6ECDD7E75B14
-:10B670004BB8B0B087EC9AD65FFEACF87307DEA784
-:10B68000F94F294A91565FAE27389DEA58FEF7BB1D
-:10B69000BDF1F5EA49B40B6CDA761CAFDE5D0AED5C
-:10B6A00049B06EFE6CB04452D0CF6FD86AF181E6DB
-:10B6B000650DCF3EF124EE87B04F6C74FF41FDB3B2
-:10B6C000FB3FBE14CAF59D16F71C3E7D879211C53F
-:10B6D0004F9397DB27121FAB5EDC4FF70CE27BB476
-:10B6E0006B255EEA3BF75AD9F8C1F0ABE8D82B7E60
-:10B6F00077C1809F8ECFAFA4FB3C7FF99D15E9FAFF
-:10B70000E81E8565160C6E5FB7757F0AD21FC209E9
-:10B71000FD4B89A701BC0DC257E49ADDA5548FE209
-:10B720001AF1F036379FF178D0AF9E7D0E7F07B0CB
-:10B73000EE37361FAEBFEEB9DB53701D5F999B39F4
-:10B740007DFFE29E0C3F8C5B67096538E9C9DFD756
-:10B750003D7E07D1DDCD07EEC8E0BFA7E1CF364D76
-:10B76000A17566E3FA6E7A6C3EAD6F250B12DDD5DE
-:10B77000FD82C727BE15BFC760C4E769C11F5F6DE3
-:10B78000B3E18F64B0AF30111DF3083F50459EEF19
-:10B79000AD4C7B8F0558DC54FE56C407DE1FD0032A
-:10B7A000CCCE3471D9A6EDF7F6207E8E0DF367E28C
-:10B7B000BE1AC02124E0A5E0FDBAEA81CA4C8E1F62
-:10B7C000E635CBB832D8DF15F81EEBF758FC09C5C3
-:10B7D000BA7662BF9E8F2FE31330EF44DCF7FB2A6B
-:10B7E00023F6B9ADD1C31521DF580FD3D2573C7E14
-:10B7F000DF7E1FD1D5371F71BE690C5757D1F71E99
-:10B800004B048F163786F7D628240F6CBAFB9F0699
-:10B81000E862BB45F0B3FE3BCCD3AC68E1BB87E745
-:10B82000D5AE7CC8A6BB0F214A37D6E8FB82287F5D
-:10B830004A3FEA66C1FFC6F51AE5C11F0CF2803D1A
-:10B84000E619D2BD320D96F0938F22FF02BFA29F60
-:10B85000D9F0AC85FCFCE33BDFF8F83AA0F3E31D3C
-:10B86000926FF572D5C8B7752F4C62B1F8F6B8C3B0
-:10B87000C762F22DBC8FC9B78EE83E8D97FD7072FE
-:10B88000F5E63872356FB8F11C4B512AE6BA1F7BCA
-:10B89000BA7E38C5050C7095FEAC515EBE9CEF8D2E
-:10B8A000292F195E41A581A3849FA4C755CFACA6BB
-:10B8B0007106E856D2A5A4DB01BA1C945FA983A344
-:10B8C000F1FB17288F2645F16E590F7E0ADAB1AFCA
-:10B8D000A9F43B287D30978D00F7BE9D05B40F7A03
-:10B8E0008FB0F3FB9CFD2918D7BB47F815FD184F07
-:10B8F0004C8DBEEF4F10790381FE94348D5DF47949
-:10B90000B79A82765C6F38F6EFC9CA7B2A7BE3FC74
-:10B91000DEAC3CBF54A93AF2D7629CB69DEF4FAE65
-:10B9200068599882F18CBEEE42FA3DA19BDE057FFC
-:10B9300017E6DB27E39A21BF39BB2C7ABFE9111642
-:10B94000A2FDCAE5DDF5B45F688C83AC74D4A4E2D3
-:10B950007EA0310E7233E641611EF263FAF7AB301E
-:10B960003E827832D05310E9297B303DAD1C2EF653
-:10B970005F4B58896EFF55C8B54AB5E8A7689FF474
-:10B9800081DF8EF120A616FD1AF5E9B7E8C723037B
-:10B99000843C44A7F5C12332CF8AE85AD29DD17F97
-:10B9A000373E4FBCF469199E076A78F9DF8A7F0E2B
-:10B9B000CF132F7F32FA552CFFEA5FF3FF8D0DAEC8
-:10B9C0005FB1E78FE4AFF4EDB1D17CFAF6BC9D7FB7
-:10B9D000179677DB7C38DFBEF536FE7BD07B92E9AD
-:10B9E000DEE9BE613CCED6FADA77C5BDA4A7361033
-:10B9F000DEFE6E38BF2FF654F77F7D86F7AB9EEAEA
-:10BA0000B67931EED0B42789FCF0A6DD09744F7CFD
-:10BA1000DF6BDF9569E345FFDDF5348AF3167DC9F9
-:10BA2000AC16F35BFAD2B8BFD6F4EAD4275A0AD0E0
-:10BA30002EDD4BF71657BCFEA762943F7D2F70BBDF
-:10BA400002FCF3C77113F117C3BB7F6A998AE78DB4
-:10BA500018F9D553BD7FBA36E48805170E873E80A6
-:10BA600003AE0BE042F775C78347D7707E0FFFFF29
-:10BA70003E787C4DFE4243F764E2A3285C14FEFB53
-:10BA800023DDC961BB42EBE7EFF77C578C76D2F13F
-:10BA90008E16D2FBE75BF787FF6BE9E0FBAE5B89B5
-:10BAA0000C65DDA7FED7AE9BD3FFDAE15C3F19F949
-:10BAB00060309DFFEAAFA9FC5CB28FE66BE0FFFF50
-:10BAC00007ABA359F3008000000000001F8B0800A3
-:10BAD00000000000000BCD3C0B7814D5B9FFECCC76
-:10BAE0003E926CC22604084260F2244A1E0B791072
-:10BAF0001EA99B842008E206A4A2222EF8E015923B
-:10BB000008B6C66ACD622202F5B6516CAF6DD16F30
-:10BB10004141DADA6B8A41B1025D10115AAAAB8257
-:10BB2000A246BA52AB50031B41052ABDDEFFFFCF30
-:10BB30004CB233243CFCAEDFD7E423C733E7CC3927
-:10BB4000FFFB75CE18498599ADB9004DDB4EE587F1
-:10BB5000B1056806280648526D00FD004E6CFDFADE
-:10BB600090944CAD5D853480BAED710045D8FE31BE
-:10BB70002600124064DBA9129F13E01BFAB912A041
-:10BB8000A3119718D6DD37B71D9B3F2CB917A7D443
-:10BB9000BCF041FEAFB1ED78E1BDEC97A9FFE2BB8F
-:10BBA000433EC0B6D606BE565C2F120F3337213C3B
-:10BBB0009144F000EE5FF7F2E8A796E1FE8BDB3EE2
-:10BBC0009F4DFBD76C1D0532F62BFFF4EFFC30CDFB
-:10BBD000DF2479C4F3F88003E1AADC7E463CDF7EF3
-:10BBE0002A1FB0FD6C93149413B0FF807D7E80D625
-:10BBF000ED05EF118477F17F22DE3B6CB7E278C36D
-:10BC00005095E1EBC67B870DF208DFBDB3697E641A
-:10BC10007BBCCB9E46F0FD7B0844E17F21BCBDFF91
-:10BC2000B1FC3E3FDE007E86DB2A7B1DE908DFC3D8
-:10BC3000100CA9D83E0830B1D5792E3C3FA6C16280
-:10BC40007A0F42D01F4006F123272F9C0209D4AE61
-:10BC5000FA5CCEA7F7A74D4C4338FCAAC5BD5EA53C
-:10BC60001916A6C38AC1EEC02A840B14EFFCB5D8FE
-:10BC7000B70EAD71AFE215EE042801F881435BAF5A
-:10BC8000FF948912AED7B40CE1C2759AFA595C4D93
-:10BC9000B88EA25A82F67C6E3FA2F6A1FE57EFA1A3
-:10BCA0007D15A70D82DABBDFE03F27603F47EBE35E
-:10BCB0007EB199517DFC17033B5D0AEE1FE35620D0
-:10BCC0008028D921EA7D9C7F93EA62BAC442C0EF02
-:10BCD000725E3A9D7E4F83FD7AA793993E3ADDCE00
-:10BCE000A1138083DE57E8BF08FFE45521D2430546
-:10BCF000147F58E0237D23113DDD290E5CCFDAE768
-:10BD00000EF72A899FAB4A89F69E85FE2C31D01703
-:10BD1000E9E789C9EFA673D47A8CBF99CE974A5FB9
-:10BD20009D2F31308DF91C33D8E90E20FC0FAA82EB
-:10BD3000EE0F22DD25A99BBE3ADDCC7CF093EC14FE
-:10BD400077D3BFBB1DE7FA64383312BE41E2FA2B4A
-:10BD500020A71ED7A992C785FDB8FE89D238B79D06
-:10BD6000F44582A03412DBF2FE15807874A4DA1454
-:10BD70006ACB3A11A72878AF3CED00250ABF72487C
-:10BD800034F43B52B3F9FD4AC740C37B1D034B1D3E
-:10BD9000F4BCCA956698FF464C423E14D07B1326ED
-:10BDA000D2F85529971BDE9B7AB863CD1C6CAF95F2
-:10BDB000C245241C1D7B675510BD26A9230CF3B674
-:10BDC000A059217DEEAC9203EB901ED552B07F3E80
-:10BDD000D26D72CE68237C128C273C6B2C285A388B
-:10BDE000EF1A77B961FCDAD2498675AB3DD5867E0C
-:10BDF0004DC357A0F40518DB70169442B4E3C15646
-:10BE0000C3FB857BB618E627EC03391EDB11FBD597
-:10BE1000266A0BDB434924BEB6BE0EBFA50F8A704F
-:10BE2000D85B89E840C991FA57A86D70203DF0F9B8
-:10BE3000A918D122BF58CEFD8762024D08EF294BC9
-:10BE4000C04774B85B0EE4501B3BE88E7C48073853
-:10BE50009AF2B0DC87E0075FA78A7230FA8B401352
-:10BE6000F5AF3CDB2AFBC80E6F94FDB602E2FB94F3
-:10BE7000B8BF92DD6D9580F85EE3B47802E4B792C6
-:10BE80005AF39746C9D7673F845BBCB9E7EAEB8BA7
-:10BE900059E596345CBF39C5D3B283EC66C587B328
-:10BEA000E5F473E7814BE90CEB7449A7F7BC4583D4
-:10BEB000511EE5F8F10EB2EBB19532E30557590387
-:10BEC000EB719DE516778CA6FCEC5F5D13AC6B49BE
-:10BED000AFD7A409FB10FB175025843FB6AF4FCE58
-:10BEE000A3F77E26C17AE8DEEFD652603CB2D22CB0
-:10BEF000420F1457BF9BF3E8FD787EBFA454D011C6
-:10BF0000A6580259B864C241F76E2BF657E7EC7792
-:10BF10009119689B72D82F235DDA0E86CA24D4A5A6
-:10BF2000010F979FCC14F3210BFB6D39E3E3F2D89B
-:10BF30008FE558C8CE2C41B347766647D93339E4EC
-:10BF400027965C7EC500E8C1BEE96DC26909D4C20E
-:10BF5000EEFE9A3495E14A50C2407A9D705AE171E2
-:10BF600068C8B690FDD1D74F98A5BEBB94E0D86302
-:10BF7000852CDA5EF12C223C565DD1AEAE623C04DB
-:10BF8000DE00E1142FA2FA4FF4932A315609A7DC00
-:10BF90001C7F2E1CFFDC589CA8221E7DCBDD896EE9
-:10BFA0006A7F8F441FC374F7131D7E4A7F2EA3DE62
-:10BFB000DAD0781CDF4836518C0701E57A954D1BA5
-:10BFC000279382FDBE9236EE5FEB1D4F7C958DF37D
-:10BFD0000BD2BBE67B1C29DDEB7BD7AE0D35F748DA
-:10BFE0004F3BFBE55513AC01BB7431748DBB005D59
-:10BFF00013045DCFA2F5C77DEE72887D3E96D421F5
-:10C00000246FAB2D68053200F6BB7CD7935CC7CAA2
-:10C01000C13C7A3E37C133A00CE5AFCDE619720FB3
-:10C02000D9956D31EE75F85EF59D9F3DDE407A3D08
-:10C03000F59F39CD24378A276E24EE53E7FA8AED2F
-:10C0400041959CDB87E29D2E3A923CE39E3FB5747E
-:10C05000F7C93E2474D3D59389E3ABA2E8EC709082
-:10C06000FD12FD47D3DABC4CA7DB1C4CA7A59A4EAA
-:10C070003527428B05F5E1A46BC3F7491E4E6EB41C
-:10C0800002C54D6D3448FE32C7C17A05C9E1946AD4
-:10C09000D483BC372D5E8ACBDA513E3C241FF5D9C0
-:10C0A00086F54E8E7B37290FDF3B99AC24117D1628
-:10C0B000866D4CB79B1508DAD15EB625DF5659CE92
-:10C0C000FAA1F278ABB6CE6B599EFBD2D8EF8C7743
-:10C0D0007D8278499E31F237C37BE71779D04F7460
-:10C0E000FB8874AE2334937A9783E6724780E2CC60
-:10C0F000BAD265B9E41F9624660F00C4A36EBCC40F
-:10C10000FEB6AEE10BA6BBBEBE725A06B56F777F18
-:10C110007C86CAF640513C2C0FCA691B8FD7349CD1
-:10C12000643B8EE0A491DE742C13F6AEC50AB754BE
-:10C13000635BF3BFF22DD538BF06430CF617B0D3BF
-:10C14000B624CA1E42EBE75D76BF0079B77ACA5BB8
-:10C15000B16467AB25D70C401C8EA6BBAA95D1D87D
-:10C160008F71CD90B0DFB6EE8C97FBA9AE1916ECAF
-:10C17000EF4ABB498C0F74FDDCE206F87CDD5DA262
-:10C180009FE63A40FD0FD31EA95606623F5EC8C126
-:10C190006FD26AABFDB9245F4EA6CB891571AC1F77
-:10C1A000BDD1795EC3CB06BA9C332E4BB778C96E2E
-:10C1B000CC1476F1D8CA416B391ECA0C65D39E5B8C
-:10C1C000D344FCDA1F79538AFF5E45BD77201D9268
-:10C1D00033C063C1F9C92FA23FA2F91F878610FDA2
-:10C1E000E6BD181394901F8B9F78C546FE68AEACD1
-:10C1F00066935EBD3FCCB793E4E3787C88FBF31A8B
-:10C20000B6335C29592E61A75D9DB95E94CFF9D0F4
-:10C2100062A3F1F9A01C26BF614161A6B866A173B3
-:10C22000978DE2B2854F5B0F87A3FCEA22081F229D
-:10C230003DAD79D67A381CE57F81DE8F92AFC3168B
-:10C240000187A2D163AE1C9A6D13701D20B816270A
-:10C25000617C2F93BB08F5F7715C5493C379494A0D
-:10C260002C90DC2DBFECFD7C5F0F7EB0B511FD3E48
-:10C27000AADCA6C62DDCAEC135C9EE0C50C23637DD
-:10C28000AE53ABD9E592D0611B44BD7F42A36B9FF7
-:10C290002D128FEBF6A27B3C5ED025D733C2827085
-:10C2A0002C9EB66F1CF145E7E79571D01A93C47CBC
-:10C2B000716B7C71135F74FA233D0B157C6FD7593A
-:10C2C0007C2FAD27B9D0E92FE06D8B15F6A27373E3
-:10C2D0000CC74D66F8E3D205BC3A1E43D3CF0FFF1F
-:10C2E000D0F4EF06FEA1E9428FCD78E87AAC3FD7D3
-:10C2F000F5D88CB70EF7A5CB59C8763172A6DB9965
-:10C300005AF0E5D0FABA5DD1E9ACC3A9D3AB8DF24E
-:10C31000A11EE0541A5E32E0A3842A28898071E9C4
-:10C32000E9C28EB54E02E283D2B095E75D2A3EBAED
-:10C33000BDED0D2FDDCE9AF1D3EDAD8EA76E7775E5
-:10C340007CCBD090B03DC4349EF2AC2B4FFB0C7133
-:10C3500070392C30C4C9958E3B0DFD2AD73D86F926
-:10C3600057A52C338C4F52571AC627E73C62E85F1B
-:10C37000E3FEA5298E5F6B8AE37F63181F170E719A
-:10C38000DCFD7AE344509047DF3BD2C9F177B0D16E
-:10C39000C5FD9D8D29DCEE6A5459BF7737E670BB29
-:10C3A000A7D1CDCFFFDC58CAEDBE460FB7A1462FAF
-:10C3B000B766BB30F5F9EB15CA574A432D9564CAE9
-:10C3C0007764F87E928EF47BC312688A473A8D6A4E
-:10C3D00017F139CC37FBE35387EE25BFEEB2B9C96D
-:10C3E0001F36EF182DA93DC47309E8EF3C51F292B6
-:10C3F00030250C1E8A7BD03DF7245F2DE916964729
-:10C4000032FB807A37D301D664D4B79933257713BA
-:10C41000F0733F24711BF4E1F85405FCE4FFAB9D7D
-:10C420004AD09EC0A0791D08E70C0126D8699CFC63
-:10C4300077725F85E2D6EBE821C22B7B64F81E3E63
-:10C440009F51FA97339437DFE86CB5929CDCB0E7E4
-:10C450008163F7E23834FB8B493FBAE206FFFB9673
-:10C460004B891B5A28AE443A462477C843F14EA262
-:10C47000E28ECE07F4F6B674910F4C6DF2CB0948FC
-:10C48000CFCE3781E3385D1F11BF1504BFAE17D57E
-:10C490002E25382C81FCFD239534BF66BFCA74D18C
-:10C4A000F542D7033D0FD4F5A04A7EB689E69F3802
-:10C4B000089C4F8FEAF01D799EF034C59DA59D2DF7
-:10C4C0009594975D286F1C73BAF5159AB7BDD1C7BF
-:10C4D00072B4B57126B7C1C6F99A7CD6737F57631B
-:10C4E00003F77737FAB9DDD3B84293CF161EDFD7FB
-:10C4F000F838F75F6F0C6872BA919F8FCF10FEF714
-:10C500008B50E50092BF17D3451D071CE59C478063
-:10C5100022DA8B95939A9497453C65920FB35CE829
-:10C52000F200683724A4D78DE867C93FDC04FEBC5D
-:10C5300039D8CE9CD7621D2B7D7BB958E86CE6F8C4
-:10C54000C36C0F174090EDDDB9F65DC4FF17B2EF75
-:10C5500032E6ABE4AF74FBB718C2BC9E5DBED34DF0
-:10C56000F594EFCEAFB834BF0273687E57DE1DDBA3
-:10C570003E5BB65C38EF2E1A2CF8AAE7DD183F02B6
-:10C58000F9E54840E6B87A7E5A4B02E7DDA59D09F9
-:10C5900014072CD826333F30CF540622DFE6697CBF
-:10C5A000EB80E03BC49779E3E6715D6EFE1A233EB3
-:10C5B0000B9DD7F509AA3DC6693DE2590B0F7F4E89
-:10C5C000F5B95A8D5EFC1CE16968BF61D2AEA879ED
-:10C5D0003119F1C99FC49142C128A207C2EF0E923E
-:10C5E0009EED9759CF7A938BE3989F909C9F6A9C7E
-:10C5F000396917CAFDF1B38D9C7F25653CF2887FB0
-:10C60000DC77C7AFB559DEA1199C0F856DA43F3A01
-:10C61000FF96938D44B8975738029468478A5D0A0D
-:10C62000ED1F913C723CF1E323702F43FA956F7D2F
-:10C63000ED20E947B9C3C9E708884447343F47EFCD
-:10C64000F7353971DEA87D1E99C2F7E25DE1269AC1
-:10C65000A6FB1BDDFF8CEDE8947D5C17C8643D02F2
-:10C66000CC25BEC9B8783D32E79B4D946FA2413AC4
-:10C67000E99CC0F09E0C829B9E77D7B544BD69ECC7
-:10C68000598F9C80F02DD7F2C3D11F7B198E6A87FA
-:10C69000CA7268D7F2497B8A053C517474D97C1BF5
-:10C6A000A9FE097F8CE13AAF19BEC919C28EAB4908
-:10C6B000DEC94C5FA79A4D794395DCB1E1D7240FD1
-:10C6C0006D716E3BBE67B6B7BA7DEB2D6EAF739DD5
-:10C6D000EC318ED4DB3A8B38371859A91652FE4705
-:10C6E000F125E5857A9E689EEFCBAA989DD18FEBC8
-:10C6F000AB210FC1E5B29C574EEB1A3E3F6F9EA691
-:10C70000EF5FB7ADD83537AA0EB226433F5F505C16
-:10C710009F38BAF976B1FC2DEB9C69F03FFFE9F147
-:10C72000DA540C7324D4A13C2920E20810F1C42C63
-:10C7300008713B1B3AB9F5A124513B17DCDCDE063E
-:10C740005E6EBFCEF4AD26B989583BFB931E1F7BAE
-:10C75000E1EB5C928B63DF1BEB4A53BBFDABEE6FEF
-:10C760002FD5AFC6D2F9520FF2B041935BDD6EF711
-:10C77000CA1F93DD8E8C40FB807046368B73B148A8
-:10C780007C6C80CE0174FB007E63BCA8DB8BC2593D
-:10C79000EE37B85EB84FE6BAA5D97E5429228F0786
-:10C7A000C59D43F5517DFF260BCC2739DB88ED1F56
-:10C7B000108F3EB3C28A1A85CF760D8FF21BC60347
-:10C7C000E52F535D223F9CEA80E4D364DBCE9ECC10
-:10C7D0009D8186602AC5A328CFA3923C7F227AFB45
-:10C7E0001F1A97C8E70F647F8622FF3E12E736B014
-:10C7F000400A64213DB6B4897EDEED898CDF4D10A0
-:10C80000643EDE0C612BE17F0B00DBDD39A0727B27
-:10C810002B78989FB8725C3EDAA1DBDB9491AB1069
-:10C82000CF82A4CE74D2CFBCD1EF254908573EC5E4
-:10C83000BF4EAECDACA03845C7C39229F0B82CD3BB
-:10C84000F336C15790145AB59AE2C2CD16A0B8F08B
-:10C85000D3D1F7DC01517EB524ABE220CD7B4E1263
-:10C86000E785FE6D76515783CEFEDEA878FCEBCCD3
-:10C87000CA43A4F7FF20D838FF5DC5E748D52E414D
-:10C880007B18DF8F6980EF0DF1E6F5A49F7EB68FF0
-:10C8900005444B5127F44329EFCBFDAF9EFAA2BAD2
-:10C8A00059E0E3A778AC24CB17A1FD0A6C680A090C
-:10C8B000FE27EC81751C37D50FA1FAC5BC27ED16F4
-:10C8C000F2E3EFA11DA673D30F1A1DDC7E88F90DCC
-:10C8D000B57FC3FC86DA8F30BFA1F6EF98DF507BBF
-:10C8E000FBE9112844003FCCF4FC6FC679F0E8DD89
-:10C8F000CE083C2212CCECE9BCEF5486C83FF2DBF8
-:10C900003E7E208EE4608BEC2639CDDBAC701DE2E0
-:10C91000F8D65101392D9AAEBEB84C84237FCBDBBB
-:10C920008F8E2DA2F7149784F38F6F39D99FF3263A
-:10C93000137C5DF4D86613F4D0E07D2E31B48ADE2A
-:10C940007F6E733A41887604841C123F7BA8A30152
-:10C950002C633EBE9E21E2A76BED9D45D1E79B4037
-:10C960002103D52B353F53259F4D08E76A75DBD151
-:10C9700024D7996FD07EFE3D420F91AF86BA44A571
-:10C9800026877A9BB7CDE6257D7A6EDB3BD32623BF
-:10C990001DA68E99542CABDDF30B33FBF1BE79A3AE
-:10C9A000CFFC6A7532CFE7738B1B606D950BE7DDAB
-:10C9B000E4D8F12A91E066D7475589D8BF2545DAF2
-:10C9C0004DED1C356D4212D90108F03EB7E694EFEB
-:10C9D00026119BE2AEB6915F2E27A58AB2BB958E3B
-:10C9E000383A49EDEA57B9FA1AFA57A50C32CC9FF2
-:10C9F000A46618C627E70C378CEBFB4E71171AE6B6
-:10CA000091BE52DC8C7830DF61BDCCE732799BBFC0
-:10CA1000787F11E37F4311E11F41FAD930B03852DA
-:10CA2000BAF217ABC96C6CDE99C0E7B4A6F8B4666D
-:10CA3000DB53BB3D6AEFF1E997B0B5C7B8AEB69727
-:10CA4000B8EE62E353B41F8F92FD2878E13A3E7747
-:10CA50007F6EF499CB54C4CB9789712BD93D53DCAD
-:10CA60001AD1E256B3FC74C9A9A40AB9D92B03C5DB
-:10CA7000417AFC6A961F800734FF2FDA4BD5F3A961
-:10CA80006F097FF50FD2F7BED172ADB5A67A44819A
-:10CA90000DFD0AD509FF2AC33A7A7016E1D0E99F45
-:10CAA000D12DF770DBDA570716F1737F3C6E59AB67
-:10CAB000D5277E95A99DF3D7EC78756072F738DCA1
-:10CAC000F591613EDC27ED36F49BD38CFD87CB7767
-:10CAD00047BFDF9B1D9AB7E64E9B8FEAD28F893AFC
-:10CAE000A5795C87A76A678C87ECA5B2D5CEF9508B
-:10CAF000ADCBC3F513A597FA896E176E90A1BE272B
-:10CB0000FBB65E5B77CACE1890BFC5BAEFA1AC107A
-:10CB10003CFE17859F79AF8F07BC51FBB4668AB87E
-:10CB2000EF5862CB8FBFC279C75E023791FE58A221
-:10CB3000B0B7F96D9F5A2CE4276285BCE4BBC2965E
-:10CB400024BAEF323FCE4FE7C9750BE2FD746E5445
-:10CB500090DEF98E0359BFE569DFA30E94BBF72D74
-:10CB60001683DF8990ADC3FE8E4CDF34F23B9377A2
-:10CB7000C6042DDF029F1D9920FC5A85D0F7D924C9
-:10CB800037FAB9189A9ABA07C1704E46F853FFCCD3
-:10CB9000D3B7BEF518C5BD7B85FEE3B0D39C8FDE51
-:10CBA00014958FC21AA1BF0EFCA53867E1AE161B03
-:10CBB000E549DF95DEB7673ABBF57BD8B9FAACEB50
-:10CBC0007BDD01A1EF27B67EF916D9F513E8EFA2B8
-:10CBD000F5BDCB2F6A7A5EF7B8CCFAA83F3FBE55B9
-:10CBE0009E18E881BEAF697200AE6CC3B9D992B22B
-:10CBF00053D3C8AF2DD9A6F079606FFEBA6E85F118
-:10CC00009CECB9EDF6F9E21C59E011D1FDE9B62F23
-:10CC100093CA7345BB8CCF6B5B34BB23E218F4A380
-:10CC2000D664F2A3D512D7DF0E6C1BC0F7330E48C3
-:10CC3000105447F212D739906FD3C572F4DC49F122
-:10CC400018A4E428B4CF348D9FD3B5BAD08C6D33FB
-:10CC5000B2885FEFB4CD3DE021F4B232587EAE072A
-:10CC60003FC7830712BDA9744F616A9390EF038990
-:10CC70009D1D54473A501627D17914AEDF1C1DEF85
-:10CC80001DB07A53EB192FFD7CF20AF99BB84BC803
-:10CC900083357B88FCF44B229F63F957063ECC72A8
-:10CCA000B50002BB3DB86FAD3BC871E9221079BD3C
-:10CCB000399EAF1DF7998DFC8239FF2CDFB2E3203E
-:10CCC0009D7B9C538730C9EB85EA0EE6BCB7B7FA6B
-:10CCD000C1A8246F615654DDCF1C9F77C5A17A1C73
-:10CCE000B53E8ECF855E29FBEFE38BB07FD7FA3858
-:10CCF00017E5D9479FB4FBC92E1F5D670F48387EE3
-:10CD000034A9B39DF28EA39BF2DCB802CCB3A8BFCA
-:10CD10007B96FCFA6FAD2C1700C67B0D4BCAEEE676
-:10CD2000FB7F4BD6C74B740F0752C4B89EF3C9CFD5
-:10CD3000C4735CB0E0F9817CCEA9FB17D20F3A979F
-:10CD40003EF2448C8782FCA37BA6F7A17A5F87E53D
-:10CD50000F7C9E0FF27D87E8BC7ED186F891143F50
-:10CD6000402E30DFE6AFBB9CCF377FAEF86610FEBB
-:10CD700095CF5C3380EE952D78BB1F103E91ADCFE3
-:10CD8000F3F95F779CDE737C77626B461FC8EDA674
-:10CD9000935E075CF1F4322FF1BD5852C5390DD4C2
-:10CDA0007B06915C6CA9065A77A42CEE8D76AE8C2E
-:10CDB000E3B8D42C773559220EACD1EB0D7DC1915F
-:10CDC00042FAE303A64364E5F075741ED69C95A46D
-:10CDD000F9E9CEEC6951F712ABE4F6DA97493ED7A0
-:10CDE000D8B90ED211D3F33958435622CF9FE7302A
-:10CDF0009E9BD7369C31F67331BFC3F74736A98562
-:10CE00007762BB54A3FFEA54EFBD59F8FEC2D64780
-:10CE10005ED8C77459F3C3F769DF3D4E517FD927F8
-:10CE2000E8678EFFE739449D03602DEFAF3FFFF4C5
-:10CE30008977F97CF5D3CDC3B3C5B971E8935FA702
-:10CE4000F179F1A17BB1DDB4E72DE68B19DE73CE6C
-:10CE5000FD2489F1AD213CFAD2F9AEF71182131904
-:10CE6000C179DBDC55794C3FFDFC2D72B4E7FC4405
-:10CE700087535F5F874F5F5F9FF76496C863666BFA
-:10CE8000F9C1315BE8389FA3BF305CA2FA5ED7F3EB
-:10CE9000A4507E6294BC7C57F5F41BB57AC841CB94
-:10CEA000B21FD8E89E5CEB6AAB2FDAEE5D621DBD67
-:10CEB0002B0EF480EAEA2F5C09FB2D444EE94FE784
-:10CEC0007D5A9F9401FBE334F0248287EE0D6A2D96
-:10CED0002CF4A5709D9CD693E91A6280FB4DE56EFB
-:10CEE00095DA2B25AF22EE7D0558FE2740FD60C266
-:10CEF000C3E208F3B9987ECF6546E2F26BD270BF09
-:10CF0000E67EB09CE29866ABD00BFF9C38CEDF7417
-:10CF10003AE97E065CB906FFD2EC0255C175662A75
-:10CF2000B0C29A24E60D453A1FD833F7558A13DE6E
-:10CF300055EAFBD1BEEF391FCB932C14DF05E22954
-:10CF4000477CFFADDF16FF15E77E009E3227CACF74
-:10CF500075AF39D8EE9BEB11B7838FFBF3206CFDD7
-:10CF600002DFFBDBE87FADDF09DD78FD6DCC579B91
-:10CF7000293FB829F181627A5FBF8769BEEF77D414
-:10CF8000E5E47B81E67B7FD782EF33B25BA72CBEE3
-:10CF90005A51FFA81F45FE3792680309E747FA690F
-:10CFA000F438064C8F88557BFF7395FB459523B964
-:10CFB0001E09A754B6C7634DFEA668B845E461DFF5
-:10CFC00088F9659D8AC1DF141568759BAF558E4B36
-:10CFD000AF3CAD9CD71F3D942DEC59515F4B7D4F1D
-:10CFE000F1A19A2DF4A70982B2C047C40963BBE43A
-:10CFF000CA2313FF6AB57E2DF93394A74882C34F25
-:10D00000171DC76E15F2355609EEA016AD2B34501C
-:10D010005CB105FD9D0E079D11A60C673918A3CBC9
-:10D0200027AE350BE72D97EA396F71503C83ED2A17
-:10D0300029C4707C0F3AB9F5687EBC02DCDC8E072F
-:10D040002FB7289FDC4E84166EAF86566EA74048D9
-:10D05000F8FD2B824DECCFE03E179F5B4C9A67A109
-:10D0600078A3E8FA9EF3850A8D4EBDD30115AEE490
-:10D07000D2E9300150EF327AA0C7E01CB61F667AC1
-:10D0800098F5B30CC232EB2719860CAA13A8ACA7EB
-:10D0900095E0E17ED545D2A134EC53B84E63A64766
-:10D0A00065CF723159A3C7BFB281E543E7D3FDD93C
-:10D0B0002A3FD7F9857A9542F26FE6A3FEBC28AEE7
-:10D0C000E2245D4DBF237BF874BA57555458B19490
-:10D0D0004CF2DD1BC64CA77B5545632B9EA723CF87
-:10D0E0007BB2C7897E4145A1D58D598B54367D3C95
-:10D0F000CEF769F79261A688AFEFD2E216DFB21FD2
-:10D10000B85DA827BE54A79BF07360704FF759E431
-:10D110000C713E38646270A715E71D527C73B2290A
-:10D120003E70041354A4FB5DCBAAF8DEDA4336311B
-:10D13000DF6E1775581D2F7CEE8FC1FEA64DC3976D
-:10D140004AE9BDEF8FEBD6D2BABE65597ED257DF22
-:10D1500066C92D3859316026EA6747C80A540FD589
-:10D16000F7C94EF52DCDE673DD6CAE930DD2E29985
-:10D170008E4DC387135FEECFD6EE6125A71512DD66
-:10D1800096A57AEFA7F99178215FF76B7CE8ADDD82
-:10D1900090EDB92FBBF8DCE7917F2000F8FECFB20D
-:10D1A0007D0FD07A757167D9BF1F1FF1F6F2705AE3
-:10D1B000B79C4AC8A459887793070236F603DA7DEC
-:10D1C00075EDBC2A723BAE837428F2FA9AC8A48D1E
-:10D1D0009AD55942F613D7FD2F5ED7161E3202DFBD
-:10D1E0007B6CFA219B90B3C142CE343BB46DFBDE25
-:10D1F0007B0789AE17A2F4AA6EFB99AF3E40FAD521
-:10D200009D70BA697AB73EFD7229E793E034D80D74
-:10D210005DCFC66CB1735C3D76EBE5B7D3BCB2B7FE
-:10D22000DB3308AF2BDBC37C0E16D9F6EE2001876B
-:10D230009E6F9C92BE8DDFA5735ACEE3368B73DA58
-:10D240002552FD2BF1D4FFBDE4F623FC9F6A7E43FB
-:10D25000CF8BE76B782DDEBB7E39D545E6AFB97550
-:10D260000ADFE30988BC41C55FD2FF2F611F9F8F92
-:10D270002FDA68CE273A6DC4FFC5ADA6FB40940FE8
-:10D28000D3BD8768FBDE433EBC3D5B3BA74D855469
-:10D29000C6439ED5C7D783BD33E7BB8F83E755967B
-:10D2A0004FF0CAB47FB1D2733DE1B9EEEF69581FB8
-:10D2B000E6697B139D9C9CEFDAC47DE12796BA5DFD
-:10D2C000D4D7F4732DCA4A29C5D19DBF64F9D7DFDD
-:10D2D000D3F575C10A712F1BD6F465992BD860F769
-:10D2E000105F0B360CE0FC02F3208EFBD66EB0AF65
-:10D2F000A07ED383B17EB980EAC99D97515DA529EF
-:10D30000467CE744EE91EE8916A48B3AC719DDAE50
-:10D310006B7E5DBF6FDB95FFC467F3BDE6AEF1B01A
-:10D3200062C8379AB4F8B988E0A338B0DE2AF2A709
-:10D330001801FF8E37BF1F4771EC66C51B4775E9A3
-:10D3400013FBD3FB400F74D3DB62742F709E73C644
-:10D35000E277A7649C8F5F458F6BF7D335F9FC6349
-:10D36000A307FE6EEDE6878E5795FC6CA58DEA1C33
-:10D37000B7818BEA1E4BF63ED544DFDB2C59095CA6
-:10D380005138417F285F3862E173F0317B0B53489D
-:10D390001EDB347B47E7C26A945C95505108E7175F
-:10D3A0000F86007D7F14A3C6821A9517C7E524193E
-:10D3B000FAF1EECB0CEFF7294D378C83DF13CA2D32
-:10D3C000E98E5F133D5718E63F943081BFC7290BA4
-:10D3D000DDC175A5BE13471AC6ED28D774CF01BEAF
-:10D3E00010F14F29FEB25F857A99E01C1B06F815F3
-:10D3F000CADD980E637C541A6EE13C3066BF62C889
-:10D40000EBED17A8335D3E4CD3ABC13058D8073392
-:10D41000BD8DF72196EC95398E5B928A81675AEF24
-:10D42000F4D6F54FA77B3FAF91EE03661AE93CD0E7
-:10D4300067A4F3A0F9463AA7D61BE93CB4C148D784
-:10D4400034BF918E192BC618E667B55418FAC31E5F
-:10D45000BFDA30FFF2C034437FF8C61B0DF3F35A36
-:10D46000E71AC60BB62C3C2FDF47049718C6CD7CB5
-:10D470002FDCF323931C2A4CE762EDFB2C9DFF7EEF
-:10D48000FC25FE8F056F9FA044E5407F13E9E3FF75
-:10D4900017FF170CD3CE1174FE5FA45DBD4AF3C312
-:10D4A000E6EFBCA6C6097BF3FA9E13FB3DD87F438B
-:10D4B0002DB4A650DCA4C5075EFD3CC294F7E97903
-:10D4C000CAB5A592E99C3EC6704E7FA17B6DC5A1F1
-:10D4D000A0A13F62BFF83E6AE441F72BD4167FEC6F
-:10D4E00091A3BF871AFD05BBE573F24EFD7E9C9E9E
-:10D4F0003741F3939C87CED2E127252839B7BEA8C0
-:10D50000E7A7E6BC55CF57CFFDDE4AC42577CBBD94
-:10D51000E5B1227FD5F3D6EF8387BF2BBB6AB06F0F
-:10D52000ED30B4FFB2A5B32F8DEBF92C1196CE8D53
-:10D53000234458FE6EE69DE99E5CFE1E95EBDE0BD5
-:10D54000A5B7A7D33D7F04DF152E11E51FFA796932
-:10D5500098EF77B4DE61C9B5BC10DF7D7DCC674341
-:10D5600068BDFF1926E237BB8C1442FF3360960773
-:10D57000E8F9A824CF7334DF7C3FDBDC9AEF0DB5EC
-:10D580003506B9555C6EBEB763AE0F862D2AC79DB2
-:10D59000FE1F497C4FE733026E7477BC726285953B
-:10D5A000E315D0F2F19B35FAEB758B591A3E877172
-:10D5B00089F9E87F6FDEF21AF365514A8756EFA8C2
-:10D5C000E7F8FAD6C1CE917C0FCD53E816752EBD83
-:10D5D0008E31E892BE2FB910FE8B528E1AEA48F0B7
-:10D5E0006CDF8B3ADFEEC65BAC7F78A5A8471E5E8A
-:10D5F00099CAF5EFEEF58F733DE9E6FA370D7A71CA
-:10D600004BC37B063D98E3FFC8301E4EEEB452FD7F
-:10D6100030FCC2C0093721FD8E6DB6F3F7D0280764
-:10D620001DC4577DFDF0CAE1E3F9BBCA0BE2F9194D
-:10D63000C3D1DE1862FEEA781E6A3CC8FD706398AA
-:10D640005B339E7A9D426F6D3B2187EEE7774AB14F
-:10D650006EAA0B9BEB17775BD44F480F1ECA49D7B6
-:10D66000E2B5FA022FF34FD42BDAB5EF4BDBB5EF6F
-:10D670004BDBB5EF45DBB5EF43DBB5EF402356E7BA
-:10D680000AAA6BB44BE2DECF2CC9F3E41CDC2F6D8D
-:10D69000B0CF994371FFC2CE7C05F7A92B08CF9676
-:10D6A00090CF79FD7C7DE8B984E9C240FE9EC8CF69
-:10D6B000F7C38E58FCF9F4FDCDE48D59D7511E788F
-:10D6C00024D67F9C2291CA9CB4EB28EF3B62137A4C
-:10D6D000387D63EC75A4771FE362849FFF2549D4EE
-:10D6E000959C611B7D3F3535D93728A758DCFBE277
-:10D6F000EF66F039C9A55EE78C58451C18D1E2C128
-:10D70000F41C710E989123E256BD2D239EE3F3E99C
-:10D71000D4B27E3E9CCDDF9BACB103C5AFB83F7F9A
-:10D720005FA3DF33317F7F33F24F76FE4E42AF8708
-:10D7300096E4A4F13AF45D0EE965F24FE2D86E4149
-:10D74000383484BEE3E98277BFF8AEF218D591A3EE
-:10D75000EACF2539A20E03B781E13BA0C57B0F1F9D
-:10D76000A23CEBFD61BE3144D7B916B584F8BA3896
-:10D770006107D7BBA6E4A8BC2FC2CBF8A2FD6926DF
-:10D780003E2D7684B93E76A17A786FF81FBB3DF4C2
-:10D790008B5CAEFFAAF9FC1D9EB62FC23185E8AFA7
-:10D7A000E3ADC3D1BDCEF9E55FAFEBEAFD4F9F78A6
-:10D7B000285BABCBDFE2EDC19FDEAAD1A5DDDA733A
-:10D7C0001DFD7E8DBFE7F0671800D5EDEDB1E823B4
-:10D7D000B0ADD7E874EC06C487EB139E11C4DFC567
-:10D7E000D39CFCFDB9BE3EAEE3FBC379F6599DEA7E
-:10D7F0005D48F82FAC1775777D3C2209BEFA578A31
-:10D800003AE8E2EDEF1DA2FF0FC28267F20A39BFCC
-:10D81000D7DE37D319E9CBDF45CD95C5B915D2F79A
-:10D820006EE2B3B9DEFE6DE91A4915E7AB91B56753
-:10D8300086D03DB2C5746F8DBE0FD3EA57D066ACAB
-:10D840004B21BDFC54AF38F73C0AF85CCBAEF91164
-:10D85000BBFEFE60C5F0FE31A7F7A7449F1734BB9F
-:10D8600081F30316DCBF4DCF934D7594B690A87726
-:10D87000B6A5D8384EA67887FC931EEFDCF5A6A88F
-:10D8800077DE9526E268828FF82B1DDCCD714297FA
-:10D89000FF97DC2AD1CF69F505687FF02D65FF255C
-:10D8A0000F45FED2F9C59FAFD6EA01C21F166BFE27
-:10D8B000AF98D6A10027B70FFBC5226D5F8C1FB9AB
-:10D8C000EE361A7C4D0218AD6EB672B7A18EF07F9F
-:10D8D000947817F25045000000000000000000009E
-:10D8E0001F8B080000000000000BFB51CFC0F003AD
-:10D8F0000917B1A1F26FA0F1533951F9BF5951F98C
-:10D9000097D0F884B02E1303C30A46D2F420E39DC7
-:10D9100040FD0780F838109F6322DF1C103E2CCC9E
-:10D92000C0F04D8C81610E906E03D2E781F83B1000
-:10D93000DF05F2C5441818548178A12803430C90E0
-:10D940005E0EC44522107D4780749D2879766AF268
-:10D9500050E6E6514C195E2D8DCA2F5701A647554A
-:10D960000686B76A10FE622479267506860A1508AF
-:10D97000DB408E81A10BA866B63476730D81F2DD93
-:10D9800040792175081F00B5882CEC680300000061
-:10D9900000000000000000001F8B080000000000D5
-:10D9A000000BCD7D097855D5B5F03EC39D879C24ED
-:10D9B000377033C9490C1835C04D0C838878120371
-:10D9C000064DF106D1C6FEB45ED0DA481922F26ADD
-:10D9D000B4B6B94012C2A441B4A568E98D554B79DB
-:10D9E000B646C53EDAA7F482F8446B6BB4D4E1695D
-:10D9F000FF469EB5D65FF9E280536DF9D75A7B9FFB
-:10DA0000E49C939B04B5EF7D0F87C33E670F6BAF1C
-:10DA1000BDE6BDF6BE6ED9C5D804C64EE09FF3186C
-:10DA2000BB5A628CE50D3D9937D6C4228C356B6E9E
-:10DA30007D530963DF546287F56A783F5E8EDDA30C
-:10DA4000E3FB49752CCC9882F5F3198BE1FFA0DD3F
-:10DA5000FAE0BA718920BC531667E1D3ECDF7C365B
-:10DA6000AB8C6955F87DCBA44CDFCD274BB906FABA
-:10DA7000BD8CFE9C2865ACF59597261F32CBF05FD8
-:10DA8000010B455E0FC05F66B0192714C6DE0D2E70
-:10DA9000CC4AB391FB7BB3ADFB4C7522631FB6BD83
-:10DAA00038F9D0C4E1DFBFA9B096DE8AE1EF673074
-:10DAB00018741AE223E98E4F1E9AF7E03C8380A483
-:10DAC000B3A13D63694F0E3C776F3B532D1F82D34B
-:10DAD000390FC6921CBF9FB39D27529B2E8052A523
-:10DAE00094984D70A9F0CF74C6A82AACCBB2DD8D46
-:10DAF0008CE072C0DB11F9E7C03BE27A897AEF066D
-:10DB0000D7753268B7DEC5E9A53D4F8EAD63C3E971
-:10DB1000C55C0F138F27BB1E37301F8D63D251B3E7
-:10DB2000BC78D4751F8B8EAE443A3AF3BF9F8E9269
-:10DB3000FF7BE9A883FAF95F46478C75737CB17E59
-:10DB400015C71F7ACF9F91C5BD12D21914FB10EED5
-:10DB5000623E142B6EEDBC569E02628AC59E3C0D41
-:10DB6000E45671FF9206847BFC2BF3FF8ACFCE45EF
-:10DB7000B5F573617EF94DBDCF5E00CF483C2525DC
-:10DB800060BDB63319850AF4B73C5903F36BC7CEB1
-:10DB90006631766F728991C4F93283B1718CFD8BD5
-:10DBA000981363B2AE4239447FCD340F374B737C48
-:10DBB00048273CC3DB8F34FF10B633EB94E0FF57AC
-:10DBC000339CDF58EDD81A3E5E12FE417C170E8D55
-:10DBD0004FFDE4375BCA0CF163FFDE877F21FC5EFB
-:10DBE000FB3F325E01ABF2A17C0835C85A0AEBB3A9
-:10DBF000DE6C15CA91E52A4B838C28A8EE965CFA58
-:10DC0000D8EBD2C9587D2F5F1FA9313404DF9F990B
-:10DC100044F473CA8DAFF56C00923BBE381823FAFA
-:10DC2000D018CBCD193E9FDBDB90902DE545B5524A
-:10DC300082C68B3D5906ED938BB8DEDBDEB030DB60
-:10DC40002AAF3C9224F0E6A40FA6ABD391AD387D69
-:10DC5000A80DB2E19BF2C5E943FD9CF491B7C6D291
-:10DC60008E7DF6F58A9876C149D2C7171DCF5CD74D
-:10DC7000E17CB556AC6B998F01DFDE5ABF30A39DB6
-:10DC800031F2BA5611BF471A9891CAD02E7F703D13
-:10DC900093C39FB03ECAE0F25E675B2F65FCF4A6BB
-:10DCA0009E51F0A144ECF335FBF5B52AFA6BB9505F
-:10DCB000543519FB73637F40671BA3B72619F0C364
-:10DCC00071A46DC087D25D99C6322B63B17B040409
-:10DCD00032947D5123B589E82045EB62C2E7D165D6
-:10DCE0001BFED588DF56664D49C90ABFAFD54D70BA
-:10DCF000B8713CA07745830E01156A90A57D61AC93
-:10DD0000C1E1473238712A96BF6DA3832EBD8A6563
-:10DD10005A07935E11AD9C5EBF7D72F2C539DE225B
-:10DD20003BBC27DD2EA8EAAF5BF4D0C8ED54F6BAB1
-:10DD3000B93E80C4ABB0836943EBB4C1C5F6495367
-:10DD4000415F175DC612F076037E3A9BE894EC992A
-:10DD50000D45551AD215DB2DA908A7A947593487B7
-:10DD6000EA554A3AF5237B5B18D65382063DCDEF40
-:10DD700023C325E82F691C28837EBF24D6F74B4296
-:10DD8000AFB16AD76BFD26DCA467D5A132CCE3ED39
-:10DD90001BE07F4027C94A29758F34FC7B03EA4585
-:10DDA000904B0DF8DE2257760CF24194D6AB417CB5
-:10DDB0007BECE117269D05F4D11753188AAD750F3A
-:10DDC0007B8C3AE8FFD973A5944712F0029C0B04B0
-:10DDD0009C4F1BB9C548A77D751EA2E305177C188B
-:10DDE00041323EB6EFF76A267A5930DB350407FC3C
-:10DDF000B7CA3A3FF8EF2783EB5244E39870ADA8D7
-:10DE000052088EBED9520AC739F4C7BFDC7C0EC097
-:10DE1000F974B514F3E8046F88C1787DC67B91511D
-:10DE2000FD0E737C9D69884FE7F8E67A840B19E153
-:10DE300095FD09F00AE3256B07FAD7239E8F4AB1B7
-:10DE4000F5305ED69CD609384E892C13BC1B677BF7
-:10DE50006505E887BD384E467C06059F67B9BBBDA2
-:10DE6000A7029C9D13657617BCDA5836BA3C6B77CF
-:10DE7000C833558B1B12B4D7935A95320A5FA40C42
-:10DE8000B93E93BC7B4AE27AB223B9502BC3E91D59
-:10DE9000B2DB81A897E216BD0AF6E25312CCDF1579
-:10DEA000E1749C5D17E77662DF38925F01B11E591D
-:10DEB000531666B10C76F088F3808132D9CDD93211
-:10DEC000878FBDC2FB57CDFE7346EF7F83E8FFA36C
-:10DED0006689F5217C6ADC8BEBCF8C4AA267BFA0F8
-:10DEE0004FB62687CAA6DCF594C7BB4A601D3D51D4
-:10DEF00099E93ACE2F49EBBC19D6B80840F1D7C101
-:10DF000077A8BAF9EF0AD925D9F2F16412E0D87CE2
-:10DF1000E01AA6839DEA8FA61895275FED45FC6C55
-:10DF200006A5C0C7EF65387E00C816E56B00E4ABF8
-:10DF30008EF255EF4DCB5056EB59CC804F212D260C
-:10DF4000F981640E464BD7AAF0BE7D3123FA65688D
-:10DF50004558F0DB1E7DCE5000AECE2646764D678E
-:10DF6000A496E6D75E51EB2D417BA741A5F7EC5374
-:10DF7000C0876987803CF4973303C7DB9CCF52414D
-:10DF8000E4A5BA3CA247B7C6E7AFEF2863E9B3E020
-:10DF90007BF6F403387EF23B2C36910F49724D35F7
-:10DFA000E9424D2425F4EF5AB5D8A60C74B7832561
-:10DFB000B2E469363A25BDEBC45B969B5D88F8ED0B
-:10DFC000AC04FA2F19DE4F11F20FD05B2AB6F0E243
-:10DFD000D20CE394C83AD18759D63F7213FC23D5AB
-:10DFE0001FAA0776662E766D4888175617A1F9E5A1
-:10DFF000B0C13F069673C57CC7B116AA179DD97DDF
-:10E0000000F9ACC0E8AD415CDC1EBAEC595A377679
-:10E01000A786F10880B6EC44EE909C30825C4EBC42
-:10E020001B93493E86E4B4664007215F5F9494B534
-:10E03000CEC88FC8C22600F0A6B6EEC9E85F8659E2
-:10E040004CC2EFA1989AB4CA9F2C06659BFDC78E5F
-:10E05000944D27D2E27CC1B403C8325A79CB69D837
-:10E06000DF7600C8077EF2965082F4C587BEF014B2
-:10E070001CEC43399E95E6EDCBD1EEBE5EF1C73682
-:10E08000213DC4B87EF0C23F28FFB266AA36799C13
-:10E090006DD8CBB90EBD314F09D27CB3BFC4843E1D
-:10E0A000301A268E1B820F206B44BAD956A7321C19
-:10E0B0002F18E4709970E62A9FA66546701C4538B3
-:10E0C000003D0447B89C91BF07F01C75C073D40194
-:10E0D000CF512B3CAD5E3E5FA7DFBF54167E3FF8AD
-:10E0E000BDA8078FB3B78C7A2418A398F44A58E3D5
-:10E0F0007583DE3E32AA34A6D1FA3BFD7E589F7767
-:10E100006DFA61A628EB60D797127CF6EFAC88E831
-:10E1100084CA0A1BF45F97CE34F1A37FF965E0BB94
-:10E120006B0EBB18F215F0AF82DF5DE2EB35C28FEC
-:10E130005D8AFA1FF4F6552C1E46F8DE6632D9CBFE
-:10E140006FB3E7C26759E4E276D92DF4382CA8956D
-:10E150007F592C8A7EB51AECEC53C2840693CEA468
-:10E1600013B46E31467E7790D35B9279D7927DD18E
-:10E17000C5F5A3E9F77DBDDBAEAFBFB1C35EBE9A07
-:10E180002D1C87F475F56D2E96827EAFB1DA1FB027
-:10E190003E37CA1AC1F70DD6D2A905C9CE6AC279CF
-:10E1A0002CD5988A7EDA8A7FFBE1F425309F9D4248
-:10E1B0008FBE09725DB7E88D659194DBA8183EBFEC
-:10E1C000F5526CC139D2C8F3DBE0EA5B80F64172EC
-:10E1D000AB8BFC3AE6F4D7F62AE4AF59DA11BC5718
-:10E1E00076D9E737D6FC9DF3058F85E6BB6CF71231
-:10E1F000D29B23CDC7BD5B325219F4DB03A63E147C
-:10E20000F2C5A46F93AF93B58CDB7BFFD7975A0F02
-:10E21000E3FD01E523AD7FCB541E47699981CFB162
-:10E22000DAFDE7E76CF7A7CFD9EE3521C79DED56AC
-:10E2300078FBDDB89EABD464BD240FD9D15E578B7B
-:10E240005108A870EDAB49A32966A9D77592F50EC0
-:10E250004BA52755AF5E1EA5BF63C2CE78E2BE1F99
-:10E26000BBFB91FFF6BCBA00F5FB37FF5D615E9822
-:10E27000D7B1FB422C8DF4A9A6DC68AF2C03BA4AB7
-:10E2800051393DFD128B5D05144BFD7FF3FE10D916
-:10E2900007CB1EF4A41AA0FDB25FFCD71406783891
-:10E2A000B66EE03F0A915EF748DCFF4BF64FB904CB
-:10E2B000DE2F53D915F10C74222B9C5FDEFA65A07A
-:10E2C00009ED3E69F781AF51BFBD5F76A15C36EBCA
-:10E2D0007D8CFB007954CFC0EFC99F4AA989128772
-:10E2E000AF71F270BFFBAD9F4A1CBE7DAE940FE1D3
-:10E2F000DBDDE34E40BD55BBDF21BA3DFFFE9F8510
-:10E30000110FABF629367F77D56E25ED9942CF57A1
-:10E31000F1899A51027E5B29F875E5DE15A407564E
-:10E32000F66E7E07F975D53E974DAE035E6269C401
-:10E33000EB0B4AAC01CB0FFD24AC03AADE8CEE093B
-:10E340006B15D4EF1237D0D5C533EDEDB0FF8F721A
-:10E3500086F7C7D800C53557F56EE4E331AE6F4C8C
-:10E360003E7D13FF923F5C6F9CAED8F71D8EB3A726
-:10E37000A7531C72776E463FCED41726BF7EF36735
-:10E38000C7772561DCB71EFC7FBB9200FFF27FBC24
-:10E39000B7EBDB302FB6DFA7A11C5AB5E70F6166DC
-:10E3A000C17B9DC2FDB0633FFDC9BD3B815F8EBD9A
-:10E3B000E421BBEED8A37F394587791F7BE0E37169
-:10E3C0006877AE7974EE78A4AF350F9F3F9E8DE2EB
-:10E3D0003F20BDA63CD6754DD1BAEAFB240CC23015
-:10E3E000F688783AD6E7B1BD4A1A43B76FBFE84915
-:10E3F00079003FABE05D6B15AED70AD24358BE093A
-:10E40000F0BCF2BE0DEF285332E13B592847F10929
-:10E410006C13C5F5BEE4E273ABF1E98AE9481F6C01
-:10E4200080E4BFB3DDAA23B0AE53475EC7E3EC532D
-:10E4300037E27FD57D1BF9B88E757C1BFF7276069F
-:10E44000FD3F6C1D97FF68277EDC9B4BEB3ED23A6D
-:10E45000AE78F8D251FD33531E8C85DF6689C33503
-:10E460005531562BC8570FFEEBBD3B237C7D1B005F
-:10E4700021C77E76FC140C2EBFE11AF81ACAC98196
-:10E48000473DDA5DD066D9A32F109F1D7BF859B7A1
-:10E490004E72920525D07BC7D8E09F3ED4832B25B2
-:10E4A0005E58757728ED090FADD3CA5463BD1EA61B
-:10E4B000F7AFD2FB14A7FF95A9038BA40CEBB647CB
-:10E4C00029E5723995477859A1F7B9B5A07D3DA5E1
-:10E4D00099B88EAFCE43BA1B691DCDF96B38FF19C1
-:10E4E00096F5BC9BF3ED48FC79ACC7A34A5943EBC6
-:10E4F0007B4CD807AB52D20B2C03DF32B68EC33B1A
-:10E50000C2FEA3F974D2C3DD0E7A30DB9BF31E8BFF
-:10E51000AFC79ECF67C3D76D8A6EA31B136F6F7D86
-:10E520009A59DEA7859C58C992F505A70ED7572A98
-:10E530008B270B4B86E0EDEC55488EBFB55B213B3E
-:10E54000DD2917568EE08FFF4EE1F6C7CA7D07A67C
-:10E55000A0FC7AEBE02F051D723A5F79DFABEEA4E9
-:10E5600090FF29ABFCC7FE32ACC78B02EE558F641F
-:10E57000EE6FD57DEF64ECEF4DD5F832C2FF669FAC
-:10E580008B25A18B377B958CF18D838ACB16C7EDBC
-:10E590000C4D7F310BE39B61BF8EF35EBFCE7821C4
-:10E5A0008976C8732E4676A01A7BC303DFD787FC13
-:10E5B000B4EFBD3E7C35D32D7ABADD8127351A27DD
-:10E5C0003F588DC4AB79EC3565F3475D9A6C839BFE
-:10E5D000A9C9228CA7FCAEE42F2AF6FB0CDA7FA790
-:10E5E0000DD57F46651DB9D0DF3386145BCB32C4B1
-:10E5F000A71CFDC7672B4CB7D299512E5BE3ABE14B
-:10E600008337505CA295B5A4314EC48A58EF3D962D
-:10E610007EEF6CD3581AC667F5E5B235BEEA696974
-:10E62000313C0047D11AAD144DB391C62F6E91ED18
-:10E63000716D31FE6A114F60BBF7ECD903FDD6E373
-:10E64000B752F46378BC0ADC29B263CE1772F0D7F4
-:10E65000C20E3E28C50FA19F65E8DB54947352D9C2
-:10E660003615ED89F99F76AB4B2DF438BF6C6D11E3
-:10E67000D2CBE1BF2B4D99E86A91CAE96A6DC98690
-:10E68000226C7FD8777D117742A334CF0231CF43FC
-:10E69000C5DF08F643BF074ABEB16512C0551F5516
-:10E6A00018C65BEA234BB654C2FC0B8E28311F946C
-:10E6B0000B9A936A62F2F07176A1BC07FCDD857853
-:10E6C00004F8EF6E8B52F9DE369D9EBBDBCAE9B9CA
-:10E6D000A72D46DFEF6B9B49E5DEB67A7A3ED8166A
-:10E6E000A7F7E11BFD09A4DFBD6D4DF4FE176D0911
-:10E6F0007AD6AA9CDFE60B7C58E64DFB608BDAC32A
-:10E70000EB308E62E2CF89EF3AA0B81CDA37907412
-:10E71000C4F77895CB15275E5B5B836497EE929880
-:10E720000D9FD3556E47C6051CBFF6262E54E1F942
-:10E730006E7D5905D93D2C1E4339BD4B8ADF5209E8
-:10E74000FCF244F18CA855EE66051371356FA87C78
-:10E750004A178FCFCC50B97CAA676B0F65017CC676
-:10E76000A74C473A33E779B0462F42B978702DC0AD
-:10E770005381DF65566EA133B3BF59023E16CC2CD0
-:10E78000A787E896F37F7456F9368C1383E3199BB9
-:10E79000A893D56D6BB74D35E3DE3AD1B14927C0AB
-:10E7A0003F4F1447A81BEE2F3697F0EF3E4EE7ADD4
-:10E7B000FDEF507C2B3A8ED9E28D1DCD32F9393BDD
-:10E7C0005FE171E9E3CDA5DB2641FD1AC01BFAED3F
-:10E7D00039F3CBB21216BADE22E869A7379EA58DAF
-:10E7E000A2BF3A453DB3FCBC2FF15D5C97EF4FF8FB
-:10E7F000793ED2F34E57EA72948FADAF78F475300C
-:10E80000A57F04E249FC1E2F82F700D2F1FA351EE3
-:10E810009A5A90EF3FB4DEA46F3BCDC2E7A1989D1A
-:10E82000AF77B58E1E9736E1DE85708F129735E192
-:10E8300036D7E378FDA2816FB0E17870F69B337F25
-:10E84000D1A8E3DF897CE7213CECB2D25B518B4657
-:10E85000FB0C667B73BECEF6CEF90EE52B9CDCFE80
-:10E860004CAF8BE5E27A3EF0B7531E7A86E192C751
-:10E8700015946357A8895E84673A6BA1325307F2F7
-:10E88000915F5EF473FADFD9796F3EF1919A2A4174
-:10E89000BD70B2E375B078BC06F5564C8E59E5B93B
-:10E8A000F97C5C35E304698A1FD116330C29076EA5
-:10E8B0008A66C2F360FF45EA5BD6FDA42D8C713FEA
-:10E8C0003DEDA57D0E0C8868502E39CCAA36417FCF
-:10E8D0007B843CA951B95F78D661BD47E1F123A59E
-:10E8E0003164C1A388A79A71AC0E7613D3A0A95B3B
-:10E8F000AD3C80D54D3E6C74279E477CB9A33AED64
-:10E90000BFBB2209E22B26E2DFC5224E3F57C419C6
-:10E91000EF69E571C65616BFF034E4EB230A23FF16
-:10E920003871AA8D7F9DF33C20E8EADF85FEFBA5C8
-:10E9300090DB65EA01290BFA0FBD913E1886E7BF0F
-:10E940000939FEB090E307B7FD4709E6137424DCEC
-:10E9500031C469B8DA9F96C00EBD79FA1BFA3550FA
-:10E96000BFA37B523BE267C31A1E977F08E53EB404
-:10E970007B40C8FD704BE7B5B46F27E44B91992FEE
-:10E9800020E4499190278F6D7B7EC9069C5FC24B26
-:10E99000E3B4B2F49318D7676B64B253C2BDDFBB64
-:10E9A0000EFBB9BFCDE0FD76EFF917B4EF7FE84D70
-:10E9B00057FD06E3FFB3DDB124CAA9D4449B9C0AEA
-:10E9C000F7EEBB1EEB857B9FBA81F261041E3C8F84
-:10E9D000C07CA14AD6AD87D321A857D89F46B31B88
-:10E9E000D6B567FEE9D05F59834CE1EAFBA4F8F99C
-:10E9F00021A48746BE0F9D55B9682DD6EF5EFE5CFB
-:10EA000012DB8F7BBA45C265CFF997BB6A107FF7DF
-:10EA100014BDF6640D3C27B94A880E82AFE8F93F71
-:10EA200061D87F3C7A8D3E321D3EB67C354339E657
-:10EA3000B94DA67DFA7B6E5BCDBE61CDBB58AE668F
-:10EA40008C8F4D7279F87ED66D0BFB50CE9AFB57AA
-:10EA5000852BEABCC4FF4F33DBFEACB98F65B6AF84
-:10EA60009412935C79B45FC1F7B544FB02056D3C29
-:10EA7000285E27733E88A77DD67C93E0B5723C1351
-:10EA80003C335C2AC1D31EABDBFD1F309E3AE33220
-:10EA9000D2CBACDB0E87B31DC03183C3C1E133E100
-:10EAA0002806932008E3DF3AFFF97C84EFA3FA41BC
-:10EAB0007DE347FFBFE376393D01D6676BBB4CFB77
-:10EAC000F707AB0F7A118F5BAA6BFDDCFEE1749741
-:10EAD00023F8E8EE7A99F8F67835DFEF679F9EA085
-:10EAE000FD3097F89E9377D04B7B18492358331D00
-:10EAF000D30FCC3F96FC02C04D55D26F939F726BE3
-:10EB00008E2DDFA0981538F2564A87EAA3FF5D7F65
-:10EB10004442BD1412FBD165E6FEB6F24A0CE77F13
-:10EB200087A917DBBCF4EC6939E8D301AEC75B8079
-:10EB30004E685EF6BC144F33A37915B4F07DB62D44
-:10EB40005ADF0137948B6E07D4EB68CFF5927C6166
-:10EB5000DD3C5FC0DCEF98B8DC9EB752E4C8B71963
-:10EB6000969FF519FDCC6B5DF67CC3E36CCBE94455
-:10EB70000F7DA5B675E9391BDC9AA9C3FDCDC17E11
-:10EB8000853FC5A25CCEE5F8F81837DFA834A3BDF1
-:10EB900014BEB02ADBBA3FDAE9E276D2A13F7A1896
-:10EBA000C6E337D479298E63EEA39BEBBD1593AEF4
-:10EBB00030DFA1FD5E1FD2CBCE48293D1F9BF594CF
-:10EBC000AF9FE890E70378C49CD6CD7A6A7E33E0A5
-:10EBD000F5877932E9988EA2E7F2717FF1D63A2F64
-:10EBE000EDF78703FDBD8F4139F87D770CF7B7EF5F
-:10EBF000A9493759FDD7FB5DDCDEDAE112FA6A8BF1
-:10EC00007DFF19F86007F2812718A7FD4BD92BF279
-:10EC1000261C7E8E898FF0C17CB964327F964E1E91
-:10EC2000B2CFEF1474B353C8FB2D42DE3BFB29690E
-:10EC3000D60EBAD1EE5FAE552919F87242ABDD4E51
-:10EC4000286EB1E7D51436DBE93E142B70D8156970
-:10EC5000D263A63EDEE00B9E8A745F05FA92DB0764
-:10EC60009A6CDD6F77EAE33DAAB1CF45F6EEC9D9DC
-:10EC700009E140BC05F1EDB4730F097CFF4D310E85
-:10EC8000227E036AFC908BF240E324679C76C330BB
-:10EC90003819C0397954387FEBFA0CF6D358FB0396
-:10ECA0001FCAF11DCF00C873B298C8BB08911CEEF3
-:10ECB00008717FA5C3C5FD8477C5BCFECBA550BF39
-:10ECC0000382BEE604584BE67C321E2F7A1F0D13DA
-:10ECD000AC373E73FE2E5A2CF4BD30F3F7F75D7C53
-:10ECE0009F6DCE84D1C7F900C781E7EF54E31D972C
-:10ECF000651FE75197F19ECB12A7F8C8A5717E302A
-:10ED0000D743E4E79AF6D33ED5F8D8DADE7CE6CCF2
-:10ED100057693FF738F3C714C0CFFE7CB697811C04
-:10ED2000D92F097CFED147794026BE07ED6B941F91
-:10ED3000A8075E09A4309E62AE83B90F332847440A
-:10ED4000FD33DC5C9E00DD04DC347E9CEF17B234C6
-:10ED5000C9870241373B7D8B6FA983E7CDB3DE7C4A
-:10ED600011F315DE7ED8A7235C5BAB8F86AD729363
-:10ED700035DBE9C77CEFFAA890F6E9BF2525F2DD7F
-:10ED800016BBDE15197063FBFD924EFE5CF20F0A96
-:10ED9000D923FBA5D4E964A8A88CF633F65F134DFC
-:10EDA0006DB2EC7738EDFC1C5FFF1DAB70DECD6003
-:10EDB0002FB10CF12961A70FDA1D517BFBB89B091C
-:10EDC0003B1BA60B7C5D29E61D530D05E198C61281
-:10EDD000F49CC1747A823F50E586FA67B1817CE485
-:10EDE000A3758153CEE176C67F1BDE8CFF8D781B29
-:10EDF000A25BBBDE36F71DF2041E42AC85F6DF1FB8
-:10EE00006F5ABA71228CE72E0A923D9CD7D47EAD00
-:10EE10001CC66CBF3E0DFDCD3CB11FCE1671FD6C06
-:10EE2000EE4FE734D8F5B9537F7B84BDE11941AF8C
-:10EE30003BE5E6487A7DB9DBAED707E3C723C83F99
-:10EE400067FC786CF9A7DF525782791AC60B756890
-:10EE5000D7CD5629DE193E955D11B7D0C3FF751386
-:10EE6000D1C193E7CD6C027E4D9DC6F99CA19F1048
-:10EE7000000584FB09C5720AF36D362453F5987FAB
-:10EE8000B6419DA859D7B1A698DBB35B6BFDCD56B3
-:10EE9000BBF6753F8FA75E1BA8790AE9AA2298AA3C
-:10EEA0002577CF0047701CCFBBC4753B5363FDB8BB
-:10EEB0000FEB615C6F034778B95EA9D35EA7FCCC0A
-:10EEC000043B11184D2FD8F331F7A8A9757EC4471C
-:10EED00084C75F423B244ACE517A8D34E6724D0D91
-:10EEE0002CBCD3CDF557398E73603A98BB50FF8355
-:10EEF000036EB2737A43852ADA93FBE5A53F423B62
-:10EF000070E0250FC3FD94DEBF9F41E71A7A43E707
-:10EF1000CC433AE8951878B6307FE01F9EFCC302D8
-:10EF200018B70F9F6F308C5B0E3CCE6277C1F8AE86
-:10EF3000E84371CADB6546409E09ED7CAC0BF35794
-:10EF4000629FF8DF3B0FE8EEC160D5F6A96C280E92
-:10EF500060FAFFE7F9130F219C1DE3FEB319F9AC2A
-:10EF60000BE054C80E33A20877559E4CFCC7F282C2
-:10EF7000A989F0BEE670A40EF3D16AD44A94340095
-:10EF8000075FEFE77D8947B19F3AADB12E1BEA5786
-:10EF90001FD1C95E9917BDF61096A7BFC2CB1D6ED3
-:10EFA00046F620F22FB3F05FCD47A7D0FC0E0B3909
-:10EFB000DE1E35FA0C6994F5D054C7790E7B1E8B92
-:10EFC000950EB4E9363A48B8AC743013E860B2959F
-:10EFD0000E0CE9B3D0C1F784BC1D9B5F389F5CAFBA
-:10EFE00070BE194EF72DDE9C8AE1FC618EBBA93AFA
-:10EFF0002782FBAB261F68336ED2B0EC59E28E231A
-:10F00000DF997C61F2C33FBC2E820BF8E2421F3CC9
-:10F010001705F5B999F802FD382BFD5F32029F2CD8
-:10F0200060038730E77E81CA925920427E77F61BC3
-:10F0300065A758E8DE89A705B32576D4228F4E9CB4
-:10F04000E0650B1EB5C13C68E5E4F1FD9CAA774480
-:10F050002C7CD709F6331A855D728CE59520DF2D5F
-:10F060000D7AA6E1F98607A214DFF7C49B296F6D1C
-:10F07000C65B81AB810E3F1827EB38F90E7DE9FDA9
-:10F08000C4BF2F0618DA6D5BA72F9B80FEC907D778
-:10F090002426609C7323E0FF281937A9F132E5424A
-:10F0A000F58FE7FB657A943F1351FE9E89EF295156
-:10F0B0003644BD7EAA07EB6C9387DBBD9CBEB77B55
-:10F0C000B95DB8D1DDED45FE1A28F1D27EAA59EF1F
-:10F0D0003C85DB6DB33C229EFCE97A1DFDFB591E8D
-:10F0E000DE6E7B5B2AFEDA448473373D731B520C61
-:10F0F000F703FCE5491DE3F1DE752C91C9EEBBDD9C
-:10F10000CBFD7FEFC11FD03E526E598CFCCE480321
-:10F11000F46759AF05809A2C901F00AE8174DCA172
-:10F12000FBC90E5B10A9FDAB3A65F8FAE29FA39606
-:10F1300075F2FE4349F472FF8CFC8B35C29FAB2BFA
-:10F14000F5125F74B4BA7B702A8B3CD9DCDE8DD4A7
-:10F150008E9A3F8B7E5312D639057E133E717F23E4
-:10F16000791ADFDFC032EE6FE013F737F089FB1B4F
-:10F17000F81DF737B0FCF33683CAB8CF8165DCE7FA
-:10F18000C032EE6F6019F737F0B9AFAD999EBF6A24
-:10F190006BA1EF8FB4B552F93C0FB7B3597932BABE
-:10F1A00010F0DC7583DBC07DEBCD627D1E334A73CE
-:10F1B00063B08EBE08F73B7D4FDFCA703EBE288F1E
-:10F1C0001775466F6557C2B36B5AA80B0359DEFB20
-:10F1D00083F4F4A9DB19C60D7649C9668CD0ADF667
-:10F1E000FCE27C15F47359F4DADA1C28B77A1E595C
-:10F1F0008F793B93F4B5B1A5DA50590F552D7BC0EB
-:10F20000529E50D1A3FAA1FE7736EC5F8F7C8A70B4
-:10F21000A0F1B6C173E0FCB5B0E4E95246E73706A9
-:10F220004ADC29A4B3AB70BD2622FCDCAEBF88AD9E
-:10F230008FA29F3C417757217F40FD34A7CB93ABF2
-:10F24000BF1937A9A60D6F375A3DB9FAA4EA31653F
-:10F2500094FEF0BB344A3F1D6CBD8667C936232F30
-:10F26000633E912F407E5A978BF365978F3FDFF473
-:10F2700072BFECD7DEDA8BBCF0BC48F069972F5E2A
-:10F280008F71CE81C932C50B7A5DD00526E5B69661
-:10F29000FCBE14C6FDD6532AC3B8F35D1E6EDF4C08
-:10F2A0009C10E2FAF2DB5ED297174CF8597B0E9471
-:10F2B00027FE381643FDB799C5FC4827C92D3C6E7B
-:10F2C000FAAFD5A7E63442F533A73D9C43713FC161
-:10F2D000DF293C6F04E5B51D574FC038C707CF7213
-:10F2E000B9F480A0B71E575F0BADE7B420D90D8CE1
-:10F2F00075935DB036AAD2BEBC9CCF9F6E97F615B3
-:10F30000ACE706C59B0478DC7F9FE125FFFB238FDC
-:10F3100038A7D647F682DB97D0B2E17D7752267EBA
-:10F320005FAFF953988ABF395845E76693152AE5C8
-:10F330005D6FAEE0F1B940E8B214DA09B71CF071C4
-:10F34000F910F452FE55AA62EFE1DA083E650DF9B4
-:10F350003D652CAC27BC6BB246795CF037FADE1CFD
-:10F36000A13CEDCD4CAC4BB34C7E60C7B84F7E3367
-:10F3700015F7BBBFAEC5C4D921CA8324D346C67313
-:10F38000BC03070308CF57CD7347FDEB0250BF7D89
-:10F39000A916C37598A2D5D6637CB043ABF5225F9E
-:10F3A0000526D77997901C1ACC53A6F36DED15DC82
-:10F3B0005EC5EFC897AC9D1DC2F32C85429605B281
-:10F3C000AB24B4733A1A286C8479BCB6BCCBF69CD7
-:10F3D0000B29AF5D599043707630C38BF5930D2A9E
-:10F3E000E9A5C2A0378D765CA11937C494638B1F41
-:10F3F00091BBDC9EB79CDFACDACE758C4FD8CB7955
-:10F40000C22FC873E4377FEA31F755EC7872CE37F4
-:10F4100037725736C29B8B0795F5E1F3D91EA96A5F
-:10F42000C479166A7E823BAAADAB41F9359EB5AC74
-:10F4300045BAFBCCF03AE09C52D1DE87EB3E455713
-:10F44000E91CC35436B00EFBDD2CE8BCABC4AE27C0
-:10F45000EFF228627FB7B6DA3B8DC7B99296F14BCF
-:10F46000927E96B48C776A578EAD3CB1BBC056FF86
-:10F47000B41DA5B6EFA7A7CEB07D3F737795AD3C81
-:10F48000B97796ADFED47DB5B67265FA425BFDB331
-:10F490000E2FB495A7F57DC5567FC68B4B6DDFCF7C
-:10F4A000EE5F66FB7ECE1BAB6DE573076EB4D537A2
-:10F4B000ED66A75E9CE2FD7CF6B207CF79D9E282C9
-:10F4C000767BDC694F7BFFB15E5F87722DEC26FA9D
-:10F4D00056518F4379F50DDC9FF1CE89E92857CA43
-:10F4E000845D931534CE41395A13F6923E5083BC55
-:10F4F0009E1A9C4776C7293B401E9D8556201BFCC3
-:10F500001E40B9DC968C97B986E0F669DD7466A179
-:10F51000265C4F7175B3BDAA192C11C2F1746ECF60
-:10F5200080B788F57C3AB4B7CC63BF2CD311EF0118
-:10F53000F0BBEEB2F85D23F9594EBFEA64FDA85363
-:10F5400064E6C7678F146FC16745CBB3B5985E0794
-:10F55000FED5158887ADEE78730FF4BBB5D4CFF721
-:10F56000C1847FD555D24B7C3150A2927E61AA5E78
-:10F57000B1D012DFDAE4E57A25E0BD83FC3BB57457
-:10F58000E6611DF1BE56A5B8C36689C74792B00EA5
-:10F59000A8D776CD7AE39DEFC07B6FA9B7D00BF2E9
-:10F5A00028F698DBC0FDCFED02AFA55A652D585C5B
-:10F5B000605F341EC4E7241DEC0C7896976F3B887F
-:10F5C000CF9BBC3CBFEE8CD803B5284BBC73B8FDB9
-:10F5D000A74C71A7D6E1FA691C8E91E84CCDD9C130
-:10F5E000F7A9CAD4D791DED0DA3E210FD1810FE935
-:10F5F00040A227D18F2F1224BDE1C38D1C2CAB520A
-:10F600002A00DF23658684791735E11DB4EFE64BC8
-:10F61000DBED55F03737215E230DF6F50E787711C7
-:10F620007CED128FBF7665EB4FD702FC5D79A53973
-:10F63000183BC1F844A345DE6C17FAF42B3ED9D42D
-:10F64000FF246FE85CD7B4217B07E87F877C2AC260
-:10F65000D7CD506EF96EEA6648EF3E0D5613EDEDCC
-:10F66000EF2689FE4D7BF73AC15B75A54DB4DFF5FA
-:10F670005EA48AEC5B5FEBCF33E2CFD7AF30E3AC75
-:10F6800091F11A9EB493F43D2B75EB6857B4EA6E72
-:10F69000A327833CA8F2703B6623E67D203C22EF43
-:10F6A000A34BE0C3DC6F7BCFCC8712FBBCD76533A9
-:10F6B000DBBEDF757955E347B3C77DE0F7252CF056
-:10F6C0006E8471102F1D9F36D6C769FF8FF1736A44
-:10F6D0007FAFE8A1F3C0C27FA91276D22C0A9A01AB
-:10F6E000DFB819F909E763FCE22CF4362FAA47BE0C
-:10F6F00034E31DAF7973A85E2CC99416B2575CA68B
-:10F70000DE924F4C259875B719A7249397EB35F8DF
-:10F71000F7009EAB38B5CB7E5E6962B7BD7CDA0E72
-:10F720007BF9F494BD0C56F311B40B1A19C7CF9999
-:10F73000BBEDDF1BCD385F1D3F67E185914F70FD4D
-:10F740006B3BD7CA84FE37E3A9C5BDE91A14AF45A0
-:10F750006BEC7AB540E8F90287FEAC0A29E4E7D7FA
-:10F760001C8E1C42FBD18CBF3CEFD36DF96F661C25
-:10F77000C529CFFDAF6C63F085FCE58487C7171200
-:10F78000E0DFB41689B845317FBA14FD99C564A786
-:10F79000B59C86F2E9D7DEC4075E325AECE720DE7C
-:10F7A000AD571F97743E4EC232CEF5E5C90BF8F443
-:10F7B00053945762C6314C3FFD1F01E322E4AFCDA5
-:10F7C000B1E75A1EC338D24B1E86FDCC559E3EDC97
-:10F7D00006E5D5C52AE5416A3396FFC88F7140FC1E
-:10F7E0000EE59A127D3CD1FF932EF2D737087A3678
-:10F7F000CFE798718F5C9FD03F3EC9DC87F08B3C90
-:10F80000573FDAB967EE06D96CD3733C9E66C6CD16
-:10F8100026F7DABFF732295783F59BDA9492B95D60
-:10F8200065046B2C71F533C47A4D599CBE753194C7
-:10F83000EF63A92ABC2FA252D045EC90FD3CD838EA
-:10F8400026D1B981714794580AEA4F79C4FEBDC2E6
-:10F85000715EEC0CE7F931479C37A4B07796C0781D
-:10F860005BF41609E5E796C560C343B9C227F28782
-:10F8700027B149487F7395602C8DF8FD83427AC388
-:10F88000F3EA692F2C417DFE2CCF4FD14ED5B7D551
-:10F890004159FB8D42FA490BB0CACAE0505CF87B73
-:10F8A0002762ACDD351467DA03EB5A3611FD6B2F96
-:10F8B00043BDF273585F2CF7823F8EE507C11FC727
-:10F8C000E75EF0C7F1FD2FC01FC7F23EF0C7F1F9A8
-:10F8D0002BF0C7F1FD23E08F63F9DA404D8D2FCF78
-:10F8E0001EA7B2C6ED86E254FD9219A74251F2BEA0
-:10F8F0009BD3FF60BC2AC1E35563F76398FD503C7E
-:10F9000070583F222EF8F60DFF792F9E9F5E316DC5
-:10F910005D179E83F5BACCB818CF7F30F39A4DFEB1
-:10F920005BB1F75ADA0F76E71F69C1F5D85B1DA402
-:10F930003B86DCAE8486F2D1E97F997E97D3FE3593
-:10F940009F4E7DE4473BE02CB493BA29EEB3C9C582
-:10F95000CAE95CACE48F215F38E390261F3FEB2BB4
-:10F96000CD789E69303F56C4673C2CE5C578995BDD
-:10F9700012F314F99B24C2A08BCDC8CF967CE36010
-:10F98000459AE21CC1A041F697047619D9695A221A
-:10F990008A71A8CE11F26177093E5D9BEFA67B24A8
-:10F9A0003AF3F9FE7F5D512C8AEDD7E74F8F5AF37A
-:10F9B00063CDFCDD43A1E9DE7E4B7FAB43A5A3EA2B
-:10F9C0002905F4AA3E8A5E553C3C7F7DFDC1B3BD4E
-:10F9D0009897BC29B8B40FEDAB4DD1089D5F3F900F
-:10F9E0003F9DEC8FC1FAD19994BFAC04B9DDAA4414
-:10F9F000BD64B7AA38FF8AA1FA66BD1B857C06F6EE
-:10FA0000A3F85C20D84BF53C6A9CE21F9E08A3FD3E
-:10FA10002A8F97E70B04C1BFF6DAE2A6421FFBB8B4
-:10FA20007CDBA427E2D86E5354D5511C6D2AAF223B
-:10FA30003CAF17785E9F67EAFD18D91B0F0A39683B
-:10FA4000F6B35EF8EBEB9BDD6477C55BB38DBA5C18
-:10FA5000CAC7FC09F2DFA6E05D5ECC6F77E7578F7F
-:10FA6000DAEFA363F6FB6A6DDD59D4EF83187F7676
-:10FA700087966AD8AF6B84BCFBA7447F9FD7BE0430
-:10FA8000CC69B4DFC54C7D9B8A5AF7899D4F3FDA1C
-:10FA900089670D6FB742EF9F8779BF2A4BD6FB95D9
-:10FAA000E1E71656EEE3F7506D55FBC8DED9FAA92B
-:10FAB00094F1FC43B6DFD43F837EB8CD5E2914FCBD
-:10FAC0005428BEEB68AF94A05F69B72FCE3A6C2F75
-:10FAD0004FEBB39767BCE8B4578C3FA0BDB248C8A2
-:10FAE000BB3E90CF3C6962404539104FA66A10EE8C
-:10FAF00046D6BB16F7295D22CEBC48E8AB8BCDFDC0
-:10FB0000477F36C15FD8ECB7F989E67D1A45A2FF79
-:10FB1000E2BA43D7B6A3708D9BF68F4EFE65F1FC1B
-:10FB2000076B484C3AECA046C37E1EF562879DE306
-:10FB3000B4876AD41ECAB72C70C41FCC7D4A9C27D8
-:10FB40009ECB758EFF59C735FBDB097A0BED15F39C
-:10FB50009E02BAC70BDA17AB692916A4FC2DCAF3AB
-:10FB60002B5CC38C9E0C743CD3CFE5DA30BC25CF24
-:10FB700023BC9D2FDE1504F93D2805754A4A2FE167
-:10FB8000F95F284F162E87F990BD7C82F6A1CDFA39
-:10FB900039D9BD942FB6B341E2FE6392911D62AE96
-:10FBA000F3CE203F3FD378AE9492B17D4B298D4F59
-:10FBB00070950EAD2FE0E928C713CF2FBBA4DE7ED2
-:10FBC000CEA7D1616F98F470B1E3FDCB3E7E4EDAE3
-:10FBD000E483B7CF7E71D22900C70A29591F504E3E
-:10FBE0005E4F5AF8C37502F910FF3E8EA642FC71B3
-:10FBF000D0FB9046F901D9FD773020C9063F4BD69E
-:10FC0000CD06BDE81F385382F225FEC91D5DE7E22F
-:10FC100071C5817F45A3CCE3A99A5B5F3C54F6FB99
-:10FC2000E7503922C601D722C9D7DB726F01C0FB6A
-:10FC300003911FB0D960DB14CCAD94B56DB192A126
-:10FC40007639D84E1AA55D9C6D5333B40B9AED00EE
-:10FC50005D9DE63D1FA5F8E4DF65018F757C15F11C
-:10FC6000A6E9413AC7334FD530EFE18BC2316EACD4
-:10FC70007927D836D7A9C3DB01D86B4DF8E5CCF08E
-:10FC8000A7F0BB757CD728F0FFB3F131567F6EF13A
-:10FC9000FD33C307D5D78D1B79BE08978BEECBD02C
-:10FCA00083B2A59F5B0E7C4CF16BF57246E77454F2
-:10FCB00097A1C580CE2BB4DBC80F57B3EB34B40388
-:10FCC000364219ED808DBDDD14A7AE28BBB50B897A
-:10FCD000BE22ED67280F26332DFB3EE877B2A662E1
-:10FCE000260E53CF3D2463DC9B7D89D13991AC0333
-:10FCF0007E7EAF45C9AC1FA37F949DEDA5385020F3
-:10FD00007BFA8FB9B1CBE3C126FC819A23B51827C2
-:10FD1000571B590C59519552AC0699EC7446FB107F
-:10FD20007E63EFF578DE12141FE927BAEB01F5AA1E
-:10FD3000888B8FE724C3BADC5A23FA09C9A7548AEF
-:10FD4000BF8F47D31488B2A222671BC25391800E83
-:10FD500024849FC7B52627E4581AFAAF7A87B76379
-:10FD6000BFE5E703C097687A3838845753AE8C17DD
-:10FD7000F1F2E8627B3C990DC09CA17DD56F17DE46
-:10FD800083F18471C3E437F7AFCD7B74B2DE61F1E8
-:10FD900087695FD3AE37FCE2BE0ABFE31E8492A040
-:10FDA000CB768FC130BFE1BB71D2031E16F3BAC947
-:10FDB000BE584C7683E98FECC48A18FF2F66FC5E30
-:10FDC0002B67FBE9BC3D8B72FFC4E30733AF0ABE70
-:10FDD0002FF31BA46F3D50063C4A6EE6CD87F70516
-:10FDE000328F8BAC95988AE5A1F1D2B44FBF418A8E
-:10FDF00075C5A421FF77BD16A3FC01B626C7662FE3
-:10FE00009B79A8ABAF29199F03CFACA1F3401AD2BD
-:10FE1000E3EABC32B29FC3B9FDFF07E5EBFB9B36BB
-:10FE2000CFF5A2FCC4FC8559F05FA0B32309F2D63C
-:10FE3000F35121D32D7699476DA13898E7A3536CE0
-:10FE4000EFD36DF6F3834650AEC371C607747E2EB2
-:10FE50008369EDD8AE86D9CF097A3ECAB7D9E943CE
-:10FE6000FD17D9DEA7C19EB1DE4F3172FF01A69703
-:10FE70005BFB3F7584FE2739FAD732F63FD46FAE6D
-:10FE8000ADDF0E95C74793113FADBBD31E981AA89F
-:10FE90002D0A4C1B257E1FE0F1C70DD1168ADFD736
-:10FEA000326078A093F33E3DAAF0F36C8CEC3656AA
-:10FEB000648FDFD70AFA958122907ECF53EDF782C7
-:10FEC000CD61CE7BC2ECF6D073C82830AE1CAAEE52
-:10FED000A338FEC7411DFDAF91ECE5BE3646F1E308
-:10FEE0003981FEEB709FFA82CD77BA3A668AFCD7E9
-:10FEF00002C62EDDFCC05CB4EFFBC479BD8E884C1D
-:10FF00007889D78EA7F337663F71379B88F2302EFA
-:10FF1000F3FC04FA03E3F7E515DCB52903FE9CE7DF
-:10FF20003B1B0D295E66A19B3E19F06A1DEFFCC2CA
-:10FF30001EC5328FB8874DA3F1849D3B38DEB8CF04
-:10FF400037DEB322EE648ED738CF3EBF46B746F3D6
-:10FF50006B14FC6B8EF72CCE2F037EC71C4FE67400
-:10FF60003338DE05F6F9357A349A5FA3B8E777704F
-:10FF7000BC719F6FBC0DAE9604DA6DDB24CEFFDD45
-:10FF8000815F75E0BABED7B03A4AFA40D8C5176368
-:10FF900003A877B1CAC75B50E44DADB58CB713E485
-:10FFA0008021F2DC0D0FE66F68544EB545E97917F4
-:10FFB000D8D906E56F94D3F77BDB6254DEDD369348
-:10FFC0009E663FE533F9BD33A7CF9632DADB870370
-:10FFD000DCCFDA96AF5D7E15EAA51A3F3F0F39F305
-:10FFE0001C6658EC5F30880FFA70FFE5325689BA0C
-:10FFF0006DD20E0E77A46E5C0AD7CF5F79A8AF0DD5
-:020000021000EC
-:10000000CA1E974B477D0ABC10CFE4A73E16E07E80
-:10001000B8C7CDE53D9BC5EF315C20F40A531A24E7
-:1000200017E2E3E26CDAEF5FB8C8086980B745927F
-:10003000F48732A1A7F0DCCAA562A99C767E0435BC
-:1000400006F41B319414DE4F7469D1E126D4CBF150
-:10005000D025E41FC4A1610EF473A9D09335AF7A03
-:1000600018E63BB0B96E8263D122BB3DBFCD97D6B7
-:10007000D03ED9561961B83E0B1BECDF3D6ECE87E2
-:1000800071C7BD050BC6B8C780EED2CA9047EA8CCF
-:100090004F3E1AB0C7218FB38A5BEAF0635164D434
-:1000A0007B0CD6609BBC21FD369C8E393CAFFB9906
-:1000B000F0DBF6513CCC84AF404D4928AF0B9BF7A9
-:1000C000D9F29A00B1640C9B7178A6DC57897E88BE
-:1000D000733E3BA5FBF247BBB7A480A9AFF7978B54
-:1000E0007B3DA5E1F37E2520F26F07E73DFB9932CA
-:1000F00096897F78DC75C16125B6561FC28B8987CA
-:10010000FF693EEA12787FE6FCF7ABB9FF5664BBA5
-:100110003FD3BC17F892C1B2CA540B3D5FBCCC4D63
-:10012000F60C33062A90EE8E9C1BE0F7B899F64B3E
-:10013000FA2519ED972FDEBF516CCBDB14FD8EB481
-:100140005ECE3C42CB39D0A13C77CC2F91F83E56C5
-:1001500001E6B985F9FBA3763BD396E7B6FEC04F1F
-:10016000258CF3DD81F978967DEB42F0E7516E1630
-:100170002DB7E7D539E132F3AA06CFD1CE5EA4DDA3
-:10018000A7D3BD89DD78114DD78E649C59F223CD5C
-:10019000F381A63FED3C17A804F9FD795171DEC249
-:1001A000190FBE5E4E6A2512E6A3A6BC35F09C92DE
-:1001B00093A8C2A3EAD72BC97A7CAF8C9FD58C7841
-:1001C00058DCFAED18C6EFB4DCCC71E9C5427F9F6C
-:1001D0001BE4F18E575CE9628C632FCDA93D373863
-:1001E0002D43FDD6EF527F7346B88FFEB220A7BFD6
-:1001F0003B843E777EBF588CF3E51532DD6FE163BB
-:10020000A1945482FBC6DD33E93CDECA9DB14CE7C4
-:10021000DE9E0A2716042D71075F193F7FCD58EF28
-:10022000D988AF8D7FBBB3F77E4065CEDF82244790
-:100230007314DEAFA5FD6599DAEFFFF8793AB7BC24
-:100240001FCFA9A09DCCEE9887FEDCD6C1324B4AC9
-:10025000181FCC16E5642BFF3E58AE9A578365A451
-:100260004120B29782733B915EB64A4C10E33C5EEC
-:10027000DFC5EBFF427C9F73E15B3FBE05E5FD748C
-:1002800037F9815B853D62C2F77290E7CDBC3C06D1
-:100290003E5BC5F720E233F299F0D99A091F2FE7A8
-:1002A0001837E0BAFB30930240F0FDCDBB06F3886F
-:1002B0007FD0C66257C11CEE88EDFDE92D8CDA2790
-:1002C000ADF461B6BF28C7581B24788ED2FC4265B6
-:1002D00041746FD8C6198CFAC900C7C64CFD98EB9B
-:1002E0007A308BCBB10FD1769E86EBCAED3FC5D36A
-:1002F00017C5FD7FADFA7BD76920473A4BBA9B32D1
-:10030000D1F7F7437C9F3A7B8478F5CF053DBEA4B7
-:10031000C57F8070B46BB7D2FDAA6E89DB0D1B67F9
-:10032000F633C9D2EEB7218E6F80BB07EBBBCFE6A9
-:10033000F79E8600EF986016AAE6F06FD48F30CC57
-:10034000EB0E458F505E68A8BA9FF89D8E2A1470F8
-:10035000BA427FCD2BECB39F07BF320FEFDBC85102
-:100360004CBA7BAB13E946192A131DF5E4F0F6BF2E
-:100370000FBDD5990491BB0BEC17BC872359C0F373
-:10038000469CF3FBA5807747D8D88BEB320C9F9E19
-:10039000FE1FDF02EDB74EE4E76DE6C87D4D572244
-:1003A0005D5E1824FB0BDE3759EFBF795DE0EBF59E
-:1003B00020B79FB67EECA5EFCEF518895E7F27DAD1
-:1003C0007F0E7AFD5D263A017A7D06E765A1D7F7B3
-:1003D00059667A7D7E047A7D21135E9C6585193B82
-:1003E000707F56FD64DE6EEC4FBD68F68EFBE1A9B2
-:1003F0007C725392563326D9CE979AE3544A893F5A
-:10040000072DF2DDBC9FFB9B41DEFFB07E674CDF1A
-:100410008172EC24FA1DC0F938FBDD1FE4F0CEB97F
-:100420003098C8746FD1CE10CF1BBF5BCC6B24BE8D
-:10043000792AC4FDD991F8E681D020DFB050DED80A
-:100440007CF3AAA80FEBE0C5FA63F3CD6DF4F49545
-:1004500071BEA163C8B386F30D4BBE487CD259C2AE
-:10046000F9227FEB9F3B31CE31C847C90FEC7C941A
-:10047000FCC0C6477FD9FA01D577B60F8F704F956C
-:100480003EC8FFF109380FE34CAD9D9FB3E927BD8E
-:10049000DDC3060E7828CF96E7B5FA9349839B0D06
-:1004A0007D0CEF3D2C1778D8853E18FA39D3459C42
-:1004B00049ED630B43C3F939549DAEB6DE23F06BAF
-:1004C00031FE47A1F8D4D0341CAFFF74B4BF465AF4
-:1004D000A76A517F5BB6511DCA40D763E9A1CB43E0
-:1004E000FCBCEBE502EE9CBF795BD0FE74F2FB9C9A
-:1004F00095BFFAEBBDA3F4739968BF20F4B9F97FF7
-:10050000412833FF5F1CB2F37F35DEBF9981FF2F97
-:10051000CBD41EF8FFCBA10CFCFF05F8FDCA50069A
-:100520007E9F1DE2FD8F85EF7B05BEEFFD82F86E9D
-:1005300017ED6F0A7D6EFBE0A65066FBE03BA169FC
-:100540002785EFF611F0DD1122781E24F8437A900A
-:10055000E2D85D33D85EA934231C5BADFD7875DE2F
-:100560000FE0FD7D09E87ECE275DB14CF7CE40BBA4
-:10057000DBACF09BEDAA439A99BC7D2DFAE7775C42
-:1005800014A4783FE8C71DFF643AB83B94413ECFBE
-:1005900091B91CFA20F820D9815FA0FFDE4CFD2F15
-:1005A000137436965DF098A00F98F7BF85A60D9747
-:1005B0007F3DE27752768413FB4384AFFEF928AF88
-:1005C00076DD9823613CAAC8484BE827EC15FA660B
-:1005D0007248E7E71944BB5D6A5AC27C965D2D9A62
-:1005E00084E78D2CFD1D0E4D1BB93F271C00DF6FCE
-:1005F0004224EF8CA7B15DF5901DF899ECA44BB2A5
-:100600008D2321D23FF1E7496E9F6697DBE63CE4FC
-:100610007837E5BDF86666FE1D97BD41D594FF7F2E
-:10062000B2CAFF17429AF9BB52D4DF67D53F00DF49
-:100630001B02BE3733C1E7C4CB58708E177A1EFA3F
-:100640007B3F939E72F667FAADE63AB9512759E2BD
-:100650003A5278D0EE656194DF1D329D435A20E412
-:10066000C98299D9C26ED7FCD8FF1D224E7EC7F22F
-:100670005B6B70BFBBE726AD125150D0CCF59EBE70
-:10068000FC148A7F0644BF4EF807DBBB7B4FC77B59
-:10069000C761DC2C1CF7BCD92C8D7E6316DA0D14D7
-:1006A0008FD0E877BC723CDD518C9F6E94BA9B96DC
-:1006B000A25E9D1FE4E74AA28BC6B8BF6D9D8D6EFA
-:1006C00059B47A8CFA6BA9BE16E8A6FB2F4EBABEB7
-:1006D000A7BB29537E492C2C9B76D199A3E2351ACE
-:1006E000A1B89689DFE1E3F0F5AB89B74888EF5010
-:1006F000B5A4E1D1AB10D009DA4B72591FE5337DB7
-:10070000A99AD30B03BF64F4FB333ACDF59E13CE05
-:10071000FBE27099F5461E4FD4739C57C07D2F8A1B
-:10072000CF06B91CA38A507EF7706EC6B8BFF9DC3D
-:10073000D0A615A92E6BFF29BE3F33983F1D8BA273
-:10074000BDD5CA383DB2A897EC30BAA7DDB29E4BF2
-:10075000C3DC7FFC4156FCAB61E2EF18DD4BC834D3
-:10076000EDA4E603EDAEA2762AB40B9D7CBB919F6F
-:10077000E6EFD7C5F4B8E51E34935FC727920CEFB8
-:1007800099F157304D82F58F84CC7D424E07B705E5
-:10079000CD729236C9E365DD3C2F5F37E984CB1516
-:1007A0002DD06BC8958C6DBF79FE05D1D3A1BFB29A
-:1007B0004414AFD487F213788F5A8EC2CBC0684FDF
-:1007C0001C227DA19D21C5404FB5CF7DE27031E354
-:1007D00047A5E8F7D5E63E81F9843D66192FA428A0
-:1007E00087B27FB06C78A3502E1D2C27B1BC4BE88C
-:1007F000C9ED37CF7DA23D4872EC662B7FD4083A15
-:10080000FC67D35F8FDEAEE13983645425BB6AA3F6
-:10081000831E7E157613FEA76A8914F2C5829B0695
-:10082000543CBAE22D8984901F2644DF4FE2FD79C3
-:1008300013668B34D5327E4F434F740DF1650FAE86
-:100840000BE36909189F1C5A9F54E6F5294FD1FA0A
-:10085000F875FE5DC632F9DB3CFE1628E7FCAC7984
-:10086000787CEF2141AF07C33C7E7450C8D7AC6899
-:100870003BF953DE7A99E2C759F5B24D6FD02FE0BC
-:10088000517DD5466F2FE724F6872D7A01962F5E8E
-:100890000EF3F09F1EC9C1FD979A72750DFADB3FEA
-:1008A00012F61FACD30F495E5446FC0992DBF1C728
-:1008B00033AE9BC0CB58EBF67C5B2256E71A79DD52
-:1008C0002EBB9CE7D33BDFBF28E4EAB1A63F7F0FF6
-:1008D000D965857780EEF3EE2A5B4B715833EEEAEB
-:1008E000D95B932ED487F201D705C2B3E95C8A6342
-:1008F000DCE73FFDBE46E7443EF664DC4FFA87C0C6
-:10090000F391B6266A070B4CBFBF72054E85E7B15F
-:10091000D9CEF199E711BEC638312C8A2FF912CA07
-:10092000A1A54D0ADDDB7005B3E7537CCDCCFB6A96
-:1009300035F3E378DE578265CF43365C9274FC7EF4
-:10094000048BCDC373F4C37E5742EC6F7DDD9137CA
-:10095000F1E5A625B13A51EF3DFA7F8AF0B748E7B5
-:10096000F277518CDFDF7369FCF2589D653FFA85A1
-:10097000BF2B19F3262FCA32F1118FD54D1C8E8F44
-:10098000A571C9ADE963E3E564F1B044AD9C97A7F7
-:100990000FC78373FE80B1AD88E7AF039ED1EE1C15
-:1009A000091F508FD6E385CB15FA3D99794A830B01
-:1009B000F741AE6C94688F09F01B1679710D732D99
-:1009C000F03AF1E8C4D7958F323A3770E5ED218AD5
-:1009D000B73D67E2277D1EED5F98FB2796791EE500
-:1009E000F95B1ACD73E1CCCAC7F1DE84443B485BA6
-:1009F0003E5FDB3EE05216CFC2730B30EFA323AC59
-:100A0000BB6D3FD0099F137E9FD02BCE7D31A6A614
-:100A10002B500F1A59625F700A8B89FDB12C4AC79F
-:100A20002DCB2C6F9DF7CD997476456BE3E0B8D84C
-:100A3000BFC41283650DCF6B3DA96CBD14FEBE3AD9
-:100A4000CA7FD7307E796E077E5BC0CCDF1B3268F1
-:100A5000BFE90A81BF46F0F8F0B7D0CE03E184FBCE
-:100A60007A0B0C9F1EB4CCF3DD6EA95E9CA3CA5A10
-:100A70003419DB250F285386C3BB3ACA7FBF10E861
-:100A8000F07D2B1DFA26F27B659D7831F175659618
-:100A9000D8379CC2A67C16BCBC848A731AEDD7904A
-:100AA0009D3B2079E93CBCB98F037F4DBA4174B6B8
-:100AB0006695083B80CFDBBCBF8BB116B2EF178BBE
-:100AC000F358AFB858D30341BEAF5365915B37E4D9
-:100AD000D4B46659EC6E735FC7BC2FCAA4E7AF7974
-:100AE000836985D3A1ED3EA8A13CA604E53129592F
-:100AF000CB75C447177E3A9BEC9EF5D8BF12E0FB3E
-:100B000055BE271FEABA541F5ABF4D573DDC3D0D55
-:100B1000CAFEAFFF3E499DEA3984B79058B71AB173
-:100B20006E267CFE0AFEDEB27E3C7E562EE26762B8
-:100B30001D47D213E63A9AEB867614D2AFAF5CFD2E
-:100B400024D3EFF0B143D503C8A789A84A39740963
-:100B5000E9B50EBA678BE9BB70FFFD8A5697EDF7D2
-:100B60009712784E1FEB6FF409BF2446ED97E6F31A
-:100B7000F6AC9CDB8D83749F84F6963C20E60D8F4B
-:100B8000C375EB87B6982706FD8D437DCFBA2CE35E
-:100B9000940E1F77C4FE1CED94C17D93582C669172
-:100BA000D70F65713DF96EB4BA57CE107F319F4BA8
-:100BB000BDB945AA253FEC68BEB729D3BDA4667F61
-:100BC00083F7C60DDA896F3F71A868C84EDCEC7AEE
-:100BD000C36E27B237BE909DF872D61B4FB4033C4C
-:100BE0001FFED143FAEADD7A3FAD436EEBF9ECBF6D
-:100BF000F0BCAD8ABFED47F63DDD7BE36D2DA4F97A
-:100C0000482A600E7F1F4C8F4988EFD7F0925E8C88
-:100C1000DFE92C1D02E072D59884F8BA55F8A3409C
-:100C200067A75BEF677D2D8BDB5BE6381E2F4BE202
-:100C30003963B35FA083B59457DAC0488F98FBB08F
-:100C4000263F9BFD0C64D9FDE093E0DF814CFCFB6B
-:100C5000B4DCF2A7EFA0FDFA9442F9A05F8DDE406C
-:100C6000EF2F6BBD929E97B75E43CF4FC478DF9254
-:100C7000129F64C17AF535FDFEABD703BDAEDAEB4A
-:100C8000A173652BBEF5D79B913FBDADB0EED8EEFD
-:100C9000EB57DE3E0DBEBB27CA64BF7615F37C0E54
-:100CA000F75A89C7FB75773DC650FE3F378B9AA828
-:100CB00000800000000000001F8B08000000000002
-:100CC000000BE57D097C54D5B9F8B973EF2C496662
-:100CD00026933D210B37842548C049202128D60979
-:100CE0005B632510C40525C0844008109280568798
-:100CF0004A654200A3468D75C3A5BC8162ABADFABF
-:100D00008252A56DA4137101A518ABB5B820417826
-:100D10004ADD12411EA3D5FACEF79D73927B6F6612
-:100D200042687DBF7FFFBF177FEDC7B9E7DCB37CAB
-:100D3000FBF9CE77EEAC7096E4BA0A09F90EFE2EF6
-:100D4000266485731A9649AAD3448A085963A3FF77
-:100D500056093973F8E6D4C5898444DBED6EFA840C
-:100D6000581AB3EF34D132D92F9347289063C8A2D1
-:100D7000F23C0AAD0C0E712984240134218C074801
-:100D8000FBB585244212A09DDBDD60A765C54F5CE5
-:100D900000430A3EB74852795B5EDF7C0414FDD9FC
-:100DA000423221E3613CE3FB167C7E8B6A2985F7A6
-:100DB000E504360FF17E0E7F3F87CFC7168A61F3B9
-:100DC0004830F6E364CF65D2D066EF3F8FF5B1537C
-:100DD00047B992004F9E5C80847499CB1D842CB4DB
-:100DE000BF72481A47A1CD1E9429243EF3A75DB9CE
-:100DF00004FFBE1B06FF5FE1FA700C2112E992BEF0
-:100E0000A343CFFA460A0EA5F88B2A91031BB229F9
-:100E1000945C651326D066256637E0B37378A263C9
-:100E20009866FC0B5C12E2EF75C5E58079964F97EA
-:100E3000CB0379D87DD2E5D0CFF4AAA25BD97036A6
-:100E4000924CC822F66FF2BABAA37918ADF7FBCD6F
-:100E5000EE11948E8B6CFE00CC6F1151FC5D366CE4
-:100E6000227D2721549522FE1E9DEFA269B227CA3A
-:100E7000A96B47BEA3F3241BC90BC369FF0B253E17
-:100E8000809F96E97BEFF3E29169A7AE80657411CC
-:100E90009765186DBFB0AB722619875576E0A7A588
-:100EA000BCDD229FF9786FBFF47F957E7D797171EB
-:100EB000FE4B940C142F81D209C067A34DC867550F
-:100EC000CDFA764BDFBBE46FC409FD2AC77BF10D79
-:100ED000F32477313A4F6F72A9144FE7BB542CCFEC
-:100EE0009A766C1AA1E5D9845C01FDCE9E26BB8260
-:100EF000B4758BCF443C74E2073D7240A26B3B98C3
-:100F0000DBB5FF62C05BB1597D04D69A4B6E9F9BE7
-:100F100008F5E35D80E772789686ED098176A9B6DB
-:100F2000C008FAACD373CC5EA5E1BB83C5C7467BD2
-:100F300029BDB69A484D387E22A411E9FAC24FA2C3
-:100F4000B19F23F748012B9DFF74F99B3F4DA4F3FC
-:100F5000A9FAA9D96D55715926A0EB4C3793474290
-:100F60003CF6E9149F0B092B1F23E545413A7E55BA
-:100F7000FEE1122BEDA76A9384722AF04FF1FD81F6
-:100F8000166FDE86F2D8A08A78D73DA79D59809F3C
-:100F9000299E3F8880E70FB478F6BDF7F6D817345E
-:100FA000ED5A5C8E44E07352400ABEA3A8394D2628
-:100FB000C78E27FDD72DE099F587C6BE3082907B7E
-:100FC00088E76E2E4F4AF9584A278578C2E9815240
-:100FD000279383E9F2A7489F93C5B20AF83AE8FB42
-:100FE000D84E398C1CFC462E053C130FED6C52DF9D
-:100FF0007B8FB92C48FFAD16E2013C6F1D620B34AC
-:10100000D2AE3A7E725E4A17D247BD7F32D0F1151A
-:101010003379448D3C5F874F26C3296396F9248436
-:10102000827E437D514419DFD76E28093FFFDF835D
-:101030001CD37924AD2326958E1BE7279E4018BE2E
-:1010400010ED56D97A662804DB07E3E8FCEA54532E
-:1010500040A2EBCD97183FDBCC0D9E74DA54699F0C
-:10106000E34F27300F19E7A1D2F929747ED9BE18B2
-:101070002C0FF32520CCF1C5211CEE4BC7FA11BE75
-:101080001C84237DD9F87C946F0C96737DE3118EBC
-:10109000F6E5233CCF7721C231BEA9D82ECF5782A7
-:1010A00070ACEF527C3ECE3717E1F9BE3908DDBE99
-:1010B000F9589FEFAB4258E0ABC4E7E37D2BB13C5E
-:1010C000C1772D960B7DAB1116F96E4438D1D784BC
-:1010D000B0D8D788ED26F96EC3F205BEBB115EE825
-:1010E000BB0BE164DF43580F0A08F010CDE5F13681
-:1010F00075898B4A0A70B80A7C1C49EEBEE2F6A8D4
-:10110000D2E5390AF64EB4B3988857DB5EB43BCDCE
-:10111000611CD0354C7F3D5C3F7FEEFEE0BE51A4AC
-:101120008F6ECDA98DE544EEA397755749309DFE8E
-:10113000B36EF71C027A81E426EAF8B4BF7E60EB56
-:10114000EBE2FA6BABD2E991817F1B88DB4F1F95F5
-:101150004D785D827EB6A94A69200CBF8D8E33E33F
-:101160007BE7BBBC248ECE2F26FBF80BA04F66FB83
-:101170005D7F9A02FC9297F8CA14DADFD08D2618A8
-:1011800081AA1257C714AA77D46904F5E2362A72E5
-:10119000B0DE6DD17A7B9A1DC7EC28216DFB86A14C
-:1011A0003C0D2F60F6A7EB12902FCB4F86915BB3CF
-:1011B00041DE829242FBF3AF21E4116133A0FDE6F0
-:1011C000C5BF84FABEFE2C4C8E9AC9F3363A91EC18
-:1011D00056754A1485395B3CCF47D1574604BC53FA
-:1011E000A26979D4A3FEE7018E6E0B4C89A170CC65
-:1011F000EEE0F3D49C92B1C1AE29765A3E7F1FD95E
-:101200000B68CDEF54A73A6879FC21CF5ECA06A4DB
-:10121000B0CB3BD5A9C27C024D4E3A9FADEF1377C0
-:10122000232D177FDA2AC7120DFD2DC4BB53431798
-:10123000C784CE6909F49F19D7B9F265785FE98A46
-:101240008ACBEB4F9F6DB06E5827B5238FD0756555
-:101250007882924BC327657192A0437E1CD8A175FA
-:101260003D0AAC73DBC67807D22FDA550243F64C41
-:1012700027AEED2AF0B18278B26C1A86F22EF88E83
-:10128000E277F41C87166F92D06B356D7991F15B24
-:10129000F66F86DFF7383F47C2AF0D7865D2D9E5E4
-:1012A00078615CAF1C5F03788DD4AE298EC9A7111D
-:1012B000CFDB4C641FB555745CCAA74CAE889F3613
-:1012C000BD89F3F7D9F0EAFB37C3EB157103E3955A
-:1012D000A889A82729BF8E263991F50DF417CE7E4F
-:1012E000DDCEF94DA3E72CE02F36BBA89ECB89AC11
-:1012F000E7AE8E3B8BFEE27AC6C2F5B818EF413EF0
-:10130000DE2BCEF22DA0BFEC9B4C7E90B312E240C0
-:10131000B920A9899C4F5CD1C02733655709E81BC8
-:10132000328AA01F1D9317F0C33E65A85F2D90A1C0
-:10133000192865C0E390DCC0ADB4EB6CEA67289473
-:10134000FEB4AB20409BEA322DA6EB8E15F2E6AA46
-:101350004CD5CA9BB0F77DF228F8227EDBADD98C44
-:101360005FE750FFE56DCE6F7DFD48D86EF3DA2163
-:10137000DB6ED5E8C16DA9A95816ED23F1EF19C1AF
-:10138000BF1B37102FC8C7E4F07EC31B7132E7DBE9
-:101390001E0FF0B9FF07C405FE4CDCC60F503FC559
-:1013A00051FD24A17E62E367F8A27FE9A7E53FC76C
-:1013B00025737DEE8ABED2F1FF8E9F7F45110BF320
-:1013C000183AD9D521D3FAA1D40EA920A793E9DCE4
-:1013D0002700BE2C487795303AAA934900FC5E8AD4
-:1013E000B7A009F4AFC911003B63B1B47A409E893C
-:1013F000250ED7FF8AD37B346E00B970C5A8F9409B
-:10140000D493715F95DA29FF6DCE764543B99B96EB
-:101410005B52E9B8F15D84979BED283FF46F085269
-:101420003148F706601F45D96383F6C37ACB7E281F
-:101430006F059FE402DAFF5D67F66DA488991BE7EC
-:10144000E989637C7D12F8DA338A6E5073FAF8F911
-:101450006CFE8090CF3E7972E50B79AACC437DF883
-:101460000DF42FFA8BE4DF3CC3F5A7237E60FF4623
-:10147000F0FD39FB377CBE7F07F92F8C2CFF51FB29
-:10148000DFD8B28396D7A4CAEA71EADF3986BCD521
-:10149000A9D0B28DFA9BC768D964EB54A05D1995A9
-:1014A000503BC5B7873A79B0FFB04D6065F883FD12
-:1014B000C7C956A994E96B35F6F2B103E13180F35F
-:1014C00059936AC1F1A2460C8F05B97272BE228A85
-:1014D00014003BEE2C76298BB1BF2E7219EDEF3C38
-:1014E0008E2721D7A0B79ECA03BD14AFC07EDD6A88
-:1014F000237E477C5FFF508E2DE8D34F84EFE3AE11
-:10150000E57BA6D60DEED8E120A707591CA5F52648
-:101510002697651924B001F48487A82EDA3E8A88BC
-:101520003F2AB8B46CE6A5995F4BC443E77FE06BF4
-:1015300019A1349C041D74BF57E69682B00FB4986D
-:101540006C01B0A525436CC40265A7296005F9F8B4
-:1015500040C2755A0A6202A0FCA60D298EEDA2EBCC
-:10156000387560AFDD1B86FE57792BDDD3C647C6C5
-:10157000636FBB052FBA008F0FA91B5DE047FA53BD
-:10158000158C3BDC024D357AFDEA786637A93F348D
-:10159000379EC2594B7A365A80DED989E80F91E1DD
-:1015A000F1C8B769A9BB6E29019355CBFCD321249F
-:1015B000D0A8F5AB047FBD1BEF5D104FE143DC8E7F
-:1015C00050B1EC1C09F1AAD189F1E09796D40F69CA
-:1015D000077FF781F5C4BDC48CFAA01CDA7B12DA50
-:1015E000F2817F1F72EF7AEC4EC0A795EE8B418F90
-:1015F0008F3F6C5729BD2A0AF726C17AFE6498BF2F
-:101600008015BE9B102FC67DF0AA78BA0F068538CC
-:101610008E8C837DF029F7DCD820F2564258F9AE43
-:10162000F0DD88FD88FDF07BE660A62BAC1CEAF1BE
-:101630002DC6AF90D8BE969825A6FFB81DA5FA6511
-:101640003DE097BE8676D36395B683BD39E51EEF40
-:1016500006BB1D49DF88F9503C8E287784A997483E
-:1016600079383DF1403CB3D71566BA5FA0F5D2EAB0
-:10167000C206985785C32E01DF89769BE2993D13F8
-:10168000FC2CE25572EC3785407F880F865BFF2289
-:10169000A27CA98D476D02594B62F87287F15722DF
-:1016A000E1EB90B9B50CE67568A94C1A693FA7BC87
-:1016B00013534898F7057C07F886D2A53E818DD74D
-:1016C0004BCFE1E1F177687D8D7B9AB98F9EFDEA82
-:1016D0002BA3E681FD9E0778D48CFB0AC7DF3181FE
-:1016E0001FAB5775D17ACBE27B5D642CE8A92F0B39
-:1016F000FD0E888BF5FCB611E8FD5307C62BE655A9
-:101700009E2E6C1CABC167314123B968EF032E9547
-:101710003E9F37626392DF1E198FC7381E6F8307A3
-:1017200093301EF322F2CD20E331242F1EF98DECED
-:101730008D7207211EF917D90D7E038CEB45FDC96B
-:10174000E2C9D7B9D8BCA20C7EDE3C5F9D4EBFC4B7
-:1017500084241248D09495368CCFC684147C6E9421
-:10176000B75F19E44DE03F123D05FE8DCF9FE7784E
-:101770003F54B95C85B8A1253ABC1F9C96C0E824AB
-:10178000CA6FADF7EAC6FBEBB7B26EBF2CE07F7352
-:10179000FA9EF24E4A8178D53C8B7FC460E45CE0CF
-:1017A000E7AD6FEE7741BF515F59C3CA5F37B74F9F
-:1017B000D49E365FA16AECE9D5F246C07B8CC2F5B7
-:1017C0009B41EE3C6057293E2F06BB4AA718731673
-:1017D000BBBA88F83B208E6C1C5FD853237F09FB73
-:1017E0006AA49BE08384041E37E4F41371C348F2B7
-:1017F00025E4EA5DE0DBC2FEF837C2AB2C7ABF47D6
-:10180000C013BDF488227EAA1FAF2D91034442FE6F
-:1018100040FB78E85E09FDCD60A515ED72556514B5
-:10182000C667ABF265ACAFBA5D46FB19A4FAA196E8
-:10183000CEE74F5C4F18E3B32544724FD3AC7BD651
-:1018400084285DF9EAA577FF693DC4978BCD2A8C82
-:10185000775065F166BF4746FF95F6E10E427CFA88
-:101860009E8BDC60CF043F1CF4C8286FFE376537C1
-:101870000CDBC9E3D1079BF30332D059F2F68EA3F8
-:10188000E640FF552AD0E1EDD42D2ED07751DFDE92
-:101890005F5E8EFB47AF9A8F76933AAB74DE515CF6
-:1018A0004EA70E29BE12ECF891163381B8D191756E
-:1018B000A7509EBBD637B8A78DE88B2F8BF8B031D9
-:1018C000CE6C8C2FF78B2B1BE2C9821F8C7C725540
-:1018D00004FE10FA2A127F503DB630E19FD06342D9
-:1018E0007FBCC3D73975C896DB1B291E6296C88892
-:1018F00007C1976F7F73F3CF410F4751FED800FCAC
-:10190000FCEDAF5E847D08592E858D23FF07E737F8
-:10191000BA4F744FCBEDA3CBD5DEE5BD6510FFF913
-:1019200035AB7BCBB07EA35D89ACD706D65BD9093E
-:101930002C0E6EB43B4679F8BEEDCEBCCA7B73E18B
-:10194000FD79954B03006F1962AB01FD6BD4134613
-:101950003B21E6639C674C482681F1DA79ABD8AE2F
-:10196000CF4E58B0DE67738E0367FD4C14837E70D4
-:1019700002C12F7D3F2AD084E3359C5F8EF36F98A0
-:1019800008D047DC5D7E585F6A34C60F5A33587BF7
-:10199000F99268E68F4F88C775CAC221FF320ECB15
-:1019A0004D7C0DE3E2BD4F02BF35794C5170AE3036
-:1019B000D5A1EC87904BEB1413B1923E3C09FF9DEF
-:1019C000406480AE17EB24D877E6DB2C39E89F3EE5
-:1019D000930074B889EE0B29BF1F3820EFDA4697C1
-:1019E00078C03D3E369C7F2EE082D4B5A817AEF479
-:1019F00055213CFCE3BF6681BC5E2F793B605E9D58
-:101A0000F3AA6E2FA4F3A9DF2DE3B9D282EBDF1E78
-:101A1000C9F669FAF349D969CB85384A9314ED06BA
-:101A20003D22F0D8E1B0A07E693ACCF460D3518970
-:101A300097D93EE2055E7FEA3D07EE3304DEE97AA0
-:101A40003A613D9EBBE3703D629FF12FACE75DE8DC
-:101A50002FF27A325CE80F005FC97DF3971D0AAE62
-:101A6000AB9B44BB61FE3E1E0F22EF45A1DF2CE87D
-:101A70005BCFF94FD0B78ED3B7BBFDF41D17D2F6AD
-:101A8000AD9E783C65903309AEB7FBBD18E40FB14D
-:101A90005ECA07DD80EFBDEDCC4EB4BEEF60F872DC
-:101AA00014E5C2FC847FED4A607EB271DD157C9F37
-:101AB000FE7502D34BE0DF429C6271FC94AF130AC7
-:101AC000C3B4E77E2DC5F3B780971217F93240FAF9
-:101AD000F02CC611E38AF7A212F5F255C1E30AEF22
-:101AE00099C93C8CD3D2710B34F35B1B5F12959870
-:101AF000D47FDC7F818E898903F2A59E8EF58ABD15
-:101B0000598A25BDFB620CA5A9FDE5DC2867527B3F
-:101B1000C757703E6F94FF33A60622D17E6F90BDEB
-:101B200087E2296CF2922E6B4E7F79389B1EA1F4CE
-:101B3000CE4B4CEAAF4F064BE78989FDE83C31714B
-:101B4000003A0F8B2F9F04F5B0FEF402DCE75D082E
-:101B500065D0139661381EF2654F1C096CA78D1273
-:101B6000781C45CC07E21251F4BD1F256623FD25E4
-:101B700085F8CDB49C90EB9640EF0F820F7EA49D2C
-:101B8000DFF7C007570CCC0741F44B56717AAF1200
-:101B90007916BB06CEB31804DDAA60DC3326778F36
-:101BA00037FBDCE956D79F6E7503D3CDBB1AEA9B92
-:101BB0002CE44BF4C38B2B5361BC579C9EE3B1F4D4
-:101BC000F99E46AE4FB229DD68FD8B8932EAAB9FA4
-:101BD00091F3500FFFC064C2F97753FDBB3D3B1C2E
-:101BE000DFFB9578FAFE99CB089EC7D1F5F9195F0E
-:101BF000FA25787EC3226282E7A96A23319D831E7B
-:101C0000BA8DEB09CD3A6F4B0C6397357AE80EA885
-:101C1000A7FC781DF0A34D752903E9A107CF5D0F3F
-:101C20003DF83DEBA14706E6BF73E6AB27C3E903EA
-:101C3000C1C7625F10295F88CA23498FEF3F2E21F9
-:101C40006E3C0F2B71DA98DDDD29A19D6D3A9AEF7C
-:101C5000C5B2C3864A41D8E193BB58BD3C25BC3FC1
-:101C6000F86C623CF2EFAAB6D56E459707E2477A68
-:101C7000DCE939E91A4EF5E20CD98EEB4B2863F119
-:101C800043B17EAA67674E4FE67153BA9E844C8675
-:101C90008704EA0FC0399A93EF0F628B159DDF2FEF
-:101CA000F076835C2E41DC3B2E9140DA0DF5EBD7CC
-:101CB0008D82F3FB388FBE7D1269F942C64108CA96
-:101CC000433CB5DF10C74A2835B4837DC83868AFB8
-:101CD000799EDD7F3F713491EF272C2415EC0A911A
-:101CE0002B06E41BCD7EE244E220F6139F278AF305
-:101CF00071BDFD6A8B2261E302EB92B8DFFD651CCA
-:101D0000FABF32B75BD3BAB2313F658D43C5788134
-:101D10002CBB6D33B3FBBF1FE7311155B3BE84D26B
-:101D200068A26AF60F49E5F1BA72CABC21BAF6692F
-:101D3000DE61BAFAF49AF374F5990D05BAF250DF40
-:101D400005BAF6D95400B4E59CE61FE9DA8F68BD00
-:101D50004C571EB5E51A5DFBD181C5BAFA318FAE7D
-:101D6000D0D58F6D5BA32B9FBFFB27BAF64D3CEE02
-:101D70006BC4CBC5494C3F37294CEF34DA0B301ECE
-:101D8000D964D7C723D338FE4B6227E7421CBCE98E
-:101D900083FC5CC0F70BCE0B302E1E892F8C7A2C67
-:101DA00092FE343E2FE6E37DFEBCC5047250B79729
-:101DB000CAEBF9B46C7F6733ACA9398F9DA72A842D
-:101DC000E5F788F315F17EEFF98AE266F155A79DF4
-:101DD000DC1A862FD292F4EF093D29F82812DE048E
-:101DE0003F9E0D6F9EEF096FEF49649E761E15FCB6
-:101DF0003CDBF8DEDA24133F0FF65E93C4FC9D094A
-:101E0000D1E889BB501ECF55FF8B7950FDBF3409F7
-:101E1000F7136F2CB801F4FF2EAB1BF6649FCF7B3A
-:101E2000A3FA7E15DA57B3F626772ED02552FC7B1F
-:101E30006D52BFF8770D8B7F47EBF0B64CC8BB21D6
-:101E40000ED7E4FC1AE3DF4D1677EE60E2DFCBA09D
-:101E50000F383FE474EEA52F8F9F47DA07F908D9B2
-:101E60002FC1BEC7AEA870CE75B67D2DDDCFE6C240
-:101E7000796A2BEC9B34FB1CBABFE5FB9B28B40BA7
-:101E8000D4EEDD9184EB22FB55FAFC0CDDF7DEAAE3
-:101E90004251D83F8FCE2FB712B7CD22233DEFC18D
-:101EA000F76E22D745C9102F0B1E989CFD2FD9F332
-:101EB000FF481A707F68B4AB673D9743BB5346D762
-:101EC000BF218CDF653C87EBF5BFC14F93F03C0E23
-:101ED000F1B489DA45388FEB4862F679D361B64FB1
-:101EE000DE74744E2ACA4D52D180E77083D5371DF7
-:101EF00049FDFCB58EA401FC35B1FE357CDF3B5DB0
-:101F0000CE6B8378E3C99005F12613961F59BFCF96
-:101F10004C02484F96672CE8680E6DEE04FB6C2669
-:101F2000C6BC623516D66DDE27A37E2289ACDE4F95
-:101F30006C8DE0E7C416EBED569C476FB7124AE391
-:101F40000D764C6FB752E6E9ED569A576FB7D26BE4
-:101F50000A0C764C6FB786FAA618EC98DE6EE5345C
-:101F60005F66B0637ABB356A8BDE6E8D0EE8EDD6A8
-:101F70009847D718EC98DE6E9DBF7B83AE3E3F78C6
-:101F8000ABAE7EFCBE9FE9CA859D0FEADA2FDBFF70
-:101F900034E6DF4C3CB45DD76E52D7AF75ED28C246
-:101FA0003B214F7B099284900B4F3CA5AB5FC2FD58
-:101FB000B48B7A7EAFEB87B4B27C6B3FFD0FE8F554
-:101FC00011F15AC0395148CF4BE994AE7501C91D82
-:101FD000A4CD96EFDE5904F3F8E4FD4BF6413FCB78
-:101FE000B6E8F3B49707F4E57A322C16F4433DE5EE
-:101FF0008B00E5939590BFADD16B2B498313F321F3
-:1020000006C967CBF6CF2598F7E9F774427EBA5830
-:10201000A7E0370FE737313FB1DE95D4EF0BAA7D4C
-:10202000EBF4D0FFD83EB2CB027C5BBD5B220F4A03
-:10203000FDD753D37ED7E6F430EB32AEC3E877BAA0
-:1020400093F5E754D3653BC6F54FBE29BB597C5089
-:102050002F876BF6B378FE9A27248CAF19F121FCF9
-:10206000D2487891FD6C9F509F4802018DFCA91CBD
-:102070001FD654BDFC9D847FC07C1E960390171410
-:10208000A5461BF9AD2848FAE33926572FA7463C49
-:102090003BDC43C2F2954AFF83795413762E65E404
-:1020A0002B23DEEB76DF6501BD78AE785F64C0BBC5
-:1020B000383F28A1ABB584C9831378A5FBF2A5C925
-:1020C0004991F7ADAB9325FDF9F2D9F7ADAB93BFCD
-:1020D000DFB8C9BAE401F6ADDD102FA37EA5315EED
-:1020E000D63F3EB6F72BC989716816FFF2BA6D2C40
-:1020F0005FC5602773537576B277DFFB8114680282
-:1021000039767A6E83F9D43A3D2D007FE4F4DCAE63
-:102110005D6F13C50BDECFA1766A6718FFF0E5642B
-:10212000E11795635C6453096B6F6CB7335941BC1D
-:10213000772415A5A2DF79349FD94F47D1807EE758
-:102140009DFC3CE736382F1CD197C7733B3F57A106
-:1021500062E701BA6D3297A76AF37CEF498EC3F14B
-:102160009C939EEA847CE72697C925A9E03F9BF0D3
-:102170005C74A3C75EBA2B8FBD97A87B8FDD3B92A3
-:1021800001DFE0CFDB95AFB57CFB32C525F41B69E1
-:102190009D2F27337FD74C3C36D0BBE23CD7FC4148
-:1021A000BE0DF4AD22B95DE1F238CD3C4F6A0A3F75
-:1021B000CF955DEC7CB757CECF922755E7F4BE9410
-:1021C000ACF117C4B9EE954ECFCB404F9FE2B7822A
-:1021D0007FE9B385DFFFFE89D3F156BE3EEA682270
-:1021E0001FE1F8F2A0E2276F25635CCE8FF98A37F2
-:1021F000C8EE13109F1B6CBCEA6872BFB8DC512D8F
-:102200001F1AE58FFA9FC763E17C22768882DB097B
-:10221000C59D0BFCDF0CFF9E84F1D513F07EBFFC47
-:1022200053359EE7D3AA03E6D38A7EE6C679BA93EE
-:1022300059DEDF17003DA35C1B654D3FCEB3F44371
-:10224000F194DB601F14FEFEC1F0E73EC18209E796
-:1022500016D78C4AE9E73F46A50CE03F9E393C2A59
-:1022600016CE9345DCCAD8CEE64BC8D0DE8F698E39
-:10227000D38FBFB9809513F9B8CB6319DFE7F2B2FA
-:10228000C80314716BDB4CE281FB0E3FE3F9D9A26A
-:102290009FDC1407B68F8B9F929B5208E76912EE62
-:1022A0002B37C749BAFDE5F1E4925C58CF30DE7FA9
-:1022B0006E0AE3D36DC3587CC69807F9196FFF59AE
-:1022C000F214849460A3019F16590E8BC7B1296C38
-:1022D000FEC76359BF227E56752FBBDF25E26622FB
-:1022E0000E483D83B762A85E39D6622610D75A2AB7
-:1022F000DB37031FF6DE9FE3E7EA2EFA1FD8CBCACF
-:10230000BC72CC3FFA57EF6F013E63E2FBDBCBE9D7
-:1023100029BDF6D27D8EF7B86632FC0CEEBCBD2B23
-:102320009AF16D8FC38EF16C63BB6A4E9F161EA728
-:10233000007D0D76235E260DE1EC4735C7FB99C382
-:10234000560FFA31A5D198CF21CE3F14CA9FB1F1D3
-:102350009806EE0768F3A567C07DA2DEF30F95E04F
-:102360007B09763BBEA7A824E8802BA18A5B82FC70
-:10237000B22E4BD7A61498EF45921BEE0FA454B87B
-:102380003A5212E11EA18A62B6399B388BA13EDF18
-:1023900084F57197BB369B21EF5A2570924DCC7412
-:1023A0001C071DE78E946C5C7F8B7F6E470A6D1750
-:1023B000ABF6906179A0475C3352418EE7B1FC7572
-:1023C000E3FAD6A730BCD937D17D03E0430D9F0790
-:1023D000BE3E85E501513D7313D0A34425BBD8BD56
-:1023E0002896870A69D6982FE866F9D231906F94BB
-:1023F000C3F40CD4DF15377523C88F902F99E31BD6
-:10240000F85E9B0F7F07C77782413E053EE9008D4E
-:10241000900FA1CC24C8D7B32BC2CFF7314EE77AA7
-:1024200067F93D30EEECC98D98E74EBEF9EE3BB949
-:10243000089C5E2627F47D027188A844A67FA354D9
-:1024400015F531714998676A53DD35508EB25FE0FA
-:1024500092C1EE59F979E1121351A8BC4DE5FD780E
-:10246000E611E9C35C166765FA55211F0AB9903970
-:10247000728AC07EB23FEA17B5C4D0F54CB51FC012
-:1024800073C4A8E10D2570AFE0C545AC8F9F45C86A
-:10249000DB3FCEF558BCEC4D35814F4F8EBDFA4237
-:1024A00006D2F93CB8A179DBA6C3AFEEBB88C7CF93
-:1024B000215FDC7FF8554FDE3F9F5FFED2FD875FD7
-:1024C00085FCF27F9EFFDD12E8F1E394B160DE4609
-:1024D000FE17FAEC90EC3D7423C5FF1594A97C051A
-:1024E00000155281F466F94397733CFBBFA678B69A
-:1024F000F5E1F98AF6FD88BF43663A6F3ABE790A7C
-:1025000043B5F927B13C1F2380FD5F696B9D0EFE2B
-:102510004DB7A5671C8CDBFDDC5F33FD549F1CFEB3
-:10252000E92907A1FC7744E971C0F313EBDE707869
-:10253000E87A0FAF93F1FE1BDE4BD6E4039DE07CFF
-:10254000353DB5FC08F0D5A2F5DF1669FD6CE24B10
-:1025500042BBBB3C20C31DDF5EFDB7F2D118CE7479
-:10256000ACBCAA2D415716F6789535FC3DF1CC54FC
-:1025700046F7E58F6FB3403EFCF454EF1730FE0989
-:102580009E6F70629703F757623E8B1FCFB7C07E76
-:10259000F248BB950481EF954E33C1389567A64448
-:1025A000F9D6CBF9D038CF97F6C4607F4BEF953191
-:1025B0008E5449C7F251BC7ADB97B3FDAD611D4B18
-:1025C0000FAB33405F2DBD45227E95B55F47E9E6F1
-:1025D000F5DD8CE72BC6751AEDCB69B2CE027AC455
-:1025E000685F961077F364B05BADFAE7CBDA6FC340
-:1025F0007E979DE53C262195DB9B2232F1BB1C8812
-:10260000330FC37CC148F6E6C47A26941FAFB721C6
-:10261000FC74BD0BE11150A614CF2B7777BC948EC0
-:1026200062DD590476286AFF54DB35A4CF7F56B6A5
-:10263000CD0D3EA4025FEAF3212B389E85FFBC8CB2
-:10264000DF33389BFF5C01EB1C201FB26290F990D6
-:1026500027F78DB7C1F3C2547E3E3591E203ED6F8B
-:10266000DE6B2A39BBFD8D849748EFAD82EF1C8469
-:10267000C1B3909B23DC8E2CD93167F3103A81A62D
-:10268000E73ECAEA42BE647108714E25A76EEE8429
-:10269000F5CBC410FFF3933789867F8DFCB98CB8D6
-:1026A00099DDB1B3F76C3C2ED1CB97EDB7235E0526
-:1026B0001FC18D02532AC060AAA9B8FF7703FA7D13
-:1026C0001FA0555FFEDCDC95057A6399215EF0B9A9
-:1026D000147EFFF5C3D4616CFDAA6706E4452C2582
-:1026E000E59B595CBD159F9F505A5FBA11E479076D
-:1026F00093A755CF3EF10CE8A915FF79AF13F4D499
-:10270000DF94D66418AFF6914D4ED0EB2714BF136B
-:10271000DEFF5B400E7B5F777BAA24F2E2ED901731
-:1027200056872C0602E69F057AF2BF1F31BB208E2A
-:102730005AFFA83568A5F8A8DBC5F048CB4759F97A
-:1027400066C457FD6EBD1CAEF8D5BDC92AEEE7FDC7
-:10275000E91C7FE9A0AAEB7698317FB4EE4DD90D44
-:10276000C3D4931E5C9FF17D984788D2ADBE4DAE19
-:10277000B4C4F6AFA71E8F05E4AC7E17A353BDC14A
-:10278000CFACE17AD9C8EF3F1372CFF99CE205E3F1
-:1027900061229F9504987E6E7AECFE7147E9BC3EFB
-:1027A000DDF1AA53CAEBE377025997145F27DBAA3E
-:1027B00016419E41243EFF9CCB45AFDEE77646DDC9
-:1027C0004D2706BE7F3B83B5E6A0F3428A8FDA6DC4
-:1027D00066B79F3EAE7D42F6D8C14F7ADB8ADF777F
-:1027E00058F9C48B6F5D40E7B772A73971265B86D5
-:1027F0001DF4B3A0533DF077411F5D563CFDA2058B
-:10280000F220E1F9BAF83EFAACDCD96181BC4A2386
-:102810001EA7B67558987C19E8D4767406D8E5A634
-:10282000C7CE58800FFEB64722E0421ADFAFD9F676
-:10283000A213F407E009EC87A0572FFDFAD12D3839
-:10284000EBF713B09D0BCE6922D1EF5A984B12F2E1
-:10285000F793BFA7E3D7BC6375C3FA6B9EBCD609D9
-:10286000EBF84869607CFEF34DC9608F6BCCFE6469
-:102870001742F6BC66EB8F91FF96BDFEE364827A49
-:10288000D39306F24BD79906EB5BFAF015B8BE6A04
-:10289000E245FEABF9B95C0E7EE269859486F3F3FE
-:1028A000D3D3989C7CB4DD8A9B828F2C847D87E374
-:1028B000CF32CBE323ABD10FF9315F2BD5C4583ED8
-:1028C0006D6374EA4E357139637AAC9EB7AADF71D5
-:1028D00033EAB18F333D2920EF140FFA78EAEBD3B6
-:1028E00053B8FEC3EFA5E07B94EFA6C27368DF691F
-:1028F000F6448DD3BDC7F35AD9F8D7F1F1E9BCA39B
-:10290000212EF751B27EFF2AE02569220E463A8930
-:1029100096BF22C9FD8E5B90AFBE7C93E995BAC08D
-:102920009C52ACEF340753A03ED071B9847A81FA3F
-:1029300017E1E47A8799CBB5BE9ECE5391B4F8DD0A
-:10294000C3EEC555DF43DB69FC903EBEB1F43DCF1D
-:10295000EE934F915FB1CCE09F0968D40B49697A3F
-:10296000FB27DE270F2785BD87D5A70FFC88B75A21
-:1029700073E0970F821CBF6DC57B86B54F98F17BC6
-:10298000399F3CBEF7AD6B28BF7FD226E457AF67B7
-:102990008DF25BF3D415249CFC7E92584EC2CA2F54
-:1029A0007D1E567E1359FEFEFFB69E5D1641CF5E1C
-:1029B0009CA6D7B3D49F88BD90163FFEF5CAA1B898
-:1029C000CF32E055E0D3A8370FA5AA885FA3DEA4D5
-:1029D0007F6F120D1E05FE045FAEF8CD2A1CA7976F
-:1029E0007F057F0AFEEDE54FE37AF57834D62B704C
-:1029F000E7A8B08FEEE60D747F0DE7AECFC978EE95
-:102A0000DAADF638E3212ECBF36EBA5DBC1CC7CA33
-:102A10003D4996CDA03FC4F39E289687D05DDEE366
-:102A20008CD3F8F547DB6527E4D57705C2E74B6023
-:102A3000264512DC128D54DFC8BF5B63CFF2C1BEE6
-:102A4000AC959DF72C69BCCA09FE74777BCEEC79F6
-:102A5000E0C7EF97D1A7EA8EE6F9557E8F9246F14F
-:102A60005AC5964C4E10FF7DE06757B5AF9C099B49
-:102A7000C6252D7A7C54DB2FC7F3ACEA7BCC7D7C5A
-:102A800041C0DF0958C0CFAA7958FF7C05E4550141
-:102A90007D0C7CE4053E0A730FA359F0513EC967D3
-:102AA000FB647E5EC5F5DA74396FF63CC85FDCC73F
-:102AB000EE499C6C97C96658EFE3FCFCCA9F84FC06
-:102AC0005947F9581BE7FC14F86C5464FBFDE96F97
-:102AD0000F17DD489BD43EF3EEB88728FCF499B776
-:102AE00047FE01CACFFE35EB5DD2BFFDD43D5F2D61
-:102AF000C43CCA3D5602FBA2EE3D2F67DD08E5DF70
-:102B00005BDDA8FF37B0FDB17F8F03ED7A7726F349
-:102B1000FF9A9E3B33AE0BEDD346A4D7D369EC9E10
-:102B2000EAC9F6BFBF2F413E5D3B5D15D85DBEEFE4
-:102B3000AAFF7D14EEAFBB9F3BA3DB57FEABEBA917
-:102B4000E3F795BA1D641EDC2FEE8E63F73BEBFFB7
-:102B500030E917705F71D5AE0E4B15AD9FFAC76F98
-:102B6000C781BEE97E8AF913D4BFDD0A2EF59E0720
-:102B70000EB49829FD3E079F6F0821573D682F83AB
-:102B80007B18FDF1C2F0D04DF100EBA278A9013D18
-:102B900019091F7FF9B7C5C7170B61FCDAF689045D
-:102BA000E2E97D78913CECB903F32EE8FAD9F33DE4
-:102BB00067C6817F74B6F59E4A63F765FEAFAC3792
-:102BC0006EC8BFEB7A19BF3F90A6E23C8D7CDF9FB9
-:102BD000AF9FBD1ECB4F3ADC38DF41CA7BFE90FF72
-:102BE0005BFC3DFBDF76BD67A3F77E4E6F870BCEA8
-:102BF00053BA9FFB368B9CC3BAEBFE3F5D77AF9F0A
-:102C00006372DB26D0F9BD430257944891F3381F15
-:102C10001AA2DF47CCE27EC4ACC46AF41F667958BE
-:102C20007CA58914EC837B6A7E8F8CE70E984C43DD
-:102C3000F1D079797E00F3B614FF88FB208FEBCAC0
-:102C4000556EF69D2FFDFE6A56726929F86F071BB7
-:102C5000E9BC68BB830E93AB892E61B647467F8F74
-:102C600042F4F3FE32E552CC0B995DACDF675C6356
-:102C7000D8375C354F5F7F25D99E04F97757D698B2
-:102C8000315FE80A43FBB5435CB8CEAB48C32616B8
-:102C90009F39373CBDCAF1D41F0F03E3AD1F9EF827
-:102CA0007E127379D4FE78B37AD9FED24A2BB8BF9C
-:102CB000C5F3E4D60C0A9F84EF3BAD7C68815FAB23
-:102CC000877DAF53D32FE245E0FD5CF12DE864C46E
-:102CD000BBC0AFC09B910E5BE14C42E38FF74191CB
-:102CE00047E225DA7CCB59BD7EA31DF1F8DA0E76DA
-:102CF0005FE1B5E2AA967C283F2EA1BF767AF278F2
-:102D000062A3EB3D6826BBD9FD2F8FEA2AEACB6789
-:102D1000918A5FC67305C827D4EE4B219F50BB2E06
-:102D2000C827D496219F50DB1EF209B5F5904FA815
-:102D3000AD877C426D19F209B5ED219F505B867C11
-:102D4000426D7BC827D496219F50DB1EF209B5F552
-:102D5000904FA8AD877C426D19F209B5ED219F50C7
-:102D60005B0FF984DA7AC827D496219F50DB1EF2D4
-:102D700008B5F59047A8AD87BC416D19F205B5EDD2
-:102D80002F0E3DAF2B97905775EDA7DADED095A7A4
-:102D9000BBDED5B5FF61EA315DFD25EA27BA7A4190
-:102DA000FF4B734FE99EC39985BF08F631ECAFCC5A
-:102DB000FD775D3F0A29C738B3853420B441FC96BE
-:102DC000C268D286D04EC51CE0F491DE11E9C0AFD6
-:102DD0005BFD9B81B90E4E3A9305FAFFB5C9735955
-:102DE000FC819F13CC867FAA948963BEC9807DAD88
-:102DF00038F7748664121C4FF930242174856248B8
-:102E00003081F261280A617C28019F2784E2102624
-:102E100086D2F17952280D61722807614A281B6118
-:102E20006A680CC2B4D068844342E3F1BDF4503EFA
-:102E3000C28CD085F83C3334096156682A3E1F1A8B
-:102E40002A41A8862E45981DBA04E1B0D05C6C9743
-:102E5000139A837078683E3E1F11BA1AE1C8501564
-:102E6000C251A14A84B9A19508478796233C2F7483
-:102E70002DBE3726B41A615EE8467C3E36B416E1B4
-:102E8000B85013C2F3438D08DDA1DBB05D7EE816B8
-:102E90008405A1BBF1F9F8D05D0827841EC2E7853F
-:102EA000A1071016857E817062681BC2E2D06F1088
-:102EB0004E0A3D86F082D0D3F8DE85A19D08278793
-:102EC000FE80CF2F0AFD0EE10F427BF1F9C5A10E66
-:102ED000849ED0ABF8BC24B41FE194D01BF87C6A6C
-:102EE000E87584D342EFE2F3E9A1B711CE081D43A0
-:102EF000F8C3D05184A5A14F105E12FA1BC21F85E2
-:102F00004EE17B9786BE403833F4777C5E16FA0A32
-:102F100061EF7E7F72A47B895ED37710D7B2C70F33
-:102F2000EA3B5F846CD19D4BDD1FE3443D397B1D43
-:102F3000CB23D95C726A1AFAB5ABAD2AFFBEA641A3
-:102F4000AF7E6307FF6113D4A4B13E200F7001E789
-:102F5000DFD78AF72681BFB4B9A0AB16E221B767E5
-:102F6000775500BC339DC5573773787B3A3BCFAC60
-:102F700018E9C272C5EA11787E451207B78ED78666
-:102F8000B0F744FBBA4C5EB6F764E1BD8041F6335E
-:102F9000D87667CB8FBA2EDDBB1DE5BCDFFDBC410B
-:102FA000BFFFEBF4C27FE9FDA7067AFF08A7972BC6
-:102FB000A3FC199CA7E21907F55336A4C989B49F4D
-:102FC000CA16C90576B26A63FE0CA05F01F1603CC7
-:102FD000714184BCAE7739FD16379809C41517AB1B
-:102FE00004E3B98B77B13C5F88839651BEA8E17C3E
-:102FF000B1EA969D1670416B1A96B1FCA3008B3313
-:10300000D9E87FC0CF2B5AE660FED1CA47F5F1A7B9
-:103010005A88EBC8708EAC7F5ECFE34CC678A53182
-:10302000BEF4663A8FFBBA59DE11913370BDA7E941
-:103030007A219FC37BBDC306FA9FE201CF49C4FA40
-:1030400045BC52E081F4BFCF8079A127F78DC03C09
-:10305000B593AA9A02EDBC549C3AED90FFE09D080E
-:10306000CF29FE309FA4A73106F3918E527DAE4248
-:10307000E293CB3B11BE9FD6F54E26E1DF6FD49F86
-:103080001BD85A30FFBAD24C07A6ED2A1F49C0FB05
-:103090008FB4BF71BB211EF98819F381FC644D2ADE
-:1030A00029EE7FAE50BEC98CFCB178771CCB0FF3F4
-:1030B0007BDE847C7D418FA31B7366405ED1E2E69C
-:1030C000EC7C0CBBED36A39F27CE4B059DFAE74564
-:1030D00097C7C2F7115734BF8EF4A4F4D2D5D7B630
-:1030E0007C81F70728BD8E47A0D7F181E8159DC1E7
-:1030F000E3816E912796177B1554AE4B4039ADD8BE
-:10310000101CD1A0E147639C9E64D8F1BEA3C827E0
-:103110002E1DC2E841147732D0F5544B21D2CB4852
-:10312000A7D27F54213DC83B0EFCDEEE821CB2E8E4
-:1031300032FA7C118F5B2E68BA04FDE79C0CE6D74F
-:10314000BFB61E722D09797DBD8D78A8F3FCC67AB5
-:103150001796FFB23E15CB7F5DAF227C7B7D2EC2E2
-:10316000E31696CF23E4893200E6D58DCE60723423
-:103170003A43ECABAE4B85B874E93FDE2884FC9E45
-:10318000247FD2ACE999E877EBF234E65DAECFC3A9
-:10319000E832F33CAF5B24377C476571F985BAF6BA
-:1031A00024777C5F19EC07CF1B59DC1C87DF6FBBD2
-:1031B0007A6682AEFD95CDE9BA7249868AFA754E75
-:1031C000698EEEF935156374E54AFEBB09C4166DC8
-:1031D000D29E4F51CAB23C6F176BFB65C3C4941BA0
-:1031E000E8F85F1E3063BD911EC72D7EDC8FFBB7F4
-:1031F0005BDD60874EC03D325A3EF11719F5DD099F
-:1032000033F1BBA8EA3E21918D0089C2E4E9F421A3
-:10321000264FA5FF9009ECC3C9AFAD787E57B545E1
-:10322000227EB843D543314FC7BDEE312BAE7BC9AB
-:10323000169978F1BE92DA06E7D6D73D32CA0DE785
-:10324000960B728299706FAFE7B751EEEDB4B6AAE4
-:103250008BBD7F82EEAFE3202F492AC0F383CFCA14
-:103260005AAB4D906F201F480239FDEC2919E32914
-:10327000CB57FFA5C8057AEDA5B6B78AE938C75B75
-:10328000651CF79347ADDB6494774F0A7CD7B56F25
-:10329000DD018C33BC945ABE2283F2C1C7D5817143
-:1032A000A877D6B1F8767FFCD0F502BD815F357A7C
-:1032B000ACCF6EB17332AA7CD2403F5499DD786EA8
-:1032C0007ABCC58CE77954FFE3F9FFF1D60413D338
-:1032D0003F4F21DF2D56548B76DCC52DB287FD2E56
-:1032E000846A81F992BB642F99086596AFE06F9666
-:1032F000BCECBC464FDF6B574FC4FBC5C6FC290175
-:103300003FA732E5D59C03AD788E9DCF92095D8AAB
-:10331000367F5CC457482AEB5F7CC7A776D8FD7719
-:103320004CA6F0A4877D72F0F40E07EAC74F4DCF8C
-:1033300017DD40E12765FE0F154A9706D97B5F062A
-:10334000E4EF985AB64A782E72EC0E388FFFF809DF
-:10335000B31BC590E76BADF8F5F2A103E507C10C0F
-:10336000D8F97230594A85AFF212CCDF984FDA782B
-:103370007C20C0CEFF6112143FAE5A768E75ACD061
-:10338000712BDCC3AD32DCDB3DC6EF2D3C96C1FCBE
-:1033900021619F3FE2E52A13934FB2877D7F11F2AF
-:1033A0005E866BECA9D0A7BB3386A1DEE8B5ABA4E3
-:1033B0000DF54A35FF3E70EDA356764F47252E900A
-:1033C000C7E584CB1FC8337D6F85E589FB809D975A
-:1033D000914EB4731F9B03D59DD9F0FEB68DF1F8C5
-:1033E000BED91D00F9E576C0461507E88F6584CD86
-:1033F0006F55AB14086AE214E2F73808D8058DBEA1
-:10340000E96F0FF4766029B7774B8921DFA7556FF5
-:1034100097CA631CB8AE15AD3CEFB9775E32F98E32
-:10342000E2ACDA1B786916CE5B7207C2CC6319E98D
-:1034300009C27780573DCEEE0319E7655CC760E7A8
-:1034400059ED9E330DBE27DC3BAE61DE02DF042E5C
-:103450002869E820F05EED67F8AC6E97905EFFC5D6
-:10346000FD2A71CF4ED07D19299F057A6DD93D7403
-:103470005F98DDC707BDF67A6700FDA54F48ABD35F
-:103480004EF9BF76CBCE2B27C17B0FBF6E01FEAEB0
-:10349000880F8E30C5C14FD2DC7847E94561ECBB5F
-:1034A000C19E7F5FF8213CCE84EF517C2CDD2163EF
-:1034B0005E83A61D3FDFF7337EF613CC23AA795334
-:1034C0007637D1A735F0733E05E73E5F819FFFED6C
-:1034D000791BFD989CCC81FD18A37EE9E7C718EC09
-:1034E00027DC9B007BD993C4F2C0BF543CB1F1A848
-:1034F000970D7A37A900BF3B2AF46E35B77B629CE3
-:10350000A560EF68F9C32D4F3B21FEF05FF73C9DAE
-:103510008C7914605FF2FAECCBF5556CBCEB9F8DA7
-:10352000C2BCA5CFCA3AC781DF57F1F3979DDAEF46
-:103530009AAE48F59664827EE6F67095BC2DCB0572
-:10354000F6D0173EAFA2DFFE2BD23A1D6759A74334
-:10355000BFCEC5B04ECD7D902ABECE0F9AD9FA8E81
-:10356000B5B0F52EE9B74E3F9E835CFF0BABDB8F0A
-:103570007E4610EDF8899D3281FB67BD7E86C1EEE7
-:103580009F26AD5B011FABD6FCF57D85F2C5F291A0
-:10359000143F940F2AEEB2A29D5FFE5B76FEF9B156
-:1035A00054928207F02F049D6BE9F315D43F00FF7E
-:1035B000A26F1EBD767F39E0B1D7EE0F127F753C4A
-:1035C0000E55D7FE32FE5E94E461F99075E23B3011
-:1035D000BB0DDF81514107B07BF236A0530651D9B4
-:1035E0003E511F4FFDEF115F2C5C83FCDF3352FB1C
-:1035F000BDDEFAE8A019F27D7B764AE817ADBAAED7
-:10360000C4594220BF95C5C1366732FB25793C9825
-:10361000F762A5748DA6E3DD92A9B2E7AA8BE575E2
-:103620003F4CF0BB3362BEC6E7101FB781FDB39BB2
-:10363000D0FE19D7BF3B93F9CBAB6413FAD3B516C1
-:10364000E65777F3EF3EDCC7EBEFCB64FEF5C399AB
-:103650002C9EDF0D7E249C4F5F64C5DFEB21641A36
-:10366000C6C915C2F84F117873299FF7CA37FACB2C
-:103670003D1980A785A4D30CF49C553C47857B035A
-:10368000EF27DBF03B4AF4AF1CFA99CFFB396866B1
-:10369000F704DE8731E8BAE6F378F2FBF019503A26
-:1036A000FEFB6916F463FDCF59D14FB8399AC5FBBB
-:1036B0004862AC027C7E0DD7530B265B3D703E30DA
-:1036C0007FF2CDE500697F7E42F15561EBD9944FE1
-:1036D000C76934313BDF184FF0BE24D9D85508F8FC
-:1036E0003B9FBAC590274F57BFEBBB8481F8487FFB
-:1036F0004FA116E20A1710C660C5885F5DB9D6C231
-:10370000EA0F661E99754F06217F866C26B03380BE
-:1037100023E08BCA58DCE7CE863CFE78800AF2DBD9
-:10372000650AF19B186CB6E37788585EBF3807B915
-:10373000A2980463E9FA82FBF5F728AE0A9A82A3FD
-:10374000E07C47097600FE4C36D5ECA2E394974A1C
-:103750000580F7DA0D839BEFD1CC8F67DD33999627
-:10376000E17B5730CFB512E6F3CCA7420F7CBA50BD
-:10377000212FC8058C7EC087F5F1AA1FDBAD667CC2
-:103780002EEE6F08BAE4D3EEB5F89DCFE747FB699C
-:1037900076C2FB96F07193CF32C53E8FF9692BB993
-:1037A000DCAE147CF7B85E5E63B354F63D35F007CB
-:1037B00029DEE6731889EFED59AC7F7B16E3FB1029
-:1037C00097C7C18EB7CA4A82B8EEE7AC484731EE18
-:1037D0006C0EA3B358FEB29887E0DF6AD280F93747
-:1037E000D53C1E63A29A04F3745B7F81F9FDC63C4D
-:1037F00021EA2061DED98A1DC6E79A788EACD34BC8
-:1038000018E7942C3D4B607ED20FA2DCC0EFF32D65
-:103810006D180F30B633B74A28E7E666EA4F49FC21
-:103820007C8B96AD2D12FEBEC3FC8C9EB1F8BD7292
-:10383000EE575773BA52ED3D03EE0155833F85E7CE
-:103840005FFC3B515B981FA970FF77718BDECF98AF
-:10385000BF51E36732A0BB576F35E4879BB9BF7197
-:10386000C4D23316F4BDF19EFD11139BBF3F996086
-:103870007EA4B867AF707F52F0537A9659773E2690
-:10388000EE7356809E62DF3B30E453D9F1BB2B15BB
-:1038900012FF5E258F2B9EA4FE267E57E67014DA5B
-:1038A0002D1167EC2E71F84DB1F0394B565E107B3F
-:1038B000FD2CF0332B9C1605E01953178E7383DC17
-:1038C000E9C8CEEE8BE36E2E19BF05F286E66CCD0D
-:1038D0009D6DCBC4530E7E1F69EC6B90CF7BF93787
-:1038E00074FE581E37DB43F747DD2FF62CB4511515
-:1038F000BD2CEBFCD90AB5E7DDF7F66C85F2DAAC46
-:103900006256BEBD270BBE21BC76EB64566E14FD1D
-:103910004D9E0D79F0DD0FB0F295B4DE0F7E2EBF17
-:1039200007547181847A762DB73F227E54617A9E46
-:10393000C129EC773ECED66E4356F9DACC24F8DEB8
-:10394000E771FC3D8116D5B316ECF5FA0C6F6516E0
-:10395000ECA3E6487E0BDC8B7F333092DBAFB0BF4D
-:103960007BB13693E5096F1C5A8EEF0B7CD17E56E6
-:1039700064159E7B3FF1FDFBB9F69F99CF91A16C39
-:103980007D9A7ED6FD33FD4C51F5F311FE99F8CEAC
-:10399000DCBE6CCF16E877E54D6C3F4C8EDB75F7DF
-:1039A000FF4F353C3B12ECFEA9C7AD09C0872B9FEA
-:1039B000FC5D5635F87FDC1FFAA4E36D0BE47DD780
-:1039C00085D87771EA43EC3B3975BB3A2C33F2204A
-:1039D0008FB5C3325533BFDABEDFB9522ED3F831BB
-:1039E0003FCF12F9DAEC771D573EF937FC9EE04ADB
-:1039F00053DB8790E74B2E607134E33A37F1F7DE03
-:103A00008773FF30F1825F70FDFB558E673BAC73AF
-:103A10006316C1F67284EF767DCAFBAB88667ABC0A
-:103A2000AAC8615329BE0BDFF43641DE69F5C3D95C
-:103A300005329DC7F68C298F037F448E6FF6B0F850
-:103A4000663B8B6F56C4775E478D14F9686BC59DD6
-:103A500036BACFBBF47ED27BDF0FE286A556213F7C
-:103A6000D7CE9E96C1E265507E256BD59D203FFB4B
-:103A7000F8EFB32D9838361AE4BC2B3BC6E4A2F21B
-:103A8000FF747AE547308F05132F9A01CF4BAC8E28
-:103A900091952C3E8EFCF1747AF9F3500FED21EEE6
-:103AA000E1B50493AEA2EBF0BE2263DEB4775C8C8A
-:103AB00037DC3D9520B7571F65313F6D9F89CEB3E9
-:103AC000A06F1E627CEA985DD70971AB0D69F9E0C1
-:103AD00047BB324A3ECC4AEA1BDF95E17D03CA620E
-:103AE0007CBADC71F07CB0F3E8E4F4F810E846FB53
-:103AF000299F2CC397127AF5FA65D36274E5CB67D8
-:103B000026108F366E7A79BAAE3CAF2247D7FE9A2E
-:103B1000256374F565D6CE090DE7E0EFD73B1EC5EA
-:103B2000FCDEC3EDA7DF9A0F7EEC0ED92DD1F52C6C
-:103B30007FEE91B720FFFA24FC0449018B8BB1EF93
-:103B400035F2F318C5A3E8CE63F63F6D01BF5D13F0
-:103B5000E737DCCB3B80717CE3798CC817FF67CFFC
-:103B6000632C43F9BEB8F7F73C3F7D89AE8C4CDD42
-:103B7000DD81F469DACFF2989BA8DF02DF13FBE165
-:103B80002E6B00BEE1FED9EF8E5A54CDB94C7DA804
-:103B9000117F5777EAEEA3786EF3AB2CA6B7EBDA7A
-:103BA000BFB0C03DA91FB6AF46799E41F5572CE581
-:103BB0009BCE0E327617C493B31D9887B3B2F91219
-:103BC0008C53C786E623AC6DBD04FB5B159A8BE571
-:103BD0003AFE7BBEFBA23B67801DDEF74C1CEE0766
-:103BE0005F9383231F827EAC0ED40F65E90B368072
-:103BF0009FB02FDA9F772D1DAFEC3F7F8879E87556
-:103C0000BB248C9B96C9649F04F9F7A128ECAF4CA8
-:103C1000FEF384D5F4F9A553995D2D031F87D6CB08
-:103C2000458E5BF17BD2117E27AD6028D32BE62E2B
-:103C300036EFE9A139D89FA82F1E3A4CF7DD18734B
-:103C4000D20E65B1BD6F3DE62E09E18F426310D6FD
-:103C5000EF9AA340FEF92BB9BF48043CD1F6F87D9A
-:103C6000B0FEFA78622C09A3B704B4723D3C1FF48D
-:103C7000309CD3677B660D4D82DF23EC526CA047EE
-:103C8000ED3617F82FB38AF3D56ACDBAE4E7AFC69D
-:103C90007B10D6C41E33F803F329D4EAED4511ECAA
-:103CA000CCE5434DDC7F6EC4F50A7B448EFF18CF14
-:103CB000B517F2F88090A792A1261D5E3A25261727
-:103CC000FEDFB27381D26C6F35CCB7B384CC7B0A84
-:103CD000F5686716DC47FFBEE64FE96B03FA3B95D4
-:103CE0002E02718C95BDF367F27CB6F95FCDE7FFCC
-:103CF0009A4C7CC017AF5D7C71A787CEABE3C6F151
-:103D0000E3C12E88F1D60D65F987C4D5F30DE61B06
-:103D1000EE895121AE5F06671E13FAFC79C847840D
-:103D2000F861FD1EEB76F8406ABD93EEEFED90175B
-:103D3000181504BEEDF8639402F663EC70EFBAA1B7
-:103D4000982F386A1A7CC7C7D36E5508FA419E9FD0
-:103D5000C2F348F33D9BFE12F268E4336F33933FA6
-:103D60002F97C34ACEB78BB91C562AEE58388F59B5
-:103D70007440C67B918BD7496377417C4075E03DA9
-:103D80007D218742DECCC097E3813F195FD686E272
-:103D9000B87C67F37E991C94C92CDFAE6C4C1CEE8A
-:103DA0009FEB4209D84EC8AB90D3CDD9DEC761DDB9
-:103DB000654D54BEE938DE0D6913405EFAF8C4E281
-:103DC000027EA27C925AADE183A68EAF14E013F37B
-:103DD0006409F9C44AE1540D1F95F7FA27AE19C9D1
-:103DE000741EB33666E3F79445FDCEA1C24F191C8D
-:103DF000BF6FE5FCB5D81E1C017EADB921CA0DDF31
-:103E0000913F99A8A21E5B738B843F4EB8C65C3E5F
-:103E100015FC8B350F4818DF03BF03F44FD1A10603
-:103E20008BF61CE4EAD0383CAF9E1B1A8E707B8662
-:103E3000F78F8087CAD0951C8FE3C29EF77DD9701B
-:103E400033C6D5BE0C58DDEC3B63FAF85DA1C78DD7
-:103E5000E77FE60366B24D85B89B57C6F3BD4CE2DB
-:103E6000BA5B62F13B88E789F89B38A71371382B5E
-:103E70007C0F5763474F2BAD59B00FE9178F2B615C
-:103E800076FFD31D66766FABE3CF45265AFF71B63A
-:103E900007E3722FA57ADF86F5ACB82CF0A49996CB
-:103EA00057DEFEB413E2E5029F6D4A7004EC97DA28
-:103EB000281E213ED8D622970698BF133347935F1A
-:103EC0001189AF578472103FC2DE08FDFDECFA5431
-:103ED000DC940A3D7E363B24F87B159783552007FA
-:103EE000446B6FE694C3EF9A915C09EFB9F6D91B66
-:103EF000260F424F537E47B929CBC9C4B8BAD0DB8D
-:103F0000467BB4576EBBFB02B0BBAA3746A5EB9B02
-:103F1000F29BBF3FFD0EADAA7DEAB16940A7923189
-:103F20001281734CA39EFC1F2B97089D00800000FC
-:103F3000000000001F8B080000000000000BB55BB4
-:103F40000B7854D5B55E67CE9C9949322F9210C23A
-:103F500023F1CCE441A8018747243CFC3C10082015
-:103F60000627F8155153994404C4BC40B9A642BF72
-:103F700039210902A53654ABD4A29D50B0D4AA8DE4
-:103F80008035AD3C06411A8AD569B5B7F416E828E4
-:103F90005CDE60C05AF116E5AEB5F7399939930485
-:103FA000B5FD3A7E7E9B75F6DA7BAFBDD6BFD65E99
-:103FB0006B9F9359C523E5058500D7E8772B80F8DB
-:103FC000E667923C1CC0BAA21C143BC0BDD896D870
-:103FD00063FD1280D28E3440D43CDB117BEE964DD3
-:103FE00000FDE979234011C02C9DEFC432800C8084
-:103FF000FBDCC07F0DC83410E08B1B38FF742BCC6A
-:10400000F3E3FA608E64C7CF37DD33D92B63FF50FB
-:1040100059E0F3AD889A6DE9C867B7B9B77890FEF3
-:1040200017E52E13C126A40238CD51482DA4F94D11
-:104030006C7E0095C9F36572F7D7F6F9AE080DED01
-:1040400038FEDD5B6F8D2828D7DEE5A3478B726CC9
-:10405000BDF1B285F195A5E1D831005DBBACA14DB4
-:104060002837E07C02F27FB46B58682D6EED18742F
-:104070005D05A4D59D2932EDAB6E770AE3AF4B7693
-:104080008504ECAF7376E5FB519E923D4961188142
-:10409000EBEC493203AEFB59CEFDE3E5227A3E74E8
-:1040A0008AE044A1775ACD807C2BB39509A4B7BE92
-:1040B000E4D7E54B6CF5FD97960BAACB0530B3C45E
-:1040C000A19AB05D7C25076034C043AB67B0F6F5BC
-:1040D00060262A1960EA957200DC5BCD953BD9F326
-:1040E000DA2B298C9EF9DD4829ED075E17600BCA93
-:1040F0005F36F85B2B01E5EB4C86E13B705F9DDEA4
-:104100002C5F137657B7CE60FC65BF9C369DF65585
-:10411000BB0399695C8110CA233D9DB09B48FE8713
-:104120006D5CFC8FEBFF3C46C6F11F8F718C046405
-:10413000DD27B63F395E60F6EC247B4EFEC53FB707
-:10414000FF0FF249574450501EEB1581B57F940381
-:10415000D5A427E40340BEEA6D03C704EC5F054F16
-:10416000BF9664C4A3547D49223C59B12D89EB9F6D
-:10417000A7E124518F4BBAF1F4D5FC609EC6FF65D0
-:10418000786AFECFE3A9B90F3CB5FC3B78BA8E1D27
-:104190007DE089E16CE6218E0FC871F8B600C30B93
-:1041A00093BBD392156A42BE7BC9AE84AF6B504FAE
-:1041B000FA9C47F64D8BE1F5979EC0CF494EDDCE78
-:1041C0009DC96AE192C2AF62E7BB81E2C6BDE9F573
-:1041D000A0E0F379D8C6C70D2BD9AFB0E7FE5EF9E2
-:1041E0009AF16EE357B4F31EB233E1C78D761CC368
-:1041F000EC27935D13ED4E7625BBD7EDB66EBA9ED8
-:104200005D87E7067E477A49B42BB8934D7073BC3F
-:104210005DAC77126E3E0E9B81FCAB2FBB4A1BB888
-:10422000DE75BA256C9E1E62E701A4950F6778398A
-:10423000F4EFE0A5ACA4FDEFB67E0067E4257E3385
-:10424000F2CF29C6AE41D4BFB45531537CC17F8E65
-:1042500067332A6063FAD4E8872353508E994F76E8
-:10426000F7ABD43F75A24B1B0F0A6EAB9BFFB45C40
-:104270001F59C7E46EE5FA0E44CDFEE171F418A4AF
-:104280001D71747102BD91F3D339E266F384D87362
-:10429000C29F308A687D3ECD0FA0ABB41FDA6FD6C7
-:1042A0000EC1BD16ED7DCFC48F2C649FB292E88104
-:1042B000C1B8DFABF2637E7B123EA73888F2DA3DED
-:1042C0002B5B55B3361EF558ADA9D1DA2E2822DA6C
-:1042D000A9BA5808793D3DF568F7E8B8D4D7C5A321
-:1042E000D5381E2C63BEDE78C2091BEF65E3C3D64A
-:1042F000AFB1FE5D134109F512270779B43879157E
-:10430000697D7ED4DD9DB8BF502FFEE6D5E68D9841
-:104310004C3580FAFA86E7E9565B16DA17383E0A1A
-:104320003D3FF4AB1C87A024ECF77AF2BA3DC6F30C
-:104330009F7EB2717CF87AFACAE8315EC3C7222345
-:104340005E5C66FFFE8F510E57BAE056D1FEB5FE99
-:10435000A475E022FBEBF80EF99521B8BF24E8C65E
-:10436000AB11DF6DFE29A8975AD0FB7FDA4AF1CA5C
-:104370006FEAE6E778DF29748F2F40FCB8808F2F33
-:10438000F56C6A550B993D583FA3CDD7C17B7B0295
-:104390003D31C13F347C33FFA4B88DFAC9EB256EA3
-:1043A000DCAFD9ED82007329EE4526F37C2FE2E5E0
-:1043B0006D9387E7770F697A7C586B23C9717A18F8
-:1043C00012B333FEC25060D837D3D3DDE9DABED59D
-:1043D000BDFEDB715F9154182E204EBED3B6ABB537
-:1043E000F996D8F860DB5E8693EEF9D43D113ADF9A
-:1043F000EFD6F4D4D4168E683812C8EF6A1820109D
-:10440000073B0455C47DD6100E7AD967594FBF516A
-:1044100013C62BD275C6DFD973BC92301EA4F4AF7D
-:10442000335EB3D3ED09769C9E60C7290974854E2F
-:10443000870CF14C8F73551DEB5B32508E87B60A9B
-:10444000744C50BCB608230136780EF9EDE308AF82
-:10445000B2341863FE46CFEF23B66100E514CF18DF
-:104460007EDF695572514EF27746BFEB576E22FCE4
-:10447000D4B76422FF264FA4D586ACF734AF972873
-:10448000A779C1F3C75633CE7BF7985F1EA0F9CC4E
-:10449000C2FB91DB3DD7C16B6BC23E3626D06A02B0
-:1044A000FF535F12DF9B13C6AF48E85F97406F482A
-:1044B000A0571BC757CE17989F54A2FD48715FE6BF
-:1044C000373B3DDDF942F77926D8599E64C0FDCCD3
-:1044D000264E1FF07CE85F6D8FA3DB8EFBC9DF7576
-:1044E0001C4BC07FF7A6834AE787D4473CDBD11734
-:1044F0008E0A12CF3BDEFF37FAE740CA3BC1702E6F
-:10450000EF138DF45E51F7B74B91470AE9A14E774F
-:10451000F90348CF7CC6B82FAC0BB5FE8BFE29E85B
-:10452000FF33BFAFF75FF453DCD3F7A9F3977E7E79
-:104530004DA4F58EB45DF06FC6FE8AC9E1BC7A94D5
-:10454000B32295B778CE88748ED5D9B83F95EE1240
-:10455000FD74CE542487F39616C6ED13DAF3699FE3
-:104560007B978BCC3E6A13AF47AAC067012C85F6B8
-:10457000BA5C0D2F20FFBEE562039D6BC71AD232D5
-:10458000A89E18EEE579DB3ED70D190F20BD3765E3
-:104590009E4546BEBD8F4F65ED9BA2B2AA0B71FC36
-:1045A0007F9ECFFDF661D4EF62FAF947DB157F23DA
-:1045B000FAC5671E99E93390EACEE8A07C75AD0490
-:1045C0005B6492C7F73CC3CDF7AC23D7A21C958D93
-:1045D000376650FE56F5C3F2D281C857D522F9048A
-:1045E000C6072348EEC0DAA916EA9FDFACB5EA3465
-:1045F000D6EEF962FBA111C8DFB546F46D42E6DDE7
-:1046000057BCCE2A94EB78128FC31F9ECF75929C15
-:10461000EBBD01C98B72543A1DC9021D1E6ED939FA
-:104620001BE77D2247B1788B62FC7BBE10E751BE51
-:10463000F9C6F9AA0CB29FDBCBF1BAFB4A55465535
-:10464000DC79BFE08299E9798F457E84F2CB3DC960
-:1046500059822A303DA795A3BFCCD7F26BC44BC378
-:10466000F65ECEFDCF3D22D3CB096B031C4710EF86
-:10467000FD6EFF8924A73EAEE8FD409383F03C44E5
-:104680001E159F47F7CB9E3C84F611C359DA1F08CD
-:10469000372C8F467AA8D7BD5E455CC13ECCFF491A
-:1046A0008E74A594CE0158810C18C720B33D3FFEEF
-:1046B0003E2296A7AED4E201E73BAA3A58DD7AF44F
-:1046C000A5A410D53347D5BF3AC01ECFCFFD64A1F6
-:1046D000D3A1D2617CCAE130935E8F998327BF8DCD
-:1046E000E3163C27B138BAE0B9FE2BBA281EA03D2C
-:1046F000F3A0E7BAAA5762F3F4E927E02937F8896B
-:104700002A972BF6BEFD6492572EBF9E9F2CD4F2A3
-:10471000F6D2E7243FE17C6191C30C18AF273FF745
-:10472000D616C2E3C22549A3AC28F8C2E7ACCCBE7A
-:1047300051874375637FC0E930F7A3B8EEE5712474
-:10474000DA98C4EA1431C3C2E29EB8AA4826FD949E
-:104750008860B6E1B9223A7DB29FD3CD6EACDB5A08
-:104760001CC532D9F73B5EEE0FDDFDAEB9B7095877
-:10477000D75CC67DA4E1B8330D4F3E3D16E53B0B3B
-:10478000A1396351EF97C9D0B8CEE51D6248A57332
-:10479000C2AC98CB30EE2D02EEEF3507B75B26E1C9
-:1047A0003F17D52FBC9DEAA30743D28751ADF6B979
-:1047B00086FF7F026F5B28BF7D68ABF1397A8C85FD
-:1047C000FCAAA6DDF8BC0ED65D1247506BFE305A2F
-:1047D000A03DC7751B8EFC65F8FE38BE5AAF23FDA1
-:1047E0002496E0300A46A166719D42D75D04BB065F
-:1047F00091C92BAE4C0A911EC56C7E3E4C03219490
-:10480000448070E3BE71DD4F838787EF4740888F18
-:104810008D667A3911443C0D457D386D8C5F7C4C3A
-:104820000C5971DD923450FA913E9F2E0770307D05
-:10483000AA6EA4A7A5D79B293E9DD3E24BA500FE57
-:1048400076E6F7BE6CAA8F173C97C4ECB7F0F90771
-:10485000FFFB4763C85E65E9F17EB446C31DCE0722
-:10486000B6D4D83CA71ABF934DF294FC04EB4AAAE5
-:1048700037C5C0D377B37899E26371CB1DFDDE589D
-:10488000C24963CAC8B540381998ED2D8C8D5FB800
-:1048900072793E1F8FF5AA93E25512DB4FF50E2B6E
-:1048A000C349E51A5161E76396859D8F1F3627310D
-:1048B000BA7A4831F3B34A1304681F980B66B2B84A
-:1048C000CE550ED57650B6DB29CEAF8B884E661FFF
-:1048D00055B39B85ECB3D99BC6FC771EE918CFADC9
-:1048E000FD84B322361FBF7FDA2D84B6B0F8542F73
-:1048F00093FF57980416E712FDF1352FCF5B2BB3CA
-:104900007DF7D1B89A27ACBE951E2E83A8CB8378AD
-:10491000AA314516FC98E6FD9595DD6BD4E13E92F3
-:104920009CACBE50B6A1FC7566305BE85E4AE6F111
-:104930004C97A74E2E9F4638C5FEC366ECAF71F06C
-:10494000785CD38FDFF780C316DA12BF1EC99CC311
-:10495000C7C94EF2B3710C2FE4F726ECFF08787F3D
-:1049600089B3588EE2F34E13ACA67B129267D888B7
-:10497000B875911E3882F0B8C4EC75901DD2E6CCA3
-:10498000A5F55E16595C42677AA298F2BF97C5D129
-:1049900054C756AED957BA81E85747BA4984CA575F
-:1049A000DE63E7D3431ACEA294F7D37985F4ABD86C
-:1049B0001ED5E24240E4F73847498FFD637AD5FBC4
-:1049C0006BD648CC1E352D1C0F358D7F66F3D6383F
-:1049D0002219648F9AD7A49B09D72735B9AB1AB38C
-:1049E000261E467C54492EB7808FAAD5320BD1D5CE
-:1049F000AD02A3F5F56AD6FC29C354C8E7A3D6AA2D
-:104A0000E128366FFF6C3ACFCEBD94965D1967F7FB
-:104A100073CDAF3B653BF94D38CF4DF7304B927CB2
-:104A20009B989F727B9C6BCEDB44F734F3DD118740
-:104A300080FDF31FC949A573EE983B6CA1FE63EDA1
-:104A40001E13D18ADB3D9168C57C13A3CF61086F2B
-:104A50002FD4C08B76AA15386EAA5FDA67F1E27A96
-:104A600029395C3F175E7E2F9FEE0B6AB223F974E3
-:104A7000FE22AEF207935D5E14589E50FB92A8246E
-:104A80008D88E1AA967085FEBF58C355ED8ED71F5D
-:104A9000253FAD253C8DEA894BAC2BF7B3E7DBDA3C
-:104AA0004A818FDF4FB8D3CF7BA49B25BA57B36819
-:104AB00034AE43B43D87EB1FFBA7F07EB5909D233A
-:104AC00010B5503E5C27F23C01FD2993F288BA0EE6
-:104AD00049ED8E97B42EF517C6FAFBC2CDF01C93A4
-:104AE00066672B3B8F86E770FF8BAE79CD49B8B8F0
-:104AF000F0F2BE03E3A9BEDA26B829DEF7F0434D93
-:104B00006F75A42727DB27CB8BEA482FCE989EBA58
-:104B1000FD4DC3451D703DE87AA9336B7AD2FBB5D4
-:104B2000F123343D5483A6D71D43B9BF6BFEAD9F1F
-:104B300023FAFE02A97CBC8EAF79DAFE266A6D35B7
-:104B4000E2C657C8F0A5586ED6EA7EECBAF06A1BEA
-:104B5000BB37D2EDA9CBFDA8B63EC669A55F6ACC2E
-:104B6000CE51132CEAED9E7AB6862BC9CEE3CA0746
-:104B70008D83EF6B40FD2D7E49F431E551CD15B7A6
-:104B8000AED51475B0BCF431D14DFB2AF945F96DA1
-:104B9000B46F1D77D256C1DC3186EA8C7E4CFFBAE9
-:104BA0007C2503FCB7F5E3B80B933CBA9C1F086166
-:104BB000662FF555C1CDF3DCA885EE0F753F4D94FA
-:104BC000779E666FD1298C176E22797C32F937E097
-:104BD00039C8E4B11F5ECED6538F2EF78C88AD73E3
-:104BE0004C759889EF18F038A0E3F203ED3EE283AC
-:104BF00096D7591EACAFB34CD34BDC3A8186F49EAA
-:104C0000EBE8FC351ABFEE179DA91CFF25CD7F668A
-:104C10007C7A9CA51FDDC3E9FAD4F516E79706FD5B
-:104C2000E8FEA5FB936ED77FD5AF60457F96AF3E7C
-:104C3000AEED9BF94846EC5C207CD27967B5202E1E
-:104C4000ED867393E535D3865CB2047A79AEEB29B1
-:104C5000F179AC9E726793FEA7D9334D94074073E8
-:104C6000E6FEDCB8BCEC38DD77513CED0FFC7D0690
-:104C70008694F8F35CCFD7F4F31A7FEBBA7189E32B
-:104C8000EBD29533D4BF68CC927CCA232EE578D979
-:104C9000BA67A1DD3209E7AB3E1D2975CAB17AE5D5
-:104CA00096BF874517DD07EEF018EA85EAF3FB9912
-:104CB0007FD7406415D5B7956BDE2B1B4B76FF393C
-:104CC000E6E3C837BFD5C3CEBD339BEF1F4DA56C00
-:104CD000654B1EA31FDCF200A7D7F07CAEB2A5E89F
-:104CE00005BA8F3F9EA49412BEBBD60B6EAAB72600
-:104CF0006C295A710FF64F70DCD08FE43EBAF97808
-:104D0000D978AA1B1A44E62FCAE627E750BFD2215A
-:104D1000FA68ABF3C1BDE21EC2B7D9C5FCED987607
-:104D20004E34491C676F6B71627F0E3F2FF76B38F3
-:104D30002C696ACA37D1BA6D783EE1FE2B2C727BA2
-:104D400098EABE5D037C9B485F58A666228E4E0B98
-:104D50003CFF5E64011BE1EAA0145946F21F5CE6C9
-:104D600018D9480288576FAEE2753A8B2F5837B181
-:104D700075757DE9EB1FD2D6D5E7D1C775523E4593
-:104D8000E78726EF99E69FCFA13CE1CCD6BC5488BB
-:104D9000D3FB19DA17EAFB418C8BDB7AA9FF0EE70C
-:104DA000E8F7AB21D62ED2EE0D0F4AAD43E8FD2D2C
-:104DB000E6F127E2F3F2536D4936C223E6F1C6E786
-:104DC000123F4F308F373C47BF3961CCF7B5FA4EB1
-:104DD000AC70057A89437A9B98E79FCBB1A79FBCBB
-:104DE000117AE4F9BADF258ED7F3FAEE7B9623F633
-:104DF00084F731635D709DF5CF07D13058FBFD948A
-:104E00007C17C74F49F97C7B84EAC956ABDB8AFA29
-:104E10003D417E45EF015F13799E68035F18717114
-:104E2000E24FA37DE4870B8E70BF5BD02E84E81524
-:104E3000FBFEF58F8BC4FFC0460106087175D65383
-:104E4000EBE790DB5DF605560D44FECB5B059FCA94
-:104E50002454EC09F5D5818172DFF5D5BF5B57E9A4
-:104E6000F74C897A1F94ABD5573EF019F5CEEBF38A
-:104E70003D089FE2513DF57E3E186075D4C5E022A5
-:104E8000D68E6B6F2B198CF27F247CF0C404F21F3A
-:104E9000878BDD939C0FD6B39780173B465F9D852C
-:104EA000FA79C3EE7253DCB8186C60CFBBF1A2E1A3
-:104EB000F3961D7BC5C1C0F8774E40FEDD7617BD69
-:104EC000D6E8E57D1BB72F40327F3FAAD5DB0F2FF9
-:104ED000193B809EEBFB3DFB6D6E675DFEB35BEFA8
-:104EE00077527EBAF7C7693BC7917D535C6E82D11A
-:104EF000C20D220446633EBC81C7A1D336D70B74D2
-:104F00005F7A7AE39D19540F3E2075597C38AF6F54
-:104F100057B993EE41FED71C75BAA945FE30C96159
-:104F20000E8914FFC64F07F61E707CD80CB287BDE1
-:104F3000A267381977DE1C0A237D8EDE0FD2B97D79
-:104F40003599BFA7D7DEFB3DF06B7E9FD67D7FA254
-:104F5000DD234CD0F6FB5FB9A91CE7DAF39262FEC1
-:104F6000FCD4C6EDB368BE339B2537C97B71B3C48F
-:104F7000E65F8C75BC0971781AF146F16BF1FBA202
-:104F80008F207D662BAF9317236EE9BEB86689A488
-:104F9000585C3DF158A2F3ED14587DADE372B112A7
-:104FA0002A657AD7F069C3FFAEE191D10FDA579144
-:104FB0003E1271FAAFD6FD35B9BDD7FD8938D0F5AF
-:104FC000A5E321864F60B8D4ED9EDA3E72D26036FA
-:104FD00040657A54274301E5054D162830130E4CE1
-:104FE000C93EF2F3069B7304DD337D9AC4DB474D63
-:104FF000EEB7A85EFED4244B02B6D15C0F1BFFA80F
-:10500000E89B4AB4941E65F70362894931D179D788
-:105010006465F12231DEACC9E571382B8FC79B2D59
-:10502000B96E9E3F423DCB1FF416379845F949793A
-:105030004AEA2732B23CBD79C66C33EEAF7C42EA15
-:10504000B21CCC2C9FDF7CC76C7AAF5B3E3AF53547
-:105050002FD2A1DC59BCFFA6D42209E9C646FFEC39
-:1050600029D8BF2B57792AB728B68E3E2F3E7F8688
-:105070009EFF7640E0D9DCFE749ED95753BCFF48B2
-:10508000E8AA358931FE3F0870EC0D21464725C856
-:10509000A67C7A4B2EB07DF4D59EC9557E9ADBCB8B
-:1050A000F32A8016D26395FADBC394AFE1CF6F4346
-:1050B000BCDDA1E1ADCA660F132E60B574BE1B172F
-:1050C0005E8A4B2E33F9F72CCDDC7798C37B69FCD5
-:1050D0003068769FB4B15470E3B5B4BEE33C3A2671
-:1050E0009CD4E7C3FD7D24E17ED1AE8282B6469793
-:1050F0001250C91518DF849DBFFD8CE66D52219AB0
-:10510000C4EC50E1A6F3488080E91AB63529880737
-:10511000D4D3D2D72EEC27F83FA8E75399FCFB8CC9
-:10512000651A1EEF8828CFB4A150A782909E8BB637
-:10513000BE006F5E34E3BA674C8183A4976AD3DB09
-:10514000D94B65F2DB2627E52F175E117DB7E3B853
-:105150006A2D6F87AB62F8567CDEE919B6696D1C63
-:105160008EFE98CBF394F39E70F6728A1F1E5E77C4
-:10517000C2D57DD9CB917FBA7746119D4B4F81F235
-:105180007E6EDCFBC559E6DEBFBFF8FD209E77C012
-:10519000667EBE5ACDA03A52590B4ED4C70C94A588
-:1051A0001869096991BD8F0F313B129F93F214F971
-:1051B000FE4CFEBE06FCE48FBA1D75FBF4B01B8AE4
-:1051C0004CF9B9C90612F9CB30D8E826FFD6ED372D
-:1051D00055B4B378B3F4357E1FB7548836A711FDA4
-:1051E000329E97A42FCD2F7B9E9B5B2C648A451B00
-:1051F000EF67F1498F4B32FE47F8F94FDD4B0A79E3
-:105200000E9EAF8C849184AB2FCB77F4B884F6B12B
-:10521000E57D1DFB908A70BF0BB5B5A78A15B299C5
-:10522000F4D2DFE6A3B8BCF4B91C76DEC1BA1FB075
-:10523000FB0F9D0F36A6317CAEF288CC8E651D83A8
-:1052400041C6470F760820E339777B471AA39D575D
-:105250000632BAEC67032653FEDFFDDEF267431920
-:105260007DE685436302FC7EC54672F84197A3B094
-:105270009DF2A1CB769403EDE0B7AF66F7857EE8AB
-:10528000AE63846B02D18812F2274552B95D6C8DF2
-:10529000CCAFB57D2D75733B2E3DC8CFDDA593F802
-:1052A000FB3DB33ACC4578903A450821FDCD836269
-:1052B0005118599BB4B86CCD34811C678F243919AF
-:1052C000E4B8FA0D54254275D25C0D272905A9864C
-:1052D000FEC785804472CDB52F60B871F80619E617
-:1052E0008B649776327D04787EABE309C4F36692D3
-:1052F000F3938902A4212EBE3917FBE3E695265EBF
-:105300009A22B0D69817A35E4E5C0F4F33F3B4F3D6
-:105310006E180C63784AD00FFA07CB3F2FE3394E53
-:1053200069136617CF4C447A4EA7042199E59BCCAC
-:105330007F2E2B29ECFEBE45D3938E3BFF50702869
-:1053400038AFABD8A8B77E8A516F69D38D7AEAEFB0
-:1053500037EA65C05CAFA17F60E01B86FEC18B466B
-:1053600019E8ACFAF106FE1B1A261B688F7A9B819E
-:105370003F67F56C039DD77A8F817FE8862A43FFCC
-:10538000B0D06243FF8D5B971AE8E1ED8F19F86F9B
-:10539000EA5869E81F195E6BE81FDDF903035D1425
-:1053A00079D6C03FF6F02643FFB8E88B86FE09A702
-:1053B000B719E85BBA7E63E0BFF5CA9B067A121C98
-:1053C00032F097D8DE33D053DD7F35F04FCB3C6ED3
-:1053D000E89F219F33F4CF2CF8D84097F9FE69E07D
-:1053E000DF3828F02CC59FB9A6754755A0F82C7F4B
-:1053F0007F22E2F9AE74B32F4C4C5FB36EDBA4C7CF
-:10540000410DB79F80FD3E93F7CBE3E0E35A5E305A
-:1054100055BC1DE8BEF772BBC070DDD7F9ECC27C8D
-:10542000D71CB78F7E8A0D0BF0189D36DD6DA0FB63
-:10543000FB330DFC03E6CA86FE81810243FFE04593
-:105440003E039D555F6CE0BFA14131D01E75BA810E
-:105450003F67B5DF40E7B5CE35F00FDD1030F40F14
-:105460000B2D32F4DFB8B5DE400F6F6F30F0DFD4B4
-:10547000A11AFA4786571BFA4777B61AE8A2C80658
-:1054800003FFD8C32143FFB8E85643FF84D3ED069A
-:10549000FA96AE0E03FFAD57C2067A121C34F0978F
-:1054A000D8FE60A0A7BAFF62E09F96F981A17F862F
-:1054B0007CC6D05F7D0EE147F9F31B027BFF35B35D
-:1054C000E092A15F4AC73C9DEEA721D9270A3DF390
-:1054D000743D7F2BF37D6658E751533DFB2EEE5311
-:1054E00013CFEB6CF9FC7E0BF3779B8DC5593CA178
-:1054F00086B3AB9646CA4F5DAAC07047A94605BBA6
-:105500002F4C67E72A3B1A65FA0E0DF31B24524D08
-:105510001E0FD50F29B13C74C8B5D15F3D0FCDC862
-:10552000078EFFFC404A7E11D563AF96527DF22074
-:10553000A8AB480E3C5F5DF49EE99D24E3BD91DE7F
-:10554000CEB0A1FEE2D63B98D43A64D475FC768600
-:10555000ED3CE3EF9E57BB5712707F4BE3E67F02B3
-:10556000EB26339690AD41F42FF4D31F04DD8C7EEF
-:105570002A98C9E8A783326B37040B58FB6CD0C755
-:10558000FA37068B19FD7C50617428389DB59B82D3
-:105590007EF67C73702EA35F080658BB35B888B5BD
-:1055A0002F06EB59FF4BC10646BF125459DB1E5C58
-:1055B000CD9E6F0BB6327A477003A37F150CB1B640
-:1055C00023B895B5BF09B6B3FE9DC10E46EF0E8652
-:1055D000191D0E7632FACD6084D1FB8387197D20A8
-:1055E00018656D67F0346B7F17EC62FD6F07AF30A5
-:1055F000FABC76DF5F926F7CAFA6D30053181EF41F
-:10560000BC7616D52D048E62E9A2A16E49A81F12A0
-:10561000ED71565B479A8CC736E53983F23735C54D
-:10562000E5FB7768EB3D9E0C6A12C6BF462AE61181
-:105630008A8DA9106A62EF5779DEBD50C325A4F3A5
-:105640007C7B8126D742CD1F8A089F050C9F6F7FE8
-:105650009D3A49AF93834302F3F2B15D9C6552D901
-:105660003D813D944F79FFA621812AC2EDE5FA07DD
-:105670000EB0F5DCBE7C5AA4CC1AEE7F17DDFF1C01
-:1056800014D97D695FEBD5697FBFD067FFEE3343E7
-:10569000E81C9AFE85C8EED3DF911C73E97EE49185
-:1056A0007CFE1EE3917C93A11D96E57F98E43C95DA
-:1056B00057FFC2C3C852B124CF4579EB1D545AA33A
-:1056C000DF97832CB1EF6341798B3E99FC262676D8
-:1056D00044DF052A6BB70F0EACA0F177630141746C
-:1056E00060BC35BBB7FD24CAB34AB3D3AA7C93A12F
-:1056F0002DCDF2B7D07C27F214833CCBB364EDEF11
-:1057000064BA9E27B9FEB1EBD2492127A66FFD5E90
-:1057100062D524EDFBA92582FE9E9AE78336D0F35D
-:1057200041D65FB18CDFCF7C0BEB327A5F79448B53
-:105730008797EB25162F2B84641FE5D397EB970DE6
-:10574000A5FD24C6CD0A1C67C27115C0BF87A83845
-:1057500092C2F085F301BD77ABC0CC9DEABFDA2CD5
-:10576000FDDE236AEFCFE551E83DECBC9DD636AABD
-:105770005311279B591C1B27AA16AC93DF3185F2C6
-:105780000591E1C322A0BC0BD3111FBDE4053A0E65
-:105790006AB5BF8FD19F23BE5EA1F92EFE7A6C0140
-:1057A0007B6FB27B9C4CFA6B32A13DE8BEE6772260
-:1057B000FF4E82AED8E93B0E57611BFBCE9F92088D
-:1057C000B2D738077B1FB2578486577B899FEF6A11
-:1057D000387A27539A1E62F31ADFF3756A76ECD48F
-:1057E000EC5BF6E6C1AC4771DEDA4E89D53B30267C
-:1057F0005AE8EFE5FBA6BA86430373E3F651D7F107
-:1058000001FF2E0AA285F1DF439DD2D6D7F1245A9B
-:105810001C81367BBC7CDDB87E47C3F549CAEB678B
-:105820005965D75D38348AAA09631BF8899B7D576F
-:10583000A77F5F371FFCAC5D8870201CFBD5F5ACE3
-:10584000FE5D0CEDEC796DF1FDD944D741D7944C58
-:10585000AA5F5637BE9589D2DDD9BA7E2ADD3FCF01
-:105860000E55BE456DF966E124D5DDE8177FA3F539
-:10587000A3427D0B95A4F7BC34A985EE796789DC3A
-:105880000E7088DB0171A488A93DF7877E7052F302
-:105890000326BFEE07152B397EF4BFC7E8F68BE26F
-:1058A00087FE3698DE7D98BBD8772175BBADA9847D
-:1058B000AFC554798AF179A17E3EF3BCE021CC0BCF
-:1058C00088EFACC4ED7FF66812FBBB97B302E263CE
-:1058D000544FDCEB79E6A7267EEFF6A8885B14A987
-:1058E0005E7E92E969912D3482F484E7330C255C65
-:1058F0001F6F5F3592EEFB2687B2295F955EB4FA83
-:105900009A3C86380FD75262F7784F48FC5E2D518B
-:10591000DE1E794BF181CF289FB05A40A5F749E8A8
-:10592000FFDCEF8F71F93F3505326F1679BEC2EAA1
-:10593000E8217E56FF4386CDB756E8B97EB3B66EF2
-:10594000E7E7BC9E56B3807D8F932887E0E6EB2681
-:10595000CA634DE672E8E74E4F79B81D74790A863E
-:105960007AF8FD7DB6C2F6DD68EAC7E2D747626025
-:10597000E8503A2FB5FB31BD8EEDF49C62711DAE3F
-:10598000360DE1DFF786FB3A4FCF77D7CFDED879F8
-:10599000A7DF33C1C4DEEF05FD36B744769B0D3E6D
-:1059A00016F787C1115D3FEC9EE9FF019ECDEE1811
-:1059B000B0390000000000000000000000000000FE
-:1059C0001F8B080000000000000B7BC4CEC0F0A3BA
-:1059D0001E822538106C62711D0B03C30756D2F569
-:1059E000C17025507F0910E703711610A7027102DC
-:1059F000104703711810BF069AFD0C881F02F11D95
-:105A000020BE0EC49780F82C109F40B277191B035C
-:105A1000C35A36D2EDFF83E4E78940763910CF24AC
-:105A2000231C46F1F0C0F23C0C0CDABC08FE3E5ED2
-:105A30005479051E047BB92065766D03EA0700E9F9
-:105A4000CD424A800300000000000000000000007A
-:105A50001F8B080000000000000BD57D0B7854D58B
-:105A6000B5F03E8F79253393C9839040C493970452
-:105A700009382421F2AA1E0842A4D406F42A5AAEF8
-:105A80000EC823869044B02DB7729B21092F411B6D
-:105A9000152D5AB483458B0A36F268D106EEF028EC
-:105AA000C65BB4D1A282D536D45B450B4944116F95
-:105AB000B5BF77ADB5F7C9CC393349406BFF7BC370
-:105AC000C7B7B3CFD967EFB5D75E6BEDF5DA3B76E5
-:105AD000D9C6E42B19FB027FA09CA330C60644CA9A
-:105AE00051775EBB687B09FCFE99DDFFB8166967DC
-:105AF00094173389B1D1F09E653056CAD8954EF8C7
-:105B000015DA95BD70EA0F97A531B69F29CC018FA4
-:105B1000C26A59EAB7A09FFD9F333FBE975F706787
-:105B200075B8F1BB2063E98C5DC1F877E16C2DCBD2
-:105B300057881526E373DD49BF433FB99BEAE0FB75
-:105B4000B39FBAE97B2B1C46C93E9759587CF34555
-:105B50000EF6AB7EDC5120EAD90C066702DE2C1A69
-:105B6000D780F7D0DBEF11BC075480578B33BE13BF
-:105B7000E04F8BC0BF9F5D9BC40A39FC7A6904FE6D
-:105B80000B8587E60F786EACD7BE9997CFD8BA7AD7
-:105B900046E5DA7A2795ABEB7DDFCCB331B6B23E82
-:105BA00083CA46153E01381AB7B0501050EF2E8404
-:105BB000F646FFF03F21CF69AA3BB37CA6BA3D0D64
-:105BC000FA2988D455B766AA37BA2739036E1C1F3D
-:105BD000E6EEC0F19D5402984733001F978A79BAC8
-:105BE000B4E02C06EB91E7B66B2180E352F782E933
-:105BF0006C24B6CB27BCD9055E9764367420BC1FD5
-:105C0000433B06F31DE69EF23EF332F69FD94FF07A
-:105C1000796C606C203C5FFDEF751D12F4B732D3D8
-:105C2000AE35407F4FC0F86B1C5178DCAAFEB9033B
-:105C3000FA74C23FC4E3D08DBC1E9937D4A3E631B9
-:105C40008C45BDCF8EF473A1FDE6379BEBD67EF37A
-:105C5000347D12D2ABD16F3EAB68F0B9FFF7F67B63
-:105C600029E03C3525D2AF314EBFFD023954C0B7D3
-:105C7000F91B59289C1D3B4E9EE62F0FC2FBBC8D85
-:105C80002A0B65F3E769C01779FC57D6E49B94109B
-:105C9000288C8587458F93135997BC34FB1C19E8D2
-:105CA000292FE3FA4512D25573D4FAE63066F0CDC7
-:105CB0008FEA7D4C1FCAD8DDF505546EA9F7E9C8F7
-:105CC0002777FF5D99D55218CB8F7F11F2EA1E1B03
-:105CD00023FA0B3ECE428F4BD85FC5AC39505F3FA5
-:105CE0002ABDE82E8D885C4679E61274BC5ED26EC1
-:105CF000C8C1F6AF280CE5A0951FEEB6E9D3B0BF3A
-:105D0000B5A364A901F19CC7F921CF1676E662BF5D
-:105D1000CD39A382D88FFF55E287BCFC4B3405C632
-:105D20001D9627F861F4834E94873DF35F96AEE7A6
-:105D300015339664A103DF79D2816F42DF74F07569
-:105D4000F1C3D7475FCD7DD2D77AFF7DEF3BE0FD32
-:105D5000963CBBA664C7C295797138A3C21D4B6F30
-:105D6000797982CEFC7DD399B57CB03EC4DE011A30
-:105D7000BABF3E83E8EEDE7A8DCAB5488730EF07BA
-:105D8000B0E958A8231DE2B8D71551BDD77D8BAD1A
-:105D900020BA4C9FD5CC50FEDE8FF4390E875BA91C
-:105DA000EB1360AE79A20E5BA40C7BC0BDF87E1035
-:105DB000D575DCCAEE928CF6CF0675C0778A683F3F
-:105DC00075C5B3C146F8FD7E17AF5FBDA2530F6620
-:105DD000457D1F5CA7EB5991F6500F4F52A3FAC3B4
-:105DE000FE0BA3E13948ED8DFEE6AF38A10701BEF9
-:105DF0007B5DBCBFB52B8EFD53FA5F2B053240B5E2
-:105E000060AB2CFDACEDA9DFAB231E8C7172A45FDF
-:105E1000E8C1E8F7C16774DD1D797FB9746F10DFE1
-:105E20006F64157912AC43E6F48A0C06EB6FAF6829
-:105E30000EE296DB039FC077647E0F12BCAE0CFEB1
-:105E40007EC48ADFEB8D51EB3369C5CB4184D7D05B
-:105E5000731441AFF20B594B8F00BD2A49763FE9CD
-:105E60001BD701D364C278B32A980670C969150C90
-:105E7000E58192A6BE1BCD0706FD019C6309CEC934
-:105E800015B37A8133180DA701477F701B70F44E4C
-:105E9000A77C7C2B3D4DBA66CCEF26C0FE6D6FB75C
-:105EA000F9515D48453C4157ECF35B8336789E3AA7
-:105EB0001370ADD1BACD62B9B1FDA64D1FC4425128
-:105EC000FBF73F7A5DF3B0CEF116885E5FA8CF9501
-:105ED0000644F03856B4B3D29F313F5BCCFCAE35AC
-:105EE000CD8FA9818C0A4FFFF3BBD7E59F55E18E7B
-:105EF0006DF75B49A2F1274D19F36DC6C7630E908C
-:105F00005FC9385E5164BCE469301E76A636C71D91
-:105F10002F65328CE7FCFAF069E547035E7B0CBC29
-:105F2000B79AE05D6B03BE8DB3FE5F37BCE7CB7FF6
-:105F30002E90BFC47F797DF3DF3FBABF64FC153E6E
-:105F4000F94865E12B015F775CE524FDDE9073FF86
-:105F50006C7CA5E2A7B07E77BC547CE24A192B404A
-:105F6000D72322E3D74A1AED57BDD1776FF3810DBE
-:105F7000D6D4CFFFAFF9F486D7AF5B0E9DAF7C6D63
-:105F8000783D81213FAD2C642107F4B1B2ED2AB2F6
-:105F900037571E291BC8A05FDB9AE14C8749256350
-:105FA000FFD0DF4A43CF985CD24FFF5CCF00FB4E5F
-:105FB0006F02A56BB7B782F4A29512A3EFD783DE69
-:105FC00016023DA6E4950DCE3958F7EF70CEC1719B
-:105FD0006D8CF4E992570EF9CA80CE5D23524629A2
-:105FE00040022B5DC6F3A3E5A8E7DE55289E7B782B
-:105FF0007FF0BC02DB2788F6BDC1959007F044AD69
-:106000007FA2BD395011477FD76599F0F390D0BB7F
-:10601000EE46BD0B047262424B00F56A57BA5D7BD7
-:106020004C8AFDEE265912F306BD0DEDEC115332EC
-:1060300051CF3A30E389157684AF90915C77E5854E
-:106040007419EAEE02CEDB0F59F67D37AE21E95D19
-:106050009952994ADF99EA77F7E831D913516FF3EA
-:1060600016F0F7650D574C6C8C7ECFFC1371FF3525
-:10607000DE071A4AE97DA6B3E2D804183F13E468A4
-:1060800023E02B536D96EA685DD3E2EA8F1BE63B73
-:10609000678500860D331ECC9E1F673F81D534F186
-:1060A000E9A079663E7B48E0EF6E81CF4CE4F5D104
-:1060B000820E41BEB978D31EF9E61ACAE55B4241A9
-:1060C000F30AC4F7A079CC8FFAF686194F90DE6AEE
-:1060D0008CE32A30CBB94CD53CAFAF6B3E1B99FE5D
-:1060E0001D7974EFFD5BF96C230BDC8AED33C57E03
-:1060F0009E5010920285FDCFDF3ADFDEE6FD2DC413
-:10610000271FA74E1E103BCE3F0B2F996E18A7E4FA
-:106110001F3F4EC23CB3BC3C5FBCC33E20E88C2951
-:10612000B81F58EDAB84129FC464AAB6A31D4EF2EB
-:106130001BE0F6B0E6F24B80DE522B56DD2E83DDFF
-:10614000EC79EBEAF7D1CE4EED9843F676536151F8
-:10615000DB246897E4F7CD984274CA08CF6BB1335B
-:10616000E2BBAA1513615E8D8CF3DD66F996895C3E
-:106170003FD069BDBF2B70062BAEA950477665395D
-:10618000F1E66167613E6FE90B47ECF7BDCDDF16C5
-:10619000F94EF8FF9690DFB4BFEFD8743BF9118346
-:1061A000F00FEDD2644B3F49BA3DE2676488A7A87F
-:1061B0003ABCFF6D0F5FDFFE4F19CFC7EE736A4029
-:1061C0000AB63CD987F67A12F325AB2867278342B3
-:1061D00000A2D897D61D94B5FED7A589B1F29642F4
-:1061E0004E7733A2F4DC0E99EBC969332767AF848D
-:1061F0007ECF9670BF70AA0FFE17C5CE671DEC6BE1
-:10620000E1283FC7BAC2C7887F1B819E72802F8258
-:106210008532F9B7D7E6EDF045F3B5AC18FE6D2B36
-:106220007D304D2D15FA1FE047C99375D7C8AF4E85
-:106230001FCA97A48FC4E951DFB10B5FAF24E5C239
-:10624000E8E3AB8E67AC6B2C5F71FD246DE63C27F9
-:10625000EA3BAB326626C593B3BDAFEB7DB4AEA8C7
-:106260004F84E2F49FA64871FD39567D9EB1A5A6E4
-:10627000F5520696CEDADCD7BAA599F161F4EB5A5D
-:10628000A668FF85C24BF5915FDC29FA5BABDD1791
-:10629000C4FDF32CEEED800FA5795418F53D96C79B
-:1062A000FC8FF326A487B8343D443A24CADDD208D3
-:1062B0007CF62CD9349E9A9660C2379B05DA761408
-:1062C000FCAE657682C389E3C1388A0F3A94D0FF69
-:1062D000CFC22E2FF548FDE1505FE462FD4E131D45
-:1062E000ACCE2A8ABBDFA9625DD16CE5F47AE7F90E
-:1062F000C917EB78D799E13DEFEFDCAAF66E1CFFEA
-:1063000071EC772A7BD7C01720F1961E7AE7EBB4A1
-:10631000CAC6F64849200F32AE67010DEAF80A36C0
-:10632000EB35588E453A2CF2915EB05552114E62C3
-:10633000690DFF737DBE10955BE84F7606084F8AA6
-:106340005B67D45E3B3F7DFF9CD0AFD3843E6FBC88
-:10635000FFA162A77E5556C1D06E3EF7F6D40CEA77
-:10636000578747A51138ACFD162A811F2A0390ECE8
-:10637000383CF801FA09584701F9B5F305CECE3D8E
-:10638000303389F5C15F0F59F8EB2189C3C92ACE93
-:10639000CFCE380763B6637B359040F1B29305C426
-:1063A00007B962FC27D6CF4DC0F19FD8D8379F1BC5
-:1063B00070FCB4DEC9C2A0A786EA7D541AEF43C2BE
-:1063C000DFBF59D831C6F3738A4C70EC137CFF845D
-:1063D000B32281FCE7076F9C360CF82BE7A8E24755
-:1063E0001D4F5BCB52FA1A3F3B68E637A6CCEE1343
-:1063F000DE656F4D9C71288A1F7FA178D2DE1D0E4D
-:10640000BF5CCE2E47FAEBEFFB73F5FA8C43F95FD6
-:106410001D2F9B85FD79AEF1772B48CF095F49FC95
-:106420009923E448CE3C2E0F72AB594843FEFDFC45
-:106430000B164D1F6099109E32AB558DFC4D4C775D
-:10644000CF81F743C5DB4C65BA8C5BF850D4BF50A5
-:106450008E6CE2FE73C3CF0FEB7E17CAB9CDAF29A6
-:10646000640BE7556A0DB8DE39EBCDFEFDC12CCAD1
-:10647000EF8EFE7AA1D7655AFCF85F751D3A701D44
-:1064800012FFF9EB105219D19D51D72456116FFF0D
-:10649000FB44D0A9B6E210B743C0F87B272A1E01FF
-:1064A000EB99829BC04F83F74D44BB35B886F9F317
-:1064B000E3C84B9B9A48746F637A7828FA0FE65CBE
-:1064C000DFB117E5D50466925F71E4864DC5EFD262
-:1064D000B8DC080567F2F27385E265F9EB5908E369
-:1064E0005B9337D4ED47BF5E6635B79B33D7042542
-:1064F0003BD473EA981F87C9AD64BCFD6C16D27992
-:10650000BCE66806D0CD104137430C7A5966A69791
-:10651000C17596B8D01A737D20D2057C37D0422F32
-:10652000D67E723446F1B8BCF5328F17CD32C77DB6
-:10653000F259F7FB3F0778F30FB9FD61161B6FB2F5
-:10654000F6AFB24001E265F70FDDFF590013FCD949
-:10655000FA49A98817902749244F2AE2DB3D31F4F4
-:106560006AE81BBDB48FC84FDEAEB7F7ABF2D39766
-:10657000CE0538D67A7446E307B349AE2B225E794E
-:1065800030F37A6707FA6DDC4524DFF7631DFD3CC5
-:1065900019970C8C96F78AF02319F546E147B28ECD
-:1065A0003755E57AF07B4C9F8A7818E50864605C83
-:1065B000CF9691BE730E8C67F381BE15E7BBB16AAF
-:1065C000029FAFA6FE2D1AFFB071FB481E32BE1F00
-:1065D0003377CA79E1A3440DDCA442199C04660414
-:1065E000D27F0E0B35E2FAD635F3FD2DD2EE16D161
-:1065F0002E8879053DED02D06E84A9DD3C9C0FB458
-:10660000D34DED2A62DADD26FA63A671F598716B37
-:10661000447FA4CFF5B4F3C7F4B754B4233DB0A777
-:106620009D16D3DF3231AE6E6AE78B69F7EF067CD9
-:10663000A6719979DC9EF7A576E33DF9630FE44FE7
-:10664000217A39943FA57C2E8CB3F4451B97115BBE
-:10665000793E874157FB45BB26A4AB42CC5B6163C7
-:10666000AA294F85E7AD34BA673A0351CF7BE8CA10
-:106670003DD317FFF95C537B758D8BE9C5F49CDA2C
-:1066800037FD5D11F1AA1F4C427FEBEA3459F8DB6C
-:10669000AE69D05590630354537D4D86786FBBA689
-:1066A000810262223E02B2F29B8551FCDD33FE3F45
-:1066B0000B7EE13F8EC03FDB02FF6C33FCA2EECCD1
-:1066C000E4EFD595B327E17C0CFFF2D9A6E50D41A7
-:1066D000F7FFE6F95559E65765995F95697EF69596
-:1066E00055938279FF97E6B7CC32BF6596F92D3383
-:1066F000CDCFB972D905AD9FB5DDDDB66692B76B6A
-:10670000F35F27FD7FAD88E326ACD41B56E07BE02A
-:10671000ED76EA4F23F93E8AE99FA33CE8EFBB47B9
-:10672000548DE482D323935C60F9F6507E36876BF8
-:1067300026C885E7541F97DF02CED72CF50F2D759D
-:10674000F8E56FB86FFA9861475AE47C3FFBDACA04
-:106750004CBE9FACF2F8E5E87D4D15B83938A094F1
-:10676000E44FA38FCB9FFD03843C4A837D8DFC4483
-:106770001924AF6C425EDD57CFF3D89A457E506343
-:106780005A11E1A759D80B2C9465DA370F4C9CD2DB
-:10679000867EAB334779DEE23A1BD7C756D6339DA8
-:1067A000E8ABDE49F945FBA0DF003468057D0FCB7F
-:1067B000E741DFC3724F7D0695BFACD7A8DC01E38C
-:1067C00062F94CBD9F0560FC6DF563A8FC31EA8B56
-:1067D000503E20F4C52BD264F2576CAE872D339F08
-:1067E000F4482A1FA9F78D5561BC9FD46750FD233B
-:1067F00069E6581BD9AD1D8D4900E7EE57F3285FB8
-:1068000069429A4AFB2F53C34A5249E4B981D78F50
-:10681000A44957E077E33264DECE196AF4C66F57B5
-:1068200086EDC664A8040F7307156F5ADC76E5364B
-:10683000C04BA95BF4E70B347AE2F7F72D6C57E411
-:1068400016FDA5698DEEF8FDCDC47147FA381E58C6
-:1068500046474362FC763760BB429F986F56584E5E
-:106860008C3FEE6C1C3725A53980F1AD2B6733D2F8
-:10687000476D69DA66292A3E141A50C164A0F39460
-:10688000D4E63A6CF78D809FE5C0F89AD7CF64A024
-:10689000679B1BDE17624E138F478DBF0EDEA33E34
-:1068A0008CEF4744BDC7EFA11C3B4B7C9F647EDF50
-:1068B000A397AF613D793C98BC646B32D79365CEAA
-:1068C0009FCB571E98847C9F6CE7EF7F8A75D4B767
-:1068D0009633431EF1F609FCFD8F8CF65EFEFE1723
-:1068E000A27D4A0A9FB76B8A338471B147BE7B4948
-:1068F000E6DCC2C87C2FFA5EC1B0B951F37BE47B01
-:10690000E332E7BA23F3B9E8FB1386CDEDC3EE49D2
-:106910002D977B7264516E25371792FC1CE5A820D9
-:10692000B9336A60A98EFCACACE770FD87EDAE862A
-:10693000863C822B88F2C680EB278BCD700DAE3162
-:10694000C3F5931A335C836BFB866B9D8DCBB5DEF1
-:10695000E083F1F5E8F11FFD37F3F8437E601EFF99
-:10696000D11F98C71F72E7571E3F1CBD2E9B6E3765
-:106970008F9FB5C43CFEA625E6F1B3967EB5F1FF28
-:1069800051FA78922D70C426F45D255AEFAC0B981D
-:10699000F45368F78A681754A2F5D840C0A49F4200
-:1069A000BBD76D42DF35B5AB8869F707D11F338D93
-:1069B000ABC78CDB21FA0BCBD1FDF963FAFB8B68FB
-:1069C0001794A3FBD362FAFBC080CFD4CE17D3AE0B
-:1069D0004BB463A67199795CF82950A19FEFB30479
-:1069E0003FFA47964D5E4371AF812C20A1BFCF97F0
-:1069F000CA461D82EF592ECFBF4F9EB2EC62B43B08
-:106A0000D7249BFD5CE9766E9FD9EC0A95BE44566F
-:106A100047F900CE60E68CA87C8B6A3BDFCF7ADE3C
-:106A2000BB8399D746BD1F28BE5F23E2D469F6D247
-:106A300046942BBEC1D03E8EBF22538C6BBC67697F
-:106A4000FE761DE0DDF8AF3347A3BF2832AE8DB729
-:106A5000BB588C9B151FAE35D97CDC45386E213E6A
-:106A600037F48B6026E1D7C74BE3F9839EEF49FFEC
-:106A70000578593DD9292B49F07E3DF76F1A7EF6EE
-:106A8000647B9D13F3761B2F92D963D82EAB6F3F97
-:106A90004E53BDD9DFA9FA2A74B4F70655FA8A1401
-:106AA000D6FB770F97CBE5F1E20DA3C5BC9A2A2759
-:106AB00035E7C1F8EC90D96F0B84CDA2F3610A954C
-:106AC000C0687B3CBF6D538129AF3E7950DF7EDBD0
-:106AD00046A15FF4CC033A8AB77E370AF8D8C602DB
-:106AE000939E959C3293F4ABE486AB9DBE38DFADAC
-:106AF000B5F4EF6233756C9798D6CC64EE5C34E9EC
-:106B0000614DBEC7F83E94093209E33F693BC2C8F4
-:106B10003F674BF8790A3523149428CEC1E7896A78
-:106B200025FE24AAE1A00CED076D54593895B1FB60
-:106B3000E5C08D881F575E33F9C7549F2E219ECE26
-:106B4000D94257D379025017E3E57FCCB3733FF0B6
-:106B5000C3DACCDF65C759C7DBEC9A492F1DF4A90E
-:106B60009D858B7B6F1F69C7E1EAA1D30CA04FE421
-:106B70006F8DD3E9ED8ABED84EFA5A968FFC8E8679
-:106B80007C35F85FC4B7E78E61E247BBE10F308F19
-:106B9000DBDA6C3CBFEF73681D15F7B94DF8BFE643
-:106BA0008A78F73C56E1C597A7995C8E7C759ABDAB
-:106BB000EA2D8E5AAFB5763B1F678D8DFC5B463C48
-:106BC000777EB3CDE4EF5AB8D15C5FC066A6A35C14
-:106BD0005AB0C1C6F07CC76D167FD8BFE17C615E3C
-:106BE0000B59DD2AD4D38DFCA0B93EA662FEF7E294
-:106BF0005F3D528A7943CD769EAFF301D08B16C5A7
-:106C00005755EE901DEDF97776155F3F9EE1F7A1A0
-:106C10005583509E26B3B8E78C6E5D6386AF3FF810
-:106C2000ADF032D640F0F60687BA558AEBBF7AD47B
-:106C30002E99E244CB9CDE910CE4CC39172F7BFCDF
-:106C4000297F74917CDF27E80836C0CBB89CAFBBA6
-:106C50001CCBFEBE3BD8CB778B9D1D76E48F5AB5FF
-:106C6000AE5C92237126872DA00F86EF6C7B268663
-:106C7000073353BB35E7D9AE4DCA39AF76E5721F3E
-:106C8000FD750A79F9C2B69FD9D1BF78FAA913D791
-:106C9000201F2EFAB5C29CD0AE739B8785715F50C2
-:106CA0004376942755BB94B871598AFCC3FC17FDF1
-:106CB000C24372A26A8723341DBEAFFAE53B231993
-:106CC000E0A1B3A1FBF060DC479F92787C34D8311F
-:106CD00012F7AD2A95DD122F4FEC84A0BB53CF25C0
-:106CE000CEC27595B6EEBF99FA6DB9C1E688920F1E
-:106CF000C7C4BE04EDB87FED4929941F477E18F143
-:106D0000AC534F4A1CBE3DB6900BE1DBBAD91E0016
-:106D1000386AB77E487454F68BED5EC443ED1EC5E9
-:106D2000E4F7ADDDAA841D23A93C8125C65124E0EA
-:106D3000EB1AC6E563CDAEC5E40FAF6959F7A1E222
-:106D4000C5EFCDF40C78F18711AF6F28FEE958DF5D
-:106D5000F973AF06A8FAA0FD712FE215FA9D634FF3
-:106D6000C278AED98F8DFD7F9A12DB1F63DD76A4CA
-:106D7000AFDA96B57C3C0BBF7C80BF64C6C64F9C27
-:106D80000E4B1C6B6BEA79E9898BB69F7D3408E367
-:106D90009DDAF1D74783B87FFFBF8F1EBD13F59AE9
-:106DA0007D2E1FF27BED53AF7959D43E98E3E07C02
-:106DB000D7F9E4CF9F7818F8A4F3B8838EEE75EE78
-:106DC0007D6F8806F3ED7CF6BFD335687FC7DEABF9
-:106DD000C8EEBF6377D9C0BEF643A4D350F43917C9
-:106DE00091C7A4ED9150D902435E94967539B84B82
-:106DF000612E80F3F4314708F39A6BE1D9B2225C3B
-:106E0000A7C5247FB1BE1CF05BB36DF587CAC878F7
-:106E1000780E0E9631C79E01BB64E03A5FFBED6FC2
-:106E2000946069A338492DEB26F969FDAEF628ACCC
-:106E3000E765BDAFDF59F6B91D8378B5DBD6F271D2
-:106E40002DEB771A7F191BBB7EBA65FDCEB2EA9F88
-:106E50003E8C2F77A5C68DE71AF1AFC5BBFFA54FB6
-:106E6000BDC99003FDE1B752E270791C7A8503F940
-:106E700069C7D34F3C9CC6D7773A20A473FBD9216E
-:106E80000CE8E3A4ADFB66948FDD7B1D3EDCCFAB4D
-:106E9000F6BE41FCD5B9FB15BB46F291B925D0131E
-:106EA0003A59CF4F3BEA0D3512AFD46EF1841DDE57
-:106EB000C83AD58466946B5E7A7E829E8738DDD729
-:106EC00084F65F27C559B7D58E1C2E8F433C696F5A
-:106ED000F1963FD899DBBC9ED2185CC71353F0796A
-:106EE0006FEB68CCDF87F3BF3C6A3DB7707EED8DFA
-:106EF0002F3B373B54CC4730D6B7D3C6F5FDDA909D
-:106F0000F4068BC3AFC6FE76A1F1D00687251E2AF4
-:106F1000E6DB1F3FF73F8F0BC3D3124CAA1C1D8B20
-:106F2000AF539FC797EF8F382401475DF9A0DCD896
-:106F3000FD496515C1C1D911784F8973B3A79E5218
-:106F4000424178BEAAE520C969AB5CA8E9454F7EFD
-:106F5000C6186FCFFE9128BF4E1D788EE8B066DB55
-:106F6000093BDA4787B7EEB4771446E81EE57F742D
-:106F70005EE4A967F68F24398DFDC7599F5F0B79B1
-:106F800057DB6AEEBF76DB87A6FE17055BECE417DE
-:106F9000ED679C0F54FD069CEF07ED368679F71FD1
-:106FA000B428E5F1F49B90C366CA835AE5293D866F
-:106FB0007E4525C5AEA1BC6B5AA1BF11A4738F3607
-:106FC0007EEE51D58F39802F1B93ED1ADAAB4D9E93
-:106FD000EB991625B79B2DF8F4A5F926625CCD3701
-:106FE000B9A224DA7E32E04FD66513FC7778CA075F
-:106FF000E27909B4C3344C3250FDE45756BC53CA4D
-:10700000713E8A4FF6B9E2EECFBC3FF4B721FDDB0B
-:107010007C32D3A2E86B54D9F5C3D1D5A632CD9436
-:10702000BF7AEF641EC735E67FEF456C1303B97B6B
-:10703000AFD4DD86F9ECC1AB795E201376BA17EDDB
-:10704000F4EC587D8EE9BA86F287C40F6FCF7423B3
-:107050007F147EBE0FE0C898BF23FB4999FFBEA2F4
-:10706000533E8F1DC7CD45FB2944CF135998EA8A5B
-:1070700093CB1F0FABA3E749ACA319CF30BDEDA84D
-:10708000F8D401CFEF2B4F9138DC61CAD74816E313
-:10709000C88959997DF13F9BAC9E8AF6FB38D8266A
-:1070A000B24BD0EDF8456A040F463E9CD1EFBDAE21
-:1070B0000912EE3738BFC178AE479C9FF7F5CC5721
-:1070C000A7FA00A36E19075BFA4AC5164BAC1890D5
-:1070D00054056F0D68263FC720D64265166BA73250
-:1070E000C5E9935482EF2DF24BC9ECCFEC8B440BE6
-:1070F0007CE7A18F9F93F5E301281B6DE2F9DB9EEE
-:10710000D0E350DF90CC4CE783739D9CBF2F77CAB0
-:10711000865F26106D7735B26A9ABB2B8D1F63315F
-:10712000BEBBDE1918EE8CA227C5DDCEF3BE84FDF2
-:107130006BD8EB5729CB29FEBE3A83DBD5BDADCF4B
-:10714000CAFA0A935D6D2D9B0738E76C66043FF71A
-:1071500053494E7E7E59679A2F9AFE605C67697428
-:107160003EA3AE937D2FDEDB607AF8D28178546245
-:10717000E96F06D2DF68A4BF0ED14937F9296E57EF
-:107180000257E37C33F2EA24FE3C2071BF97AEE065
-:107190007CD345FF72627566A08F79B259401F514A
-:1071A000792D1B84FDA8AA4C4D284278368975B7E5
-:1071B000D2A5393FD5D0D7DCA2E6107972BF2979A4
-:1071C00095CEA3A8696ECA4F719734DD8EE77C55C2
-:1071D00056E743F9E936F24FFC3C9FD0B08B5D0592
-:1071E000E63C4E87256FD526ECEF983C6EB1EFDE7E
-:1071F000830FE2E8C3D67DF77667FC3C2436267E13
-:10720000BEA0A1879D2FDD5BEDC86A67FB611ADC1C
-:10721000A7539EA52AFC0D13AFF3911FBC6B9BC413
-:10722000CFAD59E8A86B47D2489487C8BF78CF45FF
-:10723000A2782E6DDBBF1FF5A6262FD3935348CE21
-:10724000694A2E9E971AE594A05CBCEBC3977F8D8C
-:10725000FEF55685E1D6DCE536E2937A322E5622EB
-:107260005B6F5ADF0B9D4F6C5C91F3DB129FC16F1C
-:107270006EFAFECC3689CE4F296CF88FF1FC436D47
-:107280009B8D85E0FD19C6FB3FB389EB030B5F8443
-:1072900051F03CA8181FF7A5E8FD23B53C8169D142
-:1072A000793C41BD1DCFFFCF13F8185091627AFF92
-:1072B000D7B9E56DE49F09F07B0006CE1A64EA6F4A
-:1072C00091B27C2825E1093F8606FF90FE8CF99F4C
-:1072D000930376BE4F542485499F01FB17ED86909A
-:1072E00044F94A567F47CD1E89F6A7DB607FC2F37B
-:1072F00038B7852CF6A3258FCEC0B7952E0F3985CC
-:107300007DE066EE5EF0EA0F97507C94F86AC98BD8
-:107310003C2F6CC976294479CC1D439318E159213F
-:10732000BFD17BACEE41D83922F46BC19B23C38C17
-:10733000679766C673628119AF1EBF198F563C27C7
-:107340008DC931B55FA454DB89C8049E0BE01FE2F0
-:1073500019E420CDA306E611D662F159D97AEF2AB5
-:10736000F46FF48B470BFE4E59F07796B5EEE76F4E
-:107370005985339D589BE69DA986897FACFC66E0C4
-:1073800029CBD73E919EF93DE42FCE109D48F3F8CE
-:1073900077839C2D9C798AFCC46F467E7062CF7E79
-:1073A000F90EFB02CAA5330E9D98CB62F96B1396BA
-:1073B000C0D72DF54EDFBC7C8C4F33DF3C1BC6ABFA
-:1073C0007D54C6D947A97FA047DA0FEEC1B8641A29
-:1073D000F2B54AF12B5CAAE9504F6CB5F9D06F7940
-:1073E0004F51F735A8B7D7CEE7798E372770FFEB27
-:1073F0009204BEBFDA12785EF35D1532D3D1BE6F50
-:10740000554212FA8B7CFA8B57A2DED56AD3685F9D
-:10741000F375BFFC1D7A5FECC3F86EA6DC3C0AE195
-:1074200080F6E46FEF6A7DC77B6B94BED3B9E7FE4D
-:1074300061B8EF3C24B3CA787A7CBE8BC3D159F0D3
-:10744000E77424C7C5CE6EB2A35777D455E0BC0C01
-:107450003BC2BE8BFBB76AF6CC207DF2D0027E1E0B
-:1074600073F7297E1E738A32FB9B23A03EF6359567
-:10747000CB4DA64F9F93CE5328701D3760BE24F28C
-:10748000C17FC9A106C24FF3EF314ED5F81795A1C0
-:10749000FE5852B780F69F5F7BA7B46159AAB71414
-:1074A000235F4F6E4D9E88E7646ADFE27995A3DB28
-:1074B000CDFE1CA6541F443FD8D9637C5BBEFC980C
-:1074C0006AB5BB14DC8FC776989F8FEF876ECB5C55
-:1074D000623FF2B2F40BC98BFD91AC4F73917F9474
-:1074E0009FE3F2ABF1EDA74713B87D037891504EBF
-:1074F0007575337F03E0A96BDE209A6FD7C7FC6AEE
-:10750000A6AECF95F278F6D12D2E4E2F0FD979DC7D
-:10751000F6A105EED00A98C781055517A35DF4C9F9
-:10752000BF052E8E17A788D8072C49A63D4F4F625E
-:1075300063902F9AF8F932D69C19EFFCBCC10F0664
-:107540007F187C91B9202110CF7FF98E8BCF6FD21D
-:107550008202CA83EDDC27518CA7B301E0EA038FD6
-:1075600041D63018E1A9DDF311F9179CADF1FDD03A
-:10757000F5784803E9B621B8623CE0EB7BC0D44122
-:10758000E4077B7376BCFE836C03F99B16B834E288
-:10759000B74E27B7A399DA9C39D3837C5276F52A64
-:1075A00080F361E03F24F9876C7E823BB89831F22A
-:1075B000AFAA9CFFB3AE619BEF8AB2B7D6BA263EA4
-:1075C000E082FE1E70F178476AC02F21DCFEBF9F6B
-:1075D000F362FF5D9F3A68FD06093F8FF15D8BC046
-:1075E0004F5982FE23FC9E55A69130F407BCBE790C
-:1075F000B0FF5FB607F01D27BFCBD077520220FB4C
-:10760000009E14B74CE756D0DE427BA296193F414C
-:10761000523E0DFEC34366783ECB90B752AB14F694
-:1076200080DC2C71BAC3E84F49A98479633C8A395C
-:10763000797FED667D14252FCA5D94013C599EDB50
-:107640003B861C36E477533297834DF7AAA146094F
-:10765000D3DF3B5CE83FCED6B549985A95A26A94F1
-:10766000E7705125F3075148E63E92DCA3F78C679B
-:10767000ECD9BF2B71FD1B275DDC1E294B08FC0AD2
-:10768000F135B2ADFB00AA4F7E174BC5F59E22F433
-:107690009BB1A7B93C32F2FA6B85BD619547CF012A
-:1076A0009DA3C018FB0DBEEF8D3DEDF623FDF4C884
-:1076B000A10553681F2D6A2D3E88F939456F717EEB
-:1076C0006442FE80F54678296D0B2A880FABDCE911
-:1076D0004FDE18F2C4BACEA05CF7D4B30029C56D52
-:1076E000C06751FBB7554E1D7389FD55C8A9B36CD2
-:1076F000C2C0ABB4083D152DF31F7444D18F21A730
-:1077000022F414223AB48E2331674FDD978BF2E5D1
-:1077100088827E90AE893C3EB942F051F2C7A1AB5F
-:1077200071FE1B5AA7BA90EE77B4953991AD966465
-:10773000F0735EEAFEEB824C904F745CD7C69C1AE5
-:107740009E291F0F2B8FF8507C508F9AD79966492E
-:107750009C73D492AE8B733F82512EC9E0E7B8760A
-:10776000B4E524713B334CEBDE43F7C20F61F08587
-:1077700041EF56FA36F8A19171BF84A13F28528B90
-:10778000B00BCD7E8146C3CF1174519CF80EA10F72
-:1077900036BA2F5937017E6D0A4FF2615CE20E4F07
-:1077A0000EE533DF3180E3CD8A07A3ACFD14F4C3CB
-:1077B000A8BCF35AB59BFC5AB59FDA4DCF0DBCF669
-:1077C000860F03AFE310AFD297C7EBA7B8BEA36392
-:1077D000F1FB65E79DB5644CDCF372FF57E63D9E17
-:1077E000057EDD4176173FB761D097212F4A976E0E
-:1077F000CC24E26837DFEB65C891317BEA0EA28AC0
-:1078000068951397B5B26B114F63C32AC3A32EFDBE
-:10781000C98D8FF1974C3A7F716302F0DFA817662C
-:107820002DDA068F466A2C753A0035B25D2539C6C9
-:10783000DACF2F0ED512FE381DFD8B865E1A8357C8
-:10784000A1971AFB8B11075A9710A8C4F1A53DC048
-:10785000375ECC3FE5F6EE5A57605102B44F0498BC
-:107860001330D7AE209CCDED53335FF6C687891613
-:107870003E6B01BCD03904D8E7F2A558388CF1F33F
-:107880001292399C406DA8BF6495323E580DBFCF0F
-:107890002E6B240BE03E8CC736719E6B85FE759770
-:1078A000A55CEBAA68C079D9541674147D79B80D1B
-:1078B000BFE0BA043D88F87096EB348FC13EE647CE
-:1078C000BD7EB0DA22F9018E946A4DEA71D618FBBA
-:1078D000379EFB99AE4D44BA189CC7E83CEC60D487
-:1078E00083E2ACCFA6041EAF5DECEC388C21F3DA5A
-:1078F000E975E5DE3EE2D3917B06FCC24F65CEC35F
-:10790000E8DAFBC64518977CFBDF3FF260DCE94F05
-:107910006AB707E13CB9FCF71EBCBFE5EDE5DCCE7C
-:10792000B8D9A2CFEC14F84B4EAC780AF1774BFDE6
-:10793000DF4BA3F99D2DE37194DB420A1A9D3DF4C0
-:10794000BD686B22F9E68CFAE2965453DDA0D3C5EC
-:107950000E9E27659DFFFBC28EBA6DDB66FB600D38
-:10796000C70FB422BE4F0A7DEDE42E0FF9330C7819
-:10797000E66E1B65473CFCA9D521E2F0ED368E7F13
-:107980007D3AC6CF026229AC701EDE9748FDCD7FDE
-:107990004021FD620E8CB50CE83BD07A1BD9D9D6BC
-:1079A00079CC7F5B9B3210D66FFE5A89F4526CBF44
-:1079B0001CE821B06C35C5D9ACF39C13B4C6339721
-:1079C000939D6ECDF398C7B47513B2E3E47BB4F224
-:1079D00038F9C27EEC9A3F26087DA1945D8EF9E8C5
-:1079E0006759E18F0AB5FEED9A93F58C92B43EA8E3
-:1079F000775279AADE47E553091A8F67EFD97F9846
-:107A0000E84B6D2F457EDFD1F64EE24D5A446E5F56
-:107A1000B1F9A3833F817A31E3FE1BC33F3E5BE0B4
-:107A2000FB4A21BF170A7DA0F8D3BEE5F76C9CEF97
-:107A3000C858780DB93D1BEF958DC28321C7ADF8AD
-:107A400038D3969B887421255AE3C05F0D2FBD7DE6
-:107A5000B758899F3768F0CF53C21F306FCB8C5512
-:107A60008360FCC6BDEF0DE1F702B3A3281F0CFA3B
-:107A7000B4D21F637576E4E71E3A6BBD9BF063D00A
-:107A800005F05186883F66A0DD67A5B7FEF2893A0A
-:107A90006D1D43500E58E9AB536271EF154D4DE427
-:107AA000FEF2799A3E05ED50D85E56F1381D973FAB
-:107AB00027D5E6C377227F6EE1FCB1F857DB7F89DB
-:107AC00072A7EA170F7851EEBCAF36A7E378D58FCF
-:107AD000AFF4629CFBA41AF4E2F7EF8794B87985BF
-:107AE0000B1325E10F37E72BB035C16B906F3F7952
-:107AF000DCE6433F43ED56078F83EFE278833A8F0E
-:107B00007FEF8A9FAF50F5F307D2359EC76ACE5BF1
-:107B1000D862A3FC13F497E130BDC5717BE2C22D9E
-:107B20007DC7B76B77AD8B9B7762E40758E9F606A4
-:107B30000BBD025EC88E09023CE4161771EBC62726
-:107B40007F3CF204C0756ACB6FBD5261B4DF9CC745
-:107B5000C7CFB4DCFA530CF1F446AF9D82BE237A52
-:107B600043286E1E43B52DEC453BBC7AB38DECBA71
-:107B7000EAED0A73623ECB7107EDDB8BB6FFE6F5EB
-:107B80007100DFA2676D69D3F934285FC158A79EE1
-:107B90003C12B12E553B7FC3E3BD9AC82711EBB30E
-:107BA000E8D9FD76CC8BB1E2B1AC65BFBDC3928F95
-:107BB00040EBD472620A9DCB7BF29C1DF7D3F7F7A2
-:107BC0004974BFB2F5FBCACDBFF1A27C403C515C09
-:107BD0005EAC57EFF942E16B9E2FA176E487EB6D27
-:107BE000FDC6E0DE3A9AE8FB99E761FCCA371D94CE
-:107BF000AF54F9CC52CAEF794FADE374FEC8CA74E2
-:107C0000DC5F2B6DC1741F95FC79E5A3DF25FA5B62
-:107C1000F8CA77D3F9791E3D93FB6D829938BFF985
-:107C20009BFE85E6B7800588FE2A1F512AD05F7229
-:107C30005665E5CFC6E1933F093E79EF310706511E
-:107C4000D97BC26F197C5511F7FE5AE349FCBE95EA
-:107C5000B3C28EDE95281BF71439A3EDAADA2DAB3B
-:107C6000DB717D3EB8481FE8A3B8BE1A14F89248ED
-:107C70001F7FE5AA81428ED13D31869E5386CFB1CA
-:107C80007DBB8DEE8B89FACE74DFCB1D627C803B91
-:107C900041BA0CCAF4F8FE4C8F5B32E0E3F92F06D0
-:107CA0007DF5C6F75B783EC9C747B95CC1BC187A99
-:107CB000DF6E0B0F34E5C3384CF78944F23D6C821C
-:107CC000AFCDEF014ECA57E9C1EF3E89E2AC0B36AA
-:107CD00038CC79703D7463BDE7C69CBFB2D0A26F4B
-:107CE00019A5552EBC69910B6CD3F9E5AF54DB4255
-:107CF0009477547DDC41F643F5765B05E2E3AFDB38
-:107D00000EBE7E13D0F95F5B0CBE35CB572BDF5612
-:107D1000EE18CDE2F1ED5FDD7E16976FE1795CBE86
-:107D20007547E2111AFBFAE4EBC25EE4ABE28ED1D6
-:107D30000792302FF783A7165D4C7E060B5E0DB9B8
-:107D40006A95978F246AFCFE8298BC3ABE9F47F2E0
-:107D50001D39FE0C7AAC7A7A318DD343B7065D1AA1
-:107D600074DB4B9E96158FD6F72FA23C1A10EBCFE3
-:107D7000084E620578AF5EA39D15A0FF392827F84D
-:107D80001FCF8E93D7C1EA86A29ED1E8CE8E9B9F4D
-:107D9000EB77FBD08CC573654ABC78B7BF4C8EAB14
-:107DA000C797B8B95CD98BB40065B59BE3AD49C43E
-:107DB00057C012A4BC7FF429123F257B899F6CF029
-:107DC0009CD1B94A3F9DDBF627CA1F69A08255B8EE
-:107DD000B5292AFA538BE5A5B9505FE82EE6F5F1EF
-:107DE000F2CE1CA8DFE62EE1F5CBE4621B90E61391
-:107DF0006CF494C950AF31E6392FC9E4DF50E51374
-:107E00000F62DC457D9EDF17B70EF8DA591489F74B
-:107E1000263A58D05584F7344209F555D9BF5F85C5
-:107E200046E00647E01A37C9A3491AE2F594CF495C
-:107E3000F932773C7715E56756BBB9DF78F8CEF1B4
-:107E400074FFEED730FECDEE01BD8FDF64E3FD9C05
-:107E5000DA31BC0CF13AFC62467E0803FF45AA46C3
-:107E6000CF5D2D78F494F83F03CF7F3426DBA99FB4
-:107E7000EA9EF53ABFB251E43528899C0E9424B9A4
-:107E8000EE5928978AF5BF43E0037FD05EEEDA3BD8
-:107E9000F0317EDF53F7105C5F4539F347D41BBBED
-:107EA000FF35D18FE757DE4CE0F8BA2169BDED52BE
-:107EB000A81739872C45A27E53DAF65D2CBFED0951
-:107EC000FC90E39F85B1BF9B6E56787FEE3A0FDE44
-:107ED0009F26E95C8F96806866031E1A75A6D97383
-:107EE0009145CDF9168A52D41DA6713DA671591639
-:107EF000EC83B04E378CE5EB0438A57DF18D31BCB9
-:107F00003E2B94D3D8A1111CF7201CA31CA18BD00D
-:107F1000FEB909D4224ED766FBDB88D3D7FE4526AF
-:107F20003BB356D21ADD50DFF91623B9DC99E015C0
-:107F3000F907FCDE19C32F31F6A5B965B864257BB6
-:107F400016F13C0EE18732E2E86759AB829389F182
-:107F5000535BE4E178B69EE4647FF1B19FBB457C5E
-:107F60006C101B7481F1B167DCE7111FBBC86DE8B1
-:107F7000F322DE2EF6FF334772285F485531278FF4
-:107F800031BBA6508A88F1DD2E8BFC35E878C451D0
-:107F9000DFAD88971147D92DDC5EEA253FE224A3A7
-:107FA000BCE6511D05941F61B3E6471C9329E1A966
-:107FB000F4C5620DF1D924E2C6171AB737E2FEC53F
-:107FC000FC514C1CFF796F39C5418B7DF1E3F8E31F
-:107FD00094D914776047F8FA19717CA6142A08E737
-:107FE000D930D86008E751F3DF01B93C2DA8505AC9
-:107FF000CD5BE6E7E32C74605DEFBF58D7FB7CF305
-:1080000020DEE7F7AA8D6223290FC226F2207EC95F
-:1080100002F747E7411878EC2FCFC49A5762CD2377
-:10802000C90C98F134B8F252D3FB8BEA8A4CF58B29
-:10803000978D33B5CF868D30BA9EBB669AA97D7E6B
-:10804000F34C537DE8C69B4CED8785E69ADE0FDF47
-:108050005AD5E7BA8F6859627AAFC8A162BC0FD20D
-:1080600058F7CBF6FC202E5D18EB6EE46961BA116F
-:10807000E27734ACFBC3D9E43F2A93B4D8F5F78751
-:1080800083B42F5FE8FAE77B843E7481FC3E0A8963
-:108090000DE3443AD713BB6CEE35A81727036C28C1
-:1080A0006FADFA4572EB0BFF2D79E3E55B682B9022
-:1080B0008EBEAFE86371BF1F20F2239B64719E7474
-:1080C0009293F4817B64F996E87BE4AFF0703972A7
-:1080D0008587FB557E02FB26EE9383135990F64F5E
-:1080E00071BE9CA1430AE6EB4D65E2FCF963AB2649
-:1080F0004FC078664781968C2205EADF88C8FD9BD1
-:108100001C5A23C60346295C8E837C9FE6198DFB8F
-:10811000CE721BD77F8236C4F360270B7A8B68DF61
-:10812000A3B866324B939614A2E9D5B3BF685F003B
-:10813000311CAC1A9E8476D0CB383406699D09B4C4
-:10814000FFDF68C8BDCA6124F7CEB87BEEB5A0F3E7
-:108150008E67E6E5D2F3E33703D701FF1CB79BED4B
-:10816000A2FEFC53959BEFF7A0FFFF780133E519C2
-:10817000547BB81D55ED5178BC3CF49774444BD7F3
-:10818000FCCF2E41A06BA5F65528A2576FBCBD822F
-:10819000F27677CD08A2FFCFF03B1BFDD4B64E643C
-:1081A0003DF707433F37BCC1FD5F377C66F6E7DE2E
-:1081B000E9E179D7778AF1AE87C20778BB1EEFF481
-:1081C000C6F2850953901FE0795882FAB7DB40F573
-:1081D00003BA9F11C8B6213CBF67FED7764B98AF54
-:1081E000ADD1F7D7B10A1BC2F5FACD8B3DD8AEA7FA
-:1081F0003FA39FC178A613F6E9E4A02D1DE8A7FBD5
-:108200001B12EDEB309E139F57CC1EBC12B70E63B2
-:10821000BCD759E0F46BB0DE33999FFA35FA672C7E
-:10822000C1240777542EFA536A0ECA3F99FC1F4B9C
-:10823000F63A48FE75559DDBFE20BCBF6570C7450C
-:10824000A85FBC59F5D92588971B372A4C83F50FB1
-:108250002504EEF344E1EDF8BC8F3CF81EF484C72E
-:108260001FC44DFE69079DF37AB3EAE94BA2F5EA14
-:108270004D9E893FF6E03E39E6FCE23D654F0D2319
-:108280007BDBA0AFDB047D2D797228E9834B3CE6D4
-:108290007B53963C9E4BE7894A2516D78EC47B3F7D
-:1082A000302F7D07D0159E23DCF729CF1FDF7924DF
-:1082B000A598CEA3B2C07684CF68BFF3E59B865362
-:1082C0005EE7B1B4F3BB1719E00BA27EC5389C2F53
-:1082D00009FE98D59A5A2CF4BBE7106F37FDFAC9FE
-:1082E000D37F40FCEC7DFAF13BB14DC9F9E18389C4
-:1082F0007DCC2FF000FB18D93F5D2CC1EF8863FFC8
-:108300003C2BF4AFEFCB3AD925E7E40A91BFCEED91
-:108310001045F667601E774BAB928878F3A2C16276
-:10832000C817D009BD78FFA2B83FDD09F6D9702182
-:108330007FDA3D1F4F69E27108935E5772A8CAA4A5
-:10834000CF55C03F94F7976F0A34E23D8DBDEA7573
-:108350006199ECE12FABDFBDF325E57DA787F37FC6
-:108360004B0197DF2DE18410B71B5831EA7BCFE03A
-:108370005CE0FDB464BE2FD8A5CE0227FC7EC6F318
-:10838000C9AA3559B0DC791C1F58C7BFD3C3DA3826
-:108390009DF6E87F872EE57F674E9C032E11E7A2AE
-:1083A00063EC49E02BBEC92698F4C7F0E1BFD13990
-:1083B00097ED29DAEFC6A33E0F7A0AF2BD4BEDB076
-:1083C00027C799DF2F517E027D8FF572FBC4B987D5
-:1083D000C7E19C9A4EF79EB97CBE51682F19ED4FAC
-:1083E00089FD66F1E13787D8619D4ECB47BC1847C0
-:1083F000A8DEBDC38B66F2658981242FC64B8EBF74
-:108400005AEAA37CABCD43D0AE6D09F3F8C408950E
-:1084100005D538F735D76E2CA64BBF6B36A652392B
-:108420000CFD09F0A836CCE7D9B9A731259EBD5D72
-:10843000FB1F7B07E1BA3D3D809F971AD15ABC10C4
-:10844000E51FC2620339F7D4A7C3A9BF4BBCD93417
-:108450003F185FC5E7209164BCEFE86961AF757EA6
-:10846000AA503BA3DF117B262A3E58CBC270F301F2
-:10847000B20F5B1D1AAEB36B0BBF0FCED5EA22B99C
-:1084800057BB6F2AB7E39279DC737B42F71FC5397C
-:1084900036FABB042E5F334B81FEB7DBF9FE380C96
-:1084A0001860873BF2DC18CFD5FA634A6A77E6F1A9
-:1084B0007BF55C6A33FB863B1AEF1EC2FB542FA789
-:1084C000ABED096119F376BA81261F23B822703209
-:1084D0001AD7807318E9F3DBEDDDEFE2F94B3A5F71
-:1084E000A7211C1C4ED63A5443BDC2E5E3F15B976D
-:1084F0004FF307A558B86A47829E0BFC764F038B53
-:10850000FC7D04CC634B88D49DC013DB739890072B
-:10851000C3564FCE8AAE83401A13F97EF63DC35739
-:10852000374D203B27A8A05D0FA52705E7C9F737E2
-:10853000BCBF604011C703FA89139DFC7D4F7B27A8
-:10854000BFB24475F376FE245FE23489F5DC676AD6
-:10855000F89DEE90C2EF5E89FEADF081911AC05297
-:10856000FDC2F344B78BE4D6074768782E31B000DC
-:10857000E9F5576FC90CEF47FAE049179D432E788C
-:108580006E33F9ABADFDAD3ED6701FE665773D2786
-:10859000699807DA65EBA6B8514DEB7B745E71EA1A
-:1085A0009E13746E4B490AD47947635EC48A32C401
-:1085B000DF58D6DC88FE3D908714A76FC9E0F2E350
-:1085C000CCD14B1E5B1185EF07BDC2BFDB1DB818B8
-:1085D000F9A655F0E73ED46FA0DC2DF4ACDDFB6FBF
-:1085E000CC8D3E87156407C81FD6C00E517EA1F101
-:1085F000BC2BA4D239B0E1AF3B6FD1A3E8AD59F0A9
-:108600007BB3182F3F29B08AF876FF9FED5E0DF3FC
-:10861000585B86A0DC6D013DACAF7CC65A0BDFF425
-:10862000E4B79CE4F771C3BA3625C13A3DFDFA9E22
-:108630004BF1EF8B00FC8CEEAB3AEE20B9B93B9BD3
-:10864000F3DF8AD73E198972EB93BD8B2E467C2DC2
-:10865000F3DA0C3A9F9480FCF42C233966F0632102
-:10866000F2A384F742713F4A21D239F29FBD7D1AAD
-:10867000F1DF6E7E2F04D039D13DD0B90FF58B429A
-:108680001FD03D7D3F94F8797BBBCCCF81831CCF3D
-:10869000A7FA24CA57D9DE3ED947FC2C036A8B902F
-:1086A0002FC307A89F16FADB75ACC4729FEB294C49
-:1086B000D21810918F7FF3703E6D29D092FC309FBD
-:1086C000444531F141D43EC9EB621F957F74D3EA32
-:1086D0000DF8F7C3DAC5BE20F4AE7D42CF65C7B84A
-:1086E000BC5F2AF6B225BF19F7ED6D30DF252F29C3
-:1086F0005CFE0B3A3920F4E043F51954C7FD428380
-:10870000751A0D25DE0754AAD7E19F2F6163CA9B16
-:108710000F6239AEA2A50C8F4C4D98D57E909F610B
-:10872000D38723FDED3A70F570CADF3DEE6098A265
-:10873000B8EB6FDD7F7C0AF351F701FEE3EC4BE809
-:108740009F6514BFA9207AEC8D6EBAA48E6BC6FB10
-:10875000410FBCA77AAA0A1B7D0D1206E0E3F57B48
-:10876000AA56E3BD803725E9C7911E97FB02C79142
-:108770008FBA5EF95B3ACAF4DD47FFEC4579BFCBAF
-:10878000AE0F473ADB9503F6401CFA3C2CE8A7A451
-:1087900097BC8ACFBCDC5EBA24C8D621FDD4EC528B
-:1087A000E8EF169CDEA5E8780EFB5D3D908E7ACE54
-:1087B0004916BC7E3CEEEFC2AE9DCFD1CEE6A3DE25
-:1087C0003292EECB30D9994C592ED33DEFAD12F900
-:1087D000272A2D7A48356B5E3518F78DD6CD769CD5
-:1087E00047D516F3F7D5A8BF8CC4B26F7BF533AF6E
-:1087F000D05F72592EEA2F403FE49FE87E4DF13F53
-:10880000C628BFA70DF37B9E96397E405E121F1AC5
-:108810007ACC569F7E1AF5CAD3824EB70B7BB47BB7
-:10882000BB44F9FDC3B6F2BCEB7127B5CD8CCF9F2D
-:10883000F2C22A851C1CA7F2F8C5B8A3B9140F1DF3
-:10884000A333F2872C68954288C74A43AF13E729C0
-:1088500060DB25BD6E2C0B35E2FD720BB74A740E42
-:1088600063D156B3FFBE7AE32B87D13C5CDC62391F
-:108870001F2FF0628D6FECC05FE2C4372E4E12FEE8
-:108880009C216C88E9BC55DBF99DB7FAAB387FFDBC
-:10889000AAE8DF68372189D34D8D986F754809891B
-:1088A000BF4FE9C6FCDB5B057DDC2AE8A39685EDBE
-:1088B00098BFBF78039F2F5B6F33DD5BBC60D7ED44
-:1088C000741EC14A4795DB78DC0D1048F19DCA4DF6
-:1088D000E6F755021F55167CD404240B5C5CDF8E32
-:1088E00085ABE57A5CDFC5DB6CF4F739AC709D6570
-:1088F000B3298FE81F0D9F759DAE33D6E95276A937
-:10890000699DCAFBBE9F2062DF98F5DF670F5F4A53
-:10891000F92E67DA72C87F60D087B59F29427F9EA3
-:10892000BA91EB99A7F794258E40BBE888EA97A007
-:108930009FE2973EF6E2798FA2BD0AC3B860576BFB
-:10894000F13A3CA7BDB32DEF5ABC8FA2E82595F6AE
-:108950008DE2978AE85E90A2978A1273298F424B24
-:10896000457C403FB4EF761DC9FB7D21CACFB6C917
-:108970002588E615478A12513FD8C9B83F427AA9DF
-:1089800024B5236A1F599CC4FD03AB32DEB907F539
-:10899000F7A9CFDAE8BCC9545BF7CB987FB0B34DE9
-:1089A000F5AF807AF54B731BF09E8AEA27253FAA24
-:1089B000D987DB97A47D07E9ACD5E67310BCDF3D12
-:1089C00080EF83DB247F3EB4AFDD7BD5F0ED98E70D
-:1089D000BDB9D81F7D2EBB2859BB1FF32A5966226B
-:1089E000D9DF532FB2D17E7A6A50E2CFE83E167DAE
-:1089F000F31494B3A79EDF69A77383DB2596011355
-:108A0000399C71F019BADFE397AF50BE42D9AE5727
-:108A1000283FA137797F3AA4B030D9DDCD742FCC6F
-:108A2000E2CD46BD83CE415408BDA966CB09AA5705
-:108A3000A1FE0FE3556D52421AFC7A70EFAF28BFCA
-:108A4000A1661BCF6F80F7247FAA307EAA45E87C01
-:108A50002EE3743057C89F458CDF33B4A8999FA389
-:108A600033EE4532E87CFEB639948716936F86F66E
-:108A700025C5219A89BE63EF1BE2F46DBD77C84A14
-:108A8000DF2D067D0F63C390BE3F99C8F3C33E79C7
-:108A90002521B110E6F3C98B0AE5DDF741E7B49F64
-:108AA0001E11FBFF99B04CFB93D1AE73CF47B48F2F
-:108AB000D41E3963477D754AEB87B40ED35BF74FFD
-:108AC000463C7F8B05AA116FDF6A4DF4219F4FEF63
-:108AD000E0726B5AAB23847EEA6FB196265CDFAE00
-:108AE0007D3F6F4A417A7982D38B21CF160A7C2E43
-:108AF00014F85CA8F2FB9EAA0AF73F88F9D0D318B5
-:108B00009737D35A84BCD964C66F97AD4525BA1937
-:108B100021B1E6ECD8FD6E11EBA0738F5D99C3E92E
-:108B2000EF4906C15E453DAC7A9B350ECEEDFA1A93
-:108B3000CB7E7A30C9F6A5EEC178C7B22ED3BBF989
-:108B40007E360DE809E3216DE18642947B067EAC1A
-:108B5000EBD2A6E526F575DEF965A1B71BF56F8B9F
-:108B60007B265A7CCDEE683BBCDCC7F5F0AAB14A47
-:108B700010D7B5C75EC93B38529323F60AD8299F50
-:108B8000250DE076CB28E8FA852C85A5A545EC9542
-:108B9000D519F74F2F4AC3FB23B8BCE81C03FD616E
-:108BA000BE80CA484ED56E7384D0CEF81F84BFB83D
-:108BB000BB008000000000001F8B080000000000C8
-:108BC000000B8D576D6C53E7153EF7C31F8913FBE0
-:108BD0009A78662C34BB31F9202584DB109A40D773
-:108BE000F626A51D83141C58296AABE2B65BD90A88
-:108BF0004E5085281295B889A9D6956942DA7E54D7
-:108C0000EA56DD226D621BAB4C096A9892C8A1A19D
-:108C100025E990A0401BD0D659FC60EB9490C0345D
-:108C2000D24D95D873DE7B8D1D12B43A528EDFAFD4
-:108C3000F39EF39CE77DDED75D7DFFF29AF544DF7E
-:108C4000EDBFEECDC2C6FBA54709B63A94F069DF89
-:108C500020EA20F2449A60FB242343B0ABAF7B139D
-:108C6000254423558B4209CCBBA1EAF335B46FF1FF
-:108C7000E7E1BCEDFA52212A23EA84D5CBF2FD9D2F
-:108C80006AD6CBF33BFB25D386ED3DF99F8ACA52CA
-:108C9000A2C981E98AE760576832FE71FFF796A89A
-:108CA000D877EA928F6295D8D8322FD0FD442F9290
-:108CB000F3D9A611ED9987F6F04BEDD4800E697FBC
-:108CC00039B5C0AF878C0CD6755E540C4B47FF0985
-:108CD0000F513351F7277F1A9E1721BAF6AE64F869
-:108CE0007467FDAB8D683F6FEF9F87F9377F27195A
-:108CF00016A6BFF84DA287D0BFED4DCF95ACDFD9FA
-:108D0000EB96F89FBEB217F39247FCFA1B687553B7
-:108D10004F39616E0FED1736493FBBAE04E1AF2FFF
-:108D2000E5655CC82E581F23DA7E78A6BF24A9F912
-:108D300036F2DBF397D68EE182F1355A69E46A00A8
-:108D40005FEAA8EE96C2F1171F90B0FFE488A2F97F
-:108D50002481DBDBDF2AC4E734C058C0FD4526216F
-:108D6000CFC973257611E6FD731FC66A89C6F7C1A0
-:108D7000B90F7E5A148187BCD2B14B06DF8F713D8B
-:108D800019FFC452A23F0CBE7F2FF30109883A6C31
-:108D90003F8C798B0BE24E23A88238119791C17ECC
-:108DA0005D9F2A06DC735C35DE483EAEE36A3668BA
-:108DB00014F0637A9FD9315C8D72492745BD64698F
-:108DC00058D8DBBC39A1C4EDFA7C1BF96C35B1FE77
-:108DD000299717A44E45E388F3590D45043FBBFB83
-:108DE0009DFACA038EC5FE9B8971419BF79F35DEB4
-:108DF00066EDE0F19B9501B218B72FAD766EEF8E60
-:108E000029F406DABB3F79A9960AF6278E13F5ED09
-:108E1000F24C4599B75DE764115FD7B91BD12AB40D
-:108E2000D7D23BAB35B4D7517A3F8F7F180BFC8834
-:108E3000796DF1BEF3F37EBE0829225EE27CE1CFBC
-:108E4000A25F3A7EDD7C7B68A3C0A1C7E5D50B217C
-:108E500059CC7F554BBCC2E770F2DC7FA3489B8E98
-:108E60005FB812E47AE5EA7DE7B9BB1D3776E0F535
-:108E7000375BF5F34F83078D23AA15429EC7C68A39
-:108E8000EC76C66560DBDFF672DD2EFB88CFC3EEC5
-:108E9000C16DB5C47E138965719CC39B833F5EC65B
-:108EA0003890D423E2B2383EC435D17731AAA33FFB
-:108EB000397031CAE3C9E32B7E6161FEF2338DEB79
-:108EC000B8FFD86955F0AFF14C93E0DFB13F37956B
-:108ED0002DE2C0C908B0DFE4881A677C92234D1FD9
-:108EE000B7635EF24C5B93C4DB9C692A63FD592E29
-:108EF000513C8D7169A44AB473F9FC5C73F09B1CFE
-:108F0000021FD02F51CCE10F55CDE0CF8EDE535E46
-:108F1000CE63479F6216F228B7EE90A60A3FBF6560
-:108F2000FE804FDD69C914FC38EAD81D7DC7447E38
-:108F3000DB3D6951EFEE231E67FC8F8E253A28D664
-:108F40005934CF623C3EE62ED461ADD75E480871FD
-:108F5000B492B6A4E7D0C39AB024D68D5E4A7C9B67
-:108F6000F932DA9AA8D5EA67CFB3A84DE443928BD9
-:108F700077AF678D3D87BF2AF6873C8265B4353E63
-:108F8000C77838ECF067AD971273C5F379EE3C11F2
-:108F90001D90C18BF3ED1E8DF94F64962C80CEAEE3
-:108FA000777576D3E31ED3BB0CE3A49D2AC2F8FAEF
-:108FB0009CDEB640CFA00B71FCB1BEC5DF8C873202
-:108FC00080B4C39CA9731B29EEA145F0B36666FF6C
-:108FD00013AC970D6C55E1E76E3AF829EBE0127C83
-:108FE000A9A11AD641524A021278F3EFD31E4D11AD
-:108FF000F1DA55AC0777E697D3990FA17F3AF4EFF2
-:1090000034F48F6D77DD670D59E0313A74E9DDB0E6
-:10901000D0CF228A3101BF8277E49DD4DCBDEFF04E
-:10902000D77DFB7C7E7F06DF72F5998064A7EB67B6
-:10903000D7E786E6D421E91FF782ACD4453B5F979A
-:109040009147BDE2F0CFE74998E5C8C3D3D79A2945
-:10905000673DAD838A22BF8947259B751E7156F8EF
-:109060000A747E628124C6776F966C0B5F87EA3E36
-:1090700013F7763273D6CB7CAAE97DEE35716E2D6F
-:10908000BA40D17C1D37F89DFBF276FD72F9F2A053
-:10909000CEF981CF428F23C2F27CBE1FD7BBF7E14E
-:1090A000869699F5ABA5B38F95238E274DC9B0E76A
-:1090B000AAFB96FB4EB1DC7DDDBA2F09272261E0C9
-:1090C0003179F6C6E6A5F0375AF7F70ABE473BEF07
-:1090D000C2DF0A97DF5D81600385A02EB57A2A0B77
-:1090E0003CDE2B4DDC13669D90BF0ADE4BBC3EFB85
-:1090F000F6CB12D78304DE773B2F55AEBFAAB0E67E
-:10910000E874849633AF7EAF69CEB9F5D80B590FAA
-:10911000A81E8F9995FF5F77BB4F7CD4C075B93679
-:1091200034D2E02DA8DFF8CB38F77C8F0C7C10D53B
-:109130004B0AF925BBFC528595A48DEEFD38936F43
-:10914000E3CC37AEF7D10FD63FCD3CE9DD1491F437
-:1091500082FBF3F8F9607581DF897E45CC27355BAA
-:10916000F34469619CAF893827D28E3FA26CCDA6AB
-:10917000A585E32997B759C1DB9F2CDE19E7739CBE
-:10918000E3AD4A0E6F3BFB3A48DC476EDE692FBE0B
-:10919000202E6BD067FF06E3939EA98A70C1B9F8B1
-:1091A000A18B737346127C5C4996C27E9BE1F119D8
-:1091B0006EAB9451611FA08CE8275A48CCE3FB5D4D
-:1091C0001E37AB9921A941CCB354F072159D15F30C
-:1091D0001EA229614D82C0C3B691216C8B3FB38E14
-:1091E000E5A33E9D56984F99A81ABE0A3EB294CC6C
-:1091F00055BF7CFE2A5DCDF11393F1B8D91A9F4378
-:10920000AF0FBAE7DCE0B71AD77982EC43E87A907F
-:10921000B20A6FF2804A6B14E4F3A04AFE62C47B88
-:10922000745816E77730ABDBAC5F4699BBEE0BACFE
-:1092300043BBD974CE295F35CF34E6F3BD138755D0
-:10924000F017E2792ABDEE113866C47E0F73E0C8CC
-:10925000BB957495DBA970A5C3679A7A96F779A434
-:10926000DF27DE39B2DF1278FC34ECD433003C83E4
-:10927000F0B3EAA04463D8D758E4E49BF3BF0AAF45
-:10928000BE5023CF77EE31B4690CFD01BFB38E68B9
-:10929000B5C6784999A87C2BF0F5719D8C92883BD6
-:1092A000F8C2D4B5BDE2DDE6D30E2124A3FFA3317D
-:1092B00009EF69C934690FC7E32FC9F0FB1AEC182D
-:1092C0002F7C57FF3AFCFC5B7CDE255D13785182D6
-:1092D000747E67CCA75F697C6FC83CAFCC81EF1F01
-:1092E000C0EF4957EF2E173BBA71D8DEA8CBA8C7FD
-:1092F0009688DFE07A34FA2B9613FC6E284D08BF6F
-:1093000097A523D5C2896AAF60BF399E07C86C6133
-:109310009C25B75E7BFC8EBFE922C7F299643E07AD
-:1093200020E77EC47500E7C28FB6D5E6D4DBFABC71
-:10933000C84E61BF69392EC8F88A62F805DF6389B3
-:10934000B16658B5CDD47796F0931D7904F279A41F
-:10935000781FDCC7F4033C1041865D9A934FAA4402
-:109360005ECCBF9752546CE07144BB4A1D9EEDFA2F
-:109370006B914D95B3E33BE94B9CE4FCA665636CB4
-:1093800054DCA33B9B59EF18A7EFE47092F3386DC0
-:10939000B163A9AC2E7019619DBECF67DF93C1BACE
-:1093A000A77C7635C79FC303051224D55C9C73F850
-:1093B000685C3FE6B189FAE5EA1FCBE374A0D8C147
-:1093C000073FDF1C1C74D471E9ECFCFF0753B7A7FF
-:1093D000EBB00E00000000000000000000000000E4
-:1093E0001F8B080000000000000B7BCBC7C0F0A360
-:1093F0001E81FDD0F8E8B89D17BF3CA9588601C171
-:10940000CEE7626008E160600805E2FD407C00880C
-:10941000E53919182280381288A703F93380B8007B
-:1094200088D3816A9B99191876B131301C04E213F4
-:10943000407C9E8D74FB3F88333054C820F8C78031
-:10944000EC2372D4F5E3281EBC38CF0095BF4E1331
-:1094500095BF4D9B81E13D929AF59AA499AF6CC856
-:10946000C0A002C4003A4CE95968030000000000A3
-:1094700000000000000000001F8B0800000000003A
-:10948000000BED7D0B7854D5B9E8DA8FD9F39EEC5B
-:10949000494218421E3B2140800487102250B0935D
-:1094A00014142DB5113D2D7ABC3A8447906740AB1A
-:1094B000E9114F3624840001068A3572224E103499
-:1094C0005AA841F1D1536C878716ADED8DD656DB86
-:1094D000FA88A8A0A89C5445A7E7D472D7FFAFB5D7
-:1094E00093BD273301DBDE73EFF7DD9B7E75F1EF74
-:1094F000F5FED7FF5AFFFAD71A45B411F9EB849C51
-:10950000873F9AE68A849021FD2921B2D6E3809490
-:10951000E8E7475860725EBA18F82FA3ADB0CEDB0B
-:10952000FD1742B208F91ECFA37F21806770C018D3
-:109530008F9192A04262C5FDEDCC200CD644819C57
-:1095400017E0AB35DFE8A7DEE11B4FD208F9C2C94F
-:1095500052BD8A6695D3F44D67B4B1801087101E52
-:10956000C1C65377497529A69742DA2890B95D9EFE
-:1095700024E320EB08994493FDC34452D13FFEC439
-:109580007246DAD44048CCDE0FCB3209256BB78265
-:109590008E1FDA7D5F0857E0783C44067C281C1F4C
-:1095A00036122484CEEB88FFF2C03C3AFED6694ADC
-:1095B000D00E193B874165E233F038371F610787CA
-:1095C0002B89C6F11D6B1941EB398322D944A1A621
-:1095D000822A07292164EB94CF03613A1EA71C213C
-:1095E0002AA49EE4E3BB9A88BC9DBBC8C5CC3B7152
-:1095F0003D6458A349088A302F63BCDB6C745C99C6
-:10960000743D2689641F85B794CF4983F118F3729E
-:10961000A4E8A719F03A9A90CD0D0E4C9B26CF499D
-:1096200023508FF4CE85F5DD3A254BDC24F4973FAB
-:1096300032E539470F9D6F23AFD7AA1D7540796377
-:109640009D13F1B695E32744041CF7E652D7DC6876
-:10965000C9C07184880FF3B73A692598879744F792
-:1096600015400B3D6DF329EC9BAC966DD206D2CB29
-:109670008C523918A3E3F4783C413BCDF704587D74
-:10968000C7EB4254C3FA21CF305ADE65ACFF64B158
-:109690001F9FF4FF3E524D08E5475F4EEF6BD08FA2
-:1096A000FD757B3044BFBBFFFCE96BF369BBE46D28
-:1096B00021B80FFA25AB2CEB45F632BCDA54FA6F21
-:1096C0009AEF9AB668364CC1FDE5E3D580B78D4573
-:1096D000AB5D6B61AD8AD9FAA9F47FE70B69FB9AA0
-:1096E00062E9DF665EDF02204D2BEC1E39E7DB23EB
-:1096F000B4D4F4E1EEF19158062D2CDD88EB9DAA4F
-:109700005CFDEB132E3B6EEAB78D78334FB9E93F22
-:109710002E2597229F5FA0FE170DC1CB8EDB70DE3A
-:10972000A259DEA42ABF9ED3471F9D1550FA28C117
-:10973000F50C5C53DAFFFD25A00BE007BD12E51820
-:10974000F2229D6FF374D22BD1F5681AA968EB2829
-:109750001EECAA12137CACCF5EA02FF807AD6A2FC7
-:109760006AEE16C603F03D8B1C6C19FAAFC1D82007
-:10977000E34B5C87AF8ABF18E06F5C3FFEECA43A16
-:109780002D06EB5D1D40FC78F938364CBF5D8BD162
-:10979000F96CC8FE61E86D62C2E3A58CCFFAC6938E
-:1097A0001325E6FE0DFEBA4408BD08F89194E06B5F
-:1097B000618A0F325509EE4B322F596072A51FCFC7
-:1097C0000E99187802FA3DAC07AEF1E290AA1D2678
-:1097D0003CDB03CFFD19F0276792987B3C7E6F92AC
-:1097E000D3A9FCCA24BA3B0D5B9101FE332940FE8C
-:1097F000A4F9339432900B9707C3B49F661BEF4FC5
-:109800005D6B59D73FF375EDCFD703FF64C9B761DF
-:109810007BCD5E2E37D4461CDF80FA7E563F71BE6C
-:109820007F02393A09CAA99C7E1A03A06F1CC39A09
-:10983000671D01BC8FAEEB9A0F735409E2C190FF14
-:109840005401122847F5C39FA19E43AB46BCDB736E
-:1098500042248C78B3EAD3947239418F0EA02795B5
-:10986000C2461B85F0DF1C15F98D24EA6F9E8672B7
-:109870002F4A0F3626F0156D2AA99E291598BC256A
-:109880007A26CE5F36E880DB0736031D3B193FABF7
-:10989000BC5F05C643E5A19344B17137A57480BD93
-:1098A000A40EE173A1B298007423938D20E7EC21FC
-:1098B00091E80503FBDFCAF549AA796C9D925C0F1C
-:1098C000E40A4C0F489E3ABE1E37AAC067821E2685
-:1098D000E781DF4884EBBF20AEF786867AF20E9DE3
-:1098E0008CEBE89544A3F423E7D48542B49E04BCF2
-:1098F000484534F194B3540E6A66FAEA5B47B216EF
-:10990000DBB351B4C03C6D1EC73C321E52F51A4C3D
-:109910008BC72E04FEB0A55D5E0FA61CA59B4A0159
-:10992000FA7724A72BE2A14C3A0561AD3A697F7C16
-:10993000BD79B994F4D5471FC67C35A5DA3B906E46
-:109940005CE5AA00AC40C16E18CF503E9AA1E1E69A
-:1099500055E27858B7C8AC51747D86F6CC43FDE427
-:109960007DFDCA0F605EEB4BCA4E8009971654AF5F
-:10997000B99CAEA7AB980880EF8DD0D85468E1842D
-:109980005E097A1DFE994DC8FF109E09E91E463EEC
-:10999000567B53D464439E8883DA2FC279FBC0FA86
-:1099A00029E53331F10FEAF1D517672FDDC8FAD376
-:1099B000E9FF80EFFC09FA342D646A97007EACFD64
-:1099C0006C00BA41FCAEFA6FE94F253B1C1AD81D5A
-:1099D00045A21AA57DA711D54F653171CD9009E833
-:1099E0001335A75787E5BDD0BAAC276416CA51CA4C
-:1099F000B7663A6FE7722050D354D04CDB3D57EE38
-:109A000009821C184AC56646FAC0F96C4EB0B337D5
-:109A100097EC41F9D848E9A810ECFD1211EDA18DA1
-:109A2000458FA9667DF53343DE0CA00FA2C915282A
-:109A30003A08A1F8918AC49073FCDF4F1F8976D24F
-:109A4000C5D287FB46EB7A7CD5F5FA659FFD7D7123
-:109A5000F4F1F7F667AC6B2AB945D715EDEF166D43
-:109A6000CEA0F6CBC075DD81EBEA2A22A16472B8E4
-:109A70005B10ACFAC99C9AF507B9D5B25EB64BBF7C
-:109A800033F78141F0619B6B9DAFD1AEB35ED2DE07
-:109A9000053B5656511F19FB878DDA0E1DECF973E5
-:109AA0003984D97B91553101ECA022827610342083
-:109AB00052D8A985A29B0446FFB02E867D63A3E6FB
-:109AC00098B93F497559FB9FAB0BE6F13BEB151C71
-:109AD0008703FA03BEF4D00669BB520E8939D1FE62
-:109AE00064EB075DB17DFC9D17450706BD025A1961
-:109AF000BD5AEB3507CA48B2F51BD0DF75D6F1A6C3
-:109B0000944B89F53CB276CA648FA4AE2793532652
-:109B1000BB66789FFF4237ECB9A7056A173606BEC9
-:109B2000A3E3B8E13F54BFB6404AF59934AC8A8408
-:109B300035D0931AE3132D9DE9DF4EC1B20F37BE26
-:109B4000A71E07EB2FBE90D222C83559B3D8CB89B8
-:109B5000696343E06B32254A77FD0353E589D48876
-:109B60005D1B9A5B4DCB6F6CE89C0ADF8D723345B1
-:109B700063FF4DD5A6C93E96092DE7C0AFE4FC446E
-:109B8000F8A812CDA4DF1DA40BF3E957BE7E04D7BD
-:109B900001ED2ADA649DA861BB0A791ACB414350D2
-:109BA0008E4AF1A972316B0EE0CDB65008C7254739
-:109BB0001CAB29DF6D767258E3B09FC32A870B3840
-:109BC0004CF504C06E85C23475DA222AC22E0E17F7
-:109BD00070389DC37E0E177258D881F06685B5B770
-:109BE000498EB2F65D1CD6389CCE6195C3851C2685
-:109BF0007B58FF7606BB6C51D6BE9BC3051CCEE0DE
-:109C0000B09FC323382CEC4138D5FAB98A3A199E53
-:109C1000FAE442573F8CCA83E3B50F8E25C08C5EB1
-:109C200032044687F16F19741344F9483C79C86FC0
-:109C3000E31C6CBD1BF797A15F82703F8AE9FB09AB
-:109C4000D0C7E73AC5E060FCF5432E4F77829D4BC5
-:109C5000D3ED0D2AA6DB1A0268F76E69D0B85FA5AE
-:109C600018BF6F6C0822BCA16132A6EB1B42F8BD85
-:109C7000B16116C29D0DD5983ED83017D3BD0D6188
-:109C80004CF7342CC672D1863A8477537B17D2F6C0
-:109C9000061DD35D0D2D98DFD61041F891FD65CFDF
-:109CA00017513D7D2E2CA29E4F35FEA173AD7E90A7
-:109CB00021D556B9983E23DD92AF4ECBB6FA4DCAA8
-:109CC0000B2DB0A764AC0576159559DA73E44CB545
-:109CD000E42B99551658F65C6581C744E758E0D1E6
-:109CE0006D3758DA1B19A9B1E48F685962C92FD0B2
-:109CF000575BE0FCFA7FB194CFAD5B67C9DFE60C40
-:109D00003F235279357CF1264BB961E11DD67DDDCB
-:109D1000ECCC8B925BE4333DCBECCF4894F7521EF6
-:109D20000985506F31FDD208740B7EAF5C12DD27C0
-:109D300080FFEA8A13B0EFB01731BD33607F99D04E
-:109D40009EE279F0359DF653E93B11E831F11909AE
-:109D500098EA51B97F5264FBE64D77B17D75EB5DB2
-:109D6000C9F7D728D9E93C5ABF4CEEBFED11256E93
-:109D700007E9967D4AEB5D0296FF7BDB37F213DB4A
-:109D8000EDEF8FD25C85D90E891A7E51A267F5EF6F
-:109D9000776D3DFEF9B0EF31F6B912E7F3CAB9C1FC
-:109DA000B79B289FAC5709FA0DD77BAA08D815E7AF
-:109DB00054C6F7646F1EEEC78DF203C767B22B500F
-:109DC000FEB8AC7E5ACF1C942FEB3307B7CB94B8B8
-:109DD00084FE3B292E9018D53B8A5C3DAB808E4B90
-:109DE00079450AAE25A87F92EEEF09D981789012C5
-:109DF000EC9BA60509726F462ECEDB66C8B7CC2A4F
-:109E0000FCDEA40E3E2E3B8C0BC6C3C7658BBB315C
-:109E100095E24E1CEF947806C293E37E4C2F8D0F93
-:109E2000C7B4223E0CD349F1119896C70B309D1848
-:109E30001F87F5CAE263309D109F88DF83F1099880
-:109E40005E12FF1A7E1F1F9F826969FC1BF8BD24EA
-:109E50005E89E9B8F837F1FBD8F895988E895F8B61
-:109E6000DF8BE3D7603A3AFECF988E8A5F8FE9C8DE
-:109E7000F87C4C8BE2F3301D115F8AF50AE3B76082
-:109E80005A10BF15BF6BF15598E6C7EFC4342FFECB
-:109E90007D4C73E38D98E6C4D7623A3CBE19EB65FE
-:109EA000C737623A2CFE03FC1E886FC7342B7E2F07
-:109EB000A6FEF80398AFC63B304D8BFF08BFFBE210
-:109EC0000F63EA8D3F8EDF3DF18398BAE33FC5EF24
-:109ED000AEF84F3075C68FE17747FC08A6175A27B2
-:109EE00025C72AC7A54C97059EFC6EBA853E2A5EFB
-:109EF000B7CAF1F2570A2DF9652F5AE578F078992B
-:109F0000051E7F78AAA57CC9A12A0B3C76BF558E79
-:109F100017EFB5CAF151ED56395EB4D32AC70B5BC2
-:109F2000AD725C6BB2CAF1BC3556399E739B558ECF
-:109F3000672FB3CAEFC002ABFCCE22BBACFBEF195C
-:109F40007BAC7A6DDA2396F63CE58F25EC57A22898
-:109F5000675C25FF6EA9E7283A9A209F7526A7120D
-:109F6000FCE5801299F2F71DC415349FAB18693ACD
-:109F7000970719C07734CDE47C3704F88EA6E9DF63
-:109F80005C86E74C5F7CABE5174DB4B1F4E184F936
-:109F900005F44855887E6F1EC661FA45003897A0C3
-:109FA0009F80E8672AC12FD65CC0E07F934E55EAB8
-:109FB000CC7FCBF2C95996EF64F0238DBF5A0BF9D1
-:109FC000E969D1EC204D1FB12597D38F49ECBCED49
-:109FD000AC18EA90E87CFFA3B2E776F0A3FDD51EAB
-:109FE000DE27D1EFCB1CE17C704D7F6C0B3F2483CF
-:109FF0005C24A107E17B1A093D24A1BCB6FA451BEC
-:10A00000C1E0A6ED7C2656EF87FC8CAB17A35FCA98
-:10A010009877B377F0F14425A6979AFD04F78DFA67
-:10A0200011859F2311765E0329D583F7B87D21C85A
-:10A03000DF7044D963A7EB60CBC99A4FC6B36216F1
-:10A04000FD116B5E057AD8017A680448F92E4C3D03
-:10A05000A49B9D1B915E4C55A20A901AF3EF9B772F
-:10A060002E9B37C5C72F24DC1FD461F975EEAB27B3
-:10A07000C37C283E4EC0778A8FE7A521A9F141E035
-:10A0800064818E3FCFA0A2FD82C5FFF8BE10FE8D79
-:10A0900064F263E6D507713F794052111F06FEE86E
-:10A0A000DF6DE9863F86D5FB23F69BD09ECCCFC5DE
-:10A0B0007E23F1FEB93E34E8384324E1647ADD388A
-:10A0C000F7219D795FC99F2D28CC2E49ECC72657D3
-:10A0D000E379EA00B99799B0AFCF0CC3A250FD491C
-:10A0E000F56592714D57B87F4ACEBFA8F32BC35F79
-:10A0F00042F6E77DA5F32EA004286F901C399E87B9
-:10A100007090EBDF02B0EBA83D72EC8DA762CBA99B
-:10A110001CD85044752DFA2DACF6DC869888E7EBF8
-:10A12000057E2A706863F5DC0E90B93D68F42B3724
-:10A1300059FD299B6D7C7F7BD88AC7024AD0FF4E90
-:10A14000B7DCC493CFC6C7CF2D8D76F6F48DDF3A3A
-:10A150008E074AA83964C2676129251D18478C8D6E
-:10A1600023B17FC2CF170CFE913DDC6FA2E663BB2B
-:10A1700046BF89FD1069369E27A5C2EF807EBEE2EC
-:10A18000795D859CFCBC93AE0FE2696C8AF535CE97
-:10A19000EB0CF8D81BB578FEDDDC59837654738060
-:10A1A0009FB3FF85B60AED1092D45EDCCBF1BB897C
-:10A1B000EF17F746AA1C582F33DFB24E45DB67B8BE
-:10A1C000000F4D6A553AA4FB76B27223EFBECE154E
-:10A1D00066765B3AA49B8AD977D798BD0E567E8F58
-:10A1E0000AE9E612F6DD5D7AC8C1CA333F2DA9A798
-:10A1F0007FA673A022B55A14CA41FF92904C619772
-:10A200001A25E04776AB5D981AE3CE8E88E2185A9D
-:10A2100025BB33947E25F8DDEA4870241BAA03D6BB
-:10A2200039CA972FC7C8AFA7F9B4BD313B8F564283
-:10A230003DE7CEBD95576AFDE577F3FEC774465BF3
-:10A240000AA17C8EB5BD76DE9EB3B3EB04F89B29E4
-:10A250008EB13D237F17CFB7437E26521BD6974B37
-:10A26000DE8DC1798681E740B1D8087022BF1BED31
-:10A27000B4F171043BA3912AE867AE751C3F34C862
-:10A28000B29384A21E933CE0F9119EBF01F6FDB487
-:10A290003FB993F9518DFCADC63823AC7E23F70B43
-:10A2A00018781DC3E591413FA9E898E8A265FF46EB
-:10A2B000EA5D56B8CE64DF01BC38DB9A1F2EB4C20B
-:10A2C00073C75AE15099159E3CD5D2DE177D7E9416
-:10A2D000A813FD25DC8F62F85E76A935B8CFE9F7C3
-:10A2E000D3455C588EEF3B7278B987EB98BFA5D108
-:10A2F000C3F985FB5D9C5C2E3617B17D499F5DC11E
-:10A30000F1DDC5FD1A8F36B4B1F8940BD8C3EDBC9E
-:10A31000DE2E7EFED8C6FD323F04FCDB61BD985FB9
-:10A3200026C2FD325BC12F43D356F0CBD8813F9973
-:10A330005FA605FC32343DC0FD323F02BF0C851FD5
-:10A3400006BF0C4D1FE27E997DDC2FF300F86528D7
-:10A350007C7042F75CF0B775807F86C2F773FF8C24
-:10A360009FCBE58333A3D9E00F7B6466F27DB1DF39
-:10A37000C6FCEEB960A850FAB884048FA1BF9B8ACE
-:10A3800061F0774FAC0B362A9960B732BC4D0C07A1
-:10A390001B6DE560B73238DFC6F428E80BD01FE448
-:10A3A00030F327503ECB047C6FE1745976222CCCDD
-:10A3B000A3E3F8A3CCF5A2460218B7C0F902F24114
-:10A3C0009EBC21845E972741BB04C795BFB7AE0AE8
-:10A3D000C468F1D3D5475DB4DCA8AEE03A707D1611
-:10A3E00095A8E05920CE224D84F5395819443FDA1A
-:10A3F00096DF4AC13DD06626B1D0031D1BCABD31D0
-:10A40000063CCD4A0F97C477A3FDDB5C37270DE9E7
-:10A41000492383EEC7FD21EB3E286DB2D59FD5BC05
-:10A4200097B5938A6E8ADBADF6C4A89DD67D54732A
-:10A43000D19C41FDCF45ADD6FE0B9B12EA7B06AF0A
-:10A440009F1FBF1AEDFB54F43D4EAC49B34DEA8754
-:10A450003DF1CBB07CA27D2703A150BB4D3EAE6049
-:10A4600048957C5C0D815D2B1FD7781AE4DF431C77
-:10A47000AE66B0CAE220A83D986B1B82EB9370BE1B
-:10A480001D2270FE7C109501FDBFBE705D88D2DC80
-:10A49000C17F22B8DF78435E55A55378D76C8728F3
-:10A4A0005D02F4C6E21914BE5E194A746301D0C39A
-:10A4B000C322017A78A473703E1E10E7E009A17FE1
-:10A4C000A6A0492D03F59DAADECE2671563449BBC0
-:10A4D00053395F91E324D16E9E0AF35DDF34474523
-:10A4E0003D725D10F7074463E337E45C46FAE0EB46
-:10A4F000B7ABC17ABE964D92DBA16B6C9CDF8A999B
-:10A500007C34E83FE3C1C1DBDFC0DB8F770916FF96
-:10A51000CE90EBAA2B6D99B8DF097A408E7E293157
-:10A520003FD961169F66F05363D10E179437FACF67
-:10A53000CE89C1F684341F99C2E226287E713F7805
-:10A5400084CAF11294E368F73917D785989F3C8243
-:10A55000F10DCEBAA00EED481E462FB0DFE4E57136
-:10A560003C1BF78A1872D13897D9AD869C37E8A082
-:10A5700031C0FDEB7365E667FB0B9D9FB11F81FD4D
-:10A58000A15A87E77BCD93D87C6C992C0EC4561CBE
-:10A590008BC1D959B377D15A98AFBED0D0D73CEE42
-:10A5A00082B0B82B231E0FF003E7E0056DE3518E58
-:10A5B0001878FCB610AE073EB265EA4218E7D185BE
-:10A5C000ED1B784BC4FB77B93C1D9EC20F97A6309C
-:10A5D000B99EA1A85781BCDD7284D277927DBD93CC
-:10A5E00097EB88CDD90636A2C1AF46FE0149C37E9E
-:10A5F0000CB820AEB0B8BE9875FFF1FFBA1DFFA829
-:10A60000CD1A77F7FFEDF8FFDBED789A0F7648F873
-:10A6100002763CB7F3F7F6D16F829D5E2C1FC130F6
-:10A62000BA047B3EAB7846AC0AF23BBBBAD18E9FF4
-:10A630003CB81D4F12EC77C3AE37EC77C39E37ECB6
-:10A640007532D09EE7FAEF1BEB4232C48911D47FFA
-:10A65000E39ABFB14E87FE13FC1E12157366FF45C9
-:10A660002FF0F910133F78AC76C3C5CB0719F53F2F
-:10A6700009E65AE46B46F6E0768E11EFFD45AE61D1
-:10A68000AF87D83968513131DB634D548EFBE87C9C
-:10A69000DAE7B2F329C2E578B6E197290EFB47A3C2
-:10A6A0007CB7CADDF6C5353A9EA394133C7FF4E42B
-:10A6B0007485E07C3C6B6E04ED492A7F8B1593FC1E
-:10A6C0002D68AB4039A773FB32119F20EF0265D094
-:10A6D0004F829C21C19745C8CF85B36BE087A88086
-:10A6E000FA03E234C60F226F2E325EC3889FC8A3DE
-:10A6F0007F206736C86C7CE4696BFC3951297D5436
-:10A70000F4DBCDE4FDF98239EECFB06312EB51B941
-:10A71000A026937B6F08E16F2983D047A23F8A244C
-:10A72000C8692A8844E8BF60F62CF433F5F9A564BB
-:10A73000ABDC9603463CCB7FAFFCAE55FEC6B8F310
-:10A74000AFE8B7DBC8E5F3007E4E68472CE9223D51
-:10A7500049FAF79458F1EE2AB2DAF302085B881F3F
-:10A76000CEB19E93CB9EECE4E7003C3EB366B2B123
-:10A770006CDA77FF48F9E4961336BC4762E81DC3EC
-:10A780002F7B0BC469D2F5A981B84D4ACF0B48B5D0
-:10A790000F323F2622C6837D4C5EF64D34ADD37D0D
-:10A7A0008AC2FA69B19D847B42463CE2C20883FBBF
-:10A7B000F0DF668517913959701EB168A70D38888A
-:10A7C000DC42E4933DC6F8297F6F51587C752DA972
-:10A7D0006B0639B69EC773D7A84486F8C1E54FDD2E
-:10A7E00057318FC27BB9FFF60CC5BF66B28397782D
-:10A7F000A20A9C2BBC7368E277BE46A07EB4391BCC
-:10A80000E208A9BD0A718489789FDF621DDF85C6D1
-:10A810009F385EE35E51AA71C89D4228D9FEE0319F
-:10A82000C51AEF76A1FB4EBF53347EDE6CBDEF74CC
-:10A83000A17A7F543492EC9ED485EAF5FC8DFDBD5F
-:10A8400097A2DE72478F027260A51C9E2514F6C780
-:10A850006B29B6EAD0708A0AF9E90931385A32957B
-:10A860006BB9C8722760637111E5668983B4779606
-:10A87000F3F12FF63FA0007F7EFCC8DB57C379CDF4
-:10A88000D29F4AC441E77576BF97C470DF11554027
-:10A890007F2D392431FF9B1CABB8D6247F315296D3
-:10A8A000E27BE9A35E8CAF58F2983D3A9BD65FF20B
-:10A8B000E43BE309C5C3D975BDCF0D87FDC42302B1
-:10A8C0008B27D47BC65F4BBF2F91C9CDD549E4A060
-:10A8D000646774FED14FDC73818E84CE233761BBF5
-:10A8E0005DDFB5D94D76FF7F2A36A31C9E33E90F75
-:10A8F0000BD191021B9FF99E8411C7F9D1C3021B92
-:10A90000DFD3B6A813C6D7D9A18469B9959D7F4274
-:10A91000BAFDC6A3077C8087954F4B16F9B2B25398
-:10A920008AD9C763FAB61DCFAF421E81CA911528D6
-:10A9300062687A6839C67DAFE8DAFC27C907F5ADE9
-:10A94000FC43F1128C015E5F9582B3017EFC211FF6
-:10A95000EC07CF74EFF3015E69BBF3144A57977DA0
-:10A9600066E233C2DA8FA70F6C8F5A380AD0D7CA83
-:10A97000AE8DACBF04FE3C03FF1836502F8CB55B88
-:10A98000EDFA73E4C50ADC877766248D93EFD30B69
-:10A990009C5F971E38B75BA7FD7EF4D887BB753ADE
-:10A9A000FE657FFD74F79D6057FECCA9829C59F926
-:10A9B000C86F7DC484F79976C6EF671F7EE8C15DD6
-:10A9C000945FCEFEDE8EFBD1B3CF9CCED3E8BCCF5E
-:10A9D0001EFC739646CBDFF6CCCCA18087DB9EF8BD
-:10A9E000C6D0C1F6E740AF51BB795DA3B8AEDAD3AC
-:10A9F000020BCA3FCCD384F53976E8581E8CF3E3BA
-:10AA0000D7EC780F7125FD565F06EBB51CE53EC00F
-:10AA10006B289E57ECDFF027697C327CEBC345B88E
-:10AA2000F34628DB0460BDAFFDF6F472486D410DBE
-:10AA3000DA23BD28B713EBAD7C85AEEB25A9D7F1A2
-:10AA40001CF98B02F85FB97F23EB37611D3F867FCE
-:10AA50004C19B88EF3ED56FD7E8E2CBB1F6DFD4359
-:10AA60001949E3A68C755CFEC43F0D6A0718F2E035
-:10AA700042F85DCCE3FF82F6D0AD76E0ABC7DC7A7E
-:10AA800080AD6F7436CD3B7BE05C1E186BEFDB7ADC
-:10AA90006F0239D9FB8C5D85FDFA92675E453E3BBE
-:10AAA000FBC44B8A86729278046A279C257D7FDDE1
-:10AAB0006037AC60B63059B9D71BB3FBFAD76945DC
-:10AAC000F49A599A0FBFBF8DDFA38CFE57448F5C59
-:10AAD000272459B703F6422697A343102FCB49B733
-:10AAE000A29658D753980CEBF8F6E54077A9D6D143
-:10AAF00098BF0AF3BFD4B49E7B19DF26965F41F955
-:10AB000013FC837DEB1A155E2549F8F46C875D868E
-:10AB100038DFB329CED9FBEEEF7E45FBEF217B8AF0
-:10AB2000FD3BC7C385F8FC42F3FBAAF8BB1B82BF01
-:10AB3000260DC4E3477F492EFF8FD999FF6C050985
-:10AB4000CFCA9606EA2F8984F4E105FDE36DEE9203
-:10AB500050AE7FD42945A16AA29C5891C24FF89269
-:10AB6000D1CFD347C6833CFBE8E84F385D32BA5FAC
-:10AB7000B1FF6D45E7FA206AD60729FC547FE4ED62
-:10AB8000AD3C9CBCBD95FBFF94B4BD3372E8BB30BB
-:10AB9000FE33DD36A2D326CE744949FDABCFDA6D44
-:10ABA000D638716FC56B69B49EE47369D075E3BA2A
-:10ABB000D0ABB09FD35FB611BC4F2B07DFB7D3FC30
-:10ABC00046AF4BDB44F1D5E85B847E48A3BDA604C9
-:10ABD0003CC9816A1DFC1C72667539B391A396FD50
-:10ABE000B04D152DE3A67A3607F4D09B134EDB60EB
-:10ABF0009E6F25D8836FC9A479286DEF2D5D08AEAF
-:10AC0000D592D1B7B5FDF01A896866FD67EF7D135F
-:10AC1000C6437EEE2470BE22FDCCA9833C59B9DB2D
-:10AC200019B5D3F91C7BE28B07016F67EFB713BB34
-:10AC3000295EBC56656D9C7EE28BDDFF45F34F437C
-:10AC400065DA7FED6E5A1EECF0FD6E0CDAFF8FC7F1
-:10AC5000D2C6132A9F6B7F7EE7D5205F6A41A6D2BA
-:10AC6000F2B58F0E45BBEED410069F3A901B85754A
-:10AC700059F6F8332B408F2CFDB19B80ABE0D813F5
-:10AC8000AFDE04F0D99F7B31BEF1ECCF4F5F067C85
-:10AC900040ED67CDACC76F31BF3340DB5D0A30CBD1
-:10ACA00017CE735907FB92A59052B9B1F4E934BCA1
-:10ACB000BF632A87F556DA7B6F0FA27F45CF1671E7
-:10ACC0008F13CB063E5CDA69ED4F73303FE84AA53F
-:10ACD00077112B1FC966FCDA8DF54A1D9C4E797ED3
-:10ACE000627DA3FC384761423BACFE0A3BA94B4660
-:10ACF000FF931D4CDF2FEDFC72B4B53D9D7F4FECF3
-:10AD0000877DFF9EC0EE9790834E8C235AA6C44643
-:10AD1000A5537E7D52218B816F97F962A3FCB4BF4E
-:10AD20009F7239B9CC4561FA3D9B8F03CA034C1C15
-:10AD30003D3F86F55DFE949300BD2FFFB917CF5FB1
-:10AD4000963FF9C5A97FA3DF3F7AC28DFE92E53F0A
-:10AD5000BF03D77BB93D7613F8517A0FDAC91E5A73
-:10AD6000FEA383CFE7811DF2912D96973EC8FE7C0E
-:10AD700079979D5F6AB0CE83EE0B8AEBE878F4EDAD
-:10AD80002CFEAC9EB8826B21AE041C0740C7AF3BC3
-:10AD9000D939213FB75DCDFD499F2CD0D270FC251C
-:10ADA000CCAFB59AFB0F567F4B1BEA378D03E243BE
-:10ADB000C94442EE50EA46839C95E2DF241A85E5B9
-:10ADC000F8084C8D7292CAFCD05226F3B7D9328360
-:10ADD000A4B604EAB17822E2B9AA8FCFFE275DE2D9
-:10ADE000D5F76A43A1BD790E664F6F7386563870EA
-:10ADF0003FE3C17BA1384F2A10F427D8BCBE10D83E
-:10AE0000BC12C7FB854DB7833CEF3FCF66E727F504
-:10AE1000B2F6AA06F33FC1E5D280F9333EFB444DBA
-:10AE2000473E33E6B1B9414579B2B12180E9868622
-:10AE300062A2615C7F106189E3C35EA21309EEC95F
-:10AE40006A6CAC764F7508FC56D026F83B254F1837
-:10AE5000E9CB1EA8C3BDBFC3C3FC94924727B51E50
-:10AE6000F487219EE0BC05F0A470586E9B8D78A5F8
-:10AE7000F5F1FB7267F86EC08B2367AC454E2999DC
-:10AE800065167800DE0CBA38F0DF8D3F82F8023F9D
-:10AE90008DC6EF4500DEE05E04C0FF07F0F70CC38F
-:10AEA000DF542AA3CCF8ABB2C029F1772FC55F6677
-:10AEB0003F5F25E2A19EC7A519FC948A7FE15E0948
-:10AEC0005C1AD8D1D086A9F13D3D855ECF7532B9E7
-:10AED000564FC2782E4654E65721993AC931F99314
-:10AEE0004840C7FB4C782F1AF23DCC8F68ACAFA41A
-:10AEF000CAA7ACF24F7B15E673C70B3611E4955425
-:10AF0000FF0079C7748E26CDAE766A88E720FA7581
-:10AF10001BB97E5DDFB79E56FED8DCA061BA85F313
-:10AF2000C936CE27DB61DDC13F1714714D5B671158
-:10AF3000D49F775398EDEF6396732B7FB02B06F178
-:10AF40000E2893344C6328BF5EB34747D27AEE1283
-:10AF500012027AF1BFF6FD28CE957405C01FEAE70C
-:10AF6000F823870BFDD7B377106C4C4F1189A511CF
-:10AF70001BEC9F12F1DB183CEA807D77AAF1640597
-:10AF8000757B1EED2FEB753BCAEFCC1BBB5EABA1F7
-:10AF9000F3F0B4BA713F991564F4E80986855AD381
-:10AFA000FA65A5B0FBEE735EE976D2F5F4401C2E8F
-:10AFB000A5C71D6D239C781E64EB0A801CDCEC6722
-:10AFC0007A469B4B7BBBB4BFDEE70E667FF9CAAD0A
-:10AFD000FC6FC863755A99858E0D799B3EC34AEF05
-:10AFE00086BCEDE993B7D5B9309E8C783BF26322ED
-:10AFF000FD37DA145DA0764A23D89260DFBD2DB00C
-:10B0000078DB817200E3513EE929D803EF05ACE318
-:10B0100071D03AE517D43BDCFF699CB71F20D52DD2
-:10B02000F07E4B0BA52302EFCC50FA2118AF538CC6
-:10B030006984D20FE393C9981AF439139C2726FF29
-:10B04000B954F49CC8EE6188A073884CF7811EF057
-:10B05000331D99E200BB50B6054F80FCEAF58A5DCE
-:10B060001097B0DE33C70171D482BF1CD7FD736F58
-:10B070004DFE60E729F01208D08DEA09929325FD74
-:10B08000F77525B58CC07EF280A71BCFFBCA9DA2A9
-:10B09000C59EDCE60C5FE534C1A5D03B5FB7AFE3EE
-:10B0A000FC93DFFBFD0EE77792A39322137F1BF146
-:10B0B000A144D349B189CFD78DBC9CC039E740FEAC
-:10B0C0004E21C7F6FD63E458637E14D7CD9628372A
-:10B0D00032A97CF760AA8B2A8CFF50D33F4F403AAD
-:10B0E0005B0AF8209E3D7DF6CBD70B078E33516E61
-:10B0F000F5EB230DFD55541FDD3319E4600A7D7413
-:10B10000E48DD1DF86F8A9779E9704B3BF6E717C7A
-:10B1100023EA83DAF814A2D1F1D6B4FD00D3456D49
-:10B120001D48F7EF47D7FB303EA685EDE7DE8FDA07
-:10B13000A25201D2ED7909FCFA84B5FF7E7B2396F9
-:10B1400023E07D31F5FB7E3BAB4FCA35B4A73FE131
-:10B1500073ACD9660FC139CDFB6DB4DE20F8AC817C
-:10B16000CD5012FB14DF0180987F52371AE49CC146
-:10B17000EF7728542E011EDEB427F5B32F77CEDCEF
-:10B180000E7CBDDC196A839478D22FEA3D8A77441D
-:10B190006AF722BEC3BE6B2C7E56E6C77C87DBC532
-:10B1A000C49122DFC7EBABC9F397B77EF8DC5D141F
-:10B1B0006A2E095713D3FE5A226C7FBDE2E94AFE7C
-:10B1C0002E081B4F12FA64F66CAB1DE5D002EE0F91
-:10B1D00032E8B59F5EC23E7E2FD4424FB7C4B7E37C
-:10B1E0007A0B9B4BEF9942F1F729A523F0CB099BF2
-:10B1F000A70F053E5ABBE96BDB6EA4ED7FF6A28478
-:10B20000DF17C79D58FE83BB82F7DC08F6FAAF6CE8
-:10B2100018DFF4D98999780EFB81CDEA47A871B17E
-:10B22000FDCD5B4E962E8A6FB6D8C78B5AE62BE0C3
-:10B230007F5C14DF8ADF17C1A10CDECFF8F078A5A0
-:10B240000CE73504CF47DFDA787AC63AD46765E889
-:10B25000C7AADD624F7A9FE42DA766913BB53DAD4D
-:10B26000D82EA1F65166166FCF243F6AE370F90419
-:10B27000D6472770DF601197237DE36BB759E4C889
-:10B2800007CEE47E92FFE89BDFD7908F06CEEF32A9
-:10B29000C65F46BF3D8CEFFAE773CF9464F3E99F36
-:10B2A000C7342CFF813F79FF591CCFA71A16931082
-:10B2B000954335765ACE03FDDFDA3C19F6D9EDFE1B
-:10B2C00074C134AFDAB6A524643EA76C9FA7D498A6
-:10B2D000DAED5F07DBB39545FDEB90E52233611DA9
-:10B2E000EE73568B2EDA5FCDE6E9E3C3B8CF66F294
-:10B2F000E41D5B300FE4EAE9B65B93F277962B61CD
-:10B300007DDAF8FA50BBB7DCB43EC6BA24D63FF5B6
-:10B3100046EDE777811FE05E66D4A4C2D780752B27
-:10B32000488EB7A08BE9975354CF86116FDA93AF4D
-:10B33000015D6F71631C676AFC8D23E1C1F097C2E8
-:10B340007EA5F6CE18D710E897201E6ADB181D5C84
-:10B35000086FFDFD723AA84C3E9F9BFAE8A09EE85C
-:10B3600094614F2A17A2833B89EE18641E7D7430C6
-:10B37000E659333FDEB449433A781FEC94D103D702
-:10B38000FFA4A2FBA6C239D02609CF994EBAF4ACCD
-:10B390001B183C01E4F3495FE4EAA9E5FDF02DFB4D
-:10B3A00046FAE699FA3DDD72AB2F999FF5A654F463
-:10B3B00053A493928AFF7DF4F38E2D79FCF2726789
-:10B3C000650DF0018924F7E71AA921BFA5344FDFE5
-:10B3D000BE13F4E9494FE1E7519AFBA833BC1CE8DE
-:10B3E000E20E511B3F4FE8DF7F0EB03F1B664D7FE3
-:10B3F0007724F80BABA7BF6B437B08DB23605716A2
-:10B40000F0B808F46F0C437D90785EBAC35590F4A1
-:10B410003C767D43DD4468973874A29AE3E008B334
-:10B42000A3FE9330BF97311FC51656E15E9A229056
-:10B430006AA0739B1C6E817BBCB640E604DD84D79A
-:10B44000888BF9BF9CC78FB714D0FACEF75E5461D2
-:10B45000D076DA0FF8D71C39F22766FFB42D93C5E2
-:10B46000279222D3F742884FA0B0659F4FC73BC8B1
-:10B470003EF5A702C383EEB5333F0FD125D07BD76E
-:10B480003B89F187F6F7EF8D3810B989E5FB8DEC34
-:10B490002696CFFD972B6B987F32715DAF3FBCA195
-:10B4A0001BEC99EB0F0FC3FB74D77B46BF07E70B71
-:10B4B0003F051F3ED0BB9FE9E5C47A8F733EFDE791
-:10B4C0000E51B7D175396EEB3DEA86F17E8FBDBF67
-:10B4D00078C36F8FDBDC34FDC32B276D104F7433C3
-:10B4E00004E8D079CD239AC28CE028D69F4FBABC0D
-:10B4F0000CEE1A32C76B6E8F6E55A1BD55EC9CF7E2
-:10B5000086DFBE3213D4276D6F3DA437BF48146861
-:10B510007FDE21AD995DBFE3ED1DA6ED89FDEDF563
-:10B52000E391DF2B941D88977E3C39106F069EF0C7
-:10B5300002478505CF686F1878EEC35BDADCABC8CD
-:10B54000F8D4FC72BD67D47BEC7E221B57229E3F51
-:10B55000832CCA6FCFB8422F03DFEC75857E03E9D9
-:10B5600032476F9E5C88F70F5F05BE5C2185F3B3A1
-:10B5700046E0BDC4D143E05D98EEE4E7AB897CFAD8
-:10B5800026F00BC475F338CB9BF8FC8E7DFFB41707
-:10B59000E3289F78350FD2E552CF96EF02BFFD52D8
-:10B5A00042FBFB9343A3078D477B93FB3BCEBA8CB7
-:10B5B0007759D8FC6EE676DCCD87DC517847F3E628
-:10B5C0007AC962FFDE5CCFE23888DC3DFE3A8B1D33
-:10B5D000D9C4E31D06B603FBCEC4768CF91DCDCBD2
-:10B5E0001E07FBC3FB27291AF81F8EBCF8C9EF6B97
-:10B5F00029ECCA75E0B9EC163FA7DF4A11D7FD7EEA
-:10B600007FC85D0A7EA74DE9419DCE73D3B3A44B9D
-:10B61000A4F8393AE6F628C4216E9D2EA2CF6A5BC3
-:10B62000FC814815D42B61EF15A9DC1EDDD67DB257
-:10B630000DE8F1F46B76F4F73BBD128E6393AD3AEF
-:10B640000FECF7F73A94A4EFE39DF7C82C8E58E877
-:10B65000C178B7F924E200B971A87BCE50188F2FBA
-:10B66000485420FFD3ED92C8EC64C3CF1193999F47
-:10B670005D97191CE2A9EA34C7AB6D9C3503E32939
-:10B6800016B4BE84F7297DE5C9DF87BAC4CDEED9EB
-:10B690007ABBD3AF04FC7A6788F8B69137D82B40D1
-:10B6A000BDFCEE2A05EB478441EBE7AF51AF04BC8C
-:10B6B000427D90FFF917597FB49BC53B6DE7FBE4D2
-:10B6C0000E5BB079066DA7638B5F80F530CA85DCB1
-:10B6D000CC9E393DC3F0DFB0B8F6BC22D509EFA44B
-:10B6E000E48590B989B73C82F1B77BA01CF36F2247
-:10B6F0001E3AC63C1983F3E34DA01B609D6D8C9EE2
-:10B70000366D11D09F49F1970DFAE2BDBBEDDF8494
-:10B7100079E4B7082AECBD699A74DCF51E07A3F337
-:10B72000D67B701F08EE516837AFFD37382E6F8A11
-:10B73000F9EEF130FA78EF02F491E1667E9BBCFA03
-:10B740006EBE4F8AE13B8911C013C0A172F63EA1C3
-:10B750001CD2CC7128FDFCC3F661749E2138DFAA8F
-:10B7600099AC44C10F20B674E07BC0F32376720518
-:10B770009D5FABD01D027ED12789FC1DAED09B8082
-:10B78000A7ADDB87623CDB06319487FE9D7F55F0D9
-:10B790007CEC68E8937BE13DDDDD9315E48BA32130
-:10B7A00076BFF5FE35851DB00FF7D657E13BBF518B
-:10B7B0005541C9D2584E5E180DE7836B4455A0E53C
-:10B7C00023D5C63D0315EF314C903EBDB218CECF08
-:10B7D0008689E04B22A705F63EC8FA35552AACEB20
-:10B7E0007A355330EF5BEE7033FDF2B2BFFA0E37AD
-:10B7F000C563E0AE1D2A35E3297F668C037FA1DE99
-:10B80000A268C63D7178572483AF4B46B7185BE4F6
-:10B8100043D8B3986E91B74D637ECA1F5C1566FE20
-:10B82000453893AC40FF22FF0BE0BA667268D358EC
-:10B8300017023BD72DC2F2D04E166D27A35C8C5554
-:10B84000D076F7F843BB519FCC74209E88DCD3069A
-:10B85000788ACECC0E425CEB8E29A35E82FB551912
-:10B86000277AE7801E8DE6BAFED001726ABDA2017A
-:10B870009F67AC3975237CF7077F782BA4194DBFE0
-:10B88000BB13F481BFE74F0DF87D9662F1EF65BC05
-:10B89000FEC197909F51AD58FC84BDFEEA5D809734
-:10B8A000DD2591488DC6BE87B2FAE771606DF72C31
-:10B8B00078F7FAF43562700FCFC779ED54A39B186F
-:10B8C000DECA41AF1978DB206A5DF02EB37EB50386
-:10B8D000E9A38874A3BC1A06A7C8234CF4FAFAC6D5
-:10B8E00055102791389E1F73BE853F785F12D60A88
-:10B8F000E25194612CAEFE60597700ECF82DFEE425
-:10B90000F109673DACBE3DC53DF5331E460F201223
-:10B91000DBCA300D9542EA217A1AA4398E10C4C7C9
-:10B920001E14B53F229DEF9034581F286FA3EB776C
-:10B93000E48533E81F3C12F90DA6CF7B8A8DF662B1
-:10B9400059F03E6EF9493C1FD9AA321AA96D61F22D
-:10B95000A236D0E380F38ADA12A2EEE1F4A61B78D5
-:10B96000067F17D75735D731BC6696103C6F059FB9
-:10B9700018BC579605E528FE325BD6AEC27524DDAD
-:10B98000FA085A6E2BB40BEBD32412D66E8F03F940
-:10B990003722E17923E5F75FC379624DEB503C6FC5
-:10B9A000876BEAD05E3AEF379DB7D741DB01FFDF07
-:10B9B000E91609EFB140D80BC0DA1A4ACB489FBD4F
-:10B9C00095C5B45DAD5C5537197460C831CA1A0BA2
-:10B9D000A8BE00BC2DD0F555407F271DEA0B300EC8
-:10B9E000F74EBB06F35FB0F3A93BC06E71077A5AFE
-:10B9F000403ED44E66E34D6FA5DFD1BED17E0DE54E
-:10BA00006B5BED1AEB8FE3AF9CD319C7C3423EEEDD
-:10BA100085ED6CDCAEDC6804E8B3760DC52BE485FF
-:10BA200019DD834BF3BC887C7502E6EFD5B3B0DD3E
-:10BA3000217313F82281FE8C79D5F079D5AC61F3AE
-:10BA4000229C9FE8B062D06E4D399BE702C2EA8B20
-:10BA5000F09DB6BF90CFA7467F12D3852D764BFBC6
-:10BA6000BB8BF776E37DB612451310CFEC9DCC3C33
-:10BA70003EAFBC26D65F5EC993882F526F1A2FFA4D
-:10BA8000454D30E5ABD3CF53C6A276AE90E74062CA
-:10BA90003AF97D05CF518A765AE7757AE3E8075A75
-:10BAA000C1FF79B782E71507C5E09BF9B80F553498
-:10BAB000267F82BF990D727A615310E4F8814A861D
-:10BAC000FFD3DF2251A0879127AAD301DF234F8420
-:10BAD000795A87E7D81421429FDCA3E3A35BA7161A
-:10BAE00001E4657CC48F16831CA0EB0CF660AE7974
-:10BAF000DC747C192D59551087943939BD4AC1A77A
-:10BB00007F13F24FEC9A03EFD8661EDF752BF433E8
-:10BB10008C98E643F3477947B0FB57C7692E94AB3F
-:10BB20003F7517AC472B7F8F7E248C2C1DD3E39061
-:10BB30006650FEDE9C0EE394C98CB27E79B0EFEEC7
-:10BB40008A092057F0EE4819A6315236506E98CA2D
-:10BB50008FE1E5752149B952AF66D997EFBBFBF28A
-:10BB600031B07FDF0A76621ABCE7A77E0AF1317A2C
-:10BB70005044BC6FB5C51C2599F05EB848C07ED94D
-:10BB800056FC3B11F86EEB211204FAC8A8FEABDD9F
-:10BB9000BC8EB51E3FCE5B56C866E0FFA3634ECD9C
-:10BBA00082758A1E11F13D89AA5F7876B9C11EFAA5
-:10BBB0003D8B3FE978BE0EF5F7ED794AD2F79AC989
-:10BBC00005ECC4C4F2E923E7A01F2F7FE7767C17BA
-:10BBD000B676961CBC8296CEDC595909768C564DA9
-:10BBE000A96B281D77FB84B5C084DA6C765EA5CD81
-:10BBF00062DFB5192CDDDCB07822ECDB239DB2B31B
-:10BC0000888E77EC46F66EDDE6924F1C616A979659
-:10BC1000573EE6F816FDFE6E39D582F4FBBBD33EE7
-:10BC200071C2F9CCFDE5551980CF432D56BB8EC0AE
-:10BC3000A36A741F546A8F84BC745CADBF25884F9F
-:10BC4000C91E6BABA1B0F494072C9C01FB9B8DAD7E
-:10BC50001D73814E17146378F280F97ECEF5C9FC0E
-:10BC6000FADE59705FA94027EC1C35720F0AE58592
-:10BC70005C6414E8DD2874BC3BD9FE2422879E0353
-:10BC8000B91C29092B50C59067AD236B1E0479F6AA
-:10BC900025B7EB48DD62BC0789FC2F813DD45B9959
-:10BCA0006CDF749DDB857475BAFDDA57C13FBDA0AA
-:10BCB0009ED9FBF9ED9F0AB81ED4EE1B46DBCF2FB1
-:10BCC000C7A72AC98235114729AC4F9148340DC600
-:10BCD000D345609F10A1FAC78C07A3DDBFB5FE76E0
-:10BCE0008F1DEB5F079BE749FDF3F1F0F9E405E9F0
-:10BCF0007C92E8E939BCDFEFDDF7E9912980FF3577
-:10BD00006C8B941F795B7098C691AF5FDC38AE8501
-:10BD1000F6283E1FF1B07B0BDEF21EBC679428DFD5
-:10BD2000C19C07BEDDED3E3B81EDEFADF27400CC72
-:10BD3000E92AF17B5E82BC2AB577E13DD0D603ECDF
-:10BD40005D74D87943BE40448DBD171B35DE2FAFDF
-:10BD5000837263BD1E15E8A075CCEFCA003F5BB8C7
-:10BD6000BDB0B084E07E75614E37DA0BF39BB8BD91
-:10BD700020079B41C8BADBFD6493C97E405309B6D6
-:10BD8000D04DDC5E30F43FD7DBB581EE16D4AB4D41
-:10BD9000EC7E6A9F9DA133BD9A1F607ABDB685F681
-:10BDA000A37162AE30DB254C8F6B3BB9FDC0F570E3
-:10BDB00006EF37B385E9AB0CB0237C107EA0A35E01
-:10BDC000C6B3BCAC7EBB654809D39719AD0751AF6C
-:10BDD0007583D36508C80DA62F735F7A45073405B0
-:10BDE000E8E7362AA77FEA667234A052FB2CBDDF53
-:10BDF0003EDB20F27326C2EC438CADA7E37C9CB7FC
-:10BE0000677CDFCBC777F078FA3741BEEE8B144EF4
-:10BE1000904C7C6BDCDBCA2B67E7F479F5EC9CDAA1
-:10BE20001B5CF4A0643A7F68F1B077AE5A0CBAAAF2
-:10BE30008F05A05DBC4788725C41BFDA4678170A5F
-:10BE4000E885EFAF6E70F3778D38FDA4D227861C9E
-:10BE5000F29290AF84E2F7DDE88328AF75BA5F8293
-:10BE6000B9BD1B69CC5E02FC1EB9A61CC6BF75CA53
-:10BE7000E71877919F62BF78DED8677E45B9EE9D5F
-:10BE8000F50ADB87768B49EFC94CF3CA389F2E99A8
-:10BE9000B8019FCE087BA7D03959495AFE122F937B
-:10BEA0009B2E2F7BA760EB9407F15E634AFD2C135A
-:10BEB0005D4AA24F0D7DDB0AEB3C9590999E1B9A43
-:10BEC0007594FBD16A09E52BC17D6784FF5E8C5EAA
-:10BED000ACA0DFB0D51671C07A6C2BE7EBAA3A3A6A
-:10BEE000E05EFA575E178A0F58E78D21312A14C099
-:10BEF0003A47D552E6D7C177394ED3FDBBF99CE21C
-:10BF00004A2FF36775C99A08F189F92D8CBEB64E90
-:10BF100051701C9B266475480566F9CBF0749D9B97
-:10BF2000D1D7A629CF217D5DECF816D5DF39F55D97
-:10BF3000D339E2A97B1F2A043CF7BFCB121AF4FEC7
-:10BF4000C2A2FA97A6EE4D723ED0970FFB280FECD7
-:10BF500003A33798CF59E6F1F55DE0B5FAEF40BE9F
-:10BF6000DA707311CD06FFD281E9511FFAEF97B154
-:10BF7000F3DA5BF879ED99BDD7E2BB07A570973688
-:10BF8000C9BA7FD0607D07E2837D0F6533BF46D499
-:10BF9000625FDDF2E04FC6B2776574FE7B1A44CB78
-:10BFA000AC60EF5FA39E7E2EA8DBA5FE77CD8C77DD
-:10BFB000D82EF65DB7746A86E1BE8B54639A45EA63
-:10BFC000300D9008A6D9A40BD31CD8E7C2FB6BA4F4
-:10BFD00017538DA82231C9FD421244B88854632AF0
-:10BFE000C3BA65F49F4BC89D0E8CBF80F30BE07BFA
-:10BFF000E39CC238DFAFF6D644BC49CE2B567B4318
-:10C00000DBBDA8576228B7E773117EE2C763BBE0C8
-:10C010007ECFEA2DEC7E8921D7715F43DBFF513A59
-:10C02000D303FA0E01E5D73AF7D597211E5B6D1FB2
-:10C0300099CF1B88C35104BF1B63B43B9FFB17E61A
-:10C0400073FD07EE6D76FF2E88F77FE6839FC19420
-:10C050004FFAF2D97D6AA31DD13D6DD460E77BA66E
-:10C06000FA188F5C9360FF5F506F27C00B12EBFFD5
-:10C07000850E28ABDF0FF7A3CBB43C76CEC4F436E5
-:10C0800025240DEBB5D8DFC67D586466C88C9713A0
-:10C090009CFE0D7DB220C1AF9F982E90395F24B4D5
-:10C0A00043359F1FEECDE0DB2626BE36DEBF357E54
-:10C0B0005FEB96505819C6AA05601D553EEE0869FB
-:10C0C000AF1A46D3F70136F9F35FF4857FE735C53C
-:10C0D00043A9A13AD1FCFED222CE8733A5D64A90FD
-:10C0E0006FA7C32408FB875B48DD56B0C7C82B1277
-:10C0F000CAB7E174DCF0BB3FB970A0918EB0AED08E
-:10C10000F4E306762FE754C2FBD51FF277914ADBA2
-:10C11000EEB81AE8E00C7FB7DAE07FA3DFD22EF7A3
-:10C120003CD0FBA55DD36BA15C69A71D7FE7A9F897
-:10C13000D0C66AF00BC13B2D2EDA4F0EEDCF910E1B
-:10C140007284A0BEFDB0D5155D47C7F9619B8472AE
-:10C15000F95C8988EF8DC07397121F5F5A3AB4F368
-:10C160005F37811D7286CB11E3DDC70F2B35DC1FD6
-:10C170003F7B608300F7123E9CA7E1BC3F1CD69535
-:10C18000974EF193E363F7738AF6DB6385741C4B78
-:10C190001EF97D610DC8BFC2C89264E7CC437C4CD8
-:10C1A000FE7DF804C178B80F9DFC778D1C5D3EB311
-:10C1B0009F35CD2758E4D6875EFEFB48391728C740
-:10C1C000E3CB89A7CBC7F8BECB07E751F7B87F8C85
-:10C1D000F7D74E3DC1CE299EBDB7360FFC51C37D6A
-:10C1E0001A3BF73EF038C68DC33C601F4DC7A7C150
-:10C1F000F8EE71BF7906FC0FB41EDECF30EA9D3A2F
-:10C2000050CBCAB7D1F23EC43BF195013D30BC934F
-:10C21000FD4C4E18F6E3D26816FEEE427FBE88F95A
-:10C22000304427C57FE9FE6BF05CABD497CEE8596C
-:10C23000ED1A3B07C71FC983791C981ECE033FDE4A
-:10C2400029E377A0E4481EE0A1DA1B2EF599E6FF6A
-:10C25000C1DB4FA17C2F16EBDEBA0BE8F231F63BC7
-:10C260002477BCBE5D34CB8F69F0837893607E2BDE
-:10C270007C701E75AAEFBD9C088BF739CCDE635D20
-:10C28000CA79EF5407DD3F517C7CB0FF07987FAA45
-:10C29000EF3D9B2E8C27FB60FFB174486B783C3FD1
-:10C2A000895E8BFC45F1D2E248A2AFFAEE4545D952
-:10C2B0007DB7B3027F87F43E036F75CA1CCB791537
-:10C2C000E3EF9CF682E3682F4793DF934BD4F78923
-:10C2D000EFCA5EE81EF049CEA7EFF277D1567BC3D6
-:10C2E000D7FB505F58F548CDE6E57980E71AB8539B
-:10C2F00087710ED3AF80FD36DE3761EFCAC6104FAF
-:10C300007DEFC64EBC02E21C4FF9195CE79BBD41B4
-:10C31000E77864EFD256B2FA052CBF95E7FFCA5B07
-:10C32000BD98F54F04F6BB46363FFC3E8521FF52D3
-:10C33000CFDFFAFB14F7834C1E82EDADF60DC16C16
-:10C3400081CDE7EF6BCF90377F773B8E7F6C3B865D
-:10C350001C06BE84903D120C8EFD47E0EF6FAD4F82
-:10C36000E6E65BE4F917F78E688673A0730182F145
-:10C37000CFF6D6B504F4D2C29DDB93FEBE5D1FCCD2
-:10C38000E349941194CF4CFC1CF3313B3DC6E521AD
-:10C39000FCC1F9CC2842F87B1794A6B230E406F72A
-:10C3A0007FA3F97BEFC52482F6D558D2856909E9C8
-:10C3B000C6743CE9C5148F494780AB2F28F1777BC1
-:10C3C0002B60F2CB1CE1FB2154F7AFF6F033404F6A
-:10C3D000F07EAF20815DB4622A8CFFA84F357E07C6
-:10C3E0009424FCAE5AFFEF816860D7CC0E0C66D760
-:10C3F0001055FEA82F7EA390BDFFCBF821D5EFC42A
-:10C4000025FCFE24BF476CE06139E9C2388867DB50
-:10C4100057BF3086E27FC97E2FEA8351ED4DF83B4E
-:10C42000604B487716DC2F1DC5DF93206DEC1D0F88
-:10C43000E39D88316D76CBBB1ECB137E876829FFC9
-:10C44000DDB0A509DF8DFB9B9BE143923882C4FBE5
-:10C450009FA77D29DE612D49FE7B3089F73FF77765
-:10C460008918DFB31AE285847EB937666F9DDD4A8D
-:10C470005F5D971599DE7B6A14826C3FED7585F6DA
-:10C480000903FB19AB323BEE8020248D23BB268DA4
-:10C49000EF174913B98AB6D3B84C5661BFD918758E
-:10C4A000E13968A3CAF685C3BD550ED8A713BFA846
-:10C4B000C2FD94CBA569185FAE2C9727C2B9E7F1EE
-:10C4C0003D4BBAE1FE426340463FED703F3B0725DE
-:10C4D000C3447C1FA0497DCC3F1FD6C9C3CE19736E
-:10C4E0005582BF637AA4E37611E046BA6D190AFD5E
-:10C4F00008E16EBC77334C26FCFC75F6044A7FF9E4
-:10C500009C1E64D28AF78F672C7FD7097A3D9FAF34
-:10C51000FB94B4029C87CCD77377FD493FD0E9F3F5
-:10C520001DCD2F5F4EDBB345658C6B2DFEB2F10F39
-:10C5300097D3FE7A3B148C6735F090B746B6DC9FF4
-:10C54000CDB9CD0A2B09F7886562CAA7F038DE3F5E
-:10C550003CB81A33C755658698B350F5E0FDE04BFB
-:10C56000D304661773B814608A924E5BA4CA45C799
-:10C57000D9F986807E87A31D8BF2314EFF27E17C9F
-:10C58000A06F831E12D7EF4BB087908F7427BF1F09
-:10C59000EC84C3BA44FA696A2023C11FED881E7770
-:10C5A0008D83753C61C3F7A4D673FB5BF6B0F87757
-:10C5B000835E12D3F50974B7FECB6B91EE7A29DD59
-:10C5C000257B17CEA827AB1ADA09B61C1204F6B0E1
-:10C5D000657667ABB4DEB8A794A087A2ECF2474BB0
-:10C5E000D2C09E1977EC7AF65E1FC517BEF758AF1A
-:10C5F0008C847DBFBD3E73A49C01E53C488F9F7831
-:10C60000D8F98F5CEF0E427E6347454033D1757396
-:10C61000833A521E09EFA53A46C2EF2335A7F89D8B
-:10C62000E65CBF580DFE2585EFFF97A4B1F12E49BA
-:10C6300073637A0B87EF93F53930FEFB28FD40BC1E
-:10C64000C091DB18FDAE1EE6C07BCFAB9F1F3174DF
-:10C65000B038A0071B0223016FEDB7D5A0DFA3728E
-:10C66000D571E715C0E75E870AF428F946DD330D7A
-:10C67000E8FD051BDEFB6AF45668F34DED49BEC9C3
-:10C68000E85792443D1B36450D697FB8421E06F4BB
-:10C69000A2EF024DB461DB11067BF56C81E66FDB26
-:10C6A000F62C8387E8BB049A7FCFB6E7199CAB676B
-:10C6B000C32F80DCBFED570C1EA9EF02F8A16D2F30
-:10C6C00031186C0B6AC73CBAEDB75780EFA7D1168B
-:10C6D0009C0BFE9D1FD3F197D8E0BD5A961EE478BF
-:10C6E00031F21F83EF14DF87789A98FF24AFF77435
-:10C6F0008AFC7FE7F98753B4FF335E2F96A2FE5181
-:10C700005EEF788AFACFF17A2752E4BFC0F35F4C2C
-:10C71000D1FEAF79BDEE14F55FE6F55E4951FF77C6
-:10C72000BCDE6B29F2FFC0F35F4F68FF4D5EBE8732
-:10C730007FCFF1B6FC41A77497D3C15EF82CF6B653
-:10C74000A0FDDE5E578EF4DF3889D91906BDE740BB
-:10C75000BC26C85B95C5558D52D93EEE9769CCDE97
-:10C76000A85C55B40DE86EF5AF24D4A7548FE0EF64
-:10C77000F0EAAB58DCCBEAE7D97D90D5AB647C27F7
-:10C78000CDA047A3BE31FEDD7C7C4D7CBCC7D20A68
-:10C79000F9794B60E46C73BCA76A851D949F206493
-:10C7A000A72993E997E255558ED1A03FA87E01B9FC
-:10C7B000B9DEA3C4E01EFD7A55C6FCA6CC2A15F24C
-:10C7C000755546FDB33EB3CA311FFD39E9E89FC830
-:10C7D000E7717B4DAA8CF7F865FF0CCCBFFCD1D973
-:10C7E0002AC8D126D2EBAF84F9AD91F1BCF6485DF1
-:10C7F000157ECFF77FE607F9FCAC9FE1FDB8F7396E
-:10C8000027BCE72A7F4F447D81F8A3FD16AE11A314
-:10C810001A2D725C5D2D02FC4013D357F4CF3BA15F
-:10C8200082C771D0BFCEDB2B5E80F89DC62D721003
-:10C83000CE73E04F36E98322FE7BA54355B66F34B5
-:10C84000F4D57DDC8FAB071C188757249380F977CC
-:10C850002C87AAFC3C8DBF63362262D54F052DD6AE
-:10C86000776CF213F453A2BECAADA3F2D154DE1E0C
-:10C87000502DB0A0B2F72CFE17044CD03900800028
-:10C88000000000001F8B080000000000000BDD7D91
-:10C890000B7854D5D5E83E67CE3C3349669299640F
-:10C8A00026CF49801020C0044204449D848011B1E9
-:10C8B0000E0F15D4E2846780BCA0A858E9C7840491
-:10C8C0000C1435FE46047EA003A28516ECD0A2020D
-:10C8D000063B2022FEC53658DB8B8FDA11B9883C27
-:10C8E000C747953ED4BBD7DA7B27734E12C5B6F740
-:10C8F000FFEF77D3CF1EF6D98FB3F65A6BAFB5F6ED
-:10C900005A6BEF215EE2FD5A47C8E23D8B6FB410CF
-:10C9100042C6FFA228395A44C85253D210924CC87A
-:10C92000D7F07703214DCBC3D7F7D513B269B9A997
-:10C930009F429F4D5F0E9F464A0889255A7CDB2403
-:10C9400042562DB7F553FA75B51F68A32F9D846C19
-:10C9500056829389833E430A69CC23E4D0129940DE
-:10C9600079B1DB1432D2268B5FFBFD4DFDA1BC48B3
-:10C97000F6124F577FEDF399E5AE7EF0FDDF50984C
-:10C98000605C7D40EA777A38FDB71270F91309E9E7
-:10C99000D3AA9C8A9A08FE7D4DFFCB6BA1E5C2AE5F
-:10C9A000B25EEFB7D9AC84E492B876141E4553D684
-:10C9B0003BDFB4078A607C05C7D7C291DD40E71F23
-:10C9C00037AED165539557490D85A40F7D52580157
-:10C9D0003F41A71C7A9ACE336BE983A34FA71292EB
-:10C9E00079D4D20C7825AD4F129246880EBE4DE711
-:10C9F000AD483E0FA17468CE2BF64AF479EC590B82
-:10CA0000C353B615F16490BCE937D3A751F6DB6088
-:10CA10007CFAE783F11FCAB66C5D9307C58009F005
-:10CA200090B5830E98418BC19CD53E85D289A29B3F
-:10CA30008C86FA375A7C745E3BA4CE722594C3214F
-:10CA4000036B4F4804FE6F8F2CF17AE2535C84EC49
-:10CA500096245E5F54599145DB2BB6418A9790B975
-:10CA6000AD435BF4D741BD2CFAFBC8483A3FF81EF2
-:10CA70002F035E7E7E84D707AF6BA9E84BC737884C
-:10CA8000EF9320B4DF23CBAC1C2C6D81F17797F3AF
-:10CA9000FE41CF6ADF1884E7669D9D9025B6B216E9
-:10CAA000ABBB0BDE95F61B5B1AE9FC2E7AA2497430
-:10CAB0001AA476EBE93442875A352DE0073C12E29E
-:10CAC00025FEC1849C9528724774D14FBFB72C981E
-:10CAD000495F5D3EFAB7A422FAACD7458F2650FCD9
-:10CAE000D5EE0B98F4F914CF7A5F3033AFAB5FED2E
-:10CAF000DE492440F9A6BEBD189F3DF43BA6C8FF01
-:10CB0000543F93E12ABE7731F246DD2E5A55AB0BE6
-:10CB1000B458FB607BC2E8DFF3FC44FF8BBBDEB89C
-:10CB20001DBE77C9134D9B007C19A178E9A19F68B0
-:10CB30005FB7AF8C00DF5FB1F89A6CF4FD5D76B63D
-:10CB4000CE88D2E085F66153ABCD4BEBCDFA56BF24
-:10CB500097B6A7A40CC923BB9EAB6C7D713CED7B43
-:10CB6000EDFA099B48EA44CAD7C11AC5FB34817261
-:10CB70003061082DAFAD55863752905614FF71586D
-:10CB800011949FB312232D37D51C7115C13AF21A97
-:10CB900008152F64EDA8B01BD67173AD61DA76E08D
-:10CBA000DFC862D79CA2AEF157DAF508F7EA57E87A
-:10CBB0003A1B4A9FFAB05D82FEFD1402EBD06CA7CF
-:10CBC00074A665B33B8504F3A09D752DACC7D5FA5B
-:10CBD000406539B473CBE469FA5D73BFA995E51478
-:10CBE0000E975396740847C5C9B9B4BEC96600C943
-:10CBF00046DEB0CFDC0578FAB9E26D8075F873AB2C
-:10CC0000D516A4155436FA60DD2AFD1C21281B75A3
-:10CC1000A4214CE1CB2C26FEB0B50BCE376094118D
-:10CC2000F03420BC6BCDE14965741CCB62D916A4ED
-:10CC3000DF5B5DBBAE633CFDCE7FD63E7FA291BE87
-:10CC40005F93A61080C3EA50228624CAC7B7501843
-:10CC500029DCBB1BFD36909F31A742B6D17A4B5FD2
-:10CC600003F1C4C9416B112DC7C9A75487E233D35F
-:10CC7000FE317BE0651BFDEEF0D7DF34417FD70846
-:10CC80005986651356189D934AD4E3D8C6A8C74958
-:10CC9000A950D73B26AAEBD3A6AAEB5D77ABCB195D
-:10CCA000B3D5E58982DFA8CCB196D279B02A628962
-:10CCB0007EBC9C24217EDE02FC5B0A642FE0C75C04
-:10CCC000BBFDEC5C5A9F09F284C24F8690D0D3948E
-:10CCD0009E87737EE889523C1B531A3CF6A2EEF8FD
-:10CCE000C8CC36DD0CF4B2F6556C84B6B7BEFBD1B9
-:10CCF0009730BE95C4B5CB03FCF84E037DE1CF451C
-:10CD0000E149847F7800DF0D7FFE11E8BD133A2FE3
-:10CD1000E03BB356C1EF3F3CD513D2E5B1E684B654
-:10CD20004FE2ED934C6B3B7443E8F3DDD58B7449D4
-:10CD3000DDF19A461A245897943F505F902A82FA60
-:10CD4000E221995403DFD0E54A603C1B74A072E6EF
-:10CD5000C61403F2CDDFB97EA59C26437D9A8D8D46
-:10CD60006970CF36C37A5E7994F1FF4A031BA773CB
-:10CD70003C0F7E145510C849A35DC6F1C438EB6C56
-:10CD8000BC0D2F3BEDACBCE748CACDB02ED74D4D06
-:10CD900019067C62944900C64BCE32F906D0F99947
-:10CDA0005F3304253A68B2428EE853687B0BB9C7FB
-:10CDB0004FE1D870CC12D4D1F7E639FF61A34826F1
-:10CDC000857606F79E15DEDF831C8855298847B3D4
-:10CDD000B3D536AC88CD2148E14B817F50F958D688
-:10CDE000AFCD06F43497B5A2FE3617B7B6029E361D
-:10CDF0004C94D19E48992D233F9BB3C327FAD2F779
-:10CE0000FA39B20DC64BA18ADD4007793CABD5EFAC
-:10CE1000877129CEE552C62A302ECE907E2795E323
-:10CE2000D5E1D87BBF44C74985F186B0F680273B62
-:10CE3000C793D7EE41B81D7CDCD4BEB4FD10364E8E
-:10CE40007369D738828E1B2A4908E013DF15E37413
-:10CE50008E4F7C12C855FD6F28DE289DA41C13023E
-:10CE6000B772010919F3003FFE86ADB8AEAD641B81
-:10CE7000AC17475639F051C6B18D93E521D0CF821A
-:10CE8000DFD1CF2121E0E30C8598AE4F01FBC58FA8
-:10CE900078D4AE57F791D629748D74D245BB7EDD18
-:10CEA0000A69D1A5745FC76E87A3BC60480FEB59B0
-:10CEB000B35EDCC762F702D36BD7F596844BC580AF
-:10CEC0001712DF5EF7ED659D2E7C623C102B9DEA0C
-:10CED000098AFA1CCDF708F9CA086589C89EAFFB14
-:10CEE00080DCB7F3F540F5155DAC7B86D9C65A6199
-:10CEF0009D2E22C85FE52FACBDF33774BCCFFB1964
-:10CF00006CA057B28FB576807E24FB02FD810E9B0C
-:10CF100094C04F1268FDA693E904E4F66A339906BB
-:10CF2000FCAD703ED7EA97957CDD7840CFB9FEF92D
-:10CF3000A7B007C37DD306D9E8DA5BF9D8E1632649
-:10CF4000E77FA39D45FAA39D9575A4A3D10ADF6F42
-:10CF50002D6F3151FC9A5F67ED9B6939A800FE6A1D
-:10CF600072611D1ECE9E8B7852DE3612E0D3C13A1E
-:10CF70005F08CAE41D3301F9BBE3B9BBAB3D207FB9
-:10CF8000D22678400EADE3EBBDCD2EF5882FC5E05F
-:10CF90000B803DA17DFF08E017E9E93F5B45E938DB
-:10CFA000F8290359432B0BE5992D79B02E5653F9E7
-:10CFB0004B6B67EA3C753F96BAE8F30B73D9763B47
-:10CFC000EC3B969B48C048E775452201BA38B31D33
-:10CFD0006F9481FCC9211109F46C4E03357881AF3F
-:10CFE000965848208EDFB3AE28D8FE1766DF763B12
-:10CFF00097FF262A07F4EC9FE4E7297E52E560328A
-:10D000000AEC17FD2ECBFB203788A3C2D7B9DFC8A7
-:10D0100007FEA57A9F7E6F0F9FBF9EE2503F8CFE5A
-:10D02000679523C621DDDB3FCFF1A398AC11909724
-:10D030008AF5F849942F36E5427C3B5388E91B5228
-:10D040004342FD2486172CFFC086E54C2A7F8DC302
-:10D05000D0EE0F1A01CE24B6FF203E9FC79106EBFB
-:10D06000852092B34CA4C544DB21B7D3F5E6261D39
-:10D0700066B49B8F100FAC078A31FB9904145904D6
-:10D08000F0BA8990CAF875209E0536462765A90E24
-:10D09000F74B835E36233CFA061232833D04B051CF
-:10D0A0007C2B4B484881FDD65203B62BB079B09FFC
-:10D0B0008134A03DBBFBCBF732404E5B8E527B6C84
-:10D0C00028D059463965B1A8D71F218D88A7D39C90
-:10D0D0003F362FB7219D3BF7678137399DA38DA040
-:10D0E0002F7296A4A8E82BDA655DC92481E1F1E3EB
-:10D0F0008670DCACBE47245204F53958BF79B9E7D5
-:10D100005BC6CFEF657C37F251EFE36761FDE6C8A0
-:10D110009BF6EF51546C8A1DB1FB3D5DF6B516CF01
-:10D12000594BD47279E83E7559E0C5ACF7392651B0
-:10D130009C9BEF95BD5BE978D79C54B7ABCCFB03C8
-:10D14000EE6FBBDA471C53A03DDD7F6FA56FAF3D8F
-:10D15000AB6EEF2F7BC50EEBB8AB3D83EF862BEAB2
-:10D16000765AFA68E1A570396F8B836BACC9A8AAAF
-:10D170009F56D50D2EE71D7170DDE852B70F34F6BE
-:10D180000CD7CD85C66F844BB4BB75E4D5B5D3CE73
-:10D19000634AA5B117BCB3F6774CBBBA71EFAAFED0
-:10D1A000E676F72CD57E2788FC7EB3E4BB26853E49
-:10D1B00067C22BB017AD16B47BB5FCB29DEBA7EBE5
-:10D1C000C19EA34F7FA2EF7AE83706D61D2D1B76AE
-:10D1D000FEF14E902FC79E1D980E723D13F41CE277
-:10D1E00093F915F6D4B8D0AF3095AF53AA4F9A4102
-:10D1F0005EECD941FB2531B8E2EDA7D41AB6AFB049
-:10D200009118AE67612FA5109BC4F6E3CCDEE9ED63
-:10D210003BDAF11BED0CEE594BC7920FE83A7CDE7E
-:10D22000602B53607FB645427B6056854F9748F927
-:10D2300063748B847EA3590FFC6038C89551A73D59
-:10D24000FBA2F4FDAC90DD0B9FADEB20BE10E5AB77
-:10D2500074DDA2E21FD1E71387A9FDC3CB8B80DF6A
-:10D26000AC3E0FEC37AA00223ACE057D43B10DE467
-:10D27000E6F7AD3E909B55537D6FE17CFF41AD12CB
-:10D28000DA6E0E9B3A79A16D92C143ED8CAABB3D3B
-:10D2900023C1EEA90A9B7DF83411C542E75145ED43
-:10D2A0003178A61B886286A78598E059BA82D95F33
-:10D2B0004923FD862AFAFDAAF69FFE05FACD5322E0
-:10D2C00087983D19C27957B5BFF657B0D7E6F8FC35
-:10D2D000069017837618984DCAF96170585D0679E3
-:10D2E000105F2E8EA8CBC38FA9CB7F4A61F83D205B
-:10D2F0008506017D0E500507FBE2E06E23EA8BC335
-:10D30000078D489F85E72D5BC1FF3476A115E5FAAF
-:10D31000F99F99D11F75400E3F0BE5E0B309B8AFF7
-:10D320003EF4F68152899617FC225186FA17BFD433
-:10D33000219E613A7AFA7EE1B303B6AEA1EF170EF1
-:10D340000F97DAE8FBE70712D201F54A6808CCEF3D
-:10D35000F9AF74387E6CA731B48DF2C3F9FD3F7D0F
-:10D36000F641FAFDF33B3353244A976B411FD076C5
-:10D37000A39F3259609F31FAFCAE3E202F16EE304B
-:10D38000AAE6B53545E2FB194F12F05B6FFEC453B8
-:10D39000AB7F8AFD0BCF9E447E3BA00FCA1698FF41
-:10D3A0006AC65FDAF63B52D87A127040BF3C4A9F99
-:10D3B000CB1F59EE013F5AFFF56AFC0E08A9CB615D
-:10D3C0000ED74C12F73E0FC6CB5FE5023B752B41E3
-:10D3D0007BA6F0ECBB77E6811D6D64F683168EFDAF
-:10D3E0001C8E9FFD8C8EC3E4838ED9CF74C6743D92
-:10D3F0002EE47CFCA2C4EC57FAB72493F2ED425021
-:10D40000FCF95DEF176AE010E3DFCBC777F07D75BD
-:10D41000EC751DD2E3DCF2EAE1A7FB7587E7CCF2FD
-:10D42000860115FAAEF2DCF58B8EBA69BF9A3D4ED5
-:10D43000DC278AF7353B5F4EBB8BBEBFB043F18222
-:10D44000E95A33FD99474643BB9DBA30C00BF53EC0
-:10D450003ADF0BE15792A0DDDC4DF661BA383ACCE9
-:10D460005B7FEF808A3879F85DD78358BF357C7F42
-:10D47000FBC2C88EF199C0DFEB252F345B18BE6D5F
-:10D48000CA2D60AB6CD279FBD1FA5285F875C370A6
-:10D49000EB3D159E357B9E3B9A41EBEB0F8E28852D
-:10D4A00079AD91FD370F06FEDFA2473F96162F9FFD
-:10D4B000707AD3FE1199F65F73BBB53A64C5718F6C
-:10D4C00040F970E1361DF8D993CE52F9C4DE9F942D
-:10D4D000E99A3CDBBE7208F8130FE8AD2DC0E707F0
-:10D4E00012191D82BB7528E74984CD6334F71B2FC1
-:10D4F000FC539B41A1CFB367572495B17584F205C6
-:10D5000084B283CEAFFAA9C1B8EEE6AD57AF13D15E
-:10D510004EC03B3FA4AED7F2474AAA5857A4309E0C
-:10D52000CFB4ED5227060DB0AE6A9652791C67FF54
-:10D53000D49C6E3580DDA4FD0E588044D05587FC08
-:10D54000493C385F339B2F35594D74BEE7E05FCCC3
-:10D55000EF2DC1BE7C818453240B07920A0FC5E7CF
-:10D56000C2C9A4129E07A4C8233A2ECFD0FFBE3B47
-:10D5700001E5D9055BF499FF04FEDB95ED0DD2AA18
-:10D580000CEE97BBE08924A5D0E7655817C07F361D
-:10D59000565ED04EE5395DDFE72F1A50AE37865F15
-:10D5A0004E027A5D78D62CCB942EE7F7A496833F73
-:10D5B000E742F8374930AF73E1D472F0CBF5266F0C
-:10D5C000B4724AE8F3F7E19FA3A89D96EA1B960A76
-:10D5D000FB9DE65430C6497A6A4371430FEB5FF412
-:10D5E00073181A8A3D2037BE6FF5C2FABC21D5C325
-:10D5F000F486C4C6833F1FADFFE458EA36A0FFB1EE
-:10D600004305C9A0E73F219E6490BFB739FDE5A956
-:10D61000B4BDABBCC3A703FFDF04E26DA27D3ED067
-:10D6200079EFB3513CCF2654EFC0B32460407F491B
-:10D63000B313E19AA5908842F97416E8C5215846BB
-:10D640003CCFDA24859A281CB3D7AAE739B7CDD8BE
-:10D65000455FFADF7C4205232CA04D71EDE8F8F31D
-:10D6600041FF51FC2D309148021D77C17675BF8571
-:10D670002482F0D4ECFADAD8131EFFC2F1789BD3DF
-:10D680007757AA4A7EE9517E2D24FEEBE1BB0BB908
-:10D690009E9D633C8470D43FF0C080D9D46EB8BCEA
-:10D6A000F4C101B353C10FC8FA91F512F2DFC20AF7
-:10D6B00012C9A6702D6C972283C10E7893D1478C26
-:10D6C0004FB6B07677723B650EC507E8FDD1BBA4B7
-:10D6D0006022DDC7CC31D12D18C80F3E2FA84FA630
-:10D6E000E56AD28AF3A9255184E37E4E3F8848013A
-:10D6F0003EFFF226A3DBE8EAAD3A00EAD8A1528C5D
-:10D70000CB7D4ABC483F6A4F10734A77FE007CFBD2
-:10D71000E2F053BD495D26DBE3CAF9804F5A8EC360
-:10D7200073DDDEAF8DBE1EF0FB44A73E090D9834BD
-:10D730009874B357DFE3F87FE2B6B96E58FF8F8273
-:10D74000FD96C1071809F292087F44C444C7B70C7C
-:10D75000272AFF04B58BB0DCF6F86B37ADCF226417
-:10D760009D3E807EFE593AFF5108497DE60CAC078C
-:10D77000BACE927D390ACA015F01EE5397327A3CE4
-:10D7800039AC6140430FFB5301FF3A291C91411E04
-:10D79000EC67FA3DB124A60FC4ADAF5F72F9967C79
-:10D7A000387A3413F8E63909FDE91B24D22C513CB0
-:10D7B000BB2859400F6C90DE3F0A7A63C34D1ED2DE
-:10D7C00044EB4BF64E5AF40AEE712D5E884FD4EEC0
-:10D7D0002DD3D55A71FECCCE4C68D82AD3FAF47B1F
-:10D7E0000A87C1FAA0F3BE67327DFF02A7B7DBCA82
-:10D7F000F8C1B52298B718FCA987FD8B5E81753DED
-:10D80000D8827EAB748AABC4147CB680FDE8228DCE
-:10D8100012B45BE594901EABAAC8B45F1621D7285A
-:10D82000C929EC79923E258534831F365DA1F628FF
-:10D830007BDF0CDF792289C1E59475F74C027B7898
-:10D84000182BA72C937CDB90F91F437CA51B492543
-:10D85000CC1BDE83FD4CC1F0EDC1FA10C29D3EB67B
-:10D86000A118E048EFC39E0E43240BC6392EF8A43E
-:10D87000DD2D839C5EC2F5ED923D65E929B4FFF193
-:10D880000B2605E4E77197B0FF2256B0FF48DF4250
-:10D89000D69EEBB525C563D381EF1D39EA7697F5A2
-:10D8A000BEE4E1A01F4EE8304EF399D5976CA7ED8A
-:10D8B000AE35B07968E97F96D3B5FE8A444271FBF4
-:10D8C000FDFA699FA35D5D7F4551BDBFB0DC444259
-:10D8D00071FBFD9AEAC3E3A15D2DE95805FC581BD5
-:10D8E0004E20A1B8F571ADA5E7EF8A75517F454788
-:10D8F00082C391EDB3C02F795C1F5B3507F8F0A0B0
-:10D9000084FEA37ABA8F0EC6C375259504537B8215
-:10D91000334DFD9ECE4755DEF705B62323A349F0D0
-:10D920009D4BB668929DCF0FDA097D77392407F5B4
-:10D9300043312EC8F41EF875ACCCAE9D04F455628C
-:10D94000499313BBC615F5305E4ADC3C2F4D33902E
-:10D9500008D22586DF05BC05FB13B2B1FD63830742
-:10D96000F47FFB21C49BE09778FC05E3E3444D1D65
-:10D970001199CA8A7C876D4DD100CA7A87855C4827
-:10D9800059037EC9349DAC921309259D7203C5D4F9
-:10D990001310B5423993BAA6624C7C99B5EFEAEF01
-:10D9A00098007ECF9222D6BFC8E1FCAF157DE17D05
-:10D9B0002B93BB4A2CC79F18573669CA565A1E1C50
-:10D9C00057B669EA1D9A7A97A69CC5DA5F488CE437
-:10D9D000E8BC54DF3BDC13142A2F2FB82333E80EA6
-:10D9E00096AC6DCA9C5041E5586D09D3C775ED9250
-:10D9F000177D751C7F755E66275ABD51C3AC22C06A
-:10DA000043C751902B35FB249B44D78135BC2782DB
-:10DA100065E8E789EB1796B05F4DF87DECD7EBF83A
-:10DA20008532AEF33585A758BBF087A8F757355731
-:10DA3000613C5DC48B75C4EFCB94BAE2C542BE5E57
-:10DA400072FB5E96195FDBE2F74FF5306E9C9F46E6
-:10DA5000B47F6770FB1FC0AC4858F27123D8AF7F0A
-:10DA6000AAFD7004D873EF40935120AF4303E0BB8D
-:10DA70001B496000E8C9EFD7F63B24D376EFE9A352
-:10DA80009B2126769FA318F1F75E62345BA2326673
-:10DA900069DBB5ACEC8C6E067CFEB66D0C2B674773
-:10DAA000B3655A5EE698C7CAFDA29BA1BCBD6DF2E4
-:10DAB0000485E2FBBDC1D16C1DED9F1F9C32A1828C
-:10DAC000D63F6DEB793DD73A981C11F0FD57BEAFAC
-:10DAD000DA01F3A961FA6733B5374D545ECE587059
-:10DAE0006EF7D3140F337E988072ECE90B53263017
-:10DAF0007B3CE8574AC1DFCAFE503FA29C57D03E4C
-:10DB000071834E4CE9A247624E8707F5C7C0863D38
-:10DB10006067A4CF2842FDE14DF5FD0EBE2B9EF7B8
-:10DB200067B0E7EF1C3626B77532C69FD31F4C444B
-:10DB30007BEC51339B0F5D37485F2BA7C70A07F378
-:10DB40004BAF70303FEAF4D47138CEDB926F8389EB
-:10DB5000E2FD6D3D099A41CECEB7A0FD7CD7562A95
-:10DB60003792C18FCFE06E7BCC1D82F8F95D12F148
-:10DB7000835C11F2A3CDEE73A7C4ED43DA8A69D9B1
-:10DB8000DAB5EF6C9BE4735B1CF04C9321CE22E47E
-:10DB9000525B1EEB27F4517A13FB4EFAA303B6C176
-:10DBA0003C1214E62F9A33AD605B23DA03937FE7D0
-:10DBB000007BD9E77383DFE1F4FC7C19FC48823EEB
-:10DBC000E7F37D9BA0FE4EEE87177412F4FC1D9FB9
-:10DBD000F72C1DB527E87C8F3B03381EB52F8670C8
-:10DBE0007F15DA17BF03DD1E875FA24447C0FBFF26
-:10DBF0008FF07408E8FEAFE2A976299517F255C8B0
-:10DC00000B8EBF7552449FCEE405EE9FE13DE89D2B
-:10DC1000CDA9813FC0F8E2FB331EAC457B52C095D5
-:10DC200070FF0B957790EEEB4C6BEFFD19E81567E5
-:10DC3000977A85DF917FE7BDB74D186778CF10469B
-:10DC4000B9F91EDDFF34827CE171F2D21F2E3C0E49
-:10DC5000FB3F31EE38A70EC75B2DF9DC30BFD59402
-:10DC6000EE26807F9201ED7FA157DBECA10D90A7FE
-:10DC7000D0765B16E6295C262C1F24B83401DB5DC8
-:10DC80002B9F22E0C78C8DB2619C9AF209D6B74DCA
-:10DC90002FC07C11CA0F4133D4537E82BCBAB66206
-:10DCA0003A21186FFA40AC87FD31EE6BA79B70BC30
-:10DCB0001EF884F985FBB37C88B63CCE87F3F391DC
-:10DCC0000FD39A98FF9128BE2193E2F47C9E93F99A
-:10DCD0007D124AA2CFFD2FE0F9B566B46741C76255
-:10DCE0000CA7351DC7A3F4B738991F00F96CF623AC
-:10DCF000893CFFCC5B0A787D2891F1E526338B2F98
-:10DD00006DA2F633CA45CEBF22EF2DC0EDBC68B57B
-:10DD10009C04F682CBD9E95FF0C17E1FFDDBB47EA7
-:10DD200066547A1FF66B3383BA8811F65F2DE37C55
-:10DD3000D1B8FD0BFC417CEE1E2E57C97A827EBF06
-:10DD40007BA05F128C6F498278E43DD01FFCABCB87
-:10DD5000C6A9E26E039D6C7D0BF8B4727FA093C9D7
-:10DD6000490AB72FFE3B627CED7874FF39C8E9445D
-:10DD70003C4792611FD1A8433A6AE18CAE677EEAC4
-:10DD8000E8FA5CE43B315E6F70FE5917BB57A27A2C
-:10DD900070EE58B62F17FB9E397CDF4C96A9F775AD
-:10DDA000E057E92CEBBA97B5FB4488A7ABDB33BB54
-:10DDB00025A12866C0388B4752C12FF0D51B1E26DF
-:10DDC0007D47BC09BDF7A499CAD314D87E4BC8B708
-:10DDD000EB1F48403DE6308406005FDDEDF460BB9C
-:10DDE0008D90D7827A95ED973F3D2EFC1CEA7D728F
-:10DDF000BD25B605F0556F61EBE8D2C1445C07A4C0
-:10DE00006F7406E4855D3E6024C0BF7552B400D6D1
-:10DE1000F525C95785ED1A133CB09E3E903B10DFA7
-:10DE2000F580410A577DF0EF988F54BF4FBD6FBE0C
-:10DE300044FFABA6FC7E498E96C238421EC0FA470C
-:10DE4000BBA89AC569EA6412847DD5B5F2CCF9A85D
-:10DE5000FFA767906DF8FEFD02D84709394FDB1D1B
-:10DE6000915218DBC07AA9E1F8AB934F61BB1AC895
-:10DE70002B023CC2FE0AFC615019E7C7AD5B7B1E5A
-:10DE8000F39AEAF6AAE95CD3C507D2D712F48BE37A
-:10DE90000B5CC741A41BDAD9B0EE2B589C39919783
-:10DEA000132A3B30CFA99EFB3B9C87A3E3419E24D2
-:10DEB0009684C94CFAAC3FCBEC8CD1ED5B5F867D90
-:10DEC000B4BDB2231BD8BF9EFB03059D059CA3DAFE
-:10DED0001F43FF86B04FE2F6990326ABFC0C2BB034
-:10DEE0001FEC5BE17B5178E506F233BDB68EEBB5F6
-:10DEF00004D80083FE6BED8FFA0FF413C825B1EF41
-:10DF0000053905F2E13367F94F418EAD4D2BDFC680
-:10DF1000E419E52FB0E761B334AA773F9EC08F685C
-:10DF200007FBDF6FF2D3FD92F3ABC3C0E52E617E3A
-:10DF3000B9C5AF39855F0EE36F8B254F3AF0EB190A
-:10DF40005D00FD6FF34810FD42F3C1EF459F357C46
-:10DF50009DCFE5FEA4B9DC8F047EDDF83821F857AB
-:10DF6000E3CB0B08E35FB2C3D8953F037E9F0A1251
-:10DF700049A4E3D5825F0A9E6175BF3A12637CBFF4
-:10DF8000EF6BA32A0ED9C6E67D0FA7BFBD22A4035F
-:10DF9000F9B0C1CCFC51426E8C5EC6FC56C9C37C44
-:10DFA000792B81CF5FD3A33FE37F73BA093CDDE6D2
-:10DFB0002CDF05F8B7C03E0DDAAD34A2BC3C4DF500
-:10DFC000F01EEE47990CFBCFE5810190FF4D145BED
-:10DFD0004EFCFE543CD71C305703FFFC89EB31F15B
-:10DFE000FE31A79EF9E15730FE8D3526A0BD4DC507
-:10DFF000C610E0AFD27CA10FC910F06BBDAF677E39
-:10E00000E0BADBAD01182F2A3339738ECBB3734ED0
-:10E01000967F27CA9DFB3BCE3F22BE077E9E78FFA0
-:10E02000FAC79DED1FE37624C1F9AE9BCFF3B73B52
-:10E03000F95846799450E447B97BAD5C8EF228F6E6
-:10E0400091D50378A93C5F331FE6F1C9340B8138C1
-:10E05000DB6CEEEF95D2EC0887F0EF7E5BFCAB72E9
-:10E06000CD009493A23DC472A1BFD64F7C80CBB1AA
-:10E070000384C11B6C3632BF3C87FFC0D98121E0CD
-:10E08000636AD70641CEC5F69899BEA37628C8D74D
-:10E09000037BFB87603EEFEB99BD10A4F297F50F71
-:10E0A0006C003FC8815F3ABD90D753BFE0DC10B031
-:10E0B0001F0F9CFDD9AF7E0BEF0F1ABDB0DF3BC029
-:10E0C000FDF235864801DACB3C9FB1262952007E0D
-:10E0D0009F1739BD6A2CB44CDF579802D96923BA0F
-:10E0E000E267D00FDE9F0A31BBFC14617C105CCB71
-:10E0F000E29C14BF6E8023B63A1DE36F302FA0C39D
-:10E1000007070723DCEBF4BCFDC3CC7E3BC5CBA7E4
-:10E11000F617637EDF65BF01F371EB1F65F6E22C36
-:10E12000D9B36529C8CA9712D0CF38A7ED04C64322
-:10E13000EA1F993711EAEB172CFB1EF9863801E824
-:10E140009578FFF62512CBC17D70757E3842BF7B76
-:10E15000A97D809785FB5C185CAAE3799FA7297E3F
-:10E1600001EED8413DE2FF6AC747876129D36FE8D6
-:10E170000F8F8FC7A03E50C767BEAD7C491F2D785B
-:10E18000807E3F9812B835CDC9C41DD0BDFE25375D
-:10E19000CABB0F1EFE2207ED8956164F38ADF7CDCC
-:10E1A000807562AF881866C6D95FF3D2F8BEC3C85F
-:10E1B000ED462A07E3D7BDA82F2D57AF33F19C9B1F
-:10E1C000C6ECC9441EFFEF5E2FF25EA718417F32F6
-:10E1D00097128CEBC17173795C6EF4D9D821C8A306
-:10E1E000AA091763DC2F775904D725C57704ECFFFC
-:10E1F000D31B12993CA1D38471E68E2468B7CED587
-:10E20000B17C86B9466A07333D8EEDCF6C48473CFA
-:10E2100094AE60F65FEC3909E5A2884F5611D6FF3F
-:10E2200085E6F7833ADABE6A87544C452BA96A2EF5
-:10E23000C37C87059BF290FEA3B9FC9D65F4156C29
-:10E24000007E7B2111F98D7E0FEDED1AC8E91A864B
-:10E2500072C900FAB07A8744D690F878AA860F423D
-:10E26000EA78CCE83093DFA037489C9D26F410E88C
-:10E270000BA2B11FD57C11E4712A469FC701AF23C1
-:10E28000BAE43F62EC1BF420B5A3DB601D9796B3A4
-:10E29000F516DB23219E6B49038B1F713DD4090FBB
-:10E2A000D76367744C6FCE353E86CF9D697908C7BA
-:10E2B0000288B360DC206600B9D81B5FECEC852FC8
-:10E2C000043FFC8CCFA3E62C895C47BF57B38C443A
-:10E2D0006A87B067E210D4CB4C3F9B987E86A7E557
-:10E2E0002AF4B4563F6BF5B1560FA71B98BE157CA8
-:10E2F00010EF97077B64F4B2908EF95FB36C90C710
-:10E3000027E8323DD57730C3D9656FD59F34993C26
-:10E3100043A1EC27F956F02B95556681DF9ACA6F19
-:10E32000587709144F5BE9FBCDDC2E1F91C5E6EF52
-:10E33000E2F93A7AC54F8AAD40A70EDC47C79C0484
-:10E34000F7B502BF9B1369BF61D08FADC7CEFE2664
-:10E35000D26C89EB5F7EC08CFAE4F3FD89985F4252
-:10E36000F543AE9D8E97F60EB5CF69F9D28144D4B0
-:10E37000EF97B8BC77087F055985F4FD13A7739014
-:10E38000946782DF9748133241440ABBB1D6DE9BC3
-:10E390009F9ED7E775DCCEF8CC887AF6737BF43E87
-:10E3A000285378301FF80F5C2ED4EF1D5BFC20E45F
-:10E3B00001F8AD5E86D54031D80D46DD92DBC11F38
-:10E3C000345EB72CF6009D476DB615F38C2B72DFCB
-:10E3D000FDE3745AFE68AF9E1881EE4F4F498E40A0
-:10E3E00037C5E7EA493FCF0FE955E7D816EE509712
-:10E3F0006BC3EA723D893BE74651B0F4DDE2EB8F37
-:10E40000C4F1C95769898E338308C8142FE44913AE
-:10E41000DDDDC9811EE4A5787EB1DC7BFD113DE622
-:10E4200099E9D3591E8D01EC9A99C00F3DF46B4FB9
-:10E4300063768DD1D87016F2D58D2F1ABD8DB4D7D5
-:10E4400089B44012F4AF936347819EC6DC0B43400E
-:10E450000F96E7FE03E3679FFF8878013F9F9BCB02
-:10E46000D0BEF97C83D903FBB2B61C2BF357BC2476
-:10E47000852466BF4F1C510AF1529C03A95F7FD3CC
-:10E4800047EC700531C9485FBA7B71819CF1E17E30
-:10E49000EACC248B6D05ED57BD9EE9DB1AD29104C1
-:10E4A00072604A3AA79F6E97C144FF99D7EC1BD080
-:10E4B00048E15DE8B7E0B91AE54BC50FFCF5100C73
-:10E4C0001967FF0F4C67F2A0D6143594C1F7FF31DE
-:10E4D000BBD299DFE5DF32E8997F4BD9571CC9A43D
-:10E4E0005DE72D9D85FB9CCEF8F30696CF34EF813A
-:10E4F0002A7CFFF20623CEEFCC4109F9FCCC66362C
-:10E50000FF79EBCD1EC8BBBEC1CEF6B3F368BF9E8C
-:10E51000E77FE34730AF0F37DDEF05FFFC87847DF2
-:10E520002768637EA80F6D2C4E0E6D619C0FF7F669
-:10E53000413BA67AFDFC899867B659E7053B821CEA
-:10E540004C44FFCEBCCDF7FE7614F88F26DF59027F
-:10E5500078B8C1BE240DFC25B49D3FC4EC6296BFC3
-:10E560009B32F2195887377C39B6E306B09736D319
-:10E570007592C7F2E3C14E3FB2F946B44BE74DB2D4
-:10E58000D8615E9E4D4F8F07FDF1E1A40C19E7B3F2
-:10E590005B2236C0837D691ABC9F2729FE9EF8E95D
-:10E5A000A334E6672BCBB57A23D0EF0F3AE413BA46
-:10E5B000AE6E07FD59BB598F76EF91C96FFF71BAE7
-:10E5C000A36B5DCDD3B5DE3E3ACEEEA9DF748BE012
-:10E5D00013122985FD14C389767D19739715003CA4
-:10E5E000DA75366F4543018B577DB7F54636B1F581
-:10E5F00056932E91AFE5EFB4DE7E90EEBCFAF54671
-:10E60000B25254FBA8EE722D88ED84BFDFE425BE24
-:10E61000A7AD18D7F549E0974B57B07E533ADBCFFB
-:10E62000287F5DBCE3755817E9819500472EF115E9
-:10E63000031F7962B672382B64E5761CD9C4EC6688
-:10E64000B0EF81DEEB9CE49935717E87F5E9EC3C17
-:10E650001B5DFF8FC03897DEFAC751A04F5DCE8596
-:10E66000212CDEF919C607ADED2CAE6CF5C630DEF7
-:10E67000AE77F891FF845CAFF732BDA39DD79FD3EF
-:10E68000D9F98B7A470CC739E062EB50F8DB372EAB
-:10E69000B5A09F74A32364667E852001BD3471A458
-:10E6A0008EC5C5B89D750BF73F9A4A5E26100F239D
-:10E6B0006358DED7EB252F2BA9B4FCDB91E3BC78A4
-:10E6C000DEAEE4A9967C98F7183DAFEF138479FF8E
-:10E6D000CE5786F58B5D3A0FACEB89252C7F915494
-:10E6E00027A1BFE4F5920F1CB3E3E0F71393C74AE9
-:10E6F000F96432DDE4C4E7DB7D6F8CD9638DE3AF71
-:10E700004F5AA54A66EF7A92A70E66FE10D4C3252B
-:10E710006A7C2C7619F0BB6BD3CAF6039E6FB89E49
-:10E72000D1E3DC6E6308E4DF397E7E458BBF63E9AD
-:10E73000DCCF7A77A12A3EEF308473403F9E97D496
-:10E74000FD16B4E8303E3EBF452221FABD733B5F63
-:10E75000C80139FED1D32FE4CC8C8347DB4F3CDF9B
-:10E760004857FB01B57EDDDEFCB9A2DDE5F524608E
-:10E77000EAD3D5FE72F5DFD09F3BB39DFB837DBE10
-:10E78000BE0ED807F1F6DAF1FECEF943DA27A1BFC3
-:10E7900043F8334F1D7B0A22279DF433B7E7C9F1B5
-:10E7A000F98AE2399AD36D0AD08D4EC5DCC2CABD52
-:10E7B000D1ABB7F5F8643A8343D0ED544B9F64C0B6
-:10E7C000A3A1CEAA10768EAC10ECF4CDC4E285F5F0
-:10E7D00064C87059417E8973F85F98D9D361A14F9D
-:10E7E0006AAF65671462BFFB653FE6C57D21B7E28E
-:10E7F00039C2FB750D986FFD15FF5E96CDBF672E74
-:10E80000EE4FC2987F4D5AD4F84D6B62FA2356658D
-:10E81000403D25F07CEDCCFB709FDA037DD603DF15
-:10E82000648C64EFAE71E571BF4614E304E691C4F5
-:10E8300006FBF9A651418447D0A79E352752BB84D9
-:10E840007632E4B524A4603C34C89FC49A423AE3CB
-:10E8500003097C5F4B34F1002AB682D04EC00962B6
-:10E860000CF2631EB5875B0B4A309E8AF6278C0B31
-:10E87000EF671629E84F87768661DFCE6F9D7CC9EA
-:10E88000F30C278AF7D5961EE30F13E1BC0E6D9F9C
-:10E890004DF520D87FC4AB579DD7D944ED66D88FAE
-:10E8A00089F8AE4E0E17BB701FD21105FF88A1D498
-:10E8B000E401BD9AA00B1702DDB4F15EDA2E8FE5FC
-:10E8C0001964D941AF88F338754BC7FA21DFBDD33E
-:10E8D000CE38C8F647750F94E1FBB1EDCC7F5EDF13
-:10E8E00062C4F384F5FB248C57D5F90D2113FA315A
-:10E8F0003C8D40AF20B5C360DFD86667F9516D37F6
-:10E90000D9BC4112EFBF8E6E7910FDD7568CD3FD66
-:10E91000B3F1CBCB89140143E3E253C926A647B830
-:10E920007F3B8DF393A0BF58CF22DE9958E4CF03ED
-:10E930008BFBD7EB66FFC6E2FC2E7921D73E0C7924
-:10E940001FBDE7851CBD05F2464C60CDF37A008BF8
-:10E95000EACDCEF375660FC6B53AEBE15E04D33E61
-:10E9600089F7FFC12DE3FA62FE283F5F77DD5AC8C1
-:10E97000637ED44C54DF8B874FD18CAFA7E35B3DD4
-:10E98000A2FD3D378F5330BECBCB2FFDD847E17F63
-:10E9900054AF1E0F59509C0734757DAF3233E1E1FF
-:10E9A000B563BAF437D5E7CB5DCE2E3DFED0DB1391
-:10E9B0005B877A607D7D8AF9B8421FD73B589E8875
-:10E9C000566EAD7149C2FE1D0F2A76D5B42ABC47DA
-:10E9D000A033BEDB3EC907F72988F86EFD323FE65B
-:10E9E000E582FE77A1FEBF70E61001FBF21CDAFFA4
-:10E9F000F55714E60FA2768444F9D0D45E867E4F94
-:10EA0000483705BD29E8BF80EB25B0D581BFEB377E
-:10EA1000DDF1B40EEC6597EF491C97EF03B5F08676
-:10EA20005DCC5EAF2F2CDF00F2806C9708E8ED35EF
-:10EA3000859FA09D51B77FDC88F8BCF2F9FB9E60F2
-:10EA400079C93BF43DCE3FECD2A17CABDBFF1CFA95
-:10EA500033CF85D871966A25B47A34F855AA65B053
-:10EA6000B44849A86A3AEAFF69741EE03704BD0356
-:10EA700076CA8E2941C873AFA7FF01CA36FAE7A24A
-:10EA8000BDBF719AC90AF19AFAC2998B703DD82C10
-:10EA90003E98BF16CECEF8F00316F437AED9A7AF26
-:10EAA00004BBA994DA49BFA2F066A74CA8F452B9F6
-:10EAB00094A9DB53FC032BC4D57BD6C35333981ED8
-:10EAC0006E96FCC15B4B300F92C4E7E9E4EE63F64F
-:10EAD000D8AB2E66BF89F7AF42E223C5E79860C77F
-:10EAE00058E0B997946802D8C5F5C4F731EC73893A
-:10EAF000DFEA8171E02606B0B31CCB3DE8CF3539A3
-:10EB0000A23F1E8A769382FB0CB18FB8B49FF9BFE7
-:10EB100046B9036F021D4B75D1C76F05BCFD989DAB
-:10EB2000F3250A93373953ACC3C05F6576441FAFF2
-:10EB3000F4607E0DFA1F92AF6B463ABCE42036C0FB
-:10EB4000CFD8609522C5E9192137C6769EA771A056
-:10EB50009FB49C8B977E945A674CC8A2CD5FA776D2
-:10EB6000D905C7FE31558197C25E904D01DCCF5467
-:10EB70004CA3FB43E0CB55B1A332F8E51D1D682F34
-:10EB8000D68625FC4E6DE12F31FF6D21CFB3EACC47
-:10EB90007752A298FF75C995C0F56333E34BD281D4
-:10EBA000FB5FB28BE19FEA4DCC0BEBB2DB1BB19D5F
-:10EBB00018CFC0E309B5DC5F431185F57F7589780F
-:10EBC000C20AEEAF12796CECBB44F194C6FB17D6C7
-:10EBD0004DA29A04E1F22401BCBF30FB65376D7F82
-:10EBE000AA5A66FEEC9684101C0E5D2775F8C0EFDD
-:10EBF000182CEEF91C4CBA5BE279B2B1F1E8EFDF08
-:10EC0000DF5B9E2CCB8BDD306220E69597ECFB78AA
-:10EC10003CF007A924B81EA9BCB8AA3CD92C375B84
-:10EC200047FFCFE4C97A25DF36FA1CECB6ABF364B4
-:10EC3000BD8C5E227EA9CD8FBDE48E282C9F2DBA7F
-:10EC4000E569D0BBFB8C98273771DFAB27C17F39D3
-:10EC5000D144C218CFD5D80FAFA54E29053A5DBE15
-:10EC60007866CB4A02F9D5CF7B59DE9DDA1EE8CD16
-:10EC7000FEC79846DC3EB1D2FDEFB5FF85BCAEE7DE
-:10EC8000FBA9F352EC910298DF419DADA77331B718
-:10EC900089EFF796E7D1DE739E8738775519CD5304
-:10ECA000C5A7EEE91CEFBBC5BB66820FBA87789794
-:10ECB000C2F3B71489890E926D50C5BB147B416FA6
-:10ECC000F1AE08D63FD71FEB1FEA16EF627905CDEC
-:10ECD00007D33D60DFD73863CF3CE381F10C384E7A
-:10ECE000F3FE8410E4B93773FCD75C7DBCEB41774D
-:10ECF0000FF1AEADDC7EFBA0508E18285EB7120679
-:10ED00007FB05DC4BD64DCC7C61ECE16F063FDE5F2
-:10ED10008707A1BF68968867BDC4FC68B378DCEA42
-:10ED200083C90598E7D51B9E67B5A8E3020F039E2C
-:10ED30009DE8E7437FFC7DFF3109FD5373C18FDF01
-:10ED4000A7EB1C04E1FE3C4F0B3BDFEED921853CD9
-:10ED50002CAE6292D136B4C9F07E2115A31B41F4CA
-:10ED60000629D75C435F4B146BB4DED34CCBD4E89D
-:10ED700057562B41176DB7F56402FACF1E72781003
-:10ED8000DE879A597C39B8560AF563E3E2BD61C162
-:10ED900066D907E3EC7633BFD32B6EA6FF3C9AFB14
-:10EDA000089AF53C4ECCBFD748E4083C65893D1F26
-:10EDB000B229953DD90F62BC667D83A90CF09DCD2B
-:10EDC000EE27F9DCE09B86FEE59402BC87A839B10A
-:10EDD000A1A592D5E39AFDDC1CF363FD750A3348C7
-:10EDE000892705E07DCACDEC1B2D9EE7B4AACBDABE
-:10EDF000F88EF6DCD52C12E8EFEED3FD5CD2536E24
-:10EE0000A6FF3E5F93C7E9E2C57849B3DEF3461E2D
-:10EE1000F0FB6A76CF506316C39B9CCD9EF9F60A31
-:10EE2000BC0F8ED8B91D4718FCF9D73924580FCD1F
-:10EE300076C6B7FF2ADC5A785F771730FCDAD97AC2
-:10EE40006D5E2D8518BE18DC57EB1739FF6F968B5A
-:10EE50001F48DE672279D80FE542F0613DAEBB5313
-:10EE60002494C9F2266D283767F27DEE675CCF6D7A
-:10EE7000ACCE4F8238E8ACB3ABF0BEA0B153AC0817
-:10EE80007FDD4B66DCC7D52E8BE6003F6BF108D0EB
-:10EE90002A429ED2FA990EC2EE996951C7F5B4F191
-:10EEA000DA608A5F8678505D79B400E2464FC81F09
-:10EEB000EC7995C935D4AB75CB62CF809F796A4A1E
-:10EEC000C09C41F173E181B7C74B1EEC8EF2EDF2AD
-:10EED000C1FE78BE7066B3FABC1659AB8E1B929613
-:10EEE00014762EAD4DFD1ECE27A9FA758B2332BBAD
-:10EEF000669D213000ECCE1BAE67791217E7CB047C
-:10EF0000E879D14C787C5EC8596F41BC1E28E07608
-:10EF10006F77BAD27680679E172ADAD7025D293DCD
-:10EF20006B385D2F3E774D01D0F5C29E6B0A80AEE7
-:10EF3000EBF4AD3E58179F390303011FA7C7F9D162
-:10EF40002E1479B057CB6FA332FE67F5F078819716
-:10EF5000EFA887E12FDE5FF2D23F58BE6AB09D9DD9
-:10EF60004FEDF2D39DC37BB62E5F912590C3BD8D2F
-:10EF70007792EF935C261204FBABB43C8AFD4AFF08
-:10EF80002613B00385FDAB857F3AC7DF820CDF4BCC
-:10EF90002EC023F7EB56F3B14DA14F999DBD5D42B5
-:10EFA000BFADC9134C1A8DFBAA39C37528577E858E
-:10EFB000E72048BB6483FDC9FCED8D587F69DF2CD9
-:10EFC000AC974D9108ECC36A693D94578D51E73574
-:10EFD000EBF71647E2F7BD148E03B09F4970C40CDF
-:10EFE000C09F7560575310EB14E6DFAE7310F4AB9F
-:10EFF00094EC53EF1345DC76A39FDDE3B2B15DC221
-:10F00000FB9CD20C81BC2CA0AB267E7B7F866F1D27
-:10F01000AC571147BFCDE97B2083E597E5009E8281
-:10F02000190C9F51BD38AFA73E4F78ECD0ED680763
-:10F03000FD85F8937BCE370BA9E2EB73F979CFB955
-:10F04000FCBC27C8E788463EC7976BE2F2CD223D5D
-:10F05000E50DC4E59BC5F78BCF378BA8E41A5BFFA2
-:10F06000E9BAC518D7AEA77CBE7458171FD610FED4
-:10F07000B73EF6019E6BD961447F5A0DCF33ADAFD9
-:10F080003E85FB947A3827C3D623CBC7E6F71CD43A
-:10F09000D0FD1FE6DB86D5F9A8BB7B951BFF77FC6F
-:10F0A000E4FB843CE0EB51CC4BCCA3A65D62EB4788
-:10F0B00003A776DFABF5778B7DEBD5CAA5E3FFC35E
-:10F0C00072E9AD7F935CEA1637E81B4BF2FE1BE258
-:10F0D000061F795AD3C095D822317E1DAFB3FA5896
-:10F0E0005C52C7F216B4F15ACF788C430A3FADE9AF
-:10F0F000795D68451EB6C7386CEDC144CC23A8F6CF
-:10F1000054A39DAD8D4F2E207BC60309FE428EE396
-:10F1100079AC7F351F806476E603E47DC77C0063AD
-:10F12000E677884FBE6CFD343510C727E545D460BF
-:10F130002FEA3D5FCB99C9F82E81E78D989420B1D5
-:10F14000C7F5EFAD5F7626CB037B99E7193D9A981B
-:10F1500080E7F65D0676FEC025B37CA8332E7F6E71
-:10F16000E608D0038C8E3FD97F0781FCC29FE8C39D
-:10F17000788E3E586BF582FE127E2631FE83DCCF00
-:10F1800072B5EBA724F3DFBB7EBE4D6E5C2FBE775E
-:10F19000B5F1B5F5140771EB4ABB0E7AEBD79B5C62
-:10F1A000B935D33F2113E5966F08C629AE521E2507
-:10F1B0009450790DFA79AFD103FB05133F2743D65D
-:10F1C000BA55FBED598F66A3DEBA6866FB07719EE0
-:10F1D00047CC7F66AFF8FEE7ECBBE34EFF6C98CF01
-:10F1E000E9321F9E07782891E995D84E9617A43DDD
-:10F1F000D7A2D527E25C86F8DE7DFF667EF8AEF208
-:10F20000B4497CFF5F94A754BFA27FA5D7386CB7E1
-:10F21000FE419E9FD9E1E3F1293CE720E0AAEF609F
-:10F22000F9748F674A2A7FF37D5CFE9FCCF4B501A9
-:10F230001D2EBC653241DCB3A484C9CF3ABF15E3AF
-:10F24000067561964753B78CE03E5F9C5FCD4B0FD0
-:10F250006C0139F5D0DB56BC77B46EDFD6967CCC2A
-:10F260002F08A05D77E92DF6FE445A601B8C5FBF26
-:10F270002CAA8A4F947EFDE9AACA128417F7E90ED8
-:10F28000A3FA5CD0914CB6FF16CF439DF8A5FB12B4
-:10F29000DAEF4235CBDFAE77F86C659857C0FCDF0C
-:10F2A000099E0EF45BD7ED452541309914EA1FCC39
-:10F2B00042BEA9DB5B568CF70884CDC578FFCC3BFA
-:10F2C00056DC5F5D782023A463FEF2FD006F624987
-:10F2D000E826B02F73E977C0FF7D61CF4DC5E80FF9
-:10F2E000D4AC3BB1DE3ACF83DE650A35495DEB71C4
-:10F2F0009D9EE947A1D77682318B79153C2FB07D51
-:10F30000129963ED2A5B1DEA7CC90519E376023C7C
-:10F310003B33591E8988A3E799E8EE33BF3B1FE6CC
-:10F32000F138FA249EFF4082A6AEBC87FC6F8FA303
-:10F330000BF84459C4D113AE30FB36DF6640BE48EB
-:10F340006C61728350BE00FB7A4CAC632C9CC3EAA8
-:10F35000DB161903F84A06F463FE69F4C743215E1D
-:10F3600091AA8C8178C596A5C30E9B1CE03FEAB894
-:10F370000E48E369B595C3D6322FDD7F06F59ED2E0
-:10F380005008FC5FFE073DCB535C9D80FABE2DA765
-:10F3900006F3142FBD6D549DBFD13E8364850BFCD5
-:10F3A00044F92DBFC77841E25EA9C7FCD37E60F463
-:10F3B0008F60EDC1EF94D8D2111C097E9487257619
-:10F3C0007723855E72C1FE5F91C1EE98B58F9DE394
-:10F3D0009ED56A2F37A13C9558BC658C03E5A4B235
-:10F3E000FA6619F6674A23C17BD2B2B2D839817E58
-:10F3F0006D3619E8FEEB2F753DC6D112B2985E85C9
-:10F40000BC374057AD31761442FD22FE27F2DDC4F1
-:10F410007EA853BEF2FBC4853ED2DAB1DDEC57AE16
-:10F420008F3AED780D1FF7D64FF0B7E0E75FEB09A5
-:10F43000DA61BF964C78BE4BF075B3C8DFFF92F926
-:10F440007173793ECDA9357F1FC2EE0F14F1931071
-:10F45000CB83D247576522BEA2D70761DE7BED7210
-:10F460005D11FABFEA709CD5ECBEB3DC963E2B462C
-:10F4700096C0D3460005A70E2CCC857519A47CD068
-:10F48000AF073E3897C9F29694D5094837E531BCA5
-:10F49000D99928F634A49BF204A3CF69CEE7227E43
-:10F4A0002BFC94273303A3B39C71E7B2965AD8B9C7
-:10F4B0002C7EDE3771E9DBBBE1BCD316EE2F3EFCC0
-:10F4C000D220FCDD85CF572B12F88D3EB757E5C211
-:10F4D0007E6F1CA76BA2D2416CD678FE3C8CF9B231
-:10F4E000F90759DE9FC2EF4F52563BB6023EBDA907
-:10F4F00001CC0BBEAE39823F59F092ED34C6E5A87F
-:10F500005D84E79FCFED97845DA4D28762BFA6DDBF
-:10F51000874DCFFAEFB5936667A9F71557BDBF22A0
-:10F52000EA7D66677BB16FD4EE2334FD7BB37F88C1
-:10F530002FA8CA8BB99FE7450BFD9EC165A3C8974D
-:10F54000E93CBF4C42663807910CB9AF4CAF63DE63
-:10F55000D07AC9E2053B499B2FD499C7431AFAB325
-:10F560003C9286A1EC5E8A866BE029F289CC904FB2
-:10F57000129FB79AC8F281CC904F42DF37F57ADEFE
-:10F58000D9D308DF6FFB914D9C77667EF64AC2E3C4
-:10F590000CDBF03C74ECB62C3C5F33B692F9EF52C6
-:10F5A000FC0619F8F2F9AF743E90BB31BA6EC1BED9
-:10F5B0004AE9EB7383BD65A6F590A7D279DEB98AD7
-:10F5C000F478DE59E43389F86E46FF7512E89FCE71
-:10F5D0003C93FAAE73D0F0DDB6451EF40F77E63DEE
-:10F5E0007D9FE03CCB859C31A9E997E463ED92A631
-:10F5F00019D0CE4893033B318EB7B1C38CFE8AAC91
-:10F600007CE4ABA69121BC3F37A5A815FDAF2B53D9
-:10F610007DBBB24674F18F808FAC67F3BF0CE7BC43
-:10F62000A4AEEF5E9EFFB71CB0A7CADB8D8C0F3572
-:10F63000706CECBC6F857E873E0F6531FA7B35F6CA
-:10F64000AD781E12FCCEE5B0F87E6FF314FCF86DB9
-:10F6500076BB96BF82E59C3EEF99432C5F49CD5F18
-:10F660008797570E3F4D65C991E57E7C5E364B61AD
-:10F670001DE4159963334002FE38BBFE7B700FC753
-:10F68000E5C4580EDCE3F178CE6DB7C23D1D979D01
-:10F69000B1F7A0FC4CF643ACDC2FB605EEF568CF15
-:10F6A0004E6465F85606216F6D926E0D5AF11EADCF
-:10F6B000551DA09F4A34F9299AFB07208F12EF4B62
-:10F6C000B0327AA6F33C5652C1ED77882CD17293B2
-:10F6D000BBD80BF90756E2D9DB01F55946764F0145
-:10F6E0006179534DFDF2589E03E77792C5FDCF2413
-:10F6F0001A04FE6DCAB363FF4E79BDD7C8E34EEC62
-:10F70000FB279E63E7CB447E2E21B66CB07BAC1EFC
-:10F71000A22A8BFB3B8862CB86F3FA4DC2AFC7CBE4
-:10F72000EF5A027FCF8AB38B4E8CBBBF087FFFE3BB
-:10F73000F907FBC27C6F34A8EF4F16CF65394CFE3A
-:10F740005EE6F70CB659024A362D9F4C98311EAE34
-:10F750006E9D965A66B0A39DB65307F2C8C9F9C20A
-:10F760003E95C167AFF04BF0BB1BE29E3F67404147
-:10F770007F0009B4E9407F3A4FFB310FB0C614CB8C
-:10F7800051F2C1AB1FB065431CB0EAFDFB300E98CF
-:10F7900071E23DC8DB38A16F1D9B04FA228FDF03A5
-:10F7A00041377E415A3E9A998BFBBECE7B41FB4945
-:10F7B000281F264E65E7562790B082FE171B3B4751
-:10F7C00035BE24CFDB44BF3791E77D8C3FE94F0244
-:10F7D0003FC0F83BA20A8BB7C494F83C0BF1242E2F
-:10F7E000BD277E1DDCE4892B13B84F585DBEC5AB29
-:10F7F0002EDF3AF2CBFEF1E564E21B04F37C518A82
-:10F80000E239E4E0286263F362F9843FE3FBB64146
-:10F810002E62CA857C478714847DC1A01732308E42
-:10F82000F2C24882E5B41DA66DA6F8F93F26B338AA
-:10F830002DF7738BDF0D823AD0ABCFBF9586F84A98
-:10F84000B3CA284FC1030EFC569A69B2807CD771A7
-:10F85000392FCE6D8F4B32E17DAF4D8BD8EF0D68D8
-:10F86000EFBB6CD2DB0E011D9B3EA273A0DFD99EC5
-:10F870006888C849402F420C8E2E792CF807C6BBE9
-:10F880001EF87E04FB5D27CAE57DE3EF1B6F723235
-:10F89000589B7EA4F0F81CFB7D89C2CEDF9BA0CBD9
-:10F8A0008EB6079B92E03A61F1B16C314FA2F8A09D
-:10F8B000BD9B88323B9F95C6CBE29E4D42CA14BC8D
-:10F8C000674712ED1AB1FC246F27B5BFFA57E08FD6
-:10F8D000BE49743EF4D994CDE4C453F289F5C827E7
-:10F8E000D68007F8C49BD0F379A1BA6CB66EC62552
-:10F8F0008D7441DE4093DBEB02BB4AE0A7F33D1F72
-:10F9000057D48BEF79537B1EB7898F1BE6E78DB5F4
-:10F91000F53FCA66765BE7F87A3AAEF51BBEEB5464
-:10F920007FB7ABBEB77EECBD688F3F07550AEB8C47
-:10F93000E16D02CF732585EAFC1432D26B62F25E70
-:10F940009D8F72A3B4CC0DEBF326536D7B94F67FA1
-:10F9500095F3C98D72E0338837BC3AA3E008ACCF89
-:10F960004AB8D09E8E733389AC0266B95C16F889AA
-:10F97000BD0FCA8B75208FEA7481FE29B47C51DFDC
-:10F98000DA77511EAEAF27B34774874FF061279CDB
-:10F9900094FF80EE82FFB4700B3E20DF0B6342DFEA
-:10F9A0006612C1A78BB03C6AAABF58BEB427BB6B16
-:10F9B0005E9439C79B1AFA827E7FB53188F2E7469A
-:10F9C000FBE39837B63337B00BD6FDB4A11FE33D48
-:10F9D00039C45585F6168577F7FF24BC745DB9E107
-:10F9E000BDB00385BDD72D7FF823832A7F58C0A7DC
-:10F9F0005DC7028E7AC2EE3F1ADBBE15EDBBFAA9D7
-:10FA0000562F9CF3A887BCD8128C7F619EF101BE53
-:10FA10002F0B4A2CDFB79BBDD87B9E31BB0FA0D6E6
-:10FA2000C6EEC111F729DD9B2FEEC9617053F9C5F0
-:10FA3000EFC9C1725B9507F77F9D76E31C6687DE91
-:10FA4000506069867B07BBDF97C3FC7BE405A38717
-:10FA5000DB89A8BFDB12D9772E9A595E7B9C1C27C5
-:10FA6000525AD73D5EEBF4CC1EBC949DC7E278B2EF
-:10FA7000B714E8B111E256BAEE7EC8CF9C818F81EF
-:10FA80004FE614F972E0273D6619989F91F2D5A6CA
-:10FA90000E02E9710DDBE17ECB9B48C39B721FE434
-:10FAA000AB2F807FA60DFA98DD7BD9C55757185F1D
-:10FAB0000551087EDB3A7D2D3520E58CC03CEF7783
-:10FAC000EA4A20CE6844FC8BFC43EDFA8D83E7B410
-:10FAD0009EC1E3807B75293CE61C677778AE86BFC4
-:10FAE000E3F9289D303EEE8DCF21CF3F7158179F0F
-:10FAF0002793800BE0EFE4F755DE165D9F1EE0D6FE
-:10FB00005991EEB74F67F198FA0466A7425CC69D1B
-:10FB100006FE27F6FDDB5733FEB8DD6C447E99D434
-:10FB20005E8BF11752C1E2295EFA3F80671AF18DB0
-:10FB3000839FE698629B84E736A74E54C75BA699DD
-:10FB40006EC4F8CE6D84F9D36E9FAA57FDEEA0C0A7
-:10FB5000C334B2F663C8E798A6F9BD412D5EB4F18F
-:10FB60001A818FA691DFBCEEAFCD4974609CD8435B
-:10FB7000FA7FC7B84E790ECB9FBBAAB8CE117D0CC9
-:10FB8000CFEBBFE29CB769115D17FDFFB308EFE94A
-:10FB90001E97367FFB63B4FCD38D03B1FC4ADA5D5C
-:10FBA0004B4E40FD96022C57C81FCFC07BD34BA7AE
-:10FBB0004F80FBCD8F98D9382E4BA00D7EAFC2352C
-:10FBC000247F186CC92A0C316C77F3D0DAE19007E6
-:10FBD000536161E5E3C5FF6B1896F37979D88B0320
-:10FBE000A17C44FA78464F71A1418552047E97AAC0
-:10FBF0002285B59F386C6706F8092ACA597990B7EB
-:10FC00006C751FA8973F99D1933E6EE0F6B1B0B7DF
-:10FC1000FC7CBDBFE07BBF19CE87F9AD9217CE0546
-:10FC2000F847BECFEEC732B13C02BFAF5881FB13DD
-:10FC3000CB7DCCBF37D6DAE806F9F7BD80A104FC4E
-:10FC4000B8366B5E33FCBE40F2C8B21140EFB1D49F
-:10FC50000C03FD47D7D5125C57D77C9C93847688DC
-:10FC60007A5D09BE9D24D653857ADD5079F04346EE
-:10FC700047F57AA0E32E87F7D3AE55EBA54EF9AE44
-:10FC800059B75A7EEC55EF13B51CECD44FABC2C834
-:10FC90009759849DFFD90C7CCAD66F2BC061903BCD
-:10FCA0003CF03E57F20EC4C48A5EEC07011F983D3B
-:10FCB000645877B8E04F11F62283C0664B83EFB2E9
-:10FCC0007ADACF073F2226E0A2DF0F217E56317875
-:10FCD000364B0DFC7729985D2EF6BD7562BEFBD4C0
-:10FCE000F32DB5B073EC2E42E50EFAEE8B077E13C2
-:10FCF000DCF55CCF4E35F91F36D239DC669F857452
-:10FD0000BE83049F03FBA6C312F825D05B27070F11
-:10FD10004625F85D091FC693291D7F9513672F0897
-:10FD2000B8B4F8A8EB45AE6AE1D6E2A18B3E1D68F7
-:10FD30009FB9F9EFCF75CE4B339F267EFF7CACD8B1
-:10FD4000A8CA133D5EC5F260055CC72552887A5289
-:10FD5000B2601CB5D3EFA4956FBD9C6713FA59C070
-:10FD6000793F3F4FF585CCE4DEFDBA08C2995BD9F7
-:10FD700061063C7E92C3FC2E02FEA691416C679008
-:10FD8000A51EE3C49FE4C8C25FA6A2B7B8D74CC4FF
-:10FD9000B9045E1D064F16E67B6AF039D364EC3970
-:10FDA000AEAA8DBFF6D24EA2F8CB4CE98E67112FCA
-:10FDB000BB45EB87BB89F9A76EE17EB8B1950CFF17
-:10FDC000294B1371DF965272422183BBEE5D16F40C
-:10FDD00078C711F82A07E316D111E027787DC44FC0
-:10FDE000314E24EE37D4E2C792DB337E7A5B0FBD0F
-:10FDF000C1FFAEC56FCDA5E35C943AF01EB4BFBBA6
-:10FE00006C7CDC401EAC17BB2DAF0CFC0B54AE7EE3
-:10FE1000FD356C36A10AE8E70C38729DB03EFCE374
-:10FE200020F73AA532A067FE7982FEE1C57C9F38B3
-:10FE30008EEBF74F76B1F3F315BE014F8E01FBF356
-:10FE4000989E843C90C7CDF0F3C9261DEAF579AFA2
-:10FE50000D77817DFE01E7B7FEEB65D5EFD30D0889
-:10FE60005954F76C0CDA91A22A0F0E67A8DA0FDD4D
-:10FE700097AFAA2F8E0C54D50F3F364C551ED1315B
-:10FE80005AD5FE9A93E5AAF2A8E80455FB6BCF4E2B
-:10FE90005695AF8BDDA9BE2724E8EB284C83FBF9F0
-:10FEA000193E6EB83253D5FE7CD2F863B0EE66AF21
-:10FEB0006579DB6564A1AAFF425D0DE64393566652
-:10FEC000C734D0FF213D75772B982746EDF754C0F6
-:10FED000DB7AB59D53DDFED82A90B5DDEEA7D0D8EC
-:10FEE000335AFBA5BFA30AAE7726B7E6F2BC936BE5
-:10FEF000C835FCF74AB474C5F3FE9FBCA9C37DC4E2
-:10FF0000E2D7987DBF7837CB872B20FD92F11CD8A4
-:10FF1000311D094970EF41C3BA3152971DA3C58BFA
-:10FF2000D1A5A6B3D9A3A67342A19ACE895E359D69
-:10FF30009347AAE96CF7A9E99C5AA9A6B3D3AFA63F
-:10FF400073FA34359DDD01359D33ABD574CE6E50DB
-:10FF5000D33977A99AAE79C105AA7A2137FBB42C97
-:10FF600056BD6F92C2A5545292D9FE6ABCEFA15FF2
-:10FF7000EB0F7BE40F41FF20FD1F5BCF0D985F3F30
-:10FF800097D21FF2EBFF42D61E855094960FEAF6E9
-:10FF90003D8671B5EFCA078F6AE97F95F629D58747
-:10FFA0004F803CA176CC7A900FD3FAF37D87BF6760
-:10FFB0003B46C8AD78BB217E5FDD9B3CEBA627F9B5
-:10FFC0003EBB573DA9D967BF05D94D688FAF45BF27
-:10FFD000D674CED79FC2AB51E0577D16F5FF5B14A8
-:10FFE000909114AEB7006EFA9DB72C83D00F7217A4
-:10FFF00089E8F19E6BC8DCD4E17D9998875945ED7D
-:020000022000DC
-:100000007278CEE2F6C11CEE27F9CA183890CBFC04
-:1000100023B969F0DDAC0E76EEEB78EA55DD0BF135
-:100020007BF827F8DD73FD87619C0A9367C913F499
-:10003000D561EE7F221359FE2751FC83E3EF61EC7B
-:100040001A87C54D5F940201DC67BB4D5ED8670F10
-:10005000CA242637E83757281FE25427347A652008
-:10006000E791DD19E1C576C4572805E304DFF1BB4C
-:100070007FCAF59D047E10EDBF6DBE06437811F377
-:1000800027B0DF4B7993D3E5A9DB8D11D897093ED3
-:100090003A9930E3A8D383FEF033C86F77DCB40A13
-:1000A000CAD2E154CF620ADFE5AA28EEEF29FECFDB
-:1000B00001DE6A4C14FF748A17B303FD938119FCA7
-:1000C000A9DC49E91FDCD3792401CF58897DFF5D84
-:1000D0004BE05318E7B0DC91E3057C281D786E8F68
-:1000E00058D1B821170D3DFB03051ECA13B2EFC648
-:1000F0007B788D462FEC2FCA2546D7D3A9F7CC8025
-:10010000D8E21CD99F16D1A9E0963C00B7AD2AD7FA
-:100110004DF9F1FF00AA42FBD90080000000000069
-:100120001F8B080000000000000BE57D0B7854D504
-:10013000B5F03E7366CE4C924932492024848499AE
-:10014000843C20214C82202AE2F0088D1A30BC1415
-:1001500030E2E401843C2080DEC6963603E1A5420D
-:100160001B2C2A2ACA8040D102068B801AEC206AF6
-:10017000F16A356DB5A55AB90950E54D0C3E68EBED
-:10018000ADFF5A6BEF9D9973480AF6DEFB7DFDBE0D
-:100190003FDEDECD3EFBBDD6DA6BAFD7DE73DEE2EF
-:1001A000CD8C561963B6DE8CDD00A9D999531CC9D4
-:1001B000D8B7F8774B3065CCC718546954E09FBD69
-:1001C00020F723C5BFCDC5F81FE4F7FB62FC0F4144
-:1001D000DE6ABAF4C114C8770C36B9B740D1C6701C
-:1001E000E83A9FB1F7B11EF4FFB405F2B1F47D35E2
-:1001F0007E4F08E7ED131E33F91BA17DF198971789
-:10020000B2EB187B76BEDDADC258A5CCA931985FA4
-:1002100039F3682C8DB1BF8CFEFBC1362763FD9D81
-:10022000DEBECE618CDD1B674AF980E6E1CD9E041F
-:10023000F36623E3184BBC72FEC67530B6C6C4869F
-:100240003336D9C197301BD705EDA6308F05C79936
-:10025000C6BC161CF77717340F8B82D404E530DF49
-:10026000BB988FBECF607E4AEF6601AA7F0F6BA35B
-:10027000FC6F237293EB617E931ECF4C67D0E662D6
-:1002800069DB702CFF87D5EB76C2B83536EFBDBD84
-:10029000E0FBF964EF677D10EEEB39DCAF36DF4948
-:1002A0000A87DFC5FEC52370DDE36CCEEBF2521981
-:1002B0007BDDC42A9BED5036AE37CD9F991DE99367
-:1002C0000777D7CF32C6A05D6B67542E1B82798F1C
-:1002D0003D11D6FF3D81C2EF79AA8B709D05AA9D85
-:1002E000F502F8B73A55BF15C62C1C5DDA17D705CD
-:1002F0007F913EC0D3448FCA10CFBF5E0A5FA0DE9D
-:10030000AFF3543FD2C4C40DE34F63FBA2D1539665
-:1003100047C3FAC77FD3765D00D2C27E96E36D599C
-:100320007C8C6FE17F5FB28DE36220BD2D618F9980
-:10033000C1FC6F1BA02F2FCA81BC2D989FC8CCC1B8
-:100340007218F710C201E8A7FECF79A3DE0869C7CB
-:1003500058935A0CEB2E7146F6FA3402B283D8A0A9
-:100360006F71DE6A49B4D7DE337CBF6E708F7A035B
-:1003700068F276C553EE24BA706A48FF6566E6698E
-:10038000EEA6DDAE7445D00F60379EB13BC45C3B3A
-:100390008B2E691761BD4F3ABDF3B19F4513FE32F5
-:1003A0000BD7C7CCEC3743016EF3DF03B841F9F14B
-:1003B00006807C2663271B6CCC6365ECD30607E5BF
-:1003C0004F3524507AA6C149E9B9862C2ABFD0E01E
-:1003D000A6FC2167F1F7B1DFB2D59F9BBD398CAD8B
-:1003E0000A9378E4F3582CE87855F2F03FBA61BCF0
-:1003F00055EF5A285FD9DC341EC1B138F9F8B2087C
-:10040000F8BEF839C58DDFAB5B3C9A1DE633FB0DBA
-:10041000EF4A249FB9EFB64D04F0B1DACB0AF3E20C
-:10042000161A50BC02C71BF6E1C97884DF670D239A
-:10043000683EA71B3C341F4F4BFB5B71D0FE6C43E7
-:1004400021E53F72163F8CF53DEC730DEB4FD8D98B
-:100450006E4E82F2028FE2C1FD3DCAC3FC7EC0DF58
-:10046000068BD78B74B321D1E6C6FD3E7AF0E4A7A4
-:10047000EF83713FE9EF7D14E97A5A6C79411C7C76
-:100480009F38A2D48CF5EEFA8631CC4BFABEFABE78
-:10049000E6F0A8157839FF9A42703ABF2FFB8E9B81
-:1004A000A0BFD78EA84C8579755E36D1BC3A8F86B1
-:1004B000FB9912ACB7E82595E87AD160CDCF5C986E
-:1004C000CFEEC372709DD019AC3F4B71B27AA0BF12
-:1004D000B3BBBE9F807890E39F8D6DFEEA23E47BE3
-:1004E0009F70BEC758F3A74F225FEC97E07E08725B
-:1004F000172C6C3AED5356173119E86BBEC6BC3C4D
-:10050000EFCDC6FCD970766F31E487EF4E1A83FBCE
-:1005100008C7736606F95AC6EEC7537FE80C8EB754
-:10052000A379F6474F42FEBCDFE4B34443CA9A2F97
-:10053000BC827C79ABDDBD8DE13CCDE138CF872D30
-:100540007C5EBE6DE1EE6D4EECCF4F7C00CA352C6B
-:10055000AF79F189BEB88E5701062320FFEABA08A9
-:10056000E277AF5ADCC7EAB1DDD3BCBF9FFFE481BD
-:10057000E307305D5B9BFF00A4BF73C612BC2B1E5C
-:10058000993708DB6727017A803FFE62BF1208CBEC
-:10059000656CF0FA43CB1261BC211BDB4D7D21CD94
-:1005A000DBAA34629A9D5C784485FE8F3A9D348F35
-:1005B000A13B5D6A126ED7BEFE8F6E4923C02988AB
-:1005C000BF41027F39EB3F1FD317D25D7D9B17C51B
-:1005D00040F920A5F9CC5217D2F91FF2BD04BF266D
-:1005E000EAE7A59629BFBF9BE13A7C89369C77A9AB
-:1005F000E6A6F309966B81FCF9BD699B1F8235EE77
-:1006000033F936D3F95566736F43BC17FB9E407CB4
-:10061000D7427D1FE46BF37C51374279ED2703DC31
-:1006200040512CF999EF15223CE6EF7D747C5FA8D0
-:10063000777E24730309B0CA972E8DC7762C993123
-:100640006409E7F736C6CF84760FE78C1986F45530
-:10065000AC36D3386C011FE77171EEB136004EBC79
-:100660002055A8F7307CC6EFB12D31879258103F46
-:100670000B5A96BACCD0FE3AAFCDADE2BE71F912AC
-:10068000EBECC17314CEBFBFE17E4BD444BF8E29C7
-:1006900029C5DFE1FCD3C47926FB7B5C63BE30E86F
-:1006A0002719BE2B783E6BFCDCDE067CA53E3F782E
-:1006B0006EC3B8E1AE61D4DE837C38090EE93C98A4
-:1006C00067D2E3563A07AE75FC8B16FB6A05E876EF
-:1006D0004138E76363C4F93B3DAEF1601BACF760A2
-:1006E000B837DE05F5668B739F99DD4EE4EF5BC38B
-:1006F0003D7D70FC1A5B470AAE01CED524CCCF57A6
-:10070000BDFDE3D3E85CD5C933579B476BB8C785BC
-:10071000EDAFB5BE91DF2EFED2C4F2800E163F6A59
-:10072000257ED1887C19D6D51839DC867C83BD61BD
-:10073000AA790BCED99B79CBAEFE1647E6135F693B
-:1007400064AC5B78BD06FBDF0BFC2600E78417F882
-:10075000C0A8CB1D2AA7F7D6C3D1D7219F659E4835
-:10076000A09F5B2E9B9837E41C34F603F8F2201C04
-:1007700047B308E60D39573D2C46C37DCBECB1FF9E
-:10078000DABAC5FC470AFC8DEC3C1AC1EC080FF83C
-:100790006EEF795D07C5BA7E85EB82747B7AF16472
-:1007A00084FFCD5F38CCB8BE9BCD935250AE8179DB
-:1007B0004FC7798FFAC2A49FF737E1BAFCB5CEFFD5
-:1007C0007E85F94CB81F3FD7FCB81F5BF078043822
-:1007D000B6CCCBF1E3BEDFA7F1BC2F4A23B9B625D7
-:1007E00092F9908FB44C8AF7FB5CC80F19977B7B0A
-:1007F000335E1E26DACF88A7F67DAD0052E4077778
-:10080000878BFEEBDE198CE54B93888F345AFCAB5B
-:1008100053B1FF1FA9C4878F0ABEBD3E2670B70A19
-:10082000FDAEFF3C9EE13847592069018E53194EB9
-:100830007CF72693E9DE4976ACE7498C0578EFFB37
-:10084000874AE7C4FA3CC8DB896F4F6F86EFEB2716
-:100850007912C3B19F49F1269A8FCAEAE8BB8BB7D8
-:10086000FBC8C2EBCD14F8FA93C00FEC6BDAF7DEDD
-:10087000891166A4DB4DAEB247683F304FA202F348
-:100880007DB2229D21DF9C5975AB8BE8A5E971E211
-:100890005FD3050E647FD8C0361CE566FE3763F66D
-:1008A000B630C4E7B4CAB0763859D9D1CA65914ECA
-:1008B000683FCDAB06ACC04FD9D4024F975C978A46
-:1008C000E37A68DCDAE681692743E8B9CC0A7C027E
-:1008D000FA7F21CCFB04CDEB401E951F00A1E65B07
-:1008E000D84FC72BD277E3BE621571427F0994239C
-:1008F0001E5EEBB0919CDA133D3422FC87083A452A
-:10090000BC2CE17807798DF28DD307913EB3C9C233
-:10091000E9C6B7278CF05A38D94678EE9C1EBED966
-:100920000AE5F70ABED5383DDCA340BDC697AC7ECC
-:10093000938BF424AAE73B1849FDD6683C5FF36229
-:100940003AD1D33ECDFFDC762C7F2D8CE8A1268AD0
-:100950008F5BF34A92A0378F6B058E7BD04A745021
-:1009600013EE8CA6F2FF8C233A1967F3BE82F000D7
-:10097000BAAB4339A2460B64C4007C8F09BA3A066D
-:100980006D107FBEBA489A376D79C87B1B93B7202C
-:100990003EBD1A2F673F50A9FC98838F7F6C0D1FB7
-:1009A000BFE4A7D5EF32C0DBB1E2F189B3611EC766
-:1009B000EA22486EFC73BD1AD0A250EFE9782C03EE
-:1009C000EA5D587262F806987FDBB28F53903E4A18
-:1009D00096D51661BB92AA2513F1DCEC695F96D41B
-:1009E000C0E60FD9C7275C9EDFE17ABE75793FC4A8
-:1009F0007DBF20A76D0ECACF17B4D66750FF888D74
-:100A0000F31EC5EF175FFE6C3B97AB3B32F03C9893
-:100A10006FE6F421CFD50582FE56A57A8FD1391124
-:100A20001E9885E747444E2BE7774BAE8DCF9F69E5
-:100A3000D9B64F8171AAC35BE653AAFA73B19FB3CB
-:100A40004A204A4923F879713F9D7304A210EE5E53
-:100A50001397E7AA77E8D7857F66985735FE03DABC
-:100A60005537AB9E30C435F36B38FF6AA605EBBB38
-:100A70008278827E084FCCFEE7593F04F8573D3715
-:100A8000301FF587EA98033FB989EA413BB94FD453
-:100A90002BF3723D57CE87AFEF9CA0FF7392FEA75A
-:100AA0006B529FA7F12FBCDC87C63F3BC99F81F0EB
-:100AB000BFA0887ACF59793DA00633CEF3054E4FBB
-:100AC0008F597CA670B20B30A2E7EAB8E6E10817AE
-:100AD000C987600E3E13D43FBB3B89EA4BBEC58A33
-:100AE00019C376D5BB13B770F94CE8B33851A85F7A
-:100AF000F50BDE3FE6711F9E793E498CC7E5692301
-:100B0000FE8CEB4D4E35D17A1F93FC3B52EE737742
-:100B1000C224807FE6064D57FF42A476AF07FA1D38
-:100B2000E8D77F97FD0F4C55483EEB6FC05B5FB534
-:100B3000E39015F7D3B38CF6AB715EEE54AE373E4F
-:100B4000FF7C179E548E371003257D38B91C6E41EB
-:100B500038FFA90B1FF725015FAD4618A406E1B3C6
-:100B60002FCF9B84FCFF02E6F15C88817C0ECA419A
-:100B70001CDE322FE16CA4B3657F9A93D406EDEFAF
-:100B800046F810BF77F7417AEC925F2CA08FE4A073
-:100B90003E5A39F4643AEAA97503E128E85ACF9C31
-:100BA0000D7936DC4F7337E6D9CA42F0D0B863E826
-:100BB0001127C0F9DC0EB31BD972A3D9FF1394A778
-:100BC0001B77A8CD3E46E53684EF39FBEBEF61BDE0
-:100BD000391B63F2515E96EDE76EB87F604508DC25
-:100BE000B377E8F130B8599F1F72409F9F8DBC6169
-:100BF000D8776F9717D0E7871ED1E75907600BF0BA
-:100C0000A0DA389EF68F701F71029EFAFB55377E70
-:100C1000EA6F9F3C6502CA171B55773A94F75F52FB
-:100C20007CFB60C89FDA38DB8D68AE547DF37F08AB
-:100C300038ACFC78FC113C0FCFB2E63F4C003CCC0A
-:100C40006959A7999DB86E3DDDEE33097A7D9EDB2B
-:100C5000D9E6F9F5E557EEEBA5028F2C2B949E8C87
-:100C6000788771EFF4C0846AEA170F3D094766651B
-:100C700011103AC0EC86E6751ACA6D571FC7C7E552
-:100C800041BBC789F0281DC1CB6EAC1FCB4E0C8574
-:100C90007FACF9ED789C77E9C30AC90DA5BFCC7C80
-:100CA00003CF81F63D336EA3F4CE425ABFB4E7CDF5
-:100CB0006D51029190778C701E688376B3FD8A1B0C
-:100CC000E75DB6DC1AE467F0BF8A358679AC0F2998
-:100CD00087F9CF3D70E8AF0AF45FB951DF6E1EF0BF
-:100CE00059E45F555BBFB5867E977AE38D2D9B55A2
-:100CF0005CF76C397FDF2886EBBA915765BD847C41
-:100D0000731233706E4CEB5DBC2315DBADE7ED80E9
-:100D10005D96E27A6BED9A13D75B6B63810898C797
-:100D20009148CDE380EF973644921D6D8E15E4C94E
-:100D30007C4A59583EB6734763BB4FDFE7F6B4DAD7
-:100D4000388EEFDA4D0AE951B568FCC4FCB33C3F7C
-:100D50008F05681D48279ED0F5F9F579D6C4F5AF03
-:100D60001A73E010C2A38AB571FD09F0E891F0038F
-:100D700078D5C03A8FC6A2BC6568CFDC5E1C77818F
-:100D80009DCB4F0B0E7C6B0D2D977AA0D453A57D78
-:100D900077534671388EB342F13C618379AE10F2DD
-:100DA000B56F5D18D1EFCCCDFCBC01393603E1B293
-:100DB0007E5DA21BE58C99209787E1BE99174EF5C1
-:100DC00040DE25BB4C07C8D55B5C58BF3980E7C601
-:100DD000FA475D244783FC4B70E9581BE6DFA2A06D
-:100DE0001CCCE598F5EB32490E7F559E536BB9DC70
-:100DF000D58D5C4CE5AC0F97E33FC2A584C8C15FBD
-:100E0000F4F67E9ADA3BB8AE8A659E443C772A2691
-:100E10006B26B457B1CAB86B921FB60939B203D664
-:100E20008FEB38A914BF650A9147BF16E7C8F031A8
-:100E30009EEDA29E1BEB5598263D740B8EF798C92C
-:100E400089E375C1DBE3C9C0799C5C17968F743662
-:100E50007C0CB7171DCBE3FC3DE23AE6F1E3799A4F
-:100E6000C6FB6569265D9A100EF407FD9C2CE0F622
-:100E7000EAC8EB8AC94E076735F179E33AECA29FDD
-:100E80000AADF83F6FEE663E123E6C1C97174E2E71
-:100E900054B6F079017E213FFC9130B2EF9D14E70A
-:100EA0008F8433D0CD30B2D30B7EB54ED0CB3A0B3E
-:100EB000A703DF3CAE3F05E985113DAC177AD64C60
-:100EC000815FB696CBB5402F1CCE6B1305BD30F6B7
-:100ED00037A487022797B3AF515F02BC0F48EB7D61
-:100EE000A5DE24F1CDCCFE61FFCC2F52BB7FD73ED7
-:100EF0001F9C9F552F3C1AC5A0DE697353BC1BDA9B
-:100F0000D76C5B11E581F494D917E580F14FFBD5DF
-:100F1000427F37F02E4D9376658F5D01FE331FFFC4
-:100F2000E94479E7E189B8BEAFB6591CC81216EC9E
-:100F3000B092FE347FEF3C92B321DFCEF3AB3E574D
-:100F4000317F406F3FAFFAF9A3F14E82B72FC994BA
-:100F500080692089413A7FABC51D40BBF407AA1BBD
-:100F60008601B9B96325CECFD81EE77119F0BDA0AF
-:100F7000592DD5A2AF2C5F20F8CB82BD0F7F8E7686
-:100F8000BD05067B7DA5F05B18EDF593D2227B7D38
-:100F90009A0DFFB89E5D8F7210C0C51DC07D0BF30A
-:100FA000492732E1F6DEC6E71ECF6D477961EB3B9C
-:100FB000514A4ED05E2FFD199DCDE59B5E71F6BC6A
-:100FC0001F2F08BB6D105F9C6F390F28C80340416D
-:100FD000E7698D25107513C0A366B385F84CCDAEB7
-:100FE00067B73F8974F6272B9DE7D5BBDEFCC38D21
-:100FF00028EFEEB1F42AE2CBB02BF1413C2D707218
-:101000003B99C44BD52FDFD49C83F9F725B141FC24
-:1010100054EF39A4B1C157C2716CF321ADCDDE0DCF
-:101020009E9ADBC7939DE8B9AF35DC07A75F53589D
-:101030001FD795ED2B37BF1985F218C209CF258927
-:10104000AF2EFC19EA43FF135FB98EEA3950AFE8BF
-:10105000097FF97876A05EBE3F92C5C0F8951F590A
-:10106000FD4588D7DD8BA3701D9F99EB389D3FBD53
-:10107000221EE5BA4A8B2FDE4129FF5EF9CCFD44E2
-:101080007F7395BA78470ED177A28964065F22AE46
-:101090006FF6C669B4BE39CC4BF457F9B45AEC8735
-:1010A000F44B332BDCD3CD3EF958F0A5CFB600522C
-:1010B000617D9FA1DD06F9C6EF54A1E72EA4F3FBE5
-:1010C0007EB156C61651FE4B21B7ED4E33497B9685
-:1010D0002D545F5CB075552BE2E74CB2A70FCE13D1
-:1010E000E0E013F052BE857ED5DF16F4E1F8614EE4
-:1010F000F370D10ECED1B1F81DEBB75A3C68F70EA4
-:101100006927F4393EFE7D627C987738EAAB9FC54B
-:1011100073B9DDB8BEB001920FB056164A5F3DED0F
-:10112000FBAD0F125D7DF101E72BF3FD930AA9BC26
-:10113000D512E883E5FE435315E20B5616E86E5FC1
-:101140006FB5887DAD2F87799A9550F8BEC6E5D0EA
-:101150003920770542F671906EB4E0775AF7236232
-:101160001D6DE44F937EB8B9821F18D76DE40F1F31
-:101170001AF8836CCF3676EF070AF2051F8D5B03F2
-:10118000E709CA19357FB2D2B951B3CB528CF039C5
-:10119000BBF3F01F66A21EDA2CF7B19EDF1AF771BF
-:1011A000E58BC3BADDC767D7E475BF8FE17BB7FBBB
-:1011B000788D42FCED7FCA6FE1A423BB414FFB75E4
-:1011C0006E0FFCF6DB34E11715F0FC92E544DF848A
-:1011D000858ED2FE841F035C253C8DFCF3F1342701
-:1011E000C1D7C83FE1EF03160247093F499F8C79F9
-:1011F000699C2E3A96742AE9B88B4E8DEBD5C3D1F3
-:10120000587E18F913CCA7F8650BB79FB528246F43
-:1012100043BBB792AEA37DEAA1E38F35BD95D42B36
-:1012200034EF37E49B0DF53D867CB1A1BED790AF7E
-:10123000D3D5AF397058E3FA414057CF5A7F3BE9D5
-:101240001957CA117EEEF7D9FBB9E643BAE8D7A120
-:10125000215FB42C63BE4894770FAA24EF5E7476A6
-:1012600044A15CB2228CCB6D171D221FC3F31DBDA0
-:10127000B595C817E5F78E306E27B958DC111513F0
-:10128000A2A7B7B7A851688F6DF3B3C2EEEC28647C
-:101290001905B8B6B19ECAB9FC56A0DA53EAD11EF8
-:1012A000DAA4BA814C58C5D2BBA228EEA125ED8E96
-:1012B000E9F07DF6DB2A850F5C0CE77605E6F3980E
-:1012C00031EEA09CA3909D62BEC746C2BACA5B78AD
-:1012D000FC41C51A3D7EE7D8A746079CC877F47144
-:1012E000027351AF4B437D4FFFBD8AAD217AAB32C4
-:1012F000EC0BAFB0D31AF745D900B12FF2589EB01E
-:10130000C7909F6391E0D7056ACE1DD301FE178F6A
-:10131000A8CC0AF9CE1695ADC4F5EE54C8DF830EFD
-:1013200001DC6FF3615FE27C247CCEE1BEC9EC5945
-:101330002E39F7D227C37F8874B2EFE3DCA7203DB4
-:10134000B7EF4F19AF627EFF1F533E6657D61FFBA4
-:10135000DA5F67211FBEF89A95217D5F7CEDD72962
-:101360006817BCF88A95F4E58BCBACDCDEFC5AA49C
-:101370001FFD911793B99CDB78F0EBDC363A779739
-:1013800013BED60ED0B8DCD4F2F76368AFEE6C8132
-:1013900055A13CF15A04ED9F05AF84913FFCE2C199
-:1013A000AF8787C64DFC4FD723FDDD1723D9F41730
-:1013B000916E855CBFE0D51B9E457F6EEDDE435A86
-:1013C00039948FFDD57FE722FFBCF82297932E58E2
-:1013D000DA9E415BE386AD373C624944FB1C74D620
-:1013E00017D0B5ED81C9B84FAE840B87C3458003D4
-:1013F000AE0BE052897CBF2778BCF06F0B8FCF67B4
-:10140000717E763D43FF6F102E0AF723B444FA6DC8
-:101410000AAD9F7F7FEDEB5CE437575BEF6F70BDEC
-:10142000BDFFFF59EFD97F5BFC727A5F3CC049F387
-:1014300033D2FD9574BDFF3F28BF3BD24DF3BDC6EF
-:10144000FD1E91FEEFBAFEFF1B7C0FFCB75DEFD5D2
-:10145000F0FDB6C077A403FD8A170FFE770AFB0ED6
-:10146000EB2E4CFF77DDD7FF7CDD525E1FA3BA8FDA
-:10147000E441FD7758F3076E17491FDDCA1DF707D2
-:10148000E3EF483F1ACBF8393DD6564DF2E6D87E09
-:101490006B492E6E64F9E487F0F553C91F43C117F9
-:1014A00000875F27E4F9C99F640EF45B0CF93149AA
-:1014B000B5149F65D41BC7864F284479F4F0529821
-:1014C00017F47338D2E4405FF1B87E6AC09A4B6972
-:1014D0003BA66FA5DC7E04E5967176BDFE74BB412C
-:1014E0001FBAD5A92F2F642FF642FF59618E85F9B7
-:1014F000613EE3B17E88DE3825DD41F0BA95352DB9
-:1015000077D8BF3B9CB6A5733DF94A38FC73B85DEC
-:101510000127A1279B457D23DCCCF6875AB19D99F5
-:1015200081DECBD74BFAB2D47BAF064F26F469B33A
-:10153000185AC2D7DC8FFB4943FA25B848B87F5701
-:10154000784B3C19E12EE12BE166C4433D1AA37AA6
-:1015500007E1DFCF9C67C67D77B390E3C7996378D7
-:10156000BE5FAB5A4CFBD1CFE9FC0BB719E593D169
-:10157000F6188AD764CEE418D46751C4FC3609E45F
-:10158000CE1131C315586F9299F9ACA06FA20F8D8F
-:10159000ECA80F9AFDCB5C380EB7D7269BB95D1A25
-:1015A00076B72F3C9FEA7B34C897FE6C2EF340FD44
-:1015B000D224E656787D161D4BE1684CC5B82C4800
-:1015C000B15D6934EFB7B40FF32FE3F824BC0CC05E
-:1015D0003495FAF5986279FBA87C6AEF33F1F61E30
-:1015E00033C67BA571FB7AC70A2BE91FA5AB9233E3
-:1015F000907F148DD1DB8D9333B89D59A6AB33F812
-:101600007E574DEE04948BCB960F247D480D2FAE64
-:101610007D09EDFDBB23881E4B57DE336118CE6F6D
-:10162000779C1BA77766E29EE1BCFE8CFB3F84EFB4
-:10163000DE1D61F47D6786F7683AF4774671CE7AED
-:10164000093E944D3BAC25C010DEE649E7D1FE379C
-:10165000D1B7E73DF4334E9CAA52FD898CC73DB209
-:10166000E511E48F9EE0FBDC9C00FD4D006503CBA3
-:10167000DBC31C290B61FEA5C2DE7B52EC17359C37
-:10168000795FB4E3BC923352E1FB04D67D1C706AEF
-:1016900086A83F46D988FEA1FE63B93D5ED6C77EC7
-:1016A000B0DF2C018F8BE9DCEE24F30057AA5FB189
-:1016B000DADA9E867ACF6A4B2013D25959632EE12B
-:1016C0003A8B52D9F80D08F70754B685E6DB514A34
-:1016D00076EEC82C27E2C10B244DF1854D2E27DA7A
-:1016E000BDDA473707D03FD0FE84CBDDE8242C534A
-:1016F0003C8ED4B3DA470706A05DBE238FFB198E5C
-:1017000039DA22513F2CB7DB283E47C6F5CC76F0BC
-:101710007DDEBFB16DEDF5A8773EAABAB7407EF683
-:10172000A3DCEFF217BBCDAFA0BEB69EEF53B6461B
-:101730001FC7C31C6EB2F794378DD650BFACB07BB9
-:10174000345C6776A6372603F7D13700BFE118C7A8
-:10175000C96833943695529C891A05FB0EF789D9CE
-:1017600019857AAF310E688188FB91F917C2BC7D6B
-:1017700033004E65D1CEDD482FC7EBD3C8EE3943D9
-:10178000D05D11C631A27FC2DC9688F379078DB88F
-:10179000307E51AC23C34EF41CC6100EED16470626
-:1017A000D277FB8A3013FAD98A9671BA867D66336E
-:1017B00043FB07CD2C1CFD06A7D279BF254BCDC519
-:1017C0009B21DFCFC6CC91B148577944D79BB3BC9E
-:1017D00017D3A1FF533F6223901ECAD7AC23FF8AC1
-:1017E000A40B666E1D1707E39CDAE6CA47BE29E91B
-:1017F0006873D6983C844B173D4C55880E203D9419
-:1018000046F430793896178D090C589483FA680D90
-:10181000F3E0F99EC0DC282774B20EF23F76DA3589
-:1018200027DAB9243F917C03F0EAB1C507E9603BB0
-:101830009CF7660B633B1A6C943EDFE06066E071D8
-:101840003B1B1228BFBBC149697343167D7FB1C1E1
-:101850004DF9BD0D2328BFAFC143F9030D8594BEDB
-:10186000D2504CDF255F02B8101F927C45F2A37264
-:10187000BBD68EFE48C9978C74330BC03B2A9FDAC7
-:1018800013DF93FC0ED761CA0FF22389DF54A5D86A
-:1018900097E0423ED63603F15FA09EDBB51FF5F21E
-:1018A0004ABB9BF474C6F95E27D02BC2254563075B
-:1018B000D0EEDAB8D0D3BECA1584FFDD950A3387DF
-:1018C000D0D53D7561CC1C726EDC5B1FA3CB97D469
-:1018D000FFFECD3ED0FF1DBDBC55487FC77EFCE955
-:1018E000D37F84EF9B7E7C261DF10DF3D8F6388ED6
-:1018F000BB24BC6B1EB1985F6E217F547F6907814A
-:101900003FC44B19E3FB6DD38FFF46FBBBBDDEEA43
-:101910004479F823C413C0F5CF024F65F556825FB2
-:10192000E98A13BBF6E33E5FA2119F2B5B2EF6E123
-:101930006A8067887FF77822237B0448D314AF7EC0
-:10194000FC475A2002FA3FAEF0FDAB805050827146
-:101950007FAB7F7D14F7BF527F84FCE75E9B3D40E9
-:101960007280CF722EB43FA5FE2DAAC7DAFAC5A0A9
-:10197000BD84CEB15BD0EFE8D19CB06EA469C45BEE
-:1019800059D6EB2C11FD264D8A03B74C85F85EB174
-:101990005AE1FE49B33B612AC87D8F64A884C7F72A
-:1019A000D2CDB42F733298885F68A2F349D26BC549
-:1019B0001A6887FBA2294F9B13C287CBC4F7F22C6E
-:1019C00013A5F2FB16D16FDFD579D3519EE88BE5D5
-:1019D0003998E64F47F8F6B58F372B21F8DF986135
-:1019E00016F3E0E3E7E06683FF7B282B559B9D839E
-:1019F000F8E1E7971CA72C2B7F25C67196AD198DB2
-:101A0000DC97355ADC09BDA0DEB6AE7E1C5C5EB04C
-:101A1000F178E59A1ECE0F693F3B85FFBC81D64D1C
-:101A200076DDAADDBFD88D71FC551F5B09BF55431C
-:101A300044FC548E7FF8143234EAEDD5E37EF1494C
-:101A400014F91FF6F2B84A48B93D754925B7BFBA2F
-:101A5000615F75E3FF7963F7C751DDDAA9F7AAD7AC
-:101A600064A75EA07C1385F2835C4FC1C12FE3693C
-:101A70001ECA65F2FF2C38B822BEBB7B37467B7589
-:101A8000973D5BD8ED8CE5467BDDD10CBD1D1B047D
-:101A900044BAC725ED754CCD8946FBFE97E29E47BB
-:101AA0004F7A8DB46F2FD8009DC4C1FE343BA3D1B3
-:101AB0005F75B10779DA99C9CFFBF3C21E7E71A7B2
-:101AC0004A7ACEC59D91B49FE6EFFCD95BE83F9C76
-:101AD000BF55A169D4B256821BC093D942CF318C75
-:101AE000378BBB72DE9DFEF4683C47AA7F11598795
-:101AF0007436AF59F16C83F974DA9CD1BD43E6F3C7
-:101B00008DA0B36A6BF37082B39C3FF2C5DEC17ADD
-:101B1000F35A7E46F663A87781E4A0172218BFFF28
-:101B2000D1F11ECEF3ECC6A16EF4FBCD6BDE339F7C
-:101B3000E4889D110E1481CE883861D98F2D938F42
-:101B400067CBE472CB59E10F3ABB5B257E86F3C4C9
-:101B5000FD7546D1C7E345897651026E2FE2FEEE50
-:101B60001DAC3FAFB93D6A00D4FFECC0EF294DC8B2
-:101B7000E47C609EBD3517CFDFCFF646903FEBB3D8
-:101B8000BD4F8D7F15C63BDF3CBA17EE07D97F46A8
-:101B9000A685EA9FDFA81622BC989FC7BDD4227CE9
-:101BA0008786CE336EB3CF15BAEF78DCCFD9BDBF01
-:101BB0008C32E504F1596BF3DA125371FF9416235A
-:101BC000DF38A538A99E65EF681FDE635AD092C73B
-:101BD000909E69DF2552FDD5A6907A9AC54D4CD1CD
-:101BE0007C60922789E02CEE21897879BC5747F7F1
-:101BF0008A26D9C83F316B88F3AEBB914FBE63E1F3
-:101C000078E9E77C1CE5B759EFC751DCD42297F39C
-:101C10002E9CFFE2DFAA14EF3B6BA8E003096DC323
-:101C2000306EB166B5C23CB0CE7617971B6AFC2AFF
-:101C3000F342BE2FD0830F4031313355F0D34006ED
-:101C4000DE077CB2D2E4D1E0FC3BA6319F8A76A3CA
-:101C500017793C734D2A8F1B7E12E91ED29AD84009
-:101C6000461CF4774EE0B366722003E3246A5E4CB0
-:101C7000A43889731AF75BE277F493D6E4437BA820
-:101C8000D74BC4C362FB9810FAA929733BB19E1AC3
-:101C9000EB76E6D971BE8E0B24C7BE14C9508E35C3
-:101CA000ED8FE4714E3F0FDB620DC15399A0B75E1B
-:101CB000028F6C268F877C4CC4633FB62DD18FFA80
-:101CC0009BACFF98C53B03E180EB40F97D9ED69429
-:101CD00081F2AD9CEFBCA8269AE73941DFF3C29BA5
-:101CE00078BCB4C6E329B13EE6DB2D8CE2B83B9E5E
-:101CF000B3523CC999C4D67D38FE99E706325C7F61
-:101D0000BBCB3FE7009583FC0878AB7ADE1AC0F5C1
-:101D10009C7E8EDB9B4F5BB83C767A528213F156E9
-:101D20003879C32CB2C76CB52A88F7D30AD312B05E
-:101D30007C5B6FB70FDB37D4539C7415B009BC8F35
-:101D4000036921DEAB39BD6D20C5879D7E5BC51B58
-:101D500051F87D357EF7B2A6593F4078ECE0FAD3D2
-:101D600099E7FF3E30F41E9A4CABB6EAE3E0249DBF
-:101D7000C8F246B12F1B059C5765F273AB36A2F92A
-:101D8000B1545A27873BE089F43E38F8239FBA0EB6
-:101D9000E320D215E41B4F025D3D8576851D5CBFB7
-:101DA0003AB3D34271E155FB233D1477B6EA7A1377
-:101DB000C541A85C0EAF3201F82855A8DFAAC95961
-:101DC00074DF17E04D7A6CC736558CC3981DD7BDAC
-:101DD0009DC7F916A1AC48E583A9FCB4C89FDE37BE
-:101DE00098E43AE8DF83F795AA7EF0430EC7299579
-:101DF000EF32B263D888BFD674F9714646E379579B
-:101E0000BBEAA668BC07C8DE5719CA2746385D3248
-:101E1000BBFB205FFD83E05FD5FB9ED6901F548BFC
-:101E2000FB21D5CF2BDC9F0CFB0CEF4956AFBCE957
-:101E300071A2CFF72C2C1DD673AEF96751A1F8080B
-:101E400008BED6555F7353FD6AA88FFD54AF7C273B
-:101E50008AE6B3DD427126463C5E73FBE7D56B6ACA
-:101E6000DF451FCDDC8E72C5FA59EB7F7C0CFD7F00
-:101E7000B133CCEDA3AFCD74AFECACA5790EAEFF12
-:101E8000ECAE30E2476763387FF80CF8A72F13E712
-:101E900071FB4F292EEB7753E83EDC5CBFBE5F3908
-:101EA000EE9BC8B7319E24CE1D8D717DB5EF73FEBC
-:101EB0000678B983DABF6FA1F6C6756C15FCBE6BE8
-:101EC0007FEE8A207A38DB97E3E5ECEE4C3A8FDA46
-:101ED00063389DC37C53F0FEDCD95D9979742F0D76
-:101EE000851BA0872AA1DF9E8D694E718494B75B04
-:101EF000849E16809A4837D806E4BEAA7A2E575593
-:101F0000DBD6507C08C6D50ECFA734608DBD323EDF
-:101F100016E895F4C77E597C7F311C2F5EC46F9301
-:101F2000BCD3AC21FFF60AB9B066A731BE9697FFC5
-:101F30005DEC4F9C6D2F19CF8B74E85328CEA47A9B
-:101F4000F9C27948E7D575EBEEC67D26E75F6D6689
-:101F500085A887B52B2ACDA33D8CDD3B19CF8DD02D
-:101F60007142E4362DABCB9ECA1CF124AFD2391698
-:101F70009EE5E474832726DE135DAEACA1715C524E
-:101F80009FE5EB927002706818D7D73E5A94F7B06D
-:101F90006E394FE3BAE57C52B2B89DA4DDE5FCE9A9
-:101FA00048C4F36F54BA4F7BE99BA1D1B1DDC8653A
-:101FB000C1735D0BC6B7C2FCB391F6D0EE92C9ED0A
-:101FC000A8D5183F0BF3CCD8A88FEBCEDAAACF0F49
-:101FD000DAA9CFE7ECD5E7735BF479F71BFA7C1C41
-:101FE0008EDB9BEBD9787F17F56C4C51CF765AB9C5
-:101FF0009E8D79D4B331453D1BBFA39E8D79D4B35B
-:10200000318F7A36E625BC51DFC63CEADB585E22CA
-:10201000E05423E224110F48EFECE530DD7D9F8B87
-:1020200007F93D0EA003BE6F6668B46F9EC41AA484
-:102030007770BB52DF293627C6FBFA62BDE3B38651
-:10204000E17D8FD695898837731BC59D2E7885C70E
-:102050009DD6E487D9D1BED1B6E2B39518CE393535
-:10206000D67B7B566FBCCFD9B11DE15B5B7F98EE11
-:10207000BDB72D75BE7F0BC71FD95958652CC94DEB
-:10208000A578CEC5F68C4763DC375BA38FF336C6E5
-:102090007D1BE3BD8D7420E5BD4D968E44E4EB279A
-:1020A0009EB3ADC1F99F0813F74FA6DB0CFE7E214E
-:1020B000A7AD55B6E0795D9315CBFD4947403EEF9E
-:1020C000E69C9569F9E5A1248777E5D72826BA1714
-:1020D00097104FE7D06231A714A5A37D15F2B97907
-:1020E000263A372F815C86E35DFA4025F921738318
-:1020F00049B79E81FE701D7D65EF8835DC6BE8ABCE
-:10210000AB3FE440AAE15EC3207D1CFDD4A587500F
-:10211000BF9FB266A8AE5E45F14D06388A790BF9CD
-:10212000B502CE0F0FACEFC9251B5210BF8BE77560
-:10213000B6AF42F9F4A530BA175689FF0FF86225F9
-:10214000F489F7192BF78AFBC0F5FA73B85C9C4346
-:102150009566E673C406E9B0D2C13C31D07EDEA0FC
-:10216000D6DC00EA156FFF7EB82315F58AD17D9085
-:102170001FA5583C14075BB3273D6629F4BB22CD4D
-:10218000FB14D2DDC9A6C33F29C1F3700FD7F74EA8
-:10219000ACF96514C589097A4BB138C211EF9B9B24
-:1021A000787C1CDAC7D4D8205D6C6E8A0B1F600F58
-:1021B000AE374807DF109E003FDC8E53F93AF93DF9
-:1021C0003A9BC57A472B3E94A7E5FA168973850D8D
-:1021D000E0FDDC27F227857E21D7796EE0A15C2720
-:1021E000DEBF683890A2223F37EDDC9E08A9DBEA0B
-:1021F000DD87FBAE7273FA1F47C238551FF2F5FC3C
-:1022000065FDD8A81B50FEDC657117417E55D3B320
-:102210001AEAD95566BF46F195CF6DD630BEF87B28
-:102220003B36D3F7393B4A299E722EAB23FDF394FC
-:102230007C7740C0A3728CB2D101F34E1AC8E5BEC0
-:10224000CA70EEBF03F9E84D7CF7E3D20E250FE329
-:1022500078A616EFD14AE1FBFB82CF18F749E7BB1E
-:10226000530A7A133CF87D8D0F1968F16957EE8B8C
-:1022700029975DB42FA65ECE26BD6C5A6020D77F0D
-:10228000730CFAEFBBFCDD85CE16BE0F2AB540AF4E
-:1022900029B84F5EB3909C5B0BE7CD887CD4AB191B
-:1022A000BB11D2E291AA8E5E178C8BD0D1F374163B
-:1022B000B24FA0BF3B316824243FB5284D57FFAE35
-:1022C000A9D906FACF0F96131FB95177BFAE7689F9
-:1022D000CFA9909C3946FF9DF13841C66ED3B5AF6A
-:1022E000659383F590BEB77239B8766FCC16B4F7A4
-:1022F000559AB8FE34DDCBBFCF3FC0BFB3E94CB772
-:102300000FFBA7B9FFC8CF450BF905A43D7D3AFEE9
-:10231000BB1BF8C349DE753F1CEFC5A33D42777F69
-:102320005AF80371DE88875A6137AACDE276A35A3C
-:102330005FAB86EF0E00FCCD71B154CF1687F191E3
-:102340004D0AD915315D42F192FA382CEC0FE318A1
-:10235000E71F514B719F18CB2BF1DD1FC4EF2B3CB6
-:10236000AE74EE06631CE41AF247CE477B5008DEDB
-:10237000EE1EE814F28A7F655F845F919247F72230
-:10238000771ED230CE6EEAD4983CDC3746FA927C87
-:102390001DF633E9DF9DEF1E26FAEAAC3413FD5E2D
-:1023A0000D0EF33DDC8E6AA4BB39AC55C37BE273E2
-:1023B000F62A6ED447B11EC2A32FD2A3011E71B15B
-:1023C00057C241C2A70B5E7B8D716E1C4E730F28E6
-:1023D000FE40377032CEBB27B8C9F5CCF17AC7239F
-:1023E0005F90EB9A8BF3C7FE61FED8BFF443B01148
-:1023F000C6FD9946F6A9F9C53C3ED6480F932F7302
-:10240000BBCB9D97CD944E2DD2EF476C87FB62DA04
-:10241000E5782AFFAEF4321FE6C9EF3F5D1B9DC889
-:102420007548BE1BDC0FFCDEC0D5DE0532DA1DE7C9
-:102430000E14F1C8C3D8305D3CB2E0ABC6F6C67826
-:1024400064290718CF97D24813C54D76DA5349BE91
-:10245000907CD62BCE0FEF8A2FA99E17EAF1D9C414
-:10246000EBCE1BAFB0FF2D8A4CA5F7185296C6C510
-:10247000239E4AC31C147F5FBA54A5B8E752A8E74D
-:102480000C914F562E4F4BC1F3E2F88399CFF84091
-:102490006E3FFE40AFF81130CE8915965E3667B0BC
-:1024A000DEF115052918A771629D75BABF1B78ADBD
-:1024B0001BC8CF87DA1F1FA5F3ECBCE9DDA8E9D064
-:1024C000BE66C54B5118E65FBD829FE303D3BC4D8A
-:1024D000037BE379BE79BB03E1E7D89C8B76DF4DC4
-:1024E000701C607B293F54AD28E883F245CD3F0E38
-:1024F0003FE3C07BD64B2DF1287F9EFE00CE438567
-:10250000CE33921B4E854117E44F8B243BC2298565
-:1025100079D0AF74CE74E8AB55A817E635670420C0
-:102520005D68F56E1A88F2FF8A67496EA97A686954
-:1025300086AA62BFE9D1DDD94D64BA5D9CDB28BFB4
-:10254000638AF23BC6C9A0FC8E7994DF3145F91D40
-:10255000BF2FD8A097FF5E10FE42694FEEDFD891E3
-:1025600087FE3BDF18965547E7AD3D0BE5F5C54ABD
-:10257000B81BF9D162949530FF4918E9B16C6B2210
-:102580003F6F059EEB6DDC6FF4B5B89F7B7307C89A
-:102590006421F479CB651B0BBD373B9AC5E8F26328
-:1025A0006D89BAFA050E97AEFC7B090375E5B73A5B
-:1025B000F374F9DBB36ED0D59FE01EADCBDF31E213
-:1025C000565DFD499E49BAFC94C219BAFAD38A4BAA
-:1025D00075E5774D9FA72B9FE15DA8CBDF5DF98067
-:1025E000AEFE3D754B75E55F9B4023057A6941BDA5
-:1025F000CB8AEFA7D828FDBEEA3023DF58FC9B74B6
-:102600003BE27BE458535D77F6FD53421E4ACFF61A
-:102610009C407A4916EFE3248B776EBE1AC8F19975
-:10262000C480AA48DF6D4D44FA35D633968F8C7836
-:10263000FD92137058FC7CF43433F08991D7BF3E7F
-:10264000340DF20F3E3F9EE76F7AFD97A9905FF73A
-:10265000FCC3D3CCC0A7460E79FD129627FCE276C8
-:102660009E9FC248F4787AD0DFA7FA70FEB7A4AE76
-:1026700071733B49B7F7CC658A70C0FBDA08074C29
-:102680000340BF98BE0EF48BE91B40BF15C09FDE10
-:1026900002FAC5F408E89FF8FD3F41FFC4F45DD09D
-:1026A0003F317D0FF44E4C5B41EFC4F4770DD329DD
-:1026B000FDA0C14BEDFED05049E9D1863AFAFE515A
-:1026C000433DA57F6EF0D1F7D841D28E1160BAFBA1
-:1026D00001E867447FE201CBB9503FB0F4574AFFAD
-:1026E00064631D6B8B407ED1668EF9D416F43BF685
-:1026F0006C0730B34F43E4B168E6491E44E3F77317
-:1027000090DF487CFF557F6FEA20E03B1FBAA6A40C
-:102710000F55F1DCAA7B13DDB21F8AFBF5C67EBF25
-:1027200012F4F1D7419E4C6C27FDEBD2BFDD15377B
-:1027300013E27F3785C4EBD05F48DC8DF483CB3860
-:102740009F9B6DFC9EB1F473CB781ED95FC1178C33
-:10275000F8C3A8D566925F22CD2C80FDCBB89D51E1
-:10276000B6E63C8C63185563A77BB57DE0BB964FFE
-:10277000F53C2AA45BFF0AF573837EF53E62FE50AA
-:102780004EF32FF8C24B76D85122AE00DBDB78B97E
-:102790000FDB8F42DBC27594127F7A1AEFEDE607EA
-:1027A000FDFC583F82D70F607F03FE06E34505F727
-:1027B0004D726C731EF2EBE4F976BA17BA7174803D
-:1027C000DEB322A313C0658AD49F6C222FFD793B10
-:1027D000FA901D69ACD8EBC39CDE1988CF62ABE3DD
-:1027E0009308DA6769C9689F9C24E4E77F82B75938
-:1027F000D84EC253E245E251E223247E8AF0D01340
-:102800005E8DF834E251E2AFE08B205E10AE57E20D
-:102810002D8857B4E7FEBBE0ED3A337FBFCC5A6357
-:10282000A377D1AE86C77B3BD8F868A8F295D3FBD7
-:1028300015F2CFD2CBCEB7305FCE468F47D4CAF297
-:102840006F7B28F77ED161890EC1F7CD02DF19AE0B
-:10285000EEEBCB7AF23D06D97F410FF5DF0993719C
-:10286000171E7BDEF060FCE3E2020EFF42974AF0A7
-:102870001F9B3397E46466E772A613FE43BE34FEE3
-:102880009B627AD7F24BB6133DB76C7C2FBD7C5A56
-:1028900068F05BDF26E4D2DB0C72A951AE7C71904C
-:1028A000F067BB98EB3BBE57F932E76BD7FA5E2572
-:1028B0007FEF749CD8674982CED29C2A1B8974C44E
-:1028C000BC744EBE81EF9DE6E2BBA03ECADFCAFCEF
-:1028D00094DECE0274BE4E00468CF93B18A37BE416
-:1028E00087232696E0DDB8B143C70EC0EF21EFB2D3
-:1028F000BD87F39BAF7AFFCB11F22EDBEBE39C7429
-:10290000BFF2755B1AC95FB80F2D21F6C0B7E17C25
-:102910001A00E7C76138BF307D13CEAF01B0DE5F6C
-:10292000C3F985F9DBB296326C37DEA98FDB91ED06
-:102930006F778C05C5A467F8DD9EFB723F84EF3B83
-:102940003199E3D07EFE4ECCF5E370BDEFC4F43197
-:10295000F1D4AA513A78FF80EEE443B90F82E38DB7
-:10296000A7F18CF095F034C251C2F75F80E7E5EE35
-:10297000E0F995909F3B6DBF8F4A4845FF5D947885
-:10298000C7F237B92AE44FE3D412315EF5269AE74D
-:10299000A8FA1B987928F96D7210AE35360E2FA360
-:1029A000DD8A6DED630A8DDF3DA379C3B2619CCFF3
-:1029B00036AA746FFCFC8B61648F3AE5E7F6B6DBF0
-:1029C000156F5436CCAF4675AEC1F747D93BFC9D69
-:1029D00033F6CDE194C991DF814EB7F2FBF635B6FF
-:1029E000F1DDE251EA53D12E0FED7326DE8B9472A6
-:1029F000453F2B7F9740BE5FD8939C313C9CF3C1F1
-:102A00007E56CEB7255EA11DE593A09FE1C0E7925B
-:102A10007E1A4EFA45636F4F06AE4FDA113AFB4508
-:102A2000F891DF8E0A64D3BB5C8547548A277E5DAC
-:102A3000C4777D2FBBCE9E0A789A94EE756793BEBD
-:102A4000F98D8A7CE65D58671CDA1F8E0CB593FE03
-:102A5000F81DF5D011D9825FE4B25CDD7D35497790
-:102A6000AA9DE2773A3FE0F7F116BDCDE33617F5C0
-:102A70005629FEDF1817378A65FC14ED8D637B59E4
-:102A8000DC7E6790BFC87780AC0926E60C91B3C3A3
-:102A90009CE1CC19329F88AC585D3ED2DD57573F40
-:102AA0007A44AAAE3CC63348571E5798AFCBF72E90
-:102AB000BE5157BFCFF431BA7CA2F7365DFDA4CA30
-:102AC000C9FA3CEE3B807B72DD4C5DBBFEF565BA1E
-:102AD0007A2E5F95AE9CF93CAD59F1C8C7F95FDA23
-:102AE000EA45BAF2A7A20A79FCB87D0EDD534C6F15
-:102AF000FA81AE3F89DFA4388E5FE6E4E7830FFEFC
-:102B000023BF85C0734182FEDC18EB18FD8683521B
-:102B1000BD5D23E92A71500FFCAB7450CBF474D027
-:102B20008BC7F114BC3DD489728C11FFE88F085D0E
-:102B300027FA2342E182FE88D03CFA2342EBA33FEE
-:102B400022B41CFD11A1E5438FE8F13FAC558FFF86
-:102B5000EB8F8EF9A778BAA14D4F0F463CDD744A32
-:102B60004F1FA3BCE10497B1208F21BD4B3C4D8783
-:102B7000FFE89C67C5D16837B88579E85EC0FF1665
-:102B8000BE5EC816F62381AF2FD99A61F8CEE5C58F
-:102B900052CEC77B3AE79FEBEF7909F9EE09E4F3F0
-:102BA000C3AEB403C87852DF188E4FDFB130E2579E
-:102BB0005F9BDA22F1FCF8BEDA4676F944D6F126BC
-:102BC000BE3FE3E8E53D84FCA80F460F40F993F3D0
-:102BD000EECCC3736ED6AFAC2928D7CCEACFDF13C7
-:102BE00064396DF44E8B9CCFAC241E7FF476B6E036
-:102BF000D36E1E87F46E36B7FF44BA1D14075D9A74
-:102C000023DEA131B3945983910EDF0DCB443A5B9F
-:102C1000CFED5C6D1627C5B5F8801ED14F89F23611
-:102C2000CAC3C9421E6DFC93CDC6E98EE9CEF781B9
-:102C30007E9B2E0E377B8743971FDC9CA0AB3FE427
-:102C40008053579E17C8D2950F3DE2D6E587B58EC3
-:102C5000D0D5BFFEA84797BFA1AD5057FFA653C51B
-:102C6000BA7C12EB7802E1A9E6A4123CFA2BC20E60
-:102C7000E0E47899F5FD78BA4F23F5081997ED153A
-:102C8000746CD447FA6B5E8AF36E4C646EBA0F6252
-:102C900013FA20D3EB295E11572DE579E6D3C755FA
-:102CA000CB78EA2E7D46E82F529F0889A7F6E0FCF4
-:102CB000653C7517DEC5FB9246FA74E408BF906167
-:102CC0001DFD357EFFABF1018DEEB1C8F919E73579
-:102CD00043C4036EB375FFFE504A0EB71B6C4E2DF6
-:102CE0008ECF817ACFC0F144F0BC623C779B0FE07D
-:102CF000DBF823CDBDCC79F5F1660DE1EB29C17789
-:102D00005573E89D4EBAB726C7CD15E3F6CA55BA36
-:102D10005DDFAC681EDFC5A235BA77D1F3781CAE93
-:102D2000091A5B4EEF24897B08F7AC695E9B094565
-:102D3000255A9385BFABEFB7A09DA8680CC88179D1
-:102D4000C027B6ED5B6F07F9E7997A33D97D86E541
-:102D500024DFE91B10BC57D21FF434A49322C43FD4
-:102D6000F4FBFC601EEF7C670E5F5F81FA4DD77D40
-:102D700000AB8ECF73FDAF1BBA237A94EBF8BFBACA
-:102D80001F20E9D70827A95F33717E0D10F392F059
-:102D9000EBB29F08F8C9FB19CE8596E22D76BAE70B
-:102DA00051887165127F070773BA5C2DE081F59039
-:102DB0001FF554AF40CD89463B782773463BAE6242
-:102DC0000FFE3FBA3741F0EFE9BE574F7CE20AFEF3
-:102DD000D0C3FDAF9EE893FEBEC33DB0103EC1E33D
-:102DE0007D043EFC034CE4575F15A9DFC7FB73B8B5
-:102DF000DDA544EC2738B7ED797A3EC1D0AEDFB817
-:102E000042157C624ED7EF4FE0F7D92B2C245F336D
-:102E100056FC18C619FC65BD85E262477918C931B0
-:102E2000651B15FF6605CFD1910938FF529FFE3C07
-:102E3000BE85B957A2FFA37CB5FEFB5C3BFF9D8A14
-:102E4000D9C6775384BE3EF72AFAFA8E1C718EBB20
-:102E5000999BE42EE1FFAF146D8C7257A79FFBCDB9
-:102E600050DF56B9DD89E2C6E4F9EE44FF4DC87B78
-:102E70002000CFF02C3CC7979BBB8DE7EB82670F00
-:102E8000F10AE7EC225EC1CEE3333AF78671FFA682
-:102E9000F42B89FAE77C97A81CEB636FE7F378DCE7
-:102EA00085F42719FD559D7613F95B3AF746927F15
-:102EB0001EFD38D14007674C7BE247B882F3F3B67A
-:102EC000A93A3F8831F52E7D89F4C58169DEDF217D
-:102ED0005F3F6B76DBDC907FD0FE3ABD1F5524EC64
-:102EE0005EC6F976E95D23F9FB2E9D3E2ECF761660
-:102EF000F27738802F32DC47320E6112032D15D263
-:102F0000D2C00D349FEFEACF9972398FFB312FDF9A
-:102F100044EDBDAB6FA07CFFE56B17E23D98698D7A
-:102F2000732DE8C26E7B62494138346D4BF62F0B2E
-:102F300047BC8D56BAB5CB5F12786B33C4D7CBB4D0
-:102F40005CF0237C438EF3251187B454A17DB048F7
-:102F500061322E89F8B8CC5F6A12F9029E5FBC829A
-:102F6000E7DBC4FBFADB851D05D78D29AE1BF5FE1B
-:102F70009DC2CE82EBC614D78DDF916F611EF9160C
-:102F8000E6916F611EF916A6C8B7F07B192B4EC9E2
-:102F900053B91F6A5CE8BEBB6C63E342F60BFAA14F
-:102FA00042F3E8870AAD8F7EA8D072F4438596A3DA
-:102FB0001F2A348F7EA8D0FAE8870ACDB311B7064E
-:102FC000F3C8E73C9374F92920E78F0BD9DFE88732
-:102FD0000AED1FFD50BAFEBC0B75EDEF66F5BAF6B3
-:102FE000E8870AAD7F6FBDA2F353DD2BDE392DDFFD
-:102FF00010C7E9C759EC1E0C74F05F11FFB8DF92DF
-:103000008A786E99C7F5B27037C7735321C7BB89E9
-:10301000713C77CC203C2FD178BE80C7271BE907B5
-:10302000FD3DE32CDCDF8329FA7B30457F0FA6E8EA
-:10303000EF1997CEFD3D98A2BF07BFA3BF0753F47A
-:10304000F7608AFE1E4CD1DF8329FA7B30457F0F63
-:10305000B6437F0FA6E8EFC1EFE8EFC114FD3DF8DE
-:10306000FD18FA9D2CC179A11C3F40A73F021DEA23
-:10307000F447872E8F727C687D94E343CB518E0F8B
-:103080002D47393E348F727C687D94E343F3753964
-:103090004EDA5F28CF87B643793E343FB8C9F7266A
-:1030A000DACE266CBCF006A66D91CA330AB08C85C8
-:1030B000BBF6DE897EB9B63025250638A74579E509
-:1030C000CE7190F78AF8BF5CD661427C7BC57BEA03
-:1030D000DE00A378CBC17F4DA4F217C4BD7EFA03F6
-:1030E000BCE7ED65F4BB24D25F2CDBBB9943C55430
-:1030F000D60FE6BBAF671C5FD623FE19320FBC01AB
-:103100008CF12A794BECF918EFB9DDA4509CC4F688
-:10311000653C4ED84857DB045FDA6EDAF33ADE03DB
-:10312000E92855E83E7086991DB1E4239CEAF2F146
-:10313000FC5D3B3846ACABEE46BC6F22E72DED9B09
-:10314000C027E8FEDCC88ED6B1D1D08FD7379A7EA3
-:1031500027A548E37203B6437D32DBA778B684D057
-:10316000F7E38339DFF4FAF8F83FDF3491B70BE780
-:10317000ED7EBE298AE03871B942F1522377320FD1
-:10318000DECFF58B7967EF0CA8385EE9723E9EECD6
-:10319000B774630ADD5B2C656DE312C847A230E4A7
-:1031A000DB126EB0BE37707DA0361C41FBF4B5DE7D
-:1031B000FBB9F9BA98028CA3632D8CDEB19C70DD4B
-:1031C0006F75EB25B40FA77EE95CCBF429F45EF0B4
-:1031D00044DFD265A86E4CF02D7CB337D6DFCADC55
-:1031E0002E271D45742F56CE6790678F098E459602
-:1031F000C35A4D610AE29B1D8E0BA11FD8F95311D2
-:10320000DF796E0BBDDF3BC9ECB0D0FB113DC49F35
-:103210005CB2CBF81383BC608833695C723405ED13
-:10322000C98B224D64FF5DF412FF3D00EF0685F867
-:103230009A94834A459CDAA5E56FF6BE0BE1BEC7BA
-:1032400042FDC9F893DA347F8A09E3EAFB6ECE8D3A
-:1032500055490EF8FD6094037CBFBC7304D65BC176
-:10326000DFB1BCB47C5A74807AE2FE9A0A01AF0ADC
-:1032700011C7548A0F7AABC1DFD392F73B5813972B
-:10328000F7A43DA7F43743DF42FC963E2DDE955E62
-:103290005D4AF7B28D7144F3965B28EE689E412E2D
-:1032A000AC167261F555E4C2B3830D72A1FCBD1476
-:1032B000D186A9FDFE80717BF25E628985EFFF9267
-:1032C0003D8CECB0254BC79AE81DE49738DD942C73
-:1032D000E5F24DC9CB1EBA5F28E5C5F7851C33F969
-:1032E0007212C1FDF7426E9986F19500DFA2B630E9
-:1032F00011879548E95D9779BCE5643BE7036D0765
-:10330000F93B109D3E2B97A7DE60FC1D33035D4EFD
-:1033100032FB4D78E1CE3D12E812F213500E82FEE0
-:10332000A6A35C148774EE2AA0F8BD4285EEBD18F2
-:10333000E9BCC852F726C687166D636E1F0BA573CE
-:10334000A05FECCFA7D0FB005EA1D74AFA35D2FB35
-:10335000AC08618FB2737B53975D0265547CA4DB2C
-:10336000177517CA8DB3D0B7D797130CC69D45E60E
-:10337000F0F2F4DD51772D4725A7073B85FA038D41
-:10338000E0E195EF20F46037407B01F2C97BEECBA2
-:10339000D3CA42F8E49743C6140CE91DC47759D741
-:1033A0007DBF1C7A1774D183E9F47B383DC9C3E52E
-:1033B0000057DC17B3A2DBEEC75F661B97CB3CE37D
-:1033C00046E0EF0B32F9087900E308678AFCC2DCBB
-:1033D000EBFF88BAEDAC089EF7ECEE7717C685D404
-:1033E000DADAC623D92DC8F116E23DC6207F2AF6C7
-:1033F0002429C89FF202A813CEC810E78FC11EB1BE
-:1034000030D7C9D769B04B94E770BE2D7F17E5F868
-:1034100083FB77E37925E77FBC87DF6198976BFAB9
-:103420005FBD0761BCFFF0FDBEDE99B9D0FF63262A
-:103430007E9FBFAFDAC4847D88FCC2925F30F10EFC
-:103440004610EF1E7A47B7F141C5116A9FF2AE569A
-:10345000F83DFA1EEC382CABE3896DD06E568346EE
-:10346000BFE3B72983D3CF26A01FFABD14ADF54D16
-:103470009B2B08C78FEB1FB1D0EFD2B0403ABEBF35
-:1034800033B32ECC8DFCF8CB21C575B9C3F0F7480A
-:10349000DCC4870A30861CCFF35EC58B713DB56BEB
-:1034A0000E3D83EF092C6871D1EF95941EC85B899E
-:1034B000EF9C7C39C45B8FE5A57607BDA7317F798A
-:1034C0000C9D5FB3FA887BA1AC83FC6C12FE4DC2ED
-:1034D0007E75AB9B89DFDB12F71D80414ED2D5EBA9
-:1034E000DE8E27ED84463B83F17D899EEC0BD29ED8
-:1034F00080F6032DC4CE28ED1396ACE333506E282E
-:10350000D1F4F712657A2857E8B9420F9CDD756E41
-:10351000E58CEF83F2F13AC541EF4DDA9D77DD009E
-:10352000F98A23168CEC6445B14E0DDF1FE800FCD0
-:10353000627C7419EC57E43325224EAB62C30DB4A0
-:10354000DF2AFC9076F30EA74CEF5E7738F965A47E
-:103550009F8087FC96150E8F161BB2EFCB9B14DD58
-:10356000BB0332BF2797DBE34A602B23FCEEB9CFC6
-:10357000A5E1DB3E25204660FCDFA15CA7CE7F0CE9
-:10358000F5281EA42895BDC5DF818779BBF878F999
-:1035900021FD9735F17BD3320FF549FE793537920E
-:1035A000F057EA8075BB3075D03C010E04A78EB58C
-:1035B000D09F93C6217C9407FC16D4B74B300E05E0
-:1035C000F2331D7E0B8E53B69CBF63E25DC3C7F121
-:1035D000AE8ED106A37C647668C9083FF13BAD305E
-:1035E0003F92232B002E781F0BEFBBE1D962844F53
-:1035F000A9986F45530CBDA310FCBECE82F898D19C
-:10360000C3BB08E705DD962D1F4DF7D72BCC1EBA9F
-:10361000E7E015F0FDCBC2B087D03F3063FDE31685
-:1036200017E43F11F47B5EECBBA2D4403ABD57B423
-:1036300030CC8DF39CE168A2F575C1F7518087828B
-:10364000EFDC14137C812E7C18B757B15E8FCFE06E
-:103650007C387C2BD697D27E9B63F66A8ED0796CB1
-:1036600038948EF7AA66C0FEC6772598C34BF72517
-:103670003F7DF4AE145A27CC13E11AE9768EC7F7D2
-:1036800087804EF83D18B11E79AF5B8E6719C2EF87
-:103690009D5A8670FB59CFFBD243724D23E017ED44
-:1036A000DE3DED4B0D19378CAB55F0DF9130EE530D
-:1036B000B93FE5BE94FB54EEDF672CC5810425C8F5
-:1036C00067E09CAD7BB11B38150CE1789829F00AB6
-:1036D000707D23F49E57EE10BE9F4B52F5FB1DFBF1
-:1036E000C37EFB0EE1782F191348C77799647D39A3
-:1036F0006E492C6F87748FF4D6578C87F517517DE0
-:10370000938E5F9477F18B9D2BE2915FEC51B81F04
-:1037100074EDE1E4EFA3FCBA8BCBAF676BB6CDC71A
-:10372000F39299FD29A1EFFBCF063907F9C41C716B
-:103730003E5704BAE7173B33BCD94342F673C5CFB3
-:1037400076657839BF0920BFF9F3AE573FBCD11970
-:103750003C4FE57ACA56FFD6526A0F859F22DE1D7E
-:10376000E9A4FB78E576CD89F1CEE5CB4B89FFB2B4
-:1037700004900B9590F833035D942E57E81E597909
-:10378000FD70BFFABFC8A7CBD74CA2770F24DEE4E9
-:10379000FB2CF27C95F39F28F0356908DF87330511
-:1037A0007DCFAC1CAD25F622B91BC32CD90CF17D05
-:1037B0004685FE7B17DEBAFCD7392B71BFE0FD22B0
-:1037C000D24FD658B8BD6F27B73F9E5DB4FFBD3B03
-:1037D000A1DE99C736A730558F379453E70879751E
-:1037E000AEB0FF7583B73294DB647EEE268EB7F2FF
-:1037F000DDBFF904DF132B4915FC6E2D7F07A0AC4C
-:10380000790FE171C6EA751617CA75435CBAF736C7
-:10381000CAEBF21C68579EB97AB305F9C4A2211C01
-:103820008EC6FD5022E284259CF15C5242FC1BB204
-:103830003EF2477CFFFEBE85615118CF23C7794A0F
-:10384000D07D795D4C2C8E575E57FA13D487E4797E
-:10385000605CE78930BE5FCAA03FDCB72746BB5338
-:1038600016E504E55963FD47041D3E65E1BF53932A
-:1038700014D1FC1CC5352C087723FF1830A0CD8F40
-:10388000E3227DE3BC3513FF5D9B01356D9FE33C77
-:1038900040D4A6B81A4CF17D2C14BDE321BFC5C499
-:1038A000EF6FA5AA3C3D20E003E5012C67BDDAE8F7
-:1038B000F73542E26675F4ABB1ADF4FB895A2F4699
-:1038C000EF9B497A95FD487A95F4DCD3FA9AAF716B
-:1038D0007D275C1C9E9AF8DD946B5E9F95FF8EAEF3
-:1038E0005C979C1FC8F01E7ADFE38783C9DE736292
-:1038F000A93B05E3267B5EEFFA82F86ED66B5CA7E8
-:10390000DC373216BECB9FD5C4FD0E271438DFA09E
-:10391000DD89856114DF26D7F55DEDE11F0C899502
-:10392000EFF947A29C59121EBC2F8FF03B56CF7F58
-:103930005F577E9772817C674EF2EF9375E2DC648D
-:103940006D6B717FB3FA347AFFE458D389487C8F6A
-:10395000E5C4683E3FD9EE3E0BBF9FCC223527DE43
-:10396000138BB8EFB7057DD03FB4DE95A740BB7B86
-:10397000EA871EC3F7C7EF59DE87F4FBD976E74A1B
-:103980003C1767FB5CE40F8E589FF729BEA3377B7B
-:103990007936FD6EEF7D0A2B267D52E8097358D7E4
-:1039A0001FE90973055F9B8BFC12EF4BD51FA677B0
-:1039B000F3E6B8C3F2F07C9FBB81EB094526B61A4B
-:1039C000FD89FD1B8BC7231FEB7842E1BFFBBC5178
-:1039D000FF0E577666F1453C1F8CEFDEDD6769F61A
-:1039E000E03A18C82368779A6D2FE672BDE09FC74A
-:1039F000D6B7D3EF6522BCE9F7720CF69BFE1ABF6F
-:103A000047DC1169227B1CE0FD7DFC3D327C6FDDD3
-:103A10004AE78DDE7ED3FFC723E8F7DAE43DA10A4B
-:103A2000E177FA7F89106A7A0080000000000000C8
-:103A30001F8B080000000000000BCD567D4C535733
-:103A4000143FF7BE7E53E8E31B44B08060B7157C9B
-:103A500005257126FA066A4C66B4B8A13451A851FE
-:103A6000192A65CC2C019739AB9DCE68B6B10415E7
-:103A7000892C8529FB675B4A249B666C6924CE6C84
-:103A8000928CC83F266CA4240BA299A16359906420
-:103A9000D39D735F9B1A3F92FDB9F7CF79F7DEF3A1
-:103AA00075CFEF77CE7B506FE29005D06C02F1ECD2
-:103AB000ED7B2D0BAC28BB25B05702F4D0E62A8055
-:103AC000135D35591127C09E4FD69FF597011430CD
-:103AD000708750EF375DA4165600CCF465A71D65BE
-:103AE00078EE0B94029EEFE9FBA080E44C9FB93E78
-:103AF000887AEBE4DA75A919004D17525D921DE042
-:103B0000113D6BD18F82469900FB7D35D95004D091
-:103B1000F270E453B918E31702C8E8F7AF5052D077
-:103B20008F2A2D47AE14481C40317A7395950007B3
-:103B3000F8F0B655E8E71E0B0EE40A7D7BB66C4D37
-:103B4000F87D524E1F01B01B017CEFDD167EEEF3B7
-:103B5000D1CD1EB46FF15D4E213F07CE8C57C9B851
-:103B6000FF42B1B744C924BF7D03B28477EFEE2B87
-:103B700077E33D4A1510796E4A736FF3605ED11F8B
-:103B800025A5DFFEFC78CD5730E9CAC47A67D06638
-:103B900000AC9F370C0699A40C86349433127484BD
-:103BA000506E2A82C6ADD6C4FEAA585D666C9D05CD
-:103BB0006EDCDF3770AEC08EF26EB2B6DE31B0FDB5
-:103BC000274841FD8B4603E1E5D5814141BBDD7EC0
-:103BD000A6065142731A406E227E8D92048075DBD8
-:103BE000D78D49A527F6018262FFAE0E36521E4BD5
-:103BF0000251D75B282774E1BD84EB449B59F11730
-:103C0000124E7691CF44A7B481F6FD6F332861B48C
-:103C1000BE9CBC14E337D8A08DEC935784C21C71B2
-:103C2000F60DA556481AA504BF5A656DB15EB26E71
-:103C3000C8C3F383834C36A2CB8357AF6F006D0D9F
-:103C4000C09E5FCFFD0F5683FDB1BCF70F0D1AEC80
-:103C500018AFE50BBC2FC66F090DFEB008FDB45EB2
-:103C6000D955A9C5ED04A8C23CE815E3B40E6975A1
-:103C7000F10D4D19763B137E7639D24EE421B64DC7
-:103C8000A135DBCFA0DE2EC2ED6580C3E515F5477B
-:103C9000979294C5BD41172D7027039C72DC327832
-:103CA000C9CFFB317F8E5B278AC47D6BD3E1313E68
-:103CB000BCA1E8855DDC1EEB21ECC23ECB49580E71
-:103CC000A0B65A7524033E6B0AC90B6DDCA1C3BABA
-:103CD000AACCA24858EF0E534A39D800E6CD9A1C18
-:103CE000B668B29DBB079B30C5793E6606E47DBBD6
-:103CF000D4C948AE75B631AC34C819DEC3C4DF1CB4
-:103D0000083110850833CA7BF6BB3B95147FCD92F2
-:103D1000C89F8029E9995ABF0EF9715C9105FEE0B0
-:103D20008C5412CF33AF4123F1AB570F27CD15740D
-:103D30006F376C2D232FF84EB82FF0E025CC6F98FD
-:103D4000853F23FFF1FB5E25BEA21FB7D17A9261AA
-:103D50009E06BBF723CA630BD397B93861209590B1
-:103D6000FF59BD760E9DE75413F2A25AA305E473E2
-:103D7000F00352D6B028C74ABC66AA0A1D18FF989D
-:103D8000F3DA6EE2C7E9A8098C183710AB4775D48F
-:103D900032C5502F7FD1460EE5A86FCF801D687FBA
-:103DA000CDC9FD46CCF3349882A40FA6F56AC4A110
-:103DB000C57884F3C5C0CDAAD01FBEB1C050E649B6
-:103DC0007F8CD8503FAF9D2901D469989BEEFD1997
-:103DD000E50E08BAA8AE5B32BC9FD3BC999CDB3819
-:103DE000E5457C4FCB2113F5193D8FE73F7C6821DA
-:103DF000258D27F29A8D4E7FF9CD0A922685A15DF9
-:103E0000F5B01436963F9DCF6C8E5D4771502FCC28
-:103E100049DFCA838C91FEC86DCAAFDA640D4B29A5
-:103E200064A7FF3D624AD8C1587EEAF44B20207E49
-:103E300094079015D0705B13EBC3382E37152E7096
-:103E4000B919C3275E3F913CF6C74193D61FDF5B8C
-:103E50000776127FE2FDFA666C7FEE41918DE6CB2C
-:103E6000DC70B10D9CCFEFCF719CAFB00CE75CA1C3
-:103E70003A4EB8E3A39AD07F5DAC3E8837905F2975
-:103E8000E6B72E56A73A2BD7EAF2FA137589F12432
-:103E9000CE8378DE719CE3F8C13B63D76D8502B7B2
-:103EA000B28F41E0F52BC59F5C183D8E6D058B24CC
-:103EB00075CA5BF87FC42B6C5E86BC8E9EE14A3F60
-:103EC000F19F0A5F21A4CAF17EE000310F1A248B12
-:103ED00072EA19F3C04BF36039CD834ED1E7F33C5E
-:103EE0007A9D339A076D629D03D1A33A5C4FF248E5
-:103EF00032E51B3123EB5116BA8AC43CCAA38E2E7D
-:103F0000D670A2BEEE3D94DC7F0AF5034C3D6F42B5
-:103F1000FB803ED6EFFBACC14BB83F1BE47E3DC6F9
-:103F2000EB4A0D9E6FC2FDAEBAC58A1FEB340B3152
-:103F3000BD668B980BAB3917EBA8272BD85F48FAD7
-:103F4000D8D778CF2ECF8BE23BFEF543744EF72EB9
-:103F500001EDDC05A5DD745EEB10FEBE8DCF990F83
-:103F60009385BFAE5A35D722CEB338D91F4FF7E667
-:103F7000B93209574D0F7F04845E4F8F9A4B78F406
-:103F80006C3508BDB3CCEDD94B7ECAACCA25F41B49
-:103F9000F158BE1AD0E00833DC9FECD0EE1BE7AF3F
-:103FA000A7549B834BFC53E7E93FC45F0D8E36E477
-:103FB000FD24F17079021FA6221669099CE27CF4A7
-:103FC000EB11AF0C0DAF63EC69BC326278B10EE45B
-:103FD0006D0AE11612F59FE71A0EED124492F04EAB
-:103FE0001257728C282732BC55DA3DC772E9BCC122
-:103FF0001859D9E9243CA139F48C3E7CC5A5F53982
-:10400000D0571479DE18E379639C8FEF3EC1C7C89F
-:10401000E2D4E9A4181FD1FE178BBB86E2DD67E36B
-:1040200055B439FA8F54FFAC389B5CDA7FC99CD108
-:10403000FB2AE9C3C56C2EE688ACF5F5A8EB4E3E2D
-:104040007D67E0EF91C5F4DDE94D776F263DF3D252
-:10405000A8C14BF5CC8DEAE93E939E7BF9F43FD3A2
-:10406000D87143F4CD7FCDF35F8E8A94E2B00A001D
-:104070000000000000000000000000180000000028
-:1040800000000000000000400000000000000000F0
-:1040900000000028000000000000000000000010E8
-:1040A00000000000000000000000002000000000F0
-:1040B00000000000000000100000000000000000F0
-:1040C00000000008000000000000000000000000E8
-:1040D00000000000000000000000000000000000E0
-:1040E00000000000000000000000000000000000D0
-:1040F00000000000000000000000000000000000C0
-:1041000000000000000000000000000000000000AF
-:10411000000000000000000000000000000000009F
-:10412000000000000000000000000000000000008F
-:10413000000000000000000000000000000000007F
-:10414000000000000000000000000000000000006F
-:10415000000000000000000000000000000000005F
-:10416000000000000000000000000000000000004F
-:10417000000000000000000000000000000000003F
-:10418000000000000000000000000000000000002F
-:10419000000000000000000000000000000000001F
-:1041A000000000000000000000000000000000000F
-:1041B00000000000000000000000000000000000FF
-:1041C00000000000000000000000000000000000EF
-:1041D00000000000000000000000000000000000DF
-:1041E00000003328001000000000000800003330F9
-:1041F0000010000000000002000033280010000042
-:104200000000001000003A780000000000000008E4
-:10421000800000000000000000000000800000009E
-:10422000000000000000000080000000000000000E
-:104230000000000000003120000000000000000825
-:10424000000033600001000400000001000033683A
-:1042500000000000000000020000337000000000B9
-:10426000000000080000337400000000000000029D
-:1042700000003A70000000000000000800003A4012
-:10428000000800000000000800003D880040000019
-:104290000000004000003A50000800000000000844
-:1042A00000003A60000800000000000800003A88A2
-:1042B00000C800000000009800003C1800980000B2
-:1042C0000000002800003C58009800000000002872
-:1042D00000003378036000300000036000003EB04F
-:1042E000000800000000000100003EB100080000CE
-:1042F0000000000100002008001000000000001075
-:104300000000200000000000000000088000000005
-:10431000000000000000000080000000000000001D
-:10432000000000000000000000000000000000008D
-:10433000000000000000000000000000000000007D
-:1043400000000000000000008000000000000000ED
-:1043500000000000800000000000000000000000DD
-:10436000800000000000000000000000800000004D
-:1043700000000000000000008000000000000000BD
-:1043800000000000800000000000000000000000AD
-:10439000800000000000000000000000800000001D
-:1043A000000000000000000080000000000000008D
-:1043B000000000008000000000000000000000007D
-:1043C00080000000000000000000000080000000ED
-:1043D000000000000000000080000000000000005D
-:1043E00000000000000000000000000000000000CD
-:1043F00000000000000000000000000000000000BD
-:1044000000000000000000000000000000000000AC
-:10441000000000000000000000000000000000009C
-:10442000800000000000000000000000800000008C
-:1044300000000000000000008000000000000000FC
-:10444000000000000000000000000000000000006C
-:10445000800000000000000000000000800000005C
-:1044600000000000000000008000000000000000CC
-:10447000000000000000000000000000000000003C
-:10448000000000000000000000000000000000002C
-:10449000000000000000000000000000000000001C
-:1044A000000000000000000000000000000000000C
-:1044B000000000000000000000000000000012C822
-:1044C00000800000000000800000000100000000EB
-:1044D0000000000000004000049000000000049074
-:1044E000000019C800000000000000080000494852
-:1044F0000008000000000008000049280008000033
-:104500000000000800004938000800000000000812
-:104510000000200800100000000000100000200033
-:10452000000000000000000800004010049000405F
-:104530000000004000004998000800000000000151
-:104540000000499900080000000000018000000000
-:1045500000000000000000008000000000000000DB
-:1045600000000000800000000000000000000000CB
-:10457000800000000000000000000000800000003B
-:1045800000000000000000008000000000000000AB
-:10459000000000008000000000000000000000009B
-:1045A000800000000000000000000000800000000B
-:1045B000000000000000000080000000000000007B
-:1045C000000000008000000000000000000000006B
-:1045D00080000000000000000000000080000000DB
-:1045E00000000000000000000000000000000000CB
-:1045F00000000000000000000000000000000000BB
-:1046000000000000000000000000000000000000AA
-:10461000000000000000000000000000000000009A
-:10462000000000008000000000000000000000000A
-:1046300080000000000000000000000000000000FA
-:1046400000000000000000008000000000000000EA
-:1046500000000000800000000000000000000000DA
-:10466000800000000000000000000000800000004A
-:1046700000000000000000000000400000180000E2
-:10468000000000180000430000400000000000404F
-:104690000000430000400002000000010000430150
-:1046A0000040000200000000000030000040000058
-:1046B000000000408000000000000000000000003A
-:1046C000000030000008004000000004000030043A
-:1046D000000800400000000400004B00002800001B
-:1046E0000000002800004B500010000000000010E7
-:1046F000000038000080000000000080000038004A
-:1047000000080080000000020000390000200000C6
-:104710000000002000002008001000000000001031
-:104720000000200000000000000000080000510808
-:1047300000080000000000080000512000080000F0
-:1047400000000008000051300008000000000008D0
-:10475000000051C00008000000000001000051C12D
-:1047600000080000000000010000394000100004B3
-:1047700000000004000051D00030001800000010BC
-:10478000000051D800300018000000028000000036
-:104790000000000000000000800000000000000099
-:1047A0000000000080000000000000000000000089
-:1047B00080000000000000000000000080000000F9
-:1047C0000000000000000000800000000000000069
-:1047D0000000000080000000000000000000000059
-:1047E00080000000000000000000000080000000C9
-:1047F00000000000000000000000000000000000B9
-:1048000000000000000000000000000000000000A8
-:104810000000000000000000000000000000000098
-:104820000000000000000000800000000000000008
-:1048300000000000800000000000000000000000F8
-:10484000000000000000000000000000000023E85D
-:104850000080000000000080000000010000000057
-:104860000000000000002008001000000000001000
-:1048700000002000000000000000000800002DA043
-:10488000000800000000000800002DB8000800002B
-:1048900000000008000024E802D00028000002D038
-:1048A00000002E58000800000000000100002E59F2
-:1048B000000800000000000100002D90000800002A
-:1048C0000000000880000000000000000000000060
-:1048D00080000000000000000000000080000000D8
-:1048E0000000000000000000800000000000000048
-:1048F0000000000080000000000000000000000038
-:1049000080000000000000000000000080000000A7
-:104910000000000000000000000000000000000097
-:104920000000000000000000000000000000000087
-:104930000000000000000000000000000000000077
-:1049400000000000000000008000000000000000E7
-:1049500000000000800000000000000000000000D7
-:1049600000000000000000000000000080000000C7
-:1049700000000000000000008000000000000000B7
-:1049800000000000800000000000000000000000A7
-:104990008000000000000000000000000000250072
-:1049A0000040000000000008000025080040000052
-:1049B00000000028000009C00120001000000008CD
-:1049C00080000000000000000000000080000000E7
-:1049D00000000000000000000000402002D000287D
-:1049E000000000080000300000000000000010007F
-:1049F000000050990000000000000001000050B0CD
-:104A00000000000000000002000045A00090000827
-:104A1000000000088000000000000000000000000E
-:104A2000000029600008000000000001000029616A
-:104A300000080000000000010000297000080004C8
-:104A400000000002000029780008000400000004B3
-:104A500000002FB0000800000000000400002FB488
-:104A6000000800000000000400002FC0000000004B
-:104A70000000000800002FC800000000000000082F
-:104A80000000300000000000000000100000504056
-:104A900000010001000000010000500000000000C3
-:104AA00000000020000008080010000000000004C2
-:104AB0000000080C0010000000000001000008B712
-:104AC0000000000000000001000008B60000000027
-:104AD0000000000100001000003000180000000479
-:104AE000000010040030001800000004000010084E
-:104AF00000300018000000020000100A003000180A
-:104B0000000000020000100C00300018000000013E
-:104B10000000100D00300018000000010000100E11
-:104B200000300018000000010000101000300018D4
-:104B30000000000400001014003000180000000401
-:104B40000000300001000080000800040000300474
-:104B500001000080000800040000000A00000000BE
-:104B6000000000000000306801000080000000012B
-:104B70000000306901000080000000010000306C7E
-:104B800001000080000000020000306E0100008083
-:104B900000000002000030700100008000000004EE
-:104BA0000000307401000080000000040000306646
-:104BB000010000800000000200003064010000805D
-:104BC00000000001000030600100008000000002D1
-:104BD0000000306201000080000000020000305040
-:104BE000010000800000000400003054010000803B
-:104BF00000000004000030580100008000000004A4
-:104C00000000305C01000080000000040000307CE7
-:104C100001000080000000010000307D01000080E4
-:104C20000000000100001C1800100000000000043B
-:104C300000001C30001000000000000400001C38C0
-:104C400000100000000000048000000000000000D0
-:104C500000000000800000000000000000000000D4
-:104C60008000000000000000000000008000000044
-:104C7000000000000000000000004C1000080000D0
-:104C80000000000200004C120008000000000002BA
-:104C900000004C14000800000000000400004C203C
-:104CA000000800000000000800004C300040000830
-:104CB0000000000800004C00000800000000000296
-:104CC00000004C02000800000000000100004C043D
-:104CD000000800000000000200004CD000080000A6
-:104CE0000000000800004CE0000800000000000484
-:104CF00000004CE4000800000000000100004CF03F
-:104D0000000800000000000200004CF40008000051
-:104D10000000000200004D00000800000000000438
-:104D200000005000001000000000000400005004CB
-:104D300000100000000000040000500800100000F7
-:104D40000000000400001400000800000000000241
-:104D5000000014020008000000000001000014041C
-:104D6000000800000000000200001410000800000D
-:104D700000000002000014140008000000000002FF
-:104D8000000014160008000000000002000019B81E
-:104D900000080000000000080000142000080000C7
-:104DA00000000002000014240008000000000002BF
-:104DB000000019C8000800000000000800002C10C6
-:104DC000000800000000000100002C110008000095
-:104DD0000000000100002C1200080000000000018B
-:104DE00000002C13000800000000000100002C004F
-:104DF000000800000000000200002C020008000073
-:104E00000000000100002C04000800000000000267
-:104E100000002C30000800000000000200002C32CE
-:104E2000000800000000000200002C340008000010
-:104E30000000000200002C2000080000000000011B
-:104E400000002C21000800000000000100002C22BE
-:104E5000000800000000000100002C2300080000F2
-:104E60000000000100002C240008000000000001E8
-:104E700000002C25000800000000000100002C2686
-:104E800000080000000000010000140000080000FD
-:104E900000000002000014020008000000000001F1
-:104EA00000001404000800000000000200001412BA
-:104EB00000C00018000000020000141000C000181C
-:104EC000000000020000141C00C0001800000008D0
-:104ED0000000141400C0001800000008000014278F
-:104EE00000C00018000000010000142400C00018D9
-:104EF000000000020000142600C00018000000019D
-:104F0000000015900008000000000008000015A037
-:104F10000008000000000008000015B000080000B4
-:104F200000000008800000000000000000000000F9
-:104F30008000000000000000000000008000000071
-:104F400000000000000000008000000000000000E1
-:104F500000000000800000000000000000000000D1
-:104F60008000000000000000000000008000000041
-:104F700000000000000000008000000000000000B1
-:104F800000000000800000000000000000000000A1
-:104F90008000000000000000000000008000000011
-:104FA0000000000000000000800000000000000081
-:104FB0000000000080000000000000000000000071
-:104FC00080000000000000000000000080000000E1
-:104FD0000000000000000000800000000000000051
-:104FE0000000000080000000000000000000000041
-:104FF00080000000000000000000000080000000B1
-:105000000000000000000000800000000000000020
-:105010000000000080000000000000000000000010
-:105020008000000000000000000000008000000080
-:1050300000000000000000008000000000000000F0
-:1050400000000000800000000000000000000000E0
-:1050500080000000000000000000000000000000D0
-:1050600000000000000000008000000000000000C0
-:105070000000000000000000060205000000000023
-:00000001FF
diff --git a/firmware/bnx2x/bnx2x-e1-6.2.9.0.fw.ihex b/firmware/bnx2x/bnx2x-e1-6.2.9.0.fw.ihex
new file mode 100644
index 00000000000..0ed7f589118
--- /dev/null
+++ b/firmware/bnx2x/bnx2x-e1-6.2.9.0.fw.ihex
@@ -0,0 +1,9484 @@
+:1000000000003BB0000000680000070C00003C202E
+:1000100000001AF8000043300000007C00005E3051
+:1000200000007A2C00005EB0000000B00000D8E0B4
+:10003000000080200000D99800000088000159C00D
+:100040000000398800015A5000000090000193E040
+:100050000000AC040001947800000FFC0002408016
+:100060000000000400025080020400480000000F5D
+:100070000204005400000045020400580000000083
+:100080000204005C0000000602040070000000048E
+:1000900002040078000000000204007C1217000037
+:1000A00002040080221700000204008432170000BE
+:1000B00006040088000000050204009C12150000E0
+:1000C000020400A022150000020400A43215000062
+:1000D000060400A800000004020400B8021000009A
+:1000E000020400BC00100000020400C01010000058
+:1000F000020400C420100000020400C830100000F8
+:10010000060400CC00000004020400DC0010000023
+:10011000020400E012140000020400E422140000B3
+:10012000020400E832140000060400EC00000004A1
+:100130000104012400000000010401280000000067
+:100140000104012C00000000010401300000000047
+:1001500002040004000000FF02040008000000FF89
+:100160000204000C000000FF02040010000000FF69
+:1001700002040014000000FF02040018000000FF49
+:100180000204001C000000FF02040020000000FF29
+:10019000020400240000003E0204002800000000C9
+:1001A0000204002C0000003F020400300000003F69
+:1001B000020400340000003F020400380000000088
+:1001C0000204003C0000003F020400400000003F29
+:1001D000020400440000003F020420080000021155
+:1001E0000204200C0000020002042010000002049F
+:1001F00002042014000002190204201C0000FFFF6A
+:10020000020420200000FFFF020420240000FFFF62
+:10021000020420280000FFFF0604203800000080B0
+:100220000204223807FFFFFF0204223C0000003FC7
+:100230000204224007FFFFFF020422440000000FD7
+:1002400001042248000000000104224C00000000CC
+:1002500001042250000000000104225400000000AC
+:1002600001042258000000000104225C000000008C
+:10027000010422600000000001042264000000006C
+:1002800001042268000000000104226C000000004C
+:10029000010422700000000001042274000000002C
+:1002A00001042278000000000104227C000000000C
+:1002B000020424BC000000010C042000000003E83C
+:1002C0000A042000000000010B0420000000000AC6
+:1002D0000605400000000D0002050044000000205B
+:1002E00002050048000000320205009002150020BF
+:1002F000020500940215002002050098000000305D
+:100300000205009C08100000020500A00000003358
+:10031000020500A400000030020500A80000003122
+:10032000020500AC00000002020500B0000000055C
+:10033000020500B400000006020500B8000000023B
+:10034000020500BC00000002020500C00000000021
+:10035000020500C400000005020500C800000002FC
+:10036000020500CC00000002020500D000000002DF
+:10037000020500D400000001020501140000000184
+:100380000205011C0000000102050120000000021E
+:1003900002050204000000010205020C00000040FA
+:1003A00002050210000000400205021C00000020AF
+:1003B00002050220000000130205022400000020B4
+:1003C000060502400000000A04050280002000002B
+:1003D000020500500000000702050054000000075D
+:1003E00002050058000000000205005C0000000843
+:1003F0000605006000000004020500D800000006A9
+:10040000020500E00000000D020500E40000002DE0
+:10041000020500E800000000020500EC00000020DA
+:10042000020500F000000000020500F400000020BA
+:10043000020500F800000000020500FC000000209A
+:100440000205000400000001020500080000000190
+:100450000205000C00000001020500100000000170
+:100460000205001400000001020500180000000150
+:100470000205001C00000001020500200000000130
+:100480000205002400000001020500280000000110
+:100490000205002C000000010205003000000001F0
+:1004A00002050034000000010205003800000001D0
+:1004B0000205003C000000010205004000000001B0
+:1004C0000406100002000020020600DC000000010B
+:1004D000010600D80000000004060200000302200C
+:1004E000020600DC0000000002060068000000B800
+:1004F0000206007800000114010600B800000000A8
+:10050000010600C8000000000206006C000000B8F0
+:100510000206007C00000114010600BC000000007F
+:10052000010600CC0000000007180400007B00005A
+:100530000818076000140223071C00002A040000AA
+:10054000071C800032110A82071D00001E0C1707CD
+:10055000081D4550575602250118000000000000F4
+:10056000011800040000000001180008000000004D
+:100570000118000C0000000001180010000000002D
+:100580000118001400000000021800200000000103
+:1005900002180024000000020218002800000003D6
+:1005A0000218002C000000000218003000000004B7
+:1005B000021800340000000102180038000000009A
+:1005C0000218003C00000001021800400000000476
+:1005D000021800440000000002180048000000015A
+:1005E0000218004C00000003021800500000000038
+:1005F0000218005400000001021800580000000416
+:100600000218005C000000000218006000000001F9
+:1006100002180064000000030218006800000000D7
+:100620000218006C000000010218007000000004B5
+:100630000218007400000000021800780000000496
+:100640000218007C00000003061800800000000271
+:10065000021800A400003FFF021800A8000003FFDA
+:1006600002180224000000000218023400000000FA
+:100670000218024C00000000021802E4000000FF13
+:100680000618100000000400021B8BC000000001CF
+:10069000021B800000000034021B80400000001894
+:1006A000021B80800000000C021B80C000000020A4
+:1006B0000C1B83000007A1200A1B830000000138E7
+:1006C0000B1B8300000013880A1B834000000000FE
+:1006D0000C1B8340000001F40B1B8340000000054D
+:1006E000021B83800007A120021B83C0000001F4CD
+:1006F000061A100000000273041A19CC0001022728
+:10070000061A2008000000C8061A20000000000297
+:10071000041A499800040228061A2E280000000234
+:10072000061A2E2000000002061A0800000000022F
+:10073000061A080800000004061A08180000000243
+:10074000041A08B00002022C061A2FD0000000067E
+:10075000041A2FE80002022E041A2FC000040230EF
+:10076000041A300000010234061A300400000003AD
+:10077000041A301000010235061A3014000000037C
+:10078000041A302000010236061A3024000000034B
+:10079000041A303000010237061A3034000000031A
+:1007A000041A304000010238061A304400000003E9
+:1007B000041A305000010239061A305400000003B8
+:1007C000041A30600001023A061A30640000000387
+:1007D000041A30700001023B061A30740000000356
+:1007E000041A30800001023C061A30840000000325
+:1007F000041A30900001023D061A309400000003F4
+:10080000041A30A00001023E061A30A400000003C2
+:10081000041A30B00001023F061A30B40000000391
+:10082000041A30C000010240061A30C40000000360
+:10083000041A30D000010241061A30D4000000032F
+:10084000041A30E000010242061A30E400000003FE
+:10085000041A30F000010243061A30F400000003CD
+:10086000041A310000010244061A3104000000039A
+:10087000041A311000010245061A31140000000369
+:10088000041A312000010246061A31240000000338
+:10089000041A313000010247061A31340000000307
+:1008A000041A314000010248061A314400000003D6
+:1008B000041A315000010249061A315400000003A5
+:1008C000041A31600001024A061A31640000000374
+:1008D000041A31700001024B061A31740000000343
+:1008E000041A31800001024C061A31840000000312
+:1008F000041A31900001024D061A319400000003E1
+:10090000041A31A00001024E061A31A400000003AF
+:10091000041A31B00001024F061A31B4000000037E
+:10092000041A31C000010250061A31C4000000034D
+:10093000041A31D000010251061A31D4000000031C
+:10094000041A31E000010252061A31E400000003EB
+:10095000041A31F000010253061A31F400000003BA
+:10096000041A320000010254061A32040000000387
+:10097000041A321000010255061A32140000000356
+:10098000041A322000010256061A32240000000325
+:10099000041A323000010257061A323400000003F4
+:1009A000041A324000010258061A324400000003C3
+:1009B000041A325000010259061A32540000000392
+:1009C000041A32600001025A061A32640000000361
+:1009D000041A32700001025B061A32740000000330
+:1009E000041A32800001025C061A328400000003FF
+:1009F000041A32900001025D061A329400000003CE
+:100A0000041A32A00001025E061A32A4000000039C
+:100A1000041A32B00001025F061A32B4000000036B
+:100A2000041A32C000010260061A32C4000000033A
+:100A3000041A32D000010261061A32D40000000309
+:100A4000041A32E000010262061A32E400000003D8
+:100A5000041A32F000010263061A32F400000003A7
+:100A6000041A330000010264061A33040000000374
+:100A7000041A331000010265061A33140000000343
+:100A8000041A332000010266061A33240000000312
+:100A9000041A333000010267061A333400000003E1
+:100AA000041A334000010268061A334400000003B0
+:100AB000041A335000010269061A3354000000037F
+:100AC000041A33600001026A061A3364000000034E
+:100AD000041A33700001026B061A3374000000031D
+:100AE000041A33800001026C061A338400000003EC
+:100AF000041A33900001026D061A339400000003BB
+:100B0000041A33A00001026E061A33A40000000389
+:100B1000041A33B00001026F061A33B40000000358
+:100B2000041A33C000010270061A33C40000000327
+:100B3000041A33D000010271061A33D400000003F6
+:100B4000041A33E000010272061A33E400000003C5
+:100B5000041A33F000010273061A33F40000000394
+:100B6000041A340000010274061A34040000000361
+:100B7000041A341000010275061A34140000000330
+:100B8000041A342000010276061A342400000003FF
+:100B9000041A343000010277061A343400000003CE
+:100BA000041A344000010278061A3444000000039D
+:100BB000041A345000010279061A3454000000036C
+:100BC000041A34600001027A061A3464000000033B
+:100BD000041A34700001027B061A3474000000030A
+:100BE000041A34800001027C061A348400000003D9
+:100BF000041A34900001027D061A349400000003A8
+:100C0000041A34A00001027E061A34A40000000376
+:100C1000041A34B00001027F061A34B40000000345
+:100C2000041A34C000010280061A34C40000000314
+:100C3000041A34D000010281061A34D400000003E3
+:100C4000041A34E000010282061A34E400000003B2
+:100C5000041A34F000010283061A34F40000000381
+:100C6000041A350000010284061A3504000000034E
+:100C7000041A351000010285061A3514000000031D
+:100C8000041A352000010286061A352400000003EC
+:100C9000041A353000010287061A353400000003BB
+:100CA000041A354000010288061A3544000000038A
+:100CB000041A355000010289061A35540000000359
+:100CC000041A35600001028A061A35640000000328
+:100CD000041A35700001028B061A357400000003F7
+:100CE000041A35800001028C061A358400000003C6
+:100CF000041A35900001028D061A35940000000395
+:100D0000041A35A00001028E061A35A40000000363
+:100D1000041A35B00001028F061A35B40000000332
+:100D2000041A35C000010290061A35C40000000301
+:100D3000041A35D000010291061A35D400000003D0
+:100D4000041A35E000010292061A35E4000000039F
+:100D5000041A35F000010293061A35F4000000036E
+:100D6000041A360000010294061A3604000000033B
+:100D7000041A361000010295061A3614000000030A
+:100D8000041A362000010296061A362400000003D9
+:100D9000041A363000010297061A363400000003A8
+:100DA000041A364000010298061A36440000000377
+:100DB000041A365000010299061A36540000000346
+:100DC000041A36600001029A061A36640000000315
+:100DD000041A36700001029B061A367400000003E4
+:100DE000041A36800001029C061A368400000003B3
+:100DF000041A36900001029D061A36940000000382
+:100E0000041A36A00001029E061A36A40000000350
+:100E1000041A36B00001029F061A36B4000000031F
+:100E2000041A36C0000102A0061A36C400000003EE
+:100E3000041A36D0000102A1061A36D400000003BD
+:100E4000041A36E0000102A2061A36E4000000038C
+:100E5000041A36F0000102A3061A36F4000000035B
+:100E6000041A3700000102A4061A37040000000328
+:100E7000041A3710000102A5061A371400000003F7
+:100E8000041A3720000102A6061A372400000003C6
+:100E9000041A3730000102A7061A37340000000395
+:100EA000041A3740000102A8061A37440000000364
+:100EB000041A3750000102A9061A37540000000333
+:100EC000041A3760000102AA061A37640000000302
+:100ED000041A3770000102AB061A377400000003D1
+:100EE000041A3780000102AC061A378400000003A0
+:100EF000041A3790000102AD061A3794000000036F
+:100F0000041A37A0000102AE061A37A4000000033D
+:100F1000041A37B0000102AF061A37B4000000030C
+:100F2000041A37C0000102B0061A37C400000003DB
+:100F3000041A37D0000102B1061A37D400000003AA
+:100F4000041A37E0000102B2061A37E40000000379
+:100F5000041A37F0000102B3061A37F40000000348
+:100F6000041A3800000102B4061A38040000000315
+:100F7000041A3810000102B5061A381400000003E4
+:100F8000041A3820000102B6061A382400000003B3
+:100F9000041A3830000102B7061A38340000000382
+:100FA000041A3840000102B8061A38440000000351
+:100FB000041A3850000102B9061A38540000000320
+:100FC000041A3860000102BA061A386400000003EF
+:100FD000041A3870000102BB061A387400000003BE
+:100FE000041A3880000102BC061A3884000000038D
+:100FF000041A3890000102BD061A3894000000035C
+:10100000041A38A0000102BE061A38A4000000032A
+:10101000041A38B0000102BF061A38B400000003F9
+:10102000041A38C0000102C0061A38C400000003C8
+:10103000041A38D0000102C1061A38D40000000397
+:10104000041A38E0000102C2061A38E40000000366
+:10105000041A38F0000102C3061A38F40000000335
+:10106000041A3900000102C4061A39040000000302
+:10107000041A3910000102C5061A391400000003D1
+:10108000041A3920000102C6061A392400000003A0
+:10109000041A3930000102C7061A3934000000036F
+:1010A000041A3940000102C8061A3944000000033E
+:1010B000041A3950000102C9061A3954000000030D
+:1010C000041A3960000102CA061A396400000003DC
+:1010D000041A3970000102CB061A397400000003AB
+:1010E000041A3980000102CC061A3984000000037A
+:1010F000041A3990000102CD061A39940000000349
+:10110000041A39A0000102CE061A39A40000000317
+:10111000041A39B0000102CF061A39B400000003E6
+:10112000041A39C0000102D0061A39C400000003B5
+:10113000041A39D0000102D1061A39D40000000384
+:10114000041A39E0000102D2061A39E40000000353
+:10115000041A39F0000102D3061A39F40000000322
+:10116000041A3A00000102D4061A3A0400000003EF
+:10117000041A3A10000102D5061A3A1400000003BE
+:10118000041A3A20000102D6061A3A24000000038D
+:10119000041A3A30000102D7061A3A34000000035C
+:1011A000041A3A40000102D8061A3A44000000032B
+:1011B000041A3A50000102D9061A3A5400000003FA
+:1011C000041A3A60000102DA061A3A6400000003C9
+:1011D000041A3A70000102DB061A3A740000000398
+:1011E000041A3A80000102DC061A3A840000000367
+:1011F000041A3A90000102DD061A3A940000000336
+:10120000041A3AA0000102DE061A3AA40000000304
+:10121000041A3AB0000102DF061A3AB400000003D3
+:10122000041A3AC0000102E0061A3AC400000003A2
+:10123000041A3AD0000102E1061A3AD40000000371
+:10124000041A3AE0000102E2061A3AE40000000340
+:10125000041A3AF0000102E3061A3AF4000000030F
+:10126000041A3B00000102E4061A3B0400000003DC
+:10127000041A3B10000102E5061A3B1400000003AB
+:10128000041A3B20000102E6061A3B24000000037A
+:10129000041A3B30000102E7061A3B340000000349
+:1012A000041A3B40000102E8061A3B440000000318
+:1012B000041A3B50000102E9061A3B5400000003E7
+:1012C000041A3B60000102EA061A3B6400000003B6
+:1012D000041A3B70000102EB061A3B740000000385
+:1012E000041A3B80000102EC061A3B840000000354
+:1012F000041A3B90000102ED061A3B940000000323
+:10130000041A3BA0000102EE061A3BA400000003F1
+:10131000041A3BB0000102EF061A3BB400000003C0
+:10132000041A3BC0000102F0061A3BC4000000038F
+:10133000041A3BD0000102F1061A3BD4000000035E
+:10134000041A3BE0000102F2061A3BE4000000032D
+:10135000041A3BF0000102F3061A3BF400000003FC
+:10136000041A3C00000102F4061A3C0400000003C9
+:10137000041A3C10000102F5061A3C140000000398
+:10138000041A3C20000102F6061A3C240000000367
+:10139000041A3C30000102F7061A3C340000000336
+:1013A000041A3C40000102F8061A3C440000000305
+:1013B000041A3C50000102F9061A3C5400000003D4
+:1013C000041A3C60000102FA061A3C6400000003A3
+:1013D000041A3C70000102FB061A3C740000000372
+:1013E000041A3C80000102FC061A3C840000000341
+:1013F000041A3C90000102FD061A3C940000000310
+:10140000041A3CA0000102FE061A3CA400000003DE
+:10141000041A3CB0000102FF061A3CB400000003AD
+:10142000041A3CC000010300061A3CC4000000037B
+:10143000041A3CD000010301061A3CD4000000034A
+:10144000041A3CE000010302061A3CE40000000319
+:10145000041A3CF000010303061A3CF400000003E8
+:10146000041A3D0000010304061A3D0400000003B5
+:10147000041A3D1000010305061A3D140000000384
+:10148000041A3D2000010306061A3D240000000353
+:10149000041A3D3000010307061A3D340000000322
+:1014A000041A3D4000010308061A3D4400000003F1
+:1014B000041A3D5000010309061A3D5400000003C0
+:1014C000041A3D600001030A061A3D64000000038F
+:1014D000041A3D700001030B061A3D74000000035E
+:1014E000041A3D800001030C061A3D84000000032D
+:1014F000041A3D900001030D061A3D9400000003FC
+:10150000041A3DA00001030E061A3DA400000003CA
+:10151000041A3DB00001030F061A3DB40000000399
+:10152000041A3DC000010310061A3DC40000000368
+:10153000041A3DD000010311061A3DD40000000337
+:10154000041A3DE000010312061A3DE40000000306
+:10155000041A3DF000010313061A3DF400000003D5
+:10156000041A3E0000010314061A3E0400000003A2
+:10157000041A3E1000010315061A3E140000000371
+:10158000041A3E2000010316061A3E240000000340
+:10159000041A3E3000010317061A3E34000000030F
+:1015A000041A3E4000010318061A3E4400000003DE
+:1015B000041A3E5000010319061A3E5400000003AD
+:1015C000041A3E600001031A061A3E64000000037C
+:1015D000041A3E700001031B061A3E74000000034B
+:1015E000041A3E800001031C061A3E84000000031A
+:1015F000041A3E900001031D061A3E9400000003E9
+:10160000041A3EA00001031E061A3EA400000003B7
+:10161000041A3EB00001031F061A3EB40000000386
+:10162000041A3EC000010320061A3EC40000000355
+:10163000041A3ED000010321061A3ED40000000324
+:10164000041A3EE000010322061A3EE400000003F3
+:10165000041A3EF000010323061A3EF400000003C2
+:10166000041A3F0000010324061A3F04000000038F
+:10167000041A3F1000010325061A3F14000000035E
+:10168000041A3F2000010326061A3F24000000032D
+:10169000041A3F3000010327061A3F3400000003FC
+:1016A000041A3F4000010328061A3F4400000003CB
+:1016B000041A3F5000010329061A3F54000000039A
+:1016C000041A3F600001032A061A3F640000000369
+:1016D000041A3F700001032B061A3F740000000338
+:1016E000041A3F800001032C061A3F840000000307
+:1016F000041A3F900001032D061A3F9400000003D6
+:10170000041A3FA00001032E061A3FA400000003A4
+:10171000041A3FB00001032F061A3FB40000000373
+:10172000041A3FC000010330061A3FC40000000342
+:10173000041A3FD000010331061A3FD40000000311
+:10174000041A3FE000010332061A3FE400000007DC
+:10175000041A4CB000080333061A400000000124AC
+:10176000021A492000000000061A2500000000109F
+:10177000061A258000000012061A09C00000004861
+:10178000061A080000000002061A082000000012D5
+:10179000041A2FB00002033B041A4CF00002033D70
+:1017A000061A500000000004061A449000000124AC
+:1017B000021A492400000000061A2540000000100B
+:1017C000061A25C800000012061A0AE000000048A8
+:1017D000061A081000000002061A0868000000122D
+:1017E000041A2FB80002033F041A4CF80002034108
+:1017F000061A5010000000040200A468000AFFDC72
+:101800000200A280000000010200A294071D29111D
+:101810000200A298000000000200A29C009C042488
+:101820000200A2A0000000000200A2A40000020921
+:101830000200A4FCFF000000020100B4000000014F
+:10184000020100B800000001020100DC00000001FC
+:10185000020101000000000102010104000000017A
+:101860000201007C0030000002010084000000281A
+:101870000201008C000000000201013000000004A1
+:101880000201025C000000010201032800000000C8
+:101890000201055400000030020100C400000001F4
+:1018A000020100CC00000001020100F8000000016C
+:1018B000020100F000000001020100800030000081
+:1018C00002010088000000280201009000000000D2
+:1018D0000201013400000004020102DC00000001EA
+:1018E0000201032C0000000002010564000000302A
+:1018F000020100C800000001020100D00000000148
+:10190000020100FC00000001020100F400000001DF
+:10191000020C100000000028020C200800000A1130
+:10192000020C200C00000A00020C201000000A0427
+:10193000020C201C0000FFFF020C20200000FFFF13
+:10194000020C20240000FFFF020C20280000FFFFF3
+:10195000020C203800000020020C203C0000002176
+:10196000020C204000000022020C20440000002352
+:10197000020C204800000024020C204C000000252E
+:10198000020C205000000026020C2054000000270A
+:10199000020C205800000028020C205C00000029E6
+:1019A000020C20600000002A020C20640000002BC2
+:1019B000020C20680000002C020C206C0000002D9E
+:1019C000020C20700000002E020C20740000002F7A
+:1019D000020C207800000010060C207C0000004F54
+:1019E000020C21B800000001020C21BC0000000123
+:1019F000020C21C000000001020C21C40000000103
+:101A0000020C21C800000001020C21CC00000001E2
+:101A1000020C21D000000001020C21D400000001C2
+:101A2000020C21D800000001020C21DC00000001A2
+:101A3000020C21E000000001020C21E40000000182
+:101A4000020C21E800000001020C21EC0000000162
+:101A5000020C21F000000001020C21F40000000142
+:101A6000020C21F800000001060C21FC0000000F10
+:101A7000020C223807FFFFFF020C223C0000003F4F
+:101A8000020C224007FFFFFF020C22440000000F5F
+:101A9000010C224800000000010C224C0000000054
+:101AA000010C225000000000010C22540000000034
+:101AB000010C225800000000010C225C0000000014
+:101AC000010C226000000000010C226400000000F4
+:101AD000010C226800000000010C226C00000000D4
+:101AE000010C227000000000010C227400000000B4
+:101AF000010C227800000000010C227C0000000094
+:101B0000020C24BC000000010C0C2000000003E8C3
+:101B10000A0C2000000000010B0C20000000000A4D
+:101B2000020C400800000562020C400C0000055148
+:101B3000020C401000000555020C40140000057214
+:101B4000020C401C0000FFFF020C40200000FFFFC1
+:101B5000020C40240000FFFF020C40280000FFFFA1
+:101B6000020C403800000046020C403C0000000C13
+:101B7000060C40400000005E020C41B8000000016D
+:101B8000060C41BC0000001F020C423807FFFFFF9B
+:101B9000020C423C0000003F020C424007FFFFFFE6
+:101BA000020C42440000000F010C424800000000FB
+:101BB000010C424C00000000010C425000000000EB
+:101BC000010C425400000000010C425800000000CB
+:101BD000010C425C00000000010C426000000000AB
+:101BE000010C426400000000010C4268000000008B
+:101BF000010C426C00000000010C4270000000006B
+:101C0000010C427400000000010C4278000000004A
+:101C1000010C427C00000000010C4280000000002A
+:101C2000020C44C0000000010C0C4000000003E85E
+:101C30000A0C4000000000010B0C40000000000AEC
+:101C4000060D400000000A00020D004400000032B2
+:101C5000020D008C02150020020D009002150020DC
+:101C6000020D009408100000020D009800000033DF
+:101C7000020D009C00000002020D00A00000000008
+:101C8000020D00A400000005020D00A800000005E0
+:101C9000060D00AC00000002020D00B400000002BE
+:101CA000020D00B800000003020D00BC000000029D
+:101CB000020D00C000000001020D00C8000000027B
+:101CC000020D00CC00000002020D015C00000001CA
+:101CD000020D016400000001020D01680000000215
+:101CE000020D020400000001020D020C00000020A1
+:101CF000020D021000000040020D0214000000401E
+:101D0000020D022000000003020D02240000001852
+:101D1000060D028000000012040D030000180343AA
+:101D2000060D03600000000C020D004C00000001D5
+:101D3000020D005000000002020D005400000000DF
+:101D4000020D005800000008060D005C00000004B1
+:101D5000020D00C400000004020D0114000000097F
+:101D6000020D011800000029020D011C0000000AEC
+:101D7000020D01200000002A020D012400000000D5
+:101D8000020D012800000020020D012C00000000BF
+:101D9000020D013000000020020D0134000000009F
+:101DA000020D013800000020020D013C000000007F
+:101DB000020D014000000020020D0144000000005F
+:101DC000020D014800000020020D00040000000187
+:101DD000020D000800000001020D000C00000001CF
+:101DE000020D001000000001020D001400000001AF
+:101DF000020D001800000001020D001C000000018F
+:101E0000020D002000000001020D0024000000016E
+:101E1000020D002800000001020D002C000000014E
+:101E2000020D003000000001020D0034000000012E
+:101E3000020D003800000001020D003C000000010E
+:101E4000060E200000000800020E004C00000032C8
+:101E5000020E009402150020020E009802150020C8
+:101E6000020E009C00000030020E00A008100000CE
+:101E7000020E00A400000033020E00A80000003093
+:101E8000020E00AC00000031020E00B000000002A3
+:101E9000020E00B400000004020E00B800000000B2
+:101EA000020E00BC00000002020E00C00000000292
+:101EB000020E00C400000000020E00C80000000274
+:101EC000020E00CC00000007020E00D0000000024D
+:101ED000020E00D400000002020E00D80000000133
+:101EE000020E014400000001020E014C000000013E
+:101EF000020E015000000002020E02040000000168
+:101F0000020E020C00000040020E02100000004011
+:101F1000020E021C00000004020E0220000000203D
+:101F2000020E02240000000E020E02280000001B18
+:101F3000060E030000000012040E0280001B035B6B
+:101F4000060E02EC00000005020E00540000000C1A
+:101F5000020E00580000000C020E005C00000000A1
+:101F6000020E006000000010060E00640000000475
+:101F7000020E00DC00000003020E01100000000F42
+:101F8000020E01140000002F020E011800000000D4
+:101F9000020E011C00000020020E000400000001DF
+:101FA000020E000800000001020E000C00000001FB
+:101FB000020E001000000001020E001400000001DB
+:101FC000020E001800000001020E001C00000001BB
+:101FD000020E002000000001020E0024000000019B
+:101FE000020E002800000001020E002C000000017B
+:101FF000020E003000000001020E0034000000015B
+:10200000020E003800000001020E003C000000013A
+:10201000020E004000000001020E0044000000011A
+:102020000730040000AF0000083007680013037693
+:10203000073400003305000007348000327F0CC2F3
+:10204000073500001A951962083539E058C403783D
+:10205000013000000000000001300004000000001A
+:1020600001300008000000000130000C00000000FA
+:1020700001300010000000000130001400000000DA
+:1020800002300020000000010230002400000002A5
+:1020900002300028000000030230002C0000000085
+:1020A0000230003000000004023000340000000163
+:1020B00002300038000000000230003C0000000147
+:1020C0000230004000000004023000440000000024
+:1020D00002300048000000010230004C0000000304
+:1020E00002300050000000000230005400000001E7
+:1020F00002300058000000040230005C00000000C4
+:1021000002300060000000010230006400000003A3
+:1021100002300068000000000230006C0000000186
+:102120000230007000000004023000740000000063
+:1021300002300078000000040230007C0000000340
+:102140000630008000000002023000A400003FFFC3
+:10215000023000A8000003FF02300224000000004B
+:1021600002300234000000000230024C0000000087
+:10217000023002E40000FFFF0630200000000800EB
+:1021800002338BC000000001023380000000001AFF
+:10219000023380400000004E0233808000000010B7
+:1021A000023380C0000000200C3383000007A12010
+:1021B0000A338300000001380B33830000001388CA
+:1021C0000A338340000000000C338340000001F418
+:1021D0000B33834000000005023383800007A120F9
+:1021E000023383C0000001F406322A88000000C2D6
+:1021F00006322008000000C806322000000000025D
+:10220000063223E80000004004322E580004037A0E
+:10221000063250A000000004063250B80000000250
+:102220000632508000000006043250980002037EFF
+:10223000063250000000002006323000000004008A
+:1022400006321C0000000004043218300002038033
+:10225000063224E8000000B402322DB00000000075
+:1022600006324000000000B40632300000000020BA
+:10227000063231000000002006323200000000204B
+:102280000632330000000020063234000000002037
+:102290000632350000000020063236000000002023
+:1022A000063237000000002006323800000000200F
+:1022B000063239000000002006323A0000000020FB
+:1022C00006323B000000002006323C0000000020E7
+:1022D00006323D000000002006323E0000000020D3
+:1022E00006323F000000002006321C1000000002F1
+:1022F000063245A000000024063227B8000000B4D2
+:1023000002322DB400000000063242D0000000B4BA
+:1023100006323080000000200632318000000020AC
+:102320000632328000000020063233800000002098
+:102330000632348000000020063235800000002084
+:102340000632368000000020063237800000002070
+:10235000063238800000002006323980000000205C
+:1023600006323A800000002006323B800000002048
+:1023700006323C800000002006323D800000002034
+:1023800006323E800000002006323F800000002020
+:1023900006321C20000000020632463000000024F5
+:1023A0000720040000870000082007800010038237
+:1023B000072400003165000007248000081D0C5A26
+:1023C00008248EB06C9003840120000000000000FF
+:1023D00001200004000000000120000800000000AF
+:1023E0000120000C0000000001200010000000008F
+:1023F0000120001400000000022000200000000165
+:102400000220002400000002022000280000000337
+:102410000220002C00000000022000300000000418
+:1024200002200034000000010220003800000000FB
+:102430000220003C000000010220004000000004D7
+:1024400002200044000000000220004800000001BB
+:102450000220004C00000003022000500000000099
+:102460000220005400000001022000580000000477
+:102470000220005C0000000002200060000000015B
+:102480000220006400000003022000680000000039
+:102490000220006C00000001022000700000000417
+:1024A00002200074000000000220007800000004F8
+:1024B0000220007C000000030620008000000002D3
+:1024C000022000A400003FFF022000A8000003FF3C
+:1024D000022002240000000002200234000000005C
+:1024E0000220024C00000000022002E40000FFFF76
+:1024F000062020000000080002238BC0000000011D
+:10250000022380000000001002238040000000121F
+:102510000223808000000030022380C00000000EF3
+:102520000C2383000007A1200A2383000000013848
+:102530000B238300000013880A238340000000005F
+:102540000C238340000001F40B23834000000005AE
+:10255000022383800007A120022383C0000001F42E
+:10256000062250000000004206222008000000C899
+:10257000062220000000000206224000000000C6E3
+:1025800004224318000503860622432C0000000B9A
+:10259000042243580005038B0622436C0000000B05
+:1025A0000422439800050390062243AC0000000B70
+:1025B000042243D800050395062243EC0000000BDB
+:1025C000042244180005039A0622442C0000000B44
+:1025D000042244580005039F0622446C0000000BAF
+:1025E00004224498000503A4062244AC0000000B1A
+:1025F000042244D8000503A9062244EC0000000B85
+:1026000004224518000503AE0622452C0000000BED
+:1026100004224558000503B30622456C0000000B58
+:1026200004224598000503B8062245AC0000000BC3
+:10263000042245D8000503BD062245EC0000000B2E
+:1026400004224618000503C20622462C0000000B97
+:1026500004224658000503C70622466C0000000B02
+:1026600004224698000503CC062246AC0000000B6D
+:10267000042246D8000503D1062246EC0000000BD8
+:1026800004224718000503D60622472C0000000B41
+:1026900004224758000503DB0622476C0000000BAC
+:1026A00004224798000503E0062247AC0000000B17
+:1026B000042247D8000503E5062247EC0000000B82
+:1026C00004224818000503EA0622482C0000000BEB
+:1026D00004224858000503EF0622486C0000000B56
+:1026E00004224898000503F4062248AC0000000BC1
+:1026F000042248D8000503F9062248EC0000000B2C
+:1027000004224918000503FE0622492C0000000B94
+:1027100004224958000504030622496C0000000BFE
+:102720000422499800050408062249AC0000000B69
+:10273000042249D80005040D062249EC0000000BD4
+:1027400004224A180005041206224A2C0000000B3D
+:1027500004224A580005041706224A6C0000000BA8
+:1027600004224A980005041C06224AAC0000000B13
+:1027700004224AD80005042106224AEC0000000584
+:1027800006224B000000001704224B5C00010426C7
+:1027900006224B600000000304224B6C000104275A
+:1027A000062238000000004006223000000002002F
+:1027B000042251C00004042806221000000000C0BA
+:1027C000062215C00000024004221EC80008042C86
+:1027D0000622390000000008022251180000000003
+:1027E000062251D00000000606221300000000025D
+:1027F00006221410000000300622392000000008D4
+:102800000222511C00000000062251E800000006D0
+:102810000622130800000002062214D00000003037
+:102820000216100000000028021700080000000235
+:102830000217002C000000030217003C00000004F7
+:1028400002170044000000000217004800000002C8
+:102850000217004C0000009002170050000000908A
+:102860000217005400800090021700580810000062
+:10287000021700600000008A021700640000008058
+:1028800002170068000000810217006C0000008041
+:10289000021700700000000602170078000007D041
+:1028A0000217007C0000076C02170038007C10043F
+:1028B000021700040000000F06164024000000026A
+:1028C000021640700000001C0216420800000001C1
+:1028D0000216421000000001021642200000000112
+:1028E00002164228000000010216423000000001DA
+:1028F000021642380000000102164260000000018A
+:102900000C16401C0003D0900A16401C0000009CCE
+:102910000B16401C000009C40216403000000008DD
+:10292000021640340000000C02164038000000106F
+:102930000216404400000020021640000000000182
+:10294000021640D8000000010216400800000001F5
+:102950000216400C000000010216401000000001A9
+:10296000021642400000000002164248000000002B
+:1029700006164270000000020216425000000000DD
+:1029800002164258000000000616428000000002B5
+:1029900002166008000006140216600C0000060013
+:1029A00002166010000006040216601C0000FFFF03
+:1029B000021660200000FFFF021660240000FFFFE7
+:1029C000021660280000FFFF021660380000002099
+:1029D0000216603C00000020061660400000000265
+:1029E00002166048000000230216604C000000241C
+:1029F00002166050000000250216605400000026F8
+:102A000002166058000000270216605C00000029D2
+:102A1000021660600000002A021660640000002BAD
+:102A2000021660680000002C0216606C0000002D89
+:102A30000616607000000012021660B80000000167
+:102A4000021660BC00000001061660C00000003ED7
+:102A5000021661B800000001061661BC0000001FEC
+:102A60000216623807FFFFFF0216623C0000003FBB
+:102A70000216624007FFFFFF021662440000000FCB
+:102A800001166248000000000116624C00000000C0
+:102A900001166250000000000116625400000000A0
+:102AA00001166258000000000116625C0000000080
+:102AB0000116626000000000011662640000000060
+:102AC00001166268000000000116626C0000000040
+:102AD0000116627000000000011662740000000020
+:102AE00001166278000000000116627C0000000000
+:102AF000021664BC000000010C166000000003E830
+:102B00000A166000000000010B1660000000000AB9
+:102B100002168040000000060216804400000005F6
+:102B2000021680480000000A0216804C00000005D2
+:102B30000216805400000002021680CC000000043F
+:102B4000021680D000000004021680D400000004A9
+:102B5000021680D800000004021680DC0000000489
+:102B6000021680E000000004021680E40000000469
+:102B7000021680E800000004021688040000000429
+:102B8000021680300000007C021680340000003DF8
+:102B9000021680380000003F0216803C0000009CB6
+:102BA000021680F000000007061680F40000000501
+:102BB0000216880C010101010216810800000000C4
+:102BC0000216810C000000040216811000000004AF
+:102BD0000216811400000002021688100801200469
+:102BE00002168118000000050216811C0000000575
+:102BF0000216812000000005021681240000000555
+:102C00000216882C200810010216812800000008F6
+:102C10000216812C00000006021681300000000719
+:102C200002168134000000000216883001010120E4
+:102C300006168138000000040216883401010101E3
+:102C400006168148000000040216883801010101BF
+:102C500006168158000000040216883C010101019B
+:102C6000061681680000000302168174000000014E
+:102C7000021688400101010102168178000000015E
+:102C80000216817C00000001021681800000000114
+:102C9000021681840000000102168844010101012E
+:102CA00002168188000000010216818C00000004D9
+:102CB00002168190000000040216819400000002B8
+:102CC00002168848080120040216819800000005B9
+:102CD0000216819C00000005021681A0000000057C
+:102CE000021681A4000000050216881420081001B5
+:102CF000021681A800000008021681AC0000000640
+:102D0000021681B000000007021681B40000000125
+:102D10000216881801010120021681B80000000186
+:102D2000021681BC00000001021681C000000001F3
+:102D3000021681C4000000010216881C0101010175
+:102D4000021681C800000001021681CC00000001BB
+:102D5000021681D000000001021681D4000000019B
+:102D60000216882001010101021681D8000000012D
+:102D7000021681DC00000001021681E00000000163
+:102D8000021681E4000000010216882401010101FD
+:102D9000021681E800000001021681EC000000012B
+:102DA000021681F0000000010216882801010101CD
+:102DB00002168240FFFF003F061682440000000218
+:102DC0000216824CFFFF003F0216825000000100F5
+:102DD000021682540000010006168258000000020C
+:102DE00002168260000000C002168264000000C06B
+:102DF0000216826800001E000216826C00001E008F
+:102E0000021682700000400002168274000040002A
+:102E100002168278000080000216827C000080008A
+:102E2000021682800000200002168284000020002A
+:102E30000616828800000007021682A40000000126
+:102E4000061682A80000000A021681F400000C0891
+:102E5000021681F800000040021681FC000001000B
+:102E600002168200000000200216820400000017F3
+:102E700002168208000000800216820C0000020088
+:102E8000021682100000000002168218FFFF01FFE8
+:102E900002168214FFFF01FF0216823C000000139D
+:102EA000021680900000013F021680600000014081
+:102EB00002168064000001400616806800000002CF
+:102EC00002168070000000C0061680740000000723
+:102ED0000216809C00000048021680A000000048F6
+:102EE000061680A400000002021680AC0000004814
+:102EF000061680B00000000702168238000080002D
+:102F000002168234000025E40216809400007FFF40
+:102F100002168220000000070216821C0000000733
+:102F2000021682280000000002168224FFFFFFFF25
+:102F300002168230000000000216822CFFFFFFFF05
+:102F4000021680EC000000FF0214000000000001E7
+:102F50000214000C000000010214004000000001F7
+:102F60000214004400007FFF0214000C0000000067
+:102F700002140000000000000214006C00000000B9
+:102F800002140004000000010214003000000001DF
+:102F900002140004000000000214005C00000000A5
+:102FA00002140008000000010214003400000001B7
+:102FB000021400080000000002140060000000007D
+:102FC00006028000000020000202005800000032CB
+:102FD000020200A003150020020200A40315002035
+:102FE000020200A801000030020200AC081000003C
+:102FF000020200B000000033020200B40000003002
+:10300000020200B800000031020200BC0000000310
+:10301000020200C000000006020200C4000000031B
+:10302000020200C800000003020200CC00000002FF
+:10303000020200D000000000020200D400000002E2
+:10304000020200DC00000000020200E000000006B6
+:10305000020200E400000004020200E80000000296
+:10306000020200EC00000002020200F00000000179
+:10307000020200FC00000006020201200000000025
+:103080000202013400000002020201B0000000014F
+:103090000202020C00000001020202140000000102
+:1030A00002020218000000020202040400000001F3
+:1030B0000202040C00000040020204100000004064
+:1030C0000202041C00000004020204200000002090
+:1030D0000202042400000002020204280000001F73
+:1030E00006020500000000120402048000200434DF
+:1030F000020200600000000F0202006400000007EE
+:1031000002020068000000000202006C0000000ED5
+:103110000602007000000004020200F40000000437
+:103120000202000400000001020200080000000189
+:103130000202000C00000001020200100000000169
+:103140000202001400000001020200180000000149
+:103150000202001C00000001020200200000000129
+:103160000202002400000001020200280000000109
+:103170000202002C000000010202003000000001E9
+:1031800002020034000000010202003800000001C9
+:103190000202003C000000010202004000000001A9
+:1031A0000202004400000001020200480000000189
+:1031B0000202004C00000001020200500000000169
+:1031C00002020108000000C802020118000000020B
+:1031D000020201C400000000020201CC0000000055
+:1031E000020201D400000002020201DC0000000221
+:1031F000020201E4000000FF020201EC000000FFF7
+:103200000202010C000000C80202011C00000002C2
+:10321000020201C800000000020201D0000000000C
+:10322000020201D800000002020201E000000002D8
+:10323000020201E8000000FF020201F0000000FFAE
+:1032400007280400008E00000828076800130454B3
+:10325000072C000033C80000072C800038050CF351
+:10326000072D000038B61AF5072D800007762923B0
+:10327000082D8CB04E6A04560128000000000000A2
+:1032800001280004000000000128000800000000E0
+:103290000128000C000000000128001000000000C0
+:1032A0000128001400000000022800200000000196
+:1032B0000228002400000002022800280000000369
+:1032C0000228002C0000000002280030000000044A
+:1032D000022800340000000102280038000000002D
+:1032E0000228003C00000001022800400000000409
+:1032F00002280044000000000228004800000001ED
+:103300000228004C000000030228005000000000CA
+:1033100002280054000000010228005800000004A8
+:103320000228005C0000000002280060000000018C
+:10333000022800640000000302280068000000006A
+:103340000228006C00000001022800700000000448
+:103350000228007400000000022800780000000429
+:103360000228007C00000003062800800000000204
+:10337000022800A400003FFF022800A8000003FF6D
+:10338000022802240000000002280234000000008D
+:103390000228024C00000000022802E40000FFFFA7
+:1033A0000628200000000800022B8BC0000000014E
+:1033B000022B800000000000022B8040000000185B
+:1033C000022B80800000000C022B80C000000066F1
+:1033D0000C2B83000007A1200A2B8300000001387A
+:1033E0000B2B8300000013880A2B83400000000091
+:1033F0000C2B8340000001F40B2B834000000005E0
+:10340000022B83800007A120022B83C0000001F45F
+:10341000062A3D4800000004042A3D5800020458D2
+:10342000062A3D6000000006062A30000000004821
+:10343000062A2008000000C8062A2000000000021A
+:10344000062A31280000008E062A33680000000397
+:10345000042A33740001045A062A3A780000000254
+:10346000042A3A800002045B042A3A700002045DD8
+:10347000042A3E280002045F042A3EB000040461CE
+:10348000042A250000020465062A25080000010020
+:10349000062A297000000004042A29600004046739
+:1034A000042A2F480002046B062A3378000000D853
+:1034B000022A3A3800000000062A3A88000000324A
+:1034C000042A3D880010046D062A502000000002E6
+:1034D000062A503000000002062A500000000002B8
+:1034E000062A501000000002022A50B80000000115
+:1034F000062A50480000000E042A3D780002047D90
+:10350000062A3C1800000026022A50400000000055
+:10351000062A36D8000000D8022A3A3C00000000F3
+:10352000062A3B5000000032042A3DC80010047FE8
+:10353000062A502800000002062A50380000000227
+:10354000062A500800000002062A50180000000257
+:10355000022A50BC00000001062A50800000000E24
+:10356000042A3D800002048F062A3CB00000002699
+:10357000022A504400000000021010080000000160
+:103580000210101000000264021010000003D000AE
+:10359000021010040000003D091018000200049100
+:1035A00009101100001006910610114000000008DB
+:1035B00009101160000806A1061011800000000229
+:1035C00009101188000606A9061011A000000018B5
+:1035D000021010100000000006102400000000E09F
+:1035E0000210201C0000000002102020000000013A
+:1035F000021020C0000000010210200400000001A1
+:10360000021020080000000109103C00000506AF70
+:1036100009103C20000506B409103800000506B961
+:1036200002104028000000100210404400003FFF3C
+:103630000210405800280000021040840084924A82
+:1036400006104C000000010002104058000000006D
+:103650000610806800000004021080000000108046
+:1036600006108028000000020210803800000010C0
+:10367000021080400000FFFF021080440000FFFFA6
+:1036800002108050000000000210810000000000C5
+:10369000061081200000000202108008000002B520
+:1036A0000210801000000000061082000000004A96
+:1036B000021081080001FFFF061081400000000297
+:1036C0000210800000001A80061090000000002404
+:1036D000061091200000004A061093700000004A76
+:1036E000061095C00000004A0210800400001080FF
+:1036F00006108030000000020210803C0000001024
+:10370000021080480000FFFF0210804C0000FFFF05
+:10371000021080540000000002108104000000002C
+:1037200006108128000000020210800C000002B583
+:103730000210801400000000061084000000004AFF
+:103740000210810C0001FFFF0610814800000002FA
+:103750000210800400001A800610909000000024DF
+:10376000061092480000004A061094980000004A93
+:10377000061096E80000004A0212049000E383401D
+:103780000212051400003C10021205200000000285
+:1037900002120494FFFFFFFF02120498FFFFFFFFD5
+:1037A0000212049CFFFFFFFF021204A0FFFFFFFFB5
+:1037B000021204A4FFFFFFFF021204A8FFFFFFFF95
+:1037C000021204ACFFFFFFFF021204B0FFFFFFFF75
+:1037D000021204B8FFFFFFFF021204BCFFFFFFFF4D
+:1037E000021204C0FFFFFFFF021204C4FFFFFFFF2D
+:1037F000021204C8FFFFFFFF021204CCFFFFFFFF0D
+:10380000021204D0FFFFFFFF021204DCFFFFFFFFE4
+:10381000021204E0FFFFFFFF021204E4FFFFFFFFBC
+:10382000021204E8FFFFFFFF021204ECFFFFFFFF9C
+:10383000021204F0FFFFFFFF021204F4FFFFFFFF7C
+:10384000021204F8FFFFFFFF021204FCFFFFFFFF5C
+:1038500002120500FFFFFFFF02120504FFFFFFFF3A
+:1038600002120508FFFFFFFF0212050CFFFFFFFF1A
+:1038700002120510FFFFFFFF021204D4FFFF3330D6
+:10388000021204D8FFFF3340021204B4F0003000EB
+:1038900002120390000000080212039C00000008BE
+:1038A000061203A000000002021203BC0000000484
+:1038B000021203C400000004021203D00000000042
+:1038C000021203DC000000000212036C0000000181
+:1038D000021203680000003F021201BC0000004019
+:1038E000021201C000001808021201C400000803FF
+:1038F000021201C800000803021201CC00000040BF
+:10390000021201D000000003021201D400000803DB
+:10391000021201D800000803021201DC00000803B3
+:10392000021201E000010003021201E4000008039A
+:10393000021201E800000803021201EC000000037B
+:10394000021201F000000003021201F40000000363
+:10395000021201F800000003021201FC0000000343
+:103960000212020000000003021202040000000321
+:1039700002120208000000030212020C0000000301
+:1039800002120210000000030212021400000003E1
+:1039900002120218000000030212021C00000003C1
+:1039A00002120220000000030212022400000003A1
+:1039B00002120228000024030212022C0000002F31
+:1039C0000212023000000009021202340000001945
+:1039D00002120238000001840212023C000001833E
+:1039E0000212024000000306021202440000001905
+:1039F00002120248000000060212024C00000306F8
+:103A000002120250000003060212025400000306D4
+:103A10000212025800000C860212025C000003062B
+:103A20000212026000000306021202640000000697
+:103A300002120268000000060212026C000000067A
+:103A4000021202700000000602120274000000065A
+:103A500002120278000000060212027C000000063A
+:103A6000021202800000000602120284000000061A
+:103A700002120288000000060212028C00000006FA
+:103A800002120290000000060212029400000006DA
+:103A900002120298000000060212029C00000006BA
+:103AA000021202A000000306021202A4000000138A
+:103AB000021202A800000006021202B00000100468
+:103AC000021202B400001004021203240010644029
+:103AD0000212032800106440021201B0000000012D
+:103AE0000600A000000000160200A06CBF5C0000F1
+:103AF0000200A070FFF51FEF0200A0740000FFFF9E
+:103B00000200A078F00003E00200A07C00000000AA
+:103B10000200A0800000A0000600A08400000005B4
+:103B20000200A0980FE000000600A09C0000001416
+:103B30000200A0EC555400000200A0F05555555568
+:103B40000200A0F4000055550200A0F8F0000000AB
+:103B50000200A0FC555400000200A1005555555527
+:103B60000200A104000055550200A108F000000069
+:103B70000600A22C000000040200A0600000030761
+:103B80000200A10CBF5C00000200A110FFF51FEFB6
+:103B90000200A1140000FFFF0200A118F00003E0E2
+:103BA0000200A11C000000000200A1200000A000F3
+:103BB0000600A124000000050200A1380FE000006B
+:103BC0000600A13C000000140200A18C5554000026
+:103BD0000200A190555555550200A194000055557D
+:103BE0000200A198F00000000200A19C55540000C2
+:103BF0000200A1A0555555550200A1A4000055553D
+:103C00000200A1A8F00000000600A23C0000000491
+:103C10000200A06400000307000000000000000094
+:103C20000000002E00000000000000000000000066
+:103C30000000000000000000000000000000000084
+:103C40000000000000000000000000000000000074
+:103C50000000000000000000000000000000000064
+:103C60000000000000000000000000000000000054
+:103C70000000000000000000002E004D00000000C9
+:103C80000000000000000000000000000000000034
+:103C90000000000000000000000000000000000024
+:103CA00000000000004D008B00000000000000003C
+:103CB0000000000000000000000000000000000004
+:103CC00000000000000000000000000000000000F4
+:103CD000008B009000900094009400980000000079
+:103CE00000000000000000000000000000000000D4
+:103CF000000000000000000000000000009802DE4C
+:103D000002DE02E802E802F200000000000000000B
+:103D100000000000000000000000000000000000A3
+:103D20000000000000000000000000000000000093
+:103D30000000000000000000000000000000000083
+:103D40000000000000000000000000000000000073
+:103D50000000000000000000000000000000000063
+:103D60000000000000000000000000000000000053
+:103D70000000000000000000000000000000000043
+:103D80000000000000000000000000000000000033
+:103D90000000000000000000000000000000000023
+:103DA0000000000000000000000000000000000013
+:103DB0000000000000000000000000000000000003
+:103DC00000000000000000000000000000000000F3
+:103DD000000000000000000002F202FA00000000F3
+:103DE00000000000000000000000000000000000D3
+:103DF00000000000000000000000000000000000C3
+:103E000000000000000000000000000000000000B2
+:103E100000000000000000000000000000000000A2
+:103E20000000000000000000000000000000000092
+:103E300002FA02FF02FF030A030A03150000000052
+:103E40000000000000000000000000000000000072
+:103E50000000000000000000000000000000000062
+:103E60000000000000000000000000000000000052
+:103E70000000000000000000000000000000000042
+:103E80000000000000000000031503160000000001
+:103E90000000000000000000000000000000000022
+:103EA0000000000000000000000000000000000012
+:103EB000000000000316035700000000000000008F
+:103EC00000000000000000000000000000000000F2
+:103ED00000000000000000000000000000000000E2
+:103EE0000357037B000000000000000000000000FA
+:103EF00000000000000000000000000000000000C2
+:103F0000000000000000000000000000037B03BB75
+:103F100000000000000000000000000000000000A1
+:103F20000000000000000000000000000000000091
+:103F3000000000000000000003BB03F700000000C9
+:103F40000000000000000000000000000000000071
+:103F50000000000000000000000000000000000061
+:103F60000000000003F7043D043D045204520467BE
+:103F70000000000000000000000000000000000041
+:103F80000000000000000000000000000000000031
+:103F9000046704ED04ED04F204F204F700000000ED
+:103FA0000000000000000000000000000000000011
+:103FB00000000000000000000000000004F704F80A
+:103FC00000000000000000000000000000000000F1
+:103FD00000000000000000000000000000000000E1
+:103FE000000000000000000004F8050A00000000C6
+:103FF00000000000000000000000000000000000C1
+:1040000000000000000000000000000000000000B0
+:1040100000000000050A051F051F052205220525D1
+:104020000000000000000000000000000000000090
+:104030000000000000000000000000000000000080
+:1040400005250555000000000000000000000000EC
+:104050000000000000000000000000000000000060
+:10406000000000000000000000000000055505DC15
+:104070000000000000000000000000000000000040
+:104080000000000000000000000000000000000030
+:10409000000000000000000005DC05E305E305E783
+:1040A00005E705EB00000000000000000000000034
+:1040B0000000000000000000000000000000000000
+:1040C0000000000005EB062B062B06330633063BEB
+:1040D00000000000000000000000000000000000E0
+:1040E00000000000000000000000000000000000D0
+:1040F000063B068806880695069506A20000000085
+:1041000000000000000000000000000000000000AF
+:1041100000000000000000000000000006A206AE43
+:10412000000000000000000000000000000000008F
+:10413000000000000000000000000000000000007F
+:10414000000000000000000006AE06B40000000001
+:10415000000000000000000000000000000000005F
+:10416000000000000000000000000000000000004F
+:104170000000000006B406B70000000000000000C8
+:10418000000000000000000000000000000000002F
+:10419000000000000000000000000000000000001F
+:1041A00006B706BD0000000000000000000000008F
+:1041B00000000000000000000000000000000000FF
+:1041C00000000000000000000000000006BD06BE68
+:1041D00006BE06D006D006E2000000000000000087
+:1041E00000000000000000000000000000000000CF
+:1041F000000000000000000006E2074F0000000081
+:1042000000000000000000000000000000000000AE
+:10421000000000000000000000000000000000009E
+:1042200000000000074F0750075007630763077639
+:10423000000000000000000000000000000000007E
+:10424000000000000000000000000000000000006E
+:10425000000000000000000000000000000000005E
+:10426000000000000000000000000000000000004E
+:10427000000000000000000000000000000000003E
+:10428000000000000000000000000000000000002E
+:10429000000000000000000000000000000000001E
+:1042A000000000000000000000000000000000000E
+:1042B00000000000000000000000000000000000FE
+:1042C00000000000000000000000000000000000EE
+:1042D00000000000000000000000000000000000DE
+:1042E00000000000000000000000000000000000CE
+:1042F00000000000000000000000000000000000BE
+:1043000000000000000000000000000000000000AD
+:10431000000000000000000000000000000000009D
+:10432000000000000000000000000000000000008D
+:1043300000010000000204C00003098000040E40D8
+:1043400000051300000617C000071C80000821406C
+:1043500000092600000A2AC0000B2F80000C344000
+:10436000000D3900000E3DC0000F42800010474094
+:1043700000114C00001250C00013558000145A4028
+:1043800000155F00001663C00017688000186D40BC
+:1043900000197200001A76C0001B7B80001C804050
+:1043A000001D8500001E89C0001F8E800000934004
+:1043B00000002000000040000000600000008000BD
+:1043C0000000A0000000C0000000E00000010000AC
+:1043D0000001200000014000000160000001800099
+:1043E0000001A0000001C0000001E0000002000088
+:1043F0000002200000024000000260000002800075
+:104400000002A0000002C0000002E0000003000063
+:104410000003200000034000000360000003800050
+:104420000003A0000003C0000003E000000400003F
+:10443000000420000004400000046000000480002C
+:104440000004A0000004C0000004E000000500001B
+:104450000005200000054000000560000005800008
+:104460000005A0000005C0000005E00000060000F7
+:1044700000062000000640000006600000068000E4
+:104480000006A0000006C0000006E00000070000D3
+:1044900000072000000740000007600000078000C0
+:1044A0000007A0000007C0000007E00000080000AF
+:1044B000000820000008400000086000000880009C
+:1044C0000008A0000008C0000008E000000900008B
+:1044D0000009200000094000000960000009800078
+:1044E0000009A0000009C0000009E000000A000067
+:1044F000000A2000000A4000000A6000000A800054
+:10450000000AA000000AC000000AE000000B000042
+:10451000000B2000000B4000000B6000000B80002F
+:10452000000BA000000BC000000BE000000C00001E
+:10453000000C2000000C4000000C6000000C80000B
+:10454000000CA000000CC000000CE000000D0000FA
+:10455000000D2000000D4000000D6000000D8000E7
+:10456000000DA000000DC000000DE000000E0000D6
+:10457000000E2000000E4000000E6000000E8000C3
+:10458000000EA000000EC000000EE000000F0000B2
+:10459000000F2000000F4000000F6000000F80009F
+:1045A000000FA000000FC000000FE000001000008E
+:1045B000001020000010400000106000001080007B
+:1045C0000010A0000010C0000010E000001100006A
+:1045D0000011200000114000001160000011800057
+:1045E0000011A0000011C0000011E0000012000046
+:1045F0000012200000124000001260000012800033
+:104600000012A0000012C0000012E0000013000021
+:10461000001320000013400000136000001380000E
+:104620000013A0000013C0000013E00000140000FD
+:1046300000142000001440000014600000148000EA
+:104640000014A0000014C0000014E00000150000D9
+:1046500000152000001540000015600000158000C6
+:104660000015A0000015C0000015E00000160000B5
+:1046700000162000001640000016600000168000A2
+:104680000016A0000016C0000016E0000017000091
+:10469000001720000017400000176000001780007E
+:1046A0000017A0000017C0000017E000001800006D
+:1046B000001820000018400000186000001880005A
+:1046C0000018A0000018C0000018E0000019000049
+:1046D0000019200000194000001960000019800036
+:1046E0000019A0000019C0000019E000001A000025
+:1046F000001A2000001A4000001A6000001A800012
+:10470000001AA000001AC000001AE000001B000000
+:10471000001B2000001B4000001B6000001B8000ED
+:10472000001BA000001BC000001BE000001C0000DC
+:10473000001C2000001C4000001C6000001C8000C9
+:10474000001CA000001CC000001CE000001D0000B8
+:10475000001D2000001D4000001D6000001D8000A5
+:10476000001DA000001DC000001DE000001E000094
+:10477000001E2000001E4000001E6000001E800081
+:10478000001EA000001EC000001EE000001F000070
+:10479000001F2000001F4000001F6000001F80005D
+:1047A000001FA000001FC000001FE000002000004C
+:1047B0000020200000204000002060000020800039
+:1047C0000020A0000020C0000020E0000021000028
+:1047D0000021200000214000002160000021800015
+:1047E0000021A0000021C0000021E0000022000004
+:1047F00000222000002240000022600000228000F1
+:104800000022A0000022C0000022E00000230000DF
+:1048100000232000002340000023600000238000CC
+:104820000023A0000023C0000023E00000240000BB
+:1048300000242000002440000024600000248000A8
+:104840000024A0000024C0000024E0000025000097
+:104850000025200000254000002560000025800084
+:104860000025A0000025C0000025E0000026000073
+:104870000026200000264000002660000026800060
+:104880000026A0000026C0000026E000002700004F
+:10489000002720000027400000276000002780003C
+:1048A0000027A0000027C0000027E000002800002B
+:1048B0000028200000284000002860000028800018
+:1048C0000028A0000028C0000028E0000029000007
+:1048D00000292000002940000029600000298000F4
+:1048E0000029A0000029C0000029E000002A0000E3
+:1048F000002A2000002A4000002A6000002A8000D0
+:10490000002AA000002AC000002AE000002B0000BE
+:10491000002B2000002B4000002B6000002B8000AB
+:10492000002BA000002BC000002BE000002C00009A
+:10493000002C2000002C4000002C6000002C800087
+:10494000002CA000002CC000002CE000002D000076
+:10495000002D2000002D4000002D6000002D800063
+:10496000002DA000002DC000002DE000002E000052
+:10497000002E2000002E4000002E6000002E80003F
+:10498000002EA000002EC000002EE000002F00002E
+:10499000002F2000002F4000002F6000002F80001B
+:1049A000002FA000002FC000002FE000003000000A
+:1049B00000302000003040000030600000308000F7
+:1049C0000030A0000030C0000030E00000310000E6
+:1049D00000312000003140000031600000318000D3
+:1049E0000031A0000031C0000031E00000320000C2
+:1049F00000322000003240000032600000328000AF
+:104A00000032A0000032C0000032E000003300009D
+:104A1000003320000033400000336000003380008A
+:104A20000033A0000033C0000033E0000034000079
+:104A30000034200000344000003460000034800066
+:104A40000034A0000034C0000034E0000035000055
+:104A50000035200000354000003560000035800042
+:104A60000035A0000035C0000035E0000036000031
+:104A7000003620000036400000366000003680001E
+:104A80000036A0000036C0000036E000003700000D
+:104A900000372000003740000037600000378000FA
+:104AA0000037A0000037C0000037E00000380000E9
+:104AB00000382000003840000038600000388000D6
+:104AC0000038A0000038C0000038E00000390000C5
+:104AD00000392000003940000039600000398000B2
+:104AE0000039A0000039C0000039E000003A0000A1
+:104AF000003A2000003A4000003A6000003A80008E
+:104B0000003AA000003AC000003AE000003B00007C
+:104B1000003B2000003B4000003B6000003B800069
+:104B2000003BA000003BC000003BE000003C000058
+:104B3000003C2000003C4000003C6000003C800045
+:104B4000003CA000003CC000003CE000003D000034
+:104B5000003D2000003D4000003D6000003D800021
+:104B6000003DA000003DC000003DE000003E000010
+:104B7000003E2000003E4000003E6000003E8000FD
+:104B8000003EA000003EC000003EE000003F0000EC
+:104B9000003F2000003F4000003F6000003F8000D9
+:104BA000003FA000003FC000003FE000003FE001E8
+:104BB00000000000000001FF0000020000007FF87C
+:104BC00000007FF80000016A0000150000000001ED
+:104BD0000000FF00000000000000FF0000000000D7
+:104BE00000000000140AFF000000000100000000A7
+:104BF00000201001000000000100860000000100FC
+:104C00000000860200008604000086060000860878
+:104C10000000860A0000860C0000860E0000861048
+:104C20000000861200008614000086160000861818
+:104C30000000861A0000861C0000861E00008620E8
+:104C400000008622000086240000862600008628B8
+:104C50000000862A0000862C0000862E0000863088
+:104C60000000863200008634000086360000863858
+:104C70000000863A0000863C0000863E0000864028
+:104C800000008642000086440000864600008648F8
+:104C90000000864A0000864C0000864E00008650C8
+:104CA0000000865200008654000086560000865898
+:104CB0000000865A0000865C0000865E0000866068
+:104CC0000000866200008664000086660000866838
+:104CD0000000866A0000866C0000866E0000867008
+:104CE00000008672000086740000867600008678D8
+:104CF0000000867A0000867C0000867E00008680A8
+:104D00000000868200008684000086860000868877
+:104D10000000868A0000868C0000868E0000869047
+:104D20000000869200008694000086960000869817
+:104D30000000869A0000869C0000869E000086A0E7
+:104D4000000086A2000086A4000086A6000086A8B7
+:104D5000000086AA000086AC000086AE000086B087
+:104D6000000086B2000086B4000086B6000086B857
+:104D7000000086BA000086BC000086BE000086C027
+:104D8000000086C2000086C4000086C6000086C8F7
+:104D9000000086CA000086CC000086CE000086D0C7
+:104DA000000086D2000086D4000086D6000086D897
+:104DB000000086DA000086DC000086DE000086E067
+:104DC000000086E2000086E4000086E6000086E837
+:104DD000000086EA000086EC000086EE000086F007
+:104DE000000086F2000086F4000086F6000086F8D7
+:104DF000000086FA000086FC000086FE00008700A6
+:104E00000000870200008704000087060000870872
+:104E10000000870A0000870C0000870E0000871042
+:104E20000000871200008714000087160000871812
+:104E30000000871A0000871C0000871E00008720E2
+:104E400000008722000087240000872600008728B2
+:104E50000000872A0000872C0000872E0000873082
+:104E60000000873200008734000087360000873852
+:104E70000000873A0000873C0000873E0000874022
+:104E800000008742000087440000874600008748F2
+:104E90000000874A0000874C0000874E00008750C2
+:104EA0000000875200008754000087560000875892
+:104EB0000000875A0000875C0000875E0000876062
+:104EC0000000876200008764000087660000876832
+:104ED0000000876A0000876C0000876E0000877002
+:104EE00000008772000087740000877600008778D2
+:104EF0000000877A0000877C0000877E00008780A2
+:104F00000000878200008784000087860000878871
+:104F10000000878A0000878C0000878E0000879041
+:104F20000000879200008794000087960000879811
+:104F30000000879A0000879C0000879E000087A0E1
+:104F4000000087A2000087A4000087A6000087A8B1
+:104F5000000087AA000087AC000087AE000087B081
+:104F6000000087B2000087B4000087B6000087B851
+:104F7000000087BA000087BC000087BE000087C021
+:104F8000000087C2000087C4000087C6000087C8F1
+:104F9000000087CA000087CC000087CE000087D0C1
+:104FA000000087D2000087D4000087D6000087D891
+:104FB000000087DA000087DC000087DE000087E061
+:104FC000000087E2000087E4000087E6000087E831
+:104FD000000087EA000087EC000087EE000087F001
+:104FE000000087F2000087F4000087F6000087F8D1
+:104FF000000087FA000087FC000087FEFFFFFFFF2C
+:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10501000FFFFFFFFFFFFFFFFFFFFFFFF0000000399
+:1050200000BEBC20000000000000000500000003DE
+:1050300000BEBC20000000000000000500002000B1
+:10504000000040C000006180000082400000A3001A
+:105050000000C3C00000E4800001054000012600FC
+:10506000000146C000016780000188400001A900DE
+:105070000001C9C00001EA8000020B4000022C00C0
+:1050800000024CC000026D8000028E400002AF00A2
+:105090000002CFC00002F08000001140000080003C
+:1050A000000103800001870000020A8000028E00D8
+:1050B00000031180000395000004188000049C0088
+:1050C00000051F800005A300000626800006AA0038
+:1050D00000072D800007B100000834800008B800E8
+:1050E00000093B800009BF00000A4280000AC60098
+:1050F000000B4980000BCD00000C5080000CD40048
+:10510000000D578000005B0000007FF800007FF872
+:1051100000000166000015000000FF000000000014
+:105120000000FF0000000000000019000000000067
+:1051300000000000FFFFFFFF00007FF800007FF885
+:1051400000000361000015000000FF000FFFFFFFDB
+:105150000000FF000FFFFFFF000000FF0000FF0046
+:105160000FFFFFFF0000FF000FFFFFFF000000FF29
+:105170000000FF000FFFFFFF0000FF000FFFFFFF19
+:10518000000000FF0000FF000FFFFFFF0000FF0016
+:105190000FFFFFFF000000FF0000FF000FFFFFFFF9
+:1051A0000000FF000FFFFFFF000000FF0000FF00F6
+:1051B0000FFFFFFF0000FF000FFFFFFF000000FFD9
+:1051C0000000FF000FFFFFFF0000FF000FFFFFFFC9
+:1051D000000000FF0000FF000FFFFFFF0000FF00C6
+:1051E0000FFFFFFF000000FF0000FF000FFFFFFFA9
+:1051F0000000FF000FFFFFFF000000FF0000FF00A6
+:105200000FFFFFFF0000FF000FFFFFFF000000FF88
+:105210000000FF000FFFFFFF0000FF000FFFFFFF78
+:10522000000000FF0000FF000FFFFFFF0000FF0075
+:105230000FFFFFFF000000FF0000FF000FFFFFFF58
+:105240000000FF000FFFFFFF000000FF0000FF0055
+:105250000FFFFFFF0000FF000FFFFFFF000000FF38
+:105260000000FF000FFFFFFF0000FF000FFFFFFF28
+:10527000000000FF0000FF000FFFFFFF0000FF0025
+:105280000FFFFFFF000000FF0000FF000FFFFFFF08
+:105290000000FF000FFFFFFF000000FF0000FF0005
+:1052A0000FFFFFFF0000FF000FFFFFFF000000FFE8
+:1052B0000000FF000FFFFFFF0000FF000FFFFFFFD8
+:1052C000000000FF0000FF000FFFFFFF0000FF00D5
+:1052D0000FFFFFFF000000FF0000FF000FFFFFFFB8
+:1052E0000000FF000FFFFFFF000000FF0000FF00B5
+:1052F0000FFFFFFF0000FF000FFFFFFF000000FF98
+:105300000000FF000FFFFFFF0000FF000FFFFFFF87
+:10531000000000FF0000FF000FFFFFFF0000FF0084
+:105320000FFFFFFF000000FF0000FF000FFFFFFF67
+:105330000000FF000FFFFFFF000000FF0000FF0064
+:105340000FFFFFFF0000FF000FFFFFFF000000FF47
+:105350000000FF000FFFFFFF0000FF000FFFFFFF37
+:10536000000000FF0000FF000FFFFFFF0000FF0034
+:105370000FFFFFFF000000FF0000FF000FFFFFFF17
+:105380000000FF000FFFFFFF000000FF0000FF0014
+:105390000FFFFFFF0000FF000FFFFFFF000000FFF7
+:1053A0000000FF000FFFFFFF0000FF000FFFFFFFE7
+:1053B000000000FF0000FF000FFFFFFF0000FF00E4
+:1053C0000FFFFFFF000000FF000000FF000000FFD4
+:1053D0000000FF00000000000000FF0000000000CF
+:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1054000000001000000020800000310000004180FA
+:1054100000005200000062800000730000008380E2
+:10542000000094000000A4800000B5000000C580CA
+:105430000000D6000000E6800000F70000010780B1
+:105440000001180000012880000139000001498096
+:1054500000015A0000016A8000017B0000018B807E
+:1054600000019C000001AC800001BD000001CD8066
+:105470000001DE000001EE8000000F0000000000CF
+:1054800000007FF800007FF80000021D00001500FA
+:1054900010000000000028AD00010001FFFFFFFF29
+:1054A000FFFFFFFF00090206CCCCCCC17058103CB6
+:1054B000000000000000FF00000000000000FF00EE
+:1054C000000000000000000000000001CCCC020140
+:1054D000CCCCCCCCCCCC0201CCCCCCCC00000000D1
+:1054E000FFFFFFFF0000FFFF000000000000FFFFC4
+:1054F000000000000000FFFF000000000000FFFFB0
+:10550000000000000000FFFF000000000000FFFF9F
+:10551000000000000000FFFF000000000000FFFF8F
+:1055200000000000000E0000011600D60000FFFF82
+:10553000000000000000FFFF000000000000FFFF6F
+:10554000000000000000FFFF000000000000FFFF5F
+:10555000000000000000FFFF000000000000FFFF4F
+:10556000000000000000FFFF0000000000720000CB
+:10557000012300F3FFFFFFF3318FFFFF0C30C30C5B
+:10558000C30C30C3CF3CF300F3CF3CF30000CF3C5F
+:10559000CDCDCDCDFFFFFFF130EFFFFF0C30C30CC1
+:1055A000C30C30C3CF3CF300F3CF3CF30001CF3C3E
+:1055B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2C
+:1055C000C30C30C3CF3CF300F3CF3CF30002CF3C1D
+:1055D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C2
+:1055E000C30C30C3CF300014F3CF3CF30004CF3CE6
+:1055F000CDCDCDCDFFFFFFF2304FFFFF0C30C30C00
+:10560000C30C30C3CF3CF300F3CF3CF30008CF3CD6
+:10561000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF7
+:10562000C30C30C3CF3CF300F3CF3CF30010CF3CAE
+:10563000CDCDCDCDFFFFFFF731EFFFFF0C30C30C19
+:10564000C30C30C3CF3CF300F3CF3CF30020CF3C7E
+:10565000CDCDCDCDFFFFFFF5302FFFFF0C30C30CBC
+:10566000C30C30C3CF3CF300F3CF3CF30040CF3C3E
+:10567000CDCDCDCDFFFFFFF3318FFFFF0C30C30C3D
+:10568000C30C30C3CF3CF300F3CF3CF30000CF3C5E
+:10569000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9F
+:1056A000C30C30C3CF3CF300F3CF3CF30001CF3C3D
+:1056B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2B
+:1056C000C30C30C3CF3CF300F3CF3CF30002CF3C1C
+:1056D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C1
+:1056E000C30C30C3CF300014F3CF3CF30004CF3CE5
+:1056F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFF
+:10570000C30C30C3CF3CF300F3CF3CF30008CF3CD5
+:10571000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF6
+:10572000C30C30C3CF3CF300F3CF3CF30010CF3CAD
+:10573000CDCDCDCDFFFFFFF730EFFFFF0C30C30C19
+:10574000C30C30C3CF3CF300F3CF3CF30020CF3C7D
+:10575000CDCDCDCDFFFFFFF5304FFFFF0C30C30C9B
+:10576000C30C30C3CF3CF300F3CF3CF30040CF3C3D
+:10577000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CF1
+:10578000C30C30C3CF3CF3CCF3CF3CF30000CF3C91
+:10579000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CD1
+:1057A000C30C30C3CF3CF3CCF3CF3CF30001CF3C70
+:1057B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CB1
+:1057C000C30C30C3CF3CF3CCF3CF3CF30002CF3C4F
+:1057D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C91
+:1057E000C30C30C3CF3CF3CCF3CF3CF30004CF3C2D
+:1057F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C71
+:10580000C30C30C3CF3CF3CCF3CF3CF30008CF3C08
+:10581000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C50
+:10582000C30C30C3CF3CF3CCF3CF3CF30010CF3CE0
+:10583000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C30
+:10584000C30C30C3CF3CF3CCF3CF3CF30020CF3CB0
+:10585000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C10
+:10586000C30C30C3CF3CF3CCF3CF3CF30040CF3C70
+:10587000CDCDCDCDFFFFFFF3320FFFFF0C30C30CBA
+:10588000C30C30C3CF3CF300F3CF3CF30000CF3C5C
+:10589000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9D
+:1058A000C30C30C3CF3CF300F3CF3CF30001CF3C3B
+:1058B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C29
+:1058C000C30C30C3CF3CF300F3CF3CF30002CF3C1A
+:1058D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BF
+:1058E000C30C30C3CF300014F3CF3CF30004CF3CE3
+:1058F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFD
+:10590000C30C30C3CF3CF300F3CF3CF30008CF3CD3
+:10591000CDCDCDCDFFFFFF8A042FFFFF0C30C30C90
+:10592000C30C30C3CF3CC000F3CF3CF30010CF3CDE
+:10593000CDCDCDCDFFFFFF9705CFFFFF0C30C30CC2
+:10594000C30C30C3CF3CC000F3CF3CF30020CF3CAE
+:10595000CDCDCDCDFFFFFFF5310FFFFF0C30C30CD8
+:10596000C30C30C3CF3CF300F3CF3CF30040CF3C3B
+:10597000CDCDCDCDFFFFFFF3300FFFFF0C30C30CBB
+:10598000C30C30C3CF3CF300F3CF3CF30000CF3C5B
+:10599000CDCDCDCDFFFFFFF1300FFFFF0C30C30C9D
+:1059A000C30C30C3CF3CF300F3CF3CF30001CF3C3A
+:1059B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C28
+:1059C000C30C30C3CF3CF300F3CF3CF30002CF3C19
+:1059D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BE
+:1059E000C30C30C3CF300014F3CF3CF30004CF3CE2
+:1059F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFC
+:105A0000C30C30C3CF3CF300F3CF3CF30008CF3CD2
+:105A1000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF3
+:105A2000C30C30C3CF3CF300F3CF3CF30010CF3CAA
+:105A3000CDCDCDCDFFFFFF97040FFFFF0C30C30C82
+:105A4000C30C30C3CF3CC000F3CF3CF30020CF3CAD
+:105A5000CDCDCDCDFFFFFFF5300FFFFF0C30C30CD8
+:105A6000C30C30C3CF3CF300F3CF3CF30040CF3C3A
+:105A7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEE
+:105A8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8E
+:105A9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCE
+:105AA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6D
+:105AB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAE
+:105AC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4C
+:105AD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8E
+:105AE000C30C30C3CF3CF3CCF3CF3CF30004CF3C2A
+:105AF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6E
+:105B0000C30C30C3CF3CF3CCF3CF3CF30008CF3C05
+:105B1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4D
+:105B2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDD
+:105B3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2D
+:105B4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAD
+:105B5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0D
+:105B6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6D
+:105B7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CED
+:105B8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8D
+:105B9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCD
+:105BA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6C
+:105BB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAD
+:105BC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4B
+:105BD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8D
+:105BE000C30C30C3CF3CF3CCF3CF3CF30004CF3C29
+:105BF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6D
+:105C0000C30C30C3CF3CF3CCF3CF3CF30008CF3C04
+:105C1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4C
+:105C2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDC
+:105C3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2C
+:105C4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAC
+:105C5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0C
+:105C6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6C
+:105C7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEC
+:105C8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8C
+:105C9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCC
+:105CA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6B
+:105CB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAC
+:105CC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4A
+:105CD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8C
+:105CE000C30C30C3CF3CF3CCF3CF3CF30004CF3C28
+:105CF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6C
+:105D0000C30C30C3CF3CF3CCF3CF3CF30008CF3C03
+:105D1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4B
+:105D2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDB
+:105D3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2B
+:105D4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAB
+:105D5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0B
+:105D6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6B
+:105D7000CDCDCDCD000C0000000700C00002813069
+:105D8000000B81580002021000010230000F024097
+:105D900000010330000C0000000800C00002814038
+:105DA000000B81680002022000010240000702503F
+:105DB000000202C000100000000801000002818003
+:105DC000000B81A80002026000018280000E829810
+:105DD0000008038000028000000B8028000200E021
+:105DE000000101000000811000000118CCCCCCCCD7
+:105DF000CCCCCCCCCCCCCCCCCCCCCCCC00002000F3
+:105E0000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCD2
+:105E100000002000CCCCCCCCCCCCCCCCCCCCCCCCD2
+:105E2000CCCCCCCC00002000000000000000000022
+:105E30001F8B080000000000000BFB51CFC0F003D7
+:105E40008ABB5819180238107C7AE0A58C94E9DFD7
+:105E5000C8CCC0B00388AF02F17E66D2F5B34A2346
+:105E6000D8F7241818182419184E893130EC9244A8
+:105E700088E702D5084A3130DC858A0500D967A554
+:105E8000E81B4EA39836F8BB3A2AFF912A84CE87A6
+:105E900089A3C93F86CA6F5480D03FD5B19BBB0947
+:105EA0002A0F00FE694F6760030000000000000039
+:105EB0001F8B080000000000000BED7D0B7854D50F
+:105EC000B9E8DACFD933994C7642422610700703ED
+:105ED000040D30208FA85427E1D1E0E5E8F0462EEC
+:105EE000CA80AF0892448D356D39373B6412020287
+:105EF0008ECAA1B4A53A207AA247DBD4464B7BF5E3
+:105F0000DC206A73DAD37B9152A52DB6413D281669
+:105F100068F49403BDD796BBFE7FAD3DD97B672661
+:105F20000F5FDF395F1B3EDD597BAFBDD6BFFEF78C
+:105F3000FAFF7FEDA8A297A8971072117EAE256494
+:105F40009D4008C9EBBD5AF78916AD26B9845405A2
+:105F500055632B7DB65E0A1B8DD3E8FD4BC4D01371
+:105F600004EE8F9B432611A2C07B05844C85FF4D18
+:105F70002744CE691D1EF5D37BD2AA2CB85AE3590B
+:105F8000D72A99107D2A3CDF362ED5F3E4FC09A5EB
+:105F9000A75B23F873710C21F5C76F9CFF8AD5A608
+:105FA000FF8D2499B9272FA7BFCC24332F4A847C97
+:105FB00054B828ABD3483FDE070D5DBA3C9690F34A
+:105FC0000D2BE6BF32B6EFF3F512A96D2FED7BFF77
+:105FD0002AA2215E8866AA9189BDEB5E4F48A72759
+:105FE0008790CD859BD87A7329B2AEA4F7DBFE45A6
+:105FF000974B7AE15C2FD37E53FBAE871013C7B566
+:10600000C649BE9FE872BCEF7E2F391E7F9FC8F441
+:10601000DF0C42B00B5DFF74217A2DDCF7142E32B9
+:1060200047D0F6FA67CA49B4343DFC497A7D42F854
+:10603000ADF7D2D291F7FB687F530BA1EF9D54E3EC
+:10604000D75F45F9E8BDEF4BA14DC0477BC6CF21D7
+:10605000017A9F303EB2E8746A7FD3F054FC918E8F
+:106060004E7F4FBCC87F167F5589ABB23AC927E730
+:10607000AF3B80BF326CFCD5BEB8DFF13E297FC597
+:10608000DCFCC5F171BA9DAD9FEC1EC6E8C2E9E526
+:10609000A64F5ABA7CD2F7FAF2D316C0ABA77DB19D
+:1060A0003982A4E0270EAF45AF4F0BEF407C444848
+:1060B0001CE94C484482F97BEFB36B469921009F61
+:1060C000D1E6615847904D4582B7B6DC2D52380372
+:1060D00024D13AAE88B6BBD72C00B803C7E79F02DD
+:1060E00079680E5568B3E97AF569C643F3E835A3D4
+:1060F0005417603D5B89084A808E576D969702BDA4
+:1061000008B69F366F099B80071226643821F7F185
+:106110003511221A326DABF0EB9854EB504927C37E
+:106120008770D1D3F7FD74EB577BDF23178BE0FF2C
+:10613000F71058DF40EF91287BCFA4FF00DF39AE86
+:1061400071F439B46DE3FB00B1B5E9F3A3F00BE2F0
+:10615000FBEE2F64BE6CB24F33A87E504B443D0122
+:10616000FD89912DD37646255544F03C480E528A40
+:106170000C489766422ADB811F493B5938B117BE4C
+:106180005344C0F514DCBE734D0B555DE7CAFC21CA
+:10619000E0F3A04EC8B09CBEEBD9D6401979BCAD97
+:1061A0001D7A0EF93F46F9680C7DDF0C317BB8B5DE
+:1061B000E4653D6A93EF0C41E07CE9E60F62C83389
+:1061C00040CC8055E8B5440C7B039F9E3F64171E6E
+:1061D00007CB1FFEA88D3E64E8F40A72BF61B0FCD5
+:1061E000F169E7B3E8DA57AE1A2DBA6A84D2614B87
+:1061F000F1A294FE477ABAEE23D03FA384841329F8
+:10620000DE1B25085C0E4C87BEC12BA58F9424EFA6
+:10621000BD0E7A49F93356ECED071F52AE131FD667
+:10622000B8DE7AC97897AA4422EB228CA7C2789468
+:106230004FB7041F3609958773C0DB141F527C4A81
+:1062400027B44931413EA43F9D026D7B83E1C45692
+:10625000E48304D2C582CF63880EFCCAB93E479B53
+:10626000AC30053BFCDE7A15E150D147A0E3E87481
+:10627000408A0AD94F3A816F2D7E0536B87829B405
+:10628000BFEEE08356632A4945078B5F01AD8C5F03
+:10629000BF3E38FDE29E6F8913DE41BFE7978D93C5
+:1062A000363B94FE3D999CB4E84391580503D8F8D9
+:1062B00060B3420E089309692A5C46A2F4EE667840
+:1062C00044ED580B5C0BC03F9C8A7A81B40932C004
+:1062D00069D95512CCC17ED30503C713B55AD42B47
+:1062E000923FCCEC2B7F9E1E2E36FF70231ED629AC
+:1062F0007EF3493C2C52FA505D19EA24A037C304BE
+:10630000F88084185F48DC4FB7DE8F717EF692A369
+:10631000F83ED5AEA68EF6CC29C77325FA908EB37B
+:10632000A584243C48A7B8066DB94426B02FA0FA2E
+:10633000C95F40FB6759EC2F2D0801FC59DCBE9268
+:10634000599CBF05AACF289EFDD39CF2ED73C9BF0F
+:10635000CCED711F7D96663F615DDDFEDB6302F76C
+:10636000DF32881FE9CDDF27FED4FEAAE5B75978D2
+:10637000CD1309E293FC54493C51C4D746DBF7BC2A
+:10638000959D80759B159135CD140FE6DB42A809CC
+:10639000E829877BB2E8F3934F4AB85FCA5B567F20
+:1063A00009CCB7BDC11C5B6CF307B7CBB51AE09B3A
+:1063B000F28566B7173790E80B826DFFE509B68C5A
+:1063C0002D1E86FCF7767709980A01F9CFEB8F0529
+:1063D0005F05B9E4F793F8B1B7A5BEEDDC7CC2ED7B
+:1063E000E50DE5613A6F2BE8AE11F8D814283CAD05
+:1063F00005ACFD93C6E1E5603F5B3359FBA3C6776F
+:10640000C28DC817512D42EFD5138E972E8A17A42F
+:10641000BF916FB7AFEEAB7BFD3B64DD077CB6D7BA
+:106420009F735D09D8CF32310468DF1B3BA2AFB147
+:10643000E1E39B9E8A37001F2349422040BF582E2C
+:10644000CA8FE5CF01E341BB80CB5321398CFD4698
+:10645000477ACA15B8B5427F19AE2DC1E7B2519E31
+:10646000C81CFD24CABF245CBC7CF0F29E6EBD013A
+:10647000814452F9F3F74B392857816974DD0EBD19
+:106480005EA8233FF271BF063402FD914D619A0C64
+:106490007A24BE229262BC9F0822F6D3C01E5C41C1
+:1064A000D150B8ACECDFE87A352D3CE5550A97279A
+:1064B000D71F32116C66270C2E039E78A306F82591
+:1064C000472502F2AF158623B7019F924858A0F7DF
+:1064D000B56038B4D5E8BB3E9530FB9043AF179913
+:1064E0007C13E87F4F9E8EFD09D80B6B5D63002EF9
+:1064F00015E1FA0CE89D2B4E1F98CE23487B3918E6
+:10650000B374F4FEACE99CEE7D377D030293AFFBE0
+:106510009BCE874D2A4F2DC7055102A5182F46BA8D
+:10652000689C2EE795A8067EE396AF8A641F6D3FB0
+:106530005ADFBF9F12033FC563B39B3AA3DFC8BBBB
+:10654000F4A9C042E9DEDB7597589948C14F9522FE
+:10655000D3FB5BEE7A383E16E8F98A73BFA7AC0A24
+:10656000A35F4AF77D95400FEB3D6F31B34F643F1A
+:106570005D0FEDAF707FE47CDEA22C92621EEBBA61
+:10658000C7057F21C5732AB9B94FE2FED54E36BE85
+:10659000E5EF9C2FE87F7C0B3F172A4572B814C9A2
+:1065A000EA23A57C3114EF8549BF3B0FDB1EFE2893
+:1065B000512BFA08D8BDC2CE72B82AA4A711F8741C
+:1065C0009748AA52C1B7561211BEC230DD7A50BDEB
+:1065D0005F688AA099C8BD9281F7F357D51E5428E9
+:1065E0005D5A47911098994B603CD0AB07BD683F0E
+:1065F000D55C92F0523DFD5AD1574CB0CB7A21096F
+:10660000032C7A2DEC39E97FD4BE1AF4B9B2316A81
+:10661000225CC108EE110E152D437AB750FFCEC390
+:1066200016E2E0A71653EC04BE8DD3F1C11F8C1BFC
+:106630001528AFE782D4F2C3CFC7147E6BBF712990
+:10664000C485282901CE0932C2494762F4D4195EB3
+:1066500046EE9E453AA9DD69CDDE85F2605E495081
+:106660005E6572D814C0CEC80953A4F0C6AA983E7D
+:106670005072E382DD8EED21D107ED7C23EB9DE8A6
+:10668000FFB5FE595A910AAFD522D36FF7717D78C5
+:106690005E699F8FFE4633958FA2BEFDC39C0EDFC1
+:1066A0008E2D7A703CEA336697ACE75D82E18863B1
+:1066B0008EBCA0E27ADC7ECD3CEED7B41452BF068D
+:1066C000E59D2C003F2683F3470B608F3EF76493D4
+:1066D0008449E1C8007F86FA25A494F9251AFD07AC
+:1066E000FA2F7F85D39FF1B8FC9674FECCD784C86F
+:1066F0000F50DF515505F0EF16E2F3C701BE0BE86E
+:106700007ED2E8BBEE2EBE9F9C2B6D2B6AA1703D06
+:10671000962B3AF861349797C78879E2227D1E2F2D
+:10672000140D803B5E2FE23ACE19CC6F27EF7A1D15
+:1067300076A2D95CA4119BFED9C1E5695B83E69082
+:106740005BF7D5AFC6A391147A4BE7F4C99815C689
+:10675000F8873F9440FAC33A53F9E90F945668FD1D
+:10676000E93FB9445D83F82BAC3825C3B5CCBD5F98
+:106770004A3DAEFB4AEC7EA694BEDF60AF5B289E2E
+:10678000DE561CFE78A704FB2E93A0FFE70D5153A5
+:106790001580AB3E1CE0F786A8B8C1B5BBBC12EEB5
+:1067A0001BB3221AC891659FBDA1C856B89FF52595
+:1067B000790BD0CB5B2E8A12A59F269B24C7263748
+:1067C00053E1A68DBF33A9BAB4E3438B7EA512FC77
+:1067D00054522892B1148ECD1F3768763A75D16D18
+:1067E00008DBB73AF9265EDFBF9EFDB47CF173D1BA
+:1067F0008A8738E9853FF67808A77392FE7DE21A0A
+:10680000FF39E8AD71FA19947E9B0CA027D3177459
+:10681000E385FE435C33C3D08E1B8668DAF4D8C7A9
+:10682000620EE241BE20A35EDABDA6250CF4D2E9D9
+:1068300018405A7A0DA7B2DB5D828A7245F5C655BB
+:10684000D27454C802C43FE74A1B91DE8F517A8349
+:106850001E7B8CD4765DCCED957F2DAAA21FDFD553
+:10686000689637160F456F52F8A85F47F630FFE578
+:1068700012CB7FF97BCA2783F057CE53A3C1EDB16A
+:1068800017F84AEEA62C4DE12ADCC8EC26F86A3946
+:10689000B46D50BBD729F4F2A387CFA394260E8FF3
+:1068A000477A3BEDD363852F0B1EB06FC5CCBEA9D5
+:1068B000666718F44CA098DA2782F66735E06744DB
+:1068C00049BC1CDA2377CFC3757C1BFC503FD8171B
+:1068D00082F8F8A698683429CD7CE148A728C1FE43
+:1068E00099E0FECEA29F7B5E6AF5909EBE6C712FF2
+:1068F000D029507B189669B77BD5525EAF3D1C51AD
+:10690000D289EAD6ED2FA4F513FE2CF1FDD8CCC622
+:10691000306D8F825FA93FB9537CBC11F663114F74
+:10692000B81EE9EEDA4724E3503CDEBDB6CC122AAD
+:1069300063F96FE83C7776291400027E80648F0348
+:10694000DD097689EA9BB5DCAEDD4A2201787886DE
+:1069500088185F3B438E04AEB0F1E14E4965F3B455
+:106960002A6F43FCDE8AEFDE16676D4BFFDCB1DB7E
+:10697000D9BE9D2C1A0EF1DBDB772AB8FE3B5DFBFE
+:10698000D698A4E3B87790DA16C043B342D04F58F4
+:10699000AB1319E2B11B7EF89D19B04FF836B72B37
+:1069A0001F50FE326CFA679D3FA1C27EF69D8E2B72
+:1069B000965D4DE0FD44CB08D89767939476F496A6
+:1069C00056277C03C1EF8697904DFDC221B7092958
+:1069D000E3874F4982236E58AF052641D0E4BC9728
+:1069E0005DCD0AA63FCCDF7A134DE0274A06EF5F64
+:1069F0003B99E5396A67C275A0F77EC6FDD1A1BE95
+:106A00007738CD7B1BB46E15F8BF46362B05B137F2
+:106A10005EA529B5E19120C707CA3B471247BFD6FB
+:106A200041F6AB14FBE9E786F794AE99E2E4BE7059
+:106A3000DF40A26F81DC9D17A3D51827E0707B0093
+:106A4000CF125C65A427C64F8A605E7FAB9005714C
+:106A5000940EF44FBC86ECA0778DA507A85E82B893
+:106A60004F4689F3B93BAED293A46B27CA1786442D
+:106A7000E992029ABF53027FB14C3E9DEC4FE7ABC7
+:106A800086754DC64EA85FEAB87EA926C683B3A612
+:106A9000A17C61BCAE6EFE1813E0A8CB3342A60108
+:106AA0006A3414C6315C7C5573412009DBFEBB4659
+:106AB000EE51418E6AA8FEB6DFBF27C8E2C9E9F4ED
+:106AC000B64234C35F027EAD88789274DAB6ADFB0D
+:106AD000A3B850D9CEF655594BFAD917DF1364F144
+:106AE000E2B55BC666B1B88B535F9DE5F6E127CF93
+:106AF0003CAE76839E79FAC4F5B0CEF5FF53221AE8
+:106B00009DF7EC3399A413ED464205BBB1AE434A61
+:106B1000690F096962F9F3EF6522BDD63DE7492C9B
+:106B2000A0EFAF7BE19D4984C2777653CF6B23C141
+:106B30009F7E5A607171B37BD2627A7F9D4C56A75B
+:106B40008AB34C90D93EE4F48F325680FC0A6D072C
+:106B50006FC671DB972B6057AD7E86AC20BFD27EAF
+:106B600068B7CDA784C45821157C2C1F71FA2981E0
+:106B7000C17740C1FDDFBAB6BD6A94C251D3F621D8
+:106B8000EA8BD9DF7B360078A8392039FCB89A36F1
+:106B9000A9D33309AF27E00A71566106F009E797D8
+:106BA0008E0D185FAD6E7FE0432900EF3BF516C5F3
+:106BB0004BA813F0FAA6145A00ED1FFC63C0A0A85E
+:106BC000FAE0F01301C02B1D778D9A05717C277FA9
+:106BD000C3F81772FA8E47391DF3BD35ED5BD87CCB
+:106BE0002EBDF801FC52D0370E1B919D7974D23620
+:106BF000B83CEFFA67CF3D6AD2F94E3FF7FB474DFD
+:106C00000AF75D7FF9F747BF0E72F9CF5E1DF47A80
+:106C1000CDD3BF0C101B1FAE9359FCE0EC28BA85F6
+:106C2000A2FDCEFECA930087E0EC4BEF8D36E87AEA
+:106C3000CF7EFF4FC30DDABFEEA5B9F9B0FEBAE7BC
+:106C400067E7F7E7C7009F263C76B81238BE714069
+:106C500060CEC28BFCEAA2CBA18E43A301CE33C788
+:106C60003CB83FABA1F7EAA7029D36A09D85F6464A
+:106C70008ADFEA67367F08FAA12F9ECD912206BFF0
+:106C8000A81A0C029DDF9987F4223D681FDDFD6B79
+:106C90008E523A4E4E4FB773E46315F45CCD335BBE
+:106CA000D87C2EBA9D815FAEEC4BB7CD2EBA9D231A
+:106CB000773D560089D78E618E3C8275ED8D9F475A
+:106CC000B222FDE8074BFE07C22BE659285C4BE5D4
+:106CD000F0376490A3E73292745D00747DF6DC684F
+:106CE00042F9E27DA5E766B0073D2F79F47DF4FE19
+:106CF000BA97DE44B93AFBFCEBAA81768CF805EA38
+:106D0000579E25C99FC3E06756339F93D4ECCFECC1
+:106D1000F4047AE9539D58586904F0FE09BC9F6059
+:106D2000FC5E9D38B8444841AFD7E5314CFF27F2AF
+:106D3000102F1BF6FF46257E271D8532A0E389799B
+:106D4000703F1D1DADF5EBB0FE99367AEE6772EA25
+:106D5000EE5F4DE511EC5D92AE09E14D92422ECF12
+:106D6000EEF5C860EFCE825F95326FCAFC99A1E65E
+:106D7000577E263BEBAF92F9158E87F4FCC1E47B7E
+:106D8000A0F50D157F3F920D1CD78DC7D31FA7D639
+:106D9000F7EF717D514DCCCA1197F6F5436412316E
+:106DA0004716F5C27B1A36A894FF4E3F2D613CA8CA
+:106DB000A5FD10EA6DB79EA84E13DFBC20333FA19E
+:106DC000FAC0C149A0CF4EBFFC23E4CFEA674EA86A
+:106DD000102F7EADED076A7769AF3C803D48D8EC57
+:106DE000C1E9EF1E9CC4F4001D3F059D14858D5F15
+:106DF000F3A273FC9A673E748CBFDE6C47FF60A001
+:106E0000793E90C3CB61BD1F1C5608E8D10FDAA5AF
+:106E1000CA547EED07DC1E5A786A797DDE6F200F3A
+:106E200036ED88CF00BBD9B1299CBF1DFCB5230A24
+:106E300001BD4DE4F0EF3DB4DDF1BACF80FC74C785
+:106E400091659261DB87FED085CF9947CDD9997442
+:106E5000BC99DD9169E0A2BAF546D971BAAFB2F139
+:106E600041DDEB95F9A0EF611F6A8C87F94241D8AB
+:106E7000E74A8179952C7F2DEADE94F69A8DA7F862
+:106E80002318AF5274311923837147924423C45796
+:106E900089DFEFCE4F44347B1E6AC5E183B0C5CC99
+:106EA0005DFC62018C132031FD24FA9F2474B11F14
+:106EB000FFCB9D8FB0F09994BF34F9890CFDE6E0CB
+:106EC00041D277BCBE7998A806F1ED16FFDAD6223A
+:106ED0005B1EA625D8270F3357A178681548CA78B6
+:106EE000ED78A562BE9287BBE368AAE737294CAE6E
+:106EF000AE25DDF7AE0138232C9F33CB85AF2F7144
+:106F00007CFDF364BA70AA42CBC1B3A2F89DBD2444
+:106F10001C53E8FDB9AB7A2E7F19BBF37C8E395E2A
+:106F2000BC983178FC0D356F17F12CBA5D1944DE31
+:106F30002E5DFEB8170E93EFC7731C798C436FDD7F
+:106F4000AF75639EA1B6B5C816F71BDEE92561CC07
+:106F5000E319E81F0EEFBCF39BB741DC39B730E40F
+:106F6000257DC7912F5C8D71232B9F2F17863B2189
+:106F7000DE2FEB46B984F32C0F437E61B3C1F205DB
+:106F80009B83FDC7F56628D16605E351D7E0B8A21B
+:106F9000C6EB0F06B9CE6F2C0E209E0314CF20EF48
+:106FA000B8FF81F51D1778DEBCDB94207F78221BAB
+:106FB000F305019994403CE0BCE00B6DC27C823348
+:106FC0006F9E8E7FB7CB26E6CD5B8D3E79F3EF28A3
+:106FD000B67C8396266FAEF99760DE5C23367FB76A
+:106FE000A8B75FAFDCB9F2E63016C665B6CF86B893
+:106FF0004C733671E4CD9B41F0AF22E439E5EAD918
+:107000005877E6E5CFCD59B3C3F63639FE32B679B7
+:10701000FCE98FCDE73641FFDC91A416EBD4E40800
+:10702000596AD383EF292C4EBB4109FF50B1D71DBC
+:10703000717EB0F23F87DE7A0FF90AAE63285E9B5D
+:10704000295F7990AF4E11BB5EB5AE16FF341BFDC4
+:10705000F3857A610AC6CD92EDA0897C110846C3FA
+:10706000E114EF4DF230B9B7E60D94513D4AE54DCC
+:107070003122988F5275BAE135060F7F3AB82C3E0F
+:107080006D36C6B03A289D60FD5EFA754C63714C52
+:10709000887051B876DD787BA83F3FC75AE70C254A
+:1070A0007CD28EF7DC4B52D7EF56AB6CDDCD9155D1
+:1070B0002CBF5EE5CCA742FADA1E679D2E44FF5D29
+:1070C000C13821CBA78A5A84E7474C2B3E1E4CC6B9
+:1070D000C30DA833BCCB047DA8AC6A3705B8E6B2B3
+:1070E0007C4AAE16FD58B1D90759EF6672EBCA0F4C
+:1070F000CE954E0F09BF565DDCD6061DFDF42D0D55
+:10710000416C6F6E30F0DAD210C6FB6E3A361B2F30
+:10711000076FC1BA341FC665D38DFF604308C789A6
+:107120003594B1F178DE9C90CC26E02B55B4E46523
+:1071300018B6FD127F6E163481FC6D17D8F36B5AAA
+:107140002E4579B3F86787D17F5C5A4ACC403E1808
+:10715000EAF87DF9F527B8CEE6597ED4AF03C951D8
+:1071600056279B77B0F328497BC1E6D9314BC379C9
+:1071700076E40E304F9CCD3330FC0C5FDB0E9EC2AC
+:107180003A0485F203A828450FA7AED3E3F2D677D9
+:107190001C0FEAF9E620AB0B538BFD6150FECD06C8
+:1071A000CF3716B27CA35A32BC02EEABA1CBB04EA5
+:1071B0005C2DF5633E4F2D1E7E0BB4B71DDCA25730
+:1071C00080FD2814435E03EC76379173516C307E5A
+:1071D000AB1697DC06FD7590630AC7280FDB6FA915
+:1071E000C557DD01EF1F9CF29AD144FB3717FA42D5
+:1071F0001E90B76ED9C1FF83D61385CE3C1A91A9D4
+:10720000BEA0FA6BDB94DB4B503E355B9D648A7A03
+:10721000419BDED8A0DAF4864AE6988087747A87A4
+:10722000DADFFBD4BCBEE358EF6F5022F52AEA85C3
+:107230000871D6BBA7CE675BF400370BF2917230B2
+:1072400059A7B7A060786F7EDBAAD373E7B5E3F4E4
+:107250005FAABCB6BBFEFCB3AAD3DBA926EBF446FF
+:10726000419DDE8F1512EA84BCFC2FA5D03EA32FD2
+:10727000DFB9C7739FB7A0FE8F06FB9C7472F9330A
+:10728000D5993F2D88BAE87EABD731DF2B202FA5CB
+:1072900003EB979155CE7146D53AEB6A2FA9CF7182
+:1072A000B48BCC118EFE97B68E713C1F1BBFCCF1F8
+:1072B0007CFCEEA98EF684C4558EFE97B75538DA5D
+:1072C00013DBAF73F49F7C6091A33DA573A5A3FF6F
+:1072D000155D6B1DCFA71F5EE7783EF3D83D8EF698
+:1072E00095DD5F73F4AFA7EE900A729BCBEB9073C2
+:1072F000F3457B9EB6358FDA25BACFDF9147190665
+:10730000E3DFACAE4B658F937943F77BB2A1867513
+:10731000CCFB8F9B035722D7A13D958DE11506DE4F
+:107320009F310FAE649AB3BE5635587D32ECE39C64
+:10733000F502CE3A6355DA86793ACFF12F77099381
+:10734000FAD2552D74CAC160EB9415C3F5DE10E571
+:10735000E2BC2517A3A85C60FCED6309CFB5CCC9DE
+:1073600044FFC2B69F423C5AFBA96B34120317D3A9
+:10737000928BF2553D235FC56ED63ECA230EA52ED5
+:10738000CE92BF804DEFC37EC5D233CD6583D3AFE0
+:1073900052E20A873FE9BE3605D6A5D38F051E9B6C
+:1073A0007FEFD68F339448213CD7E4B0496CF11A73
+:1073B00052AB38E01E2C9C9FD40EDC45198EA4D015
+:1073C000E32AA9C5BAAB9615610C02903AE2E0D364
+:1073D0009D8BFF47198C4BFDC219CE7532BFD0ED86
+:1073E0004F53FD86FEF40EEA4FA3BD73E947AAA7EB
+:1073F0004C5EFF65303F82E943F73A3F2F3FFADFAB
+:10740000C059ED875E81A25025EE0FF34402FBC305
+:10741000E6599120C4E7ACBA79EBBD56CFA5384EFA
+:107420002C5715217E19EB9A8BF1FA262DAAB13C27
+:107430007114C769CA16F5547562751E962FD6EA7F
+:107440001F18BBBF9FB88BA69268AA78DA4E0FCBE5
+:1074500007C5F4B55D604733F35403F6DCAD074F61
+:1074600045208E2497C93AECD70905E61D5B7E8F2F
+:107470009028C699B4A0887657ABDF81F30F04EF4C
+:10748000CD1E819FFBD8D22FBC5E3575DC251DBC7F
+:107490005B00DE6903C3EB05788B60FE6D387F8D82
+:1074A000C748897F85842B6703DD4E7C3982E95686
+:1074B000CA36201F3BCAD8BE9C1A02077F5BFB1C42
+:1074C000CADF0F7BF2B07E15F9DA3AE770A347C73F
+:1074D000792CBA92C21C8C6B04A2B1B1C594DF3274
+:1074E000A36C3FDFAB9F181F652A6102F12CD92FD7
+:1074F000627E50E5F110ABDF1F383E9B667523BD01
+:10750000365F29934D426F9D75AC90AE6B72EFBAAA
+:10751000FE8F279BF1279FD7479664615D8AF44CC5
+:10752000B03FBDEDE3F872EBEFEF79B8FE2E20052A
+:107530004C7F972E877C77BA71DC7E4C3D8FF30EA3
+:10754000BDBE9E9F2FF0DFD30571262BCE4782D381
+:1075500052C6E57BF1CAF295BDF45D6E7452FAC96C
+:10756000D3A7629EDC3AAF40D599B35E98D3D7A239
+:10757000AB15472741163FB2E8EC4DE2734FBFF819
+:10758000F482BC5CD1179FBFF2F07CC37F317CBE1C
+:10759000023E0DBD6666B2F3E9E4D05709E6A50ADE
+:1075A0009D7268BD67F1BB7BFD7FFA2FCA4FD6FA8B
+:1075B0002D7E48DFDF4CB9AFB1F2AB999CDF343898
+:1075C000654515CFAB656FB75E0AFBD7A01FF77D8A
+:1075D0009965313CDFAB105307BD9069ED6BF879CD
+:1075E00023AB5EC957EAF4CB34D7FE45E575517D30
+:1075F000CEDB72FFCD7D8E2A895F17BD266B69F2C7
+:1076000063833C7FB48BE7EB0AEAE28DB01F2EB8B0
+:1076100095D5FBEF51C86AA8AF1C51658ABE5CC8FE
+:10762000DF147D3F83AEBFE0C5871A4702496E3540
+:107630008AC0CD7846331C76B8E0AE78B98F3D9FCE
+:1076400002E33CA531BD5B5019C773CE4DCF8FCF40
+:10765000023FE195B796EB101FF828B718F74F6770
+:107660005EF08441FF9FC921555817F6C2CCD7C0A0
+:107670008FFF7D43578E6CE39333DF7D7D86428998
+:1076800074E6B9D767C848AC8463FE0D177F310331
+:10769000E0362B48492DE4EF7495C0B8351ACB97E6
+:1076A00059F53EBB86AB2D70FDA9379BC513F3C5BD
+:1076B0001DD0AE878018F80D3C9E7FF5696339D4E4
+:1076C0005F66772902D4E33D2498A69F5ECF9F781A
+:1076D00048003F4BEDAC85300BBD1F3A042837C73F
+:1076E000B27DC9F922525244F5BEEF70ED78F4A78D
+:1076F0005DF54E16FFCBB309E6FB7A6ED41260AF90
+:10770000B7CBC6375681FD5E25633DCE76F930CACC
+:10771000859B8EC7BD639CF5B93C1E7DE8AD3BE201
+:10772000E5F4FD7BA688C8AFFE1353B2480AF9DD25
+:10773000DE5086F3070ADEAE2C07B03EA67767F46C
+:10774000EE93FC3231B3A889548A4453A178F1975F
+:1077500011F2B68DEF5A4412D6E9F3171A088ED3F8
+:10776000D1A0E1B5AD411F5B4C3706DF6A08E27579
+:10777000678381D7871B4AF0F9830D2187DCC37C9F
+:107780006F97F0760A7FE5F3BA3ED040E7B5C1B116
+:107790006B22957A4AAF5D3C1FF540E9D4ACB5FD4C
+:1077A000C4C1F634740D9B3396230BEA4DEBF4BD44
+:1077B0005BFB817F4FA3B07A11F83577CB917DA821
+:1077C0001FA3058B6CFA91FA6D0584B2E2BD2D23DF
+:1077D000E6CC29407944799976388AFE7841302E72
+:1077E000401CB1E028BB6F9DB7407A5141FB61EE70
+:1077F0001C4101BD594ADA012CB5344A2A68FF9967
+:10780000794BCAE13E99E8BC3F4365F20DE356D09F
+:10781000EB6C2DF2236D3A7CA763B7F92C5DCF1F7B
+:107820003B3C06E4791E7CF94F2AEC0B62BF5235D3
+:10783000F0630A5E3C81750F31A15B85CAD8E35ABB
+:10784000F51C99EA19DC0C627C952A16CA2731D0FE
+:10785000B118FFEC89CDF1C37997E8297BFF5DBEB4
+:10786000E8DDFCE448580B523E4AE62FD6C7C27406
+:10787000D3F902CF5F1CD7D6C5CC4268D3FE53588C
+:107880003B46DF7F213B3A52CC86A28BAA58D79742
+:10789000A06DF5AF8A41BDED9B5CEF107FB408E4AD
+:1078A0002DD9D6693BD3D696599B68EC6AAD77C380
+:1078B000A13FBD067AAEFA45A11D40A37A8FE1FF34
+:1078C000C0435877DBD6D0A5C7144E7F8B0E542407
+:1078D000270409D6D3A909213186EA8F09FCFB14B4
+:1078E00005D3C24623E8D7841202BD19F231BF7115
+:1078F00042828E6393AB0969BE8382795FA0E336CF
+:107900005637ECE6AF67BD2C3F504FCCAD90072308
+:10791000CF283AE623799CF2B465E7F87EF52E2F5E
+:107920006B2A9B4CDF65A07FD6C818075B5F142FBE
+:1079300057E93CEB7F5414A29615F24A58D7B03E53
+:10794000BB7DF854969772B41FE275B4C16C331BBB
+:10795000CE0F541F786834D4055493F8CD5F037864
+:10796000FF95E51F4F1DBC32EB6ADADE40DB107F6E
+:10797000DDD0F1BA1AA5FD8671B8AB3BA65C07EB6A
+:10798000ABDE2612B188C967783CC573387E994C46
+:10799000F9E49AAD23E77A299D9F1A13D645CA07C1
+:1079A0002B7DE39A3568ABFA04909B95BE89CDC0D8
+:1079B00057EB27F2EF359089AF86655E2F45F96268
+:1079C000D8968618D427EC5F59791D98D9E122936F
+:1079D0005BCA88983F94B26398B7F843333BEF0291
+:1079E00029FD8D940EC532E992E97597CAE867B60C
+:1079F000C8182FA6F75B95A940977818CF57B432CF
+:107A0000BD3FF6450FC69D8B6BC377A25FA097E283
+:107A10003E653449FE605EFA12F88D8E335E27E5CE
+:107A2000700EE1C75E162F2C5EB16C3DBC27652E33
+:107A3000F1E1BE5C62E7A0C8B7599C7A979868D715
+:107A400040CE03C548DF5D01C617E6C3A5C817FBD6
+:107A5000C58ACBEE86B8A4B066EBBF005DB38B09D8
+:107A6000D015EEDF43EFEFE7F494B2433AD06F3F27
+:107A7000A7672C219A501F63DD7F41587B27C8DB05
+:107A80003AEFF373348AD7E19E707C18A5C39DDE6C
+:107A9000E763C102A4C3188DE2FDCE2D1D316D1424
+:107AA0001DA7313C42B7B5C7FF997A23989FEC4098
+:107AB0007996B31F5E07F24E9FBFA2D1753E95C364
+:107AC000F5057F5E3C26A93FC284DA1AA9B1579F0B
+:107AD00068D43E14DBFACFA1FAE0C947591DFBF583
+:107AE000743E9077BA0ECCFFF64C9013509FE5A3EE
+:107AF000B080DFE29B3806EBF3E8BA09F8253D13C6
+:107B000065B4B3561CDB3341C4F812F4077EF08D24
+:107B100062FDA9A044406FCA8532EE5765694F786F
+:107B20008201E16396D715F485786ED55B62CBE36D
+:107B300092DE3A606C17E1676E1CEDB19EEE029129
+:107B4000FA95B9C7170AA3E9787778B9BF9D4BFDB5
+:107B50006D7A7FBD97E9A5FB23E69721C4418CEEA2
+:107B600002D44F243215AEF93715E747FBB14B7DF0
+:107B7000FDEA6EF41F76F8539FD39CEE63FBF92663
+:107B8000FF111DF8AD9E50F907B9D019BF59FAC3BE
+:107B90003A9FE0AE27B6F48992CDD65837BF221F60
+:107BA000F480CCEB93643DA4437D6579E634F4FB2B
+:107BB0009EF432BD271DBCF20638A7A1FE2BCB0BCD
+:107BC000EDF146319ED45340DA815FE56098D8F3F9
+:107BD000BF963E6869D0F0FAC4D4711520274F4C87
+:107BE0001D5EA153193834E9C75D90673AB787C95C
+:107BF000EFB9C3B7E1F9C773268B37015B615CB29C
+:107C0000F3113CAFFBB81C7910EB6AA13E8282B441
+:107C10002DDB59BF55CCF16272FDD4ACB0E79B1B94
+:107C200058FC58BD7039C6B554AEC73DD15BF1DCC8
+:107C30008687DA32385FA911D364DF3B6078D00AD7
+:107C40009DDFC3502F4CC2F74D2F8B1F59F522EEED
+:107C5000BA100B9E191C9EBEE7329CF4B0F65F165C
+:107C60001DACF7EB8470BEDE0FDFD45C9048C2160B
+:107C7000FFE8ADEF56F1FE59A88BCF823A9E68FC23
+:107C8000EA22908304EE8FBCFE3A42F8F795904FBB
+:107C900083728FBD0E3DC35517DF475E0C67DB5DFA
+:107CA00017B11E9883D7F1613DAB4CBE29507A9F26
+:107CB000C9F8ED0CF06B6BA87AD02040249B3ACC2D
+:107CC0007F96FBFBF28B7787471A363E170CC73E31
+:107CD000A1FAC0428C23D4ECF763BD7F35E8BFC95D
+:107CE000706EC0ECF238CE0B843BA13E4F39C0C65B
+:107CF0007B12E0A1F7FFA85715C0BA8FC3FE270F6C
+:107D0000EC495462875E0E231E62DEF031A2337DA1
+:107D100026539E88655BFAAC3A061B865D2A71F88D
+:107D20004BBB7CBCEDAB8EC54A7BEB3F8E6BFF0F34
+:107D3000F59B55DF715CFB0FF48776A9F14ED07788
+:107D4000E60B1E03EC177D1FCFEF9A2B4BD00EC412
+:107D50008AC808C0C32BD92AEAB9D8F39E7DA0E708
+:107D6000666BD13735DBBEE14CF61BA361FF956234
+:107D70003CD331DEA8A18D47E7EF00BC5ACF5FC9E5
+:107D8000DE85E716E97B06E60D0B0F8F5E43DBC34E
+:107D90005FF0E0B9216BBFE9E6CB7C2E5F2DAEF33F
+:107DA000802AC89B1FF46D2DCA9927E8CC8359728D
+:107DB000A75E98E0C8073C097696D24F95A310A21B
+:107DC000A4CF4BF1B9C9F9AC85D723A49F2727CD00
+:107DD0003C57A03CA79F67069777C2E558D693DF2C
+:107DE00085E9E7DCA03B4FE2D653D6D5D253DFE29C
+:107DF000FC2993E8153E3ACFBA44FB3C1FBE1D9DBB
+:107E0000047EF0071A3B0755D2F6D0CB609EBFE93F
+:107E100009DFEF9D8EE7BEFEC99B37747958E923D1
+:107E2000BC2EB38F1E62FED5ADCC5FAD9B3F15FD62
+:107E3000BBBAED6374FB3945F7B5EA4286430F0DD3
+:107E4000F31AFC7B7B26EAA3AA0B017CFED9CDE7C3
+:107E5000759C5FE93B9F1F9F5BF3DDE5D2B38726EF
+:107E6000FD74179C73AFFBBE227A6CF3D47D9FD751
+:107E7000FF7BA9DE75CA7B18E45D2E22C9FA2ED0DD
+:107E80000FDB54AB1D6E9E330BFC5A9B7E2803FF09
+:107E9000ABF77DF8CEDD361FEF6F56A6EE9FE1EA19
+:107EA0003FC61A7F21F677C393D43FB01FA3FDE5E9
+:107EB0003F7B2CF8507F3D24BAC6CBB1E6BF11C73B
+:107EC000B3FCEE8BDADA574D19F8345E0EFBA79E41
+:107ED000DB8801DF9F785C0EF94276BED518BF566D
+:107EE0005DB8D441EF5EBC8F73DC7FAF21E8A8D7CB
+:107EF000BD235A8775DA1779FCA98A7AE6F8DE9EDF
+:107F0000918E3ADDBFC1F149E1B83A0D1CD77CC171
+:107F1000701439E4B3178E62C7FD4F0AC7428DE96A
+:107F2000AFE5FC3A5767E766E71A42A889DE9A4B45
+:107F3000EF7B29AF7F995E357A9D2B13D38FDF4579
+:107F40004DB0FEB40DFBFB1BFE7CEFBBD762A22A3B
+:107F5000E8A82B90789DB75BEFC0396F56EFA63934
+:107F6000BE0F675D7D12ABD774DFFFD0C7F0F28D17
+:107F7000CBAB09F8D3D4574F796E6D975FE0DFFB39
+:107F80000C8A8E38376F5B75BE9F155C72069BEF4F
+:107F90001B975F4F20AE2BE7A6FEBEDD413F83BFA0
+:107FA000450B639D784CEFFFBB349F149EE14978ED
+:107FB000AE413C4969F0546BC1A3B3BC604BF0F3D4
+:107FC00081A724C3A25BFFF8D9CAE126172E413E40
+:107FD00092389D5A60FF96A2BF95FF68D13E5FF828
+:107FE000C383A4EF73195F0C7D170D92BEC55C0EA1
+:107FF0005AF4CF179E5B0709CF7516BF05C348AF6C
+:10800000CF0B9EAF0C129E6316BD8CCF173FAD49B0
+:10801000FEEF1F9EBF70B8F333581CA4A5849D27A4
+:10802000F14991078B8481E5C257ECDC676B853E93
+:10803000679DCDBBCEBAAF74EBFC355F673A795A1A
+:10804000A924F2807EC71A583CE00DBE3FF9755551
+:108050005326C6E75DF3B404F765F617B7F9EF5595
+:10806000CE73B903C9F1A40C96FFB931EA7C6FF95C
+:108070008A0C571D9989FD2CFCA51BEFAF056F617C
+:1080800048620E026F145F5945FDEC1B3E6B7CA5E8
+:1080900093BBA1E22BA60F0D5F03C9FB5786882F68
+:1080A0004B5EFF5AF1950FF89AFE37FE1A2CBE165A
+:1080B000FD4D1E8784AF5B872A8FDCAFFD6BC5D774
+:1080C00060E5D1BD6FA3FBBB507FDF17F8ACF1E7D4
+:1080D0009EFFD3E2D11A6F659A7D5E3A7C0E0487CB
+:1080E00075FDD03748BCBAF79F5F345E5DF37F6A99
+:1080F000BCF2F1868CD701E0B0AEF220E5DBF2EB0A
+:10810000DAD4D4DF111D97C9BEE3365EA83D321F15
+:10811000F2C77F27617EFAC89E391BECF540E33237
+:1081200099BF7DA472F606889F9E8B6460EDD9513D
+:1081300031F4F36990575EC4DE738F7F84E3CB9391
+:10814000996DC57FF380AE47238BFB954752695BE2
+:1081500017E68D6CF495FAE2FB0831B64F833CC408
+:1081600082D47058744E37EF50E97B34F2F890F4B3
+:10817000CF40EBFD0FFF9841EA9F04F6CB25C9BF26
+:10818000BB7319E0B34D64F570C7E156017CD78D20
+:1081900060A7E52BF2F7029DEECE64F9C30ED5D8A9
+:1081A00000F913CFE2050F6452BA1D5D9A2DD8CFA6
+:1081B0005FCEC964FBAF19AB52EFBB16723EE87DD0
+:1081C0005F20E353F07798F75BBA8A7D7F8CC8E134
+:1081D000518B6CE74ED7BB9EF7A1476600E1389AFA
+:1081E000E6DCFF02FEFEF225FDBF4F6AD9F77D28CF
+:1081F000DF8DB29F7B4DF219978F33FEE8D24C7A18
+:108200007D43887EE73EE0A3097E766E4826455092
+:108210007F658D932B934E95E2FD5DC5180579CD55
+:1082200014E3DC9C393DFD38E9F06AADC79A074498
+:1082300011BED333576371C46961426641FCD013E8
+:10824000BA9BE50F191FE4F03AC499B5198946D8CD
+:10825000F7CA749D36783BFEEFECFF06CF3B8E8865
+:108260003A9E6F77E16120FDD094C9F2C9B952748A
+:108270009317F226AB8594DFB1DB98C9FEDED1A45B
+:10828000CC64BD14CE336E675481EF5F2C9359FEDE
+:108290008B90E8A885B6F927717E73BF972BB17ACA
+:1082A00023F22693E7B67DEB46A5929F5F70399D3A
+:1082B0009459E2A8735C12B95B01F95CB260A162E7
+:1082C000F8E1B981E32FE570B4A9D15153FCBD7831
+:1082D0004AAB87387E3A8E459BE0BB1FABEB05ACC3
+:1082E0001328DDC8F86EF5C683E2067ADDCBE56FAC
+:1082F00021D0C036DE77395DDBF6F94603FC6DC967
+:10830000FC0D1D98C271F36E82F99027B79F6E81A4
+:108310007C48B74078FEE4C64AA86BE8E6F56D2FC6
+:10832000D3E78D80BF397928DFE3367E5807FAB965
+:108330004325785EE6775B3C09384F60F14B524F3E
+:108340006C3CDF00F5C38FA89D13816FF29A6AEF32
+:108350004B953F7D89D3E18FFE48562A3FD0BA5ACC
+:10836000FADCEAB748369454FD1757BAEC1A877B03
+:1083700098A7F30C4991C74CF261A27F3FED975C3F
+:108380008FFFC295E75D722C759CF1579C7FDB12C5
+:1083900015EBD16E991E3C8762C163E12BD76478DF
+:1083A0005AB64472E8DBD50B325C7E0FC3EB0D1E70
+:1083B000E35158C723FB7E3A11CF51B9EC834F8A62
+:1083C000AAF0FC0ED2A9809E785F32F0FA4683F3C1
+:1083D000EFBCBC41A2DBA783FDAC9752CAD51F39C5
+:1083E000FFBCB1E296A5087F4CD201FE13AB865DBF
+:1083F0005F06FA65851282EFA69F88DD9B799B6DEB
+:10840000FD49BFC605D7AFAB6EE9D76E2D5FE1A4BE
+:108410005B9BCAFC02F33A268777521E9D85FCD5EA
+:10842000BD7D269DFF482267CA56D69DC0DF995A5A
+:10843000CC7F7F5F8CEE9849F5CD2991E549CCAF93
+:1084400030BDB16467A41952A7A7EAAF78A99BF61B
+:10845000F30618DFFDB6BE7FFBE8E6A7713B9DFE85
+:10846000DE8C634485F7A375A9EDC1B7F50CFEF763
+:10847000C442A341BFDCB43175BFFF05CC4CE13928
+:10848000F517A92A557CF22A9DC1BB3A92FAFDAB99
+:10849000F44CF61CEC520A3C9F0B64703DA78F060F
+:1084A0003DBD3A0DBC1F060208EF3BCDF7DF04755A
+:1084B00020EFBBBE03FF4E80F1C5C100E3EF53FBCD
+:1084C000562A7940A71641077E783B3B3401F86D68
+:1084D0004DEC049E7739C0F1FCA62F3225301DE407
+:1084E00065D1DC3C4A978E55242418E9F5FF9501A7
+:1084F000E637E4F2782DB57FEF82FDA3AFBE8BFEA9
+:10850000871C1E7DE34456020575E0A744731DD603
+:1085100019EEF3B1BA52129A6EF7E3BFCCE138B557
+:108520007F68F45E1A71F9417DFCBF7835CEBB3FA0
+:108530004387BA94239552E7B514C893FB33F0FBF5
+:10854000B86EB94837FF50FDC053FB87E6070EB43D
+:10855000EE0D81A241F981E72A1FD9310DE4488D42
+:108560004F4AA57F2D3D7D94C7DFDDFC635DBFCA0B
+:10857000F9E8FD44FF70DDB1DB09CF4DB54E782C35
+:1085800079793FD1E45B0378229D13ED7E299933FD
+:108590007D003BCBF253E9E0DCEED213C07940879B
+:1085A0003BB9BEF96DFD23013B1DDCEB3F25F2FD20
+:1085B000C1A3AC2E776C644D459ED1CB9FDFFA9C56
+:1085C000F8D2B233EE71FEB3F3A165E706E2C3DC85
+:1085D00034799C4970D099BEBF46D655C8D74F0A4A
+:1085E00018AC4DF47970548B94F1BA51628C86F3C7
+:1085F0005FA7F6F9F0EF43995B3D89B15404DEDFE4
+:1086000077F504FB7A7EC5F974F5926CFCFCC4FB2B
+:1086100062687E3ED69D49F81DB7378EE5CC83F65D
+:10862000238745D0D0E4A6BA3512ACEF8D00DB77B6
+:10863000AEDEF83AFA8343E5F3D5B54EFB7F155F1E
+:1086400047D2CF927BA601FFA4C3C36B1C0F4B2361
+:108650000BE7827EBE65A380FAF627300E5DC82D3B
+:108660007218F5368931FB48348A0F6A424EC022AF
+:10867000001FFFC0BF5B254754FB39B9DBB6DD3FA8
+:1086800017FC43B7BCACC8627C5C91C5ECC29BBE16
+:10869000E81F40DF5BFAF96DA1F6603EEDB231A054
+:1086A0005BDF094639B5D6B391C345FDB467F1FB2D
+:1086B000C57C7DA4C7C56F62BCFAC780FF0A0DFDEB
+:1086C000029F87EA7DA88B7EDC877554965C59FEF5
+:1086D0008EFBFD6572D4E13766661539FC77B71FEE
+:1086E000F2377B91BAFF15595FACBDB836EBB3B129
+:1086F00017C3389FB9ED4652AE5BD8799013C73E89
+:108700009A9B4AAE239F100EB73CBFBFCFC7BE9BFC
+:108710007C4D26EA9DDEFD547E02F6CB6EB980FDCF
+:10872000147CF7E3917D3F9B0875BD27B6DF7F532F
+:108730002A7ACED299DF44BAF31DF1BCB50182F595
+:10874000DF84CEF7846D7CEBBDA4BC0C10BF5CB69F
+:10875000F24ADC4FBEB1F2EAD16B4AFBEE2BFAF4DF
+:1087600017A2FFB014E66DE4FBE91D9EAA7DA9F6F1
+:10877000811CAF7DE3C44EFF7EE9C6F266D8526F1E
+:10878000CAB8E64BD114F327F7351B53C7E31EE4F1
+:108790007A2AB9AF31E9BE86E2A37B9514289BD62D
+:1087A000BBAFE9363F9F7DCDEF48CFCF67A2FCA797
+:1087B00086EF7B167FA9D11D5752F84ED1FD8F0948
+:1087C000F223D2F7805FBE957ABFF6387FEF771B32
+:1087D00087A8AF8E39F733E9E4EF7B9F91FCB5A909
+:1087E0003DA3400FFC6EEFC76FDD0FEBD9EB437C71
+:1087F000BBC789E812DF5FF8906F2DFBDCA132FD6B
+:10880000FFBBBF1B817F37DB2D1F84C4AFBF8A3EF8
+:108810003FBE4F9C02DF596CDB9751956A9FB35E58
+:1088200017787CC919EF21DCBF5BCAF94DDFF774FB
+:10883000AD3D1EFD26D757561CE07F67313BBB641C
+:10884000C14215E23DB725E34D04372BFA65857B20
+:10885000E1FB17BFE4E7B9CCB59929CFC7FD86E3A3
+:1088600077A038C48A55CE38C19205FDDB9B938929
+:10887000D47559163FA79B6FA8F6A52D31B4BCD867
+:1088800040EB1CA10FCEBE2C25B55F8278C73212FB
+:1088900052E0BA84D44EFC3145E5C9DD8B119E5FB0
+:1088A0005A7FFFF8E37B27DAFD98FF0F11FE85A1C1
+:1088B00000800000000000001F8B08000000000086
+:1088C000000BDD7D0B7854459670DDBEFD4AD24924
+:1088D0003A9DEEBC091D020818620742001FD02114
+:1088E0004482B2DA810041519A87184948A2E2CA0B
+:1088F000FEBA438720467466C2AA8CBFE3B80D82D5
+:10890000EB286AA2D1418CD8A0F8D8D59DA0AE8B17
+:10891000B3E846C7415E4322A32BB3CB0CFF39A774
+:10892000AAD2F7DE744370C7FDF6FBE338D7BAB7B7
+:108930009EE77D4E9DAAB63915C63C8C7D5B73FBC8
+:108940005F4D628CFDABB579BCD3C1D859FC9B1E81
+:108950007DFECB3AC6221731F6E13A3B8BD8A01CFC
+:1089600036558563D4FB53AA8931E8E85FE1C14AF3
+:10897000190B2D50C33B94C1F5B2705CACB7785E57
+:108980006A30463FF2B9A04665113BA3BFB3F06F12
+:10899000CD9C245DF922A753F4D39A182C62EC885D
+:1089A0001CF7513EEE91307F2FFBBB488C7B247C23
+:1089B000EE716F7E04C61D131DE78666FDB8BD2CE3
+:1089C000B48AB9619C70A2734701C3FF8CD8264456
+:1089D000DBEF759A08AEEC48A689653076876C1B8C
+:1089E00067BC0F057C8DF56BCC7E8B161FB7A77A05
+:1089F00069FEB25C33473F4F6F8A938FCB9CF981FE
+:108A000064C68E6E4BF4133CA6258747C13C2BED04
+:108A10002CE480793EF8E4C59FB1118C2D13F8AF9A
+:108A2000097C6D41781C35F5DF938CEBFAC0E4DCF2
+:108A30000143951DF45BB4F0BB2B85C3EFE8F673DF
+:108A4000C3EFAE143ECF7955FAF9CD3F98A82B1B52
+:108A5000D7FBEF7F7BEF04ECF7DFFFF63B8BB6FF36
+:108A600005A77359243D5A5E52ABF8C34583C77DB1
+:108A700029D53A24B8BF6480E392D3F9D4BF5B65AB
+:108A8000CD1D31D655EEB453FDF981728B07E0B997
+:108A9000FC6EC5A74017339CBC9FE566E6EF80F9E6
+:108AA00030B337BF1AE0EE696DBE2310A39FFF23DA
+:108AB000E0FD8D23901A8BCFE4F363410FB2DE0209
+:108AC00073D012ABFEC25A3D7C7B19AB8A35FF1FB7
+:108AD0003B395F0E951EE5F8C6FA439DC7DD820E51
+:108AE000D36D91DF33155E9C807ECA2E605C437D22
+:108AF000E3B8F73BF5F8338E7FF4CF6A5D2C38BCD2
+:108B000026F83F1800FA89F93D99BE7FC0DA1B7735
+:108B1000137F27F9762018B62FFF09A09DAD9C7D05
+:108B2000C75BF09A25A614D0FA16070E5412BB9D07
+:108B300079B018F1FE6DD5833F2985A91DB5065B77
+:108B400093A1C1D1F58A2FE41D3CCE07B84E90A366
+:108B50001FA13CBD08FB639C6E67C2FF65333646B0
+:108B6000F5D7A3506177D9BC3B347CEB5EFBDD3A93
+:108B700056CCD853D6C0FA64783FFAEEAFD73094CB
+:108B8000792C4CF3FEC2E2BB85E0CD18F1FDA16D5E
+:108B90008EAD9BA05E6A0A97938CF9F203E335725F
+:108BA000C2ECA4F250F1F3611CFC5CA89C92EB8C2B
+:108BB000370E409EE6377786A34D4965ACCBEABDBC
+:108BC00009D7D33F3BC1B90D5038D7EABF1AE1F3FB
+:108BD000C10193A9A580BA35239DCEE343B0826B32
+:108BE0000AEE1F578AF2C7E24F80A954431B36157D
+:108BF000E868862384FD957E38E719C4CF83B536AF
+:108C0000AF8AFD4DF37EAA4279EE5536EF7AE8AF92
+:108C1000AC67C45E37F43F7F8EE264D07EE6EC51F1
+:108C20009E5E585FD25AE8270747B8B7AAC2CCD889
+:108C3000D3F89F97323E6180C55C45965F6C9B0977
+:108C4000F2609CA7CBE40050AF4C7BB1CD0EFDDEB3
+:108C5000D312C872A6C1D236DFD7661FC658468661
+:108C6000BF67BA8FB1D99BEFAFB25F01EB7C54B451
+:108C70000F3DD0E6CF63EC5553B04081EFCD9B77ED
+:108C80005499015EEE4239FE2B6DFECB613D57DDFE
+:108C9000B2630DF4BF25ED9FAACC38EFC572FC9EE0
+:108CA000AA8A9130FFCB65F95FEC385F77926C0F41
+:108CB000F39DC298654474FEE62C18DF25CB9F54C3
+:108CC000CD84F13F2E6FAE30C3F8C7D2FEBDAD6884
+:108CD0002C6393E7943BFD50EEDBFC1F5549809FCE
+:108CE0002E06740AE53F6C3E4DF377AB26DE7FE837
+:108CF0008F34BFB2C5A171F85D617F6AAB8275AF79
+:108D0000B6F7BE85E4DAB43664CF4091A4703AB1C8
+:108D10005B9AFDB9003BCBAEF2482E4DA79DD36BBD
+:108D20005E643CEAB181F218288FD794B378B96BAE
+:108D30003D5B124BDE76BAB81EEE4A8CFDBD228D2D
+:108D4000CB03801BE993D483CCBF33865E1997E6AF
+:108D5000A07EF627B290DD15E5B76B8187A7005F8F
+:108D6000323B9FA7EC6790FE48E3729F85AE75216A
+:108D7000DFCCC12E60E9853E258474CD9A93C2A3D1
+:108D8000907658C43C0FF5876AA2F97A5465493544
+:108D9000F49791C8829DF0F4A4332A437B7FA723E4
+:108DA000DADF7B82EE2B0B03DBB1BFCACCEC92D6B1
+:108DB00082683F30EF0DF609BA799BA7B8F0FBDC6B
+:108DC000925B8B34F02CE2EB003AA07630CC33D3BC
+:108DD000810FBA7AC68DD804F3FB06E5AE27BAAE8A
+:108DE000B29EB91606F5B6B8843CF1F2F69E0A2E8C
+:108DF0007FFA6F4D0A6F43FEB4FB4A104FB2DD0D90
+:108E000002EE15F7CEF919D66BE8B1301BD45BD35F
+:108E1000599EC9CEA1171B4E5FC6C213356573C4D8
+:108E20008A72A7E1F4347A5F71EF7B56E453ECC7A2
+:108E30000BEB5A93E0CFF421DC5A63E39FB1169A0F
+:108E400047C3E934169AA87DCFE114EDDF4DDFCF9B
+:108E5000B7AE687F2A0BA79FAB3F2B7D1F80BB5906
+:108E6000C0DD1A7B9E1B04FD20BC4D1AFA9A2FE828
+:108E70000DA49F1FE5E1A16B8AB6A1BC8F8EBB9E9E
+:108E8000FAEF32031ED10EEC49F4A25D5C66E6F205
+:108E9000B3ACC7E50C2951FA907421F1DAE56A2EDA
+:108EA000A7F5562BCE6D0583E775BF9C97D0A79984
+:108EB0008B83EA52CDFC243F40FF5DA2FFD229C440
+:108EC0003FBFE0F4027C7303F22FDA2DB80E5F642B
+:108ED000FCDCE4C1F33F0DE4854FC02387FF5F391D
+:108EE000C2A80724DC06C33FF73CF8CCA7EF653DDA
+:108EF000FBACB8CE86387CFB802B85DA651E8CA453
+:108F000078A1DE19617774754C4CB80CF9628E89C2
+:108F1000A108C375A3BD5A36206FAF7C7706C8DBA6
+:108F2000CC8132C85B2FE26140FE46ECF668FD1F43
+:108F3000B9AE9CBD01E4B5DB06F82F223BD4CE349C
+:108F4000FEC4EE346EBF4D09B29876CBDFB9927590
+:108F500072ECFFAEAD60BF85F599D3B8DE9FD21B32
+:108F600052102F92AF8D72EA13C18F1F8BE7FFBC97
+:108F70009C52CE23A7AA859CE2EFF783998FF53206
+:108F80003222E315D089CBDE9D380AFD99DBB2543D
+:108F9000EF97C057F314DFB067A1DF1ABBF79E64E9
+:108FA0006F944E6A98DDEB40B883D17416F5FE9C41
+:108FB000042AE31FDA25A7DA154E87CC9B5A333EE5
+:108FC000BE1C92F3B82DCB4AE32DBB6F546A503BC5
+:108FD0003FA127AEB5459E658583F95C9661FEABE2
+:108FE0004DAAE6BB83EBB3B1C9FE6FD2D00E555884
+:108FF0002DCDC7602F3904DF19EDA587B16F0FFDA7
+:109000002F62233E3691739AD9660B33DE24847E19
+:109010006A660713FC1A313568E8C0EECAA3792CDA
+:109020005E081F2F01A6B4BF71C9971A3E7A07E7E1
+:10903000437A213209F934C1C57476DE623590A7CE
+:10904000A0DD9A69F3A19C013C111CF62730730244
+:109050008CFB363C116F95EAAD7B2D6EA403C5D712
+:109060004AD0DF2AFC5616417D73EDF424B25BD959
+:1090700099DB4756033C3C499C6EA11FBBE8C74E99
+:109080007422E4DEAFF3C76E43FD24E5A7C4033BBF
+:10909000A3527FF2FB7EA53ACF09E5FD9E8B4A5A8B
+:1090A00015BDFD83F650D47E4ABF6F16F0E3E4AAE7
+:1090B0008E880958A825E4997D27D4AF4CE26B1E11
+:1090C000E9E27A707F41484DC1FE46C13AE0D55B86
+:1090D00089C1A26647141F60E304117F1956783ACC
+:1090E000387FE0739F8BF3D99C748E942DE9BC9CE0
+:1090F00091C2EB1BE9ED49F17D95C2F1BBA99CCB77
+:109100000963BDE92EDEDF6A7BA82A6384D6BE0A26
+:1091100030A44333E37696DF25E8A482C3ABE2DED6
+:10912000C5A9A837BFED999FCA8AA272F41E25E887
+:10913000F441FD7B2C819F52BCE35F5486FE883551
+:109140002DE87441BDF4A4D8FEF24D621EE9E84F4B
+:1091500043BD9F087FC772FA62F2B317BAB83C4B9F
+:10916000C9AA21798E30F4A29FC2FA434E0DFE5255
+:10917000A798747E83E57431B5BF70BBA1248EDDE2
+:1091800050AAB31BE4B846FBE1D37559347FD9FE2E
+:1091900086AC8F2A99A6FE8DACF71EECEFC635B9CA
+:1091A000BA38513CBBE32E011FB4134231E765D5F9
+:1091B000BDFF14FCC49076FC237CFCE8B849C06871
+:1091C000D171FD2EFFDD2EE2A7CB9D872F864702B2
+:1091D000BC5749DF90DC07BDE4DFEA207D5485F20F
+:1091E0005AFA47C8F7CE54A4F1F20DAE491AFD2839
+:1091F000DA19E5D09F453CE3CF4E6EFFA51E94F6ED
+:1092000062A25751A2FA66B0BE127AC62017CF6783
+:109210005F03BD86B4FADFD8EF53AEEF6B5716C6C7
+:10922000A18FD1FF237665D9E541753CCACD2A854A
+:109230008D82C7E4997A3DDFEDE2FE47B72B49A75F
+:10924000E7E72ED6D78B60BD49F84C1A92BFA2D55E
+:10925000438A8AF28EF7D728E8A1E0D807562FC8AC
+:10926000DFFF1276D017E9FEB791AE3624A614A31D
+:109270007ED8FAA78A315B61DEFDEF5B7CDBB0BB99
+:109280005D9C3ECA17AD6935C37B4B87E2B4318D17
+:10929000DE5ADB79C90A58EF0792FEDD7C1D0DEE20
+:1092A0008875248C9BD3C0C7CFEBD8AB9835F22DF3
+:1092B000AF8ED73BE4B2E8F45EAF287F26FD0F16F1
+:1092C0006EA92CC5FA7EF326107D391D0AC583735D
+:1092D0009A01004007393EDEBFC31756961745D79F
+:1092E000D966AA2E42BDD09691E443BD30D61D3C2E
+:1092F0008CF4DF70281241304D3ED46346FBAEC281
+:10930000EDFF0ADFCB757A55670ECAD5A4437C7E84
+:10931000ED067A070B59D0F9362E6F55F60E437CC1
+:10932000A0EC80F132D68F21BD24EB67B8849EC8B3
+:1093300060C117C8AE626D8CF0C5681D19EB47930C
+:109340007D2FF119B5A3C64E403BAAF0818879194B
+:10935000B4DBFD58ECF8BC45E81158074BF744D78F
+:10936000118F2FA41E93F52C71FC6849EF4955B15C
+:10937000ED53D000F4BD7C91FB3A5C77C3062BB370
+:109380002951F857B803E9389F9C8EAD0AC246D2DE
+:10939000D706D7D34A2EACEFF65B985365F1E7DBDF
+:1093A000B0F6C54B5668FC2DE89FF0B1D5CAEAB4BB
+:1093B000FA54FA1317A773FD73A73B3002C76DDC8D
+:1093C000B5D98AF8BD65FBE7566DBC7BD03A8608F7
+:1093D0002FA58EFB290DB5F630AEB37C9199F057D1
+:1093E000BFC11A4679D4B0B33362427BFA6EE6430A
+:1093F0007E6FE8E87C2B07E092DBE09FA47AA3FD78
+:10940000E53684159C4F0610610FF979112BEA6738
+:10941000235DA33D8C76C95B099CDF4F943B420AD8
+:10942000C0EF8425D880F54E6427F942055178BFF6
+:10943000DD39EB1D05583AF9055B049F6DA66D59A2
+:1094400076A8D736CEEA433AAA700767A5037C5CB4
+:10945000E64017B64F7327FB5AA0ADD7C626907EBD
+:109460001E221C261BE861F2DD9C4FFE263D45DADC
+:109470007B13500E2D4D4F96F612C9A7B72C7C1DAD
+:109480001B189FEF3E977F01D1ABD345E3E63444F1
+:1094900014B4F78DE346E9C9BFF842E81BEC3C2B56
+:1094A000CAF57A2167CA176D577EABA1837A3064FB
+:1094B000905E72766E55D00F84EF2D956EAACF6CAC
+:1094C000286776F2FD887AF87E9346AEC875C49018
+:1094D0002FB7217C1D877ADEE4F22542F427E76B63
+:1094E000C4E78FD2B91D77259805F4DE1A1AE385F3
+:1094F000FEDE1A9148FD497E37F2E78F049DE7D4DE
+:109500006E57306EE04EE276A39C9FACF745FA8C26
+:10951000F5389FC9553D0487D5B566C29B9C4FA5BC
+:10952000353012FDAF76D1DFBE859F597BA1FCD0CF
+:10953000AF0E103DAE6E57FCE417B41FB0CEC7F8A7
+:109540005CE8972AC663AFE62609DBF2D201D22394
+:109550005777F138C1EAAE4EF37247944E0B8EED59
+:10956000BB11E96C75878D2528883FBE5E239D82DF
+:109570007C21BA67212BED67817C0C913C65C1028F
+:10958000F447A4FCDD27EC4BE6E0EF9F10F396FDDB
+:1095900046E56602D17BC1B109FBEC00CFD53EC5E3
+:1095A00007A612D8DBBC1EF41F21F9CBD808F4CBD8
+:1095B00064FF46F8FD5AC8D518787E3E3D861E9158
+:1095C0007AB5E0F1190C9F127F660177D9EF9E748E
+:1095D000BE9FB527DD4CFD6F28E7F1EB0D16AE3FC2
+:1095E00036B4D8C3C8D76FA75DF98E520C707259C4
+:1095F00023F8DC6F5AD680DFF7E7F079B499D68F7D
+:1096000069E6FAEBF574C25F0AE3F289CBA3875EE1
+:10961000E4F2A421E4203FB12158B382F61FDC0913
+:109620003EB4F759F04DEBFCE4283D18F1EB7D61B9
+:10963000AFD50BDFAFEEE07C10855B5847B720E776
+:1096400008EFFB5C723F2258807005FFBD05E30CFC
+:10965000D27F4F591C08257B07F36BBAF0DF27092F
+:10966000FFDD32C5FE17F5DFEBD7FE5336965765A3
+:10967000BD4B4FC92FE027EAF8EA84F0DB0E08BCA7
+:10968000FF41D04B7D6907F143FD97CDC4478E2A3A
+:109690002E4F1C87F47290B11F8BF53F40FD54266E
+:1096A000755CA9A23FFCF78AB395C59FF7CD4AF335
+:1096B0003F4F45BC74AAB42FC5CE80555F06704D90
+:1096C000103010F52C6E1EF73EF1142002F9D2DC9A
+:1096D0006C3D97FD7BBE7E59E42305F15D2F607DD7
+:1096E0006267C5D4DF613CF1A954DF2858FAF19DC7
+:1096F000F3FEE677D0FEC4F6E93ED4D3EED600D131
+:109700004FBF27C1877143B70A962DD0434BC71B64
+:109710002997E1BED833974C40B999E7E67C79ECBC
+:1097200045752DC267FD3F3C3F0DBFD7879574B48B
+:109730001B4F3CF5F77F46BD58B7BD093D0DD6FA26
+:10974000CCEB64879BC25BF9FBA752C9BE3CFAC451
+:10975000E66908F7D68E56FA7EEC89AD54DEF70F2F
+:10976000CFEFF94FB43702293EAC77ECC5CD3FFAC5
+:109770004FA4F39A141FAEA32168E6FBB692BE8DE8
+:1097800072AB732FF1A9A497AB51EF229C6AB9FC7D
+:1097900091F4FC85D8575A56E1684379F6C5A6E49A
+:1097A000BA58F144BF582FC65C488ED52A144F6B67
+:1097B00003AAC1B8465B229B82CFA4A2883517C6F4
+:1097C00059B8B8731AD93DA1CF5762FD79BB12D8E9
+:1097D000268ABF61F016EC7F2275C6C683183C0C42
+:1097E0007E32F4BEFD2CD8D71F5B309643FDE9ECEA
+:1097F000FF796DEFFE11E5688DBD77AFC71B7DDF8B
+:1098000026E234509FF44ED99AD8F1D02AB743D0EB
+:109810002DD79B395DD5795E921336DF288D5D3A61
+:10982000EC60F32610432CA7AEE74A5CC75563965D
+:109830004E24BAC0381FEA9F9083FA5F8D714AE0C8
+:10984000B3456ECE4F194EE6BE14C6AF3433B703E0
+:109850009F8C7D642139B283FA05FB83EC2AEFEB00
+:109860000B77A03DB2C512CC9E84FDB409BDB59D59
+:10987000CF1BDA3B71BF14FA735E3A81FAE9B1B8D3
+:10988000A87D88B79FB5BD4589CE1728351FF51629
+:10989000F657EA403D13AA25FC78ADB4AE635825CF
+:1098A0009BD65D7CC3F828FF1AE33B28CF701FF8D6
+:1098B0004E77F96DEE49D1A78CFB18E1F9327E871E
+:1098C000757FEBF6D3933D95AED32BF1EC957D0BE5
+:1098D0004F72FDFBEAE7246F1A918E71FCE0973A14
+:1098E000FDBB5CD2F12B9F131D2FDFC5F56FE3AEDF
+:1098F000122BD2EDF1757EF65B30401BC53EEB16A8
+:10990000A57725C5795E497062FCEEA4D037F50FC6
+:109910007C7E18F74747ECCA26BFFEE42B09B5D872
+:10992000CF7E9389E0B97FDBC55B5B15ED3CB93F2A
+:10993000007630916A23D8A9DC0E5EB119FDB3D54B
+:1099400075CC87FCDF68A09FC65D07885EA41D5CA0
+:10995000F0F8DC15DCFE4CF025A0FF3693DBA30C01
+:10996000EC51AC9F3633DC6225FA2A2943FADAB788
+:1099700070CF46D4E38D339913FBDF32CCFF4A2EF0
+:10998000AD476198CFB2C5D23EC30CEDB7547A9DB6
+:10999000004980DB76B27BD918ABD0732BC85E6EE2
+:1099A000CCBADE477C669407AFB490DDD5E84DA411
+:1099B000F95CBD4BB98DDB230EC6E7AF107D5E1D94
+:1099C000BE2C8CFBCABF17F093703C69E9B911E15A
+:1099D00071F2252044F87EF54C4EAF69333B488E3A
+:1099E000BCFDCA2CD2E3922E935FB6913E77999D2F
+:1099F0008A8FF4DA3C9B16AFED16AE97D2849E297F
+:109A00007C80E33722F82922F440C46DD5C75B9CE3
+:109A1000A162D4BBBF17F8273182F25DC893D52B62
+:109A200022C44F0D3B797F6E9BBFE4760DFDBA2BB0
+:109A3000B85E94717FDC07A88E212F7EE7E6FAB12D
+:109A4000E0F1659BD15EBE0AF08E2A25678C90A35B
+:109A5000401708B79CBA00D1C155EE9B7D6A01ED55
+:109A60001F909FD8DF6265B1E23C47851CF5A407D3
+:109A70004A31DEECC94C263BC7A3969B12B05D89E8
+:109A8000E2DBE6A5FD4DB2F3FA3DD9BE6D3A7E0F9D
+:109A9000949AA0DE918C648EE7F0AFCD73C7231F3C
+:109AA0007AA59FAEB3FB06FBDBDC6E9CD31E2A4679
+:109AB0003F44EE5F4838845B126BB5F2B34FC02170
+:109AC0003C96C7F3C1BE7750FCDA09E3A05FBFED57
+:109AD000B227B85FDF4AE31F74F3784625AC0FED79
+:109AE000364F61600DD7A7C9BE58F0B853E079DF93
+:109AF000C21B4BD0AF6CAC71F890DF1E7A55594643
+:109B0000F48CC141F4B7832B080F0CF080FCC082A9
+:109B1000DC2F6D6C0E8463D37B35F15F23F29F42A3
+:109B2000F44EF176A0F730A777AEFFA4DF8FF2B145
+:109B30003AC67EA8942F8DD6DED148C7921F1AA7A9
+:109B4000F58E46B80D559E9CB400FF23FF001C9077
+:109B50007F24BF24EFE67CB2A9C55B8EDF37553288
+:109B600067AB461F19FD259C27FA9D52AE8F7507DE
+:109B70000A3D1807304536621E8594C38DBBEF1B26
+:109B80001D2BCF4DCA61BB99CB377B3829DCAAA1ED
+:109B90002FDCDB4B9E404FCADB495A1B3B2E52E663
+:109BA000718878FDD0F222325097A3BCD996144622
+:109BB0007925E344C67EC778145D3C46FA2DB8BFCC
+:109BC00080F5E77A38BD547AB89CB85E3CE5FC2550
+:109BD000FD7B4DC1CF319F289EFE92EDFE52712B31
+:109BE000398ED4A346FCCBFD115C4F7551FC7AED48
+:109BF0007BB97C32D2E372C1275E5C2BD47B4EEC06
+:109C0000670DC62FEF87D59A75F96F6DA6CEBA5836
+:109C1000F12FB9BFC11E320F29BF6EEF3A9E47F533
+:109C20009CC8A7658BCDBA7C2A87CFDB82F1D3197C
+:109C3000F6821295C6E571ACE469EC6BD4C3C5BB82
+:109C4000DAC7609E9227A0DF1FC9AC4DD4ED3F64F8
+:109C5000075DBA726E5D8EAEFEB0E611BAEFC3D785
+:109C60008ED37D2F084DD0950BDB2ED5D51FD53E3D
+:109C7000439F8FFBC855BAFA63C37375E54D2D1D1D
+:109C8000B588978B9FBA4ED76E86D9692E01B88E4C
+:109C9000EF58A6CF1333C033F5CF6A4C3A7CD2537A
+:109CA00040789D61D6E70B5FB24B0F0F4C8BC3FE24
+:109CB0008A99E86FDA9109E7CA632D66E66F7A65DB
+:109CC000FB82C1F4C0ECBDBE400C3F53D2B92C1B8B
+:109CD000F7B1A4FCB850FA8B374F497FF1BEC78368
+:109CE000DBBB1EB90FC3E16219804BADEF5C70B1F5
+:109CF0009C0F2E0CE092FCFDE162EC6F7D5223E59F
+:109D0000037F84058D7DDC2BF84896178452B91E9D
+:109D10000ACC3B8F1DCDE3C0411BDF9F347EB7676C
+:109D200070B9361AE640F019225F7F26F070281EBF
+:109D30005FAFFD7A7F26CAEF2A467EB3B3B9E56BE3
+:109D4000D45B4BCC1186F4FF9058CF169117FAC80C
+:109D50003A27F5F3A8D87F7C6C9D97DE3FBE6E0C4A
+:109D60003DC3EB7CF47EDBBA29F4DC0EF61C3E9F8F
+:109D70005C5745CFA7D605A8DED3EB6AE9B9735D7A
+:109D800090CF6B10BE5819D93981F498F1D2A52122
+:109D9000754878626A5E4C7D19B71F75F139F3C852
+:109DA000D71E5A34FB4D0DFF666524BB0F630EE3CF
+:109DB000643619F733CFD7FEBB75B5B3DF1C3574E6
+:109DC0003E92F4C4CEA48F8EC5D741913FF9BB8794
+:109DD000CF6E0A15C5875794CE62C3A9C67E3207D7
+:109DE0009DF562B41934ED0F1AF8B826981AD36E9F
+:109DF000A811F4596BE3FBEF8B0CFCFD92F8FE52BB
+:109E000006D7779FC49133576798A43F6FA1FDC0D1
+:109E1000417CF7932B62C1777F8657C7C78B820639
+:109E2000BC1AFAF9C4D23ECC1783CFCED78F5C9F31
+:109E3000B1DDC3195C6EBDF8FF297F7E725332F924
+:109E40000F08378F66FD9FDC94541B2B2EF35A06A8
+:109E5000DF0705EB9C15B8C8D40F59D1561CC3BCFD
+:109E60007C9F77A413E343320F203EBD9A298E4492
+:109E7000305407C315F0E1B51642FFE68171226642
+:109E80001CC7678AEA59CCA9619A731EEA607A8076
+:109E9000F6212BE5EFF4E6D0BEFF05D213531F1BCE
+:109EA00075AE7DBA41ED2F50CEECF881E58CE473B0
+:109EB00076E6C151B1F4642D8E7D29AC63CBD4FB21
+:109EC00049CE9CA7DF0B855FADDA4BFBD64386DF1F
+:109ED0002EF790E2526BED29C50CFCBAEF12F83365
+:109EE0003483F1F3589F2584D1CE3F20E6098EFFBD
+:109EF00025DCAF6E9E8CCF7FCE0A7C9801ED975902
+:109F0000B99F383EC3FF119613C53EB035D3BA1181
+:109F10009FCCC9D7718958C74693371FD7F1A5E29F
+:109F20001B8B7E8AD314F6E1338545C6F3BCBB7028
+:109F300010FDB3F48B13BDE8DF268E66AC87E2E13B
+:109F4000BE048C9B5993FAFF7124F2FBEB268C30F4
+:109F5000B2E79D7CBECF3F924BFB2AE801A17C2853
+:109F6000C6F730F54D688743FB6B59F018CEEFA864
+:109F7000D31E32C1BC8A677FE1C27CA8E7BB67D031
+:109F80003E42E4293564C5730B3D27FEEE6AE8EFD7
+:109F9000921E0BC59B2F612AC9F37A337B00F926E9
+:109FA0001E3C8FFF75ECFCAE2B32B9DC93795BC69F
+:109FB000EF79E2FBF13879C48E4CAE17647E8C45A4
+:109FC000E6C778FCE7CC8FB118F2632CE600C37DBE
+:109FD00060CB407ECC6246F931D08F363FE6F88CBC
+:109FE000D8F3708B79584E27C5E93785DE1F1F716E
+:109FF000EE755A4E27E8F2ACA3ED1DF43E5E7ECE20
+:10A000007831FEF138F9496307FACF66A1746D3BE8
+:10A010002F9FF7C03879F4DD62C8F3897EE7F93DF8
+:10A020001BD2389DECCD72BA9742D74B59AF05E998
+:10A030007489C36DC1F85180F93AE9DC8ED9D2DF59
+:10A040002BF96E04D6337F8176B609242DDAD94BED
+:10A05000D65ABEE8D5C8A96ABFBECCB0BE46EE6E21
+:10A06000CA6234DFC4716328AFEF14F3A63ACF217C
+:10A070003717DB55BB59B3DE4371EC865B05FC0E2D
+:10A0800065C786DF7599DCEE88771EE2D6CC14DDD5
+:10A0900039BDDB9DE7969708DF60BAB67F231EDCEB
+:10A0A000F4FD7C70F6E0E61AC6D1CA159EBFFF1714
+:10A0B00087779A3857C5CF05580C79E89BB2B8FC1A
+:10A0C0008BCE9BE7A17FE40CDC9E8972D1EC1DADA9
+:10A0D0003D07D065F6274D80E72121778C70D99D0B
+:10A0E000C9ED37E3BABB443E7DA2CA9A3B35F0378F
+:10A0F000AEF73941E7B2FE060BDFBF82BF801DF02D
+:10A100007203E372EFE1CC11222F3CCD8CF270315F
+:10A11000EF82DDE07C8BF693249C07C14FC0DD0805
+:10A12000C700F3DE8879DBE783674796FF6184CB5E
+:10A13000D203895694FF37DAFBF7A38FDADB63FA91
+:10A1400078243C3F778C3CBC9DE1FEDB9897F7C1BF
+:10A1500033658A8FE751B09964EF28A15CF5ECC5AF
+:10A1600043B77736A604C7207F7C29F2AEA53EDA36
+:10A1700098736C34E6CF7B5DE5ABB23C1477F7A700
+:10A18000231DBD66E374F408F404E5A63D63B7A29D
+:10A190009E79302B5887F5641E1FF3F78FC63C84D9
+:10A1A0000B8513FC59908ECE07A7273219E1E75093
+:10A1B0004A6C3AF94D1C3A31F2079D2F2BFDE1F81C
+:10A1C00043C253EE5BC8F9D565713A944F093763C2
+:10A1D000FE505D9649D4E3F9880F660508CE7DC32D
+:10A1E000BE3E9C00733F64C8F792CF93421E9D6FA2
+:10A1F000FD12DE3F941C3E94187B7EA6ACA1E1E7E5
+:10A20000879A5FBD9C5F71ECF965660D0D7E01D686
+:10A21000FF59DA0FA0C700CFF58867B6A19FE4E326
+:10A220002157EC79960D799E41CB0FA16F257DB317
+:10A23000D0D23ADAAFCF4A8CB95FBF00FC27F47FA7
+:10A240008CFBF6727F1EE407ADB7C6DE7F633AE291
+:10A250007DA65877068BA4E17EE61E1BC5FF8DEB1D
+:10A26000BF42D011C0AB82E035A79FE2188746C736
+:10A27000960B15C6FA6D7C9C78E70BAECE528674B1
+:10A28000BE80950629FE576E774454C0C36D021FE9
+:10A29000D6DC553EB40FCBB3DE3B88EB04F89F18F9
+:10A2A00080A7269FEFD8BA779C232DF1E576BDFADB
+:10A2B0004259738CF5043DC11BB3347E50FD53EFFE
+:10A2C0003A476AF0359EF59AF8F9E87E93CE2FCE9C
+:10A2D0006417E41757639F988FE00A903E40FD8013
+:10A2E0007A67E3EEA925884CB433309FA73F3991B4
+:10A2F000E4686BCEA563BC1A7886B2A47DA9C6B10A
+:10A300001BFF7BF9FF51BB49D1D9AFD1FECDF45E24
+:10A31000E2A7DCF18F31F111F4F8EF213DE6F26FA5
+:10A32000C4A7117EA17B2F4FA3F30508BFE9D1FE7F
+:10A3300006F01F07CF1D1E7F3BF6D720CED1283257
+:10A340008F6F205E61761EB647E13D54BC248A784B
+:10A350001AD80D8F211D586D821F9983CE874BBB54
+:10A360008519EC1B3686FBB73764BDF7478CF76C55
+:10A370004CE12CBBF14709E4072E519C565C37D8C1
+:10A380001F9FFE1CEA0759E4D3BBC83F9476469250
+:10A390007A3669E8F394FEF2F9F2A9F7A13D06F3E3
+:10A3A000996172D0FEE63E585F36C88D1956FE2C74
+:10A3B0009F055405FDCD50F3BA7B615EDFB2338952
+:10A3C00057C0F3A78CC361CD81DFB9D01F9D61B6A3
+:10A3D0001CD3CA2D63BCE38DAC6437E151C43BBED2
+:10A3E00065737E7D31C2E57217C1A5F8959999DA3A
+:10A3F00078CB40BC43AC635E682997A7063927E554
+:10A4000099C9CEEF11617EE6756650DC88C33DA424
+:10A41000303394AF90657452A07CB9409282ED6164
+:10A42000DD5788275B16CC423983693C381E787F1C
+:10A4300059F86C9DEAF3E273BA1230F3798479DE4D
+:10A44000216BCEC3FA267BAFCACFE7C10C32B0BDB9
+:10A450001C8F9793457943CDA91B6FF20E8E633005
+:10A460004732D9BD5631AFA34E47C804EF6D8EC8F1
+:10A4700051CA4F154F63BCE33B532884F9D977AADF
+:10A48000619A6F128B447A303E61071098288EF0E3
+:10A4900007E403F06E1A719E09CE5391BB18E6399A
+:10A4A000FA152CA71BF491C7B186F29E3D01B3416A
+:10A4B0000F0515E49BCC5AE37BBD7EB2B343741EFB
+:10A4C000488904B2CEA69F3F5E638CD35866701451
+:10A4D000F7DFC2EDDE8F13793B4917E9D95CFF3610
+:10A4E000BAAC8CF25D32EC76B4DB4F261FC12397F9
+:10A4F000A837DA506FD82D7E8287D41FABBB6E652C
+:10A50000889FC65DD50CE5E86F14BEFF19BA41A15E
+:10A510003C05796F436D117B1F5AB2A6EC1134CE06
+:10A52000FC7782373440B9E63D363E02F54AA6074D
+:10A530002AF17E96D6F1CCB71ECAAD09C1675FC2BB
+:10A54000F51C50A99F26712E963167FD4EE87FEBD2
+:10A5500075C37C9B704915FD1B310FA8FF3EE6C4F7
+:10A56000BC9141747A06D607F87F02CB30EFA6156E
+:10A57000C15FDC01F5B3DF633EAA23BEA32F82785F
+:10A5800053043DE0FBE9F0BE49D04D61B7C2F7EF9F
+:10A59000DD36CA9F600733895FE6DBF9384DDDE5BC
+:10A5A000D74E827915F64C24321E09F531BF093396
+:10A5B0000C787E1D237FD9587F24D6F752B48AE7C2
+:10A5C000D5E458E9FE2326E4DC6403BF5D16A57FCD
+:10A5D000FA5E22CA4D421FE9F804FB01FFDC5FC6A8
+:10A5E000B7F3A99D9BF3838FC93FCEB797B2E81FFE
+:10A5F000F65B111D87E4EF4CF16DFFA2D994D73DB6
+:10A60000D91CD98B7C7D9978968827F2B51DE0B846
+:10A61000D0DCBCDF03EB495BCB7C2D38CA626F2BEF
+:10A62000F657CA022AC2B9CC795F2BCE6FEAE20391
+:10A63000E9485F4F6617123D5D6EF715260089B435
+:10A640004EF1F99CF0AA76B14270995F6B0F63FEF0
+:10A65000DAFC81FB7A82050B806F160615718E3E3F
+:10A6600058B058138F95797D0B6CE047C7DA77CED9
+:10A67000E67A5CB66F12E74EE4F76DD90E9E5F99ED
+:10A680007D655336E557F07C67E0FBDBB22745E597
+:10A69000088C4BF928F398DF82EB9A27F856F2FDE5
+:10A6A0007CFFED64B7CE0FE8EDCFDF281CDFA145BE
+:10A6B0000AD9830B6BCF6D9FB664CBFDDE3C27C5FB
+:10A6C000B799D4479CAEA4DC9E8B7A1CE56D15E847
+:10A6D0006D8D7DBCF8CE3369D42EF3C9D56787471D
+:10A6E000CFB93419CEB9348A732E4DBB5A2C1948C0
+:10A6F000EFE29C4B53F7E71BB5F97D124E83CFB9C0
+:10A70000F4535EE3026B782F9EFF59B00AD608F52A
+:10A71000DF10E722DEC4731113A274947C5D4284BF
+:10A72000E7CDF9297F2FCF99E4C37C9336D304CAB0
+:10A73000176A4B49F669F37336B53457623D99276A
+:10A7400024CFB52C88B31FFC9C906B5B149EAF1577
+:10A750005A6427787B5476507B4EDF5318A03CB95F
+:10A76000A66C2F8DB345C41130AF74223CC3608EEC
+:10A77000717CF1F646F900FD6DC0FE2A0A7D941F3A
+:10A780005391CAF3CC3CE98192DB8AA2FDD674F3E3
+:10A79000BCBC9AC0D76FF1FCDAEA5284A7519E4B39
+:10A7A000FA32CA75A0BF7D488FDF99B8DE89CAF733
+:10A7B000C0A29BA0BFBEF7AD943FC7EEF62B1668B4
+:10A7C000F7E2BB4E1F9EA7DB501EA8AEA4EF663A71
+:10A7D000EF9751CB2236F85EFA9E751BE6EDD5B1A8
+:10A7E000762BF65767D05BAB1C6F5A913F576DB70E
+:10A7F00044E99161BEA1AF10055DC3CE41710F92D6
+:10A800003F522E19E9988DD4CB9F12296F412E709B
+:10A810007DB598EB39F6A482F19FBEE423AAF09FA0
+:10A8200049DE4D9242CA20E72775BF4DF6CA3490E3
+:10A830000FE89F29582EA6FA5406F93906F3472F38
+:10A840006389445F83EC0431AFD28179737B48CA5A
+:10A85000C5F2298CE17D06122F300ED1B3DCAF9BFF
+:10A8600084F7F0C0F33231EE9D267F5144413CB174
+:10A87000B0A910ED8820D93B46FBA7CCDE9C6487AD
+:10A88000F54D61ED241727EF7F93E424E0F92CCAFE
+:10A8900099D798C4B3CF8E72A61213FF547CEAF1F5
+:10A8A00034CBF19019E1342BCB888F9019E13ADB4E
+:10A8B0003B084F744EC01F074F7E2947985E8E1489
+:10A8C000B033FC5CF27D6FDD817EEFF9EC900F3DE3
+:10A8D000C1AC1C929F7A7B245E5E5D418EE382F266
+:10A8E000EAFA2CDC4FB894F5AEDCA90CA68B93FBEE
+:10A8F000D7AA591AFA9174B95BE4D92BAF8BBCDD96
+:10A90000D264D27351BDC8F15F264A97225D69F0C7
+:10A910007FC5AE84880AF45622DA5F8AF43021AA11
+:10A9200017232687D70AE36E547C6D6A0CBC67B880
+:10A93000BCA4FF269AFC2AD953CC978E7806BC4F2C
+:10A9400043784DB177B49A619E87ADBE9FA3BF5245
+:10A95000CEBC84F772837EA970D498913F2BEC46CD
+:10A96000FCFA09EF95CE41EF4DDF07EFC311EF522F
+:10A970007F0CC1FE04BC2FCC89B15F180FEFC1EF73
+:10A98000897723BE25DF7726382B1C18D7ADE3F94E
+:10A99000C413DF1FD98AE58CD50574CEA533CDF756
+:10A9A000067D6FE6DF4B7BFC2ADE9F58B806BE4370
+:10A9B000B9B3205081E5A6B50AC9CB491F055BB1E3
+:10A9C0003CF26EFEBD647DF31B780F595388B7DFF0
+:10A9D0007D7423DD2711DE28DA97B75760B9A98D7A
+:10A9E000B7FF2AD91E42FFBAEC60B815DF8F7D8011
+:10A9F000CF43DA75D3059D752A2FBC41EDDA79BBBB
+:10AA00009BDFB227927C1276DA34B1CEE98FF175F2
+:10AA1000BA7F7B559517E8F0A6FE9005E9E0B0A94E
+:10AA2000A18CE4651C7FAB5C69CFC3E72C900B8CD9
+:10AA3000F00DF43982E79B6E83211ECBE17686CC44
+:10AA4000D3C47CF16A0DBE1ECBE17127592FC3C55B
+:10AA5000785EF1A3C964B7CA3CD2C8CF98827100AE
+:10AA60005C23E9D73879A5B30A9B495FCE1A2EF348
+:10AA7000497BCDCB60DC92B37FB832967FFD8418E2
+:10AA8000F788C87F97EFEBC20526F43F3A9178E844
+:10AA90001EB3DAF7D12EE94C63BA7B423A0B78B990
+:10AAA000F3D19A1FB7E5017C4DCDE6100AFD7C85F8
+:10AAB000EE3DB9A68745525306CF7F96994578DE7D
+:10AAC000039FFFCA56EBB64D1A3B7DBE141B978FF2
+:10AAD000223D5223F024E5C57C812FE0EFDDC8DF65
+:10AAE0000BECCD64172E12F2FD1616A638C52D06F6
+:10AAF000FEAE777CF399C984F1303D1FAF86E970D3
+:10AB0000BDD0FFF82700FFBA47929DA8E75777E826
+:10AB1000EBD53DF2FE416E5FE9F9BC4EF27958CFBC
+:10AB2000E76038703EFFD938DA7F91E7FA12ECFD22
+:10AB30009F855874BD03FADDC07F0978CE6F0CFA8B
+:10AB40002D269E5F28CA72DC53ED5C0F87400F0BE9
+:10AB50003F8744EDA943B3C3480F25827F251F9744
+:10AB6000087D3E485F5719FD9887883F268A928462
+:10AB7000BBD4CFD00FE967796E10F4F2FB7EF2EF11
+:10AB8000C1FFC4798ED3F3CB2605E47341D45F01B2
+:10AB9000BC7D8D7803796CE7718A7686F22CAEDD08
+:10ABA000EF5813D3EE074947FB0083EDFD88CE8EA7
+:10ABB00037E22B9E5D3F80AF04B09792D08F67C481
+:10ABC0001FFF88CF21E475809C76E4C690D3D67DA4
+:10ABD000BC5EFFD6048A17C8F8B8E437258FDBD5EA
+:10ABE000EF66F95DB9B8FF20FA3F74EB2CDAAFFEDF
+:10ABF00086F969BF1AF38D7263E44BE07EF5064D6A
+:10AC00009CF4505AECB8F5F05CCEEF4B72F9BAC632
+:10AC10007BFC5E1CEF8895C7C58F248A670ADF57C7
+:10AC2000B83897C7B9978867B9781E1179D8475C43
+:10AC3000FA78BAAC5721C6F9729DDDBE412357BCE4
+:10AC40003FB335A3BEF2148ABCF5359C5EFB5E496A
+:10AC5000DBAABDAFED9ADCF22508474FA1DF9A8D44
+:10AC6000719657B85E6834F75A31BFE41A77702A84
+:10AC70007E6FF432FF0BD88FB7D73A0FE0DC27F6A0
+:10AC8000E9FB2CDCDFE84BE04F39AF6B72AB97E0B0
+:10AC90007AFB6EED25F93050AEEE25FEBF2637402B
+:10ACA000E3F6CD97DF45F9C7BCCC847F582EF882F8
+:10ACB000E2BC31E2BA83E3B8FAFB679AACB1F7972A
+:10ACC000595EB22E3E7B43378F1BDE68671B73E1F4
+:10ACD000FB92EE4CF21FEA5242A39D14C7FBEFC554
+:10ACE0005DFB86F5D0BA3695F7E73F5A4AFBB814B4
+:10ACF000F759DDFD36C9B9D5924FBAF47C522FF021
+:10AD00007BBEFD0F635C7C08FCB32616FFBC8CFA8F
+:10AD1000C91285FF6D220FA9526DA8C0B8D0A91520
+:10AD20008CCEBFDEF6AE4AF474DBB30ADD0721ED4C
+:10AD3000B3D502BEF1D683E707BC1AF981E707BC99
+:10AD40001AFF0CCF0F68CB787E405B1FCF0F68BF18
+:10AD5000E3F901ED773C3FA02D97B0E5AD18676BA7
+:10AD60006A63CEB0979F27D0B6C7F304DA329E2726
+:10AD7000D0B6C7F304DAF229C6E178EA3195E2F4F5
+:10AD800078AE40DBFEE677276621DD7425F03C32A5
+:10AD900016F2F714015C5608B8E079036D7FC753CB
+:10ADA000AE7C8701DDADE85939079F97EC5AA5EBDA
+:10ADB000AF5E6D203A64ED5CEE36C33F243FD52292
+:10ADC00015E7F1ED2E85A517E0FDE106FDD9BD796A
+:10ADD000238A9E5BC2FAF7F54C13AF2D181C977FA0
+:10ADE0003957E421E6B01C6D9C264A070E5F04D754
+:10ADF000FF91EA8B450725ECA2548ACFBCA362ECF5
+:10AE0000817DC59AB75CAE68E2F70678D8B2F4F4F3
+:10AE100090E0D5D343D2183D3D24FBF4F4903A455D
+:10AE20004F0F69FE71E7846F7A959E3E8CF09D020C
+:10AE3000FF207C27E0CD9018578275629CF72F0584
+:10AE4000DF2F72C5BE8780EFB7ECF20A87973ED737
+:10AE5000D8CBA2F649E93BCDB4496B8C7B4A384A42
+:10AE60003B41C62F2731EEA7DBF1BC6521DA01DCBF
+:10AE70007F43FD8F7C7ED8CAFD36A420949337B1E2
+:10AE800020C9A39B0CFAFF66C74356D4FF83D60B99
+:10AE90001617DE1B685C2FDA514C134F32EA7FA580
+:10AEA0005B892417E372BBA55C0E9E2563C7AF0CBC
+:10AEB000455EFCDEE1B7E579681C662FD3C57B6390
+:10AEC000DA73721E122E727C1B6B56B3909EC718DB
+:10AED000ED2FBDBF2CFD6BEA54138F96FEB1F44FDE
+:10AEE0008C7056871790DD35D129FDE29EEBF1BDC0
+:10AEF000F4878D7EE8F9F6A5E68594DE9F1744ED8C
+:10AF0000C92BC4739E8817C1B27EFB6FD0F872C57F
+:10AF10003B0CC79BBBFB220FD2CB46A59919E6770A
+:10AF2000F055E84735F5A7F3F84B50B75FF5B6D2C3
+:10AF30004BF35EC0FCF7E0B351C4D31ABBDEA67D71
+:10AF4000D4C62E1E2F60BBF47831DAFBAB5887B520
+:10AF500040196CEF37B01EEACF68DF0FA293F3E819
+:10AF6000F18E3C79DF16CF1760422ED50978C5F3F4
+:10AF70000BCC08E0A9D1FB3B811FE6E54D8AE6D169
+:10AF800066B8C08F51310FC36B8D9527C5F0721510
+:10AF9000B049973B6A484E2C6F1B1497B0123FB5CF
+:10AFA0009F7B7DD20EB81F7C377C96E67979DC20BA
+:10AFB00071CE3B7EFC5CDA93AF3DFFD164E5E70EDA
+:10AFC00059B3FE7CFEDA3C933C3FA50E65FD83E160
+:10AFD000FAFDF2F265FE01C0EF2E2DFCE43E825C2C
+:10AFE000CFEF27F53C89F1433579A61DFD5AAF2BEC
+:10AFF000D882F5871DEC3DACA03C7378293FE4E492
+:10B00000AEA31FA3FF2ED7C758EF16BCDFB66E97AF
+:10B010004AFE60DDAE37C82E8AEFEFB50FDCA32005
+:10B02000F6377E126B5E32AFB9522D4AEDD5D8E9B4
+:10B030004B851F307978E0216C57FA615E0ACED7D4
+:10B0400032A283EEC5EABF83DBC16E95CD44F881A1
+:10B05000DEE37ADF61A67D077752484D413B6E29DA
+:10B06000E3F7D0F99A7D482AEAB0228AD366DCA1B8
+:10B0700006D0FEFE74CDF2343CAF9C91BC22AD10E4
+:10B080009ED36DFC5E9A0CC514E0E74E97A5E13D9A
+:10B090002037D8F8BE7CC15F27450A81DF5EB7F252
+:10B0A000FB46DD4941BABFA03F4DA5F91C5B074BEC
+:10B0B0001B85FB1EDF4CC47B0772CE3826E07CB2BA
+:10B0C000C5BD163FCAE3F7DC1C7FF6BB89E8AFAA13
+:10B0D000671D74BE5DD29FBB30B6BFB242C0A3D164
+:10B0E000C3F3DE4F0AFBF190D86F9579F06BC43E45
+:10B0F000E0A1D103F78379302FA431C19FBA10E3C7
+:10B10000110754CA6BFFC6E94F4D23BB99E7B3AF94
+:10B1100011F6C34991F7B966F68C4CF42FE2E54B72
+:10B120001FC8E376EF0F755FA5CC3F8D0B873433D7
+:10B13000335F42F72E05CE55EFD53FAB31E1795A5B
+:10B140007C8F9737DF97A7E8F2E21B312F1E5EADA9
+:10B1500079A53C939D235FBA11EF23D7E4D7A09F35
+:10B1600086EB6BC4FBC8E99ED213744F07F683F7D6
+:10B17000869DEFDEC815621E8D984F9EAE7DCFF97D
+:10B1800039DABF9BBE3F2DE0F6F43BA6AA6D31E64F
+:10B1900099378CCBA7711E7300F7252F8EF07B3F5C
+:10B1A000E3D593E7B8E3CDAB6B46EF8D386FCCCFEB
+:10B1B0008C355ECA304E2772BE5DAEDE9501BE9FF5
+:10B1C00037BA3A595376F6E7CFD5C8D7D9023F5D9B
+:10B1D00057F5E6D37D00B3B9FF1A0FCF65E66605D4
+:10B1E000E190E00A06D11E91F715E37DC63CCF231E
+:10B1F000744E7C47E1ACEACE1F0C86B395BECBFE05
+:10B20000A4DC39FA884A72E7E807821F99DFA19423
+:10B21000A1BEE27C7594F1B8EED176FEFB1FCB8225
+:10B22000A02B407E2CDD5E3F070F1FAFDC3171236A
+:10B230008A7F7C7F37C89FA5598C4D83E7B20DFA72
+:10B24000FDB16FD903A4E7563C60D467012BCAD97E
+:10B25000950FE9EBD7B107BE46FBA0CE60F76608B5
+:10B26000BD6BB47F670C13F66F192BBB90734E8FB9
+:10B2700030FFEC61A4FFF97EDB24B19F6EACFFBC14
+:10B2800097D3C36D3BFE60C59F048AD7EF319017FB
+:10B2900023A1DF13EB9CF45C32CC5F330CDA350D69
+:10B2A0000B2EC471FA0E70389F6A38B592E2D2B58F
+:10B2B000DC0EB0E1252BF09FB6EBEDE447DF8BF71A
+:10B2C0008C019C6D366E5F48BB4A556F57F1275B0A
+:10B2D000A6FE6E451AAECFFDCCAC2AF43F3CCF247F
+:10B2E000F9111F9BCAFD2528BF37553B689F78ABD6
+:10B2F00089DF4368B7F1FDB9F0D353F7613878645B
+:10B30000C7E619E86738BBF746302ED166E2FBAFD7
+:10B310006DD398B8C79A8FD7D45DDD89F3CAAF01D2
+:10B32000790FFD6D2AF0973835FD33612F350A5CB2
+:10B33000F4BD76D14FF1DEAB9FBF43E62AAC730478
+:10B34000C5BFC6314E3732BF847E1B43132F3A012F
+:10B35000FA8769CE3F8FEB50229614BA5F8FE2D8FE
+:10B360000DEB2319D7A3FEFC25DFAF95F373BF9E2A
+:10B370003D03E3FD529F5E8FF96D18071676EF22AD
+:10B3800026FFF87E41ADA0EB45C2DEBD3E89C37904
+:10B3900019F3D1F9ABEBEC2C05E3CBD757744CA2E6
+:10B3A000FBAFEB2D6968AFC8B8773CBCC78BCF3417
+:10B3B0003E99CCEFCB51FA476327C73006521ACDDE
+:10B3C000B737F6B36398E0E7D1C24E1BC9FCB8CFDC
+:10B3D000D2B8E722CAC7B725F27D35906F76C4EBA5
+:10B3E0007ED4E7B0EE5B5E4D88F07DE3B0B81787A2
+:10B3F00085683F664F26ED2BB80BFDB4EF7ED2D2A9
+:10B400009B4FF200E49702BA73CFB04FAE31E3FD29
+:10B410002039604741F9F82F0E5F83BFCFD238A2A1
+:10B420007725DE179EFEF8595E1ED77B18CBC31E0C
+:10B430004FBC96CA137A57AA509EF278D6B5D41E3E
+:10B440001D2820ACCAC7875F8BE7FC8E89F825F3DF
+:10B45000F5D23D418DBB2F3269E38325F95C4E1F48
+:10B460004BE0F58E15B0257311DE637A476B7F379D
+:10B47000C1932FED526E97C975CA762C2B76FFEFCC
+:10B480000B3D708BB8DF677A126B4BE0FB1521B474
+:10B49000AFDEECBE88E0F2C2309780572FDDDB28AC
+:10B4A000FB319EEF97E3AE42BD8D72DDA23F4FF4BC
+:10B4B0001BA12F609C0D344E91BF04EFE5699C9B4E
+:10B4C000578278037C9905BECCDC0FDC4A78C67EB7
+:10B4D000D38A498F4CC43CB137CF40FD82E8BC8D44
+:10B4E000F471588C734B2BDF67EA4F2B243A9A9EEA
+:10B4F000C4ED3F560AF003393645C0AD245F9CE3E6
+:10B5000019C043A642FDB70AF8E5F1FA17BADED32F
+:10B510003FD07A3578F263DEF19BBBC6129EA60C53
+:10B52000D0C1665D3FC75A0CEDA6F0BC94465721CA
+:10B53000B5BB57DCB32FEF2DC67605D06E7A45FF2D
+:10B5400044E407796F1B0B4D2367BD41488B817B1A
+:10B55000D83A787E0A1BE9E7F711CD9D532AD6E742
+:10B5600014EB736AEFA51BE0C38FFAF36B34F75249
+:10B57000CBF703701FE8AF6882E84FC7CFB1FA433B
+:10B58000BE88878F71F97F617CC8791AE0390067BE
+:10B59000C3FC243C918FA95D919E9FE43C87E59B71
+:10B5A00084BF6DE0E782EF399EC8EF5FFD37221F51
+:10B5B000D2ABA7E7D55D0526DC3F95EDDA3A5A0216
+:10B5C00028E765BCDBD6551D42FDD7D45D4E799B7F
+:10B5D000AB7FF5ECCB2168BFEAF987533099F6A829
+:10B5E000B93D03EDDC861DF7A4F871BFC41C4A41C8
+:10B5F000F97934AC56C53A0F181278907654A3D026
+:10B6000037C79EBEFF1A84C77FECB038518F363DD6
+:10B61000658BD8280E720BD95150FE9C97EFFD1AFE
+:10B62000FDD2A65D7A3B69D53F3C9CE1257A0AE5CF
+:10B630009AF08C0B8BE43278366EB7F8226E1E4F80
+:10B6400084615813EBDF88F333B6C7799C06BC37A7
+:10B6500075A84BF13CAFF13B4812B2C39ABAEE2742
+:10B66000BBAB491B67003CD4C5B1BB6ECDD7E75B14
+:10B670004BB8B0B087EC9AD65FFEACF87307DEA784
+:10B68000F94F294A91565FAE27389DEA58FEF7BB1D
+:10B69000BDF1F5EA49B40B6CDA761CAFDE5D0AED5C
+:10B6A00049B06EFE6CB04452D0CF6FD86AF181E6DB
+:10B6B000650DCF3EF124EE87B04F6C74FF41FDB3B2
+:10B6C000FB3FBE14CAF59D16F71C3E7D879211C53F
+:10B6D0004F9397DB27121FAB5EDC4FF70CE27BB476
+:10B6E0006B255EEA3BF75AD9F8C1F0ABE8D82B7E60
+:10B6F00077C1809F8ECFAFA4FB3C7FF99D15E9FAFF
+:10B70000E81E8565160C6E5FB7757F0AD21FC209E9
+:10B71000FD4B89A701BC0DC257E49ADDA5548FE209
+:10B720001AF1F036379FF178D0AF9E7D0E7F07B0CB
+:10B73000EE37361FAEBFEEB9DB53701D5F999B39F4
+:10B740007DFFE29E0C3F8C5B67096538E9C9DFD756
+:10B750003D7E07D1DDCD07EEC8E0BFA7E1CF364D76
+:10B76000A17566E3FA6E7A6C3EAD6F250B12DDD5DE
+:10B77000FD82C727BE15BFC760C4E769C11F5F6DE3
+:10B78000B3E18F64B0AF30111DF3083F50459EEF19
+:10B79000AD4C7B8F0558DC54FE56C407DE1FD0032A
+:10B7A000CCCE3471D9A6EDF7F6207E8E0DF367E28C
+:10B7B000BE1AC02124E0A5E0FDBAEA81CA4C8E1F62
+:10B7C000E635CBB832D8DF15F81EEBF758FC09C5C3
+:10B7D000BA7662BF9E8F2FE31330EF44DCF7FB2A6B
+:10B7E00023F6B9ADD1C31521DF580FD3D2573C7E14
+:10B7F000DF7E1FD1D5371F71BE690C5757D1F71E99
+:10B800004B048F163786F7D628240F6CBAFB9F0699
+:10B81000E862BB45F0B3FE3BCCD3AC68E1BB87E745
+:10B82000D5AE7CC8A6BB0F214A37D6E8FB82287F5D
+:10B830004A3FEA66C1FFC6F51AE5C11F0CF2803D1A
+:10B84000E619D2BD320D96F0938F22FF02BFA29F60
+:10B85000D9F0AC85FCFCE33BDFF8F83AA0F3E31D3C
+:10B86000926FF572D5C8B7752F4C62B1F8F6B8C3B0
+:10B87000C762F22DBC8FC9B78EE83E8D97FD7072FE
+:10B88000F5E63872356FB8F11C4B512AE6BA1F7BCA
+:10B89000BA7E38C5050C7095FEAC515EBE9CEF8D2E
+:10B8A000292F195E41A581A3849FA4C755CFACA6BB
+:10B8B0007106E856D2A5A4DB01BA1C945FA983A344
+:10B8C000F1FB17288F2645F16E590F7E0ADAB1AFCA
+:10B8D000A9F43B287D30978D00F7BE9D05B40F7A03
+:10B8E0008FB0F3FB9CFD2918D7BB47F815FD184F07
+:10B8F0004C8DBEEF4F10790381FE94348D5DF47949
+:10B90000B79A82765C6F38F6EFC9CA7B2A7BE3FC74
+:10B91000DEAC3CBF54A93AF2D7629CB69DEF4FAE65
+:10B9200068599882F18CBEEE42FA3DA19BDE057FFC
+:10B9300017E6DB27E39A21BF39BB2C7ABFE9111642
+:10B94000A2FDCAE5DDF5B45F688C83AC74D4A4E2D3
+:10B950007EA0310E7233E641611EF263FAF7AB301E
+:10B960003E827832D05310E9297B303DAD1C2EF653
+:10B970005F4B58896EFF55C8B54AB5E8A7689FF474
+:10B9800081DF8EF120A616FD1AF5E9B7E8C723037B
+:10B99000843C44A7F5C12332CF8AE85AD29DD17F97
+:10B9A000373E4FBCF469199E076A78F9DF8A7F0E2B
+:10B9B000CF132F7F32FA552CFFEA5FF3FF8D0DAEC8
+:10B9C0005FB1E78FE4AFF4EDB1D17CFAF6BC9D7FB7
+:10B9D000179677DB7C38DFBEF536FE7BD07B92E9AD
+:10B9E000DEE9BE613CCED6FADA77C5BDA4A7361033
+:10B9F000DEFE6E38BF2FF654F77F7D86F7AB9EEAEA
+:10BA0000B67931EED0B42789FCF0A6DD09744F7CFD
+:10BA1000DF6BDF9569E345FFDDF5348AF3167DC9F9
+:10BA2000AC16F35BFAD2B8BFD6F4EAD4275A0AD0E0
+:10BA30002EDD4BF71657BCFEA762943F7D2F70BBDF
+:10BA400002FCF3C77113F117C3BB7F6A998AE78DB4
+:10BA500018F9D553BD7FBA36E48805170E873E80A6
+:10BA600003AE0BE042F775C78347D7707E0FFFFF29
+:10BA70003E787C4DFE4243F764E2A3285C14FEFB53
+:10BA800023DDC961BB42EBE7EFF77C578C76D2F13F
+:10BA90008E16D2FBE75BF787FF6BE9E0FBAE5B89B5
+:10BAA0000C65DDA7FED7AE9BD3FFDAE15C3F19F949
+:10BAB00060309DFFEAAFA9FC5CB28FE66BE0FFFF50
+:10BAC00007ABA359F3008000000000001F8B0800A3
+:10BAD00000000000000BCD3C0B7814D5B9FFECCC76
+:10BAE0003E926CC22604084260F2244A1E0B791072
+:10BAF0001EA99B842008E206A4A2222EF8E015923B
+:10BB000008B6C66ACD622202F5B6516CAF6DD16F30
+:10BB10004141DADA6B8A41B1025D10115AAAAB8257
+:10BB2000A246BA52AB50031B41052ABDDEFFFFCF30
+:10BB30004CB233243CFCAEDFD7E423C733E7CC3927
+:10BB4000FFFB75CE18498599ADB9004DDB4EE587F1
+:10BB5000B1056806280648526D00FD004E6CFDFADE
+:10BB600090944CAD5D853480BAED710045D8FE31BE
+:10BB70002600124064DBA9129F13E01BFAB912A041
+:10BB8000A3119718D6DD37B71D9B3F2CB917A7D443
+:10BB9000BCF041FEAFB1ED78E1BDEC97A9FFE2BB8F
+:10BBA000433EC0B6D606BE565C2F120F3337213C3B
+:10BBB0009144F000EE5FF7F2E8A796E1FE8BDB3EE2
+:10BBC0009F4DFBD76C1D0532F62BFFF4EFFC30CDFB
+:10BBD000DF2479C4F3F88003E1AADC7E463CDF7EF3
+:10BBE0002A1FB0FD6C93149413B0FF807D7E80D625
+:10BBF000ED05EF118477F17F22DE3B6CB7E278C36D
+:10BC00005095E1EBC67B870DF208DFBDB3697E641A
+:10BC10007BBCCB9E46F0FD7B0844E17F21BCBDFF91
+:10BC2000B1FC3E3FDE007E86DB2A7B1DE908DFC3D8
+:10BC3000100CA9D83E0830B1D5792E3C3FA6C16280
+:10BC40007A0F42D01F4006F123272F9C0209D4AE61
+:10BC5000FA5CCEA7F7A74D4C4338FCAAC5BD5EA53C
+:10BC60001916A6C38AC1EEC02A840B14EFFCB5D8FE
+:10BC7000B70EAD71AFE215EE042801F881435BAF5A
+:10BC8000FF948912AED7B40CE1C2759AFA595C4D93
+:10BC9000B88EA25A82F67C6E3FA2F6A1FE57EFA1A3
+:10BCA0007D15A70D82DABBDFE03F27603F47EBE35E
+:10BCB0007EB199517DFC17033B5D0AEE1FE35620D0
+:10BCC0008028D921EA7D9C7F93EA62BAC442C0EF02
+:10BCD000725E3A9D7E4F83FD7AA793993E3ADDCE00
+:10BCE000A1138083DE57E8BF08FFE45521D2430546
+:10BCF000147F58E0237D23113DDD290E5CCFDAE768
+:10BD00000EF72A899FAB4A89F69E85FE2C31D01703
+:10BD1000E9E789C9EFA673D47A8CBF99CE974A5FB9
+:10BD20009D2F31308DF91C33D8E90E20FC0FAA82EB
+:10BD3000EE0F22DD25A99BBE3ADDCC7CF093EC14FE
+:10BD400077D3BFBB1DE7FA64383312BE41E2FA2B4A
+:10BD500020A71ED7A992C785FDB8FE89D238B79D06
+:10BD6000F44582A03412DBF2FE15807874A4DA1454
+:10BD70006ACB3A11A72878AF3CED00250ABF72487C
+:10BD800034F43B52B3F9FD4AC740C37B1D034B1D3E
+:10BD9000F4BCCA956698FF464C423E14D07B1326ED
+:10BDA000D2F85529971BDE9B7AB863CD1C6CAF95F2
+:10BDB000C245241C1D7B675510BD26A9230CF3B674
+:10BDC000A059217DEEAC9203EB901ED552B07F3E80
+:10BDD000D26D72CE68237C128C273C6B2C285A388B
+:10BDE000EF1A77B961FCDAD2498675AB3DD5867E0C
+:10BDF0004DC357A0F40518DB70169442B4E3C15646
+:10BE0000C3FB857BB618E627EC03391EDB11FBD597
+:10BE1000266A0BDB434924BEB6BE0EBFA50F8A704F
+:10BE2000D85B89E840C991FA57A86D70203DF0F9B8
+:10BE3000A918D122BF58CEFD8762024D08EF294BC9
+:10BE4000C04774B85B0EE4501B3BE88E7C48073853
+:10BE50009AF2B0DC87E0075FA78A7230FA8B401352
+:10BE6000F5AF3CDB2AFBC80E6F94FDB602E2FB94F3
+:10BE7000B8BF92DD6D9580F85EE3B47802E4B792C6
+:10BE80005AF39746C9D7673F845BBCB9E7EAEB8BA7
+:10BE900059E596345CBF39C5D3B283EC66C587B328
+:10BEA000E5F473E7814BE90CEB7449A7F7BC4583D4
+:10BEB000511EE5F8F10EB2EBB19532E30557590387
+:10BEC000EB719DE516778CA6FCEC5F5D13AC6B49BE
+:10BED000AFD7A409FB10FB175025843FB6AF4FCE58
+:10BEE000A3F77E26C17AE8DEEFD652603CB2D22CB0
+:10BEF000420F1457BF9BF3E8FD787EBFA454D011C6
+:10BF0000A6580259B864C241F76E2BF657E7EC7792
+:10BF10009119689B72D82F235DDA0E86CA24D4A5A6
+:10BF2000010F979FCC14F3210BFB6D39E3E3F2D89B
+:10BF30008FE558C8CE2C41B347766647D93339E4EC
+:10BF400027965C7EC500E8C1BEE96DC26909D4C20E
+:10BF5000EEFE9A3495E14A50C2407A9D705AE171E2
+:10BF600068C8B690FDD1D74F98A5BEBB94E0D86302
+:10BF7000852CDA5EF12C223C565DD1AEAE623C04DB
+:10BF8000DE00E1142FA2FA4FF4932A315609A7DC00
+:10BF90001C7F2E1CFFDC589CA8221E7DCBDD896EE9
+:10BFA0006A7F8F441FC374F7131D7E4A7F2EA3DE62
+:10BFB000DAD0781CDF4836518C0701E57A954D1BA5
+:10BFC000279382FDBE9236EE5FEB1D4F7C958DF37D
+:10BFD0000BD2BBE67B1C29DDEB7BD7AE0D35F748DA
+:10BFE0004F3BFBE55513AC01BB7431748DBB005D59
+:10BFF00013045DCFA2F5C77DEE72887D3E96D421F5
+:10C00000246FAB2D68053200F6BB7CD7935CC7CAA2
+:10C01000C13C7A3E37C133A00CE5AFCDE619720FB3
+:10C02000D9956D31EE75F85EF59D9F3DDE407A3D08
+:10C03000F59F39CD24378A276E24EE53E7FA8AED2F
+:10C0400041959CDB87E29D2E3A923CE39E3FB5747E
+:10C05000F7C93E2474D3D59389E3ABA2E8EC709082
+:10C06000FD12FD47D3DABC4CA7DB1C4CA7A59A4EAA
+:10C070003527428B05F5E1A46BC3F7491E4E6EB41C
+:10C0800002C54D6D3448FE32C7C17A05C9E1946AD4
+:10C09000D483BC372D5E8ACBDA513E3C241FF5D9C0
+:10C0A00086F54E8E7B37290FDF3B99AC24117D1628
+:10C0B000866D4CB79B1508DAD15EB625DF5659CE92
+:10C0C000FAA1F278ABB6CE6B599EFBD2D8EF8C7743
+:10C0D0007D8278499E31F237C37BE71779D04F7460
+:10C0E000FB8874AE2334937A9783E6724780E2CC60
+:10C0F000BAD265B9E41F9624660F00C4A36EBCC40F
+:10C10000FEB6AEE10BA6BBBEBE725A06B56F777F18
+:10C110007C86CAF640513C2C0FCA691B8FD7349CD1
+:10C12000643B8EE0A491DE742C13F6AEC50AB754BE
+:10C13000635BF3BFF22DD538BF06430CF617B0D3BF
+:10C14000B624CA1E42EBE75D76BF0079B77ACA5BB8
+:10C15000B16467AB25D70C401C8EA6BBAA95D1D87D
+:10C160008F71CD90B0DFB6EE8C97FBA9AE1916ECAF
+:10C17000EF4ABB498C0F74FDDCE206F87CDD5DA262
+:10C180009FE63A40FD0FD31EA95606623F5EC8C126
+:10C190006FD26AABFDB9245F4EA6CB891571AC1F77
+:10C1A000BDD1795EC3CB06BA9C332E4BB778C96E2E
+:10C1B000CC1476F1D8CA416B391ECA0C65D39E5B8C
+:10C1C000D344FCDA1F79538AFF5E45BD77201D9268
+:10C1D00033C063C1F9C92FA23FA2F91F878610FDA2
+:10C1E000E6BD181394901F8B9F78C546FE68AEACD1
+:10C1F00066935EBD3FCCB793E4E3787C88FBF31A8B
+:10C20000B6335C29592E61A75D9DB95E94CFF9D0F4
+:10C2100062A3F1F9A01C26BF614161A6B866A173B3
+:10C22000978DE2B2854F5B0F87A3FCEA22081F229D
+:10C230003DAD79D67A381CE57F81DE8F92AFC3168B
+:10C240000187A2D163AE1C9A6D13701D20B816270A
+:10C25000617C2F93BB08F5F7715C5493C379494A0D
+:10C260002C90DC2DBFECFD7C5F0F7EB0B511FD3E48
+:10C27000AADCA6C62DDCAEC135C9EE0C50C23637DD
+:10C28000AE53ABD9E592D0611B44BD7F42A36B9FF7
+:10C290002D128FEBF6A27B3C5ED025D733C2827085
+:10C2A0002C9EB66F1CF145E7E79571D01A93C47CBC
+:10C2B000716B7C71135F74FA233D0B157C6FD7593A
+:10C2C0007C2FAD27B9D0E92FE06D8B15F6A27373E3
+:10C2D0000CC74D66F8E3D205BC3A1E43D3CF0FFF1F
+:10C2E000D0F4EF06FEA1E9428FCD78E87AAC3FD7D3
+:10C2F000F5D88CB70EF7A5CB59C8763172A6DB9965
+:10C300005AF0E5D0FABA5DD1E9ACC3A9D3AB8DF24E
+:10C31000A11EE0541A5E32E0A3842A28898071E9C4
+:10C32000E9C28EB54E02E283D2B095E75D2A3EBAED
+:10C33000BDED0D2FDDCE9AF1D3EDAD8EA76E7775E5
+:10C340007CCBD090B03DC4349EF2AC2B4FFB0C7133
+:10C3500070392C30C4C9958E3B0DFD2AD73D86F926
+:10C3600057A52C338C4F52571AC627E73C62E85F1B
+:10C37000E3FEA5298E5F6B8AE37F63181F170E719A
+:10C38000DCFD7AE344509047DF3BD2C9F177B0D16E
+:10C39000C5FD9D8D29DCEE6A5459BF7737E670BB29
+:10C3A000A7D1CDCFFFDC58CAEDBE460FB7A1462FAF
+:10C3B000B766BB30F5F9EB15CA574A432D9564CAE9
+:10C3C0007764F87E928EF47BC312688A473A8D6A4E
+:10C3D00017F139CC37FBE35387EE25BFEEB2B9C96D
+:10C3E0001F36EF182DA93DC47309E8EF3C51F292B6
+:10C3F00030250C1E8A7BD03DF7245F2DE916964729
+:10C4000032FB807A37D301D664D4B79933257713BA
+:10C41000F0733F24711BF4E1F85405FCE4FFAB9D7D
+:10C420004AD09EC0A0791D08E70C0126D8699CFC63
+:10C4300077725F85E2D6EBE821C22B7B64F81E3E63
+:10C440009F51FA97339437DFE86CB5929CDCB0E7E4
+:10C450008163F7E23834FB8B493FBAE206FFFB9673
+:10C460004B891B5A28AE443A462477C843F14EA262
+:10C47000E28ECE07F4F6B674910F4C6DF2CB0948FC
+:10C48000CFCE3781E3385D1F11BF1504BFAE17D57E
+:10C490002E25382C81FCFD239534BF66BFCA74D18C
+:10C4A000F542D7033D0FD4F5A04A7EB689E69F3802
+:10C4B000089C4F8FEAF01D799EF034C59DA59D2DF7
+:10C4C0009594975D286F1C73BAF5159AB7BDD1C7BF
+:10C4D00072B4B57126B7C1C6F99A7CD6737F57631B
+:10C4E00003F77737FAB9DDD3B84293CF161EDFD7FB
+:10C4F000F838F75F6F0C6872BA919F8FCF10FEF714
+:10C500008B50E50092BF17D3451D071CE59C478063
+:10C5100022DA8B95939A9497453C65920FB35CE829
+:10C52000F200683724A4D78DE867C93FDC04FEBC5D
+:10C5300039D8CE9CD7621D2B7D7BB958E86CE6F8C4
+:10C54000C36C0F174090EDDDB9F65DC4FF17B2EF75
+:10C5500032E6ABE4AF74FBB718C2BC9E5DBED34DF0
+:10C56000F594EFCEAFB834BF0273687E57DE1DDBA3
+:10C570003E5BB65C38EF2E1A2CF8AAE7DD183F02B6
+:10C58000F9E54840E6B87A7E5A4B02E7DDA59D09F9
+:10C5900014072CD826333F30CF540622DFE6697CBF
+:10C5A000EB80E03BC49779E3E6715D6EFE1A233EB3
+:10C5B0000B9DD7F509AA3DC6693DE2590B0F7F4E89
+:10C5C000F5B95A8D5EFC1CE16968BF61D2AEA879ED
+:10C5D0003119F1C99FC49142C128A207C2EF0E923E
+:10C5E0009EED9759CF7A938BE3989F909C9F6A9C7E
+:10C5F000396917CAFDF1B38D9C7F25653CF2887FB0
+:10C60000DC77C7AFB559DEA1199C0F856DA43F3A01
+:10C61000FF96938D44B8975738029468478A5D0A0D
+:10C62000ED1F913C723CF1E323702F43FA956F7D2F
+:10C63000ED20E947B9C3C9E708884447343F47EFCD
+:10C64000F7353971DEA87D1E99C2F7E25DE1269AC1
+:10C65000A6FB1BDDFF8CEDE8947D5C17C8643D02F2
+:10C66000CC25BEC9B8783D32E79B4D946FA2413AC4
+:10C67000E99CC0F09E0C829B9E77D7B544BD69ECC7
+:10C68000598F9C80F02DD7F2C3D11F7B198E6A87FA
+:10C69000CA7268D7F2497B8A053C517474D97C1BF5
+:10C6A000A9FE097F8CE13AAF19BEC919C28EAB4908
+:10C6B000DEC94C5FA79A4D794395DCB1E1D7240FD1
+:10C6C0006D716E3BBE67B6B7BA7DEB2D6EAF739DD5
+:10C6D000EC318ED4DB3A8B38371859A91652FE4705
+:10C6E000F125E5857A9E689EEFCBAA989DD18FEBC8
+:10C6F000AB210FC1E5B29C574EEB1A3E3F6F9EA691
+:10C70000EF5FB7ADD83537AA0EB226433F5F505C16
+:10C710009F38BAF976B1FC2DEB9C69F03FFFE9F147
+:10C72000DA540C7324D4A13C2920E20810F1C42C63
+:10C7300008713B1B3AB9F5A124513B17DCDCDE063E
+:10C740005E6EBFCEF4AD26B989583BFB931E1F7BAE
+:10C75000E1EB5C928B63DF1BEB4A53BBFDABEE6FEF
+:10C760002FD5AFC6D2F9520FF2B041935BDD6EF711
+:10C77000CA1F93DD8E8C40FB807046368B73B148A8
+:10C780007C6C80CE0174FB007E63BCA8DB8BC2593D
+:10C79000EE37B85EB84FE6BAA5D97E5429228F0786
+:10C7A000C59D43F5517DFF260BCC2739DB88ED1F56
+:10C7B000108F3EB3C28A1A85CF760D8FF21BC60347
+:10C7C000E52F535D223FAC724032E57370F664EEA4
+:10C7D0000C340453291E45791E95E4F913D1DBFF6F
+:10C7E000D0B8443E7F20FB3314F9F79138B7810568
+:10C7F00052200BE9B1A54DF4F36E4F64FC6E82201C
+:10C80000F3F166085B09FF5B00D8EECE0195DB5BB8
+:10C81000C1C3FCC495E3F2D10EDDDEA68C5C857845
+:10C82000162475A6937EE68D7E2F4942B8F229FE26
+:10C8300075726D6605C5293A1E964C81C765999E2D
+:10C84000B709BE82A4D0AAD514176EB600C5859FBD
+:10C850008EBEE70E88F2AB2559150769DE73923854
+:10C860002FF46FB38BBA1A74F6F746C5E35F6756B9
+:10C870001E22BDFF07C1C6F9EF2A3E47AA7609DA94
+:10C88000C3F87E4C037C6F8837AF27FDF4B37D2C53
+:10C89000205A8A3AA11F4A795FEE7FF5D417D5CD89
+:10C8A000021F3FC5632559BE08ED5760435348F04A
+:10C8B0003F610FACE3B8A97E08D52FE63D69B7907C
+:10C8C0001F7F0FED309D9B7ED0E8E0F643CC6FA834
+:10C8D000FD1BE637D47E84F90DB57FC7FC86DADB15
+:10C8E0004F8F402102F861A6E77F33CE8347EF7672
+:10C8F00046E0119160664FE77DA73244FE91DFF676
+:10C90000F1037124075B6437C969DE6685EB10C7E4
+:10C91000B78E0AC869D174F5C565221CF95BDE7E45
+:10C92000746C11BDA7B8249C7F7CCBC9FE9C379941
+:10C93000E0EBA2C7369BA08706EF7389A155F4FEF2
+:10C94000739BD30942B42320E490F8D9431D0D60B2
+:10C9500019F3F1F50C113F5D6BEF2C8A3EDF040AF1
+:10C9600019A85EA9F9992AF96C423857ABDB8E26D3
+:10C97000B9CE7C83F6F3EF117A887C35D4252A353D
+:10C9800039D4DBBC6D362FE9D373DBDE993619E978
+:10C990003075CCA46259ED9E5F98D98FF7CD1B7D81
+:10C9A000E657AB93793E9F5BDC006BAB5C38EF26C0
+:10C9B000C78E57890437BB3EAA4AC4FE2D29D26EC2
+:10C9C0006AE7A8691392C80E4080F7B935A77C378B
+:10C9D00089D81477B58DFC7239295594DDAD74C4AE
+:10C9E000D1496A57BFCAD5D7D0BF2A659061FE2406
+:10C9F00035C3303E3967B8615CDF778ABBD0308F92
+:10CA0000F495E266C483F90EEB653E97C9DBFCC57D
+:10CA1000FB8B18FF1B8A08FF08D2CF8681C591D2F5
+:10CA200095BF584D6663F3CE043EA735C5A735DBE9
+:10CA30009EDAED517B8F4FBF84AD3DC675B5BDC449
+:10CA400075171B9FA2FD7894EC47C10BD7F1B9FB7A
+:10CA500073A3CF5CA6225EBE4C8C5BC9EE99E2D676
+:10CA60008816B79AE5A74B4E2555C8CD5E19280EF6
+:10CA7000D2E357B3FC003CA0F97FD15EAA9E4F7D64
+:10CA80004BF8AB7F90BEF78D966BAD35D5230A6C16
+:10CA9000E857A84EF85719D6D183B308874EFF8CB4
+:10CAA0006EB987DBD6BE3AB0889FFBE371CB5AAD37
+:10CAB0003EF1AB4CED9CBF66C7AB0393BBC7E1AE89
+:10CAC0008F0CF3E13E69B7A1DF9C66EC3F5CBE3B97
+:10CAD000FAFDDEECD0BC3577DA7C54977E4CD42955
+:10CAE000CDE33A3C553B633C642F95AD76CE876AE7
+:10CAF0005D1EAE9F28BDD44F74BB70830CF53DD92D
+:10CB0000B7F5DABA5376C680FC2DD67D0F6585E081
+:10CB1000F1BF28FCCC7B7D3CE08DDAA73553C47D8A
+:10CB2000C7125B7EFC15CE3BF612B889F4C712859E
+:10CB3000BDCD6FFBD462213F112BE425DF15B62458
+:10CB4000D17D97F9717E3A4FAE5B10EFA773A38248
+:10CB5000F4CE771CC8FA2D4FFB1E75A0DCBD6FB15B
+:10CB600018FC4E846C1DF67764FAA691DF99BC33ED
+:10CB70002668F916F8ECC804E1D72A84BECF26B996
+:10CB8000D1CFC5D0D4D43D08867332C29FFA679EF8
+:10CB9000BEF5ADC728EEDD2BF41F879DE67CF4A61D
+:10CBA000A87C14D608FD75E02FC5390B77B5D828B9
+:10CBB0004FFAAEF4BE3DD3D9ADDFC3CED5675DDF4E
+:10CBC000EB0E087D3FB1F5CBB7C8AE9F407F17ADE8
+:10CBD000EF5D7E51D3F3BAC765D647FDF9F1ADF2EB
+:10CBE000C4400FF47D4D930370651BCECD96949D8C
+:10CBF0009A467E6DC93685CF037BF3D7752B8CE7BC
+:10CC000064CF6DB7CF17E7C8028F88EE4FB77D9915
+:10CC1000549E2BDA657C5EDBA2D91D11C7A01FB51F
+:10CC200026931FAD96B8FE7660DB00BE9F714082F2
+:10CC3000A03A9297B8CE817C9B2E96A3E74E8AC7E6
+:10CC4000202547A17DA669FC9CAED585666C9B918D
+:10CC500045FC7AA76DEE010FA19795C1F2733DF8DF
+:10CC6000391E3C90E84DA57B0A539B847C1F48EC01
+:10CC7000ECA03AD281B23889CEA370FDE6E878EF15
+:10CC800080D59B5ACF78E9E79357C8DFC45D421E31
+:10CC9000ACD943E4A75F12F91CCBBF32F06196AB6D
+:10CCA0000510D8EDC17D6BDD418E4B1781C8EBCDF2
+:10CCB000F17CEDB8CF6CE417CCF967F9961D07E964
+:10CCC000DCE39C3A84495E2F547730E7BDBDD50F35
+:10CCD0004625790BB3A2EA7EE6F8BC2B0ED5E3A875
+:10CCE000F5717C2EF44AD97F1F5F84FDBBD6C7B98E
+:10CCF00028CF3EFAA4DD4F76F9E83A7B40C2F1A393
+:10CD0000499DED94771CDD94E7C615609E45FDDDD9
+:10CD1000B3E4D77F6B65B90030DE6B58527637DFEE
+:10CD2000FF5BB23E5EA27B389022C6F59C4F7E260A
+:10CD30009EE38205CF0FE4734EDDBF907ED0B9F441
+:10CD40009127623C14E41FDD33BD0FD5FB3A2C7FE5
+:10CD5000E0F37C90EF3B44E7F58B36C48FA4F801F9
+:10CD60007281F9367FDDE57CBEF973C53783F0AF9C
+:10CD70007CE69A0174AF6CC1DBFD80F0896C7D9E0E
+:10CD8000CFFFBAE3F49EE3BB135B33FA406E379DEB
+:10CD9000F43AE08AA7977989EFC5922ACE69A0DE96
+:10CDA0003388E4624B35D0BA2365716FB473651C68
+:10CDB000C7A566B9ABC91271608D5E6FE80B8E14A2
+:10CDC000D21F1F301D222B87AFA3F3B0E6AC24CDBA
+:10CDD0004F77664F8BBA975825B7D7BE4CF2B9C676
+:10CDE000CE75908E989ECFC11AB21279FE3C87F113
+:10CDF000DCBCB6E18CB19F8BF91DBE3FB2492DBCA6
+:10CE000013DBA51AFD57A77AEFCDC2F717B63EF28E
+:10CE1000C23EA6CB9A1FBE4FFBEE718AFACB3E41B3
+:10CE20003F73FC3FCF21EA1C006B797FFDF9A74FD0
+:10CE3000BCCBE7AB9F6E1E9E2DCE8D439FFC3A8DE3
+:10CE4000CF8B0FDD8BEDA63D6F315FCCF09E73EE87
+:10CE500027498C6F0DE1D197CE77BD8F109CC80804
+:10CE6000CEDBE6AECA63FAE9E76F91A33DE7273A66
+:10CE70009CFAFA3A7CFAFAFABC27B3441E335BCB2D
+:10CE80000F8ED942C7F91CFD85E112D5F7BA9E274E
+:10CE900085F213A3E4E5BBAAA7DFA8D5430E5A96F3
+:10CEA000FDC046F7E45A575B7DD176EF12EBE85DA3
+:10CEB00071A00754577FE14AD86F21724A7F3AEF39
+:10CEC000D3FAA40CD81FA78127113C746F506B6153
+:10CED000A12F85EBE4B49E4CD71003DC6F2A77AB0F
+:10CEE000D45E29791571EF2BC0F23F01EA07131EBA
+:10CEF000164798CFC5F47B2E3312975F9386FB3588
+:10CF0000F783E514C7345B855EF8E7C471FEA6D3EA
+:10CF100049F733E0CA35F8976617A80AAE3353814C
+:10CF200015D624316F28D2F9C09EB9AF529CF0AE0D
+:10CF300052DF8FF67DCFF9589E64A1F82E104F393D
+:10CF4000E2FB6FFDB6F8AF38F703F09439517EAECF
+:10CF50007BCDC176DF5C8FB81D7CDC9F0761EB1752
+:10CF6000F8DEDF46FF6BFD4EE8C6EB6F63BEDA4CC2
+:10CF7000F9C14D890F14D3FBFA3D4CF37DBFA32EAD
+:10CF800027DF0B34DFFBBB167C9F91DD3A65F1D5C3
+:10CF90008AFA47FD28F2BF91441B48383FD24FA37D
+:10CFA000C731607A44ACDAFB9FABDC2FAA1CC9F511
+:10CFB0004838A5B23D1E6BF23745C32D220FFB4604
+:10CFC000CC2FEB540CFEA6A840ABDB7CAD725C7A98
+:10CFD000E569E5BCFEE8A16C61CF8AFA5AEA7B8A72
+:10CFE0000FD56CA13F4D1094053E224E18DB2557FE
+:10CFF0001E99F857ABF56BC99FA13C45121C7EBA30
+:10D00000E83876AB90AFB14A7007B5685DA181E2B0
+:10D010008A2DE8EF7438E88C306538CBC1185D3E56
+:10D0200071AD59386FB954CF798B83E2196C574978
+:10D030002186E37BD0C9AD47F3E315E0E6763C7883
+:10D04000B945F9E47622B4707B35B4723B0542C22F
+:10D05000EF5F116C627F06F7B9F8DC62D23C0BC55A
+:10D060001B45D7F79C2F546874EA9D0EA87025972E
+:10D070004E8709807A97D1033D06E7B0FD30D3C3D0
+:10D08000AC9F651096593FC93064509D40653DADD9
+:10D09000040FF7AB2E920EA5619FC2751A333D2A7D
+:10D0A0007B968BC91A3DFE950D2C1F3A9FEECF56ED
+:10D0B000F9B9CE2FD4AB14927F331FF5E745711524
+:10D0C00027E96AFA1DD9C3A7D3BDAAA2C28AA5645B
+:10D0D00092EFDE30663ADDAB2A1A5BF13C1D79DE59
+:10D0E000933D4EF40B2A0AAD6ECC5AA4B2E9E3711B
+:10D0F000BE4FBB970C33457C7D9716B7F896FDC0A5
+:10D10000ED423DF1A53ADD849F03837BAA7FCA19D6
+:10D11000E27C70C8C4E04E2BCE3BA4F8E664537C9E
+:10D12000E00826A848F7BB9655F1BDB5876C62BEEE
+:10D13000DD2EEAB03A5EF8DC1F83FD4D9B862F950D
+:10D14000D27BDF1FD7ADA5757DCBB2FCA4AFBECD22
+:10D15000925B70B262C04CD4CF8E9015A81EAAEF1D
+:10D16000939DEA5B9ACDE7BAD95C271BA4C5331D12
+:10D170009B860F27BEDC9FADDDC34A4E2B24BA2D04
+:10D180004BF5DE4FF323F142BEEED7F8D05BBB2167
+:10D19000DB735F76F1B9CF23FF4000F0FD9F65FBA5
+:10D1A0001EA0F5EAE2CEB27F3F3EE2EDE5E1B46ECD
+:10D1B00039959049B310EF260F046CEC07B4FBEAE5
+:10D1C000DA7955E4765C07E950E4F53591491B3589
+:10D1D000ABB384EC27AEFB5FBCAE2D3C6404BEF762
+:10D1E000D8F44336216783859C697668DBF6BDF702
+:10D1F0000E125D2F44E955DDF6335F7D80F4AB3BC5
+:10D20000E174D3F46E7DFAE552CE27C169B01BBA42
+:10D210009E8DD962E7B87AECD6CB6FA779656FB7E8
+:10D2200067105E57B687F91C2CB2EDDD41020E3D4A
+:10D23000DF38257D1BBF4BE7B49CC76D16E7B44BA9
+:10D24000A4FA57E2A9FF7BC9ED47F83FD5FC869EBB
+:10D2500017CFD7F05ABC77FD72AA8BCC5F73EB1453
+:10D26000BEC7131079838ABFA4FF5FC23E3E1F5F13
+:10D27000B4D19C4F74DA88FF8B5B4DF781281FA6D1
+:10D280007B0FD1F6BD877C787BB6764E9B0AA98C46
+:10D29000873CAB8FAF077B67CE771F07CFAB2C9F49
+:10D2A000E09569FF62A5E77AC273DDDFD3B03ECCBB
+:10D2B000D3F6263A3939DFB589FBC24F2C75BBA8A6
+:10D2C000AFE9E75A9495528AA33B7FC9F2AFBFA753
+:10D2D000EBEB8215E25E36ACE9CB3257B0C1EE2102
+:10D2E000BE166C18C0F905E6411CF7ADDD605F4164
+:10D2F000FDA60763FD7201D5933B2FA3BA4A538C59
+:10D30000F8CE89DC23DD132D4817758E33BA5DD72F
+:10D31000FCBA7EDFB62BFF89CFE67BCD5DE361C52E
+:10D32000906F3469F17311C1477160BD55E44F319D
+:10D3300002FE1D6F7E3F8EE2D8CD8A378EEAD2275D
+:10D34000F6A7F7811EE8A6B7C5E85EE03CE78CC506
+:10D35000EF4EC9381FBF8A1ED7EEA76BF2F9C7463A
+:10D360000FFCDDDACD0F1DAF2AF9D94A1BD5396E76
+:10D370000317D53D96EC7DAA89BEB759B212B8A263
+:10D380007082FE50BE70C4C2E7E063F616A6903C01
+:10D39000B669F68ECE85D528B92AA1A210CE2F1E49
+:10D3A0000C01FAFE28468D05352A2F8ECB4932F422
+:10D3B000E3DD9719DEEF539A6E1807BF27945BD20F
+:10D3C0001DBF267AAE30CC7F2861027F8F5316BAFC
+:10D3D00083EB4A7D278E348CDB51AEE99E037C21A2
+:10D3E000E29F52FC65BF0AF532C139360CF02B942E
+:10D3F000BB311DC6F8A834DCC27960CC7EC590D79D
+:10D40000DB2F5067BA7C98A6578361B0B00F667A5D
+:10D410001BEF432CD92B731CB7241503CFB4DEE9C3
+:10D42000ADEB9F4EF77E5E23DD07CC34D279A0CFE3
+:10D4300048E741F38D744EAD37D279688391AE6978
+:10D440007E231D33568C31CCCF6AA930F4873D7EC4
+:10D45000B561FEE5816986FEF08D371AE6E7B5CE47
+:10D46000358C176C59785EBE8F082E318C9BF95E17
+:10D47000B8E74726395498CEC5DAF7593AFFFDF890
+:10D480004BFC1F0BDE3E4189CA81FE26D2C7FF2F0F
+:10D49000FE2F18A69D23E8FCBF48BB7A95E687CDF2
+:10D4A000DF794D8D13F6E6F53D27F67BB0FF865A02
+:10D4B000684DA1B8498B0FBCFA798429EFD3F39456
+:10D4C0006B4B25D3397D8CE19CFE42F7DA8A4341D0
+:10D4D000437FC47EF17DD4C883EE57A82DFED823A8
+:10D4E000477F0F35FA0B76CBE7E49DFAFD383D6FA9
+:10D4F00082E627390F9DA5C34F4A50726E7D51CFEA
+:10D500004FCD79AB9EAF9EFBBD95884BEE967BCB06
+:10D510006345FEAAE7ADDF070F7F5776D560DFDAF8
+:10D520006168FF654B675F1AD7F359222C9D1B4733
+:10D5300088B0FCDDCC3BD33DB9FC3D2AD7BD174AB2
+:10D540006F4FA77BFE08BE2B5C22CA3FF4F3D2309C
+:10D55000DFEF68BDC3926B7921BEFBFA98CF86D00E
+:10D560007AFF334CC46F76192984FE67C02C0FD024
+:10D57000F351499EE768BEF97EB6B935DF1B6A6B89
+:10D580000C72ABB8DC7C6FC75C1F0C5B548E3BFD30
+:10D590003F92F89ECE6704DCE8EE78E5C40A2BC71C
+:10D5A0002BA0E5E3376BF4D7EB16B3347C0EE31214
+:10D5B000F3D1FFDEBCE535E6CBA2940EADDE51CF54
+:10D5C000F1F5AD839D23F91E9AA7D02DEA5C7A1D53
+:10D5D00063D0257D5F7221FC17A51C35D491E0D95D
+:10D5E000BE1775BEDD8DB758FFF04A518F3CBC3277
+:10D5F00095EBDFDDEB1FE77AD2CDF56F1AF4E296FB
+:10D6000086F70C7A30C7FF91613C9CDC69A5FA6112
+:10D61000F88581136E42FA1DDB6CE7EFA1510E3ADB
+:10D6200088AFFAFAE195C3C7F3779517C4F3338649
+:10D63000A3BD31C4FCD5F13CD47890FBE1C630B732
+:10D64000663CF53A85DEDA76420EDDCFEF9462DD98
+:10D65000541736D72FEEB6A89F901E3C9493AEC5B4
+:10D660006BF5055EE69FA857B46BDF97B66BDF9747
+:10D67000B66BDF8BB66BDF87B66BDF8146ACCE1542
+:10D6800054D76897C4BD9F5992E7C939B85FDA602B
+:10D690009F3387E2FE859DF90AEE5357109E2D2198
+:10D6A0009FF3FAF9FAD07309D38581FC3D919FEF7E
+:10D6B000871DB1F8F3E9FB9BC91BB3AEA33CF0484F
+:10D6C000ACFF384522953969D751DE77C426F4700E
+:10D6D000FAC6D8EB48EF3EC6C5083FFF4B92A82BD1
+:10D6E00039C336FA7E6A6AB26F504EB1B8F7C5DFF9
+:10D6F000CDE073924BBDCE19B18A3830A2C583E913
+:10D7000039E21C302347C4AD7A5B463CC7E7D3A956
+:10D7100065FD7C389BBF375963078A5F717FFEBE0A
+:10D7200046BF6762FEFE66E49FECFC9D845E0F2DA3
+:10D73000C949E375E8BB1CD2CBE49FC4B1DD82705C
+:10D7400068087DC7D305EF7EF15DE531AA2347D593
+:10D750009F4B72441D066E03C377408BF71E3E44F9
+:10D7600079D6FBC37C6388AE732D6A09F17571C2EB
+:10D770000EAE774DC951795F8497F145FBD34C7C50
+:10D780005AEC08737DEC42F5F0DEF03F767BE8174B
+:10D79000B95CFF55F3F93B3C6D5F84630AD15FC709
+:10D7A0005B87A37B9DF3CBBF5ED7D5FB9F3EF1503C
+:10D7B000B65697BFC5DB833FBD55A34BBBB5E73A14
+:10D7C000FAFD1A7FCFE1CF3000AADBDB63D14760DF
+:10D7D0005BAFD1E9D80D880FD7273C2388BF8BA733
+:10D7E00039F9FB737D7D5CC7F787F3ECB33AD5BBA2
+:10D7F00090F05F582FEAEEFA7844127CF5AF14757A
+:10D80000D0C5DBDF3B44FF1F8405CFE415727EAF3C
+:10D81000BD6FA633D297BF8B9A2B8B732BA4EFDDF2
+:10D82000C46773BDFDDBD235922ACE57236BCF0C74
+:10D83000A17B648BE9DE1A7D1FA6D5AFA0CD5897DA
+:10D84000427AF9A95E71EE7914F0B9965DF3237608
+:10D85000FDFDC18AE1FD634EEF4F893E2F687603DF
+:10D86000E7072CB87F9B9E279BEA286D2151EF6C20
+:10D870004BB1719C4CF10EF9273DDEB9EB4D51EFE8
+:10D88000BC2B4DC4D1041FF1573AB89BE3842EFF43
+:10D890002FB955A29FD3EA0BD0FEE05BCAFE4B1E08
+:10D8A0008AFCA5F38B3F5FADD503843F2CD6FC5F8C
+:10D8B00031AD43014E6E1FF68B45DABE183F72DD67
+:10D8C0006D34F89A04305ADD6CE56E431DE1FF00BB
+:10D8D00090CECABD504500000000000000000000CE
+:10D8E0001F8B080000000000000BFB51CFC0F003AD
+:10D8F0000917B1A1F26FA0F1B33851F9BF5951F92D
+:10D9000097D0F884B02E1303C30A46D2F420E39DC7
+:10D9100040FD0780F838109F6322DF1C103E210C69
+:10D92000F48F1803C34220DD0DA4AF00F11F207E49
+:10D9300004E44B8B30306801F1325106864420BD3F
+:10D940000688CB4520FA4E02E96651F2ECD4E3A1F9
+:10D95000CCCDA39832BC411A955FA3C2C0B05695F6
+:10D9600081E1931A84BF02499E5D9D81A15605C243
+:10D9700036956360E807AA59208DDD5C33A0FC046E
+:10D98000A0BCB83A840F00134DDDCB680300000043
+:10D9900000000000000000001F8B080000000000D5
+:10D9A000000BCD3D097855D599FF5DDEBEE42679A3
+:10D9B000819705B8090183067C09612DE24D8C1819
+:10D9C0006C8A2F88364E197DA0D56859223235B61B
+:10D9D000DABC4012C2A6416D8741A52F5A2D525A7A
+:10D9E000A3624B67D4792C1DD1B1355AAA76A49D78
+:10D9F000C8388E5A65E242AB558739FF7FCE4DEE6F
+:10DA0000BD7909A89DF98ACBE1DC7B96FFFCE7DFB5
+:10DA1000CF7FEE73CB3E80090027F1CFB900574B83
+:10DA2000009037548237D608118026CDAD6F2A0674
+:10DA3000F886123BAC57B1E763E5D8FD3A3E9F5CF0
+:10DA40000B610005DBE703C4F07FACDFFAE0BA311D
+:10DA500089207BA62CCDC2D21CDF2C9B5400AD129A
+:10DA6000DF6F999CE9BD5942CA35D0EF05FA73B210
+:10DA700004A0E5E86FA71E32EBECBF0208455E0F7D
+:10DA8000B0BFCC8259271580F7828BB3D230F278A1
+:10DA90006FB5769FA54E02F853EBCB530F4D1AFE90
+:10DAA000FE1B0A34F7960F7F3E0BD8A433101F4994
+:10DAB000777CEAD0BA07D71964489AC3FA03A43D21
+:10DAC00039ACDCB5ED2CB56C084EE73A00921CBFC2
+:10DAD0009FB39F2752932E60B50A29318FE052D908
+:10DAE0003F3301A829DB97EB763500C1E580B723EA
+:10DAF000F2978177C4FD12EDDE0BAEEB04D66FBD5D
+:10DB00008BD34B7B9E1C5B07C3E9C5DC0F138FA730
+:10DB1000BB1F37818FE631E9A8495E3AEABE9F8A8A
+:10DB20008EAE443A3AEBFF9E8E927FBD74D441E3B1
+:10DB3000FC95D1114037C717F4AB38FFD0735E4660
+:10DB400096F64A4867ACDA87708FE353C1B896CE31
+:10DB5000EBE5694C4C41ECE93398DC1AD7BFAC1EBD
+:10DB6000E11E7B74E19B58762EA9A93B9FAD2FBF88
+:10DB7000B1F7F90B581989A7A404DBAF3B4046A1C4
+:10DB8000C2C65B91AC66EB6BC7C1E6023C905C66BB
+:10DB90002471BD60008C01F83BB126005957593DF6
+:10DBA000447FCDB40E37A4393EA4939EE1FD475A7D
+:10DBB0007F08FB996D8AF1FF6B00D777AA7EB0963C
+:10DBC000CF9764FF20BE0B87E6A771F29B2C7540B0
+:10DBD000FCD8DFF7E15F08BFD7FFBFCC5700953E09
+:10DBE000940FA17A594B617BE8CD56593DB24285DD
+:10DBF0003493110555DD924B3FF5BE7402D4F5F216
+:10DC0000FD911A4243F0FD2748443FE3BFF55ACF48
+:10DC100006467227960663441F1A406ECEF0F57CC6
+:10DC2000B71509D9525F52232568BED8D3A5AC7F5A
+:10DC30007209D77B77D42FCEB6CA2B8F2409BC3973
+:10DC4000E903747526B215A70FB55E367CD3BE38CE
+:10DC50007DA89F933EF2D65AFAC167DFAF88691755
+:10DC60009C267D7CD1F9CC7D1DCE576D625F4B7DAE
+:10DC7000C0F8F6F6BAC519ED8C91F7B592F83D5299
+:10DC80000F462A43BFFCC1FD4C0E2FD9FE2883DB73
+:10DC90007B836DBF94B1331B7B46C18712B1AFD775
+:10DCA0001CD7D7A2E8AFE5B2AAAAC9389E1BC763A2
+:10DCB00074B6317A7B12183F9C40DA66F850BA2B62
+:10DCC000D258875288DD2F209059DD1735529B8816
+:10DCD0000E52B42F267C1E5DB6E15F8DF86D75681F
+:10DCE0004C4A56F87D2D6E82C38DF3317A57343607
+:10DCF0002043851A84B42F8C2D38FC4806272762D0
+:10DD0000FDDB363AE8D22B21D33E98F48A68E5F45D
+:10DD1000FAEDD3932FCEF996D8E13DED7E41557FB4
+:10DD2000DDA28746EEA7C2EBE6FE30245E8503CC7B
+:10DD300018DAA70D2ED8279DCDF475D1A590604F88
+:10DD400037E0AB3944A764CF6C28AAD490AE609773
+:10DD5000A4229CA61E85680EB5AB90741A47F636B1
+:10DD600003B653820695E6FB91E112F49734F697D9
+:10DD7000B271BF22F6F72B42AF4195EBB57E136E21
+:10DD8000D2B3EA509DADE39D9BD8FF189D242BA4F0
+:10DD9000D4FDD2F0F7F5A817995CAAC7E716B9B277
+:10DDA0007D900FA2B45FF5E2DDC1C75E9A3C9DD1C4
+:10DDB000475F4C01145BEB1EF318B56CFCE7CF9189
+:10DDC000521E49C0CBE05C24E07CD6C81D8774DAC3
+:10DDD00057EB213A5E74C19F2248C6C7F7FD5ACD62
+:10DDE000442F8BE6B986E060FFADB6AE8FFDF7C37A
+:10DDF000C17D29A2794CB856562A0447DF3C2985B3
+:10DE0000F31CFADD7FDDFA2506E7B35552CCA313E8
+:10DE1000BC2160F3F519EF4746F53BCCF975D010FE
+:10DE20009FCEF9CDFD081702E115FE9DE195CD9736
+:10DE3000AC19E85F8F783E26C5D6B3F9B2E6B74C89
+:10DE4000C0798A6599E0DD38CF2B2B8C7EE0E531F7
+:10DE500032E23328F83CCBDDED9DC8E0EC9C24C3D6
+:10DE6000BDECD1C6D2D1E559BB439EA95ADC90582E
+:10DE70007F3DA9552AA3F045CA90EB32C9BB672460
+:10DE8000AE273B928BB5525CDE21BB1D887A296E92
+:10DE9000D1ABCC5E7C4662EB7745381D67D7C6B9FF
+:10DEA0009DD83786E45740EC47D6B4C55990C10E8B
+:10DEB0001E711D6CA24C7673B6CCE183A37C7CD51D
+:10DEC0001C3F67F4F13788F13F6C92A00FE153E3F8
+:10DED0005EDC7F302A889EFD823E616D0ED54DB995
+:10DEE000EB298B7715B37DF44465D0755C5F92F6B2
+:10DEF0007933DBE322068ABF96BD674D377FAA9050
+:10DF00005D922D9F4826191C9BF75F0B3AB353FD7A
+:10DF1000D114507DEAD55EC4CF66A614F8FCBD804E
+:10DF2000F30718D9A27C0D30F9AAA37CD57BD33294
+:10DF3000ABAB751033D8AB901693FC8C640E444B8E
+:10DF4000DA54F6BC7D2910FD025A1116FCB6475F63
+:10DF5000301406576723905DD319A9A1F5B597D75B
+:10DF6000788BD1DEA957E9397CC2F061DA214C1EE9
+:10DF7000FACBC0C0F936E7432A88BC549B47F4E883
+:10DF8000D6F8FAF5EDA5909ECEDE67CFDC8FF327AD
+:10DF90006F81D8243E25C935D5A40B359194D0BFC7
+:10DFA0006BD1629B32D0DD764864C9336C744A7A97
+:10DFB000D789B72C375C88F8EDAC60F45F3C7C9C6B
+:10DFC00022E41F466FA9D8E28B4A32CC532CEB4493
+:10DFD0001F665DFFD04DF08FD47EA81DB3337371E3
+:10DFE000684342BC406D84D69703837F0CACE78ABC
+:10DFF000F58E81666A179DDDBD1FF9ACC0E8AD46A0
+:10E000005C7C3774E9F3B46F70B786F108066DE98C
+:10E01000C9DC21396104B99C782F26937C0CC9692D
+:10E02000CD6003847C7D5152D63A901F91855D1856
+:10E03000C09B5ABBA7A27F19869884EF43313569EC
+:10E04000953F59C0EA36FB0F8E94CE24D2E27C0174
+:10E05000DA7E6419ADACF90C1CEF0E06908FF9C98D
+:10E060005B4209D2177FF285A7E1647F92E3596989
+:10E07000DEBF0CEDEE1B157F6C13D2438CEB072F2C
+:10E08000FB07E55FD66CD5268FB30D7B3DD7A13757
+:10E090001628415A6FF65740E803A37ED29821F81C
+:10E0A00018640D4837DB6A55C0F982410E9709673D
+:10E0B000AEF2495A0682E318C2C1D0437084CB80C5
+:10E0C000FC3D06CF31073CC71CF01CB3C2D3E2E5D0
+:10E0D000EB75FAFDCB65E1F733BF17F5E00978DBA7
+:10E0E000A8438231C6915E096BBC6DD0DB47469573
+:10E0F000061AEDBFD3EF67FBF39E4D3FCC16759D1F
+:10E10000D9F525049FFD3D14119D505D8141FF759A
+:10E11000F96C133FFA575F617C77ED6117205F312F
+:10E12000FE55F0BD4BBCBD56F8B1CB51FF33BD7DA4
+:10E1300015C4C308DF3B2093BDFC0EBC109E6E913E
+:10E140008B77C86EA1C7D9865AF9176251F4ABD53F
+:10E1500060679F1226349874269DA47D8B01F9DD9B
+:10E16000414E6F49F0B6917DD1C5F5A3E9F77DBD6C
+:10E17000DBAEAFAFD96EAF5F0D8BC7207D5D7DA7E6
+:10E180000B526CDC6BADF607DB9F6FC91AC1770DC4
+:10E1900034776A41B2B31A711DCB3550D14F5BF958
+:10E1A000B37B662E63EBD921F4E85B4CAEEB16BD76
+:10E1B000715D24E536CA87AF6FBD145BF42569E451
+:10E1C000F56D70F52D42FB20B9D5457E1D38FDB5A6
+:10E1D000BD0AF96B967E04EF955DF6F59D6AFDCE5E
+:10E1E000F5328F85D67BDDAE65A437475A8F7B9796
+:10E1F00064A432E8B7874D7D28E48B49DF265F278A
+:10E200006B80DB7BBFF7A5D6B3F97E83F291F6BFB7
+:10E21000F96C1E47699E85E5A9FAFDDBE7ECF7EF8F
+:10E220009FB3DF6B428E3BFBADF4F6BB713F57AB48
+:10E23000C93A491EB2A3BDAE66A390A1C2B5AF3A1A
+:10E240008DA698A55DD769B63B2C959C56BB3A79AF
+:10E2500094F18E0B3BE3A93DF7B9FB91FF76BFBA72
+:10E2600008F5FB37FE49012F5BD7F13D2148237D9F
+:10E27000AA2937DA2BD731BA4A513D3DF3628B5D7B
+:10E28000C52896C6FFC64321B20FAE7BC493AA67CA
+:10E29000FDAFFBE97F4C038687E3EB06FEA510E9A3
+:10E2A00075B7C4FDBF64FFB48BD9F3EB54B8229E9D
+:10E2B000814E6485F3CBDB3F0F34A2DD27EDDA7F9F
+:10E2C000398DDBFB5517CA65B3DD47B28BE665EDCB
+:10E2D0000C7C9F7C504A4D92387C0D5387FBDD6F40
+:10E2E0003F2871F8F6B9523E846F578F3BC1DAADC3
+:10E2F000DEF52ED1ED790FFD388C7858BD4FB1F990
+:10E30000BBAB772969CF342A5FC51235A3C4F86D3A
+:10E3100095E0D7557B57921E58D5BBF95DE4D7D50C
+:10E32000FB5C36B9CEF0124B235E5F5262F5587F2C
+:10E33000F487619DA1EAADE8EEB0564EE32E73334B
+:10E34000BABA68B6BD1F8EFF61CEF0F1000628AEE6
+:10E35000B9BA77239F0FB8BE31F9F42DFC4BFE708C
+:10E36000BD3145B19F3B9C806767521C72576E461A
+:10E370003FCED41726BF7EE3C7277626D9BC6F3F92
+:10E38000F2879D4906FF8AFF797FE7B7D9BAE0494E
+:10E390009F867268F5EEDF84C182F75A85FB61C7FC
+:10E3A0001FFCE1033B18BF1CFFAD87ECBAE34FFC39
+:10E3B000D7789DADFBF8C31F8D41BB73ED13E78F7D
+:10E3C00045FA5AFBD879636114FF01E935E5B1EEEE
+:10E3D0006B8AF655DF27611006E071513AF6E7E0E7
+:10E3E0005E258DA1DB775EF6A43C0C3FABD9B396DE
+:10E3F0004ADCAF95A487B07E33C3F3AA3D1BDE553C
+:10E40000A665C277B2508E62C9D8268AFB7DF145D7
+:10E41000E75461E98AE9481F3040F2DFD96FF5110E
+:10E42000B6AF678FBC8F27E01337E27FF59E8D7CF8
+:10E430005EC73EBE837F999341FF0FDBC715DFDFC9
+:10E44000812FF7E6D2BE8FB48F2B1FBB6454FFCC55
+:10E450009407A7C26F93C4E13A5B31D628C8578F9F
+:10E46000FCE8811D11BEBFF50C21C77F7C623C0614
+:10E4700097DF700D5C8E7272E0098F762FEB73DD83
+:10E48000132F119F1D7FEC79B74E72128212D37B2E
+:10E49000C761F04F1FEAC15512AFACFE4128ED092C
+:10E4A0000FEDD3AA54439D1EA6E7AFD2F314A7FFE6
+:10E4B00055A9FD4BA40CFBB65B29E1723995477851
+:10E4C00059A9F7B9B5A07D3FA5D9B88FAF2E40BAED
+:10E4D0001B691FCDF56BB8FE5996FDFC01E7DB917A
+:10E4E000F8F3788F4795B286F6F7B8B00F56A7A421
+:10E4F000972003DF02ACE3F08E70FE68964E7AF848
+:10E5000081831ECCFEE6BA4FC5D7A75ECF67C3D7BF
+:10E510009D8A6EA31B136F6F7F9259DEA7859C584F
+:10E5200005C9BA8289C3F5950AF16461F110BC9DF1
+:10E53000BD0AC9F1B7772964A73BE5C2AA11FCF16E
+:10E540005F29DCFE58B56FFF34945F6F1FF8B9A0E8
+:10E55000434EE7ABF6BCEA4E0AF99FB2CA7F1C2FC6
+:10E56000C37EBC2CE05EFD78E6F156EF7937E378A8
+:10E570006FA9C65711FEB7FA5C906443BCD5AB6473
+:10E580008C6F1C505CB6386E6768E6CB5918DF0C90
+:10E59000FB755CF7FA75C64B49B4435E7001D981CF
+:10E5A0006AEC0D0F7BBF3EE4A773EFF5E1AB41B71B
+:10E5B000E8E976079ED4689CFC603512AFE2B1D7DB
+:10E5C00094CD1F7569B20D6E509345184FF955F1F2
+:10E5D0007FA938EE7368FF9D31D4FE39153A72D9A0
+:10E5E00078CF1952AC0D32C4A71CE3C7E729A05B52
+:10E5F000E9CC2893ADF1D5F0819B282ED102CD69CD
+:10E600008C134111F4DE6F19F7EE560DD26C7EA813
+:10E610002B93ADF1554F73B3E1617014ADD54AD072
+:10E62000341B69FE71CDB23DAE2DE65F23E209B029
+:10E630006BF7EEDD6CDC3A7C57827E0C8F573177BE
+:10E640008AEC98F3841CFC6761071F90E287D0CFA7
+:10E6500032F46D2ACA39A9749B8AF6C4C24FBAD55E
+:10E66000E5167A5C58DA5684F472F853A531135DD6
+:10E670002D51395DB5156F28C2FE877D371671277C
+:10E68000344AEB2C10EB3C34EE9A603F1B777FF161
+:10E69000355B2633B8EAA20A60BCA52EB26C4B05E6
+:10E6A0005B7FC11125E663F582A6A49A983A7C9E09
+:10E6B0009D28EF19FEEE453C32F87FD01AA5FA03EB
+:10E6C000AD3A95BB5ACBA8DCDD1AA3F77B5A67534A
+:10E6D000BDB7B58ECA475AE3F43CFC2D7F02E977FB
+:10E6E0006F6B233DFF696B82CA1A95F3DB42810F82
+:10E6F000CBBAE91C6C497B781DC6514CFC39F15DE5
+:10E70000CB282E87CE0D241DF13D56E572C589D745
+:10E71000969620D9A53B25B0E173A6CAEDC8B8806E
+:10E72000E3903771A1CACAF7EA4ACBC9EE81780CE7
+:10E73000E5F44E297E5B05E397A7C6CD8A5AE56EC0
+:10E74000249888AB7943F5F15D3C3E334BE5F2A963
+:10E750000EDA0E6531F88C4F40473A33D779A05A1C
+:10E760002F42B978A08DC1538EEF6528B3D0993967
+:10E77000DE5C011F0433CBE921BAE5FC1F9D5BB6CB
+:10E780000DE3C4CCF18C4DD2C9EAB6F5DBA69A7183
+:10E790006F9DE8D8A413C63F4F8D8BD030DC5F6CE3
+:10E7A0002AE6EF7D9CCE5BFADFA5F856740CD8E222
+:10E7B0008D1D4D32F9393B8EF2B8F489A6926D93D6
+:10E7C00059FB6A8637F4DB73169666252C74BD45B3
+:10E7D000D0D30E6F3C4B1B457F758A7666FD155F67
+:10E7E000E23B88E7BF9FF0937CA4E71DAED4652889
+:10E7F0001F5B8E7AF475129E37C493B86FF122F6C0
+:10E800009C8174A26EAD879616E4E70F2D37EBDB83
+:10E81000CEB0F0792866E7EB9D2DA3C7A54DB8775C
+:10E8200022DCA3C4654DB8CDFD3851B764E01A1899
+:10E830008E07E7B8390B978C3AFFDDC8771EC2C345
+:10E840004ED5229F8A9A353A6730FB9BEB75F67757
+:10E85000AE77285FE1F4CE677A5D908BFBF9F0C765
+:10E86000E31F7D0E70CBE30ACAB12BD4442FEECB4D
+:10E870004C68A63AA803F9C82FBFF373FADFD1F9A1
+:10E88000403EF1919A2A46BD70BAF375403C5E8DC8
+:10E890007A2B26C7ACF2DC2C7FA19A718234C58F0B
+:10E8A000E888994D29076E8E66C2F3E0F845EADBE9
+:10E8B000D6F3A42D00DC4F4F7BE99C0303221AAB57
+:10E8C000171F86CA4D6CBCDD429E54ABDC2F9C7E6C
+:10E8D00058EF5178FC48690859F028E2A9661CAB4A
+:10E8E000036E068D7575AB15FBB1B9C9870DEEC406
+:10E8F0008B882F7754A7F3775724417C0522FE3D60
+:10E900004EC4E9CF1771C6FB5B789CB105E2179E38
+:10E91000817C7D4401F28F13136DFCEB5CE77E413B
+:10E9200057FF24F4DFCF85DC2E55F74B596CFCD014
+:10E930001BE9036156FE4CC8F1C7841C3FB0ED5F74
+:10E940008A319FA023E18E214EC355FEB4C4ECD082
+:10E950005B67BEA15FCBDA77744F6E47FC6C58CB18
+:10E96000E3F28FA2DC67FD1E16723FDCDC793D9D71
+:10E97000DB09F95264E60B08795224E4C9C16D2F12
+:10E980002EDB80EB4B78699E16483F8D717D582BAE
+:10E99000939D12EEFDDE0D38CE43AD061FB77BF71B
+:10E9A000DFA17D7F8F375DF9AF18FF9FE78E25517F
+:10E9B0004EA526D9E454B877DF8DD82EDCFBCC4D9C
+:10E9C000940F23F0E0799CAD9735C9BAFD703AC435
+:10E9D000DA15F6A7D1EC66FBDAB3700A1BAFB45EAA
+:10E9E000A670F51E297E5E08E9A1819F4367552C1C
+:10E9F00069C3F6DD2B5E4862FF31CF364BB8ED3987
+:10EA00007F776F35E2EFFEA2D79EAE66E5645731A1
+:10EA1000D141F0A89EFF43C0F1E3D16BF591E9F03D
+:10EA2000E08A358072CC73A74CE7F4F7DFB906AE05
+:10EA3000B1E65DAC5033C6C726BB3CFC3CEBCEC553
+:10EA40007D2867CDF3ABC295B55EE2FF67C1763E28
+:10EA50006B9E6399FD2BA4C464571E9D57F0732DC4
+:10EA6000D1BF40411B8F556F90391FC4D33E6BBE41
+:10EA700049F07A399E099E592E95E0698FD5EEFAB4
+:10EA800017369F3AEB52D2CBD06D87C3D98FC131A5
+:10EA90008BC3C1E133E118C74C82209BFFF6852F61
+:10EAA000E6237C1FD60DEA1B3FFAFF1DDF95D3132B
+:10EAB000D8FE6C6D97E9FCFE40D5012FE2714B55F5
+:10EAC0008D9FDB3F9CEE72041FFDA04E26BE3D5184
+:10EAD000C5CFFBE19393741EE612EF73F20E78E953
+:10EAE0000C236904AB6762FA81F9C7925FC0705367
+:10EAF00099F4DBE4A7DC9263CB371807058EBC954D
+:10EB000092A1F6E87FD71D91502F85C47974A97919
+:10EB1000BEAD1C8DE1FAEF32F562AB97CA9EE603FB
+:10EB20003E9DC1F58B664627B42E7B5E8AA7096899
+:10EB30005D05CDFC9C6D8BD6B7DFCDEA45DF65A8C2
+:10EB4000D7D19EEB25F902DD3C5FC03CEF98B4C203
+:10EB50009EB752E4C8B719969FF519FDCCEB5DF648
+:10EB60007CC313B0650AD1435F896D5F7AE630B725
+:10EB7000E6ECE1FEE6E0B8C29F82289773393E3E9C
+:10EB8000C7ADDF529AD05E0A5F58996D3D1FED7494
+:10EB9000713BE9D0EF3C80F1F80DB55E8AE398E770
+:10EBA000E8E67E6FC5A42BCC77687FC087F4B223DC
+:10EBB0005242E5C1B9CFF8FA890E793E8047AC6977
+:10EBC000DDDC67163631BCDE9327938EE9287A2187
+:10EBD0001FCF176FAFF5D2797F38D0DF7B90D58309
+:10EBE0007FEF8EE1F9F6FDD5E946ABFFFA908BDBBE
+:10EBF0005BDB5D425F6DB19F3F333ED88E7CE009A9
+:10EC0000C6E9FC52F68ABC09879F63E2237C205F39
+:10EC10002E9ECACB92A943F6F9DD826E760879BFA3
+:10EC200045C87BE738C54DDA0137DAFD2BB44A25F4
+:10EC3000035F4E68B1DB09E39AED7935854D76BA0D
+:10EC40000FC50A1C76459AF498A98F37F88213915C
+:10EC5000EE2B99BEE4F681265BCFDB9DFA78B76A8E
+:10EC6000EC7391BD7B7A764238106F467C3BEDDCCD
+:10EC70004302DF1F2BC601C46F408D1F72511E68F7
+:10EC80009CE48CD36E1806273038A78E0AE72F5DD8
+:10EC90009FC17E3AD5F9C09FE4F8F6E718C8F3B3F0
+:10ECA00040E45D84480E7784B8BFD2E1E27EC27B47
+:10ECB000625DFFE15268DC01415FF303D09C399F44
+:10ECC0008CC78B3E40C304DB8DCD9CBF8B160BBD28
+:10ECD0002FCCFCFE03173F679B3F61F479FE88F35E
+:10ECE000B0F257AAF1AECB728EF384CB78DF658990
+:10ECF000537CE8D2383F98FB21F2734DFB699F6A41
+:10ED00007C64ED6F96390B553ACF3D01FE98C2F009
+:10ED1000F3643EEC0526479E94043E7FE7A33C2027
+:10ED200013DF83F635CA0FD4034703298CA798FB5A
+:10ED3000609EC30CCA11D1FE4C3797278C6E026EB1
+:10ED40009A3FCECF0B214DF2A140D0CD0EDFD2DBCA
+:10ED50006A5979EBDCB75EC67C85771EF3E908D784
+:10ED6000D6AA6361ABDC84263BFD98CF5D1F16D22B
+:10ED700039FD37A544BEDBE247BA22036EECFFA49F
+:10ED8000A4933F97FC8D42F6C893526A0A192A2A27
+:10ED9000D079C693D746539B2CE71D4E3B3FC7D730
+:10EDA0007FD76A5C7713B39760F8BE9976FAA0DDD7
+:10EDB00011B5F78FBB41D8D96CB98CAF2BC4BA63EE
+:10EDC000AAA1201C332041E52CD0A964FE40A59BBC
+:10EDD000B59F0E03F9C847EB02E3BFC4ED8CFF33C8
+:10EDE000BC197F8D781BA25BBBDE36CF1DF2041EE3
+:10EDF00042D04CE7EFBF685CBE71129BCF5D14241C
+:10EE00007B38AFB1FD7A398CD97E7D1AFA9B79E2D5
+:10EE10003C1C9670FD6C9E4FE7D4DBF5B9537F7BAD
+:10EE200084BDE11941AF3BE5E6487A7D85DBAED78D
+:10EE300007E3C723C83F67FCF8D4F24FBFADB6184D
+:10EE4000F3348C976AD1AE9BA752BC333C11AE8889
+:10EE50005BE8E1F76E223A56F2BC994D8C5F53673E
+:10EE6000703E07F413024C01E179C2383985F93656
+:10EE70001B92A93ACC3FDBA04ED2ACFB583D8EDBB7
+:10EE8000B35B6BFC4D56BBF60F7E178DFFCD40F587
+:10EE90003348C7E5C1540DB97B067304C7F0BC4BBA
+:10EEA000DCB7B334E8C773580F70BDCD38C2CBF5AB
+:10EEB0004AADF63AE56726E0646034BD60CFC7DC52
+:10EEC000ADA6D6F9111F111E7F096D97283947E9A4
+:10EED00035D298CB5515587CB79BEBAF329C67FF6A
+:10EEE0004C66EEB2F67FDCEF263BA73754A8A23D76
+:10EEF000F9A4BCFCFB68070EFCD603789ED2FBE9A4
+:10EF00009974AFA137F4A5054807BD1230CF96AD6F
+:10EF10009FF10F4FFE8100C6EDC3E7198071CB81D1
+:10EF20005F40EC5E36BF2BFA689CF276C108C8B32E
+:10EF3000593F1F7461FE4AECCFFEF7CF6574F74866
+:10EF4000B0F28EB361280E60FAFFB5FEC4A3086765
+:10EF5000C7987F6B423EEB62702A6487195184BB6D
+:10EF6000324F26FE83BC606A127B5E7D38528BF97D
+:10EF700068D56A054A1A0607DFEF577C892710FF14
+:10EF8000B55A436D366B5F7544277B6541F4FA4390
+:10EF9000589F7994D73BDC40F620F22F58F8AFFA0F
+:10EFA000C3F1B4BEC3428EB7478D3E431A653F34AA
+:10EFB000D5719FC39EC762A5036DA68D0E122E2B21
+:10EFC0001DCC667430D54A0786F459E8E07B42DEF2
+:10EFD0009E9A5F389FDCA870BE194EF7CDDE9CF27A
+:10EFE000E1FC61CEBBA92A2782E7AB261F68B36E7E
+:10EFF000D6B0EE59E68E23DF997C61F283E21BE402
+:10F000008B8B7C6C7F9704F5F333F105FA7156FA1C
+:10F01000BF78043E5904038730E77E910AC92C2645
+:10F02000427E35E78DD2F116BA77E269D13C098E7E
+:10F0300059E4D1C993BC6EC1A3369807AD9C3EBEBE
+:10F040005F50F58E8885EF3A99FD8C4661971C8359
+:10F05000BC62E4BBE541CF0CBCDFF07094E2FB9EE8
+:10F060007813E5ADCD7A3B7035A3C33F8E91755CC7
+:10F070007C87BEFC21E2DF97038076DBD699D74DF3
+:10F0800040FFE48FD72626609C7323C3FF31326E86
+:10F09000526365CA85EA1FCBCFCBF4282F1351FEEC
+:10F0A0001CC4FB94A81BA25D3FB563FB6C9387DB7C
+:10F0B000BD5C0E6EF7723B70A3BBDB8BFC3550EC76
+:10F0C000A5F354E7FACFF5707E38D70355B108CDD4
+:10F0D00046F1960EAF52D7C3E350E973D9F37327C5
+:10F0E00096DD6BD58F66BF3B5A53F1D726E17A7612
+:10F0F00051995B9F023C37F09725758CDB7BD7419C
+:10F1000022937DB8C3CBE304DE03FF40E74DB9A5EE
+:10F1100031F24F23F56C3CCBBE2E6228CC62728656
+:10F120002DCB407AEFD0FD64AF2D8AD4BCA94E1B05
+:10F130004E07F8E798653FBDFFA3247AB91F477EC5
+:10F14000C85AE1F7D59678897F3A5ADC3D184FBB0B
+:10F15000CC934DF8FA2052336A9E2DFA5749460F48
+:10F1600029E65F6189E720C933F83908D6F11C0424
+:10F170004B3C07C112CF41F03D9E8360FD27AD0699
+:10F18000D5F13C04EB781E82753C07C13A9E836042
+:10F19000B9AFB589CA7F6C6DA6F78FB7B6509DED34
+:10F1A00013D9E350968C2E6678EEBAC96DE0F976E5
+:10F1B000B7D88F8346492EEEA32FC2FD53DFB3B7D6
+:10F1C00003AEC717E571A5CEE8ED70252BBB6684AD
+:10F1D000BA30E0E57D2848A54FBD0330BEB0534AA4
+:10F1E000366124EFC60DFBCE53991E2F8D5E5F93C3
+:10F1F000C3EAB76C78723DE6F74CD6DB62CBB5A1BB
+:10F20000BA1EAABCEE614B7D42798FEA67EDD779D1
+:10F21000F6AF477E4638D0C8DBB2E1E0796DA58C09
+:10F22000984A80EE790C14BB53488F57E17E4D42CB
+:10F23000F8B9FDFF65581F457F7A82EEAE443E6205
+:10F24000EDD39C7E4FAF7D371E66CD18DE6FB47652
+:10F2500072D569B5036594F1F0BD34CA381DB05E4E
+:10F26000C33B679B91E731EFC817207FAECBC5F951
+:10F27000B7CBC7CBFF167C7BC85B13F7B232EEE58A
+:10F28000FBDAE58BD7613C7460AA4C71855E171B75
+:10F290000293775B8A7F5DC2E6FDE6332A607CFAE3
+:10F2A000871ECEFF932684B85EFDB697F4EA051359
+:10F2B0007EDC9EC3EA93EE8BC5504F6E86981FE9A5
+:10F2C00024B985F3FB8FAA26E634B0E667CD782C07
+:10F2D00007E30DAA802385F79258BDADE3EA09182C
+:10F2E0000FF9E3F35C7EFD54CCD3E3EA6BA6FD9CFF
+:10F2F0001124FB82618CEC87B6A84AE7F7723E2F97
+:10F30000DD2EED6FB09D9B29E82483C7FDE92C2FEE
+:10F31000F9E91F7AC47DB63EB22BDCBE8496CD9E41
+:10F32000772765E2F7F59A3F8529FB9B839574BFA4
+:10F330003659AE527EF6E6721EC70B842E4DA13DA5
+:10F3400071DB7E1F970F412FE569A5CAF71EAE89B5
+:10F3500060296BC8EF2963711DE15D9335CAF762BF
+:10F360007FA3F74D11CAE7DE0C625F9A64F2173B88
+:10F37000C6FCF95FCFC673F1AF6B3171C788F22558
+:10F38000C90492F1BEEFC08100C2F3B7E6FDA4FE4E
+:10F390007501D6BE7DB916C37D98A6D5D4611CB1C2
+:10F3A00043ABF1225F05A6D67A97911C1ACC67A6CB
+:10F3B0007B70EDE5DCAEC5F7C897D00E87F0DE4B6D
+:10F3C000A1906581EC4A09EDA18E7A0A2F61BEAF4A
+:10F3D0002D3FB33DE742CA7F5716E5109C1D60786C
+:10F3E000B17DB25E25FD5518F4A6D1DE2B34E38B3A
+:10F3F000989A6CF1377257D8F39BF39B54DBFD8FCF
+:10F40000B1097B3D4FF80F798E3C68C96B9E23DABA
+:10F41000F1E45C6F6EE4DE6C8437172F34EBC3D7F6
+:10F420007347A4B201D759A8F909EEA8B6AE1AE5F8
+:10F43000D758686E43BAFBCCF03AE09C56DEDE87C4
+:10F44000FB3E4D57E9BEC3D930B00EC7DD2CE8BC3A
+:10F45000ABD8AE4F7FE851C43970CD1CE4478C87E0
+:10F46000252DF31727FD90B4CC37B12BC7569FD469
+:10F470005D606B7FC6F612DBFB29A9336DEFCFDA37
+:10F480005569AB4FED9D6B6B7FF6BE1A5BBD227D60
+:10F49000A1ADFDF4C38B6DF5197D7F636B3FEBE58B
+:10F4A000E5B6F773FAAFB3BDFFD21B6B6CF573060D
+:10F4B000BE656B6FDAD74EBD38DDFBF9EC6A0FDE47
+:10F4C00007B3C50FED76BBD3EEF6FECF7A7D1DCA2E
+:10F4D000B5B09BE85B453DCEEA6B6EE27E8F777EF2
+:10F4E0004C47B93245D063246818B86FD5612FE90D
+:10F4F0000335C8DBA9C10564778CDFCEE4D174B4D1
+:10F500001661F07D00E5726B325EEA1A82DBA77548
+:10F51000D3DD86EA701DC5DFCDFEAA66402284F3E6
+:10F52000E93CFF887995D8CEA7B3FE96753C29CBE8
+:10F5300074157C80F967F75AFCB391FC31A7FF750D
+:10F54000BAFED67819FC58F648F1662CCB9B9FAFD3
+:10F55000C1343CE6875DE565FBB3D51D6FEA61E329
+:10F560006E2DF1F3F332E1877515F7125F0C14ABD2
+:10F57000A45F40D5CB175BE260B709BB32E0BD8B1F
+:10F58000FC40B564F6611DF1DEA6527C62B3C4E3B3
+:10F590002849B60FA8D776CE7DE3DD5BD8736F8997
+:10F5A000B7D0CBE451ECA0DBC073D23B045E4BB4CC
+:10F5B0008A1A667131FBA2E1009693756667B0B254
+:10F5C000AC6CDB012CDBBC2534DF99B1876B50962A
+:10F5D00078E773FB4F99E64EADC3FDD3381C23D1BA
+:10F5E000999AB39D9F6795AAAF23BDA1557E521EE0
+:10F5F000A2031FD2814425D18F2F1224BDE1C30362
+:10F600001FACAB522AC0DE474A0D09F333AAC3DB55
+:10F61000E97CCE97B6DBABCC2FBD0DF11AA9B7EFC5
+:10F6200077C0BB93E06B97789CB62B5B7FB686C1A7
+:10F63000DF9557928331168C633458E4CD76A14F11
+:10F64000AFF0C9A6FE2779E343DEC81BB27718FDE9
+:10F650006F9727227CDD8072CB77733720BDFB3418
+:10F66000B69B686F7F2749F46FDABB3708DEAA2D97
+:10F6700069A473B1F7239564DFFA5A7E92117FBEB5
+:10F680007E058CE923E3353C7907E97B2871EB683B
+:10F6900057B4E86EA327D339A047F81F981F82F00C
+:10F6A00088FC902E810FF35CEE7D336F4A9C07DF60
+:10F6B000900DB6F3C11BF22AC78E668FFB987F9818
+:10F6C000B0C0BB91CD8378E9F8A4A12E4EE784C0E9
+:10F6D000EFB37D5ADE43F7863F59AFE339E62C811D
+:10F6E000EF733D1CBFE3DD407EC27918E7988E5E64
+:10F6F000E997EB902FCDB8C89BDE1CC27F2C094A3E
+:10F7000033D92B2E536FC927CF269875B719CF241D
+:10F710009397EB35F6EF7EBC7F31B1CB7EAF69526C
+:10F72000B7BD7EC6767B7D4ACA5E6756F311B40BC1
+:10F730001A80E3E7AC5DF6F70D663CB096DFC7F0E4
+:10F74000B2994F72FD6BBBFF0A42FF9B71D771BD2F
+:10F75000E96A14AF456BED7AB540E8F90287FEAC73
+:10F760000C29140FA83E1C3984F6A319A779C5A744
+:10F77000DBE29F66BCC529CFFD47B7017B437E75A1
+:10F78000C2C3E31009E6DFB41489F8C6385EBA14C0
+:10F79000FDB9A564A7359F81F2E99037F1B197E2F1
+:10F7A000CEF6FB12EFD5A9BF90743E4FC232CF8D7B
+:10F7B00065C90BF8F253947F62C63B4C7F5E091A11
+:10F7C000711C6F73EC85E683186FFAAD07709CF3BC
+:10F7D00095670FB7B2FA9A712AE54B6AB3567CDF88
+:10F7E0008FF1427CCFEAD5C5FA58A2FFA75DE4D7D6
+:10F7F0006F10F46CDEE331E323519FD03F3ED32EF4
+:10F800004AFA453EAC1FEDDCB37631D96CD3733C7C
+:10F81000EE66C6D7A6F6DADFF78294ABB1FD3BBB46
+:10F82000312573BBCA08565BE2EF678AFD9AB6348E
+:10F830007DFB5256DF03A94AFCAE4485A08BD8213C
+:10F84000FBBDB13120D1FD82314794588AB59FF676
+:10F85000B8FD7DB9E35ED999CE7B668E787048811C
+:10F860007797B1F9B6E8CD12CACF2D4B99CCC2F932
+:10F870007D22CF78324C46FA3B5F09C6D288DFDF63
+:10F8800028A4373CAF9EF1D232D4E7CFF33C166DBB
+:10F89000A2BEAD96D5B57F55483F6901A8A8080E10
+:10F8A000C58FBF773206EDAEA178D46EB6AFA59303
+:10F8B000D0BFF602EA959FB0FDC57A2FF3C7B1FE1F
+:10F8C00008F3C7B1DCCBFC717CFE53E68F637D1F70
+:10F8D000F3C7B1FC47E68FE3F3C7993F8EF56F0698
+:10F8E000AA1738E359D6F8DE503CAB5F32E359280B
+:10F8F0004A3E70EBB4EF8371AD048F6B9D7A1CC3ED
+:10F900001C87E286C3C611F1C3776EFAB707F09E73
+:10F91000F5CA19EBBAF0BEACD765C6CF789E84990C
+:10F92000FF6CF2DFCABDD7D3B9B13BFF4833EEC796
+:10F93000DEAA207D8BC8ED4A68281F9DFE97E977D7
+:10F9400039ED5FB374EA233FDA01D3D14EEAA6B8AA
+:10F95000CF261794D1FD59C91F43BE70C62B4D3E0B
+:10F960007ED15792F1BED4601EAD88CF7820E5C518
+:10F97000B89A5B12EB14799E24C2D8109B919F2DEC
+:10F9800079C9C1F234C539824183EC2F89D96564C4
+:10F99000A7698928C6A13A47C89BBD4FF0675BBEDF
+:10F9A0009BBE37D199CFF3046A8B6251ECBF3E7F87
+:10F9B00066D49A476BE6F91E0ACDF4F65BC65B1374
+:10F9C0002A19554F294CAFEAA3E855C5C3F3DCD734
+:10F9D0001F98E3C5FCE54DC1E57D685F6D8A46E88B
+:10F9E0009EFBFEFC99647F0CB68FCEA63C6725C8B3
+:10F9F000ED5625EA25BB55C5F5970FB537DBB5FAAA
+:10FA0000385D31F6A3F85C20D84BED3C6A9CE21FD0
+:10FA10009E08D0B996C7CBF30A82CCBFF6DAE2AB28
+:10FA20007CDE1611F7DDA427E2D86F5354D5511CA4
+:10FA30006D2AAB243CAF17785E9F67EAFD18D91B8F
+:10FA40003F137836C7592FFCF5F54D6EB2BBE22D4A
+:10FA5000D9466D2EE56DEEF1E1F8C17BBD9807EF5B
+:10FA6000CEAF1A75DC0338EE8CD1C67DB5A6763ADA
+:10FA70008DFB331CD71D5AAEE1B8AE11F2F39F13C4
+:10FA8000707E5EFB92614EA3733130F56D2A6A3D44
+:10FA90004F76967EB413A70FEFB752EF5F80F9C190
+:10FAA0002A24EBFCCAF0FB0DABF6F1EF556D55FBCC
+:10FAB000C8DED9FA8994F19EC418BF24CE6B07FD25
+:10FAC000709BBD5228F8A950BCD7D15E2946BFD241
+:10FAD0006E5F4C3F6CAFCFE8B3D767BDECB4578CCB
+:10FAE000DFA0BDB244C8BB3E269F7972C5808A7232
+:10FAF000209E4C5523DC0DD0DB86E7992E85E7113F
+:10FB00002C11FAEA22A1CF82FE6C82BFB0C96FF33A
+:10FB100013CDEF6E1489F1C7D51EBABE1D856BDCFF
+:10FB2000B47F74F22FC72D7CA49AC4A4C30E6A308C
+:10FB3000ECF7562F72D8394E7BA85AEDA1BCCC02F7
+:10FB400047FCC13CCFC475E2FD5DE7FC9F755E7369
+:10FB5000BC1D4C6FA1BD627ECF80BEF7C5FA8F532E
+:10FB6000D3522C48795E940F58B8168C9E0C747C36
+:10FB70008ED8F761784B9E4B783B4F3C2B08F2EFC9
+:10FB8000A514D42A29BD98E789A13C59BC82AD8728
+:10FB9000ECE593745E6DB6CFC9EEA5BCB21DF5124F
+:10FBA000F71F93407688B9CF3B82FC9E4DC33952F4
+:10FBB0004AC6FECD25343FC15532B4BF0C4FC738BD
+:10FBC0009E781EDAC575F6FB400D0E7BC3A4878BAD
+:10FBD0001CCFFB7DDC2F32F9E09D392F4F1ECFE08B
+:10FBE000582925EB02CAE9EB490B7FB84E221FE2E8
+:10FBF000DFC7D052883F0E781FD5288F20BBFF2E3D
+:10FC00006024D9E08764ED3C807FF60F9C25B17AB3
+:10FC1000E3A6B33BBAC6E1B5C6811FA151E6D950F0
+:10FC2000757EDD394375FF2683EA11310F732D92FE
+:10FC30007CBF2DDF3760F0EEC43C02B44B0DD8A67C
+:10FC4000600EA6AC6D8B150FF5CBC17ED228FDE200
+:10FC5000B04DCDD02F68F663E8EA34BF0752822555
+:10FC60007F2F0B78ACF3AB88374D0FD27D9F05AA61
+:10FC700086E73F5F148E31A75A7702B6B9260EEF9A
+:10FC8000C7C06E33E19733C39FC2F7D6F95DA3C0F7
+:10FC9000FF97C6C7A9C6738BF79F193ED67CDD9820
+:10FCA00091D78B70B9E8BB1A7A50B68C73DBFE8F94
+:10FCB000287EAD5E06749F4775195A8CD179B97646
+:10FCC00027F9E16A76AD8676C04656473B60636F9A
+:10FCD00037C5A9CB4B6FEF42A22F4FFB01E5C154B3
+:10FCE000D0B2F7B071A76A2A66EC807ACE2119E308
+:10FCF000DEF015A0FB2459FBFDFCFB17C573EF4399
+:10FD0000FF283BDB4B71A040F6CCFBB8B1CBE3C185
+:10FD100026FC81EA23351827571B2086ACA84A29E0
+:10FD2000A846269B02740EE137F6DE88F73299E288
+:10FD300023FD44DF8440BD2AE2E26339C940975B7A
+:10FD40006B403F21F98C4AF1F7B17864C188B2BCAD
+:10FD50003C671BC2539E600348083F8F6B4D4DC8E4
+:10FD6000B1341BBFF25DDE0F7EC9EF11305FA2F12F
+:10FD7000B1E0105E4DB93256C4CBA34BEDF164181F
+:10FD8000606B66FD2B7FB9F87E8C278C1926BFB976
+:10FD90007F6D7E6F27EB5D883F46E79A76BDE11762
+:10FDA000DFB5F03BBE97303968BFBF37CC6FF84E38
+:10FDB0009CF48007625E37D9174BC96E30FD911DE8
+:10FDC000D810E3FFE3807FFFCAD97F26EF0F51EE03
+:10FDD0009F78FCCCCCAB64EFAFF31B9417E4617558
+:10FDE0008647C90DDE7CF6BC40E67191360954ACFD
+:10FDF0000FCD97A6F3FC0D52AC2B260DF9BFEBB53A
+:10FE000018E519C0DA1C9BBD6CE6ABAEB9B6786CD0
+:10FE10000E2BB386EE0D69488F6BF24AC97E0EE752
+:10FE2000F67F0DE5EB47FE5BCFF7A23CC53C87B9FB
+:10FE30004C286FEEEA483279EBF9B010748B5DE62E
+:10FE4000519B290EE6F970BCED79BAD57ECFD0086A
+:10FE5000CAB5384F514027BC5683D68EFDAAC17E05
+:10FE60009FD0F361BECD4E1F1ABFC8F63CCDEC1932
+:10FE7000EB772C461E3F007A9975FC89238C3FD97D
+:10FE800031BE9671FCA171736DE376A83C3E9A8CED
+:10FE9000F869DF9DF64055A0A63890374AFC3EC071
+:10FEA000E3F71BA2CD14BFAF01C6F08C4ECEFDE42C
+:10FEB00098C2EFBD01D96D50648FDFD708FA95194C
+:10FEC0004520FD9EABDABF1F361F9CDF13B3DB431B
+:10FED0002F21A3B079E550551FC5F13F0AEAE87F0D
+:10FEE0008D642FF7B502C58FE707FA6FC073EAFA82
+:10FEF000C0F75D1DB3459E6C01C0DF04F69E8FF711
+:10FF000003FBC4BDBE8E884C7889D78CA57B3AE6AE
+:10FF10003871374C42791897797E02FD61F3F7E525
+:10FF200015D8F21CCCD2790FB4C190E2A516BAE96B
+:10FF300093195EADF39D57D8A358D611F7C00C9A0C
+:10FF40004FD8B983F38DF97CF33D2FE24EE67C0D5B
+:10FF50000BECEB6B706BB4BE06C1BFE67CCFE3FA73
+:10FF600032E0F794F3C99C6E06E7BBC0BEBE068FB5
+:10FF700046EB6B10DF031E9C6FCCE79B6F83AB39A6
+:10FF80008176DB3689F3FF77373FDE81FBFA7EFD32
+:10FF90009A28E90361175F841D58BB8B543EDFA28A
+:10FFA000226FAACD32DF0E26070C910F6F78307FBB
+:10FFB00043A37AAA354AE5BDCCCE36287FA38CDE92
+:10FFC0003FD01AA3FAAED6D9549AE394CDE6DFA770
+:10FFD00099324FCA686FFF32C0FDC66DF9DA6557B6
+:10FFE000A15EAAF6F37B93B3BF0486C5FE6506F156
+:10FFF000011F9EBF5C0A15A8DB266FE770476AC722
+:020000021000EC
+:10000000A470FFFC1587FA5A59DDE372E9A84F196D
+:100010002FC433F9A98703DC0FF7B8B9BC87B9FC43
+:100020007B878B845E01A55E72213E2ECAA6F3FEFD
+:10003000C54B8C90C6F0B644927E532AF414DE6F02
+:10004000B9446C95D3CE8FA0C660E3460C2585DFFE
+:1000500031BAA4E87023EAE578E862F20FE2AC6313
+:100060000E1BE712A127AB5FF500E63BC0F96E82DD
+:1000700063C912BB3DBFCD97D6D03ED9561101DC26
+:100080009FC5F5F6F71E37E7C3B8E3FB068B4EF1C5
+:10009000BD03FAE656867C53677CF24040E4AB8AA7
+:1000A00038E40928BFAD165F164546FDDEC14D0197
+:1000B0002E9F4CFD369C8E393C7F10726C47EB3E78
+:1000C0008A8799F015A82909E57561D33E5B5E130F
+:1000D000432C19C3661C1E943D15E88738D7B343DB
+:1000E000DA933FDAF74D0A407DBDBF4C7CFF531ACF
+:1000F000BEEE5703F6F8EB0998F75C2964E21F1E81
+:10010000775D745889B5E9437831F1F0FFCD475BED
+:100110001166563E77DE0755DC7F2BB27D67D3FC38
+:100120007EF0C5837515540B3D5F749D9BEC1930B3
+:1001300006CA91EE8E9C13E0DF7B33ED97F46F657A
+:10014000B45FBEF8F8C6385B7EA71877A4FD72E6E8
+:100150001B5AEE8B0EE5C3637E89C4CFB10A30CF44
+:100160002DCC9F1FB3DB99B63CB7F5FB1F9430CE67
+:100170007717E6E359CEAD0B993F8FF1AEA215F696
+:10018000BC3A275C665ED5E07DDB794BB43D3A7DB9
+:100190005FB11B3F58D3B53D19074B1EA5798FD0D2
+:1001A000F4A79DF7079520FFCE5E54DCCB70C68385
+:1001B0006F94935AB18479AB296F352BA7E72466E6
+:1001C000E195F61B95641D3E57C6CE6D423C2C6DE5
+:1001D000F9760CE3775A6EE6B8F452A1BF6B829CB5
+:1001E0006E8EBAD2E3308E7D4D4E4D4D302F43FB97
+:1001F00096EFD078F347F86EFDD7823C6E7297D0B9
+:10020000E7CEF74BC4FBAFAE94E93B183E08A5A47C
+:10021000623C37EE9E4DF7F656ED8865BA1FF75CE7
+:100220003871B1151E5F29BFA70DD03B07F1B5F19D
+:10023000E3BB7B1F62A8CCF93848723447E1E35A2C
+:10024000FA7F2D386378FF273F7A91EE373F89F7A1
+:1002500059E6E2F6DDB300E3DF5BCD3A86E4B19E1A
+:100260006DD6BFCDDF0FD6672CA866FDB7220D3245
+:1002700022FBFD960B3A51CF6E95407C87BC6E01F8
+:10028000FA875B5DBCFD3F89F7F32F7CFBBEDB503B
+:10029000DECF74931FB855D823267CFD417E1FA95D
+:1002A000FF14F8BC45EC5B10F119F94CF8BC2513B0
+:1002B0003EFB738CEF209E7C9849C140F07DEC5D45
+:1002C0008BF9C6FFD00AB1ABD81AEE8AED7DF036B5
+:1002D000A0FE1D99F019CF313AF17970E5315A5FDE
+:1002E000A83488EE0D6C9C05344E06386E1D6D5F8B
+:1002F0009FCAE272EC93102F7384FDA778FAA2785C
+:10030000FEAF557DEF068DC991CEE2EEC64CF47D71
+:100310007788DBE5D923C4AB1F15F8FDBD16DF894F
+:1003200070B76BB7D37758DD12B71B36CEEE07C95F
+:10033000D2EF85106FCFE07E00E176CFE1DF470D91
+:1003400031BC638259A88AC3BF513F0298FF1D8AFE
+:100350001EA1BCD050553FF13B5D6928E07485FE7D
+:100360009A57D8678F6E59BA00E54C8E62D2E1F188
+:100370004EA41B65A84E74D493C3FBBFBCF578276D
+:10038000FA733B99FD82DFEB4816F0BC11E7FA9E49
+:1003900014F0DE13367E8EEB1B864F4FFF7DB7B118
+:1003A000FE5B27F17B39F3E5BEC62B912E2F0C9215
+:1003B000FDC59E375ABF93F307416F7F0872FB69F3
+:1003C000EB475E7AEFDC8F91E8F5D702DF9F835E23
+:1003D0007F9D89DE18BD1E71D0EB0790995E5FC9C5
+:1003E00044678C5E8F66C28BB3AE80B11DCF67D57C
+:1003F0003F2FD885E3A95F9EB7FD21562A7FBE39DE
+:1004000049BB19936CF750CD792AA4C45B418B7C0E
+:1004100037BFE34D391099C69D35733BCAB1D31828
+:10042000F704C2ED1CF7208E3B03E54B3091E9FB4E
+:1004300046DF0FF1BCF107C5BA46E29BE74EC13774
+:100440003F0D713A607CE30A9D06DFBC2EDAB37D76
+:1004500008854E8B6FEEA4D257CAF986AE2BCF1DFE
+:10046000CE3700AF74A23CEE2CE67C313EF44667FA
+:10047000B2C8C247F011BD5786EA24BF4D3E7A3B51
+:10048000F411F191B37F7884EF594D1A5C47BC1495
+:10049000D76D9CA5B5F3FB38FDA4B77B6060BF8723
+:1004A000F26C795EAB3F9934B8D9D007F87DC4A916
+:1004B000821F77A20F867ECE4C116752FB60716857
+:1004C000383F87AAD255D6EF0D1C12F37F1A8A57F0
+:1004D000E1FC3DD03F05EDAF91F6698E98EF7BD9F9
+:1004E000C69C50063A3F951EBA3CC4F3372F17F30B
+:1004F000E67CEC6D46FBD3C9EFF357FDE39B0F8C15
+:1005000032CED744FF8B439F9BFF2F0E65E6FF251E
+:10051000213BFF57E1773A33F0FFD74299F97F69E2
+:1005200026BC7C017E6F0A65E0CBEAD3C4F78F045A
+:10053000BE7FF405F1BD51F46FFBFCF86E1B01DFCB
+:10054000EB108FA781EF8D23E07B5388EC95470854
+:10055000FE901EA43876D72CD82B956484E376EBD6
+:10056000385E9D8FC3F0FE81C4E87EFE9FBB62991A
+:10057000BE4FC3FAFD83157EB3DF9C90B8270DFAFA
+:10058000F5E89FDFF5E520C5FB997EBC27F497953C
+:10059000FB0F8632C8FDF93297431F6FD9DB89FA0A
+:1005A000FE0B8CFF58263A5B2DE03E955D7058D0CF
+:1005B000075BF7E3A1BCE1F2AF47FC9ECA3DE1C493
+:1005C000C110F957FD0B515EEDFC568E84F1A82247
+:1005D000232DA19FF073A1C72A433ABFCF20FAED84
+:1005E00054D312E6B3EC6CD624BC6F6419EF97A118
+:1005F00019238FE78483C1D7172279673C8FFDE6E3
+:100600000CD9819FC94E6ACC367E1B22BB2DFE0AB7
+:10061000C9ED33EC72DB5C871CEFA6BC17DFECCCBA
+:10062000BFF7F2F3A02AECBFF86B56F97F34A409A8
+:100630003F948FF759F50F83EF9D10D72BFF8DA5B2
+:10064000133E275E4E056711EA793EDE4799F49422
+:10065000733CD36F35F7C98D3AC912D7718707ED4F
+:100660005E5718E549874CF790160979B26876B657
+:10067000B0DB353F8E7F978893DFB5E2F66A3CEFBB
+:10068000EEB959AB4014143471BDA7AF184FF14FF8
+:100690002D2CD9CE93CD72B0BFBB770A7E9F9CCD57
+:1006A0001BC179CF9D0769F41BB3D06EA078844637
+:1006B000BFF795E3E98E62FC74A3D4DDB81CF5EABC
+:1006C000C220BF57125D728AEFBCF1F893B96E88F1
+:1006D000569DA27D1BB5D702DDF49D8CD36EEFE94C
+:1006E0006ECC945F32232C9B788D8D8AD76884E200
+:1006F0005A267E87CFC3F7AF3ADE2C21BE435592F0
+:100700008657AF428C4ED05E924BFB289FE92B550B
+:100710009C5E80F925A37F67A3D3B4D7CE0BE77D7A
+:1007200071B8CC7623CF27DA39EE2BE0B917C5673D
+:10073000835C8E5143567FEF706EC6B8BF596E68AA
+:10074000D58A549775FC148F430EE64FC7A2686F85
+:10075000B500A747887AC90EA3EFB95BF6F39A30C4
+:10076000CF73DE99155F1E26F862F4FD42D0B4D334
+:100770005A0FEB772DEE2BA8AC5FE8F4FB8D5C9A5B
+:10078000BF7317D3E396EFA599FC3A369104FC1E8C
+:100790008DBF1C3489ED7F24649E13723AB8336890
+:1007A000D69374481E2FEDE679F9BA49275CAE68F6
+:1007B000815E43AE00D81EAEBF203A858D579A8821
+:1007C000E2A7F759FD2995E42FAF03D43F7588F4CC
+:1007D0008576A614637A4AAD7BEAF038E057A5C85F
+:1007E000CFAD7B8AE4DD601DD298CFDCE31FAC1B6C
+:1007F000DE28AB970CD69358DF29F4E4F670DD536E
+:10080000EDC4FFF13BACFC512DE8F02F4D7F3D7A5C
+:10081000BB86F70C925195ECAA8D0E7AF8E7B09B47
+:10082000F05FA525EE477A5874F3808A5757BCC508
+:100830009110F2C384E80749FCCEDE8479224DB5DD
+:10084000947FCFA127BA96F8B207F705785A02C667
+:100850002787F62795797FCA52B43F7E9DBF97B10F
+:100860004EFE368FBF05CA383F6B1E1EDFDB27E406
+:10087000C9536145945CBE6645DBC99FF2D6C91475
+:100880003FCEAA936D7A837E298FDAAB367AEBCF8F
+:10089000491C0C5BE523A4E3656C1DFE29911C3CFF
+:1008A0007FA92E53D7A2BFFD7D61FFB17DBA97E42A
+:1008B0004545C49FE0FBF64CC67D137839D5BEBDD7
+:1008C000D89A88D5BA46DEB74B2FE3F9F4CEE7BF06
+:1008D000137838DEF89FDF437659E91DA0EF7E7765
+:1008E00095B6511CD68CBB7AF656A70BF5A17CC0E9
+:1008F0007581F03C2C9DF3BEF8C9DF6B744FE42387
+:100900004FC6F324258BE3F9486B23F5631B4CBFDB
+:10091000D372052E85E7B1D9EEF199F7112E074E66
+:100920000C4BE2CBBE82726879A342DF77B802EC4F
+:10093000F914979B795F2D667E1CCFFB4A40F60227
+:1009400064C36549C7EF4C406C01DEB71FF6FB136B
+:10095000E27CEBEB8EBC89AF362E8BD58A76EFD35B
+:10096000FF5384BF253A97BF4B62FC3B3F97C42F90
+:100970008BD55ACEA35FFA54C99837191FC4473C88
+:10098000563B69383E96C725B7A69F1A2FA78B8777
+:10099000656AC5823C7D381E9CEB6718DB8A78FE51
+:1009A0003AC333DA9D23E183B5A3FD78E932857E2E
+:1009B00077668152EFC273902B1B243A6362F80D65
+:1009C0008BBCB8FAF32DF03AF1E8C4D7954F00DDAF
+:1009D0001BB8F2BB218AB7BD60E2277D2E9D5F98D0
+:1009E000E72796751EE3F95B1AAD73F1EC8A5FE0B9
+:1009F000F71512ED4CDAF2F5DACE019733CCE3BD00
+:100A000005B6EE6323ECBBED3CD0099F137E9FD06F
+:100A10002BCE733150D3E5A807CFCF12E763D32095
+:100A200026CEC7B2281DB734B3BC757E97CEA4B30B
+:100A30002B5A1A06E7C5F125480CD635BCAFF5B4DC
+:100A4000B2F512F6F73551FEFB87F1CB723BF0DDC4
+:100A500022307F97C8A0F3A62B04FE1A98C787BF41
+:100A600099762E134E78AEB7C8F0E941CB3ADFEB5A
+:100A700096EAC43DAAAC2553B15F72BF326D38BC53
+:100A80006BA2FC770E191D7E60A543DF24FEFD5985
+:100A9000275E4C7C350DE165DA67C1CBEF5171E61D
+:100AA000D1790DD9B9039297EEC39BE738ECAF49E2
+:100AB00037139DB764150B3B80AFDBFCCE1740337B
+:100AC000D9F74BC57DACA32E687C38C8CF752A2DCD
+:100AD00072EB3B39D5B76459FC63F35CC7FCAE9449
+:100AE00049CF977B836985D3A1EDBB5143794C09ED
+:100AF000CA6352B256E8888F2E7C3587EC9EAE2CA6
+:100B0000F49F03FCBCCAF7F4A35D97E843FBB7E985
+:100B1000AAC7BA67B0BAFFEBBF4ED2A07A0EE12DDA
+:100B200024F6AD5AEC9B099FBF9C3FB7EC1F8F9FEB
+:100B30009589F899D8C791F484B98FE6BEA11D852F
+:100B4000F4EB2B53FF9CE9F7FAE050D500F2692251
+:100B5000AA520E5D427AAD83BEC705FA4E3C7FBFF6
+:100B6000A2C565FB9DA604DED3C7F61B7DC22F89F7
+:100B700051FFE5F9BC3F9471BB7190EE93ACBF257A
+:100B80000F08BCE131B86FFDAC2FE689B1F1C6A00A
+:100B9000BE872ECB3C25C3E71D713C473F65F0DC8B
+:100BA00024168B59E4F5BE2C6EDFBE17ADEA9533E3
+:100BB000C45FCC72B937B748B5E4871DCBF736664A
+:100BC000FA7EA939DEE0F7E506EDC481A70ECD1B5C
+:100BD000B2133777BC65B713936F7D213BB1FFB676
+:100BE000B79E6A67FDFFF43B0FE9ABF7EAFCB40F71
+:100BF000B92DE7C17FE07D5B157F0390EC7BFA3E6A
+:100C00008EB7A590D623A90C73F83B627A4C427C30
+:100C1000BF891FF3C5B88A0EE910032E578D498886
+:100C2000AFDB853FCAE86C8AF53BAE6F66713BC3AC
+:100C30009CC7E38524DE3336C76574D04679A5F5B5
+:100C4000407AC43C8735F9D91CE74496DD0F3E0D48
+:100C5000FE3D91897F9F959BFFFD16B45F9F5128B4
+:100C60001FF46FA337D1F34B5BAEA4F2B2966BF9CE
+:100C7000BC62BE6F4A8993384E5FE3AFFFF64646CB
+:100C8000AFABF77AE85ED9CA6FBE792BF2A7B7850A
+:100C9000ED3B6BFFBFCC8E383800800000000000B9
+:100CA0001F8B080000000000000BE57D0B7C54C585
+:100CB000B9F89C3DFB4AB2BBD9DDBC96BC38E11902
+:100CC00025C44D801010EB86575109049F51026CCA
+:100CD0000884008104A4BAAD1436246040ACF155F8
+:100CE000F1AA7451ACB657BD4169E5B6D16E442D39
+:100CF000540AB1BED00A06A516154DE45156ABE50F
+:100D0000CEF7CD4C72CEC92E84DAFBFBF7FEFEF196
+:100D1000D77ECC9939F3F8DEF3CD37676F5C587521
+:100D2000FF986442CC430D4E8910D29C45CA5B6D3E
+:100D3000B4DC209501DCA898A7EDA4B0CE5132D246
+:100D4000398690B3F0773994276399781C0652441A
+:100D5000C84A2BFDB742C89943B77BE6D3FEE26D84
+:100D6000362F7D42FBC9B9CB40CB64AF4C1EA740A8
+:100D70004E20F3CAF228B43038D069242405A001EB
+:100D8000611A40DAAF3542679304EDBCDE7A3ABEB1
+:100D9000D518244E8011233E374B747E79BDF31154
+:100DA00050F4678DC8848C82F1F4EF9BF139AC0B61
+:100DB000DE9793D83CC4FBB9F0FE1880621E096C24
+:100DC0001E49FA7E1CECB94CEA014FFA7934254EE3
+:100DD000CA73A6009E7C230112D2692AB31332D7AC
+:100DE000F68783523E85565B58A690044CC73B73EA
+:100DF00009FE9D1D04FF5FE1FC78042112E994CEF9
+:100E0000D2A1677C23850752FCC595C8A17539140A
+:100E10004ACED2D1A369B3129317F0D93124D93E67
+:100E20004835FEE540453AEFD78D4E3BCCB36C8A52
+:100E30005C16CAC3EE53AE857EA654156D62C359C7
+:100E4000492A21F3D8BFC9EBCAF6E641B43E1834AB
+:100E50007987523ACEB3064330BF79C418ECB462F6
+:100E600013E9AC84503116F1F7E87CE74D967D71BB
+:100E70000E4D3B7296CE9334919787D0FEE74A7C15
+:100E800080202DD3F70EF3E207934F5E07CBE824C3
+:100E90004EF320DA7E6E67E574928F5536E0A785B3
+:100EA000BCDDBC80E9684FBFF47F95416D797E71F0
+:100EB000C1AB940C142FA169A381CF2E32209F5572
+:100EC000356BDB2D7CFF8A4F8803FA351EEDC13769
+:100ED000CC93DCCDF8654AA353A1781AED54B03C0D
+:100EE00063F24793092DCF24E43AE877E664D919F1
+:100EF000A6AD37070CC44727BEDF278724BAB6FD47
+:100F0000B99D7B2F07BC159B94C761ADB9E4CE6B2F
+:100F100092A17E9413F05C06CF06607B42A09DC731
+:100F20001A1A4A9F75F83EB255A9F86E7FF1471715
+:100F3000F929BDB61A484D347E22A401E9FAF28F90
+:100F4000E2B19F0FEE9342163AFF29F2377F1C4B16
+:100F5000E753F56393D7A2E0B20C40D7E95E268F42
+:100F600084F86C53283EE71256FE88941585E9F8FC
+:100F70005505874A2CB49FAAF512CAA9C03FC5F7E8
+:100F8000876ABCF9EBCB12C30AE25DF39C76660676
+:100F90007EA678FE30069E3F54E339F0FEBB235F09
+:100FA00056B5BBDB694F063E2785A4F02C45CD69BD
+:100FB00032217114E9BB6E01CFAC3D38F2E5A1845A
+:100FC000DC477C5B50EF904E63D9484A2723F145BC
+:100FD000D303A50E260753E4E3489F13C5B202F8D6
+:100FE000DA1FF8D446398CECFF469E0678263E4A36
+:100FF000EC71BDEF3DE334E37B5BCDC40778DE9A53
+:101000006E0D35D0AEDA7F74715A27D247796002FF
+:10101000D0F10F26F2B8127BBEF6804C8650C62C5B
+:101020000D480805FD0606E28871944A5F91E8F3D1
+:10103000FF1DC8319D5ACA6A6250E8B8AE20F185DA
+:10104000A2F08568B7CCDA3DD548B07DD845E7B782
+:101050005C318424BADE0289F1B3D554EFCBA04DC4
+:101060008D6DB3821904E621E33C143A3F239D5F62
+:101070004E2001CB8302490807075C08870432B081
+:101080007E686030C261811C7C3E3C3002CBB981FD
+:1010900051082F0A1420BC387029C2118149D82E5A
+:1010A0002F50827064E02A7C9E1FB806E12581598A
+:1010B00008BD81D9585F10A8425818A8C4E7A302F8
+:1010C0004BB13C3A703396C70456202C0ADC86702C
+:1010D0006CA0116171A001DB8D0BDC81E5F1817BDE
+:1010E000115E1AB81BE184C043580F0A08F010CFF4
+:1010F000E5F10E6581934A0A70B8027C1C4BEEFE46
+:10110000C1ED52B5D3F731F09D68673610BFBABD57
+:1011100068F735B71B2EA06B94FE4E73FDFC85F768
+:10112000C39F0E27BD746BF6349411B9975E969DDC
+:1011300025E10CFACFE5BB6611D00B243759C3A7C4
+:101140007DF5035BDF5FB8FEDA6AECF0C9C0BFF57E
+:10115000C41BA48F4A47BF2E413FDB14E3B4501495
+:101160007ECB7799705EA39D7E938BC2849CA32FC8
+:10117000833E991974FE7122F04B5EF21F26D2FE57
+:101180000636196004AA4A9CED13A9DE512613D431
+:101190008BDB084179DA16AFB5A7C35C0C1F84B4AA
+:1011A000EE1984F234A490D99FCE2B40BECC3F1AC6
+:1011B0004436E580BC852523ED2FB89290C785CDB8
+:1011C00080F61BE6FF1CEA7BFB33337FA199BC64EE
+:1011D000A513C9695126C65138788BEFA538FACACC
+:1011E000D0907F623C2D0F7F32F812C08B5A431390
+:1011F00013281CB12BFC1235A76464B873A28D961A
+:101200002FD94376035A0B3A9449765A1E75D0B7B4
+:101210009BB20119D3E99FE450603EA146079DCFE0
+:10122000D6C3C4DB40CBC5C75BE444A2A2BF99F8D8
+:1012300077A8E8621FDD313989FE337395B34086A4
+:10124000F78D9D71AEBCBEF4D906EB8675523BF2AC
+:10125000385D57A62F2C39557C72B54B1274280275
+:101260003ACC58DD6D84756E6B72DB917EF1CE12D7
+:1012700018B27B0A713EAA001F1B114FE6F583507E
+:10128000DE05DF51FC5E34CBAEC69B24F45A4D6BB9
+:101290005E6CFC5EFD6F86DF23C06D6362E3D70A80
+:1012A000BC32EEFC725CE5EA91E379AE31B1DB353C
+:1012B000BB983ED5E3799B81ECA1B68A8E4BF9941D
+:1012C000C91509D2A68D9CBFCF87D71FBB985DF9E2
+:1012D00077C1EB4D2EA62762E19528C9A82729BF23
+:1012E0005E4406C7D637D05F34FB758FAB8F9E3315
+:1012F00083BFD8ECA47A6E706C3D37D7C5E81D5318
+:101300007F713D63E67A5C8CF7334EB7038EB2474C
+:1013100080BEB6F58620C85909B1A35C104F32E7EC
+:1013200013673CF0C974D95902FA860C27E847279D
+:10133000E48582B04F1918540A6568064A19F09876
+:101340009E1BDA44BBCEA17E8691D29F761506689D
+:10135000559C86F974DD8942DE9C951EB5BC097BDF
+:10136000DF2B8F822FDCDB36E5307E9D45FD97C37A
+:101370007CDEBDFD48D86EC30FD3B76D52E9C16D99
+:101380001E0F9645FB58FCFB8DE0DFA675C40FF2DF
+:101390003121BADF70D02573BEEDF6019F07BF473C
+:1013A0009CE0CFB89A3E44FDE4A2FA4942FDC4C68F
+:1013B000CF0CC4FF3C48CBEFB852B17FC0E3F5F689
+:1013C000FF77FCFC948B30799AE06C9769FD406A5A
+:1013D000871490D30974EEA3015F66A4BB42181D65
+:1013E000950924047E2FC55BD800FAD7600F819D34
+:1013F000319B5B7C20CFC4ECC2F51F70F83F769D1B
+:1014000043DF3813940220EA99BBFF3ECD46F96FC3
+:10141000438E331ECAA76879B3878EEBEE24BCDCFB
+:101420006C43F9A17FE948C530DD1B807D14659FC1
+:1014300015DA0FEA2907A1BC157C92F1B47FD7D742
+:101440007B9A2862CA5DBED3301FCAD76700FA866E
+:10145000D30DEAE05E7E3E9F3F20E4B3579E9C059D
+:10146000429E2AF3501F4AEE94DEFE62F937BFE532
+:10147000FAD3ED6630967F23F8FE82FD1B3E5FE2D5
+:1014800056CEE9BFC4ED7D63CB765A5EE99195A354
+:10149000D4BFB3A7BFDD61A4652BF5373FA2658339
+:1014A000B5C308ED4AA984DA28BE7DD4C983FD8777
+:1014B00075342BC31FEC3F4EB448D398BE5612AFC1
+:1014C0001D792E3C86703D2B3D661C2F6EE89044A6
+:1014D000902B07E72B62944260C71DC54EE37CEC5E
+:1014E000AF935C4DFBBBC4CDEC82906BD05BCFE681
+:1014F000815E721B61BF6EB192A0DDDDDB3F941394
+:101500000B7BF513E1FBB89BF99EA9659D3771082C
+:10151000C8E97E16476959C3E4B2349384D6819EE4
+:10152000F011C549DBC711F1470597964DBC34FD55
+:101530006B89F8E8FCF77D2D23948690B09DEEF73B
+:101540004ABD5218F68166833504B6B424DD4ACC10
+:101550005076184216908F0F255CA7B9302104CA27
+:101560006F727A7162275DC7C97DBB6DFE28F4BFBB
+:10157000C15FE99D3C2A361E7BDACD79C509787CAE
+:10158000486972821F19F41831EEB0119AAAF4FA60
+:101590005C37F347A83F540E7C3A6341779319E8D0
+:1015A0009D938CFE1019E246BE1DE0D9B9B1044CE2
+:1015B000562DF34FD349A841ED5709FEEA74FBE7D6
+:1015C000BBE93C1EE276848A65C73088575D94EC9F
+:1015D00006BFB4A42EBD0DFCDD07D712EF0213EA3F
+:1015E00083EB605C5F526B01F0EF43DE9DBFB80B95
+:1015F000F069A1FB62D0E3A30ED9144AAF8A31BBD4
+:1016000053603D7FD4CD5FC08AC01AC48B7E1FBC9F
+:10161000D2CDF7C1F9241FF6C127BDD7248691B7D3
+:1016200092A2CA7745E036EC47EC87DF3785B39C5A
+:1016300051E5508B6F317E85C4F6B5C42431FDC7AA
+:10164000ED28D52F4DA8074204EDA6CF223D0AF67E
+:10165000E6A4779417EC762C7D23E643F138B4CCDE
+:101660001EA55E2265D1F4C45637F30F2A4C74BF11
+:1016700040EBA51563EA615E15769B047C27DA6D65
+:10168000E2ED043F8B78959CF8CD18A03FC407A3EA
+:10169000AD7F1E319E52C7A33681ACA5307C79A3A5
+:1016A000F82BB1F075D0D4520AF33AB850260DB4E5
+:1016B0009F93FEB16924CAFB02BE077C43E9B22AAC
+:1016C000898DD743CF21D1F177706D8D77B2A997EE
+:1016D0009E7DEA2BE3CAC17E97031E55E31E70333D
+:1016E0003B7F8C4362F12B4E5A6F9E7FBF938C04DD
+:1016F0003D756A4CD00E71B1EE5F3500BD7F6CC791
+:10170000784579E5E9310D2355F82C266824E7ED75
+:101710007ED0A9D0E7E5439B5282B6D8783C0678C4
+:10172000A478BA031E8CC378CC1FDC17108F2179E4
+:101730006EE437B23BCE1B8678E45BB217FC06182A
+:10174000D78FFA93C5935739D9BCE2747E5E79601E
+:10175000B946BF244424124A52958DAD189F4D8836
+:1017600018F1B95EDE9ED2C99BC07F2C7A0AFCEBD1
+:101770009FFF9EF3E5C1CAC50AC40DCDF1D1FDE0BE
+:10178000EC2449C3576FAFF56BC67BE75B59B35F7A
+:1017900016F0EFBCFF93FE716910AF2A370787F68A
+:1017A00047CE057EDEFEE60127F41BF79525AAFC51
+:1017B0009DE2F689DAD3E6EB14953DBD516E02BC8D
+:1017C0002718B97ED3C99D0FEC2AC5E7E56057E914
+:1017D0001413CE6357E791603BC491F5E30B7BAAEA
+:1017E000E72F615FF574137CE049A2F44BE8A59FF5
+:1017F000881BC6922F21579D5CFEF5F8D7C31BCCE2
+:101800005ABF47C0CFB99C9DF4C79120D58F379759
+:10181000C82122217FA07D3C78BF84FE66B8D28299
+:1018200076B9AA320EE3B3550532D657DD29A3FDAA
+:101830000C53FD504BE7F347AE27F4F1D912227950
+:1018400027ABD63D63749CA67CE3C27BFFB816E24F
+:10185000CBC52605C6DBAFB07873D027A3FF4AFB04
+:10186000F086213E7DDF655EB067821FF6FB6494E3
+:10187000B7E09BB21786EDE0F1E8FDCD052119E850
+:101880002CF97BC6510643FF550AD0E15DCF1627E0
+:10189000E8BBB86F1F282BC3FDA35F2940BB499D40
+:1018A000553AEF382EA793D28BAF073BFEC1661394
+:1018B00081B8D107AB4FA23C77AEADF74E1EDA1B15
+:1018C0005F16F1617D9C591F5FEE1357D6C59305D6
+:1018D0003FE8F9A422067F087D158B3FA81EAB4A7E
+:1018E0004AB9703D26F4C77B7C9D93D2B7DCD940C2
+:1018F000F190B040463C08BE7CF79BDB1F013D1CCD
+:1019000047F9631DF0F3B74FBC02FB10B2588A1AB7
+:1019100047DEDE63F7285D727BE972A37F714F19A2
+:10192000C47F76CD8A9E32AC5F6F5762EBB573EBA6
+:10193000AD61492C5EA1B73B7A79F857DB9DF2CABD
+:10194000FB73E1FDF2CA8521801BD3AD35A07FF585
+:101950007A426F27C47CF4F34C88C824344A3D6F24
+:1019600005DBF5DA0933D607AC8E7C70D6CFC431EF
+:1019700018042710FCD2C371A1461CAFFE92329C02
+:101980007FFD588001E2ED0CC2FA3CF1183F68C9B6
+:1019900064EDE52BE2993F3EDA8DEB9485437ECAF8
+:1019A00085E546BE86516EFF734914BF8D3E431CCC
+:1019B0009C2B4CB21BF742C8A565A28158482F9EAC
+:1019C00084FF4E203240D78B7512EC3B0BACE6C146
+:1019D000E89FFE16FA216BE8BE90F2FBBE7DF2CEC8
+:1019E0006D7489FBBCA312A3F9E702CEF1FC10F5DC
+:1019F000C2F5812A84877EF04E36C8EB2D92FF55C2
+:101A000090838EF2AA3BE15CB86E978CE74A736EC6
+:101A1000797718DBA769CF2765873517E2288D52BC
+:101A2000BC17F488C063BBDD8CFAA5F110D3838D9D
+:101A300047245E66FB889779FDC9F7EDB8CF10782B
+:101A4000A7EB790BC6F7DDEBC2F5887DC677584F5B
+:101A500027E027F67A329DA82F80AFE4DEF9CB7617
+:101A600023AEAB8BC47B61FE011E0F22EFC7A1DF4B
+:101A70002CE85BC7F94FD07739A76F57DBE99F5C3C
+:101A80004ADBB7F8DC78CA2067115C6FD7FB09C85E
+:101A90001F62BD940F4EC1FC76B7313BD172D8CED8
+:101AA000F0652FCA85F909FFDA99C4FC64FDBA2BE9
+:101AB000C43E9DFB19E0DF429C62917BE2D9A431D8
+:101AC00051DA73BF96E2D9904CEB4B9CE45488F406
+:101AD000E2598C23C615EF3992B57E4C058F2BBC8D
+:101AE0006F22E5104F84710B55F35BE32E7124A731
+:101AF000F41DF73BD07140F239F9524BC73AA3AD10
+:101B0000594A243DFB620CA5297DE55C2F67525B99
+:101B1000FB57703EAF97FF33867A22D17E6F95FDDB
+:101B200007DD1436FA49A765705F79389F1EA1F466
+:101B30002E484EE9AB4FFA4BE709C952CF3E86D348
+:101B400079427214BD27F03DDC5DF63DA887F5674C
+:101B500014E23ECF0774073D611E84E3215F76BB2C
+:101B600048E851DA2889C751C47C202E1147DF9BF1
+:101B7000999C83E34A461234D17252AE5702BDDFBC
+:101B80000F3E98F92FE6839B92CF29CF61F44B96B5
+:101B9000717A2F1379163BCF9D67D10FBAD5C03A12
+:101BA000CE18BCDDFE9C0BA7DBCDC97DE4F3E6E4DB
+:101BB00073C8E770B7FF1618AFD14C4EA11F5E5C1B
+:101BC000E981F10E387C9F24D2E72F36707D924355
+:101BD000E946EB5F4996515FDD432E463DFC3D8370
+:101BE00001E7DF45F5EFA339D1F83E6874D3F7CFAD
+:101BF0005C4DF03C8EAE6F3DE3CBA004CF6F9D47B4
+:101C00000CF0DCA33410C305E8A196BEFCD9722EFB
+:101C1000FEA47AE85EA8A7FCB80AF8D1AA388DE736
+:101C2000D2433F4BD6DAF97EF0DFCFD478FE17F0FF
+:101C3000DF2FCFCD7F17CC57CF45D307828FC5BEBF
+:101C40002056BE10954792E1EE3B2E215E3C0F2BB5
+:101C5000715899DDDD21A19D6D3C52E0C7B2DD8A4E
+:101C60004A41D8E1133B59BD3C31BA3FD896EC66A6
+:101C70007906AD2BBC464D1E48109FDFE53BE11CAD
+:101C800042F5E254D986EB4B2A65F143B17EAA674F
+:101C9000A74F49E57153BA9EA42C868724EA0FC04A
+:101CA000399A83EF0F128B8D1ABF5FE0ED56B94C56
+:101CB00082B8B72B9940DA0DF5EB570F87F37B9776
+:101CC0004FDB3E856CFE52C64108CA839BDA6F88A3
+:101CD00063254DD3B5837D483EB4573DCFE9BB9FC7
+:101CE000F83899EF27CCC4037685C815E7E41BD5EF
+:101CF0007EE2F3E47EC4454E261BF8798AD67EB593
+:101D0000C691A871818614BE2F38E542FF57E6764A
+:101D10006B72670EE6A7ACB42B182F9065AF757A7F
+:101D20004EDFF75D3E035154EB4B9A164F14D5FE30
+:101D300021A5CCAD29A795A76BDA0FF00FD2D467F8
+:101D4000D45CACA9CFAA2FD4940706C66BDAE750AF
+:101D500001509707375FA9693FB4E56A4D79F89656
+:101D60009B34ED2F0ACDD7D48F787289A67E64EB91
+:101D70004A4DF9925D3FD2B46FE4715F3D5E2673C8
+:101D8000BC361A99DE69B015623CB2D1A68D4766A1
+:101D9000F37625891372210EDEF861412EE0FB6592
+:101DA000C7788C8BC7E20BBD1E8BA53FF5CF2F4BA1
+:101DB00061FAEE8B97CC069083E5BBA9BC5E42CB63
+:101DC000B6F736C09A9AF3D879AA91B0FC1E71BEC4
+:101DD00022DEEF395F317A597CD561239BA2F04531
+:101DE000768A1235FE29F82816DE1AFA89B7297C78
+:101DF0001DDF156FEF4B2C3F55ADFF774499D79AF8
+:101E00001416DFA2F6655E0AF37746C7A327EE44F1
+:101E100079BC50FD2FE641F5FF9214F443DF98732F
+:101E20002BE8FF9D162FECC9BE287FA3FA0105DA27
+:101E300057B3F6066F2ED02556FC7B4D4A9FF87798
+:101E40000D8B7FC76BF0562BE45D17876B747C8D11
+:101E5000F1EF46B337B73FF1EF5AD031294007C60B
+:101E60001F3DF4E5F1F358FBA000217B25D8F7D8FE
+:101E70008C0A9C739D6F5F4BF7B3B9709EDA02FBBF
+:101E800026D53E87EE6FF9FE260EED02B57BF7A64E
+:101E9000A0DE237B15FAFC0CDDF76E52A028EC9F28
+:101EA0004FE3975B88D76A96919E0FA6E07E97AC2A
+:101EB0008A93215E16DE3721E73BD9F3ED291760BF
+:101EC000CFC9F9CFE5D0EE94D2F5AF8BE277E9CF69
+:101ED000E17AFC6FF0D3243C8F433CADA77611CE62
+:101EE000E3DA53987D5E7F88ED93D71F99E541B97A
+:101EF00049293AE7395C7FF5CDAB297DFCD25753B0
+:101F0000CEE1978AF5AFE4FBDE29725E2BC41B4F4E
+:101F100044CC883799B0FCC8BA3D2612427AB23C0C
+:101F200063414753644307D86713D1E7152B89B042
+:101F30006ED31E19F5134966F541626D003F27B156
+:101F4000586BB75C3EADDD4A9AE6D6D931ADDD4A75
+:101F50002BD7DAAD017EADDDCAA829D4D931ADDDEC
+:101F60001A1898A8B3635ABB35B8F96A9D1DD3DA1D
+:101F7000ADE15BB476EBA290D66E8D7872A5CE8E75
+:101F800069EDD625BBD669EA0BC29B34F5A3F6DC16
+:101F9000A3298FE9F80F4DFB457B9FC3FC9BB1073D
+:101FA0001FD5B41BD7F94B4D3B8AF00EC8D35E80CA
+:101FB0002421E4D263CF6AEA17703FEDB2EEDF6806
+:101FC000FA212D2CDF3A48FF037AFD95F8CDE09CED
+:101FD0001849F7AB1994AECB4392374C9B2DDEB525
+:101FE000A308E6F1D9E12BF6403F8BB668F3B417AE
+:101FF00087B4E53A322811F4431DE58B10E593A52B
+:1020000090BFADD26B4B49BD03F321FAC9678BF684
+:102010005E4330EF33E8EB80FC74B14EC16F3ECECF
+:102020006F627E62BD4BA9DF17567AD7E9A3FFB175
+:102030007D64A719F8B67A9744FE43EABB9E9AB628
+:10204000BB37644459977E1D7ABF734CAA368E3DC8
+:1020500045B6615CFFC49BB297C507B572B8722FD5
+:102060008BE7AF7C5AC2F89A1E1FC22F8D85173995
+:10207000C8F60975C9241452C99FC2F161F168E517
+:10208000EF04FC03E6F3B01C82BCA038255ECF6FE2
+:102090004561D217CF09B95A39D5E3D9EE4D8FCA68
+:1020A000570AFD0FE6514DD8B9949EAFF4785FBE44
+:1020B000EB6E33E8C50BC5FB8254EDF9A0383F2821
+:1020C000A1AB3547C9831378A5FBF225A929B1F740
+:1020D000ADB7A45EF0BEF596D47FEDBEB521F51C7C
+:1020E000F1B32E889751BF521F2FEB1B1FDBFD95BD
+:1020F000E4C038348B7FF9BD5696AFA2B393B91EB6
+:102100008D9DECD9F77E28851A69E7F50E5F0BAC3B
+:102110006F85C37737C0990EDF3DA92AFC3452BCC6
+:10212000E0FD1C6AA77644F10FF7A50ABFA80CE3EF
+:1021300022EB4B587B7DBB5FA7B2FB40ED29451ED0
+:10214000F43B8F1430FB692F3AA7DF79173FCFB9E3
+:1021500003CE0B87F6E6F1DCC9CF55A8D8F9806E1F
+:10216000EB4D651E759EEF83A92E1CCF31EED90E67
+:10217000C8776E741A9C9202FEB301CF459B7CB661
+:10218000693BF3D87BC99AF7D8BD2319F00DFEBC83
+:10219000CDF8B59A6FF7515C42BFB1D6B92F95F91A
+:1021A000BB26E2B382DE15E7B9A60F0BACA06F8D9C
+:1021B00092D7192D8FD3C4F3A426F2F35CD9C9CEDC
+:1021C000777BE4FC3C7952373BFCAFA9F9549CEB9C
+:1021D000CE76F8F6C1F380316801FF32608DBEFF24
+:1021E000FD13A7E35DB03EA4A70DF908C797FB1543
+:1021F0003FF9732AC6E58298AF78ABEC3D06F1B99A
+:10220000FEC6AB3E4EED13AFFA58CD877AF9A3FE6A
+:10221000E72789908797986EC4ED84D19B0BFCDFEC
+:102220000CFF1E87F1D5CF61DD7DF24F1537CFA7AB
+:1022300055CE994F2BFA2977F94EA5B2BCBFBFA551
+:10224000B2BCBF2659D58FE33CFD503CE5D6DBFA46
+:10225000853F396D0CC6358FB160C285C5351D69A6
+:102260007DFC4747DA39FCC733878627C279B288B5
+:102270005BE9DB59034999EAFB31CD2EEDF81B0AE6
+:102280005979001F777922E3FB91698C8E220F50D8
+:10229000C4ADADD3890FEE3BDCC3F3B3453F23D3CD
+:1022A000ECD83ED53D71645A0A9CA749B8AFDCE032
+:1022B0009234FBCB4F524B46C27A86F3FE47A6318F
+:1022C0003EDD3688C567F479902778FB13A9131192
+:1022D00052825D04F834CB72543C16A6B1F97F9259
+:1022E000C8E45BC4CFAAEE67F7BB44DC4CC4010969
+:1022F000F1BE9D40F5CA479B4D04E25A0B65DB06D3
+:10230000E0C39EFB73FC5CDD49FF037B5999578654
+:10231000F947DFF5FE16E033C1DDD75E5E99D6E3FF
+:10232000A7782FF01ED7ACB40B386FEF8C677CDB2F
+:102330006DB7613C5BDF6E29E787CD3C4E01FA1A31
+:10234000EC865B26F5D1ECC7528EF733872C3EF432
+:1023500063A6C5633E8738FF3052FE4C74631A781B
+:1023600010A035909109F7897ACE3F1482EF25D9D4
+:102370006CF89E5121613B5C09357A25C82FEB34FE
+:1023800077AE4F83F95E2679E1FE405A85B33D2D45
+:1023900019EE112A28661B7288A318EA0B0C58EF55
+:1023A000BAD6B9C10479D70A81936C62A2E3D8E99D
+:1023B00038F7A6E5B07505AF694FA3ED12956E32FB
+:1023C000280FF48873AA07E4B89CE5AFEBD7D7C40D
+:1023D000F9D5B69EEE1B001F4AF43CF0A63483C824
+:1023E0009B6F047E2D51C84E762F8AE5A1429A3507
+:1023F000E60B7A59BE7402E41B0D667A06EA7FEAA0
+:102400009AB411DE13F225737C03DFABF3E1EFE541
+:10241000E324E9E453E0930ED000F910C6E904F98F
+:102420007A6645F4F93EC3E9BCCA51F620F0CFCC38
+:10243000090D98E74EBE397B562E02A797C9097D34
+:102440009F401C222E99E9DF3845417D4C9C12E6C5
+:10245000995A156F0D94E36CE39D32D83D0B3F2FD5
+:102460005C6020462A6F93783FBE72227D9CCBE24F
+:10247000AC4CBF1AC9C7422E648E9C22B09FEC8F11
+:10248000FA459B13E87A26D9F6E13962DC90FA1214
+:10249000B857F0CA3CD6C73D31F2F63FE17ACC2DB1
+:1024A000FB3D06F0E9837F79EDE50948E78BE1869E
+:1024B000E61DA6CED7F65CC6E3E7982FDEF99A2F85
+:1024C000EF9FCF2F7F2DADF3B5A6BCEFC2FF5E0906
+:1024D000F4F82794B160DE7AFE17FAECA0EC3F78AE
+:1024E0001BC5FF7594A90285008DA402E9CDF28772
+:1024F000AEE5780E7E4DF16CEDC5F3756D7B117F09
+:10250000074D74DE747CD344866AD38F12793E46BD
+:1025100008C7BDDEDA3205FC9B2E73773E8CDBF5F7
+:10252000C23B5941AA4F0EFDF8A49D50FEFBC0D8F6
+:102530006D87E7C756BF61F751BC1F5A2DE3FD37C2
+:10254000BC97ACCA07FA9CCBCB959EB2A3C057F3FD
+:10255000D67E5BA4F6B3492005EDEEE2900C777CC5
+:102560007BF4DFD2271338D3B1F2B2D6244D59D839
+:10257000E36596E8F7C40779985C2C7E6A9B19F2AC
+:10258000E1AFF4F8FF06E31FE3F906C776DA717FDF
+:1025900025E633FFA90233EC273F68B39030F0BD46
+:1025A000B1C344304EE59B2E51BEF5733ED4CFF3FC
+:1025B000D51713B0BF85F7CB1847AAA46305285ECB
+:1025C000FD6D8BD9FE56B78E858794A9A0AF166E88
+:1025D00094485061ED5753BAF903B7E3F98A7E9DE9
+:1025E0007AFB729AAC36831ED1DB9705C4DB3C01C3
+:1025F000EC568BF6F9A2B63BB0DF45E7398FF178A0
+:10260000F8FEAC888C3D3B18E2CC83305F3096BD41
+:1026100039B69609E5A76BAD088FAF75223C0ACA9B
+:1026200094E279E9AEF6573350AC3B8AC00EC5ED63
+:102630009D64BD89F4FACFC66DD7841F52802FB533
+:10264000F990151CCFC27F5EC4EF199CCF7FAE807E
+:10265000759E231FB2A29FF99027F68CB2C2F3F1A8
+:10266000021F63293ED0FEE61D50C8F9ED6F2CBC59
+:10267000C47A6F197CE7200A9E85DC1CE5FA7DC1CF
+:10268000F6591BD2E9041A5FF86B7627F2258B43C3
+:1026900088732AD9B3A103D62F135DFC2F48DE24FB
+:1026A0002AFED5F3E722E26576C7C6DEB3F2B84468
+:1026B0000F5FB6DD8978157C04370A0C1E80618FA8
+:1026C000A1B8EF7703FA7C1FA0455BFEC2D4990D39
+:1026D0007A63912E5EF085147DFF35DD3388AD5F22
+:1026E000F14D85BC8885A46C038BABB7A09E3A6680
+:1026F0006C79F53690E7ED4C9E963DFFF4AF414F77
+:102700002DF9AFFB1DA0A73E31B6A4C278B58FAF9F
+:1027100077805E3F660C3AE0FD4F4272D4FBBA4FC1
+:10272000787ACE056C9017B61C590C042C3803F43B
+:10273000E4DF1E3739218E5AF7A4256CA1F858BE64
+:1027400093E191968FB0F2ED88AFBA5D5A395CF2A1
+:10275000C4FDA90AEEE783191C7F19A0AA976F3759
+:1027600061FEE8F237652F0C5347BA717DFAF761C5
+:102770001E114AB7BA56B9D29CD8B79E7A3C669019
+:10278000B3BA9D8C4E753A3FB386EB653DBF3FE0D3
+:10279000E17E26E7738A178C87897C561262FAB924
+:1027A000F1170FE41FA1F33ABEFD358794D7CBEFA5
+:1027B00004B22EC12F6FAD9A077906B1F8FC0B2E2B
+:1027C000173D7A9FDB1965179D18F8FE6D0CD69A98
+:1027D000C28E4B293E6AB799BC41FAB8F669D967EF
+:1027E000033FE95D0B7EDF61E9D3AFBC3D9ECE6F59
+:1027F000E90E53F274B60C1BE86741A73AE0EFC24A
+:102800005EBA2C79EE1533E441C2F3D5EE5EFA2CB4
+:10281000DDD16E86BC4A3D1E27B5B69B997CE9E8A2
+:10282000D47A642AD8E5C65F9C31031F7CF2A244A7
+:10283000C085D4BF5FB3ED1507E80FC013D80F41B3
+:10284000AF1EFAF5A15B78C66F46633B279CD3C4E5
+:10285000A25F00E63206F9FB99DFD0F16BDEB378B8
+:1028600061FD35CFDCEC8075FCD558CFF8FC91F5D7
+:10287000A9608F6B4CC1542742F6BC66EB0F90FFEA
+:1028800016BDFE8354827AD33700E497AE7300AC52
+:102890006FE1C3D7E1FAAA891FF9AFE611B90CFCC1
+:1028A000C4D346322D9A9FAF0C60FAE9AF8F5A70AD
+:1028B00053F0573361DFE1F893CCF2F8C80AF443E0
+:1028C0007EC0D74A3531964F5B199D4E79C4FD7550
+:1028D000A6C7EA78ABBAEDB7A31EFB34CB9706F2D6
+:1028E0004EF1A08DA7BE3E258DEB3FFC5E0ABE4794
+:1028F000F96E123C87F61D265F5CBEE63D9ED7CA88
+:10290000C65FC5C7A7F38E87B8DC5F53B5FB570119
+:10291000670C107A807410357FC592FBED1B91AF68
+:102920004EBDC9F4CAF2D0AC6958DF610AA7417D37
+:10293000A8FD5A09F502F52FA2C9F57613976B6D1C
+:102940003D9DA75152E3F745762FAEFA3EDA4EE5AC
+:1029500087F4F28DB9F7794EAF7C8AFC8A453AFF4D
+:102960004C40BD5E481FA0B57FE27DF2704AD47B2B
+:1029700058BDFA20887C516B0AFDFC3F408EDFB5C4
+:10298000E03DC3DAA74DF8BD9CCF9EDAFDF64D942D
+:10299000DF3F6B15F2ABD5B37AF9AD79F63A124D4C
+:1029A0007E3F4B2E2351E5973E8F2ABFC92C7FFFD8
+:1029B0007F5BCF2E8AA167270FD0EA59EA4F245EAA
+:1029C0004A8B9FFE72E940DC67E9F02AF0A9D79BA9
+:1029D000873C0AE257AF37E9DF9B448547813FC117
+:1029E000974BFE73198ED3C3BF823F05FFF6F0A746
+:1029F0007EBD5A3CEAEBE3E0CE514A2FDD4DEBE8D9
+:102A0000FE1ACE5D5F90F1DCB54BE976B8212ECB96
+:102A1000F36EBA9CBCEC62E5EE14F306D01FE279CB
+:102A2000771CCB43E82AEB76B8547EFD9136D9016A
+:102A300079F59DA1E8F91298499102B74463D53719
+:102A4000F0EFD6D8B203B02F6B61E73D0B1A6E7072
+:102A5000803FDDD536786639F8F17B65F4A9BAE2B6
+:102A6000797E55D0671C40F15AC5964C8E91E04F47
+:102A7000C1CFAE6A5B3A1D368D0B366BF1516DBB23
+:102A800016CFB3AAEF33F5F205017F2764063FABFB
+:102A9000E661EDF325905705F4D1F1911FF828CAAE
+:102AA0003D8C3B051F159002B64FE6E7555CAF4DD8
+:102AB00091F3669643FEE21E764FE2449B4C36C08D
+:102AC0007A9FE2E757C114E4CFE5948FD571CEE346
+:102AD000C067C363DBEFE3BF3A54741B6D52FBEB7B
+:102AE0003FE73F44E1F15FBF3BECB7507EFE9DEC1A
+:102AF0003F93BEED27BDF8D55CCCA37CD142605F8F
+:102B0000D4F5E2EFB36F83F26F2C5E9867D73AB6D5
+:102B10003F0EBE6847BBDE95C5FCBFC617CEE47747
+:102B2000A27D6A427AED1AC0EEA99E68FBFB61099C
+:102B3000F2E9DAE8AAC0EEF27D57DD6FE2707FDDE0
+:102B4000F5C219CDBEF2BBAE6739BFAFD46527E57C
+:102B500070BFB8CBC5EE77D6FD76DC63705F71D9F8
+:102B6000CE767315AD9FF4BB6FF341DF743DCBFCA4
+:102B700009EADF6E05977AF780039B4D14CF5F80DB
+:102B8000CF974EF71FE989A5700FA32F5E181EBAC5
+:102B9000281E605D142F35A02763E1E3BD01ECFE24
+:102BA000C8BF1F3EBE9C0BE3D7B68D25104FEFC5A7
+:102BB0008BE463CFED987741D7CF9EBF78261FFC7B
+:102BC000A3F3AD37F2FFD97A53D3FF5DD7CBF87DAE
+:102BD000EB00667FF47CDF97AF9FBF05CBCFD8BDFE
+:102BE00038DF7ECA7B51FABFABBCFFEFD0FBDAFF08
+:102BF000B3F4DECBE96D77C2794AD70BDF66930B6E
+:102C000058F7CDFF47D7DDE3E718BCD6D1747EEF88
+:102C100091D0752552EC3CCE50BA761F3183FB1112
+:102C20003392ABD17F98E163F1954652B807EEA994
+:102C3000057D329E3B60320DC543C7B50521CCDB17
+:102C4000320687FE14F2B8AE5FE665DFF9D2EEAF6A
+:102C500066A44E9B06FEDBFE063A2FDA6EBFDDE071
+:102C60006CA44B98E993D1DFA310FDBCB7265E8519
+:102C70007921338BB5FB8C9B74FB861BCAB5F5D7CA
+:102C800093475320FFEEFA1A13E60B5DA76BBF269E
+:102C9000DD89EBBC81D4AF67F1990BC353473ADBB5
+:102CA0004FF6C5C3B9F1D6074F7C3F89B93C4A5F9F
+:102CB000BC59FC6C7F69A115DCDFE279722BFB85C6
+:102CC0004FC2F79D163EB4C0AFC5C7BED7A9EA171D
+:102CD000F122F07EA1F81674D2E35DE057E04D4F8B
+:102CE00087C7E04C42E58FF7429147E227EA7CCB69
+:102CF000193D7EA30DF178603BBBAF70A0B86A733D
+:102D000001949F92D05F3B3D6114B1D2F5EE3791B3
+:102D10005DECFE974F7116F5E6B348C5BFC7730566
+:102D2000C82754EF4B219F50BD2EC8275497219F91
+:102D300050DD1EF209D5F5904FA8AE877C4275197B
+:102D4000F209D5ED219F505D867C42757BC82754E2
+:102D500097219F50DD1EF209D5F5904FA8AE877CD4
+:102D6000427519F209D5ED219F505D0FF984EA7A79
+:102D7000C8275497219F50DD1EF208D5F59047A82B
+:102D8000AE87BC417519F205D5ED2F8FBCA42997EC
+:102D900090D734ED2759DFD094A738FFAC69FF7D79
+:102DA000CF479AFA2B94CF34F582FE57E59ED43C58
+:102DB00087338B6011EC63D85FA9F7EF9A7E8CA400
+:102DC0000CE3CC66528FD00AF15B0AE3492B421B1D
+:102DD000157380570EF35F9C01FCBA35B801986BF0
+:102DE000FFB833D9A0FF0F4CB886C51FF839C14CC6
+:102DF000F8A7429938E19B4CD8D78A734F474426AD
+:102E0000E151940F2312426724818493281F46E2E4
+:102E100010BA2349F83C29E242981CC9C0E729911D
+:102E2000010853238311A64572107A2223100E88BD
+:102E30005C84303D320ADFCB881420CC8C5C8ACF96
+:102E4000B322E310664726E1F3819112844AE42A13
+:102E50008439912B100E8A5C83ED064766211C1283
+:102E6000998DCF87466E44382C52857078A41261B4
+:102E70006E6429C28B228B115E1CB919DF1B11599C
+:102E800081302F721B3E1F19F921C2FC4823C24B0F
+:102E9000220D08BD913BB05D416423C2C2C8BDF89C
+:102EA0007C54E46E84A3230FE1F33191071116459E
+:102EB0001E433836B20D6171E43F118E8BFC02E186
+:102EC000F8C873F8DEA5911D0827447E8BCF2F8BA1
+:102ED000FC37C2EF4576E3F3CB23ED087D91D7F0C5
+:102EE0007949642FC2899137F0F9A4C8EB082747C4
+:102EF000FE8CCFA744DE453835F211C2EF478E2055
+:102F00009C16F90CE115914F105E193989EF5D158A
+:102F1000F912E1F4C8DFF17969E42B843DFBFD0986
+:102F2000B1EE25FA0D6721AE6573F7EB3B5F846C5C
+:102F3000D19C4B3D90E0403D397335CB23D9507245
+:102F40007232FAB52B2C0AFFBEA64EAF7E6303FF8A
+:102F5000613DD40C607D401EE01CCEBF078A77A780
+:102F600080BFB4A1B0B316E22177E6745600BC2F3F
+:102F700083F90D776430BB784F068B97560E73B28A
+:102F80007B062B86E2F91549EEDF3ADEE4F659B40A
+:102F9000BF398B976DDDD9782FA09FFDF4B7DDF990
+:102FA000F2A37E98E17F2203FD22FDFDBC7EBFFFE0
+:102FB0005FA827FEF9F79F3FD7FB1F707AA564969D
+:102FC000FD16E769F4E543FDC47503E464DA4FE5F3
+:102FD00066C90976B2AAA9602AD0AF90F8309E38A7
+:102FE00027465E5727A7DFFC7A1381B8E27C85600D
+:102FF0003C77FE4E96E70B71D052CA17359C2F9640
+:103000006DDC610617B4A67E11CB3F0AB1389395EB
+:10301000FE07FCBC64F32CCC3F5AFAA436FE540BDA
+:10302000711D19CE91B5CFEB789CA9CFB9822EBE78
+:10303000F46E068F2F7959DE11913371BDA7E97AAD
+:10304000219FC37F8BDD0AFA9FE201CF49C4FA4575
+:10305000BC52E081F4BDCF8079A127F60CC53CB508
+:10306000138A9206EDFC549C3A6C90FFE01F0BCF44
+:1030700029FE309FA4BB2101F3918E507DAE40E22A
+:1030800093D33F16BE9FD6F95E16E1DF6FD49E1B29
+:10309000583763FE75A5890E4CDB553E9E84F71F9D
+:1030A000697FF9BB201EF9B809F3818264A58714F2
+:1030B000F73D57285B6F42FE98BFCBC5F2C382BE77
+:1030C00037215F5FD0E348D3E0A9905734BF39A7D9
+:1030D00000C36EBB4CE8E789F35241A7BE79D165C6
+:1030E00089F07DC425CDAF233D29BD34F5B59BBF07
+:1030F000C4FB03945E4763D0EBE8B9E89598A9A5B3
+:1031000017C4956F80CAD54928A715EBC243EB5564
+:10311000FCA88FD3934C1BDE7714F9C4D3D2193D8E
+:1031200088D19B0A743DB9790CD24B4FA769FFA88F
+:10313000427A90F7ECF8BDDD3983C9BCABE9F3798D
+:103140003C6E39A7F10AF49F7333991E3BB0167297
+:103150002D09797DAD95F8A8F3FCC65A2796DF5A5C
+:10316000EBC1F23B6B1584EFAECD4578D4CCF27950
+:10317000843C5106C0BCBAFC4C2647F999625FB545
+:10318000CA0371E969FF78638C0155A367C6942C63
+:10319000F4BB35791AE5D76AF3303A4D3CCF6BA3CF
+:1031A000E485EFA8CC2FBB54D39EE48EEA2D83FD9B
+:1031B000E07923F39B5DF8FDB61BA72769DA5FDF93
+:1031C0009CA1294FCD5410BFB3A60DD63CBFA96218
+:1031D00084A65CC97F378158E30DEAF329EA19B167
+:1031E0003C6F276B7BAA7E6CDAAD74FC53FB4C58AA
+:1031F000AFA7C7517310F7E3C1472D5EB043C7E0D7
+:103200001E192D1F7B4B467D77CC44824EAABA8F68
+:1032100049A409203132793A7D90C9D3B47FC804DA
+:10322000F6E1E497163CBFABDA229120DCA1EAA6D6
+:1032300098A7E3AEFA8505D7BD608B4CFC785F4953
+:10324000698573EB558F0FF7C2B9E59CC1E12CB8C6
+:10325000B7D7FDAB38EFA3B4B6AA93BD7F8CEEAF62
+:103260005D90972415E2F9C1E7A52DD506C83790E2
+:10327000F7A5809C7EFEAC8CF194C52BDE2A728271
+:103280005E7BB5F5ED623ACED11619C7FDEC49CBA0
+:103290003619E5DD9706DF75ED5D7708E30CAF794C
+:1032A000CAEA32291F7C5A1DCA47BDB39AC5B7FB6B
+:1032B000E287AE17E80DFCAAD263BD768B9D9351D1
+:1032C000E53300F44395C98BE7A647379BF03C8F65
+:1032D000EA7F3CFF3FDA926460FAE759E4BBF946C3
+:1032E000C5AC1E77FE66D9C77E174231C37CC9DDE7
+:1032F000B29F8C8532CB5708364B7E765EA3A5EF06
+:10330000CD2BC6E2FD627DFE94805F5099F2ABCE7C
+:103310008196BCC0CE67C9E84EA33A7F5CC457888B
+:1033200087F52FBEE3533BE8819F4CA0F0848F7D4F
+:1033300072F0F4763BEAC7E386978A6EA5F0B3D2C3
+:10334000E0C7464A977AD9FF5026E4EF18366F95C2
+:10335000F05CE4A39FC079FCA74F9BBC28863C5F30
+:103360006BC92F170F3C577E10CC809D2F8753259C
+:103370000F7C959760FEC66CD2CAE3032176FE0FE0
+:1033800093A0F871D6B273AC8FC6D837C13DDC2A92
+:10339000DDBDDD8FF8BD856732258D7D3ECECB55F9
+:1033A00006269FE445F6FD45C87B19A2B2A7429FB9
+:1033B000BE90C9F2497AEC2A6945BD52CDBF0F5C77
+:1033C000FBA485DDD3518813E47131230FF90AE49E
+:1033D00099CE7789F9E99F023B2F221D68E73E3598
+:1033E00085AA3B72E0FD6D4D6E7CDFE40D81FC72C1
+:1033F0003B60A58A03F4C722C2E6B7AC450A8555EF
+:10340000710AF17B1C04EC824ADFF4B5075A3BB029
+:1034100090DBBB854497EFD3A2B54B6509765CD7AB
+:1034200092169EF7DC332F999CA538ABF6875E9DEC
+:1034300081F396BCA128F35844BAC3F01DE0654F50
+:10344000B1FB40FA79E9D7D1DF79567B674D86EF3A
+:1034500009F78CAB9BB7C037810B4A2A3A08BC5797
+:1034600007193EABDB24A4D75FB85F25EED909BAB4
+:103470002F22653340AF2DBA8FEE0B737AF9A0C7B8
+:103480005EEF08A1BFF4196971D828FFD76ED97112
+:10349000FD3878EFE1D7CDC0DF15EEF050838BEE2D
+:1034A00017833FFEC9B4AC28F65D67CFFF55F821FE
+:1034B0003CCE84EF517C2CDC2E635E83AA1D3FDF63
+:1034C0000F327E0E12CC23AA7953F636D2A735F0EE
+:1034D000733E85173E5F819FFFED79EBFD98DC2CF5
+:1034E0009E6F10C38FD1EB973E7E8CCE7EC2BD09FE
+:1034F000B097DD292C0FFC94D197E846BDACD3BB27
+:103500002985F8DD51A177ABB9DD13E32C047B47A6
+:10351000CB1F6F79CE01F187BFDCF75C2AE65180C3
+:103520007DC9EBB52FB754B1F16E793E0EF3963EDF
+:103530002FEDC807BFAFE291DF3BD4DF35ADF3F825
+:10354000A766C17CB93D5C266FCB76823D0C44CF2B
+:10355000ABE8B3FF8AB54EFB79D669D7AE733EAC04
+:1035600053751FA48AAFF3C366B6BE8F36B3F52E6C
+:10357000E8B3CE209E83DCF298C51B443F238C76B3
+:10358000FCD80E99C0FDB31E3F4367F74F9396AD2D
+:10359000808F652BDF396CA47CB17818C50FE5836B
+:1035A0008ABB2D68E717FF8A9D7F7E2A95A4E101DB
+:1035B000FCCB61C70FE9F325D43F00FFA2771E3D86
+:1035C000767F7996DAEEF7137FCB791C6A79DBEF99
+:1035D000F1F7A2241FCB875C2EBE03B34BF71D1857
+:1035E000057400BB276F053A651285ED13B5F1D45C
+:1035F000BF0DFD72EE4AE4FFEE61EAEFF5D6C58736
+:103600004D90EFDBBD4342BF68D9AA12470981FC48
+:10361000561607BB238BD92FC9E7C3BC170BA56B65
+:103620003C1DEF27590A7BAE38595EF7C304BF3BF8
+:1036300023E6AB7F0EF1712BD83F9B01ED9F7EFD02
+:103640002FF07196C906F4A76BCDCCAFEEE2DF7D0B
+:1036500078288BF9D30F6531FF7A1B8F0F74811F88
+:1036600009E7D39759F0F77A08998C71722361FCB6
+:10367000671478731ABFE8916FF497BB33014F73E7
+:10368000498709E839A3789602F7060EA75AF13B55
+:103690004AF4AF0CFA99CDFBD96F62F7040EC31848
+:1036A000745DB3793CF9307C06948E7F788019FD87
+:1036B000D8E00B16F4136E8F67F13E929C68043EBF
+:1036C000BF89EBA939132C3E381F983DE1F63280B3
+:1036D000B4BF20A1F8AAB076AF2FA0E33418989D0C
+:1036E0006F7013BC2F499A3AC700FE2EA16E31E4C9
+:1036F000C9D3D5EF3C9B742E3ED2DE53A885B8C209
+:1037000078C218AC18F1AB29D79A59FD1B8F1C99B8
+:10371000715F26217F826C26B0338023E08BCA4400
+:10372000DCE7CE843C7E374023F2DBD546123430D2
+:10373000D86CC3EF10B1BC7E710E725D310927D217
+:10374000F585F76AEF51DC10368487C3F98E31DCDA
+:103750000EF833581593938E53364D2A04BCD7AECA
+:10376000EBDF7C3F7EE4F88CFB26D0327CEF0AE670
+:10377000F94309F3796653A1073E9D6B242FCB854E
+:103780008C7EC087756E2588ED56303E17F737045E
+:103790005D0A68F76AFCCEE6F3A3FD343BE07D7377
+:1037A000F4B8C9892CB1CF637EDA522EB74B05DF4E
+:1037B0003DA595D7E46C2E37E00F52BCCDE6301610
+:1037C000DFBBB2995CB8B2599EF5B71738DE320B41
+:1037D00009E3BA5FB0201DC5B833394CCC1E84FD57
+:1037E000897908FEAD26F5987F53CDE33106AA49C5
+:1037F000304FB7E531CCEFD7E709510709F3CE9643
+:103800006CD73F57C573648D5EC238A764EE5E0007
+:10381000F393BE17E7057E9F6D6EC57880BE9DA9A8
+:103820004542393735537F4AE2E75BB46CD92CE126
+:10383000EF3BCCCEEC1E89DF2BE77E7535A72BD571
+:10384000DE53E11E5035F85378FEC5BF13B585F938
+:103850009146EEFFCEDFACF5336637A9FC4C06345B
+:10386000F7EA2DBAFC7013F7373E30778F047DAF3F
+:10387000BF67FF8181CD3F984A303F52DCB337723A
+:103880007F52F093926DD29C8B89FB9C15A0A7D898
+:10389000F70E74F95436FCEE4A85C4BF57C9E38A63
+:1038A00027A8BF89DF95391487764BC419BB4AEC2A
+:1038B0004143227CCE9295E724DE3203FCCC0A877A
+:1038C000D908F08CA113C7B955EEB0E7E4F4C6717E
+:1038D00037948CDA027943D7678F9869CDC2530E3B
+:1038E0007EBFC87B00F2D6AFFD86CE1FCB05337DF1
+:1038F000747FD4F54AF75C2B55D1B55B0B661AA9DA
+:103900003DEFBABF7B2B94D76C1D3FD348ED60D7FA
+:103910009DDDD9F00DE135D997B3FA06D1DFE53356
+:10392000213FB8EB41569E4DEB83E0E7F27B40151B
+:10393000E325D4B36BB8FD11F1A30AC34B0C4E645D
+:10394000BFF371BE76B76797AD01FB2CDB8FE2EF5B
+:1039500009DCADF8D680DFD394E9AFCEA670C92CD0
+:103960002968867BF16F868671FB15F5772FD66403
+:1039700031B9DC3890F527F045FBA9FB67FA49839C
+:103980007E5234FD04FE997E8EF6EDA7E19FE9E7B5
+:10399000FB8AB61FE19F89EFCCFD31C7F708F4BB66
+:1039A000740DDB0F93A336CDFDFF93F5CF0F03BB53
+:1039B0007FF2294B12F0E1D267FE3BBB1AFC3FEECF
+:1039C0000F7DD6FEAE19F2BE9747D87771EA22EC8A
+:1039D0003B39CB77B69BA7E6411E6BBB79926A7EDB
+:1039E000B5BDBF7365BC5AE5C73C9A2DF2B5D9EF9A
+:1039F0003A2E7DE613FC9EE05243EBC790E74BC6A0
+:103A0000B3389A7E9D9BF87B87E1DC3F4ABCE0C9D6
+:103A10006CA66FFF31D8F74436851BB309F62FC764
+:103A2000F86ED797BCBF8A78A6C7AB8AEC5685E2FA
+:103A30007BCC9BFE46C83BAD7E38A750A6F37822D0
+:103A400073E20EE82F767CB39BC537DB587CB3C29C
+:103A5000DDB18A1A29723C7BDE5DD6CB08B9EA015A
+:103A6000D273DF0FE286D32CA27CCBCCC91358BC17
+:103A70000CCA07B6D6DD05F2B387FF3EDB9CB12347
+:103A8000E341CE3B73120C4E2AFFBB322A8FC33C5C
+:103A9000E68CBD6C2A3C2FB1D88755B2F838F2C7F6
+:103AA000AE8CB2DF037DA13DC43DFCE670CA0D744F
+:103AB0001DFE3FC89837EDCF4FF047BBA7F20AB7BE
+:103AC00057C7B3999FB6C740E759D83B0F313E75EA
+:103AD000CC567540DC6ADD8002F0A353324B3ECBFE
+:103AE0001ED33B7E4AA6FF2094C5F874B9F9F0BCFA
+:103AF000BFF3788BD3E333A01B85651364F8524280
+:103B00008F5EBF7A7282A67CEDF424E253C74DAF7C
+:103B1000CDD094CB2B066BDADFB46084A6BED4D2B2
+:103B200031BAFE02FCFD3AFB9398DF7BA8EDF4DB93
+:103B3000B3C18FDD2E7B25BA9EC52F3CFE36E45FD8
+:103B40009F809F2029647131F6BD467E1E63F41963
+:103B500035E7317B9F3383DFAE8AF3EBEEE5EDC3D0
+:103B600038BEFE3C46E48BFFB3E7310903F5BFE7FF
+:103B700079FC55BA323269573BD2A7712FCB636EAD
+:103B8000A47E0B7C4FECFB3B2D21F886FBE7FF7DF1
+:103B9000C4ACA8CE65EA220DF8BBBA93761DC173FA
+:103BA0009BA7B89FB4BCED4B33DC93FA7EDB0A9441
+:103BB000E7A9547F2552BEE968272377423C39C7DD
+:103BC0008E79384B9BAFC03875626436C2DA962B5B
+:103BD000B0BF65916BB0BC9CFF9EEF9EF88EA96054
+:103BE00087F7FCDA85FBC1037278D843D08FC58E86
+:103BF000FAA13463CE3AF013F6C407F36EA6E39548
+:103C0000FED7F7310F7DF94E09E3A6A532D923413E
+:103C1000FE7D240EFB2B95FF347A057D7ED5246630
+:103C2000574BC1C7A1F572917D137E4F3AC6EFA4E1
+:103C30008D1DC8FC3A53279BF794C82CEC4FD45FDA
+:103C4000367090E6BB7CA694EDC6F9B6DEF5983AE0
+:103C5000258457464620ACDB39CB08F9E77FC87D81
+:103C60002C19F044DBE3F7C1FAEAE3B189248ADED8
+:103C700012D0C2F5F06CD0C370FE9EE3BB66600A42
+:103C8000FC1E61A7D10A7AD4667582FF32A3B840C0
+:103C9000A956AD4B7EE946BC076149EE3681FD9ED3
+:103CA0004DA15A6FCF8B61676E1C28F47603426179
+:103CB0008F48E407EC3BA83C3E20E469EA4083E6F9
+:103CC0007B3A1D12938BE0AFD8B940698E7FE940F3
+:103CD000DA4F4709297F16F5684736DC47FF57CD8D
+:103CE0009FD2D70AF477183B09C431EAF97C843CA7
+:103CF0009F6FFE7379FB033209005F1CB8FCF20E64
+:103D00001F9D57FB6DA346815D10E3350C6479A6BA
+:103D1000C4D9FD0DE61BBE98A0405CBF14CE3C4646
+:103D2000F7FAF3908F08F1C3BA172D8FC20752EB41
+:103D30001C747F6F83BCC0B830F06DFBEFE28C6009
+:103D40003F0A87F81B002F937E377C327CC7C7D78A
+:103D5000663112F4837CEBE079ACF99E4F7F0979F0
+:103D6000D4F399BF99C99F9FCB6125E7DBF95C0E1E
+:103D70002B8DDE44388F99B74FC67B91F3574B2379
+:103D800077427C40B1E33D7D218742DE4CC097A362
+:103D9000803F195FD6465C5CBE7378BF4C0E4A65A7
+:103DA000966F573AC285FBE7E591246C27E455C826
+:103DB000E91D39FE1DC0D7A58D54BEE938FE750337
+:103DC0004683BCF4F289D909FC44F9C453ADE283BB
+:103DD000C6F6AF8CC027A60912F28985C2492A3ED1
+:103DE0002AEBF14F9C5353E93C6634E5E0F79445E8
+:103DF000FDAF7BF8A57FFCFE18978FF9B6F050F069
+:103E00006B4DF5715EF88EFC896405F5D8CA8D128C
+:103E1000FE38E14A53D924F02F563E28617C0FFC2E
+:103E20000ED03F4507EBCDEA73901B23F9785E7DFA
+:103E30004D6408C22732FD2F03FD2B23D7733CE6C8
+:103E4000473DEF3B557F3BC6D54E852C5EF69D31F9
+:103E50006DFC6E8CCF8BE77FA67D26B24D81B89B23
+:103E60005FC6F3BD2CE2BC5762F13B88E789F89B43
+:103E700038A71371380B7C0F5765474F1B5BB26136
+:103E80001FD2271E57C2ECFEF1ED26766FABFD4F19
+:103E900045065AFF698E0FE372AF79FC87613D4B8F
+:103EA000AE0E3D63A2E5A5773EE78078B9C067AB6B
+:103EB000313C14F64BAD148F101F6CDD2C4F0B31C1
+:103EC0007F2761962ABF22165F2F890C46FC087B4C
+:103ED00023F4F7F36B3DB829157AFC7C7648F0F7AC
+:103EE000322E07CB400E88DADECC2A83DF3523B9A9
+:103EF00012DE73EDB5374C1E849EA6FC8E72533ACB
+:103F0000380BE3EA426FEBEDD16EB9F5DEF1C03765
+:103F10008ADFA950FCFC0F4D62B3890080000000CD
+:103F20001F8B080000000000000BB55B0B7854D518
+:103F3000B55E67CE9C994932AF3C0986C43393077E
+:103F4000700D383C22E1E1C78140002138C15B455A
+:103F50004D65402411131250AE51B8DF9C90808003
+:103F6000D486EA55DA824E28285AB551B0C68A302E
+:103F70003CB4A15A1DABADF456E8A014791BB15660
+:103F8000FCA472D7DAFB9CCC9C4982526F874F37D6
+:103F9000EBECB5F75E7BAD7FADBDD63E8789BFFC50
+:103FA0007AFBFF0240ED8B4F4F820C8009570920AE
+:103FB0000A00339747CD36A4C16E736FF5205D3A82
+:103FC0004C5E500C70917EE301C4BD5F49F210005D
+:103FD000EBF24A50EC00B7625B668FF54B004A3B50
+:103FE000D20051F32C47EC79A66CC2FFD1F32680A6
+:103FF000129C57E73BBF14E01A80DBDCC07F8DC802
+:10400000D41FD7217EE49B6A85397E5C1FCC91BC8E
+:10401000F8F92A3C1307CAC85A2C0B6CDEFF2FB9DB
+:104020002B44B00969004E7314D28A697E5D6E9587
+:10403000AFF32D725FA1F1BF2342633B8E7F67FC1C
+:10404000F8888272ED5936628428C7D61B2F5B1818
+:104050005F453A8E1D09D0F59A35B419E5069C4F97
+:1040600040FE4F5F1B1C5A8B5B3B0C5D17C83EEA42
+:10407000CE1499F655BF2B85F1D727BB4202F6D750
+:104080003BBB8AFC284FD9EEA4300CC57576279926
+:1040900001D7FD26FFF6F1A49FB2DD0327094E14D8
+:1040A0007AA7D50CC8F7409EA2D0F3BEE4D7E54B63
+:1040B0006CF5FD97570AAACB0530BDCCA19AB05D2F
+:1040C000783E1F6004C05DABA7B1F6E560362A19E3
+:1040D00060F2F94A00DC5BDDF91BD8F345E75318C1
+:1040E0003DFDC14839ED075E16602BCA5F91F3C3F1
+:1040F0001580F27526C3901DB8AF4E6FAEAF9970A4
+:10410000D93A8DF157FC6ACA54DAD7A21DC84CE3DC
+:104110000609A142D2D351BB09B200EEB671F13FFC
+:104120006FF860A48CE33F1FE91806C8BA4F6C7F94
+:10413000788CC0ECD949F69CA8E15D3A2F8282F2D6
+:1041400058CF0BACFD400E2C964B181F401AF9436C
+:10415000FF9101FB77C1D32B928C78946A3F93082F
+:104160004F566CCBE2FAE7683849D4E37F5DA61F6F
+:10417000CCFF8E785A43782AF9B7E2690DE9A9177E
+:104180003CADFD3E78BA841D7DE089E16CFA9B1C54
+:104190001F90EFF06D0586172677A72537D48C7C06
+:1041A000B7925D095F17A181F43987EC9B1EC3EBC1
+:1041B0000E4FE0F9783B7726ABC58B8BBF8B9D6F9D
+:1041C000068A1BB766348082CFE7601B1F37AC645A
+:1041D000BFE29EFBDB7E99766EFB8E76DEAFD91951
+:1041E000DC68C791CC7E32D935D1EE6457B27BFD05
+:1041F0002EEBE64BD9757841E09DDEEC0AEE6413B8
+:10420000C919B38BF506C2CDE76133907FF56557C9
+:104210006903D7BB4EAF0C9BA786D87900E99543BD
+:10422000185E22DF072F1565ED7FB7A5029C0DDD17
+:10423000ED378F06B8B114BBAEA0EE7B5A95028A5B
+:104240002FF8F7316C46056C4C9F9C56974626E13B
+:104250007EA73FDCDDAF52FFE4712E3E1EF9715B9D
+:10426000DDFC67424B22EB98DCAD5CDF81A8D93FD7
+:10427000248E1E89B4238E2E4DA037727E3A47DCE1
+:104280006C9E10F74F9C5F184EB43E9FE607D055CA
+:104290009E8AF69BB94370AF457BDF32EE530BD954
+:1042A000A7A22CFA460EEE57685BEEB70FC6E714CE
+:1042B0000751DED4B69656B5401B8FFE53ABA9D13D
+:1042C000DA2E2822DAA9B65408793D3DF598EA316C
+:1042D0009E67F4331BC78365E4E58D273BB2F15E2F
+:1042E000363E6CBD8CF56F1A074AA8973879A587BA
+:1042F0009FFF7001697D7ED4DD0DB8BF502FFE3663
+:10430000509B376232D501EAEBEAB60DADB65CB42C
+:104310002F707C0C6B7BCCAF721C8292B0DF4BC9D0
+:104320009BA9CB11B75FD9383E7C297DE5F4D097A6
+:10433000868F1A235E5C66FFFECF510E5786E056CD
+:10434000D1FE8BFC49EBC045F6D7F1BDD9AF0CC00F
+:10435000FD2541375E8DF8FE859FF0BD0874FEADEA
+:10436000AD742EF94DDDFC1CEF3B85EEF183D0954D
+:104370005DC0C74F6FDBD2AA16337BB07E469B2F42
+:1043800081F7F6047A5C827F68F866FE49711BF556
+:1043900053D84BDCA8D1F47B4680D914F72213798B
+:1043A000BE17F1F276B587E7770D1A5FA36EE7E4E3
+:1043B000383D0C88D9197F611864D837D3D3CD190B
+:1043C000FABEF7FB67A0DF44D26088803859E10964
+:1043D000B7B6C4E1A4C5B39FE12436DFDE08C5FD4E
+:1043E0009B353DADF6EC8B683812C8EFEA1820100B
+:1043F000073B0455C47DD6110E7AD9E7AC9E3852DE
+:1044000013C62BD225C6CFEE395E49180F52C6E52A
+:104410008CD7EC3423C18E5313EC382981AED2E90A
+:1044200090219EE9716E5EC7FA955928C75DDB043D
+:104430003A26285E5B8461009BDA7EEFB7F727BCE3
+:10444000CA520EC6FCB6B6772236C47225C533866C
+:10445000DF48AB8278BB81FC9DD1EFFA1517E1A74D
+:10446000616536F23FD5F687561BB2DED2B25EA248
+:104470009CE6976DEFB79A71DE9B47FEEA0D9ACFE7
+:10448000DCF4A7C80CCF25F0DA9AB08F8D09B49A66
+:10449000C0FFC8B7C4F79684F1CB13FAD725D01B59
+:1044A00012E8D5C6F173E70BCC4FE6A2FD4871DFE9
+:1044B000E6377B347B76FB3FEE40B0B33CC980FBF4
+:1044C000E9CD9C7EB3EDA87FB53D8EF61CF393BF7E
+:1044D000EB389680FF6ECD0095CE0FA98F78F64A07
+:1044E0005F381A9478DEF1FEBFD25FFB53DE098697
+:1044F00073799F68A4F788BADC7F8FDC63A7873A5B
+:10450000FDB99FF2F1E98F19F78575A1467FE69F06
+:1045100084FE3FFDC71AAD76F995B87DEAFCE5FF4C
+:10452000BC28D27A473C5DFE2DB8EFAA89E1C206CD
+:10453000E4AB4AE32D9E33229D63F536EE4FE5AFA3
+:10454000897E3A67AA92C3854B8AE3F609ED45B4A2
+:10455000CF3DCB44661FB599D723F3C067012C85A7
+:10456000F6B85C8D4F22FFBE6562239D6B871BD31F
+:10457000B348FEE15E5EEFED735D997507D27B5245
+:10458000E65864E4DBF3C064D6EE1595555D88E328
+:104590008B6D17D939BF27C5C5F4F3B5E76B7F130A
+:1045A000C6AB6F3C325B3F90E6CEEAA07C75AD04B3
+:1045B0005B6592C7F738C3CD8FACC3D6A21C739B83
+:1045C000AECAA2FC6DDEFF5496F747BE792B259F3D
+:1045D000C0F86028C91D583BD942FDF35BB4569D15
+:1045E000C2DADDDF6C7F7328F277AD117D9B9179A4
+:1045F000D779AF731ECAF571128FC31F9D2E7092AB
+:104600009C8F7A03C95EC2ABD3912CD0E1E1969D19
+:10461000B370DE87F395146F668C7FF737E21CCAA0
+:10462000375F3D3D2F2B8074A697E366D7F9795904
+:10463000F3E2CEFB0567CC4CCFBB2DF23D945FEE91
+:104640004ECE155481E939BD12FD65BE965F235EDD
+:104650001AB7F772EE9BBC22D3EB516B237C8C20F4
+:10466000DEF360E63892531F57F27EA0D941781EE0
+:10467000200F8FCFA3B3F2267A48DE18CEB2DE2504
+:10468000DCB03C1AE9E2CD69EB553A0BF761FE4F1D
+:10469000726428E5D40FCB9101F34EC86E2F8ABF08
+:1046A0008F88E5A92BB478C0F90EA90E56B71E7AEB
+:1046B000362944F5CC21F52F0EB0C7F3733FA97608
+:1046C0003A543A8C3F7138CCA4D7C3E6E0B1FB70C2
+:1046D000DC824D128BA30B36652EEFA27880F62C70
+:1046E000849EEBAEF44A6C9E3EFD44CDAF34F80997
+:1046F000E457D2B9D6979F946FF6566EB1F7ED276F
+:10470000D55ADE5EBE49F213CEAB4B1C66B81AEB2F
+:10471000EC4DAF6F253C562F4E1A6E45C1AB375945
+:10472000997DA30E87EAC6FE80D3614EC5F6560D6D
+:104730000FD1A62456A788591616F7C4552532E975
+:10474000A74C04B30DCF15D1E993FD9C6E7163DDC9
+:10475000B6D2512A937D577865B6DFEE7ED7ECEB63
+:1047600004AC6BCEE13ED271DC89C6871F1D85F299
+:104770009D84D08DA350EFE7C8D0B8CEB91D624854
+:10478000A573C2AC982B30EED500F7F7BA03DB2D3A
+:1047900013F0AF350DD533A83EBA33247D14D56A56
+:1047A0009F8BF8DF17F09685F2DBBBB6199FA3C786
+:1047B00058C8AFEADA8DCFEB61DD67E2506ACD1FF2
+:1047C000450769CF71DDC60FFF3C647F1CDFDD5EEE
+:1047D00047C6312CC161380C47CDE23AC5AE9B08C3
+:1047E000768D2293575C9114223D8A79FC7C980245
+:1047F00042288900E1C67DE3BA5F060F0ED98F809B
+:1048000010EF1FC1F4723488781A88FA70DA18BF72
+:1048100078BF18B2E2BA65E9A0A4923E1FAD047059
+:10482000307DAA6EA4A7643498293E7579B83EE716
+:104830000AE06F677EEFCBA3FA78C1A62466BFEAD1
+:10484000C7EFFCD34F4792BD2A32E2FDE821C25D9B
+:10485000099B0F6C69B1793E69FAEF3C92A7EC09AC
+:10486000AC2BA9DE14038FDECCE2658A8FC52D77D1
+:10487000F447A308274D29C3D602E1A47F9EB73889
+:1048800036BE7AC5B2223E1EEB5527C5AB24B69F75
+:10489000DA1D568693B96B44859D8FB916763E7E98
+:1048A000D492C4E8DA01A5CCCFE69A2040FBC05CE4
+:1048B000309BC575AE72A8B583B2DD4E717E5D4486
+:1048C0007432FBA89ADD2C649FA7BDE96CFD39A466
+:1048D000633CB70E68389B6BE2F8815D42682B8BB6
+:1048E0004F0D32F97F954960712ED11F7F434918D2
+:1048F000C5C93CDF6D34AEEE21AB6F8587CB20EAB6
+:10490000F2209EEA4C91053FA7797F6D65F71AF575
+:10491000B88F2427AB2F941751FE7A33982D742F1C
+:1049200025F378A6CB532F574E219C62FF4133F6D7
+:10493000D739783CAE4BE5F73DE0B085B6C6AF471A
+:1049400032E7F371B293FC6C34C30BF9BD09FB3F42
+:1049500005DE5FE62C95A3F8BCD304ABE99E84E4A6
+:10496000193C346E5DA4FB0F253C2E367B1D6487FD
+:10497000F41B67D37ACF892C2EA1333D544AF9DF3B
+:1049800073E208AA63E7AED957BE81E81786B94932
+:1049900084B9CFBFC7CEA7BB349C4529EFA7F30A84
+:1049A000E917B0FDC8CBF3FB80C8EF713EF2F2FC13
+:1049B0005FD7ABDE5FB74662F6A85BC9F150D7F4AC
+:1049C000019BB7CE11C9227BD4BD245D43B83EA55F
+:1049D000C93DAF2977DC41C4C73CC9E516F051ADEC
+:1049E0005A6121BAB65560B4BE5EDD9A3F66998AB7
+:1049F000F97CD45A351CC5E6CDCCA3F3ECD4B3E98D
+:104A00007973E3EC7EAAE565A76C27BF0917BAE9BD
+:104A10001E6671926F33F3536E8F532D859BE99E03
+:104A200066BE3BE210B07FFE3DF96974CE1D76870D
+:104A30002DD47FB8DD63225A71BBC711AD98AF6624
+:104A4000F4290CE1EDC51A78D14E8B048E9BDA6700
+:104A5000F759BCB89E3B9FEBE7CC73EF15D17D4176
+:104A60005D5EA488CE5FC455510ED9E51981E50974
+:104A70008B9E1595A4A1315C2D225CA1FF2FD470D3
+:104A8000B568C7CBF7929F2E223C0DEF894BAC2B1C
+:104A9000F7B3E72FB695031FBF9F70A79FF748B7DF
+:104AA0004874AF66D1685C87E8D47C99F901F64F09
+:104AB000E2FD6A313B47206AA17CB85EE47902FAE4
+:104AC0005336E511F51D92DA1D2F695DEA2F8EF53B
+:104AD000F7859BE1F926CDCE56761E0DD7F4125DF3
+:104AE000F392937071E6B97D6F8CA1FAEA45C14DDE
+:104AF000F1BE871F6A7AAB273D39D93E595E544FC4
+:104B00007A71C6F4D4ED6F1A2EEA81EB41D74BBD12
+:104B100059D393DEAF8D1FA1E9A11634BDEE18C89D
+:104B2000FD5DF36FFD1CD1F71748E3E3757CCDD72E
+:104B3000F637219F9F9BB5881B5F31C39762B946AB
+:104B4000ABFBB1EBCC0B6DECDE48B7A72EF7F27CDC
+:104B5000EE0718A795D4B4989DA326A8E9ED9EFA70
+:104B6000264D7F929DC795234D39B735A2FE163E3F
+:104B70002BFA98F2A8E68A5BD76A8A3A585E7ABF1F
+:104B8000E8A67D95FDB2F23ADAB78E3B699B60EEFE
+:104B9000184975462AD3BF2E5F593FFF75A91C7768
+:104BA00061924797F3881066F6525F10DC3CCF8D18
+:104BB0005AE8FE50F7D34479E76BF28A4E618C7065
+:104BC00035C9E393C9BF01CF41268FFDE032B69EC0
+:104BD0007A689967686C9DC3AAC34C7C8781C701BA
+:104BE0001D9747B4FB88232B5F6679B0BECEFD3D91
+:104BF000D7093466F45C47E75F92CFCF01DD2F3AE7
+:104C0000D338FECB5A3E607C7A9CA51FDDC3E9FAFF
+:104C1000D4F516E79706FDE8FEA5FB936ED77FD582
+:104C2000AF607926CB571FD0F6CD7C242B762E1083
+:104C30003EE9BCB35A109776C3B9C9F29A29033E2C
+:104C4000B3047A79AEEB29F179AC9E72E791FEA7B5
+:104C5000D8B34D9407404BF6FE82B8BCEC63BAEF74
+:104C6000A2789A09FC7D06A057C69DE77ABEA69F4A
+:104C7000D7F85BD78D4B1C5F9FA19CA0FE9A918BB0
+:104C80008B288FF847BE97E9EF24B45B26E07CB50C
+:104C9000C723E54E3956AF5CFBF7B0E8A2FBC01D59
+:104CA0001E43BD507B7A3FF3EF3A88ACA2FA76EE12
+:104CB0009AF72A4691DD9FC67C1CF9E6B77AD8B9E7
+:104CC0007762CBED23A8949DBBB290D1776EBD8364
+:104CD000D36B783E377765C993741FFF7192524E3C
+:104CE000F8EE5A2FB8A9DE1ABBB564F92DD83FD615
+:104CF00071652AC97D68CBC71563A86E681499BF12
+:104D0000285B1EBE91FA950ED1475B9D0FEEE5B76D
+:104D100010BECD2EE66F87B573A259E2387B578B54
+:104D20001307BA5B8EC3B2E6E62213ADDB86E71348
+:104D3000EEBFCA22B787A9EE7BAD9F6F33E90BCBDD
+:104D4000D46CC4D17181E7DF3516B011AE0E489135
+:104D5000A524FF81A58E614D248078E11AF20B45D0
+:104D6000ABB3B06E62EBEAFAD2D78F68FEA2CFA3E4
+:104D70008FEBA47C8ACE0F4DDE132D4FDF4879C216
+:104D8000896D856910A7F713B42FD4F79D18175FA5
+:104D9000ECA5FE3B94AFDF4784585BA3DD1B1E9060
+:104DA0005A07D0FB5BCCE38FC6E7E59FB425D90853
+:104DB0008F98C71B9F4BFC3CC13CDEF01CFDE6A856
+:104DC00031DFD7EA3BB1CA15E8250EE96D629EDFF7
+:104DD000956FCF387615F4C8F375BF4B1CAFE7F568
+:104DE000DDF72C1FDA13DEC78C72C125D63F1D44B8
+:104DF000C360EDB78D7C17E59D94F2CFED11AA2726
+:104E00005BAD6E2BEAF728F915BD077C49E479A262
+:104E10000D7C61C4C5D13F8EF0911F2EF890FBDD53
+:104E200082762144AFD8F7AF7F4024FE3B360AD0CC
+:104E30004F88ABB31E597F23B9DD395F60557FE4DE
+:104E40003FB74DF0A94C42C59E505FBDD15FEEBB50
+:104E5000BEFABE75957ECF94A8F72B0BB4FACA079D
+:104E60003EA3DE797DBE1BE1533ABCA7DE4F0703AC
+:104E7000AC8E3A1BAC61EDE8F6B6B21C94FF53E180
+:104E8000C84363C97F1C2E764F723AD8C05E029E1B
+:104E9000ED18716126EAE755BBCB4D71E36CB0911B
+:104EA0003DEFC68B86CF6B77EC117380F1EF1C8BD7
+:104EB000FCBBEC2E7AADD1CBFB366E5F8064FE7E00
+:104EC00054ABB7EF5E3CAA1F3DD7F77BF23E6E674F
+:104ED0005DFE93DB6E77527EBAE7E7E93B47937D51
+:104EE000535C6E8251F506110223008E6DE071E86D
+:104EF000B8CDF524DD971EDF784316D58377485D5E
+:104F0000161FCEEB7BADD249F7027F33479D6E6A09
+:104F1000913F4C72984322C5BF315381BD071C138A
+:104F20003683EC61AFE8194E469F3687C2489FA290
+:104F3000F783746E5F48E6EFE9B5F77E77BCC2EFA2
+:104F4000D3BAEF4FB47B84B1DA7E9715A4E9EF7B37
+:104F5000D8F3B252FEFC938DDB67D27C27B6486E45
+:104F600092F7EC1689CDBF10EB7813E2F038E28DA2
+:104F7000E2D7C2F7451F41FAC4365E272F44DCD280
+:104F80007D71DD6249B1B87AE2B14CE7DB29B0FA54
+:104F90005AC7E5422554CEF4AEE1D3867F2EE29186
+:104FA000910AEDAB481F8938FD57EBFE2584CBDE17
+:104FB000E241020E747DE97888E113182E75BBA7D3
+:104FC000B50F9B90C306A82C5EA8136110E505CD14
+:104FD000161864261C98927DE4E78D36E750BA6770
+:104FE000FA3289B7F79ADCAF53BDFCA54996046C39
+:104FF000FF56E061E3EF157D93899632A2EC7E4087
+:105000002C3329263AEF9AAD2C5E24C69B870A786A
+:105010007EEA25B061FB4C819BE78FD0C0F207BDD3
+:10502000C50DE6527E529992F6858C2C3F2F983111
+:105030008BDEE3568E4D5B9A8F99E52F0A66CD3253
+:1050400023AE2B47A4BDE4457AEB163FA7AF4E2B0A
+:1050500091906E126E983509F9F716283F2D288920
+:10506000ADA3CF8BCF37D2F3B7FA059EA0B6DE62E1
+:105070005F4DF1FE53A16B91498CF1BF2BC0E157FD
+:1050800085181D95208FF2E967E89D6A49DFEDD903
+:1050900002655B412FCFE701AC243DCE537F7B906F
+:1050A000F235FCF96D88B7EB35BCCDB3D9C3840BB1
+:1050B000582D9DEEC68597E292CB4CFE3D5333F7BB
+:1050C000F5E6F01E1A3F185ADCC76C2C15DC783157
+:1050D000BDEF388F8E09C7F4F9707F9F4AB85FB46F
+:1050E000ABA0A0ADD1A504547215C63761E76FBF60
+:1050F000A2799B558826313B54B9097F02044C178D
+:10510000B1AD4B413CA09E96BC74663FC1FF4E3D85
+:105110009FCAE6DF672CD5F0787D4479AC0D85FA1F
+:105120002408190568EB33B0F7AC19D73D610ABC08
+:105130005D807AAC35BD95B74426BF6D7652FE7260
+:10514000E679D13703C7D56A793B5C10C3E3F179BF
+:10515000A767F0E6B57138FA40C3CF694F386F19C9
+:10516000C50F0FAF3BE1C2BEBC65C83FD53BAD84A8
+:10517000CEA54740F97301B3377FDF30D3DCFBF7AF
+:10518000177FB882E73BB0859FAF5633A88E34D6E1
+:105190008213F5310D6529455A425A64EFE3438C79
+:1051A0009FF89C94A7C8B767F3F735E0277FD4ED45
+:1051B000A8DBA787DD5064CACF4D3690C85F06C311
+:1051C00046379D3BBAFD268B76166F96BCC4EFE33F
+:1051D0009608D19674A29FC3F392F4A5F965CF7394
+:1051E00073AB854C51B3F176169FF4B824E31FC21C
+:1051F000CFBFEB5ED252A89D9BC36018E1EADBF201
+:105200001D3D2EA17D1C8571EF7FBFD53EA422DC04
+:105210006FB5B6F664B14A36935E326D3E8ACB4BBB
+:1052200036E5F7E3F1F82710CF071BD3193E57797E
+:105230004466C78A8E1C90F1D19D1D02C878CECDE0
+:10524000E84867B4F37C7F46573CD56F22E5FFDD25
+:10525000EF2D9F1AC8E8134FBE3932C0EF576C3498
+:10526000BF1F74398ADB291F3A674739D00E7EFB8E
+:105270006A765FE887EE3A46B828108D28217F527B
+:105280002495DBC5D6C4FC5ADBD71237B7E39203AB
+:10529000FCDC5D3281BFDF33AB835D8407A95384BF
+:1052A00010D23F3820968491B5598BCBD66C13C859
+:1052B00071F6489293418EABDF4055225427CDD6EC
+:1052C00070923228CDD0FF80109048AED9F6050CF0
+:1052D000370EDF1586F92279E59D4C1F019EDFEA26
+:1052E0007802F1B499E4FC629C00E9888B1FCCC67B
+:1052F000FEB879A5719F4D12586BCC8B512F472F5B
+:105300008527BF8EA7C13098E129413FE81F2CFFB8
+:105310003C87E738A54D985D3C360EE91B3B2508D8
+:10532000C92CDF64FE734E4961F7F72B353DE9B8B0
+:10533000F30F048782F3BA4A8D7A4B558C7A4B9FD0
+:105340006AD453A6DFA8977EB3BD86FEFE81FF30E8
+:10535000F4E7D40C37D0B90D630CFC57364E34D07B
+:105360001EF53A037FFEEA5906BAB0F51603FFC0F0
+:105370000DF30CFD83430B0DFD576D5B62A087B4ED
+:10538000DF6FE0BFBA6385A17F5878ADA17F44E7A6
+:105390004F0C7449E46706FE5107371BFA47479FD5
+:1053A00031F48F3DFEA281BEB6EB3706FEF1E7F782
+:1053B0001AE809F0A681BFCCF69E819EECFE8B8197
+:1053C0007F4AF6C786FE69F22943FFF4419F1BE836
+:1053D0000ADFD706FEB62B024F1462C89F6D5A77BC
+:1053E00048058ACFF28FC7219E6FCA30FBC2C474B2
+:1053F0009975DB53855A9EA6E1F60BB0DF66F27E07
+:105400007B1C5C47794126E17A06D07DEFB9768135
+:10541000E1BAAFF3D985F9AE396E1FA98A0D0BF049
+:10542000189D3ED56DA033FDD906FE7EB365437F42
+:10543000FFC020437F4E8DCF40E736941AF8AF6C03
+:10544000540CB4479D6AE0CF5FED37D085ADB30D06
+:10545000FC0337040CFD83433586FEABB63518E8F4
+:1054600021ED8D06FEAB3B5443FFB0F06A43FF884D
+:10547000CE56035D12D960E01F753064E81F1DDD54
+:1054800066E81F7BBCDD405FDBD561E01F7F3E6CC3
+:10549000A027C001037F99ED5D033DD9FD6703FFA0
+:1054A00094EC2386FE69F209437FED29841FE5CF42
+:1054B000AF0AECFDD7F4419F19FAA50CCCD3E97ED5
+:1054C0001A927DF41D7E629EAEE76F15BEAF0CEBA7
+:1054D000DC6B6A60DFC57D69E2799DA3C8CBCE37FE
+:1054E000CCDF6D361667F1841AC2AE5A9A283F7522
+:1054F000A902C31DA51A55ECBE3083BD576047A352
+:105500004CDFA1617E83449AC9E3A1FA21259687E5
+:105510000EB838E2BBE7A13945C0F07F5D51C05DF0
+:105520005442F5D80BE5549FDC09EA2A9203CF5781
+:1055300017BD677A3BC9786FA4B7D36CA8BFB8F51D
+:105540000E24B50E187E09BF9D663BCDF8BBE7D58E
+:10555000EE9504DCDF92B8F91FC2BAC98C25646BE2
+:1055600010FD0BFDF4274137A31F096633FAD1A0C4
+:10557000CCDA0DC141ACFD59D0C7FA37064B19FD45
+:1055800078506174283895B59B837EF67C4B7036D5
+:10559000A39F0C0658BB2D58C3DA67820DACFFD908
+:1055A0006023A39F0FAAAC6D0FAE66CF5F0CB6321F
+:1055B0007A477003A37F1D0CB1B623B88DB5BF0920
+:1055C000B6B3FE9DC10E46EF0A86191D0E76327ADD
+:1055D0006F30C2E8FDC1838C7E2318656D67F0389B
+:1055E0006B7F17EC62FD6F05CF33FAB476DF3FB502
+:1055F00088E75FBA5E741A6012C3839ED7CEA4BADE
+:1056000085C0512A9D35D42D09F543A23D4E6AEB44
+:105610004813F1D8A63CE78AA2CDCD71F9FE7F16DA
+:10562000F17BC10792414DC2F8D744C53C42B12934
+:105630000D42CDECFD2ACFBBAB355C4206CFB71790
+:105640006872556BFE5042F81CC4F0F9D6E5D44997
+:105650007A9DDC322030BF08DB85B92695DD13D872
+:10566000434594F73F3520504DB83DD770C71B6C6C
+:105670003DB7AF8816A9B086336FA2FB9F0322BB4C
+:105680002FED6BBD7AEDDF2FF4D9BFEBC4003A8765
+:10569000A67E23B2FBF4B725C76CBA1FB94FD3CB94
+:1056A0007D4526433B34D7DF48727E52D8F0E4DD97
+:1056B000C852B5B8D04579EBF5545AA3DF57822CC0
+:1056C000B1EF6341799D3E99FC01267644DF042ABF
+:1056D0006B3B72024D34FE662C20880E8CB1E6F5D1
+:1056E000B69F44791ED470F16091C9D04ECFF5AF0A
+:1056F00025FD1C2D540CF2A8B9B2F6BD7BD7E324CE
+:10570000D73F5EFBEC98901FD3B77E2FB16A82F62D
+:10571000FDD462417F4FCDF3411BE8F920EBAF5A36
+:10572000CAEF677E887519BDAFFC508B87E71A24D6
+:10573000162FAB84641FE5D3E71A960EA4FD24C68A
+:10574000CD2A1C67C27155C0BF87A8FA3085E10B0E
+:10575000E7037AEF5685993BD57F77E7EAF71E5145
+:105760007B269747A1F7B073765ADBA84E459C3C41
+:10577000CDE2D86851B5609DFCB6295424880C1F31
+:105780001601E5ADCE407CF49217E83858A4FDFB35
+:1057900018FD39E26B3BCD77F6955183D87B935D4D
+:1057A000A365D25FB309ED41F735BF13F9771274E2
+:1057B000C54EDF71B88ADBD877FE944490BD463B76
+:1057C000D8FB903D2234BED04BFC7C5FB3DBDBD9F1
+:1057D000D2D4109BD7F89EEFF71AAE7EAFE1AD6240
+:1057E000EF81DC7B71DE459D12AB776064B4D8DF5E
+:1057F000CBF74DF58D6FF62F88DB477DC711FE5D2A
+:1058000014448BE3BF873AADCDABE349B438026DA6
+:10581000F678F9388E10D7EF911E10D7C728AF9FB2
+:1058200069955D37E1D028AA268C6DE00937FBAE7B
+:105830004EFFBE6E3EF8595B8D70201CFBD5F5AC5B
+:10584000FE5D08EDECF9A2D2DBF388AE87AE49D954
+:1058500054BFAC6E7A3D1BA5BBA175FD64BA7F9E9B
+:10586000159AFB3AB5955B84635477A35F1C25BFFB
+:10587000880A0D2BA924BDE5D9092BE99E77A6C876
+:10588000ED006F723B208E1431ADE7FED00F4ED18C
+:1058900078F40326BFEE07552B387EF47F8FD1EDC9
+:1058A00017A577FD3587DE7D98BBD87721F5BBAC92
+:1058B0006984AF8554798AF179A17E3EF3BCE02EEC
+:1058C000CC0B88EFA4C4ED7FF25012FB772F270595
+:1058D000C4C7F09EB8D7F3CC2F4DFCDEED5E11B7F8
+:1058E0002852BDFC30D3538D2D3494F484E7B33467
+:1058F0009070FD71FBAA6174DF37319447F9AAF407
+:105900008CD5D7EC31C479B89812BBC77B48E2F785
+:105910006A89F2F6C85B4ADFF88AF209AB05547A65
+:105920009F84FECFFDFE3097FF4B5320FB1A91E77B
+:105930002BAC8E1EE067F53F64D97C6B859EEBB780
+:1059400068EB76FE93D7D36A2EB0EF7112E510DCC8
+:105950007CDD4479ACC95C0EFDDCE9290FB7832EF0
+:10596000CF90811E7E2EE6296CDF4DA65416BF3ED9
+:105970001503C5A437FD7E4CAF633B3D9FB0B80E09
+:10598000179A07F0EF7BC37D9DA7A7BBEB676FEC72
+:10599000BCD3EF99605CEFF7827E9B5B22BBCD02AC
+:1059A0001F8BFB83E1435D3F867BC2FF035073AFD8
+:1059B00086E0390000000000000000000000000048
+:1059C0001F8B080000000000000B7BC4CEC0F0A3BA
+:1059D0001E822538106C62711D0B03C30756D2F569
+:1059E000C17025507F0910E703711610A7027102DC
+:1059F000104703711810BF069AFD0C881F02F11D95
+:105A000020BE0EC49780F82C109F40B277191B035C
+:105A1000C35A36D2EDFF83E4E78940763910CF24AC
+:105A2000231C46F1F0C0F23C0C0CDABC08FE3E5ED2
+:105A30005479051E047BB92065766D03EA0700E9F9
+:105A4000CD424A800300000000000000000000007A
+:105A50001F8B080000000000000BD57D0B7854D58B
+:105A6000B5F03E8F79253393C9839040C493970452
+:105A700009382421F2AA1E0842A4D406F42A5AAEF8
+:105A80000EC823869044B02DB7729B21092F411B6D
+:105A9000152D5AB483458B0A36F268D106EEF028EC
+:105AA000C65BB4D1A282D536D45B450B4944116F95
+:105AB000B5BF77ADB5F7C9CC393349406BFF7BC370
+:105AC000C7B7B3CFD967EFB5D75E6BEDF5DA3B76E5
+:105AD000D9C5E42B19FB027FA09CA330C60644CA9B
+:105AE00051775EBB687B09FCFE99DDFFB8166967DC
+:105AF00094173389B1D1F09E653056CAD8954EF8C7
+:105B000015DA95BD70EA0F97A531B69F29CC018FA4
+:105B1000C26A59EAB7A09FFD9F333FBE975F706787
+:105B200075B8F1BB2063E98C5DC1F877E16C2DCBD2
+:105B300057881526E373DD49BF433FB99BEAE0FB75
+:105B4000B39FBAE97B2B1C46C93E9759587CF34555
+:105B50000EF6AB7EDC5120EAD90C066702DE2C1A69
+:105B6000D780F7D0DBEF11BC075480578B33BE13BF
+:105B7000E04F8BC0BF9F5D9BC40A39FC7A6904FE6D
+:105B80000B8587E60F786EACD7BE9997CFD8BA7AD7
+:105B900046E5DA7A2795ABEB7DDFCCB331B6B23E82
+:105BA00083CA46153E01381AB7B0501050EF2E8404
+:105BB000F646FFF03F21CF69AA3BB37CA6BA3D0D64
+:105BC000FA2988D455B766AA37BA2739036E1C1F3D
+:105BD000E6EEC0F19D5402984733001F978A79BAC8
+:105BE000B4E02C06EB91E7B66B2180E352F782E933
+:105BF0006C24B6CB27BCD9055E9764367420BC1FD5
+:105C0000433B06F31DE69EF23EF332F69FD94FF07A
+:105C1000796C606C203C5FFDEF751D12F4B732D3D8
+:105C2000AE35407F4FC0F86B1C5178DCAAFEB9033B
+:105C3000FA74C23FC4E3D08DBC1E9937D4A3E631B9
+:105C40008C45BDCF8EF473A1FDE6379BEBD67EF37A
+:105C5000347D12D2ABD16F3EAB68F0B9FFF7F67B63
+:105C600029E03C3525D2AF314EBFFD023954C0B7D3
+:105C7000F91B59289C1D3B4E9EE62F0FC2FBBC8D85
+:105C80002A0B65F3E769C01779FC57D6E49B94109B
+:105C9000288C8587458F93135997BC34FB1C19E8D2
+:105CA000292FE3FA4512D25573D4FAE63066F0CDC7
+:105CB0008FEA7D4C1FCAD8DDF505546EA9F7E9C8F7
+:105CC0002777FF5D99D55218CB8F7F11F2EA1E1B03
+:105CD00023FA0B3ECE428F4BD85FC5AC39505F3FA5
+:105CE0002ABDE82E8D885C4679E61274BC5ED26EC1
+:105CF000C8C1F6AF280CE5A0951FEEB6E9D3B0BF3A
+:105D0000B5A364A901F19CC7F921CF1676E662BF5D
+:105D1000CD39A382D88FFF55E287BCFC4B3405C632
+:105D20001D9627F861F4834E94873DF35F96AEE7A6
+:105D300015339664A103DF79D2816F42DF74F07569
+:105D4000F1C3D7475FCD7DD2D77AFF7DEF3BE0FD32
+:105D5000963CBBA664C7C295797138A3C21D4B6F30
+:105D6000797982CEFC7DD399B57CB03EC4DE011A30
+:105D7000BABF3E83E8EEDE7A8DCAB5488730EF07BA
+:105D8000B0E958A8231DE2B8D71551BDD77D8BAD1A
+:105D900020BA4C9FD5CC50FEDE8FF4390E875BA91C
+:105DA000EB1360AE79A20E5BA40C7BC0BDF87E1035
+:105DB000D575DCCAEE928CF6CF0675C0778A683F3F
+:105DC00075C5B3C146F8FD7E17AF5FBDA2530F6620
+:105DD000457D1F5CA7EB5991F6500F4F52A3FAC3B4
+:105DE000FE0BA3E13948ED8DFEE6AF38A10701BEF9
+:105DF0007B5DBCBFB52B8EFD53FA5F2B053240B5E2
+:105E000060AB2CFDACEDA9DFAB231E8C7172A45FDF
+:105E1000E8C1E8F7C16774DD1D797FB9746F10DFE1
+:105E20006F64157912AC43E6F48A0C06EB6FAF6829
+:105E30000EE296DB039FC077647E0F12BCAE0CFEB1
+:105E40007EC48ADFEB8D51EB3369C5CB4184D7D05B
+:105E5000731441AFF20B594B8F00BD2A49763FE9CD
+:105E60001BD701D364C278B32A980670C969150C90
+:105E7000E58192A6BE1BCD0706FD019C6309CEC934
+:105E800015B37A8133180DA701477F701B70F44E4C
+:105E9000A77C7C2B3D4DBA66CCEF26C0FE6D6FB75C
+:105EA000F9515D48453C4157ECF35B8336789E3AA7
+:105EB0001370ADD1BACD62B9B1FDA64D1FC4425128
+:105EC000FBF73F7A5DF3B0CEF116885E5FA8CF9501
+:105ED0000644F03856B4B3D29F313F5BCCFCAE35AC
+:105EE000CD8FA9818C0A4FFFF3BBD7E59F55E18E7B
+:105EF0006DF75B49A2F1274D19F36DC6C7630E908C
+:105F00005FC9385E5164BCE469301E76A636C71D91
+:105F10002F65328CE7FCFAF069E547035E7B0CBC29
+:105F2000B79AE05D6B03BE8DB3FE5F37BCE7CB7FF6
+:105F30002E90BFC47F797DF3DF3FBABF64FC153E6E
+:105F4000F94865E12B015F775CE524FDDE9073FF86
+:105F50006C7CA5E2A7B07E77BC547CE24A192B404A
+:105F6000D72322E3D74A1AED57BDD1776FF3810DBE
+:105F7000D6D4CFFFAFF9F486D7AF5B0E9DAF7C6D63
+:105F8000783D81213FAD2C642107F4B1B2ED2AB2F6
+:105F900037571E291BC8A05FDB9AE14C8749256350
+:105FA000FFD0DF4A43CF985CD24FFF5CCF00FB4E5F
+:105FB0006F02A56BB7B782F4A29512A3EFD783DE69
+:105FC00016023DA6E4950DCE3958F7EF70CEC1719B
+:105FD0006D8CF4E992570EF9CA80CE5D23524629A2
+:105FE00040022B5DC6F3A3E5A8E7DE55289E7B782B
+:105FF0007FF0BC02DB2788F6BDC1959007F044AD69
+:106000007FA2BD395011477FD76599F0F390D0BB7F
+:10601000EE46BD0B047262424B00F56A57BA5D7BD7
+:106020004C8AFDEE265912F306BD0DEDEC115332EC
+:1060300051CF3A30E389157684AF90915C77E5854E
+:106040007419EAEE02CEDB0F59F67D37AE21E95D19
+:106050009952994ADF99EA77F7E831D913516FF3EA
+:1060600016F0F7650D574C6C8C7ECFFC1371FF3525
+:10607000DE071A4AE97DA6B3E2D804183F13E468A4
+:1060800023E02B536D96EA685DD3E2EA8F1BE63B73
+:10609000678500860D331ECC9E1F673F81D534F186
+:1060A000E9A079663E7B48E0EF6E81CF4CE4F5D104
+:1060B000820E41BEB978D31EF9E61ACAE55B4241A9
+:1060C000F30AC4F7A079CC8FFAF686194F90DE6AEE
+:1060D0008CE32A30CBB94CD53CAFAF6B3E1B99FE5D
+:1060E0001D7974EFFD5BF96C230BDC8AED33C57E03
+:1060F0009E5010920285FDCFDF3ADFDEE6FD2DC413
+:10610000271FA74E1E103BCE3F0B2F996E18A7E4FA
+:106110001F3F4EC23CB3BC3C5FBCC33E20E88C2951
+:10612000B81F58EDAB84129FC464AAB6A31D4EF2EB
+:106130001BE0F6B0E6F24B80DE522B56DD2E83DDFF
+:10614000EC79EBEAF7D1CE4EED9843F676536151F8
+:10615000DB246897E4F7CD984274CA08CF6BB1335B
+:10616000E2BBAA1513615E8D8CF3DD66F996895C3E
+:106170003FD069BDBF2B70062BAEA950477665395D
+:10618000F1E66167613E6FE90B47ECF7BDCDDF16C5
+:10619000F94EF8FF9690DFB4BFEFD8743BF9118346
+:1061A000F00FEDD2644B3F49BA3DE2676488A7A87F
+:1061B0003ABCFF6D0F5FDFFE4F19CFC7EE736A4029
+:1061C0000AB63CD987F67A12F325AB2867278342B3
+:1061D00000A2D897D61D94B5FED7A589B1F29642F4
+:1061E0004E7733A2F4DC0E99EBC969332767AF848D
+:1061F0007ECF9670BF70AA0FFE17C5CE671DEC6BE1
+:10620000E1283FC7BAC2C7887F1B819E72802F8258
+:106210008532F9B7D7E6EDF045F3B5AC18FE6D2B36
+:106220007D304D2D15FA1FE047C99375D7C8AF4E85
+:106230001FCA97A48FC4E951DFB10B5FAF24E5C239
+:10624000E8E3AB8E67AC6B2C5F71FD246DE63C27F9
+:10625000EA3BAB326626C593B3BDAFEB7DB4AEA8C7
+:106260004F84E2F49FA64871FD39567D9EB1A5A6E4
+:10627000F5520696CEDADCD7BAA599F161F4EB5A5D
+:10628000A668FF85C24BF5915FDC29FA5BABDD1791
+:10629000C4FDF32CEEED800FA5795418F53D96C79B
+:1062A000FC8FF326A487B8343D443A24CADDD208D3
+:1062B0007CF62CD9349E9A9660C2379B05DA761408
+:1062C000FCAE657682C389E3C1388A0F3A94D0FF69
+:1062D000CFC22E2FF548FDE1505FE462FD4E131D45
+:1062E000ACCE2A8ABBDFA9625DD16CE5F47AE7F90E
+:1062F000C917EB78D799E13DEFEFDCAAF66E1CFFEA
+:1063000071EC772A7BD7C01720F1961E7AE7EBB4A1
+:10631000CAC6F64849200F32AE67010DEAF80A36C0
+:10632000EB35588E453A2CF2915EB05552114E62C3
+:10633000690DFF737DBE10955BE84F7606084F8AA6
+:106340005B67D45E3B3F7DFF9CD0AFD3843E6FBC88
+:10635000FFA162A77E5556C1D06E3EF7F6D40CEA77
+:10636000578747A51138ACFD162A811F2A0390ECE8
+:10637000383CF801FA09584701F9B5F305CECE3D8E
+:10638000303389F5C15F0F59F8EB2189C3C92ACE93
+:10639000CFCE380763B6637B359040F1B29305C426
+:1063A00007B962FC27D6CF4DC0F19FD8D8379F1BC5
+:1063B00070FCB4DEC9C2A0A786EA7D541AEF43C2BE
+:1063C000DFBF59D831C6F3738A4C70EC137CFF845D
+:1063D000B32281FCE7076F9C360CF82BE7A8E24755
+:1063E0001D4F5BCB52FA1A3F3B68E637A6CCEE1343
+:1063F000DE656F4D9C71288A1F7FA178D2DE1D0E4D
+:10640000BF5CCE2E47FAEBEFFB73F5FA8C43F95FD6
+:106410001D2F9B85FD79AEF1772B48CF095F49FC95
+:106420009923E448CE3C2E0F72AB594843FEFDFC45
+:106430000B164D1F6099109E32AB558DFC4D4C775D
+:10644000CF81F743C5DB4C65BA8C5BF850D4BF50A5
+:106450008E6CE2FE73C3CF0FEB7E17CAB9CDAF29A6
+:10646000640BE7556A0DB8DE39EBCDFEFDC12CCAD1
+:10647000EF8EFE7AA1D7655AFCF85F751D3A701D44
+:1064800012FFF9EB105219D19D51D72456116FFF0D
+:10649000FB44D0A9B6E210B743C0F87B272A1E01FF
+:1064A000EB99829BC04F83F74D44BB35B886F9F317
+:1064B000E3C84B9B9A48746F637A7828FA0FE65CBE
+:1064C000DFB117E5D50466925F71E4864DC5EFD262
+:1064D000B8DC080567F2F27385E265F9EB5908E369
+:1064E0005B9337D4ED47BF5E6635B79B33D7042542
+:1064F0003BD473EA981F87C9AD64BCFD6C16D27992
+:10650000BCE66806D0CD104137430C7A5966A69791
+:10651000C17596B8D01A737D20D2057C37D0422F32
+:10652000D67E723446F1B8BCF5328F17CD32C77DB6
+:10653000F259F7FB3F0778F30FB9FD61161B6FB2F5
+:10654000F6AFB24001E265F70FDDFF590013FCD949
+:10655000FA49A98817902749244F2AE2DB3D31F4F4
+:106560006AE81BBDB48FC84FDEAEB7F7ABF2D39766
+:10657000CE0538D67A7446E307B349AE2B225E794E
+:1065800030F37A6707FA6DDC4524DFF7631DFD3CC5
+:1065900019970C8C96F78AF02319F546E147B28ECD
+:1065A0003755E57AF07B4C9F8A7818E50864605C83
+:1065B000CF9691BE730E8C67F381BE15E7BBB16AAF
+:1065C000029FAFA6FE2D1AFFB071FB481E32BE1F00
+:1065D0003377CA79E1A3440DDCA442199C04660414
+:1065E000D27F0E0B35E2FAD635F3FD2DD2EE16D161
+:1065F0002E8879053DED02D06E84A9DD3C9C0FB458
+:10660000D34DED2A62DADD26FA63A671F598716B37
+:10661000447FA4CFF5B4F3C7F4B754B4233DB0A777
+:106620009D16D3DF3231AE6E6AE78B69F7EF067CD9
+:10663000A6719979DC9EF7A576E33DF9630FE44FE7
+:10664000217A39943FA57C2E8CB3F4451B97115BBE
+:10665000793E874157FB45BB26A4AB42CC5B6163C7
+:10666000AA294F85E7AD34BA673A0351CF7BE8CA10
+:106670003DD317FFF95C537B758D8BE9C5F49CDA2C
+:1066800037FD5D11F1AA1F4C427FEBEA3459F8DB6C
+:10669000AE69D05590630354537D4D86786FBBA689
+:1066A000810262223E02B2F29B8551FCDD33FE3F45
+:1066B0000B7EE13F8EC03FDB02FF6C33FCA2EECCD1
+:1066C000E4EFD595B327E17C0CFFF2D9A6E50D41A7
+:1066D000F7FFE6F95559E65765995F95697EF69596
+:1066E00055938279FF97E6B7CC32BF6596F92D3383
+:1066F000CDCFB972D905AD9FB5DDDDB66692B76B6A
+:10670000F35F27FD7FAD88E326ACD41B56E07BE02A
+:10671000ED76EA4F23F93E8AE99FA33CE8EFBB47B9
+:10672000548DE482D323935C60F9F6507E36876BF8
+:1067300026C885E7541F97DF02CED72CF50F2D759D
+:10674000F8E56FB86FFA9861475AE47C3FFBDACA04
+:106750004CBE9FACF2F8E5E87D4D15B83938A094F1
+:10676000E44FA38FCB9FFD03843C4A837D8DFC4483
+:106770001924AF6C425EDD57CFF3D89A457E506343
+:106780005A11E1A759D80B2C9465DA370F4C9CD2DB
+:10679000867EAB334779DEE23A1BD7C756D6339DA8
+:1067A000E8ABDE49F945FBA0DF003468057D0FCB7F
+:1067B000E741DFC3724F7D0695BFACD7A8DC01E38C
+:1067C00062F94CBD9F0560FC6DF563A8FC31EA8B56
+:1067D000503E20F4C52BD264F2576CAE872D339F08
+:1067E000F4482A1FA9F78D5561BC9FD46750FD233B
+:1067F00069E6581BD9AD1D8D4900E7EE57F3285FB8
+:1068000069429A4AFB2F53C34A5249E4B981D78F50
+:10681000A44957E077E33264DECE196AF4C66F57B5
+:1068200086EDC664A8040F7307156F5ADC76E5364B
+:10683000C04BA95BF4E70B347AE2F7F72D6C57E411
+:1068400016FDA5698DEEF8FDCDC47147FA381E58C6
+:1068500046474362FC763760BB429F986F56584E5E
+:106860008C3FEE6C1C3725A53980F1AD2B6733D2F8
+:10687000476D69DA66292A3E141A50C164A0F39460
+:10688000D4E63A6CF78D809FE5C0F89AD7CF64A024
+:10689000679B1BDE17624E138F478DBF0EDEA33E34
+:1068A0008CEF4744BDC7EFA11C3B4B7C9F647EDF50
+:1068B000A397AF613D793C98BC646B32D79365CEAA
+:1068C0009FCB571E98847C9F6CE7EF7F8A75D4B767
+:1068D0009633431EF1F609FCFD8F8CF65EFEFE1723
+:1068E000A27D4A0A9FB76B8A338471B147BE7B4948
+:1068F000E6DCC2C87C2FFA5EC1B0B951F37BE47B01
+:10690000E332E7BA23F3B9E8FB1386CDEDC3EE49D2
+:106910002D977B7264516E25371792FC1CE5A820D9
+:10692000B9336A60A98EFCACACE770FD87EDAE862A
+:10693000863C822B88F2C680EB278BCD700DAE3162
+:10694000C3F5931A335C836BFB866B9D8DCBB5DEF1
+:10695000E083F1F5E8F11FFD37F3F8437E601EFF99
+:10696000D11F98C71F72E7571E3F1CBD2E9B6E3765
+:106970008F9FB5C43CFEA625E6F1B3967EB5F1FF28
+:1069800051FA78922D70C426F45D255AEFAC0B981D
+:10699000F45368F78A681754A2F5D840C0A49F4200
+:1069A000BBD76D42DF35B5AB8869F707D11F338D93
+:1069B000ABC78CDB21FA0BCBD1FDF963FAFB8B68FB
+:1069C0001794A3FBD362FAFBC080CFD4CE17D3AE0B
+:1069D0004BB463A67199795CF82950A19FEFB30479
+:1069E0003FFA47964D5E4371AF812C20A1BFCF97F0
+:1069F000CA461D82EF592ECFBF4F9EB2EC62B43B08
+:106A0000D7249BFD5CE9766E9FD9EC0A95BE44566F
+:106A100047F900CE60E68CA87C8B6A3BDFCF7ADE3C
+:106A2000BB8399D746BD1F28BE5F23E2D469F6D247
+:106A300046942BBEC1D03E8EBF22538C6BBC67697F
+:106A4000FE761DE0DDF8AF3347A3BF2832AE8DB729
+:106A5000BB588C9B151FAE35D97CDC45386E213E6A
+:106A600037F48B6026E1D7C74BE3F9839EEF49FFEC
+:106A70000578593DD9292B49F07E3DF76F1A7EF6EE
+:106A8000647B9D13F3761B2F92D963D82EAB6F3F97
+:106A90004E53BDD9DFA9FA2A74B4F70655FA8A1401
+:106AA000D6FB770F97CBE5F1E20DA3C5BC9A2A2759
+:106AB00035E7C1F8EC90D96F0B84CDA2F3610A954C
+:106AC000C0687B3CBF6D538129AF3E7950DF7EDBD0
+:106AD00046A15FF4CC033A8AB77E370AF8D8C602DB
+:106AE000939E959C3293F4ABE486AB9DBE38DFADAC
+:106AF000B5F4EF6233756C9798D6CC64EE5C34E9EC
+:106B0000614DBEC7F83E94093209E33F693BC2C8F4
+:106B10003F674BF8790A3523149428CEC1E7896A78
+:106B200025FE24AAE1A00CED076D54593895B1FB60
+:106B3000E5C08D881F575E33F9C7549F2E219ECE26
+:106B4000D94257D379025017E3E57FCCB3733FF0B6
+:106B5000C3DACCDF65C759C7DBEC9A492F1DF4A90E
+:106B60009D858B7B6F1F69C7E1EAA1D30CA04FE421
+:106B70006F8DD3E9ED8ABED84EFA5A968FFC8E8679
+:106B80007C35F85FC4B7E78E61E247BBE10F308F19
+:106B9000DBDA6C3CBFEF73681D15F7B94DF8BFE643
+:106BA0008A78F73C56E1C597A7995C8E7C759ABDAB
+:106BB000EA2D8E5AAFB5763B1F678D8DFC5B463C48
+:106BC000777EB3CDE4EF5AB8D15C5FC066A6A35C14
+:106BD0005AB0C1C6F07CC76D167FD8BFE17C615E3C
+:106BE0000B59DD2AD4D38DFCA0B93EA662FEF7E294
+:106BF0005F3D528A7943CD769EAFF301D08B16C5A7
+:106C00005755EE901DEDF97776155F3F9EE1F7A1A0
+:106C10005583509E26B3B8E78C6E5D6386AF3FF810
+:106C2000ADF032D640F0F60687BA558AEBBF7AD47B
+:106C30002E99E244CB9CDE910CE4CC39172F7BFCDF
+:106C4000297F74917CDF27E80836C0CBB89CAFBBA6
+:106C50001CCBFEBE3BD8CB778B9D1D76E48F5AB5FF
+:106C6000AE5C92237126872DA00F86EF6C7B268663
+:106C7000073353BB35E7D9AE4DCA39AF76E5721F3E
+:106C8000FD750A79F9C2B69FD9D1BF78FAA913D791
+:106C9000201F2EFAB5C29CD0AE739B8785715F50C2
+:106CA0004376942755BB94B871598AFCC3FC17FDF1
+:106CB000C24372A26A8723341DBEAFFAE53B231993
+:106CC000E0A1B3A1FBF060DC479F92787C34D8311F
+:106CD00012F7AD2A95DD122F4FEC84A0BB53CF25C0
+:106CE000CEC27595B6EEBF99FA6DB9C1E688920F1E
+:106CF000C7C4BE04EDB87FED4929941F477E18F143
+:106D0000AC534F4A1CBE3DB6900BE1DBBAD91E0016
+:106D1000386AB77E487454F68BED5EC443ED1EC5E9
+:106D2000E4F7ADDDAA841D23A93C8125C65124E0EA
+:106D3000EB1AC6E563CDAEC5E40FAF6959F7A1E222
+:106D4000C5EFCDF40C78F18711AF6F28FEE958DF5D
+:106D5000F973AF06A8FAA0FD712FE215FA9D634FF3
+:106D6000C278AED98F8DFD7F9A12DB1F63DD76A4CA
+:106D7000AFDA96B57C3C0BBF7C80BF64C6C64F9C27
+:106D80000E4B1C6B6BEA79E9898BB69F7D3408E367
+:106D90009DDAF1D74783B87FFFBF8F1EBD13F59AE9
+:106DA0007D2E1FF27BED53AF7959D43E98E3E07C02
+:106DB000D7F9E4CF9F7818F8A4F3B8838EEE75EE78
+:106DC0007D6F8806F3ED7CF6BFD335687FC7DEABF9
+:106DD000C8EEBF6377D9C0BEF643A4D350F43917C9
+:106DE00091C7A4ED9150D902435E94967539B84B82
+:106DF000612E80F3F4314708F39A6BE1D9B2225C3B
+:106E0000A7C5247FB1BE1CF05BB36DF587CAC878F7
+:106E1000780E0E9631C79E01BB64E03A5FFBED6FC2
+:106E2000946069A338492DEB26F969FDAEF628ACCC
+:106E3000E765BDAFDF59F6B91D8378B5DBD6F271D2
+:106E40002DEB771A7F191BBB7EBA65FDCEB2EA9F88
+:106E50003E8C2F77A5C68DE71AF1AFC5BBFFA54FB6
+:106E6000BDC99003FDE1B752E270791C7A8503F940
+:106E700069C7D34F3C9CC6D7773A20A473FBD9216E
+:106E80000CE8E3A4ADFB66948FDD7B1D3EDCCFAB4D
+:106E9000F6BE41FCD5B9FB15BB46F291B925D0131E
+:106EA0003A59CF4F3BEA0D3512AFD46EF1841DDE57
+:106EB000C83AD58466946B5E7A7E829E8738DDD729
+:106EC00084F65F27C559B7D58E1C2E8F433C696F5A
+:106ED000F1963FD899DBBC9ED2185CC71353F0796A
+:106EE0006FEB68CCDF87F3BF3C6A3DB7707EED8DFA
+:106EF0002F3B373B54CC4730D6B7D3C6F5FDDA909D
+:106F0000F4068BC3AFC6FE76A1F1D00687251E2AF4
+:106F1000E6DB1F3FF73F8F0BC3D3124CAA1C1D8B20
+:106F2000AF539FC797EF8F382401475DF9A0DCD896
+:106F3000FD496515C1C1D911784F8973B3A79E5218
+:106F4000424178BEAAE520C969AB5CA8E9454F7EFD
+:106F5000C6186FCFFE9128BF4E1D788EE8B066DB55
+:106F6000093BDA4787B7EEB4771446E81EE57F742D
+:106F70005EE4A967F68F24398DFDC7599F5F0B79B1
+:106F800057DB6AEEBF76DB87A6FE17055BECE417DE
+:106F9000ED679C0F54FD069CEF07ED368679F71FD1
+:106FA000B428E5F1F49B90C366CA835AE5293D866F
+:106FB0007E4525C5AEA1BC6B5AA1BF11A4738F3607
+:106FC0007EEE51D58F39802F1B93ED1ADAAB4D9E93
+:106FD000EB991625B79B2DF8F4A5F926625CCD3701
+:106FE000B9A224DA7E32E04FD66513FC7778CA075F
+:106FF000E27909B4C3344C3250FDE45756BC53CA4D
+:10700000713E8A4FF6B9E2EECFBC3FF4B721FDDB0B
+:107010007C32D3A2E86B54D9F5C3D1D5A632CD9436
+:10702000BF7AEF641EC735E67FEF456C1303B97B6B
+:10703000AFD4DD86F9ECC1AB795E201376BA17EDDB
+:10704000F4EC587D8EE9BA86F287C40F6FCF7423B3
+:107050007F147EBE0FE0C898BF23FB4999FFBEA2F4
+:10706000533E8F1DC7CD45FB2944CF135998EA8A5B
+:1070700093CB1F0FABA3E749ACA319CF30BDEDA84D
+:10708000F8D401CFEF2B4F9138DC61CAD74816E313
+:10709000C88959997DF13F9BAC9E8AF6FB38D8266A
+:1070A000B24BD0EDF8456A040F463E9CD1EFBDAE21
+:1070B0000912EE3738BFC178AE479C9FF7F5CC5721
+:1070C000A7FA00A36E19075BFA4AC5164BAC1890D5
+:1070D00054056F0D68263FC720D64265166BA73250
+:1070E000C5E9935482EF2DF24BC9ECCFEC8B440BE6
+:1070F0007CE7A18F9F93F5E301281B6DE2F9DB9EEE
+:10710000D0E350DF90CC4CE783739D9CBF2F77CAB0
+:10711000865F26106D7735B26A9ABB2B8D1F63315F
+:10712000BEBBDE1918EE8CA227C5DDCEF3BE84FDF2
+:107130006BD8EB5729CB29FEBE3A83DBD5BDADCF4B
+:10714000CAFA0A935D6D2D9B0738E76C66043FF71A
+:1071500053494E7E7E59679A2F9AFE605C67697428
+:107160003EA3AE937D2FDEDB607AF8D28178546245
+:10717000E96F06D2DF68A4BF0ED14937F9296E57EF
+:107180000257E37C33F2EA24FE3C2071BF97AEE065
+:107190007CD345FF72627566A08F79B259401F514A
+:1071A000792D1B84FDA8AA4C4D284278368975B7E5
+:1071B000D2A5393FD5D0D7DCA2E6107972BF2979A4
+:1071C00095CEA3A8696ECA4F719734DD8EE77C55C2
+:1071D00056E743F9E936F24FFC3C9FD0B08B5D0592
+:1071E000E63C4E87256FD526ECEF983C6EB1EFDE7E
+:1071F000830FE2E8C3D67DF77667FC3C2436267E13
+:10720000BEA0A1879D2FDD5BEDC86A67FB611ADC1C
+:10721000A7539EA52AFC0D13AFF3911FBC6B9BC413
+:10722000CFAD59E8A86B47D2489487C8BF78CF45FF
+:10723000A2782E6DDBBF1FF5A6262FD3935348CE21
+:10724000694A2E9E971AE594A05CBCEBC3977F8D8C
+:10725000FEF55685E1D6DCE536E2937A322E5622EB
+:107260005B6F5ADF0B9D4F6C5C91F3DB129FC16F1C
+:107270006EFAFECC3689CE4F296CF88FF1FC436D47
+:107280009B8D85E0FD19C6FB3FB389EB030B5F8443
+:1072900051F03CA8181FF7A5E8FD23B53C8169D142
+:1072A000793C41BD1DCFFFCF13F8185091627AFF92
+:1072B000D7B9E56DE49F09F07B0006CE1A64EA6F4A
+:1072C00091B27C2825E1093F8606FF90FE8CF99F4C
+:1072D000930376BE4F542485499F01FB17ED86909A
+:1072E00044F94A567F47CD1E89F6A7DB607FC2F37B
+:1072F00038B7852CF6A3258FCEC0B7952E0F3985CC
+:107300007DE066EE5EF0EA0F97507C94F86AC98BD8
+:107310003C2F6CC976294479CC1D439318E159213F
+:10732000BFD17BACEE41D83922F46BC19B23C38C17
+:10733000679766C673628119AF1EBF198F563C27C7
+:107340008DC931B55FA454DB89C8049E0BE01FE2F0
+:1073500019E420CDA306E611D662F159D97AEF2AB5
+:10736000F46FF48B470BFE4E59F07796B5EEE76F4E
+:107370005985339D589BE69DA986897FACFC66E0C4
+:1073800029CBD73E919EF93DE42FCE109D48F3F8CE
+:1073900077839C2D9C798AFCC46F467E7062CF7E79
+:1073A000F90EFB02CAA5330E9D98CB62F96B1396BA
+:1073B000C0D72DF54EDFBC7C8C4F33DF3C1BC6ABFA
+:1073C0007D54C6D947A97FA047DA0FEEC1B8641A29
+:1073D000F2B54AF12B5CAAE9504F6CB5F9D06F7940
+:1073E0004F51F735A8B7D7CEE7798E372770FFEB27
+:1073F0009204BEBFDA12785EF35D1532D3D1BE6F50
+:10740000554212FA8B7CFA8B57A2DED56AD3685F9D
+:10741000F375BFFC1D7A5FECC3F86EA6DC3C0AE195
+:1074200080F6E46FEF6A7DC77B6B94BED3B9E7FE4D
+:1074300061B8EF3C24B3CA787A7CBE8BC3D159F0D3
+:10744000E77424C7C5CE6EB2A35777D455E0BC0C01
+:107450003BC2BE8BFBB76AF6CC207DF2D0027E1E0B
+:1074600073F7297E1E738A32FB9B23A03EF6359567
+:10747000CB4DA64F9F93CE5328701D3760BE24F28C
+:10748000C17FC9A106C24FF3EF314ED5F81795A1C0
+:10749000FE5852B780F69F5F7BA7B46159AAB71414
+:1074A000235F4F6E4D9E88E7646ADFE27995A3DB28
+:1074B000CDFE1CA6541F443FD8D9637C5BBEFC980C
+:1074C0006AB5BB14DC8FC776989F8FEF876ECB5C55
+:1074D000623FF2B2F40BC98BFD91AC4F73917F9474
+:1074E0009FE3F2ABF1EDA74713B87D037891504EBF
+:1074F0007575337F03E0A96BDE209A6FD7C7FC6AEE
+:10750000A6AECF95F278F6D12D2E4E2F0FD979DC7D
+:10751000F6A105EED00A98C781055517A35DF4C9F9
+:10752000BF052E8E17A788D8072C49A63D4F4F625E
+:1075300063902F9AF8F932D69C19EFFCBCC10F0664
+:107540007F187C91B9202110CF7FF98E8BCF6FD21D
+:107550008202CA83EDDC27518CA7B301E0EA038FD6
+:1075600041D63018E1A9DDF311F9179CADF1FDD03A
+:10757000F5784803E9B621B8623CE0EB7BC0D44122
+:10758000E4077B7376BCFE836C03F99B16B834E288
+:10759000B74E27B7A399DA9C39D3837C5276F52A64
+:1075A00080F361E03F24F9876C7E823BB89831F22A
+:1075B000AFAA9CFFB3AE619BEF8AB2B7D6BA263EA4
+:1075C000E082FE1E70F178476AC02F21DCFEBF9F6B
+:1075D000F362FF5D9F3A68FD06093F8FF15D8BC046
+:1075E0004F5982FE23FC9E55A69130F407BCBE790C
+:1075F000B0FF5FB607F01D27BFCBD077520220FB4C
+:10760000009E14B74CE756D0DE427BA296193F414C
+:10761000523E0DFEC34366783ECB90B752AB14F694
+:1076200080DC2C71BAC3E84F49A98479633C8A395C
+:10763000797FED667D14252FCA5D94013C599EDB50
+:107640003B861C36E477533297834DF7AAA146094F
+:10765000D3DF3B5CE83FCED6B549985A95A26A94F1
+:10766000E7705125F3075148E63E92DCA3F78C679B
+:10767000ECD9BF2B71FD1B275DDC1E294B08FC0AD2
+:10768000F135B2ADFB00AA4F7E174BC5F59E22F433
+:107690009BB1A7B93C32F2FA6B85BD619547CF012A
+:1076A0009DA3C018FB0DBEEF8D3DEDF623FDF4C884
+:1076B000A10553681F2D6A2D3E88F939456F717EEB
+:1076C0006442FE80F54678296D0B2A880FABDCE911
+:1076D0004FDE18F2C4BACEA05CF7D4B30029C56D52
+:1076E000C06751FBB7554E1D7389FD55C8A9B36CD2
+:1076F000C2C0ABB4083D152DF31F7444D18F21A730
+:1077000022F414223AB48E2331674FDD978BF2E5D1
+:1077100088827E90AE893C3EB942F051F2C7A1AB5F
+:1077200071FE1B5AA7BA90EE77B4953991AD966465
+:10773000F0735EEAFEEB824C904F745CD7C69C1AE5
+:107740009E291F0F2B8FF8507C508F9AD79966492E
+:107750009C73D492AE8B733F82512EC9E0E7B8760A
+:10776000B4E524713B334CEBDE43F7C20F61F08587
+:1077700041EF56FA36F8A19171BF84A13F28528B90
+:10778000B00BCD7E8146C3CF1174519CF80EA10F72
+:1077900036BA2F5937017E6D0A4FF2615CE20E4F07
+:1077A0000EE533DF3180E3CD8A07A3ACFD14F4C3CB
+:1077B000A8BCF35AB59BFC5AB59FDA4DCF0DBCF669
+:1077C000860F03AFE310AFD297C7EBA7B8BEA36392
+:1077D000F1FB65E79DB5644CDCF372FF57E63D9E17
+:1077E000057EDD4176173FB761D097212F4A976E0E
+:1077F000CC24E26837DFEB65C891317BEA0EA28AC0
+:1078000068951397B5B26B114F63C32AC3A32EFDBE
+:10781000C98D8FF1974C3A7F716302F0DFA817662C
+:107820002DDA068F466A2C753A0035B25D2539C6C9
+:10783000DACF2F0ED512FE381DFD8B865E1A8357C8
+:10784000A1971AFB8B11075A9710A8C4F1A53DC048
+:10785000375ECC3FE5F6EE5A57605102B44F0498BC
+:107860001330D7AE209CCDED53335FF6C687891613
+:107870003E6B01BCD03904D8E7F2A558388CF1F33F
+:107880001292399C406DA8BF6495323E580DBFCF0F
+:107890002E6B240BE03E8CC736719E6B85FE759770
+:1078A000A55CEBAA68C079D9541674147D79B80D1B
+:1078B000BFE0BA043D88F87096EB348FC13EE647CE
+:1078C000BD7EB0DA22F9018E946A4DEA71D618FBBA
+:1078D000379EFB99AE4D44BA189CC7E83CEC60D487
+:1078E00083E2ACCFA6041EAF5DECEC388C21F3DA5A
+:1078F000E975E5DE3EE2D3917B06FCC24F65CEC35F
+:10790000E8DAFBC64518977CFBDF3FF260DCE94F05
+:107910006AB707E13CB9FCF71EBCBFE5EDE5DCCE7C
+:10792000B8D9A2CFEC14F84B4EAC780AF1774BFDE6
+:10793000DF4BA3F99D2DE37194DB420A1A9D3DF4C0
+:10794000BD686B22F9E68CFAE2965453DDA0D3C5EC
+:107950000E9E27659DFFFBC28EBA6DDB66FB600D38
+:10796000C70FB422BE4F0A7DEDE42E0FF9330C7819
+:10797000E66E1B65473CFCA9D521E2F0ED368E7F13
+:107980007D3AC6CF026229AC701EDE9748FDCD7FDE
+:107990004021FD620E8CB50CE83BD07A1BD9D9D6BC
+:1079A00079CC7F5B9B3210D66FFE5A89F4526CBF44
+:1079B0001CE821B06C35C5D9ACF39C13B4C6339721
+:1079C000939D6ECDF398C7B47513B2E3E47BB4F224
+:1079D00038F9C27EEC9A3F26087DA1945D8EF9E8C5
+:1079E0006759E18F0AB5FEED9A93F58C92B43EA8E3
+:1079F000775279AADE47E553091A8F67EFD97F9846
+:107A0000E84B6D2F457EDFD1F64EE24D5A446E5F56
+:107A1000B1F9A3833F817A31E3FE1BC33F3E5BE0B4
+:107A2000FB4A21BF170A7DA0F8D3BEE5F76C9CEF97
+:107A3000C858780DB93D1BEF958DC28321C7ADF8AD
+:107A400038D3969B887421255AE3C05F0D2FBD7DE6
+:107A5000B758899F3768F0CF53C21F306FCB8C5512
+:107A60008360FCC6BDEF0DE1F702B3A3281F0CFA3B
+:107A7000B4D21F637576E4E71E3A6BBD9BF063D00A
+:107A800005F05186883F66A0DD67A5B7FEF2893A0A
+:107A90006D1D43500E58E9AB536271EF154D4DE427
+:107AA000FEF2799A3E05ED50D85E56F1381D973FAB
+:107AB00027D5E6C377227F6EE1FCB1F857DB7F89DB
+:107AC00072A7EA170F7851EEBCAF36A7E378D58FCF
+:107AD000AFF4629CFBA41AF4E2F7EF8794B87985BF
+:107AE0000B1325E10F37E72BB035C16B906F3F7952
+:107AF000DCE6433F43ED56078F83EFE278833A8F0E
+:107B00007FEF8A9FAF50F5F307D2359EC76ACE5BF1
+:107B1000D862A3FC13F497E130BDC5717BE2C22D9E
+:107B20007DC7B76B77AD8B9B7762E40758E9F606A4
+:107B30000BBD025EC88E09023CE4161771EBC62726
+:107B40007F3CF204C0756ACB6FBD5261B4DF9CC745
+:107B5000C7CFB4DCFA530CF1F446AF9D82BE237A52
+:107B600043286E1E43B52DEC453BBC7AB38DECBA71
+:107B7000EAED0A73623ECB7107EDDB8BB6FFE6F5EB
+:107B80007100DFA2676D69D3F934285FC158A79EE1
+:107B90003C12B12E553B7FC3E3BD9AC82711EBB30E
+:107BA000E8D9FD76CC8BB1E2B1AC65BFBDC3928F95
+:107BB00040EBD472620A9DCB7BF29C1DF7D3F7F7A2
+:107BC0004974BFB2F5FBCACDBFF1A27C403C515C09
+:107BD0005EAC57EFF942E16B9E2FA176E487EB6D27
+:107BE000FDC6E0DE3A9AE8FB99E761FCCA371D94CE
+:107BF000AF54F9CC52CAEF794FADE374FEC8CA74E2
+:107C0000DC5F2B6DC1741F95FC79E5A3DF25FA5B62
+:107C1000F8CA77D3F9791E3D93FB6D829938BFF985
+:107C20009BFE85E6B7800588FE2A1F512AD05F7229
+:107C30005665E5CFC6E1933F093E79EF310706511E
+:107C4000D97BC26F197C5511F7FE5AE349FCBE95EA
+:107C5000B3C28EDE95281BF71439A3EDAADA2DAB3B
+:107C6000DB717D3EB8481FE8A3B8BE1A14F89248ED
+:107C70001F7FE5AA81428ED13D31869E5386CFB1CA
+:107C80007DBB8DEE8B89FACE74DFCB1D627C803B91
+:107C900041BA0CCAF4F8FE4C8F5B32E0E3F92F06D0
+:107CA0007DF5C6F75B783EC9C747B95CC1BC187A99
+:107CB000DF6E0B0F34E5C3384CF78944F23D6C821C
+:107CC000AFCDEF014ECA57E9C1EF3E89E2AC0B36AA
+:107CD00038CC79703D7463BDE7C69CBFB2D0A26F4B
+:107CE00019A5552EBC69910B6CD3F9E5AF54DB4255
+:107CF0009477547DDC41F643F5765B05E2E3AFDB38
+:107D00000EBE7E13D0F95F5B0CBE35CB572BDF5612
+:107D1000EE18CDE2F1ED5FDD7E16976FE1795CBE86
+:107D20007547E2111AFBFAE4EBC25EE4ABE28ED1D6
+:107D30000792302FF783A7165D4C7E060B5E0DB9B8
+:107D40006A95978F246AFCFE8298BC3ABE9F47F2E0
+:107D50001D39FE0C7AAC7A7A318DD343B7065D1AA1
+:107D600074DB4B9E96158FD6F72FA23C1A10EBCFE3
+:107D7000084E620578AF5EA39D15A0FF392827F84D
+:107D80001FCF8E93D7C1EA86A29ED1E8CE8E9B9F4D
+:107D9000EB77FBD08CC573654ABC78B7BF4C8EAB14
+:107DA000C797B8B95CD98BB40065B59BE3AD49C43E
+:107DB00057C012A4BC7FF429123F257B899F6CF029
+:107DC0009CD1B94A3F9DDBF627CA1F69A08255B8EE
+:107DD000B5292AFA538BE5A5B9505FE82EE6F5F1EF
+:107DE000F2CE1CA8DFE62EE1F5CBE4621B90E61391
+:107DF0006CF494C950AF31E6392FC9E4DF50E51374
+:107E00000F62DC457D9EDF17B70EF8DA591489F74B
+:107E1000263A58D05584F7344209F555D9BF5F85C5
+:107E200046E00647E01A37C9A3491AE2F594CF495C
+:107E3000F932773C7715E56756BBB9DF78F8CEF1B4
+:107E400074FFEED730FECDEE01BD8FDF64E3FD9C05
+:107E5000DA31BC0CF13AFC62467E0803FF45AA46C3
+:107E6000CF5D2D78F494F83F03CF7F3426DBA99FB4
+:107E7000EA9EF53ABFB251E43528899C0E9424B9A4
+:107E8000EE5928978AF5BF43E0037FD05EEEDA3BD8
+:107E9000F0317EDF53F7105C5F4539F347D41BBBED
+:107EA000FF35D18FE757DE4CE0F8BA2169BDED52BE
+:107EB000A81739872C45A27E53DAF65D2CBFED0951
+:107EC000FC90E39F85B1BF9B6E56787FEE3A0FDE44
+:107ED0009F26E95C8F96806866031E1A75A6D97383
+:107EE0009145CDF9168A52D41DA6713DA671591639
+:107EF000EC83B04E378CE5EB0438A57DF18D31BCB9
+:107F00003E2B94D3D8A1111CF7201CA31CA18BD00D
+:107F1000FEB909D4224ED766FBDB88D3D7FE4526AF
+:107F20003BB356D21ADD50DFF91623B9DC99E015C0
+:107F3000F907FCDE19C32F31F6A5B965B864257BB6
+:107F400016F13C0EE18732E2E86759AB829389F182
+:107F5000535BE4E178B69EE4647FF1B19FBB457C5E
+:107F60006C101B7481F1B167DCE7111FBBC86DE8B1
+:107F7000F322DE2EF6FF334772285F485531278FF4
+:107F800031BBA6508A88F1DD2E8BFC35E878C451D0
+:107F9000DFAD88971147D92DDC5EEA253FE224A3A7
+:107FA000BCE6511D05941F61B3E6471C9329E1A966
+:107FB000F4C5620DF1D924E2C6171AB737E2FEC53F
+:107FC000FC514C1CFF796F39C5418B7DF1E3F8E31F
+:107FD00094D914776047F8FA19717CA6142A08E737
+:107FE000D930D86008E751F3DF01B93C2DA8505AC9
+:107FF000CD5BE6E7E32C74605DEFBF58D7FB7CF305
+:1080000020DEE7F7AA8D6223290FC226F2207EC95F
+:1080100002F747E7411878EC2FCFC49A5762CD2377
+:10802000C90C98F134B8F252D3FB8BEA8A4CF58B29
+:10803000978D33B5CF868D30BA9EBB669AA97D7E6B
+:10804000F34C537DE8C69B4CED8785E69ADE0FDF47
+:108050005AD5E7BA8F6859627AAFC8A162BC0FD20D
+:1080600058F7CBF6FC202E5D18EB6EE46961BA116F
+:10807000E27734ACFBC3D9E43F2A93B4D8F5F78751
+:1080800083B42F5FE8FAE77B843E7481FC3E0A8963
+:108090000DE3443AD713BB6CEE35A81727036C28C1
+:1080A0006FADFA4572EB0BFF2D79E3E55B682B9022
+:1080B0008EBEAFE86371BF1F20F2239B64719E7474
+:1080C0009293F4817B64F996E87BE4AFF0703972A7
+:1080D0008587FB557E02FB26EE9383135990F64F5E
+:1080E00071BE9CA1430AE6EB4D65E2FCF963AB2649
+:1080F0004FC078664781968C2205EADF88C8FD9BD1
+:108100001C5A23C60346295C8E837C9FE6198DFB8F
+:10811000CE721BD77F8236C4F360270B7A8B68DF61
+:10812000A3B866324B939614A2E9D5B3BF685F003B
+:10813000311CAC1A9E8476D0CB383406699D09B4C4
+:10814000FFDF68C8BDCA6124F7CEB87BEEB5A0F3E7
+:108150008E67E6E5D2F3E33703D701FF1CB79BED4B
+:10816000A2FEFC53959BEFF7A0FFFF780133E519C2
+:10817000547BB81D55ED5178BC3CF49774444BD7F3
+:10818000FCCF2E41A06BA5F65528A2576FBCBD822F
+:10819000F27677CD08A2FFCFF03B1BFDD4B64E643C
+:1081A0003DF707433F37BCC1FD5F377C66F6E7DE2E
+:1081B000E9E179D7778AF1AE87C20778BB1EEFF481
+:1081C000C6F2850953901FE0795882FAB7DB40F573
+:1081D00003BA9F11C8B6213CBF67FED7764B98AF54
+:1081E000ADD1F7D7B10A1BC2F5FACD8B3DD8AEA7FA
+:1081F0003FA39FC178A613F6E9E4A02D1DE8A7FBD5
+:108200001B12EDEB309E139F57CC1EBC12B70E63B2
+:10821000BCD759E0F46BB0DE33999FFA35FA672C7E
+:10822000C1240777542EFA536A0ECA3F99FC1F4B9C
+:10823000F63A48FE75559DDBFE20BCBF6570C7450C
+:10824000A85FBC59F5D92588971B372A4C83F50FB1
+:108250002504EEF344E1EDF8BC8F3CF81EF484C72E
+:108260001FC44DFE69079DF37AB3EAE94BA2F5EA14
+:108270004D9E893FF6E03E39E6FCE23D654F0D2319
+:108280007BDBA0AFDB047D2D797228E9834B3CE6D4
+:108290007B53963C9E4BE7894A2516D78EC47B3F7D
+:1082A000302F7D07D0159E23DCF729CF1FDF7924DF
+:1082B000A598CEA3B2C07684CF68BFF3E59B865362
+:1082C0005EE7B1B4F3BB1719E00BA27EC5389C2F53
+:1082D00009FE98D59A5A2CF4BBE7106F37FDFAC9FE
+:1082E000D37F40FCEC7DFAF13BB14DC9F9E18389C4
+:1082F0007DCC2FF000FB18D93F5D2CC1EF8863FFC8
+:108300003C2BF4AFEFCB3AD925E7E40A91BFCEED91
+:108310001045F667601E774BAB928878F3A2C16276
+:10832000C817D009BD78FFA2B83FDD09F6D9702182
+:108330007FDA3D1F4F69E27108935E5772A8CAA4A5
+:10834000CF55C03F94F7976F0A34E23D8DBDEA7573
+:108350006199ECE12FABDFBDF325E57DA787F37FC6
+:108360004B0197DF2DE18410B71B5831EA7BCFE03A
+:108370005CE0FDB464BE2FD8A5CE0227FC7EC6F318
+:10838000C9AA3559B0DC791C1F58C7BFD3C3DA3826
+:108390009DF6E87F872EE57F674E9C032E11E7A2AE
+:1083A00063EC49E02BBEC92698F4C7F0E1BFD13990
+:1083B00097ED29DAEFC6A33E0F7A0AF2BD4BEDB076
+:1083C00027C799DF2F517E027D8FF572FBC4B987D5
+:1083D000C7E19C9A4EF79EB97CBE51682F19ED4FAC
+:1083E00089FD66F1E13787D8619D4ECB47BC1847C0
+:1083F000A8DEBDC38B66F2658981242FC64B8EBF74
+:108400005AEAA37CABCD43D0AE6D09F3F8C408950E
+:1084100005D538F735D76E2CA64BBF6B36A652392B
+:108420000CFD09F0A836CCE7D9B9A731259EBD5D72
+:10843000FB1F7B07E1BA3D3D809F971AD15ABC10C4
+:10844000E51FC2620339F7D4A7C3A9BF4BBCD93417
+:108450003F185FC5E7209164BCEFE86961AF757EA6
+:10846000AA503BA3DF117B262A3E58CBC270F301F2
+:10847000B20F5B1D1AAEB36B0BBF0FCED5EA22B99C
+:1084800057BB6F2AB7E39279DC737B42F71FC5397C
+:1084900036FABB042E5F334B81FEB7DBF9FE380C96
+:1084A0001860873BF2DC18CFD5FA634A6A77E6F1A9
+:1084B0007BF55C6A33FB863B1AEF1EC2FB542FA789
+:1084C000ABED096119F376BA81261F23B822703209
+:1084D0001AD7807318E9F3DBEDDDEFE2F94B3A5F71
+:1084E000A7211C1C4ED63A5443BDC2E5E3F15B976D
+:1084F0004FF307A558B86A47829E0BFC764F038B53
+:10850000FC7D04CC634B88D49DC013DB739890072B
+:10851000C3564FCE8AAE83401A13F97EF63DC35739
+:10852000374D203B27A8A05D0FA52705E7C9F737E2
+:10853000BCBF604011C703FA89139DFC7D4F7B27A8
+:10854000BFB24475F376FE245FE23489F5DC676AD6
+:10855000F89DEE90C2EF5E89FEADF081911AC05297
+:10856000FDC2F344B78BE4D6074768782E31B000DC
+:10857000E9F5576FC90CEF47FAE049179D432E788C
+:108580006E33F9ABADFDAD3ED6701FE665773D2786
+:10859000699807DA65EBA6B8514DEB7B745E71EA1A
+:1085A0009E13746E4B490AD47947635EC48A32C401
+:1085B000DF58D6DC88FE3D908714A76FC9E0F2E350
+:1085C000CCD14B1E5B1185EF07BDC2BFDB1DB818B8
+:1085D000F9A655F0E73ED46FA0DC2DF4ACDDFB6FBF
+:1085E000CC8D3E87156407C81FD6C00E517EA1F101
+:1085F000BC2BA4D239B0E1AF3B6FD1A3E8AD59F0A9
+:108600007BB3182F3F29B08AF876FF9FED5E0DF3FC
+:10861000585B86A0DC6D013DACAF7CC65A0BDFF425
+:10862000E4B79CE4F771C3BA3625C13A3DFDFA9E22
+:108630004BF1EF8B00FC8CEEAB3AEE20B9B93B9BD3
+:10864000F3DF8AD73E198972EB93BD8B2E467C2DC2
+:10865000F3DA0C3A9F9480FCF42C233966F0632102
+:10866000F2A384F742713F4A21D239F29FBD7D1AAD
+:10867000F1DF6E7E2F04D039D13DD0B90FF58B429A
+:108680001FD03D7D3F94F8797BBBCCCF81831CCF3D
+:10869000A7FA24CA57D9DE3ED947FC2C036A8B902F
+:1086A0002FC307A89F16FADB75ACC4729FEB294C49
+:1086B000D21810918F7FF3703E6D29D092FC309FBD
+:1086C000444531F141D43EC9EB621F957F74D3EA32
+:1086D0000DF8F7C3DAC5BE20F4AE7D42CF65C7B84A
+:1086E000BC5F2AF6B225BF19F7ED6D30DF252F29C3
+:1086F0005CFE0B3A3920F4E043F51954C7FD428380
+:10870000751A0D25DE0754AAD7E19F2F6163CA9B16
+:108710000F6239AEA2A50C8F4C4D98D57E909F610B
+:10872000D38723FDED3A70F570CADF3DEE6098A265
+:10873000B8EB6FDD7F7C0AF351F701FEE3EC4BE809
+:108740009F6514BFA9207AEC8D6EBAA48E6BC6FB10
+:10875000410FBCA77AAA0A1B7D0D1206E0E3F57B48
+:10876000AA56E3BD803725E9C7911E97FB02C79142
+:108770008FBA5EF95B3ACAF4DD47FFEC4579BFCBAF
+:10878000AE0F473ADB9503F6401CFA3C2CE8A7A451
+:1087900097BC8ACFBCDC5EBA24C8D621FDD4EC528B
+:1087A000E8EF169CDEA5E8780EFB5D3D908E7ACE54
+:1087B0004916BC7E3CEEEFC2AE9DCFD1CEE6A3DE25
+:1087C0003292EECB30D9994C592ED33DEFAD12F900
+:1087D000272A2D7A48356B5E3518F78DD6CD769CD5
+:1087E00047D516F3F7D5A8BF8CC4B26F7BF533AF6E
+:1087F000D05F72592EEA2F403FE49FE87E4DF13F53
+:10880000C628BFA70DF37B9E96397E405E121F1AC5
+:108810007ACC569F7E1AF5CAD3824EB70B7BB47BB7
+:10882000BB44F9FDC3B6F2BCEB7127B5CD8CCF9F2D
+:10883000F2C22A851C1CA7F2F8C5B8A3B9140F1DF3
+:10884000A333F2872C68954288C74A43AF13E729C0
+:1088500060DB25BD6E2C0B35E2FD720BB74A740E42
+:1088600063D156B3FFBE7AE32B87D13C5CDC62391F
+:108870001F2FF0628D6FECC05FE2C4372E4E12FEE8
+:108880009C216C88E9BC55DBF99DB7FAAB387FFDBC
+:10889000AAE8DF68372189D34D8D986F754809891B
+:1088A000BF4FE9C6FCDB5B057DDC2AE8A39685EDBE
+:1088B00098BFBF78039F2F5B6F33DD5BBC60D7ED44
+:1088C000741EC14A4795DB78DC0D1048F19DCA4DF6
+:1088D000E6F755021F55167CD404240B5C5CDF8E32
+:1088E00085ABE57A5CDFC5DB6CF4F739AC709D6570
+:1088F000B3298FE81F0D9F759DAE33D6E95276A937
+:10890000699DCAFBBE9F2062DF98F5DF670F5F4A53
+:10891000F92E67DA72C87F60D087B59F29427F9EA3
+:10892000BA91EB99A7F794258E40BBE888EA97A007
+:108930009FE2973EF6E2798FA2BD0AC3B860576BFB
+:10894000F13A3CA7BDB32DEF5ABC8FA2E82595F6AE
+:108950008DE2978AE85E90A2978A1273298F424B24
+:10896000457C403FB4EF761DC9FB7D21CACFB6C917
+:108970002588E615478A12513FD8C9B83F427AA9DF
+:1089800024B5236A1F599CC4FD03AB32DEB907F539
+:10899000F7A9CFDAE8BCC9545BF7CB987FB0B34DE9
+:1089A000F5AF807AF54B731BF09E8AEA27253FAA24
+:1089B000D987DB97A47D07E9ACD5E67310BCDF3D12
+:1089C00080EF83DB247F3EB4AFDD7BD5F0ED98E70D
+:1089D000BDB9D81F7D2EBB2859BB1FF32A5966226B
+:1089E000D9DF532FB2D17E7A6A50E2CFE83E167DAE
+:1089F000F31494B3A79EDF69A77383DB2596011355
+:108A0000399C71F019BADFE397AF50BE42D9AE5727
+:108A1000283FA137797F3AA4B030D9DDCD742FCC6F
+:108A2000E2CD46BD83CE415408BDA966CB09AA5705
+:108A3000A1FE0FE3556D52421AFC7A70EFAF28BFCA
+:108A4000A1661BCF6F80F7247FAA307EAA45E87C01
+:108A50002EE3743057C89F458CDF33B4A8999FA389
+:108A600033EE4532E87CFEB639948716936F86F66E
+:108A700025C5219A89BE63EF1BE2F46DBD77C84A14
+:108A8000DF2D067D0F63C390BE3F99C8F3C33E79C7
+:108A90002521B110E6F3C98B0AE5DDF741E7B49F64
+:108AA0001E11FBFF99B04CFB93D1AE73CF47B48F2F
+:108AB000D41E3963477D754AEB87B40ED35BF74FFD
+:108AC000463C7F8B05AA116FDF6A4DF4219F4FEF63
+:108AD000E0726B5AAB23847EEA6FB196265CDFAE00
+:108AE0007D3F6F4A417A7982D38B21CF160A7C2E43
+:108AF00014F85CA8F2FB9EAA0AF73F88F9D0D318B5
+:108B00009737D35A84BCD964C66F97AD4525BA1937
+:108B100021B1E6ECD8FD6E11EBA0738F5D99C3E92E
+:108B2000EF4906C15E453DAC7A9B350ECEEDFA1A93
+:108B3000CB7E7A30C9F6A5EEC178C7B22ED3BBF989
+:108B40007E360DE809E3216DE18642947B067EAC1A
+:108B5000EBD2A6E526F575DEF965A1B71BF56F8B9F
+:108B60007B265A7CCDEE683BBCDCC7F5F0AAB14A47
+:108B700010D7B5C75EC93B38529323F60AD8299F50
+:108B8000250DE076CB28E8FA852C85A5A545EC9542
+:108B9000D519F74F2F4AC3FB23B8BCE81C03FD616E
+:108BA000BE80CA484ED56E7384D0CEF81F85B75AA2
+:108BB0003D008000000000001F8B08000000000046
+:108BC000000B8D576D6C53E7153EF7C31F8913FBE0
+:108BD0009A78662C34BB31F9202584DB109A40D773
+:108BE000F626A51D83141C58296AABE2B65BD90A88
+:108BF0004E5085281295B889A9D6956942DA7E54D7
+:108C0000EA56DD226D621BAB4C096A9892C8A1A19D
+:108C100025E990A0401BD0D659FC60EB9490C0345D
+:108C2000D24D95D873DE7B8D1D12B43A528EDFAFD4
+:108C3000F39EF39CE77DDED75D7DFFF29AF544DF7E
+:108C4000EDBFEECDC2C6FBA54709B63A94F069DF89
+:108C500020EA20F2449A60FB242343B0ABAF7B139D
+:108C6000254423558B4209CCBBA1EAF335B46FF1FF
+:108C7000E7E1BCEDFA52212A23EA84D5CBF2FD9D2F
+:108C80006AD6CBF33BFB25D386ED3DF99F8ACA52CA
+:108C9000A2C981E98AE760576832FE71FFF796A89A
+:108CA000D877EA928F6295D8D8322FD0FD442F9290
+:108CB000F3D9A611ED9987F6F04BEDD4800E697FBC
+:108CC00039B5C0AF878C0CD6755E540C4B47FF0985
+:108CD0000F513351F7277F1A9E1721BAF6AE64F869
+:108CE0007467FDAB8D683F6FEF9F87F9377F27195A
+:108CF00016A6BFF84DA287D0BFED4DCF95ACDFD9FA
+:108D0000EB96F89FBEB217F39247FCFA1B687553B7
+:108D10004F39616E0FED1736493FBBAE04E1AF2FFF
+:108D2000E5655CC82E581F23DA7E78A6BF24A9F912
+:108D300036F2DBF397D68EE182F1355A69E46A00A8
+:108D40005FEAA8EE96C2F1171F90B0FFE488A2F97F
+:108D50002481DBDBDF2AC4E734C058C0FD4526216F
+:108D6000CFC973257611E6FD731FC66A89C6F7C1A0
+:108D7000B90F7E5A148187BCD2B14B06DF8F713D8B
+:108D800019FFC452A23F0CBE7F2FF30109883A6C31
+:108D90003F8C798B0BE24E23A88238119791C17ECC
+:108DA0005D9F2A06DC735C35DE483EAEE36A3668BA
+:108DB00014F0637A9FD9315C8D72492745BD64698F
+:108DC00058D8DBBC39A1C4EDFA7C1BF96C35B1FE77
+:108DD000299717A44E45E388F3590D45043FBBFB83
+:108DE0009DFACA038EC5FE9B8971419BF79F35DEB4
+:108DF00066EDE0F19B9501B218B72FAD766EEF8E60
+:108E000029F406DABB3F79A9960AF6278E13F5ED09
+:108E1000F24C4599B75DE764115FD7B91BD12AB40D
+:108E2000D7D23BAB35B4D7517A3F8F7F180BFC8834
+:108E3000796DF1BEF3F37EBE0829225EE27CE1CFBC
+:108E4000A25F3A7EDD7C7B68A3C0A1C7E5D50B217C
+:108E500059CC7F554BBCC2E770F2DC7FA3489B8E98
+:108E60005FB812E47AE5EA7DE7B9BB1D3776E0F535
+:108E7000375BF5F34F83078D23AA15429EC7C68A39
+:108E8000EC76C66560DBDFF672DD2EFB88CFC3EEC5
+:108E9000C16DB5C47E138965719CC39B833F5EC65B
+:108EA0003890D423E2B2383EC435D17731AAA33FFB
+:108EB000397031CAE3C9E32B7E6161FEF2338DEB79
+:108EC000B8FFD86955F0AFF14C93E0DFB13F37956B
+:108ED0002DE2C0C908B0DFE4881A677C92234D1FD9
+:108EE000B7635EF24C5B93C4DB9C692A63FD592E29
+:108EF000513C8D7169A44AB473F9FC5C73F09B1CFE
+:108F0000021FD02F51CCE10F55CDE0CF8EDE535E46
+:108F1000CE63479F6216F228B7EE90A60A3FBF6560
+:108F2000FE804FDD69C914FC38EAD81D7DC7447E38
+:108F3000DB3D6951EFEE231E67FC8F8E253A28D664
+:108F40005934CF623C3EE62ED461ADD75E480871FD
+:108F5000B492B6A4E7D0C39AB024D68D5E4A7C9B67
+:108F6000F932DA9AA8D5EA67CFB3A84DE443928BD9
+:108F700077AF678D3D87BF2AF6873C8265B4353E63
+:108F8000C77838ECF067AD971273C5F379EE3C11F2
+:108F90001D90C18BF3ED1E8DF94F64962C80CEAEE3
+:108FA000777576D3E31ED3BB0CE3A49D2AC2F8FAEF
+:108FB0009CDEB640CFA00B71FCB1BEC5DF8C873202
+:108FC00080B4C39CA9731B29EEA145F0B36666FF6C
+:108FD00013AC970D6C55E1E76E3AF829EBE0127C83
+:108FE000A9A11AD641524A021278F3EFD31E4D11AD
+:108FF000F1DA55AC0777E697D3990FA17F3AF4EFF2
+:1090000034F48F6D77DD670D59E0313A74E9DDB0E6
+:10901000D0CF228A3101BF8277E49DD4DCBDEFF04E
+:10902000D77DFB7C7E7F06DF72F5998064A7EB67B6
+:10903000D7E786E6D421E91FF782ACD4453B5F979A
+:109040009147BDE2F0CFE74998E5C8C3D3D79A2945
+:10905000673DAD838A22BF8947259B751E7156F8EF
+:109060000A747E628124C6776F966C0B5F87EA3E36
+:1090700013F7763273D6CB7CAAE97DEE35716E2D6F
+:10908000BA40D17C1D37F89DFBF276FD72F9F2A053
+:10909000CEF981CF428F23C2F27CBE1FD7BBF7E14E
+:1090A000869699F5ABA5B38F95238E274DC9B0E76A
+:1090B000AAFB96FB4EB1DC7DDDBA2F09272261E0C9
+:1090C0003179F6C6E6A5F0375AF7F70ABE473BEF07
+:1090D000C2DF0A97DF5D81600385A02EB57A2A0B77
+:1090E0003CDE2B4DDC13669D90BF0ADE4BBC3EFB85
+:1090F000F6CB12D78304DE773B2F55AEBFAAB0E67E
+:10910000E874849633AF7EAF69CEB9F5D80B590FAA
+:10911000A81E8F9995FF5F77BB4F7CD4C075B93679
+:1091200034D2E02DA8DFF8CB38F77C8F0C7C10D53B
+:109130004B0AF925BBFC528595A48DEEFD38936F43
+:10914000E3CC37AEF7D10FD63FCD3CE9DD1491F437
+:1091500082FBF3F8F9607581DF897E45CC27355BAA
+:10916000F34469619CAF893827D28E3FA26CCDA6AB
+:10917000A585E32997B759C1DB9F2CDE19E7739CBE
+:10918000E3AD4A0E6F3BFB3A48DC476EDE692FBE0B
+:10919000202E6BD067FF06E3939EA98A70C1B9F8B1
+:1091A000A18B737346127C5C4996C27E9BE1F119D8
+:1091B0006EAB9451611FA08CE8275A48CCE3FB5D4D
+:1091C0001E37AB9921A941CCB354F072159D15F30C
+:1091D0001EA229614D82C0C3B691216C8B3FB38E14
+:1091E000E5A33E9D56984F99A81ABE0A3EB294CC6C
+:1091F00055BF7CFE2A5DCDF11393F1B8D91A9F4378
+:10920000AF0FBAE7DCE0B71AD77982EC43E87A907F
+:10921000B20A6FF2804A6B14E4F3A04AFE62C47B88
+:10922000745816E77730ABDBAC5F4699BBEE0BACFE
+:1092300043BBD974CE295F35CF34E6F3BD138755D0
+:10924000F017E2792ABDEE113866C47E0F73E0C8CC
+:10925000BB957495DBA970A5C3679A7A96F779A434
+:10926000DF27DE39B2DF1278FC34ECD433003C83E4
+:10927000F0B3EAA04463D8D758E4E49BF3BF0AAF45
+:10928000BE5023CF77EE31B4690CFD01BFB38E68B9
+:10929000B5C6784999A87C2BF0F5719D8C92883BD6
+:1092A000F8C2D4B5BDE2DDE6D30E2124A3FFA3317D
+:1092B00009EF69C934690FC7E32FC9F0FB1AEC182D
+:1092C0002F7C57FF3AFCFC5B7CDE255D13785182D6
+:1092D000747E67CCA75F697C6FC83CAFCC81EF1F01
+:1092E000C0EF4957EF2E173BBA71D8DEA8CBA8C7FD
+:1092F0009688DFE07A34FA2B9613FC6E284D08BF6F
+:1093000097A523D5C2896AAF60BF399E07C86C6133
+:109310009C25B75E7BFC8EBFE922C7F299643E07AD
+:1093200020E77EC47500E7C28FB6D5E6D4DBFABC71
+:10933000C84E61BF69392EC8F88A62F805DF6389B3
+:10934000B16658B5CDD47796F0931D7904F279A41F
+:10935000781FDCC7F4033C1041865D9A934FAA4402
+:109360005ECCBF9752546CE07144BB4A1D9EEDFA2F
+:109370006B914D95B3E33BE94B9CE4FCA665636CB4
+:1093800054DCA33B9B59EF18A7EFE47092F3386DC0
+:10939000B163A9AC2E7019619DBECF67DF93C1BACE
+:1093A000A77C7635C79FC303051224D55C9C73F850
+:1093B000685C3FE6B189FAE5EA1FCBE374A0D8C147
+:1093C000073FDF1C1C74D471E9ECFCFF0753B7A7FF
+:1093D000EBB00E00000000000000000000000000E4
+:1093E0001F8B080000000000000BFBC6C7C0F0A3E5
+:1093F0001E81C3D1F8E878022F7E7952B10C038226
+:109400005DC1C5C010CBC1C01007C42780F82410AF
+:109410006B70323024027112102F00F21702712586
+:10942000101700D5363333301C6663603805C41717
+:1094300081F8061BE9F66B483030EC9241F0396454
+:109440001918D8E4A9EBC7513C78F15A0354FE5BD4
+:109450004D54FE576D06063D4304FF9D2669E627E1
+:1094600001F526033100FBB288BA68030000000052
+:1094700000000000000000001F8B0800000000003A
+:10948000000BED7D0B7854D5B9E8DA8FD9F39EEC5B
+:109490004942184248765E1030E01042048A9E49E4
+:1094A0000A8896D2889E165BAB4340823C035A4C96
+:1094B0008F78B2212104083050AC91224E10305ADE
+:1094C00068A3A2D216DB8094A2F5F4466BABB53E3E
+:1094D00002521E3E68EAA38EF7D4C359FFBFD6CE10
+:1094E000EC3D9909D89E7BEEFDBE7BD2AF2ED65EB9
+:1094F000EF7FFDEFF5AF358AE824F23F117211FEE0
+:10950000683A4C24840C8AA784C85A8F0352A25FFD
+:109510002CB4E4C945E972F27F1B61CDEBBCDF7F5F
+:1095200021248B90EFF032FA1782FC149E31E6630F
+:10953000A424A890AE92783F5308CB6BA2402E0A89
+:10954000F0D55A6E8C53EFF08D2169847CEA64A9C2
+:109550005E458BCA69FA9633DA984F88430817B28A
+:10956000F9D45D593D1AD3AB206D14C8EC4E4F921F
+:10957000799035848CA7C9FE2122A988CF3FB19E5E
+:1095800091363510D2658FE765998492F55B41E796
+:109590000FFD9E13C215381F0F91011E0A87878D7C
+:1095A0000409A1EB3AE29F169843E7DF3A5909DA3A
+:1095B000A160FB10684C7C061C67E761DEC1F39577
+:1095C00044E3F0EE6A29A4ED9C41916CA0B9A6FC9D
+:1095D0002A07292564F3C4BF06C2743E4E3942549B
+:1095E000483DC9E7379388BC9F7BC9E5AC3B713FD9
+:1095F00064D8A3F19815615DC67CB7D8E8BC32E9A0
+:109600007E8C17C95E9ADF543E2B0DE663ACCB917E
+:10961000629C6680EB0842363638306D9A302B8D6E
+:10962000403BD23B1BF677F3C42C718310AF7F64B1
+:10963000E271470F5D6F236FD7AA1D75407D639F51
+:1096400013E1B699C32744049CF7C6D1AED9D1D251
+:10965000FEF308111F966F76D246B00E2F89EECD1D
+:10966000871E7ADAE6D2BC6F825AB641EB8F2F534F
+:1096700046CBC12E3A4F8FC713B4D3724F80B57704
+:10968000BC2144356C1FF20CA1F55DC6FE4F10E302
+:10969000F0A4FFF7916A42283DFA727A5F8371EC79
+:1096A0006FD88321FADDFDD947AFCDA5FD92934256
+:1096B000702F8C4B965BF68BEC6170B5A9F4DFB420
+:1096C000DC3579FE0C5882FBF327AB016EEB8B5631
+:1096D000B856C35E95B0FD53E9FF2E16D0FE35C5D2
+:1096E00032BECDBCBFF9809AD6BCBB78D6D70AB5FE
+:1096F000D4F8E1EEF191AE0C5A59BA05F73B55BDDD
+:10970000FA37C65E73CC346E1BF1669E71D37F5CF4
+:1097100045AE423ABF44FB4F1B82D71CB3E1BA456A
+:1097200033BF49557F2DC78F3E3CCBA7F8518AFBED
+:1097300019B86174FCFB4B8017400F7A25F231A4F5
+:1097400045BADEE6AB49AF44F7A3A958D1D65038A5
+:10975000D855A54BF0B1317B01BFE01FB4A9BDA81E
+:10976000B95B180399EF58F860CBE07F0D760D30A8
+:10977000BFC47DF8A2F0EB02F85D11879F9D54A74E
+:1097800075C17E5707103E5E3E8F7557AFD4BAE85D
+:109790007AD6657F3F749298E07815A3B3BEF9E45A
+:1097A0004489797C83BEAE14422F027C2425F85A6A
+:1097B00098C2834C52827B93AC4B16185F89C3D9F5
+:1097C0002113034E80BF87F5C00D5E9C52B5C304C4
+:1097D000677BE0F867003F399374B9C7E0F7263933
+:1097E0009DF2AF4CA2BBD3B01719F29F917CA44F4E
+:1097F0005A3E452903BE302D18A6E334DBF878EA3B
+:109800006ACBBE7EC6F7355EAE07FED9526EC3FE8A
+:109810009ABD9C6FA88D38BF7EEDFDAC7DE27AFFCE
+:10982000027C743CD45339FE340640DE3886344F13
+:109830003F02701F51D73917D6A8128483C1FFA9E0
+:109840000024508FCA87CFA09D43AB46B8DB73423C
+:10985000248C70B3CAD3947C39418EF6C32795E625
+:109860008D3E0AE0BF392AD21B4994DF3C0D0DBB67
+:109870002C39D8984057B4ABA47266B4C0F82DD137
+:109880003371FDB281075C3FB019E0D8CEE859E5ED
+:10989000E32A301FCA0F9D248A9DBB29A643DE4BB5
+:1098A000EA30FF49A8AC4B00BC91C97AE073F6904E
+:1098B00048F4FCFEE36FE6F224D53A364F4C2E070F
+:1098C00086094C0E489E3ABE1FB7A84067821E26E6
+:1098D0001781DE4884CBBF20EEF7BA867AF20E5DA0
+:1098E0008CEBE87544A3F823E7D48542B49D04B417
+:1098F000485934F194B3540E6A66FCEADB47B21A55
+:10990000FBB351B0C03A6D1EC71C320652F5064C6F
+:109910004B46DD0EF4614B9B560FAA1CC59B4A01BA
+:10992000C67724C72BE2A1443A11F35A75D2F1F855
+:109930007EF37A29F1AB0F3F8CF56A4AB5B73FDE6B
+:10994000B8CA5501488166BB613E83F96C06879BA6
+:10995000978B6360DF22D387D3FD19DC3307E59350
+:10996000F78DEBCEC3BAD696969D00152E2DA8DEA8
+:10997000308DEEA7AB840800EFF5D0D924E8E18460
+:109980005E09721DFE994DC8B7856743BA87A18FDE
+:1099900055DF1435D9E027E280FA8B70D1DEBF7D28
+:1099A0004AFE4C4CF483727CC5E5E94BB7B0F174C8
+:1099B000FA3FA03B7F823C4D0B99FA25001FEB3804
+:1099C000EB006F10BECBFF5BC653C93687067A47E4
+:1099D00091A846E9D86944F5535E4C5C536402F2A1
+:1099E00044CDE9D5617B2FB52F6B09998E7C94D23C
+:1099F000AD19CF77723E10A869CA6FA6FD7E52EEF0
+:109A000009021F184CD966467AFFF56C4CD0B33763
+:109A100096EE46FED848F1A800F4FD5211F5A1F5E6
+:109A2000454FA86679F57383DFF4C30FA2C915C843
+:109A30003A08A1F0918AC49073CC3F8E1F897AD2E4
+:109A4000E5E287FB16EB7E7CD1FDFA759FFE7D7902
+:109A5000F8F18F8E67EC6B2ABE45F715F5EF166DA2
+:109A6000D680FA4BFF7DDD86FBEA2A22A1647CB812
+:109A70005B10ACF2C99C9AE507B9D3B25FB6C2AF2E
+:109A800007760F000F5B49829CE4FD3AEB25ED342D
+:109A9000E8B1B28AF2C8B01FD66BDB74D0E73FC919
+:109AA000214CDF8B2CEF12400F2A22A807410722FE
+:109AB000CD3BB5507483C0F01FF6C5D06F6C541DFC
+:109AC00033C357525D963C99AD0BE6F93BEB159CC1
+:109AD0008703C603BAF4D00E69BF520EE972A2FE24
+:109AE000C9E60F43313BFE9ECBC203035F01AC0CC2
+:109AF0005FADED9A036524D9FEF51BEF26EB7C5391
+:109B0000F2A5C4761E593B63D24752B793C9199345
+:109B10005E33B4CF7FA11BFADC2181EA858D81AF52
+:109B2000EB386FF80F95AF2D905279260DA9226171
+:109B30000DE4A4C6E8444B67F2B743B0D8E1C6F7DA
+:109B4000D4F360E3C56EA7B8087C4DD62CFA7262D8
+:109B5000DAD810F8924C91D25DFFF024791C55624E
+:109B600057876657D3FAEB1B3A26C177A3DE54D149
+:109B7000B0BFA9D834E9C732A1F51CF8955C1C0721
+:109B80001F55A299E4BB83746239FDCAF78FE03E8A
+:109B9000A05E45BBAC1335EC572187B01E7404F5AD
+:109BA00028179F2497B0EE20BFD1160AE1BCE488A5
+:109BB0006305A5BB8D4E9ED778DECFF32ACFE7F3A2
+:109BC0003C951390772B344F53A72DA262DEC5F33B
+:109BD000F93C9FCEF37E9E2FE079611BE6372AACDD
+:109BE000BF0D7294F5EFE2798DE7D3795EE5F90266
+:109BF0009E27BBD9F8769677D9A2AC7F37CFE7F30B
+:109C00007C06CFFB79BE90E785DD984FB57FAEA28D
+:109C10000E06A73EBED019CFA3F0E070EDCB77259E
+:109C2000E419BE64080C0F635F35F02688FC917858
+:109C30007291DE86F0368DF3CAD877EE47317D3FDC
+:109C4000A15139F749584439996ABEDFE7FC743BA2
+:109C5000E8B934DDDAA062BAA521807AEFA6068DD4
+:109C6000FB554AF0FBFA8620E6D7354CC0746D43AD
+:109C700008BF37364CC7FC630DD598EF68988DE95F
+:109C8000BE8630A67B1A1660BABBA10ED328D57744
+:109C900021DDD5A063BAB3A105D31D0D114CDBE6C0
+:109CA000953D5F04F35F40E73F007F183CDBEA0728
+:109CB00019546DE58BE953D22DE5EAE46CABDFA4D2
+:109CC000BCC092F7948EB2E45D456596FE1C399354
+:109CD0002CE54A6695252F7BAEB7E4AFE89865C9B9
+:109CE0008F8C7ED3D2DF88B61A4B797164A1A5BC64
+:109CF000B06585259FAFFF8BA57E5EFD1A4B799BD6
+:109D000033FCAC48F9D5B0BA0D967A43176CB3CA98
+:109D1000AB199997C5B7C8C77A96D99F91C8EFA5CF
+:109D20005C120AA1DC62F2A511F016FC5EC3487455
+:109D3000AF00FEAB6B4F80DD612F6272A79F7D99F4
+:109D4000D09FE2D9F79A4EC7A9F49D08F498E88C01
+:109D5000044CED28DF3F2532BB79C3BDCCAE6EBDD0
+:109D600037B97D8D9C9DAEA3F5F3E4FEDB1E51E279
+:109D70007A906EB1535AEF15B0FE3FDABF519ED8BC
+:109D80006F7C3C8A7315663D246AF845899E15B739
+:109D9000776D3DFEB960F71876AEE460DF2B4B823D
+:109DA000279B28BCD7AA04FD866B3D5504F48A4F37
+:109DB000544637644F2EDAE346FDFEF333E915C807
+:109DC0007F5C563FAD6716FA3DD7660EAC972931DA
+:109DD00009FD77524C205D54EE2872F5F47C4ABFA1
+:109DE000CA2B52703541F993D4BE27641BC2414A35
+:109DF000D06F9AE625F0BD29C370DD36BE8EC6CC85
+:109E00002AFCDEA40E3C2F3BCC0BE6C3E7658BB9E6
+:109E10003195624E9CEFC45806E627C4FC985E1547
+:109E20001B8A69456C08A6E363859896C7F2311DC5
+:109E300017BB02DB95C546623A36360EBF07636331
+:109E400031BD32F625FC3E263611D3D1B12FE3F7D2
+:109E5000D25825A657C4BE82DF47C5AEC37464EC92
+:109E600046FC5E12BB01D311B16F613A3C7633A65A
+:109E7000C5B1B99816C5E6605A185B84ED0A6277D9
+:109E8000609A1FBB13BF6BB1E598E6C5EEC13437CE
+:109E9000F65D4C87C51A31CD89ADC674686C23B6A2
+:109EA000CB8EADC77448EC7BF83D10DB8A6956EC6D
+:109EB000014CFDB187B15C8DB5639A16FB217EF72D
+:109EC000C51EC5D41B7B12BF7B628F63EA8EFD0C5F
+:109ED000BFBB623FC1D4197B0EBF3B624730BDD4CC
+:109EE0003E2939563E2E65BA2CF909A7D32DF851D3
+:109EF000F186958F97BF5260292F7BD1CAC783C740
+:109F0000CA2CF931872759EA971EACB2E447EDB75E
+:109F1000F2F1923D563E3E7CA7958F176DB7F2F158
+:109F200082562B1FD79AAC7C3C7795958FE7DC65E2
+:109F3000E5E3D98BADFC3B30CFCABFB3C80EABFD58
+:109F40003D65B755AE4D7ECCD29FA7FC09ABBDC0D9
+:109F5000F98CABF4A796768EA2A349ED9A447F398B
+:109F60008044A6F47D377105CDE72A469ACEF941A3
+:109F700006D01D4D3339DD0D02BAA369FA5716E339
+:109F800039D3A75F6DF95513ED2C7D28617E017DD6
+:109F90005B15F8BD9A87F03CFD22D07ACDC308FA54
+:109FA0000988FE6E2596E7B3FC0FA433953AF3DFDC
+:109FB000B2727281953B59FEB1C67F5B0DE5E969CE
+:109FC000A1EC20ED678F2D391F7F4262E76D17C42A
+:109FD00050BB44D7FBE7CA9E95E047B33BC27B2505
+:109FE000FA7DB1239C07AEE90F6CE14764E08B2456
+:109FF000B40FBEA791D02312F26BAB5FB415146EF1
+:10A00000DACFC762F57E28CF98D9817691B1EE6616
+:10A01000EFC0F3894A4C2E35FB09DA8DFAA30ACA40
+:10A0200053FC33E4059583F7BB7D2128DFF5A8B207
+:10A03000DBCECB2D72A33E0BE586ADA37939B824D8
+:10A04000EDB09F5232BF680FE6D340E32F04FBBE52
+:10A050003757A6E9527B5733C8F5BFFABBDF122446
+:10A0600084C7AF003E2BAF0F63FD35EE9913603D03
+:10A07000141E27E03B85C7F3D2A0D4F02070B24075
+:10A08000E71F30B068BF60F13F9E13C2BF954C7EA2
+:10A09000CC403888703B20A9080F037EF4EFAE74E3
+:10A0A000C31FC3DAFD11C74DE84FE6E762BF95F85D
+:10A0B000F85C1E1A789C21927032F81BE73EA423AC
+:10A0C000F70BF9B39D8A98741C9B5C8DE7A9FDF88A
+:10A0D0005E66825D9F1986B35E2A3FA9BC4C32AF93
+:10A0E000690AF74FC97997757E15E5FA3DD99FFB47
+:10A0F00085CEBBC0D083FA438D7D3A968BF951BC97
+:10A10000FD50D0EB283E3DF7A6FDE812CA07765178
+:10A110009E614FE20FD8D521E2F9FA503F45385AF7
+:10A120005ECFF5006A13A13E688C2B2FB6FA8F2202
+:10A13000360EC7C356380EA588FD536A72134F1EDC
+:10A140009B1F3FB734FA69EF9BBF751EBBF52031EB
+:10A15000DBDDF9ABA322E83572079DC798FEE31358
+:10A160007EBE60D091ECE17E13350FFB35C64D1CF1
+:10A17000874833F03C29157CFB8DF305CFEB2AE4AF
+:10A18000E4E79D747F104E4529F43CE3BCCEC83F04
+:10A19000F7662D9E7F37476A50BF6B0EF073F6BF90
+:10A1A000D15EA11F921C4FF6727C7A889F8BECDDEA
+:10A1B0005EE5C0769979967D2ABEEF265798E967C5
+:10A1C000E990EE6B63F5863F308F7FAFC1EF0FAD47
+:10A1D00062DFF3EEFDD8C9BE7FE88734AAB3EFDAB9
+:10A1E0006A99D717B13EA9A77FA673A0E16AB508FF
+:10A1F000FAEEF0ED2404DFF2D45E01FCC89A4A4482
+:10A20000DD04D7ECED472BAFA3E5D991EA59D7C1CF
+:10A21000797898048B35F8FEF2EA91B88FC401FB87
+:10A22000BD83AF3B2712DE3012EACDA6F548BCBC99
+:10A230008D8F3B2C12DE761DF8EF4A583F46F9F71A
+:10A24000797B97511EB2B68FF0F2DC55A7BA46D093
+:10A2500076B991DE97AE857A1DD67A9B79BD51503D
+:10A260000EF3085AC769E5F390F4DD04D0438A90F1
+:10A27000F4E9D08F6AED678381BF505E8EFFC6F22E
+:10A28000870DBE90C0478C762D29F6DFE0273BC1B5
+:10A290004F3002FD5598E6B426F7BF96717E65E013
+:10A2A000572A3C270B448B7D47C22E6B7EB649FF55
+:10A2B000837C28DB5A3EA1C05A1E1C65CD97945959
+:10A2C000F3DA244BFED33E3F4BD409F460F8590C2B
+:10A2D000DFCC0E95D149DC8FD7ED34DB2539BCDEE0
+:10A2E0008375CC1FD3E8E1F4C4FD322E4E97CD2503
+:10A2F000CC6E31D6FD24E75711EEF7D8D5D0C6FC89
+:10A300003063438E7CBA9F2DBF938203F9A11FE770
+:10A31000FBF1634E8F07B8FFE6877C5F1EE5FE9B6F
+:10A3200047C07F03F40AFE1B3BEC3FF3DFB473FF2F
+:10A33000CD43E0BFC17DADE67E98D958DE06FE9BD9
+:10A3400011E0275A80E916EEBFD9C4FD371BC17F43
+:10A350003302FC422D980EB231BB7CEBD45036F860
+:10A36000CBF64C4D6E170FB231BCC8074586A6B967
+:10A3700024F46517E02F456C3897293F167ACE4DA7
+:10A38000F323A20CAEE50743CF4179711BCB17F243
+:10A3900071409E807CA1FF60713639541B32E1EF21
+:10A3A000B817A3640EDDB7B7657E0EA051D5232B79
+:10A3B000EE2F8572D8A73785508F3C1EFA25CC8F9B
+:10A3C0001F0E0B401E83EFEAD5155A4F5DDC1D8230
+:10A3D00036BE96CE2EB0B335BD0BDB6DAD0CA29F55
+:10A3E000CDD8273ABA051FE8DC902F0EE3FB4F26A5
+:10A3F0005BF12137B60BF5E1E6BA596988771A198E
+:10A40000D05E2FD969D517866FB7DA49CD77CD1AC7
+:10A41000D0BF9CE82F53275BFD65CD2503B7F7958B
+:10A420005BC7F79426B4F70CDCDE199B39A03D78A6
+:10A43000855893611B14CF17C6AEC1FA89FA9F0CD9
+:10A44000F16F54AF93A72821380796A7A8187A254B
+:10A450004FD1781AE4DF433C5FCDF22A8B93A0FA08
+:10A46000623E8C43F727E1FC3B44E07C7AEB48C238
+:10A47000ED91DA35A11C9AFF6782F6C449F9CE2A1C
+:10A480009DE677CC7088D295806F2CDE41E1FB95FC
+:10A49000A144D723DD6E15C96E9ADF131998EFF525
+:10A4A0008B83F084D07F3374B15A260D40F7DB17CD
+:10A4B0008BD3A349FABD86D315394612F5EA6B6CE6
+:10A4C000F4FBDAC5B354E0FFF24D41B41F88C6E691
+:10A4D0006FF0B98CF481F76F57C27C7353F87556DF
+:10A4E000DB38BD9530FE68E07FC64A86E7A9FA5F93
+:10A4F000C7F959AC53B0F87F06DD545D69CB447B96
+:10A5000028E8013EFAB9C4FC688759FC9A414F8D8E
+:10A51000252F23FF36C6CFCEE902B38D341F99C84D
+:10A52000E22A287CD15E3C42F97829F27B02F55D73
+:10A530000B7A2A991F3D8AF10FAEBAA00E79C9C3D2
+:10A54000F005EC515E1FE7B3E1AE5921D8A7C61C58
+:10A5500012E420C6751A78D018103134E29312A68E
+:10A56000F7CA2AE51330FF9132CE9FEA59172F1A06
+:10A57000F68B04E789BACEEC37167765C4E30D6D28
+:10A580001B83F8DFEC5D89E785FA58A60748A49B92
+:10A5900088F9381F5D2C077FBF1A04596FCBD4058B
+:10A5A00033BE7D4D08DF0BFB1EC7AF4E8C4731E03D
+:10A5B0009708FF6F71BE9A4792DB1F83B97D93A105
+:10A5C000745E077CB7E5518AE749E266FCBCDE0FA2
+:10A5D0003A66A5012919746B941F90341CC7C80FE3
+:10A5E0008D292CFEAFCB6AA7FCFFAEEF1FB459E359
+:10A5F000F3FE47DFFF1F7DFFFF117D9FCBC7A96BD8
+:10A6000060236C1E962F6F9EBA46C7F559ED7649AA
+:10A610000E5AFC1FBD40FF26392F7BAC7AC9E5F3EB
+:10A620000D19F527121C66E1BF19D903CB19C3CF49
+:10A63000F1E930439F0F215D90A21262D6D79A8034
+:10A64000CF5338EEA470E47187384E365F97ABA7CE
+:10A650005A17317EC2CAB7772E38EA1C81FC5FC612
+:10A66000769E406708E4AD43EB46FE6BF069CA9FF7
+:10A67000C72A8380CF5720FF739544307E6D2DD736
+:10A680004313E10AFC305006E325F021A2A53BA0CC
+:10A69000FCBB0C0764F0E3819FB27E603FCBE5C654
+:10A6A0007D187118B9F40FF8D04699CD8F1CB2C639
+:10A6B000B1537C7458E275CF3D8CF2D4E8C7D077A3
+:10A6C00012DB35A9556A32BEF8A610FEBA32009EDA
+:10A6D00024FAB548021FA71C54007D6EE88CE9E8F7
+:10A6E000AFEAF36FC956BE2E078CB898FF5EFE5EC8
+:10A6F000A7FC9DF1EB5FD0FFB78B9FEF27D2716274
+:10A700003FA24EC49E24E3E7EB62C2B9B355EF17F4
+:10A71000648DDD13AAB39ED3C89EECE4E7093CCE5A
+:10A72000B366421FFE7EE38F147FEF3861633C8C7B
+:10A73000CB25C3BF7B07C47BD2FDA981F84F2ABFBD
+:10A74000E7916A1F147E40448C2BFB80BCEC1B6796
+:10A75000DAA77D0AF3E79316DB29B86F64C435DE08
+:10A760001E6179633EB56DD6FC7C322B0BCE35E68F
+:10A770006FB7118863BC83C8A77A8CF9533DE7FB98
+:10A780000A8BD3AE2575CDC0CFD672FF7D8D4A64BE
+:10A7900088435CF2CC8315606F1E50981EF52E85A1
+:10A7A000BF668A575BE8892A703EF1CEC1715FFFB0
+:10A7B0001281F6D1E66C8847A47A2DD8BD89709FA6
+:10A7C000DB629DDFA5E69F385FE37E52AA79C81D54
+:10A7D0004228991DF133C51A3777A97B536F8391AE
+:10A7E0008CE720D67B53976A775AD148B2FB5697AD
+:10A7F0006A77FEEF1CEF428AF196387A14E003CBB9
+:10A80000E4F074A1201EF7A5D8AA43432928E44305
+:10A8100063BBC0176EAAD77299F54E80017219F505
+:10A82000A68B03F47781D3F1AFF63FAC007D7EF0C9
+:10A83000D8C99970EEB3E8671271C0BAF67B4917B0
+:10A84000B34F1490630B0F4AE88F237257C58DA640
+:10A85000385A8CB8A5EB5FF4632FC6692C7CC21EF6
+:10A860009D41DB2F7CFA9D3184C2E1C29ADEE34335
+:10A87000C1CE784C6071897ACF981BE9F78532B9DF
+:10A88000AD3A091FF4D8199EBFFF13F76CC023A17E
+:10A89000E3C8ADD86FE7376C76D3B9A064B7E1B839
+:10A8A000B45E889D6709D16281CDCF7CDFC2880705
+:10A8B0007DFF5181CDEF902DEA84F975B42B615A5B
+:10A8C0006F59C75F106FBFFCE3033E80C3B2439272
+:10A8D00085BF2CEB90BAEC63303D69C7FB34218F08
+:10A8E00040F9C8526431343DB804E3C797766EFC32
+:10A8F0008BE483F656FAA1700976015C5F9582338A
+:10A9000020FFE4233EB01BDFEDDEEB03B8D27EE791
+:10A910002814AFAEF9D8446784F51F4BEFDF1FD57D
+:10A920007414C0AF659DEBD97809F4F92EFC634827
+:10A930007FB930CE6E950B9F90172BD05EEFC84835
+:10A940001A6FDF271738BD2E3AF0C92E9D8EFBFEF9
+:10A9500013EFEDD2E9FC17FFC747BBEE01BDECE7F3
+:10A960004E15F8CCB2C77EE72326B8CFB433BFC1AB
+:10A9700085471FD9B783D2CB853FD8D1AEBDF0EC88
+:10A98000D95C8DAEFBC2E39F6569B4FE5DCF4E1D01
+:10A990000C70B8EBA92F0F1EC84F00F81AB59BF723
+:10A9A000358AFD6B870416DC7F98A709FBF3DCC1B1
+:10A9B000E772619E1FBC66C7FB8CCBE8B7FA32D842
+:10A9C000AF25C8F721BF8AC279E9FE757F91C624F9
+:10A9D00083B73E54C4C3454A3601D8EF1BBF7675D2
+:10A9E00039A4B6A006FD915EE4DB89ED96BD42F781
+:10A9F000F5CAD4FBF809F99B02F05FB67F3D1B371F
+:10AA0000611F3F807F4CECBF8F8BFBEDE3E287D073
+:10AA1000E638989134FECAD8C7254FFDF3807A8076
+:10AA2000C10F2E05DF053C8E70A23DB4CA0E74F531
+:10AA3000845B0FB0FD8DCEA065170E7C924B287EF7
+:10AA40009CB3F5DE0A7CB2F759BBBA9B7E5FF8EC8B
+:10AA5000AB4867179E7A49D1904F128F40F5840B0F
+:10AA6000A4EFAF1BF486A5FCCC79D91E6F97DD1738
+:10AA7000DFA7A5D11BA66B3EFC7E12BF4719FE2F98
+:10AA80008D1EB94948B26F4FDB0B183F8F0E42B88D
+:10AA90002C21DD8A5A6ADD4F6102ECE3C9698077B7
+:10AAA000A9F6D158BF0AEBBFCAB49F7B18DD26D6E2
+:10AAB0005F4AE913FC887DFB1A155E2549E8F442DC
+:10AAC000BB5D8678E10BB64BDC03FE82FA5FA73DE7
+:10AAD000857DCFE170293ABFD4FABE28FC76817318
+:10AAE0007B507F38BEFFB7E4FCFF45CE379692F02F
+:10AAF000F46CA9BFFC9248481F9A1F9F6F73A784EC
+:10AB00007CFDFD0E290A4D13F9C4D2147EA7D7EDA2
+:10AB10004C1F597AE8C818E067EF1FFD09C74B863C
+:10AB2000F74BF79F54742E0FA2667990C23F799A23
+:10AB3000CF7BD9E1E4FD2DDBFF97A4FDBD2B87BEC4
+:10AB400001F37FB7DB4674DAC5BB9D52523FEC6F11
+:10AB5000EC364B5C61B3B7E2B534DA4EF2B9341877
+:10AB6000BA714DE8551DF492976D78DE41E4E039F5
+:10AB70003BF813BD2E6D038557A36F3EFA2B8DFE58
+:10AB80009A12E02407AA75B04BE5CCEA72A62347D7
+:10AB90002D76B14D152DF3A6723607E4D05B63CF49
+:10ABA000DA609D6F27E8836FCBA47930EDEF6D5DA0
+:10ABB00008AED692E1B7B5FFF02A896866F967EF6B
+:10ABC0007D0BE6437EE12410A722FDDCA9033F595B
+:10ABD000B6CB1985B880E79EFA741FC0EDC24376E4
+:10ABE0001E27C0E2CE6B55D6C7D9A73EDDF5EFB420
+:10ABF000FC2C34A6E3D7EEA2F5410FDFEFC6E0FF51
+:10AC00003F3F91368650FE5CFB8B7B66027FA90539
+:10AC10009E4AEBD7FE7830EA756706B1FC9903C30C
+:10AC2000A2B02F8B9F7C7629C891453F7213701973
+:10AC30003CF7D4ABB742FEC22FBC182779E11767A7
+:10AC4000AF013AA0FAB36696E37798DF2BA0FD2E0A
+:10AC5000823C2B172E9AE26F16414AF9C6A243692D
+:10AC6000780FC8540FDB2DB3F7AE0CA23F59CF16A7
+:10AC7000D1C6E9CA063A5CD4611D6FA483F949972D
+:10AC800029BDF359FD4836A3D76E6C57E1E078CA69
+:10AC9000CB13DB1BF5CB1D05967A46FBA5765297A9
+:10ACA0000CFF2B79BF8B3A3E1F61ED8FE16BFF717B
+:10ACB000D8F7EF08EC9E0A79DC89E76D8B95AEE159
+:10ACC000E9945E9F56C802A0DBC5BEAEE17E3ADEC7
+:10ACD000CF389F5CECA279FA3D9BCF03EA439E38C4
+:10ACE0007A7E04FBBBE41927017C5FF20B2F9ECF19
+:10ACF0002C79FAD3333FA0DFDF7FCA8D7E9325BF47
+:10AD0000B81BF77B89BDEB56F0FBF53E6E477FF332
+:10AD1000FB8F3F9F0B7AC8FBB6AEDCF401ECF3254A
+:10AD20009D76EE8CB0AE83DA052575743EFA561624
+:10AD3000C7564F5CC1D5109F028E03C0E3379C2CD1
+:10AD4000DE8A9FEFAEE0FEA00FE7696938FF52E6AA
+:10AD5000DF5AC1FD072BBEAA0DF69BE60171A66462
+:10AD60001C21772B752380CF4AB1AF108DE6E558B3
+:10AD700021A6463D490DE2F98394C9CECF6D994194
+:10AD8000525B0AED585C12F15CDF4767FF8B6EF196
+:10AD90008A07B4C1D0DF4207D3A7DB9CA1BB1D68E3
+:10ADA000CF78F07E29AE933204FD29B6AE4F05B6BA
+:10ADB000AEC4F97E6AD3EDC0CFE3E7DEEC9CA55EBE
+:10ADC000D65E85F34C7282F3A57EEB6774F6A19A8A
+:10ADD0008E7466AC6363838AFC647D4300D3750D17
+:10ADE0002544C3FB0141CC4B1C1EF6529D4870DF2D
+:10ADF000566373B57BAA43707E017DE2B986278CCA
+:10AE0000F8650FD4A1EDEFF010B44F258F4E6A3DD9
+:10AE1000E80F4338C1B90CC049E179B96D06C29554
+:10AE2000B6C7EF2B9DE15D001747CE280B9F52322E
+:10AE3000CB2CF97E7033F0E2C07F37FC08C26B7D0B
+:10AE4000830353B85F017083FB1590FFBF00BFE31E
+:10AE50008EF1ECBE8366A21FB8EFA059E82905FC6D
+:10AE60001EA0F0CB8CD355221CEA797C9B414FA9C4
+:10AE7000E817EEA7C0E5836D0D6D981ADFD353C8B0
+:10AE8000F5E14E81C7058457DBB87F1CF7215327B6
+:10AE900039267F1209E8782F0AEF5743B987F9114D
+:10AEA0008DFD9554F98C95FF69AFC27AEE7EC1266F
+:10AEB00002BF92EA1F26EF6498E87846B5534338FC
+:10AEC00007D17FDBC8E5EBDABEFDB4D2C7C6060DFD
+:10AED000D34D9C4EB6703AD90AFB0EFEB9A0887BC2
+:10AEE000DA3A9DA0FCBC8FE6997DDF45CC7E6D7F74
+:10AEF000B0B3CB46F71F7992866917F2AFD7ECD182
+:10AF000062DACE5D4A42802FFED7BE1BC5B592CE17
+:10AF100000F843FD1C7EE47081FF66F69E828DC9B9
+:10AF20002922B1346203FB2911BE8DC1A30EB0BB2F
+:10AF300053CD272BA8DB73E978596FD8917F67DE53
+:10AF4000D2F95A0D5D87A7D58DF6645690E1A327F7
+:10AF500018166A4DFB979542EFDBE7BC2ED349E903
+:10AF60007810C4F3D2745B5BA113E0BBD1D6190097
+:10AF70003EB8D1CFE48C369B8E7695A93DE78FBE47
+:10AF8000722BFD1BFC589D5C66C16383DFA64FB12D
+:10AF9000E2BBC16FCF3B983ED7E6AC1EEE8478DEB5
+:10AFA000D84EA4C744FC6FB429BA40F59446D025C6
+:10AFB00041BF3B29B0B894FE7C00E3563EECC9DFAC
+:10AFC0000DEF0EACE1F1D43AA517943BDCFF699C80
+:10AFD000CB1F20D52DF00E4C0BC52302EFD550FC16
+:10AFE000017AD84CF107D208C51F4627133035F037
+:10AFF0007326384FCCE7BF45C745769F4304994336
+:10B00000646A077AC0CF7464A203F442D9C6E259D5
+:10B010007ABD6227C4B3ACF5CC7284C0AFE32FC74E
+:10B020007DFFABB7266FA07315785104F046F50489
+:10B03000C9A9D2F8BD5F492D23604F1EF074E3F912
+:10B04000DED54ED132AF3667F846A7C9CF3F1A4694
+:10B05000E7FBF64FB8FEE4F7876F73723F658E4EDD
+:10B060008A4CF46DC499124D2725263A5F533C8DC6
+:10B07000C039687FFA4EC1C7F6FED7F0B1C6BC280A
+:10B08000EE9B2D916F6452FEEEC154175538DF3B95
+:10B09000D4F42D3FE2D95D000FE2D9DDA7BFFC5308
+:10B0A00041FF7926F2ADB83CD2D05F45E5D1FD1322
+:10B0B000800FA6904747DE1CF1358596BFF3BC2470
+:10B0C00098FD750B62EB511ED4C626128DCEB7A625
+:10B0D000ED7B98CE6F6B47BC3F175DEBC3389A167C
+:10B0E00066CF9D8BDAA2523EE2ED4509FCFA84F56B
+:10B0F0007F6E6723D623E07D318D7B6E276B4FCA31
+:10B1000035D4A73FE46BACD9620FC139CDB936DA7B
+:10B110006E0078D6803194443FC5F704E0EE00A974
+:10B120001B017CCEA0F7BB15CA97000E6FD993FA0E
+:10B13000D9573AA7EE00BA5EE90CB533B8A75FD687
+:10B14000BB16EF8854EF4578877D3758FCACCC8F21
+:10B15000F90ED78B892345B98FB75793972F697D00
+:10B16000EFF8BD34D75C1AAE2626FB5A22CCBE5E61
+:10B170007AA892BF2FC2E693043F993EDB6A473E0E
+:10B18000348FFB830C7C8DE34BD8C7EF975AF0E9E3
+:10B190008ED856DC6F61E3E8FB2752F87D44F10856
+:10B1A000FC72C2C6AB07031DADDEF0A52DB7D0FE05
+:10B1B0003F7E51C2EF0B624EAC7FFEDEE0FDB780FA
+:10B1C000BEFE6F36027CE4E31353F13CF6BCCDEADD
+:10B1D0004758E462F2FA1CA7E3F9B18D16FD787EB8
+:10B1E000CB5C05FC8FF3639BF1FB7C3894C17B2027
+:10B1F0007F3E5629C3790DC1F3D173CEF7A7AC01B9
+:10B20000381C2E433F56ED267BD27B29E79C9AE5DE
+:10B21000DCB9B6A715FB25543FCACCE2FD99F84727
+:10B220006D0C2EB1C0FEE804EE2DCCE77CA46F7E41
+:10B230003B6D163E72DE99DC4F12E37AC9FCD8975B
+:10B24000908EFAAFEF1A465FC6B83D8CEEE2EBB9CE
+:10B250007F62B2F5C4D73119EB9FF7271F3F8FC329
+:10B26000F94CC30212A27CA8C64EEB7960FC3B9B52
+:10B2700027809DBDD39F2E98D655DBB688844CEB96
+:10B28000AADD3947A931F51BDF07E72FCDFB90B7C2
+:10B29000419EBAC60372BBDAEDA270AED978F598BA
+:10B2A00030DAD98C9FBC630BE6025F3DDB766752D8
+:10B2B000FACE736916B950DBC6F787EABDE5A6FD7D
+:10B2C00031F625B1FD99376BFF7A2FF8011E604AE0
+:10B2D0004D2A78F5DBB7FCE4709BE862787986CA82
+:10B2E000D930C24D7BFA35C0EB4D6E8CF74C0DBF9B
+:10B2F0002B487820F8A5D05FA9BE53E61A0FE312B9
+:10B3000084436D1BC3834BC12D3E2EC783CAE4EB20
+:10B31000A9EDC3837AA253823DA55C0A0FEE21BA40
+:10B32000638075F4E1C1680B1ED4BA8AA7023D9E02
+:10B33000033D6544FFFD3FA5E8BE49700EB441C220
+:10B3400073A6532E3DEB9B2C3F16F8F3295F64E662
+:10B35000A4F278FE8EBDC5BE39A671CFB6DCE94B2E
+:10B36000E667AD4D853F453A29ADF83F873FEFA4ED
+:10B37000B8C7B5D259B908F6934492FB738DD4E09F
+:10B38000DF529AA7CFEE04797ACA53F0D7282D3D21
+:10B39000E40CAF047ABA5BD4C6CC11E2F6673FFD89
+:10B3A000B361FAD5A78BC15F587DF5691BEA43D815
+:10B3B0001F01BD329FC745A07F6308CA83C4F3D273
+:10B3C0001FB8F2939E8FAE6DA81B07FD12874E54D7
+:10B3D000739C1C617AD4FF86F1F3E3EB516C613509
+:10B3E00008F6A540AA01CF6D72B805EE03DB0299FD
+:10B3F0006375135C1F7031FF97F3D8B1967CDADE6A
+:10B40000F9A7175582F7CC74F4AF3972E40FCDFE6B
+:10B41000695B268B5F2445A6EF0510874CF3163B2E
+:10B420009FCE77003BF567028383EEB5F37B75BA59
+:10B430000472EF662731FE50FFFE8311072237B1F9
+:10B4400072BF51DCC4CAB9FF72590DF34F26EEEB3F
+:10B45000CD87D775833E73F3E12173C18F75B367D1
+:10B46000C49FE07CE167E0C3077CF733B99CD8EE6A
+:10B4700030A7D36FB58BBA8DEECB315BEF5137CCA4
+:10B48000F73BEC1DC76FFEEE98CD4DD3D75F396506
+:10B4900083773B6E83001DBAAE39445398121CC5A6
+:10B4A000F67349A797E53B07CDF29AFBA3A62AF4CA
+:10B4B000B79C9DF37EF377AF4C05F14FFB5B0BE937
+:10B4C0006D2F1205FA9F73506B66D7F8787F8769E6
+:10B4D0007F62BCBF381C1566E7C80E844B1C4E0E3D
+:10B4E000849B012778E606CBE370467DC380731FFB
+:10B4F000DCD2665F4FC6A4A6979B3DC3FF44C6C47B
+:10B50000E79508E78FA188D2DB7157E88F403707AE
+:10B510005CA137205DECE8CD950BF01E630FE4973E
+:10B520004AE1BC2C8A671F0C0B8F1804715CDDC9C3
+:10B53000CF5713E9F42DA01788FFE67198B7F2F5FD
+:10B540003DF7DDB35E8CB37CEAD55C4897483D9B04
+:10B55000BE01F4F66B09F5EF0F0F8E18302EED2DAE
+:10B56000EEEFF8D425F2F303B6BEDBB81E77DB416D
+:10B570007714DEE3BCAD5EB2E8BFB7D5B3380E22B8
+:10B58000778FB9C9A24736A5EC07ECCEC47E8CF5FF
+:10B590001DCDCDBE02ECC387C62B1AF81F8EBCF89A
+:10B5A000E11F6A69DE35CC81E7B29BFC1C7F2B452D
+:10B5B000DCF787FC21F768F03B6D480FEA749D1BB0
+:10B5C0007E493A450A9FA3235746ABE8789BAF16BE
+:10B5D000D167B525F670A40ADA95B2778F54AE8F8D
+:10B5E0006EE93ED506F878F6353BFAFBD3BD12CEB0
+:10B5F0006383AD3A17F4F73FB52B49DFD97378650C
+:10B60000ACD72EF460BCDB5C127100DF38D83D6B28
+:10B6100030CCC717242AA0FFD99D92C8F464C3CFA9
+:10B62000D125333FBB2EB37C88A7AAD3FCDEDDFA3D
+:10B63000E953309E625EEB4B184FEC2B4F7ECF6987
+:10B64000829BDDD7F576A7635CB4778A886F24790F
+:10B6500083BD02B4CBEBAE52B07D4418B07DDE2A80
+:10B66000F53A802BB407FE9F7799ED836E05E1B024
+:10B6700095DBC9EDB660F314DA4FFB26BF00FB6122
+:10B68000D4BBCECDF499B3530CFF4D04FD37B9456F
+:10B69000AA13DE5BC90D2171136F79C401F0DA0DB5
+:10B6A000F5987F13E1D03EF2E92E383FDE00B2017B
+:10B6B000F6D9C6F069C32601FD99147ED9202FFE64
+:10B6C000749FFD2BB08EBC164105DB9BA649E7BDE0
+:10B6D000DAE360F2A6F57EB403C13D0AFDE6EEFCB6
+:10B6E0002DCECB9B62BD3FF430FCF8D325F023C7B1
+:10B6F000CDFC36B9F5DDDC4EEAC2F716230027C8CB
+:10B7000087CAD93B87724833C7A1C4E987D9617416
+:10B710009D18075A334189821F406C69C77785E7B6
+:10B7200046ECE45ABABE56A13B04F4A28F17F97B4B
+:10B730005EA1B7004E9BB70EC678B675622817FD9E
+:10B740003BFFAAE0F9D8D1D0870FC0BBBCBB2628ED
+:10B7500048174743EC9EEC43AB0ADAC10EF7D657C5
+:10B76000E17BC1515541CED2584E5E8078D2C6554C
+:10B77000A22AD0FA916AE33E82EA02BC182B7D74B9
+:10B780005D099C9F0D11C19744CE0AEC9D91B5AB0C
+:10B79000AA54D8D7B56AA660B65B748E077FF457F3
+:10B7A000EB6EBABEC0BDDB548801DF12CBB802FC21
+:10B7B000857A8BA2B1778BD9FB24197C5F32BAC50D
+:10B7C000AEF93ECC7B16501379CB64E6A7FCDEF5D0
+:10B7D00061E65F8433C90AF42FF2BF00EE6B26CF17
+:10B7E0006D18E5C2CCF635F3B13EF49345FBC9289C
+:10B7F00017BB2A68BFBBFDA15D284FA63A104E4477
+:10B80000EE69033845A76607E1DDE46D1387BF04E1
+:10B810004F54659CE89D0572343ACCF57A3BF0A90B
+:10B82000B58A06749EB1EACC2DF0DD1FFCFE9D901A
+:10B830006634FDFE1E9007FE9EBF34E0F7E98AC520
+:10B84000BF97F1C6F9CFA13CA35AB1F8093FF3570E
+:10B850003FECA6F0D9551A89D468EC7B282BBE8E14
+:10B8600003ABBBA7C3FBD9676F1083BB7939AE6B42
+:10B87000BB1ADDC0E0560E72CD80DB3A51EB84F787
+:10B880009DF5990EC48F22D28DFC6A089C2217C6A2
+:10B89000F725E38DF5CB214E22713ECFB885BE77DB
+:10B8A00061E09D4A8CD7A7724C1932C50578FD78A6
+:10B8B000597700F4F84DFEE4F1099F7A587B7B8AB2
+:10B8C000FBEE1F79183E004B6C2BC334341A520F19
+:10B8D000D1D320CD7184203EF67151FB23E2F9369D
+:10B8E0004983FD81FA36BA7F475E7817FD83472288
+:10B8F000BFC5F4654F097BD78F125C16BCB35B7E66
+:10B900000ACF4736AB0C476A5B18BFA80DF438E086
+:10B91000BCA2B694A8BB39BEE9069CC1DFC5E555FB
+:10B92000CD4D0CAE99A504CF5BC12706EF9E6541B6
+:10B930003D0ABFCC96D5CB711F49B75E48EB6D86EB
+:10B940007E617F9AD8FD14427A1C48BF1109CF1B33
+:10B9500029BDFF06CE136B5A07E3793B5C7787FE60
+:10B96000D2F9B8E9BCBF76DA0FF8FFCEB648643733
+:10B97000F2B76E78639868AB282E237EF65696D081
+:10B980007EB57255DD60E081C1C72869CCA3F202A3
+:10B99000E0364FD79703FE9D72A82FC03CDCDBED4D
+:10B9A0001AAC7FDEF667EE06BDC51DE86901FE50E4
+:10B9B0003B81CD37BD957E47FD46FB0DD4AF6DB5C0
+:10B9C0006B6C3C0EBF728E671C0EB7F379DFBE93B3
+:10B9D000CDDB352C1A01FCAC5D45E10A656186F7CB
+:10B9E000E0D2BC28225D9D80F57BF52CEC77D0EC75
+:10B9F00004BA48C03F635D357C5D35ABD8BA08A753
+:10BA0000273AAD2EE8B7A69CAD731E61ED45F84E02
+:10BA1000FBBF9DAFA7467F1AD3DB5BEC96FE779505
+:10BA2000ECE986F9E4972A9A807066EF6DE6F27584
+:10BA3000E536B1F1724B9F4678917AD37CD12F6A6B
+:10BA4000CA53BA3AFB3C252C78CC22D781C874EA79
+:10BA5000BB0A9EA3146DB7AEEBECFA110FB782FFD1
+:10BA6000F33E05CF2B1E17836FE5A11DAA688CFF3F
+:10BA7000047F3B03F8F4ED4D78BFEA402583FFD9FE
+:10BA8000AF9228E043F189EA748077F189304FEB77
+:10BA9000F01C9B0244E8E37B747ED4746A11805FDF
+:10BAA000C60A7FB800F800DD67D0078799E74DE741
+:10BAB00097D192550571489913D2AB147C4238A1A5
+:10BAC000FCC48E59F01E6EE6B11D77C238438869FA
+:10BAD0003DB4FC4A6F21BB9F758C9642BDFA33F78B
+:10BAE000C27EB4F277ED8B6166E9981E833483D20F
+:10BAF000F7C67498A74CA694C5F9C1DEFB2AC60206
+:10BB00005FC1BB2565987691B2FE7CC3547F24AF9C
+:10BB1000AF0B49EA5578358B5DBEF7BE6923C17E10
+:10BB2000DF0C7A621ABC0BA87E04F1317A5044B85B
+:10BB30006FB675394A33E1DD719180FEB2A5E4F745
+:10BB400022D0DDE6832408F89151FD1F76F33ED61E
+:10BB500079FCB86E59211B81FE8F8E3C331DF6296E
+:10BB60007A84EA9DB47ED5AF3C3BE03E71FB1F5822
+:10BB7000FC49FBF37528BF57E62A49DF7D2697D09D
+:10BB80001313EBA717CF423F5EDEF6ADF8BE6CEDA8
+:10BB90007439782DAD9DB9BDB212F418AD9A62D743
+:10BBA000603AEF9D635703116A33D87995369D7DCE
+:10BBB000D7A6B07463C3827160B7473A6467119DBA
+:10BBC000EFA8F5ECFDBE8DA51F3AC2542F2DAF7C1A
+:10BBD000C2F155FAFD74399582F4FBE9C91F3AE1C7
+:10BBE0007CE6A1F2AA0C80E7C116AB5E47E0713695
+:10BBF0006A078DB647425E3AAFD6DF1184A764EF7D
+:10BC00006AABA179E9190F6838FDEC9BF5ADEDB38E
+:10BC1000014FE795607872FF7DE7F2626E7DEFF489
+:10BC200002A05B9DB073D4C8FDC8946FE72C235F5E
+:10BC3000EF46A6E3DDCEEC93881C3A0E7C39521A0F
+:10BC400056A089C1CF5A8B6BF6013F53B8DE4FEA3D
+:10BC500016E0FD48A47F09F4A1DECA6476D3B7DDFF
+:10BC60002EC4ABB33B6F7C15FCD3F3EA99BE9FB7F0
+:10BC7000F32301F783EA7D4368FF79E5F8E425992A
+:10BC8000B72AE2180DFB5324124D83F97412B01336
+:10BC90002254FE98E160F4FBF7B6DFE1B1E33ABE6F
+:10BCA0000DC6F3F8F87A3C7C3DB9C1DECA64F1B345
+:10BCB000DFE2E37EE7C18F8E4C04F8AF6226525E6E
+:10BCC000E4A4E030CD234FBFBC79DC02FDD1793C48
+:10BCD000E961F7A7BDE53D78EF2891BF833A0F747E
+:10BCE000BBCB7D612CB3EFADFCB45F9EE355E2F7B7
+:10BCF000DC047E35DADE793DEEEF01F6BE3A2194C2
+:10BD00006E1DF8ACA8C6DE9D8D1AEFA0D741BD51BF
+:10BD10005E8F0A78D03AF2F765009F4D5C5FB8BD40
+:10BD200094A0BD7A7B4E37EA0B739BB8BE20079B6D
+:10BD300081C9BA77FAC90693FE802E2C702D357111
+:10BD40007DC190FF5C6ED706BA5B50AE827E60927A
+:10BD5000AB353A93AB790126D76B5BE8381A47E6E7
+:10BD60000AB35EC2E4B8B69DEB0F5C0E67F07133A8
+:10BD70005B98BCCA003DC207E1073ACA653CCBCB21
+:10BD80008AEB2D834A99BCCC687D1CE5DA1FC0E99B
+:10BD90003208F8069397C35E7A45073005E8E73620
+:10BDA000CAA78FF1F2804AF5B3F4B87EB64EE4E745
+:10BDB0004C84E987185B4FE77998D737BEEFE1F3FA
+:10BDC0007BFC58FA5780BFEE8D148C954C748B5EBB
+:10BDD0004F9ACF2D67E7F4B9F5EC9CDA1B9CBF4F67
+:10BDE000329D3F6CF5707BD3C0ABFAAE00F48BF79D
+:10BDF0001D918FB3F7AAD6537D09FD4FDCBE9AEB98
+:10BE0000E67E0D8E3FA9E489C187BC24E42BA5F012
+:10BE10003D1DDD87FC5AA7F612ACED74A4317B21E1
+:10BE2000D07BE4867298FFE6897FC5B88BBC14F698
+:10BE3000A2C3EB30E0F085F8BA77FA2BCC0EED1602
+:10BE400093DE9399CAFD0F9D3271033C9D11F6DE7E
+:10BE5000A1738292B4FE042FE39B195E768F68F380
+:10BE6000C47D78BF31A57C96892E2591A786BC6DAF
+:10BE7000857D9E44C8CCD65B9B75B4D3A3D512F206
+:10BE800057760F30C27F77462F51D06FD86A8B38E4
+:10BE9000603FB694F37D551DED703FFD0BEF0B85B4
+:10BEA00007ECF3FA901815F2619FA3EA68E6D7C190
+:10BEB000DFED394BED77F339C52CAFC8E1A489101C
+:10BEC0009F98D7C2F06BF34405E7B1616C56BB9401
+:10BED0006FE6BF02E79F0C4E1B261E47FCBADCF93B
+:10BEE000CDAFBF67D269D339E299071E290038C7A1
+:10BEF000DF6F090D787F617EFD4B93F624391FE8D3
+:10BF00002B073BCA037660F49BE67396855E6667F3
+:10BF10002DF11AEF3333FE06FCD586C645341BFCE3
+:10BF20004B07AE8EFAD07FBF989DD7DEC1CF6BDFB7
+:10BF3000DD7323BEBF301AEED426D9F7F30DD6F742
+:10BF400017CEEF7D249BF935A216FDEA8E7D3F19B1
+:10BF5000C5DE9FD1F9EF72102DB382BDA38D72FAA9
+:10BF60007850B74BF1F7D114F85D0CF0B703051713
+:10BF7000C22BA09D987A807E0BE1F7857A315541DE
+:10BF80001C15829D14C4349354639A45EA300D9075
+:10BF900008A6D9A413D31CB0730B412EF462AA11C6
+:10BFA000552426BE5F4082982F22D598CAB06F19BB
+:10BFB000F17309B9C381F117707E01746F9C531836
+:10BFC000E7FB377B6B1EF02639AFB8C71BDAC1BE63
+:10BFD0007721DF9ECB59F8891F8DEA84FB3D2B36F4
+:10BFE000B1FB25065F47BB86F6FFC3742607F46DD9
+:10BFF00002F2AF35EE99D7201C5B6DEF9BCF1B880B
+:10C00000C35104BF3F63F43B97FB17E672F907EE99
+:10C010006D76FF2E88F77FE6829FC1544EFACAD90B
+:10C02000FD6BA31FD13D79F840E77BA6F6188F5C26
+:10C0300093A0FF5F526E27E4E725B6FF1B9D505685
+:10C04000DC0FF7C36BB45C76CEC4E43645240DDB5D
+:10C05000B5D84FA21D16991A32C3E5258EFF863C2E
+:10C060009997E0D74F4CE7C99C2E12FAA192CF0FB7
+:10C07000F766F00D14135D1BEFE81ABFD375472860
+:10C08000AC0C61CD02B08F2A9F7784ECAC1A42D3FE
+:10C09000739037F9F37FE70BBFED35D1891AAA13F7
+:10C0A000CDEF34CDE77438556AAD04FE76364C8258
+:10C0B000603FDC41EA36833E465E9190BFC13D6CF5
+:10C0C000F8FDA06170A0918E795DA1E9070DEC5E8D
+:10C0D000CE1978476904BC7FCDDE517A0FDE4DA2C0
+:10C0E000E9E8B6BB67021EBC0BEF27C1FD5B4EFF44
+:10C0F000C6B8A33BDD7340EE8FEEBCBA16EA8DEEF8
+:10C10000B0E3EF45951C5C5F0D7E2178CFC545C738
+:10C11000C9A1E339D2818F1094B7EFB5BAA26BE809
+:10C120003CDF6B93902F7F522AE2BB23F06CA6C4B6
+:10C13000E797960EFDFCFBADA087BCCBF988F17E9E
+:10C14000E47B951ADAC7BF3CB04E807B09EFCDD1B6
+:10C1500070DDEF0DE9CC4D07B9E463F1E545FBED8A
+:10C160005D05741E0B1FFB43410DF0BF82C8C26406
+:10C17000E7CCB93E264FDE7B8A603CDC7B4EFEFB83
+:10C18000488E4E9FD9CF1AF00916BEF59E97FFCE66
+:10C1900052CE25EAF1F872E2E9F431BAEFF4C1794E
+:10C1A000D4FDEE1FE1FDB5334FB1738A5F3E509B66
+:10C1B0000BFEA8229FC6CEBD0F3C8971E3B00EB026
+:10C1C000A3E9FC3498DFFDEEB7DE05FF036D87F7CA
+:10C1D000338C76670ED4B2FA6DB4BE0FE14E7C6537
+:10C1E000800F0CEE643FE31386FEB8289A85BFDF0C
+:10C1F000102F17B11CA6E8A4F01FBDFF063CD7AA5C
+:10C20000F0A5337C563B47CDC2F94772611D07AE9E
+:10C210000EE7821FEF8CF17B52722417E070B33768
+:10C220005CE133ADFFFCC96790BF9788756FDF0B8A
+:10C2300078F904FB3D93BBDFD82A9AF9C7541FD382
+:10C240007BEE772FF5C179D499BE7775222CDEE786
+:10C25000307BD77511A7BD33EDD47EA2F038BFFF78
+:10C260007B587EA6EFDD9B4E8C273BBFFFB9744801
+:10C270006B783C3F89DE88F445E1D2E24822AFFA90
+:10C28000EE4545D97DB70B027FCFF441036E75CAE9
+:10C290002CCB7915A3EF9C9DF9C7505F8E26BF2745
+:10C2A0009728EF13DFA7BDD43DE0539C4E4FF377A3
+:10C2B0004DEEF1866B7C49E448CDC625B900E71AFE
+:10C2C000B85387710E95D782BD8DF74DD8FBB45DFD
+:10C2D0000827E3FD59FDAA6B21CEF18C9FE5BFBB7A
+:10C2E000B97A9DCEE1C8EA4F63EDF359F97D504E1E
+:10C2F000EBFFDE5BBD9C8D4F04F6FB48363FFCCE6A
+:10C3000085C1FF52AFDFFA3B171DC093C7637FF7AC
+:10C31000607F32ED6FF43FDE9FC16FFEE17E1CFF58
+:10C32000B5FD187C18E81242F6483038EABF027EA4
+:10C330007F6F7B323BCFC2CF3F7DA0B019CE813E15
+:10C3400009B077A2ECADAB09C8A5DBB76F4DFA3BDE
+:10C35000797D791E4FA214523A33D1F3F39CAF3E4C
+:10C36000EF8B9F07C0F9CC7042F87B175455C9C2B8
+:10C37000901BB4FF46F077E34B4804F5AB51A41390
+:10C38000D352D28DE918D28B291E931682AB2F88F7
+:10C39000E99F2B7B2A60F18B1DE1872054D7EE08A3
+:10C3A0001F077CFA6058F8117807788D7BE924988C
+:10C3B000FFAF7DAAF17BA224E1F7D9E2BF2BA281D6
+:10C3C0005E332330905E4354F9FDBEF88D027C4706
+:10C3D000F8651FAE2FD5EFCD25FC8E25BF476CC06D
+:10C3E0006109E9C438885FEE5CF102BCEBB370BF51
+:10C3F00017E5C1F09D4DF87B620B497716DC2F1DC8
+:10C40000CEDF93206DEC1D0FE39D88916D76CB3BC5
+:10C41000164B127ECF6811FFFDB14589BFEFC5EF06
+:10C420006F6E840F49E20812EF7FF6FA52BCE75AAA
+:10C430009AFC776512EF7FEEEF1431BE6705C40BEF
+:10C440000971BE37724F9DDD8A5F9DD71499DE83D7
+:10C450006A1482CC9EF6BA427B85FEE38C53197E29
+:10C460001D1084A47164DF4C33EC9B26723DEDA754
+:10C4700071B1AC82BDD91875E13968A3CAECC2A10B
+:10C48000DE2A07D8E9C42FAA703F659A3419E3CB96
+:10C490009525F23838F73CB67B6137DC5F680CC80D
+:10C4A000E8A71DEA67E7A0648888EF0334A94FF87E
+:10C4B000E7C23E79D839E33095E0EFA11E695F29E4
+:10C4C00042BE919A2D83611C21DC8DF76E86C88453
+:10C4D0009FBFCE189B85EF98F138A556BC7F3C6571
+:10C4E000C96927C8F53CBEEF5569F9B84E99EFE721
+:10C4F000AEFA537EC0D3E7DB9B5F9E46FBB3456538
+:10C500008C6B2DF9BCF1F56974BCDE768598DFE3A0
+:10C51000CC5D255BEECFE6DC65CD2B09F788656247
+:10C520002AA7F972181FE148F544735C55668839EB
+:10C530000B550FDE0F0EA5094C2FE6F90AC85390D4
+:10C5400074D822552E3ACF8E3705F43B1C6D9F9F31
+:10C550008771FA3F09E7017E1BF890B87F4A9A6617
+:10C56000BCEFE1E4F7839D705897883F4D0DA41808
+:10C57000FCD18EE831D715B08F276CF89ED45AAE17
+:10C580007FCB1E16FF6EE04B62BA3601EFD67E7E81
+:10C5900023E25D2FC5BBDD03E09DAC6AA827D872FE
+:10C5A0004810C8C396D99DADD276573CA3043D141C
+:10C5B00064D37E5C9A06FACC15CFDDCCDEF5A3F011
+:10C5C000C27721EB9562B0FBEDF599C57206D4F305
+:10C5D000203E7EE861E73F72BD3B08E58DED150129
+:10C5E000CD84D7CD0D6AB15C0CEFE3388AE1779644
+:10C5F0009A53FCDEF330BF580DFE2585DBFF77A68E
+:10C60000B1F9DE99E6C674451AF35B3C28EBB360DA
+:10C61000FE0F52FC817881237731FC5D31C481F7B4
+:10C620009E573C5F3878A038A07D0D816280DBCEBC
+:10C63000BB6AD0EF51B9FC9813DE055BE175A880A9
+:10C640008F926FF8FD9301DF5FB0E1BDAF466F855C
+:10C6500036D7D49FE49B807E2549D4B3C1286AD9BC
+:10C66000F2D6B5F244C0177D0748A248DAF16B65EF
+:10C67000CA5F3ABC7AB640CBDBD25E60E583F41D7C
+:10C68000022D8FA6FD86E587E9D9F04B221D692F83
+:10C69000B37CB1BE03F29D69BF67ED41B7A07ACC10
+:10C6A000A1B4D7AF053DA7D1169C0DFE9D1FD1F9B2
+:10C6B00097D2F977F2F4A71C4E46F913F09DC2FB0E
+:10C6C000204F13CB9FE6ED0EA528FF292F3F9CA2FC
+:10C6D000FF9FF3765D29DA1FE5ED8EA5687F9CB795
+:10C6E0003B91A2FC055EFE628AFE7FC3DB75A768F4
+:10C6F000FF326FF74A8AF6BFE7ED5E4B51FE3A2FE5
+:10C700007F23A1FFB778FD1EFE3DC7DBF23ABC1BBD
+:10C7100096D3CE5E022DF1B6A0FEBEB3AE1CF1BF25
+:10C72000713CD3330C7CCF81784D9ABF52657ECD5E
+:10C730002B55C6E75FE1785DB9BC680BE0DD8A7F09
+:10C7400093509E523982BFE7AB2F67712F2B9E67A4
+:10C75000F741562C97F1F7800C7C34DA1BF3DFC5D8
+:10C76000E7D764C031AD809FB7048A6798E33D5531
+:10C770006BDE41E90942769A32997C29595EE518C7
+:10C7800001F283CA17E09B6B3D4A17DCA35FABCA7B
+:10C7900058DE9459A542B9AECA287FD6665639E606
+:10C7A000A23F271DFD13793C6EAF4995F11EBFECEA
+:10C7B0009F82E5D37E3C43053EDA447AFD95B0BEC8
+:10C7C00055329ED71EA9ABC2EF79FE8FFDC09F7F69
+:10C7D000E367703FE63DEE84775FE5EF88282F86BC
+:10C7E00003FCE8B805ABC4A846AB1C535788907F40
+:10C7F000B889C92BFAE71D6B7A77B16365C50B1051
+:10C80000BFD3B8490EC2790EFCC9267950C47FF750
+:10C810005453D32DF2EA41EEC7D5030E8CC32B92AD
+:10C8200049C0FC7B989A2AF17729D83B668511ABE1
+:10C830007CCA6FB1BE63F39FD7EF7F0B008000000F
+:10C84000000000001F8B080000000000000BDD7DD1
+:10C850000D7854C5B9F09CB3677FB309BBC96EB2FC
+:10C860009BDF4D801024C006420C88BA090122A229
+:10C870002E880ADAE286DF00493670A962C5B22145
+:10C880001103450DB71181825DA85AB462438B1222
+:10C8900031E88A88F8157B43AFF6A2F67A17A48AA6
+:10C8A00080B06A45FB63F9E67D6766B3E7245168AB
+:10C8B000FBDC7ECF870F1EE69C397366DEFFBF99D7
+:10C8C000CD23CA89A889E09F8BF984289A764EA344
+:10C8D00069B052C4DBF4AFD16553B52DB664C787D8
+:10C8E00049F41F5EE2BDA82364D9EE65932DB439E7
+:10C8F000E917C503A2C584AC30A58C2003685FF896
+:10C90000732D21CDAB3AAE19A42764EB2A3A2EBD84
+:10C91000367F3D7A26292524966CF1ED900859B38F
+:10C920008A8E3FB8A7FF681BBD3986906D4A683A6A
+:10C9300071D06B58214D745EAF2C9709B497B94DE7
+:10C940006123EDB2EC8DFFBC6E08B497CA5EE2E9DC
+:10C95000795F7B7D72956B307CFF2D3A2718571FCE
+:10C9600090069F1C4DFFAD045CFE644206B625ACEC
+:10C970009FFECD6FA5ED84F5EAF57E9BCD4A48DE9E
+:10C98000B7C04DEF7CCB1E2886F1151C5F3B8F6F27
+:10C9900083EB1AA9B1880CA4573A57804FC829874E
+:10C9A0009FA0EBCC5E71EFB8936984641DB2B400B4
+:10C9B0005C49DBA384A413A2836FD3752B92CF436E
+:10C9C000281E5AF24BBC12BD1E7ED6C2E0946345AF
+:10C9D0003819246FC6F5F46A94FD36189FFEF1C12C
+:10C9E000F80FE458B6AFCB8766C00470C8DE4907BD
+:10C9F000CC84F6C0B53E85E289829B8CA37F43BF81
+:10CA00006BF5D175ED94E2ED6A6877840DBC3F89D2
+:10CA1000C0FF76CB127B4EC7575C84EC9224F63C69
+:10CA2000E4ADAECAA6FD15DB30C54B48D056DAAA38
+:10CA3000CF81E7B278DF47CAE9FAE07BBC0D70F935
+:10CA4000F941F1BCB2B56A101DDF40C4F821E8BF5E
+:10CA50005B9679FBAA56187F57A5787FF05A5F3608
+:10CA6000CEE77A9D9D90FBDA26B65ADD3DF37D68D0
+:10CA7000C3F5AD4D747D9F78A2297419A47EFBC9BE
+:10CA80007442875A3333E007380261FB8713724AD6
+:10CA9000F220BD08FCE9F75484B2E8ADF387FE9CB0
+:10CAA000524CAF415DF45012855F7D67C0A42FA04A
+:10CAB00070D6FB4259F93DEFD5EF994602946E824C
+:10CAC0005D2578EDE3BDC38AFC77BD67325CC2F7B4
+:10CAD0003E89FCB6E119FAA85E1768B50EC4FE845B
+:10CAE000E1BFEFF589F73F79E6B7B7C2F7CE79A294
+:10CAF000E953802E23142E7DBC27FA37745610A0DC
+:10CB00007B29C9B7DEE624641E853971027F357A38
+:10CB1000A17F87A9CDE6A5CFCDFA36BF97F6A7A806
+:10CB20000CCBE53DD7876D83703CED7D2DFF749870
+:10CB300048DA544AD7A13AC5FB0481762869046DC6
+:10CB4000AFAF574637D129AD2EF9DDA862683F67F0
+:10CB50002546DA6EAE3BE82A063EF21A08152F6427
+:10CB6000FDD80E37F0714BBD61E6E340BF9165AE75
+:10CB7000F9C53DE33F64D7E33CD6BE46F96C24BD1E
+:10CB8000EA3BEC12BC3F5821C087663BC5336D9B26
+:10CB9000DDA924940FFDACEB811FD7EA03D595D016
+:10CBA000CF2D9327E877CD83675457D279B89CB2BD
+:10CBB000A4C379541D5B409F37DB0C20D9C87BF69A
+:10CBC00039CF019C7EAE781B810F7F6EB5DA42F4BF
+:10CBD00001958D3EE05B65B0230C6DA38E3476D05D
+:10CBE000F96595107F87B5679EEF71F9F89ECD8046
+:10CBF000705E6FEE985641C7B12C936D21FABDB5AA
+:10CC0000F51BBB27D1EFFCB8FEF9A34DF4FEBA74B7
+:10CC100085C03CAC0E256248A1747C039D239DF722
+:10CC2000AE26BF0DE467CCA9901DF4B9659081785C
+:10CC300012E4A0B598B613E4539A43F199E9FB7F47
+:10CC4000B2078EC0FC47BFF99609DE778D9165600B
+:10CC50009B0E85E139A5543D8E6DBC7A9CD42AF596
+:10CC600073C754F5F3F419EAE7AEEFA8DB99F3D4F0
+:10CC7000ED5B80DEC640473AE732BA0EF68858A22E
+:10CC80009FAE2229089F7700FE9642D90BF031D73C
+:10CC90003F7E6A017D9E05F284CE9F8C20E127288D
+:10CCA0003E0FE47EDF13A57036A6367AECC5BDE1F3
+:10CCB000919563BA1EF0651DA4D808ED6FFDFDC700
+:10CCC0005FC3F85692D02F1FE0E3FBC43686B55DF4
+:10CCD000743EC9F00F0FC0BBF17FEE03BD7754E780
+:10CCE000057867D52BF8FD076778C2BA7CD69DD04A
+:10CCF000FE29BC7F8A697DB76E04BDFE7EED525D64
+:10CD00004A6FB8A6934609F892D207EA0B524350ED
+:10CD10005F3C20935AA01BCAAE04C6B3C10B54CECD
+:10CD2000F8530D0827C5CEE887FE4B86E7E936366F
+:10CD3000A6C13DCF0CFC7CFF2146FFF71BD838F184
+:10CD4000F13CF851544120276D765935CE461BEF02
+:10CD5000C3DB4E3B6BEF3E987A3DF0E5C619A9A3C5
+:10CD6000804E8C3209C07803B24DBEA1747DE63787
+:10CD70000C21890E3A402107F5A9B4BF85DCE9A74B
+:10CD8000F3D87CD812D2D1FBE6F9FF6EA34026255A
+:10CD90007CDEBB577BFF13E440AC4641389A9D6D67
+:10CDA000B651C56C0D213ABF54F807958F1583DB3A
+:10CDB0006D804F73451BEA6F73495B1BC069F35469
+:10CDC00019ED89D47932D2B339A7E3E8207A5F3FED
+:10CDD0005FB6C178A954B11BE8203FCA6EF3FB616E
+:10CDE0005C0A73B98C910A8C8B2BA4DF49E37075B4
+:10CDF00038F6DC2DD171D260BC11AC3FC0C9CEE198
+:10CE000034D6EE413E75F071D306D1FE23D8382DCD
+:10CE1000653DE3083C6EAE2661989FF8AE18273E4C
+:10CE20003EF1492057F5BFA670A37892724D38B9EC
+:10CE3000FB1793B0311FE0E36FDC8E7C6D253B80E8
+:10CE40005F1CD99540479987B74C9747C07B16FC24
+:10CE50008E7E3E09031D672AC4744D2AD82F7E8416
+:10CE6000A3965FDD07DB6EA63C12C78B967FDD0ABB
+:10CE700069D5A5F6E663B7C3515938A20F7ED6F03F
+:10CE80008BFB70EC7B40F45ABE7E2CE95C09C085BC
+:10CE900024F6D77D7B5BA7EB383A09909541F504E2
+:10CEA000057DAEE67B84FCCD086D89C89E8B034171
+:10CEB000EEDB391D537D459975F728DB042BF0E92E
+:10CEC0005282F455B977FDEDBFA6E35D186CB081D1
+:10CED0005EC939DCD60DFA91740686001EB62A8129
+:10CEE0009F24D1E75B8F651090DB6BCD6426D0B7B4
+:10CEF000C2E95CAB5F1E02BE71226B8465D7DF7F27
+:10CF000015F660C7A0F461361B8CFBFA6193F37FC2
+:10CF1000D1CE0A0D433B2BFB60779315BE6F9BDC94
+:10CF20006AA2F035BFC9FA3F48DBA14100BFBA3C55
+:10CF3000E0C303390B104ECABB4602743A5CE70BE0
+:10CF4000439BBC6726207F773EF79D5A0FC89FF40E
+:10CF5000291E90433F017EA7EBD9C6F95EBB7EC573
+:10CF6000E00B803DA1BDFF685C2EF94FD5503C0E13
+:10CF7000FFA981ACA30F8BE439ADF9C0176BA9FCF5
+:10CF8000A54FE7E83C0D3F947AF0D369AED86587AA
+:10CF9000EFAD32918091AEEB2B89042873E6387E99
+:10CFA0005B01F227974424D0B3B98DD4E005BA5A77
+:10CFB0006E2181047ACFFE4AC1FE9D66DF2E3B972B
+:10CFC000FF262A07F4EC9FE4E7A97E52E360320AC9
+:10CFD000EC17FD3396E3203788A3CA17F7370A808A
+:10CFE0007EA9DEA7DFDBC7D7ADA76A423F8AFEB5C1
+:10CFF000CA11E388DEFD5FE6FD14933502F252B1FB
+:10D000001E3986F2C5A69C4DEC670A337D43EA487B
+:10D0100078B0C4E082ED7FB3613B8BCA5FE328B494
+:10D02000FB434698670AF33F88CFE771A403BF101C
+:10D030000472B689B49A683FA476CA6F6ED26D4600
+:10D04000BBF920F1003F5088D9C13F845B00D7ADC8
+:10D05000845427F281B88EB4313E5056E8D05F1A1E
+:10D06000F6AA19E7A36F246133D84330370A6F65F6
+:10D0700039092BE06FAD3060BF91360FBE67208D50
+:10D0800068CFEEFAFAFD4C90D39643D41E1B097874
+:10D0900096514E592C6AFE23A409E1F409E7BF6DAD
+:10D0A000AB6C88E7B87F16788BE339DA04FA22771D
+:10D0B00079AA0ABFA25FF6575924303A71DC308E44
+:10D0C0009B3DE8A0448AE1792E3EDFB6CAF32DE30A
+:10D0D00017F433BE1BE9A8FFF1B3F1F9B6C85BF64C
+:10D0E0001B2928B6C60EDAFD9E1EFB5A0BE7ECE59F
+:10D0F0006AB93CB253DD167031EB7D8E6914E6E6F9
+:10D10000EFC9DEED74BC2B8FA9FB55E7BF8DFE6D1B
+:10D110004FFF88E366E84FFDEFED201D4EA9FBFBB6
+:10D120002B5EB3031FF7F467F3BBF62B753F2D7E21
+:10D13000B4F3A5F372DE9230AF0926A3EAF9CC9AD4
+:10D140005EF372DE9630AFC92E75FF4053DFF3BA3F
+:10D15000BEC8F88DF312FD6E2ABFB47EDA75DC5CB2
+:10D160006DEC07EEACFF6D332F6DDC3B6ABFB9DFB2
+:10D170009D2BB4DF0921BD5F2FF97CA9F43A076E1E
+:10D1800081BD68B5A0DDABA5975D5C7E4E067B8E4C
+:10D19000F69F95EC9B9C4ADB1305DF3DF5BBDB411D
+:10D1A000BE1C7EF68A0C90EB59A0E7109E2CAEB008
+:10D1B000BBCE857185EFF2FE549FB480BCD8BD9381
+:10D1C000BE97C2E695683FA5D531BFC24662C8CFBB
+:10D1D000C25E4A253689F9E3CCDEE9EF3BDAF1D7C6
+:10D1E00071FF73EE8A09E403CA87CF1B6C150AF836
+:10D1F000678F49680FCCADF2E992297D8C6B953031
+:10D200006E34F79E7F1B0D7265EC494F6794DE9F6D
+:10D210001BB67BE1B30DDDC417A67495A15B5A72F2
+:10D220001FBD3E7280DA3FBCBD14E8CDEAF380BF7B
+:10D23000510333A2E39CD53796D8406E7ED7EA03DC
+:10D24000B95933C3F70EAEF7AFD42AA1FDE6B3A5A3
+:10D2500093BDEDD30C1E6A67D47CC7530E764F4D39
+:10D2600087D9875713512C741D35D41E836B868143
+:10D270002866B85A8809AE65AB99FD9552EE37D449
+:10D28000D0EFD774FDEC0B786FA1127985D993613B
+:10D29000C45B4DD71B7F027B6DBECF6F0079316CB5
+:10D2A000A781D9A49C1E8677A8DB200F12DB25114D
+:10D2B000757BF46175FBC35406DF7D527818E06717
+:10D2C0001F5570E017877619515F1CD86F44FC2CEE
+:10D2D0003963D90EF1A7094BAC28D7CF3C6DC6787E
+:10D2E000D43EB9E35968879E4D42BFFA9577F795CA
+:10D2F00049B4BDF817C9323C7FF16B1DC21996A322
+:10D30000A7F7973C3B74FB3A7A7FC9E88E321BBD86
+:10D31000FFFC158474C373253C02D6F7FCDF743818
+:10D320007EEC29637807A587332FFCECD97BE9F7DE
+:10D33000CF3C95952A51BC5C05FA80F61BF75393B8
+:10D3400005FC8C71679E1908F262C94EA36A5D4F95
+:10D35000A7327B83223305E8ADBF78E289B53FC3AE
+:10D36000F78B4E1D437ADBA70FC91658FF5A465F4D
+:10D37000DAFEBB5399BE11F380F7F2297ECE7F6CA3
+:10D38000B913E2684336A9E13B34AC6EBF90CAF4EE
+:10D39000FB1C92703F1FC62B58E3023B753B417B41
+:10D3A000A6E8D4EF6FCF073BDAC8EC07ED3C0EA43C
+:10D3B00032BE7EFA693A0E930F3A663FD315537E1A
+:10D3C0005CC2E9F84589D9AFF4CFF22C4AB74B409B
+:10D3D000F117F4DC5FA2998718FF077C9D0EEE57CA
+:10D3E000C7DED4213E4EAFAA1D7D7270EFF97CB826
+:10D3F000AA716895BEA7BD60D3D2436EFA5EDD6E9A
+:10D4000027FA89E27EDD53AFA6DF41EF9FDDA978E1
+:10D41000C174AD9BF5E443E3A0DF53BA0E982F3CF3
+:10D42000F7D1F59EED782D05FA2DD86A1FA54BC0D2
+:10D43000C3C24DDF1B5A95200F2F971F04FFD671D3
+:10D44000FF766F79F7A42CA0EF4D9217BA2DE9B8AB
+:10D45000E5E61BC056D9AAF30EA6CFCB14E2D78DB2
+:10D4600042D77B065CEB763F7728933E0FEE1F5347
+:10D4700006EB5A27FBAF1F0EF4FF981EE3585AB86D
+:10D48000FC85E39BBE1F91E9FBEB6EB5D686AD38FC
+:10D49000EE41681F28DAA183387BCA292A9FD8FD6C
+:10D4A0006332E5C9535DF78F8078E23EBDB515E87C
+:10D4B0007C5F32C34368970EE53C89B0758CE3719D
+:10D4C000E325FFDD6E50E8F5D4A9D529158C8F50E2
+:10D4D000BE805076D0F5D5FE7438F2DDC24D6A3E7E
+:10D4E00011FDC47C1785D5CFB5F4919526E20DA426
+:10D4F0002891CEB4FDD2A6860CC057752BA83C4E01
+:10D50000B07FEA4EB619C06ED27E072C4022F0AA38
+:10D5100043FA241E5CAF99AD979AAC26BADED3F0DD
+:10D520002F16F796C02F5F2CE112C9922B489587D2
+:10D53000C273C974520DD77D52E4211D9767187FBD
+:10D54000DF9584F2ECAC2DFAE48F81FE9EC9F18662
+:10D55000E8A34C1E973BEB89A4A4D2EB79E00BA087
+:10D560003F1B6B2FEEA2F29CF2F7994F0C28D79B32
+:10D570003A5E4D017C9D7DD62CCB142F6776A75546
+:10D58000423CE76CC7AF53605DA73BD22A212ED740
+:10D590009FBCD1CA29A1CF8FC33FC7526598E6BBB4
+:10D5A0002A0DE4564B1A18E32423ADB1A4B10FFEA3
+:10D5B00017EF390C8D251E901BDFB57A77303811A7
+:10D5C0001F6D7F76386D07E05BC8A91A898D2FDE45
+:10D5D000BF318EC76F968FD5EB86621EE833E21996
+:10D5E00000F27A1A287AFADEE1570A0780BD20EEA7
+:10D5F000373AFD33D2E87D5765B74F0771C429C468
+:10D60000DB4CBB7EA0F3DE65A3F89A47A8FE826BD5
+:10D6100069C08071971627AE6FAE42220AA5F7B98E
+:10D62000A05F47601BF13577AB146EA6EB99B75E30
+:10D630000DAF05EDC61E3AA17F17112A608111B703
+:10D6400026F4A3E32F023D4AF1B0D844224974DC0A
+:10D65000C58FABDF5B4222389FBA672E1AFBC2C769
+:10D66000171C1F8D4E5F7D9A4A0EEA510E2E21FE29
+:10D670006BE0BB4B84BE7E8BE12B78CF3D43E75103
+:10D68000FBE3FC8A7B87CE4B837822F1811D41DA54
+:10D6900093918E975491480E9DD7922E29323CA596
+:10D6A000675CF24B89F96744C1F57FF116C3DFED82
+:10D6B000DCEE994F6F831D7115F8EF80EFCD12CE20
+:10D6C00063DC33522899FA49F34DD4C503F9C4D722
+:10D6D0000BFD07D0F6421242F83C9C968F785B44D3
+:10D6E000BA0D8C7FC2CDE9F4BB0DA7A84C2297429E
+:10D6F000076311DF9F132FE2FBDFE3745086F421F1
+:10D70000EE53FB8698537BBF0F78F325C0B976ABF9
+:10D71000BA4D1E4F6817005E683B015F0D7B2E1AE5
+:10D720007D7DE0E991B87E0B0F9D363C913F98FDE1
+:10D73000FC3EC7E323B72C70833C7A18ECC94C3EFF
+:10D740004039C86F22E22311131DDF329AA8E22567
+:10D75000D44EC3F62FD2FEEBBA4DD9846CD4073029
+:10D76000EF3057E73F0429B281E9815F01DDCF95B2
+:10D770007DB90AC2D557887EF30A460F8F8E6A1C80
+:10D78000DAD887BF2CE6BF51EA88C8209F5E60F6D2
+:10D790004672694C1F48E0F737D3981D33E040F4D8
+:10D7A0005016D0DF7312C6F7374BA445A2707651DE
+:10D7B0003C835EDA2C1D3F047A6CF3751ED24C9FBD
+:10D7C00097EE99B6F435F4B92D5EC897D4EFA9D089
+:10D7D000D55B71FDCCEE4D6ADC2ED3E71977168D43
+:10D7E000023EA3EBBE733ABDFFDB340FC2CD6D65C5
+:10D7F000F4E35A1DCA5F06F1DD03FEA5AF01DD0D9E
+:10D80000B7601C2D83C22A3915AFAD60CFBA4893DB
+:10D8100004FDD63825C4C79A1A32F397C548CDCA35
+:10D820008054763D46AF92425A202E9CA150FB98E0
+:10D83000DD6F81EF3C92C2E6E59475774E03FB7C89
+:10D84000146BA7AE947C3B508F6D403864184935FB
+:10D85000AC1BEE833D4FA7E1DB8DCFC338EF8C09C6
+:10D860008D25308F8C81ECEA3044B2619C23824E4E
+:10D87000BADC32E88DE55CFF2FDF5D91914ADF3F36
+:10D8800072D6A4803C3FE212F668C40AF628195406
+:10D89000C4FA733DBBBC64420630B52357DDEFBC10
+:10D8A000DE376034E8ABA33ACC1BFDD1EA1B60A79E
+:10D8B000FDAE32B07568F1AF7330BC06BF92483828
+:10D8C00021FE109C7901EDFCE0578AEAFED955262D
+:10D8D000124E883FD4D51E9804FDEA49F71AA0C716
+:10D8E000FA8E24124EE08FAB2C7D7F57F045F02B43
+:10D8F0001D098D46B2CF8638E9117D6CCD7CA0C361
+:10D90000FD12C6B382D4AF0F25CEEBAB34124AEB77
+:10D910006B9EE9EAFB743DAA76E797D88F9447534C
+:10D92000E03BE76CD1143B5F1FF413FAF77C580E11
+:10D93000E947629E92E96188335999FE9A06F85543
+:10D940006229D3937BC615CF61BCD484759E9B6935
+:10D950002011C44B0CBF0B700B0D21644BD7A706D5
+:10D960000FD8235DAF20DC04BD24C22F9498B76A82
+:10D97000EE8EC854565CDD9EB3AED84C517580CB4C
+:10D980008550DE3ADF78FA5C27ABE44452695C6E7E
+:10D99000A0987A04B2681857F5AC83386BBCCDFBFD
+:10D9A000C7DF0FE54FA9A2E39516B3F727B717FC1A
+:10D9B0009FD5A003491BD3CF4A2CD79F9CD0366953
+:10D9C000DA56DA1E9ED0B6699E3B34CF5D9A763623
+:10D9D000EB7F363992ABF31232BDBD708A42E5D689
+:10D9E00059776436F5A8C97ADDD02955B45D5FCA88
+:10D9F000F47A4397E44535C5E1D7E06576ABD51BAE
+:10DA000035CC2D0638741F02B952D729D924CA073C
+:10DA1000D68EDD116CC37B9E84F73A247CAFAEE3D7
+:10DA200038BED7EFF84532F2F9BAA213AC5FC74758
+:10DA3000683FAC69A9C1FCBEC85FEB88DF9725F5DC
+:10DA4000E4AF857C3DE7F6BD2A33BAB625FA7341CB
+:10DA50001837216E24FABF37BCEB6D304F92967F9A
+:10DA6000DA04F6F47FD77F3406ECCBF7B81ED9285A
+:10DA70008587C277B790C050D0A3DFAD1FFC8A4C1A
+:10DA8000FBBDAF8F6E831CDD86F66B107EEF2747E4
+:10DA900073242A637EE4B88EB59DD16D00CF8F1DAF
+:10DAA00053A628749CF773A239326D3FDABE9CB539
+:10DAB0000747B741FB654780F51F1ECDD1D9C0553B
+:10DAC000AB9952459F3F61EB9B9F5BB91C11F333B0
+:10DAD0000FF4353BC07EAC63FA671BB57F4D545ED7
+:10DAE000CE5E7C7AD713140EB3BF9F8472EC89B3D9
+:10DAF000374F61FE41C8AF9441FC97FD41FD8872EC
+:10DB00005E41FBC20D3A31B5071FC9B9DD1ED41FF6
+:10DB10005734EE06BB25637631EA8FB169BED3F088
+:10DB20005D71FD4526BB9E76D8985CD6C9980FCF0F
+:10DB3000B83719EDBA87CD6C3D946F10BF568E8FF4
+:10DB40006D0E66976E7330FF7649DAC4D30E7A7D18
+:10DB500057F26D3651B8BFAB272133C8D94516B43B
+:10DB600097EED84EE50695DBED7CDEED1BDC61C85B
+:10DB7000E7DF21113FC815213FDAED3E776A825F6A
+:10DB8000D45E42DBD61E3FB87D9ACF6D71C0355D45
+:10DB900086BC8F904BEDF9EC3DA18F329AD977324C
+:10DBA0001E1EBA03D691A4B0F8D5FC99853B9AD035
+:10DBB0001E988EF3253E9F1BE220271715C810D70D
+:10DBC00012F8B962A06F2FC0E5769E17107812F890
+:10DBD0003CCDD73D5747ED09BADEBF380308476A49
+:10DBE0005F8CE0F133B42F4E836E4F802F51A263D0
+:10DBF000E0FEFF4770FA3D3CFF47E154BF82CA0B8D
+:10DC0000F912E40587DF4629A2CF60F202FD79B858
+:10DC10000F7AA7332D1083F1C5F767DF5B8FF6A46A
+:10DC20009857D2DD7BAB6F23BDF94C6BEFFD19F03C
+:10DC3000E5ECB14BBD220ECABFF3FEBB26CC7BBCCC
+:10DC40006FE840B9F93EF5A39A40BEF0BC7DD9F724
+:10DC5000971C017F548C1B70EA70BCB592CF0DEB02
+:10DC60005B4BF16E82F94F33A0BF21F46ABB3DBC20
+:10DC700019EA26DA6FC9C6BA89F384D5A78456246F
+:10DC800061BFABE41304E2AAB1B136CC9B533AC1F5
+:10DC9000E7EDB30AB17E85D243C80CCF293D419D43
+:10DCA0005F7B095D108C37EB0A7C0EFE3AFAD9B324
+:10DCB0004C385E1F74C2E2D443587D467B3EA7C3F6
+:10DCC00045054887E9CD2C1E4A14DF8869097A7E0C
+:10DCD000BC93E139A934FADC7F01CDAF37A33D0B0A
+:10DCE0003A16734A6D19381EC5FF60278B4B209D6D
+:10DCF000CD7B2899D7C379CB00AE0F2433BADC6A29
+:10DD000066F9AEADD47E46B9C8E957D4E105B89DF1
+:10DD100017AD9553C05E18ED8CC73B7C107FC07863
+:10DD20003B7D3E272A1D07BF6F4E481731425CB826
+:10DD300075A22F9AE0BFC01FC817DEC9E52AD944D3
+:10DD4000D0BFBA13DE4B81F12D29901FBD13DE0722
+:10DD5000FF71E544551E7022C8F0313DF3D3CAFD72
+:10DD6000894E1EDF6C7BD497F81D31BE763CEAC726
+:10DD70004E723A11CE9101E04734E9108FDA7946BC
+:10DD800037B1B87974531ED29D18AFBF79FE8F2E6C
+:10DD9000F63D89EAC10513987F2FFC9EF9DCFF262A
+:10DDA0002BD57E1DC479E26D5DEFB6D64F84FCBEE7
+:10DDB000BA3FB35B928A6306CCFB7824D5FC05BCE2
+:10DDC000FA83439DC0E725C24DE8BD47CD549E521E
+:10DDD0007AD904759094BE36DD93847ACC61080FAD
+:10DDE00005BADA02F535A84F99FFFEF91175FC4521
+:10DDF0008BBF1FC4E9EAF2FCEE26C0B9B3B7DF1D42
+:10DE0000B4C41E03F8072D8C2FCFED4F46BE2283DE
+:10DE1000A2B3A1EEEDFC3E23017E6890A2852027EF
+:10DE2000CE49BE1AECD794E401FEFC406671812015
+:10DE30006084AE3318FA0BD65B053BD57EF839FA11
+:10DE4000B796F2CF39395A06E308F902F204EDAC7D
+:10DE50005A96876A904908FCB4ABE4398BD09E98F7
+:10DE6000954976E0FDE385E09709BD41FB1D94529D
+:10DE7000191902FFD5717C34C827B05F1DD44D013C
+:10DE80005EC05F83781F3C4C885337AC3F83755B23
+:10DE90000D7BD47453D74357D24509DE4BA033943E
+:10DEA0000B218423DAED2047AA581E3D99B793AA87
+:10DEB000BBB18E2BC8E32FCE03D149209F924B3BA1
+:10DEC000C81C7A0D9E6276CBB8AEEDAF825F6EAFA6
+:10DED000EECE01760AF278A7A01B31CFB15D1B749C
+:10DEE000E0370A7B27C16F1D3A5D15B7588DEF816A
+:10DEF0001F0CDF8BC22D379015D3931BB99E4C029C
+:10DF0000871AF469DB10D4A7A0EF40CE093F1AE4CA
+:10DF10001ED0D5C0F4CA23C0F72FA657BEEE74B2E8
+:10DF2000EFA17F00CED7D8FEE94EC047F4037FFAB9
+:10DF30009BE3905C7E13167F5CF686F31BE9FFFD86
+:10DF40004BA6FFA11940E7CB244F06D0F9F138FDCD
+:10DF50001762BE52DCFF5017C038A388772D82F8B5
+:10DF60001EBDD67139B480C7C71688B8D826755E6D
+:10DF700015E2D189EDC5224EB6D3D8536F04F2A372
+:10DF80008A4492E978F51067836B87FABD061263BD
+:10DF90007CD479D1A8CADBB63338DEC9E9C95E15AD
+:10DFA000D681FCDA6C66F13221D7C6ADDC8E7432D4
+:10DFB00060942FFF7EE09B37F4186FF903A70301ED
+:10DFC000974667E551C0A745C7E381F71B519E9F60
+:10DFD000A476C26E1EE7990EFEF1AAC050A897273C
+:10DFE0008A2D37D17F16D775FBCCB5687FA7CB2A92
+:10DFF0007A7DDEC9EA9B30FE85FA2209FD012ADE20
+:10E000004600BD9615087D4D4640DCEDB89EC5CD59
+:10E010001B6EB50660BCA8CCE4A13B9DE929773A0C
+:10E02000AB5714EDB8FFC9E951E443210E95988F21
+:10E03000F0C4FB6FE075C804D7BB7111AF778FF3E5
+:10E04000858CF22DA9D88F7AE12AB912E55BEC63B1
+:10E05000AB07E0527DA66E11ACE3B399160279C905
+:10E06000793C1EEE4DB7E3B8228E7DB9F1F0D1E9CF
+:10E07000717A54C5C3F771B9B88FB0F9865A8C2C30
+:10E080008FC1E7BFEFD41561CE1F21909BB1DD6634
+:10E09000A68FA99D0CF27ADF9E216158CF713DB306
+:10E0A0006742FB93F9FB81CD10A7D9F74BA717EA7D
+:10E0B000A0828B4F8F00FB76DFA9A77FF51BB8BF2F
+:10E0C000DFE8057F741FCF63D419228568CFF3FA88
+:10E0D000CFBA944821C4A55EE4F8AAB3D036BD7F78
+:10E0E00083293035DDD9936F84F7E0FE8930F31B47
+:10E0F0004E104607A1F52C2F4CE1EB8679C4D6666D
+:10E1000060BE12D60578F860FF709CF7463DEFFFC1
+:10E1100020B32F4FF0F689174AB01EF2BCDF80F50E
+:10E12000CBC187993D3B57F63CB60264EF4B49188B
+:10E13000079DDF7E14F347C187164E85E7C1C52BC7
+:10E140006F24DF9057013D9518C73F4762B9E8A794
+:10E15000D7167444E877CF750DF5B2F4A80B937118
+:10E160000DBC4EF624852FCC3BB65F8FF0BFD4F1AB
+:10E1700031A059C6F4257C279898BF42FDA2CE67EE
+:10E180007D5BFB9C3E5A780FFDFEDAD4C00FD213A4
+:10E19000ECD8E04B6E94A31F3CF8652EDA3B6D2C57
+:10E1A0006F7252EF9B0D7C62AF8A18E624C8D78D40
+:10E1B0009C8FE71AB95D4BE56022DF8BE765956AB6
+:10E1C0003E13D747D2995C4EE6F512BD9F8B7ABCC1
+:10E1D0009B8DA08F59C80BC6F5E0FD3C9EC71C77F0
+:10E1E0002AF60AD49DD57594609E346F6504F99221
+:10E1F000C23B02FEC9C9CDC94C9ED065C2380BCA0C
+:10E2000009DAD50B74ACFE638191DAE9CC2EC0FE3D
+:10E210001F6ECE403894AD66F669EC3909E5A2C8A8
+:10E22000E7D610F6FEDE96E3211DED5FB3532AA17B
+:10E23000A295D4B454607DC8E2ADF988FF715CFE4C
+:10E24000CE35FA0A3703BDED4D467AA3DF437FA0F2
+:10E250000E6AE046A15C32807EADDD29617E44AC71
+:10E260005F9B3F256175DE695C0793DFA03748A29D
+:10E27000DDC9F510E80BA2B16FD57411BA247DAADF
+:10E28000D50787E372F2F2F4E9AF417E8DE9AD4F35
+:10E29000A9BF70249DD10993FFBB59BEA99E34B27A
+:10E2A0007C1BD767F175717DF8A18EE9DF05C60D7E
+:10E2B000783D9E9E8FF35A4CA23CEF1433C0FCFA7B
+:10E2C000A3AFE3FDD097A0AB139CCEEA4E91C8D587
+:10E2D000F47B752B49A47E04BB268F40FDCEF4BC95
+:10E2E00089E979B85A2E41DF6BF5BC56AF6BF579E9
+:10E2F0008681E96D414F89F907B093C6AD0CEB58A3
+:10E300009C39DB86FBEB387E97A4F92E668EE9B14B
+:10E310000383C74C26CF4868FB498115E26715EB9C
+:10E32000B2212F40F500F06F1285D376888B71FFF4
+:10E33000E3EE6CB67E17AF93D22B7E5262053C752E
+:10E3400063BC20E624E8BF0BF86E4BA6EF8D82F786
+:10E35000185FC7DF3791164BC2FB95FBCCA8972EF1
+:10E36000BC908C753D54CFE4D9E978E9EF51BF8179
+:10E37000B6CFED4B463BE11CD71B0E1197216B101E
+:10E38000BFCE0C86E710A9CC82F83691A66481A88E
+:10E3900015F66CBDBDBF7C047F9EDF7D2BA33323B0
+:10E3A000EAEB0BF6E85DD0A6F3C13AECE40C36EFED
+:10E3B000E09E0925F742FD85DFEA65500D9480FD5A
+:10E3C00061D42DBF15E25E93742B63F7D075D4E74B
+:10E3D00058B1BEBB2AEFF7BF9B45DB1FEFD113231C
+:10E3E000E0FD899B0744E035C5E7EA8B4F1685F5CC
+:10E3F000AAFD834B76AADBF51DEA769024EC2FA4C8
+:10E400002058F1FB926B0E26D0495946B2E3C36106
+:10E41000C096C40BF5E944F79D01813EE4AEB87E99
+:10E42000B9CA7BCD413DD6F75D9DC1F8D900F6D183
+:10E430001CA0873EDEFB23E77BA3B1F114EC133075
+:10E44000BE68F436D1B7CC198149F07E831C3B04F9
+:10E45000F834E69D1D01FAB432EFAF9827BC701F67
+:10E46000F1027C2E982BD04EBAB0D9EC017FB13D91
+:10E47000D7CAE2322F496189F91553C750F95A8B2F
+:10E4800053A1EBDD74DDC76C530B31C9885FEA55CE
+:10E49000B9405EF9D0CFFB709AC5B69ABE57BB891A
+:10E4A000E9ED3AD29D0272E087803FA06BDD330632
+:10E4B00013FD677E8B6F68139DEF12BF05F733293D
+:10E4C0005F2B7EA0AF0760C804BF644E069307F5BC
+:10E4D000A6A8A102BEFFD779D5CE829E389E41CF95
+:10E4E000E2784A6749248BBEBA70C55CF4BFE2F992
+:10E4F000FACDAC8E6CE13D3578FFD5CD465CDF873B
+:10E50000FB25A4F30FB7B1F52FDC64F640BDFBB5D6
+:10E5100076E6BF2FA4EFF5BDFEC91FC3BA3EDA7A77
+:10E52000B717F2101F11F69D908DC5DB3EB2B1BA40
+:10E5300002E80BE37CB46720DA43B59B164DC5FABD
+:10E54000BE6D3A2FD823647F32C6B1166EFBDE6FE4
+:10E55000C6429C6CFAEDA500876BEDCBD3212E440F
+:10E56000FBF9C3CCBE6675D3A9E54F021F5EFBF570
+:10E5700084EE6BC1EEDA46F9249FED4B007BFFE0A1
+:10E58000B6C968DF2E9C66B1C3BA3C5B9F98047A1B
+:10E59000E8A3699932AE6797446C0007FB8A74B8A8
+:10E5A000BF5052FC7DD1537E860EE15A9167F546ED
+:10E5B000E0BDB775482794AF6E053D5CBF4D8FF643
+:10E5C000F3C1E9EFFE6E96A387AF16EADA6E1D97E8
+:10E5D000603F05B7DE20E88444CAC02F6330D1F223
+:10E5E00097316F6521CC47CB670B573716B2BCDC30
+:10E5F000E5F11BD9CAF8EDF10C89C56F2E9DDF7EC0
+:10E600007E39FC46B25355FAB7B75C0B613F91D7E0
+:10E61000307989EF092BE6AF7D1295BB6F6528F83D
+:10E62000FCAD0CBE8FEB4FCB76BE49E1332B23B054
+:10E630003F03EC28E22B013AF2C46C95B047CBCAF9
+:10E64000ED41B295D9DFE02700BE373AC993EB120E
+:10E65000E221DD196C1F21E5FF4330CEB977FE7A48
+:10E6600008F0D3907B7604CBEBFE11F3A0D62E9668
+:10E670003FB77A635857A077F891FE845C0F7A9978
+:10E68000DED1AE2BC3C5FCC2A02386E37CE6627C50
+:10E6900028F20A5B5658301EBCC51136B37847883D
+:10E6A000805E9A5AAE63F93F6EAFDDC0E3ACA6D28E
+:10E6B0005709E4FDC878566FF766E9AB4A1A6DFF53
+:10E6C000A67CA217F73996FEB4B500D63D5ECF9F63
+:10E6D0000F0CC1BAFFC35781CF97B9741EE0EBA9E5
+:10E6E000A5AC6E94D4A6601CE7CDD20F1CF312E645
+:10E6F000EF27268F95D2C974EA2C25D639DE38DE6D
+:10E70000ECB126D0D7676D5235B39B3D03660C67DD
+:10E71000711AD4C3A56A782C7319F0BB2FA6577C45
+:10E720000A70BEF61A868FD3BB8C61907FA7F9BEA4
+:10E73000A15E74E1E2F4F39D22551D82C3D0910BDA
+:10E74000FAF18CA47E6F71AB0EEB0016B54A244C27
+:10E75000BF77FAA9BDB920C73F7E626FEE9C84F9EE
+:10E7600068DF13578BF81E8F776AE3D7FDC5AD4579
+:10E77000BFF39B48C034B0A7FFF9DA3F63DC7A4EA1
+:10E78000178F7BFB7C831CE04FF1FEDAF146BB194F
+:10E790007D489D12C64D44DCF6C4E19F4286288E1A
+:10E7A0003F7357BE9C58272AAEE338DE6E06BCD1B5
+:10E7B000A5985B59BB3F7CF5C78FFFC1F58FC0DBC8
+:10E7C00089D68103008E8606AB42D8FEBD22B0F703
+:10E7D000B7118B17F8C990E9B282FC12E71F7C6968
+:10E7E000665787855EA9BD96935984EFDD2DFBB1F1
+:10E7F0001EF14BB90DF76FDEAD6BC43AF73217FB64
+:10E800005EB6CDBF7B01FA391D58F74E5AD5F04D93
+:10E810000728809EAA31A09E1270BE6ACE5DE8EFE6
+:10E82000F6819F4D403799E5EC5ED095CFEDE52818
+:10E83000E643CCE5C4067181E6B1219C8FC04F90C0
+:10E8400075275297847632D4EF24A562DE37C4AFA1
+:10E85000C49A4AE2799024EE1F134DDE838AAD10EC
+:10E86000F413F304310675400FDB3BDA0A59DE1866
+:10E87000ED4F1817EECF2956306F00FD0CA3BE9D4B
+:10E88000DEE274C9EB3BA78AFBB5963EF32C5361DD
+:10E890009F14ED9F43F520D87FC4AB57ED93DA4A20
+:10E8A000ED66F0EB441E5B277794B8D00FE98E42FB
+:10E8B0009CC55066F2805E4DD2751401DEB4796D50
+:10E8C000DA2F9FD55364DB41AF887D500D2B26F89E
+:10E8D000619F41DCCED8CFFCA3867B2AF0FE842E3C
+:10E8E000962708B61A711F67B053C2BC5C83DF104D
+:10E8F00036613CC4D304F80A513B0CFCCF763BABE9
+:10E90000036BBFCEE60D91C4B87AF4B17B31AE6E25
+:10E91000C57CE4DF9BA73D9F4C013032210F37C0FF
+:10E92000C4EB0D59DC3D9DD393C0BFE06791D74D3B
+:10E930002EF6E783C5FDE5C6D0AF2DCECBA87F214F
+:10E94000B73DF88DF52FE4A31BA0FEC504D63C7F90
+:10E950000ED3A27A33BEAFD1ECC1FC5DFC399C472B
+:10E9600061EA94F8FBED374C1C8475BBBC9E66D6FF
+:10E970007AA8C37FD84C54DF4B9C9FA2195F4FC726
+:10E98000B77A44FF7BAF9FA8601E9BB7DFFD21D401
+:10E99000FB3CAC578F872428F6619A7ABEB72E6B62
+:10E9A000C883EBC7F7E86FAACFF7BAC6F4E8F10758
+:10E9B000DE9DDA36D203FCF539D6410B7D1C74B0EE
+:10E9C0007A18ADDC3AE09284FD3B0954EC9A993513
+:10E9D000787E433C8FDD35CD07E758883C7670A5BF
+:10E9E0001FEBA141FFBB50FF9FFDF01580D2F4D378
+:10E9F00068FF07BF52585C89DA1112A543535705C7
+:10EA0000C64FA13C17F4A6C0FF62AE97C05607FAE6
+:10EA10000E6EBDED091D7D9EEBF6FD078ECBFD4014
+:10EA2000ED7C4FB9D8BE816051E5669007E47189ED
+:10EA300080DE5E57F419DA190D2F4C1C9358CFBFA6
+:10EA4000A8F311560FBE53DFE7FA4FB9983DDAF03D
+:10EA5000C27318173D1D66DB886A95F0DA71109F46
+:10EA6000A995C1D222A5E19A59A8FF67D275D075A0
+:10EA7000FD86DB25C19D3787607F4190FE05906D47
+:10EA8000F12F407B7FCB4C9315F248C1A2394B91BB
+:10EA90001F6C161FAC5F3BCF781EFC1E0BC62DD71C
+:10EAA00075EAABC16E2AA376D2AFE87C7352A75445
+:10EAB0007BA95CCAD2ED2EF9372BD40FF4AD87D7E2
+:10EAC00067323DDC22F943379562BD2749AC47CA1E
+:10EAD000EB64F6D84597411587BFE86276E2F850B7
+:10EAE000F704A0B997946812D8C541E2FB14FC5C06
+:10EAF000E2B77A601C380103EC2CC72A0FC6854D9B
+:10EB00008EE80F47A2DDA4A09F21FC88732FB038A8
+:10EB1000DA5277C0EA86F88E2EFAA39B006E3F6425
+:10EB2000FBAB89C2E44DEECDD65110F7323BA23F8C
+:10EB3000AAF6601D11C61F065CDD827878C9416C9B
+:10EB4000009F09A11A454AD033426E4C88EF637288
+:10EB500060BCB5928B97C1145B1F9A90445B2EA644
+:10EB6000F5D80587FF3A43819BC25E904D01F4675B
+:10EB7000AA6652FF10E8724DEC900CF17D4737DA2F
+:10EB80008BF51D127EA7BEE89758E7B784D793C5CB
+:10EB9000EBBA9428D6B915BA93785CAC85D103E961
+:10EBA00046FF973CC3E04FF526D6BFF5D8ED4DACF8
+:10EBB000EE888F67E079897A1EAFA180C2E7256E63
+:10EBC000116F5BCDF5AFA8D763DF258AA72C31BEC7
+:10EBD000B0711AD524382F4F0ACCB7D3EC1FE7A653
+:10EBE000EF9FA895595CBC35290C9B72374ADD3ED6
+:10EBF000885F864AFADE7F7413FFEE8003B149987E
+:10EC00003778A1BF7A6056FFBB79CC1558875FDA99
+:10EC1000F9E924A00F524D901FA9BCB8A47AE019BD
+:10EC2000800FE7FF43F5C05EC9B7835EE7BBEDEA3F
+:10EC30007A602FC397C8AB6AEB80CFB9230AABDBEE
+:10EC40008B3EF604E8DD4E23D6034EED7CFD18C462
+:10EC50002FA79A4807E69935F6C3C9B49B1B004F06
+:10EC6000E73FF9F0B1FB09D4913FEF65F5856A7B89
+:10EC7000A03FFB1F7323097E6248D0CD3FC9FE171A
+:10EC8000F23AC8FDA93352ECA14258DF7E9DADAFE8
+:10EC9000FD480FBA45DEB59F7A96AEBEEB5944DC0F
+:10ECA000B93A9AAFCA733D1AE783CBCB9B6D819C6F
+:10ECB000761F793385D7A92912131D24C7A0CA9BB3
+:10ECC00029F6C2FEF266117CFEDC107CFE40AFBC71
+:10ECD00019AB7768D99FE101FBBECE197BF2490FD2
+:10ECE0008C67C0715A5E480A433D7F0B877FDDA564
+:10ECF000E7CD7EE5EE236FB69DDB6F1F14C91103D0
+:10ED000085EB76C2E61FEA12F93319FDD8D88339AC
+:10ED100062FEF8FCFC83C3305E3457E4C55E62716A
+:10ED2000B4B93CFFF5C1F442AC67EB0FCE735BD5D1
+:10ED3000F985D7389C2F982B301E7FD7BF4FC3F84B
+:10ED4000D40288E30F84B8561B8FCBB3789EA79567
+:10ED50009D2BE0D929853D2C3F6392D136B4C970F3
+:10ED60007F0915A35B40F48628D55C496F4B146A74
+:10ED7000F4B9A785B6A9D1AFAC55422EDA6FFBB175
+:10ED8000248C9F3DE0F0E07C1F686179EAD07A290D
+:10ED90003C988D8BE7B5855A641F8CF30737D3F306
+:10EDA0005FBB0D7D9E0FD1A2E7F910FEBD26224765
+:10EDB000E02A4BECFA804DA9EECB7E10E3B5E81BC0
+:10EDC0004D1500EF1C762ECC05836F26C697530B8E
+:10EDD000F1FCA796E4C6D66AF61C79F68239E6C736
+:10EDE000E7572BCC20259E5498EF7B6E9E5FD3C0B7
+:10EDF000797E9BBAADCD1369F7BBCD258121EE811C
+:10EE0000BDF783BDC7F5DF8575F91C2F5ECC97B4C0
+:10EE1000E83DBFCD077A5FCBCE776ACA6670937341
+:10EE2000D8B5C05E85E7F0113BB7E3089B7FC1D53D
+:10EE30000E09F8A1C5CEE8F61F9DB776BEFACC4202
+:10EE4000065F3BE3D796B55298C18BCDFB52E322C8
+:10EE50000333FFB972F103C9FB64241FDF43B91008
+:10EE60007A508F7C778284B3587DA80DE5E61CEE3E
+:10EE7000E716677AF0FB5B6A0B52209F3AF7D41AC9
+:10EE80003CA769C2CD569C7FC34B66F4E3EA574664
+:10EE900073819EB57084D92A429ED2E7731C849DEB
+:10EEA000EFD3AACE0F6AF3BE6B53FDE3201FD450FD
+:10EEB000192D84BCD123F207BB5F67720DF56AC3BD
+:10EEC000CAD8931067FE6E6AA002FA9DBDE7DD49BD
+:10EED00092075F47F9767EFF10DCD739A745BDBFA3
+:10EEE0008DAC57E71F496B2AC6D549BBFA3EECC328
+:10EEF00052BDD72B1FC9EC9A8D86C050B03BAFBD19
+:10EF000086D55B7CB2482680CF4FCC84E7F9859CC0
+:10EF1000F51626EA81D9FDE295F60338F3FA57D1C2
+:10EF2000BF1EF04AF159C7F1FAC9735716025ECFF6
+:10EF3000EEBEB210F0BA51DFE603BE18981E980379
+:10EF4000F03839D18F76A1A8F7BD547A5B9AC9F50C
+:10EF5000E0BF480FFF407CFF32F530FC498C97BC86
+:10EF6000F45756971BEA62FB827BE274A7F17CB3ED
+:10EF7000F35FC912C8E1FEC6B371FBCE652221B0B2
+:10EF8000BFCA2AA3F85ED99F650276A0B07FB5F309
+:10EF9000DFC0F1BA23D377C105F8E571DD5A3EB67B
+:10EFA00029FC39B3B31F97306E6BF28452C6A15F50
+:10EFB000357FB40EE5CAAF70BF07E9926CE09F2CB5
+:10EFC0007ABC099F9FEB9C8BCF655324027E583DF2
+:10EFD0007D0EED35E3D5F5DBFA3D259144BF97CEA7
+:10EFE000E333F04B931C3103D06703D8D5748A0DFB
+:10EFF0000A8B6F373808C6554A3BD57EA2C8DB6EF0
+:10F00000F1B3F373B67449788E56BA21909F0D7898
+:10F01000D5E46F7F91E93B96E9ECC9BF373A7DBBF8
+:10F02000810E1D06928BF57A7AB11F51BD8FB3BF49
+:10F030003AB897057F7CABFD340BEDA42F881FED0C
+:10F04000A403107BC0BCFDAD685789FBBDEBE0C2DB
+:10F05000AA7CFD02BEDF7601DF6F0BF23EA291F7C4
+:10F0600089EDBA843AB8485FF50C09757089EF25C7
+:10F07000D6C1455472B28DEF07598679F220E59BCF
+:10F0800015A37AE8BA8EF03F9B621FE07EA09D46F2
+:10F090008CCFD5F1FADC60ED09F47B82B0BF88F14A
+:10F0A00037AB63E7E755D4517F12EB943BD475BC83
+:10F0B000E7FFC9FA45F4EB2FEEFE670D7F8B7589EC
+:10F0C00075D475498C1F35F3D4FAD1DAF8B9F083C9
+:10F0D0002F55CEA564FD6BE55C5696A0EF7F4CCE18
+:10F0E000F5CA430C8AA578FF0979888F3D6DE91030
+:10F0F0009A6C9518BD4ED2597D2CCFA9637510DA44
+:10F10000FCAF6712E63545DCD7F4BC2EBC3A1FFBDA
+:10F11000635EB77E7F32D625D47A6AD16ED7E63B5E
+:10F120001793DD9300055F9023B88FED1FAD2FA8D7
+:10F13000CC8AD717E45F667DC175599791EF7CD56E
+:10F14000FA795A20814E2A8BA90350DC7F1DD96D94
+:10F150009CEE92781D8A4909117BC2FBFDBD776741
+:10F16000168B1FBECAEB9F1E4E4EC2F3175C06B62F
+:10F170006FC325B33AAD5CB7BF266B0CE81586C7E5
+:10F180009FBC701B81BAC79FE83BF03C8450BDD543
+:10F190000BFA50C4ADC4F8BFE2F1D44BE59FBBFEFF
+:10F1A000C9FCF36D722324BE77A9F9BA4D14060980
+:10F1B0007CA5E583FEDEEB4FAE6CC8F2AFCF42B963
+:10F1C000E51B81798F4B944749A5545E83BEDF636D
+:10F1D000F480FF61E2FB8BC87AB7CA7F9FFB700E99
+:10F1E000EAC34FCCCC1F11FBA0C4FA1FEF17DE7F80
+:10F1F0009FBDF817A7FF4958CFC90A1FEE7B78209B
+:10F2000099E995D853ACCE48BB1F48AB4FC47E1686
+:10F21000F1BD4E21CFFE45F2F4B57F923CA5FA1523
+:10F22000ED8D7EF3BABDDE0FE177CB2ABB7D3CDFEF
+:10F2300085FB39C4BC82DDAC3EEF6D8E3F71FF595A
+:10F24000AE7733B37DBF033C9C7DC764823C6A6963
+:10F2500029939F0D7E2BE6211A3A585D4EC34A82B0
+:10F260007103B1EF775646200A72EA8177AD787E56
+:10F270006C43E7F6D602AC5708A09D78EE1D76DF0A
+:10F280009C113809E307574655F98EB28B9FAFA9F9
+:10F290002EC5F9A2DFEF30AAF75319B2993F2FAE6E
+:10F2A000BA6CA1B7A99F43DF3B5BCBEACA830E9F31
+:10F2B000AD02EB14583C3DC9D38D71F0863DA824B6
+:10F2C0000816B9C2F37BB3916E1AF65494E0F90BA9
+:10F2D0001DE6123C47E83D2BFA6B67EFC90C433C37
+:10F2E0007BA93BF017986F7269F83AB057F3E8774B
+:10F2F000209E7E76F77525185FD4F09DE0B7F83E26
+:10F30000DA3B4CE166A9871F37EA997E147AED0C47
+:10F3100018C74ECC7BB03AC3AE6964BEB5A76D7555
+:10F32000A8EB2F77644E3C03703E93A5F03C39CB9D
+:10F33000CBE79BA8375BD09B0EF3795E7E1AAFA715
+:10F340002021534F1D45C1B7E7E5C5FC445BE4E50B
+:10F3500093BE62767381CD807491DCCAE406A17499
+:10F3600001F6FAF858F704D8BF36A83D321EE0354A
+:10F3700000C00F312E12FDE148C87FA429E321FF10
+:10F38000F1D88A51074C0E8847755F0DA8F1B4D9A2
+:10F390002AC1559D95E12F82FA4AA2341601FD57E4
+:10F3A000BEAD67758F6B9350DFB7E7D661DDE3B90C
+:10F3B000778DAA7D46BDE43459ED82B85341EB7F89
+:10F3C00062FE21798FD4673DEB427022C6B0FE10F9
+:10F3D000C74A6EED0E95435CE641899DC149672F92
+:10F3E000B9209EA0C86077CCED64FBDFE7B6D92BCF
+:10F3F0004D284F2596BF19EF4039A9ACBD5E067F59
+:10F400004F692278DEDDEC6C76DEEDE0769B0C78E1
+:10F410007FF96B5D9F79B91BB27BEAE8005CF5C6AA
+:10F42000D821281D10F944513F27FCABB87CE5E7F3
+:10F43000C20B7DA4B5637BD9AF5C1FC5ED780D1DF4
+:10F44000F7F79EA06F41CF2FEB09DA612F4B26DC37
+:10F45000C726E8BA45EC2BF89AC585F3787DCE89A6
+:10F46000757F19C1CE8114F99830ABABD247D76400
+:10F4700021BCA2D78460DD7BEC724331C6D31A7005
+:10F480009CB5ECDCBABCD681ABCB4BE16A230082E5
+:10F4900013FB96E4015F86281D0CEE830E8AB35998
+:10F4A0001D94B23609F1A66CC013BA89624F47BCED
+:10F4B000298F30FC1466333A17F96011F7CCCC0E63
+:10F4C000ACCC1E93B0FF6C8585ED3FE3FBA4935756
+:10F4D000BCBB0BF6753DC6E3CF075E1A86BF9F71B6
+:10F4E00061AD22411CEA82BD260FFCBD07385E9348
+:10F4F000956E62B326D2E701ACBF2DD8CFEA0815CE
+:10F500007E0E96B2D6B11DE039362D8075C657B73E
+:10F5100044F0A7275EB29DC43C1FB58B70DFF8E9AD
+:10F5200017246117A9F4A1F0D7B47ED88FB3FF7761
+:10F53000FDAB27E372FA32FD2BA2F633E3FD85DF44
+:10F54000A8F52334EFF767FF105F485567F302C74C
+:10F55000BBD0EF995C368AFA9BF8BE6F1236C3FEB9
+:10F560008CC9504BCBD68375489B248B17EC246DEC
+:10F57000FD51BC2E88340E6175298D23D9791E8DDD
+:10F5800057C255D42799A13E25B10E3699D5179962
+:10F59000A13E85DE6FEE779FB8A709BEDF7E9F4D47
+:10F5A000EC136771FB6AC2F3163B701F79EC966C23
+:10F5B000DCF733A19AC50353FD0619E8F2F9BFE958
+:10F5C0007C207763946FC1BE4A1DE47383BD65A63A
+:10F5D000CFA1EE25BE4FBC86F4B94F5CD447897CE1
+:10F5E00071E6908D12E89F78DD4AB067FF387CB7EE
+:10F5F0007DA907E3CDF13AAAEF125C67A590332607
+:10F6000035FE527CAC5FCA4C03DA19E972E029CCB2
+:10F610000B6EE936037FEECE2E40BC359787F11C8A
+:10F62000E4D4E2368CE786D37CE7B29D3DF423E652
+:10F630004736B1F59F87FD6752CF77CF2FFA732EEC
+:10F64000D853955D4646879A796C899F5343BF434B
+:10F65000AFBA1C867FAFC6BE15575D8EA4AAE31352
+:10F66000DFEF6F9D821EBFCD6ED7D257A892E3E722
+:10F670007D7398D53FA9E9EBC0AAEAD127A92C3917
+:10F68000B8CA8FD7F366A94307754AE6D86C90804D
+:10F690006FE6B4DD08E7999C4F8EE5C2F9276FE766
+:10F6A000DE7513B69DB1F7A17D2AE769D61E1C7BD6
+:10F6B0000CCE43F95BCE889BE0BC93F3F0AD4C429B
+:10F6C000B2B615DC142A867D26D135DDA09F4A35D9
+:10F6D000F52E9A731BA02E13CF99B0327C66F0BA28
+:10F6E0005852C5ED77C854D176B3BBC40BF50C5650
+:10F6F000E2D9D30DCFB38DEC7C07C2EAB09A07E70D
+:10F70000B3BA094EEF249BC7B3493404F4DB9C6FB2
+:10F71000C7F7E3F27A8F91E7B1D8F78F3EC7F6BD0E
+:10F72000897A5F426C3960F7583D44D516E79E10E0
+:10F73000C59603E71C348B78216FFFC112B83A27B6
+:10F7400041FF1E9D787731FE8ECBF3F70E82F54E8A
+:10F7500036A8CFC116D79772197D9CE7E7456EB3DF
+:10F760000426C138C792664F82237867A65518ECE5
+:10F7700068A73DA50379E4E474619FC1E667AFF231
+:10F780004BF0FB29E2BC466740C1780009B4EB406E
+:10F790007F3A4FFAB1AEB0CE14CB55287D194D81CA
+:10F7A000E9399057AC397E17E615338FBE0F7520B7
+:10F7B00047F56D1352405FE4F3F333A8E317A2ED6E
+:10F7C000435979E8F7C5CF771D2CA17C983A83ED92
+:10F7D000A79D423A148CBFD8D8FEAE49A5F9DE6683
+:10F7E000FABDA9BC8E64D2317F0AC40126DD16554C
+:10F7F00058FE26A624D66D882B71E93D897C709D24
+:10F8000027A14DE05C6875FB06AFBA7D53F9D7437D
+:10F8100012DB0388AF1EE0F8A214C5FDD6A1B1C467
+:10F82000C6D6C5EA139FE67EDB301731E541FDA45D
+:10F83000430A815F306C6F26E665F696136CA7EF7E
+:10F8400034ED3025AE7F83CCF2BE3C6E2E7EFF09B8
+:10F850009E815E7DFE9D748457BA5546790A117566
+:10F86000A0B7B22C9305E4BB8ECB79B13F7D628A01
+:10F8700009CFED6D5ECA7E37427B6E69B3DEF60A54
+:10F88000E0B1F96338928AFAD9C986889C02F8A255
+:10F89000BE8FA3471E0BFA81F1AE01BA1FC37E9F34
+:10F8A0008B52F9A0C473E39B9D6CAECDF7293CDF6E
+:10F8B000C77E27A428FEBB2194ED687FB02909F2FA
+:10F8C00009CBB7E5887512C507FDDD44B4D97EAF15
+:10F8D00074DE16E7A51252A1E0F94492E8D784ED50
+:10F8E00047793FA9EBF53F017D0C4AA1EBA1D7D7A2
+:10F8F000723C48DC3F958F6E423AB1063C4027DEB1
+:10F90000A4BEF71F75E4303B62624AB90BE2EBCD4F
+:10F910006EAF0BEC2A011F715F8C2B9E8BEF79D39E
+:10F92000FA1EF7352EAF3BF83E68EDF3977364F59A
+:10F9300077F5745CEB377CD7A9FE6EFCBD9CBEDF0F
+:10F9400013F7457FFC59AF32E03306B729BC6E96FA
+:10F9500014A9EB5D48B9D7C4E4BDBABE65B2B4D250
+:10F960000DFC799DA9BE2B4ADF7F9DD3C96439F078
+:10F9700047C837BC3EBBF020F06735FC30011DE7BF
+:10F980007A125903C472BE22F013FB409417C78049
+:10F990008F1A748121A9B4FD89BE6DD0D27CE4AFE9
+:10F9A0007772C6F49E9FA0C3F83C29FD01DE05FDD9
+:10F9B00069E72DE880DCD8810582DB4804AF2EC2E0
+:10F9C000EAB2A9FE62F5D79E9C9E7551E29C646ADC
+:10F9D0001C04FAFDF5A610CA9FC9F61F611DDAF9CD
+:10F9E000BCC03998D7CC919FE2F942C45583F61632
+:10F9F0009DEFF97FE57CA18208EE0B3B50D87BBDE3
+:10FA0000EA913F36A8EA91C5FCB47C2CE61124ECBF
+:10FA1000DCA8095DDBD1BE0BCEB07A61DF4810EA0D
+:10FA20006C4B319F8675CBFBB85F169258FD702FDB
+:10FA30007BB1FFBA65764E41BD8D9D1F24CEA1FAE4
+:10FA40005E81385F88CD9BCA2F7EBE10B6DB6B3CD3
+:10FA5000E8FFC5EDC6F9CC0EBDB6D0D202E735F64B
+:10FA60003E6788C5F7C85EA387DB89A8BFDB93D94B
+:10FA7000773E31B33AF904394EA4F49EF3CF36EA17
+:10FA8000993DE8CDCD677941D95B06F8D802792B4D
+:10FA90005DEF38E4C0F4C0E85CDA6F7EB12F177E0A
+:10FAA0009A65AE81C519295D6DED26506ED7F8387F
+:10FAB0009C0B7A1D697C4B1E88743516FACF1CF698
+:10FAC000293B2FB487AEC6E53A99DC0421F86D7C5A
+:10FAD0007A322D3001C669B777BCD7500A794B23EB
+:10FAE000C25FD4336AF937613E27F56C3E0E381F8A
+:10FAF00099CEE7FABEE67329F49D48471984D1717F
+:10FB00007F740EFB069247F5D0F90012B81DBE1B9C
+:10FB1000A7F735DE56DDC03EE6ADB322DE6F9DC5EC
+:10FB2000F231C12466A7425EC69D0EF127F6FD5B49
+:10FB3000D732FAB8D56C447A99D6558FF91752C591
+:10FB4000F2295EFA1FCC6726F14D849F58B9D93649
+:10FB50000DF781CE98AACEB7CC344DC6FCCE2D84FD
+:10FB6000C5D36E9DA157FD7EA480C34CB2FE53A8A1
+:10FB70000F99A9F9DD482D5CB4F91A018FE6F26FEF
+:10FB8000E6FBFB72E3799D219799D769C945F97422
+:10FB900069799D83FA189E23F09A73E1D6A5942F74
+:10FBA00086FCB818CF5B9F98BEE8F10DB4FDB32D6D
+:10FBB0005760FBB5F43B961F85E78F1562BB4AFE85
+:10FBC0007436F04151D9AC29704EFD41331BC765E5
+:10FBD00009B4C3EF8EB846148C0297ACCA10C37E2A
+:10FBE000D78FAC1F0D75355516D63E52F25FA3B0B8
+:10FBF0005DC0DBA35EBC02DA07A54F67F795171A55
+:10FC0000562445E0F7C5AA5259FFA9A39ECA8438D5
+:10FC10004155256B0FF356AC1D08CFE5CF66F7A510
+:10FC20008F7FC9ED63616FF939BFEFF51D6F81FDFE
+:10FC3000667EABE4857D06FEF2E3EC5C3113AB4BF4
+:10FC4000F0FB4A143877B2D2C7E27B13AC4D6E900A
+:10FC50007F37060CA510C7B559F35BE07CE701E5DB
+:10FC6000156300DF13A81906FA8FF2D5F3C0CF335E
+:10FC7000AFFC343705ED10355F09BA9D26F8A94A67
+:10FC8000CD37541E74313CAAF9818EFB0A8E7B95C8
+:10FC90005A2FC5E5BB866FB5F4D8AFDE276A391891
+:10FCA000D74F6B3A902EB309DB4FB40DE894F1EFC8
+:10FCB0006F617E06B9DB03F7F324EF1558A8D18FE7
+:10FCC000FD20E607660F19D57B5EF04711F6229BF3
+:10FCD00081CD960EDF65CFE97B3EF83138312FFAC2
+:10FCE000FD13089F356C3EDBA446FEFB22CC2E178D
+:10FCF0007E6F83586FA77ABD6516B62FDE45A8DCE8
+:10FD0000C1D87DC915DF34EF20D7B3334CFE078D42
+:10FD100032FC4EE15CC4F36D24F41CD837EF58027A
+:10FD20007F84F9E8E4D0FEA804BF0FE2C37C32C5AB
+:10FD3000E3174CAE33BC887969E1D1D08F5CD5CE66
+:10FD40005B0B871EFC74A37DE6E6BF23185F9766F6
+:10FD50003DCDFC770462254655DDE9911A56572BB7
+:10FD6000E675442245A827250BE651E37127AD7CB3
+:10FD7000EB677F9CD0CF629E77F3FD595FCA4CEE54
+:10FD8000DDAD8BE03CF3AABBCD00C7F2BC02763EF2
+:10FD9000109F7F737908FB1964A9CF3C71799E2C61
+:10FDA000F260A4CF73DC3CF956E08B3B4DFCDC3AAF
+:10FDB0000D5D104DFEAC3F3A11F1BB4AEEB7C4F3F6
+:10FDC000A99A73E2E698FACE9B4914BE59A9BDF1EF
+:10FDD00020F2693768E374D7B1F8D50D3C4E37A1EE
+:10FDE0009AE127754532FA75A9A5471532BCE73C5B
+:10FDF0006B81AF0B8E40551EE635A263208EF0E678
+:10FE0000989F611E499C1BA9859F3F4F16F1C64BC9
+:10FE1000E297FEE6FF078B7F3A7CF713A91BCF839F
+:10FE20001BEDE6E79192403EF093DD965F01F1070E
+:10FE30002A772F5E0467141E51FCEE74066E87F756
+:10FE40006E23FE8950EB9D5A1DD0B3F83DC1F8F1E9
+:10FE500032EE474EE4FAFFB367D87EFD2ADFD04783
+:10FE6000C7837D7A584FC21EA81B67F0F96CAB0E92
+:10FE7000F5FEC23746BBC07EFF80D3E3904DB2EAA9
+:10FE8000770887862DAA733D86ED4C55B587776434
+:10FE9000AAFA8FEC2C503D2F895CA17A3EFAF0280B
+:10FEA000557B4CF73855FF2B8F55AADA63A3535473
+:10FEB000FDAF3A355DD5BE3A76BBFA5C9290AFBBEA
+:10FEC000281D7E3F81C1E3DAAFE6A8FA9F49997405
+:10FED00018F872DE7A56275E4196A8DE5FA2ABC3A1
+:10FEE000FA6BD2C6EC9C46FA1FDF17AF607D1AB5DD
+:10FEF000EFE1A701166E52DB41B55D1BD6802CEEFB
+:10FF0000751E86C6DED1DA37431C35706C3679240F
+:10FF10008FFFAEF895E44AFEBB345ABCE2F9029F6B
+:10FF2000BDA5433F63D91BCCFE5FB68BD5DF1592D1
+:10FF3000C10370DFD9611D094B70CE42E3C6F15297
+:10FF40008F9DA3858BD1A5C6B3D9A3C67352911A31
+:10FF5000CFC95E359E0794ABF16CF7A9F19C56AD05
+:10FF6000C6B3D3AFC673C64C359EDD01359EB36AAA
+:10FF7000D578CE6954E3396F851AAFF9A1C5AAE7E0
+:10FF800042AE0E6C5DA6BADF2C759451494AE6F973
+:10FF90006BF17C89C16DDFEF933E04FE43F43FC6F5
+:10FFA000CF8D58CFBF80E21FEAF9BF20EB0F414A47
+:10FFB000564B070D9D1B30EF76B974F0761EB75F78
+:10FFC00005FE2FD17EA5FAF2BDBC3168E7BC0FF269
+:10FFD00061E610EE97F8FBB67384DC4AB42B12FD91
+:10FFE000EEFEE4592F3DCAFDF07EF5A8C60F7F074F
+:10FFF000AA9FD05E5F8F71AF599CAE3F875B632134
+:020000022000DC
+:10000000EEFA2CDA07EFD08994D379BD03F31E0101
+:1000100076C2308C93DC41227A3C3F1C2A4675A87C
+:10002000BFB04EB386DAED709DCBED87F93C8E62A2
+:10003000340588C789F193BC74F86E7637EE33FBCC
+:10004000BF17F44F2B008000000000001F8B08003A
+:1000500000000000000BE57D097C94D5B5F8FDE6B5
+:100060009B2DC92499241012026126210B908449EA
+:100070005804451C9660D4806193C58833498090AC
+:100080008504D0D7B4A5CD40C2A28536B4A8A8A80F
+:100090000302050B345804D4688745A44F5B636B97
+:1000A000AD4BCB4B0045F618B4D23EDFF37FCEB953
+:1000B000F766E6FB480AF6BDF7FBF5F7FBE3EBBB9B
+:1000C000B9DFDDCF76CF3DE7DC3BECED38C612196A
+:1000D000FB06FFDD717DCA988FB1DE8CFD01FF84C8
+:1000E0007A231C455607E4275A1D0F3D069F8E189C
+:1000F0005879B30DFE28847E46436A2CCA9E96DD4D
+:100100005D3F2BA13163AF2A1E0F1B0EBD265A5D2A
+:10011000DB15C68624316B622C1427F853A64532B2
+:10012000D6C761A07AF04F61F18C0DB6D2DF6C4F6B
+:10013000DFE6A531A9F8973FB628FBDB8F9BEA7075
+:10014000273B4604EBDF68BD6673F3129C6747B537
+:10015000CDB5D5C9D87B5804ED9EBFCF1250A3189A
+:10016000BB62B2AD55A219FB2062DEF1DE0EC69E67
+:1001700009F764215C66CFBA6B35E69523718EA5CD
+:1001800030BF2BDEB6910CE66DB17A5C585E65F53A
+:100190000C8887255EEAEFC98856A1CF220E7FF82A
+:1001A00023BBA8DBF9F3F94C50F8F89F847B46E3B6
+:1001B0003A8E185A935D080F63EB486CC76CBDA963
+:1001C0009F4B660E979EE0303EA27F31AEABCC6275
+:1001D00071A9D0E77885E3F54CDC83F36AE0CFF9C9
+:1001E00086A2F880AA99F79D346FBB7740620AF423
+:1001F0006F12F3B6F6167077641545F63CEF06EC11
+:10020000BF17E47EA0F8B73B392E317FD017E37FCC
+:1002100014F216C3D5F7A643BE23DBE0DA0A459BEA
+:10022000C3A1EB3CC6DE11F07EC604F958FABE1637
+:10023000BF2784F3F6098F1BFC0DD0BE68FCCB846E
+:10024000A7E717DB683D5EE63033985F29739B7143
+:10025000FE9F8CFBCFD7DA001FF31D1E0FC2EDC12E
+:100260003843F27B340FCF90A9306F36E6E6E89F33
+:10027000B175063692B16976BE84F9026ED399DB08
+:1002800084E3CC641E138EFBFBCB663703FAF83D88
+:10029000E098C17C67311F7D9FC3FC94DECF025480
+:1002A000FF01D646F9772372FAD7C1FCA63E919199
+:1002B000C60C1AB8FF1BCE17E8E5C15E9C5ECEF6F1
+:1002C00041B86FEC7D53F43B55D00BF0EB0FB11FF1
+:1002D000E0D7E1B929217C3391D30B33DAD3FE1176
+:1002E000DFB47646E5B0A19877DB1261FD770A149A
+:1002F000DEE9AE2CC475E6AB36D60BE0DFEA50FD86
+:100300001618B3609CB72FAE0BFE45FA004F53DCB6
+:100310002A433CBFB902BE40BD3773553FD2C49497
+:100320004D93CE61FBC271D31BA361FD93BE6E1BC7
+:100330001E80B4A09FE9545B261FE31BF8DF976C77
+:10034000F3C41848EF4ED8676430FFBB076ACB0B85
+:10035000B3206F0DE6A73063B01CC63D8C7000FA69
+:10036000A9FB73EED86321ED186B52916FB63A2258
+:100370007B7D3A04B283D9E06F70DE6A71B4A71B4B
+:10038000FE91E957F5AEB1C78026EF51DCBB1C44A6
+:10039000170E33D27F8991B9BBE3BB8B698AA01F4B
+:1003A000C02EC8B37BC55C3B0BAF9AAFC07ADB1CD9
+:1003B0009EFDD8CFD2C99FCCC3F53123FBED308051
+:1003C000DBE2DF01DCA0FC543D403E03F8B3DECAB3
+:1003D000DC16C63EADB753FEB3FA044ACFD73B286E
+:1003E000BD589F49E597EB5D9467CEA2D7B0DF92E9
+:1003F000B59F1B3D598CAD099378E4F35826E878F6
+:100400004DFF917F72C1786BDE3651BEBCB9695227
+:1004100004A4CBFA9F5A1901DF97ED525CF8BDB2E4
+:10042000C56DB6211F1DF3AC46F259F876DB1414E6
+:100430003BD5D714E601169A3DB0E82D1C6FC41FBA
+:10044000CFC423FCCED68FA2F99CAB77D37CDC2D16
+:10045000EDC7E3A0FD85FA02CA273A8BDE45BA74E0
+:10046000B3CFCD587FF2EE76631294E7BB1537F227
+:10047000F75837F3FB017F9B4C7CBFD804FB05F298
+:10048000FBB8EC69CF3CC4509E7B3EC6F166C69675
+:10049000E6C7C1F729A3BC46AC37EB6BC6302FE9E2
+:1004A000FBC67CCDE1512DF072E97585E074E9C0A1
+:1004B000907B6F83FE5E3FA13215E6D579CD40F388
+:1004C000EAFC20DC0F3B5357BDA52FA5F661364C47
+:1004D00087F46159B83EE804D69DA9180D75C0FF90
+:1004E00017F67C2701E12FC7BD10DBFCD78F50DE4C
+:1004F000FD85CB3BC69A3F7D0AE561BF04D7A3903B
+:10050000BB6C62B3893F596D04EE878BCDCCC3F3CE
+:100510009E2198BF10CE1E2C82FCC8BD49E3917F5E
+:10052000703C4746509EA5EF7D22E5FB8EE0783B70
+:10053000F63CD9F98A03CBFDC4CFBBF63ED3F769AD
+:10054000C855ED5B158EF37A15D6320AF8E3D50D52
+:100550001124B75E35B94ED6A1BC7EC6E6DA0EF5DB
+:100560007EFEE3EF9E3A84E9FAEABCEF421AE38C9E
+:10057000A57ECA7EBA6830B687FD9B25C23A7F71D8
+:10058000500984E53096BDF1F0CA44186FE8E6766C
+:10059000435F4873B7290D980EE95F7002F7CD3EAF
+:1005A0004E07C17DD86EA79A846CD7D7FFD11DB4F2
+:1005B000AF6BF7FBAC8D9F8FEFCB82FBFE60A5F995
+:1005C000FC0A27D2EBFB791E824713CDE3A596E9FF
+:1005D0007FB89FE13A40A3C0797BCD2EDA6760B93E
+:1005E00026C85FDA9FBAE55158E301836F0BED43EC
+:1005F000255CEFB854E47B12E9A51AEAFB205F9D65
+:10060000EB8BBA15CAABFF32D00594C1FA3F7B67BA
+:1006100001C263F1FEC726F5857A97C6309702536B
+:100620002F7FE9EA246CC7FA3386AC7D697F43FCEF
+:100630005C68F7A3ACF123904E8AD4661A87D5F094
+:10064000719E10FB176B03E0C40B92837A3F82CF3D
+:10065000F83DB625E670120BE2A7A66585D308ED36
+:10066000877BAC2E15E9DFE94BACB505F743D8C75E
+:10067000463B91B4CDA25FFBF4E4A26FB18F99C564
+:10068000BE24FB7BC2CC7C61D04F7FF8AEE03E6BDA
+:10069000E6FBEF76900F48BF72FF8571EF728EA078
+:1006A000F66E94A749B0D9E6C23C939EB0903CBF89
+:1006B000D9F1A5DE5413CEE591D43F66C735BCD63B
+:1006C00006EB3D1EEE9989E3CC17FB3733BA1C28A5
+:1006D000A7F784BBEF73D27ED8918C6B80FD712E0F
+:1006E000E617ABA04FA586E853D69BDB1F3F0C77E0
+:1006F0007BB0FDCDD6D7CBCD655F1A582ED0C1B219
+:10070000C72C7E06F36E40F90AEB6A881C694539EE
+:10071000C08E19AA8EC37E793B6FD9D5DFB2C83C93
+:1007200092130D8C750BAFD7819F3D203F0220EFB8
+:100730003DC0D763AF75A89CDE5B8F460F4779C974
+:10074000DC91403F775C33304FC87EA6EF07F05511
+:100750008FEB1BC7229827647F74B31833F22DB335
+:10076000C5FE73EB16F31F23F037A6F38308947FBF
+:10077000CBBECC2339D8D3BA5E13EBFA35AE0BD24D
+:100780004FD28A36201DDFFE85DD88EBBBDD383594
+:1007900019F51398F71338EFB15F18B4F3FE3A5C0C
+:1007A00093BFD9F93FAC309F01F9F173B31FF9B191
+:1007B00005B7398063CBA22C3FF2FD0133CFFBA2FA
+:1007C000CCA49FB644321FCA9196A9F17E9F13E52F
+:1007D00021E3FA6B6FC6CBC344FB39F1D4BEAF053E
+:1007E000408AF2E0FE70D17FED5BD958BE2289E4E9
+:1007F0004883C9BF3605FBFF81EADA0E78FBC06F7C
+:10080000F099804E36C604EE57A1DF8D9FC7331C8A
+:10081000E7031648AAC171CAC349EEDE66303C3808
+:10082000D586F5DC89B100EF03FFAD92DCDF980BD4
+:10083000791BC9EDD9CDF07DE354776238F63335B5
+:10084000DE40F351592D7D77F2761F9978BDB902BC
+:100850005F1F0AFC005F13DF7BA64418916E4F3ABE
+:100860004BDE7512BEDD890ACCF7A9B234867273ED
+:100870006EC55D4EA297A627487ECD163890FD61C5
+:1008800003EB48D47FF9BF39F3B787213E679687DA
+:10089000B5C30EC93E285F19E980F6333D6AC00230
+:1008A000F294CDC87777E9672938AE9BC6AD6E1E46
+:1008B000947A26849E4B2C2027A0FF43619E0F88AC
+:1008C0004F0FE552F921504EBE017E3A5596B617AC
+:1008D000F98A95C9F35FA014F1F07A8795F4CD9E5B
+:1008E000E8A101E13F54D029E26539C73BE85D94B6
+:1008F0006F983D98CE25CF9938DDF8F685115E0BBF
+:10090000A65909CF9DB3C3B758A0FC4121B71A66B9
+:1009100087BB15A8D7F092C56F70D27987EAF95EC8
+:100920008BA47EABCC3C5FF5621AD1D301B37FD7E9
+:100930000E2C7F3D8CE8A12A8A8F5BF54A92A03766
+:10094000B773158EFB9A85E8A02ADC114DE5FF1ED2
+:10095000477432D9EAF91BC20BE8AE16F5822A7346
+:10096000203D06E07B52D0D5496883F8F3D546D2C6
+:10097000BC89E521EF69E8BF15F1E931F372F63D75
+:1009800095CA4FDAF9F827D7F1F18B7F52F9360380
+:10099000BC9D2C9A94381FE671B23682F4BF3FD7C3
+:1009A000A90173149E5F3A1E4F877A97979F1EB9CD
+:1009B00009E6DFB6F2E364A48FE295D585D8AEB838
+:1009C00062F914DC377BE2CBE22A60FE103E4E492E
+:1009D00071C7A4C07AC6A6787A615A93D5B600F5D5
+:1009E000E0CBE6D667F11C9114E7E983DFAFBC7C6E
+:1009F0007607D78F3BD2713F586CE4F421F7D51AB4
+:100A0000417FC7533CFD53709F080FCCC3FD232289
+:100A1000AB95CBBBE53727E7CFB76C3FA0C0389588
+:100A2000E12D8B2955FD39D8CF052510A5A412FC41
+:100A30003CC84F17ED812884BBC7C0F5B3CA9DDA07
+:100A400075E13F23CCAB12FF807695CDAA3B0C71AC
+:100A5000CDFC669C7F253307EB3B8378827E084F75
+:100A6000CCF6E779DF07F857EC1A9487E780CA9845
+:100A7000433FBE8DEA413BC927EAF579B99EEBE7D2
+:100A8000C3D77751D0FF4549FFB3CDF25C4EE35F4A
+:100A90007EB90F8D7F61AA3F1DE17F5911F576590F
+:100AA000783DA00623CEF3979C9E1E37F90CE17487
+:100AB000BE6744CF9571CD23112E520EC11C7C060A
+:100AC000A87F616F12D597728B153186ED2AF726B4
+:100AD0006EE5FA993897E244A17EC52F78FF9847D2
+:100AE0003E3CFF4292188FEBC77AFCE9D75B9C62D1
+:100AF000A0F53E2EE577A4E47357C254807FC62646
+:100B0000B3A6FEE548F3836EE877905FFB5DF65F82
+:100B10009EA2907E364087B7BE6AC7610BF2D3F3C0
+:100B20008CF8553FAF9A147EFE7BE1852E3CA91CC4
+:100B30006FA0064AFA70703DDC8470FEB00B1F0F88
+:100B400025815CAD4418A404E17320D79384F2FF9F
+:100B500032E6715F88817C16EA411CDE322FE1ACFF
+:100B6000A7B3951F2E486A83F64F09F80042FB2071
+:100B70003D76E92F26385F64E1B9B27CD899343CE0
+:100B80006FD60E82ADA06B3D0B36E55A919F166E67
+:100B9000CEB59684E0A161E7B0130E80F3C59D4603
+:100BA000178AE506A3FFC7A84F37EC549B7D8CCA74
+:100BB000AD08DF8BB623BFC37A0B36C7E4A1BE2CCA
+:100BC000DB2FDCF4F0A0B210B80FD9A9C54376B37F
+:100BD000363FF49036BF0D6543EF6FDF2E37A0CD63
+:100BE0000F3BA1CDB30EC016E041B5723C1D1CE514
+:100BF0003AE1003C0DF0AB2EFC34C0366DFA64D403
+:100C00002F36ABAE34281FB0BCE89E6CC87FB679D7
+:100C1000BE0BD15CAEFA167F1F7058FEF1A413B85C
+:100C20001F5E60CDEF4F063C2C68D960363A70DD10
+:100C30005ABA3D6010F4FA02B7972DF26BCBAFE7CA
+:100C4000EB15D25E9A194A4F7ABCC3B8F7B9614224
+:100C50005575CB869D812DB3BC10081D6036BA79C1
+:100C60008319F5B61B8FE3E3F462733B101EDE516C
+:100C7000BCECD6BA09ECF430F863DDBB9370DEDE71
+:100C80001F29A437787F95710CF781F67D73EEA646
+:100C9000F4BE025ABFB4CB2D6C51029190B78F7243
+:100CA0001C6A8376F3FD8A0BE75DD26809CA33F8C4
+:100CB0005FD93ADD3C368694C3FC171E3AFC3705F3
+:100CC000FA2FDFAC6DB708E42CCAAF8A6DDF58424B
+:100CD000BFCB73E3AD2D5B545CF77C397FDF588667
+:100CE000EBBA955765BD847E730633B06FD4F62E8C
+:100CF0003A8BFBCAAD1B793B10975E5C6FB5CDECB0
+:100D0000C0F5565B592002E67122D2ECB6C3F7ABB0
+:100D10009B22C91EB6C002FA641EA52C2C0FDBB99B
+:100D2000A2B1DDA7EF70BB58751CC777F5730A9D9C
+:100D3000A3AAD18889F9E7797E110BD03A904EDCCD
+:100D4000A1EBF36BF3AC899FBFAA8C81C3088F0A18
+:100D5000D6C6CF4F8047B7841FC0AB0AD6F9412C07
+:100D6000EA5BBAF6CCE5C1716B6C5C7FAA39F48D95
+:100D700025B45C9E03E53955DA699F4B2F0AC7718C
+:100D80005629EE27AD30CF5542BFF66D0823FA9DA8
+:100D9000BB85EF37A0C7A6235C366E4874A19E3191
+:100DA00017F4F230E49B45E1540FF45DB2AF748068
+:100DB0005E8DF6F68D31CD01DC37363EE6243D1AE8
+:100DC000F45F824BC7FA30FF5605F560AEC76CDCA6
+:100DD00090417AF8AB729F5ACFF5AE6EF4622A67F3
+:100DE0007DB81EFF112E25440F4E8DF7A4A586ACAD
+:100DF000AB6CA53B11F79DB2696603DA9D58F9CD3E
+:100E0000F90DB60B3DB203D68FEB38A3141D378412
+:100E1000E8A32353F93E3272BC7B87A847FE853294
+:100E2000C3D447EFC0F11E373870BC2E78BBDDE964
+:100E3000388F331BC2F290CE468EE7F69F93B95C93
+:100E4000BE470C676E3FA477887EEF483568D28432
+:100E500070A03FE8E74C3EB73B470E2F227B1BECD0
+:100E6000D524E7F5EBB847F453662EFAF7DBBB99C8
+:100E70008F840F9BC8F585334B94AD7C5E805FC833
+:100E80008FFC6918D9E9CE88FD47C219E86604D9F4
+:100E9000DB85BCDA20E8658389D3816F113F3F058C
+:100EA000E985113D6C14E7ACB902BF6C3DD76B818D
+:100EB0005E389CD7270A7A61ECEF480FF90EAE67CF
+:100EC000DFE47909F05E9ADAFBFA7393C43733FAF8
+:100ED00047FC23FF46F5C13D077CB07F56FCF2B1CD
+:100EE0002806F5CE199BE25DD0BE6AFBAA2837A47E
+:100EF0009F197D517618FF9C5F2DF077036FBF809F
+:100F000037DAD715903F8BF14F07EA3B3F9A82EBD8
+:100F1000FBEB76931D4542CD4E0B9D9F16EF5F4434
+:100F20007A36E4DB797ECDE72AE60F69EDE0153FFE
+:100F30007F2CDE41F0F6251912300D243148176F51
+:100F400033B902685F7E4F75C130A03777ACC6F900
+:100F5000E9DBE33CAE01BE6B9A55AF39FAFAF21AFF
+:100F6000215F6AF6FFE873B4EBD5E8ECEEE5C2FF6B
+:100F7000A0B7BB37A546F6FA140DCCB7B05B500F3F
+:100F800002B8B802C8B7309F3422136EB76DD8F5D7
+:100F9000444E3BEA0BDBDE8A52B2827677E997E871
+:100FA0006C2E7D0EED9A3DF1E36561870DE28BCBF2
+:100FB0002DC7210565001CD0795A650A44DD06F06D
+:100FC000A8DA62223953B5E7F91D4F219D7D68A14A
+:100FD000FDBC72CF1BEFDF8AFAEE3E53AF42BE0C70
+:100FE0009B121FC4538D83DBC9245E2A7EF586D9EC
+:100FF00091CDBF2F8F0DE2A772DF6133CBBE1E8E66
+:10100000139A0F9BDB6CDDE0A9B97D12D989767D3F
+:1010100065463E38F7BAC2FA38AF6F5FBEE58D2835
+:10102000D4C7104EB82F497C75E14F571FFA9FF275
+:10103000CA70AA67C773454FF85B827B07D17724D4
+:101040008B81F1CB3FB2F80B11AF7B9745E13ACEE4
+:101050001A6B399D3FB32A1EF5BA72932FDE4E29C3
+:10106000FF5EFEECC3447F0B95DA787B16D177A246
+:101070008174065F22AE6FFEE699B4BE05CC43F4E0
+:1010800057FE8C5AE487F44B232BD8D70D9FF41DC1
+:10109000C8F9E4EC56402AACEF2CDA6D506EFC5ED9
+:1010A00015E7DC25B47F3F2CD6CAD852CA7F29F475
+:1010B000B64BA95D7E656BE879B166DB9A56C4CF05
+:1010C000F9FEEE3E384F80834FC04BF906FA55DFEC
+:1010D000CDEFC3F1C31CC691A21DECA313F03BD608
+:1010E0006F35B9D1EE1DD24E9CE7F8F80F89F1614A
+:1010F000DEE1785E3D1BCFF576FDFA0A062AD2DEE8
+:10110000D6CA42E9AB27BEDFF608D1D517EF71B9D1
+:10111000B2D83FB580CA5B4D813E58EE3F3C43217B
+:10112000B9606181EEF87A9B49F0B5B61CE6695466
+:1011300042E1FB3AD7431780DE1508E1E320DD9852
+:1011400083DF69DD3F15EB6823BF98F4A72D14F208
+:1011500040BF6EBD7CE83550F8E3847C90EDD9E665
+:10116000EEFD3941B9E0A371AB603F413DA3EA43D5
+:101170000BED1B557B4C45089F0BBB8FBE3F17CF1C
+:10118000A1CD928FB5F256CFC7E52F8EE8968F2F5F
+:10119000ACCBED9E8FE17BB77CBC4E21F9F63F9541
+:1011A000B7B0D391DDA0277E5DD883BC1D3B502B0B
+:1011B0006FBF6459D1B761A1DD3B80F0A383AB84DD
+:1011C000A75E7EBE9FEA20F8EAE527C3D0881038E4
+:1011D0004AF849FA64CC43E374D1B1A45349C75DDA
+:1011E00074AA5FAF168EFA72C34046F3297AD9C447
+:1011F000ED672D0AE9DBD0EE78D270E253376D7FD0
+:10120000ACE97852AFD0BC5F976FD6D577EBF2459B
+:10121000BAFA1E5DBE5653BFEAD051333F1F0434A5
+:10122000F52C75F7D039E37A3DC2CFFD3EFB3F3751
+:10123000FB902EFA7598512E9A56325F24EABBAF76
+:10124000A9A4EF5E717444A15EB22A8CEB6D57ECD9
+:10125000221FC3F31DBDCDAB512ECAEF1D61DC4E65
+:1012600072A5A8232A26E49CDEDEA246A13DB6CDC7
+:10127000CF0ABA8F136920B8B6B19ECAB9FE96AF2D
+:10128000DA92EBD01EDAA4BA804C58D98A5951149C
+:10129000BFD0927AEF6CF83EFF372A85015C09E7F0
+:1012A0007605E6731B317EA094A3907DC67C8F8F5C
+:1012B000817595B6F03882B2755AFC2EB0CD880E85
+:1012C0003850EE68FDFD0BF15C978AE73DEDF70ABB
+:1012D000B68EE8AD42C7171E61A7D5F3C516C9176C
+:1012E000B92C57D863C8CFB154C8EB7C35EBDED9E5
+:1012F00000FF2B275466817C678BCA56E37A772BD5
+:10130000E4EF418700F2DB62E04B9C8F84CF45E441
+:101310009B8C9EF5928B2FFD65E4F7914E0E7C9C85
+:10132000837ED88B073E4C7F15F307FF94FC31BBBF
+:10133000BEFE84D7FF360FE5F095D72D0CE9FBCA2A
+:10134000EB6F26A35DF0CA2B163A2F5F5969E1F6C1
+:10135000E6D723FDE88FBCD29FEBB90DAF7D95D3C7
+:1013600046FB6E23E1EBED8166AE37B5FCE749B491
+:101370005777B6C0AA509F783D82F8A7E69530F21D
+:101380006B5F79EDAB91A1F10FFFD3F548FFF595B8
+:101390004836FB45A45BA1D7D7BC3AFA79F4E756A7
+:1013A000EF3F6C2E85F209BFFEAF1C949F575EE4A1
+:1013B0007AD26553DBB3686BFCD3C0393F3525A2C5
+:1013C0007D0E3AEB0BDC96F6E434E493EBE1C2E1FC
+:1013D0007005E080EB02B894A3DCEF091E97FF656F
+:1013E000E1F1F93C2ECF6E61E8FF0DC245E17E844C
+:1013F0009648BF55A1F5F3EFAF7F9583F2E646EB34
+:10140000B5A59989AFFF7F59EFE0B47F55FC727A9B
+:101410007F71A083C7F5E9E8FE7ABA3EF86F94DFE2
+:101420001BE9A2F9DE24BFDFFD2FBBFEFF1B7C976B
+:10143000FFCBAEF746F8FE8DC077A41DFD8A575E40
+:10144000FBAF64F62DD6BDE65F96AFFFF1BAA5BE41
+:101450003E5E759DC885FA6FB1E6F75C4ED23EBA26
+:10146000D53BF6A7493B093F1F4D607C9F9E60AD71
+:10147000247D7342BFF5A41737B03CF243F8FAA9B4
+:10148000E48FA1E00B80C39B09B97EF2271903FD0D
+:1014900096417E7C5235C55BE9CF8D13C22717A0DC
+:1014A0003E7A7405CC0BFA391A69B0A3AF78623F63
+:1014B0003560C9A1B41DD3E3C9F79C40BD65A24DF9
+:1014C0007B7EBA47771EBACBA12D2F602FF642FF45
+:1014D00059419689F9613E93B07EC8B9F1A7697602
+:1014E00082CB5DACA9D16EFBF6703A23E0743D1C53
+:1014F000FE31DCAE839338271B457D3DDC8CB6473F
+:101500005BB19D91C1B997AF97CECBF2DC7B2378CD
+:1015100032719E368AA1257C8DFDB89F34A45F82EE
+:101520008B84FBB785B7C4931EEE12BE126E7A3C55
+:101530001C446354EF20FCFB19738DC877B70B3D37
+:101540007EA23186E7FBB5AA45C48F7E82FB842F3D
+:101550005C46D44FC6D96228EE9239FAC7E07916B4
+:1015600055CC6F92182B1915335281F5261999CF46
+:1015700002E74DF4A1911DF511A37FA513C7E1F674
+:10158000DAFE466E9706EEF685E7517DB719F2DE74
+:101590009F2D646EA8EF4D622E85D767D1B1148E52
+:1015A000C6548CCB8214DB79A379BFDE3ECCBF92CC
+:1015B000E393F082C726B45F40BF6E432C6F1F9544
+:1015C00047ED7D06DEDE6D8474402AB7AF77ACB29E
+:1015D000D0F9C3BBA67F3ACA8FC2F15ABB71713A28
+:1015E000B7ABC8F4CD74CEEFAAC195807A7149E348
+:1015F000203A0FA9E145D52FA1BD7F6F04D1A37774
+:10160000F5039347E0FCF6C6B9707AE7A7EC1BC96F
+:10161000EBCF79F88FF0DDB3338CBE5F48F7F44938
+:10162000877ECF2B8E792FC187929947CD09308441
+:10163000A779EA25B4FF4DF1EDFB1DFA19A7CC50AF
+:10164000A9FE14C6E32B596304F9A327FB3E3726F2
+:10165000407F93E1B081E5ED61F6E425307FAFB0E6
+:10166000F7A6A673BB8B1ACE3C2FDA705EFDD35360
+:10167000E0FB64D67D3CAF57D61FAF6C46FFD080F1
+:1016800009DC1E2FEB633FD8EFC274EE5FCD117003
+:101690009179802BD52F5B6B694FC573CF5A53203F
+:1016A00003D26732C7E7A54379610A9BB409E1FE1B
+:1016B0005D956DA5F97678C9CE1D99E9403C788095
+:1016C000A429BEB0C9E940BB57FBB8E600FA07DA67
+:1016D0009F74BA1A1C84658AC791E7ACF671818140
+:1016E0006897EFC8E57E8693F6B6483C1F96DAAC5D
+:1016F000149F23E37AE6DB399F0F68685B7F0B9EBC
+:101700003B1F535D5B213FFF31EE77F9C466F52B3C
+:10171000785EDBC8F994ADD3C6F130BB8BEC3DA548
+:101720004DE3CC78BE2CB3B9CDB8CE8A0C4F11AEF8
+:101730008B7D0DF01B89719C8C98C1DBE4A538135F
+:10174000350AF80EF9C4E888C273AF3E0EA846C445
+:10175000FDC8FCA130CF1CECAF24DAB117E9E55489
+:101760005D2AD93D3709BA2BC43846F44F18DB122D
+:10177000713EE1F81DE05F186B4FB7113D87318472
+:1017800043BBC99E8EF4DDBE2ACC807EB6C2959C3A
+:10179000AE81CFAC4668FF889185A3DF2043B42F8C
+:1017A0005E612CDA02F97E56668C8C45BACA25BA7F
+:1017B0006ECBF4E4207D7EF603360AE9A174DD06E3
+:1017C000F2AF48BA60C6D6897130CE67DB9D792802
+:1017D00037251DB5658EAF4D0FA587190AD101A418
+:1017E0008753891EA63D8CFD168E0F0C5C9A85E7EB
+:1017F000D12AE6C6FD3D81B9504FE8641DE47FEC77
+:10180000B4991D68E792F244CA0DC0ABDB1A1FA45D
+:10181000831DB0DF1B4D8CEDACB752FA42BD9D1954
+:1018200041C6EDAE4FA0FCDE7A07A5CDF599F4FDDB
+:10183000C57A17E5F7D78FA2FC817A37E50FD51760
+:1018400050FA4A7D117D977209E0427248CA152903
+:101850008F4A6DE676F4474AB9A4A79B7900DEB1BA
+:1018600079D49EE49E9477B80E435E501E49FCA640
+:101870002845BE0427CAB1B63988FF7CF5E29E83AD
+:10188000782E2FB7B9E89CCEB8DCEB047A45B824A3
+:101890009BD921B4BB362C71B7AF7106E17F7FB9FC
+:1018A000C28C2174F5406D183386EC1B0FD6C568C9
+:1018B000F2C5757F78A30FF45FD1CBB30BF176F24D
+:1018C000879F3EF327F8FEDC0FCFA721BE611EDB0A
+:1018D0009FC071978777CD2316F38D26F2470D9021
+:1018E0007610F8877829619CDF9EFBE1DF89BFDBFA
+:1018F000EB2C0ED4873F423C015CFF2CF054526726
+:1019000021F879579DDE7310F97CB999E45C49A3FD
+:10191000E0C3B500CF10FFEEA94446F608D0A659A3
+:101920001DC0EDD40FCC8108E8FF94C2F95701A582
+:10193000A018E3FED6BEF901F2BF527782FCE71E83
+:10194000AB8DEE35319FE962687F4ADD71AAC7DA57
+:10195000FAC5A0BD84F6B13BD0EFE8363B60DD4868
+:10196000D388B792CC232C11FD264D8A1DFD266508
+:10197000E27BD95A85FC9318773303F4BE77D355AD
+:10198000C26364BA91D2CA7426F4BA26DA9F24BD1F
+:1019900096AD8376C8174DB9E6052172B8447C2F01
+:1019A000CD34502ABFB78B7EFBAECD9D8DFA445F00
+:1019B0002CCFC2346F36C2B7AF6D925109C1FFC789
+:1019C00038FE089C071FBF12910AFFF768668A79E4
+:1019D0007E16E287EF5F729C92CCBCD518C759B2D5
+:1019E0006E1C4A5FD6607225F4827A67BAFAE17A91
+:1019F0001BB3F278E5AA1EF60F693FFB0CFF1C4DE6
+:101A0000EB26BB6EC5DE5FEC7D057AAEF8D842F8FA
+:101A1000AD182AE2A7B2FC23A793A1516BAF9EF8A1
+:101A20008BBF4491FF613F8FAB8494DB53979773D7
+:101A3000FBAB0BF8AA1BFFCFB1BD1F47756BA7DE31
+:101A4000AFDE949DBA46F93A0AF507B99EFCD7BEB7
+:101A50008CA77928D7C8FF53F3DAAAF8EEEECFE8BF
+:101A6000EDD55DF66C61B7D397EBED757D32747E85
+:101A70000123A3FB58D25EC7D4AC68B4EF7F29EE34
+:101A80006BF474AE91F6ED9A4DD0491CF0A7D111CC
+:101A90008DFEAA2B3DE8D30F66F0FDFE92B0875F66
+:101AA000D9ADD239E7CAEE48E2A7C5BB7F761CFDA7
+:101AB000878BB729348D6AD64A700378326BE83E3B
+:101AC00086F16671D7CFBBD39F168DFB48E52F22D9
+:101AD0006B91CE16352BEEED309F4EAB23BA77C807
+:101AE0007C6ECBE0745669691E497016F3CFCD70D9
+:101AF000D077596F51CBCFC87E0CF52E931EF4CB07
+:101B000008F4F523BC7F87F3BCB079980BFD7E8B7E
+:101B10009AF72D263D6277841D8F0CE7459CB0EC2B
+:101B2000E7CE0CCE9F776670BDE582F0075DD8AB3F
+:101B3000923CC379227F9D57B4F1789345BBC9028B
+:101B40006E9F0BFE92F51735B7470D84FA670FFDB0
+:101B500081D259625D8B6CAD39B8FF9EDD1F41FEAD
+:101B6000ACB3FB9F9EF42A8C77A9795C2FE407D94C
+:101B7000FFFC0C13D5BFB4592D4078313F8F7BA9A2
+:101B800046F80E0B9D67DC169F3394EF78DCCF850B
+:101B9000FDBF8A326405F1596DF558F15E63CD7E63
+:101BA0006F11CA8DCF140E4FD3FE713EBC8F54D32C
+:101BB00092CB909E89EF12A9FE5A43483DB3C94586
+:101BC00042D17868AA3B89E02CEE13897879BC1F52
+:101BD00087F267E9542BF927E60D75CCBA1FE5E4C7
+:101BE0005B268E977E8E27507F9BF74E1CC54D2D12
+:101BF000753A66E1FC97BDAB52BCEFBC61420E2466
+:101C0000B48DC0B8C5AAB50A73C33ADB9D5C6FA892
+:101C1000F2ABCC03F9BE400F3E00C5FA8C14214F45
+:101C200003E978AFEFA97283DB0CFBDF4933F3A93B
+:101C300068377A91C73357A5F0B8E1A790EE21AD88
+:101C40008A0DA4C7417F17053EABA605D2314EA22F
+:101C5000EAC5448A93B868E67E4BFC8E7ED2AA3CE5
+:101C6000680FF57A8978586C1F13423F55252E0767
+:101C7000D653635D8E5C1BCED77E99F4D89722191C
+:101C8000EAB18683913CCEE9E7615B2D2178DA9257
+:101C9000C1F5E55E028F6C2E8F877C5CC4633FBE0E
+:101CA0003DD18FE73759FF7193670EC201D781FA93
+:101CB000FB2273533AEAB772BE8BA29A689E17054D
+:101CC0007D2F0A6FE2F1D2E29E2CD6C77CBB8951F0
+:101CD0001C77C72E0BC5939C4F6C3D80E39FDF356F
+:101CE00088E1FADB9DFE0587A81CF447C05BC50BA5
+:101CF0009600AEE7DC2E6E6F3E67E2FAD8B9A9090E
+:101D00000EC45BC1B44DF3C81EB3CDA220DECF29F3
+:101D1000CC9C80E5DB7BBB7CD8BEBE8EE2A42B4096
+:101D20004CE07D1C480BF05ECDB9ED83283EECDC29
+:101D30006F54BC1185DFD7E2770F6B9AF73D84C7EC
+:101D40004E7E7E3AFFC27F0E0ABD5726D38A6DDAD9
+:101D500038384927B2FC4806B70F1C11703E9EC1A7
+:101D6000F7ADEA88E6C753689D1CEE80273AF7C1B5
+:101D7000C61FF9F4708C834853506E3C0574F534DB
+:101D8000DA1576F2F3D5F9DD268A0BAF3818E9A615
+:101D9000B8B335B718280E42E57A788501C047A94F
+:101DA00042FD564CCBA47BBB006F3AC7766C57C53F
+:101DB000388CD970DD3B789C6F21EA8A549E4DE5C2
+:101DC000E744FEDC816CD2EBA07F37DE57AAF8DE59
+:101DD000F7391CA797BFCDC88E6125F95AD5E5C73D
+:101DE00019138DFB5DF59ADBA2F13E1F7B4765A8B9
+:101DF0009FE8E174D5E8EA8372B577A690B3079EB1
+:101E000031A33CA814F7432A5F50B83F19F80CEFF0
+:101E10003B56AEBEED09A2CFDF99581AACE762F38C
+:101E2000CFA234F81072B0ABBED945F52BA13EF667
+:101E300053B9FAAD289ACF0E13C5995CB75FDD6C24
+:101E4000FB17D49B6ADF451FCDDC8E72DDFA59EBA0
+:101E5000BF7D0CFD7FB13BCCE5A3AFCD74AFEC8271
+:101E6000A97901AEFFC29E3092471762B87C380B49
+:101E7000F2D39781F3B8E7271497F5FBE9741F6E47
+:101E8000A15FDBAF1CD79869E27416E78AC6B8BEBB
+:101E9000EA77B87C03BCDC4BEDDF31517BFD3A4E79
+:101EA00067F0765DFCB92782E8E1425F8E970B7B95
+:101EB00033683F6A8FE1740EF34DC6FB7317F66407
+:101EC000E4D2BD34546E801E2AC4F9F6424C73B27B
+:101ED0003DA4BCDD24CE6901A88974836D40EFABBD
+:101EE000A8E37A55A5751DC587605CEDC83C4A031B
+:101EF00096D8EBE363815EE9FC787FA6B053E27885
+:101F0000F1227E9BF49D6633CA6F8FD00BAB76EBCC
+:101F1000E36B79F9AD998A8C0371F492F1BC48872F
+:101F20003E85E24C2A1B972C423AAFACDD703FF263
+:101F3000999C7FA59115E039AC5D51691EED61EC6E
+:101F4000C169B86F848E13AAB7C979E254E3495FB7
+:101F5000A57DECAE4CBEAF61BE09FAAB6A54D6D1DA
+:101F6000384E799EE5EB927002709831AEAF7D9C51
+:101F700028EF61DD729EFA75CBF93C90C9E551BB43
+:101F8000D3F1933188E7DFAA743FF6EAD7C3A2639F
+:101F9000BBD1CB82FBBA3918DF8AF1BE487BD04F68
+:101FA0004E26976B95183F0BF34CDFAC8DEBCEDCD8
+:101FB000A6CD0FDEADCD67EDD7E6735AB479D73134
+:101FC0006D7E1A8EDB9B9FB3F13E2E9EB331C5739F
+:101FD000B6C3C2CFD998C77336A678CEC6EF78CE2F
+:101FE000C63C9EB3318FE76CCC4B78E3791BF3781A
+:101FF000DEC6F2A7059CAA449C24E201E99DBD1C13
+:10200000A6B9EF73E5357E8F03E880F3CD1C33F17D
+:10201000CD535883CE1DDCAED477BAD581F1BE8FB7
+:10202000C47A5665A25F54695D9D887833B651DCE9
+:1020300069CD2B3CEEB42A2FCC86F68DB65567576A
+:102040006338E703B19E47B1FE1553C70E846F7521
+:10205000DD51BABFDEB6C2F1CE1D1C7F646761E5FB
+:10206000B1A43779719F8BED198FFAB86FB64E1BFB
+:10207000E7AD8FFBD6C77BEBE940EA7BCF993A12FD
+:1020800051AE9FDE655D87F33F1D26EE9FCCB6EA1D
+:10209000FCFD424F5BAF6CC5FDFA1799B1DCAF7226
+:1020A00002F4F36EF65999965E1B467A78577E9D38
+:1020B00062A07B7109F1B40F2D13734A563ADAD737
+:1020C000A09C5B64A07DF32AE86538DED5F754D286
+:1020D0001F32361934EB19E40FD7D0D7909DB1BA1F
+:1020E0007B0D7D35F5871E4AD1DD6B18AC8DA39F26
+:1020F000B1E2309EEFA7AF1BA6A95756749B0E8E78
+:1021000062DE427F2D83FDC30DEB7B6AF9A664C4BA
+:10211000EFB2459DED6B503F7D298CEE8595E3FF39
+:1021200003B9580E7DE27DC6F2FDE23E709D761F3A
+:102130002E15FB50B991F9ECB1413A2CB733770C1D
+:10214000B45F34B8352780E78ADFFC61A43D05CF52
+:1021500015E3FAA03C4A36B9290EB66A5F5ACC0A92
+:10216000E8F758AAE7A34CC0CB99A6A33F2EC6FD1B
+:10217000701F3FEF9D5EF7AB288A1313F4966CB285
+:102180008723DEB734F1F838B48FA9B141BAD8D279
+:1021900014173ED0165C6F900EBE263C017EB81D13
+:1021A000A7FC08F93D3A9BC57AC7293ED4A7E5FAB2
+:1021B000968A7D850DE4FD3C24F267C4F942AEF3B6
+:1021C000E2A0C3390EBC7F517F285945796ED8BD36
+:1021D0002311D2D116CF97B89EF22D697F1A03E34F
+:1021E00054FC91AFE7938D13A246A3FEB9C7E42A2E
+:1021F00084FC9AA6E7CD78CEAE30FACD145FB96BE9
+:102200008B19E38BEFDCB985BE2FD8E9A578CA8599
+:10221000AC96CE9F9FC97704043CCAC72B9BED3078
+:10222000EFB983B8FC280FE7FE3BD08FDEC0F73B49
+:10223000AEEE5472318E6746D13EB317BE470D12D3
+:10224000F783747CD2F9F6F4FCDE040F7E5FE38F33
+:102250000C4EF1A9D7F3C5F46B4EE28B19D786D09B
+:10226000B96C6660103FFF66E9CEBF6FABDC5ED72E
+:10227000C2F9A0DC1CE8351DF9E47513E9B9D5B045
+:10228000DF8CCAC37335EC8D90168D5135F45A33FB
+:10229000314243CFB359ACE6DECB7D183412929F66
+:1022A0005198AAA93F6BC6101DFDE705CB498EDCEE
+:1022B000AAB95F57BDDCE75048CF1CAFFDCE789C74
+:1022C0002063776BDA57B369C17A48DFDBB81E5CED
+:1022D000BD3F662BDAFBCA0DFCFC34DBC3BF2F3ECF
+:1022E000C4BFB3D94CC38703525D7FE2FBA289FC14
+:1022F00002D29E3E1BFFEE06FE8C8577DD0FC77B6C
+:10230000F1688FD0DC9F16FE409C37E2A15AD88D31
+:10231000AA33B9DDA8DAD76AC6770700FEC6B8586F
+:10232000AA678DC3F8C82685EC8A982EA778496DD0
+:102330001C16F687718C8B4FA85EE4137D7939BE2D
+:10234000DF83F87D85C7952EDCA48F835C47FEC8AC
+:10235000C5680F0AC1DB53831C425FF1AFEE8BF0FF
+:102360002B5472E95EE4EEC3668CB39B31232617CF
+:10237000F9464F5F52AE033FD3F9BBF3EDA3445F81
+:102380009DE546A2DF1BC161B19BDB51F574B780AF
+:10239000B59AF19EF882FD8A0BCFA3580FE1D117B1
+:1023A000E951078FB8D8EBE120E1D305AFFDFA384A
+:1023B000370EA78587147FA01B38E9E7DD13DCE41F
+:1023C0007A16783C93502EC8752DC4F963FF307F80
+:1023D000EC5FFA21D8283D7FA6927D6A71118F8F1C
+:1023E000D5D3C3B46BDCEE72DF3523A5330AB5FC5D
+:1023F00088ED902F665E8BA7F26F4B2F8B619EFC52
+:10240000FED3CDD1895C8794BB417EE0F7066EF4A4
+:10241000BE8FDEEEB8639088131CC14668E29185DA
+:102420005CD5B7D7C7234B3D40BFBF78230D1437CA
+:10243000D9694B21FD42CA598FD83F3CABBEA47A23
+:102440001EA8C76713AFD96F3CC2FEB7343285DE12
+:1024500063485E11178F78F286D929FEDEBB42A54C
+:10246000B8672FD47384E827AB1B539371BF38F53B
+:1024700048C6B33ED0DB4F7DB757FC2818E7F42A97
+:10248000532FAB2358EFD4AAFC648CD338BDC13290
+:10249000DBDF0DBC5AC5FE50FDC30F683FBB64783F
+:1024A0003B6A36B4AF5AF5521486F957AEE2FB7860
+:1024B00079AAE79D41BD713FDFB2C38EF0B36FC90A
+:1024C00041BBEF49D80EB0BDD41F2A56E5F741FDF8
+:1024D000A2EABF8F3E6BC77BD62B4CF1A87F9E7BB9
+:1024E0000FF64385F633D21B3E0B832EC89F164949
+:1024F0007684CF14E646BFD245C3E1BFAEC1736157
+:102500006E737A00D2EF593C2771DCCA55CF93DE47
+:1025100052F1E88A7455C57ED3A2BBB39BC87487B9
+:10252000D8B7517FC714F5778C9341FD1DF3A8BF31
+:10253000638AFA3B7EAFD9A4D5FF2EA7713925ED6A
+:10254000C9031A3A72D17FE71BCF326B69BFB565F9
+:10255000A2BEBE4C0977A13C5A86BA12E6FF1246CB
+:10256000E758B62D91EFB702CF7556EE37FA4ADC31
+:10257000CFBDBD0374B210FABCE39A9585DE9B1DF6
+:10258000C76234F909D6444DFD7CBB53537E67C204
+:10259000204DF95D8E5C4DFE9ECCD19AFA935DE3A1
+:1025A00034F97B47DDA5A93FD53D55939F5E304764
+:1025B000537F669157533E6BF6224DF91CCF124D57
+:1025C000FEFEF2EF6AEA3F50BB4253FE95014EA475
+:1025D000402F2D78EEB2E0FB29564ABFA3DA8D28B2
+:1025E0003796FD36CD86F81E33C150DB9D7D3F63A7
+:1025F00030D787CA86B85306F7E6EFE0203DF617D6
+:10260000EFDC8C18CCF199C480AAE8BCDB9A88F482
+:10261000ABAFA72F1F1371E4AA0370F893C14367F0
+:102620001A410E8DB9E5C8B054C89F18BC60A611F8
+:10263000E4C698DB8EFC2A05F2AD837FC1CB871EF2
+:10264000B98AE5B38654F2F2E98C548F3FBFD07754
+:10265000A60FE77F47CA3A17B793747BCF5CA608EB
+:1026600007BCAF8D70C03400F48BE911A05F4C8FB4
+:1026700001FD96817C3A0EF48BE909387FE2F77F01
+:1026800087F327A66FC3F913D3DFC1B913D3563825
+:102690007762FAFBFAD994BE57EFA176EFD797533A
+:1026A000FA417D2D7DFFA8BE8ED23FD7FBE8FBD43B
+:1026B000C1D28E11609AFB01E867447FE221D3C545
+:1026C000503FB0F4574AFF64432D6B8B4079D1667D
+:1026D0008CF9D41AF43BF66C0730B24F43F4B1686E
+:1026E000E62E1E4CFA423F3BC96FF1DDE4F0781153
+:1026F000CF7F744E4F1BA6E2BE55FB06BA65FF683E
+:10270000E8FEDDC411823E460D712F20FA10FE75E1
+:10271000E9DFEE8A9B09F1BF1B42E275E85F48DC06
+:102720008DF483CB389FDBADFC9EB1F473CB781E68
+:10273000D95FFE178CE4C3D8B546D25F228D2C80BA
+:10274000FDCBB89DB1D6E65C8C63185B65A37BB509
+:102750007DE0BB398FEAB95548B7FD0DEAE704FDC6
+:10276000EA7DC4FCA19CE69FFF8587ECB063455CD5
+:1027700001B6B7F2721FB61F8BB685E194927C7AD0
+:1027800006EFEDE605FDFC583F82D70F607F03FFA3
+:102790000EE34505F9A67F6C732ECAEBFE8B6D74B4
+:1027A0002F74F3B800BD6745462780CB74797EB29D
+:1027B0008ABCF4E7EDEC4376A40982D7BFEFF06C56
+:1027C00042F81759EC7F89203E4BED8FF6C9A9429C
+:1027D0007FFE07787B06E940C253E245E251E223DF
+:1027E000247E8AF0D0135EF5F8D4E351E22FFF8BFC
+:1027F000205E10AED7E32D8857B4E7FEABE06DB88E
+:1028000091BF5F66A9B2D2BB6837C2E3831D6C5229
+:102810003456717A46207EBCD71CC7315FCAC64D7C
+:1028200042D4CAF2B1583EE2FA72CF171DA6E810A0
+:102830007CDF2EF03DBF87FE643DF91E83ECBFB107
+:1028400087FA6F85C9B80BB72D776430FE71593E92
+:10285000877F815325F84FC85A487A32B3713DD3E8
+:1028600001FFA15C9AF47511BD4FF925DB8D9E5BCC
+:1028700036A997563F2DD0F9ADEF167AE9DD3ABD6E
+:1028800054AF577E3E58F8B39DCCF92DDF9DBCC6A2
+:10289000E5DACDBE3BC9DF2D9D28F82C49D059AAD9
+:1028A000436563908E9887F6C963F86E690EBEEF34
+:1028B000E9A3FC5DCC4FE93D2C40FBEB6410C498D0
+:1028C000BF174428E68F464C29C6BB7113864D18A6
+:1028D00088DF43DE658B1CD29BDE65FB0F7BC8BBAC
+:1028E0006C47263AE87EE5116B2AE95FC887A61097
+:1028F0007BE06F607F1A08FBC751D8BF307D03F6BD
+:10290000AF81B0DE3761FFC2FCDD992B18B69BE4C6
+:10291000D0C6EDC8F6F7D827C0C1A467F8DD93F399
+:10292000723F84EF5B311913D17EFE56CC2D1371AB
+:10293000BD6FC5F431F0D462A634FBE0C0EEF443C1
+:10294000C907C1F126D1787AF84A78EAE128E1FB93
+:102950004FC0F396EEE0396230E3F649EB1FA21266
+:1029600052D07F1725DEA3FC6D8E0AF97338B5446B
+:102970008C57BD8DE639B66E34330E23BF4D16C26B
+:10298000B5CACAE1A5B75BB16D7D0CA1F1BB57CD4E
+:102990009E8221B0EEB39B55BA377EE9C530B2476F
+:1029A0007DE6E7F6B67B14CF649C5F95EA5887EF27
+:1029B00088B2B7F83B67ECEBA3C9D322BF059D6E85
+:1029C000E3F7EDABAC93BAC5A33C4F4D71BA47707A
+:1029D000FAE7EF454ABDA29F85BF4B20DF2FEC49A8
+:1029E000CF1819CEE5603F0B97DB12AFD08EF249BE
+:1029F000D0CF489073493F09A7F3C5CEDEEEF9B8B2
+:102A00003E6947E8EC17E147793B363084DEE52A3A
+:102A100038A1523CF11111DF75E7905A5B0AE0A929
+:102A200029CD5383ED98FAB58A72E66D58671CDAA2
+:102A30001F4E0CB3D1F9F15B9E43BF3344C88B1CCE
+:102A400096A3B9AF26E94EB551FC4EE77BFC3EDEBE
+:102A5000D2DFF0B8CDA5BD558AFFD7C7C58D65E9D2
+:102A60003F417BE3845E2697DF11942FF21D204BBC
+:102A700082813942F4EC3047387384CC27223356B4
+:102A8000938F74F5D5D48F1E95A2298F710FD6948C
+:102A9000C715E469F2BD8B6ED5D4EF337BBC269F9E
+:102AA000E8B95B533FA97C9A368F7C0770EF5F3B98
+:102AB00057D36E405D89A69ED357A129673E776B99
+:102AC000663CCA71FE2F75ED524DF9D351053C7E1F
+:102AD000DCB680EE29A6357D4FD39FC46F521CC74C
+:102AE0002F73F0FDC107FF91DF42E0393F41BB6F1B
+:102AF0004CB08F3B66A7546BD748BA411CD4A17F1A
+:102B0000960EAA99960E7AF1389EFCDF0C73A01EE1
+:102B1000A3C73FFA2342D789FE8850B8A03F22348A
+:102B20008FFE88D0FAE88F082D477F4468F9B013EC
+:102B30005AFC8F68D5E2FF960FC6FF433C8D6ED3DB
+:102B4000D2831E4FB77DA6A58FB19E7082CB04D0D5
+:102B5000C790DE259E66C37FB4CFB3A268B41BDCEA
+:102B6000C1DC742FE07F0B5F9775F8FA92AD1B8183
+:102B7000EF5C5EF17239DED33E7F6580FB0B94BB68
+:102B80002942CEEBED00329ED4379EE3D377328CD0
+:102B9000E4D55786B648DC3FBEA3B6915D3E91753D
+:102BA000BC81EFCF0CE9E56159BDF1CA36703F94A5
+:102BB0003FB5E8BE5CDCE7E6FDDA928C7ACDBC017D
+:102BC000FC3D4196D546EFB4C8F9CC4BE2F147D66F
+:102BD0002C21A75D3C0E29228BDB7F225D768A8328
+:102BE000F6663111E7C992E765231DBE1D96817413
+:102BF000B691DBB9DA4C0E8A6BF1013DA29F12F55A
+:102C00006DD487FB0B7DB4E143AB95D31DD3ECEFC3
+:102C100083FC564D1CEE909D764D3EBB3941537F53
+:102C2000E82187A63C3790A9291F76C2A5C98F68DD
+:102C30001DA5A97FCB076E4D7E745B81A6FE6D9F9F
+:102C40001569F249ACE34984E7F8AC141EDFAF081C
+:102C50003B8083E365DE77E2E93E8D3C47C8B86C94
+:102C60008FA063FD796480D94371DE0D89CC45F76F
+:102C700041ACE23CC8B4E7148F88AB96FA3CF369E8
+:102C8000E3AA653C75D779469C5FE47922249EDAF5
+:102C90008DF397F1D45D7817EF4BEAE9F35E817716
+:102CA000FD3A0698F9FDAF86EF9AE91E8B9C9F7E50
+:102CB0005E9B443CE0766BF7EF0F3D20E8AC2DA522
+:102CC000686616D47B16B62782E775E3B9DA7C000E
+:102CD000DF861F985D2B1D371E6FDE50BE9E627C07
+:102CE00057358BDEE9A47B6B72DC6A31EEF41CA5F0
+:102CF000DBF5CD8BE6F15D2CDA4CF72E7A1E8FC317
+:102D000035C1CC1AE99D24710FE18175CDEB3154A9
+:102D1000B3D8DC64E2EFE3FB4D68272A1C0F7A602E
+:102D20002EDA0DDFDF68037DEDD93A23D97D1EDA77
+:102D30003DE63ED020BBEE950C80731AD24921E2CD
+:102D40001FFA3D97CDE39D1FCBE2F2215FFDBAEB69
+:102D50003E804523E7F9F9AF1BBA237A94EBF8BF1D
+:102D6000BA1F20E9570F2779BE6662FF1A28E625A9
+:102D7000E1D7653F11F093F7331C4B4C455B6D7405
+:102D8000CFA300E3CA24FEBECEE674F96616C737A9
+:102D9000D64379D453BD7C352B1AEDE09DCC116D13
+:102DA000BF813DF8FFE8DE04C1BFA7FB5E3DC989D6
+:102DB000EBE4430FF7BF7AA24FFAF72DEE8185C8F7
+:102DC000091EEF23F0E11F6820BFFA9A482D1FFF6C
+:102DD000358BDB5D9E96FB850FCEDD5A39C1D0AEBB
+:102DE000DFB04A15726241D7EF48E0F7F9AB4CA467
+:102DF0005F3356F438C6197CB2D14471B163DD8CAF
+:102E0000F49892CD8A7F8B82FBE898049CBFD7A769
+:102E1000DD8FEF60AED5E8FF285DABFDBED0C67F8D
+:102E20006F62BEFEDD14715E5F7883F3FAD92CE128
+:102E300007723117E95DC2FF5F2EDAE8F5AE4E3F4B
+:102E4000F79BE1795BE576278A1B93FBBB03FD3794
+:102E500021EF81003CC333711F6F34761BCFD70540
+:102E6000CF1EE2152EDA44BC828DC76774EE0FE3E5
+:102E7000FE4DE95712F52FFAAE5239D6C7DE2EE5D0
+:102E8000F2B80BE94FD2FBAB3A6D06F2B774EE8F96
+:102E900024FF3CFA71A2810ECE1BF6C58F7206E7A5
+:102EA000E76953357E107DEA59F1129D17CB533DEA
+:102EB00031D918876D74595D907FC47684DE8F2A6E
+:102EC00014762FFD7CBBCE5D63F8FB2E9D3EAECF0E
+:102ED0007616F07738402E32E42319873095C129D1
+:102EE00015526F6034CDE7DBFA73A65FCBE57ECC7D
+:102EF0006BB7517BCFDAD1941FD0B87E09DE8399AE
+:102F0000D9B0D0842EECB62797E78743D3B6FEFE20
+:102F100095E188B7714AB776F9BC6C85F8A14D1771
+:102F20005F2FD3ADD99C5F7E9D2DE5B888435AA114
+:102F3000101F2C55988C4B22392EF3579B443E9FE3
+:102F4000E797ADE2F936F1BEFE0E6147C175638ABF
+:102F5000EBC673FF6E6167C175638AEBC6EF28B776
+:102F6000308F720BF328B7308F720B53945BF8BD20
+:102F7000841525E7AADC0F353194EFAE59D9C4107A
+:102F80007E413F54681EFD50A1F5D10F155A8E7E2B
+:102F9000A8D072F44385E6D10F155A1FFD50A179D0
+:102FA00036EAAE601EE59C7BAA263F1DF4FC892113
+:102FB000FC8D7EA8D0FED10FA5E9CFB344D3FE7E11
+:102FC00056A7698F7EA8D0FA0FD6291A3FD583E27B
+:102FD0009DD3D24D71443FF31D4535D980DFFF8825
+:102FE000F8EF874D2988E79645FC5C16EEE2786E8F
+:102FF0002AE07837308EE78E3984E7E5669ECFE7A2
+:10300000F1C97AFA417FCF4413F7F7608AFE1E4C6C
+:10301000D1DF8329FA7B26A6717F0FA6E8EFC1EFE7
+:10302000E8EFC114FD3D98A2BF0753F4F7608AFE94
+:103030001E4CD1DF83EDD0DF8329FA7BF03BFA7B96
+:1030400030457F0F7E3F897E2753705EA8C70FD41F
+:103050009C1F810E35E747BB268F7A7C687DD4E3C1
+:1030600043CB518F0F2D473D3E348F7A7C687DD402
+:10307000E343F3BFCC72109FA13E1FDA0EF5F9D0E7
+:103080007C7693EF0DB49D4DDE7CF918A66D91CA48
+:10309000B30A888CE6ECF7EE433F5D5B98921C0325
+:1030A00092D3B4E2C3FB2682BEE611F17F39ACC3F2
+:1030B00080F8F688F7D43D0146F196D97F4BA4F20B
+:1030C000CB78AF5FC4DB22DE73F733FA5D12E92FF2
+:1030D00096ED5DCCAE622AEB07F3DDD7D38F2FEBF5
+:1030E00091FC0C9907DE00C67895DCE5B63C8CF7C0
+:1030F000DC6150284E62C74A1E27ACA7AB33424F53
+:10310000DA61D87704EF81747815BA0F9C6E642762
+:103110004C7908A7DA3CDC7FDFCE8E11EBAABD1517
+:10312000EF9BC8794BFB26C809BA3F37A6A3754267
+:1031300034F4E3F18DA3DF49293473BD01DBE17978
+:1031400072884F716F0DA1EFF785DCF4F8F8F83F46
+:103150007F6E0A6F17CEDBFDFCB92882E3944685AB
+:10316000E2A5C6EC666EBC9FFB1F429E0ED91D50A9
+:10317000713C6F231F4FF6EBDD9C4CF716BDAC6D19
+:103180006202F9481486725BC20DD6770CD707C766
+:103190008613689FBED97B3FB70F8FC9C7383AD611
+:1031A000C2E81DCBC9C3DFD5AC97D03E92FAA57D4E
+:1031B0002DC3A7D07BC1537C2B56E2B63ED9B7E4D2
+:1031C0008DDE587F1B73391DB415D1BD58399FC191
+:1031D000EE7D06D81659166B358429886F76342E05
+:1031E000847E80F36720BE735D267ABF77AAD16E96
+:1031F000A2F7237A883FB96A93F1273A7D4117678E
+:10320000D2B0FC8364B4272F8D3490FD77E94BFC5A
+:10321000F7003C9B14926B520FF28A38B5AB8D6F5E
+:10322000F49E8570DF67A2FE64FC4975AA3FD980D1
+:1032300071F57DB7E4C4AAA407C4E6A01EE0FBD5DF
+:103240007DA3B0DE2AFE8EE5D5C699D101EA89FBC1
+:103250006BCA04BCCA441C93171FF45683BF8B254A
+:10326000EF77B026AEEF497B8EF7B7C38E237EBDD6
+:10327000CF8877A5D77AE95EB63E8E6851A389E2FA
+:103280008E16E9F4C24AA11756DE402F1C9CA3D328
+:103290000BE5EFA588364CEDF73EC6EDC97B89C539
+:1032A00026CEFFC5FB18D9618B574C30D03BC82FB9
+:1032B00071BA295EC1F59BE297DD74BF50EA8BEFCE
+:1032C000083D66DAB52482FB1F84DE3213E32B014E
+:1032D000BE856D61220E2B91D259D778BCE5341B87
+:1032E00097036DAFF177203A7D16AE4F1D63FC1D3D
+:1032F000331D5D4E35FA0D78E1CE3506E812F293B6
+:10330000510F82FE66A35E148774EECCA7F8BD024F
+:1033100085EEBDE8E9BCD054FB06C687166E672E65
+:103320001F0BA573A05FECCFA7D0FB001E71AE955D
+:10333000F4ABA7F77911C21E65E3F6A62EBB04EA2B
+:10334000A8F44877CE2CD41BE7A16FAF2F27188C99
+:103350003B8BCCE2E5653939B31AF190D3839D42BA
+:10336000FD9E99E0E191EF20F46037407B01CAC9EE
+:10337000071ECA359784C8C9E1AEF18D434704F1F1
+:103380005DD275DF2F8BDE055DFA481AFD1E4E4FAC
+:10339000FA7029C015F9625E74DBC3F80B6B0D3946
+:1033A000CC3D31017F2750AE8F05308E70AEC837CF
+:1033B000EFBDEF4F6B6D0417CAD7E78C998571216C
+:1033C000D5D6B649487635599E02BCC718944F45A4
+:1033D000EE2405E5536E00CF849BE4FD649D3DA281
+:1033E0003987D7D7DB254AB3B8DC96BF8B72EA9111
+:1033F000837B71BF92F33FD5C3EF30ECCCE1F2F7A2
+:103400007FEB1E84FEFEC32FFB7A9ECC81753C6E43
+:10341000E0F7F9FBAA4D4CD887C82F2CE50513EF30
+:103420006004F1EEA677741B1E51ECA1F629CF5A69
+:1034300085DFA3EFC18EC3323B9EDC0EEDE6D59B4C
+:10344000E9F7F89E4BE7F4F31CD00FFD5E8AB9F55F
+:103450000DAB3308C78FEB7E6AA2DFA56181347C98
+:103460007F676E6D980BE5F17057D12F71DE1159A2
+:103470002E92438D18430EF9BB7A15BD88DFABD76A
+:103480001D7E16DF13A86971D2EF95780FE5AEC6E1
+:10349000774E86BB3C07B1DC6BB3D37B1A8B1B63C7
+:1034A00068FF9AD747DC0B651DE46793F07F47D828
+:1034B000AFD6BA38FD5E11E70E14905335F5BAB7A2
+:1034C000E3493BA1DECEA07F5FA227FB82B427A009
+:1034D000FDC01C626794F60953E6A939A837149B0E
+:1034E000B5F71265CA86F27D5F9E03E777ED5B59FB
+:1034F00093FAA07EBC41B1D37B9336C7ACD1902F59
+:103500003B61C2C84E5618EB30E3FB031D805F8C55
+:103510008F2E017E4539532CE2B4CA368D267E2B80
+:10352000F343DACD3B9C32BD7FC3D1FE2F23FD0494
+:10353000DCE4B72CB3BBCDB1217C5FDAA468DE1D1F
+:1035400090F98E1C95F311A8E308BF071E729AF13B
+:103550006D9F62502330FE8F0D7568FCC7508FE25F
+:10356000410A53D871FE0E3CCCDBC9C7CB0BE9BF77
+:10357000A489DF9B9679A84FFACFDF732209AE5E4C
+:103580003BACDB89A99DE60970203875AC87FE1C31
+:10359000340EE1A334E037E179BB18E350203FD784
+:1035A000EE37E138258DFC1D13CF3A3E8E676D8CCA
+:1035B000391BF523A3DDDC1FE1277E6F15E6477A73
+:1035C0006419C005EF63E17D37DC5BF4F0F18AF943
+:1035D0009635C5D03B0AC1EF1B4C888F393DBC8B5B
+:1035E000903594D36D49E338BABF5E6674D33D0716
+:1035F0008F80EF274BC21E45FFC09C8D4F989C903B
+:10360000EF3794D36FD6504E5F852981347AAF68F7
+:1036100049980BE739C7DE44EBEB82EF63000F05F7
+:10362000DFB92922F8025DF8306EAF6CA3169FC196
+:10363000F970F8966DF412BF2D307ACCF6D0796C13
+:103640003A9C86F7AAE6007FE3BB12CCEEA1FB9280
+:103650009F3E362B99D609F344B846BA1C93F0FD29
+:1036600021A0137E0F46AC47DEEB96E34D1CCAEF5C
+:103670009D4E1CCAE567CF7CE926BDA601F08B767E
+:10368000EF9EF8D28C821BC63597F1DF91D0F3A95B
+:10369000E44FC997924F25FF3E6B2A0A24284139EF
+:1036A00003FB6CED8BDDC0A951CC77AEC02BC0F510
+:1036B00058E83DAF6A81D7E2142DBF637FD8EF1C75
+:1036C000C1EFC5E30369F82E93AC2FC72D8EE5ED4E
+:1036D00090EE91DEE688F1B0FE52AAAFBDA752DAB5
+:1036E000252F76AF8A4779B14FE17ED0F547FB7F32
+:1036F00007F5D73D5C7FBD50B57D31EE97CCE84FE7
+:103700000E7DDF7F3EE83928271688FDB92CD0BD15
+:10371000BCB890EEA9181AC2CF653FDB93EEE1F278
+:103720002680F2E6CF7B5EFDE3AD8EE07E2AD753A6
+:10373000B2F65D93D7160A3FBEFE47333BE93E5EC5
+:10374000A9CDECC078E7D2462FC95F96007AA112C6
+:10375000127FA6A30B6FA342F7C84AEB46FAD5FF28
+:1037600045395DBA6E2ABD7B20F126DF6791FBAB40
+:103770009CFF7A31FF2621DFE60AFA9E5B3ECE9C53
+:10378000D88BF46E0CB36473C4F73965DAEF5D78E7
+:10379000EBF25F67AD467EC1FB45743E5967E2F6CA
+:1037A000BEDDDCFE7861E9C1DFDD07F5CE3FBE2579
+:1037B00099A95ABCA19EBA40E8AB0B85FDAF1BBCD2
+:1037C0006D19DA3B985FF81CC75BE9DEDFFE05DFA9
+:1037D000132B4E11F26E3D7F07A0A4791FE171CE2D
+:1037E000DA0D2627D4DB37D44970EA92FFB5B976D3
+:1037F000B42BCF5DBBC58472629F84838E1F8A45C4
+:103800009CB08433EE4B4A887F43D647F988EFDF7C
+:103810003FB4242C0AE379E4381F093A2FAD8D898F
+:10382000C5F14A6BBD3FC6F390DC0FF4EB3C1DC6FF
+:10383000F9A504FA43BE3D3DCE95BC342BA8CFEA92
+:10384000EBBF2BF0F8B489FF4E4D5244F32E8A6B38
+:10385000A80977A1FC1838B0CD8FE3227DE3BCCD59
+:1038600006FEBB3603ABDA3EC77980AA4D713598A8
+:10387000E2FB58A87AC7437EAB81DFDF4A5179FA71
+:103880009590D7501EC072D6AB8D7E5F23246E56A6
+:1038900043BF66B68D7E3FD1DC8BD1FB66925E6501
+:1038A0003F925E253DF7B4BE2B42AEDC687DA79DFE
+:1038B0001C9E66F1BB2937BD3E0BFF1D5DB92E393D
+:1038C0003FD0E1DDF4BEC7F7B3C9DE737A852B19AB
+:1038D000E3267B5EEFC6FCF86ED6AB5FA7E41B1950
+:1038E0000BDFE5CF6AE27E87D30AEC6FD0EEF4926D
+:1038F000308A6F93EBD2DBC3FF1FB640B5F6008072
+:10390000000000001F8B080000000000000BCD56D7
+:103910007D6C5355143FF7BE7EAFDDDEBAB1751B2B
+:10392000DBBA8D8F46BAF1CA80F891681D8CF0C75A
+:10393000A2DD14DD0C6C25B031C68A9360A8C6B830
+:10394000B2229211E24C3618044C876C7F18205D2D
+:10395000208AB19A8689468311E11F1292A60B38FC
+:10396000D16856310A44649E73DF2B9D08897FFA23
+:1039700092E6F4DE7B3E7FE7E3DE0F7A658085002A
+:10398000C77B1D00468093BD4E41A3BD2EB19FA7AE
+:10399000D801E6007E495B930D60AD05DA7C565C8C
+:1039A000C6F1970F9008568DF4B3CC7E831DDA9A3A
+:1039B0009026E4A4CDEEC67DBBBA7FADC7DC0F393F
+:1039C000002D90DCE7588AB2C12A1845538981AB93
+:1039D000368E7C579F463E77466EBB3EB51E88CFDF
+:1039E00066708E5600646DFFAEBE10EDB50F567852
+:1039F00018CAAD0BD6268278BE6E57A102B86EB734
+:103A00003A773BE83C54A1F4E13A6BD033358CE78C
+:103A1000EDBB1629C4BF9D812F4A7E0F1C002800D4
+:103A2000E8807B9FD7B41C6013FD43BE4D56C32472
+:103A3000ABC1F3E0C43C19E53B14B387A1FD4DC312
+:103A40002C6EC4FD060E7BD81280F2B06F5511DAD1
+:103A50004B1D64CA51923D5CEF4D9A5485339500DD
+:103A60005D0B7D35CA325CDC99999941FD8F20460A
+:103A700020515C512FC501434C1E05F2DB67207CB1
+:103A80004E2C760A9C13839336A75BC5BB11F106B7
+:103A900047010794DF6652FD2B37A426DF46BF524D
+:103AA00036AE1CC575BDE4FED649717E2581D1496F
+:103AB000721ABFACF1BFF9A8C98FFAB6D92A0B01A7
+:103AC000E9C66174A216CF9A4D9C70E8D47C6E1F33
+:103AD00079AE00D08F763C77E2F921DA7C0C60F782
+:103AE000E08A8224C9BD5BBF3F540D50A6E1784DEA
+:103AF000976CA4FC5C1F29B4EFC4D83606C20B0037
+:103B0000CF378EBC5D46F4FA88B939827C2BE5C686
+:103B100095B9186FC7E15C8F84FECCD0F714E64DE1
+:103B20004121C4A72BB0A21010AFEEBB13EFC955B3
+:103B3000681FB126DC7F8F664542C8D2DD7BA64C6C
+:103B4000E2E88AD1DF4C786EE1B1171E433D3FB108
+:103B5000C85891E07716CAD68CDEFBE9542FC28094
+:103B6000F51C78F3B2D0F30B3FFF4C0BCA77074E2E
+:103B700065939E2D439796CBB8DF59E5DFA8CC21FE
+:103B8000BD2363324204C323353E8CA35D01E1674C
+:103B900083DDF7420BE1FE9524707F98BDCE334C58
+:103BA000E07B2FCE488E8170F7C7C1201395C140AE
+:103BB000F57D5D8260146943A5DA2FE9FD20E1827D
+:103BC0007E5CCF1928A3BAD83C76A0CC89F4479B59
+:103BD000BA5E3BF6E2D7908DFCC78C06CA975F07AA
+:103BE0000605E5368498374275D389FD5A94B1DFCE
+:103BF000A764097D9B87D1A9BCCC3E4044C4F5A3F2
+:103C00000E56931FE5E194E715A45774F176CAEBBD
+:103C1000951EB312AAA03C3905DF95016915ED8701
+:103C2000B091E6335A9FB2CD43FBAD39D043F2B6E3
+:103C3000A5D138C73C074EE72E91D49212F5B55561
+:103C40005617F5927555099E6F1B6732D5E9B68FE9
+:103C5000CFAD02750DC01E8E67D7AD27C039CBEF33
+:103C6000AED3E306EA8FEEE3182FDAEF8E8E7F51A4
+:103C70008C7AB69E595FABDA1D00AAFF80D6CF5B67
+:103C80004FABB8044E4F1A36B8337AD6BBECBB4BA9
+:103C900030B7A34AEB8B43C8BA9EF2F63840EC64C7
+:103CA00063F3CE79486B641137E852653EECC37E0E
+:103CB000D74503F5516097A6CF757177A588B731C1
+:103CC0000F66D5C398A217726979C443C8C5039615
+:103CD0003DB01887CD56AB8E683860CD267AB88750
+:103CE000BB7488AB97591409F10E9AB26B684EDE1B
+:103CF00034AB346651E90EEE1BEF40176FF20B66E2
+:103D0000C0BADF210D30A24FB97B18220D8BF2FD16
+:103D100031AA5F0744190820E28CFC9EFEF4875A02
+:103D2000B2FF6479F2374097F43BDB9A57627D7CAF
+:103D3000AE68F1B993B554E773CEAA73FA881EF64C
+:103D4000989750DC3E68AA262DF89FF27E9B476824
+:103D50000EC758FC7DD29F8EF796D6C73EA3750F2F
+:103D6000433F1B9CFE6FC88F6799BEDAC32907D2F9
+:103D70007CD23FAD57CF71FE7A4D581775DAF02DD2
+:103D8000E510022C5943B1C34A75CDBC5E08A2FDB3
+:103D90003EF7D90D541F7B532630A2DDB086475D18
+:103DA000CA32C990AFB47835079CC7CC994F770C0D
+:103DB0009C75F39011FDDC0BA608F18309E7B12B8C
+:103DC000338F0DDCEC15FCB12F6FD37C2F917E9DD2
+:103DD000C841FE921D4C09234FEB8DA923DF225DC4
+:103DE0000B110FE1DA95EF9FA2381237564FFA31D7
+:103DF000BF7BE5A84971ABFA66FB1F7BED76B69DEC
+:103E000067FC9A4E4D9DF868295193B877EA629203
+:103E1000B837EEF767DAE1D4911DE48B73E2B7F2BD
+:103E20000863C43F7199FCAB3359E35236C9E97F4B
+:103E30009E7DAFC085D2DCA945E22A8199129CF60D
+:103E400061356F4F6A7D98CE8B85C05F4654CD4FEC
+:103E50001A3FE1FCACFBE433EBD83AAA9F74BFBE37
+:103E6000ACEDDFB8559943F3E546AC2A07DC0FEF1C
+:103E7000CF4B385FE99D70B8C26BF72CCBDCA76BDA
+:103E8000D2B7AB76DF4A9ADE351A4E6BAC5CC5E52D
+:103E9000F9FB70D1EA245D0769BFD3794EE70F5E65
+:103EA000BF702EA742E4ADFA1D10F99A4BF613B776
+:103EB000CFBF856D05C59277D25FF17FCC57DCBC53
+:103EC00090DE0D435CBC1B4A09F825827A39C6078F
+:103ED0002E10F3A055B228FD0F98077E9A078B6924
+:103EE0001E0C883EBFC953E738A379D023D60E48AD
+:103EF000EDD4E13AC19336F23769C6AA47EAF754DE
+:103F00008A7BA0843ABA4ACD13F5F591D76C47E97C
+:103F1000FD1666DE8326940FEBB57EDF6C8D8CE29A
+:103F2000FE748487F4686F303772B003F707D7CC1C
+:103F3000554288D334687C9D1631179EE05CAC53A3
+:103F40002D0591A315C48F7D8D710EB63C22EEF127
+:103F50000FEF4AE2BD989A0FEAB907160CD379A37E
+:103F60004BE8FB243D67F6D984BEC1466F91459C62
+:103F70001770928FE4F95FA2FC164B2A1F3E0404CF
+:103F8000DFA143DE22CAC7A12683E0DBCF7C2DED73
+:103F9000A4A7DAAAD0FB32D9623939A6A623CE96D5
+:103FA000D27B558D375DBFC30B64814B7968F2209E
+:103FB000BD434275E0EAA1F72BD5E1E24C7E9817AC
+:103FC0007361CFE4295D8F213DE62B5FCD571FFB49
+:103FD00077BEF2B57CB120D66D36E52D2AF0BFC98B
+:103FE000D53CEC9020998531495C711891FE91EF98
+:103FF0007F558DF342119DB71A93CB06E85DCCA196
+:1040000033FA803E0C519F8BF739DEA258E76D5A88
+:104010009DB7A5EBF18DFBEA313937772A4BAB47DA
+:1040200094FFDEE2EB237BBFB04BCB69F3FC5F5226
+:10403000F383ECECD5E6C89F467FBFE8F36385FFCA
+:1040400078679EF7FC504AF70CDC99984BF7CE99AD
+:104050003CDF3EE233CF4B19FC8467514A4FF124D9
+:104060005A7E2AA5F74C5BF04BD137FFD5CFB41F52
+:104070007F03DC4DE081B00C000000000000000078
+:1040800000000018000000000000000000000040D8
+:1040900000000000000000000000002800000000F8
+:1040A0000000000000000010000000000000000000
+:1040B00000000020000000000000000000000010D0
+:1040C00000000000000000000000000800000000E8
+:1040D00000000000000000000000000000000000E0
+:1040E00000000000000000000000000000000000D0
+:1040F00000000000000000000000000000000000C0
+:1041000000000000000000000000000000000000AF
+:10411000000000000000000000000000000000009F
+:10412000000000000000000000000000000000008F
+:10413000000000000000000000000000000000007F
+:10414000000000000000000000000000000000006F
+:10415000000000000000000000000000000000005F
+:10416000000000000000000000000000000000004F
+:10417000000000000000000000000000000000003F
+:10418000000000000000000000000000000000002F
+:10419000000000000000000000000000000000001F
+:1041A000000000000000000000000000000000000F
+:1041B00000000000000000000000000000000000FF
+:1041C00000000000000000000000000000000000EF
+:1041D00000000000000000000000000000000000DF
+:1041E0000000000000000000000033280010000064
+:1041F0000000000800003330001000000000000242
+:1042000000003328001000000000001000003A7881
+:104210000000000000000008800000000000000016
+:10422000000000008000000000000000000000000E
+:1042300080000000000000000000000000003120AD
+:1042400000000000000000080000336000010004CE
+:1042500000000001000033680000000000000002C0
+:1042600000003370000000000000000800003374FC
+:10427000000000000000000200003A700000000092
+:104280000000000800003A4000080000000000089C
+:1042900000003D88004000000000004000003A504F
+:1042A000000800000000000800003A60000800005C
+:1042B0000000000800003A8800C8000000000098D4
+:1042C00000003C18009800000000002800003C5846
+:1042D00000980000000000280000337803600030E0
+:1042E0000000036000003EB0000800000000000174
+:1042F00000003EB10008000000000001000020089E
+:10430000001000000000001000002000000000006D
+:104310000000000880000000000000000000000015
+:10432000800000000000000000000000000000000D
+:10433000000000000000000000000000000000007D
+:10434000000000000000000000000000000000006D
+:10435000800000000000000000000000800000005D
+:1043600000000000000000008000000000000000CD
+:1043700000000000800000000000000000000000BD
+:10438000800000000000000000000000800000002D
+:10439000000000000000000080000000000000009D
+:1043A000000000008000000000000000000000008D
+:1043B00080000000000000000000000080000000FD
+:1043C000000000000000000080000000000000006D
+:1043D000000000008000000000000000000000005D
+:1043E000800000000000000000000000000000004D
+:1043F00000000000000000000000000000000000BD
+:1044000000000000000000000000000000000000AC
+:10441000000000000000000000000000000000009C
+:10442000000000000000000080000000000000000C
+:1044300000000000800000000000000000000000FC
+:1044400080000000000000000000000000000000EC
+:1044500000000000000000008000000000000000DC
+:1044600000000000800000000000000000000000CC
+:1044700080000000000000000000000000000000BC
+:10448000000000000000000000000000000000002C
+:10449000000000000000000000000000000000001C
+:1044A000000000000000000000000000000000000C
+:1044B00000000000000000000000000000000000FC
+:1044C00000000000000012C8008000000000008012
+:1044D000000000010000000000000000000040009B
+:1044E0000490000000000490000019C800000000C3
+:1044F0000000000800004948000800000000000813
+:1045000000004928000800000000000800004938A9
+:104510000008000000000008000020080010000053
+:104520000000001000002000000000000000000853
+:104530000000401004900040000000400000499836
+:104540000008000000000001000049990008000078
+:1045500000000001800000000000000000000000DA
+:10456000800000000000000000000000800000004B
+:1045700000000000000000008000000000000000BB
+:1045800000000000800000000000000000000000AB
+:10459000800000000000000000000000800000001B
+:1045A000000000000000000080000000000000008B
+:1045B000000000008000000000000000000000007B
+:1045C00080000000000000000000000080000000EB
+:1045D000000000000000000080000000000000005B
+:1045E000000000008000000000000000000000004B
+:1045F00000000000000000000000000000000000BB
+:1046000000000000000000000000000000000000AA
+:10461000000000000000000000000000000000009A
+:10462000000000000000000000000000800000000A
+:1046300000000000000000008000000000000000FA
+:10464000000000000000000000000000000000006A
+:10465000800000000000000000000000800000005A
+:1046600000000000000000008000000000000000CA
+:1046700000000000800000000000000000000000BA
+:104680000000400000180000000000180000430077
+:104690000040000000000040000043000040000215
+:1046A0000000000100004301004000020000000083
+:1046B00000003000004000000000004080000000CA
+:1046C0000000000000000000000030000008004072
+:1046D0000000000400003004000800400000000456
+:1046E00000004B00002800000000002800004B5094
+:1046F00000100000000000100000380000800000E2
+:104700000000008000003800000800800000000267
+:1047100000003900002000000000002000002008F8
+:104720000010000000000010000020000000000049
+:104730000000000800005108000800000000000808
+:104740000000512000080000000000080000513067
+:104750000008000000000008000051C00008000030
+:1047600000000001000051C100080000000000012D
+:10477000000039400010000400000004000051D087
+:104780000030001800000010000051D80030001860
+:104790000000000280000000000000000000000097
+:1047A0008000000000000000000000008000000009
+:1047B0000000000000000000800000000000000079
+:1047C0000000000080000000000000000000000069
+:1047D00080000000000000000000000080000000D9
+:1047E0000000000000000000800000000000000049
+:1047F0000000000080000000000000000000000039
+:1048000000000000000000000000000000000000A8
+:104810000000000000000000000000000000000098
+:104820000000000000000000000000000000000088
+:104830008000000000000000000000008000000078
+:104840000000000000000000000000000000000068
+:1048500000000000000023E800800000000000804D
+:10486000000000010000000000000000000020081F
+:1048700000100000000000100000200000000000F8
+:104880000000000800002DA0000800000000000843
+:1048900000002DB80008000000000008000024E817
+:1048A00002D00028000002D000002E5800080000AE
+:1048B0000000000100002E59000800000000000167
+:1048C00000002D900008000000000008800000009B
+:1048D0000000000000000000800000000000000058
+:1048E0000000000080000000000000000000000048
+:1048F00080000000000000000000000080000000B8
+:104900000000000000000000800000000000000027
+:104910000000000080000000000000000000000017
+:104920000000000000000000000000000000000087
+:104930000000000000000000000000000000000077
+:104940000000000000000000000000000000000067
+:104950008000000000000000000000008000000057
+:104960000000000000000000000000000000000047
+:1049700000000000800000000000000000000000B7
+:104980008000000000000000000000008000000027
+:104990000000000000000000800000000000000097
+:1049A000000000000000250000400000000000089A
+:1049B000000025080040000000000028000009C099
+:1049C000012000100000000880000000000000002E
+:1049D0000000000080000000000000000000000057
+:1049E0000000402002D00028000000080000300035
+:1049F00000000000000010000000509900000000BE
+:104A000000000001000050B00000000000000002A3
+:104A1000000045A000900008000000088000000091
+:104A200000000000000000000000296000080000F5
+:104A300000000001000029610008000000000001E2
+:104A4000000029700008000400000002000029781E
+:104A5000000800040000000400002FB0000800005F
+:104A60000000000400002FB4000800000000000453
+:104A700000002FC0000000000000000800002FC848
+:104A800000000000000000080000300000000000EE
+:104A90000000001000005040000100010000000173
+:104AA0000000500000000000000000200000080886
+:104AB00000100000000000040000080C00100000BE
+:104AC00000000001000008B7000000000000000125
+:104AD000000008B600000000000000010000100007
+:104AE000003000180000000400001004003000181E
+:104AF0000000000400001008003000180000000250
+:104B00000000100A00300018000000020000100C25
+:104B100000300018000000010000100D00300018E7
+:104B2000000000010000100E00300018000000011D
+:104B300000001010003000180000000400001014E5
+:104B40000030001800000004000030000100008068
+:104B50000008000400003004010000800008000488
+:104B60000000000A000000000000000000003068A3
+:104B70000100008000000001000030690100008099
+:104B8000000000010000306C010000800000000205
+:104B90000000306E01000080000000020000307054
+:104BA000010000800000000400003074010000805B
+:104BB00000000004000030660100008000000002D8
+:104BC000000030640100008000000001000030603F
+:104BD000010000800000000200003062010000803F
+:104BE00000000002000030500100008000000004BE
+:104BF0000000305401000080000000040000305824
+:104C000001000080000000040000305C0100008012
+:104C1000000000040000307C010000800000000162
+:104C20000000307D010000800000000100001C1821
+:104C3000001000000000000400001C300010000004
+:104C40000000000400001C380010000000000004F8
+:104C50008000000000000000000000008000000054
+:104C600000000000000000008000000000000000C4
+:104C700000000000800000000000000000000000B4
+:104C800000004C10000800000000000200004C1260
+:104C9000000800000000000200004C1400080000A2
+:104CA0000000000400004C20000800000000000884
+:104CB00000004C30004000080000000800004C00DC
+:104CC000000800000000000200004C020008000084
+:104CD0000000000100004C04000800000000000279
+:104CE00000004CD0000800000000000800004CE06C
+:104CF000000800000000000400004CE40008000070
+:104D00000000000100004CF000080000000000025C
+:104D100000004CF4000800000000000200004D00FC
+:104D20000008000000000004000050000010000017
+:104D30000000000400005004001000000000000407
+:104D400000005008001000000000000400001400E3
+:104D5000000800000000000200001402000800002B
+:104D60000000000100001404000800000000000220
+:104D700000001410000800000000000200001414DD
+:104D800000080000000000020000141600080000E7
+:104D900000000002000019B8000800000000000830
+:104DA000000014200008000000000002000014248D
+:104DB0000008000000000002000019C80008000000
+:104DC0000000000800002C10000800000000000196
+:104DD00000002C11000800000000000100002C124F
+:104DE000000800000000000100002C130008000073
+:104DF0000000000100002C0000080000000000027C
+:104E000000002C02000800000000000100002C043B
+:104E1000000800000000000200002C300008000024
+:104E20000000000200002C32000800000000000218
+:104E300000002C34000800000000000200002C20BC
+:104E4000000800000000000100002C210008000004
+:104E50000000000100002C220008000000000001FA
+:104E600000002C23000800000000000100002C249A
+:104E7000000800000000000100002C2500080000D0
+:104E80000000000100002C260008000000000001C6
+:104E900000001400000800000000000200001402DE
+:104EA00000080000000000010000140400080000D9
+:104EB000000000020000141200C0001800000002F0
+:104EC0000000141000C00018000000020000141CB4
+:104ED00000C00018000000080000141400C00018F2
+:104EE000000000080000142700C0001800000001A6
+:104EF0000000142400C00018000000020000142666
+:104F000000C000180000000100001590000800001B
+:104F100000000008000015A00008000000000008C4
+:104F2000000015B00008000000000008800000002C
+:104F300000000000000000008000000000000000F1
+:104F400000000000800000000000000000000000E1
+:104F50008000000000000000000000008000000051
+:104F600000000000000000008000000000000000C1
+:104F700000000000800000000000000000000000B1
+:104F80008000000000000000000000008000000021
+:104F90000000000000000000800000000000000091
+:104FA0000000000080000000000000000000000081
+:104FB00080000000000000000000000080000000F1
+:104FC0000000000000000000800000000000000061
+:104FD0000000000080000000000000000000000051
+:104FE00080000000000000000000000080000000C1
+:104FF0000000000000000000800000000000000031
+:105000000000000080000000000000000000000020
+:105010008000000000000000000000008000000090
+:105020000000000000000000800000000000000000
+:1050300000000000800000000000000000000000F0
+:105040008000000000000000000000008000000060
+:1050500000000000000000008000000000000000D0
+:105060000000000000000000000000000000000040
+:1050700080000000000000000000000000000000B0
+:08508000060209000000000017
+:00000001FF
diff --git a/firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex b/firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex
deleted file mode 100644
index 5f04df69e7c..00000000000
--- a/firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex
+++ /dev/null
@@ -1,13181 +0,0 @@
-:1000000000004F48000000680000070C00004FB8D7
-:1000100000001ED4000056C800000094000075A027
-:1000200000009F4C00007638000000CC00011588CD
-:100030000000DC4C00011658000000940001F2A8FA
-:10004000000040000001F340000000A4000233481B
-:100050000000F38C000233F000000FFC0003278047
-:100060000000000400033780020400480000000F75
-:1000700002040054000000450204005C0000000679
-:100080000204007000000004020400780000000078
-:100090000204007C121700000204008022170000F6
-:1000A00002040084321700000604008800000005E6
-:1000B0000204009C12150000020400A0221500009A
-:1000C000020400A432150000060400A80000000489
-:1000D000020400B802100000020400BC001000007E
-:1000E000020400C010100000020400C42010000030
-:1000F000020400C830100000020400CC40100000D0
-:10010000060400D000000003020400DC0010000020
-:10011000020400E012140000020400E422140000B3
-:10012000020400E832140000020400EC4214000053
-:10013000060400F000000003010401240000000098
-:1001400001040128000000000104012C000000004F
-:100150000104013000000000020401D00000890603
-:1001600002040004000000FF02040008000000FF79
-:100170000204000C000000FF02040010000000FF59
-:10018000020400140000007F02040018000000FFB9
-:100190000204001C000000FF02040020000000FF19
-:1001A000020400240000003E0204002800000000B9
-:1001B0000204002C0000003F020400300000003F59
-:1001C000020400340000003F020400380000003F39
-:1001D0000204003C0000003F020400400000003F19
-:1001E000020400440000003F020404CC00000001AF
-:1001F00002042008000002110204200C000002008A
-:10020000020420100000020402042014000002195D
-:100210000204201C0000FFFF020420200000FFFF5A
-:10022000020420240000FFFF020420280000FFFF3A
-:1002300002042038000000200604203C0000001FBB
-:10024000020420B800000001060420BC0000005F8A
-:100250000204223807FFFFFF0204223C0000003F97
-:100260000204224007FFFFFF020422440000000FA7
-:1002700001042248000000000104224C000000009C
-:10028000010422500000000001042254000000007C
-:1002900001042258000000000104225C000000005C
-:1002A000010422600000000001042264000000003C
-:1002B00001042268000000000104226C000000001C
-:1002C00001042270000000000104227400000000FC
-:1002D00001042278000000000104227C00000000DC
-:1002E0000C042000000003E80A04200000000001C4
-:1002F0000B0420000000000A0605400000000D006D
-:100300000205004400000020020500480000003201
-:10031000020500900215002002050094021500203D
-:1003200002050098000000300205009C0810000043
-:10033000020500A000000033020500A40000003008
-:10034000020500A800000031020500AC0000000218
-:10035000020500B000000005020500B40000000620
-:10036000020500B800000002020500BC0000000207
-:10037000020500C000000000020500C400000005E6
-:10038000020500C800000002020500CC00000002C7
-:10039000020500D000000002020500D400000001A8
-:1003A00002050114000000010205011C000000010B
-:1003B0000205012000000002020502040000000105
-:1003C0000205020C0000004002050210000000407F
-:1003D0000205021C0000002002050220000000139C
-:1003E0000205022400000020060502400000000A69
-:1003F00004050280002000000205005000000007F4
-:10040000020500540000000702050058000000002B
-:100410000205005C00000008020500600000000109
-:100420000605006400000003020500D80000000675
-:1004300002050004000000010205000800000001A0
-:100440000205000C00000001020500100000000180
-:100450000205001400000001020500180000000160
-:100460000205001C00000001020500200000000140
-:100470000205002400000001020500280000000120
-:100480000205002C00000001020500300000000100
-:1004900002050034000000010205003800000001E0
-:1004A0000205003C000000010205004000000001C0
-:1004B000020500E00000000D020500E80000000059
-:1004C000020500F000000000020500F80000000036
-:1004D000020500E40000002D020500EC00000020F1
-:1004E000020500F400000020020500FC00000020CE
-:1004F000020500E00000001D020500E800000010F9
-:10050000020500F000000010020500F800000010D5
-:10051000020500E40000003D020500EC0000003090
-:10052000020500F400000030020500FC000000306D
-:10053000020500E00000004D020500E80000004058
-:10054000020500F000000040020500F80000004035
-:10055000020500E40000006D020500EC00000060F0
-:10056000020500F400000060020500FC00000060CD
-:10057000020500E00000005D020500E800000050F8
-:10058000020500F000000050020500F800000050D5
-:10059000020500E40000007D020500EC0000007090
-:1005A000020500F400000070020500FC000000706D
-:1005B0000406100002000020020600DC000000011A
-:1005C000010600D80000000004060200000302201B
-:1005D000020600DC00000000010600B80000000078
-:1005E000010600C8000000000206016C00000000C7
-:1005F000010600BC00000000010600CC0000000065
-:1006000002060170000000000718040000910000BD
-:10061000081807D800050223071C00002BF700006C
-:10062000071C80002DD10AFE071D00002F461673FF
-:10063000071D800016342245081DB13049DA022515
-:100640000118000000000000011800040000000074
-:1006500001180008000000000118000C0000000054
-:100660000118001000000000011800140000000034
-:1006700002180020000000010218002400000002FF
-:1006800002180028000000030218002C00000000DF
-:1006900002180030000000040218003400000001BD
-:1006A00002180038000000000218003C00000001A1
-:1006B000021800400000000402180044000000007E
-:1006C00002180048000000010218004C000000035E
-:1006D0000218005000000000021800540000000141
-:1006E00002180058000000040218005C000000001E
-:1006F00002180060000000010218006400000003FE
-:1007000002180068000000000218006C00000001E0
-:1007100002180070000000040218007400000000BD
-:1007200002180078000000040218007C000000039A
-:100730000618008000000002021800A400003FFF1D
-:10074000021800A8000003FF0218022400000000A5
-:1007500002180234000000000218024C00000000E1
-:10076000021802E4000000FF061810000000040058
-:10077000021B8BC000000001021B8000000000343F
-:10078000021B804000000018021B80800000000C4B
-:10079000021B80C0000000200C1B83000007A1206A
-:1007A0000A1B8300000001380B1B83000000138824
-:1007B0000A1B8340000000000C1B8340000001F472
-:1007C0000B1B834000000005021B83800007A12053
-:1007D000021B83C0000001F4021B14800000000112
-:1007E0000A1B148000000000061A1000000003B36A
-:1007F000041A1ECC00010227061A1ED000000008B1
-:10080000061A2008000000C8061A20000000000296
-:10081000041AAF4000100228061A3718000000041E
-:10082000061A371000000002061A500000000002ED
-:10083000061A500800000004061A501800000004B0
-:10084000061A502800000004061A50380000000460
-:10085000061A504800000004061A50580000000410
-:10086000061A506800000004061A507800000002C2
-:10087000041A52C000020238061A40500000000656
-:10088000041A40680002023A041A40400004023C84
-:10089000041A800000010240061A800400000003D0
-:1008A000041A801000010241061A8014000000039F
-:1008B000041A802000010242061A8024000000036E
-:1008C000041A803000010243061A8034000000033D
-:1008D000041A804000010244061A8044000000030C
-:1008E000041A805000010245061A805400000003DB
-:1008F000041A806000010246061A806400000003AA
-:10090000041A807000010247061A80740000000378
-:10091000041A808000010248061A80840000000347
-:10092000041A809000010249061A80940000000316
-:10093000041A80A00001024A061A80A400000003E5
-:10094000041A80B00001024B061A80B400000003B4
-:10095000041A80C00001024C061A80C40000000383
-:10096000041A80D00001024D061A80D40000000352
-:10097000041A80E00001024E061A80E40000000321
-:10098000041A80F00001024F061A80F400000003F0
-:10099000041A810000010250061A810400000003BD
-:1009A000041A811000010251061A8114000000038C
-:1009B000041A812000010252061A8124000000035B
-:1009C000041A813000010253061A8134000000032A
-:1009D000041A814000010254061A814400000003F9
-:1009E000041A815000010255061A815400000003C8
-:1009F000041A816000010256061A81640000000397
-:100A0000041A817000010257061A81740000000365
-:100A1000041A818000010258061A81840000000334
-:100A2000041A819000010259061A81940000000303
-:100A3000041A81A00001025A061A81A400000003D2
-:100A4000041A81B00001025B061A81B400000003A1
-:100A5000041A81C00001025C061A81C40000000370
-:100A6000041A81D00001025D061A81D4000000033F
-:100A7000041A81E00001025E061A81E4000000030E
-:100A8000041A81F00001025F061A81F400000003DD
-:100A9000041A820000010260061A820400000003AA
-:100AA000041A821000010261061A82140000000379
-:100AB000041A822000010262061A82240000000348
-:100AC000041A823000010263061A82340000000317
-:100AD000041A824000010264061A824400000003E6
-:100AE000041A825000010265061A825400000003B5
-:100AF000041A826000010266061A82640000000384
-:100B0000041A827000010267061A82740000000352
-:100B1000041A828000010268061A82840000000321
-:100B2000041A829000010269061A829400000003F0
-:100B3000041A82A00001026A061A82A400000003BF
-:100B4000041A82B00001026B061A82B4000000038E
-:100B5000041A82C00001026C061A82C4000000035D
-:100B6000041A82D00001026D061A82D4000000032C
-:100B7000041A82E00001026E061A82E400000003FB
-:100B8000041A82F00001026F061A82F400000003CA
-:100B9000041A830000010270061A83040000000397
-:100BA000041A831000010271061A83140000000366
-:100BB000041A832000010272061A83240000000335
-:100BC000041A833000010273061A83340000000304
-:100BD000041A834000010274061A834400000003D3
-:100BE000041A835000010275061A835400000003A2
-:100BF000041A836000010276061A83640000000371
-:100C0000041A837000010277061A8374000000033F
-:100C1000041A838000010278061A8384000000030E
-:100C2000041A839000010279061A839400000003DD
-:100C3000041A83A00001027A061A83A400000003AC
-:100C4000041A83B00001027B061A83B4000000037B
-:100C5000041A83C00001027C061A83C4000000034A
-:100C6000041A83D00001027D061A83D40000000319
-:100C7000041A83E00001027E061A83E400000003E8
-:100C8000041A83F00001027F061A83F400000003B7
-:100C9000041A840000010280061A84040000000384
-:100CA000041A841000010281061A84140000000353
-:100CB000041A842000010282061A84240000000322
-:100CC000041A843000010283061A843400000003F1
-:100CD000041A844000010284061A844400000003C0
-:100CE000041A845000010285061A8454000000038F
-:100CF000041A846000010286061A8464000000035E
-:100D0000041A847000010287061A8474000000032C
-:100D1000041A848000010288061A848400000003FB
-:100D2000041A849000010289061A849400000003CA
-:100D3000041A84A00001028A061A84A40000000399
-:100D4000041A84B00001028B061A84B40000000368
-:100D5000041A84C00001028C061A84C40000000337
-:100D6000041A84D00001028D061A84D40000000306
-:100D7000041A84E00001028E061A84E400000003D5
-:100D8000041A84F00001028F061A84F400000003A4
-:100D9000041A850000010290061A85040000000371
-:100DA000041A851000010291061A85140000000340
-:100DB000041A852000010292061A8524000000030F
-:100DC000041A853000010293061A853400000003DE
-:100DD000041A854000010294061A854400000003AD
-:100DE000041A855000010295061A8554000000037C
-:100DF000041A856000010296061A8564000000034B
-:100E0000041A857000010297061A85740000000319
-:100E1000041A858000010298061A858400000003E8
-:100E2000041A859000010299061A859400000003B7
-:100E3000041A85A00001029A061A85A40000000386
-:100E4000041A85B00001029B061A85B40000000355
-:100E5000041A85C00001029C061A85C40000000324
-:100E6000041A85D00001029D061A85D400000003F3
-:100E7000041A85E00001029E061A85E400000003C2
-:100E8000041A85F00001029F061A85F40000000391
-:100E9000041A8600000102A0061A8604000000035E
-:100EA000041A8610000102A1061A8614000000032D
-:100EB000041A8620000102A2061A862400000003FC
-:100EC000041A8630000102A3061A863400000003CB
-:100ED000041A8640000102A4061A8644000000039A
-:100EE000041A8650000102A5061A86540000000369
-:100EF000041A8660000102A6061A86640000000338
-:100F0000041A8670000102A7061A86740000000306
-:100F1000041A8680000102A8061A868400000003D5
-:100F2000041A8690000102A9061A869400000003A4
-:100F3000041A86A0000102AA061A86A40000000373
-:100F4000041A86B0000102AB061A86B40000000342
-:100F5000041A86C0000102AC061A86C40000000311
-:100F6000041A86D0000102AD061A86D400000003E0
-:100F7000041A86E0000102AE061A86E400000003AF
-:100F8000041A86F0000102AF061A86F4000000037E
-:100F9000041A8700000102B0061A8704000000034B
-:100FA000041A8710000102B1061A8714000000031A
-:100FB000041A8720000102B2061A872400000003E9
-:100FC000041A8730000102B3061A873400000003B8
-:100FD000041A8740000102B4061A87440000000387
-:100FE000041A8750000102B5061A87540000000356
-:100FF000041A8760000102B6061A87640000000325
-:10100000041A8770000102B7061A877400000003F3
-:10101000041A8780000102B8061A878400000003C2
-:10102000041A8790000102B9061A87940000000391
-:10103000041A87A0000102BA061A87A40000000360
-:10104000041A87B0000102BB061A87B4000000032F
-:10105000041A87C0000102BC061A87C400000003FE
-:10106000041A87D0000102BD061A87D400000003CD
-:10107000041A87E0000102BE061A87E4000000039C
-:10108000041A87F0000102BF061A87F4000000036B
-:10109000041A8800000102C0061A88040000000338
-:1010A000041A8810000102C1061A88140000000307
-:1010B000041A8820000102C2061A882400000003D6
-:1010C000041A8830000102C3061A883400000003A5
-:1010D000041A8840000102C4061A88440000000374
-:1010E000041A8850000102C5061A88540000000343
-:1010F000041A8860000102C6061A88640000000312
-:10110000041A8870000102C7061A887400000003E0
-:10111000041A8880000102C8061A888400000003AF
-:10112000041A8890000102C9061A8894000000037E
-:10113000041A88A0000102CA061A88A4000000034D
-:10114000041A88B0000102CB061A88B4000000031C
-:10115000041A88C0000102CC061A88C400000003EB
-:10116000041A88D0000102CD061A88D400000003BA
-:10117000041A88E0000102CE061A88E40000000389
-:10118000041A88F0000102CF061A88F40000000358
-:10119000041A8900000102D0061A89040000000325
-:1011A000041A8910000102D1061A891400000003F4
-:1011B000041A8920000102D2061A892400000003C3
-:1011C000041A8930000102D3061A89340000000392
-:1011D000041A8940000102D4061A89440000000361
-:1011E000041A8950000102D5061A89540000000330
-:1011F000041A8960000102D6061A896400000003FF
-:10120000041A8970000102D7061A897400000003CD
-:10121000041A8980000102D8061A8984000000039C
-:10122000041A8990000102D9061A8994000000036B
-:10123000041A89A0000102DA061A89A4000000033A
-:10124000041A89B0000102DB061A89B40000000309
-:10125000041A89C0000102DC061A89C400000003D8
-:10126000041A89D0000102DD061A89D400000003A7
-:10127000041A89E0000102DE061A89E40000000376
-:10128000041A89F0000102DF061A89F40000000345
-:10129000041A8A00000102E0061A8A040000000312
-:1012A000041A8A10000102E1061A8A1400000003E1
-:1012B000041A8A20000102E2061A8A2400000003B0
-:1012C000041A8A30000102E3061A8A34000000037F
-:1012D000041A8A40000102E4061A8A44000000034E
-:1012E000041A8A50000102E5061A8A54000000031D
-:1012F000041A8A60000102E6061A8A6400000003EC
-:10130000041A8A70000102E7061A8A7400000003BA
-:10131000041A8A80000102E8061A8A840000000389
-:10132000041A8A90000102E9061A8A940000000358
-:10133000041A8AA0000102EA061A8AA40000000327
-:10134000041A8AB0000102EB061A8AB400000003F6
-:10135000041A8AC0000102EC061A8AC400000003C5
-:10136000041A8AD0000102ED061A8AD40000000394
-:10137000041A8AE0000102EE061A8AE40000000363
-:10138000041A8AF0000102EF061A8AF40000000332
-:10139000041A8B00000102F0061A8B0400000003FF
-:1013A000041A8B10000102F1061A8B1400000003CE
-:1013B000041A8B20000102F2061A8B24000000039D
-:1013C000041A8B30000102F3061A8B34000000036C
-:1013D000041A8B40000102F4061A8B44000000033B
-:1013E000041A8B50000102F5061A8B54000000030A
-:1013F000041A8B60000102F6061A8B6400000003D9
-:10140000041A8B70000102F7061A8B7400000003A7
-:10141000041A8B80000102F8061A8B840000000376
-:10142000041A8B90000102F9061A8B940000000345
-:10143000041A8BA0000102FA061A8BA40000000314
-:10144000041A8BB0000102FB061A8BB400000003E3
-:10145000041A8BC0000102FC061A8BC400000003B2
-:10146000041A8BD0000102FD061A8BD40000000381
-:10147000041A8BE0000102FE061A8BE40000000350
-:10148000041A8BF0000102FF061A8BF4000000031F
-:10149000041A8C0000010300061A8C0400000003EB
-:1014A000041A8C1000010301061A8C1400000003BA
-:1014B000041A8C2000010302061A8C240000000389
-:1014C000041A8C3000010303061A8C340000000358
-:1014D000041A8C4000010304061A8C440000000327
-:1014E000041A8C5000010305061A8C5400000003F6
-:1014F000041A8C6000010306061A8C6400000003C5
-:10150000041A8C7000010307061A8C740000000393
-:10151000041A8C8000010308061A8C840000000362
-:10152000041A8C9000010309061A8C940000000331
-:10153000041A8CA00001030A061A8CA40000000300
-:10154000041A8CB00001030B061A8CB400000003CF
-:10155000041A8CC00001030C061A8CC4000000039E
-:10156000041A8CD00001030D061A8CD4000000036D
-:10157000041A8CE00001030E061A8CE4000000033C
-:10158000041A8CF00001030F061A8CF4000000030B
-:10159000041A8D0000010310061A8D0400000003D8
-:1015A000041A8D1000010311061A8D1400000003A7
-:1015B000041A8D2000010312061A8D240000000376
-:1015C000041A8D3000010313061A8D340000000345
-:1015D000041A8D4000010314061A8D440000000314
-:1015E000041A8D5000010315061A8D5400000003E3
-:1015F000041A8D6000010316061A8D6400000003B2
-:10160000041A8D7000010317061A8D740000000380
-:10161000041A8D8000010318061A8D84000000034F
-:10162000041A8D9000010319061A8D94000000031E
-:10163000041A8DA00001031A061A8DA400000003ED
-:10164000041A8DB00001031B061A8DB400000003BC
-:10165000041A8DC00001031C061A8DC4000000038B
-:10166000041A8DD00001031D061A8DD4000000035A
-:10167000041A8DE00001031E061A8DE40000000329
-:10168000041A8DF00001031F061A8DF400000003F8
-:10169000041A8E0000010320061A8E0400000003C5
-:1016A000041A8E1000010321061A8E140000000394
-:1016B000041A8E2000010322061A8E240000000363
-:1016C000041A8E3000010323061A8E340000000332
-:1016D000041A8E4000010324061A8E440000000301
-:1016E000041A8E5000010325061A8E5400000003D0
-:1016F000041A8E6000010326061A8E64000000039F
-:10170000041A8E7000010327061A8E74000000036D
-:10171000041A8E8000010328061A8E84000000033C
-:10172000041A8E9000010329061A8E94000000030B
-:10173000041A8EA00001032A061A8EA400000003DA
-:10174000041A8EB00001032B061A8EB400000003A9
-:10175000041A8EC00001032C061A8EC40000000378
-:10176000041A8ED00001032D061A8ED40000000347
-:10177000041A8EE00001032E061A8EE40000000316
-:10178000041A8EF00001032F061A8EF400000003E5
-:10179000041A8F0000010330061A8F0400000003B2
-:1017A000041A8F1000010331061A8F140000000381
-:1017B000041A8F2000010332061A8F240000000350
-:1017C000041A8F3000010333061A8F34000000031F
-:1017D000041A8F4000010334061A8F4400000003EE
-:1017E000041A8F5000010335061A8F5400000003BD
-:1017F000041A8F6000010336061A8F64000000038C
-:10180000041A8F7000010337061A8F74000000035A
-:10181000041A8F8000010338061A8F840000000329
-:10182000041A8F9000010339061A8F9400000003F8
-:10183000041A8FA00001033A061A8FA400000003C7
-:10184000041A8FB00001033B061A8FB40000000396
-:10185000041A8FC00001033C061A8FC40000000365
-:10186000041A8FD00001033D061A8FD40000000334
-:10187000041A8FE00001033E061A8FE400000007FF
-:10188000041A62C00020033F061AD0000000007254
-:10189000061AD24800000010061AD6B00000002038
-:1018A000061AD47000000090061AD46800000002E6
-:1018B000061AA000000001C4061A30000000001043
-:1018C000061A308000000010061A310000000010D7
-:1018D000061A318000000010061A330000000012C2
-:1018E000061A339000000070061AD4580000000257
-:1018F000061AD34800000002061AD3580000002040
-:10190000061AA710000001C4061A3040000000109B
-:10191000061A30C000000010061A31400000001006
-:10192000061A31C000000010061A334800000012E9
-:10193000061A355000000070061AD460000000023C
-:10194000061AD35000000002061AD3D80000002067
-:10195000021AAE2000000000061A5000000000022B
-:10196000061A508000000012041A40000002035FB3
-:10197000041A63C000020361061A7000000000042C
-:10198000061A320000000008021AAE24000000000F
-:10199000061A501000000002061A50C8000000127B
-:1019A000041A400800020363041A63C800020365B6
-:1019B000061A701000000004061A32200000000809
-:1019C000021AAE2800000000061A50200000000293
-:1019D000061A511000000012041A4010000203679A
-:1019E000041A63D000020369061A70200000000484
-:1019F000061A324000000008021AAE2C0000000057
-:101A0000061A503000000002061A51580000001259
-:101A1000041A40180002036B041A63D80002036D15
-:101A2000061A703000000004061A32600000000838
-:101A3000021AAE3000000000061A504000000002FA
-:101A4000061A51A000000012041A40200002036F81
-:101A5000041A63E000020371061A704000000004DB
-:101A6000061A328000000008021AAE34000000009E
-:101A7000061A505000000002061A51E80000001239
-:101A8000041A402800020373041A63E80002037575
-:101A9000061A705000000004061A32A00000000868
-:101AA000021AAE3800000000061A50600000000262
-:101AB000061A523000000012041A40300002037768
-:101AC000041A63F000020379061A70600000000433
-:101AD000061A32C000000008021AAE3C00000000E6
-:101AE000061A507000000002061A52780000001218
-:101AF000041A40380002037B041A63F80002037DD5
-:101B0000061A707000000004061A32E00000000897
-:101B10000200A468000B01C80200A294071D29114D
-:101B20000200A298000000000200A29C009C042475
-:101B30000200A2A0000000000200A2A4000002090E
-:101B40000200A270000000000200A2740000000069
-:101B50000200A270000000000200A2740000000059
-:101B60000200A270000000000200A2740000000049
-:101B70000200A270000000000200A2740000000039
-:101B8000020160A000000001020160A400000262E6
-:101B9000020160A800000002020160AC0000001811
-:101BA0000201620400000001020100B40000000113
-:101BB000020100B800000001020100DC0000000189
-:101BC0000201010000000001020101040000000107
-:101BD0000201007C003000000201008400000028A7
-:101BE0000201008C0000000002010130000000042E
-:101BF0000201025C00000001020103280000000055
-:101C0000020160580000FFFF020160700000000741
-:101C10000201608000000001020105540000003054
-:101C2000020100C400000001020100CC000000011C
-:101C3000020100F800000001020100F000000001B4
-:101C4000020100800030000002010088000000282E
-:101C500002010090000000000201013400000004B5
-:101C6000020102DC000000010201032C0000000060
-:101C70000201605C0000FFFF0201607400000007C9
-:101C800002016084000000010201056400000030D0
-:101C9000020100C800000001020100D000000001A4
-:101CA000020100FC00000001020100F4000000013C
-:101CB000020C100000000028020C20080000021195
-:101CC000020C200C00000200020C20100000020494
-:101CD000020C201C0000FFFF020C20200000FFFF70
-:101CE000020C20240000FFFF020C20280000FFFF50
-:101CF000020C203800000020020C203C00000021D3
-:101D0000020C204000000022020C204400000023AE
-:101D1000020C204800000024020C204C000000258A
-:101D2000020C205000000026020C20540000002766
-:101D3000020C205800000028020C205C0000002942
-:101D4000020C20600000002A020C20640000002B1E
-:101D5000020C20680000002C020C206C0000002DFA
-:101D6000020C20700000002E020C20740000002FD6
-:101D7000020C207800000010060C207C00000007F8
-:101D8000020C209800000011020C209C00000012A0
-:101D9000020C20A000000013060C20A40000001D6F
-:101DA000020C211800000001020C211C000000019F
-:101DB000020C212000000001060C21240000001D5F
-:101DC000020C219800000001060C219C0000000775
-:101DD000020C21B800000001020C21BC000000012F
-:101DE000020C21C000000001020C21C4000000010F
-:101DF000020C21C800000001020C21CC00000001EF
-:101E0000020C21D000000001020C21D400000001CE
-:101E1000020C21D800000001020C21DC00000001AE
-:101E2000020C21E000000001020C21E4000000018E
-:101E3000020C21E800000001020C21EC000000016E
-:101E4000020C21F000000001020C21F4000000014E
-:101E5000020C21F800000001060C21FC0000000724
-:101E6000020C221800000001060C221C00000007D2
-:101E7000020C223807FFFFFF020C223C0000003F4B
-:101E8000020C224007FFFFFF020C22440000000F5B
-:101E9000010C224800000000010C224C0000000050
-:101EA000010C225000000000010C22540000000030
-:101EB000010C225800000000010C225C0000000010
-:101EC000010C226000000000010C226400000000F0
-:101ED000010C226800000000010C226C00000000D0
-:101EE000010C227000000000010C227400000000B0
-:101EF000010C227800000000010C227C0000000090
-:101F00000C0C2000000003E80A0C20000000000177
-:101F10000B0C20000000000A020C40080000101109
-:101F2000020C400C00001000020C401000001004D5
-:101F3000020C401400001021020C401C0000FFFFA6
-:101F4000020C40200000FFFF020C40240000FFFFB5
-:101F5000020C40280000FFFF020C40380000004641
-:101F6000020C403C00000010060C40400000000243
-:101F7000020C404800000018020C404C000000F029
-:101F8000060C40500000001F020C40CC0000000175
-:101F9000060C40D00000003A020C41B800000001DD
-:101FA000060C41BC00000003020C41C80000000107
-:101FB000020C41CC00000001060C41D00000001AC8
-:101FC000020C423807FFFFFF020C423C0000003FBA
-:101FD000020C424007FFFFFF020C42440000000FCA
-:101FE000010C424800000000010C424C00000000BF
-:101FF000010C425000000000010C4254000000009F
-:10200000010C425800000000010C425C000000007E
-:10201000010C426000000000010C4264000000005E
-:10202000010C426800000000010C426C000000003E
-:10203000010C427000000000010C4274000000001E
-:10204000010C427800000000010C427C00000000FE
-:10205000010C4280000000000C0C4000000003E86E
-:102060000A0C4000000000010B0C40000000000AB8
-:10207000060D400000000A00020D0044000000327E
-:10208000020D008C02150020020D009002150020A8
-:10209000020D009408100000020D009800000033AB
-:1020A000020D009C00000002020D00A000000000D4
-:1020B000020D00A400000005020D00A800000005AC
-:1020C000060D00AC00000002020D00B4000000028A
-:1020D000020D00B800000003020D00BC0000000269
-:1020E000020D00C000000001020D00C80000000247
-:1020F000020D00CC00000002020D015C0000000196
-:10210000020D016400000001020D016800000002E0
-:10211000020D020400000001020D020C000000206C
-:10212000020D021000000040020D021400000040E9
-:10213000020D022000000003020D0224000000181E
-:10214000060D028000000012040D03000018037F3A
-:10215000060D03600000000C020D004C00000001A1
-:10216000020D005000000002020D005400000000AB
-:10217000020D005800000008060D005C000000047D
-:10218000020D00C400000004020D00040000000164
-:10219000020D000800000001020D000C000000010B
-:1021A000020D001000000001020D001400000001EB
-:1021B000020D001800000001020D001C00000001CB
-:1021C000020D002000000001020D002400000001AB
-:1021D000020D002800000001020D002C000000018B
-:1021E000020D003000000001020D0034000000016B
-:1021F000020D003800000001020D003C000000014B
-:10220000020D011400000009020D011C0000000A6B
-:10221000020D012400000000020D012C000000004E
-:10222000020D013400000000020D013C0000000B13
-:10223000020D014400000000020D011800000029F9
-:10224000020D01200000002A020D012800000020DC
-:10225000020D013000000020020D013800000020B6
-:10226000020D01400000002B020D0148000000207B
-:10227000020D011400000019020D011C0000001ADB
-:10228000020D012400000010020D012C00000010BE
-:10229000020D013400000010020D013C0000001B83
-:1022A000020D014400000010020D01180000003969
-:1022B000020D01200000003A020D0128000000304C
-:1022C000020D013000000030020D01380000003026
-:1022D000020D01400000003B020D014800000030EB
-:1022E000020D011400000049020D011C0000004A0B
-:1022F000020D012400000040020D012C00000040EE
-:10230000020D013400000040020D013C0000004BB2
-:10231000020D014400000040020D01180000006998
-:10232000020D01200000006A020D0128000000607B
-:10233000020D013000000060020D01380000006055
-:10234000020D01400000006B020D0148000000601A
-:10235000020D011400000059020D011C0000005A7A
-:10236000020D012400000050020D012C000000505D
-:10237000020D013400000050020D013C0000005B22
-:10238000020D014400000050020D01180000007908
-:10239000020D01200000007A020D012800000070EB
-:1023A000020D013000000070020D013800000070C5
-:1023B000020D01400000007B020D0148000000708A
-:1023C000060E200000000800020E004C0000003243
-:1023D000020E009402150020020E00980215002043
-:1023E000020E009C00000030020E00A00810000049
-:1023F000020E00A400000033020E00A8000000300E
-:10240000020E00AC00000031020E00B0000000021D
-:10241000020E00B400000004020E00B8000000002C
-:10242000020E00BC00000002020E00C0000000020C
-:10243000020E00C400000000020E00C800000002EE
-:10244000020E00CC00000007020E00D000000002C7
-:10245000020E00D400000002020E00D800000001AD
-:10246000020E014400000001020E014C00000001B8
-:10247000020E015000000002020E020400000001E2
-:10248000020E020C00000040020E0210000000408C
-:10249000020E021C00000004020E022000000020B8
-:1024A000020E02240000000E020E02280000001B93
-:1024B000060E030000000012040E0280001B0397AA
-:1024C000060E02EC00000005020E00540000000C95
-:1024D000020E00580000000C020E005C000000001C
-:1024E000020E006000000010020E006400000010E8
-:1024F000060E006800000003020E00DC000000036E
-:10250000020E000400000001020E0008000000019D
-:10251000020E000C00000001020E0010000000017D
-:10252000020E001400000001020E0018000000015D
-:10253000020E001C00000001020E0020000000013D
-:10254000020E002400000001020E0028000000011D
-:10255000020E002C00000001020E003000000001FD
-:10256000020E003400000001020E003800000001DD
-:10257000020E003C00000001020E004000000001BD
-:10258000020E004400000001020E01100000000FC6
-:10259000020E011800000000020E012000000000E1
-:1025A000020E012800000000020E01140000002F9E
-:1025B000020E011C00000020020E01240000000099
-:1025C000020E012C00000000020E01100000001F8E
-:1025D000020E011800000010020E01200000000091
-:1025E000020E012800000000020E01140000003F4E
-:1025F000020E011C00000030020E01240000000049
-:10260000020E012C00000000020E01100000004F1D
-:10261000020E011800000040020E01200000000020
-:10262000020E012800000000020E01140000006FDD
-:10263000020E011C00000060020E012400000000D8
-:10264000020E012C00000000020E01100000005FCD
-:10265000020E011800000050020E012000000000D0
-:10266000020E012800000000020E01140000007F8D
-:10267000020E011C00000070020E01240000000088
-:10268000020E012C000000000730040000C9000009
-:10269000083007D8000503B20734000033320000C9
-:1026A0000734800030A70CCD07350000353518F70A
-:1026B000073580002A6226450736000018D330DE31
-:1026C00008364660373403B40130000000000000D3
-:1026D000013000040000000001300008000000008C
-:1026E0000130000C0000000001300010000000006C
-:1026F0000130001400000000023000200000000142
-:102700000230002400000002023000280000000314
-:102710000230002C000000000230003000000004F5
-:1027200002300034000000010230003800000000D8
-:102730000230003C000000010230004000000004B4
-:102740000230004400000000023000480000000198
-:102750000230004C00000003023000500000000076
-:102760000230005400000001023000580000000454
-:102770000230005C00000000023000600000000138
-:102780000230006400000003023000680000000016
-:102790000230006C000000010230007000000004F4
-:1027A00002300074000000000230007800000004D5
-:1027B0000230007C000000030630008000000002B0
-:1027C000023000A400003FFF023000A8000003FF19
-:1027D0000230022400000000023002340000000039
-:1027E0000230024C00000000023002E40000FFFF53
-:1027F000063020000000080002338BC000000001FA
-:10280000023380000000001A023380400000004EB6
-:102810000233808000000010023380C000000020DE
-:102820000C3383000007A1200A3383000000013825
-:102830000B338300000013880A338340000000003C
-:102840000C338340000001F40B338340000000058B
-:10285000023383800007A120023383C0000001F40B
-:1028600002331480000000010A33148000000000CD
-:10287000063280000000010206322008000000C875
-:10288000063220000000000204328EA0001003B6C1
-:1028900006323EB00000000606323ED800000002BC
-:1028A00006323E800000000A04323EA8000203C641
-:1028B00006323E00000000200632500000000400F6
-:1028C0000632400000000004043274C0000203C855
-:1028D00006324110000000020632D0000000003035
-:1028E0000632DD40000000440632DA00000000D06D
-:1028F0000632DEA0000000020632E0000000080000
-:1029000006328450000001180632100000000188D1
-:102910000632500000000020063251000000002066
-:102920000632520000000020063253000000002052
-:10293000063254000000002006325500000000203E
-:10294000063256000000002006325700000000202A
-:102950000632580000000020063259000000002016
-:1029600006325A000000002006325B000000002002
-:1029700006325C000000002006325D0000000020EE
-:1029800006325E000000002006325F0000000020DA
-:1029900006328DF00000000204328E00000203CAED
-:1029A00006328E08000000020632DE9000000002AF
-:1029B00006321C4000000038063288B000000118C2
-:1029C00006321620000001880632508000000020E8
-:1029D00006325180000000200632528000000020A4
-:1029E0000632538000000020063254800000002090
-:1029F000063255800000002006325680000000207C
-:102A00000632578000000020063258800000002067
-:102A1000063259800000002006325A800000002053
-:102A200006325B800000002006325C80000000203F
-:102A300006325D800000002006325E80000000202B
-:102A400006325F800000002006328DF80000000290
-:102A500004328E10000203CC06328E1800000002F1
-:102A60000632DE980000000206321D200000003809
-:102A700002328D50000000000632401000000002BB
-:102A800002328D5400000000063240200000000297
-:102A900002328D5800000000063240300000000273
-:102AA00002328D5C0000000006324040000000024F
-:102AB00002328D600000000006324050000000022B
-:102AC00002328D6400000000063240600000000207
-:102AD00002328D68000000000632407000000002E3
-:102AE00002328D6C000000000632408000000002BF
-:102AF000072004000091000008200780001003CE8A
-:102B0000072400002AF300000724800015090ABDED
-:102B10000824A9F0692803D001200000000000006B
-:102B20000120000400000000012000080000000057
-:102B30000120000C00000000012000100000000037
-:102B4000012000140000000002200020000000010D
-:102B500002200024000000020220002800000003E0
-:102B60000220002C000000000220003000000004C1
-:102B700002200034000000010220003800000000A4
-:102B80000220003C00000001022000400000000480
-:102B90000220004400000000022000480000000164
-:102BA0000220004C00000003022000500000000042
-:102BB0000220005400000001022000580000000420
-:102BC0000220005C00000000022000600000000104
-:102BD00002200064000000030220006800000000E2
-:102BE0000220006C000000010220007000000004C0
-:102BF00002200074000000000220007800000004A1
-:102C00000220007C0000000306200080000000027B
-:102C1000022000A400003FFF022000A8000003FFE4
-:102C20000220022400000000022002340000000004
-:102C30000220024C00000000022002E40000FFFF1E
-:102C4000062020000000080002238BC000000001C5
-:102C500002238000000000100223804000000012C8
-:102C60000223808000000030022380C00000000E9C
-:102C70000C2383000007A1200A23830000000138F1
-:102C80000B238300000013880A2383400000000008
-:102C90000C238340000001F40B2383400000000557
-:102CA000022383800007A120022383C0000001F4D7
-:102CB00002231480000000010A2314800000000099
-:102CC000062210000000004206222008000000C872
-:102CD00006222000000000020622B000000000C60C
-:102CE0000422B318000503D20622B32C0000000B07
-:102CF0000422B358000503D70622B36C0000000B72
-:102D00000422B398000503DC0622B3AC0000000BDC
-:102D10000422B3D8000503E10622B3EC0000000B47
-:102D20000422B418000503E60622B42C0000000BB0
-:102D30000422B458000503EB0622B46C0000000B1B
-:102D40000422B498000503F00622B4AC0000000B86
-:102D50000422B4D8000503F50622B4EC0000000BF1
-:102D60000422B518000503FA0622B52C0000000B5A
-:102D70000422B558000503FF0622B56C0000000BC5
-:102D80000422B598000504040622B5AC0000000B2F
-:102D90000422B5D8000504090622B5EC0000000B9A
-:102DA0000422B6180005040E0622B62C0000000B03
-:102DB0000422B658000504130622B66C0000000B6E
-:102DC0000422B698000504180622B6AC0000000BD9
-:102DD0000422B6D80005041D0622B6EC0000000B44
-:102DE0000422B718000504220622B72C0000000BAD
-:102DF0000422B758000504270622B76C0000000B18
-:102E00000422B7980005042C0622B7AC0000000B82
-:102E10000422B7D8000504310622B7EC0000000BED
-:102E20000422B818000504360622B82C0000000B56
-:102E30000422B8580005043B0622B86C0000000BC1
-:102E40000422B898000504400622B8AC0000000B2C
-:102E50000422B8D8000504450622B8EC0000000B97
-:102E60000422B9180005044A0622B92C0000000B00
-:102E70000422B9580005044F0622B96C0000000B6B
-:102E80000422B998000504540622B9AC0000000BD6
-:102E90000422B9D8000504590622B9EC0000000B41
-:102EA0000422BA180005045E0622BA2C0000000BAA
-:102EB0000422BA58000504630622BA6C0000000B15
-:102EC0000422BA98000504680622BAAC0000000B80
-:102ED0000422BAD80005046D0622BAEC00000005F1
-:102EE0000622BB00000000530422BC4C0001047207
-:102EF0000622BC50000000030422BC5C00010473E5
-:102F00000622BC60000000030422BC6C00010474B3
-:102F10000622BC70000000030422BC7C0001047582
-:102F20000622BC80000000030422BC8C0001047651
-:102F30000622BC90000000030422BC9C0001047720
-:102F40000622BCA0000000030422BCAC00010478EF
-:102F50000622BCB0000000030422BCBC00010479BE
-:102F60000622880000000100062280000000020006
-:102F7000042212700010047A06223000000000C003
-:102F800006226700000001000622900000000400F5
-:102F900004226B080020048A022212C0FFFFFFFFF8
-:102FA000062211E800000002062212C800000009F3
-:102FB000062212EC0000000906228C000000000826
-:102FC0000222114800000000062213200000000623
-:102FD000062233000000000206226040000000309C
-:102FE00006228C20000000080222114C0000000084
-:102FF00006221338000000060622330800000002F3
-:10300000062261000000003006228C40000000080B
-:10301000022211500000000006221350000000069A
-:103020000622331000000002062261C000000030BA
-:1030300006228C60000000080222115400000000EB
-:103040000622136800000006062233180000000262
-:10305000062262800000003006228C8000000008FA
-:103060000222115800000000062213800000000612
-:1030700006223320000000020622634000000030D8
-:1030800006228CA0000000080222115C0000000053
-:1030900006221398000000060622332800000002D2
-:1030A000062264000000003006228CC000000008E8
-:1030B0000222116000000000062213B0000000068A
-:1030C0000622333000000002062264C000000030F7
-:1030D00006228CE0000000080222116400000000BB
-:1030E000062213C800000006062233380000000242
-:1030F0000622658000000030021610000000002843
-:1031000002170008000000020217002C0000000354
-:103110000217003C000000040217004800000002F3
-:103120000217004C000000900217005000000090B1
-:103130000217005400800090021700580810000089
-:10314000021700600000008A02170064000000807F
-:1031500002170068000000810217006C0000008068
-:10316000021700700000000602170078000007D068
-:103170000217007C0000076C02170038007C100466
-:10318000021700040000000F061640240000000291
-:10319000021640700000001C0216420800000001E8
-:1031A0000216421000000001021642200000000139
-:1031B0000216422800000001021642300000000101
-:1031C00002164238000000010216426000000002B0
-:1031D0000C16401C0003D0900A16401C0000009CF6
-:1031E0000B16401C000009C4021640300000000805
-:1031F000021640340000000C021640380000001097
-:1032000002164044000000200216400000000001A9
-:10321000021640D80000000102164008000000011C
-:103220000216400C000000010216401000000001D0
-:103230000216424000000000021642480000000052
-:103240000616427000000002021642500000000004
-:1032500002164258000000000616428000000002DC
-:1032600002166008000012240216600C0000121002
-:1032700002166010000012140216601C0000FFFF0E
-:10328000021660200000FFFF021660240000FFFF0E
-:10329000021660280000FFFF0216603800000020C0
-:1032A0000216603C0000002006166040000000028C
-:1032B00002166048000000230216604C0000002443
-:1032C000021660500000002502166054000000261F
-:1032D00002166058000000270216605C00000029FA
-:1032E000021660600000002A021660640000002BD5
-:1032F000021660680000002C0216606C0000002DB1
-:1033000002166070000000EC0216607400000011EC
-:1033100002166078000000120616607C0000000FA4
-:10332000021660B800000001021660BC0000000137
-:10333000061660C00000000C021660F000000001DC
-:10334000061660F400000031021661B800000001AA
-:10335000061661BC0000000D021661F000000001BD
-:10336000061661F4000000110216623807FFFFFF25
-:103370000216623C0000003F0216624007FFFFFF9A
-:10338000021662440000000F0116624800000000AF
-:103390000116624C0000000001166250000000009F
-:1033A000011662540000000001166258000000007F
-:1033B0000116625C0000000001166260000000005F
-:1033C000011662640000000001166268000000003F
-:1033D0000116626C0000000001166270000000001F
-:1033E00001166274000000000116627800000000FF
-:1033F0000116627C000000000C166000000003E86B
-:103400000A166000000000010B1660000000000AB0
-:1034100002168040000000060216804400000005ED
-:10342000021680480000000A0216804C00000005C9
-:103430000216805400000002021680CC0000000436
-:10344000021680D000000004021680D400000004A0
-:10345000021680D800000004021680DC0000000480
-:10346000021680E000000004021680E40000000460
-:10347000021680E800000004021688040000000420
-:10348000021680300000007C021680340000003DEF
-:10349000021680380000003F0216803C0000009CAD
-:1034A000021680F000000007061680F400000005F8
-:1034B0000216880C010101010216810800000000BB
-:1034C0000216810C000000040216811000000004A6
-:1034D0000216811400000002021688100801200460
-:1034E00002168118000000050216811C000000056C
-:1034F000021681200000000502168124000000054C
-:103500000216882C200810010216812800000008ED
-:103510000216812C00000006021681300000000710
-:1035200002168134000000000216883001010120DB
-:1035300006168138000000040216883401010101DA
-:1035400002168148000000000216814C00000004B1
-:10355000021681500000000402168154000000028F
-:103560000216883808012004021681580000000560
-:103570000216815C00000005021681600000000553
-:1035800002168164000000050216883C2008100124
-:1035900002168168000000080216816C0000000617
-:1035A00002168170000000070216817400000001FD
-:1035B00002168840010101200216817800000001F6
-:1035C0000216817C000000010216818000000001CB
-:1035D00002168184000000010216884401010101E5
-:1035E00002168188000000010216818C0000000490
-:1035F000021681900000000402168194000000026F
-:10360000021688480801200402168198000000056F
-:103610000216819C00000005021681A00000000532
-:10362000021681A40000000502168814200810016B
-:10363000021681A800000008021681AC00000006F6
-:10364000021681B000000007021681B400000001DC
-:103650000216881801010120021681B8000000013D
-:10366000021681BC00000001021681C000000001AA
-:10367000021681C4000000010216881C010101012C
-:10368000021681C800000001021681CC000000046F
-:10369000021681D000000004021681D4000000024E
-:1036A0000216882008012004021681D800000005B7
-:1036B000021681DC00000005021681E00000000512
-:1036C000021681E40000000502168824200810017B
-:1036D000021681E800000008021681EC00000006D6
-:1036E000021681F0000000070216E40C0000000042
-:1036F00002168828010101200616E41000000004CB
-:103700000216E000010101010216E42000000000A1
-:103710000216E424000000040216E428000000045D
-:103720000216E42C000000020216E0040801200446
-:103730000216E430000000050216E4340000000523
-:103740000216E438000000050216E43C0000000503
-:103750000216E008200810010216E44000000008EC
-:103760000216E444000000060216E44800000007C8
-:103770000216E44C000000000216E00C01010120DA
-:103780000616E450000000040216E01001010101D9
-:103790000216E460000000000216E4640000000469
-:1037A0000216E468000000040216E46C0000000247
-:1037B0000216E014080120040216E470000000055F
-:1037C0000216E474000000050216E478000000050B
-:1037D0000216E47C000000050216E0182008100123
-:1037E0000216E480000000080216E48400000006CF
-:1037F0000216E488000000070216E48C00000001B5
-:103800000216E01C010101200216E49000000001F4
-:103810000216E494000000010216E4980000000182
-:103820000216E49C000000010216E02001010101E3
-:103830000216E4A0000000010216E4A40000000447
-:103840000216E4A8000000040216E4AC0000000226
-:103850000216E024080120040216E4B0000000056E
-:103860000216E4B4000000050216E4B800000005EA
-:103870000216E4BC000000050216E0282008100132
-:103880000216E4C0000000080216E4C400000006AE
-:103890000216E4C8000000070216E4CC0000000194
-:1038A0000216E02C010101200216E4D00000000104
-:1038B0000216E4D4000000010216E4D80000000162
-:1038C0000216E4DC000000010216E03001010101F3
-:1038D0000216E4E0000000010216E4E40000000427
-:1038E0000216E4E8000000040216E4EC0000000206
-:1038F0000216E034080120040216E4F0000000057E
-:103900000216E4F4000000050216E4F800000005C9
-:103910000216E4FC000000050216E0382008100141
-:103920000216E500000000080216E504000000068B
-:103930000216E508000000070216E03C0101012024
-:1039400002168240003F003F021682440000000041
-:103950000216E524003F003F0216E52800000000A3
-:1039600002168248000000000216824C003F003F11
-:103970000216E52C000000000216E530003F003F73
-:10398000021682500100010002168254010001005B
-:103990000216E534010001000216E53801000100BD
-:1039A00006168258000000020216E53C00000000E6
-:1039B0000216E540000000000216826000C000C050
-:1039C0000216826400C000C00216E54400C000C0B8
-:1039D0000216E54800C000C0021682681E001E00E4
-:1039E0000216826C1E001E000216E54C1E001E0010
-:1039F0000216E5501E001E000216827040004000B4
-:103A000002168274400040000216E5544000400057
-:103A10000216E558400040000216827880008000BF
-:103A20000216827C800080000216E55C8000800027
-:103A30000216E560800080000216828020002000CF
-:103A400002168284200020000216E5642000200077
-:103A50000216E56820002000061682880000000299
-:103A60000216E56C000000000216E5700000000080
-:103A700002168290000000000216829400000000EE
-:103A80000216E574000000000216E5780000000050
-:103A900002168298000000000216829C00000000BE
-:103AA0000216E57C000000000216E5800000000020
-:103AB000021682A000000000021682A4000000018D
-:103AC000061682A80000000A021681F400000C0805
-:103AD000021681F800000040021681FC000001007F
-:103AE0000216820000000020021682040000001767
-:103AF00002168208000000800216820C00000200FC
-:103B000002168210000000000216821801FF01FF59
-:103B10000216821401FF01FF0216E51001FF01FFEA
-:103B20000216E50C01FF01FF0216823C00000013A3
-:103B3000021680900000013F0216806000000140E4
-:103B40000216806400000140061680680000000232
-:103B500002168070000000C0061680740000000786
-:103B60000216809C00000048021680A00000004859
-:103B7000061680A400000002021680AC0000004877
-:103B8000061680B000000007021682380000800090
-:103B900002168234000025E40216809400007FFFA4
-:103BA00002168220000F000F0216821C000F000F69
-:103BB0000216E518000F000F0216E514000F000FA3
-:103BC000021682280000000002168224FFFFFFFF79
-:103BD0000216E520000000000216E51CFFFFFFFFB3
-:103BE0000216E6BC000000000216E6C0000000025B
-:103BF0000216E6C4000000010216E6C80000000339
-:103C00000216E6CC000000040216E6D00000000612
-:103C10000216E6D4000000050216E6D800000007F0
-:103C2000021680EC000000FF0214000000000001FA
-:103C30000214000C0000000102140040000000010A
-:103C40000214004400007FFF0214000C000000007A
-:103C500002140000000000000214006C00000000CC
-:103C600002140004000000010214003000000001F2
-:103C700002140004000000000214005C00000000B8
-:103C800002140008000000010214003400000001CA
-:103C90000214000800000000021400600000000090
-:103CA00006028000000020000202005800000032DE
-:103CB000020200A003150020020200A40315002048
-:103CC000020200A801000030020200AC081000004F
-:103CD000020200B000000033020200B40000003015
-:103CE000020200B800000031020200BC0000000324
-:103CF000020200C000000006020200C4000000032F
-:103D0000020200C800000003020200CC0000000212
-:103D1000020200D000000000020200D400000002F5
-:103D2000020200DC00000000020200E000000006C9
-:103D3000020200E400000004020200E800000002A9
-:103D4000020200EC00000002020200F0000000018C
-:103D5000020200FC00000006020201200000000038
-:103D60000202013400000002020201B00000000162
-:103D70000202020C00000001020202140000000115
-:103D80000202021800000002020204040000000106
-:103D90000202040C00000040020204100000004077
-:103DA0000202041C000000040202042000000020A3
-:103DB0000202042400000002020204280000002085
-:103DC000060205000000001204020480002004AA7C
-:103DD000020200600000000F020200640000000701
-:103DE00002020068000000000202006C0000000EE9
-:103DF000020200700000000E0602007400000003C2
-:103E0000020200F4000000040202000400000001AD
-:103E100002020008000000010202000C0000000184
-:103E20000202001000000001020200140000000164
-:103E300002020018000000010202001C0000000144
-:103E40000202002000000001020200240000000124
-:103E500002020028000000010202002C0000000104
-:103E600002020030000000010202003400000001E4
-:103E700002020038000000010202003C00000001C4
-:103E800002020040000000010202004400000001A4
-:103E900002020048000000010202004C0000000184
-:103EA000020200500000000102020108000000C8E8
-:103EB0000202011800000002020201C4000000001A
-:103EC000020201CC00000000020201D40000000246
-:103ED000020201DC00000002020201E4000000FF17
-:103EE000020201EC000000FF0202010000000000DD
-:103EF0000202010C000000C80202011C00000002C6
-:103F0000020201C800000000020201D0000000000F
-:103F1000020201D800000002020201E000000002DB
-:103F2000020201E8000000FF020201F0000000FFB1
-:103F3000020201040000000002020108000000C8A3
-:103F40000202011800000002020201C40000000089
-:103F5000020201CC00000000020201D400000002B5
-:103F6000020201DC00000002020201E4000000FF86
-:103F7000020201EC000000FF02020100000000004C
-:103F80000202010C000000C80202011C0000000235
-:103F9000020201C800000000020201D0000000007F
-:103FA000020201D800000002020201E0000000024B
-:103FB000020201E8000000FF020201F0000000FF21
-:103FC000020201040000000002020108000000C813
-:103FD0000202011800000002020201C400000000F9
-:103FE000020201CC00000000020201D40000000225
-:103FF000020201DC00000002020201E4000000FFF6
-:10400000020201EC000000FF0202010000000000BB
-:104010000202010C000000C80202011C00000002A4
-:10402000020201C800000000020201D000000000EE
-:10403000020201D800000002020201E000000002BA
-:10404000020201E8000000FF020201F0000000FF90
-:10405000020201040000000002020108000000C882
-:104060000202011800000002020201C40000000068
-:10407000020201CC00000000020201D40000000294
-:10408000020201DC00000002020201E4000000FF65
-:10409000020201EC000000FF02020100000000002B
-:1040A0000202010C000000C80202011C0000000214
-:1040B000020201C800000000020201D0000000005E
-:1040C000020201D800000002020201E0000000022A
-:1040D000020201E8000000FF020201F0000000FF00
-:1040E00002020104000000000728040000A00000F4
-:1040F000082807B8000904CA072C000034DA0000B9
-:10410000072C800038F80D37072D000037B91B76D3
-:10411000072D800031782965072E00001C7A35C4F0
-:10412000082E48E036E404CC01280000000000001E
-:104130000128000400000000012800080000000021
-:104140000128000C00000000012800100000000001
-:1041500001280014000000000228002000000001D7
-:1041600002280024000000020228002800000003AA
-:104170000228002C0000000002280030000000048B
-:10418000022800340000000102280038000000006E
-:104190000228003C0000000102280040000000044A
-:1041A000022800440000000002280048000000012E
-:1041B0000228004C0000000302280050000000000C
-:1041C00002280054000000010228005800000004EA
-:1041D0000228005C000000000228006000000001CE
-:1041E00002280064000000030228006800000000AC
-:1041F0000228006C0000000102280070000000048A
-:10420000022800740000000002280078000000046A
-:104210000228007C00000003062800800000000245
-:10422000022800A400003FFF022800A8000003FFAE
-:1042300002280224000000000228023400000000CE
-:104240000228024C00000000022802E40000FFFFE8
-:104250000628200000000800022B8BC0000000018F
-:10426000022B800000000000022B8040000000189C
-:10427000022B80800000000C022B80C00000006632
-:104280000C2B83000007A1200A2B830000000138BB
-:104290000B2B8300000013880A2B834000000000D2
-:1042A0000C2B8340000001F40B2B83400000000521
-:1042B000022B83800007A120022B83C0000001F4A1
-:1042C000022B1480000000010A2B14800000000063
-:1042D000062A9AF800000004042A9B08000204CE73
-:1042E000062A9B1000000006062A90800000004865
-:1042F000062A2008000000C8062A2000000000024C
-:10430000062A91A800000086062A900000000020DE
-:10431000062A93C800000003042A93D4000104D0A5
-:10432000062A9DA800000002042A9498000404D1E3
-:10433000042A9D58000104D5062A9D5C0000001146
-:10434000042ACB20001004D6042A3000000204E620
-:10435000062A300800000100062A40400000001034
-:10436000042A4000001004E8042A8408000204F82B
-:10437000062A9DA000000002062AB000000000509E
-:10438000062ABB7000000070062AB150000000022F
-:10439000062ABB6000000004062AD00000000800C6
-:1043A000062AC00000000150062A94A8000000322E
-:1043B000062A502000000002062A503000000002A9
-:1043C000062A500000000002062A501000000002D9
-:1043D000022A520800000001042A9B28000204FA65
-:1043E000062A963800000022042A96C0000104FC28
-:1043F000062A96C400000003062A976800000022DF
-:10440000042A97F0000104FD062A97F40000000337
-:10441000062A989800000022042A9920000104FE30
-:10442000062A992400000003062A99C800000022E9
-:10443000042A9A50000104FF062A9A54000000033F
-:10444000062AB14000000002062AC54000000150C3
-:10445000062A957000000032062A5028000000024B
-:10446000062A503800000002062A50080000000208
-:10447000062A501800000002022A520C0000000117
-:10448000042A9B3000020500062A96D00000002274
-:10449000042A975800010502062A975C00000003D1
-:1044A000062A980000000022042A988800010503CB
-:1044B000062A988C00000003062A9930000000228A
-:1044C000042A99B800010504062A99BC00000003DB
-:1044D000062A9A6000000022042A9AE800010505D5
-:1044E000062A9AEC00000003062AB14800000002E8
-:1044F000022ACA8000000000042A9B38001005062A
-:10450000062A50480000000E022ACA84000000005B
-:10451000042A9B7800100516062A50800000000E21
-:10452000022ACA8800000000042A9BB80010052651
-:10453000062A50B80000000E022ACA8C00000000B3
-:10454000042A9BF800100536062A50F00000000EE1
-:10455000022ACA9000000000042A9C380010054678
-:10456000062A51280000000E022ACA94000000000A
-:10457000042A9C7800100556062A51600000000E9F
-:10458000022ACA9800000000042A9CB800100566A0
-:10459000062A51980000000E022ACA9C0000000062
-:1045A000042A9CF800100576062A51D00000000E5F
-:1045B000021010080000000102101050000000015D
-:1045C000021010000003D000021010040000003D93
-:1045D0000910180002000586091011000010078656
-:1045E0000610114000000008091011600010079625
-:1045F000061011A00000001806102400000000E0C2
-:104600000210201C00000000021020200000000109
-:10461000021020C00000000202102004000000016F
-:10462000021020080000000109103C00000507A648
-:1046300009103800000507AB09103820000507B045
-:1046400006104C000000010002104028000000107D
-:104650000210404400003FFF0210405800280000B4
-:10466000021040840084924A02104058000000006A
-:104670000210800000001080021080AC00000000DA
-:1046800002108038000000100210810000000000BD
-:10469000061081200000000202108008000002B510
-:1046A0000210801000000000061082000000004A86
-:1046B000021081080001FFFF061081400000000287
-:1046C0000210800000001A800610900000000024F4
-:1046D000061091200000004A061093700000004A66
-:1046E000061095C00000004A0210800400001080EF
-:1046F000021080B0000000010210803C0000001099
-:104700000210810400000000061081280000000251
-:104710000210800C000002B502108014000000009E
-:10472000061084000000004A0210810C0001FFFF07
-:1047300006108148000000020210800400001A8068
-:104740000610909000000024061092480000004AD5
-:10475000061094980000004A061096E80000004AEF
-:104760000210800000001080021080AC00000002E7
-:1047700002108038000000100210810000000000CC
-:10478000061081200000000202108008000002B51F
-:104790000210801000000000061082000000004A95
-:1047A000021081080001FFFF061081400000000296
-:1047B0000210800000001A80061090000000002403
-:1047C000061091200000004A061093700000004A75
-:1047D000061095C00000004A0210800400001080FE
-:1047E000021080B0000000030210803C00000010A6
-:1047F0000210810400000000061081280000000261
-:104800000210800C000002B50210801400000000AD
-:10481000061084000000004A0210810C0001FFFF16
-:1048200006108148000000020210800400001A8077
-:104830000610909000000024061092480000004AE4
-:10484000061094980000004A061096E80000004AFE
-:104850000210800000001080021080AC00000004F4
-:1048600002108038000000100210810000000000DB
-:10487000061081200000000202108008000002B52E
-:104880000210801000000000061082000000004AA4
-:10489000021081080001FFFF0610814000000002A5
-:1048A0000210800000001A80061090000000002412
-:1048B000061091200000004A061093700000004A84
-:1048C000061095C00000004A02108004000010800D
-:1048D000021080B0000000050210803C00000010B3
-:1048E0000210810400000000061081280000000270
-:1048F0000210800C000002B50210801400000000BD
-:10490000061084000000004A0210810C0001FFFF25
-:1049100006108148000000020210800400001A8086
-:104920000610909000000024061092480000004AF3
-:10493000061094980000004A061096E80000004A0D
-:104940000210800000001080021080AC0000000601
-:1049500002108038000000100210810000000000EA
-:10496000061081200000000202108008000002B53D
-:104970000210801000000000061082000000004AB3
-:10498000021081080001FFFF0610814000000002B4
-:104990000210800000001A80061090000000002421
-:1049A000061091200000004A061093700000004A93
-:1049B000061095C00000004A02108004000010801C
-:1049C000021080B0000000070210803C00000010C0
-:1049D000021081040000000006108128000000027F
-:1049E0000210800C000002B50210801400000000CC
-:1049F000061084000000004A0210810C0001FFFF35
-:104A000006108148000000020210800400001A8095
-:104A10000610909000000024061092480000004A02
-:104A2000061094980000004A061096E80000004A1C
-:104A3000021205B0000000010212049000E383405E
-:104A40000212051400003C100212066C0000000166
-:104A5000021206700000000002120494FFFFFFFF24
-:104A600002120498FFFFFFFF0212049CFFFFFFFFEA
-:104A7000021204A0FFFFFFFF021204A4FFFFFFFFCA
-:104A8000021204A8FFFFFFFF021204ACFFFFFFFFAA
-:104A9000021204B0FFFFFFFF021204BCFFFFFFFF82
-:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A
-:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A
-:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16
-:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2
-:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2
-:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2
-:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91
-:104B1000021204FCFFFFFFFF02120500FFFFFFFF70
-:104B200002120504FFFFFFFF02120508FFFFFFFF4F
-:104B30000212050CFFFFFFFF02120510FFFFFFFF2F
-:104B4000021204D4FF809000021204B4F00050005E
-:104B5000021204B8F00010000212039000000008D6
-:104B60000212039C00000008021203A000000008CB
-:104B7000021203A400000002021203BC00000004A1
-:104B8000021203C000000005021203C4000000046A
-:104B9000021203D0000000000212036C00000001AA
-:104BA000021203680000003F021201BC0000004036
-:104BB000021201C000001808021201C4000008031C
-:104BC000021201C800000803021201CC00000040DC
-:104BD000021201D000000003021201D400000803F9
-:104BE000021201D800000803021201DC00000803D1
-:104BF000021201E000010003021201E400000803B8
-:104C0000021201E800000803021201EC0000000398
-:104C1000021201F000000003021201F40000000380
-:104C2000021201F800000003021201FC0000000360
-:104C3000021202000000000302120204000000033E
-:104C400002120208000000030212020C000000031E
-:104C500002120210000000030212021400000003FE
-:104C600002120218000000030212021C00000003DE
-:104C700002120220000000030212022400000003BE
-:104C800002120228000024030212022C0000002F4E
-:104C90000212023000000009021202340000001962
-:104CA00002120238000001840212023C000001835B
-:104CB0000212024000000306021202440000001922
-:104CC00002120248000000060212024C0000030615
-:104CD00002120250000003060212025400000306F2
-:104CE0000212025800000C860212025C0000030649
-:104CF00002120260000003060212026400000006B5
-:104D000002120268000000060212026C0000000697
-:104D10000212027000000006021202740000000677
-:104D200002120278000000060212027C0000000657
-:104D30000212028000000006021202840000000637
-:104D400002120288000000060212028C0000000617
-:104D500002120290000000060212029400000006F7
-:104D600002120298000000060212029C00000006D7
-:104D7000021202A000000306021202A400000013A7
-:104D8000021202A800000006021202B00000100485
-:104D9000021202B400001004021203240010644046
-:104DA0000212032800106440021205B40000000142
-:104DB000021201B0000000010600A0000000000C7B
-:104DC0000200A050000000000200A05400000000FB
-:104DD0000200A0EC555400000200A0F055555555B6
-:104DE0000200A0F4000055550200A0F8F0000000F9
-:104DF0000200A0FC555400000200A1005555555575
-:104E00000200A104000055550200A108F0000000B6
-:104E10000200A18C555400000200A1905555555533
-:104E20000200A194000055550200A198F000000076
-:104E30000200A19C000000000200A1A000010000EF
-:104E40000200A1A4000050140200A1A8000000006C
-:104E50000200A45C00000C000200A61C000000037D
-:104E60000200A06CFF5C00000200A070FFF55FFF75
-:104E70000200A0740000FFFF0200A078F00003E031
-:104E80000200A07C000000000200A0800000A00042
-:104E90000600A084000000050200A0980FE00000BA
-:104EA0000600A09C000000070200A0B8000004005B
-:104EB0000600A0BC000000030200A0C80000100013
-:104EC0000600A0CC000000030200A0D800004000B3
-:104ED0000600A0DC000000030200A0E800010000C2
-:104EE0000600A22C000000040200A10CFF5C0000E0
-:104EF0000200A110FFF55FFF0200A1140000FFFFF8
-:104F00000200A118F00003E00200A11C0000000054
-:104F10000200A1200000A0000600A124000000055E
-:104F20000200A1380FE000000600A13C00000007CD
-:104F30000200A158000008000600A15C0000000368
-:104F40000200A168000020000600A16C0000000320
-:104F50000200A178000080000600A17C0000000390
-:104F60000200A188000200000600A23C000000042C
-:104F70000200A030000000000200A0340000000089
-:104F80000200A038000000000200A03C0000000069
-:104F90000200A040000000000200A0440000000049
-:104FA0000200A048000000000200A04C0000000029
-:104FB00000000000000000000000003000000000C1
-:104FC00000000000000000000000000000000000E1
-:104FD00000000000000000000000000000000000D1
-:104FE0000000000000300031000000000000000060
-:104FF00000000000000000000000000000000000B1
-:1050000000000000000000000000000000000000A0
-:10501000003100520000000000000000000000000D
-:105020000000000000000000000000000000000080
-:105030000000000000000000000000000052008995
-:1050400000000000000000000089008D008D00912C
-:1050500000910095009500990099009D009D00A188
-:1050600000A100A500A500A900A900AE00AE00B1F6
-:1050700000B100B4000000000000000000000000CB
-:105080000000000000000000000000000000000020
-:105090000000000000B40309030903130313031DF8
-:1050A000031D03240324032B032B03320332033990
-:1050B00003390340034003470347034E034E0355A0
-:1050C00000000000000000000000000000000000E0
-:1050D00000000000000000000000000000000000D0
-:1050E00000000000000000000000000000000000C0
-:1050F00000000000000000000000000000000000B0
-:10510000000000000000000000000000000000009F
-:10511000000000000000000000000000000000008F
-:10512000000000000000000000000000000000007F
-:10513000000000000000000000000000000000006F
-:10514000000000000000000000000000000000005F
-:10515000000000000000000000000000000000004F
-:10516000000000000000000000000000000000003F
-:105170000355035B0000000000000000035B035CBC
-:10518000035C035D035D035E035E035F035F036017
-:1051900003600361036103620362036300000000B4
-:1051A00000000000000000000000000000000000FF
-:1051B00000000000000000000000000000000000EF
-:1051C00000000000000000000363036D036D037B1B
-:1051D000037B0389000000000000000000000000C5
-:1051E00000000000000000000000000000000000BF
-:1051F00000000000000000000000000000000000AF
-:10520000000000000000000000000000000000009E
-:10521000000000000000000000000000000000008E
-:105220000389038A00000000000000000000000065
-:10523000000000000000000000000000000000006E
-:10524000000000000000000000000000038A03D6F8
-:10525000000000000000000000000000000000004E
-:10526000000000000000000000000000000000003E
-:10527000000000000000000003D604010000000050
-:10528000000000000000000000000000000000001E
-:10529000000000000000000000000000000000000E
-:1052A00000000000040104330000000000000000C2
-:1052B0000433043A043A0441044104480448044FC6
-:1052C000044F04560456045D045D04640464046BD6
-:1052D000046B04A4000000000000000004A404A863
-:1052E00004A804AC04AC04B004B004B404B404B81E
-:1052F00004B804BC04BC04C004C004C404C4051342
-:105300000513052A052A05410541054305430545C1
-:1053100005450547054705490549054B054B054D1D
-:10532000054D054F054F0551055105E805E805E90F
-:1053300005E905EA05EA05EF05EF05F405F405F9C9
-:1053400005F905FE05FE0603060306080608060D18
-:10535000060D0612061206130000000000000000F1
-:10536000000000000000000000000000000000003D
-:10537000000000000000000000000000000000002D
-:1053800006130624000000000000000000000000DA
-:10539000000000000000000000000000000000000D
-:1053A0000000000000000000000000000624063994
-:1053B0000639063C063C063F0000000000000000E5
-:1053C00000000000000000000000000000000000DD
-:1053D0000000000000000000063F0675000000000D
-:1053E00000000000000000000000000000000000BD
-:1053F00000000000000000000000000000000000AD
-:1054000000000000067507780000000000000000A2
-:10541000000000000000000000000000000000008C
-:10542000000000000000000000000000000000007C
-:105430000778077F077F078307830787000000003F
-:10544000000000000000000000000000000000005C
-:10545000000000000000000000000000078707C8EF
-:10546000000000000000000007C807D107D107DADC
-:1054700007DA07E307E307EC07EC07F507F507FE94
-:1054800007FE080708070810081008670867087C67
-:10549000087C089108910894089408970897089A3E
-:1054A000089A089D089D08A008A008A308A308A6BC
-:1054B00008A608A908A908B2000000000000000022
-:1054C00000000000000000000000000000000000DC
-:1054D00000000000000000000000000000000000CC
-:1054E00008B208B800000000000000000000000042
-:1054F00000000000000000000000000000000000AC
-:1055000000000000000000000000000008B808BB18
-:10551000000000000000000000000000000000008B
-:10552000000000000000000000000000000000007B
-:10553000000000000000000008BB08C100000000DF
-:10554000000000000000000000000000000000005B
-:10555000000000000000000000000000000000004B
-:10556000000000000000000000000000000000003B
-:1055700008C108D008D008DF08DF08EE08EE08FDF3
-:1055800008FD090C090C091B091B092A092A0939FC
-:10559000093909AA00000000000000000000000016
-:1055A00000000000000000000000000000000000FB
-:1055B00000000000000000000000000009AA09BF70
-:1055C00009BF09D009D009E109E109E209E209E3CB
-:1055D00009E309E409E409E509E509E609E609E75B
-:1055E00009E709E809E809E90000000000000000F7
-:1055F00000000000000000000000000000000000AB
-:10560000000000000000000000000000000000009A
-:10561000000000000000000000000000000000008A
-:10562000000000000000000000000000000000007A
-:10563000000000000000000000000000000000006A
-:10564000000000000000000000000000000000005A
-:10565000000000000000000000000000000000004A
-:10566000000000000000000000000000000000003A
-:10567000000000000000000000000000000000002A
-:10568000000000000000000000000000000000001A
-:10569000000000000000000000000000000000000A
-:1056A00000000000000000000000000000000000FA
-:1056B00000000000000000000000000000000000EA
-:1056C000000000000000000000010000000204C013
-:1056D0000003098000040E4000051300000617C0F7
-:1056E00000071C800008214000092600000A2AC08B
-:1056F000000B2F80000C3440000D3900000E3DC01F
-:10570000000F42800010474000114C00001250C0B2
-:105710000013558000145A4000155F00001663C046
-:105720000017688000186D4000197200001A76C0DA
-:10573000001B7B80001C8040001D8500001E89C06E
-:10574000001F8E80000093400000200000004000F9
-:1057500000006000000080000000A0000000C00009
-:105760000000E000000100000001200000014000F6
-:1057700000016000000180000001A0000001C000E5
-:105780000001E000000200000002200000024000D2
-:1057900000026000000280000002A0000002C000C1
-:1057A0000002E000000300000003200000034000AE
-:1057B00000036000000380000003A0000003C0009D
-:1057C0000003E0000004000000042000000440008A
-:1057D00000046000000480000004A0000004C00079
-:1057E0000004E00000050000000520000005400066
-:1057F00000056000000580000005A0000005C00055
-:105800000005E00000060000000620000006400041
-:1058100000066000000680000006A0000006C00030
-:105820000006E0000007000000072000000740001D
-:1058300000076000000780000007A0000007C0000C
-:105840000007E000000800000008200000084000F9
-:1058500000086000000880000008A0000008C000E8
-:105860000008E000000900000009200000094000D5
-:1058700000096000000980000009A0000009C000C4
-:105880000009E000000A0000000A2000000A4000B1
-:10589000000A6000000A8000000AA000000AC000A0
-:1058A000000AE000000B0000000B2000000B40008D
-:1058B000000B6000000B8000000BA000000BC0007C
-:1058C000000BE000000C0000000C2000000C400069
-:1058D000000C6000000C8000000CA000000CC00058
-:1058E000000CE000000D0000000D2000000D400045
-:1058F000000D6000000D8000000DA000000DC00034
-:10590000000DE000000E0000000E2000000E400020
-:10591000000E6000000E8000000EA000000EC0000F
-:10592000000EE000000F0000000F2000000F4000FC
-:10593000000F6000000F8000000FA000000FC000EB
-:10594000000FE000001000000010200000104000D8
-:1059500000106000001080000010A0000010C000C7
-:105960000010E000001100000011200000114000B4
-:1059700000116000001180000011A0000011C000A3
-:105980000011E00000120000001220000012400090
-:1059900000126000001280000012A0000012C0007F
-:1059A0000012E0000013000000132000001340006C
-:1059B00000136000001380000013A0000013C0005B
-:1059C0000013E00000140000001420000014400048
-:1059D00000146000001480000014A0000014C00037
-:1059E0000014E00000150000001520000015400024
-:1059F00000156000001580000015A0000015C00013
-:105A00000015E000001600000016200000164000FF
-:105A100000166000001680000016A0000016C000EE
-:105A20000016E000001700000017200000174000DB
-:105A300000176000001780000017A0000017C000CA
-:105A40000017E000001800000018200000184000B7
-:105A500000186000001880000018A0000018C000A6
-:105A60000018E00000190000001920000019400093
-:105A700000196000001980000019A0000019C00082
-:105A80000019E000001A0000001A2000001A40006F
-:105A9000001A6000001A8000001AA000001AC0005E
-:105AA000001AE000001B0000001B2000001B40004B
-:105AB000001B6000001B8000001BA000001BC0003A
-:105AC000001BE000001C0000001C2000001C400027
-:105AD000001C6000001C8000001CA000001CC00016
-:105AE000001CE000001D0000001D2000001D400003
-:105AF000001D6000001D8000001DA000001DC000F2
-:105B0000001DE000001E0000001E2000001E4000DE
-:105B1000001E6000001E8000001EA000001EC000CD
-:105B2000001EE000001F0000001F2000001F4000BA
-:105B3000001F6000001F8000001FA000001FC000A9
-:105B4000001FE00000200000002020000020400096
-:105B500000206000002080000020A0000020C00085
-:105B60000020E00000210000002120000021400072
-:105B700000216000002180000021A0000021C00061
-:105B80000021E0000022000000222000002240004E
-:105B900000226000002280000022A0000022C0003D
-:105BA0000022E0000023000000232000002340002A
-:105BB00000236000002380000023A0000023C00019
-:105BC0000023E00000240000002420000024400006
-:105BD00000246000002480000024A0000024C000F5
-:105BE0000024E000002500000025200000254000E2
-:105BF00000256000002580000025A0000025C000D1
-:105C00000025E000002600000026200000264000BD
-:105C100000266000002680000026A0000026C000AC
-:105C20000026E00000270000002720000027400099
-:105C300000276000002780000027A0000027C00088
-:105C40000027E00000280000002820000028400075
-:105C500000286000002880000028A0000028C00064
-:105C60000028E00000290000002920000029400051
-:105C700000296000002980000029A0000029C00040
-:105C80000029E000002A0000002A2000002A40002D
-:105C9000002A6000002A8000002AA000002AC0001C
-:105CA000002AE000002B0000002B2000002B400009
-:105CB000002B6000002B8000002BA000002BC000F8
-:105CC000002BE000002C0000002C2000002C4000E5
-:105CD000002C6000002C8000002CA000002CC000D4
-:105CE000002CE000002D0000002D2000002D4000C1
-:105CF000002D6000002D8000002DA000002DC000B0
-:105D0000002DE000002E0000002E2000002E40009C
-:105D1000002E6000002E8000002EA000002EC0008B
-:105D2000002EE000002F0000002F2000002F400078
-:105D3000002F6000002F8000002FA000002FC00067
-:105D4000002FE00000300000003020000030400054
-:105D500000306000003080000030A0000030C00043
-:105D60000030E00000310000003120000031400030
-:105D700000316000003180000031A0000031C0001F
-:105D80000031E0000032000000322000003240000C
-:105D900000326000003280000032A0000032C000FB
-:105DA0000032E000003300000033200000334000E8
-:105DB00000336000003380000033A0000033C000D7
-:105DC0000033E000003400000034200000344000C4
-:105DD00000346000003480000034A0000034C000B3
-:105DE0000034E000003500000035200000354000A0
-:105DF00000356000003580000035A0000035C0008F
-:105E00000035E0000036000000362000003640007B
-:105E100000366000003680000036A0000036C0006A
-:105E20000036E00000370000003720000037400057
-:105E300000376000003780000037A0000037C00046
-:105E40000037E00000380000003820000038400033
-:105E500000386000003880000038A0000038C00022
-:105E60000038E0000039000000392000003940000F
-:105E700000396000003980000039A0000039C000FE
-:105E80000039E000003A0000003A2000003A4000EB
-:105E9000003A6000003A8000003AA000003AC000DA
-:105EA000003AE000003B0000003B2000003B4000C7
-:105EB000003B6000003B8000003BA000003BC000B6
-:105EC000003BE000003C0000003C2000003C4000A3
-:105ED000003C6000003C8000003CA000003CC00092
-:105EE000003CE000003D0000003D2000003D40007F
-:105EF000003D6000003D8000003DA000003DC0006E
-:105F0000003DE000003E0000003E2000003E40005A
-:105F1000003E6000003E8000003EA000003EC00049
-:105F2000003EE000003F0000003F2000003F400036
-:105F3000003F6000003F8000003FA000003FC00025
-:105F4000003FE000003FE00100000000000001FF12
-:105F50000000020000007FF800007FF80000014010
-:105F600000003500000000010000FF0000000000FC
-:105F70000000FF00000000000000FF000000000023
-:105F80000000FF00000000000000FF000000000013
-:105F90000000FF00000000000000FF000000000003
-:105FA0000000FF000000000000000000140AFF00D5
-:105FB00000000001000000000020100100000000AF
-:105FC0000100900000000100000090020000900419
-:105FD00000009006000090080000900A0000900C5D
-:105FE0000000900E0000901000009012000090142D
-:105FF00000009016000090180000901A0000901CFD
-:106000000000901E000090200000902200009024CC
-:1060100000009026000090280000902A0000902C9C
-:106020000000902E0000903000009032000090346C
-:1060300000009036000090380000903A0000903C3C
-:106040000000903E0000904000009042000090440C
-:1060500000009046000090480000904A0000904CDC
-:106060000000904E000090500000905200009054AC
-:1060700000009056000090580000905A0000905C7C
-:106080000000905E0000906000009062000090644C
-:1060900000009066000090680000906A0000906C1C
-:1060A0000000906E000090700000907200009074EC
-:1060B00000009076000090780000907A0000907CBC
-:1060C0000000907E0000908000009082000090848C
-:1060D00000009086000090880000908A0000908C5C
-:1060E0000000908E0000909000009092000090942C
-:1060F00000009096000090980000909A0000909CFC
-:106100000000909E000090A0000090A2000090A4CB
-:10611000000090A6000090A8000090AA000090AC9B
-:10612000000090AE000090B0000090B2000090B46B
-:10613000000090B6000090B8000090BA000090BC3B
-:10614000000090BE000090C0000090C2000090C40B
-:10615000000090C6000090C8000090CA000090CCDB
-:10616000000090CE000090D0000090D2000090D4AB
-:10617000000090D6000090D8000090DA000090DC7B
-:10618000000090DE000090E0000090E2000090E44B
-:10619000000090E6000090E8000090EA000090EC1B
-:1061A000000090EE000090F0000090F2000090F4EB
-:1061B000000090F6000090F8000090FA000090FCBB
-:1061C000000090FE00009100000091020000910488
-:1061D00000009106000091080000910A0000910C57
-:1061E0000000910E00009110000091120000911427
-:1061F00000009116000091180000911A0000911CF7
-:106200000000911E000091200000912200009124C6
-:1062100000009126000091280000912A0000912C96
-:106220000000912E00009130000091320000913466
-:1062300000009136000091380000913A0000913C36
-:106240000000913E00009140000091420000914406
-:1062500000009146000091480000914A0000914CD6
-:106260000000914E000091500000915200009154A6
-:1062700000009156000091580000915A0000915C76
-:106280000000915E00009160000091620000916446
-:1062900000009166000091680000916A0000916C16
-:1062A0000000916E000091700000917200009174E6
-:1062B00000009176000091780000917A0000917CB6
-:1062C0000000917E00009180000091820000918486
-:1062D00000009186000091880000918A0000918C56
-:1062E0000000918E00009190000091920000919426
-:1062F00000009196000091980000919A0000919CF6
-:106300000000919E000091A0000091A2000091A4C5
-:10631000000091A6000091A8000091AA000091AC95
-:10632000000091AE000091B0000091B2000091B465
-:10633000000091B6000091B8000091BA000091BC35
-:10634000000091BE000091C0000091C2000091C405
-:10635000000091C6000091C8000091CA000091CCD5
-:10636000000091CE000091D0000091D2000091D4A5
-:10637000000091D6000091D8000091DA000091DC75
-:10638000000091DE000091E0000091E2000091E445
-:10639000000091E6000091E8000091EA000091EC15
-:1063A000000091EE000091F0000091F2000091F4E5
-:1063B000000091F6000091F8000091FA000091FCB5
-:1063C000000091FEFFFFFFFFFFFFFFFFFFFFFFFF4A
-:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
-:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
-:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
-:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
-:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
-:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
-:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
-:10644000FFFFFFFF0000000300BEBC2000000000B3
-:10645000000000050000000300BEBC20000000009A
-:10646000000000050000000300BEBC20000000008A
-:10647000000000050000000300BEBC20000000007A
-:10648000000000050000000300BEBC20000000006A
-:10649000000000050000000300BEBC20000000005A
-:1064A000000000050000000300BEBC20000000004A
-:1064B000000000050000000300BEBC20000000003A
-:1064C0000000000500002000000040C000006180C6
-:1064D000000082400000A3000000C3C00000E48070
-:1064E0000001054000012600000146C00001678050
-:1064F000000188400001A9000001C9C00001EA8034
-:1065000000020B4000022C0000024CC000026D8013
-:1065100000028E400002AF000002CFC00002F080F7
-:10652000000011400000800000010380000187008E
-:1065300000020A8000028E00000311800003950013
-:106540000004188000049C0000051F800005A300C3
-:10655000000626800006AA0000072D800007B10073
-:10656000000834800008B80000093B800009BF0023
-:10657000000A4280000AC600000B4980000BCD00D3
-:10658000000C5080000CD400000D578000005B0010
-:1065900000007FF800007FF8000000D50000150023
-:1065A0000000FF00000000000000FF0000000000ED
-:1065B0000000FF00000000000000FF0000000000DD
-:1065C0000000FF00000000000000FF0000000000CD
-:1065D0000000FF00000000000000FF0000000000BD
-:1065E000000019000000000000000000FFFFFFFF96
-:1065F0000000000003938700000000000393870061
-:1066000000007FF800007FF80000068E00003500D3
-:106610000000FF000FFFFFFF0000FF000FFFFFFF64
-:10662000000000FF0000FF000FFFFFFF0000FF0061
-:106630000FFFFFFF000000FF0000FF000FFFFFFF44
-:106640000000FF000FFFFFFF000000FF0000FF0041
-:106650000FFFFFFF0000FF000FFFFFFF000000FF24
-:106660000000FF000FFFFFFF0000FF000FFFFFFF14
-:10667000000000FF0000FF000FFFFFFF0000FF0011
-:106680000FFFFFFF000000FF0000FF000FFFFFFFF4
-:106690000000FF000FFFFFFF000000FF0000FF00F1
-:1066A0000FFFFFFF0000FF000FFFFFFF000000FFD4
-:1066B0000000FF000FFFFFFF0000FF000FFFFFFFC4
-:1066C000000000FF0000FF000FFFFFFF0000FF00C1
-:1066D0000FFFFFFF000000FF0000FF000FFFFFFFA4
-:1066E0000000FF000FFFFFFF000000FF0000FF00A1
-:1066F0000FFFFFFF0000FF000FFFFFFF000000FF84
-:106700000000FF000FFFFFFF0000FF000FFFFFFF73
-:10671000000000FF0000FF000FFFFFFF0000FF0070
-:106720000FFFFFFF000000FF0000FF000FFFFFFF53
-:106730000000FF000FFFFFFF000000FF0000FF0050
-:106740000FFFFFFF0000FF000FFFFFFF000000FF33
-:106750000000FF000FFFFFFF0000FF000FFFFFFF23
-:10676000000000FF0000FF000FFFFFFF0000FF0020
-:106770000FFFFFFF000000FF0000FF000FFFFFFF03
-:106780000000FF000FFFFFFF000000FF0000FF0000
-:106790000FFFFFFF0000FF000FFFFFFF000000FFE3
-:1067A0000000FF000FFFFFFF0000FF000FFFFFFFD3
-:1067B000000000FF0000FF000FFFFFFF0000FF00D0
-:1067C0000FFFFFFF000000FF0000FF000FFFFFFFB3
-:1067D0000000FF000FFFFFFF000000FF0000FF00B0
-:1067E0000FFFFFFF0000FF000FFFFFFF000000FF93
-:1067F0000000FF000FFFFFFF0000FF000FFFFFFF83
-:10680000000000FF0000FF000FFFFFFF0000FF007F
-:106810000FFFFFFF000000FF0000FF000FFFFFFF62
-:106820000000FF000FFFFFFF000000FF0000FF005F
-:106830000FFFFFFF0000FF000FFFFFFF000000FF42
-:106840000000FF000FFFFFFF0000FF000FFFFFFF32
-:10685000000000FF0000FF000FFFFFFF0000FF002F
-:106860000FFFFFFF000000FF0000FF000FFFFFFF12
-:106870000000FF000FFFFFFF000000FF0000FF000F
-:106880000FFFFFFF0000FF000FFFFFFF000000FFF2
-:10689000000000FF000000FF000000FF000000FFFC
-:1068A000000000FF000000FF000000FF000000FFEC
-:1068B0000000FF00000000000000FF0000000000DA
-:1068C0000000FF00000000000000FF0000000000CA
-:1068D0000000FF00000000000000FF0000000000BA
-:1068E0000000FF00000000000000FF0000000000AA
-:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
-:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
-:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
-:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
-:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
-:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
-:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
-:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
-:106970000000100000002080000031000000418075
-:10698000000052000000628000007300000083805D
-:10699000000094000000A4800000B5000000C58045
-:1069A0000000D6000000E6800000F700000107802C
-:1069B0000001180000012880000139000001498011
-:1069C00000015A0000016A8000017B0000018B80F9
-:1069D00000019C000001AC800001BD000001CD80E1
-:1069E0000001DE000001EE800001FF0000000F80CA
-:1069F00000007FF800007FF800000344000035002D
-:106A000010000000000028AD000100010005020692
-:106A1000CCCCCCC5FFFFFFFFFFFFFFFF7058103C41
-:106A20000000FF00000000000000FF000000000068
-:106A30000000FF00000000000000FF000000000058
-:106A40000000FF00000000000000FF000000000048
-:106A50000000FF00000000000000FF000000000038
-:106A60000000000000000001CCCC0201CCCCCCCC5A
-:106A7000CCCC0201CCCCCCCCCCCC0201CCCCCCCC80
-:106A8000CCCC0201CCCCCCCCCCCC0201CCCCCCCC70
-:106A9000CCCC0201CCCCCCCCCCCC0201CCCCCCCC60
-:106AA000CCCC0201CCCCCCCC00000000FFFFFFFF1F
-:106AB000000E0000011600D6002625A0002625A005
-:106AC000002625A0002625A000720000012300F367
-:106AD000002625A0002625A0002625A0002625A00A
-:106AE0000000FFFF000000000000FFFF00000000AA
-:106AF0000000FFFF000000000000FFFF000000009A
-:106B00000000FFFF000000000000FFFF0000000089
-:106B10000000FFFF000000000000FFFF0000000079
-:106B20000000FFFF000000000000FFFF0000000069
-:106B30000000FFFF000000000000FFFF0000000059
-:106B40000000FFFF000000000000FFFF0000000049
-:106B50000000FFFF000000000000FFFF0000000039
-:106B60000000FFFF000000000000FFFF0000000029
-:106B70000000FFFF000000000000FFFF0000000019
-:106B80000000FFFF000000000000FFFF0000000009
-:106B90000000FFFF000000000000FFFF00000000F9
-:106BA0000000FFFF000000000000FFFF00000000E9
-:106BB0000000FFFF000000000000FFFF00000000D9
-:106BC0000000FFFF000000000000FFFF00000000C9
-:106BD0000000FFFF000000000000FFFF00000000B9
-:106BE0000000FFFF000000000000FFFF00000000A9
-:106BF0000000FFFF000000000000FFFF0000000099
-:106C00000000FFFF000000000000FFFF0000000088
-:106C10000000FFFF000000000000FFFF0000000078
-:106C20000000FFFF000000000000FFFF0000000068
-:106C30000000FFFF000000000000FFFF0000000058
-:106C40000000FFFF000000000000FFFF0000000048
-:106C50000000FFFF000000000000FFFF0000000038
-:106C60000000FFFF000000000000FFFF0000000028
-:106C70000000FFFF000000000000FFFF0000000018
-:106C80000000FFFF000000000000FFFF0000000008
-:106C90000000FFFF000000000000FFFF00000000F8
-:106CA0000000FFFF000000000000FFFF00000000E8
-:106CB0000000FFFF000000000000FFFF00000000D8
-:106CC0000000FFFF000000000000FFFF00000000C8
-:106CD0000000FFFF000000000000FFFF00000000B8
-:106CE000FFFFFFF3318FFFFF0C30C30CC30C30C329
-:106CF000CF3CF300F3CF3CF30000CF3CCDCDCDCD66
-:106D0000FFFFFFF130EFFFFF0C30C30CC30C30C3AB
-:106D1000CF3CF300F3CF3CF30001CF3CCDCDCDCD44
-:106D2000FFFFFFF6305FFFFF0C30C30CC30C30C316
-:106D3000CF3CF300F3CF3CF30002CF3CCDCDCDCD23
-:106D4000FFFFF4061CBFFFFF0C30C305C30C30C3AC
-:106D5000CF300014F3CF3CF30004CF3CCDCDCDCDEC
-:106D6000FFFFFFF2304FFFFF0C30C30CC30C30C3EA
-:106D7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDD
-:106D8000FFFFFFFA302FFFFF0C30C30CC30C30C3E2
-:106D9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB5
-:106DA000FFFFFFF731EFFFFF0C30C30CC30C30C304
-:106DB000CF3CF300F3CF3CF30020CF3CCDCDCDCD85
-:106DC000FFFFFFF5302FFFFF0C30C30CC30C30C3A7
-:106DD000CF3CF300F3CF3CF30040CF3CCDCDCDCD45
-:106DE000FFFFFFF3318FFFFF0C30C30CC30C30C328
-:106DF000CF3CF300F3CF3CF30000CF3CCDCDCDCD65
-:106E0000FFFFFFF1310FFFFF0C30C30CC30C30C389
-:106E1000CF3CF300F3CF3CF30001CF3CCDCDCDCD43
-:106E2000FFFFFFF6305FFFFF0C30C30CC30C30C315
-:106E3000CF3CF300F3CF3CF30002CF3CCDCDCDCD22
-:106E4000FFFFF4061CBFFFFF0C30C305C30C30C3AB
-:106E5000CF300014F3CF3CF30004CF3CCDCDCDCDEB
-:106E6000FFFFFFF2304FFFFF0C30C30CC30C30C3E9
-:106E7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDC
-:106E8000FFFFFFFA302FFFFF0C30C30CC30C30C3E1
-:106E9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB4
-:106EA000FFFFFFF730EFFFFF0C30C30CC30C30C304
-:106EB000CF3CF300F3CF3CF30020CF3CCDCDCDCD84
-:106EC000FFFFFFF5304FFFFF0C30C30CC30C30C386
-:106ED000CF3CF300F3CF3CF30040CF3CCDCDCDCD44
-:106EE000FFFFFFFF30CFFFFF0C30C30CC30C30C3DC
-:106EF000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD98
-:106F0000FFFFFFFF30CFFFFF0C30C30CC30C30C3BB
-:106F1000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD76
-:106F2000FFFFFFFF30CFFFFF0C30C30CC30C30C39B
-:106F3000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD55
-:106F4000FFFFFFFF30CFFFFF0C30C30CC30C30C37B
-:106F5000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD33
-:106F6000FFFFFFFF30CFFFFF0C30C30CC30C30C35B
-:106F7000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0F
-:106F8000FFFFFFFF30CFFFFF0C30C30CC30C30C33B
-:106F9000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE7
-:106FA000FFFFFFFF30CFFFFF0C30C30CC30C30C31B
-:106FB000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB7
-:106FC000FFFFFFFF30CFFFFF0C30C30CC30C30C3FB
-:106FD000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD77
-:106FE000FFFFFFF3320FFFFF0C30C30CC30C30C3A5
-:106FF000CF3CF300F3CF3CF30000CF3CCDCDCDCD63
-:10700000FFFFFFF1310FFFFF0C30C30CC30C30C387
-:10701000CF3CF300F3CF3CF30001CF3CCDCDCDCD41
-:10702000FFFFFFF6305FFFFF0C30C30CC30C30C313
-:10703000CF3CF300F3CF3CF30002CF3CCDCDCDCD20
-:10704000FFFFF4061CBFFFFF0C30C305C30C30C3A9
-:10705000CF300014F3CF3CF30004CF3CCDCDCDCDE9
-:10706000FFFFFFF2304FFFFF0C30C30CC30C30C3E7
-:10707000CF3CF300F3CF3CF30008CF3CCDCDCDCDDA
-:10708000FFFFFF8A042FFFFF0C30C30CC30C30C37B
-:10709000CF3CC000F3CF3CF30010CF3CCDCDCDCDE5
-:1070A000FFFFFF9705CFFFFF0C30C30CC30C30C3AD
-:1070B000CF3CC000F3CF3CF30020CF3CCDCDCDCDB5
-:1070C000FFFFFFF5310FFFFF0C30C30CC30C30C3C3
-:1070D000CF3CF300F3CF3CF30040CF3CCDCDCDCD42
-:1070E000FFFFFFF3320FFFFF0C30C30CC30C30C3A4
-:1070F000CF3CF300F3CF3CF30000CF3CCDCDCDCD62
-:10710000FFFFFFF1302FFFFF0C30C30CC30C30C367
-:10711000CF3CF300F3CF3CF30001CF3CCDCDCDCD40
-:10712000FFFFFFF6305FFFFF0C30C30CC30C30C312
-:10713000CF3CF300F3CF3CF30002CF3CCDCDCDCD1F
-:10714000FFFFFF061CBFFFFF0C30C30CC30C30C396
-:10715000CF3CC014F3CF3CF30004CF3CCDCDCDCD1C
-:10716000FFFFFFF2304FFFFF0C30C30CC30C30C3E6
-:10717000CF3CF300F3CF3CF30008CF3CCDCDCDCDD9
-:10718000FFFFFFFA302FFFFF0C30C30CC30C30C3DE
-:10719000CF3CF300F3CF3CF30010CF3CCDCDCDCDB1
-:1071A000FFFFFFF731CFFFFF0C30C30CC30C30C320
-:1071B000CF3CF300F3CF3CF30020CF3CCDCDCDCD81
-:1071C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F9
-:1071D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD75
-:1071E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D9
-:1071F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD95
-:10720000FFFFFFFF30CFFFFF0C30C30CC30C30C3B8
-:10721000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD73
-:10722000FFFFFFFF30CFFFFF0C30C30CC30C30C398
-:10723000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD52
-:10724000FFFFFFFF30CFFFFF0C30C30CC30C30C378
-:10725000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD30
-:10726000FFFFFFFF30CFFFFF0C30C30CC30C30C358
-:10727000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0C
-:10728000FFFFFFFF30CFFFFF0C30C30CC30C30C338
-:10729000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE4
-:1072A000FFFFFFFF30CFFFFF0C30C30CC30C30C318
-:1072B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB4
-:1072C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F8
-:1072D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD74
-:1072E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D8
-:1072F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD94
-:10730000FFFFFFFF30CFFFFF0C30C30CC30C30C3B7
-:10731000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD72
-:10732000FFFFFFFF30CFFFFF0C30C30CC30C30C397
-:10733000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD51
-:10734000FFFFFFFF30CFFFFF0C30C30CC30C30C377
-:10735000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2F
-:10736000FFFFFFFF30CFFFFF0C30C30CC30C30C357
-:10737000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0B
-:10738000FFFFFFFF30CFFFFF0C30C30CC30C30C337
-:10739000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE3
-:1073A000FFFFFFFF30CFFFFF0C30C30CC30C30C317
-:1073B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB3
-:1073C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F7
-:1073D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD73
-:1073E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D7
-:1073F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD93
-:10740000FFFFFFFF30CFFFFF0C30C30CC30C30C3B6
-:10741000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD71
-:10742000FFFFFFFF30CFFFFF0C30C30CC30C30C396
-:10743000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD50
-:10744000FFFFFFFF30CFFFFF0C30C30CC30C30C376
-:10745000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2E
-:10746000FFFFFFFF30CFFFFF0C30C30CC30C30C356
-:10747000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0A
-:10748000FFFFFFFF30CFFFFF0C30C30CC30C30C336
-:10749000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE2
-:1074A000FFFFFFFF30CFFFFF0C30C30CC30C30C316
-:1074B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB2
-:1074C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F6
-:1074D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD72
-:1074E000000C0000000700C000028130000B815832
-:1074F0000002021000010230000F024000010330C0
-:10750000000C0000000800C000028140000B8168F0
-:10751000000202200001024000070250000202C0E7
-:10752000001000000008010000028180000B81A80B
-:107530000002026000018280000E82980008038031
-:107540000010000000010100000281100009013854
-:10755000000201C8000101E8000E01F8000002D895
-:10756000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC5B
-:1075700000002000CCCCCCCCCCCCCCCCCCCCCCCC5B
-:10758000CCCCCCCC00002000CCCCCCCCCCCCCCCC4B
-:10759000CCCCCCCCCCCCCCCC040020000000000067
-:1075A0001F8B080000000000000BFB51CFC0F00350
-:1075B0008AB7B13130ECE644F0E98159181818F86F
-:1075C00099C8D7BF1168C04E20BE01C4075948D71B
-:1075D0007F551AC15E26C9C0700A8827883330B427
-:1075E0004A21C4ED651818EE01F92BA16272403DE5
-:1075F00073A4C977F3281E3CB8D014951F620CA160
-:107600005F9840E82234F950A8BCB81E842E36C5D5
-:107610006EAE841E71F6A7A9A0F2BD55F0ABCFD512
-:1076200040E5C7A2A90F81F2017EE9B234D8030078
-:1076300000000000000000001F8B08000000000098
-:10764000000BED7D0B7455D5B5E8DA9FB3CFFF6421
-:10765000278470123EEEC400C1063C4280A0A83BC5
-:10766000FC1A7DD41E1025E5A11C446B004922A6FE
-:10767000D78C96D76CC8870450E3E751BD457BA0F3
-:10768000D88B0E5BA3A68ABDB43D887AA9C3DB2242
-:107690005AA52D7A83FA2C58A0B1572ABD4FCB5B3F
-:1076A00073AEB592BD77CEC9C74F47EF788D43769D
-:1076B000D6DEEB3BFF6BCEB95634D943F22E27E42E
-:1076C0001CFCD0A7291142A6F73DC92D5932C92368
-:1076D000E41B3E823F1FF923534816210D3EF6BCA2
-:1076E0003D10D905CF2D8D84A426C2F771491221F2
-:1076F000244848899A0B2D02B1870BE15977617CA8
-:10770000323E67C23387C8848C84F218FDBD20EBFB
-:10771000FB9C42FF399AA880F114F68AA8A43C96F3
-:10772000C2F6DF226446DF3C48DD57F578B86FDEED
-:10773000EEA7A26B24C5EB9E837F94E5598950E6A2
-:10774000FA0D47A5C79FB7D51F4FC2B9382F95A8C7
-:10775000382FDE9E108BD8E7E7EEE7A346F2F8F36A
-:10776000E3FBC32DD3B8026E6D8D3E7CB636EA24A2
-:10777000E5258436333B4BE93344CC5DA5FDDBCDB9
-:107780002312871F9F0F8C63D0FAF47F42E1DE9CA7
-:107790004B9241C0214938E0D61C5AEC33D3F42730
-:1077A0009E2497C2AD84CFB9A8FF7AFD302F0A0777
-:1077B0003FCC2B0D3C97C2BCA6F79F97BFD83DAFDF
-:1077C0006A6287CF70E7159844C821C0876A128221
-:1077D00078B9CDD19FAC9B56779AFE08A70BD5E020
-:1077E000EB1B229E822572DFF8000723E0A02F6F9B
-:1077F00034C7496F6EBA067820BE3A387CE20AE395
-:1078000007AB0F8FF4199A1D93803568F110E02DA6
-:107810009F30F8E557B7DE2A4F2194D53A0F4EA096
-:10782000F0CBEF5EB99040F9E8152780DF9ACBA640
-:1078300056CEA5F5B2CB63AF2CA04D423143027AB0
-:10784000DD0A9D15407F5FB32A68B909FAA365CBAD
-:10785000BACAB4106EA6036E1472864ACB1EF8B56F
-:10786000280DFC482F1EA473DEFEED33C1CF436C00
-:10787000F8437E5EEFA0CB8C78BF91E1CBA2FF01F5
-:10788000BE46101B5FD37EB22B35075EB25CE33C75
-:107890000ABF20BC6FFD9B8C97439EF41994CE3D8C
-:1078A000A5B29EA478CA26B16CB58CE263A14A4009
-:1078B0008EE5E4EA1290C360786926A412F89F4A24
-:1078C00007B2C826E77ECEF9AB60CDEE9DAD749CC5
-:1078D00033B34331A895AFD3B94EEDBF9E3B40BE05
-:1078E000786DE5B2E74802C7EB3C5844E76595C9B7
-:1078F000B18729DD6C2D3DACDBE5E3B15EF9E2A695
-:107900000F62A833B83CA0F0514A65D31FF9ECF4DC
-:10791000A17C4AFA08DFE8C4C770F1757A98F4F1DF
-:1079200059C71378EDCF571B055E7D847EDF52B2B9
-:1079300078407DD51FAF4F92046D172A2566324DD2
-:10794000BBFFB4EB0BF7D326DFDD72541935A36A06
-:10795000E74078CB75AE57F4EB6F508C7747D0A2E9
-:10796000AAA37CD5B81E688FDE63114A776740F6FC
-:107970005078281D17A5A04C8A49EC61D64D4AA223
-:10798000657FD44C6E413A48225EC4FCBC86EC90C4
-:10799000B36AAE530E932A4BB2CFDFDFA0E13C3483
-:1079A000182F17EC02DA2105851A2229A05B41AFB6
-:1079B000A092CE9D0F65A79DD1664C25E9F0A072DF
-:1079C000BC4B92A0D76F0D4DBEB8C75BE29CEF9049
-:1079D000DB8554E33DD1268D9CEE6BA792F7047EA8
-:1079E00028102F13761DC7D3660FD92B5D48E5C12C
-:1079F000986BC152209BE1D32C6A87C0932A9FCDFC
-:107A000063A6EA4057648FA4C23C71488A4742F596
-:107A10001DD40B4A06F623FBEA90FE9490894FF1A1
-:107A20003DF3BCD8F8BD655FA206F0531DD58C2D83
-:107A3000748E6B15D3D80874318DC9A7EAE88479A0
-:107A4000A0EF3C129BD7B7A57C5C879AD39687762C
-:107A50005906FBAE5AA52A7F2A7CDF3661207E229A
-:107A6000494F4FB70D9E6E7BF06689DA835FA2BFE8
-:107A7000CC2433018E7F8A2DCE4A0D80AFF71B0FA9
-:107A8000EAEAF83E7BD0FD7DAD42EAD2C98156C913
-:107A9000C7F8D26769601F8875AF0576A720DD1625
-:107AA000DBC4D69B9B8BF05DBBE717BA6AE3BFB51F
-:107AB00054CD78A7F65F8F80B7E8A7B77DF2A0A373
-:107AC000BDBB5D6F7F425E507B18E85CD041504A81
-:107AD0006C95E87B6F6CB105EA6CED63150CFF19D2
-:107AE000E6DF8BAF4F397FD16E30BAFAD3EEA656B0
-:107AF000D04FEF691D575D4CE9E8F74F28B14DF4C1
-:107B00006BF58E89F3C05E7A8FD3B7C0D389DD4D14
-:107B100079E9E823139E7E21F9711C415FD5F2F2C9
-:107B200001E96130FA7ACA4D5F9D577F21F475C82B
-:107B30004D5F1C1E273BD9FAC9FD23185E38BEDCF9
-:107B4000F8C988974FDBAE3F3DFD5AA27CEDEDBCF6
-:107B50003A3D3DF1F90A7C7DD6F90E4647798669B2
-:107B6000EA74FC51D48E91407F9491588ACE53A7E9
-:107B70000FD45B31A6B7845C12ED4F4BCC4E53C98A
-:107B80006BD85E21294B477BDB6967CC57E84BDA22
-:107B90004F7309497A715F64FA504F95A884E93FA1
-:107BA00033943F03EC08FEA3CC8EC1BAB3C0FE07EA
-:107BB000FD359BEB5F89DA5B747DA132E7BE37E070
-:107BC000B23F14BE5FE8676F0D737FEC97F9FE3824
-:107BD0004842A88FC4FE38037FF6EE8B395C476AB3
-:107BE000C494E9BAB5839EE42609B41B41FD4C8ECA
-:107BF0004A49E62F20256037AF970A62A00FE83E7A
-:107C0000AF278B7E7FEF070AEA878668DD8A1658E2
-:107C1000F6B50D13BBE9B8F7349269C59EBEF1EE17
-:107C2000513B7C00EFF6E2F50EBBF6BB52A250B61C
-:107C3000E91D7F549B563C0D8653DFEEA6F090293C
-:107C40002081FF02A1FBA22F18003FF6BE174EF6BF
-:107C5000B2D2BF9C0B364F011653B02F6DA7B63B67
-:107C6000B9188AA3A50A4A07ED1EFEDDFA4D05ECF8
-:107C700077DBFDACBC63D3AC8D169447F2FA561596
-:107C8000FB9ECFCAB76DFA4105EC0BDAB2E99AA9AF
-:107C9000BE6EF324ABE269F8FB365976D85F4DC669
-:107CA00082F2FF43D7E1F79917BD40E1498112B352
-:107CB0000CD26B97150ABF41C7DD952500FFD7147D
-:107CC00002F4EC3762F19B0CA43FA47B7FAE19DB7E
-:107CD000424B0DF4850CF528DE1E96605FC7EC3133
-:107CE000F0E79C43FAA57C41BFAFCFD6B13ED16D42
-:107CF000F659519F3DD68B2717DEEE557BFC80B79A
-:107D0000EF8DF9F01713693FD642390664F3BD0DC4
-:107D100045D92B6D787CCC37A70AF0489A73D12EC1
-:107D20008992DE1F13CA62DF5C403A2BC0781C4385
-:107D3000251FA1743A2EDE53012830AAF4E7708F74
-:107D40004BE6E9EFA15DA548E7BE34743BCA0D07D9
-:107D5000DAE3A845543E8D90483C9DDC5DA9E6A041
-:107D60003C185149D73B809FE09B549F30FB2CE14E
-:107D700003FF56A67132CDF333C073934CC71D4D2C
-:107D80009208A7C1E09A099EADD127B3515E7FCE7C
-:107D900070CDD4DE0DCF1112E397956A39F2CB5036
-:107DA000FD3B6D7C3FD5027E38FA6CE27E38777BF6
-:107DB000BFDA416269F0EB379CFE210DF625B67201
-:107DC000BD6C307D1072FB89189EDD7A6101D70B86
-:107DD0002D51AA17983C5C087A20C8E1DF02BB7ECF
-:107DE000909F6192B4E8F720F707915226FF7DF447
-:107DF0003FE0B751554E7DA00D511FBC2BC55F9084
-:107E0000910E8904F3BB5FEAB86202D04F3EB3C75C
-:107E1000A337B445133638D4CB4CDF097D962C16E6
-:107E2000FA8C20FCCEE37348920E3FE8C307362C51
-:107E3000CE42BFDD8D41871C8AB62EC6FDAF8D9E1A
-:107E4000D12FDAC1FDA399F0A76BC9443A7958A89C
-:107E5000307918317B52E0F34342CEE32E434ED6C5
-:107E60000CFEC4B10F8B4CED39783E5DEFCE8BE448
-:107E7000D826DA4E9DADA63C14BE6AF98B55127D0C
-:107E8000EE2C64F0B76611A4D390B1E08402FA58E6
-:107E9000ED467F4DA8D2BD2FB69515E8A7E77AD459
-:107EA000DF763FF500FBB8A13E9B28BCDEB6F13F74
-:107EB000855C4AA1EB50371003EC09D5A4223102AE
-:107EC0004F3D0FE8453563217C765754C2F3BCD94A
-:107ED000F14AD9A6075433BE05EA8FF8CA7DEDB042
-:107EE0005EF526595624C6073936789B4AA1633F6A
-:107EF00097ADBBFCA589D62AD4EF8646C617F69F58
-:107F000077BDAC72B9E7A417412703C8BBCF441FA4
-:107F10006FCAC25FEDC4BF834E8AFAF02BDA85FACE
-:107F2000F9AB9CF875973F6FBCFA014F141FE751EE
-:107F30003C017D9E379BD123B547D17E7AC0D76166
-:107F400002BC1F2836644BEA6B175672989FF92CB7
-:107F5000DD6851BBE7FE95DB4D68975F4C6580841B
-:107F6000CFB4FEA37A59C376542E542ACC6E97C050
-:107F70001E9FAF6CAB82F63B295E81DF77027F43A9
-:107F80007C20A1A11CAE97DB2B36D2BE5B8F4AB200
-:107F90000246ACBE14F1EBE7FCFE912751097EC806
-:107FA0002DFF4B26BB0CD04B03FBBD9A38BE4519A9
-:107FB000FC0D609F8CA9D3A702D833B5DB5E275791
-:107FC000A65B57B5C2F07F47DDE10E344F9F77EED9
-:107FD000473CCB4DA048D897542B36FA0E97317FAB
-:107FE0000749D0F5407D4E371F150E4CAF0FBAE64E
-:107FF0003F96C753DCF55E56B8BFCE60F03244FF03
-:108000001B07EE5FC0E76C9BC2E323D40043221E34
-:1080100049ECFA5BB9F15005BCA75CB709F0B55D56
-:1080200026D5CCDF1C473D14E1E3ED2CCFC1F60B88
-:10803000552647C79AFA16C0F7D866192C05F2B824
-:1080400062E0FB51CBEBF67B281EDA0B492C64E097
-:1080500010D8EF8BE335A4CBFC5CA6C7F2EB290963
-:10806000D07AF9A52469D0F6EDFB1FA8D068394273
-:108070003754600AFBCA193E7D252406A690C72204
-:1080800029997D4F424C5229EFB140951E183F036C
-:10809000F75F77E69298D7E8931B82AEEE6CBEC787
-:1080A0000F7AE481E27BAE9800FEC65215FDE4E44F
-:1080B000630A27E14F54205E163761BCF6596CDE27
-:1080C000F40DE253D5D9FAC7DC3F1BF9A43DFC34CB
-:1080D000CEC35A4762E3B15E8C60FC860A54F05707
-:1080E0003655337BD78D8FF524F1B832DD4EAF870F
-:1080F000906EDA3F51F8BEE0C58D60E78F835F690F
-:10810000F9974D7FDC381CBB45C40F85DDB245EDCA
-:1081100044BEB728CF815E12768CBFB813C7FDBFAF
-:108120009CDE87DABFBFC4E96F75DB356E7BA65E68
-:10813000D61DF6AB7B5D1F795257C0FCB6E4537E6B
-:108140004FA3077E03FA9AB6DF115DFCAB89465F49
-:108150003F7D72C8C0EFA23CE6AC86F8197A7D2A52
-:10816000F7608F6632BE1A2BE4D037285F0D107F80
-:10817000147CF511151287804FD40EA42F6296201F
-:108180005F097E51BA3BDACFA7F460D4CBE0B906E1
-:10819000FE2239B45C48E93D65B38784BC504B3B53
-:1081A000E313A5FE74F7A021231ECF94317F7596AB
-:1081B000D56D4293606927C6F5285DFD17D095AA55
-:1081C0002725C0EB98FB17E0BA7EA93056F7AB2CF9
-:1081D0007EEC5EC7CF397C89BE1BED793F1B8EB22A
-:1081E000F87D31363F579CBDFE5703C6D9FD319708
-:1081F0009D334C3F428ECAFD08DCEF3558FBE1C68B
-:10820000D795B323903E7ACB19E4ED4D2AE78BA3A3
-:10821000BB1C70E9070F65476CA0F9F9859FFE53F9
-:10822000C60550870D010E6E385EA23AFD879F3756
-:108230001CDDF1EF97B8DC1F4C1E044D33252BE0FD
-:108240003F23CCBF1322DCBFE3A4F79DCD32DA215C
-:10825000C1B0BC134CC9ACFA6ED4C1627C4AEF55B4
-:10826000AA8DDE47971E4A413BB73ECAA4870693B4
-:10827000B7AB7CE60D2ACAADF4FBF1BE7C03CA2580
-:1082800069F20D32E2B5EEF3C937182ABC7BFD9BCB
-:108290003C7FE0867241C7C6D2DF51B8AC3EE821D0
-:1082A000E897F998AECE16575BCDF78137F07DE4AD
-:1082B0008D241E818FA7885C09FC728A1C8E4CB3AA
-:1082C000C993FB548DF14B9BE76DF0AF8A78F94D64
-:1082D0001DAC2CE673F3FDCEF2D7C9E23CF0EB7D8A
-:1082E000FD3E0FE26BB5CBBFD6AC32FD7133A96B4F
-:1082F00005BCB5784815C8B11B74A28EA0A6EBBA10
-:10830000671E9CB19296BFCBED91F7A95C366C715C
-:10831000D035A1A406F87DA76BDAB59710689F6CDD
-:108320002D807D5A36C17DAB1BCEABDA9CF31B6C26
-:10833000FEEEF952F2C2F9669A87BA474A6B4F3F8E
-:1083400022E40DC757A6BC2A914FF50B20205ADF17
-:108350009A43D8BEF3AD60B209E535CBA71AACFDA0
-:108360002F55463F9FB6FDAB83B45FE7EB5900CC7A
-:10837000D6966BC5C12F24E28235A4CE1C4D7F5505
-:10838000F72DB246135BBDE810EB150F5C2FD3BC85
-:108390004FE83E4BBEB06FFEDF9512C7D434F3BF3B
-:1083A0005D49D440FF5EC083024F15F18D7E608A27
-:1083B000DF5A35D4266541BE5317EE03FD86EAA089
-:1083C000875AF805E45A09936BC112E777B77FF82B
-:1083D0004355C4E153C87F188236C07E08A514F007
-:1083E000DF94AB277BEBD3F16A605D1742298E7275
-:1083F000A35E67F56B8871D7EC32E43F8C3FD4B74E
-:108400009F8F71F5FA9106FA77551233B10F17DD88
-:10841000D59E9548D2A60F6BD51E0DF8AC96DA45C1
-:10842000F6F7EBA38AC34FEB7E7AA8E51C2A817D81
-:1084300092CCFC483A2DDBD6FDA70E89E7AF185940
-:108440004B06F0DFAD8F327FF00DEDE3B398DFD058
-:10845000297F4F3732BFDCBF3DF67D0DFCFCA71EE8
-:108460003D7615C07BEDBF2AC407F91B8F85490AED
-:10847000EDB1A406F6D89A2EC54CA6CDAF6862F130
-:10848000CFC7C388AF354F7A930B69FB354FBF33E6
-:1084900085D0F99DDED4F3E268B09B1F95581E820B
-:1084A000D53DE56AFA7E8D4A56A4F31B4CF630F9A9
-:1084B00073F2D96015F0B7B467FFF5D86FE7528F44
-:1084C000D7B6DF2EF678906F693D66973F2225C7B5
-:1084D0004BE9E6C7F23F4E3E22B1F9EDF524FD30FF
-:1084E000BF3D3BB5049D47ED9E0F509ECC7DFC8764
-:1084F000118043ED5EC5A1076AF72829EF147C1EA1
-:108500008327C48DA41940279C5EBAD661BCA8A657
-:1085100073EB07E0C7A8DDEB946B142EB114C0F524
-:108520000D25B610CA4FFD4BC4A0A07AFFD0C311D1
-:10853000802BED77A59605FAC649DFD0FFD99CFEC2
-:10854000FD11D283F1BADACE76365ED7577E0F7A36
-:10855000A5D6253FDF875FF2FBDB33D7785CF6CC0F
-:108560009EA1C5EBD6FEF0CC43161DF7E4937F78B1
-:10857000C8A2F3BFE5AFFFF9D0B7803F7FE6D74190
-:10858000FED73EFAEB08B1D163AD87F1E3E9B1C4A0
-:10859000A27B5472FA37DE24F84B4EFFF4F7E30C5B
-:1085A000BAEED34FFC25CFA0F5EB7F3A7F14C0A1E4
-:1085B000FEC773470DB4FF067A4D7AEDF34A225E8B
-:1085C0008DBD123382F6F1A70B3F07BA0E8C83796B
-:1085D0009E3AE28D81DBB996BE6B980AF85A87FA0B
-:1085E00018CA1B289C6B1EDBFC01C889FEF0B6462E
-:1085F000CBE8AC4F8D06A77D4DD73B0B106FA40782
-:10860000F5A8BB7EED6B149F1766C6DF19F2B106A5
-:10861000F2AEF6B176365E27C55FA43FFE4EC12F9F
-:10862000B3FAE3EF0E17FECE905BBE970F798D5D28
-:10863000231C7152F1EC8B0FC6B3E203C80B210F60
-:1086400006836FB5C4E6B5CC633EE801BE7A32D886
-:108650008BDF8580DF1F9E1947287D1CF7F45C0F98
-:1086600072B3E7A75E7D177DBFE6A76F209F9DFED3
-:10867000F12B9A81F9992424E5F13C31F67308E451
-:10868000700DDBCB91DADDE19437D287A79AE4A2B3
-:108690004A2382EF8FE1FB24A3FF9AE4FE25521ABE
-:1086A000BCBDE1296276407224C265DDEEDF69CC93
-:1086B000BEECC3A7540EF83CB600DE67C2A758BF95
-:1086C0000EEB9F69C3EB6EC6B7EEFA35943F41EFF0
-:1086D000F5C36F527A039EA7777A55D07BA7C1FE68
-:1086E0000AF5C77B1FFC99FD33DCFDCA2B6EFE1615
-:1086F000F1630E87CCF461713B60E0F50D177E3FAE
-:10870000F7180E3A12703CF9717AF97F8ACB8D1AFC
-:10871000625516D8EC139F87DA27905F46E2D6E8B9
-:10872000C2BEF99E847D04A5BF938F2A18AF69ED60
-:108730003C8072DC2D2F6A48FA7DFB5F3DCC5EAC3D
-:10874000D9BB7F0AC8B593CF3D8BF459F3D8310D0F
-:10875000F62F2FEE794AEB2EEDE307D00F499B7EE3
-:1087600038F9A3FD53983C48BFFF0D6AACFFDA7D92
-:10877000CEFE6B1FFBC0D1FF5AAB5363790C038F46
-:10878000F3BE6A2E85F5BE7FC843409EBEDFA9A416
-:10879000F5BFF670FD28E0D4FACA82DF419CBFEC39
-:1087A00070C0003DDAB5C91C7507D86B873D04E47D
-:1087B0003751CD3F7869B9EB9500C633BA0E5FAB40
-:1087C0001836FFC4332E78CE7CCD9A1BA6FDCDEC97
-:1087D0008E97C116CA2D37CA8FD27DA3DD7FF54A89
-:1087E000E52890FBCD60CF4F84F16251F07F289156
-:1087F00005952C7F50D6FD69F537EBCF138A63BE04
-:10880000A047977B7DB6488F62BFC5FD4DADA1F4F3
-:10881000FEE8059AD817D0716D7290DAAA55E9F082
-:10882000364B637648A6EF976ACCDF93E97BC52089
-:10883000ED7BF99BE3470BCBF174F39EC6FB71FB19
-:108840005733C9030FEFA74C331CEB05782FB2E564
-:10885000C58F26C98D90274A4221773C3AEEB3C78F
-:10886000A3AB0EED87F873EED5FBF201FE11D2AC8F
-:10887000BF87763C899D1BC08E75C79FDD7989991E
-:10888000E2D1BE50CD9114E9DF5FFFF8BB897928B2
-:10889000CD63E6F90A6DF1F766BD5FFC7DBD46C7A5
-:1088A0006DC9808725DA9C7FD280BE649248F77DAF
-:1088B0000BA79BCB49F7532B619E3116BF9FED82CF
-:1088C000D7A51C5E3F3B9F2E9CAA9E0A62A81E0A4B
-:1088D000DFB94BCC661081F397F7ACDD0F7C26E255
-:1088E000F7D644F95C70E8F01B6E5EC42ADFE27BC9
-:1088F000B521E445103D27AD5EE89B87C5F755518E
-:10890000DC2779389F1D78F3661FC82D95242A0B24
-:1089100061BFC4E39A986F4FFBCB4BF98949E7AB32
-:10892000E906DADB79A9D50FDC0471757D0CC62365
-:1089300094B397A0FFD0DDAF128D59980F16322A4D
-:1089400014DB38ADB92C3EA3EAF1B479C3ABB4C49F
-:1089500013B05EE5EC65D8AFEC8B613D121A5ABEE0
-:10896000EC77AE8E207C7D14BE201F1164B02E9E4D
-:108970003775F7D511D433FE839E9DF0DD1F6279E4
-:1089800054B7CB8118E459B9F3A82ADE6A27D05F1F
-:10899000EB3109E328827E5B0BEBCE03393E401EB0
-:1089A000D54B9ACDAF9E298FCA1FBA11F3A8FC9F51
-:1089B000368FCA2A9807F6586B361179559644E7D0
-:1089C000D1CAF3A2FEA3F5A5B9A09F5AFDE2FBCB45
-:1089D000734D7BD95A7F00CB3CEF6AB4B7BD09EA2F
-:1089E000E78E26759DE8CF33C93536391BF1AA08C5
-:1089F000E77FD6CC7735479E7CD4115F3AF0E666A8
-:108A00001FE86FFAAC2C02F851BA02BB3D2FD54ECD
-:108A1000ECFA483C051DB5160F1CBF53CF5E847E93
-:108A20007C51F6E949D34C537FBE8FD91F827E7D9E
-:108A3000B924097AC967241EB809E83937140B32FA
-:108A4000BAC438595B08DD53FDD6D1567C03C6DB6A
-:108A5000CEE804B95ED071FFF95FC6E75F64615C80
-:108A60002244309E96791D65B88E559A19F6DAE043
-:108A7000987B5EFABCD4BBBD6C3D2DF1E52CEFAC10
-:108A8000DA198715791AA27E504A1478411EE6B287
-:108A900038ACEC63FCD6872FAA2A6CFECD26B2DC5C
-:108AA0000212509777E2D146554F62FD127FE27C69
-:108AB000AF233ED7CDE2BAAE78E27CE516C6DF83BF
-:108AC000E04F9CCBD80A71B789109F8BF2F37D06DB
-:108AD0008FD3992CAF28033DB5150F1C87EA688CFE
-:108AE00061FBBB1ACB59BE9244B85F3BD9047402F8
-:108AF0006E0946F73F6802BE092B822F7E88E53B50
-:108B00002556BEC9FBCC5CC8373CF0E61B55AB28EC
-:108B10007DB49A01E4FFC1D6A72767205E873B4E4C
-:108B2000FFF5B271DBCC10EE77075BB79E62E30E08
-:108B3000751C115FEB5B9F0FC769350619A7838D05
-:108B400033F8FC199FDCB17F35E62FF828FFFBE9ED
-:108B50007BDFEC1E9248D37F16E79F036F7A515E4E
-:108B6000B7E5B2FC284F49C8644E4067FF9ED2BCAF
-:108B70003978DEA1EC02CC9FBF637F3BCA190DC6DA
-:108B8000A1553CB1D04AD62E61C239DBC83C82F136
-:108B9000674F49DE2A78DF403AE273400F97CB2CCB
-:108BA0003FB9A4E426E8271BF892CEA3DCC7F69DC4
-:108BB0009E928B6F86FAFBA7BF9E68023895333A68
-:108BC0002007F31D706C358AC4B99D01F9DE53EEA0
-:108BD0008C5B109F33FF93A84B306E4EE54287D7D6
-:108BE000665752BD781FF23329B3C0DEDBFEB56B8A
-:108BF00063767EFE672DFE1D565FE46B093E4F9F38
-:108C000037D79A2BF2E6123EA50CCE29F5E6532F64
-:108C1000CCB7E77FF17CEA90C8A7E6F1CC0EFA5F0B
-:108C2000BAFC39F739C6CF2B9FFA292FDF0F07C9B6
-:108C300058C8A7FE8987C4529017F36B250679316F
-:108C40006EFA70F7E73E07D06B8F64E0E7F7013804
-:108C500036B9979F70E1ED463FC6E7C478CF837C75
-:108C60002A1D9C4F47573BFB195BE73C9F755E8372
-:108C7000335E55681538EA9FDF56E4F83EBEE302DE
-:108C8000C7F789F74F759427252F76D4FFD29E39E1
-:108C90008EF2E4CE2B1DF52FDCBBD851BE28B5CC0F
-:108CA000517FDAC11B1CDFA71F5AE3F83EF3C87AD5
-:108CB000477956F7371DF51BA87902F92C7040004B
-:108CC000F7ABDB46CB76FA6CCFA67A250BF3B8353B
-:108CD0009ED48FF166968BDC9767E06EA7146BA627
-:108CE0004EF9573126CCD331CFF046E423A5386F67
-:108CF0008E81EF672C00BF132963E7B444FCDA537D
-:108D00004C527EC8EF0BB9F0EB8A4B7B946D29C0B7
-:108D1000B376F4CB07A5487FBC7AA2EE7CC6A1C58A
-:108D2000B555E3B3E507E4F9385F8CA57C817EC4D3
-:108D30008F15D8B7907961B40F6CFB1B84A3D8DF73
-:108D40005CE623CD0053C11715CB7B46BF80D5C44D
-:108D5000BEC62B0F272FB9BF5EF1A2DD25E4CC6084
-:108D60007A45494E73E421B89F54FE95F9609F1EE1
-:108D70005986F2A8775FD02B1FE333E1BB478DA163
-:108D80007CEC957F7B0A1C7261A8F6995B4EDF052F
-:108D9000421FCF05A597D711C80BA372E9CEABAF81
-:108DA000C23818A9278EF3807955711FE83D6A975C
-:108DB0007DC567DB3F47CA997DF6F766A78660BD2C
-:108DC00036F927EC5501D7118575718CEB85650255
-:108DD000FBAAA6D9B128F801DBA08A6D9FF65DDF5A
-:108DE000F958BF39A4C9E02F6D3E381FE3035E7FF9
-:108DF000DC0779CE4D9E7825ACAB295BD6D3E53B1D
-:108E00006DF631FF8CD6109CB67B00FAD034BAEFE9
-:108E10004FB3DE7FF131BF4BB3BEF820E8B99CB051
-:108E20006640FE44EBFE598B305F77A1AAC3BE9625
-:108E3000D04DDC3BB6B8222171F46769B932EA45FE
-:108E4000AD2182E30F36DF5B7DCCCFE06DF00F38D4
-:108E50005FAF96DE4F9169BE9B61BEB983CFD70BE2
-:108E6000F39560FC108EBFC9C7F0E886BF87986D88
-:108E7000F368BD96635FEE28468A61F97AF72E9C07
-:108E80008A744A05B5837EC53E82D2EFC340BF6275
-:108E9000FF2ECEB3DEE263790902AFC460FE881113
-:108EA0000915F7BD3909B6FFED931F8C8E723C3161
-:108EB00082E7BFC6A8189704378DDD8FA1F8D9BE09
-:108EC000C77B690CF1D5FE15956C027A2BA6EB8158
-:108ED00073B90759DCA9DD13AB8A87FAC613EDDF36
-:108EE000E1FB40952CC9C27B529485D174F6672F63
-:108EF0009D73B8B9E5EC011FCFC3CA27F94CCE96D4
-:108F00002E85A34499FA71DB1B0DDCAF3CFCF329E1
-:108F10001D08CFF631F7A11D2DFC63245A3688BFFA
-:108F200087C54BFBF0BCD448513CAA574C45A75FC2
-:108F30007B31C7739D2B9F97E359E057F8ED493478
-:108F400017F95AE05B017802AE94D9D181F495C249
-:108F5000F9C60DCF53FF4DE17904D600743B96AEB0
-:108F60001FF8E6C01504E3602E7E14ED04DDBBD7C8
-:108F70001FF6FFF75EBFA087CCF5ADB4FB0F11D78E
-:108F80000D737AF371BDF942F9DB6D709E44CD65C6
-:108F9000FBDD7079F3AD329CC320960EFEB5B03880
-:108FA000BF53E6BC7F2450EADC7FF85CF74D78F8CD
-:108FB000FEA3DFFD2ADCCE12E7F9DDF377E36BAE2B
-:108FC0003F7D1E261993DEEFEA8EC789F886C88397
-:108FD00015710084035DBF67961C47F95746CC9D09
-:108FE00069E4D3323FD30B5DCFF9314F225CA5A1A9
-:108FF0003FB6A02C5501E5823A12033D71F1F143D1
-:1090000024413BBD20C0E47E41595202BF47C149C3
-:109010009617B89DC72B0BEA93D24ADB38969FE987
-:10902000AD8FDEBC1DE5E37363595EFA6D15CC7E32
-:109030003B14BDA1A302C62D67F9E461BA5F84BCED
-:10904000B1F0116F12EDADB26E027E54AA05AC30D4
-:10905000FD7EBC914CBD713CE47DF9F079B251C705
-:10906000E781B1DAFECB69BDF5850103FA6D290A06
-:10907000B0F3BD611FEEF7FF9CFD75F4AB9E6E8CE7
-:1090800062FDB66F9B685734EF3F817EC3A0392DD8
-:10909000C6FCA8A642CA613E874CF0731035662C08
-:1090A00086EF077E83F5142DF11B0BEC93651AEE0A
-:1090B000EF010E104F68F2B37CB9CDFEBA68363CB2
-:1090C0000BC98A4569E0BD82EB1D4A518A96D79744
-:1090D00087A495A7942CF02797914EC873F7B424D2
-:1090E0002B404F93D5BA01E38CF1252BC07F3CA6D2
-:1090F0005A8F810F5D2B67E745043E3C7E127F222D
-:1091000004F552D2AD74DC89011DC7293892C4BC64
-:10911000E58FDE9C99D6FEBFFD68057EDFD65879C7
-:10912000789E8D9F4319E2951B8BE73CE0A7E3BD3A
-:10913000EA67FC9AA95FF11C6ABFAF723A39F0E6A0
-:10914000C451605F3664C8A356748AA7114C3E812F
-:109150003F62FD78635476C8DE0F8387F2DCB30C80
-:10916000AFA58C3E9B7E3C310BFA7DFECDA53AF837
-:10917000FBFE945B8CFB86534F7B4DB05F4EE590BE
-:109180006ACCB77C7AE68BB03FFC43E3C11CD526A2
-:10919000174FFDE895191EDADFA9275F99A1227301
-:1091A000251D76ECBA73AFCE003BC19A434AEAE87C
-:1091B000B356D708F45BEB63EB107972DBF3B4566C
-:1091C000785E19CCC6F679A3E43BA1ACF85E1DF736
-:1091D000EE345C378B2BF0380E5D5F5308E95AA7ED
-:1091E0001B1088175ADE7110CF7AD38BF4F75121F8
-:1091F0002929BC10FC820AB6EB594D92904FA1A5CB
-:10920000EA803D89FFE52401BE09BEA6EF475AE387
-:10921000F7C1DDE9E7F90F3C8F70E39BB74F04F826
-:1092200008B9AECE2518CFE8F99A2F09F6E83DAA7D
-:10923000F19DE560075EA7E23C6819CF1BB9F1B369
-:109240003C58E488E3E5F0F884C06B263AD9DA4864
-:1092500062C514DE3F6BF4C560FC7D8D3A967FD20B
-:1092600018C5F2DE46039F4F3796E0B3AB3186DF79
-:10927000F73496E353E4F5E1D65E417B3A5E017A3A
-:10928000E81AE687D30DD9847C852C95F8E0BE26B4
-:10929000FDE8BF55C17E1BE44A560EF2BD04ED73D6
-:1092A000799EDFC8FC39ED15469F7C15F2B4C943A1
-:1092B000249047D62CE66708437FB47DEE1242DE49
-:1092C000B6C9F573F49FB74BF8FAE87CB24CE77770
-:1092D00077FD884A1790D3BF1D958B58EEEB373D2D
-:1092E000FC86FB047FF9DB36FADE3E9DAE9AD2D1D6
-:1092F0007689C9B13BF9F73BA6CFC8BA01CAB366B4
-:1093000064815CDF3E8B183A85E35D866C79B2FA46
-:10931000EAEF683C98376F3CD74120A7EAF59D5BA0
-:109320006CFB9831165911B7D1CB5D756AE52EB437
-:109330003312F98B2763BE31F76BEF9E678EC17EC8
-:10934000B13C21F0E23C8BEB159033979D657AA8F8
-:1093500057FF7CCCDE0BBDA771FC6F9BBD4989001C
-:109360009F803C057959962073E83C4397B2F8F703
-:10937000AC775304F2FBB4187D0FF6A8C6F24D0A81
-:10938000A24909CA3FF2C7670620EF3DE7FED42E87
-:109390008AEF0FBBBC06C41BBB9EFB0BE6672853C2
-:1093A000341FF077C1BE6398B7A4C8DD1AEC789774
-:1093B0000526CF57C19E8589607C802A6A8A6725E9
-:1093C0008FAF8F3CD5322F04E7BE1227ECF5B707DD
-:1093D00012B7B21D33317D51CA0F7ED1FE82168085
-:1093E000C7560F2B2F0B4C6AB1B04CEB67B37233DF
-:1093F0006DBF35BB332A6743D2D4C4968397425995
-:10940000D49FD862CD26E41AAE0F48285108FCDE5E
-:109410005BD669396C2BABAC4C7CEC29D6BBEEC06F
-:109420005F5E1C4DE150B34FEAC410DFBE9D12AC2D
-:10943000BB60EF4E94AF054982FBFE82A49484A3E7
-:109440009D7B1A0FEACDC2B926F04245C3A428BBC2
-:109450005F484B7A62B0BD9CC4EF0F1174F17490F9
-:10946000E9C74949DADE1E9776DD273289DF57835F
-:10947000200579B98D9D0776D37929EFAF81585BA7
-:10948000E03C2E79CCA3637C9CFBD94F0ABB89FBC3
-:10949000736EE10E3CCF262B7001C8BF952AFA816E
-:1094A000D7162637521B8AAC7DB630462D56D2E2EF
-:1094B00067F4B236BB336F2AC5674BB6B3DCC4F36F
-:1094C000E7A3D956369CD7ADD97BF738C8EFA92189
-:1094D0001DD77F13E6FB328B879FD83F2BEB125AA9
-:1094E0005EF7328B63ACEB7A4503FABE27C0F38E8E
-:1094F000BA2EBA12D657B34D267221E34B73229D72
-:10950000AED971019CAC7B7EEB5BF3FD630979A462
-:10951000C8D4E58B08E90E9E68F151FC3FA2E9939F
-:10952000803EBA833D2D405F6B67C99C9E7A5E305A
-:10953000559EFF5800E35CDE027196DDCB2AAF0436
-:10954000732B4F66FC4B0912E3DA4A76B30FECF942
-:109550003FB6C8683F838B7403857BB14A0EAAF47B
-:10956000B95DA3F8043E6B55511ED2F76D1EC44B76
-:1095700007DE3342DAD83D2DE3F77957829D5D5CF3
-:1095800067AE467B5B2F453FC038D2FB837912E73D
-:1095900011267F27EAA442A5F566050B117FC55564
-:1095A000D7AE85764A784900F83D4F495AD8FF77BB
-:1095B000991CDE2E273B7D2097234588DFED114641
-:1095C00017D63DA54817BBE53917805DD422ADDC21
-:1095D000F20BC06B76119E7B85F7EB61FD1C9F4DF6
-:1095E0007ACC07F8DBCDF1A9EC942DC8D714EFB7EE
-:1095F0004A37AC06B89ED8523FDF47E19AE735DBE1
-:1096000046503C1CDF52DF129D857828F2D1EFC70F
-:1096100003F52D3E8A97DD1BCD02DD569EF8099598
-:10962000EA48B4F52DE66CF09FDCB7069410FDFE19
-:1096300002F83F1EC9117CCFBE1717F5CA1113ECF3
-:10964000D226AB4FAEF8A85E28B6D59F47E5C20F2D
-:109650001E5210AFFF4EC7033941D76101DDF74CF1
-:1096600052D12E08D0B904683930B908F36DE9BA7F
-:109670004900EC86C92AEA7911C7D126C96837435F
-:109680007DA087407E11E6CF51791D87733E4A94B5
-:10969000C5751465874979980479FEBEA42FC2FB6D
-:1096A00048FC25B6BC0290BFAE3C04C5551EEFED8C
-:1096B000CE97A97ECD3DBA481A47F1F25E80EF8B76
-:1096C00072E93E96BE7F3FC0FC40B7C7AD2F43BE98
-:1096D0000C31BAF3593C2A3E159EA3AE2B1E359091
-:1096E000FFA5FF7E3586F6CBBD63D4B4F960FF1AC3
-:1096F00064FE41EFD862BC57A38150FE07BE08F15B
-:10970000FBF2B8FCF0707BC17D4E40C8134F365B56
-:10971000637DFBDC5139A1BE73704AC8F4813CD82B
-:10972000AF4FCD027B743C9753CDA9595F05BB4524
-:10973000E5F260879F9DCBEDC9269DBB08D8BF3160
-:1097400062CF4B10F2605BA30F9F0F5F3601E39770
-:109750000F5F963707E215072E7E1FF7BF6776303B
-:10976000FE3D73E805B84B899CB1A8B6311859A1E4
-:109770005F3E752FDE17F27D357E17E6CB43BE0EBA
-:109780009DD25DD9CE3CCC47395CCE0578DE808752
-:109790007D17F778A867BF847EE06D7C3DBEC43C32
-:1097A000DC57821B0FCE1DFB4907DEC724E0E0BE5D
-:1097B000BF433D3B85F9EB036C5F2AF297DC794AA6
-:1097C000623EFB8219EE3376E143F835041E44FB1A
-:1097D0007AC91CA50F4037B5671592B4E585F49D8D
-:1097E000DBD0F0FD6938EF9205F7AF243A2E29045B
-:1097F0003E48A29DE80F353BEE712551B5C77EBEB0
-:1098000024E83AEFE2E617B83F18F4B4660C7CAEF1
-:10981000E57DBACD1579B998A7AE9207C0AE3D15D2
-:109820007C6B06F8E36AA998005739512D3C4F7AB2
-:109830009AEF4BD47DB7E2791E313FE18F13E59A61
-:10984000BD8BD04F57BB3B84E7796A924C0EAEF389
-:109850005907BDB23DEFD64C41BEAD672FEB6F3C13
-:10986000E080D2C7877A753EAC3FD870FE4C38672F
-:109870009227D79D370EE0A3323CC07EF9C9109ED7
-:10988000D355BDB6FB53DFE2FBE365DC1E09124B8B
-:1098900006782A8158376167164D95DA474AAFDC5A
-:1098A0009BDC02FCB0DD656F6D0FB0726B70724BAC
-:1098B0007329EA67948BCB023F437BA8C52FCACF9D
-:1098C000A29CDCAEB1FB3AACA7BD06E83DDA1ECFE8
-:1098D000A75BCB4A507F2845A400E0360F1C2D2003
-:1098E000FF9EF6EE023FC38FFC896B0236B89D0ADD
-:1098F0001F1907FBCA34FD598EFEC60DAF3F3A7ED5
-:1099000017E0417C9F17B91FFBA7EDD0DF41C61CB4
-:109910007A8BDABA24EF692F9E33DCE171DADBE26D
-:10992000F920E7CB36D7BD1DBE44B3099B73C19F59
-:10993000EE7B9605BFAA672739F2A4C607593C5BA0
-:10994000554D7055D2EFA5EC7B80D1411BCFC7C9D7
-:109950003C4E4E86719C71BBFEE3CCE07282F07D82
-:10996000ACAAF7DECB3940FEAB3BBEE8966FBD4FED
-:109970002EDFF2393DC7A5C4B3415A5E93EC5C10AB
-:1099800060FC3905F87335A7D3923D773F076AFD30
-:10999000319FF967D837ACF2991704A70F9F7FBAA8
-:1099A00083623DFDE417B3CBAA999D5BDF3EED4A90
-:1099B00028D7DF51A45B69E245E2597D36E8905F24
-:1099C000F7707F51B56AA11CAB3E1BC1EF9FDF78DA
-:1099D0007EC779B6FEE385F0BB18EF16977C3E7024
-:1099E000F14BDBCB291DD73FE191BDB671EA9FE07A
-:1099F000E780FC545E3BF9DD047E570B496F9E22E5
-:109A0000C887BB3451565AC12E7AC42E1FCAC16EA4
-:109A1000EB6B0FF716DE15E0F5AD60FAFA4157FD76
-:109A200022D17F2ED677CF47C81F28839DA67EE2FE
-:109A300015F343F975B7ECEA2F478C3F06FB13F695
-:109A4000FAB703E35F843B25EECA4E568C66FE1DD3
-:109A500003EC80EFABB180FD3EAC6F737AAD3E7B23
-:109A6000BE03DF7D709FE078FFFBC6A8235FFFE6A3
-:109A7000443D9ED3F87680D16535B5E8B1DD8ED111
-:109A80008E3CFD7FCCE3D3CEE3920CF3B8EC6F3C7D
-:109A90008F42077FF6CDA3D8F1FED3CE631FF70B1D
-:109AA0003FC79FF375762FC07C4342BFF57C5AD7E2
-:109AB0004F69FDCBF4E9A3CFF92AB14278CF6D927B
-:109AC000DD6346CBE00FF8EA27B7BD7B39DE0B6DCF
-:109AD000623E8E57E4E3F0731E9BC70C7C5F91FBE4
-:109AE000EF3BB8BF0733DCD3DA1862FBEEBB2FBC09
-:109AF0008A60FE7A28817182FDF90BA260A77FE758
-:109B0000C21A7C36E7CF88823C6A0A7FDD916F4EAD
-:109B1000F70869CFC1FE91F74BCE7E59B69F47D962
-:109B20000CE751D2D41771B1CDBE3ACC03FFA2D607
-:109B3000FBE017B4DE4BC38CDE36FB1218176C8DBE
-:109B40007E31F37F26C4C6B9FBC2CB089BEF6529E3
-:109B500016F7D10CFB7960F1DC1F9E118575366517
-:109B60002F88023D3767CF70AC47C9B09E5561065C
-:109B7000A7CDFA17BB9EC39F793D0BD2E6C1AAB908
-:109B8000E9EF176B17788A2690CEBEA8759DFA1B51
-:109B9000AF6B14C7577588F90D361B8C8F824AFC42
-:109BA0005785D2E07C38D8DF1D21C5863C943CBC6B
-:109BB000DF727865E2DF659EE44898D79146B67F0C
-:109BC0007E9DDF27F5DBEAA630FAB55DE36C1EB3B8
-:109BD0002B3C909FE37F563BCFA70F26375A422C52
-:109BE0005EF3B584B3DDD2AA60DAFB4D28FCEE2A21
-:109BF0002CEC83673FFC7FCE70CB448FC3855B6BBF
-:109C00007478701B8C0FAAE1929BE983C34DD05BE3
-:109C1000A67EFE7FA1B307870E2FA4AFBF15BCFEA3
-:109C20005EE9EB1980D710F8F21FF03AC7F5E6D0DD
-:109C3000E025E4D81E8DDDBBE8EEE74498DDAF34C7
-:109C400051AA3B7C05C417BEA2A0BFF7F08E79EBEA
-:109C5000886CAFC7F4D9E1CAB9EB30DF351EC47BDD
-:109C60003C5F9363FF5E067187C5AC5DBF7972F898
-:109C7000BC14CEE67E4B6324F8115E8B5F3DE0FAA8
-:109C800048A56D5D989769BB8F4AE90FDFC3C4B8DB
-:109C9000A30CFC4D0BD3CF43E033D3B8C3C5E76B64
-:109CA000F1EF0F0B9F83ADF7D970D190E485D837D2
-:109CB000E492DEBF977101C0738FCCF2398EC2ABD4
-:109CC0007CB89F8C60A5A555A376029ECA223CEF66
-:109CD0004933D6819FCC7BF5C2AD618AB7D7AEC977
-:109CE00096BC367879230CCF3396A7B70B73233CF9
-:109CF0002FB7B7BD44E03E44773D85D7BB6639BB3F
-:109D0000978AA8E6D8C5B67375535CDFDDEDC74604
-:109D100022F8FD351E6F777FCFE2ED972E19B83D03
-:109D2000A963F7B950BA1B9BEE7E41C11F9DE14468
-:109D300034429FAF4B8907BF01743429C4E21E2A05
-:109D4000298478BDE8275725298DC2FD5D8F3116FE
-:109D5000FCB469FA291CA89F4C7015EB11E3002B89
-:109D6000C2BD2C74FF88FBC5329390D9B04FF4C6A6
-:109D70006E65870D191DE4F0FC999975C1E446B034
-:109D8000F354BA4EDB7CBBFE6BEEFF80EF5D876564
-:109D90007D53617F380C261F1670BAC955129BFC83
-:109DA000E01F5B21A5BDDFECF208FB3B251F847B98
-:109DB000E3EA38CE84FB121EB8E7E05A9EDF44483F
-:109DC00062ACFDEF8C7DC0E58ABB5DAEC2E2D1E442
-:109DD0000DC6CF7B76AD199B8E7F5EE57CFA41B8D0
-:109DE000C4919FB4247EAB07F873C9C2451E2304F7
-:109DF000DF99BCBC86CF638F96187B51A80F4E1994
-:109E0000E510874FD7914413DCEFB0A241C238521E
-:109E1000E90646772B36EC97D7D1E74ECE7F8B00FD
-:109E200007B6FE6EE578DDB32B300EE6BFA7D74F41
-:109E3000473BA6F3B8FE7E827EAFD591AB3683DF7B
-:109E4000AB5B22FCEF32FCA412F20DBA799E480BF8
-:109E5000FDBE11E63B6F24F2F7840D1FD4837CEE28
-:109E6000D2089E97FB8F762FFE7D0B412FBD72622D
-:109E7000C3478D907477AF969A0C7433B2A9EE1BDA
-:109E8000E9FCE416E7FB0F43F1AC7476AE780A798F
-:109E90002EEA2D560D4FBAFA57573AE59898F7081B
-:109EA0006FEA54BAFB1A7AE93039B0DEFB3597E332
-:109EB00002EFBDF83E927E5FB423C2E2777B9273DD
-:109EC000D6A2DEB2BC06C843311F01AF5C8BC1E92C
-:109ED000DA258A43DEAE5818749D476270FDAAD712
-:109EE0007808D671EFAE9726E3DF5174E987809248
-:109EF000D0E0FBCD24E50139715C31F0F97AA3F3B0
-:109F00005EE6D749E28EE9A03F1B94B47CF50CA72E
-:109F10009FD7AB565D83F36F567498FFB1E523AEC0
-:109F20002A07F952E5C17B828F35DF16BEC9B67E9E
-:109F3000A1EFDCF3FA6DF5AA01F5D6D22A27DEF6F9
-:109F400068CC2EB0AE647CB89ACA9BD9485FDD77E6
-:109F5000CCA4E31F4EE65CB4855527F0F71CAFE6B2
-:109F6000BF1F971377CEA4F2E684CCFC61D63F31B5
-:109F7000B9B1E4BE780BC4794F344CFB6937ADF707
-:109F8000325FDF5B0D03EB47373D4DB8CF793FE5DF
-:109F90008C234483F689FAF4FAE0FAEC2093AF6A52
-:109FA0006C1CC897EB36A4AFB709922B69BD137F21
-:109FB00055AAD3E56D7EA2333E59114FDFFE133D06
-:109FC000CCBE835E4A03E7BD59412EE7F47120A75A
-:109FD0005764986F575604EBBDD372FB7510EF3B77
-:109FE0002E3BE5F30FB278FC3C8BC9E713BB9679A7
-:109FF00046029E5A251DE8E1EDECD824A0B795CD88
-:10A00000C7D08FF02D5EFFBA50FC43D04F4B8E2C43
-:10A010009E3F92E2A56B3989494666F9FF31E79F79
-:10A020005C85DD6340F5DFBBA0FF68D377D1FE50D0
-:10A03000CD715F9BCCAE6C84BCC213B2B506F3503D
-:10A04000760558DE11894DB7DF2F13E0F338B17B69
-:10A0500078F8BE261E1CD08E3F4C3A6A70DCDD417B
-:10A060001DE28F872B95D4E57492EFED0EE23DAFA4
-:10A070006EBEC834FE70EDC013BB8767070EB6EE28
-:10A080005856E190ECC03395F7DE59067CA4754C28
-:10A0900049277F859C7E8DFBADDCF4239EB3393E42
-:10A0A0008E27079ED7CDF73BE7735D9D733E825F9A
-:10A0B0008E279B02901F4E479F6CB74BC9BCE9830C
-:10A0C000E859E6FFCD34CF389FA790134079104F61
-:10A0D0005BCDE5CD5B0DF746EC7870AFFF84CCF738
-:10A0E000070FB1BCADF1F19573461A7DF4795D1699
-:10A0F00093439F375D0A3DE3EEE7EF9D0E859E1B80
-:10A100008C0E855C70B7FF00E2FC23E1EFE3E81AF8
-:10A11000C4653E8818AC4CF40570448694F373CB48
-:10A12000C41807E76E4EEC0AE0FDF6D6166F12FE75
-:10A130006EC7F15D974CB2AF6707C7FF8A25D97824
-:10A140005DCA713976C528CC2F50F0BEAED78FE4EA
-:10A150002C80F2BD876490D0E4BAFA950AACEF8106
-:10A160002C9677BE62C32B680F0E97CE57D439F565
-:10A17000FF277C1DBD7696DA5306F493090EED5940
-:10A180003EB6CF892F9A0FF279D50609E5ED962CC8
-:10A1900003DFAF524D94DBA499E947E2A3F0A02A74
-:10A1A000E4182C02E0F1BFF9DF2953E39AFD7CD2D9
-:10A1B0004DDB6E9F0FF6A19B5F46EB8C8EE15E3010
-:10A1C000785E174A3C9935B24F3EBF2DD5ED1F45FD
-:10A1D000AB5C9EC5ED6DCEA7623D9767B1F5513B77
-:10A1E000ED87F8F799F8FA48CC456F7247CD4F00E4
-:10A1F000FE737C681704BC54EE43DEDCF7033ACBF5
-:10A200009B637C25EC1D77FB6BD584C36E3C94551A
-:10A21000E8C8C771DB21FFD017E9EBFFF96FAC2F5E
-:10A2200064FDD3E98BFF0779B222080080000000AB
-:10A230001F8B080000000000000BDD3D0B7854D59B
-:10A2400099E7CE9DB9994966924932933738930080
-:10A250000625780321449E370991A0A803040C1A0F
-:10A260007044D4282144C54ABFD2CD0D893120DAAB
-:10A27000505DB4D67587885DB6D235586AD1D2762E
-:10A28000B0828FEA365A45DA8D1A1FA5800FA2AD2B
-:10A29000ABDB8FAD7BFEFF9C93B9F76626046DFBAD
-:10A2A000F12D7C7ED733E7FDBFFFFFFCE7B0A22591
-:10A2B00085449D04FF7C49FF3B9C1A20C44FC8F194
-:10A2C000BFCA8DBD6E428E45DA93AF81AF4D5D90B2
-:10A2D000ED2344EF94C9A3B4DD3B473EAD81F2BD0D
-:10A2E0007D36AF44CB2BD65F238769BB4C28F9A1C1
-:10A2F000DF9234287F097FE60EFFDEF0804CA2C596
-:10A30000B179AF867518CAC77A923502F3CDF14498
-:10A31000C60709D9AB109D9411F2F6E6ECC8265A8F
-:10A32000AE7112DD3D8590B9696CBDBE8D9FB77A67
-:10A3300027D3F5F4FCBA8414D2F5DD7DFB8AF0A4B2
-:10A3400038F37B6D844CA3130402369245C86D7CB0
-:10A35000EFAB528906E3133ADFA386F145BFC3ADE5
-:10A360008444CFA5F5E368BFF2583FEBF8CBAEBC11
-:10A37000702CECFBF09533C75E3329D62F111C9659
-:10A3800049E17F5E0AF3B6C92AC075D73D498D3DC4
-:10A3900071E0A673B85AE7873F76BA8F25FCFF971E
-:10A3A0006EACBCC34341B22965CEEC709CF90F93EF
-:10A3B000F0DDD3E87CFA46369F759EC57C9EC3F5DA
-:10A3C000D72E05F87FA6CB5E99C263A0414EAD8023
-:10A3D0007EF50E753C1D7F40BFD5739D619DBF4FBF
-:10A3E000009FDF375EEB898B07FEBDA2DE4C076F57
-:10A3F00093C197A7C33C3BE3AFEF16581FC5DF31AE
-:10A40000257CCF85747DC72F96559DAEE7B88DF618
-:10A41000037A7990F60B0CEF773DEFF7F6C691E9EA
-:10A420007249AD793D4B8F249BE9D2461A7BE3EC10
-:10A4300067685D6748F72B2CFCB74B191CE3A5FD3B
-:10A44000DFDE71EACDDB613F3B9211DED67132D3A4
-:10A4500065C6A7C02700AF2D499C4FBA9B9FA6FD9C
-:10A46000DEBE344FDD4486F30721DD97CDA0F5FD38
-:10A470003DB6D22DB46A574F4A6324CE7A27A7330C
-:10A480003AF0C97AF279B43D7983E103C80DF866F0
-:10A4900029A7376FCF0F5B882DD6EF0DA0832442FD
-:10A4A0007EDBEAC4EF36AF13C7A95BB84809D079A1
-:10A4B000AEB3130DE0877FE8B8DEF30A766CA153E4
-:10A4C000BD6E63657D15E53F69F87A1EE674B92BAC
-:10A4D000B27844F8D637C82678D62D34C3D74A9FE9
-:10A4E0004723B6DA78FB17F49C68BE2B1D113FE0BA
-:10A4F000E908DFEF61BEDFDF37B67BA0BD759E5D8B
-:10A50000919E11F9E0AA46335D9C6E9F6F7A830895
-:10A510008FE56173BF2BEACDFB5D4A5A66134A2A69
-:10A52000CB88EA806F1D6929799A82F2E8034B7023
-:10A530003DAF13520B729E9CBAB56451496CFC1727
-:10A54000393D7F5677EBA5202EDF505A4ABC71D695
-:10A55000F33A8793C0F7EB09E019E572F70DC033C2
-:10A56000D0EB32392E9EFF8BCFFB46C3C87CB4ACF8
-:10A570006E643C9FF07A113E6F34B427C33E8F89DE
-:10A58000791F64F3825E33E2E3C457D45B56FE1D49
-:10A5900020FA4D48C791642FE8111F9087418F74AE
-:10A5A000A4DB981C2F1E598F88EF6F855CB5B4AF64
-:10A5B000B36B0E233ECABD01849B28D72D34AFF365
-:10A5C000BD54060FCA7163431E83DCE0FA55E8BB35
-:10A5D0007B7F70FE5BA03FC7A7333CD4853E7100F4
-:10A5E0003CA87CBDC303FB7AD5E605F95A7E4473CB
-:10A5F00018E137278DB53FBE7364F8CD4963EB3C56
-:10A600009D9CB5EEF7ED6FDF3905C67DFBDB9F3B0B
-:10A610008CE32FFB229F443363E5ABEB252D1287A0
-:10A62000CF36789551C17D83058E577F3116C7F798
-:10A63000C9A4A537CEBEECE94E6CBF3454E9F05343
-:10A64000785EBB5152253A84239DC9DD6B85BCB32E
-:10A6500007C62EA270F7B7B7DC168A33CE6C0EEFA2
-:10A660003FBB4369F1F84C7C853E17ED96D9C38E0C
-:10A6700078EDAD7A7580F3B9B55DE80CE971C80E77
-:10A68000B2B41FED3AE6A6313ACC4C8A7E04F28889
-:10A690004C32DB61A79DD7D2DE3AEF651CEE89E62E
-:10A6A0001776AD757C9DC33F1CA2F413B7DE83F50E
-:10A6B000AF12A65FF5480AEAC3633BAFBD07CCB74C
-:10A6C000EB17DC7608D4E4CBA9416CD7107AA50649
-:10A6D000D9EDD4BD9301EF9FD5DE7B4F195DDA71C3
-:10A6E00025DCEEA11D8E6F92D06EB1CEF32AD72756
-:10A6F000AF813C3D17C623CC5E9D4747CBA56097F5
-:10A70000B5352054C8B79202463BD5B7E1F356326F
-:10A7100019EC87D0260FFD7DC2C64FD6835E262456
-:10A7200082FDDF75A83722BC09B373FB7BDC3BB627
-:10A73000D076AF825C80F1893A3654629013762FDE
-:10A7400096478B9FDF26C0CF99CA29B1CF44F350DB
-:10A75000C8E3FA1657B9BBA434B07702D7C17E0656
-:10A7600017B8BC3D14858B15ED1280CFABAFD86CFC
-:10A770006D411C16ED15611F072F0BDE755E19C8A4
-:10A780001F87E6A24B5904CECB85948EAADC3A8C67
-:10A7900057F6DB858F017EEEAD4F0AC830DE9CC0D8
-:10A7A0009B322D2FBE3829007E47795FE1011F1DA6
-:10A7B0007FE942C94B68FF790BC6FB07E8FE5236BA
-:10A7C000D071F26079C76AABC711F243986C066129
-:10A7D0000BA6B0582CF1B2EEDB3C8FB63FCFBFD703
-:10A7E000E6A6A09EF85DDF66271DF78EB6508E3771
-:10A7F0009DDA13E91F743967139295A5F5CD5509B4
-:10A8000071677C540BE5BD0F8AF13EEED20A08F960
-:10A81000992D1C9468FDD48CA405760A2F5F91981D
-:10A820003F6FB3368BEEE7E21B1F5D4FC75FFEDD68
-:10A83000490BECB0EE06317FE90258DFD259A25C39
-:10A84000EE82B22F85F787F55650F955185BBF3D5C
-:10A8500087CE9F21DACF58308FF63D5CD9526DA755
-:10A86000F3FFE8BBDAE649130999BEB0D2ABD1F2E7
-:10A870001319F50B52287EF6124AA7B4FC64C6954C
-:10A880000B60FD3ED9C6C7BF6A33ACBFBC413F0FAA
-:10A89000EA257DE5E65ABAEFB5CE814340AEEB3608
-:10A8A000E8CE2CFA3F2912E363A7A345CBA7B073E8
-:10A8B000ECAB8CE6E372BA19BD16444B408F0D9594
-:10A8C0008B69B9C450CE61E5BD9BC8D5F1E4ED6D8F
-:10A8D000994CEEED4D8E5FAF64307B80C20DF54933
-:10A8E000DA11A2ED8EA3573E4A77E37C079389EEF7
-:10A8F000CC88F1DBE594872B285F12275BA71867CC
-:10A9000098FEC8607287E89767803C5D0843D0ADC9
-:10A9100017A912FABBA42525321E688744ED4B40C7
-:10A920007FC8365CAF5F96AE5E44C7CB4A26E13D3A
-:10A93000F4EBCF2458A6FDB53DEED8782F71BAAF11
-:10A94000290AED84F16AB2734BDB83B171E8BA3B3B
-:10A950009C534CEBB6576440FDE2D29B2719E0397B
-:10A9600089ED83D201F6A3D33C3697F2C1DEBEF364
-:10A970000AC17EFFA945EE96F72D7610DAEECA4C95
-:10A980002E5F02ACBFBF9AC99FC19B53223DC09F9F
-:10A990004EB53464B03B031C1ED5772EBC1FDA3590
-:10A9A000F53948126DB77E4F653619412F367D3126
-:10A9B0009344A61ACAF6A80272A7E98B39F87BF568
-:10A9C0009D2F29C0A7304E80EE6BBD4BCB56016E3C
-:10A9D000EDF1F14F1D725C47D317E9449F6AFC9D6E
-:10A9E000C12936BE0FEB4FB7AFD8783289648E34A9
-:10A9F0009E82F54370B773B82BF1D7395FD02985A4
-:10AA0000B7CD405F4B39BD51E9877194FECB26F538
-:10AA100080BC8FCDBB09C7DF6BA778043BB02F3953
-:10AA2000007671B99DC9CFF2BE0CAF2EC5E843D0F8
-:10AA300085C0EBDE8C964ADCEF22C9DB131CBEAE70
-:10AA4000CBC4BAB83ECD6E08CBD718D627F8818EC6
-:10AA5000BF978F5F5681FCF32F4CFF50BE5901FC0E
-:10AA60000B760BEC438D962CF60C5FFFCFA8EC8099
-:10AA70002FC52383FFA5EE08E80101B7E1F0CF3F22
-:10AA80000D3EC7627D79DF330AECB32901DF8632E0
-:10AA900053B15FF691682AF8B5BF4C677A6D6FEFD6
-:10AAA00054D74CE08B853602220CF60DF66AB9902D
-:10AAB000B764D70B5576FAFB5099CADB00E06148C2
-:10AAC000FE469DCE58FBAACC5D0B3A689D2F89E2CD
-:10AAD0007F12DAA14E62F027BE9DC1E4584598C4AA
-:10AAE000B55B966532BB45C0FB7B1BAAC97B747FF7
-:10AAF000CFA533BEAC18D025C08BE06BAB9C7A8859
-:10AB0000E3F17BFCFB8F9753D269E4D4222EA7D8C4
-:10AB1000EF07A9990FEDB2B2A22512D589AB5E98C5
-:10AB20003A1EFC995B72E4C0FB94AF9648EA981F0A
-:10AB3000D171EB9C018C93093AA923CE801BE04E86
-:10AB40008DA62F41EF2F746119FE805DF269B7C4A5
-:10AB5000E89004D2EA4A12CB21B18E5B72149C6F4A
-:10AB6000D5E6F16961E3FAB89EB83C29FA2352347C
-:10AB70009CCF4599AE7FAD4D36D4BB993EFBD0A35B
-:10AB8000FD3483E2E15589D4E37A2CF6D26F78DC88
-:10AB9000C66A2FD5733BD20FE625F2B10D9DD3ECDB
-:10ABA000AEA408615D74F053B37B09E7D7A8ADC9C3
-:10ABB0004007BFCE286076ED15B4F202CA94CE6A83
-:10ABC000ED7D831C7B1ED6837A213A0DF8F4A50C0B
-:10ABD00062B2F31AE4508104766B76920A7286E2CE
-:10ABE00009E170D045EC2E3AEF73F40B78AB916F1E
-:10ABF0003EE0F0011D486A3B427F07F75B4914F4D1
-:10AC0000CDE57353D06E25A76E1D07F10A7F0AA309
-:10AC10005B3A8E938FE3443AE172EF376327F68015
-:10AC20007E12F253E0819C92713C517F505A54E065
-:10AC3000A5E583FE734BDB25B3FD03F650CC7E5AAE
-:10AC4000BF793EB597A6D7F6466D5E902AB72FB866
-:10AC50009DB6AFA1F6938BEEE78F194C0F1E0CEA51
-:10AC6000722A8C379EEE83FE7428393CA9C51DC319
-:10AC700007B571C280BF2C857EDD8C3FE0DB99C9B2
-:10AC80009091E163DF06FECD4A65ED87E93D5EAF59
-:10AC9000490CDE5B2A999CB0B6B3F171D73AF5DA6C
-:10ACA000AC42A37D1522408776C2EC2C19748F1F0D
-:10ACB000F519C2ABFACE8634D09B9FF52D4D239368
-:10ACC0006272D4E1FCEDD8F7A91C899225DF017EE0
-:10ACD000555E9709D8CB7738185D2AE9616F06FD74
-:10ACE00066A6C4F79B27F2F564825F4DDBDDC3FDEA
-:10ACF0001EC717E7A3BF9D9FC9E245A9397528D78D
-:10AD00000196018AF73432A87B0D784CABB099FCE0
-:10AD100007C71793B1FF99DB0FA509EC873293FDA5
-:10AD200020E6B5DA116FB6E6E0FA45FF1539AFD582
-:10AD30001043FB9564E00E186FE5FA7C53BC289134
-:10AD4000FD3137531AB217F4B8EB524CBFBF49FD6F
-:10AD500045DD38FF31367F6CDE14CA70B179E54CC1
-:10AD60004DCB44BF6F96F7E8F9F4E3A2BFCBA877C9
-:10AD700050FE53FDA4ED70A35EAA05B92DFC24E09E
-:10AD80007F6F1AF077656DA6DFA027793FAB3C3A5D
-:10AD9000C0FDEA035CDFA41D117663724092627A03
-:10ADA00067B8DEE276B1453E9ECECEA674AB1BED13
-:10ADB000806178CEFCAAF6655102FA98F00FB12FA7
-:10ADC000CB6785E512909FB512194F3FD3E799F5F0
-:10ADD000BD9EC9FC109D329CD16F59DC606ED701BD
-:10ADE000EDFCF04D1995DF62D447920C728F8DD730
-:10ADF000CCE92178E2552540E57094DB43BB7CDA51
-:10AE00005D40171DC9A993414F74248F8D405C622A
-:10AE1000C7FF5617EFA0EB1F7CD9A1F6C0B0FB18F7
-:10AE20009D542E5FDF6EA7BF3B7A256F1289ADD38D
-:10AE3000BD41D256533EBE9FCB89261FDB4F932F79
-:10AE4000AA8CA3F3E735B17514F41E90EC0679577C
-:10AE5000D0C8DAEDC87498F4CFA350A6E33C22FC26
-:10AE6000111269AB2983F69A1DCE41F27A258C0F17
-:10AE7000E7B55040507AC853D9F86E35225D3B296A
-:10AE8000B6DF2EDBA249A027BAB25254D013277DD9
-:10AE9000E1C760BF4DFDD128806B7A7F9F1DEC3DDF
-:10AEA000975FDB0DBF8B7D06646F1EC8D9947EB69D
-:10AEB000BE6E0BDD1372175F570F93BF32799E0082
-:10AEC0005E4086D0F9B23615A39E12EDB332B8DEDD
-:10AED000C822E127D0CE225D04F146701F599B267F
-:10AEE000A0BD2FF01AB3AB264E01BBAA686BD4BE2F
-:10AEF0008AF67BFAA1F8F1FA17399FD07D1C34EE5F
-:10AF000023117F08BD26DA3912F8D582EE536AE3A1
-:10AF1000DBAB5413607DE572DF95B0EFA60E8524A0
-:10AF20004931F8BBFCA12320B7F27A7748001B2BEC
-:10AF30009D7564FC50CAA7FBBCF546E29549E275D5
-:10AF4000376D90B5D5467EEE5018DD28E6F33DE12D
-:10AF5000677CC2E305B3FDA163008FE67DDB14C00F
-:10AF6000F38D3BDF51463AD7192DDCA446E6BF34BA
-:10AF7000D53B23B0DFCAE576C4E39A0E2502F2A9D9
-:10AF800069F79EA80DECEC8D4405FE6FEADD732891
-:10AF90008FC227BF499B260762E3E5374524584FF8
-:10AFA0001625C63EF4FFA20AE86D2B7D839D0CF6A4
-:10AFB000CA2117E3FF0F2BDDBA44E1F8A123DC041B
-:10AFC000ED3ECC4D51F5600CEECFED99FFBC4459F0
-:10AFD000DCF3445214BE5DB69E1C276DD7759EA24D
-:10AFE000023DB9FC618F8FC229C31EDA0BFDD37DF0
-:10AFF0001EB58DF60D249129A8AF470987E916BA29
-:10B0000098BE91F1CB5C5FAAB003A7805C3AD7E70A
-:10B01000117614CAAB430EB68F0EC2D6DB99A915B2
-:10B02000C07A883703E7CD6B8A4AE00758E78DD1AD
-:10B03000955688ED47BDCE5E05E4FC1A2E6F2A9723
-:10B04000EF94DE33D041A98F9DCFE6EDDE21817FE5
-:10B0500048EBDB6A7CD89E2481BCD9CDCE29D6D0E2
-:10B06000FAEB0CF245EC238E9CA980F5B9FBFB9E14
-:10B070006572268AF427D66BC5E73C1FB3EF2EA274
-:10B080006602FEAEE8C5013ADEA1C2641C4FF0BD07
-:10B09000954FE7F9189DE7D5EF94209EE04B61F6B8
-:10B0A000A4589F68B7CB5755EB4338F4211CD6D62C
-:10B0B000DB116F623D354A681CF865CBF878CF5CD0
-:10B0C000F1963240CBF7FDF415A4C7B5DD9286FEAC
-:10B0D00042F72BCA5288DBE9FF2E439CF61266A288
-:10B0E00090ED3F7905F5CA257B59FC60EDDE3DF614
-:10B0F0006BDD313A0D9E786625D0D9DADE24E292F6
-:10B10000007F01E4532B9D523983744F7405CFB9EE
-:10B11000A89CD451AE927010FC1421873B397F1348
-:10B1200037FBFD46BE6E316E4C7EBA90DE8327A69D
-:10B130003CE3A4F05CAB4AAA0BF891C39B8E1F457D
-:10B14000394C4821F86B627C2BFCFE99DBED71F0E9
-:10B150007C1BE0D9AA4F849E0D3E5C45E02BF06736
-:10B16000E7701FD2EF3E05D7DBE1B3333D5FC9E2A5
-:10B17000DA1D0EA6473ADA9C11E0EBE7D22F7A5E91
-:10B18000A2F2D293A144E17BD0B6AA09EA0FE6B1BC
-:10B190007574D93615B7303D76870FF1974A987C8C
-:10B1A00062F2E8BE1F3379D2A4BBD17F6C0AD7AD5F
-:10B1B000C673099F4B857309127E5659EA89D1835C
-:10B1C00015BF81270E28015A7F492FE38318DC9889
-:10B1D000BE12744BE51CE2BD33539C5F868300575F
-:10B1E000EAD7B741FC41F8F5A90D21DD1318CEAF20
-:10B1F00099DCAF9FC6FD7A4785F36FEAD7AFD9F0E8
-:10B200006BF4836ECA7901BF825FA8FF68E2AB2747
-:10B2100038BEEFF731BDFA948FD1D59AB25EE4878C
-:10B2200035EFB7201FB96B993C71F79BE52021776B
-:10B2300073FB602B8E5393D27B910C7EF2BF4ADE60
-:10B24000769278DD37482DFF097932640FCFDF38E9
-:10B2500045ADFC720A571787016FF76B1FF3B73EB6
-:10B26000DC4511017C696F5146B2874F372E89BE8C
-:10B270002601BED770587FB8BBFAC23F409C7157B9
-:10B280001AE6B37CB07BC937FF40FB7FB873AE0AC8
-:10B290007ADAD71E42FA19F4BB54882752F1592B97
-:10B2A000517A68EBFD55EA4C382F7BEC8229203728
-:10B2B000DFE57C79E2C7F20680CFA67F7B7C0ED4E7
-:10B2C000AF894899603F7EB8EB5FFF0A7AB171E7BA
-:10B2D0003ACC4B6B7FEC976897DB223BD8EFBBD225
-:10B2E000D0CE3CFEC8B63900F7F6DE76AC3FF1C8EA
-:10B2F0000E2C3FF36F8FFFE22F60778452556877F3
-:10B30000E2C7DBFEE92F40E775A92AECA3296C67A9
-:10B31000E7B982BEAD726BCF01E453412F9780DE57
-:10B320000538D533F923E8F95D7EDEB4AADADD0508
-:10B33000F2ECDD2D9EC6787146C5CFF002B11894AF
-:10B3400063F512C6D9BA28D540BCA32B9954C0378F
-:10B35000655254C9A7F35CD1B0670EDA3DFA3BD70A
-:10B3600043FB25FB5C640BC6E520A84BFD0124755F
-:10B37000424AA8183C4AFD663AFACE2F29DD1EA69D
-:10B38000F201F58EC51F58D2F5C2FF801CAD730EB9
-:10B390001C0051287EEFE2F11BDA1EF54EF9FAF897
-:10B3A00071D254BF9BD32DD39B797B171504504E7C
-:10B3B00024A9E30DF6E998232D5B203D29AFB1EFD9
-:10B3C00022D8C7C5C5D74C45BA80F81FE81FDD8D08
-:10B3D000E3AF85F825E5BF73FC3C2EE225BE19746A
-:10B3E000FE1A3BF1B9E14BC86B0E94238FE2B8D43F
-:10B3F000FE40BB2AF0CB2B1E057B64BB239C3B0D80
-:10B40000C6E9E27A6B275B37EDEF8573543A9E7796
-:10B41000C6141CA7CF9181FD75D67FFECE3629B606
-:10B420005E4AA963416FC178656ED0337A3DE227E9
-:10B43000A0E0BE4E40935CDCF7E4152531FEB5C6B6
-:10B440007D409EC1F9F06C7F65857F5AEC2BE2410F
-:10B4500056786EE4F53FF36BF825BB324D7A2591B3
-:10B46000BDF2CC151F33FDFBB37750DE34031DC393
-:10B47000FCE1F74DFAF75A41C74FBD83747CED3EAE
-:10B48000A67F9BF7952A40B71FB46AE43D6A8036D1
-:10B49000F3F3D7EDD2C0F598EFF294CB0B71BD8FDB
-:10B4A000B9BE59B3F59DA3706E5AB82F17FDFC8F26
-:10B4B0009F72D5C338076D3684E7C19EF377B44BCE
-:10B4C000C67532BF80DAC148AACDD44E6576F0EA9F
-:10B4D0006DE0A7AD6D242AF07FB3857E9AF7BD821B
-:10B4E000F422ECE0E0C38B5733FBD3A5BAC08F9BAB
-:10B4F000C7EC5142ED51689F3E2FD2A6207D959614
-:10B50000037D3D73C52F3A418F37CF235E187FFBF4
-:10B5100018EDA97CDC8F4420CF65BBA3BBCA4EFBD2
-:10B520006FAF0978292429DC76A2DD4B8A15AEE7B6
-:10B5300056A3BDDC9C73958A7C6695074FB5A1DD4B
-:10B54000D51C48C6F55CB24FBA85D9236EC2D62F3A
-:10B55000217D5E12991981F8D9471C7E028E1F3B0E
-:10B56000FA56023C3EFE0925445A7FC93C46AFE9E3
-:10B57000F37A518E3CF7D47CD4E3822E3D4F26A142
-:10B580003ECFB07B2515F5DA9224235EBB1D4C2FF0
-:10B59000A5733D53B495E1B793F353A7DFC6BF8AB4
-:10B5A00039FEE2D52783DEFD88E31FC508C8772E64
-:10B5B0004FD6AE8E223F35ED66E3F992B4D25B0DE5
-:10B5C000F4EBAB667A519C07C0F9C0A238F2E231C5
-:10B5D000BE8EE0C3ABB681BD7C31C53BA894BC62D6
-:10B5E0002E47295D00DCF21A43480717FB6E5021F5
-:10B5F0003FD59F49D05F1C6C5348BCB8CFE35C8EED
-:10B60000FA3343651087F6677BD0CEF1CB953617BA
-:10B61000F42B95D49E009E7BA29D37E8CF557B4CA2
-:10B62000FC1E2AB3D176C7B23C0CCF91DFD8179756
-:10B63000001F06D8B816BB6FB8DFCDECC685DDFAA3
-:10B6400064F043C4B9868043A42DB9DE283F7FC28D
-:10B65000E11099C8E2A9D4BE77635CDB4BE701FF38
-:10B66000BE67E623CCBF6FC7760FFB997D5443F7C7
-:10B6700007769BBF28B49EE9538F1A0F1EB3FDC2F5
-:10B680002E5F590A7E65739D5B057EBBEF67D22AEC
-:10B69000A467081682DF1D5E8D7820140FC00F246A
-:10B6A000CCFCD2E69650243EBD2F42FE6B06FE93A4
-:10B6B00090DE310E4FE93DC2E89DE93FE1FF837C1A
-:10B6C00034E61D0A3920E44BB3323001E858F04328
-:10B6D000F39C810900B7D1CA938F1D94FF817F2805
-:10B6E0001C807F04BF789E667CB2A52D5009F55B57
-:10B6F0006A88B7DDA08FACFE12AC13FC4E21D74F89
-:10B70000FA42C7FD1007B0453B21BF42C8E1E6A79A
-:10B71000374F8897FF26E4B0D3CEE49B339212696B
-:10B7200037D0179CF979A6E017F3795236C48F8F7A
-:10B730009CF2BB791C7F74F91259A0CB41DEF4A4B2
-:10B74000605EBB881759C7FDD82F99E232C26F815E
-:10B750007307689F93C5F827258BF3679688CF46B4
-:10B760004CF41FB085DF813CA344FA4BF4FB5BC56E
-:10B77000AFC43C428F5AF12FCE4D603F8B26256ED1
-:10B78000D77D80C9272B3D4EE47C72147C0FDAEE06
-:10B790003FF839D770FCB2714878A2292FAECBB6EA
-:10B7A000A7315E1C4C9C779087268E2AEFEE402BAB
-:10B7B000CBAFFA0F9E674B564F34E559B9D5401BB6
-:10B7C000C451AB9CC15219E765712CCF1CF209E83A
-:10B7D000E1C9FBBA8B217FC91F329F9764D7279B92
-:10B7E000CE2372C319A6727E639EA9FD989642531A
-:10B7F000FD391BCE33D507F529A67251D70C53FB63
-:10B80000F1DD55A6F2B90F5C6C6A3F31B2D854DE57
-:10B81000D2D65B0F78397FD795A67E5576AFBD948B
-:10B82000C2B5A47795397FCC02CFB4BFCA71E9B055
-:10B83000292B8878ADB29BF3882FD8678607A4CBD5
-:10B84000019C27133EDE9C635346CA6F9D4CEC7FE0
-:10B850001E10FD83C3E9813807D4501C3F53D0B973
-:10B86000285BCFB584FC3853FA4BB44E417F89EA4C
-:10B8700013C1ED3B9CFF055C1C4370A95747828BAD
-:10B88000E3747021142E9EAF0E17EB789B529A3101
-:10B890004FF8352818ECE38156F37D98657A1AD372
-:10B8A00043A125A7B1A3591C389CC4CE2BADF5FFED
-:10B8B000C9E1F2218509E261947CFD16C7437F222C
-:10B8C000BEDEF0C9C16C90DFB504FD666F4BDB27AF
-:10B8D000A0B7AEB64709D0FF7D7C3FDB79BEE80359
-:10B8E000AD5E1CE7417E1EF9506B007F7FB8B51836
-:10B8F000BF9156157FEF69ADC0EF4E6ACFC1F70714
-:10B90000ADB5F8DDD51AC2763F6CADC7EFEED630D7
-:10B910005BD7307C9172B473429971E3A5D7E8F29A
-:10B92000A8F044E482B8FA32E13872C388F9E51B22
-:10B93000FAA5C79F35F0EF5B591EDF51C86D9C4ECD
-:10B94000A6C3F9E6E9FA7FDE4A1E7F76FCE8F948ED
-:10B95000D013399539211E5F87795EE563DB57DDAA
-:10B96000A54F4A0CAF189DC587539DF3E33C70D695
-:10B970002783CD60E82FEE9F88725D382DAEDD9075
-:10B9800097CDF46E7D123B8F5F6EE1EF6F6533FAFA
-:10B99000FD5636D377BF4B2067D2793D5DA703CFE5
-:10B9A0000787F1DD3DB3E3C1F7AEEC80292FC57AFF
-:10B9B0006FC53ACEEF1CDD63D4387C76BA71C4FE15
-:10B9C000ACFDAEE2FBFF663661EBFF7FC69FBFBBFF
-:10B9D000CE83FE03C0CD6FD8FFEFAE4BA98F179774
-:10B9E00069CF66E7A1D43A27C10C34F575056CC55B
-:10B9F000621260E7BEE3BC101F12790189E9D58E9F
-:10BA0000712484A13C1CAE141F01A5888E6F1F9A5F
-:10BA1000276A8779545B4CCF42AE0D31DCFF9087AB
-:10BA2000D303EDAF2B98D7339007EB3B537A22F239
-:10BA300043E3473AA71BD6FF0CE5CC9AECBFAF9C7B
-:10BA4000117C4E4EDD3B3E9E9EAC87B967507BEC31
-:10BA5000FE87989C39CDB8670ABF7A7900CFAF4787
-:10BA60000DBF7DBE51C5A53E77A54E26D4AFDBE008
-:10BA700064DFDB93537BE0FBB96B6C84A4527E8163
-:10BA80007552BED5AB08BBBFF596F09B5AA683BCDA
-:10BA9000DD9E1B7A309B8EB34A61FEE29FB2B4EF0B
-:10BAA0004339999F0B27F37361255BE98432D18A6F
-:10BAB000715F17F07D75DA0263615FEF4BEA44F066
-:10BAC0005BBCB6880ADF54122D61F9799130F86BAE
-:10BAD00099E72707C0DF4D9E40481FC6C75517C4CA
-:10BAE000D19494C117C701FFFFD286F7A21FF7B206
-:10BAF000753EFE403E9EB350818FF26232FC4EB7DF
-:10BB0000B205EC72DAFFFB52F8896CBAAFE35EA7BC
-:10BB10006EA3EB9ABCF9BD8C0CFAFBE3FBABF05CBB
-:10BB200021BA4BD615B8DFD0F7E1772FA1E35DD06E
-:10BB3000E7C0F8F3054446F9BEC64EB6021F25829B
-:10BB4000EF07DF889F07E6C8914CF95DD6FAF7B991
-:10BB50001EF82041BEF16BBC5EE4CF3844FE8C5F22
-:10BB60001B317FC661C99F71D84304CE851D43F93F
-:10BB7000330D04F367E838C6FC990FAAE2AFA39F20
-:10BB8000CB73C7172909C64DC5DF3F281C799F8E87
-:10BB90002F5CA67CEC587F37FE9E287FE73301A7F9
-:10BBA00004F94B9F0CAD2F97E899C67E8CEF62F39A
-:10BBB0001460BDC3920714AB67F93F1DE98C4E0EAC
-:10BBC000E4787DD7D0A1AF2103789FF36AB7CF0186
-:10BBD000F1A41051F7E0FD1EBB637040F06121B489
-:10BBE000B3BF0B76B78D4A5EB0BBAFDEE07877C0EF
-:10BBF00020B71669E63281F60639BC1862D8741F80
-:10BC0000C9E71563FEDFA72490E61D418E3638E5AF
-:10BC100090DDB08FFE0476C4859C0EFB73E3C3AF4A
-:10BC200030C766CA631ADE9FE703F07B68B77A47BE
-:10BC3000969F00DF70A6717C2B1E7C587F3A38FBE4
-:10BC4000E1B00DE26A9512CBF3FF9BC33B9DE7BBCE
-:10BC5000B1FB030E4BBEFAE25CEBBA59BEFAFDE94A
-:10BC6000A19939D82F30C1785F60AF5D4B9942BF41
-:10BC7000FD5CEE58E1B289C3D9BAEFBD3CEF3E5945
-:10BC8000262D7B0CF0B7EEF71B398CCE45FB0E074B
-:10BC90003BCF02C1E7A4726F0561726F454E21CFA1
-:10BCA0001F4FB703BE1AD8106485F7109E2F0938AE
-:10BCB0000F831F87BB158E21125809F9DDA783E773
-:10BCC000865C6D450E9DF79A57921590FF2B9D83CC
-:10BCD00007C1671DE8B31D1E47BFEFB8C71DDD498B
-:10BCE000E03CAEF8C967E837B542657915641EDAFD
-:10BCF0003F929E2F7F79FEE8ED9FCED47031F0C742
-:10BD0000FB3C3F5BE8A5CEBC131320CFFEBD8CCA25
-:10BD100029B97E8CC36B9940473F4F6274F4001D74
-:10BD20008996D7FD6222DE87BF2A37AC423B91E776
-:10BD300047B4C109909770A670A27F1C4047A783A3
-:10BD4000D39A1CC2F831353E9DF4E4B0F8DFE9F82F
-:10BD500003EFA195FDFDF843C0539C6388F5A9B995
-:10BD60008C0EC557C0CD9A4FA4E6DA783B96AF78D3
-:10BD7000556E08E17C72CC27475D74EDFD4AFCF7F7
-:10BD80001D9E1CE5FE05BCFF5E72B83F39FEFA5EE3
-:10BD90004CC0C7FFA8F54DCDE5F43339FEFADE1EE1
-:10BDA00025FC4264F0ADF4BF831EA3789E0A78267A
-:10BDB0001D83281FFB33E2AFF3AFA35E67D8F1F713
-:10BDC000D0B782BE897E4D239EDFE724C73DBF5F8B
-:10BDD00046FD29F087ACE7F8E2BC9ECA0FDC6F9DF8
-:10BDE00073706526E07D1EDF771689A6C3F9E62FFE
-:10BDF00092F03C60989EE4FC41E195920BFA64E17C
-:10BE000020C635FA27C4970B29B98CEE86DA77B1AC
-:10BE10007912DD43C8CC9546750F819485311E5843
-:10BE2000E97447658A875B383E94FC9B54B00F2BBE
-:10BE3000735E3A02FBA4F0FF70089E86FCBE13AD51
-:10BE4000CF7BC73912CBED35F213E52D71F63321D7
-:10BE50002B3C21D7106F5CB3EB05EF3803BE4AC80B
-:10BE6000808DDDA31EB499FCE46C72467EF27E17D1
-:10BE7000E397F73242A80F403F80DEE97CFAC252D6
-:10BE80004026D81990DF33E8494639DA9E37A3387F
-:10BE90006080676DAEB02FE50476E3D7BB1F10B3AB
-:10BEA0009B2493FD1A1BDF8EBF0BFC54BA5F8C8B57
-:10BEB0008F0959DAA500CFBF646897C1D70A3FFD43
-:10BEC000CE59E978FF00E0373736DE10FE13E0F98F
-:10BED0001B595A3DC04DCD0CB0BC0191D73714BF92
-:10BEE000B07B8F3A63F01E2D5E92797C8DDA0DABBC
-:10BEF00061BD4A12E747E2C67BE4C26E2116FB86AB
-:10BF000014337F7745CE4BFF03F19FCE54C6B29DCD
-:10BF1000FFE4423FF06AC9ABC0BEA9FDF1E6F76994
-:10BF2000FB3089BEF92DF40F859D91227F9932FA5D
-:10BF3000750AFFF97479D6CF803D46D7536573E310
-:10BF400079E733747FB9546E5429EC5B399F5215ED
-:10BF50001DAF4A2ED83F40D7F51939953C9B7EBF7F
-:10BF600043181CD6BFF2870CF047ABEC8E1346B9D2
-:10BF7000658D7FDC956B8E7F7C4616FEE67C80CBE4
-:10BF8000AC0C84CBE4A7E6651BE32F43F10FBE8F17
-:10BF900025FA354C9E5AE49C906736277B6F84685F
-:10BFA00024E0CDC2381283BB2EE1FB57B345199C68
-:10BFB000145A9EC59124417FBAEFD9FC4B56857324
-:10BFC00040CE405A0FCC47BDBF1CF8B65FA806E074
-:10BFD0003B570AD9D93A222C0F91B414407B9B735A
-:10BFE0004086F945BC02579205E3887959D9C3CBFD
-:10BFF0001D759FAEBC2E303CAE41DC1EB47F15BE1D
-:10C00000BEE35EB76E33C43B92DCD1E398BFCABFD8
-:10C01000D6B8C7EDB2AE43FE7632E94579E9767F10
-:10C02000A40330BCC42B41F9FB52F8E7C017479575
-:10C030006E12A4BF9FFCF9E704DF65831B6245F025
-:10C0400035EB27BF7B3DE645FB43768B5E0A4BC055
-:10C0500047D9F5D6DFCDFACA49FAF1FE90140DE5BD
-:10C060007C9979FA784EA2388EA38AA17EF0466632
-:10C070000F1F4E66FD0F27B37E6F71BDD49CA110BC
-:10C08000CC8BC9723AC19EFFD8730CAE6C823EE96C
-:10C09000027DE274688857A157D6EEBD9900DE9AFA
-:10C0A000F72D4238FC5E62E7A4FA0A09F319C4BB13
-:10C0B0000FF593C8CBB4279991C7FC94A5CF8757A8
-:10C0C00034D172DD4BA4244ADB95CE0DD5C0FB2EB6
-:10C0D000ED2544DD44CBEDAEF08F7E02FB7885BDCF
-:10C0E00037B68EDFABA59858B39B8EBFE3CA31EA53
-:10C0F00016D852F56027E40B0D6E265EC82F194640
-:10C10000BFA7283F507A7804CA74DDEB5687FFE555
-:10C1100036DA3EF725A2621B5E0F3E0AE04FE2745C
-:10C1200001BFCFA5BFAFE37454B45F62E7FC3EF636
-:10C130000E180E0EEF7439D9FFAEDB5F79F934BA01
-:10C14000AEA2BEA948DEE3687BC883824C04D69EBB
-:10C15000D8E2B51F07ED0370AECFF043F2147C3F79
-:10C160008970F937DDC2873363FC80F5A5BCBC8ECE
-:10C17000EB2913DFC038D46FD7CAD9B13FF6F331FA
-:10C18000FE5089F8C3F8790689FD8171AB63F3A08D
-:10C190005C9EC7EB0E2E5F80F9DFD3EDD103C0EFBD
-:10C1A00033F9B7947F81DF9D148E57D85B0EFAE97F
-:10C1B0007ED23710B50D666908B4C37865242403B0
-:10C1C0009CCBBD9BDB617D1736BC9209F475735E19
-:10C1D00011D2DF2CA75AE4A224D25EA1AADE2278D3
-:10C1E0006F4C42B82CAD774620CF6DE9D07B3FE154
-:10C1F000E032CA3F5784257E0F3F1C6C30C46D452A
-:10C20000FEDFB224EA5FC791DF37E731FD2EFAAFD8
-:10C21000E3F75344FDDA3C37CBCFCCBB68461E9ED8
-:10C22000C7B0BC68CAFFB3F3A6C5E40A9D17F356AE
-:10C230009610CD01FB5AC2F957F0FF52ED56B46784
-:10C240009786CC76E9EF25866F7DB98476E215F581
-:10C2500023DBAD0BF3C4B9708117F500117A8AD1D5
-:10C260009590E78B41BF831CAEA5FADC603737DCC5
-:10C270007E2A1DFB65FF60ED97E7C4EEC3ACB3DC1F
-:10C280008769E6F761D6ED6B736401BDF3FB30EBB4
-:10C29000F6BFD369CC0314701A7E1F6610F31F9784
-:10C2A000299103704F68D94D748FB4FDAFF8FD89A3
-:10C2B00067E1FEC494181D79AE7445597E9D867958
-:10C2C0007E05DE1415F252BA6C5330AFA82BD5A3FD
-:10C2D0001AF378B6B4B5D4403B914F24EEBF2C4B43
-:10C2E000706EFCCD3C663F6F97585E97BEDC89F060
-:10C2F000F6CBE488F19EBFBF2884F97433F202388C
-:10C30000CF761E5F80FCD3A9F41BA1661AC317EB7E
-:10C310006F950F74BC0E18AFBA48C53C9AEA3496B4
-:10C320008FE6CF0C95DE3229366EDD7E96BF57172D
-:10C33000FAE410CBC35D5406F04C24D7ADFA8BD28F
-:10C34000DF3D408FC3F556B819E8CF51155A7E1D11
-:10C350001DF7E4CB0AE6DB918D9AE4A0ED7EFC822A
-:10C3600057857B781D95A14535586FC77B8259F558
-:10C37000249A44EBCB5E527A20CFAF91742B304E8F
-:10C38000A3458FDDE47E56013EBD69A72346970491
-:10C39000F213D52210784DBB87C545500E09F964BC
-:10C3A000A56732CE2C874A85DCA5F281E5F73530CA
-:10C3B000BD477E20417CE8A4E798CCFD6B947BD3FD
-:10C3C00084B0B2C8FB69FB9F437B46C0730E9517D0
-:10C3D000E0C749F0FB64EC87652A4F8B21EF742698
-:10C3E00049467A1B6647F0F5950DAD9FD94D424EF3
-:10C3F00056561002EF2358F143E7433A17E77D7092
-:10C40000B402E70833F9FC9FDBB449D120E08B4448
-:10C410006C14CE9D520BEA1D27E481D2EF16298CB5
-:10C4200072F1A7BA2E035C2F242D4B160611EF2FA5
-:10C4300001DE6739FB52000F4715D509F5359030FD
-:10C44000885F33BEE6BBEFB303BCE6E758F1A2DB7F
-:10C4500001BE0B02C3F085F70BB404F8D2845C2153
-:10C4600066B91224A7D8FDE6CD876E03FFF874F6EF
-:10C47000C9F7B2C247E3D1AFB05312E5E59DE4F28C
-:10C4800078B47979271DCCAF984106AEDF2D0DA782
-:10C49000938F0F6E90730CF424E8F4699EA72FFD20
-:10C4A00092E7FD967950FFC5F425A383725E9A0149
-:10C4B000F465A083D9FB5C5199EEB394F79F01F426
-:10C4C0003025A62FA33677402904BCAB5DB23CDCF7
-:10C4D0004ECECA0820FEA7DA34C4FF34EA8171BB0D
-:10C4E000D39D4FF75FE1EC6DB70710FFDF07FFA6A5
-:10C4F000920410FF9516BD53EDAEB3039D543BADB2
-:10C5000078D610FF35DE61BFDBBE0AFECF01FC0B23
-:10C51000BD320AFB94E27F42FE08E78D89F07F413D
-:10C52000BEFB8CF23205FEAD781772608FCB5BEDEF
-:10C5300086787023CB4B9EFAF2B8762867AD0DE271
-:10C540007D993DE9EAAFB0BE85D597F56932BCCF9C
-:10C5500058B49ED6D3F29E60A81ACAEB3648284734
-:10C56000A7BD166E87F2B88DACBE7453CBAFE09DFD
-:10C57000B3753AEBFFF4F14E7CAF22D2C9FB57768C
-:10C580005743795D17EBFF478F5307BFBCFC48A4A7
-:10C590001D7E9FB895AD43D87D7339BDED919EF852
-:10C5A00015F6EB66FD6E38E44C66FE12B3E3E6F07A
-:10C5B0007DCE7D88EDD3F7DEC5B5010AF7EB0675B4
-:10C5C00007CA0D5B5339CAD1047E5AA5D45D00DF7A
-:10C5D000F9544E10C43BA5D34296B7DA43A75893FB
-:10C5E000CFEC2691EF0979E78B0CF85A93CFFC0832
-:10C5F000D12E2B83B0FCE407D9BBB3221F357A3F81
-:10C6000091207E007B44FD9B203F757E510BEAD339
-:10C61000F9E788BCD401FB2A3A6FE9977FBA289ED4
-:10C620005F7E4B3EB3938EF13C7AF17B63246803CB
-:10C63000FF640F100FBE03147D19EC963DF0BE9100
-:10C64000E11D923D4156D6F3F7DFDD459DDC1B6CC5
-:10C650002D761D94C05809DF55B9AC8F44D352874D
-:10C66000AF7FBE9D4459FE045BFFF5ED4ACF1683B4
-:10C670001DBF54888F59E351AFD4713C09B9B194AF
-:10C68000E38BF2F9E67CBAFE65CE16B41B9713A6CF
-:10C69000D76F24118C6FDC68E1F335EE3FBF65B3D3
-:10C6A000411CCDCCCF6BE972D8F9FAE0C3BFA3F03F
-:10C6B0006F7CC0E305FDBFB6D7DCAEF181978F304C
-:10C6C000FBCBCCEF8D82DF23667EA70605E3F7FB6D
-:10C6D000CFC3731B713FD0E51C7C4B27B1FD0EE926
-:10C6E0007D0BFFB9E0BE6031F8353696A7C8CB6246
-:10C6F000DE4FBB995ED6A95EE67E108ADC4FFB2F2B
-:10C70000C17CF852A147B99C11FC5CCAF5FC303DD4
-:10C710005E6BF577EE433E99CA4B56FD2DF4B6B8E5
-:10C720008748C745FD4DF5F5CB1A5D6F9FCD1D01BF
-:10C7300078C7F47604F9688A93CA6B1BE2EF00E0CD
-:10C740006F1AC75B3BD7EB09FD03F7FAB8FE01F59B
-:10C7500037F01C61B85F1035D9FBC3CE3112D8FF5A
-:10C76000437873517B2A05FC7DC2ECE23C32AA3C43
-:10C77000112AB7DFCC1F416F2BCFB0DF0777B8305E
-:10C78000BE20E2EC82FF5E2F6076F8B65CED3D9055
-:10C79000FFFD7CBE7E3E7EFFCDF3F1FCFBCF44C3AC
-:10C7A000F36FC867CA8F937F01E7DF1D8678697FC3
-:10C7B0007AFC38F8275CFE941610FCFEC9AF7D0A9F
-:10C7C000EB3FA6B038FBB164FE4D65E714FF3BD4E8
-:10C7D0009EC98F4CFE15EF911FCB30C7E7453B3FFD
-:10C7E000FFBEDFEA0C7518E2E181FB935A408FF936
-:10C7F0008B785EFC7A46C7279F4ADF617C272E50E4
-:10C8000050595A300DDA694A2EC4679E62FAA2D98D
-:10C810003EA0C0FB3E3E7F38A5C00FF79B88F604C4
-:10C820008C1318509650789FE4E7FE27F97B402739
-:10C830005DEC2BD6152858540AFD4EDE3C80726301
-:10C84000A8BC6800E542A02084F39E5C2AEA79F93E
-:10C850006E5626DCAFACE47C8271E33871E2E171A4
-:10C8600061F37B37EB94F8E7D5A4C0638AF7AED8C1
-:10C87000CFE2902B9DA4339FD65FBD3F1BFD8DC69D
-:10C88000547D02D0C3D78DE39E1CD387FBDA523987
-:10C8900038F6C1323C17C678D1DAFDCFA1FC5B2B4C
-:10C8A000F866AF996F66178CEE3CC51A671F053F97
-:10C8B000CD2F18C10E7A12F4972386875B787E53AA
-:10C8C0008DDC540D71A54F5713BC677BCB0B32D257
-:10C8D000D52D3F92F0DD0961C7ADE5704EB42FB89C
-:10C8E000A71030C815B8A71030F875704FC158861A
-:10C8F0007B0AC6F6704FC1580FF7148CF5704FC104
-:10C90000582E25D7B6439C6E5D17F14602ECDE82A9
-:10C91000B13FDC5B3096E1DE82B13FDC5B30963FBD
-:10C92000250C6E9F3E2463FC1FEE2F18FBDFF0C228
-:10C930008FCBA3B06D17CB536B7751F8031DEA5A19
-:10C94000DF240A9FD51C3E70BFC138EE07A9173DF2
-:10C950000FF859DD77FD42F85EB0EF26D3B8A49BFF
-:10C96000C9E316FA17E0783D09A5813F37850C1E0B
-:10C9700082784773445261DE1B1E30CBEDA1F74C29
-:10C9800022E6DFD71043FC37383CEEBFA5C0E343B7
-:10C99000BACA2379C6784F8C1EDC6A14E0F09AACD0
-:10C9A000C6A38752726E1AC6799E97218641FE48A9
-:10C9B0005AB6CF920CE703167824E598E9C21530F1
-:10C9C000D3454AB1992E3CAA992ED22ACC7491AE65
-:10C9D0009D37227C336BCD74B2466E42BE1770AE6B
-:10C9E000A07F01CE53E0854A802FDD27C48BADF0B8
-:10C9F0006DDCBFAD13ECFE3385EF9316F87E466613
-:10CA000055BB03585DE72C8FD93165CFB7E021B016
-:10CA1000357E2AE028EC081107A5FA1FEDE9985F9A
-:10CA2000CFFC3D6A1F1C2CC0F303E6E7012581DC27
-:10CA3000BC8E84513E5D67B10F6E70DFA7807D3084
-:10CA40006CBFD43283F70BADFB057B8B18E25256DB
-:10CA5000FB40DA2F453D9361BBFB859C0E7F89C669
-:10CA600090268D466EF47AB4FF02B9058EA2B3DC2F
-:10CA700014378E6BF7897508B888F993488B9C0337
-:10CA8000F45C6CB5CFCCFEB5F0C745BC5DC4B585D4
-:10CA90003F2DFC182B9CE57382ED40FF53BDC28FE8
-:10CAA000EEBB0A7E17FEB3D56F1DBA170090857BCB
-:10CAB000373C4E7FA77F9593BDCBC7F84EFCDEE990
-:10CAC0005B9C36523EE61DADE67B30741BDA88F780
-:10CAD0008A00645970EE4420A842B65E7A6800DE8F
-:10CAE000DAD97AD98B83CFD2EF96921F0C6C82BAA7
-:10CAF000535FCA00D7A1783E61F78415DE4F29E85D
-:10CB0000BC19F468B26A27EF1AE8C24935D5BBC52B
-:10CB10007C5ED0133943F5BF319EEBFFA3BE775146
-:10CB2000F8BC3B7E847A456D8C67D759E1259EC35E
-:10CB3000704DBAE838D8272E62D837EA4343598E69
-:10CB4000C10B55AB8CF7A644BD06EF977CDD7D018C
-:10CB5000DEDF7518CBD157DE7718D71F617905F660
-:10CB60001081FC5BC547EB8DFA65880E2943951B48
-:10CB7000F6378A7D01D380FBC9EC1286EFBFD5BEA4
-:10CB80003A2CF88271435967F5FAF4B37C7DD1B33E
-:10CB90001CBF64D1D90D3F6DD1D90D3FFD2C5F5F16
-:10CBA000F42CC72F597C76AF4F5B7C76E3573FCB95
-:10CBB000D7173DCBF14B969CDDF0D3969CDDF0D39F
-:10CBC000CFF2F545CF6EFCEA6807BA2BA204DE97D8
-:10CBD0000874103518A0262BFD19FCF92295609ECB
-:10CBE00006E17E4921F74BB66D6DA90717EA115D85
-:10CBF00009603C88FAF739B47E2261F58F742DC63E
-:10CC0000386BDB980979F05E95BBEBA2E3707F6F20
-:10CC1000A2CEFC71EBBF1BB64833FFFB6B9757648A
-:10CC20009ACAD3FACCEF575CD55864AA5F1E3EDF90
-:10CC3000F2EFE74D35FFBB64A19996F7206E26C64B
-:10CC40007B918524AA427CA5F06E5B159C9BD9C183
-:10CC500067BE90FEB753C17E1AFD6BF45F0AA92729
-:10CC600034347E10E0A698C6775BEACFF41EEAFE65
-:10CC7000B1F1EFA112786432CEBD736B1E26B1DF25
-:10CC800088F13981AF3B37DBD0E5FD6C2BC1771ED6
-:10CC9000AB23011BBE83CEF1763E273DB1EF48ABFF
-:10CCA000F93E7AA14EAA009F451DC406F1B5E04E9B
-:10CCB000A26A04E34248278FE8F1E9E411E2AD8279
-:10CCC00077B91E8910FC77B2045DDCE908E4C1B9CC
-:10CCD000DAF95D8C1E049D04804E52212FC8FAEEB5
-:10CCE00080155F644A94AEF591AD8519C67C54B247
-:10CCF0009BC1DD49FF8E84AFE29D667C0588A1FC67
-:10CD000015F0F5E9D7C497E20B45D37C10CF240189
-:10CD1000C8933A3866820DE011EC52D1FFAFA5CD31
-:10CD200000CEC12EF69E9AC093186F6B2B89CE331E
-:10CD3000F87F4135AA019C6BE44955907FBEA30C56
-:10CD400043C6C3F0B383789321EEBDA3CB968C6F1B
-:10CD500054EFA3782921E4BF372F4B2BA6F53D4193
-:10CD6000920CEF6CF5B4D9F0DDB29EA7A47AF3BBB8
-:10CD7000CAD1245B0EEE23C956815F3BFB6AFC4B94
-:10CD8000ECAC3E2A4379ECC661EF7EC8509F5E6BE7
-:10CD9000F97703892641FBE473581E679A667ECFB4
-:10CDA000C651619607148C7D39E5106FE1F4CEDF32
-:10CDB000498DD490C826BAEE73B8DCB1D251FA1DB1
-:10CDC0008B9198DAC67C03E5594F9B82F077707996
-:10CDD000453632BAD0E95FA0A7740B1D7954331DD4
-:10CDE00039E402CCC3157C25D623E66F1B93956CE2
-:10CDF000C775D9F13D6C87554E58D6E7866020C57A
-:10CE00009DDB4722115AEFD0197F10B91F7F774C55
-:10CE1000272433F815D6F935E553E89CBF8D7CF20D
-:10CE2000F031EF9CC6F6F999CADEB5AEEE60F4EECD
-:10CE3000D9CAE81D6E74B37C2D6D61AEE15C752FAF
-:10CE4000975356B879FAB46AA0E78BE49734C88F41
-:10CE5000B8FB3546FF6D630E3F0FE5AD7733F8073E
-:10CE60005586674A2F6A942EFDEE3BDC98173CB539
-:10CE70008CE20BF0FF92599E4CEB33C3B1C82237C2
-:10CE80008209E06AE5D74470FD96806B39856BD1E5
-:10CE900099C355D1997C4E9FC5DE593C384661FFF8
-:10CEA0003EAFCEE098AEA9287F2F924F45D368BB06
-:10CEB0006D1A9537749DB51A83B7779690E36678A7
-:10CEC0000AF922E05FC8E1EF55BD2FC0BFF3E2D6FB
-:10CED000ED2420017CFF5B033BA27B9A9037830407
-:10CEE000F096A631BA1570EE9ECDE05CA871387749
-:10CEF00071B8494402385BE9D52A9FD3BE269C7796
-:10CF00009DC3E3F159A4FCABC0795B0A7B47D931DF
-:10CF10008EC1D5E11E8C829CED0ADA715F07820A10
-:10CF2000D67795B0FAFB5356E680BEEDF277E60071
-:10CF30005DB605AFCF01F9EECAE1728668EEDCF2AC
-:10CF4000D8BD831A792BBE43DA1950103F9E407C1E
-:10CF5000F995362BECC47926D9898C7078488D07E1
-:10CF6000076799629297F98D66F8A658E0EBFA9AEE
-:10CF7000F2E1B5AF291FEE216CFD778E17EF347407
-:10CF80003B513F55DC8471F34C3ED7E685DF65BFEE
-:10CF900073BD66F8BDB610E489DBAE023C13ADBBD1
-:10CFA000A795F0F75A9CFCFD16F6AECB3678D785E0
-:10CFB00096BF03EFBA2401FDB3775DB6C0BB2EF474
-:10CFC000DB05EFBA9C0BF6B4865FF9D2427C7FF0AA
-:10CFD000B35A82F1F14D297F25F1E055D465D67F12
-:10CFE000413DD9F20E9B59CF65CCCB3395BDB3CC27
-:10CFF000EFB67954F66EDBFF0164680340008000F1
-:10D00000000000001F8B080000000000000BDD7D09
-:10D010000B7854C5D9F09C3D6737BBC966B3B9924C
-:10D0200040124E42081B0861810483829E84406343
-:10D030004D71435151A88D40314248285E1A7FF509
-:10D04000C94282841834A0585A2F2C378BB56AB441
-:10D0500051A922DD2052FAD5964551F152BFF55221
-:10D060002F40258A177C3E5BFF79DF99D93DE76425
-:10D0700013C0E2FFF8FDF1C1C99C993367E6BDBF5B
-:10D08000EFBC332184906FE8BF04CF0412F410FC8E
-:10D0900081BA433D9704EDD1FA23C3EB1C6A3A21D0
-:10D0A0005677A5E139F1F7115F22562D248390546C
-:10D0B000DE365DBED71E2E26644DCDAC24520CFD4F
-:10D0C000B450266D4F80469590D5566F968F3E4F43
-:10D0D000A85954435C84AC6A2124388A90F6163BE4
-:10D0E000962B726CDE601A2177BE2C7BE3E82B3620
-:10D0F000CDA7B969FFDE9C5B09A1CFD7B80919920A
-:10D10000479FBB9711924F88423F20D1BA5233E3D9
-:10D110002352425F98B3849049D1F9ACA9B1788386
-:10D12000A584C4253BBDF07D52ACBC13A66D6EFA40
-:10D13000DF37F4FD6FE0E782681947583BAE13BE56
-:10D14000A3EAEA04BE676C6F7E537A74AFAE7DAC1F
-:10D150009A98F63E2CF61C72CE37322DE579497539
-:10D160004E5A96A71092D5FF7B5FB69047F78E4434
-:10D170008012920E653D01782A7CCCD5C9B3ECC4EF
-:10D180001985B378BECACDE01B27D1CAE4FEE3B649
-:10D19000015CE3A2758510AD1BF0915D1AB3BF2849
-:10D1A0002906082923A4B32578F03D6BF4B9730A46
-:10D1B0007DDFD9BFFF4C55C679CF55552C9D4A9080
-:10D1C000B869BF442F7D5F0717A77666DFA73FA525
-:10D1D0006974BD2E4E37E477920278B5F37A8254A3
-:10D1E00037572D037CF9081941FB956BA4AE987D48
-:10D1F0004F13EF49502AE41D41DF79AC74D3760612
-:10D20000522869BBDDD8AE6620BC705C25FABEF63C
-:10D210008D34F0BCBFAB12F0F8CEC841DA6DDE7AC7
-:10D22000E0A77ECF558B80635F1A859BCCD71B030D
-:10D230008E6DC0DF028EB293C1B14DCADB19A6FC60
-:10D2400066D55C5E8A115291A676035FB6694EE49C
-:10D25000CBB6B4EE5025AD9F28B57861A8C49195A2
-:10D26000C88F6D43F71D5E08709DB9FFC36D08350B
-:10D270002D5425E04BDB133DD5A12A9DBC11F88A26
-:10D28000E7BF778C7D20BC9296A917CF236E4A2AE0
-:10D29000CE21362253BC384656D9EB9C51FCD8E0FF
-:10D2A00017FA3C3E6DC64732E5FB78AF0E8FF0EFC4
-:10D2B0001B564778D0C5DBB26FFDB904449119E91C
-:10D2C0007700E6A3A8BEE8FCC8D9C717C94E43BE7D
-:10D2D000278A3713E4657F7AF733BEE7FD06E60B4E
-:10D2E000D66FBA5C93791585CB9A17987C241E2645
-:10D2F000176C7686CF354463EDD98A97BE41D664E4
-:10D30000AE44F9D1AECE6F07F9F979A685C8123CC3
-:10D310005F6F07F9A198E447BACF62D00743E6C42C
-:10D320001BE4FE9A825928CF069A67569DF1FD614B
-:10D33000F5C6F77396A518EAE23D6BE6452F55A5AD
-:10D3400046EBAB943A3BC8915B33D74B753AFA1E28
-:10D350005254F73AD0ABA8DB3267E27B7139A53182
-:10D36000E7B5CFA3BD0572A25D65F326EED870BE0A
-:10D370008BEBA1BBB91E3AD53A37F2FEBFE6FDEF03
-:10D380006D716319C167C13506BCACCEA2F29A8E2D
-:10D3900007B0D77FFF29B5EE73985F14CF96287C2E
-:10D3A00080698B175B805FC5386D59F90EC0DBFA59
-:10D3B000EAC1E727F4AAE867557CC44BDFB312A3A0
-:10D3C0001CB7A5590CF89890C7E5C6B66B0CDFDD05
-:10D3D0009B3C63631EA5ABF587648274F73BE3FA5D
-:10D3E000FAD3AB711DEB33D9FA07A66FD3BAA944B0
-:10D3F00088D011D6534CF5A1A6FEF9A6F6D1A6F613
-:10D4000009A6FAB9A6FE95A6FA0F4DFD6799EA5747
-:10D4100098FACF37B52F36B52F37D5FF8FB17F2983
-:10D42000C3F3F5E2D920F205F4BAB9BFA268885F68
-:10D43000A1E7237CE536F2E30F722AB43C66671855
-:10D44000F02BE8F374F1B39ACAB810F093A23A50F3
-:10D4500099962F267A7A589F998FFAA38D4E0BF5BD
-:10D4600037B75F52041D5773FB70CE12031DF5E6EC
-:10D47000143AC07E24CE34944BA7A20B89A418DBA7
-:10D48000B5A1D1F67CF8FFD9A58B53D37180EBDD24
-:10D49000C1E72DE4C023C37DD7223E02D49E1E1BCC
-:10D4A00085931AB1A7E9C728DF6D49238138AAEF10
-:10D4B000B6F82D58FF3C937E08EC952AC687237852
-:10D4C0007F42C2128C23E6D3CEE9651DC8295ADEFD
-:10D4D00001728A96B7B56462B97AAD256B218C5713
-:10D4E00063433CA58EBBD5AF4059595E04FAFBB6E9
-:10D4F000B13B340BAD279E94497022B5174AAE2834
-:10D5000087E5244C9F9FB9173EF735FDCE24E04EAA
-:10D510008246C6E62A12B08E2364ED9EAC1F7AE8DE
-:10D52000B86A81E275405BB177859286FDFCE03692
-:10D53000A84ADFFE11B43EBCC082F685B5BCAF057B
-:10D54000EC7731EFB53FA4844B3BE6557B2D7E0A4B
-:10D550008215C3EB7E05701ADE492C1AADAB7E55E1
-:10D5600002B9F6469E8AF276EB1F28438E800FF5AD
-:10D5700065819EFD62AD6D25CC73603C11D952FE74
-:10D58000ED4B310EDA9943F1B906F4AC2A484274F6
-:10D59000951F76C13C9D32AB3F9777CCB7B2385AD6
-:10D5A0007F2CEF987B256DEF9C986B8175E4A5B976
-:10D5B000B4400CBA3A0CF218D6B776D170BD1E340E
-:10D5C000976A0D1D77082D8B7909B4760EC09F9749
-:10D5D0002A7F9EC9EA0738DCD466DE9EC6CAB3FD40
-:10D5E0001DF3F8AFE5B9855D3A94FB8FC5CE8C414C
-:10D5F000EDD3C37965FDED532AE886029D6FB27ABB
-:10D60000875AE8D89BD6DA889FF2D4A61C827EA2DD
-:10D610007F8D2DB01DF84351875EAAB3BB026B32DC
-:10D62000AED0E8FB0189CCD1CBC97B399CEFCA973E
-:10D63000707ED3E5637E99D2EF263F413B6B137139
-:10D640003BC01E89E0DBFFB90FE990E3BB2ABF6A4C
-:10D650001DD02959C8F4667E549EAD50E8389B61B0
-:10D660001C5ADFDC6EC1F96DDA45F9977EEAF39B4F
-:10D67000DFB180DD3C96042DB0BE312480A5872C1F
-:10D68000B30050BAB91EDFC6F9B790F237FA3B20A3
-:10D69000FA68FBA5C3EBBE06BE48222AD655BF1BBF
-:10D6A000E9A9715772652CFBC0966FE17E26A957D8
-:10D6B00026713F87C1D9965FD61FFE56B20CE17E18
-:10D6C00093C767CF07FF6EE7C1E030DAF4C4AB461B
-:10D6D000BA05A8CCD2C99D1CFE9D24AF4F93E93852
-:10D6E0007B72EB92E1FDC6FA4FF665C0D07E3FBE7D
-:10D6F0003F39DF8DFDAE08764F8761C679C395400F
-:10D700000B63AB7BF700C98CD136839B413CE53F73
-:10D71000DF93AAC23CEA86C23885A17005908FB318
-:10D72000FE603003E773BE05E86204CC87D3472D63
-:10D73000D2978A7422F00DF4504BEB573430F850E6
-:10D740008310DB89E236CC7FCB2A4A27CEFE749247
-:10D750009ACFEC236F148EC43AB87FE5CD8F41BFCA
-:10D76000022EB37ABC560817F87EE75E053ED0CC91
-:10D7700040DF5E077DDE9E5B770EACB374A3AF1512
-:10D78000E8CFB92BE4877E024ECE29214DC27EDA46
-:10D79000B9D06FD3CD9595A817BA08FA4B427F9AA6
-:10D7A000F16F9D62B4F708E9C2F58CEC32DAE994C6
-:10D7B0008E519FF7A3E39B23741CAF8F4B08FD137F
-:10D7C000E8B4C47BC0CFA0FE078E35801C7980EB07
-:10D7D0002541D7E27901891D67B8323FE2CF66CA99
-:10D7E00083C3FBCAFC18FEAC0BF86304F2CB7CC00D
-:10D7F000879BF461FBF09B8DFCD2B8F3937DC3E86B
-:10D80000FC9DA5EA04C08FF87E03C737A5E3C54891
-:10D81000C71BFBF6815E1B7E33A3E36BC1D6488F2B
-:10D82000D2E34D1E6D297C47D099793D4BF87ADAC9
-:10D83000737DD7C278576CEC7EDE81EFF9AE473E40
-:10D84000DB180A3A4814BEC3397CE36E89E0D90D6F
-:10D85000F263568DF779D0CF3E8F7B3A9433D5BEA5
-:10D8600036302DE6D6CB06BBCF8C5F4A5FAD485F26
-:10D87000C4374D92C09AEDB6A2FE1C806EA27AD338
-:10D880002FE8FEE653C8ED3B62E1E174C73F99EB38
-:10D89000BB1BDE4FA9F611E4D3D39DD769F61371F4
-:10D8A000B3A81D1BB0EBED5841F71DEDB3D04F16DB
-:10D8B0007810CF57B5CFAACE033A772ADE58FE4F5D
-:10D8C00044DF703ABF9FD3F97A6E7F7571FBEBF638
-:10D8D0001615E57B678B07CB8E162F8F879663B95E
-:10D8E000AA45C37EF29A4F2BD07FBF99605C6B65CF
-:10D8F0004289148BAEF2FC467B7F78B311EFA9D539
-:10D9000046FF3B596F2FD37F49E5F986F644EF6810
-:10D9100043FB69C48B0F00DDDBD22A0DFD48F813F1
-:10D92000837D2BE0385D9E87F1620A4FB4AB853D65
-:10D930002BDA09A9C378AED5E467769AECD80E80C5
-:10D9400023C297C1B10BE088F02DE7F0AC667E13DF
-:10D95000F77BE285DF53B47ECE7C8C8B1094572B03
-:10D96000726CA89F3BF298BDDD8F7E3275F293F208
-:10D97000FCEA354C9F0B7BFCF99C57AAC1AEDD92AB
-:10D98000694139B9256D8F672BD6E3BD4C9FFABB32
-:10D990003C147F560F8F57538ACDA2EB4DE47CB3D6
-:10D9A000DA4A30FEDD91EEF4421C2CD1B3A806FB1E
-:10D9B00099BE4BC8CF89DEFF23EFD51BEC0EA25CCE
-:10D9C00063586764FEA536368E44241827A5D866AA
-:10D9D000C09F9DE8EA79305F5B148F79B05E8E2737
-:10D9E000939D23E214663CB96B8CFA6675117BBF7C
-:10D9F00037E701C4BB19BEAE2A23FD7670BA684B67
-:10DA0000DF827C68EE6F1E9F4C8937F87F1D9EC1B8
-:10DA1000E324C29F16FDC08F76C7E86FF6A3CF86BA
-:10DA2000BFEEC6EF19F55D0C7F7DD2085D3C49C0A5
-:10DA30003B8207115FE47E98885B8BF114C2C6C3FA
-:10DA40003AC6B7FD28FF7E99E0423FB2C0690B801D
-:10DA50002C2CA0F3003A6EFB55426025ADAF4B98DD
-:10DA6000D99744EB05DB6415DB9DBEA11067EEDDA5
-:10DA7000306368987EF71EA9EEA211BA38DCB6E4CE
-:10DA80001B32993DA0BC13F600934BE8E7FAD74D43
-:10DA90000C69608F1711EF76025E306B17F444F457
-:10DAA00075B97FFDB3114CEF66CE25CBBA63E07F2D
-:10DAB0000D6F8FCA715F3CCA6B2EC70B38BCB6772F
-:10DAC000CD8AD7CB71DDF3A4587475B6E4771BC843
-:10DAD000EF51F09D1735D4DBA584CBEF47C8F75144
-:10DAE0007E2FCBAB5B3DA22CC67E9F1246F93D51EB
-:10DAF000D5DA01EFE9E0EF015E7E4AF112631DCF56
-:10DB00008E60F6CDF7152F42AF6EEF7A9CE1A558E7
-:10DB1000E0E57612CBFFFD1EE0E569807B3FBD4A64
-:10DB2000C2B80FFB45B6F60CB43FA56ABB007F1127
-:10DB3000FC5C169B6FFEF91DE3E77EEEB7AEE7F8DF
-:10DB4000E9E2F1F1DB397E3AB9BEEEE0F869E7FAD5
-:10DB5000FA56C04FDC99F3CDF066237E52ABE34D0D
-:10DB6000F830E227A9DC889F44AF113F099ED126F7
-:10DB70007C18F1935EA022FCE2328D78EAC737A7C9
-:10DB8000F057D2609C187672765DA802F6B886CE01
-:10DB9000E9EEB5C220BEAE0A28C57AEF35F9A5A2D6
-:10DBA0004C2F6078CD9C161BEF16DE1EC8D7A40242
-:10DBB0003D9DFC20361FDB79FF63AA1667E87F5185
-:10DBC000ECFE2EDEFFF5E15AA2BE3FFDB94B1EC4AE
-:10DBD0005F30AF3F41D2D20B701DEACE30C5FDB6EB
-:10DBE000156C1F729B43ED86FD7CFF0AA777BB8AED
-:10DBF00023F9ECE01FF171883F09C7CDE59F19EECD
-:10DC0000DCFF15ECFBE52DC81E7A356DCF5B9E79E8
-:10DC1000A48E96A30B46E03CF3EBBD7B00CEB26B2B
-:10DC2000CE50B67F3CCFFDFE184A6AC154E91B7046
-:10DC3000B8DDB1F7ED4529F42995836807D2890449
-:10DC4000B6533A8D5388929802EBD5705D56B06307
-:10DC500065586F17D6E34937964E1262FBD7DC1F23
-:10DC60003DAF200FC7731337FAAB29C48BA5E06310
-:10DC70007B1A51D227E0F86D7113082AFCF3C05FBC
-:10DC800075666FEE009F46A3509884AC82F090EECC
-:10DC9000DA87EB271EA2B278DBCD6ECC4FF8335D6E
-:10DCA000DF98D35FDFE9F6FBD2E12A21498434DB38
-:10DCB00059F98B78D71628BF74E4062068A58DA87B
-:10DCC000FB31E0D55F49D0FEF0BF951068C5C92E85
-:10DCD0003B87F907A73DCEBCB334CECFCED2388D2B
-:10DCE00005E9A71EE736F87532EC63FA9643FFB6EE
-:10DCF000E44968778AD20CD77D1EED06989F627F33
-:10DD000029F7BDD4A8DDE67C5342BBAD4D0A12888D
-:10DD100053FADF96D0BE22C50C4F4E9578F2C64519
-:10DD2000C7717A970D67F12E16EF59F1F75F8C02E4
-:10DD3000FBFB970933C349F4FDAD07A99D0779346F
-:10DD4000D3BCAFD7537A4A4FB579B750FA49E57E7D
-:10DD500072DCDA4907EAE9AF9F8C62FCBDA365BFBC
-:10DD6000BB8D0AA444C57BE104FA9E93EFDF12B990
-:10DD7000260C7663E22445853D8E2239580DF32525
-:10DD80004D16027C714F83713FB7B3B008E122EAB0
-:10DD9000C3F87E2E2955FA227936D48EDF58C0F387
-:10DDA0006A5CC40576A1F26F2D2956DE8328C5FC76
-:10DDB0004AD3A8DE4A82B820E5145A96760631F98D
-:10DDC000A3D21BB4831DBB2140FC360AA707E7FB87
-:10DDD000AE81F13ACB7D0960976F3834EBA2B17414
-:10DDE000DEA1B0E205100447A5E0BA439ABC368133
-:10DDF0003EDFF9A6C50DEBDBCADFEFF449C8FFF73C
-:10DE0000CC23013F85C7D6863D7619ECDE90858C04
-:10DE1000443B973A5C93B82854215ECBF8FE965168
-:10DE2000E9F8B027B43C19E0B22EE1FC9046C7AF48
-:10DE3000AD6671E71972F6F3306EA8D386F849E73C
-:10DE4000F94712A945FB39659ECE5EA6FF123B99A4
-:10DE50005F19BA8E60DE535299D3EBA7DF7B22CCD9
-:10DE6000F68DEEA96671671709E2F767C8BB1C1645
-:10DE7000FABCA75A71033D2599EC73278C4749AE2C
-:10DE800067231BCF359E8D9768CA83B28B79B9E91A
-:10DE9000BC28FEE44405F1ECAE36E64FB94CEF3950
-:10DEA0004DDF7B59E0399B14029E4FF86E98F812B3
-:10DEB000B67AD558F9139D2D2454A5CBB7700E1002
-:10DEC0003FFCB290F909B6ACBD7698D709DF2B6953
-:10DED00010EE7AE15FFBDEBB03CA7FFF574F135D95
-:10DEE000D75FBF3ABCED518063F36D2F221D72BF27
-:10DEF0006A084C81CEE7F95A1BC2B14C63F101525A
-:10DF0000DABBD75A8AEDB8AFB5768F03DB87959326
-:10DF10008083C27398A265FD0CF835247B57A83026
-:10DF200088E6CC9A44D85615ADAFBD92120E950F27
-:10DF3000E9F334D95F0CF190174822C5F7064D522A
-:10DF400059FE9BF43CF0534E95847E58CE219F039E
-:10DF5000E8E1C46C0BE6BFACA8BDF4C29174FCFB55
-:10DF60002A148C375457555C0EEDC30E317A715D0F
-:10DF7000C7F047E114ACA2FC30E2108B279492B0BA
-:10DF80003748DB877989350DF4C73C0A60985F27ED
-:10DF9000C70F8F0F949686FC00D444AF118F6E1379
-:10DFA0001ECD78758DA47804FD52448A985FC7EC25
-:10DFB000C75ADE6743D544F45FEF5189DF3AAE3F7D
-:10DFC000BE5EA4F6A346EDBF10B51FA1FC1BB51F96
-:10DFD000A1ECA1F62394895AC545A574BEA1743A53
-:10DFE0002EF05F4DD94AD81FB86FEAD537FD93960A
-:10DFF000657C9F8D726A4A25FDCE2CE062565FAF2C
-:10E00000519BE4A552D9505F9BA6887D3C3FE8D444
-:10E01000C42C0BDFE79971A746EB9D990ADFD76304
-:10E02000F511C5C450EFA9B118EAE7EDD18D3F0550
-:10E03000F01387F5092377AEF71744DBEF28A475B3
-:10E04000DA7E80DB73B54B2DBE2D31E877D948469B
-:10E05000BFCABF895FA2F8FAAC80A09F2E5B349440
-:10E06000DFA4505141BEF6D7CB540EEAFDEB022A95
-:10E070005775F191C3853CAEEEAB60713612FDF978
-:10E080007A12CFB322F0BC330476C4ADAF5EE90D93
-:10E090009281E5AE355339A2A7938B051D8C2423BD
-:10E0A000D19F27530E54009D754D54801E4A391F31
-:10E0B000106EC761889FD2CF539FDEFD174D053F7D
-:10E0C000ADDDDD3612F37E2E1FA9CB935995BE68C8
-:10E0D00022E83391F7434895FB7DBA2EC97FA90505
-:10E0E000ECB681ED1485BCAF83476FED8C24D00373
-:10E0F0004E2EC7CDFD57B5EC7C05BEBFBAA51B4B58
-:10E10000679A0F858C5DF163FC669FA7AE11E6658B
-:10E11000CFA6ED3A396C4BA3EF19FC806C667709FA
-:10E120003CB809C683C4BEC986CE09F17114189DD6
-:10E13000545F807CDE109A8579159DDE0983C6AF19
-:10E140004EC5275BAB5E2269148E4FBE3AF32FB3E8
-:10E15000697910F88DEAC12738DFE4943FF6DAB523
-:10E16000067E396AE297A3267E397A0A7EB9E04EA6
-:10E1700068EFC9540CF51CE0175D7D6B845F583D5A
-:10E18000CA2F47915FEE79D986F58D238F1AF865EE
-:10E190004521AD67EBF865BAECDB12C30E78E53BC1
-:10E1A000E2975F9F29BFBC7166FCF2C4D9E3973F39
-:10E1B0008E4CFFEEF8C5779AFCE2EBCF2F87605EBE
-:10E1C00067CA2F9DEE20E60376CEB6540762E0FBC9
-:10E1D0007A8E6F11F72EE3718A69F3B4CBC7823D53
-:10E1E000CBF3D6443E4DE73CA6BF57D4CE407DB9D5
-:10E1F000F520D397423F97713CFE8DC731CA424C00
-:10E200006FA6974BF8FE4C4D0AA8F4D74E6A12A49D
-:10E2100082BE9E22912E1596BAAC76A414B59BE8C8
-:10E22000F7D06EBACFCBF266C92166EFD8E97F404E
-:10E230004F17975B0D7A7588D9FE32D5C53EA6D8A3
-:10E24000BFBC0FF212283CBE1EC9ED2693BE15704E
-:10E25000D870A812ED90CFB36D83EE5775F2F546E6
-:10E26000ECA9525F45AC78587DA184F0BEC9A3C526
-:10E270001796813EBE0AF5AED0E766BDDC53F59237
-:10E2800051CEF8C7A75616EBE48C7F3CEACD889CAC
-:10E29000E1F501E50C3907E546442FF37A442FF305
-:10E2A0007A442FF37A44CEC0F8D951BD3CF281F1C3
-:10E2B00077FA757A7B19D4B34FAD9717707970B62A
-:10E2C000E5CC1FB8BDFA5DE9E5CA424E2FFFB99C07
-:10E2D000A929FC0EE54C2DC899A453CB995A90332B
-:10E2E000C506397355E1B7D0CB890DBD7ED8BFBF08
-:10E2F0006200BA77707C371568D7C0F8A4E6F4F2EC
-:10E30000B6CD74D55BFBC0AA0CA0172FF3F3067A29
-:10E310003FB1F9F7AFB4E9F2A21395103B5FD1FC1E
-:10E32000243E9FDB7010E365A79A6F7D21C1D2ACBC
-:10E33000477B6BF7D9916EBD16DC13FFB6F3E89CF3
-:10E34000CDF8F28DED4FAF073EBA8FC7FDCC76AE5C
-:10E35000C0EBE9DA3FE6EF5E3F52C571CDDF3F1516
-:10E36000DD523ADD0C747A22FBBA31E0E7C98977D5
-:10E370002500BCBE07FAF0C96F43A7AF8C64F83C18
-:10E380008D750761FCEF6ADDFF017FBEFC6DD6BDB8
-:10E39000A090D1D569ACFBBFBF4B7CFF07FEC26725
-:10E3A000DF66DDCB04BE093B2FE3865F289FACFF11
-:10E3B00057E1DB10BF58FFEFD18FC13ABBBEB26F40
-:10E3C00086F805F9FA1BD9AD3F3F45D8B99944FE07
-:10E3D0005EA28F9D877157EBCE4791E879295C0F3C
-:10E3E000C63722ED07629D97FBAE4BB047DEB10EFC
-:10E3F000D26E63713BF3F3FF2E90D83936A9D60164
-:10E4000079F1BDB3F760BE41E7EC09B86F65B6536B
-:10E41000C47B3D2D1AC6933A5B7C58DEDE521D82CA
-:10E42000B8C9932FBD25413E58E94B0DA8DFD64E04
-:10E43000FAE130CCE39B5A1A0FF5DB4D768A8BDB81
-:10E4400029DE51AFDFA9F75F9EFC4D13CA4111874A
-:10E45000BA2362BFD0F7549D9F44EB400E113F0991
-:10E46000EA063F69D97AB05F7AC07EA1FDA78E5ACD
-:10E47000B63ED677D65A483DD82F6B1B2CD5B1EC7B
-:10E480009770416CFB85D671DFCD91680FACCC03E2
-:10E490007B86D4E9E36AA7B25F1E1EF5DDFA495711
-:10E4A0008C3A3B7E52846FB9DD32A4485B0821D997
-:10E4B000B32527869DA69C18D65F4EDC38EA5BF80C
-:10E4C00049E102965F2DE86BABEAC578726735C10A
-:10E4D000F8636768656A09AD3FD1602112AD5FFFDF
-:10E4E000328B0B6F2827013847BB219B603DE465C9
-:10E4F00074304376FE08E2E03D55D47F52216EF73A
-:10E50000E35A80EDBA8499B73928BDD4962B04FC20
-:10E51000A619F214FC4E4863F9A1B54EF2A338F0E7
-:10E52000ABA62A64E519C4AD13E562897224E54FF0
-:10E530003519F876A078B439FE4CE417BC802F73F7
-:10E540001CFA4CE3CFDB055D7DFBF833F2DF970F60
-:10E5500034CD8278EEA9E871C12815F599594F9903
-:10E56000F958D0D340F4E7043B69A2AECECFE186A0
-:10E57000F93EB513ECA48951BAE8AD9D94142BFF74
-:10E580004A9409CD7F78457F1E2F41E9C6F1129A42
-:10E5900077E1F3BB206F00D6A778519E3E5849E53E
-:10E5A000708CF9ED6E597608E4E7AE96662C2F5024
-:10E5B000FAE414DAFFE916FF2180DBCE96762C9F71
-:10E5C0006CE9C2F69E968D58DED112C0726DCB0EEC
-:10E5D0002C6F6BE9C6F2C17CF69D294A10C7B9E0E1
-:10E5E000241D5F474753FBE87774F83EEF43BFA114
-:10E5F0007D72B8DDD07ECEE12E43BD2CB4D1D0DF0C
-:10E600003D2560686F2AA83B067CE92ADD6178EE2B
-:10E610002CEE36BC77BA7EC1D9EE976B7F04B6C9B3
-:10E6200049329CBBA0AFC8706E88F2F190662A5E3A
-:10E6300069FDFE441EE7E866FBE49924F283740951
-:10E64000A964601FF426B23CC8D62CF67EEB8DACD4
-:10E650007E7F0EDB3F12799AB23D42D744CA88EEE4
-:10E66000E7DF9FC8CF2915B0BCC8DCE200442448CE
-:10E670002E24A8C17E4829DB2713FBDEAD3CEE70BB
-:10E68000BF95EC94A83DD9AAB0F9B76A24B082F638
-:10E690006B2D66F57BAA48C002F3D7A814CFD0ED46
-:10E6A0007337EFFB4A2A89EE9793D11AEED7C87CCD
-:10E6B0009F3DB2EFED7897E0BE3E87D7CA848F3199
-:10E6C0008F36B9B94F02FE1AD2DCD70BF3BBFF1657
-:10E6D0009B1ACB1FEABDE58B2CE09B4D377E910545
-:10E6E000CCBE29923FD3E7D0E7CFE472B86C6ACEB4
-:10E6F000C7FC854DF52E2F87B3C5D48EF90C9FD757
-:10E70000F3FB0988827ED1307714AE01913F22431A
-:10E71000DE1D5DFF88E8F9D3FF34BF6653F37296C0
-:10E720005F934D787ECD4CF427051E364139AEFF00
-:10E73000B9DEEF3ABFE6947935A63C0703FD42DD2A
-:10E740006FA66F15F112C7E95BBA99E5456499E8C0
-:10E7500046E45D08BA14F919225F43E46FD8785E85
-:10E7600007FD2CCF6B8E4D5FB63DC403E7DE644BD7
-:10E77000BC774BDEA9F3089A3DF95C392C1BC7C660
-:10E7800065F903FF334AFB85A72C3A6E9E47BB51C0
-:10E790005F17E556F875321DC21BAE027BB5A85C4B
-:10E7A0006B85F37C29A504CFE994964B58161D621E
-:10E7B000F5DB3C327EAFCDC3E24DA27EB1A63D0774
-:10E7C000EF2799DEBB38F29E15FBFDDE63E1A5C2A3
-:10E7D000E6CDF3906772FA5E3D5966F9D155129312
-:10E7E0001BB0A13A89EB430ABF8B89FB92025DDC27
-:10E7F000F5C71C5BB7B7B0FC3E910FFDB79765CC72
-:10E80000877696FBA6C1D9B3B2502808FBEBA5DBEF
-:10E81000883B4585F98535E0C7153977EF817C88D8
-:10E82000272E647BB6171F62F6C28FCBAFC6FB469E
-:10E830005C5FCB188F754F49F406E0433556A6FF51
-:10E84000453E74B9D15EA835D90B179FE2FE8F14EF
-:10E85000D2E7073DF988C7148FE5F7800C24BFA3E2
-:10E86000F78030F950CAC77496BB1D10BF2E3A64AA
-:10E87000C1E39EF2364DC6F3B19D2CCFE389906F74
-:10E88000D0F3A82F723886B89CF81BCF93ECE172B6
-:10E89000E2752E270E839CA0E52B3C4FF210CF9300
-:10E8A000349F97D8D152FD92DEDE319745927F1684
-:10E8B000E6416D56089EBF1BE0BE8FA2001DC790AB
-:10E8C000C7B802E9676FF2DD15401CEB350BDA952E
-:10E8D0005D5348562CFFAEEBC2CA41F30F3B5BE6DB
-:10E8E000BCD43688DFE8B4517F26D6FB1E71AEABB0
-:10E8F0000BCF5BA4955B08E45565D9FBD8FE43AF0D
-:10E9000003E97988D78EFBFB649E93BCABCB53B9EC
-:10E91000DDD7350BE6FFE03605CFE7887113BD7410
-:10E920003E3A3A499BB22713E6DF39359809F64C4F
-:10E93000D7F87D1B0B205FE4A04C800CCCF3B21603
-:10E94000717F96AF2B4DD1A45879EA03ADEB038FBD
-:10E9500064B867C20CFF01ED0EC80818FCBC95B383
-:10E960002846FEE269CC13EDDB6F765C3B1BCF4D96
-:10E970009EE6FD17099C0EB3161207FADD408F8341
-:10E98000E0D9650D21DED62EB454C73A5F5B54C47E
-:10E99000F0BDB6F453B48B4971EC7924959BE9959D
-:10E9A000CDE70E858E4FDFEB2A8D3DFEE51C6F9483
-:10E9B000AE5F0379D5556D41BB22092E62C0FC1CA8
-:10E9C0006A074948EF28973E2BB5313BC1242FFAFF
-:10E9D0007DBF54474FF9FDE5D0F9454E437CFF44D8
-:10E9E000F6ECA4600C3C8B52C051C8A1FE70247898
-:10E9F000FEB58BC39114C7E6EB28BE56887855DD6B
-:10EA000029CEEBCD2E2A8B714E6C003C98E9E18E1D
-:10EA1000853E5C1779EE35A282BE2CA5FCA88B43FF
-:10EA20000C043F33BC167EC7F032B7FFA888C74737
-:10EA30004E739DA7DD8FDA456E9D5D0C87A2155A3A
-:10EA40009FCAEB3FF64BE17BA85C9576FD09ED9EF6
-:10EA5000A9BCFC3194543FEE9282EFBE415F9E22EE
-:10EA6000A93980B4594F8F820819B9555A66B07FB9
-:10EA70003A24EFE167302ED4970AFDA6933A852118
-:10EA80003980EBFA93146E05857529D15641D94822
-:10EA9000BA6CF05E63CF9F0EC3771A7B1C4119825C
-:10EAA000933BADC7F471A36BF4E747F2E0168D6EAC
-:10EAB0005B1E9DCF921DC67DD20612C2F196761BBB
-:10EAC0009F9BCF8F4832050C5C4E10C97F9D82F909
-:10EAD000BDC4C1DAE3478BF3E87D85FAFBCCEA39A4
-:10EAE000BCEAEDCE20DC2F4402C6798A7B739EA758
-:10EAF00072CC3E01CFC33C0C74FC91DBEEB7507B73
-:10EB00003923A5AE11E07115516DAC647683589729
-:10EB1000B887668173B60DE0BBA0DDBC0ECD06F3F1
-:10EB2000F959D7E0EB1378FF4711C175DC5EA46299
-:10EB3000B934BE66BF06CDA5A15CFD7D104D5C3F1E
-:10EB40009065A906FE7D51D023D1E4D3597F7FB8CB
-:10EB500016609C4CC075603A35C6C976C121D77421
-:10EB600084DFCB7AF811A5AE04C615EBF96759E836
-:10EB70008120ECAB26B27BA0DE4DA97B03FAE71C1B
-:10EB80000EBF2FD1A913A75A08EBFC78E747AFC8EF
-:10EB9000F9D1F51112BE1BF2A3EB77CAEE0E58CFD6
-:10EBA000CEE70E03BD0FB42E911F4BE901E146E7FE
-:10EBB000F521E837F3BC8EDE407E0A76C974B9D8F9
-:10EBC00010477986C3F19E62DFC7F05EE94BD92E0C
-:10EBD000BC7F27BF7BDF503A8FBEEB25CCAB4D937C
-:10EBE0004915C04FE4237CEA54D0CF4E4BF0CB2ED6
-:10EBF0005AEFBB8A78B7C034BCCBBC402A724EB146
-:10EC0000B783D24DC6F5B20FE4C9DFAF5B90BC80CD
-:10EC10009619890B9347D0F28238E277D0F13224EB
-:10EC20008BAF1B8350F3932FA1F3FC491C9D27ADA1
-:10EC3000E7DD90101C41F9ED8F3662077A4D4BA845
-:10EC40005B371DBE932CE37C8E503B51A172ACE22E
-:10EC5000F2CF26DAE9F7867EED9C00F3C96A9E467C
-:10EC6000DEA5A03C5CC4F8E4E8C35F4E8473E0F228
-:10EC7000374E2F9E33E7F4973682C1C38CEFDD1CED
-:10EC80001E6FC6337FA731DD762BC4DB3FE6FE0F58
-:10EC9000D13CE82F5CC7FD8537E3991FF466A18856
-:10ECA0002F05D3F5F66DA3434BBA0C9C076A274199
-:10ECB000BEF3676E2D2919FA111FF2ED75DC6FFE98
-:10ECC00098906AA0F3EBD64C1B9242DF4F6F6570B1
-:10ECD00030CF6FEC68A69F1B4E5282D6C5CF1A94D8
-:10ECE000A00DE477C3499BE1F9DFA91DEDD79D573E
-:10ECF000FFC98787A6C3FCAE24E155D0FFCAEB123B
-:10ED000058E09EF36B0F9FC74070694C568842E1F4
-:10ED1000D12811DF60FD9EF9B71C13BEB34733FB4A
-:10ED2000257D5AECF55DC4D7376D75CD2F81CE1A90
-:10ED30004356B4E5AFFB43C590C1ECE7C693E791FA
-:10ED4000802EFED7A884111E8D27CFC7E7D3561F6C
-:10ED5000B301DDC3382A7D7E9D431B02F1DA81E0D9
-:10ED6000BC9BDB418D2793893F55FF9CF17774FC59
-:10ED7000346CFF2D87DB6FF75BAA63E577358F6611
-:10ED800070199DAEF8201F684C90689B637C57F407
-:10ED9000CB4831EE5F98E7D55319BE12E67D4E158C
-:10EDA000D1627D6F3187A3986F4F4A78910FE9B395
-:10EDB000AF10EE9988D4DD7DB9FA7B24B672FCF5EC
-:10EDC000FC309C0BE37F7C61EC733B02CF9394653A
-:10EDD000682FBF9052F734C8B77997D10AA58F2111
-:10EDE000F38216763EC53F28BEA370964960E26066
-:10EDF00070B661BB18EFA317393F523F1CF2D4AF76
-:10EE0000E2F2FFAA6D4B30EF49C8A98F36CA28A796
-:10EE10003E42DD42CB8084F6EBFC3A0A6B2A571661
-:10EE20006D9FB60FD4C15599D4064D61CF6F86B290
-:10EE3000CD6A88F78BEF2D38CCECB7859D463D57D2
-:10EE40004F3A3F01FBE0A317993CA0FC6D0379BC4E
-:10EE5000E82EE338F5DB2EFA00E6576FF2CB33B835
-:10EE60007E36DB799B47F3F8FE2432E94CFCF24610
-:10EE7000A2ED188D7AC127C33CCA14E33D5BA24CB6
-:10EE80002F61F05FBEFD84CDA50E3CEE112A470A2E
-:10EE9000E8B8C7A83F0EE51F476BBF1F4DF170FCD8
-:10EEA0002083CB81D1754FC1F78E1F64EBFFB4E196
-:10EEB000D345704F0C99C3EC8638387C407F8D9BCE
-:10EEC0006B0FB4D2F5AEA662CA01E782E2983D228A
-:10EED000EC3059BE5676D1F6C9FF58980CEB4C7BF6
-:10EEE000E807D5305EFA43091AC0ADA3421B0FF202
-:10EEF000BEA3D6E985F32A9B291996D3F7ED741C96
-:10EF0000D02781DF4EDE03DB9105DDEB2AE1DE1742
-:10EF1000F7AEDEE030BAAE760BBB27A3FD7CE26D28
-:10EF200025D1EF35EDAA7D0CE6953B9BEA0709CE8E
-:10EF3000D16BE3DDBAF109B7AF1A394E8E3F3BEA28
-:10EF40008EF3E05CC27E19CDC74F1BF2D1AF1F4DCF
-:10EF5000183D89FC7BF836D891027EC7A8BE22BA3C
-:10EF60003CB5D1DD52D04AD7B5B4E731BC8FA361EF
-:10EF70006530632EE8DB0715A647F9FCD2FE9855ED
-:10EF8000A9BAA2FA77AEE4463B52D8C99713F15317
-:10EF90008CF1C2399C0F2EE7F6F1DC0406E7F9C4C8
-:10EFA0009B0BEF5D61272E0B85D9DC69DD65CB40BE
-:10EFB000EF2EB126837D036B898577519AED20C1B1
-:10EFC000878D0F24FA21EEFAB1D45708831CB13291
-:10EFD0003EEB7B362EB025AFFF38D631CCAF6F2C51
-:10EFE000E4765D01D1E0FC40E3EE51781E2C2E9ECC
-:10EFF000E27102CA3F3BE0F579D0FF74DDD73CE314
-:10F0000008E2B930715F999BF813E9779A760FD9C6
-:10F01000027646DA086DFC723ADEC7D6702ECA0B4D
-:10F020002ADF24AA5B73C7ACB944A17CD53894DA33
-:10F030005DB47ED14377B37A7E789185D6AF7DE893
-:10F04000D14B144A9F8DA3C3EF43FD96879E66F56F
-:10F0500009E14532AD6F7C683FEB0F7BD894B0B6C9
-:10F060003F74E012F0FF8F2433FB8178C35702FD19
-:10F07000343E3DCAD2A15BEFBA314C3E1E71B07E28
-:10F0800047F2C84F6701BC3DE1C259BA7DB9EBC731
-:10F09000083B96D971629DE23D92197BFCB1639861
-:10F0A0001EBD661AEB7741026977B0F3757EB0C773
-:10F0B000F6EE1A8570491993C2E145C7298D8E2352
-:10F0C000E028C613DF5D0C7A1DE4BE95CA7D9D9CC9
-:10F0D0003997E38D7EA70DBF53AC8D877BAC1A6744
-:10F0E000658F07BC517C291C5F8A1D2F57DBCCE63E
-:10F0F00047C74D2E413D3311E2CA7BBFA6FDF3A2A7
-:10F10000F336D3C78C314C1E5DD3CACEF7F7258FAB
-:10F11000403ABA2081D98BA494C28FCAB38D1C6E99
-:10F12000EBC624333F32828721128EDFCAE197CDAE
-:10F13000FA9FE97AE7F0799CEDF5EAF0A4417C6565
-:10F14000EFCE22C4D3C6081DAC338C736485E9BDF1
-:10F1500072CA78308F9411F8DE6A07B1E373B22572
-:10F16000F25E1E7DEF82697D13811F96727B98F897
-:10F17000CFC7BC86062E2D96B6876C10975EDACD6B
-:10F18000E2E4A480AE0FE863564D295F9F9BAFCFAA
-:10F19000CDD61730D02739D4973B3BB13FDD46E081
-:10F1A0001E19AF78021FCFC0CFB1C603BE18081F0B
-:10F1B0001D671B1F629E267846E06C9A9F8027F091
-:10F1C00031BE576CE42731CF5BC644E2B1467ECEF8
-:10F1D000FB96DFAB60EF2DBD91E211EC1FD548CF60
-:10F1E0004B7BF22CF38BA3EFB577AFF0819C4F9064
-:10F1F000541607EFA9F583FE6BDA558171AAA54F66
-:10F200003DFCA49FBEBFF8D10D2E48AEFA48E9CA16
-:10F21000003BB861FB2A17DC33F7A1E27781FCFCE5
-:10F220002820C7CC5B7F9BCB01617735727D73E46F
-:10F23000B7B7CD04787CB1DD8AE70C9B76C405E3D3
-:10F24000306E720DDA63B4FE36ABAFFE04FCD8A6A6
-:10F250009D46FB69F16F3664A8484FFE6116DC04D9
-:10F260000B0E83CDB0C66D56DC4F693C247BE9673D
-:10F270004813E9BB15E6677E1FE67192E2BDA95B04
-:10F28000BE0AF2FBCCED5492A03DD6D4731BDA69D2
-:10F290004D3D177E00764593299FA27E003BECC52D
-:10F2A00031DC0EE3F7A40BF890403ADA37AD0FFEED
-:10F2B000B2E46D3AAF63DBFEE2928AF57A7325E23F
-:10F2C000E9D3EE059B9E5607D6AF1F837D10A77F1F
-:10F2D0008FE157DD29B18DA15DAC6CB0065D101FCB
-:10F2E00068D86CF5520D4C1A1EDEFAC0AFC1BF7C57
-:10F2F0002DCE0BA9A64B1E7EFE9573697DC963D6E4
-:10F30000B41A367D27EC730B3C41CE06D829022F68
-:10F310008B7FFFBC0DE290F01CEC5E819F258FF58A
-:10F32000DAE09C9F198ED3BA7B6D980F6BC653F7AA
-:10F33000DB33C004697DF04B1BD0F747BB25BCF71E
-:10F34000DEFC7EFDE6E75D40870027F04305BE2238
-:10F35000F8EB87B7E0CCA74BB11FC6434E85BFC7BC
-:10F3600001476548E78F3C0D7194D7E3BC0087FAED
-:10F3700047AE75C17A3E5096317ABF6F5506DC971D
-:10F38000576FF567B8B164CFEBEFBF1EE9F0EA83C2
-:10F39000D767B07B24B42C768FA63F0BD6F9B37B0E
-:10F3A0002FC1752E22754887F5F7B1F8C6E70AA96F
-:10F3B0007E2C06BFCC2D66FCF2C19638480E221F6B
-:10F3C000C03E02EC9BBC28E3B9FB7EF72291E558D6
-:10F3D000FF9CC717C61547EEEDB3837DD7C47B35B9
-:10F3E0006D5B1D023C1DC9D186403C9FC2C1CFE16F
-:10F3F00026C1BDEFF2C1E943189E880AFB21F81E21
-:10F40000B5C7A7C173E81FB26A8E12C37BFC7E1B0F
-:10F41000F67D11DFA0F38E87FDF40F32585E9E79E2
-:10F420007D1DC5421E9010D1D3D940FCBF6D0DD2B9
-:10F43000D7678718FF34066AABB13D640D0E81F6BD
-:10F4400040EF6C09E5439C61FF3C421FDBAC9CBF75
-:10F450008DED749E8AA487EF6E09EFD314F4B2E8A1
-:10F46000AE38C37E7D947E8CF745097E157ED6D559
-:10F470005C1E98D76D960F97169BFE8EC2BDE9A7AE
-:10F4800015FF6EB0061EF835F033E55FBF0AFC6C61
-:10F49000C5F8C0D1DF3DF7CA1594EE8F760B3E3626
-:10F4A000CA5B331FD73F5E4662F1F151A797C4E4B0
-:10F4B00063FA3C261F3BD9B9E9FF57F2F6EA01E4AB
-:10F4C000ADBFD8286F3F27C549E711D0334BF0BEF9
-:10F4D00057337C85DF6B96A399C56A4C394A7F0EFA
-:10F4E000111D3C051C057D2E7E68297E2742C782A2
-:10F4F0004E051D47E8D4BC6E233CCDED5530775DFD
-:10F50000FE837525F563C0CE7D560E6CA1533B4E30
-:10F51000E7722B85FFF1DFE561BED12AEE071C778C
-:10F52000F7B9207F6C15F73BFA202E99147DDEE7A2
-:10F5300060F6D2715F9F2B596737BDBD4B76819DB9
-:10F54000170E90EA58F1242AB1711E6132503BDB4C
-:10F55000173BCEE3A1C779BC73BAECCC6D8638708B
-:10F5600017BBD77FE18ACB5CB02F707CD7883B80FC
-:10F57000FF7EF66799DDEBE9D714C89358C0404089
-:10F580003E24FEBBA7D0752ED8B504F31BCC7194D6
-:10F5900045CE6DB8BFF039B9194B73FC6431C4590D
-:10F5A00080DEEF353DDF7511D2D762137DD5017D49
-:10F5B00065F5A7AF1704BF8E27E3F5E7CF9673B9BC
-:10F5C000375D2EBE03EC99E3D4CFC75C02B9F800D7
-:10F5D000E8DDCFC1EF07C6F0A723DD2EA9FBD0C61B
-:10F5E000EF71467A177468F6F7CDE5B127FE3EE96C
-:10F5F00026DAA5E1C9374AEEA1E5B1275F2B7C06E3
-:10F60000EA4FBD9AFB06E9DF7FDAEEAFD0BF39BE25
-:10F610003B0EE7737CF79F726F82FAD37198877500
-:10F620007C651CE645F9772706E03CDFF11C16B740
-:10F630006B7DF6CB12CCBF206D88C793C536668F25
-:10F64000ECFA9FB7207FFAD35D712AC4299A7627F6
-:10F65000A0DFDEF4B403F35E8E3FFBE5247D9CE97E
-:10F660003F5D4FA38DC5338F2792398F033D2733DD
-:10F67000FFAEE999C95B215F6E694FAF0DF607A632
-:10F68000FDF15F2520978E3FCEEC0FEACFDF0F37DD
-:10F690001DCA639BEEB652787F0C3622F5C3378DB8
-:10F6A000EDBE14FCF0FE706170384EE100EBA2700C
-:10F6B000A907793A103C868EB521FD7FFFE0F1095C
-:10F6C000FA170DBBCE413E8AC245D2D8F3C4805D45
-:10F6D000C2F5B3E7BBBF2C017BEA68F70AB40B4E57
-:10F6E000B5EEC963BFAF74F06DD72D054F67DD73FD
-:10F6F000BEB7F866F4FF16D757663EE84FE74FDD12
-:10F7000080F54712BD38DFD3E4FFE6FFDFF0FEB837
-:10F7100084FBF2A7C2FB2FFFD7E2FDCF1CEF896E5F
-:10F72000C82F3BFEECBF72896EFDA75AF793FF4BC3
-:10F73000D71DB18F649F1DAEB8EF24C1109C5F5FD1
-:10F7400035809DF2EE5849E4EFA01F22F277E4B431
-:10F75000C56867C8691D6837AC22EC1E64BF6AE1E2
-:10F76000F7B1B1BCEFF66C6F00E3A28AAF7E33ADA8
-:10F770005B8737783B7004A37F2667D454439CA5EE
-:10F7800075059D171DA735DDE26E55E19A764B3064
-:10F79000AE04CBB7A15C9DF1C3FDF05DC569BCAF04
-:10F7A000D669F237E20B6CC6BC62B2C70DFBD50E50
-:10F7B000AF0277B95353D678BF6DEF58B6AF1D4F30
-:10F7C0000298B779A6704A2D191C4E66F808B8F54C
-:10F7D0008313F747C57DFC4A5A4708F85021D49F48
-:10F7E00064EB413F14FE8E14ECD7589316793BD846
-:10F7F0007E8A1AB9C71FF220B8BF19B96756B5A0DB
-:10F800005F2AE0AC1B0FD76F86F399C257E0C54162
-:10F8100066219E1DD94E6F80CE7F95CAE0BE8AC2FA
-:10F820001DEE1717F0157033E3E17DA0519D1D1FEC
-:10F830002D8DF93AFE4AE2817D96E9F294B01FECF3
-:10F84000E5F204B4978F49242851FFED5845462529
-:10F85000F815C7726C0A9453FBE89A74F3BDE0A4E0
-:10F860003DF237F4A05E41920DF5633985F8FE3420
-:10F870007B96E1BD0390B74DFDF66359E576DC0F4D
-:10F8800075E719DE9B99E0DA02ED07208F1BBF3F79
-:10F8900003FD9B1F641619C699F9CEB17BAFA2E593
-:10F8A0004EEE57F74DB5623CFED89FE755021C2F30
-:10F8B00054C71BFA1F24EE74202ABABE2A58DF450B
-:10F8C0009EC986EF36BCBDA710E2103FF256189EC7
-:10F8D0005F5C7EA1611C9F3D1C04F2AED56A0DCF1A
-:10F8E0001B9ABF204A2A21E7357F4D9489D47C0F8B
-:10F8F000761BC699B87FA7A1BF37E49E0626E3848E
-:10F90000C3DEE7A014F9ECB654BBDF42CBB16F57AE
-:10F91000CAB0EF59F65E5D2B84A1CF3B463C400751
-:10F92000E79078DC0F1C28EFFD4B4BA00ED6F90BAF
-:10F9300039E081327ED8A21258D747999D326C4B5C
-:10F94000DF23D55D5E0276D6678156A85FF075B776
-:10F950000CFE64EB0E19CFD74D976B12FE0AF2B86E
-:10F960005BC21CFF06A705E3F04753BA4BAED5D1E7
-:10F970009DC8DB31F371D1C48A25307E5BA6D6D514
-:10F980000BF2B4F2EF57CA31CEBB12B7F15EBAA296
-:10F9900089BEDB619F5EE425C54F935972FB0FACB6
-:10F9A000182FB9D5E27570A1807AD73DC3BA19F87E
-:10F9B000DD3A8EC98DF8BF1015E241F1A975329C70
-:10F9C000B323774898D722BEB7A09CE5DBDF5E2241
-:10F9D000EE3771A7FF642CBC9FC8F205209606EF96
-:10F9E000D558D04E711DF6EE83FBC8EEF41C728321
-:10F9F00078E8A979C70FFB223D874353258A9721D1
-:10FA00009D15270A587F02F1CD1E4F55C258D46F5D
-:10FA1000E59887B39CE7CFF44EFD8D07F4C7F2A2BB
-:10FA2000D14306CB2F779D9488AACB33B08E5371E8
-:10FA30005E2E258CE7C55C27156C27E1F1CC1FE411
-:10FA4000E3BBE6A9AF5E0BF3D86FC57C67A2684B3A
-:10FA5000601D1DA3DF543B701D84FF5D9130FEDDF2
-:10FA60003CC84FC20BD19470E64F629CC33BB2A31B
-:10FA70002C19FCF2D40A2F9E1B4C7D588E9C9B05A2
-:10FA800038DC0EFFC373B597BE5A45C7DD01B2928D
-:10FA9000B50709A5EF0E9B68A7A2C6C3EF3DC4F644
-:10FAA0004B2F831843BC6CEC3F2E3FD25FB36746AD
-:10FAB000C7FF43C9A5AFB6C584671CEAEB8E1956CC
-:10FAC000CC9F38355C134E01571783EBD7542B640A
-:10FAD00044E38BEF496A2ED0DB9D705C80FAD1BF86
-:10FAE0004CAE0B96A4C3FC8363E1F97C9736642A81
-:10FAF000A5BF1E9B967B23C6491C98FF55FBF3A30D
-:10FB00001BE1C8986BE6114F1BD08DA2254C8038A5
-:10FB100095FB0B940B22CF2D0A474ACFF49BB75B82
-:10FB2000A2759013AE285C35B82BB84307673BAD80
-:10FB3000D772B8FECF23F597B5017E17DA912EAEB6
-:10FB4000E53CD5964CBA20CFEE84FB814B811E4E0E
-:10FB5000ECB062326B0F34821EF5D8D9DFF5490B59
-:10FB600067C2DF71197BD082F1BD37297D68401FE4
-:10FB7000C1F1087731DE8929AFA6C0F98913694A36
-:10FB80000AC06771D88670FB894282707F6A4FDA3B
-:10FB9000C26915C81F2AB677F371264FD4FE518269
-:10FBA0007A9D9FFFD5CE95E1BED481F065DECF87EB
-:10FBB000F8F0B92903D3415B851DEF1F6A2A5F5115
-:10FBC0000C7A62797221E663355549A8879B9A3F82
-:10FBD00043B88BF1959332517579533D104D4CD705
-:10FBE000DD237FD286ED0DCD27509ED3E9E401DFE2
-:10FBF0001CE3FB9D5D56F2D35A5A36FC5BFE69ADA1
-:10FC000013F72DDB419F34903DB6E53A7948BA3F72
-:10FC100089C8FF71147777D6BC180F72B656725F19
-:10FC200002970ECCEADE7B19ECE7D73ADC97C0FEF0
-:10FC30007F8EF71156CF715F02FBFD631F4D9A0354
-:10FC4000FBFBB559EE0DF09741AFF016CDC1F63C78
-:10FC5000F7CB509F316E06AB27323A4879347F8E0E
-:10FC60001FF5B913E1F2697B4260B07B48AE6E7E4E
-:10FC7000C600977EEDB284795198B841E9E79F6B51
-:10FC800086B17B710B4298A735721C8BAF67A4B00D
-:10FC90003FC92BF277D346100DF657D39E72B07B37
-:10FCA0005BDF0BE502FCAE7ECA1184B8E4D2FB9E9A
-:10FCB000B3813E9A2FAB85C057B3CBEAC68C2B835A
-:10FCC000F84908EB5737EFC679754C70F3FB72FBB8
-:10FCD0008A217E55CFF39EEB4DF9BF8B9D7B311E64
-:10FCE000B7789B31EEB68484DF023E6DF8DDE079B3
-:10FCF000BFEF58D83C140E8FF972E84A1B9BD7F916
-:10FD0000E3E8F797A6F462DEB1E20E65D4217C1B2E
-:10FD10003CE8AF64C6E3B99A5B87BE5E12EBBE985F
-:10FD2000EE16AAFF29CB3DDEB2134BE77882EB1922
-:10FD3000A2846D5E3A4E2397CB9342EFD8F4F983B9
-:10FD400073395C9376B2FD6F735EEC5CD05700172D
-:10FD5000BECFBC74D60B53002F029F1724906ECCDD
-:10FD60005F4D215E8E172FE045C03FBADF4CDFCBE1
-:10FD70008B451702FE84E5DBC53379D1F78403EDAB
-:10FD80002BF3FCAFE3FA57ACA39DD7079A7F3BD781
-:10FD9000B7677BFEED5CAE9BD721F8583C177C6CB7
-:10FDA0005EB798F799D359C8763A7426E44C23A9DC
-:10FDB000F3605C96CB150167314F01AF9E01F25D98
-:10FDC00095E63F18D6A3842AF1B0FC7650A420C74C
-:10FDD000BA2FC4942BA57917F63BD3F508793BD0FD
-:10FDE000BA849C35AF4FC85BB14E2177C57AA75214
-:10FDF0004182F210EE7E90C07FA833D8C3157062A6
-:10FE000041BF0F64FFB9A13EDD7DA3A1FF0F3257B3
-:10FE100018DA2F54D718DA2FF2AC33D47FE4FD95DB
-:10FE2000C9AEDF6C68AFD51E34B44F0987A681DD3B
-:10FE3000FDB7966ACCE73EFFC3BEE7A01E6C7163B8
-:10FE40007D4F4B26967B5B54E4EF7D2D1E2CF7B740
-:10FE500078F1F97FB59463F9428B8665A8C587A5CB
-:10FE6000592ECCFCFD650AD8EDE5A12EF407C68F0E
-:10FE7000AFFB0CE4E1014BA03591C2E99C37997DC1
-:10FE80004E02667DFCE55B37815E77B37BE8DA7A0C
-:10FE9000274B6A0C7BCE45F59DA6A317574D98C0FE
-:10FEA000FEB28BC4CEBBFC6A1CCBF7C17C3D4A9B27
-:10FEB00073ECEC5EDB397324CC4F9C43D879055A44
-:10FEC00006EB68FB4C85F841FFD73A15DC8F22FC26
-:10FED000FCF0256C9A70BFBA3F0EF4775A2A9E57F1
-:10FEE0009A0D0FE97C654DC6BCD64BCAFF82F980DE
-:10FEF0005738D9DFCDBA7CFFCA7FDE44DB499BBFD0
-:10FF00008C9D8710F786BC6E3913BBE12B386300DC
-:10FF100079A09297FDDD9464C5ABF70744F9D771DA
-:10FF2000CC1F98D9CACF0B1C2468C7097EA4EB6BE1
-:10FF300087F90BBEA8752BC1512ED0F7EBA641FF58
-:10FF4000FF0B270420E00080000000001F8B08004A
-:10FF500000000000000BB55A0B74146596BED5D591
-:10FF6000AF904EE88400411E76886020AF4E271D7A
-:10FF7000C26B2812C01762A3B2038A52A0189E490E
-:10FF80000CCC8AA37BBAB11904D6B39B193DAEAE93
-:10FF9000E869705076D6738890B8194D980695C761
-:10FFA000ACA3514141B3D820F258133A121470381F
-:10FFB00087BDF7FE5574572701F4ACC9C9B9F9AB31
-:10FFC000FEFAFFFFBEEFFDAA961D70B98300505DDB
-:10FFD000B63A0F0A904E918EDA902E5BF50398FB9D
-:10FFE000E178D5393017034C95DF08A696009C3D83
-:10FFF000046E1BCE1FD3AE9EDAE1C27F2E5D9660EB
-:020000021000EC
-:1000000000C04A3BFE8FE3B2CEBA8ABEF86F51B849
-:100010001ECC740D7F2EE35FF1BE2630E7C4C6E32D
-:100020002ED4BF4BF376FA55305B009AFDB3998618
-:10003000FD8BC03C0260B7BF86C7EFF957F1788FE0
-:100040003FC0749F7F1DD3BFFAEBF8FE07FE177801
-:10005000FCA13FC4B4D5BF95AF37B89D00FD01CE1C
-:10006000B5560C54F3F06834F6E286F6C999BE141E
-:10007000A4664167D3813C48ED60C9C8403A5B62E1
-:1000800079E0F500A4330DAB787F59E63B2C0FFCEB
-:10009000F1D991DF59A0FD64F4334329C0BD20F8A4
-:1000A0009F55F6DF17A5541AA83912CAEBBECC3EED
-:1000B000B04102B81F02F9F391CEAEACB38C97E811
-:1000C000FE14E709948714F8C274391765423F9308
-:1000D000BA533C289CD0E526032C71ACB1C2700009
-:1000E00094D2B108CAD704125CCE02580C612BD04E
-:1000F000FD3F5A8E45E2E4BC14200BB2F1FC6F5870
-:1001000078BE7E1DE8F9B875E50A19CAD2496E2E87
-:1001100096DB7288F07A36F951778D83F6ABB3D2DD
-:100120003A89FB2E71BC67C5410FFBB6F2F3D7DAF3
-:1001300057D75315C07C9ABF2653A9DB85EB2EEF0A
-:10014000D3F6A06CEA411E4E73E795F5500EFF32D0
-:100150004AE8554E9962571D64A70E30A11EA3218F
-:100160003964C3751665D5A5D2BA6898A980D71722
-:10017000B7C8AC0F302BE641A8B74A4D6FED10FE63
-:100180008CF45239A1723AA0FE166D34F2B3C471E8
-:100190009CE5FE3D34F7C86F153CF39D9CDA9DDF6E
-:1001A000AA09B79CA4F5AA34B9F1753CD7AA366957
-:1001B000DB7B71F356B853324E249363C118920B14
-:1001C000F2E10E93BF1D90D9DF7AB38F337E607B4F
-:1001D0003FEF876DEFA1FD9FB984176E0078D23D88
-:1001E000ED85C0845F4E6FFD8A7DEBDDE44F6827AF
-:1001F000E447BA1ED7A20D019E7B6DB93D1440792C
-:1002000046BD4E33ED1F9542C154D2CB4570AF462B
-:10021000794F6EDE7B88FC64B2DD1126B92113EDC7
-:10022000F17A9DD42E2E4F3C1E0AA6E0FCF16D0102
-:1002300099DC76EC0135E8C0F1980F14D434C699F6
-:10024000F77C32E97DBBBF89E550EFAF671AF39FBA
-:100250009BD8CF60105ECBBE7E3F8387ED268A6B36
-:100260002BB43305D3A0CE8401ABCB314D4E413EF0
-:10027000BAC2E0A6EB45075C413A57719B22A7E260
-:10028000B9BCC7D5209D7B2DAA41B1519C0CC87D1E
-:10029000F1BACD0C611BC6115BA6099438B98E3D2D
-:1002A000170A521CD4E35A7392B0E74997EA658A59
-:1002B0005B4EABBA7513CA13DE4E726F71753FF7A2
-:1002C0003B6E13CBFDEB74DF3B6EA4E0708DF4E569
-:1002D00093FDB4BFF612D94F43B2DB86CF25C66972
-:1002E0003D2EEAEBE872D3E558EDECE2B8BF6C5571
-:1002F00017C7BDC47DAB4DA0D6A3DC3D15AEE25AF9
-:100300005CA77D35CC9B89E33A0BD2BCEEF33FF181
-:10031000947F48F632559ED0AAD0B99CA6ABDA7528
-:10032000F5AAEF78FF5EEF6BFB57B7789D0B1CB11A
-:10033000EB8E2249C479303B4FD863FABC5EBD4F87
-:10034000EC9C6DC85B932EA886BC3519236DFCFD13
-:100350000AFBA386F154E7E386F9B764AE36DCBF47
-:10036000CDB5DE70FF8E9CDF1BC677BA5F34CCBF85
-:10037000AB6C93E1FE4CE53F0CF767C8A048E8730F
-:10038000F952C8427E3607EA99CE8556A60F422713
-:1003900053152D89E80270337D187C4C977B54B936
-:1003A00008ED266AE91C407EDFF1D6DFF3C82E3A5D
-:1003B0007E35DE99E58AE5653D4FFFD47CDCC78A52
-:1003C0007AEAC11E061409BBD5E37DAFFA4988F766
-:1003D000D1228C2778CE686332C799684A9F9024CF
-:1003E000C5E2095AA489F2B1EEB77A7C299EEBFEE8
-:1003F0006805F9D107328C70758F3753CD581A784C
-:10040000E8BA3BE781FCD8FE41132C223BDB8AF49F
-:100410004DE4A3EFDC88D915C74F01F181F6367999
-:10042000CE1488E0F5194E5042387F861D322E508A
-:100430002CBCD495370B03C48C0BA828B4E71FD36E
-:1004400095429277E0E909692772B5B87423EAEF1B
-:10045000A889F981C5526804CAA3A9418CF317A6DB
-:10046000317FF74398F5F800442CC4FF3C008ED34D
-:10047000F3C1C5F42150589FB8727201C6A7850D0B
-:1004800066CF06E4B330BD7338F967FED8C3E9120E
-:100490009E0B4B3B85F82934C13AAA6F743E6A35EE
-:1004A0003E3614291574BEC2F4D60DCFE2FE9D8DE2
-:1004B00026D88CEB9C1CFBF82310978FB77ACA6F59
-:1004C000A579DB245028AF065A6CA12D59B47FE7DB
-:1004D00000CA07FABCE59E8A1945B8EEAC22607DD9
-:1004E00043EB5F80F433D329640F53FAB30CF0B9B4
-:1004F00061BEFC9EFC33C0CF15922C6F0071A18CA5
-:10050000F7E5F1236FBE317B4D1EF313A03A6EABBE
-:10051000479DC7E7B7622CA0F3BF6C0B6DE67AABC3
-:10052000669884E7AC7CC566A2FC7F18E333DC0CDC
-:10053000F0A5DFCEF47FFC4EA65FF933991EF5BB24
-:10054000987EEDCF61BAF0023280FA3B59A4541183
-:100550003FBDF1D17B9C117C4425985DEFE87EBFC7
-:1005600052F3878286E34F25931D34C96EB2D3FCC4
-:1005700046344C3CF799E63121392B5EAEEA13C480
-:100580006741D3A77F185F42CF999D12CE3FD3D446
-:100590003580FC37F17C57E4D16215F2D0CEBB2D0B
-:1005A000AD75033DBFAD71389D10E308083B247D58
-:1005B0004A3DF1B19AEDE4574522DFDF65EB2C713E
-:1005C0003A62FC01951898676AB53C3355BE944A67
-:1005D0007E3193D61D4B767DD347B45F609FF04349
-:1005E000D4EB3C5F9C3FEDD0E4A0D3FC16AB8FFC7A
-:1005F000695BCB6777DF81729831EE36AFEC8ACDDD
-:100600007F9584E025FBBEF8EFCF66F07C276D3543
-:1006100007364D75E2BCFBEDBBDE27113CE03C3AF2
-:10062000350DC7F332A53D44E7BBB2A6A5531C80E8
-:10063000103FFF50CEE43D6462D3DD33AD544F4CE8
-:1006400026A78A8BBB15768C378638DFCF30BE2540
-:1006500073B061FE6DAE6CC3FD3B72720DF7F57D3C
-:10066000A7BB8B0DF3C85FA9DE463E58EFB0450E21
-:100670008D90C80ECE7DB194F99F5342FC47517EB8
-:10068000562C1C4E95AD7FFE590A1B8DBB53C93F9E
-:1006900013EBDA652DAFEE515CBDD7B555E0EB1B22
-:1006A000967AAF677BAB07AFB7AEC538F2078A2340
-:1006B000856FDDEB0CE239B68DBD78830BF9FBB8A5
-:1006C000A8E77A37AAD5BB897674C55E2597B09F0F
-:1006D000FD32503DA4D7BD897604F094560708FA40
-:1006E00053FD7DC627226F7D437EDF2FDEBE351A88
-:1006F0002A32E499422BE617D44FE7DF64D84C172F
-:100700002EE139743D64C7EC1F1EDEF4FEA012BE5C
-:100710001EA0BAB68AF202AE9FEC91C4BACB76BDE7
-:100720003F2823761F561E35CC8727A53D86F19A94
-:100730002CE3F899C97BE29FEF2D1E556E7CD4AA5D
-:10074000629CAE7C4EE27C95785F3FCFD4DD490A57
-:10075000C54D73B38DFBA92AA7028A83AA26CC2391
-:100760003DE4753D3ECC91A1A6A73837405B77FAB2
-:10077000EE24907FC6BA87D156E83C81FF12F9E695
-:10078000705F057C71FB647944FDD79156F74F3F4C
-:10079000E0BC8E3F839B44DF9126E26E41C34993C8
-:1007A00089F25F1F612F05CE88291D69745172007F
-:1007B000D09FAA17A7044C85787F78E7677654FD09
-:1007C00028CFA017EDA8B72F4C2643FE8952CCC3E3
-:1007D000B1677BE61CCA3F77EC4E0A9B7E063F1E44
-:1007E000AA399016960BBF7F90EC46ECA300FA470F
-:1007F000F5EF40DF57A13841FCD378A967C8E1E79E
-:1008000070DDEAFD220EE06D47623F7B7F5C3F0BAF
-:100810001B85FFDAF197EA9D2A084D73106E10468A
-:10082000FF875FCEFF67781C195CE7909FDFDCDDF8
-:10083000AF75BFAF3E28FCFE6CF3F79F509C3F8B1B
-:10084000F92FDEEF75B9E9FE5EFD82CC7EA95F3F30
-:10085000D32CDF1AEA41CE65BA5F296EF6D75AA7C4
-:10086000D8B776E2F9BB29CFD5B6A086A4EEFBE8CF
-:10087000B47A9D0CAEB87DB6EDB42D0A39627C44D5
-:10088000F5FCDAF27DFAE43C415753FE853A2DFE41
-:1008900088BA06F3AA2583F2EA4CC9BD05C9C196F8
-:1008A00081E524BF8312845D1E5EE25E3B9EEF1EE7
-:1008B000B11C5D77507D06993966DAE76E4DAFF76A
-:1008C00068F8D2AC96592328DE7FD6B0E0A042511A
-:1008D000CE93CDFBFD1A025C1F1E4CF30D5D4175DE
-:1008E0006850D8F9C1B4CE76C2A30E4E4C9682128F
-:1008F000AFBF26BEFE3B68F10DAD61BE345C4A1948
-:100900002D5F4EFE09FDB21617519F0149F477EC99
-:1009100007E641CF30CEB018427B14DCB7CA1DE6E3
-:100920003A7529085C20B1BEAF9AF0AD95F24362EA
-:100930003F3AB969D721A9A0071C23C16EAF855BD7
-:1009400024F6C1BDE10F3FA6FBB678E2F0C3C47A3E
-:10095000FD4A5DAAD7555B92439BF13CEF4EFCB735
-:10096000334B71BC724BB293FAEED3AFD802149FE3
-:100970004F6FB68524BC7F3ABDB38DFA90D3DBF3BD
-:10098000DDB802549A5CFFF906E5F93F59D82E000C
-:10099000DCC23FAED8E9634728DED56E499180EAD4
-:1009A0006B55DCD77B40F9F514AE1316EF1814B273
-:1009B00049B13C43FEE1C2D2E2D4CB490A15FDA7BE
-:1009C000F7DDD397F0AB76D39BC3180F939F3CF220
-:1009D000383EB7F4B5140FD5139007ACB7459B4715
-:1009E0006DA2FAF8258BBA97F8AF78FDCE8159B48D
-:1009F000FEA7FD81F88936EF1840F551AC6EEFB9CE
-:100A0000DE3BDB9CDD17F26272D2F1C4757F5CEDD8
-:100A100023BD274B2EBE6E861A6530D945D34CA018
-:100A2000753DB2A4905F76AE4FE63A35D1EE8E7842
-:100A3000449FB24CC71FFA813D93FC47059643740F
-:100A40007DEEE60D28A71F3CE95ABEEE1C79777EA5
-:100A5000BC7DB655BD43F6B9D1C6B8487B92B16EE0
-:100A6000D0E9FF7AD2789F4AFB39030E51B5EAA24A
-:100A7000719C87FD1E3EEF09BA8A1F45BA42937FDB
-:100A8000D7685F87079F5F52FFFBB73E60B96CFC7A
-:100A9000C72F68DF7D0E81C77C20E497D80F54DA1A
-:100AA00005EE01B089CFAB5F3FF9F2E70564872718
-:100AB0001B7347921E17C8AD275E423ECFA4B41EDB
-:100AC0007902E9F67D9FB05E12CF9B88DFB44B12AE
-:100AD000F3BB8CF8C0EBF77A7D72717F7667EEE33B
-:100AE000166CC867F94D95F3FA921EA3A77BE957D8
-:100AF000B473EAEBEBE7D3D7D7E7398B85BE3ED4A7
-:100B0000F0F70E6BEB19D26FC75BB912E18357AEEA
-:100B1000A7B716A4C5D9CB2F85CBDFA7E123874C78
-:100B2000AB7F63457B6CAF7FD6A2C6C7BD9F88C72E
-:100B30005FA907157039078854C2790B9933E37898
-:100B4000A23E2667C0F104ED78129D07FD72A24611
-:100B500061899AC9783BAD873409423C0E4E76BB19
-:100B6000884E927C8C7BE87DC334A819427C98EC3B
-:100B700011C609D7103E8975CBACB4B57766E17E56
-:100B80006BFAC35AAA67D658845F04E627733FA757
-:100B9000CB49CF33E0CC33E497354E7099719DD972
-:100BA0006658674917F36E44391FDCB7E07DC25DB4
-:100BB0003F37D7F4A77D0F3B9ECB974C54E7855228
-:100BC000A867FCE2933F79FF8673BF046522D515C1
-:100BD000F7EEB573DC4FC4271682CAE34A8858CEB5
-:100BE000E1735F8DFD71CB6E88F1F5D5B81F1AA941
-:100BF0004FB83FED292F3D1F28871CCA4BE7935262
-:100C00000B889F5576411FEB93BA99E869A723405B
-:100C1000B8ECF9A46121CAA72F49EA8364CFF81C74
-:100C2000F7B18123C921CA778FC96A15E3D0695604
-:100C300090707EB4BF26970E60B9442DDAFCEF5C4D
-:100C40003C2EA9F0304E09E75D1C97C727E49D9222
-:100C50005C93E8CF2E8BF9133BCD86BC5352A8E1B1
-:100C6000397F77719D3AE982F9AA79E952B1E8773B
-:100C70004BFA996A7AAA179FD5EE07212C0B9C474D
-:100C8000D40BE3AFD89722931EABB47115E535B4FE
-:100C9000AB68AA3D2023BFE39B859D8D37877711E5
-:100CA000C5280BABA8BE68C2BCA79F03E30A64E6D5
-:100CB000B23D8CD3ED14D79A8BF3D64A35DCC7D826
-:100CC000A9AE41BA416AE573FC0A3A992A5A3E2F05
-:100CD0000737D329E0638A76CAF456A8637A3BD4EF
-:100CE000339D0EAD22FF8F0E0739AFC1934EEE0735
-:100CF0006FAB3451DD51F2EB9EFB87462D9EF42EF7
-:100D00000774BCD29F2E876980FE97DD833C86E402
-:100D1000701C499447A29F4E8488CC7E4A01229B36
-:100D2000F00317FB6B05283C9E7A9D72288BA86602
-:100D3000C66F12E551D1B35DECD4ECA2966CAD7FD9
-:100D40004C4F5DC52E1EEBFA42FFCAA43A34518FB8
-:100D5000FAF592E4F22E1786E22F761C9F63C6BC4A
-:100D600054525CBE221BC7EDC5DFCF31633E2B1949
-:100D70005FBE63388ECFECF8418C0BCB8B2D6EECC5
-:100D800062569F9F3305E7ABE49F8544D10F299EB0
-:100D9000A9A23F5EA9D531EAEADFB89DE82FEA5063
-:100DA000879BF8B463B19F847294B3C57BC761B766
-:100DB00086775B70DE718B7A90FC77B93D9CEA4256
-:100DC000F9AF5C3D752085CEA7AD62BECD26705AC9
-:100DD0009D3FBC1E48C2F1F6EDB92BA4E1D73E07FA
-:100DE000AEFF35ADAFAE1E1120FF551B25B7D06C41
-:100DF000F9C0D928C3F6560B106EAAEFF7D468F5E0
-:100E000014E747979BE3F760ADCE69DF9E9B4B7A73
-:100E1000EA2A163818646415931C8F8EF675D1FC77
-:100E2000688AB0B72ECAE5DEDEE9E012E53B9A9F9C
-:100E3000783DFA0D1E009F3797A8E7E97E75F225E9
-:100E4000CEFB678A3E5D1BC98AD9AD844A9B8BFC69
-:100E500007150859393F4C705EA95329DE2DC4751A
-:100E6000501E253E3548216ECCDCCE528AABB8AE42
-:100E7000A904F7A9B6468615E173CFDD73C42AEC41
-:100E80006E88B03B2D2EB5ECDCFFC46031F4419C84
-:100E90009F55EFBCF8C39728BFEAB30E374D8FF9C3
-:100EA000D78B2BB8DF0487218EE87E37AEC9C6F515
-:100EB000F6F8E6510B69DEC44FDBB289AF496D111C
-:100EC0007E8F166DF97CB03887DE879C977E4E3E0C
-:100ED0003EA9E58993769117E8BD30F77B8DE2BD99
-:100EE00070AD8673D6B648A100C71FD13F2FD2F888
-:100EF0005BBEBF710FE1278B363E349DED2824FA8F
-:100F00000A17FE525C587248F4CD4BB71AFB8D6A33
-:100F1000EA9B693E84AD640FCBEB13EE6FACE0BE91
-:100F2000B93A3EFEF7D0377B4B347C6C280C65BE5B
-:100F3000E4B97DD51EE261625F5C05CA8412AE7BB6
-:100F40007D32EDEF35F78C3FF42FD0DF9389FABD7A
-:100F500052DB9BE4E460B958B99FA87D7985DB49F1
-:100F600063CD6F3799A8A7C689EF7D04F1CFE97EDD
-:100F7000BC789DC47D076CECC73658F89A4D217E2D
-:100F80000B5F1BC87D08F64B5C1F6E7ACDB68EC614
-:100F9000C1DFF509C885844377DE40384C3009EB62
-:100FA0004D81E783E4611C867191474BB4B8AFD59E
-:100FB00001102E32F4F3412DFFD7A68C1C889D73AF
-:100FC0006CDEBE4186FE24A8D5DB25744EAA1BB775
-:100FD000DE20EE27093E767DFC0FC954F7369A7D58
-:100FE000C9846B9F3D309CFB98DEE4EEC53404570A
-:100FF000794FE9FD7C7AF6D5F456F28259C84BB3A5
-:10100000DBB7FD0A7C6D89E945E76FAAFC4685954B
-:10101000709187C1493849EDFE578376EA0BD703B3
-:1010200023106741D8F3D953267EEF5E0A39FF3A81
-:1010300001C7DE536677089F6FD0E222BD7F76C579
-:10104000D9994DC37F935C7DC015D74727E7A41B73
-:10105000C629EE1B0CCFF52D1B6EB88FF2DE4CEBC4
-:10106000434069CD2B8DD5BD69CA68C3734FA74E68
-:10107000DBC77EDFFA08E352FD6EF518CF2337CBCE
-:10108000140FE09CA897CAF097FC6D0C0482A48F03
-:1010900071EDC63AAA2C52C77D63D201B30107B0E5
-:1010A0005D0397DA44FE457172080C11712351DE1D
-:1010B000C6EF2F6AF7CB5CEFD50EC54235AB27796B
-:1010C000DF6490B7EE8FBADCFBFB8C721F38DB2835
-:1010D000EF41AA51DE831719E53DB4C628EF1B572F
-:1010E00019E59A1530CA317BDD38C3FC1175E586E8
-:1010F000F1CD2FDC6E983F2A74B7619CBBF53EC3DF
-:10110000FCFCFA0586FB854D4BAE4BFF45E15AC30F
-:10111000BC44FD17EFFBED55F51FC05FA17F607D5F
-:1011200094A13EC2AEFF3F3B38A6C759DD0EAE3399
-:10113000CEBE4D3ECB78C2844880ECA02C99ED64A5
-:1011400046B2883B1FEE3B7B40C1F147AE624B2667
-:10115000D5595AFDE0D3E290DECF24F68D7795493C
-:1011600009EFFB930CEFFBAFF55D9DB7356C1817DE
-:101170001D00FE6EC673C8FD2E51EF7185E1AED223
-:101180005335EF121D7B8ED376B77E55FF3E2FB1C0
-:10119000DF826507F8BDE25CFDBD0C394569777CEF
-:1011A00052EFC7F43E37B1FFD5FBDEEE7D9AA86360
-:1011B000BAF71BEE4C33D7D12AD7D57B259571CE04
-:1011C0004DA3D4C15E2F3501D8279BA84F8E04852F
-:1011D0003015A0F7D051FA9F8A90C0B3F7111E1FA7
-:1011E0004D03C6CF15A9EEBE401E1FDF192915F00D
-:1011F00011FD147BD5115ED4EB31C9B9B698F089D5
-:1012000071DF0EA37A24C72BEA3C9B8C92C2BC34BC
-:1012100070AE0274FDC7746594D71BC34B7AB39B41
-:10122000C4EF931AFC61A666A79BBF5F4AC417234D
-:101230002617D7A781DF4AFCDDCFB774B8B1B13A22
-:10124000E6EC3A0BD731A0F5F30F68F2D7718FB9FE
-:101250001A3FC770894598971F68DACB7A599AD98F
-:10126000AEE125355C8F3F34C4E1E1EFE19462B734
-:10127000C0C9741C64B0FC53EAAE6BF1BF34F3B464
-:1012800001878237FA5DD7FBF218DF62FD63EB0559
-:101290009E796CFD50C6CF63EB9F613CEA819A8FCB
-:1012A0000DFE316FD561833FCC0F1C35DC8F64742C
-:1012B0005A087F8CBC3568DAFD28BF8E465B29E969
-:1012C00003EDE011D2ABBE7E647DEE14DAF7DA7C7A
-:1012D0007ECBE768F3B7B27E753E8FF80FF138E248
-:1012E0008F247C9F26F8D4710E9D5A77438E99DE09
-:1012F000274A7DDC842BF7867FE87E662A1DCEEBAD
-:101300009C37B94E089CA8660CD57F6D930794D383
-:10131000B9DB865ACD828E14E3416576319E762BF9
-:10132000D1A8C5B18E709136497C4F3457525E9921
-:101330008FFB3E314A7D9AFCA17A496701F95F75BE
-:1013400061E44109D7EFEAAF6E20F948D85E0C4A54
-:10135000673EF8BBB353A6408184AEB2C7FBF57DB0
-:10136000D4279EEA13384315CACEC623626C15FEF5
-:10137000F8A1771FFBDF715C8CF80CFC5912F89414
-:1013800023629D89EB64F4579FA77DE97B327ABF86
-:1013900047D7C93E75BC346A11756254AB175FF606
-:1013A0008A7AF69504DA44352EE18F44395E3F336C
-:1013B00092F0F4B31B6D40F52DEEAF984A62DFAFAB
-:1013C0000C405EA88E7DDF2AFA4CCF5F6C618A5399
-:1013D0003AAEFAA6378BD7CBC8167869C63F63DC1E
-:1013E000223F8CB40E9B991277DE03C0387607E15A
-:1013F000D17138F69B5ED1AFC3C322EE75AC1FCC62
-:1014000078FBF2FDC78E50FCBAD7AB36925C1798CA
-:101410005CA5FC7D56EA2EC6CDF67A5DBC2F9E9764
-:10142000F9C538B486F4B4DC1E619CED5AB87A6F05
-:10143000FC772C6C7D3E8F71645701D98DBE2F9E39
-:1014400063AF370EFFD6CF115BE7EA7EA0E3C3FAA6
-:10145000F8E4CB4F8FD4F0FD79BE1EF2EB114D2E88
-:101460006D969EF1F88B5EF11EAF9B7E6E0620FCA2
-:10147000DFD607733FD26FBD82FF8E39C80FE31BE3
-:101480004A11E977F9DD0E37C9595F1FD751DFBC23
-:10149000CA3E5DA37DDF10FF4B6A047EAFDF8F4A3B
-:1014A00042AF81F5024F5DBEF3F091277097C5AF53
-:1014B000E717533ED09F4F9433CA77247F7F278B03
-:1014C000F75F28DFB3B47E226EFF73E51A1D2ADEB4
-:1014D000D346375D1C46DFA72DA7EFE10AC83E04BF
-:1014E000FE050D465C0BE515207CA3FB7B2DE0F78C
-:1014F00063362D9FD8F4E787980DCFD7A7F8924A87
-:10150000F1FC6F697103E7874CF43DB7169F1AB47D
-:10151000BE3B117F696815B86943A695EB68AA7F41
-:10152000E8BE5EFFACFC58E0A62BB3449D4DE7241B
-:101530003D4B87F670BD7005179730DFA31CD3AD08
-:10154000EA9052F2277505E733F946D433BD0FF917
-:10155000EBED1A8E20F2A357CB875E5A87CE95D734
-:1015600097F36489B62FF6178CDF8D0555AB1F34C2
-:10157000FC6DFD1E03FEF07FDDF5EC49303100000F
-:1015800000000000000000001F8B080000000000A9
-:10159000000BFB51CFC0F0030947B0A3F20FA0F13D
-:1015A00067B2A1F2D3B850F9875950F9FE68FAD161
-:1015B000713B13030323137E35F8B0083303830C08
-:1015C00010AB00B10E33F9E680B0BE2803438104AE
-:1015D00003033B90FE23CEC0E00E641702B11790C8
-:1015E000DF02C45381581C287E16484B8931303C99
-:1015F0001185E8B300B23F8B9167A7192F656E1E66
-:10160000C594611359543EAF1A03839B3A03439F19
-:101610000684AF8D24BF1428C6A70661EF976760C4
-:10162000D004F29564B19B7B0028AF0594DFA681BE
-:10163000DFFECD3AA87C0733547E269A7CA30B2A82
-:101640005FC30D95AFE30EA101C062BAC4D8030019
-:1016500000000000000000001F8B080000000000D8
-:10166000000BCD7D0B7C54D599F8B98F99B933997E
-:1016700099DC241398BCE02604081A7012C243C4F3
-:10168000701322468D6182687197BA23AD36A240ED
-:1016900040D6C647CDE41D5E1AC4EE22B874E213EC
-:1016A00094D6D462FFB4AB7402B8D2966A54ACB488
-:1016B000B5DD485D6BFD2BBFA0A2D4D2B2E7FBCE57
-:1016C000B9997B6F2601B4DD5FE3E3E6DC7B1EDFC7
-:1016D000F9CEF73EDF39718A0EA2CE23E40CFCD09E
-:1016E000E71B84FE64269E84741332039E03727883
-:1016F0002A3CA3FC3D7B0696F60AA4008BFD6426DB
-:10170000217984FDE43576AC16A7113296847E3AB1
-:10171000399F96076EAC217E5A7EEB8A3FC2B36337
-:101720007165F5651A21594B7A5FBD9C3E03E198BE
-:10173000102926640B1109C986FE0AA3155E42DA38
-:10174000A0B339848C8966E9D16228E8B440C8BF67
-:101750002A7C20226A322DFBF0D7C43C8C27214EF4
-:10176000122FC28AC219D7F0F6F6FAC6D307ED8C4B
-:101770003AF9F0FF3504E677B676642D1B2F4AFF61
-:101780003943F19293181FFBC9AA379509E0C7FAAC
-:101790005D1FC2FBEAFF93F1B249A95B2BA3F3AD36
-:1017A00011D518D427BD69322D076E93495CA0DF8F
-:1017B000CBBA058776F675E920A4BAD78BF815EA77
-:1017C0007C09F8AE2502CE67DC5DEFF474060839BB
-:1017D000B9D41B42FA5009C9481F3E9F6F371112F6
-:1017E0007799CA8B2B85088E17FA69216D1F5D2C9E
-:1017F000861E07786A16A5C17BA3DE37F938C3E9D0
-:10180000836832C5A3CCE943AE1175F7B42F4F1FDF
-:10181000F217A48FCCB5A676E4FCD70BF13EE3DC3F
-:10182000E9E3CB8E67ACEB70BE6A4638C6DD55E89F
-:101830002674FD1FA85E941A49526FE4752D457EEB
-:101840000FD4103D96A4DD3A584F9C67D4226FF018
-:1018500049D7471A5ADEDB2DEB258D9DB9A46714B5
-:101860007C4801EB7C8D7E9D8D92F64E062DCAAA9A
-:1018700008FDC9BCBF0E75599400DD026D537C484C
-:10188000DD257142F9830449E8710E8148CB4E553C
-:101890008FAD17A014C37531E0530A45CB788E5C29
-:1018A0008F653DC892A86086DFD9E844386460132C
-:1018B0002EEFC228DC18DC30C4990950BEDBB2FE22
-:1018C000B297C4DD54AEAE2B2C25E67530E854102B
-:1018D0000C3ABDFBDCE48A7DBCC55638CFB99D57B8
-:1018E000D6DE35DA148CD64E26EF1A78A2C87B1DC8
-:1018F0007E31AD7BA783EC152E22A435B7230A6F6A
-:101900003BE17F17237D82D0229DB9A52AD013D930
-:1019100029C800A7DB208F603AD6EB211AD2535496
-:10192000B883403DC91B463C19DF47868BD35D54C5
-:10193000EF2BA4FD5ECDBBBD9AEB3352E67867C0BA
-:1019400080BB00E79128D3797C7827FD1FA58F689D
-:1019500089107B5C18FEBD06F421954735F0DE2426
-:101960004F5C82559ED5F06F079E7B73D2744A8F71
-:10197000FD218980B86A79CEA557D1FE5FBD548814
-:10198000B9040E2FAD5FCBE13CAC67E4017DF657A7
-:10199000B9907E6B2FFF2C00E47B7CEFEB72327EE4
-:1019A000AD9DEB48C041FF5B659E1FFD6F0C8C81B8
-:1019B0007C59857464C0B5A2544238FAE70A3118DC
-:1019C000E7E06FFF70DF2514CEC36542C8A521BCD8
-:1019D0003E42C7EBD73F0E8C26278831BE4654C007
-:1019E000A77DFCA1F550424B802FEB55A7B69E8EEC
-:1019F00077AB143A047A8C8C65FAA15E9D5405EBA2
-:101A000023098C3EE60B59D8AED5DB3206D75D5A9A
-:101A10009A545ED55345A196C2F78D93468533E619
-:101A2000181C30D175E35BF9F71D34C13955F00549
-:101A3000DE4DA1BFCC22B3609D3FF22E4A8D939123
-:101A4000FB7BBF4969961D847CD6A4DD77D031FC31
-:101A5000FBAD1269E82D1EFEFE4A41E1F8883AC14D
-:101A60003E33E63D344F6F00E9FB5610BF94D46F10
-:101A7000DDE96E96CDF2C7368F21FC7EC1764A60D5
-:101A80004D345B037E8B2C14A01F99FE3333C18F22
-:101A9000B7EEAE637C6783B73DF0B781F76C7CFC33
-:101AA00091B7A503ECD55607A397B64C31D442861F
-:101AB000D38BB11E061ECF753D360A6EE40F838EA2
-:101AC000EAC5A5A3AEFBD9E8E80EA0A30BFFFE7400
-:101AD000B405E868C63F241D6DFD47A4A344F97210
-:101AE000B41716F2BEFA067EFF20C8E75FEA12CAF4
-:101AF000BD5FCE65F2FF97112617FB4964D30CD06A
-:101B00000747249453FD7AAB0FE1A52631CC03FDA2
-:101B10002E4A7FAF83BD3499CAF526059F74F679A6
-:101B20008BE8F7572FFB2C17F4D7AB746DC1FE264B
-:101B30006450D769FB5786CAD40087B29B95079B30
-:101B40004F45C13EEF1758F927CDA7F4288EB7B1FE
-:101B5000E3728ACF85F02B8563F15C418F25A18BE1
-:101B60009F094E86972A62D1AB745D7E26507A51CA
-:101B7000C2ABD1AE26244CD03F2CA47682C9BE681D
-:101B800004050672B9CA85FACFDEFF2BDC2EB4DB62
-:101B9000718BE79638405FB8C227E401FA5C1816EB
-:101BA000B00CF8574D708BBAA0831E08CF753D025C
-:101BB000FA2F2C13879A845F17EA2E8BDD7582EB40
-:101BC000318A9725CC6F51F3EAA626EA9F30F4AF0D
-:101BD0006D3E23D185310FA37CCDDC13073360DE4E
-:101BE000D54268223454D4BC1B7CE6FE530CFBC6A1
-:101BF0000778FBE5926B52191D4450AF1AF4F4D3E9
-:101C0000B7BFE180F993C51948978B6B248B3DB919
-:101C1000A82AC552BE6EEE35A3DAE12462C28389DA
-:101C2000EEFD3904E994FC37B553289D462B072374
-:101C300068B71C13B4565A4E2D6F1C0FFDDE2DA62F
-:101C4000637DA1BC71F200DA5B0B90FE53789FA913
-:101C5000CE863F14805C9D28924734B04747F70BEF
-:101C6000DA399D1B6547201215E87A6A51B5541A76
-:101C700005DF315DAC4EE6374C10D9BAB54717A930
-:101C80008500D041ABDC48AB6A40FBCFA84FE97878
-:101C9000829809E346F1FD101D77D179D1761E6651
-:101CA0008B90D40B16A59251E6D1665B7F2AFEF588
-:101CB0006472F6560E1FD9CBFA3764526A3AED3F7A
-:101CC000497DE3D9C9FB3F1512493FC0298715E477
-:101CD00087A24A62EE87E8255876F2A22B1856F2C0
-:101CE000293E5DC5224C83B4173FA2CB1AE0218A5E
-:101CF000EBBD81AE6DAE892F37FC45423FFF56B13B
-:101D0000A019E4C686BE5B8846F1E109C60896A71D
-:101D1000DEAC009E365027AB1FC6977B09C0919260
-:101D20004B7FA7E3A4A824A6D1FE64AD372ED2B280
-:101D30005C4D423AFDE453438287CA89FDC1826605
-:101D400099BE6F5B4A503E12901E26FA690BBEA6E2
-:101D50004B403F4B4808006E0B2CC37976142FEB99
-:101D6000CAA7EF4FD6C8183F20A729BC865F4FFDF2
-:101D70000C4F11D161BC0D5924E6453B5847FC3A44
-:101D800055B67EDAD642129F4EBFA7CDEC83F1A3A3
-:101D9000DF228C2F09936B32972744A6F407E33791
-:101DA000AAA1F549E84F21915BC419A67556C3E86D
-:101DB000C7DAF196EA2457027EDB4A281F24917B7A
-:101DC000778822D2412CB46861419271EE16359425
-:101DD0004F46593BE544F847AA9FA82793780674D5
-:101DE000AD0B8017120EE0FCD2C9D08F0EE50C3E71
-:101DF000DF31A401EB056777F701BF65EBBD158007
-:101E00008B6FFBAE7B15D78D3CAC821D4BA12D3C5F
-:101E100093919017A073607E1F8544F43B7C625CB5
-:101E2000D569073E777F109D5F8D605C2E159A50B7
-:101E300080D737296D6097F8494880EFBE901C35F0
-:101E4000DBF5A984962DF11472A4702661221FBFC0
-:101E5000AB7DC03A6A51C34500CC16BFFE5FE03788
-:101E60006DF445D00FFBCCED9F06837DD3E37F045B
-:101E70009E9FB9C7C5D03F0B317F4BA1FF80BC4BA4
-:101E80009D2D5BFC9B34DD5ACEB0F9610B242FCE27
-:101E900033ED6AC2FD2BBD66E298045C14A23AA041
-:101EA00097CD553201FFDFEB65F018F06548F7CCB0
-:101EB00042FD18928F011C142D08C749723A0E4B2F
-:101EC000EC2F22183FA5701DB3C175CC06D7313356
-:101ED0005C8D0A9BAFDD5E8C5692A2060ADC0B225B
-:101EE000F73FA8DD0476E349F2815E0D8413BE124C
-:101EF000F5AC5F656DBC4A3F062B54A2221DD8EDA0
-:101F000046BA4E1F59FCAFD9BCAC1101E641E1B451
-:101F10007E27B9482F5896C8505C78D96C035FDA91
-:101F2000577E43F9EF96430E02FC45F95882EF0EB7
-:101F3000FEF5161E1F5E06FE35C5DFD749D80FF029
-:101F40007D48448C437D485EF34F37C9C9E322B7CF
-:101F50004F6089CD7C4C424190E3B2B7A35FF2233E
-:101F60001A0C7A13CEE03A86989CF732BA8B12A5F7
-:101F700019F56117F33F8D78EA4DDD567FF81B5B4D
-:101F8000ADE59BC9A231102FBDF9410789D17E6F04
-:101F900031FBF7749DDE105584EF1BA4A103EC9276
-:101FA0004E07B33796A94486F8E78AFFF71F336FC9
-:101FB000A4F33909F26006D8EF147C931E591E88E9
-:101FC00039F5E2E1F36B1542B5970823CFAFD3D1D2
-:101FD0005F0BFE77749303ED4C628F83EE91300EAE
-:101FE0006A6A87F07EADCB3ABFB3CDDF3E5F421E5B
-:101FF000C0F92EDF7923DAE723CDC7B933B9BDE9BC
-:1020000095044BDCC7E06B83DEEDFC5D26692CAEEE
-:1020100043D520DA2BBF4B89B5E2FA36CC82F53DA9
-:102020005BFB8BA17DE6176F5FFE25C79F7F96F652
-:102030002B94C105B0DEEB02DD61E04F238EB5923B
-:1020400044F51CFAABE3F9D55130DD86EA05CFB192
-:102050005E2EAD279D43BDC2D1FB3BCEED92977660
-:102060003FEA043BF5C3A7DEAE053BE0D6FF94880C
-:1020700042E9E1F86E1F89A3BD1273827DB39CD241
-:102080005D0CCBF199D798EC614AD1B80EB73EE31D
-:10209000433B62F9B3AE580D6DBFFC87BF9F462826
-:1020A0001E8EB70CFE570ED0F353028BBB4607A60D
-:1020B0005D43DF2F97C9BF8493D0D18D12E3A70F63
-:1020C0007E94B204EC446167DF0DD86FEF571C2E8D
-:1020D000933E5E2239705C5A0FFD88E82E213651FE
-:1020E00060F099FD0123DEFDC12E81C1B7D71173C8
-:1020F000037C3B7B9C115A6FD5CE1348D7F39FF9D5
-:10210000AE1FF0B06AAFD54E5FB5538ABBA6E1F300
-:102110006D7882061566023E193FAFDCB302F5C644
-:10212000CADE0D27809F57ED7558E43FC54B280E3A
-:10213000787D530AD540F9074FFA358AAAF7FB1F75
-:10214000F7035E69BF373A295D2D9C6D6D07FD9FD2
-:102150004A1FDE1FF50CD16F5ED5BB8E8DB7E7EA47
-:102160003F80BC5D45989E32F8F97DF8256BB89E9E
-:10217000592759E35B27C9E199B80FB83323A9FF61
-:102180006CE81583AF6FFDEEC91D513AFE07CFFE17
-:10219000FF1D513A8FDBFEFAF18EBBE9FCC83EB75A
-:1021A0000AF26AD5536FF88909FF8F496C3FE0F84E
-:1021B000AE279FD846F9E4F8AF5C68071E7FE10FB1
-:1021C000E3343AFFE3DFFFD318B053D7BE70D958DA
-:1021D000C0C7DAE7E68F1DCD5E07BA8DB9CCEB1B21
-:1021E000C3FEB5BD026C8210F23C7FDAD6E9C01E98
-:1021F000290E21820F8FBA622E8A9F55F45D6329C2
-:10220000ACDB0AD45750BE87E27BE5EECE13D2B4E6
-:1022100064788FE6884178C6734810D6FD9A859712
-:1022200096C1D311D2804EC820EA097BBB5547E83E
-:10223000FA5E34F27A527BC209F85FB57B1D1BB798
-:1022400097AEA77FF87A7E08BF5C3C7C3D0F48D6EE
-:1022500038D34972DB77B6C1C73D19B8FE23ADE765
-:102260008AE7AE1DD5BF33E4C3D9F05C2F30B8EE9A
-:1022700097F4D725E0C7679F7E625B80AD730D45FD
-:10228000CCF1EF9E1C079BBCEF39066F003939F883
-:10229000824B05BB7AF90B6F22DF1D7FEE55A786B7
-:1022A000FBD3C42B503D799C0CFDF483DE5C29B03C
-:1022B000C2AAC77C71973FB15E2B6375D59A1FDFA9
-:1022C000BF8DEF638C1F56C6FA160B49D6CF2B175E
-:1022D00030FD14CB44BCACD0FA9DAAD7BAAEC26CC8
-:1022E00058CFB71700FD8DB49EC6FC5598FF2CD370
-:1022F000BA3EC6F878247E3DDEE39285D4E1EB7CDD
-:102300009CDB15AB62C29BC9D69D901616DF1B21C4
-:10231000EE6D3CED74E194AD7C6EB437E67F363EF5
-:102320003FFBBCCE0F6F27B9BEB6E3EF83D3C9F531
-:1023300040812C70BDD55D9D6DD2776E07D563F958
-:102340006077364473F213F076F44A28DF3FD829D9
-:10235000A1BD6F97132B47F0EB43C6387BFBA681DB
-:102360003CFB60FF8F383D327A5FB9FB6D6794EBC1
-:102370008598592F407F49D6630EEF6FD5F3C9FB7F
-:102380005BB5FB44D2FEDE97F5AF00FCEFF73B48B0
-:102390009476F17EAF94344E52283B2C7656876F5C
-:1023A000E6D154DA4EF27B3498776B8BFE6614ECF0
-:1023B00091D71C04ED4739F49E8B7E6FF57970BF81
-:1023C000A5D57F33D14CFABBCD86273918463F5A65
-:1023D0000E84CBD85E68CCE2CF3A54D1023791A3B9
-:1023E000B9B0CFF972FE1F64E817E2699A292EF49A
-:1023F0008A4CDA219EF68A2E849A4992B896ADFFCD
-:10240000F05C8968663AD3C78BE6F8A27FFF9D1817
-:10241000D768240D718837915CD2FBB8A9DF879B00
-:102420003416770D8F17CDF13F574383EEA270E43A
-:10243000AE550BC07F1B69FCBC06EBBEAF31FE1A6C
-:102440001E8F203B9F7AEA295A1E0FDF44A0C3B09B
-:102450008E709C66FBCAF3B93C7C89DBCFFB0572AE
-:1024600010ECB0EA7B2232C83B217823C64517E442
-:10247000DE282F33D1E382E0892CD0ABDFF98BB497
-:1024800024199DEEE574D5FCAD27B2A0FD36F757B3
-:102490007299331B46F87278BCEB60E6E55E88EF14
-:1024A000F5DDB2E0F0243ADF6C552210AFC92615F5
-:1024B000DE120A67CE1129E44EB20EC673078FEB07
-:1024C0003DD2A4A2FC7FAC2988E527385E7736157B
-:1024D000E1F3A9A6107EDFDD341BCBBD4DD5F87C22
-:1024E000B6298CEFFD77FDB8CF0978B997F442BCD7
-:1024F000664FD312FCFEC3A6083E1FE7F3590078CF
-:10250000F15AE68FF198BD6DF35A201E63E0D18E2B
-:10251000F779247AD085FBF9820678BF5366F2C535
-:102520008EDF71AE5E01E44BE36D04EDD71D3C6EB2
-:102530006CCCF72199D99B7B383C3F7447BE27C3AD
-:102540007E53756131DA45241C02F9BD4308A79614
-:10255000D02A2F66CE0A9AE570B62FB24736ED2BF9
-:102560008CEB62F19E6D329357E3B5137D69140FC6
-:10257000D5B98206E10463BEFB2BB45C9093FB05E6
-:1025800001D7BB3A57224526BA37FAFB0F59E4FB6D
-:102590001BC9E576828E993C48BF422E02BFF624C5
-:1025A000F18424CAEFFBB2C81E42ED8F7D40972014
-:1025B000177E9B827162C3BFD9C8D73B1D8802F2C8
-:1025C00025DEF2C540FE8CE4F774F0FA1F71B856B0
-:1025D000C8E1D765DC57E6F15712C73826A41C01BD
-:1025E0003D6E732FBDBF8A3EEF9BF3FE51880F7E79
-:1025F000F89C5B03B836951DF39BF148EAE50FCCD8
-:10260000FBF143F2E6540EC6C5FE8744DE96CD725A
-:102610002830E884F6FB046D33EC5F47DF9090FFD1
-:10262000F609B12918C79209FA05FB6E09627E877F
-:10263000D1CE17B2F277BA7B60FB2A9877BD3314FC
-:102640004DC217BF4ED12CFB46AEA0B57D1074E62F
-:102650000C56D6287D96F07987645D02386690081E
-:102660003E67110D9F598EC8E7308FE9A4370BCA1A
-:102670002D29E32E61FB077F37BC298E7F40BC19D3
-:10268000F41A9C53847090BBC4D0440DBD490B9D7B
-:102690002F74081CBF0ACAF3ECA1FDA98697F202A9
-:1026A000D80D8B93A8292807B3DD0C7F8D03273025
-:1026B000BE1B1C472C71F7F67A11F960DB5B6C5F6F
-:1026C000EF647DC1E649B47E05D1EEAFCA1F3E0F6F
-:1026D000833FB629E1D464FB53C6D3E00BA3BC7996
-:1026E000FC0D04E4D0BF8FBF01F38EB2DF726BE04C
-:1026F0007754FC6E5733C8C5F6B7597EC5514F6441
-:10270000AE634642CEB4DFD2301EFC20B72F5C0E43
-:10271000EFC3B9B1EB41DE9DAC5EEBC2A97B59DEE4
-:102720004BE33DDAE6C9DAC8EBB3A371F4FD1B63F2
-:102730005E3B605EA3EC5F18F332D6EB64F5E2C15A
-:102740009B35903385A99124ED86E4C9158B471DEF
-:102750007F07D72B74FE4BCDF439AE51C5FC16A3C1
-:10276000BD315F7B7BFB7C13FBC0E79617D4EB206E
-:102770001940EFDFFFF3B81FBC82A2312C819EA667
-:10278000FCB912E099491AB04CE4DE2CB06F0C7A17
-:10279000DED6F14416EA0539968FF95DE7385E3BDF
-:1027A00009872B80DF4262C86CAF18CFD6213A8FE1
-:1027B000635CD5C5E58098724F30199E87FACFB516
-:1027C000F2FF4642989C8F2B28E72150A8D272FE38
-:1027D0002152BA9EF6570F49A1749C0A99C543A687
-:1027E0001FD27A24165795EA7C263CF2FD0623BEBA
-:1027F000DB4EEE21AA067E45491F5437F8F480339C
-:10280000F2A003F2F0821AE67B3A021181EDC7B121
-:10281000FDA1226E975C262D55C02E692461E5022C
-:10282000E0DB23126179788CAF5DC63E18E7631751
-:10283000E763CAC1589EC4BF3FCFE96B2FD8276852
-:102840004F303ADAC3ED93AAC1C1033EDAAEA8BF56
-:10285000BB12A6F32CD82B2EB04F42F8FD7B60AFF5
-:10286000D0F281B47FBFF2028A979DBA18025CEF62
-:102870006ED2193F34D5E3F74612F5AC06B9F4B081
-:10288000A8029C9D0FB7487E5ADEA50818BF78B8ED
-:10289000A901EBFB4F7BE2E06FEE52E202D8232767
-:1028A00043241405B8A97B04F39AC4E751F14E3FC1
-:1028B0006E973F11FBE8F7F7D37A5B667B709FCC8E
-:1028C000E0AF498D83EA95C0578F1FD35603FC3381
-:1028D000D6E8507F63A800F7299EA4F88275DAB97C
-:1028E000F5A3ADFDF4BB5FEE5C0D7EF0E4BC456886
-:1028F0000FF9957FBF1DCA7EF5E97FC5A7F2A36FCB
-:1029000082BE9E1C132DFBE77EE5E777C2F7CA81E6
-:1029100050552AED67CA91FEAE2BE8B33DB456047C
-:10292000124F4DFF23EE6BEC17D4AF77435CED46AF
-:1029300027D2AB7E546F0676749459F320330F4739
-:10294000206D818C3D48F14E00EFBA0CFDBEE7C80A
-:10295000473A0BFAB3AAFCB4FCC463C77E7A05FD00
-:102960007E60EB1A948BAE8765B4C726FFC75AF218
-:102970000D939C703D2627CD2B7DCFE1627CF4F03A
-:10298000E2EE291A234FE0BF298F572928270E5B33
-:10299000F31C8C7DE11E1279CF81F4CCEC135965C8
-:1029A000FBC8B0E705FB8964BBC8F8241CF198F3A9
-:1029B0009F8B1E12C3C9E2DCA71C32CEAB2D56552D
-:1029C00004EB209FB903F7C948B7757C633C3AFE16
-:1029D00029B37C935506571EA87EBA9E7DCEDF6430
-:1029E00001FCA71A0C3D15473D75B0448C8FA7F02C
-:1029F0003DF0A01883A4CC03D54C6F6D9259BEE076
-:102A0000265E7EEC348909F9093E9ACCF9EDB1874E
-:102A10004566CFC508EA3972FA0CDA175EFE3DBD8D
-:102A2000E43505F727A2BAB762266605F21F13BD83
-:102A3000501C5D14F558E4ACD8986E59FF3C6AB14F
-:102A400058F3A90B12F52590E34714A0DF93D46F38
-:102A500005FA9DC7F789AA8C3C4CE9F47498FF7677
-:102A600043CF1A7933B63CE9C71B9679205EF8A2AA
-:102A7000413FF50D3AFA3FAA0BC733F6098B6E0BAF
-:102A800047417F3A72ADF9D315B6FCE879B6F2F951
-:102A9000C6574A9DF638EAC62948079A1FE55521C8
-:102AA000C7F3E31753773E75789C65A85F1E4720F0
-:102AB000DD7E5CBF424E40F7DD25D5835FE07FA021
-:102AC00034CD9C5F70B993D9DD077FEB2260E7EFCF
-:102AD000AA52309E69E4753AF8B8B54E0DEBED7A1E
-:102AE000F00E05DA77060ADC80AF0373967B30FFC1
-:102AF00083E7A71A72B765CEF22B6F01799829A2E6
-:102B0000EE69CF6DC9867DF907AA14CC3FF5A70CF5
-:102B1000F41EA065EF93CED023F4FBAE8AF81273B7
-:102B2000DCE60E27D35FD73BF93ED0466BFE06E5C9
-:102B300083EB9D901FE66DC07D4B51E179BC36FF64
-:102B4000DEC0877FFFF562BE8F3D0B7CE08F32FADF
-:102B50008871FAD8C1FDD38741FEBB806E98FCDF37
-:102B6000C8FD537BBF13EBC3FB9D6087DDA6964278
-:102B700028CABEBE13BAACF6447ED42AE7C6DBE947
-:102B8000BE21DB523FA7BEC0F2DD17BAC0669FC4AC
-:102B9000995E236C7D3ADDDE0920B74BA9DE6576B0
-:102BA000862A86CDFB2A36BD5EEFD09B9CE761DF8F
-:102BB000F853C20DB03E767B7A035F9FAFCAFA3AF4
-:102BC000E70CF4DF36C093DAC73C5FDD6A7F0C8325
-:102BD000935038A78E0AE783E703E7D9F6D9ECFBD1
-:102BE0006BDF94C25B5FA1CFF254960FD9EE63FE08
-:102BF0007C3BC45169F9C79C0E9F764AD8FF5E3E64
-:102C0000DFF2145A3F097F1BF1D5E721F106EA8D67
-:102C10004D9E670916107ECF49FEFD7927DBCF2E2A
-:102C20001F3FFA38FB601CFADCE8D07FE434C5F1C2
-:102C3000DA9CFA7F9ACB7127DB7F1E5A179E476971
-:102C4000D8637738F43E73FDC4D32A378D7D904C1A
-:102C5000BE9E3EC2F8EFC525CBD64DA4FCECCCF50C
-:102C6000A2FD93B9A46DB5E887FCA37E15FC814C49
-:102C7000BE8F4F1633396AECABA7D758E5AAFDBC17
-:102C8000958BE7C5BBECE76CB87CB5D3E348F2F5B0
-:102C9000774EEBBEC650FC7A04BAB2C7AF1BE15701
-:102CA0006667723B389CBA68EAC8F4F872D3E0A64B
-:102CB000831313E557E0FC4C523A60FB89FEFD7F1D
-:102CC000AC595C06FB762C9ED6DF142F7F676242E0
-:102CD0007E85E7A6BD0871CF70551ACA9BDAE0A7BA
-:102CE0009B0E527FBC4EEF2B7FC734CF7E95423B6D
-:102CF00061143ED11D9F9BF9EB4981D14F3B1FEFE2
-:102D00007E8E4FBB1DDD29465DD0EF2764401792B4
-:102D1000F8B5E679B721DE06BC406723CD3BE46217
-:102D20007CE59FDD1082389DEB8C847CE01A6FD8A7
-:102D30002D21B45BA6BBD2D8B90F6F01EEE3513F92
-:102D40007DB00FD6C1CBF2FB0DFDF8B1114FE57A86
-:102D5000EFF63456DED0C4E2C7AE0317BFA9D17672
-:102D6000BEC30EE2A6EFD751B90E71C02E6AC7C31B
-:102D7000777FD90081387A2BAD1F31F9DDADA14ABB
-:102D800015EC84B6E25245A3DFA5A9655896F34B2E
-:102D9000D54A3AE605AE6FCFCF843878A18879B5A9
-:102DA000C5B4DC4C4DBA54978AF37BB9E81D2FD8D3
-:102DB00067A9E09CCF48ACA7A32CA24B141E475098
-:102DC000AD845C8C21BDCDE98CBE7F04E2254F0A29
-:102DD00091992E3AFF97F9F9AB4E6743D11AF07BE0
-:102DE000E4A80BE2078D0ADB87007A689B9E807B54
-:102DF0001EC7AF938F3BE407F1F5FC441E88426A7F
-:102E00006BA748EA93ADCF152E26E7DA545D1D95E2
-:102E10009E54F9734BFEF45CC64FCE00A5A724F177
-:102E200047BBBC26AE709D2B3391AF441756453E31
-:102E300025CCDE33CEF7BCE3D4AF75D1797CCBCBD8
-:102E4000E5586E3AD2297D5FE9F942729FC567F66F
-:102E5000CF2D7BB50AFC927E07C68BFC13C8BF84BE
-:102E60004DF2F6900B836EF4C9ECA4F5943E629398
-:102E7000595C8200DDA450450CFB907962EC917C9A
-:102E800080B7A77A02EDAF539E482DF3443F1579E2
-:102E9000CCFEDF54E9A937FB01EFA5B0FD97B5DE05
-:102EA0008A67010FC5DE5825BACF909D39869D9F50
-:102EB000023ABE502503820872304C98DE0C294C31
-:102EC000BF56A9705E4A201172266534FD683D57D1
-:102ED000F5941C6BF1003E022CDEE5DB2A6032A08B
-:102EE000D4ABC73DB44EA977519B8BE98B2218A771
-:102EF0006FA6877869FD4FFB9C681FF6FA7264C065
-:102F0000EB3E71D97720FE34F82B17E637F6FEE555
-:102F100002CCBFEFF55DB200E476AF400E51654FD5
-:102F20002A4EE5F064439202FB7CFEF93A817D8EE5
-:102F3000C1174908F2831DC19F97BF331D279E22E9
-:102F4000CEA6EDDCA4CB4DDB853EF77C3C8FD2D505
-:102F5000B3DED22D1791445CC588A754A444B603B0
-:102F60009CED637E5D0F7CD345E194D07ED58300DC
-:102F70007769A688F14792E98D4D8478D9A14015EB
-:102F8000E48F56C825981AEB9FCFD6FBA827F238B6
-:102F9000F453A5D655417CBDEC888672764170F518
-:102FA0004128CF7C8B95DB9D8C5F205E444C72B7B3
-:102FB000E2D4389C5F2FA793B6A0DEAF0BA3F28DAF
-:102FC000EDDC81355FCE4C0790E76EA28388C34C61
-:102FD00007B3291D4C35D3812E9C0F1DDC8BCAFAFB
-:102FE0008BF08FFE66959088DB0DE783D54A7AF1EA
-:102FF000707E31E0585F961E00396AF0853AEB1E0C
-:1030000094ABAE1B9D61F0D70D3E31F8E353B7038F
-:10301000F990F2C9551EFA5CECD52E4BC627E08715
-:1030200098F9E19A11F8A6960C1E0CD046B5328993
-:10303000A65251F2F2C5EF158E33F1811D6FB573B3
-:103040000572CC22CF58D9845775E87CA374EEF86A
-:103050007F4DD6DA03263EECA07E0818CB5D628851
-:10306000805E29F52EFB14E852AEF97E10FC4187F4
-:103070002B5C8F79B3B33E48B999D2E5A763440D71
-:1030800026DFAE2D7B06F9F9680A01FB64D3CCE597
-:1030900018F7FDF496C878D013EB28FE8FA15E8E4A
-:1030A0008D15310773602CDB6FD782EC1909B2F7ED
-:1030B000847F8FF1B2CEEB0D603DBACE16F9B8DE4B
-:1030C000CDF6BBD6BB99BE59E7EC5680DF06F315AB
-:1030D000D59CEF3C4F62766C89C2F79F4EB76A1061
-:1030E0001F2951989ED9D2D48BF6C7BAA6BDF8CC69
-:1030F000A88911C8A7F2144535D8F756FE3A5F7073
-:10310000001F5FC0F667E17DB3C9FECA51181CCA33
-:103110005FA508F0A7D212D5D24D7256118548325C
-:103120003B7AA39BC55F941682DF95FD0FE17E7607
-:10313000466148B809CA2DDD2404F1F3387B1F2805
-:10314000D485AF9BFA0DD4F45AF45C2D5D82D45231
-:10315000B49EF0BC4BBBE6C1FDAFDA40E51FE569AC
-:10316000C3E9087E8E99E8C180DFD8875DCBFDEF8B
-:10317000AA0205F9AFBDD1D903AAF92A85D9459F7D
-:10318000042A473D2F00FBAFD472433F179EB00F78
-:103190001B9DCCF661A10CFBB0F0847D5878C23E3B
-:1031A0002C7C877D58287FAF49C732ECC74219F67F
-:1031B00063A393D9FE2B9461FF159E7B9BEAF1F9E3
-:1031C000E3A606FCFE7C532396E7B9987F438AA2C8
-:1031D00041B097BBEE74EA9067D3C2D7EB805E90A4
-:1031E00011A2EBEA0EB03881FBF00378DED91D1492
-:1031F000316ED7117C807C8D3EBB66F8BA20EEA183
-:103200003CE3C5A75BDE42C01EDB2144EB4988904E
-:103210005BBA4AAA646A2714065757A6D3F2AAAE25
-:10322000596D907738496B0E2D531365CD57BAFC05
-:10323000FBA6F2F8E21ED913023CCF6903790070B5
-:10324000C0A6D9BD5D73AB9A0BA9DF54400D159094
-:103250006BF9CE18D0F3D761BD2602FCCCBEBB8A79
-:10326000B40621AE315E7396021FD2FA7146FFE7B3
-:1032700056BF45D1F0BDBDDD68F5C4B273AA47A401
-:1032800051FA83EFC228FDB49356B59FC2BE0164C4
-:1032900006D8476EB6CFDBE560FCDFE566CFB7DD6D
-:1032A0008C7F7FE8AEAC74D367A59BF177973B5CCE
-:1032B0000DE74D06A78A18DFE975D02EE0F04163CF
-:1032C000FEEB702EE88E9FC904F60F1EE27430717B
-:1032D000BC8FE9E9BB15D4D3978FFF6E5B3A2D4FB6
-:1032E0007C341402BDBB81843C4027D18D22E6A1F1
-:1032F0003C5D3621BD8E56BF70C673E9A07F3E553A
-:1033000098FC89717FA3B9FDE6F11097FAF4552670
-:10331000FF7672B9D3E3E86FC0F59CE1457B853A4F
-:103320000C688F340765CC1F12B3D8D3E950FF095E
-:10333000EA39A9C28F52789C7F99A560FCE3948BEF
-:10334000DF6FD18F768AD31D51D3E8FBEEA888FCBE
-:10335000DEAA7A6260576FF096E2B9D268B18CE764
-:103360004B3614B3F8698AEFBA18D827F7F7B9992A
-:103370007CF02A983F1A2BDE73A832004F51057E4D
-:103380008FE98BAA11EFAAA8621E2AFD0DBFD707ED
-:10339000F03CCA06C2D7A55EC4F374ED633EFFF9E4
-:1033A00045909773931AE2770E609E379A5C22ECF1
-:1033B000070DEE4F0178BE6ADC5730D09242EBB772
-:1033C0002D5343B00ED3D4CA6AC82368572BD1CF2C
-:1033D00049995AA5DC887268E83C06DE8BD1562CE8
-:1033E000631E117C07BE246DE4209C87CFE1B22CC4
-:1033F00025AD5400FBAABD06C37C705EC19257DEAA
-:10340000967E259E43926AD311CE76A22B503F5AC8
-:1034100023A3FECBF12A71B037728C782E1CB13009
-:10342000C51B326EB39ED3C8AA972DE7C2C746AC60
-:10343000E54C1E3FC8B49DE7F85831F6C7AC78B2EA
-:10344000CF3723F0481AC09B010779B5E1F3D912B1
-:1034500028AD8379E6A81E843BA8B65480FC1A4B9D
-:103460001A9A81EECE1B5E1B9CD38ADBFA61DDA724
-:103470006932D1E8F81791C116E87703A7F3AE7C5B
-:10348000AB3E7E48910C7EBC10F8717CA348A2A68E
-:10349000F1210E19358D37A12BDD529ED89D6DA9D6
-:1034A0003F796B81E5FB94D80596EF17EE2CB59428
-:1034B000A7F6CEB1D4BF686FA5A55C12BFD2527F6C
-:1034C000FAA14596F28CFE7FB2D49F757499E5FB04
-:1034D000C503CB2DDF2F796F8DA57CE9E05D96FAD2
-:1034E00086BD6ED78B13B9DD72BE76BA0BEE89B08E
-:1034F000C465AD7E80DD8E57FEDAAAB5805CF33BF5
-:1035000091BE65D0E3B4BCE64EE64729E5210DE463
-:103510004A0E97A3D93EBDD40DFBA97E05F581ECDB
-:1035200065F564EF02B43FC66DA5F2683A589B6436
-:10353000E87B0AC8E5A66879A129DEE456BBF16CF0
-:103540005685BF1AF7378CF6B2AA93880FC6D3D820
-:10355000F96AEAA5423DB746DB9BE6B54F14F10890
-:10356000F420F5F71E31F97B23F977767FEE5CFDC9
-:10357000B77122F1E0B90221DC00CFE286572B219E
-:103580001D98FA75D701FD6E7286EB7B68BF9B0AAA
-:103590003C6C1F94FB755DF9BDC81783F932EA17BF
-:1035A000226BC5E6785C33D74329CAD3E85752BCAF
-:1035B000A3BC35F0BE411888B582DCB9D383F27064
-:1035C000DC7FBB5E03FE520A941C85BE0F1D70EAB1
-:1035D000B0BFB485E3B5402DA984905261B06E3F71
-:1035E0003C2769D4CEA0CFA2A2CDFBE179BB9BE55D
-:1035F000035F10FA7E25C812A59CD97FF23467AC10
-:1036000085F623A9148E247E85F194FC5BD9FE45B2
-:10361000A1FC2ED01B58F567E8142AD215CCF77000
-:10362000031D08F844FA7107BCA837DC70B815CA46
-:10363000B21083FD3FB04F611FAE227D2BAEBB6148
-:10364000B7823D1B617E6E33D057A0C6BADE29CA51
-:10365000F7104F6D028B7B77A569872BE9B85D99D1
-:1036600005E9106385B8489D49DEACE7FAF49F3D53
-:1036700022CF7363F2E6CFD0E78C84BD43E97FAB02
-:103680003801E0EB2620B7DCF77413A077B74A5770
-:1036900013EDFAA816467DCAECDDDB394C55054B17
-:1036A000707FFFE34029DAB7EEC67D49F1E71E904F
-:1036B000883E7D64BCFA276D437D4F0A9C1AD8155D
-:1036C0008D9A53EF49220FA6703F64DD38E33C2BFF
-:1036D000CBEFE9E2F830E2A14371461E4F33E28CB2
-:1036E000463FB767968E1DCD1E7753FF32628277B5
-:1036F0001D1D07F0D27EBAAE1AF12013761EF72FE9
-:10370000C53DEB719F95F9495338BE4B387EC7399B
-:1037100009FA09F3216E92015EED55D5C097469CDA
-:10372000E537606CD17AA12891585CCD61E82DF124
-:10373000CC4508B3E634F2C3D0E4657A8DFEDB07EE
-:10374000E7C6267459CF654EECB696276FB596A797
-:10375000C4AC656A351F01BB006C348C5BECB47E75
-:10376000AF33F603AAD83932858E7C86E95FCBBDAC
-:103770003884EB7F238F2DAF375E01E23577AD556F
-:10378000AF66733D9F6DD39FA53E09E30915870280
-:1037900007C17E34E23E473D9A259FCC88DFD8E5BD
-:1037A000B9E7ADCD847E41BF3CE262710C880F7FEA
-:1037B00096C7E325B93C5E328EC74BF258BCC42194
-:1037C00069AF2C1530FFF3B81B8D97868B589C86FC
-:1037D0009DE7FAA85A7E51D0D87811D378DF2C8A89
-:1037E0005ECED010CB827A46DCC4880BB87D7A25B9
-:1037F000F0EF86D06B0D07289D54FECA45A09FCBE5
-:10380000A4C3879A40BEE5C998B7ADCEBAED3B1EBA
-:103810008843C2775AAECCD7C6221FFCD481F1812F
-:103820004E4ED7C6394423CE92E2617691CB63D80F
-:1038300047510FCFCBF780BD7BE14E2AA32DFA8EE7
-:10384000C5F38CB8DDD45EEBF75E2264A8B0EFBFA1
-:10385000242632FB4AF75698F21A2FE0EB366D69B0
-:10386000FC81A5B4BC9BC44AE1BEB9124E1FA18322
-:10387000D6F3AF638880E79FC61C9142315A7FDA46
-:10388000F3D6EFC5B6F3B117D8CFCBDAF6857C12F5
-:103890003971231D6FA3D620801CDDB894DAF2B4F1
-:1038A0005CE8E1FB4593C824A0C3CB246F280EF845
-:1038B0007D43C2FD2DD7DB93DFBC11F4FAAB2CEFB7
-:1038C000489DA06D8638B2FA7309F5949A424A4A27
-:1038D000BC897DA47F3B1322B02F62C4B59EA2EBAE
-:1038E0000A7A6537F5CB0B1DE067AB58EEA57E393C
-:1038F000949FA57E393CF750BF1CDEFF90FAE5503F
-:10390000DE4BFD7278FE98FAE5F0FE79EA9743798E
-:10391000ADB7A212E262FDB43ED08BA7648F3281B4
-:10392000C2DBA93854A00FBB1CAAA8B85D594C49EA
-:10393000EA2B9D4FE3FE45E5652C4FBA72FDD3B8E7
-:103940007F618EAF99E38F89F8DA8060C4D720E475
-:10395000F93BBECF3014678BB038DBD9FBD18D7EFD
-:1039600030AE39AC1F1EDFFCF0CE5F3FD14A3FAD19
-:1039700098F14097A700CE6D34F0789E9117A35927
-:10398000F2EE57EC69C6BC1867D6910658D73D656C
-:103990005ECC17713A222AC85BBB3F67F871767B11
-:1039A000DA78DAF59B8FDB1546DC749383609E74BE
-:1039B00054A0F604D8174DB1F2771C23C7535FF714
-:1039C000F0F34336B930743E80C77D5C60CDD27968
-:1039D0003A058E0F9EB78EA2B180C5F5CC71554FBA
-:1039E000610C0FA57BBC3ADA7502B5F7D0FE532304
-:1039F0004188A375C0798024F38B7998FE6BCE72D1
-:103A0000A2BDD191C5F240AA72434168DF9A353315
-:103A1000683E1F609C5F38E89BA90C98FA5BE32B1B
-:103A20001855FF49545F6BA3E86BC9C5CEEFB4EEE0
-:103A3000BF588173195DDE65FDE047770503187F88
-:103A4000EFCB9A49064CFD4BC1D9787E43F2327BCD
-:103A5000580A2A680FCB30FFE2447DA3DE3D1E46A4
-:103A600027949D31BEE8F676633D971CC67B235CA8
-:103A7000015099F4A9B2FD384FA1481493BC30C647
-:103A8000FD570F93975DC51115E22C5D4159837366
-:103A9000205D5A29E2B995E3B935CFB0274268C70E
-:103AA000ECE17836FA69E57180D67A27DA73E1C6F7
-:103AB00034B52A03F37577C1BE5697B745817D4962
-:103AC0006756D9A8FDFE84CBEB91FB2D1953351D0C
-:103AD000FBDD03FD3A7DCB54E8D731C2B9A3C31C4B
-:103AE000CE2F6AB7DAF7F128B441733E8AFDE9E3D5
-:103AF000F6A7BDDD8AE20127ACFBBAC7ACE7941D8F
-:103B0000849DDB5AB97735F2F926B91FEDA84DA788
-:103B100085A4E7BF325204CE6F43FEBDC50ECAE195
-:103B2000FC94C3BF03A981BE28895BED96E987ACED
-:103B3000E519FDD6F2ACA3763B487F03ECA0C55C4B
-:103B4000EEF55379CF92610665C047381AAB00B8DD
-:103B5000EB486F33E44938789C7C31D77F0BB97ED2
-:103B600074A7B0786F4EBDC7E27F127ECF5F2EEF95
-:103B70003FAFEAE0EA3610B261C3AED2D06FCDBB40
-:103B8000E2D90A149736FBAA4EB79EE35F68B39F4B
-:103B9000EC765685DC83F9B8D9B6B886B19F0BF3BD
-:103BA00084FB0CECE39FEFB8467F908705F2CDB81D
-:103BB000E705EF15A6EDF3E4B810A278CA6E60E74A
-:103BC0007072D612BD27091DCF49617C310C6FD1AF
-:103BD0007988B7F9FC5DB697DDCF955D25C5343A98
-:103BE0007E767D2FDA038B6EA3F3413BFC0CE6C19E
-:103BF00018F5D3D37AF13CD2B61A81E7E712B46B49
-:103C00008C75DEE665E707EB2E156222B46F28C0DF
-:103C1000F111AE82C4FA523C1D637862F986D75422
-:103C20005BCF39D6D9EC17831E16DADEFFD6C3F682
-:103C3000C50D3EF8F0E2A393C651385608DDD529EC
-:103C400013CE5D5F9AF8C37106F8107E1FC3525FF2
-:103C5000308F57F9818AE73DD206B6134A92B529CB
-:103C6000245A3517E4CFE085022D5F9BF2BDF6AEF6
-:103C70004BE1F8F6E0D360E4B95C3FB8AC3A2F51C1
-:103C8000F6787E82E5001F07B616D97A9BEE7DA1F5
-:103C9000A8DBCEF3E337E864B304B9B5A2BA39942C
-:103CA0009F68970EED8451DA85C96639493BAFD1DB
-:103CB0008EA2AB03EE75E2F3F2F0EF2287C73CBEB3
-:103CC0000C7853352F9E635C20AB9097F165E1181B
-:103CD00073B67947C866C784E1ED28D8CD06FC6283
-:103CE00072F863F0DD3CBE6314F8FFD6F8385B7FF2
-:103CF0004EFEFDBCE1A3D55BC68C3C5F80CB81F75B
-:103D00000D695ED1D4CFFD7D7FC2B8B87C3D09413D
-:103D1000C84B76E82AECE715AB0FA27F2FA755A971
-:103D20006007ACA365B003D6F57663FCBBB8F08141
-:103D30002E20FAE2B887803C984AD4B4DDB4DFA9DB
-:103D4000AA0C27AB887CE94111E2E9E46A82792375
-:103D5000A97D1E763F50FE9C47C1DF4A4B53703F02
-:103D600023256DE6A3CCE865716603FE948A23954E
-:103D7000107F97EB484800B88418A900269B427032
-:103D80007FC3A3EFF9269C032032D34F78470EE878
-:103D9000551E6F1FCB48867439D53ACC5FF9998C84
-:103DA00071ACB170051825CAE2E2F4CD004F718400
-:103DB000762000FC2C5E36352286E2B4FFD213ACAE
-:103DC0001DF9053B3F427D9325CF79137835E4CA31
-:103DD000581E870F2EB5C6A9C9209D336D5FFA8B7B
-:103DE000458F439C62CC30F9CDFC760F8733F504C8
-:103DF0000943FF811AABDEF0F0FC6D8FEDFE988B6E
-:103E00007C0EEBBDCF76FFE1DE30EA011709294ECB
-:103E1000B42F96A2DD60F825DBA022D8E37984DDFB
-:103E2000B76B6F3F93B52741E6A7B83C44514AE9C9
-:103E3000F7E51E1DF30D5DB44CF12838899245DF7E
-:103E4000678B2CDED22C1019CA89F1E29867E052F8
-:103E5000AE6A03FB65BF321DEF4533FCEA5635847D
-:103E60007910A4A8D262371BF95E6B4A0AC6C2F762
-:103E7000D43143712715E8724D6621DAD1FE8C8169
-:103E80007F0639FB598A6F81027215F230E6C0B5A0
-:103E9000B4AE8E2895BBAE53394433D9672EB901E1
-:103EA000E36CAE53E32CEFE34DD673D4BA57AC8238
-:103EB00071B2BD1A3BBF43D436685741ACE7A55D2C
-:103EC000A7B22CF67AA2FF5CCBFB38B56BCCF7FB24
-:103ED0008CDC7F0AD18ACCFD4F18A1FF49B6FED5F4
-:103EE000A4FD27FACDB0F4DB2EB3F86B34E0497AA9
-:103EF000DF64A9B772BC77C6C8FB03255E16D7EC92
-:103F00000C36E0FE4025A18C4FE965DEE963123BEB
-:103F1000C74BD07E23B9D6FD814A4EC722A50C3CA3
-:103F200017205BEF2D2E27F67B8CAD76D111086E16
-:103F3000517A177D65FDB84FF0272F9EF31BC96E90
-:103F4000EE6F22189F2E4F19B81DF6C1AFF48E7375
-:103F5000B607319F19FDF925DEE90BF8BD9F2CAF9F
-:103F60003920225EC29563F19C96D14FD8492682B2
-:103F70005C0C8B2C0F027FE8F8FD99D98FAC4F8237
-:103F80003FFB39F73A5D282F34CDAB1FF20ACDE362
-:103F9000CDCFE9914CF308BBC80C1C8FDBBB43E3CE
-:103FA0008DF962E3BDCAE359C678750BACF3AB7308
-:103FB000AA38BF3ACEC7C678AFC2FC92E0F7ACE3EE
-:103FC000F1BCC9A1F12EB7CEAFCEA5E2FCEAF83D17
-:103FD000BB43E38DF962E319719D4E674303D0E162
-:103FE00048F11D23AE734DE72E4B5C874477CDAF70
-:103FF000282464B3C0E4C7F68DF33AC0FFFBB8666B
-:104000004D11EA156E5FE37DAA541F2F9419BCB5BC
-:10401000B9DE58B3098FDBA81CD127C3390985C085
-:1040200081323837A1E3398A203E1FA1F6BA8EF9D2
-:104030002545F8FD89A610967736CDC6A7D14FD174
-:104040006C76EFD794B94252BBFD752FB3DB37675F
-:10405000A9D77F1DF45B8587E5FBCEBE84E8263BB0
-:104060009A1AD6FBDDB03F741D29011D39692B83D7
-:104070003B50352606EBEF2939D8DF047150D9A122
-:1040800061BEAB96FCEF18BCEC65FEBCCBC5DA9309
-:104090004BD8FDA7B55C3F11A906F38F6A17A6613F
-:1040A0003EC2A2C5BA4FA5785B2C086F14727D077B
-:1040B000E79EAEE54B6DF71702A079E87A05742903
-:1040C00006F7C35D9B7B788940FB0DFBAE413F2328
-:1040D0004C1BA6D37EAEE5FAB6E26D17817804B923
-:1040E000CC89F26BF162AB5FB0D91D57C1CED95C00
-:1040F0001220CDB4DDA21AEB77978BF155D876FF5D
-:104100004BED59EE8331F26DEDF8B1C74D0F79F9F2
-:1041100079251E1F3D498AEFC7335F3C2FD7DEDE6E
-:1041200088833679997CEB7432F9309C0F183CEF18
-:104130007139B8ADE928C6D10CF8B2E59800F23E65
-:10414000A7FEA825EF9D22168D6A639F8048BB4B72
-:10415000500FDBE6B34DD89D35DA7D50D9447E77DC
-:10416000A088FFDD0261F8BCFFE0B5C6854F92B9BB
-:10417000AF149264FCC3E2C1B587A450B396C08B60
-:104180008187FF6B3EDA0278A7CF57E67F52C6FCE5
-:10419000C05CCBDF0730CE6F5D335496896CA2E7ED
-:1041A00085CB9D3AF357078B812E8F5C9A12627FE5
-:1041B000E782DB41F15F8960077DF9FEF53C4B5EEC
-:1041C00033EF77A4F5B2E7539ACE1B27EE3F80FC7E
-:1041D00097E65010ED814C91003F65433E9E9F7DD8
-:1041E0003F66B55B2DF978AD7DBB04881B6E87FCFF
-:1041F00044D339BB9CFA5EA11DECBBE6188B43C4CB
-:10420000693D0A776E7D5C682B4EE47DD9E57AEED8
-:104210006DD67CC1F6B98BD5DD1AE4D55476C3C50D
-:104220005FEBB6B23897517F28DEC5CF9F3A48037F
-:1042300081F3179297C59B83FC5E8EB3E5EF7E26D4
-:1042400046D5FC7CC8DB8D291574FE0F65442A7C9D
-:10425000B4DFAE4069430FD0A71CC23CEFA58D77F9
-:1042600087214EA866248F832FE5F6418D8FC5D315
-:10427000DE72C4F3206EFE8B8CCA1ADF8C24F51B11
-:10428000EFC5FECA47B86FFE261FA3CFED62727955
-:1042900070031FE72B2B44BC47C84D7C783ED55D8F
-:1042A000D83D1BF0B17DE5B650B27396D3D5C85753
-:1042B0007DA638ABBB90DD034048EFC530CF757F9E
-:1042C0007EB8F7193AEFF43F7B51CEA64BAC5F5363
-:1042D000FB9BCCF331DAEFFBD32FF1FCFC3E7EAF3E
-:1042E0003A89165C0E71F64D4619B600A09C3654FC
-:1042F000BE1CFCCA44F9C70BE0EF266D021AA5C428
-:10430000F7DEA6C3A887370984EBE95F2CC0FEF867
-:104310003DEE2FF2EFE5577EF0E8FDA00F663AD1B3
-:10432000DFDCC4ED1D03BEF77DEC9CC2FB1C5F23EC
-:10433000E1B393E3DB0BF80C9C173E3B93E1634145
-:1043400040EF023CBB21138482E0FEB3B216F2AD13
-:104350001F6A22E1AFD3396C0FEDD905678A68FB7C
-:10436000FB93ADC70F33F46E1FC2730CE7E72BF45A
-:10437000860015EB6611EC27091C5B475BD7A96922
-:104380004CCEC11D63F04CE7F6A5E4EA0F42FE8275
-:104390005AF66FB7AB54CE74E4F72F4916277EC296
-:1043A000CFECFEB411E2E22F70FC55A5877702DC5A
-:1043B0006DEA03E8EF39051286FAEB660F10C1D4F7
-:1043C000EE2D3F5B0F0A772FC0EDBC98DD4FEDA3BC
-:1043D000788704395F19837F9D768440FEBB2F78F0
-:1043E00004F35A7D6503C8EF280AB3195D813FA81D
-:1043F00070FBED854D6F2F00BA48970C3ABCBD138A
-:10440000E84C4A9491EE7AD259FB63F7DDDE09FE5F
-:10441000E20E276D037230DB89F68D7D7E8738BC16
-:1044200082AA1F80F90DC3A76BE051B86F60D34417
-:10443000764F4BB9D8BFE46B4097577AD13EA3EF84
-:104440009798CFDB9FE4F83AE963F6D5A63F29F8C1
-:10445000DDBE1E23D1EB6FBF38BDFE76047AFD9D15
-:104460008D5E3F21C9E9F57F46A0D777E1BD1D2FBD
-:10447000F6B244F4ADB0AF2C7FBE6027F4275F35B1
-:1044800077EB33F4297DBE318AAB19122CE79913EF
-:10449000F23EF209F46FDC2B60FC7DA2BB7C23F4BE
-:1044A0003B6BE6569063E7D0EF19C087BDDF5FF046
-:1044B0007ECBAFF44692DD93B0CBCFF2E37FE067E3
-:1044C000F546E29B5FF9597ECA487C13F70FF14D20
-:1044D000AA3FF3EC7C33C8EBD37518EB9F712E7CAD
-:1044E000F3203EDD858C6F70FE7386F30D2111E4A1
-:1044F000938E7CC61745FE159DD15C131F917BAD35
-:104500007C44EEB5F0D1A7FE7B918FECEDFD23DC72
-:104510000778D110FF87A7C13CF40BD536763E69EA
-:1045200000CFE1F690C13E17E609B3BC5C4F34AA58
-:1045300033F3A09FC0BDB3B378FB1DE0A3811F344C
-:1045400093C7B3E47EB2C8379C9F7D65F132F3FD1B
-:104550002E2FF3F6AED47039E0BD870C4C01FB6C06
-:10456000A4759ACFEB9F4ED7E7FB93D0F9D9F450BF
-:10457000BD9FE9A17ADE4FFA9F9506B04FEDFC5E34
-:10458000BEF2C77F7C62947E6EE2EBFF55DECF17F2
-:10459000E0FFAFFA93F02FE5FF1B601D4CFC5F2698
-:1045A0001424E5FF9BFC49E407E5FF9BFD7F5B7E50
-:1045B0005FE34FC2975701BF659E1DDFCF717C3F00
-:1045C000F725F1BD85E37B83FF0BCBDB0DC9F04500
-:1045D000F1BDF11CF1BD65047C3FE8C7F57F16E134
-:1045E000F7695E8C9777CD227BA09F24703C6CEEA0
-:1045F00047D1583F94A73E1128DD977FDE154A76B4
-:10460000FF116DF768B276F3FDAA917CBE1AFC87A4
-:10461000ED5779715F81EAC72793F1C797A0831F90
-:10462000F893C8FD7291C921C77D1777421CEF4BE3
-:10463000F4FF9364FDDFC9E5FAD9EC82D7385DD089
-:1046400079FF977FC670F9D7C3CF270B6AE4177E2F
-:104650008CDB0F5C01F26AC75DE902C4BB72F5B87E
-:10466000007E025EEA43E1980B97F8CC48B4DB2168
-:10467000C705B83F6747832AC07929537F6FFA334C
-:1046800047EECF0E0785EFD77E9477FA6FE0399F1C
-:10469000CFEF7CEDA47DE9FAEFFD4C6EFF0F3CF50A
-:1046A000C956B96DCC430C77B33CDBD9C9FF7EE565
-:1046B000019FCCF558F8B859FEBF3B4457ACBFF347
-:1046C000D53F14BECF387C7FC27E6DF0D9F17236F3
-:1046D0003827819E67FD49A999C3F594BD3FC3CF93
-:1046E00036D609AEC530C77DD4D421FD9D0AFD79EB
-:1046F000DB453C4755CBE549EDEC346EB7AB1EE8E6
-:104700007F3B8FC36FBFED810AD857EFB9472D01AB
-:104710001464D733BDA7DD360EE3ABD9BC5F3BFCD9
-:1047200043ED9DBD53E0EF42D071C7C1B8F3E692AF
-:1047300038F88DA9603760BC42C5BF5F9CEEEA0EB9
-:10474000427C769DD0BD6419E8D52BBCEC5C4C70E6
-:10475000F159EEC56CB1D02D09969DA57E33D65783
-:1047600053BAF1FE9473AEEFEA4E6A67CD4B150D66
-:104770007F62CEA8780D0630EE65E077F8386CFDE4
-:104780002AC20D02E0DB5726A8907AE7A37402F64E
-:104790009258D88F79535797317A21D42F19FDFE2B
-:1047A000950E03AEABFF167019F5461E8FD7B39D5D
-:1047B000B718FA3B635E26C7B0222D7F742823E921
-:1047C000BE82F1EC6C5275B80AF92355C37B193BD4
-:1047D00087F2BE43C145BEBF7FBDC4BC626CDFC9AA
-:1047E000567FE8FE91A082F61FFEFD0E131D75A4F4
-:1047F00032BF554A0BDF9D8AF23784F73FD2F2B7BA
-:10480000B0ACD0B20FCB4DB03E441D2A37E3F720F9
-:10481000AB4F54F59CF04EDB75613B79A89FF5D802
-:10482000AF7768DC8D580E0C95EFC3FAB9ACFEB9C2
-:104830008E33ECFE957E09E7FF89ACA7C2BEE97511
-:104840008D5FC3F8D2F58DB7E0B3AB49AD80389D2D
-:10485000710FC975D77F4D057FFAFA9BB6E0BEBED2
-:10486000D1FF42F03B80FF35B91AEC2567BE187EB8
-:10487000CC9BE0BF041C6D58AE95D97DFE0B679FA5
-:10488000D8D4668ADF29F077D121BF4633DD834152
-:1048900012F2F04941DF9D7A1EF43C7C9E841CA4F8
-:1048A000F4FB89B73016457AAE5493F18D31DF9120
-:1048B000FA37E63B92BC31F066BC5F57C8FF8EAE5C
-:1048C0002D7EE99E5885F93F0B050EA78FDF0BC99A
-:1048D000EBD5D2719E2D46BAD0806E6BB97F67D76B
-:1048E0000FC6B84F0A91D7013F1027BEA774387E74
-:1048F000CF156F46FF63235102F772798A09EE8B59
-:10490000057CC6BE3A936B0F7A8D7214934BC285A9
-:10491000DD28E7DC9A21F7989E54537A75B184FA22
-:1049200041A97FBD3C3805F2402341F8133EB4FC59
-:1049300012DCCF9C2EB132217F7DE920DA3FEA05DF
-:104940007093A3227FFED2A13CC28E2E62DCE6F3DE
-:1049500097209ED733542671385FD0E3192AEB4A4B
-:1049600090960B86CA5128EFE076DFE9D4CF5F6AD4
-:10497000437D16FE0CF8C790AB155CAEFEADE4E9C6
-:10498000FF02CED174B20080000000001F8B08002F
-:1049900000000000000BE57D0B7854D5B5F03E73A8
-:1049A000E695642699BC27BC721240A23C9C040286
-:1049B00041B14E78355E790CF51524C824E1119E7D
-:1049C00001A432ADB60C24202868AC2FEA833B2822
-:1049D000F66AAFF682C55BFE16F907410B2D62AC95
-:1049E000A8F840C3A3151F2511B44CAD2D77ADB564
-:1049F000F7CE9C733203C1B6FFDFFFFBC3D72EF7A0
-:104A000039FBECC75A6BAFB5F65A6BEF612CCC583B
-:104A10002E639BB566CFE8618C85BD565F7F8DB1F7
-:104A2000750CFE0A183B877F5733D6D76367AC9C5B
-:104A3000B1473283291EA83FE98E0EAB13EA398BAA
-:104A400072DC41176385DE2FC295F07DE128C63404
-:104A5000FCB65F166323A15DEF32C59E037010F3B1
-:104A6000288CDEADF240FD1C3763AD009935C2D80D
-:104A700020C61E70C9328C0760A024C2DAE079AA71
-:104A8000C6DF5BB00CCF55075BBC15CA6925CC1FD0
-:104A900081B2C7C1660400F6F258681E033DAA80C1
-:104AA0000A8D37C3DBCC34A8EFACB2F82300331047
-:104AB000BAE2F362AC99EA0DF4580932818FF13908
-:104AC000C1011E286F66AC6A2B8E8B450325308F83
-:104AD000D44B73B2EE825265897519832EFF7D0522
-:104AE0000BCCB43136D413B0637D57694E6A701065
-:104AF00095875079B525CC002F95CC1D518AE27849
-:104B00008191A706DCF171C4C7C3FB7F6B453030D0
-:104B1000D6D6F5BD84374E5503FA79485889788042
-:104B20007E4F55FFFE219CCE4267879D15033DFBBE
-:104B3000DD17602ACE47A3F7CEED53A23DE1FDA2DB
-:104B40001D4B188E77555AFA28A4A3B9DFB7BE7E3D
-:104B5000D81380F7297F7604B626E86F0EE219C6CF
-:104B60007B6845357D07CD6BD63CC666E0548A1917
-:104B700011B4CD899029E71C34BD43FDE0FD2D8C97
-:104B800033C3F581DA890CF05A57AD32B508BFEB63
-:104B9000ACCFCE41F996B6DA096C081442B613F8D8
-:104BA000DC09FFCE41BB419639DE038F6BC3FC3974
-:104BB000D587FFCD62BEF1B9F05DFD5AD3F3F7AFF3
-:104BC000F998A5E37BEB89B69278FB3755D706C6F3
-:104BD0008A7A67E8FF23849FEB35E647BA5DEF4B9F
-:104BE0008B84618A3704A606C696C4DB7BFBAFEADA
-:104BF0000CC48B191FDB05DF1D5A11088CEDDF1566
-:104C00001F7501C5EED12E8C97EEE2A1D65A3A3E21
-:104C100057EB8A07F3FC01631B10CFB300CF771566
-:104C200025C707D4237ABC3D15EAC154C6AB136C23
-:104C300016C043FD14853914C26F3AEB8BF5FC1393
-:104C4000C6E9C66BC6A3195FF52F325F14DAAD7FD4
-:104C5000D0ED030E67BF93F88902D286833CE155FD
-:104C6000F5F33C86E3F7C03F9CE7772A4A5FCE81A5
-:104C700071049B151FE3F33DA69F5F1D0B64441554
-:104C80009AF7B124743FA69FA7797CE6F1A7A0B05C
-:104C900002F9177ABFE89EBDBA7ACC1A1D1418CC57
-:104CA000D8331E77CE1FD2A03C84F9CEC1BAFA9277
-:104CB0008DCA188AEFFBE5D0FA36F3C5D915DA3D6F
-:104CC0007B6DFA75CEF96C46684A67BFD8BEC28262
-:104CD0009D650FE0393055DD7003FCF75BFBB25783
-:104CE000E3B3A55E553B918DF882F912BDFC8C496A
-:104CF000FE6208C3BB55C0DF14E6D45CD0CED5201D
-:104D0000A4CEC15C26F95334976E1EA75B942A94F7
-:104D1000A340BC8CEB07C7E76B1EF752AF9DFA03AD
-:104D20007EFC42CF8F66BCBC55DD3703E5C88138B9
-:104D30005E865C0C5E46E3620639E2C9665105E8B0
-:104D4000DCA138234FC0986A42B707C60E45BCB0F5
-:104D5000B01D44E7514F11D593F3B631F9B798A17F
-:104D60003CADB1B320CEEB7D1BABDEE64218ED5D72
-:104D7000A6935B27B22B8FA25C96E59AD00FA97DF4
-:104D80006044E243C9CFB7385D5195F3E1679D7C3C
-:104D900043F2ACC6F387814427760EE6A9662CD091
-:104DA00070DE6A5AFA1096C1D85AAC02F354330333
-:104DB0007F443DA9A6F58920FFA54E7D722DA7E36E
-:104DC000FD5537EAE89832EBE7616A5CCB32E03FA9
-:104DD0004DD0AF52D02FA5C469A61FC3751A2E613E
-:104DE00091A7148102289FEEE78FE0BA4DA63724E1
-:104DF0003D534AAC5FB5E9F99AB5103F4A3AB2BDA6
-:104E0000C33A70BD06BD567617BD2F21FC043D1276
-:104E10003F1D36D4273342B6D3FA76820533232B8F
-:104E2000F1BB750E1F3EABB36879580FF0E4413DFE
-:104E3000CE4A7C3E5C3F2C0CDF497E42BCA231A1B5
-:104E40006BBF0DE6505086ED81F4C4EFD6EAFA2927
-:104E5000EEDA6FE7BA32B76BFA4E55C17E203BC22D
-:104E6000E7F3E9E4779F4C6E3F9CF60EDB6A294E30
-:104E70008EBF3A67B6DF9A1D2F1F2B70564712E878
-:104E800001D99ED4E7596AD06BC1B9B127F7ED1D9E
-:104E9000857AD87319483276F7EAC7F7EDEBCD90EB
-:104EA0004518EB81D51FDFE77791DDC1CBC898307E
-:104EB000FECDA99D65BFD30BE5E2CE7218CB9BA0BA
-:104EC0003B7605C8EBFB1EDFD70CDF9F3DE220FDE4
-:104ED00075BA2A35828B273B34861D87715BC1CC1E
-:104EE000C90056031046E80CF5A4F92856C01CE08A
-:104EF0003B5BF32988EFC9991AF183556351370C4D
-:104F00002EDBEA53105F3FB2B30621372E9DA2B3CA
-:104F10005F266772BB43F6E370B2704A59BC5DC648
-:104F20007C2B518F582730D22BB0CEC96E93EB5BC0
-:104F3000B6332D93EBCFCEF579E1F53C2D33C17A25
-:104F40003E6059FCE10FD09EFD8DCA9E82A94CF7B0
-:104F50007E8F9EDF18AA2738353497E0AC4C6EBFA1
-:104F6000FC9E056765026CAD7E63FA72E0DFC6EDFC
-:104F70000E1FAAE585B77D7C4FB9867802BAE37724
-:104F8000B3EA1F2C87F7F6FE16B267D7F666D5C8C8
-:104F90004FF6950AD947EB347BD576800F6454DE03
-:104FA0008FEDC9713D903196CAAC4AB3209F2F75E1
-:104FB000723E3F7BE44E6F1DDA952E17AD17FBCA8C
-:104FC000A27B2D5066FB61DC0CE507233B4375702B
-:104FD000B83A93DBA9AB05BE7F20F8CC1943227306
-:104FE000BE5E0CFD3BAD618676B63366A5E7760501
-:104FF000C697804F657BCE182CD2A1D89FF97B3BFA
-:105000003DC779E1F76A3633D83DF7E0F7B908E5EF
-:1050100038D2F838B2CDEDA4F3E762FD99C771D26A
-:1050200033E647889F0732FCF767921DDE664379B7
-:105030007E8BEB37879521DD91C76D0ACAE3495F07
-:105040002BD142C05F4AA51A5955847ACD337118C5
-:10505000F001ABB4F9109FADFD72DCC5BAFE9F1232
-:10506000F47FDDEA71E33803E3C0AE26FE66B9D70C
-:10507000633BE3EA8773F90706974ECFBEAE6D59DF
-:105080005B8CF2376CA3FDD20C673882E3D3D96D09
-:10509000CA392E9735EBF0B8FD3763ACEA4F49EFCC
-:1050A0006ADFC136642FD97F529687A10CDF7D203D
-:1050B0008A1F8E3D73034EA38D79ECC57A7B1077E2
-:1050C0004BC3D1BEE17F334246BBCF6C17D655945C
-:1050D000BE026400BC44AA86219F5D6A213EEBAEFD
-:1050E000BDCCD87D9CCEE39A3CB8AF7A04E504EE03
-:1050F00007C71E1F4B72034C2B6C77F258D51385D4
-:10510000DAEB4316E687811FF4AB1105E676B0A40F
-:105110006DFFD588B70A9B467AAB846DB82E07DF42
-:105120000FF5209E03C20E81FA5CBF799D91FEF0BF
-:10513000ACD57FDC55AFE3BB8315C72FC5FD0AC8CF
-:10514000BD8644FCC4D84AE2EBBDDF4FA5763E7C69
-:1051500040893860FCE3D4AF5F1D81F6EC0F6C3EF4
-:105160008746D3B2205D27F898D8B8FA5DE3747605
-:10517000C07116184E7665E9914A07DAAFAB155A39
-:10518000A712FF3342467B33B818EC32ADAB7D0A31
-:105190008DD9919FBB6B9F9AEDABB399C2AE2A6339
-:1051A000657ABB2A999E92769595F9FF467287B5E6
-:1051B0005951EF4E820789E4C04D195CEE8E533F82
-:1051C00023FA9CAE5035C4D7C1D0272EDC8F1FFCEC
-:1051D0005AE5FB607FAEC18ECBC9E27E814D763051
-:1051E000C8E0BB4D3D9C9195D0D4EEEF5F96DF4675
-:1051F000F4D11E1E8574FC8D8DE470B2F1BA432A81
-:10520000EB078C3931A41094F42B0CA530AB4E3F36
-:1052100014B2C4E3EF9FC5C79F7B07B368D06F6626
-:1052200098F913ED8F653DD8178FB732AA1FCD843B
-:10523000F12DEA6721FE94FBE3145BD8DF13E66FE0
-:10524000DBB9248CFBE442181F8E4383F1A1BE2CF2
-:105250000AA551B938944DB06F289360BF504F7A6A
-:10526000DF3FD497E025A1227A3E203490CA25A1C1
-:10527000A1042F0D9512BC2C7425C181A037B1DE7D
-:10528000A05025C1C1A16BE9F990D075042F0F4D35
-:1052900021E80B4DA3F7A5A17A8265A15A7A3E3485
-:1052A000349FCAC342B752B93CB484E0F0D0ED0495
-:1052B00047849A0856845652BD91A1BBA97C45E803
-:1052C0007E825786EE23382AF428BD97764BAA585B
-:1052D0008F776B333DE8EF000ED7908F93ADBB997E
-:1052E000595C2F1DC8F44FC82A8FD7B35B408FBBC2
-:1052F000BAD60B6671BD9189744DD0DE3441AF537F
-:10530000BE630F0D6071BAADF39EDF9FC14A12EF0D
-:1053100037E2F281CFEFDA2C2EBF36595BFD2AF24D
-:10532000EF62E60BC3A389C35E5750BE6CD6AC5583
-:1053300089ECBB07B26CF4DD2399C1F95900D38A1B
-:105340004EEC45793239EC797534F2CBA09CDF8C88
-:1053500086F60A9B2DB4DDD7986737FAD7B4B18C9F
-:10536000E4A2F42B815D67D0A7EB055E18DBBAAF32
-:1053700098D653BF32AE7FDAAEC1F565FF7E31ED10
-:10538000DF37D9A38A15ED9BA5A0C374F6FFA63518
-:10539000753FC1F7F1F6EC34CEC2B5EC2534B18BD4
-:1053A0005AB4D12900FB6EF4BF94029FF48F0447D6
-:1053B000A74279C0D3E197105EBA35323A0DE0C00A
-:1053C0001DD19750DC0C8EB68D7641F9F27D6C0FB5
-:1053D0002EFFD2566D8C1BCA430FFBF7001BB0F299
-:1053E000B6E098740DC713694A87F16CFA000C3D5A
-:1053F00028577CD6A2C276284E7FB0E3D07E937425
-:10540000710F6B1D9B0DFFD96B99A754C5EFAD6D47
-:10541000299983BAD26733CE1BE7097AE4299857D2
-:105420002F7F54F1E8F864479622E9F018F29BF4D4
-:105430004B6E6ECE22BFE4E6544F2576D9318E797D
-:105440009ED0908FAD8427FBEA62F2C749BE03FC71
-:105450001AECD9F582EF3675DABB89F1BB43C8BFC8
-:105460007F15FC7E5BF07332FC3A9157465E781DE7
-:10547000EF17EB12D6F1CBC8DFC9EA9D12F837E37C
-:1054800079B385ED035D05FD029FF275C5D08FF6FA
-:10549000B1E0EF0BE1F5F8BF18DF462F8057A6E526
-:1054A000909C047EBD14FD63C9E48D5DEC67CCEF78
-:1054B000635DE51CF7DB7A40CEF54D2EE7F666F12D
-:1054C000E749E597903376937FC796CDFB1BEA09B2
-:1054D000A8D989FCD4DE1C839F7A82EAA94479C3C7
-:1054E0000630B2A3D30645C2B84F290C6B652A56C5
-:1054F00043A18C78EC5142FE8722B033AC407F68E8
-:105500002A8AD0A9792C75E87F97EBCD53EBD5AFDC
-:1055100037A9EFE3EB51F245D6E6BBB85F529B02E9
-:10552000F6CB5831EE783BDC0FB2E67B3D36DFA59B
-:1055300093839BBD5E2ACBFAC9F8B72E5BF06FF35D
-:105540002AC2A7735462BBE15BD9AAE0DB0E3FF22B
-:1055500079F85BCC83F64C66F331924F99209F1417
-:10556000924FBCFF5EA1D49F84A17C55769EF00330
-:1055700078526F74FFDFE3E72CB4A9703D8DF2EC35
-:1055800056314E037A48C3753A0AC63E0CF1652778
-:10559000BA6B8CD3511BC52268F702DEA2B86F0F1D
-:1055A0005BDCE467B2DB5BFCB89E993D93E63FD4DD
-:1055B000139C907D9E75E149D34A91A8D3EFFFD902
-:1055C000352EE0BF35459E542CDF0CE5F515D06F28
-:1055D000561B13E575AE91DFDCEF313DFBB9FDCD18
-:1055E000D0DFAE2CFF341C0FF0F57484FE011E2BAF
-:1055F000F9ABBDDDB307E4FA8CAF274FA95C4FB51B
-:1056000083481ECEC176657BC9EC9BA26C2EE74217
-:105610000226B36F24DF5FB47D23C63B3BFBFCEB6C
-:10562000FFAD7DF76FDCC274FEC61E0FB55A35F4B0
-:1056300067703F8DC5D94AEDB985BFD18FFE46E071
-:1056400003673F5EC6BF44FEE2E4788CD078A49F37
-:1056500051FA13D3055F31AB12413D9E5EE1B1D6E5
-:10566000517B6DEC3BD0DE83024F725DA3DC7A7E12
-:1056700010CAA52C2BEED7D19FE4CE8AB78FE58C2C
-:10568000B2B87C62621F77AB1873CB2A5F06BA9CF4
-:10569000C307B91FA5E5877C5D4EECC522AB504E14
-:1056A000F899E681FA294CFEF90DFEE4095F29CC50
-:1056B0000FE33FF0954A50E9C7A26ED8EF4DF429A9
-:1056C00051DC07DA2DCE08EAD2CA1E4E86F14D7B98
-:1056D000BA2582F111FB3185E6692F4B8BA0F01BB7
-:1056E000DBA32203E398670EEC710513D0FFA660DD
-:1056F000ADC1FF65C66367BDE92F7B108F8F5E204C
-:105700004EBB37BB334EBB0BF974D2CC8E66BB1687
-:105710008FD3CAF8638177FBBA4A54590BB87DDA44
-:10572000834556EAED2A5D1C741FB6F3683C0EDA19
-:105730007A893E0EDAD86327DABB3FEE8C83067F88
-:1057400085FAC49FBDB514F9F751DFF667EE457CC5
-:105750003A44BC62E81197867EFAF23DB9389F5709
-:105760004DE39750FAF1CCFBE0C3D9C6F8C219DF7C
-:10577000751951E2ADEC84EB5BFA17E57E18FD87F5
-:105780009E84EBD0886FD97F8DC2F7B5CCA670F917
-:1057900027F428C8974F480E4418E94DBF437902B3
-:1057A000F5CD19DF501FC53D93C81B391EC063FFDF
-:1057B00044F15FE82F619CD59AC3F5588D8DFB4D60
-:1057C0009525E58B715C356E97E2D0F9FB3B84BE85
-:1057D00033C785D48CAFCB83C2EF9D68FEE6F84E0D
-:1057E00087D017882FBD9FFC42F83A6C6BA1F8E177
-:1057F000E1592A5B09ED9C098EC86709BE97F05DE7
-:10580000E49BFE0073787F9DF44C122F3ABCA2817A
-:10581000E2CCE6785AE7FBDA946AD4DFD588475DB4
-:10582000BFE5395CCF4F129039829A07DEDBEB1E61
-:10583000F4308C7FF5FFA23CEC46BF58C70B18BF75
-:10584000603F7093BFA2BAF6CBF2958375F8AC6057
-:105850003C3EBBE7C71E0D9E57F76FCE0DBB92E3D4
-:105860007112B60578BA1B1F8C247F8C2F87FB37EB
-:10587000BBE58F6183785C88ED49A1F869CA9BAA72
-:105880000FED06EC97EB01EE4F5E26E226E6385E62
-:1058900075689141BEA4C51416D1C52FD2AC5BC9A1
-:1058A0003F9B16B3D273F37ACBCA81F53630BEDE96
-:1058B00024FE93D153E2DFFC7CB0C0FBE1DAB91ADD
-:1058C000FA0DEDA989EDE066514F96CDF908C9E2D0
-:1058D000EEB5627D9C098ECC477F55B53DDCBF3B64
-:1058E000EB5CE2E742790E37E7F0FD907BEA1B22A2
-:1058F0008EA736636B52AFA659CF1F8FF59BE2B1CF
-:1059000069C3BAC4F3FE29F1D81F9AE8D7DD78EC51
-:1059100078B11E2F94877293DD68F748789DA0E3D5
-:1059200099600A0B837CBCB552A53814F007E9C70F
-:10593000C30F2A646F466B1DA497EB6B53C83F5B84
-:105940005FAAD2FBFA0D2AE9CF28C88705201F5E7F
-:105950001572C2EC9FAD648A217E3E69588AA13CD3
-:1059600075D6FDAFAE40FF72854DC3FE0E6ADCDF1B
-:105970001CF6AB64BF421BBE28FAA71FB8CA87FA41
-:105980004CF2C341BF4AEB2D7C48F561B7ADC21F55
-:105990007D706D6904F35498128FD36B7DB1FD7ADD
-:1059A0008A03BFE3DD4871CE94BF3E1C08D0FE31B0
-:1059B000A89592DEE4F1D314B14EC7F4A8B811F55E
-:1059C000F887EB6D0CFD461FDE7186D673DB8AC54A
-:1059D000941721FDCBD23F6CF6339BFDCB5DFCCA07
-:1059E000267F72B27C86977212C7EBA5BC4AC61F8F
-:1059F00020B6F67F133926E5C7BB629E637A6CDC5E
-:105A0000B012F0903653253C48BE7CE7EB3B1F4775
-:105A1000399C02FCB18A213EFFE365DC87B0B94ABC
-:105A2000423F72AA94EB983F5112A7CBD4E0DCCE50
-:105A3000322EFF690D4B0C791F66BD925CAE9D5FE7
-:105A40006EADCFE1FE0AB3DE31AF877FB4DEA9AE23
-:105A50007DB004BFAFAE9D1541B8AE87B301E5AFD1
-:105A6000593E98F5C47526391BD70F2A8B0CD58F54
-:105A70005BA37A713D61A7F7675378BE43C8C9E15C
-:105A8000F2D4F427109E4DE1F90E61340AD14EFD97
-:105A9000202DD244FBF2C523904F42CCD716C679B5
-:105AA0007A53C98FD0D28BD753AF49E576F9DE4A06
-:105AB0009AAF2A0DF3E64A5A374D622E3FCE0EF6C4
-:105AC000C885F134F92D29185F18E3B6EE47D74B96
-:105AD000CB680B73B038BEE27921CCA3C0F7F44E8B
-:105AE000C1FD67A9D3DE97ECD4E25CE4CB1FC2FE14
-:105AF00010F8FEC00175FB6698EA01DFD08C447691
-:105B0000BA84E638F291EFBEDD07D7EDEF59703079
-:105B1000B6D75A5DBF01E3C38D3B548A2F4DBFED0D
-:105B20009D4BC8EE36C529D5746709FA539A94542B
-:105B30001FCA1389C7DD6E3BC999A62369B49F6844
-:105B40003AAA88B29BE4A1C4FB5EA857300C7395B7
-:105B5000DC243725FE615E57217E241D2A59F4C0BE
-:105B6000A8A2BF6B5E55E79F572F0FC90FE43335CF
-:105B70003E0FD56DA5F9B5B3541F8E2F24FC43EC11
-:105B8000FD34DAFF493A370A7E94745E24E8DCBEBD
-:105B9000F3CB7BAE84FA2DFE2C8A3AA8BD19E1A185
-:105BA000FD7D37F189C4839C37F0C574FDBCF7ECEB
-:105BB0001C7A3888DFA7A7521C5FDADD32EFC03CC1
-:105BC000FF1AB17F6FC8553AED5EF45FBC9A3DBADB
-:105BD00021B73C417D61EF02BEE763BF951EF645EC
-:105BE00084C5F779C9F21B96E72A179BDFB05CDF03
-:105BF0007F677EC337A7E7AA8BA167A3D5B556C930
-:105C000088E35BEE9B69496B5DD7BF79FD497A28D4
-:105C10003B77FF19E3F866B9B05C5DCC14E867CD5B
-:105C200060BE2ED91D4CA3FC20D37AB990BC01FADA
-:105C30003F8E74482677BA4BFFA7BBD2FFE9F3D15A
-:105C40007F4376E0A7F81EBBEA5946FBC267B18CDA
-:105C5000F2C45E4CFD11DF766432CA6793F931728B
-:105C60003C324FE65798B49AABCBC329F129A82709
-:105C7000BAC11FBFFA07F3C72BE7E78F28ADD3855B
-:105C800082FE0B655EC6F6F3E76574837E6F26A21F
-:105C9000DF72D5D7112CEA3EFDDABAD2AFEDFCF4B3
-:105CA0000B1E277D62675F90FD5E51EB457E19EA12
-:105CB000F14FC6B8F9AE9542EE1401FDE0FDCB39C7
-:105CC0002AC9B51FB1CB486E7FCB62A1F1B683BCA8
-:105CD0007E42E9D63CCF90DE61616B16B4BBFC3AE4
-:105CE00046F13DAFB652C172BE067A5AEBFE7CFF5A
-:105CF000D675BE7FBB80BC52F272893F97217F3A36
-:105D0000358FF57CF2CA9D67B413BAC18FEEBCDC47
-:105D10007F283F7AF32E42AF7603FFC5D85E323933
-:105D2000D1DD3C5058A7AC6756D7FE19F3515CAD96
-:105D300032DDC9F5F63645E8F1D22095DD4E121672
-:105D40007B859E3FBD9DBF574727B62B07E6651154
-:105D5000FE176E5D12B01AF249C2F4FC5EFF694F85
-:105D60003F15F3B45D349FEC89DC0F29E72FF3B4C2
-:105D7000D3C57CB27BF379671FE179ED125FE962ED
-:105D8000BF91516135EC2324DE96AB0105FDE89906
-:105D9000390CD324609F3048413F57A6DF585FE25B
-:105DA0003B97ADFF5CC594AF2AE3FB5CDCCF0CC135
-:105DB000F7BAE709F6AF409F12CC1FBB314FEC4F4B
-:105DC000ECCC8BFA88A935E7E523DDFE647A5E37F3
-:105DD000F627F57932DE6ED47B5B5358423FC3E73A
-:105DE000623D80BD42FE6655E8B9B16D4594EFB2A3
-:105DF000D4AD91FF41557DCE09455DBFCFF4C3F2CF
-:105E0000D6E123BB2A9569BA79E706B20CE5FCEA2C
-:105E10001E86FA05C162C3FB9E0D9719DEF75E5C14
-:105E200066281786AE30D42F02C4EACB7DD7FE9BFE
-:105E3000A17EFF96EF18CA0336DE6CA87F69A4CE58
-:105E4000F07EE0D3F30CEF076F5D6A285FBEE3FBE3
-:105E500086FA4DC28F6CC6CBF63C6E173559B91C0D
-:105E60005AE92A23FF6693CBE8DFBC47D4ABCC18B2
-:105E700055827EF5A663A52588EFBDE957909F3D25
-:105E8000195F98E55A32796A7EFE9CA0F7A997ECD3
-:105E900016E4EB457B60DD5E0E65D7BB6B704EEBA9
-:105EA00006F1F8AC8DF17C2119AF91DF77C66BACB0
-:105EB0003EEEAF4D77B1BB12F0C53D795A427FAA95
-:105EC000E4A3647893FC7821BCBD20EAFDBD787B17
-:105ED0005FE1F9AE7A7DB02DC1B84E897505FAE65D
-:105EE000B53C6E0F0D4B254BDE43EBF162F5811C8B
-:105EF00007E8837751BF98F3744F55BF31FB610DAD
-:105F0000EBCFE6F52DBE12A44B327FFAA9BC2EFED4
-:105F1000F406EE4F4F35E0ED7DB9DE4D7EBDA6F4C3
-:105F2000AFC89FDE64F79574C79FFE3E7C8BFDBDB6
-:105F30008074CED5D157F8E393EDA3428CEDC7F32F
-:105F400010CC65D5F4FBA664FB6329CF617F5C822E
-:105F500071DA16DC7F2909F5A035BF9CF6CFA40FB6
-:105F60005A400F3AC84FC0F66B505E3EC6C2EED2E2
-:105F7000E2F396F6BC83F99C7695E89A9A8F78F9C5
-:105F8000215B96A2FE43F699B9F917A1E7D985E3FB
-:105F90007D64A74D84F9AFD2EDAF257ECCF13D896C
-:105FA0009F893E1EBF5B0DFA11E37BBB73B99E5EFA
-:105FB0000DFB6FC4A3273BE0ED83F63C3C7F02C999
-:105FC000913B9CD68FC4AB39CED75DB933229FF3BA
-:105FD000A3CE8E1B919FC03F133FAFC2E7BF54ECCF
-:105FE0009FC7A983B6A21FF374CC4E785319CFBBB9
-:105FF0006CDC676311A223CF5F9674B4C5D6B4A2DC
-:106000007EB63173BEB29681F3B7EDE3E7C4580EA6
-:106010007F1F66CE9568F7645418F557A6DFA8BFB2
-:10602000B2ABB24CFACCA8BFF2AB8DFAAB2068D4BD
-:106030005F3D1BCA4CFACCA8BF0A43A34DFACCA8BB
-:10604000BFFAAEFD8E499F19F5D7808D46FD756963
-:10605000C4A8BF063EBDD4A4CF8CFAEBF21DAB0C96
-:10606000EF4BA37719DE0FDDF72343B9BCF51143DE
-:10607000FD39FB7F4E793D230E3F61A837B2EDA776
-:10608000867A80F056CCFF9E492461ECCA93CF1BE0
-:10609000DECF14F6DA551DBF34B4C35A781E771814
-:1060A000FE21BD3E62413B1A2956D6F14A4FA0EB74
-:1060B000A288E28B42B5B93BB60DC7717CFAC135F7
-:1060C000FBB09D391B8DF9DF7323C672232BCE40A5
-:1060D000B9D0087C11013E998F79E13AF9369F2DAC
-:1060E00016E702BBC76773F65FC7289F34EC6FC51E
-:1060F000BC77394FC96F7EC16F727C72BEF3C1FE2F
-:106100008B6AF179FAE11FDF6FB6D9916F67EF50B3
-:10611000D8234AD7F934ECBC6F4DCF04F332CFC348
-:106120006C87FE24DF183F19A7BA285E70FA90EA40
-:10613000E3FE46E33A5CBA9FC709963EA790BFCEFE
-:106140008C0F699F26C38B1AE6FB86C61C1689E84E
-:10615000D69F26F0E1F01AD7DF69FC0F1CCF636AE7
-:1061600004F38D52B45433BF0D8FB2AE784E2B3141
-:10617000AE53339EDDBE1E09F94A837F388ED9E2C5
-:10618000FCA199AFCC785FB4E33E3BCAC38BC5FB9F
-:106190009BF989E312A0ED86D913E4D749BCC2BEAE
-:1061A000FD3DD423C9F6B31FE55FF47EF6A3FC7F63
-:1061B000EC7EF6F4F9F45C3BFADBC0BE34FBD9CCE0
-:1061C0007A58D9B9E7CF4A3AF9B5DB1CB8EE823E26
-:1061D00027CF8331E9C99212839EECDCF71E536806
-:1061E000DFBB2DC3AF78613CAF64F82D08A766F81C
-:1061F00055AF6EBE4D80173AF7037A6A5B023BF1EA
-:106200006AAFB48F02E437595DC9EB9BEB0DF0F236
-:106210007342BB73877BC9FE3C5AEA25FBD33DFC26
-:10622000BCF6E7BD224E7437C621FBC7F383368820
-:10623000780D2C3B3FD26DB52DE0D5E70FA77A3313
-:10624000499FA68F7CBE15F3A89B3C168FA221E424
-:10625000F9DCCD2E6BD516F15D8EE13B3E4E15F18E
-:106260000D78B5BAAC5FE9F9F66A2FE3E7AF92CCE7
-:10627000F36A2F8F13DB587003DA43323E6C3B56C0
-:10628000E94479D7C4FC1E2E277D1E7DFE878DF143
-:1062900078F068111F96CF55CF37CBC3FA6D46F013
-:1062A0005BDE047958CB32FC57237D43D6B003ED37
-:1062B000CE9033F1BE789C57C4EDC47CC10025BE9E
-:1062C000A271A8171FFF017B3380FD2E57C39427AF
-:1062D000D9E41E5E127475DFCF35CDDBC53E9AE67C
-:1062E0003D8F7D04F6E9643C47E6CFE861A56D8704
-:1062F000D55782F85E8BFF3D92FCB475889F2E794E
-:10630000AFE21C2EECE3CE9BC72BDBD995E59FEBD0
-:10631000E5F986F3B13DFF004FB3AA6B27FD02ED0F
-:10632000483F4737FC56DFF326F05B2D577D27515A
-:10633000BF77178FCDDE2EFEC266EF79FC85678FA3
-:106340000CC8C078B6F47799EBC97391B2BC36D358
-:10635000D8FF9A325EBE57D0EF77E27E8A27C538E3
-:106360009CA6F3A2CE098CEEE990E74C653B4F7AF0
-:10637000DD54FF8EECD14FE278D71429B40F5D9332
-:10638000A918F6A3B7782B9F447A3C2EFA7B52F0DB
-:10639000EFE662EECF31E761CE11F5E7784713C43F
-:1063A00073AD28C7ECAA9A108F4F7BF9F8274343A7
-:1063B000941F27FC6EF50F2A62FF64BC1701D6F903
-:1063C0005B69207F8EAFB7D1B9D759AA6B0DF26345
-:1063D000B27B0E6A070528FFE9EF3D3F86F84CCBFC
-:1063E000EAAA57A3DE4E7BC67791E7C87ECDF1D3EC
-:1063F000BD787F5B2AE7D30EB78BFCE6E67A4705CC
-:10640000FDD70BBF06CA75D42F592A5B9C48CF1CF9
-:106410001572F59B9F6BE6F77964BB5CF49DF95CA4
-:10642000739BBD6D753E8EF72AC587E717F26B3CEF
-:10643000BBF373F01CA3463EBE35452CBD02DF976F
-:106440005AE87DE6F59E3536CCFBD61866EE331B52
-:10645000F4E3867E520A781C677DF8BADDF9502F86
-:1064600043EB60C583E8BCF7782FAEDB6A9E3F6FD5
-:106470009EDF57021FAED5B0BF407C6889F3D0BF06
-:1064800012780079F367A447A5C6B6F373593C0F99
-:1064900016D992F2157D3C5F3B0DF39DFA7279831C
-:1064A000EFBFCE1A730EBF93EB4B15F8369FE74E36
-:1064B00029B8B8F3DC936B128FB75F01E787C31974
-:1064C000818C02E877F2A895DC1FF6F5B973EA70C3
-:1064D000348EF93A81EF19FA2B5272B81C4ED1342E
-:1064E00092CBCCA3509EAB53F3356039C57585472D
-:1064F000453BD9C1E3926CA685E1FD2A63443BFE8E
-:106500006AA6FCA184FB65B99CB5B23F48FE57055D
-:106510007286A39EE57F603FAD4F83F98C711DA00D
-:10652000F8644ABFC59578AEE1E519BC8D1F2539E1
-:106530003720CFBB779EEB0F470E18CEF5DB1E3D05
-:106540006038D7CF1E3DF0F79CEBAF2C78F4C03FFE
-:10655000F35CBF946787D5E0E1DB01FF370053852B
-:10656000CA105A590DD1DB4B78BB5EE039FC15E0FF
-:10657000D919C7F30D3BF713FE0EDB60DCD0BF6DFE
-:106580003447B5EDFB199126928B11EAF74667CB9C
-:1065900038DC77B6DB3B8660BFED2FBEDD3B0CF20F
-:1065A000E4C80FCEB819F0DF87D60E373E3F79C763
-:1065B0001B6EC4D7913B54B2D7E85CB42E1FA95EC2
-:1065C000F0D54B05819B91AF66ACF8EB70BD3DCE2D
-:1065D00042B9A47FE746544ABD92F26FFED3698266
-:1065E000E97879E1D66C4359EAE5858EC4E7D41F92
-:1065F00011EB62EEB39BED3D35EC3FB800FB3F295C
-:10660000F21B4E6E77D33E4C8EA7EED9523BEE3B3B
-:106610003FDCE96051F203B7DA18F9B3FC13943C9C
-:10662000BCC788FF99C7F9CAAE346A6FD6832AF906
-:106630009D6AA1AF10E035B8732EDF079BE631EB02
-:1066400088361EE5D5AC750A0B6BBCFE1D787F46FF
-:10665000E84E8AC398E769D62F7392DC9F3367E7C9
-:10666000DDF4FD4CE6BF1BEDD9592DE6F7D77C8450
-:106670004C3EE702F19C7B0B84DE19CE469CEB4B33
-:10668000F1A38CC1DA85F5CEC9157C917EB2C249E1
-:10669000F0B3151E823717703E9EBF63F72B3D691E
-:1066A00099B70E47BDF4D6BEFAB49BB5B8DD3D7CB4
-:1066B000F3AD7B1EA5AAC6FCCC1A81F711222F735D
-:1066C0008E38F7507EF8FC799935888F215DC72B7D
-:1066D000EDEC1A93DF57DADD667C9CDE37260DF988
-:1066E000E3F902B1CF1D017851FF7EBC24FB6EA1FE
-:1066F000CAEF4D333F97EBE866C1D733B74C59D358
-:1067000003FA6F7AF1A33E6DC4A7DC7F512EF055DA
-:10671000EE5AD38AF32F6726BF61981D623A7E0630
-:106720007E5251EF98F956F2133BC4BF770ABF4629
-:1067300027BFEEDC40F8957C85271D2C68C381E5DA
-:1067400062A9B8F03D57B35A8CE553B6B63E284F10
-:10675000E698FC0DA794C4FBB7BD05C51C0F9A7F36
-:106760003CE65FCC628135DC3FCFEFC739696D799C
-:10677000E5765CE75BF83A5BF88BE7FE1BE5D7BC98
-:10678000FF7A301DE5D7C7D6963CEC6FC153ABD32B
-:10679000FD28C7ACE174FCFEE3889AF01C71510F30
-:1067A00045E6EBBB304F6D11B11AFC6F667812CA2B
-:1067B000CF3F3D65F3A01FB6F16947D401F858B447
-:1067C0009DE311CA4779F94EC257E30EE3BA9CF72D
-:1067D0001F0FE669E40F08F714F8EB89227CD11645
-:1067E0001BE5B52E3AA4FAB09B46D641F3337F8F12
-:1067F000E38801DD1AB7AAB5F68CAEEFC112B2E399
-:106800007A6BDCCEE9D9B89DD3ABD164873608B9B1
-:106810006DE6FFCC1E46BE07FC905F4DE6DBB2087E
-:1068200097DF4DCF3C3CE4288CEFB32DBF4D57068E
-:10683000C5F99F615628E0EDF4D6FA19F6F3DCD7D6
-:10684000734AAC934EBD20F490B60306960FC59DD7
-:106850001C2EB045D3AF04BC2CD86CF385E1F1827B
-:10686000E754BF0BEDA8771C74FFC4FCE75E7EEB1A
-:106870000A18DFFC6DB69C097C1A2E94DF925E8D9F
-:10688000C8E76571FACCFBF9CB76CCD3C4E7776463
-:10689000C5E9347FDB6E3BE67D9AF13966EB6E3BF2
-:1068A0005F6F267A6D3D3A1EF576D33367EDC80FDC
-:1068B0001FEF52587E51D7EF1B36BF9C8E7206F1E8
-:1068C00084FA45D2AD938E5DE8179DF4CB6154CF29
-:1068D00083719E0BD1F1733C83504EFCFEB35FC2BB
-:1068E000381ADE75F8100F0D3FBB351DE7F39175B3
-:1068F00031E7FBC757E7A1DE6EB085F33C04F9F33F
-:10690000864DDF257E9CF3FA77F97D4ECC5F80EBD8
-:1069100019E65B80F39CF5D80D34CFD92C48FCD810
-:10692000F038BFDFF04B2BAB4AB41F784CAC9B8FD9
-:106930009E70D0E6E1233BE3F785FC4E15F7612D11
-:10694000217BE5BB62CE20A1A9FCA553D0AB878CEF
-:10695000FB73F9D6286A356EB993E4DB27BDFDF9E0
-:10696000B8FE010F46FFECEBE3F2855CA47B5DE82B
-:106970003BE0BF31F81CEBB7DAFC29430CDF89FCA4
-:106980005BDEFF32D13F8C3B15FD7C1FE519F7B96B
-:1069900012FEB687F4ABB156A6E7B3647260CB3A89
-:1069A000E2AF2F0E7139B32832A58ADEB7DAA2F929
-:1069B000F83EB2FB7A85E404D82189D6F9169B58B3
-:1069C000E7C6F7304EABA2C7EF2E7E7E4FF2CBEC80
-:1069D00007A0BE6E5DC7F9C71E7F5E145FAF327F32
-:1069E000638EC99E93D02C271E32C909F93D7B2C9A
-:1069F00037E1F988B87C0813FE16D8223F7904D70E
-:106A0000F53B0E3A17B9E0391BDDEFF3E9B37BDE56
-:106A1000BA19F8FFD3AD723D1BE5AF793D373C7F26
-:106A2000034BB49E3FCD09B084EB199E275CCF3950
-:106A3000FCBCC1FF29F93B2789FCDDDD43D8633A63
-:106A4000BBE34A287EF2D3F985B43F33E157E2D560
-:106A50002C4FABD158C8ED2A4FE1EF10D3E153E2F0
-:106A600051F2E9BCFF5C48FD74F2B3E457C9CF9D15
-:106A7000FC6A9EB7119FE6F7CDB877CA8DD3DFB613
-:106A80000AF6E518AF7D51A5FCBC76AD233D0BFAA7
-:106A90005D2DF27BDA3DA29CC9CB1DB9F635284F9E
-:106AA000E4F38E149EEFD01EE848CFD4ED078EEEAF
-:106AB00054D3F13C405B24715E06656CE4E2E9D698
-:106AC00064EF57D27A684FE5FEBEF654EEE71BA797
-:106AD000BAFA84707FD7C2E34B3357DE948EFBFB48
-:106AE000F69D7D2757E37E60BFCA738EC27E6B0121
-:106AF000E0B79E4F9D9D64E18746A1FDBE73FE04F5
-:106B00006C67E67A235E66BBB6D8B19D2FD91D04AB
-:106B1000673F608BF309FC6F1EE66B219F3F667A2F
-:106B2000BEF35AE2AB7926BE0A225F25384FE2EA6D
-:106B300029F8AA9495F2FDB6888F09B9374E1D340D
-:106B4000B91AF329F7F1F31EA777AA6C0DCEF759FE
-:106B5000112F0BE712BF2E02FED6FB4D3F43BE1B8B
-:106B6000905CCF7FF6C291E1B7439505FFFDDE90C3
-:106B700047017EF6DFEF5CF22B2CFFE2ED3EEFB13A
-:106B8000AEF5C7ECFAF32D94D7B9CB41F79AB6EF2F
-:106B9000FA759FDBB1FC4B07DD2FDABE8AEFB3C37A
-:106BA000BBDCA4FFDB7B737BB1E9C5B343DA487F71
-:106BB000F17B8347F4E4E73E4EEFFCCB070AE6F3B4
-:106BC000ED8459A17C14FBB7C65FA6D03EBDFDC5C0
-:106BD000B386FDE9DF3B9F45E2DC55BB9B55E339BE
-:106BE000E9F64C7E4EB5F157239FC473970BB7EF70
-:106BF000B6D7C3FB31FFFBAF43500EB53FCFED0E11
-:106C0000B08737311F63A31FBD67830DE8770A6D17
-:106C1000445833EF3D7A7062785022BC703CB40324
-:106C20001E705E809706949FC9F031B5273F7FFCA8
-:106C3000AF878FCF6FC1FE17EC1C41F70CC7F1A2D5
-:106C4000F8F97337E57BC0FCF9F35D6787A01D7524
-:106C5000A1F92EFFFF6CBE0FFECBCE97F37BEF9E0C
-:106C60005C1F99F9BE2B5FFFE2362AFFCCEDA3F142
-:106C70007673BDBFF02FBBDEFF39F47EE35F76BED7
-:106C800017A2F77E416FB707E332ED2FFEB50FBBBA
-:106C900088799FFE7F74DE9D768FC5E71C06E37BB7
-:106CA00097456EA85492E78F16F632EE33E43DDC3A
-:106CB000937266931D31C9CFFD314DAC6C1F9EB3ED
-:106CC0000BFB558A5F50F20EE0A1F5FAD208E58978
-:106CD00059C3FD1FC2BCB11B17FAF87D65C6FDD7AD
-:106CE000A4BCAA2AB4E70EAE847141BD836E8BA703
-:106CF00009A630D9AF92FD0790ECBE37475F4B79BC
-:106D000028932B8CFB909B4DFB899BAA8DEF6F6486
-:106D10004FE462BEDF8D0D36CA4FBAC154FFAF3D9E
-:106D20003D44D79BD8E2D5DC9F7371789A2CF0D480
-:106D3000150FE7C75B173C89FD26E50E695DF1E697
-:106D400008F2FDA7035E087B4BE4E52DED163E99A6
-:106D5000D8973A44D712BF0E3FBF7754D72EE1459C
-:106D6000E2FD62F12DE964C6BBC4AFC49B990EC5B8
-:106D700078DE53679FC7A1F15E6D26ECC6499D760C
-:106D8000A38BF0F8DA167E5EE2B58AFAF5A5587E96
-:106D900096DF07FFE5A8A1CC09F33D68633B282EE9
-:106DA000E4F76B9EE1F1FC19A5E2D7149FC0FC4506
-:106DB000FD7E15F317F5F3C2FC457D19F317F5F5C4
-:106DC000317F51FF1EF317F5EF317F515FC6FC4550
-:106DD0007D7DCC5FD497317F515F1FF317F565CC74
-:106DE0005FD4D7C7FC45FD7BCC5FD4BFC7FC457DD6
-:106DF00019F317F5F5317F51FF1EF317F5EF317FCA
-:106E0000515FC6FC457D7DCC5BD4BFC7BC45FD7BD7
-:106E1000CC53D497313F515FFFEAD84B867225FBA4
-:106E2000ADA1FE18E71B86F238CF7B86FADFF61E8F
-:106E300037BCBF46FBD4F05ED2FFDA923386E71848
-:106E4000FB080FC77D0CFF9BE8FB8BA11D2B0B5094
-:106E50009CD4CE161374A2BF17602ADB4AD005CB90
-:106E60001CE18901C1677A21BF6E0AAF41E63A3859
-:106E7000F26C1F94FFAF8DBA8EFB25447C6132FE0D
-:106E8000A7064C9CF6752FDCE7CAF8697A4C65D1E9
-:106E9000A1C0873185A02796C6A2D9C087B1148228
-:106EA00059B16C7A9E1DCB249813EB49CF736305BF
-:106EB00004F3627D09E6C78A087A63030916C42EC3
-:106EC00025D8233694BEEB192B25D82B76253DEFFC
-:106ED0001D1B49B04F6C0C3D2F8C5512D462D7123C
-:106EE0002C8A5D43B038761DD5EB1B9B42B05F6C9E
-:106EF0001A3DEF1F9B4AF092583DC101B15A8225BD
-:106F0000B1F9042F8DCD257859EC56FA6E606C09D5
-:106F1000C141B1DBE9F9E0D8F7080E893511BC3C75
-:106F2000B692A02F7637D52B8DAD235816BB9F9EDA
-:106F30000F8DDD477058EC517A5E1EFB31C1E1B117
-:106F400027098E886D265811FB4F822363CF10BC12
-:106F500022F673FAEECAD83682A362BFA2E757C5FB
-:106F6000FE17C16FC5F6D0F3AB63BB09FA63BFA5CB
-:106F7000E795B1FD0447C7DEA0E76362AF131C1BB2
-:106F80007B8F9E8F8BBD43707CEC38C16FC78E1298
-:106F9000AC8A7D4AF09AD8C704FF2D7686BEBB36F0
-:106FA000F639C109B1BFD0F389B13F13ECDCFF8FD3
-:106FB0004AFABB029673B87F766575EBBEB2FBD218
-:106FC000D2492E4EBA83CBC587D34EED253939D25F
-:106FD000A13948F86D34C4BBE8472460DFB77BE4CF
-:106FE00047BDD0DE595379FCFD5B519F2D7130A117
-:106FF000CF4C72F76B97F07732CC479C2EF8FAB5EE
-:107000008A3DB96847AD296B5B807E930D456D3530
-:1070100008F37A73BFAC5BC09CDE3C5FE12F03B822
-:10702000FEAD59D29FFFBE404EF7E6775D2FFE9D25
-:10703000ACFF751F0FD717AE8E3E745EAF9BED741D
-:10704000B7DE85F2B062BD8297F5CE3DDFF9C16E45
-:10705000B733B477827CAE6FD0CEA8EEB4F3A1A0E4
-:10706000FB63BD037E1C3FB3FA87E0FBD1AB0A5440
-:10707000FC5D95DAF58A07F9A5BEB9743CD2B58CEA
-:10708000F9C92F393D493ED96C41D7BAC53686FE7C
-:10709000C93A8D917FB86E3BCF43467FEA44E09773
-:1070A00006C12F0BD77D4E7EA786C57378DE53842D
-:1070B000FBA7E4EFD8CC6FD9FC0ABAF5BE64072869
-:1070C0003F7EFED346FF55A3F04F2DDC6A7ABEF813
-:1070D000DB09FD9E66BFD48CDEC22FE5E3794F4C01
-:1070E000ED45F3FE12E68DF924C1DBDC4ED41B80A6
-:1070F0000F8AC3483C48BFA7C407EB7AEE82F25719
-:107100004FEFEB4F7972A7352D1FEB05D3F9EF59F0
-:1071100029D6E0087C0E78A47C968E9569940F752C
-:1071200014F4808689579EE008BC3FAEEDDDDE4C4E
-:10713000DC5F698C4738D7539E782D8C01F3526AF7
-:107140009FCAA6739BD0DE901DE8D77CCA46F9483B
-:1071500061B6D4CB2ABAC62B02AB6DC417753B32CD
-:10716000797E5AD87F08CF1548BA1C6DEE3B1EF3C6
-:107170009AEAD6169592BB6E878DEC43199795F4D3
-:10718000EA9ABFCDF3051A59640DA62E01BD4E240F
-:10719000A457CB6EA22BD0ED4412BA9D381FDD1E32
-:1071A00032D10DFDD437E1CB3BB2693DD7AC8AF685
-:1071B0005FACE34FB3FF9FCDBC82EE3D91F9CF555D
-:1071C0003DE4EF8CF9F290BE67D69713DDCCF4AABC
-:1071D000FA5B3DD185BDEBA67B87A7F76533BE0380
-:1071E000CF6708BFE7F4A66BC8FEFEAFDE7C5FF09A
-:1071F000DA0ACCFD64ECF5154EE607E3FB8D151EAF
-:107200002ABFB9C24BE5B7576804DF595142F08431
-:107210009DE715C9F5058C40F97D2FF4E671A91796
-:107220007ACBB8F0322FFAB9ABFEF64639E619E55B
-:1072300086DF9B34EE2AB2DB0DF922D5D71BF34152
-:10724000DA6C22DF6C9DE2C3FB64EA02571AEAB3F0
-:1072500092A1F132EA1F91BF52B73693EEB19B3A39
-:1072600021DB50FFC6B53D0DE5577B6B34BE29557C
-:107270007D0DCF6FAE196828D78ADF8F605A05ADB4
-:107280001B19FF02CDCDE9E2E175BF583C227F39E1
-:10729000F4FFC5011BBD37D3E3843D4CFBF9F0136C
-:1072A0000E1FC6F74EE2F937289F7C53A5FCA29328
-:1072B0003616F680883FA9B06684CCCAD7D59787A2
-:1072C000F9BAAAFA9BCA701FCF7EEAA0F860FD4601
-:1072D0008585F16E860EC03CF4BBEC1907CD7BE6CC
-:1072E000469505E97C95B615E3E4CB9E1AE0C3F814
-:1072F000E8F4BED1DE78DEB0E385141F9EFBAA6FF2
-:10730000E3DF9F84FD7926E6472965148FF8E3C4FF
-:1073100096D916CCB7530FE4E27AFDE3F3FC77CDB0
-:10732000E62E7973B807F03CEF95AD6F55403F27D7
-:107330005A54EAF7D3A71D9B555AF7FE7CBCDF369B
-:107340003EEF08F929C6F708FC09E5FB27B32343FC
-:1073500048FEDCC1FDE35DF103F3457A23BFEAE4B7
-:10736000595CBFF1F81B08A1029413F5361FC565DF
-:107370004FACB751BC10F401E51B9C68C9B670391D
-:10738000F43CF15D9D55B3EBFBAD5BAFFAF9EF63F8
-:1073900068761C2FBB4F0DB21158E6F911E1B54AC2
-:1073A00090C77F8CF4BD75C9083A176DCEE392F093
-:1073B00014ACA9A02EAE34EF451EFF65C3DAACFABB
-:1073C0003C77E99F61C10AC37D460B8A1FBE6714E3
-:1073D000C0D37E7EF5E2975BDC24273FB3BC347CD0
-:1073E00039C04F2786FF6005BABCAE068BFB60DE56
-:1073F0009065FD2685E22AC7EFC1B8FF27CFD97C6B
-:10740000B40C45DED8BC9FCEA5F854727B81797947
-:10741000FC3A9AA778F1766246F922D3D856E15F12
-:1074200088F03C031C04E0C7B380C7C58E97BBEF50
-:10743000C2F3C3F5A6F3C6C7C5398BF23E8A415FD6
-:107440002F13E57A0B5F9F6C17BF8752FE5E9C94EB
-:10745000E352DE4A793DAE4F317D27E52C635B492F
-:10746000BECC16F7252F78DAC1CF1769CC83789C6C
-:10747000CBC9C456F5D1E8BB79F6E71E42B69EC328
-:107480005A49EF7D628BCC6E2DC2EF373767D1F74B
-:10749000365F04D77144FE1E9D95E4C81CC6C7B96B
-:1074A000B045894475FE0EF9FB240CF5844EEE744C
-:1074B000D10B267D304BE8BF59CC946FD462D453A6
-:1074C000813437CD6B5E8BC8C3EE1C97CACE61BCCE
-:1074D0002B187965128D5BF145128C630EEB88E2F7
-:1074E000BDC80B9FE5E798CCE332CFA3BBE39CED8F
-:1074F0009B3216EF57EEECD7346E896F8607AB746C
-:107500007490789F1DE6F89CBD53217AFD5ED85B90
-:10751000F27CA099FE73586012CAB9390FC03EB30D
-:1075200028CE0F920FE66E8BD079C04F594BBA0B15
-:10753000D6C3828DDB6E1C09DFCF79EC753BF27B05
-:107540004D56B4BF25137FAA67F4BD55BD13E87D22
-:10755000939EFF47E18909BF157D077899B545A539
-:107560003C0A5D3D914710267C3584F9EF09361CB5
-:10757000527D4DF0B4017FE6A8ECE2C72BF1F6CFC7
-:107580001EB7D9AED9D6E7FC768D59DE74B16B4CF7
-:10759000FA14CF73A0FEECC8E5F9E95F58FD19595C
-:1075A00024A74D7238B78CEE63957278B6D083B24B
-:1075B0009F59A8FFA0FC878D3F4F477FC6EF1FF85C
-:1075C000791EE56BA0BE1914D737B7D5F3FE6EFB55
-:1075D000450AE54BFD7162EB10B4076B1EFF75BAEF
-:1075E000FEBED79305C1D7FAE078857E5CA86EEE23
-:1075F00083BF6B28E5EC05F76DC9E6E9BEC03CDD4D
-:10760000C679D6E13C75E754EAC53C8FADE5F33B5E
-:10761000BE9ECF776697798629AE72DB930E5F9810
-:10762000EC8E28E9F593DB5486FBAC4EBBC36407B4
-:107630007CC95A36213E162E7DFB032BF0C5DC4B50
-:10764000003FC00735F73948EFCF7D81C7533F5121
-:107650002AF329A0BF379AFE3D783E0FEC05B437D8
-:10766000E2E3E8B403CE221E3BED806EE26F91F0C0
-:107670006B2DDAF96BFA1D2DC5CFF33117C97B6D70
-:107680007698EEB5D15006F073FE4EA4532FF37DDD
-:107690005CDC3FFBA7FE9FDFB294F8BFE312FD392D
-:1076A000B6C6D4A80DF3903BB62964272D5C569935
-:1076B0005EC9F07C1BF7ABE51472BB56F1FB29BF2A
-:1076C000C601744D85FEF20B35FE5CF3F07CF3C70A
-:1076D00018DDA323C76B7E8EFE7627EA439785F4D9
-:1076E000A179FEE30BB9DE5CA85AC8BE5E60E776FE
-:1076F00076BBB8BFA29F1847BF426E6F5F56C8FDEA
-:107700000AED685762BCFB2A07FD8E116363C9EF5F
-:107710006E659CFFAC126F1EEBA9CEF54DF673475C
-:107720002FC4D32DAC957E177152C5140DCF337C69
-:1077300090E7A47BA2E02F80ED4C13ED1CB4F1F395
-:107740000B1F601F30AF69C23FFD015E8F0AFD7FD6
-:10775000506027BB36FCA283EC863B53B9FF90E513
-:107760006458713DDC2CE4D4F4510E3FCAF569A392
-:10777000EE0C2084F6C20CF055E3EC585D0AFDAC2B
-:10778000B4707DBF328B71BF40735B39E2EF7230F2
-:1077900093317F1F66BFFD5CF6F9F8C8787E620101
-:1077A000FA19AE609CC12A08BF86F2023B7F5F5384
-:1077B000F893C90FF462EC779835857A0671847C6A
-:1077C000519B41FBDFC978BE200BA195F8ED3B56DC
-:1077D00016B670B8D645F72A790DBF0B7B43058BDB
-:1077E00066C0FCA2FB8DE73B6E8A5AA203305E6442
-:1077F0008DEE46FC599C9ACD03FD04AA9432C4FB3D
-:107800008255DD1B6F63E1361AEF02BCCF0BC7F95F
-:107810003D85F285A6C1A2473EBDC5CAF6AA659CB4
-:107820007EC8878D595A98EA2DE17C2ECF9548BAAB
-:107830009442F37AFC4E13E38376D6A6E3F7F6C4BC
-:107840007E95DB0BE5BE8FDB6BF3C5BA9D2FF9EEA2
-:1078500059E37A7D1CD70DF02DDAB248F76902267C
-:10786000E3FB4744FB8F08BE5F5328E37FDDEB6FEC
-:10787000A1834569DE2F3A888EB2DFC9026E2CE4FF
-:10788000F9D3721C927F67B3C594CF335BF8692C30
-:107890002049283FB8E549EE1732E51D81A144F99A
-:1078A0006DF3B6989FEBFC3CAA412E91DF54B17763
-:1078B000CCC4F129DF4AF121BF4FB36F25FF80B956
-:1078C0009E0D7F3F15E36E6BC1AE5244BC0CCA8E59
-:1078D000F50AFDEEC5B45E1D83519F83B41E4FE7CC
-:1078E0004285BD3D5BD0D721EEB79A8DF615C6D542
-:1078F000D0BE427C6DE476A555D8C375EB8DF6C637
-:10790000B4669DDDC981E17E0087294FDD26EC8EBE
-:107910000FED1D8351EE9BEF0BF8D0C2E711CE6344
-:10792000FC5ECD1CFEDE2AEC4BC9573F2DB419E29C
-:107930006DF2DC690DCA2B7E6F83294FCB45F7C7EB
-:10794000D428FCFE4EE9877C5FC0D36087D27D39A6
-:1079500047D2280E6EF64FB657BAC3169D9F727A5D
-:10796000C66D93103F35E9762BC2F73BEF156BA33D
-:10797000FE8F788AC9FE5953397423E6271D2BFCE4
-:107980007CB2B3374553C479A83FBD86F9F4D77F9D
-:107990000DF3A1F2D9C97ED847B5BFDC718B134472
-:1079A00077ECDFCF4EB6829E6F7FB0631396532382
-:1079B0002C6005FDD8BEA1A30FDEB99CAAD902F4A4
-:1079C0007EA56CCF16C0F6DA7FCCCB1F15DA027815
-:1079D0009F6E8D38B754738542F2D721D697F43312
-:1079E000D5585EE27034FF5D940BD5CBD6028EC2C3
-:1079F00072BC0FF504FDFE429F62BFA310EAA5F51D
-:107A0000099E46386F8A12B6E379FF43914B845E34
-:107A10004BF83B218E42EE6FCD2B0AD0F7D28F0E62
-:107A2000EDFCE59BB4B3458CEB7F0053DFF7AB0077
-:107A3000800000001F8B080000000000000BE57DA7
-:107A400009785445B670DDBEBD656FB260622076C0
-:107A50001212020668208100419B84252C810E2889
-:107A60004689DA2C02622091D131333A7F77D844AB
-:107A70007434A84F19079D169161E6A92FA32C41D4
-:107A8000B60EA0823ADA282A3AC04445058D4E4403
-:107A90007813FF87FA9F73AA2ADD75495866E6BDF9
-:107AA000EF7DDF1F3EBECAB955B7EEA9B39F537530
-:107AB0006FAA6ECF49F0E6331693E1353B53185B5E
-:107AC00050A1F9AD0318638702B99E38C62633E684
-:107AD0006E8C65EC27FCB93ADCDAAE303106E36F28
-:107AE000CFF4D8AE2864AC2A3C4FDC3F32CF21C360
-:107AF0003C376970EF30F8CF5C4EBCFF866C771F67
-:107B000027F4DFF67F9817E761A34798D810C67E61
-:107B10006667F4F35DEDD65C7B01B4CFD99258264D
-:107B20008C7B615BC65C9887D5C1E4698C7DD5FC94
-:107B3000A1D509F32C6AD7993B89B19A768DDA459C
-:107B40009B9AAD63615C0DB4A511F8550B7C196B64
-:107B5000314F8D0B5FEFEF047C0BF1FA6AC2FBB67D
-:107B6000174E9ABD30EE3653E3E74F24C3E5E19A52
-:107B7000EB59E7B9EBECEEE4EB3CC6585963FEB9C0
-:107B8000FD054E8DFA7F9DE31E8CF44B8139F03953
-:107B9000BA89AFD738FE57028FAA6876B307FA675B
-:107BA0000F89B33B81DE8587BC4BE3008FB96B3314
-:107BB00007E93047FF8C929148373667B842AFB239
-:107BC000CB190BE1FACC6DDD19B4DFED284C6080E8
-:107BD000575562E80E3610C8E6CC69B08F646CE287
-:107BE000E330E672BAC5CDE0DE329B848B3DA38BD9
-:107BF00001FE51277846A0B0C10FF3EC477C609E90
-:107C00001B87F68B66FD817A993126470263237BB9
-:107C1000CEACC375DD3874E458BC3ECA16973B93AE
-:107C2000E8CB483E46F6F44C433C713C837578AD56
-:107C3000C194EB601DDED775971FD6E1ED1FE30DF4
-:107C40007442B70A41D73AA783E8B1DF04780E0A35
-:107C5000E3219FCF98E38E10CC777C49DAC0553072
-:107C6000DFDA9EA3EE427CE4F3D7F6F4CE897C3EC5
-:107C70002CB73F5EBF583C660A3CEE42BE41EB2942
-:107C8000063913B4FE09FE4F1D1DA3C0D74C4A622E
-:107C9000EEBC303CFD9A7405AEACCA56C6DF30E788
-:107CA0004AA5BFDC162AA88D0DCBB7111FD932E625
-:107CB000277C6AE236C63340F1E88E33EFCF003DD1
-:107CC000F9DB7ADDA501AEB7EE7CF6FD1130EA14E2
-:107CD0002C3809E876CA0D00ACF7D4263DE0CF4435
-:107CE000F9709BCBBB33361FA782F10B0FBC641D11
-:107CF00005BFCEAF9D3709F9786BC0F2494B049EA2
-:107D000067D8592BCB027DD8A85EAF610F7CABF74B
-:107D1000472868F5F483791A0DFDB5E3BE60F138A4
-:107D2000CEFC498B5C273CBFEE48E683FB22D6BDE8
-:107D3000C61997FCF995F0CB2036E8271D9FD7FA96
-:107D40002AAC90953635139F961ED05D28A24B7BAA
-:107D50006A4C83758EDB640B44816A7DBDED63AB39
-:107D600013E8F5779FF3C17D16D4FF7AC692F0BE73
-:107D70008FAD2D70BDC8E9243A2DDAF1AD9501DF44
-:107D8000C7EDB89DF47A2CD8B104909F5033EBB76F
-:107D900009E6F767C6B99E85F96F5B399EB1C18C5C
-:107DA00025B4CFA0B6BA613CCDB7B07D1AC18BDA8D
-:107DB0006308DE1F1D1ACB008FFD5BBAB1A580C71B
-:107DC000DB7A30F7B7388F2D8EEC4479FA8D4B7013
-:107DD000DDFBA3FDF93F83E795FFC7B832A4EBA213
-:107DE0004D9A1BE5AC5C67FBB544C4378AE62BD7DC
-:107DF000DF29B81DAE4F2C8DF39B12A89F31E8D719
-:107E000087C4AD6200EB56B0179DC8E73E615F2C9A
-:107E10002D1CEF31ED15349FEC7FDD9945FD12B639
-:107E2000A4AC37CF8A0DAFC7D2A2513BA1FD4A6A9D
-:107E30006B3655989DF09CD7F39E49463AC1F85849
-:107E40006FA776796802EBC47E75D87F618F67A0D3
-:107E50003D86799BB3DC2DA88793EF6931DBD19EFA
-:107E6000C6DA1DCF821C4C2E1AE89C1BB12E7DCF8A
-:107E7000F5CC0972644B6EB3B861FE19D046DAEFE7
-:107E80009BBBF0379F0B3D65AC9EEC85F44BACC7BC
-:107E90003D0CF1BEC9C1F1967AF5AE182FEF0F690E
-:107EA0005C3FFC9B6D8167E1F78FB2BCED68474298
-:107EB000A358E58B644F43191571FF3AFC81BF76D7
-:107EC000E47FBCB98525C2FD3F74E0CFF5FA42F8E6
-:107ED0007F25FCC4DB3AAB43B978FBEAAB436EC009
-:107EE000ABF9EEC183D13FC8E7C5675AF9BC8EB67E
-:107EF000B328AF35BB629CAB607DE5C01B84DB76ED
-:107F0000DA02EB32E93AD392B1B5ADD3A0BF26BEC7
-:107F10002D17FD4FE9EEA820CA6DF3EE2833FA9134
-:107F20003D39DEF8CC14BCDE7BB406F2EDDE613305
-:107F3000A31C2439DD0978BD2B7C2F64C7A43E1A0D
-:107F4000E5CCBB92EB9F57E8E14C21B7B3841ECE42
-:107F500034BB12EE02BC6F7E536768C767DDA3F5C2
-:107F6000DB5480362DCE9513A18752DF2C289783C2
-:107F7000513EB95C56B77713FA9D29E6E57A500E63
-:107F80000E1AE9537E65B700EAF7A2F6241A27F520
-:107F900055EA696AB6F7AA4CE043F952D06F788E79
-:107FA00077495A01EA4B584EAC0E94279093D4B9B6
-:107FB0001172B0B4F97B33CA89A5582339B1415B3A
-:107FC0001A21479E8E38C531B63BE0317959A669F2
-:107FD000150BF79766CA78E5E2E4DD95C9E56B56BF
-:107FE0006C30C704F3596AA35C4B00AF53C94EB25F
-:107FF000638BEF030048B0D8E229C53863F16F34D2
-:1080000017DA5F8C3FD0FE0C395C6BF546E0777D6C
-:108010007B7FE6043A4D6BEF456DFF0C6F05F27FF9
-:1080200066FB7441C7FED432679189819FB9C3CE84
-:10803000FDCCE9DA7B6FC2E79D0ED85CF83CB0D08E
-:108040009CDF02DF42B7EBB2BB10BF372DEC6918E3
-:108050007F22CAABA35E9EE8C91C8F008AB3D700FB
-:108060009F61DE1316E677003FE700EC45B81B730F
-:10807000771B847A07EB8CF02B67CC0D192C1BF83F
-:10808000BBF88363663085B7E686FA07E1B955A386
-:10809000B8FF6F5D6F21FF5FDDFCCE1013F47F9999
-:1080A000E9BE8C81ED1D7BB9F7365CCF82A98117C3
-:1080B0002C00DFF6EB97E28739C3F46C340773CCFE
-:1080C000707F23D0D10F78353EA0970578DC13530D
-:1080D000D1EFC272BDA03D9BE823FD8DB4DF5B7D77
-:1080E000A9B088B01DBF901F92F2BD50E8C142D424
-:1080F0000316E96F2A3CA3500EF334570E8BF43766
-:108100005C1FA49D067927BD29CFEEE95ACAC27625
-:10811000DBE88FF6EA8D8F0C87F5FAB2BC4FA2DC54
-:1081200097FCFB7FBDF4117455BFF887D1C8A751E8
-:10813000576A4CD72EC64E7E6F213B794F05233BA5
-:10814000096DA49DB47411A7AFBB44B96F10720F31
-:10815000F12DC58D68C723E7FB28AB6413F2795B6B
-:10816000A6C6E7FB17E16DB4EFDB3AF0BE38FBFEC5
-:10817000FBCC8BB3EF6FA27D2F3CD79E33980FEDD6
-:10818000F9DF76F609A0BD3FC6C0FEA37FDB11E391
-:108190007C56D87BF207D10981F3D9FB5FE7CC7E0F
-:1081A000B30B7BFF67E4FF3F6BEFA57C19F5C1A81C
-:1081B0000746B99F783FC45FC8A7AD1A43FB1A8E24
-:1081C000B718C9F1FE2C2EC7526F22E22FF2F3A08E
-:1081D0000F819CCC73F5F2BBDA0F0A9C986F16C422
-:1081E0000D645A58DEA5BE487937FA913959DE1F19
-:1081F000C90F083DA97ED1E807BA92A76D16CC5FDA
-:108200002DD5DF723F006DA41FE82ADED1B32E2DDD
-:10821000DEF9F622E5A97B168F17FE1BE5A97B5632
-:1082200061A7F27459D63F113F9C878FE467A49CE5
-:108230004D7C83CB07CBE6F13EC80BE1BDDFDA33E3
-:10824000B03413ED1EB787137F62B548CF9B453D11
-:1082500041CAEBA86CEF88AC083E637C8F71FBC50C
-:10826000C68533926B991BAEDF0C6DA4DDB021FF88
-:108270003A89EFDD599766EFFA0BB9B8109F2BB228
-:10828000FEE5716155677C656EEEFFC37CB14D43C1
-:10829000B9F92E6866A85F5DF1D5B286D35DC2CB11
-:1082A0008366E95F93D0BF82BCDC98F54FD89FF21C
-:1082B000D2C6D37608FDEECE1A5E611E06797A111B
-:1082C00013F58F11ABDD66B42FF0EB709A91EA23B2
-:1082D0006FEB122E3E381AF098F84847BF1FFBC7C5
-:1082E000142774D453309590E37F9935ECE00384E0
-:1082F0007703E7A3B7C5ECE9170117001C170117AF
-:1083000019E0B57C3CFA1107CD13E0F61EE6D7065E
-:10831000212CE7137AC0DAC676C3787193E6C07A67
-:10832000C80DC57FB3227FCA4B5B5E4D87F53E9873
-:10833000555A110B21C00D680701DFA7B226AEF612
-:108340009BC5FDDDA93E463FB646CDAD039FAA8B3A
-:10835000B44056E6B9747C2A4BF567F86356EF676C
-:10836000D6824BBB1FF948F767D1FD41DB253CFFA7
-:10837000BA62E60E7462279F9376F22CC0727EA0DA
-:10838000DDB4469E871BC76F12E34326D34206F433
-:10839000DA9175F36AAC978D615C3E7665DD54E1E8
-:1083A000CFE7E8BA0DEB3D1FBEEB3A59AF53BD3FE7
-:1083B000783E7A6D3CE77E211FF3557949307BF694
-:1083C0007D077824246B0E8C6B1779A21EC0F8BD34
-:1083D000BC54CAF7AD15EE62585F1453EA7F61F9D9
-:1083E0005E50311AD6B788C9FEEAD5E8973CA68E0A
-:1083F000F15CDE77681DF7E781FC50290EEE3F9CAB
-:1084000075DB6AA40FF083FA09369F47DE1B0D70F7
-:10841000B1413F847C937EA2DD06FAE4746237CEDC
-:1084200008BE7DADB14AB47BA1121EEF85B2789B28
-:1084300092CDEB243F083A5AB2791B8A8EA0438F23
-:10844000309FE127887944C4BA894ED7278B75FBC2
-:1084500057554CEA05F727B27E1AC849C2332B5646
-:108460002FEB19BEBFDB33AB484E3AE6F3AF3C8887
-:1084700074BC5ED029E599FB0E0A39D250EF1692F2
-:1084800040801C6CD2FC3AAC7321CA4127EBFCEB58
-:10849000B972E437DCEFB69CE7FECFCEBDDF6DB836
-:1084A0009F59922FE57EC1A749063E9619F838DA02
-:1084B00000574938A0D83369E76635AD5EDE3D190F
-:1084C000EB8D1ABA09B4D7566D20637DB31FAD8802
-:1084D0001D86F2EAB4A483CDEF9FFDD8413BC8725C
-:1084E00005DA3392DFC7C97E4F437D27784D857B00
-:1084F00000CA4FEDF254185F90FD9BD576D0AF1BAC
-:1085000096ADB6604C5394FDDBD56698F7FA82FFC2
-:108510007815E7336B4F1E9C94791E796D30AC63F0
-:10852000AD01F61BC63F7A01FBBECC70FF3D86FE57
-:10853000070CF01A03BC52BD7FE61C8DF46426F0D4
-:108540000F097721BD999CDD111776F8332D96E23E
-:108550002445EE272EE57065F6BF57AC8C8D809FC5
-:1085600079AE22528E2D8CFFCC48667EF41F962E5B
-:10857000ECD9D86CB5DED5B19E3CA3BFE3FD7FC579
-:108580005FD3689F45F1CB7B75156ED6A5BEBD7CCC
-:10859000F08E58BC28E16D1558BFE872DFC3BFB537
-:1085A00002F73D263E24FBB756B823D629C78FFDD8
-:1085B000E1271D9FB7E8992D15EBA1BFAA24988349
-:1085C000F5FAAA44DE829FD1D18FD5887AC7D89D8B
-:1085D000BA07FD4C55743067717EC43A59632EAEAC
-:1085E000B3F96E9DF8E35FCAF39159CC65C57A453E
-:1085F000734242DD0618BFF76EBD0EFDDAB1BAA4B4
-:10860000EE984FECCEE6F9DEDE842BBADF02707313
-:10861000CCCD56ACD736DF3B86DA3DBA7B451BC89E
-:10862000F103D9AF56C4F6C1FE04A2CFCA679A2B94
-:10863000EAC15EDD9FEDA4FBBD898EEE4D18AFAEA5
-:10864000B230AC5733E67A8AE4E6D7B681AB008F16
-:1086500099F557D2FED1AC7FAB189B06E3662DB7D8
-:10866000D0BE02FCF447BCBDABC658B17FCE32D100
-:10867000FAC751BBFBC797DEE80FE3DBEED35DEB38
-:1086800060F0AEF6ACF85980D7A751DC0E7FD2DA95
-:108690002B1EF1ECD5CBFB7836CA6B7C5CB486CE56
-:1086A000C3E18C9F0AF366E6B8D7E075397EF78F91
-:1086B0003AED836D6F9DD51DF9B74EC8CDAEF65915
-:1086C000DD6745F8FBB95F9B89CEBBADCE3B30BEC5
-:1086D000DC1DDD53C3BA0CD03909EBB673447C0DF5
-:1086E000F252F752277EFFA16C9DE872DC56C73E1E
-:1086F00005216EBE3FA518F194F7C9FD374B0FE772
-:10870000A0C838FA775794BC909D122967470E622B
-:108710007C4F7134C0DBB23F5CED07BFC2F642FC58
-:108720008F7824BBC7A25CB17B92F83E686A636E07
-:10873000643D221CA72E11F6808F3BEA8FA3BCF567
-:10874000E8735101CC678EFAFF1217597F977A327E
-:108750002F3ECE8FCEF88BB83833D2F598D9F7F9B3
-:108760002F70DFF0490BD9D1B94FA6DCD386F600C4
-:10877000F889F520E373937A59689EAEF707BF54E2
-:10878000F5C47FF2BC7AF26EF6C98AF5F95DEBC9E1
-:108790003C11B78F7DD2E241399F571867C67DBA29
-:1087A00092275F7916E571DEED51836C80F8BC2766
-:1087B0006DC4DF96B838BF03F711E3E3CCDDA03D0D
-:1087C00021EC574B7D14E5297A772BD93D7D45A1C6
-:1087D00013E953AA33B31DFC8A1EEF727A38BC0C1E
-:1087E000EB86CBE38A9CC85F472FAE0F1DFD099532
-:1087F00013B4FEE17DB393758F3C361457CD02D38D
-:108800008766FEF3FB6835CC9380F5C7FFAE7D34F9
-:10881000AD575CF2E7908A87F7D1F213AE43F1AB24
-:10882000D3096F7D495400E9A967703F318E69B45F
-:108830008FC61CB0FE7EE17D34FD9783893EC77DE7
-:108840002057BD812EF1761AAFFF520FD8E0B9A59F
-:1088500049BCDEAA3F56C1705F0DE8EA77003C2EA6
-:10886000B996F6D77E25ECCC4C8D791A49FF5D1967
-:108870009827CF7D328AF838EFA95BDFFF4D01F2F0
-:10888000AD3C39529F7A08F983F9983D313CCF17B6
-:10889000F5BFCA407C4A7F07F925E69DBAF7B1EBE0
-:1088A000C96EC6D07E1B73B4FC7A28CA4B7DCC40FF
-:1088B000AC93CF7B322D232B3F7CFFBC2577E7F297
-:1088C000FB216F8D47BB1545EBA9DE6423799979B0
-:1088D0009FEE263FD9D34A7EF29365510457F7287D
-:1088E000227D9B69E2FB6F1013A6927DE72467D57A
-:1088F000B1CCFD522CDAFB07423AE78F5FF0CD8A0C
-:10890000FC19DA2B899E7F33D218FCD77542DE66BC
-:108910009AB81CB15D1AED373156EB443B5065D225
-:10892000C8DE19F5B2AC178F5F6766B86EC2FB166A
-:108930003E68732DC9E438E8121FC89B169A42732B
-:10894000711F926DB1517DA306D61115CFCF3DBCDD
-:1089500008F8D79899D98AF52927B76B129F1A6713
-:10896000C5389457E83F6C86FE8571DC2E2FECC627
-:10897000EB3E2CCE1E7836F279887336BFCF198F36
-:10898000FA368CE405F5DF04FD7F63BCBF34BEC856
-:10899000D9924FFBF72BB15E82F8F4E91FF15C80AE
-:1089A000D3FAA33CDE6ECE8A433E244DAFC4E73DEE
-:1089B000AF937D02A57AB008E3C0E7F5C198CFCEAA
-:1089C000BC6FEFD83508FF69A0035198F9C2BBE42A
-:1089D000A76E1372D682F13FFA2D80FF046D6D2FC2
-:1089E0006E1FBC3AAFE7D4F6E2755E4957D9BFF0C7
-:1089F0003E0BF163E1722E0F0BEB3FA07917C6859A
-:108A0000BA233F166EB60C41B9FE85C07B567DCFAA
-:108A1000E2C3201FB32C090E0D2E55FBCBAD08571A
-:108A2000376804CBE72DBCEFBDEEA67C3E1FB63603
-:108A30002147E1795332D0AF7DF55C52C6CC08BEF8
-:108A40007FB56C6B3CEE6B7F1A15CC71603DE6F622
-:108A500028D73AD253CE8FAF96E5ACC37ACD1C4718
-:108A6000280EF7C3E7DC919D88FEEE982368C5FECB
-:108A7000638D992684DD0E4731C26EF30082BF12EA
-:108A8000E754E807F8B448E37253FDDC5E6B163C2C
-:108A9000EF29419FAF9F7F3717EB060B3342B9E8B1
-:108AA0008741AE72D3912F7FD4285E58F49CEE8E0E
-:108AB000EA1F96AB452857A0FF0B845C2DDAB4F56E
-:108AC0002ED4D345284F83CE954BC82FF7D1F51719
-:108AD0009F1ECBF8FDFB50EEA4DF07789905EB6BEA
-:108AE0005601C37310FE1DD23F85FA47F37E7F3EC9
-:108AF000F913D662C5B8B846E7F102703615E389B6
-:108B00009A268BBF25C23E2EC2FEFC707F57721381
-:108B1000EC25F6CBEA6DE4978242FF5AEEDB1C8F20
-:108B200072F1F5F37B5F1D8E79D68B9A03EDFE39DA
-:108B30007A28E85683748AA775527C548374890F07
-:108B4000D3A943DF845CD4304E0749971AB3A0936E
-:108B5000EC17F7370B39AC6682AE9B7A737D17FA48
-:108B60000D12437E44AECF9BA89E1F3825E4FE6DB8
-:108B7000B1CE6A901B573EC997DB3A44E4FFD0F56B
-:108B8000F59F9EA6FA91E4A7C43B3A873F1FECB439
-:108B9000BB5B6298CF2D2636BFB37AF56742AE2C09
-:108BA000B1DCAE7C5C9F7E531DD06FC173BA8B88E5
-:108BB00087B957C4736DA696388A4F7FA93B705DFD
-:108BC000A5FF5E3101D72DE5CEB2513337E13E210D
-:108BD000EB46F497F8955EE699D08DCB5D10F19158
-:108BE000787EAC05895FFE3F690E1EEFB658B18EE8
-:108BF00028F5D488EF2981AF1EAF0DD706203E2E71
-:108C000027EA37033F48F8C41EBE9B9EE73F7A77AA
-:108C100066FFF0738EF9E3CC38EE18E37640CAE5D0
-:108C2000C7A22EF1F1F2AD140FCBE7D873B85C45B3
-:108C30003CC75B977CEE733AE2BC1C8E97D48BFDED
-:108C4000895CFE4B977D40E3A49DC51FACC7497A64
-:108C50004ABA45E8A5421FA95F529F245FFF51BD54
-:108C600062F7A450DC7AAF5837E948F7B05F40F9B3
-:108C7000447F67B3F27370117E93E29A713DBEB583
-:108C80007A3BB92EE964BC1ECEAB1C1948FF71B10A
-:108C9000A9B45FCE96A5EEEB15119F7D8A752FB412
-:108CA000A77FD003644F196865843F97715BFDED22
-:108CB000E31CA350BE9ED3E8DC91F4DFF0F34087C1
-:108CC0009CC27CF30B6ECFC57862794E16F767C9EC
-:108CD000EE93787FF589D0D87867387F19793AA8EC
-:108CE00027607D7053A6923F54B7EE233D5FC84284
-:108CF0002B30DF9D79DFBBE54391FF7FB0D0F98555
-:108D0000390D99E4FF4EAE9F3D1853DB99CB7308A4
-:108D1000BEF5D95B387C1F8FEB662E2FDC80F5F912
-:108D20004FA3DC6351CEDB566B0ECCBF463C5B7869
-:108D3000CF0DD03F22EE8A6E88EFD1F59F960FC7F8
-:108D40003CA24E27BD71AF7F643AF6BB9B74172ED1
-:108D5000710E73DC7303CAB93981F44E9E6B5C6A81
-:108D6000E1F2E6CDE176A33287DB8D4A21BFA54B48
-:108D700097E6E2B982B6A7C14FE1FEBAD5D918C4C9
-:108D80003C70E765AE75F09C1A485B53419E4E6897
-:108D90003C1E9F6F657694AF0396D09D88FF813B04
-:108DA000E306D62302FAD921A81F6E9177411E450A
-:108DB000CF95F492CFBF59E8819C47DEB71FE32AD5
-:108DC000F42302DF93CBFE301DE385931B7312590E
-:108DD00004DD4FE2BA80DEB7827D7CB1937CB03A8D
-:108DE00047D6B902FC39A28E78C0D2D003F77321DE
-:108DF000AE3F1E199F7FF174941DE512E27AF5BA19
-:108E000085FB1588E795EBA03F0ADC91EFE9550952
-:108E1000DE4EEC916C8DF1BE2F27B6D3785FEA9FC2
-:108E2000F17E19DF77D45D7A5DDAB9AE561F300670
-:108E3000146228066780EFE8981F5EC2F397731BE1
-:108E40006C0E1BD0F738EA17EE0B6ED679BC68E7CC
-:108E5000FA767CE7C000D615E61E61AE20C0730F1F
-:108E6000E92E278CDFB7FA5E3ADF71CB5A8D5DA60B
-:108E700045E45D8FAE9E8EEA76CAE55D9106E34FCE
-:108E80006DE4E751A03BD6906FBD9AE6EC3ADFFA6D
-:108E900057E559B2FE64A4FF7FE4887CCBC55C2A09
-:108EA000FD79DEBE1BC4A868D0B9F46FF57929AF8F
-:108EB000FAC6379FDA618D4F97A6C33AFEA67DFCAE
-:108EC000E008D4A3B804AA9FB4FA6A6973F09BA619
-:108ED000C16727039DB6C72638D07E7CE3ABA3EBE2
-:108EE0001D7223E474E4A6663D9DD1F81D2360FC49
-:108EF000AED804DCEEE8641F8EF3D978FEE667B7DF
-:108F00000FBD0CAFCBF57EF90BCE6F89FF971B67BA
-:108F1000C763BCDAFCDBA41DC390CF31090E1485F6
-:108F200079E21CCEE76BB83D3A614FD88075D41317
-:108F30006BA775C7FCF0164B9BD505F3BA7656C4E4
-:108F4000637DE433734BBC035B181F443CCC011DB1
-:108F5000EDE0F03246FB83C38366E6CCA4AD7B92A2
-:108F60009F61ADE600E6CD5FE1BE21FAF1B3D17CB1
-:108F7000FF5EEC07DEB28DD7D93AEA2AA2BE3042B4
-:108F8000AC37363751EE03D1F5D2227EFD8BB52FAB
-:108F90004DC6F94EAEB73810DF6FD65B68FE059050
-:108FA000DF9B401E4F6CE4E70516EC803C3913ED67
-:108FB0008846F2BB00E4D78EF277BBC56D4D3857BB
-:108FC0002E4B37F2FC7A41A346F9B694CF05EEC09A
-:108FD00058A2BB90533BFCFB095C4737D6B802E96B
-:108FE000D195BCFEA3F5003DB7F37A80511E24DD78
-:108FF000A45C84E594917C4AFE27360E1C954E377E
-:10900000F8899EFE129687F1C2522BCBC3F3507E95
-:1090100053B40BF5FEEF51F1FDB10E5567E7ED5D71
-:10902000D1F1EBB0FD7B544600F1FEBBC9F10AE67D
-:1090300059BFCCCD24B9BD4B775A34F8755A72CB91
-:10904000687203A526B709FDE0521BD911A31D7252
-:10905000E672FFB32D97D1FDC5B9FC9CB885D552FA
-:109060007C215B88077A62FC52119378068F92F715
-:10907000CB4D996606B9AE1891786736449E85B98E
-:10908000E9D370FFB76270E2E62C80876E48E3FD9B
-:1090900003120B2D00D76B3DA68D86FE6B72DD573C
-:1090A000E6463C47CE0BD7FBE3F59234EFC0DC1429
-:1090B000F473B12BD10FFC4D6B5B64D2C3E30F6A29
-:1090C000ECD8762D0CB7585806C6DBC5887F4AD732
-:1090D000EDD25CF770FE5CF5FA2C0839B02E31CB7E
-:1090E000FFDA618DEC19F3D8819F5384FCCDB2C7B0
-:1090F00006C9CEADB4B476C84716DAA90433F27DFA
-:10910000B260FB1473B019EFEFC396393EB753A8A2
-:10911000B8F6A7A4AEED3F282AFB5CCE07EBFB9B7D
-:1091200005D60B7CD5DCC06B50310D885C05F64E46
-:10913000DBF1DAF738EF523F6B89223E5439F07C8D
-:10914000B7C6BCA69FA05D18037231005B900718DC
-:10915000B778F3D7FB502D6E957196B788E2C53B73
-:109160001C7C3DCC3B9CE4F54E21AF5FF82075079D
-:10917000F99C120AC5E351D8D6C9C15CB40F65BACF
-:109180007736F2E18BB54B7B2C06F9F9FA459B6BF0
-:10919000128C3F1178291EFD6AB588F7D9593D78A0
-:1091A00035F4EFCFECB36E55847C55E772BFDF9A90
-:1091B00019CCB81BED4C26CF57D9D9BD1977C3F8B8
-:1091C000B2ACF185AB880AEE45B911FB9393CD9D06
-:1091D0009FDFA8E8C1E323B69EFB639B99F9E312E6
-:1091E000A965F140A7F1804B119E4B0558A7FDFCE6
-:1091F000003D1FC7C5635CE39C9DCAF77B9807EDE4
-:1092000096E4AFE4DB39FC049431AE37D99905D745
-:10921000DB87AD75A0FE4BBE7E21F4F10B3BD7C3BF
-:10922000317A2CD9A9C59B795D6FB1C6EDEDE29D70
-:109230001AAF6F9EE36F37AF409B3C7FED6CB26718
-:10924000D28E39E11FCAD702872721E8FC07FCEE3E
-:10925000DAD28BB2674FE68AF70406B281287F170D
-:109260008A97A41D03F6ACBF247E21C960DDF304F8
-:109270008E63F42AA719E9926277A13D5FFC6436F8
-:10928000F94976620D8B1CC7D62691FCAEC8D489ED
-:10929000AFE54DE9CC09976E6DD2E89CECA4A6240D
-:1092A00082E3DBD3082EFFFD6525B8EE8E7DD0DF8F
-:1092B000F726F8E486370ABCBC4E63C7F93D4CE29A
-:1092C00091DF88FEE7542CE00174F6C4AEA4BAA383
-:1092D0008775E443DA4F1AC22035A8776E8B9FF367
-:1092E000C75E4FFA2FD6B558E8D5E203DC5F2F1ED4
-:1092F000C5F70BCDFE3E09C87FCB7E9D0500BEF6AF
-:10930000805E1884A14B853DB7A59A9833826F5132
-:10931000CE68E68CE00FF3BB43986F550A79B937F6
-:109320008ADBFD98BC44655C65EC5C929F50C6D8B6
-:10933000FDB8DE38D7E5CABCCCCBE3632957D345AB
-:10934000DD7C326B5B867EF2DA4AE88F98CF52FC86
-:109350002DF90D4BB11A57035D8E9F4F9EBE90FEA7
-:10936000B10FEB43F264A00FE807F9FB5387F8FB5A
-:109370002710953C5E0CF0F4FD161680FEE5822E5B
-:1093800018B762FE73CA1D477A23E52E847E0FEC60
-:109390005C42914AB76E6E956E49652A7D523C2AB1
-:1093A0003D2EABCC52FAD3BC7D95FEF4F98314B8B4
-:1093B00067ED7065FC1575250A9CE99FA08CCF5E52
-:1093C000395581731A6E50C6F75E334BE9EF135867
-:1093D000A0F45FB971B102F76BFCA5327E40D312E5
-:1093E000A57F607095D23F78FFC30A5C187A421956
-:1093F0003FF4F03AA57F58CB1F95FE11275E54E04D
-:10940000916D2F2BE3AF6EDFA3C0A3D81BCAF85218
-:10941000FBBB0A3CC6F11765FCB8D44F95FEF1CEF4
-:10942000AF94FE8979DF29F07211E794BBFE4BB946
-:109430002FC496E5A01C3B7B788B7A53DDE784191B
-:10944000F5EFF08D1A4BC2FC67FF3407E9FD25E606
-:1094500081EEDEAA1C9F61B137E179F60BD9C50C0C
-:10946000114F8CD127D17B55A71A79BDC3E8D76599
-:109470003C97006ED91CF1DC6E6E3B24F46138A978
-:10948000CCA1C0299E5465FC65954EA53FCD9BA7F8
-:10949000F4A7CF772970CFDA2265FC15756E05CE5B
-:1094A000F49729E3B3577A1438A7A15219DF7B8DBB
-:1094B00057E9EF1398AFF45FB9B15681FB35D62960
-:1094C000E30734F995FE81C1954AFFE0FD0D0A5C82
-:1094D000185AA38C1F7A38A0F40F6BD9A8F48F38D0
-:1094E000D1A8C023DB9A94F157B7071578143BA095
-:1094F0008C2FB51F54E0318E0F95F1E3523F56FA91
-:10950000C73B4F2AFDD55FB982B42FB59DBFEF2A67
-:10951000E3B98979DF2AE32CC910EF63FD9B45BBD2
-:10952000F0BC7F5771BE8C03CB5DDF2BCFFDBB89B9
-:10953000C7E7BFEFCDDF4FBB4BE771E252BF87CE2E
-:10954000E725E28157D09304BF46F287295615D507
-:10955000239369DF825CA613CFBB411C0440A22980
-:109560003313F39098701CDBE3A7C1171FC76E86F7
-:109570001C07F138DEDBFBC7DE8598B7FD692CE6FA
-:1095800039B732FF0AC403FC6E02EE63BD15A5D6DF
-:10959000A3643BDE0E748C78DE81A8861E83CEA386
-:1095A000BFE3EDAD34BE635E51AFD2607D8B23E689
-:1095B0007F10F22F33E869830FF40C12ED877D0ED4
-:1095C000821FF5A512FC98CF49ED1A5F1EB54FF822
-:1095D0005CD4BFD65744F0533E37C1015F19B5EB99
-:1095E0007C1EBABEDE5749F0069F97DA8DBEF9D4CD
-:1095F000FED1574BFDCFF9EA087EC1E7A7B6D1B738
-:1096000092AEBFE86B2078936F0DC15B7C016A9BC3
-:109610007C1BA97DD9D748FD3B7C4D04EFF20509A1
-:109620000EFAF613BCC71722789FEF30C1AFFA5A73
-:10963000A8DDEF3B41EDEBBE36EA7FD3D74E70ABF2
-:10964000D84FF8A4B7A6BCAF2761C646933CC8F86C
-:109650007732E63D281C45966F94BCC7907F18F979
-:10966000F1A5788EA504C25F8C7F2ECF5DB7342222
-:109670002FF8463CEFDE68E68F027DA837F1BA404E
-:109680007D22A3F7C39888CFE709B964C93C2E9F10
-:109690002BF09A27F4A010E5338FE4F3CD4BC9B338
-:1096A00064BE1D93E1FD91E4B3A7C94F758758FED1
-:1096B0001E7EFF0CAF9607FDA76A6F79959EE77037
-:1096C000E5E243CA6DC194EBB09E7440A73A6C5773
-:1096D000CFAB11EF4974D9BFEB640FF447653FEA94
-:1096E00054AF7FCB125789F596A43C5E874DCA33A1
-:1096F00029EDD60C4F621EEEDBE7D46EF899167E8C
-:10970000FF7F0AA6E6A0E715CC69A173B8CCFD0AD5
-:10971000BE7A732D047C085FC7FCD48EECE94DC77C
-:10972000F55C0F0906C2DEE1B68CCED663C42747CE
-:10973000E09323F090EDA10C4F2FC4E7788E5BC12E
-:1097400027EA0AA73857DFF614E2F59F3BBFFD5C16
-:10975000CB0ED35BD637568C12E7B46ED7E43E38C7
-:109760008F13ED4CC689D45F7527AFF7487F79A476
-:10977000A3E5F6F054AD85EC669516EDC278FB5482
-:10978000ED9D0370BFF046C8F770FF54DAD12A8010
-:109790004D0057317EEEA2EA481CC999D1BEC27D68
-:1097A0000CF7FBAA2004C0FCF16C06AFA7BCE5F9DE
-:1097B000D682F3B2E4367A6F15E4660CAE7FC13020
-:1097C0009DBEDFF0962990ABE9242F560DF09F97B0
-:1097D0000CF2D249BC20E56291782F475E07799B55
-:1097E00082FCF966DBD03CDAA7D935CC89F45C6A17
-:1097F000E2EFD5F95FD7F9B90C2CE5E3B99184FC18
-:10980000A7E9FD020C2E907FC3E2E8FD82669DD59C
-:10981000FDA9137B5A2BF8F856AAA52C40F3AAFBF6
-:109820008AB7E6F1FACFAD795C2FCBF71CE889EF68
-:109830000D2EDA6FA1BC8815B4E47B3A3957555325
-:1098400077FFCF7B45C8794DD3C7FC3C166BC98FDA
-:109850003C87B552CC2BE54BB7C6799F8E8DC4AFF4
-:1098600043CE6B849C7F8E71FF649B33E13AB8B525
-:1098700005481384D6FB3B079DE793E7FAE6300FD4
-:10988000B5F380DD28D71EFF6A7AAF7E016BA4EBAB
-:109890008B8A6667205CC3DA46A7C27CD7AEAC7FF2
-:1098A0002515B09BD6B07A0CD6B9A70666BE826DD8
-:1098B000C57AED73BF93F4C48FCF6FD16A975F0EF3
-:1098C000CFBBE1B951CBB18E3C59E77C606F703EA4
-:1098D000803CB9F5C473D7077A71AFD00BC25FEA89
-:1098E00045D512E6D692C3EF8174E849D16D7F4D1C
-:1098F000C73D16731B9D43A9D9654BC4FAC902C65F
-:10990000FD76B80EC4FDB5D4832F2D9CEF5F3EAF1E
-:10991000D17B365F6A8CBEE7D055DC20E34FD03F69
-:10992000AE77C762B8FCEBA2AE97E14D1D941DF671
-:10993000CF5F9A0243E2B3C97F3F83EBB194781FB4
-:109940001888E7F55ED05C4B01972FBB0532F839DC
-:10995000810E3FC07E8A09D7091FB4F0BA9D31DE5F
-:1099600095EBE80A4F9B95F9713F4B2B7AF57B8C71
-:1099700043CEC5D79B3A04E8B214598475C9128FF7
-:10998000B3333C9689E7EFFF81E7E3FE9E8CCE057B
-:1099900019E9A939F873BAAAAFDAA2393ED24F4908
-:1099A0003CCFC58BF3EBADBC4C5E6714F831E6C819
-:1099B00073C0F3CDE66817EA6B85D9FB67D473599A
-:1099C0007F9379F1FECC2FC81FB0B34B7BF0F3C768
-:1099D000C1AEFC706B473E9E15F693B28EC58A3BB6
-:1099E000AF477AEC0EB25F53998BFC451F7644D299
-:1099F0008BEA583AEE10529DD74BEBB0A1BD86369C
-:109A00000AEB28E42F0324AF318817AD2B841511FE
-:109A1000B63A269EE830FC30233B3D1CD700EBDDF8
-:109A2000F9310BE079AAE633D34BE3A07FE7D766A1
-:109A3000CA831E8F79211DBF23B1F3E4FBE958EFE0
-:109A4000A93FB385E021AD634FF2FAD9911938DF10
-:109A5000F6D356A78DE280DB890EB24EB99D311741
-:109A6000EE83167D184BEF19171E6A8C21BA89BA3E
-:109A70005AB15877F1695E0FD985C030C803DAACA6
-:109A80002C18112F5B1C2A5CC422E04C7C24C011D2
-:109A9000758E4BCD1FED7D445D6D281B1A595763A4
-:109AA000ED899DBE4F65DC472CD038DE9FE679BA44
-:109AB000F5A13ADB549DD3FB471DE975756C200D6C
-:109AC000E3DBE65B37A461BCFB78CC8F44C7277E21
-:109AD000B0A6215D1B46FD27F99106B83784F9AF82
-:109AE0003910C5A8FEB590EA6B570B3FFBC4D94FA0
-:109AF000582AD0B3A18891FF64C20FCBFE86B3A7CA
-:109B0000E6233FCF14DB9D681772453DB4FEAAFFE4
-:109B10009BDA12418F9D10570781C1DB21AE0E42A7
-:109B2000ECBF0DE26A84F1BD536C37435C8D6D0070
-:109B3000E26A6C9F82B81AC7615C8DED131057639F
-:109B4000BB06E26A6C1F83B81AC73D0A7135B60FAF
-:109B5000435C8DD71BCECE2A257C0E337ABF7E493F
-:109B60004CBC09ED2BE01F8D75A1B7DD83A2911EC2
-:109B7000579D3629FC2D6E8D56E0E1C713C3FC4579
-:109B8000FE1FB95CE91F72284BE9CFF4F755E02BB3
-:109B9000EA062930D68722EF4F9F5FA2C069DE090F
-:109BA000CAF8CB2AA72A708AE706657C52D92CA569
-:109BB000FFA178031F03D526958FFCFB0A678A63F4
-:109BC000E97C655772FAB0E08B841FF9855ED9593C
-:109BD000DD766E1FB95FCFF381CB056E8BFA384906
-:109BE0003EF71D1DFA87DC02E487896F9BBADB62B2
-:109BF0007A015F721F31313C5748270E003F87B80A
-:109C0000EF9192533128977BCBAD51C89FDDEE92F7
-:109C1000688497945BD322E5A821D33B88DE53F078
-:109C2000F2F5C9FB1F2A997ADE7DF48751FE7A9FEF
-:109C3000A77FC2822CD48773E8C8E6D37E6D988E46
-:109C400053E9FB4ECC3B5FC1DFA8170C37E9D3F0DB
-:109C5000B976959EEEACFB900E4F3C6AA673581DEC
-:109C6000F389FBE57C63F4B3312DF9E7E2BFDBCD8B
-:109C7000C743FC1B8574816729F825BA9CA3903ED5
-:109C8000BF11FAF66F42DF1E177CC53C1661E6E095
-:109C9000F749BE35CC7F787C2EEA4D11C76BDD3598
-:109CA0000F6B686E9298ABDE1141D747051E4F8946
-:109CB00075ADC579014EB9C6AD21FD32EA3C1AEA4F
-:109CC000DB15F7B410FC84D0EF1EB56D74BDE71D35
-:109CD000416A2F9F1FA2FE31FA73B48E0E3AB85418
-:109CE0003A1AF91410EB91F386EF7FF100CADB19F1
-:109CF00037C73FDE1FEB467F11EF77B878EB14AD27
-:109D0000CB85763FDEEF16706D3EC2DBC4BAE2FD56
-:109D10007E8203625D0DF3930F6C70869FC79C3546
-:109D2000A6487FD3953C6D15F4DF2CE864BC6F9B8F
-:109D3000A576B0A313BD92ADF4A745474C06BB135F
-:109D4000ADE8FD01FC85FB8177C80FF83DBAD8BFAF
-:109D5000223A4EEBC897AA489E56C7DCF406E6DBCB
-:109D6000D71CD219F7B7935F417BF9EE781BF9D373
-:109D7000E6F1E37A46CA5D9358C75641F7617EF72C
-:109D8000D13B60FC448F8DEAF14399BBE79D30DF06
-:109D90008449BA2B08F31DEAF0279E187EDE81FB6A
-:109DA00093A9620D7B264DBB1F9FFFEE21B00BCE0A
-:109DB000309EB27F73D9B489FD908F21CEC7AEE8B3
-:109DC000F39AE0D72B02AFBD825FCD42BE770B7F07
-:109DD000B253F893EDE84F6CC8E722B11EEE4F3650
-:109DE0000B7F12427F02ED5BC29FBC89FE04DA82C8
-:109DF000F1D9A3C96EDA35E14F2041A1F3048B9468
-:109E00007549BCCA7AE80ABFC626C728FC1A1D9B3A
-:109E1000A4F49798D315D87D364B81AF3ADDD7E0BF
-:109E2000A754BF32FCF870839F2A51E0218726286F
-:109E3000F757B8A729FD538A6628FDE5AED94A3FF2
-:109E400013FB6185FC775618BD56A73C57EC3BC900
-:109E500078EADD329DF66D86BDA7BB22F5B690751A
-:109E6000EC9399709F0CC217A759CE97A5F4531C79
-:109E700075C8E249C7F37BF5152087D0161F8238D5
-:109E80008D8A8F20D710F7167AC6511C08F1D26040
-:109E9000E2431BDF6F92FB56C30CFB4F13F2D5FD61
-:109EA000A9C20BEC4F8DE8DB455CD62BE9A2E23270
-:109EB000D02F8ABF1E8FB9692FCACDB60F214EC5CC
-:109EC00038F7C39F53FC25E3B6AD9FFD9CE2DBADA5
-:109ED0001DFAE255F4A550E8ED9643594D2DA06FBB
-:109EE0009B5335972035E94B91D497166137CB6A50
-:109EF000E8FA1071DF568B2706E3BFCD8797887984
-:109F000023EC08C5EB117604F34896A8F6A7A687BC
-:109F1000FBB338B322C733D6D730DF20033CDC3065
-:109F2000BEC4004F308C9F6A806F308C9FA5F43781
-:109F3000C1BACF176F6F16F6418E2B347B7457273B
-:109F4000F676C821D5BE324F8D72EEA1F9E85CB22B
-:109F50009B5B8EAC10749CAFF0678F7CCE21A0739E
-:109F6000FEB9F79798FD31FD410E4A0E9B5DF5CE87
-:109F700030FF249F18E6C311F395DA7545FF9A0E5A
-:109F800073FE76B5CE5DC23EEF107EE66543FCA65D
-:109F9000FF70FADD29203F5B5A4C945F6D393435F0
-:109FA00009E7DB7D760EE1DB74D844EF91ADFFE38A
-:109FB000A46BF17D45899FC4A7F0BD2531B8CF7A48
-:109FC000A6C544F6AFD0E24972744277A37C7535DA
-:109FD000AF945B08A092902EBBC10FD1B961614FC5
-:109FE000255DF61C7D8CE8BEEDF0E224A4FBD5EDEA
-:109FF00026852E23DBD4787DC48944051EFA318F53
-:10A0000007C1EF2AF4BD10DE46BDC09D1115BE5C30
-:10A010001D7F91F1C076C1A76D824FDBA35C959D3A
-:10A02000ED6B6C3B669D1FF95D854FFBF2BAD1A7C6
-:10A030007D79FD6D33F011EDEC99E326B2B3231C6D
-:10A040008D7A6D27FC286E3519FC841A375C6ABE40
-:10A050007AACAFD8EF34D8C5AEEE9776B1447E3F38
-:10A0600025744DA7E763C37C10E72A0DF49471F4BF
-:10A0700085F926CFA31BF8D7C5FDE179FCC67CFA8C
-:10A08000BFFA62FDA5A582FCCDEA98B7843D7F8B1F
-:10A09000ECF93BDF0B7BFE7D778A930E8EBFAC27FE
-:10A0A000EAD1C10E3BCEE222EDB83C0F196A7D2702
-:10A0B0002632CEF70879DCE97E77E200E4672FFDEF
-:10A0C0007F34DE794BC43B6F62BCD31BF78178BC15
-:10A0D00073C03D9BC73BA91A7D2F6649CC55666F5F
-:10A0E0002772FABF3DCE9952A4C639E52E35CE91DE
-:10A0F000FB07BB1D1A9DC39A98A7C63DBBF117ACC1
-:10A1000033D9B500BEC7B5DD3DEDBC763828F4FBCC
-:10A1100080E0CF6BC20EBF22F2861D487FE24B99D2
-:10A12000E00BAF57149F76C5BA9CC89FF93C2FCB64
-:10A13000ABA17C7AA4F4EFBE5A1A7FF0CCACD3F872
-:10A140007EFF6E470CD55976233EB0848316EF69A7
-:10A15000FC7EC56EB7E65CD2495E3FA24DB50332C8
-:10A160004E9072B9BBF51392CB5DEDE7F7A7D27EA7
-:10A17000C971AFB1974A913E57B5328679C385EC24
-:10A180008FD12F5EE839C6F123CC8D7A677EC7F870
-:10A190001C4F7B50C7F3CF3BDB4249B85DE7091E3C
-:10A1A000D0F13DF0E2B620E1BBCFAD39F44C1A5707
-:10A1B0008AE7A25F3BFBCE44BCBEEBB4D964A37D6F
-:10A1C0002607E96DB1D0CF37CF9A625D445F9DF627
-:10A1D00039826D9FDC8FFAEAB7EBF4BEC8EEB38329
-:10A1E0009223E9B6EA4A9DECC9F6D13613D697B761
-:10A1F0009F368BF3D6418A1F76B467C562BBDD0DEF
-:10A20000FA43F62244F47FEC4A07DDB713E6E3761F
-:10A21000C249784839089E369575F6BD9DC7AEE4AB
-:10A22000EFD18F38FBD718A4CFABA7F7C4A0BDDA06
-:10A23000D5C69F33E29E9618CC33DF6837C5F1BA96
-:10A24000CAE064BCDE3CE6DED841B8AE3613DFBF00
-:10A2500011718D7CDEEED1F3A89EBFBB8DE761BB93
-:10A260004FF3FAD1F6003FB7C6841D93E3B79F9E24
-:10A270003AB11FD60F02161A3F820556C4C3B8570B
-:10A2800052B65E49E76BFCD52CD2EE953AD438A78E
-:10A29000A4CDE09FBCD5A407920F07BF9D7A4D05C2
-:10A2A0009DAFE77672BC59B52FBB4E2F499E8ACF22
-:10A2B0008FE5CF67017EBFCCCFF0C71CF1DD95FAEB
-:10A2C00031D74D2BC7F936F373662362557B767011
-:10A2D000D4ECDF2EC4F3FF9B62C8CF6EC7F5E3FC5E
-:10A2E0008718D5CF76973D521A8F75EB56E6E271F7
-:10A2F0009C6AD74BCF6CDA1B0FE3DF59AF117DC7D8
-:10A30000E5A9EBDDE9CEFE35E6C1675A397D653D4D
-:10A3100049EAE59ED6C41BC93E8D86BB818EEF946B
-:10A32000BD4475EC5B03EA3C4337C628782F6C4983
-:10A3300034E46F6A7D1CE24D591F882D1F12CEDF59
-:10A340000ADB797D7DE80F53070701DFE2D1FCFCD2
-:10A35000BCB12E3EDE6C53E32C435DBCD0581737A6
-:10A36000FA73118F0D11FB1AE7C43FC2CFC97AC32C
-:10A37000364B7086E712E2876166485DE85CAF376E
-:10A38000A900E8FFB2882F87591B7E9606AAB2550E
-:10A39000F78F6011710173F859F290707E3BFCB831
-:10A3A0009A0F141D51E512F2C7CF319F5C897B9A39
-:10A3B000A4077E7E2EE222E38CD531FD9B5A80AF2E
-:10A3C000430F31B1DFF17FF6A25C357D26F73320F4
-:10A3D000F4E88EFBF38CE2EDE6CFAC24775BC6703D
-:10A3E0003F25E314B94F730D6B5956AAE1B96CFBC5
-:10A3F000F216A0E7A68373D317C1FCEF7D44DB9D63
-:10A400006C4BA1FC3E7D83925F0E9575A823267F41
-:10A410005201C6EB3645AF657FD3912531F87D916A
-:10A42000332113C969F38756867F1FA069878DF68C
-:10A43000739A0E5B69BF65DB0EAE27B2EE2CE3FCB0
-:10A44000D7853DDF2FE2DE5745DCB24FC42D7B447C
-:10A45000DC121471CB2E11B7EC1071CBCBC26F6E26
-:10A460003A22F4EF9E9800FF8E2DAFCB4A3C6FEE60
-:10A47000DD72D40C0BAEF968C89A20437FAEEAC9EE
-:10A4800078A7AA27E35255FB31C691AE8C2FB5674A
-:10A490002BFDA3D8954AFFD5ED830CF9C870433E38
-:10A4A0005262884726AA7A792822DFA5FC5ACD77FE
-:10A4B000AF8DCC7733914F3C0FDCD6F230F171DBAE
-:10A4C000F1AC84C8B8EC65A137DB8E73FFFCF28970
-:10A4D00053719DC56D27043FBE14FC6815718A2712
-:10A4E000CD7D7D7E0AE615A7AC78EEA32B7996F795
-:10A4F000CBFB4E043E8D8FF47F9F51D21886BFDE7A
-:10A50000F2975CAA9F5CA47E2C8DE3E7DC366BD1CE
-:10A51000F4FEFD85DE6BA9CBCF12E7926A07F07DD2
-:10A52000D1DAA1D86EB078D2F1FDA7CD9A6706DA5C
-:10A5300071FF6FAC9DFE3D095FBE3CD7C49AD03F12
-:10A54000F023C9F0F39C6646F98A12E0D3CCEB43C2
-:10A55000FAD8315F87417AAC87E1BA36595813FA95
-:10A5600079E6664E4777C655089E73AA9F77398E5F
-:10A57000D7427CFF18DC2B7DEF038F66E177B7B005
-:10A58000C57D329B9DBF7760C9F7DE9F5FC8BF67FF
-:10A590009B3008E72DC9E6FBA841B2DF33C4BCA657
-:10A5A000981D3DC99F7665570D792EAB56DF473113
-:10A5B000CA4B93B0B32F677A6674F61D8C67F3F9B4
-:10A5C000B9906D5F4CD6F1B905F67837FF2EA45BD4
-:10A5D000C7F7C05EFE7242CCCC4EE42CD87FE6B307
-:10A5E000F911725010AAD5C5DFA930A9F52D531065
-:10A5F000F97D26D64A7A3D1C179C78EE7C234EA81E
-:10A6000071DEB01635FF0FEFEF376878DEAC439E92
-:10A610009021C8FF83FC7B1A179227E3BEFD07F940
-:10A62000F2BCA4F72F788E584F88A5F3359B0EDA2D
-:10A63000D7611C69ACF7BDFD1EB7E346FC9BDF9BF1
-:10A640009E8EF1D7E691D7A5A31E6F41034FDFF38E
-:10A650005934DD1D09E3FA63D1DE33FE9D2D7FF50C
-:10A66000743C2FB365BC8417F2F1A3F8F8F79F7B15
-:10A67000EB31FC1ED8961B453F7B808F97B0BF66A1
-:10A68000FA28ECB79808AE781EC6437F7B5FF707C1
-:10A69000246FF9EEC328A71B5077001ED5D7FD11F4
-:10A6A0005EFF00650CAEBFDDC77D24128EEFE33E7A
-:10A6B00016096FEEF02F6DB191FBC7520EDF3E3CD5
-:10A6C00055F81DCEF72932AF29BEB83AFF9F859CB9
-:10A6D000BE21ECD501E13F5E13FEE315F41F940F9C
-:10A6E00073FFD12CF68D770BFFB153E4BDE1BCCBEA
-:10A6F00023E28B4A910FF33CAC606429CF7B1DB2FF
-:10A70000CE9F61EE2C1F9A5CA0C68993F255BF3292
-:10A71000A1579222A7653DD20D7972B6214F56FD01
-:10A720004A8979B0214F1E6EC893D5BCB7B87582DF
-:10A73000214F9EAA8CFF20DF29F6916E30E4CBB327
-:10A740009471613EAAFB36617ECDEE948F5B8A6781
-:10A75000DFFFBF8B8F9DEFD7FCFFC7C77F501F6305
-:10A760004DCAFE8DB17D53F8FFD785DFD82FE2802B
-:10A7700057459D639F88E7F6201F7B635CE7127156
-:10A780001D3FC721EB202F8B3A549338C7B145ECBE
-:10A79000BB6D1275A8A5C5DFF1731C6799E0E35B7B
-:10A7A0009DF2B1DCA5C67913F3543E8E772619E2EB
-:10A7B0003E35CE1BE350E3BC52BBCAC7516CB0213F
-:10A7C000EE53F938B2ADC410F74D30F829F51C0737
-:10A7D000C405ABFA15E27B09EA798EC2907A9EC372
-:10A7E000E8DFE5FB8A326EE888137CEA3EF326F464
-:10A7F000A1B85F9466E5DFDB307B2FC7B843D2EBAF
-:10A80000B7FDB83FDFF2979B889E85E8CF3BF1DF2D
-:10A810001BFAF1B868433F5E97C0F723A30761793D
-:10A82000D3CFE39F84490E7EAE8A85F0FB53E78940
-:10A830009B36F44B09C74B66472DC33842B799FC8A
-:10A84000F8FD5DA6DBE9DCDDDB5DC451C7FA65CA56
-:10A85000EF9F6A38EF5FC4BC5AF16B14579DEAE76B
-:10A860006EA4F94B5D6D5817DFFCA1D5558FF21C16
-:10A87000C5BF83628CB75EEF97CBFF7E8FA01F9E14
-:10A88000FFFF39FA4BFC502CF9DF16D57F6220010F
-:10A89000F36C88E6F09BFD3E9E8EDF1794FEFAFD7A
-:10A8A000E74F913FCD8DBD7C36E6CBDA1A7F22DFB4
-:10A8B000AF0C927E19E3B62EE35F439C7624CFFD66
-:10A8C00006AEEB1BE19773F1935283BABE7F43B49C
-:10A8D000E736FE3D18B78ECF957492FDFB04DF5F1F
-:10A8E00017F375D045CA157E9F2631E23D5803FE09
-:10A8F000925E2B0EEE0DE111C64B5D8F5C4727F289
-:10A90000E3B940DCFD4D67F2C326B9C47BBA9DC7ED
-:10A910007D16114746F27F38AD2B20D7CFC60CC22B
-:10A92000F75FE47BEBDC1ECA7766121D0D8E4CD000
-:10A93000A39B0EE974CE81897D7073073F8B35F43C
-:10A9400033E6B11A4B8AA8BB1AF7138DF503E3B9A6
-:10A95000B2E2D6CB15F8AAD3EAB932F7D9BEE7F5F9
-:10A960002BA3634718FC52A9C16F4D34F8B5690693
-:10A97000BFA7D6C5CDCC2CBF3324F6EB35277E7FC1
-:10A98000C7CC2914D92FBE03C4E9BDAC0BFD95E794
-:10A99000674FF57312DD3BF4632D7372FEF995F783
-:10A9A0004CF4582FF1F9A121D28FB928EFB50687C1
-:10A9B000D1F73CAD2EF5EF33047CF68F46E7E07B14
-:10A9C000368CDAA77C8E8F46D3FB38A9D43EE17350
-:10A9D000D2F535BE3C6A1FF3B9E8FAA3BE226A1F5E
-:10A9E000F6B9A96DF09551FB80CF43E356F92A09DA
-:10A9F0005EE9F3529B05E10DFEBD812C3F7301C65C
-:10AA00002C7B253C2F82CE997EC023828E57D43951
-:10AA100014B8676DAA323E7DBE53E94FF3E629FDB7
-:10AA20009755BA1438C553A48C4F2A732B703777B7
-:10AA300099323ECEE551E098BC4A657C94D3ABF4A4
-:10AA4000EFB96A7842CB79F4B9C1E73E8A7458E528
-:10AA5000F31CE5742A3BCAE95349ED2DFDBB117F78
-:10AA60001DE64637FA6D47BE83E1F976AB9DBFF729
-:10AA7000DDCDECD0BA45CCDFCD0DF329F8C27C4A50
-:10AA80003E17E0E789F33C4755BC2B95FB4007C9CF
-:10AA90004FCA38668CDE230EF3B1FB2D8E3F0F06B6
-:10AAA0003CEE1BA3337C6FE5E0E8695417C12D4CE5
-:10AAB000D6891DFD4CC4A731FDED942F4E7954A3CA
-:10AAC000FC0E56528E75C4B987B25D917F0F4AB69F
-:10AAD0006FFF8A7F6F2866CF3627D6C5A614CF4C66
-:10AAE0008A8AC8FFA604BF1F9D46F30D1C12057875
-:10AAF0004C5933D33A3B3FBC3E396EEEA36A3C1A05
-:10AB000096FF805DC4E3B44E699F5639D6D1F555A2
-:10AB100079E7DFB73929D6F58588D73E13F1DAA76B
-:10AB200022EEFE58C4DDC744DC7D44C4DD1F89B875
-:10AB3000FBB088BBDF17F1DA2111AFBD23E2EE15C0
-:10AB400022EE5E95B78EFEAED5998D1AD3CF73BE29
-:10AB500074C17A759DF3D7AAFB86731F55E3EE394E
-:10AB60000FA8F1DAAC656ADC7D739D1AAFDD58ABD6
-:10AB7000C66B33E6ABF6F17A6FA9025F57A9D6E54B
-:10AB8000AEF5A8FB86924FD3CA543B694B55E3B54B
-:10AB9000AED6BB35385EC7BF4382CCFC34C21F463D
-:10ABA0007C0F5E39EF58E07097E27E4D21F32CC5A3
-:10ABB000FD9C91A6D0BBB8DFC4DED7E93B904D78B1
-:10ABC000C730D0D73343264D7146F81DBF4AD7AAA8
-:10ABD000236A7DE4863BD438B8A25ACD67AC656A57
-:10ABE0001CECEEA1EEC74E33F81D26FCA195FFCE5E
-:10ABF000467BCEEF874C31D5F4BED2A5FA232B335A
-:10AC00009E1FE3FE889E9BA5F4933F320FE0E7244E
-:10AC10008688F714EAA386BE89FB777B3EE4EF17AC
-:10AC200000D943BDE0FEAB18A7B7D53E8EBE1FB717
-:10AC3000D3C2DF1BD89D16EB5A025D579DE5EF0787
-:10AC4000B076339D1FF3E27B235938AF7A7EAC3068
-:10AC50006456CE97590DFD97A14F3C2F3EFC1CDD4D
-:10AC6000FF1C3EE21CC7003680CE47B474FEBE41D6
-:10AC7000471C679053697F0A823C3E2AE8323EAA0D
-:10AC8000A2EF8C99DF67F49EBDCDD476E2197C3FAC
-:10AC9000EA735E871DC5D4BCED9A496ADE36C6717B
-:10ACA000FEBC6DBC5395D78979AA1D2877A976E09B
-:10ACB0009CB8A6859F43EC2AAEF10CC892EFE91030
-:10ACC0007DA272F6C5F07D4C2E3F23C43A1FB27AA6
-:10ACD000E8FD95653D19F16984839F57ACC77D1BDD
-:10ACE0003CFFF71E7FEFC5CC3C4903B03D3E569C70
-:10ACF0005F9CE4A2F95A39BF8AE0DF4F59E79E4FC3
-:10AD0000B485CCCA7737CC2C82BFD03F07E5AB30B7
-:10AD10002C47FF7BF012E728A59CC5265E60FFCE7E
-:10AD2000AFC481B21D1572EBB88E571C7C1FF59510
-:10AD3000506D08BF13F95D2AAF53DCDB63AA997F1E
-:10AD4000B7C51D3B06F83256ACBF48EC936DF1B168
-:10AD500010C6739B7C766AE5FEE78AD4C549E8375E
-:10AD6000B76478D3F15CE096946ECB18D8E9CD96B1
-:10AD70006E3D3A7B8FA0D93294FCEC96E63433C614
-:10AD8000A1A3CC0E33DE37AAC72C1DEBB1E3F07DB7
-:10AD900093648419EDD36DF20543A3E95CA897CEC3
-:10ADA00011C13A4A318E1DED98497FEFB1F93DFC52
-:10ADB0009B4A181F77ABC2FBF6A5F0F3D736073FC7
-:10ADC000DF3A36791EF1ABC0C5BFDF57D023D615A9
-:10ADD000C0E952F9777CE6C33FCE17EE2740EF95E6
-:10ADE000EFFB0C651130F2CB00AF31F2C7702E7162
-:10ADF000C561717EAEA5F37D9BBF8AB8628BA83B0F
-:10AE00001C1171C54722AE3828E28A15863AD0BB9C
-:10AE100022AED827EA40AF8A7ADE7E51CF7B5DC46E
-:10AE200015F2FCB5948BD495CC694B60ECAD999C34
-:10AE3000CE692BB54019ACA3740E8753EBF8FEE82E
-:10AE400015DE064F4901F65B5CE3601DA9950D63B5
-:10AE5000701D69556DF49E52A5D7EA746BF87ED2C9
-:10AE600013F45E947C2FEC164E1A76D39CB1647F5B
-:10AE70006FF18A73C77A6B21C9D7A316FA4E92FC79
-:10AE80007E5CE51CF57B4AB30CF4BDC9005B356EF6
-:10AE9000475E93741FCC0647D23D4D8C8DBA459CBE
-:10AEA000E7C597AE3AD1973582EE922ECD574D88B1
-:10AEB000E3EBE0FBA13631CFA1E21BE2709EF77A13
-:10AEC000F0F9A60A7D30CEB74ACE27DEA78916FC58
-:10AED0007FA8EFF9CF9DBEED63CA39D3B7057F3A9E
-:10AEE000E62DB9DF82DFD3AE0CDED713F525FC5E8D
-:10AEF0008D3B8EBFBF32E9CF99C0A755E23D0469B3
-:10AF000057AF13FA6B7CDE7BBEF3BFBFF35EC90C99
-:10AF10000B7E0FFDDAE02FF8DF0336D7A6469EF74B
-:10AF20007D0FF1035B79EFB53FA3BF2319CAE0F2B0
-:10AF300060BBC6E6C4EF0C5ED1C3BD1CE998DAC3A2
-:10AF40003546D447C99FD9043EA698B55A0A8E1FE4
-:10AF5000AE91DED65F3581CEFF5D770D3F27F1FFE5
-:10AF60000010785941008000000000001F8B08008D
-:10AF700000000000000BED7D0B5854D7B9E8DA3320
-:10AF80007B1EC0A0838A1912B003A819531F230F78
-:10AF9000051C70A39812436410548C8803A2D0D669
-:10AFA0001892A6B7F4D4731804110951D3A63DDA48
-:10AFB000F818CDA3BDB9DE9698DCA64D73CE21C698
-:10AFC000A4696F12B1471BED6D0DBE92F46BBF1EED
-:10AFD0006DD236A7ED77BCFFFFAFB566F6DE0C6825
-:10AFE00052D3263D852FD9AEBDDEFF63FDCFB5B967
-:10AFF00072057EE633E6606A78C8C7F0C77245819D
-:10B00000FF4798579D83EFF18DA19E5DC9C4FFB79F
-:10B01000B26032BC0F7EEA176C266335ACD53F00B8
-:10B02000EF7BF3B454F774A8AEB35D187232E683C5
-:10B03000DF2B59D047CC239F354CA57A39DE920AB5
-:10B04000682FC767349FA17E6B0FF33AC642E14F6A
-:10B05000B0BA89D05FD46D55234E9CAF37F839A76D
-:10B06000E6622C2BDDD2E080F554666C5ECD264086
-:10B07000832A877B0AF60F2CFA796E1E3C7DEBBD86
-:10B08000B83D6CD70CED4E4DEBCEF04E8FAD6BEB6B
-:10B090003656128279B666FC0FCFFA646CF7BBF6AF
-:10B0A00010B6B3B1DA7E18BF77C12FD3335DB1F6D6
-:10B0B0008766954EF3E7C380E5A98CA53136D51E8A
-:10B0C000CAF24F1FBE5FC6C28C41938E9244C660C7
-:10B0D0001DE71B948803D655DB07F01B83F5975AB1
-:10B0E000F07D439FC3DB8B0B649AEB0ED8E77ABEEF
-:10B0F0004DD630A52B7F009EEBFB9A2BA8FD2EDBB7
-:10B10000398497137E11BE19ADEAB928BCB03DD37E
-:10B1100095711E53D98E73C07A17F89327BCF949DD
-:10B12000F8772ECBBD62E5F847F8D68AB6090DD57B
-:10B130006319E2D303C02C1CBEAF95EF59D9C07878
-:10B140004604C3F263EF4F37652786B01FD28D5395
-:10B15000D0D52CF8BF9779ED7310FF9CAE6A045DD3
-:10B1600079197B9EE82A6C0B47D709FB62F7D962F5
-:10B17000749765188FE17A97EBCBD45F3B3919D67A
-:10B18000BF9AD15C6C75A085C3EB3E4E8F4E78297B
-:10B19000C689D11B8C1334D11FE16BA258278CB305
-:10B1A000ACACECFFFC1060F6E8CEAC3B104FCBFE35
-:10B1B000D1CAAC305F3534C37275AD12894079792C
-:10B1C000E056E287E5FAF1E17D4D8DED821E3F6F9D
-:10B1D0006CCAA671D694F371D826DDFCB4BE9D046A
-:10B1E000CF20635BDC3A7A7B33934D6600C7E77709
-:10B1F00037EFC3FE171F7430A423867DE720DE39A6
-:10B200005C4F02ED22FDBFB54D891C84755FD8ED02
-:10B21000A075BEB94E8930C43F733F3E00EFBBFD01
-:10B22000294497171342FBBE08F58D5B93FC61D848
-:10B230006FCFB8D68D4198F7624AA81EC769DCFA6D
-:10B24000494B18DAF724869D59386EA3D57F10A68E
-:10B2500058A9024CC7C113FE7D133C1B7A74F883B6
-:10B26000FF8EF9151A7F898585FA5DC3E9C7319B81
-:10B27000D723C01DBAF52FC9B2D07A4F3DE4A0F54F
-:10B2800026CCF6123C1A0A12B484318847A6A93992
-:10B29000B09E746D12AEF38202FC09F4767E9912B0
-:10B2A00046F83095E3C57ED38D07909F1E15FBBCF5
-:10B2B000F0C0DC4948CFE75378FD394F6204F77599
-:10B2C000CECBCB618F2BF218F2861AF22D4FE6FB14
-:10B2D00050800E1AC5BA1ABD162D01F0DBF8D08ABF
-:10B2E000CF229E1B3D7DF7E0F36472385981FE6FDB
-:10B2F000EDB6328437C2C39983F545CD586F86CBFE
-:10B30000257F16ED07E1371EE0F6E6AECEE410EC41
-:10B3100083B959C83E310687869DCF7C419949FC47
-:10B320001CE6FCCEF94461BAF318E877A5D71E2EC7
-:10B330008771D8D1C944B72BDD9C6EED855B52B3C4
-:10B34000783357943EBC54EEC3F3BD51941B906EBA
-:10B3500001AE2B915F66223CC6CD1980F7B54D46F4
-:10B36000BADD3261F303D5B0CF7505366685FA755F
-:10B370001ED5C037556D463E827D1BCA636633DAE3
-:10B3800077CF38419FDD9C3E81D2270567C4E862B4
-:10B3900097DF42ED7075B651E06F86EBC70D0EE793
-:10B3A000905E41DE9CCFF0EE2B24B900F4C3D7C5EC
-:10B3B000AC3A7E68E87110DD33200F8413D0A7BD4E
-:10B3C0006A468C5E247C1A7675103D3608BA6BECA2
-:10B3D00003FA19A3A32313BC70CFAA9C273B46678B
-:10B3E000541F87CEBEE767C44792FF1A58B09E59D4
-:10B3F00087F3B57C129E8B109F9FA90DA7E3286150
-:10B40000EABFA3A4682CD1BBC007173DF4E344BC3A
-:10B41000254BFC84D9093CCF5DA2D2DDA69C2E032E
-:10B42000796315E7AC5D1B8C0CC0FB94362BBD47D4
-:10B43000F9A2427B9C9621C29F9BFBEDA9504E1026
-:10B440006597C0ABD5EA4A43782533A3DE338E999E
-:10B45000E4899FE355CAD99D369686E7718238DF25
-:10B460009B17652BD86EA7A2907E602F33D281D513
-:10B470002407BCB32DE2BC0BCB738FE4ADDDC9F761
-:10B480009B906621BEF86D3A085425060FBBD8FF85
-:10B49000B8016FFF00D4D77B9CFE0894C73337C92F
-:10B4A0008752986940376F4D45121BD0E179917BE7
-:10B4B000BCA1FC29CF4D86F6B779B30DF5B7FB3E9D
-:10B4C00069A8BFC39F6B28DB994EAEE33A8738DC8F
-:10B4D000ED02CEBA7A299707118FD5621F3BEC2176
-:10B4E0004F10CEE16ACF7A92CF1D259FF10CC13E5D
-:10B4F0001C1ECE7F76D42761DC84294D6ED2238436
-:10B500007C2E805FC443270E9216A333BB09CE6600
-:10B51000FE33EB930DB385DE730BBB85F41ED7B8FA
-:10B52000B8FA8D597F031961417A4D14F85A647540
-:10B5300091DCD85A03FA9C82FAE552AE2FF9EE2636
-:10B54000BC06453B16B690DEBA5CEC5FEA5FAFB571
-:10B5500033367033C06301D7B396175CAA41FA340F
-:10B56000CFDF2BDAC97262C1014D8B234FDB057D22
-:10B57000250578FD722753510EC9FAB090B7CB85D7
-:10B58000DC5E027C8C745B894F9DDEDA27C6E98B1A
-:10B59000D22B1BCCD1F3E9214545382488E2011692
-:10B5A000EA9B9D8A700E5323AB2BC888BFFF04D043
-:10B5B0009D437A0CFD94CE6EDAFB79A05F474DB2C5
-:10B5C0001F6D0B87D6F0D857017E8935497E8B37A2
-:10B5D00046EF64774079828FD37B6DBAD34FD561C4
-:10B5E000EDC4E43931BDAC46E877A9AC95F8609874
-:10B5F0001DE3E47439B21DC3CF1F399F439CFFCCB8
-:10B60000BAC94F7417E4E7BE057E91EE96D51AE9E4
-:10B610006A4568743AFB96A4B3B96C2ED159680395
-:10B62000D18543B4D93109E885C389E82351C2578C
-:10B63000E8DB36950DA880A763887F58A4CBC69217
-:10B64000719F83DA0BC417833E66D3D3413060D534
-:10B65000223A3C0E16B24437C897411BCB7810DA19
-:10B660008DD1562C76C3FE064B1DC90D74A8460C11
-:10B670007AFB3118F7AC8B8DA8EF9BF9612AFC039C
-:10B68000E5C0D68C373DB89EAD3646E73D0B5FAA88
-:10B69000D5A0BC5D96D92F6A4B61DCED09B2FCEEFA
-:10B6A0002EAC7F3C91972F3FF9A75D241F805E1140
-:10B6B0001F49021F49527F9FAE832BE0C13921876A
-:10B6C000CE19A709DE66BD5ECA09F3396C9EF74D37
-:10B6D000139E46DAF7B0F50269DE323A5FFCC76CBA
-:10B6E0009297AD06BE183ECE00E9EFABC4BE2D4921
-:10B6F000CF6584E2D89151F86FB0FD4A6F2F009C5E
-:10B70000BFABA0DEAB41EF398C8B0E18472978E92F
-:10B710003F51FE2BBBC2E3108E56688072DEC642DC
-:10B72000B41EC9AF0948075684FB00D583FC1D52DF
-:10B73000B271903A37C24581F6571029D77A4E96A2
-:10B7400073B9B6529C7F9538258C57D9C34AD13EE0
-:10B750004F58B7F6E03694739A03350A787FA914E8
-:10B76000D707F59A839E9734C41BD0B341EE3C5F54
-:10B77000F287B71F817EDD8356BF03C6ED0E3CCB3B
-:10B7800050EF7E673AF3E3A6BBB021ACAF3EE45E78
-:10B7900064F722DF0C9CEA9AC2D8D9763658661B29
-:10B7A000BEDEC12309762F6C36144E99F9348CD342
-:10B7B00053E070A33EF7C626AB1DF134B8B9218C17
-:10B7C000C0389D16EE57E07D8F1A6268DFDB377553
-:10B7D0002E42BE3B6D0BFBC7C1B36773F82EB4435B
-:10B7E000346F457926ACFF608F5A1E89733E6FC84F
-:10B7F0005188DF5E7BFED3B4FF6369767F028C3BAA
-:10B8000084FE0DC0DF31DBCE0C3F8EDBF1950C1CCE
-:10B81000FFD8BAADFE23B0AE631D0EB4A4D8B1DD1F
-:10B82000CE5A1CF75871B367BD6E7CE74DF6567C57
-:10B830003F78A3DD9E4DFBB99CECC1FD6CCA1D8F0A
-:10B84000B4D99D669FB416EBD73733DCAFDDB3D3E5
-:10B8500086FB73AA6C179E2F9FF05C7A752EDA4BCD
-:10B860005ECB9C4F41FBCFFB43B7E6001E57B69D16
-:10B870005D8472C95E96B2059FDD629DF2BC92F84E
-:10B880001D4A6B74E239D6DDB496FB613C9606C264
-:10B89000639A2588E75177609D73EA74FEBE79CC80
-:10B8A00070B874A3DF6516AE73BD67FD0C6CF7BB93
-:10B8B000F610B41B2A76D4C68363630E9763CECE8C
-:10B8C000E6AC365877F76EA71BE1D3AD847635002A
-:10B8D0005CC3992EFF63DEE1FDBE25FA49FA003C08
-:10B8E000111F6E387CC3EEB08AFA2AC723C0C5691F
-:10B8F000D3C9CD43B34A9B111E51789BE74DEB262C
-:10B9000079D1AD70BEFED6E159BBC3509EE90FDDC3
-:10B910008DFD8EF500AFCDA27D4E427D7F24FE19B8
-:10B9200012F5DD1DB0EF38FC3FD46465378FE5CFED
-:10B930001BE03975B3759212073E43C56BB3D04F08
-:10B94000750CEA2D30CED06E277FC2FB2CA4AF1130
-:10B95000E873560E97F7BE99C12D39687F4DF7935E
-:10B960009FEFE5D9C1AD39A407B47AB0FC31A0DFAF
-:10B970007D1F11FA65EC46A4D7E9BBC3609232F78C
-:10B980003883DE3AD2F91964432A9EC71D257F68A1
-:10B99000417BA07786DDEBD0F905A51EBDC4C7E5C8
-:10B9A0005B70CA853C38B959F5F4F564DF80BE4C4C
-:10B9B000FE4137FCC6F30F06D11FA893874B4C6599
-:10B9C000A99FBE94037211CF7DA127A77B7706178D
-:10B9D000A0FDF18AD51F01B86560072857552811C9
-:10B9E000D4D73B4A9E203D9E093D6E8958E74FDBE8
-:10B9F0009DAC6C0A8BDA732BC5FBA496B38FA27D2A
-:10BA00009D84FE4FF4D7B638BCE47F41E4C3FCD537
-:10BA1000627FD2AE233D12F6B3B245F841D9835CC2
-:10BA2000DE5803F9480FB00F835D1264263BA4C9AA
-:10BA300066B0E75699F407B3DD506DD21B76A0EEE1
-:10BA4000847AA1DAEF447A7A777ACEB12C2F5587AF
-:10BA500007A47E0FED420527B60CE9CE9F1342FEE8
-:10BA6000FCB85D3B8DF2684BF011E710FAADD5885C
-:10BA700013E5496FF9E79291EE7AEBACE5486F83F5
-:10BA8000EDE5D4EEB5F6203DAF08B951E1D77E4FD4
-:10BA90007C29F4B3EAF2D2D35D3ABC5669B79DEE85
-:10BAA000D2ADBFB2A0CA5096F4556965ADFD71CE56
-:10BAB0009759B9D2EFA231833E6A3DE40FC5392FC1
-:10BAC000E43391A9EFEAE1989C2BE846E853F74F5D
-:10BAD0005F3076347D46EE53C247EE5FD68FB4DEDC
-:10BAE000DFE55C9FF566BFCFF59AD719C5D308EDA2
-:10BAF0002BF1108373E077873B56A25CA8F0877226
-:10BB000073010FD565CA96F140273F16FECA1F077D
-:10BB100092236158CF8B3EEEFF4C6CE17665625903
-:10BB2000D5223C9FDE2FBEEF2C50883F6B024A444B
-:10BB3000837FDE2AECD59FFA18C51F805F5F4D8694
-:10BB4000F2EBC536EE47665AC51D7362766A621D12
-:10BB50008F4FECB033FF00F69BE6F26F86F7CB25F4
-:10BB6000FFD51AE310353536C33953698A3B249A19
-:10BB7000CE99A512EE7300EED931B88F647F8C4454
-:10BB8000274CBD94877E31337C369AE063B6772AA2
-:10BB90009F33F1C735DA3D077BF25E9C807A469988
-:10BBA000E29F82F8C32AE897A83D49E1905EC94721
-:10BBB000C2DE93F1AA1D4BABC9DE7B0DF581B1143A
-:10BBC0006F9A84FE6A39BEB4F366FAB5FB725347C6
-:10BBD0005EC709D16F6B557C3DE104EA09B3F8F308
-:10BBE00006784E5DBA30239E9E70A250E809508FB1
-:10BBF000FAC189DDE5FC5968D4135879EE55E0D2D5
-:10BC000041FB4D989237361EDF1D9B157A30570742
-:10BC1000F7245F2B2BD3C17DFD6CEDCBB8DF2AE180
-:10BC20008790F3817C3FAAD7C3CCF33D95E316F60A
-:10BC3000C6789217F27935FCA9EE56867476BF4D18
-:10BC4000AB457DCFEC4F3A9CCBF5C49E2CAD05EBBC
-:10BC5000992BE72AE376487FB56FF6441E7E20BF16
-:10BC60008FC91E94F6D301ACCC8FD985AA9BDB85F6
-:10BC700089E9978EBAA1AA3937F40CC2A3F85224E5
-:10BC80006C01BE735428A43F39D219E93DD76C87A3
-:10BC90005D63BB1E646AA0E7AD8DDC1F5F3A5BA5E8
-:10BCA0007262C87A90CE05931F2751BB4C76D8128A
-:10BCB000D00384DF86F4A953429F0AB256B2F75CE0
-:10BCC000B68813FD1566BF4D6DBA65602AC8F5DAF2
-:10BCD000824B35DE99D4DFE0F7A9F5661D4D15F5E9
-:10BCE0006E782E09723FD072F403E1F835919E2CE4
-:10BCF0008CC3F955BFC6B89D87FAC58AB55F98F160
-:10BD000035EFF5F30349FF92D417A53E03F2A5677B
-:10BD10003CE265A1E225DBDFE42732FB85A45FC6B8
-:10BD2000EC3F32FB8BDECBCD247C48FD4BFA7F7E93
-:10BD30009F6BD4C3FE0BD803DBF516C2910AFCDD62
-:10BD40006B63193BA773FF0EEA4BC74A7FE046FDC2
-:10BD5000E2BF4CFDAEF57CEB8673E83C9EAB2F2436
-:10BD6000D850DF0E7A42E44F5CA218F9242D4FF828
-:10BD70001BF35C7C1E1147EE6E6F93FDC3286F8230
-:10BD8000E9F64882121B8715E45F133F8D9DADA530
-:10BD9000E6E5933D72431ED2B31FEC9119688F08FC
-:10BDA000BE2F48A5FD302D959DD7C78DC5BAA3EBF5
-:10BDB0007082DD32E3FDCF3F218F19E6B91ADC76C0
-:10BDC000941439EDE88F001C5B395DB9A3FEFB2CA0
-:10BDD000F4EB6CF0EAF58A7A8C5BE4A2DEC9E31A34
-:10BDE000F2BDCE7FAE22FD26A687B4609C73F5CE51
-:10BDF000BC689C8CE2A751FFBB8F51BC488EA3321C
-:10BE00004F07F101F2AA5C8F358E9F5EACB749F007
-:10BE10000100DCE9009259BBD3CA785E02E713192E
-:10BE20008F500B83E599B0DFB5DB148A1BB370ED3F
-:10BE300051D4EFD7897ABBF0BF99E348EB441C8615
-:10BE40005937909ED6F49031BED6D8672C9BF572A8
-:10BE5000E9EF576191B8EE7F403C713844ACA3C321
-:10BE6000E100EDF36F140E920E2B723FEBC1BC9606
-:10BE7000EE84D0AE068C6BEF75923F846C48E497ED
-:10BE800001F885FD6CDB53F008EE675B9E95E0D70B
-:10BE9000ADF03C97A3695F730EE9E86D9BE0F35B3F
-:10BEA000F2BCDCEF82E7128844963E81F848E6B5A2
-:10BEB0001C4BE37AA53DC0F5C643938F2CE5715723
-:10BEC0009EDFE20BC4F25B4A013E33047C7C539A52
-:10BED000FC03F09C116826784C7FDA68AFDEEE3305
-:10BEE000EA953EB3BD6A2AEFCD8B9FD7128BB3097B
-:10BEF000BFBB58BF99AFBED9CEE32D4F80DD8ACFEF
-:10BF000043ED6E7A7EABDD43CFFE762FE96987DBAA
-:10BF10007DF49470BFDF16ACC7B896F4434AFFF8BF
-:10BF2000F7F3B8FDC6027C1D95622F8BACE9C908FA
-:10BF3000E7E301AE178E74BE54971BFDA0CB82C6FB
-:10BF4000F8DE8A5A637CEFEE99DA73785E26CDF4D8
-:10BF5000D842BA78D43AB1FF1D5FE3F12639FEF139
-:10BF60007FE47897E58B62FFAF0ABA483A9266F3AE
-:10BF700002B2AA1EAABA15FDF6CC9D734DFAE0498D
-:10BF8000C197499BDD36F40B550DACB4E338EB7625
-:10BF9000C138AE6B1F676BC6C40C637CE1EE3BB16E
-:10BFA000FFF1687C61E39DA5507F5CC417DE7EBA1B
-:10BFB000F5EB6117D2ABF673941FD63CED0CC2E3E0
-:10BFC0006D719E437908DFCB32FCBC9C3271543FCB
-:10BFD000FEDB79F9C3FDF8D6854A6BBCBC96CB79FC
-:10BFE000513FDAAF496E39A37EB44BBCCCE5919A90
-:10BFF000CFE7EFFC296BC1713A9F652D87E3E8F32A
-:10C000007FCC53E478EFE591FD2FE560F00FF1C6AA
-:10C01000B33AAA2621BC2FDA785E8C793C35DF2E24
-:10C02000C7B3E463FFF4E8FAD47CDD783B00068311
-:10C030008827D59D4C714D7617C53F251D25D5BB4D
-:10C04000EFC0BC05302C199E2F49DF71DF91877E30
-:10C050009C9F64FB1F6323E3F51782BEDE12FC7511
-:10C0600011F90BF8E8BCE0AFB3C85FF03C23F8EB84
-:10C0700067ED7E2AFFB4BD80CAA7DA352AFFA4BDCA
-:10C080009C9E27DA83F4FEC7EDB554EE6E0FD1F314
-:10C0900078D923B7E2B9F3DB6F2A248F475ACF67E9
-:10C0A0001EB51AF8A7654F9281DFD63F34DE506E79
-:10C0B000EA33C6CF1BBBB20DE5356DC6F8F9EA56BB
-:10C0C00063FC7C55CB3CC37C2B430B4DFC7CBB8978
-:10C0D000DFAB0D652D9FEB89D5E5AB0CFD1C9E46B6
-:10C0E00043BBA4A52C140FFFE5F99C3E8F94148D3F
-:10C0F0001D1AC5CF616FBBFDE7A89F44CB6A88A11D
-:10C100003E6F6F5B42EFEF4FE0E79DB95F7D3E3FD3
-:10C11000EFBACB9A820B18EA458BAD7ABDE7D3B361
-:10C12000424BF375F6A0DDC3EDB17726D7583D40FD
-:10C13000474BCB2EBF7803D051689091DDA381BAD5
-:10C14000E7013DB8A0F5C1853740B9267C8FC17E97
-:10C150002C6A79F205605F16283BDE3901FAFB672D
-:10C1600087EA71FC12CFA517B0FF828AD92A92F50F
-:10C17000FD298CF4D18B19F6C8C138F4706FBE62FA
-:10C18000885FBDDF73DA1CA7CFF2B152F42367F9E1
-:10C190002E95A25C83B286F1AF43B342F7229FC1D2
-:10C1A0007B0DE5E4FD33D667E1793252DCE86B02C2
-:10C1B0005FD29F20D7B5A384AFE7B8882F0C99E250
-:10C1C0000B3A7FC23FE58FE24FB828FA0D7D35BEAE
-:10C1D0003FE1A2883B5C947187AF55C78D3B5C5CA7
-:10C1E00024FC09508F7E848BBB6BF973D1E87107F7
-:10C1F000B93F388F1EA2F3271A77107ABEF09B1F23
-:10C200009BA5FD33D6AF9FADEDC2E76F6668BB114E
-:10C21000CFC775F14FF7445DFCB3EC0786F8E753E1
-:10C2200039A103F93C6ECDD0AEEA0CB3A1846C8C7D
-:10C23000C70637C6A3E3FF9D2FF5EB813F2B3EAB2F
-:10C240008BA35AAE7C925D731CE09ADB15F0BC1494
-:10C25000B37E9384101917D3FB9EC80B1D417875CC
-:10C26000A57CC7CBF3AF2CB1F30385DF08FA907937
-:10C270003E391ECA2B945B278063F09CD99E72A91D
-:10C280000EED94410137F3F3DFF3DD029EEE0988F2
-:10C29000DF27F2823F267C3FDDEFA5BC36F1FE5A58
-:10C2A000D7F1B83DF873D463BB1BADDE835C6F2759
-:10C2B000BFC5CD819448AF2E1EFC6B3C2FF3D1FF40
-:10C2C0003834D90EF8EE0CBDE0C27CF037F6A898F1
-:10C2D00011C3BE911CB621FE6B7DFC7C5BE0097D29
-:10C2E0006268143E077A186FF1D03A2C96023E2B02
-:10C2F0007F86157C9ADB0FEE7937D50BE37D632FB4
-:10C300008F7FDDBCB7C9D9A81B3F6B0E3F77BA91B1
-:10C3100066F2303EA9443051BD3670F9D5B9185F88
-:10C32000F15AC8CFF1C6A6DF9E5C817E47CD4A7E1A
-:10C33000C73736BD43E5535E4B2EA2EF0DCF6F4E90
-:10C3400062FB9BFF71DD446EB77078ACD994FB78CB
-:10C350006F26C5C59439008753DA3BC9D9D363F139
-:10C36000B3350A0BC6D363D2E670BC2DD65AEFC4E0
-:10C37000752D0E3918E6399F6AD8FA732C7FA354AD
-:10C38000F15AD1AEF7F1796AF7A8944F0BF0D98042
-:10C39000E557FC490CE75D107A52C5F6BF9BA1B08A
-:10C3A0001B94EB0857ED9D54E4C33790FEE2ACFFBD
-:10C3B000D7F2DC147C345505BECF41F81F75E9FD7A
-:10C3C00094929EBE94A765CF21BF5FA825487AEEC0
-:10C3D000D2ABE8A79B799EF6372FA9187B487CB48F
-:10C3E000F546F42F0D5BE708EBCB9BC3E5E46F0448
-:10C3F0005FDCBC577DF536A4E74D36CA43B8252F20
-:10C400003807F115B5B7AEF3B921F3D7060BF87DB0
-:10C410000450A7691E58AF4F8575242889FE30E760
-:10C420002BF2CF39C5F907EDB4B1D06E0DEB1F403B
-:10C430003F1F53B59D56F41F16DAC83E5EB1DA961B
-:10C440008C7889C5CBFC067BC3FC3C8FF131CAD309
-:10C4500070D27310EC6C8C97E00F68E250A90ABDA3
-:10C460007FC6C31AFCF37191577A6FC16D0F8703B2
-:10C4700060675878795DC16D376D862D9D9FD47A40
-:10C480007219ECABF741C5DFE1C5E7815D8D78BF7F
-:10C49000A24DF19743D3FA8169F518626CEE719061
-:10C4A0008E7F6EDB176E457A7DC7C3DC48CF2BD2FB
-:10C4B000383DAF3DC12216287FAAEF418A7B064F47
-:10C4C000A894B726E3B267D2785CF6CBED03B46EDE
-:10C4D000B46B17CDE12636FE8CF3C33AD08F5AA643
-:10C4E00052BC743C7377E3F992A86596727DDA6D5D
-:10C4F000A7384F05635F473F4F1BB79B0B455EA4B3
-:10C500008C63B10BDCBE6D815F9427E3CB8DF6713C
-:10C51000BEC9FE95F2CD1C6F01FA0FE3FB8E3946C2
-:10C52000FB7824BFBD7C3E0D7A04EEEF3B228EFBF0
-:10C530005DD0D7319EF92CE8EBF87C0EF4757CFFCA
-:10C54000AFA0AFE37300F4757C1E017D1D9F4741D2
-:10C550005FC7E74BA0AFE3F365D0D7B1DF8F405F94
-:10C56000C7E72BA0AFE3FBA78BF9F9D73DC51ED9D1
-:10C570000CEBEDB6B19F215D854B455C58C4C9B647
-:10C58000A54CA5F3DDF927A072D0A70695D06710BA
-:10C590001FE10C27B51B4CBEF4C7FFC0F2B64CB26E
-:10C5A0004398EAFDEE10F4EBFA62A6BF178A3D76D7
-:10C5B00046F2FEEC71E656409F796B993213FDA866
-:10C5C000E7EF50FAB13C788742FAC45464BD9CD876
-:10C5D000395AF4AEF7209E679DC94CD0E3237BB552
-:10C5E00074E88F6B237A1D5B8F76E97C872CBBEA1E
-:10C5F00035A0CFC63645D8A9EE7D48BFDB14D93F5C
-:10C600006D2FB6EF92FD45F98445F6FFCC1EB4B709
-:10C610004F46E76B5885E39DCC92F54D75583E1B10
-:10C62000CDAB2B5E8DED07A3E3E7EEC5F2F90C3938
-:10C63000FEFA5554B6C9F2E3D4FE7C2A6F7F4B71E3
-:10C64000EA7EB49BAFF7789D217EFEC139A6E9E36F
-:10C65000399B8AACE67C70F2BBC938BF25C935E589
-:10C660005AFCA5BA383FF94B613E1BF2D9E74B5350
-:10C6700026A1DC3D9BE18F6BA72C2C1AC17FAA2938
-:10C680003CDFDECD42981F9F28DE27F6F13C7ABBC7
-:10C690004F1D96477F2DFE4499F720FD89B54DA388
-:10C6A000FB136B4B8DFEC435A27E247FE21A933FB1
-:10C6B00071E526531C22F4FEFC89756CC086761841
-:10C6C000D314E2A33A77FF8B13D1DEBFE0257F229C
-:10C6D000F3BE4CFE56797F02FF6F9983F7CD78F950
-:10C6E000ADBB140FDA15BD772913F179E62EE546B7
-:10C6F000E4AF0B77296EE4B7CB73F93D98FCB7FD37
-:10C700002F7BF1BCF558FC1C1CC17FC15045B029E2
-:10C71000C5DB0BE39CBD4B1987FD57DF9769477A53
-:10C7200000BD53D023DB83FC624D520CE5BC499223
-:10C730001EF73E8CFC317FBCE497657B905F4BED30
-:10C74000B27F3B95578614D1FEDE3DDA64E0AF053B
-:10C75000B2FD843AAC5F962DC7DB4FE3CF4F92E535
-:10C76000AF12FFF544C7FB5F34DFEB2821A9FC00C3
-:10C770008D575A25E5D9742A77D7C9F15BF7625EE0
-:10C78000EC2A8BEC7F1BF1FF5A26CAA8BFC37EFFA1
-:10C790009F381FD6CDFDE32AE4A73BA3F57F7C1885
-:10C7A000F9AD4E949B9F79620FD6FFCDEFEF2F3CF2
-:10C7B0009FB9BC9A0D2EBA212FC617E673A5AE906D
-:10C7C000EB9D052D4FA2F86275AD07ACC88FB1B8CF
-:10C7D0005A5A4D10E9DB69A5FCB9A087DD1A2F9FD5
-:10C7E000FF0F73F9F9F485B92E83BC1E39BE167F8D
-:10C7F0009C86423E4ECF0216D7CE3D346BC1E6B981
-:10C80000F931BD0155443B3C4BE06981E77B334244
-:10C810003D588FB20BFD30D2AFBD44E41377947C0A
-:10C820003DB800EF2F15DAFCC21D3EA88FF7AAE233
-:10C830009EEBAA053CCF2BD4EB207BADA647E49121
-:10C84000585D148F506FB21FA0B89988A78630EF3B
-:10C85000388BF2BA46BDDFA19AE2A89D62BFA5B3AC
-:10C86000DFA538F5DA5778BEB08C63D78B75AD4548
-:10C87000B90CEB6E6C522216E8D7888207E3BA3EF9
-:10C8800016F166C6E2CA2BCBD4013BDE0B13F7339D
-:10C8900098D087A3F1F01A6F3FE6C7A85A825FC30A
-:10C8A00079D84090F2E2305E94C9A2F1672947AA94
-:10C8B0009A6FB80BE3D43AB94571EA44364C6E909E
-:10C8C0005C88E63589387A343F47C801199F6E1075
-:10C8D000FB5A1E9503154B50CF4DBC5FC4A945FCB8
-:10C8E00059C6A9AB4CF7DA1A030BC7903FD7AFFA7A
-:10C8F00029AD26DD789F29D18487A945FC5EA58CCA
-:10C9000053BF32D7186FBEDFC648EEF66419E9AEE2
-:10C91000A488DB3D9F2C927EC8C48104D4BF999328
-:10C92000EC905EF4E78CE5F6085DE632F975D4B676
-:10C9300055E47FC47A05E850F1BDF49F2897B15CB7
-:10C9400004ED55BCDF82F87059C81E95FE1F545384
-:10C9500016E5901FE8DC5CCC0369ABA771E47DF6BB
-:10C96000C713E3F3C7AFE74A3DA1DF86ED56795E13
-:10C970003A85F3FDD97E20618745F5182FCF7F4991
-:10C980009DEB9571091BBFEFC76C4B6790BFE4BD72
-:10C99000B9E41FEBF7E23AE4B9B4EC7B4FD1397656
-:10C9A000ED7170DEAFA1F0DF5685278C1CC7981A99
-:10C9B000E078F2CD0C3A3064CE26C8B883E6C49055
-:10C9C0007854CEE2460A0C72B6AEE5BF819C8DE982
-:10C9D000FDDE3A1CEFE3B67EA0A70584D772EE7F9A
-:10C9E000FBB8ADFF07F9DA4AA4C30F7B9EEFE5075A
-:10C9F0009B719EAD8A56EBA27B31CCAF8C1E2FDC97
-:10CA000088EDCDF1C2ABF931FEEEB718DD6FB1ABF9
-:10CA1000E0A3E9B7F832C00ECF6BE0A743C44F01E3
-:10CA2000CE4F7FEBE71FECF747B8DFAD4A7F24D14D
-:10CA30007AFDFD064FE4855EC7F1A7A63B1B509F1C
-:10CA40008179BCC87F517F08AEBBC0E00FD9D3F25B
-:10CA500021F843609F6F115ECB385EFF06F0A6148D
-:10CA6000E27E34AE47FC0DD2654621E2B09FEFEF87
-:10CA7000AF30FF0C9AFF10A797287C849EA4834FA9
-:10CA80005DCB5F073EA5B4BEEFF2F57D0CF0B98239
-:10CA9000E8D5CFD77B35FB7BC35CAEB742BF7AEA24
-:10CAA00097C7E960A3D0ABC12E5F78833766978FB5
-:10CAB0009DAD3516F2F87353A121CF545B87E55134
-:10CAC000ECE64F17A68E6A37DF8DF51F17BB798FFF
-:10CAD000805B2C6E13A17B7120C129BE5C2FDAF61E
-:10CAE000B6552F9E867935007F2C3B703F56DD7EF4
-:10CAF00032546E6F9BEEABC9EF1DC87DA9D6BAB19B
-:10CB000003DE183C5F1BD36AC7FB50CD5A4A37DEA1
-:10CB1000BB5DD87599F206ED9AC38B76E1273CDEB2
-:10CB20006E8CCB566B7CFFF61637DDEF93F7DDE4AA
-:10CB30003D94E681692FD9F1DE1CD82F69307E65DE
-:10CB400099ED9C7EDF0ED3BD14D5546EFB59E6F6ED
-:10CB5000A3BAF6DF284C36E437837E534EDFE9E88C
-:10CB600052DC22CF97F2329AC5181D25772E46FF48
-:10CB700025E8715E84C3C29D0F0E623CCDDE65A5C3
-:10CB8000D8F9EFDBBDDB8F024B25ECB592BFE1B7E7
-:10CB90006D0AFFDE47058FE3AF15717C66F23348FF
-:10CBA0007FB88463C2033CFFC35E70B68CEE37D699
-:10CBB000AD1BCCE7B443FE0695AF8CC9EF6F5409AB
-:10CBC000BAAA0F5CEEC27ECB3D1643FE90D91FA1E0
-:10CBD00032739E3CCFE354359EC7A9FA789E7C22DF
-:10CBE000D3E87B1D895BAA099F551ACFE304254929
-:10CBF0007C778BE3A532700FE5F998FD088E02A3D0
-:10CC00001FC24C97667C9C36E1E33195DF4FEA3ECC
-:10CC100061F587E175F7434D3DE83F0F3F64213FE4
-:10CC2000C605991F028B447FFE0A16852FE9CBDDCE
-:10CC3000AD3C5F40E265C54E9E3742AD0C7EFB7455
-:10CC4000A6FF8EC70AE157B893F5D37D87D56CC888
-:10CC5000867CB0065DE956F4C778E9B99685B730A9
-:10CC6000825FA82713E67BAC75BC1FFDDA0337DAB9
-:10CC700052DEF4713B229EFE1A8BD7AAEC4D9D9F8B
-:10CC8000FFEF7EADF7EBD7B286E97EA9C71E99A26A
-:10CC90005CDDAFF5238C4BE8FC5A17768AEF6D8884
-:10CCA000FB1683B6D6493B5DD8CE4BE7E5983D2BC6
-:10CCB00016231D1CDBFB03B7B8FFBA69E2E8DF856A
-:10CCC000C8298A934F7A7C2EE379209943748FFA8E
-:10CCD0008CCD98971BF51305ECC22F139A57941A15
-:10CCE000D38F993B9AC7595C44FE237E5F5BFA99C8
-:10CCF0009A73430BF07DF125410F154A4481FD568F
-:10CD0000BA9417156F6C7E66CEA3FF7B3C8CCB0963
-:10CD1000840FE63325F0BCDAC14C567B380E7E26F4
-:10CD20001773393A383B3EFE643DE827F716A57283
-:10CD3000FB690CF72BFCCA3EBA5FE18BF1E846E2D7
-:10CD4000F7D07CED4B1CEFBC9C9413EAC0F69DA180
-:10CD500020E5EBBCD567F57620FC075A5F2B80F207
-:10CD6000927FB2BA311EFE61C7F952E7665E539CEC
-:10CD7000EFB280EF99685EF7A67AD4077BA57D268F
-:10CD8000F4C755E3746538928B4EF0F6DF7B76EE90
-:10CD9000BEB03AB2BE79F773757BF1FEADD437A160
-:10CDA000BC1ACBB23F0B574C2A057D766D8B8C2776
-:10CDB00056EC43FD363A5F78F93EB4872ED88CE3C3
-:10CDC0004B7DF5FF3EBB681F8E1794F38717ED432D
-:10CDD000FDF7ACA93D7D9F12C67BFDD9526ADFC825
-:10CDE000E4F8A5B4DFA85F31BC7135F63F6997E57B
-:10CDF000CF523EC1F64C3EDEB1E736EE45BFD147DD
-:10CE00006D3D1FF6F8EFB7FD487AFF191BCF1F0CD9
-:10CE1000839EF65826A651F65B39F369762BD07FB0
-:10CE200091A6D079F45BF48343FFA0CB22E8EE1FF8
-:10CE3000F6A24EBFAA44EEF320E5818C44771B0294
-:10CE4000CF3C6CF4173FB3CAB06EB6B11EFBCB75C6
-:10CE50009FC0F6B0EE551B3FEDC175AE92FE8D70D2
-:10CE6000E75EDC5F778AEC376DDF68F38602DBF71D
-:10CE7000E2BCABA2F37C85FAAF4A94E37DDD98BFB8
-:10CE800012DE4FFE8FD8BAD61BE0F9FC73FB099E69
-:10CE90004177640B9E0F410FA3F3F8CE960ECAEFB5
-:10CEA0008EF2117B2083F8C8132DEF35F2D17DB4BB
-:10CEB000EEEBBD2E384FD3E7E1F9E7E376E2F5DF9D
-:10CEC000379C93B8EF3E2E87241DD5B9653F803F30
-:10CED000C893B55E39EEDDF52DD3AFC7BCDCDE0DF2
-:10CEE000FE8A917E2BF90938C9C43FD7365EA7EB7D
-:10CEF0005ECAA36806B91E2F1F7BE35C45FA336F39
-:10CF000025781648FB9949BD63F13C9D5F8E79A356
-:10CF10007A47C53C32408C7A4737E659CDA27C2E01
-:10CF2000929B1AD4787479403717F3F85AA7C893AC
-:10CF3000CCDBCCD6EBEDEDFF399FAFE71BF3B9DCD3
-:10CF400094DFB73DBF41A13CB1CEBEEC3178DFEDFF
-:10CF50005CBA773BCAB5C14C0B7DA7E08CF8BEE646
-:10CF6000E0171D19F7C1FB53194E3FCAAB53293BBC
-:10CF7000E93B6AE7FC56419FDF7903F959E7570C13
-:10CF8000A35C917EC396EF77911FF0B4979773FFE0
-:10CF9000ED9937F01C633EF3FDCE00E931F65BE11D
-:10CFA00018C1BEE2FB9C45A2BE6ADB535FADC63131
-:10CFB00084FE22E5A7F9BE27FED8F4FA578F95EB39
-:10CFC0005F1EDECEC3863AAE58705C5E768EF05D34
-:10CFD000D85A797FD9A44F5599EE2733F11D54A91A
-:10CFE0008F174D68F4A31D57B4C1A81F9DEB79A1FD
-:10CFF000AF00ED5ABFD58DC7E4ED3E63BDD4C31677
-:10D00000F73C42F628E885867964FEEDEDACBF8BEF
-:10D01000EE857B5F3E6A9D18B35B3ADD55A4A7346D
-:10D02000FBA004FB39F9A5D2E47CD40FFAACF84597
-:10D03000589E7BAFDB07B4B35926D039ED57147D2A
-:10D040005ED0E6FDC6BC205E8EF9E3DBF61BF2E89F
-:10D05000C277AFC172D4CFC956EE473E8AFAC5D85F
-:10D0600052AA3FAF0A3F186BD88FE759CCAF779AD7
-:10D07000F83AEA27634BF6233D05A3E7DF0ECAFB28
-:10D080005BEE16EB613F23F9D1A97179F2DCF7135E
-:10D09000CEE0F781DE6F7BE0CF67893F83FCBC3356
-:10D0A000D7179D88748E117A1DE68B9BF93C39C089
-:10D0B000F3EFCAB4D95DA95EEEBF72007EB4D5D6D7
-:10D0C000D5E83788E5AB14D277D2D68E905F725B05
-:10D0D00080F3EF2BF346CF53592BF254461AA7A9EE
-:10D0E00084E7030C2AEE1A2E97AD0CE572E983D97A
-:10D0F0002E8C4DC976A525FC1C786F86761ACF1B21
-:10D10000B33FED02FAD388CFB8DF63A9A01D75271E
-:10D11000FF5EBDFC9EC9F914977F33BC5FDA27FC24
-:10D1200015E57F9EFFEC57F38CDF151D29FF2120AD
-:10D13000D69F57727DF21F1E4FD43484D710B4454A
-:10D14000FFE0B07C0891E720F32012033CEF4EE6AD
-:10D150004374865B097ED7FD9E8B38FF814EC706E0
-:10D16000904E6BB91C917476749E97D3DFDB7EA2D0
-:10D170003F4977D03E358072A486B72F7A9B7FF7E0
-:10D1800042EA17C9CF0DEDED984C72E8A6805E0E0D
-:10D19000B9A2F722330271E4D0F185DA27023AFB13
-:10D1A00008FA670752E3F69F1288633FFB66067D25
-:10D1B000346EF43EA7360DCBFFDDF320589F39EFD8
-:10D1C000849F17E6BC13A90F36FDEB2F5663DEC90B
-:10D1D00095055A15C713876F54AF1CE27A4E4C9FC2
-:10D1E000F4733BECFAEB8B8D34BFC8A7F910C6DFA4
-:10D1F000A81F5FEA4FF0FE9E802E8FE7A366BFC197
-:10D20000FAB6047471930FD0FF01DA9F88D7FC053A
-:10D21000D6FB30AD57E8FD1F41787E3B90FA915E1A
-:10D22000DF0BB4BE0A713ECF63F2DC7E89DE0FA352
-:10D23000836BA6FFD702BAB8B96EDCE3FAF946B23F
-:10D24000CFA1DD4FA87FC530FE39AD1F7794FE67B3
-:10D25000689E68BB68FFB37AFABC0E7CFE4B3D7ECD
-:10D260003F8473E4F7B4DFC97CFC378BA270FC0306
-:10D27000CD2BDEFFDD4F76553AF71623BC5A393DEC
-:10D280005D837E3DB598FB6743DC3F1B96709F2610
-:10D29000DE0FE17DD2A5F3385DDD92179C5E9C1F09
-:10D2A000B36FA3F6087B781FAE376A8FE040D30DCB
-:10D2B000727E9FDEDE58F82F07F7E17AAD0B79FB1F
-:10D2C0008262F71A94B3E632E82345B49F585EE6CB
-:10D2D0003C2C5F6D5C8CFFE33ACDF17F5DFDA2627B
-:10D2E00063FE02E9AFA0B7391D80E3D7EBAC131A98
-:10D2F000A15C59CCF557D03FE2DEEBAE2C8EFA1193
-:10D300002A8B75F918278256BA1F18D553C209649B
-:10D310004FC5F4A843FB8CF736BE4DE51281DFC63E
-:10D32000E2C3F5629D77D23E26887D5CBD7D88DABA
-:10D330007B78FB38F54DB4CE74BE4EE67AF9825553
-:10D34000170F434EB3609C17FF05E74CA96D593189
-:10D350007E23EA488FE2B542B9718FC4EFF7F7191F
-:10D36000ED43CE7F2B05BD6F2E3E528FF85BF9AE9D
-:10D370005CAF8DECC5BC681ED311E29FD3C21FE128
-:10D380002E81F6E9B4BE365ABF97AFEF4318BF8B74
-:10D39000C6671C3EB52C6C9B384A9E459FC03FF427
-:10D3A000BB9FFA39F9BA6A430AE9EBC126E068C0C3
-:10D3B00073FD0916D7CFF49562BBECFF15EAEF12A7
-:10D3C00076AC3FFE7DD9DDB1B8C96E6AEFE6F359A0
-:10D3D00041FE23DE02A1E30BF13B10B5E27BE3B596
-:10D3E000652A7D6FA1B6E0D252E107A1F8A68C8331
-:10D3F000973E3099E29B896509DC5E741AFF8E4581
-:10D4000070AD83BE2727BF5B2BF332AA98F1FB7266
-:10D4100071E25B067F8BF48B44BF27674D27FBD6F9
-:10D42000BE5FFCFD27D3F7E312DB18F9B71C5DFCE8
-:10D430001EB8394ED5B0A9F5B542CCFB506D149746
-:10D4400035C733CD7F0F63BE93696372281FE5F93B
-:10D45000E2D4581ECA5B7BB25DC88766FBF9AD910A
-:10D46000ECE73D46FB7950DACFDAF5B19F4F141B5C
-:10D47000EF0FECCF0DFE84F0AC6A74BE1D29295A63
-:10D480008A7E8477441EC5D987262C417F54B88F65
-:10D49000DF573827E2FC32DE7FB690B9DCF8DCE2F9
-:10D4A00020789E5D9712C123784C5773057E5750A4
-:10D4B000DAD10879F47F558A7D9AEDEDC402C0E790
-:10D4C0002C6233B2B3CFBADD1417A8EC11DF97107A
-:10D4D000F902D2CEAE14F7F8D796F17BD5E8B14376
-:10D4E0007A90DF0FAC1476B8B4C7077EC8147D1EDF
-:10D4F000C052E627FAAD01C2C0E772F13DC55A3706
-:10D50000DB828BFACD8CD01FE99CDAC3E9846D579E
-:10D51000E9EF5C9DED7B90CED591EE313884BF81F3
-:10D52000E4D8C40FC5CE7795E8CE8F6B386FC6515F
-:10D530007B95F37117DEFF4D8D7D5742DE9BDF9E9D
-:10D54000C2FD283797703F93F929BF1BF17EE5078D
-:10D55000C8CFAC128447CC9ECF2EB936F9398DFA9C
-:10D5600089EF56A4611C889F4BD34BB85EE01DC366
-:10D5700083B83DF6D1F300724B4689E7B2ABE711B1
-:10D58000CCC3F9CCFD2F0B7DA43937A495F0783F9F
-:10D59000D1AD39DE2FDB9D44FF549CF3F673255C3F
-:10D5A0007E9702895A7286DFE77FBD5D3B833ADE54
-:10D5B000C9F6727A9E52C3C998BFF59AB8CF0F8A3E
-:10D5C00016E533C9BC28396E6D5DE9990BBAF3AC29
-:10D5D00072D1A39467D6E93BF8B202EB3C27F2BDC7
-:10D5E0000693BD74CE858FF3EF4B2DAFB9EDCC050F
-:10D5F000DDF9615E2FE6458581D5379470BFE60B76
-:10D60000A58E81F979F8BD26CE874D7D67E93E4C20
-:10D610007D5B030BCDA0BC2915F17B6A1EFFFE428A
-:10D620006581958575EB1A3B5B5B57C2FD3ECD442A
-:10D63000A7B1BCC0167C5F6AD3C6E0DF9F94FE49E9
-:10D64000192F282DF915C5DD065318CD1FF4B00884
-:10D65000C6DD176AF7D88730EEE2F1927FA4A1C445
-:10D660004BEB6CEC3940EB490C5CA6F594AA00EF4F
-:10D6700071C3E12DF9A25BC05BB76F82F748FC5B19
-:10D68000B9484D46F8BE86F882763D826F8EA997DE
-:10D690005CEE38788FF62B2835C0DBE12937E0AD1A
-:10D6A00053FBDC18DC8FC473A3A87BABC7FA2AE258
-:10D6B000F15DC023233CC6CF83388EF8BA99B17F81
-:10D6C0002FE1DF9993F8AAEFE2DFBDAEEF2AA5EFD5
-:10D6D000C5D517DC664FA33880D28FF725D796358E
-:10D6E00030D4F7ED5A0A7DDF4EE26F6919E04FB78B
-:10D6F0005EE0C77D253ABDF303F8D71F27BC0B3D7D
-:10D70000F8C3F6FFC37C4F97C4D1CBFF52F187E13A
-:10D71000DFF3E1E7EECF84DC303FE5B93B627E33F7
-:10D720005BB2A6E503AC43F20DF26D8782F9938AF2
-:10D730000DE92C88FC8BF7D70A7EB105E3A1CD1E3D
-:10D74000D68F67E16EE423809BBD3CD38EFCD3B8BB
-:10D750002793E802ED7F82A738A75F8E9DD367E904
-:10D760007D0BA78BBF76DC07D6F30EADA74EDC2F63
-:10D77000F888C5A56E2A0F3AE6A37F563B40F2E52E
-:10D78000E83CB7944F19FCBB4DEF2F0E5AA4F1BCE7
-:10D7900031190F8D13FFF42A1F20FE698EAB8E14F2
-:10D7A0000F8D13FF34E8EB23C53F99294E6A8E7F16
-:10D7B0002EEEC9A6F8F3629F85BE532DF57E19F7AC
-:10D7C0007CA5E72995BE8B345D612999C3E3A33B12
-:10D7D000857F8CA156A7DBFFA90CFEFDEBDE34276D
-:10D7E000FDDD55FCC17C2C094F900F4E07CCDBB5FD
-:10D7F00088E76556651E36C3D52EEC926B82AB8CDE
-:10D80000AFDB7B94C866240D0F8BE6FFD97578B625
-:10D81000FBBE437864EA800BBFC7DDE81F4FF964A5
-:10D82000663C14F5F0BF4B59E49E437F9752E2BF2C
-:10D83000C8333C6F5095EB8B9337F817C7A777B376
-:10D84000336B147CCA38F64878BC252FB811F946DA
-:10D850007EBF49BE3F95C1E17B7E1A137FFFD4880E
-:10D860004F80BF46F7FA7DECC06665383D14897C71
-:10D87000CC225FF81ECA834FACF060DC2C0ADFF4C8
-:10D88000EF127C3B5BBDDBD13E3A5E66A37C9538F4
-:10D89000F4407FDFF66AF4300CEF7D1F0C7FAB0A9B
-:10D8A0001F5B9819873E3E305EAF824FBBF5504FED
-:10D8B00081371E9FBED0477CEAB7BA11AF129F12C4
-:10D8C000BFC3F1C9F50B89EF53F9DA37E7E7EBF19D
-:10D8D000AC3D81788EF16F98DB312CFE776F0E8B2B
-:10D8E0007C1618E749ECF7D4FCE8384FE1B8D59F2F
-:10D8F00088FFF74E0E9772B95BC7FA5F9C8876DF98
-:10D900000526F235FD2F7BD14FD3961D375FF3E40B
-:10D91000FD0AFF3B3D1E76C022CE578BCEDE3D8BEF
-:10D92000799B60DF9EC6BC4D78FE707E26EDB717F2
-:10D93000F337C7823E2EF23BEB706C9C07F4598C98
-:10D94000CB3335C4F05EFA207E9F65167E9FA5839B
-:10D95000E46E2C0FE31D531E062F5705A4BC714522
-:10D9600028EF261AFFF4840CF14F363362947705C2
-:10D970002143FC53E4E948F9B6595B100A1BE29FC6
-:10D98000E534FE993AD97E47A474BA3EFE591DD1BA
-:10D99000F4F1CDF01D54AE8B968354967EE8C70605
-:10D9A0001E08A11FDA3733F44BC493BC370F02486B
-:10D9B000C3BF436775B90FA21D0EF601D3F247D658
-:10D9C000AB3F2ACFFF0F526BA57D00800000000007
-:10D9D0001F8B080000000000000BE53C0D7454D5BF
-:10D9E00099F7CD7BF39364422621E200415F02E880
-:10D9F000D442187E020109BCF94932B62003048DD5
-:10DA000005E903722C746D1B6CA9B4AB9B81C4989F
-:10DA10000485D0B2DB9F6DB72342CFB1DAB371EB8F
-:10DA2000A944A41DA4555A2AC6363962976AA0296A
-:10DA3000075ADBA295D5EEE929FB7DDFBD77E6CD60
-:10DA4000CB84A0D03DF674389E97FBEE77EFFDBEF9
-:10DA5000EF7EFFF73E972F54185BC0E0E74D1A1A90
-:10DA6000630361F87302B6FDA651C6D8AAC9B25DB8
-:10DA70009934A631B6B840B6AB4D6321631D2E264E
-:10DA8000C6B30403F8579893DADB8DB09998C2585F
-:10DA900068B92AE06334FF6B6B24FCAE6408E65B74
-:10DAA000ED10EDC4CAA4E165EC634CB697527B4D12
-:10DAB000BA1DA7F69D8CAFBF3FF5B09980F1DF99F5
-:10DAC000139F605C03EFA23D7A7CFADF1FFEA7156F
-:10DAD00089CF6413FB3FE8F802BF6346154ECFF9C8
-:10DAE000FD7780EF5A928F031CDF0F207EF7103FE7
-:10DAF0009FE0F87D00F069237C7A009FC2BFFD7A29
-:10DB00002F5419BB71BDBF011DDFA47D9FC6E9B8AD
-:10DB10000CF84789EE20DF077BFF84908F31EC9F64
-:10DB2000C3E77BD529E428D164A2DC9F725AF60DA5
-:10DB3000DA0BFAE57A5BF49066C57F0BE9C9EA1265
-:10DB40003EFE77A97BCD4459A60D3F03F75D8EFFBE
-:10DB50003DF6678DFF3C8DEF72A6E1693D97E85772
-:10DB60000E6F237C33F42608BECF06DF28E82B3A5D
-:10DB7000DC914C58F8C1120F127FD27629F130D9BE
-:10DB8000A501976CEF20BDD959CEE71F7FF8E1249E
-:10DB9000E20FFC3B46FC9EC2F9F78FCE8F3F184246
-:10DBA0005E029C1F520EBF33C7F823CAD9070D5F10
-:10DBB000D83F35744D46FEFF1FD62BA6F5843EBDDB
-:10DBC000D7F1697D147E9F2D49F3776208DE8F0FB0
-:10DBD000EBD45FBDF1C9C8B5F0E79AE6475413E747
-:10DBE000051856CA587C9025B7C39A37B3A4CAC043
-:10DBF00087C58326F34DB3E835FB0AE1E1F23A44E9
-:10DC0000FB5B64FF562F92727D2289F145066FEF10
-:10DC10003ADCA734DEEC9B59782F3CEC7D44D01DD8
-:10DC20000C59F4E46ACFEF0F035F2CF150BA2DF8D2
-:10DC3000B3FAD35F9B847C585D21E7FD7612E779C8
-:10DC4000B558CEFB24ADBB3ABDCE0F783B5FC2FFCB
-:10DC500094E033780D985978257E417197C4EBB1E3
-:10DC6000C303B45F2E5FF2817173E0D9A40413B0D3
-:10DC70001F1FDBB84D35AD7681F5E821F06F77B029
-:10DC8000749BE42A63077A68DDAB8DD7E690E08F5A
-:10DC9000D0D3349E832C986056FC0EF0FDB9CAEBAD
-:10DCA0005BECC23D28B7579FEF29E7B516BE4B3D49
-:10DCB00058E34BEBB7C13CC0775DCEF36373A3F77A
-:10DCC000CAD705397FD86A4FAE9C8EBE5AA2E30DE3
-:10DCD000BE2F19FBF392996D7F2E1BBF4742167F13
-:10DCE000FE9EC787B2F5CC627F1E47BA5BBD252E6C
-:10DCF00094EF757E662401BF8BF85B9C798E0F2BA9
-:10DD0000649FD2FA59CDC7AFDCC59A7BA60D87BFF9
-:10DD100036EC20B8D667D8C61E982FE43ADF14B781
-:10DD2000C0A542BCFF5048A127D07788F8BF95E333
-:10DD3000772CA4D37A21A6310374AA61E5A4329486
-:10DD400083D65FF2F9983FC8561466E63B2BE693FC
-:10DD5000EB1C5E5ED868A5E327629D63214E07FA3F
-:10DD60007FE2E77D9C0EB5E86E3FCEAF16C8FCF2B1
-:10DD700077C4D776A76827DE22BF3690B6437F24C4
-:10DD8000795FE59672F90EE9BF8CD7DF0AFD6F3235
-:10DD9000B110F167CC31CB3AEE0F6407471B37283F
-:10DDA000FD459BD8AF447ABF4E21DEA38D57234A51
-:10DDB00033F1C9C3520AF80FD5EBDBDB05A4042A03
-:10DDC0008D7338FEE84CE3B797330FF0E93CEDCBA9
-:10DDD000E7B2F3114BFFDBA1AC7CE0FCDD719C07EB
-:10DDE0005676C3BEBDB2462D5D0F7CFB2BEE4F15A4
-:10DDF000E507B15CF2F5D7CCBEFC359415CF470AE8
-:10DE0000AB408FD8784770AA3E7C9C37AC4839131A
-:10DE1000FBA43D8274B4A7F58DB77716F3FEBCE77B
-:10DE20009CEB843E1584719DA7047F99AF14D76342
-:10DE3000D38EA6D4B9E05F59FA6738A0BD1EFF8221
-:10DE4000F50722A79C28076B3B14239943EE87E92B
-:10DE5000498798FFA1F4FE8D0F5F43F39A6CAEF0F3
-:10DE60001FF01BF8C4369AB7B14921FDB3EBCBE4E0
-:10DE700030E7DFE4709A4F93097F43C8EF9CF85472
-:10DE80006C032873CFCACCBF56E01D72C60F5D0B62
-:10DE900072D0DEA6E8688FD66D5DD7510E6DA639BB
-:10DEA0008353E17103720AC6B5FB2BBC68075E148D
-:10DEB000EBE17C2ED847F425FE1282631A3CE7C6BC
-:10DEC000361FC1E1EF4E37AB909EEAF8EE0892B5EF
-:10DED000A0F1C923F8BC15CC34C629DB167D3D1E44
-:10DEE00086FDEB9BEF0CA2A84174D63705F06A10B3
-:10DEF000786946FD393606B228170BA6E6A05FF70B
-:10DF000006B7C3FB86A64F2C61950013770E0D7ADA
-:10DF10009018935DACC079B5A1C100E7D945B07147
-:10DF2000CBB73A336DC40DFB3D99FE95D773FBB467
-:10DF30003A0CFCB4C8DD0F057D3F14FCDC0538F459
-:10DF40004DA3090A19EA0DDBE840FEAD1373F5B5E0
-:10DF5000ADFCC88700BF0B0116C4B61BE95333F4F0
-:10DF60009D9AA471FA98E15D3A0ED615FB7ABC052C
-:10DF70006CDD8D306D1BD009F468EA9AA294458E51
-:10DF80008F8F315910E3B640E20106721231773BB0
-:10DF900007018FEB9BDEDC8871DF5AD3ADD7038A94
-:10DFA000776CF4D5625CBBD2147C59E23C8D747BF7
-:10DFB000E01FF2C5953AF76317F279A1C2C6C3FC18
-:10DFC000CBA2BC5FF2C5CDB4D356BE68B6F6D6932D
-:10DFD000E53B7F6481FF4CB8B0F4CC87E18FD96C0E
-:10DFE000F645A0130CC852C4E74287E253CB09CCD4
-:10DFF000C1804E9787EFE3FE8ECD2FA29EAEF56BCC
-:10E0000041878EF831E25FA358E39D167DE78F20AC
-:10E01000568D6CDDDD8D727747BFCADC00D7BE66DA
-:10E020003FCE843F0FCEA709B970147CA34F0338AD
-:10E03000ED8B2AC3F5241F81DFBEB9F0FEF4008CFE
-:10E0400007D03BAA814FB0EEAD865BD7012E7FE1B2
-:10E050009B6DC8A77CD69C1A0BEDDBFC0E96F26478
-:10E06000E802BA13822F8E8B0AADA56B725D4756FC
-:10E070003FF125FF0B11C6D076278CBE2900B75C77
-:10E08000CA6D07DFCFE506DF0FB9AF2CCAE555EE45
-:10E090004BBE4D5EDDD5CE8C7CE69057FB3E246DAD
-:10E0A000FBB05FE37A72AA5FA5F8E8D49ED25BABBF
-:10E0B000811F893D0ED263C8D30E2845F0474A61BF
-:10E0C0001AF0FF76812FFD006E7F7371B2AB3CB307
-:10E0D0001FB7079EFFB352C938D4B88C3D6298C4AD
-:10E0E00042FB36D1BAFDAB8912D4D38FB11E27EAD9
-:10E0F000F59D6CD089F2FF714C0555B48F4117BE68
-:10E100006FF4F85CC8C7FD7B9E2B443B929AE02CD1
-:10E110003E13205561563B697F2227CE48BA01380D
-:10E1200025EDA7C7F4935DF6C293ECB4C1B05D5C76
-:10E130001BF59839FCC8E1D9E60B6807655BF33538
-:10E1400033C4E35BB3E33F217B29C6EB95C64FB1F4
-:10E15000FDBD59C6317C7E1BE33DF00FE7C3F7518F
-:10E160005EF2EE74E338DA35BB1D3B8D764CCFC8DA
-:10E17000C30A9B3C483B7602ED1874AD407D05BE5A
-:10E18000B1D895D9B153520E6E6237217F809E5F10
-:10E19000931FD1801EE0CB6BB8EF331856DF52AC23
-:10E1A00084C8D47D809F22F0C3F70AD87765EB0B33
-:10E1B0007F56C6F0F6028053C4BE621A598B7EE3C6
-:10E1C0003F821ECF64B417E609A4DBCE1770CC4E95
-:10E1D000CACBFCCF9F40B971143C3BC9CCE107D3FB
-:10E1E000FB7AB7F38D345DA84710C9231D0A331D90
-:10E1F00017911E1F2031FE5272912039685FAA10BC
-:10E200007DEDE5AC11ED791B76CD07795FAAF4A021
-:10E21000BC3F1E29E1F1D2141E17761527FD415E81
-:10E220006721781608B295D333F33E1E5109FEA636
-:10E230003946013A2E88FB285E92F1AA84F345788C
-:10E240005C3936C2E38C4065BC841C5D6990F80E75
-:10E2500071D4586A7B5349C7385117E13FDD618952
-:10E260002306262619C621F946EEB8E1BA48DAAFE8
-:10E270005F17413AF648BF6E5C8FEDC5637D0D6850
-:10E28000E75C80F7DEF28CBFFEFED2FB5558967D30
-:10E2900038524EF85537ED6E1D07FB1D0A4DF662DC
-:10E2A000D894AA49FA318EE81A0F7CC8A12F5B23B3
-:10E2B000DC0FCEB94EC0097E49BFEF81F0DB09EB20
-:10E2C000609AEFC038A08CC70177462A689C8C07FB
-:10E2D000003EE102B8D00D26CDD33E35F77A770A5D
-:10E2E0007E66FC6DB008ED3563CDE42FE2C29FBCC5
-:10E2F000D262BC36044239D012A327D8FFBE2818F8
-:10E30000B8135AA23098837FCB6AF779D06FB706DB
-:10E31000D67B0631FE3322346FE39AD06B43167BF3
-:10E32000DB55C626611C705BC32DAF0D59F4ADAF34
-:10E3300090E38B7E26E1CECCBB0AE504F03D127261
-:10E34000A7160343F3FD2CE956E8E9D4510F223A0E
-:10E35000F5C78D75CCC47CBCFA9446F5AF62968641
-:10E36000DF065B13093027E215F727198ECB8736B6
-:10E37000C2C717BE49F0CBAA5596B0E009F6672D83
-:10E38000C9812D5EDA850206F3B6CF5792DB61DED6
-:10E3900006FF5DE47FB62DCAA7F7B06ED20DEF6F12
-:10E3A0009DDA447E4BC657EDD16890FCD315C65319
-:10E3B0008767C7EF41BC5CFEB45DFD1CC97FC6AE7C
-:10E3C0006E8970BBFA797C2FEDC7DE23AF90FD809C
-:10E3D0001C84F8DC05FCFEAF1CFBB84DE84157314E
-:10E3E00097437BFFD784BCBE3B3DDE8AF31BE0D363
-:10E3F000FCB3DE7FBCD92EE34DC1C72BE50FF0E3A4
-:10E40000DF2216BB0CFCF84AA46A381FE0D786F658
-:10E410004295D6E2094543F9CF13CD479899C47187
-:10E420001ED64C40AA37CED0DF0D9F27C570DC6AC0
-:10E4300041DF7BB5C7FF09E10DB76BC61311CA0BEE
-:10E44000B93C4BBB0C7AC9FDEFFBB4DBFD0EB0A7AA
-:10E45000804F07BE9A9FE93F24F6B9B7CA3C84EBC8
-:10E46000DE50E65987FC7F5031FC5E15EB9E66233B
-:10E47000DA11A6CFCA1A377C9D6D34CF4085B91109
-:10E48000F59AE92B4681DF2ED6D5B9BFD0391DB01C
-:10E49000EE57F32767DAA3D1F5FD88F173C4BBD536
-:10E4A0008CFF0AF5EEA580434F28F4243DECAACE5C
-:10E4B0004B2AD02E9865BECAF711EC284CDD157892
-:10E4C0008BE2A2654B148AD396792083CB6127CF48
-:10E4D000087FB34CE7FDECA4E1B7D63B8AA38EECF2
-:10E4E000BC1744C2B0D62FA28EF5589797FE0CEBFE
-:10E4F00026B9F4EDBCD027D5FD6619DAD5979CB9BD
-:10E50000EDF65B1117C12951519710FE6F959BE7EE
-:10E5100057EC67809FC5BFF65685FF47D8AF84622A
-:10E52000F18B0313CF93BDA31ECBFB65A2EEC4FA00
-:10E53000B3E79174964459D6BA20AF8E28AF63A83A
-:10E54000514BFF2A95F1BA475F36BF001F4F94E247
-:10E550003F3634023EFB72E273221B9F9228DF9704
-:10E56000DE2AA304E703FF3C16D7EF0883FCE5E0AF
-:10E57000EF1333C2D762BFC6121D15E5978C5BAF90
-:10E580004338D9B6C4AD7A34DBBE9647B97DAD8881
-:10E59000927DCDBD6EA5E0DB95DA87F7ABF73B6CDE
-:10E5A000FA2E9F5D834F1554021E6E77E2B3A4AF1F
-:10E5B000D32E4FBF3F7E5DDF44A4F390904FB4ED68
-:10E5C000186F183A8F473E1DE5721CBA214970CF6B
-:10E5D0008C107FA4E1803158971B290E99FF3EE3F0
-:10E5E00090AE850305384FEBDB7B0B308F7F6628C1
-:10E5F0009C330E3954D64D78DAE390DE11E290BBAD
-:10E60000A23C5E3DF21B17C5153567B99FAF39DBDC
-:10E61000ADEA209F7747B9DD9E3FD4A79A202735E2
-:10E620001887C03CBD220E41F86D20BA91B7BB558A
-:10E63000C46BFED93E1A57036D8C43E68F108700DA
-:10E64000162ACADD819AAE5FE0BED9E97DA1D2DC8F
-:10E6500012B5E45BD5837D744E22C77505B6179855
-:10E66000B4CFD972737836B7BF99715CDEED702381
-:10E67000C957ADEA0D607DA093E507910FEFE48DDA
-:10E68000A964453CAFC1B8B8134181EECE9305C92A
-:10E6900004E6D51EDE7F6FFE98BDF894F6C723F41E
-:10E6A000E29DBCEB92220F328A60FCBDAA915A0C0B
-:10E6B000FEA073CA977C9C9ECDA4475B046FC2BB2F
-:10E6C00035CAA76FF6F37D90F1D78BAB148A0F6133
-:10E6D0009A254B017E9E98DF3587E78775AA97E0DC
-:10E6E0007604781C7973E23CD52FE60FBA741DDAF4
-:10E6F000F306EFE2F9A2FAECD1028CF73FAC311548
-:10E70000DEAF6A8BB7927C9E74513DC3807FA89F19
-:10E7100055FD3DC4B7822157569D231F2C59CA125F
-:10E72000B7B86C6DA6AE29CA6587E4D35E87783228
-:10E730002AF2CF4A36E322F0E502BBAF0369734FFA
-:10E740000D1F79940D1F2FEB0B9B66184FA37C4C6C
-:10E75000710E7EF769E057EF1B2EAA5BF4EED9F33A
-:10E76000D14AA02FD1AD515D57E6334059C972CC83
-:10E7700067910754973EBE1EE5F260A16C8341038A
-:10E78000BC0FA6CFEB37AD372CED63D1074EA3DF1F
-:10E790003B788D843FC7C7CB7662703DDED7383873
-:10E7A0009EB72F44D54713B4BF831AE5D15B7FEDE5
-:10E7B000CD651F8FD772FD92ED5BAB3773791D6509
-:10E7C0001CD8F557ADFA21C7E52D35774C077E1CCF
-:10E7D0001C72D0F910E459298C0F36CD305F47F800
-:10E7E000074F70BE1E7CE31E1FEE937BECE0E772CA
-:10E7F000D9F9DF0B7F94CEF36672FB016E4E43BFF7
-:10E80000B56BD133C72A619DE3F3A7CE528104E0F3
-:10E810008507E36539DE5D5B91A587B756BFACAE72
-:10E8200047FBF3C6E9865CFA5E1535FF944D0F3F52
-:10E83000176DEDD688FF25CFD7EFC57B3FA99AEEA0
-:10E840003E0DF6B7F7F70E86794AEF7491878F84FD
-:10E850005710F02AB92CBCF6CCCB216F8097ABF6C1
-:10E860009AE178BD54CB883F2F541A9EDAAAE178FA
-:10E870003251C75C20EC7DDEB92F51DDB177D0413C
-:10E88000C5930B437B55143D59FFEE3A518111104E
-:10E890005BBCE4948A2265DEA766E9DDBC13F95906
-:10E8A000ED3B9BC766B5576F9C98D143F86F457495
-:10E8B0007256DBEDBF29AB1D62B3B3DA0D4B6ECEE2
-:10E8C0009AAFD617C96AD7FB3F9A057F8BBE32AB8A
-:10E8D000FDD1C0EA2CF8A5C10D59FD35BEDD0F6094
-:10E8E000F9283E6DA63696913CCE44BE16F41B2404
-:10E8F0008F0F9EB8C7877291AA894F42791B28EC67
-:10E900002BC3FAF58BCEDCF9DA7DB5AAF4DF65E826
-:10E91000EF0DC6F335091FAA18CCAACB6FA8E5FEE8
-:10E92000796DAD92B34E60F7C7D20F4BBF6C5FDF0E
-:10E93000EE77EDFE76D987F67A78BD9FFBFD5542DE
-:10E940000E5A033FF762BEFE6203AF237495C5A95A
-:10E950006E3020FCF39155B74FC273B5FC8039D6A9
-:10E960005D9EF1D7914092FD1AEB3CBE249B3C1D6D
-:10E97000FB936CC374AA4B6B9169FCFD0DE2FD5DCA
-:10E98000F8043F5D67E19BDDFF863C337F5CC4326A
-:10E99000F14AC3BB46B408F0FB48D3935A293C2341
-:10E9A000DEC39AD50E1DAFF96DE9087EFA93B53630
-:10E9B0007DC271BD432B2EE9075E6FE175F7EFB79E
-:10E9C00078580AE83BD9E2A3E72F5BFCF4FEE51692
-:10E9D0009D9EED2D017AA65A82D4FF8B966A7AFE0F
-:10E9E000A8C5A0E7F32D317A1E6D8913DC4F5B1AA1
-:10E9F000E9F9B31693DEEF147AFA41C1C708C8BA31
-:10EA000042FC884321BE36E055DD05670DD56AE737
-:10EA100081AFFF9A8BAFEFD79FA46A7A26A29C8121
-:10EA2000BFCAA94F3DB532AE4FEF37E125E361CC08
-:10EA30005F504E649D0EF07B0CF173637DAEE4CAB3
-:10EA4000F13BA870BC0E16F3FA0DCEB3BC10EDF975
-:10EA5000D7E361B2E7D7CC247BEE675AB63D2F1FD0
-:10EA600066CFD791DEB1A35827C5FA229D53D8EAC5
-:10EA70002045753A8D93759045EFF23AC868F403D6
-:10EA8000DD47D16E49BB7DB974DBE93D3CDB7809DC
-:10EA9000E791FE7998FF30EF26FF512D7496696F4C
-:10EAA000539C5820E8D9757A4511DA173722C8F3F4
-:10EAB000748355E33E33791F60EFC6B2E1F3BE5E67
-:10EAC000D343FE7C473ACE7993E298E1FE2B9B0F2D
-:10EAD000180B59FD3BF0E15CB65FE47CA8559F1D27
-:10EAE000DC0EFEF9E020E375B239FCBC4EFAC183BE
-:10EAF00067791DE382A624196C5D983577CF83E78B
-:10EB000081FB59691CCF9B263982FB01B4E0B95EB9
-:10EB1000DD0370A141736C1EF457A7F2685C78C9DD
-:10EB2000CC24B61BE26F927D0A6BD97E1223D4B43B
-:10EB3000DFA1225889AD3D2103AFE2FE5664DA30F1
-:10EB4000EF27669B5A1DD0B5E27C33D3617E7719DF
-:10EB500073D2FD90E1FEFD6EC55267D358B003E954
-:10EB6000D0BEB0839FEBD9E44DF249D6DB641EFEE4
-:10EB700008337C7539E2873671EE623F6F796BBA84
-:10EB8000E94778C5F73C9DB7B08D8CDF8F70407E2C
-:10EB900082FC1BE34AEE2F1F2E77DF9B75CBA43A36
-:10EBA000AA532494AB93B7772B94B78BBC89E99F76
-:10EBB0007158F3189937D9F3A387849DDD897616A8
-:10EBC0009E0F3919E55BED4A7E70AF92C997C06F11
-:10EBD000CE40BA16D589F317D63C8F9FD3DD9F95CB
-:10EBE0002F8D88B7C84B9CE97D2FF39D29C8ECBBBE
-:10EBF000D7D5EDC77B8E9D33BFD1B81EF936D34331
-:10EC0000E79C4C4BE96877ECF4305F8295CECDEC15
-:10EC1000B7CAB433589FED806006CF7B1FC62F0163
-:10EC200060BEC2A0232BEE29AACE8EDB6EAF9376F8
-:10EC3000F6EAD0810240E7DB124F1617E7993CFE57
-:10EC4000F488F76D3AB7170CED9DE57CBDCD6B7878
-:10EC50007C96FD7F10F7C73D323E6A799B0FEBE053
-:10EC6000DD5E07E97787AE759643BBC3ABF1F84627
-:10EC700077C4729D43EDAA5304DD1C2F9FC04B0D3A
-:10EC8000ADA03868A4F5BA84BCC876FE34D3207D24
-:10EC9000D48371CC935BBDA50AD64765FFA63A45E0
-:10ECA000C84B37F1A153C455F9819E9403E56CFC20
-:10ECB0005DB3916D1E8893CEC07BCFB41E8AABBC72
-:10ECC000135C662EBCBF2CE6EB74066394F7173A10
-:10ECD00018E6FD9DE5B9FDE83FD7F138B3559F151E
-:10ECE00047F804F065AA321CEE53420E1E70821CD7
-:10ECF000C2FA9D536FA37B629D9318D9EF8AFAE9FC
-:10ED00008F6EF3E69043FD33B47F4E1F93E7EF59C8
-:10ED1000F7255AF586C675B0AEF6320BA2CDB0EB2C
-:10ED20009B73FC8AC67578DFA23A3F88F0B5EACFBC
-:10ED300012C8C7F620A37A8756DCE441BC1F2CD347
-:10ED4000E87E449AAF33CCC7D07E8C26DF767C60D9
-:10ED50003D92BB91F6D78E1F85F2B32E015F6C36C4
-:10ED6000C673CCF7CBB45E65CB977314F91A8D9E3E
-:10ED70002CFF5A96F1AF3FA9DBBC01EFA93DCC783F
-:10ED8000FFB1BA30E5FBF6F6D5D2F356ADBB11F7BD
-:10ED9000A5758A8BE4CF3EBEB39CE3D5F57C8D5838
-:10EDA000D7A7A0FCEFAC2EC943FBEE45436DE16B4A
-:10EDB000AAD23C5567F1DFC5D1661EB7D731925F45
-:10EDC000AF1EF74D01B9F0F6AB2053C077C75FDE39
-:10EDD0003DA5BF7F3EB26E83E4964C3B975BF61732
-:10EDE000E04B9110EB31ECA13E7E5F640BC1497E9C
-:10EDF000EDBAFE0FC1D425F8366661767DEABDD640
-:10EE00009F94FAC252E2731ECB433E5F60F729E43F
-:10EE1000BFA306E99D2F6D57F9BD9552D90472B075
-:10EE20004D22A764EA520CCF3D50BF4C46F10D4134
-:10EE30008E13475E44B78FC64D14D34CC00B352A92
-:10EE4000CA3FB7BB17D81B7C7D1886F756948483BE
-:10EE5000FCECF528D70057CECC3F9FCA719F679234
-:10EE6000AFE9C90DF09C582FEA69829ED1F821F1D3
-:10EE7000FE5BC9AD8C0FEC755459677D1AEBACCABB
-:10EE8000E87554A69D27BEC9F8D75E5705BF5680C2
-:10EE90007C7FE7068D7511DF79BC90C9F34D8FF546
-:10EEA000FE9DF497EDBE1559F5F97923D0FBD428D2
-:10EEB0007EB1AB1FEC26C6D1FEED549F3F7072FDB4
-:10EEC00051CCE32FF85D3AB3D8FFF6C2ECF3033927
-:10EED000EFF67A51871F5FC770BCD66732BCB7E7C1
-:10EEE000F207C92FB42AB9CF1DBAEA1DE2BCD1E698
-:10EEF000276CE733FF9DE74DBA2A58DA7FA8C23E58
-:10EF00004BFFCA34F0A2E3ACE3B91D95FC3820E214
-:10EF1000D1AEE736D13D03E6B7D47D2B72AC6F8F0F
-:10EF20001B0D43F7CDCDC4B1CA208F5FE5FAED22AA
-:10EF3000EF6E3DC9F7235FDC37B2D30BF1EF17EB70
-:10EF400081DE8280C356DFCAB637F678D8ED618994
-:10EF50007C8BFD8378B8A59EE284EC7876428CF1B8
-:10EF60007B41C526C3FA4FC46FAA58AF99DBDFAC0B
-:10EF700032A07BDEC94BEF47633D8F17DA03EBE32B
-:10EF80009837C9FAF3AE451F21FB0A7EB4BBDE6297
-:10EF900077E57D87F75A8F92F23A57EC637A7DFBDB
-:10EFA000BD94855BF8B9D1C97B8EA13C1E00794424
-:10EFB0003FDF5E98D8311DE3939755B65F1F5EBF64
-:10EFC000B2D325EB506363FCDE8ACBDF7E64B1C332
-:10EFD000C29FC1665527FE180CCF8934714E64AFAD
-:10EFE0003BB9DD4633FAEF548DD168AD3B4BBE35AE
-:10EFF0000A797EBDA699CEB19E1EE1DC58C2E1E73A
-:10F00000659887CB3A56D90CF359E4EFDCD86615EE
-:10F01000CD48757C33DDBF2CF81746F923CB5792CA
-:10F02000FB61A9E7163D43F9E59FFC8CEA6C2ECC09
-:10F030002F4B319FE4F9A5CC5BA59DA8559FE8A86F
-:10F04000C07B1DFD1ADDD32B786E9307E3DE50FFE6
-:10F0500006CAF10C655501EEA3BCB724F1BCD2FC85
-:10F06000B40AF353CBF94AC66EC47E8572D0D5126A
-:10F07000FF5514E4A3B7C5A0767B4B233DABB4A4E6
-:10F0800081F4540528E3630B86A0DF8247555F2C8B
-:10F09000ABDD5569FE86EB553CEBBDDB0FF359E468
-:10F0A00002F2E3730837F724E7A76B8942F711965A
-:10F0B0000DB207B86EFFC3D8A182D8D5B143BED870
-:10F0C00025ED103F67750D8A73569BBE3D5EAF936D
-:10F0D0001EA4F50ECF5BC9CF25683C9D19CE077ADB
-:10F0E000C67C92DBADCCBD0EFA9E3124BEB3BEF120
-:10F0F00068CD3E8C67DB5F95FDCBF719967E9688D1
-:10F100003661EDEF3026C71067761E2D6DA2EFB089
-:10F11000C5773491C6E2B20196B9EF68E7D74331BB
-:10F1200047D67D9A10E3F534D9BF3926F24320073C
-:10F13000EB76F2BE443EDE97C811BFFF9398EF5EB8
-:10F14000E453157E1FC2EF2B2CB67D1F62C42EFD2B
-:10F150007D4842F48FF63DC81D319E5F98623DFCAC
-:10F16000FE3F86F8C6F97718EBC57E2DE84FB68EC0
-:10F17000C120D1CF72CE138F713FFF428CDF7771E8
-:10F18000F90D0DF705E65B4172D0C8EF67CAFE05C1
-:10F1900067D3FDB7D17A0DBC7FC15993EA48F2BB62
-:10F1A000BC78ECC67DDBB4CCBD9C76AC4778F1FB7B
-:10F1B000147EDFE9DF059DF6A7FC3EE5369FB8DF4C
-:10F1C000C326EFC3DA66ABC1BFC7BC2576D35042B6
-:10F1D000A3F5EFA2F5C5F738D5825E78BF89DEDBEF
-:10F1E000FEBF024DB1B27DE23B9E4F115DCD1CEFE3
-:10F1F000F4FF2721319BE44BC257C7663509F8CF8E
-:10F2000012FC460E9F431E843C56119E9731DFFD33
-:10F2100084DF1A8EDF87627AD6F75F526E016E3B0B
-:10F22000C189EF83FAE31B3C68CFD3DFFD27A6ED4E
-:10F2300033A65C169F76D03CA65C8FF3497573BDF0
-:10F2400090F22FE5E1BB621F66C61429575FA6F155
-:10F250004D578DFE6F123F6DDF238D4647A032BEA6
-:10F260008FF0F0A7EF23EF8FE5D6CFF7848FFC7EEA
-:10F27000CCAE17CF0AFA61DDEFD13A6541BA9704F7
-:10F28000EB3E7535D685797F407CF0A4E7FD21B54E
-:10F29000AF705E56567A59F74AFE0FED913B6F609C
-:10F2A00046000000000000001F8B08000000000066
-:10F2B000000B93E46660F8510FC181486C62F11A4B
-:10F2C0007606866816068699AC0C0C15402CC74944
-:10F2D0009AFEE540FD8B80782E10CF00E2C940DC1D
-:10F2E00007C49D40DC02C49240F34480981F88B953
-:10F2F000809815881980F8370703C3370E8439378B
-:10F3000080620F48B41B84AD7810EC3340FF6F046B
-:10F31000E2AB6484C3281E1E389D9F81A15A00C1A0
-:10F3200017104495CFE047B0B94429B34B1AA81F32
-:10F3300000656D40B4800300000000000000000084
-:10F340001F8B080000000000000BE57D0B7854D5F2
-:10F35000B5F03A8F79666672124298842027103091
-:10F36000680A4380088AF51022624BED48A9622F93
-:10F37000B5038D80104854ACDC4ABF0C4C8020286B
-:10F38000415141910E0816156D44AC58D13B20B542
-:10F39000B4B56D6CB9D55AED0DB5AD2F0C8852FDD5
-:10F3A000FBEBE5EEB5F63E9973CECC24E0EBB7F778
-:10F3B0000F9FEEECB35F6BAFD75E7BEDB577DCB242
-:10F3C0000B0A07029CC49F0B006E7103C098743A2D
-:10F3D000F2C66FCC7F6834FBFDFFBA23DBF5743DCA
-:10F3E000331D0812D50330008A012EF0B25F59BDDB
-:10F3F000893F3FF2A7114500FB40010FFB945227C4
-:10F40000F6F91AEB67DF8710C172F9E781B2CE0017
-:10F41000B68B53BB2F036F972AD7CBB42ACC808CE3
-:10F42000DF0D2FFDCEFA19BCA989B53FF14180DA75
-:10F430003BE13053F850869468737210F6ABBED738
-:10F440005929F2E5C00607016F1D404D1ADE03AFD2
-:10F45000BC46F0EE5719BC7A96F1BD0CFEA234FC06
-:10F46000FBE01BF950C5E1376AD2F09F2E3C34FF18
-:10F47000BE002B9BF5272B5C003737C39315430049
-:10F4800056377B29BFBC59A37CA2394CF9952A6B0E
-:10F49000C2F0B0721B24E3AC7D6834AB6FF6C7FEDC
-:10F4A0000B54796D7977116BEF4DE7D540D896F70E
-:10F4B00096E9B63C03E75098CDFB2C319FE5CD0C87
-:10F4C000071E1CDF0BC69958FE6DC28B4FE02D1135
-:10F4D0001C7AF9208697D6E715466900976E4C4747
-:10F4E000F82A026E3DC958E3ACC0EC29309C8D1B54
-:10F4F0008A01B07A89DB016E65700F0B4C7A03428A
-:10F5000000F7B1FE5B59FF4AA8F5450F2B5F55EE9A
-:10F51000D615C4CB0EF52F9D6C0C2FFB87783B7353
-:10F5200003CFA7E7C5F296790E034B396BFFCB8269
-:10F530003B5E94181C890AB7EE91D2E374D3A59769
-:10F54000FE87B4D9F3CEFE2B74A316F9D4EC77085A
-:10F55000449769812F6EBF6731DCF6294CF76B8EBB
-:10F56000D36BBF8CFC51D676C80648A6CA33C7A950
-:10F57000D02393E3ACBC62830AC972FEBD88C94341
-:10F5800005FF155696D5FA635599F080759C41692B
-:10F59000BA54E8EE9932E38B8A8ACBE64B8C6FA0A3
-:10F5A000CD42E7419C41515ED6366BC48F37375709
-:10F5B00052BAAD596B27F9F94899DE5E9529877FD4
-:10F5C000453DC5DADDE202E2C3F876486E97B0BF8A
-:10F5D000E8F4992CBF666471F54D3AE6A7CBA817FD
-:10F5E0004CFE5E23E9C4DF71C6DFA8FF9CF271B355
-:10F5F000CBF80AF6B76AA42C2D433C57707EAF7047
-:10F60000A5BC83B1DFB64123E3D84FE4779D58AF63
-:10F6100062C8505D61E30EABE0FCFFCB31777851FF
-:10F620000F76CF7F71717BC528807C071F68A7C8C4
-:10F6300007DAF89EF9C01CE7D39687CF8EBFDA7A37
-:10F64000E4AF35915BDF40BDB1AD82EB0D275C25AA
-:10F650000353E1682093DF2A2A189F219D223DF35E
-:10F660009933BDBD3909AF321EBAAD394C7CB7AE46
-:10F6700059A774B5E04317F25409CB0B3E84A2D1CD
-:10F6800094CFB95EC1525A8FFA4E4B428CC1791B4E
-:10F69000F2E7B9F87DB96194B1E695661E5232D3AE
-:10F6A000FDEBB0BC94F20694217F9AE58FC40DD691
-:10F6B000BE50D49F243D124F3024DDE6E3F9C952F9
-:10F6C00097112FB3B65F6D18E3D3F5593E555B61C3
-:10F6D000ED8FF55F6585E719AA6FF6572F1D36E2A6
-:10F6E0002CBFCEC7FB6B955EFC5CFABF496A0BE38F
-:10F6F00042B3CAD1CF4D663EDE661855E971CA974E
-:10F700003E6CC4ADE5F0B0ADBC66695B3CCEF07656
-:10F710002744074B8CBE2553A26160F4F7459371D3
-:10F720005C6AD3F0717CA7E77707C1EBAFE0E555E2
-:10F73000D2EF8D84853E13A4DFC4117ED3BE510465
-:10F74000BFCA3F2FBBEE39C6AF4ABE3B4276461119
-:10F75000CB8C63E34D8B81CEE090C331407DA084A0
-:10F76000D5BF5BE5C0E43F06E75882B32E3A3D07BC
-:10F770009C712B9C261CBDC16DC2919B4FF9F84E0C
-:10F780007EAABD64EC6FC73316F775B82268E7F53B
-:10F79000413C313D001FDE66B8D8F73E5319EE7587
-:10F7A000A2DB74189CD96FD19452485AD6F14F9B62
-:10F7B000AE83313F86F0F61D694C9ABE2C3FD38A4A
-:10F7C000C7B1A29E93FFCCF9B933E6F75DDBFC40ED
-:10F7D0006D0B4783BDCF6F9D2F323D1AC8ACF74BE1
-:10F7E00089DBD1B593C67E1DF878E061FAAB00C71E
-:10F7F000AB4E8F57F015361E76A626B38E5758C7D8
-:10F80000C6F37E76F874CAA309AF2F03DEDB6CF073
-:10F81000DEE462729B85FE9F35BCA72A7F7EA67FB1
-:10F8200049FE2A7B96BF4FBBBF02FC95F1D3BB2A92
-:10F83000A42E60F85A74A1371997D27AEEF3C657FE
-:10F840001F2C62F45BF4EB51872F9031C3F8FA4B15
-:10F85000E9F1174A3AC19D8BBF73CD072069EBE7E9
-:10F86000FFD57C72E1F5B3D643A7AA5F97FDC14FE0
-:10F87000FBBBE5159044795A7EF042DA672E7F6E25
-:10F88000623F60FDB85ACF06834DAA40D819CBD14C
-:10F89000CEC0FEEB4ECDCEB8A919DA5B98D1F558A3
-:10F8A000284A76D17209A8FD1A66B72599FD32FA61
-:10F8B000F96DDE9901B2AB285DEE02B263463F7F7F
-:10F8C000409BC8A6E01F523812797FB9CFFC7E68F2
-:10F8D00032DAB9AB2BD877C61ACB83BC3FF63D8A58
-:10F8E000F5F386F0EFB9E0CAAB64F058F0EE732799
-:10F8F00063D9F4E3976599F0B351D85D37A3DDC5BB
-:10F9000014B2CFDF1643BBDA5FECD6B74A99EDA647
-:10F91000CBDCEE5F3FE427717469AC42FB8DCD7F99
-:10F92000FFA5F7416715AE836D868CED23DC35B0FE
-:10F93000D1B1DE07D086A375332C4D646BA6DF9161
-:10F94000BFD9AC1FD727A0BD16AAE4E513969D3FEB
-:10F9500021612D87111370DD35CBAF5C3686CA4B24
-:10F96000BCD117C7B3F14B98FE4C303C95A86D52F3
-:10F9700013D1333BBFACBFCA3B3DC960587FE91DC3
-:10F98000E55765C113A322D1D9CC97D6DBE56BA38C
-:10F99000C0DBCD028F6194718B5EF3F1AADD7ACD6D
-:10F9A0007726D76BFECAB6A588E7D27A88A09DBD18
-:10F9B0009EE12F6619DF5769D76F25AA7D5E9FD517
-:10F9C0007CEE04E30AB96FEEFE9DF27527C4666211
-:10F9D000FD12B18EFB2B9352ACAAF7F93BE79B6B60
-:10F9E000DE5F15F864E32CCC36CEE7859792001BDA
-:10F9F00067F4A73F8EBFDEAE274F15EFD0B0CDC066
-:10FA00007D359A9AB86FF6415D2445FBB91BC90F45
-:10FA100077BD801D621B35B46B120059F5995AE110
-:10FA20004EFBD3F07FCA8CFC6C7431D3C52FBF530F
-:10FA300070C0523F29078BFE9EC77E3907CE39A979
-:10FA4000A4DB83F0F7A9261C8142DBBCDE6F3E56A7
-:10FA50007000FD72DAD47CE861BCED4C8FA6987C16
-:10FA6000DDDBEC851493AF2DCD1AE57FC8E40DD313
-:10FA70007B98FC617A37DB2F62F9C6E608E5EF6C0C
-:10FA80001E4BE9EDCD067DBFAD7932E5D73547296F
-:10FA9000BFB6793AE5BBF1F9211BAF46F02B9BC706
-:10FAA000908A645C463FED6888303061257EB7C03F
-:10FAB0007FB33CE16919FD9ED37DE4DF0808FF8632
-:10FAC0009FD17730B63BA4C076C83DAF04CE8BC182
-:10FAD000F11545E6FE53B592E4C56FCACB7A20BF57
-:10FAE0008A2FC2D62DA672D582BA42E4775F847F70
-:10FAF0000F54AA4974C1048160C40D7C727B39958E
-:10FB0000A77CC3A90B15FB1B21F8A3352053BD35DA
-:10FB10003B787F4E3E1951BD4B6614036F50E5F59F
-:10FB2000927CBDAC1A752B7D6FD5641A77CD06DE3D
-:10FB3000DE57C9F8C6C2B7616510CD6367E8406992
-:10FB4000391BEFC7C1FD8306B3741DDBDAE0FA751C
-:10FB5000EF9AAD85332D7E24AFC2EDF360DDD6A9DB
-:10FB600015AC1E1BD6C0719535FEE4D672A28782F5
-:10FB7000F09DE5E3F007BD7CDE4A0324715D32CBE6
-:10FB8000CF2EE03004B58811ADB27C178A27A827A4
-:10FB900097F9B15D2B44B6EAE9F24AB39D616F571C
-:10FBA00069B68BB7EFA7764B583B48970F2B10F0F1
-:10FBB000C0485BBB61269CB04CA676717BBBA1A202
-:10FBC0009D39FF61DB3A24AB9C0DDDD02971B9B1C1
-:10FBD000D32517FF8C0021B7FBE3D249C4473BCFA5
-:10FBE0004B92B7F52423D5D93BEC723D2CE990F329
-:10FBF0000D6E9B1F3D8AB2CBE8B156D06B53537646
-:10FC00007AAD558F1D44FB44D9A1DAF069D269ADB4
-:10FC100057D0B1C94E47934E6B3541C7A8838E026A
-:10FC2000EF6B4D7ACDC84EAFB539E8B5D6A457CCF9
-:10FC3000DECEA4D7DA1CF45A6BD26B5A767A39E945
-:10FC4000316C5B8CD69D34DD2294FFACE8E1D40BA3
-:10FC5000CFC93A7D97D71BDA04D40FF52ADF275591
-:10FC6000A600F7035056D88BDD1A17F64913E0BAF1
-:10FC7000700BFE6AB1CBEF75F3FC9589C313D00E00
-:10FC80000F75DBE1FB27A03F6C9328BF2E7182CA62
-:10FC90001F97A33185FA4BF2F11DF8F24493B0811E
-:10FCA0008154AE6A175730BE285F2347E21639F0F9
-:10FCB00080892710E737A7C6FF005CFF2078270759
-:10FCC0009F129CD72B84CF24CD3B034EB6BFDCC004
-:10FCD000F635A582BF4B9B189CF0E9C309F57CBDA6
-:10FCE000E85E9F859DE482ECFD54AC916D7A765080
-:10FCF0008BDF96D79714DAF2672C2AB5F15559C3E2
-:10FD0000205BBEB4FE2C5B3E3CA3DA962F9E76AE03
-:10FD1000ADBFA229B5B6F20C7E11F96DCA4B4B6D81
-:10FD2000FC121F5A8BFBB64DA27C4762682DEEDB9E
-:10FD30007A2BFFFA55AAE165F8578BDCB4FE300A3E
-:10FD4000127E4C7CE56B1077A3BC16059217B1723E
-:10FD5000BF66C4C91FA019807684ACC528EF0ADB32
-:10FD6000D7A7AFA1A1C4F8F4EBEB54E8A57FE3E378
-:10FD7000F4DFDBBC9CFC62AEEF4A115F4FD7B1ED04
-:10FD80009284E7224C3FE23AEE62668E2F847C2119
-:10FD9000F887F133EA154D9584FC9E9E9C0D6CB559
-:10FDA000EB9B01717BBEFF62FB7C4E95BF3F2FF941
-:10FDB000ED0D7F6B2112574E017F115512E7D5A72C
-:10FDC00027FFE11976FC144F733BE4C4A1CF3F67D2
-:10FDD000FCB598EB0568B5B8FE065AB80FE5DE35F8
-:10FDE000FBB55816FC99FCB2AEAEDA6FB543206293
-:10FDF00099D7A0F4389457B2E5BF687C929C40F63E
-:10FE0000F15C36FF72B46372CC5FD07BEDF8FDBE5F
-:10FE10007FA5F9A7E9FC83D36A1FEE86B74CA3FD43
-:10FE20009A9977ECCB32DBC7B9BE89F964AB9E6493
-:10FE30003F952AE3B310F82388E7F77DA1E190CF3F
-:10FE4000F6875E9E7ED6FBB67BEBF87E26FE725E64
-:10FE50007208E253C471DCF2F2979244F7F132DC9B
-:10FE600081E5553295DFE00F6D45B8BEA9C46E50EF
-:10FE7000FB22BC6724F1BC18D44E6DEA972CF31416
-:10FE8000769139FF5CF6D1B296EBECEB194CABB541
-:10FE9000F2E39D2D2BA99CD91D2D2AD1EB8B621F3E
-:10FEA000E58473A3FA05B68FCCF30167FB7F15FBDE
-:10FEB000E8A0DAB0CC6E1FEDE17410E5CFB5ECA987
-:10FEC0003D9572D33EF207DC621FEFB05F2A997D49
-:10FED00084E7470161BF5426C95EF15526B9FD523A
-:10FEE00069DA33F6F5EA1A3440C7A4EDA31EFA37EF
-:10FEF0003E4EFFBDCD2BD7FAEE0B98F6511BB78FB8
-:10FF000018EE31CE44A9E47E0EC5B1BE8F76E55819
-:10FF1000DFFFD7D847D9E5B737FCAD85366E1FF57B
-:10FF200082BF69B9F0F72F6E1FED50E1FF33FB2858
-:10FF3000179FFCEFB68FD274FE74EC1CA75D63DADA
-:10FF4000119FB57D63DA27CC8EA954516E999D859A
-:10FF500076CCFB72BBF70E369F1B944E2F2E8AB7C2
-:10FF60000A795DAC46D7B968FDEE247FFF06D4E779
-:10FF70007D859EC5F601119FA74600ED9DC56A6C63
-:10FF800083CB720EA1043AB558E08B870766E7D998
-:10FF9000E72FF062E261B7AB40D0BBE99C289FD766
-:10FFA000A38407E8E4768CDAE9C5F449B1BEDD9BA9
-:10FFB000810F20BB5119AB27511FB0F64FBAFADAA7
-:10FFC000F0E2B5E185AD437C3C50A236BB91A7FE83
-:10FFD000D19A84FE7296ED40FEA5F3721DFDC26DAE
-:10FFE000938732F8FBC4565C83F198C1972F7E0348
-:10FFF000E31AFB74CEA4F8C696AAEA83B5AC5E7E7B
-:020000022000DC
-:1000000044BB74928EEB2A905F71157646EB2624E2
-:100010002604C4394E29C06F969F10EBA60176BB0B
-:100020005CD655D39F3428B7BCB01FE9A427B37D55
-:100030002EF97059E59AE4F3DA53934FA1F7E3EC04
-:100040001FEA8B02473FF9867D5D088225CFCA3FB4
-:10005000107CCC2C94CF653C0D6EF5EA8C3F5C1582
-:10006000B286F191F9A01520FFF9EB5448A1FFA544
-:10007000E8581C5DB0BDD1A505FDE87C3F0A975A44
-:10008000F613413797D7F0AC96F215ACDF13A3798E
-:10009000FC7D1F8DFD579D399FD542BEBAF3555B40
-:1000A000E9DC34C1F86910DFDFD03D825515BB347F
-:1000B000AB9E1EE1966CF7082CFB365DAD11F63455
-:1000C000C38F52211B68077C52FE503E267FE44DB1
-:1000D000B1DB09A74BAFF1E25EC5A9F2C7271DCF7F
-:1000E000A46BA65C2D1574ADF7A2DDBF223CB5C78D
-:1000F00073D44CBADE4A74F5578091CCD2FF04B762
-:1001000094357ED6B93F72DAEB4ABF9AE95B7AA2A0
-:100110005B91D3AEE5FDFA162BFA5F5179A91AADC2
-:10012000035ED1DF2AFDD638EACF13A813193E9417
-:10013000B6912971FE18D9CEAB50FC874F37489F36
-:10014000D279774D1A3E77997DBFA616F9ED76E103
-:10015000F4B86485DFB7D84D7078713CD4D31AD029
-:10016000B9A71AE0FEBD8CFDA3C36E5859569D3544
-:10017000CE40FDB4F6ABD3ECF09E72BB80AAFFDD9F
-:100180006C93454FA7DBA9F0778B3DB506F9DD42AF
-:10019000FF152ED823B1753811BE0C623ACB6351CE
-:1001A00009402BA6E3900FABB97DB743A2F36012D1
-:1001B000691DFFE3E74457B875EA47F6C6084F4A9A
-:1001C000C000AAAF9FDA39D2FB0378DCD220096CD9
-:1001D000F51F74BBA95C8528609CE2FBAF5C14A68C
-:1001E0007E0DF6A9260D87B3DF2BDCB107DDD84ED7
-:1001F000E3F060035AC7C772BF40D8CBDBBD3F7383
-:100200002AC571E5826F43333F5FEFCE8BB82C6810
-:100210003DB5B8AEF7D9981D55C4FF7EDCD7421B5B
-:10022000B787060A9A6D595248DFB7B4F42CE777BE
-:100230000939DF8CF69187EE55D8E47E9B8837DB51
-:100240002E81ED9EC5100F8FCF7A4BC8FD166FDC47
-:1002500047F7159E59E51B8AF12E8794888FE1A1F7
-:10026000E22AA330D6031E86B4D9E5ED74E33B5EE3
-:1002700076678FEFC8D5DE8CEBF8A47821DBAC1461
-:10028000F1303B41FB96D405249F25826F4AD8FE6E
-:1002900005F5D0C0382475ACFBE149B0F207FBD9B5
-:1002A0008F7E8AD27A3616D22B26D3B974E9EDEE38
-:1002B000A44CF2AEDD84EDC387141E6B0846606665
-:1002C0000DB12AB50F2BCF4D40511B2CEC33586389
-:1002D000BF7751B6C47E5FAAD4714F228CF65D08F9
-:1002E000FDAE967AE59F9C1E210FA3C7D99F3F3D87
-:1002F000B6A9865FB3B4AF9020DA9EA5BF0A0FB748
-:100300003B2AD6ADE77160F50178D5B25FDC2E19D6
-:1003100085B8186C6EDBBA14CFD9E2F51019C2F0AB
-:10032000DDBF01642B1F8FF2E4513F2E30E26732B4
-:10033000BC2DFFF6659D4F215DC7834D8F65D11F95
-:10034000A33C4C5E5C455C7F6C6B9BCAD30F155A1B
-:100350003FC24B20B98C8158178B2D7521FDE702C8
-:10036000C5A187EB9BF6617C754903447018C6579D
-:10037000C45FE1E99034885FE05098F1C7003E1512
-:1003800018807C81EBCF224E5F932F4A1BECF76DD8
-:10039000C2F5F67CB1B0FB8B9DF7B71CFD94E8FC71
-:1003A0001E94BE4406BCF707D3ECF76DC2D079FFAC
-:1003B0008F10BE0381480AF935EE18C7D1BF0AB1C4
-:1003C000CB3C0C9F8F7D7FCA2FCF64F57FB8A4B63E
-:1003D0000FE2658B379A4FF78A5AB3C79D65F0AB2A
-:1003E0006977E4A89FD6A3715B5CB3335D31A4F851
-:1003F000BA590C8E55410348AFC5AF20FDAE08F980
-:100400007DA6E4322FC6932E0F54537CD83ECCB336
-:10041000747978683F6BBC9822E277CD7C42E853D0
-:10042000E778D77BB81EFD3B18D7231E467A62615A
-:100430009CB72B5CFCE84C9DCE0B8D649676733C90
-:100440007E6E5FEAEA3FADF8670BB8467208705AF5
-:10045000FE85599E582BF267BC966D2790FF074189
-:100460003281F46F6A137EF7EE7A378B7A71BC773C
-:10047000D95D2FD606D67D27AB772BCE87D5336CAB
-:10048000F5A219F5EE14F5C036AE9131EE26133E05
-:10049000B0F617C9E86F8BE88FECC1EE7A7A467F29
-:1004A000F789FE0C5B3D2DA3DE83267CB671C13E31
-:1004B0006E77F959EE6482F4368FA7DF3F6412F14C
-:1004C000CB81219326CF62E35CF70B97D01157D2F3
-:1004D000BA6DF2D53E51AF05F9AA8AE2F05A1BF087
-:1004E0001EB0B8279C084CF5C62CDFBBF92A305546
-:1004F000CBFE7D96ADBEDAEA0363147DA7FA2D1F0D
-:10050000293CBE395E5087FEB89545B28877FE5BC0
-:10051000C250991EEBABDAF2AD615E3EDCFBB74434
-:100520001CEF14897B304C573E596591EFEEF13F3B
-:100530002FF8C579461AFE77134685157E9E37E15A
-:1005400037F3DE125E5EDDFAEE44BC5865DE03185A
-:10055000DCDAA785FC175FD8F9492DF6F9F17C7A2A
-:100560007E3C6FCE6F74AB54F7AF35BFFC163BFFCC
-:10057000F17C7A7E3C6FCEAFA635FFB4E6E7AC8760
-:10058000F79550CFAF1A725F18D79D55B890B27ECD
-:10059000C7B6BE9058CAF237F535ED6D9DF4FB48ED
-:1005A00030CEF28EE9BDDDAF30F8AD2FC6ADF2F33F
-:1005B0006018E216E7C16D61F473BEE6D1441C1DFC
-:1005C0008753F1DAF30331DF379D67BFFC13D7613F
-:1005D0000C53E4FB49879EEF655D5B5EC2D79315C4
-:1005E000C1886C5DD7CC38E867FAD690FE49685C64
-:1005F000FFECEB2BF451115BD7B83F8FEABB84BE05
-:10060000BAB599BF17D026EEC3268AAA093F6DE670
-:100610007DD8F8249B7EDB3F61D241F45F1D3FC44F
-:10062000DF8978C2CBD7BDE5CDD0CEDF3DF0D2BDDE
-:10063000EEA759BF3156612FB3F730FD29B3F7301C
-:10064000DDD31CA6F427CD3AA5BBD8B8983EDC1C58
-:1006500081181B7F67F3584AEF14FBABDB85DFF78C
-:10066000CB4532F92DB634334BD985FE5F2FA5F734
-:10067000346B6BD421E8FF0D53FEB834758E97F6BA
-:10068000AF9D897C06E763BFABA07BE2E38B545A46
-:100690007F414D29F9A3D3DF4DBC1E976A1BB0DD06
-:1006A000B96199D7F32613A1ECF5AEC17A63C32AD9
-:1006B000C10381B8122ACA5AEF7BC85F3501D19FA6
-:1006C000164B04B3F77723F6571D10FD15E9894043
-:1006D000F6FEE2D8DF708DE301C29DCBF2B2D75BAC
-:1006E0008EF5AA3431DFB2949C977DDC9BB05E61BD
-:1006F000611BDDDFB96006903DEA2AD2B790CF4298
-:10070000D44BF68D82CCF8BCB04F5B13D63B3F1672
-:1007100081416C7C3D140199F1B32BC0CAABF02E22
-:1007200039EB87A5E74D63E5AC5E12CBBF6429C703
-:10073000F62C1D375DB4CFB7979BE3B95AA1FBFEEA
-:10074000345E1A77B5D8F3053297CF075AAFA8436E
-:10075000B92F10E74FBFC63C1BD7B5044C7DC4EB87
-:10076000FB79F95366FD102F7F45E40B0BF9BC7D37
-:1007700093BC142F7CCFF5434B6655A5E73BE07B3C
-:1007800095C36659E677CFF7CE2D991548CF67C048
-:100790000DE387CDEA61DFD367B2DCFD2609EAAD60
-:1007A00082B62AD29F233D51B20F47F6AB31509EFD
-:1007B00095351CAEB7BDE52DCB54822B4EF73405D5
-:1007C0005C772FB0C3D57FA11DAEBB17DAE1EADF9E
-:1007D000D8335C4F78B95ECB051F1BDFB08EBFF9F5
-:1007E000DFEDE39FF17DFBF89BBF6F1FFF8C1B3F8D
-:1007F000F1F8292B5D365D631FBFEC5AFBF89BAE09
-:10080000B58F5F76DD271BFFD3B2C7CFF7C6FEE9F2
-:1008100015F6AE62B53B9B6236FB94D53B29EAF1F7
-:1008200073F46E7B3C66B34F593DD527EC5D5BBDE1
-:1008300068463D9F4FD8BBB6718D8C7143A2BF9463
-:100840006CED2F92D15F1F518FEEADA4EDF18CFEB8
-:10085000C2625CC3564FCBA837C084CF362ED8C7F0
-:100860000511077603C6814942DE59FDC533D83EDE
-:10087000BB1CF7A15109F7FB5A1F1879807D87C16E
-:10088000FCDDA382498B07E27A2E4D5A7C26AE7F8F
-:10089000AD0560DBB74DF2713FC2189F42A99607C4
-:1008A0004DE4BFF336955C6AB9F7BA59D4EB2E0F15
-:1008B00034957CC3527E9168DF2AEE0DD6F97E4BCB
-:1008C000F688D69FD5CFE237BBD8EC4F944351A4DE
-:1008D000C36070DF79C5D43156FDBCD9E7A2F96B8E
-:1008E00003C5B865D9E16A2DE7E3DE83E306F0BB13
-:1008F000697F349510BE359E9ADF6F0FCE96FE8AC3
-:1009000058DDE6A575DD2DD6F50277D38FCA191C03
-:10091000890132E0FD8695653DFB735A9AEDE70B40
-:10092000AA163570DF573A57AB46F1C8D5EEAEC9B7
-:10093000F2E46CE70FF5623E2D736BDBF0BE0E1C2C
-:10094000B0FB71198383F53EF215EE58BD2F9B1F46
-:10095000B7C56BB36F0A8A7BBEFF65DE93EA9E075D
-:10096000EB281BDD56FBC4F9C821AFCDDE2A289445
-:1009700069DF79A28A9F1B40BC84FC84DD782DADA1
-:10098000F55AC75FE518CF07530D5C077099427998
-:100990007157F07755FC456D5AB98EFE830E3A0FAC
-:1009A0000471DFCDECB7253C95F6E327C43D5835FF
-:1009B000DC3681FB1D057C9AD055629CD20D2AA4A1
-:1009C000FAB0B15DB1D5BE3156BAC5E95ED0FBAE65
-:1009D000E4C5F4DE5339A3BF9439FF3B7CDC5F7C74
-:1009E000973EF5B7E559E87B373A8B2DFD967EE0CB
-:1009F00086D4A8DCF5D3F5385CDD7C1B66FC8AF276
-:100A0000AF0BBE751B3FF4658BB730F58338079F7E
-:100A10003516C48F7EF99FD83CAE3EE8E2EF2E88B3
-:100A2000FB36E6F9D0D5C26F3A4BF85DEB211AC21E
-:100A3000C2B741A67B496FC3EF42A32CF47FD2E734
-:100A4000E670B5BAC8DF659EFB5ED5E6B2F9C3E6CF
-:100A50006CB0E767C3D462D45BB3D7BBC8BF76B50D
-:100A6000C34FFBA098EF1C685A8176BC796F7B96C8
-:100A7000062ABECBB3E0F17B6AF07ED47E1FBFBFF7
-:100A8000F726E31BDD226FF3024937DE037875F7A3
-:100A9000A8CBCE036C9F5C518AFAB600B2BEFBF6BF
-:100AA000DD563B7CBDC1EF841760598F70A83BA415
-:100AB000ACFEAD0E9F794ECCE9952BCEC38CBB38E6
-:100AC0002EF8A8DB0FF3E73CE187E1F117BDB57F16
-:100AD000BF97F60BBC9D6E949F46B569B224A7CF15
-:100AE000A73CAE98D19FCDD3B56742AA3FD8EAB50F
-:100AF000F65CEFD824207DD914453E32EB2D045608
-:100B00000FE572EFA5715BBD0A566F70EE7A5D421C
-:100B1000AFFE7CE7BD6EF447BEFDC0E14B502EE753
-:100B20003FA980978DDBB5330829DAC726DDB89F4A
-:100B30009BB75BC97A9E4B1103ACFFF93F0ED27A8B
-:100B4000396F97273985B59FF793578703C343D7E5
-:100B5000B263CFF6C775F701899FABC63B87E3BA8F
-:100B6000364F85EF44B3F4D7D7CFF9F0C81379D314
-:100B700091CED28E7D5752BFED97BB3C167D11F0C2
-:100B8000BBCC7ADC1F77BF941C92459F98E76047E7
-:100B9000EE97387C7B5C491FC2B7638B3BC6E0682D
-:100BA000DCF10EF1D5C41F3F14423C34EE516C7E93
-:100BB000E2C61D4ACA339CD2C31EBA8F6A04A41A65
-:100BC000C427D78F0B772F20FFF9C2F6D5EF282146
-:100BD0006C6FE76F8697480AF1FA82129982F9479B
-:100BE0007F14D219AADEECD81E42BCB27E67BAF3DB
-:100BF000F11CD8EEF7C6FE3F28CCEC0FE0981BF9AD
-:100C0000ABB17D151F6FF7D75E43FDD2E890A337D8
-:100C1000F19792CC7397F3FD8E73B01D7D4EC9BED4
-:100C20009CFFD089CD7136EE915D6F6D8E33F81BD0
-:100C3000FEFBDDCD37A21DF4B44F433DD0F8C07F9D
-:100C400086C0B26E5EEEE7F2D875FF8FEEBB8BC941
-:100C500047D71F3DB47E743DF5DA193A9B77D72309
-:100C6000FFA75867F5173D7521F90B163D36B15FA3
-:100C70004FEB27F26BD2FA2E99B87FAEEF61E3F417
-:100C800063D9BD2275D0E799DD0AF8189C6FBFE8DB
-:100C9000A17B528DECDBE26AA4D702D2CB985FC273
-:100CA000F0BC70E7CA7794E1D9F01DEF2FE3A503FC
-:100CB000606218467A7FE3EBE78FC6D445E72B8D59
-:100CC000708CF4AAB35DE32146D711B9E978023EEE
-:100CD0007463DC4AE3CE557CDC7646C750261DDFC4
-:100CE000C65FC665D2F17B0E3A9E80861FE2F92070
-:100CF000ECEE93F55CD83C3F5BF0D8377BB4B74C57
-:100D0000BDD01B9EE74A1CAE5ABFB1C28FF2B5EBF5
-:100D1000C1FBEE2AE2749EC210D3F5D08933F052A3
-:100D2000F7EBAE6357A27E3CF69447C3F57EDE53E5
-:100D30002F90BC753DF6BC5B27FB1B0212B337BA84
-:100D4000A0FBA703ED8F8512CF346E0BA63CA13418
-:100D5000BD16262F9DAC87E8FB61FA9EE472B03089
-:100D6000B96F9A94857E4FFBF97D6E48F625BC2CB1
-:100D7000D8F627379D835BE82A8D457A1E9E84DF4F
-:100D800073D1D39CBF86F33FC742D76D5C7E73C9D6
-:100D900069D7168F8A710D4E3A77B9F83EA131297D
-:100DA000BD908DEEE63A78BAE7AA4F38E55BCCBB4A
-:100DB00037F9EE7D3EA787AF1D7EDDC63726DE8E76
-:100DC0007C985DEF1FF24B028EA6C9A58333D741F5
-:100DD00015A2F1FEE569788FD0DB642C7D40A1F788
-:100DE0004E57B43F43FADBA92716E6B0B3FF26F40B
-:100DF000D3C23DFB86A33E3BB2FF09E2C7853B0F52
-:100E0000BB717FF3EC8E47DD9D5569FEC775C1FA56
-:100E1000BEC59187F70D27FD8DFD67A1CF71D17FED
-:100E2000E35E7BFF8D3BDFB1F53F3FDEEE26FF6AE1
-:100E30002FE3BCA91A97E37CDFEC7001BE9BF4663C
-:100E4000BB32399B1DF4825817BBE36A82352FA24F
-:100E50007F522974EBA8FF5A961A2FE0BB89F1E75D
-:100E60005DFCDD4AD578D1C3E43351E0D671DFDBD8
-:100E700012BC0C748B1E6F73E0532BD226E07E40A5
-:100E8000AB8B8EB6EEBF4CF80B0CD906FFA2E0E49C
-:100E90007EF8DE15EEE3747C27568D70FF7568D200
-:100EA00064BAF7A8C99A2FEBBACDFB43BF1DF2BFB6
-:100EB0004B9341B7F0D7C889979D8D2E3B1574DBB6
-:100EC0007E605D1D3F0F36E7BF6E006CC2C723D644
-:100ED000493CDE3F7E318F3334ED3B70DCFF72DA0C
-:100EE0007B60183AEA2352473A1FDFB0DC734EC7E3
-:100EF000F1822E533C738436012AC42808C38B71B7
-:100F0000B68371DFD54E6980A9374CC7E70DE2FC87
-:100F10000DC7287FEBE4BF50DC63515E74645E5FF5
-:100F2000CC178A771452B4CF13CF06809C5756D271
-:100F3000933E803AF588D59FE4814DB49F4177E692
-:100F4000C93E69BC98F17666BFEB7CE3255C8F7087
-:100F50009EFDF19D367CE4A8989F1FF0791B94EFCD
-:100F60006BE61DE3604DAD462CC1249A31C935189E
-:100F7000CFF7DB249C5F29B4535A061D94167A35AB
-:100F80004925F85E267F970C7F8193790EF84EC134
-:100F90008E77DADF3728FA4B3146C784D8E76C2DD5
-:100FA000B0C7237D3B8FEB996BF26433FE3966DD6E
-:100FB000B725A08170E02BE2CF9375CB415EECAA00
-:100FC0003C0B9F29810E1E5FE6D82F5FA82CA1F352
-:100FD000FD95E19EE3BA968BF8F05CE56D7DBD333F
-:100FE000B700C1CFFD609297C7791BA06B567EC436
-:100FF000589E1A6BDCA4617B4FC7857CA8209EE3BA
-:1010000094FA50AE589A877CC5E8B05AF061103A0D
-:101010004527C7C8FFB1D91D4B201FF6AB88493CF7
-:1010200098282A71BF9AA158F940CE9B51D253DC1F
-:10103000164C637C62899BD92AE8A2AAA0FAAB115C
-:101040009E4D82FE4EFEB4C7C19A765D40E43C22BE
-:101050001EEF67A37F47EF8CA945018A7F098C6E3D
-:10106000B906DF6F55A14943BD1A30E35BC47D0F5C
-:10107000735FED7CF7C5E3888F7589FD7B46BCB84F
-:10108000588FE97E5C16BBD9B91E3F98973DCE09B3
-:10109000C6668F4B34EDB48FCBFFE6FEB3C1DBF1F8
-:1010A0002C01A11914D7A90ABFC584691AF9DB8FCD
-:1010B000EE94F87B1B0E7E3ABA2B7F387F6C47A3E9
-:1010C000F7CBF3C47769E7BE7D685FB584C0282895
-:1010D00024FDA72B0CFF2BA4915E89A50B76BFF3F3
-:1010E0009B27D18FBF57017CD7ED289B6307CE5339
-:1010F000350A906879B0C646E78F3BAFCC734C2E6B
-:101100007FD76AA6FC05A8DDF19D12DD1753E0EC40
-:101110003BF1BDABC6832E48B2F2E3C0FB3DBE89B6
-:10112000DB0D737EF1680D9304D820E0C1F5CBBAD6
-:10113000CEF499EC07DDC22761735D881B1DF8DED4
-:1011400073BDC04FDF68A1AD9E39BFB7664D3E4845
-:10115000FE9F187FFFB9DFF4525BFF20FC233AFBB0
-:10116000877C99E16790636EA075259A9F223B88E2
-:10117000EDA771FF91942208B7D39FB2708F44EB13
-:10118000D9D56C3DC3F7D8AE4E3AF6A38E782A1364
-:10119000FF4EBE9503C28E0C4020079E23A9D1743A
-:1011A0003E4B7277ED2F14B2C7AE7D484A523C7564
-:1011B000E799F9407857C82FF51A34DDC1569834AD
-:1011C0007F3BF0E709DBF1EED3ED78CFABB4E3374B
-:1011D00018B1E3D189E7FCB1836CF5E72B0D6E62A2
-:1011E0003E81EF4AF60FF1CDF424CD63219B474AAF
-:1011F000CFC4E7DCBDEB56A0BFA4573C3AF07796CE
-:10120000037F2760EF3E5E0A516FB125FE534D917B
-:101210005C39E5D0C45399D63181BE4582E4A70E2E
-:101220008B4EA47ADEAED4DBCE85AA3A427268C673
-:1012300029E775AFABAFC249965E77E981C3B320AA
-:10124000B7DCB5377B23F52E3C1F8748FD103C2FBC
-:10125000D728DD84F547F4B4DE1A349E0B221AA693
-:10126000B7887393A355FC5DA4F6D47BC568FFDDF6
-:10127000527DEC12B4FB1BAF8228EAFF6490AFBF33
-:10128000BB455A17E471D637456530D05FB0574932
-:101290004AE887D28C5F5C8076DB5E974EEB9F7668
-:1012A000EC37FF46E5A3343CC72891DB46E2B8ACF7
-:1012B0003EF9FB8FEE7D35F45D8B7DD4B5E7B661ED
-:1012C000B83E6D94616EB67D407D808FDF55F99795
-:1012D0006264CB05DE63B42F5FD969F7B3B9777366
-:1012E0003FDCC23D97923D7A60367F8FF3B123FC9D
-:1012F0005EEA2465C657BFC4F2E3FE53BC6304C66E
-:101300009499C53C9403E999F0313C333CAE17F114
-:101310009B8D7F95297E73DCF920A1BC8EFB23D0A9
-:101320003DD4D14DB369BD7A3234E920A6757B2511
-:10133000F21F351EE1EBDB980EBB9FE89C3AA61727
-:1013400058FF357BB97FABA6939F0F9CF3A2BDDE00
-:10135000B84E7BFEBC5EF8775940AC5B21283E9DC1
-:10136000F8DCBD2E6355809FA7D1BDB2889A7DFF62
-:10137000D519E47618C307CDFFE831882C63F3381C
-:101380005A5F3A01EF291D7D8F9F371CFD50999CB4
-:101390006D7FB539C0F965A39B9F1F6F9C1D482EBB
-:1013A00065F3D83F7BDE40DC57FDE3DF6303B59E8A
-:1013B000EC12A622645A138D7C188BF2D1C2EFBBBB
-:1013C000415B49B6F7934DB930E5C4948F92D9FE8D
-:1013D0005836BFE8A020DFFFD5CEAE94307EBBEB01
-:1013E0006989CE98BA9631B87AC0631C96F5477869
-:1013F0001AF7BC4B7E0AEFDEECFEEEA703219A7FC4
-:10140000D7B2F8D2F318BEBEC7843B8EF2E06E2B83
-:10141000CFD67F1CD693FF6A7B80F3739797EFC379
-:10142000416D2B991A44399978F10A06E75D4CFE13
-:1014300070FDDEE88A10DCF10540EFFF81B85F58EF
-:1014400076096CB9C9B25F3B18987008E97D28C06D
-:10145000E38FFAC42212C21DF9E8FD10F67FF403EF
-:101460000FD1AF54F88BCC764703E21C2E68FC8674
-:10147000F8656E1129C5482C14A91F0530620FC3E9
-:10148000B7457FA7E916A7710A634C0732780A03AC
-:10149000323F0F63FB34DC7F3482F913A7FD8A29C6
-:1014A0007F78E94DB5C4DD4B7BA55490E9CFD1DE03
-:1014B000400AFD328573657C8387D9A35EDE5F8732
-:1014C000DD6E450D8CFA177500509EEF8F4C7D6CCC
-:1014D000EAF19602AEFF5AD6A9A41F37A99D3EF4A1
-:1014E0004B971B7AADCAC62D54758AB7183097CB67
-:1014F0007BDEE07B0ABAEDA2F3001EF948C9EA1FC1
-:10150000393368E22BF60FC4D7F083C7F6A37915F9
-:10151000F1411FA4F72461F78C7B5BBC8B28EE198B
-:101520003476DF23B0EBA38D3E61C740DBEFF1DC07
-:10153000FE89BFAA747FA05BFFCC9E44EB2928558F
-:10154000CF207F9DF72BB13D10FA87EDF6082FE7EE
-:101550003C174B201C4E7D3316985E927AD73B4E3B
-:101560003A3323BC3B5FC69032EA2093334B7BA7D0
-:101570009EEA1714EBACD05327607CBF0BF5343FC9
-:10158000552F8E3CE3B1F08FA9A7D2FC9424BC3A2E
-:10159000C791C0DB9DD706A37E794E413FCAD109D2
-:1015A000FCEFFCA4841C15BC97BC18F961FDDE8B14
-:1015B0007CC8F7BB0E4EF4A2585D1BE6F7CED47D77
-:1015C000D3E220D8C77AAEEC02AF1EA8447CC88410
-:1015D00007456379CBF8C7DB2471EF52CF9F96E5BF
-:1015E0007D6C33BD36CCEF95ED3A38289FEF4753ED
-:1015F00044F76EBE17FE0B532E4C7E77F2B7290FC1
-:1016000009D64AB6D8118AD42EF68F763F4242D8F0
-:101610001109F3FD997809D9878B847D98080C5DB1
-:101620008D7FE6A02555ABE1B9C7A2E0208AAF5E69
-:10163000D497E3CF890F336DFC80D98B9638F84669
-:10164000F518F9C71A3F70DBBE9BF8CD851713BF9D
-:10165000E7227EA58F8FDF73829CCE4E3C7FD2F92E
-:10166000975D3B36EB7DBE7F95F99F07B1273BC960
-:101670001FCBEF9398FC66EA8F9AEB5A13797A5A4C
-:101680005F98F7414CBD63EA97731ADA9EC9CBA203
-:101690003F9C7A23E2D2BEBB86E12FF2B300BD7736
-:1016A000E2D423EFE12F25E477BB3BC8E07DE4D90A
-:1016B0003765F49B3CF6533677561ED957C7FD82E3
-:1016C0001DA776DE65DAADA6BDEAAC67DAABE6BA91
-:1016D000639E37FD3A187B00C797F630790A617C24
-:1016E0002CDF271F0CC41EC2EF790C663FC60256C2
-:1016F000A6CAF97ED62EAFB9E433CF217FED299566
-:10170000D6BF385BFF8648997098E3D707C5BB0200
-:101710008CEBD0AE29AB013ED842FE6E40D970882A
-:10172000E1FA8CD74B719EBF1276D97362BD31D36B
-:101730008381E80184DFA542DC53FDF1E136FD8BB6
-:10174000BF0E1AFBB13FEF6483E6D15F8308DAFB7B
-:10175000FDD57629C2E0286CD0A56E678FB9AEB3EF
-:10176000FEFA4FD1E9DD8FFE78A700EBA37D9485CB
-:101770003E7F0EF2B8A605DECE67D1846F9CD234D0
-:1017800039D4C3F97AFA3D8488F073D9E3408E3EA8
-:10179000F5C2003CFF7CE507EF06F15CEBBFD463CC
-:1017A0004184F3F525BF0FE27D885796F0FDC7957C
-:1017B0000E3BE784C0DFB450F44890A5DF69FEA873
-:1017C000C6F60EC9627E3E737552C14D6937BFCFF2
-:1017D000DF9147BE3D33BFA0BD8F2D6FF2E9020FF1
-:1017E0008FDB72CEBF2AC4E368AEDEB9C5DD5FC74A
-:1017F000F163FF8DE3BF2EECB8D77707C9FF61C255
-:10180000336BE74837E2E1BFF67AC4B97F878BE3F1
-:10181000DF9882E77331410A279CCF3E9D47FD5DEB
-:1018200075BB4276C74C36D662C6DFB1BD57D33ED4
-:10183000DC398FAB5ED127F563F4BB6A9544F62A99
-:10184000D65FC2F821B678259DE339E73933EE88B3
-:101850001F11768533CE64CE5E7EFE5E0FFAEAF10E
-:10186000E559E24EF65E4CE76E737AD9F7948784B9
-:101870003D5103E760DCFC09A85A5BA5F7BEEF7990
-:10188000BD192888ECCD662FA5479A359E0AFD39EB
-:101890007FCFBE6789CFD48E1A94FB5D075FCDFBE7
-:1018A000969ED6E35FDEF2EE3377B3FC28E07E1E31
-:1018B000D3DF3E43E0FD02A1CFE7087B61D4073DC3
-:1018C000EBF319888FE199F09A7A7C06FEBD410B03
-:1018D0001E4CBDEEC4C7F18383F3903FEA42CEF3C2
-:1018E000E64F86975CED1628D9E3194D393A12E494
-:1018F0007C5DBFEDD215A56CFCC453AF9DD1C9F57D
-:10190000C421D413269F0234B9518E9DFC68F2493C
-:1019100037DFEDBD99F064F20793ABB038E70CE325
-:10192000FED0C97FBDC53775B93ACF40BDE0E4B33D
-:101930002EC7BD6833BD2CC4FDEFF5BA3109F7AB36
-:101940006CB959C1CF03B93E7A5D6D7BF64694D729
-:101950006D5C5E163CFED04F500FCDFBF1ED21D4F7
-:10196000436FA86DC5385EC3F6E5213C577F5D8D9A
-:1019700087B0FD1B49256BFCE3CE9064BEA7618B4D
-:101980009380D6F82528C7FFD8EED2F01CAC71871B
-:10199000879FBBEFE67863797EDEBE3B7B9CC4BC51
-:1019A0001FDD5EACF3B85B7BBCC43617F92FD0BF2C
-:1019B00086C3E43A2FEE3E7F6EEFF93CBD71B788E7
-:1019C000B3D97D71D67809332EC1C9C79B1CFCCB16
-:1019D000F0437EBF38838BDCEDE29C3C71FF9DC3FE
-:1019E0000F33F88E6CFB5548AAB2FAE3F979FCF193
-:1019F000F6EFFED02BE7E6DF2EC1EF697B229935AB
-:101A00007EA2C1950AE1BEAA618B8BF6810D0F29DA
-:101A1000F45E1DFCD143EBF9FC877EF68773197CDD
-:101A2000F31F71154DE1D3A03809935EDD712C824F
-:101A30003EF31EFD193F5FD6453C8BA0D3FC47F615
-:101A4000B9312EC789CF89EDFBDC9D8E3808A257AE
-:101A5000FBE149749FF0FEF7DDB8CEBEF1B404FDA2
-:101A6000CA33DBCFDDF2B310EA0BC413C50108BAE9
-:101A7000E58E5B4A5DF2D3D1548FFC76BDD17109FE
-:101A8000CAE218E2F7877FCAE098FB9287E2A7E6EE
-:101A90003E7C1DC519BDA63671BEBF677931AEBF8C
-:101AA000735DF1628D52FE7DEEE6EB891FE73C7FB0
-:101AB0007DB1B88F54C2FD3DF1129CE7559BBE49E4
-:101AC000F39C0D31E2C7B9F72851F4B39C5061F291
-:101AD0002359E466683E979BD7B67AF0311D784D5E
-:101AE000F839E3BF53C4DF8B749E57F177634E8898
-:101AF000FDF73F43DDE78D5EEB7EAC71DBCA0EA4E4
-:101B0000D39B038C7E1AC513A87181377A7F5D79C8
-:101B1000FEC27E42BFD17B37A61D3411BF63FD0ECE
-:101B200017BD7B6369677BB76691189FC1ED9746C8
-:101B3000B0B438BB1FF49BF9921907CFE36F4C3E4A
-:101B4000CBA507B6F17896F70E713D83713954DE57
-:101B5000E14AF5B3C5E3786CEFA2A4E34C5C42CE56
-:101B6000EDE50C4E8A97E9C6EFD312FD3D08935F71
-:101B700066AFF7D8E3F3BAF9C7F96E8F3D7E668E8C
-:101B8000C32E33D38CF53FDF715EB7E9D4E2671A19
-:101B90005C498A7F6AF8A387F6270D0FB9A2889758
-:101BA000B7763EF3876F31BE7FABDD9463BBDE75E6
-:101BB000CAF1DC5D63209B1CBF158840563966DF87
-:101BC000B3CA71207DAEA1C367AF77E7E4D0BB5F36
-:101BD00075E093D90DF91847FCE603F30792BFC2ED
-:101BE000815F53DF3AF5E8AB219DF09C19EFC7D731
-:101BF000FD743C26C7A3C99FF31E5C40E374F3B198
-:101C0000C9A7261FE7881B73E2D3599E8FBEB33145
-:101C1000997E91782D54E2DF694AB881BFF726FB9F
-:101C200023C8BFBD9D77FE36BFDC7CFF6D04DF1788
-:101C3000F2F3CE4840C3BF5881F7E5946CE7EC91CE
-:101C4000897256FBFF07F9DC4E42B72CA68FE7736B
-:101C5000FCB52851E1C86BA77B0C74B68A7016845A
-:101C600048CE5C224E85F54CF7D12379F2BB3AEB96
-:101C7000E3AEB5072E52D13F3B4ABE6E30CBEF5A92
-:101C8000FBE2452AA377E43CF9D1412CBF7BED1F51
-:101C900079F90879948BB1EA8EF84B17D5B1FC42EB
-:101CA00031EF85A69FA4658CCD4FA2CA87EFC0F304
-:101CB0001CF5A7FCEF11AD6672EFAD4E9F33E779CF
-:101CC00020EE63F93C374B597E45F9EF57E026F299
-:101CD00057FED8867CC257AD8E783EA279297E67A2
-:101CE000D11317521CE9E3F9DC1F7DF6A3E7D1DF1E
-:101CF00075FC0CE1B83FBF6F6E385A5CBC9F23BBCC
-:101D0000CE9E88783E7B20FAD4D2F4A85675FAEE9F
-:101D100063688F73BB3F8CF75B12056EEAE771C196
-:101D200067A79A9A712F4A1EE70B255F6E7A84A5E2
-:101D30004F0B7EF88F7CCD5C8768DF7DF4A97E5BDE
-:101D4000F9BB31C7CE407A2BCAF13FA3BD79ECDB9A
-:101D500079F4F7475EF273BCBDE4E778BB3C7F8D56
-:101D6000EB2CF6BDDA7BC675C8F42F493BAFC774C0
-:101D70008B16FB25A707A4B0DF6F5DA9F07E034D8E
-:101D8000417C374E32B81D2E31669AC1F0913040F9
-:101D9000770F4611B6C77F284AF5B1148D1FB48D51
-:101DA0000F656CDD64727EF9384E2F865B5A475F93
-:101DB00018CBF3267CD39383129D3AC1F327846713
-:101DC000A4273900F753DF626615E77BFBBEBECB65
-:101DD000CFCF37BBB0FDF074FC40E3DF64DACF3621
-:101DE000E21C58FED12320FE5E217F5FC7F47B8C6E
-:101DF000FBF5B5E4FF1EBD673E8F3311FE2EF33CAD
-:101E0000BFE6003F9F73FAB7CE8335A44FC739F4BE
-:101E1000E8797BBE4AFAB5B7F3B97F987AB5144A28
-:101E20004FF37CEEA3FC53389FFB1F7622B26E006B
-:101E3000800000001F8B080000000000000BB55A56
-:101E4000097454559AFE5FBDDA92AA54AA2A45082D
-:101E500004E34B0224210B45122004D42220D0316C
-:101E60004A801681F64881B298AD98B4DB699D43EB
-:101E70008520D2DAA319756CCE69BAE785D611250B
-:101E8000E92924D1E05432C52204254E9045A01DF5
-:101E90003BED7423DA64313D824BF761FEFFDEFBDC
-:101EA000A82541E93E67C8E1DCBAEFDD77DF7FBFF7
-:101EB000FFFBB77BDFBA4409600CD03F1D2403D47D
-:101EC0009BF19702307C3C2311F200F47A00D9098F
-:101ED00060546428C1F62AFDBB0DA06D338E338596
-:101EE000FB6F252A6C9EFC53F6FBC1462DAC868207
-:101EF0008879ED7CDEDB652B4031CE7F1154533A7F
-:101F0000C0B4BEEC9FCFC1BEA1DB002ABD979EA08E
-:101F1000FB6775AA1F459B71ECD74521BCB435CE34
-:101F2000560053F195293A50CC6C5EB88AFFE39481
-:101F30007850B2C37D4BB633AA2FC7DB764122FE61
-:101F4000F07B7A53508E227E0B12DCE3A3E679DB22
-:101F5000B6A89BE42EB2AFAF20B9134B32A2E681F4
-:101F6000E3FA4FFAB09F8D7F573300A643656208AE
-:101F7000E52F844A8F84F2BA3F027708E59F718A81
-:101F80008FD39E7387FCB217712CF928FA7A2944F3
-:101F9000F4719EC73EFAC27138429EE9F604D70535
-:101FA0000BFE180FE3AFCAA3E2E80E114EA7643789
-:101FB000AA01EA8FE12017B69F810A88DB342848FE
-:101FC0000486AB0C2AF6DF04EF0B73B0BDB279C800
-:101FD000717852184F87271ACFA445D1788EA98CD3
-:101FE000C673EC8A68DCC679A3714ADD3825EAFE3F
-:101FF0004D9B0AA3FA373F561A353EDD5F16D5CF03
-:10200000DC5E1E357E52D3D2A87ED68E5551E37348
-:10201000D4B551F7737757DD90FEF303F551E362C2
-:10202000F53FB5E32751F396CAF7CA9011E6811F31
-:10203000FF880785A462D23FEA210423F53FD3E558
-:1020400027C6FFCDFA7F98F49F1BA17FF9DE44AF2E
-:10205000356C6FB1ADA6D79FD05AC7905E714E1444
-:10206000EE0AE919AF0D1AACDB256C1DC89D7BF19A
-:10207000FA63667EFD5181CF95B83495D6EF081E80
-:10208000FD5AC216D5C2ECD0FFB1456D44DE3C2AE4
-:102090002B0DC4AB17E54A09509E54549D2E13795D
-:1020A000A4838D01E4F7B33ADDEACA08F99EB3735D
-:1020B000BFF29C5DC7DA5F18D156F1BDA916F09B3F
-:1020C0000BD973B436FAE7015CB72D8981822F2CC6
-:1020D000DF3E7F0EDE77F4652B0E0033F56F01389F
-:1020E0001FCFE53D1FCFE55C65521AFBC87FC8EAEC
-:1020F0002492A7D9EEDD69C7F79C979E30E09BC17B
-:10210000E0F21BC8EE52CDE0B7E1FB1A0DB0BA12F7
-:10211000FB0E7049F5D826C24E3BE18B62285791E1
-:102120001487AA7213FBF0FAFB24D138B231B70E30
-:102130006600ACD4FCE1C61CE60F87718DBDA450CF
-:10214000BD9208D80E3F90C9AE9FBB0FAD10EDE910
-:102150009C91E3A1E17051F8C9CF379B597B69B3DA
-:102160003DCA6F6E6C7E2141C179CE65C3A2400429
-:102170007E5D84DF746A6586DF80FAC7648267707B
-:10218000DDB79349689FD4BBCD8A439EDAF10F95A2
-:10219000807A30B62DF1A34E60A55161E3B5797C0C
-:1021A000C1B940381063E9FA3D1FC22692EF9E6F15
-:1021B000B18D785F8FDDC0DED743EFC376393676D9
-:1021C000C46D39EAC541EDD1390BC82EF07A48C249
-:1021D000FEE26E30903D2CF1A61B489E93E03EDD62
-:1021E0008EF29CB52BECF91F42A581E43A735F6D2A
-:1021F000028DBB369F360F0AEBC078F2A1C36F4841
-:1022000046BF35748BE4DEA5B0F799E97AE5BDA940
-:102210004F5A95F0FBCE80B7FF34EA7B29B8D9BC82
-:10222000DAFC6879517EF18D8DD5BF4BCA207FA82D
-:102230000333F9C34E13F3878355575A5FC2FBAB81
-:1022400053FB6E32E273E7ABBE9D4CB8ACDC21832E
-:1022500082FAFF24C1FB07FBF4301EE71EF873026D
-:10226000DD5F65525F7909ED00F698DCAF003DB7A0
-:10227000873DA78D1BB0CFFD8C78072508D4ACEB2C
-:10228000DBA786FFBCD773C612CF347E3D28F85536
-:10229000FF5AD658E2537DC2357EF1FE2B996389F1
-:1022A0005F3324CECBD879BB905F4A16AE1B79A59D
-:1022B00020AFBABE2A4B223FB1EFB8B388E4D48333
-:1022C000F76AE4BAF6BDBF2A97EEC359D70DC94BDA
-:1022D000B6E94739EF012E678FB08F15C1A422D21E
-:1022E0003BDA9DC581E356FDC76BFDBF257C3AF700
-:1022F000BCF2388D29BE313C34FFB4379EC7231061
-:1023000071CE2D70C13897AD47510721DE4DF9C20E
-:10231000F5FCD65EF20BC8AB2B3A747C99E4AF2A7D
-:1023200081FC8205DC0AB5E865DE9B8D7A6C3CA0F9
-:1023300083A7B16B23A7A6F99F12ECCB3AEE7FB02F
-:102340006F4EC13822FCD324C7BF2EDACAECC76354
-:102350005D3383B9442657F1E1AA0A7A2FF4A21F0C
-:1023600047592BF18FE2C16CD874280EE59CB1035C
-:10237000F3031C37F32CBFAFF9F55921DD1A6322A3
-:102380008DFBD917B28D208A8E03B30F977F4AF346
-:10239000CE8688E746890FB31C7F5F7C98EFE0FE0E
-:1023A0002190CDFD7B2014AFFAD3D9B44595F9C85F
-:1023B00017278F1F2D8839D9B1511AC836A31F5E30
-:1023C000E468DEBE7D02D26122C785FA8DF45B2906
-:1023D000623CBE96371E9EC2FC21FC05A522BCECC9
-:1023E00042E618798AD1EE78307647E59DA123DF61
-:1023F000D8FA701DAD4EE5BF485F4398D7905F880F
-:10240000D3F7191DA3ACEF4DF2AFC8FFE71C3A2676
-:10241000AFB943F2A8F87EB3E20109D71067B74F0E
-:1024200093A5F0F832078F4BB547CEA719515FFD42
-:10243000BAE3B63C9CBFA6FD0D1B2E1F7E6CF3AE0F
-:1024400073E03CD5E73E9841A10B199E5699403860
-:102450006524923DE5EBC1AF2F1C29876F072E063F
-:10246000295FB72389B5391D125B9F2FC4D739D097
-:10247000D1E88CF41BD79EFBCFCEF1A4B73D6360AF
-:1024800005F9E3FC60D106E231C962405DBCFE554E
-:102490002E9BEF09473ACFAFF5A0A7EB00AA6E2914
-:1024A0000EDA63C0E770DE81AF64364E9B37BF63E0
-:1024B000AE6C471EE5859A0E525E18173429A4E7C4
-:1024C000B89781E3128C637ED1D7B510287F1D7435
-:1024D000805BC2FBADF1431F132F863A4DCA2E8994
-:1024E000F06B0227CEDF6AE4F133070DE10D6BF8E4
-:1024F000BAF6BEB8E0CF81FC15F2C3A3D27D7D133E
-:10250000DC628DC43D81C9FF4B07E7576B7C486790
-:1025100025BF8F9CDCC5E40ACB09ECBD9A9C39AC85
-:102520000E68350E5D78DCC5E4B2131F7280CB09EE
-:10253000C12CE5157ADEEE61EB88B32B6EBF345209
-:102540002E5F01E6C56877CF6E816B764E76EF8B96
-:102550000FF7CD6813AD1920FCC229968784FBE8DC
-:10256000B04AC2CFBFF1CF67B66F9DC3EA23BF8C1D
-:102570007CB0609BE0A47572FBC2B2C933A690E345
-:10258000E0469C2C667EFFDA78E4BB95FA563ECE98
-:102590009D68B7944BCC6E80ECA64EF89987A4D07A
-:1025A00085DB50B55F860E1628284BCDD1B7196F45
-:1025B000AB75C197F2F17E59BC3748FEF7AD8F7409
-:1025C00060C3F57FFE5A9C5A817864EF6F4EF658CF
-:1025D00047CEF7D4D92DCFA792BEF74B0A228D79DB
-:1025E000E1501AC95717FCD4E8C17661C7EF8D14C2
-:1025F0009F5639BD47C80E4A3A1AE6117EB3A0A9C4
-:10260000D16E657ED14B3C0DA470FF317C6AF2AE79
-:102610008608BC2F3978DE0243DE9BC96E82C23E3B
-:10262000BB28FFC1B65DE461ED0756662AF9E1E714
-:10263000FC70301570CE2D70389570D6AE0FAAFA9A
-:1026400045C4A7DC33E6D59E08BE5D10F67E41BCCE
-:10265000EF1F9DDE8F0887EA039F186DB82EDF1FDE
-:102660000269149F0298A7D9BFC32FFA62ECC6A7CC
-:102670001F32D278DF45607E04F5BA3511F5B4E734
-:102680004CC7943556263F24E2BADBCF9998DF6CCD
-:102690004FE7F6D770FA7201F9ADCB9DD537135ECF
-:1026A000EF3B0C1ACFCBE2C99EF602F3639A3DE6EC
-:1026B000913DA2E879C4F362EAE7B0F95A8DBDE52D
-:1026C000CCFEDA7540F6873C67BC479EDB29FFC825
-:1026D000B323EFD9F359CC9E5B7B31E061DF8F7E72
-:1026E0007C12EB972DA37E6BEF7C3BB3671D425BA7
-:1026F0004876193AC8E609604C23D549501999A77C
-:1027000096396C4C5ECD3F563AB8FF0F642B896EFC
-:102710005C8F4596A3EC20225EF2BE88A72B9F37E4
-:10272000FCF4C509644D222E88BCAC4BE4C1E02DFD
-:1027300062FEFEC72296D5BF53BAB805D75BDF232A
-:1027400073FF2F787250E4C98737A7B03EC50B05D9
-:10275000F5341D5B0FFAD3199E4DF3D0C6A064511A
-:10276000D3216A4B2B03F3107198B3A2F790819B8E
-:10277000732EF1AFEDE00F72F5C4F77326884311A5
-:10278000DBBE19FAF875C4E1912EC47F94B884CBEE
-:1027900061FC4304181FAFC79B41A9EFAED96E4C33
-:1027A000F99F1FFB037D1CDA0F1103F1C87B7ECC60
-:1027B0004FFD2850BBD333D58938FE36C93BD58968
-:1027C000380E9EF826997C7AFBA94F6CE4EFDB8CDF
-:1027D0009E5CE2595B06D60BA3F0738293F3A7D8F5
-:1027E000149DA76BED5227E7FF643F3C43FCA96BA8
-:1027F00093ED2AEABBBF4DF618318FBAE0F126EB14
-:1028000011D28BE05F3E9BE2BBA87FD771D8611DE0
-:10281000E52F1867D6BF6888AA4B6BC4BE4616F46E
-:102820006D4B459C7C2F4BACAEDD18938FD450FE86
-:102830005240F545B391D653F572CC3C94C714D0B1
-:10284000B8EFAE73973AC53E472664521E833C628A
-:10285000F5F4D069D9BD8B62A01EBA4DC8DF3D3AF0
-:102860008E13FA4D668F5A3E637279E691DDCFD3AF
-:10287000E28AA85B875A2595D9CF6EF4F3D82FBD8D
-:10288000A83403C7E154CA0C5A0FE765A99E8F2FDD
-:102890000DA633FB2BF1603D8FEB5E8FF5BC4AEB51
-:1028A000D6F23CD5C0D68FE197E579B3406DB4E15F
-:1028B000B80DBB25B6EF53BDDB1095E7F9043E35E7
-:1028C0003B4E1CA172B23610735FE0E38BC1E70D83
-:1028D000FA316B244E8F3A45BE97066991F91E7402
-:1028E0003B47AD0B347CB43CFB4F069E5F7C20E63F
-:1028F000D7C6FD8B93D7E7751E60FB4735AAACAAF8
-:102900003C1FB4AE41BEDC2FF872BFE08B0FF8B8AD
-:10291000DADD921AA278F533AE7733FE112EEB0290
-:102920006B16A42A23795525F0D8D86260F92FC0F8
-:102930002623D9E7C69D31E3042E5531B8D479A5B5
-:1029400018F9783EFEB7CA576DE0FB35D5C82FBFE2
-:10295000F2FF276FACFEFE5DD3DF149812A5BF45D2
-:102960004937A4BFD83C79EF9129167A7EB83B83CA
-:10297000ED4368BC899D6781C8B317EEE0F9687FB5
-:10298000C73C4B3ED553C7F56E09E729EAF95F5BB3
-:102990003EE251D82943054E31182C7AC68FEBDC24
-:1029A000D73D719982F1A1B047CFE24B514FA14A77
-:1029B000754D614FA1253381194F12D50B380F8BFF
-:1029C000CF83C7279ECC233FDB3DBF98606F385E27
-:1029D00068A13C621FF07D0DA9A738A92F22DE74E3
-:1029E0003BF9BEC6B694FF7996F2FC857B0D6ECAA4
-:1029F00047161A86DE9FEDA2F7EBDD0DD8AFE95939
-:102A0000BB258EF4FE9AE4A674FC486FBDEB47A488
-:102A1000DFA0C16E62F23E7C90EEFB5B24F7241CCB
-:102A2000EFEBBC3DB715FB85CD456E82597B5FA1B1
-:102A30004379A182F2C5711656C72FBCC9C0E2EE18
-:102A4000A5F1965F53BE54E5695E40FEF8D2DBFB0C
-:102A50008CE40F065B2548C1851C4939F41B3FAE49
-:102A6000F3D29B278C9494CF6B3B61ECFB8E7CA2C2
-:102A70005F9521C4EAF72623D541B5CD5ABFCF488B
-:102A80007AAA14F955DDCBBF67FD2AAA13F07D554C
-:102A90003B6555C19F873ADF3212DE752D128C4D92
-:102AA0008FB8FFB2C4EE6BBC5F0B9C076B857FAA2F
-:102AB00016FB90D5B40F89D7613BF7371AEF1FD8B3
-:102AC000BDE40885EF754DD17EE841C1F30D549703
-:102AD000B2FADB6B24BD6ED811334EF0FCC1EFE1CE
-:102AE000B93549F8F31CC8219E5F9ECBE3C9E513B5
-:102AF000F1963C5CD7E563B21BE03BF9CEE2EF71A7
-:102B0000912F0C87742C9E69E3063AFECCE28DEF80
-:102B1000F8B091F2DB05C12F983E2A8207E613DE5A
-:102B20007782B786F0BB3368B193FD57F4717F505D
-:102B30001E34A9B40F7E2704B6929E07BB5EDDEA61
-:102B400024DEFC1BE70D087FB741E0BA41E0BA0183
-:102B50001D7E12BAD8AABC032F61BA0FE5C0FD5082
-:102B60007940F8A19DD13863E4B98FF4551734C189
-:102B7000D378FF0EE18FEE68E1FE28364ED6897DD0
-:102B800080C171B98BD97E2BD6BB94C7D5B444E331
-:102B90005F27F605EA62E2F0CD497CDFEEFBEAFF53
-:102BA000583DCD8DD153C510E74F39C53D5C7F777A
-:102BB000684B1EEDDB6978C5EAA95BC94C1CAD9E6C
-:102BC000D5DAF745DEAFF517237129DF0CD89BACBA
-:102BD0009175FCAB493CFE54CD92FDA4E76BF5CE5C
-:102BE000C443058A2E5CEF609DB332690CAF7BA6AF
-:102BF000E1D44727C8E07285EB9DA7525EA828A4C0
-:102C00007CA585FB9181129C2F91F27960FECBD738
-:102C10006252A94EF1217F589D43BCC1B63228DDD6
-:102C20004EBCC1FA611DCDBF84B68E1187251D3CF7
-:102C3000EF5932FF0BC6B76313F97A87F5CAD8D1BB
-:102C4000EA09AD8EA8FB8AE7A9DAF53AB47B1A5FE8
-:102C50001794585DDC76F0EBB474F49F839D57D2E3
-:102C6000D660FBA258BF96A70E619E9A21F214CAA5
-:102C70009FD77395C1064C871F431EAE17710EA4D4
-:102C8000ADCC4EEA28D925BEB54B7C1F673F5E9878
-:102C900089FEF7837896C70C9CE1E743F4FC139810
-:102CA000470DAC0D1C76E2F8CBAD128B7FEB31C734
-:102CB000BDB570A4BDD70A5E36C01651976D656D5F
-:102CC00079F6DE4F1E277FD46256C8BF0E74341AC1
-:102CD000D9FEB21AF17CC6C87CA856F0B7F67BF6CE
-:102CE000B55E4D127152F012D7C1F2DBC163B2DD95
-:102CF0002431FC7E353E122791FFB41D8C637A1E71
-:102D00003C615529CFFF5CF0EF92D8776F2891197D
-:102D10002EBA59BCCDED7A2B83F44A7AF0D23E4AD2
-:102D2000D75B533C6C9F4F65F654BD5BA6C3BEB0EA
-:102D3000FC010BDB0BD5FA1ABE3E812FCA35D9E850
-:102D40000ACBD5AEEFB3B947B11B493AC8F4A69345
-:102D5000A2EB5CDF7EB9528DB0275CCF6AF26FFBCD
-:102D6000053F403F944C7EB9334961F23504B99E2A
-:102D7000759DBCC5F72FE7FB3606F6FE11F7CBFCB9
-:102D80003574FF72BA05184FBEF25750FF910C9977
-:102D9000F9A9473EA8CA8288F783C4EB719F6128CE
-:102DA00099D5C327744C3EDF89E1E48956F283CD7F
-:102DB000F3ED79E4DFB87F389261D948FCF6D37B34
-:102DC000C786E75998C4E33CD07A53289B7991CFC2
-:102DD0002BD6BB0596321CB6089E75897C14EBA6D3
-:102DE00033648FB175D3F5F2DD88FA8D3D7F79AE0E
-:102DF00072F247C883C2637A3FD5EBFBCE723FD1F4
-:102E0000D0B9E1775407FBCE9B80FCC4235D1BB295
-:102E1000280E83D73B95F2BBCB5D0F4E65FB97D257
-:102E20001626979FE44BA1BCE97432E543B59DA7F4
-:102E300093595C6F9FFE02E5499817DD41D7315FDA
-:102E400061FC2BEC2966FCDB77BC3829930407B7BF
-:102E500085E6AD3DA6AF247C6A8F15BF5741F94B7F
-:102E60004F19CB93B4BCA888EA71CA938E4D8CCA13
-:102E700093FA057E8307E2D8FE8704199C3F303120
-:102E80008A3F356DEFB07CA2A643F644F2E8DA73D0
-:102E90002E3DE38DC1A5B0F91A029287F1632F6F21
-:102EA0006B3AF6B1F5551B024CDF0D2D067EBF9532
-:102EB000B7004DEC793F38FD84C77B7409F5506E3F
-:102EC0005427D0FEFABBE9BCBE88D5C77617DF4FC2
-:102ED00078F79CF766E2CBBB73BD59F651E2861FCB
-:102EE000CA78DD2D09BCDB0C2CAF8C1DB7CDC5F726
-:102EF0007B6C491075DEA8B5F52ECE9F7223DFA737
-:102F00008ABD7FAB8BD7CDF8EF191DF2E26485C186
-:102F1000FEB4A827C6A1BFBD4BF8DB65771A58DE03
-:102F200071529C33DDA5F9DD121EBFB5FDFE253BB8
-:102F3000E1492CFFE14BC863E7604B3CD17EEF6E6B
-:102F4000915F2D5B14735DE453777F4F3E35C3254E
-:102F5000FCE16498CCEB06AB85F645BFEC36D86552
-:102F600026B73AB1327FE43A357F73449C0F75A39C
-:102F70001FA4B621E743B64FF5EE8173BF71303F12
-:102F80001A07197CDF91EDD7D75E67BFBEE19A9D26
-:102F9000FE308A779A9EFA29CFCF1BA9A7A502EF08
-:102FA0005AF325233BB7844DDB7572F89CD264F04D
-:102FB0007A52711D868EB9213ABF6CC831B17CA995
-:102FC000FF7649257F8F72A69922FC7DFF389E7F70
-:102FD0003DB25C62FBC207723E6471BC36D46B24A6
-:102FE0005E4D6E5BF324B35F3F9CA27A49D3E762E8
-:102FF000338F9FD7F4A8AD976E2AB43EA79FFB6589
-:10300000176B693CC5CBBB447C5C5C12ADBF2CE844
-:103010005D40FB23F77824962F5D4FEF4B574C7B99
-:1030200087DCDF8DEAFF9F5CDE875D64EFBDC3CB8D
-:10303000697FF7DD9C4FD328BED65D87CF7E81AFF9
-:10304000CFC2CFC57C167E1EE6CE521AFB101FBD26
-:10305000C3BBD945FB4FBABFD8A600CDD3F7AB7AD7
-:1030600089F4030CFFEBD9D13631EF36979DDB8B1A
-:103070008B9F0FC5519FECD9A04E203F0179377629
-:10308000CED7B0FF6801E969E0C0B10263843E2F8A
-:10309000D5A33FA0F8D2792859B146F24D27F8A61A
-:1030A00067AD242D1571339A7F97887FA4FFBD8764
-:1030B000EEA2BAB0BF6D994B5222E26AFB49DBA483
-:1030C0008879FB83321B8FF5D8E4BB1322E57C9211
-:1030D000C9D91FE0F301F44D5E961F79BF919F1B84
-:1030E00099FB188F9FCADEC4CEDD351EEB81F3B885
-:1030F000AE6309B03825D61D30E20FAA33BA4C2A88
-:103100009D53D07EBB23C24E8E0A9C67627140FCE9
-:103110009C057E99E69D8933DE4B7D3D84E84C6EAF
-:103120003684647EDE3D0188D73304AF67EA430707
-:10313000A402368E9D4B95422F1B772B0CB1D603E4
-:10314000763DB565E0666D89397407B993BC4080FA
-:103150007D97144AD63B2E98D951298CA6BFF0FAF8
-:10316000F57041E3290EC6A487EDE3C78E1B1676E2
-:10317000EFA6DA82F4DC0F6C1FEE16E893E925B3B4
-:10318000F5B088BE27BB450FE6789477EF611DB395
-:10319000E7AE3E45257FE64E12CF7D86CF617FA606
-:1031A00087DB2D8520FA6E455B6F2C0EA5381FED51
-:1031B0000BCED463E5CB700CB1F7DD4682E3BAE702
-:1031C00082A2A7FE1F5DE9623F85D769F3449DA6F1
-:1031D00033FB191E7F12F191CE736C384F69930443
-:1031E00067E97C2693AF579BBF14B3C1C4421ACF83
-:1031F000E31B6D859F75F2731E1B3B9F9B6F27BC66
-:10320000A450B2EEAAE5C6711D4C0626B7EDFEA18C
-:1032100081C78BC3E75DEEE0D1B3F45D8EE4F1B01E
-:10322000EF7ADC666B88F27364C7A5C8BCFBAA6B37
-:10323000ED5FC9DE25C5CEF0022F28947F8C0D7F6F
-:10324000EF025793C2DFD3108C1793C3E7FBDAF773
-:1032500035BBD5A58A0EF5B2C26576935E0ACD69F7
-:1032600045540F36DBBD7F75B1EF6C5A26B1C9F4FA
-:10327000EAF4CA8430DF2DE02921BCB5737D49E82A
-:10328000EF7AE7F664ABC4730BBA7DFA2EE819B493
-:1032900017B373B4EF8FF8793E5AA142DF1DC11303
-:1032A000F314FA2E609BC3EC7E5AA2141FD7670951
-:1032B000AFAFD1CCBF276834F3EF0260EB74B67FB9
-:1032C000F690388F68B4EAB2A9DE6A84783795F44C
-:1032D0009ABC0F25703E3EF4DF16763E1A2BF7D7C8
-:1032E000F1DE9C31D3C3F23F2ABBCF62EE1385E7F8
-:1032F0001C0D4F5D18CF156A46639FC2F09B46CFE9
-:103300004F33A937D1BEC82A13FF7E49C30D15CA52
-:10331000486D17FAD0F0B393BE691D1ED4B7C69797
-:103320008C307ECFC473DC0CF4E544267B56217FC1
-:103330001D8BCBFF01AF6B7F8EF0290000000000DA
-:1033400000000000000000001F8B080000000000CB
-:10335000000BFBCACFC0F0A31E8143D1F8E8389D13
-:103360000F534C941182D7B3E0D78B0D5B3122D829
-:10337000FEDC0C0CCA9C0C0C2A40DC07C4FD40FC93
-:103380001E880DB818180C81380DC84E07627B20B6
-:1033900076E386E869666760E806E2C9403C9B9D83
-:1033A00074FB39241918A6C822F84F806C4505D241
-:1033B000CD19C54313F31BA1F235B451F9C1BAC0FD
-:1033C000F481A446539B34F34F01F59E36C22DAFD2
-:1033D0006E8ECA97B344E52F3343E55F7487D00000
-:1033E00093DDE134B803000000000000000000009D
-:1033F0001F8B080000000000000BC57D0D7C54C52C
-:10340000B5F8DCBB77EF7E6F361F840D24E1260410
-:103410001230C125060C56DA4D0405451A502BA86A
-:103420004F970009C857502A69C57F2E49080102E5
-:103430002C186B50C4E553ACD006053F5EAD5D1053
-:103440002DFA7C362A2AEDB318104129D014A56C28
-:10345000DFD3F29F73666EF6DECD6EC0E7FBBF7FF3
-:10346000FAABC3DC993B77E67CCF39676665D14C14
-:10347000D206107209FE7E44C81813216444B42495
-:1034800015AA404612F2532BC13FAD5F6CD9584785
-:1034900048D842486426211D4EDA51AAB192425AB8
-:1034A000DE7EB348D2094982F715429A849A4303D3
-:1034B0004B0851B344B29D3E5A9E393929E04C3CE9
-:1034C000EE2E3EEEAFEAAC58B6D779B07CBECE8BCE
-:1034D000E5DE3A8584F30979B1AE00CB97EB7CF851
-:1034E000FC5FEB4AB17CB5CE8FE56B75E3B00CD7D2
-:1034F000556079A06E0A9607EB02F8DE9B75B3B0B3
-:103500003C545783CFDFAEABC5F29D3A159FBF5BEE
-:10351000D78C65475D10CBF7EBDAB03C5C17C27E09
-:103520001FD5EDC4F2485D3B3EFF53DDCB587E52C4
-:1035300017C6F24E924C481F42EEB8E382751A5DF0
-:103540006FFE538BDE1F9F46C8DA11A20FC095FF96
-:10355000D4096FA030BAEEB5DF9AA6B4C781CB4FBD
-:103560008880E3AC75116C5FBBFF8F44292264CD6A
-:10357000884EAF4AEBE3F977866C3F6C9D5618EDA9
-:10358000173BCEE7C4C4C631D376DA6FF006D65FF8
-:103590006B1F0FDF19116DDFD1F6BE75BA53DFCE89
-:1035A000DE7F66E3FB56C0DFEA8844C28877951069
-:1035B0005ADA95AEB63E14CFB6231662C9A1F857B3
-:1035C000DA49271D67CDA85F84C5125837EDA6C01C
-:1035D0003A3F20028583EA22480F0A8C716DF43B42
-:1035E000D71211E791FFD461F69DDB2F60F9DA3F26
-:1035F0006442E87B6BEE10420E3AFE9AD1E7BD7E44
-:10360000A037F55913D01B92AB02FFE9F456D0B1A5
-:10361000D78EFEC8AB5238ADFEF68329D381FE8625
-:10362000131F7C6FF5FE578802ED455D08BF06BE8F
-:10363000EED553A70DF01426A64B4A49442CA5CB32
-:1036400075127F280E7CFF058040E163F284704D87
-:1036500076DA2F1E1EFE85C8D86FB5ABE243808B8D
-:103660007A87D9B79DCEFB065F989C7446E70DF527
-:10367000CF68DDF97598985C30EF2FBD26BA7E478C
-:10368000A97C8D8DCEC6D9D57504DE775E5FE587C2
-:10369000B5AF19DEE9ADA2FDAD051DB85EE223BEF2
-:1036A00041745C7B814AA617021C4C88D7D8F94C20
-:1036B0000778F7013CFDDD0B38D1E8F0C3DB3FB004
-:1036C00056EAFA3FA3D187C0E88BB484AD935CD1AE
-:1036D000F6A7B4761BA31F6235B66F88A1639299D3
-:1036E000A0DD4C018DF81243DB0584BB757251CF10
-:1036F00079B784DF423E70FAC2D6409C75513EB124
-:1037000082DC492A117D00AF35A329BF1446D77941
-:1037100039BE6BE670595D32D905E35F4E6E15B563
-:103720008B245CC06526FDFFD52FDBE9CCA3F5E13A
-:10373000E11443FD9A43FD0CFD4774E41ADAAF3DF2
-:1037400032D4D03EAAB3D850FFC117D719FA8FEEA2
-:103750002A37D47F14B9D9D0BF8CDC66A8DF60BD0E
-:10376000DBD07FAC67BAA1FD26EF1C43FB78E541B7
-:1037700043FD9682870DFD6FF53518DA7F5CBACA76
-:10378000D03EC9FFA8A17EDBB8270DFDEFA8D86AFF
-:1037900068BF73CA7386F6A981170CF579F6C05114
-:1037A000C0CFDDB37E6378EF5F6A5E37D43F2464B9
-:1037B0005C3CFC1281C9194A419E9357F1FE54C4E6
-:1037C0007980E6808EFB303A2DD89C404EF2F66729
-:1037D000B7BD6F9D6990936646C719AC7D67E8FDDC
-:1037E000F8EF67713E211DD6C92E7D3B9BD755FF53
-:1037F000A0F215DA25F53BC95797C787FD35B94AB9
-:10380000E99B90EB287CD5FEAA8ADFA3E351796976
-:10381000624B26B584C929421EC4E79ADE27992443
-:103820006CA2E336B83237AF0498D0B1A534A817EC
-:103830006E81BAA8F849671CB89A3CB2014FB1F042
-:1038400025CE144ACCBDC95915E1A78E2505127C99
-:103850005FB0FB96D2F54A24D04FA0CF2F8A012F1C
-:103860004C7EB149FD7D2027DA7FE968FA4FE87F79
-:103870004C08D5637F05E1D85044FCA037D40C39FF
-:10388000B43D07E1690179A2BD471F289D6CBEEADE
-:10389000A581863A9BEF65EBDFE41BEBDAB83F3797
-:1038A000C293C219EAF7F14A8F75FBE428DD9AA0AA
-:1038B0001FAB2BA2402EA11C34B66BDFB968730F6F
-:1038C0002349148F56562EB6BBB74079D1961D2288
-:1038D0006E420AC54039C04D2D67F0518F3A420DF6
-:1038E000385ECDB5154500DFF8F60221F58C3F3E78
-:1038F000192FEAD791086F0D60B7E5EBE820D38761
-:10390000729CAE1AF55B6CFF3B05998DEFA4A8A2E3
-:10391000E35B08A3B12453E04E6104ACB68248389F
-:103920004F1FA9407C8D2360975A3578066762DD6A
-:10393000C9EDCCFDAE91470214CFABFDB20FC6AAC4
-:1039400014148E079F17F480A554242B696DB5F2CB
-:10395000BE15F8A33947CE00B96E916A8887D62D77
-:1039600079940FE2E89105DD72E211722576712CEF
-:103970009E0AE8EB6C1E04E1A8CD3F98D561CD0509
-:10398000BA1C4DED623AD5B5D7F7AE5F9671F8AE79
-:1039900002BB98966B94C94904F9964C05FA6ECE11
-:1039A0004917914F399CBAE192F39115F874057F4C
-:1039B0007FB5EF7DB4D357687A3C068ECDC38F2395
-:1039C0007CA6094C1FAF2AB24F09C581CB34C18DEB
-:1039D000EDCDC05369685F31FE8AA117DAE2ADA46C
-:1039E000ED56C553BC928E3FA6489A0A74E12A252B
-:1039F0008A05F9D7EFCCA0DFB7F3DE92221AE4876D
-:103A00002B8DD1ADF51321A4D0FE4E2FFB9EC549C1
-:103A1000427E7C7FA1012FF6D2C004328CDA49FFAE
-:103A200030E17B748ECC8E383C1EF9D1EC61EB24F6
-:103A3000050C4F1EFABF4BB9743C4536E88DA565A1
-:103A4000B22F4CBFB3D8ED447A32EBF14ABFEBF85A
-:103A5000F6850A187F79E603F6A574FC8B654DCBD5
-:103A6000812D4D9F8CFF12F8CE14DB3F6BF21F06A9
-:103A7000C6E103AD7474BA49381506B8A7573A7051
-:103A80007FB2F9ED83BA79BE2AB8D250BE5E4BAE92
-:103A900045B97099F72FD685DE3E3808E1215E09D9
-:103AA0003D2F8BE1EBA61C4D6FA9DE493ABBEC82A2
-:103AB000C0F41A51CB10CE12E7E7A6D1A40BECD676
-:103AC0003539B2524FBB48A572184807FEBAE8F71D
-:103AD000C1362320AF95A60EF6FCA706B9B9A2EF12
-:103AE000445FB817B8497931FAE632EBAF05F8E927
-:103AF000FA9F00F839A2F0B3908AA430D04B709CA2
-:103B0000611FBBBCEC21254CFFB9BCDF2FFCC78873
-:103B10000E8E3FA27CA8E30F4B6688E8BFAFC9C5F5
-:103B2000DB447F17C86193EC4339457265DC8FC471
-:103B3000CEAF4064F2260A67AB4474FC4126841081
-:103B4000EEF4AFC29ACEE147FF6CDE37FF01F0A37F
-:103B50003A3AEC1886CF1BA5623A9F34A23AAEA639
-:103B6000EF4B44827A9698837C4BDBC7C829C0BF51
-:103B700037FA400E36F17D1FF16CF6EAEDF22C912A
-:103B8000E135DA1EF2DE616867F64E9366D77BB6E2
-:103B90001AE8A2FBFD641277FFD14764767696E8B7
-:103BA000E1F4B315F76F2BD22644000DB68C1B7DC4
-:103BB00095C0AF1E8270D0F484A617A8BEC812FBB1
-:103BC00044C793F32A8880ED46FD9B505EC7E85DAD
-:103BD0005B81510E10BD3D930BFFCDF420BD90587D
-:103BE0007DCFCB8A9BAF88AF7AE84B127FBF384935
-:103BF000647298A869B87E8DAF08B727CC1A5D109B
-:103C000046AF6EFE5D19E63310F01CC2C11D745B39
-:103C1000057517A9C1FA85D2E230C0C922753613DD
-:103C2000AE1FD59C38FB28EE8749B48EB5A3E3EBD5
-:103C30008732D18DF834396B4800E9F81EB403059A
-:103C400035402EA13D18E47AD5E7053C2EAFAB25D3
-:103C50009FD1C5D80F8CC7FDB994E9F7C3FEDE0428
-:103C6000449041FFEF2C61A5E453F4F4D98D47B2A1
-:103C700014C73353B0C03ACD4EEB34D00366A767B8
-:103C800012960543670A5026DD582B225BC5A727ED
-:103C90006D3C4A57B344182F2D80FC2C792AB02450
-:103CA000CE34B45F697FA522EE3C381DF07E09E971
-:103CB000AE9B6E343828328C174B4F361FDD308860
-:103CC00058ED80F9A6F3F9A6DFD3B41040EC24AA8E
-:103CD000753085517AE734D47B4EAE7F1A0B8A9BC0
-:103CE000CB693F772149BE9196B6BC2E9C3FEE6BC7
-:103CF000FBC178772F2D43FF07C17A637D4519DB20
-:103D00001FF863EC565191343ACBEDD5DE112E59A4
-:103D10007ABE9F68FDB1FA949007AECCBE9AC2F805
-:103D200051A5FF037EF4101D7FD271DCD71BF581F6
-:103D300033E63BBF025822BC17FEAF7C2F89D45B11
-:103D4000154A0A6645F484289E286A92611F65F325
-:103D5000D3FD1DB4A775FA45E5F27869847D6C2121
-:103D6000A3173DFDBFCEE56BDF7B171D5B46C7BDCF
-:103D7000E073FAA0573A15A7A9C53DD7B33246EE6E
-:103D8000AC2C588F74D140E92817F6070522EAA514
-:103D900066658B47EF57F95C93433DE88328D2482B
-:103DA000BE9FA4F03129A2DFE6FEFEF4116B3F5D59
-:103DB000297DD8A718F1F15DF175FE3BD2C7F7FD5B
-:103DC0009E86D744F28CE215EDF1CBF99F7AE2B5ED
-:103DD0001EE5AE4D89EFAFBCD88D4FB56769F0A732
-:103DE0001AFD02D6BB9BDAE2D92D5A69BD2776FFB0
-:103DF000CFC6B5D59A941360DF4A1EC33E6885B21C
-:103E00005E057BFE02D8E5601F06CBD03F4CF298E2
-:103E1000BF160610815F147F88ED6F4244AF07E53F
-:103E20004CA3DFCD946637EAEF29AAA09FBFAD5619
-:103E3000C67958E17B69E8CF0DC1774D1E12B6B93E
-:103E4000A3F40A9F62FE8087AF880E347A05339808
-:103E5000D1ABF1BDE599C5241EFE7A7CEF76E37CFB
-:103E600013CAA5D8F79C92725267A7247E4F2227C7
-:103E700075F64EB916F7E178A276DECB42129507B9
-:103E8000DE9F9000856F133465807C22A8CF9ABC9A
-:103E9000C52817C84E2166DFAE30FA5152B0BF6850
-:103EA000657A53AB279E0FFB6E348EA4E0BE36516D
-:103EB000FF86BAD2C724AA8C1CB5AFB74A148F8D1F
-:103EC0004BFD532A707F7BA8551A14ED37CFA4ED14
-:103ED000DBA9FA1C19A56789D07E0837915CBA0660
-:103EE0001E7A883212A0C9E99B74603B7DCAF148F2
-:103EF00084EEFD0C1DB20DD689FE8923D80F06BABB
-:103F000084FEA64E56A72F427D95D9EFC779494129
-:103F1000EB03145EAB6CBCAEF07A32AF7B783D87BE
-:103F2000D7C97AAC3B645A07FE35073D58B7F37AD8
-:103F30000EAFA7F07A32AFE7F2BAB01EEBAB643641
-:103F4000DE4A29C4C6B7F3BAC2EB29BCEEE1F55C80
-:103F50005E275BD8F72DAC6E3787D8F80E5ECFE1C1
-:103F6000F5545E4FE6F581BC2E6CC17A42799947D3
-:103F7000E16F900F1DD13A2A110ED7EE7A674C3BB4
-:103F8000A3975481703B2C940176D3FED9BFC8000F
-:103F90007FE88663D77A613FD670AB464F3E949FE9
-:103FA00024F3169463197CAC86195BD00FD1304B87
-:103FB000C6FD27E1FE99687BF12185B65F08883E42
-:103FC000A09B2792E3FBC97E51C7E295ADDC4E5E14
-:103FD000C7E3956B215E09FE161EAF5C05F14A0B27
-:103FE000D0A90FEBCB215E990FFB6B16AF6C8078DD
-:103FF00025AD3F07F14A5A3E0BF14A5A3EC3E395BD
-:10400000DB79BC722BC42B69B919E295B47C9AC7D1
-:104010002B9FE2F1CA2779BCB26D46F15B7930FF84
-:10402000B96CFE89F0D1778A517EF6A930C62D523F
-:10403000C6A418DA3DD71BE316EE925C43DD59683F
-:104040008C5BD8F38A0DE35933AF33B4CB69E58683
-:10405000BAE434C62D0A774D36D4876EBBCB502FC9
-:10406000D85869187F70EBFD86F6BC96070CEDB941
-:104070008D3F37D49525F586FE4F9A7291BEB217C3
-:10408000AD34F4CB9CBBDED06F9EDD7FDA04F26EE4
-:1040900042DA15C937F2B59AAE9797B1FAC1944D85
-:1040A000FC7ED4734C1FA18F16FC6A59CC7F65FD32
-:1040B000E4A643B07FB1E4313D15EBAF8A1D4F76E6
-:1040C000EE38A2D2EF94B90F793B75FC48BCBAF731
-:1040D000E85293242627573EC2F6E72D8FC4DFA768
-:1040E000A326A0EB68F9363E1FB82493418F68FBE6
-:1040F0009A964704ECFF7DC7D7DA63C78D7E8FD2CF
-:10410000DE48FD7E38C4E7437584CE5E3077264FA7
-:1041100027A8E7D97ED9C4FD3B65134B8F35527E66
-:1041200059E6213E0BAD2F7396FB995D42AD73C0EE
-:10413000C5925B715FAFF5D7E6D5E89CCCE40BD1B7
-:10414000F92D514ED90D7E856569BDDB6F72C48432
-:10415000FE3F53442061AA9764A9625C0E9D8F7C48
-:10416000D8E45B4A503FC5F50F10B29EC59DBD46D1
-:10417000BF69E38C18F9C7F332CC7CFE0D69E5F812
-:10418000BCD1D3FBBC2C302F980F9F9739E2C0D203
-:1041900014B1E17C474552B15E1A49C6F2DA487F54
-:1041A0002C474632B01C11198865492407CB6B2275
-:1041B00057E17BC59121580E8F5C83CF7D91E158EB
-:1041C0005E1DF9013E1F1619856551E4067C5E18D7
-:1041D00029C3F2AAC82DF87C68643C964322B7E153
-:1041E000F382C8242CF323776339383215CB4191FD
-:1041F000E958E645A66139303207DFCB8DCCC632AF
-:1042000027F2203E57220BB11C107918CBECC8CFF7
-:10421000B0CC8A34609919598A65FFC82A7CAF5F8F
-:10422000640596199147F1B937B20ECBF4C8062C44
-:1042300093235BB1DD13D98C6552E4397CEE8E3C5F
-:104240008BA52BF2023E7746F660E988FC069FDBE1
-:1042500023AF60698BBC8ECFAD91FD585E0E4F973A
-:10426000B3834B4F18E3CF233F31CAF192C3C6F853
-:1042700073F13B4639EE3B688C3F0F7BD5187F2EA0
-:10428000DC6B8C3F0FDD6594E305DB8C727CF0C644
-:10429000BB0CFDF35A2B0DEDB92DF71BE574A351A3
-:1042A0008E672FF9B9A17FE6A27A437BBFB92B0DA8
-:1042B000EDDE1946F99D4E9E30ECD33C63B618F501
-:1042C000DAF5BF34EEDB4A9E8FD9D78450BED80BC7
-:1042D000FFD5F09E35EF408C5C56997C8AF1B70390
-:1042E0004820BEB998D87DB0AF89C5670A9707A99D
-:1042F000C077B44CE37CD707F88E9629B7CCF5028B
-:104300003DA44E2C9D0676CCC5638202BE3261620E
-:104310006D3EC47B52FA138CFB1275C80D7E5A6F2A
-:10432000CAE075FA44807A1661FE06B2B41CFC6CD1
-:104330004D39ACFE56E39272C88B6932F376B5B153
-:104340001CDFB7B1FA91C619F5D09E92E4EBE7A352
-:10435000EF6D35C797D79F4A2CBED75FF2FF41A2BA
-:10436000EBFF6B59E743E097FB776BE003893E9FD8
-:104370006B0D0C80D0DA5973E019501DB982FF30F3
-:10438000F42B12FC1F4A28B78D7ED609A038E9F31A
-:104390001CC9FF4768D7D6DFE4EA7D1EEF72BDD4A3
-:1043A000944C709FA93E26F3BC1282FA52F36B3DE7
-:1043B000EE70A3BC5FFE98BC05E252E6CCF4E9E0E7
-:1043C0004F833F83FE686D5A087E762BE8A18120DB
-:1043D000E5DBB174920E2CDDA40B4B0F64120C8C38
-:1043E000AEBB7BBD596CBD140E5F4BB88FA8C1FE30
-:1043F000F58E89A5B01E0A870B1C0E7F97FA2486BE
-:1044000003FDABF08E642E51B4277609067F6692C9
-:104410002940CC3C8E0ACE998C193EDC8FFD49F2A6
-:10442000203D6AF0A37F8B524646F301E87B56732A
-:104430009F9EE369E320C0E0FB5C1F6AF45C9B4045
-:104440003F697E6EA2DEFA9DE24DBF97C5B8DF31AF
-:10445000493E8CD7C6BE27398DF2CFEC0C601E8446
-:104460002CC58FEBCA161EAFDA38F18AE2DB3BB8F7
-:104470009D4F1A6FBDA2FE5BB475534A80FE591A58
-:10448000D76FBC15E96E107F3F0BEC3A4A4FAFFF78
-:10449000B9BABE05E80F62D2F1FC07AD22DA835942
-:1044A0000BA9E0C989C23BB390DA83C3A2DFCD5C1C
-:1044B00064F4BF8465165F21AD57067F2DAF338B43
-:1044C00012FCBFA6F49C07D93691AD87C751A50D44
-:1044D00015CD362A7F0639593DB3B5F7F9101EB709
-:1044E000C8E47495E9E47E979DC6717B7CD7F4CED1
-:1044F000F078795E09BFF31DE38033CDF1E3A814B2
-:104500005F88EF81DA3C6AE91F9DD7603E7F6D3C92
-:104510002D1EA8D5293EAD607737B554A29DD5E4B0
-:1045200065FA9B7C43471F892C4FE2EDCB421CFE72
-:104530009BF87E32A49663FE23D965A45365A964D3
-:104540000FA0FD26A640B9B991F5CB59966607385C
-:10455000357A5252A0DC542BD6DB28DD34AAC40FA6
-:10456000CBCAFED9091B6B3F9E0C654E5BD75BF92E
-:10457000147F391ED127D1F964A8E7DFBA09CA161A
-:10458000BF3507FC704B24CC23CC6E23F602DA2F08
-:104590007B2EC17E0444209DCF931A1ED556611CEC
-:1045A000FD67664BD7521BBE47FC8374FD3670F027
-:1045B000E5353E50066C9AD7E2993C0EE2F385C48D
-:1045C000378844FB3DCEC773403B8C3386E5316A68
-:1045D000EDEB78BBA5F6BC9A0F654BE7BA9BA05FE5
-:1045E000AB719CB5BCDF20ADBDC4D8BE5A23AB2592
-:1045F000CF87611C534BD77B37C17CDA58BF6EB96C
-:10460000C5FBAFE2FD63E5C560788FFB2BF5F35C7E
-:1046100011835F4D7E84C03F900FF865FE018B755E
-:10462000EB53E08FD4FA2D17D8FE4889C9337DC5E6
-:10463000CCE46197CCFCB61A3D25A26F3257B71F68
-:1046400080B8E50CBBB17E4F8A611F48C6F433B613
-:104650005F9F6B6C2F196AAC17161BEB79D719EAA1
-:1046600017BBFD2F411BE68573FFCB60FE8D0D6DE3
-:1046700095988712F5FBF9EDFA7D4A26EFB7ADA6BE
-:1046800018F9A7C1C9F987FB691CBCBDA9B0D2AE96
-:104690008FBF6BFCD30C7E100BF85958DEF68EB62C
-:1046A000DEE1B589E37B23CFAF7982E3A98DE3E92E
-:1046B00017DC8F13E47E9C353CEFBC85E79DAFE4AF
-:1046C0007E9C469E77FE02F7E3ECE17E9C6DDC8FDC
-:1046D000F36BEEC7D9CDF3CE9FE37E9C15C3BBA68B
-:1046E00082FFEC59EECF7986FB73C670F9BD62ACE0
-:1046F000AF1FF8F7B68E8DBF7F1EC3E9E2C7E0C8D3
-:10470000EC037ADB536F06BAF4B13CEB9C5A8F682A
-:1047100029013B97D165CE2C8F2897809DCBEA93BA
-:10472000B8BE05BD827933993C6F26936A9D74EEBD
-:10473000FF85AEAA4AC01FDF778A6738B842DD32EC
-:10474000D7A30AF1EAE3067DD58000712DC9E44FB5
-:104750009247C0F86C5EF9C1AE0390A7E8EBE82879
-:1047600007740E3BD45E0FFD0A0B83109120E6B454
-:104770009008726945990FFD6F4F7F68F26D813126
-:10478000D388812EE81C519FE5F1FD2CB9DE481736
-:1047900096C826B49B9B6A587E06ED1377FFAE95AC
-:1047A000C97EA3FD90546AF483350527F7EA97F68E
-:1047B000BD6A7C7FD85EE3FEABA9D09827125B165A
-:1047C000EE1263FC5C31EF3B7BFF7E7E6422AE37F2
-:1047D000119DDF66AA2C97757912CEC80F711F1133
-:1047E0006B0F4A60E70DC4BC1A3FD8BF529EC70F7B
-:1047F000FE12294FE1A58F3FF7F37A05D6A9DDF820
-:1048000063189FE2C560379A480063222B8610BE6A
-:104810001FF967BD9F2AFF157710DC4F789AEC3798
-:10482000A84083FE99881F99E32755AE7906FC1F9F
-:104830004FAF1609E07F6B4BEFFCDB239FC2E9C74C
-:104840003852D6224F31E8BD44EFB52E12C7C58B82
-:104850008FCDE774BD6CD1640FEA8D8397CD179827
-:104860000FEBD7F205FADCCEF305CE8C37F8955373
-:10487000AB7AC7E3062EBFB47A06896FBFEEE1FCC0
-:104880004E9C2CDF44A3FBD461BD8FDF7D6E2724BB
-:10489000920EE00B2980F2B3CFED01CC8B27145F91
-:1048A0007A3E69FA76FADBC087EA3A96A748FB892E
-:1048B0007A3B4C9B4786275C2640FFFDA3307F63F5
-:1048C000B0332042DCBA693FE1DF69477BDC31A3CA
-:1048D000C6CFFC65ED04FCF68E1A9F0ADF077C61EB
-:1048E0001E5246777FD40FAB8222A67E349430BB13
-:1048F0005793FF1A9D34788B0F417CFD4289847158
-:104900006F6A5F5DBAA4ED67E87F06B7313A68EA7F
-:1049100043F0DC8D54A086811E897F1CC20DC81F08
-:10492000FE9A5C3FF1E3B99422A6FF4D70DE03FAD4
-:10493000491D7ECC830E787C90BF98D5360CF94CFF
-:10494000F2D40880DF87C4C06E3D5F999C2CFFAB1A
-:1049500029C1B982162E67FB25C0EB87BC3D55EEF9
-:10496000180F72F8E9C728FDC7C9CBF903D70B4F59
-:10497000B54EFE438112E55FADFD4F60A4E9E695BB
-:104980001591597E61DB77DB078C35139E7F647C44
-:10499000CF2C5518F6615966E3F7E434A33FF2CA09
-:1049A000E729A15C2285371BF09CDAAF77F9A9F1E2
-:1049B000FFC5AC18BB23AF00E9396A7794233D6C7F
-:1049C000F412462F9C9E343DE2EAF4ABE2C09EF422
-:1049D000B13178C00676B246671667C80F7E038786
-:1049E000378CE9823A7AF82BD04356DB4884B7AB50
-:1049F00044C5E7FBB8FECBADED2AF3C7598766DFA8
-:104A0000C1BECB5B0C5F88D9FF908A20D8D559599D
-:104A100010C303B5CCFC0B999997DB6F5D59FC5A19
-:104A20008B2767D33FD8FFBCA2E1FD8B18BF9587CA
-:104A3000AA785D3CB5EF17D30531A7271E62DF6B5F
-:104A4000F4947BE2C96FC91448B7E8F01FBB8F8F9D
-:104A5000DD6F13BE7F94BBAB8B500E5B268CC3F80F
-:104A600048F7BE7BE3445CB785E34F6ED1E2FBB110
-:104A7000FBCAB9BEDEFDAADF6F5FE9B318F34BAF27
-:104A8000383FF73BFA25B672BB35767F113B8ED89F
-:104A90001610E39DDBC86F33C23DAFC568FF0CE362
-:104AA000FC9DA31AFDC8036AFBC5F777F27CB5CA63
-:104AB000520D4FCA9DFF41E977F62133E6E16BFBCA
-:104AC00060CDEF349BE7AD55F23CB619A4C20D8D15
-:104AD000678988E777CE92F7DDD7E8F8A6CAC2CE15
-:104AE000D19166F371387FA1E567CD0CB2BA369FDC
-:104AF000EA3663BD8A4C4E07BF6B55AB99403ED634
-:104B00006C221DEFD4E64FE9F8271696875A4D6AB6
-:104B10009A40BE2DE379AF951E22A5A61032EFA5CF
-:104B2000A746C2799E7916267F4F53F82B3A7D7D92
-:104B3000BF3324037F7FB6F79A9FFC80C0FBA1A6FA
-:104B40007EA03F93E39F8398DE6C9CDFE5E61F3BEE
-:104B50005FED9C46A279483B85B8F93F0F6BFEAFED
-:104B60002B3C47B215826223129F23B9DCFB3B2DFD
-:104B70008C7EFEBBEFEFFE9EEF3F7F99F9CFB376C1
-:104B8000DD8879DE6935152057B57C96F924E00774
-:104B900057BAE9D5496A7F45D7CF7B85FD32693F52
-:104BA000D315F4CBEB7DBC739CCF7FBF6BAB0CFC00
-:104BB0007BF697C726823F70CE6F4CC44AE9E0DC93
-:104BC0002E173F2F169241EFDDBFD7E40F613D3C1A
-:104BD000F2365DBE206616D2F1E7FCDA85FEC4FB34
-:104BE0009FB78426D0F7EF7FF1B36184C2E15C7D8B
-:104BF000D79BFDC10EFAA5C0F2AFD4CE61B7D1E705
-:104C0000F74BE4BE8A387AAB83F3C199571C5380C3
-:104C1000CE849DFBEFC571DBEF345B74718DDF5B80
-:104C2000CC087FDA8F9DC77A56080D12D8FCF4F9AC
-:104C3000E25ADEDB99670536BF97CD211BCC6FE7C3
-:104C4000663940FB2DD8F937A4EB1B7EBDDB0D7018
-:104C500058F0B2C9207F16EC34852DC3B03C6641B4
-:104C6000FFBDDF298C047812D457F3F7CE9B00F4F4
-:104C700030BF7DD5DF4C6E78DFC85F142E78EE63D1
-:104C8000CEC726DF04A8BFF08C1BECD9D31DDBDD1B
-:104C900000573AEE3499D2D50FBFD6F12161E347E0
-:104CA000527A8E071E1BA0AF05ED2BD8F7F6DE7AE1
-:104CB0000AE4DB82183E3E0DFFC8E8A93F2216A396
-:104CC0005FF202796724D81D64676ADCFCE26EFD3E
-:104CD000C1F97ACEEE0B9BE03CF199E7FFB209EC0B
-:104CE000FBB9FFFC6AD3C3E01778CDE60179B4E0E5
-:104CF000971FBA890EFEA95666CF9F7BF6991D4F66
-:104D0000503E39F7470BDA3BE77E7B2A5BA1EB3F4E
-:104D1000B7E71FE970EE76D16FC7F605782CDA7722
-:104D200043DFDEF61B40B7218B1EBF21C4AFF2323A
-:104D3000FD4E5F020758581983A7D7F7BE9E0DF3A3
-:104D40003C7BC482E76F16D067B5C580B779A81FD2
-:104D5000A0BE84C27BFEAEE57F330D8B0777B5BF67
-:104D600008678548B83FF102DE6FFBF1E81228CDF5
-:104D70003E05C6235D28DF63DF5B7098E2F7EAC477
-:104D8000F8BC40BE9101FE0B76AD60DF6DA7F874F4
-:104D9000F7C4E759F8C7A89EF82CB6C6E273EED35D
-:104DA0004F40E3DED4B879241A3EE7EDBBA357BBEE
-:104DB00041930F9783F32C9E37F54F8BBFDC0A7C12
-:104DC000F6BC43F5323C8726D0B673BB2F64134A3A
-:104DD000275F98BBEE0539D9F55B8B670B7D7EFFAE
-:104DE0006F3F46BE3BB7EF3D5961E74F9C02B52B85
-:104DF000CE91EEBF0EB033E6F3D8DA826DAEB0C519
-:104E00001DC5D7FCD0A4718A1B9F1FC3E721C60F05
-:104E1000F343FB6F17E2E06F893597E9A7501F84D2
-:104E2000CB3CD221C3F97C3D5E8552C0E7B11B81EA
-:104E3000FE12E1535BBF07D67FAD0EAFDB181FC775
-:104E4000F69F4FF915E4700FFC86848FA13CB7D90B
-:104E500022417EE4391E6F8CC57B14FEFCFCE47796
-:104E6000B4171FB226884370385C8EDF2FB7BEEFB1
-:104E70000ABF195605C78D85E3996FE2EB83F55C90
-:104E80007ECC2735E3FAE9F499C54CF5590ED87B69
-:104E9000156A7F213ADFA67613CAF9333B4D21D03C
-:104EA00017B1F2627E827D72C8CAEC97F92FEF1FAC
-:104EB0000672EDCC8157385D32BA9FBFEB98AC7269
-:104EC000FD10D2EB870471CA5FF2F116BC1A7FBCE9
-:104ED00005BBFE1677BCD392FF4E98FFE90E335107
-:104EE000E910A7DB4D71FD49AD56B331CFD635F290
-:104EF00048127DCFE4B62BB0EE867AFFC72AD825BC
-:104F0000EF9BD1CF4224DF17163C6F6D575652B836
-:104F100035B8ABD0AFA28DD7180327C95BA10A253E
-:104F200070FEABA284D9D46CDE5ABBD9231AE64DED
-:104F3000F56E26E8A5A3C34F99619D9FC6D88F9FA4
-:104F40004AA4A92F1DEF5355F02D55E2ED178DE31F
-:104F500007969888A2D78796AEA3301FF23B1B0115
-:104F60003FB2E9359B0AF264C1265B08E29BAFEFD2
-:104F7000BBB803E076EE690B8F77B23CDB6ABE5FAD
-:104F80003BB5EFE2A6FFA2EDA7E065FAFDEA4DB45E
-:104F90003FD8EDBB1C98F4FCD7E79386112AA7AB4A
-:104FA0007FF7F044902FD5B0C7A2FDAB7FDD37D49B
-:104FB00040C73BD987D54FEECE0A015EE6BEF0DB97
-:104FC000F9A04FE6FCCA4180245FDFF7F1BD503FF6
-:104FD000F73B17E67B9DFBDDA91F021F507B5BD1D2
-:104FE000EBF5D9FAF3DE74DC395067EDC2255D1EAE
-:104FF000C11C2829BDCF7939C90FFB715D3F7C6F7A
-:1050000081A5EB21744011B59F887BA2703FE0C35E
-:10501000393B8DDFFBAB95D9530BE4AE2AD63FD895
-:105020008FF16B07BEF78D46A7BC3DF67DADFF7FC8
-:105030005A7363C661EFCFB7909A78F46FB1B171CC
-:10504000E7ECFC36DF381EA3D79EDF61CF7F2AB0A6
-:10505000FC7CB2C786E77FE7CAE1C129945F5F9411
-:10506000C92CE0DBB9EEF0E064FABDDF707939D726
-:105070004EEBF4793F3E0FE80F7562EDFC15E077DB
-:10508000DE4B3602F43EEF772EF42BCF7BF1E2C9F4
-:1050900027E9F333FB1C98C73AEF778B11DFF32C2A
-:1050A000E17BC18FD3B5C782FEB1337BDECA067BFD
-:1050B000E48C399C9DD28B9F685EBB853B2F8CEB2B
-:1050C000A0FB82821A27F839595E4E2D61F70ED463
-:1050D00042E207D0F12736160FE1F1A907B8BFE881
-:1050E000FC0C2509E77FFD2DEC398F5F3F70ABD2BB
-:1050F0003759370FC89B23D7D07D895C930F72D661
-:1051000014B98528B42E450662A9F533C1FD0DE01A
-:105110000F4D2368BF9BD37CA49A968B534800CF36
-:10512000FF386FEEE6B33F50143FB041E90BE3F9AF
-:105130006C4CBECCB3FB47DB306FC478EF82BA8FC8
-:10514000ADEB22BF4F2176BE17CDAA05E479346EB0
-:10515000C7F2066B25E563F0FF92435C2EF5583FDE
-:10516000E3B3F39E14E4336D1DABEA3C284F56D4F1
-:1051700079B15C5E574014CC77F661DDC4E16129FA
-:105180005409F8578107E1CFE2ACF0C37D16302611
-:10519000C4534DCE00D297C55B83BE022B8F8B9A32
-:1051A0009C2AA976429E078393C959817092795DA2
-:1051B0006A9B8070A5EFE3F3B1F6C00CDB08C83F33
-:1051C0001E6A9053725AB1A1DE036E1A5DECFEDFC7
-:1051D000861F4178ADA8B36209F9E20037C8178786
-:1051E000FAFF07F8B530F85D47141DFF40FEB662C0
-:1051F000E0A704F0DB40E19716E5AB5838D4F23C69
-:105200001D8D9F12F12FE4DB4310667D5D1B96DA46
-:10521000F394047AFDAC8DD923B524B014E3A11E18
-:10522000E68721692AC9D4F99F8857C5732078DE9B
-:1052300014DA336F41FFA5865F93473A69947FCABA
-:10524000C7B09EC56F9B459057A6DAADE4335D1C91
-:10525000DF34A1C2A6209C7D02C4351AB87E5DD67B
-:105260008D4F237FACAA53B05CCDF9642DE79375C5
-:1052700080775A6FF0B1FC9F967104F5E763B4CE66
-:10528000F6FB61A2F78B27FBDAC3668A7F94490A93
-:1052900096EC1E8E2396D020FA9EA390603C23F9B4
-:1052A000C8CF42B856D28EE7AD93B57B605ECD4D88
-:1052B0009E8A712062667A8A98581934C33E2A16EB
-:1052C000BE0DBE0378BF44A2F9941D9D2DC0F72EDC
-:1052D0004E65B1B3B47BDA8FC07D10CE16073BA705
-:1052E000E8AB19908DF2D582F4EAF405846A1D1EAC
-:1052F000D313D87F4BECE3FF03E8F113C84BA4F8BA
-:105300005DDF3610F35A5699DBBD200F57F1F31AC3
-:10531000CA140A05DDFD626F7039E92E31CA014DEC
-:105320002E7BAE2F36D0B3267753C618E95E93BBDB
-:10533000BFEE96BB156741EEA64636225FC6F24128
-:1053400083595685ABF13E1AE67F3A26B0FB327A96
-:10535000CA038CBF9FEFCCD902E7B135FE895DBF90
-:10536000D43C1EBFD36D0F26C87FECCFEF6568A677
-:10537000F446F2215F414144ACA174066590D21914
-:10538000E3A7522C353AAE274C86A87B45364FEE24
-:10539000AFD5CEE2D45B8BFD80C765ED8C87B2ECD8
-:1053A0008CCF96A589A0BB8844F7934EFA48DA3F84
-:1053B000CA0AF6A56466F1FC2E97D80EF1DC65CE1C
-:1053C000C956C82B15924B907EFEEEAA1CD05B7C72
-:1053D00007EE5F03FAF3387DE438EDB78CDFEB645A
-:1053E000F21413D897EE7676603E94D32E1AE249E3
-:1053F000F3EC815CBBAE5E045FE77887617727B82A
-:105400001F6A185F0FC954499E4E4E74DF97A4A8B7
-:10541000A440272FEA07DD88F731F5941309E4E16A
-:10542000F6FF1979D83020847835C7CA9F343FDE1B
-:1054300001454B15AE56A0D6F9B2BB87239DDE6061
-:10544000877D88734BB71DF4A3DC9EF38C957F5149
-:10545000BDA6A01F8CEAB5C74B419E26D46B35F77D
-:10546000211DB7F457808EF7AF79F869A87FB6C6CB
-:1054700082F7BE5445561085CEB73A320ACB596DE5
-:105480008F6259D9B6993211214B5757AF990AFDFE
-:105490003798D0FF733274CDB95A5A3FD96241FB65
-:1054A000FDE4C6070780FD77B2C5A198C0DEDF38EE
-:1054B000C2D8DECCEE7F39D9660E9918FD5E324136
-:1054C0003C8270F90E5E20DD7C49898276FCF99879
-:1054D000784BE55A8B5F7027867F655B7C7B12CFAC
-:1054E0006F63726E4D3EC8D7B2A33F1B00F4A1C9D3
-:1054F00099C52954EE01FC8E5A48BCB8C058FBD857
-:105500000580A7B176FF6286AF2BBB37EB3391DA0C
-:10551000DD88A7807B92C1EFCBFCAA9F71BB9C5812
-:1055200013B4BBF9FB9EF8EDF35AFEF2E62304F246
-:10553000548D7E6D13F8AB05D88F4F62790F5A1CCE
-:10554000A8275D337BBAC582726506F74769741E6A
-:10555000A5B3809B9FDB33D0E1ECC83A947BC2AA11
-:10556000A2C74751F87D45E90FE8435835BA2FC027
-:1055700077E9CA1FACBD878EFFF53B267C3E2B62C8
-:10558000C3FE5F3EE27BFC1ED82FFCBB19F349BE75
-:105590003E3416E3C95F9A8D7E8C32079397AF71C4
-:1055A000FEAF8AAC32D8E755CDD365F0835645D6E9
-:1055B000E0F32A0822619EFC5D6F9449105F2298F7
-:1055C000E7F29AFDCEB1F5A84F8BD18F56BDDA1216
-:1055D00037CFFF35BB629057D59D2D382EA1F65998
-:1055E0005A3A1F4F2777AA23A9C81FC4A312C8FF7E
-:1055F000AEE2F2A77B7E1BCD06F9F3A52DBE9FE69A
-:105600005D3B5B6755E407C8773DD7F7437C5EA5F4
-:105610007DB793F169743D8F8F8AB79EE83AAEC724
-:10562000FE5F26C7FFFE050EDF9375B3889FCAAFE6
-:105630004A0BEDE784EF3FD8540AFBFC8DC9298261
-:105640006E5DD56D73885FB7AEEA8DD364FDFD9452
-:10565000513C2C32E0E1C2CA05888725F68A63A056
-:10566000072A578D1E16C07DFE0A84F367665F36D3
-:10567000C8E3536D0FBAE3E5175F88C54F1BC70F2B
-:10568000B5BB4B74F8D1F012FBFEC93F57FFFD11BB
-:1056900090531B5C06B9125BF6C05B4E7CB825715B
-:1056A000FA3C49F57700E1A6BC7804E87AB503F343
-:1056B000E412C3EF2A12E80D7E09EC676A67591DF0
-:1056C00023E0BB04E150DDC6E8E072708B7E97D327
-:1056D0004159FCF58C766874504B54CAB0C7E5CB81
-:1056E000D1C1C344B5F6B28E6E3A687BA32C2F4A63
-:1056F00007A31DC1B1F5B4DF1760FFE4F7C4FF7164
-:1057000059755F07F6CE4A13C6BD8EDBD5F4BB587C
-:105710007D38C8E7E3EEE0C4EB4AA2F5D9DB07B970
-:10572000F5F73A9E6AA6708803BFD18E04F493A75A
-:1057300092C291FFEFE8E73373FC3CD1B1F6B2328D
-:10574000C02709C6F7276BA526BF4D49CEEE7D2F92
-:10575000E8D1E3CEDCBF8768EB1A7BE056076D6FBC
-:105760004C7E08F5FCF1E302EAE1A57F5E9C0F7236
-:10577000B887FD5B1779E2C420F45B3E79C28CF6F2
-:10578000148E4BA8FD037A00CFD7E03EA03FFA5914
-:1057900012C5731F84CB7F4744E3BA5AFC76595D28
-:1057A000C7A3303EB1AAC4A39DD757A064F6D87F43
-:1057B000C23C74FE79D91CF0C0B92159201540F7BC
-:1057C0006629D00CF986666FDA705507E7850E9664
-:1057D00097633B78B03987BE6F9BF9070FF8F92CB8
-:1057E000F43B505A33A5F37A7FB939AD9DDD7794F8
-:1057F000A77B9E0BE7A269DDE077A0F3ED65DFFCF8
-:105800001BA1FB9E35BCDF78AA76D117808ED2CD46
-:105810001FB5FC15A991B5276BCD8DAC9DFB51171C
-:1058200054323FE9EBD392107EDABAA6BEBA1CEF2F
-:105830005B9BFA6A069E739AEACCFF1CE0F91BC8D0
-:10584000FB01BA4F66FA39962E1EE5F2E7EECDA2BD
-:105850006AA6E31D34771D70005FFC54C07DF55DC2
-:105860001F1E3403C9FFE9F07133DC97701FA4EAEF
-:10587000D0F54C238ACC8CE810BE3F9DB4BB58BDFC
-:10588000BD0FDC7F1A1D8F6E9961BC852CFE7CD705
-:105890008787C7821AA5E32D83F2BE77880CE34F72
-:1058A000DBAB34B163517CBC57E9786274BC6EF8F1
-:1058B00049568447143E568497061FB85E04DBA3FE
-:1058C000F0457B45836F03C08DC26F6AD2949BC93C
-:1058D000B0C4FC32D539F873765E8CCD2716BE5F26
-:1058E0004313E5B7A71CFE3DC07F8D0EFFF3C03FFD
-:1058F00073AD5DD9522E9E077B119ECF370506A44E
-:105900000FC47362F97D200FAD237E9C37964F8FB5
-:1059100002BF5C0D25E50B98073FB7722F5FE7EBE1
-:105920003F3BE5C2F328FB3ECE86729EA973F59DF0
-:10593000C06FFF6642FBF3FCDEFC5EF3EB8E72BFD2
-:10594000CBBB0E7E9E88AFF33E6ECFDDB7D7118204
-:105950007B10EFAB3575EFAF80AEEFAB65F9274449
-:10596000EA1876BBC19E6CE4F1909EE3C07E21767E
-:105970001C6D9D07B2FB5D05FBCBA747C8B88FD850
-:10598000FFCEF93F56D3BA3DCB8AFB84D5C99C7E66
-:10599000CBD8BEF5E964BFA308FC5F2B537C2A5D1E
-:1059A000E7CA3748BB48E17460C843A1F212B81790
-:1059B0005A44DFD9DAC8D66039BC57C8EE9DF170B9
-:1059C000BB746DC7F136A0C753472C1877F8D2C502
-:1059D000CE13AE345764831DFFF96639EEFD679F21
-:1059E000BA249CEF66A153003A9F4E825690177BD3
-:1059F0003B26F785F9B87DC403E47F6AA34964F7C1
-:105A0000A369FE96B0C4FCFDAAC4EA7E5E7A6CFA75
-:105A1000FBC6568C1B83791E335ADEC3BC5A7709EA
-:105A2000F3DBC5CE23C9C9E6EBEA48C17C52D718DF
-:105A300011F3B15DBE2E01DE1BD0512EE3FB41A15F
-:105A4000D7F7072CF18C07B8C2FB20E7075CE1FB16
-:105A50001627CBD35AC7F7D99BCDBEA631749CCDA0
-:105A6000AB9305C087D64F7132B9726A8CE6470A8C
-:105A7000A21F293BCF63837B2CB2FDC8DCC4551227
-:105A8000C4FBBEB7403FE66745386C1EF26218E2C1
-:105A9000D82BC1BF027836337A5AB95A40BF2A850B
-:105AA0005F3FD0139F3F66B905D631A059F0C0DEE5
-:105AB0009D9671E73DC5656574DEF238EE0BC14D0C
-:105AC0000BE3666FFC00E7E54AB0DE7A17BB27FF01
-:105AD000F3CBD0C7570E766F62766D07BF1F2F8C42
-:105AE000F7E005B57BBEFC25EC7E13C9AFE8F36398
-:105AF000A2FCB394D321F1439CADB2540E811F415B
-:105B00006CDE3C05D63D3D682137D1F5B5081D7EDC
-:105B1000E0177584C8EF53F21F0538AD59D717F356
-:105B2000F0968BFE6CD0C3EAFF91314E77C07F7E3A
-:105B300003DC1FBFA95446BE380070A7F5A797E441
-:105B40006E8638A5ABB6BC6D3A1D2FE49151B234C8
-:105B50009490B7F3214EB944F408B47FB042CBDF40
-:105B6000F6E0799EE1A6AFC617401C2F43449FD2B2
-:105B70002981DDDBB06C49B907F0BACC9326E8F790
-:105B80002F77723A389A5271A793C2C7FBC87A0F1F
-:105B900035E3287FA65E057E44B55956B6B3782115
-:105BA000DEF790CAF192DA2186ABDC5877CE4A81D3
-:105BB000FB7499BFF4D19B03CCCF09B1D191E8E735
-:105BC000E47F5EC46B1AAFAD1C6AC74A6B7D15F6E5
-:105BD0008771D2E938A9256278241D774BB27F13EB
-:105BE000FAEDC65A114E44EA6C033885C6F6C3BCBA
-:105BF000F0F5A306BF07E758520F754D063D1ACAC8
-:105C0000B2FF6933C8A965B2027C9EBAE4E43D786C
-:105C1000F99BEF170F4299DAF8D1C320A7933BFF06
-:105C20005687CFC7C906FF62EA275F7E0BEDA9152D
-:105C3000B2C14FF94D4AC5CF012E9B0A8341BC1713
-:105C400013309A1E5DC7EEA51DE3E0BEE3539344F7
-:105C5000DF16DE8EEB6AF5845632B895805ED0E0B2
-:105C6000B65C54DAC3B0AE8956A48F3CD281F22A16
-:105C700003A2D903A37849FD64C542C8D7889DCF44
-:105C80001AA7D07DFF06DC1308B882FC1839630C14
-:105C90009E43DC53DCE1057B7E7582FB73DE75B1D0
-:105CA000F72D22F3B3C6B6BFED62F40022B1AD18F2
-:105CB0004B7F11944EA226419969C5FBE6F688CA2E
-:105CC0007F209DAF3729801FE86FA6F8DBFFF669BC
-:105CD000F42FEE0F7E80E5B3AE02FC1E6D0FA7D34E
-:105CE000F7D794B0FB8ED778188D5437337951EDB0
-:105CF000EDB442DCA4BA9078B6707A53353883BFDD
-:105D00008CEBABCADB195CD30A09C67DC11704F75B
-:105D10004DA5433F0ABFB4E6A50B118FA4431D4810
-:105D2000FBAD8171013F8D2CAF9F904E2BF26FD058
-:105D300084714FCAEFEF825FABB2A52FC6FDE1F8C9
-:105D4000308C97C2BF9BC2C7DB4CC701FFE1A9667D
-:105D500013D982F2AD03EF675796505A46FAEC2AF0
-:105D600083F39A4A89C7B352A3034D8E51D6984103
-:105D7000F505C06D86AA2E04FA3B6EF5BC0DF370D6
-:105D8000B45A1458FF8CD6971683FDE2F07636830A
-:105D90007CA82E65F34D69A1CFD1CE51DE85FED50D
-:105DA0002D16857D8FC3AF84D31987C34C3EEF99E1
-:105DB0001BD9BCED59A120D067F5120A57680B30EA
-:105DC000BA0797E82511F9EA10ACDFA5A6E3B87D7C
-:105DD000A6C4F0450CFD69EBAAE4EBAA5CC2D6456B
-:105DE000383FD1698561DCCA12B6CE1984BD2FC295
-:105DF000733AFE4CBE9E4AF5452C67365B0CE36F4A
-:105E00002AD8D601F3C92994153C3742D87D87D9C1
-:105E10007C5DD98DEC7BD9852F22BC48AD6EBEE868
-:105E200057D5D5295F9D7A8B3216B573856C2B12A9
-:105E3000D3F19FC918CFC96B35AEEBD48AFCAD70D6
-:105E40001EFCB3C7648C7BEF117D4707E07E545680
-:105E500098FCF17D3001E4F4CC461FC8F1DD650CFF
-:105E6000FEA76E2521A08741872A5200DE830E05FA
-:105E7000785983F1740A10A15BEED1F9D12D53B397
-:105E800000F23232F0B95920074AD9399F2CFDBCB3
-:105E9000E9FC529BD3CB211F2AAD34A55CC6AB5D78
-:105EA00063DA0F3D315984F6834F3C08DFC920BACD
-:105EB000F5D076D93D909D6B39485BA15FEDC94720
-:105EC000001F2DFC1EF24130B3142C0F42994AF9E9
-:105ED0007B550ACC53226374F7586E7F6C249E0363
-:105EE000C794A7622CC324CE3D97BAFE43787F5552
-:105EF00088D3CFE5560CFBF3ED8FDD3804F6F16B5C
-:105F0000C04E4C8273BC9EAF204F47F58908F735D1
-:105F1000E6B0B590D69753BB11EC97B5051F89C075
-:105F2000776BF6121FD0476AC53F2D7A3CDEE462DC
-:105F3000BFCF23C96415F0FF812127C7019E42FB13
-:105F4000A9DD49FB97FFDEF98403ECA13FB23C9841
-:105F5000CD6FD5A0FE7E285B8E7B1F2FB98C9D1840
-:105F6000DB3F65D064F4E70D685D370EEEF7AC1EDD
-:105F700027F96EA2BDD35ACBCAC08E512A2875F517
-:105F8000A5F3DE387C2930A13281C5CB9471ECB900
-:105F9000328695ABEA0E3D0AFBF6E04EC99647E71E
-:105FA0003B7405BB576C55E1796B80DAA52565CF4D
-:105FB0005B6FA5CF4F94502D489F9FB8FEBC0DE25C
-:105FC0003B4F9794A7023CF7361BED3A02975DD101
-:105FD000FD509125E877D179B57C48109E264BB8C5
-:105FE000AD92D64D2F39C1C2E9B1CF59D1B2790A9C
-:105FF000D0E98C0219DDF6B1EBFD88EB93E9B55DD4
-:10600000E3E07EFD1C9530FF7EF07114CA33B9C801
-:10601000C8513B50E8B85AD9FE2428F9DF04B91C0E
-:106020002C0CC8F08A26CF5A0655EE0079F6676E1A
-:10603000D7919A5978BE0CF9DF04F6505759BC7DB8
-:106040005389D38EFD4F6DBCED63F053CFA865F639
-:10605000FE808D5F09880F6AF765D0F10794E055DF
-:106060008364C692A0B508F09327124581F9B41352
-:10607000D82704A9FED1C3411BF7BFFBFE429705F9
-:10608000F9B0046C67DD7A9C7C3DD93EBA9E387AC3
-:10609000BA987FF7A74F7DB57F14C07F09DB220D2B
-:1060A000081E13ACBA790C50AF6C1ED7C07860BF15
-:1060B000BAD8F9535749279E938A95EF60CE03DFEC
-:1060C0006E729C1BCEF6F74679DAA3CEE92AF679F2
-:1060D000768CBC2AB2B4DF8CF8DDCDEEBD868C5850
-:1060E000681788A8B07B3F43DAFDD435D06FA8CBC2
-:1060F000E9013A6819F25131C06735B717661612CF
-:10610000DCAFCECCEC407B617A23B717245F130859
-:1061100059C7C664B252673FA0A9045BE8466E2F18
-:1061200068FA9FEBED6A6F4733EA55B00F747AB5A2
-:1061300052657A758097E9F5EA66FA1D8513F3488A
-:10614000BD5DC2F4B8D2CAED07AE8753F977D39AD2
-:1061500099BE4A053BC20D69102AEA658C61A547C4
-:10616000ED963E854C5FA6B6EC41BDD60E87B64790
-:1061700080DC60FA32EBBDC32A80C94B1FB75139AE
-:10618000FD246FF77AA87D9612B5CF968B3CDE443E
-:10619000987D8839FF749E8F427F9DDDB88DCF6FCB
-:1061A000CFC1945B40BE6E0FE6E2F9728D6FD1FBFA
-:1061B00049EBD9252C7F25BB96C5C95DBEAA1D26F6
-:1061C0005D1C62968BDD3B344BA3ABDAB017C60D7A
-:1061D000C2FB28C7D9FD3F2BE0BE1EA017BEBFBA29
-:1061E000CEC9FD1A9C7E12E9134D0EB988DF5D48B9
-:1061F000E17B22B403E5B54AF74BB0B613C1867E06
-:10620000F703BF072795C0FCD78CFA3BE67F0C4805
-:10621000B05FFC54DB677E47B9EE1A7798ED433BDD
-:10622000C4B8E77B32DDCCFFD02E1107C0D3166493
-:10623000F7C8D94AE5B8FD93DCCCCE3ECDE1B666D1
-:10624000D40E3CA799503F4B4435C5D1A79ABE6D9B
-:10625000013C5F47FBBBDE6E52719F1EAA30A17CE2
-:1062600025B8EF0C924EDC47AA0532FA0D5BCC4103
-:106270002BE0636D09C7ABC7BA19CEFB7E67BC5074
-:1062800078009E57F8C5909003780E798A985F073A
-:10629000EF413845F7EFFA78C510B7C8E1A4E00F31
-:1062A000F30D6866F4B566948CF358393C7DB329D8
-:1062B000472F7F052E3FD939B195A3DE44FABAD2D4
-:1062C000F955D53EF7D4095D3CF1E486677201CEFD
-:1062D000BA7B307A3D4F5155FBB7D66D71E204DD84
-:1062E000EDB08F72C23E30749721AEC9F13BC62D1E
-:1062F0001AFC6E205FCDB8B908F503FFD2EED121AC
-:1063000037BC4796B0B8ED6C1EB73DBDED363C5777
-:106310005E44C9CA1C07EF5FD619CFDF7FB9FD996C
-:106320007ECCAF1132E409CFDEF1CA50437CD84FA6
-:1063300094B491EC1E63D4D36FFA548B297A0F81F5
-:10634000763FD695DEB79542CD30DC77910A2CD3D7
-:10635000490D965E12C4B21F6967E766619F3B10E4
-:10636000F44217960AF1884427F773890FEB79A452
-:10637000024B09F0961A8D4B483BAD98BF01F10BCB
-:10638000E0FB44E7CE7CEECA856EE4EF9AABD9EF32
-:1063900018B178C564B7FF0137E2218CF27B3A1758
-:1063A000E5877E35B41DCE1F3DB09A9D7BD1E43B81
-:1063B000EE6FE8779E4B61FA405D2FA01CAB774CE7
-:1063C000FC21C2B3C57C461F6F20566B1EFC3E8865
-:1063D00036EE74EE6798CEF520B8BBD9F9411F9E12
-:1063E0004F9A0EFE065D3BE96E67F7D968E3888E2B
-:1063F000EB07F716EFD3BD8FF9D19531FB80CBEAD0
-:10640000EF98FA8CD8F7BFA1134A8FFAE39EFBA14D
-:10641000928DF4CAF537252805DF6BB61CC3FD58ED
-:1064200070AC5F0F9767391F687A65464CBE476C42
-:106430003943E2FC11330ED580C970AE17EF96D008
-:10644000F1B7763FA9F6BB5AB3FD013983BDE60526
-:106450003C7AF8BC83646379062DBF80BACEBF7FD7
-:106460003829F0925BB71FF1F86B44FDBD377339E3
-:106470003F8E35B594819C3B15203ED847CC2635C0
-:10648000EE1F803FFFB009E55C7F3A6FB918EF1D42
-:1064900053C514ACABF07B2F67EBD839A193FC7ECE
-:1064A0009A1DFC7E9ABFF07B858BDA164F043A3832
-:1064B000CDEFA529D8BBA202FC3E45ED8E69A0F721
-:1064C0008BDA4757437BD14E0BFB1D1F2E27B47928
-:1064D000C1B96C3BFD4E26FD9E3505E40941BD7BEF
-:1064E000B6C51E82DFFF39DB6E62F7AA168A789F77
-:1064F00003DC8B66E2F34B4A81EFFDD7BD608F9CD6
-:10650000E6F2E48C3B99E14B5205350DD252880FEF
-:10651000EC9A758EF9780EB2CA19DAF1441AE4874A
-:106520005B7DF5F4FBFBF7BC940DCF1F77CCC7F276
-:106530002F1B3ECE06B97576DFC7723CBA9D278504
-:1065400065F04FCDD92B88103F296B9F26437CA443
-:106550006AD77EF42BCFF304B07D6EDB1EAC8FD9EF
-:10656000F51EC64F06262938AFB31901F4F3E6B578
-:1065700059C2F07B1CBB7383F7C78DDB27313DB35A
-:10658000CEF11A8EFFB8E3B537112E1B2C78FE63BF
-:10659000FF86DFE3B867F6BDC4E74B305FF0ACAD14
-:1065A000FDE8CF417FEDE1E731AD1D6EBD3F584ABB
-:1065B000120CF2F5AC8BC7BD322FD38FE70B1267ED
-:1065C000879BC9A50E37C4CDAADA191CFE620ECB73
-:1065D0006047CE691714F83DBDB25D9BF13CE09C6D
-:1065E000BD563C2F3107E00170A3F042B8B4EDC7AF
-:1065F000F9E7025CFAC03A3EC07CFCBCBD142EC375
-:10660000A2EB9EE30C20BF6AEBA57060EBDE7D3948
-:106610003C058C786A7B4F06BFCCDCBD02C26FEEB6
-:106620002E368FAABD6C5E63764D43FC9FD947140E
-:10663000F0B79CDCF3F16958CFD97D56BCCF579B9E
-:1066400017A553E22E06FE61744AF632B9AAD9DDC7
-:10665000F342E9F8BB03DDEDBBD8EF9202C86C94BE
-:106660005E8BF64EC2B86009102FF0BFA77D28FBE5
-:106670007DC16036C075F7E87036CCFB8CF6FB4800
-:1066800052301BF0E273074A9274F8F8F2D84BA824
-:10669000170BC49A4F1F013E7E5E44BB68F127EB87
-:1066A0000CF7ADDC003F483502E0F6AE1BE1D67DCD
-:1066B0008F4B90E54B9100F26315E7C7B39BE9BEA2
-:1066C00093AEFFCBB617B0FD6C8631BFEA2F6DAF2E
-:1066D000A700DC2AF9790C12BA0DE511854BB33508
-:1066E0008E9EEF3ED71662E715CF09FC5ECDA7342C
-:1066F000B8D5C8930D713E260F3337E61CC47D46CE
-:1067000028FE39C7583B29F6BED444F900C7B93C26
-:106710003BC1EF3FD0F4EE6477605A529FC4E7BDAF
-:106720002B57CDCB067857C2D948BC0775FF4DE033
-:10673000AFC07343EC9ED430C0E7A4760F2A79E94A
-:1067400026C8333D99CCEAB5491DCBC1AE3DA9DD84
-:10675000ABAABEC1DECF61EDADD04EFBFFCA5D512D
-:1067600093C4EC7B81FDBE8F39197EA741D31B8971
-:10677000E160FC9D8667E85A012E74BC9FE37812A5
-:106780001DAFE8FB8FA7C9E9EF3D8EF57F761C4D65
-:106790007F017F42EA23F1F986FE4FC0EFBFFB3E47
-:1067A00009CE34F0D5C50D039B208E7681DF23639F
-:1067B00069594A409FCF6C5D17F7F7DFBAEB3C2F62
-:1067C000471E48F94DC7D78792985D7E88CB69F8F8
-:1067D00083F89676CF24FCB5A463EA12EE9FF3F912
-:1067E0003DE6052488F6E950D28E6521E9C072188D
-:1067F000E9C212C3CC03C155EA33F1FB6847C2E2D8
-:10680000E75A034FDB44CC3B7803E410DC4B2B9876
-:10681000C09E9C7F1DCCFFED240F8757D8F07B2BAB
-:1068200044FF7B180AD88313BCBDD983C4239DE9D8
-:10683000CE7BC9C57B6DDF4BC2F525FA1DB5853111
-:10684000F7DEB073E11A1CE69176CC237963E3039B
-:106850006F0FA1F0BF7F970BEDE4C11B1B17823CAC
-:10686000BF9F74A4C339E1C1FC1E11D266FCFDA612
-:10687000216D16E3EF08C7FC5ECF1CB88704CFEF8D
-:10688000199F6BE770F11EC838F918B1E778FF9AC5
-:1068900014FFDE175218FFF75062CFF1EE6A17317E
-:1068A0003FEA01C8BBD2ED2F866CABB118E94BF9BA
-:1068B000B73CB3AE2EF8983FC265F76F177A7EE704
-:1068C000FF020F2194E60080000000001F8B0800EB
-:1068D00000000000000BDD7D0B7854D5B5F03E3391
-:1068E000679E99849964924CDE131E2128E004432C
-:1068F0008C68EB49881811EDF0A845DBE20404022E
-:10690000249940D1E22D2D131220206AD08840090D
-:106910000EF828D64727BDA888813B20225AED0DC6
-:10692000D5B6D45A3A20554484F145B9BDF57AD745
-:106930005A7BEFCC83A460AFDFBDFFF7A79F3DEC90
-:10694000B3DF6BAFF75AFBCCE50E85B14CC69E5654
-:1069500094DBBC2319FB12FFAE893D6FB1EB181B12
-:10696000CBE0AF8D4D2C67ACB541B5AF81526BD04C
-:10697000AAE99DF0B4EB824A316379A9D5E6F950D2
-:10698000660E9D7D989BB109FAAB0FBAA1BDB151BE
-:10699000BDDC04E5FDDBE6F71AB0BF4B6526983297
-:1069A000CF01E34299E5E882C3A0DC66FFA5631648
-:1069B000CC5F6283F7304E819D05DD30EEDEAD7732
-:1069C000EAB0DCDACC5836CEA3F87ADDD44F658F46
-:1069D000E1B29836A92C8BB122FC27CCA3B2B51F0B
-:1069E000EBD318AB693C6E89D8E07DA46E121BCD49
-:1069F0005895BD98F6A9BE73FD0758DEB2E498C35A
-:106A000007F3BDBA75E56F26C0788620AC0B8628E3
-:106A1000FDA2F5ED09305F74AB916D633138142E32
-:106A2000558F45CC3421FB12FECB5F9C5836322863
-:106A3000978A7231AE23AE1ECA978BF9199BCEC2CC
-:106A400059582FD6EBD418837532BBCDF9DEA58CFF
-:106A50005D6357D8978363E5B1A2BCDDD0516D85E6
-:106A6000756EFF93E26981EA7D5BE714E1FECEBEBD
-:106A7000E02BB2C33E9698D346B341E79F9FC1EE49
-:106A800016E717B0E85CF80C5B982BD67EC4A3CD54
-:106A9000261F8CD3B68C798E0F63CC1CDC6FBD1493
-:106AA000CFF1A0C10345B64261D34350AFDA981687
-:106AB00082792E17F892FC5CB1CCFDABA186D8BCD4
-:106AC0002BBE983A1DCF379A6AD5B629E7AF4BF659
-:106AD00053EDEE009EAF219F7952603E83B337D7CE
-:106AE0000EFD2E7DDEE8B101C826FC62E4A008CCD4
-:106AF0007BE94BB730772A8717AE575D62F41CCF1E
-:106B000060CCB4C4E9512FC77636C2C74F6CC6A05B
-:106B100009E1BFE4EE0EAC6FDD5AE172C7E1F5CAE0
-:106B200065768F0AEBDCBCCCEC5161832BC5FE9201
-:106B3000D757E0D07983D0CFA8633EAC5F04E7801D
-:106B4000705C644FA1E74251EE52035370FD5D80CB
-:106B50003F2D88AF8B39FE2ECA310711CF17BD3AB2
-:106B6000249BF54357F2F9F832976728AC63F3E2B8
-:106B7000992E065DAB16EEB75C07FB5F946AB623F1
-:106B80003EEAD34A1EBA1AF1FD350343BA6A4DAD47
-:106B900070CF8A1B4F9F56E94278E875815C666723
-:106BA0006C957D46AD9A83F812D8C43C8CDDD771C4
-:106BB0002D2FA7067215A87FA8E37A5ECE0C6C5223
-:106BC000A0FEE18E1B79B92090AB83F2CF3A26F379
-:106BD000F2B0C0262CFFA2E3DBBC3C0AD690CBD897
-:106BE000F31DB7D40660FE568367BA07E67D06D666
-:106BF0003F12D61F12CF17ECFC5C65FD2FF13DC094
-:106C00007B877826D73F27FAED1CA07E97A8EF193F
-:106C100060FC3DA25F7880FEFB44BFFD03F43F2093
-:106C2000FA1D1CA0FE3551FFFA00E3FF5AF4EB1DDC
-:106C3000A0FF6F44BFB706E8FF3BD1EFF000F56F50
-:106C40008BFA7792C63F22DA47C4FBFCD4F6B7032F
-:106C50008077F9C0B7F0AF34B53D1DF16E7373396D
-:106C6000E17FEB58C0F391317CCF579817CBA31D30
-:106C70002A8D371AF9313CDF14E3572D1C7A1FE2B5
-:106C8000DDA237F41EC4C356C573D807E30716EA5E
-:106C90003CC87717BDAAE778BE500DB238FA7E33EC
-:106CA00069FD5BC4FADAC47A7F651F4C7453B4C4BF
-:106CB000E59924F925D2BD3DB16C067AD260FE3645
-:106CC00027972FA50BABCDC3517E807C41BEB9C2A7
-:106CD000660C9B60FE157695EADB9CD576AC0FD8EA
-:106CE00055923F2B9CD5E659C8576DC0EC2A603EA3
-:106CF0003B1FBBCDAED606917F386AA87EC22F2639
-:106D0000D9918FB6B1A8A30AF7B714E40AF4DFDB70
-:106D10005C4DEF8B1C9F39903F1F4AE7FBDA9F7A4F
-:106D2000C0520CEDD43B74242F4AEC2AC9B1C14B9C
-:106D300075413734D96F5FA4C3F2236D5C5EC15FC8
-:106D40006A19CC3F944FCFB6DF59F15A29CAB37BA9
-:106D5000548FDBCDDFA971F26028CAAB349C373D7C
-:106D6000415E7595330DC70DB8CCC1C760DCA12A53
-:106D70007365A4C7E05EE4D073F9A29FE441B9361D
-:106D8000A423513E15B7C7C92786F232513E25CB01
-:106D9000AB8266E08F71FD4D2E7B42D9E24825F92A
-:106DA000043CC6F3254CBDA87BD1755616E3D7C964
-:106DB000F2A855C807C9775BBFB83C413E48BE9CA6
-:106DC0002C1F2ECC5FDFBC7E38E121702BF785F9BC
-:106DD000EC9B8807807F069F42F283A93E9737F598
-:106DE000C2F03218BC76BBEDC2703364BE457A8502
-:106DF000C1A7D2F8E7C9950BC055B6339A1FE93A37
-:106E00000E72EDB3777E58CA806456026CE8FC338C
-:106E100075C1C760DFF94B9EECC2F1F30E58DB1071
-:106E2000CE46D7ACAE36DC4FC7438C013EE9CD1C15
-:106E30009F8C39D576ECAFEA3457FA10283FF1BB76
-:106E40005B15C0277D46B387C1B91D7CE6B5F41B31
-:106E5000107E6F1888CE4D3AAF9D0DA1E510BEADE6
-:106E60002AB06E5D4378EC33239CF2B79B490EB099
-:106E7000C0A3AB3540EA56380E360EEBA7AFD6604E
-:106E8000DFDB95BEF2F5580E058DBC3DB068FCBF4A
-:106E90006E9D22EA99A6BA48EF14F5BFACADB91AB7
-:106EA000DAABF64B55903B8BD63DDB6E28C07A9D16
-:106EB000ECAFB14AD82FCE27CA2A9CCF93FB457D91
-:106EC000E0A5F61A20A26EA39C9F05B07DB74EC721
-:106ED000CB819E761CFFE96AD13FF0F86A2D9FD6E0
-:106EE0007383DE0145C72BEDB62B63EB5D97FE4642
-:106EF0007B0BECEF2377240DB6C11AB71ECF42F9F6
-:106F0000BC6A7AB317E18688EF05993848EF263CCA
-:106F1000ED3BB71D930379507BE6C0DFD246429527
-:106F20005F1F399002F06BDCD96C36407F93C11B38
-:106F3000C82B8EF56BDC5147FA8CBFA78C9EFDF4F5
-:106F40003BA80EFEA7FA998D1731DF47E1DF343DEC
-:106F500005558DFAE6769B9EDA337EFEFDEF4FF601
-:106F6000FFE8A9DFDC8CF39D7647B22642EB556142
-:106F7000804B3FFD64FBA69D93E9793845BBCF016B
-:106F8000EFE702EF227EA5367BB07DC8DC61F7001B
-:106F9000A02D860E2FCA0D007D5057197BDEEF18ED
-:106FA0004AED93DF27D357C8CC3226211F6F5049B3
-:106FB0004E85CC8194D1505E0B76480B2C6979D9E3
-:106FC000EFC68CC4F2B3368676496BC37ED748A42D
-:106FD0002B8F91A1BEBBF6CA500ED2795BA371FA7A
-:106FE000A388BFE145AED971FAD6BA7403AD63F593
-:106FF000CB407797C1D3107228D87F18C80D05F9F8
-:10700000A2CF8C768E25279D058AB19D6D2DD2E766
-:107010006A83AFB61ADBE5E848BE58864DABAD864D
-:1070200075B832758A9ED65173780ECA37BB112552
-:10703000283B923E7327C2E949D5D38C74F8A4CD7E
-:10704000660F4005F0480DF99F3ACC19C4B249CFFC
-:107050009A518EE795813C8FD3638F08FE79C46186
-:10706000247EB7D6129A5C05E35817E9EC01986FB5
-:1070700075E3FADE0930CF4F1B9F3BD402EFD76494
-:10708000A90CD76173AA6123C81FC38DB04658F7F6
-:10709000D32D5E3BF2D768A6CAB641BD75A891B99B
-:1070A000E3F8956D2494E3F8648653D52CD0FFEF74
-:1070B000E9BE7F77C0BC97BFF19619FBBBC6EA74E7
-:1070C000483621959F735A79E238F6AB13C749AF1A
-:1070D00049AC774E4AACCF9A9658EFFA5E6239F7D0
-:1070E000F6C4F274896FC0736C208FADBC8A5923CB
-:1070F0001F2F43790BF0F903C2DF5AA2F3207C2C37
-:107100008D8F9E9803F579C84FD01E1ACD48EEEEAC
-:107110002BFC1737EA05A6F466B763E4F9F0C82B31
-:1071200030DF80E7651BAADA19B4B7BDF3C11738A1
-:10713000BE8DC5B52B46F8685147262FBB603DA9CB
-:10714000F80F37C2BBF9CF3F46B97848EF4178E72F
-:1071500035AA34FF3DD3DC413DD7275CA8CFA489B5
-:10716000F669E6B5BD7AE0E769EFAC5E88766F3226
-:107170005CB358B3827409F8C1EDED3A46F26395F9
-:107180008ED523DEA08D80E3917A04FC626A86911D
-:10719000E0644A5784DDA8EAB03E4BE84FC69CDB6A
-:1071A0002D48C72B0E70FC5F61E4E3F48DE7A64920
-:1071B00011E519F2C98C745DC238EBEDA28D286718
-:1071C0003A78B97B7FFA0D4897EBA7A58F413C3100
-:1071D000A1DD05E30DCA376B23607F96578D01054E
-:1071E000061DA4B2FD0638CB6E2BBBCD0BEBD878B9
-:1071F000D01AD0C37BCBECFBEDA8A7958B75772F6E
-:10720000F7BC897C205AA7121C2D991DF63123F951
-:107210001E02B03E4407948B55C33A49CFB3547510
-:10722000907CB7947574209C364ED291BE917EBBF3
-:107230008EF0D952103A3414FD04B375761C2F1D0C
-:1072400004BF11067920BFC38B7E130630D755705B
-:1072500054C1716987304F8680ABD3B9E3870A8CFC
-:107260009381E38DE6ED114E0E01A7ABD3DD0477DC
-:10727000A718376328B41FCDC769AB888D23CF719A
-:10728000632D0BE2FAE4BC729CBEF199A6205F3537
-:10729000FC0AE006E7A4149A69712BE633B28FBBAF
-:1072A000977B9BB7125DDBC8CF91EBCCAF463CCA56
-:1072B0003DB8698A6E34F6B3D23C86D92C88789C66
-:1072C000AB32F337D351BFF1121C93E935677FC757
-:1072D00054D453E5B924D36F8ECADAF5E9E7D371F4
-:1072E0008ED3595D32BA1F7A4EA2979C83D13B1040
-:1072F000E993E97A4BCAE932840B8B6FAFBF7059BF
-:10730000AF0F1D423F0FCB063901A02F4C9A8FB112
-:10731000FF326159613AF7974390EF3B84FF06E4EF
-:1073200015106BF718FB781BD2E94246F855FDFCA7
-:10733000DA5B7F05E39D1D66B4A35C2938D8D18B49
-:10734000F291EDF40DC773D8ACFA1E4E81FACD87D9
-:10735000B319F2EDD5166E8FA902CF93E5CB3A4162
-:10736000376E9473AE7FFE29F5C3D0D0AC4BED40A1
-:107370007BEBEEAF7DD59CF9BFA867B1A749CFCA1B
-:10738000DFDFDB62C3F9D71D6C37037C2D6FF0F6AE
-:107390001D500EA808BF06F267ED2B98437052DF10
-:1073A0003631C4D3517A2D8865F6470B43FEBBFDB9
-:1073B000D9EFD5BB91FF644D74231FDA26E83D2831
-:1073C000ECB3E4FDAB46CD87FA44F2FB4DE93A71EC
-:1073D0009EDE1375708EA31E31B2355059AA9BD90B
-:1073E0008EF65D7435F05FA89DA97737DD1D67DFE8
-:1073F000DE6BAD0AA5A35DB2CCCC7CA030E79F5379
-:10740000980F88B3C0F99B2AE43F852CACA09C2D33
-:107410006C068517F16AB195F9E2F03DFF9C4AEDE3
-:10742000EFB56AA1F4B1FCBD19F88081FF933D99D5
-:10743000EE65754ECEA3507F313C653D8A7C833925
-:107440006BB43E7B6430E22FC87D986FB7D8B7012C
-:1074500060681803FFD97461D3E8F3DBEF1370524F
-:10746000CDB630F24BD5F6FA61E22F76F5547C3B7F
-:10747000B4BB89893530F2CB225CA8FC033B95F381
-:1074800080FF9AC690DE1F40FB3B90C6ED11A669B7
-:107490006E6716D20B2320E79B59BB19DA11B6038E
-:1074A000BDE5B05E0BE9CDFB991BE9013D6CEFA595
-:1074B00010CB6208D7CD8CD5C6D3817C4ABF84BAA5
-:1074C000444FF6D4A52F59683D866616B4A03E8475
-:1074D0006B0378AB8B59502D8EF905473BDCD4CF2D
-:1074E000C89A499F7DFA8B23B9C8A7AD07401FBB37
-:1074F0000CCF59477CCA6A4DA43FC65A084E5181E9
-:107500001F5DCBEC74CE7DF69BEF2D71CE91169462
-:1075100017858BD313CE57B6CB3F97C77C97C78FB2
-:107520001BA471F387EE57D02F937FAE90EABB96E2
-:10753000B92F30FEE001C6CF213C1A78FC7CAAEFBF
-:107540000ABFE5B80940B139BADFE175C7F4EB64A9
-:1075500038E72F4EE4CB97ED4C2C4BB8580C9A7370
-:1075600032C0DC7287CEB315C6BBE27062BBDAE212
-:10757000DF92FD1B6B1F764EC5F6609F6F85B75778
-:107580009D486CEFAD7AD981741C6BCFD777CDB99C
-:10759000C476C9E793BC5E5857E6B7E3D635DE6CD0
-:1075A0004AA89F5E77DEBA32BF13B7AEEB5C89EDB7
-:1075B0007D2DFDAFEB8652D33F5C976CF7ADCA8B48
-:1075C0006B97BC8FA9B5A601E0CEDB7F67FAC58DAE
-:1075D000FBDDFA7FDCEEB625C9F30408DF17E9B45A
-:1075E000F119503F135FA1BE68B392DE7B9E9D25CB
-:1075F000E4D344543CA09F274D9B88FD6A25DD09B8
-:107600003FC3C1672EC946BE9E27FCE84CF815BA99
-:107610001B5CE457F089F6204FDA905F746F877E29
-:10762000697C5DF1FA534603B72BEC2C4AF42CF538
-:10763000A5746657B83DCEF59D81E6491EFF1E54E0
-:107640000061BDB3968C67EF021D3E67B457A96811
-:107650009F6D51481F9855A3E953013FC6B52BE4D0
-:10766000579A75D79B0FA03FE6CAE3EE9D11783F6E
-:107670002BE8F0E0B44DBD4CC33841B67E61D98FE4
-:10768000E1F9E03E4671342C2F447CB3696EB43787
-:10769000EA704530CE294373991DF9E6F76D1AF269
-:1076A000CDBA69DA1F68BF7F07AD04DACDE65B6744
-:1076B000CF774E3662BCA3EE7BEE4AD47BEA42160D
-:1076C0008D9E66A65A611F75A08FE133DBC8540BEF
-:1076D0003EADCC8CCF8AE55CFF4AABF41AEB60FE82
-:1076E000BA9E9F7D8EFDE6AAE1BD5C9F0CD2BEEBEB
-:1076F0007A5EFD0FD4D7666B5E23F28B4BB71BB956
-:107700004E2AF0615428B18CFC20BE5C164E2C5FD2
-:107710007E30B1FC710687EF38E1C7DAB7DB447C15
-:107720007BC18756D23F7781C0433B39F0B489E4AF
-:10773000C7F805363AAF0F4F5AB7A25F6FEFDB5667
-:107740006A3FFF490B6FAF0B3D83E5C03329646788
-:107750002FC80855A4C3BA5FFC424FF0C66D19701C
-:10776000FC67466C5D83F597872A302EF6DC258C06
-:10777000F562BD1A1C8DFB7CEEBFB8DF3AFA842996
-:10778000B80DC6FDF0859F3DF3239CF789BC7405B9
-:10779000CEE72A940BD06EDC23662BDA1BE33E7C0B
-:1077A0006A08F28D05DB4D09FB7B264311FA833B0A
-:1077B0000DF16E20BFE3B1D53FA3FEA5270E13DE6A
-:1077C000ED32047418C70BACE678B6CBC2FDA4BB8F
-:1077D0002C85413CA7DD199CAEAED26DFB6913EA46
-:1077E000976F703D64A0F14B5DB3BA6AFAF133F65E
-:1077F000D5C3BCC570CE673EB0DE86FEB8E11B12B5
-:10780000CF694430B1FC7206D71366B2B8F7C5B879
-:107810009EC12B5DB89EAD8CD6537AE29D5B8B5199
-:107820001F37713D2479DE5F6770F9F9F39FC33824
-:107830009CCFE8B91E0E1003BA5E20E8E14585EB47
-:10784000C1F0B7380FF07F012A108363EF1724AD22
-:10785000438EDF22E0F4A9396D1BCA73A791E3FDC3
-:10786000C965071FC038A66CF7DE324DAB89F32B14
-:10787000CFD9B0F0400E9C7F437726D999F27DC3D3
-:10788000132F657D17DE9FDAAE7A50F56DB8E5F1FE
-:107890007BC761BB27F4215C27D66B30FEA9D0CB18
-:1078A00069D86ECE66C718F497C8FE73375CABD53F
-:1078B000C4F1D3AF4A4F92FE1B847DFC7C65EF84FC
-:1078C0003C80F7820D8A079B2D087D7BEA8DA8EB13
-:1078D0006CD67B30BE51A132AF7E0C99EED3F0D97D
-:1078E000D0FDEC815CA8F7EF1E5B81FB5AA3F3DEB1
-:1078F000300AE9658B81FC60C9E7637472FC85FE20
-:10790000611DF45F73B3AD1EE32230EE7E2CEF2BCE
-:10791000DDA6473F7EDA09E06FFCFD611DF0CC1368
-:107920003D2B4683CD02786C6B47FAD8858E0B9C35
-:10793000E7693DC90916E6FB1827FCCF0BFED469A1
-:1079400054E179E2C4F2B42A4E7F744EC8D49DB09B
-:10795000BFFA474611BDCEDD90485FB29D5CEFBCDB
-:1079600060627D325E9438A5BF8295C6E35772BBD4
-:107970008C490123D263C312E0E77174D370BCC396
-:10798000887A57F23CA8413279AE7AC24BE6A6FD1E
-:107990005AF87E41E535C37E4FE2BFB8DF5C41BB9C
-:1079A0007EBE425B640B2E61356E80E78229AC1689
-:1079B0009F921F9EAA0C8DC6F6BB0C91C77F4A7C76
-:1079C0003095F8C1297B380DFD4AB9C2AF77CA1D81
-:1079D0004E433E7746C4EDB01ECBF37B401E005DA8
-:1079E0007FF89191E4424BE8A5343CAF53CF5874F3
-:1079F0003A38970FBB33AAD11F742AF4AB34DCD7C3
-:107A0000C9504635FAF506E213C9FC4DEA0347F1C1
-:107A10009F5782DEE3D4263811BE1864C8017993DB
-:107A2000D15CD6DC0FDDCB7E4E637319E66944BFB3
-:107A30006FF3209F9DEA74D3FB3A858F877F18DF11
-:107A4000FBE460C6363CFF837B4B06A19EF00973C6
-:107A50000F42BEBD20CB7B33CEE7AAEEA5B8BE6BEE
-:107A600022F3B4429F77F59E3BED00B7DB19C82D9A
-:107A70007C96FB8CE46F69CBA475CD525958053CBC
-:107A80009D8572753495498F99B55909B6C23A6E7C
-:107A90005F9BB8CF399DA6D8F9C27FF31830442434
-:107AA000A0CD71ED60FC79283F017EF3CD2C9C02C6
-:107AB000E3CE7F34B1DF0216A6F5343CF5A5A93F2D
-:107AC000387E2EE0B8204BF33BA1AC4C31D3BA7ECC
-:107AD000F0B442F2CD29FC8CD1070705311EB64027
-:107AE000C8EBD9A6BDB41EFF5D75DAED8037679689
-:107AF000CCD26ECFE0292364976D50080F17D4B015
-:107B00007001AC6F418F121E85FAC45BFC9CE4B817
-:107B10006C0B6F77ABD07766035C507F18F79412CD
-:107B20004805FE39DB0CA61CF211B13FAC1F04E581
-:107B30007AD641FB6A64115AC75A3C47EECFA3F587
-:107B40007FFE163FBF71F55BF5B8A8837B2B28FE3F
-:107B5000F729F3D039825EC22CE9E7E309C25D8BD5
-:107B60008353FDE6C4327B34AE3C18E10AE5387835
-:107B700037EDF8D2A4F503E707FBE44970C4E451FC
-:107B8000EC3CBDF788388707BF3D2707F9C07DA8C3
-:107B9000BFE68A012A916F32E9D7089B617CEBE549
-:107BA0002CC1CF01FA15959F704E9BB8219FB1F55E
-:107BB000061FC50B66E9BD0730B49592ED7B1AF13F
-:107BC00076964E2B54891F682564EF2EE1E7F1D09D
-:107BD00098E611CDFDD8B972FDEB95505887FCE0C1
-:107BE00005AE1FA496470DBE383A7B45F0B941FB60
-:107BF0002207F2105F9E55C82FBF51616D0AC0D990
-:107C000005C782F260A372F400CA8F8DD7BB592BCF
-:107C1000D497EF98BCF065B295AD94D7D3B8A34A8A
-:107C2000DF68A3FD737D35A579AB0EEAB36F2B1D1D
-:107C3000837402FBBE6D0ABC7F5DD06D8E8DE383C5
-:107C40006B79A07811FA65F77917BE8CF43DCA4AB2
-:107C5000FEAF6C80556A3A3DDB510F75B11605DBFE
-:107C6000ADCC5478DE411D9BFECB918435EAA074E7
-:107C7000FE3C0C4F45656DE8CFCD5641AFE5EFDBDF
-:107C8000709E07D3F8BA3275FADB26A35E3D86975D
-:107C9000D3972ADA3642FE75B4AE6C13ABC57DE3DA
-:107CA0007BD4C361195A37D507094ED9E39BCB70F2
-:107CB0001DD943F8D3690CE7E338AFF7E1894F8763
-:107CC000FC7AB190BB8BB75667237F7DFD945945F5
-:107CD0003EFABA4BEA8F611BEA8F6C68296F2FE47A
-:107CE000DBE2B2F1D988F7CEC2C476670CDAA0CB5A
-:107CF000514E1CD253BCE7339B36C801EDAE32B2B5
-:107D00007EF3ECBE10E7EA3FA7B0609CDFC03FFD0A
-:107D10002CE9E7FE736AC2FB53CBCC2C18E737681B
-:107D2000A8DF3701DB35B2DE95888F8DA114168C64
-:107D3000A38FABACFDCF2BE9C27F4ECF02FDCE6B44
-:107D40004C7C7F2E830532FA6B9795F81EF6915086
-:107D5000DEF9D7BE7DE07B561949433FEA2494877C
-:107D6000503E13D4050CC0875E37703977DA1E4950
-:107D70009083A7DD112E07D14F64E37AFA643C6744
-:107D8000359A362535368FACC7FEE971FB3D3DDDB2
-:107D9000C8C2743E515A07C22F309CB14D3D1F1BC3
-:107DA000313FA6A1672FC14FE24D3C1C03F171A7E3
-:107DB000D6DEB00E784665E64FD78C1C0128B84F4A
-:107DC000F287AE35E8E7CCD2EB12F8454A791FFFCF
-:107DD0002076F52046C188DF6C59837ED25899B74A
-:107DE0008FF57F78620D8C573E92F7AFCE0CBEB602
-:107DF0009C92443A38FF55A385DED4B8B239A96CB9
-:107E000083F2A8B8B23DA9DE9954EF4A2AE7F3F607
-:107E1000A752C3857A0F6337663E3A5105BE792A69
-:107E2000273C03F3C6D6B63E3EB106F859633997F0
-:107E3000CF4D3D8A877C7F027E4D1EAE37DA3C11E6
-:107E400023E6ABA594F71E40FED2B053B12B400FF2
-:107E5000B6507798CAD8CF1DD72FA450BF86D0511F
-:107E6000EA37E0F8A53AA2F735A5C778BBD0FBA45E
-:107E700007AC6A5B48F179197FD6339F96A7C4E2B5
-:107E8000CF92CF9ECED15E223EBB5BB1237DF6E189
-:107E9000298E1BE7F791EDFF38AAE7B7A866A42C57
-:107EA000FEB805F5D93F35BE3F16F5BB3F0A79B29E
-:107EB0005E098EC0793731DF089497DF6F1CB657A3
-:107EC00007ED8E18225D18635B9BD93311F3E88EA2
-:107ED000A4460A300FEFDE070F103C8F6446BA103D
-:107EE0009EC71F7C85D717440A30EFEEFECC4F7833
-:107EF0007958A40BCBBB1EFC132F8F8A14E8A1FF6B
-:107F0000E0C0918935D0FF317BFF74DD9AC9F57BE4
-:107F1000B9BE2B866A3FC9447BB581CBA12EB089FF
-:107F2000CCC03767CC3FF9F463008719FF9242FC5D
-:107F3000ECB153532772FD3CE0552BD07FCBFF486B
-:107F40004E12BF57C96ECE41D9981E3B8FD4C25E28
-:107F500037C9914B9ABB51DFC89E3192E4488D538B
-:107F6000FB0BCE2B9FF7E7C113DAFF25D3CEF9B772
-:107F70005E47F1ECEC1FA5927E769F85EF07E886C1
-:107F8000CED726CE6383D8CF864C6E57363AAFA570
-:107F9000716E15FA74E7EAE0131680FFDB324F6664
-:107FA0001DD7CFBFBB15F80AF0F14E879683FCE4CE
-:107FB000BB22EF4DF20F7C9F1E6797749641D91636
-:107FC000B33F3B276B3956273EB37418B791FCA8D3
-:107FD000B398F7937229BB95CF9B7DDF886DB88FDF
-:107FE0001495FB9F664F2FD9D6427AC1145A2FD3CE
-:107FF000B41C05C63B3E6FB00EFD52F27CA60FD5F9
-:108000007E89F0B955F8F5E539C9F3FC8BD8F72C22
-:108010003DE815B0CF77B37C341EE819A385FF8BFC
-:10802000F48CBFE019C7C197A991B1F8FEFF2338BE
-:10803000FDFEEB8053E312E017BA8BE017027EEBF4
-:1080400095B0219BF30BB2A7F13DCA9D5F3A7D1F0E
-:1080500066C6E5C7CCF85123E995725D293F7CBE21
-:10806000F63BEC7C3A4BD6FB3EC7F38AD34F3DD26E
-:108070008F29E639F2B699E216478C21E29B47C078
-:108080001E6A41FE22E2EE15FFB2E075B407E5B8C4
-:10809000DFCDD2737FB03C77C5DB3DA718F35058D6
-:1080A000C08CFB986CA4739772B7D3C1F34A3AEFB4
-:1080B000CAA3BC92332CC2C81F5AC9883F021E50A3
-:1080C0007DF4962CA27F681FB060FB7997507BC02F
-:1080D0008B00F1875BAC64BF74629C1AEB6F290D57
-:1080E000621E0CDACD846FF374346F3FF8C2FDCD9D
-:1080F000C3799E85C49BAC56EED761AA367A729C32
-:108100009CBF228B9F734A79E4D9DFA35EBBD64222
-:108110007A2DCA588A097564D33870FEEE2CEE1792
-:10812000203CBBFDDE5491CFE6A940B8AE4AE578CD
-:10813000B9D9C2E3559B418F26BE28F057E6D3F943
-:1081400084BE17A9D7A5A1BE303AABCFDFA0A1FD51
-:108150004FFE72A89F19518EA2DD3633A00F9BD01F
-:108160000E6BBF568BC4D931F887F1BEDB045F6557
-:108170001B18F90F6FC37E6938BE350DE39BB761DD
-:108180007FF4D72EBD36218EA76571FA96EB4BE6AC
-:10819000FB5A96F04B763CA4C5CF23C74F1E0FEC7D
-:1081A000D12A840FC0393C08CFB7454FE797BCCEE2
-:1081B000C806EEF78E6C2822BC93E30DB4CE3FEBDD
-:1081C000A377282007E78CE776BAB47F660B3B9A43
-:1081D0002D4DB4EFD0CFD257D69F5F4EB617313E5C
-:1081E0009FD89EEB2D2923A346A25BB792B07E09B0
-:1081F000AF81E030F72BC24DCABD872C4007E9683C
-:10820000862B84BF1BEE4A2139E6340647205E2DBB
-:10821000CA7253BB4D9827437295DBCD9FBE2EFD8E
-:108220001E89F6B2DF1ADD82F0F25B19D1D3E9DDE7
-:10823000A9443F6C686406E6999DD9656288BF4D84
-:108240004AA404F9D66945ABA3762D296EA423E987
-:108250005778F739EE57F02324617DFEC07F529E98
-:10826000937F67A21D7D1AFEAB07BC3FAD8B54E028
-:1082700078921F801EAD917E54CFE33F4D3A164059
-:108280003BEB2ADDCC799CCE73D9367A7FB464512E
-:108290009C9E0EEDF62BE91C7D906E1A041C9B74BF
-:1082A000C7A85D03E62B213CD1DE423F1956C6F933
-:1082B000759BD67E48F9524D3B12CFBB21860FCA23
-:1082C000970AF68BC30FA2E780E0078CFB3B6A7826
-:1082D000FC3A5594536A7B297FCA2FFC1F99FB22D5
-:1082E0001390AFA49687D84C78FA4F707D635CCF1B
-:1082F000D697D0AE76D4F6162019F8859F509EB743
-:108300005CE7953DEBC8DF21F59438BB73C494045A
-:10831000BFC372EA87762CCE17C1573988065CBE78
-:10832000AD17F22D050D6294831DC3490EA29C4228
-:10833000FE24ED60E457C82752B2ABF720BD3E9251
-:108340005DFD02E76B8067A8D7A35175E5C0FE3DD0
-:10835000091FD90EEDE17FE4BF7B55E0ADF4ABD34F
-:108360008ACA31DF3A53FAEB28AEB748716723DE89
-:10837000BEA7F7915F6E2E0B909F681EFAC3E0D9DF
-:1083800020E87D8EF02FCD117E25F4F7C6C71FD1D2
-:10839000EF1A5F9ECF7A39DFD86E8AE5E5A01FA875
-:1083A00086855361BC46F453E13394D8AF8945A91F
-:1083B0009F7FE797A684F86627DFF76DE2FC1D35FF
-:1083C000413DF2898D16EE9F92FC63DC52EEC71A96
-:1083D00034462B5E8178FEAA81FC1B7F11E7D6E72D
-:1083E0002FCDAA7E290BE064D5F37B6CD11526E254
-:1083F0009BC7411E770BBFCA14B44397310DF3DE00
-:10840000996A2F8CB753E573CD2E4B3DE2CF67426F
-:108410009EC9F7DBB30CB41EF237115F4E21B90BC6
-:10842000EC6334E257C5602917D968F4731D1576DB
-:1084300073D3CD361F8E17D1717EA3647339A564B3
-:10844000F3BC3E59EEB3F304FEC8B821FA7DE2FD59
-:10845000EEE6BEF6EB843EC968BFEBE789BCF03EB2
-:108460003CD6115F4A19E925FE7B95AE9AF852F485
-:10847000039B1BE152FB61C33CDCC727D3AD74FFF8
-:10848000EF76E10776653B687CE9F7BD503CAD7659
-:10849000CD08E297B27D1E1A2863CFF71FEF127C3A
-:1084A0006C17E3EB0D9CB0F23C15950590AFED0A0F
-:1084B0008D08E27AEB84FF01F51BE4AFD167F9394F
-:1084C0003295EB43BB7A460511DF8F1A7C1B67A3FD
-:1084D0003FA7DB407E39A6069F781CC7D993E3C12E
-:1084E000BCA1D3BAE8965F43BB5D277E9E8771A28D
-:1084F0005DC25FDF600C9790DE2CF2241BD2C22598
-:10850000E8077A519C578315CAF03EC3E22BCF1E71
-:108510001B8BA7613F7C7F2CC8F5F2638CE3416025
-:108520002D8F97027C7366E37A5767533C0ECF0515
-:10853000CFE1DDDDA3685FEB0DA2FD0B0AB557A609
-:1085400094CE20B9B0C69481F03FE335529EAFFF80
-:108550003EAE37CED2B9B72C415EB92785F637BBD0
-:10856000F310C549FCF7CEA5FB93FEF94B6F62FFF4
-:10857000207E807225DEEF7D9A450BC91EAE1F1C42
-:108580000AC33A4EF78CF0F0F01FBF8FD324F249A4
-:108590008F1B9886EB8EEE3604FBBB2738D0F8E4B1
-:1085A00040ACE0F28DFCE3F1711A920789719B0BEC
-:1085B000954F1B222577C1FC6B337C73B2E3F445E6
-:1085C000FF9E1CE277EFDEF3D742D22B3A789CE194
-:1085D000B8419B8174E2A8091B67C6E9613FC916CF
-:1085E000F68749E88FC007E3E95ED6575427D2994A
-:1085F0007CFE389BEB21A922AFE0FC7A99B736D5F7
-:1086000084F293BB96705C37BD2F12F1BA7127A22A
-:108610007B313FAB215446F1C0A2A561A24B8077CC
-:1086200018F5FFE31B53393F816DE238732A19E9CE
-:10863000AF73F43C4F628E09F4612EC7A9FD7B1B1A
-:10864000B3090E15CBB91E187D5621BE28E39675C9
-:108650008CF77FBEED68400FEDEBB62B65C05A5925
-:108660005D5B15E551CCDF5C4CE73F4EF0DF5926F2
-:10867000AD6423E2DBF33CEE05F391DEDD80B9620D
-:1086800063882F19511ED66F5718DE3796FB4F8E11
-:1086900013B260629C665C88F36F941B2C4E5F93F0
-:1086A0007208E5054BD22313F12220E257FC7C7EB1
-:1086B0002EE02AF93F41EC1FC841D0A79F44FCA9F6
-:1086C000A8E6F417ED5608CE8DAC99C795841CEA40
-:1086D0005B8F9063EFE9B9DC9C635A47CF305E1E35
-:1086E0001B8B7230C2E520C835E48B03E14578006E
-:1086F000BC90F8B017F701E3359C60E16FC07C0DCA
-:108700004B59B871347FA68E26B9CCE5B399CB67A7
-:108710007C5A2F424E27CBE764799C2C87510CA1C1
-:10872000BC957810EFA7477D64DCD2A09EFB61F377
-:10873000ED981F28CFA5D1A91DCE1B1BD3B7FC8751
-:10874000CD66F76558F6B2C136F42F55DD5E00FBF5
-:10875000F7ABFC9E720AC0692BBCEF12FAF9E40277
-:10876000BE7F97C80332A85E5666C373EA257B3A7C
-:108770009AC928AF5BC2B72B15FA8DC17E5CFEF596
-:10878000F537B3366B5CFFEA5D16922F675F48A53D
-:10879000FB684CF5153960BCAC3F829E0EE5D3BB3F
-:1087A0005249BE9F16FCDE29FD166C259DD76778C1
-:1087B000CE998875D579E8FF65CAC43C46F7B4B947
-:1087C000DED8E818C86F2FEA8B7B6FE6786622390F
-:1087D0007BD611B913CBB01ECA333E25CEDDBF63A5
-:1087E0007CD98F303FC06BF370A8FACA506F30E964
-:1087F00017DF6CD6E37DFDA5D1BB601F8D0536CAA2
-:108800005FAE297AE777B740F9831D06BAE738EFFC
-:10881000B1A983C2D84DD55CFDC9E7794143C2FDFA
-:10882000B905DB13CB8DA1C4B23FE9BEFC9277B68C
-:10883000BEB63FAE3ED395EAA4F377330FE65F337F
-:10884000FDF706F9FAE197F2F9D765C1D7F60FA35C
-:10885000FCB57C17CFCB31A25E3313F1A19F7E6FA5
-:108860000ABDC6646A3E8179F0A6174D74AFFE4416
-:10887000B66F18F66FD2450FE0799A8A4E8D463959
-:10888000585DF4778AA79DFD31F3207CCE5AAA4823
-:10889000BF39BBD1E246FBACB3D04678D0B947096B
-:1088A0002A5C7F9F34B602E3A7B407E6DF70FD07BA
-:1088B000FCD20633F37BF860BDB890CF68644FBD3F
-:1088C00037D96A5F0EFDEA377079DBC07AD3900F33
-:1088D000CC7771FEE3D73F6534C33F8BDBB4112DFA
-:1088E000B0DE055E2BDDD751BF50E99EFA2A1C325F
-:1088F0004EFFAF72093FA93962ACC2F9FFBEB8168C
-:108900005D63D2CF6532F834BC1766D85916CE8372
-:10891000577397BC44764E5F1C7A37E75B73EFDA88
-:108920004BEF9529B5B4DFF760BF089797369A6883
-:10893000BFEF15D8C8CE7CAF8BDBBF73EDC6A09957
-:10894000F48D7319789FF6BD2E03DD633F1F1ED78C
-:10895000D1BDD6F737BF427EB8F7199F37B0434F26
-:10896000FACAFBF6684518E1E86E4E437DB77EC350
-:108970003CBA173BB74BEF457E36B7EB8E5F5F894E
-:10898000FEA329B796E396AE712CCE72DB62F55248
-:108990004F55D32B1F473ABCE68BF1BDD7A0BED4B1
-:1089A000057452CCF3EE514FDFDF751DE9A5732737
-:1089B0005B1DB82FF7E6C726A0FC787F722EDDE39B
-:1089C0009DFBB4C2F0D30D731D4BB2F0FD5C45F5B9
-:1089D000F6874FCCC5FD6D5545364F18FBFD564FFC
-:1089E0007802747533CACFC62E03E9BDFBA7BCFD60
-:1089F000BB5B9C31BA52A66CB8691CB6FF9981DA90
-:108A0000F7E93B9B6F94F8C2C215685771B825D33C
-:108A100099A9686909AE2B99DEE62E6F2EE1F1ABBC
-:108A2000AF46776C33BFD7DBE652D897BAAF4477FF
-:108A300077BBC65E3CDDB1FCF4047BEA7CFE16200D
-:108A40003C95FE7FB387698FD928DEAB29C07F773D
-:108A5000B8F8BDF51D2E7EBF4DFD8F45DBDF00F85C
-:108A600054BA7C5DB88E22A695A1DC7447EDD5780A
-:108A700017C926F439B6D924ED00D2EFD767B2C7AB
-:108A8000D7C4F91F422E6E27011F781CC739FD87F6
-:108A9000BF1FC0736A2A3C351AFDBEFE739F51BCCE
-:108AA000D0D6C3E3CD364F94E2F006A797F050F24C
-:108AB00077BF87CB9FF3E0E5E2F73BFCCE288DF351
-:108AC000560EE7CF9D22BEB2698995FCA99B9C41B9
-:108AD0000BF72F0418CAA749957A1E2713FAD68DCB
-:108AE000C21F692E7F89617C8C5DCDF3C2DE287F39
-:108AF00049CD80F2AF2BAFF5D07DBEF247DA07E368
-:108B0000BEAF3688FA21F4BD8D7FD7AAA87E914BDF
-:108B1000EF46FA9E54CEF322597D1AF94DDE287F96
-:108B2000D7797BDCFABDCCECB601DE4C01628DCF8F
-:108B3000C3BBE96A8BDB16873F9F7428B55CEF7572
-:108B40000F9A368AFB45481E9727C26391CB48F39C
-:108B50003E925D7508E17CCD37F9799C7CDA14444E
-:108B60003E7852DC8F49865FC425F0471D9110B7CF
-:108B7000771A438528273F5412FBCD6FD753DC7CEF
-:108B80005EBBC28230DFC9279E2F447EFEC163CF09
-:108B900017CE8C5B4F723FF93C29E7137EC1643FCF
-:108BA000EF40FE5DD9EECC06E6330F89B53F53FFAB
-:108BB00037F2EFCEEC11FE614D1BEA447B48B44F17
-:108BC0001E2F3397F36B65A7427E0FE9DF3C76F0EB
-:108BD000118CA4F49D9FA5A758179FCF289FE3C48D
-:108BE000B94DC57383AD58DA7979A0F31A881E7F21
-:108BF00021E4903CB763ED4306211C8D4D3695F181
-:108C00007B6AA5A8AF7731AB07E9E9AF22AFD56999
-:108C10008527E869C65C970DF999FC2EC00FAD69F0
-:108C2000DBF0F95791F7EAB4C213C629C82DA5F1B4
-:108C3000FEAAF3925DF7437D07DD5F74093AC966CA
-:108C40006145C14F1D2C784EA1BCAFF6447867B585
-:108C5000723912AD3392FC9270BF6AE69D64BFF622
-:108C6000735E1B108F722BF9BBC939C5C2DF11A10E
-:108C70003882A592D9D1BE6FBD3240EB90E7E5E7CF
-:108C8000CD99D2A390FE8CF92F29E9142F0D8827B6
-:108C9000B3A5B3BEF8418AB0775952BC201BF46E1D
-:108CA0006C27D70965CAA3B9CF11EA28E1F156D2DA
-:108CB0004B715C7C3F73A44AFE766C671C7361FC4D
-:108CC000EBC35391973849BEAFB7F61B9F9884F713
-:108CD00083F01C403EA25EC83C8684FB419B419FC2
-:108CE000463B4DC67FF5BA50998BEC93DE08FA4FA0
-:108CF0008C156637CADB147DA814CF2F391E0CEDF6
-:108D00008A791E42BE03E58CBCFFD3B464BC17E372
-:108D100054A07F04CC787E93F9F935DD5545EF9565
-:108D200029A52D885FFEA58CBE5330BEA79BF2A45B
-:108D3000FCB55C1FF3EF3C6A6480BF33853F870955
-:108D4000FF739638D76342FF8EC5BB225B30EFBB03
-:108D5000735E3EDDF74DCE2BF9AAF1CE33A900901C
-:108D6000CBE2E25883CC5CCE88F397F42DE35AA98A
-:108D700023BDC5A889FF2E3BFA2BEBD8AF90371245
-:108D80003878CF3FCE1B997613E68D9851CB17F5E7
-:108D9000B80C90A37DF7F92C6E8A7BF5D5E3771894
-:108DA000CC3B15717F8FDD74ED50CA3715E5D7D6F2
-:108DB00062DEF87D1696305FFCFAD4A4F10D30BE69
-:108DC000CD2DDA074EDE70AD4AF15F513F712DE6D1
-:108DD000C9DC67481C8F5050DE3F34C7E6BB7DF3CB
-:108DE000867BD6E6C7E439C8F78D396363727DD5D3
-:108DF000DB933A2E73237D7D4AF9BB523EFB9D3CAB
-:108E00008F24998F3D9AA348BD78028ADC55D317E9
-:108E1000D2770BFAE2BF3D751AEAC332FEEB5FEA86
-:108E2000A53C5ED007B6E7903E70EABDBD0CF5CE1E
-:108E3000936417F8CFA9DC4F047A057E87C6DC530C
-:108E400045FE504C4F1D1677FEF3859C421D1EE9D2
-:108E5000C1BFF93B8FE9B13E57EBCEC98CD987C969
-:108E6000EB7D2D87E7B9FB4BAB37223F608F2AF4B0
-:108E70001DA835A59F90DED1F4C2B563E3F3D0E71A
-:108E8000ED7C90E7316F37F4BBFFD772F877629AC9
-:108E90005E7896FC9D2783FCFA4CBD1A5C8D7A683F
-:108EA0007DBD0E352F561EACBB85F481E9B00FD8C1
-:108EB000572887C3C7BF7D6A00F3E2FDF09F02AF6A
-:108EC0003679E7905DB069BAD986711C7FE9CC85A7
-:108ED00084FF76AB86FB4F5E672CCE6CA5FBCB6B1D
-:108EE000761A6A518FAA00BDE95F61BD05E9136B6F
-:108EF0003DC097F2F4DD653FB061DCBD7FB9ECCFDA
-:108F0000E3E7D8A67803DF2A273F278BCFE329DAC8
-:108F1000C9F5B3A339C604BFFAD11C95E07975A091
-:108F2000773CE2DC1E3592827AB29F691FA3FDCBAB
-:108F3000BC3637F977198FB33B97B9C9BF6B764603
-:108F4000EEBE8CF42895E2CCD2BE38FD02F78B4DF4
-:108F5000CDF59D46FCA8D0471EF816C2ED6E55F81B
-:108F600089399F299C6A1B837E2C8B33F240AD9BF1
-:108F7000F26FC82F31E81B6D740E7B9CCC8EF019FC
-:108F80001FA85395383923F9C6F8BEFB3B4EF29F14
-:108F90005673B6C686C169BD6726146DFB3223A61B
-:108FA000271CFCFB34155F4AFD4167F6919D533346
-:108FB0001DEC46C4BB95D1033AF4D73B7B497F6C8B
-:108FC0000C29344F63E92F293F6E81C8C3EACB8750
-:108FD0005223941F66CE4D117EA6368E97AC97EC29
-:108FE00062F614873FC84DCA1B8BE9F12DD44E8E13
-:108FF0006714718646E1C70140517D46AE22C65DC9
-:109000009E189F10F332D55D11EF77583F19240950
-:10901000ADCB9D86EBBDD7EACDCF85F6C7EA75040B
-:10902000A263ED29F45DAAF54AAF86FEC84019CFC8
-:10903000A74DC6A33231EFA07DD109284FA22F0C36
-:10904000944FCBF367378EBD84F2D0CB777E3C0153
-:10905000F183D532A2C7A69D17974F5B81E731F602
-:10906000FFA17C5A8FA26D83E775B98EC47C5A0F1D
-:109070003F2F19D74CCEA33D9D135679BE5B64CBD1
-:109080006368B7EF34519EC8A49DAF1C46BFE62469
-:10909000330B519C37497F38E29CEACD8579CE7CF1
-:1090A000F4DE96150CF3B09FF3F07B9989FAC0407B
-:1090B000F600C53AE2ECC699126FBE267B40F26B11
-:1090C000BFB0AF3E54A2F796E0FE76EBEDFDDDA318
-:1090D000F1E7CAF8D80079203DFDE781C87B66B585
-:1090E00091E284B8D55D7D74F0D5E2604B5176F69F
-:1090F000130753455E97AA70D6C11C3CEF47C6C103
-:10910000D4EE1114DF32C5E26061D64F1C4C1571EC
-:10911000A55506AD8EFC34BB4D6E6E477B897FB581
-:1091200075677A90BFF9E79F7C063F05A03A26B89D
-:10913000506F6813F06FB8F838D883B9FDC4C1B662
-:109140000ABDEDDD525DD80870DDCA38FF0DF4C8E8
-:1091500078988EECDAE83D05B46E658A99D6FDEE16
-:109160001ED336F44FCD9271AE3DDCBF364BC4B347
-:10917000DE9D5242FEA781E03CAB3D315EF0330103
-:10918000E7B3962AF2D3DF79FF64F2CFCF41FFFE37
-:1091900090D87D0926FC7CEE767E9FDEBD5DA1EF3A
-:1091A00099229AE84827B5D3774D17001BDD84AC88
-:1091B0003700587305BC56740AEA43EE362883D24A
-:1091C000AFAE56032E68B7F5700AF9155739DD2290
-:1091D0006F8DC79D036B95E0303E2E7DC72CD0A6CA
-:1091E000D3709C5772B93FEACFB9C67EBF23D16610
-:1091F00010F163315F0B837387A74EE1CF55E23BDC
-:1092000079C9F090E3B5199ACDE8DF8B16F0EFA19C
-:109210009C356AD3C9EF9C5E42DF3D6A4B6D6EAFF1
-:10922000E5F544B3672D512FD57F43E50A2973A790
-:10923000E37A77E772FD2619CEB33B12CBC9719F53
-:10924000E47B5AB3986F78CE90F3EF31ED16FCF6CD
-:10925000EC9A62712E1E8AA3B419DCBF29A6F829E4
-:10926000FFAE514B3E879BAE803F073B6AE8FB74E5
-:10927000402F5C8F637CFD83BFE154905EDA1C1C41
-:109280006FFFA7EB4E5EEFFBB9251CBE0E4EAF6D18
-:10929000AB952087175FF7C5FA490C795F2F5F7C84
-:1092A00057F13C1E2EA67EC41F02F71888EE765991
-:1092B000F8FD4BC9AF28B107ED4F61EF0E42651ABB
-:1092C000E3A12756D2F78936D50F4EC378E9F8A91E
-:1092D00036DA47D31E7EBFB77169A410F1BAA93A36
-:1092E00052D2DC0F5C710255F2576837D3C9F87758
-:1092F0006EDA13E37FC971DDB5195A415E26DA4B88
-:10930000EF76BF82E7DD6D21F9DAB434FA38FA0F6F
-:109310007C19BEA1587FEAAEB727286EEA46FAFC50
-:1093200099DDC3E95EE2CCB6C47B5E6C6D625C9194
-:10933000B5A7F3FB6C9D89EFF13E5342BFF3E28C7E
-:109340005CBF596FF48D40FDF39A6FF23C8A8FE653
-:10935000E9189EEB47167EFE817B5205BFF694C44A
-:10936000CB83AA01CF17DA8DC4783ECF1F95ED1BB2
-:10937000F17CE15C1BC4F97EF4EC152578BEA7BA3C
-:10938000AF28C1F35D6FE8D0903E52B27DD7629CAA
-:10939000EDF8B55ED20F65BEECC5E2DDB4BCAFD76B
-:1093A0003FF755E5719D9CFF2BCA63FC8BF79BEC47
-:1093B000F9BB3E6021F9C2EFB5C6FC7727E9FB5E39
-:1093C00067CEE914E4C7038DF789B0975C66164051
-:1093D0003DACA23A42FD2AFEA663A80F4A3D387969
-:1093E000FD8BC5B9AEC8D30EA35D28FDBDF5626C7B
-:1093F00073F053AE6F3FAA903FD7EC0EA48D23FBC2
-:109400006AF6E57AE22FFF4AF725588F62473B65F7
-:10941000DEA32D547F7AE72CAAD799C361B4C71A6B
-:10942000A11ECBABAE4ECC7F36EEE0F12069FFC281
-:109430003ADEC275A438A346C4CF26D4AF61894DA5
-:109440002AF77B37399927C0501F4EB417655C77D0
-:1094500093977F3F66538F42DF91CA32FA8AF3F1C6
-:109460005C93E2BBF7E769DD887732CEBE204BEB39
-:10947000CCE3F9678508A79FE2A2A01C31C87B5BFB
-:1094800089F70F0FEEBD99F4A1CF997750FFF968D6
-:10949000C184F8FB1C714F748EB8278A7C3A9CC437
-:1094A000A7E3CB0D71F968E1FEF20AE2F2D1E2FB2B
-:1094B000C5E7A38513F819A7FF6CFD228A7BFB0182
-:1094C000CF978C89E16103137F1BA2EFD2FD97ED4B
-:1094D00026F2AB35887C547FFD31B257FC789F86ED
-:1094E000D3A3C6EF61737DA801EC40CACB0D25E67E
-:1094F000AD1EFC9AE953B61BC87FFE66123DCA7DBD
-:10950000C97D34F4289C7E92D6996CFF26FBC1A5B8
-:10951000FD7AB17CE9FDAF591E7E55BEF4D9D7C4A2
-:1095200097CE8B270C8DA679BE8678C207EE8E2C3F
-:109530007429CAFCE1F6DD3C7F7882DEA6F1F8A54D
-:109540009EE73724C771DD13284E29E3C6E6E7F40A
-:10955000C1E5C5D4DE83795F8DBB5329DFA0DE5D15
-:109560004F7A7772FC723EEB9E8047F1397B9DEE1D
-:109570006FFD4FF306F2F3C57789DDACF82BE60DEE
-:109580000CC9FF0AF1CB976C9F66F8E2F0A57A242C
-:1095900028F02307CEEB2ACBE7F89722F24BCC6AD0
-:1095A0008039E2FA0FD4EFCA7CAE1FBF24F291EEED
-:1095B0004B4DA17BFF2E23BFAFE0D2F1BC2996EB30
-:1095C000BD2A3F13E5013FCF875FF80EC3FB670F4E
-:1095D0001B42740F3FD068F3A01C937E2739FE8393
-:1095E000397C3F174B47DEFCFF5DFE71AB9CEF62A1
-:1095F000E36F1B000671F4954C0F03F51B88BF2C1D
-:10960000C8F7CEC9277B5C1B4D718B8BE44B29E5DA
-:10961000C0B7514EEF30B9D17E403F0AC9C7B53906
-:10962000D2FEE6DF25B8AF80E4D747166E4FC8FB01
-:109630003F72FF3F1910DEFF9C9EF76E96378078D1
-:109640007EBC4AA3FB03AB52B97C893EC1F387922F
-:10965000EFC124CB15798F43CE777FFEFF2D5F7D41
-:1096600058C2E77FC85741CE92FD32609CF6BCFEDF
-:109670000191C7D9AB897C19BA0F21D7E5EFE579FC
-:1096800077BF10EB93EFD70939F059BE1642BC3AB9
-:10969000F507B319E3A0E5E59C7F36796D144768BB
-:1096A0000AF1FC9AA6A58CEC7E79DFB5D2E5DB85C4
-:1096B000FD56BD6DA3EF9E36EDDCDA3E98F20F7CD1
-:1096C000A4DF9DFE037F7F22DBB707DBF9974612FD
-:1096D000E215155F7EBAB2B69CD64B76BBD39478B2
-:1096E0008F2892CFF386E4F34F7DF005FB04FA9DBB
-:1096F000AAE779DE7EA766AFA2BC03EE0F4F71F733
-:10970000921FA8690709094649A758FFA37CC29B75
-:10971000A61D5565F4FD8190A58CBE5FF347FEBD87
-:10972000A75377E506F5DC7FFE5B5C6F6A79F07A1C
-:10973000D4338B601E54494F755F5F46FEC124BA17
-:1097400093F4D6777FF4BBE660AB12A3C7F5062E81
-:1097500027A57C7B39DFCDFDD54E913FD83399CD00
-:10976000B6C5CA3667625EE58ABC6B5FC6F5BC9C4F
-:10977000CFE30532CE5E6C06EB73F0F978582CE23D
-:10978000EC93457E040B98637911832F1C6797EB4C
-:10979000936519674F39277E5FC06E24BC486DE71B
-:1097A0007C83015EA09E7D75B4773CDEDB1ADA19FE
-:1097B000BE1AE13508C14F79AA91BB2FC3F845867F
-:1097C0007A35C62FB62C19B30FE3AAEAEADE6FE0AA
-:1097D000D1B83BECD5686256BABCBA02E22FCDA52F
-:1097E00088FFD5BF35F07CC6D52924EF3B0B1B285D
-:1097F0009FF1F4DBA6847B3AC9CF005BEE42BFD178
-:10980000E0F637297E90BA43E9374FB5AAC046FB48
-:10981000C4F6E8874A6DEF0D54A25FE51E857F3BD5
-:109820001256AFB8D0FE5775A877CCDAC9EF7DCF06
-:10983000EA70549B899F2A3CFE72B593F8A4BAFA49
-:10984000061DDA696A0BA3EFB45516703FF6B04EE9
-:10985000BB0ECFFDDFBED0F71B571B5E10CB8F4377
-:1098600070359AA2075CC5B178A0CC8B1BE8FBE7EA
-:10987000521E25EBB3E7E9B1421EF5E9F349783C06
-:10988000503F89DF129FFFCDC0480FFB37C54CF713
-:10989000C1245EB7C93CFF2FB85FB748E4DB1C5B4F
-:1098A000F39FA3F97D77194F09F23C294364651EA4
-:1098B000C12BF2CD00EE7B8743D73492FC614D344F
-:1098C000CE6AFE7DB5A2F621CB2BCBF169670A2CBF
-:1098D000E1D8AE0545489701C08361FDE081B180C4
-:1098E000DF575157A7D0B9A9EBE8CBD24C7564D15B
-:1098F000B9A90FF2F361057C3F329E2BFD969FE5DF
-:10990000FB6E463CECBBBFB5C4CAEF6F89FBC1A977
-:109910004BDE7E1AEF456D11FEE37D7B2EA5DF85C4
-:1099200038BB5A55504F3DEBA8A3DF41AA2BE0FAB4
-:1099300052AADACBECB678FCDC4779B58377F3FC36
-:109940004055DC7F56573BB7223C6B9C3ECA1FFEFE
-:10995000465B987E3A618FFD38C5E9402FA27BAE09
-:10996000275F50A45E94200FA5DD966C8FDD51F02B
-:10997000BFAB2705E47C5FD5CE6289F6665F7B6965
-:109980003F26DB1349FD07D27F981648C8937940DC
-:109990009CBB94EFB98237CAFC99BEFBCE2C68C140
-:1099A000FB12239028C7C6F28898C82FDAA0583D2A
-:1099B000A82F0D9447D497E7C39A2FE3FEC8E62B50
-:1099C000F029F390649E9105F34D32CECF37B1600C
-:1099D000BE4906FE7E06BF372DF3455A0D6ECA3FBF
-:1099E00009FC98511C5199524BFEBA74AF91F0EF9B
-:1099F0000C0B6EC4EFC707A6D9E87E38DE2742BC41
-:109A00008F2A2E1A777CAD26DBEBB07DDF7708EB53
-:109A100018D5A70FD572500FB3403D7E1FB9EFBECA
-:109A2000F46CFEBDF6E47C1399F724E3C0B9C39F40
-:109A300053D02F8A6E7FCA3FF881E857CCC7E9FC24
-:109A4000BE9BF846562BCF6B8A5EC9ECE897AF9663
-:109A5000FCC79C78AEEB155F31D2E77A2BFF5E40F6
-:109A600017F3B4EBA17C77C160EED761EEBD3A622B
-:109A7000D81DF47B0F9B9CDA6B0599317C92EB62CD
-:109A80001BF8BECFE0FD302536DF99797F2B44FDF2
-:109A9000AABAC7C4F13269FE4D7DDF6B095A509EE8
-:109AA000FCB980F1EF8C26E9BBF2F96789FF822FC0
-:109AB000CBF907DA9FC4CF0BE9F112FF06C2B7401A
-:109AC000B538A72329A47F487CDBB76C3B7D877022
-:109AD000FFB2103DCF5894901EEFD55AA233903369
-:109AE0001EDFF25F37E1F73CCEA4460BF17B20D1BD
-:109AF00087F55E2A67468F6099155DC1CBC3A25B6F
-:109B0000F0FB20590FBFF82D2AE379E63276AE201C
-:109B1000F4AD808DBECBB5B217E55679521E4BD24F
-:109B2000770C52C4EF0765DB8CA44F668BB81EAB75
-:109B3000117A3D46A0A0DC9A5346713C1B73EFE8B6
-:109B4000C5FA7C13FFDE0103FCC7FA61C53C1F8226
-:109B5000F17DB37CE19F669100FD1E60B183FAF751
-:109B6000F1F11D26119FE2F31F7A96C711655E2F52
-:109B700063F602D4876C6E965096DF0161AABD0031
-:109B8000EFFDB74ABF9F28BF98E2CB2D8CD3970E2D
-:109B90005DFBC391F4BB24CFFD6828F2CDEB8C892B
-:109BA000DF7596CF3F14717BE58CF87EE11D29BEF1
-:109BB000218599F8BB243326E0A768A76754191DAF
-:109BC000A4BF3DA1473E9529F0C3318DAFCF51E3EE
-:109BD00055F0F740E4F703337D2AF90998AF538F26
-:109BE0007235F3B897F2051BCCD142FCDD9637CC29
-:109BF000BECB70FCB37547EFA47861EEA12398DF6C
-:109C000071C8D0313E0DE548B1F89E040664A17CD0
-:109C100020AF88ECC13EFE304CA178E6A469FCDEA2
-:109C2000EB441652F19C27D8F93DAC09E5C59E5688
-:109C3000986F92C80F9970D89B86FC6DC277222AC4
-:109C4000FFDE45548DCFC7904FE632B8E3E9E17AA5
-:109C5000775C99E1778E13CB377A12CBDFAAFC625F
-:109C6000787C7994A24DC47DBEA888EF46007FE140
-:109C7000FBE279873F17F6DCA52E662E427F8553DF
-:109C800009A0BD70E9F3B9146779BE9251396BBB75
-:109C9000799B397EFFEB743C0E2DFCE0F2778DB0A2
-:109CA0000EE5ED737FC8227865D980DF3A89FB1015
-:109CB000BEED1374BB4FD069459ED98AFC7F9FC10E
-:109CC000BD99F03CD5EC463FD5DE54237D37B675C3
-:109CD00021FF5D0425CDCC8C30AE7E262F433BF694
-:109CE0004DA8D75798299F649FC8D36EFDB14A7E6F
-:109CF0002EACC7EFF9EAEFB5927FBB26ADF47B58E7
-:109D0000AF4F33D23D89BDA9153E311F7DCFFED166
-:109D10005473187F5F21F9FB9D87705D083758D712
-:109D2000637C1D448FFA0A23E9E1F2DE3A8C43F1A9
-:109D3000377DAE99E6DBE7B0EF45BC6BFD80343D87
-:109D4000A8AF7463FE97C4EF9AB44AFABD12A0BEDE
-:109D5000A1F1DF67D76779DCFCBE2DFF1D8ED2BE77
-:109D6000DFE58069A11DFE861123BAE5F1BC020979
-:109D700077A66AD83E87C932BF6F96D557AE52E9EB
-:109D8000BB418A2CB750F921512FBF37FA4EA19B06
-:109D9000DF4BEE79E53F106F87A6015CE09C3C2924
-:109DA000FDDF777AB290F3F7F3CFAFC2857E7F0500
-:109DB000F73932B6FF7D0E8FCB1B57EEE75C8288FA
-:109DC0006FC9E7B2CFE271A39FEDC2E371B8CA7D5C
-:109DD000E873393CFBF691D1FF3EDE11FB0889FBAD
-:109DE000D9C9F5070B755FF73EFBC5BF7F7A9F5951
-:109DF00089FBFC1AD71951BE8675EA0B617DB6D86E
-:109E0000FAE867C72A906F72FC9B28F29B59696237
-:109E10005E12ABF498B9BE989887749DB2B90DE5FF
-:109E2000EB4322CEFD8AA0AB03293F198AFAD62B39
-:109E3000334AF613BF1DD4D286C425F9B3E4FF67B5
-:109E4000738E566019E44014E5D59D830FCDC0C1D3
-:109E5000F73B1E1A8AF20AF8E6C78599E7AF53D294
-:109E60006FDF7A817E918E24FD26AF5FD211BB29F0
-:109E700044099D5D2C4C4F17E3F9F3A097D0F7D11F
-:109E800099BB20B63F20F209E666BE8F9600ADFB77
-:109E90003AC7039437682DF6198B605DD32FFB9872
-:109EA000BEA3C45C75C3518EC07A4D4563FFEFD627
-:109EB0000BFC2907DF4B3D3F59AFBF501EB95C6714
-:109EC000323F94EB51A66C273DDE0F7A3CCF3357DF
-:109ED00088DFFBEB759C0FEF5448AF6F023983723C
-:109EE0004A7ECFF79A126B1B7E2F729781FB53032A
-:109EF000CF9ADC89DF574ACE3717F6C45226ED05D4
-:109F0000FE1D89463BFF7E9290339D770C96DF576E
-:109F1000E2F210E454C2F795EADC89DF571AC05E1A
-:109F200000BB80F433364827EC022EA73BAF74DB2E
-:109F3000038CFCCFFCF7256F310A7D10609115FB77
-:109F4000FE1BD801F45DBB1B8A8AC5F7B582FCF7FE
-:109F50003C84FE9FEC8F4EC9F6DD8478327BA4569C
-:109F6000883F2D33CBC8FDCD806F9B7B19A64D3626
-:109F70003F8ADF47BD9E35BFA51B42F8360DDB4F3C
-:109F8000BFF463FEDDD418BE7DBB2893CB2514320D
-:109F900017A2E3234EDF0C1CA7D311FA237E3F7DCB
-:109FA000538F89E02DF35293E93B6E3DC70D7C3D05
-:109FB0004EBD9ED63387F03F693D1783F7F1789504
-:109FC000CD387E0F84FF78FF23754C0CFF4729BEE8
-:109FD0003B70DE3E3A58C9EDAEF3D6ADB7D179DF6E
-:109FE0007C0B8FCBF953A49DAC4DCAC9423F249F33
-:109FF000FFE6D51C2F6EAEE37944937B1A290EC77A
-:10A000006A785CCD03FFA3DF8711FC6D9AB3CC8027
-:10A01000A8F739FB9E01FD9CD32625C6DFA69BAF82
-:10A02000A378DFCDD30C09BF8F29E1305DFCFEF6AC
-:10A03000F4A4DFC54C864B72DCAE8F1F88FDE6E1D1
-:10A04000EFC5C0339FF17B3739E277CC3614F5C5C5
-:10A05000F7867FC5F8DEC31C8F2E2EBEB7DF10A596
-:10A06000EF3BBC9C3977F342A09BE13F1D49DF7B6E
-:10A07000BF366BDEA3EBA0FCB34D9750F9E5ACEF18
-:10A080002E3E84F55B4AA85CA3FB7806D24169C5E5
-:10A090002D13F1FBF8FB2D7C1C97D5D789BF9BE2D4
-:10A0A0001A3D780CE60FD718A3D4EE86CB1A2FC72B
-:10A0B0007CA81A2B2FBF5EF6FB31541E2CCA635EA0
-:10A0C000BC04CBFB958F67F4171FBCB45409E3EFB6
-:10A0D000A3D5A4F3F693C63C918BFEA29A6A5EBE0A
-:10A0E000D453B57A08D6EB3E99D19F3EF286B0871D
-:10A0F000A47EED15F4FEBC76B40DEF117A6D8A07DF
-:10A10000EF8B782B8FF2EFAA99795E89572B53F159
-:10A11000BB9BD51AF7F38EB7B5E4205FBCC9672C9B
-:10A12000477FBEDD56DC867AF1A0CAAAB178DEE3AD
-:10A13000CD8CF009E8EA10D1D5151F17A62132DB26
-:10A1400012E94AE2ED64494F35897403FCE0F7FCFB
-:10A150001C13E901C67D87F8C75589F2AA8FDF274E
-:10A16000D16D323E0EA817B0443E18C3D390128F63
-:10A170009F5D48AF9C7E3FC2751875BD6E7C5FA425
-:10A18000782EA1449B01F40BB93E745BB231E7AF6A
-:10A190000BFF54A98FF315D8ED59382FAF877E1ACE
-:10A1A000FE989D5C17CCFF05C167255F4F97D22CA9
-:10A1B0007E1F85DB61D2DFD124F6FBDF798429C3E2
-:10A1C00000800000000000001F8B0800000000005D
-:10A1D000000BE53D097894D5B5F79F7FB6249364CD
-:10A1E000929090100893044280244CC222CAE2B09C
-:10A1F00004A32C0E9B8022FE095BC84202E833B602
-:10A20000D80C844D8B6DA8A8A8A80302A2450C0AFF
-:10A21000881AE8B088585163D5D6A5D244ADEC1061
-:10A2200083B6D8FAEA3BE7DC7B33F3FF498AF4BD17
-:10A23000F77D7DDF83DACBFDEF7ECEB9E79C7BCE69
-:10A24000B977D83ECBB9C64C467F7E48636C503850
-:10A25000F385E53196C8DC6B54153E76CAEDE3CD47
-:10A26000C6D2AE315FF5650C3FFD703D63172D8E94
-:10A27000354A346315E15139AC1F6353ECDE076C8A
-:10A2800026C6A6C6CCB630E8671AF3ED894967EC56
-:10A2900085082DDA3510DA997CFB1B15C6E6328F5E
-:10A2A00095C1F76CC5E3C4EF8C056050C616E23F5C
-:10A2B0005DC17EBB415F0CE6B1D0EE08A839F06FFE
-:10A2C0000FEBD129813145D4638679437D0F8B858E
-:10A2D000F2FA37BE53B0FEAA3A05C7E9CA1A92305D
-:10A2E0004D6295946F5D97613D3591B856C69A73EE
-:10A2F0006DFECD388819FE1BC0D8F1C20CFFFD4A97
-:10A30000705EC7159669867A3E25DCBD3595B1BF6E
-:10A3100086C1FAE17B2701872145FF318145B59D43
-:10A320006F959DD7BB3B3C6A33A6D76784AF30455A
-:10A3300063FB143FD6EF140E694E70FE7F3531CDAE
-:10A340000EF3BD5B8575A8B88EE6656618EF0956F5
-:10A350004BF9492E5834C0AF73EB7A7C0AE2C96AD4
-:10A3600052EEF03A604DF8E7FA603AC905008D27E1
-:10A3700070292C21086FE652981DF245222FE1DD4D
-:10A38000C9EAEA8AFD18E15C64B735117CD7E47B41
-:10A390001AEDC1EFACF6114F683F1DD55300AEC9A1
-:10A3A000B16DE10FF3A7F98DAF1AE5FD320EC717B6
-:10A3B000F8B82792F031FE9E11F45D9994A934C249
-:10A3C000BC4615B8288D1DF09E9965135EA6D7650D
-:10A3D00005F1F475BC368BE8CBDC387022E0F6ED85
-:10A3E00081CFE46A507EC2C48AB19E113E25089F87
-:10A3F000816DE1D34A7F06387434FFD722BC6538BB
-:10A40000EE79A5611016C677710AB86BA9889F18F6
-:10A4100067EA881884FBF7302ED0FD142C023C3FED
-:10A4200096A0DD89EDA6316FBE19D61B5BA059340D
-:10A43000070D67C2F92C76F2F9E4AB0EA2CB961D9C
-:10A440008ADF06F5467B7A3F3214F215C72CCC0F13
-:10A45000E52D8CD36DCB46D5EF037A99FFE64B8380
-:10A460006087B12F049DF6DA60622E890FF8AFB7CE
-:10A470003F9CB93283F9BEDB6375F9ECBA2EBAFAA8
-:10A48000FDF6A5E9CA73037D74E5FD8FE5E9F203E6
-:10A490001BAED3D5BFE6A391BAFCB58D37E9EA0F61
-:10A4A000393549971FD67CABAE7E4D18EC9F7E08A0
-:10A4B0006E4F4326C0658EC0D3F5978B74EDCE46A4
-:10A4C0008D3986FB6ACEDAF9E3705F8D60A5BA7EBE
-:10A4D00058ADE573A4CB4AF88BF89CC7BCD101807A
-:10A4E000573E6B3E9A0CF05BE857DC08B7F91B78D7
-:10A4F0003DD96EC1BE45236330F5EBBF9732733053
-:10A500000FFD54FD71D36F8F84948F76169A90FE51
-:10A51000EA5C919D906ED835EC9A1FD476F1EB0EE3
-:10A5200020FE3E50DD36F8B4F84D95F6C1E2E71551
-:10A530003F837E3358CF68CC571C53991FF07F92CE
-:10A54000553E3C14D2BF56FB7F7BA467103EB644F9
-:10A550003D9EC35C7A3C4764EAF11CE9D6E3397A54
-:10A56000B01ECF311E3D9EE30AF4788EF7EAF1DC8F
-:10A5700079BA1ECF499A1ECFC9C57A3C77ABD4E3CE
-:10A58000B97B951E9FA9BE123DFE0CF897FC377D46
-:10A59000CD625DBD563AF0168FC3B467ED4F74FDC2
-:10A5A00096AA6556660AD2830FFE223DF462CC1D40
-:10A5B00000382F043C045C6DE9A0B87EDDAAE47F7E
-:10A5C000810E9A11FF1121F85767466BEDF06B99D8
-:10A5D0004ABC82BCFC8B0BF84878AAF61DA6D37B3C
-:10A5E0007D9D6206BEC1BC85BDBC9141BE6794A77E
-:10A5F000528EA23C320F0ACAA38EF85A1B393A4136
-:10A60000CA9F0EE4A8AB5B900F02403E665CCE335F
-:10A61000B6D684F39821E8FA5038A7CB4B58742D5E
-:10A62000D4833A83615E1FE3BC619C8FC3FB1EC170
-:10A630007D7A2BABB360FF335903A5B35833A51A0A
-:10A640007392DE50C4DC94CE615E4ADFB66BC9A95A
-:10A65000C037CBEC8D8350EFF84BE17B27149CCCBB
-:10A66000F1389C6C877095FCFA7DFC27D4F3A67AB0
-:10A67000D353213FDAEEBAF321F87408E504F2DF90
-:10A680007171345F66F6664FCA6EAF9FE524375E20
-:10A6900053340DF9AE2FC9EEDE0A6BEB9BCCEC49BF
-:10A6A00028E712FD6993003F79A97AF9D247D0C40F
-:10A6B000F35DEA16A39EC4983F16E5C3D58E3B3CD6
-:10A6C000D5732DAE5FD6BFD27AADD6BA4538CFE6B8
-:10A6D00072877B33D0E707021F4FDF620BA851411F
-:10A6E0003AFA2862D6D178C0DB5D11DA0DD8FFF4D2
-:10A6F0006937AEC2BC7228CEB518E677B110E0CD8E
-:10A70000E13F96C35FEB9E004B3CDF4DEB158DF0B8
-:10A71000F772F8C33FB2BDEDCE9FCF6794C2C77F3B
-:10A720002D429B82FD1C3235A4B8111EE68641A441
-:10A73000773AE2A99FF3560E978EE03032A2DB4CB7
-:10A740005CD71C9BCDAD429F23158ED72FE3EE988F
-:10A750005501FF9C6BF2260454DDBC8B10DF65CEE7
-:10A76000C2EE494037E72D62DEF67801775716EEE4
-:10A77000AB8EE65D83FDA31E78AFE2473D90FE40C1
-:10A78000FE655F8CFF7EC8DB4C973E988CFA4BB61B
-:10A79000C9BD198A368643D740EFEF0A783F6181F9
-:10A7A0007C2C7D5F83DF13C379FBC4874DFE1A6861
-:10A7B000EF1DF90AE1E9E9850E5A4F2173597193AA
-:10A7C000CD16FAF39F47FC7D7F23E0C397AAFD14C3
-:10A7D000D771479C29E5039A87D617F51D36F4C72C
-:10A7E000D1BFDCA7939C7C097305DC26330FEDBB3E
-:10A7F000A94CB3E0B8BFBB60F520FFFC9DE027A0EB
-:10A80000DFD3F719CC4FE96D2C40F56F678D947F3E
-:10A810002F22A75B15CC6FE223BD7A227F0D81FB2F
-:10A820003A82BB5DBBA313A797939D11EEEBE37F29
-:10A8300014FD4E14F402FBF551A417D8AF0372D3E4
-:10A8400042F6CD684E2FCCECECF9CFF64D430B978A
-:10A8500017C0181D49B0FE1B040A6FF094929C406B
-:10A860003DAB13C0BFC1A5929E5530A2C98CF3DF8A
-:10A87000F635E7636F2C63913E287F6384CA105FCF
-:10A8800013368C398DED8EB340A701503FFFB27661
-:10A89000241AD63F01F83B706456D015E444885C16
-:10A8A000BA2971DD68D4236EEAA1FF3E96D5AA08C5
-:10A8B000BF71597AB93201E58AAC07E31D4438C447
-:10A8C000B6952FF5A942BEF4617DAE46BE2C367911
-:10A8D0000E131F013A43BA2F32334F7BFBCDD54BBA
-:10A8E000917C8CF4969BC5D82DE32E592FC27AFF0C
-:10A8F0009EAABD83FD2C1EFFE759C88FE11CF5768B
-:10A900007F94A3EFA8EC7E28FFBC1A200EC2F5CBE3
-:10A910006A3BF38082F355B593F2A7AA13293D53FE
-:10A92000EDA2F45C7526955FA876533E2DCDFB070E
-:10A93000ECB768CDD766D4A3568749FCF1792C11C2
-:10A94000F4BB3A8C9FA396442EF9A810C65D420230
-:10A9500010E4755DED18044BC9BEBAA398C277D553
-:10A9600081E5EB1437CAA7B947B455483EF38F3792
-:10A970004E40B633F0C32F13106EE59715A6C1569F
-:10A98000BABFA7E72B1CFF64F5609AD7E96A0FCD21
-:10A99000CB53DF74340EDA9FAD2EA0FC9034EF3928
-:10A9A000ACE7615F5BB1FDF81D4DE66428CFF72889
-:10A9B0001EDCDFC33DCCEF07FC6DB07079B101E464
-:10A9C00005D2CF88EC494FDCC9909F6B7FC1FD3128
-:10A9D0003576767E1CD2D5E04233D69BF63DE85CD8
-:10A9E000A941FABED23E397F4021F89C3F1043F086
-:10A9F00090702A17F83ABFB7EFCD43A0DF03A04706
-:10AA0000AA30BF96CB269A5FCB47E17E54128CEDDD
-:10AA100017EF49EFCC1CB84E686CC37CDFCE0CF04E
-:10AA200010617FFA093C979D7DFEEE44C4CBD9D8D6
-:10AA3000BABF7C827CEF33CEF740E3FDEA31E48B92
-:10AA40005D13DDF743EE8205CE6974AEA98C40B983
-:10AA5000B8D0CA349ED7FA62FE6C38A3F3EBA09D3F
-:10AA6000C923713FE178AE5E41BE96A9B85815D0B2
-:10AA70007DC6CE47D27E0AF3DE5E37F793C7203D10
-:10AA8000EF37F92C20B7CEB3BA0BAF225FDEE270FE
-:10AA90006F6558DF1C8EF57F6EE1F3F26D8573BB39
-:10AAA0000BFBF3131D43B915CBCB5E7CB40BCEFF70
-:10AAB00035D44B20FFDABA08E277AF59DC27AAB0C9
-:10AAC000DD13BCBF677E71CFE7FB307DA03CEF1E7E
-:10AAD00048FBA7C5523F737EB5A00FB607B9CF920A
-:10AAE000803FFEFA6525100670CB5E7F7079128C70
-:10AAF000D76F6393A90BA4B95B941A4CFB762B38E0
-:10AB000086F2F6DA3417E1ABFF8E5415F5C93E5DD7
-:10AB1000FC9F5C4FFA805E4FC85AFFF5C82E2CA8E8
-:10AB20002FF451EACE2C037A58DDEDF779FC9C58CE
-:10AB30004BF3D8533FF9FDDB18AE0334119C77A1DA
-:10AB400095EC14B85C0BE4CFEF4EDF84F68CBD2699
-:10AB5000DF26925F455C5F39EFF53D8A74560EF54E
-:10AB60007D902FCFF5455D07E5E59FF5700345B175
-:10AB70006E4FDE5080F058B8FBA1315DA0DEF9A128
-:10AB8000CC0DA860C57B2E8DC176AC1BE8D6D8CF86
-:10AB9000EE9A845BA1DDCFB3460E44BAF2AA7534B7
-:10ABA0000EABE0E33C22E41E6B04E024081104F544
-:10ABB0007E0E9FF17B6C7DCCC16416C44F45FDB207
-:10ABC00054B4B70CD0EC6E15F74DAA2FA9D211943E
-:10ABD000A320FF6E4B837A4956D1AF73728AF72A4E
-:10ABE000E49F55C833D9DF2356E60B8BE57AB38251
-:10ABF000F2D9CAE5F656E02F557941B90DE396E250
-:10AC0000B856A12F278390CE8579263F62F3936EA5
-:10AC1000F023C737DAD1A4DE323DAE667F23DA7B7C
-:10AC200022B4BB711C69376366B70BF5A215119E80
-:10AC3000AA34D2BB9A53700D205797A6417F0B556B
-:10AC4000D0C3D243F430FB8F93AB2F447896637F0D
-:10AC50003FB6BE91EF2EF9D6C472810E963C64A326
-:10AC6000736A8DB037D408FB564DE4203BF20B7667
-:10AC7000C4547614E4ED30DE436BBF4B22F3889F5F
-:10AC8000D430D62EDC0E001FD080EF04406E68C09A
-:10AC90000F865F6E5639DD371C8E1E80FC9679223A
-:10ACA0005D680730312D449E1AFB01BC6DC6758E60
-:10ACB00060114C0B919B1E1663C5FDCB1CB1FFD2DE
-:10ACC000FA870AFCC9750C15F6BCA12D1F4520DFBB
-:10ACD0005CF26D1EF1CF8ED6B75FACEF37B83E4851
-:10ACE000937A79F7E03C877DE334E33A879927A6A6
-:10ACF000A09E03F37F0DF13CFC1B937EFEDF87EBF0
-:10AD0000F23F761D7729CC67C2FDF9B5D58FFBB32D
-:10AD10001EE81BF773FD822C3FF281BDB01FEC785B
-:10AD2000AE9964253DB75ED849EBE39D645F7ACD6B
-:10AD3000C2F3BE19A27D182339523FA30BB5EF62AF
-:10AD4000AB7C2B1BFBAF8920FE596FF1AF49C3FED3
-:10AD5000EF8D73FB005F2ACA8FFE70DE10FCBBC64E
-:10AD600012B84DC5FEBEB6321C6F7D4C20B902EA4A
-:10AD7000AF5FD085EA7F04AA14DAEF86984C774C4F
-:10AD80007460B9272916F27BFFA192DC589F0B79DA
-:10AD900007F171B207AE9FE8490AEF84698289E63C
-:10ADA000A3B24AFA9ECADB7D62E1F56E15F8FB5844
-:10ADB000E007F639F1016D428419E9D8945EF46D2B
-:10ADC0001AE1DD93A4C07C1E9BD393211FBDB5E483
-:10ADD000C654A29BDA47889F4D173890FD6103FB4C
-:10ADE00020D4A3F99F1973B786213EA71687917DBA
-:10ADF000F4A3E2E5912E683F55530336B41B4FC9C7
-:10AE0000F7849EC74DE91E1AB7BCAE77FA97217436
-:10AE10005D6403BE01FDFF225CFB9EF6EDBE5C2A75
-:10AE2000DF07CACD0FB0AF3E9FD37327D935E6C831
-:10AE300073646036E2F540B39DE1F9A4237AA8413A
-:10AE40003C40BFDD855C277A45FC4F0FE7E71C33AC
-:10AE5000D00BE46BEA7AD339E7290BF32888AF3DAE
-:10AE600036C27FC124BB87EC8FD3C337D9A0FC0E79
-:10AE7000C1CF6AA687D3F79AFD917E9342E727CA8E
-:10AE8000FB7659A85D99D5FFEC36E8A7EC406F92A8
-:10AE9000377BAD62DC57237879942775E5002CEF7A
-:10AEA0004C74F09AC5154DE56FAA8CCAC3031931CD
-:10AEB00000C7B830AD5BFA40A43BC0B303FBE5DF8D
-:10AEC0004F08FA3A01DD22FE7C9591D42F6D7DC8A2
-:10AED0006B35DD36233E352B2F673F51A9FC84D3DC
-:10AEE000933417F2272A93695ED2CE74C26B25BAC7
-:10AEF0003F51A690BEF4C72A35600DB5E34FDA7E08
-:10AF00005F06B4FBE28085EC78337F597A1CBFCFB3
-:10AF10005C5E4EF6C899254BC94F7061E9178336C0
-:10AF2000C07A1A977F9AA285D8A5679641AB90FD03
-:10AF30007C43BA67503AE06776BA762DAEAF22AB63
-:10AF4000711EEAD717AC0D4FE27921A3933614BFD7
-:10AF50005F7CE5E436AE773767A09C5868E67422DC
-:10AF6000E56D85A0C34BE9DA48AC0F709B8572256F
-:10AF700022AB81F3BFA53F8EFF9FA9DFBA57817136
-:10AF80004AC3EB1752AAFA73B09FB34A204A492723
-:10AF9000386AB8AFCE390351087FCDC4F5BCD2EDC5
-:10AFA000FA75E11F7302DACD18D9C14BEB544F1873
-:10AFB000EE03E6B7E2FC4B9935583F35882FE8871A
-:10AFC000F0C51C7F9CF553C043C9B3BDF3F07C5161
-:10AFD0001AB3EF1743A81EB493FB456D9B97EB691B
-:10AFE0003B1FBEBE73621F9C832F16A4971D36792C
-:10AFF000CEA7F12FBCD299C64F10FBE48222E8F510
-:10B00000D9304E576E5817CEF3054E570F4B3EF9B9
-:10B010002CEFA734CE6742BE545AED24BA927C0975
-:10B02000E642FBEBECCE646A27F918F33246F5777B
-:10B03000266DE6FA9B38EFE284A17EC9AFF9389815
-:10B04000477E7EE6B964392EE9DB46796C5CF7EA27
-:10B05000746E9F0239DDF99F9D173313673F31A747
-:10B060007FC87A22AD822FB8132766A37FC1AAEBCF
-:10B07000F742A4F50E8F03FD0CFAEFB2BF07D3F928
-:10B0800079B2BB01CF5DD4E68336DC874F33921BA8
-:10B09000C6793C26DA3DF75C2B5E55614F672E4939
-:10B0A0004F2EAECF13FE3EB64AFCDD990CFCB81411
-:10B0B00061951684E3DE5C2D19E5C605E11FDA1BF8
-:10B0C00003F92CD4A7385E645EE2C34897CB3F9E59
-:10B0D000978CFEA837D2B99FCD08EF6500572CAFEB
-:10B0E000B1C0F9260BCFB9C71EFCB267703D5F55E2
-:10B0F0007B3C7342F2F336E4DA713FCEDF986B2F7C
-:10B100000AC147CDF6FEC75C00F773DBCD6E64EF76
-:10B110003566FF2F504FAFD9AED6211D41B91DE185
-:10B120007DCE71E81DAC376F634C1EEAE1B2FDFCC9
-:10B130000DF99E392178E8BB5D8F97EC3A7DBEDF33
-:10B140003E7DFE3DD441E3AFBE5D6E409FEF7F4C40
-:10B150009F67CD80BD41A80F70BCBD3CD87DCC059C
-:10B1600078EBEE57DDF8A9BB63D2E4F1A8476C5445
-:10B17000DD3DA1BCFB52EF58D42B4E6D9CEB46B489
-:10B1800017ABBE853F059C167F3AE618CAD5B3AC0F
-:10B19000EEF7E3012FF3EAD759CD2E5CB79EDEF729
-:10B1A0009A04FD3EC7ED770BFCFAF2B67C6199B4C8
-:10B1B0007B6486D297910E60DC5B3C30A1B2AAF72B
-:10B1C0001F44BE503C0E081FE8ECDABA7556D4FF97
-:10B1D000AE3C8E8FEB970E8F0BE1513898975D57F1
-:10B1E000358A7D01FB8EAD7D6F0CCEBBF0E70AE9A1
-:10B1F0001F852FF53A82F4D5B46BC64D94DE5240CC
-:10B20000EB9776C2F9F54A2012F2CEC1AE7D8DD011
-:10B210006EAE9FDB3B8A56D882FC90A19FCC308FCC
-:10B22000F521E530FFF9FB0E7EA740FFC51BF5EDCC
-:10B2300016009F46F953B2E5075BE877791EBDAE6D
-:10B240007E938AEB9E2BE62FE527F30D273FC575EE
-:10B25000BC09FB12FF0FE44E698216DF233E28472C
-:10B26000AF5BCFDB03DB2DC475973BAC2E5C77B9AE
-:10B270009D0522603EC722AD1E277CBFB42192EC03
-:10B2800074F36CA0AFE651CA308E011831F9CBBE11
-:10B290007A5725BDA73C8EE3BDFC2985CE69E568BC
-:10B2A0005CC5FCD33CBF8005683D482F9ED075FA35
-:10B2B000F57956CBCF7765E6C041844B096BE4E75F
-:10B2C00033C0A727C4DF5D06EBFC2816F537437BA8
-:10B2D000E6D6C88FE7E0FA58C5BE1F6CA1E5F29C20
-:10B2E00029CFC1D27EFC5486371CC7B108BD79FD79
-:10B2F0007D9E0C9CEF4A8B2703E1E05B1746E7FD40
-:10B300005B3771F9B53E06F4D84EA43F933E7EAB51
-:10B31000C2F5733683F3C321A61703286F9A1F8AD9
-:10B32000716F76517D9263EB1FE8CDF5FF7FA8A486
-:10B330000F35AFE37111EB7339FCD63F90CDF57F3C
-:10B3400029F7E219F5D756DFF664A01D823DC8E75C
-:10B35000F5092E2944BF8EE8AC4D467CCBF549BD9E
-:10B360009C15FF387FC65611A7D1BC2ECC8FFE8C02
-:10B370002F15EF5153887E3BA707971383467AB664
-:10B38000897AE4F798639A78FFF530AF390F9B5CC0
-:10B39000687F6B85B7C79381F2F3CB756179486796
-:10B3A0008346727BD4895CCEF72306308F1FD2721E
-:10B3B000D16F790F932E4D0C07FA837EBECCE7F642
-:10B3C000F0C8015EB2036E7571BE6F5CC73DA29F8F
-:10B3D0003956EF6F87B5331F0917369AEB1D5F2E6D
-:10B3E0005236F37901BE213FE85761643FFC52C8F1
-:10B3F00025095FA01B8A7B907C2BA6955EFCCF86DF
-:10B4000001BDACB3703A90E7B6107A11F8EF46F888
-:10B41000BD55E0973D1026E8C5C4FE8670CC777216
-:10B420007AB8CAF317E07B5D8F816DCF6112DFCCF4
-:10B43000EC1FF8CFFC2EE52F3FBFD7077A46C90B8C
-:10B440000F4531A877DA5C9BE086F6655B57467955
-:10B45000203D65F6453961FCD37EB5C0DF0EBCDF0B
-:10B460004578F3739C4309F1939E79EEE713709D41
-:10B470007FD96A71224BA8D86EA3F3D8C2DD0B48DE
-:10B480005F877C13CFAFFE1AFDA615FBF4F6F99289
-:10B49000671E4A7011BC7DC9A6444C03C90CD285F5
-:10B4A0005B2CAD7E641806F4EFE655383F637B9C59
-:10B4B000C765C077459D5A688D6E5B5E21F84BC5A8
-:10B4C000EE9F7F8D76C38ADD379E447E5F61F00BF1
-:10B4D000140BFF88D12FF09B1E7ABF33C087E20C7C
-:10B4E0007C30AF9E442EDCAE5CF3EC23394DA83F9C
-:10B4F0006C792B4AC90AFA07A4DFA4A56EF653AFEC
-:10B50000BA3ADE9717847D388837CEBF5CFB140CBF
-:10B510005682833F4FCB2C81A82178DEDB6421FD4E
-:10B52000B7ECF9A7B73D8674F6B18DE47BE9F3AFCC
-:10B53000FFFE3AD49F77593A8DE3CB7028217139B9
-:10B54000152E6E8F93F82979E975AB2B9B7F5F1AC7
-:10B550001BC453E9AE83568C0F32C27354DD416B6A
-:10B56000A3A31D7CD5358D213BD4B37FB5E2FE3836
-:10B570007D40619D53DBB62FDEF47A14EA6708271D
-:10B58000944F126FAD7834D487FE27BC3A80EA39E5
-:10B59000F19C72253C3ED58371BEF272248B817979
-:10B5A000147F62F38F43FCEE5C1285EB3969AEE4E5
-:10B5B00074FFC4CA04D4F78A2DBE0427A5FC7BF10E
-:10B5C0009377113DCE572A139C5944EF4926D22533
-:10B5D0007C49B8CEB91BA7D23AE7318DE8B1F8095A
-:10B5E000D5EB87F45B332BD8D5CEBE19DB93F3A90B
-:10B5F000939B01B9B0CE93223ECBF73B559CA3174A
-:10B60000913CBF4BAC99B1C594FF56E873DD7AB657
-:10B61000FABFEDA1E7D08A2DAB1B104F67BA793A7C
-:10B62000E33C010E3E0137E507E8577D2FBF33C7E6
-:10B63000137361FC02B503B93A0ABF63FD068B07B9
-:10B64000EDEC21EDC439918F7FA7181FE61D8EE721
-:10B65000E09309EDC77FFDA4A7E40BAC2134FEAB5A
-:10B66000433EB0E53EA2AF6F3EE07C66A17F620143
-:10B67000953758029DB1DC7F708A427CC2C602EDCC
-:10B68000EDF32D16B1CFF5E5304FB3120ADF035CB1
-:10B690003F95F4320FF4B240889E10A41F6BF03B2C
-:10B6A000ADFF57623D8DE4CF937EC0F9823F18D73E
-:10B6B0006FE417F93D0D714AA23DDBD8BEFF29C8E2
-:10B6C000277C346E19C877D447CA3EB6911E51F60E
-:10B6D000BCC58B703ABBE3F0EF6FC5F36D9DDCD753
-:10B6E0007A3E6CDCD7C52F0E6C775F9F5D9BDBFECF
-:10B6F000BE86EFEDEEEBB50AF1BBFF2E1F06C94784
-:10B7000076892BEDDFF91DF0E14A035CBF6559D165
-:10B7100043B0D059D89DF06480AF84AB91AF5A91BB
-:10B7200049B6C35719867484C053C251D22B631AC9
-:10B730008DD34AD7926E255DB7D2AD71DD7A781A76
-:10B74000CBF310F7301FEF2B16D217CAEA797C2201
-:10B75000B4A378BA0AB4CF53EDDAA3C99D42F37EFD
-:10B7600043BECE50DF63C87B0DF53543BE5257BF95
-:10B770006CDF612B3F3F0474F56C5563E93CD25696
-:10B78000CFF073BFD3EEAFAD3EA48FAECD56E493F2
-:10B7900096E5CC1709ED9BF7ABA4F75C743547A190
-:10B7A000DEB2328CEB75179D221FC3F3CDF1D65557
-:10B7B000C827E5F7E6306E87B9E86D8E8A0939CF7C
-:10B7C00037D5AB5168FF6DF4B382F6E35B6A683F2F
-:10B7D00035B28ECAB97E77319CDB1B2E86737B43D4
-:10B7E000BEEA48A9423B6C2D8F239CB36C5A14C50A
-:10B7F00061D4A7DF3C1DBECF7D93C20C308ECE8CB2
-:10B80000F10FB3392AD929E6A378C2D9F53C0E62E3
-:10B81000CE5A3D9EE739B650BCDCB76C29A5F3D6AD
-:10B82000EBE3174AD85AA2B3E28D86EFF563699F1E
-:10B830009418F68926ECC3C67DF2A1DC27B92C57F3
-:10B84000172729F879BE9A75F374C0C7C5632AB360
-:10B8500041BEA55E65AB06F0B858F43FE18104F740
-:10B86000DF42D8AFA83749789DC37DD4AB63FDE5EF
-:10B87000DC9ECF06FD14E966EFA7398F437A6EEFA1
-:10B88000C719AF61FEE53FA47CCADAD61F75E0BBDD
-:10B8900059C8A72F1EB031A4F78B07DE48417BE4BF
-:10B8A000C5576D74CEBEB8DCC6EDDC0722FD28623C
-:10B8B0002E76E37A71CDFEBFE634925C5EC1E5621E
-:10B8C0008695F0DC52FFF713684F6FA9875521DF8B
-:10B8D0003F1041FBA9E2D530B2335FDCFFD741A175
-:10B8E000F6B9FFEE7AA4FFFD62249BFE22D2710C12
-:10B8F0003F1754BC76EDD3E85F2EDF7DD03A1BCAEC
-:10B9000047FDE63F7390AF5E7C91EB53172C8D4F54
-:10B91000A28D3322E3D2AF2C4968E783CEBA30B68A
-:10B9200025A3FF645F567B70E170B80870C0750195
-:10B930005C8A511E74048FB47F5B787C3D8BF3B7B7
-:10B940006B18FAA38370513CFC7BA4DFAED0FAF9EC
-:10B95000F7037FCD41FE73A5F57A70BD03FFFFAC01
-:10B9600077D6BFED7A39BD7F85F235BE2DDDB7A51F
-:10B97000EB97FF83F23B23DD34DF1FB9DF7FF6FF58
-:10B980008CBE37FEDBAEF74AF87E53E03BD289FE31
-:10B99000CC8BFBFF33855DC5BA5FFB3FBA6EA9C791
-:10B9A0008F54DDC772A1FE5BACEE03772A6923EDED
-:10B9B000EA21A7321479BEA3F3D328C6E5F4287B85
-:10B9C00029E99FA3BA3E40FA720DCB23FF85AFABA6
-:10B9D0004A7E1D0A020138BC91984BF7AC9839D0C9
-:10B9E0007509E447269753BC98F15C392A7C7C01A1
-:10B9F000EAA78797C1BCA09FC3912627FAA84777DB
-:10BA00005503B61C4A9B303D9A3296E2FE473BF402
-:10BA1000E7ABB18673D28D2E7D79017BB113FAED40
-:10BA20000AB22C74BF620CD60F39571ECD70D23AB1
-:10BA30006F64B52B9C8EAB8753622F7ECE6C0B87C9
-:10BA40007F0EB7367012E768B3A86F849BD9717FF9
-:10BA500003B633333817F3F5D2795A9E8BAF044FC0
-:10BA600026CEDB6631B484AFB92BF7CF86F44B70AA
-:10BA70009170BF5A784B3C19E12EE12BE166C4C3AB
-:10BA8000D90C26CEB71CFE5DCDB966DC77C3845ECB
-:10BA90003FDA1CC3F35D1B542FED473FE16DD437F4
-:10BAA0006E33EAF5231C3114476ABCBF5034386644
-:10BAB0009002EB4D36339F0DCEA1E87B23BBEB7D8F
-:10BAC00066FFF2541C87DB77BB99B9FD1A76B72F56
-:10BAD0003C8FEA7BAC902F7C703EF340FDC264E665
-:10BAE00056787D161D4BE1714CC5383148B15D610A
-:10BAF00034EFB7B033F32FE7F824BCA0D907ED1B20
-:10BB0000D0AFC714CBDB47E5517B9F89B7F79821AE
-:10BB1000ED9ECEE3149A5772BB7CE1EA6E19C83FE2
-:10BB2000C68DD4DB996B7B717FA44CBFEFC5F7BB8F
-:10BB30006A7227D27D8A15BDE97CA4867BCBF7A0EB
-:10BB40009D7E278FD3295C75FBF88138BF9D716E70
-:10BB50009CDE9909BB06F1FA33EEFA10BE6BDBC32B
-:10BB6000E8BB2B531BDB0BE30114D7AC3DF0A16802
-:10BB7000EA616B220CA1D54D3C8F76C209BE5DEF08
-:10BB8000A07F72C21495EA4F603C0E93AD88A03836
-:10BB9000CCF1BEAFCD89D0DF78387460795398335B
-:10BBA0006511CCBF50D887A7897863359C692F3A37
-:10BBB000705EDD32D2E0FB78D67E7CF243627FA9F4
-:10BBC00023958DE867EA3E8ADBEF657DEC07FB7D18
-:10BBD000BC17B747158954E601AE547FCE1A5B53A4
-:10BBE0003A9E7FD65802BD20FDB0F7C879BDA07C33
-:10BBF0005C1A1BB301E17E8FCA36D37C9B0BC9AFA5
-:10BC00001099E9423C6840D2E45FA94D75A15DAC52
-:10BC100069445D00FD094D8FA6BA6B5C84658A0797
-:10BC200092E7ADA611811E68C76FCEE57E8913CE5F
-:10BC3000C6483C2FCE76D8F9FD4911573457DCA3BE
-:10BC4000E95ED3F8C035780E7D48257FCDDC87F8D6
-:10BC5000FDB03F3BEC7E05CF6DEBF93E656BF571BA
-:10BC600044CCE9263BD0ECDA11563C6FCE7178AC6F
-:10BC7000B84E7FA6B602D725EF23F641244097851C
-:10BC8000B58514AFA246C1BEC37D627645E139D801
-:10BC900018875421E28E64FE17E1DA03D85F51B4AD
-:10BCA0006B27D2CBE755E9641F3D2EE86E1CC655C5
-:10BCB000A23FC3DC9884F3198EDF11AEB1CE0C071E
-:10BCC000D17318433834599C1948DF4D2BC34CE8C5
-:10BCD000971BB79CD335EC33BB19DADF6766E1E815
-:10BCE00067B84DB49FB9CCECDD04F9AE76668E8CA6
-:10BCF00045BACA25BA4EECA315E17C4EDDCB06232E
-:10BD00003DCC5EBB8EFC31922E98B961741C8C7355
-:10BD10006A6B6A1EF2CD563EDD67E4965EA1F43092
-:10BD200045213A80F4603AD1C3A46791EEC78D0CE7
-:10BD3000F4589C85E7D132E641F99EC8DCA827B4C7
-:10BD4000B066F257B638AC2EB47F497E22F986BC75
-:10BD50002F2BE9601BC87BB385B1EDD5764A9FAB2D
-:10BD60007632734FC6765427527E67B58BD2BAEAC5
-:10BD70004CFAFE62B59BF2BBAB07537E6FB587F200
-:10BD8000FBAA0B287DB5DA4BDF255F02B8101F92A6
-:10BD90007C45F2A3D90E6B13FA2F255F32D2CD2C3E
-:10BDA00000EFF03C6A4F7C4FF23B5C87292FC88F35
-:10BDB000247ED314AF2F3115F958E30CC47FBE7A1B
-:10BDC000EEF997F15C5EEC70D3399D71BED702F449
-:10BDD0008A7049B1B27D6897AD59E4695A9D1A8459
-:10BDE000FF6DC50A3387D0D5ED9561CC1C2237EEA7
-:10BDF000A88AD1E56756BDFF7A67DC0FF1DA67885C
-:10BE000097133FFBEA893FC0F7A77E76A627E21B80
-:10BE1000E6B1F5111C776978EB3C6231BFC2427E16
-:10BE2000AEEEC27ED25DD84FF04FE87DE6A77EF63B
-:10BE300037DAE74D553617EAC59F20BE00BE7F149E
-:10BE4000F82AAAB2111C0B577EF1FCCBB8DF975A27
-:10BE500089DF15AD10FBD1700FFAF324467609D0B7
-:10BE6000AA299EFDF37BAD8108E8FF7385EF63058A
-:10BE7000948399187FB8E68D8F900F2855C7C8FF17
-:10BE8000AEE1BD3D9C9FCF724E77AFBAEA28D56335
-:10BE90008D5D63D0CF23EF25470CF0585DB07EA4B5
-:10BEA0006DC45F51E62196847E965AC589AADF1C2F
-:10BEB000F17DCE1A85FC9A18C73305EF9167AAB4B5
-:10BEC000AF46F432135E9FC2187CD2EF6A494E49E6
-:10BED000BA9DB316DAE1FEA8CDB5CE0BE1C745E2B7
-:10BEE000FBEC4C13A5F27B02F60BFD7559933B1D41
-:10BEF000F58A2E589E8569DE74846F17C718B312B1
-:10BF00004207CE4CB398071FFF29442EFCEFFECC0E
-:10BF100034EBDC2CBA0F48724C8E539499B70AE379
-:10BF20004B8BD68E402ECC6A2CEEC44E502FA9B52A
-:10BF30001F711FDBCEE3A8CB3A9023D2AE760AFF67
-:10BF4000792DAD9BECBE253B7FBD13EF17947C6A2A
-:10BF500023FC96F413715B59FE4193C900A9B7679E
-:10BF60008FFEF56751E4A7D8CDE33B21E576D6A552
-:10BF7000C5DC2EEB86FDD58EBFE8C8CE4FA3DAB563
-:10BF800063EF567F941DBB42F93E0AF508B99EFC4B
-:10BF9000FDDF26D03C94CBE427AAD8BF32A1BD3820
-:10BFA0002FA31DBBD5DE2DEC7A154B0BDAB5771B15
-:10BFB000ED77E3330DFE0333A37B66D27EC7D4ACAB
-:10BFC00068F4037C2BEE9F7474CE91F6EF8A0DD04B
-:10BFD000491CEC57B32B1AFD5B173BD0AF1FCAE4CB
-:10BFE000F2FFBCB0975FDCA1D2B9E7E28E48DA5726
-:10BFF0000B773C7814FD8E0BB728348D72D640F049
-:10C0000003B8327BA85CC338B6B8B6F36EF1F78CD0
-:10C0100046B952FAEBC84AA4B705758A672BCCA774
-:10C02000C5EE8A8E0F99CFA24CBE6F4A6D758308FC
-:10C03000DE62FEF3335D4457B2DE82FA07C9BE0CFE
-:10C04000F52E905EF44204E3F7539ADFC1799EDD4A
-:10C05000D8DF8DFEC20575BB16925EB123C289760C
-:10C060008533226E59F673AF18EFDE4CAEE79D159F
-:10C07000FEA3B33BF93B00384FDC6767146E87962D
-:10C08000ED6AC4BEA8C9E47A5606C2203E587F4174
-:10C090005D53540FA87F72DFFB943E20C659E068C1
-:10C0A000C841797C727704F9BF4EEE7E7CCC6B3050
-:10C0B000DEF9BA119D705FC8FE1FCFB4707C6C545E
-:10C0C0000B105ECCCFE366CA11BEFD43E719B7C9BA
-:10C0D000971ABAFF78FCD0D9DD2F4599B282F82C97
-:10C0E000B757DA934CB88F167991BEA39178A07F99
-:10C0F000EBEE893E946115F5B90CE99AF65F12D51D
-:10C100005F630AA967B3B829CED4B2AFD0C3EF99A1
-:10C11000887B51228E3F5FCD22BFE2AC7EAE69B7F5
-:10C12000219F7CCB42F858DCDB350DF9D3A5069571
-:10C13000E13C17A7B200EA274BEE89DC84724CCEB3
-:10C140007B567FCE0FCAD628CC03EB2BF3AB4C83A8
-:10C15000B40BE0DF87F494D83810E3249B52B95E27
-:10C1600021E3471F2B3679AC20075FCF8C157C5617
-:10C170007B742EFACF2665D279EE8495F954B42BD0
-:10C18000BDC8E34BCBD2785CF363221EBE2C369045
-:10C190001107FD9D13F82D9B14C8C0B88BB21793DF
-:10C1A00028EEE29C95FB3DF13BFA59CBF2A0BD8312
-:10C1B000DED9D064FB98107A2A2B72BBB09E1AEBA2
-:10C1C00076E53A70BECE0BA4E7EE8964A8E79A5EE6
-:10C1D0008EE47153CF846DB685E0EDE34CAE47CB72
-:10C1E000F73BD8AD3CCEE8610B8F4B7D786B92DF8F
-:10C1F0001F02AF872DDA0C8403AE03F5FB05D6DAF8
-:10C200000CD47FE57C1744D5D23CCF097A5F105E11
-:10C21000CBE3B9C57D60AC8FF9261187DEFCAC8D10
-:10C22000E280CE2435ECC5F1CF3CDB9BE1FA9B529A
-:10C23000FDF3F65139E89780CF92E76C015CCFE9C6
-:10C2400067B93DFAB485EB6BA72726BA10BF0593F3
-:10C2500036CC227BCD169B8276BED30AB32662F9FA
-:10C26000D6788A3F2FA9AEA2F8ED12601B787F081E
-:10C27000D202BC07747A6B6F8A373B8DEF3628F495
-:10C280007D0D7ED758EDAC9F203CB6F3F3D599E7F2
-:10C29000FEDE3B34DE5BA6255BF4F175924E64F95D
-:10C2A000DF047FFB9BD8E7FFC8E4F688F288BA87F3
-:10C2B000D3689D1CEE8027FE8E0D6B8C7C7C00C6A7
-:10C2C00053F454908F3CC602198FA3DD613B3F7F2E
-:10C2D0009DD961A1B8F59297233D14C7B6FA1A13F8
-:10C2E000C553A85C4F2F3101F820557EB69DE2CB97
-:10C2F0003A3D17966723FD9CD139B779AB2AC661C1
-:10C300000CEF539EDEC6E38EC7A12E49E5D9547EBD
-:10C310005AE44FEFCD26BD0FFAF7E0FDAA929FFC3D
-:10C3200094C37172F171AE77D989DF96B5FA7986C7
-:10C3300046A31C2C5F3D241AEF2BB27755867A8BCF
-:10C34000114E97CCEECEC867C7F7E6FCAC74EF137E
-:10C35000E49F2A15F7084A9F53B81F1AF621DEE713
-:10C360002C5D35E411A2CF772CAC27ACE75CDD83E4
-:10C3700051A1F8B8A637E773ADF5AD6EAA5F0AF51F
-:10C38000B19FD2556F45D17CB659285EC588C71F6D
-:10C39000DDFE39F547B56FA58F3A6E6769B37ED676
-:10C3A000F01F9F42FFDFEC0873FBE86B1DDD833B52
-:10C3B0006BA99B87EB3FFB7C18F1ADB3319C3F9C95
-:10C3C000047EEAEB85F318FB4B8AEFFADD64BABF13
-:10C3D00037DFAFEF578E3BB437E7E3E571EE688C9C
-:10C3E000172C7F97F341C0CBCDD4FE5D0BB537AE94
-:10C3F0002359B46BDD9FCF47103D9CEDC2F172769F
-:10C40000672F924F4D319CCE61BE2978DFEFECF360
-:10C41000BD72E91E1D2A3D400F25E2FC7B36A62E8B
-:10C42000C51952DE6411E7B800D444BAC136C0DF82
-:10C430004BAAB8BE556A5F4BF12518AF3B288FD287
-:10C44000802DB66DDC2DD02B9D2F1FEC2DEC983858
-:10C450005E828813273DA8CE8A7C5B13FA62D90ED0
-:10C4600063DC2E2F5F2CDBC36C3BC93861A4439F78
-:10C4700042712AA52B162DA0F8FBCA75B7E13E9391
-:10C48000F32F35B3023CA735292ACDA3298CDD3102
-:10C4900009F5CAD07142F4B97B83E3306702E9B190
-:10C4A000A4F42FEBEDA2EF98AFC57BAD2B94B53480
-:10C4B0004EAA3CEFF27549380138AC1827D83442FF
-:10C4C0009477B06E394FE3BA5BF5AEDE9CEF37A5DB
-:10C4D000BA7E3914F1FCB64AF77F2F7DDF3F3AB6BA
-:10C4E0001D3D2D28E7ADC1785998FFE6DE8CFA99FD
-:10C4F000D79BF3B5528CC78579666CD4C78B676EB2
-:10C50000D1E7FBECD0E7B376EBF339F5FABCFB8867
-:10C510003E7FBF1817CFE178DF18CFE198E239DC12
-:10C5200065E3E770CCE3391C533C87E3773C8763D2
-:10C530001ECFE198C77338E625BCF13C8E793C8F5D
-:10C5400063F9FBBD39DF2E13F1968807A477F64A0D
-:10C5500098EE3ED2C5FDFC7E09D001DF3733ACB486
-:10C560006F1EC31A741EE176A72E93ED2E8C1F5EEC
-:10C570001BA7EDEF1D8FF7501A562521DECC8D1429
-:10C58000C75AF12A8F632DCB0B73A0FDA371E5C9A8
-:10C5900055181EAAC56987B0FE454BF336846F79DE
-:10C5A000D561BAAFDFB8CCF5EEF51C7F648761C505
-:10C5B000B1A44715A29C8BED188FC67872B6561F92
-:10C5C0003F6E8C2737C6911BE940EA7F4F599A93FB
-:10C5D00090AF7FF1AC7D2DCEFF8B30711F66BADD41
-:10C5E000100FE0207EB2F8016533CAEB2F7A733D5D
-:10C5F000AAE518E8EBEDC85999CEBEDC9FF4F2D657
-:10C60000FC5AC544F1E99A87E4D01231A714A5B9C0
-:10C610006935F2B90526929B97405F237DF003951B
-:10C62000F4077C572B743DF8AE56287DE1BB5AFACF
-:10C63000FB125D74F5F15D2DFD7D893EFAF8FC2954
-:10C64000CB0EE2B97FF2DAFEBA7A73BC430C7014F7
-:10C65000F316FAEC1C901F1ED42F976E4841FC2E47
-:10C6600059D0D2B41AF0BB644F981BCB8BF1FF802A
-:10C670002F16439F78EFB278B7B8BF5CA597C3B3C6
-:10C68000851C2A36339F33364887C54EE68981F6A6
-:10C690000BFA34E4E0FB590BDE7C7F90330DCF19AD
-:10C6A000233A233F4AB17828AEB66C57CF9865D06D
-:10C6B000EF373DB4D83E80972F6B0FFF6226CAC379
-:10C6C0005DFCFCF7C5DA97A228BE4CD05B8AC51981
-:10C6D0008E78DF54CBE3EBD07EA6C606E962536DBD
-:10C6E0005C780F4770BD413AF89EF004F8E1769E01
-:10C6F000E243E41769A913EB1DA1F850CF96EB9321
-:10C70000EF6EB115BC9F3B45FE4B71DE90EB3CD705
-:10C71000FB608E0BEF7554EF4B51919F9B766CC372
-:10C7200073C83F6C5A769F788C07EDF9077C87AD0C
-:10C73000E443BE9E3FAF1F15752DEA9FCF5BDCE340
-:10C7400020BFBAF6692B9E2B4ACC7E2BC5673EBB19
-:10C75000C98AF1CA376CDF44DFE76D2FA478CCF9C2
-:10C76000AC92CEA3A7E43B09021EC523958D4E983B
-:10C77000F7837D389F2D0EE7FE3DD08F5EC7774A49
-:10C780002E6D577231CE678A7797B510BE8FE9C389
-:10C79000F98C719FB41C9F9C1F4FF0E0F7403E64E2
-:10C7A00070BA4F6FBB2F265F4EA57D31E5725F3AA1
-:10C7B000A74D0DF4E6E7E12CC379F8B8CAED79F599
-:10C7C0007C1F145B039D26E33E3960213DB7DCCC22
-:10C7D000DF792A877F5F07A977A8AAA3D78AD11113
-:10C7E0003A7A9ECE6275F7696EC1A09290FC947100
-:10C7F000E9BAFAD3A6F435D07F5EB09CF8C875BA12
-:10C800007B7FE54B7D2E85F4CC91FAEF8CC71732F8
-:10C810007693AE7D399B14AC87F4BD45E1E79EDD90
-:10C82000319BD10E586CE2E7A7E91AFFBE701FFFDB
-:10C83000CEA633DD3EEC9EEEFE03978B16F21B4830
-:10C840007BFB74FC773BF0672CBCF51E3BDEE347BB
-:10C85000FB84EE7EB7F017E2BC110FE5C29E549E3A
-:10C86000C9ED49E5BE062BBE9300F037C7C5523D62
-:10C870007B1CC655D62A646FC47429C559EAE3B433
-:10C88000B03F8C7F5C784C2DC47D622C2FC6778A9C
-:10C8900010BFAFF2B8D48568178A6AFB3EDA42B49B
-:10C8A00013A17DCBF01EDA877D5CC26FE75FD505F3
-:10C8B000E1384EC9A57B9B3B0E5A313E6FCA949816
-:10C8C0005CDC3F463A93FC1DF635C515B61C3F4C63
-:10C8D00074D6526C263ABE123C167AB89DD5487F63
-:10C8E000F3588315EFA7CCDBADB8F15C8AF5102EB9
-:10C8F0005D902E0D70898B6D0B0F09A756B819CA64
-:10C90000E7330EAFF9FB143FF2C7367012F033CEA7
-:10C91000BF23F8C975CDD3B431C827E4FAE6E33AAA
-:10C92000701C58078E23FD166CB071BFA693FD6A6C
-:10C93000A197C7D91AE963D2656E97B9E5B299D2C2
-:10C9400029E3F4FB13DBE13E997A3981CAAF967E85
-:10C9500016C23C512E5C2DDDC8F5487E1CDC27FC40
-:10C960005EC295DE3932DA279BFA88FB1003D94084
-:10C970005D7CB3E0B7C6F6C6F866A91F18E54E6140
-:10C98000A489E22D5B1C69A47748FEAB09B9A2AD6E
-:10C99000FC96EA69508FCFC6A393439AB0132E8EAC
-:10C9A0004CA377245296C52520BE0AC39C14D75F9A
-:10C9B000B84CA538EA42A8E70AD15B56AD484F41CA
-:10C9C00039F2F97DBD9EF4813EFFF93D9D1206C30B
-:10C9D000385FACB474B2BB82F53E5F999F82F11DA3
-:10C9E0005FACB34DF7B703AF88BEE23ED3CF3E2274
-:10C9F0003977DE743C6A3AB42F5BB9270AAF0F94DB
-:10CA0000AEE4F2FDE11E5A78DF8128E7376D73222C
-:10CA1000FC9C9B72D04E9C8436DFF8A05E51B232F3
-:10CA2000BF33EA1D65FF38FCA413EF852FB324A0A4
-:10CA30005E7AFA0390930AC939D2274E854117E4EA
-:10CA4000878BA4F7CF4E29CC83FEA873A6837F598A
-:10CA50008DE7C5DCBA8C8082CE532DA92FDA5557CD
-:10CA60003E4DFA4CC9FDCB32F01D426D59CFE8F670
-:10CA7000EC2932DD26E439EAF598A25E8FF135A87B
-:10CA8000D7631EF57A4C51AFC7EF151BF47A619A44
-:10CA9000F06F49BB73F79AE65CF4FBF946B2CC4AF7
-:10CAA00092C30E7A17788912EE46FEB4047528CC2C
-:10CAB0007F16417607F6C18D3A3CCB7783E5BBC044
-:10CAC000C39A41570BD927D75FB6B3D07BBA235847
-:10CAD0008C2E3FCA9EA4AB9FEF4CD595DF90D85BC0
-:10CAE000577EA32B57971F9B79ADAEFE78F7085D55
-:10CAF000FEE6C137EAEA4FF44CD4E52717CCD0D58F
-:10CB00009FEA2DD4954F9BBE40573E435BA4CBDF9D
-:10CB1000567C8FAEFEED95CB74E5F29DE47A3C8FAA
-:10CB2000D9F0FD173BA5F2BDE4BB5546EFB10D1D95
-:10CB300065E276461B97474BDEEEE908A583D97D73
-:10CB4000B91E7430CB330BE955BE8729DFB95CD4ED
-:10CB500097E3359905147E1E6E48423A36D63396D1
-:10CB60000F8D3874C905B8FCA4EFDB53CDC02F86F8
-:10CB70005E73A87F3AE4D3B2E26EA1FC90432FA586
-:10CB800039F15C3AE31633F0ABA1FD0E5DC2F2DD84
-:10CB900059893C3F99916A3268C7BEA9182F3BF466
-:10CBA000FAB4B56E6E4769F7BEBB4C111E784F1CC8
-:10CBB000E1816900E818D34340C7981E013A9E639B
-:10CBC00061EC28D031A6C7E07C8ADF7F0BE7534CAD
-:10CBD0008FC3F914D377E05C8A69039C4B31FD5D08
-:10CBE000F5744A3FA8D6A8DDEFAB8B29FDA8BA9211
-:10CBF000BE7F525D45E91FAB7DF4FD81BE8A90E3A7
-:10CC000001DD7BA31DBD2B2AFD9CD2AF5953C91A50
-:10CC100023906F349A63BEB207FD951DDB09CCECFF
-:10CC2000AB107D2D5BF16CE84BE37775121F17DFBE
-:10CC30005DA9DA1388E70F5327F7ECAFA21CAB7C92
-:10CC40001D436D3E34B5FF7EE422411FEBB33C9B98
-:10CC5000B1DD303BBF9F3CCCCEEF1F0F3337D4202C
-:10CC60007DD57CC75C18FF733092BFFB51739FD991
-:10CC70008F7650E532DFE7C33B31CAD77CD748F720
-:10CC8000958739DD8928AF64BED5EF8F7F42E27C7E
-:10CC9000A41F5EC6F78CBEDC300AF585E10EAB0B37
-:10CCA000F94868DC00FADB0F467E25E7C3703CE9F3
-:10CCB000DFDFF21D0B9872827EFC61F68654B41B96
-:10CCC0000CBFD3EE0E8D5B92FE7AE572A38A765589
-:10CCD000199F24C791F38D34437F79C1F8A361CEA6
-:10CCE000BA5CF477D4943BA8BFCEF0DD9A47F53C0C
-:10CCF0002AB5ABCB45BBDCF03207C5C1CA3881CE03
-:10CD000062DD508FD639FAB2467112C3459C04F6E3
-:10CD100063E7E53EEC6778A74012C6810DAFE4EF0C
-:10CD2000903DA1F0F7E865DC02D68F08D9B7384FFF
-:10CD3000ECB7C7DF60BEA847793C04DFC9F25CE707
-:10CD40001279E977B48F24FBD628C16B1E4ED5BE6D
-:10CD5000403AF2DA9C9F45D0FE4EEF8676D3894268
-:10CD6000AFFF27F4720ADBFDF7E9C5C3F1DD95914A
-:10CD7000BDCD4837122F12CF1DD191C47B489C19CD
-:10CD8000E1B9356E4CF463A4AF8EE84AD2D3303BA0
-:10CD9000C73BE215E3D4241D2997F9BB6EC3CBEC46
-:10CDA00024EF241D19E9A02D1D71BAACB9CB4EFD9D
-:10CDB000B5A5A320FE111EFF3A1D35AAE8BFBA5A39
-:10CDC000FAB9A3998D8986A26969DA22C46FE165EF
-:10CDD000D751CCCF6623C62049C9720DCB07B62DDB
-:10CDE000D7BE69B64487D0D9304167AB3BA82FEB9B
-:10CDF000C9772F64FFCF7430FE5B426F782B4CC62F
-:10CE0000A9781CB9838271A34BF2397D15A4AAA419
-:10CE1000778CCAE2EF9F3307D7B35DF017F9F14D76
-:10CE20004C3B129D8AEF947AE97DD2319D0CEF93B1
-:10CE30000AFDBCC0E0E7BF29EB06D2CF6FBAC23B08
-:10CE4000D7E3B3847E9DCA52AFF21DD2295964D76D
-:10CE5000FEB1EF90F2F76B478BFD9E2CE829DDA524
-:10CE6000B2A1B1F89EBB6646E17204DFAFCDC177D7
-:10CE70005E7D94BF91F9291DCB02A4478C074184A4
-:10CE8000F99B19A37BFB872326CCC43B87A3FA8F8E
-:10CE9000EA81DF43DED95B90154FEFECFDC919F253
-:10CEA000CEDEA1D12EBABF7AC89E4E7A28EE574B5D
-:10CEB00088BDF44D90CF3D607D87417E63FA3AC8CE
-:10CEC000EF1E2047DF00F98DF99B3297316C37C692
-:10CED000A58F7B92EDC73A47C141AD63F88DCD79FF
-:10CEE000A52BC2F7AD985EA3912EDE8AB96634AE4B
-:10CEF000F7AD98CE269EDAAC9466BFDCA33D3D59D3
-:10CF0000EE87E07863683C237C253C8D7094F0FDCF
-:10CF100017E0F9607BF05C84E708B4DFDADF8F4A62
-:10CF20004C43FF26E7B3E51129E23DD2B773D43471
-:10CF30008CF71D42F31C5E752D33A3BFDDCEE1746B
-:10CF4000B29AF910BEA7710968F036D8F79879A49B
-:10CF500029340EFA659BB615E9EEE44695EEEB9F93
-:10CF60007F318CEC76A7FCDC2EB9D8A43D87E56533
-:10CF7000AA6BAD1BF5CDB754FE8EE8F78753264557
-:10CF80005E05BD6EE1EF1C94D9C7B48B4F79BEAC82
-:10CF90004CF310BF6086DFA3E86AE3EF41C877294E
-:10CFA0003BD2B7E4EFB874B5717E2DF1BBD12AF452
-:10CFB00000E86710F0D9E45F86D379EBB104CF21A4
-:10CFC0005C1F9C63E8FDA996AE91249F0E89B8B8BA
-:10CFD000E181BEF4DE5A81F8DD8137C47BEE8744FF
-:10CFE000BCDC910CED6D6CFF86EB5057B43F5CCF11
-:10CFF000B81FE846077F3FFF6ACFE71F6689F8A1A1
-:10D000001C967355BF9310AFD27D8AE12C83FCF040
-:10D01000A370BEC8E7DE9C6D463919F23B09B4AE79
-:10D02000FF6BBF93C058B38AEB4A762AECB1D4ABFE
-:10D03000FFDD04559CABE4EF2714F0A236BF9BF054
-:10D040007854018FCB77CC6BF7771392C5BBD6CCD6
-:10D05000C5E586FCDD84FC44BD1C19E51C71C44992
-:10D06000A9DECE937C85F8B1F86C213FAE16FFE5C2
-:10D070008CF0DF1A67DA89C73F0DD7FAFC12EDF39F
-:10D08000A33A59DC7E575B3AF877FB5D948EF064E7
-:10D09000FCBD14239E8CBF9F92AC9699E91D4881DC
-:10D0A000A7E9F017F174BDF87D8BD1F8FB16EC7F82
-:10D0B0000E6FE30C78FB96AD1D88EF965E2CE47C3A
-:10D0C000BD23B91F9EEA99940DFC6396B01F49FBDE
-:10D0D000888CCB35FE7E92B403C8785DDF488E6FB6
-:10D0E000DF8908F25FDDAD3646A29C3961E2BF9769
-:10D0F0009411AF69D8FF1D59950AC223917977CD54
-:10D1000083F9CFFA8D2D05F3B3BAF3F7225916FF41
-:10D11000BD2039BF59C93C9EAB385BF06F378FDFFC
-:10D120002ACDE676B248B793E2CC0BB398889F65D8
-:10D1300029B3B2913E8F87F542FA5BCFED818DF82E
-:10D140005E65A7E07B95A8A7A35EDC4DE8A5351F2B
-:10D15000DBED9C0E994EFEF7F6DB7571CE7DB73B8D
-:10D1600075F9ECBA445DFD7EFB5CBAF2DC40A6AE1C
-:10D17000BCFF31B72E3FB061B0AEFE351F7974F9F8
-:10D180006B1B0B74F5879CF2EAF2C9ACF95184EF82
-:10D19000E6EC34C25B7745D8495C1C1FB3EE4EA069
-:10D1A000FB4AF2FC21E3DE3541CFC6734D772BD726
-:10D1B000EB6B92183FB7DAC5F994E9CF379A885BE1
-:10D1C000977A3DF3E9E3D665BC7AEB39489C73E482
-:10D1D0007922245EDD83F397F1EAAD7817EF871AA1
-:10D1E000E9F5856CE15733ACA3BB95DFAFABB9C7AD
-:10D1F0004AF784E4FC8CF33A2EE298B7DADB7F0F2F
-:10D200006A7F36B7AB44F6F0EE417A7D12D815C18D
-:10D21000B3CD78EE46FCFD819A7BADEEE5AE2B8F6B
-:10D2200037AB1F5FCF4C7C37378BDE5FA57B8172BE
-:10D23000DCB7057DEFE9A7B4BBBE59D13C3E8E45B6
-:10D240005BE95E4BC7E371B8265AD90A7AB74ADC64
-:10D25000F3B87D6DDD035834D35A6BE10F0FF82D11
-:10D2600068471B3712F4C45CC0C3334B1E72805E28
-:10D27000F4649599EC621F3C7FEE16D0305BEFEDC5
-:10D280007487731AD2C938C43FF47B533F1E9FFE84
-:10D290006D365F5FBEFA7DEB7D0B9B8EFF33E2FF49
-:10D2A000EDD01DD1A35CC7FFD6FD0B49BF4638C9E1
-:10D2B00073391372AD879897849FDC17127EF2FE44
-:10D2C0008B6B91C5BBD941F7680A302E4FE2EFF660
-:10D2D0007E9C2E7BE57078603DE4471DD5CB57B32F
-:10D2E000A2D15FD0C25CD1CE2BD8CDFF97EEA510D6
-:10D2F000FC3BBA4FD7119F68C31F3AB85FD7117D67
-:10D30000D29FABB86717C22778BC94C087BF878904
-:10D31000E2125647EAF7F1B41C2E17FE2EE5850FF0
-:10D32000CEE77A3EC1D0FF51B352157C625EEBEF7F
-:10D330008DE0F7B92B2DA47733E67D18E334FEBCDE
-:10D34000DE42EF3C0EF730D26F8A362AFE4D4AF0AD
-:10D3500077BE0A7D86775AD4EF493FFC76ADE2C4AA
-:10D36000DF8B98BD465F3EDFC17FA764AEF1BD1A7B
-:10D37000E98FBBC2B9BE2047E8E56EE626BD4CC4C6
-:10D3800051148B3A46BDACC5CFFD8D782E57B91DD3
-:10D390008BE2EFA4DC77A1BF2BE41D16806B78260F
-:10D3A000CAF115E676E3225BE1DA41DCC73987880A
-:10D3B000FB70F0389796DD61DC3F2CFD70A2FE39E2
-:10D3C000DF252AC7FAD8DBF95C1EBF22FD6F46FFB6
-:10D3D0005E8BC344FEA996DD9114E7807EAF68A002
-:10D3E0008733A65D09835383F3D31A559DDFC8980D
-:10D3F0006ACBF6D079F2E11EDAE21C8C6F37BBED16
-:10D400006EC8DFE73844EF788D137630E37C5B7FBE
-:10D41000F76F287F57A7C5C7F5DD9602FEDE09F036
-:10D420004786FB49C6734C64A0DD415A18B896E69E
-:10D4300073B5FEAFC99773B9FFF7F2106AAFADB914
-:10D4400096F2DD573CB008EF194DAD996FC1508091
-:10D45000C64797E68743D3C66EFEE5E188B7114A13
-:10D46000BBFE8B0773B85C6934DC5B90A9DA8FEF85
-:10D470001B573FC9CF453CD73285F6C36285C9F8F3
-:10D480002EE2E7327FA956E4F3797EC94A9E6F14F3
-:10D49000BFABB04DD85B70DD98E2BAD12EB043D8A7
-:10D4A0006370DD98E2BAF13BF22FCC23FFC23CF26D
-:10D4B0002FCC23FFC214F9177E2F62DE945C95FBFC
-:10D4C000ED4687EC0FF4DB8D0ED18FD06F179A47A6
-:10D4D000BF5D687DF4DB8596A3DF2EB41CFD76A1CD
-:10D4E00079F4DB85D647BF5D689E0DBE3198477ED7
-:10D4F000E799A8CB4F06FD7F74C8FE46BF5D68FF65
-:10D50000E8B7D3F5A72DD2B5BF8D55E9DAA3DF2E45
-:10D51000B4FE1D558ACEAF7787788776F68638A217
-:10D520001F5FAAB701E9FE4F11FFB8CB82E745B5EF
-:10D530007E013FB785BB399E6B0B38DE4DFC9E8567
-:10D54000D23C83F0BCD4CAF3F93CCEDB483FE817A9
-:10D550001B6DE17E314CD12F8629FAC53045BFD8ED
-:10D56000E89EDC2F8629FAC5F03BFAC53045BF1886
-:10D57000A6E817C314FD6298A25F0C53F48B613BBD
-:10D58000F48B618A7E31FC8E7E314CD12F86DF4F49
-:10D59000A07FCE129C17EAF33D74E74AA043DDB9A1
-:10D5A000D2A9CBA33E1F5A1FF5F9D072D4E743CBC3
-:10D5B000519F0FCDA33E1F5A1FF5F9D07C748E8B5F
-:10D5C000F621EAF5A1ED50AF0FCD67D7FA5E47DB44
-:10D5D000D9F88D178E60DA18A93CA900CB8879613B
-:10D5E000C534F45F3686292931C0392DCAFDD346AA
-:10D5F0002701998838CA1CD66CA2DFEBC3C323C6A7
-:10D60000390418C5AD667F9744E569F2FE1DFE0139
-:10D61000BCE7EE66F47B34D2BF2EDBBB9953C55416
-:10D62000D60FE6DBAF671C5FD623FE19320FBC694D
-:10D630008DF13EB94B1D791837BB4DFC5EEEB6E55A
-:10D640003CDEDA4857F9425FDA66DA7508EFD33420
-:10D65000172A74EF3AC3CC8E59F2104E9579A84729
-:10D6600064F78B11EBAABC0E7F774CCE5BDA41815D
-:10D670004FD0FDC4A1CD0DA3A2A11FCD37827E1F27
-:10D68000679C95EB0FD80ECF957D7D8A6773087DDB
-:10D690005F23F471CDC7C77FE6A909BC5D386FF77A
-:10D6A000CC535104C7092B148A3B1BBA8379F01E53
-:10D6B000B447CCBBEF8E808AE315AEE0E3C97E0BA6
-:10D6C00037A6D0BDD042D6381AEFB5B0010A43BE56
-:10D6D0002DE106EB3B82EBCB80AD8276EC1F7B9F8E
-:10D6E0006AD880987C8C4764F58CDE151D3FE03D40
-:10D6F000DD7A09ED83A85F926BBD7C0ABDE33CC176
-:10D70000B76C39826FBC6FD1EBF1587F0B73A7BA3E
-:10D710004814D1FD63399F3E9E5D26108B2C8B35BE
-:10D7200098C214C4373B1C17423FB0F3A720BE7306
-:10D73000DD167A5779A2D969A1773A3A88D7B9E440
-:10D7400090F13A067DC1109753B3F4A314B4372F68
-:10D750008E3491DD64F19E08D21BB40D0AF135A917
-:10D7600007158A78BF4B2B5E8F9F8670DF65A1FE01
-:10D7700064BC4E79BA3FC584F713BA6CCA8955495F
-:10D780000F58D20FF500DF4BB70CC67A2BF9BBA2AE
-:10D790009756ECE1BF4B2AFC3BF2774EE788F8AF97
-:10D7A000C26C6F34C6C3C8DF5393F764E4EF984A82
-:10D7B0003B4FE1DBFD8F227E0B9F10EF7EAF29A454
-:10D7C000FBEFC6B8AB52A1FF2D5861A1B8AD05065D
-:10D7D000FDB054C4655DE9F74DD7F633E887F277BD
-:10D7E00072441DA676FD3DDA85E5BDCF9916CE07BC
-:10D7F00066EE62E4AF9AB96C9409DFAB667B38FDE4
-:10D80000CC5CC6F59C99AF78E8FEA6D41BDF15FA70
-:10D81000CCA4CBC904FFF785FE3215E35501CEE356
-:10D820001AC3441C5B12A5D32EF3F8D5490ECE0FB4
-:10D830001AF7F377375A7C36AE571D61FCDD380393
-:10D840007D4E34FB4D78A1D13D14E813F2E3511F16
-:10D8500082FEA6A37E1487F49E9A4FF190050ADDFE
-:10D860002332D2FB384BE5EB186F3B6E2B73FB5822
-:10D8700028BD031D637F3E85DE63D0C43957D2B116
-:10D8800091EE674508FB9483DB9F5AED14A8ABD259
-:10D8900023EA7F9A86F1C4B3D066D88596E1C1B8F1
-:10D8A000BDC82C5E7EB4DF9FA6ADC0BB1F1DD82DAA
-:10D8B000D49F58091E9A7C77A2033B02DA0F905F2F
-:10D8C000DE7E67AEB528845F3E9C3BF22BF7C0201E
-:10D8D000BE8B0CF72917DFD7937EFFA823BD7836C0
-:10D8E000C015F7C7ACE8C6BB8052D99FFB31CFE863
-:10D8F000C1F8FB92727D2C80F198B78A7C6C9DED0B
-:10D90000A3350E820BE59BFA9D9F867134E5F6C622
-:10D9100031487615599505189F1DE4539A273915F6
-:10D92000F9546E007F8FEFB8944306FB44AC9BD74D
-:10D9300037DA29666771FECDC47BE39FDFF7F24ECD
-:10D94000945B72FE9F5BF4F76A651AEE16F2A3FA17
-:10D950007FE65E89F13EC9AF92B5BFF783FE1F3601
-:10D96000F1F713BAA8B54CD88BC8AF2CF90613EF52
-:10D970008E04F1EEA1F78DFF0B290E70D50080000B
-:10D98000000000001F8B080000000000000BED7D70
-:10D990000B7854D5B5F03E73E69564122621210F1D
-:10D9A00048980402A94698BC20BC0F9147B068076C
-:10D9B00092286812268447B068236A0D2D2D139291
-:10D9C0006040F0068D82D4C780CA45A51A955B4198
-:10D9D000693B48B56A513148F5D6DE303C7DB535F6
-:10D9E000E2F5AAFFE76DEF5A6BEF9D99733213F0E2
-:10D9F000D1FFEF7FBF8E9FDF669FBDCF7EACBDDEC8
-:10DA00006BED93960D8A735D36635E87F5849200A5
-:10DA100065BB12B08D618CF9666AC13C46BFBFE53B
-:10DA2000307678B48BB114A8E4F5DEF3703263B5C8
-:10DA30006BAD6C233C7A6014D318D41FF891D5EFEA
-:10DA40008371AAAD475EB04399E4E6FDDF69BAC3CE
-:10DA5000C24C384A20D705FDAE6E8C716F84F6BB80
-:10DA60000B3C896E688FCB775BBD0EC6CEBA19F5BD
-:10DA70009F91E249C6E7D76D3A78FF5BF0E8070768
-:10DA8000B2ADDE7CC6EAF615AC4F73E17BDE74778F
-:10DA900009D41D4EAB07DEBBBE35D1EA82B2369546
-:10DAA0003576E5E33CBD59F3E361CDF89BC658817B
-:10DAB0005B610CFA7F50C0A8FCC8C216F07E1D96B0
-:10DAC00079BA7E266A671D5B35FB108003DF3ACB8F
-:10DAD00034339FA990B1E1562FD360FD2DE9CC8D51
-:10DAE000F01A0ACF6D85BC3D2629043F23DCAC8C9F
-:10DAF0006926681F0AA5B53004C74C6857E1B925E7
-:10DB0000EFE442968370638B703F723DB25C2CD61B
-:10DB1000CF16D84D0CD6B5D40EFF862166AAF9B320
-:10DB2000528B195BB54571DAE0D11287EBAA095027
-:10DB30005FF29285AD83FADC2497351DEABD70BE95
-:10DB40003BA1BEF8A602AB0BF65D8D6701EB58B2A8
-:10DB50006D02730D86D20F6551FF796579CD9643BD
-:10DB600099FB5D787C9AD503F05AE2D4AC49F9A1CF
-:10DB7000F6FA0E45F33BFAD7E7BB55DA67351C29B1
-:10DB8000C2AFE6A66CEB6207D65FB2ACCAC77DB97E
-:10DB9000685FF23DE817C07E7373D88B0CD70DFB1E
-:10DBA000DA99CDE72B0C1B7F318E1F363FF45FE4F3
-:10DBB000C17DB9E369BE3A27EC3B1B4B27AD13E0AF
-:10DBC0004070EADD0CE3B9681E3A8FFA80DFE2C6E6
-:10DBD000F598615EA85FEDF45B709EC5AD055606D5
-:10DBE000A577139FC7DB9E68BD04EA7566A735134A
-:10DBF000E789055824D3FAFC3BE16896005C921C47
-:10DC0000380F5B34DFD11F3E7562BD4B3A12AD4B0E
-:10DC100075CFB758F03C16C27ABA229CFBED78EE6D
-:10DC200029B89EE95686EF9B35AB1BD723E07BE6F0
-:10DC300086988D6C10BCDFB9D5920DF59F22FEA69B
-:10DC4000E07B1CBFE6E6047215DCF70D316E5CE785
-:10DC5000426707EDAF0FBE77013CE0F952A787E0BE
-:10DC60000B78E1630087259DFAF30CAD87C37749F4
-:10DC7000671DD1DB32B3D7EA0C5FC7B683B90AC0E0
-:10DC80006521D0B702F0674E6F16E2CBD9BBAECAA2
-:10DC9000A27DC23A11AEF16ED7ACB462C213C263B8
-:10DCA000892FB5459C7EE57CBBDC669A6F97D8577B
-:10DCB00074BAD45E4C43BA84F35DE78A4E97560635
-:10DCC000E3C1BCD6258ABF45E94FA7923E255D4AF0
-:10DCD0003A95F47BBFC5134853427CA676106B7C03
-:10DCE0002A029CCE0A3E72B5385780EB6F10AEB256
-:10DCF000FD7571AED5397A7AC7F170DCE7647B596E
-:10DD000020F786FC507F396F75127F0FF11EF1ED01
-:10DD100039011FECBF8AFA0B78097E51DFC72FF655
-:10DD2000B40D417EF1A4E2467EB16AF3A1CC5B0062
-:10DD30006EAB7E1E879C977DB8F2E1EBD3010ECCD3
-:10DD4000ECA77393EB5AFA7901F189659F4FE2FCD6
-:10DD50002210995FB8F2BC87916FCBFA923B7F3E5D
-:10DD6000CACBF94D00F9CD1F7FFEDCB189C84798B9
-:10DD7000DFE2B924B49FC5ED6F58EA1CE1F0E3FC83
-:10DD80006E63DEB93A3CAF7A87D5A5C2A3FAD63A1C
-:10DD9000E2BF2C8DB97395D0F91BF1A2AE55D1E835
-:10DDA000BDA6717EF55BE4D3F59BE6319453F2DCBE
-:10DDB0006062C6C6C13E1987AF5CFF4762FDE704DB
-:10DDC0007FBB5AE0F7D50DD3ADE9C9B8DFBA22E081
-:10DDD0008C6CA178BE7089FE79DFB939FBF8FC7ACA
-:10DDE000A497735DFCDCCE6DB210FF39B727DECF90
-:10DDF000607F1FAE7AE6B52BA1DF0777EFC862AA76
-:10DE0000FEDC58113F372C97C3B9B1C111CF4D2D4E
-:10DE100008E3C3CB1FE0E756FFF8ABFFF1AC8BF68E
-:10DE2000CBF9DD669B1FF9F1E2AE27E91C17B66F4F
-:10DE3000B16443BFC105D93A3E5EDF58E06400DFFC
-:10DE4000ABDB7758904F0C2EE07034D203941A0B52
-:10DE5000A333944B4A12E25F301DF14FF647FEF8B0
-:10DE600024CC73D30D31096C6C689EC9059CCEEA35
-:10DE70001B139370BEFAC6BADBD998903C30EEF310
-:10DE8000540CA797C5301ED2EDA9E9EEAC55849F7E
-:10DE9000A68872B7A8809FE3CF00DC31800F43E3F0
-:10DEA000BA1E41380CFD41AC1BF9C7C891413FCEA9
-:10DEB0008BF88DEBB602FFB443BF912B831FE33A7F
-:10DEC000460286E17B58C62751C986407D272CBB78
-:10DED00014CA1C95970B0B389E407B00DB5972B01F
-:10DEE00004F72FF1DB88BF56F6507B0EF2B164E6E3
-:10DEF0006E7185F0558E23F155E273B4FDCD2BE0A4
-:10DF00007CE57CFB3B95CDE1698D85FD257D85FD1F
-:10DF100001B2962685F625D7C7F2605DA83FFEF8C8
-:10DF2000921D1B619E53CDEEAC46C740FBED9C3964
-:10DF300024C27E8DFB9474B3C4CE691AE866501077
-:10DF4000D67DAE63C420943BA714906FF0DEA91B6E
-:10DF5000624CB87EB9AF5D6BA133AC75F75A3B9597
-:10DF60008FAE05C21BCDD89EB569547F7CAD8BCAE0
-:10DF7000AEB579F4FCE68224BE0F168C473D13F44F
-:10DF800001CE0F029C4E7A9A46D0BEE473A917F4D4
-:10DF90003883F14961FCFB74A3909B2CB819E99B71
-:10DFA000358D600FC3543D1DA7E24DF9889F7C7DE0
-:10DFB000F2BD9B2CBDC40F59BCD5F530905CDC4D37
-:10DFC0006FCC4C85F99676661728F05E4D53514F0D
-:10DFD00013B4D7B4A6BA916F2C75B8D6A35C5CEA1B
-:10DFE000CB76A35C8CEB2C38BB0DDA97B65EECC617
-:10DFF000FE3729CC83F405FC9321DC96B1BE9F66E5
-:10E0000007BEB65CF0B5E5C82F015ECB9A0E8D74E5
-:10E01000C2FBCBDC310528DF976FE376C25C136B64
-:10E0200057500EB77866211FEBBD4771A3BEC9EEEE
-:10E0300005FE6A0FF1577F9EA7A300E5D297807F68
-:10E0400030FE45288355DC579786FB60A08F3CCC7B
-:10E0500070DD1ED2EB07097CE9E93C11EFCAE7F05D
-:10E06000467D9D793513F2DD5542AE0DB7F69EB86B
-:10E0700015F59978937B27E797AFBB709F2FABCCB3
-:10E0800046F246F417FC74F84F4BEDC8DF56C5E76F
-:10E09000A4925EB54D25FE28F1A741AC79E98E8AA0
-:10E0A0002188374BA11DE5DD767C082C747DE7A522
-:10E0B0004310AF966C9979B70FE4589680E3697373
-:10E0C000701E9ECF7B3B52939A512FBCAE6514833A
-:10E0D000F6253B6ECDC2F2BD1D310B90DFCF70CE69
-:10E0E0009B9108FB5D766F62811A26377E2DE8F1E1
-:10E0F000DAEB2E4D457B60E55F0FDDEF1C01F3038E
-:10E10000AC11EE9F76C5F97DD065E5DA7D592AD050
-:10E11000D85F6DDE67916F7FDF74E0CA09C8FF15B5
-:10E12000FFAE74EAEF4A7546A0F73EF90AF8EE0230
-:10E130007CBEEEA76FD3387F361DBE6221BCBFF216
-:10E14000BAA713709CEFDF75749C139EDF3DD2FB62
-:10E15000229ED707CA8E5D4E144CDB768C41B9FDEA
-:10E160005B6147CD4DF25CB910E1FEB24A708F366B
-:10E170005FC33E85E02BEB35FE41A4CF7A03CCEAAA
-:10E18000C4D2C9485F7E4F654DA80F48BD463EFFCB
-:10E190008380CB7B833AB2102F56ECDA9A8572E5F6
-:10E1A000FD785EAFDE75D52BC8A7BC0FD9B8DE6E83
-:10E1B00066A427D7FBB8DECD1A805ED343F39F2E2B
-:10E1C00088A3F5AFD856A4938780A1F4FC7D332BA8
-:10E1D000C7750C6FE92D40FDEB1D7360299EEB3B6D
-:10E1E000A0D7A27DFB6B21CFDEE95067E1731F1042
-:10E1F00012EA23EF743C1D3FD211D2E3E28BBB0243
-:10E20000C8E7AEDB9B58A8729422FCBADE29F993CA
-:10E2100063D6D064D2C79C88A7ABF6BF308BF13AE7
-:10E2200008C2E8F0BC56E8617DF5BD4F925DB7725B
-:10E230000FD72756763DF962068C73FD3EA14F0835
-:10E240003DE53A41CFD7EFE570B96EEF096B7DB888
-:10E250003D9297B47E286882B6C2410BEE72A1BD92
-:10E260000D8B9808F8DD655AD80C4C3CCBEDE47A60
-:10E27000A5B997F4C38D79DD64975FD72AC6CBEB38
-:10E280005E9F43FB9D37385C1FB2175A08AEF27D84
-:10E290008007BDF7594CC218E47F81EB62DB51AEB9
-:10E2A0006BD73BCC58B65CE720397F6FA329CF0CE6
-:10E2B000F0D5945837EA714D76DEFF96D8849D5894
-:10E2C0001E88E5F5CF62B2484E7D66F23CB90CFA85
-:10E2D000DDA21E896123F0C87B0F99A03E2AC53BB1
-:10E2E000BC10E64F65403D2ACA8F8082ED1FFDF2CB
-:10E2F000DD225CC7D4E1C14F182CCDA2242E9C0195
-:10E300007832BAD0C9F97B7EB008F13DE579CEAF5D
-:10E31000EFB3B0769477CCEC61F3E17900F9179E16
-:10E32000FF17263FF2E3034AE0C170FDABBA90EB62
-:10E330000F1E9BA35D81752ECFF6BA711DDF532C86
-:10E3400097A0EAC25C6A2E8EFF9185B74B3DB64C12
-:10E3500030E14C618F5933D21CB8BF16012F45D321
-:10E360005813AC635DFEF3F5882FB7F5DA990DE627
-:10E370002FEB8D25BD3633A39CE45B8B808BE24A6B
-:10E380004699C39ECF37F96CB0DEDB98DD8FFD99DF
-:10E39000DDA0FF9A62347C4F39F0DB2F90DF0F5500
-:10E3A0003F3E3408FA0FBD4571B7409FDA7367EFFF
-:10E3B0007B9DA1FDEC2F40F82D4DF15E5608E7D96D
-:10E3C00073AEFC8417CEFB366797DD9DCFC70BDF9E
-:10E3D000C781D55F24249942EBFBA8F7ECCF9F2996
-:10E3E000C6D24E72A8EC80CAFD4D86F57C94E6320A
-:10E3F000D339F5DA0326ECEF30F91505FB1F7A1B4C
-:10E40000D75766770454D4E3ED963F85CB1976242D
-:10E4100033F1ECC5245AD8DF405918D2C2CF6FEA85
-:10E4200020BD7DF98342AE3FFE409C9384AF841BA8
-:10E4300073692C5CCEFCCAB1AB86FBB1381DFF40C2
-:10E440003C3FF7790EE917E70E809E1141EF94E506
-:10E4500051D433407F08E468B7149684E46C9594F3
-:10E46000BA420EAB62DC2A01AF2A8789C3A7D20069
-:10E470001F813746BC309EBB3C4FF6A3232F0CCAEE
-:10E48000A673BCE45F189DDF3A5C47CF1787DB803B
-:10E49000DC5886AA9DF066FF239E5F206634EA154D
-:10E4A000779948AF40BD0FF544C93FBCC807C6D2F5
-:10E4B00073AE07E631E21BB56A2CF9198D7C43F285
-:10E4C0000B6F2C9463906F74103FB845ED7DC1A421
-:10E4D00084F8C4F0F2E02528877BC0F4C7F6A0A931
-:10E4E0008B9EBF549843F8328C1D49C7E760AF94A8
-:10E4F000A01EA8DA1FBCEF348894CE0D9C3E5A2C87
-:10E50000FE7B96217FA872B851AFFBC86FF25960AD
-:10E510009D9D899C6F74AEC82079FE11137C648127
-:10E5200095F8C82493C947F6D6C20CB2B7FAFAE7F1
-:10E53000BAC8BFFA8BBFAAA3B661FB3C3BC9DD4E8C
-:10E5400094C750EFDC7C09B53F27F9D20ACE973A41
-:10E55000E769E9B1D83E6F8809E7DB9EEC7D1ECF05
-:10E560003D43F53F1283FAE4F763D9C3F0BC335B54
-:10E570004B47797BB7E259B814DFBF84AF3BB83063
-:10E58000F6F15DFC7802E84FEA698ADFB9314C3E6A
-:10E590001D1ECDF9FA70DF897B105EBE329687FAB8
-:10E5A0007C0FE2E7D8D0798155CE9A9242E7966CFB
-:10E5B000383789AF3E0B9C5F323FBF754AF4F34B4F
-:10E5C00016E7A734017E13FFE7E7738BCAF93BFB1D
-:10E5D0001518E0507E9CE20DE27E5B6E8073218117
-:10E5E00018BC19E175DFEA780DF7D163620D5D1192
-:10E5F000E8F643C11F184A63A08745821E1649BC2E
-:10E600005D63C0DBE0B0C4B371026FE1FDE7E23CE3
-:10E610007FC679FFAC1C1D870F0FFFB7BA20D23C15
-:10E62000FF25F8CF41BBF7D34292AF653A7DF57035
-:10E63000C1BB9928A7D8978786A1DC7D2AD9F33951
-:10E640008E1B33B297FCE63DE9BD16DC67CFC20FE7
-:10E6500032512F5AD4F45BA2AF0B5DE7BAB85A0B14
-:10E660008E9358996D0942995A99FD02E2CFB139BA
-:10E6700036972D821E7270CEE84CD47FBBAB4667B6
-:10E6800022DFEB86033C82EB33BBE291FFB17D35A9
-:10E69000C4C7AA041FEBAE1CC19F0BBE19F67C7346
-:10E6A00031EAB50E933B5C5F3096EF03DF0C00DF81
-:10E6B0007C17EC332CCF807D1600FDF514D86758FD
-:10E6C0003F01F61996C7C13EC3B27BAD9BDA5B2A08
-:10E6D00047EC0BC2397FDAAED0F8E8BF8DA4175FE4
-:10E6E000FB90CA02123EF07FC3BD712C9017AA2F77
-:10E6F000EB1CACAB2FD93454575FDC3A4257977AB6
-:10E70000A477CDC5BA712BCA8B74FDD6C58DB1E087
-:10E71000B926961770B8971710DCBB2F8F02F7CB6E
-:10E72000C713DC8FCE199F89F03C8A7047FBCDEC74
-:10E730008EC77390709F2FE63C5A5EC49F0BB887BC
-:10E740009E570C28A73E4478DB10EE762ADF4578EA
-:10E7500013DC39BC4F21BC6D08F73C2A8F23BC4722
-:10E76000E3B800EFE2F3C37BE51E5507876B1FD2CA
-:10E77000C3BBE1DEC106F80FD5C171C9A611BABA93
-:10E7800084F7E2563DBCBD6B8A0CFD18DB0470A813
-:10E79000C07F001D1C2D994D7129B39DF9E280AFFA
-:10E7A0002422BDC1FACD950AD78FE0D70174381F56
-:10E7B000FF01F46576F0F6D6858A1FF912EA4468FF
-:10E7C00057005C0371406715CE5167902F5D851C23
-:10E7D0004C45BBDE4FE5352C40F459C382545FC431
-:10E7E0007AB3AC505EAF06D6A3FFEE55BBF7C62298
-:10E7F000A0FBFF9AF3468F8244E9AE1B8D74CE1CBA
-:10E8000049646F463B27E0945C1FC7AEE3C4BEE09B
-:10E810005789FC1FDEEB8E1B73F3CD700E1FD505E1
-:10E82000C7E1FC2BEDDE07924D345F7311F2258BAF
-:10E8300077F46078FE6AC9F84CA47FE649D1D949DB
-:10E84000D1E6DB829B0538D495039C148CC371B848
-:10E850009CAEE27039B8C566457FC6E90D16F25721
-:10E860006E8DCBCA42BC3DDD363B0BF1AE79CBE8B9
-:10E870002CC4F7F9EDB3DF47FE3D539D5B8BEF9F53
-:10E88000ECE078CFD80DA477DD2CCEEEA48BB903C5
-:10E89000D05E3527DEED83FD787DD909B45EA639DB
-:10E8A0000AA05FBDD8777DC7F2B9389EDCFFE24D84
-:10E8B00036DDF97FAF545FAF62D6109E65E3395BFA
-:10E8C00043ED78FE6AF520EF007674D31F77BCF233
-:10E8D0009BB0F11E2B8A4F46BECAC6B3F17F53438D
-:10E8E000EF4783EB676BFDAFFC26370457894FEB8F
-:10E8F0008B3C7B111FE031C5DB8096481E5CDFE757
-:10E90000D73A9080F0DB12F7ABDB27215CDEE47EA8
-:10E910008EAD71B5C43F3E44BE9D8D7CFAAACC60DD
-:10E92000185F90EF07053F3DF6F3AB888F1CAA4AAE
-:10E93000A5784CF75EEE5F3E2EE8BEBBF2AA9A9B2E
-:10E94000817F76EF5149CFEBDEF7C90BE8A7E9EEFF
-:10E9500052DC02E4A6F071BBF7013F477EEBB150F9
-:10E96000FBC13D4FD33ABF2D7E5EB95FF0F36D7CA6
-:10E97000FEA5660FF117E65DA0DBDFDF8BAF9F8F93
-:10E980009F1FB3703CED3EA692BF8DF9B42379432F
-:10E99000C2F0B39CE36773958D71F9CAF9CCFC4A58
-:10E9A000A003D4F399AB046DCA0FF755A490BCDC57
-:10E9B000643989FAB413FE43B96D846315339F0C2F
-:10E9C00086E1EFCABDD03F6C7DF3B13D0C9F8DF861
-:10E9D000AA1403BE5E1CC2D74FD99759D61CDE7E3F
-:10E9E000644888EFE12F9CBF48BE25F117F8562DEB
-:10E9F000F235E02B8E62C0DB1F1666FF32A884F171
-:10EA0000950BE4635BE2FE4A72706BDC5F098F8FEB
-:10EA100056093C063D039F775FCEF50DE65F40F457
-:10EA2000B048EA11164F3CFA498FAD199C80ED278A
-:10EA30005A2B88EE243D19E73B2EF04FF65B64EE2F
-:10EA4000B5B823C843EF1A3DFEB0DD0B08DF6F36C3
-:10EA5000E059B4F18DFDE53C8B0CF15EE33C938B0A
-:10EA600085DED9557341F32119F6BD4FFA6D6C0857
-:10EA70002F55E4039FC50749FF5AA0D3CB8E978F2C
-:10EA800027BDEC68E52711F5B3E3959FBC3A1EE975
-:10EA9000ADDC22E8BD81DEAF10EDC675BC2BF4867F
-:10EAA00033827F9C12742DDBD51D6D43AE46BC5F57
-:10EAB000A3BA915F1D9B5B4478FE9EBF8AE63F5ED2
-:10EAC000A992BFA976EF77AE467F935C8F9CAFE2A9
-:10EAD000F24FE2D19FF629C00BFD631516774A2449
-:10EAE000FDC2088F68E34AFC017DF618EEF328F2B8
-:10EAF000516CF5EAE17414DF87F6F93B548AB719D3
-:10EB0000E17468CE68E24BC7770BFE0970453DBCE7
-:10EB1000E15EFDB92EEB8C33F09BC1BAF6F9555C82
-:10EB20002F93FC5AAEEFE89A1129CC71E1E72DC77B
-:10EB3000B9507CB956BC8F62F36F247F9374E38124
-:10EB4000A568982FC7D07E91A1BD505FBF403C3EC5
-:10EB500021F047CA9F1331EE9A4871BCE397D91A46
-:10EB6000C2F313FEB598FB87FFB558C4BDBFA2DC46
-:10EB7000DE69E083E77B5FF2BDA622CF23C8EF58B2
-:10EB8000A082E2D917CAE7C2E4FC93C548E741C5B1
-:10EB90008AEF4BBDEADA722E17B6C63D4E791A7F60
-:10EBA0006EE67AD1C1661BE1E15F2EE7ED7FF9B732
-:10EBB00077499F3AB47F6B42B89C9778F9FEBED9EB
-:10EBC00009E8173E5DF96042B81D20DB3FA87CF0E4
-:10EBD000F68944DFAA7BA073F9BAF64077A5B0079F
-:10EBE00084BEF07D73D7FF157BC06807CC54EF4D12
-:10EBF00040FE67B407DE7769094E828FA03B21573C
-:10EC0000AE15F0F98B454BA038DDEE222E570CF8EF
-:10EC100029E17056C26153C580787346C805595FB3
-:10EC20006A66040FAF9D91BECC3A1537C6BF304D12
-:10EC3000A514CEE54865C183E8BF92FD7F54C2F3B9
-:10EC4000A9E43CC7EE53BAD0BFF2DBD68A9A9B3117
-:10EC5000DF616E1CF155D97F996F60F9756C73E2B5
-:10EC600015388F779BEAC6475EDF8994F0F54B3DF8
-:10EC7000CDF8DE0A73C705D9D15EDF8E04B46F8389
-:10EC8000629DC1833156577CFFF7305E83FB5F3155
-:10EC9000577537C3FA576CE2EBAAF2A9EE1CA8FF2E
-:10ECA000B6E3C12B900E4E35594CDC3E70EAF0FCB9
-:10ECB0007047D16BD8FF7439972B272A2F4DC03C52
-:10ECC00038DF368B3BD7D57FBED108478CF3ECB30A
-:10ECD00099D07FFA7E938505C87FE1217BF9D8A67C
-:10ECE0001154BE8FF0E3F6359D7F5109F7739DEA0D
-:10ECF000A81FC2E9C945EB90F87262B75AEE8FC0FF
-:10ED0000AF8AC47C67BE7C82F0EDC5DD15248F4FD1
-:10ED100055F279CEAC7127203C7FB749253A3EEDBC
-:10ED2000E3E31FDC7F6BC244D8C7FB957C5FEFEF4A
-:10ED3000BBE5B509B0CF60A594C75C4EC9FC9EE0A9
-:10ED4000A61114EFFD732BB7BF25BDCB78F8A5AB8B
-:10ED50008F25D0FB52CEED59A05B7FF7EE53648731
-:10ED6000BDBF0966E372CE5180F986FC75B66CAE04
-:10ED7000FE7CE757C6E9EA8BDAF5F2AC793FE75754
-:10ED8000463D77E926D083D12F65B0F3EA9B8B12FD
-:10ED90004A917E510FC63C93872B5E48C57D74D542
-:10EDA00050BF4A1137ABEFB4E9F84155ABDEAE5B6B
-:10EDB0006CB0E3FAD975067924E1745D14F924F591
-:10EDC000B96E61AF1CB7786A22E553AC2EE17ADBED
-:10EDD00022A0DF348C1331AD6A9280F746848FB560
-:10EDE000F7D35CD0A7BB55F714D4ABFBD181410F4F
-:10EDF000AC28D7C397B97DAC54FA235CA4DF9F45F8
-:10EE0000FDBF7DB090DB3E9043F12897B41F97A0E3
-:10EE10005CBA50FFC105EBE7B5423FAFD5E9E7DD8E
-:10EE2000D825ECFD835557919FEAD8E55791BE7ED2
-:10EE3000ACCF4FE5D1F9A9A45E776C6E854EFF0C7F
-:10EE40007B3E880DC04FA3E99B27901F139FE6725E
-:10EE500069BDB0235B851D796CAEB0239319D19148
-:10EE6000D9ACB148FCECABEA6F8B5BF572C9BB4621
-:10EE70006F3F3E33DDFB5409E0872DED22DD738BC0
-:10EE8000B350EF3F34E0E750C6FDE7B7A22F00E0F4
-:10EE9000DE52C5F34EF139E6BF48B9C4A03FF28B4C
-:10EEA000AA4D17F937F2769F5A88E9720C553AEA5B
-:10EEB0006FE6754DE1759F43B4AB22EFCD02F513BC
-:10EEC000D9EE05A877615E4F5C126F4714190A7876
-:10EED0009D9014927FE8D78FE1A1755F02BC37AC9B
-:10EEE00032FB3748D798EF330AEAC74AB2096FD2E4
-:10EEF000D0A55F48E30730AF27D8328DFCCD15F69B
-:10EF0000041E9F073B7A60FC6BE6F650F9609A6C32
-:10EF10009899AF272A3E8B7EE7C3E7303DEC24D19A
-:10EF20000B3391BF654BDC180BE2EF7C872713E1B5
-:10EF300000F84EF2B5FB9756E2C307ABB81FB67B9D
-:10EF4000CEF8FB6E82E7639E70902FBD7BA9F483A1
-:10EF5000F7C687E3EDF135A74CC8977FBF8FB9316E
-:10EF60008FF1F89EEA175E81710EADA9DF5C8274A5
-:10EF7000745825BBC1E8BF9DFEC464B2BFAEBC5C83
-:10EF8000A5FCEEA3E52A43B9767453ACCE0E09F97D
-:10EF90007555C28F4F0F98A91D4D9D3CCCBF42FFA8
-:10EFA00026E66995F3737956F0B32E718E8F083D7E
-:10EFB0006697A09B4E41377708BAD960F4EFDECB55
-:10EFC000E9E6E83E301C40AEBF3EB7BE8CFCD6DB67
-:10EFD00018C5A1B3E7A81B8B617F17DBDC1684DFA4
-:10EFE000F4B9051C9E958A09E33715E50516A4F7C3
-:10EFF0008B07BB2CC8472BCAE7517D466536D9F92C
-:10F0000007D7807C447B3FDE9D89743972AE2D60CA
-:10F010004A40BBB188F8C4A4F74C3A7A2908C4EA3C
-:10F02000E8EEA2879274EDA3B765E8EA299E1C5D1D
-:10F03000FFC1E57A7A8C1D59A8E7BB8CEB8512CE0F
-:10F0400033D5C9E4E73A1E92A3D42EF511E9AF9364
-:10F05000FD015A3ABED62EE4C818A8633EDD86CA22
-:10F06000163BE64D7CDA6576F3F1AB493FB067EFCE
-:10F07000B5239D606815F3ABDAA5FE29FCF74C6358
-:10F0800086756D6218673D5ECE089F62463205F553
-:10F09000AF4E71DE778A7981AF4EB7909F8E9FE336
-:10F0A000E0B91EEAC73C7AFB200DE9AC10F184BF41
-:10F0B000FF88787F97C097E3E50FAE8B457C58C0FB
-:10F0C00048DF98A9AE5C87F1C4E37319D14957E0D2
-:10F0D000F9585C3F8E83F981CF461BA7F2E977AEE2
-:10F0E000C7F5ECB6D238150FB1A98827177DEFC444
-:10F0F00007AF21F8B6390FC5B0FE7278CC439A1B22
-:10F100008193F71E0B58A80C68C87FF2DE3BA26102
-:10F110003CF0A2BFECFEE07186F372B9D02EF0DBBA
-:10F12000C85F1F7BF8178B513E3FB66B7BE1DB500E
-:10F130007E67DD3D194D503EB2EEFBDB6F7285FC04
-:10F14000A5BBAE58BEB313EAA3BFFB9347F7225E3D
-:10F150005DF1933FECC5F55EF1C57F3860FDA35AC4
-:10F16000E219D2B75C9F719E34D6AE605C14F92868
-:10F17000F165B38FEA753EBDFD6394FBD8DF0CF0FB
-:10F18000AB687A8CE2CB69E2FDA397DFAAA830EFE7
-:10F19000DB759CAF74AFEDED9C61A1FE01EC0F7CC3
-:10F1A00092F235870E03B682EF5B7D0AC6C54141F8
-:10F1B0007263BC371DDA919F33978BF4AB2C89BFF8
-:10F1C00082AFE0350746FE4033E1599E884722FF73
-:10F1D000457E7FE7381E071FEA601A9E6FF9739B12
-:10F1E00014CC537BCBEB72935EB096DD3503ECE42D
-:10F1F0008B549E779157FED6D5782EB055B3B73045
-:10F2000034EE6EA1D7953FE7A0BCEDB7763B769084
-:10F210009E7FE40A53B87E58F6D89F9EFA1DE257A7
-:10F220005D0CE197516FE916F4D157B7B8EEBB0901
-:10F23000E0E3FBA59DDB559A2B93EC74B72B13F3FE
-:10F2400077FAFAFD44C6D3DCFF81FC7C7E751CC5D1
-:10F2500019645C492DFFB80DE97151696309EAEF42
-:10F2600019780E834371ECB7575829DFC0A7C452F1
-:10F270005E7AB478F5A171D9229EDC3896D6C11A8F
-:10F28000C763F9C98296FBACAEE8F2AA559C6BB491
-:10F29000768B957923C5950F8DE3FE90163C074B31
-:10F2A000D839387E7F35C687A39D0333FB0B29CF22
-:10F2B000D26E1F897920A9E2F1D6B89FBE8AF2AA40
-:10F2C000E7189757A94D9FAD45FA937E8BDA34D650
-:10F2D0001737D3E03D8B782F55C459908651FFAE38
-:10F2E00015F1A29E1A46F1A2D4A677FF1BE1B34501
-:10F2F0008C5FFB261FDF6A0E1C447CA975B848EEA4
-:10F30000F4A424B8F15E13FB92E7A764308E8F72E9
-:10F310007C26C6C795B3B075A7C656BF4ED7A7A65D
-:10F32000B2401CE28F62A77933D6D828AF55EA578E
-:10F33000A94DB7DEA08ED18DA7A05EFD5635B7B71B
-:10F34000D1ECEC1B375BA757919E655C877CAFC700
-:10F35000C2F6A1FD1BA667911EC6C2E719A1AB0BA1
-:10F360003F9ABE6E49B3EAF8C45B5F560C6AE4721A
-:10F37000C0953C8EFBEF101E521F937A5BBF710548
-:10F38000BD87E9973EE417328FA24F4F6A08B39BBF
-:10F3900072FABF27F3D5E4394878467BFF99E95ADA
-:10F3A000C278D2B302348E570C638A7364117C0D19
-:10F3B000FC12D816CFA7177A286891BA3C06A9572D
-:10F3C0004AFEDC23F86E303B487E4399273E0CDE34
-:10F3D000C9423D687C22D183D44F8FAFFD88E2EFD4
-:10F3E000B5A887C2FCC1751FEAEEA114974D1F395D
-:10F3F0009EFC73FA7C89B0B82BADD72BF8E64CD5C0
-:10F4000041792B3D2CD68DFCABC727F4B13FC6917B
-:10F410003E26F985913F5CEED6F3FFEF95EAF9FFC2
-:10F420003C6DB0C12ED4C7A9AA3C8678F89B7374F2
-:10F430007C53F29F5BD0CDA7A27BC943719DC38251
-:10F440005FBE26F4402B6BA4E776CC171D81FCBF72
-:10F450008B4A073B426502EBA5D2C99C945F93C4DB
-:10F46000DC5426330F9543582395698CE75365B0D8
-:10F470002E2A87B1235466B15E2A5DCC69C23287D9
-:10F48000B9A91CC93C547A9893E2E46FC607338F3C
-:10F4900002FCE65EC5C86FCF7C7BAFD1E09C7AAA48
-:10F4A000441D1108E96A26E3C8E77B8AB7CF91F5C6
-:10F4B000A7AFD1B07D3AEF5F3F7EFFCF7C0EE23742
-:10F4C000A2FD17BCBDAFFE6FD74CC7F72D26AAFF14
-:10F4D00040F47FBC585B82F8DA349ED17927166BF2
-:10F4E000CBC2EB4F16690DE1F5E325DAB5E17556B0
-:10F4F000A4AD44FC91F5B145DAF5E1F5B612AD9154
-:10F50000D779BEE99B168DF45DF8ED56C6717CC3C4
-:10F51000DF20D5DB4474B34731E3B9DA04BD59F1D8
-:10F520001C55A423B7DD86A587E7FD04631CC138FD
-:10F53000D300F68F818E82C89F000F2F51BC6D348F
-:10F540008F819F283E913F98AC8F9B00BE935F3583
-:10F55000B886DBE98C456E97F39E0FCF9916E6E7E8
-:10F56000CD098D1B6D1F46FC3D22F4BC6EA1E7BD8D
-:10F5700029E2C87DFB0E9A13CFDA43741CDD3E34BA
-:10F58000B3B3E1FCB2DFBEFF546301BA0E36D99CBF
-:10F5900028EF7A62D86B68A7F98EA90CF58CAFBA00
-:10F5A000DE9AA2594F72BE38CC49F903725EC16728
-:10F5B0007AF09FA0E75C3C48DA976E3B8737B73B11
-:10F5C00012C5BA5A66245D9647FE7CAED7E75B8EBD
-:10F5D000CC9B0DEB4CDDC4FDAA0948DF183A7BE259
-:10F5E0008F4E8CA375CC3431E4536DD2CF6BF0C702
-:10F5F0006D99B1CA19EE0F6E4BF02B18BFCC08C431
-:10F60000703F4432F3C7A01C2D779753DE8C4F75A3
-:10F610009663BD9A5D9107F5C59DAAAB1CE63DD4E6
-:10F62000F9F42AF4032EA9B6521CC3A2CD7A9FFB8B
-:10F63000FF78FE4692C0F3D60D367700E198E220BF
-:10F64000BF6D7E5B6139DABB2D8EA424C4C5A4EAEC
-:10F6500065E4376C71B85FC2FB1D3EA789F2139950
-:10F6600053B35780BEB2E3267339F2F1CC278B1324
-:10F67000D4B0759F6A3D17837190079C266A7F609E
-:10F680004D997D9903EF3182BD00E521E7490DF5E4
-:10F69000F7EDD007FD8DB7379CEC1835C0392694AF
-:10F6A0005B75781BE7D6D76D067FA3C5A017F48ED0
-:10F6B000177922E3D8383CE7B18F7E49F6EF2287ED
-:10F6C0008BFCEA65ED0AE5C7040FBAB350DF3CB521
-:10F6D0007934E5BBB4B6EBFDD1C14C9685F77DEA34
-:10F6E0003A14D257D5D68F9BF1BDE179AE741C6721
-:10F6F000B8BB37DD19467F0FFCE4873128EF5AF19C
-:10F70000C21AE111E3712161AFCA7BE575CE733591
-:10F71000A8F72FE978C383F04FD44C4433C72DFEAC
-:10F72000343CFF8DD3E7135DE23D2DD463FAE9A3AA
-:10F730009FC33AC3EE27B425E7C4E2BC21FCD5122F
-:10F7400070BFA73B8A483FDAD95E46F7018CE3DCFD
-:10F75000B69675A1DEDAB6D6DE1549FFBD2DCB9380
-:10F7600085F7B7CF6C99BE9EC1F99F39B8220DEFCE
-:10F77000BB2FEDB0B11857FFFEA7B78CA7F996E2E3
-:10F780003D6A9CB7639E15E5C6ECCEE95684DB6DF9
-:10F790006B173C193ECFCFCABCA34A81FEE23A9E0A
-:10F7A000243C71B0800FE1FAEB295A16EA17A773CF
-:10F7B00059C47C4E77A942FCFC77533C743FE54C1E
-:10F7C00066E47EC5A55C3F7FA4D445FDEBCCECB5DB
-:10F7D000E5C9640F3A915E4FB51751FCCE8271773F
-:10F7E000908B967D5FAE45FCFFA4BAFEEDE5D0DEC2
-:10F7F00036E7CAF7B01C6B6D24BD99FD5E257A0013
-:10F80000BD90EE89FD67A5DDD912964788FAA3A6BB
-:10F81000F36B7818DA1F9676356005FE6E397096B0
-:10F82000F470C4572D0C7FE9374EE8F3223F246D66
-:10F830001CDDBBA35FDB6557FA03509E6CAFB74777
-:10F840003AC7E8F3878D8BFAED0CA6C584CD0F522D
-:10F8500031407E6D2F9FAFAF9F68073354A3F509EA
-:10F86000BDDCD82ED73F7A9B9E3E9789F391FA79DB
-:10F87000B4F57EC7AF7FAF058313949771858E5E15
-:10F880002E52BB56615C85BDC5F93FD875CC13219E
-:10F89000CE15E2B3B0F621027E00CFF5C9F3C93E22
-:10F8A00089B60EABFF88963D2664BF7D274DBF2EDF
-:10F8B000D9AFA594C7C16D7E16B0246019A0FB1CFA
-:10F8C00036781FE5F7A7D5373A2F8B4017B234F2B9
-:10F8D0002DFCB9C2E23F463E81683052EA2326FE43
-:10F8E000BE16C6E7E2EFE2FAEFE96D0AE9BF1BB721
-:10F8F000F03C8A4FFD5027E5829F13AA167F13CA5A
-:10F900008E23ECDEE1B2E7DA6FBFC8A583DB128A93
-:10F910006789F6F71EFDD16BD8FEEEE33FF2E07289
-:10F920006F4D5E92C0F9D689C538CF998BADE48F03
-:10F93000C19F5DE207745CEEB7E9F070E3FE47B784
-:10F940002D46B9B3DFEEC674BCA5DBF4EDB6B4B09A
-:10F950007D318E5F3E1D9C8239F3808E8EFFE45F89
-:10F96000E97E782CF24FA4C73536BA17D68F0E4AE7
-:10F97000FBBE334278BB381487A2FB2092AE4E6E9A
-:10F980006A39A3C238EBD7585DF43D0583FD75DCB9
-:10F99000354F4B0B8B0F5BD7F07B9A2CDC4ECC0991
-:10F9A000ED5F8E7BDC576F7739FA8FD70FEFA28C24
-:10F9B00037A84CFB2DF2C5B432CFCBA5148FAEA720
-:10F9C0007D37ED5B73FC15E8737BACF7D5D2125C29
-:10F9D000FF88710ADE9731BBE8DE606BAB2906F960
-:10F9E0007E4797396624C2BBD54472BEA32B3976B5
-:10F9F00024CA258789E2A72857D430FF3E9BC0F947
-:10FA000064487E7812C2F59F58818F67F284FE3376
-:10FA100083EB3FCA130748EF686DE3712AA96F387B
-:10FA200005FE385B791C329AFE838C07D71D5FB2C6
-:10FA3000C4897CAD2D817F7F63C90CB70FEF735EE6
-:10FA4000EA60243786E3A50AD4B31CCC3F1BE651F9
-:10FA50009D5CBFF17630D267921C0E37823AB5D3E7
-:10FA6000EFA3756B9CCEECF01FC233364F6338BEEC
-:10FA7000D9A057580D7A836AA87F51AAD72398D066
-:10FA8000BF653C387EF3C07940D2AFDB21FC13A0C8
-:10FA90003FF9E8DE4829F323DE324D73250F09D9FB
-:10FAA00001E877C4F6B452B6A3252CFEA4682F92C1
-:10FAB000DF40FA25A5FF41FA39C69482BD9610E6CB
-:10FAC0008FF81598962AC5C39226009E64033B20A2
-:10FAD0007B329F29FC7AC6D7D4D39B2E2CEEF3B36E
-:10FAE000E7F9FDA05653AC7B6776FF7EC593397D61
-:10FAF000C61EC21C4998E52A3BDDC399A9EEA17B2D
-:10FB0000F75B8B4D3CAF991D71A23E903F81CB932B
-:10FB1000EC32CFC5B81FE6F06423DE003C7C16BC97
-:10FB2000BF27FCB69937E7C4A23EFC76FAD92DA8C8
-:10FB300097FBDA4CC46F241CB39B4D77201A86C503
-:10FB4000E702E6C2509C6DA3E79C0FEF0BA74EE6C1
-:10FB50007ED7D879A70FA21F74C34813F9D96F8D28
-:10FB6000D7286E07F4635779BCEE258CB7B5BB92E6
-:10FB700092F0BB3B8F27F27626CEF1EEF8213BC206
-:10FB8000F34BE2C4BEEF5622EB2B7F9CC4E54BCF78
-:10FB90007E00E420F26B097BFC0FD59A23BC0E702B
-:10FBA00083F7FFC5C7EDE97913FE50ED33939D242C
-:10FBB000ECF9981AB2D7D1C708ED7B263C58ED83F3
-:10FBC000FAFDD991E7ED98CCE7BDFF65EF70D467FA
-:10FBD00083FB017F06453ADF003395D2B859189769
-:10FBE0000AAEB62D88F41D9B33629F5BA1CD3628EB
-:10FBF000A4C76EAD36EAA97EE2579F349C7C81D2C1
-:10FC0000B4817F94003D24B2C8FCF2FCFAAA3B0DFB
-:10FC1000F5CE96D5CA7AE41F2DA0AF625C30D569C7
-:10FC2000257DB535F187D3F15C3E69604EBCEFBAF6
-:10FC300013D43EE45FE857C57BACB39B389FF13AE1
-:10FC4000B99F15EC38CFA5888FE966C247A9BF9A3E
-:10FC5000AB39FFB9D8C6F3917B121DE4374D6CE286
-:10FC6000F9C7713ED067717F3378FEB006FF211F60
-:10FC700092FAAD23DFACCB23B61AF28CCD86BCE270
-:10FC80008D13F47C28BEA47840BDEA5760FFE23AA9
-:10FC90000F00FFC13200763096CF83DD8EE56FC056
-:10FCA0006EC7B8C18B6BF3A87C69AD9B9EBFB2B623
-:10FCB00094CA6959418A2B921F999C8F2CA0901F3E
-:10FCC0004FE2D71BC3CA10DFA7F3F65F4EAC7EC06E
-:10FCD000370CDA9365FFB1847F7D755F750DF6AFE4
-:10FCE0004DE3F551CF5E5D83FE9FDE99DA4313004D
-:10FCF000EF524C9EBA36ECFB239B3B927D5F30511A
-:10FD0000DE138B6CBF33FC4482DE9FF314F1892831
-:10FD1000FE9CBB15BE8E3F4E7AF05EA48B41F3CCA9
-:10FD20001EC4E3AC1CBD9F7FF044CE77168B32EB34
-:10FD300015A08F01E02EE9235A7BCB7E4081087409
-:10FD400025CBADF16C2ADDCFAEB12E8894E774409F
-:10FD5000D055D4F11DCC651B1BA2B7168791DE824E
-:10FD600014DFFDA4E9C683282FBF39BD31B20F834C
-:10FD7000351AC9EB20D01BF273B581D39B6AE6F725
-:10FD8000336B0F73FFC84EA42FCC87437A837FCE8B
-:10FD9000F6F17AAA81DE5A8CF4E6D0D35B10E90D35
-:10FDA000C64BF471FD22AEBAEB5BA5B7CFBF21BD48
-:10FDB000FD7A4A90F21A7AB21BD3113E5BC5F7F076
-:10FDC000BE2A1DDE35D1CABFCF7189467E81561C41
-:10FDD000C741FAFC26FCCECAEC61CDE62480DFDC0C
-:10FDE000E402FA0EC1E48943043D1C71A0BF266100
-:10FDF000BAE69C88F475E57B74BF31C5C4E9B7E009
-:10FE0000D937491E64B675CF9B8D74B75A253969A9
-:10FE1000DC57EB548E6F2D0A9F174E2E3D3CAE37AC
-:10FE200042D0A56B758B62477DBC8EB973B3E9BBBD
-:10FE300032F4BD9B7F69FD4F278EDB3A3589D6E5CD
-:10FE40006A7E33D1CBFD6B6968BFD195E6C2FEF403
-:10FE500008BF2ECB101D3DE74F1CC03F7B3EFEF17F
-:10FE6000C80445F209CA03F68AFB9B322E12959EFE
-:10FE70000D7EDCA8FEC34B387C8CEFC74FE1F3B698
-:10FE800008FFAF51DF93FB3F3ADD3B1BF7A7385E1E
-:10FE9000E47EE003CC85EB9471B3BE3C23A91FFA4A
-:10FEA00098BF05F56D33A83243B8BA81E3F5E51F75
-:10FEB000093D714599773E8EBB83B90EA27C73B81C
-:10FEC00079BEC233D3B50A82E7D7D4034BCBB46B28
-:10FED00006C2AB15B3B54503B5B32F619471A1B894
-:10FEE000D6F47966CE179A14C1071CEBAD50DF9A91
-:10FEF00008FCCC857A3BDFB713F8868BEC0CBD1D74
-:10FF0000310B9D91C837908F1070B5B998579920D3
-:10FF1000C60FC9EBE00BA8970601B6774053828F56
-:10FF2000CBEB96C39CAF5881AF505CBA94DB09F21F
-:10FF30005E505CBE9BEC2F551BD87E301BECFBE665
-:10FF40008922EFBD901523DCB24CAE3B27C0F3A253
-:10FF50007B661E9D008F4BEE5B3A18C5E9F81D6D60
-:10FF600015F8BDAF150F9FD9817ED209FF6E63E2F0
-:10FF7000BB6A9467F0779433742E07269FE1FA6387
-:10FF800076643CBE620A977F32CE3A001EFB098F30
-:10FF9000459CF32BE0B1E33C78FC58143CDEF30DB8
-:10FFA000F178EF44D8D7357808304ECC6CED17583F
-:10FFB0008F86B7B36669CF0ED41E163FE0F943AC07
-:10FFC00081EC6719BF34AEA70DE56BEE007EA90D7D
-:10FFD0003B63D09E6D69D8F9327EF7B1A589DBD934
-:10FFE0003DF16E7B29DA376FA8F43DAB68EFA3DDF6
-:10FFF000ED036639730ACF8F3EB4DA169806E364D0
-:020000023000CC
-:1000000038B8BCCD70680CF3C5CDCEA0C51B8FFA37
-:100010009A87A19D614D36315F983F66ACE508C96E
-:10002000E51E90E3481F409F9CDE12F938523E4F78
-:100030005B7D274672D8945E90836174F2F2FE5223
-:10004000F2C3C597EC5D85EFA9355617E2F7B4CF3B
-:10005000416E86CD331D3491F0FAA5F674DD383348
-:100060009DD9BAF6D969DFD1B55F06F862A53836F1
-:10007000BF1728F59A39AE025DBF4411E7F86EDE6E
-:1000800004DD7866F5CB3BC623FD0B3D6232FC8771
-:10009000F4AF1AF405A33E61D41FD824FD3DD53139
-:1000A00066918766E6F9115B999DBE4B017C90BE17
-:1000B0007B501BCA13203A19630DEEBC0DFD2A0BB1
-:1000C000ED6E1F3C6BDD7F595A5D71C87FB6B589F7
-:1000D000FBFD5AF6D977203D6C177429E92B3FFEBA
-:1000E000E4424672DDCA501E1BE955E63B497F815A
-:1000F000F427280DDCCFF0D4D46CA207C97FB65604
-:1001000073FBF7674A204619C1E9D29514FA3E5DA0
-:100110001A537C73387D6B49A254453EAACC7BC5EB
-:1001200071D0CE4EE3F3B19778DE64F38FF17D2783
-:10013000F30D13FE8CCCA4909F02F31356F2F77CC0
-:1001400073C47BC345BEE520BEFEC04C31DF18281A
-:10015000D5464DF8A7BD54DA301E0E658EE28E45A9
-:10016000FFC708D543819604115FCF10F1F43825FD
-:10017000C099C7D7E42363818D625E024BE2DF172B
-:10018000297BCCC154A20FEB4E9447B79E70BF8E13
-:10019000A9BAADF13F7C751A3C6F7F4375A39FF4FC
-:1001A000D64CDFDB48D76640061FF9B53C75786E44
-:1001B0006AA5DD391BDE537D3B9A31BE3BD6EA3F53
-:1001C00048E7B9CE46F41E84F7101FB6C7039D2238
-:1001D000BEA2A76B5C281F48C6318213DC7694A3AD
-:1001E00041ECC7FDCD3AFF67847C13F2979A45BD79
-:1001F000D5B193F4F7F5C956FCE226E6F76435214C
-:100200005EA6C4F2FBB78CC70D86E33FC2F2EDAD2C
-:10021000CEC87E4DD0D7080EC1E6E56903E95D5131
-:10022000E3280E53C09A70E17194B66BAFF407C225
-:10023000D629F7BDDEB15359CCBECAFC4C1F476965
-:10024000605ACC98087194A05FC1750E6FE07196EA
-:10025000E1C25FFF75E3285953BF5E1C45EEF7729C
-:10026000F1EFB980D8E29E31C513E8BC4CA1F58509
-:10027000C1EF21E247841B0245A0FE3D517F754F2F
-:10028000F79F1E857F1EDEFDFC1E2CA51E374FB47A
-:100290005F31FAB30398BB356FC32A11C7D2C71FAA
-:1002A0002E07AB2EDCCF8FDF0B08AFCF33ACA7CC44
-:1002B000AC8F13CC70E8FBCF4AD6B7970FB3F53BA2
-:1002C00037F4CBD37E95FEFBBD35EE76C6BF371532
-:1002D000760EEAF9EB76CC9BC3B88FAB3F9E84C712
-:1002E000013CBF34B3A462C41713E9A5DB7DCBEF97
-:1002F000AA02FA590F7294F362978EFE42718F72BE
-:100300000DF149FAFBA3D1D349470EF9FF87371DF9
-:10031000EC9A3198F5C5016E8FF5BE3109BF17E42F
-:1003200038A7A01E32BCE937D47EE5C29201F1287D
-:10033000B7E950D78CB0EF08E69A3D26B49F739B7F
-:100340005EA4E751F5F9FE7C84F2D672055EC8BC66
-:10035000C0ED98170870CF6D10DF07EE1C38FF4D09
-:10036000CAC3D6B0FC3E4A6670292C7C7C29F7FAB9
-:10037000F9D319F7FBCAF9FAF2020DF3F6C93F27D0
-:10038000977FCF4CF77E312925EC5E86B8C701FBFD
-:100390008E9807CA268B7BB1D1F3D8B8DD59F9D234
-:1003A000DB38FE57B63BA38C3B2D2B18F19ED4A017
-:1003B00089C28F1C13CC44BF418F25B25EFFB39915
-:1003C000B392270F60A761DE2CC232DA3ABF6EDE2D
-:1003D000EC04116F92F156993F2BF362CF973FFBDC
-:1003E0004DFDF065C21F10379951698C4318D73BFA
-:1003F00059F8C7B3CB3C9326D37DAEC8F107D9FFDC
-:10040000ED746B44BFF8FD53059EF4BF7F44F9A122
-:10041000B0DEE4703B48BE27F3F28DE3815D74C526
-:10042000E4307FA0B73997FC7D61F696CC8725FA3A
-:10043000D82AFC107D7460D40B453CC4A817CAF8B8
-:100440008852CDFD13401F350807D4BB302F5DDA2D
-:1004500079329F54E68D625E28C5A3BEA65EF5ADD7
-:10046000DB53CD3329AFABC559F6D237B1A7DAA7E5
-:10047000F27BC2D29EF23AB8DFC18BF6D425FDEDF5
-:10048000A9E2326F2BC2CB68571DFFE987941F0B7F
-:100490007668DBE46F834F18FC53232670FC96725A
-:1004A0005AFAD30E8E34E9FCAEB3D43507295FBCBB
-:1004B00081FB5B32B42EB2D3AC0EAB0BFD2DE61933
-:1004C0009C8E2CF9CCAFF1382FF957645E599263AA
-:1004D00059C4FBA6D24E0C4A3BD1C7EFA7F61CE687
-:1004E00071DB38F4B760C7722ED7A4BFC5922CFC5D
-:1004F0002D867CEC38837FC5E86F7962B2DEDF72CF
-:10050000BFE2BA0D49FDE96D337F87A0F8B77B974D
-:10051000C6A1A9FF8CBFEDBBC2DF728F03D6B7FFA8
-:100520006DBDBFC518FF8A10F722E7D599034F901C
-:10053000DF44C257D2ADF4676534F1EF37CD52F7DF
-:1005400028C85FB63A387C55F4672587FC59CA132A
-:100550007FEAF34BD17DDC7E71F2C697719D6660B8
-:10056000381B23F9B7045C8DF1A88426710FF85B62
-:10057000F267BD63806FE13D4577E2778D8BEFAB2E
-:10058000388AE5B81D370EBE1ACAD287EFACC0F262
-:10059000BF5E0E66A3DE69F463BD821F414EE90FA4
-:1005A0005F231C259E7A1B249E3AAC44B7D51C8E33
-:1005B0004638A56A1C4F73014F4145E8C3BF9E44AE
-:1005C0004E9F1933DC2FA17F6D78BE9945C26373AE
-:1005D00013FF5E9684E37601C7A48665E42734E2C0
-:1005E000E9F0CEAF869FEA14E11710F07B6A5BD189
-:1005F0006D08B7BDF756FC0ECB5FF86F8C43B8EDB6
-:100600007BE8CEEF0AF8A5D3F7740DF05B14057EF6
-:10061000D3DCDCBEFEB8CC9B3805E4C265C021D07B
-:100620001FB2B3BDD0AE8F03E9F969EAB7E49F0A00
-:10063000F6F153F65AEE57E0A74F1BFC53A93E4E76
-:1006400037A9BE13449F19409F31E8AF6AE07A246E
-:10065000887D7F9C823637E7AF52AE21CB3181F067
-:10066000D9EEE471E7087ECA007DEFD7C087D1815B
-:10067000138E772057274C4909C9BBED0D3C8E7668
-:10068000E34CCF2484AB8CAB3D335D9B3C85EE2F9C
-:100690007C6DFFE30C9C47FA1F014F69FF2AE03B8A
-:1006A0007EDFFC52902768FF9B1B8216942BB54D72
-:1006B00037285E28DF9EC8CF3F35CDCB30CEDADF7E
-:1006C0005F178C47BD7DDAC83E7CA808C787B1ABF1
-:1006D0003FB913FD5CD1F021234ABED2F9F1A14C00
-:1006E000275FB7F6E143E38651C9178E0F478DF8B0
-:1006F00020E83FB521780FD2AF59E083D9097C0CAF
-:10070000E0A1221EE487E29E921E8222FFC0089F83
-:10071000A06F44943C84554AE900EBBBE0FC031114
-:100720000F6D11F1506F13CF97ED596D9BA5CF3F12
-:1007300070D3BA673B1A95F03CFE0879B2B7E1F97D
-:10074000C938A78C6B7E5CE6D98CCFA7E5F1730E18
-:10075000468F3305F07E2BA09FD380E777139ECB87
-:10076000FB07428FBB71A6B6159F8FB1FA29CF192F
-:10077000F4BD7BB1BE7DFFA3FC7BBBC20F29F3F2AE
-:10078000BEB1DF2CC1EAC7FB92D26FB635DEBA1319
-:10079000CFBB8E0567D2777E314E817EA7CD36CA1C
-:1007A0006BAC57C0F046BE78A9B76B0AE94D1ECABC
-:1007B000C7F556DA9DA8E7B726CE4A43BE51BB5EC1
-:1007C00025B91ECDBE91F4560BFC86E8AD89F39B8E
-:1007D00054C02FC2379F42FC2603F80DE73F1A434F
-:1007E000BDCE8C74E7E8CF6FB60E00FF0BE43B2F55
-:1007F000E17946E03BAFE03EC3F8CEEFA67C83B89C
-:10080000C7A553188FE788FD633C80F68FF415BEAB
-:100810007FA33EDBB76F3D7D49BAFB5F40679F23F7
-:100820005C23D0D9FFF98674A64E8D4C67E6A97A71
-:100830003A8B99FA8F496799534BCE4F675D02AF58
-:1008400064FEB6D42B2E52BBCEE5E2FCFF8FF3B78D
-:100850006F9FC4FDA9E7CBDFC6DF85F84F8DF9DCBC
-:10086000FFF4A7FEAFF5A7FE78EAB7E04FFDF74922
-:100870002ED2DB8C7ED5BDE3B5B6A903C495259FEA
-:10088000364B3E0DFC18796F2DF033E4CFA9D5BD62
-:100890007F7E86DB9BEE3817F91BEEC0F566087E7F
-:1008A0006DE4CBA077DE39F5EFE86FF87BF90DCB7F
-:1008B000265FD87DFBB2C92EE1778D7CEFBE45D88F
-:1008C000F72D3006DED3DBBEDAEA6F8505A78BF3A2
-:1008D00019D370E5654864AFAFB0C60607B09BE4B6
-:1008E000DF91E858EB7DEE746EF8FE5844B9D5B749
-:1008F0003F839E1C6E37B9BE82DD94324DEF873246
-:1009000037703BD70CF28EE2FA5A6900F975864FC0
-:10091000E9C2D4606F72A3827230B5C143F9F05F4F
-:1009200035AE6FC4A36871FE6F3BAE6FCC1BF8474A
-:1009300089F3FFF754FD772D659C5FFA5F8D71F9A0
-:1009400031D68E7292AF3526FC0B18AC75FF073B83
-:100950006FC3F35E68A77B1AC67C806871FB314960
-:10096000D6605C4EF4F8BDF417DC6F697C19EDF0CD
-:10097000FB9B4D74BEC6BC81FC789E3FFED4AF3657
-:10098000DD47F93F521FAE167CA649B1D2771DABA9
-:10099000FDC467BCDAEE668C27A73A5817EA5947B8
-:1009A000A7727A51D334E233E66A2FE1958C4FD4A3
-:1009B00066F17B733102BFD4918DAFE2F889475461
-:1009C00037C6B7376357E019F1282B518F9860A2CB
-:1009D000BC884EA591FC1E1D8A8BFEFE4762BE930D
-:1009E000F4A3C713DDBF5F80EB4FE17FA7E4D09C8A
-:1009F0006569C807D73737A7E1FDC4E2693C1FF135
-:100A00008E39676B288E9E07FA9F42A5EEEFD9CAF2
-:100A100072A7A688BFB7E4A77C4458F7367A6FA4BC
-:100A200095FC6CAA76F78DC807D451B308AF3B1478
-:100A3000E7C2C5785EB956D2635A73C72D5802FB18
-:100A4000DA90E229CFC6734D1C49FB6C4D1C928095
-:100A5000FAE886F41C9ABF5DF19667E37BE926A26B
-:100A60006B55C4E737E42E7B09FF0E484B8689E1BE
-:100A7000BD83CEDCB3EDD8AF7302FF2338C6F5AA31
-:100A80004EFD3D29FCF011F26F358DC7C55511178C
-:100A9000570D71E5324D917F6783E20E31826FD53C
-:100AA000E6AE5B40DF4F70589D88642DF1C12AC2CD
-:100AB0008FD51686713A66EED0E969B7ADD57FFF5E
-:100AC000C591AF5F4F7BDFFD846C2FF219FA1BB02D
-:100AD000942F9EE845FC407ECB93FEE2783D46D4C1
-:100AE0000316AF2FC2F9FCB3FC67F9CFF29FE5FF05
-:100AF000EFE5FF00834DEAE8008000000000000001
-:100B00001F8B080000000000000BC55B0D741CD596
-:100B100075BEB3333BBB2BADA459FDD82B90CDC8CC
-:100B200096880C421E0BCB488D8D66A595B4322E4F
-:100B3000D938FC98C476D6D8B8E43427559D26B168
-:100B4000135AADAD95254BB62C09829C43CFE9DAFB
-:100B500024396DF00125E9690C01CE1A1C420834D4
-:100B60000A10427A92208CE39496E698828968690A
-:100B7000E9BDF7CD6877462BFFC53D1187F3FC66CD
-:100B8000DEDCF7DEFD7BDFBDF72D0078600180EC59
-:100B900007001D6073912709E500676B200DD5D80C
-:100BA000F74E576841800FE9AF35DB0EF702647CE2
-:100BB000D97EB05E05B30EF8EF43D1B8E88E9B1630
-:100BC0005DF863D21DAC5537A48373E9DAE3DA4CE0
-:100BD00009A029EF3C205DD43CA77FA6E3F8E4CF31
-:100BE00064A8D5E7CEE7FEDEFE6E73D1FA12A8FF49
-:100BF000FF1B3F1F5F979A1E800AD18755B86F6A07
-:100C00009788AE8E7C5040F0A1AF73553A83FF9C1D
-:100C1000901283D5B4BF90C7F806CCE583DDCADA5D
-:100C20001CF965E9CB827CB94D1F9720EF0C9881A8
-:100C3000627A85DF21EF355CF6872812A5DCC3CF09
-:100C4000C1A2170678E6435CDFD1ACBC405B90A53F
-:100C50002B6F5479FC72B5E785A695F8EC15D9F899
-:100C6000869EA5CBEBA9069E00ECEFAAB3EF156B11
-:100C7000DE8F1C5221638FC7FF8F9921E6D3C4A654
-:100C8000FB2181FCFDF9C64F9424F2E881DD2E4B57
-:100C90003BBF7F036902F30DD2DFC07FA77E312AFD
-:100CA000F1E4C7C4F3D40A2D3D84CF87A4F4D03532
-:100CB00034EE2EC15F5B0E85961CF02F5C837CF4B6
-:100CC0005A72F2BAF7857FCA02E693C59C1C392C8A
-:100CD000611A35B4EF3E9B9E6E6400F934BCBC6172
-:100CE000C5904EFB1FFD876FE13A0E1DDDF3E6B7A1
-:100CF000F075A0BE61A419D75360780C99F4F9532C
-:100D0000C78EA1B860A0FE0BA34476DBA8646AF886
-:100D1000DEAF058FC8B447BF64123DE5E042DE4F49
-:100D2000789B530F2624634125ED6F4C02924BA113
-:100D3000E17CEFD373F683FF1F2239B37EE63C4795
-:100D4000BE21F7364CD6CFE5FB2B963E2B383E69BD
-:100D5000D345BE8C7BF59B89CFE3FB644822C9F168
-:100D60005D68145700FC5BE6BE4FEF46DBFE42BFFA
-:100D700097E5301151D3128E9F28D26EDB40FD0AC9
-:100D80008F7184998AFFE3BE46975DCDFBB2E76B16
-:100D90006AD579BEB1C8824AB2471C5719BF6EAE38
-:100DA000FEB9D77FB1FA77B7596AE9FB28107D9869
-:100DB000BCD943F6E4B7C65C234F362EA1F97E2E8C
-:100DC00083D09B1E8817CDE54F3FF9838F64F54490
-:100DD000B5F4686FF9FA9F10F9F9F4594D4F99D5A8
-:100DE0000D340FF410DF97859DEBB3C77DCE92973E
-:100DF0002F0D196F31B519131AA89D32256CCF6EBE
-:100E0000FCBCB6569F7F1E1FE4D0AD267AC0FBF611
-:100E100042829945723573E4BAA7B0E10E924BFF56
-:100E20004D2AB0FEB9F97C9EBEAA648E4BC5A40FB4
-:100E30001F61FD48A27ED4221D6FD8A987F12756D5
-:100E4000C27450C829C9CF6326C96959AB77D67F08
-:100E5000FA73FC25E8BB7F2323BD7B63AA3E84EBAA
-:100E6000BC37BEFDABB7929D3F2F1B12BFD7D91F1A
-:100E70007EC19A034627581F4AAC7367E7B17B5E71
-:100E80007B8E6414535F27BE911DCFF245F867D364
-:100E9000BF2A3BDFC1E693834B910FA9C1FCF4EF5E
-:100EA0002CD33F47FCB3F93C1FDD59FFBDF3F86479
-:100EB000F4FA6C7FA4201188A01C4682063A017ABD
-:100EC0007F82DFC34AD4CBCAF9E5891C65FEBC46E4
-:100ED000FFC471DD51538B605F3E864B5F8E7EB1E8
-:100EE00048BF793DBEEA287F7D13F17F5BD0A3C95F
-:100EF00039F6D5B7DF0B99203102E745BD5B07D343
-:100F00009BD6E338A8F1B29ECBE52BF8F9D6A2B870
-:100F1000E2C1F6EAC8129ECFFEBE1BEE5376E0F3A6
-:100F2000E55EED15D29354B9442BC2E7C8405CFA94
-:100F30005A05CC626CBBF4889FCEB5D8E33411401F
-:100F40006B68BC9CCEA586C70E5525C8AE93E654EB
-:100F50001DCA276489EB5ADF54BC1DE9F5BD201B6F
-:100F60007BB01F0A6E5F07A847D22341F6137DE8C6
-:100F7000E77D287725D8F9263D5F7306209AA34F91
-:100F8000AD337E88E6F8BD0852CEEDB7FB2B1DE3EE
-:100F90003BB46AC77B194C23837CEA0A2F738C2BE2
-:100FA0006A5AA9D17ABBF5158EE737D5B538BE8711
-:100FB000A872721AFBABF13F92BB0CA2CFEFAB0948
-:100FC00027603FE77B0572FAF87E6DA4A8FC341D0C
-:100FD0004A37C00D6447289723C3E47F36F8F9DC0D
-:100FE000EAF3C231A904C8F493D048CC36F9BC97CF
-:100FF0002C7D4D46AA594E52F099F7590F1F9FF676
-:1010000010CE82C7A091FCEBDF6AFA710F0EB99285
-:1010100048E2F76154741DE584AE3A1968E4E7E6E6
-:10102000D2523AE7A46437F617E1B8B05045789643
-:10103000C6F961F757C4385844E3344856615F3302
-:10104000A080E45A85743E5BCADF25BBADEFAE12CB
-:10105000DF254B4A05FD86463E47331DD81E060355
-:101060007CEC7FE2089AC88BF4707B15AD0A9F3F39
-:10107000084623F56B619AFD148A5FA2FE4298D45C
-:101080008493CF08BF3DAD844EFB85DFCF672F59DA
-:10109000BB51E0B42D0F1C7C55ABF925B2BFDBEE84
-:1010A000683A27EE50763EEDB0DBEF4474711EEEE9
-:1010B000EC623B51763EC3EF5F8AC4F7901D12EBA2
-:1010C000FD8D73F9DDA06680FC572A02461249A403
-:1010D0001E5D1BDE82F24D3EEA376AE1F2C9E36231
-:1010E000E59006AD80F82AF75CAA1C80CFF9E031C4
-:1010F000FFE121564693CFC93F402EDFBA14B9B85D
-:10110000E501F79401B49CDF8F3E206502D252E6E0
-:1011100087196ECCF21FFBC96516BF4A2D79C8A28C
-:10112000CDC8D673A5747EB910BDB2D2AC7CCE2723
-:1011300097701CDF3766E523F798CC3CFB9CF6C123
-:1011400019C6B74B2483E5B5548E7BA85F28652C60
-:10115000D093E673BD183496CF15D0C36DB9777AA6
-:101160000BE3E19D3811E1D90FF094CD89C752C14D
-:10117000367F35F9D73AC5F060BFBEC8134F231F7D
-:10118000AF542043FBAB542049FE1C9101D34F3D8B
-:101190008AA7159E33293CA63DF4DD2E7F3A2565AE
-:1011A000E76FB0FCF64F8ABEA94DD767F97C92FC79
-:1011B000D772C10F0FFB9FC90C7D1F8E81D1A7CFA6
-:1011C000F567382E295B7E8ADACDF4A285F9962C54
-:1011D000C6BE34F8C3F70967103D05FBDF8B24DE7C
-:1011E00021BD219C1E2C65BF345D48C07A2E2E3057
-:1011F00009576CB1E6D970A3BE388EEBDC32E87BC0
-:101200009DE841CAE7C405EEEF750972BFB7BF9B01
-:10121000D52BF7F7976807B0B3E2827040E491D519
-:1012200025D37970FB2CCE243B29CBFD4EC8492D0C
-:101230004F30EE50C95ECACE4FC7EBC22F361D2FBE
-:101240002A2ED1F15AF8C53EA7B6C319AFB2D45A67
-:1012500027F26B2BD87FE5CCCFCD16FF3E4DE7555F
-:1012600031F1130315DCF73688ABA4B77F86109AEB
-:1012700070FC927DDB8A192F405423FE48998FCA57
-:101280001F5E7B117CB4F8B439F3A65727BFB4B303
-:1012900008DEC88DDFACF7EF6CFC8488D3FDFE1A46
-:1012A0007F4E7C5878EC835E72EA7B0AFFE68556B7
-:1012B0005C7AFF4BB22157D37B819B0320CEEF4258
-:1012C000B2535C77E1E3A7FF87C617BA7035518642
-:1012D0001CBA9EC2FD8C670B8B559D71B64BCF6CB3
-:1012E0001C0D1F081C1CB4B897435722BC6CC73D8B
-:1012F0004C579A3BEF75163EC757910F2F00CFBB47
-:10130000713ACCE273F13E1854859D609C9971C48A
-:10131000C17A5E3BB3D76D7F57A1C6AB8DFA3CDF78
-:101320005B72A8A7401CFDC2C22A48EFC6F50E0E8C
-:10133000EE8814627FAC02748C3061A0F38B12E1F2
-:101340008DB672A14AA166810B690AB0E378FC0BE5
-:10135000FDAB3E5487EFB757050D5C192C7C0B7124
-:1013600032D2B9ABCA6F98F82005E27DB2D923E238
-:10137000C924BC4C78749B251FEFE30267B26CD084
-:101380000EF7B7097CB5EDD867D7917C474A6F3126
-:1013900032386E1BFAA732C263A35EC67388EB1C99
-:1013A000B8DFD79C8303F1FFBB0E791D7DAF0B2700
-:1013B0000EB7210E44FDB671E0FD6DC07646EBA27E
-:1013C000F3E472CD03C172F6A7D729539E7CF93797
-:1013D0005B1E36FE7EA242F0D9FBAEE00B06CC3B94
-:1013E000E8B9EF5D118FA1030F362DA0D35FF0CFC9
-:1013F000D784FCA1A7EF8AF300BFE4759BF81FAD6B
-:10140000DB8D877D2E3CEC5EAF2D87476CFEAC827A
-:1014100055C41FC4E78C13ECFDB8F7F138C6E7518B
-:10142000548A277BFDDC667A356E9FEA0D737BA2BA
-:1014300057872802B0677AEBB87DB6D7E0E7CFF5DB
-:1014400036736BF3612E7F445EF32A6BCD4AFD54F5
-:101450009CCED12BA21E3685B17B3CCCB7B3A89FC6
-:10146000647CC506E5DE707CCC93A690DE8E7F168C
-:101470005AFA7AADEFCC711F8E1FA904630F7EBF9D
-:10148000B0793BEBD99A339EAC9D00C539058E3CB3
-:101490004104CA1CFD76FF958EF11DDA52C7FBD2BE
-:1014A000C834FBA9AEF0B58E71B69CFF8EE22C5C01
-:1014B000DF58F4A4467CEDD6AF778C53EE41F93774
-:1014C00050FCF351075D90D719E4A74B373AF5B0BC
-:1014D000D82557F5EE73C741B69CDF6A73C643F350
-:1014E000C9D7ADAF365F4B67F92AE2CA14C595C8B4
-:1014F000D7524DF0D5DEEF88B55F7B5EA559ECEF96
-:1015000072C797C5145F56E78B2F4F597C3E4F7CAF
-:101510001973C6976EBE9E2FBE5CD0EEF42B17CA11
-:10152000CFCD8B45DEADF47999E31639D6C3E760AC
-:10153000D9946C74914BB4705911F9001CB7B94926
-:101540004D13CE1C83E9309DE70725E42AEA5B5959
-:10155000BD51497EE6E190F1CA06C28DDD220FF849
-:1015600074E4B630E18EFEDD87C37858414BBB870B
-:10157000FDDD68E434E72F141D387F81AD99CE83FB
-:101580004FECF176BEF1E026352DE1F88356BEF141
-:1015900060F76CBE91EB1B134D22DFF827EDBA9577
-:1015A000FF4B86295EB977D3AA4A3EAC14EC5F475D
-:1015B000C30DB693A180564C71746A9347A37DC93D
-:1015C0002BEFFF3CE9C701A9675F0DC56F151ECE64
-:1015D000BBA642AB2AB7E0387933C218EA6F5AF596
-:1015E0002AF9EC890A7D5F0D7D1FAA61FEF5AFBE69
-:1015F000CD4FF38C841674537E64A4C3C332920916
-:101600006714339DBA73C53DEE3A804C1E97E2B71E
-:10161000724F46A5F38AF0474EDEDF96FF5048E54D
-:10162000FCECD6F6870E276BF831FBAF85765D664E
-:10163000531BE799CF129E90E6AFCBECB5F29DB36A
-:10164000E74ED8B99E3CF3302EB0EB12F4A7DB790D
-:101650005AFC4BDDDC99A673741CE231F29FC9E0A1
-:10166000B9EB204AF0DC7590F9EA1EBBDA451EF5AD
-:10167000CB2477915F74D44B94985517B1E2D783FC
-:10168000940F277D70D549EC75F459F452B37AE480
-:10169000AA9BAC562D7A06E4CB5FFFA1F593FBDB4A
-:1016A00045BDE662EB26DF6D07B15E2BDFEDB5E4ED
-:1016B0007F8D3CB983F4F18F9DEFFE6EFBE5CD7716
-:1016C000CFAD13A5D95EE0D89937D8AE972DB0F03D
-:1016D000CBB9EB404304F4517EE32B109752FDC38A
-:1016E000EA27AF1374DD75A1809547F951FB5211BC
-:1016F0006F913F21E12AC662E26B50F97652C37DB9
-:101700001404C72084ADAF7C4B92DAD6C53AD78794
-:10171000C69779F8BC1A2F4A1CEEA7F52F0BE6B531
-:101720008B572DFF3768D56F48813D646F926D1CD4
-:1017300090F0A09C2640C8F9ADF6108F57B4D1E6C2
-:101740003B516F4E913E54F07EF2D67F4EB78BFAEE
-:101750004F0EFDAF939EA62CE244670BD2F90F4BC0
-:101760001F810E8E0514EC88F9FCFA6833E182DFE4
-:10177000B56BE2BDB2C2207B180FE59FEF77D67E36
-:10178000805231ABB2F868E1464107FCE2FB83D2FC
-:10179000990D2757B25CD99E681DF4DE5DFF72D3A8
-:1017A0000FD439E31BB5CA39FE83D97D38E3A203D0
-:1017B000F3D4C7164585BEB62E167A46FAB1278FE2
-:1017C0007EB8ED5DA5BC27C553D190359FF03B4158
-:1017D00065AA8DE29D603D185C53548EF37EE34F05
-:1017E000D41C9B5E497EBED8A03848F1A3AB6CCC1C
-:1017F000C689EE7D9F2FCE5314487A1BE7C67B48DF
-:10180000D72C6914E74C3287DE5551A127726E3C04
-:10181000584DE1887E33D7F1A80E48FD5DBE0DF925
-:10182000CEE9DA76EFAC9FCC57D73914C73882822D
-:10183000D447F6EFDB8AFD77348FE6E3317ADEBA00
-:101840008E66F567EB3AF10BABEB8C464BBB6B2E20
-:10185000A6AE330FDDD9F3786E5D271AC57D8E05F0
-:10186000457D65B6AE734BF905E573C03A974B2DD0
-:10187000BF5CD46DC5113B258E239E6AFAEDF072D4
-:10188000D2B3262FEB01EC9F805C3B59B751FF5A36
-:10189000199D33AFFAA056F83593E8D971B1CD3F11
-:1018A000D5A2DFF6D0F30A8D1FAFF4AC627A90F1C7
-:1018B00079B8D89D54AD56A676B99A914B886E29C1
-:1018C0005875F48C44CF23C8ACDCF86064E6C5F6E8
-:1018D00012CA9304C120173412D17697D03FA80AB8
-:1018E0004478A75A4F93BF6DF7173AFCFF48B72AC1
-:1018F000FC6BADB82F337E5CFFDA361C3FB033C0D3
-:10190000B8E9409547D85752E27A7287E68C7BC691
-:101910002797083CB6DF6BD03D91A39362FCD6C8F5
-:10192000AAB4CCB8DB191775EBCEB8686B65E32B9E
-:101930008417A1DFCBF978CDC2B537D539E3A4A29E
-:10194000EA9E6709A76CEE1778786FB874C156F4F1
-:101950007FBF8AEA8E38714BFF5D5C37EA5781EBB7
-:10196000A9239B54B68F11EFEB87B6326E2C603EE5
-:101970004E6C522B1339F652D6E1B3EE4508FC817A
-:10198000F0323199E77D5987F03BA8D87C8EDBFA9D
-:10199000F2A79F117C2EAE82B44E38AE7B4786E212
-:1019A000CAF12ADC13BEEF0FD7741FA7F95F968127
-:1019B000F6E9D6C3EA8E5AB6D3D9F3B4D9E3E093A5
-:1019C000D717EF21FA7013E8E4D7A231EC531E6069
-:1019D000A30A941FF085FF8AF75B8AFD00F6FDB12C
-:1019E000D1A4827D7F4DE27AC2C54FEFBA7D3052DD
-:1019F0004EE79DB06FDFC6EDF14FD0F8955E08D091
-:101A0000FA4097C2B4BEA4B8CFE0B687BDA91F44C0
-:101A1000494E7B0D8945B4B97BFDDD7C6FA9BC8047
-:101A200071D3A837BE85FDD1AD7E2DC967E034C71F
-:101A300011DEAFF880F46E62D76F2A087FFF382A74
-:101A4000EA9A01DD195FFB6194CFEDD5E6D446FA41
-:101A50006E75B34A150F78AAE534CB6DA2C967F845
-:101A6000701D132D12F3F9BD266F9AE679529D92DF
-:101A700069DE27DFC3B9ABF3D9777EBBB2EDC83DD2
-:101A80007EA479BD9FF4622F4CDD42FC49CE883C98
-:101A9000957B5CBC439C577B53B7D6299CCF52B9EE
-:101AA000DEAE9C31CC12A41E9A89FF3DE55E9351B7
-:101AB00045C449959EA484F406BAC5BD8C81A2C4D0
-:101AC00020E9F300EA3DC749E5E23ED27865B93145
-:101AD0009433DF78CB6D75E4CF5E680A30BEEF3BA0
-:101AE000F1177712BE6F93DFFAEE23145755A92C26
-:101AF000CF016FCFAB1407259B02BCDE138B54F0D4
-:101B0000933F28BFF3418AB3E1E846C8D5D7899807
-:101B1000B0D3892A61F7D2231B390E189764E6B334
-:101B2000597144223CE68BD9792791678A58EE6C2B
-:101B300062E377380F7545B7C8A3466256BE490EB3
-:101B400026592F6F083C48F66F2A5E477CBCE68C0E
-:101B5000335EBEC2152FBBF351FF1BB5F21156DE2B
-:101B6000C9D6CB626BCC44B3E5A757FAD2420F7B00
-:101B70002AB5FAB9F6FDCF167E9EEAF5F33DB21707
-:101B80007B35EE179B6FEF2E433A2FF786F9F9C797
-:101B9000561F9672BF1B5979AB5F677F321D26BAFD
-:101BA0006E3FE2D68BA16881E33CB1D759D4D226EF
-:101BB000EEDF9D618F0C6B82D3ED7C36C254301703
-:101BC000EF677AC53DB7A7AC759EA075FA284F267A
-:101BD000D6F76CAFCEED73BD75DC6EEA00510FB079
-:101BE000FDC355E81F900FD12AD1277F40F22F2D3A
-:101BF000BF93F364BEB0A291BDFBAB4633528E7F60
-:101C00009828EAF9C55DE4F72B82AC8FEE7DADE94B
-:101C1000F0E4DDD7E6961DEC77CEE23CC47FF433EA
-:101C200077B31F42BFC0F36E54EFE07598E897D8C2
-:101C30002FF47CED76F60B5E203D77FB81D2A4B0CD
-:101C4000EF842EF277F63DA159BF80F3A4719EA7D1
-:101C5000D0AF537F00FD00CD33D0F2FA9FD3BCEF5D
-:101C6000BD5FC0F7A22636BDC27EE185B3E8B32FC3
-:101C7000A35FB0EDF0B5139123B9F17C56CEEB6FB5
-:101C80003F26F8A181E0EB86789E38F162E50CE60C
-:101C900085E198B4327D87A83BAACC8779EB8E4941
-:101CA0008F416981BE492566D51D81EA8E76FD3159
-:101CB000A7EE58E0AC3BAAE914E39BB45577BC6DA2
-:101CC000ADA83BAA05D3C1EC3AEC7A633F3DAACC60
-:101CD000D6E7EFEC48ECEA68CAD6197549D4C15F7B
-:101CE0008A985FA6E7505ECAE7BFBB4E69D723114B
-:101CF000DE49899CFA66033EF79766EB5FEE7AA6AB
-:101D00007D2FA3419D3E328C7CE9BBC3CFF8C15EE1
-:101D10005FDFA37FF26AA23C7B1FC0AE77DAF54C8F
-:101D2000BBEE89EB1ECB5D373C0EEC77E031FF61FB
-:101D30003ADFDCEBFD5E24717F47459E755F607D79
-:101D4000711D58F41177913DBF66F1D11EF7906572
-:101D50008FCB5591DF866295E39DB687822013CEA7
-:101D60002E528F905D6C81E90EE26F5F48E0BCD42B
-:101D7000012FFBC9A31D3ACBAF4235F93E44C597AD
-:101D800003C66E24933AAE1553FEA93B6A1EEDE0DE
-:101D9000758CDEB29ED681B89DFCDDAF6BBF5ACE8E
-:101DA000F57EBAF75442F19FB198F220CF77E4BFA5
-:101DB000AFD4BAF8CC7A9EB7C803149FA502C6B3B5
-:101DC0007CAFF80985E9752309B391EF2F45D5520A
-:101DD000A223EEA7F6054FB2BC5A6B7D2B38AF5746
-:101DE000943F0E7CA643C4AD6B91968A743ED39605
-:101DF000F801AD9B72A561D66311DF3D4F7E52F8AD
-:101E0000AF7B3CABB279B01239F13C8D87A39242E3
-:101E1000E7A3CFD21B3B4E7CBBCD7C81E48EF2305E
-:101E2000697EFB1E903DFF4B961C921DE68B34EEA7
-:101E3000756B9E062D19213B6C48A03E486C3FAE49
-:101E40003ABCD00BB7BEDAFA365B87B7F450D2444F
-:101E5000BD16F5EA755EEF93FA718F44F5F6C4E1AD
-:101E600061FAF612EBDD57B69B6FD2BA4BDAE2FF9E
-:101E70004E747FBDEB76BE177CA1F7385A17F784F6
-:101E8000A98E3F1010B8F9E188E1F0778B3A857C94
-:101E900016750ABC742DEACC14DF2F35F8DE37C076
-:101EA000DD8CA36DFF34DA9BF8FEA9DAECF7A95EAE
-:101EB00098A47AD07CEBF0EEDBC179DDBEAA363F88
-:101EC000F91FF46F25D41FA832C3B9EB4815093D9B
-:101ED0004F2E12790BCAA72573EE939776CABC9F33
-:101EE000F62AC890EEF882A2EEE643C3D5F1FCF1E3
-:101EF00099CD7CBF189F4F528AE18A4E5DC4E5E5BB
-:101F00000698146F56C581ECDBA765BFA73A6A7BBC
-:101F1000550FDFB79C8F8E1CB6BF4FF0F737766A30
-:101F20004C572DF738F200E7E39B9B2FFDC4B7DA3F
-:101F3000F9F9A65E30DF84DDB9F9B5CAE2D7D3A1DD
-:101F40002FF2FEE08376B6339F86FBC47675A7F04A
-:101F50002F72D0844411F9A8382248CAB3F700D5AB
-:101F6000A16D3ECB9AE0B3ACF5F077BE2A0312D751
-:101F7000115F12CC17371FD04F00F9891F3D7AA887
-:101F80009CF0692BF6C3C27F800FDB073A845C6C40
-:101F90003B5D073F0D8AFCB7F3BC70FB53BB7DD89C
-:101FA000CA3FBB9F4B5D01E13F7470F0BDC8FAFDB5
-:101FB000C291C146C607787E26E95E4C67656D0111
-:101FC000F52F771DD15D3F74D709DDF5C1ACDE98E3
-:101FD0007E5AE73BDAC9E4C7F3E88BDD0E5BF6D641
-:101FE000DFEBCF6B77C368EF24BF8116334975A34E
-:101FF000BDA1E930EBCDF13719172BCFCB06E14B63
-:10200000451172EE5C34CD72EC6A3681EA4DC3BD87
-:102010001BBE9D4BF781B6C4573A514F0AB5499341
-:10202000E8042193A4F3676D99D9930F370D587E77
-:10203000E4EDB6F86EFA8EAEAD93FC4F45CC3DD4D0
-:10204000BF50BF359F3D2936EF2EDA9E4E0A7B6A80
-:10205000DEC1F63452D5C3386BE4A73221A92C8EE9
-:10206000B4EC69A4E534DBBB6D5769DBFF340BBB13
-:10207000A03C029DDFC55526FB8D6F5AF6A4A09D9E
-:10208000903DF92C7B2AD6B2E3293FDE4E7CC6E791
-:102090004AD5347F57DC6CD91FD95390EE0F03E338
-:1020A0008001B43BCA8BB8EDABB5469C9B8FB7257E
-:1020B0001EEE247CB1683DE7E507AAFEB38CF18BE8
-:1020C000A5FF59BCDBC8E7F9D9418F41F6D04000E4
-:1020D000BA316B07F6BE57CFC89041D1AC9991B8D1
-:1020E000BD71A690DBD69900B7E64C19B79199104F
-:1020F000B76D335772DB3E53C96D7406EDE07AB4A9
-:1021000087996A6E3B67AEE5B66B6619B7B199EB16
-:10211000795CF7CC0A6ED7CE7C94DB9B665AC43CC4
-:1021200075625F79EC81CA6097C11E8C2414911D81
-:102130007CE655F6EF9ACA779452A1555C27F229AE
-:10214000D36C0F479A85BFEF0A0A39B9EDE1EDB6B6
-:10215000C4AFF2D9C32CBE554023FEAB60FDB9F02D
-:1021600003E29FDFD0F736EE55C326EB19E293D397
-:1021700024CF4BC509B33873B1CA78D4C699238B21
-:102180001067566771E6408B88CB52077C1CBF6D89
-:1021900095C4FDB22BDB13FFC5F609224F94B8C5D9
-:1021A000AF116E4E853AC341CAEBED9581F20588B9
-:1021B000433EE0752A71719FF502EDF95444F87DB4
-:1021C0007B7C039CF4F45C048EF935FDB3657EBF23
-:1021D000507AA9E7ACB75DF8054DF8855455CF2086
-:1021E000D7A55D7EC13E67911F0EBFB0B4CBF20B89
-:1021F000969D975689F3B294FC02F2675997ED17B2
-:102200009CE7AC62E390988D432CBF1013DF216EE6
-:10221000779CB3286E3FE4E062D4A3E55D79700853
-:102220009FE739E75C5F4D6D847E4B103A03115296
-:10223000CFE2197DAD91E7DC49698D6C07C79576D2
-:10224000C8CDAF5CB49D85EC73C7E473C73DCEB613
-:10225000B781E3DD629FD639741CF76FE6D85B97D0
-:1022600026CE233C7F6EA27DBAEDAD75B19988E78D
-:1022700059E727BB04DEFFF11A0BF722AE34828C3C
-:10228000EFF3E2864F92FC9AC4EF341E43FFD31162
-:102290004BA6149DEDFC9334EFEAE8944C79A01B17
-:1022A0009B475FA69208DAE9A7BA9A2EDD4E9BDB20
-:1022B000AC7ADFCE3271D9D96ACFA7FF362EB2ED14
-:1022C000C03DEEE16A73433E7E3C63F1A36FD0D321
-:1022D0004D17FE6CBD38AE2C65FC93C7DF9AC66502
-:1022E000F1B717863F8EE33948723F07FE18CE27B5
-:1022F000FFF9F0C778D72CFE182339B5D60BFCF1BF
-:102300004C179C33BEB9645C1139C97CBB545CF179
-:1023100050D7B971C5B7BB84DF54B469F61FC597F0
-:10232000882BDC7E02F1C33F317F0C71EEDABF37C0
-:10233000E10B9439E717FA99EFD338C20D7479ECB1
-:1023400048B02D29B11DC49FA0E7A3E612D6A3CBA8
-:10235000650F88137FD895D33F9F5D5CF0B8C94D5A
-:102360009C07B4EB99BF0F1437507E64A75FB45F2E
-:102370002A283E42ED58AFC843EFB7F27E635EE0D5
-:10238000FA41BF54601C91E8BBC569916FEF594E8B
-:1023900079CFDF76D9BF97ECB9817F77037FEDA83E
-:1023A0009BCEBF2E71CF97487DC8F7C1AB34CEA36B
-:1023B0005B7CA174109DD343CBFC8C03873A8E1EAB
-:1023C000BA93F2321D220F860A51FD713A7F11D65F
-:1023D00034E79C0B3228A7293F3F4877DB19746C00
-:1023E00010F7A035F1BE348AF17B6EDDCEB8DBD1BB
-:1023F000072B5F6AFF3EB070CD7ADB4E988E6D275B
-:102400008545939A96E36F067B9DBFFF76B772ED85
-:102410007D71BA9B3C5AEFE1FAC5BE1A2540F5948E
-:102420007D7522CB3E5CE389E5AB8F5F1B931C7906
-:102430006DBBBE5D1011EB9A6FBE01D77A7C7ADC62
-:10244000243D1DD6D371FE1D725DB994CCC93B7B72
-:10245000AD79862423D38ACC1C2A12E785AF2A09BA
-:102460001EC203A1EDD7138FFD553D703A48F737D3
-:1024700092F006B6A1523591CEE38796C7841F1A13
-:10248000F24EC6588ED77938DF8B982A6F9E6C61D2
-:102490004CF8E9E19A23BCBE24F285EA55EE7101BD
-:1024A0006B5C813ACAF58E7DB5DFD4695FFBE807C6
-:1024B0003757A07CBBFFFBC1DD41D2DFBB394F33B7
-:1024C00046F91AF4A705D71C8BB521DDFD372A1A6A
-:1024D000EDA343AEDA4DEB1A8D82C17500975E9481
-:1024E000AC51025C2F353D7C07D4AD2705C554198E
-:1024F000213D9CF20BFD107A16B4F4E68021EA3EF1
-:1025000007A2A27E65CB2FE77D80EAD267A30AC728
-:102510002576FD8A6A3DF970DC7ECB2EFB2DBB440F
-:102520009CCA7587D9F78B337CEEEC6FC984E99C24
-:1025300029D2FC468CE81E75AE6B6FD39403971CB2
-:1025400058F1A2DFBA8CEF5A9FD02FE5A95FB03FB8
-:102550002D52A6F8BC2A5A7D8AFDE97DD67ABA9A10
-:1025600081F759BCD2F2DB713322E8FDA5C30F48D5
-:10257000D7BC6A7AE95CB855DC49F0368BBA5D8124
-:102580000A4606F97CA022C8F79ACA565A75BA7547
-:10259000E25E857D2FBC22EEBC1716829CDF0954BB
-:1025A0008B7B59B97D90379EF3FEDBCE5F1E7EEEAE
-:1025B000440EBD2FC59CF7C7CFF7FDEF7BD3CF9D52
-:1025C00040FD1A35CE6D87B6BCEEED6D667ED9FA4C
-:1025D00068EB6788B6D838FFF763A178DEFACC31AC
-:1025E000CB0ECEE7CFCA7CF11EC245F7AD893BF0DA
-:1025F000D103967D3E1013F94F75F119CEAB1DB482
-:10260000EE5F1D0CC086EFE499371353797C56FFBB
-:102610009D38C2D69FB97C380F8E5813B5E2104F43
-:1026200080CEF151A3ED59AA47BEABA93AE4F80117
-:10263000779EDDC61105DD76BEEF3DC65125C12969
-:10264000A1B72B9D71871B070C2BE90D64E7C375A0
-:10265000AAED9FD88F5CFD6CE1D7938C939252EEDC
-:10266000B9B93F7307D30DB9F2EC50EEFCDDCAFEE9
-:1026700018F07A42FA9929BA671E8A29E2DED6A8AA
-:1026800009B9F76EC63CBF9C3965FDFB031B77B0EB
-:102690003EEF9FE2DFD3C0172077FEBD1FDBCCBF2C
-:1026A0002F399FDC67FD7A5875E4DF2ED62EFE2584
-:1026B00066D5B7031020BB380BF770DD1D46638E5F
-:1026C000F3882B100BF8C8167FB84D6595757449C3
-:1026D000597B817651D73F9B98F58B0A7D67589F30
-:1026E00055D2AD0A8AC721C3BF53B4EF959E855F0B
-:1026F000F2BCC9A7246916675D89E13EFDFE712918
-:10270000A99CE6A1D6BDFE2560F0F31A88737B353F
-:10271000F4705B07A3DC5E0393DCD6C314B70D70C3
-:1027200086DB15A0CB34C9F560CAC0573513DCBFB2
-:102730000192DCB640E2FD53B8FEFE8AED2B385E16
-:10274000B4FD87C5279BCF79EC9D71A4CD0F9BEF7E
-:10275000FF48CEFA02EC3915127EB87D6586F53C4D
-:10276000181438D98EAF6D3AF3E1DECB85CF6C5CAF
-:10277000F97FE7ADB141E048000000000000000033
-:1027800000000018000000000000000000000040F1
-:102790000000000000000000000000280000000011
-:1027A0000000000000000010000000000000000019
-:1027B00000000020000000000000000000000010E9
-:1027C0000000000000000000000000080000000001
-:1027D00000000000000000000000000000000000F9
-:1027E00000000000000000000000000000000000E9
-:1027F00000000000000000000000000000000000D9
-:1028000000000000000000000000000000000000C8
-:1028100000000000000000000000000000000000B8
-:1028200000000000000000000000000000000000A8
-:102830000000000000000000000000000000000098
-:102840000000000000000000000000000000000088
-:102850000000000000000000000000000000000078
-:102860000000000000000000000000000000000068
-:102870000000000000000000000000000000000058
-:102880000000000000000000000000000000000048
-:102890000000000000000000000000000000000038
-:1028A0000000000000000000000000000000000028
-:1028B0000000000000000000000000000000000018
-:1028C0000000000000000000000000000000000008
-:1028D00000000000000000000000000000000000F8
-:1028E0000000000000000000000090000010000048
-:1028F0000000000800009008001000000000000226
-:1029000000009000001000000000001000009DA8D2
-:10291000000000000000000880000000000000002F
-:102920000000000080000000000000000000000027
-:10293000800000000000000000000000000091A0E6
-:102940000000000000000008000093C00001000427
-:1029500000000001000093C8000000000000000219
-:10296000000093D00000000000000008000093D495
-:102970000000000000000002000094980000000029
-:1029800000000008000093D80008000000000008C4
-:1029900000009B3800400000000000400000941838
-:1029A0000008000000000008000094580008000023
-:1029B00000000008000094A800C800000000009873
-:1029C000000096380098000000000028000096786B
-:1029D00000980000000000280000C0000540003002
-:1029E000000005400000CB200008000000000001AE
-:1029F0000000CB21000800000000000100002008BA
-:102A00000010000000000010000020000000000086
-:102A10000000000800009D600008000000000002A7
-:102A200000009DA000000000000000010000000068
-:102A30000000000000000000000000000000000096
-:102A40000000000000000000000000000000000086
-:102A50008000000000000000000000008000000076
-:102A600000000000000000008000000000000000E6
-:102A700000000000800000000000000000000000D6
-:102A80008000000000000000000000008000000046
-:102A900000000000000000008000000000000000B6
-:102AA00000000000800000000000000000000000A6
-:102AB0008000000000000000000000008000000016
-:102AC0000000000000000000800000000000000086
-:102AD0000000000080000000000000000000000076
-:102AE0008000000000000000000000000000000066
-:102AF00000000000000000000000000000000000D6
-:102B000000000000000000000000000000000000C5
-:102B100000000000000000000000000000000000B5
-:102B20000000000000000000800000000000000025
-:102B30000000000080000000000000000000000015
-:102B40008000000000000000000000000000000005
-:102B500000000000000000008000000000000000F5
-:102B600000000000800000000000000000000000E5
-:102B700080000000000000000000000000000000D5
-:102B80000000000000000000000000000000000045
-:102B90000000000000000000000000000000000035
-:102BA0000000000000000000000000000000000025
-:102BB0000000000000000000000000000000000015
-:102BC00000000000000012C800800000000000802B
-:102BD0000000000100000000000000000000A00054
-:102BE000071000000000071000001EC800000000D1
-:102BF000000000080000AEC000080000000000084F
-:102C00000000AE4000080000000000080000AE8098
-:102C1000000800000000000800002008001000006C
-:102C2000000000100000200000000000000000086C
-:102C30000000A01007100040000000400000AF405E
-:102C400000080000000000010000AF410008000083
-:102C50000000000100001ED0000000000000000184
-:102C600000001ED8000000000000000200001EDA74
-:102C70000000000000000002000012B00008000088
-:102C800000000008800000000000000000000000BC
-:102C90008000000000000000000000008000000034
-:102CA00000000000000000008000000000000000A4
-:102CB0000000000080000000000000000000000094
-:102CC0008000000000000000000000008000000004
-:102CD0000000000000000000800000000000000074
-:102CE0000000000080000000000000000000000064
-:102CF00000000000000000000000000000000000D4
-:102D000000000000000000000000000000000000C3
-:102D100000000000000000000000000000000000B3
-:102D20000000000000000000000000008000000023
-:102D30000000000000000000800000000000000013
-:102D40000000000000000000000000000000000083
-:102D50008000000000000000000000008000000073
-:102D600000000000000000008000000000000000E3
-:102D700000000000800000000000000000000000D3
-:102D80000000B00000180000000000180000B300B0
-:102D900000400000000000400000B30000400002BE
-:102DA000000000010000B30100400002000000002C
-:102DB0000000800000400000000000408000000093
-:102DC000000000000000000000008000000800403B
-:102DD000000000040000800400080040000000041F
-:102DE0000000BB0000280000000000280000BC40DC
-:102DF00000100000000000100000880000800000AB
-:102E00000000008000008800000800800000000230
-:102E100000008C00002000000000002000002008BE
-:102E20000010000000000010000020000000000062
-:102E30000000000800001108000800000000000861
-:102E4000000011680008000000000008000011A840
-:102E500000080000000000080000127000080000D8
-:102E600000000001000012710008000000000001D5
-:102E700000008D000010000400000004000013207A
-:102E80000030001800000010000013280030001867
-:102E900000000002800000000000000000000000B0
-:102EA000800000000000000000000000000011E8A9
-:102EB0000000000000000001800000000000000091
-:102EC0000000000080000000000000000000000082
-:102ED00080000000000000000000000080000000F2
-:102EE0000000000000000000800000000000000062
-:102EF0000000000080000000000000000000000052
-:102F000000000000000000000000000000000000C1
-:102F100000000000000000000000000000000000B1
-:102F200000000000000000000000000000000000A1
-:102F30008000000000000000000000008000000091
-:102F40000000000000000000000000000000000081
-:102F500000000000000083080080000000000080E6
-:102F60000000000100000000000000000000200838
-:102F70000010000000000010000020000000000011
-:102F80000000000800008D1000080000000000088C
-:102F900000008D7000080000000000080000845050
-:102FA000046000280000046000008EA000080000FB
-:102FB0000000000100008EA10008000000000001D8
-:102FC0000000840800080000000000080000844899
-:102FD000000000000000000100008DF40008000067
-:102FE0000000000200008DF6000800000000000252
-:102FF00000008E04001000000000000480000000AB
-:103000000000000000000000800000000000000040
-:103010000000000080000000000000000000000030
-:1030200000000000000000000000000000000000A0
-:103030000000000000000000000000000000000090
-:103040000000000000000000000000000000000080
-:103050008000000000000000000000008000000070
-:103060000000000000000000000000000000000060
-:1030700000000000800000000000000000000000D0
-:103080008000000000000000000000008000000040
-:1030900000000000000000008000000000000000B0
-:1030A00000000000000030000040000000000008A8
-:1030B00000003008004000000000002800003390AD
-:1030C00001C00010000000080000320000200000D5
-:1030D0000000002000003720000000000000000871
-:1030E0000000102006200038000000080000A000AA
-:1030F000000000000000200000003EA900000000C9
-:103100000000000100003EC80000000000000002B6
-:1031100000001C4000E000080000000880000000E3
-:103120000000000000000000000040000008000057
-:103130000000000100004001000800000000000144
-:103140000000404000080004000000020000406051
-:103150000008000400000004000040000008000017
-:10316000000000040000400400080000000000040B
-:10317000000040400000000000000008000040483F
-:1031800000000000000000080000800000000000B7
-:103190000000001000005040000100040000000189
-:1031A0000000500000000000000000200000500857
-:1031B00000100000000000040000500C001000008F
-:1031C00000000001000052C70000000000000001E4
-:1031D000000052C6000000000000000100003000A6
-:1031E0000030001800000004000030040030001817
-:1031F0000000000400003008003000180000000249
-:103200000000300A00300018000000020000300CFE
-:1032100000300018000000010000300D00300018E0
-:10322000000000010000300E003000180000000116
-:1032300000003010003000180000000400003014BE
-:103240000030001800000004000050000100008061
-:103250000008000400005004010000800008000481
-:103260000000000A0000000000000000000050689C
-:103270000100008000000001000050690100008092
-:10328000000000010000506C0100008000000002FE
-:103290000000506E0100008000000002000050702D
-:1032A0000100008000000004000050740100008054
-:1032B00000000004000050660100008000000002D1
-:1032C0000000506401000080000000010000506018
-:1032D0000100008000000002000050620100008038
-:1032E00000000002000050500100008000000004B7
-:1032F00000005054010000800000000400005058FD
-:1033000001000080000000040000505C010000800B
-:10331000000000040000507C01000080000000015B
-:103320000000507D010000800000000100004018F6
-:103330000010000000000004000040900010000099
-:10334000000000040000409800100000000000048D
-:1033500000004110000000000000000200004112C7
-:103360000000000000000002000041140000000006
-:1033700000000002000041160000000000000002F2
-:1033800000006040000800000000000200006042F1
-:103390000008000000000002000060440008000077
-:1033A0000000000400006080000800000000000829
-:1033B000000060C00040000800000008000060003D
-:1033C0000008000000000002000060020008000089
-:1033D000000000010000600400080000000000027E
-:1033E0000000634000080000000000080000638047
-:1033F00000080000000000040000638400080000D2
-:1034000000000001000063C000080000000000028E
-:10341000000063C400080000000000020000640017
-:103420000008000000000004000070000010000010
-:103430000000000400007004001000000000000400
-:103440000000700800100000000000040000700080
-:1034500000080000000000020000700200080000E8
-:1034600000000001000070040008000000000002DD
-:1034700000007040000800000000000200007044DE
-:103480000008000000000002000070460008000074
-:10349000000000020000764800080000000000085C
-:1034A000000070800008000000000002000070842E
-:1034B00000080000000000020000768800080000FC
-:1034C000000000080000804000080000000000012B
-:1034D0000000804100080000000000010000804260
-:1034E0000008000000000001000080430008000008
-:1034F0000000000100008000000800000000000241
-:1035000000008002000800000000000100008004AC
-:103510000008000000000002000080C00008000059
-:1035200000000002000080C200080000000000024D
-:10353000000080C40008000000000002000080803D
-:103540000008000000000001000080810008000069
-:10355000000000010000808200080000000000015F
-:10356000000080830008000000000001000080844B
-:103570000008000000000001000080850008000035
-:10358000000000010000808600080000000000012B
-:10359000000060000008000000000002000060025F
-:1035A00000080000000000010000600400080000A6
-:1035B000000000020000604200C00018000000028D
-:1035C0000000604000C00018000000020000604CD5
-:1035D00000C00018000000080000604400C000188F
-:1035E000000000080000605700C000180000000143
-:1035F0000000605400C00018000000020000605687
-:1036000000C0001800000001000066400008000033
-:1036100000000008000066800008000000000008AC
-:10362000000066C000080000000000080000D94249
-:1036300000180000000000020000DE400000000052
-:10364000000000000000E000000000000000000496
-:103650000000DD4000000000000000040000DD4428
-:1036600000000000000000040000DD480000000031
-:10367000000000040000DD4C000000000000000419
-:103680000000DD5000000000000000040000DD54D8
-:1036900000000000000000040000DD5800000000F1
-:1036A000000000040000DD400000000000000020D9
-:1036B0000000DA0000000000000000040000DA0052
-:1036C00000000000000000680000BB600000000077
-:1036D000000000000000D000000000000000000416
-:1036E0000000B0C000000000000000040000B0C4F2
-:1036F00000000000000000040000B0C8000000004E
-:10370000000000040000B0C0000000000000001035
-:103710000000D6B000000000000000040000D6B495
-:1037200000000000000000040000D6B80000000007
-:10373000000000040000D6BC0000000000000004EF
-:103740000000D6B000000000000000100000D348C8
-:1037500000000000000000080000D3580000000036
-:1037600000000080000000100000000000000000C9
-:103770000000D35800000000000000080000000016
-:08378000060205000000000034
-:00000001FF
diff --git a/firmware/bnx2x/bnx2x-e1h-6.2.9.0.fw.ihex b/firmware/bnx2x/bnx2x-e1h-6.2.9.0.fw.ihex
new file mode 100644
index 00000000000..ba1ce53df1d
--- /dev/null
+++ b/firmware/bnx2x/bnx2x-e1h-6.2.9.0.fw.ihex
@@ -0,0 +1,13192 @@
+:1000000000004F48000000680000070C00004FB8D7
+:1000100000001ED4000056C800000094000075A027
+:1000200000009F4C00007638000000CC00011588CD
+:100030000000DC5800011658000000940001F2B8DE
+:100040000000400C0001F350000000A400023360E7
+:100050000000F4240002340800000FFC00032830E4
+:100060000000000400033830020400480000000FC4
+:1000700002040054000000450204005C0000000679
+:100080000204007000000004020400780000000078
+:100090000204007C121700000204008022170000F6
+:1000A00002040084321700000604008800000005E6
+:1000B0000204009C12150000020400A0221500009A
+:1000C000020400A432150000060400A80000000489
+:1000D000020400B802100000020400BC001000007E
+:1000E000020400C010100000020400C42010000030
+:1000F000020400C830100000020400CC40100000D0
+:10010000060400D000000003020400DC0010000020
+:10011000020400E012140000020400E422140000B3
+:10012000020400E832140000020400EC4214000053
+:10013000060400F000000003010401240000000098
+:1001400001040128000000000104012C000000004F
+:100150000104013000000000020401D00000890603
+:1001600002040004000000FF02040008000000FF79
+:100170000204000C000000FF02040010000000FF59
+:10018000020400140000007F02040018000000FFB9
+:100190000204001C000000FF02040020000000FF19
+:1001A000020400240000003E0204002800000000B9
+:1001B0000204002C0000003F020400300000003F59
+:1001C000020400340000003F020400380000003F39
+:1001D0000204003C0000003F020400400000003F19
+:1001E000020400440000003F020404CC00000001AF
+:1001F00002042008000002110204200C000002008A
+:10020000020420100000020402042014000002195D
+:100210000204201C0000FFFF020420200000FFFF5A
+:10022000020420240000FFFF020420280000FFFF3A
+:1002300002042038000000200604203C0000001FBB
+:10024000020420B800000001060420BC0000005F8A
+:100250000204223807FFFFFF0204223C0000003F97
+:100260000204224007FFFFFF020422440000000FA7
+:1002700001042248000000000104224C000000009C
+:10028000010422500000000001042254000000007C
+:1002900001042258000000000104225C000000005C
+:1002A000010422600000000001042264000000003C
+:1002B00001042268000000000104226C000000001C
+:1002C00001042270000000000104227400000000FC
+:1002D00001042278000000000104227C00000000DC
+:1002E0000C042000000003E80A04200000000001C4
+:1002F0000B0420000000000A0605400000000D006D
+:100300000205004400000020020500480000003201
+:10031000020500900215002002050094021500203D
+:1003200002050098000000300205009C0810000043
+:10033000020500A000000033020500A40000003008
+:10034000020500A800000031020500AC0000000218
+:10035000020500B000000005020500B40000000620
+:10036000020500B800000002020500BC0000000207
+:10037000020500C000000000020500C400000005E6
+:10038000020500C800000002020500CC00000002C7
+:10039000020500D000000002020500D400000001A8
+:1003A00002050114000000010205011C000000010B
+:1003B0000205012000000002020502040000000105
+:1003C0000205020C0000004002050210000000407F
+:1003D0000205021C0000002002050220000000139C
+:1003E0000205022400000020060502400000000A69
+:1003F00004050280002000000205005000000007F4
+:10040000020500540000000702050058000000002B
+:100410000205005C00000008020500600000000109
+:100420000605006400000003020500D80000000675
+:1004300002050004000000010205000800000001A0
+:100440000205000C00000001020500100000000180
+:100450000205001400000001020500180000000160
+:100460000205001C00000001020500200000000140
+:100470000205002400000001020500280000000120
+:100480000205002C00000001020500300000000100
+:1004900002050034000000010205003800000001E0
+:1004A0000205003C000000010205004000000001C0
+:1004B000020500E00000000D020500E80000000059
+:1004C000020500F000000000020500F80000000036
+:1004D000020500E40000002D020500EC00000020F1
+:1004E000020500F400000020020500FC00000020CE
+:1004F000020500E00000001D020500E800000010F9
+:10050000020500F000000010020500F800000010D5
+:10051000020500E40000003D020500EC0000003090
+:10052000020500F400000030020500FC000000306D
+:10053000020500E00000004D020500E80000004058
+:10054000020500F000000040020500F80000004035
+:10055000020500E40000006D020500EC00000060F0
+:10056000020500F400000060020500FC00000060CD
+:10057000020500E00000005D020500E800000050F8
+:10058000020500F000000050020500F800000050D5
+:10059000020500E40000007D020500EC0000007090
+:1005A000020500F400000070020500FC000000706D
+:1005B0000406100002000020020600DC000000011A
+:1005C000010600D80000000004060200000302201B
+:1005D000020600DC00000000010600B80000000078
+:1005E000010600C8000000000206016C00000000C7
+:1005F000010600BC00000000010600CC0000000065
+:1006000002060170000000000718040000910000BD
+:10061000081807D800050223071C00002BF700006C
+:10062000071C80002DD10AFE071D00002F461673FF
+:10063000071D800016342245081DB13049DA022515
+:100640000118000000000000011800040000000074
+:1006500001180008000000000118000C0000000054
+:100660000118001000000000011800140000000034
+:1006700002180020000000010218002400000002FF
+:1006800002180028000000030218002C00000000DF
+:1006900002180030000000040218003400000001BD
+:1006A00002180038000000000218003C00000001A1
+:1006B000021800400000000402180044000000007E
+:1006C00002180048000000010218004C000000035E
+:1006D0000218005000000000021800540000000141
+:1006E00002180058000000040218005C000000001E
+:1006F00002180060000000010218006400000003FE
+:1007000002180068000000000218006C00000001E0
+:1007100002180070000000040218007400000000BD
+:1007200002180078000000040218007C000000039A
+:100730000618008000000002021800A400003FFF1D
+:10074000021800A8000003FF0218022400000000A5
+:1007500002180234000000000218024C00000000E1
+:10076000021802E4000000FF061810000000040058
+:10077000021B8BC000000001021B8000000000343F
+:10078000021B804000000018021B80800000000C4B
+:10079000021B80C0000000200C1B83000007A1206A
+:1007A0000A1B8300000001380B1B83000000138824
+:1007B0000A1B8340000000000C1B8340000001F472
+:1007C0000B1B834000000005021B83800007A12053
+:1007D000021B83C0000001F4021B14800000000112
+:1007E0000A1B148000000000061A1000000003B36A
+:1007F000041A1ECC00010227061A1ED000000008B1
+:10080000061A2008000000C8061A20000000000296
+:10081000041AAF4000100228061A3718000000041E
+:10082000061A371000000002061A500000000002ED
+:10083000061A500800000004061A501800000004B0
+:10084000061A502800000004061A50380000000460
+:10085000061A504800000004061A50580000000410
+:10086000061A506800000004061A507800000002C2
+:10087000041A52C000020238061A40500000000656
+:10088000041A40680002023A041A40400004023C84
+:10089000041A800000010240061A800400000003D0
+:1008A000041A801000010241061A8014000000039F
+:1008B000041A802000010242061A8024000000036E
+:1008C000041A803000010243061A8034000000033D
+:1008D000041A804000010244061A8044000000030C
+:1008E000041A805000010245061A805400000003DB
+:1008F000041A806000010246061A806400000003AA
+:10090000041A807000010247061A80740000000378
+:10091000041A808000010248061A80840000000347
+:10092000041A809000010249061A80940000000316
+:10093000041A80A00001024A061A80A400000003E5
+:10094000041A80B00001024B061A80B400000003B4
+:10095000041A80C00001024C061A80C40000000383
+:10096000041A80D00001024D061A80D40000000352
+:10097000041A80E00001024E061A80E40000000321
+:10098000041A80F00001024F061A80F400000003F0
+:10099000041A810000010250061A810400000003BD
+:1009A000041A811000010251061A8114000000038C
+:1009B000041A812000010252061A8124000000035B
+:1009C000041A813000010253061A8134000000032A
+:1009D000041A814000010254061A814400000003F9
+:1009E000041A815000010255061A815400000003C8
+:1009F000041A816000010256061A81640000000397
+:100A0000041A817000010257061A81740000000365
+:100A1000041A818000010258061A81840000000334
+:100A2000041A819000010259061A81940000000303
+:100A3000041A81A00001025A061A81A400000003D2
+:100A4000041A81B00001025B061A81B400000003A1
+:100A5000041A81C00001025C061A81C40000000370
+:100A6000041A81D00001025D061A81D4000000033F
+:100A7000041A81E00001025E061A81E4000000030E
+:100A8000041A81F00001025F061A81F400000003DD
+:100A9000041A820000010260061A820400000003AA
+:100AA000041A821000010261061A82140000000379
+:100AB000041A822000010262061A82240000000348
+:100AC000041A823000010263061A82340000000317
+:100AD000041A824000010264061A824400000003E6
+:100AE000041A825000010265061A825400000003B5
+:100AF000041A826000010266061A82640000000384
+:100B0000041A827000010267061A82740000000352
+:100B1000041A828000010268061A82840000000321
+:100B2000041A829000010269061A829400000003F0
+:100B3000041A82A00001026A061A82A400000003BF
+:100B4000041A82B00001026B061A82B4000000038E
+:100B5000041A82C00001026C061A82C4000000035D
+:100B6000041A82D00001026D061A82D4000000032C
+:100B7000041A82E00001026E061A82E400000003FB
+:100B8000041A82F00001026F061A82F400000003CA
+:100B9000041A830000010270061A83040000000397
+:100BA000041A831000010271061A83140000000366
+:100BB000041A832000010272061A83240000000335
+:100BC000041A833000010273061A83340000000304
+:100BD000041A834000010274061A834400000003D3
+:100BE000041A835000010275061A835400000003A2
+:100BF000041A836000010276061A83640000000371
+:100C0000041A837000010277061A8374000000033F
+:100C1000041A838000010278061A8384000000030E
+:100C2000041A839000010279061A839400000003DD
+:100C3000041A83A00001027A061A83A400000003AC
+:100C4000041A83B00001027B061A83B4000000037B
+:100C5000041A83C00001027C061A83C4000000034A
+:100C6000041A83D00001027D061A83D40000000319
+:100C7000041A83E00001027E061A83E400000003E8
+:100C8000041A83F00001027F061A83F400000003B7
+:100C9000041A840000010280061A84040000000384
+:100CA000041A841000010281061A84140000000353
+:100CB000041A842000010282061A84240000000322
+:100CC000041A843000010283061A843400000003F1
+:100CD000041A844000010284061A844400000003C0
+:100CE000041A845000010285061A8454000000038F
+:100CF000041A846000010286061A8464000000035E
+:100D0000041A847000010287061A8474000000032C
+:100D1000041A848000010288061A848400000003FB
+:100D2000041A849000010289061A849400000003CA
+:100D3000041A84A00001028A061A84A40000000399
+:100D4000041A84B00001028B061A84B40000000368
+:100D5000041A84C00001028C061A84C40000000337
+:100D6000041A84D00001028D061A84D40000000306
+:100D7000041A84E00001028E061A84E400000003D5
+:100D8000041A84F00001028F061A84F400000003A4
+:100D9000041A850000010290061A85040000000371
+:100DA000041A851000010291061A85140000000340
+:100DB000041A852000010292061A8524000000030F
+:100DC000041A853000010293061A853400000003DE
+:100DD000041A854000010294061A854400000003AD
+:100DE000041A855000010295061A8554000000037C
+:100DF000041A856000010296061A8564000000034B
+:100E0000041A857000010297061A85740000000319
+:100E1000041A858000010298061A858400000003E8
+:100E2000041A859000010299061A859400000003B7
+:100E3000041A85A00001029A061A85A40000000386
+:100E4000041A85B00001029B061A85B40000000355
+:100E5000041A85C00001029C061A85C40000000324
+:100E6000041A85D00001029D061A85D400000003F3
+:100E7000041A85E00001029E061A85E400000003C2
+:100E8000041A85F00001029F061A85F40000000391
+:100E9000041A8600000102A0061A8604000000035E
+:100EA000041A8610000102A1061A8614000000032D
+:100EB000041A8620000102A2061A862400000003FC
+:100EC000041A8630000102A3061A863400000003CB
+:100ED000041A8640000102A4061A8644000000039A
+:100EE000041A8650000102A5061A86540000000369
+:100EF000041A8660000102A6061A86640000000338
+:100F0000041A8670000102A7061A86740000000306
+:100F1000041A8680000102A8061A868400000003D5
+:100F2000041A8690000102A9061A869400000003A4
+:100F3000041A86A0000102AA061A86A40000000373
+:100F4000041A86B0000102AB061A86B40000000342
+:100F5000041A86C0000102AC061A86C40000000311
+:100F6000041A86D0000102AD061A86D400000003E0
+:100F7000041A86E0000102AE061A86E400000003AF
+:100F8000041A86F0000102AF061A86F4000000037E
+:100F9000041A8700000102B0061A8704000000034B
+:100FA000041A8710000102B1061A8714000000031A
+:100FB000041A8720000102B2061A872400000003E9
+:100FC000041A8730000102B3061A873400000003B8
+:100FD000041A8740000102B4061A87440000000387
+:100FE000041A8750000102B5061A87540000000356
+:100FF000041A8760000102B6061A87640000000325
+:10100000041A8770000102B7061A877400000003F3
+:10101000041A8780000102B8061A878400000003C2
+:10102000041A8790000102B9061A87940000000391
+:10103000041A87A0000102BA061A87A40000000360
+:10104000041A87B0000102BB061A87B4000000032F
+:10105000041A87C0000102BC061A87C400000003FE
+:10106000041A87D0000102BD061A87D400000003CD
+:10107000041A87E0000102BE061A87E4000000039C
+:10108000041A87F0000102BF061A87F4000000036B
+:10109000041A8800000102C0061A88040000000338
+:1010A000041A8810000102C1061A88140000000307
+:1010B000041A8820000102C2061A882400000003D6
+:1010C000041A8830000102C3061A883400000003A5
+:1010D000041A8840000102C4061A88440000000374
+:1010E000041A8850000102C5061A88540000000343
+:1010F000041A8860000102C6061A88640000000312
+:10110000041A8870000102C7061A887400000003E0
+:10111000041A8880000102C8061A888400000003AF
+:10112000041A8890000102C9061A8894000000037E
+:10113000041A88A0000102CA061A88A4000000034D
+:10114000041A88B0000102CB061A88B4000000031C
+:10115000041A88C0000102CC061A88C400000003EB
+:10116000041A88D0000102CD061A88D400000003BA
+:10117000041A88E0000102CE061A88E40000000389
+:10118000041A88F0000102CF061A88F40000000358
+:10119000041A8900000102D0061A89040000000325
+:1011A000041A8910000102D1061A891400000003F4
+:1011B000041A8920000102D2061A892400000003C3
+:1011C000041A8930000102D3061A89340000000392
+:1011D000041A8940000102D4061A89440000000361
+:1011E000041A8950000102D5061A89540000000330
+:1011F000041A8960000102D6061A896400000003FF
+:10120000041A8970000102D7061A897400000003CD
+:10121000041A8980000102D8061A8984000000039C
+:10122000041A8990000102D9061A8994000000036B
+:10123000041A89A0000102DA061A89A4000000033A
+:10124000041A89B0000102DB061A89B40000000309
+:10125000041A89C0000102DC061A89C400000003D8
+:10126000041A89D0000102DD061A89D400000003A7
+:10127000041A89E0000102DE061A89E40000000376
+:10128000041A89F0000102DF061A89F40000000345
+:10129000041A8A00000102E0061A8A040000000312
+:1012A000041A8A10000102E1061A8A1400000003E1
+:1012B000041A8A20000102E2061A8A2400000003B0
+:1012C000041A8A30000102E3061A8A34000000037F
+:1012D000041A8A40000102E4061A8A44000000034E
+:1012E000041A8A50000102E5061A8A54000000031D
+:1012F000041A8A60000102E6061A8A6400000003EC
+:10130000041A8A70000102E7061A8A7400000003BA
+:10131000041A8A80000102E8061A8A840000000389
+:10132000041A8A90000102E9061A8A940000000358
+:10133000041A8AA0000102EA061A8AA40000000327
+:10134000041A8AB0000102EB061A8AB400000003F6
+:10135000041A8AC0000102EC061A8AC400000003C5
+:10136000041A8AD0000102ED061A8AD40000000394
+:10137000041A8AE0000102EE061A8AE40000000363
+:10138000041A8AF0000102EF061A8AF40000000332
+:10139000041A8B00000102F0061A8B0400000003FF
+:1013A000041A8B10000102F1061A8B1400000003CE
+:1013B000041A8B20000102F2061A8B24000000039D
+:1013C000041A8B30000102F3061A8B34000000036C
+:1013D000041A8B40000102F4061A8B44000000033B
+:1013E000041A8B50000102F5061A8B54000000030A
+:1013F000041A8B60000102F6061A8B6400000003D9
+:10140000041A8B70000102F7061A8B7400000003A7
+:10141000041A8B80000102F8061A8B840000000376
+:10142000041A8B90000102F9061A8B940000000345
+:10143000041A8BA0000102FA061A8BA40000000314
+:10144000041A8BB0000102FB061A8BB400000003E3
+:10145000041A8BC0000102FC061A8BC400000003B2
+:10146000041A8BD0000102FD061A8BD40000000381
+:10147000041A8BE0000102FE061A8BE40000000350
+:10148000041A8BF0000102FF061A8BF4000000031F
+:10149000041A8C0000010300061A8C0400000003EB
+:1014A000041A8C1000010301061A8C1400000003BA
+:1014B000041A8C2000010302061A8C240000000389
+:1014C000041A8C3000010303061A8C340000000358
+:1014D000041A8C4000010304061A8C440000000327
+:1014E000041A8C5000010305061A8C5400000003F6
+:1014F000041A8C6000010306061A8C6400000003C5
+:10150000041A8C7000010307061A8C740000000393
+:10151000041A8C8000010308061A8C840000000362
+:10152000041A8C9000010309061A8C940000000331
+:10153000041A8CA00001030A061A8CA40000000300
+:10154000041A8CB00001030B061A8CB400000003CF
+:10155000041A8CC00001030C061A8CC4000000039E
+:10156000041A8CD00001030D061A8CD4000000036D
+:10157000041A8CE00001030E061A8CE4000000033C
+:10158000041A8CF00001030F061A8CF4000000030B
+:10159000041A8D0000010310061A8D0400000003D8
+:1015A000041A8D1000010311061A8D1400000003A7
+:1015B000041A8D2000010312061A8D240000000376
+:1015C000041A8D3000010313061A8D340000000345
+:1015D000041A8D4000010314061A8D440000000314
+:1015E000041A8D5000010315061A8D5400000003E3
+:1015F000041A8D6000010316061A8D6400000003B2
+:10160000041A8D7000010317061A8D740000000380
+:10161000041A8D8000010318061A8D84000000034F
+:10162000041A8D9000010319061A8D94000000031E
+:10163000041A8DA00001031A061A8DA400000003ED
+:10164000041A8DB00001031B061A8DB400000003BC
+:10165000041A8DC00001031C061A8DC4000000038B
+:10166000041A8DD00001031D061A8DD4000000035A
+:10167000041A8DE00001031E061A8DE40000000329
+:10168000041A8DF00001031F061A8DF400000003F8
+:10169000041A8E0000010320061A8E0400000003C5
+:1016A000041A8E1000010321061A8E140000000394
+:1016B000041A8E2000010322061A8E240000000363
+:1016C000041A8E3000010323061A8E340000000332
+:1016D000041A8E4000010324061A8E440000000301
+:1016E000041A8E5000010325061A8E5400000003D0
+:1016F000041A8E6000010326061A8E64000000039F
+:10170000041A8E7000010327061A8E74000000036D
+:10171000041A8E8000010328061A8E84000000033C
+:10172000041A8E9000010329061A8E94000000030B
+:10173000041A8EA00001032A061A8EA400000003DA
+:10174000041A8EB00001032B061A8EB400000003A9
+:10175000041A8EC00001032C061A8EC40000000378
+:10176000041A8ED00001032D061A8ED40000000347
+:10177000041A8EE00001032E061A8EE40000000316
+:10178000041A8EF00001032F061A8EF400000003E5
+:10179000041A8F0000010330061A8F0400000003B2
+:1017A000041A8F1000010331061A8F140000000381
+:1017B000041A8F2000010332061A8F240000000350
+:1017C000041A8F3000010333061A8F34000000031F
+:1017D000041A8F4000010334061A8F4400000003EE
+:1017E000041A8F5000010335061A8F5400000003BD
+:1017F000041A8F6000010336061A8F64000000038C
+:10180000041A8F7000010337061A8F74000000035A
+:10181000041A8F8000010338061A8F840000000329
+:10182000041A8F9000010339061A8F9400000003F8
+:10183000041A8FA00001033A061A8FA400000003C7
+:10184000041A8FB00001033B061A8FB40000000396
+:10185000041A8FC00001033C061A8FC40000000365
+:10186000041A8FD00001033D061A8FD40000000334
+:10187000041A8FE00001033E061A8FE400000007FF
+:10188000041A62C00020033F061AD0000000007254
+:10189000061AD24800000010061AD6B00000002038
+:1018A000061AD47000000090061AD46800000002E6
+:1018B000061AA000000001C4061A30000000001043
+:1018C000061A308000000010061A310000000010D7
+:1018D000061A318000000010061A330000000012C2
+:1018E000061A339000000070061AD4580000000257
+:1018F000061AD34800000002061AD3580000002040
+:10190000061AA710000001C4061A3040000000109B
+:10191000061A30C000000010061A31400000001006
+:10192000061A31C000000010061A334800000012E9
+:10193000061A355000000070061AD460000000023C
+:10194000061AD35000000002061AD3D80000002067
+:10195000021AAE2000000000061A5000000000022B
+:10196000061A508000000012041A40000002035FB3
+:10197000041A63C000020361061A7000000000042C
+:10198000061A320000000008021AAE24000000000F
+:10199000061A501000000002061A50C8000000127B
+:1019A000041A400800020363041A63C800020365B6
+:1019B000061A701000000004061A32200000000809
+:1019C000021AAE2800000000061A50200000000293
+:1019D000061A511000000012041A4010000203679A
+:1019E000041A63D000020369061A70200000000484
+:1019F000061A324000000008021AAE2C0000000057
+:101A0000061A503000000002061A51580000001259
+:101A1000041A40180002036B041A63D80002036D15
+:101A2000061A703000000004061A32600000000838
+:101A3000021AAE3000000000061A504000000002FA
+:101A4000061A51A000000012041A40200002036F81
+:101A5000041A63E000020371061A704000000004DB
+:101A6000061A328000000008021AAE34000000009E
+:101A7000061A505000000002061A51E80000001239
+:101A8000041A402800020373041A63E80002037575
+:101A9000061A705000000004061A32A00000000868
+:101AA000021AAE3800000000061A50600000000262
+:101AB000061A523000000012041A40300002037768
+:101AC000041A63F000020379061A70600000000433
+:101AD000061A32C000000008021AAE3C00000000E6
+:101AE000061A507000000002061A52780000001218
+:101AF000041A40380002037B041A63F80002037DD5
+:101B0000061A707000000004061A32E00000000897
+:101B10000200A468000B01C80200A294071D29114D
+:101B20000200A298000000000200A29C009C042475
+:101B30000200A2A0000000000200A2A4000002090E
+:101B40000200A270000000000200A2740000000069
+:101B50000200A270000000000200A2740000000059
+:101B60000200A270000000000200A2740000000049
+:101B70000200A270000000000200A2740000000039
+:101B8000020160A000000001020160A400000262E6
+:101B9000020160A800000002020160AC0000001811
+:101BA0000201620400000001020100B40000000113
+:101BB000020100B800000001020100DC0000000189
+:101BC0000201010000000001020101040000000107
+:101BD0000201007C003000000201008400000028A7
+:101BE0000201008C0000000002010130000000042E
+:101BF0000201025C00000001020103280000000055
+:101C0000020160580000FFFF020160700000000741
+:101C10000201608000000001020105540000003054
+:101C2000020100C400000001020100CC000000011C
+:101C3000020100F800000001020100F000000001B4
+:101C4000020100800030000002010088000000282E
+:101C500002010090000000000201013400000004B5
+:101C6000020102DC000000010201032C0000000060
+:101C70000201605C0000FFFF0201607400000007C9
+:101C800002016084000000010201056400000030D0
+:101C9000020100C800000001020100D000000001A4
+:101CA000020100FC00000001020100F4000000013C
+:101CB000020C100000000028020C20080000021195
+:101CC000020C200C00000200020C20100000020494
+:101CD000020C201C0000FFFF020C20200000FFFF70
+:101CE000020C20240000FFFF020C20280000FFFF50
+:101CF000020C203800000020020C203C00000021D3
+:101D0000020C204000000022020C204400000023AE
+:101D1000020C204800000024020C204C000000258A
+:101D2000020C205000000026020C20540000002766
+:101D3000020C205800000028020C205C0000002942
+:101D4000020C20600000002A020C20640000002B1E
+:101D5000020C20680000002C020C206C0000002DFA
+:101D6000020C20700000002E020C20740000002FD6
+:101D7000020C207800000010060C207C00000007F8
+:101D8000020C209800000011020C209C00000012A0
+:101D9000020C20A000000013060C20A40000001D6F
+:101DA000020C211800000001020C211C000000019F
+:101DB000020C212000000001060C21240000001D5F
+:101DC000020C219800000001060C219C0000000775
+:101DD000020C21B800000001020C21BC000000012F
+:101DE000020C21C000000001020C21C4000000010F
+:101DF000020C21C800000001020C21CC00000001EF
+:101E0000020C21D000000001020C21D400000001CE
+:101E1000020C21D800000001020C21DC00000001AE
+:101E2000020C21E000000001020C21E4000000018E
+:101E3000020C21E800000001020C21EC000000016E
+:101E4000020C21F000000001020C21F4000000014E
+:101E5000020C21F800000001060C21FC0000000724
+:101E6000020C221800000001060C221C00000007D2
+:101E7000020C223807FFFFFF020C223C0000003F4B
+:101E8000020C224007FFFFFF020C22440000000F5B
+:101E9000010C224800000000010C224C0000000050
+:101EA000010C225000000000010C22540000000030
+:101EB000010C225800000000010C225C0000000010
+:101EC000010C226000000000010C226400000000F0
+:101ED000010C226800000000010C226C00000000D0
+:101EE000010C227000000000010C227400000000B0
+:101EF000010C227800000000010C227C0000000090
+:101F00000C0C2000000003E80A0C20000000000177
+:101F10000B0C20000000000A020C40080000101109
+:101F2000020C400C00001000020C401000001004D5
+:101F3000020C401400001021020C401C0000FFFFA6
+:101F4000020C40200000FFFF020C40240000FFFFB5
+:101F5000020C40280000FFFF020C40380000004641
+:101F6000020C403C00000010060C40400000000243
+:101F7000020C404800000018020C404C000000F029
+:101F8000060C40500000001F020C40CC0000000175
+:101F9000060C40D00000003A020C41B800000001DD
+:101FA000060C41BC00000003020C41C80000000107
+:101FB000020C41CC00000001060C41D00000001AC8
+:101FC000020C423807FFFFFF020C423C0000003FBA
+:101FD000020C424007FFFFFF020C42440000000FCA
+:101FE000010C424800000000010C424C00000000BF
+:101FF000010C425000000000010C4254000000009F
+:10200000010C425800000000010C425C000000007E
+:10201000010C426000000000010C4264000000005E
+:10202000010C426800000000010C426C000000003E
+:10203000010C427000000000010C4274000000001E
+:10204000010C427800000000010C427C00000000FE
+:10205000010C4280000000000C0C4000000003E86E
+:102060000A0C4000000000010B0C40000000000AB8
+:10207000060D400000000A00020D0044000000327E
+:10208000020D008C02150020020D009002150020A8
+:10209000020D009408100000020D009800000033AB
+:1020A000020D009C00000002020D00A000000000D4
+:1020B000020D00A400000005020D00A800000005AC
+:1020C000060D00AC00000002020D00B4000000028A
+:1020D000020D00B800000003020D00BC0000000269
+:1020E000020D00C000000001020D00C80000000247
+:1020F000020D00CC00000002020D015C0000000196
+:10210000020D016400000001020D016800000002E0
+:10211000020D020400000001020D020C000000206C
+:10212000020D021000000040020D021400000040E9
+:10213000020D022000000003020D0224000000181E
+:10214000060D028000000012040D03000018037F3A
+:10215000060D03600000000C020D004C00000001A1
+:10216000020D005000000002020D005400000000AB
+:10217000020D005800000008060D005C000000047D
+:10218000020D00C400000004020D00040000000164
+:10219000020D000800000001020D000C000000010B
+:1021A000020D001000000001020D001400000001EB
+:1021B000020D001800000001020D001C00000001CB
+:1021C000020D002000000001020D002400000001AB
+:1021D000020D002800000001020D002C000000018B
+:1021E000020D003000000001020D0034000000016B
+:1021F000020D003800000001020D003C000000014B
+:10220000020D011400000009020D011C0000000A6B
+:10221000020D012400000000020D012C000000004E
+:10222000020D013400000000020D013C0000000B13
+:10223000020D014400000000020D011800000029F9
+:10224000020D01200000002A020D012800000020DC
+:10225000020D013000000020020D013800000020B6
+:10226000020D01400000002B020D0148000000207B
+:10227000020D011400000019020D011C0000001ADB
+:10228000020D012400000010020D012C00000010BE
+:10229000020D013400000010020D013C0000001B83
+:1022A000020D014400000010020D01180000003969
+:1022B000020D01200000003A020D0128000000304C
+:1022C000020D013000000030020D01380000003026
+:1022D000020D01400000003B020D014800000030EB
+:1022E000020D011400000049020D011C0000004A0B
+:1022F000020D012400000040020D012C00000040EE
+:10230000020D013400000040020D013C0000004BB2
+:10231000020D014400000040020D01180000006998
+:10232000020D01200000006A020D0128000000607B
+:10233000020D013000000060020D01380000006055
+:10234000020D01400000006B020D0148000000601A
+:10235000020D011400000059020D011C0000005A7A
+:10236000020D012400000050020D012C000000505D
+:10237000020D013400000050020D013C0000005B22
+:10238000020D014400000050020D01180000007908
+:10239000020D01200000007A020D012800000070EB
+:1023A000020D013000000070020D013800000070C5
+:1023B000020D01400000007B020D0148000000708A
+:1023C000060E200000000800020E004C0000003243
+:1023D000020E009402150020020E00980215002043
+:1023E000020E009C00000030020E00A00810000049
+:1023F000020E00A400000033020E00A8000000300E
+:10240000020E00AC00000031020E00B0000000021D
+:10241000020E00B400000004020E00B8000000002C
+:10242000020E00BC00000002020E00C0000000020C
+:10243000020E00C400000000020E00C800000002EE
+:10244000020E00CC00000007020E00D000000002C7
+:10245000020E00D400000002020E00D800000001AD
+:10246000020E014400000001020E014C00000001B8
+:10247000020E015000000002020E020400000001E2
+:10248000020E020C00000040020E0210000000408C
+:10249000020E021C00000004020E022000000020B8
+:1024A000020E02240000000E020E02280000001B93
+:1024B000060E030000000012040E0280001B0397AA
+:1024C000060E02EC00000005020E00540000000C95
+:1024D000020E00580000000C020E005C000000001C
+:1024E000020E006000000010020E006400000010E8
+:1024F000060E006800000003020E00DC000000036E
+:10250000020E000400000001020E0008000000019D
+:10251000020E000C00000001020E0010000000017D
+:10252000020E001400000001020E0018000000015D
+:10253000020E001C00000001020E0020000000013D
+:10254000020E002400000001020E0028000000011D
+:10255000020E002C00000001020E003000000001FD
+:10256000020E003400000001020E003800000001DD
+:10257000020E003C00000001020E004000000001BD
+:10258000020E004400000001020E01100000000FC6
+:10259000020E011800000000020E012000000000E1
+:1025A000020E012800000000020E01140000002F9E
+:1025B000020E011C00000020020E01240000000099
+:1025C000020E012C00000000020E01100000001F8E
+:1025D000020E011800000010020E01200000000091
+:1025E000020E012800000000020E01140000003F4E
+:1025F000020E011C00000030020E01240000000049
+:10260000020E012C00000000020E01100000004F1D
+:10261000020E011800000040020E01200000000020
+:10262000020E012800000000020E01140000006FDD
+:10263000020E011C00000060020E012400000000D8
+:10264000020E012C00000000020E01100000005FCD
+:10265000020E011800000050020E012000000000D0
+:10266000020E012800000000020E01140000007F8D
+:10267000020E011C00000070020E01240000000088
+:10268000020E012C000000000730040000C9000009
+:10269000083007D8000503B207340000332B0000D0
+:1026A0000734800030A40CCB07350000351A18F52C
+:1026B000073580002A8A263C0736000018D830DF0C
+:1026C00008364630373A03B40130000000000000FD
+:1026D000013000040000000001300008000000008C
+:1026E0000130000C0000000001300010000000006C
+:1026F0000130001400000000023000200000000142
+:102700000230002400000002023000280000000314
+:102710000230002C000000000230003000000004F5
+:1027200002300034000000010230003800000000D8
+:102730000230003C000000010230004000000004B4
+:102740000230004400000000023000480000000198
+:102750000230004C00000003023000500000000076
+:102760000230005400000001023000580000000454
+:102770000230005C00000000023000600000000138
+:102780000230006400000003023000680000000016
+:102790000230006C000000010230007000000004F4
+:1027A00002300074000000000230007800000004D5
+:1027B0000230007C000000030630008000000002B0
+:1027C000023000A400003FFF023000A8000003FF19
+:1027D0000230022400000000023002340000000039
+:1027E0000230024C00000000023002E40000FFFF53
+:1027F000063020000000080002338BC000000001FA
+:10280000023380000000001A023380400000004EB6
+:102810000233808000000010023380C000000020DE
+:102820000C3383000007A1200A3383000000013825
+:102830000B338300000013880A338340000000003C
+:102840000C338340000001F40B338340000000058B
+:10285000023383800007A120023383C0000001F40B
+:1028600002331480000000010A33148000000000CD
+:10287000063280000000010206322008000000C875
+:10288000063220000000000204328EA0001003B6C1
+:1028900006323EB00000000606323ED800000002BC
+:1028A00006323E800000000A04323EA8000203C641
+:1028B00006323E00000000200632500000000400F6
+:1028C0000632400000000004043274C0000203C855
+:1028D00006324110000000020632D0000000003035
+:1028E0000632DD40000000440632DA00000000D06D
+:1028F0000632DEA0000000020632E0000000080000
+:1029000006328450000001180632100000000188D1
+:102910000632500000000020063251000000002066
+:102920000632520000000020063253000000002052
+:10293000063254000000002006325500000000203E
+:10294000063256000000002006325700000000202A
+:102950000632580000000020063259000000002016
+:1029600006325A000000002006325B000000002002
+:1029700006325C000000002006325D0000000020EE
+:1029800006325E000000002006325F0000000020DA
+:1029900006328DF00000000204328E00000203CAED
+:1029A00006328E08000000020632DE9000000002AF
+:1029B00006321C4000000038063288B000000118C2
+:1029C00006321620000001880632508000000020E8
+:1029D00006325180000000200632528000000020A4
+:1029E0000632538000000020063254800000002090
+:1029F000063255800000002006325680000000207C
+:102A00000632578000000020063258800000002067
+:102A1000063259800000002006325A800000002053
+:102A200006325B800000002006325C80000000203F
+:102A300006325D800000002006325E80000000202B
+:102A400006325F800000002006328DF80000000290
+:102A500004328E10000203CC06328E1800000002F1
+:102A60000632DE980000000206321D200000003809
+:102A700002328D50000000000632401000000002BB
+:102A800002328D5400000000063240200000000297
+:102A900002328D5800000000063240300000000273
+:102AA00002328D5C0000000006324040000000024F
+:102AB00002328D600000000006324050000000022B
+:102AC00002328D6400000000063240600000000207
+:102AD00002328D68000000000632407000000002E3
+:102AE00002328D6C000000000632408000000002BF
+:102AF000072004000091000008200780001003CE8A
+:102B0000072400002AFF00000724800015090AC0DE
+:102B10000824A9F0692803D001200000000000006B
+:102B20000120000400000000012000080000000057
+:102B30000120000C00000000012000100000000037
+:102B4000012000140000000002200020000000010D
+:102B500002200024000000020220002800000003E0
+:102B60000220002C000000000220003000000004C1
+:102B700002200034000000010220003800000000A4
+:102B80000220003C00000001022000400000000480
+:102B90000220004400000000022000480000000164
+:102BA0000220004C00000003022000500000000042
+:102BB0000220005400000001022000580000000420
+:102BC0000220005C00000000022000600000000104
+:102BD00002200064000000030220006800000000E2
+:102BE0000220006C000000010220007000000004C0
+:102BF00002200074000000000220007800000004A1
+:102C00000220007C0000000306200080000000027B
+:102C1000022000A400003FFF022000A8000003FFE4
+:102C20000220022400000000022002340000000004
+:102C30000220024C00000000022002E40000FFFF1E
+:102C4000062020000000080002238BC000000001C5
+:102C500002238000000000100223804000000012C8
+:102C60000223808000000030022380C00000000E9C
+:102C70000C2383000007A1200A23830000000138F1
+:102C80000B238300000013880A2383400000000008
+:102C90000C238340000001F40B2383400000000557
+:102CA000022383800007A120022383C0000001F4D7
+:102CB00002231480000000010A2314800000000099
+:102CC000062210000000004206222008000000C872
+:102CD00006222000000000020622B000000000C60C
+:102CE0000422B318000503D20622B32C0000000B07
+:102CF0000422B358000503D70622B36C0000000B72
+:102D00000422B398000503DC0622B3AC0000000BDC
+:102D10000422B3D8000503E10622B3EC0000000B47
+:102D20000422B418000503E60622B42C0000000BB0
+:102D30000422B458000503EB0622B46C0000000B1B
+:102D40000422B498000503F00622B4AC0000000B86
+:102D50000422B4D8000503F50622B4EC0000000BF1
+:102D60000422B518000503FA0622B52C0000000B5A
+:102D70000422B558000503FF0622B56C0000000BC5
+:102D80000422B598000504040622B5AC0000000B2F
+:102D90000422B5D8000504090622B5EC0000000B9A
+:102DA0000422B6180005040E0622B62C0000000B03
+:102DB0000422B658000504130622B66C0000000B6E
+:102DC0000422B698000504180622B6AC0000000BD9
+:102DD0000422B6D80005041D0622B6EC0000000B44
+:102DE0000422B718000504220622B72C0000000BAD
+:102DF0000422B758000504270622B76C0000000B18
+:102E00000422B7980005042C0622B7AC0000000B82
+:102E10000422B7D8000504310622B7EC0000000BED
+:102E20000422B818000504360622B82C0000000B56
+:102E30000422B8580005043B0622B86C0000000BC1
+:102E40000422B898000504400622B8AC0000000B2C
+:102E50000422B8D8000504450622B8EC0000000B97
+:102E60000422B9180005044A0622B92C0000000B00
+:102E70000422B9580005044F0622B96C0000000B6B
+:102E80000422B998000504540622B9AC0000000BD6
+:102E90000422B9D8000504590622B9EC0000000B41
+:102EA0000422BA180005045E0622BA2C0000000BAA
+:102EB0000422BA58000504630622BA6C0000000B15
+:102EC0000422BA98000504680622BAAC0000000B80
+:102ED0000422BAD80005046D0622BAEC00000005F1
+:102EE0000622BB00000000530422BC4C0001047207
+:102EF0000622BC50000000030422BC5C00010473E5
+:102F00000622BC60000000030422BC6C00010474B3
+:102F10000622BC70000000030422BC7C0001047582
+:102F20000622BC80000000030422BC8C0001047651
+:102F30000622BC90000000030422BC9C0001047720
+:102F40000622BCA0000000030422BCAC00010478EF
+:102F50000622BCB0000000030422BCBC00010479BE
+:102F60000622880000000100062280000000020006
+:102F7000042212700010047A06223000000000C003
+:102F800006226700000001000622900000000400F5
+:102F900004226B080020048A022212C0FFFFFFFFF8
+:102FA000062211E800000002062212C800000009F3
+:102FB000062212EC0000000906228C000000000826
+:102FC0000222114800000000062213200000000623
+:102FD000062233000000000206226040000000309C
+:102FE00006228C20000000080222114C0000000084
+:102FF00006221338000000060622330800000002F3
+:10300000062261000000003006228C40000000080B
+:10301000022211500000000006221350000000069A
+:103020000622331000000002062261C000000030BA
+:1030300006228C60000000080222115400000000EB
+:103040000622136800000006062233180000000262
+:10305000062262800000003006228C8000000008FA
+:103060000222115800000000062213800000000612
+:1030700006223320000000020622634000000030D8
+:1030800006228CA0000000080222115C0000000053
+:1030900006221398000000060622332800000002D2
+:1030A000062264000000003006228CC000000008E8
+:1030B0000222116000000000062213B0000000068A
+:1030C0000622333000000002062264C000000030F7
+:1030D00006228CE0000000080222116400000000BB
+:1030E000062213C800000006062233380000000242
+:1030F0000622658000000030021610000000002843
+:1031000002170008000000020217002C0000000354
+:103110000217003C000000040217004800000002F3
+:103120000217004C000000900217005000000090B1
+:103130000217005400800090021700580810000089
+:10314000021700600000008A02170064000000807F
+:1031500002170068000000810217006C0000008068
+:10316000021700700000000602170078000007D068
+:103170000217007C0000076C02170038007C100466
+:10318000021700040000000F061640240000000291
+:10319000021640700000001C0216420800000001E8
+:1031A0000216421000000001021642200000000139
+:1031B0000216422800000001021642300000000101
+:1031C00002164238000000010216426000000002B0
+:1031D0000C16401C0003D0900A16401C0000009CF6
+:1031E0000B16401C000009C4021640300000000805
+:1031F000021640340000000C021640380000001097
+:1032000002164044000000200216400000000001A9
+:10321000021640D80000000102164008000000011C
+:103220000216400C000000010216401000000001D0
+:103230000216424000000000021642480000000052
+:103240000616427000000002021642500000000004
+:1032500002164258000000000616428000000002DC
+:1032600002166008000012240216600C0000121002
+:1032700002166010000012140216601C0000FFFF0E
+:10328000021660200000FFFF021660240000FFFF0E
+:10329000021660280000FFFF0216603800000020C0
+:1032A0000216603C0000002006166040000000028C
+:1032B00002166048000000230216604C0000002443
+:1032C000021660500000002502166054000000261F
+:1032D00002166058000000270216605C00000029FA
+:1032E000021660600000002A021660640000002BD5
+:1032F000021660680000002C0216606C0000002DB1
+:1033000002166070000000EC0216607400000011EC
+:1033100002166078000000120616607C0000000FA4
+:10332000021660B800000001021660BC0000000137
+:10333000061660C00000000C021660F000000001DC
+:10334000061660F400000031021661B800000001AA
+:10335000061661BC0000000D021661F000000001BD
+:10336000061661F4000000110216623807FFFFFF25
+:103370000216623C0000003F0216624007FFFFFF9A
+:10338000021662440000000F0116624800000000AF
+:103390000116624C0000000001166250000000009F
+:1033A000011662540000000001166258000000007F
+:1033B0000116625C0000000001166260000000005F
+:1033C000011662640000000001166268000000003F
+:1033D0000116626C0000000001166270000000001F
+:1033E00001166274000000000116627800000000FF
+:1033F0000116627C000000000C166000000003E86B
+:103400000A166000000000010B1660000000000AB0
+:1034100002168040000000060216804400000005ED
+:10342000021680480000000A0216804C00000005C9
+:103430000216805400000002021680CC0000000436
+:10344000021680D000000004021680D400000004A0
+:10345000021680D800000004021680DC0000000480
+:10346000021680E000000004021680E40000000460
+:10347000021680E800000004021688040000000420
+:10348000021680300000007C021680340000003DEF
+:10349000021680380000003F0216803C0000009CAD
+:1034A000021680F000000007061680F400000005F8
+:1034B0000216880C010101010216810800000000BB
+:1034C0000216810C000000040216811000000004A6
+:1034D0000216811400000002021688100801200460
+:1034E00002168118000000050216811C000000056C
+:1034F000021681200000000502168124000000054C
+:103500000216882C200810010216812800000008ED
+:103510000216812C00000006021681300000000710
+:1035200002168134000000000216883001010120DB
+:1035300006168138000000040216883401010101DA
+:1035400002168148000000000216814C00000004B1
+:10355000021681500000000402168154000000028F
+:103560000216883808012004021681580000000560
+:103570000216815C00000005021681600000000553
+:1035800002168164000000050216883C2008100124
+:1035900002168168000000080216816C0000000617
+:1035A00002168170000000070216817400000001FD
+:1035B00002168840010101200216817800000001F6
+:1035C0000216817C000000010216818000000001CB
+:1035D00002168184000000010216884401010101E5
+:1035E00002168188000000010216818C0000000490
+:1035F000021681900000000402168194000000026F
+:10360000021688480801200402168198000000056F
+:103610000216819C00000005021681A00000000532
+:10362000021681A40000000502168814200810016B
+:10363000021681A800000008021681AC00000006F6
+:10364000021681B000000007021681B400000001DC
+:103650000216881801010120021681B8000000013D
+:10366000021681BC00000001021681C000000001AA
+:10367000021681C4000000010216881C010101012C
+:10368000021681C800000001021681CC000000046F
+:10369000021681D000000004021681D4000000024E
+:1036A0000216882008012004021681D800000005B7
+:1036B000021681DC00000005021681E00000000512
+:1036C000021681E40000000502168824200810017B
+:1036D000021681E800000008021681EC00000006D6
+:1036E000021681F0000000070216E40C0000000042
+:1036F00002168828010101200616E41000000004CB
+:103700000216E000010101010216E42000000000A1
+:103710000216E424000000040216E428000000045D
+:103720000216E42C000000020216E0040801200446
+:103730000216E430000000050216E4340000000523
+:103740000216E438000000050216E43C0000000503
+:103750000216E008200810010216E44000000008EC
+:103760000216E444000000060216E44800000007C8
+:103770000216E44C000000000216E00C01010120DA
+:103780000616E450000000040216E01001010101D9
+:103790000216E460000000000216E4640000000469
+:1037A0000216E468000000040216E46C0000000247
+:1037B0000216E014080120040216E470000000055F
+:1037C0000216E474000000050216E478000000050B
+:1037D0000216E47C000000050216E0182008100123
+:1037E0000216E480000000080216E48400000006CF
+:1037F0000216E488000000070216E48C00000001B5
+:103800000216E01C010101200216E49000000001F4
+:103810000216E494000000010216E4980000000182
+:103820000216E49C000000010216E02001010101E3
+:103830000216E4A0000000010216E4A40000000447
+:103840000216E4A8000000040216E4AC0000000226
+:103850000216E024080120040216E4B0000000056E
+:103860000216E4B4000000050216E4B800000005EA
+:103870000216E4BC000000050216E0282008100132
+:103880000216E4C0000000080216E4C400000006AE
+:103890000216E4C8000000070216E4CC0000000194
+:1038A0000216E02C010101200216E4D00000000104
+:1038B0000216E4D4000000010216E4D80000000162
+:1038C0000216E4DC000000010216E03001010101F3
+:1038D0000216E4E0000000010216E4E40000000427
+:1038E0000216E4E8000000040216E4EC0000000206
+:1038F0000216E034080120040216E4F0000000057E
+:103900000216E4F4000000050216E4F800000005C9
+:103910000216E4FC000000050216E0382008100141
+:103920000216E500000000080216E504000000068B
+:103930000216E508000000070216E03C0101012024
+:1039400002168240003F003F021682440000000041
+:103950000216E524003F003F0216E52800000000A3
+:1039600002168248000000000216824C003F003F11
+:103970000216E52C000000000216E530003F003F73
+:10398000021682500100010002168254010001005B
+:103990000216E534010001000216E53801000100BD
+:1039A00006168258000000020216E53C00000000E6
+:1039B0000216E540000000000216826000C000C050
+:1039C0000216826400C000C00216E54400C000C0B8
+:1039D0000216E54800C000C0021682681E001E00E4
+:1039E0000216826C1E001E000216E54C1E001E0010
+:1039F0000216E5501E001E000216827040004000B4
+:103A000002168274400040000216E5544000400057
+:103A10000216E558400040000216827880008000BF
+:103A20000216827C800080000216E55C8000800027
+:103A30000216E560800080000216828020002000CF
+:103A400002168284200020000216E5642000200077
+:103A50000216E56820002000061682880000000299
+:103A60000216E56C000000000216E5700000000080
+:103A700002168290000000000216829400000000EE
+:103A80000216E574000000000216E5780000000050
+:103A900002168298000000000216829C00000000BE
+:103AA0000216E57C000000000216E5800000000020
+:103AB000021682A000000000021682A4000000018D
+:103AC000061682A80000000A021681F400000C0805
+:103AD000021681F800000040021681FC000001007F
+:103AE0000216820000000020021682040000001767
+:103AF00002168208000000800216820C00000200FC
+:103B000002168210000000000216821801FF01FF59
+:103B10000216821401FF01FF0216E51001FF01FFEA
+:103B20000216E50C01FF01FF0216823C00000013A3
+:103B3000021680900000013F0216806000000140E4
+:103B40000216806400000140061680680000000232
+:103B500002168070000000C0061680740000000786
+:103B60000216809C00000048021680A00000004859
+:103B7000061680A400000002021680AC0000004877
+:103B8000061680B000000007021682380000800090
+:103B900002168234000025E40216809400007FFFA4
+:103BA00002168220000F000F0216821C000F000F69
+:103BB0000216E518000F000F0216E514000F000FA3
+:103BC000021682280000000002168224FFFFFFFF79
+:103BD0000216E520000000000216E51CFFFFFFFFB3
+:103BE0000216E6BC000000000216E6C0000000025B
+:103BF0000216E6C4000000010216E6C80000000339
+:103C00000216E6CC000000040216E6D00000000612
+:103C10000216E6D4000000050216E6D800000007F0
+:103C2000021680EC000000FF0214000000000001FA
+:103C30000214000C0000000102140040000000010A
+:103C40000214004400007FFF0214000C000000007A
+:103C500002140000000000000214006C00000000CC
+:103C600002140004000000010214003000000001F2
+:103C700002140004000000000214005C00000000B8
+:103C800002140008000000010214003400000001CA
+:103C90000214000800000000021400600000000090
+:103CA00006028000000020000202005800000032DE
+:103CB000020200A003150020020200A40315002048
+:103CC000020200A801000030020200AC081000004F
+:103CD000020200B000000033020200B40000003015
+:103CE000020200B800000031020200BC0000000324
+:103CF000020200C000000006020200C4000000032F
+:103D0000020200C800000003020200CC0000000212
+:103D1000020200D000000000020200D400000002F5
+:103D2000020200DC00000000020200E000000006C9
+:103D3000020200E400000004020200E800000002A9
+:103D4000020200EC00000002020200F0000000018C
+:103D5000020200FC00000006020201200000000038
+:103D60000202013400000002020201B00000000162
+:103D70000202020C00000001020202140000000115
+:103D80000202021800000002020204040000000106
+:103D90000202040C00000040020204100000004077
+:103DA0000202041C000000040202042000000020A3
+:103DB0000202042400000002020204280000002085
+:103DC000060205000000001204020480002004AA7C
+:103DD000020200600000000F020200640000000701
+:103DE00002020068000000000202006C0000000EE9
+:103DF000020200700000000E0602007400000003C2
+:103E0000020200F4000000040202000400000001AD
+:103E100002020008000000010202000C0000000184
+:103E20000202001000000001020200140000000164
+:103E300002020018000000010202001C0000000144
+:103E40000202002000000001020200240000000124
+:103E500002020028000000010202002C0000000104
+:103E600002020030000000010202003400000001E4
+:103E700002020038000000010202003C00000001C4
+:103E800002020040000000010202004400000001A4
+:103E900002020048000000010202004C0000000184
+:103EA000020200500000000102020108000000C8E8
+:103EB0000202011800000002020201C4000000001A
+:103EC000020201CC00000000020201D40000000246
+:103ED000020201DC00000002020201E4000000FF17
+:103EE000020201EC000000FF0202010000000000DD
+:103EF0000202010C000000C80202011C00000002C6
+:103F0000020201C800000000020201D0000000000F
+:103F1000020201D800000002020201E000000002DB
+:103F2000020201E8000000FF020201F0000000FFB1
+:103F3000020201040000000002020108000000C8A3
+:103F40000202011800000002020201C40000000089
+:103F5000020201CC00000000020201D400000002B5
+:103F6000020201DC00000002020201E4000000FF86
+:103F7000020201EC000000FF02020100000000004C
+:103F80000202010C000000C80202011C0000000235
+:103F9000020201C800000000020201D0000000007F
+:103FA000020201D800000002020201E0000000024B
+:103FB000020201E8000000FF020201F0000000FF21
+:103FC000020201040000000002020108000000C813
+:103FD0000202011800000002020201C400000000F9
+:103FE000020201CC00000000020201D40000000225
+:103FF000020201DC00000002020201E4000000FFF6
+:10400000020201EC000000FF0202010000000000BB
+:104010000202010C000000C80202011C00000002A4
+:10402000020201C800000000020201D000000000EE
+:10403000020201D800000002020201E000000002BA
+:10404000020201E8000000FF020201F0000000FF90
+:10405000020201040000000002020108000000C882
+:104060000202011800000002020201C40000000068
+:10407000020201CC00000000020201D40000000294
+:10408000020201DC00000002020201E4000000FF65
+:10409000020201EC000000FF02020100000000002B
+:1040A0000202010C000000C80202011C0000000214
+:1040B000020201C800000000020201D0000000005E
+:1040C000020201D800000002020201E0000000022A
+:1040D000020201E8000000FF020201F0000000FF00
+:1040E00002020104000000000728040000A30000F1
+:1040F000082807B8000904CA072C000034F10000A2
+:10410000072C800038A60D3D072D000037B61B6731
+:10411000072D800032632955072E00001C6835EEFC
+:10412000082E48B036EA04CC012800000000000048
+:104130000128000400000000012800080000000021
+:104140000128000C00000000012800100000000001
+:1041500001280014000000000228002000000001D7
+:1041600002280024000000020228002800000003AA
+:104170000228002C0000000002280030000000048B
+:10418000022800340000000102280038000000006E
+:104190000228003C0000000102280040000000044A
+:1041A000022800440000000002280048000000012E
+:1041B0000228004C0000000302280050000000000C
+:1041C00002280054000000010228005800000004EA
+:1041D0000228005C000000000228006000000001CE
+:1041E00002280064000000030228006800000000AC
+:1041F0000228006C0000000102280070000000048A
+:10420000022800740000000002280078000000046A
+:104210000228007C00000003062800800000000245
+:10422000022800A400003FFF022800A8000003FFAE
+:1042300002280224000000000228023400000000CE
+:104240000228024C00000000022802E40000FFFFE8
+:104250000628200000000800022B8BC0000000018F
+:10426000022B800000000000022B8040000000189C
+:10427000022B80800000000C022B80C00000006632
+:104280000C2B83000007A1200A2B830000000138BB
+:104290000B2B8300000013880A2B834000000000D2
+:1042A0000C2B8340000001F40B2B83400000000521
+:1042B000022B83800007A120022B83C0000001F4A1
+:1042C000022B1480000000010A2B14800000000063
+:1042D000062A9AF800000004042A9B08000204CE73
+:1042E000062A9B1000000006062A90800000004865
+:1042F000062A2008000000C8062A2000000000024C
+:10430000062A91A800000086062A900000000020DE
+:10431000062A93C800000003042A93D4000104D0A5
+:10432000062A9DA800000002042A9498000404D1E3
+:10433000042A9D58000104D5062A9D5C0000001146
+:10434000042ACB20001004D6042A3000000204E620
+:10435000062A300800000100062A40400000001034
+:10436000042A4000001004E8042A8408000204F82B
+:10437000062A9DA000000002062AB000000000509E
+:10438000062ABB7000000070062AB150000000022F
+:10439000062ABB6000000004062AD00000000800C6
+:1043A000062AC00000000150062A94A8000000322E
+:1043B000062A502000000002062A503000000002A9
+:1043C000062A500000000002062A501000000002D9
+:1043D000022A520800000001042A9B28000204FA65
+:1043E000062A963800000022042A96C0000104FC28
+:1043F000062A96C400000003062A976800000022DF
+:10440000042A97F0000104FD062A97F40000000337
+:10441000062A989800000022042A9920000104FE30
+:10442000062A992400000003062A99C800000022E9
+:10443000042A9A50000104FF062A9A54000000033F
+:10444000062AB14000000002062AC54000000150C3
+:10445000062A957000000032062A5028000000024B
+:10446000062A503800000002062A50080000000208
+:10447000062A501800000002022A520C0000000117
+:10448000042A9B3000020500062A96D00000002274
+:10449000042A975800010502062A975C00000003D1
+:1044A000062A980000000022042A988800010503CB
+:1044B000062A988C00000003062A9930000000228A
+:1044C000042A99B800010504062A99BC00000003DB
+:1044D000062A9A6000000022042A9AE800010505D5
+:1044E000062A9AEC00000003062AB14800000002E8
+:1044F000022ACA8000000000042A9B38001005062A
+:10450000062A50480000000E022ACA84000000005B
+:10451000042A9B7800100516062A50800000000E21
+:10452000022ACA8800000000042A9BB80010052651
+:10453000062A50B80000000E022ACA8C00000000B3
+:10454000042A9BF800100536062A50F00000000EE1
+:10455000022ACA9000000000042A9C380010054678
+:10456000062A51280000000E022ACA94000000000A
+:10457000042A9C7800100556062A51600000000E9F
+:10458000022ACA9800000000042A9CB800100566A0
+:10459000062A51980000000E022ACA9C0000000062
+:1045A000042A9CF800100576062A51D00000000E5F
+:1045B000021010080000000102101050000000015D
+:1045C000021010000003D000021010040000003D93
+:1045D0000910180002000586091011000010078656
+:1045E0000610114000000008091011600010079625
+:1045F000061011A00000001806102400000000E0C2
+:104600000210201C00000000021020200000000109
+:10461000021020C00000000202102004000000016F
+:10462000021020080000000109103C00000507A648
+:1046300009103800000507AB09103820000507B045
+:1046400006104C000000010002104028000000107D
+:104650000210404400003FFF0210405800280000B4
+:10466000021040840084924A02104058000000006A
+:104670000210800000001080021080AC00000000DA
+:1046800002108038000000100210810000000000BD
+:10469000061081200000000202108008000002B510
+:1046A0000210801000000000061082000000004A86
+:1046B000021081080001FFFF061081400000000287
+:1046C0000210800000001A800610900000000024F4
+:1046D000061091200000004A061093700000004A66
+:1046E000061095C00000004A0210800400001080EF
+:1046F000021080B0000000010210803C0000001099
+:104700000210810400000000061081280000000251
+:104710000210800C000002B502108014000000009E
+:10472000061084000000004A0210810C0001FFFF07
+:1047300006108148000000020210800400001A8068
+:104740000610909000000024061092480000004AD5
+:10475000061094980000004A061096E80000004AEF
+:104760000210800000001080021080AC00000002E7
+:1047700002108038000000100210810000000000CC
+:10478000061081200000000202108008000002B51F
+:104790000210801000000000061082000000004A95
+:1047A000021081080001FFFF061081400000000296
+:1047B0000210800000001A80061090000000002403
+:1047C000061091200000004A061093700000004A75
+:1047D000061095C00000004A0210800400001080FE
+:1047E000021080B0000000030210803C00000010A6
+:1047F0000210810400000000061081280000000261
+:104800000210800C000002B50210801400000000AD
+:10481000061084000000004A0210810C0001FFFF16
+:1048200006108148000000020210800400001A8077
+:104830000610909000000024061092480000004AE4
+:10484000061094980000004A061096E80000004AFE
+:104850000210800000001080021080AC00000004F4
+:1048600002108038000000100210810000000000DB
+:10487000061081200000000202108008000002B52E
+:104880000210801000000000061082000000004AA4
+:10489000021081080001FFFF0610814000000002A5
+:1048A0000210800000001A80061090000000002412
+:1048B000061091200000004A061093700000004A84
+:1048C000061095C00000004A02108004000010800D
+:1048D000021080B0000000050210803C00000010B3
+:1048E0000210810400000000061081280000000270
+:1048F0000210800C000002B50210801400000000BD
+:10490000061084000000004A0210810C0001FFFF25
+:1049100006108148000000020210800400001A8086
+:104920000610909000000024061092480000004AF3
+:10493000061094980000004A061096E80000004A0D
+:104940000210800000001080021080AC0000000601
+:1049500002108038000000100210810000000000EA
+:10496000061081200000000202108008000002B53D
+:104970000210801000000000061082000000004AB3
+:10498000021081080001FFFF0610814000000002B4
+:104990000210800000001A80061090000000002421
+:1049A000061091200000004A061093700000004A93
+:1049B000061095C00000004A02108004000010801C
+:1049C000021080B0000000070210803C00000010C0
+:1049D000021081040000000006108128000000027F
+:1049E0000210800C000002B50210801400000000CC
+:1049F000061084000000004A0210810C0001FFFF35
+:104A000006108148000000020210800400001A8095
+:104A10000610909000000024061092480000004A02
+:104A2000061094980000004A061096E80000004A1C
+:104A3000021205B0000000010212049000E383405E
+:104A40000212051400003C100212066C0000000166
+:104A5000021206700000000002120494FFFFFFFF24
+:104A600002120498FFFFFFFF0212049CFFFFFFFFEA
+:104A7000021204A0FFFFFFFF021204A4FFFFFFFFCA
+:104A8000021204A8FFFFFFFF021204ACFFFFFFFFAA
+:104A9000021204B0FFFFFFFF021204BCFFFFFFFF82
+:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A
+:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A
+:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16
+:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2
+:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2
+:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2
+:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91
+:104B1000021204FCFFFFFFFF02120500FFFFFFFF70
+:104B200002120504FFFFFFFF02120508FFFFFFFF4F
+:104B30000212050CFFFFFFFF02120510FFFFFFFF2F
+:104B4000021204D4FF809000021204B4F00050005E
+:104B5000021204B8F00010000212039000000008D6
+:104B60000212039C00000008021203A000000008CB
+:104B7000021203A400000002021203BC00000004A1
+:104B8000021203C000000005021203C4000000046A
+:104B9000021203D0000000000212036C00000001AA
+:104BA000021203680000003F021201BC0000004036
+:104BB000021201C000001808021201C4000008031C
+:104BC000021201C800000803021201CC00000040DC
+:104BD000021201D000000003021201D400000803F9
+:104BE000021201D800000803021201DC00000803D1
+:104BF000021201E000010003021201E400000803B8
+:104C0000021201E800000803021201EC0000000398
+:104C1000021201F000000003021201F40000000380
+:104C2000021201F800000003021201FC0000000360
+:104C3000021202000000000302120204000000033E
+:104C400002120208000000030212020C000000031E
+:104C500002120210000000030212021400000003FE
+:104C600002120218000000030212021C00000003DE
+:104C700002120220000000030212022400000003BE
+:104C800002120228000024030212022C0000002F4E
+:104C90000212023000000009021202340000001962
+:104CA00002120238000001840212023C000001835B
+:104CB0000212024000000306021202440000001922
+:104CC00002120248000000060212024C0000030615
+:104CD00002120250000003060212025400000306F2
+:104CE0000212025800000C860212025C0000030649
+:104CF00002120260000003060212026400000006B5
+:104D000002120268000000060212026C0000000697
+:104D10000212027000000006021202740000000677
+:104D200002120278000000060212027C0000000657
+:104D30000212028000000006021202840000000637
+:104D400002120288000000060212028C0000000617
+:104D500002120290000000060212029400000006F7
+:104D600002120298000000060212029C00000006D7
+:104D7000021202A000000306021202A400000013A7
+:104D8000021202A800000006021202B00000100485
+:104D9000021202B400001004021203240010644046
+:104DA0000212032800106440021205B40000000142
+:104DB000021201B0000000010600A0000000000C7B
+:104DC0000200A050000000000200A05400000000FB
+:104DD0000200A0EC555400000200A0F055555555B6
+:104DE0000200A0F4000055550200A0F8F0000000F9
+:104DF0000200A0FC555400000200A1005555555575
+:104E00000200A104000055550200A108F0000000B6
+:104E10000200A18C555400000200A1905555555533
+:104E20000200A194000055550200A198F000000076
+:104E30000200A19C000000000200A1A000010000EF
+:104E40000200A1A4000050140200A1A8000000006C
+:104E50000200A45C00000C000200A61C000000037D
+:104E60000200A06CFF5C00000200A070FFF55FFF75
+:104E70000200A0740000FFFF0200A078F00003E031
+:104E80000200A07C000000000200A0800000A00042
+:104E90000600A084000000050200A0980FE00000BA
+:104EA0000600A09C000000070200A0B8000004005B
+:104EB0000600A0BC000000030200A0C80000100013
+:104EC0000600A0CC000000030200A0D800004000B3
+:104ED0000600A0DC000000030200A0E800010000C2
+:104EE0000600A22C000000040200A10CFF5C0000E0
+:104EF0000200A110FFF55FFF0200A1140000FFFFF8
+:104F00000200A118F00003E00200A11C0000000054
+:104F10000200A1200000A0000600A124000000055E
+:104F20000200A1380FE000000600A13C00000007CD
+:104F30000200A158000008000600A15C0000000368
+:104F40000200A168000020000600A16C0000000320
+:104F50000200A178000080000600A17C0000000390
+:104F60000200A188000200000600A23C000000042C
+:104F70000200A030000000000200A0340000000089
+:104F80000200A038000000000200A03C0000000069
+:104F90000200A040000000000200A0440000000049
+:104FA0000200A048000000000200A04C0000000029
+:104FB00000000000000000000000003000000000C1
+:104FC00000000000000000000000000000000000E1
+:104FD00000000000000000000000000000000000D1
+:104FE0000000000000300031000000000000000060
+:104FF00000000000000000000000000000000000B1
+:1050000000000000000000000000000000000000A0
+:10501000003100520000000000000000000000000D
+:105020000000000000000000000000000000000080
+:105030000000000000000000000000000052008995
+:1050400000000000000000000089008D008D00912C
+:1050500000910095009500990099009D009D00A188
+:1050600000A100A500A500A900A900AE00AE00B1F6
+:1050700000B100B4000000000000000000000000CB
+:105080000000000000000000000000000000000020
+:105090000000000000B40309030903130313031DF8
+:1050A000031D03240324032B032B03320332033990
+:1050B00003390340034003470347034E034E0355A0
+:1050C00000000000000000000000000000000000E0
+:1050D00000000000000000000000000000000000D0
+:1050E00000000000000000000000000000000000C0
+:1050F00000000000000000000000000000000000B0
+:10510000000000000000000000000000000000009F
+:10511000000000000000000000000000000000008F
+:10512000000000000000000000000000000000007F
+:10513000000000000000000000000000000000006F
+:10514000000000000000000000000000000000005F
+:10515000000000000000000000000000000000004F
+:10516000000000000000000000000000000000003F
+:105170000355035B0000000000000000035B035CBC
+:10518000035C035D035D035E035E035F035F036017
+:1051900003600361036103620362036300000000B4
+:1051A00000000000000000000000000000000000FF
+:1051B00000000000000000000000000000000000EF
+:1051C00000000000000000000363036D036D037B1B
+:1051D000037B0389000000000000000000000000C5
+:1051E00000000000000000000000000000000000BF
+:1051F00000000000000000000000000000000000AF
+:10520000000000000000000000000000000000009E
+:10521000000000000000000000000000000000008E
+:105220000389038A00000000000000000000000065
+:10523000000000000000000000000000000000006E
+:10524000000000000000000000000000038A03D6F8
+:10525000000000000000000000000000000000004E
+:10526000000000000000000000000000000000003E
+:10527000000000000000000003D604010000000050
+:10528000000000000000000000000000000000001E
+:10529000000000000000000000000000000000000E
+:1052A00000000000040104330000000000000000C2
+:1052B0000433043A043A0441044104480448044FC6
+:1052C000044F04560456045D045D04640464046BD6
+:1052D000046B04A4000000000000000004A404A863
+:1052E00004A804AC04AC04B004B004B404B404B81E
+:1052F00004B804BC04BC04C004C004C404C4051342
+:105300000513052A052A05410541054305430545C1
+:1053100005450547054705490549054B054B054D1D
+:10532000054D054F054F0551055105E805E805E90F
+:1053300005E905EA05EA05EF05EF05F405F405F9C9
+:1053400005F905FE05FE0603060306080608060D18
+:10535000060D0612061206130000000000000000F1
+:10536000000000000000000000000000000000003D
+:10537000000000000000000000000000000000002D
+:1053800006130624000000000000000000000000DA
+:10539000000000000000000000000000000000000D
+:1053A0000000000000000000000000000624063994
+:1053B0000639063C063C063F0000000000000000E5
+:1053C00000000000000000000000000000000000DD
+:1053D0000000000000000000063F0675000000000D
+:1053E00000000000000000000000000000000000BD
+:1053F00000000000000000000000000000000000AD
+:1054000000000000067507780000000000000000A2
+:10541000000000000000000000000000000000008C
+:10542000000000000000000000000000000000007C
+:105430000778077F077F078307830787000000003F
+:10544000000000000000000000000000000000005C
+:10545000000000000000000000000000078707C8EF
+:10546000000000000000000007C807D107D107DADC
+:1054700007DA07E307E307EC07EC07F507F507FE94
+:1054800007FE080708070810081008670867087C67
+:10549000087C089108910894089408970897089A3E
+:1054A000089A089D089D08A008A008A308A308A6BC
+:1054B00008A608A908A908B2000000000000000022
+:1054C00000000000000000000000000000000000DC
+:1054D00000000000000000000000000000000000CC
+:1054E00008B208B800000000000000000000000042
+:1054F00000000000000000000000000000000000AC
+:1055000000000000000000000000000008B808BB18
+:10551000000000000000000000000000000000008B
+:10552000000000000000000000000000000000007B
+:10553000000000000000000008BB08C100000000DF
+:10554000000000000000000000000000000000005B
+:10555000000000000000000000000000000000004B
+:10556000000000000000000000000000000000003B
+:1055700008C108D008D008DF08DF08EE08EE08FDF3
+:1055800008FD090C090C091B091B092A092A0939FC
+:10559000093909AA00000000000000000000000016
+:1055A00000000000000000000000000000000000FB
+:1055B00000000000000000000000000009AA09BF70
+:1055C00009BF09D009D009E109E109E209E209E3CB
+:1055D00009E309E409E409E509E509E609E609E75B
+:1055E00009E709E809E809E90000000000000000F7
+:1055F00000000000000000000000000000000000AB
+:10560000000000000000000000000000000000009A
+:10561000000000000000000000000000000000008A
+:10562000000000000000000000000000000000007A
+:10563000000000000000000000000000000000006A
+:10564000000000000000000000000000000000005A
+:10565000000000000000000000000000000000004A
+:10566000000000000000000000000000000000003A
+:10567000000000000000000000000000000000002A
+:10568000000000000000000000000000000000001A
+:10569000000000000000000000000000000000000A
+:1056A00000000000000000000000000000000000FA
+:1056B00000000000000000000000000000000000EA
+:1056C000000000000000000000010000000204C013
+:1056D0000003098000040E4000051300000617C0F7
+:1056E00000071C800008214000092600000A2AC08B
+:1056F000000B2F80000C3440000D3900000E3DC01F
+:10570000000F42800010474000114C00001250C0B2
+:105710000013558000145A4000155F00001663C046
+:105720000017688000186D4000197200001A76C0DA
+:10573000001B7B80001C8040001D8500001E89C06E
+:10574000001F8E80000093400000200000004000F9
+:1057500000006000000080000000A0000000C00009
+:105760000000E000000100000001200000014000F6
+:1057700000016000000180000001A0000001C000E5
+:105780000001E000000200000002200000024000D2
+:1057900000026000000280000002A0000002C000C1
+:1057A0000002E000000300000003200000034000AE
+:1057B00000036000000380000003A0000003C0009D
+:1057C0000003E0000004000000042000000440008A
+:1057D00000046000000480000004A0000004C00079
+:1057E0000004E00000050000000520000005400066
+:1057F00000056000000580000005A0000005C00055
+:105800000005E00000060000000620000006400041
+:1058100000066000000680000006A0000006C00030
+:105820000006E0000007000000072000000740001D
+:1058300000076000000780000007A0000007C0000C
+:105840000007E000000800000008200000084000F9
+:1058500000086000000880000008A0000008C000E8
+:105860000008E000000900000009200000094000D5
+:1058700000096000000980000009A0000009C000C4
+:105880000009E000000A0000000A2000000A4000B1
+:10589000000A6000000A8000000AA000000AC000A0
+:1058A000000AE000000B0000000B2000000B40008D
+:1058B000000B6000000B8000000BA000000BC0007C
+:1058C000000BE000000C0000000C2000000C400069
+:1058D000000C6000000C8000000CA000000CC00058
+:1058E000000CE000000D0000000D2000000D400045
+:1058F000000D6000000D8000000DA000000DC00034
+:10590000000DE000000E0000000E2000000E400020
+:10591000000E6000000E8000000EA000000EC0000F
+:10592000000EE000000F0000000F2000000F4000FC
+:10593000000F6000000F8000000FA000000FC000EB
+:10594000000FE000001000000010200000104000D8
+:1059500000106000001080000010A0000010C000C7
+:105960000010E000001100000011200000114000B4
+:1059700000116000001180000011A0000011C000A3
+:105980000011E00000120000001220000012400090
+:1059900000126000001280000012A0000012C0007F
+:1059A0000012E0000013000000132000001340006C
+:1059B00000136000001380000013A0000013C0005B
+:1059C0000013E00000140000001420000014400048
+:1059D00000146000001480000014A0000014C00037
+:1059E0000014E00000150000001520000015400024
+:1059F00000156000001580000015A0000015C00013
+:105A00000015E000001600000016200000164000FF
+:105A100000166000001680000016A0000016C000EE
+:105A20000016E000001700000017200000174000DB
+:105A300000176000001780000017A0000017C000CA
+:105A40000017E000001800000018200000184000B7
+:105A500000186000001880000018A0000018C000A6
+:105A60000018E00000190000001920000019400093
+:105A700000196000001980000019A0000019C00082
+:105A80000019E000001A0000001A2000001A40006F
+:105A9000001A6000001A8000001AA000001AC0005E
+:105AA000001AE000001B0000001B2000001B40004B
+:105AB000001B6000001B8000001BA000001BC0003A
+:105AC000001BE000001C0000001C2000001C400027
+:105AD000001C6000001C8000001CA000001CC00016
+:105AE000001CE000001D0000001D2000001D400003
+:105AF000001D6000001D8000001DA000001DC000F2
+:105B0000001DE000001E0000001E2000001E4000DE
+:105B1000001E6000001E8000001EA000001EC000CD
+:105B2000001EE000001F0000001F2000001F4000BA
+:105B3000001F6000001F8000001FA000001FC000A9
+:105B4000001FE00000200000002020000020400096
+:105B500000206000002080000020A0000020C00085
+:105B60000020E00000210000002120000021400072
+:105B700000216000002180000021A0000021C00061
+:105B80000021E0000022000000222000002240004E
+:105B900000226000002280000022A0000022C0003D
+:105BA0000022E0000023000000232000002340002A
+:105BB00000236000002380000023A0000023C00019
+:105BC0000023E00000240000002420000024400006
+:105BD00000246000002480000024A0000024C000F5
+:105BE0000024E000002500000025200000254000E2
+:105BF00000256000002580000025A0000025C000D1
+:105C00000025E000002600000026200000264000BD
+:105C100000266000002680000026A0000026C000AC
+:105C20000026E00000270000002720000027400099
+:105C300000276000002780000027A0000027C00088
+:105C40000027E00000280000002820000028400075
+:105C500000286000002880000028A0000028C00064
+:105C60000028E00000290000002920000029400051
+:105C700000296000002980000029A0000029C00040
+:105C80000029E000002A0000002A2000002A40002D
+:105C9000002A6000002A8000002AA000002AC0001C
+:105CA000002AE000002B0000002B2000002B400009
+:105CB000002B6000002B8000002BA000002BC000F8
+:105CC000002BE000002C0000002C2000002C4000E5
+:105CD000002C6000002C8000002CA000002CC000D4
+:105CE000002CE000002D0000002D2000002D4000C1
+:105CF000002D6000002D8000002DA000002DC000B0
+:105D0000002DE000002E0000002E2000002E40009C
+:105D1000002E6000002E8000002EA000002EC0008B
+:105D2000002EE000002F0000002F2000002F400078
+:105D3000002F6000002F8000002FA000002FC00067
+:105D4000002FE00000300000003020000030400054
+:105D500000306000003080000030A0000030C00043
+:105D60000030E00000310000003120000031400030
+:105D700000316000003180000031A0000031C0001F
+:105D80000031E0000032000000322000003240000C
+:105D900000326000003280000032A0000032C000FB
+:105DA0000032E000003300000033200000334000E8
+:105DB00000336000003380000033A0000033C000D7
+:105DC0000033E000003400000034200000344000C4
+:105DD00000346000003480000034A0000034C000B3
+:105DE0000034E000003500000035200000354000A0
+:105DF00000356000003580000035A0000035C0008F
+:105E00000035E0000036000000362000003640007B
+:105E100000366000003680000036A0000036C0006A
+:105E20000036E00000370000003720000037400057
+:105E300000376000003780000037A0000037C00046
+:105E40000037E00000380000003820000038400033
+:105E500000386000003880000038A0000038C00022
+:105E60000038E0000039000000392000003940000F
+:105E700000396000003980000039A0000039C000FE
+:105E80000039E000003A0000003A2000003A4000EB
+:105E9000003A6000003A8000003AA000003AC000DA
+:105EA000003AE000003B0000003B2000003B4000C7
+:105EB000003B6000003B8000003BA000003BC000B6
+:105EC000003BE000003C0000003C2000003C4000A3
+:105ED000003C6000003C8000003CA000003CC00092
+:105EE000003CE000003D0000003D2000003D40007F
+:105EF000003D6000003D8000003DA000003DC0006E
+:105F0000003DE000003E0000003E2000003E40005A
+:105F1000003E6000003E8000003EA000003EC00049
+:105F2000003EE000003F0000003F2000003F400036
+:105F3000003F6000003F8000003FA000003FC00025
+:105F4000003FE000003FE00100000000000001FF12
+:105F50000000020000007FF800007FF80000014010
+:105F600000003500000000010000FF0000000000FC
+:105F70000000FF00000000000000FF000000000023
+:105F80000000FF00000000000000FF000000000013
+:105F90000000FF00000000000000FF000000000003
+:105FA0000000FF000000000000000000140AFF00D5
+:105FB00000000001000000000020100100000000AF
+:105FC0000100900000000100000090020000900419
+:105FD00000009006000090080000900A0000900C5D
+:105FE0000000900E0000901000009012000090142D
+:105FF00000009016000090180000901A0000901CFD
+:106000000000901E000090200000902200009024CC
+:1060100000009026000090280000902A0000902C9C
+:106020000000902E0000903000009032000090346C
+:1060300000009036000090380000903A0000903C3C
+:106040000000903E0000904000009042000090440C
+:1060500000009046000090480000904A0000904CDC
+:106060000000904E000090500000905200009054AC
+:1060700000009056000090580000905A0000905C7C
+:106080000000905E0000906000009062000090644C
+:1060900000009066000090680000906A0000906C1C
+:1060A0000000906E000090700000907200009074EC
+:1060B00000009076000090780000907A0000907CBC
+:1060C0000000907E0000908000009082000090848C
+:1060D00000009086000090880000908A0000908C5C
+:1060E0000000908E0000909000009092000090942C
+:1060F00000009096000090980000909A0000909CFC
+:106100000000909E000090A0000090A2000090A4CB
+:10611000000090A6000090A8000090AA000090AC9B
+:10612000000090AE000090B0000090B2000090B46B
+:10613000000090B6000090B8000090BA000090BC3B
+:10614000000090BE000090C0000090C2000090C40B
+:10615000000090C6000090C8000090CA000090CCDB
+:10616000000090CE000090D0000090D2000090D4AB
+:10617000000090D6000090D8000090DA000090DC7B
+:10618000000090DE000090E0000090E2000090E44B
+:10619000000090E6000090E8000090EA000090EC1B
+:1061A000000090EE000090F0000090F2000090F4EB
+:1061B000000090F6000090F8000090FA000090FCBB
+:1061C000000090FE00009100000091020000910488
+:1061D00000009106000091080000910A0000910C57
+:1061E0000000910E00009110000091120000911427
+:1061F00000009116000091180000911A0000911CF7
+:106200000000911E000091200000912200009124C6
+:1062100000009126000091280000912A0000912C96
+:106220000000912E00009130000091320000913466
+:1062300000009136000091380000913A0000913C36
+:106240000000913E00009140000091420000914406
+:1062500000009146000091480000914A0000914CD6
+:106260000000914E000091500000915200009154A6
+:1062700000009156000091580000915A0000915C76
+:106280000000915E00009160000091620000916446
+:1062900000009166000091680000916A0000916C16
+:1062A0000000916E000091700000917200009174E6
+:1062B00000009176000091780000917A0000917CB6
+:1062C0000000917E00009180000091820000918486
+:1062D00000009186000091880000918A0000918C56
+:1062E0000000918E00009190000091920000919426
+:1062F00000009196000091980000919A0000919CF6
+:106300000000919E000091A0000091A2000091A4C5
+:10631000000091A6000091A8000091AA000091AC95
+:10632000000091AE000091B0000091B2000091B465
+:10633000000091B6000091B8000091BA000091BC35
+:10634000000091BE000091C0000091C2000091C405
+:10635000000091C6000091C8000091CA000091CCD5
+:10636000000091CE000091D0000091D2000091D4A5
+:10637000000091D6000091D8000091DA000091DC75
+:10638000000091DE000091E0000091E2000091E445
+:10639000000091E6000091E8000091EA000091EC15
+:1063A000000091EE000091F0000091F2000091F4E5
+:1063B000000091F6000091F8000091FA000091FCB5
+:1063C000000091FEFFFFFFFFFFFFFFFFFFFFFFFF4A
+:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10644000FFFFFFFF0000000300BEBC2000000000B3
+:10645000000000050000000300BEBC20000000009A
+:10646000000000050000000300BEBC20000000008A
+:10647000000000050000000300BEBC20000000007A
+:10648000000000050000000300BEBC20000000006A
+:10649000000000050000000300BEBC20000000005A
+:1064A000000000050000000300BEBC20000000004A
+:1064B000000000050000000300BEBC20000000003A
+:1064C0000000000500002000000040C000006180C6
+:1064D000000082400000A3000000C3C00000E48070
+:1064E0000001054000012600000146C00001678050
+:1064F000000188400001A9000001C9C00001EA8034
+:1065000000020B4000022C0000024CC000026D8013
+:1065100000028E400002AF000002CFC00002F080F7
+:10652000000011400000800000010380000187008E
+:1065300000020A8000028E00000311800003950013
+:106540000004188000049C0000051F800005A300C3
+:10655000000626800006AA0000072D800007B10073
+:10656000000834800008B80000093B800009BF0023
+:10657000000A4280000AC600000B4980000BCD00D3
+:10658000000C5080000CD400000D578000005B0010
+:1065900000007FF800007FF8000000D50000150023
+:1065A0000000FF00000000000000FF0000000000ED
+:1065B0000000FF00000000000000FF0000000000DD
+:1065C0000000FF00000000000000FF0000000000CD
+:1065D0000000FF00000000000000FF0000000000BD
+:1065E000000019000000000000000000FFFFFFFF96
+:1065F0000000000003938700000000000393870061
+:1066000000007FF800007FF80000068E00003500D3
+:106610000000FF000FFFFFFF0000FF000FFFFFFF64
+:10662000000000FF0000FF000FFFFFFF0000FF0061
+:106630000FFFFFFF000000FF0000FF000FFFFFFF44
+:106640000000FF000FFFFFFF000000FF0000FF0041
+:106650000FFFFFFF0000FF000FFFFFFF000000FF24
+:106660000000FF000FFFFFFF0000FF000FFFFFFF14
+:10667000000000FF0000FF000FFFFFFF0000FF0011
+:106680000FFFFFFF000000FF0000FF000FFFFFFFF4
+:106690000000FF000FFFFFFF000000FF0000FF00F1
+:1066A0000FFFFFFF0000FF000FFFFFFF000000FFD4
+:1066B0000000FF000FFFFFFF0000FF000FFFFFFFC4
+:1066C000000000FF0000FF000FFFFFFF0000FF00C1
+:1066D0000FFFFFFF000000FF0000FF000FFFFFFFA4
+:1066E0000000FF000FFFFFFF000000FF0000FF00A1
+:1066F0000FFFFFFF0000FF000FFFFFFF000000FF84
+:106700000000FF000FFFFFFF0000FF000FFFFFFF73
+:10671000000000FF0000FF000FFFFFFF0000FF0070
+:106720000FFFFFFF000000FF0000FF000FFFFFFF53
+:106730000000FF000FFFFFFF000000FF0000FF0050
+:106740000FFFFFFF0000FF000FFFFFFF000000FF33
+:106750000000FF000FFFFFFF0000FF000FFFFFFF23
+:10676000000000FF0000FF000FFFFFFF0000FF0020
+:106770000FFFFFFF000000FF0000FF000FFFFFFF03
+:106780000000FF000FFFFFFF000000FF0000FF0000
+:106790000FFFFFFF0000FF000FFFFFFF000000FFE3
+:1067A0000000FF000FFFFFFF0000FF000FFFFFFFD3
+:1067B000000000FF0000FF000FFFFFFF0000FF00D0
+:1067C0000FFFFFFF000000FF0000FF000FFFFFFFB3
+:1067D0000000FF000FFFFFFF000000FF0000FF00B0
+:1067E0000FFFFFFF0000FF000FFFFFFF000000FF93
+:1067F0000000FF000FFFFFFF0000FF000FFFFFFF83
+:10680000000000FF0000FF000FFFFFFF0000FF007F
+:106810000FFFFFFF000000FF0000FF000FFFFFFF62
+:106820000000FF000FFFFFFF000000FF0000FF005F
+:106830000FFFFFFF0000FF000FFFFFFF000000FF42
+:106840000000FF000FFFFFFF0000FF000FFFFFFF32
+:10685000000000FF0000FF000FFFFFFF0000FF002F
+:106860000FFFFFFF000000FF0000FF000FFFFFFF12
+:106870000000FF000FFFFFFF000000FF0000FF000F
+:106880000FFFFFFF0000FF000FFFFFFF000000FFF2
+:10689000000000FF000000FF000000FF000000FFFC
+:1068A000000000FF000000FF000000FF000000FFEC
+:1068B0000000FF00000000000000FF0000000000DA
+:1068C0000000FF00000000000000FF0000000000CA
+:1068D0000000FF00000000000000FF0000000000BA
+:1068E0000000FF00000000000000FF0000000000AA
+:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:106970000000100000002080000031000000418075
+:10698000000052000000628000007300000083805D
+:10699000000094000000A4800000B5000000C58045
+:1069A0000000D6000000E6800000F700000107802C
+:1069B0000001180000012880000139000001498011
+:1069C00000015A0000016A8000017B0000018B80F9
+:1069D00000019C000001AC800001BD000001CD80E1
+:1069E0000001DE000001EE800001FF0000000F80CA
+:1069F00000007FF800007FF800000344000035002D
+:106A000010000000000028AD00010001000902068E
+:106A1000CCCCCCC5FFFFFFFFFFFFFFFF7058103C41
+:106A20000000FF00000000000000FF000000000068
+:106A30000000FF00000000000000FF000000000058
+:106A40000000FF00000000000000FF000000000048
+:106A50000000FF00000000000000FF000000000038
+:106A60000000000000000001CCCC0201CCCCCCCC5A
+:106A7000CCCC0201CCCCCCCCCCCC0201CCCCCCCC80
+:106A8000CCCC0201CCCCCCCCCCCC0201CCCCCCCC70
+:106A9000CCCC0201CCCCCCCCCCCC0201CCCCCCCC60
+:106AA000CCCC0201CCCCCCCC00000000FFFFFFFF1F
+:106AB000000E0000011600D6002625A0002625A005
+:106AC000002625A0002625A000720000012300F367
+:106AD000002625A0002625A0002625A0002625A00A
+:106AE0000000FFFF000000000000FFFF00000000AA
+:106AF0000000FFFF000000000000FFFF000000009A
+:106B00000000FFFF000000000000FFFF0000000089
+:106B10000000FFFF000000000000FFFF0000000079
+:106B20000000FFFF000000000000FFFF0000000069
+:106B30000000FFFF000000000000FFFF0000000059
+:106B40000000FFFF000000000000FFFF0000000049
+:106B50000000FFFF000000000000FFFF0000000039
+:106B60000000FFFF000000000000FFFF0000000029
+:106B70000000FFFF000000000000FFFF0000000019
+:106B80000000FFFF000000000000FFFF0000000009
+:106B90000000FFFF000000000000FFFF00000000F9
+:106BA0000000FFFF000000000000FFFF00000000E9
+:106BB0000000FFFF000000000000FFFF00000000D9
+:106BC0000000FFFF000000000000FFFF00000000C9
+:106BD0000000FFFF000000000000FFFF00000000B9
+:106BE0000000FFFF000000000000FFFF00000000A9
+:106BF0000000FFFF000000000000FFFF0000000099
+:106C00000000FFFF000000000000FFFF0000000088
+:106C10000000FFFF000000000000FFFF0000000078
+:106C20000000FFFF000000000000FFFF0000000068
+:106C30000000FFFF000000000000FFFF0000000058
+:106C40000000FFFF000000000000FFFF0000000048
+:106C50000000FFFF000000000000FFFF0000000038
+:106C60000000FFFF000000000000FFFF0000000028
+:106C70000000FFFF000000000000FFFF0000000018
+:106C80000000FFFF000000000000FFFF0000000008
+:106C90000000FFFF000000000000FFFF00000000F8
+:106CA0000000FFFF000000000000FFFF00000000E8
+:106CB0000000FFFF000000000000FFFF00000000D8
+:106CC0000000FFFF000000000000FFFF00000000C8
+:106CD0000000FFFF000000000000FFFF00000000B8
+:106CE000FFFFFFF3318FFFFF0C30C30CC30C30C329
+:106CF000CF3CF300F3CF3CF30000CF3CCDCDCDCD66
+:106D0000FFFFFFF130EFFFFF0C30C30CC30C30C3AB
+:106D1000CF3CF300F3CF3CF30001CF3CCDCDCDCD44
+:106D2000FFFFFFF6305FFFFF0C30C30CC30C30C316
+:106D3000CF3CF300F3CF3CF30002CF3CCDCDCDCD23
+:106D4000FFFFF4061CBFFFFF0C30C305C30C30C3AC
+:106D5000CF300014F3CF3CF30004CF3CCDCDCDCDEC
+:106D6000FFFFFFF2304FFFFF0C30C30CC30C30C3EA
+:106D7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDD
+:106D8000FFFFFFFA302FFFFF0C30C30CC30C30C3E2
+:106D9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB5
+:106DA000FFFFFFF731EFFFFF0C30C30CC30C30C304
+:106DB000CF3CF300F3CF3CF30020CF3CCDCDCDCD85
+:106DC000FFFFFFF5302FFFFF0C30C30CC30C30C3A7
+:106DD000CF3CF300F3CF3CF30040CF3CCDCDCDCD45
+:106DE000FFFFFFF3318FFFFF0C30C30CC30C30C328
+:106DF000CF3CF300F3CF3CF30000CF3CCDCDCDCD65
+:106E0000FFFFFFF1310FFFFF0C30C30CC30C30C389
+:106E1000CF3CF300F3CF3CF30001CF3CCDCDCDCD43
+:106E2000FFFFFFF6305FFFFF0C30C30CC30C30C315
+:106E3000CF3CF300F3CF3CF30002CF3CCDCDCDCD22
+:106E4000FFFFF4061CBFFFFF0C30C305C30C30C3AB
+:106E5000CF300014F3CF3CF30004CF3CCDCDCDCDEB
+:106E6000FFFFFFF2304FFFFF0C30C30CC30C30C3E9
+:106E7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDC
+:106E8000FFFFFFFA302FFFFF0C30C30CC30C30C3E1
+:106E9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB4
+:106EA000FFFFFFF730EFFFFF0C30C30CC30C30C304
+:106EB000CF3CF300F3CF3CF30020CF3CCDCDCDCD84
+:106EC000FFFFFFF5304FFFFF0C30C30CC30C30C386
+:106ED000CF3CF300F3CF3CF30040CF3CCDCDCDCD44
+:106EE000FFFFFFFF30CFFFFF0C30C30CC30C30C3DC
+:106EF000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD98
+:106F0000FFFFFFFF30CFFFFF0C30C30CC30C30C3BB
+:106F1000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD76
+:106F2000FFFFFFFF30CFFFFF0C30C30CC30C30C39B
+:106F3000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD55
+:106F4000FFFFFFFF30CFFFFF0C30C30CC30C30C37B
+:106F5000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD33
+:106F6000FFFFFFFF30CFFFFF0C30C30CC30C30C35B
+:106F7000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0F
+:106F8000FFFFFFFF30CFFFFF0C30C30CC30C30C33B
+:106F9000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE7
+:106FA000FFFFFFFF30CFFFFF0C30C30CC30C30C31B
+:106FB000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB7
+:106FC000FFFFFFFF30CFFFFF0C30C30CC30C30C3FB
+:106FD000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD77
+:106FE000FFFFFFF3320FFFFF0C30C30CC30C30C3A5
+:106FF000CF3CF300F3CF3CF30000CF3CCDCDCDCD63
+:10700000FFFFFFF1310FFFFF0C30C30CC30C30C387
+:10701000CF3CF300F3CF3CF30001CF3CCDCDCDCD41
+:10702000FFFFFFF6305FFFFF0C30C30CC30C30C313
+:10703000CF3CF300F3CF3CF30002CF3CCDCDCDCD20
+:10704000FFFFF4061CBFFFFF0C30C305C30C30C3A9
+:10705000CF300014F3CF3CF30004CF3CCDCDCDCDE9
+:10706000FFFFFFF2304FFFFF0C30C30CC30C30C3E7
+:10707000CF3CF300F3CF3CF30008CF3CCDCDCDCDDA
+:10708000FFFFFF8A042FFFFF0C30C30CC30C30C37B
+:10709000CF3CC000F3CF3CF30010CF3CCDCDCDCDE5
+:1070A000FFFFFF9705CFFFFF0C30C30CC30C30C3AD
+:1070B000CF3CC000F3CF3CF30020CF3CCDCDCDCDB5
+:1070C000FFFFFFF5310FFFFF0C30C30CC30C30C3C3
+:1070D000CF3CF300F3CF3CF30040CF3CCDCDCDCD42
+:1070E000FFFFFFF3320FFFFF0C30C30CC30C30C3A4
+:1070F000CF3CF300F3CF3CF30000CF3CCDCDCDCD62
+:10710000FFFFFFF1302FFFFF0C30C30CC30C30C367
+:10711000CF3CF300F3CF3CF30001CF3CCDCDCDCD40
+:10712000FFFFFFF6305FFFFF0C30C30CC30C30C312
+:10713000CF3CF300F3CF3CF30002CF3CCDCDCDCD1F
+:10714000FFFFFF061CBFFFFF0C30C30CC30C30C396
+:10715000CF3CC014F3CF3CF30004CF3CCDCDCDCD1C
+:10716000FFFFFFF2304FFFFF0C30C30CC30C30C3E6
+:10717000CF3CF300F3CF3CF30008CF3CCDCDCDCDD9
+:10718000FFFFFFFA302FFFFF0C30C30CC30C30C3DE
+:10719000CF3CF300F3CF3CF30010CF3CCDCDCDCDB1
+:1071A000FFFFFFF731CFFFFF0C30C30CC30C30C320
+:1071B000CF3CF300F3CF3CF30020CF3CCDCDCDCD81
+:1071C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F9
+:1071D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD75
+:1071E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D9
+:1071F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD95
+:10720000FFFFFFFF30CFFFFF0C30C30CC30C30C3B8
+:10721000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD73
+:10722000FFFFFFFF30CFFFFF0C30C30CC30C30C398
+:10723000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD52
+:10724000FFFFFFFF30CFFFFF0C30C30CC30C30C378
+:10725000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD30
+:10726000FFFFFFFF30CFFFFF0C30C30CC30C30C358
+:10727000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0C
+:10728000FFFFFFFF30CFFFFF0C30C30CC30C30C338
+:10729000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE4
+:1072A000FFFFFFFF30CFFFFF0C30C30CC30C30C318
+:1072B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB4
+:1072C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F8
+:1072D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD74
+:1072E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D8
+:1072F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD94
+:10730000FFFFFFFF30CFFFFF0C30C30CC30C30C3B7
+:10731000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD72
+:10732000FFFFFFFF30CFFFFF0C30C30CC30C30C397
+:10733000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD51
+:10734000FFFFFFFF30CFFFFF0C30C30CC30C30C377
+:10735000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2F
+:10736000FFFFFFFF30CFFFFF0C30C30CC30C30C357
+:10737000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0B
+:10738000FFFFFFFF30CFFFFF0C30C30CC30C30C337
+:10739000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE3
+:1073A000FFFFFFFF30CFFFFF0C30C30CC30C30C317
+:1073B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB3
+:1073C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F7
+:1073D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD73
+:1073E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D7
+:1073F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD93
+:10740000FFFFFFFF30CFFFFF0C30C30CC30C30C3B6
+:10741000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD71
+:10742000FFFFFFFF30CFFFFF0C30C30CC30C30C396
+:10743000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD50
+:10744000FFFFFFFF30CFFFFF0C30C30CC30C30C376
+:10745000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2E
+:10746000FFFFFFFF30CFFFFF0C30C30CC30C30C356
+:10747000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0A
+:10748000FFFFFFFF30CFFFFF0C30C30CC30C30C336
+:10749000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE2
+:1074A000FFFFFFFF30CFFFFF0C30C30CC30C30C316
+:1074B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB2
+:1074C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F6
+:1074D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD72
+:1074E000000C0000000700C000028130000B815832
+:1074F0000002021000010230000F024000010330C0
+:10750000000C0000000800C000028140000B8168F0
+:10751000000202200001024000070250000202C0E7
+:10752000001000000008010000028180000B81A80B
+:107530000002026000018280000E82980008038031
+:107540000010000000010100000281100009013854
+:10755000000201C8000101E8000E01F8000002D895
+:10756000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC5B
+:1075700000002000CCCCCCCCCCCCCCCCCCCCCCCC5B
+:10758000CCCCCCCC00002000CCCCCCCCCCCCCCCC4B
+:10759000CCCCCCCCCCCCCCCC040020000000000067
+:1075A0001F8B080000000000000BFB51CFC0F00350
+:1075B0008AB7B13130ECE644F0E98159181818F86F
+:1075C00099C8D7BF1168C04E20BE01C4075948D71B
+:1075D0007F551AC15E26C9C0700A8827883330B427
+:1075E0004A21C4ED651818EE01F92BA16272403DE5
+:1075F00073A4C977F3281E3CB8D014951F620CA160
+:107600005F9840E82234F950A8BCB81E842E36C5D5
+:107610006EAE841E71F6A7A9A0F2BD55F0ABCFD512
+:1076200040E5C7A2A90F81F2017EE9B234D8030078
+:1076300000000000000000001F8B08000000000098
+:10764000000BED7D0B7455D5B5E8DA9FB3CFFF6421
+:10765000278470123EEEC400C1063C4280A0A83BC5
+:10766000FC1A7DD41E1025E5A11C446B004922A6FE
+:10767000D78C96D76CC8870450E3E751BD457BA0F3
+:10768000D88B0E5BA3A68ABDB43D887AA9C3DB2242
+:107690005AA52D7A83FA2C58A0B1572ABD4FCB5B3F
+:1076A00073AEB592BD77CEC9C74F47EF788D43769D
+:1076B000D6DEEB3BFF6BCEB95634D94FF22E27E422
+:1076C0001CFCD0A7291142A6F73DC92D5932C92368
+:1076D000E41B3E823F1FF923534816210D3EF6BCA2
+:1076E0003D10D905CF2D8D84A426C2F771491221F2
+:1076F000244848899A0B2D02B1870BE15977617CA8
+:10770000323E67C23387C8848C84F218FDBD20EBFB
+:10771000FB9C42FF399AA880F114F68AA8A43C96F3
+:10772000C2F6DF226446DF3C48DD57F578B86FDEED
+:10773000EEA7A26B24C5EB9E837F94E5598950E6A2
+:10774000FA0D47A5C79FB7D51F4FC2B9382F95A8C7
+:10775000382FDE9E108BD8E7E7EEE7A346F2F8F36A
+:10776000E3FBC32DD3B8026E6D8D3E7CB636EA24A2
+:10777000E5258436333B4BE93344CC5DA5FDDBCDB9
+:107780002312871F9F0F8C63D0FAF47F42E1DE9CA7
+:107790004B9241C0214938E0D61C5AEC33D3F42730
+:1077A0009E2497C2AD84CFB9A8FF7AFD302F0A0777
+:1077B0003FCC2B0D3C97C2BCA6F79F97BFD83DAFDF
+:1077C0006A6287CF70E7159844C821C0876A128221
+:1077D00078B9CDD19FAC9B56779AFE08A70BD5E020
+:1077E000EB1B229E822572DFF8000723E0A02F6F9B
+:1077F00034C7496F6EBA067820BE3A387CE20AE395
+:1078000007AB0F8FF4199A1D93803568F110E02DA6
+:107810009F30F8E557B7DE2A4F2194D53A0F4EA096
+:10782000F0CBEF5EB99040F9E8152780DF9ACBA640
+:1078300056CEA5F5B2CB63AF2CA04D423143027AB0
+:10784000DD0A9D15407F5FB32A68B909FAA365CBAD
+:10785000BACAB4106EA6036E1472864ACB1EF8B56F
+:10786000280DFC482F1EA473DEFEED33C1CF436C00
+:10787000F8437E5EEFA0CB8C78BF91E1CBA2FF01F5
+:10788000BE46101B5FD37EB22B35075EB25CE33C75
+:107890000ABF20BC6FFD9B8C97439EF41994CE3D8C
+:1078A000A5B29EA478CA26B16CB58CE263A14A4009
+:1078B0008EE5E4EA1290C360786926A412F89F4A24
+:1078C00007B2C826E77ECEF9AB60CDEE9DAD749CC5
+:1078D00033B34331A895AFD3B94EEDBF9E3B40BE05
+:1078E000786DE5B2E74802C7EB3C5844E76595C9B7
+:1078F000B18729DD6C2D3DACDBE5E3B15EF9E2A695
+:107900000F62A833B83CA0F0514A65D31FF9ECF4DC
+:10791000A17C4AFA08DFE8C4C770F1757A98F4F1DF
+:1079200059C71378EDCF571B055E7D847EDF52B2B9
+:1079300078407DD51FAF4F92046D172A2566324DD2
+:10794000BBFFB4EB0BF7D326DFDD72541935A36A06
+:10795000E74078CB75AE57F4EB6F508C7747D0A2E9
+:10796000AAA37CD5B81E688FDE63114A776740F6FC
+:107970005078281D17A5A04C8A49EC61D64D4AA223
+:10798000657FD44C6E413A48225EC4FCBC86EC90C4
+:10799000B36AAE530E932A4BB2CFDFDFA0E13C3483
+:1079A000182F17EC02DA2105851A2229A05B41AFB6
+:1079B000A092CE9D0F65A79DD1664C25E9F0A072DF
+:1079C000BC4B92A0D76F0D4DBEB8C75BE29CEF9049
+:1079D000DB8554E33DD1268D9CEE6BA792F7047EA8
+:1079E00028102F13761DC7D3660FD92B5D48E5C12C
+:1079F000986BC152209BE1D32C6A87C0932A9FCDFC
+:107A000063A6EA4057648FA4C23C71488A4742F596
+:107A10001DD40B4A06F623FBEA90FE9490894FF1A1
+:107A20003DF3BCD8F8BD655FA206F0531DD58C2D83
+:107A3000748E6B15D3D80874318DC9A7EAE88479A0
+:107A4000A0EF3C129BD7B7A57C5C879AD39687762C
+:107A50005906FBAE5AA52A7F2A7CDF3661207E229A
+:107A6000494F4FB70D9E6E7BF06689DA835FA2BFE8
+:107A7000CC2433018E7F8A2DCE4A0D80AFF71B0FA9
+:107A8000EAEAF83E7BD0FD7DAD42EAD2C98156C913
+:107A9000C7F8D26769601F8875AF0576A720DD1625
+:107AA000DBC4D69B9B8BF05DBBE717BA6AE3BFB51F
+:107AB00054CD78A7F65F8F80B7E8A7B77DF2A0A373
+:107AC000BDBB5D6F7F425E507B18E85CD041504A81
+:107AD0006C95E87B6F6CB105EA6CED63150CFF19D2
+:107AE000E6DF8BAF4F397FD16E30BAFAD3EEA656B0
+:107AF000D04FEF691D575D4CE9E8F74F28B14DF4C1
+:107B00006BF58E89F3C05E7A8FD3B7C0D389DD4D14
+:107B100079E9E823139E7E21F9711C415FD5F2F2C9
+:107B200001E96130FA7ACA4D5F9D577F21F475C82B
+:107B30004D5F1C1E273BD9FAC9FD23185E38BEDCF9
+:107B4000F8C988974FDBAE3F3DFD5AA27CEDEDBCF6
+:107B50003A3D3DF1F90A7C7DD6F90E4647798669B2
+:107B6000EA74FC51D48E91407F9491588ACE53A7E9
+:107B70000FD45B31A6B7845C12ED4F4BCC4E53C98A
+:107B80006BD85E21294B477BDB6967CC57E84BDA22
+:107B90004F7309497A715F64FA504F95A884E93FA1
+:107BA00033943F03EC08FEA3CC8EC1BAB3C0FE07EA
+:107BB000FD359BEB5F89DA5B747DA132E7BE37E070
+:107BC000B23F14BE5FE8676F0D737FEC97F9FE3824
+:107BD0004842A88FC4FE38037FF6EE8B395C476AB3
+:107BE000C494E9BAB5839EE42609B41B41FD4C8ECA
+:107BF0004A49E62F20256037AF970A62A00FE83E7A
+:107C0000AF278B7E7FEF070AEA878668DD8A1658E2
+:107C1000F6B50D13BBE9B8F7349269C59EBEF1EE17
+:107C2000513B7C00EFF6E2F50EBBF6BB52A250B61C
+:107C3000E91D7F549B563C0D8653DFEEA6F090293C
+:107C40002081FF02A1FBA22F18003FF6BE174EF6BF
+:107C5000B2D2BF9C0B364F011653B02F6DA7B63B67
+:107C6000B9188AA3A50A4A07ED1EFEDDFA4D05ECF8
+:107C700077DBFDACBC63D3AC8D169447F2FA561596
+:107C8000FB9ECFCAB76DFA4105EC0BDAB2E99AA9AF
+:107C9000BE6EF324ABE269F8FB365976D85F4DC669
+:107CA00082F2FF43D7E1F79917BD40E1498112B352
+:107CB0000CD26B97150ABF41C7DD952500FFD7147D
+:107CC00002F4EC3762F19B0CA43FA47B7FAE19DB7E
+:107CD000424B0DF4850CF528DE1E96605FC7EC3133
+:107CE000F0E79C43FAA57C41BFAFCFD6B13ED16D42
+:107CF000F659519F3DD68B2717DEEE557BFC80B79A
+:107D0000EF8DF9F01713693FD642390664F3BD0DC4
+:107D100045D92B6D787CCC37A70AF0489A73D12EC1
+:107D20008992DE1F13CA62DF5C403A2BC0781C4385
+:107D3000251FA1743A2EDE53012830AAF4E7708F74
+:107D40004BE6E9EFA15DA548E7BE34743BCA0D07D9
+:107D5000DAE3A845543E8D90483C9DDC5DA9E6A041
+:107D60003C185149D73B809FE09B549F30FB2CE14E
+:107D700003FF56A67132CDF333C073934CC71D4D2C
+:107D80009208A7C1E09A099EADD127B3515E7FCE7C
+:107D900070CDD4DE0DCF1112E397956A39F2CB5036
+:107DA000FD3B6D7C3FD5027E38FA6CE27E38777BF6
+:107DB000BFDA416269F0EB379CFE210DF625B67201
+:107DC000BD6C307D1072FB89189EDD7A6101D70B86
+:107DD0002D51AA17983C5C087A20C8E1DF02BB7ECF
+:107DE000909F6192B4E8F720F707915226FF7DF447
+:107DF0003FE0B751554E7DA00D511FBC2BC55F9084
+:107E0000910E8904F3BB5FEAB86202D04F3EB3C75C
+:107E1000A337B445133638D4CB4CDF097D962C16E6
+:107E2000FA8C20FCCEE37348920E3FE8C307362C51
+:107E3000CE42BFDD8D41871C8AB62EC6FDAF8D9E1A
+:107E4000D12FDAC1FDA399F0A76BC9443A7958A89C
+:107E5000307918317B52E0F34342CEE32E434ED6C5
+:107E60000CFEC4B10F8B4CED39783E5DEFCE8BE448
+:107E7000D826DA4E9DADA63C14BE6AF98B55127D0C
+:107E8000EE2C64F0B76611A4D390B1E08402FA58E6
+:107E9000ED467F4DA8D2BD2FB69515E8A7E77AD459
+:107EA000DF763FF500FBB8A13E9B28BCDEB6F13F74
+:107EB000855C4AA1EB50371003EC09D5A4223102AE
+:107EC0004F3D0FE8453563217C765754C2F3BCD94A
+:107ED000F14AD9A6075433BE05EA8FF8CA7DEDB042
+:107EE0005EF526595624C6073936789B4AA1633F6A
+:107EF00097ADBBFCA589D62AD4EF8646C617F69F58
+:107F000077BDAC72B9E7A417412703C8BBCF441FA4
+:107F10006FCAC25FEDC4BF834E8AFAF02BDA85FACE
+:107F2000F9AB9CF875973F6FBCFA014F141FE751EE
+:107F30003C017D9E379BD123B547D17E7AC0D76166
+:107F400002BC1F2836644BEA6B175672989FF92CB7
+:107F5000DD6851BBE7FE95DB4D68975F4C6580841B
+:107F6000CFB4FEA37A59C376542E542ACC6E97C050
+:107F70001E9FAF6CAB82F63B295E81DF77027F43A9
+:107F80007C20A1A11CAE97DB2B36D2BE5B8F4AB200
+:107F90000246ACBE14F1EBE7FCFE912751097EC806
+:107FA0002DFF4B26BB0CD04B03FBBD9A38BE4519A9
+:107FB000FC0D609F8CA9D3A702D833B5DB5E275791
+:107FC000A65B57B5C2F07F47DDE10E344F9F77EED9
+:107FD000473CCB4DA048D897542B36FA0E97317FAB
+:107FE0000749D0F5407D4E371F150E4CAF0FBAE64E
+:107FF0003F96C753DCF55E56B8BFCE60F03244FF03
+:108000001B07EE5FC0E76C9BC2E323D40043221E34
+:1080100049ECFA5BB9F15005BCA75CB709F0B55D56
+:1080200026D5CCDF1C473D14E1E3ED2CCFC1F60B88
+:10803000552647C79AFA16C0F7D866192C05F2B824
+:1080400062E0FB51CBEBF67B281EDA0B492C64E097
+:1080500010D8EF8BE335A4CBFC5CA6C7F2EB290963
+:10806000D07AF9A52469D0F6EDFB1FA8D068394273
+:108070003754600AFBCA193E7D252406A690C72204
+:1080800029997D4F424C5229EFB140951E183F036C
+:10809000F75F77E69298D7E8931B82AEEE6CBEC787
+:1080A0000F7AE481E27BAE9800FEC65215FDE4E44F
+:1080B000630A27E14F54205E163761BCF6596CDE27
+:1080C000F40DE253D5D9FAC7DC3F1BF9A43DFC34CB
+:1080D000CEC35A4762E3B15E8C60FC860A54F05707
+:1080E0003655337BD78D8FF524F1B832DD4EAF870F
+:1080F000906EDA3F51F8BEE0C58D60E78F835F690F
+:10810000F9974D7FDC381CBB45C40F85DDB245EDCA
+:1081100044BEB728CF815E12768CBFB813C7FDBFAF
+:108120009CDE87DABFBFC4E96F75DB356E7BA65E68
+:10813000D61DF6AB7B5D1F795257C0FCB6E4537E6B
+:108140004FA3077E03FA9AB6DF115DFCAB89465F49
+:108150003F7D72C8C0EFA23CE6AC86F8197A7D2A52
+:10816000F7608F6632BE1A2BE4D037285F0D107F80
+:10817000147CF511151287804FD40EA42F6296201F
+:108180005F097E51BA3BDACFA7F460D4CBE0B906E1
+:10819000FE2239B45C48E93D65B38784BC504B3B53
+:1081A000E313A5FE74F7A021231ECF94317F7596AB
+:1081B000D56D4293606927C6F5285DFD17D095AA55
+:1081C0002725C0EB98FB17E0BA7EA93056F7AB2CF9
+:1081D0007EEC5EC7CF397C89BE1BED793F1B8EB22A
+:1081E000F87D31363F579CBDFE5703C6D9FD319708
+:1081F0009D334C3F428ECAFD08DCEF3558FBE1C68B
+:10820000D795B323903E7ACB19E4ED4D2AE78BA3A3
+:10821000BB1C70E9070F65476CA0F9F9859FFE53F9
+:10822000C60550870D010E6E385EA23AFD879F3756
+:108230001CDDF1EF97B8DC1F4C1E044D33252BE0FD
+:108240003F23CCBF1322DCBFE3A4F79DCD32DA215C
+:10825000C1B0BC134CC9ACFA6ED4C1627C4AEF55B4
+:10826000AA8DDE47971E4A413BB73ECAA4870693B4
+:10827000B7AB7CE60D2ACAADF4FBF1BE7C03CA2580
+:1082800069F20D32E2B5EEF3C937182ABC7BFD9BCB
+:108290003C7FE0867241C7C6D2DF51B8AC3EE821D0
+:1082A000E897F998AECE16575BCDF78137F07DE4AD
+:1082B0008D241E818FA7885C09FC728A1C8E4CB3AA
+:1082C000C993FB548DF14B9BE76DF0AF8A78F94D64
+:1082D0001DAC2CE673F3FDCEF2D7C9E23CF0EB7D8A
+:1082E000FD3E0FE26BB5CBBFD6AC32FD7133A96B4F
+:1082F00005BCB5784815C8B11B74A28EA0A6EBBA10
+:10830000671E9CB19296BFCBED91F7A95C366C715C
+:10831000D035A1A406F87DA76BDAB59710689F6CDD
+:108320002D807D5A36C17DAB1BCEABDA9CF31B6C26
+:10833000FEEEF952F2C2F9669A87BA474A6B4F3F8E
+:1083400022E40DC757A6BC2A914FF50B20205ADF17
+:108350009A43D8BEF3AD60B209E535CBA71AACFDA0
+:108360002F55463F9FB6FDAB83B45FE7EB5900CC7A
+:10837000D6966BC5C12F24E28235A4CE1C4D7F5505
+:10838000F72DB246135BBDE810EB150F5C2FD3BC85
+:108390004FE83E4BBEB06FFEDF9512C7D434F3BF3B
+:1083A0005D49D440FF5EC083024F15F18D7E608A27
+:1083B000DF5A35D4266541BE5317EE03FD86EAA089
+:1083C000875AF805E45A09936BC112E777B77FF82B
+:1083D0004355C4E153C87F188236C07E08A514F007
+:1083E000DF94AB277BEBD3F16A605D1742298E7275
+:1083F000A35E67F56B8871D7EC32E43F8C3FD4B74E
+:108400009F8F71F5FA9106FA77551233B10F17DD88
+:10841000D59E9548D2A60F6BD51E0DF8AC96DA45C1
+:10842000F6F7EBA38AC34FEB7E7AA8E51C2A817D81
+:1084300092CCFC483A2DDBD6FDA70E89E7AF185940
+:108440004B06F0DFAD8F327FF00DEDE3B398DFD058
+:10845000297F4F3732BFDCBF3DF67D0DFCFCA71EE8
+:108460003D7615C07BEDBF2AC407F91B8F85490AED
+:10847000EDB1A406F6D89A2EC54CA6CDAF6862F130
+:10848000CFC7C388AF354F7A930B69FB354FBF33E6
+:1084900085D0F99DDED4F3E268B09B1F95581E820B
+:1084A000D53DE56AFA7E8D4A56A4F31B4CF630F9A9
+:1084B00073F2D96015F0B7B467FFF5D86FE7528F44
+:1084C000D7B6DF2EF678906F693D66973F2225C7B5
+:1084D0004BE9E6C7F23F4E3E22B1F9EDF524FD30FF
+:1084E000BF3D3BB5049D47ED9E0F509ECC7DFC8764
+:1084F000118043ED5EC5A1076AF72829EF147C1EA1
+:108500008327C48DA41940279C5EBAD661BCA8A657
+:1085100073EB07E0C7A8DDEB946B142EB114C0F524
+:108520000D25B610CA4FFD4BC4A0A07AFFD0C311D1
+:10853000802BED77A59605FAC649DFD0FFD99CFEC2
+:10854000FD11D283F1BADACE76365ED7577E0F7A36
+:10855000A5D6253FDF875FF2FBDB33D7785CF6CC0F
+:108560009EA1C5EBD6FEF0CC43161DF7E4937F78B1
+:10857000C8A2F3BFE5AFFFF9D0B7803F7FE6D74190
+:10858000FED73EFAEB08B1D163AD87F1E3E9B1C4A0
+:10859000A27B5472FA37DE24F84B4EFFF4F7E30C5B
+:1085A000BAEED34FFC25CFA0F5EB7F3A7F14C0A1E4
+:1085B000FEC773470DB4FF067A4D7AEDF34A225E8B
+:1085C0008DBD123382F6F1A70B3F07BA0E8C83796B
+:1085D0009E3AE28D81DBB996BE6B980AF85A87FA0B
+:1085E00018CA1B289C6B1EDBFC01C889FEF0B6462E
+:1085F000CBE8AC4F8D06A77D4DD73B0B106FA40782
+:10860000F5A8BB7EED6B149F1766C6DF19F2B106A5
+:10861000F2AEF6B176365E27C55FA43FFE4EC12F9F
+:10862000B3FAE3EF0E17FECE905BBE970F798D5D28
+:10863000231C7152F1EC8B0FC6B3E203C80B210F60
+:1086400006836FB5C4E6B5CC633EE801BE7A32D886
+:108650008BDF8580DF1F9E1947287D1CF7F45C0F98
+:1086600072B3E7A75E7D177DBFE6A76F209F9DFED3
+:10867000F12B9A81F9992424E5F13C31F67308E451
+:10868000700DDBCB91DADDE19437D287A79AE4A2B3
+:108690004A2382EF8FE1FB24A3FF9AE4FE25521ABE
+:1086A000BCBDE1296276407224C265DDEEDF69CC93
+:1086B000BEECC3A7540EF83CB600DE67C2A758BF95
+:1086C0000EEB9F69C3EB6EC6B7EEFA35943F41EFF0
+:1086D000F5C36F527A039EA7777A55D07BA7C1FE68
+:1086E0000AF5C77B1FFC99FD33DCFDCA2B6EFE1615
+:1086F000F1630E87CCF461713B60E0F50D177E3FAE
+:10870000F7180E3A12703CF9717AF97F8ACB8D1AFC
+:10871000625516D8EC139F87DA27905F46E2D6E8B9
+:10872000C2BEF99E847D04A5BF938F2A18AF69ED60
+:108730003C8072DC2D2F6A48FA7DFB5F3DCC5EAC3D
+:10874000D9BB7F0AC8B593CF3D8BF459F3D8310D0F
+:10875000F62F2FEE794AEB2EEDE307D00F499B7EE3
+:1087600038F9A3FD53983C48BFFF0D6AACFFDA7D92
+:10877000CEFE6B1FFBC0D1FF5AAB5363790C038F46
+:10878000F3BE6A2E85F5BE7FC843409EBEDFA9A416
+:10879000F5BFF670FD28E0D4FACA82DF419CBFEC39
+:1087A00070C0003DDAB5C91C7507D86B873D04E47D
+:1087B0003751CD3F7869B9EB9500C633BA0E5FAB40
+:1087C0001836FFC4332E78CE7CCD9A1BA6FDCDEC97
+:1087D0008E97C116CA2D37CA8FD27DA3DD7FF54A89
+:1087E000E52890FBCD60CF4F84F16251F07F289156
+:1087F00005952C7F50D6FD69F537EBCF138A63BE04
+:10880000A047977B7DB6488F62BFC5FD4DADA1F4F3
+:10881000FEE8059AD817D0716D7290DAAA55E9F082
+:10882000364B637648A6EF976ACCDF93E97BC52089
+:10883000ED7BF99BE3470BCBF174F39EC6FB71FB19
+:108840005733C9030FEFA74C331CEB05782FB2E564
+:10885000C58F26C98D90274A4221773C3AEEB3C78F
+:10886000A3AB0EED87F873EED5FBF201FE11D2AC8F
+:10887000BF87763C899D1BC08E75C79FDD7989991E
+:10888000E2D1BE50CD9114E9DF5FFFF8BB897928B2
+:10889000CD63E6F90A6DF1F766BD5FFC7DBD46C7A5
+:1088A0006DC9808725DA9C7FD280BE649248F77DAF
+:1088B0000BA79BCB49F7532B619E3116BF9FED82CF
+:1088C000D7A51C5E3F3B9F2E9CAA9E0A62A81E0A4B
+:1088D000DFB94BCC661081F397F7ACDD0F7C26E255
+:1088E000F7D644F95C70E8F01B6E5EC42ADFE27BC9
+:1088F000B521E445103D27AD5EE89B87C5F755518E
+:10890000DC2779389F1D78F3661FC82D95242A0B24
+:1089100061BFC4E39A986F4FFBCB4BF98949E7AB32
+:10892000E906DADB79A9D50FDC0471757D0CC62365
+:1089300094B397A0FFD0DDAF128D59980F16322A4D
+:1089400014DB38ADB92C3EA3EAF1B479C3ABB4C49F
+:1089500013B05EE5EC65D8AFEC8B613D121A5ABEE0
+:10896000EC77AE8E207C7D14BE201F1164B02E9E4D
+:108970003775F7D511D433FE839E9DF0DD1F6279E4
+:1089800054B7CB8118E459B9F3A82ADE6A27D05F1F
+:10899000EB3109E328827E5B0BEBCE03393E401EB0
+:1089A000D54B9ACDAF9E298FCA1FBA11F3A8FC9F51
+:1089B000368FCA2A9807F6586B361179559644E7D0
+:1089C000D1CAF3A2FEA3F5A5B9A09F5AFDE2FBCB45
+:1089D000734D7BD95A7F00CB3CEF6AB4B7BD09EA2F
+:1089E000E78E26759DE8CF33C93536391BF1AA08C5
+:1089F000E77FD6CC7735479E7CD4115F3AF0E666A8
+:108A00001FE86FFAAC2C02F851BA02BB3D2FD54ECD
+:108A1000ECFA483C051DB5160F1CBF53CF5E847E93
+:108A20007C51F6E949D34C537FBE8FD91F827E7D9E
+:108A3000B924097AC967241EB809E83937140B32FA
+:108A4000BAC438595B08DD53FDD6D1567C03C6DB6A
+:108A5000CEE804B95ED071FFF95FC6E75F64615C80
+:108A60002244309E96791D65B88E559A19F6DAE043
+:108A7000987B5EFABCD4BBBD6C3D2DF1E52CEFAC10
+:108A8000DA198715791AA27E504A1478411EE6B287
+:108A900038ACEC63FCD6872FAA2A6CFECD26B2DC5C
+:108AA0000212509777E2D146554F62FD127FE27C69
+:108AB000AF233ED7CDE2BAAE78E27CE516C6DF83BF
+:108AC000E04F9CCBD80A71B789109F8BF2F37D06DB
+:108AD0008FD3992CAF28033DB5150F1C87EA688CFE
+:108AE00061FBBB1ACB59BE9244B85F3BD9047402F8
+:108AF0006E0946F73F6802BE092B822F7E88E53B50
+:108B00002556BEC9FBCC5CC8373CF0E61B55AB28EC
+:108B10007DB49A01E4FFC1D6A72767205E873B4E4C
+:108B2000FFF5B271DBCC10EE77075BB79E62E30E08
+:108B3000751C115FEB5B9F0FC769350619A7838D05
+:108B400033F8FC199FDCB17F35E62FF828FFFBE9ED
+:108B50007BDFEC1E9248D37F16E79F036F7A515E4E
+:108B6000B7E5B2FC284F49C8644E4067FF9ED2BCAF
+:108B70003978DEA1EC02CC9FBF637F3BCA190DC6DA
+:108B8000A1553CB1D04AD62E61C239DBC83C82F136
+:108B9000674F49DE2A78DF403AE273400F97CB2CCB
+:108BA0003FB9A4E426E8271BF892CEA3DCC7F69DC4
+:108BB0009E928B6F86FAFBA7BF9E68023895333A68
+:108BC0002007F31D706C358AC4B99D01F9DE53EEA0
+:108BD0008C5B109F33FF93A84B306E4EE54287D7D6
+:108BE000665752BD781FF23329B3C0DEDBFEB56B8A
+:108BF00063767EFE672DFE1D565FE46B093E4F9F38
+:108C000037D79A2BF2E6123EA50CCE29F5E6532F64
+:108C1000CCB7E77FF17CEA90C8A7E6F1CC0EFA5F0B
+:108C2000BAFC39F739C6CF2B9FFA292FDF0F07C9B6
+:108C300058C8A7FE8987C4529017F36B250679316F
+:108C40006EFA70F7E73E07D06B8F64E0E7F7013804
+:108C500036B9979F70E1ED463FC6E7C478CF837C75
+:108C60002A1D9C4F47573BFB195BE73C9F755E8372
+:108C7000335E55681538EA9FDF56E4F83EBEE302DE
+:108C8000C7F789F74F759427252F76D4FFD29E39E1
+:108C90008EF2E4CE2B1DF52FDCBBD851BE28B5CC0F
+:108CA000517FDAC11B1CDFA71F5AE3F83EF3C87AD5
+:108CB000477956F7371DF51BA87902F92C7040004B
+:108CC000F7ABDB46CB76FA6CCFA67A250BF3B8353B
+:108CD0009ED48FF166968BDC9767E06EA7146BA627
+:108CE0004EF9573126CCD331CFF046E423A5386F67
+:108CF0008E81EF672C00BF132963E7B444FCDA537D
+:108D00004C527EC8EF0BB9F0EB8A4B7B946D29C0B7
+:108D1000B376F4CB07A5487FBC7AA2EE7CC6A1C58A
+:108D2000B555E3B3E507E4F9385F8CA57C817EC4D3
+:108D30008F15D8B7907961B40F6CFB1B84A3D8DF73
+:108D40005CE623CD0053C11715CB7B46BF80D5C44D
+:108D5000BEC62B0F272FB9BF5EF1A2DD25E4CC6084
+:108D60007A45494E73E421B89F54FE95F9609F1EE1
+:108D70005986F2A8775FD02B1FE333E1BB478DA163
+:108D80007CEC957F7B0A1C7261A8F6995B4EDF052F
+:108D9000421FCF05A597D711C80BA372E9CEABAF81
+:108DA000C23818A9278EF3807955711FE83D6A975C
+:108DB0007DC567DB3F47CA997DF6F766A78660BD2C
+:108DC00036F927EC5501D7118575718CEB85650255
+:108DD000FBAAA6D9B128F801DBA08A6D9FF65DDF5A
+:108DE000F958BF39A4C9E02F6D3E381FE3035E7FF9
+:108DF000DC0779CE4D9E7825ACAB295BD6D3E53B1D
+:108E00006DF631FF8CD6109CB67B00FAD034BAEFE9
+:108E10004FB3DE7FF131BF4BB3BEF820E8B99CB051
+:108E20006640FE44EBFE598B305F77A1AAC3BE9625
+:108E3000D04DDC3BB6B8222171F46769B932EA45FE
+:108E4000AD2182E30F36DF5B7DCCCFE06DF00F38D4
+:108E50005FAF96DE4F9169BE9B61BEB983CFD70BE2
+:108E6000F39560FC108EBFC9C7F0E886BF87986D88
+:108E7000F368BD96635FEE28468A61F97AF72E9C07
+:108E80008A744A05B5837EC53E82D2EFC340BF6275
+:108E9000FF2ECEB3DEE263790902AFC460FE881113
+:108EA0000915F7BD3909B6FFED931F8C8E723C3161
+:108EB00082E7BFC6A8189704378DDD8FA1F8D9BE09
+:108EC000C77B690CF1D5FE15956C027A2BA6EB8158
+:108ED00073B90759DCA9DD13AB8A87FAC613EDDF36
+:108EE000E1FB40952CC9C27B529485D174F6672F63
+:108EF0009D73B8B9E5EC011FCFC3CA27F94CCE96D4
+:108F00002E85A34499FA71DB1B0DDCAF3CFCF329E1
+:108F10001D08CFF631F7A11D2DFC63245A3688BFFA
+:108F200087C54BFBF0BCD448513CAA574C45A75FC2
+:108F30007B31C7739D2B9F97E359E057F8ED493478
+:108F400017F95AE05B017802AE94D9D181F495C249
+:108F5000F9C60DCF53FF4DE17904D600743B96AEB0
+:108F60001FF8E6C01504E3602E7E14ED04DDBBD7C8
+:108F70001FF6FFF75EBFA087CCF5ADB4FB0F11D78E
+:108F80000D737AF371BDF942F9DB6D709E44CD65C6
+:108F9000FBDD7079F3AD329CC320960EFEB5B03880
+:108FA000BF53E6BC7F2450EADC7FF85CF74D78F8CD
+:108FB000FEA3DFFD2ADCCE12E7F9DDF377E36BAE2B
+:108FC0003F7D1E261993DEEFEA8EC789F886C88397
+:108FD00015710084035DBF67961C47F95746CC9D09
+:108FE00069E4D3323FD30B5DCFF9314F225CA5A1A9
+:108FF0003FB6A02C5501E5823A12033D71F1F143D1
+:1090000024413BBD20C0E47E41595202BF47C149C3
+:109010009617B89DC72B0BEA93D24ADB38969FE987
+:10902000AD8FDEBC1DE5E37363595EFA6D15CC7E32
+:109030003B14BDA1A302C62D67F9E461BA5F84BCED
+:10904000B1F0116F12EDADB26E027E54AA05AC30D4
+:10905000FD7EBC914CBD713CE47DF9F079B251C705
+:10906000E781B1DAFECB69BDF5850103FA6D290A06
+:10907000B0F3BD611FEEF7FF9CFD75F4AB9E6E8CE7
+:1090800062FDB66F9B685734EF3F817EC3A0392DD8
+:10909000C6FCA8A642CA613E874CF0731035662C08
+:1090A00086EF077E83F5142DF11B0BEC93651AEE0A
+:1090B000EF010E104F68F2B37CB9CDFEBA68363CB2
+:1090C0000BC98A4569E0BD82EB1D4A518A96D79744
+:1090D00087A495A7942CF02797914EC873F7B424D2
+:1090E0002B404F93D5BA01E38CF1252BC07F3CA6D2
+:1090F0005A8F810F5D2B67E745043E3C7E127F222D
+:1091000004F552D2AD74DC89011DC7293892C4BC64
+:10911000E58FDE9C99D6FEBFFD68057EDFD65879C7
+:10912000789E8D9F4319E2951B8BE73CE0A7E3BD3A
+:10913000EA67FC9AA95FF11C6ABFAF723A39F0E6A0
+:10914000C451605F3664C8A356748AA7114C3E812F
+:109150003F62FD78635476C8DE0F8387F2DCB30C80
+:10916000AFA58C3E9B7E3C310BFA7DFECDA53AF837
+:10917000FBFE945B8CFB86534F7B4DB05F4EE590BE
+:109180006ACCB77C7AE68BB03FFC43E3C11CD526A2
+:10919000174FFDE895191EDADFA9275F99A1227301
+:1091A000251D76ECBA73AFCE003BC19A434AEAE87C
+:1091B000B356D708F45BEB63EB107972DBF3B4566C
+:1091C000785E19CCC6F679A3E43BA1ACF85E1DF736
+:1091D000EE345C378B2BF0380E5D5F5308E95AA7ED
+:1091E0001B1088175ADE7110CF7AD38BF4F75121F8
+:1091F0002929BC10FC820AB6EB594D92904FA1A5CB
+:10920000EA803D89FFE52401BE09BEA6EF475AE387
+:10921000F7C1DDE9E7F90F3C8F70E39BB74F04F826
+:1092200008B9AECE2518CFE8F99A2F09F6E83DAA7D
+:10923000F19DE560075EA7E23C6819CF1BB9F1B369
+:109240003C58E488E3E5F0F884C06B263AD9DA4864
+:1092500062C514DE3F6BF4C560FC7D8D3A967FD20B
+:1092600018C5F2DE46039F4F3796E0B3AB3186DF79
+:10927000F73496E353E4F5E1D65E417B3A5E017A3A
+:10928000E81AE687D30DD9847C852C95F8E0BE26B4
+:10929000FDE8BF55C17E1BE44A560EF2BD04ED73D6
+:1092A000799EDFC8FC39ED15469F7C15F2B4C943A1
+:1092B000249047D62CE66708437FB47DEE1242DE49
+:1092C000B6C9F573F49FB74BF8FAE87CB24CE77770
+:1092D00077FD884A1790D3BF1D958B58EEEB373D2D
+:1092E000FC86FB047FF9DB36FADE3E9DAE9AD2D1D6
+:1092F0007689C9B13BF9F73BA6CFC8BA01CAB366B4
+:1093000064815CDF3E8B183A85E35D866C79B2FA46
+:10931000EAEF683C98376F3CD74120A7EAF59D5BA0
+:109320006CFB9831165911B7D1CB5D756AE52EB437
+:109330003312F98B2763BE31F76BEF9E678EC17EC8
+:10934000B13C21F0E23C8BEB159033979D657AA8F8
+:1093500057FF7CCCDE0BBDA771FC6F9BBD4989001C
+:109360009F803C057959962073E83C4397B2F8F703
+:10937000AC775304F2FBB4187D0FF6A8C6F24D0A81
+:10938000A24909CA3FF2C7670620EF3DE7FED42E87
+:109390008AEF0FBBBC06C41BBB9EFB0BE6672853C2
+:1093A000341FF077C1BE6398B7A4C8DD1AEC789774
+:1093B0000526CF57C19E8589607C802A6A8A6725E9
+:1093C0008FAF8F3CD5322F04E7BE1227ECF5B707DD
+:1093D00012B7B21D33317D51CA0F7ED1FE82168085
+:1093E000C7560F2B2F0B4C6AB1B04CEB67B37233DF
+:1093F0006DBF35BB332A6743D2D4C4968397425995
+:10940000D49FD862CD26E41AAE0F48285108FCDE5E
+:109410005BD669396C2BABAC4C7CEC29D6BBEEC06F
+:109420005F5E1C4DE150B34FEAC410DFBE9D12AC2D
+:10943000BB60EF4E94AF054982FBFE82A49484A3E7
+:109440009D7B1A0FEACDC2B926F04245C3A428BBC2
+:109450005F484B7A62B0BD9CC4EF0F1174F17490F9
+:10946000E9C74949DADE1E9776DD273289DF57835F
+:10947000200579B98D9D0776D37929EFAF81585BA7
+:10948000E03C2E79CCA3637C9CFBD94F0ABB89FBC3
+:10949000736EE10E3CCF262B7001C8BF952AFA816E
+:1094A000D7162637521B8AAC7DB630462D56D2E2EF
+:1094B00067F4B236BB336F2AC5674BB6B3DCC4F36F
+:1094C000E7A3D956369CD7ADD97BF738C8EFA92189
+:1094D0001DD77F13E6FB328B879FD83F2BEB125AA9
+:1094E0005EF7328B63ACEB7A4503FABE27C0F38E8E
+:1094F000BA2EBA12D657B34D267221E34B73229D72
+:10950000AED971019CAC7B7EEB5BF3FD630979A462
+:10951000C8D4E58B08E90E9E68F151FC3FA2E9939F
+:10952000803EBA833D2D405F6B67C99C9E7A5E305A
+:10953000559EFF5800E35CDE027196DDCB2AAF0436
+:10954000732B4F66FC4B0912E3DA4A76B30FECF942
+:109550003FB6C8683F838B7403857BB14A0EAAF47B
+:10956000B95DA3F8043E6B55511ED2F76D1EC44B76
+:1095700007DE3342DAD83D2DE3F77957829D5D5CF3
+:1095800067AE467B5B2F453FC038D2FB837912E73D
+:1095900011267F27EAA442A5F566050B117FC55564
+:1095A000D7AE85764A784900F83D4F495AD8FF77BB
+:1095B000991CDE2E273B7D2097234588DFED114641
+:1095C00017D63DA54817BBE53917805DD422ADDC21
+:1095D000F20BC06B76119E7B85F7EB61FD1C9F4DF6
+:1095E0007ACC07F8DBCDF1A9EC942DC8D714EFB7EE
+:1095F0004A37AC06B89ED8523FDF47E19AE735DBE1
+:1096000046503C1CDF52DF129D857828F2D1EFC70F
+:1096100003F52D3E8A97DD1BCD02DD569EF8099598
+:10962000EA48B4F52DE66CF09FDCB7069410FDFE19
+:1096300002F83F1EC9117CCFBE1717F5CA1113ECF3
+:10964000D226AB4FAEF8A85E28B6D59F47E5C20F2D
+:109650001E5210AFFF4EC7033941D76101DDF74CF1
+:1096600052D12E08D0B904683930B908F36DE9BA7F
+:109670004900EC86C92AEA7911C7D126C96837435F
+:109680007DA087407E11E6CF51791D87733E4A94B5
+:10969000C5751465874979980479FEBEA42FC2FB6D
+:1096A00048FC25B6BC0290BFAE3C04C5551EEFED8C
+:1096B000CE97A97ECD3DBA481A47F1F25E80EF8B76
+:1096C00072E93E96BE7F3FC0FC40B7C7AD2F43BE98
+:1096D0000C31BAF3593C2A3E159EA3AE2B1E359091
+:1096E000FFA5FF7E3586F6CBBD63D4B4F960FF1AC3
+:1096F00064FE41EFD862BC57A38150FE07BE08F15B
+:10970000FBF2B8FCF0707BC17D4E40C8134F365B56
+:10971000637DFBDC5139A1BE73704AC8F4813CD82B
+:10972000AF4FCD027B743C9753CDA9595F05BB4524
+:10973000E5F260879F9DCBEDC9269DBB08D8BF3160
+:1097400062CF4B10F2605BA30F9F0F5F3601E39770
+:109750000F5F963707E215072E7E1FF7BF6776303B
+:10976000FE3D73E805B84B899CB1A8B6311859A1E4
+:109770005F3E752FDE17F27D357E17E6CB43BE0EBA
+:109780009DD25DD9CE3CCC47395CCE0578DE808752
+:109790007D17F778A867BF847EE06D7C3DBEC43C32
+:1097A000DC57821B0FCE1DFB4907DEC724E0E0BE5D
+:1097B000BF433D3B85F9EB036C5F2AF297DC794AA6
+:1097C000623EFB8219EE3376E143F835041E44FB1A
+:1097D0007AC91CA50F4037B5671592B4E585F49D8D
+:1097E000DBD0F0FD6938EF9205F7AF243A2E29045B
+:1097F0003E48A29DE80F353BEE712551B5C77EBEB0
+:1098000024E83AEFE2E617B83F18F4B4660C7CAEF1
+:10981000E57DBACD1579B998A7AE9207C0AE3D15D2
+:109820007C6B06F8E36AA998005739512D3C4F7AB2
+:109830009AEF4BD47DB7E2791E313FE18F13E59A61
+:10984000BD8BD04F57BB3B84E7796A924C0EAEF389
+:109850005907BDB23DEFD64C41BEAD672FEB6F3C13
+:10986000E080D2C7877A753EAC3FD870FE4C38672F
+:109870009227D79D370EE0A3323CC07EF9C9109ED7
+:10988000D355BDB6FB53DFE2FBE365DC1E09124B8B
+:1098900006782A8158376167164D95DA474AAFDC5A
+:1098A0009BDC02FCB0DD656F6D0FB0726B70724BAC
+:1098B0007329EA67948BCB023F437BA8C52FCACF9D
+:1098C000A29CDCAEB1FB3AACA7BD06E83DDA1ECFE8
+:1098D000A75BCB4A507F2845A400E0360F1C2D2003
+:1098E000FF9EF6EE023FC38FFC896B0236B89D0ADD
+:1098F0001F1907FBCA34FD598EFEC60DAF3F3A7ED5
+:1099000017E0417C9F17B91FFBA7EDD0DF41C61CB4
+:109910007A8BDABA24EF692F9E33DCE171DADBE26D
+:10992000F920E7CB36D7BD1DBE44B3099B73C19F59
+:10993000EE7B9605BFAA672739F2A4C607593C5BA0
+:10994000554D7055D2EFA5EC7B80D1411BCFC7C9D7
+:109950003C4E4E86719C71BBFEE3CCE07282F07D82
+:10996000ACAAF7DECB3940FEAB3BBEE8966FBD4FED
+:109970002EDFF2393DC7A5C4B3415A5E93EC5C10AB
+:1099800060FC3905F87335A7D3923D773F076AFD30
+:10999000319FF967D837ACF2991704A70F9F7FBAA8
+:1099A00083623DFDE417B3CBAA999D5BDF3EED4A90
+:1099B00028D7DF51A45B69E245E2597D36E8905F24
+:1099C000F7707F51B56AA11CAB3E1BC1EF9FDF78DA
+:1099D0007EC779B6FEE385F0BB18EF16977C3E7024
+:1099E000F14BDBCB291DD73FE191BDB671EA9FE07A
+:1099F000E780FC545E3BF9DD047E570B496F9E22E5
+:109A0000C887BB3451565AC12E7AC42E1FCAC16EA4
+:109A1000EB6B0FF716DE15E0F5AD60FAFA4157FD76
+:109A200022D17F2ED677CF47C81F28839DA67EE2FE
+:109A300015F343F975B7ECEA2F478C3F06FB13F695
+:109A4000FAB703E35F843B25EECA4E568C66FE1DD3
+:109A500003EC80EFABB180FD3EAC6F737AAD3E7B23
+:109A6000BE03DF7D709FE078FFFBC6A8235FFFE6A3
+:109A7000443D9ED3F87680D16535B5E8B1DD8ED111
+:109A80008E3CFD7FCCE3D3CEE3920CF3B8EC6F3C7D
+:109A90008F42077FF6CDA3D8F1FED3CE631FF70B1D
+:109AA0003FC79FF375762FC07C4342BFF57C5AD7E2
+:109AB0004F69FDCBF4E9A3CFF92AB14278CF6D927B
+:109AC000DD6346CBE00FF8EA27B7BD7B39DE0B6DCF
+:109AD000623E8E57E4E3F0731E9BC70C7C5F91FBE4
+:109AE000EF3BB8BF0733DCD3DA1862FBEEBB2FBC09
+:109AF0008A60FE7A28817182FDF90BA260A77FE758
+:109B0000C21A7C36E7CF88823C6A0A7FDD916F4EAD
+:109B1000F70869CFC1FE91F74BCE7E59B69F47D962
+:109B20000CE751D2D41771B1CDBE3ACC03FFA2D607
+:109B3000FBE017B4DE4BC38CDE36FB1218176C8DBE
+:109B40007E31F37F26C4C6B9FBC2CB089BEF6529E3
+:109B500016F7D10CFB7960F1DC1F9E118575366517
+:109B60002F88023D3767CF70AC47C9B09E5561065C
+:109B7000A7CDFA17BB9EC39F793D0BD2E6C1AAB908
+:109B8000E9EF176B17788A2690CEBEA8759DFA1B51
+:109B9000AF6B14C7577588F90D361B8C8F824AFC42
+:109BA0005785D2E07C38D8DF1D21C5863C943CBC6B
+:109BB000DF727865E2DF659EE44898D79146B67F0C
+:109BC0007E9DDF27F5DBEAA630FAB55DE36C1EB3B8
+:109BD0002B3C909FE37F563BCFA70F26375A422C52
+:109BE0005EF3B584B3DDD2AA60DAFB4D28FCEE2A21
+:109BF0002CEC83673FFC7FCE70CB448FC3855B6BBF
+:109C00007478701B8C0FAAE1929BE983C34DD05BE3
+:109C1000A67EFE7FA1B307870E2FA4AFBF15BCFEA3
+:109C20005EE9EB1980D710F8F21FF03AC7F5E6D0DD
+:109C3000E025E4D81E8DDDBBE8EEE74498DDAF34C7
+:109C400051AA3B7C05C417BEA2A0BFF7F08E79EBEA
+:109C5000886CAFC7F4D9E1CAB9EB30DF351EC47BDD
+:109C60003C5F9363FF5E067187C5AC5DBF7972F898
+:109C7000BC14CEE67E4B6324F8115E8B5F3DE0FAA8
+:109C800048A56D5D989769BB8F4AE90FDFC3C4B8DB
+:109C9000A30CFC4D0BD3CF43E033D3B8C3C5E76B64
+:109CA000F1EF0F0B9F83ADF7D970D190E485D837D2
+:109CB000E492DEBF977101C0738FCCF2398EC2ABD4
+:109CC0007CB89F8C60A5A555A376029ECA223CEF66
+:109CD0004933D6819FCC7BF5C2AD618AB7D7AEC977
+:109CE00096BC367879230CCF3396A7B70B73233CF9
+:109CF0002FB7B7BD44E03E44773D85D7BB6639BB3F
+:109D0000978AA8E6D8C5B67375535CDFDDEDC74604
+:109D100022F8FD351E6F777FCFE2ED972E19B83D03
+:109D2000A963F7B950BA1B9BEE7E41C11F9DE14468
+:109D300034429FAF4B8907BF01743429C4E21E2A05
+:109D4000298478BDE8275725298DC2FD5D8F3116FE
+:109D5000FCB469FA291CA89F4C7015EB11E3002B89
+:109D6000C2BD2C74FF88FBC5329390D9B04FF4C6A6
+:109D70006E65870D191DE4F0FC999975C1E446B034
+:109D8000F354BA4EDB7CBBFE6BEEFF80EF5D876564
+:109D90007D53617F380C261F1670BAC955129BFC83
+:109DA000E01F5B21A5BDDFECF208FB3B251F847B98
+:109DB000E3EA38CE84FB121EB8E7E05A9EDF44483F
+:109DC00062ACFDEF8C7DC0E58ABB5DAEC2E2D1E442
+:109DD0000DC6CF7B76AD199B8E7F5EE57CFA41B8D0
+:109DE000C4919FB4247EAB07F873C9C2451E2304F7
+:109DF000DF99BCBC86CF638F96187B51A80F4E1994
+:109E0000E510874FD7914413DCEFB0A241C238521E
+:109E1000E90646772B36EC97D7D1E74ECE7F8B00FD
+:109E200007B6FE6EE578DDB32B300EE6BFA7D74F41
+:109E3000473BA6F3B8FE7E827EAFD591AB3683DF7B
+:109E4000AB5B22FCEF32FCA412F20DBA799E480BF8
+:109E5000FDBE11E63B6F24F2F7840D1FD4837CEE28
+:109E6000D2089E97FB8F762FFE7D0B412FBD72622D
+:109E7000C3478D907477AF969A0C7433B2A9EE1BDA
+:109E8000E9FCE416E7FB0F43F1AC7476AE780A798F
+:109E90002EEA2D560D4FBAFA57573AE59898F7081B
+:109EA0006FEA54BAFB1A7AE93039B0DEFB3597E332
+:109EB00002EFBDF83E927E5FB423C2E2777B9273DD
+:109EC000D6A2DEB2BC06C843311F01AF5C8BC1E92C
+:109ED000DA258A43DEAE5818749D476270FDAAD712
+:109EE0007808D671EFAE9726E3DF5174E987809248
+:109EF000D0E0FBCD24E50139715C31F0F97AA3F3B0
+:109F00005EE6D749E28EE9A03F1B94B47CF50CA72E
+:109F10009FD7AB565D83F36F567498FFB1E523AEC0
+:109F20002A07F952E5C17B828F35DF16BEC9B67E9E
+:109F3000A1EFDCF3FA6DF5AA01F5D6D22A27DEF6F9
+:109F400068CC2EB0AE647CB89ACA9BD9485FDD77E6
+:109F5000CCA4E31F4EE65CB4855527F0F71CAFE6B2
+:109F6000BF1F971377CEA4F2E684CCFC61D63F31B5
+:109F7000B9B1E4BE780BC4794F344CFB6937ADF707
+:109F8000325FDF5B0D03EB47373D4DB8CF793FE5DF
+:109F90008C234483F689FAF4FAE0FAEC2093AF6A52
+:109FA0006C1CC897EB36A4AFB709922B69BD137F21
+:109FB00055AAD3E56D7EA2333E59114FDFFE133D06
+:109FC000CCBE835E4A03E7BD59412EE7F47120A75A
+:109FD0005764986F575604EBBDD372FB7510EF3B77
+:109FE0002E3BE5F30FB278FC3C8BC9E713BB9679A7
+:109FF00046029E5A251DE8E1EDECD824A0B795CD88
+:10A00000C7D08FF02D5EFFBA50FC43D04F4B8E2C43
+:10A010009E3F92E2A56B3989494666F9FF31E79F79
+:10A020005C85DD6340F5DFBBA0FF68D377D1FE50D0
+:10A03000CD715F9BCCAE6C84BCC213B2B506F3503D
+:10A04000760558DE11894DB7DF2F13E0F338B17B69
+:10A0500078F8BE261E1CD08E3F4C3A6A70DCDD417B
+:10A060001DE28F872B95D4E57492EFED0EE23DAFA4
+:10A070006EBEC834FE70EDC013BB8767070EB6EE28
+:10A080005856E190ECC03395F7DE59067CA4754C28
+:10A0900049277F859C7E8DFBADDCF4239EB3393E42
+:10A0A0008E27079ED7CDF73BE7735D9D733E825F9A
+:10A0B0008E279B02901F4E479F6CB74BC9BCE9830C
+:10A0C000E859E6FFCD34CF389FA790134079104F61
+:10A0D0005BCDE5CD5B0DF746EC7870AFFF84CCF738
+:10A0E000070FB1BCADF1F19573461A7DF4795D1699
+:10A0F00093439F375D0A3DE3EEE7EF9D0E859E1B80
+:10A100008C0E855C70B7FF00E2FC23E1EFE3E81AF8
+:10A11000C4653E8818AC4CF40570448694F373CB48
+:10A12000C41807E76E4EEC0AE0FDF6D6166F12FE75
+:10A130006EC7F15D974CB2AF6707C7FF8A25D97824
+:10A140005DCA713976C528CC2F50F0BEAED78FE4EA
+:10A150002C80F2BD876490D0E4BAFA950AACEF8106
+:10A160002C9677BE62C32B680F0E97CE57D439F565
+:10A17000FF277C1DBD7696DA5306F493090EED5940
+:10A180003EB6CF892F9A0FF279D50609E5ED962CC8
+:10A1900003DFAF524D94DBA499E947E2A3F0A02A74
+:10A1A000E4182C02E0F1BFF9DF2953E39AFD7CD2D9
+:10A1B0004DDB6E9F0FF6A19B5F46EB8C8EE15E3010
+:10A1C000785E174A3C9935B24F3EBF2DD5ED1F45FD
+:10A1D000AB5C9EC5ED6DCEA7623D9767B1F5513B77
+:10A1E000ED87F8F799F8FA48CC456F7247CD4F00E4
+:10A1F000FE737C681704BC54EE43DEDCF7033ACBF5
+:10A200009B637C25EC1D77FB6BD584C36E3C94551A
+:10A21000E8C8C771DB21FFD017E9EBFFF96FAC2F5E
+:10A2200064FDD3E98BFF0778BAC08E008000000080
+:10A230001F8B080000000000000BDD3D0B7854D59B
+:10A2400099E7CE9DB9994966924932933738930080
+:10A250000625780321449E370991A0A803040C1A0F
+:10A260007044D4282144C54ABFD2CD0D893120DAAB
+:10A27000505DB4D67587885DB6D235586AD1D2762E
+:10A28000B0828FEA365A45DA8D1A1FA5800FA2AD2B
+:10A29000ABDB8FAD7BFEFF9C93B9F76626046DFBAD
+:10A2A000F12D7C7ED733E7FDBFFFFFFCE7B0A22591
+:10A2B00085449D04FF7C49FF3B9C1A20C44FC8F194
+:10A2C000BFCA8DBD6E428E45DA93AF81AF4D5D90B2
+:10A2D000ED2344EF94C9A3B4DD3B473EAD81F2BD0D
+:10A2E0007D36AF44CB2BD65F238769BB4C28F9A1C1
+:10A2F000DF9234287F097FE60EFFDEF0804CA2C596
+:10A30000B179AF867518CAC77A923502F3CDF14498
+:10A31000C60709D9AB109D9411F2F6E6ECC8265A8F
+:10A32000AE7112DD3D8590B9696CBDBE8D9FB77A67
+:10A3300027D3F5F4FCBA8414D2F5DD7DFB8AF0A4B2
+:10A3400038F37B6D844CA3130402369245C86D7CB0
+:10A35000EFAB528906E3133ADFA386F145BFC3ADE5
+:10A360008444CFA5F5E368BFF2583FEBF8CBAEBC11
+:10A37000702CECFBF09533C75E3329D62F111C9659
+:10A3800049E17F5E0AF3B6C92AC075D73D498D3DC4
+:10A3900071E0A673B85AE7873F76BA8F25FCFF971E
+:10A3A0006EACBCC34341B22965CEEC709CF90F93EF
+:10A3B000F0DDD3E87CFA46369F759EC57C9EC3F5DA
+:10A3C000D72E05F87FA6CB5E99C263A0414EAD8023
+:10A3D0007EF50E753C1D7F40BFD5739D619DBF4FBF
+:10A3E000009FDF375EEB898B07FEBDA2DE4C076F57
+:10A3F00093C197A7C33C3BE3AFEF16581FC5DF31AE
+:10A40000257CCF85747DC72F96559DAEE7B88DF618
+:10A41000037A7990F60B0CEF773DEFF7F6C691E9EA
+:10A420007249AD793D4B8F249BE9D2461A7BE3EC10
+:10A4300067685D6748F72B2CFCB74B191CE3A5FD3B
+:10A44000DFDE71EACDDB613F3B9211DED67132D3A4
+:10A4500065C6A7C02700AF2D499C4FBA9B9FA6FD9C
+:10A46000DEBE344FDD4486F30721DD97CDA0F5FD38
+:10A470003DB6D22DB46A574F4A6324CE7A27A7330C
+:10A480003AF0C97AF279B43D7983E103C80DF866F0
+:10A4900029A7376FCF0F5B882DD6EF0DA0832442FD
+:10A4A0007EDBEAC4EF36AF13C7A95BB84809D079A1
+:10A4B000AEB3130DE0877FE8B8DEF30A766CA153E4
+:10A4C000BD6E63657D15E53F69F87A1EE674B92BAC
+:10A4D000B27844F8D637C82678D62D34C3D74A9FE9
+:10A4E0004723B6DA78FB17F49C68BE2B1D113FE0BA
+:10A4F000E908DFEF61BEDFDF37B67BA0BD759E5D8B
+:10A50000919E11F9E0AA46335D9C6E9F6F7A830895
+:10A510008FE56173BF2BEACDFB5D4A5A66134A2A69
+:10A52000CB88EA806F1D6929799A82F2E8034B7023
+:10A530003DAF13520B729E9CBAB56451496CFC1727
+:10A54000393D7F5677EBA5202EDF505A4ABC71D695
+:10A55000F33A8793C0F7EB09E019E572F70DC033C2
+:10A56000D0EB32392E9EFF8BCFFB46C3C87CB4ACF8
+:10A570006E643C9FF07A113E6F34B427C33E8F89DE
+:10A58000791F64F3825E33E2E3C457D45B56FE1D49
+:10A5900020FA4D48C791642FE8111F9087418F74AE
+:10A5A000A4DB981C2F1E598F88EF6F855CB5B4AF64
+:10A5B000B36B0E233ECABD01849B28D72D34AFF365
+:10A5C000BD54060FCA7163431E83DCE0FA55E8BB35
+:10A5D0007B7F70FE5BA03FC7A7333CD4853E7100F4
+:10A5E0003CA87CBDC303FB7AD5E605F95A7E4473CB
+:10A5F00018E137278DB53FBE7364F8CD4963EB3C56
+:10A600009D9CB5EEF7ED6FDF3905C67DFBDB9F3B0B
+:10A610008CE32FFB229F443363E5ABEB252D1287A0
+:10A62000CF36789551C17D83058E577F3116C7F798
+:10A63000C9A4A537CEBEECE94E6CBF3454E9F05343
+:10A64000785EBB5152253A84239DC9DD6B85BCB32E
+:10A6500007C62EA270F7B7B7DC168A33CE6C0EEFA2
+:10A660003FBB4369F1F84C7C853E17ED96D9C38E0C
+:10A6700078EDAD7A7580F3B9B55DE80CE971C80E77
+:10A68000B2B41FED3AE6A6313ACC4C8A7E04F28889
+:10A690004C32DB61A79DD7D2DE3AEF651CEE89E62E
+:10A6A0001776AD757C9DC33F1CA2F413B7DE83F50E
+:10A6B000AF12A65FF5480AEAC3633BAFBD07CCB74C
+:10A6C000EB17DC7608D4E4CBA9416CD7107AA50649
+:10A6D000D9EDD4BD9301EF9FD5DE7B4F195DDA71C3
+:10A6E00025DCEEA11D8E6F92D06EB1CEF32AD72756
+:10A6F000AF813C3D17C623CC5E9D4747CBA56097F5
+:10A70000B5352054C8B79202463BD5B7E1F356326F
+:10A7100019EC87D0260FFD7DC2C64FD6835E262456
+:10A7200082FDDF75A83722BC09B373FB7BDC3BB627
+:10A73000D076AF825C80F1893A3654629013762FDE
+:10A7400096478B9FDF26C0CF99CA29B1CF44F350DB
+:10A75000C8E3FA1657B9BBA434B07702D7C17E0656
+:10A7600017B8BC3D14858B15ED1280CFABAFD86CFC
+:10A770006D411C16ED15611F072F0BDE755E19C8A4
+:10A780001F87E6A24B5904CECB85948EAADC3A8C67
+:10A7900057F6DB858F017EEEAD4F0AC830DE9CC0D8
+:10A7A0009B322D2FBE3829007E47795FE1011F1DA6
+:10A7B0007FE942C94B68FF790BC6FB07E8FE5236BA
+:10A7C000D071F26079C76AABC711F243986C066129
+:10A7D0000BA6B0582CF1B2EEDB3C8FB63FCFBFD703
+:10A7E000E6A6A09EF85DDF66271DF78EB6508E3771
+:10A7F0009DDA13E91F743967139295A5F5CD5509B4
+:10A8000071677C540BE5BD0F8AF13EEED20A08F960
+:10A81000992D1C9468FDD48CA405760A2F5F91981D
+:10A820003F6FB3368BEEE7E21B1F5D4FC75FFEDD68
+:10A83000490BECB0EE06317FE90258DFD259A25C39
+:10A84000EE82B22F85F787F55650F955185BBF3D5C
+:10A8500087CE9F21DACF58308FF63D5CD9526DA755
+:10A86000F3FFE8BBDAE649130999BEB0D2ABD1F2E7
+:10A870001319F50B52287EF6124AA7B4FC64C6954C
+:10A880000B60FD3ED9C6C7BF6A33ACBFBC413F0FAA
+:10A89000EA257DE5E65ABAEFB5CE814340AEEB3608
+:10A8A000E8CE2CFA3F2912E363A7A345CBA7B073E8
+:10A8B000ECAB8CE6E372BA19BD16444B408F0D9594
+:10A8C0008B69B9C450CE61E5BD9BC8D5F1E4ED6D8F
+:10A8D000994CEEED4D8E5FAF64307B80C20DF54933
+:10A8E000DA11A2ED8EA3573E4A77E37C079389EEF7
+:10A8F000CC88F1DBE594872B285F12275BA71867CC
+:10A9000098FEC8607287E89767803C5D0843D0ADC9
+:10A9100017A912FABBA42525321E688744ED4B40C7
+:10A920007FC8365CAF5F96AE5E44C7CB4A26E13D3A
+:10A93000F4EBCF2458A6FDB53DEED8782F71BAAF11
+:10A94000290AED84F16AB2734BDB83B171E8BA3B3B
+:10A950009C534CEBB6576440FDE2D29B2719E0397B
+:10A9600089ED83D201F6A3D33C3697F2C1DEBEF364
+:10A970000AC17EFFA945EE96F72D7610DAEECA4C95
+:10A980002E5F02ACBFBF9AC99FC19B53223DC09F9F
+:10A990004EB53464B03B031C1ED5772EBC1FDA3590
+:10A9A000F53948126DB77E4F653619412F367D3126
+:10A9B0009344A61ACAF6A80272A7E98B39F87BF568
+:10A9C0009D2F29C0A7304E80EE6BBD4BCB56016E3C
+:10A9D000EDF1F14F1D725C47D317E9449F6AFC9D6E
+:10A9E000C12936BE0FEB4FB7AFD8783289648E34A9
+:10A9F0009E82F54370B773B82BF1D7395FD02985A4
+:10AA0000B7CD405F4B39BD51E9877194FECB26F538
+:10AA100080BC8FCDBB09C7DF6BA778043BB02F3953
+:10AA2000007671B99DC9CFF2BE0CAF2EC5E843D0F8
+:10AA300085C0EBDE8C964ADCEF22C9DB131CBEAE70
+:10AA4000CBC4BAB83ECD6E08CBD718D627F8818EC6
+:10AA5000BF978F5F5681FCF32F4CFF50BE5901FC0E
+:10AA60000B760BEC438D962CF60C5FFFCFA8EC8099
+:10AA70002FC52383FFA5EE08E80101B7E1F0CF3F22
+:10AA80000D3EC7627D79DF330AECB32901DF8632E0
+:10AA900053B15FF691682AF8B5BF4C677A6D6FEFD6
+:10AAA00054D74CE08B853602220CF60DF66AB9902D
+:10AAB000B764D70B5576FAFB5099CADB00E06148C2
+:10AAC000FE469DCE58FBAACC5D0B3A689D2F89E2CD
+:10AAD0007F12DAA14E62F027BE9DC1E4584598C4AA
+:10AAE000B55B966532BB45C0FB7B1BAAC97B747FF7
+:10AAF000CFA533BEAC18D025C08BE06BAB9C7A8859
+:10AB0000E3F17BFCFB8F9753D269E4D4222EA7D8C4
+:10AB1000EF07A9990FEDB2B2A22512D589AB5E98C5
+:10AB20003A1EFC995B72E4C0FB94AF9648EA981F0A
+:10AB3000D171EB9C018C93093AA923CE801BE04E86
+:10AB40008DA62F41EF2F746119FE805DF269B7C4A5
+:10AB5000E89004D2EA4A12CB21B18E5B72149C6F4A
+:10AB6000D5E6F16961E3FAB89EB83C29FA2352347C
+:10AB70009CCF4599AE7FAD4D36D4BB993EFBD0A35B
+:10AB8000FD3483E2E15589D4E37A2CF6D26F78DC88
+:10AB9000C66A2FD5733BD20FE625F2B10D9DD3ECDB
+:10ABA000AEA408615D74F053B37B09E7D7A8ADC9C3
+:10ABB0004007BFCE286076ED15B4F202CA94CE6A83
+:10ABC000ED7D831C7B1ED6837A213A0DF8F4A50C0B
+:10ABD00062B2F31AE4508104766B76920A7286E2CE
+:10ABE00009E170D045EC2E3AEF73F40B78AB916F1E
+:10ABF0003EE0F0011D486A3B427F07F75B4914F4D1
+:10AC0000CDE57353D06E25A76E1D07F10A7F0AA309
+:10AC10005B3A8E938FE3443AE172EF376327F68015
+:10AC20007E12F253E0819C92713C517F505A54E065
+:10AC3000A5E583FE734BDB25B3FD03F650CC7E5AAE
+:10AC4000BF793EB597A6D7F6466D5E902AB72FB866
+:10AC50009DB6AFA1F6938BEEE78F194C0F1E0CEA51
+:10AC6000722A8C379EEE83FE7428393CA9C51DC319
+:10AC700007B571C280BF2C857EDD8C3FE0DB99C9B2
+:10AC80009091E163DF06FECD4A65ED87E93D5EAF59
+:10AC9000490CDE5B2A999CB0B6B3F171D73AF5DA6C
+:10ACA000AC42A37D1522408776C2EC2C19748F1F0D
+:10ACB000F519C2ABFACE8634D09B9FF52D4D239368
+:10ACC0006272D4E1FCEDD8F7A91C899225DF017EE0
+:10ACD000555E9709D8CB7738185D2AE9616F06FD74
+:10ACE00066A6C4F79B27F2F564825F4DDBDDC3FDEA
+:10ACF0001EC717E7A3BF9D9FC9E245A9397528D78D
+:10AD00000196018AF73432A87B0D784CABB099FCE0
+:10AD100007C71793B1FF99DB0FA509EC873293FDA5
+:10AD200020E6B5DA116FB6E6E0FA45FF1539AFD582
+:10AD30001043FB9564E00E186FE5FA7C53BC289134
+:10AD4000FD3137531AB217F4B8EB524CBFBF49FD6F
+:10AD500045DD38FF31367F6CDE14CA70B179E54CC1
+:10AD60004DCB44BF6F96F7E8F9F4E3A2BFCBA877C9
+:10AD700050FE53FDA4ED70A35EAA05B92DFC24E09E
+:10AD80007F6F1AF077656DA6DFA027793FAB3C3A5D
+:10AD9000C0FDEA035CDFA41D117663724092627A03
+:10ADA00067B8DEE276B1453E9ECECEA674AB1BED13
+:10ADB000806178CEFCAAF6655102FA98F00FB12FA7
+:10ADC000CB6785E512909FB512194F3FD3E799F5F0
+:10ADD000BD9EC9FC109D329CD16F59DC606ED701BD
+:10ADE000EDFCF04D1995DF62D447920C728F8DD730
+:10ADF000CCE92178E2552540E57094DB43BB7CDA51
+:10AE00005D40171DC9A993414F74248F8D405C622A
+:10AE1000C7FF5617EFA0EB1F7CD9A1F6C0B0FB18F7
+:10AE20009D542E5FDF6EA7BF3B7A256F1289ADD38D
+:10AE3000BD41D256533EBE9FCB89261FDB4F932F79
+:10AE4000AA8CA3F3E735B17514F41E90EC0679577C
+:10AE5000D0C8DAEDC87498F4CFA350A6E33C22FC26
+:10AE6000111269AB2983F69A1DCE41F27A258C0F17
+:10AE7000E7B55040507AC853D9F86E35225D3B296A
+:10AE8000B6DF2EDBA249A027BAB25254D013277DD9
+:10AE9000E1C760BF4DFDD128806B7A7F9F1DEC3DDF
+:10AEA000975FDB0DBF8B7D06646F1EC8D9947EB69D
+:10AEB000BE6E0BDD1372175F570F93BF32799E0082
+:10AEC0005E4086D0F9B23615A39E12EDB332B8DEDD
+:10AED000C822E127D0CE225D04F146701F599B267F
+:10AEE000A0BD2FF01AB3AB264E01BBAA686BD4BE2F
+:10AEF0008AF67BFAA1F8F1FA17399FD07D1C34EE5F
+:10AF000023117F08BD26DA3912F8D582EE536AE3A1
+:10AF1000DBAB5413607DE572DF95B0EFA60E8524A0
+:10AF20004931F8BBFCA12320B7F27A7748001B2BEC
+:10AF30009D7564FC50CAA7FBBCF546E29549E275D5
+:10AF4000376D90B5D5467EEE5018DD28E6F33DE12D
+:10AF5000677CC2E305B3FDA163008FE67DDB14C00F
+:10AF6000F38D3BDF51463AD7192DDCA446E6BF34BA
+:10AF7000D53B23B0DFCAE576C4E39A0E2502F2A9D9
+:10AF800069F79EA80DECEC8D4405FE6FEADD732891
+:10AF90008FC227BF499B260762E3E5374524584FF8
+:10AFA0001625C63EF4FFA20AE86D2B7D839D0CF6A4
+:10AFB000CA2117E3FF0F2BDDBA44E1F8A123DC041B
+:10AFC000ED3ECC4D51F5600CEECFED99FFBC4459F0
+:10AFD000DCF3445214BE5DB69E1C276DD7759EA24D
+:10AFE000023DB9FC618F8FC229C31EDA0BFDD37DF0
+:10AFF0001EB58DF60D249129A8AF470987E916BA29
+:10B0000098BE91F1CB5C5FAAB003A7805C3AD7E70A
+:10B01000117614CAAB430EB68F0EC2D6DB99A915B2
+:10B02000C07A883703E7CD6B8A4AE00758E78DD1AD
+:10B03000955688ED47BDCE5E05E4FC1A2E6F2A9723
+:10B04000EF94DE33D041A98F9DCFE6EDDE21817FE5
+:10B0500048EBDB6A7CD89E2481BCD9CDCE29D6D0E2
+:10B06000FAEB0CF245EC238E9CA980F5B9FBFB9E14
+:10B070006572268AF427D66BC5E73C1FB3EF2EA274
+:10B080006602FEAEE8C5013ADEA1C2641C4FF0BD07
+:10B09000954FE7F9189DE7D5EF94209EE04B61F6B8
+:10B0A000A4589F68B7CB5755EB4338F4211CD6D62C
+:10B0B000DB116F623D354A681CF865CBF878CF5CD0
+:10B0C000F1963240CBF7FDF415A4C7B5DD9286FEAC
+:10B0D00042F72BCA5288DBE9FF2E439CF61266A288
+:10B0E00090ED3F7905F5CA257B59FC60EDDE3DF614
+:10B0F0006BDD313A0D9E786625D0D9DADE24E292F6
+:10B10000007F01E4532B9D523983744F7405CFB9EE
+:10B11000A89CD451AE927010FC1421873B397F1348
+:10B1200037FBFD46BE6E316E4C7EBA90DE8327A69D
+:10B130003CE3A4F05CAB4AAA0BF891C39B8E1F457D
+:10B14000394C4821F86B627C2BFCFE99DBED71F0E9
+:10B150007C1BE0D9AA4F849E0D3E5C45E02BF06736
+:10B16000E7701FD2EF3E05D7DBE1B3333D5FC9E2A5
+:10B17000DA1D0EA6473ADA9C11E0EBE7D22F7A5E91
+:10B18000A2F2D293A144E17BD0B6AA09EA0FE6B1BC
+:10B190007574D93615B7303D76870FF1974A987C8C
+:10B1A00062F2E8BE1F3379D2A4BBD17F6C0AD7AD5F
+:10B1B000C673099F4B857309127E5659EA89D1835C
+:10B1C00015BF81270E28015A7F492FE38318DC9889
+:10B1D000BE12744BE51CE2BD33539C5F868300575F
+:10B1E000EAD7B741FC41F8F5A90D21DD1318CEAF20
+:10B1F00099DCAF9FC6FD7A4785F36FEAD7AFD9F0E8
+:10B200006BF4836ECA7901BF825FA8FF68E2AB2747
+:10B2100038BEEFF731BDFA948FD1D59AB25EE4878C
+:10B2200035EFB7201FB96B993C71F79BE52021776B
+:10B2300073FB602B8E5393D27B910C7EF2BF4ADE60
+:10B24000769278DD37482DFF097932640FCFDF38E9
+:10B2500045ADFC720A571787016FF76B1FF3B73EB6
+:10B26000DC4511017C696F5146B2874F372E89BE8C
+:10B270002601BED770587FB8BBFAC23F409C7157B9
+:10B280001AE6B37CB07BC937FF40FB7FB873AE0AC8
+:10B290007ADAD71E42FA19F4BB54882752F1592B97
+:10B2A000517A68EBFD55EA4C382F7BEC8229203728
+:10B2B000DFE57C79E2C7F20680CFA67F7B7C0ED4E7
+:10B2C000AF894899603F7EB8EB5FFF0A7AB171E7BA
+:10B2D0003ACC4B6B7FEC976897DB223BD8EFBBD225
+:10B2E000D0CE3CFEC8B63900F7F6DE76AC3FF1C8EA
+:10B2F0000E2C3FF36F8FFFE22F60778452556877F3
+:10B30000E2C7DBFEE92F40E775A92AECA3296C67A9
+:10B31000E7B982BEAD726BCF01E453412F9780DE57
+:10B320000538D533F923E8F95D7EDEB4AADADD0508
+:10B33000F2ECDD2D9EC6787146C5CFF002B11894AF
+:10B3400063F512C6D9BA28D540BCA32B9954C0378F
+:10B35000655254C9A7F35CD1B0670EDA3DFA3BD70A
+:10B3600043FB25FB5C640BC6E520A84BFD0124755F
+:10B37000424AA8183C4AFD663AFACE2F29DD1EA69D
+:10B38000F201F58EC51F58D2F5C2FF801CAD730EB9
+:10B390001C0051287EEFE2F11BDA1EF54EF9FAF897
+:10B3A00071D254BF9BD32DD39B797B171504504E7C
+:10B3B00024A9E30DF6E998232D5B203D29AFB1EFD9
+:10B3C00022D8C7C5C5D74C45BA80F81FE81FDD8D08
+:10B3D000E3AF85F825E5BF73FC3C2EE225BE19746A
+:10B3E000FE1A3BF1B9E14BC86B0E94238FE2B8D43F
+:10B3F000FE40BB2AF0CB2B1E057B64BB239C3B0D80
+:10B40000C6E9E27A6B275B37EDEF8573543A9E7796
+:10B41000C6141CA7CF9181FD75D67FFECE3629B606
+:10B420005E4AA963416FC178656ED0337A3DE227E9
+:10B43000A0E0BE4E40935CDCF7E4152531FEB5C6B6
+:10B440007D409EC1F9F06C7F65857F5AEC2BE2410F
+:10B4500056786EE4F53FF36BF825BB324D7A2591B3
+:10B46000BDF2CC151F33FDFBB37750DE34031DC393
+:10B47000FCE1F74DFAF75A41C74FBD83747CED3EAE
+:10B48000A67F9BF7952A40B71FB46AE43D6A8036D1
+:10B49000F3F3D7EDD2C0F598EFF294CB0B71BD8FDB
+:10B4A000B9BE59B3F59DA3706E5AB82F17FDFC8F26
+:10B4B0009F72D5C338076D3684E7C19EF377B44BCE
+:10B4C000C67532BF80DAC148AACDD44E6576F0EA9F
+:10B4D0006DE0A7AD6D242AF07FB3857E9AF7BD821B
+:10B4E000F422ECE0E0C38B5733FBD3A5BAC08F9BAB
+:10B4F000C7EC5142ED51689F3E2FD2A6207D959614
+:10B50000037D3D73C52F3A418F37CF235E187FFBF4
+:10B5100018EDA97CDC8F4420CF65BBA3BBCA4EFBD2
+:10B520006FAF0978292429DC76A2DD4B8A15AEE7B6
+:10B5300056A3BDDC9C73958A7C6695074FB5A1DD4B
+:10B54000D51C48C6F55CB24FBA85D9236EC2D62F3A
+:10B55000217D5E12991981F8D9471C7E028E1F3B0E
+:10B56000FA56023C3EFE0925445A7FC93C46AFE9E3
+:10B57000F37A518E3CF7D47CD4E3822E3D4F26A142
+:10B580003ECFB07B2515F5DA9224235EBB1D4C2FF0
+:10B59000A5733D53B495E1B793F353A7DFC6BF8AB4
+:10B5A00039FEE2D52783DEFD88E31FC508C8772E64
+:10B5B0004FD6AE8E223F35ED66E3F992B4D25B0DE5
+:10B5C000F4EBAB667A519C07C0F9C0A238F2E231C5
+:10B5D000BE8EE0C3ABB681BD7C31C53BA894BC62D6
+:10B5E0002E47295D00DCF21A43480717FB6E5021F5
+:10B5F0003FD59F49D05F1C6C5348BCB8CFE35C8EED
+:10B60000FA3343651087F6677BD0CEF1CB953617BA
+:10B61000F42B95D49E009E7BA29D37E8CF557B4CA2
+:10B62000FC1E2AB3D176C7B23C0CCF91DFD8179756
+:10B63000001F06D8B816BB6FB8DFCDECC685DDFAA3
+:10B6400064F043C4B9868043A42DB9DE283F7FC28D
+:10B65000E11099C8E2A9D4BE77635CDB4BE701FF38
+:10B66000BE67E623CCBF6FC7760FFB997D5443F7C7
+:10B6700007769BBF28B49EE9538F1A0F1EB3FDC2F5
+:10B680002E5F590A7E65739D5B057EBBEF67D22AEC
+:10B69000A467081682DF1D5E8D7820140FC00F246A
+:10B6A000CCFCD2E69650243EBD2F42FE6B06FE93A4
+:10B6B00090DE310E4FE93DC2E89DE93FE1FF837C1A
+:10B6C00034E61D0A3920E44BB3323001E858F04328
+:10B6D000F39C810900B7D1CA938F1D94FF817F2805
+:10B6E0001C807F04BF789E667CB2A52D5009F55B57
+:10B6F0006A88B7DDA08FACFE12AC13FC4E21D74F89
+:10B70000FA42C7FD1007B0453B21BF42C8E1E6A79A
+:10B71000374F8897FF26E4B0D3CEE49B339212696B
+:10B7200037D0179CF979A6E017F3795236C48F8F7A
+:10B730009CF2BB791C7F74F91259A0CB41DEF4A4B2
+:10B74000605EBB881759C7FDD82F99E232C26F815E
+:10B750007307689F93C5F827258BF3679688CF46B4
+:10B760004CF41FB085DF813CA344FA4BF4FB5BC56E
+:10B77000AFC43C428F5AF12FCE4D603F8B26256ED1
+:10B78000D77D80C9272B3D4EE47C72147C0FDAEE06
+:10B790003FF839D770FCB2714878A2292FAECBB6EA
+:10B7A000A7315E1C4C9C779087268E2AEFEE402BAB
+:10B7B000CBAFFA0F9E674B564F34E559B9D5401BB6
+:10B7C000C451AB9CC15219E765712CCF1CF209E83A
+:10B7D000E1C9FBBA8B217FC91F329F9764D7279B92
+:10B7E000CE2372C319A6727E639EA9FD989642531A
+:10B7F000FD391BCE33D507F529A67251D70C53FB63
+:10B80000F1DD55A6F2B90F5C6C6A3F31B2D854DE57
+:10B81000D2D65B0F78397FD795A67E5576AFBD948B
+:10B82000C2B5A47795397FCC02CFB4BFCA71E9B055
+:10B83000292B8878ADB29BF3882FD8678607A4CBD5
+:10B84000019C27133EDE9C635346CA6F9D4CEC7FE0
+:10B850001E10FD83C3E9813807D4501C3F53D0B973
+:10B86000285BCFB584FC3853FA4BB44E417F89EA4C
+:10B8700013C1ED3B9CFF055C1C4370A95747828BAD
+:10B88000E3747021142E9EAF0E17EB789B529A3101
+:10B890004FF8352818ECE38156F37D98657A1AD372
+:10B8A00043A125A7B1A3591C389CC4CE2BADF5FFED
+:10B8B000C9E1F2218509E261947CFD16C7437F222C
+:10B8C000BEDEF0C9C16C90DFB504FD666F4BDB27AF
+:10B8D000A0B7AEB64709D0FF7D7C3FDB79BEE80359
+:10B8E000AD5E1CE7417E1EF9506B007F7FB8B51836
+:10B8F000BF9156157FEF69ADC0EF4E6ACFC1F70714
+:10B90000ADB5F8DDD51AC2763F6CADC7EFEED630D7
+:10B910005BD7307C9172B473429971E3A5D7E8F29A
+:10B92000A8F044E482B8FA32E13872C388F9E51B22
+:10B93000FAA5C79F35F0EF5B591EDF51C86D9C4ECD
+:10B94000A6C3F9E6E9FA7FDE4A1E7F76FCE8F948ED
+:10B95000D013399539211E5F87795EE563DB57DDAA
+:10B96000A54F4A0CAF189DC587539DF3E33C70D695
+:10B970002783CD60E82FEE9F88725D382DAEDD9075
+:10B9800097CDF46E7D123B8F5F6EE1EF6F6533FAFA
+:10B99000FD5636D377BF4B2067D2793D5DA703CFE5
+:10B9A0000787F1DD3DB3E3C1F7AEEC80292FC57AFF
+:10B9B0006FC53ACEEF1CDD63D4387C76BA71C4FE15
+:10B9C000ACFDAEE2FBFF663661EBFF7FC69FBFBBFF
+:10B9D000CE83FE03C0CD6FD8FFEFAE4BA98F179774
+:10B9E00069CF66E7A1D43A27C10C34F575056CC55B
+:10B9F000621260E7BEE3BC101F12790189E9D58E9F
+:10BA0000712484A13C1CAE141F01A5888E6F1F9A5F
+:10BA1000276A8779545B4CCF42AE0D31DCFF9087AB
+:10BA2000D303EDAF2B98D7339007EB3B537A22F239
+:10BA300043E3473AA71BD6FF0CE5CC9AECBFAF9C7B
+:10BA4000117C4E4EDD3B3E9E9EAC87B967507BEC31
+:10BA5000FE87989C39CDB8670ABF7A7900CFAF4787
+:10BA60000DBF7DBE51C5A53E77A54E26D4AFDBE008
+:10BA700064DFDB93537BE0FBB96B6C84A4527E8163
+:10BA80007552BED5AB08BBBFF596F09B5AA683BCDA
+:10BA9000DD9E1B7A309B8EB34A61FEE29FB2B4EF0B
+:10BAA0004339999F0B27F37361255BE98432D18A6F
+:10BAB000715F17F07D75DA0263615FEF4BEA44F066
+:10BAC0005BBCB6880ADF54122D61F9799130F86BAE
+:10BAD00099E72707C0DF4D9E40481FC6C75517C4CA
+:10BAE000D19494C117C701FFFFD286F7A21FF7B206
+:10BAF000753EFE403E9EB350818FF26232FC4EB7DF
+:10BB0000B205EC72DAFFFB52F8896CBAAFE35EA7BC
+:10BB10006EA3EB9ABCF9BD8C0CFAFBE3FBABF05CBB
+:10BB200021BA4BD615B8DFD0F7E1772FA1E35DD06E
+:10BB3000E7C0F8F3054446F9BEC64EB6021F25829B
+:10BB4000EF07DF889F07E6C8914CF95DD6FAF7B991
+:10BB50001EF82041BEF16BBC5EE4CF3844FE8C5F22
+:10BB60001B317FC661C99F71D84304CE851D43F93F
+:10BB7000330D04F367E838C6FC990FAAE2AFA39F20
+:10BB8000CB73C7172909C64DC5DF3F281C799F8E87
+:10BB90002F5CA67CEC587F37FE9E287FE73301A7F9
+:10BBA00004F94B9F0CAD2F97E899C67E8CEF62F39A
+:10BBB0001460BDC3920714AB67F93F1DE98C4E0EAC
+:10BBC000E4787DD7D0A1AF2103789FF36AB7CF0186
+:10BBD000F1A41051F7E0FD1EBB637040F06121B489
+:10BBE000B3BF0B76B78D4A5EB0BBAFDEE07877C0EF
+:10BBF00020B71669E63281F60639BC1862D8741F80
+:10BC0000C9E71563FEDFA72490E61D418E3638E5AF
+:10BC100090DDB08FFE0476C4859C0EFB73E3C3AF4A
+:10BC200030C766CA631ADE9FE703F07B68B77A47BE
+:10BC3000969F00DF70A6717C2B1E7C587F3A38FBE4
+:10BC4000E1B00DE26A9512CBF3FF9BC33B9DE7BBCE
+:10BC5000B1FB030E4BBEFAE25CEBBA59BEFAFDE94A
+:10BC6000A19939D82F30C1785F60AF5D4B9942BF41
+:10BC7000FD5CEE58E1B289C3D9BAEFBD3CEF3E5945
+:10BC8000262D7B0CF0B7EEF71B398CCE45FB0E074B
+:10BC90003BCF02C1E7A4726F0561726F454E21CFA1
+:10BCA0001F4FB703BE1AD8106485F7109E2F0938AE
+:10BCB0000F831F87BB158E21125809F9DDA783E773
+:10BCC000865C6D450E9DF79A57921590FF2B9D83CC
+:10BCD00007C1671DE8B31D1E47BFEFB8C71DDD498B
+:10BCE000E03CAEF8C967E837B542657915641EDAFD
+:10BCF0003F929E2F7F79FEE8ED9FCED47031F0C742
+:10BD0000FB3C3F5BE8A5CEBC131320CFFEBD8CCA25
+:10BD100029B97E8CC36B9940473F4F6274F4001D74
+:10BD20008996D7FD6222DE87BF2A37AC423B91E776
+:10BD300047B4C109909770A670A27F1C4047A783A3
+:10BD4000D39A1CC2F831353E9DF4E4B0F8DFE9F82F
+:10BD500003EFA195FDFDF843C0539C6388F5A9B995
+:10BD60008C0EC557C0CD9A4FA4E6DA783B96AF78D3
+:10BD7000556E08E17C72CC27475D74EDFD4AFCF7F7
+:10BD80001D9E1CE5FE05BCFF5E72B83F39FEFA5EE3
+:10BD90004CC0C7FFA8F54DCDE5F43339FEFADE1EE1
+:10BDA00025FC4264F0ADF4BF831EA3789E0A78267A
+:10BDB0001D83281FFB33E2AFF3AFA35E67D8F1F713
+:10BDC000D0B782BE897E4D239EDFE724C73DBF5F8B
+:10BDD00046FD29F087ACE7F8E2BC9ECA0FDC6F9DF8
+:10BDE00073706526E07D1EDF771689A6C3F9E62FFE
+:10BDF00092F03C60989EE4FC41E195920BFA64E17C
+:10BE000020C635FA27C4970B29B98CEE86DA77B1AC
+:10BE10007912DD43C8CC9546750F819485311E5843
+:10BE2000E97447658A875B383E94FC9B54B00F2BBE
+:10BE3000735E3A02FBA4F0FF70089E86FCBE13AD51
+:10BE4000CF7BC73912CBED35F213E52D71F63321D7
+:10BE50002B3C21D7106F5CB3EB05EF3803BE4AC80B
+:10BE6000808DDDA31EB499FCE46C72467EF27E17D1
+:10BE7000E397F73242A80F403F80DEE97CFAC252D6
+:10BE80004026D81990DF33E8494639DA9E37A3387F
+:10BE90006080676DAEB02FE50476E3D7BB1F10B3AB
+:10BEA0009B2493FD1A1BDF8EBF0BFC54BA5F8C8B57
+:10BEB0008F0959DAA500CFBF646897C1D70A3FFD43
+:10BEC000CE59E978FF00E0373736DE10FE13E0F98F
+:10BED0001B595A3DC04DCD0CB0BC0191D73714BF92
+:10BEE000B07B8F3A63F01E2D5E92797C8DDA0DABBC
+:10BEF00061BD4A12E747E2C67BE4C26E2116FB86AB
+:10BF000014337F7745CE4BFF03F19FCE54C6B29DCD
+:10BF1000FFE4423FF06AC9ABC0BEA9FDF1E6F76994
+:10BF2000FB3089BEF92DF40F859D91227F9932FA5D
+:10BF3000750AFFF97479D6CF803D46D7536573E310
+:10BF400079E733747FB9546E5429EC5B399F5215ED
+:10BF50001DAF4A2ED83F40D7F51939953C9B7EBF7F
+:10BF600043181CD6BFF2870CF047ABEC8E1346B9D2
+:10BF7000658D7FDC956B8E7F7C4616FEE67C80CBE4
+:10BF8000AC0C84CBE4A7E6651BE32F43F10FBE8F17
+:10BF900025FA354C9E5AE49C906736277B6F84685F
+:10BFA00024E0CDC2381283BB2EE1FB57B345199C68
+:10BFB000145A9EC59124417FBAEFD9FC4B56857324
+:10BFC00040CE405A0FCC47BDBF1CF8B65FA806E074
+:10BFD0003B570AD9D93A222C0F91B414407B9B735A
+:10BFE0004086F945BC02579205E3887959D9C3CBFD
+:10BFF0001D759FAEBC2E303CAE41DC1EB47F15BE1D
+:10C00000BEE35EB76E33C43B92DCD1E398BFCABFD8
+:10C01000D6B8C7EDB2AE43FE7632E94579E9767F10
+:10C02000A40330BCC42B41F9FB52F8E7C017479575
+:10C030006E12A4BF9FFCF9E704DF65831B6245F025
+:10C0400035EB27BF7B3DE645FB43768B5E0A4BC055
+:10C0500047D9F5D6DFCDFACA49FAF1FE90140DE5BD
+:10C060007C9979FA784EA2388EA38AA17EF0466632
+:10C070000F1F4E66FD0F27B37E6F71BDD49CA110BC
+:10C08000CC8BC9723AC19EFFD8730CAE6C823EE96C
+:10C09000027DE274688857A157D6EEBD9900DE9AFA
+:10C0A000F72D4238FC5E62E7A4FA0A09F319C4BB13
+:10C0B0000FF593C8CBB4279991C7FC94A5CF8757A8
+:10C0C00034D172DD4BA4244ADB95CE0DD5C0FB2EB6
+:10C0D000ED2544DD44CBEDAEF08F7E02FB7885BDCF
+:10C0E00037B68EDFABA59858B39B8EBFE3CA31EA53
+:10C0F00016D852F56027E40B0D6E265EC82F194640
+:10C10000BFA7283F507A7804CA74DDEB5687FFE555
+:10C1100036DA3EF725A2621B5E0F3E0AE04FE2745C
+:10C1200001BFCFA5BFAFE37454B45F62E7FC3EF636
+:10C130000E180E0EEF7439D9FFAEDB5F79F934BA01
+:10C14000AEA2BEA948DEE3687BC883824C04D69EBB
+:10C15000D8E2B51F07ED0370AECFF043F2147C3F79
+:10C160008970F937DDC2873363FC80F5A5BCBC8ECE
+:10C17000EB2913DFC038D46FD7CAD9B13FF6F331FA
+:10C18000FE5089F8C3F8790689FD8171AB63F3A08D
+:10C190005C9EC7EB0E2E5F80F9DFD3EDD103C0EFBD
+:10C1A00033F9B7947F81DF9D148E57D85B0EFAE97F
+:10C1B0007ED23710B50D666908B4C37865242403B0
+:10C1C0009CCBBD9BDB617D1736BC9209F475735E19
+:10C1D00011D2DF2CA75AE4A224D25EA1AADE2278D3
+:10C1E0006F4C42B82CAD774620CF6DE9D07B3FE154
+:10C1F000E032CA3F5784257E0F3F1C6C30C46D452A
+:10C20000FEDFB224EA5FC791DF37E731FD2EFAAFD8
+:10C21000E3F75344FDDA3C37CBCFCCBB68461E9ED8
+:10C22000C7B0BC68CAFFB3F3A6C5E40A9D17F356AE
+:10C230009610CD01FB5AC2F957F0FF52ED56B46784
+:10C240009786CC76E9EF25866F7DB98476E215F581
+:10C2500023DBAD0BF3C4B9708117F500117A8AD1D5
+:10C260009590E78B41BF831CAEA5FADC603737DCC5
+:10C270007E2A1DFB65FF60ED97E7C4EEC3ACB3DC1F
+:10C280008769E6F761D6ED6B736401BDF3FB30EBB4
+:10C29000F6BFD369CC0314701A7E1F6610F31F9784
+:10C2A000299103704F68D94D748FB4FDAFF8FD89A3
+:10C2B00067E1FEC494181D79AE7445597E9D867958
+:10C2C0007E05DE1415F252BA6C5330AFA82BD5A3FD
+:10C2D0001AF378B6B4B5D4403B914F24EEBF2C4B43
+:10C2E000706EFCCD3C663F6F97585E97BEDC89F060
+:10C2F000F6CBE488F19EBFBF2884F97433F202388C
+:10C30000CF761E5F80FCD3A9F41BA1661AC317EB7E
+:10C310006F950F74BC0E18AFBA48C53C9AEA3496B4
+:10C320008FE6CF0C95DE3229366EDD7E96BF57172D
+:10C33000FAE410CBC35D5406F04C24D7ADFA8BD28F
+:10C34000DF3D408FC3F556B819E8CF51155A7E1D11
+:10C350001DF7E4CB0AE6DB918D9AE4A0ED7EFC822A
+:10C3600057857B781D95A14535586FC77B8259F558
+:10C37000249A44EBCB5E527A20CFAF91742B304E8F
+:10C38000A3458FDDE47E56013EBD69A72346970491
+:10C39000F213D52210784DBB87C545500E09F964BC
+:10C3A000A56732CE2C874A85DCA5F281E5F73530CA
+:10C3B000BD477E20417CE8A4E798CCFD6B947BD3FD
+:10C3C00084B0B2C8FB69FB9F437B46C0730E9517D0
+:10C3D000E0C749F0FB64EC87652A4F8B21EF742698
+:10C3E00049467A1B6647F0F5950DAD9FD94D424EF3
+:10C3F00056561002EF2358F143E7433A17E77D7092
+:10C40000B402E70833F9FC9FDBB449D120E08B4448
+:10C410006C14CE9D520BEA1D27E481D2EF16298CB5
+:10C4200072F1A7BA2E035C2F242D4B160611EF2FA5
+:10C4300001DE6739FB52000F4715D509F5359030FD
+:10C44000885F33BEE6BBEFB303BCE6E758F1A2DB7F
+:10C4500001BE0B02C3F085F70BB404F8D2845C2153
+:10C4600066B91224A7D8FDE6CD876E03FFF874F6EF
+:10C47000C9F7B2C247E3D1AFB05312E5E59DE4F28C
+:10C4800078B47979271DCCAF984106AEDF2D0DA782
+:10C49000938F0F6E90730CF424E8F4699EA72FFD20
+:10C4A00092E7FD967950FFC5F425A383725E9A0149
+:10C4B000F465A083D9FB5C5199EEB394F79F01F426
+:10C4C0003025A62FA33677402904BCAB5DB23CDCF7
+:10C4D0004ECECA0820FEA7DA34C4FF34EA8171BB0D
+:10C4E000D39D4FF75FE1EC6DB70710FFDF07FFA6A5
+:10C4F000920410FF9516BD53EDAEB3039D543BADB2
+:10C5000078D610FF35DE61BFDBBE0AFECF01FC0B23
+:10C51000BD320AFB94E27F42FE08E78D89F07F413D
+:10C52000BEFB8CF23205FEAD781772608FCB5BEDEF
+:10C5300086787023CB4B9EFAF2B8762867AD0DE271
+:10C540007D993DE9EAAFB0BE85D597F56932BCCF9C
+:10C5500058B49ED6D3F29E60A81ACAEB3648284734
+:10C56000A7BD166E87F2B88DACBE7453CBAFE09DFD
+:10C57000B3753AEBFFF4F14E7CAF22D2C9FB57768C
+:10C580005743795D17EBFF478F5307BFBCFC48A4A7
+:10C590001D7E9FB895AD43D87D7339BDED919EF852
+:10C5A00015F6EB66FD6E38E44C66FE12B3E3E6F07A
+:10C5B0007DCE7D88EDD3F7DEC5B5010AF7EB0675B4
+:10C5C00007CA0D5B5339CAD1047E5AA5D45D00DF7A
+:10C5D000F9544E10C43BA5D34296B7DA43A75893FB
+:10C5E000CFEC2691EF0979E78B0CF85A93CFFC0832
+:10C5F000D12E2B83B0FCE407D9BBB3221F357A3F81
+:10C6000091207E007B44FD9B203F757E510BEAD339
+:10C61000F9E788BCD401FB2A3A6FE9977FBA289ED4
+:10C620005F7E4B3EB3938EF13C7AF17B63246803CB
+:10C63000FF640F100FBE03147D19EC963DF0BE9100
+:10C64000E11D923D4156D6F3F7DFDD459DDC1B6CC5
+:10C650002D761D94C05809DF55B9AC8F44D352874D
+:10C66000AF7FBE9D4459FE045BFFF5ED4ACF1683B4
+:10C670001DBF54888F59E351AFD4713C09B9B194AF
+:10C68000E38BF2F9E67CBAFE65CE16B41B9713A6CF
+:10C69000D76F24118C6FDC68E1F335EE3FBF65B3D3
+:10C6A000411CCDCCCF6BE972D8F9FAE0C3BFA3F03F
+:10C6B0006F7CC0E305FDBFB6D7DCAEF181978F304C
+:10C6C000FBCBCCEF8D82DF23667EA70605E3F7FB6D
+:10C6D000CFC3731B713FD0E51C7C4B27B1FD0EE926
+:10C6E0007D0BFFB9E0BE6031F8353696A7C8CB6246
+:10C6F000DE4FBB995ED6A95EE67E108ADC4FFB2F2B
+:10C70000C17CF852A147B99C11FC5CCAF5FC303DD4
+:10C710005E6BF577EE433E99CA4B56FD2DF4B6B8E5
+:10C720008748C745FD4DF5F5CB1A5D6F9FCD1D01BF
+:10C7300078C7F47604F9688A93CA6B1BE2EF00E0CD
+:10C740006F1AC75B3BD7EB09FD03F7FAB8FE01F59B
+:10C7500037F01C61B85F1035D9FBC3CE3112D8FF5A
+:10C76000437873517B2A05FC7DC2ECE23C32AA3C43
+:10C77000112AB7DFCC1F416F2BCFB0DF0777B8305E
+:10C78000BE20E2EC82FF5E2F6076F8B65CED3D9055
+:10C79000FFFD7CBE7E3E7EFFCDF3F1FCFBCF44C3AC
+:10C7A000F36FC867CA8F937F01E7DF1D8678697FC3
+:10C7B0007AFC38F8275CFE941610FCFEC9AF7D0A9F
+:10C7C000EB3FA6B038FBB164FE4D65E714FF3BD4E8
+:10C7D0009EC98F4CFE15EF911FCB30C7E7453B3FFD
+:10C7E000FFBEDFEA0C7518E2E181FB935A408FF936
+:10C7F0008B785EFC7A46C7279F4ADF617C272E50E4
+:10C8000050595A300DDA694A2EC4679E62FAA2D98D
+:10C810003EA0C0FB3E3E7F38A5C00FF79B88F604C4
+:10C820008C1318509650789FE4E7FE27F97B402739
+:10C830005DEC2BD6152858540AFD4EDE3C80726301
+:10C84000A8BC6800E542A02084F39E5C2AEA79F93E
+:10C850006E5626DCAFACE47C8271E33871E2E171A4
+:10C8600061F37B37EB94F8E7D5A4C0638AF7AED8C1
+:10C87000CFE2902B9DA4339FD65FBD3F1BFD8DC69D
+:10C88000547D02D0C3D78DE39E1CD387FBDA523987
+:10C8900038F6C1323C17C678D1DAFDCFA1FC5B2B4C
+:10C8A000F866AF996F66178CEE3CC51A671F053F97
+:10C8B000CD2F18C10E7A12F4972386875B787E53AA
+:10C8C0008DDC540D71A54F5713BC677BCB0B32D257
+:10C8D000D52D3F92F0DD0961C7ADE5704EB42FB89C
+:10C8E000A71030C815B8A71030F875704FC158861A
+:10C8F0007B0AC6F6704FC1580FF7148CF5704FC104
+:10C90000582E25D7B6439C6E5D17F14602ECDE82A9
+:10C91000B13FDC5B3096E1DE82B13FDC5B30963FBD
+:10C92000250C6E9F3E2463FC1FEE2F18FBDFF0C228
+:10C930008FCBA3B06D17CB536B7751F8031DEA5A19
+:10C94000DF240A9FD51C3E70BFC138EE07A9173DF2
+:10C950000FF859DD77FD42F85EB0EF26D3B8A49BFF
+:10C96000C9E316FA17E0783D09A5813F37850C1E0B
+:10C9700082784773445261DE1B1E30CBEDA1F74C29
+:10C9800022E6DFD71043FC37383CEEBFA5C0E343B7
+:10C99000BACA2379C6784F8C1EDC6A14E0F09AACD0
+:10C9A000C6A38752726E1AC6799E97218641FE48A9
+:10C9B0005AB6CF920CE703167824E598E9C21530F1
+:10C9C000D3454AB1992E3CAA992ED22ACC7491AE65
+:10C9D0009D37227C336BCD74B2466E42BE1770AE6B
+:10C9E000A07F01CE53E0854A802FDD27C48BADF0B8
+:10C9F0006DDCBFAD13ECFE3385EF9316F87E466613
+:10CA000055BB03585DE72C8FD93165CFB7E021B016
+:10CA1000357E2AE028EC081107A5FA1FEDE9985F9A
+:10CA2000CFFC3D6A1F1C2CC0F303E6E7012581DC27
+:10CA3000BC8E84513E5D67B10F6E70DFA7807D3084
+:10CA40006CBFD43283F70BADFB057B8B18E25256DB
+:10CA5000FB40DA2F453D9361BBFB859C0E7F89C669
+:10CA600090268D466EF47AB4FF02B9058EA2B3DC2F
+:10CA700014378E6BF7897508B888F993488B9C0337
+:10CA8000F45C6CB5CFCCFEB5F0C745BC5DC4B585D4
+:10CA90003F2DFC182B9CE57382ED40FF53BDC28FE8
+:10CAA000EEBB0A7E17FEB3D56F1DBA170090857BCB
+:10CAB000373C4E7FA77F9593BDCBC7F84EFCDEE990
+:10CAC0005B9C36523EE61DADE67B30741BDA88F780
+:10CAD0008A00645970EE4420A842B65E7A6800DE8F
+:10CAE000DAD97AD98B83CFD2EF96921F0C6C82BAA7
+:10CAF000535FCA00D7A1783E61F78415DE4F29E85D
+:10CB0000BC19F468B26A27EF1AE8C24935D5BBC52B
+:10CB10007C5ED0133943F5BF319EEBFFA3BE775146
+:10CB2000F8BC3B7E847A456D8C67D759E1259EC35E
+:10CB3000704DBAE838D8272E62D837EA4343598E69
+:10CB4000C10B55AB8CF7A644BD06EF977CDD7D018C
+:10CB5000DEDF7518CBD157DE7718D71F617905F660
+:10CB60001081FC5BC547EB8DFA65880E2943951B48
+:10CB7000F6378A7D01D380FBC9EC1286EFBFD5BEA4
+:10CB80003A2CF88271435967F5FAF4B37C7DD1B33E
+:10CB90001CBF64D1D90D3F6DD1D90D3FFD2C5F5F16
+:10CBA000F42CC72F597C76AF4F5B7C76E3573FCB95
+:10CBB000D7173DCBF14B969CDDF0D3969CDDF0D39F
+:10CBC000CFF2F545CF6EFCEA6807BA2BA204DE97D8
+:10CBD0000874103518A0262BFD19FCF92295609ECB
+:10CBE00006E17E4921F74BB66D6DA90717EA115D85
+:10CBF00009603C88FAF739B47E2261F58F742DC63E
+:10CC0000386BDB980979F05E95BBEBA2E3707F6F20
+:10CC1000A2CEFC71EBBF1BB64833FFFB6B9757648A
+:10CC20009ACAD3FACCEF575CD55864AA5F1E3EDF90
+:10CC3000F2EFE74D35FFBB64A19996F7206E26C64B
+:10CC40007B918524AA427CA5F06E5B159C9BD9C183
+:10CC500067BE90FEB753C17E1AFD6BF45F0AA92729
+:10CC600034347E10E0A698C6775BEACFF41EEAFE65
+:10CC7000B1F1EFA112786432CEBD736B1E26B1DF25
+:10CC800088F13981AF3B37DBD0E5FD6C2BC1771ED6
+:10CC9000AB23011BBE83CEF1763E273DB1EF48ABFF
+:10CCA000F93E7AA14EAA009F451DC406F1B5E04E9B
+:10CCB000A26A04E34248278FE8F1E9E411E2AD8279
+:10CCC00077B91E8910FC77B2045DDCE908E4C1B9CC
+:10CCD000DAF95D8C1E049D04804E52212FC8FAEEB5
+:10CCE00080155F644A94AEF591AD8519C67C54B247
+:10CCF0009BC1DD49FF8E84AFE29D667C0588A1FC67
+:10CD000015F0F5E9D7C497E20B45D37C10CF240189
+:10CD1000C8933A3866820DE011EC52D1FFAFA5CD31
+:10CD200000CEC12EF69E9AC093186F6B2B89CE331E
+:10CD3000F87F4135AA019C6BE44955907FBEA30C56
+:10CD400043C6C3F0B383789321EEBDA3CB968C6F1B
+:10CD500054EFA3782921E4BF372F4B2BA6F53D4193
+:10CD6000920CEF6CF5B4D9F0DDB29EA7A47AF3BBB8
+:10CD7000CAD1245B0EEE23C956815F3BFB6AFC4B94
+:10CD8000ECAC3E2A4379ECC661EF7EC8509F5E6BE7
+:10CD9000F97703892641FBE473581E679A667ECFB4
+:10CDA000C651619607148C7D39E5106FE1F4CEDF32
+:10CDB000498DD490C826BAEE73B8DCB1D251FA1DB1
+:10CDC0008B9198DAC67C03E5594F9B82F077707996
+:10CDD000453632BAD0E95FA0A7740B1D7954331DD4
+:10CDE00039E402CCC3157C25D623E66F1B93956CE2
+:10CDF000C775D9F13D6C87554E58D6E7866020C57A
+:10CE00009DDB4722115AEFD0197F10B91F7F774C55
+:10CE1000272433F815D6F935E553E89CBF8D7CF20D
+:10CE2000F031EF9CC6F6F999CADEB5AEEE60F4EECD
+:10CE3000D9CAE81D6E74B37C2D6D61AEE15C752FAF
+:10CE4000975356B879FAB46AA0E78BE49734C88F41
+:10CE5000B8FB3546FF6D630E3F0FE5AD7733F8073E
+:10CE60005586674A2F6A942EFDEE3BDC98173CB539
+:10CE70008CE20BF0FF92599E4CEB33C3B1C82237C2
+:10CE80008209E06AE5D74470FD96806B39856BD1E5
+:10CE900099C355D1997C4E9FC5DE593C384661FFF8
+:10CEA0003EAFCEE098AEA9287F2F924F45D368BB06
+:10CEB0006D1A9537749DB51A83B7779690E36678A7
+:10CEC0000AF922E05FC8E1EF55BD2FC0BFF3E2D6FB
+:10CED000ED2420017CFF5B033BA27B9A9037830407
+:10CEE000F096A631BA1570EE9ECDE05CA871387749
+:10CEF00071B8494402385BE9D52A9FD3BE269C7796
+:10CF00009DC3E3F159A4FCABC0795B0A7B47D931DF
+:10CF10008EC1D5E11E8C829CED0ADA715F07820A10
+:10CF2000D67795B0FAFB5356E680BEEDF277E60071
+:10CF30005DB605AFCF01F9EECAE1728668EEDCF2AC
+:10CF4000D8BD831A792BBE43DA1950103F9E407C1E
+:10CF5000F995362BECC47926D9898C7078488D07E1
+:10CF6000076799629297F98D66F8A658E0EBFA9AEE
+:10CF7000F2E1B5AF291FEE216CFD778E17EF347407
+:10CF80003B513F55DC8471F34C3ED7E685DF65BFEE
+:10CF900073BD66F8BDB610E489DBAE023C13ADBBD1
+:10CFA000A795F0F75A9CFCFD16F6AECB3678D785E0
+:10CFB00096BF03EFBA2401FDB3775DB6C0BB2EF474
+:10CFC000DB05EFBA9C0BF6B4865FF9D2427C7FF0AA
+:10CFD000B35A82F1F14D297F25F1E055D465D67F12
+:10CFE000413DD9F20E9B59CF65CCCB3395BDB3CC27
+:10CFF000EFB67954F66EDBFF0164680340008000F1
+:10D00000000000001F8B080000000000000BDD7D09
+:10D010000B7854C5D9F09C3D6737BBC966B3B9924C
+:10D0200040124E42081B0861810483829E84406343
+:10D030004D71435151A88D40314248285E1A7FF509
+:10D04000C94282841834A0585A2F2C378BB56AB441
+:10D0500051A922DD2052FAD5964551F152BFF55221
+:10D060002F40258A177C3E5BFF79DF99D93DE76425
+:10D0700013C0E2FFF8FDF1C1C99C993367E6BDBF5B
+:10D08000EFBC332184906FE8BF04CF0412F410FC8E
+:10D0900081BA433D9704EDD1FA23C3EB1C6A3A21D0
+:10D0A0005677A5E139F1F7115F22562D248390546C
+:10D0B000DE365DBED71E2E26644DCDAC24520CFD4F
+:10D0C000B450266D4F80469590D5566F968F3E4F43
+:10D0D000A85954435C84AC6A2124388A90F6163BE4
+:10D0E000962B726CDE601A2177BE2C7BE3E82B3620
+:10D0F000CDA7B969FFDE9C5B09A1CFD7B80919920A
+:10D10000479FBB9711924F88423F20D1BA5233E3D9
+:10D110002352425F98B3849049D1F9ACA9B1788386
+:10D12000A584C4253BBDF07D52ACBC13A66D6EFA40
+:10D13000DF37F4FD6FE0E782681947583BAE13BE56
+:10D14000A3EAEA04BE676C6F7E537A74AFAE7DAC1F
+:10D150009A98F63E2CF61C72CE37322DE579497539
+:10D160004E5A96A71092D5FF7B5FB69047F78E4434
+:10D170008012920E653D01782A7CCCD5C9B3ECC4EF
+:10D180001985B378BECACDE01B27D1CAE4FEE3B649
+:10D19000015CE3A2758510AD1BF0915D1AB3BF2849
+:10D1A0002906082923A4B32578F03D6BF4B9730A46
+:10D1B0007DDFD9BFFF4C55C679CF55552C9D4A9080
+:10D1C000B869BF442F7D5F0717A77666DFA73FA525
+:10D1D0006974BD2E4E37E477920278B5F37A8254A3
+:10D1E00037572D037CF9081941FB956BA4AE987D48
+:10D1F0004F13EF49502AE41D41DF79AC74D3760612
+:10D20000522869BBDDD8AE6620BC705C25FABEF63C
+:10D210008D34F0BCBFAB12F0F8CEC841DA6DDE7AC7
+:10D22000E0A77ECF558B80635F1A859BCCD71B030D
+:10D230008E6DC0DF028EB293C1B14DCADB19A6FC60
+:10D2400066D55C5E8A115291A676035FB6694EE49C
+:10D25000CBB6B4EE5025AD9F28B57861A8C49195A2
+:10D26000C88F6D43F71D5E08709DB9FFC36D08350B
+:10D270002D5425E04BDB133DD5A12A9DBC11F88A26
+:10D28000E7BF778C7D20BC9296A917CF236E4A2AE0
+:10D29000CE21362253BC384656D9EB9C51FCD8E0FF
+:10D2A00017FA3C3E6DC64732E5FB78AF0E8FF0EFC4
+:10D2B0001B564778D0C5DBB26FFDB904449119E91C
+:10D2C0007700E6A3A8BEE8FCC8D9C717C94E43BE7D
+:10D2D000278A3713E4657F7AF733BEE7FD06E60B4E
+:10D2E000D66FBA5C93791585CB9A17987C241E2645
+:10D2F000176C7686CF354463EDD98A97BE41D664E4
+:10D30000AE44F9D1AECE6F07F9F979A685C8123CC3
+:10D310005F6F07F9A198E447BACF62D00743E6C42C
+:10D320001BE4FE9A825928CF069A67569DF1FD614B
+:10D33000F5C6F77396A518EAE23D6BE6452F55A5AD
+:10D3400046EBAB943A3BC8915B33D74B753AFA1E28
+:10D350005254F73AD0ABA8DB3267E27B7139A53182
+:10D36000E7B5CFA3BD0572A25D65F326EED870BE0A
+:10D370008BEBA1BBB91E3AD53A37F2FEBFE6FDEF03
+:10D380006D716319C167C13506BCACCEA2F29A8E2D
+:10D3900007B0D77FFF29B5EE73985F14CF96287C2E
+:10D3A00080698B175B805FC5386D59F90EC0DBFA59
+:10D3B000EAC1E727F4AAE867557CC44BDFB312A3A0
+:10D3C0001CB7A5590CF89890C7E5C6B66B0CDFDD05
+:10D3D0009B3C63631EA5ABF587648274F73BE3FA5D
+:10D3E000FAD3AB711DEB33D9FA07A66FD3BAA944B0
+:10D3F00088D011D6534CF5A1A6FEF9A6F6D1A6F613
+:10D4000009A6FAB9A6FE95A6FA0F4DFD6799EA5747
+:10D4100098FACF37B52F36B52F37D5FF8FB17F2983
+:10D42000C3F3F5E2D920F205F4BAB9BFA268885F68
+:10D43000A1E7237CE536F2E30F722AB43C66671855
+:10D44000F02BE8F374F1B39ACAB810F093A23A50F3
+:10D4500099962F267A7A589F998FFAA38D4E0BF5BD
+:10D4600037B75F52041D5773FB70CE12031DF5E6EC
+:10D47000143AC07E24CE34944BA7A20B89A418DBA7
+:10D48000B5A1D1F67CF8FFD9A58B53D37180EBDD24
+:10D49000C1E72DE4C023C37DD7223E02D49E1E1BCC
+:10D4A00085931AB1A7E9C728DF6D49238138AAEF10
+:10D4B000B6F82D58FF3C937E08EC952AC687237852
+:10D4C0007F42C2128C23E6D3CEE9651DC8295ADEFD
+:10D4D00001728A96B7B56462B97AAD256B218C5713
+:10D4E00063433CA58EBBD5AF4059595E04FAFBB6E9
+:10D4F000B13B340BAD279E94497022B5174AAE2834
+:10D5000087E5244C9F9FB9173EF735FDCE24E04EAA
+:10D510008246C6E62A12B08E2364ED9EAC1F7AE8DE
+:10D52000B86A81E275405BB177859286FDFCE03692
+:10D53000A84ADFFE11B43EBCC082F685B5BCAF057B
+:10D54000EC7731EFB53FA4844B3BE6557B2D7E0A4B
+:10D550008215C3EB7E05701ADE492C1AADAB7E55E1
+:10D5600002B9F6469E8AF276EB1F28438E800FF5AD
+:10D5700065819EFD62AD6D25CC73603C11D952FE74
+:10D58000ED4B310EDA9943F1B906F4AC2A484274F6
+:10D59000951F76C13C9D32AB3F9777CCB7B2385AD6
+:10D5A0007F2CEF987B256DEF9C986B8175E4A5B976
+:10D5B000B4400CBA3A0CF218D6B776D170BD1E340E
+:10D5C000976A0D1D77082D8B7909B4760EC09F9749
+:10D5D0002A7F9EC9EA0738DCD466DE9EC6CAB3FD40
+:10D5E0001DF3F8AFE5B9855D3A94FB8FC5CE8C414C
+:10D5F000EDD3C37965FDED532AE886029D6FB27ABB
+:10D60000875AE8D89BD6DA889FF2D4A61C827EA2DD
+:10D610007F8D2DB01DF84351875EAAB3BB026B32DC
+:10D62000AED0E8FB0189CCD1CBC97B399CEFCA973E
+:10D63000707ED3E5637E99D2EF263F413B6B137139
+:10D640003BC01E89E0DBFFB90FE990E3BB2ABF6A4C
+:10D650001DD02959C8F4667E549EAD50E8389B61B0
+:10D660001C5ADFDC6EC1F96DDA45F9977EEAF39B4F
+:10D67000DFB180DD3C96042DB0BE312480A5872C1F
+:10D68000B30050BAB91EDFC6F9B790F237FA3B20A3
+:10D69000FA68FBA5C3EBBE06BE48222AD655BF1BBF
+:10D6A000E9A9715772652CFBC0966FE17E26A957D8
+:10D6B00026713F87C1D9965FD61FFE56B20CE17E18
+:10D6C00093C767CF07FF6EE7C1E030DAF4C4AB461B
+:10D6D000BA05A8CCD2C99D1CFE9D24AF4F93E93852
+:10D6E0007B72EB92E1FDC6FA4FF665C0D07E3FBE7D
+:10D6F0003F39DF8DFDAE08764F8761C679C395400F
+:10D700000B63AB7BF700C98CD136839B413CE53F73
+:10D71000DF93AAC23CEA86C23885A17005908FB318
+:10D72000FE603003E773BE05E86204CC87D3472D63
+:10D73000D2978A7422F00DF4504BEB573430F850E6
+:10D740008310DB89E236CC7FCB2A4A27CEFE749247
+:10D750009ACFEC236F148EC43AB87FE5CD8F41BFCA
+:10D76000022EB37ABC560817F87EE75E053ED0CC91
+:10D7700040DF5E077DDE9E5B770EACB374A3AF1512
+:10D78000E8CFB92BE4877E024ECE29214DC27EDA46
+:10D79000B9D06FD3CD9595A817BA08FA4B427F9AA6
+:10D7A000F16F9D62B4F708E9C2F58CEC32DAE994C6
+:10D7B0008E519FF7A3E39B23741CAF8F4B08FD137F
+:10D7C000E8B4C47BC0CFA0FE078E35801C7980EB07
+:10D7D0002541D7E27901891D67B8323FE2CF66CA99
+:10D7E00083C3FBCAFC18FEAC0BF86304F2CB7CC00D
+:10D7F000879BF461FBF09B8DFCD2B8F3937DC3E86B
+:10D80000FC9DA5EA04C08FF87E03C737A5E3C54891
+:10D81000C71BFBF6815E1B7E33A3E36BC1D6488F2B
+:10D82000D2E34D1E6D297C47D099793D4BF87ADAC9
+:10D83000737DD7C278576CEC7EDE81EFF9AE473E40
+:10D84000DB180A3A4814BEC3397CE36E89E0D90D6F
+:10D85000F263568DF779D0CF3E8F7B3A9433D5BEA5
+:10D8600036302DE6D6CB06BBCF8C5F4A5FAD485F26
+:10D87000C4374D92C09AEDB6A2FE1C806EA27AD338
+:10D880002FE8FEE653C8ED3B62E1E174C73F99EB38
+:10D89000BB1BDE4FA9F611E4D3D39DD769F61371F4
+:10D8A000B3A81D1BB0EBED5841F71DEDB3D04F16DB
+:10D8B0007810CF57B5CFAACE033A772ADE58FE4F5D
+:10D8C00044DF703ABF9FD3F97A6E7F7571FBEBF638
+:10D8D0001615E57B678B07CB8E162F8F879663B95E
+:10D8E000AA45C37EF29A4F2BD07FBF99605C6B65CF
+:10D8F0004289148BAEF2FC467B7F78B311EFA9D539
+:10D9000046FF3B596F2FD37F49E5F986F644EF6810
+:10D9100043FB69C48B0F00DDDBD22A0DFD48F813F1
+:10D92000837D2BE0385D9E87F1620A4FB4AB853D65
+:10D930002BDA09A9C378AED5E467769AECD80E80C5
+:10D9400023C297C1B10BE088F02DE7F0AC667E13DF
+:10D95000F77BE285DF53B47ECE7C8C8B1094572B03
+:10D96000726CA89F3BF298BDDD8F7E3275F293F208
+:10D97000FCEA354C9F0B7BFCF99C57AAC1AEDD92AB
+:10D98000694139B9256D8F672BD6E3BD4C9FFABB32
+:10D990003C147F560F8F57538ACDA2EB4DE47CB3D6
+:10D9A000DA4A30FEDD91EEF4421C2CD1B3A806FB1E
+:10D9B00099BE4BC8CF89DEFF23EFD51BEC0EA25CCE
+:10D9C00063586764FEA536368E44241827A5D866AA
+:10D9D000C09F9DE8EA79305F5B148F79B05E8E2737
+:10D9E000939D23E214663CB96B8CFA6675117BBF7C
+:10D9F00037E701C4BB19BEAE2A23FD7670BA684B67
+:10DA0000DF827C68EE6F1E9F4C8937F87F1D9EC1B8
+:10DA1000E324C29F16FDC08F76C7E86FF6A3CF86BA
+:10DA2000BFEEC6EF19F55D0C7F7DD2085D3C49C0A5
+:10DA30003B8207115FE47E98885B8BF114C2C6C3FA
+:10DA40003AC6B7FD28FF7E99E0423FB2C0690B801D
+:10DA50002C2CA0F3003A6EFB55426025ADAF4B98DD
+:10DA6000D99744EB05DB6415DB9DBEA11067EEDDA5
+:10DA7000306368987EF71EA9EEA211BA38DCB6E4CE
+:10DA80001B32993DA0BC13F600934BE8E7FAD74D43
+:10DA90000C69608F1711EF76025E306B17F444F457
+:10DAA00075B97FFDB3114CEF66CE25CBBA63E07F2D
+:10DAB0000D6F8FCA715F3CCA6B2EC70B38BCB6772F
+:10DAC000CD8AD7CB71DDF3A4587475B6E4771BC843
+:10DAD000EF51F09D1735D4DBA584CBEF47C8F75144
+:10DAE0007E2FCBAB5B3DA22CC67E9F1246F93D51EB
+:10DAF000D5DA01EFE9E0EF015E7E4AF112631DCF56
+:10DB00008E60F6CDF7152F42AF6EEF7A9CE1A558E7
+:10DB1000E0E57612CBFFFD1EE0E569807B3FBD4A64
+:10DB2000C2B80FFB45B6F60CB43FA56ABB007F1127
+:10DB3000FC5C169B6FFEF91DE3E77EEEB7AEE7F8DF
+:10DB4000E9E2F1F1DB397E3AB9BEEEE0F869E7FAD5
+:10DB5000FA56C04FDC99F3CDF066237E52ABE34D0D
+:10DB6000F830E227A9DC889F44AF113F099ED126F7
+:10DB70007C18F1935EA022FCE2328D78EAC737A7C9
+:10DB8000F057D2609C187672765DA802F6B886CE01
+:10DB9000E9EEB5C220BEAE0A28C57AEF35F9A5A2D6
+:10DBA0004C2F6078CD9C161BEF16DE1EC8D7A40242
+:10DBB0003D9DFC20361FDB79FF63AA1667E87F5185
+:10DBC000ECFE2EDEFFF5E15AA2BE3FFDB94B1EC4AE
+:10DBD0005F30AF3F41D2D20B701DEACE30C5FDB6EB
+:10DBE000156C1F729B43ED86FD7CFF0AA777BB8AED
+:10DBF00023F9ECE01FF171883F09C7CDE59F19EECD
+:10DC0000DCFF15ECFBE52DC81E7A356DCF5B9E79E8
+:10DC1000A48E96A30B46E03CF3EBBD7B00CEB26B2B
+:10DC2000CE50B67F3CCFFDFE184A6AC154E91B7046
+:10DC3000B8DDB1F7ED4529F42995836807D2890449
+:10DC4000B6533A8D5388929802EBD5705D56B06307
+:10DC500065586F17D6E34937964E1262FBD7DC1F23
+:10DC60003DAF200FC7731337FAAB29C48BA5E06310
+:10DC70007B1A51D227E0F86D7113082AFCF3C05FBC
+:10DC800075666FEE009F46A3509884AC82F090EECC
+:10DC9000DA87EB271EA2B278DBCD6ECC4FF8335D6E
+:10DCA000DF98D35FDFE9F6FBD2E12A21498434DB38
+:10DCB00059F98B78D71628BF74E4062068A58DA87B
+:10DCC000FB31E0D55F49D0FEF0BF951068C5C92E85
+:10DCD0003B87F907A73DCEBCB334CECFCED2388D2B
+:10DCE00005E9A71EE736F87532EC63FA9643FFB6EE
+:10DCF000E44968778AD20CD77D1EED06989F627F33
+:10DD000029F7BDD4A8DDE67C5342BBAD4D0A12888D
+:10DD100053FADF96D0BE22C50C4F4E9578F2C64519
+:10DD2000C7717A970D67F12E16EF59F1F75F8C02E4
+:10DD3000FBFB970933C349F4FDAD07A99D0779346F
+:10DD4000D3BCAFD7537A4A4FB579B750FA49E57E7D
+:10DD500072DCDA4907EAE9AF9F8C62FCBDA365BFBC
+:10DD6000BB8D0AA444C57BE104FA9E93EFDF12B990
+:10DD7000260C7663E22445853D8E2239580DF32525
+:10DD80004D16027C714F83713FB7B3B008E122EAB0
+:10DD9000C3F87E2E2955FA227936D48EDF58C0F387
+:10DDA0006A5CC40576A1F26F2D2956DE8328C5FC76
+:10DDB0004AD3A8DE4A82B820E5145A96760631F98D
+:10DDC000A3D21BB4831DBB2140FC360AA707E7FB87
+:10DDD000AE81F13ACB7D0960976F3834EBA2B17414
+:10DDE000DEA1B0E205100447A5E0BA439ABC368133
+:10DDF0003EDFF9A6C50DEBDBCADFEFF449C8FFF73C
+:10DE0000CC23013F85C7D6863D7619ECDE90858C04
+:10DE1000443B973A5C93B82854215ECBF8FE965168
+:10DE2000E9F8B027B43C19E0B22EE1FC9046C7AF48
+:10DE3000AD6671E71972F6F3306EA8D386F849E73C
+:10DE4000F94712A945FB39659ECE5EA6FF123B99A4
+:10DE50005F19BA8E60DE535299D3EBA7DF7B22CCD9
+:10DE6000F68DEEA96671671709E2F767C8BB1C1645
+:10DE7000FABCA75A71033D2599EC73278C4749AE2C
+:10DE800067231BCF359E8D9768CA83B28B79B9E91A
+:10DE9000BC28FEE44405F1ECAE36E64FB94CEF3950
+:10DEA0004DDF7B59E0399B14029E4FF86E98F812B3
+:10DEB000B67AD558F9139D2D2454A5CBB7700E1002
+:10DEC0003FFCB290F909B6ACBD7698D709DF2B6953
+:10DED00010EE7AE15FFBDEBB03CA7FFF574F135D95
+:10DEE000D75FBF3ABCED518063F36D2F221D72BF27
+:10DEF0006A084C81CEE7F95A1BC2B14C63F101525A
+:10DF0000DABBD75A8AEDB8AFB5768F03DB87959326
+:10DF10008083C27398A265FD0CF835247B57A83026
+:10DF200088E6CC9A44D85615ADAFBD92120E950F27
+:10DF3000E9F334D95F0CF190174822C5F7064D522A
+:10DF400059FE9BF43CF0534E95847E58CE219F039E
+:10DF5000E8E1C46C0BE6BFACA8BDF4C29174FCFB55
+:10DF60002A148C375457555C0EEDC30E317A715D0F
+:10DF7000C7F047E114ACA2FC30E2108B279492B0BA
+:10DF80003748DB877989350DF4C73C0A60985F27ED
+:10DF9000C70F8F0F949686FC00D444AF118F6E1379
+:10DFA0001ECD78758DA47804FD52448A985FC7EC25
+:10DFB000C75ADE6743D544F45FEF5189DF3AAE3F7D
+:10DFC000BE5EA4F6A346EDBF10B51FA1FC1BB51F96
+:10DFD000A1ECA1F62394895AC545A574BEA1743A53
+:10DFE0002EF05F4DD94AD81FB86FEAD537FD93960A
+:10DFF000657C9F8D726A4A25FDCE2CE062565FAF2C
+:10E00000519BE4A552D9505F9BA6887D3C3FE8D444
+:10E01000C42C0BDFE79971A746EB9D990ADFD76304
+:10E02000F511C5C450EFA9B118EAE7EDD18D3F0550
+:10E03000F01387F5092377AEF71744DBEF28A475B3
+:10E04000DA7E80DB73B54B2DBE2D31E877D948469B
+:10E05000BFCABF895FA2F8FAAC80A09F2E5B349440
+:10E06000DFA4505141BEF6D7CB540EEAFDEB022A95
+:10E070005775F191C3853CAEEEAB60713612FDF978
+:10E080007A12CFB322F0BC330476C4ADAF5EE90D93
+:10E090009281E5AE355339A2A7938B051D8C2423BD
+:10E0A000D19F27530E54009D754D54801E4A391F31
+:10E0B000106EC761889FD2CF539FDEFD174D053F7D
+:10E0C000ADDDDD3612F37E2E1FA9CB935995BE68C8
+:10E0D00022E83391F7434895FB7DBA2EC97FA90505
+:10E0E000ECB681ED1485BCAF83476FED8C24D00373
+:10E0F0004E2EC7CDFD57B5EC7C05BEBFBAA51B4B58
+:10E10000679A0F858C5DF163FC669FA7AE11E6658B
+:10E11000CFA6ED3A396C4BA3EF19FC806C667709FA
+:10E120003CB809C683C4BEC986CE09F17114189DD6
+:10E13000545F807CDE109A8579159DDE0983C6AF19
+:10E140004EC5275BAB5E2269148E4FBE3AF32FB3E8
+:10E15000697910F88DEAC12738DFE4943FF6DAB523
+:10E16000067E396AE297A3267E397A0A7EB9E04EA6
+:10E1700068EFC9540CF51CE0175D7D6B845F583D5A
+:10E18000CA2F47915FEE79D986F58D238F1AF865EE
+:10E190004521AD67EBF865BAECDB12C30E78E53BC1
+:10E1A000E2975F9F29BFBC7166FCF2C4D9E3973F39
+:10E1B0008E4CFFEEF8C5779AFCE2EBCF2F87605EBE
+:10E1C00067CA2F9DEE20E60376CEB6540762E0FBC9
+:10E1D0007A8E6F11F72EE3718A69F3B4CBC7823D53
+:10E1E000CBF3D6443E4DE73CA6BF57D4CE407DB9D5
+:10E1F000F520D397423F97713CFE8DC731CA424C00
+:10E200006FA6974BF8FE4C4D0AA8F4D74E6A12A49D
+:10E2100082BE9E22912E1596BAAC76A414B59BE8C8
+:10E22000F7D06EBACFCBF266C92166EFD8E97F404E
+:10E230004F17975B0D7A7588D9FE32D5C53EA6D8A3
+:10E24000BFBC0FF212283CBE1EC9ED2693BE15704E
+:10E25000D870A812ED90CFB36D83EE5775F2F546E6
+:10E26000ECA9525F45AC78587DA184F0BEC9A3C526
+:10E270001796813EBE0AF5AED0E766BDDC53F59237
+:10E2800051CEF8C7A75616EBE48C7F3CEACD889CAC
+:10E29000E1F501E50C3907E546442FF37A442FF305
+:10E2A0007A442FF37A44CEC0F8D951BD3CF281F1C3
+:10E2B00077FA757A7B19D4B34FAD9717707970B62A
+:10E2C000E5CC1FB8BDFA5DE9E5CA424E2FFFB99C07
+:10E2D000A929FC0EE54C2DC899A453CB995A90332B
+:10E2E000C506397355E1B7D0CB890DBD7ED8BFBF08
+:10E2F0006200BA77707C371568D7C0F8A4E6F4F2EC
+:10E30000B6CD74D55BFBC0AA0CA0172FF3F3067A29
+:10E310003FB1F9F7AFB4E9F2A21395103B5FD1FC1E
+:10E32000243E9FDB7010E365A79A6F7D21C1D2ACBC
+:10E33000477B6BF7D9916EBD16DC13FFB6F3E89CF3
+:10E34000CDF8F28DED4FAF073EBA8FC7FDCC76AE5C
+:10E35000C0EBE9DA3FE6EF5E3F52C571CDDF3F1516
+:10E36000DD523ADD0C747A22FBBA31E0E7C98977D5
+:10E370002500BCBE07FAF0C96F43A7AF8C64F83C18
+:10E380008D750761FCEF6ADDFF017FBEFC6DD6BDB8
+:10E39000A090D1D569ACFBBFBF4B7CFF07FEC26725
+:10E3A000DF66DDCB04BE093B2FE3865F289FACFF11
+:10E3B00057E1DB10BF58FFEFD18FC13ABBBEB26F40
+:10E3C00086F805F9FA1BD9AD3F3F45D8B99944FE07
+:10E3D0005EA28F9D877157EBCE4791E879295C0F3C
+:10E3E000C63722ED07629D97FBAE4BB047DEB10EFC
+:10E3F000D26E63713BF3F3FF2E90D83936A9D60164
+:10E4000079F1BDB3F760BE41E7EC09B86F65B6536B
+:10E41000C47B3D2D1AC6933A5B7C58DEDE521D82CA
+:10E42000B8C9932FBD25413E58E94B0DA8DFD64E04
+:10E43000FAE130CCE39B5A1A0FF5DB4D768A8BDB81
+:10E4400029DE51AFDFA9F75F9EFC4D13CA4111874A
+:10E45000BA2362BFD0F7549D9F44EB400E113F0991
+:10E46000EA063F69D97AB05F7AC07EA1FDA78E5ACD
+:10E47000B63ED677D65A483DD82F6B1B2CD5B1EC7B
+:10E480009770416CFB85D671DFCD91680FACCC03E2
+:10E490007B86D4E9E36AA7B25F1E1EF5DDFA495711
+:10E4A0008C3A3B7E52846FB9DD32A4485B0821D997
+:10E4B000B32527869DA69C18D65F4EDC38EA5BF80C
+:10E4C00049E102965F2DE86BABEAC578726735C10A
+:10E4D000F8636768656A09AD3FD1602112AD5FFFDF
+:10E4E000328B0B6F2827013847BB219B603DE465C9
+:10E4F00074304376FE08E2E03D55D47F52216EF73A
+:10E50000E35A80EDBA8499B73928BDD4962B04FC20
+:10E51000A619F214FC4E4863F9A1B54EF2A338F0E7
+:10E52000ABA62A64E519C4AD13E562897224E54FF0
+:10E530003519F876A078B439FE4CE417BC802F73F7
+:10E540001CFA4CE3CFDB055D7DFBF833F2DF970F60
+:10E5500034CD8278EEA9E871C12815F599594F9903
+:10E56000F958D0D340F4E7043B69A2AECECFE186A0
+:10E57000F93EB513ECA48951BAE8AD9D94142BFF74
+:10E580004A9409CD7F78457F1E2F41E9C6F1129A42
+:10E5900077E1F3BB206F00D6A778519E3E5849E53E
+:10E5A000708CF9ED6E597608E4E7AE96662C2F5024
+:10E5B000FAE414DAFFE916FF2180DBCE96762C9F71
+:10E5C0006CE9C2F69E968D58DED112C0726DCB0EEC
+:10E5D0002C6F6BE9C6F2C17CF69D294A10C7B9E0E1
+:10E5E000241D5F474753FBE87774F83EEF43BFA114
+:10E5F0007D72B8DDD07ECEE12E43BD2CB4D1D0DF0C
+:10E600003D2560686F2AA83B067CE92ADD6178EE2B
+:10E610002CEE36BC77BA7EC1D9EE976B7F04B6C9B3
+:10E6200049329CBBA0AFC8706E88F2F190662A5E3A
+:10E6300069FDFE441EE7E866FBE49924F283740951
+:10E64000A964601FF426B23CC8D62CF67EEB8DACD4
+:10E650007E7F0EDB3F12799AB23D42D744CA88EEE4
+:10E66000E7DF9FC8CF2915B0BCC8DCE200442448CE
+:10E670002E24A8C17E4829DB2713FBDEAD3CEE70BB
+:10E68000BF95EC94A83DD9AAB0F9B76A24B082F638
+:10E690006B2D66F57BAA48C002F3D7A814CFD0ED46
+:10E6A0007337EFFB4A2A89EE9793D11AEED7C87CCD
+:10E6B0009F3DB2EFED7897E0BE3E87D7CA848F3199
+:10E6C0008F36B9B94F02FE1AD2DCD70BF3BBFF1657
+:10E6D0009B1ACB1FEABDE58B2CE09B4D377E910545
+:10E6E000CCBE29923FD3E7D0E7CFE472B86C6ACEB4
+:10E6F000C7FC854DF52E2F87B3C5D48EF90C9FD757
+:10E70000F3FB0988827ED1307714AE01913F22431A
+:10E71000DE1D5DFF88E8F9D3FF34BF6653F37296C0
+:10E720005F934D787ECD4CF427051E364139AEFF00
+:10E73000B9DEEF3ABFE6947935A63C0703FD42DD2A
+:10E740006FA66F15F112C7E95BBA99E5456499E8C0
+:10E7500046E45D08BA14F919225F43E46FD8785E85
+:10E7600007FD2CCF6B8E4D5FB63DC403E7DE644BD7
+:10E77000BC774BDEA9F3089A3DF95C392C1BC7C660
+:10E7800065F903FF334AFB85A72C3A6E9E47BB51C0
+:10E790005F17E556F875321DC21BAE027BB5A85C4B
+:10E7A0006B85F37C29A504CFE994964B58161D621E
+:10E7B000F5DB3C327EAFCDC3E24DA27EB1A63D0774
+:10E7C000EF2799DEBB38F29E15FBFDDE63E1A5C2A3
+:10E7D000E6CDF3906772FA5E3D5966F9D155129312
+:10E7E0001BB0A13A89EB430ABF8B89FB92025DDC27
+:10E7F000F5C71C5BB7B7B0FC3E910FFDB79765CC72
+:10E80000877696FBA6C1D9B3B2502808FBEBA5DBEF
+:10E81000883B4585F98535E0C7153977EF817C88D8
+:10E82000272E647BB6171F62F6C28FCBAFC6FB469E
+:10E830005C5FCB188F754F49F406E0433556A6FF51
+:10E84000453E74B9D15EA835D90B179FE2FE8F14EF
+:10E85000D2E7073DF988C7148FE5F7800C24BFA3E2
+:10E86000F78030F950CAC77496BB1D10BF2E3A64AA
+:10E87000C1E39EF2364DC6F3B19D2CCFE389906F74
+:10E88000D0F3A82F723886B89CF81BCF93ECE172B6
+:10E89000E2752E270E839CA0E52B3C4FF210CF9300
+:10E8A000349F97D8D152FD92DEDE319745927F1684
+:10E8B000E6416D56089EBF1BE0BE8FA2001DC790AB
+:10E8C000C7B802E9676FF2DD15401CEB350BDA952E
+:10E8D0005D5348562CFFAEEBC2CA41F30F3B5BE6DB
+:10E8E000BCD43688DFE8B4517F26D6FB1E71AEABB0
+:10E8F0000BCF5BA4955B08E45565D9FBD8FE43AF0D
+:10E9000003E97988D78EFBFB649E93BCABCB53B9EC
+:10E91000DDD7350BE6FFE03605CFE7887113BD7410
+:10E920003E3A3A499BB22713E6DF39359809F64C4F
+:10E93000D7F87D1B0B205FE4A04C800CCCF3B21603
+:10E94000717F96AF2B4DD1A45879EA03ADEB038FBD
+:10E9500064B867C20CFF01ED0EC80818FCBC95B383
+:10E960002846FEE269CC13EDDB6F765C3B1BCF4D96
+:10E970009EE6FD17099C0EB3161207FADD408F8341
+:10E98000E0D9650D21DED62EB454C73A5F5B54C47E
+:10E99000F0BDB6F453B48B4971EC7924959BE9959D
+:10E9A000CDE70E858E4FDFEB2A8D3DFEE51C6F9483
+:10E9B000AE5F0379D5556D41BB22092E62C0FC1CA8
+:10E9C0006A074948EF28973E2BB5313BC1242FFAFF
+:10E9D0007DBF54474FF9FDE5D0F9454E437CFF44D8
+:10E9E000F6ECA4600C3C8B52C051C8A1FE70247898
+:10E9F000FEB58BC39114C7E6EB28BE56887855DD6B
+:10EA000029CEEBCD2E2A8B714E6C003C98E9E18E1D
+:10EA1000853E5C1779EE35A282BE2CA5FCA88B43FF
+:10EA20000C043F33BC167EC7F032B7FFA888C74737
+:10EA30004E739DA7DD8FDA456E9D5D0C87A2155A3A
+:10EA40009FCAEB3FF64BE17BA85C9576FD09ED9EF6
+:10EA5000A9BCFC3194543FEE9282EFBE415F9E22EE
+:10EA6000A93980B4594F8F820819B9555A66B07FB9
+:10EA70003A24EFE167302ED4970AFDA6933A852118
+:10EA80003980EBFA93146E05857529D15641D94822
+:10EA9000BA6CF05E63CF9F0EC3771A7B1C4119825C
+:10EAA000933BADC7F471A36BF4E747F2E0168D6EAC
+:10EAB0005B1E9DCF921DC67DD20612C2F196761BBB
+:10EAC0009F9BCF8F4832050C5C4E10C97F9D82F909
+:10EAD000BDC4C1DAE3478BF3E87D85FAFBCCEA39A4
+:10EAE000BCEAEDCE20DC2F4402C6798A7B739EA758
+:10EAF00072CC3E01CFC33C0C74FC91DBEEB7507B73
+:10EB00003923A5AE11E07115516DAC647683589729
+:10EB1000B887668173B60DE0BBA0DDBC0ECD06F3F1
+:10EB2000F959D7E0EB1378FF4711C175DC5EA46299
+:10EB3000B934BE66BF06CDA5A15CFD7D104D5C3F1E
+:10EB40009065A906FE7D51D023D1E4D3597F7FB8CB
+:10EB500016609C4CC075603A35C6C976C121D77421
+:10EB600084DFCB7AF811A5AE04C615EBF96759E836
+:10EB70008120ECAB26B27BA0DE4DA97B03FAE71C1B
+:10EB80000EBF2FD1A913A75A08EBFC78E747AFC8EF
+:10EB9000F9D1F51112BE1BF2A3EB77CAEE0E58CFD6
+:10EBA000CEE70E03BD0FB42E911F4BE901E146E7FE
+:10EBB000F521E837F3BC8EDE407E0A76C974B9D8F9
+:10EBC00010477986C3F19E62DFC7F05EE94BD92E0C
+:10EBD000BC7F27BF7BDF503A8FBEEB25CCAB4D937C
+:10EBE0004915C04FE4237CEA54D0CF4E4BF0CB2ED6
+:10EBF0005AEFBB8A78B7C034BCCBBC402A724EB146
+:10EC0000B783D24DC6F5B20FE4C9DFAF5B90BC80CD
+:10EC10009619890B9347D0F28238E277D0F13224EB
+:10EC20008BAF1B8350F3932FA1F3FC491C9D27ADA1
+:10EC3000E7DD90101C41F9ED8F3662077A4D4BA845
+:10EC40005B371DBE932CE37C8E503B51A172ACE22E
+:10EC5000F2CF26DAE9F7867EED9C00F3C96A9E467C
+:10EC6000DEA5A03C5CC4F8E4E8C35F4E8473E0F228
+:10EC7000374E2F9E33E7F4973682C1C38CEFDD1CED
+:10EC80001E6FC6337FA731DD762BC4DB3FE6FE0F58
+:10EC9000D13CE82F5CC7FD8537E3991FF466A18856
+:10ECA0002F05D3F5F66DA3434BBA0C9C076A274199
+:10ECB000BEF3676E2D2919FA111FF2ED75DC6FFE98
+:10ECC00098906AA0F3EBD64C1B9242DF4F6F6570B1
+:10ECD00030CF6FEC68A69F1B4E5282D6C5CF1A94D8
+:10ECE000A00DE477C3499BE1F9DFA91DEDD79D573E
+:10ECF000FFC98787A6C3FCAE24E155D0FFCAEB123B
+:10ED000058E09EF36B0F9FC74070694C568842E1F4
+:10ED1000D12811DF60FD9EF9B71C13BEB34733FB4A
+:10ED2000257D5AECF55DC4D7376D75CD2F81CE1A90
+:10ED30004356B4E5AFFB43C590C1ECE7C693E791FA
+:10ED4000802EFED7A884111E8D27CFC7E7D3561F6C
+:10ED5000B301DDC3382A7D7E9D431B02F1DA81E0D9
+:10ED6000BC9BDB418D2793893F55FF9CF17774FC59
+:10ED7000346CFF2D87DB6FF75BAA63E577358F6611
+:10ED800070199DAEF8201F684C90689B637C57F407
+:10ED9000CB4831EE5F98E7D55319BE12E67D4E158C
+:10EDA000D1627D6F3187A3986F4F4A78910FE9B395
+:10EDB000AF10EE9988D4DD7DB9FA7B24B672FCF5EC
+:10EDC000FC309C0BE37F7C61EC733B02CF9394653A
+:10EDD000682FBF9052F734C8B77997D10AA58F2111
+:10EDE000F38216763EC53F28BEA370964960E26066
+:10EDF00070B661BB18EFA317393F523F1CF2D4AF76
+:10EE0000E2F2FFAA6D4B30EF49C8A98F36CA28A796
+:10EE10003E42DD42CB8084F6EBFC3A0A6B2A571661
+:10EE20006D9FB60FD4C15599D4064D61CF6F86B290
+:10EE3000CD6A88F78BEF2D38CCECB7859D463D57D2
+:10EE40004F3A3F01FBE0A317993CA0FC6D0379BC4E
+:10EE5000E82EE338F5DB2EFA00E6576FF2CB33B835
+:10EE60007E36DB799B47F3F8FE2432E94CFCF24610
+:10EE7000A2ED188D7AC127C33CCA14E33D5BA24CB6
+:10EE80002F61F05FBEFD84CDA50E3CEE112A470A2E
+:10EE9000E8B8C7A83F0EE51F476BBF1F4DF170FCD8
+:10EEA0002083CB81D1754FC1F78E1F64EBFFB4E196
+:10EEB000D345704F0C99C3EC8638387C407F8D9BCE
+:10EEC0006B0FB4D2F5AEA662CA01E782E2983D228A
+:10EED000EC3059BE5676D1F6C9FF58980CEB4C7BF6
+:10EEE000E807D5305EFA43091AC0ADA3421B0FF202
+:10EEF000BEA3D6E985F32A9B291996D3F7ED741C96
+:10EF0000D02781DF4EDE03DB9105DDEB2AE1DE1742
+:10EF1000F7AEDEE030BAAE760BBB27A3FD7CE26D28
+:10EF200025D1EF35EDAA7D0CE6953B9BEA0709CE8E
+:10EF3000D16BE3DDBAF109B7AF1A394E8E3F3BEA28
+:10EF40008EF3E05CC27E19CDC74F1BF2D1AF1F4DCF
+:10EF5000183D89FC7BF836D891027EC7A8BE22BA3C
+:10EF60003CB5D1DD52D04AD7B5B4E731BC8FA361EF
+:10EF70006530632EE8DB0715A647F9FCD2FE9855ED
+:10EF8000A9BAA2FA77AEE4463B52D8C99713F15317
+:10EF90008CF1C2399C0F2EE7F6F1DC0406E7F9C4C8
+:10EFA0009B0BEF5D61272E0B85D9DC69DD65CB40BE
+:10EFB000EF2EB126837D036B898577519AED20C1B1
+:10EFC000878D0F24FA21EEFAB1D45708831CB13291
+:10EFD0003EEB7B362EB025AFFF38D631CCAF6F2C51
+:10EFE000E4765D01D1E0FC40E3EE51781E2C2E9ECC
+:10EFF000E27102CA3F3BE0F579D0FF74DDD73CE314
+:10F0000008E2B930715F999BF813E9779A760FD9C6
+:10F01000027646DA086DFC723ADEC7D6702ECA0B4D
+:10F020002ADF24AA5B73C7ACB944A17CD53894DA33
+:10F030005DB47ED14377B37A7E789185D6AF7DE893
+:10F04000D14B144A9F8DA3C3EF43FD96879E66F56F
+:10F0500009E14532AD6F7C683FEB0F7BD894B0B6C9
+:10F060003F74E012F0FF8F2433FB8178C35702FD19
+:10F07000343E3DCAD2A15BEFBA314C3E1E71B07E28
+:10F0800047F2C84F6701BC3DE1C259BA7DB9EBC731
+:10F09000083B96D971629DE23D92197BFCB1639861
+:10F0A0001EBD661AEB7741026977B0F3757EB0C773
+:10F0B000F6EE1A8570491993C2E145C7298D8E2352
+:10F0C000E028C613DF5D0C7A1DE4BE95CA7D9D9CC9
+:10F0D0003997E38D7EA70DBF53AC8D877BAC1A6744
+:10F0E000658F07BC517C291C5F8A1D2F57DBCCE63E
+:10F0F00047C74D2E413D3311E2CA7BBFA6FDF3A2A7
+:10F10000F336D3C78C314C1E5DD3CACEF7F7258FAB
+:10F11000403ABA2081D98BA494C28FCAB38D1C6E99
+:10F12000EBC624333F32828721128EDFCAE197CDAE
+:10F13000FA9FE97AE7F0799CEDF5EAF0A4417C6565
+:10F14000EFCE22C4D3C6081DAC338C736485E9BDF1
+:10F1500072CA78308F9411F8DE6A07B1E373B22572
+:10F16000F25E1E7DEF82697D13811F96727B98F897
+:10F17000CFC7BC86062E2D96B6876C10975EDACD6B
+:10F18000E2E4A480AE0FE863564D295F9F9BAFCFAA
+:10F19000CDD61730D02739D4973B3BB13FDD46E081
+:10F1A0001E19AF78021FCFC0CFB1C603BE18081F0B
+:10F1B0001D671B1F629E267846E06C9A9F8027F091
+:10F1C00031BE576CE42731CF5BC644E2B1467ECEF8
+:10F1D000FB96DFAB60EF2DBD91E211EC1FD548CF60
+:10F1E0004B7BF22CF38BA3EFB577AFF0819C4F9064
+:10F1F000541607EFA9F583FE6BDA558171AAA54F66
+:10F200003DFCA49FBEBFF8D10D2E48AEFA48E9CA16
+:10F21000003BB861FB2A17DC33F7A1E27781FCFCE5
+:10F220002820C7CC5B7F9BCB01617735727D73E46F
+:10F23000B7B7CD04787CB1DD8AE70C9B76C405E3D3
+:10F24000306E720DDA63B4FE36ABAFFE04FCD8A6A6
+:10F250009D46FB69F16F3664A8484FFE6116DC04D9
+:10F260000B0E83CDB0C66D56DC4F693C247BE9673D
+:10F270004813E9BB15E6677E1FE67192E2BDA95B04
+:10F28000BE0AF2FBCCED5492A03DD6D4731BDA69D2
+:10F290004D3D177E00764593299FA27E003BECC52D
+:10F2A00031DC0EE3F7A40BF890403ADA37AD0FFEED
+:10F2B000B2E46D3AAF63DBFEE2928AF57A7325E23F
+:10F2C000E9D3EE059B9E5607D6AF1F837D10A77F1F
+:10F2D0008FE157DD29B18DA15DAC6CB0065D101FCB
+:10F2E00068D86CF5520D4C1A1EDEFAC0AFC1BF7C57
+:10F2F0002DCE0BA9A64B1E7EFE9573697DC963D6E4
+:10F30000B41A367D27EC730B3C41CE06D829022F68
+:10F310008B7FFFBC0DE290F01CEC5E819F258FF58A
+:10F32000DAE09C9F198ED3BA7B6D980F6BC653F7AA
+:10F33000DB33C004697DF04B1BD0F747BB25BCF71E
+:10F34000DEFC7EFDE6E75D40870027F04305BE2238
+:10F35000F8EB87B7E0CCA74BB11FC6434E85BFC7BC
+:10F3600001476548E78F3C0D7194D7E3BC0087FAED
+:10F3700047AE75C17A3E5096317ABF6F5506DC971D
+:10F38000576FF567B8B164CFEBEFBF1EE9F0EA83C2
+:10F39000D767B07B24B42C768FA63F0BD6F9B37B0E
+:10F3A0002FC1752E22754887F5F7B1F8C6E70AA96F
+:10F3B0007E2C06BFCC2D66FCF2C19638480E221F6B
+:10F3C000C03E02EC9BBC28E3B9FB7EF72291E558D6
+:10F3D000FF9CC717C61547EEEDB3837DD7C47B35B9
+:10F3E0006D5B1D023C1DC9D186403C9FC2C1CFE16F
+:10F3F00026C1BDEFF2C1E943189E880AFB21F81E21
+:10F40000B5C7A7C173E81FB26A8E12C37BFC7E1B0F
+:10F41000F67D11DFA0F38E87FDF40F32585E9E79E2
+:10F420007D1DC5421E9010D1D3D940FCBF6D0DD2B9
+:10F43000D7678718FF34066AABB13D640D0E81F6BD
+:10F4400040EF6C09E5439C61FF3C421FDBAC9CBF75
+:10F450008DED749E8AA487EF6E09EFD314F4B2E8A1
+:10F46000AE38C37E7D947E8CF745097E157ED6D559
+:10F470005C1E98D76D960F97169BFE8EC2BDE9A7AE
+:10F4800015FF6EB0061EF835F033E55FBF0AFC6C61
+:10F49000C5F8C0D1DF3DF7CA1594EE8F760B3E3626
+:10F4A000CA5B331FD73F5E4662F1F151A797C4E4B0
+:10F4B00063FA3C261F3BD9B9E9FF57F2F6EA01E4AB
+:10F4C000ADBFD8286F3F27C549E711D0334BF0BEF9
+:10F4D00057337C85DF6B96A399C56A4C394A7F0EFA
+:10F4E000111D3C051C057D2E7E68297E2742C782A2
+:10F4F0004E051D47E8D4BC6E233CCDED5530775DFD
+:10F50000FE837525F563C0CE7D560E6CA1533B4E30
+:10F51000E7722B85FFF1DFE561BED12AEE071C778C
+:10F52000F7B9207F6C15F73BFA202E99147DDEE7A2
+:10F5300060F6D2715F9F2B596737BDBD4B76819DB9
+:10F54000170E90EA58F1242AB1711E6132503BDB4C
+:10F55000173BCEE3A1C779BC73BAECCC6D8638708B
+:10F5600017BBD77FE18ACB5CB02F707CD7883B80FC
+:10F57000FF7EF66799DDEBE9D714C89358C0404089
+:10F580003E24FEBBA7D0752ED8B504F31BCC7194D6
+:10F5900045CE6DB8BFF039B9194B73FC6431C4590D
+:10F5A00080DEEF353DDF7511D2D762137DD5017D49
+:10F5B00065F5A7AF1704BF8E27E3F5E7CF9673B9BC
+:10F5C000375D2EBE03EC99E3D4CFC75C02B9F800D7
+:10F5D000E8DDCFC1EF07C6F0A723DD2EA9FBD0C61B
+:10F5E000EF71467A177468F6F7CDE5B127FE3EE96C
+:10F5F00026DAA5E1C9374AEEA1E5B1275F2B7C06E3
+:10F60000EA4FBD9AFB06E9DF7FDAEEAFD0BF39BE25
+:10F610003B0EE7737CF79F726F82FAD37198877500
+:10F620007C651CE645F9772706E03CDFF11C16B740
+:10F630006B7DF6CB12CCBF206D88C793C536668F25
+:10F64000ECFA9FB7207FFAD35D712AC4299A7627F6
+:10F65000A0DFDEF4B403F35E8E3FFBE5247D9CE97E
+:10F660003F5D4FA38DC5338F2792398F033D2733DD
+:10F67000FFAEE999C95B215F6E694FAF0DF607A632
+:10F68000FDF15F2520978E3FCEEC0FEACFDF0F37DD
+:10F690001DCA639BEEB652787F0C3622F5C3378DB8
+:10F6A000EDBE14FCF0FE706170384EE100EBA2700C
+:10F6B000A907793A103C868EB521FD7FFFE0F1095C
+:10F6C000FA170DBBCE413E8AC245D2D8F3C4805D45
+:10F6D000C2F5B3E7BBBF2C017BEA68F70AB40B4E57
+:10F6E000B5EEC963BFAF74F06DD72D054F67DD73FD
+:10F6F000BEB7F866F4FF16D757663EE84FE74FDD12
+:10F7000080F54712BD38DFD3E4FFE6FFDFF0FEB837
+:10F7100084FBF2A7C2FB2FFFD7E2FDCF1CEF896E5F
+:10F72000C82F3BFEECBF72896EFDA75AF793FF4BC3
+:10F73000D71DB18F649F1DAEB8EF24C1109C5F5FD1
+:10F7400035809DF2EE5849E4EFA01F22F277E4B431
+:10F75000C56867C8691D6837AC22EC1E64BF6AE1E2
+:10F76000F7B1B1BCEFF66C6F00E3A28AAF7E33ADA8
+:10F770005B8737783B7004A37F2667D454439CA5EE
+:10F7800075059D171DA735DDE26E55E19A764B3064
+:10F79000AE04CBB7A15C9DF1C3FDF05DC569BCAF04
+:10F7A000D669F237E20B6CC6BC62B2C70DFBD50E50
+:10F7B000AF0277B95353D678BF6DEF58B6AF1D4F30
+:10F7C0000298B779A6704A2D191C4E66F808B8F54C
+:10F7D0008313F747C57DFC4A5A4708F85021D49F48
+:10F7E00064EB413F14FE8E14ECD7589316793BD846
+:10F7F0007E8A1AB9C71FF220B8BF19B96756B5A0DB
+:10F800005F2AE0AC1B0FD76F86F399C257E0C54162
+:10F8100066219E1DD94E6F80CE7F95CAE0BE8AC2FA
+:10F820001DEE1717F0157033E3E17DA0519D1D1FEC
+:10F830002D8DF93AFE4AE2817D96E9F294B01FECF3
+:10F84000E5F204B4978F49242851FFED5845462529
+:10F85000F815C7726C0A9453FBE89A74F3BDE0A4E0
+:10F860003DF237F4A05E41920DF5633985F8FE3420
+:10F870007B96E1BD0390B74DFDF66359E576DC0F4D
+:10F8800075E719DE9B99E0DA02ED07208F1BBF3F79
+:10F8900003FD9B1F641619C699F9CEB17BAFA2E593
+:10F8A0004EEE57F74DB5623CFED89FE755021C2F30
+:10F8B00054C71BFA1F24EE74202ABABE2A58DF450B
+:10F8C0009EC986EF36BCBDA710E2103FF256189EC7
+:10F8D0005F5C7EA1611C9F3D1C04F2AED56A0DCF1A
+:10F8E0001B9ABF204A2A21E7357F4D9489D47C0F8B
+:10F8F000761BC699B87FA7A1BF37E49E0626E3848E
+:10F90000C3DEE7A014F9ECB654BBDF42CBB16F57AE
+:10F91000CAB0EF59F65E5D2B84A1CF3B463C400751
+:10F92000E79078DC0F1C28EFFD4B4BA00ED6F90BAF
+:10F9300039E081327ED8A21258D747999D326C4B5C
+:10F94000DF23D55D5E0276D6678156A85FF075B776
+:10F950000CFE64EB0E19CFD74D976B12FE0AF2B86E
+:10F960005BC21CFF06A705E3F04753BA4BAED5D1E7
+:10F970009DC8DB31F371D1C48A25307E5BA6D6D514
+:10F980000BF2B4F2EF57CA31CEBB12B7F15EBAA296
+:10F9900089BEDB619F5EE425C54F935972FB0FACB6
+:10F9A000182FB9D5E27570A1807AD73DC3BA19F87E
+:10F9B000DD3A8EC98DF8BF1015E241F1A975329C70
+:10F9C000B323774898D722BEB7A09CE5DBDF5E2241
+:10F9D000EE3771A7FF642CBC9FC8F205209606EF96
+:10F9E000D558D04E711DF6EE83FBC8EEF41C728321
+:10F9F00078E8A979C70FFB223D874353258A9721D1
+:10FA00009D15270A587F02F1CD1E4F55C258D46F5D
+:10FA1000E59887B39CE7CFF44EFD8D07F4C7F2A2BB
+:10FA2000D14306CB2F779D9488AACB33B08E5371E8
+:10FA30005E2E258CE7C55C27156C27E1F1CC1FE411
+:10FA4000E3BBE6A9AF5E0BF3D86FC57C67A2684B3A
+:10FA5000601D1DA3DF543B701D84FF5D9130FEDDF2
+:10FA60003CC84FC20BD19470E64F629CC33BB2A31B
+:10FA70002C19FCF2D40A2F9E1B4C7D588E9C9B05A2
+:10FA800038DC0EFFC373B597BE5A45C7DD01B2928D
+:10FA9000B50709A5EF0E9B68A7A2C6C3EF3DC4F644
+:10FAA0004B2F831843BC6CEC3F2E3FD25FB36746AD
+:10FAB000C7FF43C9A5AFB6C584671CEAEB8E1956CC
+:10FAC000CC9F38355C134E01571783EBD7542B640A
+:10FAD00044E38BEF496A2ED0DB9D705C80FAD1BF86
+:10FAE0004CAE0B96A4C3FC8363E1F97C9736642A81
+:10FAF000A5BF1E9B967B23C6491C98FF55FBF3A30D
+:10FB00001BE1C8986BE6114F1BD08DA2254C8038A5
+:10FB100095FB0B940B22CF2D0A474ACFF49BB75B82
+:10FB2000A2759013AE285C35B82BB84307673BAD80
+:10FB3000D772B8FECF23F597B5017E17DA912EAEB6
+:10FB4000E53CD5964CBA20CFEE84FB814B811E4E0E
+:10FB5000ECB062326B0F34821EF5D8D9DFF5490B59
+:10FB600067C2DF71197BD082F1BD37297D68401FE4
+:10FB7000C1F1087731DE8929AFA6C0F98913694A36
+:10FB80000AC06771D88670FB894282707F6A4FDA3B
+:10FB9000C26915C81F2AB677F371264FD4FE518269
+:10FBA0007A9D9FFFD5CE95E1BED481F065DECF87EB
+:10FBB000F8F0B92903D3415B851DEF1F6A2A5F5115
+:10FBC0000C7A62797221E663355549A8879B9A3F82
+:10FBD00043B88BF1959332517579533D104D4CD705
+:10FBE000DD237FD286ED0DCD27509ED3E9E401DFE2
+:10FBF0001CE3FB9D5D56F2D35A5A36FC5BFE69ADA1
+:10FC000013F72DDB419F34903DB6E53A7948BA3F72
+:10FC100089C8FF71147777D6BC180F72B656725F19
+:10FC200002970ECCEADE7B19ECE7D73ADC97C0FEF0
+:10FC30007F8EF71156CF715F02FBFD631F4D9A0354
+:10FC4000FBFBB559EE0DF09741AFF016CDC1F63C78
+:10FC5000F7CB509F316E06AB27323A4879347F8E0E
+:10FC60001FF5B913E1F2697B4260B07B48AE6E7E4E
+:10FC7000C600977EEDB284795198B841E9E79F6B51
+:10FC800086B17B710B4298A735721C8BAF67A4B00D
+:10FC90003FC92BF277D346100DF657D39E72B07B37
+:10FCA0005BDF0BE502FCAE7ECA1184B8E4D2FB9E9A
+:10FCB000B3813E9A2FAB85C057B3CBEAC68C2B835A
+:10FCC000F84908EB5737EFC679754C70F3FB72FBB8
+:10FCD0008A217E55CFF39EEB4DF9BF8B9D7B311E64
+:10FCE000B7789B31EEB68484DF023E6DF8DDE079B3
+:10FCF000BFEF58D83C140E8FF972E84A1B9BD7F916
+:10FD0000E3E8F797A6F462DEB1E20E65D4217C1B2E
+:10FD10003CE8AF64C6E3B99A5B87BE5E12EBBE985F
+:10FD2000EE16AAFF29CB3DDEB2134BE77882EB1922
+:10FD3000A2846D5E3A4E2397CB9342EFD8F4F983B9
+:10FD400073395C9376B2FD6F735EEC5CD05700172D
+:10FD5000BECFBC74D60B53002F029F1724906ECCDD
+:10FD60005F4D215E8E172FE045C03FBADF4CDFCBE1
+:10FD70008B451702FE84E5DBC53379D1F78403EDAB
+:10FD80002BF3FCAFE3FA57ACA39DD7079A7F3BD781
+:10FD9000B7677BFEED5CAE9BD721F8583C177C6CB7
+:10FDA0005EB798F799D359C8763A7426E44C23A9DC
+:10FDB000F3605C96CB150167314F01AF9E01F25D98
+:10FDC00095E63F18D6A3842AF1B0FC7650A420C74C
+:10FDD000BA2FC4942BA57917F63BD3F508793BD0FD
+:10FDE000BA849C35AF4FC85BB14E2177C57AA75214
+:10FDF0004182F210EE7E90C07FA833D8C3157062A6
+:10FE000041BF0F64FFB9A13EDD7DA3A1FF0F3257B3
+:10FE100018DA2F54D718DA2FF2AC33D47FE4FD95DB
+:10FE2000C9AEDF6C68AFD51E34B44F0987A681DD3B
+:10FE3000FDB7966ACCE73EFFC3BEE7A01E6C7163B8
+:10FE40007D4F4B26967B5B54E4EF7D2D1E2CF7B740
+:10FE500078F1F97FB59463F9428B8665A8C587A5CB
+:10FE6000592ECCFCFD650AD8EDE5A12EF407C68F0E
+:10FE7000AFFB0CE4E1014BA03591C2E99C37997DC1
+:10FE80004E02667DFCE55B37815E77B37BE8DA7A0C
+:10FE9000274B6A0C7BCE45F59DA6A317574D98C0FE
+:10FEA000FEB28BC4CEBBFC6A1CCBF7C17C3D4A9B27
+:10FEB00073ECEC5EDB397324CC4F9C43D879055A44
+:10FEC00006EB68FB4C85F841FFD73A15DC8F22FC26
+:10FED000FCF0256C9A70BFBA3F0EF4775A2A9E57F1
+:10FEE0009A0D0FE97C654DC6BCD64BCAFF82F980DE
+:10FEF0005738D9DFCDBA7CFFCA7FDE44DB499BBFD0
+:10FF00008C9D8710F786BC6E3913BBE12B386300DC
+:10FF100079A09297FDDD9464C5ABF70744F9D771DA
+:10FF2000CC1F98D9CACF0B1C2468C7097EA4EB6BE1
+:10FF300087F90BBEA8752BC1512ED0F7EBA641FF58
+:10FF4000FF0B270420E00080000000001F8B08004A
+:10FF500000000000000BB55A0B74146596BED5D591
+:10FF6000AF904EE88400411E76886020AF4E271D7A
+:10FF7000C26B28124054C446650714A540313C9317
+:10FF800018981547F774633308AC6737337A5C5DAC
+:10FF9000C1D3E0A0ECACE7102171339A300D2A8F69
+:10FFA0005947A3828266B141E4B126742428E270E5
+:10FFB0008E7BEFFDABE8AE4E02E859939373F35797
+:10FFC000FDF5FFFF7DDFFB552D3FE4720701A0BA71
+:10FFD0006C4D1E14209D221DB7215DBEFA3B30F7EB
+:10FFE000C3F1EA0B602E06982ABF164C2D01387F0C
+:10FFF00004DC369C3FA65D3DB3CB85FF5CFE5182A1
+:020000021000EC
+:100000000100ABECF83F8ECB3AEB2AFAE2BF45E1B8
+:100010007A30D335FCF911FF8A0F34813927361E27
+:10002000F77DFDDB346FB75F05B305A0D93F876966
+:10003000D8BF18CC2300F6FA6B78FC8E7F358FF78B
+:10004000F9034C0FF8D733FDABBF8EEFBFE77F9EB0
+:10005000C7EFFB434C5BFDDBF97A83DB09D01FE084
+:10006000426BC540350F8F46632F6E689F9CE94BEE
+:10007000416A16740E1DC883D40E968C0CA473248A
+:1000800096075E0F403AD3B08AF79767BEC5F2C0B5
+:100090001F9F1DF99D0DDA4F463F339402DC03820A
+:1000A000FFD965FF7D494AA5819A23A1BCEECDEC1D
+:1000B000031B2580FB2090BF00E99CCA3ACB7889BE
+:1000C000EE4F719E42794881CF4C3FE6A24CE867E3
+:1000D00052778A078553BADC6480A58EB556180E10
+:1000E00080523A1141F99A40821FB3009640D80AD3
+:1000F00074FF8F96139138392F03C8826C3CFF6BC5
+:10010000169EAF5F077A3E6E5DB94286B274929BCF
+:100110008BE5B60222BC9E4D7EC45DE3A0FDEAAC39
+:10012000B44EE2BE4B1DEF5871D0C3BEADFCFCB562
+:10013000F6D5F55405B080E6AFCD54EAF6E0BA2B1B
+:10014000FAB43D209B7A9087D3DC79653D94C3BF98
+:100150008C127A9553A6D85507D9A9034CA8C7681D
+:10016000480ED9709DC55975A9B42E1A662AE0F5B6
+:10017000252D32EB03CC8A7910EAAD52D35B3B8458
+:100180003F21BD544EA89C01A8BFC59B8CFC2C757B
+:100190009C64B97F0BCD3DF25B054F7F23A776E7CB
+:1001A000B76AC22DA769BD2A4D6E7C1DCFB5BA4D69
+:1001B000DAF14EDCBC95EE948C53C9E4583086E4F9
+:1001C000827CB8C3E46F8764F6B7DEECE39C1FD88B
+:1001D000DE2FFA61C73B68FFE72EE3851B009E70A8
+:1001E0004F7B3E30E197D35BBF62DF0637F913DA0E
+:1001F00009F991AEC775684380E75E576E0F0550E9
+:100200009E51AFD34CFB47A5503095F47209DC6B7F
+:1002100050DE939BF71F213F996C7784496EC84449
+:100220007BBC5E27B58BCB134F868229387F7C5BE6
+:100230004026B71D7B480D3A703CE63D05358D7173
+:10024000E61D9F4C7ADFE96F6239D4FBEB99C6FC5F
+:10025000E726F6331884D7B2AFDFCFE021BB89E2BF
+:10026000DA4AED4CC134A83361C0EA724C93539022
+:100270008FAE30B8E97AD1215790CE55DCA6C8A907
+:10028000782EEF493548E75E876A506C1427037271
+:100290005FBC6E3343D88671C4966902254EAE6347
+:1002A0002F84821407F5B8D69C24EC79D2E57A998C
+:1002B000E296D3AA6EDF82F2843793DCDB5CDDCF7B
+:1002C000FD96DBC472FF32DDF7961B29385C237D77
+:1002D000F9643FEDAFBC48F6D390ECB6E173897199
+:1002E0005A8F8BFA3ABADC7439563BBB38EE2F5F23
+:1002F000DDC5712F71DF6A13A8F528774F85ABB87C
+:1003000016D7695F03F367E1B8CE8234AFFBFC8F89
+:100310003CE5EF93BD4C9527B42A742EA7E9AA7645
+:100320005DBDFA1BDEBFD7FBDAFED52D5EE7424787
+:10033000ECBAA34812711ECCCE53F6983EAF57EFDD
+:10034000133BE718F2D6A4EF5543DE9A8C9136FEA4
+:100350007E85FD11C378AAF331C3FC5B32D718EE5A
+:10036000DFEADA60B87F7BCEEF0DE33BDC2F18E6E7
+:10037000DF59B6C5707F96F21F86FB33655024F4B3
+:10038000B97C2964213F9B0BF54CE7412BD307A097
+:1003900093A98A96447421B8993E043EA62B3CAAA0
+:1003A0005C847613B5740E20BFEF78E3EF796417A1
+:1003B0001DBF1AEFCC72C5F2B29EA77F6A3EEE63F4
+:1003C000453DF5600F038A84DDEAF1BE57FD24C484
+:1003D000FB6811C6133C67B43199E34C34A54F4810
+:1003E0009262F1042DD244F958F75B3DBE14CF73ED
+:1003F0007FB092FCE83D1946B8BAC79BA9662C0DA0
+:100400003C74DD9D737F7E6CFFA00916939D6D4744
+:10041000FA3AF2D1775EC4EC8AE3A780F8407B9B7E
+:100420003C770A44F0FA4C272821CA4376C848A2F0
+:100430005878B92B6F36068899DFA3A2D09E7F48E3
+:10044000570A49DE81A726A49DCAD5E2D28DA8BF4E
+:10045000E326E6079648A111288FA60631CE5F94C1
+:10046000C6FCDD0761D6E3FD10B110FFF301384E85
+:100470002F0017D30741617DE2CAC905189F1635C1
+:10048000983D1B91CFC2F4CEE1E49FF9638FA64B58
+:10049000782E2CED14E2A7D004EBA9BED1F9A8D593
+:1004A000F8D858A454D0F90AD35B373E83FB77368B
+:1004B0009A602BAE737AEC630F435C3EDEEE299FAD
+:1004C0004EF37648A0505E0DB4D842DBB268FFCE42
+:1004D00001940FF4792B3C15338B70DDD945C0FAAC
+:1004E00086D6BF00E9679653C81EA6F46719E07365
+:1004F000C37CF93DF967809F2B2459DE00E2421945
+:10050000EFCBE3875F7F6DCEDA3CE6274075DC7684
+:100510008F3A9FCF6FC55840E7DF6C0B6DE57AAB24
+:10052000669884E7AC7CC966A2FC7F14E333DC0CDC
+:10053000F0B9DFCEF47FFC4EA65FF833991EF7BB0F
+:10054000987EE9CF61BAE87B6400F577BA48A922C2
+:100550007E7AE3A3F73823F8884A30A7DED1FD7E00
+:10056000A5E60F050D279F4C263B6892DD64A7F991
+:100570008D689878EE73CD63427256BC5CD5C7899E
+:10058000CF82A68FFF30BE849E333B259C7FAEA9D1
+:100590006B00F96FE2F9AEC8A3C52AE4A19D7747C5
+:1005A0005AEB467A7E47E3703A21C611107648FA34
+:1005B000947AE2630DDBC9AF8A44BEBFD3D659E259
+:1005C00074C4F8032A3130CFD46A7966AA7C39958D
+:1005D000FC6216AD3B96ECFAA60F68BFC001E1873E
+:1005E000A8D7F9BE387FDAA5C941A7F92D561FF95A
+:1005F000D38E964FEEBA1DE53073DCAD5ED9159BF8
+:10060000FF3209C14BF67DE9DF9FC9E0F94EDA6A96
+:100610002E6C99EAC479F7D9F7BC4B22B8DF797C04
+:100620006A1A8EE7674AFB882E70654D4BA7380023
+:10063000217EFEC19CC9FBC8C466B86759A99E98B3
+:100640004C4E1517772BEC186F0C71BE9F617C4BCD
+:10065000E660C3FC5B5DD986FBB7E7E41AEEEBFB13
+:10066000CE70171BE691BF52BD8D7CB0DE619B1C26
+:100670001A21911D5CF86C19F33FB784F88FA2FC26
+:10068000AC58389C29DBF0DC3314361AF7A6927F7D
+:1006900026D6B5CB5B5EDEA7B87AAF6BABC0D737DB
+:1006A0002CF55ECFF6560F5E6F5D8B71E40F14472D
+:1006B0000ADFB8C719C473EC187BE90617F2F761B3
+:1006C00051CFF56E54AB7713EDE88ABD4A2E613FEA
+:1006D0000765A07A48AF7B13ED08E049AD0E10F432
+:1006E000A7FAFBCC8F44DEFA8AFCBE5FBC7D6B347C
+:1006F0005464C8338556CC2FA89FCEBFC9B0952E61
+:100700005CC673E87AC88ED93F3CB4E5DD41257CF0
+:100710003D40756D15E5055C3FD923897597EF79E7
+:10072000775046EC3EAC3A6E980F4F48FB0CE3B561
+:1007300059C6F1D393F7C53FDF5B3CAADCF488557B
+:10074000C5385DF9ACC4F92AF1BE7E9EA97B93142D
+:100750008A9BE6661BF753554E051407554D98477F
+:100760007AC8EB7A7C982B434D4F716E80B6EE8C35
+:10077000BD4920FF8C758FA2ADD07902FF25F2CD47
+:10078000D1BE0AF8E2F6C9F288FAAF23ADEE9FBEF9
+:10079000C3791D7F063789BE234DC4DD8286D326EB
+:1007A00013E5BF3EC25E0A9C11533AD2E8E2E40070
+:1007B000A03F552F4909980AF1FEF0CE4FECA8FA58
+:1007C000519E412FD8516F9F994C86FC13A5988755
+:1007D00063CFCECCB9947F6EDF9B1436FD0C7E3C8C
+:1007E0005473202D2C177EFF00D98DD84701F48F2C
+:1007F000EADF81BEAF427182F8A7F132CF90A3CF7A
+:10080000E2BAD507451CC0DB8EC47EF6BEB87E16A4
+:100810003609FFB5E32FD53B55109AE620DC208C36
+:10082000FE0FBF9CFFCFF43832B8CE213FBFB9BB1B
+:100830005FEB7E5F7D58F8FDF9E66F3FA2387F1EC3
+:10084000F35FBCDFEB72D3FDBDFA7999FD52BF7E39
+:10085000AE599E1EEA41CE65BA5F296EF6D75AA7F9
+:10086000D8B776E2C5BB28CFD5B6A086A4EEFBE804
+:10087000B47ABD0CAEB87D76ECB62D0E39627C44F0
+:10088000F5FCDAF26DFAE43C41D750FE853A2DFED4
+:1008900088BA06F3AA2583F2EA2CC9BD0DC9E196F0
+:1008A00081E524BFC312845D1E5EE21E3B9EEF6E97
+:1008B000B11C5D77507D06993966DAE72E4DAF772A
+:1008C0006BF8D2EC96D92328DE7FD2B0F0B042513B
+:1008D000CE93CDFBFD1A025C1F1E4EF30D5D89E722
+:1008E0009C1914767E38ADB39DF0A8C31393A5A0D0
+:1008F000C4EBAF8DAFFF0E5B7C436B982F0D97520F
+:1009000046CB3F26FF847E598B8BA8CF8024FA3BB1
+:10091000F603F3A0A719675802A17D0AEE5BE50E66
+:10092000739DBA0C042E9058DF574DF8DA4AF9211E
+:10093000B11F9DDCB4E78854D0038E9160B7D7C255
+:100940002D12FBE0DEF0871FD27DDB3C71F8616287
+:10095000BD7EA52ED5EBAA6DC9A1AD789EB727FEA9
+:10096000DBB965385EB52DD9497DF7D9976C018A19
+:10097000CF67B7DA4212DE3F9BDED9467DC8D99DEC
+:10098000F96E5C012A4DAEFF7C8DF2FC9F2C6C173A
+:10099000006EE11F57ECF4D16314EF6AB7A548402D
+:1009A000F5B52AEEEB3DA0FC6A0AD7094B760D0A95
+:1009B000D9A4589E21FF706169716673924245FF08
+:1009C000D90377F725FCAADDF4FA30C6C3E4278EF5
+:1009D0003D86CF2D7B25C543F504E401EB6DF1D6B3
+:1009E000515BA83E7ED1A2EE27FE2B5EBD63601652
+:1009F000ADFF717F207EA2CDBB06507D14ABDB7BAB
+:100A0000AEF7CE3767F785BC989C743C71FD1FD755
+:100A1000F848EFC9928BAF9BA146194C76D1340BA5
+:100A2000685D8F2C29E4979D1B92B94E4DB4BB6332
+:100A30001ED1A72CD7F1877E60CF24FF5181E5100E
+:100A4000DD90BB7523CAE93B4FBA96AF3B47DE95B5
+:100A50001F6F9F6D556F917D6EB2312ED29E64AC2B
+:100A60001B74FABF9E34DEA7D27EC1804354ADBE54
+:100A7000641CE761BF87CF7B82AEE24790AED4E4CF
+:100A8000DF35DAD7E1C1E797D6FFFE8DF7582E9B09
+:100A9000FEF133DAF78043E031EF09F925F60395EB
+:100AA00076817B006CE1F3EAD74F6FFEB480ECF007
+:100AB0007463EE48D2E342B9F5D48BC8E7B994D653
+:100AC000638F23DD79E023D64BE27913F19B7649DE
+:100AD000627E97131F78FD1EAF4F2EEECFEECC7DBA
+:100AE000DCC28DF92CBFA9725E5FD263F46C2FFD5E
+:100AF0008A764E7D7DFD7CFAFAFA3C67B1D0D7FB51
+:100B00001AFEDE616D3D47FAED782357227CF0CA6C
+:100B1000F5F4D682B4387BF9A570F97B357CE4888E
+:100B200069CD6FAC688FEDF5CF58D4F8B8F713F1F5
+:100B3000F82BF5A0022EE700914A386F2173661C4E
+:100B40004FD4C7E40C389EA01D4FA2F3A05F4ED433
+:100B5000282C5533196FA7F590264188C7C1C96E57
+:100B600017D149928F710FBD6F98063543880F9347
+:100B70003DC238E15AC227B16E999DB6EE8E2CDC8B
+:100B80006F6D7F5847F5CC5A8BF08BC08264EEE7CF
+:100B90007439E979069C7986FCB2D6092E33AE33D6
+:100BA000C70CEB2DE962DE8D28E7C30716BE4BB8F4
+:100BB000EBA7E69AFEB4EF51C7B3F99289EABC50AD
+:100BC0000AF58C9F7DF427EFDF70EEE7A04CA4BA06
+:100BD000E29EFD768EFB89F8C42250795C0911CB28
+:100BE000057CEE8BB13F6CDB0B31BEBE18F75D238D
+:100BF000F509F7A53DE9A5E703E5904379E96252D8
+:100C00006A01F1B3DA2EE8A37D52B7123DEB74040A
+:100C10000897BD98342C44F9F445497D80EC199F20
+:100C2000E33E36702C3944F9EE5159AD621C3ACD91
+:100C30000A12CE8FF6D7E4D2012C97A8459BFF8DE0
+:100C40008BC725151EC629E1A28BE3F2F884BC539D
+:100C5000926B12FDD98F62FEC44EB321EF94146AD9
+:100C600078CEDF5D5CA74EFADE7CD5BC74B958F453
+:100C7000BB25FD4C353DD58BCF68F783109605CE4F
+:100C800023EA85F157EC4B91498F55DAB88AF21A6D
+:100C9000DA5534D51E9091DFF1CDC2CEC69BC37B11
+:100CA00088629485D5545F3461DED3CF817105327B
+:100CB00073D91EC6E9768A6BCDC379EBA41AEE63AD
+:100CC000EC54D720DD28B5F2397E059D4C152D9FBB
+:100CD00097839BE914F031453B653A1DEA98DE069F
+:100CE000F54C6740ABC8FFA3C341CE6BF08493FBC8
+:100CF000C15B2B4D547794FCBAE7FEA1518B27BD05
+:100D0000CB011DAFF4A7CB611AA0FF65F7208F219F
+:100D1000391C4712E591E8A7132122B39F5280C8DE
+:100D200026FCC0C5FE5A010A8FA75EA71CCA22AACC
+:100D300099F19B447954F46C17BB35BBA8255BEB48
+:100D40001FD35357B18BC7BABED0BF32A90E4DD4F3
+:100D5000A37EBD24B9BCCB85A1F8B35D27E79A314A
+:100D60002F951497AFCCC6717BF1B773CD98CF4A4E
+:100D7000C697EF1A8EE373BBBE13E3C2F2628B1BFE
+:100D8000BB983517E74EC1F92AF9672151F4438A18
+:100D900067AAE88F5769758CBAE6376E27FA8B3ADF
+:100DA000D4E1263EED58EC133E2A678BF78EC3A69E
+:100DB00087F75A70DE498B7A98FC77853D9CEA422A
+:100DC000F9AF5A33752085CEA7AC62BECD26705AD6
+:100DD0009D3FBC1E48C2F1CE9DB92BA5E1D73E0771
+:100DE000AEFF25ADAFAE191120FF551B25B7D06C56
+:100DF000F9C03928C3F6560B106EAAEFF7E468F570
+:100E00000CE747979BE3F760ADCE69DF999B4B7A80
+:100E1000EA2A163818646415931C8F8FF675D1FC76
+:100E2000688AB0B72ECAE5DEDEE9E012E51B9A9FBC
+:100E3000783DFA151E009F3797A817E97E75F26571
+:100E4000CEFBE78A3E5E17C98AD9AD844A9B87FCF0
+:100E500007150859393F4C705EA95329DE2DC2751C
+:100E6000501E253E3548216ECCBCCE528AABB8AE62
+:100E7000A904F7A9B6468615E173CFDE7DCC2AEC2E
+:100E80006E88B03B2D2EB5EC3EF8F86031F4419CF5
+:100E90009F55EFBEF4DDE728BFEAF30E374D8FF91B
+:100EA000D70B2BB9DF0487218EE87E37AEC9C6F594
+:100EB000F6F8E6518B68DEC48FDBB289AF496D115D
+:100EC0007E8F166DF974B03887DE875C947E4E3E57
+:100ED0003EADE589D3769117E8BD30F77B8DE2BD55
+:100EE00070AD8673D6B648A100C71FD13F2FD6F884
+:100EF0005B71B0711FE1278B373D3883ED2824FAF1
+:100F00000A17FE525C587A44F4CDCBB61BFB8D6AAF
+:100F1000EA9B693E84AD640F2BEA13EE6FAAE0BE34
+:100F2000B93A3EFEF7D0377B4B347C6C280C65BE5B
+:100F3000E4797DD51EE261625F5C05CA8412AE7BF6
+:100F40007D32EDEF35F78C3FF42FD0DF9389FABD7A
+:100F500052DB9BE4E460B958B99FA8DDBCD2EDA494
+:100F6000B1E6B75B4CD453E3C4773E80F8E7743FF7
+:100F70005EB25EE2BE0336F5631B2C7CC5A610BFD5
+:100F800085AF0CE43E04FB25AE0FB7BC625B4FE3BC
+:100F9000E0EFFA04E442C2A13B6F201C269884F5DE
+:100FA000A6C0F341F2300EC3B8C823255ADCD7EAF5
+:100FB00000081719FAF9A096FF6B53460EC4CE39F4
+:100FC00036EFC020437F12D4EAED123A27D58DDBED
+:100FD0006F10F793041F7B3EFC8764AA7B1BCDBE7A
+:100FE00064C2B5CF1F1ACE7D4C6F72F7621A82AB06
+:100FF000BCA7F47E3A23FB6A7A2B79DE2CE4A5D9D0
+:10100000ED9B7E05BEB4C4F4A2F337557EADC24A53
+:10101000B8C843E0249CA4F6E0CB413BF5851B8097
+:101020001188F320ECF9FC1913BF772F859C7F9D65
+:101030008063EF19B33B84CF37687191DE3FBBE229
+:10104000ECCCA6E1BF49AE3EE08AEBA39373D20D90
+:10105000E314F70D86E7FA960D37DC47796FA5F5AF
+:1010600021A0B4E695C6EADE3465B4E1B9A752A77B
+:101070001D60BF6F7D9871A97ED33DC6F3C8CD3288
+:10108000C503B820EAA532FC257F1B038120E96354
+:101090005CBBB18E2A8BD471DF9874C86CC0016CB4
+:1010A000D7C0A5B6907F519C1C024344DC4894B73E
+:1010B000F1FB8BDA8332D77BB543B150CDEA49DE01
+:1010C0003719E4ADFBA32EF7FE3EA3DC07CE31CAF1
+:1010D0007B906A94F7E0C546790FAD31CAFBC6D55F
+:1010E00046B966058C72CC5E3FCE307F445DB961F7
+:1010F0007CF3F3B719E68F0ADD6518E76EBFD730CA
+:101100003FBF7EA1E17E61D3D2EBD27F51B8D63012
+:101110002F51FFC5077E7B55FD07F057E81F581F6D
+:1011200065A88FB0EBFFCF0E4EE87156B783EB8CFE
+:10113000B36F92CF329E302112203B284B663B99F1
+:10114000992CE2CEFB07CE1F5270FC81ABD892499E
+:101150007596563FF8B438A4F733897DE39D655200
+:10116000C2FBFE24C3FBFE6B7D57E76D0D1BC6451E
+:101170008780BF9BF11C71BF4DD47B5261B8ABF42B
+:101180004CCDDB44C75EE0B4DDAD5FD5BFCF4BECEB
+:10119000B760F9217EAF384F7F2F434E51DA1D9F44
+:1011A000D4FB31BDCF4DEC7FF5BEB77B9F26EA98CF
+:1011B000EEFD863BD3CC75B4CA75F57E49659C734C
+:1011C000CB2875B0D74B4D00F6C926EA93234121B1
+:1011D0004C05E83D7494FEA72224F0CCBD84C7479B
+:1011E000D380F17345AABB3790C7C777464A057CC1
+:1011F000443FC55E758417F57A4272AE2B267C6239
+:10120000DCD7C3A81EC9F18A3ACF26A3A4302F0D7C
+:101210009CA7005DFF215D19E5F5C6F092DEEC2686
+:10122000F1FBA4067F98A9D9E9E6EF9712F1C588EA
+:10123000C9C5F569E0B7127FF7F3351D6E6CAC8E4A
+:1012400039BFDEC2750C68FDFCFD9AFC75DC639E3F
+:10125000C6CF095C6231E6E5FB9BF6B35E9665B6E8
+:101260006B78490DD7E30F0E7178F87B38A5D82D30
+:1012700070321D07192CFF94BAEB5AFC2FCB3C6B34
+:10128000C0A1E0B57ED7F5BE3CC6B758FFC4068105
+:10129000679ED83094F1F3D8FAE7188FBABFE643C7
+:1012A000837FCC5F7DD4E00F0B02C70DF723199D20
+:1012B00016C21F236F0C9A761FCAAFA3D1564AFAE3
+:1012C000403B7898F4AAAF1FD9903B85F6BD369F76
+:1012D0005FF339DAFCADAC5F9DCF63FE233C8EF843
+:1012E0002309DFA7093E759C43A7D6BD9063A6F7E7
+:1012F00089521F37E1CABDE11FBA9F994A87F33A65
+:10130000174DAE530227AA1943F55FDBE401E574DC
+:10131000EEB6A156B3A023C57850995D8CA74D2792
+:101320001AB538D6132ED22689EF89E649CA4B0B57
+:1013300070DFC747A94F913F542FED2C20FFAB2EF4
+:101340008C3C20E1FA5DFDD58D241F09DB8B41E942
+:10135000CC077F7776C6142890D055F679BFBC9716
+:10136000FAC4337D02E7A842D9DD784C8CADC21FA8
+:10137000DFF71E60FF3B898B119F813F4B029F72FD
+:1013800044ACB3709D8CFEEA73B42F7D4F46EFF7EB
+:10139000E83AD9A78E97462DA24E8C6AF5E266AF41
+:1013A000A8675F4AA04D54E312FE4894E3F5D323A7
+:1013B000094F3FBFC90654DFE2FE8AA924F6FDCAE1
+:1013C00000E485EAD877ADA2CFF4FCC516A638A50F
+:1013D000E3AAAF7BB378BD8C6C819766FC33C62DD6
+:1013E000F2C348EBB0592971E73D048C6377101EB6
+:1013F0001D8763BFEE15FD3A3C24E25EC786C18CB3
+:10140000B7AF3878E218C5AF7BBC6A23C975A1C9EC
+:1014100055CADF67A5EE61DC6CBFD7C5FBE27999E1
+:101420005F8C436B494F2BEC11C6D9AE85ABF7C629
+:101430007FC7A2D6E7F21847761590DDE8FBE239C0
+:10144000F67BE3F06FFD1CB175AEEE073A3EAC8F54
+:101450004F6F7E6AA486EFCFF7F5905F8F69726950
+:10146000B3F48CC75FF28AF778DDF4733300E1FFE1
+:10147000B63E98FB917EED15FC77CC457E18DF508B
+:101480008A48BF2BEE72B849CEFAFAB88EFAFA55EE
+:10149000F6E91AEDFB8AF85F5A23F07BFD7E5412C1
+:1014A0007A0D6C1078EA8ADD478F3D8EBB2C79353A
+:1014B000BF98F281FE7CA29C51BE23F9FB3B59BC34
+:1014C000FF42F99EA7F51371FB9F2BD7E850F19EC1
+:1014D00036BAE5D230FA3E6D057D0F5740F621F061
+:1014E0002F6830E25A28AF00E11BDDDF6B01BF1F20
+:1014F000B369F9C4A63F3FC46C78BE3EC597548A11
+:10150000E77F438B1B383F64A2EFB9B5F8D4A0F551
+:10151000DD89F84B43ABC04D1B32AD5C4753FD43F7
+:10152000F7F5FA67D58702375D9525EA6C3A27E922
+:10153000593AB28FEB852BB8B884F91EE5986E55F1
+:101540008794923FA92B399FC937A29EE97DC85F36
+:101550006FD37004911FBD5A3EF4D23A74AEBCBE34
+:101560009C274BB47DB1BF60FC6E2CA85AFDA0E156
+:101570006F1BF619F087FF037A5FA88030310000F7
+:1015800000000000000000001F8B080000000000A9
+:10159000000BFB51CFC0F0030947B0A3F20FA0F13D
+:1015A00067B2A1F2B3B950F9875950F9FE68FAD180
+:1015B000713B13030323137E35F8B0083303830C08
+:1015C00010AB00B10E33F9E680B089280343A904BB
+:1015D00003030F906604D23E405C06C4FE407E27A3
+:1015E00010CF0262197106864B405A5E8C81E1A5CC
+:1015F00028449F2D90FD438C3C3BAD792973F32803
+:10160000A60C5BCAA2F285D41818BCD51918266B93
+:1016100040F80648F2AB8062C26A10F611790606FD
+:101620003D205F5D16BBB94781F2FA40F9DD1AF83B
+:10163000EDDFA183CA773543E5E7A1C937BAA0F248
+:1016400035DC50F9AAEE101A00B1C92A3BD80300C4
+:1016500000000000000000001F8B080000000000D8
+:10166000000BCD7D0B7C54D599F8B98FB9736732D7
+:1016700033B949263079C14D081030E02484808A7E
+:10168000701322449BC204698BBB6C77C4D646148A
+:1016900008EA6A7C6C33790701096A77295A3AB1FA
+:1016A000A2A0B44D5DDC3FB5D69D40DCD2D6D6A01D
+:1016B00058E9AE6D23F5DF5A57D9A052A9D2B2E747
+:1016C000FBCEB9997B6F2609E8EEFE363E6ECEBDA5
+:1016D000E7F19DEF7CEFF39D1345F4106D0921E7D1
+:1016E000E1873E5F25F4273BF924A48790F9F01C9D
+:1016F000922373E019E3EFD933B8B64F2045581C55
+:101700002495841410F653D0D4B9599C4BC8641254
+:10171000FEF1CC425A1EBABE8E0468F9F5ABFF004A
+:10172000CFCED5D5B557E984E4ACE93BB69C3E8332
+:1017300091B8102D25E4412212920BFD15C7AA7C09
+:1017400084B44367971332299663C44AA160D002D8
+:10175000217FA7F28188A8CBB4ECC75F93F3309FB9
+:1017600084282451821585F3EED1ED9DF5CDA71F78
+:10177000DA99750AE1FFB71298DF44EDC8ED6CBC49
+:1017800018FDE73CC54B5E727CEC27A7C152268052
+:101790001FFB776304EF9BFF57C6CB25E51EBD8279
+:1017A000CEB74ED4E2509FF465C8B41CBC452609A0
+:1017B000817EAFE8115CFAC4EBD249486D9F0FF10E
+:1017C0002BD4FB93F07D8E08389F2977BFD9DB158A
+:1017D00024E4CC5A5F18E94323242B73F47CBED64F
+:1017E0004C48C26D29AFAE16A2385EF8C7C5B47DAD
+:1017F0006CB518DE0BF0D4ADCA80F766BD3BF93886
+:10180000A3E983E832C5A3CCE943AE130DCFDC4F87
+:101810004F1FF227A48FECDB2DEDC8C5AF17E27D7B
+:10182000FE85D3C7A71DCF5CD7D17CD582704CB9BC
+:10183000BBD843E8FA3F50BB2A3D9AA2DED8EB5A08
+:101840008EFC1EAC23463C45BB2DB09E38CF984D38
+:10185000DEE093AE8F34B2BCB7D9D64B9A5CB9A652
+:10186000771C7C4841FB7CCD7E9526497F338B16C7
+:10187000654D84FE64DE5FA7B62E46806E81B62974
+:101880003EA49EB204A1FC414224BC974320D2B2A4
+:10189000A219F1FB0428C5715D4CF8D462D1369EC3
+:1018A0002BDF6B5B0FB2262658E1579A1484430650
+:1018B00036E1F22E82C28DC10D439C9F06E57B6C02
+:1018C000EB2FFB48C243E5EA96E272625D07934E56
+:1018D00005C1A4D37B2E4CAE38C75B6D87F382DB8A
+:1018E000F964FD77669BA2F1DAC9E477269E28F2B7
+:1018F0005E815F2CEBDEE52287844B0969CBEF8CA0
+:10190000C1DB2EF8DF65489F20B448577EB906F446
+:1019100044F60932C0E931C9239489F57A898EF4F5
+:101920001413EE20504FF245104FE6F7B1E1E27488
+:101930001733FA8B69BF9FE5DD7E96EB3352E17A70
+:1019400073C884BB08E7912CD379BC7B17FD1FA516
+:101950008F589910DF2B8CFE5E07FA90CAA33A7855
+:101960006F91276EC12ECFEAF8B723CFBC36631E26
+:10197000A5C7C1B044405CB53EE3366A68FFC7AE58
+:1019800014E26E81C34BEBAFE070BE686415007D5E
+:101990000ED6B8917E572CFF3008E47BEAD02B722C
+:1019A0002A7E5DB1C8958483FEB7C93A3FFADF2429
+:1019B0001803F9B206E9C8846B43B984700C2E127F
+:1019C000E230CEC0AF7E7FFF1514CE172B84B05B04
+:1019D0004778FD848E3768BC1F1C4F4E10737C9D6A
+:1019E00068804FE7F823EBA186D7005F36688A7ED0
+:1019F0001F1DEF66297C14F41899CCF4438336A399
+:101A000006D64712187D2C1572B05D9BAF7512AECD
+:101A1000BBB436A5BC6AA08A422B87EFDB668C0B71
+:101A200067DC353C64A1EBA6D70BEF1FB0C039478C
+:101A3000F0077F97467F594016C03ABFE75B959EF7
+:101A40002063F7F776B3DA22BB08F9B059BF7FC03D
+:101A500035FAFBCD1269EC2B1DFDFE1A41E5F88825
+:101A600029609F99F31E99A72F88F47D33885F4AD8
+:101A7000EA37EFF3B4C856F9E398C7087E3F613BF5
+:101A800035786B2C57077E8BAE14A01F99FE5399A7
+:101A9000E4C79B0FD433BE73C0DB11FCEF81772208
+:101AA0003E7ECFD7DA09F66A9B8BD14B7BB6186E98
+:101AB00025A3E9C55C0F138F17BA1EDB040FF2874D
+:101AC00049470DE2DA71D77D223ABA03E8E892FF7E
+:101AD000793A7A10E868FEFF493ADAF57F918E92FA
+:101AE000E5E5682FACE47DF50FFDF62190CFBF3022
+:101AF00024947BBF58C4E4FF2FA24C2E0E92E8F62C
+:101B0000F9A00F8E4B28A7068D363FC24B4D629829
+:101B100007FA5D94FE5E017B692695EBCD2A3EE9CE
+:101B2000EC0B56D1EFC7AEFA301FF4D731BAB6601E
+:101B30007F13326C18B4FD4B23656A8043D9C3CA46
+:101B4000C32D6763609F0F0AACFC2F2D678D188E25
+:101B5000B7AD7339C5E74AF895C2B17A9160C453FD
+:101B6000D0C54F0485E1A586D8F42A5D979F0894D7
+:101B70005ED4C866B4AB098910F40F8BA99D60B11F
+:101B80002F9A4081815CAE71A3FE73F6FF12B70BF2
+:101B90009D76DCEA45652ED017EEC86979883E57F8
+:101BA00046042C03FE350BDCA22118A007228BDC97
+:101BB0008F82FE8BC8C4A5A5E0D79586DB66779D8E
+:101BC000E67A8CE2650DF35BB482FA39C9FAA74D67
+:101BD000FDEB98CF587461CEC32C5FBBE8F4401680
+:101BE000CCBB56084F8786AA56F045BFB5FF34D305
+:101BF000BEF103DE7EB1E6DA74460751D4AB263D72
+:101C0000FDF88DAFB860FE647516D2E5EA3AC96694
+:101C10004FAEAA49B3953FBFE8DA71ED7012B5E057
+:101C2000C142F7813C82744A7E43ED144AA7B1EA6F
+:101C3000E128DA2D2705BD8D96D317374D857EEF28
+:101C40001133B1BEB0B869E610DA5BCB90FED37841
+:101C50009FE94AE3EF8B40AE4E17C9A33AD8A3E3FE
+:101C6000FB051D9CCECDB22B188D09743DF5985601
+:101C70002E8D83EFB821D6A6F21BA6896CDD3A62C1
+:101C8000ABB4620068C02E37326A1AD1FE33EB5310
+:101C90003A9E2666C3B8317C3F42C7DD745EB49D70
+:101CA00097D922247DF6AA7432CE3CDA1DEB4FC5BB
+:101CB000BF914ACEDECCE1238758FFA64C4ACFA481
+:101CC000FDA7A86F3EBB78FF67C322190438E588DB
+:101CD0008AFC50524DACFD10A30CCB0A2FBA431115
+:101CE000B590E2D35D2AC2344847E9A386AC031E0F
+:101CF00062B8DE5BE9DAE65BF872EB9F25F4F36F1E
+:101D0000168B5A406E6CEDBF89E8141FDE509C6044
+:101D100079CE8D2AE0692B75B206617CB98F001CE3
+:101D200069F9F4773A4E9A46E23AED4FD6FB122221
+:101D30002DCBB5246CD04F7E2D2C78A99C381C2A35
+:101D40006A91E9FBF6B504E52301E961A19FF6D0AC
+:101D5000CB8604F4B3868401E0F6E03A9C6767E939
+:101D6000BAEE42FAFE4C9D8CF103728EC26BFAF50C
+:101D7000D4CFF0961003C6DB9A43E23EB4830DC481
+:101D8000AFA2B1F5D3771593C43CFA3DA3B21FC6F9
+:101D90008FFD3D617C49985C93B93C2132A53F1889
+:101DA000BF490BDF9782FE5412BD499C6F59672DC6
+:101DB000827EAC136FE90AB906F0DB5E46F9208536
+:101DC000DCBB4314910EE2E1552B8B528C738FA830
+:101DD000A37C32CBFA5905E11FAB7EB29E4C12595F
+:101DE000D0B521005E482488F3CB24233F0694B36A
+:101DF000F87C279146AC175AD8D30FFC966BF45554
+:101E0000012EBEE6FFFC315C37F28806762C85B6E3
+:101E1000F87C56525E80CE81F9BD1716D1EFF08B5B
+:101E200009CDA01DF83D8321747E758271B9746857
+:101E30004201BEAF596D07BB2440C2027CF787E563
+:101E400098D5AE4F27B46C8BA790E3C59584897C59
+:101E5000FCAEF503EB68258D9702300F068C7F05ED
+:101E6000BF699B3F8A7ED8879EC05C18EC4E6FE0AE
+:101E700051787EE8991247FF2CCCFC2D95FE03F299
+:101E80002E7DA16CF36F320C7B39CBE1872D937CD7
+:101E900038CF8CCF12EE5F1975D32725E1A210D56C
+:101EA00003BDECAC9109F8FF3E1F83C7842F4BBAEA
+:101EB0007701EAC7B07C12E0A0684138CE90730980
+:101EC00058E24009C1F82985EBA403AE930EB84E41
+:101ED0005AE16A52D97C9DF662AC9A943452E07E03
+:101EE0002872FF83DA4D60379E21EF18B540389194
+:101EF0006B50CF0634D6C6A70E62B042231AD281E9
+:101F0000D36EA4EBF49ECDFF5AC8CB3A11601E14D9
+:101F10004EFB77928FF48265898CC485D72D34F17E
+:101F2000A57FE1DF29FFDD74D44580BF281F4BF07A
+:101F3000DDC5BFDEC4E3C3EBC0BFA6F8FB12890456
+:101F400000BE77898871A877C9CB81791639794A1B
+:101F5000E4F6092CB1958F493804725CF6750E4A87
+:101F6000014483496FC2795CC73093F33E467731B1
+:101F7000A2B6A03EEC66FEA7194FFD728FDD1FFED4
+:101F8000CA2E7BF946B26A12C44B6F7CC845E2B4D4
+:101F9000DF9BACFE3D5DA757450DE1FB0A69EC04F4
+:101FA000BBA4CBC5EC8D751A9121FEB9E1FF7DA3D1
+:101FB000F27A3A9F33200FE683FD4EC1B7E891F5E0
+:101FC000C1B862948E9E5F9B105E718530F6FCBA3C
+:101FD0005C832BC0FF8E6D77A19D499C71D08312CD
+:101FE000C6412DED10DE1BBAEDF39B68FECEF91253
+:101FF000F200CE77FDBEEBD13E1F6B3ECABED4F6DB
+:10200000A64F126C711F93AF4D7A77F27785A4B308
+:10201000B80E558368AFFC3A2DDE86EBDBB800D6F0
+:1020200077A2F69741FBEC4FDE7EF1A71C7FE90417
+:10203000ED37A8C3CB60BDB7047B22C09F661C6B85
+:1020400023891979F457D7739B6360BA8DD40B5DDC
+:1020500060BD7C5A4FBA807AC5E3F7778ADB253FAB
+:102060003AF02D05ECD4779F7C6305D80137FF400B
+:10207000222AA5875307FC2481F64A5C01FB663DB2
+:10208000A5BB38961395D75AEC614AD1B80E377F65
+:10209000D78F76C4FAA7DDF13ADA7EFD3FFF762EC0
+:1020A000A17838D53AFCAF7940CF4F0A2CEE1A1BF5
+:1020B0009A7B2D7DBF5E267F1B494147D74B8C9F66
+:1020C000DEF97EDA1AB013857DFD5FC47EFBBEE0CB
+:1020D000725BF4F11AC985E3D27AE847C4F60BF1D2
+:1020E000E90283CFEA0F98F1EE77F60B0CBE43AE10
+:1020F000B807E0DBD7AB4469BD4DFB4E235D2FFD38
+:10210000EEB70380874D87EC76FAA67D52C23D1765
+:102110009F6FC01334A85009F864FCBCF1E006D4EA
+:102120001B1BFBB69E067EDE74C86593FF142FE171
+:1021300004E0F535295C07E57F7A22A05354BD3DC4
+:10214000B8370078A5FD5EAF50BA5AB9D0DE0EFAA6
+:102150003F9B39BA3FEA19A2DFBCA96F0B1BEFE026
+:10216000677F0FF27613617ACAE4E7B7E1979CD1F3
+:102170007A668B648F6F9D212F56E23EE0BEAC9451
+:10218000FEB3A9574CBEBEF9DB67F6C4E8F8EF3CD6
+:10219000FD1F7B62741EB7FCE5FD3DF7D0F991E7AA
+:1021A0003D1AC8AB4D4FBE1A2016FC3F26B1FD802C
+:1021B00053FB9F787C37E59353BF74A31D78EA8760
+:1021C000BF9FA2D3F99FFADE9F26819D7AFB0FAFB6
+:1021D0009A0CF8B8FD99A593C7B3D7816EE36EEB5F
+:1021E000FAC6B17FFD90009B20843CC79F8E753A54
+:1021F00072504A4088E0DD13EEB89BE267137DD74A
+:10220000540EEBB601F51594EFA5F8DE78A0EBB40B
+:10221000343715DE637962089E893C128275BF7679
+:10222000E59515F0748575A013328C7AC2D96ED3FA
+:1022300071BABE978EBD9ED49E5000FF9B0E6C61FE
+:10224000E3F6D1F50C8C5ECF77E197CB46AFE71183
+:10225000C91E673A436EF9E66EF878300BD77FAC4B
+:10226000F5DCF0CCE7C6F5EF4CF930119E1B040607
+:10227000D70EC97845027E7CFAA9C77707D93AD725
+:1022800051C49CFAF69929B0C9FB966BF88B2027AC
+:10229000877FE8D6C0AE5EFFC3D790EF4E3D734C4C
+:1022A000D1717F9AF804AA274F91919F41D09B1B2F
+:1022B0000556D8F4983FE10E24D76B63BCBE560F89
+:1022C000E0FB37F07D9CF1C3C678FF6A21C5FAF9BF
+:1022D000E422A69FE2D988970DFAA0A2F9ECEB2A96
+:1022E0002C84F57C6319D0DF58EB69CE5F83F92F1E
+:1022F000B0ACEB638C8FC7E2D753BD6E59481FBD9E
+:10230000CEA7B85DB1292EBC966ADD096965F1BD1D
+:1023100031E2DEE6D349178A6CE773B3BD39FF8932
+:10232000F87CE2795D1CDECE707DEDC4DF3BE752C8
+:10233000EB812259E07AABA736D7A2EF3C2EAAC791
+:102340000AC1EE6C8CE51526E1EDEC9350BEBFB3EF
+:102350004F427BDF2927368EE1D787CD710EF5CF2F
+:102360000579F6CEE1EF737A64F4BEF1C01B4A8CB6
+:10237000EB85B8552F407F29D6E372DEDFA6E75202
+:10238000F7B7E9C0E994FDBD2D1B5F00F8DF1E74AF
+:102390009118EDE2ED3E29659CA45876D9ECAC4E3F
+:1023A0007FE58974DA4E0A787598775BABF15A0C41
+:1023B000EC91975D04ED4739FC969B7E6FF37B7142
+:1023C000BFA52D7023D12DFABBDD81273914413FE4
+:1023D0005A0E462AD85E68DCE6CFBA34D106379169
+:1023E00063F9B0CFF9F3C2DFCBD02FC4D3744B5C09
+:1023F000E8259974403CED254308B79014712D47AA
+:10240000FF914512D1AD74664C15ADF1C5C0E1BB6D
+:1024100030AED1441A13106F22F9A46FAFA5DF4775
+:102420009A7516778D4C15ADF13F7763A3E1A670D1
+:10243000E4DFAE1581FF36D6F8058DF67D5F73FCBF
+:102440005B793C82EC7BF2C92769792A7C13810E87
+:102450002306C2718EED2B2FE5F2F047DC7E3E2C79
+:102460009001B0C36AEF8DCA20EF84D0F518175DD4
+:10247000967FBDBCCE428FCB42A77340AF7EF3CFD9
+:10248000D29A54747A88D355CBDF3F9E03ED777B85
+:10249000BE90CF9CD908C297C7E35D03D9CB7D100E
+:1024A000DFEBBF69D98B33E87C73358940BC269755
+:1024B00054F9CA289C79C7A5B027C53A98CF3D3CA6
+:1024C000AEF768B386F2FFB1E610961FE778DDD766
+:1024D0005C82CF279BC3F8FD40F3422CF735D7E24F
+:1024E000F3E9E608BE0FDCFD6CBF0278F92AE98348
+:1024F00078CDC1E635F8FD9F9BA3F8DCCBE7B30CA4
+:10250000F0E2B3CD1FE33187DA97B4423CC6C4A3EF
+:1025100013EF4B486CC08DFBF9820E78BF4B66F20F
+:10252000C589DF29EE3E01E44BD32D04EDD73D3CB8
+:102530006E6CCEF7EB32B3370F72787EE0897E4750
+:10254000A6CFF76A8B4BD12E229130C8EF3D4224A3
+:10255000BD8C5679217B41C82A87A7FAA30765CB92
+:10256000BEC2946E16EFD92D337935553FDD9F41AC
+:10257000F1509B2FE8104E30E77BB84ACF073979EE
+:10258000581070BD6BF3255262A17BB3BF6FC82298
+:10259000DFDF482DB79374CCE441E6D57209F8B576
+:1025A0006788372C517E7F3E871C24D4FE781EE836
+:1025B00012E4C2AFD2304E6CFA37DBF87A670251C0
+:1025C00040BEC4EBFE38C89FB1FC9E4E5EFF3D0E80
+:1025D000D70639F28A8CFBCA3CFE4A1218C784948B
+:1025E00023A0C7DD9EB53B6AE8F3FECBDF3E01F1D9
+:1025F000C1779FF1E800D7F68A93012B1E4983FC2F
+:102600008E753F7E44DE9CCDC3B8D8FF27D137649A
+:10261000AB1C0A0E2BD0FE7941DF09FBD7B1572541
+:10262000E4BFE785F82C8C63C904FD82E76F0A617B
+:102630007E87D9CE1FB6F377A667E8E14D30EF0667
+:10264000251C4BC117BF49D36DFB46EE90BD7D08DD
+:1026500074E67C56D6297D96F1798765430238E683
+:1026600093283E17101D9F39AEE847308F79A42F6D
+:1026700007CAAD6953AE60FB07FF6378535DFF0780
+:10268000F166D26BE8F2128483DC2D86A7EBE84D6D
+:10269000DAE87CA54BE0F855519EE78EEC4F35FE0D
+:1026A000A82088DDB0388996867230D7C3F0D73439
+:1026B000741AE3BBA129C41677EF6810910F76BF97
+:1026C000CEF6F5CE3414ED9C41EB57117D474DE12C
+:1026D000E87998FCB15B8DA4A7DA9F329F265F98BA
+:1026E000E59D53BF48400EFDE3D42F62DE51EEEB73
+:1026F0001E1DFC8EAA5FEF6F01B9D8F106CBAFF8B3
+:102700009537BAC8353F29673A6E6A9C0A7E50C031
+:102710001F59ECA2F889E4C7AF037977A6F676379C
+:102720004EDDC7F25E9AEED577CED4C75E9F3D4DA3
+:10273000E3EFDF98F3DA03F31A67FFC29C97B95E01
+:10274000676A570FDFA8839C294E8FA66837224FF0
+:10275000AE5E3DEEF87BB85EA1F35F6BA5CF294D71
+:102760001AE6B798EDCDF93ADB3BE79BDC07BEB044
+:10277000BCA03E17C9027AFFDEC753FEE925148DBF
+:102780001109F434E5CF8D004F2569C43291FB72F5
+:10279000C0BE31E97977E7E339A817E47821E67715
+:1027A0005DE0781D2412A9027E0B8B61ABBD623EF9
+:1027B000DB46E83C81715537970362DABDA1547856
+:1027C0001EE93FDFCEFFDB0861723EA1A29C87407D
+:1027D000A146CB854749F97DB4BF06480AA5E35415
+:1027E000C92C1E32EFA8DE2BB1B8AA54EFB7E09186
+:1027F000EF3798F1DD0E722FD174F02BCAFAA1BA1F
+:10280000C9A74794E84340A74A48C77C4F57302A96
+:10281000B0FD38B63F54C2ED92ABA4B52AD8254DD1
+:1028200024A2CE06BE3D2E119687C7F8DA6DEE8340
+:10283000713E76733EA61C8CE519FCFB739CBE0EA4
+:10284000817D82F604A3A383DC3EA9191E3EE2A784
+:10285000ED4A067BAA613A4F83BDE206FB248CDF7A
+:10286000BF03F60A2D1FC9F8C76B6653BCEC33C40F
+:1028700030E0FA40B3C1F8A1B901BF37919877337E
+:10288000C8A547440DE0EC7AA4550AD0F27E55C0A5
+:10289000F8C523CD8D583F70CE9B007F73BF9A1033
+:1028A000C01E391326E118C04DDD2398D70C3E8F8A
+:1028B000AA370771BBFCF1F87BBFDD41EB3DB8D017
+:1028C0008BFB64267FCD681AD6AE01BEDA7B52DF61
+:1028D0000CF0CFBFD580FADBC245B84FF104C51765
+:1028E000ACD3BE5DEFED1AA4DF0372D766F0836749
+:1028F00016AC427B28A0FEE36D500E684FFD1D3ED6
+:10290000D5EFDF09FA7A665CB4ED9F07D49FDE0548
+:10291000DFAB87C235E9B49F59C707BBAFA6CF8EDF
+:10292000F0ED2290787AE61F705FE3B0A07DA907F2
+:10293000E26AD72B48AFC609A305D8D15561CF832A
+:10294000CC7E310A690B64F200C53B01BC1B32F43A
+:10295000FB96AB10E92C14C8A909D0F2E38F9DFCBB
+:10296000F1D5F4FB915DB7A25C743F22A33D36F331
+:102970001BB793AF58E484FB3139655EE95B2E37B2
+:10298000E3A34756F7CCD2197902FFCDDA5BA3A2B5
+:102990009C78D19EE760EE0BF792E85B2EA4676609
+:1029A0009FC81ADB47863D2FD84F240F8B8C4F22B0
+:1029B00051AF35FFB9E4EB6224559CFBAC4BC679B3
+:1029C000B5C76B4A601DE4F377E03E19E9B18F6F3C
+:1029D0008E47C73F6B956FB2C6E02A00D54FD7B37D
+:1029E0005FF9F71C80FF6CA3A9A712A8A706CAC4A9
+:1029F000C4540ADF030F897148CA3C52CBF4D6761F
+:102A000099E50B6EE7E5C7CE91B85098E4A3999C81
+:102A1000DF1E7B4464F65C9CA09E23E7CEA37DE191
+:102A2000E3DF33CB5E56717F2266F8AA2A312B9002
+:102A3000FF58E885E2E8D298D72667C5A64CDBFAAE
+:102A400017508BC59E4F5D94AC2F811C3FAE02FD8D
+:102A50009EA17E2BD0EF12BE4F5463E6614AE7E69B
+:102A6000C1FC1F36F5AC9937E3C893DEDBB8CE0B5B
+:102A7000F1C2174CFA696834D0FFD1DC389EB94FE7
+:102A800058724B2406FAD3956FCF9FAE72E4472F4E
+:102A900071942F36BE52AE38E3A8DB66211DE801E3
+:102AA0009457C51CCF7B2FA3EE7CFAE838CB48BFE8
+:102AB0003C8E407A02B87EC59C80EEBF5B6A00BF48
+:102AC00020F040798635BF60B9C2ECEE815FB9096C
+:102AD000D8F9FB6B548C679A799D2E3EEE0A45C758
+:102AE0007AFB1FBA4385F65DC1220FE0EBC8E5EB28
+:102AF000BD98FFC1F3534DB9DB7AF9FA6B6E0279D9
+:102B0000982DA2EEE9C86FCD857DF9076A54CC3FB8
+:102B10000DA40DF51DA165DF134AF851FA7D7F550F
+:102B2000628D356E7387C2F4D7750ADF07DA66CF18
+:102B3000DFA07C709D02F961BE46DCB714559EC7CC
+:102B4000EBF0EF4D7C040E5F2716FAD9B3C80FFEE9
+:102B500028A38F38A78F3DDC3F7D04E4BF1BE886A8
+:102B6000C9FF6DDC3F75F63BBD217258013BEC1689
+:102B7000AD1C4251CEF59DD66DB7270A6376393725
+:102B8000D549F78DB9B6FA790D45B6EFFEF06C87E9
+:102B90007D92607A8DB0F5E9F2F8A681DC2EA77AF5
+:102BA00097D9199A18B1EEAB38F47A83CB68562EC0
+:102BB000C2BE09A4451A617D9CF6F456BE3E7F2331
+:102BC0001B5B94F9E8BF6D8527B58F79BEBADDFE32
+:102BD000180527A170CE1917CE872E06CE89F6D9F3
+:102BE0009CFB6B774A915D2FD1E7E274960FD9E198
+:102BF00067FE7C07C45169F9594E874F2912F67F49
+:102C000088CF77711AAD9F82BFCDF8EA73907803B1
+:102C1000F526A7CEB3040B08BFE7A5FEFE9CC2F6BF
+:102C2000B3174F1D7F9CE7611CFADCE632BEAF583C
+:102C3000E278ED8AF1036B39A1B0FDE79175E17996
+:102C400094A63D7687CBE8B7D64F3EED72D3DC072E
+:102C5000C9E6EBE9278CFF5E58B36ECB74CACF4A46
+:102C6000BE0FED9FEC35ED9BC500E41F0D6AE00F34
+:102C700064F37D7CB29AC951735F3DB3CE2E579DEC
+:102C8000E7ADDC3C2FDEED3C67C3E5AB931EC7929E
+:102C9000AFBF56ECFB1A23F1EB31E8CA19BF6E82C5
+:102CA0005F999DC9EDE048FAAA3963D3E3CF9B87CA
+:102CB000B70F4C4F965F82F33329E980ED27060E5C
+:102CC000FFA16E7505ECDBB178DA607362F19BD31E
+:102CD00093F22BB228E305887B466A3250DEAC08BB
+:102CE000FD71FB00F5C7EB8DFEC56F5AE639A851A3
+:102CF00068A78DC32786EB232B7F3D2130FAE9E0BF
+:102D0000E3EDE0F874DAD15D62CC0DFD7E40860C17
+:102D100021855F6B9D773BE26DC8077436D6BCC3D7
+:102D20006EC65781858D6188D3B9CF4BC807EEA990
+:102D3000A6DD1246BB659E3B839DFBF015E13E1E62
+:102D4000F5D387FB611D7C2CBFDFD48FEF9BF15443
+:102D5000AEF76ECB60E5ADCD2C7EEC3E72D96B3A12
+:102D60006DE77FD1453CF4FD162AD7210ED84DEDF5
+:102D700078F81EA8182210476FA3F5A316BFBB2D25
+:102D80005CAD819DD05E5AAEEAF4BB34A702CB7233
+:102D900061B9564DC79CEDFEDAD26C8883178B98CB
+:102DA000575B4ACB2DD4A44B776B38BF9F97BCE9B8
+:102DB00003FB2C1D9CF3F9C9F57455440D89C2E33E
+:102DC0000A69D5908B31A2B7399DD1F78F42BCE407
+:102DD00009215AE9A6F3FF393F7FD5A53496DC0ACD
+:102DE0007E8F1C7343FCA04965FB10400FEDF392EE
+:102DF000702FE1F855F8B8237E105FCF0FE4A118CB
+:102E0000A4B67689A421D5FA5CED6672AE5D33B4C2
+:102E100071E949933FB2E54F2F62FCA404293DA517
+:102E2000883F3AE5357147EADDD9C97C25BAB01A41
+:102E3000F22961F69E79BEE74DC5F89C9BCEA3D5DD
+:102E4000C7E5587E26D2297DBFDCFB89E43E8BCFC7
+:102E50001C5E5471AC06FC924117C68B02D3C8DFCE
+:102E6000462CF2F6A81B836EF4C9ECA4FB287DC4A3
+:102E700067B2B80401BA49A38A18F6210BC4F8A3B3
+:102E800085006F6FED34DA5F973C9D5AE6C97EAAE4
+:102E90000A98FDBFBDDADB60F503DE4D63FB2F77DB
+:102EA000F9AA9E86F995FAE2D5E83E4376E62476BD
+:102EB0007E0AE8F8128D0C0922C8C108617A33AC89
+:102EC00032FD5AA3C179298144C9F9B4F1F4A3FDB3
+:102ED0005CD59372BCD50BF808B278977F9780C900
+:102EE00080529F91F08298F4AD6A77337D5102E36E
+:102EF000F4577A898FD6FF63BF82F6619F3F4F06F2
+:102F0000BC3E2FAEFB26C49F867FE9C6FCC6BE3FF3
+:102F1000CFC6FCFB3EFF15CB406EF709E42855F603
+:102F2000A4EA6C1E4F362469B0CF17586A10D8E750
+:102F3000187E8184213FD815FAE9E237E7E1C4D34E
+:102F4000C485B49D87747B68BBF047DEF79750BAA1
+:102F50007ADA57FEE0A524195731E329CBD2A20F24
+:102F600003DE3A26FD5B03F04D37855342FBD5085F
+:102F700001DCE5D922C61F49B62F3E1DE265478315
+:102F800035903F5A2597616A6C60295BEF5F79A3A2
+:102F90007B61BE355A7D0DC4D72B8EEB2867978594
+:102FA000360F40B9F27556EE5018BF40BC8858E451
+:102FB0006ED5D92938BF3E4E27ED2163D010C6E526
+:102FC0001BC7B9037BBE9C950E20CFDD42075197EE
+:102FD000950E16523A9863A50343B8183AF82A2A70
+:102FE000EB4FC23FC66B3542326E379A0F36AB9904
+:102FF000A5A3F9C584E3BE8ACC20C851932FB4059C
+:10300000F7A25C755FAF44C05F37F9C4E48F8F3DB2
+:10301000237C12017E5FEDD3AF4AC527E08758F9C4
+:10302000E1DA31F86605191E08D2462B64124BA767
+:10303000A2E4E797BD553CC5C2074EBCAD582490ED
+:10304000933679C6CA16BC6A23E71BA50BC7FFCB0C
+:10305000B2DE11B4F06127F543C058EE16C304F494
+:10306000CA02DFBA3F025DCA75DF0B813FE87247D3
+:103070001A306F76C13B693752BAFCE3245187C9D5
+:1030800077E8EBBE8BFC7C228D807DB2BD723DC6A5
+:103090007DFF7853742AE8892D14FF27512FC72705
+:1030A0008B9883393499EDB7EB21F68C86D87BC2A7
+:1030B000BFC779D9E0F586B01E5D679B7CDCE16116
+:1030C000FB5D3B3C4CDF6C517A54E0B7E142554B21
+:1030D00095EF5CA9B2FA4BDCA4221CC4D1705FB995
+:1030E00043956A7B599C2FB184BE5F32ADE451EBAE
+:1030F0007E81D9EEC1E63EB453B6341FC267565D39
+:103100009C40DE95B724A6C3FEB8FA97A5820BFAB9
+:103110009DCDF671E17D8BC54ED355C69FEA5FA468
+:1031200028F0B1DA1AD3332DF2581585682A7B7B43
+:10313000A787C569D45682DFD5C35FC77DEFACE2F0
+:10314000B0F06528B7F69030EDC79360EF83C58681
+:10315000F0254BBFC1BA3E9B3E5C41972ABD1CADDA
+:103160002C3C17D3A17B719F6C45B0FA0FF2DCD1D8
+:10317000F4063F272D7463C26FEED7DECEFDF49ABE
+:103180002215F9B4A349E9C573302AB39F3E085606
+:103190008F7BAE00F669A98587FE303C61BF36366D
+:1031A00093EDD74219F66BE109FBB5F084FD5AF8AF
+:1031B0000EFBB550FE4EB38165D8B78532ECDBC649
+:1031C00066B27D5A28C33E2D3C0F3537E0F3D9E671
+:1031D00046FCFE5C731396293DA0FD474A6221B070
+:1031E000ABBBEF520CC8C7E9E2EB7EC428CA027A37
+:1031F000F104593CC1F3E203782EDA131231BED741
+:10320000197A80DC409FDDF3FDDD101F51BFEBC359
+:10321000A7477E9080DDB64788359030211BD58A40
+:103220001A99DA13C5A1CDD59961C0DBE5ED909F60
+:1032300038436F09AFD39265DD5FBEFE7B96F2D453
+:10324000D25ED94BEBDFD5BDA81DE406C0019B6B58
+:103250006DEA929A96624AB445D4A001F957A8C47F
+:1032600081EEBF04EB351DE06776E067485B08E25E
+:103270001F5375A51CF895D64F303EB9B0FA5DAA1C
+:103280008EEF9DEDC6AB27565C503D228DD31F7C43
+:1032900017C6E9A783B4698314F6AD205BC08EF22C
+:1032A000B0FDE06E179313DD1EF6FC9DC7DC0FAF7B
+:1032B0005EEEA1CFE51EC687DD9E482D9C4B199E74
+:1032C00023621CA8CF45BB80430A4D85AFC0F9A13E
+:1032D0003B7E2213D867D8C3F976FA543FD3E7F779
+:1032E000A8A8CF974FFD767B262D4FFF56380CFAB6
+:1032F000792B097B814E62DB985C79AA625A663D24
+:10330000AD7EC9FC6732414F7DAC32BB36CEFD92FB
+:10331000968E1BA742FCEA8FC7989CFC361FA7D746
+:1033200035D888EB39DF87760D752CD06E6909C9E1
+:10333000986724E6B0A7E2D2FE0AEA29D430885181
+:1033400078943F2F50314E72D6CDEFC118447B4652
+:10335000F144B50CFABE272622BFB769DE38D8DFA4
+:103360005B7DE578FE34562AE33994ADA52CCE9AE0
+:10337000E6FF7C1CEC981DFD1E261F7C2AE699C6E4
+:103380004B0F1EAD0EC253D480DFE3C6AA5AC4BB96
+:10339000266A98AF4A7FC3EF0D413CB7B295F075EE
+:1033A0006910F1DC5DC7A48F7E7A29E4EF7C590BAC
+:1033B000F3BB09301F1C4D3311F68D860FA7013C5E
+:1033C0007F63DE6B30D49A46EBB7AFD3C2B00E73D7
+:1033D000B5EA5AC837E8D0AAD11F4A9B53A35E8FDB
+:1033E0007268E4DC06DE9FD15E2A63BE117C07BEF4
+:1033F00024ED6400CECDE771599696512E801DD6EE
+:103400005187E14038D760CB3F6FCFBC06CF2B4907
+:103410002B3211CE0E62A8503F5627A39ECCF3A9A3
+:1034200009B04BF2CCB82F1CC5B0C425B26EB19F09
+:10343000E7C869906DE7C72747EDE56C1E67C8765A
+:103440009CFB38CBE9C58927E77CB3828F6600BC3B
+:103450005970E0571F3D9F0783E5F530CF3CCD8B7A
+:103460007087B4D62A905F9349630BD0DD45C3EBD8
+:1034700080736E69FB20ACFB5C5D263A1DFF523207
+:10348000DC0AFD6EE574DE5D68D7DB7B54C9E4C7FA
+:1034900030F0E3D42691C42CE343BC3266196F5A52
+:1034A00077A6AD3CBD27D7567FE6AE22DBF759F1B4
+:1034B000D9B6EF97EC2BB795E7F45D6EAB7FE9A13A
+:1034C0006A5BB92C718DADFEBCA3AB6CE5F9837F53
+:1034D00065ABBFE0C43ADBF7CB86D6DBBE5FF1D687
+:1034E000ADB6F295C377DBEA9B76BD532FCEE6F6F9
+:1034F000CDC5DAF36EB84FC216BFB5FB0B4E7B5F7E
+:10350000FD4B9BDE0A722DA0207DCBA0C769F9D6AA
+:10351000BB98BFA52E0EEB2057742E47A9185C0050
+:10352000EB561550511FC83E564FF62D43FB63CA4C
+:103530002E2A8FE681554A46BEA7815C6E8E2D2EBF
+:10354000B6C4A53C5A0F9EE1AA0AD4E23E88D95ED1
+:10355000D60C12F5C3783AB37BA8370BF53C3A6D1D
+:103560006F99D7F3A28847A587A95FF8A8C52F1C34
+:10357000CB0F74FA7D17EAE74D118917CF1F089119
+:10358000467896361EAB86B461EAFFFDB587F2E752
+:103590007625D2D04BFBDD5EE465FBA5DCFFEB2E90
+:1035A000EC43BE182E9451BF10592FB5C6ED3AF911
+:1035B000FAA6A94FA1FF49F18EF2D6C4FB566128A5
+:1035C000DE0672E72E2FCAC329BF71BF0CFCA516F9
+:1035D000A9792A7D1F3EA218B00FF520C76B91561E
+:1035E000560DA1A7E250FD6178CED0A99D419F253F
+:1035F000253B0FA35AF314E178B3C3DFAB0659A2FE
+:103600002E66F69F3C5789B7D27E248DC291C2FFA9
+:10361000309F526017DBE728967F07F406D6FF79C4
+:103620003A85AA4C15F3423C4007023E917E3C414C
+:103630001FEA0D0F1C8285B22CC4619F10EC53D879
+:10364000AFABCADC85EB6EDAAD60CF46993FDC09E3
+:10365000780DD6D9D73B4DFD0EE2A95D60F1F1EEB4
+:103660000CFDC56A3A6E77765126C462217E526F90
+:1036700091373BB83E8D7AD9D39437B891333F69AF
+:10368000EF50FADF254E03F87A08C82DCFBD3D0470
+:10369000E8DDA3D1D544BB3EA647509F327BF73629
+:1036A0000E534DD11ACC03783F588EF6ADA7E9F9E9
+:1036B00094F8F30C49C49837365E033376A3BE27DB
+:1036C000458A0E764593AE18BD29E4C15C95FB3959
+:1036D00053CC73AF2C0FA89BE3C38C9B8EC4237970
+:1036E000DCCD8C479AFDDC965D3E793C7BDC43FD6E
+:1036F000D0A805DE2D741CC04BC7B9FA5AC4834C40
+:10370000D8B9DD3F97F6DE87FBB16D3AEC37CFE5F0
+:10371000F67225E087E27B8A42D04F580AF1952C59
+:10372000F07E3F530B7C69C663863CEC1C773846C1
+:1037300024167F73997A4B3C7F29C2AC2B661E19E5
+:103740009ABC4CAFD17FFBE17CD9B46EFBF9CDE9DB
+:103750003DF6F2CC5DF6F2ACB8BD4CADE6E36017D9
+:10376000808D86F18D7DF6EFF5E6BE410D3B6FA6AF
+:10377000D291CF33FD6BBB3F8770FD6FE6BB15F475
+:1037800025AA40BCE6DF6ED7ABB95CCFE73AF46759
+:10379000B95FC2B843D5D1E000D88F667CE8575EE8
+:1037A000DD967766C6799CF2DCFBFA4E42BFA0FF3D
+:1037B0001E75B37807C4913F2CE071957C1E579914
+:1037C000C2E32A052CAEE292F497D60A9827FA3E75
+:1037D000F20569BC94C573D8B9AFF76AE517049DC3
+:1037E0008D17B58C7767496C3943433C07EA99F1EB
+:1037F00015337E10F01BCB817FB7865F6E3C42E9AC
+:10380000A4FA976E02FD5C25BD78B419E45B818C47
+:10381000F9DDDA825BBEE98578257CA7E5EA427DA1
+:1038200032F2C18F5D1847E8E2746D9E5734E33180
+:103830009A97F181CF6BDA47312FCFDFF782BD7BCB
+:10384000C93E2AA36DFA8EC5FDCCF8DE9C3EFBF77F
+:103850003E226469901FB0262E32FBCAF05559F201
+:103860001F67F3759BBB36F1C05A5A3E40E2E570C4
+:103870002F5D19A78FF080FD9CEC2422E039A94927
+:10388000C7A5709CD69FFB9CFD7BA9E31CED6CE754
+:10389000B95AC7FE915F22A7AFA7E36DD31B05906E
+:1038A000A3DBD6525B9E966779F9BEFD0C3203E826
+:1038B000F02AC9174E007E5F95701FCCFDC6CCD78D
+:1038C000AE07BD7E8CE52769D3F49D106FD67E2AA6
+:1038D000A19ED2D24859992FB9DFF40FE7C304F65D
+:1038E0004FCCF8D793745D41AF1CA07E79B10BFC2F
+:1038F0006C0DCB7DD42F87F2D3D42F87E741EA9785
+:10390000C3FB7FA67E39940F51BF1C9ECF52BF1CB4
+:10391000DE3F47FD7228DFE5ABC278F920AD0FF43A
+:10392000E22D3BA84EAB0039ECD2803E9C72A8AA97
+:10393000EA36753525A92F743D85FB1CD557B17C1A
+:10394000EAE5F73D85FB1CD6389C354E998CC30DB6
+:1039500009661C0E42A3BFE6FB1123F1B8288BC7F2
+:103960004DDC8F61F683F1CF51FDF038E8BB77FD78
+:10397000DBE36DF4D386F90F747B8BE07C47238FF8
+:10398000FB99F933BA2D3F7FC3C116CC9F51728E7C
+:1039900037C2BA1EACF0615E89E28A6A206F9DFE72
+:1039A0009CE9C739ED69F3E9D46F7E6E5798F1D57C
+:1039B000ED2E82F9D43181DA13605F34C717BFE985
+:1039C0001A3BEE7AC25BC4F3F8EC7261E41C018F1F
+:1039D000FBB8C19AA5F354048E0F9EDF8EA2B18866
+:1039E000C5FFACF1576F711C0FAF7B7D06DA750216
+:1039F000B5F7D0FED3A22188A375C2B98114F3DB39
+:103A0000CBF9BD2547417BA33387E58BD4E48743BE
+:103A1000D0BE2DA732643D47609E7318F057AA436D
+:103A200096FE6EF5178DABFF24AAAFF571F4B5E4E1
+:103A300066E77CDA0E5FA6C2F98D6EDFBA41F0A3AD
+:103A4000BB43418CD3F7E75492214BFF5268219E30
+:103A5000F3907CCC1E96422ADAC332CCBF3459DFB5
+:103A6000ACD7C2E53E65678C2F7A7C3D58CF2D4799
+:103A7000F07E09771054267D6A6CDFCE5B2C12D560
+:103A8000222FCC71EFF63279D95D1AD520CED21D16
+:103A90009275382FD2AD97239EDB389EDB0A4C7B84
+:103AA000228C76CCF7B97C35FB69E37180B60605CC
+:103AB000EDB948538656938579BDDF017EEEF6B5A4
+:103AC000AAB07FA9E4548CDBEFC084FD964DAA997F
+:103AD00087FD7E1FFA55FCEB34E8D735C6F9A463A1
+:103AE0009C1E3EA9DDEADCEFA3D086AC792BCEA7E5
+:103AF0009FDB9FCE761B4A871458F72D8FD9CF3383
+:103B0000BB083BDFB5F1D066E4F3EDF220DA51DB20
+:103B1000CF0929CF8985D204CE6F23FEBDCD0ECA31
+:103B2000E3FC94C7BF03A981BE284BD8ED96794723
+:103B3000EDE5F983F6F282134E3BC87815ECA0D57B
+:103B40005CEE0D5279CF92668665C0472416AF02AF
+:103B5000B8EB495F0BE453B8249617B29AEBBF95C4
+:103B60005C3F06D23210FEBC06AFCDFF24FC3EC047
+:103B70007CDE7F41CDC0E67610B211D3AED2D16FDC
+:103B80002DB8FAE92A14970EFBAADEB09FF75FE979
+:103B9000B09F9C765695DC8B79BBB98EB886B9EF11
+:103BA0000BF3847B0F9CE35FECB8667F90AF05F26C
+:103BB000CDBC0F06EF1FA6ED0BE48410A678CA6DEE
+:103BC00064E775F26E27466F0A3A5EC2D77D14DE4F
+:103BD000624B106F4BF9BB5C1FBBC72BB7468AEB20
+:103BE00074FCDC863EB40756DD42E78376F879CC78
+:103BF0009731EB6766F4E1B9A5DD7502CFE325687F
+:103C0000D798EBBCDBC7CE19D65F29C44568DF580F
+:103C100084E3235C45C9F5A5783AC9F0C4F212AF34
+:103C2000ADB59F87AC77D82F263DAC74BC3FE96516
+:103C3000FBE7261FBC7BD9891953281C1B849EDAFD
+:103C4000B46917AE2F2DFCE13A0F7C08BF4F6229F3
+:103C50003298EFABFE9386E74232861E269424AF5D
+:103C60004D23B19A4584FC8B77F8128196FF6A6BDD
+:103C70005F4777011CF31E7E0A8C3C77D73357D5FC
+:103C80005E992C7BEFEBC772908F035B906CBD2D20
+:103C9000F7C350D4C5D3187C5B0DB253821C5C5162
+:103CA000DB192E4CB6CB8476C238ED2264A79CA2D9
+:103CB0009DCF6C47D1D509F73FF17979F97791C359
+:103CC000631D5F06BC69BA0FCF3B2E9335D8BFFA90
+:103CD000B4704C9A68DE51B2D3356D743B0A768B62
+:103CE00009BF981AFE387CB78EEF1A07FEFF6E7C6C
+:103CF0004CD49FC2BF5F347CB47AEBA4B1E70B70A5
+:103D0000B9F05E22DD275AFAD9D1FF278C8BCBD7A9
+:103D1000913084BC6497A1C17E5EA9F610FAF77257
+:103D2000468D0676C0165A063B604B5F0FC6BF4BEA
+:103D30008B1FE806A22F4D7809C8833944CB384041
+:103D4000FB9DA3C970028BC8570E88104F279F2573
+:103D5000985F92DEEF65F708155EFE2DF0B7323200
+:103D600054DCCF48CBA8FC16337A599CD9843FAD9C
+:103D7000EA7835C4DFE57A1216002E214EAA80C9F2
+:103D80006611DCDFF01A07EF84F3024466FA09EFEC
+:103D9000D201BDCAE3ED9319C9906E45ABC73C97FC
+:103DA0009FC818C79A0C578551A22C2DCDDC09F05D
+:103DB0009446690702C0CFE26573A2623841FB2FC7
+:103DC0003FCDDA919FB17326D43759F38C2F8957A1
+:103DD00053AE4CE671F8D05A7B9C9A0CD339D3F68B
+:103DE000E53F5BB517E2149346C96FE6B77B399C94
+:103DF000E9A74904FA0FD6D9F58697E7797B1DF72D
+:103E0000CC54F85DF6FBA19DFEC35723A807DC2424
+:103E1000AC2A685FAC45BBC1F44B764345B0C70BD9
+:103E200008BB97D7D9BE92B52721E6A7B8BD4455A0
+:103E3000CBE9F7F55E03F312DDB44CF1282844CD4D
+:103E4000A1EF7345166F6911880CE5E47809CC473A
+:103E500070AB9F6907FBE5B03A0FEF4F33FDEA36D1
+:103E60002D8CF912A4A4DA66379B7961B796154DAB
+:103E700086EFE99346E24E1AD0E5ADD9C56847070B
+:103E8000B286FE1AE4ECB9ADE9CB5490AB90AF71B9
+:103E900039E4477B3B6354E9BBCFE611DD629FB950
+:103EA000E5468CB3B9CF4EB1BD4F34DBCF5B1B3E83
+:103EB000B106C699EA637C5845B476685745ECE785
+:103EC000AADD67736CF67AB2FF7CDBFB04B56BACE2
+:103ED000F7008DDD7F1AD14BACFD4F1BA3FF198E70
+:103EE000FEB594FD27FBCDB2F5DB21B3F86B2CE8D2
+:103EF0004D792FE5025F75311C951D6B7FA0D2C7F0
+:103F0000E29A5DA146DC1FA82694F129BD2C3977E1
+:103F10005262E77D09DA6F24DFBE3F50CDE958A435
+:103F20009481E70764FBFDC68B89F3BE63BB5DF438
+:103F30004B8839507C89FE8A41DC27F8930FCF03E8
+:103F40008E65370F36138C4F2F4E1BBA0DF6C157A7
+:103F50006ED3958E10E63DA33FFF37DBE62F033B84
+:103F6000DFBC07B32328225E22D593F13C97D94FBB
+:103F70004421D3412E46449607813F74FCC1EC5C3A
+:103F80005BBE86F9749E87AF3784C5C596790D42AE
+:103F9000FEA175BCA579BD92651E1137998FE3719D
+:103FA0007B7764BC499F6CBC633C9E658E57BFCCDD
+:103FB0003EBF7A45C3F9D5733E36C73B06F34B8106
+:103FC000DF09C7E3F99523E32DB7CFAFDEADE1FC01
+:103FD000EAF97DBC23E34DFA64E399719D2EA5B106
+:103FE00011E870ACF88E19D7B9B66BBF2DAE43622D
+:103FF000FB97561513B25360F223EEABEE04BA787A
+:10400000BFEED612D42BDCBEC67B57A93E5E293349
+:104010007857E4FBE22D163CEEA672C49809E72916
+:10402000540207CFE07C8581E72D42F87C94DAEBDF
+:1040300006E69794E0F7C79BC358DED7BC109F668F
+:104040003F250BD9FD60B3160929EDF6133EE67F37
+:10405000EECCD1AEFB12E8B72A2FCB0B5E78053140
+:104060002C763435AC0F7B607FE8F3A40C74E48CC1
+:104070005D0CEE60CDA438ACBFB76C60B019E2A0A7
+:10408000B24BC7BC583DF5DF3B78C5C7FC79B79B41
+:10409000B52757B07B525770FD44A43ACC3F5AB174
+:1040A0003203F31156AD36FC1AC5DB6A4178B59878
+:1040B000EB3B381FF539BED44E7F21089A87AE57A7
+:1040C000D090E2708FDCE7F25F5C23D07E23FE6B42
+:1040D000D1CF88D08699B49FCF717D5BF5869B4008
+:1040E0003C825CA5A0FC5ABDDAEE17ECF42434B097
+:1040F00073769605490B6DB7AACEFEDDED667C158D
+:1041000071DC13B362827B63CCBC5C277E9C71D371
+:104110009FF9ECF1D133A474079E0DE3F9BBCEF601
+:10412000661CB4DDC7E45B97C2E4C3683E60F0BCC4
+:104130000B7DA3FF7702E368267CB9725C00799F50
+:10414000D770C2961F4F118B46B5B94F40A4036577
+:10415000A8871DF3D92D1CC819EFDEA85C22FF6EBD
+:10416000A884FF7D0361F4BCDF1935EF452F15935B
+:1041700054FCC3E2C12B8E4AE1163D8917130FFF91
+:10418000DB7CB4CBC7F0F9D2D20F2A981F986FFB13
+:104190003B02E639AF6B47CA32912DF4BC72BD6267
+:1041A000307F75B814E8F2F8956961F6F730B81DFC
+:1041B00094F8A50876D0A7EFDF28B0E53FF37EC7D7
+:1041C0005A2F67DEA5E55C72F29E04C87F690987F5
+:1041D000D01EC81609F0532EE4E305D8F79376BB3A
+:1041E000D5968FD7D6BF5F80B8E1C3909F68398FCF
+:1041F00097D7D02774807DD71267718804AD47E1C7
+:10420000CE6F4808EDA5C9BC2FA75CCFBFC59E2FB8
+:10421000D8B168B5764087BC9AEA1EB8206CCB2E20
+:1042200016E732EB8FC4BBF83955176924704E433B
+:10423000F2B1787388DFDF31519EEF87624C2B2C0F
+:1042400084FCDEB85A45E7BF272BBACC4FFBED0EF6
+:104250009637F6027DCA61CC075FDB744F04E284B7
+:104260005A56EA38F85A6E1FD4FB195DBDEE4A144F
+:1042700040DCFCE5ACEA7A7F768AFA4D5FC5FE1633
+:104280008F712FFD7A3F8BCF3C2CA6960737F0EF2E
+:104290005FD820E27D431EE2C773AC9EE29E85801C
+:1042A0008F8737EE0EA73A8FB9508BAEF35BF0EEE7
+:1042B0002966F70510D27719CC73CBC78FF47D9799
+:1042C000CE3BF3631FCAD94C89F56B69BFDE3A1F39
+:1042D000B3FDF37FFA059EB37F9EDFBF4EC8F4E5C2
+:1042E0001067DF3E52263138E8BC3D839763E272A7
+:1042F000F02B93E5E796554119689412DFBBFE97C2
+:104300003AE1FE9AED02E1C43AB80CEBF3FBDE7F32
+:10431000C2BF2FBEE69D6FED007D50A9A0BFB99D25
+:10432000DB3B267CFFE967793FFFC9D7652C7C6EB4
+:10433000E3DF7D80CFE045E1735B2A7C7E26686CFD
+:1043400087F71EC804A120783E566F87BCECAF37B4
+:1043500093C897E81C1E0E1FDC0F678F68FB8752FF
+:10436000B5FF4196F1353FC27312E7E72FF685019D
+:10437000155B1610EC27051CDF186F5DCB33989C7E
+:104380004B4B67CF4C6E5F4AEEC110E42F6815FFB0
+:10439000709B46E54C67E1E09A5471E2A702CCEECF
+:1043A000CF18232E7E98E3EFEACCC8B701EE76ED66
+:1043B00001F4F7148144A0FE96854344B0B47B23F6
+:1043C000C0E897C2FD0CC0AD5CC6EEB1F653BC436D
+:1043D000829CBF82C1BF453F4E204FDE1F3A8E797F
+:1043E000ADFE8A21E4771485B98CAEC01F54B9FDA7
+:1043F00076D8FF26DAF5999249777774011D4AC974
+:1044000032D2656F266BFFFBC01D5DE02FEE516859
+:104410001B9083B90ADA37CEF9FD2CC0E6A768C62F
+:10442000518077143EDD43DF827B09B64F67F7B9D1
+:104430002C1607D7DC0074798D0FED33FA7E8DF5DD
+:104440005CFE479C7F3FF233FB6AFB9F54FCEE5CB3
+:104450008FB1E8F5246FFF09E8F5642AFEA5F4FAA8
+:104460005B786FA1D70F486A7A7D7B0C7AFD0F6865
+:10447000EFC48BB32C116317EC2BCB1F2DDB07FD87
+:10448000C99F59B4EBBBF4297DB42D86AB19166CCA
+:10449000E79E93F23EFA2718D7BC7FC0FC3B46CD7F
+:1044A0004008F353F4BBA07217C8B10BE8570E6471
+:1044B0008FEEF7653F8377F135BE68AAFB14BE1314
+:1044C00090D9F9D800AB3716DFFC3AC0F253C6E2F8
+:1044D0009B17381F50BE0906E64FCC3767927C9376
+:1044E0001FB820BE79089F9E62C63738FFCB47F3BE
+:1044F0000D89ADEB02F9DA59C8F862CEFD9B902F19
+:1045000046F82816C3EF52B28CF2DBE4A38FEF8F8C
+:10451000617D67FBC018F70656707E5AA845E60114
+:10452000FE8D4BB476768E6908CFEBF692E17E373E
+:10453000E609B3BC5C6F2C6630F36090C0FDB48BB1
+:10454000381EF6808F067E50258F67C98364957F5D
+:10455000343FFB2B1215D67B605EE1E3FBD2234B8D
+:10456000018FBD646816D86763AD532D1F4FC832E5
+:104570006A0329F87F223DB421C0F4D0063E6EE6DE
+:10458000C76A23D8A74E7E5FBCF1D93F3C3E4E3F61
+:10459000EB391CEB029F585FAD0BA4D6573704ECE8
+:1045A000FAAA42284AC9FFEB0329E407E5FF9B5317
+:1045B000E1E553F0FB9D8114FC1E095C18BE9FE5EC
+:1045C000F87EF653E27B176FDF13F8C4F2B62715B7
+:1045D000BE28BE7706B22F08DFBB52AD17C5F7D78E
+:1045E00003B8FE4F23FC7EDD87F1F2EE05E420F4F4
+:1045F00093028E5E6B3FAACEFAA13CF58140E97E24
+:10460000F147DDE154F724D176FB52B5AB0D683CA0
+:104610000EAD6F06FFE1E1CFF8705F81EAC703815D
+:10462000FF5EB97F28151D2C16991CF206167581A0
+:10463000BEFF14FD0FA492FF5FE57436915DF01A82
+:10464000A70B3AEF9F029C4EF9D7CBCF312B5AF4F0
+:10465000E500E26BE86A90577BEECE1420DE956FA2
+:104660002404F0138E723D560597FDCC4FB6DB2324
+:104670002704B867674FA326C079294B7FAF07B2DD
+:10468000C7EECF090785EF3730BE2FDD188276B52C
+:104690007C7E176B271DC934DE0AA0FE89BC0D4F36
+:1046A00063A65D6E9BF310233D2CCF7661EABF734A
+:1046B00079D42F9BF2FF7DABFCFF8F11BA62FD5DB9
+:1046C000ACFEA1F09DE3F0FD25157C4EBC4C04E74B
+:1046D000250199EBDB889A9E424F39FB33FDEC9123
+:1046E00075029D6489FB64A78FE8EF603AAC478749
+:1046F00088E7A8567079B2626106B7DB352FF4FF00
+:10470000308FC33F7CCB0355B0AFDE7BAF5606285E
+:10471000C86D607A4FBF650AC657A7F27E9DF08FBD
+:10472000B457FA66C1DF8FA0E34E83792C59441247
+:10473000E037A683DD80F10A0DFFCE71A6BB27040A
+:10474000F1D92D42CF9A75A057AFF6B17331A1D5EB
+:1047500013DC9FD96AA35B12AA98A07E0BD6D7D28E
+:104760007AF09E950BAEEFEE496967D5A48B9C9EBF
+:10477000A24BC6C56B2888712F13BFA3C761EB5727
+:1047800015691400DFFE0A4183D43B3FA513B0979F
+:10479000C4E241CC9BFA6C05A31742FD92F1EF698C
+:1047A000E934E15A0578FFB47099F5C61E8FD773C6
+:1047B0009CB718F97B643E26C7B0222DBF77342BF7
+:1047C000E5BE82F9EC6AD60CB832F93D4DC7FB1B49
+:1047D000BB46F2BEC3A155FEFFF97AC979C5597C23
+:1047E000D4517FE49E92908AF61FFE9D0FEB7D3D93
+:1047F0009C2ED48C482C1DE54A18EF89A4E5565808
+:104800000FA2D2B21FCBED58D646CA9D583FC4EA7C
+:10481000134DBB20BCD376DBB11F79A49F1DD88F6D
+:104820006F64DC9D580E8E941FC4FAF9ACFE858E21
+:1048300033EA9E964109E7FF816CA4C3BEE9E79B7A
+:104840006EC0F8D2754D37E1B3BB59AB82389D7954
+:104850005FC9E7AFBB41037FFABA2F3F88FBFA6617
+:10486000FF2BC1EF00FED7E55AB097944231F29882
+:104870002FC97F4938DAB1BC4266F7FEAF5C787A5F
+:104880007BBB257EA7C2DF4F87FC1ADD725F06491E
+:10489000CAC32704E37BE91741CFA3E749C800A5B2
+:1048A000DF0F7CC5F118D273B5968A6FCCF98ED51F
+:1048B000BF39DFB1E48D8937F3FD9662FEF7761DCF
+:1048C000F14BCFF41ACCFF59297038FDFCFE485E3D
+:1048D0006F051DE7E952A40B1DE87605F7EF9CFA7A
+:1048E000C11CF709217A02E804E2C4F7968FC6EFEB
+:1048F00085E2CDEC7F723446E0FE2E6F29C17DB19A
+:10490000A0DFDC576772ED219F598E617249A4B810
+:1049100007E59C4737E51ED3935A5A9F2196513F8E
+:10492000A887D48666411E6834047FEA87968FCABA
+:10493000684FB0321DFEE800DA3FDA6CB8F1516D15
+:104940003FF7A3A35712767411F7DDCEFD08F5B734
+:1049500059860B7C4B68D93B5236D4102D178D9459
+:104960006350DEC3ED3EA1E7DC8F60CF84EAE573E0
+:1049700056795FC5E5EA44F2F4BF00B9E905CA001B
+:10498000800000001F8B080000000000000BE57D88
+:104990000B7854D5B5F03E73E695642699BC270490
+:1049A000C8090F098A38090482623BE1D558790C9D
+:1049B00015359628938447782620D5B1D2322180A8
+:1049C000A0D886AA156BC509C57B69AFB6A0B4E5AA
+:1049D0007AD17F10B4D0521A2B55B4A25150F15154
+:1049E000938294A9D572D75A7BEFCC39273321B45F
+:1049F000DEFFEFFF5DF874B3CFD967EFBD1E7BAD6F
+:104A0000B5D75A7B0F6361C6721963DE1CC6C63107
+:104A1000761EFF7CB967C944BB366DAD67C268A816
+:104A200079ADBEA11A631BF15541BC5D89C74EED3E
+:104A30001ECD0CA67BCA199BBEAACBEA8476CEE219
+:104A40001C77D0C55891F79370257C5F349E310D4B
+:104A5000BF1D9245E3B679572A769842DB08E651A6
+:104A600018BD5BE381F6396EC6DAA164D60863230C
+:104A700018BBDF25EB301F28032511D601CF533596
+:104A8000FEDE827578AE3A58D34EA8A795307F04E3
+:104A9000EA1E079B1380B2D863610CE6E5F3A834E5
+:104AA0004F1F8E06F50CEF5AA6417B6795C51F81F7
+:104AB00032034B971EFEB5E23B2B95121FD7E6043F
+:104AC00047209C6D8C55EDC479B168A004E0481D69
+:104AD0009E937537D42A4BAC2B190CF9E86A1698BB
+:104AE0006B63ACC21348C3F6AED29CD4E008AA8F65
+:104AF000F2403FAE75963003BC54327744298EE3C2
+:104B000005669E1A7027A7C7CBAB838149B6E474AC
+:104B1000BBE12635A087439653100FF0FDC7D5EFB4
+:104B20007C1FC159EAECB2B34140CF219B034C45F5
+:104B3000783482D3B97B66B410DE2FDBB39CE17C82
+:104B4000D7A4A58F473A9AC77DF9B3073D01789F4F
+:104B5000F25747606782F196083C1F5D5D4DDF416B
+:104B6000F79A358FB13908CA204604ED7062C994AE
+:104B7000F30E02EFE810787F0BE3CC302B503B8D27
+:104B8000015EEBAA55A616E377DDEDD979A8DFD251
+:104B9000513B958D844AC876129F3BE1EF79E83707
+:104BA000C832A778E0716D983FA7F6F0DF3CE69B2E
+:104BB000920BDFD56F303D7FFD9AF7593ABEB79E15
+:104BC000EC2889F77F63756D6092687786FE1F21F8
+:104BD000786669CC8F749BE54B8B8401C4EB0337FB
+:104BE000052695C4FB7BE573750EE2C58C8FFF44EB
+:104BF0007CE4223E028149437BE2A32EA0D83DDA29
+:104C000085F1D2573CD45A4BA7E46A3DF160861F28
+:104C100030762FE2791EE0F9EEE2E4F88076448FF8
+:104C2000576E827600CA1475AACD0278A89FA93063
+:104C30008742F84D6783B19D7FEA64DD7CCD78348F
+:104C4000E3ABFE19E68B42BFF50FB87DC0E1ECF790
+:104C5000123F5140DA189027BCA91ECEB771FE1E34
+:104C6000F88B707EADA2F4F91C984770ADE2631C1E
+:104C7000DEB7F5F0D5B140465421B8DF4E42F7B764
+:104C8000F5709AE7679E7F0A0A2B907FA1D78BBFAA
+:104C90007340D78E59A323029733F6538F3BE7DD3A
+:104CA000CBA03E92F9CEC3BA3ACBC6678CC2F743CB
+:104CB00012CBDB73ABB5EF1CB0E9D739E7B339A141
+:104CC00099DDE362FF0A0B76D73D80E7C04DEABD70
+:104CD000D7C3BF5F3E98BD0E9FADF0AADAC96CC4C2
+:104CE00017C04BF4F23326F98B6119DEA702FE667A
+:104CF00032A7E6827EBE0C42EA3CC032DD9FA2B9FA
+:104D000074709C6E55AA508E02F132665D1E87D774
+:104D10003CEF155E3B8D07FCF8899E1FCD7879B975
+:104D20007A7006CA9117112F69849791178397AFEC
+:104D3000E0628675E3C9665105E8DCA53823DB60CF
+:104D40004E35A13B039346215E58D80EA2F35D4F2A
+:104D5000B190D31C6E1B937F9A18CAD31A3B0B22B7
+:104D60005CAFDB58F52E1796D101653AB9F57E7622
+:104D7000E5BB28A765BD26F46DEA1F1891F850F22F
+:104D8000F32D4E5754E57CF85137DF903CABF120C2
+:104D9000DD814EEC3CC0A9662CD1106E352D7D24F2
+:104DA000CB606C033601389D9981D328FFD5B4813F
+:104DB00011E4BFD49B7EB481D3F1BEAA1B74744CA2
+:104DC00099F754983AD7B20CF84F13F4AB14F44B4C
+:104DD00029719AE9C7709D864B58E43145A000EAD5
+:104DE000A787F823B86E93E90D49CF9412EBA71D5E
+:104DF0007ABE66AD8457494776607417AED7A0D7A0
+:104E0000CAEEA6F725849FA047E2A7CB86FA644E98
+:104E1000C8765ADF4FB0606EA419BFDBE8F0E1B38B
+:104E20003A8B9687ED004F1ED4E3ACC4E7C3F5C3BD
+:104E3000C2F09DE427C42B1A13BAFE3B00868232CF
+:104E4000EC0FA4277EB74137CEA09EE376AF2B733D
+:104E5000BFA6EF5415EC07B2237C3E9F4E7E0FCECB
+:104E6000E4F6C369EFE89D9641C9F157E7CCF65BDC
+:104E7000B3E3F5B70B9CD591047A40F627F5799604
+:104E80001AF45A10B6F063070FF4473DECB9142436
+:104E900019BBC71639787000431661AC1FFE2F721C
+:104EA000D0EF22BB43D4813161FE6DA9DD75BFD344
+:104EB0000BF541DDF530D6B7C270EC4AB05B32235A
+:104EC00007D7C27CCE1D7790FE3A5D951AC1C59377
+:104ED0001D9AC84EC0BCAD60E66400AB4111C6D29D
+:104EE000192A2478142B600EF09DADF914C4F7AC88
+:104EF0004C8DE66FD558D40D93CBB6FA14C4D7F7C2
+:104F0000ECAC41C88DE13375F6CB2C01AF1CC7E189
+:104F100064E194B278BF606135A31EB14E65A457B9
+:104F2000609D93DD26D7B7EC2798C9F567F7FABCE3
+:104F3000F07A0E662658CF872D4D6F7E0BEDD95F28
+:104F4000ABEC3100E566EF1DF4FC86503D953785EE
+:104F50001652B9488CF70E0B2ECA84B2BDFAA59B27
+:104F60006F07FE6DDCEDF0A15A5E7ADBFBDF29D71F
+:104F7000104F4077FC6E5EFD03E5F0DE3ED442F656
+:104F8000EC8601AC1AF9C9DEAC907DB451B357ED93
+:104F900086F2A18CCA2D993A381ECA98447556A536
+:104FA0005990CF5738399F9F3B7E97B70EED4A9760
+:104FB0008BD68BBDB9F8BB16A8B343306F86F2838E
+:104FC000919DA13A78797726B753EF16F85E93C989
+:104FD000ED3D670C89CCF9BA09C6775AC30CED6C64
+:104FE00067CC4ACFED0ACC2F019FCAFE9C3158A452
+:104FF000A3703CF3F7767A8E70E1F76A3633D83DCA
+:10500000F7E1F7B958CA79A4F179649BFB49E7CF76
+:10501000C5FA33CFE34F9E890F227E1ECAF06FC9B7
+:10502000A475D36143797E8BEBD7C794917D91C7EB
+:105030001D0ACAE3E99F29D122C05F4AA51A595324
+:105040008C7ACD336D34F001ABB4F9109FED43721F
+:10505000DC8374E3FF44D0FF45ABC78DF30C4C06F3
+:10506000BB9AF89BE5CEC27E26D78FE1F20F0C2EBD
+:105070009D9E7D51DBBE6110CADFB08DF64B739CE7
+:10508000E108CE4F67B729E7B95CD6AC63E2F6DF3B
+:105090009C49AA3F25BDA77D07DB900364FF4959C2
+:1050A0001E863A7CF786A8BE39E9CCF5084607F398
+:1050B000D807E9ED41DC2D8D41FB86FF991332DAEB
+:1050C0007D66BBB0AEA2F4052003E02552351AF987
+:1050D0006CB885F8ACAFF632639B399D27B7787012
+:1050E0005FF528CA09A84F9F746212CA8D19605AC9
+:1050F00061BF3326A99E28B4DE14B2303F4CFC8831
+:105100005F8D2800DB91928E435F46BC55D834D228
+:105110005B25ECDEEB72F0FD280FE23920EC106825
+:10512000CFF59BD719190ACFDAFD275CF53ABE3BBC
+:1051300052716238EE5740EE3524E227C69A89AFA5
+:105140000F7C3395FA79F37E25E280F94F563FFBC9
+:10515000ED58B467BF65F3393402CB82749DEA63BE
+:1051600062E3EA774DD6D9012758600CD995A5C7D7
+:105170002B1D68BFAE53689D4AFCCF0919EDCD6069
+:1051800013D8655A4FFB143AB3233FF7D53E35DBAE
+:10519000579F650A7BB38C95E9EDAA647A4ADA5584
+:1051A00056E657B3F87AB2A2DE9D0E0F12C9819A65
+:1051B0000CBE0E26AB1F117D4E57A81AE2EB48E835
+:1051C0000317EEC78F7CA6F27DB03FD760C715648A
+:1051D00071BFC0563B1864F0DDD67ECE483374B53F
+:1051E000EF9B97E677107DB407C7231D7F6D2339AA
+:1051F0009C6CBEEE90CA8600634E0B29544AFA1589
+:1052000085529855A71F8A58E2F95F9AC5F7A1B948
+:10521000AB9845837133C3CC9F687F2CDBC1BE78CC
+:105220008A9551FB6826CC6FD9100BF1A7DC1FA71C
+:10523000D8C2FE4280DFB6777918F7C945303F9C67
+:105240008706F3437D591C4AA3FAA0503695834341
+:1052500099540E0915D2FBA1A1C1545E122AA6E7EA
+:10526000C3429751BD24348ACAE1A1522A2F0D5D51
+:1052700045E565A037B1DD885025959787AEA5E750
+:105280002343D7517945682695BED06C7A5F1AAA18
+:10529000A7B22C544BCF478516537D74E856AA9776
+:1052A000879653392674279563432D5456849AA9BB
+:1052B000DDB8D03D54BF32741F9557853653393E03
+:1052C000F430BD97764BAA588FF768733DE8EF002E
+:1052D0000ED7908F93ADBB85595C0FBC98E99F8921
+:1052E0007C27DBD92DA0C75D3DDBCD136526D235EC
+:1052F000417FC12CCE971FFBDEFEFE3016A7DB469A
+:105300006FEFFE0C56D237BF57208BCBAFADD676A2
+:10531000BF8AFCDBC47C6178346DF48B0ACA973693
+:10532000CD5A95C8BE7B28CB46E33E9A196CCA82FB
+:10533000EFD38A4F1E40793223ECF9ED04E4971144
+:1053400039BF9E00FD15ADB5D0765F639E7DE85FE9
+:10535000D32631928BD2AF04769D419F6ECE92764A
+:10536000E3CE8383683D0D29E3FAA7E31A5C5FF679
+:105370006F0EA2FDFB567B54B1A27DB38231BDFD01
+:10538000BF757DDDBFE1FB787F7C7D166D60CFA1B1
+:10539000895DDCAA4D488172F016FF7329F0C9D0EF
+:1053A0004870422AD487ED083F87E5F09D9109694E
+:1053B000505EB627FA1C6EE32E8F764C7041FD8A44
+:1053C000836C3F2EFFD2766DA21BEAA38EF9F70302
+:1053D0001BB0F28EE0C4740DE713694987F96C7D48
+:1053E000030C3DA8577CD4AAC276284E7FB0E3D0E8
+:1053F0007E9374718F6E9F940DFFECBFD253AAE21F
+:10540000F7D68E94CC113DE9D38670239CA0471E1D
+:1054100003B8FAFBA38A47C727CF08FE003AB42196
+:105420001DA45FB26D6D16F925DB523D953864D72A
+:1054300064E6D9A6211F5B094FF67583C81F27F9BB
+:105440000EF06BB067370B39B1B5DBDE4D8CDF6723
+:1054500010BFE5FF3AF89D9AC5D74332FC3A915701
+:10546000C65D781D1F117C08EBF8D788D764EDCE98
+:1054700008FC9BF1DC6661074157C1B8C0A77C5DA1
+:1054800031F4A37D2CD6FB85F07AEA5F0CAFCF0B0D
+:1054900039910CAF4CCB213909FC3A1CFD63C9E4AE
+:1054A0008D5DEC67CCEF3F17FCA69373DC6FEB01CF
+:1054B000393738B99C3B7421F925E48CDDE4DF49A8
+:1054C000CDE6E3557802CEECF2047E6A1137907E89
+:1054D000EAA9AAA712E50D1BC6C88E4E1B1109E347
+:1054E0003EA528AC95A9D80C8532E2B15F09F91F19
+:1054F0008AC1CEB002FDA1AB28964ECD63A943FF71
+:10550000BB5C6F9E5AAF7EBD497D1F5F8F922FB2ED
+:10551000DAEEE67E496D26D82FD764737E8BF7C30B
+:10552000FD20EBEFE8D776B74E0EB679BD5497ED78
+:1055300093F1EF02F1BE6DED1AC2A7737C62BB61FD
+:1055400062B62AE441971FF93CFC25E6417B2673AD
+:10555000EDDB249F32413E29249FF8F8FD43A9FF4B
+:105560001686FA84EC3C21CF3DA937B8FFDFF173F2
+:105570003EDA54A807C67BF6A918A7013DA4E13A74
+:105580001D0F731F8DF8B213DD35C6E9A88D6711A5
+:10559000B47B016F51DCB7872D6EF233D9EDAD7E50
+:1055A0005CCFCC9E49F057788233B37B91379E34E1
+:1055B000AD14895A97BDEB1A17F0DFFA624F2AD65D
+:1055C000E7407D53058C9BD5C1447DA36BDC3FEE4A
+:1055D000F7A8BBEF6787D0EFB13FCB1FCCE67C5D70
+:1055E00087A57F98C74AFEEA3EC6C1E4FA8CAF277A
+:1055F0004FA95C4FB523481E2EC17E657FC9EC9B29
+:105600004BB2B99CFB56B6C5C0D73DC76D36AFFB94
+:10561000BED93762BE8BB37B5FFF2F1FBC6FCB76CB
+:10562000A6F337F6FB7EBB55437F06F7D3589CEDB8
+:10563000D49F5BF81BFDE86F043E700EE175FC9390
+:10564000C85F9C1C8F119AAFF4334A7F62BAE02B7B
+:10565000665522A8C7D32B3CD63AEAAF837D0DFA14
+:10566000FB81C0935CD728B79E1C817229CB8AFB33
+:1056700075F427B9B3E2FD633DA32C2E9F98D8C7DC
+:10568000DD2AE6DCBAC697812EE7F011EE4769FD08
+:10569000365F97D3FAB3C81A94137EA679A07D0A11
+:1056A000937FFC067FF2D44F15E687F91FFE54A5C1
+:1056B0005219C2A26ED8EF4DF32951DC07DA2DCE74
+:1056C00008EAD2CA7E4E86F14D7BBA2582F111FBE3
+:1056D000DB0AC1692F4B8BA0F09BD4AF2203E39868
+:1056E000670EEF770513D0FFC660ADC1FF65C663D7
+:1056F00077BB9B9FF7201E1FBE409CF65076779C81
+:10570000767F36DA4373BBD6DAB5789C56C61F0B64
+:10571000BCBB3756A2CA5AC2EDD37E2CD2ACB7ABB3
+:105720007471D0DF22BF3F1C8F83B65FA28F833698
+:10573000F6DB8BF6EE43DD71D06014C7F567EF2C16
+:1057400045FE7DD8B7FBC7DF457C3A44BC62D471C7
+:1057500097867EFAF2FDB908CF6F4DF397A5F4E373
+:1057600099F7C1C7B38DF18533BEEB32A2C45BD9C3
+:1057700009D7B7F42FCAFD30FA0F3D09D7A111DFC1
+:1057800072FC1A85EF6B994DE1F24FE851902F9D15
+:105790002407228CF4A6DFA16C437D73C637CA4769
+:1057A00071CF24F246CE07F0383451FC17C64B189F
+:1057B000674DC9E17AAAC6C6FDA6CAF2F2269C5771
+:1057C0008DDBA53874FEFEB342AF9BE3426AC66729
+:1057D000E541E1F74E04BF39BE7356E80BC497DECE
+:1057E0004F7E217C1DB3B552FCF0D83C9535433F2C
+:1057F000678263F35982EF65F91AF2CD50C6DECCA9
+:10580000E1E375D33349BCE8D8EA068A339BE36900
+:10581000DDEF6B53AA517F57231E75E35E29F077A6
+:105820009D289923A879E0BDBDEE010FC3F8D7D01C
+:105830004FCAC36EF48B75FD1CE317EC5B6EF25719
+:1058400054D79E2D6FBE5C87CF0AC6E3B3FB1FF211
+:1058500068F0BC7AE8DADCB02B391ED1B78578BAAB
+:10586000071F8C237F4C79CE45F863D8081E17623A
+:10587000FB53287E9AF207D58776038ECBF500F787
+:1058800027AF147113731CAF3AB4CC205FD2620AF5
+:105890008BE8E21769D69DE49F4D8B59E9B979BD34
+:1058A000E5E774C73969BD49FC27A3A7C4BFF979E7
+:1058B000590EE7CB63B50B35F41BDA5313DBC11B71
+:1058C000453B5937E723248BBBCF17743D131C97F7
+:1058D0008FFEAA6A7B78685FD6B9C4CF85F21CE6D2
+:1058E000E4707DEEBEE92511C753D7626F52AFA6B3
+:1058F000597B8FC7FA4DF1D8B4D13DE279FF23F13E
+:10590000D8969C7F2C1E7BADE0DB0BE5A1DC6837D5
+:10591000DA3DDD7815743C134C6161908FB756AA5F
+:10592000148702FE20FD78EC0185ECCD68AD83F490
+:10593000727D6D0AF967EB4B557A5F7FAF4AFA3398
+:105940000AF26109C887DF0A3961F6CF5632C510FD
+:105950003F9F3E3AC550BF69DE7DBF5D8DFEE50AC3
+:105960009B86E31DD1B8BF39EC57C97E853E7C517B
+:10597000F44FDF7FB50FF599E487237E95D65BF86A
+:10598000A8EAC361DB853FFAC886D208E6A93025BC
+:105990001EA7D70663FFF514077ED5BB85E29C29B9
+:1059A0009F3F1808D0FE31A89592DEE4F1D314B1E0
+:1059B0004E27F6ABB801F5F89B9B6C0CFD466FAE1D
+:1059C0003A43EBB9637513E54548FFB2F40F9BFD0D
+:1059D000CC66FF720FBFB2C99F9C2C9FE15749F85C
+:1059E00043CAAB64FC0162EB484EEEC5CB31293FA4
+:1059F0005E13704EECB7E5DE66C043DA5C95F020CE
+:105A0000F9F2D5CFEE7A04E5700AF0C71A86F8FCF1
+:105A1000F7E7711FC2162A09FDC81952AE63FE448A
+:105A2000499C2E37051776D771F9CF6E586EC8FB93
+:105A300030EB95E472AD77B9B53987DB5D66BD6350
+:105A40005E0F5FB4DEA9AE7DA004BFAFAE9D17C1EF
+:105A500072633F6703CA5FB37C30EB896A939C8DA6
+:105A6000EB07954546E9E7AD51BBB89EB0D3FB7354
+:105A7000293CDF21E4E4E5EDA9E9DBB03C97C2F382
+:105A80001DC26814A29DFA465AA485F6E54D63919D
+:105A90004F42CCD7114638BDA9E44768EDCFDBA90A
+:105AA000D7A472BBFC4025C1AB4AC37C6D25AD9B1E
+:105AB0001601CBD6EC60512ECCA7C56F49C1F8C2F8
+:105AC00044B7F510BA5E5A27589883C5F115CF0B25
+:105AD000611E05BEA7770AEE3F4B9DF6C164A70E77
+:105AE000CB457EF936EC0F81EF0F1F5677B701A833
+:105AF000877DA33212D9E9B234C7918F7FE39581B4
+:105B0000B86EDF61C1B25C8A1FD7DF8BF1E1C63DA1
+:105B10002AC5976EBEEDD54BC8EE36C529D574673C
+:105B200009FA535A94541FCA1389C77D6E3BC99909
+:105B300096E369B49F68794B117537C94389F703B8
+:105B4000D0AE6034E62AB9496E4AFC035C13701E7D
+:105B5000920E952C7A787CF13F05D734C47772B8D1
+:105B6000FA7B487E209FA9713854B795E0EB64A971
+:105B70003E9C5F48F887D8EB69B4FF93746E14FCC1
+:105B800028E9BC4CD0B973EFD9EF5C05ED5BFD594A
+:105B90001475500730C243E7EB6EE21389070937EB
+:105BA000F0451DCE53C2BD7FEFA86341FC3E3D953D
+:105BB000E2F8D2EE9679073DE494D8BF2FCD55BADE
+:105BC000ED5EF45FFC3E7BC2D2DCDC04ED85BD0BF8
+:105BD000F86EC2712B3DEC93088BEFF392E537AC76
+:105BE00012FD77F773E1FC8655B989F21BFE717AD5
+:105BF000DE7531F46CB4BA362819717CCB7D332D47
+:105C000069ADE7FA37AF3F490F65EFBEBF621CDFF2
+:105C10002C176E579B9802E3ACBF9CAF4BB68A69BA
+:105C2000941F645A2F17923740FF6D085732B9D32B
+:105C300057FA3FD193FE4FF446FFEF65077E86EF9C
+:105C400071A8C232DA17EEC23ACA13FB201A8FF8D3
+:105C5000B62B93513E9BCC8F91F3917932514C5A94
+:105C6000CDD5E5E194F814D4137DE08FA87E7E5F56
+:105C7000007FFCA6773916A575BA54D07FA9CCCB86
+:105C8000D8DD7B5E461FE8F75A22FADDAEFABA820B
+:105C9000C57DA7DF3B3DE9F74EEFF40B9EC2F72D24
+:105CA00076F609D9EF15B55EE4970A8F7F16E6A15F
+:105CB0003CDB2CE44E31D00FDE3F9FA3925CFB1EF9
+:105CC000BB94E4F6972C169A6F27C8EB6D4A9FE0B9
+:105CD0008CE5D2FE2F6CCD827E6FBF8E517CCFAB18
+:105CE000352B58CFD7404F6B7D8757CDE37A5C0774
+:105CF000AF9A9740AFEBE4953D8FF3E74AE44FA7A7
+:105D0000E6B1F626AFB2F28C76421FF8312BEF8B5C
+:105D1000E5C70179BDCAAB8BE6B36138BF6472A237
+:105D2000AF79A0B04E596156CFF119F3515CAD3245
+:105D3000DDC9F5F62E45E8F1D220D5DD4E12160765
+:105D4000849E3FBD9BBF572724B62B7D7959C4CF76
+:105D50004B772E0F580DF924617AFE5DFF69CF1045
+:105D600015F3B45D044FF634EE8794F0CB3CED743C
+:105D7000014FF6000E77F6719ED72EF1952EF61B89
+:105D8000191556C33E42E2ED7635A0A01F3D33877C
+:105D9000619A04EC134628E8E7CAF41BDB4B7CE766
+:105DA000B24D7F5631E5ABCAF83E17F73323F1BD4C
+:105DB000EE7982FD2BD0A704F3C766E709FF839D28
+:105DC00079511F31B5A6573ED2ED4FEAF2FAE0679E
+:105DD00069C8B3887D8351EFED4C6109FD0C7F11DB
+:105DE000EB01EC15F237AB42CF4DEA28A67C9715B4
+:105DF0006E8DFC0FAAEA734E2DEEF97DA61F96B7A5
+:105E00000E1FD955A94CD3C19D1BC832D4F3ABFB8F
+:105E100019DA17040719DE17365C6A783FA0A9CC97
+:105E2000502F0A5D69685F0C88D5D7076FF8AAA163
+:105E3000FDD0D6AF19EAC3B67CDDD07E78A4CEF013
+:105E4000FEB21D8B0CEF2FDFB9C250BF62CF370DF2
+:105E5000ED5B841FD98C97FFCCE372BBC5CAE550BC
+:105E6000B3AB8CFC9B2D2EA37FF33E81FFCA8CF13C
+:105E700025E8576F79BBB404F17D20FD4AF2B327C2
+:105E8000E30BB35C4B264FCDCF9F14E37DFC9CDD31
+:105E9000827CBD6C3FACDB2BA0EE7A6D3DC2B47151
+:105EA000048FCFDA18CF1792F11AF97D77BCC6EAC2
+:105EB000E3FEDA7417BB3B015FDC97A725F4A74A22
+:105EC0003E4A8637C98F17C2DBD302BFFF2CDE5E86
+:105ED0005778BEAB5E1FEC4A30AF337916115F0EB8
+:105EE0001E15FA66742A59F21E5A8F17AB0FE43C3E
+:105EF000401FBC9997DB334FF7E3EA97E63FA86171
+:105F0000FBF9BCBDC557827449E64F3F23F0A6F3A9
+:105F1000A737707F7AAA016F6FC9F56EF2EBB5A44F
+:105F20007F4AFEF416BBAFA42FFEF4B7F218E1FFD0
+:105F300069A473AE8EBEC21F9F6C1F1562EC109ECB
+:105F400087602EABA6DF3725DB1F4B790EFBE312F4
+:105F50008CD3B6E2FE4B49A80753F2CB69FF4CFA4B
+:105F6000A015F4A083FC04EC9006F5DB275AD8DDDD
+:105F70005A1C6E69CF3B98CF695789AE19F83DFB23
+:105F8000365B99A27E21FBCC7EF917A1E7D985E388
+:105F90007D64A74D03F8D7E8F6D7123FE6F89EC414
+:105FA000CF341F8FDFAD03FD88F1BD7DB95C4FAFEE
+:105FB00083FD37E2D1931DF00E447B1E9E6F43722A
+:105FC000E48EA1F523F16A8EF3F555EE8CCFEF61E7
+:105FD000B78ECFEFC56E95F0AF10FBE7C9EA889D8D
+:105FE000E8C73C1DB313DE54C6F32E1B0FDA5884EA
+:105FF000E8C8F397251D6DB1F5EDA89F6DCC9CAF5A
+:10600000AC6520FCB683FC9C18CBE1EFC3CCD98CEB
+:10601000764F4685517F65FA8DFA2BBB2ACBA4CFEC
+:106020008CFA2BBFDAA8BF0A8246FD55D85066D23B
+:106030006746FD55149A60D26746FD3578C3D74C44
+:10604000FACCA8BF866D31EAAFE111A3FEBA6CC7E6
+:106050000A933E33EAAF2BF6AC31BC2F8DDE6D7860
+:106060003FEAE0F70CF5F2F61F18DA2F38F414E5E2
+:10607000F58C3DB6CDD06E5CC74F0CED00E1ED98D0
+:10608000FF3D9748C2D855A79E34BC9F2BECB5ABBB
+:10609000BB9E36F4C35A791E7718FE22BDDE6341DB
+:1060A0003B1A2956D6F54221D0755944F145A1D95C
+:1060B000C23DBBC6E03C3E7CE39A83D8CF822DC66E
+:1060C000FCEF851163BD910DCA40B9D0087C110168
+:1060D0003E598C79E13AF9B698358973817DE3B3FD
+:1060E0000587AE63944F1AF6B763DEBB8453F29B09
+:1060F0005FF09B9C9F847731D87F512D0EA71FFEA8
+:10610000F2FD66871DF976FE1E85FD40E9094FC345
+:10611000DECDEB0B13C06586C36C87FE47BED13F57
+:106120003E597551BCE0F451D5C7FD8DC675B8E236
+:10613000108F13AC7842217F9D191FD23E4D8617D8
+:1061400035CCF70D8D392C12D1AD3F4DE0C3E13583
+:10615000AEBFD3F80F9CCF0FD508E61BA568A96684
+:106160007E1B13653DF19C56625CA7663CBB7DFDC2
+:1061700012F295067F711EF3C5F943335F99F1BEA4
+:106180006CCF663BCAC38BC5FB6BF989E312A0EDEC
+:1061900046DB13E4D749BCC2BEBD03F548B2FDECF3
+:1061A00047F917BD9FFD28FF8BDDCF9EEB4DCF75C7
+:1061B000A2BF0DEC4BB39FCDAC8795BDFBFFAAA44E
+:1061C000935FBBC381EB2EE873F23C18939E2C299E
+:1061D00031E8C9EE7DEFDB0AED7B7F91E1B77B61B2
+:1061E0003EBFC9F03BBC00E72D197EA757076F0BD8
+:1061F000E085CEFD809EDA95C04E9CE495719700B7
+:10620000F94DD655F2F6E67623BCFC9CD1BEDC31C6
+:106210005EB23FDF2AF592FDE91ED3ABFDF95D11B9
+:1062200027BA07E39043E3F941F78A780D2C3B3F07
+:10623000D26D9D2DE0D5E70F67783369BCF4714FBF
+:10624000B6631E758BC7E251342C793EF75A97B569
+:106250006ABBF82EC7F01D3FCFA422BE01AF5697F0
+:10626000F5533DDF4EF232EA37199C93BC7C3F690F
+:1062700063C17BD11E92F161DBDB954E94772DCC0F
+:10628000EFE172D2E7D1E77FD8188F074F10F161A5
+:10629000F95CF5FC637958ED19C189DE047958770A
+:1062A00064F827E1F39035EC40BB33E44CBC2FFE9F
+:1062B000AA97AF139B80170C50E22B9A877AF1F1C3
+:1062C0001FB037AFC7716F57C39427D9E21E53125F
+:1062D00074F5DDCF15F4F6B08F82DE5EEC23B04F9F
+:1062E00067E179327F463F2B6D3BACBE12C4F706A7
+:1062F000FCF738F2D32EC0EF7BE4BD8A73B8B08FC1
+:10630000EB358F57F6B33FCBBFCCCBF30D9BB03FF4
+:10631000FF30CF5A55D74FFA05FA917E8E3EF8AD31
+:10632000BEED4DEC1F3D85FABDAF78DCE8EDE12F09
+:10633000DCE8EDC55F78EEF8B00C8C674B7F97B961
+:106340009D3C1729EB1B328DE3AF2FE3F5FBC5B85E
+:10635000AF887B3A7688BAD3745ED43995D13D1D27
+:10636000F29CA9EC6787D74DED9BB327ECC0F9AE43
+:106370002F56681FBA3E5331EC47EBBD953B900E4C
+:10638000DB44FF3B907F73296F94FC39E63CCC25BE
+:10639000A2FD12EF042AF15C2BCA31BBAA26C4E38A
+:1063A000135E3EFF5999BC5FE977AB7F4011FB2735
+:1063B000E3BD08B0CE5F4E03F97362938DCEBDCEC0
+:1063C000535DEB911F93DD73503B2240F94FFFEC7F
+:1063D000F931C4675A564FBDFABC37F1BD05C9E45F
+:1063E00088CE9F76D87B11794B1DA99C4FBBDC2EA4
+:1063F000F29B9BDBBD2BE8B349F83550AEA37EC9B9
+:10640000525953223DF3AEC0FB3F7EAE99DFE79178
+:10641000ED72D177E673CD1DF68E75F938DFAB15C9
+:106420001F9E5FC8AFF1ECCBCFC1738C1AF9F8D6C1
+:1064300017B3F40A7C5F6AA1F799B33CEB6D98F748
+:10644000AD31CCDC673618C70DE3A4171473B8C29E
+:10645000D7EDCB8776195A171B3482CE7B4FF1E2EA
+:10646000BAADE6F9F33DF02DE49B6B1DEC2F101F48
+:106470005AE23CF4F342BF80BCF93BF26BA5C6760E
+:10648000F373593C0F16D992F2157D3C5F3B0DF327
+:106490009D06737983EF95EC89D682DCF8FA520574
+:1064A000BECDE7B9D30BF8387D3DCF3DA326F17CB7
+:1064B000871770B88E67047270DC19E39BB93FECE4
+:1064C000B3F3E7D531681CF37502DF33F457A4E466
+:1064D00070399CA26924979947A13C57A7E66BC0E5
+:1064E0007A8AEB4A8F8A76B283C725D95C0BC3FBC5
+:1064F00055268A7EFCD54C79B784FB65B99CB5B22C
+:106500007725FFAB02396350CFF23F603F6D4A03FE
+:106510007826BA0E537C32654853259E6B787E0EE2
+:10652000EFE37B49CE0DC8F3EEDDE7FAD98F0E1B02
+:10653000CEF5AF7BE4F0C1AB75E7FAC38F1CF68FE5
+:10654000F8C7F3DBA73CF4C8E1B5AEFFB973FD5261
+:106550009E1D5383C7EE04FC5F0F4C152AC3D2CA9D
+:106560006A88DE5EC2DB2C81E7F0A78067671CCFFC
+:10657000D7EF3D44F83B668379C3F8B6091CD5B61E
+:106580006F66445A482E4668DC1B9CAD9371DFD978
+:1065900069EF1A89E3763EF3CA8030C893E3DF3AA5
+:1065A000E366C07F6F5ABBDCF8FCD4AA97DC780F97
+:1065B000C2F1552AD96B742E5A978FD420F8EA5716
+:1065C000058139C85773567F3E466F8FB3502EE909
+:1065D000DF85119552AFA4FC5BBC234D301DAF2F5E
+:1065E000DD996DA84BBDBCD491F89CFAA3059CEE37
+:1065F0000B1F6FB3176A387E70398E7F4AE4379C61
+:10660000DAEDA67D989C4FDDE3A576DC77BEB9D7A1
+:10661000C1A2E4076EB731F267F9A72A79788F1122
+:10662000FF639EE70BCFA6517FF31E50C9EF540BBB
+:10663000638500AFC1BD0BF93ED804C7BCE3DA14D3
+:106640009457F3362A2CACF1F6ABF0FE8CD05D14E7
+:106650008731C369D62F0B92DC9FB360EF3DF4FD09
+:106660005CE6BF07EDD979ADE6F7D7BC874CBEE055
+:1066700002F19CFB0B84DE19C3C69E1F4CF1A38C58
+:10668000CBB50BEB9D53ABF922FD60B593CA8F568A
+:106690007BA89C53C0F978F19E7D2F14D2326F1FD6
+:1066A000837AE9E583F5695FD7E276F798B65BF719
+:1066B0003F4C4D8DF9993502EF63455EE60271EE70
+:1066C000A1FC58EF799935888F913DE72BEDEC1AB5
+:1066D00093DF57DADD667C9C3E38310DF9E3970590
+:1066E000629F3B16F0A2FEF37849F6DD5295DF9BE0
+:1066F000667E2ED7D11CC1D773B7CF5CDF0FC66FB4
+:1067000079E6BD811DC4A7DC7F512EF055EE5ADF1E
+:106710008EF0973393DF30CC8E321D3F033FA9A814
+:1067200077CC7C2BF9891DE5DF3B855FA39B5FF769
+:10673000DE4BF8957C85271D2C68C3B1A8D7527114
+:10674000E17BAEE6B51AEB1FDB3A06A23C5960F2DC
+:10675000377CAC24DEBF1D2A1844F898ABF9A7603B
+:10676000FEC53C1658CFFDF3FC7E9C53D6D617EEE3
+:10677000C475BE9DAFB3A5BF7CE21728BF16FDEC64
+:106780008174945FEF5B5BF370BC258FAD4B4779F1
+:106790007FCA1A4EC7EFDF8FA809CF115FD24FEE25
+:1067A0009FFD2ECC535B46AC06FFCD0D4F47F9F94C
+:1067B00097C76C1EF4C336EE70441D808F65BB39DD
+:1067C0001EA1FE16AFDF45F86ADC635C978BFEFD09
+:1067D000813C8DFC01E14281BF4214E1CBB6DB2854
+:1067E000AF75D951D587C334B22E82CFFC3DCE23AD
+:1067F00006746BDCA9D6DA337ABE074BC88EEBADD4
+:106800007137A767E36E4EAF46931DDA20E4B69961
+:10681000FFF3FA097920F81EF0437E35996FCB22F9
+:106820005C7EB7FCF8C1916FC1FC3EDAFE9B7465DB
+:10683000449CFF196685023D4EEFAC9F63EFE5BEB9
+:106840009E8FC53AE9D60B420F697B6062F950DD35
+:10685000CBCB25B668FA558097256D365F181E2F6D
+:106860007942F5BBD08E7AD541F74F2C7EE2F9976D
+:10687000AF84F92DDE65CB99CAC170A1FC96F46A8C
+:10688000443E2F8BD367D153CFDB314F139FAFCA19
+:106890008AD369F1AE7D76CCFB34E373E2CE7D76AC
+:1068A000BEDE4CF4DAF9D614D4DB2D3F3E67477ECA
+:1068B00078FF5985E517F7FCBEA1EDF9749433888C
+:1068C00027D42F926EDD74EC41BFE8F4A747533B09
+:1068D0000FC6792E44C7BFE019845CE2F79F3E0DD6
+:1068E000F36878CDE1433C34FCF4D67484E73D6B27
+:1068F00013E7FB47D6E5A1DE6EB085F33C54F2E723
+:106900000D5BBF41FCB8E0C56FF0FB9C98BF00D7A2
+:1069100033C05B8070CEFBE1F504E77C16247E6C0F
+:106920007884DF6F78D6CAAA12ED07DAC4BA796F15
+:106930009B83360FEFD919BF2FE4F7AAB80F6B3935
+:10694000D92BDF10308384A6FA5927A7D7CA7EF245
+:106950009C3D976F8DA255E3F6BB48BE7D30C09F2E
+:106960008FEB1FF060F4CFBE38395FC845BAD785CA
+:10697000BE03FE9B88CFB17DBBCD9F32D2F09DC8B8
+:10698000BFE5E3AF14E3C3BC53D1CFF75E9E719F65
+:106990002BCBF66EB9C0DA999ECF92C981ED1B89D7
+:1069A000BF3E39CAE5CCB2C8CC2A7ADF6E8BE6E3AB
+:1069B000FBC8BE590AC909B04312ADF3ED36B1CEDA
+:1069C0008DEF619E56458FDF67F9F93DC92FF3EFD3
+:1069D00087F6BA751DE71F7BFC79717CBDCAFC8DFB
+:1069E00005267B4E966639F1B0494EC8EFD90F7334
+:1069F000139E8F88CB8730E16F892DF26F3FC07572
+:106A0000FDAA83CE452E79C246F7FB7CF8F8FE97A7
+:106A1000BF0EFCFFE14EB99E8DF2D7BC9E1B9EBC03
+:106A20009E255ACF1FE60458C2F50CCF13AEE71CC3
+:106A30007EDEE0FF96FC5D9044FEBED0AFA7DD7128
+:106A400015543FF8C9E222DA9F99F02BF16A96A714
+:106A500037A3B190DB539EC29FA34C874F8947C990
+:106A6000A78BFE63298DD3CDCF925F253F77F3AB04
+:106A7000196E233ECDEF37E2DEA93C4E7FDB1AD8FC
+:106A80009763BCF61995F2F33AB5AEF42C18779DDE
+:106A9000C8EFE9F4887A26AF77E5DAD7A33C91CF3F
+:106AA000BB5278BE4367A02B3D53B71F786BAF9A9C
+:106AB0008EE7013A2289F332286303FD2049F2363A
+:106AC000E4B9DFCE54EEEFEB4CE57EBEC9AA6B60B5
+:106AD00008F777AD3CBE34B7F9C674DCDF77EE1D3E
+:106AE0003CA31AF70387549E7314F65B0B00BFF5A3
+:106AF0001C74768A85BF3F1EEDF7BD8BA7623F737E
+:106B00003719F132DFB5DD8EFD9C65ABA89C7FBFE8
+:106B10002DCE27F0DF22CCD7423EFFA1E9F9DE6B74
+:106B200089AF1699F82A887C95E03C4966A158AF50
+:106B3000A5AC94EFB7457C4CC8BDC9EA8819D59877
+:106B40004F79909FF738BD5765EB11DEC745BC2CD8
+:106B50009C4BFCBA0CF85BEF37FD08F96E58723DA0
+:106B6000FFD1CF8F8FB9139A2CF9C51F473E0CE583
+:106B700047BF78F592FFC2FA2F5F19F847D6B3FDE9
+:106B8000C467FF7A0BE5753EEBA07B4D3B9FFDD5BF
+:106B9000C03BB1FEB483EE17ED5CC3F7D9E167DD0E
+:106BA000A4FF3B07707BB1E59973233B487FF17BE2
+:106BB00083C717F27B2A4EEFFDDB1B0AE6F3ED05D8
+:106BC000A8503E8AFD5BE3D329B44FEF7CE69C617D
+:106BD0007FFACFC2B34C9CBBEA74B36A3C27DD9901
+:106BE000C9CFA936FED7B81FE1B9CBA5BBF7D9EB02
+:106BF000E1FDC4FFF3F94894439D4F72BB03ECE100
+:106C0000ADCCC7D8570A37DF6B03FA7D8C3622AC80
+:106C1000998EC217A7E179929E78E178E8043C202A
+:106C20005C809706949FC9F0714B213F07F3AF87B3
+:106C30008F3FDF82E32FD93B96EE198EE345F1F3C8
+:106C4000E76ECAF700F8F9F367CF8D443BEA42F0EC
+:106C5000AEFA5F06EF0FFEC5F97D5021D74766BE3D
+:106C6000EFC9D7BFBC8DEA3F75FB68BE7D5CEF4FB7
+:106C7000FF2FA3F7B1FF6FE97D48D0DBEDC1B84C22
+:106C8000E7339F0F641701F7B97F593AF70E77B7CB
+:106C9000DD63F13947C3FC5E6391EB2B95E4F9A307
+:106CA00043FA2B721F44FB0C790FF7F49CF96447ED
+:106CB0004CF7737F4C0B2B3B88E7ECC27E95E217B9
+:106CC00094BC0378689F551AA13C316B78E8F73182
+:106CD0006FEC86A53E7E5F9971FF353DAFAA0AED48
+:106CE000B923CD302F6877C46DF1B4000833FC2A86
+:106CF000D97F5092DDF78709D7521ECA8C0AE33E2E
+:106D0000E4EBA6FDC48DD5C6F737B06DB998EF7723
+:106D100043838DF293AE37B5B7F4F7105E6E644DD2
+:106D2000EBB83FE7E2F034AB3FDF8FF5C443EF78D9
+:106D3000EB8127B1DFA4DC21AD27DE1C41BEFF744F
+:106D4000C00B616F89BCBC157DC22713FB5287182D
+:106D50005AE2D7E1E7F78EEAFA25BC48BC5F2CBEC1
+:106D6000259DCC7897F8957833D361189EF7CC8D14
+:106D7000E33F5E1AEFD566C26E9CDE6D37BA088FB0
+:106D8000BFDBCECF4BFCAEA27E5329D61FE7F7C1A7
+:106D90009F1D3F8A3901DE2336B687E2427EBFE679
+:106DA0001913CF9F512A7E45F109CC5FD4EF57319B
+:106DB0007F510F17E62FEAEB98BFA86F8FF98BFA78
+:106DC000F798BFA87F8FF98BFA3AE62FEADB63FECC
+:106DD000A2BE8EF98BFAF698BFA8AF63FEA2BE3DA5
+:106DE000E62FEADF63FEA2FE3DE62FEAEB98BFA89E
+:106DF0006F8FF98BFAF798BFA87F8FF98BFA3AE675
+:106E00002FEADB63DEA2FE3DE62DEADF639EA2BE33
+:106E10008EF989FAF65F8E3D67A857B2DF18DA4F10
+:106E200074BE64A84FF6FCD1D0FE2BDE1386F7D7D4
+:106E3000681F1ADE4BFA5F5B72C6F01C631FE131FC
+:106E4000B88FE17FA6F9FE66E8C7CA021427B5B37A
+:106E5000262A9DE8EF853295EDA4D205CB1CCBF711
+:106E600087057FDA1FF9756B783D32D79171E70698
+:106E7000A2FCFFDDF8EBB85F42C41766E03F356067
+:106E8000E2B4CFFAE33E57C64FD3632A8B8E023E5D
+:106E90008C29547A62692C9A0D7C184BA1322B965E
+:106EA0004DCFB3639954E6C40AE9796EAC80CABC8D
+:106EB000D8602AF363C5547A63975159101B4E6505
+:106EC000BFD828FAAE30564A65FFD855F47C406CDE
+:106ED0001C95036313E97951AC924A2D762D95C523
+:106EE000B16BA81C14BB8EDA0D8ECDA472486C3623
+:106EF0003D1F1ABB89CA4B62F5540E8BD5525912ED
+:106F00005B4CE5F0D8422A2F8DDD4ADF5D165B4EE3
+:106F1000E588D89DF4FCF2D81D548E8CB550794587
+:106F2000AC994A5FEC1E6A571ADB486559EC3E7A09
+:106F30003E2AB699CAD1B187E97979EC212AC7C42A
+:106F40007E44E5D8581B9515B1FFA0725CECC75480
+:106F50005E197B8ABEBB2AB68BCAF1B1FFA2E75786
+:106F6000C7FE93CA2FC5F6D3F32FC7F651E98FFD9D
+:106F7000869E57C60E513921F6123D9F187B91CA45
+:106F800049B13FD2F3C9B157A99C123B41E55762C1
+:106F90006F515915FB90CA6B62EF53F9D5D819FAA6
+:106FA000EEDAD89FA99C1AFB1B3D9F16FB2B95DDA3
+:106FB000FBFFF1497F57C0721EF7CFAEAC3EDD57E5
+:106FC000B6392D9DE4E2F4555C2E3E98F6F101921F
+:106FD00093E31C9A8384DF1643BC8B7E4402F67DC8
+:106FE000FBC6BDD71FED9DF595275EBF15F5D97280
+:106FF0000713FACC24773F73097F27C37CC49B0512
+:107000005FFFAE627F2EDA51EBCB3A96A0DFE4DE73
+:10701000E28E1A2C0B07703D9925CA8201C2CF5A05
+:10702000C2F56FCDF2A1FCF70572FA065FB5D0DBB1
+:10703000B2BD5224EAAEAE81745EAF8FFDF4B5DD11
+:1070400085F2B03EEF1FBC62406E6FE707FBDC4F7E
+:10705000C517D44FE580047961E67EDE14746F1B9A
+:1070600010988CED99D53F12DF4F5853A0E2EFAA4C
+:10707000D46E523CC82FF56B4BA7205DCB989FFC7C
+:10708000923727C9275B2CE85AD76463E89FACD3B3
+:1070900018F987EB76F33C64F4A74E037E6910FC85
+:1070A000B274E39FC9EFD4D0B480E73D45B87F4ABE
+:1070B000FE8ECDE2D6B617D0AD77961DA6FCF8C5EC
+:1070C0003B8CFEAB46E19F5ABAD3F4BCE92B09FDD9
+:1070D0009E66BFD4DC01C2DFE9E3794F4CED4F700F
+:1070E0009F05B8319F24789BDB897A03F0417118A2
+:1070F0008907E9F794F8603DCF5D50FEEAE98343E4
+:10710000294FEEB4A6E563BB603AFF3D2BC51A1CC0
+:107110008BCF018F94CFD2D59C46F9506F811ED072
+:1071200030F1CA131C8BF7C775BC368089FB2B8DD9
+:10713000F108E726CA13AF8539605E4AED63D9745A
+:107140006E13FA1BB907FD9A8FD9281F29CC5678E0
+:107150005945CF7845609D8DF8A26E4F26CF4F0BD5
+:10716000FB8FE2B9024997B7D60E9E82794D751B07
+:107170008A4BC95DB7C746F6A18CCB4A7AF5CCDFFE
+:10718000E6F9028D2CB21E5397805E2713D2AB75A1
+:107190001FD115E8763209DD4EF646B7874D7443A8
+:1071A0003FF58DF8725536ADE79A35D1A14D3AFECF
+:1071B00034FBFFD9DC2BE9DE1399FF5CD54FFECE03
+:1071C000982F0FE97B665339D1CD4CAFAABFD713A7
+:1071D0005DD86B6EBA77F8E6C16CCED7E0F91CE1EA
+:1071E000F7BCB9E51AB2BF770B39F7BBD598FBC925
+:1071F000D88BAB9DCC0FC6F74BAB3D54FFC36A2F6A
+:10720000D55F59AD51F9EAEA122A4FDA795E915CFD
+:107210005FC00894DFF7B458574F0F90FBB2955EEC
+:10722000F47357FDFDA5720B89BE37A64F1E40763D
+:10723000BB215FA47A96311FA4C326F2CD362A3E25
+:10724000BC4FA62E7095A13D2B1915AFA3FE11F9C9
+:107250002B751B32E91EBB9BA6661BDADFB0A1D0E3
+:1072600050FFFD008DE09E5935D8F0FCEB359719A5
+:10727000EAB5E2F723985641EB46C6BF407373BAAE
+:107280007878DB4F9AC6E6DF0EE37F72D846EFCD03
+:10729000F438690FD37E3EBCCDE1C3F8DE293CFF54
+:1072A00006F5537F5029BFE8948D853D20E24F2994
+:1072B0006C2D96CCCAD7D5D9637C5D55FD5D65B87C
+:1072C0008F673F71507CB07E8BC2C27837431760A6
+:1072D0001EC65DF96307C13D778BCA8274BE4ADB67
+:1072E0008971F2958F0DF3617CF4E6C1D10178DEEE
+:1072F000B0EBE7293E3CF755DFC1BF3F05FBF34C40
+:10730000CC8F52CA281EF1A769ADF32D986FA71E26
+:10731000CEC5F5FAA727F9EF9A2D5CFE87311EC07E
+:10732000F3A21776BE5C01E39C6C5569DC0F7738DD
+:10733000DA545AF7FE7CBCDF360E7784FC14D7F69D
+:107340000BFC0DE5F507F3232349FEACE2FEF19EAD
+:10735000F8017891DEC8AF3A7916D76F3CFE064245
+:10736000A800E544BDCD4771D9939B6C142F047DD3
+:1073700040F906275BB32D5C0E3D497C5767D5EC81
+:10738000FA71EB36A97EFEFB189A1DE7CB36AB41AE
+:107390003616EB3C3F22BC4109F2F88F91BEB72E66
+:1073A0001F4BE7A2CD795CB2FC18D6545017575A40
+:1073B000F40C8FFFB2D11D567D9EBBF4CFB060851B
+:1073C000E13EA325831EFCCE78284FFBF9D58B67C1
+:1073D000B7BB494E7E64796ECCED507E382DFCAE45
+:1073E00015E8F2A21A1C3610F3862C9BB62A145705
+:1073F00039F11D8CFB7FF084CD47CB50E48D2DFA05
+:10740000C9428A4F25B7179897C7AFA3798A176FD4
+:107410002766942F329BED14FE8508CF33C04900B8
+:107420007E3C4B785CEC44B9FB6E3C3F5C6F3A6F42
+:107430007C429CB3B872A062D0D7770CE472A0DE15
+:10744000C2D7277B96DF43297F2F4ECA71296FA5AC
+:10745000BCFEEA409EC722E52C633B49BECC17F731
+:10746000252FD9E1E0E78B34E6413C2EE4646277D6
+:107470000DE4EB7A91FD89EF235B2F60EDA4F73EDD
+:10748000B045E6B717E3F76D6BB3E87B9B2F82EB54
+:1074900038227F8FCE4A726401E3F35CDAAA44A2F9
+:1074A0003A7F87FC7D12867A4227777AE805933EF9
+:1074B0009827F4DF3C66CA376A35EAA9409A9BE010
+:1074C0005AD42AF2B0BBE7A5B2F318EF0A465E9889
+:1074D0004EF3567C9104F358C0BAA2782FF2D2C76B
+:1074E000F93926F3BCCC70F4759EF37D3327E1FDAA
+:1074F000CADDE39AE62DF1CDF060958E0E12EFF322
+:10750000C31C9FF3F72A44AF7784BD25CF079AE9C0
+:10751000BF8005A6A39C5B703FEC338BE3FC20F996
+:1075200060E1AE089D07FC90B5A6BB603D2CD9B2CA
+:10753000EB8671F0FD821FBE68477EAFC98A0EB52B
+:1075400064C2FE333CE9BB555727D0FB263DFF45BF
+:10755000E18909BF157D077899B75DA53C0A5D3BB8
+:10756000914710267C3584F9EF09361C557D2DF0A6
+:10757000B4017FE6A8ECE2E72BF1F63F3D6FB35D87
+:10758000F38B81BDDB356679D3C3AE31E9533CCF94
+:1075900081FAB32B97E7A77F62F56764919C36C9A0
+:1075A000E1DC32BA8F55CAE1F9420FCA71E6A1FE99
+:1075B00083FABB5B9E4A477FC63BF73F9547F91A64
+:1075C000A86F46C4F5CD6DF57CBCDB7E9942F952BF
+:1075D0007F9AD63E12EDC19A477E95AEBFEFF54F2A
+:1075E00005C1A30371BE423F2E55DB06E2EF1A4AE6
+:1075F000397BC17D5B3238DD1780D36D84B30EE1FA
+:10760000D49D53A91770BEBD81C377621387776E6F
+:107610000F38C31457B9ED470E5F98EC8E28E9F583
+:1076200053BB5486FBAC6EBBC364079C65AD5B115A
+:107630001F4B57BCF28615F862E125801FE0839A44
+:10764000CD0ED2FB0B7FCEE3A91F2895F914D03FB6
+:10765000104DBF039E2F027B01ED8DF83CBAED80EB
+:10766000CF108FDD76401FF1B74CF8B596EDFD15C4
+:10767000FD8E96E2E7F998CBE4BD367B4CF7DA68ED
+:107680002803F8397F27D2A9BFF93E2EEE9FFDCB04
+:10769000D03FDFB282F8BFEB12FD39B6C6D4A80DD9
+:1076A000F390BB762964272D5D59995EC9F07C1B48
+:1076B000F7AB151471FDA6F8FD945FE300BAA6C2FE
+:1076C00078FD8B34FE5CF3F07CF31F32BA4747CE73
+:1076D000D7FC1CFDED4ED4872E0BE94333FCD716A7
+:1076E00071BDB954B5907DBDC4CEEDEC4E717FC572
+:1076F00070318FE145FC9CC315C2AFD0897625C699
+:10770000BBAF76D0EF18313689FCEE56C6F9CF2ADA
+:10771000F1E6B17EDCBDBEC97EEEEA8F78BA85B5F2
+:10772000D3EF224EAF98A9E1798637F29C744F14BB
+:10773000FC09603FB3453F476CFCFCC21B3806C0E8
+:10774000355BF8A7DFC0EB5161FC370AEC64D786E4
+:107750009F7190DD70572AF71FB29C0C2BAE87AF3C
+:107760000B3975F378871FE5FAECF17705B084FEE5
+:10777000C20CF055E3EC5A570AE3345BB8BE6FCE47
+:1077800062DC2FB0B6A31CF1770598C998BF0FD063
+:10779000EF3E9FDD1B1F19CF4F2C413FC3958C330C
+:1077A0005805E1D7505F62E7EF6B1FDD31E3FEF173
+:1077B000B04FC0AC29D4338823E48BDA0CDAFFCE87
+:1077C000C0F30559585A89DFBE6665610B2F37B87B
+:1077D000E85E25AFE17761AFAF60D10C802F7AC84A
+:1077E00078BEE3C6A8253A0CE345D6E83EC49FC55B
+:1077F000A9D93C304EA04A2943BC2F59D3B7F9AE82
+:107800007CF4A919F7F7873ADEE785F3BC43A17C3E
+:10781000A1D9B0E8914F6FB1B2036A19A71FF26105
+:10782000639616A676CB399FCB7325922EA5D0BD35
+:107830001EBFB3C5FCA09F0DE9F8BD3DB15F252C6F
+:10784000F852DA6B8BC5BA5D2CF9EE71E37ADD265E
+:10785000D70DDA8780B7D9A24CC6F78F8A75F16841
+:1078600011DF67DE5324F7997D1B6FA9834509EE6D
+:10787000671C444739EE0C513E523488FA93F3901A
+:10788000FC3B9F35513ECF7CE1A7B18024A1FCE0B9
+:10789000D61F71BF9029EF080C25CA6F5BB4DDFCC1
+:1078A0005CE7E7510D7289FCA68ABD6B2ECE4FF9BD
+:1078B000528A0FF97DB67D27F907CCED6CF8FBA94C
+:1078C0001877DB00769522E26550776C52E8772FC7
+:1078D00066F7EFBA1CF53948EB29742E54D8DBF360
+:1078E000057D1DE27EABF9685F615C0DED2BC4D7B1
+:1078F000166E575A853D5CB7C9686FCC5EABB33B1B
+:107900007961B81FC061CA53B709BBE34D7BD7E5A6
+:1079100028F7CDF705BC69E17084F318BF573387AA
+:10792000BFB70AFB52F2D5CF8A6C86789B3C775A58
+:1079300083F28ADFDB60CAD372D1FD31350ABFBF63
+:1079400053FA215F17E569B043E9BE9CE369140768
+:1079500037FB273B2BDD618BCE4F7973C66DD3117F
+:107960003F35E9762B96AF77DF2BD641E31FF70C37
+:1079700022FB677DE5A82D989FF4DEA36766380794
+:107980005034459C9F8AFD0EF3E9677D06F050FD5B
+:10799000AF33FCB08FEA7CBEEB162788EECF8B3E70
+:1079A0009D61053DDFF940D756AC67686A80EAF70C
+:1079B000760DC43B9733220E5E6F96FD3902D85F79
+:1079C000E743BCFED1A38E4018ED5F716EA9E64A75
+:1079D00085E4AF0BD75779DCCF5463798E9713F8D2
+:1079E000EFA25CA89D570BB88ACAF13ED493F4FB72
+:1079F0000B8307F95D45807FCFC0E0392C17CD544C
+:107A0000C2763CEF7F347289D06B097F27C425D6BC
+:107A10006B617180BE977E74E88769E53DFBF96F05
+:107A20008E8B3EA000800000000000001F8B08002D
+:107A300000000000000BE57D0978545596F07DF5B7
+:107A40006A4B52498A244042162A090901031490BC
+:107A50004080A04512202C810A28A2A0168B10106D
+:107A60004840EDA65B7AAAC226E216D4B1691B9DF6
+:107A700012D1C66EB5A3B204D92A6C823A5228DA62
+:107A8000A8A041504163774418E30CB6FF39E7DE04
+:107A900097AAFBA8B0F4F4CC37DFF7878FEFE6BCEA
+:107AA0007BDF5DCE7ECEBDF7651C63AE7A1B633F88
+:107AB000E3CF0DA1D2D6D5C05821632F3ADCB6AEA4
+:107AC000504E5D9813EFC967CC9EE18972003CB7B8
+:107AD00052F199FB30C68EFA73DDB18C8DBB423FFB
+:107AE000BFC8BCA49F847FA49F8F74FDDCAEC0BBC5
+:107AF00083E03F733AF0FD3BB25DBD1D1D19BBEB4A
+:107B00005F9807FB6165430C6C0063775B19FD7C34
+:107B10005FB335D75A00E54B96449609ED5ED9968A
+:107B2000310BFA618BE1A514C6BE69FCC8EC807EFE
+:107B300016B4AACC95C85875AB42E5824D8DE611B6
+:107B4000D0AE1ACAD2B0F9CD13F365ACC93821361C
+:107B5000F4BCBF83CF97B1358CE17C5E396BF440C8
+:107B6000BBBB0CF55F3E95048F072BCEE71D97AE90
+:107B70003355BCF72963E5F5F997D60F722854FF02
+:107B8000588EAB08D7D905FA405835F0F5EADB2F07
+:107B900015FD4D8D6677B8A17EC68058AB03F05DAC
+:107BA00078D4B32C16E6316B5D663F15FAE89F5129
+:107BB0005282FDB19983257C9577612C88EB33B691
+:107BC0007462507EBFA3309EC1BCA62604EF617DC7
+:107BD00019FB8DBF7B9D752863637E0B6DBAD02B1F
+:107BE0002E06EF965B04ECBBDE5D560CF0DF558293
+:107BF0003D8EA23A1FBC7F10E703E56D037B45B3C2
+:107C0000DE80BDCC18833D9EB192F469BF41BEB801
+:107C10006DE0D011F87C982536771AE197117F94A2
+:107C2000A4BB27633DB667B00E8F39D0F166588785
+:107C3000E72DD5E98375787AC778FC11F03649E0ED
+:107C4000E1370E3B95070D30CF7EA17968E30367DE
+:107C5000DE1384FE4E2F4DE9BB1AFA7B367DD81217
+:107C6000C28B18FFD974CF9CF0F161B9BDF1F9D581
+:107C7000CE639698C71241377731F099C0F5CFF0AF
+:107C80007F42598C04DF383691B9F242F0A41B537D
+:107C90002578F2D46CA9FDAD33AF93EA2B2CC182C9
+:107CA0001A5B88BFF5F3D14A2014F16975ECC63828
+:107CB00006533CB1E3C28753404EFEB641752A30AD
+:107CC000D7393B9FFF7008B43A070B4E04BC9D7335
+:107CD0000100EB3DB749F5FB32913F5CC68A4E8C03
+:107CE000556157D07EFEA1D7CDC3E0D7AA9AD963FC
+:107CF000918E73FCA6CF9BC2E679815D34B32C9044
+:107D0000878DF2F36AF6D0776A6F840266772FE880
+:107D1000A75E575F33F22B1687ED8C9F3769EB8494
+:107D2000F1171FCF7C645FD8BA9F76C4267D791D7A
+:107D3000FCD28FF5FB59C5F19A0FC00A596943234C
+:107D4000D169D921D5892CBA2C5D610AAC73E4269E
+:107D50008B3F0A44EBDB6D27CD0EC0D70F5EC723E8
+:107D6000FB4C28FFB58C25E27B27CD4DF07CA8C3CA
+:107D700041785AB0E33B3303BA8FDCB190E47A0424
+:107D8000E8B178E09F6023EBB509FAF765C63A9F42
+:107D900087FEEF5A350A848BB1F8D62954CEAB1B37
+:107DA00045FDCD6F9D48F082D618820F46074730BB
+:107DB00098C7C12D1DD83298C7613590FB7BECC7A1
+:107DC000124B7AA222F5B6A5B8EE83D1BEFCBB61F8
+:107DD000BC8A3F8F2C47BC2ED8A4B890CF2A5476AB
+:107DE0005049C0F946517F15EA7B050BE1F998D25D
+:107DF000589F219EEA19837A7540EC6A06B06A069C
+:107E00007D11813F0F09FD626AE2F31EDE5A49FDD2
+:107E100069F5871D59B47E0D3675DC609C6E0BAD1F
+:107E2000C7D4A45039BAF53A2AAB37551A1D30CE0B
+:107E30005B79CF25219EA0BDCD13512F0F8C6711EB
+:107E4000F497565A843E9E82FA18FA3D90E5FA025B
+:107E5000E572DC9226A315F5A9CD6A7F1EF8605C59
+:107E6000515FC7ACB075A97B6E610EE0234B528B9E
+:107E7000C905FD4F81325C7FDFD18EBDF9A64D7FF4
+:107E8000D752A9D925E65CC218F0F9ED763E6F4DC0
+:107E9000AE8E89F6DAFB4185CB876FB3C5FF3CFC1C
+:107EA000FE5996E7279C6F70189BFC1AE9D3604631
+:107EB00065EC3F6FFE405F2BD23FCED8C412E07D11
+:107EC00043A6367F2ED7579A7F8B98FF61952D4614
+:107ED000BE387CC30D4117CCABF1BEFEFDD13E6870
+:107EE000E325669AA93F666FB988FC5ABD2BC6B1D7
+:107EF0001AD65701B441B865A7C5BF3E939E332536
+:107F0000094BCB7A05EAABE35A72D1FE94EE8E0AA6
+:107F100020DF36EE8E32A21D7933C79398D9119F98
+:107F2000772F5380BF5D3B2C46E48364872B29B3B6
+:107F3000B0FDF95E498F69F2A8E733CF2A2E7F1E84
+:107F40002187D304DF4E177238CDE88CFF25CCFB98
+:107F50008E7754867A7CFA12A5D7A602D469B1CE60
+:107F60009C3039D4E4CD847CD91FF993F3E5BCD699
+:107F70000E42BE3345BF5C0E2AC040237E2AAEEBC4
+:107F8000E047F95ED09A48ED3479D5E4343DDB53CF
+:107F90008AEBAE5806F20DE37896A614A0BC84F8DE
+:107FA000C46C477E023E499E15C607CB1A7F342219
+:107FB0009F988A15E2130B94A5617CE46EF353EC51
+:107FC000233AC13CC62DCF34AC66A1FA72E4978E39
+:107FD00057CFEF85A2FD745B20C700FD996AA29C74
+:107FE0004B615EE7921CA4C7163D0000A06091C9DA
+:107FF0005D8A7EC6A2DF294ED4BFE87FA0FE19703D
+:10800000ACC6EC099BDF2DADBD9903F034B1B51BB7
+:1080100095FD333C93100FD35A27093CF6A69239AD
+:108020008A0C389F7BACDCCE9CAFB9FF761CEFBCD2
+:10803000DFE2C4F1182BE2F416F32D74393BFF1282
+:10804000E7F78E893D0BEDCF44795494CB33E9CCDF
+:10805000FE384C71C65AA033F47BC6C47C76A0E7C8
+:108060004C803D087760AE0EFD50EE609D6176E578
+:1080700082B12E8365037D17FDE55323A8C239B96C
+:10808000C1DE011877EA306EFF9B3798C8FECF6BD0
+:108090007C6F8001EABFCE747566A07BC774F1D493
+:1080A000E07AE64EF0BF6202F8AE875F8F1BE4080D
+:1080B000E1B3DE18C831C2FBF580471FCCABFE210F
+:1080C000B5DCCFFD9E98CA5E57E6EBB9ADD9841FEB
+:1080D000CDDE68FA7BAB37191611D2E357B2431ADB
+:1080E0007FCF1772301FE58085DB9B4AF730E4C3F2
+:1080F0003CC599C3C2ED0D97074D4F03BF93DC54A8
+:1081000064A73B97B190DED6DBA3BD6AFDE3836134
+:10811000BDCBB33CEB510F94FCE9BF5EFF18AAE660
+:10812000BDF66219D269D8750A5395ABD1933F9ABF
+:10813000484F2EA964A427A10CD793A676FCF43F40
+:10814000645E9B9EFF57C1F7E0DF92DF887A3CBCFC
+:10815000BFCFB24AB6219D77652A5CEFFE93E6ADAC
+:10816000D7EFBBDAE4F5EAF4FB4BA2FD95F4FB1183
+:10817000D4EF8597EA7306FDA13EFFDBCE1E7ED4C9
+:10818000F79F32D0FF68DF76C4389E17FA9EEC4125
+:1081900074BCFF72FAFEB19C1947103F11F4FD7BCD
+:1081A000FF0C7DAFF1975E1EF472A0E7FB310F82EA
+:1081B000FF8574DAAA30D4AF217F8B111F1FCCE268
+:1081C0007CACC94D98FF45761EE4C19F9379A95CAC
+:1081D0007E5FF3970207C69B05B17D9912E2774D4A
+:1081E0005E347ED7DB9139591E35AB302427F35EE0
+:1081F000D3DB81F6F8699B09E357D3BCEFB81D8048
+:1082000032DC0EB4E7EF58B3AE4D0EFEE32AF92987
+:1082100035EB7F9C9F52B322F3535A56C77F9C9FE6
+:108220002E4347B2331A9F8D799BF307CBE6FE3E70
+:10823000F00BCDFBA039DDBF2C13F51ED787637E75
+:10824000663588CF3B443E41E3D711D91E17CE5344
+:10825000A333FAF7E8B75FAD5F3825A986B9E0F92F
+:108260001D5086EB0D0BD22F827F3FFC1AE9DC3FBD
+:10827000EBEAE83C49D0F99FE8174ECB8AE0173289
+:1082800017B7FF21BA582622DF7C1F303294AFF691
+:10829000E86A5ACBF1AEC12B0246CDBE26A27D05BF
+:1082A0007E99FEDFE1978AD2FAF35670FD7CEB8B64
+:1082B0002B8D83001F454CE43F86AE717543FD0254
+:1082C000BF0FA61E293F725815B0EFFA2365308FF5
+:1082D000318FB7D5FBB07E78717C5B3E054309AD2D
+:1082E000BD77FD90230FD1BCEB38BE3D4D4677AF37
+:1082F00030B800E0D830B84807AFE3EDD18ED8A948
+:108300001F3F974FE85FE987B0D69F9003D632A210
+:1083100003FA8B9B143BE6436E2DFE9B19E95351E8
+:10832000DA742015D6FBF8FAE195B61EF01CF5209C
+:10833000CCF7B9F5156B7C46F17E27CA8FD18FA596
+:108340005E71A940A779458A3F2BF3523C3E9725A1
+:10835000DB33FC31CAEF3373C1B5BD8FF24BEF672E
+:10836000D1FB01CB358C7F733173F923E8C957B545
+:10837000761701D6FA07DC4DACE771B8BEFD3621A1
+:108380006F4183613E037C35AE9FB606F365C3192A
+:10839000E78FBDEB3D95980F2342EBD67BB9F9FEF5
+:1083A000214B8EEFF0C721BF1FB81CBE5EBEE47D1F
+:1083B000C11F5532BFC41BDDFBBE8779C427297698
+:1083C000F46B17B8A31E42FFBDA254E3EFBB2A5DB6
+:1083D000C5B0BE2826E5FF42FC3DAF12F97B01D3B4
+:1083E000DA2F588376C96D686BCFF97D87D2F67E18
+:1083F0001EF00FA5E2E0FD13EBE7AFF1D9881E54A4
+:108400004F70B7CBF07BBD0E2ED6C987E06F924F71
+:10841000D4DB809F9C087AE33F059DBF55D864D488
+:108420007BC112EEEF05B378D9259BFB77866CDE16
+:108430002E3A5BD0393A0C0F69213AC34F00E388DA
+:10844000B075139E6E49D2D6FD70E55858573081ED
+:10845000F552804F92B21F58B33C8C4F3A653F5C47
+:10846000897808F5F7E011D4FBB7083C75C97EE8B8
+:10847000888FEB3305E56E3E3104F0C126C5A7C2F7
+:108480003AE7231F4458E7E94BE5C6A77BDF65BA07
+:10849000CCFB5F5FCA872EDDFBCC94742DEF0B3ACB
+:1084A0008DD5D1B15C47C7321D3C5583FD923ED37B
+:1084B000F4DCF486352B3A2561BE51413381FADA7A
+:1084C000ACF465ACCF734F56DA0621BF3A4CA9A085
+:1084D000F3FB3FB7F6881578B912F519F1EFEFD62F
+:1084E000B8801F27A2BC13FC54A5AB0FF24FCD8A56
+:1084F00064683FE8B9DFAFB142D35B97AF31A14FBA
+:1085000033F4B9A7D718817EB714FCF900F667AC2D
+:10851000FDB72363332FC3AF75BA75ACD3C13E5DCE
+:10852000FB27AEA0DF97EBDE5FA2AB7F4807AFD59E
+:10853000C1ABE4F7A7CD54484EA601FD1071579288
+:108540009B89D96D79A4367BA6D8C84F92F87ECC8A
+:10855000320EDFF6DCCB95ABF2C3E0EC3F5786F38F
+:10856000B189F19F2949CC87F6C3D48E3E1B93DD98
+:108570000E1FE5E9ED1DAFFF0C7F4DA17D16C92E45
+:10858000EF5565B851D5E6BDF3C83D367CA8C13B73
+:108590002AD11F6F77DF83BD5189FB1E631E15B083
+:1085A0006F5B25EA3D6D9D5AFB113FFDACE278778C
+:1085B000676FABDC80FB2A25811CCCD74F4DE025B3
+:1085C000D81915ED58B5C8778CD8A9BAD1CE4C8D2D
+:1085D0000EE42CCA0F5B27ABCFC57536DEA7127D24
+:1085E0007CCB783C329D39CD98AF688C8F5FFC0294
+:1085F000B4DF7B9FBA18EDDAA78B133BE1FCF7657C
+:1086000073BF6D6F7CD74E7702DC18738719F3B593
+:108610008DF70FA7728FEA5AD9027CBCE6B9836442
+:10862000E71B63E2093F0F67EFABAC05B9A8CB7658
+:10863000D0FB9E047BA706F457579B18E6ABC1916D
+:108640007A86F8E6614BDFD5308F69B5D7D1FED198
+:10865000F47FAD1C9102EDA6AF30D1BE02FCF4C692
+:10866000797B560F3763FDCCE5A2F48DA472F7DF5A
+:108670005F7FBB37B46F794075AE87C6BB5AB3E234
+:10868000A6C3BC4E45713DFC7973B7389C678F6EAD
+:108690009E75D9C8AF71B1D10A1A0FBB236E02F40F
+:1086A0009B9BE37A3ABB63A8FDEEBFABB40FB6BDAC
+:1086B000797A27CC3FFD41E8EF5DADD33B4D0FB359
+:1086C000F7B3BE35129E779B1DF7A07FB93B3A5D8D
+:1086D000C1BC0CE03911F3B633857F0DFCB2F8F55F
+:1086E0000876FF896C95F072DAB2989D02266E7C4E
+:1086F000B06331CE537B4FDB7F33A539FA85FBD195
+:108700001BBA96BC8EEB08F1D96747906FC88F06ED
+:1087100078D7739FACF1A12DDC0BFE3FCE23C9357A
+:1087200002EBD99244BE0F9A5C9F1B9E8F08F9A959
+:108730004B853EE0ED4EF862296E3DF152941FE309
+:108740009913BE4F62C3F3EF9A9CCC8E8BF5A13187
+:10875000FE2A36D68878FDD4E8FDF257B86FF8B413
+:1087600089F4E8ACA73B2E69417D00F4C47C907E7F
+:10877000DCE46E261AB7FDFDC1E6CAB2B430396139
+:10878000CD95AEFCF6E5E4D873DF546EB0B52F2777
+:10879000B385DF3EE269931BF97C7661AC11F7E9A2
+:1087A0004A9EDEFF3CF2E3EC8551FD2C30F1D94FBF
+:1087B0005B88BE4DB1B13E3BEE23C6C51A3B40F9C6
+:1087C000ADD0234DB55114A7A89DCCA4F7D4958561
+:1087D0000EC44FA9CA8C56B02B6A9CD3E1E6F07246
+:1087E000CC1BAE882D72207D3B76E3F2D0561F3F26
+:1087F00079B4D23BB46F7676F1E34F0E84F97DCD38
+:10880000FC930666FEF7F7D1AA993B1EF38FFF5340
+:10881000FB68E66EFA7DB4FCF89B91FD16AB346FF5
+:108820007569941FF1A966703B319229B48FC6EC2B
+:10883000B0FE5EA17D34F5D7FD093FA7BDC057DD71
+:10884000012F71566AAFFE5AF55B60DCD2449E6F11
+:10885000559FAC64B8AF0678F5D9011E995443FB17
+:108860006B4B859E99A630773DC9BF3303E3E4592E
+:108870004F47111D673F33E7C3DF1520DD2A92C242
+:10888000E52953F01FF4C7AC09A17EBEAAFD4D0631
+:10889000CEA7F4DF20BEC4B853F53C790BE9CD1860
+:1088A000DA6F63F6A6870722BFD4C6F4C53CF9EC9D
+:1088B000A75332B2F243EFCF5E7A5F2E7F1FE2D62C
+:1088C00038D45B51B49E799B2CC42FD31E505D6469
+:1088D00027D3CD64273F5F1E45F0BCB42292B76911
+:1088E00006BEFF063E6132E9778E7236CFC65CAFB8
+:1088F000DB50DF3F1454397D7C826E66A44F71B724
+:108900004492CB3B10C760BFA622BF75A4FE781E61
+:108910006A9742FB4D8CD538500F4C3528A4EFF4A4
+:108920007259D18DFBAFD3329CB7E37BF31FB138C3
+:108930009766F239A8DA7C206E9A6F08CEC27D481D
+:10894000B6C542F98D6A5847541C3FF7F01ACCBFA0
+:10895000DAC88C66CC4F39B85ED3E653EDA81C89D3
+:10896000FC0AF5C78C503F3F96EBE5F91D78DE8792
+:10897000C55AFDCF878F8773CEE6EF39E250DE060A
+:1089800011BFA0FC1BA0FE6F8CD797C615399AF2B9
+:1089900069FF7E15E64B703E3D7A878D0B704A6FFE
+:1089A000E4C785C6AC58A443E2A4C938DECB2AE9A3
+:1089B0002710AA478AD00F7C59ED8FF1ECB407F647
+:1089C0008E588BF0AB7DED388569AFBC4F76EA2EC3
+:1089D000C1674DE8FFA3DD02F85528EFEDC6F5832A
+:1089E00047E5F99C7BBB29D2BE9F563FFF0113D1BF
+:1089F00063FE0ACE0FF36BFF42FDCE8F0D76427AF7
+:108A0000CCDF6C1A807CFD2F62DED36BD38B8F01A1
+:108A10007F4C37C5DB157834CF576146785E9D4271
+:108A2000B036DEFC073EE864C8E7FD6169117C14DE
+:108A3000EAB76306DAB56F5E4ACC981646F76F96CA
+:108A40006F8DC37DED5351811C3BE663164639D7CC
+:108A5000939C727A7CB33C673DE66B66DA83B1B86F
+:108A60001F3EF39EEC04B4779FDA0366ACFFB43E7E
+:108A7000D380B0CB6E2F46D865EC43F037E29C0A2A
+:108A8000FD009D16289C6FE6BDB4D79C05E33D27ED
+:108A9000F8ECDB97DFCFC5BCC1FC8C602EDA61E05F
+:108AA000ABDC54A4CB1F15F21716BCA4BAA27A876C
+:108AB000F86A01F215C8FF5CC1570B366DFD25CA77
+:108AC000E902E4A77E97F225C497FBE8F96BCF8E05
+:108AD00060FCFD7DC8779ADD0778B909F36B660104
+:108AE000C338086F10FA1AEACB78BD2F9FEC096BD8
+:108AF00032A35F5CAD727F01E42919FD89EA069318
+:108B0000AF294C3F2EC0FAFC507D7B7CB3BF9BD875
+:108B10002FABB5905DDA2FF0D2F4C0E638E48B6F5E
+:108B20005FDE7B6030C659AF2976D4FB97C8A1C001
+:108B30005B35E2298ED649FE5135E2252E84A736D3
+:108B400079137C51CD381E34BC541B059EB47AF188
+:108B5000FE01C187F398C0EBA6EE5CDE857C03C7FF
+:108B6000901DD1D6E74990CF0FFC20F8FEA858E71A
+:108B70003CE01B673EF197CB3C40C4FF50F5EDABAA
+:108B8000CF52FE48A3A736EFF81C87A6A75D1D129B
+:108B900042746E32B0AA48F9EAAF85DC996C5CAFDA
+:108BA0009CAC4DBD7D31E06FEE4BAA939087B157E1
+:108BB000D8B81643532CF9A7BF56EDB8AED23F55DF
+:108BC0008EC6756B7C67DAA8181B709F907520FCA9
+:108BD0006BF32BEDEC1EDD81F35D00E7A3CDF3A479
+:108BE00012207AF95E55ECDCDF6D32631E5193532F
+:108BF000FD7C7F10F355E394C14A1F9C8FD381F213
+:108C0000CDC00ED27C6CC7EEA3F17C27EECBEC1D61
+:108C10001AE7535FAC11DB7DCAB81ED0F8F2A4C8C6
+:108C20004B9C5CB195FC616D9CD81CCE5761E37880
+:108C300016275D3A8ED6DE94C3E7A5C9C5C104CE1A
+:108C4000FFA5CBFF42ED343D8B3F988FD3F0A9E1D8
+:108C50002D4C2E25FC68F2A5C99346D77F54AED87B
+:108C6000928EE4B7DE2FD64D32D2296417903FD1D1
+:108C7000DE59CCFC1C5C98DD24BF6664DA77664F55
+:108C800084E71A9EF4CF4371953D03F13FD2964C91
+:108C9000FBE56C79F2BE6E61FED929CC7BA13E7DED
+:108CA00051F5933E65209561F65CF3DB6A178EB44F
+:108CB0000F43FE7A49A173479AFD869F87DAF8141D
+:108CC000FAAB2A58988BFEC4EA9C2C1ABF3AC97595
+:108CD00016DF9F77263822CE118A5F869E0FA8F175
+:108CE000981FDC9429C50FF39AF7919CCF67C19523
+:108CF00018EF4E7BE0FD8A8148FF174D747E616658
+:108D00005D26D9BFB31B66F4C7D076DA8A1C82E72A
+:108D10003C7F27871FE07EDDB415852F607EFE54E3
+:108D2000946B04F279CB1AC58EF1D790E70B97DCE0
+:108D30000AF54362BB76C0F99ED870AA6230C611AC
+:108D40008B55921BD786C72761BDAB4175E2126771
+:108D500032FB925B91CF8DF12477DAB9C66526CECE
+:108D60006F77E670BD715B0ED71BB709FE2D5DB640
+:108D70002C17CF15B43C0B760AF7D7CD8EFA00C668
+:108D8000813B3B3BD7C338D510B626033F9D51B836
+:108D90003F5E656656E4AF43A6E0BD38FF43F7C6C5
+:108DA000F6ADC509A81707A07CB844DC0571148D81
+:108DB000ABE14B1B7FA61857EB477BEF20FA5568BA
+:108DC00047C47CCF2E7F7112FA0B6737E624B03090
+:108DD000BC9FC57501BEE7807E7C2D423CB8304704
+:108DE000CB4FF8A9AC1279C443A6BA34DCCF05BF87
+:108DF000FE74B87FFED5B35156E44BF0EBE5E726A1
+:108E00006E57C09F979E83FC48705BBCA74E8DF742
+:108E100044D0475AA9F7F797E7D822FAFB9AFC5DA6
+:108E2000A2D7847FDF9677E9766DE7BA9ABD4018BE
+:108E300010886274CEE0FDB2989F5EC7F397B3EAE4
+:108E40002C760BE0F734CA17EE0B6E56B9BF68E507
+:108E5000F2767A675F3FE615661D67CE00C0B38E77
+:108E6000AA4E07B4DFB7E67E3ADF71E73A8575565A
+:108E7000C2E2AE27D64C42713BE7F4AC4C81F6E738
+:108E800036F2F328506DD3C55B07521CEDC75BFF6C
+:108E9000AC384BCB3FE9F1BF2907E2AD18F8C5C9A3
+:108EA0009C32FE79DCBE1BD8A8A8DFA5F86FF67A45
+:108EB00028AEFAABB78ACA41F5CF96A6C23AFEA64B
+:108EC0009C7C6408CA516C3CE54F9ABD35B439F8B6
+:108ED000D786FE17C7019EB6DBE2EDA83FFEEA5D2E
+:108EE0004CCFDBF846F0E9D04D8D6A2AA3F63B86DD
+:108EF00040FB5DB678DCEE88B00FC7E9AC3F7F730E
+:108F0000F7C2819DF1B9B6DEAF7FC5E9DD66C7372F
+:108F1000CE88437FB5F1F7893B06219D63E2EDC81A
+:108F20000AB3C5399C2FD7727D74C61AFF02E65169
+:108F3000CFAC9BD809E3C33B4D2D6627F4EBDC593E
+:108F40001987F9822F8C4D71762CA17D00E761F491
+:108F5000ABA807079733DA1F1C1C303247266DDD9C
+:108F600013FF0C6A36FA316EFE06F70DD18E5F8C58
+:108F7000E6FBF7623FF0CE6D3CCFD6965711F985F0
+:108F80002162BD1D7213B47D207A5E5AC49F7FB5E5
+:108F9000EEF571D8DFD90D263BCEF7AF1B4CD4FFD1
+:108FA0005C88EF0DC08F6736F2F3027377409C9CAC
+:108FB000897A4421FE9D0BFC6B45FE5B687299E348
+:108FC0002FE5CBD28D3CBE9E5BAF50BCADF1E75CD4
+:108FD000977F04E15DF0A915FEFD0CA6A303AB5F2E
+:108FE00089F8688F5FFFD17C803537723E40CF0FA4
+:108FF0001ADE34BE08F12923FED4E89F50DF7758EB
+:109000002ABDE0237CFA4A581EFA0BCBCC2C0FCF9A
+:1090100043F90CD14E94FB1FA2E27A631E6AB1950C
+:1090200097BF8C8E5B8FE50F51197E9CF70F06FB67
+:109030007E8CB3BCB999C4B7BF541D26057E9D98DC
+:10904000D4544666A0D4E032A01D5C66213DA2D770
+:109050004339B9220F98CBA81C96CBCF899B580DCA
+:10906000F9175A09FE403AFA2F95310917F0287975
+:10907000BF173A4FC4FDDECA2109F76683E739F806
+:1090800085F48946E0F3CAFE099BB3002ECE4DE37A
+:10909000709F844213C0B5B51913CBA0FD2DB92E16
+:1090A000676ED8385ABFF0BC3F3E1F99E219908BCB
+:1090B000F6DF6C5B8576E06F4ACB02831A6A7F44E9
+:1090C000619F6E574270938965A0BF3DAC6DFE9164
+:1090D000CB55B9AE1B72233C9FCED80ACC4B4CF774
+:1090E000BD794C217DC6DC56A0E778C17FD3ADB6F3
+:1090F00000E9B955A6E636FEC8423D156F44BA8F61
+:1091000013641F6F0C34E2FB3DD872FB9756721547
+:10911000D7FD9CD8BEFE0741655F6AFDC1FAFE66B9
+:1091200082F5025D1517D01A444C01244F057DA726
+:10913000EC78F347EC77998F3545111DA6DA910F3E
+:1091400015E631FC0CE5FC18E08B3E58023F40BBB5
+:10915000459BBFDD87623147F3B33C45E42FDE63B7
+:10916000E7EB619EC1C4AFF70A7EFDCACB6A3055FA
+:10917000343E188CC3A3B0CDE302B9A81FCA554F23
+:1091800015D2E1AB75CBD21601FF7CFB9AC539161F
+:10919000DA9FF1BF1E8776759EF0F7D945357003CB
+:1091A000D41FCCECB17E75187F2DCCE576BF39335A
+:1091B00090711FEA994C1EAFB28B7B33EE83F6E5BC
+:1091C00059A30A5713165C77E786ED4F8E33463E58
+:1091D000BF31298DFBEB6C03B7C71623F3C52650AF
+:1091E000C9E2004FA3602E45782E156095F6F3FD79
+:1091F000D41EDBC5A15FE39891CCF77B981BF59655
+:10920000465F8D6E97D013A68C7EBDC1CA4CB8DE6A
+:109210001E6C9D1DED9346D7AF843C7E65E572388C
+:109220005CB5919E5AB499E7F516295CDF2EDAA950
+:10923000F0FCE625F676F34AD4C955EB66903ED3AA
+:10924000F49803FE217FCDB5BBE3038E7FC0EEAE65
+:109250002BBD2A7DB65ED3677D595FE4BF2BF94BEA
+:109260009A1E03F2BC98DBF11AE885288375CF16A5
+:10927000731CAE4E7518112F1DAD4ED4E78B9ECECC
+:10928000263BC92EAE65E1EDD8BA44E2DF95992AB6
+:10929000D1B5A2219539E0D19C0685CEC98E6D4805
+:1092A0002438AE3585E08A3F742EC175B7ED83FE54
+:1092B000A13BC1675F78BBC0C3F33456ECDFCDB4CC
+:1092C00079E4D7A3FD39678379009EDDB65594779D
+:1092D00074B3B67848F9594118B806E5CE65F2710D
+:1092E000FA586B49FEC5BA1609B95A7488DBEB45C2
+:1092F000C3F87EA1D1D7231EE96F3AA8323FC03709
+:109300001D520B03D07499D0E79664037384D12D5A
+:10931000CA11CD1C61F4613E5710E3ADC9825FEE06
+:109320008FE27A3F262F416A37D9368BF82798315A
+:10933000E220AE37D6D945EA9779B87FACF1D5248B
+:1093400091371FC75A96A39DBC6932D487F5672A07
+:10935000FE8EEC86A958F6AB012FA72FC74FCD1A6A
+:109360003FF5603D889F74F801F9207B7FEE28BFB0
+:109370007F025EC96F8B019E74D0C4FC50BF42E077
+:1093800005FD568C7FCEB962496E34BE0BA2DD035B
+:109390003D175F24E3AD834BC65B62B98C9F8E6E35
+:1093A000191F9D276749F5299E9E527D6A553F09E1
+:1093B0004EAF192CB5EFBAB84482337DA3A5F6D9C8
+:1093C000AB2648704EDDAD52FBEE6BA74BF53DFC76
+:1093D00073A5FAEB362E92E05EF5BF96DAF7695880
+:1093E0002AD5F70DAC96EAFB1F7C4C820B834F49C4
+:1093F000ED071E5B2FD50F6AFAA3543FE4CC6B1226
+:109400003CB4E50DA9FD0DAD7B2478187B5B6A5F4C
+:109410006A7D5F8287DB3F91DA8F4C3E25D58F7264
+:109420007C23D58FC9FB5E8257083FA7C2F95FD264
+:109430007B4188D8908F73D23C43BB53DEE78C11BD
+:10944000E5EFD86D0A4BC4F8E7E0443BC9FD35C6EB
+:1094500081C3BB8B3844F0F10566BB1DCFB35F49B8
+:109460002F66A33F51887C3E96EE559DABE7F90EE3
+:10947000BD5DD7FCB97830CBC6B0713BB8AC10D06D
+:1094800087E0C472BB047774274BED3B4F7648F5F9
+:10949000299E3CA93EB5CA29C1E9354552FBAE8B90
+:1094A0005D129CE92B97DA67AF724B704EDD64A9B1
+:1094B0007DF7B51EA9BE87BF4AAABF6E638D04F7AC
+:1094C000AA5F2CB5EFD3E093EAFB065649F5FD0FF2
+:1094D000D649706170ADD47EE031BF543FA869A316
+:1094E000543FE44CBD040F6D6990DADFD01A90E070
+:1094F00061EC90D4BED47A448287DB3F92DA8F4C01
+:109500003E29D58F729C95EAE77DE30CD0BED476D8
+:109510007EDF55F3E7C6E47D27B5332581BF8FF99C
+:109520006F16EDC4F3FEEDF9F99A1F58E1FC511ADC
+:10953000F70703F7CF5FEA9E25FC7FEE272EF3B9EE
+:10954000E97C5E021E78053989F729C47F18624DCF
+:10955000A57C6412ED5B90C974E07937F083004814
+:10956000306466621C1213F263D37EEE7FF57EECEC
+:109570001B10E3A05F7DB6BBE7CF289773EB5F1DA1
+:109580008171CE1CE65B89F300BB1B8FFB58EF4655
+:10959000C9F928AD1C65053C868D7728AA2EADDF5C
+:1095A00065E47794B599DAB7F52BF2550AAC6F51AB
+:1095B00058FF8F40FC650439ADF3829C41A0FD98B3
+:1095C000D74EF013DE64829FF43AA85CEBCDA3F291
+:1095D00029AF93EAD7798B087EC6EB22D8EF2DA767
+:1095E00072BDD74DCF37782713FC82D743E5466F3E
+:1095F00015957FF4D650FD4BDEC504BFE2F55159F9
+:10960000EF5D45CF5FF3D611BCC9BB96E02D5E3F41
+:10961000950DDE8D54BEE1ADA7FA1DDE0682777989
+:10962000030407BC0709DEE30D12BCCF7B8CE0030B
+:10963000DE262A0F7ACF50F996B785EADFF1B61207
+:10964000DC2CF613BEEAAE48F7183598B132E207C3
+:10965000CDFF1D87710F324791E9AF52DCA38B3FDD
+:10966000F4F4F85A8C632A01F717FD9F2EB9EB9793
+:1096700085C505DF8BF1EE8F66BE2890875A03CF34
+:109680000BD42630BA1FC6847F3E5BF0254BE27EAA
+:10969000F92C31AFD9420E0A913FF3883FDFB996DA
+:1096A000384B8BB7ED191E350FF933DDE0A3BC83C2
+:1096B0008DDFC3EF9FE131E7811C9DABB9F3008DD6
+:1096C0006777E6E220159640C79B319F7448A53C1A
+:1096D0006C7BE3558B7B12EDD6EF3A9B86F6A8FCAC
+:1096E000EF2AE5EBDF35C54EC67C4B721EC74B72C9
+:1096F0009E412A7764B83BE33CBFCAA979E16E2555
+:1097000074FF7F3C86E620E795CC61A273B8CCB5A8
+:109710001FAFDEDC040E1FC237331F9525E91E077D
+:10972000BE7F0B0418087B065B3222AD473F9F9E2D
+:1097300079DC7FEF996790CA8F32DC3D103FA773C9
+:109740005CD27CE2BA3AC47D9C9667705EFFB1F34E
+:10975000BB2F95EC10BEB5FCC6CA61E29CD6424553
+:10976000DB07E77EA295697E22D54FBD97E77B3464
+:109770007B79BCADE4FAF05C8D89F4E65425DA8996
+:10978000FEF6B99A7BFBE07EE16D10EFE1FEA9A643
+:1097900047A7026C00782AE3E72EA61E8F253ED34A
+:1097A000EB57788FE17EDF54F03F317E54BAF27C84
+:1097B000CABBEEEF4CD82F4B6AA17BABC037A3716D
+:1097C000FD7307A9F4FD86770DFE5C45257E312BE0
+:1097D00030FFD949C02F11FC058D2F16887B39DA4F
+:1097E00073E0B71B913E7FDD36308FF669760D72E0
+:1097F000203E9719F8BD3ADF5B2A3F9781A97C3C50
+:1098000037129FFF2CDD2F40E702E9372896EE172D
+:1098100034AA6CF1AB11F4E9BD828EEF269BCAFD30
+:10982000D4AFBCAFB840D075816857B1E7503ADECD
+:109830001B5C70D04471112B68CA7747385755BDEF
+:10984000F8C15F740BE3F3EA8693FC3C166BCA0F16
+:109850003F87F5B0E06B8DBF5473ACE7595BF8FC04
+:10986000F8F8C0E7F7083EFF12FDFE711647FCCD81
+:10987000F06A13A02600A5E7DFEC749E4F3BD737B4
+:1098800093B9A99C0DE446BE76FBD6D0BDFAB9AC1F
+:109890009E9E2F289A918170356B294B86FE6E5AB9
+:1098A00055BB3F196637B16ECD70CC734FF04FDBAF
+:1098B0008F65E506E54B9F83E464058EDFA4D4AC99
+:1098C000E802E3DDFAD2B01598471EA7723AB0B7A6
+:1098D000391D809F5C6AC2A5EB03B97848C805CDE5
+:1098E0005F938BA94B994B490ADD03699393A2BB04
+:1098F0003E4BC53D16630B9D43A9DE6549C0FCC9BF
+:109900005CC6ED76280FC4EDB526075F9B38DDBF3A
+:109910007E59A17B365F2B8CBEE7D09EDFA0F99FDE
+:10992000207F5CEE3E8DE1FCAF8ABC5E8627B95F8E
+:1099300076C83E7F6DF00F88CB26FBBD11D7632A1A
+:10994000F13CD417CFEBBDA23897C15CBEEEE0CF9F
+:10995000E0E704DAEC00FB392694277CC4C4F376F4
+:109960007A7F575B477BF3B498990FF7B394A203C0
+:109970003FA21F72E97C3DC903002FCB904498970A
+:109980002C713B22CD63B918FFE04F3C1EF7A53385
+:109990003A17A4C7A762E7E3B4975FB544F3F96841
+:1099A000764A9BE7A5F3E2F47A3F2F93E8AACD0F1E
+:1099B00034459E1DC6371AA39D28AF9546CF7B8898
+:1099C0004F2DFFA6C5C50733BF227BC02E2E4BE30C
+:1099D000E78F03EDD9E1E6B6783C2B6427B53C165A
+:1099E0002B8E9C8F745BEDA4BF263027D98B1EEC89
+:1099F000B8862FCA63A9B84348795E0FADC382FA0F
+:109A00001ACA28CCA390BDF4937CC6E0BC685D4123
+:109A1000CC88B03531718487C1C718E9E9C1B8066F
+:109A200058EFCE93CC8FE7A91A2F4C2A8D85FA9D3B
+:109A3000DF1A290EFA6DCC2BA9F81D899D673F4CC2
+:109A4000C57C4FED852D040F681E7196E7CF8E4FB4
+:109A5000C1FEB69F373B2CE4072C243C6879CAED45
+:109A60008C39711FB4E8231BDD332E3C5A1F437819
+:109A70001379B562B1EEE2F33C1FB20B81411007DE
+:109A8000B4985920CC5F36D965B88885C1993824F7
+:109A9000C061798E6B8D1F637B883CC84036303C3B
+:109AA000AFC65A1322DEA7D2EF2316287CDE67F258
+:109AB000DC9D7A50FE6C82CAF1FD7715F17583CD7D
+:109AC0009F82FE6DE39C1752D0DFFD6DCCDF098FC6
+:109AD0004FFD644E41BCD60DFB0FB22375F06E10E6
+:109AE000E35FA33F8A51FE6B3EE5D76E1076F6A981
+:109AF0008B9FB364C0675D1123FBC9841DD6EAEB5D
+:109B00002E9EAB427A5E28B63A502FE48A7C68EDEE
+:109B1000F5FF99DC14868F9DE0570780C0DBC1AF4D
+:109B20000E80EFBF0DFC6A84F1DE29969BC1AFC6A3
+:109B3000D20F7E3596CF805F8DEDD0AFC6F229F083
+:109B4000ABB15C0B7E35964F825F8DED9E00BF1AE8
+:109B5000CBC7C0AFC6E77517A797D27C8E31BA5F67
+:109B6000BF3426CE80FA15E61F8D79A1C3AE7ED113
+:109B7000888FEBCF1B24FA1637474BF0E0D309212F
+:109B8000FA22FD8F7791EA071CCD92EA337D3D25BD
+:109B9000B8EBE27E128CF9A1F0F753AB4A2438C53A
+:109BA000335A6ADF79F20409EEE8BE556A9F583EDF
+:109BB0005DAA7F344E4747FF3C834C47FE7D850BB3
+:109BC000C5363A5FD91E9F3E26E8A2C18FFF4A9D47
+:109BD0001C296F7B570F83140F741173BBBB8783D2
+:109BE0009EEF3B31F0C5DC02A487816F9BBA5A62BD
+:109BF000BA015D721F37303C5748270E607E76F100
+:109C0000DEE325E762902FF75698A3903EBB5D25D3
+:109C1000D1082FAD30A784F3515DA6A71FDD53F007
+:109C2000F0F569EF3F5A32E1B2FBE88F21FF75BFD3
+:109C30004CFDE8B959280F97E09155D17E6D088FFA
+:109C400013E8FB4ECC5325CD5F2F170C37E953702B
+:109C50005CAB8C4F57D6038887A79E30D239ACB601
+:109C6000FEC4FB5A7FC3D58B314DF997CE7FB78B9E
+:109C7000B707FF370AF1026349F34B703A86217E3A
+:109C80007E27E4ED5F85BCFD56D015E35884999D91
+:109C9000BFA7D1ADAEEAB151B92837457C5EEB6FB5
+:109CA0007C4C417593C89CB5F630BC3E21E6F18CE6
+:109CB00058D73AEC17E08E37BA14C45FC662B78241
+:109CC000F2D6754913C14F09F94EAB69A1E7E9F71F
+:109CD00004A8EC5215A4FAE1EA4BB48E363C386580
+:109CE0003CEAE9E417EBD1FA0DBDFFDA21E4B70B4A
+:109CF0002E3EFF389FCD85F622CE6777F2D2214ADD
+:109D0000A713F57E9CCF25E09A7C84B78975C5F9A9
+:109D10007C04FBC5BAEAAA920EBDE0088DC71CD52B
+:109D200086707BD31E3F6D15F8DF2CF0A47F6F9BF0
+:109D3000A9A6BF3D825C69A5664F8B8E1B747A27EE
+:109D40005A92FB43F80BB7037FE981F2E873AB62E9
+:109D5000FF8AF038B12D5E9A4AFCB426E6F6B73198
+:109D6000DEBEF1A8CAB8BD1DB71FF5E5FBA32C6484
+:109D70004F1B478D4C0FE7BB06B18EAD02EF837CC6
+:109D8000AE13F740FB316E0BE5E3073257FABDD057
+:109D9000DFE8B1AA3300FD1D6DB327EE187EDE812A
+:109DA000DB9309620D7BC64E7C10C77FFF28E80558
+:109DB00047689E5AFDE6F289637A211D839C8EEDE9
+:109DC000E1E74D41AFFD625E7B05BD1A057FEF16F1
+:109DD000F664A7B027DBD19E5890CE45623DDC9E4D
+:109DE0006C16F62488F604CA77853D7907ED099448
+:109DF00005A3B2CB486FE22536B22710A0D07982F6
+:109E000005D2BAB47995A7A912BD4624C548F42A4B
+:109E1000B3254AF525C65409765DCC92E0EBCFF721
+:109E2000D4D929D9AE0C3E3D5867A74A2478C0D171
+:109E3000D1D2FB95AE8952FDF8A229527D85738659
+:109E400054CFC47E18DFA283327A9D4A71AED87790
+:109E5000D2FCA9F7CB55DAB719F481EA0C97DB42AB
+:109E6000D6B64F66C07D32705F1C46ADBF2CA99E32
+:109E7000FCA8A326772A9EDFABAD043E84B2F82867
+:109E8000F869947C04BE06BFB7D03D92FC40F097C1
+:109E9000FA131D5AF87E93B66F3548B7FF343A5F10
+:109EA000DE9F2ABCC2FE94AB673B7E59B7C4ABF2BF
+:109EB000CB40BEC8FFFA6DCCED7B916FB67D047EC2
+:109EC0002AFAB91FFD82FC2FCD6FDBFAC52FC8BF60
+:109ED000DDDA262F1E495E0A85DC6E399AD5D0045C
+:109EE000F2B63959710A5493BC1469F2D224F4665B
+:109EF00079353D1F20DEDB6A72C7A0FFB7F9D85263
+:109F0000D16F981E217F3D4C8F601CC912E4FAE48A
+:109F1000D4507D162756787BC67AEAFAEBA78307DA
+:109F2000EBDA97E8E0D1BAF61374F0ADBAF6D3A540
+:109F3000FA0658F7E5FCEDCD423F68ED0A8D6ED587
+:109F40001941DF0E382AEB57E6AE96CE3D349E9887
+:109F5000457A73CBF195028F55127DF668E31C05A7
+:109F60003CE75FFA7E89D117D31BF8A0E498D1595A
+:109F7000EB08D14FA313C37838ACBF52AB2AC95FEB
+:109F8000C3314EDFF6D6B94BE8E71DC2CEBCA1F314
+:109F9000DFD49FCEBF3F1EF8674B9381E2AB2D47C6
+:109FA0002724627FBB2FCEA4F9361C33D03DB217D5
+:109FB0007B8EBFA9B65B687EDA7C0A3F581A83FBAA
+:109FC000AC179A0CA4FF0A4DEE447B04BCEBF9AB32
+:109FD000BD7E35BE05072A11F1B21BEC109D1B1684
+:109FE000FA54C3CB9E134F12DEB71D5B948878BF23
+:109FF000A1D520E165688BECAF0F399320C1034FE9
+:10A00000727F10ECAE84DF2BCD5B2F17B83322C3E9
+:10A010005DE4F657E90F6C1774DA26E8B43DCA39E7
+:10A0200039D2BEC6B64FCD55E1DF5538D393E7DB05
+:10A03000CEF4E4F9AFCD4047D4B3174E1B48CF0E52
+:10A04000B1D7AB3511E851DC6CD0D909D96FB8D68E
+:10A0500078F5543B7AB1BDF735BD58A27D3F2578E0
+:10A0600063C4F3B1213A8873953A7C6A7EF495E92A
+:10A07000A69D47D7D1AF9DF743FDF8F4F134BB0E51
+:10A08000FB69AA247BB326E65DA1CFDF257DFEDE3A
+:10A090008F429FFFD889FCA423A33AA7A31C1D6964
+:10A0A000D3E32C365C8F6BE72183CDEFC584FBF9BE
+:10A0B0006EC18F3B5DEF8FE983F4ECA6FEAFFA3BF8
+:10A0C000EF0A7FE71DF477BAE33E10F7770EB96623
+:10A0D000707F2759A1EFC52C8DB9DEE889C0A7FF95
+:10A0E000D7FD9CF145B29F53E194FD1C6DFF60B715
+:10A0F0005DA1735863F264BF6737FE827926ABE2D5
+:10A10000C77B5CDB5D132FAB870342BE0F09FABC34
+:10A1100029F4F07E1137EC40FC135DCA055D78BE72
+:10A12000A2F8BCD3E674207DAA785C96574DF1F472
+:10A1300050CDBE7B6BA8FD910BD3CFE3FDFEDDF6CA
+:10A1400018CAB3ECC6F9C0128E983CE7F1FB15BBF8
+:10A150005D8A636984B87E488BAC07343F41E3CBAA
+:10A16000DDCD9F135FEE6ABDBC3DD5F497D6EE4DB5
+:10A17000F67A29E2E7FA66C6306EB892FED1DBC500
+:10A180002B8DA36F3FC458AF46B23BFA71DCAD01D3
+:10A1900015CF3FEF6C0926E2769D3B7048C57BE00A
+:10A1A000C52D019AEF3E97625733A95D299E8B7E9C
+:10A1B000F3E27B63F0F9AEF3468385F699EC24B7BE
+:10A1C000C5423EDFB968B03909BF2AED73045A3E73
+:10A1D0007F10E5D56755E9BEC8EE8BFD92C2F1F65A
+:10A1E000E8752AE993ED651603E697B79F378AF37A
+:10A1F000D601F21F76B466D9B0DCEE02F9217D11EA
+:10A2000024FCFFFE3A7E4E7527F4C7F58483E6A151
+:10A21000F141E0BCA13CD2F7767E2FC61B72F1B3B0
+:10A2200018C4CF81F37B62505FED6AE1E30C59D231
+:10A23000148371E6DBAD86589E57E99F84CF1B8758
+:10A24000DF6FEB87EB6A31F0FD1BE1D768E3ED2EA2
+:10A250009B4DF9FCDD2D3C0EDB7D9EE78FB6FBF9B7
+:10A26000B93526F498D67EFBF909637A61FEC06F92
+:10A27000A2F643987F651CB4DBDF71EB7574BEC634
+:10A28000378F85EBBD52BBECE794B4E8EC93671EC7
+:10A29000C981468723DF4DB8B192CED7733D39CA05
+:10A2A00028EB975DE797264DC0F16D7C7CE6E7EFE4
+:10A2B0006BF119FE18C3BEBB523BFCE68915D8DF13
+:10A2C000667ECE6C884DD6674786CDF8FD7C3CFF18
+:10A2D000BF2986ECEC765C3FF67F9451FE6C77F9F3
+:10A2E000E3A57198B76E664EEEC7C97ABDF4C2A6F3
+:10A2F000BD71D0FEBD0D0AE177649EBCDE9DAEEC63
+:10A3000087310EBED0CCF1ABE59334B9DCD39C7071
+:10A310001BE9A732781BF0F85EF9EB94C79EE39730
+:10A32000FB19B831469AF7FCA6045DFC26E7C7C1C5
+:10A33000DFD4F203B68A01A1F8ADB095E7D707FEE6
+:10A3400034A17F00E65B5CC6CFCFEBF3E2A38C16B3
+:10A35000D9CFD2E5C50BF57971BD3D17FED800B157
+:10A36000AF7189FF23EC9C966FD8660A4C715F83AE
+:10A37000FF30C808A10B9DEBF5241600FEDF10FE90
+:10A38000E52073DDDD29202A5B55DF1016E6173046
+:10A39000BB8F250D08C5B7834FCBF140D171992FE5
+:10A3A000217EFC12E3C955B8A74972E0E379D0AB2E
+:10A3B000F433D6C4F46E6802BA0E3CCAC47EC7BF7A
+:10A3C000EC45BE6AF842DBCF00D7A313EECF33F2E1
+:10A3D000B71BBF3013DF6D19CEED94E6A768FB34D1
+:10A3E00037B2A6E5A50A9ECBB6AE68027C6E3A32BD
+:10A3F0002B7501F4FFC1C7B4DDC9B6146ADFA7AF7E
+:10A4000093E2CB815A1EEAB8C1975880FEBA4592B2
+:10A410006BADBEE1F8D218FCBEC885A081F8B4F1DE
+:10A420002333C3BF0FD0B0C342FB390DC7CCB4DF59
+:10A43000B26D0797132DEFACF9F96F097D7E50F8D7
+:10A44000BD0784DFB24FF82D7B84DF12107ECB2E48
+:10A45000E1B7EC107ECB1BC26E6E3A2EE46F498CD6
+:10A460009F7FC796E765B579DED1BDE98411165C9B
+:10A47000FDF180B50186F65C9693510E594E462645
+:10A48000CBFA63B83D556A5F6ACD96EA87B1EBA413
+:10A49000FA1B5AFBE9E291C1BA78A444E78F8C9188
+:10A4A000E5F26858BC4BF1B51CEFDE141EEF6622D6
+:10A4B0009D781CB8ADE931A2E3B6D359F1E17ED95C
+:10A4C0001B426EB69DE6F6F98D33E76223F96D67A0
+:10A4D000043DBE16F468167ECA4D29AEDBF30B317F
+:10A4E000AE3867C6731FEDF1B3F6BEF6DE19FFA9ED
+:10A4F000B870FBF705058D21F8DB2D9FE452FEE4D3
+:10A500002AE563592C3FE7B65989A6FBF757BAD716
+:10A51000F29BFC2CB10F51D387EF8BD60CC4F20504
+:10A52000933B15EF3F6D56DC53508FFB7E678EF8E3
+:10A53000F72496E72B9AF037A07DE04792E1E725D4
+:10A54000C588FC1525C067996739E2C78AF13A3496
+:10A55000526D6E86EBDA64620D68E7998B39EC9D7B
+:10A5600018172118E7875E9ED5F9302F25C8F78F79
+:10A57000C1BCD2F73EF068167E770B4BDC27B35890
+:10A58000F9BD83E87C4F5D7E21FF9E6D7C3FECB77B
+:10A59000249BEFA306487F4F11FD1A6276A4933DDA
+:10A5A0006D4FAFEAE25C364FBE8FA2E79706A16718
+:10A5B000DFC8744F89F41D8C3F0AFC6CFB6A9C8ACF
+:10A5C000E31658E35CFCBB902E15EF81BDF1F5E876
+:10A5D000986911F86C7FEF697FCC0FE38382608DFF
+:10A5E0002AFE4E8541CE6F190248EF0B3633C9F56E
+:10A5F000605C70C2A5FD0D3923FB79839AE4F83FB6
+:10A60000B4BF5FA7E079B3367E428220FD8FF0EFC2
+:10A61000695C899FF4FBF6C7F3B5F3929E4FF01C7B
+:10A62000B11A6FA3F3359B8E58D7A31FA9CFF71D7F
+:10A63000FE80EB71FDFC1B3F98948AFED7E6A137A4
+:10A64000A7A21C6F41054FDFEF5938C925C1B07E65
+:10A650001BEA7B26BEB355CDEB476970CD243C3F4A
+:10A66000B365186FFF49FE9127F17B605B6E13F5B0
+:10A67000BE4778BD06B3459386216C32103CA917BE
+:10A68000B487FE7EEAE93A8EFC199DEF3A81E59F98
+:10A690005076A01CD1D3F519C2C791C760DD477BA6
+:10A6A000B84E86C3893D5CA7C2E1CD6DF6A5C5163F
+:10A6B000BE7FACF1E1E1631384DDE1741FAFC5350A
+:10A6C000C55797E7FF77C1A76F0B7D7548D88F37C0
+:10A6D00085FDD88FF683E2616E3F1AC5BEF16E61CB
+:10A6E0003F768AB8371477B9857F3159C4C33C0E99
+:10A6F0002B185ACAE35EBB96E7CF30468A87C61549
+:10A70000C87EE2D87CD9AE8CEE9628F169795AAA37
+:10A710002E4ECED6C5C9B25D2931F6D7C5C98375CF
+:10A7200071B21CF716378FD6C5C913A4F6C7F31D2F
+:10A7300044D7A2E3B7EAE2E5E952BB101DE57D9BF1
+:10A7400010BD6644A4E396E2190FFEDFA263E4FDA8
+:10A750009AFFFFE8F80FCAA3CD20EDDFE8CB77849E
+:10A76000FD7F4BD88D83C20F3820F21CFB843FB78E
+:10A7700007E9D81DFD3AA7F0EBF8390E2D0FF28648
+:10A78000C8433588731C5BC4BEDB2691875A56FCD0
+:10A790003D3FC77191093ABE1B918E154ED9CF1B13
+:10A7A0009327D371942351E7F7C97EDE70BBECE7A2
+:10A7B000955A653A0E63FD757E9F4CC7A12D253ACB
+:10A7C000BF6FB4CE4EC9E738C02F78B45721DE4BE7
+:10A7D00090CF731406E5F31C7AFBAEDD57D4FC86EC
+:10A7E000363FC12BEF336F421B8AFB452966FEBD06
+:10A7F0000DA3A70BFA1D1ABEFCBDF839C42D9FDCB2
+:10A800004EF82C447B1EC17EFFA917B7FB7FEA657B
+:10A810006FBB1F19DD0FD39B3EEEFFC48FB5F373E3
+:10A82000552C88DF9FBA8CDFF4275CAFE62F19ED3B
+:10A83000350CFD08D562F0E1F777996AA573778743
+:10A84000DBF1A34EF5CAD4BEBFAA60BF9F887E9538
+:10A85000E237F9B9BC5EAECDBDF05E4FA9B305F3EA
+:10A86000E29B3F323B6B919FA3F87750F4FED6E119
+:10A870005EB9D49F863F3CFFFF0BB48FF8A158FA16
+:10A88000DEDEE73AFB090B867E5E88E6F091974FA5
+:10A890004DF2A585ECF527BD2E903DCDB57599817E
+:10A8A000F1B2B2D697C0F72B03245F7ABFAD5DFF3C
+:10A8B00057E7A79DCC7305116FDFA35D2EA47355D9
+:10A8C0002E63BFF6DF7F21DA7D17FF1E8C4BC5712B
+:10A8D000353C69F58704DD0F8BFEDAF0A2F1157EB9
+:10A8E0009F2621EC1EAC6EFE1ABE561ED91BC42339
+:10A8F0008CD7BA1E6D1D11F8C77D05BFFB7BA2AFBB
+:10A900008E7FD858A7B8A71BD9EF33093F329CFEDA
+:10A9100083695D7E6DFD6C783FBCFFA2DD5BE7FA6D
+:10A9200050BB339360AFB367821CDD7E54A5730EBA
+:10A930004CEC831BDBE859ACA09D318E505862581B
+:10A94000DE55BF9FA8CF1FE8CF9515377791E0EB75
+:10A95000CFCBE7CA5C177B5ED6AE94D986E8EC52C3
+:10A96000A9CE6E8DD1D9B5893ABB27E7C58DCCA8C4
+:10A970007D6748ECD72B0EFCFE8E916328BC5E7C75
+:10A980000788E37B793BF2DB767EB69783F0DE26A1
+:10A990001FEB9883D3CF27DD33516D1EA2F3A303A2
+:10A9A000343BE6A4B8D71C1844DFF3343BE5BFCFF3
+:10A9B000E0F75A3F2ECBC17B368CCA67BCF68FCBF3
+:10A9C000E83E4E32954F791DF47CAD378FCA27BDD6
+:10A9D0004E7AFE84B788CAC7BC2E2AEBBCE5543E2B
+:10A9E000E47553BBD5DEC904AFF27AA8CC02F706F2
+:10A9F000FFDE40968F3961C62C7B158C1786E74C9D
+:10AA00001FCC230C8F5D17DB2538BD26596A9F5A52
+:10AA1000E590EA533C79527DE7C94E09EEE82E9263
+:10AA2000DA2796BB24B883AB5C6A1FEB744B704C7F
+:10AA3000DE64A97D94C323D5EFB97E707CD365E431
+:10AA4000B9CEEB3A817858ED759FE0782A3FC1F195
+:10AA50003399CAB9BD3B107DEDC67A17DA6D7BBE5E
+:10AA60009DE1F976B395DFFBEE60B42B1DC2FAEFE2
+:10AA7000E082FEA4F9427F523CE7E7E789F3DC2756
+:10AA8000E4794F96DE0319243BA9F931C3D5B458B4
+:10AA90008CC71E34D9FFBD3FCCE381E12AC37B2B99
+:10AAA00047CA26525E04AF6CB2087AF40BE19FC627
+:10AAB000F4B652BC38FE0985E23B584905E61167F9
+:10AAC0001DCD7686FF3D28AD3CFC1BFEBDA1983D0B
+:10AAD000DB1C98171B5F3C2D312A2CFE1B1FF8B185
+:10AAE0002C85FAEB3B200AE6317EED34F38CFCD06A
+:10AAF000FAB476B39E90FDD110FFFBADC21FA775CF
+:10AB00006AFA69B57D3D3D5F9D77F97D9BB3625DD6
+:10AB10005F097FED0BE1AF9D127EF749E1777F2A58
+:10AB2000FCEEE3C2EFFE58F8DDC784DFFDA1F0D7ED
+:10AB30008E0A7FED3DE177AF147EF7EABCF5F4773E
+:10AB4000AD2E6C54987A99F3A57337C8EBAC5A279D
+:10AB5000EF1BCE7A42F6BB673E24FB6BD397CB7ECE
+:10AB6000F71D8B657FEDB61AD95F9B5225EBC75B4E
+:10AB70003CA5127CF364392F77935BDE37D4E8343D
+:10AB8000B15CD6939664D95F6B6FBD5B03A354FC35
+:10AB90003B2448CC5361F630EC7BF0D279C702BB42
+:10ABA000AB14F76B0A997B19EEE70C3504DFC7FD90
+:10ABB00026F6A14ADF816CC0370681BC5E1830766C
+:10ABC000BC23CCEEF864BC4E3D2EE7476EBD47F685
+:10ABD000832BE7C9F18CB95CF6835D69F27EEC44A6
+:10ABE0009DDD61C21E9AF9EFACCC7D793B648899FA
+:10ABF00047F795AED51E9999FEFC18B747346E9667
+:10AC0000544FF628AA0F3F273140DC53A88D1AF87D
+:10AC10000EEEDFEDF988DF2F00B407BBC1FBD733A1
+:10AC20008E6FB375247D3F6EA789DF1BD89D62733D
+:10AC30002E85AAEB2FF2FB01ACD548E7C73C786F15
+:10AC4000240BFB95CF8F15068DD2F932B3AE3E0D96
+:10AC50006DE265E7C3CFD1FDEFCD479CE3E8C3FAD2
+:10AC6000D0F988A6C8F70DDAFC381D9F6AFAA7202C
+:10AC7000C0FDA38276FDA3A9F49D31E3878CEED9B4
+:10AC80005B0C2D679EC3FB515FF23CEC3026C76D19
+:10AC9000378E95E3B6E1F6CBC76DA31C32BF8EC9E4
+:10ACA00093F5408553D60397F8354DFC1C627B7EA7
+:10ACB000CD4D7DB2B47B3A849FA89C7D317C1F939F
+:10ACC000F3CF10B1CE47CD6EBABFB23C9D119D8679
+:10ACD000D8F979C55ADCB7C1F37F1FF07B2F46E660
+:10ACE0004EEC83E5E911E2FCE25827F5D7CCE955B3
+:10ACF00004FF7ECEBAF47CA2256894BEBB61646179
+:10AD0000F485FA39C85F1D437CF47F675EE2FB0877
+:10AD10001A9FD912AEB07FE793FC40AD1C1674A900
+:10AD2000B88EFD76BE8FBA3F5813C4EF447E9FCCD9
+:10AD3000F314F7A74D30F2EFB6B86CC3812E23C4DD
+:10AD4000FA8BC43ED9162F0BA23FB7C96BA552DBB5
+:10AD5000FF5C99BC2811EDE6960C4F2A9E0BDCD2C5
+:10AD6000B1C372067A7AB3A9435AA47B048DA68133
+:10AD70006467B734A618D10F1D66B41BE97B52690E
+:10AD8000D355CCCF8EC4FB26490833DAA7DBE40DBC
+:10AD900004CBE85CA887CE11C13A4AD18F2DB34FBE
+:10ADA000A3BFF7D8F801C88503FDE30E53F1BD7DBD
+:10ADB0001DF9F96B8B9D9F6F1D91349BE855E0E465
+:10ADC000DFEF2B48B339FDD85D32FF8E4F15FCE322
+:10ADD00074E17602E45EFABECF40160623BD74F03D
+:10ADE000D37A3DA03B97B8F298383FD71479DFE685
+:10ADF00033E1576C117987E3C2AFF858F8154784EF
+:10AE00005FB15297077A5FF815FB441EE880C8E7E8
+:10AE10001D14F9BCB7845FA19DBFD6F822791573C4
+:10AE200058E2197B771AC773CA2AC55F0EEB289DB3
+:10AE3000C9E1E4C57C7FB4ABA7CE5D5280F526E7BF
+:10AE4000485847F2E4BAE1B88E94A92D744F69B21C
+:10AE5000C7EC7029783FE929BA17A5DD0BBB93A38E
+:10AE600086DD3E7304E9DF3B3DE2DCB1DA5C48FCA1
+:10AE7000F58489BE93A47D3F6EF24CF97B4AD3756D
+:10AE8000F8BD5D079B15AE47DED1E4A23FEB1F8EF8
+:10AE9000F714D136EA4E719E172F5D459097B50293
+:10AEA000EF1A5E1AAF1F1DCBD7C1F7432DA29FA388
+:10AEB000C5B7C6623F1FA4F1FE260879D0F7B75A7E
+:10AEC000EB4FDCA78916F47FB4E7E5CF9D1EF63281
+:10AED000E99CE961419FB67E4B1E34E1F7B4270738
+:10AEE0001E48477909DDAB71C5F2FB2B63FF3D13AB
+:10AEF000E8B45ADC43D0F4EACD427EF5E37DE0BD10
+:10AF0000FCFD9D0F4AA698F07BE837057EC5FF1E25
+:10AF1000B0B12639FCBCEF07383FD095F7DF743766
+:10AF2000FD1DC96006E707CB8D16077E67B06B9ADB
+:10AF30006B05E23139CD395CE447C99EFD3FEE81B6
+:10AF4000191B0080000000001F8B0800000000009B
+:10AF5000000BED7D0B7854D5B9E8DAF34E32810958
+:10AF6000049C604227E161AC04262FF260083B108C
+:10AF7000344524131221981026099068D11BAA3D4C
+:10AF8000D27B68B321218418799C6B3D50090EF85F
+:10AF900068CFB99E1AACD7D27EEA8D8AD6DEA312CC
+:10AFA0007A430B6DC5F092F66B7B2F5ED49ED3A3D4
+:10AFB0001FF7FFFFB5D6CCDE3B93800AADF634F920
+:10AFC00074B3F65E7BAD7FFD8FF53FD78E93C18F57
+:10AFD0008F314BC25E65423263CE62858D87F6A6A5
+:10AFE0009245694333185B5EDDBC98CD64EC12FE7C
+:10AFF000CC83E7CCA60D65E24BCC724981FF8799E3
+:10B00000CF361BEFE31DC37376291DFFDFCA82898C
+:10B01000703F78CB6F719C6AD6EAEF87FBDD79EAE7
+:10B02000040F8CCFEAEC67875C8C65C2EFA58CE8D7
+:10B030003CF25ACD6CF45C8EB76431F497E3339AEA
+:10B04000CFF07C6B17F339C742E323806E22BC2F0D
+:10B050009E6DB5855D385F77F05E97EA662C23D5E7
+:10B06000D2E004782AD236AF64B06E56E9F44CC30D
+:10B07000F7030BDFCECD836BE65A1F2E0FFB354354
+:10B08000BFE33776A6F96644E1DABA8D9584609E0F
+:10B09000AD697FE75D9B88FD3E6C0B613F3BABE993
+:10B0A00083F1BBE7FF2E35DD1DED7F7056E94CFFC8
+:10B0B0000418B01CFE97C2D8744728C33F63F87ABF
+:10B0C00019D3189B80F88F670CE038D3A0849D00BB
+:10B0D000574D0FE06F0C3EBFD082F71B7A9CBE6EBF
+:10B0E0000490A9EEDB609D6BF93259C3B48EFC7EEF
+:10B0F000B8AEED01BA61FFDDF6D3882F17FC227ED2
+:10B10000D35A6DA723F8C2FE4CD7C6794C6D07CE33
+:10B1100001F0DEE24F4C7EF726F8772ECBBD64E5DA
+:10B12000F447FCD688BE710D556319D2D30BC82CD9
+:10B130001ABEAE15FF6665FDE319310CCB8FDE3FFD
+:10B14000B17A4A7C08DF43BE7109BE9A453CE97377
+:10B15000CC46FA73BEAA167C05ACF912F19566D7F7
+:10B160002270C2BAD87DF628DF6518C66308EF32B0
+:10B170007D9BDE578F4D05F8570AFE5F1968E1F891
+:10B18000BA8FF3A30B6E8A71A2FC06E3044DFC4751
+:10B19000F49A28E084716E2F2BFB1F3F059C3DBE67
+:10B1A00033E336A4D3EDDFB4322BCC5705DDB05DED
+:10B1B00055A384C3D05E16B899E461997E7CB85FCC
+:10B1C0005D6D3FABA7CF3B1BA7D038ABCAF9386C3E
+:10B1D000A36E7E826F27E133C8D8168F8EDFDE4DD7
+:10B1E000675319E0F1A53DCDFBF0FD73BB9C0CF955
+:10B1F00088E1BBB391EE1CAFC7807791FFCF6F534F
+:10B20000C20700EEB37B9C04E7BB6B943043FA3378
+:10B21000CF93FD70FF017F12CD732E2EB4EF1BF084
+:10B22000BC716B825F83F5768D6BBD2708F39E4BF7
+:10B230000AD5E3388D5B6FB268D0BF2B5E7365E0D3
+:10B24000B88D56FF019862850D703A0EAEF0EFEBA7
+:10B25000E1DAD0A5A31FFC37E85788EF975858A824
+:10B26000CF3D9C7FDCD90ACD8F0877EAE05F926101
+:10B2700021788F3FE42478C764FB689C86C2383508
+:10B280006E0CD291A9B61C8027559D8C709E55409E
+:10B290003E81DFCEDCAE68881F66E374715C3F6977
+:10B2A0003FCAD33F89759E7DB06032F2F39924FE88
+:10B2B000FCB4373E8CEB3AEDE36DCDEB0E3F81B243
+:10B2C000610B652E4BE4EB50800F1A055C8D3E8BB5
+:10B2D0001A07F46D7C68F95791CE8DDE9EF5783DA6
+:10B2E00096A8252AF0FEF93D5686F8467CB872F0FD
+:10B2F0007971333E37E3E5037F06C183F81B0F788E
+:10B300007B77777B6208D6C13C2CE49818C543C391
+:10B31000CE1FDEAFCC2479D6B8BC733951986E3FBE
+:10B3200006FE5DE17368E5300E3B3C95F876858757
+:10B33000F3ADA368CB840CDECD1DE10F1FB57B7090
+:10B340007F6F14ED06E45BC0EB0A949799888F71C8
+:10B35000B3FBE17ECD6A23DF6E49DEFC6015AC7382
+:10B360004DA19D59E1F91AAFCD2037951B8C720480
+:10B37000EB36B4C767335A77D738C19F9D9C3F815E
+:10B38000D32707B3A27CD1EBB748BEF0D947C1BFE2
+:10B3900019AF5F343C9C467E057D7326CDB7AF88E0
+:10B3A000F402F00F878B5975F2D0D0E524BE67C048
+:10B3B0001E8827E04F476556945F247E1A766F22D9
+:10B3C0007E6C107CD7D803FC3346C747267CE19AB5
+:10B3D0006D729E29513EA3E731F8EC453F875BCA69
+:10B3E0005F030BD633EB70B99657A27331D0B36FAE
+:10B3F0005D8D16C0513492E31D25C56389DF053D7F
+:10B40000B8EAA11F17D22D51D2476383B89FBBC59D
+:10B4100043CF06E54419E81BABD8671DEA40B81FC7
+:10B42000EE276DB0D27DD42F36E88FD33224F8F3D7
+:10B43000054F4F87769C68BB055DAD56770AE22BBA
+:10B440009119ED9E71CCA44FFC9CAE52CFEEB4B3DB
+:10B4500014DC8FE3C4FEDEBC708A82FD762A0AD932
+:10B46000078E32231F584D7A605AB685D62FF1C009
+:10B4700084BE75B8F87AE3522C24171FA482425573
+:10B48000A2F87088F58FEBF7F5F5C3F37AAFCB1F11
+:10B49000463E621ED20FA53053BF6EDEEAC509AC30
+:10B4A0005F47E7859EF186F62DDEEB0DFDBFE29B43
+:10B4B00062787E6BE64D86E7B7F9730D6D07D3E9C9
+:10B4C00075847388E3DD21F0AC7B2EF5F200D2B1F8
+:10B4D0004AAC638723E40DC23E5CE55D4BFA7953C9
+:10B4E000C95DDE215887D3CBE5CF81F6248C1B378D
+:10B4F0006DB587EC08A19F0BE117E9D08E83A444BA
+:10B50000F9CC61C2B359FECCF6E4DA6CB07B12A080
+:10B51000F165F665B27BDCE362DA3766FB0D7484B5
+:10B5200005F9355ED06BA1D54D7A636B35D8730ABA
+:10B53000DA974BB9BD94F95F88AE41D18F6916B2E5
+:10B540005B9789F54BFBEBAD36C6FA6F007CCCE719
+:10B5500076D6B2C20BD57ABB5C5EBB453FD98E2F87
+:10B56000DCAFAA31F4694736DF371302FCF9321732
+:10B57000B3A11E92CFB764737DBC4CE8ED2520C704
+:10B58000C8B71578D5D9ADBB049FEE8AF02B1BC880
+:10B59000D1CBE9538A0DF110279AFB596857F6046D
+:10B5A000C4B3469DACEE2023F9FE08B03B9BEC18DB
+:10B5B000FA29CD5EDDFB75F447AA13FDE85B38D5AB
+:10B5C0008627BE0DF88BAF4EF05B7C517E27BF0304
+:10B5D000DAC9999CDF6B525D7E7AACA983536747C9
+:10B5E000EDB26A61DF4D60AD2407C3FC1817E7CBED
+:10B5F00091FD18BEFFC8F99C62FF67D68D7EE2BB45
+:10B6000020DFF72DF08B7C777B8D91AF968746E717
+:10B61000B31F640BFBBA8015109F85D6115F3845A8
+:10B620009F1D93815F389E883FE2257E85BD6DB763
+:10B63000B17E1BD0E908D21F8074DB5922AE734063
+:10B640007D85E4622093D9F57C100C58D5B08E8EA0
+:10B6500003452CDE03FA65C0CED27641BF31EAF253
+:10B66000451E58DF40A933B18136D5B0C16E3F02C7
+:10B67000E39E72B311ED7DB33C4C877FA01ED89A38
+:10B68000F6AE17E1D96A67B4DF3376B106E1DA2E98
+:10B69000DBDAEF6A4AB11D27DB1FEE56A1FF93F1FB
+:10B6A000BCFD61F6A5DD5A2AD18BF82A41D0234191
+:10B6B000DAEF337478053AB89273689F7199F06D38
+:10B6C000B6EBA59E30EFC3E6797F27F70341A7913C
+:10B6D000D63D0C5E60CD2F8F2E17EFA35CB8C05FF8
+:10B6E000D6CBC5F071FAC97EAF15EBB6243C9F16D8
+:10B6F0008AE14746F0BFCEFE7BBDBF00783EA4A0E6
+:10B70000DDABC2DBB319571D308E52F8DABFA3FE92
+:10B7100057766BE3108F56E8807ADECE42048F9422
+:10B72000D738E4032BE2BD9F9E83FE1D52A6E02086
+:10B73000751EE45F05FA5F42FC5CE93E59CEF5DA1E
+:10B740000AB1FF55E094305E45172B45FF3C6E4D26
+:10B75000D3816DA8E754275A1470FF4229C207CF3E
+:10B7600055275D2FA84837E06783DE79A9E44FBFEE
+:10B77000790CDEEB1CB0FA9D306E67E0C70CEDEE85
+:10B780008B33981F17DD811D01BEFA9067A1C38717
+:10B7900072D37FBC631A63A7DAD840997D38BC03A3
+:10B7A0002FC7397CB0D8909634F35918A7ABD0E99D
+:10B7B000417BEE9D8D5607D26960738386C83891B0
+:10B7C000A2F52970BFCB1662E8DF3B36B62F44FEE8
+:10B7D0003E61D7FCE3E0DAB559BB1BFD10D5B7B825
+:10B7E0003C1DE03FD0652B0FC7D89FD7E7707FE7A0
+:10B7F000AD97EEA4F51F4971F8E360DC218C6F0072
+:10B80000FD8ED877A6F971DC4DFF2D0DC73FB266CE
+:10B81000ABFF6580EBC826277A52ECC81E570D8E09
+:10B820007B646EB377AD6E7CD7F58E56BC3F30C966
+:10B83000E19842EB792FD18BEBD9983B1E79B3334A
+:10B84000C531B9099FAF6D66B85E8777A71DD7E789
+:10B85000B2B1DDB8BF7CC97BE1CD02F4977C96D94B
+:10B86000B740FFFFEA0FDD9A83FEC986530B512FC5
+:10B8700039CA92B6E0B553C029F72B49DFA19446E7
+:10B8800017EE639DAB9B781CC66B69203AA6588265
+:10B89000B81F7506D6B8A6CFE0F79BC70CC74B27D5
+:10B8A000C65D66219C6BBD6BB3B0DF876D21E83749
+:10B8B00034D759130B8FCD395C8FB9DA9B333600EF
+:10B8C000DC9D7B5C1EC44FA712DADD0078D5D2DD8B
+:10B8D000FE277CC3DFFB81784FF207D089E4707DBF
+:10B8E000CEA43D9A0DED554E47C08BCBAED39B07F2
+:10B8F0006795AECBD1ED93C3E64DE9247DD1A97018
+:10B90000B9FE414ECE1E0DC6C9F587EECB81F98E2C
+:10B910007481ACCDA2754E467B7F24F91912CF3BC2
+:10B9200037C1BA63C8FFD06A2BBB612CBF5E07D793
+:10B93000E99BAD939518F8199ADB948171AA23F0CD
+:10B94000DC02E30CED71F12BDCCF40FE1A813FF3FA
+:10B9500072B8BECF9A19ECC6F5B2197E8AF3BD99BA
+:10B960001DECA1366BF562FB0BC0BF8F7D4EF897C7
+:10B97000B149C0AFCFCCDCA3814BCA3CE30C76EB22
+:10B9800048FB67900DD9703FDE54F2A716F407BA52
+:10B99000B31C3EA72E2E28EDE825995CBF05A79D78
+:10B9A000CD839D9B55CD584BFE0DD8CB141FF4C0B5
+:10B9B0006FACF86010E3813A7DB8C4D496F6E9BF65
+:10B9C000E608FB45D8C9A9BE9DC1F9E87FBC61F571
+:10B9D00087016F69F802B42B172B61B4D73795FC38
+:10B9E00033D9F14CD8714B049CBF6C73B1B2692C44
+:10B9F000E2CFAD10F7135A4E3D8EFE7502C63F31B1
+:10BA00005EDBE2F451FC05890FF35789F549BF8EDF
+:10BA1000EC4858CF8A16110765BBB8BEB106F29143
+:10BA20001F601D06BF24C84C7EC86ABBC19FAB35D2
+:10BA3000D90F66BFA1CA6437EC40DB09ED425B9FBA
+:10BA40000BF9E9FD193947327CF458EB97F63DF4D0
+:10BA50000B150E6E19D2ED3F8342FFFCAC4D3D81BC
+:10BA6000FA684BF03117C6E1BB6D6117EA93EEF24D
+:10BA70007B1391EFBAEBACE5C86F036DE5D4EFAD86
+:10BA8000B6205D6DB95C6F54FAD58F703F91F65951
+:10BA90005579E9890E1D5D2BD5AF9CE8D0C15F516A
+:10BAA0005869684BFEAAB0B2D6BE18FB4B5EAE8C8E
+:10BAB000BBA8CC608F5A9FF28762EC17F21ACF6C4A
+:10BAC000EFEBF1382ED768F73E3063FED8D1EC1992
+:10BAD000B94E891FB97EF97C2478FF2347FA279F46
+:10BAE0000DDECC4F08AF194E09FF48FD2B70139B9C
+:10BAF00084F076ACD066201D4385B980E7AA326514
+:10BB00000BE6657E26E2953F0B24863580E7D54C13
+:10BB10001EFF8C6FE17E657C59E542DC9F3E29BDAE
+:10BB2000EF2854483EAB034A58857FDE2CFCD55F96
+:10BB30006632CA3F80BCBE9908ED5FCCB5F338329F
+:10BB40005317DF363BEAA7C6D7F1FCC40E07F3F75D
+:10BB5000E37B37BAFD9BE1FE32297F35C63C447555
+:10BB6000B5DDB0CF5498F20EF1A67D6679AEB0BBCC
+:10BB70006703DEA744F13E92FF31129F30DB853C24
+:10BB80008C8B99F1738F093F667FA7E279937C5C78
+:10BB9000A1DF73A02BEFD564B433CA14FF34A41F04
+:10BBA0003E82F7E2D583940ED921E548F87B325FD7
+:10BBB000B5636915F97B6FA13D3096F24D93315E07
+:10BBC0002DC7977E5EAE5FFD466EFEC8700C8AF78D
+:10BBD000B656C6B61306D14E98C5AFD7C175FAD2C0
+:10BBE0000569B1EC84C1226127C073B40F06F794D4
+:10BBF000F36B91D14E60E5B997C1CB265A6FDCB497
+:10BC0000BCB1B1E46E7056E8E1DC09D17642662B36
+:10BC10002BD3E1FDABD9EA3FE27A2B451C42CE079C
+:10BC2000FAFDB0DE0E33CF7728C7C3F15C3E9EF439
+:10BC300085BC5E8E7E364F2B433E7BC0AED6A0BD0C
+:10BC4000678E27FD3097DB895D196A0B3E67EE9C96
+:10BC5000CB8CBB49C6AB33B327F2F403C57D4CFE96
+:10BC6000A0F49FF6E3C3FCA85F68F370BF303EF515
+:10BC7000C2610F3C5A971B7A1EF135F74258B380C8
+:10BC8000DC39172B643F395319D93D57EC875D6177
+:10BC9000BF2E146AE0E7AD8D3C1E5F9A6DA3767CE3
+:10BCA000C87A80F605531C275E7D8FFCB02560079F
+:10BCB00088B80DD953C7853D1564ADE4EFB9ED6182
+:10BCC00017C62BCC719B9A544BFF74D0EB3585175C
+:10BCD000AA7D33E97D43DCA7C69771788278EE812F
+:10BCE000EB92208F032DC338108E5F1DEECAC03C2F
+:10BCF0009CDFE65719F7F3D0BE58DE747FD6C3BE7B
+:10BD0000AB170792F125692F4A7B06F44BD778A42D
+:10BD1000CB02C547BEBF294E648E0BC9B88C397E95
+:10BD2000648E177D9C9B4EF490F6978CFF7C946BF1
+:10BD3000B4C3AC3037F6EB2E822D15E4BBDBCED28C
+:10BD400076CEE0F11DB4978E94FEC483F68535CF90
+:10BD500014E7BCC2FDAD13F6A133B8AFBE126747FE
+:10BD60007B3BE80D513C7189629493C9797C9FF3C8
+:10BD7000E4B9F93C228FDCD9B641BEAFA1BE09A619
+:10BD80003AC2714A741C56987F45F2949CAD4ECAD3
+:10BD9000CB277F2415AFCC0FFE4816FA231ECEDF2B
+:10BDA0008513683D4C9DC0CEE8F3C602EE081C2EFC
+:10BDB000F05BB23EF9FC2988E7FCE83C97C3DB8ED8
+:10BDC00092629703E31140632BE72B4F247E9F8100
+:10BDD000719D753EBD5D518F798B5CB43B795E433F
+:10BDE000DED7C5CF6DC8BFF1A9213518635F5D955A
+:10BDF0006731E44F23F1F74C46F922398E8D7937BC
+:10BE0000911CA0AC4A78AC31E2F402DED5420E00BF
+:10BE1000E12E27B04CD34E2BE375095C4E643EC235
+:10BE200056142C4F87F5366D53286FCCB49AC368DF
+:10BE3000DFAF11CF1D22FE66CE23AD117918665DEE
+:10BE40004776DAEA878CF9B5C61E63DB6C97CB7848
+:10BE5000BF0D8044B8DB249D40C15B47C7C37E5AF9
+:10BE6000E75F291E241F2ECEFDAA17EB5A3AE342A4
+:10BE7000BB1B30AFDDEBA27808F990282FFDF00B4B
+:10BE8000EBD9B6B7F0315CCFF63C2B977B85D7B9B1
+:10BE90001C4E79D835A4E3B7ED82CF66E5F978DC9E
+:10BEA00005F72550892C3599E448D6B51C49E1762B
+:10BEB000A523C0EDC6A7A6BEBC94E75D797D4B6601
+:10BEC000205ADF520AF8C912F8C99CB6DADF0FD738
+:10BED000AC00AF4B9AF1ACD15FBD35D36857669AD1
+:10BEE000FD5553FB405EECBA96689E4DC4DD05FCE3
+:10BEF00066B9FA5E1BCFB7FC33F8AD787DAACD43A7
+:10BF0000D7EFB779E9DAD7E6233BED99B64CBA4AD1
+:10BF1000BC3F600FD6635E4BC621657CBC3F8FFB88
+:10BF20006F2CC0E1A8106B59684D4D443C1F0D703B
+:10BF3000BB70A4FDA5AADC1807BD3D68CCEF2DAFF2
+:10BF400031E6F7EE9BA9BE9407F024CCF4DA43BAAD
+:10BF50007CD41AB1FE1D0FF37C931CFFE83739DD4A
+:10BF600065FB9C58FFCF045F24BC9C62F701B12A9B
+:10BF70001FAABC19E3F6CC937345F6E02F855C2627
+:10BF80006CF6D8312E54D9BFC281E3ACD90DE3B8D9
+:10BF9000AF7C9CAD6913D38CF985AFDD81701C8DAE
+:10BFA000E4175AEFC0FCC251915FF843DEBDDF4198
+:10BFB0003F6B569E7A1AF5862B4F3D83F8F883D057
+:10BFC0009BD03EA76FC3CFEB4913478DE3FF212FD3
+:10BFD0007F781CDFBA40698D55D7F2A19017D05BEE
+:10BFE00017711EE68AC4D13EE06DAE8FE2F2397E53
+:10BFF000DA7FC95A709CF61FB3966762D8F32C5F3C
+:10C000009171B98F490F7AA51E0C5E8A359ED5595C
+:10C010003919F17DCECEEB62CCE3C5E53B247CCE75
+:10C020007C7C3F35025F5C7E7E74BC1D808301A4F6
+:10C0300093CD9348794D7637E53F251F25D47B6E08
+:10C04000C3BA05702C19EE2F09CF796ECBC338CE49
+:10C05000CFA7F89F6023D3F5B782BFCE0BF93A87FD
+:10C06000F205727446C8D729942FB89E14F2F5EBE6
+:10C07000363FB57FD95648EDE36D2AB57FDE564E83
+:10C08000D7C1B620DDFF595B0DB53BDB42743D5A8D
+:10C09000F6D8CDB8EF7CF03D85F4F148F0DCF5B88A
+:10C0A000D5203F2D7B130CF2B6F6A1F186F6EA1EE1
+:10C0B00063FEBCB1638AA1BD6A83317FBEB2D598ED
+:10C0C0003FAF6D9963986F456881499E6F35C97B15
+:10C0D00095A1BD309FDB8955E5B586F79CDE4643CB
+:10C0E000BF84A52C148BFEB7E5F3B8C9CB25C56377
+:10C0F000874689733836DCFA36DA2791B62DC4D0F4
+:10C100009E776C5842F71F88E3FB9DF9BD26C1AFAF
+:10C110009D65AB83F319DA458BAC7ABBE79E59A1D9
+:10C12000E5F93A7FD0E1E5FED8C5A9D5562FF0D183
+:10C13000D2B2F75EBD0EF82834C0C8EF51C1DCF3AF
+:10C14000821D5CD8BA6BC175D0AED6D61BFCC7E2D7
+:10C150009683AF80F8B240D9D1F664783F3F3BD4A4
+:10C1600084E397782FBC82EFCF5F9C6D43367F20AE
+:10C1700089913D7A2ECD113E10831FEE1770CBFCB6
+:10C18000D527DDA7CD79FA8C4C568A71E48CCC0B7F
+:10C19000A5A8D7A0AD62FEEBE0ACD0FD081FDC5730
+:10C1A000514F3E90B53603F79391F2468FE41BE36F
+:10C1B0000912AE1D251C9EA322BF3064CA2FE8E2DF
+:10C1C00009EDF9A3C413CE89F786BE1D3B9E704EC0
+:10C1D000E41DCEC9BCC3C35531F30EE7168A7802FD
+:10C1E0003CC738C2B93D35FCBA70F4BC835C1FEC67
+:10C1F000477BF20D790761E78BB8F9E02C752F3E8C
+:10C20000FF6AB6DA8BD73F66A9FB108F4775F94FE7
+:10C21000CF445DFEB3EC2786FCE7A19CD093F93CAC
+:10C220006FCDD0AF6AD7D850DC14CCC706EF89C524
+:10C23000C7CFE4CBF862FF67CACFEAF2A8964B37C4
+:10C24000B12BCE035C71BF425E9762B66F121023B2
+:10C25000E3A276DFD379A19F20DE3A929EF3F1FA32
+:10C260002B4B74FF40E537823D649E4F8E87FA0A60
+:10C27000F5D620480CEE33DB932ED4A19F724CD020
+:10C28000D37C3D9E2FE8C93CC948DFA7F382BF207D
+:10C29000FDF36C9F8FEADAC4FD2B85E34947F06D0F
+:10C2A000B4633B1BADBE03DC6EA7B8C50D81A470A3
+:10C2B000B72E1F7C11F7CB7C8C3F0E4D7500BDDB7C
+:10C2C00043AFB8B11EFC9DBD36AC8861DF4DD4ECE8
+:10C2D00048FF9A4CBEBFCDF786BE34348A9C033FDC
+:10C2E0008CB778090E8BA590CFCAAF9A825773FF8F
+:10C2F00081BDEF4FF0C178DFEDE5F9AF1B7A57BB99
+:10C300001A75E3DF305BEC97C83379989F54C258B5
+:10C31000A85E1378EFCD02CCAFF82C14E77867E372
+:10C3200007C79663DC51B552DCF19D8D17A97DDC02
+:10C3300067C945F2BDE3FD7FC7B0FF0DDF5C3391F8
+:10C34000FB2D1C1FAB36E63ED99D4E7931C76C984C
+:10C35000E7B87A3171CA8C68FE6C95C282B1EC98EC
+:10C36000C9B339FF2F525BEF40B816859C0CEB9C8C
+:10C370008F376C7D1BDBDF2D557C56F4EB33F93C9E
+:10C38000357B6D544F0BF85987ED37FC090CE79D51
+:10C390001F3A68C3FE1F6629EC3AE52AE255BD380C
+:10C3A00001E5F01DE4BF18F05F94F22BE468BA0DCC
+:10C3B000E43E07F17FD8AD8F534A7ED2F2D4CCD978
+:10C3C00014F70BB504C9CE5D7A19FB7433AFD3FEF5
+:10C3D000DE051BE61EE21F6F9D84F1A561708E00D5
+:10C3E0005F91A0FB1FF3791CF3865EDB9B5F417EB0
+:10C3F000DE68A73A845979C139B3F5FED655DE37E0
+:10C4000064FDDA40213F8F00E634CD03F066DA00A8
+:10C410008E3825DEAF71B9A2F89C4BEC7FD04F1D52
+:10C420000BFD56B1BE7E8CF3319BBAD38AF1C32289
+:10C430003BF9C7CB57DA13912ED17C99DFE06F9887
+:10C44000AF67303F46751A2EBA0E809F8DF912FCE9
+:10C45000014B1C1EDA84DDEF7F449D0A722FEA4AED
+:10C46000EF3F74EB2358577ACCC2DB771DBAF5FA4D
+:10C47000CDB0A433935B8FDD0EEBEADEA5F837F980
+:10C48000F0BA7F77239EAFD8A0F8CBA16B7DFF8D4C
+:10C49000F598626CEE72928D7F7ADBFD3723BF5E7A
+:10C4A000F4320FF2F3F214CECF4D832C6C81F62DC3
+:10C4B0003DBB28EF191CB451DD9ACCCB9E4CE179E1
+:10C4C000D97F68EB27B8D1AF5D389BBBD8F833CEA6
+:10C4D0000F70601CB5CC46F9D2F1CCD389FB4BBCB4
+:10C4E0009A5ECAED698F83F23C8B19FB0EC67936D2
+:10C4F00070BFB948D445CA3C163BCBFDDB16F845A6
+:10C500007D32BEDCE81FE79BFC5FA9DFCCF916E0BB
+:10C510007F0DEF77CE4E34C4EB468ADBCBEBB360B6
+:10C5200047E0FA9E1379DC4360AF633EF3C760AF28
+:10C53000E3F579B0D7F1FE8B60AFE3B51FEC75BCC6
+:10C54000BE0CF63A5E0F83BD8ED7D7C05EC7EBEB4D
+:10C5500060AFE37BFF0BEC75BCBE01F63ADE7F7685
+:10C560002EDFFF3AA739C29B01DE4E3BFB35F29529
+:10C57000562AF2C2224FB62D693AEDEFAE8F80CB2C
+:10C58000C19E1A504277213DB43417F51B48BCF0C8
+:10C590001FFF17DBDBD2C90F6136DFA12178AFE3C4
+:10C5A0001BE9FE6E68763918E9FB53479947017B12
+:10C5B000E6FCEDCA4C8CA39EB94DE9C3F6C06D0AEA
+:10C5C000D913D351F472A2FB68F1FBBE03B89FB537
+:10C5D0002732C18F4FF6AAC07FE71136E4572DA945
+:10C5E0001EFDD2794ED91E538FCF1B3728C24F1D47
+:10C5F000B74F85356C53E4FBA9BDD8BF43BE2FDAD6
+:10C600008316F9FEBABDE8271F8BCCB7BA564D8505
+:10C6100076867CBEB60EC73F15A9AB9BB712DF1F4F
+:10C62000888C3FBB17DF3F9326C7BFB396DA76D916
+:10C63000FEA795D49EC0FBCF7AE1BA47B16EE56AFA
+:10C640008FD71EE2FB1FEC63AA3E9FB3A9D84AFB1B
+:10C650009EAE1E9CE26E32CF6F49704FBB9278A99E
+:10C660002ECF4FF15298CF8E72F6F5D2A4C9A8778B
+:10C670004FA5F963FA29E5C591FA5663FC5455783C
+:10C68000BDBD8785B03E3E5EDC8FEFE175F48E4C1C
+:10C69000DBB03AFA2B8927CABA07194FAC593D7A51
+:10C6A0003CB1A6D4184F5C259E8F144F5C658A2739
+:10C6B000AED868CA43843E593CB18EF5DBD10F63D6
+:10C6C000AA427254E7E97B7522FAFB677D144F6436
+:10C6D000BED729DE2ACF4FE0FF2DB3F1BC196F9FE3
+:10C6E000BF5BF1A25FD17DB73211AF27EF5626A114
+:10C6F0007C9DBD5BF1A0BC7D589041F8CFFF8DFFC4
+:10C70000751FEEB75E8B9FA323F802A62A82AB9318
+:10C710007CDD30CEA9BB9571F8FECAFBD21DC80FD7
+:10C7200060770A7EB4EE45FEB426288676DE64C9BC
+:10C730008FE147503EE68D176D6DF95E949F5287ED
+:10C740007C7F33B5578414D1FFEB7B51BF1C9B2FEB
+:10C75000FB4FACC3E7B74F91E31D20799C9720DBDB
+:10C76000BB49FEBA22E37DFF11ECFF0BD490D4DE6F
+:10C77000B917E5BDB452E8336D268DDF5927C7FFE1
+:10C780005A2FC6AD6A2DF2FDC524FF4D4CB6C17EB1
+:10C7900087F6AFC4FE70D70F3FAEC5B8D61DF2B94D
+:10C7A000F6F123084F9D68AF2BF897BDF8FCAF7EDC
+:10C7B0007D7FE6F9CCED956C60E1757951B930EF8C
+:10C7C0002B0D45DCDF296C3988EA8BD5B5EEB7A295
+:10C7D0003C46F36A29D541E46F9795EAE7825E7695
+:10C7E00073AC7AFE4B057C9C8D05579A5F8B3DCED2
+:10C7F000DA22BECF75CD6731FDDC83B3E66F2DC87D
+:10C800008FDA0D68223AE05A02570B5C3FCE0A3DA0
+:10C8100088CF91D618879171ED25A29E7853C9775C
+:10C8200082F3F1FC5291DD2FC2E103FA7CAF4D9C03
+:10C8300073AD9DCFEBBC42DD4EF2D7AABB441D8940
+:10C84000D54DF908DBF58EFD943713F9D410D61DBC
+:10C8500067505DD7A8E73B6CA63C6A97586F69F6AE
+:10C86000FB94A76E7A83D70BCB3C76BD80AB09F5E2
+:10C8700032C0DDB85A095BE0BD46543C98D7CD6460
+:10C88000615F7A34AFBCA2CCD6EFC07361E27C06A4
+:10C8900013F670241F5EEDEBC3FA189B1AE757716D
+:10C8A0001ED61FA4BA38CC17A5B348FE59EA91CAC0
+:10C8B000E6EBEEC63CB54E6F519E3A9E0DD31BA4DF
+:10C8C0001722754D228F1EA9CF117A40E6A71BC4EF
+:10C8D000BA9645F4C0E22568E7C63F20F2D422FFAD
+:10C8E0002CF3D495A6736D8D810563289EEBB7F963
+:10C8F000A9AC26D5789E29DE44879B8AF9B94A9946
+:10C90000A73E5A60CC373F6067A477BB328C7CB7B8
+:10C91000A098E743FCC5320E19DF1F87F6377391E5
+:10C920001FD28DF19CB1DC1FA1C35CA6B88E6D43F4
+:10C930002DC51FF1B9027CA864BEF6EFA897B15DC2
+:10C940000CFD6D78BE05E9E1B6903F2AE33F68A68D
+:10C950002CCCA138D079E467DB867A1A479E677FB2
+:10C96000323EB67C5C2C9079D63E3BF6ABF5BE767B
+:10C970001CE7FBCC7120E18745EC181FAF7F995471
+:10C98000E09376899D9FF763F6A559142FF9B800B7
+:10C99000EFCFE8F3211C725FBAA3E839DAC7AE3CE7
+:10C9A0000FCEDF5BFBA3976AB5E491F3183705223E
+:10C9B000790737A6C059B2CC3BA889D88EEA595816
+:10C9C00048A141CFD6B5FC27D0B351BB3FA30E9FA2
+:10C9D0007FD1E0077EBAA590EAA778FCED8B06FF31
+:10C9E0001BF96A3DF2E1B59EE7C5FCE03A9C67ABF6
+:10C9F000A2D6B8E95C0CF32BA3E70BEFC5FEE67CEF
+:10CA0000E1E5E2187F8B5B8C1EB7E82D34E6F53F3D
+:10CA10002F718B7F04DCE13E09F27490E429C0E5BC
+:10CA2000E9AF7DFF83F51EC1F56E55FAC2F1D6ABB5
+:10CA30001F37783A2FF46B94A3E9A9AE06B4676068
+:10CA40001E1FCA5F341E0270171AE2217B5BAE41C3
+:10CA50003C04D6F97BD27F659CAE7F05747314E1EC
+:10CA60007A546E47FC15F26506ADAF8FAFEF2F30ED
+:10CA70007F4E11EE034F717E89E287DB493AFCD489
+:10CA8000B5FC65F07333C17788C3F705A0671DD186
+:10CA9000D3CFE1BD9CFFBDBE80FB17F05E13BD97F9
+:10CAA000C7F9E05E6157835FBEE03A5FD42F4FCE97
+:10CAB000569B8BB89D7B6791A1CE54BDAB6874BF6C
+:10CAC000F99EA2D1FDE6FBF0FD2F8ADFBCBF80DB23
+:10CAD000FBD1BC4DD8C53FBED142F9E57AD1B77B79
+:10CAE00043D5A21BB1AE06F08F6D27AEC7AA5B4F30
+:10CAF0009A8DFBDBA6F36AF27B07725D366BDDD89D
+:10CB00007E5F149F6F8D6975E079A86635A913CF94
+:10CB1000DD2EE8788FEA061DAAD3877EE197BCBE9A
+:10CB20004ECCCB56A97CFD8E160F9DEF93E7DDE42E
+:10CB30003994E6FE1B5F73E0B939F05F5260FC8AFE
+:10CB400032FB69FDBA9DA6732936537BC3AFD3B7B9
+:10CB50001FD6F57FAAC8544F687DAA9CBED3D1A129
+:10CB600078449D2FD565348B313695DCB108E39739
+:10CB700060C7F9100F0B76EE1AC07C9AA3C34AB9AE
+:10CB8000F33FB6F9B61F06918AEBB552BCE1830DAF
+:10CB90000AFFDEC7629EC76F12797C668A33C87847
+:10CBA000B8C463DC83BCFEC35178AA8CCE37D6AD43
+:10CBB00019C8E7BC43F1061B878CC9EF6F540ABE46
+:10CBC000AA0FBCD781EF2DF35A0CF543E678848D7C
+:10CBD00099EBE4791DA74DE5759CB64C5E271FCFF8
+:10CBE00054FA5E47FC962AA267A5CAEB38C14812E0
+:10CBF000DFDDE274A908ACA73A1F731CC159688C29
+:10CC00004398F9D24C8F93267A3C61E3E7933A0735
+:10CC1000AD7E0D6E773EB4BA0BE3E7DA43168A6356
+:10CC20009C95F5210024C6F397B3087EC95EEE6C8F
+:10CC3000E5F502922ECB77F2BA11EA6588DBA732CE
+:10CC4000FD773C968BB8C21DAC8FCE3BAC6443766F
+:10CC5000948355184AB7623CC647D726A66D6184AF
+:10CC6000BF50573ACCF744EB783FC6B5FB27D99372
+:10CC7000DECDE47E442CFB359AAFB5B1777571FEFD
+:10CC8000BFC5B53E695CCBAAD1F952AF233C4DB9C3
+:10CC90007C5CEB88C84BC8B8D6D99DE27B1BE2BC54
+:10CCA000C580BD75F24E37F6F3919E19B377F92220
+:10CCB000E48323BD3FF188F3AF1B278EFE5D88829E
+:10CCC000E218F5A43F2F60345E67FA109DA33E6919
+:10CCD00037D6E5CAEBED0159BF19528B75F631F322
+:10CCE00044EA38E717D346C0CF6BCB38D3BADCD091
+:10CCF0002D787FEE05C10F8B95B002EBAD702BAF99
+:10CD00002ABEE8FCCC5C47FFB77C18C11D87F80140
+:10CD10003C0EC4F1BADA817456F34C0CFADC389745
+:10CD2000EBD181ECD8F493CFC13EB9BF7802F79F25
+:10CD3000C6F0B8C2EF1DA3C715BE551C23AE20E92F
+:10CD40007B709EAA71BAF3B62727D489FDDB4341D5
+:10CD5000AAD739DF63F56D42FCF7B7BE5508ED255C
+:10CD6000DFB27A301F7EADF37C930AD289AF2E9763
+:10CD7000E7FB50E0F764A4AEFB5B944FEF8EF867DF
+:10CD8000DC7EAC1DA76BC3965C3CC8FBBF585CBC8B
+:10CD90000FCFD98F646FDE1758D58BFE9CB437A1A7
+:10CDA000BD12DBF27D9084C9A5A0349B5A643EB1CC
+:10CDB00082F2F5D1F956EC43FBF8ACDD38BEB4573E
+:10CDC000078ACBF7A1BD1A8CCC5FBE0FEDD953A655
+:10CDD000FEF47D4A18EFD7C565D4BF91C9F1CBEAFF
+:10CDE000B17F24AEC8D6933F7ACC21DBF7D4A33DE4
+:10CDF000BE3D9D8F371858DFAB7D0EE1B9D6E37F7E
+:10CE0000D2FE23D9FD27EDBC7E50033BED89742C67
+:10CE1000A3ECB372E1531D78C6AE5855683FFA9340
+:10CE2000888307DD16E1E76CEC45BFA7B644F2E95D
+:10CE3000E354073212DFAD7FFE478F68FA756A3F11
+:10CE4000AA35C0ADB5529D8884FB04F68775D4DE43
+:10CE500073A717E1AC95F10DD6D98BEBEB4C92EFA4
+:10CE6000DDB40FDB23CDBBE6F99DBD88EFDAC83C0E
+:10CE7000DFA6F76BE3E578BDD48EE2F300C54BA2E5
+:10CE800070B518E07A2D70A017E10A7AC25B707F46
+:10CE9000087A19EDC777B46CA2FAEE881C693BD208
+:10CEA0004A510EBD9136C757448EEE2739BADA7013
+:10CEB000C17E9A3E07F7BF4CEE275EFD75C33E89E3
+:10CEC000EBEEE17A48F2519D478E03F8077DD2E4FC
+:10CED00093EDAFD5B7B8AFC6BCDCDF0DFE9E917D3C
+:10CEE0002BE58969AB4DF27365E3B5BBBF4675149D
+:10CEF000CDA0D763D563DF5B10D14FB7123E0BA532
+:10CF0000FFCCA4DD5181F72376872F627754CE8939
+:10CF1000617774629DD52CAAE722BDA9C213AFAE7A
+:10CF20000E68C65C9E076C177592799BD95ABDBF77
+:10CF3000FDFD79DC9F7F6A1E874B7EDFF6CC3A854C
+:10CF4000EAC4DA7BA68CC1F36EA7537DDB51AF0D2B
+:10CF5000A45BE83B0527C5F73507BEE14CBB0FEEE8
+:10CF60001F4F73F9515F1D4FDA49DF513BEDB70A8F
+:10CF7000FE3CF40EEEF3BAB8A2867A45C60DEF9EDB
+:10CF8000B3F55194A3133EDE2E9CF7E377509E59E0
+:10CF9000A6F97C6780EC18C7CDB08DE0BBE2FB9CA6
+:10CFA000C5E279E5B61F7CBB0AC710F68BD49FE6B5
+:10CFB000F39EF863D7DB5F5D566E7F79793F2F1B59
+:10CFC000DA74C982E3F2B66B84EFC2D6C8F3CB261B
+:10CFD0007BAAD2743E9989EFA04A7BBC38B9D18F25
+:10CFE0007E5CF13AA37D74BAEB959E42F46BFD56DC
+:10CFF0000F6E93B7661A9F4B3B6C51D763E48F82D9
+:10D000005D689847D6DFDECAFA3AE85CB8EFF5C348
+:10D01000D68951BFA5DD5349764A7326B4603DC712
+:10D02000FEBE34311FED831E2B7E1196D7DEEBD66C
+:10D0300001FDEC9664DAA7FD8AA2AF0BDAF228CAEA
+:10D0400045B42E88B7A3F1F8BF7FD45047C7BEB60A
+:10D05000CA10E7D46A1FA53A3E1917D3AAE9F919ED
+:10D060009B8883694D8FE27E16899369BFEA35C438
+:10D07000C9B4203D0F46F6BF5DFBB0BDCC23E0D167
+:10D080004EF622BFB5AB5C9FBC34C77D52B37DF278
+:10D09000FE209FFF730EC6B7827CBF333F2F1E0C4E
+:10D0A000B78F11761DD68B9BE57C5C80D7DF95A969
+:10D0B000D91D137C3C7EE504FAA82BAD2B316E10F4
+:10D0C000AD5729A2EFA4358D505FB224C0E5F7E833
+:10D0D0001CB7C12F37D7A934893A9591C6B9B38403
+:10D0E000E7D907144F35D7CB56867AB974D714379A
+:10D0F000E6A664BF9B4BF83EF071967A12D76F8E0E
+:10D10000A79DC5781AC9198F7B2C15BC63DBC9BFD5
+:10D11000572FBF677226C9EDDF0CF797F688784561
+:10D12000F9678B9FBD37C7784E7FA4FA87D212BEAE
+:10D130009F1589F57ED6FA8727E35515F135047DCD
+:10D14000313E38AC1E42D439C83A88B1810C5EB742
+:10D15000C1783D44BBD64AF8BBEAE75CC4FE0F7C0D
+:10D160009A1C403EADE17A44F2D94FE7F838FFFD12
+:10D17000C64FFC27F90EFA4F0AA01EA9E6FD8B7FC9
+:10D18000C3BF7B21ED8B718133BD9BA6921EF2053F
+:10D19000F4FEAF3B722E322310430F1D5DA04E0DE7
+:10D1A000E8FC23783F33901FF3FD2F13BCA6F7B3A1
+:10D1B0006606B3E8FDC8794E7566E06F7510A03D50
+:10D1C000CC75277CBF30D79D487BF0CE92DFAFC4B3
+:10D1D000BA934BF3D5651CCF1CBF11BB7288DB39EA
+:10D1E000517B3287F6C36B602F36133D453DCD35FD
+:10D1F00018FF5EFDF8D27E82FB7FA7BFFF79F3DFC9
+:10D2000000BE6E824FE44D3EC5FBFF40EF8B7CCDF0
+:10D210009F01DE30F191B0FB3F87F87CF6730EDFA3
+:10D22000EB44AFC59CDE657398DCB7FF35361F5CF9
+:10D2300031FFFF6F7A5FE4CD75E3FE5C3FDF48FEB0
+:10D2400039F4FB15E16DF130F93919D0E5E347798F
+:10D25000FF8C7E7EDDFBEFEAF9F32AC8F9053D7D00
+:10D26000AFC13EF2118D3F958FFFBBE2C83A2EE968
+:10D27000EFFF2D4E76593E9F3617F1D5CAF9E90AD0
+:10D28000ECEB9BE6F2FA96108FCF6A927F678AFBEF
+:10D2900043789E74F91C26BE8F12CCC6FB2AE3FE8F
+:10D2A0006DC41FD17AF719FD1118688641CFEFD3ED
+:10D2B000FB1BE5739FD88774B72EE0FDE7BE306E89
+:10D2C00015E2DFDC067B64DE5C635DA68AEDCB8D58
+:10D2D0008BF97F7ACF94FFD73D5F44CFA3F50B64E2
+:10D2E000BF82DDE672028D7F51674D6E8476B5F0A8
+:10D2F000DBC1FE8879AEBB3A1AE7AE9EABABC7186E
+:10D300000C5AE97C60C44E61EE4711FF113B4AFBA9
+:10D31000FE3EE3B98D8314E72A11F46D7EE1D97ADC
+:10D3200001E72AC4374B16EBB87CFF35D4DFCBFBC3
+:10D33000C7787E273D4FE57032F7EB67ADBA7C18B2
+:10D340004A9A05F3BCF82F1FC06FBF7D6E32D82BF1
+:10D350002F77293E2BB41BF74A7E7A81E44157F799
+:10D3600041F2B742F0FBD6170ED7233FAF785FC22A
+:10D37000EBE4EB8FD4311DA6F59F10F188092F4205
+:10D380007FCEBFDF24F87C1CBE6B30FE36A213E3D9
+:10D39000F8A9619A7DE2287516BB04FDE1BD9D04E4
+:10D3A000978BC3551352C85E0FAE06890638EA073D
+:10D3B00059CC38D3EEB90EB98FEDA679DDC28FF511
+:10D3C000C73E2FBB2FCA4FFBA8BF87CFE702FD8FF9
+:10D3D000ED40E8E802FC0E448DF8DE784D998DBEF4
+:10D3E000B750537861A98883507E53E6C14B1F9C88
+:10D3F0004AF9CDF8B238EE2FBA8C7FC722D8E4A410
+:10D40000EFC9C9EFD6CABA8C4A66FCBE5C8CFC96E2
+:10D4100021DE22E32291EFC95953C9BF753C2AFE90
+:10D42000FE93E9FB71F11B18C5B79C1DFC1CB839B4
+:10D430004FD5B0B1F5AD22ACFBB0D9292F6BCE677B
+:10D440009AFF1EC63C1753C7E4503DCA6B73F3A343
+:10D450007528E7F74E71A31C9AFDE7F323F9CF7BFC
+:10D460008DFEF380F49FD5ABE33F9F986BF49F1F35
+:10D47000CF0DFE8AF8CAA6D2FEF67249F1528C236D
+:10D480005C147514A71E4A5E82F128AD879F573839
+:10D490002DF2FC32DF7FAA88B93D78DDE2247C9E44
+:10D4A0005A9314C62D784C47F362FCAEA0F4A31136
+:10D4B000F318FFAA10EB34FBDBF18540CF5924664B
+:10D4C000E4679FF278282F50D125BE2F21EA05A4CA
+:10D4D0009F5D21CEF13795F173D518B1437E90DF72
+:10D4E0000FAC107EB8F4C7FB7FCA147D1DC052E696
+:10D4F00027FEAD06C6C0EB32F13DC51A0FDB8240F8
+:10D50000FD312BC44A102F7B399FB0ED36FA3B57C3
+:10D51000A77A76D1BE3AD2390677893CC7A0517E28
+:10D52000F61AF8F9490497D83FAE60BFB98EFADB16
+:10D53000B81C6FC3F3BFF9D1EF4AC873F3DB93781C
+:10D540001C654609DF6FCC57F9DD884FAA3F407F45
+:10D55000DE5082EF47FDF94C84E70AF4E74C825B2A
+:10D560007CB76232E681F8FAB34B783ED73786272C
+:10D5700071BB1CA3D70114968C92CF6597AF235033
+:10D5800063BDFFA1B0B3D7E5861696F07C3FF1AD41
+:10D5900039DF2FFB1DC3F8548CFD76838853950229
+:10D5A0008B5A72869FE7FF459B7A126DBC636DE5CF
+:10D5B000743D6ED312B17EEB2D719E1F0C2DAA67A8
+:10D5C00092755172DC9ABAD2936775FB59C5C2C77E
+:10D5D000A9CEAC3DF3C0EB0AC0795AD47B0D24FA36
+:10D5E000689FD38EF2EF4B2DABFECAC9B3BAFDC311
+:10D5F0000C2FD6456920EAEB4BF877CB5E2975F600
+:10D60000CFCBC3EF3571395CDD738ACEC3D46F687D
+:10D6100060A12CAA9BB2217DDF9EC3BFBF50516881
+:10D62000659A0EAEE46CF5AE121EF759477C12AD4A
+:10D630000BBC1BDBA576750CFEFD49199F94F98286
+:10D640009B5FFC3F94771B4862347FD0CBC29877B6
+:10D650005FA0AE770C61DEC5EBA3F8C8DA121FCD70
+:10D66000DBD8B59FE0890FBC47F0806DDD8FF58377
+:10D67000667C4BB9E814F8D6AD9BF03D92FC562C75
+:10D68000B425227EDF427A41BF07C53E70C476C111
+:10D69000ED8941F7C87B85A5067C3BBDE506BAB59B
+:10D6A000ABF78EC1F5483A378A67E7BBAC6F221DEE
+:10D6B000DF073A32A263EC3A88A348AF1B806F4C75
+:10D6C000F4AAEFE0DFBDAEEF28A5EFC5D5177EC504
+:10D6D00091427900A50FCF4B36953530B4A71D6A1E
+:10D6E000127DDF4ED26F6919D04F072FC8E3632434
+:10D6F000A7C2EEFC14F1F5FF5EA2B383AF75FC1F69
+:10D70000E6FB51490CBBFCCF957F18FE3D1FBEEFD9
+:10D710009E12FC62BECA7D77C4FA662DB8AAE55394
+:10D72000C021E506E5769382F5938A1DF92C88F2EF
+:10D730008BE7D70A7FBB05F3A1CD5ED6877BE13EA1
+:10D740009423C09BA33CDD81F2D3B8379DF802FD42
+:10D750007FC2A7D8A7DFC47D5AF8FF74BF85F3C581
+:10D760005F3AEF03F0FC1BC15327CE177CCEF25279
+:10D77000C9E541F73CC05B50DD4FFAE5A742DEE06A
+:10D78000278D7FB7E993E5418B555E3726F3A131AD
+:10D79000F29F3EE553E43FCD79D591F2A131F29F5E
+:10D7A000067B7DA4FC2733E549CDF9CF455D5328A1
+:10D7B000FFBC28D342DFA99676BFCC7BBED1F50350
+:10D7C0001B7D176986C292D287E747BF2DF431438C
+:10D7D000AB4EB7FEE369FCFBD7DD292EFABBABF8F5
+:10D7E00083F558129FA01F5C4E98B76321AFCBAC56
+:10D7F0004C7FC68C5787F04BAE08AF32BFEEE85275
+:10D80000C29B9135BC2C52FFE7D0D1D991F91CD1E4
+:10D8100091D9FADDF83DEE46FF78AA2733D3A1B8B7
+:10D820008BFF5DCA62CF6CFABB9492FEC5DEE175D8
+:10D830008336095F8CBAC13F3B3D7D9B5D19A3D008
+:10D8400053E6B147A2E3ACBCE0BDF32644BFDF24FE
+:10D85000EF1F4FE3F83D7323137FFFD4484FC0BF42
+:10D860004AE7FA33D9FECDCA707E2816F598C599D5
+:10D87000DA7AAA838F5FECC5BC5904BFA98708BFB9
+:10D88000EDADBEEDE81F1D2DB353BD4A0C7EA0BF0C
+:10D890006F7B397E1846F79E4F47BFDAA22716A442
+:10D8A000C7E08F4F4DD7CBD0D3617DAAABD0174BFC
+:10D8B0004E5FE92139F55B3D4857494F49DFE1F4B7
+:10D8C000E4FB9DA4F7DBF9EABFE07E18A5B3FA34C8
+:10D8D000D2392ABF9AA19EC5FCDD9B1F8A3A161831
+:10D8E000E7391CE710FA58143F540FE138555F8AA6
+:10D8F000FDF74E9E29E5FE4E1DEB7B7522FA7D67F6
+:10D9000099A8D7F4BFEEC338CD862931EB358F3DCA
+:10D91000A0F0BFD3E365FB2D627FB5E8FCDD535873
+:10D92000B709FEED09ACDB84EB5BF3D2F9F7E5B1A7
+:10D930007E732CD8E3A2BEB30EC7C679C09EC5BC09
+:10D940003CB385189E4B1FC0EFB3CCC2EFB36C2223
+:10D95000BD1BADC3F890F45534EEC9DB9501D97603
+:10D9600087A9EE46E63F993764CC7FCE0C1BF41DA9
+:10D970002B0C19F39FBC4E47EAB7CDEAFC10C6B595
+:10D98000A371C5721AFF649DECBF235C3A4397FFF5
+:10D99000D4AAC2AA5B9FDFBC2DACCF6F82BEA4B657
+:10D9A0008C433FD1FF6008EDFAAC99A10B48377961
+:10D9B0006E1E14908A7F87CEEAF61C403F1CFC0343
+:10D9C000A6E68F6C575FEBEBFF07133449A100808D
+:10D9D000000000001F8B080000000000000BE53C69
+:10D9E0000D705467B5DFDD7BF727C9866C42A04B0D
+:10D9F00009ED4DF879692561F909044AE06E76135D
+:10DA0000B62D9405429B0AC50B64101D5E0DB5280A
+:10DA10003EEBCB42421A420BC1E1F937AFBE2D05B6
+:10DA2000677CD631386AA1485DA0459496A63699A0
+:10DA3000521FD280790CD5AAB496577554DE39E7B7
+:10DA4000FBBEDD7B6F3685023A75DC4EE7E6BBF741
+:10DA50007CE73BE77CE7FF7E9745B315C66631F868
+:10DA6000F99386C6585F2DFC79338E83A651C2D8B0
+:10DA7000D2B1725C9934263236374F8EAB4D633655
+:10DA8000631D1E26E6B30403F8D7989BC69B8D5AE8
+:10DA900033318EB1F02255C0C708FF99E5127E4799
+:10DAA000320CF896B9C438B12469F819FB2893E30D
+:10DAB00005345E9E1EC769FC00E3EBEF4D3D6E260C
+:10DAC00060FE77A6C56F3646C0BD68B71EAFF8C703
+:10DAD000A3FF9C22E9196BE2F30F3BBD20EF9851A5
+:10DAE00085E8B9BCFF01E85D41FAB19FD3FB21A4F1
+:10DAF000EF2192E7D39CBE0F013D6D444F37D09389
+:10DB0000FFB75FEFC52A6327EECFDF808F2768DF7F
+:10DB100027723EAE02FE29E23BC4F7C1F9FCE67073
+:10DB200080317C3E8DE37BDD2DF428D164A2DE9F25
+:10DB3000755BF60DC6B37AE57A1BF4B066A57F0374
+:10DB4000D9C9B2223EFFD7A9CF9A8992CC187E06B6
+:10DB5000EEBB9CFF1B7C6E9BFF199ADFE94EC3D383
+:10DB60007A1EF15C39BC89E8CDF09B20F81E077C59
+:10DB7000A3E0AFE07047326191074B3C4AF249FBAA
+:10DB8000A5C4E3E497FA3C72BC8DEC667B29C73FE1
+:10DB9000EAF0E349A41FE47782E43D8ECBEF9F5D7A
+:10DBA0001EBF3584BE947379483DFCCE34E377A81C
+:10DBB000671F367A61FFD4F0888CFEFF1DD62BA438
+:10DBC000F5843D7DD0F9697B14719FCD4FCB77747F
+:10DBD00018EE8FAAD5E979F5DA7D919BE0CFE5CDF6
+:10DBE0004FAA26E2051856CC58BC9F2537C39A7712
+:10DBF000B0A4CA2086C543260B4CB4D835FB32D11D
+:10DC0000E1F1BBC4F8BFC8FF2D9B23F5FA5412F312
+:10DC10008B0CDDFE95B84F69BAD91336BA671FF67B
+:10DC20003F29F80E852D7672A3F1076B412E967C65
+:10DC3000283D16F259F6E057C7A01C969549BCDF5F
+:10DC400048229ED70B25DE7DB4EEB2F43ACFF171B7
+:10DC5000AE84FF29C167E8EA336D74255EA5BC4B2D
+:10DC6000D2F5CDC37DB45F9E4072CBC869706D5252
+:10DC70004209D88F8FAEDDA49A56BFC0BAF530C422
+:10DC8000B7FB597A4C7A95F103DDB4EE8DA66B7D26
+:10DC900058C847D8699ACE7E164A302B7DFBF9FECC
+:10DCA000DCE0F52D7EE121D4DB1B2FF794FB268BE6
+:10DCB000DCA51D2C0FA4EDDB603E90BB2EF1BC60FB
+:10DCC000AEF55FFFBAA0E78F5BFDC9F5F3D153470F
+:10DCD0007CBCC5F725E37F5E36EDFEE7AAE97B3223
+:10DCE0006C89E71F74FE7F87ED7666F13FDF42BEE9
+:10DCF0005BFD451ED4EF9541662481BECBF89B9B0E
+:10DD0000B98EAA55C83FA5EDB39ACF5FB2833577D8
+:10DD10004F1C0C7F53AD8BE05A9F656BBB015FD8E6
+:10DD200073B1296E814B85F9F3436185AEC0DF2164
+:10DD300092FF464EDF89B04EEB8599C60CB0A9869E
+:10DD400025634A500F5A7FCEF1B160882DCECFE0C7
+:10DD5000BB20F0C9750E2FCA6FB4F2F113B1CE8992
+:10DD600030E703E33FC9F311CE875AB02E88F8D5C8
+:10DD70003C595FFE9AE4DAEE16E3C43B14D7FAD2BC
+:10DD80007EE877A4EF4BBD522FDF23FB97F9FA3BD8
+:10DD9000E13F2513B3917EC65C53ACF37E4B7EF01E
+:10DDA0004AF3FA65BC6813FB9548EFD759A4FB4AC0
+:10DDB000F3D588D24C72F2B19402F143F50776772D
+:10DDC000022B1595C69B38FFA5C9C6AFAE060FC876
+:10DDD000E922EDCBC3F67AC4F2FCDDB0AD1EB8B8D3
+:10DDE0002E8E7860652FECDB6BCBD5E25520B7BF6C
+:10DDF000E2FE54517D10CBA65F7FCDECCB5FC3B666
+:10DE00007C3E925F0576C446B942E3F5C1F3FCB5AA
+:10DE10008AD433B14FDA93C8477BDADEF8787B21B6
+:10DE20007F9E73C4BD52D8535E2DAEF33D215F1665
+:10DE300028C6F5D8C4E329753AC45796FE192E189A
+:10DE4000AFC2BF60FDBEC85937EAC18A0EC5486679
+:10DE5000D1FB4176D221F03F96DEBF51B52308AF0A
+:10DE6000C9A68BF801BFBE8F6F22BC8D4D0AD99F0A
+:10DE7000D35EC6D672F98DAD4DCB692CD16F70BC17
+:10DE8000BE69F1F188174099774A06FF0A4177D8B1
+:10DE90001D3F7413E8417B9BA2A33F5AB9716547AC
+:10DEA000298C99E60E8D87CB049414CC6B0F96F9D0
+:10DEB000D10FBC24D6437C1ED8478C25C122826357
+:10DEC0001A5CA7C7D61FC5E97FA930AB70DDEAF899
+:10DED000CE08B235AB71DF51BCDE036E1AF3944D40
+:10DEE00073BE16AF85FDEB99E90EA1AA4176D63334
+:10DEF0000EE86A107469C6BC37D930A8A23C2C94CD
+:10DF00009A8671DD1FDA0CF71B9A3E3E9F55024C34
+:10DF1000DC3DD0EF43664C76B90CF16A03FDE55C5D
+:10DF20006697C1C72DDAE8CE8C91367CEECB3C5F8C
+:10DF3000722BF74FCB6A419E16BDFB91E0EF474233
+:10DF40009E3B80869E8984209FA1DDB0B52E94DF04
+:10DF50004A81ABA76DC95DB7017D97CA5908C75EF5
+:10DF6000E44FCDF077768CC6F963867FC148585769
+:10DF7000ECEBC916F075FF0268DB804FE047539762
+:10DF800017A42C7A7C7298C94298B79527B630D0DE
+:10DF90009388B9D3DD0F74DCDAF4F65ACCFB5698CB
+:10DFA0005E7D1E9078FFDA401DE6B54B4C2197F957
+:10DFB000EE73C8B70FFE43B978526FBEE04139CF58
+:10DFC00056D828C0BF30CA9F4BB9789976CE2A1749
+:10DFD000CD31DE78BA74FBF316F84FD5E6179FFF04
+:10DFE00008FC31954DBD0C7C82035980F45CEA50ED
+:10DFF000026A2981B918F0E9F1F17DDCDBB1FE2577
+:10E00000B4D315412DE4D2913E46F26B146BBCD7CC
+:10E01000A26F7F1E72D5C8C69D5DA877F7F7AACC00
+:10E020000B70EDCBF72226FCF9109F26F4C295F772
+:10E030009F3D1AC069FFA6325C4FCA11E41D980EBD
+:10E04000F7CFF5C17C00BDBF1AE404EBDE63787541
+:10E050001DE07267BFDD8672CA65CDA9E130BE37AB
+:10E06000E862295F862FE03B21E4E2BAACD05ABADD
+:10E0700026D775D99E935C723F17610C7D77C2E8F5
+:10E080001907708BA4DE76F0FD5C64F0FD90FBCA8E
+:10E09000A25C5FE5BEE43AF4D55BEDCEE867167DA1
+:10E0A00075EE43D2B10F7B356E27677B55CA8FCE95
+:10E0B000EE2ABEA71AE491D8E5223B863A6DBF52FC
+:10E0C000007FA414A681FCEF13F4D20FE0F63617FC
+:10E0D000263B4B33FB715FF9B13F2A958C438DCCC6
+:10E0E000F82386452C8CEF15A3FBBE9228423BFDFE
+:10E0F00028EB76A35D3FC0FADDA8FF1FC352504551
+:10E10000FF18F2E0FD465FC08372DCBBEB483EFACD
+:10E1100091D4CDEEC2F3E5642ACCEA279D5794C48E
+:10E1200079C93700A7A4FFF49941F2CB7EB8929F3A
+:10E1300036188E0BEBA23E334B1C3936D5FC31FA28
+:10E140002339D602CD0CE9D83335FE13EE77F9FC2E
+:10E15000F195C64FD17FEE9F629CC0FBDFC07C0F64
+:10E16000E2C3C5DA47A82EF94B857112EF3BFDD803
+:10E1700039F4637A461F163BF441FAB153E8C7E01D
+:10E18000D162B457901B8B5D9F1F3B2BF5E07676D9
+:10E190003BCA07F8F925F97F0DF801B99CC17D9FAD
+:10E1A000C4B0FB966245C4A61E00FA14411FDE5798
+:10E1B000C0BF2B1B7FFC4765181FCF023845EC2BD7
+:10E1C0009691751837BE1EF2F9C6A2BF304F21DFF7
+:10E1D0004EB9406076535D163C760AF5C695F7C396
+:10E1E0003166963898DED775EEB7D27CA11D4126F0
+:10E1F0008F7C28CC745D467E0240C4A8F7D38B0484
+:10E20000E941FB0285F86B2F658DE8CFDBF0D14C3F
+:10E21000D0F7054A37EAFBB722453C5F1AC7F3C27D
+:10E22000CEC26430C4FB2C04CFCA436C494506EF10
+:10E23000B7222AC14F9A66E461E082BC8FF2259929
+:10E24000AF4AB84084E795C3233CCFA8A88C1751A8
+:10E25000A02B0E91DC218F1A4E637F2AE91A29FA2E
+:10E2600022FCA7BB2C7944DFE824C33C24D7C89EFA
+:10E2700037DC1249C7F55B22C8C72E19D78D5B1151
+:10E28000FFDCE18106F4731EA07B7769265EFF60E8
+:10E29000C1175458967D24524AF45537ED6C1D0928
+:10E2A000FB1D0E8FF563DA94AA4906318FE81C0531
+:10E2B00072C8622F1B233C0E4EBB45C00979C9B8FA
+:10E2C000EF83F4DB0DEB6099EFC23CA084E7010F14
+:10E2D00044CA689ECC07003EE101B8F00493F0B454
+:10E2E0008FCFBEDE03429E99781B2A407FCD5833E4
+:10E2F000C58BB88827AFB51867064029FB5A6274EA
+:10E3000005FFDF130507774A4BE487B2C86F61DD6D
+:10E310001E1FC6EDD6F255BE7ECCFF8C08E16D5CAB
+:10E320001E3E3360F1B79D256C0CE601F736DC79B3
+:10E3300066C0626F3DF99C5E8C33096F06EF52D464
+:10E3400013A0F768D89B9A0B02CD0DB2A457A1ABCE
+:10E350005B473B88E8F43C6EAC6426D6E3D5673572
+:10E36000EA7F15B234FC26D89A483973235DF160F0
+:10E3700092E1BC5C18237C7CF6DB04BFB05A6509D3
+:10E380000B9DE07F56901E38F2A51DA86080B77DDA
+:10E39000A692DC0C781B826B28FE6C9A934BF7617B
+:10E3A000DDA417EEDF33BE89E296CCAFDAA3D1103D
+:10E3B000C5A7EBCCA78E4D8D3F84FAE809A6FDEAF0
+:10E3C000C34467C6AF6E8870BFFA19BC4AFFB1FB81
+:10E3D000E86BE43FA00621397782BCBF9B651F37FD
+:10E3E000093BE82CE47AE87CFE55A1AF7FA988B709
+:10E3F000221D06C4B4E0946BCF37DB65BE29E478F8
+:10E40000BDF201797C2962F1CB208F2F679303FC49
+:10E41000DAD05FA8D25B3CAD68A8FF3962F824333C
+:10E420009338CFC79A0948F5C719C6BBC178520CB3
+:10E43000E72D13FC7D507FFC1D486FB85F339E8E27
+:10E44000505DC8F559FA65B04B1E7FAFD16FF7BA72
+:10E45000C09F023D1D786B66E6F921B1CFCF55997B
+:10E4600087701F2794F856A2FC1F558CA05FC5BE6D
+:10E47000A7D9887E84E9536CF306AFB389F0F4958D
+:10E48000996BD1AE99BEF80AF09BC5BA824F9DF345
+:10E4900001EB7E25776C667C25BE7E10317E86F290
+:10E4A0006A35E3BF40BB7BB9DCA52714BA921D7661
+:10E4B00056E724151807A698AFF37D043F0AA83B3A
+:10E4C000CBDFA1BC68E17C85F2B4853EA8E0B2F860
+:10E4D000C9F322DE2CD4F97376DA085AFB1D855174
+:10E4E00097BDEE059530ACFD8BA86B15F6E5653C48
+:10E4F000C3BE49367BBB28EC49F5BE5D827EF5651F
+:10E500007776BFFD4EC443704A54F42544FC5BEA61
+:10E51000E5F5157B11E8B3C4D7E7AA6AFF8FE2627D
+:10E520008225144B5CEC1B7D91FC1D3DB1DC5F280A
+:10E53000FA4EACD78E47F2591465B675415F5D51FE
+:10E54000DEC750A396E74B55C6FB1E3D7679013DCD
+:10E55000BE28AFBB9B94E959E919C7A667A1E79408
+:10E560009D9EA228DF97E7AA8C22C407F17938D2B2
+:10E57000D1510BFA9745BEFB26D5DE84701A4B7439
+:10E580009495BE6FDE7A0BE291634BDEAA47EDFEF7
+:10E59000B534CAFD6B5994FC4AF6752B85DCAED7B1
+:10E5A0003F5CABDD6F73D8BBBC76F67F2FAF12E854
+:10E5B000F07A139F267B9D7875F6FDB15B7A462332
+:10E5C0009F87847EA26FC77CC3D0793EF26094EBB4
+:10E5D00071784292E09E1D22FF48C38160B02F37C0
+:10E5E000541E32F31AF390CED97D7988A7F5DDDD7C
+:10E5F0007958C73F3B509B350F3954D245743AF395
+:10E60000900343E4216BA23C5F3DFABF1ECA2B6A14
+:10E610002EF0385F73A14BD5413FD745B93F9B39A9
+:10E62000D0A39AA027359887009E03220F41F84D6A
+:10E63000A0BA9177BB54A46BE6851E9A570363CCAE
+:10E6400043660E918700152AEADDFE9ACE5771DFE8
+:10E650009CFCBE58696E885AEAADEAFE1E7A4F22CB
+:10E66000E775966FCE33699FED7A736C2AA73733BF
+:10E670008FEBBB136E28FDAA53FDE5D81FD8CA72D5
+:10E68000432887F7728655B2025ED7605EBC15419B
+:10E6900081EFADA7F39209ACAB7DFCF9677387ED11
+:10E6A000C6ABF43F3E6117EFE5DC92147590510064
+:10E6B000F33FAB1AA9B9100FB68EFB6280F3B39E7D
+:10E6C000EC6883904DED4E8DEAE93B827C1F64FE41
+:10E6D000F5D25285F24340337F01C0CF10F83DD3CD
+:10E6E000787D58AFFA096E5B39CF23EF485CA4FE02
+:10E6F000C5CC7E8FAEC37846FF1A5E2FAA3F3C9EE4
+:10E7000087F9FE4734A6C2FDA56DF156D2CFD31EC0
+:10E71000EA67C8FE42556F37C92D6FC063EB73E4DB
+:10E7200082274B59F2168F63CCD4E505D9FC90BCF7
+:10E730003AFB10FBA2A2FEAC64932E835C2EB14781
+:10E740003A9037EFF8DAA34FB1C1F3657FE1C149E1
+:10E75000C633A81FE3DCFDDF7E06E475E02D0FF570
+:10E760002D0EECDA757725F097E8D2A8AF2BEB19D0
+:10E77000905BD122AC675106D4973EB90AF5F2609E
+:10E78000BE1C834303BA0FA6DFD77F629561199F32
+:10E79000886E398771EFE00809FF269F2FC789FE31
+:10E7A00055785EE3E0283EBE14559F4AD0FEF66BD6
+:10E7B00054476FFCA53F9B7F3C5967D7D77BAAD7AF
+:10E7C000737DBDC23CF0EBAF47B3CCCB59606EABB1
+:10E7D00000791C1C70D1FB21A8B352981F3C38C98A
+:10E7E0007C03E11F3DC5E57AF0AD8702B84FDEE15D
+:10E7F000FD0F67F3F3BF11F1285DE74DE6FE83B12E
+:10E80000010DE3D68E39CF9EA884754ECE1C3F45B0
+:10E81000051640163ECC97E57C6F1DAFE332F4BD84
+:10E82000A2AE42FFF3D6B9866CF65E15357F1FB5F2
+:10E83000C1F3F7A2AD5D1AC9BFE8D8BCDD78EE27F9
+:10E8400055D3D5A3C1FE1EF88D8B619D72A042D415
+:10E85000E143D11502BA8AAE8AAE5D33B2E81BD06D
+:10E86000E5A91B3198AE97EB18C9E7C54AC387CF16
+:10E870009D7432D1C79C25FC7DCE9B5FA4BEE381F5
+:10E880007E17354F2E0DEC5651F564FFBBF354192E
+:10E8900066406CEEFCB32AAA94F9886AB3BB19A748
+:10E8A000726DE3079A87DBC6CBD68ECED821FCBF2C
+:10E8B000383AD636F6066FB78DC36CAA6DDC30FFDA
+:10E8C0000E1BBEBA40C4369E17BCDB067FA7BEC473
+:10E8D00036BEBB7C990D7E4168B5ED794D60E7167B
+:10E8E0006C1FC5274ED68633D2C7C975B00F79BD08
+:10E8F00006E9E3A3A71E0AA05EA46AE26350DFFA5A
+:10E90000F27B4AB07FFD923B7BBDF6489D2AE377C0
+:10E9100009C67B83F17A4DC287CBFA6D7DF9D57537
+:10E920003C3EAFA853B2F6099CF158C66119979DB9
+:10E93000EB3BE3AE33DE2EBC6DB78FF7FB79DC5FCC
+:10E940002AF4A0B5FC677EACD75F6AE07D84CE92E6
+:10E9500038F50DFA447C3EBAF4BE31F85E2DB7DCD2
+:10E960001CEE2DCDC4EB487992FD12FB3C81241B9B
+:10E970005B81CF936C7505F5A5B5C8447E7F82B8E1
+:10E98000BF06AF10A7EB2D7273C6DFB06FF20B0599
+:10E990002C93AF34FCC18816007D7735EDD38AE126
+:10E9A0001AF11FD6AC7EE864CDAF8A8788D39FB4B6
+:10E9B000DBC72B641F070616BF6F1C78A385F7DD26
+:10E9C0007FD0E26329E0EF744B80AE3F6F09D2FD48
+:10E9D000575A74BAB6B794D335D512A2E7AFB65426
+:10E9E000D3F5F91683AEC75A62743DDE1227B89F7D
+:10E9F000B634D2F5C51693EE6F1776FA61A1C72823
+:10EA0000977D85F8519742726DC0A3BAB32E18AAAC
+:10EA1000D5CF835CFF239B5CAF359EA46ABA47A326
+:10EA20009E41BCCA6A4FDD7532AF4FEF37D125F337
+:10EA300061AC5F504F649F0EE8FB26D2E7C5FE5CD9
+:10EA4000D1F5D37750E1741D2CE4FD1BC4B3281F0E
+:10EA5000FDF9D7E2B5E4CF474C267F1E649ADD9FCF
+:10EA6000970EF2E72BC9EED871EC93627F91DE53DB
+:10EA700038FA2005F53ACD937D90397FE07D902BD3
+:10EA8000F10F7C1F47BF25FDF6D5F2EDE4F7D85412
+:10EA9000E365C423E3F3A0F861AEA3F8512D6C96AF
+:10EAA00069EF529E9827F8D9716E7101FA172F12EB
+:10EAB000C8EB748355E33E33791E60F7DA92C17870
+:10EAC000DFA8E9A678BE2D9DE7BC4D79CCE0F865BE
+:10EAD0009703E642D6F80E7278B3AE6AB07ED6A936
+:10EAE0003FECDF0CF1F9603FE37DB269FC7D9D8C6A
+:10EAF00083072FF03EC6254D4932D8BA5AD6DC35A9
+:10EB000003AEFBBFC08AE3F8BE698C2BB41740F399
+:10EB10008E1CD07D0017EE3787E7C0F3EA540ECD88
+:10EB2000AB9D3F3989E386F8DBE49F6A357B9CC463
+:10EB30000C351D77A80956E418DF9C8157717FCBEF
+:10EB40003263C0BB6EAAA9D5035F8B2F36331DF08D
+:10EB50007B4B989BCE870C8EEFEB144B9F4D63A1A4
+:10EB60000EE443FBDC36FE5ECFA16F524EB2DF26D1
+:10EB7000EBF0279911C0F59CF8DBC47B17E7FB96F7
+:10EB8000F72ACC20C22B8163F4BE85AD65FC7C8462
+:10EB90000BEA1394DF304F726FE960BDDB3FE5CEC7
+:10EBA00031F564DF09E5C6D4ED5D0AD5EDA26E62EC
+:10EBB000FAA75CD63A46D64DCEFAE831E167655DF4
+:10EBC000F4989B51BDD5AEE486761393CD93F8FBB4
+:10EBD000B8E61978ADA9977EE90BB63AC91FA83FE8
+:10EBE0003330355B1DC7EB11777ABF4B02E7F33249
+:10EBF000FBEDF798413CDFD83E79DD5756A2BC4685
+:10EC0000F8E8FD26D3E23AFA9BC7F1443FDA7320D5
+:10EC1000C18AA767F65765DA79ECC77640F282EFCA
+:10EC200077E3F53C9F70D2E5BE46BA7023E93DB567
+:10EC3000B4771617EF25791EE913F7DB746EF70C1E
+:10EC4000FD96E53D799BDFF0052CFBF828CAD93B02
+:10EC5000F4BEAAA56D01EC6777F95D64A71DBAB68D
+:10EC6000B514C61D7E8DE729BA2B96ED7D5247BDA2
+:10EC700022F8E67405045D6A7831E53343ADD7299F
+:10EC8000F65D8E73279A06D9951E8A63BDDBEA2F3F
+:10EC900056B0CF299FAFAA57C4BE77911CB68AFC45
+:10ECA00028B7BC3BE5427D19B5662A8ACD07F9CE67
+:10ECB00079B8EF9BD84DF951FB089FED7C96BC3E8F
+:10ECC00026F06D75876254BFE7BB18D6EF5B4BB378
+:10ECD000C7C387C5FEB6EA53E2089F00B98C570642
+:10ECE000C3AD11705BDC5DC100ACBB75FCBD74DEF7
+:10ECF0006BEB1872356CF48F6F7B6A937FB07DC0BD
+:10ED000098F6CF1D60F23DBAEDDC43ABDED0B81211
+:10ED1000D6D55E6121340B6937DB313F81AB7BD4C3
+:10ED2000E246D4DF4BD5B92184AF535F4CA01CDB46
+:10ED3000438CFA165A61930FE97EB444A3730E9282
+:10ED40005EC8BB77A3FFC80FB96CF9794175AEC334
+:10ED50008FDAE981F548EF86DA5F277D94924F7963
+:10ED60001FF842B3319E05DFAB697BB7EB97FB0A17
+:10ED7000FA75257E6C71B22413278F1CFBD7D5F84A
+:10ED8000BEE371C69F3F7F6C0ED5EDCEF18DB2F321
+:10ED900056ADAB11F7A5759C87F4CF397F6B29A7CA
+:10EDA000ABB57E965837A0A0FE6FAF2ECA413FED9F
+:10EDB00047876B91EB0B95E6CFEB2D71B830DA4CB2
+:10EDC00071F8BBF58CE4E8D7E38171A017FE5E15FE
+:10EDD000740AE4EEFAF31FCEEAD72E47D66590DE2A
+:10EDE000FA59E6F76790CB30C6F5C4CF1EEBA1B851
+:10EDF000C436109C94D7F65B4F86526CE875FDD5EF
+:10EE0000F63ED307ED23FDA93EBF98E49CC37250A4
+:10EE1000CE97D8230AC5E1A841761748FB557EFE58
+:10EE2000A4580E811D1C93CA2999FE12C3F71768B6
+:10EE30005F26A33C8520478A57573AED0BCD1B2D03
+:10EE4000D0DC8C076354D47FEE772FB1B7F8FA305B
+:10EE50000DCF9F280917C5CB5B51AF01AE94997FA9
+:10EE60003C9BE55CCE9840D3BED5702D9E27FA62C0
+:10EE7000829F2BC943D2FDB7D25B19E79DFD50D9C4
+:10EE80002F7D06FBA5CA95FBA14CBB48729379ACBC
+:10EE9000B33F0A712D0FE5FEDE048D7592DC791EFD
+:10EEA00090A9D74D9FF51C9D8C97ED81C5B63EFB73
+:10EEB0000CA94B0E3EBF7785B8D8D90B7E13F3E172
+:10EEC000E066EAB3EF3FBDEA38D6E397821E9D596C
+:10EED000FC7F7BBEFD3D80C4FBF979A29F3EAA9ECC
+:10EEE000E17CADC76478FECE130C515C6855B2BFAF
+:10EEF0003F689D27F209679C70BC67F99F1C7FD211
+:10EF000053C6D2F14315FE59C657A641141D699D3B
+:10EF1000CFFDA894C77E9157761EF9049D176041D6
+:10EF20004BFFB62CCBFACEFCCF30F4C0F44C3EAA4B
+:10EF3000F4F33C54AEDF2EEAE7D6D37C3F72C5B97A
+:10EF4000A141FA5A617E7A1EF67FCA5D8E3E95DD3A
+:10EF5000DF38F35AAF8F25722DFE0FF2DA8DF328CA
+:10EF60001FB1E7A5C3638C9FEF293419F6712241C5
+:10EF700053C5BECBF4DE669501DF334EBFFF7E2C5A
+:10EF80009AC7F39CF6F25571AC7F641F79C79CBB9E
+:10EF9000C8BF421CDD3ACF52C7CA730B1FB4AF249F
+:10EFA000F575BAD847896FD0F992D91BF8FB9FD372
+:10EFB0000F9D407DDC0FFA8871BE3D3FB1AD02F37D
+:10EFC000935754B6571FDC8772F225FB49FE18D7BA
+:10EFD000534FB0FDE85C97453EFDCDAA4EF2311887
+:10EFE000BEEFD1C4FB1E67FFC8EB359A317EA76A1E
+:10EFF0008C466BFF58CA6D91D0E7376A9AE97DD489
+:10F000003343BCFF9570F89918D6D3B21F553AC94F
+:10F01000FC3EEEEBF4D87A15DD48757C3D9DA3CC23
+:10F02000FB77467520CB55927B61A923739EA53A49
+:10F03000F1F74146FD320FD689C55817F23A51D63D
+:10F040009FD24FD4A94F7794E1F98C5E8DCEDBE54A
+:10F050001DF9840FF3DE70EF6AAAD50C65691EEE08
+:10F06000A33C7F24E9BCDE3AB30AEB4CCB7B928C09
+:10F07000DF88FD02F5A0B325FE8B28E8C781168343
+:10F08000C6ED2D8D74ADD29206F253554E951B9B55
+:10F090003500CF2D7454F5C46CE31D95E619D4CB1F
+:10F0A000BCF2B8EDBE3708F82C7A0175EE3992EF54
+:10F0B000692E4FCF7C85CE152CEC675BB86DFFD3E6
+:10F0C000F8212D7663FC504EEC7DFD107F5FEAE960
+:10F0D00017EF4B1DF6B6679E4E7690B63B7C6F4A97
+:10F0E000712E41F3E9DDDF4CE067D827B9DFCA9C18
+:10F0F000CFA0EF12C3E27B693D366B0FE6B3EDAFF5
+:10F1000033F99DF01EC3F21CFE6AC2EF440E63B1D8
+:10F110000B79E6E65861137D4F2DBE87893416962C
+:10F12000F4B1CCB945A7BCB6C45CB6733161C6FBBB
+:10F1300062F2F92763A26E03765C96730FB978EEDC
+:10F14000214BFEDE24F0350B397578F8B983B98E82
+:10F15000EF3C66C6785D30D4771E9F1378AEF45DC1
+:10F16000C76201773FAE5745E722C331A4372EBEB1
+:10F17000CF1274CCEA4DB60EC32431C8B2E2B93313
+:10F18000C6CFEFA562FC3CB1276868B82F80EF6E50
+:10F19000C2D7C8CF59CAE7B32EA49F2F243D69E038
+:10F1A000CF675D30A91F24BFAFBBF3F8D83D9BC626
+:10F1B00065CED7B4633FC28FDF99F0734BBB04FDBC
+:10F1C000CEABFCCEE4DE8038A793B8758F81780C87
+:10F1D000FE5D65EDF10903098DD6FF18D127BEABA1
+:10F1E000992CF885FBAB882EC7BF0FF0C0F1E01E4D
+:10F1F000F13DCE1A9AD7CCE9CEFC7B07A13DD6EFE4
+:10F200007B261FAF6C12F0EB087E2D87CFA20F423A
+:10F210001FA7ECC15EEA55E0FB0CD1B79CD3571693
+:10F22000D3F977590EBD05B8CFD3BAE23B9FDEF8CC
+:10F230006A1FFAF3CCF7FBB7D17A5721A736C2631E
+:10F24000CAF59838CFC4ED42EABFD4876F08FDBC39
+:10F250003DA648BD7A8CE86DBA61FC7F89E8717C77
+:10F260005774253E2A2AE34FD0BC60FA5CF1D78957
+:10F27000AEEBA4477E07E6B48BEF0BFE61DDA7691A
+:10F280009D92109D2F8275BF7D23D605BCCF101E89
+:10F290005F1AEFFE58767FF381F0B292E2AB3A1F2D
+:10F2A00022C7FF0F94B0BE363046000000000000B9
+:10F2B00000000000000000001F8B0800000000009C
+:10F2C000000B93E46660F8510FC181486C62F11A3B
+:10F2D0007606866816068699AC0C0C15402CC74934
+:10F2E0009AFEE540FD8B80782E10CF00E2C940DC0D
+:10F2F00007C49D40DC02C49240F34480981F88B943
+:10F30000809815881980F8370703C3370E8439377A
+:10F3100080620F48B41B84AD7810EC3340FF6F045B
+:10F32000E2AB6484C3281E1E389D9F81A15A00C190
+:10F3300017104495CFE047B0B94429B34B1AA81F22
+:10F3400000656D40B4800300000000000000000074
+:10F350001F8B080000000000000BE57D0B7854D5E2
+:10F36000B5F03A8F79666672F2204C4280134830CD
+:10F370006A8A03840882F52420C696DA9152C5FE73
+:10F38000D60E34224A2051B1722BFD726002040164
+:10F390003BBC1414E9E00D8A8A362256ACE83F20C3
+:10F3A000B5B4B56D6CB9D55AED0DB5AD2F0C88520D
+:10F3B000FCFBEBE5EEB51F99734E661250F1B7F703
+:10F3C0000F9FEEECB35F6BAFD75E7BEDB577DCB232
+:10F3D0000FF287029CC49F8B00EE7003C0D8743A72
+:10F3E000EAB66FCC7DA49AFCFE7FDD916D7ABA9E61
+:10F3F00048878244EB01180045001779C9AFA4DEA5
+:10F40000A49F1FFED37985007B41010FF9945227F9
+:10F41000157C8DF4B3F7238860B9FCF3406957007D
+:10F42000DB99B4DD9781B54B95E9A55A156640C6C1
+:10F43000EF8697FE4EFA19BEB999B43FFE6180B6C9
+:10F4400077C22152F84886146F737218F6AB7ED0DB
+:10F4500055C9F3654006070EEF64809A34BCFB5F24
+:10F460007B83C2BB4F25F0EA19C6F712F80BD3F025
+:10F47000EF856FE4421583DFA849C37FBAF0D0F966
+:10F480000F0058DEA23F5DEE0258DD024F97570095
+:10F49000AC6CF1D2FCD2168DE6E32D619A5FAE9290
+:10F4A00026040FCBDB216992F6A16A525FF447FE76
+:10F4B0000B54796D79772169EF4DE7D540D896F7F0
+:10F4C00096EAB63C01E76098CCFB1C3E9FA52D0454
+:10F4D000071E1CDF0BC65958FE6D8A171FC75B3C01
+:10F4E00038E2CA61042F6D2F2A84D2002EDD988164
+:10F4F000F09507DC7A92B0C63981D9536124193767
+:10F50000140320F5E21B00D612B8CF0E4C790B4243
+:10F5100000F793FEDB48FF4AA8ED650F295F51E62F
+:10F52000D615C4CB76F52F5D640C2FF987783B6B2D
+:10F5300023CBA7E745F296799E0D9672D2FE977976
+:10F5400077BE2C1138E2E56EDD23A5C7E9A14B3F5C
+:10F55000FD5724EC7967FFE5BA51877C2AFAAD8024
+:10F56000E8122DF0C5EDF71C82DB82FC74BF629CB3
+:10F570007EFB25E48F92B6151B21992AEB3D4EB9EF
+:10F580001EA9374979F946159265EC7B219187725E
+:10F59000F62B2C2FADF3C7AA7AC303D67186A5E943
+:10F5A00052AEBB67CA842FCACBAF982B11BE8184E1
+:10F5B00085CEC31883A2BCFCB045A3FCB8BAA59203
+:10F5C000A6ED2D5A07959F8F95191D55BDE5F0AFF6
+:10F5D000A8A748BB3B5C40F9D0DC06C96D12F61702
+:10F5E0009D3193E4578D2A1A7DBB8EF91932EA05B5
+:10F5F000C1DFAB249DF2B749F81BF59F533E56BBC4
+:10F600008CAF607F2B46C9D212C47339E3F77257AF
+:10F61000CA3B1CFB4D0C1B65623F91DF7561BDF25F
+:10F620008A11BA42C63DBB9CF1FF2FC7DEE9453DBA
+:10F63000D833FF85451DE56300721D7CA09D221F08
+:10F640006813FBE60331CE672D0F678EBF127DF284
+:10F65000D7AAC8DAB7506FB49733BDE184AB7868E6
+:10F660002A1C0DF4E6B7F272C26748A748DF7CE6B1
+:10F670004C37B424E175C243EB5AC294EFD6B4E8D8
+:10F68000345DC9F9D0853C554CF29C0FA1B09AE687
+:10F69000B3AE57B098AE4703A6272146E05C87FC7F
+:10F6A00079017E5F6A18A5A479A5C8434A26BA7F66
+:10F6B0000D9697D0BC01A5C89FA2FC31D320EDF3D5
+:10F6C00079FD29D263669C20699D8FE5EBA56EC309
+:10F6D0002CB5B65F691813D3F5493E55576EED8FBB
+:10F6E000F45F6585E7395A5FF4D7201D324C925F8D
+:10F6F000E363FDB5492F7F2EFDDF2E25C2B8D0ACC8
+:10F7000070F473BBC89B09C3A84A8F53B6F851C3A2
+:10F71000B496C3A3B6F29AC509D32478BB0BA2C38F
+:10F720002542DFE2A9D13010FAFBA2491397DA345F
+:10F730007C0CDFE9F9DD49E1F597B3F22AE9F746F8
+:10F74000DC429F5AE93726C22FEC1B85F3ABFCF352
+:10F75000D29B5F20FCAAE4BA23D4CE282499F1647A
+:10F76000BCE931D0091C723806A80F94B0FA77AB07
+:10F770001C08FE23708EA3704E8ECEC802A769852A
+:10F7800053C0D11FDC028EEC7CCAC677F253DD6514
+:10F79000E37E3B91B0B8AFD315413BAF00F144F4E9
+:10F7A000007CB4CE7091EF05D308EE754AB71930DE
+:10F7B000BC77BF85534B206959C73F6BBA0EC7FC56
+:10F7C000588AB7EF4863D3F425F999563C8EE3F590
+:10F7D0009CFC27E6E7EE35BFEFDAE6076A221C0D50
+:10F7E000F63FBF35BEC88C68A077BD5F4ACC8EAEF1
+:10F7F0009B32EEEBC0C6030FD15F7938DEE8F478B8
+:10F80000795F21E361676A32E378F993C978DE337F
+:10F81000874FA73C0A787DBDE05D6783F776179137
+:10F82000DB0CF43FD3F09EAAFCF989FEA5F257D970
+:10F83000B7FC7DD6FDE5E1AF849FDE57217511C190
+:10F84000D7828BBD49534AEBB9CF1B5F055844E8BB
+:10F85000B7E0D7630E5D246386F0F597D2E3CF97C8
+:10F86000740A7736FECE361F80A4AD9FFF57F3C9CA
+:10F8700086D733AD874E55BF2EF9839FEEEF969610
+:10F880004312E569E9818BE93E73E90B930602E9CE
+:10F89000C7D5762E18645279DCCE588A7606F63FA4
+:10F8A000F9D4EC8CDB5BA0A395185D4F84A2D42E19
+:10F8B0005A2A016DBF8AD86D4962BF54BFD8EE9DE8
+:10F8C00019A076154D97BA80DA31D52FEED726914B
+:10F8D00029F82BF24721EF2FF589EF07EBD1CE5D09
+:10F8E000594EBE13D6581A64FD91EF51AC9F53C1C7
+:10F8F000BE67832BA792C063C1BBCF9D8C65D28F9F
+:10F900005F96658A9F4DDCEE5A8D761751C83E7F13
+:10F91000228676B5BFC8ADDF27F56E37436676FF22
+:10F92000FA8A9F98E8D25881F61B99FFBECBEF87E1
+:10F93000AE2A5C0713868CED23CC35B0C9B1DE0747
+:10F94000D086A3EB66589A44D64CBF23BF5AD4370F
+:10F95000F55AB4D74295ACBC76C985B5716B399C64
+:10F96000578BEBAE28BF66C9585A5EEC8DBE3C91F2
+:10F970008C5F4CF4679CE0A9584D48CD949E99F952
+:10F9800065FDB5DE194902C3FACBEF2CBB36039EE9
+:10F990000815299D45BEA4C12E5F9B38DE56733CD9
+:10F9A0008651C62D7ACDC7AAF6E835DF594CAFF996
+:10F9B0002B138B11CF250D10413B7B3DC15FCC320A
+:10F9C000BEAFD2AEDF8A55FBBCCED47CEE02E32ABA
+:10F9D0007940F6FE9DF27517C46662FD62BE8EFB2D
+:10F9E0002B9352ACAAFFF93BE79B6DDE5FE5F82451
+:10F9F000E3CCCF34CEE78597E20019A7FAB31FC74F
+:10FA0000DF60D793A78A77686C37705F8DA626EE84
+:10FA10009B7D303992A2FBB9DBA81FEE160E3BC4CA
+:10FA2000366968D7C40132EA33B5DC9DF6A7E1FF39
+:10FA300094AB7333D145A40B5F7D2F6FBFA57E526E
+:10FA40000E16FE3D87FC723E9C7F5249B707EEEFD3
+:10FA500053051C817CDBBC4EB41CCDDB4FF4C61AB5
+:10FA60006D1AD5C7D9C67B90E8D11491AF075ABC9F
+:10FA700034DDD6A2418AC8D9BF1379C3FC56227F90
+:10FA800098FE88EC1731BDB72542CBEF691947F3D3
+:10FA90009B5A0C9ABFABA59EA61B5AA2F4FBBA9622
+:10FAA0001934DF83CF8FC87835946501EDAAB36729
+:10FAB000244DD463B003221504BFCBF1BB05FED5A2
+:10FAC00072EDB332FA3D67F8A87F23C8E7E987A44F
+:10FAD00081FA1B0E2AB00DB2CFEB0E3EAFAF28322B
+:10FAE000F39FAA957470414FB91DA85FA5A89AAC61
+:10FAF0005B44E5E65ED89A8FFC5E54CDBE07038476
+:10FB000091C877A51A52BE101D5AC5F61A6FDF3676
+:10FB10004EA6F5566B2A6DEFE48B73A193AE33605E
+:10FB2000782308A777BCCAEA57B1753278FE3EA49D
+:10FB300020B44D94E9FAB9BA9CC1A168767E09D681
+:10FB4000DC0768EF879561741EAB2F50370D473681
+:10FB500080CE9787937E3690AD0DAE6B0F6CDEA98D
+:10FB6000CDB4D0D9AB30FBFCDCE93BA315088F4A00
+:10FB7000E49A8C5FB8D99FC47587D0434178737C71
+:10FB80006C3EE7E298048EC24590BCAF2C5D1EC867
+:10FB9000E3F3D18C5AEA9710DFB9E23957EF48C93D
+:10FBA000D86E2344EE8374B94FB433ECED7CA29D40
+:10FBB0009942DC42E12A7B3BBF6807B5B6767ED12D
+:10FBC0000ED61A74BC0469A7A7CB15DEAE47EE2B80
+:10FBD00035D92A674A409799DCD8E9948D7F34E07B
+:10FBE00074D8674A27115FD52C2F49DEB69332AE01
+:10FBF000B3763AF951CEAD7A2660C913D245517623
+:10FC000071BFC6E9953433D36B9D1AF94539CEAF30
+:10FC10004AB5CD4FD0699D97D3D1F467A4D33A8D1F
+:10FC2000D33106363A0B7AAD13F46AB4E34FD06B96
+:10FC30005D167AAD13F46ACE4CAF7559E8B54ED067
+:10FC4000ABC1DE4ED0CB490FB1EEA4E9D62C21DDFD
+:10FC5000CE143D9C7AE10559A7DFE5F6A39D680F18
+:10FC6000162D50D93EA9B21350CF43697E3F76ABD3
+:10FC7000C9ED93665A7F2DFE2AFC5F28A76E96BFBA
+:10FC8000267EA816EDF07C4994EFAB457F5812CB49
+:10FC900089FD7573FC382D7F528EC614DA5F1270A1
+:10FCA0003FE2C497279A848D04A40A357A6905FA3D
+:10FCB0002537CB11F4DF0A783C20F004FCFCE6D4B5
+:10FCC000F81F80E10BC13B39FC94E0BC45A1F84C26
+:10FCD000323C39E124FBCB8D645F3384F3F710F3BE
+:10FCE000CCC0090D6CBDE8599FB99DE482CCFD5490
+:10FCF0006E966D7C3362BDDFC637E5ABF26DE5C352
+:10FD00005A4B6C797DD1305BFD210BCEB195973686
+:10FD10008EB69597345C60CB87AFAEB3E57BF10BC5
+:10FD2000CFB72BAF2CB6F18B39A20EF76D496074AB
+:10FD3000D81E1F5187FBB6FECABF7E8B6A7809FEAC
+:10FD4000D542375D870805297E04BE723530DDE86F
+:10FD50001F280C242F21E57ECD30A93F403300F72A
+:10FD600073B216A37957D82E5F5F4301227CFAF550
+:10FD7000AD2A780BFBECDFF824FDF7372F27BF887F
+:10FD8000F55D2964EBEA06B25DC2F33593E8C76D11
+:10FD9000645C97C6D67597E01FC2CFA8573455E26A
+:10FDA000F27B7A72367CA31DDEB2843D3FB4CD6116
+:10FDB000079E227F7F5EF2DB1FFED641C4544E01B8
+:10FDC0007F1155E2E7D5A727FFA58D76FC9434B8BF
+:10FDD0001D72E2D0E79F33FE5AC57A01D13AC44B77
+:10FDE000CE7AE64341BB2B935D21F865C3F49BFCBF
+:10FDF000D6F50CACEBD4B0F43834AF64CA7FD1F88C
+:10FE0000A4AB16ED8B9C8564FE65CC8EC9387F4E05
+:10FE1000EF755365BFD50EFBA2CF3F4DE71F9C5634
+:10FE2000FB700FBCA51ADDAF89BC635FD6BBBDC933
+:10FE3000F44DCC275BF524F9A954ABD135E98F20DB
+:10FE40009F9DF08546422ED91F7A597AA6F76D0FED
+:10FE50004C67FB12F3D59C6405E293C771AC7DF54A
+:10FE60004B4984273955863BF19C79B29CAC20F9EB
+:10FE70005BFDA1FB10AE6F2AB15BD50108EF9024AA
+:10FE80009E1783AAE74D0B5AE6C9ED2231FF6CF6A7
+:10FE9000D192D69BEDEB194CAFB3F2E35DADCB69DC
+:10FEA00039B13B5A554AAF2F8A7D9415CE4DEA178A
+:10FEB000D83E12E703CEF6FF2AF6D101B57189DDEF
+:10FEC0003EDACDE8008C0E2FB4EEAE3B9572611F8A
+:10FED000F9036EBEAF77D82F95C43EC2F3A300B727
+:10FEE0005F2A93D45EF1552699FD5229EC19FB7ACD
+:10FEF00076231AA063D3F6511FFD1B9FA4FFFEE6D5
+:10FF0000956D7DF705847D9460F611C135C69928FD
+:10FF1000446DF846225FD8D7F76A5796F5FD7F8C77
+:10FF20007D94597EFBC3DF3A4830FBA81FFC4DCFC0
+:10FF300086BF7F71FB68BB0AFF9FD947D9F8E47F72
+:10FF4000B67D94A6F36763E738ED1A61479C69FBB9
+:10FF500046D827C48EA1769649EC2CB4734EC89A25
+:10FF6000EF4E32CF5B15DD877EEAB55C5E17AAD116
+:10FF7000352EBA7EEB7968676C447D3E80EB59B4D0
+:10FF800083023C3E4F8DC0B42F61FDD84697E51CDF
+:10FF90004209E8793DE7365F203C103BAF522DB473
+:10FFA000CC9FE345E061972B8FD3BBF9FC289BD70F
+:10FFB000E3140FA04BD4DE52751FA64FF3F58DAEA0
+:10FFC000C7D5567CB0BC52AF27511E48FBA75D0376
+:10FFD0006C78F1D9F042D621361E28CC9E336DF1D3
+:10FFE0006CFE6A4D42BF39C97622FFD2F3721D20E2
+:10FFF0000889FA11A4FF82D8B21B311E33F8EAA592
+:020000022000DC
+:100000006F615C6341D74C1ADFD85A35FA401DA99D
+:10001000971BD12E9FA2E3BA0AD4CFB8023BA3E725
+:10002000A110AF0DF0731C22DFBF597A9CAF9B0665
+:10003000D8ED725957853F69587679213FD2494F9B
+:10004000EFF6D9E4C365956B2A9F379D9A7C4E6580
+:10005000726D927FA82FF21CFDE41A8EF304B0E4B7
+:1000600049F9879C8F8985F2B98CA7C15AAF4EF8A0
+:10007000CD552E6B181F990B5A1EF29F7FB20A297D
+:10008000F4BF141E35D105DB1F5D5AB91F1D25F0C5
+:1000900072CB7E22E866F21A9ED55AB68CF47BBCEF
+:1000A0009AC5DF1768E4BFD1BDE7B392CB574FBE07
+:1000B000EA3E7A6E1A27FC340CF9B84AA6F70856BD
+:1000C00094333D2EEA9DE7966CF7082CFB365DAD28
+:1000D000E1F634C18F522E1B68077C5AFE503E2138
+:1000E0007FE44CB5DB05A74BAF89FC5EC5A9F2C721
+:1000F000A71D4FD0B5B75C2DE6746DF0A2DDBF2C07
+:100100003CADCF73D4DE745D4BE9EA2F072399A190
+:10011000FF5AB794317ED6B93F72DAEBCAC09A194A
+:100120005BFBA25BA1D32E63FDFA162AFA5F51791D
+:10013000A91A5D07BCBCBF15FA5A13D793E36833FD
+:10014000107C28895129D49F500EF41C111906CF18
+:100150004D7DBA41F7E17405AA49C3E72E956DE3D9
+:10016000A9857EBB5D3DC394ACF0FB16BA291C5E2D
+:100170001C0FF5B4C6CE3DD58038F774EC1F1D7644
+:10018000C3F2D2D119E30CD4CF6ABF3ADD0EEF2906
+:10019000B70BA8FADF2D7654F6762AFCDD624FAD58
+:1001A000427EB7D07F990B764B641D8E87AF8098C7
+:1001B0004EF258540CD086E978E4C3D11A5DBFB62C
+:1001C0004BF47C988AB48EFFB173A2ABDC3AED4756
+:1001D000F6C6289E948001B4BE7E6AE7482706B31F
+:1001E000B8A56112D8EA3FEC76D37215A2F43CFDB3
+:1001F000C46B978469BF06F9549386C3D9EF55EE53
+:10020000D8C36E6CA73178B001F5478C637E81B09E
+:1002100097B53B31B3EFB8818D285F6759F23C2E1B
+:100220000BDA4E2DAEEB0419B3B38AF2BF1FF7B54C
+:100230009060F6D0504EB3AD8BF2E9F7ADAD7DCB0B
+:10024000F9DD5CCEB770FBA81DED238BDCB7F3782E
+:10025000B36D12D8EE595478587CD63B5CEEB77A21
+:100260004D1FBDAFF0DC0ADF088C7739A8447C0451
+:100270000FE5D71AF9B13EF05091B0CBDBE9C67764
+:10028000BCEACE1CDF91ADBD88EBF8B478D9C6F7D7
+:1002900031159ED971BA6F495D44E5B398F34DF1BC
+:1002A0001CA076ED5013923AD6FDE82458F983FC51
+:1002B000EC433F454903190BE915930DD41F251B4A
+:1002C000DC4999CABB763BB60F1F5458AC21188144
+:1002D0009935945569FBB0F2422D8ADA706E9FC150
+:1002E0002AFBBD8BD245F6FB52258E7B1261B4EF03
+:1002F00042E877B5D42BFBF4F40879083DCEFDFC39
+:10030000E9D1AE1A7ECDD2BE5C82684786FECA3D78
+:10031000CCEE285FB39EC5813504E07531DF6148BE
+:1003200057231F17832D89FB16E3399BD9C0E26B36
+:100330000635826CE5E3319E1CDA8F0B0CF32C82C0
+:10034000B7A5DFBEA2EB19A4EB44B0E9B10CFA6388
+:100350008C87C88BAB90E98FF6C434967EA4D0F519
+:1003600023BC08924B08889363B1C52EA4FF1CA040
+:1003700071E8E186E6BD185F5DDC08111C86F015AA
+:10038000E5AFF00C481A945FE06098F0C76036154E
+:10039000188C7C81EBCF02465FC117258DF6FB36AA
+:1003A000E1067BBE88DBFD45CEFB5B8E7E8A7576E3
+:1003B0000F4A5F2403DEFB83E9F6FB3661E87AF03F
+:1003C00001846F7F2092427E351DE338FA572176F3
+:1003D0008587E0F389EF4FFDE559A4FE8F16D5150B
+:1003E000205EB67AA3B9F45E515BE6B8B35EFC2A30
+:1003F000EC8E2CF5D37AD4B4C5353BD3651545378F
+:10040000CF2270AC081A40F59A7915D5EF0A97DF1C
+:10041000E78AAFF0623CE9D2C0E85CD4B37B314FED
+:10042000D2A5E111346E57F4A3F0F85D918F737D7E
+:10043000EA1CEF160FD3A37F07E316C4C3284F2C83
+:100440008CF376858B1E9FA9D3F3422399A1DD758A
+:100450001E3FB32F75F59F56FC93055CA372087081
+:100460005AFE85599E581BF2A75947B613C8FFC3B9
+:10047000201947FA3727B8DFBDA7DE6A5ECFA47E12
+:100480004F512F9600EBBE93D45B8BF321F50C5BA1
+:10049000BD68AF7A77F17A601BD7E835EE66011F49
+:1004A00058FB8BF4EA6F2BEF8FDA833DF5F45EFD9A
+:1004B000DDCFFB336CF5B45EF51E16F0D9C605FB37
+:1004C000B83DE5E7B89371AAB7593CFDBE8A2994B7
+:1004D0005FF6574CA99F45C6B9F9172EAE23AEA1BA
+:1004E000EBB6E0ABBDBC5E2BF25515DEC385B64660
+:1004F000BC07CCEF09C703D3BC31CBF71EBE0A4CF7
+:10050000D3327F9F65ABAFB6F9C01843BFD3FAAD06
+:100510001F2BDCEF9D3719FD71CB0B65EE9FFB5B4D
+:10052000DC50891E1BA0DAF26D61563ED2FBB7B8D3
+:1005300089778AF83D18A22B9FAEB2C877CFF89F73
+:1005400017FCFC3C230DFFFB71A3DC0A3FCB0BF82F
+:1005500045DE5BCCCA47B7BD3F092F56897B00C338
+:10056000DB0A5AA9FFE20B3B3FA9D53E3F964FCF8E
+:100570008FE5C5FCAADBA4C9FF5AF3CB6DB5F31F09
+:10058000CBA7E7C7F2627E356DB9A7353F673DBCA3
+:10059000AF847A7E45C5FD615C7756E0424AFA1D1C
+:1005A000D7F6527C31C9DF3E40D8DB3AD5EFA3C045
+:1005B00038C73BB6FF76BFC2E037D2D61B64E7C16F
+:1005C00050E1E6E7C18930FA39DFF0683C8E8EC130
+:1005D000A978EDF9A1981F90CE935FFE89EB308644
+:1005E00029B2FDA443CFF7B3AE2D2D66EBC9B2609F
+:1005F00044B6AE6B220EFAB9013554FFC435A67F5E
+:10060000F60EE0FAA890AC6BCC9F47EBBBB8BE5A95
+:10061000DBC2DE0B48F0FBB0F1C2D1143F09711F01
+:10062000D69C62D36FFB6AA71C40FFD5B183EC9DBB
+:1006300088A7BC6CDD5BDA021DECDD032FBDD7FDA6
+:100640002CE937462AEC21F61EA63F25F61EA6BB4E
+:100650005BC234FD498B4ED39D645C4C1F6D894059
+:100660008C8CBFA3651C4DEFE2FBAB0D682F92F4A1
+:10067000CB8532F55B6C6D2196B20BFDBD5E9ADECB
+:10068000DBA2AD522BD0DF1BA6F963D2B4EBBC7456
+:10069000FFDA15CF25703EF1BB727A4F7C62A14A1A
+:1006A000D75F50534A6E75FABBC0EB31A9AE11DB70
+:1006B0005D1096593D6F321ECA5CEF46AC372EACCA
+:1006C000527820602AA1C28CF5BE87FC5513E0FD4C
+:1006D00069B17830737FB7617FA303BCBF423D1E11
+:1006E000C8DC9F89FD8DD4181E20DCB5242773BD7E
+:1006F000A558AF4AE3F32D4DC93999C7BD1DEBE5A8
+:10070000E727E8FD9D8BAE066A8FBA0AF5ADD46780
+:10071000C1EB25074441267C9E5F9068C67A17C6C8
+:1007200022308C8CAF872220137E7605487915DE27
+:100730002527FD9074C274528EE74258FE254B392E
+:10074000B627E9F819BC7DAEBD5C8CE76A839EFBD9
+:10075000D37869DCD56ACFE7C94C3E1F6ABB6A32E1
+:10076000CA7D1E3F7FFA35E6C9B8AE4520F411AB0D
+:10077000EF67E5CF88FA2156FE1ACFE7E7B379FB9A
+:10078000A67869BCF0BDB78C289E55959EEFE0EF2A
+:10079000559E3DCB32BF7BBF7741F1AC407A3E8363
+:1007A0006F9D78F6AC3EF63D05F572CF9B24A8B759
+:1007B000F21255547F8EF244A97D386A608D81F221
+:1007C000ACAC6270BDEB2D6B5DA252B84C7A4F930E
+:1007D000C375CF3C3B5C83E6DBE1BA67BE1DAE412F
+:1007E0004D7DC3F59497E9B56CF091F10DEBF85B95
+:1007F000FECD3EFE90EFDBC7DFF27DFBF8436EFBE4
+:10080000D4E3A7AC74D97CA37DFCD29BECE36FBE90
+:10081000C93E7EE9CD9F6EFCCFCA1EBFD01BFBA791
+:1008200097DBBB8AD5EE6C8ED9EC5352EF24AF67C1
+:100830002A563B3616B3D9A7A49EEAE3F6AEAD5EC0
+:10084000B4573D9F8FDBBBB6718D5EE386787F2901
+:10085000D9DA5FA4577F05BC9E295BFBD37BF517D4
+:10086000E6E31AB67A5AAF7A83057CB671C13E2E9A
+:10087000F038B05B791C189577527FE1D5649F5DA5
+:1008800086FBD0A884FB7DAD0046EDC7FB26C3D90F
+:10089000BB477953160EC5F55C9AB2F02C5CFFDAB3
+:1008A000F2C0B66F9BE2637E84B13E85A65A0E34D9
+:1008B00053FF9DB7B9F872CBBDD72DBC5E4F79A061
+:1008C000B9F81B96F24B78FB367E6F70B2EFB7D457
+:1008D0001ED10691FA19FC66978AFE783914463AB9
+:1008E0000D02F75D574D1B6BD5CF5B7C2E3A7F6DAC
+:1008F000281FB734335C6D656CDC7B71DC007E17C0
+:10090000F6477331C5B7C652F17D4370B6F457C48C
+:100910006ABB97AEEB6EBEAEE7B99B1F282370C4CF
+:1009200007CB80F7229697F6EDCF696DB19F2FA880
+:100930005AD4C07D5FC91C6D348A47B67677D7CB51
+:10094000F599CE1F1AF87C5AE7D425CAC9F8B0DF4A
+:10095000EEC7250C0ED6FBC857B9630DBE4C7EDC26
+:1009600056AFCDBEC92B9A960B7DCC23DE62F7E342
+:1009700012D56B64A2DB4A1F3F1F39E8B5D95B79FA
+:10098000F932DD771EAF62E7066016533F610F5EF6
+:100990004BEABCD6F15738C6F3C13403D7015CA685
+:1009A000505EDCE5EC5D157F61422BD3D17FD049F1
+:1009B000CF0381DF7713FDB686A7D1FDF8717E0FD7
+:1009C000560D276A99DF91C3A7715DC5C729D9A8BC
+:1009D00042AA808CED8AADF48DB5D2CDA4F74B4EF2
+:1009E000B89297D2F79ECA08FDA5DEF3BFD3C7FC25
+:1009F000C577EBD37E5B9681BEF7A0B3D8D26FC923
+:100A0000876E488DC95E3F5D8FC1D5C3B761C2AFE8
+:100A100028FF3AE75BB7F1235FA6780BA11FF839EF
+:100A2000F8AC71C07FF42BFF44E671FD01177B77B2
+:100A300041DCB7E1A5D773BFE92CEE776D8068087C
+:100A40000BDF05B91EE5EC5DF85D688C85FE4FFB9C
+:100A5000DC0CAE3617F5778973DF6B132E9B3FECFA
+:100A6000BA8DF6FC6C9856847A6BF67A17F5AF5D02
+:100A7000EFF0D33ECCE77B1D342F433B5EDCDB9EA7
+:100A8000A5818AEFF2CC7BF2DE1ABC1FB5CFC7EE90
+:100A9000EFBD4DF846B7C8DB0D81A41BEF01BCBE0E
+:100AA0006BCC151300DB279795A0BECD838CEFBED2
+:100AB0007DB7CD0E5F7FF03BE10558D2271CEA766B
+:100AC00029A37FABD327CE8919BDB2C57988B88B4E
+:100AD000639C8F7AFC307FCEE17E18167FD15FFB5E
+:100AE00013FDB49FE7ED72A3FC34A9CDF5929C3EB3
+:100AF0009FF2B862C620324FD7EEDAD420B0D56B61
+:100B0000EBBBDED12940F5657314F948D49B0FA4E3
+:100B10001ECAE59ECB4D5BBD72526F78F67ADD5CE6
+:100B2000AFFE7CC7BFBBD11FF9EE43872E43B99CF4
+:100B3000FBB4025E326EF78E20A4E83E36E9C6FDB5
+:100B4000DC0DBB948CE7B9346280F43FF7C741BA3F
+:100B50005EDEB0D3939C4ADADFF093D74702C143FD
+:100B6000F792A3CF0FC275F721899DAB9A5D2371D0
+:100B70005DBB4185EF4433F437C0CFF8F0F0533913
+:100B80003390CED2F6BDD7D07E3BAE74792CFA220C
+:100B9000E077897ACC1FF7A044E3A37BC3C7CEC11B
+:100BA0000E3F2831F876BB923E846FFB56778CC09F
+:100BB000D1B4FD3DCA57937EFC4808F1D0B45BB177
+:100BC000F9899BB62B29CF489A1EC214CF57A41A75
+:100BD000C427D38FF377CDA3FEF3F91D2BDF534248
+:100BE000D8DECEDF042F9114E2F525253215F38FE0
+:100BF0003F10D209AADEEEDC1642BC927E67BA73C1
+:100C0000F11CD8EEF7C6FE3FCCEFDD1FC05137F226
+:100C10005753C70A36DEAEAFBD81FAA5C921476F6B
+:100C2000E32FC5BDCF5D2EF43BCEC1B6179C927DA0
+:100C300039F791E35B4C32EEE19DEF6C3109FC8DAD
+:100C4000FFF5FE96DBD00E7AD6A7A11E687AE83FA4
+:100C500042605937AFF43379EC7EF081FBEF26F236
+:100C6000D1FD470F5D3FBA9F7963884EE6DDFDD821
+:100C7000FF29D249FD05CF5C4CFD050B9E9834B091
+:100C8000AFF513F935697D978CDF3FD77793710600
+:100C900092EC1E9E3AE8F3DC2E057C04CE775FF6DC
+:100CA000D07B524DE4DBC2D148AF79542F637E1123
+:100CB000C1F3FC1DCBDF534666C2B73948C64B07AC
+:100CC00040C4308CF4FEC6D72FACC6D445CF579A5B
+:100CD000E028D5ABCE764D07095DCFCB4EC7E3F00C
+:100CE000911BE3569A76AC60E376103A867AD3F19C
+:100CF0005DFC657C6F3A7ECF41C7E3D0F8233C1F93
+:100D0000845D0519CF85C5F9D9BC27BED9A7BD25F6
+:100D1000F4427F789E2331B8EAFCC6323FCAD7CE70
+:100D200087EFBFBB90D1792A414CF723C78700E1F9
+:100D300093375D47AF41FD78F4198F86EBFD0DCFFA
+:100D4000BC44E5ADFB8917DD3AB5BF2120117BA37B
+:100D50001B7A7E3AD1FE982FB14C537B30E509A522
+:100D6000E9353F7979BD1EA2DF0FD1EF492607F3A0
+:100D7000937BA74B19E8F7AC9FDDE786E4008A97E1
+:100D800079ED7F72D373700B5DA57148CF4353F03B
+:100D90007B367A8AF96B38FFF32D746D67F29B4DC1
+:100DA0004EBBB77A548C6B70D2B9DBC5F6094D498E
+:100DB000E9A54C7417EBE0E99EAB3EE5946F3EEF7E
+:100DC000FEE4BBFFF99C1EBEB6FB751BDF08BC1D15
+:100DD000FE28B3DE3FE897381CCDF525C37BAF83F3
+:100DE0002A44CD416569780FD3B7C948FA9042DFEC
+:100DF0003B5DD6F11CD5DF4E3D313F8B9DFD37AEBF
+:100E00009FE6EFDE3B12F5D9E17D4F517E9CBFE3BB
+:100E1000901BF737CF6F7FDCDD5595E67F5C17AC15
+:100E2000EF5B1C7E74EF48AABFB1FF0CF439C6FB20
+:100E30006FDA63EFBF69C77BB6FEE79A1D6EEA5FA4
+:100E4000ED679CB755E34A9CEFDB9D2EC07793DEA0
+:100E5000EE50EA33D9412FF175B127AE2658F3325F
+:100E6000FA27957CB78EFAAF75B1F112BE9B68BEBA
+:100E7000E862EF56AAC6CB1E229FF13CB78EFBDE7E
+:100E8000D6E015A05BF478C2814FAD50ABC5FD80B4
+:100E900036395A6DDD7F09F8F30CD906FF8260FD03
+:100EA000407CEF0AF7713ABE53A14698FF3A34A549
+:100EB0009EDE7BD464CD9771DD66FDA1DF0EF9DF88
+:100EC000A5C9A05BF86BD4A42BCE45979D0ABA6D3B
+:100ED0003FB066323B0F16F35F33183603D1C36B56
+:100EE000A4A307F09D08F352166728EC3BE0FBFE35
+:100EF00010EEFBCB7ADB7B60183AEA23AA8E7436BD
+:100F0000BE61B9E79C8EE3055D56309E39423701DC
+:100F10002AC468108617E36C87E3BEAB83A601A2E0
+:100F2000DE309D98338CF1371CA5F9B5F57FA171A2
+:100F30008F8539D1513903309F2FB179A4E83E4FC5
+:100F40005CE397734A8BFBD20730593D6CF52779E8
+:100F50006033DDCFA03BF364411A2F22DE4EF4BB99
+:100F6000C63751C2F508E73908DF69C3478E2CEF51
+:100F70007088F8C90122EF18076B6A357C09A6A2B0
+:100F800019935CC3F17C3F21E1FC4AA083A6A5D064
+:100F900049D37CAF26A914BE57A9BF4B86BFC0C991
+:100FA0001C077CA760C73BEDEF5B15FD9518A1639F
+:100FB0009CEF73EECBB3C7237D3B87E9991B73642A
+:100FC00011FF1CB3EEDBE2D04871E02B64CF93F548
+:100FD000C8414EECDA1C0B9F29814E165FE6D82FD4
+:100FE0005FAC2CA2E7FBCBC37DC7752DC5F8F0B372
+:100FF000B297270678676E050A3FF383495E16E7C6
+:101000006D80AE59F91163796AAC719386ED3D1D1F
+:1010100017F2A182783669EA43B922690EF215A166
+:10102000C34ACE8741E8E29D1CA5FE8F2DEE581CD9
+:10103000F97060794C62C1445189F9D50CC5CA0771
+:1010400072CED5C57DC56DC174C22796B899FB38DF
+:101050005D541554FF68846733A7BF933FED71B0AB
+:10106000C2AE0BF09C87C7E3FDACFA77F4FD17B571
+:101070003040E35F02D5AD37E2FBAD2A346BA857B1
+:101080000322BE25C2E216C5BEDA57698F17F538AE
+:10109000E2635D7CFFDE2B5E9CAFC777E0870C765A
+:1010A000B3733D7E3827739C138CCB1C9728ECB40C
+:1010B0004FCAFF62FFD9E8ED7C9E02A11934AE53FE
+:1010C000E57E8BDAE91AF5B71FD921B1F7361CFC9A
+:1010D000746467EE48D49728CFF87E790EFF2EED22
+:1010E000D8BB17EDABD6101879F954FFE90AC1FF48
+:1010F0003269945722E9BC5DEFFDE669F4E3EF51F4
+:1011000000DF753B42E6D889F3548D3C245A0EAC7F
+:10111000B2D1F993CEABF7392693BF9B34217F012F
+:10112000DAEED80E89BDF303E7DE85EF5D351D707D
+:101130004192941F03D6EFB1CDCC6EB8EE178FD786
+:101140001049808D1C1E5CBFACEB4C41BD1F740B65
+:101150009F84C5BA601A9DF8DE7303C7CF8068BE4E
+:10116000AD9E98DF3BB3EA0F50FF4F8CBDFF3C7044
+:101170004689AD7FE0FE119DFC43BEECE5679063C0
+:101180006EA0EB4A343745ED20B29FC6FD47528A28
+:1011900020DC4E7FCAFCDD125DCFAE27EB19BEC747
+:1011A000767DD2B11F75C45309FC3BF9560E703BD6
+:1011B0003200812C788EA4AAE9F92C95BB9B7EA1E4
+:1011C000507BECA647A4248DA7EE3A2B1728DE15FA
+:1011D000EA977A039AEF242B4C9ABF1DF8F384ED1B
+:1011E00078F7E976BCE754DAF11B8CD8F1E8C473E0
+:1011F000EEB861B6FA73954637653E8EEF4AF20F48
+:10120000F14DF4249DC77C328F94DE1B9F73F6ACA6
+:101210005986FE927EF1E8C0DF390EFC1D873D7BCA
+:10122000592944BD4596F84F3545E5CA2987024FEF
+:10123000A55A672DFD1609523F7598772235B0766D
+:1012400025DE0E2654A323540E459C724ECFBAFAC7
+:101250003A9C24E9CD97EF3F340BB2CB5D478B37F7
+:10126000D2E0C2F371883454E079B946D3CD58FF47
+:10127000BCBED65B838EE7828886E91DFCDCE44831
+:10128000157B17A923F54111DA7F778C3E7A19DA9D
+:10129000FD4DD74294BECB1464EBEF2E9E4E0EB2A2
+:1012A00038EBDBA33218E82FD8A32425F44369C612
+:1012B0002F2E42BB6D8F4BA7EB9F76F437FF8B969B
+:1012C0008FD1F01CA3584E8CC271497DEAEF3FB21A
+:1012D000E7F5D0772DF651F7EE7567E3FAB4498656
+:1012E0003999F6010D01367E77E55F8A902DE77911
+:1012F0008FD27DF9F22EBB9FCDBD8BF9E1E6EFBE1B
+:101300009CDAA3FB67B3F7389F38CCEEA54E51AEFD
+:10131000FEEA97487EFC7FF0778CC0983AB38885C8
+:1013200072203DE33E826782C7F53C7EB3E9AF326F
+:101330008DDF1C7F214828AFE3FF08111351DB3CF0
+:101340009BAE574F87A61CC074F21E89FA8F9A0E67
+:10135000B3F56D6CA7DD4F74FE64A21748FF357BB3
+:10136000987FABA68B9D0F9CFFB2BDDEF82E7B7ED7
+:10137000423FFCBB24C0D7AD10149D4E7CEE1E979F
+:10138000B122C0CED3E8BDB2889A79FFD515647674
+:1013900018C1079DFF91A3105942E671A4A1A4169C
+:1013A000EF291DF9809D371CF948A9CFB4BFDA1287
+:1013B00060FCB2C9CDCE8F37CD0E24179379EC9B4C
+:1013C0007DC350DC57FDE3DF6243B5BEEC12A222C1
+:1013D00064BA261AB9300EE5A395DD77834471A669
+:1013E000F793855C083911F2513CDB1FCBE4171DE4
+:1013F0001664FBBFBAD99512C66F773F2BD133A6BF
+:10140000EE2504AE3EF068C29241084FD3EEF7A934
+:101410009FC2BB27B3BFFBD94088CEBF7B89B978B9
+:1014200002C1D7F788709B280FEE4459A6FE4D588D
+:101430004FFD57DB028C9FBBBD6C1F0E6AA218DFED
+:101440008DE8DE3DE9D26504CEBB89FCE1FABDC979
+:1014500015A1709BF380BEFF07FC7E61E965B0F5C6
+:1014600076CB7EED40A0F620D2FB6080C51F15C470
+:101470002212C21DF9F84408FB3FF2A187D2AF84C3
+:10148000FB8B44BB23017E0E17347E43F9654E214E
+:10149000558A915828D23006E0BCDD04DF16FD9D48
+:1014A000A69B49C7C98F01BD479F1F90D97918D9FD
+:1014B000A7E1FEA309C48F49F72B42FEF0D29B6A35
+:1014C00089BB97F648A920D19FD5DE400AFD32F9A5
+:1014D00073647C8387D8A35ED65FA7DD6E450D8CD1
+:1014E000FA177500D03CDB1F097D2CF4786B1ED3F6
+:1014F0007FAD6B54AA1F37AB5D3EF44B97197A9DB5
+:101500004AC6CD57751A6F31780E93F79CE1F7E60E
+:10151000F5D84513001EFB58C9E81F392B28F015D4
+:10152000FB07E26BE481A3FBD0BC8AF8A000E93D95
+:1015300085DB3DE3DF65FA48DC3368EAB94760D70D
+:10154000479B7CDC8E81C4EFF1DCFEA9BFAAF4FED0
+:10155000408FFE993D85AEA7A0543D87FC35E157ED
+:101560007C7BC0F50FD9ED51BC9CFF422C8E7038AE
+:10157000F5CD38207A49EA5FEF38E94C8CF09E7C53
+:101580002941CA980344CE2CED9D7A6A6090AFB38E
+:101590005C4F1D8789032FD6D3FC347A61E4398FE1
+:1015A000857F849E4AF35392E2D5398E04DE9EBC39
+:1015B000361CF5CB0B0AFA518ED4B2BFF393E2720C
+:1015C00094F741F252E487F57B2EF121DFEF3C30B6
+:1015D000C98B62755398DD3B53F74E3781B38FF556
+:1015E0005CD9055E3D5089F890291E148DE42DE3E9
+:1015F0001F4B48FCDEA59E3B3DC3FBD822BD29CC3A
+:10160000EE95ED3C302C97ED475394EE3D7CCFFDAD
+:1016100017422E04BF3BF95BC8439CB4922D7684DD
+:101620002275F0FDA3DD8F10E776445CBC3F6316A6
+:1016300053FB7001B70FE381112BF1CF1CB4A6EA65
+:10164000343CF758101C46E3AB170C60F873E243C8
+:10165000A44D1F127BD11207DFA41EA5FEB1A60F59
+:10166000DDB6EF02BFD9F022F07B01E257FAE4F8D1
+:101670003D3FC8E8ECC4F3A79D7FE94DE332DEE7C8
+:10168000FB5799FF04883DDD45FDB1EC3E89E0370D
+:10169000A13F6A6E6E8BE7E8697D21EE8308BD236A
+:1016A000F4CBF98D89E77232E80FA7DE88B8B4EF82
+:1016B000AE22F88BFC2C40DFEB70EA910FF09762C2
+:1016C000EA77BB2748E07DECF9B765F49B3CF15322
+:1016D0003277521ED93B99F9053B4FEDBC4BD8AD43
+:1016E000C25E75D613F6AA5877C479D3AF83B18793
+:1016F000707C693791A710C6C7B27DF28140EC11AA
+:10170000FC9E4360F6632C6065AA8CED67EDF29A4F
+:101710004D3E731CF2D79152D93B3201F62E9413F1
+:101720000E317E4390BF2B40B80EED9AD21A6083E3
+:10173000CD67EF06948E8418AECF78BD14E7F92BF1
+:101740006E97BDC0D71B911E0844F723FC2E154C85
+:10175000CFE84F0EB7F02FFE3A68ECC3FEBCF5069B
+:101760009DC7200D2268EF0F523BA4088123BF5173
+:10177000977A9C3D625D27FD0D9AAAD7A21C0DC2E7
+:101780003B05581FEDA30CF4F97390C535CDF376E6
+:101790003D8F267CD3D4E6FA501FE7EBE9F7102201
+:1017A000DCCF658F0339F2CC4B83F1FCF3B51FBC62
+:1017B0001FC473ADFF548F0611CE3717FD3E88F757
+:1017C000215E5BC4F61FD738EC9CE31C7FD343D16A
+:1017D000C341927EA7E5E31ADB3B240BD9F9CCF594
+:1017E000490537A53DFC3E777B0EF5ED89FCBC8EA7
+:1017F000025B5EF0E93C0F8BDB72CEBF2AC4E2686D
+:10180000AEDFB1D53D48C7F163FF85E3BFC9EDB891
+:10181000377705A9FF43C0336BC72837E2E13FF7AD
+:1018200078F8B97FA78BE1DF988AE773314E0A27F2
+:101830009CCF3F9B43FBBB768342ED8E9964AC8586
+:1018400084BF637BAEA7FB70E73CAE7D4D9F3290BB
+:10185000D0EFDA1512B557B1FE22C20FB185CBE930
+:10186000399E739E334D47FC08B72B9C7126D7EDEC
+:1018700061E7EF0DA0AF9C589621EE64CFA5F4DC94
+:10188000EDBA7EF63D65216E4FD4C0F918377F1C46
+:10189000AA7E58A5F7BFEF79B3056810D9DB2D5E96
+:1018A0009A1E6ED158CAF5E7DCDD7B9FA77CA67631
+:1018B000D6A0DCEF3CF07ACEB7F4B41EFFF2D6F738
+:1018C0009FBB87E4C700F3F3087FFBD51CEF1771BC
+:1018D0007D7E1DB717C67CD8B73EBF1AF131B2372F
+:1018E000BC428F5F8D7F6FD08207A1D79DF838767D
+:1018F00060780EF2C7E490F3BCF9D3E1255BBB79C5
+:101900004AE67846214787838CAF1BDA2F5F564221
+:10191000C68F3FF3C6902EA6270EA29E107C0AD03B
+:10192000EC463976F2A3E0931EBEDBB39AE249F0AF
+:101930000791AB303FE70CE3FED0C97FFDC537759B
+:10194000BBBA86A05E70F259B7E35EB448AF083107
+:10195000FF7B836E4CC1FD2A596E96B1F340A68F72
+:10196000DE5413CFDF86F2DACEE465DE938FFC041B
+:10197000F5D00D3FDE10423DF4969A28C2F11AB719
+:101980002D0DE1B9FA9BAA19C2F66F25958CF18F3E
+:101990003B4292784FC31627016DE66528C7FFD8F2
+:1019A000E6D2F01CAC69BB879DBBEF6278237976E9
+:1019B000DEBE2B739CC40D0F6C28D259DCAD3D5E8E
+:1019C000A2DD45FD17E85FC361B29D17F79C3F7725
+:1019D000F47D9EDEB48BC7D9ECBA3463BC84884BEB
+:1019E00070F2F16607FF12FC50BF9F49E0A2EE764D
+:1019F0007E4E1E7FF0AE9187087C87DB7F1592AA12
+:101A0000ACFE78761E7FACE3BB3FF2CAD9F9B79B38
+:101A1000F37BDA9E48668C9F6874A542B8AF6ADC97
+:101A2000EAA2FBC0C64714FA5E1DFCD143D7F3B946
+:101A30008FFCEC0F1710F8E63EE62A9CCAA641E39D
+:101A40002404BD7AE258387D6E78FC67EC7C59E757
+:101A5000F12C9C4E731FDBEBC6B81C273E2775ECA0
+:101A6000757739E22028BD3A0E4DA1F7091F3CE1F8
+:101A7000C675F6AD67251858D6BBFD9CAD3F0BA1CA
+:101A8000BE403CD138004EB7EC714BA9CB7E5A4DCD
+:101A9000EB51BF5D7F745C84B23896F2FBA33F25A7
+:101AA00070CC79C543E3A7E63C7A338D337A436D36
+:101AB000667C7FEFD2225C7FE7B8CC228DA6ECFB60
+:101AC0009C2DB7507EBCEEC55B8AF87DA462E6EF24
+:101AD000318B719ED76EFE269DE76C88517E9C737C
+:101AE000AF12453FCB7115EA1FCB2037237299DC2B
+:101AF000BC719F071FD38137B89FD3FC9DC2FF5E87
+:101B0000A4F3BC8ABD1B739CEFBFFF19EA396FF4C5
+:101B10005AF7634DEDCB3B914E6F0F36066A349EFC
+:101B2000403539DEE8FBEBCA8B170FE4FA8DBE7740
+:101B300023ECA049F81DEB77BAE8BB379676B67769
+:101B40006B16F0F109DC7EE93C921665F6837E3374
+:101B5000571271F02CFE46F059363DD0CEE2593E78
+:101B600038C8F40CC6E5D0F24E576AA02D1EC763E4
+:101B70007B17251D67E2E2726E2F2770D278991EBF
+:101B8000FC3E2B25F11D64C12FB3D77BECF1793DD1
+:101B9000FCE37CB7C71E3F739DC32E1369AFF53FAF
+:101BA000D7715EB7F9D4E2671A5D491AFFD4F847D6
+:101BB0000FDD9F343EE28A225EDED9F1DC1FBE4596
+:101BC000F8FE9D0E21C776BDEB94E3393BC7422654
+:101BD000397E2710818C724CBE6794E340FA5C43D7
+:101BE0008733AF77AFCBA277BFEAC027B11B723183
+:101BF0008EF8ED87E60EA5FE0A077E85BE75EAD152
+:101C0000D7433AC573EF783FB6EEA7E331191E0507
+:101C10007FDEF0F03C3A4E0F1F0B3E157C9C256E8C
+:101C2000CC894F67792EFACEC6F6F68B9875508917
+:101C30007FA729EE06F6DE9BEC8F20FFF677DEF914
+:101C4000DBDC32F1FEDB796C5FC8CE3B23010DFF9C
+:101C50006205DE9753329DB34726C919EDFF1FE495
+:101C6000323B09DDB2983E99CBF0D7AA44B923AFF5
+:101C700083DE63A067AB08675E88CA998BC7A990AB
+:101C80009EE97DF4488EFCBE4EFAB8FB87FB2F51CF
+:101C9000D13F3B46BE7938C9EFFCE1CB97A884DE43
+:101CA0009109F2E3C3487ED70FFFC8CACF93C7B8E4
+:101CB00008AB6E375FB96432C9CFE7F39E2FFC24BF
+:101CC000AD636D7E12553E74279EE7A83F657F8FFA
+:101CD0006825917BEFE8F439738E074C1FC9E7B88C
+:101CE000494AF2CBCA7EBF0C3791BFF2C736E652E3
+:101CF0007CD5E988E7C39A97C6EF2C78EA621A4741
+:101D0000FA642EF3479FFBF804FA771DCF201C0FCF
+:101D1000E60EC80E47AB8BF57378E7B99310CFE7A3
+:101D20000E459F5A9A1EA3559D7EF711B49BCCEE8B
+:101D30000FE3FD96789E9BF6F324E7B3534D45DC05
+:101D40008B92C3F842C9959B1F23E9B39C1FFE7772
+:101D5000AE26D621BAEF3EF2CCC0FBD8BB314787C6
+:101D600020BD15E5D89FD1DE3CFAED1CFA774B5E1D
+:101D7000F133BCBDE26778BB327795EB1CF27DB4E2
+:101D800077C8CDC8F4AF483B6EC174AB16FB25A332
+:101D900007A4B0DF6F5DA3B07E03CD417C374E3228
+:101DA000981D2E1166BA9AE0236E80EE1E8E226C6C
+:101DB0008FFF5094D1475374FCA06D7C2825EB26EF
+:101DC00091F32BC7337A11DCD275F4A5712C2FE077
+:101DD0009B911C16EFD2293C7F4278467992837101
+:101DE0003FF52D625631BEB7EFEBBBFDEC7CB31B6C
+:101DF000DB8F4CC70F34FD4DA6FBD9269C03C93F92
+:101E00007E18F8DF2B64EFEB08BFC7F85FDF44FDF7
+:101E1000DFD5BBE7B23813EEEF12E7F935FBD9F99E
+:101E20009CD3BF350156517D3ADEA14727ECFE2AEF
+:101E3000D5AFFD9DCFFD43E8D5122839CDF3B98F3D
+:101E4000734FE17CEEBF013359118B00800000001D
+:101E50001F8B080000000000000BB55A0974545590
+:101E60009AFE5FBDDA92AA54AA2A450804E34B02FF
+:101E700024210B45122004D42220D0314A8016811F
+:101E8000F64881B298AD98B4DB699D438520D2DADB
+:101E9000A319756CCE69BAE785D61125E92924D135
+:101EA000E05432C52204254E9045A01D3BED74231D
+:101EB000DA64313D824BF761FEFFDEFBA82541E984
+:101EC0003E67C8E1DCBAEFDD77DF7FBFFFFBB77BA2
+:101ED000DFBA4409600CD03F1D2403D49BF1970264
+:101EE000307C3C2311F200F47A00D9096054642854
+:101EF000C1F62AFDBB0DA06D338E3385FB6F252AFD
+:101F00006C9EFC53F6FBC1462DAC86828879ED7C35
+:101F1000DEDB652B4031CE7F1154533AC0B4BEECAA
+:101F20009FCFC1BEA1DB002ABD979EA0FB6775AA0B
+:101F30001F459B71ECD74521BCB435CE560053F1FB
+:101F400095293A50CC6C5EB88AFFE3947850B2C3BE
+:101F50007D4BB633AA2FC7DB764122FEF07B7A5346
+:101F6000508E227E0B12DCE3A3E679DBB6A89BE45D
+:101F70002EB2AFAF20B9134B32A2E681E3FA4FFA8B
+:101F8000B09F8D7F573300A643656208E52F844AD2
+:101F90008F84F2BA3F027708E59F718A8FD39E73D0
+:101FA00087FCB217712CF928FA7A2944F4719EC77C
+:101FB0003EFAC27138429EE9F604D7050BFE180FAF
+:101FC000E3AFCAA3E2E80E114EA76437AA01EA8F75
+:101FD000E12017B69F810A88DB3428480486AB0CC1
+:101FE0002AF6DF04EF0B73B0BDB279C871785218CE
+:101FF0004F87271ACFA445D1788EA98CC673EC8A57
+:1020000068DCC679A3714ADD3825EAFE4D9B0AA338
+:10201000FA373F561A353EDD5F16D5CFDC5E1E35EA
+:102020007E52D3D2A87ED68E5551E373D4B551F7E4
+:10203000737757DD90FEF303F551E362F53FB5E3A7
+:102040002751F396CAF7CA9011E6811FFF880785CA
+:10205000A462D23FEA210423F53FD3E527C6FFCD92
+:10206000FA7F98F49F1BA17FF9DE44AF356C6FB106
+:10207000ADA6D79FD05AC7905E714E14EE0AE919EB
+:10208000AF0D1AACDB256C1DC89D7BF1FA63667E33
+:10209000FD5181CF95B83495D6EF081EFD5AC21672
+:1020A000D5C2ECD0FFB1456D44DE3C2A2B0DC4AB4C
+:1020B00017E54A09509E54549D2E1379A4838D012F
+:1020C000E4F7B33ADDEACA08F99EB373BFF29C5D48
+:1020D000C7DA5F18D156F1BDA916F09B0BD973B4BE
+:1020E00036FAE7015CB72D8981822F2CDF3E7F0E07
+:1020F000DE77F4652B0E0033F56F01381FCFE53D19
+:102100001FCFE55C65521AFBC87FC8EA2492A7D9A5
+:10211000EEDD69C7F79C979E30E09BC1E0F21BC8DB
+:10212000EE52CDE0B7E1FB1A0DB0BA12FB0E7049CA
+:10213000F5D826C24E3BE18B622857911487AA72CC
+:1021400013FBF0FAFB24D138B231B70E6600ACD4E1
+:10215000FCE1C61CE60F87718DBDA450BD9208D866
+:102160000E3F90C9AE9FBB0FAD10EDE99C91E3A16E
+:10217000E17051F8C9CF379B597B69B33DCA6F6E87
+:102180006C7E2141C179CE65C3A240047E5D84DFAF
+:10219000746A6586DF80FAC764826770DDB7934929
+:1021A000689FD4BBCD8A439EDAF10F95807A30B612
+:1021B0002DF1A34E60A55161E3B5797CC1B94038DA
+:1021C0001063E9FA3D1FC22692EF9E6FB18D785FD2
+:1021D0008FDDC0DED743EFC376393676C46D39EA7A
+:1021E000C541EDD1390BC82EF07A48C2FEE26E30FF
+:1021F000903D2CF1A61B489E93E03EDD8EF29CB5EF
+:102200002BECF91F42A581E43A735F6D028DBB365A
+:102210009F360F0AEBC078F2A1C36F4846BF3574F2
+:102220008BE4DEA5B0F799E97AE5BDA94F5A95F0A0
+:10223000FBCE80B7FF34EA7B29B8D9BCDAFC6879D9
+:10224000517EF18D8DD5BF4BCA207FA80333F9C3D2
+:102250004E13F3878355575A5FC2FBAB53FB6E3265
+:10226000E273E7ABBE9D4CB8ACDC218382FAFF245D
+:10227000C1FB07FBF4301EE71EF87302DD5F6552F9
+:102280005F7909ED00F698DCAF003DB7873DA78D7B
+:102290001BB0CFFD8C78072508D4ACEBDBA786FFFD
+:1022A000BCD773C612CF347E3D28F855FF5AD65896
+:1022B000E2537DC2357EF1FE2B9963895F3324CED4
+:1022C000CBD879BB905F4A16AE1B79A520AFBABEBA
+:1022D0002A4B223FB1EFB8B388E4D483F76AE4BA5B
+:1022E000F6BDBF2A97EEC359D70DC94BB6E947399A
+:1022F000EF012E678FB08F15C1A422D23BDA9DC5A6
+:1023000081E356FDC76BFDBF257C3AF7BCF2388DE3
+:1023100029BE313C34FFB4379EC7231071CE2D70D7
+:10232000C13897AD47510721DE4DF9C2F5FCD65EA5
+:10233000F20BC8AB2B3A747C99E4AF2A81FC82057E
+:10234000DC0AB5E865DE9B8D7A6C3CA083A7B16B97
+:1023500023A7A6F99F12ECCB3AEE7FB06F4EC1389F
+:1023600022FCD324C7BF2EDACAECC7635D3383B91E
+:10237000442657F1E1AA0A7A2FF4A21F47592BF1FC
+:102380008FE2C16CD874280EE59CB103F3031C37AF
+:10239000F32CBFAFF9F55921DD1A63228DFBD91754
+:1023A000B28D208A8E03B30F977F4AF3CE8688E7DB
+:1023B00046890FB31C7F5F7C98EFE0FE2190CDFD36
+:1023C0007B2014AFFAD3D9B44595F9C817278F1FCE
+:1023D0002D8839D9B1511AC836A31F5EE468DEBE14
+:1023E0007D02D26122C785FA8DF45B29623CBE96DC
+:1023F000371E9EC2FC21FC05A522BCEC42E61879E2
+:102400008AD1EE78307647E59DA123DFD8FA701D9A
+:10241000AD4EE5BF485F4398D7905F88D3F7191D4D
+:10242000A3ACEF4DF2AFC8FFE71C3A26AFB943F2B9
+:10243000A8F87EB3E20109D71067B74F93A5F0F86B
+:1024400032078F4BB547CEA719515FFDBAE3B63CB3
+:102450009CBFA6FD0D1B2E1F7E6CF3AE73E03CD51A
+:10246000E73E9841A10B199E569940386524923D4C
+:10247000E5EBC1AF2F1C29876F072E06295FB72315
+:1024800089B5391D125B9F2FC4D739D0D1E88CF4A0
+:102490001BD79EFBCFCEF1A4B73D636005F9E3FCEB
+:1024A00060D106E231C962405DBCFE552E9BEF094A
+:1024B000473ACFAFF5A0A7EB00AA6E290EDA63C0AA
+:1024C000E770DE81AF64364E9B37BF63AE6C471E4C
+:1024D000E5859A0E525E18173429A4E7B89781E370
+:1024E000128C637ED1D7B510287F1D74805BC2FB30
+:1024F000ADF1431F132F863A4DCA2E89F06B022788
+:10250000CEDF6AE4F133070DE10D6BF8BAF6BEB821
+:10251000E0CF81FC15F2C3A3D27D7D13DC628DC4B4
+:102520003D81C9FF4B07E7576B7C486725BF8F9CF0
+:10253000DCC5E40ACB09ECBD9A9C39AC0E68350EBB
+:102540005D78DCC5E4B2131F7280CB09C12CE515A0
+:102550007ADEEE61EB88B32B6EBF34522E5F01E65C
+:10256000C56877CF6E816B764E76EF8B0FF7CD68AF
+:1025700013AD1920FCC229968784FBE8B04AC2CF6C
+:10258000BFF1CF67B66F9DC3EA23BF8C7CB0609B61
+:10259000E0A47572FBC2B2C933A690E3E0469C2C5E
+:1025A000667EFFDA78E4BB95FA563ECE9D68B79416
+:1025B0004BCC6E80ECA64EF89987A4D085DB50B545
+:1025C0005F860E1628284BCDD1B7196FAB75C19712
+:1025D000F2F17E59BC3748FEF7AD8F7460C3F57FCA
+:1025E000FE5A9C5A817864EF6F4EF65847CEF7D466
+:1025F000D92DCFA792BEF74B0A228D79E1501AC987
+:102600005717FCD4E8C17661C7EF8D149F5639BDCA
+:1026100047C80E4A3A1AE6117EB3A0A9D16E657E6C
+:10262000D14B3C0DA470FF317C6AF2AE8608BC2F02
+:102630003978DE0243DE9BC96E82C23EBB28FFC1F1
+:10264000B65DE461ED0756662AF9E1E7FC703015E6
+:1026500070CE2D70389570D6AE0FAAFA45C4A7DC9F
+:1026600033E6D59E08BE5D10F67E41BCEF1F9DDEB1
+:102670008F0887EA039F186DB82EDF1F0269149F29
+:102680000298A7D9BFC32FFA62ECC6A71F32D2782F
+:10269000DF45607E04F5BA3511F5B4E74CC79435D3
+:1026A00056263F24E2BADBCF9998DF6C4FE7F6D786
+:1026B00070FA7201F9ADCB9DD537135EEF3B0C1A62
+:1026C000CFCBE2C99EF602F3639A3DE6913DA2E8C4
+:1026D00079C4F362EAE7B0F95A8DBDE5CCFEDA754C
+:1026E00040F6873C67BC479EDB29FFC8B323EFD980
+:1026F000F359CC9E5B7B31E061DF8F7E7C12EB97E0
+:102700002DA37E6BEF7C3BB3671D425B4876193A85
+:10271000C8E609604C23D549501999A796396C4CE5
+:102720005ECD3F563AB8FF0F642B896E5C8F45969D
+:10273000A3EC20225EF2BE88A72B9F37FCF4C509CC
+:10274000644D222E88BCAC4BE4C1E02D62FEFEC776
+:102750002296D5BF53BAB805D75BDF2373FF2F7816
+:102760007250E4C98737A7B03EC50B05F5341D5B31
+:102770000FFAD3199E4DF3D0C6A06451D3216A4BF2
+:102780002B03F3107198B3A2F790819B732EF1AFD6
+:10279000EDE00F72F5C4F77326884311DBBE19FA1A
+:1027A000F875C4E1912EC47F94B884CB61FC4304D6
+:1027B000181FAFC79B41A9EFAED96E4CF99F1FFB05
+:1027C000037D1CDA0F1103F1C87B7ECC4FFD28502E
+:1027D000BBD333D58938FE36C93BD589380E9EF830
+:1027E00026997C7AFBA94F6CE4EFDB8C9E5CE25966
+:1027F0005B06D60BA3F0738293F3A7D8149DA76B47
+:10280000ED5227E7FF643F3C43FCA96B93ED2AEAB6
+:10281000BBBF4DF618318FBAE0F126EB11D28BE039
+:102820005F3E9BE2BBA87FD771D8611DE52F18677B
+:10283000D6BF6888AA4B6BC4BE4616F46D4B459C48
+:102840007C2F4BACAEDD18938FD450FE5240F54533
+:10285000B391D653F572CC3C94C714D0B8EFAE7395
+:10286000973AC53E472664521E833C62F5F4D06910
+:10287000D9BD8B62A01EBA4DC8DF3D3A8E13FA4D0A
+:10288000668F5A3E637279E691DDCFD3E28AA85B08
+:10289000875A2595D9CF6EF4F3D82FBDA83403C736
+:1028A000E154CA0C5A0FE765A99E8F2F0DA633FB82
+:1028B0002BF1603D8FEB5E8FF5BC4AEBD6F23CD539
+:1028C000C0D68FE197E579B3406DB4E1B80DBB2573
+:1028D000B6EF53BDDB1095E7F9043E353B4E1CA126
+:1028E00072B23610735FE0E38BC1E70DFA316B24EF
+:1028F0004E8F3A45BE97066991F91E743B47AD0B62
+:10290000347CB43CFB4F069E5F7C20E6D7C6FD8B33
+:1029100093D7E7751E60FB4735AAACAA3C1FB4AE3F
+:1029200041BEDC2FF872BFE08B0FF8B8DADD921AE7
+:10293000A278F533AE7733FE112EEB026B16A42A84
+:1029400023795525F0D8D86260F92FC02623D9E71E
+:10295000C69D31E3042E5531B8D479A518F9783ED7
+:10296000FEB7CA576DE0FB35D5C82FBFF2FF276F02
+:10297000ACFEFE5DD3DF149812A5BF454937A4BF56
+:10298000D83C79EF9129167A7EB83B83ED4368BC39
+:10299000899D6781C8B317EEE0F9687FC73C4B3E5D
+:1029A000D553C7F56E09E729EAF95F5B3EE251D8D6
+:1029B0002943054E31182C7AC68FEBDCD73D71992F
+:1029C00082F1A1B047CFE24B514FA14A754D614F03
+:1029D000A1253381194F12D50B380F8BCF83C72711
+:1029E0009ECC233FDB3DBF98606F385E68A13C62A0
+:1029F0001FF07D0DA9A738A92F22DE743BF9BEC6B2
+:102A0000B694FF7996F2FC857B0D6ECA47161A863E
+:102A1000DE9FEDA2F7EBDD0DD8AFE959BB258EF4B3
+:102A2000FE9AE4A674FC486FBDEB47A4DFA0C16E1C
+:102A300062F23E7C90EEFB5B24F7241CEFEBBC3D86
+:102A4000B715FB85CD456E82597B5FA14379A18285
+:102A5000F2C5711656C72FBCC9C0E2EEA5F1965F4C
+:102A600053BE54E5695E40FEF8D2DBFB8CE40F06F2
+:102A70005B2548C1851C4939F41B3FAEF3D29B2727
+:102A80008C9494CF6B3B61ECFB8E7CA25F9521C450
+:102A9000EAF72623D541B5CD5ABFCF487AAA14F913
+:102AA00055DDCBBF67FD2AAA13F07D553B6555C1A7
+:102AB0009F873ADF3212DE752D128C4D8FB8FFB230
+:102AC000C4EE6BBC5F0B9C076B857FAA16FB90D591
+:102AD000B40F89D7613BF7371AEF1FD8BDE40885DB
+:102AE000EF754DD17EE841C1F30D5497B2FADB6B1F
+:102AF00024BD6ED811334EF0FCC1EFE1B93549F871
+:102B0000F31CC8219E5F9ECBE3C9E513F1963C5CA4
+:102B1000D7E563B21BE03BF9CEE2EF71912F0C8752
+:102B2000742C9E69E3063AFECCE28DEFF8B091F288
+:102B3000DB05C12F983E2A8207E613DE7782B7862F
+:102B4000F0BB3368B193FD57F4717F501E34A9B4C4
+:102B50000F7E2704B6929E07BB5EDDEA24DEFC1BD7
+:102B6000E70D087FB741E0BA41E0BA011D7E12BA15
+:102B7000D8AABC032F61BA0FE5C0FD507940F8A177
+:102B80009DD13863E4B98FF4551734C1D378FF0E63
+:102B9000E18FEE68E1FE28364ED6897D80C171B99D
+:102BA0008BD97E2BD6BB94C7D5B444E35F27F605FB
+:102BB000EA62E2F0CD497CDFEEFBEAFF583DCD8DC5
+:102BC000D153C510E74F39C53D5C7F77684B1EED8B
+:102BD000DB6978C5EAA95BC94C1CAD9ED5DAF7451F
+:102BE000DEAFF517237129DF0CD89BAC9175FCABD8
+:102BF000493CFE54CD92FDA4E76BF5CEC443058A53
+:102C00002E5CEF609DB332690CAF7BA6E1D4472701
+:102C1000C8E07285EB9DA7525EA828A47CA585FB21
+:102C20009181129C2F91F27960FECBD76252A94E0E
+:102C3000F1217F589D43BCC1B63228DD4EBCC1FA9C
+:102C4000611DCDBF84B68E1187251D3CEF5932FF23
+:102C50000BC6B76313F97A87F5CAD8D1EA09AD8EE6
+:102C6000A8FB8AE7A9DAF53AB47B1A5F1794585D96
+:102C7000DC76F0EBB474F49F839D57D2D660FBA250
+:102C800058BF96A70E619E9A21F214CA9FD77395DA
+:102C9000C1064C871F431EAE17710EA4ADCC4EEA81
+:102CA00028D925BEB54B7C1F673F5E9889FEF78308
+:102CB0007896C70C9CE1E743F4FC1398470DAC0DE4
+:102CC0001C76E2F8CBAD128B7FEB31C7BDB570A49B
+:102CD000BDD70A5E36C01651976D656D79F6DE4F29
+:102CE0001E277FD46256C8BF0E74341AD9FEB21A9A
+:102CF000F17CC6C87CA856F0B7F67BF6B55E4D12DF
+:102D00007152F012D7C1F2DBC163B2DD2431FC7E17
+:102D1000353E122791FFB41D8C637A1E3C61552904
+:102D2000CFFF5CF0EF92D8776F2891192EBA59BC7B
+:102D3000CDED7A2B83F44A7AF0D23E4AD75B533CEE
+:102D40006C9F4F65F654BD5BA6C3BEB0FC010BDBA8
+:102D50000BD5FA1ABE3E812FCA35D9E80ACBD5AEBB
+:102D6000EFB3B947B11B493AC8F4A693A2EB5CDFB5
+:102D70007EB9528DB0275CCF6AF26FFB053F403FB2
+:102D8000944C7EB9334961F23504B99E759DBCC53A
+:102D9000F72FE7FB3606F6FE11F7CBFC3574FF7212
+:102DA000BA05184FBEF25750FF910C99F9A9473E4A
+:102DB000A8CA8288F783C4EB719F612899D5C3277D
+:102DC000744C3EDF89E1E48956F283CDF3ED79E47A
+:102DD000DFB87F389261D948FCF6D37BC786E759C4
+:102DE00098C4E33CD07A53289B7991CF2BD6BB056E
+:102DF00096321CB6089E75897C14EBA633648FB19D
+:102E000075D3F5F2DD88FA8D3D7F79AE72F247C851
+:102E100083C2637A3FD5EBFBCE723FD1D0B9E17765
+:102E20005407FBCE9B80FCC4235D1BB2280E83D7C6
+:102E30003B95F2BBCB5D0F4E65FB97D21626979F55
+:102E4000E44BA1BCE97432E543B59DA793595C6F8F
+:102E50009FFE02E5499817DD41D7315F61FC2BECFD
+:102E60002966FCDB77BC3829930407B785E6AD3DBE
+:102E7000A6AF247C6A8F15BF5741F94B4F19CB93EE
+:102E8000B4BCA888EA71CA938E4D8CCA93FA057EA9
+:102E90008307E2D8FE8704199C3F30318A3F356DA5
+:102EA000EFB07CA2A643F644F2E8DA732E3DE38D40
+:102EB000C1A5B0F91A029287F1632F6F6B3AF6B190
+:102EC000F5551B024CDF0D2D067EBF95B7004DEC6E
+:102ED000793F38FD84C77B7409F5506E5427D0FEC6
+:102EE000FABBE9BCBE88D5C77617DF4F78F79CF7E9
+:102EF00066E2CBBB73BD59F651E2861FCA78DD2D61
+:102F000009BCDB0C2CAF8C1DB7CDC5F77B6C491011
+:102F100075DEA8B5F52ECE9F7223DFA78ABD7FABE5
+:102F20008BD7CDF8EF191DF2E26485C1FEB4A82756
+:102F3000C6A1BFBD4BF8DB65771A58DE71529C33D2
+:102F4000DDA5F9DD121EBFB5FDFE253BE1492CFFD5
+:102F5000E14BC863E7604B3CD17EEF6E915F2D5B28
+:102F600014735DE453777F4F3E35C325FCE16498CD
+:102F7000CCEB06AB85F645BFEC36D86526B73AB143
+:102F8000327FE43A357F73449C0F75A31FA4B621AA
+:102F9000E743B64FF5EE8173BF71303F1A07197CD6
+:102FA000DF91EDD7D75E67BFBEE19A9DFE308A778D
+:102FB0009A9EFA29CFCF1BA9A7A502EF5AF3252382
+:102FC0003BB7844DDB7572F89CD264F07A52711D68
+:102FD000868EB9213ABF6CC831B17CA9FF764925EC
+:102FE0007F8F72A69922FC7DFF389E7F3DB25C6286
+:102FF000FBC207723E6471BC36D46B245E4D6E5BBF
+:10300000F324B35F3F9CA27A49D3E762338F9FD703
+:10301000F4A8AD976E2AB43EA79FFB65176B693C79
+:10302000C5CBBB447C5C5C12ADBF2CE85D40FB2390
+:10303000F77824962F5D4FEF4B574C7B87DCDF8D65
+:10304000EAFF9F5CDE875D64EFBDC3CB697FF7DD80
+:103050009C4FD328BED65D87CF7E81AFCFC2CFC570
+:103060007C167E1EE6CE521AFB101FBDC3BBD9458F
+:10307000FB4FBABFD8A600CDD3F7AB7A89F4030CC7
+:10308000FFEBD9D13631EF36979DDB8B8B9F0FC588
+:10309000519FECD9A04E203F01793776CED7B0FFB3
+:1030A0006801E969E0C0B10263843E2FD5A33FA067
+:1030B000F8D2792859B146F24D27F8A667AD242DEC
+:1030C0001571339A7F97887FA4FFBD87EEA2BAB0AF
+:1030D000BF6D994B5222E26AFB49DBA48879FB83DE
+:1030E000321B8FF5D8E4BB1322E57C92C9D91FE0CF
+:1030F000F301F44D5E961F79BF919F1B99FB188FCA
+:103100009FCADEC4CEDD351EEB81F3B8AE6309B0D5
+:103110003825D61D30E20FAA33BA4C2A9D53D07EF3
+:10312000BB23C24E8E0A9C67627140FC9C057E994F
+:10313000E69D8933DE4B7D3D84E84C6E3684647EAB
+:10314000DE3D0188D73304AF67EA4307A402368E19
+:103150009D4B95422F1B772B0CB1D603763DB56561
+:10316000E0666D89397407B993BC40807D97144A35
+:10317000D63B2E98D951298CA6BFF0FAF57041E3C1
+:10318000290EC6A487EDE3C78E1B1676EFA6DA825A
+:10319000F4DC0F6C1FEE16E893E925B3F5B088BE9A
+:1031A00027BB450FE6789477EF611DB3E7AE3E4548
+:1031B000257FE64E12CF7D86CF617FA687DB2D85EA
+:1031C00020FA6E455B6F2C0EA5381FED0BCED46335
+:1031D000E5CB700CB1F7DD4682E3BAE782A2A7FE29
+:1031E0001F5DE9623F85D769F3449DA633FB191E35
+:1031F0007F12F191CE736C384F69930467E97C2696
+:1032000093AF579BBF14B3C1C4421ACFE31B6D8564
+:103210009F75F2731E1B3B9F9B6F27BCA450B2EEA1
+:10322000AAE5C6711D4C0626B7EDFEA181C78BC36A
+:10323000E75DEEE0D1B3F45D8EE4F1B0EF7ADC66E9
+:103240006B88F27364C7A5C8BCFBAA6BED5FC9DECF
+:1032500025C5CEF0022F28947F8C0D7FEF02579367
+:10326000C2DFD3108C1793C3E7FBDAF735BBD5A5C4
+:103270008A0EF5B2C26576935E0ACD6945540F3663
+:10328000DBBD7F75B1EF6C5A26B1C9F4EAF4CA848C
+:1032900030DF2DE02921BCB5737D49E8EF7AE7F6F0
+:1032A00064ABC4730BBA7DFA2EE819B417B373B4C8
+:1032B000EF8FF8793E5AA142DF1DC113F314FA2EA5
+:1032C000609BC3EC7E5AA2141FD76709AFAFD1CC65
+:1032D000BF276834F3EF0260EB74B67FF690388F47
+:1032E00068B4EAB2A9DE6A84783795F49ABC0F25EF
+:1032F000703E3EF4DF16763E1A2BF7D7F1DE9C3196
+:10330000D3C3F23F2ABBCF62EE1385E71C0D4F5D9E
+:1033100018CF156A46639FC2F09B46CF4F33A9373B
+:10332000D1BEC82A13FF7E49C30D15CA486D17FACE
+:10333000D0F0B393BE691D1ED4B7C6978C307ECF34
+:10334000C473DC0CF4E544267B56217F1D8BCBFF38
+:1033500001AF6B7F8EF0290000000000000000002C
+:103360001F8B080000000000000BFBCACFC0F0A3B9
+:103370001E8143D1F8E8389D0F534C941182D7B386
+:10338000E0D78B0D5B3122D8FEDC0C0CCA9C0C0CF8
+:103390002A40DC07C4FD40FC1E880DB818180C81BB
+:1033A000380DC84E07627B2076E386E86966676061
+:1033B000E806E2C9403C9B9D74FBCD251918CECA96
+:1033C00022F8B2720C0C510AA49B338A87267633FA
+:1033D00042E5C76BA3F2BB7419184E23A949D02646
+:1033E000CD7C466306062663DCF271E6A8FC504BF2
+:1033F00054FE5D3354FE4577080D00AEA32483B818
+:1034000003000000000000001F8B08000000000007
+:10341000000BC57D0D7C54C5B5F8DCBB77EF6EF6AF
+:103420002B9B0FC20642721302040CB8C480C14A1F
+:10343000BB89A0A0C85B502B585F5D02242004828A
+:103440005A492BFE73212104126041D4A0881B3EEF
+:10345000142BD8A0A0B6B576F9D0529FCF4645A57B
+:10346000ADA50115D4024DB5C8F63D7DFCE79C998C
+:103470009BBDF76637E0EBFBBF7FFAABC3DC993B44
+:1034800077E67C9F33676665318564E6117211FECD
+:10349000BE47C8040B21644CBC244155206309F984
+:1034A000919DE09FD6CF5C36D61312B511129B4B7F
+:1034B00048A78B76946AEDA49896B7DE28922C42A2
+:1034C00052E17D859026A1F6C8E05242D44122D92E
+:1034D000491FADCA999E1A72251F77371FF7B97A0F
+:1034E0003B961DF55E2C9FAFF761B9AF5E21D161B0
+:1034F00084BC585F84E5CBF57E7CFE8BFA322C5F72
+:10350000A90F60F96AFD242CA3F5412C0FD6CFC07A
+:10351000F2707D08DF7BBD7E1E9647EA6BF1F91BDA
+:10352000F57558BE59AFE2F3B7EA9BB1ECAC0F6347
+:10353000F94E7D1B9647EB23D8EFFDFA5D581EAB85
+:10354000EFC0E77FA87F19CB0FEBA358DE4ED20860
+:10355000E947C86DB79DB7CFA2EB1DF6C47DEF4C10
+:10356000CE2464FD18D10FE01AF6C4C7BE50717C9A
+:10357000DDEBBFB1CCE8480097EF1301C759EF2648
+:10358000D8BEFEC0EF893292907563BA7C2AAD4FE7
+:10359000E6DF19BEF3A87D5671BC9F799C4F8885E4
+:1035A0008D63A5EDB4DFD0CDACBFD63E19BE3326BA
+:1035B000DEFE54DB3BF6D92E7D3B7BFFE92DEFD8B9
+:1035C000017F6B63128922DE554268E950BADBFA4B
+:1035D000513CA71CB3115B3EC5BFD241BAE838EBE2
+:1035E000C63D12154B61DDB49B02EB7C9708140EAF
+:1035F000AA9B203D2830C6D5F1EF5C4D449CC7B056
+:10360000278EB2EFDC7A1ECB57FF211342DF5B77A8
+:103610009B1071D2F1D78DFFC217007A539FB10072
+:10362000BD21B92AF09F2E5F908EBD7EFCFB3E959A
+:10363000C269ED37EFCE980DF4379AF8E17B6B0F46
+:10364000FC9C28D03EB21BE1D7C0D7BD76E6AC3C8F
+:103650006F7172BAA49444C432BA5C17094412C0A0
+:10366000F75F0108143E166F04D7E4A0FD12E1E1F4
+:103670005F898CFDD6BA83EF015CD4DBACFE9D7410
+:10368000DED7F9A3E4942B3E6FA87F44EBAEBF478F
+:1036900089C50DF3FECC67A1EB7796C957A5D0D9A4
+:1036A000B8BABB8FC1FBAE6BAB02B0F675A3BB7CE7
+:1036B00055B4BFBDA813D74BFCC43F848EEB285232
+:1036C000C9EC62808305F16A9ECF6C80773FC0D3DE
+:1036D000573EC0894687EFDDFAAEBD52D7FF698DF0
+:1036E0003E04465FA4356A9FE68EB73FA1B5A7307A
+:1036F000FA217663FB66131D939C24ED560A68C479
+:103700009718D92920DCEDD347F69E776BF4B7C81C
+:10371000072E7FD41E4AB02ECA2776903BA9A5A2B9
+:103720001FE0B56E3CE597E2F83A2FC577CD1C2E29
+:103730006B4BA7BB61FC4BC9AD911D2289167199DA
+:1037400049FF7FE5CB0E3AF3787D7434DD50BFEA54
+:10375000C80043FF319D0586F6AB8F8D30B48FEBEB
+:103760002A31D4BFF3E93586FEE3BB2B0CF5EFC558
+:103770006E34F42F27B718EAD7D97F60E83FD13BE2
+:10378000DBD07E836F81A17DB272AFA17E53D10366
+:1037900086FE37FB1B0CEDFF52D662689F1678C879
+:1037A00050BF65D2E386FEB705B71BDA6F9FF1AC59
+:1037B000A17D66E80543BDC6113A0EF8F9C1BC5FAC
+:1037C0001ADEFBD7DA4386FA7B844C4A845F2230C8
+:1037D000394329C87BEA0ADE9F8A382FD01CD07172
+:1037E0003F46A745ED49E4246F7F66C73BF6B9061F
+:1037F000396965749CCDDA7745DE49FCFE20CE2719
+:10380000A4D33EDDAD6F67F3BAE21F54BE42BBA442
+:103810007E2BF9EAF6FAB1BF2657297D13720D8582
+:10382000AF3A5055F17B743C2A2F2D6CC9A48E30D1
+:103830003945C8BDF85CD3FB2487442D74DC06777A
+:103840004EFB1A80091D5BCA847AF136A88B4A8028
+:10385000742580ABC52B1BF064862F71A55362EED7
+:103860004BCEAA083F75222992E0FB82C3BF9CAED3
+:103870005722A101027D7E410CF960F24B2DEA6FC7
+:1038800042F9F1FECBC7D37F42FF13426405F657DE
+:10389000108E0D234900F4869A2D4776E6233C6D61
+:1038A000204FB4F7E803A58BCD57BD38D85067F348
+:1038B000BD64FDEB61C6BA36EE4F8CF0A47086FA9B
+:1038C0005DBCD26BDD7E394EB716E8C7EA8A289018
+:1038D0008B28078DEDDA772EA4784691548A473BE2
+:1038E0002B973A3CDBA0BC90921B211E428AC5500C
+:1038F00005C04DAD60F0518F3B230D385EEDD5C155
+:103900009100DFC4F602212B187F7C3859D4AF23F5
+:1039100019DE1AC06E1BA6A3831C3FCA71BA6AD4F3
+:103920006FE6FEB70B321BDF455145C7B711466343
+:10393000A996D0EDC218586D9048384F3F0922BE65
+:103940002611B04BED1A3CC373B1EEE276E601F7F7
+:10395000D863218AE7B501D90F63550A0AC783DF07
+:10396000077AC056269235B4B65679C70EFCD19C5C
+:103970002F67835CB749B5C44BEBB642CA0709F45D
+:10398000C8E21E39F120B91CBBD88CA722FA3A9B99
+:103990000741386AF30F0FEAB417005D8EA776313E
+:1039A0009DEAFA6BFBD62F2B397C5BC02EA6E53A3D
+:1039B000657A2A41BE253381BE9BF3B344E4530E9E
+:1039C000A71EB8E4BF6F073E5DCDDF5FEB7F07ED5D
+:1039D000F4D59A1E37C1B179F44984CF2C81E9E33B
+:1039E00096918E19910470992578B0BD19782A1393
+:1039F000ED2BC65F267AA12DBE4ADA6E57BC256B29
+:103A0000E8F813464A33812EDC6544B121FF065C99
+:103A1000D9F4FB0EDE5B524483FC706732BAB57F8B
+:103A2000284414DADFE563DFB3B9482480EF2F318F
+:103A3000E0C551169A4246513BE91F167C8FCE9144
+:103A4000D9114727233F5ABD6C9DA488E1C94BFF7C
+:103A500077B1808EA7C806BDB1BC5CF647E9779602
+:103A60007A5C484F563D5EE9779DDFBC1084F15784
+:103A7000E5DCE3584EC7BF50DEB40AD8D2F2E1E429
+:103A8000CF80EF2CE6FE83A6FF6E70023ED04A6721
+:103A90009787443360803BFBA403CF87ED6F1CD630
+:103AA000CDF315C19D89F2F56A7235CA854BBC7F8D
+:103AB000A13EF2C6E121080FF172E879A589AF9B1A
+:103AC000F235BDA5FAA6E9ECB2F302D36B442D475B
+:103AD000384B9C9F9BC6936EB05BD7E5CBCA0ADA86
+:103AE000452A93A3403AF0D74DBF0FB6190179ADDF
+:103AF0003475B2E73F32C8CDD5FDA7FAA37DC04DDE
+:103B00002A34E99B4BACBF0EE0A7EBFF31C0CF19C5
+:103B1000879F8D0453A3402FE149063F7655F9FD59
+:103B20004A94FE73D580470227880E8EDFA37CA8B7
+:103B3000E30F5B4E84E8BFAFC9C55BC44037C861C3
+:103B40008BEC4739450A64F447CCF32B1299BC89B6
+:103B5000C3D92E111D7F902911843BFD0BDAB33898
+:103B6000FCE85F8AEFF57F00FCA88E8E3A47E1F310
+:103B700046A984CE2793A8CE2BE9FB1291A03E48FC
+:103B8000CC47BEA5ED13E474E0DFEBFD20079BB846
+:103B9000DF47BCED3EBD5D3E4864788DB7477CB7DE
+:103BA00019DA99BDD3A4D9F5DEED06BAE8793F8DCF
+:103BB00024F43FFA89CCCE1E247A39FD6C47FF6D80
+:103BC00075E69418A02125FB7A7F25F0AB97201C81
+:103BD000343DA1E905AA2F0689FDE2E3C98541220A
+:103BE00060BB51FF2695D726BD9B52649403446F5A
+:103BF000CF14C07F73BC482FC4ACEF7919BCF1B2AD
+:103C0000F8AA97BE2489FDC5692293C344CDC4F5A3
+:103C10006B7C45B83D61D5E882307AF5F0EFCA306B
+:103C20009FC180E7080EEEA46E15D4DDA416EBE765
+:103C3000CB4AA200279BD4D54CB87E54F313F8513D
+:103C40003C0E936C1DEBC727D60FE5A207F16971F7
+:103C5000D59210D2F19D68070A6A885C447B30CC0B
+:103C6000F5AADF07785C555F473EA28B711C9C8CE0
+:103C7000FEB9941308807F6F0122C8A6FF7795B222
+:103C800052F22B7AFAECC123598EE3592958609DE0
+:103C900056977D16E801ABCB3B0DCBA211730528DF
+:103CA00053AFAF1391AD12D393361EA5AB79228CCF
+:103CB0009719427E96BC412C892B13ED57DA5F0988
+:103CC000269C07A703DE2F29DDF5D08D0607458644
+:103CD000F1CCF4E428A51E8988D54E986F7F8EED2F
+:103CE000FE739A960088DD24DC3C94E2AD7FD7AC6D
+:103CF00029A077DCA07FE83A5716971C01932FD5AF
+:103D0000EFDD70BD02710022001E56C360D7C0787F
+:103D10003F585E8EF10FFA37800A8B15C172E61F8D
+:103D2000044C76ABA8489A7D26F669EF08176DBD5E
+:103D3000DF4FB67E1BD1F115EAF17B2ECFBEBA93D1
+:103D40007D4FA5FF037E4C33E9D9D480511FB84D78
+:103D5000DF790E6089F05EF2BFF23D2FD96857C05F
+:103D60005E2914BD114ACBA9C49B067E946302F55B
+:103D7000EF68DD9BD3ADC2942E859795DC8F25949B
+:103D80009FF5F47F88CBD7ECAA4DB39AE8B8E74B00
+:103D90005D7EA0E7FE549C66A4F75E4F4B3D31F07C
+:103DA000734BF136A4EB06AAF00AC03F2816D15E89
+:103DB0005F5DF8BC57AFC73ED1E4502FFA208A347C
+:103DC00096FB93143E9642319032EA9FA70FB3FDC3
+:103DD00074B9F4E1BCD3888F6F8BAF2FBE257DFC07
+:103DE000B3DF5B992C3EC1E559765523F35794BE5A
+:103DF000FD83DE78DD88787550BF26917CBED08348
+:103E00004FB57769D02BC6B880F586EFCFD8D107EC
+:103E10003CAC33CCFE3F1B37A5CEA27C0CF6ADE408
+:103E200035F841AB958D2AD8F3E7C12E07FB305CFE
+:103E30008EF16152C8E2B5308048EB294A20C2FCBD
+:103E40009B08D1EB4139C71877B3643A8CFA7B866B
+:103E50002AE8E79F5227E33CECF0BD4C8CE746E0B4
+:103E6000BB162F89A6A0FDC9F0079F62F180072E1F
+:103E70008B0E347A053398D1ABF1BD553925241119
+:103E8000FE7A7DEF56E37C93CA25F37B2E4939A554
+:103E9000B35392BF2791533A7BA742DBF7E178A255
+:103EA00076DECB422A9507BEEF9310856F133465FB
+:103EB000433C94A03E6BF29578519FEF124C7EBB31
+:103EC000C2E84749C7FEA29DE94DAD9E7C3EECBBD2
+:103ED000F17D2405FDDA64FD1BEACB1E9628713ABC
+:103EE000EB0E6D92281E1B97076604D1BF3DB249A9
+:103EF0001A12EF5763D1FC76AA3EC7C6F7072442D1
+:103F0000FB21DC4472F12A78E825CA588026FBB3ED
+:103F1000934E6CA74F391E89D0E3CFD021DB609D33
+:103F2000189F3886FD60A08B186FEA6275FA22D45C
+:103F30005BAC8100CE4B0ADBEFA1F06A49E17585ED
+:103F4000D7D378DDCBEBF9BC4EF505D49D32ADD39C
+:103F500032C51AF662DDC1EBF9BC9ECEEB69BC5EE0
+:103F6000C0EBC246ACB7C86CBC3552848DEFE0756F
+:103F700085D7D379DDCBEB05BC4EB6B1EFDB58DD91
+:103F8000618DB0F19DBC9ECFEB19BC9EC6EB8379D1
+:103F90005DD886F564F8731452F81BE44367BC8E51
+:103FA0004A84C3B5A7DE656A67F49221106E87A9BB
+:103FB000D960B71D98757F36C4431F3D71B50FE8B2
+:103FC000A7E1668D9EFC283F49CE4D28C7FA737F36
+:103FD000AEE1CE1518876808C98C89787C26DE5E2C
+:103FE0007204F4F6F919A21F1ADB92F82FCF723B74
+:103FF000FE191E97799AEF57EEE4FB95DBF97E6583
+:104000003BDFAF7C92EF573EC1F72B1FE7FB959B41
+:10401000F97EE526D8AFA4FD36F0FDCAF57CBF7267
+:104020002DDFAF6C81FDCA6140EF7558AEE2FB95A4
+:104030002BF97E6503DFAF7CE4CE92DF16D2F59DCF
+:104040007789680F24C347F16EA3FC1CB1C3283FD6
+:104050008BB6A41BEA43370D30C8F7C256E3BE4502
+:1040600041E308435D595662A8E7DE778D61BC9C49
+:1040700085C67D8B01736E34D4FB05A71BFAA74F51
+:10408000B8C350F75E5B69A87B4AEF36D45DC5F7CD
+:1040900018C67314FEC450B7E7AC30F47FDC52800E
+:1040A000F42567AE31F4935C1B0DFD6A1C81CF2DA6
+:1040B00020EFA6645E967C237F57B3F4F2D2AC1F48
+:1040C0002CB92410403DC7F411C66821AE3688C50E
+:1040D000AFEC1FDE7004FC175B21D353E6789579B3
+:1040E0003CD9F5D431957EA7DC73C4D7A5A35BE298
+:1040F000D3BD47979A2A3139B9E64146DFAD0F263D
+:10410000A673D404741DADDF248E17BB258B418F9D
+:10411000687E4DEB8302F6FF67C7D7DACDE3C6BFF3
+:1041200047713D566FB744F87CA88ED0D90BD6AEF8
+:10413000B4D904F53CF3972D9CDFCB27F84F3452CC
+:1041400078AFF412BF8DD657BA2A02CC2E1115942F
+:104150000FCB6E46BF5EEBAFCDABD1359DC917A27D
+:104160008B5BA29C7218E20A2B33FBB6DFE4980546
+:10417000E37F969840A2542FC95270523EE55FF9F2
+:10418000A8C5BF9CA07E4A181F206423DB77F619C0
+:10419000E3A68D734CF28FE7655835F9965981CFB8
+:1041A0001BBD7DCFCB06F382F9F07959634E2C2DE0
+:1041B000B1149CEFB85806D6CB6269585E1D1B88B7
+:1041C000E5D8583696636283B12C8DE5637955EC5A
+:1041D0000A7CAF24361CCBD1B1ABF0B93F361ACB39
+:1041E0002B63DFC1E7A362E3B01C19BB0E9F17C7A7
+:1041F000CAB1BC2276133E1F119B8CE5F0D82DF876
+:10420000BC28360DCB61B11F6039343613CB21B1D8
+:10421000D95816C666613938B600DF2B88CDC7324B
+:104220003F762F3E57624BB0CC8B3D80656EECC71E
+:10423000580E8A356099135B8EE5C0580BBE372047
+:10424000B61ACBECD843F8DC17DB8065566C339696
+:1042500069B1EDD8EE8DB563991A7B169F7B62CF5D
+:1042600060E98EBD80CF5DB1BD583A63BFC4E78EB3
+:10427000D8CFB14C891DC2E7F6D8012C2F85A74BAA
+:10428000D9C1651F1BF79FC77E68DC7F2E3D6A94EE
+:10429000E3256F1AF79FFD878DFBCFA35E31EE3FBD
+:1042A00017EF33CAF111BB8DFBCF453B8C727CE815
+:1042B000963B8C7A6493518E17B4DE6DD4238D4671
+:1042C000399EBBEC27463D72DF0AA31E59B8C6D003
+:1042D000EE9B6394DF59E431A39F3E619B518F5C59
+:1042E000FB53C378AED2E74D7E4D04E58BA3F817A0
+:1042F00086F7EC85074D725965F2C9146F0790C0B7
+:10430000FEE652E2F0835F63C6673A970719C0770B
+:10431000B4CCE47CD70FF88E96E9372DF4013D64D8
+:104320004C2D9B0576CC85138202B132616ADD305B
+:10433000D8EF491F48583C818CB80EE2684DD95AD5
+:104340009DA8026D6F1A4430BE40D4E5150117C612
+:104350009BB1FE5BE9C10AC88B69B2F276B292B535
+:10436000A7B0FAB1C6392BA03D3DB5231B12991E4B
+:10437000B72696E75D12DBDF1B28057E27D1F5FF08
+:10438000B5BCEB7E88CBFDBB3DF4AE449F2FB4871C
+:10439000F2606BEDAC35F434A88E02217014FA8D06
+:1043A0001402EF4928B78D71D629A038E9F37C298A
+:1043B000F807E89731D527C0FA353834B9FB9ECFD6
+:1043C0005B5C3F35A511F437D5D57C3F18FE34BD75
+:1043D00041F5E1A34E0FCAFDC86A799B8DD9854688
+:1043E000FDA166CDC6786273D312D4C7805F4BA29D
+:1043F000386B17D653C1BA1C0C7181EE5C89968B51
+:104400006CD126D0275FA5751E172C088FF3B09EA0
+:10441000FB6F0C61FF15CEA965B01E0A8FAF383C4B
+:104420002EF4050FFA17F4D1F9F934AADA2D18E2AF
+:104430009AA9969060EDC7F653617C5FC88F7ED9CC
+:104440001F25166FD7E047FFEE4BD7E23804DF4B4E
+:10445000B18EE93D9E368E000003BAE67A51A3EB99
+:10446000BA247A4A8B7713F5E66FB5EF7444E67E8B
+:104470009CE93B16C98FFBB6E6F72497510E5A5DAF
+:1044800021CC8790A5C4FBBBB28DEF5B6D997A59A7
+:10449000FBDC3BB47534DE7C59FDDBB5FED43184E6
+:1044A000FE391C8E64CBCD4877055C1FE770FBEEB0
+:1044B000D09F6E58D14AF939429FD912C41122CDEA
+:1044C00022EE6BE6D45082CB8FC37BA0C2EC42EDD0
+:1044D000BB036B8D7198031A1C375D1EFCB5FCCEB7
+:1044E0001C4AF8BF28E93D0FB2632A5B8F9755A598
+:1044F0000D417B0A9D5701A3253290BA23FA38A0BB
+:10450000793E84EF5F0CE4C30D74B1FE649771DCF7
+:104510005EDFB5BC32BA2F3DD8EB3BDF723FB0CA8D
+:104520009A783F95E20BF13DD064FF69A5B61FA8CC
+:10453000D50FFDA9DA0E7677D3C24ADC6F6FF23160
+:10454000FD4DBEA6A38E8DAFDB3CCE4E0EF7EDDC4F
+:104550009FDCB9A902F31FC96E237D0E79F8564777
+:1045600088D96FE9503ED5C6FA0DDD3C873FAFC410
+:10457000E7DB5BD9F3C16B4BF9F3127CBE23CC9E16
+:10458000176E98E080784EA3B7221DE33A75F44F7A
+:1045900027EF86784322C4E386B491003C1BECF5F8
+:1045A0008B20FF0BBD012CB5790FDAB4AD7C38ED53
+:1045B0003F6861703AE4B952C2C4FC430221153A23
+:1045C000EFC7F87A73B5F690B1BD8D7F2FAFAD729E
+:1045D000F970FACFBC85A18D934BF1997F0889F7CB
+:1045E0007B848F63D7DA03C6F6306F575A4FA21811
+:1045F0005016FADF9904FD9A8DDF5BC7FBB928B32B
+:10460000C1BC0B16061CC3615E45ACDF131ADF9AF2
+:10461000E482146E249375DF6BE5F3B62C64715657
+:104620004D3E6CE37180AD10071816EFBF46EB6F7F
+:10463000DFFEC4C7548F4B0B593EA9D6DECCE7A58D
+:10464000E5E514DC678CDFFEC2CAF8B85B66F15B97
+:104650008DAE92D13799271AFC3D127218EB337444
+:104660007621D403038CED6505C676FF0863BDA8EB
+:10467000C45857AE31D42FF4C4613A53F471182D95
+:10468000A6F384B712FD9078FCAF3B459F479ECBC5
+:10469000F9EDC9BA12ECD7E0E27C64CAA769522AE4
+:1046A000ECFA7DF8BD9C8FF6413C84962F40FE3697
+:1046B0002DF78F0ED8F341BFBF67F16F23C9E1B665
+:1046C00095E3710BE7C3C7009FB46CE3F87C84C724
+:1046D00075D6F3B8CE5A1ED76981B80EC667585C36
+:1046E00067158FEBFC8CE7A1EFE1719D67795CE7C3
+:1046F000191ED7799AE7A1EFE479E8DB795CA79DE9
+:10470000C7752672F9BD7F624736C4D91E9F98D8F7
+:104710004F9E28337D168480262DAF224A8315E8CC
+:104720009AC206F6754AEA148B0DF262030CAE25A6
+:10473000F3148BCCF271F06F3AFF0EE815CC9F7931
+:1047400093E7F5E450AB4847EFA30F4709E47564DE
+:104750004DF08E8690682AA747DAE6837E5C0D903E
+:10476000ACC35E307388640978E57E303EC17EF963
+:10477000BBC307C19C1911ADAD70D2F78B5E0E564D
+:10478000504F9B0C2DF21F1414C8170A8880E7FDA8
+:10479000E5FE234A691C5F741606BAA073447D9631
+:1047A000A7E9876B8D7471556C2BDACB4D753C5F27
+:1047B0004A2109FD78ADF45E2B9AE249463FAA6989
+:1047C0009931DFC35C8ED861F4C38BB698DE57FA9B
+:1047D0007E7FE826D1145F33E61137B9A6F7191F9B
+:1047E000CF8F4DEDD35FBCC552799D3C265E77C619
+:1047F000BE8BFDCDF6A004761EB557A5A37200ECC6
+:104800005DE9A837007113E9A8C24B3F7F1EE0F5B0
+:1048100020D6A9DD1884F1295E0C76A3850A7CD800
+:104820001BD90FC21DFD908B2B02D418DA7F1B41C0
+:10483000BF224D765EA7827114988BF891397E3233
+:10484000E4DAA7210E12A911C9365A7F7C61DFF282
+:10485000AE575E852B80FB4939B5DE124B1FFCBE7F
+:10486000A9569C94689F6C31A7EB95B5D3BDA83F22
+:104870000E5F326F60B1ACCB1BE8772BCF1B38C318
+:10488000F2E20669EBBABF6F3A78D4B48EFE49EC17
+:10489000EAE735BE73B1BC138DEE330AFAA6935521
+:1048A0005C3EC62222E904792B05507EF6BB358496
+:1048B000F9F1A0A0F57CD2F4CD75C887EA83EC1C91
+:1048C0004FBF5B03449F77AFCD63504E17B875A4BD
+:1048D000E9C03896C741E10FFBD74D0708FF8E8A24
+:1048E000C2C17E1FA980EFD9492DB1437CB3CEAFA1
+:1048F000C2738B8BC10BFC55DE1FE7D5BC4CC49437
+:104900008A86092C3EAAC97F8D4E1A7C3C5E3F41A7
+:10491000C278B7E4AD8D02DE9B46133C6F43EDAE2B
+:104920008B1735FF06F2BC323BF1DFD6A26814E8E4
+:1049300092042621FCB4FCC026775639ECD3ABF3A5
+:1049400035FB82E7A14A7E3CB790D3368AC5C33295
+:10495000C3985771BF187A4EEEA7A7BB0E844F536A
+:1049600092F3056B6596F7E44B82D7F7B91CCE90AE
+:10497000A393993F4AE93F419CA093F7DBD23CFDCA
+:104980007743499C7FB5F63F4A0AB66BF59C988CF5
+:10499000F3266DDFCE0FB85EF3F74CFE9B550A1A77
+:1049A000FCB05CAB82FDB4BA9C699467973F4F89B9
+:1049B000E54316DF68C073C680BEF9A689F3CD85CE
+:1049C0004126BBA3B088ED1BF7D81D22F150B86E6D
+:1049D00035D193A647AC45DE0DC3F27BD3C5D66572
+:1049E00095AA00FB2A7E82FB426E7F4700F6055D9A
+:1049F000399172B08F291DFC15E840A38B9CB6B18C
+:104A000008EF1735BD57472A0209E6AFD975E06FA1
+:104A1000F9D2616493DF43825EF0AF7296331B720A
+:104A2000208F2B0C54FBF6FB2E77FF5ADB4FCEA5C5
+:104A30007FE0F7FC42C3F7A7A6B89597B2EC589D64
+:104A40007EFF3443B0E8E8B2C7CF37BD47FD0B6FF8
+:104A500022B92D594259361DBD98FD77B39F4D7A25
+:104A6000E5BD9512C89BB24C997404F21F7BFCED16
+:104A70002D5399FCE278B3727FB4B73F79A7BF2F6B
+:104A80007D627599F659BEA53FE9B719F34B2F3BE7
+:104A90003FF75BC6231A789E5E2FBFC3348E180E75
+:104AA0008889CE6D0C091BE12EB98C76C79556C648
+:104AB0009F839B8D71E4BCBA0189E39D3C5FADB2DD
+:104AC0004CC39372FB1F29BFCD3F62653E10F78335
+:104AD000B578D37C9E375D09796C144F7348D00349
+:104AE0008D678988F93167C93B9EAB747C536563D8
+:104AF000E7E848B3F5249CBFD0F2B3E686595D9B46
+:104B00004F759BB15E45A66741DCB56A9395403E03
+:104B1000D67C229DECD2E64FF9FDFB366607559315
+:104B2000DA26906B2B793CB1D24B24C8A7AA79E93D
+:104B300089B1709EA7C6C6E4F7E714FE8A2EEFE699
+:104B40006E574406FEFE68DF55DFFF0E81F7234DEA
+:104B500003406FA6253E0731BBD938BF4BCDDF3CA4
+:104B60005FED9C46B27948BB8484E7151FD0E25EB6
+:104B700097798E64BB8DE13FD939924BBDBF0BDE77
+:104B8000EFE31CCAA5DEDFF34FBEFFFC25E65F6343
+:104B9000EFBE1EE4C4AACCDA20C8552D9F651109CA
+:104BA0000520566379659A3A50D1F5F35D66BF1CCE
+:104BB000DACF7219FD0AFB1EEF1CD7C3BFD9BD5D4A
+:104BC00006FE3DFBD31353C12E58F04B0BB1533AA5
+:104BD00038B7DBCDCF8B4564D08F77EFB360DC8007
+:104BE00048D1B1B7E8F20531B3908EBFE0676EDC13
+:104BF0005FBEFB795B640A7DFFEE173F1A45281CF8
+:104C0000CEADE87E7D20D83D3F1558FE95DA35EAD9
+:104C100016FAFC6E89DC154CA0B73A391F9CF9B91D
+:104C20007306D099B0EBC00F71DC8EDBAD369D5EA4
+:104C3000F88DCD8AF0A7FDD879AC6784C81081CDF6
+:104C40004F9F2FAEE5BD9D794660F37BD91A498110
+:104C5000F9ED6A9743B4DFE25D7F43BABEEE677B4E
+:104C60003C0087C52F5B0CF267F12E4BD4360ACB84
+:104C7000133694F701973016E049500F2CDA57831A
+:104C800079B28B3A5AFE66F1C0FB46FEA270C17340
+:104C90001F0B3EB0F8A740FD85A73D60C77EDEB97B
+:104CA000D30370A5E3CE92295D7DF7EF3A3E246CE5
+:104CB000FC587AEFF1205203F4B5B86335FBDEBE41
+:104CC0009B4F837C5B6CE2E3CFE11FD9BDF547CC02
+:104CD000668C479E276F8E857D0AB22B23617E717D
+:104CE0008FFEE07CBD60CFF9AD709EF8CCF37FD92C
+:104CF0000A76FDC2FFFA72EB03100F7835C50BF28E
+:104D000068F14FDFF3101DFC33ECCC8E3FF7CCD3B2
+:104D10004F3D46F9E4DCEF6D68E79CFBD5E95C8527
+:104D2000AEFFDCDE7F64C1B9DBFB7E35B13FC0E3A3
+:104D3000BEFDD7F5EFCBCF00BA8DD8F4F88D207E2D
+:104D400095970596CCFC0A2F4D783AB4EF502ECCAF
+:104D5000F3EC311B9EBF594C9FD59500DE6A503F46
+:104D6000407D1985F7A2DDABFE66199508EEEA4095
+:104D7000113745A203C1C85EB4EF967F195F0AA53B
+:104D8000D5AFC078A41BE5BBF9BDC547297EAF4CA4
+:104D90008ECFF3E46B19E0BF78F76AF6DD0E8A4F29
+:104DA0004F6F7C9E857F8CEB8DCF12BB199F0B9F25
+:104DB000C4D8E8BE8C8479241A3E6BF6DFD6A7DD12
+:104DC000A0C9874BC1791ECF9BFA2F5BA0C20E7C76
+:104DD000F6BC53F5313C47A6D0B6737BCEE7124AFA
+:104DE000279F5ABB7F0872B2FB57362FF81D77FFFB
+:104DF000EA03E4BB73FBDF961576FEC42550BBE2E5
+:104E00001CE9F9EB043B6311DF335BBCC31DB579CF
+:104E1000E2F85A14993649F1E0F313F83CC2F8610C
+:104E200051E4C0AD4202FC2DB31730FD14E9877088
+:104E3000A9A19E0E9CCFD7E35528037C9EB81EE8FF
+:104E40002F193EB5F57B61FD57EBF0BA83F1B1B98F
+:104E5000FF22CAAF20877BE137227C00E5B9769B31
+:104E600004F991E7AC2CFE66C67B1CFEFCFCE4B7A3
+:104E7000B417EFB727D97FE070B814BF5F6A7DDF42
+:104E8000167E73EC0A8E6B86E399AF13EB838D5C11
+:104E90007E2C22B59306E8F499CD4AF5593ED87B8D
+:104EA0004175A0109F6F538705E5FC995D9608E852
+:104EB0000BB3BC584412EFDB45ECCC7E59F4F281C5
+:104EC0005120D7CE1CFC39A74B46F78B769F9055C7
+:104ED000AE1F227AFD90C4DFFE291F6FF12B89C718
+:104EE0005BBCFB6F09C7FB5C0ADC0EF3FFBCD34A5B
+:104EF000543AC4E71D964989ECAD4D76AB31CFD617
+:104F00003DF6582A7DCFE27128B0EE8615810F5408
+:104F1000B04BDEB1629C9648FE4F6D78DEDAA1ACF4
+:104F2000A1706BF054613C451BAFD10427C91744F5
+:104F3000BF54CA0C96329B3A62F0A7ADD4DFD5CFEE
+:104F40009BEADD1CD04BC7479FB6C23AFF6CB21F2D
+:104F5000FF2C91A6FE74BC3FAB827FB992C85F3430
+:104F60008E1F5A66218A5E1FDABA8FC37CC8AF5380
+:104F700008E4AF595E4D51419E2CDE9A12817DCDE1
+:104F800043FB2F3C05703BF7A48DEF73B23CDB6A0B
+:104F9000BEEF777AFF85ADFF49DB4FC3CBF4FBD57E
+:104FA0005B697FB0DB773B315FF3AFCFA78E2254D5
+:104FB0004E57FFFA81A9205FAAC1C7A2FDAB7FD6D9
+:104FC0003FD240C73BD58FD54FED191401BC2C7C87
+:104FD000E1578B409F2C78CE4980240FEDFFE0876E
+:104FE000503FF76B37E67B9DFBF5E9EF021F507BE7
+:104FF0005BD1EBF5F9FAF3DE74DC055067EDC245E1
+:105000002EEBC08F590025A5F7052FA7E2F9075D04
+:105010003F7C6FB1ADFB7E1688520788E8134507C9
+:10502000001F2ED865FCDE5FEDCC9E5A2C7757B161
+:10503000FEE1018C5F3BF1BDAF353AE5EDE6F7B53A
+:10504000FEFF612F308DC3DE5F6423B589E8DF96F4
+:10505000C2C65DB0EB9B61C6F118BDF6FE0E7BFECD
+:105060002381E5E793BD29B84FB0508E0E4D2FC672
+:1050700078C73CE0DB859EE8D034FABD5F7279B931
+:10508000D041EBF4F9003E0FE80F7562EF7A0EF0B5
+:105090005BF3520A017AAFF9B51BE3C9352F5E38CD
+:1050A000F5387D7E66BF13E37A35BF5E8AF8AEB110
+:1050B000457F08F1BDEEBD36B28DF63FB3F7B7B907
+:1050C000608F9CB14673D3FB880FD574D87832B803
+:1050D000711DD42F28AAA5F35137B0BC9C3AC2EE5B
+:1050E0001DA883A00ED0F18729EC1C31DF97BA8769
+:1050F000C7A3BE98A3A4E2FCAFBD893DE7F1867BC0
+:105100006E56FAA7E9E6017973E42AEA97C8B5C3AF
+:1051100040CE5A62371105F6FF6283B1D4FA59E0E6
+:10512000FE8662C8DF62FB7ED64C3FA9A6E5D2743C
+:1051300012C2F397AE1B7BF8EC7714C5F76C56FAE6
+:10514000C378FE14265F6A1C81F129980F69BC7729
+:1051500041DDCFD67581DFA7609EEF05AB6A03798D
+:105160001EDFAF6379837592F201C47DC9112E975A
+:105170007AAD9FF1D917DE74E4336D1D2DF55E9481
+:1051800027ABEB7D58AEAA2F220AE629FBB16EE1D0
+:10519000F0B015AB04EE99001E843F9B2B1880FBEA
+:1051A0002C604C88B75B5C21A42F9BAF16630576FF
+:1051B0007EFF8EC5A5926A17C467189C206E0C707E
+:1051C00092795D6A9B8270A5EFE3F3898ED09C94FF
+:1051D0003190EF3BC220A7E4CC1243BD17DC34BAB8
+:1051E000D8F3BF0D3F82F05A5D6FC772557D19C26B
+:1051F0006D657D00EBFF1FE0D7CAE0770D5174FCB1
+:1052000023675618EA49E1B799C22F33CE5766385B
+:10521000D4F1FC1C8D9F92F1EF23F504375F36D655
+:10522000B761A93D4F4FA2D7CFA6307BA48E8496FD
+:10523000E33EA897C56148A64A7274F127E253F18C
+:105240001C089E3785F69C9B307EA9E1D7E2954EDF
+:1052500019E59FF201AC67E91B5611E495A56E3B79
+:10526000F92843C7C75382290AC2D98F71E006AE15
+:105270005F57F6E0D3C81F2DF50A966B399FACE750
+:105280007CB201F00EF13DBF88386D9D44507F3EE9
+:105290004CEBCCDF8F127D3C3CCDDF11B552FCA333
+:1052A0004C52B064F7701CB34586D0F79CC52400FF
+:1052B000F49276ECC7115C2BE9C0F3D669DA3D3085
+:1052C000AF14A4CDC4FD1F62657A8A585819B682FE
+:1052D0001F65866F83FF20DE2F916C3EE5C7E70BCD
+:1052E000F0BD0B33D99E59E69D1DC7E03E0857AB74
+:1052F00013FDCA2C7F6D5E2ECA571BD2ABCB1F127B
+:10530000AA7578CC4A62FF2D734CFE23D0E38790B8
+:105310009748F1BBB16D700AC0B9C5DAE10379D81D
+:1053200092C6F48D3283424177BFD86B5C4E7A4A85
+:105330008D724093CBDE6B4B0CF4ACC9DDF40946A7
+:10534000BAD7E4EECF7AE46EF02CC8DD8CD816E440
+:105350004B331F34586555B812EFA361F1A7130200
+:10536000DB57EF2D0F70DFFD8BAEFC6D701E5BE326
+:105370001FF3FAA5E6C9F89D1E7BD09A381F60205E
+:10538000BF97A199D21BA174D44AE90C10B18ED257
+:105390001994614A678C9FCAB0D4E8780561324499
+:1053A000DD27B279F278ADB67FB2C25E12003CAEB4
+:1053B000EC603C34C8C1F7493345CC0B90A83FE9B9
+:1053C000A28FA403E3EC605F4A56B68FDFED163B75
+:1053D000601F7FA56BBA1DF24A85B452A49FAFDC53
+:1053E00095797DEDEBC0FD6B407F5E979F9C2C8E89
+:1053F0009F9BB4784B08F8A57B5C9D98DFE472888E
+:1054000086FDA71A47A8C0A1AB8F84AF73BCC3B0F9
+:105410007B929CBF1CC5D743725452A893133DF78F
+:1054200025292A29D2C98B1543AEC7FB987ACB8987
+:1054300024F270E7FF8C3C6CC88B205EAD66F9935C
+:1054400019C03BA068A9C2D50AD43A5FF983D148F4
+:10545000A7D739C00F716DEBB183BE57D07B9E6665
+:10546000F917D76B0AC6C1A85E7BB40CE46952BDBC
+:10547000567B17D271EB4005E8F8C0BA079E84FA54
+:1054800047EB6C78EF4B556C3551E87CAB63E3B080
+:105490009CD7F61096956DED94890859BEB67ADDC5
+:1054A0004CE8BFD982F19F5391ABCED5D1FAA95622
+:1054B0001BDAEFA7B6DC9B07F6DFA956A762017BD4
+:1054C0007FCB18637B33BBFFE5549B356261F47B74
+:1054D000D102FB1184CB778802E9E64B4A15B4E38D
+:1054E000BF30EDB754AEB705044F72F857B625B6C6
+:1054F00027F1FC36E45C93DA61205FCB8FFF380F35
+:10550000E84393334BD3A9DC03F81DB79144FB0266
+:10551000131D1317039E263A024B19BE2EEFDEAC65
+:105520008F446A77239E429E6986B82F8BAB7EC4D8
+:10553000ED72624FD2EEE1EF7B13B7D7B4FEE5F523
+:1055400007696D55B131AE6D8178B500FEF83496BE
+:10555000EFA0ED03F5A66B664FB7DA50AECCE1F1E4
+:10556000288DCEE37416F2F07C31031DCE8F6D4092
+:10557000B927B48C7C741C85DF9794FE803E84969A
+:10558000F1FD01BECBD77C67FD9D74FCBFBF69C137
+:10559000E7F36229D8FFB307FD8FDE09FEC2BF5BC8
+:1055A00009C89FBF1F9988FBC89F598D718C7227AE
+:1055B0009397AF72FEAF8AB518ECF3AAE6D932C45E
+:1055C00041AB62EBF079156C22611EFD1DAFC10687
+:1055D00070152CFD1A78FFF6892B509F96601CAD34
+:1055E0007AAD2D619EFFAB0EC520AFAABB5A715C90
+:1055F00042EDB3CC2C3E9E4EEE54C732903F8857BE
+:105600002590F75DC5E54FCFFCB6580DF2E7B39492
+:10561000C4719AB71C6C9D55B1EF20DFF55EDF7742
+:10562000F17995F6DD2EC6A7F1F53C3A2ED17AE256
+:10563000EBB816FB7F9696F8FBE7397C4FD5CF2366
+:10564000012ABF2A6DB49F0BBE7F6F5319F8F95B17
+:10565000D2D205DDBAAADB1690806E5DD55B66C935
+:10566000FAFB29E378B8CF8087F36B16231E9639AF
+:105670008227400F54B68C1F15423F7F35C2F92355
+:10568000AB3F17E4F1E9B67B3D89EE913C6FC64F25
+:105690001BC70FB5BB4B75F8D1F0627EFFD49FAA34
+:1056A000BF7A10E4D466B741AE98CB5E78CB4F0C8E
+:1056B000B7544E9FA7A8FE0E21DC94178F015DAF53
+:1056C00075627E5C72F85D41427DC12F89FD4CEDB3
+:1056D0002CBB730C7C97201CAADB181D5C0A6EF196
+:1056E000EF723A284FBC9EF14E8D0EEA884A19F6A9
+:1056F000A47C293A7880A8F63ED6D143076DAF95B1
+:1057000017C6E960BC333C7105EDF729D83FC37A71
+:10571000E3FFA4AC7AAE017B678D05F7BD4E3AD4AA
+:10572000AC3B587D34C8E7939EF0D46B4AE3F5F95F
+:105730003B8778F4F73A9E6EA6704800BFF1CE24FE
+:10574000F453A892E2B1FFEFE8E7A324E760263A1A
+:10575000CACB019F249C389EAC959AFCB6A4BA7A19
+:10576000FC5ED0A3275D055F4568EB3A47E86627F6
+:105770006D6F4CBB1FF5FCC99302EAE1E57F5A3A15
+:105780000CE4702FFBB73EF6D8C743306EF9F8C76C
+:1057900056B4A7705C42ED1FD003986F8E7EC04058
+:1057A0008CB324DBCFBD172EFF1D13DFD7D5F66FCB
+:1057B00057D6773E04E313BB4ABCDA797D054A66C7
+:1057C0008FFD07CC43179F97AD21AF1FFC5D810470
+:1057D00081EEAD52A819F20CADBECCD1AA0ECE4BC3
+:1057E0009C2C2F27E5F0E1E67CFA7ECADCDF7921EC
+:1057F000CE67A3DF81D29E237DA18F975B3359DED5
+:105800001729D43D2F8073C8B46E883BD0F9F6E1D8
+:1058100037FF52E8B9670DEF379EA95DF405A0A3E5
+:1058200074F37B2D7F456A64ED695A73236BE771CE
+:10583000D4C5952C4E7A68562AC24F5BD7CC5756A2
+:10584000E17D6B335FC9C6F34C335DC33E0178FE27
+:1058500012126B80EED3987E36D3C5435CFEFCA05B
+:105860005D54AD74BCC3D6EE834EE08B1F09E85780
+:10587000DFF1DE612B90FC1F8E9EB4425ED45D9002
+:105880005844D7338B283233A223F8FE6CD2E1661A
+:10589000F58E7E70FF697C3CEA32C3784BD8FEF30C
+:1058A0001DEF1D9D086A948EB712CABBDE24328C90
+:1058B0003F6B9FD2C48E43F1F15EA1E389F1F17A8F
+:1058C000E027D9111E71F8D8115EBFEF395FA2A28F
+:1058D0007DA1832FDA2B1A7C1B006E147E33536755
+:1058E000DC484625E79799AEA19F9051F1F998E1E0
+:1058F000FB7768A2FCF68433B017F8AFD119781E95
+:10590000F867A1BD3B572AC073602FC2F34596507C
+:105910005E16A5ABB38342C3FAC1BD1E9D89F7795C
+:10592000CD7C7A1CF8E54A28295FC03CF879951FA0
+:10593000F2751EFAF169379E47D9FF412E943596CC
+:10594000AEB5B703BFFD9B05EDCF2FF60DEB33AF23
+:10595000EE388FBBBCE514F9796BB6CEBBB83D779A
+:10596000D73E6704EE41BCABCED2E35F015DDF55AD
+:10597000C7F24F88D439EA56833DD9C8F7437A8FA6
+:1059800003FE82791C6D9D0773075C01FEE593633E
+:1059900064F4230EBCF9C5EFAB69DD31C88E7EC25D
+:1059A000DA344EBFE5CC6F7D322DE01C09F1AF3506
+:1059B000E97E95AE73CD6BA443A4703A38FCFE48E3
+:1059C0004529DC0B2D62EC6C7D6C7BB802DE2B660E
+:1059D000F7CE78B95DBABEF3641BD0E3E96336DC79
+:1059E00077F8CCCDCE11AEB10673C18EFFA45D4E5B
+:1059F00078FFD99FDD12CEB75DE81280CE6793B0F5
+:105A00001DE4C5BECEE9FD613E1E3FF102F99FDEF9
+:105A10006211D9FD685ABC252AB178BF2AB17A80B3
+:105A200097DE14FD7D63AB274DC03C8F39AD6F63AE
+:105A3000329EA734F13D3FA92E365F7767FA64BCEA
+:105A40007773828879D86E7FB700EFE57556C8F80E
+:105A50007E58E8F3FDBC655ECC4385F741CEE75D3B
+:105A6000E6FB3617CBD3DAC0FDEC76ABBF69021D7F
+:105A7000A77D6D9A00F8D0FA292E26574E4FD0E216
+:105A800048618C23E5167A53E01E8BDC00323771B7
+:105A90009786F1BEEF6DD08FC559110EEDC35F8CA7
+:105AA000C23EF61A88AF009EAD8C9ED6AC1530AEC5
+:105AB0004AE13700F4C4270FDB6E8275E4350B5ED4
+:105AC000F0DD699970DE33DC7646E7AD8FA25F08C2
+:105AD000615A183777CBBB382F7792F5AE70B37B0E
+:105AE000F23FB9047D7CE964F726E6D675F2FBF156
+:105AF000A2780F5E18E004F54029BBDF440A28FABB
+:105B0000FC9838FF2CE7744802B0CF56592647203E
+:105B10008E2036B7CF8075CF0EDBC80D747DAD42B9
+:105B20006700F8451D23F2FB9402C7014EEB36F4E3
+:105B3000C73CBC55622017F4B0FA7F64DCA73B1861
+:105B4000F86233DC1FBFB54C46BE381860E70D9FC6
+:105B50005C56D00EFB94EEBA8AB6D974BC88574610
+:105B6000C9D2504ADE1806FB94CB44AF40FB878372
+:105B70005ADEB6D7017431DAF2E5E422D8C7CB1683
+:105B800031A6745A60F736AC5C56E105BCAEF466DB
+:105B90000A7AFFE5764E07C7D383B7BB287C7C0F14
+:105BA0006EF452338EF267C6151047549B65453B21
+:105BB000B70BF73D6470BC64748AD12A0FD65DF3CD
+:105BC000D2E13E5D162F7DE8C6108B73C2DEE85829
+:105BD0008C73F23F1FE23593D7D68C706065D38A01
+:105BE0002AEC0FE364D171324AC5E8583AEEB6B4F4
+:105BF000C0568CDB4DB4239C88D4D506708A4C1CCF
+:105C0000E0877B6D378E1BFA369C5FC938D23D1D0D
+:105C1000F4686490E30FED20A756CA0AF079C6B283
+:105C20005377C2F334FF23F74299D1F8FE0320A73C
+:105C3000D3BAFE568FCF27C986F862C6879F7D03E9
+:105C4000ED1941D910A7FC3A3DF81380CBD6E2708C
+:105C500018EFC5048C66C5D7B16779E724B8EFF8AB
+:105C6000F434D1BF8DB7E3BA3679236B18DC4A41DF
+:105C70002F68705B252A1D5158D7543BD24721E924
+:105C80004479950DBBD983E378C9F870F512C8D76C
+:105C900030CF679D4BE8B97F03EE09045C417E8CF1
+:105CA0009CCDCE15EE2DE9F4813DBF362D717CF2F1
+:105CB0002D377BDF26B238ABB9FD0D37A30710892E
+:105CC0006D252C5F7E24942EA2A64299630F40FE80
+:105CD000F35E51F923D2F9468B02F881FE568ABF52
+:105CE000036F7C8EF1C503E177B17CC65DA4E5DD71
+:105CF00047B3E8FBEB4AD97DC7EBBC8C46AA9B991E
+:105D0000BCA8F675D961DFA4BA9878B7717A533513
+:105D10003843BC8CEBABCA5B195C338B09EEFB429E
+:105D20002C08EE9BCA827E147E99CDCB97201E490B
+:105D3000A73A98F65B07E3027E1A45C2C6EDB22386
+:105D4000FF862DB8EF49F9FD2D886B55B6F6C77D56
+:105D50007F38360CE3A5F3EFA6F3F1DAE938103F0C
+:105D60003CDD6CC17301907E03756519A565A4CFF8
+:105D7000EEF2223AAE52EAF5AED1E84093639435A2
+:105D8000E6507D01709BA3AA4B80FE4EDABD6FC02A
+:105D90003C9C9B6C0AAC7FCEA6979682FDE2F47584
+:105DA00035837CA82E63F34D6FA5CFD1CE51DE8213
+:105DB000FED5AD36857D8FC3AF94D31987C35C3EC6
+:105DC000EFB95BD8BC1D832261A0CFEA6514AED0C9
+:105DD0001662740F21D18B22F2D51158BF5BCDC250
+:105DE00071FBCD30F18589FEB47555F275552E6382
+:105DF000EB229C9FE8B4A2306E65295BE71CC2DEF3
+:105E000017E1391D7F2E5F4FA5FA2296739B6D8691
+:105E1000F1B716EDE884F9E417CB0A9E1321ECBE26
+:105E2000C35CBEAEDC46F6BDDCE217115EA44E37A5
+:105E30005F8CABEAEA94AF4EFF9632165C0A00071D
+:105E4000D8E8B8277F2CE37E4EE126E3BA4EAF1E9A
+:105E5000B6BD95B67FF4B08CFBDE7B45FFF13CF41C
+:105E6000476585C91FFFBB53404ECF6DF4831CDFD0
+:105E700053CEE07FFA6612017A187224980EF01E53
+:105E80007224C4CB5ADC4FA700117AE41E9D1F7503
+:105E9000999A059097B1C1CFCE033950C6EE231F12
+:105EA000A49F379D5F46735605E4436596A557C882
+:105EB00078B5ABA9FDC863D345683FFCD8BDF09D5C
+:105EC0006CA25B0F6D973D83D97996C3B415FAD553
+:105ED0009D7A10F0D1CACFB90E8199A5637918CAFD
+:105EE0000CCADF2DE9304F894C2889CB839D0F8F59
+:105EF0001D0D7205539E4AB08C9292DE7243D77F7D
+:105F000038EFAF0A09FAB93D8AC13FDFF9F0F5C3AE
+:105F1000C18F5F0776622ADCC7E6FD12F27454BFB8
+:105F200088705F678DDA8B697D15B51BC17E595FFF
+:105F3000F4BE087CB76E1FF1037D6404FFCBA6C7D7
+:105F4000E30D6EF6FB3C924C5A80FF0F0E3F350975
+:105F5000F0143940ED4EDABFE237AEC79C600FFD5A
+:105F60009EE5C1B4FFB616F5F7FDB972C2FB78C95C
+:105F700025EC4473FFF421D3319E97B76903DEEF1C
+:105F8000593D49F2DF407B676E2A2F073B46095295
+:105F9000EAEA4FE7BD65F4726042650ADB2F5326DB
+:105FA000B1E7CA0456B6D41F7908FCF6F02E29A52D
+:105FB00090CE77C46A76AF584BF117F610B54B4BBD
+:105FC000CB9FB7DF4C9F7F5C4AB5207DFEF1B55F6C
+:105FD000A4C0FECE93A5151900CF7DCD46BB8EC0C3
+:105FE0006557D41F1A690B07DC745EADEF1184A7E7
+:105FF000C5166DABA475CB4B2EB0707AF939AB5B7F
+:10600000DB67009DCE2992316C6F5EEFFB5C9FCC0D
+:10601000AEEB9E04F7EBE7AB84C5F7C38FA2509EAF
+:10602000CB4546BEDA8942C7BD89F9276129F03AD6
+:10603000C8E570714886573479D63AA4F22990673A
+:106040007FE2761DA99D87E7C890FF2D600F7597A9
+:1060500027F29B4A5D0EEC7F7ACB2D1F409C7A4E37
+:106060001DB3F7F3B67C29203EA8DD974DC7CF2B93
+:10607000C5AB06C99C6561FB48C04FA1481405E645
+:10608000D341C04F0853FDA3878336EE7FF7FD252C
+:106090006E1BF26129D8CEBAF5B8F87A72FD743D5C
+:1060A00009F47409FFEE8F9EF8F2C03880FF32E6E3
+:1060B00022E5854F0876DD3CF2D4CB9BC755301ED8
+:1060C000D8AF6E2F8EEB2EEDC2FB5CCCF21DCC79DF
+:1060D000E0DBADCE73A3997F6F94A7BDEA9CAECCF5
+:1060E000CF734DF26AA4ADE346C4EF1E76EF35647C
+:1060F000C442BB404485DDFB19D1EEA7AE857E23AB
+:10610000DC2E2FD041EBF0F74B003E6BB9BD30B722
+:1061100098A0BF3A37A713ED85D98DDC5E90FC4D72
+:1061200020649D5BD2C81A9DFD80A612B8D08DDC7C
+:106130005ED0F43FD7DBD5BECE66D4AB8DECBC5F72
+:106140008F9DA132BD9AE7637ABDBA997E47E1C4BB
+:106150003C566F97303DAE6CE2F603D7C319FCBBDB
+:1061600099CD4C5F65801DE181340815F532EE61F3
+:1061700065C5ED967EC54C5F66B4EE45BDD6013F64
+:106180002E3306E406D39783DE3EAA02987CF47190
+:106190001B95D38FF3769F97DA67E971FB6C95C8EF
+:1061A000F79B08B30F31E79FCEF321E8AFB31B771E
+:1061B000F0F9ED3D9C7E13C8D79DE1023C57AEF14E
+:1061C0002D463F693DB794E5AFE4D6B17D72B7BFC8
+:1061D000EA29FDF9B3796E76EFD03C8DAEEAA23EA6
+:1061E0001817EF8540392E637C7135B59730FEC4A2
+:1061F000FDAB6B5C3CAEC1E927993ED1E4909B04BA
+:106200003CC514BE1F479E4279AD527F09D6F67138
+:10621000B861C0DDC0EFE169A530FF75E3BEC2FC27
+:106220008FBC24FEE29F353FF35BCA75F7A4A3CC75
+:106230000FED14139EEFC9F1B0F84387449C00CFD3
+:106240009430BB472EA54C4ED83FD5C3ECECCF398C
+:10625000DCD68D7B0ACF6726D5CF12512D09F4A944
+:10626000A66F5B01CFD7D0FEEE379A54F4D323410B
+:106270000BCA57767E314CBAD08F548B648C1BB6C8
+:106280005AC376C0C7FA528E57AFBD1DEEB7F9D6C6
+:1062900078A1F0003CAF0E8811211FF01CF18E6434
+:1062A000711D3CB77C9AFAEFFAFD8AE11E91C34951
+:1062B000C11FE6CB6B66F4B56E9C8CF358333AABDA
+:1062C000DD92AF97BF02979FEC9CD89A71AF237D68
+:1062D0005DEEFCAAEA9EC57B3FB4E7A7363F5D00B2
+:1062E000708EDF7F11E8F33C4555DDDF36ED48B0B9
+:1062F0004FD0D30E7E940BFCC0C81D867D4D8EDF23
+:10630000091ED1107703F96A45E7223200E24B7B80
+:10631000C6473CF01E59C6F66DE7F37DDBCF77DC50
+:1063200082E7C94752B2B226C0FB67F5C6F3EA9FBF
+:10633000ED7C7A008B6B440C79C2F39FFAF908C3A9
+:10634000FE7080289963F915ACC0EFAFFB559B2513
+:106350007EFF800CBF57007176E0E0C170AB620732
+:10636000962EE05F5A7A4837965E504783C14FF2C7
+:10637000639949825866915A2C7D248CE500D2811C
+:10638000650EF8B983412F7463A910AF487472BFCA
+:1063900080F8B15E4882584A80B78CF8BE84B4CB8E
+:1063A0008EF91BB07F017C9FECDC99DF53B9C4836D
+:1063B000FC5D7B25FB1D23B65F31DD13B8C78378F9
+:1063C00088A2FC9ECD45F991E74674C0F9A37BD61F
+:1063D000B2732F9A7C47FF867EE7D974A60FD48DBF
+:1063E00002CAB115CEA9DF4578B65ACFE8F71B88A7
+:1063F000DD5E08BF0FA28D3B9BC71966733D08E1A8
+:106400006E767ED08FE7936643BC41D74E7ADAD959
+:10641000BD34DA38A2F3DAA17DEDF7E9DEC7FCE896
+:106420004A931F7049FD6DAACF31BFFF359D50566D
+:106430003C1EF7EC77955CA457AEBF294129F85E66
+:10644000B3ED04FA63E189013D5C9EE17CA0E9952E
+:1064500039A67C0F733947E2FC611A876AC0343869
+:10646000D78B774AE8F85BBB9F54BBBF677E20247D
+:1064700067B3D77C80472F9F77986CA9C8A6E5A7FC
+:1064800050D7C5F78FA6865EF2E8FC116FA056D4F0
+:10649000DF77B390F3E3444B6B39C8B9D321E207FC
+:1064A0003F623EA9F57C07E2F9472D28E706D2793D
+:1064B000CBF07B2FB0C1918E75157EEFE56C3D3B27
+:1064C00027748ADF33FC14DC4743CBBFF07B85475E
+:1064D000B62D9D0A74F039BF5FB868DFEA20C47D2D
+:1064E0004676386781DE1FD931BE1ADA47EEB2B17F
+:1064F000DFF1E172429B171C7377A4E33976D59ED6
+:106500000EF284A0DE3DDBEA88C0EFFF9CEDB0B068
+:106510007B558B45BCBF0CAE21B4F0F9A5A6C3F7E3
+:10652000FEF387608F7CCEE5C9194F1AC397A40A82
+:106530006A26A4A5103FD8351B9C8BF01C64952BB4
+:10654000F2D46399901F6EF7AFA0DF3FB0F7A55C60
+:1065500078FEA87311967FD9FC412EC8ADB3FB3FDE
+:106560009013D16D8D1495213EB5609F20C2FE49D8
+:1065700079C72C19F647AA761FC0B8728D3784EDFB
+:106580000BDBF6627DC2EEB771FF6470AA82F33A4C
+:106590009B1DC2386F619B2D0ABFC7B1A7207C77B6
+:1065A000C27DFB54A66736385FC5F11F75BEFA3A47
+:1065B000C265B30DCF7F1CD8FC1B1CF7CCFE97F82F
+:1065C0007C09E60B9E4DE938FE13D05F7BF9794CD0
+:1065D0007BA7471F0F965205837C3DEBE6FB5E3998
+:1065E00097E8C7F30589ABD3C3E452A707F6CDAA52
+:1065F0003A181CFE628DCA60472EE81014F83DBDA3
+:10660000F2DDED781E70C13E3B9E975800F000B859
+:106610005178215CDA0EE0FC0B002EFD601DEF626C
+:106620003E7EE13E0A9751F1752F7085905FB5F57A
+:106630005238B075EFB9149E42463CB5BD2D435C4F
+:1066400066E13E01E1B770379B47D53E36AF09BBE7
+:106650006721FECFEC270AC45B4EEDFDE07358CFF7
+:10666000D9FD76BCCF579B17DCB7E02901FE6174DA
+:106670004AF631B9AAD9DD35912CFCDD819EF6DDD3
+:10668000EC7749016429945E47EE9B86FB82A54026
+:10669000BCC0FFDE8E11ECF705C3B900D73DE3A304
+:1066A000B930EF33DAEF2349E15CC08BDF132A4DB9
+:1066B000D5E1E3B3132FA15E2C126BFFFC20F0F1A8
+:1066C000F3EC7738967EB841D4C3E33AF841AA3167
+:1066D00000B7B73C08B79EFB5BC22C5F8A84901F53
+:1066E000AB383F9E6DA77E275DFF676D2F60FBD99E
+:1066F0006C637ED55FDA0EA503DC2AF9790C12B93A
+:1067000005E511854BB33D819EEF39D71661E7153D
+:10671000CF09FC3ECD2734B8D5CAD30DFB7C4C1E27
+:10672000E66CC93F8C7E4624F13947B39D64BE2F89
+:1067300035593EC0492ECF3EE6F774697A77BA27BD
+:10674000342BB55FF2F3DE952D35B900EF4A381BD7
+:1067500089F79C1EB801E215786E88DD931A05F85A
+:106760009CEAB907F5A51B20CFF4541AABD7A57640
+:10677000AE02BBF69476AFAAFA1A7B3F9FB56F8242
+:1067800076DAFF394FB03695D9F702FB7D1F6B1AC9
+:10679000FC4E83A63792C3C1F83B0D4FD3B5025CC4
+:1067A000E8783FC1F1243ADEC87F7E3C4D4EFFD3EE
+:1067B000E3D8FF67C7D1F417F027A43E12BF7FC408
+:1067C000FF04FCFEBBEF93F05C035F5DD83CB809AF
+:1067D000F6D1CEFBD83D30B6D6E504F4F9DC4D1B3E
+:1067E00012FEFE5B4F9DE7E5C88329BFE9F8FA4832
+:1067F0002AB3CB8F70390D7FB0BF0577E5A05D4C14
+:10680000FF5AB3307509FDE761FC1EF3221246FB07
+:106810007404E9C0B2987462398A746389DBCC83EA
+:106820002154EAC7F2AFE55D6361F10BEDA1275397
+:1068300044CC3B780DE4D0D941A1A7E1A2B615CE56
+:1068400045D7C0FCDF48F57278450DBFB742F4BFAD
+:1068500087A1803D38C5D7973D48BCD2999EBC974B
+:1068600002BCCFF6ED545C5FB2DF515B62BAF786D3
+:106870009D0BD7E050433A308FE4B52DF7BC319CE7
+:10688000C2FFEEDD6EB493876E695C02F2FC6ED2DD
+:106890009905E78487F27B44481BBB0F47BB1F6405
+:1068A000789BCDF83BC2A6DFE359C07F3F6B81F9EF
+:1068B000F7A9F839DC167890201FC37C8EF7AFA9B2
+:1068C00089EF7D21C5897F0FC57C8E77778788F911
+:1068D00051F740DE95CEBF18BEA3D666A42FE5DFE4
+:1068E0000AADBABAE067F108B723B053E8FD9DFFDF
+:1068F0000B82D8B2B4008000000000001F8B08009B
+:1069000000000000000BDD7D0B7854D5B5F03E3360
+:10691000679E99849964924CDE131E21C86B0221F4
+:1069200045A47A122246A43A3C6AC15A9C8040800F
+:10693000BCA068B1C59F8144081425D488400107D4
+:1069400044C5FAE8A417E561B00344448BBDA15ADD
+:106950002F522F1D901F1111466DD1F66AFDD75A87
+:106960007BEF6466480AF4FADDFFFFFEF4B3877D2F
+:10697000F63EFBB1F67AAFB5F70C77288CA532F668
+:1069800082A2DCE31DC4D837F87753D773AA5DC75A
+:10699000D808067F8D6C5C31630DD5AA7D15941ADD
+:1069A00002564DEF84A75D1750F219CB4A2C33CF16
+:1069B000853273E8ECFDDC8C8DD58F3EEC86F6C617
+:1069C0001A75B809CAEDDBE67618F07B97CA4C3029
+:1069D000649603FA8532CBD005FA41B9D1FE1BC7C4
+:1069E0000C18BFC006EFA19F1C3B0BB8A1DFFD5BDD
+:1069F000EFD761B9A19EB1741C47F175B8E93B9519
+:106A00003D85D362DAF8A234C6F2F09F308ECA56C2
+:106A10007FAA4F62ACBCE6B4256C83F7E1CAF16C87
+:106A20000863A5F67C5AA7FAFEAD1F6179CBA25385
+:106A30000E1F8CF7C6D6E57F180BFD1902302FE824
+:106A4000A2F0EB86E36361BCC85623DBC6BAE090D4
+:106A5000BB583D1536D380EC1BF82F7B616CD9C831
+:106A6000A05C28CAF9388FA87A280F17E333368537
+:106A700085D2B05ECCD7A93106F364769BF3CC40C7
+:106A8000C66EB22BEC9BDE5DE511A2BCC3D05C668A
+:106A90008579EEF84FC5B314AA0F6C9D9587EBBBB3
+:106AA000B4C7976787752C32270D61BD2EDF3F83F2
+:106AB000DD2DF6CF6FD1B9F019B2305757FB01DB9E
+:106AC000EB4D3EE8A77109F39CEEC79839D06E1DD7
+:106AD00088FB78D8E081227B4861538250AFDA98F6
+:106AE000168471860B7C897F3EB4C4FDBBBE86AE26
+:106AF000711FFA7AD214DCDF48A255DBA65C3E2F68
+:106B0000F99D6A77FB717F0DD9CC9300E3199C1D29
+:106B10009976F86EE02EA3C706201BFBEB41BDC2A1
+:106B200030EEC08353993B91C30BE7AB2E327A4EC4
+:106B3000A730665AE4F4A8C3B19D8DF0F1339B31C0
+:106B40006042F82FFA7933D6376C2D71B9A3F07AF9
+:106B5000F912BB4785796E5A62F6A8B0C0E5627D2E
+:106B6000F1F3CB71E8BC01F8CEA8633EAC5F00FB4B
+:106B700080705C604FA0E77C51DEACFA27E2FC3706
+:106B800003FE2C457C5DC8F1774186398078BEE0F4
+:106B90008D3EE9AC1BBA92CFA797B83C7D611E9B96
+:106BA000164E7731F8B4747EBBE51658FF8244B3B5
+:106BB0001DF1519F54F0F868C4F7370D0CE9AA2174
+:106BC000B1C43D23AA3F7DD24817C243AFF3673219
+:106BD0003B632BECD32AD40CC417FF46E6616C4D03
+:106BE000F3CDBC9CE8CF54A0FEF1E65B7939D5BF6C
+:106BF0005181FA279ABFC7CB39FE4C1D949F699EDD
+:106C0000C0CBFDFC1BB1FCEBE6EFF3F26098432632
+:106C100063BB9AA756F861FC0683678A07C67D1195
+:106C2000E63F08E61F14CF3D76BEAFB2FE37F81E32
+:106C3000E0BD533CE3EB5F16DFEDEEA17EAFA86F46
+:106C4000EBA1FF57C577A11EBE3F20BE6BEFE1FB56
+:106C500043E2BBC33DD4BF29EA8FF4D0FFEFC57731
+:106C60001D3D7CFF07F1DD3B3D7CFFAEF8EE580F8C
+:106C7000F5C745FDFB71FD9F10EDC3E27D7662D344
+:106C8000713FE05D36F02DFC2B4C6C4A46BCDB546A
+:106C90005F4CF8DF3002F07C5017BE672BCC8BE5E1
+:106CA000210E95FA1B82FC189E6F8BFE4BE7F75D59
+:106CB0008378B7E02DBD07F1B041F11CF341FFFE31
+:106CC000F93A0FF2DD056FE8399ECF57032C8ABEE3
+:106CD000DF8E9BFF1631BF4631DFDFD97B13DDE44A
+:106CE0002D7279C64B7E89746F8F2D9B819E3418CF
+:106CF000BFD1C9E54BE1FC32737F941F205F906FD9
+:106D00003E6433864C30FE437695EA1B9D6576AC37
+:106D1000F7DB55923F0F39CBCC3390AFDA80D99562
+:106D2000C07876DE77A35DAD0820FF709453FDD860
+:106D30005F8FB7231F6D64114729AE6F31C815F8F7
+:106D40007E7F7D19BDCF73FCC581FCF968325F572A
+:106D50007BE2214B3EB453EFD391BC28B0AB24C7A8
+:106D60007A2FD605DCD0A4DDBE4087E5271BB9BC51
+:106D700082BFC42218BF2F1F9EEDB8BFE4CD42943E
+:106D8000670FAB1EB79BBF53A3E4415F94574938CD
+:106D90006E728CBCDA5CCC34ECD7EF32079E827E0C
+:106DA000FBAACC9592DC05F73C879ECB17FD780FAC
+:106DB000CAB53ECDB1F229BF294A3E319497B1F20E
+:106DC000295E5EE5D4037F8CFADEE4B2C7942D8E93
+:106DD00044924FC0633CDFC0D00B5A17DC62655D44
+:106DE000FC3A5E1E3508F920F96EC3D7C363E4830D
+:106DF000E4CBF1F2E1CAFCF5ED5BFB131E02B772C6
+:106E00005F99CFBE8D7800F867F029243F98EA7328
+:106E10007913AF0C2F83C16BB7DBAE0C3743EA3B62
+:106E2000A457187C2AF57F995CB9025C653BA3F9ED
+:106E3000C9CDA741AEFDE5FD9F14322099E5001BA9
+:106E4000DAFF545DE0295877F6A2E73663FF5987E9
+:106E5000AC8D0867A36BC6E6465C4FF3E38C013E3E
+:106E6000E9CD1C9F8C196576FC5ED569AEE43E5079
+:106E70007EF6DDBB14C0277D4ABD87C1BE1D7EF1F5
+:106E8000CDE4DB107E6F1988CE4D3AAF9DF5A1E9B8
+:106E900010BEADC8B16E5D4578EC33239CB27798D7
+:106EA000490E30FFF6951A2075036C071B85F553C4
+:106EB000566AB0EE1D4A67F9562C070346DE1E5887
+:106EC00034FE5FAB4E11F54C535DA4778AFADF5464
+:106ED000948F86F6AA7DA00A7267C1DA979A0C3958
+:106EE00058AF93DF6B6C24AC17C7136515F6E7B981
+:106EF0007651EF3FD8540E44D46A94E3333FB66FD3
+:106F0000D5E978D9DFD684FDBF5026BEF73FBD5204
+:106F1000CBA6F9DCA67740D1F17A93EDFAAEF9AEC3
+:106F20004D7EAB6929ACEF1377380996C16AB69EDE
+:106F30004E43F9BC624ABD17E18688EF0599D84BEC
+:106F4000EF263CEDDCB79D13FC59507BF1D0DF936D
+:106F50000641559D3E7C2801E057B3BBDE6C80EFB7
+:106F60004D06AF3F2BBFEBBB9A9D95A4CFD4B51573
+:106F7000D1B39BEF0EABBDFFA5EFCCC6AB18EF9323
+:106F8000D01F6A9F87AA1A7D7D934D4FED19DFFFB1
+:106F9000EED727BFFFE4F93FDC89E35D7087D3C6F6
+:106FA00041EB1521804B37DFC9F6B5BB27D0F3582D
+:106FB00082B6C601EF6703EF227EA5D67BB07DD0F7
+:106FC000DC6CF700A02D86662FCA0D007D4037B21D
+:106FD000EBF90B475F6A1FFF3E9EBE826696321E2C
+:106FE000F978B54A722A68F6270C81F26AB043969E
+:106FF000C2949615BD3B6C10965FB231B44B1AAA81
+:10700000DB5D8390AE3C4686FAEEEAEB831948E7F7
+:107010008D35C629DB117F430B5C33A3F4ADB5C9B5
+:10702000069AC7CAD780EE86C2D3107428F87D3F6F
+:10703000901B0AF2459F19ED1C4B4632F3E7633B68
+:10704000DB6AA4CF95065F4519B6CBD0917CB1F42D
+:107050009B5C5106F370A5EA143DCDA3FCD82C949B
+:107060006F76234A50762279FA6E84D373AAA71ECC
+:10707000E9F0399BCDEE870AE0911AF23FB59F33D4
+:107080008065939ED5A31CCF2A02791EA5C79E10AA
+:10709000FCF384C348FC6EB52538A114FAB12ED098
+:1070A000D9FD30DECA9A751D63619C5FD6BC7C74C5
+:1070B00029BC5F95A6329C87CDA9868C207F0CDFEA
+:1070C0008339C2BC5F58EAB5237F8DA4AA6C1BD458
+:1070D0005BFB1A993B8A5FD90641398A4FA638551E
+:1070E000CD02DF7F95ECFB77078C3BFCAD77CCF8CE
+:1070F000BD6B844E87641354F93E2715C7F6631F92
+:107100001DDB4F72796CBD737C6C7DDAE4D87AD765
+:10711000DDB1E5CC7B63CB5324BE01CFB1813CB65E
+:10712000F22A660D7FBA04E52DC0E73D84BFB54065
+:10713000E741F8586AB69F9D05F559C84FD01E1A09
+:10714000C248EE1EC8FDA91BF5025372BDDB31E833
+:10715000727864E5986FC3FDB2F555ED0CDADBDEAD
+:10716000FFE86BECDFC6A2DAE5237CB488239597B1
+:107170005D309F44FC871BE15DFFE707512E1ED564
+:107180007B10DE59352A8DFFF0647740CFF5091763
+:10719000EA3349A27D927975871EF879D2FB2BE7F5
+:1071A000A3DD1B0FD73456AF205D027E707BBB92F0
+:1071B00091FC58A1635588376823607FA41E01BFE6
+:1071C00098946224389992156137AA3AAC4F13FA11
+:1071D0009331E35E0BD2F1438738FE3F64E4FD74E4
+:1071E000F6E7A64111E519F2C994645D4C3FEBEC5A
+:1071F000A28D28A73A78B9B53DF936A4CB759393FB
+:1072000087219E98D0EE82FE7A659BB501B03ECB79
+:107210001B46BF029DF65259BB01F6B2D5CAEEF12C
+:10722000C23C361CB6FAF5F0DE32F31776D4D38AB8
+:10723000C5BC5B9779DE463E10A954098E96D4668C
+:10724000FBB0417C0D7E981FA203CAC5D27E2DA43F
+:10725000E7594A9B49BE5B8A9A9B114E1BC6EB4875
+:10726000DF48BE5747F86CC9091EED8B7E82993AFC
+:107270003BF6970C82DF089D3C9ADDEC45BF090385
+:1072800098EB4A38AA60BFB442182745C0D5E9DC5C
+:10729000F91305FA49C1FE86F0F608278780D3E87E
+:1072A0006437C1DD29FA4DE90BED87F07E1A4BBA40
+:1072B000FA91FBB8A18205707E725CD94F67FF4CD2
+:1072C0005390AF1A7E0770837D5272CD34B987E632
+:1072D00032B28F5B9779EBB7125DDBC8CF91E9CC07
+:1072E0002E433CCA3CBC71A26E087E67A5710C336C
+:1072F0005900F1385365E61B9351BFF1121CE3E9C5
+:1073000035A3BD7912EAA9725FE2E93743654DFA08
+:10731000E4CBE938C3E92C2B18D20D3DC7D14BC6BD
+:10732000E1C87D88F4F174BD25E14211C28545B7FD
+:10733000D75FB9ACD7078FA29F87A5839C00D0E702
+:10734000C68DC7D83F4C585698CEFD4D1FE4FB0E56
+:10735000E1BF017905C4DA3ACC3EC686743A9F1182
+:107360007E95ED5A7DD7EFA0BF4BFD8C76942B39DF
+:10737000879B3B503EB2DDBEFEB80F9B54DF130926
+:1073800050BFE9583A43BEBDD2C2ED3155E079BC99
+:107390007C592BE8C68D72CEF5AF3FA57E18EC9BCD
+:1073A00036D00EB4B7F617156F9853FF07F52CF6C5
+:1073B00002E959D9ED1D4B6D38FEDAC34D6680AF39
+:1073C000E52DDEBE19CA7E15E1574DFEAC0339B37B
+:1073D000084EEA7113433C1DACD70258667FB230A9
+:1073E000E4BF3B5EBABBCA8DFC276D9C1BF9D0364F
+:1073F00041EF01619FC5AF5F356A3ED427E2DF6F81
+:107400004CD689FDF49EAD847D1CFCA491AD82CA4E
+:1074100042DDF426B4EF222B81FF42ED74BDBBF6B2
+:10742000E751F6ED23D6D26032DA254BCCCC070AF1
+:1074300073F6970AF30171E638FF508AFC279785A7
+:107440001494B3B9F5A0F0225E2DB4325F14BE6778
+:107450007FA952FB47AC5A3079047F6F063E60E04B
+:10746000FF64CF257B59A593F328D45F0CCF5B4FE6
+:1074700022DF60CE72ADD31EE98DF80B721FC6DB22
+:1074800027D66D00181A86C17F365DC834E4F2F63F
+:1074900007049C54B32D84FC52B51D3946FCC5AE7F
+:1074A0009E8F6E87763731B16A467E59840B957F01
+:1074B0006CA77216F05FD330D2FBFD687FFB93B8E8
+:1074C0003DC234CDED4C437A6104E46C336B3243FE
+:1074D0003BC276A0B70CD66121BDB99DB9911ED033
+:1074E000C3762681581643B86E62AC229A0EE453D6
+:1074F000FA25D4457AB2A7061EB4D07C0CF52C60D0
+:10750000417D08E706F05617B2809ADFE5171CE2C6
+:1075100070D37746564FFAEC0B5F9FC8443E6D3DE3
+:1075200004FAD850DC671DF129AB3596FE185B4A8A
+:10753000708A08FCD8BCC44EFBDC69BFF9DE11FBC5
+:107540001C5E8AF222776172CCFECA76D95F663100
+:10755000DFF0E87E03D46F76DF7605FD32D95FE693
+:1075600052FDE625EE2BF4DFBB87FE33088F7AEE63
+:107570003F9BEA3787DE71DC0EA0D814697778DD8F
+:107580005DFA753C9CB317C6F2E5A1BB63CB122E26
+:107590001683E69C0030B7DCA7F36C85FEBE732C27
+:1075A000B65D45FE1FC9FEED6A1F724EC2F6609FB2
+:1075B0006F85B7379C8D6DEF2D7DCD8174DCD59EA9
+:1075C000CFEFA62F63DBC5EF4FFC7C615EA9DF8F99
+:1075D0009AD718B329A67E4AE565F34AFD41D4BC83
+:1075E0006E71C5B6F72DED7E5EB7159AFEE9BC64E7
+:1075F000BB3B465E5DBBF8754CAA30F50077DEFEFE
+:107600000753AEAEDF1F56FDF376F72C8A1FC74F28
+:10761000F8BE40A78D4981FAE9F80AF5459B95F433
+:10762000DECBEC2C219FC6A1E201DF7992B471F888
+:107630005D85A43BE16738FCE275E9C8D7B3841FD8
+:107640009D09BF426BB58BFC0A3ED11EE44923F273
+:107650008BD61DF05D129F57B4FE9452CDED0A3BC0
+:107660008B103D4B7D2999D9156E8F737DA7A7711E
+:10767000E2FB7F18154098EF8C4563D80740872FB1
+:107680001BEDA52ADA675B14D20766946BFA44C037
+:107690008F514D0AF995663CF0F6A3E88FB9FEB418
+:1076A0007B7718DECF08383C386C6D07D3304E90AE
+:1076B000AE9F5FF4203C1F3BC0288E86E5F9886FA3
+:1076C00036CD8DF64625CE08FA396FA82FB223DFC6
+:1076D000FC914D43BE5939597B8FD6FB156825D097
+:1076E0006E265F3ADBD532C188F18ECABBDD2351ED
+:1076F000EFA90C5A347A9A996A857554823E86CFDE
+:107700007423532DF8B432333E4B9671FD2B69A48C
+:10771000D75809E357B63DF357FC6EB61ADACFF5E2
+:10772000C900ADBBB2ED8DBFA1BE3653F31A915F58
+:107730000CDC61E43AA9C087C1C1D832F283E87297
+:107740005128B63CFC706CF9D3140EDF51C28F7512
+:10775000609F89F8F6BC8FADA47FEE05818776B275
+:10776000FF0513C98F31F36CB45F1F9FB36E45BF24
+:10777000DEFEE3566A3FF7390B6FAF0BBE8865FF3D
+:107780008B096467CF4B099624C3BC5FF95A4FF04D
+:10779000C66519B0FF17076C5D85F5C383251817FB
+:1077A0007BF93AC63AB05E0D0CC175BEFC0FEEB760
+:1077B0008E3C6B0A6C837E3FDEF3CC8B3FC3719FA4
+:1077C000CD4A56607F6E40B900ED463D69B6A2BD18
+:1077D00031EAE3E7FB20DF98B7C314B3BE175314B5
+:1077E000A13FB89310EF7AF23B9E5AF90C7D5F7877
+:1077F000F618E1DD5E835F87713CFF4A8E677B2D63
+:10780000DC4FBAD7921BC07DDA97C2E9EA06DDB633
+:107810005FD6A27EF916D7437AEABFD03563737973
+:10782000377EC6CE7A18371FF6F9E247D67BD01FCF
+:10783000D77F7DEC3E0D08C4965F4BE17AC274168B
+:10784000F53E1FE7D37BB90BE7B395D17C0ACFBEDA
+:107850007F573EEAE326AE87C48FFBFB142E3F7FA3
+:10786000F52BE887F3193DD7C3016240D7F3043DF8
+:10787000BCA2703D18FE166601FECF4305A277D765
+:10788000FB7971F390FD2F1570FADC9CB40DE5B90E
+:10789000D3C8F1FEDC92C38F621C53B63BB344D312
+:1078A000CAA3FCCAB3D6CF3F9401FB5FDD9A4A76E8
+:1078B000A67C5FFDECC1B41FC2FBF33B540FAABE14
+:1078C000D5539F7E6414B67B561FC47962BD06FDF6
+:1078D0009F0FBE9684ED666D720C437F89FC7EF629
+:1078E000FA9BB5F2287E7AADF424E9BF5AD8C7BB1B
+:1078F00046768CCD0278CF5BAF78B0D9BCE0F72765
+:107900007D0F759D4D7A0FC6374A54E6D50F23D3A8
+:107910007D323EAB5B5F3A9409F575FB4694E0BA65
+:1079200056E9BCB70D467AD962203F58FCFE189D37
+:107930001C7FE1FB900EBE5F75A7AD0AE322D06FFE
+:107940003B960F146ED3A31F3FE92CF037FEFE9831
+:107950000E78E6D9B6878680CD02786C6B42FAD86D
+:107960008B8E0B1CE7053DC90916E2EB1825FCCFF1
+:10797000F3FEB3C5A8C2F3ECD96549A59CFE689F88
+:1079800090A93B617D554F0E267A9DBD3E96BE6403
+:107990003B39DF3981D8FA78BC28704A7F052B8CB7
+:1079A000C6AFF87629E3FD46A4C7EA45C0CFA3E8F1
+:1079B000A6FA74B311F5AEF871508364725FF58462
+:1079C00097CC4DEBB5F0F582CA6B86F59EC37F71FF
+:1079D000BFB98276FD5C8596C8E65DC7CADD00CF7B
+:1079E000791359053E253F3C3F323804DBEF35849F
+:1079F0009FFE25F1C144E207E7EDA124F42B650ABF
+:107A0000BFDE79772809F9DC4511B7C37A2CCF6D31
+:107A100003790074FDF12746920B4B83079370BFE7
+:107A2000CEBF68D1E9605F3E6E4D29437FD0F9E05B
+:107A3000EF92705DE7822965E8D7EB894FC4F33791
+:107A4000A90F9CC47F5E0F7A8F531BEB44F86290A2
+:107A50002103E44D4A7D517D37742FBF731AEB8BA0
+:107A6000304F23F2239B671B8713C5F33E3B9CB229
+:107A70000DF75BF2D94A85F72FBF9FEABC3ABE5A91
+:107A8000B16A00C5993E63EE5EC8E7EF46DA80F959
+:107A90001DDE5FD00BF50DF9FEC134EF3D4EE8CF92
+:107AA00055D641F901AE71CCD3004D3FD07BEEB736
+:107AB00003FCEF6520FFF059EC3392DFA63195D639
+:107AC0003743652115F07D06CAE72154267D68C637
+:107AD0002625D000EBB977752CBC66B598BAF004B2
+:107AE000FE9BC380B122216E8A6A07FDCF41390C0B
+:107AF000FB30D7CC4209D0EFDCEDB1DFCD63219A6A
+:107B00004FF5F3DF98BADB8FBF8AFD78304D5B8489
+:107B1000FBA14C34D3BC7EFC824272D229FC9591ED
+:107B2000C77A0530AE364FCAFD77F8BED53D50A9AD
+:107B3000DD0BF87771D10CEDDE144A3DD1501F6199
+:107B40002D8984CFF3CA592807E637AF4D090D4E6A
+:107B5000EAEA8FFD46E1761EE3F1CEBFBEC3F7F140
+:107B60002EA13FCD84D7A88FDCA0E3793D910D0AEB
+:107B7000C9D751CF2BFE44E0CF33CD602A229F12CC
+:107B8000EBC6F6BDA03C9BF9094EBF74E6D3FAE6FE
+:107B9000B00E23A7A340431A8C5B7B167813BB1A45
+:107BA0007CB89EF6FD73E6A17DDF82734E457C288E
+:107BB000213C91EF414F6296E4CBBFC7FDD3A2E0D9
+:107BC0005DB529B6CCB647957BE3FE40396ADF6ADE
+:107BD000777E63D2BAD9AFC73AE55B60C084C1D1C2
+:107BE00074C2F5F013623F1FFBFEAC0CE44B6B500C
+:107BF0009FCE141D8C443ECEA49F256486FEADC34B
+:107C0000598CDF05F43D2ABFE2FCD1B8F5D98CAD23
+:107C100033F8287E3143EF3D84A1B6A274DF6F11A3
+:107C20004F66E8B45C95E0AA1590FDBD88E3C3E318
+:107C3000C3EA07D4776377CBF9AF5382211DF2A74C
+:107C40003D5C5F492C8E187C5174FF9EE0BBBD0EDD
+:107C5000840F6521DEBDA4509C6083C21A1580B3D9
+:107C60000BF619E5D306E5E42194671B6E75B306A0
+:107C7000A82FDE3961FE6B64BB5B29CFA86667A9BC
+:107C8000BEC646EBE7FA7342FD561DD4A7DF533854
+:107C90000CE90DD67DCF44787FC2E9A67965D83846
+:107CA000FEB896F9F317A09FF88077FE6B8877836C
+:107CB000ADE48F4B07582526D3B309F562175BAAAD
+:107CC00060BBE5A90ACF83A864537E3388B059ED21
+:107CD00095CC9FC7E0A9A8AC11FDCBE92AE8D9FC57
+:107CE0007D238EF358129F57AA4E7FCF04D4F3877B
+:107CF000F172F26245DB46F26C2DCD2BDDC42A70A9
+:107D0000DDF81EED029886D64AF5018253FA98FAFC
+:107D1000229C477A1FFE741A43D9D8CF914E3CF16A
+:107D2000E9507E2C147AC0C2AD65E9C8EF8F9C374C
+:107D3000ABC8D78FB8A43E1BB2A13ECBFA16F2F661
+:107D400042DE2E2C1A938E44EDCC8D6D77D1A0F5AA
+:107D50001A8E72EBA89EE24F7FB169BD1CD0EE0671
+:107D600023EB36EFAF572ADFD7BA2F151688F26309
+:107D7000D44DB944F642DD976ACCFBF34BCC2C10C2
+:107D8000E5C7A8AE3A3016DBD5B08EE5888F35C191
+:107D9000041688A28F1BACDD8F2BE9A2EE4B3DF3BE
+:107DA000773BAE31F6FD9729CC9FD25DBBB4D8F7B7
+:107DB000B08E98F2EE2F3AD781EFD9C87012FA75CB
+:107DC000C7A37C86F2C580CE6F00BE75C4C0E5EE49
+:107DD000057B38462E5F7087B95C46BF958DCBB367
+:107DE00009B8CF6A24696262D738B21EBF4F8E5A73
+:107DF000EF85294616A2FD89D03C107EFEFE8C6DD3
+:107E00006CFBD488F93AD56DFB097E126FA2E1E8CC
+:107E10008F8E8335748474C033C6A56E5F35680059
+:107E2000A0E001C91F9E5EA58D867ABD2E865F24C7
+:107E30001477F20F62578F61548EF8CD33ABD06F49
+:107E4000DB55E6EDBBBEDF310EEB8B07F1EF27A76D
+:107E50003EFBE6324A6A69E67A971AC9F5264695E4
+:107E6000CD71651B94074795ED71F5CEB87A575CD7
+:107E7000399BB73F9F18CAD57B18BB27F585712A58
+:107E8000F0CDF319A16998C7B6BAE1D7E3CA819FCB
+:107E9000D51473395FDBA678485C09F8D57AB81E2B
+:107EA0006BF3848D983F9750DC7108F94BF56EC5E4
+:107EB000AE003DD882AD212AE377EEA8EF820A7D9D
+:107EC000571D3C49DFF5D87FA18EE87D55E129DEBD
+:107ED0002EF821E9132B1AE753BE808C87EB994FBC
+:107EE000CB52BAE2E192CF5EC8D00E129FDDA7D886
+:107EF000913E3BF114FB8DF243C9F67F1ADCF64745
+:107F0000545712167EBA14F5EBFFACF97004EA9BD5
+:107F10007F12F2649D121880E36E64BE01284F7FC9
+:107F200054D36FBF0EDA9D30843763CC6F4BEA6B4E
+:107F300004BF1389E11CCC0B0C3CF6EFBC9C1ADE91
+:107F40008CF0BCF458C738CCFB3B9113CEC13CC07D
+:107F5000EDA9FFC5CBFDC29BB17CE4B133BC3C387D
+:107F60009CA387EF7BFB3F1C570EDF3F65EF9EAE68
+:107F70001F13FC44CEAFB6AFD69C8A7A5E359743CA
+:107F80009BC1463303DF9C36F7DC0B4F011CA6FD7B
+:107F90003481F8D953E7278DE3F682DFAB96A03F13
+:107FA00099FF919C247EAF929E9181B231B96B3F33
+:107FB00012733BDC2447AEAB6F45FD257DDA209282
+:107FC00023E54EED0B1C573EF767C113DA7F916A2C
+:107FD000E7FC5BAFA3F87AFACF1249CF5B63E1EB22
+:107FE00001BAA1FDB589FDF89558CFAF52B91D7AF8
+:107FF000BFF366EAE72EA1DFB7AC0C3C6B01F81FBC
+:1080000097793B6BB9BDF0C3ADC057808FB738B41B
+:108010000CE4273F147978927FE0FBE4283BA9A584
+:1080200008CAB62E7BB86582966175E2334D8771BA
+:1080300024C98F5AF2F977522EA537F071D3D70C95
+:10804000D886EB4850B93F6CE694826D4B492F9827
+:1080500048F3659A96A1407FA7E7F4D6A19F4CEE1E
+:10806000CF9ABE5A3BAD47C419E43EC9FDFC2295E8
+:10807000DBF733F4A057C03A2DE93EEA0FF48C2128
+:10808000C21F477AC617B8C751F0656A7804BEFFA9
+:10809000FF084E1F7D1B70AA5904FC427715FC4255
+:1080A000C06F9D1232A4737E41F63DBE47B9D3EE38
+:1080B000F47D9D1A95AF33ED6735A457CA7925FC39
+:1080C0006457C50FD8E57416AFF799D2F87E49FD0D
+:1080D000D423FDAA629C13C7CD144739610C12DF6B
+:1080E0003C0176D552E42F220FA0E4A7F38EA07DA9
+:1080F0002AFBAD49D373FFB4DC77C5DB3A2B1FF302
+:108100006298DF8CEB9860A47D9772B7C5C1F35C71
+:108110005A1EC8A23C978B2CCCC83F3B92117F04BF
+:108120003CA0FAC8D434A27F68EFB760FB39D751BE
+:108130007BC00B3FF187A956B2835A306E8EF55340
+:108140000B03989783763CE1DB1C1D8DDB0DBE7025
+:10815000FF777F9EF721F126AD81FB9998AA0D99B3
+:108160001025E76F4DE3FB9C501C7EE93F50AF5D4F
+:108170006D21BD16652CC5A89AD3A91FD8FF6169CA
+:10818000DC4F417876EF238922BFCE5382705D9118
+:10819000C8F1729385C7CF36811E4D7C51E0AFCCBC
+:1081A000EFF3097D2F5CA54B427D414B937633C89D
+:1081B000F512E1BF87FAE961E524DA7FD3FDFA9091
+:1081C00009FDCC4D376BE1283B06FF30FE788FE090
+:1081D000AB6C3D233BEB1EFC2E09FBB72661BCF5C7
+:1081E0001EFC1EEDC8C537C7C41527A671FA96F345
+:1081F0008BE7FB13E5BC9A1FD7A2C791FDC7F70712
+:1082000076EDA4B4548273A817EEEF523DED5FFCF7
+:108210003CC3EBB91F3EBC3E8FF04EF6D7D33CFFBC
+:10822000AC8FDCA7801C9C3586DBFBD2FE9929EC49
+:1082300071B638D6BE43BF4F67597F7939DE5EC409
+:108240007C81D8F65C6F4918143112DDBA9598F923
+:108250004B78F5048707AE116E52EE3D6E013A0081
+:108260007C598F7995805FEB1F482039E6340606EC
+:10827000205E6DC47C1D92A7DC8EFFFC48AC3F26BF
+:108280007EFF7E9E26FD6AD7667F3F8278D18DFD78
+:108290005D678D6C41F8D75919D1E7857D89448F89
+:1082A000AC6F781AE6D15DDC6B62480FB54AB80056
+:1082B000F9E00545ABA4764B13DC4897D2DFF1C15A
+:1082C000CBDCDF51873B03EBADF3FF17E571D5ED59
+:1082D0008EB5CB2FC07F5540471774E112EC4FF29B
+:1082E00017D0CB35D2B7AA787CAB56C7FC68B7DDC0
+:1082F000A09B3E87F38D4CB68DDE9F2C5810A5F7C2
+:1083000043BB762599A323D261B5D8975ADD296A54
+:10831000578DF958B83F68BFA11F102BA3FCD6B5E5
+:10832000AB3FA67CB0DA9DB1F853DD855FCA370A52
+:108330007E17856FC41FFC82BF30EE8F29E7F1F9ED
+:1083400044514EA8E8A0FCB03AE18F493D101E8B85
+:108350007C2AB138C8A6C3B3EE2CD75F46B56D3DB5
+:108360008876BAA3A22307C9AA4EF84125FEC87988
+:108370005EDFB6568F76A4D47BA2ECD8011363FCE3
+:1083800018CBE83BB48B71BC30BECA40F4E2F27249
+:108390009D9097096860A35C6DEE4F7215E51EF223
+:1083A0003B695723FF43FC2A4A2F3B8EF4FF467A52
+:1083B000D91F399F04BC453B018DB4EB7BC63F09F7
+:1083C0001FD90EEDEB7FEE9F147C9C71BFE48237CA
+:1083D00052FF291D9CEFE4AF57F44BA623BE2F504C
+:1083E000DCE988EF17057F3CBCBF80E2A0F2FD19F5
+:1083F000BD8FFC8FD2FF3507FD7EF0AC16FC689672
+:10840000F097CD927EB2F5B1F15AF4534797E74A0F
+:10841000BFD90E53571E13FAA9CA592811FAAB41F6
+:10842000BF1B3E83B1DFD5B2087D57B7FB1B534C52
+:108430003CB885C3F11E814F8EF2801EF9D8060B21
+:10844000F79F49FE366AF156C2935EC3B4FC87902B
+:108450006EDE3090FFE57F0B3C90707930ADECCF55
+:10846000B8AF56BDF00F3E6422BE7E1AF48556E1C9
+:10847000F7998876F212A6E13901A6DA73A3ED68BE
+:10848000F95CB5D75285F89899AE8BC1D7F634030D
+:1084900095C91F46722381F402607343105F4B7AC3
+:1084A0004BB9CD86A01FEEA4B0EB6BEFB4F9B0BF13
+:1084B000B08EF3C5FEE97C9FFBA7F3BC5959EEB41F
+:1084C00043053ECA382BFAA5A2E314433ADBAF15A5
+:1084D000FA2EA3F5AE9B23F2E83BE942477C2E61DE
+:1084E0009097E4C30DBA32E273918F6C6E844BC5E2
+:1084F000C7D573701D9F4DB1D279C97B859FFCC6CE
+:10850000749E8726FDDBD7EA272F4DEFC4C7183F9F
+:10851000F95EC117F7323E5FFF592BF7F7AACC8FF0
+:108520007C726F704000E75B29FC23A87F21BF8E1F
+:10853000BCC4F791A95C5FDBDB3638807474D2E091
+:10854000DB3013FD4DAD06F21B3235F0ECD3D8CF46
+:10855000AB191ECCB3BAA08B6CF93DB4DB7BF657DC
+:10856000591857DB2BE21BD5C65001E9F522AFB4F1
+:108570003A2954807EAA57C47E555BA10CEF532C38
+:10858000BEBBD253BBE28FF81DBE3F15E076C329B8
+:10859000C6F1C0BF9AC79701BE193371BE2BD3294C
+:1085A0007E89FB82FBF0C1BEC1B4AE7506D17E0FE1
+:1085B000F7732B130BA7919C59654A41F85FF41A86
+:1085C000292FBA6E0DD76B67E8DC5B1621EF7D357E
+:1085D00081D637B3E528C595EA1E994DE74DEBE600
+:1085E0002EBE9DFD93780BCAA968FFFE0516C9250E
+:1085F0007BBDAA773004F3B8D036C0C3C3A5FCFC5A
+:1086000052ADC8BF3D6D601ACE3BB2CF10E8EE5CF4
+:10861000654FFD9383B384CB4B1CA72E3AAE45F236
+:108620002536CE75A5F20543B8E001187F758A6F2F
+:1086300075BAD03B115E75AF66101FFDE0E12F7279
+:1086400049EF69E6F194D3066D1AD289A33C649C84
+:108650001EC55FB70B3A9E6112FA2DF0C168BA973A
+:10866000F52565B174269F4F0A7A4B14791897D770
+:10867000CB3CBF492694C7DCF585FDBAF9393411E6
+:10868000DF1C7536B21FF3D9AA8345143FCD5B1C9E
+:1086900022BA047887D03E39BD2191F3135826F6CB
+:1086A000336B2423FD7A969EE795CC3281BECEF5BE
+:1086B000026A7F66433AC1A16419D753232F29C4A4
+:1086C00017659CB792F1EF77359EF4EBA17DE50E2F
+:1086D000A508582BAB6C2CA5BC93B99BF269FF473E
+:1086E00009FE3BC3A4156C407CDBC5E384301ED976
+:1086F00005D5985B378CF89211E56BD50E85E22590
+:1087000072FDF1715516888D478D0A72FE8D728348
+:1087100045E993520EA1BC60717A6E2C5EF8AF4AA7
+:108720009EC6CB8377D3AF56AF8C95A7EF21FF4A78
+:10873000BD5C9E82DD701CF1B0A48CD371A495C782
+:108740009F6A583D8FC30979D6B92E210FCFE8B95A
+:10875000FC9D655A4BCF8BE93C0E359785451C2A0D
+:1087600062C4F9F5845F17D3657E7B2C7E49BC8A91
+:10877000209E417FD56759E8BB305EF56216AA1985
+:10878000C29F894348BE73396FE6721E9FD6AB9075
+:10879000F7F1723E5EAEC7CB73146728B7253E452E
+:1087A000C723504F1AB538A0E7FEE66C3BE665CA12
+:1087B000FDBDDFA939B253BBF4C0BA6366B37B28F1
+:1087C00096BDACB70DFD68A59B73A0BE4EE5E7C393
+:1087D00013004E5BE1FD666187ACCAE174E612F9F5
+:1087E0005706D5CB8A6CB84F1DE43788A432CAA788
+:1087F00097F0DD9C08DF613E420EC78FCEEFCDAC17
+:10880000D11AF57DD95E0BC9A94B7B12E91C205307
+:108810007D790EE82FED4F603F40F9C2DE44D21360
+:108820002E08B9E194FE19B69CF6A38F8BEFB39F87
+:108830009565A19F9B29E3B2189D8FE7FA6C8DA3E4
+:10884000A7F884A8CFEFB893E39989E4F52547F812
+:108850007E2CC37C28BF3BCBC5F7BD6EE798A29F9B
+:10886000615E86D7E6E150F515A1FE61D22FBCD33B
+:10887000ACC77B1216471E8075D4E4D8286FBC3C69
+:10888000EFFD77A742F9A39D063A5F3AE7A949BDF4
+:1088900042F899AAB9BAA393390143CCB9C5793B37
+:1088A00062CB35C1D8725DDC3D058BDEDFFA667BBD
+:1088B000547DB94B9CEB74330FE6BD33FDDDBD7CBD
+:1088C000DDF05DF9FC6249E0CDF67E9437789B8B54
+:1088D000D3B311F5A3E9880FDD7CA773F17D35993A
+:1088E000EACFE2F903D32B26BACF20DDE59BEC4A91
+:1088F000453B2A7208F7D394777E08CAD3B2BCAF3F
+:10890000286E78E941E641F85CB294929E746983DE
+:10891000C58D76634BAE8DF0A0E55525A070BB628A
+:10892000FC08E0AF55341558EFFA5B3FE2876598D5
+:1089300099DF7F0056950BF9954676DE990956FB2F
+:1089400032F8AE6A3D97DBD5AC2309F9C006B97F92
+:10895000FAE78D66F8677EA3366029CC779ED74A02
+:10896000E7A4D4AF55BA1F600576196597D4BB3814
+:108970003FA831878DA538FE570B2BD00528FD79F0
+:1089800026834FC3F37886DD45A12C78357BD14112
+:10899000B2BF3AE3F6FB38DF9AFDC07E7AAF4CAC4B
+:1089A000A0F59E81F5225C0E6E30D17ACFE4D8C856
+:1089B000FE3DB399DBF9B3EDC68099F4962F53F0E1
+:1089C0001CF399CD06BA3FE07278DC42E7893FDCC0
+:1089D000F43AF91B3F647C5CFF4E3DE93D1FDA230E
+:1089E000252184A3BB3E09F5E6AAF573E83CF2EC29
+:1089F000CD7A2FF2B3D99BEFFBFDF5E8279B785793
+:108A0000312EE926C7C234B7ADAB5EEABB6AF2C805
+:108A1000A7910E6FFA7A4CC74DA8776D063AC9E751
+:108A2000E71D50DF6FDF7C0BE9B7B327581DB82E69
+:108A3000F7A6A7C6A21CFA7042269D9F9EFD82C281
+:108A4000F0CA8CD98E4569F87EB6A27ABBC3A7A1BD
+:108A50002E7EEEB934CFE609E1777FD4139E005D18
+:108A6000DD8972B866B381F4E7F689C7DF9DEAEC69
+:108A7000A22B65E2FADB4761FB670CD4BE536FDAC9
+:108A8000F43D892F2C5482F619875B3C9D99F21690
+:108A900017E0BCE2E96DF6B2FA021EA7BB36BA6374
+:108AA0009B38DDFD9B4BDCFF71F574B7D7957AF5EC
+:108AB00074C7B29363E4F0E5FCCD4FF094710EB34C
+:108AC00087694FD928AEAD29C07F3FC080FE087CA2
+:108AD000F27362EADF16EC780BF1D8E53B82F3C85B
+:108AE000635A11CA4D77C45E8667C06C422F649B7F
+:108AF0004CD29E203B615D2A7B7A55945FE4CFA2E5
+:108B00003FE0037FC47E2EBCF7D521DCA7DADCF37F
+:108B100043D0BF5DF7E55F282E6A6BE371759B2735
+:108B200042F90606A797F050F2F73A0F973FF1EB9C
+:108B30002AC8E0F6619D3342FDE833DD546E1171C1
+:108B4000A48D8BACE437DEE80C58B8DFC3CF503EC1
+:108B50008D1FA9E7F140A1B77D4FF85DCDC507197D
+:108B6000C601D9689E8FF756F1413505CABF1F79F6
+:108B7000B387CE51163FD9D41BD73DDA20EAFBD0BC
+:108B80003D27FFAE9552FD0297DE8DF43DBE98E77E
+:108B9000A3B2AA24F2E7BC55FC81F3DEA8F97B99C5
+:108BA000D96D03BC9908C41A9DFF78FB688BDB164E
+:108BB000853F9F352B155C7F76F79A3C98FB6B4879
+:108BC0001E17C7C26381CB48E3BE915ECA3200CE96
+:108BD00037DDC8F7E3DC0BA600F2C173E25C523C60
+:108BE000FC7A6508FC5107C4E427388DC15C949376
+:108BF0001F2BB1DFCD6DD2537EC09C26850560BC96
+:108C000073CFEECA457EFED153BB72A747CD27FE78
+:108C10003BF9CCC888F57FC6FBB37BF263CB7617F4
+:108C2000D7339FB94F57FB8B557F273FF6F436E17B
+:108C300007D7B4BE4EB4AB44FBF8FECA057E28BBD2
+:108C400015F29F483FEEA9C34F62C4A873FF2C6D75
+:108C5000F9BAE83C52F91C25F66D12EE1B2CC5D270
+:108C6000C4CB3DED574FF47842C821B96FA79AFAAB
+:108C7000F442381A6B6D2AE3E7030B51EFDFCCACFB
+:108C80001EA4A72F443EB1D30A4FD0D38C992E1BDC
+:108C9000F233791FC34FAC49DBF0F985C837765AF8
+:108CA000E109FDE46416527F5FE8BC641FFE44DF07
+:108CB0004CE7466FC9E0704867214541563BEF6578
+:108CC00085F2E49A62E19DD6C0E548A4D248F24B11
+:108CD000C2FD86E9F7931DDCCD7EAD473CCA1CC9B9
+:108CE000DFF933F2851E1DA678896524B3A39FA002
+:108CF000E17A3FCD43EE571D6FCE943685F467CCB5
+:108D0000F34948A6B8B05F3C992D9975C6491284BD
+:108D1000DDCCE2E222E9A077633B394F2853BED095
+:108D20001A47B0B980C795492FC57EF1FDF4412A95
+:108D3000C515B09D71D895F1AF134F453EE878F950
+:108D4000BECADA6D1C663C9ECBC27D00F9887A21D2
+:108D5000F31862CE656D027D1AED3D19E7D6EB8200
+:108D6000452EB24F3AC2E887319698DD286F13F44A
+:108D7000C142DCBFF8B837B4CBE7F916D90E94334B
+:108D8000F2DC55EDA2315E8CC781FEE137E3FE4D8A
+:108D9000E0FB57FB4029BD5726162E45FCAA5BCCAD
+:108DA000E87E88316DAD940F5657C1F5B1BADD2715
+:108DB0008D0CF077BAF00B31E1174F13FB7A4AE8CC
+:108DC000DF5D71BDF016CCB76F99934DE7ACE3F35F
+:108DD00067AE35AE7B31110032342A5ED7CBCCE59D
+:108DE0008CD87F49DF327E9738C89B8F9AB861BD97
+:108DF000E98875C4B5E4C7841F2ECFFE27F931FE7C
+:108E0000FADB313FC68C5ABEA8C769801CED3C47CF
+:108E10006971537CAFB31EEFBF30EF56C47839B7DA
+:108E2000DFAC529EAF289F5A8D7EB1351616335E49
+:108E3000F4FCD4B8FE0DD0BFCD2DDBEBC6637F8F25
+:108E40000D13657FE56ACC075A6388ED8F50509EFD
+:108E5000FB34778DB7393BF8F0EAD15DF21CE4FBC7
+:108E600061941752AEAF383EBE79A81BE9EB73CAC6
+:108E70009B96F2B9CEC9F365E2F9D8DB829F835E97
+:108E80003C1645EE8A29F3E9BE88CE38775BA58685
+:108E9000FAB08C73D72DF652FE34E803FF9141FAF5
+:108EA000C0F933FB19EA9DE7C82EA8FB52E5FE2660
+:108EB000D02BF0FE1F735B29F955319DB75FD4FEAF
+:108EC000CF15720A7578A487BA4D3F784A0FF543DB
+:108ED00033B530F56BE8FEFEAFBF65703DBEAEB09A
+:108EE0006C03F203B65DA1FBB756157E467A47EDDB
+:108EF0009E9B4744E7FFCFD9FD18CF1FDF61E8767F
+:108F0000FD7FCBE07A6AED9E97C86F7A2EC08F2DD9
+:108F100055A98195A8875655E950F362C581CAA91C
+:108F2000A40F4C8175C0BAFE9CC1E153B763921F78
+:108F3000CF23D4C17F0ABCDAE89D4576C1C6296635
+:108F40001BC697EA0AA7CF27FCB75B355C7FFC3CC2
+:108F5000BBE2E9563A37BE6AB7A102F5A812D09B28
+:108F6000FE0DE69B933CAEC2037C294BDF5AF463B3
+:108F70001BE617742F97B764713DA051F1FAEF28E3
+:108F8000267F298BCE57CADBCDF5337BA631C63F72
+:108F90006FCFE4F74C8DF6778C419C7B550D27A065
+:108FA0009E5CC7B44FD1FE655E9B9BFCC48CE713EF
+:108FB0003897B8C94F6C76867F3E94F42895E2E9DD
+:108FC000D2BEB8B087FBD79665FA7232D13FA80FF0
+:108FD0003F7A07C2EDE7AAF037733E933BC9360CE0
+:108FE000FD611667F8D10A37E519915FA2D7771BA3
+:108FF000691F5E75323BC2678CBF5255A2E48CE498
+:109000001B633ACF4D39C90F5BC6D91AEB07BB7545
+:10901000C64C28DAF84D4A979E70F8ABC92ABE9420
+:10902000FA83CEEC233BA77C0AD88D8897CB238785
+:1090300074E8F7777690FE581354689C9AC2DF5014
+:109040001EE03C916FD699F7A586290FEE3B990952
+:10905000C28FD9C8F19275905DCC9EE7F007FE44AF
+:10906000F9715D7AFC526A27FB338A78458DF0E30B
+:1090700000A0A8BE2C53FAE19689A7CCE7E3E3321F
+:10908000D55D12ED775837012409CDCB9D84F37D52
+:10909000C4EABD2D13E6750AF017D779AA2981EE27
+:1090A000035BA77468E8D7F417F1BCE1783CF28958
+:1090B000717B1D888C457912D9D353DE30CF13DEF6
+:1090C00030E23ACADB2FDEFDE958C40F56C1881ED4
+:1090D0006B775F5DDEF04CB11FFFCFE40D7B146D4D
+:1090E0001B3CEFCF7470FD4AE60D7BF87EC9786BB0
+:1090F0007CBEF0858C90CAF3FAC25B9E42BB7DB702
+:1091000089F261C6EF7EFD18FA35C79B5990E2CF10
+:1091100071FA43C4396909D2C9C54FCE6C798861E7
+:10912000BEF9CB1E7E1E36561FE8C91EA098499474
+:10913000DDB83653E8E7DF923D20F9759DB0AF3ECC
+:1091400056228F14E0FAF6E9EDDD9D5FDA22C7EFD3
+:1091500029DFA5ADFB7C17E98FAE08E7C7C4BF7652
+:1091600074F6776DF1B4E7507676134F5345FE9A57
+:10917000AA70D6C11C3CBF49C6D3D4D6011427332C
+:1091800075C5D342AC9B789A2AE2532B0C5A25F929
+:1091900069F699DCDC8EF612FF6A6C4DF5207FAB28
+:1091A0009B7BEE453C7AA13AC6BAF09C5FA3807FD8
+:1091B000F5D5C7D3DA33BB89A76D157ADB0785BA36
+:1091C0009011E0BA9571FEEB6F9371351DD9B59191
+:1091D000877368DECA4433CDFB83574DDBD03F3500
+:1091E00043C6CB5EE5FEB519222EF6C1C402F23F9E
+:1091F000F504E7194DB1718777059C2F594AC94F7E
+:109200007FFF2F26907F7E16FAF7FBA07FAB59F8E1
+:10921000EBB99FCFDDC4EF3170EF50E81E59441316
+:109220001DE9A476BA4F761EB0D18DC87AFD80357F
+:10923000DF81D78A4E417DC8DD086550FAD595AAF1
+:10924000DF05EDB61E4B20BFE20AA75BE4E7F1F8AD
+:10925000B57FB512E8C7FBA5FBE3FC8D3A0DFBB962
+:1092600094C9E57C5296B1DBFB281A0D224E22C62A
+:109270005BCA60DFE1A953F87385B89F301E1EB248
+:10928000BF4643BD19FD7B911C7E0FCD25A33685BE
+:10929000FCCEC90574DF5463627D5305AF279ABDC8
+:1092A000648978A9FEBB2A5748993B99F2A83345AF
+:1092B0005E621C9C6736C796E3E347F1E7E36630DE
+:1092C0005FFF8C3E979F1F3B8FFC16FABFB42A5F4F
+:1092D000EC8B87E2288D06F71FF2290ECBEF935A0D
+:1092E0009ACDE1A6CBE1CFDE8E72BA1710E885EBFE
+:1092F000718CCFBFF7779D0AD24BA383E3ED7F77C5
+:10930000DEF1F34DCB2AE07A8D83D36BE34A25C09F
+:10931000E1C5E77DB57E92E2AC6FD74FF281E2798D
+:109320003A944FDF117FF03F6C20BADB6BE1E75ED0
+:1093300025BFA28423B43F85BD7B232AD318573D84
+:10934000BB9CEE85DA58D53B09E3AE6326D9681D90
+:10935000B5AFF273D5358BC3B988D7B565E182FA5D
+:109360006EE08A03A892BF42BBE94EC6EF176A8A35
+:109370008D23C6C78757A768E3B346A0BDF441EB6A
+:10938000EBB8DFAD1692AFB58B234FA3FFC097E2CA
+:109390009B9405F871FE81E36315377D46FAFCC5A1
+:1093A0007DFDE93CE8F4C6D873716C756C7C923530
+:1093B0002593DF9DB5C4BEC7735B31DF5D16AFE497
+:1093C000FACD3AA36F00EA9F37DDC8F3313E99A387
+:1093D00063B8AF9F58F8FEFB1F4E14FCDA53102DF4
+:1093E0000FEA7BDC5F683708F302789EAC6C5F8322
+:1093F000FB0BFB5A2DF6F79397BE5380FB7BBEF514
+:109400003B05B8BFEB0CCD1AD24751BA6F21C2E36E
+:10941000F4CD5ED20F655EF0D5E25DC3B78C77D731
+:109420002A8F9BB3FE35798C7FD17E9357BFD2FBB9
+:109430002D245FF879E22EFFDD39BA57EDE2973A35
+:1094400005F9714FFDE50B3DCF65667ED4C34ACA71
+:10945000C2F45DC9DF750CF541A907C7CFFF4931DB
+:10946000FF9D599A09E5A0F4F75689BECD81CFB981
+:10947000BEBD5D217FAED9ED4F1A45F6D5CCE17A60
+:10948000E22FFF46E742589B62473B65CEF6A55464
+:109490007F61F70CAAD7994321B4C76AA01ECB2BD2
+:1094A00046C7E6791B77F27890B47F611E7AD4D7ED
+:1094B000129C1123E2672DEAD730C55A95FBBD6B8C
+:1094C0009DCCE367A80FC7DA8B32AEBBD1CBEFEDF3
+:1094D000D9D8A6D0FD5D69465F7E36EE6B5C7C77A1
+:1094E0007F96760EF14EC6E71F4CD30E22DD3A8DE5
+:1094F0002C97F2F90CF25C5AECB9CF9EF2E48E761E
+:10950000E2C195F4A8A9A42FFD9579495F7A072FA8
+:10951000CD243DEA4ED2AFE4FBCBF3E40231F1FCC3
+:1095200059E29CEE2C714E17F97E288EEF4797ABCF
+:10953000A3F2E442DDE53B44E5C9457F179D2717CB
+:109540008AE18F9C9FA4EB17501CBD0EE866D1B03A
+:109550002EBCAE66E26F7DE4033A37B4C3447EBAF4
+:109560006A91C75B57758AEC9F3A3C87C4E95BE315
+:10957000E7E9B97E550D7625E5330763F37D95EC74
+:109580006F57FF96ED7AF2C7DBB2A59DC8E95BAED7
+:109590004BAEA3BA4DE1F41837CF787B3ADEAF2E4D
+:1095A000EDE1ABE573EE6F79DDD7CAE706C7C1E140
+:1095B0005FE57397C527FA46923CDF427CE223774A
+:1095C000731ABA28659E74D33E9E273D566FD37892
+:1095D0003C54CFF325E2E3C2EEB114F7947168F383
+:1095E000CBFAC0B27C6AEFC17CB49A7D8994BF503B
+:1095F000E5AE223D3E3E1E3A97B58EC5ADF82B3BFB
+:1096000042E7DEFEBB7908DFCF4E74129F72B3FCD7
+:109610006BCC43B83BFB1AE2A1076D9FA7F8A2F001
+:10962000A56C101804837ACE379B2BF63F41E4AB30
+:1096300098553F73447DDFD3770BB2B93FF1A0C893
+:10964000935A939840F737B88CFC9C874BC7F3B973
+:1096500086667A17E2FCCD6EBE9F4FECF901C373AC
+:109660007B4F1882749F82BFC6E641B928FD58B26D
+:10967000FF76E15FBD5A3A5AF93FCC3F1E957473AD
+:10968000B5F1BCF5008328FA8AA7879EBEEB89BF97
+:109690006CCFF63EC1F1421B427190ABE44B09C561
+:1096A000C0B751EEEF34B9D11E41BF0CC9DBD5199B
+:1096B000D29EE7F742ACC921B9F88985DB27F2DCF5
+:1096C000945CFF2EB9FE6F496FB4A47BF764437FAF
+:1096D000A74B353A27B12291CB97C8B33C1F29FE3F
+:1096E000FC50BC5C91E75FE478BFFBBFCC578F7D3B
+:1096F0004B7C15E42CE91D3DC67D2FFBDECFEFC171
+:1097000029EBD044FE0D9DFB90F3AAEBE0797C673A
+:10971000C5FCE4FB90D07306E7681F215E9D7FCFF8
+:109720006CC6B86A7131E79FB55E1BC5256A833C7C
+:109730005FA77631233F823C273CDBE5FB1CF76FBC
+:10974000C5711BDD5F5BBB7B6B536FCA67F091BE5E
+:1097500078E13DFE3EDDE5FB02DBD52D0EC7C43FC3
+:109760004ABEF97C794531CD97FC004E53ECF9ABFC
+:109770008C1CCE6FE4332D47C217EC1DF8EE7C1520
+:10978000CF3FAF736AF652CA63E0FEF5047707F97C
+:10979000956A77929060940C8BF53FCB26BCA9DD3F
+:1097A000595A44F736042D45740FD19FF8BD5DE733
+:1097B0001FC80CE8B93F3E2967049E3B09DC8A7A42
+:1097C0006B1E8C832AEEF9D65B8BC8DF1847779225
+:1097D000DE3ACFDDFED01C6850BAE8719D81CB49DE
+:1097E00029DFFE91EDE6F110A7C8476C9BC066DA51
+:1097F000BACA36676C9EE6CEAC9BFF81FBF38F6CDA
+:1098000055C4D179DC3EDF0CD66CEFCBF1305FC4B0
+:10981000ED27887C0BE63777E559F4BE72DC5ECE27
+:10982000AF93EF8BB87DC297E27722EC46C28BC430
+:1098300026CE3718E005EAEDA3231D63F0BC5BDFFD
+:1098400096D06884572F043F9EA361E19F0FC5788F
+:10985000488A3A1AE3215B160D3B80715A7565C739
+:1098600077716BDCCDF632345967BBBC37E4107FBF
+:10987000A92F44FC2FFBA381E747AE4C2079DF9250
+:109880005B4DF991178E9B62CE23C53FFD6C990B02
+:10989000FD50BD9BDEA67844E24EA5DBBCD79FE61B
+:1098A000D844FEE43217FAB5129B3AFC23D14FF3A9
+:1098B000B0C2EF0085D92B2EF427A83AD43B66EC32
+:1098C000E6E7E567343BCACCC44F151ECF19ED243B
+:1098D0003EA9AEBC4D87769FBA94D17D7BF373B819
+:1098E0005FBC5F8B5D87FBFEDBAFF5DDC6E97C39D6
+:1098F0003A19573422B86A4C914398DA29E38B32EB
+:10990000CFAEA77BECA53C8AD7672FD363853CEA13
+:10991000D4E7E3F0B8A7EF247E4B7CFEAD81911E27
+:10992000F65BC54CE7DE245E37CAF3075F733F7111
+:109930009EC8DF39B5EABF86F07B02647C26C0EFA3
+:10994000713584976711BCC237FA71DD3B1DBADAF5
+:1099500041E45FABA57E56F27BF2F29AFA2C1B59DA
+:109960008C4F3B53600AA7F6CECB43BAF4031EF4E8
+:10997000EB060F6ECAE17952EACA04DA37752DDDBB
+:1099800010CE54471AED9BFA18DF9FEB73383C65F5
+:109990007C58FA4107E7F8D6603E70E739B545567E
+:1099A0007E4E4D9CAB4E5C74FC053CFFB545F8A368
+:1099B0000FBC3A907EDFE3D24A55413DF592A39227
+:1099C0007ECF6AA3D8D744B583D96DD1F87980F218
+:1099D000747BEFE3F986AA3837AEAE746E4578969D
+:1099E0003B7D948FFCDDC610FD04C6ABF6D314F7A7
+:1099F00003BD88CE079FDBA348BD28461E4ABB2D6A
+:109A0000DE1E7B51F2CDFF213D694F279FBE463BB5
+:109A10008BC5DA9B9DEDA5FD186F4FC47DDF93FECE
+:109A2000C3347F4CDECD11B1EF52BE670ADE28F39E
+:109A3000713ACF89B38005CF714C41A21CD1959763
+:109A4000C444BED27AC5EA417DA9A7BCA4CEBC213C
+:109A5000563F94FB37EBBF834F99D724F3962C984E
+:109A6000BF927279FE8A05F35752F07750F87973F6
+:109A7000997FD26070533E8BFF4146714965620504
+:109A8000F9FF92BD46C2BF8B2CB0017F07C03FD902
+:109A900046E7EAF19C13E27D447151BF632A34D951
+:109AA0005E87ED3BEF93AC64549FDC57CB403DCCDD
+:109AB00002F578CF75E739F399FCDEFDF8FC1599CE
+:109AC0004725E3CA99FD5F56D0CF8A6104CA67F87B
+:109AD000B1F82E9FF7D3F22337F18DB4069E2715E8
+:109AE000B99ED9D1CF5F26F98F39765FD729BE7C51
+:109AF000A4CF75567ECFC266E669D243B93DA7377B
+:109B0000EDE346E6DEAF2386DD4CBFDBF1BC53D38D
+:109B1000E7A676E1939C175BCFD77D11CFAD295D8A
+:109B2000E35D9CF3F75CD4AFCADA4C1C2FE3C6DFCD
+:109B3000D879CF4DC082F2C495CBF1C113A7EFCA3B
+:109B4000A72B5789C9FB93E3F7B43E899F57D2E30C
+:109B500025FEF5846FFE32B14F271248FF90F8764C
+:109B600060C90EBA4FB27D49909E172D4A508FE7BB
+:109B7000872D9169C81973F2B2EEC07B502E26462C
+:109B800072F11E95016EB717EF51B9981A3981E538
+:109B9000EB9FF8BE97EAFB45B6E0BD2A77E41DBB14
+:109BA00083EA713F33192BDA72E40EBF0DCFA9841B
+:109BB0009777A0DC2A8ECB8B89BBFF2141FC0E540A
+:109BC000BACD48FA64BA8813B272A1D763440BCAFB
+:109BD0000D19451417B431F7CE0EACCF36F17B22F8
+:109BE00018E03FD6F7CBE7F9158CAF9B650B7F37B5
+:109BF0000BFBE9771DF31DF47D271FDF6912F12EA2
+:109C00003EFED197785C52E6093366CF417DC8E6C7
+:109C1000663165797F0A53ED39785F4283F4278A8C
+:109C2000F22B09BE49B95172F9E8CD3F1944BF2F53
+:109C3000F3F2CFFA22DFBCC5187B3FB77C26BB39D5
+:109C40009FBC28EEA1BC2FC17777EE08FC7D9969F7
+:109C500063F14AE12929A54607E96FCFEA914FA5AB
+:109C60000AFC704CE6F373947B15FC5D17790F6466
+:109C7000AA4F253F01F3B5E851AEA69EF652FE610C
+:109C8000B539928BBFBFF396D95785F3BC5479F29F
+:109C90007E8A3F661E3D81F922470DCD6392508E2C
+:109CA000E48B7B3830C00BE5435979640F76F2873B
+:109CB0007E0AC547C74FE6E771C7B1A08AFB3CD60D
+:109CC000CECF878D2DCEF734C078E345BEC9D8639B
+:109CD000DE24E46F637F1056F93D2111353ABF430E
+:109CE0003E99CBE08EA6875BDD516586F755C7961A
+:109CF000BFE7892DDF31F2EBFED1E5C18AD680EBDB
+:109D00007C4511F76D007FE1EBE2798CBF12F6DC48
+:109D1000401733E7619EA553F1A3BD30705726C5A8
+:109D20006D768D64544EDB61DE668E5EFF5A1D8F4C
+:109D30006B0BBFBAFC7D2AAC4379FBF27B6904AFA5
+:109D4000341BF05B27711FC2B703826E0F083A2DD8
+:109D5000C9325B91FF1F30B837119E279ADDE8A703
+:109D6000DA9F68A4FB7F1BE6F3DFB75092CCCC08E8
+:109D7000FDEAA7F332B4633742BDBEC44CF92907EC
+:109D800044DE77C3832AF9B9B01EEF41D43F622580
+:109D90007F797952E1DD58AF4F32D2B98BFD8925F9
+:109DA0003E311EFD2EC1F64473087F2723FE1ED6CA
+:109DB000A3382F841BCCEB293E0FA2477D8991F459
+:109DC00070793E1FFAA1789E3ED34CE31D70D8F700
+:109DD00023DE357C449A1ED48F74633E99C4EFF21F
+:109DE000A491F4BB33407D7DA3EFD9D7A779DCFCE8
+:109DF0001C30FF3D95C2CEDF578161A11DBAD51938
+:109E0000D12D8F0FE648B83355C3F6194C96F9F9A2
+:109E1000B5B4CE72A94AF72D29B2BC94CA8F8B7AF9
+:109E2000796F6C6A1EE7534ADBEB7F43BCED9B0402
+:109E300070817DF224747F7EEAB4E0EF97EF5F8952
+:109E40000BFDFE0AAE7350D7FA0F383C2E6F54B993
+:109E50009B7D0920BEC5EFCB018BC78D7EB62BF74E
+:109E6000C7E12AD7A1CFE4F0EC5C474AF7EB48CD35
+:109E7000E3EB088A73E3F1F54A9EEEDB5E67B7F821
+:109E8000F72FAF332D769DDFE23CC3CAB7304F7D4D
+:109E90002ECCCFD6353FFAF9B812E49B1CFFC68909
+:109EA0007C6956189BE7C4467ACC5C5F8CCD6BBA54
+:109EB00045D9D488F2F57111377F5DD0D5A184FFE3
+:109EC000D517F5ADD7A715B413BFEDB5B411894BB0
+:109ED000F267C9FF2F659C2CC132C88101792067C8
+:109EE000EEEF7D741A76DEEE78BC2FCA2BE09BD79E
+:109EF000E58DB87C9E927E3BE70BF48B7424E937AA
+:109F00007EFE928ED8ED414A10DDCC42F474319E33
+:109F10008F0F7A09DD73CFDC395DEB03221F6BAE47
+:109F2000E7EB58EAA779DFE27894F2106FC9F7DD22
+:109F30009407FB3D65E8A774FF147355F6273B4D66
+:109F4000D1B4FF9BF3C58C7F7C2FF5FC78BDFE4A16
+:109F500079E9729EF1FC50CE4799B883F4F83AD073
+:109F6000E379DEBA42FCBEAE4AC7F9F06E85F4FA78
+:109F70005A903328A7E4BDCC3715581BF19ECDBDB0
+:109F800006EE4FF5BF6472C7DE4B159FBF2EEC89FE
+:109F9000C54CDA0BFC7E8B1A3BBF774AC89996FBFF
+:109FA0007ACB7BA9B83C043915732F55A53BF65ED7
+:109FB000AA1EEC05B00B483F63BD74C22EE072BA16
+:109FC000E57AB7DDCFC8FFCC7F2774AA51E88300BC
+:109FD0008BB4AE7BF3C00EA0FB001BF3F2C5BD64D7
+:109FE00001FEBB2C42FF8FF74717A5FB56209ECCE6
+:109FF0001CA4E5E24F04CD30727F33E0DBA60E8671
+:10A000006998F5DBF15ED95B59FD3BBA3E846F0F71
+:10A0100013BE0DFC94DF37DB856F8FE4A572B98426
+:10A0200042E64A741C71FA1EC7715B1CC13FE13DD8
+:10A03000F81BDB4C046F99E71A4FDF51F3396DE0E1
+:10A04000F371EAF5349F27BA9BCFD5E07D345EA546
+:10A05000338EDF3DE13F9E27491CD685FF8315DF08
+:10A060008B386E271D2CE776D765F3D6DB68BFEFFC
+:10A070009CCAE3727509D24ED6C667A4A11F928FFF
+:10A080007FE74A8E177756F2BCA4096D35148763B3
+:10A09000E53CAEE681FFD1EFFC08FE36D9596440BD
+:10A0A000D4FB2BBBDB807ECEC9E363E36F53CCB71D
+:10A0B00050BCEFCEC98698DF39957098227E477DD7
+:10A0C0004ADCEF9BC6C3253E6ED7C90FC47AB3F0F6
+:10A0D000777FE099CDF8399E0CF17B7447F33AE332
+:10A0E0007BFDAF31BE772CEF1AE27BED8608DD3BBE
+:10A0F000F15AEAEC4DF3816EFAFF7210DDDB7F73EB
+:10A10000DA9CED6BA1FCCCC6EBA8FC5ADA0F171E4B
+:10A11000C5FA2D05542ED77D3A0DE9A0B064EA3872
+:10A12000FC9D83760BEFC765F5B5E0EFDFB886F4ED
+:10A130001E86F9C8E5C608B5BB6D68CD70CCAF2AE0
+:10A14000B7F2F291A2FF1846E5DEA23CEC95EBB027
+:10A15000DCAE7C3AADBBF8E0C0422584BF73579EAD
+:10A16000CCDB8F1FF66C26FA8BCACB7879A0A7744C
+:10A17000651FACD77D36AD3B7DC428EC21A95F7B44
+:10A1800005BDEFD24E36E2B944AF4DF1E0F913EF21
+:10A19000C893FC3E3A33CF53F93F722300BD008091
+:10A1A000000000001F8B080000000000000BE57D90
+:10A1B00009789445D270BFF3CE9564924C0E20215D
+:10A1C000102609840492300987288703048C0A38F2
+:10A1D0005C028AF08633E42011748DBBEC6620802B
+:10A1E000E8A28615151574404070118302A206BEC0
+:10A1F000E1505151E3B1AEE82E7FA2ACDC1283AE48
+:10A20000B8EBAE7F55757766DE37C902FBFDDFF32D
+:10A21000ECF7FCF8EC76FAEDABBAAABAAABABABA7D
+:10A22000C7EBC935CFCA626CB847F1F8211DE158B8
+:10A230009268EFC7D858CDDA4F5518733A5296390D
+:10A24000E3198B1E38AC3F7341B99D59582A6337C7
+:10A25000A468E1AE0E8C4DB9E6DBE4289531E62822
+:10A26000ECE98D849405181BC0D838FC13EA8FB331
+:10A270003B026A0EFC9D6F39D790C1E8DFCFD03E1C
+:10A280005BF1385DFD31D725E6EBDE8C61173F5F72
+:10A290004FFD76C0EF53067D9B6CC68F09BCDF0B6C
+:10A2A00016C74A253AD8FF4DA27FE661DDE33B326F
+:10A2B000A688FC4D72BC0CFD78F84F817A9D98F809
+:10A2C000BBEEAD1F15ACB7A25661690005F351BADC
+:10A2D0009ED528084CB6A2A5E3FCACA67A177EEF63
+:10A2E000A6B87B39119E816EBB37BB35DC12BEAE82
+:10A2F00026F890D71A2EFC67867C1293FF14A7B31A
+:10A30000238ECBCBA19D87C506E182F107107E5637
+:10A310007078D62B1594624306ED1688760BE47C94
+:10A32000F7EAE73B209CF9C2008E04E65EA962BB17
+:10A33000F8DC5EFF0AEEF2F0A81CD687B18976EF52
+:10A34000833698C3A4985944E7C9CCB73B06E6FFC7
+:10A3500062845680F0A826DFBE0698D41CE6B1229F
+:10A360005E808E37723A72BA48B88CF86881D388AA
+:10A370001703DC463C04E9539F886922ABA07CCBE1
+:10A38000BC0CF3A9461E047E6DCAB5F937E22066FF
+:10A39000F81FF0F3D1C274FF034A10AEA30ACB300A
+:10A3A000433D9F12EEDE9CC2D80F61307FF81E2F16
+:10A3B000F03068E62FC6B2A8D6F056DA79BD7BC277
+:10A3C000A336627A7D7AF8325334B64FF663FDF8DD
+:10A3D00070487382F0FF60629A1DE0BD47AD25FAB8
+:10A3E00075614D4BCC29413E7BD80593EE8F7C297E
+:10A3F000E7E353904E569332C3EB8039E1BFEB83D2
+:10A40000E9C32E4068078E2F3BC0354370D38C06BE
+:10A41000A55141785D290E5C2F33EC6AC096D39A22
+:10A420005F704676A0D3CCCBF00FAB799C61BBE1DB
+:10A43000765E6F26F68FF5168FF484D69B89E3E05F
+:10A44000B82BE1BB3DF85D01BC27C5B6A60FCC8F8C
+:10A45000E01F5339C27B220EF06515F4BA3792E83B
+:10A4600035E6DE61F45D199FA134C0FC4714B828BD
+:10A470008DEDF7A1996513DDA6D46605E9A876D41C
+:10A480009EC275CACC0DFDC7C1BCDFEBFF5CAE063A
+:10A49000E5C74DAC08EB19F1F75C107F57B48EDAC5
+:10A4A00083FFF508EF36E4FBF34AFD002CCCEFEC1C
+:10A4B000243A32A6A520FD629C29C36210DF3FC169
+:10A4C000B880EF8958047CB0A7A3B613E19DCCBC3B
+:10A4D00023CD30DFD802CDA239683813C2B3D0C93A
+:10A4E000E119A93A886F9BB72B7E1BD4CBF7643E4A
+:10A4F0003E18F2E5472CCC0FE5CD8CF375F33AD539
+:10A50000EF037E9AF7F6CB036005B2AF041FF75C4A
+:10A510006B622E490FF85FA63F9CB93282F9DE5B71
+:10A520006375F9ECDACEBAFA7DF6A6EACA7303BD12
+:10A5300074E57D8FE4E9F2FDEBAFD3D5BFE6B3E17F
+:10A54000BAFCB50D37E9EA0F3A355E971FD2749B16
+:10A55000AE7E7518ACAF3E886E4F7D06E065B6A046
+:10A56000D3F59766EADA9D8D1A7504D7DDEC55F3BD
+:10A5700046E3BA1BC64A74FDB01ACB97C89715F0CC
+:10A580001FD2732EF34607005F2359D39B4980BF28
+:10A59000057EC58D789BB796D793EDE6EFBD7378B2
+:10A5A0000CA67EFDF712660EE6A19FCA3F6D78E706
+:10A5B000704879BEB3D084FC77DE1519FF7504228C
+:10A5C000825DF3B3DA267DDD01A4DF27AADB069FD7
+:10A5D00016BEADD23A58F882E267D06F3AEB118DD1
+:10A5E000F9F2232AF303FD4FB28AC70643FA4395D3
+:10A5F000FF9DC33D82F8B125E8E91CE6D2D339229C
+:10A60000434FE748B79ECED103F5748EF1E8E91CBD
+:10A6100057A0A77307AF9ECE9DA6E8E99CA8E9E9DD
+:10A620009C54A4A773D70A3D9DBB55EAE999E22B38
+:10A63000D6D3CF407F299FD3562ED4D56BE1036F5D
+:10A64000D1684C7BD4FC52D76F895A6A65A6203FEB
+:10A65000F8E03FE4879E8CB90380E705408780AB34
+:10A66000351F14D5AD5E91F46FF041760AD0BF77F7
+:10A6700008FDD569D15A1BF25CA692AEA04FFBA68D
+:10A68000F4273B6800A6537A821D04728379DBB6F7
+:10A6900083A4FC0AB53BCC0382FAAA3DB9D64ACFC3
+:10A6A0008E95FAA91D3DEBEA1A94838090638CDBAA
+:10A6B000018CAD32211C53055F1F0CE77C79118B97
+:10A6C000AE857A506720C0750CE186718E85F73EA5
+:10A6D0008CEBF436566BC1FEA7B17A4AA7B3264A73
+:10A6E00035E624BB622673533A9B79297DCFAE4D64
+:10A6F0004901B9596A6F188076C95F0B3F3CAE209B
+:10A700003047E310D876F12AE5F5C7F827D47B3037
+:10A71000C5AB215EF3EDAEBB1E854F07514FA0FCCC
+:10A720001D1D47F032B3377B7C765BFD2C25F9FE8F
+:10A73000BAA26928777D8976F766985BEF24664F21
+:10A74000443D97E04F1D0FF4294FD1EB975E8227D0
+:10A750005EE85CBB10ED28C6FCB1A81FAE76DC5FDE
+:10A76000A5787E8170CBFA979BAFD55A7B27C2D94B
+:10A7700054E6706F04FEFC44D0E3D95B6D01352ACA
+:10A78000C8479F454C7FB303D0EDEE086D19F1DB50
+:10A79000E41B57605E3918E75A08F05D28047C73A3
+:10A7A000FCAFC4F252BBD6AD234CF17C57AD67343D
+:10A7B000E2DFCBF10F7F647BDB849FC33342E1E3B5
+:10A7C000BF1EA1ADC67E0E9AEA93DD880F73FD0011
+:10A7D000B24B1D1DA89FF3568E97F6F0303CA2EBAE
+:10A7E000349CD76C9BCD8DFB93E10AA7EB89B819FC
+:10A7F000D3CBE1CF39266FC780AA83FB1982DB59FF
+:10A80000D82D11F8E6BC45C06DEF20F0EECAC27538
+:10A81000D51EDCD5D83FDA89BF56FC6827D23FC8A1
+:10A82000BFE28BF13F00799BE9E22713D07EC93666
+:10A83000B93742D1BA70E81AF8FD0381EFF516C8AE
+:10A84000C7D2F795F83D219CB74F78CCE4AF86F698
+:10A85000DEE1AF129D9E5DE0A0F91432971517D985
+:10A860002C615FFF65D8DFF735003DF6A5687B7189
+:10A870001E33E24CC99F101C5A6FB477D8E02BE30B
+:10A880007FB94EC73BF914E608BC4D601E5A77935A
+:10A890009866C1713FFAC6EA41F9F991902760FFC5
+:10A8A000D3F7A9CC4FE9ED2C40F5EF600D94FF30C4
+:10A8B00022A76B25C037EEF19E3D50BE86E0FD7DA0
+:10A8C000BE5EB519F19C5F4E7642BCAFE97045FCA7
+:10A8D0003B4EF00BACD74FB11F58AFFD725343D670
+:10A8E0004D3EE7176676F6F857EBA6BE99EB0B10D0
+:10A8F0008C8E4498FF0D828437784A484FA09D156E
+:10A900000FF8AF77A96467150C6B3423FC5BBEE5C9
+:10A9100072ECAD252CD207E56F0D5319D26BECDA32
+:10A9200051A7B1DD511688EF07F5475ED20E47C338
+:10A93000FCC7827C0789CC0ABA809E08D14B372598
+:10A94000ACCE473BE2A6EEFAEF37B31A15F1373A31
+:10A950004BAF57C6A25E91F560BC038887D8D6FA84
+:10A96000E547A95F7AB15E57A35F169A3C2C95EC38
+:10A97000549715F97EA69979DA5A6F937B2AC29E6D
+:10A98000E576CB2D62ECE6D117AD1760BE0353B56B
+:10A9900008EC67E198BF4C47790CFBACF7FAA21EB4
+:10A9A0007D5F650F40F99755807150AE27AAECCCBA
+:10A9B0000306CED7554ECA9FAA4AA0F44C958BD217
+:10A9C00073551954FE4D959BF25353BDF1D8EFCCFE
+:10A9D00095DF9AD18EBA2F4CD28FC3B148F0EF7D5C
+:10A9E000617C9FB52872D1678530EE225280A0AF7E
+:10A9F0006B6B46A1D955BCB7F64D4CE1BBEAC0F232
+:10AA0000D58A1BF5D39CC3DA0A649F79471BC6A27B
+:10AA1000D8E9FF87131D116F659714A6C1523AD06C
+:10AA2000C39386E39FAC1A48709DAEF2105C9EBA49
+:10AA3000C637E3A0FDD9AA02CA2F4CF566A6764018
+:10AA400075FBAD15DB8FD9DE684E82F2911EC58392
+:10AA5000EB7BA887F9FD40BFB516AE2FD682BE406E
+:10AA6000FE19963D7EFD5D0CE5B9D617C799143BDE
+:10AA70006B641CF2D5C04233D69BFC13D85C2941D1
+:10AA8000FEBEDC3A39BF5F21FC9CDF1F43F89078A3
+:10AA90002A13F43ABFA7F72D83A0DFFD6047AA0071
+:10AAA0005FF32513C1D7FC59B81F8D0463FB85BB29
+:10AAB000D33A3107CE131ADB30DFBB13033A9C7D48
+:10AAC000E19E04A44786623655825C381B5BFBD747
+:10AAD000CF51EEFD99CB3DC66ABF7E12E562970469
+:10AAE000F70390FBC602FB34DAD75444A05E5C60E7
+:10AAF000651ACF6BBD317F369CD1FE76C08EA4E146
+:10AB0000B89E703C57CFA05C4BDFF178EAAF5CC1D8
+:10AB1000F96E79E189E6D75C58EE27BEDCB6637D35
+:10AB2000E7A72057BA737938C2F53ADA19B04E5E02
+:10AB30005F1D41F2EB758BFB7825CAEDF50EF766CC
+:10AB4000A8F7DC43F77EB917D307CBF2EE45FE48F2
+:10AB50008DA57E66FF6E7E2F6C0F7A9C25C2BC7E13
+:10AB6000FF8A120843FFCB9A034B1361BC3EEB1ADA
+:10AB70004D9D21CDDDA45463DABB6BC111D49F156B
+:10AB8000A92E6ADF777B8A8AF661AFCEFECFAF2728
+:10AB9000FDAED7FB596BBE1DDE9905F57F2FA5F6DF
+:10ABA000CC12A0EF7D5D3FCDE3FBBE1AEA6777DDF7
+:10ABB000848F6F67380FB02C10EE422BF92570BAD6
+:10ABC00016C89FDF95B601FD177B4CBE0DA48F669E
+:10ABD00072FBE3BCD7F704F24D19D4F741BE2CD772
+:10ABE00017751D9497FDB9BB1B3884757DFA8602D5
+:10ABF000C4C7825D8F8EEA0CF5CE0F666E05402FBE
+:10AC0000DA7D7114B6635DC156C67E765577BC0D8C
+:10AC1000DAFD366B787FE413AF5A4BE3B0723ECE69
+:10AC2000E3428FB1861CF20B904A817ABF85CFF840
+:10AC30003DB62EE600F76D71FA94D72D4941FF4AD3
+:10AC40003FCDEE56711DA4F8122B1C41BD08FAEC45
+:10AC500077B87E12ADA25FE78464EF55E833ABD0DE
+:10AC60004FB2BFC7ADCC1716CBED6005F5AD95EB78
+:10AC7000E1CD202F905FA51E867137A6F2F664FF06
+:10AC80002681D2CD0538931EB7F949D75FE1F84642
+:10AC9000BF99B443A6C455EF6B40FF4E84B603C7BB
+:10ACA000917E326676BBD0CE5916E1793195ECA80B
+:10ACB000A6649C03E8C997B1DE0215ECAAB410BBE8
+:10ACC000CA7E657AF2C508CFABD8FE4AEB1BE5E831
+:10ACD000A2EF4D2C17F860D1A336DA77560BFF415F
+:10ACE000B5F06755470EB0E3FA67874DA56F82FE52
+:10ACF0001CC27B68E97751641EC9876AC6DAC4DB67
+:10AD00007E58D71AC89100E8010DD6F7D04B4D2ACE
+:10AD1000E7FBFA43D1FD507E324FA40BF7F526A690
+:10AD200085E847633F40B76338CF612C8269217A59
+:10AD3000D0C362ACB87E9923F6DF9AFF60413F39F9
+:10AD40008FC1C27F37B8F9B30894838BBECF237904
+:10AD5000D8DEFCF689F9FD17CE0F526F4FEF39841C
+:10AD600073C8774E33CE7388795C32DA2D007F3327
+:10AD70007E1FFA9D490FFF4FE1BAFC95CEE36E8529
+:10AD8000F94CB83EBFB5FA717DD6017FE37AAE9B30
+:10AD90009FE54739B007D603FAF17DE3AD64B7D636
+:10ADA00009BF685D0727F98B5EB7F0BC6FAA681F03
+:10ADB000C6482FD44DED4CED3BDB2ADECDC6FEABB5
+:10ADC00023487ED659FC2B53B1FF5FC7B97D402F76
+:10ADD000D5FEECFA137D61FFE037F92CC82F96C041
+:10ADE000ED2AF6F7AD95E1786B620249E5507FCD2B
+:10ADF000FCCE54FF33308DD01F37C8649A31CE81DA
+:10AE0000E59EC458C8EFF9A74A7A604D2EE41D2488
+:10AE1000C7C9BFB7669C27313C1ED38E26824765C3
+:10AE200015F43D85B7FBDCC2EBDD26E8774CD00797
+:10AE3000D639C9016D6C8419F9F8DAB49959696485
+:10AE4000C778121580E7C9D93D18CAD1DB8A6F4C83
+:10AE500021BE117ECE298206B23F26FCA493F8675C
+:10AE60003675CEE630A4E7A4A230F2837E56B43421
+:10AE7000D205ED2769C2FF3951EF17BD36CD43E347
+:10AE800096D566A69D08E1EB9936901BD0FF43E16D
+:10AE90005ADF34E4C7BDB954BE178C959F615D7D00
+:10AEA00039BBC70EF253CC96FBC2C02CA4EBFE26D6
+:10AEB0003BC3FD467BFC508D74807EBB215DE2046C
+:10AEC000BF22FDA784F37D8B19F805F2D5B599B49F
+:10AED0006F79C6C23C0AD26BB78DE85F30DEEE21D7
+:10AEE0007FE294F00D36289F21E459F59470FA5EC4
+:10AEF000BD2FD26F52683F4479DF4E0BB52BB5FAA8
+:10AF0000B76D817E4AF76792BED96315E3BE16C15D
+:10AF1000CBA33C29CBFB617927E283D72DAE682AEE
+:10AF20007F5B65541E1E488F013CC6856913111F47
+:10AF30009D6D406707F6CBBF1F17FC751CBA45FA1D
+:10AF4000F92A22A95F5AFA90D7AABB6E447A6A56A8
+:10AF50005ECE7EA952F971A727710EE48F57241196
+:10AF60005CD26F74DC6B25BE3F5EAA90FDF3A74AEE
+:10AF700035600DF5DB8FDF7A7F3AB4FB6ABF85FC65
+:10AF800072D31E2E398ADFA72D2D23FFE2B4E2C52E
+:10AF9000742EF0CDE2AF06AC85F9342CFD22590BAE
+:10AFA000F1334F2B855621EBF937699E32E4832725
+:10AFB000D3B40A9C5F7956C35CB497BFB1D63F8DBA
+:10AFC000F67F7ABCB608BF5F78F5E4166E4737A502
+:10AFD000A39E5860E67C22F56DB9E0C35EDDB57BCB
+:10AFE000B13EE06D3AEA9588AC7A2EFF165F99FC87
+:10AFF0003F53B7798F02E39484D72DA054F5E760CF
+:10B000003F67954094924678D4705D9D7306A21078
+:10B01000FF9A89DB6D255BF5F3C27F789E55827FB1
+:10B0200040BB925AD51386EB80F9AD087F09B30671
+:10B03000EBA704E905FD10BD98E34FD37F05742805
+:10B04000DE969987FB859298BD0F0DA27AD04EAE01
+:10B0500017B5755ECEA7353C7C7EE7C43A38075FEE
+:10B060002CC82FDB6D72DF4EE37FF36A271ABFA374
+:10B070005827DF28825FB78571BE72C3BC10CE1718
+:10B08000395F3D26E5E436DE4F499CCF8472A9A4A2
+:10B09000CA497C25E512C042EBEBEC8E246A27E519
+:10B0A00018F33246F577246EE4F69BD8BF22C050E1
+:10B0B000BFF8F77C1CCCA33C3FF37C921C97EC6759
+:10B0C000A33E36CE7B7F9A89EC2DD0D39DFED5FE54
+:10B0D0002F2361D6FAD97D43E613691572C19D30DD
+:10B0E0002E1BCF0BACBA7EBF89B4CEF038F0DC405B
+:10B0F000FF5DF6F74E1ADF1F7633D0B9B3DA74C0AE
+:10B1000086EBF059467AC308C787A2DDF3CFB7D0E4
+:10B110005515FE71E692FCE4E2F63CD1EF9855D26B
+:10B12000EFAE2490C72588ABD4201EF7E46A49A867
+:10B1300037BE11E73D7B62209F85F614A78BCC4B71
+:10B140007A18F972E9B1B94978BEF4CF34EEB73361
+:10B15000E27B09E015CBAB2DB05FC9C27DEB914717
+:10B160004EF408CEE7EB2A8F6776487EEEDA5C3B3A
+:10B17000AEC779EB72ED3343E851BDB5EF1117E07F
+:10B18000FDDC56B31BC57BB5D9FF10DAE9D55BD51D
+:10B190005AE42328B723BECF390EBE8FF5E6AE8B17
+:10B1A000C9433B5CB69FB776A46776081D7A6FD516
+:10B1B000D325BB569FEFB3579FB7776734BFAB6DAF
+:10B1C000971BD0E7FB1ED1E75913506F00DA039CA1
+:10B1D0006EAF0C741F7101DDBAF955377EEAE618BF
+:10B1E0003F610CDA11EB54770F28EFB6D87B33DAD6
+:10B1F00015A7D6CD7123D98B54DF825F014D8BBE4D
+:10B20000187504F5EA5956FBE918A0CBDCBAD556F7
+:10B21000B30BE7ADE7F73D26C1BFCF737FDC7CBF43
+:10B22000BEBCB55C5822FD1819A1FC65E40318F7F3
+:10B23000560F00545AF9F12328178A4603E3A31E38
+:10B24000AF5D6D45FBEFF2E3F8B87DE9F0B8101F94
+:10B25000850379D9759523D857B0EED8AA0F472121
+:10B26000DC85BF55C8FE287CB9E761E4AFC69D53B5
+:10B270006FA2F4D6029ABFF4FBCDAB530291907744
+:10B280000E74ED6D807673FCDC7F3173992D280F81
+:10B29000199E7B19E05813520EF0CFDB7BE0473C40
+:10B2A000172E5AA76F371FE434EA9FE24D3FDB4267
+:10B2B000BFCBFDE875751B549CF71C01BFD49FCC18
+:10B2C0003794CE1DAEE34DD809FC3FD03BBFEEA86E
+:10B2D0008DEEDE3FA847AF5BC3DB83D82DC47997E3
+:10B2E00039AC2E9C77999D0522009E2391560FC65E
+:10B2F000955C5C1B497EB7B936B057F3286518B723
+:10B30000008298CEBFBEFE4025BBA72C8ED3BDECDD
+:10B310001985F66965E82CC5FCB33C3F9F05683E7E
+:10B32000C82F9ED079FAF57956C3F777A5E6C00104
+:10B33000C44B316BE0FB33A0A727E4FCBA14E6F959
+:10B34000592CDA6F86F6CCADD1B99C83DB63E57BF3
+:10B350007FB68596CB7DA6DC074B7FF033E9DE70A8
+:10B360001CC722ECE635F77BD211DEE5164F3AE238
+:10B37000C1B73A8CF6FBB76DE0FA6B4D0CD8B1F162
+:10B38000643F933D7E9BC2ED733695CBC341A69738
+:10B3900002A86F9A1E8D716F74517DD2636B1ECCA3
+:10B3A000E4F6FF3F55B2879A56F3388835B91C7FCB
+:10B3B0006B1ECCE6F6BFD47B1D18F5D7DADEF6A4FB
+:10B3C000A31F823DC2E1FA1CA714625FE776D21E7A
+:10B3D000E81E323F6997B3A22B3B9FD82CE2329AEA
+:10B3E0005687F9F17CE284E27DD31462DF3ED59D7D
+:10B3F000EB8901C33D5B443D3AC7986D1AF7C0F530
+:10B4000000D7ECC74C2EF4A7B5E0DBE34947FD7944
+:10B410006275581EF2D980E1DCBF743C97CBFD8881
+:10B420007E8CE29B36897E377537E9D28470E03FA7
+:10B43000E8E7C448EEDF8EECE725BFDE661797FB32
+:10B44000C679D48A7E665BBDEF0C69031E891796A8
+:10B45000CFED8E13772A1B395C406FC80FF85D184B
+:10B46000F9034F08BD24F10B7C43710C526EC5B437
+:10B47000F08B7F5B18F0CB6A0BE703B96F0BE1171A
+:10B4800041FFAE44DFDB047DD98361825F4CEC6F0A
+:10B4900088C7914ECE0F57B9FF027A1F417A1BF72A
+:10B4A0006192DECCECEFFFAFCE51CA5E79618F0FB7
+:10B4B000EC8CE2171F8D6250EFB4B9A6A31BDA978C
+:10B4C0006E5E1EE581F494D917E584F14FFBD50239
+:10B4D0007F1BF8B6F690FE688F430939F73CF3FC02
+:10B4E0006FC7E23CFFBAD9E2449150BED546FBB1EA
+:10B4F00005BBE693BD0EF9469EBFEF5B3C072DDF13
+:10B50000ABF7B7173FF7684717E1DB97644AC034DA
+:10B5100090C4205DB0C9D2722E0CC380FDDDB40290
+:10B52000E133B647382E01BDCB6BD5426B74EBF2DD
+:10B5300072215FCA77FDF65BF41B96EFBAF124CA5D
+:10B54000FB72839FBF489C7718FDFC7FEDAE3F47A1
+:10B5500006FC50DC800FE0EA41ECC2FDC4D5DB1EE6
+:10B56000CF6944FB61D3BB514A56D0DF2FCF419AFC
+:10B570006B673D83FED3F6D6E537C2DF1BA41B976E
+:10B580005FAEBD0A0F9AABE369A925103508F77BBA
+:10B590001B2C64FF96BEF0EC962791CF8ED948BF46
+:10B5A00097BCF0C6A7D7A1FDBCD3123F9A4FC3A149
+:10B5B00084C4D994BBB83F4ED2A7F8E537ACAE6C83
+:10B5C000FE7D716C904E253B0F5831DEC788CF1140
+:10B5D000B507AC0D8E36E855DB388AFC50DB7EB003
+:10B5E000E2FA38BD5F619D525AB72FDAF04614DA9D
+:10B5F000678827D44F926E2D7434D487FEC7BED689
+:10B600008FEA39719F72393A7E2AECACB2572259CF
+:10B610000CC051F4B9CD3F1AE9BB635114CEE7A475
+:10B62000B982F3FDFAE51DD1DE2BB2F83A3A29E5ED
+:10B63000DF8B9EBE9BF8719E52D1D19945FC9E68CE
+:10B64000225BC29788F39CB36E12CD732ED3881FF2
+:10B650008BD6AB5E3FA4DF9B59C1CE36D6CD52B15F
+:10B660006E4E6E04E2C23C4F8A782BDF47AAD84761
+:10B67000DF49FAFC6E3167C61652FE7B61CF4DEC96
+:10B68000D1729E6D0FDD87966FBAAF1EE974A6ABBF
+:10B69000A713C20978F009BC293F43BFEA87233BBF
+:10B6A000713A3117C623503BD0AB23F03BD6AFB72E
+:10B6B00078D0CF1ED24EEC13F9F87789F101EE70F5
+:10B6C000DC079FECD8763CD7CE16B9C0EA43E3B985
+:10B6D000DA95039BEE27FEFAEE132E6716F8C715D0
+:10B6E0005079BD25D009CBFD07262A24276C2CD004
+:10B6F000D63ADF6411EB5C5F0E709A9550FCEEE772
+:10B70000F6A9E497B960970542EC8420FF5883DFDF
+:10B7100069FEBF13F86EA0F33979AE374FC807E35F
+:10B72000FC8DF262718FB6E34ED8BAB6CF938272B7
+:10B73000C247E396827E477BA4F4988DEC88D217AB
+:10B740002C5EC4D3D9ED873EBD0DF7B7B5725DEB66
+:10B75000E5B0715D17BDD4BFCD757D76556EDBEB61
+:10B760001ABEB7B9AE572924EFFEBB7218341FF9C1
+:10B77000252EB77EE7B523879F33E0F57B96153DF1
+:10B78000080B9D85DD884E06FC4ABC1AE5EA1014BC
+:10B79000921D5ACB5586211A21F8947894FCCA98A8
+:10B7A00046E3B4F0B5E45BC9D72D7C6B9CB71E9F14
+:10B7B000C6F2F9487B80C7FBAA85EC85D23A1E6F9A
+:10B7C00008ED283EAE1CFDF354BBE6CDA4F8D0BC7A
+:10B7D000DF90AF35D4F718F25E437DCD90AFD0D572
+:10B7E0002FDD7BC8CAF70F015D3D5BE5CDB41F6956
+:10B7F0006D67F8F9B9D3AE6FAD3EE48F2E4D569418
+:10B800009396A5CC1709ED9BF6A964F75C703545B6
+:10B81000A1DDB23C8CDB75179C221FC3F34D1DAC20
+:10B820002B504ECAEF4D61DC0F73C1DB141513B200
+:10B830009F6FAC53A3D0FFDBE067056DC7AB54131C
+:10B840005E1B587BE5DCBEBB10CEFD0D17C2B9BF39
+:10B8500061A4EA48AE443F6C0D8F0B9CBD6472142A
+:10B86000C555D4A5DD3205BECF795BE561E03E8FDD
+:10B8700019E319667152B253CC47F181B3EA785C8F
+:10B88000C3EC557A3ACF756CA2F8B7EFD9624AE7A4
+:10B89000AED1C72314B355C46745EB0CDFEB6EA6DE
+:10B8A00075526C58279AF00F1BD789235DC43DE66B
+:10B8B000B25C5DDCA390E723D5AC5BA6003D2E1CFB
+:10B8C00051990DF2CD752A5BD18FC7B9E2F9136E8C
+:10B8D0004870FD2D80F58A7693C4D7395C473DDBEF
+:10B8E000B75FCEEDFEF3805F21DFECF92207CF8555
+:10B8F000CFED3996FE3AE65FF963F217AC75FD11AC
+:10B90000FB7F9C8E72FAC27E1B437EBFB0FFAD648C
+:10B91000F4475E78CD46FBEC0B4B6DDCCFBD3FD2E0
+:10B920008F2AE642576E1757EFFB21A781F4F232B8
+:10B93000A2DF35E9566E5FD5FDFD38FAD39BEB608B
+:10B940005628F7F747D07A2A7F2D8CFCCC17F6FDC6
+:10B950003020D43FF7DF9D8F3C4FBF10C9A6BC8479
+:10B960007C1CC3F705E5AF5FFB2C9E2F97ED3A607B
+:10B970009D05E523FEEB1F3928572FBCC4EDA96FA9
+:10B980002C0D4FA38F73F896A8472C89E8E783CE38
+:10B990003A33F6C596B1137C596DE185E3E102E0D7
+:10B9A00001E7057829427DD01E3EA6223E3AFC27BB
+:10B9B000E2E3DBE95CBE5DC3F03C3A8817C5C3BF78
+:10B9C00047FAED0ACD9F7FDFFF430ECA9FCBCDF72D
+:10B9D0009EFFCFE6FBE87FEC7C39BF774D77119C6B
+:10B9E00046BE6FCDD7AFFC82F23B22DD04EF15AE31
+:10B9F000F7DDFFB1EBFD7F86DE1FFFC7CEF772F4E8
+:10BA00007E5BD03BD289E79917F6FD23995DC5BCD3
+:10BA10009BFF97CE5BDAF1C355F7915CA8FF2EAB85
+:10BA2000FDC49D42D6489B7648B7609C1FED9F465B
+:10BA300030AEA747D84BC8FE1CD1E541B297AB59F1
+:10BA40001E9D5FF8BAA874AE4341208087B712727A
+:10BA5000E95E153307BA2C82FCF0A4328AFF32EE7D
+:10BA60002B47848F2940FBF4D012800BFA391469DC
+:10BA700072E219757E177E4F09D2464CDF4CBE9993
+:10BA8000E2F8F31DFAFDD5CD867DD28D2E7D7901AC
+:10BA90007B291ECFED0AB22C745F6214D60FD957E2
+:10BAA000FE23DD4978B991D52C733AAE1E4FB70805
+:10BAB0003CB5C6C3BFC65B2B3C897DB459D437E2C5
+:10BAC000CDEC78A01EDB9919EC8BF97C693F2DF742
+:10BAD000C597C32713FB6DB3185AE2D7DC859FCFF8
+:10BAE00086F44B789178BF5A7C4B3A19F12EF12BA2
+:10BAF000F166A4432AC6F8F50FE2BF8B39D78CEB69
+:10BB00006E88B0EBF3CD313CDFA55EF5D27AF473ED
+:10BB10003EFFCE6D46BB7E982386E2428DF71166CE
+:10BB20000E8C19A0C07C93CCCC67837D289EBD91E0
+:10BB3000DFF57EB37F690A8EC3FDBB5DCDDC7F0D73
+:10BB4000ABDB179E47F53D56C8173E328F79A07E76
+:10BB50006112732BBC3E8B8EA5F038A6C6F27B9B80
+:10BB6000D8AE309AF75BD889F997727A125DD0ED2A
+:10BB700083FE0DE8D7638AE5EDA3F2A8BDCFC4DB51
+:10BB80007BCC90764BE3710A4DCBB95FBEF0BEAE75
+:10BB9000E9283F460FD7FB99DFEAC9FDD232ED9B7A
+:10BBA000E1227CA9267702DD8F589649FB2335DCFC
+:10BBB0005BB61BFDF43B789C4EE18A3BC6F447F82C
+:10BBC00076C4B911BC3363770EE0F5A7DEFD07F844
+:10BBD000AE6D0DA3EF9333B4A53D311E40714DDF23
+:10BBE0000D1F664E3A644D8021B4DA71E7D14F38AB
+:10BBF000D6B7F37D3C9F1C3B51A5FA63198FF764C0
+:10BC0000CB601C281FE3FBD69C00FD8D814D079661
+:10BC100037863993EF04F80B857FF8215C2F086F86
+:10BC200038D35E72205C5DD353E1FB18D676BCF14D
+:10BC300051597FB8B20ECF99BA8DE0FE7B591FFBE8
+:10BC4000C17E3FEAC9FD514F8854E601AF547FF6EB
+:10BC50004A5B631AEE7F565A023D2175F41ABEBE46
+:10BC600027E06F742A1BB516F17EAFCA3612BC4DA1
+:10BC70008574AE1099E1423A68C0D274BE5293E224
+:10BC800042BF58E3B0DA009E27343E91E2AE76110F
+:10BC900095291E48EEB71A8705BAA31FBF29979F9B
+:10BCA0004B1C773644E27E7196C3CEEF498AB8A228
+:10BCB00039E25E4CB7EA8607AFC17DE8A32A9DD77B
+:10BCC000CC7994DFF7FA8BC3EE5770DFB646DCD73A
+:10BCD0005CA58F23624E37F98166D50CB3E27E7383
+:10BCE000B6C363C579FE31437B1DE725EF17F642E6
+:10BCF00022409785358514AFA246C1BAC3756276D6
+:10BD000045E13ED81887542EE28E64FEA170ED30D6
+:10BD1000F2C3CC68D70EE4972F2BD3C83FAA0ABE34
+:10BD20001B8D7195789E616E484478EEEEE922BED7
+:10BD30001C1DEB4C77103F8731C443A3C5998EFC83
+:10BD4000DDB83CCC84E772A39772BE867566374334
+:10BD5000FBFBCD2C1CCF197E27DA4F5B62F66E8081
+:10BD60007C173B3347C6225FE5125FDFD24B7B0275
+:10BD7000E777EAD76C20F2C3AC55ABE93C46F20555
+:10BD800033D7E7C7C138A736A7E4A1DC6C91D3BD90
+:10BD9000867F81ED5AF861A2427C00E98134E28716
+:10BDA000F10D38CFD1C303DD1766E17EB49479502D
+:10BDB000BF273037DA09CDAC89CE2B9B1D5617FA39
+:10BDC000BFA43C917203E8EAC17BB7920FB680BE74
+:10BDD000375B18DB5A65A7F4F92A2733F7606C7BC9
+:10BDE0005502E57754B928ADADCAA0EF2F55B92952
+:10BDF000BFAB6A20E5F7547928BFB7AA80D2D7AA8B
+:10BE0000BCF45DCA25C00BC9212957A43C9AE5B0F2
+:10BE1000D27D5F29978C7C331DD03B348FDA93DC45
+:10BE200093F20EE761CA0BCA2349DF54C5EB4B48B6
+:10BE30004139D63015E93F523DF7C22BB82F2F724A
+:10BE4000B8699FCEB8DC6B067E45BC245BD95EF436
+:10BE5000CB56DFE969BC2F2588FFDB8B14660EE12A
+:10BE6000AB3B2AC29839446FCCA88CD1E5A7557E4C
+:10BE7000FC4627E8FF9E0E5A7C06C071FC375FAF78
+:10BE8000FF237C7FE637677A20BD018ECD8FE3B834
+:10BE90008BC35BE088C5FC320B9D737513FE936EFC
+:10BEA000C27F82FF903EF27EF333BFF91BADF3C633
+:10BEB0004A9B0BEDE2CF915E80DF3F097ACDACB4B7
+:10BEC000111E0B977FF5C22BB8DE175B49DECD5CE8
+:10BED00026D6A3E15EF397898CFC126055B34AC065
+:10BEE000DF97BFB60622A0FF2F15BE8E15300EA617
+:10BEF00061FCE1CAB73E4339A0541EA1F3770DEFB0
+:10BF0000E1217C3ECB39DD3DE9CA37A91E6BE81241
+:10BF1000837E1379CF38A29FC7EA82F9236F23FD6E
+:10BF200066661C648978CE52A338D185385B7C9FC5
+:10BF3000BD92BFDB80713C13C1FE1B92A1123D2B51
+:10BF40007B9A29FD14F52DF9936B484F49BE9DBD91
+:10BF50000ADAE1FAA8C9B5CE0D91C733C5F7591968
+:10BF6000264AE5F731D82F9EFFADCC9D82764567F6
+:10BF70002CCFC2346F0AE2B7B363945909E1831B33
+:10BF800032CC020E46ED3EC54507E90319A9D63964
+:10BF90005974BF8FF4981C676646DE0A8C2F9DB9D2
+:10BFA0006A184A61566D7127C4433D6F4B3FDC7E72
+:10BFB00063761E475DDA8E1E917EB553F8E7B53481
+:10BFC0006FF2FB16EFF8FD8ED7A0E7E22F6C44DF8F
+:10BFD000E23E226E2BCB3F60023920F5FEECFCDF07
+:10BFE000FF398ACE2976F1F84E48B99F757111F75D
+:10BFF000CBBA617DB5715E7478C717516DFAB177B0
+:10C00000A957E4C72E577E8A423B42CE67E4BEEF73
+:10C010003B121CCA253A272ADFB7BC635B715E4618
+:10C020003F768BBF5BF8F5CA1717B4E9EF36FAEF26
+:10C03000966518CE0FCC8CEE8D49FF1D53B3A2F13F
+:10C040001CE07B719FA4BD7D8EF47F97AF854EE28F
+:10C0500060BD9A5DD178BE75A11DFBFA6806D7FF59
+:10C06000E785BFFCC27695F63D17B647D2BA5AB0FF
+:10C07000FD9137F1DC71C12685C02863F5843FC08E
+:10C080002BB387EA358C638B6B0D77B3BF4734EAEC
+:10C090009592DF475620BFCDAF553C9B019E66BBB6
+:10C0A0002BBA43083C5B91DF807F4A6CB50308DF05
+:10C0B00002FEA7514EF60FD69B5FF708F997A1DE57
+:10C0C000376417BD1881B10288F7F711CEB3EBFAC8
+:10C0D000BAF1BC707EEDCE0564576C8F70A25FE143
+:10C0E0008C885B96FDEC12FCBD2B83DB3167C5F9B8
+:10C0F000D1D91DFC5E3FC289EBEC8CC2FDD0B2DD14
+:10C100006B02CED732F8BEE48E0CBECE65FDF9B51B
+:10C110008D51DDA1FEC9BD1F537A58D49FEFA8CF22
+:10C12000417D7C7257049D7F9DDCF5D4A8D761BC0E
+:10C13000F3B5C3E2715DC8FE3FCAB050FDF3EBD466
+:10C1400002C417F3F3B89932C46FDF5038E336F8FE
+:10C150005242D71F8F1F3ABBEBE5285356909E657E
+:10C16000F60A7BA209D7D19D5EE4EF68641E80D7F2
+:10C17000BA6B9C0F7558795D2E43BEA6F59748F5AE
+:10C18000579A42EAD92C6E8A33B5EC2DF48837548D
+:10C19000F83D2711C73F52CDA273C5E97D5C936F6F
+:10C1A0004739F9AE85E8B130D33519E5D3C57A956D
+:10C1B000219C0B535800ED9345F7466E403D26E118
+:10C1C0009EDE97CB83D2950AF3C0FC4AFD2AD3208A
+:10C1D000ED0CF4F7213F2534F4C738C9C6146E5767
+:10C1E000C8F8D1278B4C1E2BE8C19F3262E5FB0FAC
+:10C1F0004FCCC1F3B3F119B49F3B6E653E15FD4AB8
+:10C200002FF1F8D2D2541ED7FCA488872F8D0DA40D
+:10C21000C7417FE7047D4BC707D231EEA2F4A544A6
+:10C220008ABB3867E5E79EF81DCF594BF3A0BD8365
+:10C23000DECDD064FB98107E2A9DE976613D35D62F
+:10C24000EDCA7520BCCE6FC8CEDD1DC9D0CE35BDC0
+:10C2500012C9E3A69E0BDB680BA19B3393F39F7C73
+:10C260008F83DDC6E38C1EB3F0B8D4C73627FAFD42
+:10C2700021F87ACCA24D453CE03CD0BE9F6FAD4941
+:10C2800047FB57C23B3FAA86E03C27F87D7E780DEE
+:10C290008FE716F77BB13EE61B451C7AD3361BC5EC
+:10C2A000019D49ACDF83E39FD996892FF200FCFE04
+:10C2B000B97BA91CEC4BA067F1F3B600CEE7F436CE
+:10C2C000EE8F3E6DE1F6DAE971092EA46FC1F8B583
+:10C2D000D3C95FB3C9A6A09FEFB4C2AC0958BEB919
+:10C2E00003C59F17575552FC7631880DBC3F046932
+:10C2F00001DE033ABD3993E2CD4EE33B0C0A7D5F8C
+:10C3000089DF355633FD97888FAD7C7F75E6F9BFA1
+:10C310006786C67BCBB478933EBE4EF2892CCFCDD8
+:10C32000E4F22D57E0B97F267F2FA42CA2F6B1545A
+:10C330009A27C73BD089BF5BC31A229FEA87F114B3
+:10C340003D1494234FB240FA53E877D8CAF75F6799
+:10C35000B65B286EBDF895480FC5B1DD778D89E2D3
+:10C3600029546EA7179B007D902ABFD94AF165F129
+:10C37000CF87E5D9C83E67B4CF6DDAAC8A71C026E5
+:10C38000C6796FE171C7A3D196A4F26C2A3F2DF252
+:10C39000A7F76493DD07FD7BF07E55F12F7FC5F194
+:10C3A00038A1E828B7BBEC246F4B5BCE790647A3D6
+:10C3B0001E2CBB6F5034DE3F641FA80CED16239E6D
+:10C3C0002E9ADD9D50CE2ECB147277CF7A3A9F2ACB
+:10C3D00011F7084A9E57F83934AC43BC9F59B262F2
+:10C3E000D0E3C49FEF5B580F98CFB9DA47A242E978
+:10C3F000B12093CBD396FA5637D52F81FAD84FC9AF
+:10C400008A77A3089E2D168A5731D2F18ADB3FAF77
+:10C410005E51FB16FEA8E57E9656F367F5BFF8025F
+:10C42000FAFF6E7B98DB475F6BE91EDC594BED5CD6
+:10C430009CFFD917C2486E9D8DE1F2E124C8535F7D
+:10C440004F84E3E68729BEEBA309747F6F9E5FDF0D
+:10C45000AF1C77512697E36571EE688C172CFB8033
+:10C46000CB41A0CB2DD4FE030BB537CE63BC68D730
+:10C47000B23E5F88207E38DB99D3E5EC8E9EA49F88
+:10C480001A63389F03BCC978DFEFEC0B3D73E91EDC
+:10C490001D1A3DC00FC562FF7B36A636D91952DE84
+:10C4A0006811FBB800D444BEC13620DF8B2BB9BD68
+:10C4B00055625F45F12518AF3B208FD2802DB675B0
+:10C4C000DC2DF02BED2FDFC9147E4C1CAFA388139D
+:10C4D000273BA8D68A725B13F662E97663DC2E2FBF
+:10C4E000DF26DB03B4F1324E18F9D0A7509C4AC9BD
+:10C4F000B23BE753FC7DC5EADB719D49F84BCCAC00
+:10C5000000F7698D8A4A703486B119E3D1AE0C1DEB
+:10C5100027C49EDB151C87E1FB5FA5F807ACD9BDDE
+:10C52000992EFA8EF91AE8AF7499B28AC64991FB2E
+:10C530005D3E2F8927408715E3041B8789F276E645
+:10C540002DE134CEBBC5EECAE4FEA5C614D7C38325
+:10C5500091CEEFA9749FF7E24F7DA363DBB0D38246
+:10C560007ADE1A8C9705F88F6532EA677D26B7D395
+:10C570004B301E17E04C5FA78F17CFD8A4CFF7DA48
+:10C58000AECF67EDD2E773EAF479F7617DFE8018EC
+:10C5900017F7E1787F18F7E198E23EDC65E3FB707E
+:10C5A000CCE33E1C53DC87E377DC87631EF7E1981E
+:10C5B000C77D38E625BE713F8E79DC8F6379782F91
+:10C5C0008EA752116F8974407E67AF86E9EE235DB6
+:10C5D000D8C7EF97001FF07533D54AEBE649AC4159
+:10C5E000FB11EE77EA3CC1EEC2F8E15571DA7799BA
+:10C5F000FDF11E4AFD8A44A49BB981E258CB5FE35A
+:10C6000071ACA579610EF47F342C3FB902C343B5F8
+:10C6100038ED47AC7FC1D2B405F15B567988EEDFC7
+:10C62000372C717D703DA71FF96158512CD9518568
+:10C63000A8E762DBA7A3319E9CADD2C78F1BE3C9DD
+:10C640008D71E4463E90F6DF3396A64494EB5F6D21
+:10C65000B3AF42F8BF0A13F761A6D80DF1000E92EE
+:10C66000270B1F5436A2BEEEDC8BDB51CD47C05EDC
+:10C670006F43CFCA74D6A5BE6497B7E45729268AFC
+:10C680004FD73CA4871609989295A6C6FB50CECDED
+:10C690003791DEBC08F61AD9839FA8643FE03B5966
+:10C6A000A1F3C177B242F90BDFC9D2DF97E8ACAB97
+:10C6B0008FEF64E9EF4BF4D2C7E74F5C7200F7FDF0
+:10C6C0001356F5D5D59BED1D64C0A3805BD8B3B3DD
+:10C6D000417F78D0BE5CBC3619E9BB687E73E37DD0
+:10C6E00040DF45BBC3DC585E84FF0772B108FAC463
+:10C6F0007B9745BBC4FDE54ABD1E9E25F45091992C
+:10C70000F99CB1413E2C72324F0CB49FDFAB3E0717
+:10C71000DFC39AFFF6C7039CA9B8CF18D609E55125
+:10C72000B2C54371B5A53B7BC42C817E7BF7D06E2F
+:10C73000EC05EBFA44CDA187A6A13EDCC9F77F5FEB
+:10C74000AD7A398AE2CB04BF255B9CE148F70D3511
+:10C750003CBE0EFD676A6C902F36D4C48577770493
+:10C76000E71BE4839F884E401FEEE7293A48E72203
+:10C77000CDB562BEC3141FDAD9727EF21D2DB68C00
+:10C78000F77397C89F10FB0D39CF739907725C78C8
+:10C79000AFA36A6FB28AF2DCB47D0BEE43FE69D3BD
+:10C7A00066F7EA8FF1A03DFE88EFAA15FF81CFE77B
+:10C7B0002F6B46445D8BF6E70B16F768C8DF57F31F
+:10C7C000AC15F715C566BF95E233B76DB062BCF224
+:10C7D0000D5B37D0F7B95B0B291E731EABA0FDE8CC
+:10C7E00029F9EE81C047D170659D13E07E47C88F5F
+:10C7F000A2707EBE07F6D11BF8EEC8C5AD4A2EC6A4
+:10C80000F94CF4EEB416C2F75F8B7AC675D27C741D
+:10C81000C2C80E840F7E0FE40F0C76F769ADD7C542
+:10C82000844B29B42E265EEA4DFBB449814CBE1FD1
+:10C83000CE32EC878FAADC9F57C7D7419135103F86
+:10C8400001D7C97E0BD9B96566FE6E5319FC7D1DF3
+:10C85000A4DEC1AA8E5FCBF32374FC3C85C5EAEE4F
+:10C86000D3DC8A412521F989A3D374F5274FEC6DD8
+:10C87000E0FFBC6039C991EB74F7FECA16FB5CF4AB
+:10C88000BE211BAEFFCE787C21BD086A0FFD3E3E67
+:10C89000580FF97B93C2F73DBB6236A21FB0C8C4E4
+:10C8A000F74F5334FE7DC15EFE9D4D61BA75D82DA4
+:10C8B000CDFD47AE172D746E20FDED53F0EF36F031
+:10C8C0000F9AA2E51E3BDEE347FF84EE7EB7382FCA
+:10C8D00044B8910E65C29F5496C1FD4965BE7A2B3E
+:10C8E000BE9300F837C7C5523D7B1CC655D628E419
+:10C8F0006FC47431C559EAE3B4B03F8C7F5C7044B7
+:10C900002DC475622C2FC2778790BEAFF1B8D405C5
+:10C91000E8178A6AFDDED902F413A17FCBF0BE9935
+:10C92000A3B74BF811FD2B3A231E472BB9746F7335
+:10C93000FB012BC6E74D9C18938BEBC7C86752BE13
+:10C94000C3BAA6B8C2E6A38788CF9A8BCCC4C797D0
+:10C95000C3C7020FF7B31AF96F2EABB7E2FD94B954
+:10C96000BB1437EE4BB11EE2A533F2A5012F71B116
+:10C97000ADF121F1D4823743F93CC6F1356FAFE216
+:10C9800047F9D80A4F027F46F8DBC39F9CD75C4D1E
+:10C990001B857242CE6F1ECE03C78179E038F2DC70
+:10C9A000820D34AED734F25F2DF0F2385B237F8CEA
+:10C9B000BFC4FD32B75E32533A71B47E7D623B5CD8
+:10C9C00027932E75A4F2ABE59F050027EA85ABE51A
+:10C9D0001B391F298F83EB84DF4BB8DCBB4546FF37
+:10C9E00064426FE19FECCFFAEBE29B85BC35B63732
+:10C9F000C6374BFBC0A8770A234D146FD9EC4825E6
+:10CA0000BB43CA5F4DE8156DF9F7544F837A1C1A82
+:10CA10008F4E0F69C24FB8303295DE91485E12D703
+:10CA200011E95518E6A4B8FEC2252AC55117423DA2
+:10CA30005788DDB262595A32EA912FEFEFF9B40FFD
+:10CA4000ECF92FEF8DEF3810C6F96AB925DEEE0A42
+:10CA5000D6FB72F9C8648CEFF86AB56D8ABF0D7C9D
+:10CA60000DEFCDFD0A65BFF98CF4DC79D3D1A8298F
+:10CA7000D0BE74F9EE28BC3E50B29CEBF7F7BA6B0F
+:10CA8000C37AD3B9EF862DF49EB173430EFA89BDF4
+:10CA90001CA72D7645F1F2919DD0EE28FDE7A1A7C8
+:10CAA0009D782F7C89A523DAA5A73F013DA9909EFB
+:10CAB000237BE254187441E77091F49ED92985795B
+:10CAC000F03CEA9CE9C05FEFC3FD626E6D7A40C145
+:10CAD000C353CDDB1BF7F7CB9F257BA6F88125E958
+:10CAE000F8AEA0B6A447745BFE14996E11FA1CED63
+:10CAF0007A4CD1AEC7F81AB4EB318F763DA668D721
+:10CB0000E3F7F2B57ABB706A4F2EB7A4DFB95B7555
+:10CB1000532E9EFBF986B38C0AD2C30E7A07789106
+:10CB200012EE46F9B4086D28CCFF3982FC0EEC9366
+:10CB30001B757496EF04CB7780873481AD16B24EA7
+:10CB4000AEBF6467A1F77487B1185D7E843D51570D
+:10CB50007FA43345577E4342A6AEFC4657AE2E7F98
+:10CB600073C6B5BAFA63DCC374F95B06DEA8AB3FE3
+:10CB7000CE334E979F503055577F92B750573E79DE
+:10CB8000CA7C5DF954ED4E5DFEF6A27B75F5EFA80B
+:10CB900058A22B97EF22D7E17ECC86EFBFD82995FC
+:10CBA000EF23DFA3327A5F6DF00813F733DAB83E74
+:10CBB0005AF45E0F47281F3C29F8F95296E751E4D2
+:10CBC00057F9BEA57CB7722BEAA3FE788E1950F8F0
+:10CBD0007EB83E11F9D858CF583E38E2E04517D01C
+:10CBE0003266FBA94966901783AF39D8370DF253E7
+:10CBF000B7E7DC4AF941075F4E857C61D6DDB79A1D
+:10CC0000415E0DEE73F022969FDDDE97974F6064D4
+:10CC10009A94657D3209E365075F9FBACACDFD2806
+:10CC20006DDE779729E203EF89233E300D001F6305
+:10CC30007A10F818D3C3C0C7B32D8CBD097C8CE91A
+:10CC400011D89FE2F777607F8AE951D89F62FA3E58
+:10CC5000EC4B31AD877D29A61F554DA1F4932A8D4C
+:10CC6000DA7D5A5544E9675515F4FDF3AA4A4AFF9F
+:10CC700054E5A3EF877B4BFF4340F77E687BEF844F
+:10CC8000CA734E79AE595DC11A22506E349863BE94
+:10CC9000B607CF2BDBF71398D9D721F65AB6E2F9AE
+:10CCA000A0378DDFC54971E2E2FB1D29DA2748E78D
+:10CCB0003FA44CE8D157453D56F10686DAFCC1D475
+:10CCC000F67B905B7B733BF9DD2CCF31EC6F889D5D
+:10CCD000DF4F1E62E7F78F8798EBAB91BFAA7F64A7
+:10CCE0002E8CFF3910C9DFFDA8BEDFEC473FA872CC
+:10CCF00089AFF3A1F18CF2D53F36D07DE5214E7797
+:10CD000002EA2B996F39F7C77F21713EF21C5EC68C
+:10CD1000F7E45FAA1F81F6C25087D5857224346E6E
+:10CD200000CFDB0F447E2DE161389E3CDFDFF42332
+:10CD30000B987282E7F843ECF529E837187A97DD0B
+:10CD40001D1AB724CFEB954B0D2AFA55657C921C22
+:10CD500047C21B6986FEF282F147439CB5B978DE73
+:10CD6000515DE6A0FE3AC1776B1ED5F3A8D4AE366E
+:10CD700017FD72434B1D14072BE3043A8979433D99
+:10CD80009A67FE258DE224868A3809ECC7CECB7DD2
+:10CD9000D8CFD0F84022C6810DADE0EF90AD57F866
+:10CDA000FBF3326E01EB4784AC5B8413FBEDFE3783
+:10CDB0008017ED288F87F03B41EEEB5C222FCF1DD3
+:10CDC000EDC3C9BF3542C89A8F53B4CE59786FC5E9
+:10CDD000E6FC7304ADEFB4AEE8371D27ECFA7FC173
+:10CDE0002FDDB0DD7F9F5F3C9CDEF8807F4A6BBE0D
+:10CDF000917491746E8F8F24DD43E2CC88CE2D71B7
+:10CE000063A21F237FB5C757929F86D839DD91AEA5
+:10CE100018A726F948B9C4DF751B5A6A277D27F978
+:10CE2000C8C807ADF988F365F5DD76EAAF351F05AB
+:10CE3000E98FF8F8F7F9A841C5F3ABABE59F194DB9
+:10CE40006C5434143D94AA6D45395278C9F526E6E0
+:10CE500067B161A390A564F9E358DEBF75B9F65DCB
+:10CE600093253A84CF86083EDBDF4E7FB29E7CF767
+:10CE700042F67FBC9DFAEF0ABBE1DD3019A7E271F3
+:10CE8000E40E08C68D2E1AC9F9AB204525BB6344B4
+:10CE9000167FCF9C39B89DED82FF501EDFC4B4C30E
+:10CEA000D129F8EEA897DE1B1D156F786F54D8E7CF
+:10CEB000058673FE9BB26E20FBFCA6CBBC5BBD2C33
+:10CEC0004BDCDF49612957F9AEE86FB3687F78A57D
+:10CED000EF8AF2F768F3C57A4F12FC94E652D9E074
+:10CEE000587C9F5D33A372398CEFD1E6E0BBAD3E39
+:10CEF000CADFC8FC94DECC0264478C014584F95B30
+:10CF000018A37BFB8722C64EC33B8723FA8EE88E8D
+:10CF1000DF43DED9F3237C0B54EDFF3843DED93BEE
+:10CF200098EFA2FBAB07ED696487E27AB584F84B12
+:10CF3000DF06FDDC1DE67708F437A66F80FEEE0EF7
+:10CF40007AF42DD0DF98BF296309C376A35CFAB8C1
+:10CF500027D9FE66E708D8A8B58FBF9B735EED8220
+:10CF6000F87D37A6673EF2C5BB31D7E4E37CDF8DA1
+:10CF7000E964E2A9CD4A69F62BDDDBB293E57A08D4
+:10CF80008E378AC633E257E2D3884789DF7F039F13
+:10CF9000EFB485CFADB88FC0FB21F68FA31252F14D
+:10CFA0007C93CBD9B28864F1BEE87B396A2AC6FB90
+:10CFB0000E223887565ECBCC78DE6EE7783A59C5BC
+:10CFC0007C88DFD3380574781BFC7BCC3CDC141ADE
+:10CFD00007FD8A4DFB13C271729D4AF7F5CFBF144E
+:10CFE000467EBB537EEE975C68D21AB3D06FAFBA61
+:10CFF00056B9D1DE7C57253F30FBE950F2F8C8AB7B
+:10D00000E0D74DFC9D8352FBA836E929F797CFA5C1
+:10D010007A68FD33C3EF4B74B1F1F720E4BB94970A
+:10D02000FBDD962E362EAF257DD759851D00FD0CD4
+:10D0300000399BF47038EDB7F674F4FC88F3837D07
+:10D040000CBD3FD5DC2592F4D34111173734D09B6A
+:10D05000DE5B2B10BF23F096789FFDA08897FB7BAB
+:10D06000BA66CE0678DF721DEC82FE87EB193F07A9
+:10D07000BAD1C1DFC3BFDAFDB9235BECCF7358CEA1
+:10D0800055FDEE410795EE530C65E9740E3F02E144
+:10D090004539F7F62C33EAC990DF3DA079FD6FFBE7
+:10D0A000DD03C69A549C579253614FA65CFDEF2056
+:10D0B000A8625F257F0FA18017B5FA1D84A7A20A79
+:10D0C000785CBE636E9BBF839024DEA9662EAE376C
+:10D0D000E4EF208C4CD0EB9111CE61879D94EAFD5A
+:10D0E0003C4997891F1B9D2DF4C7D5D2BF8C11FDDC
+:10D0F0005BE24CE379FCD350ADD7C3E89F1F116FBF
+:10D1000071FB5DADF9E03FED774EDAA393F1F74F98
+:10D110008C7432FE1E4A925A6AA67720059DA6C0DC
+:10D120007F48A7EBC5EF55E4E3EF55B0FF7774AB4D
+:10D1300036D0ED7BB6AA3FBE5B7AA190CBF5F6F474
+:10D14000FE0D299EFBB341FE3C2AFC47D23F22E361
+:10D15000728DBF9724FD00325ED7379CD3DB773CBE
+:10D1600082CEAFEE511B2251CF1C37F1DF471AD8C8
+:10D17000417B1CE5D38CAC0A05F191C0BC3BE702B6
+:10D18000FCD3FFCB968CF9E9DDF87B912C8BFFFE6D
+:10D190008F846F7A128FE77A265BE17E3F378FDFCD
+:10D1A000DA98CDF701916E27C599176631113FCBFB
+:10D1B00092A767237F1E0DEB89FCB786FB031BF04C
+:10D1C000BDCAF8E07B9568A7A35DDC55D8A5D5C797
+:10D1D000EC76CE874CA7FF33FD765D9C73EFAD4EAA
+:10D1E0005D3EBB364157BFCF5E97AE3C3790A12B1B
+:10D1F000EF7BC4ADCBF7AF1FA8AB7FCD671E5DFE45
+:10D20000DA86025DFD41A7BCBA7C126B7A02F17B23
+:10D210002C3B95DF9F50849FC4C5E931FD9E8E74E1
+:10D220005F49EE3F64DCBB26F8D9B8AFE966E57626
+:10D230007D7522E3FB56BBD89F32FDFE461371EB92
+:10D24000D2AE673E7DDCBA8C576FD907897D8EDC04
+:10D250004F84C4AB7B107E19AFDE4277F17EA8917C
+:10D260005FBF167437CEA39B95DFAFABBED74AF72F
+:10D2700084247C46B8D40CCEDF9BED6DBF07F55DF2
+:10D2800036B713F2BB7BCF21BF3E0DE28AF0D96ADD
+:10D290003C7703FE9E40F5AFADEEA5AECB8F37BD1C
+:10D2A0000F9FCF347C37378BDE5FA57B81725C7339
+:10D2B0000E1FF75C1FC1E786F1A647F3F838166D1D
+:10D2C000A57B2DED8FC7F19A6065CBE8DD2A71CF84
+:10D2D000E38E55B50FA20B759AB5C6C21F1EF05B43
+:10D2E000D08F367A38D889B9E85F7DF85107D86988
+:10D2F0004F579AC92F1691639FECEB1EBCB7D30D05
+:10D30000F669C827A391FED0EF923E3C3E3D0B6DDF
+:10D310009F0EE47F6FB96F61D3C97F46F2BF0DBE28
+:10D32000237E94F3F89FBA7F21F9D78827B92F6716
+:10D3300042AF75177049FCC97521F127EFBFB8EEF0
+:10D34000B478373AE81E4D01C6E549FAADE9C3FDA8
+:10D350009CD3053EB01ECAA3F6EA8D54B3A2F1BC1D
+:10D36000A099B9A29D97F19BFF0FDD4B21FCB777E8
+:10D370009FAE3D39D14A3EB473BFAE3DFEA47F5748
+:10D3800071CF2E444EF07829410F7F7713C525DCED
+:10D3900017A95FC70FE570FCE689F504FADB91ABCE
+:10D3A00097130CCF3FAA97AB424ECC6DF9FD10FC02
+:10D3B0003E67B985EC6EC6BC8F619CC65FD658E8E7
+:10D3C0009DC7A11E46F6CDCC758A7F8312FCDDAECB
+:10D3D000429FE19D16F527B20FBF5FA538F1F71FF9
+:10D3E00066ADD497CF73F0DF1D99637CAF469EC7BF
+:10D3F0005D665F5F9523F4BB9BB9C92E137114451D
+:10D40000A28ED12E6BF6F3F346DC97ABDC8F45F1A1
+:10D410007752EFBBF0BC2BE41D16C06B7806EAF127
+:10D4200065E636E3225BF0DA4EDCC7398788FB70AD
+:10D43000F03897E65D61FC7C589EC389FAE77C175B
+:10D44000A91CEB636FE77379FC8A3C7F339EEF3551
+:10D450003B4C743ED5BC2B92E21CF0DC2B1AF8E15D
+:10D460008C6967C7812941F8B40655776E644CB55D
+:10D4700025BB693FF95E776D5B0EC6E99BDD7637AC
+:10D48000E4EF771CA477BC460B3F9811DE96DFF1E2
+:10D490001BCCDFD569F6717BB7B980BF7702F291FB
+:10D4A000E17A92F11CE3185877901606AE2578AE13
+:10D4B000F6FC6BC2A55C7EFE7B6910B5D7565E4B51
+:10D4C000F96ECB1EBC13EF194DAA9E67C150808622
+:10D4D00027168F0C87A60D5DFD4BC3916EC3943646
+:10D4E000CF2FDEC9E17AA5C1706F41A6D7F5E17AE9
+:10D4F0007532C6E6F40F89E75AA2D07A58A83019D7
+:10D50000DF45F25CE62FD688FC489E5FB49CE71BA3
+:10D51000C4EF2A6C11FE169C37A6386FF40B6C17FB
+:10D52000FE189C37A6386FFC8EF20BF328BF308FA5
+:10D53000F20BF328BF3045F985DF67326F72AECA50
+:10D54000CFEDF243D6079EDBE587D847786E179A72
+:10D55000C773BBD0FA786E175A8EE776A1E5786E5E
+:10D56000179AC773BBD0FA786E179A67036F0CE6E9
+:10D5700051DE79C6E9F213C0FECF0F59DF786E177E
+:10D58000DA3F9EDBE9FAD3EED4B5BF9D55EADAE384
+:10D59000B95D68FD19958AEE5C6F86788776D6DA74
+:10D5A00038E29F7D295E5B1FA0EFFF89F8E7DD165B
+:10D5B000DC2FAA75F3F9BE2DDCCDE95C53C0E96E12
+:10D5C000E2F72C94A6A944E7C5569E1FC9E3BC8D7B
+:10D5D000FC83E762F9167E2E86299E8B618AE762BC
+:10D5E00098E2B9587E0F7E2E86299E8BE1773C17F4
+:10D5F000C314CFC530C573314CF15C0C533C17C319
+:10D6000014CFC5B01D9E8B618AE762F81DCFC5306F
+:10D61000C57331FC7E1CCFE72C41B8D09EEFAEDB4A
+:10D6200057021FEAF6954E5D1EEDF9D0FA68CF87D6
+:10D6300096A33D1F5A8EF67C681EEDF9D0FA68CF8E
+:10D6400087E647E5B8687DA15D1FDA0EEDFAD07C6C
+:10D65000768DEF0DF49D8D59F7CD614C1B2295A76A
+:10D66000151019057DFC93F1FCB2214C498E01C9BE
+:10D670006959B279723EE435114799C39A4CF4FB6B
+:10D680007BB879C4388700A3B8D5EC1F13A97CAA4E
+:10D69000BC7F87FF80EEB9BB18FD1E8D3C5F97ED08
+:10D6A000DDCCA9622AEB07F36DD7338E2FEB91FC0B
+:10D6B0000C81036F5A63BC4FEE62471EC6CD6E11DC
+:10D6C000BF8FBB65298FB736F2D562612F6D31ED03
+:10D6D0003C88F7699A0A15BA779D6E66472C798857
+:10D6E000A78A3CB42366F789117AA9E23AFC1D3176
+:10D6F00009B7F483829CA0FB89839BEA4744433F9C
+:10D700009A6F18FD3ECE682BB71FB01DEE2B7BFB2A
+:10D7100014CFC610FE5E20EC71CDC7C77FEE99B165
+:10D72000BC5D386FF7DC335184C7B1CB148A3B1B27
+:10D73000BC9D79F01EF43D429EF6DE1E5071BCC2C7
+:10D74000657C3CD96FE1BA64BA175AC81AF2F15E27
+:10D750000BEBA73094DB126F30BFC338BF74582A6D
+:10D76000E8C7BED2FB5443FAC58CC4784456C7E818
+:10D770005DD131FD3ED4CD97C83E80FA25BDD6D3CC
+:10D78000A7D03BCE637D4B96225B8CF1DDF946073B
+:10D79000ACBF89B9535CA48AE8FEB184A79767A798
+:10D7A00009D422CB62F5A63005E9CD0EC585F00F70
+:10D7B000ACFC8948EF5CB785DE551E67765AE89D5C
+:10D7C0008E76E2752E3A64BC8EC15E30C4E5542F6D
+:10D7D000FE2C19FDCD0B234DE43759B83B82EC06E6
+:10D7E0006DAD42724DDA418522DEEFE2B2373A4C3E
+:10D7F00046BCEFB4507F325EA72CCD9F6CC2FB09B4
+:10D800009D37E4C4AA64073C8FF2F0ACEFE55B07F8
+:10D8100062BDE5FC5DD18BCB76F3DF1915E73BF2FA
+:10D82000774B678BF8AFC26C6F34C6C3C8DF4793C2
+:10D83000F764E4EF924A3F4FE17B7DDF44FA16AE96
+:10D8400017EF7EAF2CA4FBEFC6B8AB1261FFCD5F24
+:10D8500066A1B8ADF906FBB044C4655DEEF74A0FAA
+:10D86000F531D887F27772441DA676F914FDC2F21D
+:10D87000DEE7340B9703D376323AAF9AB664840965
+:10D88000DFAB66BB39FF4C5BC2ED9C69AF7AE8FE4B
+:10D89000A6B41B3F10F6CCF84B4984FF8F85FD32B0
+:10D8A00009E35501CFA31BC2441C5B22A5932FF1B2
+:10D8B000F8D5F10E2E0F1AF6F177379A7D366E579E
+:10D8C0001D66FCDD38037F8E33FB4D78A1D13D18FA
+:10D8D000F813F263D01E82FEA6A07D1487FC9E3250
+:10D8E00092E2210B14BA4764E4F7D1968A3730DE0E
+:10D8F00076F466E6F6B1507E073EC6FE7C0ABDC7EA
+:10D90000A0897DAEE46323DF4F8F10FE2907F73F28
+:10D91000B5F829D056C547D47D7F9B8CF1C4D3D1AF
+:10D9200067D899A6E1C1B8BDC82C5EFE8F17FF3637
+:10D9300079196E7ADAF15BA8BFB4123E34F9EE447D
+:10D940003B7E04F41FA0BCBCE3AE5CEBCC1079F9C9
+:10D950007F018165E5A90080000000001F8B0800A1
+:10D9600000000000000BED7D0B7854D5B5F03E7340
+:10D9700066269364122621901048980422A906383E
+:10D980007941401E87C82358B40349143009C33B6A
+:10D99000A878236A0DBDB499908001C11B340AA2F6
+:10D9A000E880CAA5966AB4DE0A4ABD838855EB03AF
+:10D9B0008354EF6F1B86A7A0B546B8D6F67E5EFDF2
+:10D9C000D75A7BEFCC9C9399006AFFFF7EF76BF8E8
+:10D9D00074679FB39F6BAFF75AFBE4ADFCD28CFC2E
+:10D9E0007E0C7F2CAC3F630B5CF43B9BA2E6A50650
+:10D9F000F3185BB12E27953919FB067F26F62C17F5
+:10DA0000FEF54AE6EECB584D9FE01D8AC6D8208D24
+:10DA1000E993D3189B83838CA5A1022C97B1B9A25B
+:10DA20003E5D1BF2410B8C5713CFEB69ED8ED93E57
+:10DA3000A82F7704A7AAF0E89FF2EACA065818EBC5
+:10DA4000A3BA198375C5D8BCFAC02CC66C7BF20387
+:10DA500003E1919AEBA2E7CC1A1CE04960AC7A434F
+:10DA6000FBC6616E1C17FE57CC5895BDD5C67020FD
+:10DA7000E6B77986C3FAF298EE77627BF8AF88B1A1
+:10DA8000E3EB9E7F6ABD125AFF711B9BDD1E617F17
+:10DA900093340BCDB3B38131F730C6763538A87CDB
+:10DAA000B2C1C5DC318CED6E48A3FA530D6E2ADB92
+:10DAB0001B72E9F9B30D1AD59F6B28A1FAAF1B743D
+:10DAC000AAEF6928A3F285060F3DDF3FD05BA0C116
+:10DAD0007A1FB0E8C7EE82FDA5ABAD8C0D8135B6DF
+:10DAE0006E66780E8B700B6E829FEE18C598971F2E
+:10DAF0000B1B6CD7ED2C85B1A6758A6B35F4F33A08
+:10DB0000EDC79444285B9440CC0868E09BA207735F
+:10DB100079DB6FB2115E1C8E2CB7EBC127A05F4D75
+:10DB2000839DAD87478F5EC6741CE7D19FD8FDBE2D
+:10DB30002C84DBA1838EAC101C3FACBFD7061881B0
+:10DB4000C797E3867673EB62B5F5F0FEAD7C4F19AF
+:10DB5000AE3B3E4FB37B016E19F98CC6BFAE9FE75B
+:10DB6000871A94CB37EC7FE47D3CC77D59762FE054
+:10DB7000CFFC3DF96BD3DCD8CFEBC17EF39D2EBB40
+:10DB800007FADDD29C6477231EA4B2BAF63C9CA7A8
+:10DB90002B73564208FEB59A42EBC82AE0E37F8613
+:10DBA000E744ED5A6D330DED2CD40EE0A63BFA8719
+:10DBB000E09461653E4B01C2CBCB7484D700A621B3
+:10DBC000BC06C2F39802FE3E3639043F33DCEC005B
+:10DBD000770BBC1F08A5BD2004C70C78AFC2735BD0
+:10DBE000EEF1392C1BE1C6E67922E0CF83B87E84C2
+:10DBF000FB6C07D1D562073F4FA0ABA9A980872B4B
+:10DC000036292E4003B6C8E9BE7E0CD417BD666324
+:10DC1000ABA13E23D96D1F00F52E38DF1D505F707C
+:10DC20007BBEDD0DFBAEC2B380752CDA3286E86DAB
+:10DC3000911FCAC2E87479C3A603197B117F02BA87
+:10DC40001DE964914BB727E785D16DAB427461AE96
+:10DC5000AFD3545A77156393117ED5B767D9173868
+:10DC6000B1FE9A6D451EEE8BC341F68376016C378B
+:10DC7000239BBD8AF4D505FBDA91C5E72B081B7FF2
+:10DC8000018E1F363FB49FE781FA7D5A028D37DF40
+:10DC900005FBCEC2D245EB0438109CBA36C2786E72
+:10DCA0009A87CE6361C06FD3703D569817EA735D53
+:10DCB0007E1BCEB3A039DF8E7CCABB81CFE36D491A
+:10DCC000B20F87FA7CABCB9E81F08B0358A4D0FABD
+:10DCD000FC3BE06816015C929D380F9B37CBD91353
+:10DCE0003EF3C57A17B526D9171B9E6FB2E17900AE
+:10DCF0007FD323F18D83E2DC17344FB233EC6FD541
+:10DD0000ED1AAE47C0F7D4ADB1EB591FE8DFB6D975
+:10DD10009605F57F13F87B50C07546762047C17D88
+:10DD2000DF1AABE13AE7B85A697FDDF0BD1FE001C9
+:10DD3000CF17BB3C045FC00B1F03382C6A339E67B0
+:10DD4000683D1CBE8BDAE613BD2DB17AEDAEF075E1
+:10DD50006CD99FA3005CE6007D2B007FE6F2662273
+:10DD6000BE9CBEFFFA4CDA27AC13E19AA0B9A7A675
+:10DD700015119E101E4B7CA929E4F42BE7FBA3662A
+:10DD8000A5F9FE28F86774BAD45F4D43BA84F35DF1
+:10DD9000ED8E4E977664DC30AF7D91E26F527AD291
+:10DDA000A9A44F4997924E25FD3E62F304D29410E8
+:10DDB0009FA9E9C3EA9E8D00A78C7C7E0E73C5B92E
+:10DDC000025C5F41B8CAF7F67CCE8FAAB28DF48EA2
+:10DDD000E3E1B8E704BFAA2A0DE4DC9A176A2FE74B
+:10DDE000AD4AE6FD10EF11DFCE8973C7F62BA8BD53
+:10DDF000E063825F2CECE617BBD7F4477EF18CA280
+:10DE000021BF58B1F140C69D00B715BF8CD7100691
+:10DE10009FDCFCC42D03B251BEF9E9DCE4BA16FF65
+:10DE2000359FF8C412219F170522F38BEB73BD6A4F
+:10DE30007E71A8BEE8BE5F5EE6E5FC2680FCE60FCC
+:10DE4000BF7CF1C85877489ECAFD2C6879D736DF69
+:10DE5000190E3FBEDFF5B9E7E6E3792D74DADD2A66
+:10DE60003C5AD83C9FF82F4B635A8E123A7F335E50
+:10DE7000CC6F5674EA573FCAAF7E8F7C7AE18699A1
+:10DE80000CE5943C379898B15121F92AD77F593E37
+:10DE9000A7DB1FE4F3FE73057ECFAD9D641F908268
+:10DEA000FB9D5F886AC51CF17CCE22E3F3EE7373A1
+:10DEB00075F3F9B5482FE7DAF9B99DDB6023FE73F6
+:10DEC0006E77829FC1FE3E59F1FCDBD741BB8F1FAD
+:10DED000D89E89FA4AF8B9B1427E6E582E8573638E
+:10DEE0007D239EDBD8F0735BFA283FB7854FBDF5E5
+:10DEF000C717DCB45FCEEF36C6F8911F2F687F8658
+:10DF0000CE714ECB265B16B4BB3A3F8BCEAB9BFF9C
+:10DF1000D7E5BB18C0776ECB761BF289AB251C4CBE
+:10DF2000F400A5CEC2E80CE592921CD2C7647BE453
+:10DF30008FCFC03CB7DF1A9BC84686E6B92D9FF34A
+:10DF400085857549C938DFC2BAF9F7B01121796002
+:10DF5000DEE789584E2F0B603CA4DB1393B4CC153D
+:10DF6000849F968872F74681870F01B863011F0668
+:10DF7000C6B7FF1CE130F09FE234E41F438706FD83
+:10DF8000382FE237AEDB0EFCD301ED86DE1CFC1C25
+:10DF9000D73114300CFB6199904C25EB0FF51DB077
+:10DFA000EC1228B3555EB6E6733D09DE07F03D4B33
+:10DFB0000916E3FE257E9BF1D7CE1E6FC9463E961D
+:10DFC000C2B42677085FE538125F253E47DB5FCB9A
+:10DFD00045EEEF441687A73D0EF6977C09FB0364D8
+:10DFE0002D490EED4BAE0F7478DD82FAE33F0FDF63
+:10DFF0008EFAF389462DB3CED9DB7EDBA6F48FB043
+:10E000005FF33E25DD2C72709A06BAE98376C7B9B4
+:10E01000D6217D50EE9C5040BE41BF13B7C65A700A
+:10E02000FD725FA897B318AE9763897A391BC6F55E
+:10E0300072ACA35E8E25EAE5F43C3F99CB23164CE7
+:10E04000403D13F401CE0F029C4E3AEB87D0BEE464
+:10E0500073A91774BA8209C961FCFB649D909B2C5B
+:10E06000B811E99BD50F614FC0549DAD27122C7993
+:10E07000889F7C7DB2DFEDB62EE2872CC1EE7E025A
+:10E08000482EFEF677A7A4C27C8BDBB2F215E857C8
+:10E090005D5FD8590FEFAB9B5335E41B8B9DEEB5FD
+:10E0A000281717FBB234948BF16DF9A7B7C0FBC5E5
+:10E0B000CD5768D8FE76857990BEA49DB08475FF53
+:10E0C000909DB054F0B5A5C82F015E4BEA0F0C75BA
+:10E0D00041FF255A6C3ECAF7A55BB89D30C3C25AB2
+:10E0E0001494C34D9EA9C8C7BA1E5434D437D9C39B
+:10E0F000C05F1D21FEFA7EAEE7B7C867D857807FA4
+:10E1000030FEE5288355DC57BB8EFB60A08F3CC1F9
+:10E1100070DD1ED2EBA70ABED1D9762CC19DC7E116
+:10E120008DFA3AF3EA16E4BB2B845C1B6CEF3A766B
+:10E1300017EA3309166D07E797EFB8719FAFAB2C5D
+:10E1400086E48D682FF8E9E09F953890BFAD48C808
+:10E150004E25BD6A8B4AFC51E24FAD58F3E2EDE526
+:10E16000FD116F16C37B94775BF121B0D0B56D576D
+:10E17000F547BC5AB469CA033E906399028E27AD35
+:10E18000C199783E67B6A72637A25EB8BCE93206C9
+:10E19000EF176DBF2B13CB33DB636723BF9FEC9A65
+:10E1A000393909F6BBE4E1A47C354C6EFC45D0E37B
+:10E1B0008DCBAF4A457BE0E6AF0F3CE2023B6E31D0
+:10E1C000C01AE1FE457BBCDF074D6E6ED893A902F5
+:10E1D0008D7D1DE3FD1CE1799365DF756390FF2B59
+:10E1E000FE9D03A8BD3BD5D58B9D7D1AED50C0E7A4
+:10E1F000E53FFB80C6F9D4F2E6B573A0FFCDCB7F37
+:10E200009588E3DC74FFE1512E78FED650EF7FA3B2
+:10E210003DFFB1B27DA70B05D396ED23506E7F8DE8
+:10E22000765A31E2B5E7BA3908F7D755827BB4F9A7
+:10E230006AF728045F59AFF6F7217DD61B60761781
+:10E24000962E46FAF21995D5A33E20F51AF93CA967
+:10E2500080C3E54C9FD64CC48B653B3767A25C39C5
+:10E260009BC0EB553BAF7F03F994F7F118AEB75B5A
+:10E2700019E9C90B7D5CEF66B540AF0342F30F2C83
+:10E2800088A7F1966D2934C843D04BE8F9592B2B58
+:10E29000C3750C6EEACA47FDEB436B60319EEB879A
+:10E2A000A0D7A27DFB17C1C73E6C55A7E2731F1014
+:10E2B00012EA231FB6FE2A61A833A4C72514B507A6
+:10E2C00090CF2D7F2EA940E52845F8754BB75FC448
+:10E2D0003975600AE9632EC4D3157B0F4E65BC0EF9
+:10E2E00082303A3C6F147A5877FDB967C8AEBB7973
+:10E2F00037D7276E6E7FE6D57418E7963D429F109C
+:10E300007ACA7241CFB73CC7E1B2FCB963F685E186
+:10E31000F6486EF2DA81A0094E78F6F2D9F7BBD151
+:10E32000DE56C8AF52A965CE691C8AA5F4977491D0
+:10E330007EB83EB783ECF2E5CD62BCDC8EB5D9B4D5
+:10E34000DF997DC3F5A1890536EA27FB033CA8DFE9
+:10E3500097B1892390FF0596C7B5A05CD76F715A16
+:10E36000B16C5AEE2439FF709D25D70AF0D5953847
+:10E370000DF5B87A076F7F675CE20E2CF7C5F1FAEE
+:10E3800097B19924A7BEB4789E5902EDEE540FC5FB
+:10E39000A2FF6300EB3A60817A493FEF7505306F69
+:10E3A0002A03EA51517E04147CFFD96F3E2AC475BA
+:10E3B0004C181C3CCF6069B6C6BC3993014F6A0A41
+:10E3C000C43EF3828588EFFD5EE6FC7A9B8DB5A0A6
+:10E3D000BC63560F9B05CF03C8BFF0FCFF66F1235B
+:10E3E0003FDEA7041E0BD7BFEE1378EB8971B6286A
+:10E3F000B0CEC7B3BC4B711D3F526CC35175616E3B
+:10E400003507C7FFCCC6DF4B3DB65430E10C618FFA
+:10E41000D9D3D39CB8BF26012F45D7593DAC6375DE
+:10E42000DECB0B115FEEEE72B01898BFB42B8EF4FA
+:10E43000DA8CF432926F4D022E8A3B05650E7B39E1
+:10E44000CFE28B81F5DECD1C7E6CCF1C26FDD71272
+:10E45000AB633F65DF6FFF86FC7EA0FAF9813ED09B
+:10E460007EE09D8AD6046D6ACE9DDEF60E43FBD912
+:10E470009F8FF0BBB39FB7B100F6D779AEEC98177A
+:10E48000CEFB6E57BB43CBE3E385EF63DFCABF250B
+:10E49000265B42EBFBACEBF42F9F2FC2D24172A85C
+:10E4A000749FCAFD4DA6F57C96E6B6D23975390241
+:10E4B000166CEFB4F81505DB1FF800D757EA7006A5
+:10E4C00054D4E31DB63F85CB19762823E9F41524EF
+:10E4D0005AD837A02CF46FE2E737A18FD1BEDC59B0
+:10E4E000C0EDA49DE29C247C25DC985B67E172E68C
+:10E4F00025E7CE6AEEC7E274FC4FE2F9B9BF669336
+:10E500007E716E1FE81911F44E591E463D03F487C3
+:10E510002FB3F5A7106E52CE564AA92BE4B02AC6E7
+:10E52000AD14F0AA745A387C2A4CF0117863C60BEB
+:10E53000F3B9CBF3643F3974B04F169DE3F07F61BC
+:10E54000747E7B111F3BFFF6E61A203796AEEAC7B2
+:10E55000BC59FF13CF2F103B0CF58AFB2DA457A0FD
+:10E56000DE877AA2E41F5EE40323E939D703731937
+:10E57000F18D1A358EFC8C66BE21F985370ECA11D5
+:10E58000C8375A891FDCA9761DB428213E31B82C22
+:10E59000381CE5702798FEF83E6869A7E7DF146429
+:10E5A000137F18C40E0D203FAB35588C7AA0EA7843
+:10E5B0006CDB4910296DEB387D34D9FC0F2E41FE00
+:10E5C00050E9D450AFFBCC6FF1D9609D6D499C6F81
+:10E5D000B42D4B2779FE19137C64B69DF8C89516A7
+:10E5E0008B8FECAD39E9646F75B7CF71937FF5D739
+:10E5F0005FAB976DC1F7331D2477DB501E43BD6DB4
+:10E60000E3707AFFA2E44BCB385F6A9BA90F88C303
+:10E61000F733FB5B70BEDD29DEBFE1B9A7ABFE9F20
+:10E62000C7A23E79531C7B029EB765E90350DE3ECC
+:10E63000A078E62CC6FEC3F9BA8373E29EDAC98FCE
+:10E640002780FEA4CEFA841DE17E6FE9471FEC3BD4
+:10E65000F620C2CB57CA72519FEF44FC1C193A2FC7
+:10E66000B0CA597D72E8DC524CE726F1D56783F3D6
+:10E670004BE1E7B75A897E7E29E2FC947AC06FE2CB
+:10E68000FFFC7CEE54397F672F696E2CD5FEDED4FB
+:10E6900042585FD3AD702E2410837720BCB6AD4CAA
+:10E6A000D0711F9D1656DB1E816EB30B85DF09A549
+:10E6B00031D0C33C410FF324DEAE32E16D7050D255
+:10E6C000E97881B7D0FFC578CF509CF753E5F028A3
+:10E6D0007CF8E67FABB323CD33BC90FB0BF68356BF
+:10E6E0005A48F2B5D4A0AFBE99FF5106CA29F6D553
+:10E6F000814128775F49F18C2C04FE113BB48BFCDF
+:10E70000E69D03BA6CB8CFCE391F67A05E34AFFE6A
+:10E71000B7445F17BBCED5F135361C27A922CB16DF
+:10E720008432B522EB20E2CF91E931EE98087AC825
+:10E73000FEE9C33250FFEDA81C96817CAF030EF0BA
+:10E7400010AECFEA4E40FEC7F654131FAB147CAC9C
+:10E75000A362087F2EF866D8F38D45A8D73A2D5AC4
+:10E76000B8BE602ECF02DF0C00DFFC08EC332C4F6C
+:10E77000817D1600FDF504D867583F06F6199647C7
+:10E78000C13EC3B2A341A3F74D1543F604E19CBFBC
+:10E790006851687CF4DF46D28B6F7C5C6501091F91
+:10E7A000F8AFF6E17816C80DD597B4F535D4176DE6
+:10E7B0001868A82F681E62A84B3DD2BBEA0AC3B8EE
+:10E7C000E565858676ABE347D8F05C93CAF239DC21
+:10E7D000CBF209EE1DD74481FB35A309EE87A78F45
+:10E7E000CE40781E46B8A3FD66D512F01C24DC6727
+:10E7F00089390F9715F2E702EEA1E7E5BDCAA94FE7
+:10E8000010DE31087707951F21BC09EE1CDE2710AA
+:10E81000DE3108F75C2A8F22BC87E1B800EFA20B3B
+:10E82000C3FBE6DDAA010E373E6E8477EDC37D4D56
+:10E83000F01F6880E3A20D430C7509EF05CD467803
+:10E840007B57159ADA31B601E0508EBF001D1C2EA1
+:10E850009E467129AB83F9E281AF2421BDC1FAAD97
+:10E86000150AD78FE0A715E87016FE02F46575F259
+:10E87000F7CD73143FF225D489D0AE00B806E281FB
+:10E88000CECA5D979D42BE743D723015ED7A3F95BC
+:10E8900037B000D167350B527D1EEBCAB443798B7C
+:10E8A0001A588BFEBBB71CDE27919EFF32FDDD4E52
+:10E8B0000589529B3F0CE99C3993C9DE8C764EC08A
+:10E8C00029257F62CE51625FF05381FC1FFA75C427
+:10E8D0008FB8E30E3887CFE60747E1FC373BBC8FA4
+:10E8E000A65868BE3D38DFA736EFB0BEF0FCADE2FB
+:10E8F000D11948FFCCD3CF6027459B6F136E16E02C
+:10E9000030BF0CE0A4601C8EC3E5642587CBFE4DB0
+:10E910003176F4679C5C67237FE5E6F8CC4CC4DB7A
+:10E92000936BA66522DE356E1A9689F83EAB65DAE2
+:10E9300059E4DF53D41935144F6DE578CFD8ADA421
+:10E9400077DD21CEEEB89B6901785F393D41F3C197
+:10E950007EBCBEAC445A2FD39DF9D06EA1D8F7C26D
+:10E96000D6A533703CB9FF051B620CE7FFA3126309
+:10E97000BD92D943789685E76C0FBDC7F357ABFAC4
+:10E98000787BB1A3EBFFB0FD8D57C2C63B5E98907C
+:10E99000827A0B1BCD467FA386FA4783EB970DFE49
+:10E9A000375EC909C155E2D36F0A3D9FE0F9C063E4
+:10E9B0008AB7012D913CB8A5DBAFB52F11E1B7297E
+:10E9C000FEA57BAE44B8BCC7FD1C9BE36B887F7C77
+:10E9D000827C3B0BF9F4F519C130BE20FB07053FE3
+:10E9E0003DF2CBEB898F1CA84CA5784CC773DCBFDC
+:10E9F0007C54D07D47C5F5D57700FFECD8AD929E0D
+:10EA0000D7B1E7FC41F4D374B42B9A00B9257CDC70
+:10EA10008E3DC0CF91DF7A6CF47EFFEE5FD13ABFBE
+:10EA20002F7E5EB157F0F32D7CFEC5560FF117E631
+:10EA30009D6DD8DFDF8BAF5F889F1FB1713CED38D4
+:10EA4000A292BF8DF9F443B9FDC3F0B38CE36763C1
+:10EA5000650CE3F295F39959154007A8E733773130
+:10EA6000DA949FEC29EF47F27283ED38EAD32EF85F
+:10EA70008772DB0CC74A663D1E0CC3DF9B9F83F683
+:10EA800061EB9B85EFC3F0D98CAF2545467CFD82B9
+:10EA90007D9569CFE6EF0FF50FF13DFC09E72F9269
+:10EAA0006F49FC05BE55837C0DF8CA554580B73FBC
+:10EAB0002EC8FA4D5009E32B17C9C736C57F4D72D2
+:10EAC0007073FCD784C7872B051E839E81CF3BAE16
+:10EAD000E1FA06F3CF267A9827F5089B2701FDA4D3
+:10EAE0004756F54DC4F7C79ACB89EE243D99E73BCD
+:10EAF0002AF04FB69B67EDB26911E4A17795117FBB
+:10EB0000D8AED984EF7798F02CDAF8E6F6729E79D1
+:10EB1000A678AF799EDB8A84DED95E7D51F3211918
+:10EB200076F727FD362E84972AF2812F1382A47F51
+:10EB3000CD36E86547CB46935E76B8E27C44FDEC83
+:10EB400068C5F9B74623BD95D904BDD752FF72F108
+:10EB5000DEBC8E8F84DE704AF08F1382AEE57B754B
+:10EB6000FB9AFE7311EF57A91AF2AB23330A09CFB0
+:10EB7000CFF82B69FEA3152AF99BEE2F9A3217FDC9
+:10EB80004D723D72BEF26BCE27A03FED0B8017FA9F
+:10EB9000C7CA6D5ABF48FA85191ED1C695F803FA3F
+:10EBA000EC11DCE761E4A3F8D66B84D361EC0FEFE2
+:10EBB000676D5729DE6686D381E9C3882F1DDD2561
+:10EBC000F827C015F5F0DA878DE7BAA42DDEC46FFB
+:10EBD000FA1ADECFAAE47A99E4D7727D87570DE955
+:10EBE000179E3775A1F396E35C2CBEDC28FAA3D8F8
+:10EBF000FC86E46FB2613CB0144DF3659BDE5F6E42
+:10EC00007A5F60AC5F241E1F13F823E5CFB158ADC7
+:10EC10003A521CEFE8D531B5E1F9099D45DC7FD3C7
+:10EC20005924E2DE9728B7FFA328B2DC8ED65FF224
+:10EC3000BDA70B3D41E4772C504EF1EC8BE57361A1
+:10EC400072FE4C11D27950B1637FA957DD58C6E5E9
+:10EC5000C2E6F8A7284FE3D346AE17ED6F8C213CF0
+:10EC6000FCF335FCFD9FFFED23D2A70EECDD9C18D5
+:10EC70002EE7255E9EDD332D11FDC2272B1E4B0C8A
+:10EC8000B703E4FB8F2B1EBB672CD1B7AAF5762EFA
+:10EC9000DFD61EE8A810F680D0176EB2B6FF3FB1DF
+:10ECA00007CC76C014F5E144E47F667BE0AC5B4FB3
+:10ECB00074117C04DD09B972A380CF9F6D7A22C5DF
+:10ECC000E9761572B962C24F0987D3120E1BCA7B4F
+:10ECD000C59B53422EC8FA622B2378781D8CF465AD
+:10ECE000D6A66818FFC234951238974315F98FA13C
+:10ECF000FF4AB67FA65825FC96F31CD9A6B4A37F7D
+:10ED0000E5B7CDE5D57760BEC38C78E2ABB2FD1236
+:10ED10005FEFF2EBC8C6A46B711EEF1655C3475EDA
+:10ED2000DFB17EE1EB977A9AB9DF326BEB45D9D14F
+:10ED30005EDFF644B46F83629DC1FDB1767742CF4A
+:10ED40007E18AFC1FD2F9BA16A8DB0FE651BF8BA7E
+:10ED50002A7DAA960DF5DFB63E762DD2C1897A9B23
+:10ED600085DB072E039EBFD95AF836B63F59C6E554
+:10ED7000CAB18AAB12310FCEB7C5A6E5B87BCE5764
+:10ED800053CCF3D2CEEE89B1A0FFF46CBD8D05C893
+:10ED90007FE1217BF9C88621549E45F871FB9ACE0C
+:10EDA000FFC662EEE73AD1BAB03FA72737AD43E2DC
+:10EDB000CBB15D6A993F02BFBA519CDBA9AF9E26D9
+:10EDC0007C7B755739C9E313157C9E53ABB44484DF
+:10EDD000E7EF36A844C7277D7CFCFD7BEF4A1C0B80
+:10EDE000FB385BC1F77576CF9D6F8F817D062BA4B5
+:10EDF0003CE6724AE6F704370CA178EFA7CDDCFEBB
+:10EE000096F42EE3E157AD3C9248FDA59CDB3DDB3B
+:10EE1000B0FE8E5D27C80E3BBB0166E372CE998FB4
+:10EE2000F986BC3B5B32C378BEB32AE20DF5792D7F
+:10EE30004679D6B897F32BB39EBB7803E8C1E89721
+:10EE400032D9790B1B0B134B907E510FC63C932785
+:10EE5000CA0FA6E23EDAABA95D85889B2D6C8B318B
+:10EE6000F083CA66A35DB7C064C7F5B0EB4CF24847
+:10EE7000C2697914F924F5B90E61AF1CB579AA23DA
+:10EE8000E553B41773F9330FE8370DE3444CAFBCC7
+:10EE900052C07B3DC2C7DEF5450EE8D31DAA361E23
+:10EEA000F5EA1E7460D203CBCB8CF0659A8F95483F
+:10EEB0007F849BF4FBD3A8FFB7F41572DB0772289D
+:10EEC00001E592FE6C31CA958BF51F5CB47E5E2322
+:10EED000F4F31A837EDE814DC2FAEFAFBC9EFC5480
+:10EEE00047AEB99EF4F523DD7E2A8FC14F25F5BAD2
+:10EEF0002333CA0DFA67D8F33EBDE58B47D3378F6E
+:10EF0000213F263ECDE5D25A6147360B3BF2C80C75
+:10EF10006147A630A223AB556791F8D9A5EA6F0BDC
+:10EF20009A8D72C9BBCA683F3E3FC97B16CF252662
+:10EF3000ED72C3739BABC0E83F34E1E740C6FDE729
+:10EF400077A12F00E0DE54C9F34EF139E6BF48B98E
+:10EF5000C4A03DF28BCA0D97FBD7F3F73EB500D3A3
+:10EF6000E518AA74D4DECAEBBAC2EB3EA778AF8A22
+:10EF7000BC371BD48F6569B351EFC2BC9EF864FEE9
+:10EF80001E516420E075627248FEA15F3F9687D6ED
+:10EF90007D89D06F5045D62B48D798EF735901DA49
+:10EFA0008C3C2F2C0D5DFA05347E00F37A824D13D4
+:10EFB000C9DF5CEE48E4F179B0A37BC7BF46AED7AA
+:10EFC00095F5A5C90659F97AA2E2B36877217C0EB6
+:10EFD000D3C3068C223F9A85FC2D9BE247D8107F35
+:10EFE00067393D190807C07792AF1DBFB1131FDE07
+:10EFF0005FC9FDB01DD3476FBB1D9E8F78DA49BE38
+:10F00000F48EC5D20FDE95108EB747579DB0205FA6
+:10F01000FEFD1EA6611EE3D1DD5507DF80710EAC3B
+:10F020005AB8B118E9E84D95EC06B3FF76D2D3E3B0
+:10F03000C8FEBAEE1A95F2BB0F97A90CE5DAE10DFE
+:10F0400071063B24E4D755093FBED867A5F768EAA7
+:10F05000E462FE15FA37314FAB8C9FCB0B829FB524
+:10F060008B73FCB9D063760ABA69137473AFA09B33
+:10F070007566FFEEC39C6E0EEF01C301E4FA3B33ED
+:10F08000169692DF7A0BA33874D674757D11ECEF67
+:10F090008A18CD86F09B34239FC3B342B160FCA68F
+:10F0A000BC2CDF86F47E455FB70DF96879D94CAA90
+:10F0B0004FAEC8223B7FFF2A908F68EF2768194820
+:10F0C000974367C4042C89683716129FB8F28CC521
+:10F0D000402FF9813803DD5DFE78B2E1FDB02DE906
+:10F0E000867A3F4FB6A17DDF32233DC60D2D30F22B
+:10F0F0005DC6F54209E729EA38F2731D0DC9517A58
+:10F100002FF511E9AF93ED015A06BED622E4C808E7
+:10F11000A8633EDDBA8A2607E64D7CD16ED5F8F8A5
+:10F1200055A41F38B29E73209D606815F3AB5AA496
+:10F13000FE29FCF74C67A6756D6018673D5AC60836
+:10F140009F62873205F5AF3671DEF7897981AF4E60
+:10F15000B2919F8E9F63DF191E6AC73C46FB200D4C
+:10F16000E9AC00F184F7FFB9E8BF53E0CBD1B2C7F7
+:10F1700056C7213ECC66A46F4C516F5E8DF1C4A37F
+:10F180003318D1497BE0E5385C3F8E83F9812F4409
+:10F190001BA7E2571FDE82EBD965A771CA1F671351
+:10F1A000104F2EFFD1B18FDF46F06D711D88653D88
+:10F1B000E5F088C7750D81937B86056C540674E471
+:10F1C0003FB9670EE9180FBCFCCFBB3E7E8AE1BC9D
+:10F1D0005C2EB408FC36F3D75F3CF1EB05289F7F2B
+:10F1E000B1736BC10750FE60F583E9F550FE7CF505
+:10F1F0004D5B6F7787FCA53BAF5DBAA30DEAC37E7D
+:10F20000F8D3279F43BCBAF6A7FFE7395CEFB57F79
+:10F21000FBA313D67F59530243FA96EB33CF93C621
+:10F220005A148C8B221F25BE6CF5517DBECF68FF12
+:10F2300098E53EB6B702FCCAEB7F41F1E534D1FF59
+:10F24000F03577292ACCFBC17CCE573A1ABADA2698
+:10F25000DBA87D00DB039FA47CCD818380AD607F34
+:10F26000BB4FC1B83828481AC67B07C07BE4E7CC3F
+:10F27000ED26FD2A53E2AFE02B78CD81913FD04AB5
+:10F2800078962BE291C87F91DFBF312A9BF8F2403C
+:10F2900027D3F17CCB5EDCA0609EDAFB5EB7467ABA
+:10F2A0004103BB7F32D8C997AB3CEF22B7ECFDB925
+:10F2B000782EB055ABB72034EE2EA1D795BDE8A47B
+:10F2C000BCEDF77739B7939E7FE85A4BB87E58FA72
+:10F2D0008B3F3DFB3BC4AFF9B1845F66BDA543D016
+:10F2E0004777DDE6DE763BC0C7F71B07B7AB747721
+:10F2F00006D9E99A3B03F377BADBFD54C6D3B43F92
+:10F30000223F9F55154F7106195752CB3E5F83F42C
+:10F3100038AFA4AE18F5F7743C87BEA138F607CB1A
+:10F32000EC946FE053E2282F3D5ABCFABF843C6452
+:10F33000AC6E24AD83D58DC6F2FCECA66D767774E9
+:10F3400079D52CCE35DA7B9B9D7923C595FF6B143F
+:10F35000F72336E139D8C2CEC1F9FBB9181F8E7632
+:10F360000ECCEA2FA03C4B876328E681A48AC79B7A
+:10F37000E37FF616CAABCE235C5EA5D67FD980F4B8
+:10F3800027FD163569AC3B6EA6433F9BE8972AE202
+:10F390002C48C3A87FD78878516735A378516AFD78
+:10F3A00047FF8DF0D924C6AF798F8F6FB706F6234C
+:10F3B000BED438DD24773AFB256A78AF897DC5F362
+:10F3C00053D219C747393E13E3E3CA59D8BA53E3B6
+:10F3D000AADEA1EB101358201EF14771D0BCE9AB97
+:10F3E0006228AF55EA57A9F577DDAA8E308CA7A021
+:10F3F0005EFD7E15B7B7D1ECEC1E37CBA057919EC2
+:10F40000655E87ECD769637BD0FE0DD3B3480F638D
+:10F41000E1F30C31D4851FCD58B7A5D90D7CE2FDA1
+:10F42000AFCAFBD47139E04E19C5FD77080FA98F1B
+:10F4300049BDADC7B882DEC3F44B1FF20B9947D16B
+:10F44000AD27D586D94DD93DFBC97C35790E129EA5
+:10F45000D1FA3F3F499F329AF4AC008DE315C3586F
+:10F46000E29D99045F13BF04B6C5F3E9851E0A5AED
+:10F47000A4218F41EA95923F770ABE1BCC0A92DF06
+:10F4800050E6890F823E99D0FF86D149DD79F6A8F2
+:10F49000071D6DF88CE2EF35A887C2FCC1D59F1817
+:10F4A000EEA114954EBA81D66BCA97088BBBD27A5F
+:10F4B000BD826F4E519D94B7D2C9E234E45F9D3E48
+:10F4C000A18FFD219EF431C92FCCFCE11ACDC8FFDC
+:10F4D0007F5462E4FF33F5BE26BBD018A7AAF49888
+:10F4E000E2E1EF4D37F04DC97FEE44379F8AEE25BC
+:10F4F0000FC575DE14FCF26DA107DA591D3D77309A
+:10F500007E7F348EB553E96487A84C645D54BA9805
+:10F510008BF26B929946650AF350D99FD55199C6E3
+:10F52000783E553A6BA772103B446526EBA2D2CDCC
+:10F530005C162CB39946E550E6A1D2C35C14277F34
+:10F540002F21987118E037E37A26EEFD1EBA418725
+:10F5500073EAAC64A17BC04857539840BEB7F9FB2F
+:10F56000E9B2FECE0D3ABE9FC4DB6F7DFEBD87F0D3
+:10F570005E30F01BF1BE83BFEFAEBF7BC324EC6FE8
+:10F58000B3507DA7687FAA487F08CFFFE9D18CCE12
+:10F59000BBAC48DF36BA38543F53A83F1A5EEF3F42
+:10F5A0004ADF1E5E1F5DA83F16DE7F49A1FE44F8BC
+:10F5B000FB7DC5FABFF2BA8BF0F23D9B4EFA2EFCF2
+:10F5C000EC5246717CC39F3EAAF769C2C3DD8A151F
+:10F5D000CF3546D09B1DCF51453AD21C31587A7851
+:10F5E000DE4F30D6198CB7F462FF98E82888FC0902
+:10F5F000F070B8E2DD47F398F889E213F98329C681
+:10F60000B809E03BF95583ABB89DCE58E4F772DEFC
+:10F610000BE139D3C3FCBCD9A171A3EDC38CBF8767
+:10F62000849ED721F4BCF7441CB97BDF416BD269BF
+:10F6300047888EA3DB8756763A9C5FF6D8F79FAA59
+:10F640006D40D7C1FA1817CABBCE58F636DA69BE74
+:10F65000232A433DE352D7DB5638F50CE78B835C16
+:10F66000C867BAE7157CA6137F053DE78A3ED2BE80
+:10F67000D41C1CDEDCEE4812EB6A9A9C7C752EF9D9
+:10F68000F3B95E9F673B34731AAC337503F7AB264F
+:10F69000227D63E8ECE93FB8308ED63AC5C2904F80
+:10F6A000AD917E5E933F6ED3E415AE707FF09A44C9
+:10F6B000BF82F1CBF4402CF743A4307F2CCAD13267
+:10F6C000AD8CF2667CAAAB0CEB55ECDA5CA82F682B
+:10F6D00053DD6530EF81B65FAD403FE0A22A3BC508
+:10F6E000316CFAD4B3DCFFC7F33792059E37AF8B8A
+:10F6F000D10208C77E4EF2DBE6AD2928437BB7C9AD
+:10F70000999C8CB8985CB584FC864D4EED35BCDF79
+:10F71000E17359283F91B9744739E82BDB6FB796ED
+:10F72000211FCF78A628510D5BF789E673B1180722
+:10F7300079D465A1F78FAE2A752C71E23D46B017DA
+:10F74000A03CE03AAEA3FEBE15DAA0BFF19EDAE31C
+:10F75000AD97F5728E89657603DEC66BC67A8CC965
+:10F76000DF6833E905C34A1252E89C47B15178CEAD
+:10F77000239FFC8AECDF794E37F9D54B5B14CA8F97
+:10F7800009EED73251DF3CB17118E5BB34B718FD33
+:10F79000D1C10C9689F77DE6B72AA4AFAACD9F37D1
+:10F7A00062BFC1B9EE0138CE60AD6B802B8CFE1EFE
+:10F7B000FDE98F6351DE35E38535C223C6E342C2DE
+:10F7C0005E95F7CAE7BBCE55A3DEBFA8F55D0FC2B5
+:10F7D0003F49B710CD1CB5F9D3F0FCD74F9A45740B
+:10F7E00089F7B4508FE9A18FFE15D619763F614D88
+:10F7F0004A761CCE1BC25F3D11F77BB2B590F4A3D5
+:10F800001D2DA5741FC03CCEDD0DAC1DF5D6350DEC
+:10F810008EF648FAEFDD999E4CBCBF7D6AD3A4B545
+:10F820000CCEFFD4FE656978DF7D716B0C8B75F7AC
+:10F830006C7F72D3689A6F31DEA3C6795B67DA5149
+:10F840006E4C6B9B6447B8DDDD30FB99F0791E2A66
+:10F85000F5569700FDC5B73E4378E264011FC2F537
+:10F86000DFC7EB99A85F9CCC6111F33997962844C8
+:10F87000B7BF1BEFA1FB29A73222B7BBA984EBE7D7
+:10F88000C11237BFB76E656F2F4D217BD085F47ADB
+:10F89000A2A590E277368CBB0FC1EF567CD580F8DD
+:10F8A0007FBE6AE1074BE1FD9AE9D79DC172A4BD15
+:10F8B0008EF466F67B95E801F442BA27F69F150EA2
+:10F8C0005753581E21EA8FBAC1AFE161687FD85AF9
+:10F8D000D4801DF8BB6DDF69D2C3115FF530FCA584
+:10F8E0009F51429F17F92169A3E8DE1DFDACB9FACB
+:10F8F0003A7F00CAE32D0B1D91CE31FAFC61E3A2E1
+:10F900007E3B99E9B161F383540C905FDBCBE7EB6D
+:10F910006E27DE8319AAD3FA845E6E7EDF4D6F5B9D
+:10F920008CF4B94D9C8FD4CFA3ADF7077E63BF177E
+:10F930003038818644FBB5067AB95C6D5F817115FC
+:10F94000F63EE7FF60D7314F84385788CFC2DAFBE5
+:10F950000BF8013CD7A6CC22FB24DA3AECFE437A22
+:10F96000D68890FDF68334E3BA64BB17C4BE62FC4C
+:10F970002C604BC43240F73962A03FCAEF2FAA6E09
+:10F98000735D1D812E6469E65BF8E30E8BFF98F9C9
+:10F9900004A2C150A98F58787F3D8CCF25DCCFF5CC
+:10F9A000DF935B14D27FD76FE279145FF8A14ECA60
+:10F9B000053F27542DBE11CA8E33ECDEE192175B52
+:10F9C000EEB9DC6D80DBA2F0EF999C79F2276FE352
+:10F9D000FB8F9EFA8907977B57CAA244CEB78E2D1C
+:10F9E000C0794E5D61277F0CFE38247E40C3A5FEA2
+:10F9F00018031EAEDFFBE496052877F63A344CC7B1
+:10FA00005BBCC5F83E262D6C5F8CE397CF00A760EA
+:10FA1000F64CA0A3A33FFD57BA1F1E87FC13E97144
+:10FA2000550CDD0B33C3795C49F77746086F1784B3
+:10FA3000E250741F44D2D5F10D4DA7541867ED2A3A
+:10FA4000BB9BBEA760B2BF8EBA67EA6961F161FB7A
+:10FA50002A7E4F9385DB89D9A1FDCB718FFA163AA7
+:10FA6000DCCE9EE3F5C0BB28E3F529D5BF46BE98A2
+:10FA700056EA6163281EBD90F65DBF67D5D137A0F9
+:10FA8000CD3D715EEB987EB8FE21A314BC2F63754B
+:10FA9000D3BDC1E6664B2CF2FDD6766BEC50847775
+:10FAA000B385E47C6B7B4ADC50944B4E0BC54F51C5
+:10FAB000AEA861FEFDD16338BC42F2C39318AEFF1D
+:10FAC000C4097C3C952BF49FC95CFF519EDE477AAC
+:10FAD00047F31A1EA792FA864BE08FAB99C721A372
+:10FAE000E93FC87870DD09C58B5CC8D7D624F2EF32
+:10FAF0006F2C9AACF9F03EE7554E467263305EAA21
+:10FB0000403DCBC9FCD3601ED5C5F51B6F2B237DB3
+:10FB100026D9E9D410D4A96D7E1FAD5BE774E680C9
+:10FB20007F08CFB85C9DE1F856935E6137E90DAA76
+:10FB3000A9AE8D11792B428F6042FF96F1E0848D42
+:10FB4000BDE70149BF6EABF04F80FEE4A37B2325E8
+:10FB5000CC8F78CB74DD9DD23F6407A489EF1EA5BE
+:10FB600095B0ED4D61F127457F95FC06D22F29FD1B
+:10FB70000FD2CF31A204ECB5C4307FC44B605AAA77
+:10FB8000140F9B8E789205EC80ECC93CA6F0EB1923
+:10FB9000DF524FAFBFB8B8CF432FF3FB41CD9638FC
+:10FBA0006D4756CF76378DE3F8167700F6867AEDF7
+:10FBB000F50EBA873345DD4DF7EE371759785E33CA
+:10FBC0003BE4427D60E118CE77B34A3D0BC6503C22
+:10FBD000D593857803F0F0D9F0FE9EF0DB66DC91DA
+:10FBE0001D87FAF007034E6F42BDDCB7C642FC46E4
+:10FBF000C231ABD1722FA261587C2E602D08C5D9BD
+:10FC0000D67BCEF9F0BEF0B5E3B8DF356EE6C9FDC0
+:10FC1000E8075D37D4427EF6BB12748ADB01FD38FB
+:10FC2000541EAF7B0DE36D2DEEE464FCEECE534924
+:10FC3000FCBDFC7ED50309FDB787E797948EE3FAF8
+:10FC4000C8034A647DA5EF3885E759ED0540F621E4
+:10FC5000BF16B7C77D5F54E9CEB03AD21EF4FF1786
+:10FC60001FB7A75BF67E51E51B4A7692789F534DEE
+:10FC7000F63AFA18E1FD89BD2F55F9A0FE4856E481
+:10FC8000797F2BE67DE475EF60D467837B017FFA93
+:10FC9000443ADF00B394D0B89918970AAE8C991DF6
+:10FCA000E93B3683C6F37D6E8677317D427AECE69A
+:10FCB0002AB39EEA277E75BEF6F8414AD306FE5166
+:10FCC0000CF490C422F3CB0BEBAB5A1AEA9D4D2BEC
+:10FCD00095B5C83F9A405FC5B860AACB4EFA6A7323
+:10FCE000D28F27E1B99CAF652EBCEFBA03D43EE4B6
+:10FCF0005FE857C57BACD3EA399FF1BAB89F15ECE2
+:10FD000038CF55888F03AC848F527FB55671FE7300
+:10FD1000450CCF47EE4C7292DF34A99EE71FC7FB1C
+:10FD2000409FC5FD4DE6F9C33AFC433E24F55B67B1
+:10FD30009ED590476C37E5195B4D79C5FBC718ED2B
+:10FD40009984E2A25EF5AA97C0FEC575EE03FE8314
+:10FD50006500EC602C5F06BB1DCB57C06EC7B8C1F9
+:10FD6000AB0DB954BED6A0D1F3371A4AA89C981946
+:10FD7000A4B822F991C97FC3020AF9F1247E7D3A21
+:10FD8000A814EA4F4DE2EFFFF3853B1FF50D82F714
+:10FD900029A2BDEFEA6AC4D7EE3AABAFC6F6356921
+:10FDA000BC5E3DF6C7D5E8FFE99AA27F88F2AD9F19
+:10FDB000C5337F0DB6FD498C16C9BEAF1D2BE47946
+:10FDC00014FB9DE127128CFE9CB3637AF1E73CA003
+:10FDD000F075F4DDF7D2C348177D665A3D88C799A0
+:10FDE000D9463FFFD563395D3C3896F39FCC3780C9
+:10FDF0003E7A81BBA48F68EF9BF6020A44A02B5980
+:10FE00006E4E6013E87E76B57D76A43CA7F3827FC4
+:10FE1000441DDFC9DC312343F4D6E434D35B90E2E4
+:10FE2000BBE7EB6FDB8FF2F2BBD31B23FB3058AD8C
+:10FE300093BC0E02BD213F576B39BDA9567E3FB31F
+:10FE4000E64DEE1FD981F485F970486FF0EB341F51
+:10FE5000AFA79AE8ADC94C6F4E23BD0591DE60BCDB
+:10FE6000241FD72FE2ABDABF577A1B39F6BBD1DBA1
+:10FE7000BF8F0F525E436756DD0084CF66F13DBCF5
+:10FE80004BA5C337C7DAB93C18AE935FA0597CFFC6
+:10FE90001058CC06FCCECAB4418DD66480DF8C9459
+:10FEA0007CFA0EC16D63FB0B3A39E4447F4DE224CA
+:10FEB0007DDA58A4AFEBCED0FDC67E164EBFB5633B
+:10FEC000BBAA90FE32D674CC9C8674B75225396991
+:10FED000DED78B1338DD35297C5E38B901E171BD81
+:10FEE000B963393EBA5736290ED4C7E7332D278B6D
+:10FEF000BE2B43DFBBF997E6FF74E1B82F4EE0DF7E
+:10FF0000737137BE97E4E5FEB534B4DFE84A734158
+:10FF10004F7A849F765B7F033D2FC47D44A3E70B1C
+:10FF2000F18FE01845C085511EB057DCDF94719108
+:10FF3000A8F46CF2E346F51F0E8FFC5DCAC9E3F925
+:10FF4000BC4DC2FF6BD6F7E4FE0F4FF2FE6C2C8C5B
+:10FF5000A3385FE57EE07DCC8DEB9471B3EE3C235E
+:10FF6000A91FFA98BF09F56D2BA832FDB9BA81E334
+:10FF700075E71F093D7159A9771D8EBB9DB9F7A380
+:10FF80007C736A3C5FE1F949FA7A82E7B7D4034BA4
+:10FF90004AF57B71DC6878B56C9AFE406FEFD957F3
+:10FFA00030CAA8505C6BD24C2BE70BF58AE003CE2D
+:10FFB000B576A86F4E027EE646BD9DEFDB057CC39D
+:10FFC0004D7686D18E988ACE48E41BC84708B8FA89
+:10FFD0000CCCAB4C14E387E475F020EAA54180ED2E
+:10FFE000BDF02AD1C7E575D39B9CAFD881AF505CDB
+:10FFF000BA84DB09F25E507C9E46F697AAF76E3F04
+:020000023000CC
+:10000000584DF6FD9EB1C27E28604508B74C8BFB6B
+:10001000BE31F0BCF0C12987C7C0E3E26D8BFBA203
+:10002000381DBD7D4D397EEF6BD913A7B6A39F74E4
+:10003000CC7FC430F15D35CA33F83BCA193A97F327
+:10004000FB58B5CF8AFC2A321EAF19CFE59F8CB37F
+:10005000F682C7EF131E8B38E725E0B1F302787CF8
+:100060001CF135021E9FF88E78FC09F6BF170F01B0
+:10007000D61D3B4DFFB437BC9D3A55FFBC377E1AA9
+:10008000163FE0F943AC96EC6719BFEC015794AF0B
+:1000900039BDF8A5D6ED88457BB6A976C7EBF8DD66
+:1000A000C7A67A6E677726688E12B46FDE55E97B35
+:1000B00056D1FAA3DDED0366B96A3CCF8F3EB0326C
+:1000C000263011C6497772799BEED419E68B5B5DB9
+:1000D000419B3701F5350F43BDCD9E6261BE307F38
+:1000E000CC48DB2192CB9D20C7913E803E39BD2577
+:1000F000F171A47C9EB8F23E8CE4B0F15DC0FBC20D
+:10010000E8E4F5BD25E4874B287E6E05F653ABED9C
+:100110006EC4EF897F05B91936CF24D044C2EB579E
+:10012000390618C699E2CA32BC9F96F603C3FBABE8
+:10013000015FEC14C7E6F702A55E33DD9D6F68979B
+:1001400024E21C3FCC1D6318CFAA7E75EF68A47F04
+:10015000A1478C837FF45D5E93BE60D627CCFAC343
+:10016000E82B8DF75D4658451E9A95E7476C660E5D
+:10017000FA2E05F041FAEE414D284F80E864843DA7
+:10018000B8E36EF4ABCC71683E78D6BCF7EAB4F94C
+:100190004521FFD9E67AEEF76BDAE3D88EF4B05555
+:1001A000D0A5A4AFBC84E37318C9753B43796CA692
+:1001B0005799EF24FD05D29FA0D4723FC3D90959A6
+:1001C0003CEF48F09FCD55DCFE7D4809C42A4338FA
+:1001D0005DBA9343DFA74B638A6F3AA76F3D59948B
+:1001E000AAC8479579AF380EDAD9697C3EF61ACF9E
+:1001F0009B6CFC67ECEF62BE41C29F91911CF25375
+:10020000607EC2CDBC9F6FBAE83758E45BF6E1EB85
+:100210000F4C11F38D8052ADD3857FDA4B650CC640
+:10022000C3A1CC56B438F47F0C513D14684914F185
+:10023000F574114F8F57029C797C4B3E3212D828AF
+:10024000E625B064FE7D91D25F38994AF461DF8182
+:10025000F2E8AE63DA3BC5F0BC39E1C76F4D84E725
+:100260002DEFAA1AFA49EFCAF07D80746D0564F08B
+:10027000915FCB331FCF4DAD70B8A6413FD5B7BD11
+:1002800011E3BB23EDFEFD749EAB6388DE83D00FCC
+:10029000F1616B02D029E22B7ABA4685F281641CA7
+:1002A00023384673A01C0D623BEE6F36F83F23E403
+:1002B0009B90BFD42AEACDCE1DA4BFAF4DB1E317AA
+:1002C0005331BF27B31EF1B25F1CBF7FCB78DC6018
+:1002D00030FE12966F6F7745F66B82BE4670083619
+:1002E0002E4DEB4DEF8A1A47715A02F6C48B8FA33D
+:1002F000ACB9F13A7F206C9D72DF6B9D3B9405ECAD
+:1003000052E667C6384A2DD363474488A304FD0AE2
+:10031000AE73702D8FB30C16FEFA6F1B47A99CC0ED
+:10032000F5C74B8DA3C8FD5E237E9F01882DEE1976
+:10033000533C81CECB125A5F18FC1E277E44B82155
+:100340005004EA3F12F5B77677FCE949F8F5CD5D40
+:100350002FEFC652EA7133C5FB6B877DB90F73B7B8
+:1003600066AE5B21E258C6F8C33560D585FBF9F16E
+:100370007B01E1F599A6F5945A8D7182C94E63FB14
+:10038000A929C6F76583627A9C1BFAE569BF4ACF43
+:10039000FDDE157F0FE3DF9B0A3B07F5C27507E61D
+:1003A000CD61DCC7DD134FC2E3009EDF58597211E7
+:1003B000E28B85F4D2ADBEA5F75702FDAC0539CA74
+:1003C00079B1DB407FA1B847998EF824FDFDD1E8D3
+:1003D000E9B8339BFCFF83EBF7B74FEECBBAE300F2
+:1003E000F7C4791DE3F07B41CE730AEA2183EB5F0A
+:1003F000A1F7D7CD29EE158F72EA0FB44F0EFB8E01
+:10040000608ED56341FB39A7FE557A1E559FEFC913
+:1004100047286F2D47E085CC0BDC8A798100F79C5B
+:100420005AF17DE0B6DEF3DFA43C6C0ECBEFA364A3
+:1004300006B7C2C2C79772AF873F9D71BFAF9CAF6F
+:100440003B2FD0346FB7FC7371F9F7FC24AF36AE95
+:1004500038EC5E86B8C701FB8E98073A5AF8B37B32
+:10046000C963E37667C56B1FE0F8976C7746197729
+:10047000626630E23DA9A9C26FD5191BCC40BF41CD
+:100480006794BF9BF0D094A93F1CD78BBE8B79B3E8
+:1004900008CB68EBFCB679B37522DE24E3AD327F7E
+:1004A00056E6C55E287FF6BBFAE1570A7F40E93879
+:1004B00016310E615EEF6DC23F9E55EA598178118B
+:1004C0002DFE20DB7F30C01ED12F7E6442E4EF0E74
+:1004D000C8FC50586F4AB81D24FBC9BC7CF3786037
+:1004E00017AD1917E60FF436E690BF2FCCDE92F960
+:1004F000B0441F9B851FA29B0ECC7AA1888798F5DC
+:1005000042191F51AAB87F02E8A30DE745BD0BF3BE
+:10051000D2A59D27F34965DE28E685523CEA5BEAD1
+:1005200055DFBB3DD53885F2BA9A5CA5AF7D177B08
+:10053000EADF2718ED29AF93FB1DBC684F0DEF696B
+:100540004F15957A5F447899EDAAA33FFB84F26337
+:10055000C10EDD37EEFBE01326FFD4DC311CBFA556
+:100560009C96FEB4FD432D06BFEB5475D57ECA178D
+:10057000AFE5FE9674BD9DEC34BBD3EE467F8B7524
+:1005800032A7235B1EF3EB3CCE4BFE15995796EC3E
+:100590005C12F1BEA9B41383D24EF4F1FBA99D6F96
+:1005A000F2B86D3CFA5BB06119976BD2DF624B1108
+:1005B000FE16533E76BCC9BF62F6B79C1E27FCB63A
+:1005C000C2DFF288E2BE1B49FD575BA6FC0E41F17B
+:1005D0006F0F2F8E4753FF79FF9A1F0A7FCB834EF1
+:1005E00058DFDE0F8CFE1673FC2B42DC8B9C57838E
+:1005F000C6FF8EE26E12BE926EA53F2BBD9E7FBFE0
+:1006000069AABA5B41FEB2D9C9E1ABA23F2B25E48E
+:10061000CF529EFE53B75F8AEEE3F68893D7BD8E26
+:10062000EBB402C3591FC9BF25E06A8E4725D68B9C
+:100630007BC0DF933F2B79BC11BE050F16DE87DF31
+:10064000352EDA567E18CB51DB6FEB3B17CA92275B
+:10065000EE2BC7F22FAF07B350EF34FBB114047E7B
+:10066000714FF89AE128F1D45B2BF1D46927BAAD28
+:10067000E27034C32955E7789A03780A2A4237FE94
+:10068000752671FA4C9FACBD86FEB5C17956160928
+:100690008FADF5FC7B59128E5B051C936B97909F79
+:1006A000D08CA783DB2E0D3FC79AE0F7EC96C2BB38
+:1006B000116ECF3D5CFE3B2C7FEDBF2D1EE1B6E7FA
+:1006C000F1FB7E28E03780BEA76B82DF03F811E9DB
+:1006D0007E3DE13751E3F6F5E7A5DEB2F100DFAB91
+:1006E0008143A03F64474B81C3180732F2D3D4EF54
+:1006F000C93F15ECE6A7ECED9C4BE0A71F9BFC5314
+:10070000A93E4E37A9BE63449FE9409FB1E8AFAA16
+:10071000E57A24887D7FBC823637E7AF52AE21CBA5
+:10072000B180F0D9EAE271E7087ECA007DEFD7C454
+:1007300087D181138E772057EB107E52DE6DADE5A9
+:1007400071B4DBA678568CEF178AAB3D3F49BF6D7D
+:100750003CDD5FF8D6FEC77FC6FED2FF08784AFBB5
+:100760005701DFF1FBE657813C41FBDF5A1BB4A187
+:100770005CA9A9BF55F142D9E74A4E3FA9695E86F7
+:1007800071FE9EFEBA6002EAED138776E3C37A9C9F
+:1007900047E2C3C895E7EF433F57347C488F92AF99
+:1007A00074617C2835C8D7CDDDF850B7EEB2948B94
+:1007B000C787B809FCFB11DDF820E83FB536F82003
+:1007C000D2AF55E083D5057C0CE0A1221EE485E282
+:1007D0009E921E8222FFC00C9FA06F48943C8415FD
+:1007E0004A492FEBBBE8FC03110F6D12F1506F3D2E
+:1007F000CF97ED5C1933D5987FA0D1BAA739EB9488
+:10080000F03CFE0879B22FE3F9C938A78C6B7E5E05
+:10081000EA79059F4FCCE5E71C8C1E670AE0FD5680
+:10082000403F9709CFDF223C97F70F841E77DB14F8
+:10083000FD6D1C7784DD4F79CEA0EF1DC6765BF78A
+:100840003EC9BFB72BFC90322FEF3BFBCD12ED7EA4
+:10085000BC2F29FD669B13EC3BF0BCE7B3E014FA18
+:10086000CE2FC629D0EFB43186F21A172A6078232A
+:100870005FBCCAFBD1788AEB79281FD75BE170A1F6
+:100880009EDF9C34350DF946CD5A95E47A34FB460B
+:10089000D25B0DF01BA2B77ACE6F5201BF08DF7C8E
+:1008A0000AF19B74E0379CFFE80CF53A2BD29DB31C
+:1008B00027BFD9DC0BFC2F92EF7C83708FC077941D
+:1008C00009C506BE6399F01DF8CE4FC6336E1F8A68
+:1008D000FD633C80F68FF415BE7FB33EDBBD6F2316
+:1008E0007D49BAFB5F4067232744A6B3FC09DF8D2F
+:1008F000CEC662FF087476E504239DE913FE67D235
+:100900005905E1DB05E8ECA3F14CD8B7D71AF48A16
+:10091000CBD5F6733938FFFFE7FCED8357723BFE0A
+:1009200042F9DBF87331FE53733EF73FFCA9FF6BCE
+:10093000FDA9CF4EF81EFCA9AE716EC23FB35FF5A4
+:1009400093D1FABE09BDC495259FB64A3E0DFC1849
+:10095000796F0DF033E4CFA9555D9F3ECFED4D2D5E
+:10096000DE4DFE86D771BC74C1AFCD7C19F4CE3795
+:1009700026FC1DFD0D7F2FBFE14AE167BDD07DFB49
+:100980009502CED1EEDD3709FBBE09C6C07B7A5B8E
+:1009900057DAFDCDB0608FD0AB47D45E773512D932
+:1009A0003BCBEC71C15EEC26F977245A1BBC2F9E21
+:1009B000CC09DF1F8B28B7BAF767D293C3ED26F7B0
+:1009C00025D84D33261AF5646B2DB773AD20EF286B
+:1009D000AEAF9704905FA7FB94764C0DF6A6D42992
+:1009E0002807536B3D940F7FA9717D331E458BF310
+:1009F0007FDF717D73DEC0FF94387FD14461CF9B70
+:100A0000E2FCD2FF6A8ECB8FB0B796917CADB6E098
+:100A10005FC060CD7B3FDE71379EF71C07DDD330B2
+:100A2000E703448BDB8F48B607E3B3A3C7EFA5BF4B
+:100A3000E0115BDDEB68873FD268A1F335E70DE499
+:100A400025F0FCF1B313766DA3FC1FA90F57093EE7
+:100A500053AFD8E9BB8E557EE2335E7D5723C693F4
+:100A6000539DAC1DF5ACB8896EC23F354D273E6332
+:100A7000ADF2125EC9F8444D26BF37172BF04B1D5F
+:100A80005AF7168E9F7448D530BEBD119B02CF48D1
+:100A90004059897AC4180BE545B42975E4F76855BF
+:100AA000DCF4F73F92F25CA41F3D95A4FD7E36AEC8
+:100AB000BF1FFF3B2507A62F49433EB8B6B1310DF6
+:100AC000EF27DE3491F3877BA79FAEA6387A2EE816
+:100AD0007F0A9586BF672BCB1DBA22FEDE929FF25E
+:100AE0001161DD5BA8DF503BF9D954FD81DB900F2C
+:100AF000A8974D25BC6E555C7316E079E5D8498FF3
+:100B000069CE19357B11EC6B5D3F4F59169E6BD248
+:100B100050DA677352FF44D447D70DC8A6F95B1467
+:100B20006F5916F61B6021BA56457C7E5DCE92D772
+:100B3000F0EF8034A55B18DE3B68CB39DD82EDDA5F
+:100B4000C6F03F82635EAFEA32DE93C20F1F21FF21
+:100B500056D3785C5C157171D514572ED51599FF55
+:100B600048718758C1B76A7256CFA6EF2738ED2E65
+:100B700044B2A6846025E1C74A1BC3381DB3B61A28
+:100B8000F4B4BB1B8CDF7F71E619D7D3D27D3F2134
+:100B9000CB8B7C86FE062CDD5F48F2227E20BFE5F3
+:100BA000497FF1BC1E2BEA019BD717E17CFE51FE69
+:100BB000A3FC47192AFF2F0D22483C0080000000AB
+:100BC0001F8B080000000000000BC55B0D701CF5BA
+:100BD000757F7BBBB777279D4E7BD2C93E816C5614
+:100BE000B6446410F25AB68494D8684FDF322EBDF2
+:100BF000387C88C476CED8B8CE34932A4E49EC845B
+:100C00005667EB64C95FB2A414E44C3AD3B34932DB
+:100C10006DF08042661AF33967700821D028811080
+:100C200032930461885B529A310127A2434BDF7BE8
+:100C3000FF5DDDEDEAE4AFB81331CCDFFFDDFFFE91
+:100C40003FDEE7EFBDF73F00F0C00200D90F003AEA
+:100C5000C0A6224F122200E7AA200D95D8F74E9782
+:100C60006941800FE9AF25DB1EE807C8F8B2FD60D7
+:100C7000AD0A660DF0DF87A271CD3B6E5AF3C29FBD
+:100C800073DEE16AB5371D9C3BAF3DAED594001ACB
+:100C9000F2AE03D225AD73E6673A8E4FFE4C866AFC
+:100CA0007DEE7AEEEFEDEF3615AD2F86DAFFBFF170
+:100CB000F3D175A9E90128137D68C47353BB44744B
+:100CC00075A48302820E039D8DE90CFE73424A0CCB
+:100CD00057D2F9C21EE39B30970E762B6B73F897B1
+:100CE0009D5F16D347ECF9710BF2CE801908D12B1A
+:100CF000FC0E69AFE1B63F449628110F3F076BBE6B
+:100D000028C0B31FE2FE8E67F905DA82ECBCF2065A
+:100D100095C72F57FB5E6C5885CF5E918D6FEAD9D2
+:100D200079793F95C00B80FD5D65F6BD62ADFB91A5
+:100D3000232A64ECF1F8FF0933CC749AD8783F2465
+:100D400090BE3FDFF089E2441E39B0DB6569E7F70A
+:100D50006FE09CC07483F437F1DFA95F8C4ABCF864
+:100D600009F13CB5424BEFC7E7FBA5F4FEEB68DCAD
+:100D7000DD82BE361F0A2D3EE05FB40AE9E8B5F811
+:100D8000E4759F0BFF94054C278B38397C58C27350
+:100D900054D1B907ECF974230348A703CBEB56EC05
+:100DA000D7E9FCA3FFF26DDCC791E37BDEFA36BE28
+:100DB0000ED4D68D34E17E0A0C8F21933C7FEAC499
+:100DC0000964170CD5DE334AD36E1D954C0DDFFB3D
+:100DD000B5E03199CEE8974C9A4F39BC90CF13DDEE
+:100DE000EA948309C958504EE71B9380F85268383B
+:100DF000DFFBF49CF3E0FF4788CF2C9F39CF916E47
+:100E000048BDDEC9DAB9747FC5926705C727ED7999
+:100E1000912EE35EFD16A2F3F83E199238E5F82E06
+:100E2000548AAB007E6B4E7E7A3732FD9E412FF3A3
+:100E30006122A6A6251C3F51A4DDDE4BFD328F7139
+:100E40008C898AFFE3B946975DCBE7B2D7FB6C8B01
+:100E5000CEEB8DC51694933EE2B8F2F80D73E5CF54
+:100E6000BDFF4B95BFED668925EFA340F3C3E42D8D
+:100E70001ED227BF35E63A79B27E09ADF7731984E1
+:100E8000DCF441BC682E7D06C91E7C242B27AA25D4
+:100E9000477B23EB7F4CD3CF27CF6A7ACAACACA376
+:100EA00075A08FE8BE2CEADC9F3DEE7316BF7C690F
+:100EB000C87843D4664CA8A376CA94B03DB7E10B7A
+:100EC000DA5A7DFE757C90336F25CD077C6E2F241A
+:100ED0009858C4573387AF7B0AEBEE24BE0CDEACC8
+:100EE00002CB9F9BCE17E8AB4AE6A4142279F80800
+:100EF000CB4712E5A31AE7F1469D72187F72154C95
+:100F000007059F92FCBCDB243E255ABCB376C89FE4
+:100F1000632F41DFFD1B19E7FB6AB7AAEFC77D7E90
+:100F200035BEEDBEDB48CF5F900D89DFEB6C0FEF78
+:100F3000B1D680D109968762CBEFEC3C71EF6BCFD5
+:100F4000138FBAD5D7896EA4C7B37411F6D9F43705
+:100F500066D73BDC747A7829D221359C7FFEBB4A68
+:100F6000F5CF11FD6C3ACF37EFACFDDE7972B27D73
+:100F700065B63F529008C4F09C2341038D00BD3FED
+:100F8000C5EF6115CA65F9FCFC448AB23CBC46FF5A
+:100F9000C4713DEDA616C3BE7C02B7BE1CED6291C6
+:100FA0007ECB7A7CD511797D23D17F6BD0A3C939D3
+:100FB000FA3570D00B99201102D745B95B07D31BC6
+:100FC000D7E338A8F2B29CCB9115FC7C4B515CF175
+:100FD000607B6D6C09AF677FDF03FFA0ECC0E7CBE0
+:100FE000BDDA2B2427A988443BC2E74840DCFA5AE3
+:100FF00005CC10B65D7ACC4F7EADFB095A08A02512
+:101000003C1E21BF54F7D8918A04E975D29CAA41AD
+:10101000FE842D765DEF9B8AB7E17C032FCAC61E46
+:10102000EC8783DBD601CA91F47090EDC400DA79C5
+:101030001FF25D0976BE45CFD79C0568CF91A79674
+:10104000193FB4E7D8BD18CE9CDB6FF3973BC6774A
+:1010500068958EF732984606E9D4155DE61857D4A0
+:10106000B04AA3FDF6E82B1CCF6FAE69767C0FED7E
+:10107000CAE969ECAFC6FF88EF32883EBFAF249C57
+:1010800080FD9CEF15C8E9E3FBB5B1A2C819724A0F
+:1010900037C28DA447C8976307C8FEF4FAD96F0D0D
+:1010A00078E184540CA4FA49A827629BECEF254B05
+:1010B0005E93B14AE693147CF67D96C327A63D84E1
+:1010C000B3E031A827FBFA8F9A7ED28343AEA629DC
+:1010D000F1FB280ABA8E7C4218960CD4F37373691C
+:1010E00009F93929D983FD45382E2A44119EA37167
+:1010F0007ED8FD15310E16D1380D9215D8D70C2893
+:1011000020BE56E03C9F2DE1EF923DD677D788EF89
+:1011100092C52562FEBA7AF6A3990E6C8F82013EC3
+:10112000B63F71044D6445FAB8BD867685CF1F0081
+:10113000A39EFAD530CD760AD92F517F214C6AC2B1
+:10114000C86784DD9E56C267FCC2EEE7D397ACDE6B
+:101150002870C6E6070EBEBDC5FC12E9CDED773698
+:101160009C1777283B9F71E8ED23315DF8C39D5DA7
+:10117000AC27CACE67F9FD4BB1F81E9A8F48EFAF86
+:101180009F4BEF3A350364BF523130923845EAD174
+:10119000B5D1CDC8DFE4A37EA31AAE1C3F2E950FB8
+:1011A00069D00A88AE72DFE5F201D8CF074FF88F19
+:1011B000EE676134D94FFE097CF9F6E5F0C5CD0F35
+:1011C000B8B714A0F9C276F4EB5226202D657A98B0
+:1011D000D1FA2CFDB19F5C66D1ABC4E2872CDA8CCE
+:1011E0006C3D574AE6E70BCD575A92E5CF85F8128A
+:1011F0008DE3FBFA2C7FE43E938967FB691F9C65B6
+:101200007CBB4432985F4BE5B887FA8552C6023DF5
+:1012100069F69B21D0983F57411FB711EFF466C67E
+:10122000C33B7121C2B31FA097CD89C752C1567F5E
+:1012300025D9D71AC5F060BFB6C8134F231DAF56C6
+:101240002043E72B572049F61C9101CF9F7A14BD0C
+:1012500015FA9914BA690F7DB7CB9F4E49D9F5EBB2
+:101260002CBBFDE3A26F69D3B5593A9F26FBB55C51
+:10127000D0C3C3F6673243DF47BBC118D0E7DA33C8
+:101280001C97942D3B45ED267AD1CC744B86B02F1C
+:101290000DFFE07DC219349F82FDEFC512EF923F32
+:1012A000259C1E2C61BB345D48C07A2E2E30095718
+:1012B0006CB6D6E9BD495F1CC77D6E1EF6BD4EF308
+:1012C00041CAE7C405EEEF750972BFB7BF9B952B06
+:1012D000F7F797A907B0B3ECA27040ECE1D5C5D3FE
+:1012E0007970FB2CCE243D29CDFD4EF0498D24187C
+:1012F00077A8A42FA5179EC7EBC22FF63C5E145CFF
+:101300009AC76BE117DB4F6D83B35E65A9B54FA438
+:10131000D716B0FF224CCF4D16FD3E4DFE2A44F4A9
+:10132000C44005CFBD15E22AC9ED5F2184261CBF4C
+:1013300064DFD610E30568D7883E52E663F287D7AC
+:101340005F021D2D3A6DCABCE5D5C92EED2C823742
+:1013500072E337EBFDBB1B3E21E274BFBFCA9F1394
+:101360001F169EF8A09F8CFA9EC2BF7FB105B73EA4
+:10137000F8926CC895F45EE0E60008FF5D487A8A52
+:10138000FB2E7CE2CCFFD0F84217AEA69921675E17
+:101390004FE141C6B3852155679CED92331B47C38E
+:1013A000070207072DEAE5CC2B115EB6E31E9E5718
+:1013B0009ABBEE0D163EC757B10F2F02CFBB713A45
+:1013C000CCE273F13E1854859E609C9971C4C17A39
+:1013D0005E3DB3F76D7F57A6C62B8DDA3CDF5B7C95
+:1013E000A8A5401CEDC2C20A48EFC6FD0E0FEF884B
+:1013F00015627FAC0C748C3061A8F38B12E18DD632
+:101400008810A57093C085B404D8713CFE85FF4355
+:10141000DF5F83EFB755040DDC192C7C1B7132CED6
+:10142000737785DF30F1410AC4FB649347C4934965
+:101430007899F0E8568B3FDE2704CE64DEA01E1EAE
+:101440006C15F86AEB89CFAE23FE8E94DC6A64706B
+:10145000DC56B44FA584C746BD8CE710D73970BFA2
+:10146000AF290707E2FF771FF13AFA5E174E3CD02B
+:101470008A3810E5DBC681F7B702EB19ED8BFCC9A2
+:10148000955A078211B6A73728539E7CF9379B1FC0
+:1014900036FE7EB24CD0D9FB9EA00B06CC3BE8B901
+:1014A000EF3D118FA1010F362C20EF2FE8E76B40A5
+:1014B000FAD0D3F7843FC02F79DF26FE47FB76E3CF
+:1014C000619F0B0FBBF76BF3E1619B3E8DD048F43E
+:1014D000417CCE38C13E8FFB1C4F607CDE8E42F1DA
+:1014E00054BF9FDB4CBFC6EDD3FD516E4FF5EBD023
+:1014F0008E00ECD9FE1A6E9FEB37F8F9F3FD4DDC48
+:10150000DA74984B1F91D7BCC6DAB3523B15273F0C
+:101510007A55BB875561EC5E0FD3ED1CCA27295F56
+:10152000C8A0DC1B8EEFF6A429A4B7E39F8596BC68
+:101530005EEF3B7BD287E347CAC1D883DF2F6CDAEB
+:10154000C672B6E6AC27AB2740714E81234F10839D
+:101550005247BFCD7FB5637C87B6D4F1BE2436CD6C
+:1015600076AA2B7ABD639CCDE77FA2380BF737D6DE
+:101570007E5A23BAF6E82B1DE3947B91FF7514FF86
+:101580007CCC312FC8EB0CB2D3251B9C721872F1A6
+:1015900055DD7EFE38C8E6F3DBADCE78683EFEBA98
+:1015A000E5D5A66BC92C5D455C99A2B812E95AA293
+:1015B00009BADAE71DB1CE6BAFAB3489F35DE9F858
+:1015C0003244F16565BEF8F24D8BCE17882FBB9D76
+:1015D000F1A59BAE178A2F17B439EDCAC5D273D3C4
+:1015E0006291772B7941E6B845EEEE633F583A2594
+:1015F0001B5D64122D5C56443600C76D6A50D3845F
+:1016000033C7603A4AFEFCB0845445792BAD35CAE5
+:10161000C9CE3C14365EE925DCD823F280CFC46EF7
+:101620008F12EE18DC7D348ACE0A9ADB3C6CEF46D2
+:101630006367387FA1E8C0F90B6CCD741E7C628FA4
+:10164000B7F38D8737AA6909C71FB6F28D877B6606
+:10165000F38D5CDF986810F9C68FB6E9569E29199C
+:10166000A578E5AB1B1BCBD95929D8BF81861BAC0C
+:1016700027FB035A88E2E8D4468F46E79257DDFFFE
+:1016800005928F4352DFBE2A8ADFCA3C9C774D8584
+:101690001BCB37E3387913C218EA6F6C7C956CF674
+:1016A0004499BEAF8ABE0F5731FD0657DFEEA775CE
+:1016B00046C20B7A283F32D2E1611EC98433423CD4
+:1016C0004FCDF9E21E771D40268B4BF15BC4935141
+:1016D000C95F11FEC8C9FBDBFCDF1F56393FBBA544
+:1016E000EDC1A3C92A7ECCF66BA15D97D9D8CA7982
+:1016F000E6738427A4F9EB327BAD7CE7ACDF893A53
+:10170000F793671DC605765D82FE743B4F8B7FA9FC
+:101710005B3AD3E447C721DE4DF633193C7F1D44C5
+:10172000099EBF0E325FDD63579BC8A37E99F82EDA
+:10173000EA338E7A89D26DD545ACF8F530E5C349E8
+:101740001E5C75127B1F03D67CA9593972D54D5684
+:10175000ABD67C06E4CB5FFFA9F593FBDB44BDE68B
+:1017600052EB26DF6D03B15F2BDFEDB5F87F9D3CBB
+:10177000B983E4F1CF9DEFFE6EDB95CD77CFAD134E
+:10178000A5595FE0C4D93758AF972DB0F0CBF9EB2E
+:1017900040FB09E823FFC657202EA5FA87D54FDE68
+:1017A00020E675D78502561EE5876D4B45BC45F68C
+:1017B0008498AB188B89AE41E53B490DCF51101C85
+:1017C0008330B6BEC8E624B52D8B75AE0F8D2FF3D2
+:1017D000B0BF1A2F4A1C1DA4FD2F0BE6D58B572D29
+:1017E000FB376CD56F48803DA46F92AD1C90F02004
+:1017F0009F2640F0F9EDB6308F57B4D1A6BB506E9E
+:10180000DE247928E3F3E4ADFF9C6913F59F9CF98E
+:10181000BF41729AB226A77936E33CFF65C923908F
+:10182000E35840C18E58CFAF8F36112EF85D9B26FE
+:10183000DE2B2B0CD287F170FEF57E679D072815F5
+:10184000D398C5470B378879C02FBE3F2C9DED3DFF
+:10185000BD8AF9CAFA44FBA0F7EEFA977BFE408DE9
+:1018600033BE512B9CE33F983D87332E3A344F7D56
+:101870006C51BB90D796C542CE483EF6E4910FB767
+:10188000BEAB94F7A478AA3D6CAD27EC4E50996A94
+:10189000A57827580B06D71495937CDEF893552727
+:1018A000A657919D0F191407297E3495F5D938D183
+:1018B0007DEE0BC5798A02496FFDDC780FE7358B29
+:1018C000EB859F49E6CC774DBB901339371EACA40E
+:1018D0007044BF85EB785407A4FE2E5F6F3E3F5DDA
+:1018E000DD76FEBACE9138C61114A43E7C70DF16A8
+:1018F000ECBFAB79341F8FD1F3D67534AB3F5BD7D8
+:10190000895F5C5D67B4BDA4A7EA52EA3AF3CC3BB9
+:10191000EB8FE7D675DADBF19C6341515F99ADEB54
+:10192000DC1AB9A87C0E587EB9C4B2CB453D561C12
+:10193000B153E238E2E9867F3FB09CE4ACC1CB72A0
+:1019400000072720574FD66DD0BF564A7EE6551F59
+:10195000540BBB66D27C765C6CD34FB5E66F7DF0E2
+:101960000585C68F977B1A793EC8F83C5CEC4EAA79
+:10197000562B53BB5CCDC8C5346F095875F48C44E5
+:10198000CF6348ACDCF86064E6A76DC59427098294
+:1019900041266824A6ED2EA67F501588F04EA59E00
+:1019A000267BDBE62F74D8FF911E55D8D76A715F6E
+:1019B00066FCA4FEB5AD387E68678071D3A10A8F3E
+:1019C000D0AFA4C4F5E40ECD19F78C4F2E1178ECEE
+:1019D000A0D7A07B22C727C5F82DB1C6B4CCB8DBF1
+:1019E0001917F5E8CEB8684B79FD2B841761D0CB79
+:1019F000F978CDC2B537D738E3A4A2CABEE708A7A5
+:101A00006C1A1478786FB464C116B47FBF6AD71D9E
+:101A100071E2E6C1BBB96E34A802D7534736AAAC0F
+:101A20001F23DED78F6C61DC58C0749CD8A8962722
+:101A300072F4A5B4C367DD8B10F803E1656232CFA1
+:101A4000FBD20E617750B0D98FDBF2F2179F117481
+:101A50000E55405A271CD7B3234371E578059E09DC
+:101A6000DF0F46AB7A4ED2FA2FCB40E774CB6165DD
+:101A70004735EBE9AC3F6DF238E8E4F5C5FB687E2D
+:101A8000B81974B26BEDDDD8A73CC00615283FE04D
+:101A90008BFE2D9FB704FB01ECFBBB47930AF6FDC1
+:101AA000558995848B9FD975C7702C42FE4EE8B737
+:101AB0006FC3B6F82768FC2A2F04687FA04B51DA61
+:101AC0005F52DC6770EBC3DED4F7DB894F7B0D8997
+:101AD00059B4A967FD76BEB7142960DC34EA8D6F6E
+:101AE000667B749B5F4BB20F9CE638C2FB151F9060
+:101AF000DC4DECFA4D19E1EF1FB58BBA664077C6A5
+:101B0000D77E1865BFBDDA9CDA40DFAD6E52A9E220
+:101B1000014F379F61BE4D34F80C1FEE63A259622E
+:101B20003AFFA1C19BA6759E52A7645AF7A93FE050
+:101B3000DA95F9F43BBF5ED97AE41E3FD2B4DE4FAA
+:101B400072B117A66E25FA2467449ECA3D2EDE2187
+:101B5000FCD5DED46D350AE7B354AEB72B670DB3B1
+:101B600018670FCFC4FF9972AFC97645C449E59E87
+:101B7000A484F30DF5887B194345896192E721948C
+:101B80007B8E9322E23ED27879C4D89FB3DE78F37D
+:101B9000ED3564CF5E6C0830BE1F38F5377711BE67
+:101BA0006F95DFFEEEC3145755A8CCCF216FDFAB86
+:101BB0001407251B02BCDF538B54F0933D88DCF5E2
+:101BC00000C5D9707C03E4CAEB44B7D0D3890AA11D
+:101BD000F7D2C31B380E189764A6B359764C223C33
+:101BE000E6EBB6F34E22CF14B3CCD9C48647380FF8
+:101BF00075558FC8A3C6BAAD7C931C4CB25CDE1879
+:101C00007880F4DF54BC8EF878CD5967BC7C952B76
+:101C10005E76E7A3FEB7DDCA475879275B2E43D629
+:101C2000988926CB4EAFF2A5851CF6956BB573F55A
+:101C3000FBDF2CFC3CD5EFE77B643FEDD7B81F32D0
+:101C4000DFD95D8AF3BCDC1FE5E77FB9FAA894FB16
+:101C5000DDC8AADBFC3ADB93E928CDEBB6236EB9ED
+:101C6000D8DF5EE0F027F63E8B9A5BC5FDBBB36C18
+:101C700091614D70BA8D7D234C0573F17EA65FDCBA
+:101C8000737BDADAE729DAA78FF264627FCFF5EBAC
+:101C9000DC3EDF5FC3EDC60E10F500DB3E5C83F675
+:101CA00001E9D05E21FA640F88FF2591BB384FE629
+:101CB0008B2A1AE9BBBF623423E5D88789A2BE5FAD
+:101CC000DC4D76BF2CC8F2E83ED79A0E4FDE736D1E
+:101CD0006ADEC176E71CAE43F4473BB39DED10DAF4
+:101CE000055E77837A27EFC344BBC476A1EF6B7799
+:101CF000B05DF002C9B9DB0E9424857E277491BFD4
+:101D0000B3EF09CDDA055C278DEB3C8D769DFA4368
+:101D10006807689DA1E6D7FF9AD6FDC3FB057C2F17
+:101D20006A62E32B6C175E3C8736FB0ADA055B0FB1
+:101D30005F3B153B961BCF67F9BCFE8E13821E1AC4
+:101D400008BAF6C6F3C48997CA67302F0EC7A495A0
+:101D5000E93B45DD51653ACC5B774C7A0C4A0B0C7C
+:101D60004C2ADD56DD11A8EE68D71F73EA8E05CE2A
+:101D7000BAA39A4E31BE495B75C7DBD78ABAA35A5C
+:101D8000301DCCEEC3AE370ED2A3F26C7DFEAE8E0C
+:101D9000C4AE8E866C9D5197441DFCA598F9657A5A
+:101DA0000E9112F6FFEE3AA55D8F4478272572EA70
+:101DB0009B75F8DC5F92AD7FB9EB99F6BD8C3A75F7
+:101DC000FAD801A4CBC09D7EC60FF6FE061EFDE824
+:101DD000AB8948F63E805DEFB4EB9976DD13F73DB5
+:101DE00096BB6F7802D8EEC063FEA3E4DFDCFBFD98
+:101DF0005E2C717F47599E7D5F647D711D58F32372
+:101E0000EE227D7ECDA2A33DEE414B1F97AB22BFBC
+:101E10000D2195E39DD607832013CE2E528F915E20
+:101E20006C86E90EA2EF4058E0BCD4212FDBC9E359
+:101E30001D3AF3AF4C35F93E44D99703C66E9C2644
+:101E400075520B51FEA9A7DD3CDEC1FB18BD753DE7
+:101E5000ED03713BD9BB5F57DF17E17A3FDD7B2A8A
+:101E6000A6F8CF584C7990173AF2DF576A597C762A
+:101E70003DAF5BE4018ACF5201E339BE57FCA4C2F7
+:101E8000F3F5E014663DDF5F6A574B681E713F75DE
+:101E900020789AF9D552ED5BC179BDA2FC71E0B30F
+:101EA0001D226E5D8B73A938CF675A13DFA77D5350
+:101EB000AE34CA722CE2BB17C84E0AFB75AFA7310D
+:101EC0009B072B96132FD078382E29E41F7D96DCA4
+:101ED000D871E23BADE68BC477E48749EBDBF78052
+:101EE000ECF55FB2F890EC307F4AE35EB7D6A9D349
+:101EF0009231D2C3BA04CA83C4FAE3AAC30BB9703D
+:101F0000CBAB2D6FB375784B0E254DD46B51AE5EB8
+:101F1000E7FD3EA59FF448546F4F1C3D40DF5E66D1
+:101F2000BDFBEA36F32DDA77716BFC3F69DE5FEFBC
+:101F3000BA83EF055FEC3D8E96C57D51AAE30F0590
+:101F4000046E7E286638ECDDA24EC19F459D022FAF
+:101F50005D8F3233C5F74B0DBEF70DB09D71B46D7B
+:101F60009F46FB138FBF599DFD3ED50F93540F9A8B
+:101F70006F1FDE7D3B38AF3B50D1EA27FB83F6ADC8
+:101F800098FA43156634771FA92221E7C945226FC5
+:101F900041F9B464CE7DF2924E99CFD35601199295
+:101FA0001D5F50D4DD7CA8B83AFA1F9FD9C4F78BC7
+:101FB000F1F924A518AEEAD4455C1E31C0A478B36B
+:101FC000220EA4DF3E2DFB3DD551DB2AFAF8BEE5FB
+:101FD0007CF3C851FBFB047F7F53A7C6F3AA118F84
+:101FE000230F7021BAB9E9324874AB9E9F6EEA455F
+:101FF000D34DE89D9B5E8D16BD9E097F91CF071F37
+:10200000B4B19EF9343C27B6AB3B857D9183262441
+:102010008AC846C51141529EBD0FA80E6DD359D630
+:10202000049D65AD8FBFF3551890B881E89260BAF2
+:10203000B8E9807602C84EFCF0D12311C2A72DD892
+:102040008F0AFB013E6CBFDE21F862EBE93AF849EA
+:1020500050E4BF9DFEC26D4FEDF6212BFFEC7E2EAE
+:10206000750584FDD0C141F722EBF70BC786EB194C
+:102070001FA0FF4CD2BD98CEF2EA02EA5FE93AA275
+:10208000BB7EE8AE13BAEB8359B931FDB4CF77B557
+:10209000D3C98FE79117BB3D60E9DB60BF3FAFDE7F
+:1020A0001D407D27FE0D359B49AA1BED0D4F47595D
+:1020B0006E4EBEC5B858794136085F2A8AE073E78C
+:1020C000A269E663579309546F3AD0DFFB9DDC7930
+:1020D000BFDE9AF84A27CA49A13669D23C41C824D2
+:1020E000C9FFAC2D35FBF2E1A621CB8EBCD31ADFA4
+:1020F0004DDFD1B575E2FF9B31730FF52FD66ECD55
+:10210000A74F8A4DBB4BD6A7D3429F9A76B03E8D40
+:1021100054F431CE1AF9894C482A8B232D7D1A6943
+:102120003EC3FA6EEB55DAB63F4D422F288F40FE84
+:102130003B5461B2DDF896A54F0AEA09E993CFD284
+:10214000A790961D4FF9F136A2333E572AA6F9BB48
+:102150005093A57FA44F41BA3F0C8C038650EF28C3
+:102160002FE2D6AF962AE1379F684D3CD449F862FA
+:10217000D17ACECB0F55FCBE94F18B25FF59BC5BB9
+:10218000CFFEFCDCB0C7207DA823005D9FD503FBFC
+:10219000DCAB6764C8206BD6CC48DCDE3453C86D3A
+:1021A000CB4C805B73A694DBD84C98DBD699ABB94B
+:1021B0006D9B29E7B67D06F56025EAC34C25B79DE2
+:1021C00033D773DB35B38CDBEE99953CAE67660590
+:1021D000B76B673EC6EDCD33CD629D1A71AE3CFA4A
+:1021E0004065B02BA00F46128A480F3EF32ADB77DA
+:1021F0004DE53B4AA97023D7897CCA34EBC3B1268D
+:1022000061EFBB82824F6E7D78A735F1AB7CFA30EF
+:102210008B6F15D088FE2A587F2EFC80F8E737F4A4
+:10222000BD8D7BD5A8C97286F8E40CF1F37271C23A
+:102230002CCE5CAC321EB571E6C822C49995599C6F
+:1022400039D42CE2B2D4211FC76F5B2471BFECEAF2
+:10225000B6C47FB37E82C813256EF56B849B53E1B1
+:10226000CE6890F27A7B65A07C01E2900F789F4A5D
+:102270005CDC67BD487D7E3326ECBE3DBE0E4E7BEA
+:10228000FA2E01C7FC9AFED93CBF5D28B95C3FEB32
+:102290006D13764113762155D137CC7569975DB0B2
+:1022A000FD2CD2C3611796765976C1D2F3920AE11A
+:1022B0002F4BC82E207D9675D976C1E967151B87EF
+:1022C00074DB38C4B20BDDE23BC4ED0E3F8BECF6A1
+:1022D000430E2E46395ADE950787B03FCFF1730380
+:1022E00055D531FA2D41F82CC4483C4333FA5A23D2
+:1022F0008FDF4969F5AC07279536C8CDAF5CB29E34
+:10230000856DBF63B2DF718FB3F56DE8648F38A759
+:10231000E5874EE2F9CD1C7DEBD2843F42FF73335B
+:102320009DD3AD6F2D8BCD443CCF3E3FD925F0FEE4
+:102330008FD658B81771A511647C9F17377C92F817
+:10234000D7207EA7F118DA9F8EEE644AD159CF3F8D
+:1023500049EBAE6E9F92290F7453D3E8CB541241D0
+:102360003DFD5457C3E5EB6953AB55EFDB592A2EBE
+:102370003B5BED85E4DFC645B61EB8C73D5469F644
+:10238000E6A3C7B3163D06863D3D74E1CF968B9319
+:10239000CA52C63F79ECAD695C117B7B71F8E324CE
+:1023A000FA41E2FB79F0C7817CFC9F0F7F8C77CDEF
+:1023B000E28F31E2534BADC01FCF76C179E39BCBA7
+:1023C000C615B1D34CB7CBC5150F769D1F577CA74B
+:1023D0004BD84D459B66FB11BA4C5CE1B613881F88
+:1023E000FE95E96308BF6BFFDE842F50E6F82FB43B
+:1023F000338FD338C20D7479EC58B03529B11EC46F
+:102400009FA4E7A3E61296A32BA50F88137FD09570
+:10241000D3BF905E5CF4B8C98D9C07B4EB997F0C78
+:1024200084EA283FB2D32FDA2F15848E513BD62F62
+:10243000F2D07F0C2C4E53DE6CCC0B5C3F18940A10
+:102440008C63223FBA9C7F5F037D37527BA6CBAE65
+:10245000CBFF9DA35E1AD6B63DFE6669BEFD88FB26
+:10246000BD948AFF90EF8157689C3FB7E84169208F
+:10247000F6CFD5058CFF00614B538EDD4F75AC1345
+:102480007172A59FEB79322867281F3F4C6BF1FED4
+:102490007AB98E19B0FC212849FDE3BC5F9107B5DC
+:1024A0007FF7B76FF5FA627109793B8FB7E57F5F08
+:1024B00070D4AFD53AF4DDF1BB6E772BAF38A5B54C
+:1024C000E17EC77485EBAE078D4880EB2615227B35
+:1024D000EE5FE489A7F3E8E9B5DDB3F722785F6141
+:1024E0006B5FBE0E11AFCDB7DEFE7EE73DAB82DA8D
+:1024F000B849FEC45FD91727BAF9174524CAABCE2D
+:10250000D2BB5BB2EE69189916A4F7B0A587053562
+:1025100093190FD139BC6D25D1D65F938633344FD3
+:10252000ED24BC41FEA2D2DF9B6FDFD759FB1EF624
+:1025300026E38493862B15AE5F0E57E6F72F25DD35
+:10254000C2FEFA17EDE0F1B048E1FAB37B9CD22D60
+:10255000E4689FDAC7758CA145F7F37DB721FA21AE
+:10256000CD47D1EEFD70E681DDF8FC50FFF6C7DF08
+:10257000F4929C26B8DD77ED7E8DEE711EAAF76889
+:1025800094870BFB337EFA7D6678B5C87396B4E307
+:10259000B8DC7855AE08909D0DADC27972E2D031AD
+:1025A000D002B4EEBE906D1FA7FDC23E0A792AB2DA
+:1025B000C68EAC1275A9917576FE5FF02FFB7E7CFE
+:1025C000BBB82FA7EAC079685197E2D49E4EF7674F
+:1025D000EBC374AE324DD4A30E59F23568E5D9DDA4
+:1025E0007439B4788AFDC9A13553BDE43F429ADFFE
+:1025F000E826B93EEEDCD7DEE66907DE1869386DFD
+:10260000EDDFBD3F21F7CAD36F093B69E1FE90F1D1
+:102610007BC659F63DAEAED5420F8BAD7BF4C5916E
+:10262000B849F3EDBEF6B749AA131D2EB7EF167CD5
+:10263000DE790F03A6191787565B7539F96DBEFF52
+:102640000BB78A7B12F63D6F35A23AF202A5AEFBBC
+:102650005921571FE40DE7BDCFB6F397479F3F952C
+:10266000C3CFCF773BEF835FE8FB3FF6A79F3F8564
+:102670007E6E6CD5F9F5CFE6D3E1FE266E6D39B4EA
+:10268000E5324C47AC9FFFFBB1703C6FBDE5114B91
+:102690004FDCF2EA96D3625F9CFDFEE81AE73CF756
+:1026A000597A7E9F358FBA18CA090F8D86855E8E3E
+:1026B00006A0F7913CE77AAC5BE5F159B977E28285
+:1026C000A2CBC5052B5AADB8A284F56D6C55EB7342
+:1026D0002437EF915EE4D82777DEDCC6054A8FC049
+:1026E000A5CF845589FCBA169C66BC3CEBD72D1C43
+:1026F000E0F6EB7E6FB297F4CF5FA9DA7689ED470B
+:102700006577E01BC920FB0329D70F1ECADCC9F37C
+:10271000865D797388387F87B2B71B984E61DDB2CA
+:102720002FDD8AB887356A42EE3D9A31CFDB336FB1
+:10273000E8E2DF1FD838A292DE1F9CE2DFC7C03D6F
+:1027400090BBFEDE964DFC7B880BF1DDDE17DDCB0A
+:10275000CAD59B4BD58B976DBD084080F4E21CDC3D
+:10276000CB757418ED76F821AE282C601320FEF09E
+:10277000984AA365C7A4ACBE409755DF4E883A3D42
+:102780005198BE33ACCFCAE99604C5D790E1DF1D9E
+:10279000DAF6E51CFC92D74D3E2D49B3B8E96A0C38
+:1027A000DFE9F78C4B690B9A875AF7FE9780C1CF08
+:1027B000AB20CEEDB5D0C76D0D8C727B1D4C725B1E
+:1027C0000B53DCD6C1596E57802ED3222BC1948176
+:1027D000AF5E26B87F2324B96D86C4FB742774B01E
+:1027E0006CDB0AB257EFBBE864D3398FBE332EB42B
+:1027F000E961D3FD2132D20D17E66B2A2CEC6F5B19
+:10280000D314E3D7A2A01DFF0A39B7E7990FC7BABF
+:1028100071979F70D7CAB9727021DC65E3C4FF035A
+:1028200008E97101B048000000000000000000004D
+:102830000000001800000000000000000000004040
+:102840000000000000000000000000280000000060
+:102850000000000000000010000000000000000068
+:102860000000002000000000000000000000001038
+:102870000000000000000000000000080000000050
+:102880000000000000000000000000000000000048
+:102890000000000000000000000000000000000038
+:1028A0000000000000000000000000000000000028
+:1028B0000000000000000000000000000000000018
+:1028C0000000000000000000000000000000000008
+:1028D00000000000000000000000000000000000F8
+:1028E00000000000000000000000000000000000E8
+:1028F00000000000000000000000000000000000D8
+:1029000000000000000000000000000000000000C7
+:1029100000000000000000000000000000000000B7
+:1029200000000000000000000000000000000000A7
+:102930000000000000000000000000000000000097
+:102940000000000000000000000000000000000087
+:102950000000000000000000000000000000000077
+:102960000000000000000000000000000000000067
+:102970000000000000000000000000000000000057
+:102980000000000000000000000000000000000047
+:102990000000000000000000000090000010000097
+:1029A0000000000800009008001000000000000275
+:1029B00000009000001000000000001000009DA822
+:1029C000000000000000000880000000000000007F
+:1029D0000000000080000000000000000000000077
+:1029E000800000000000000000000000000091A036
+:1029F0000000000000000008000093C00001000477
+:102A000000000001000093C8000000000000000268
+:102A1000000093D00000000000000008000093D4E4
+:102A20000000000000000002000094980000000078
+:102A300000000008000093D8000800000000000813
+:102A400000009B3800400000000000400000941887
+:102A50000008000000000008000094580008000072
+:102A600000000008000094A800C8000000000098C2
+:102A700000009638009800000000002800009678BA
+:102A800000980000000000280000C0000540003051
+:102A9000000005400000CB200008000000000001FD
+:102AA0000000CB2100080000000000010000200809
+:102AB00000100000000000100000200000000000D6
+:102AC0000000000800009D600008000000000002F7
+:102AD00000009DA0000000000000000100000000B8
+:102AE00000000000000000000000000000000000E6
+:102AF00000000000000000000000000000000000D6
+:102B000080000000000000000000000080000000C5
+:102B10000000000000000000800000000000000035
+:102B20000000000080000000000000000000000025
+:102B30008000000000000000000000008000000095
+:102B40000000000000000000800000000000000005
+:102B500000000000800000000000000000000000F5
+:102B60008000000000000000000000008000000065
+:102B700000000000000000008000000000000000D5
+:102B800000000000800000000000000000000000C5
+:102B900080000000000000000000000000000000B5
+:102BA0000000000000000000000000000000000025
+:102BB0000000000000000000000000000000000015
+:102BC0000000000000000000000000000000000005
+:102BD0000000000000000000800000000000000075
+:102BE0000000000080000000000000000000000065
+:102BF0008000000000000000000000000000000055
+:102C00000000000000000000800000000000000044
+:102C10000000000080000000000000000000000034
+:102C20008000000000000000000000000000000024
+:102C30000000000000000000000000000000000094
+:102C40000000000000000000000000000000000084
+:102C50000000000000000000000000000000000074
+:102C60000000000000000000000000000000000064
+:102C700000000000000012C800800000000000807A
+:102C80000000000100000000000000000000A000A3
+:102C9000071000000000071000001EC80000000020
+:102CA000000000080000AEC000080000000000089E
+:102CB0000000AE4000080000000000080000AE80E8
+:102CC00000080000000000080000200800100000BC
+:102CD00000000010000020000000000000000008BC
+:102CE0000000A01007100040000000400000AF40AE
+:102CF00000080000000000010000AF4100080000D3
+:102D00000000000100001ED00000000000000001D3
+:102D100000001ED8000000000000000200001EDAC3
+:102D20000000000000000002000012B000080000D7
+:102D3000000000088000000000000000000000000B
+:102D40008000000000000000000000008000000083
+:102D500000000000000000008000000000000000F3
+:102D600000000000800000000000000000000000E3
+:102D70008000000000000000000000008000000053
+:102D800000000000000000008000000000000000C3
+:102D900000000000800000000000000000000000B3
+:102DA0000000000000000000000000000000000023
+:102DB0000000000000000000000000000000000013
+:102DC0000000000000000000000000000000000003
+:102DD0000000000000000000000000008000000073
+:102DE0000000000000000000800000000000000063
+:102DF00000000000000000000000000000000000D3
+:102E000080000000000000000000000080000000C2
+:102E10000000000000000000800000000000000032
+:102E20000000000080000000000000000000000022
+:102E30000000B00000180000000000180000B300FF
+:102E400000400000000000400000B300004000020D
+:102E5000000000010000B30100400002000000007B
+:102E600000008000004000000000004080000000E2
+:102E7000000000000000000000008000000800408A
+:102E8000000000040000800400080040000000046E
+:102E90000000BB0000280000000000280000BC402B
+:102EA00000100000000000100000880000800000FA
+:102EB0000000008000008800000800800000000280
+:102EC00000008C000020000000000020000020080E
+:102ED00000100000000000100000200000000000B2
+:102EE00000000008000011080008000000000008B1
+:102EF000000011680008000000000008000011A890
+:102F00000008000000000008000012700008000027
+:102F10000000000100001271000800000000000124
+:102F200000008D00001000040000000400001320C9
+:102F300000300018000000100000132800300018B6
+:102F400000000002800000000000000000000000FF
+:102F5000800000000000000000000000000011E8F8
+:102F600000000000000000018000000000000000E0
+:102F700000000000800000000000000000000000D1
+:102F80008000000000000000000000008000000041
+:102F900000000000000000008000000000000000B1
+:102FA00000000000800000000000000000000000A1
+:102FB0000000000000000000000000000000000011
+:102FC0000000000000000000000000000000000001
+:102FD00000000000000000000000000000000000F1
+:102FE00080000000000000000000000080000000E1
+:102FF00000000000000000000000000000000000D1
+:103000000000000000008308008000000000008035
+:103010000000000100000000000000000000200887
+:103020000010000000000010000020000000000060
+:103030000000000800008D100008000000000008DB
+:1030400000008D700008000000000008000084509F
+:10305000046000280000046000008EA0000800004A
+:103060000000000100008EA1000800000000000127
+:1030700000008408000800000000000800008448E8
+:10308000000000000000000100008DF400080000B6
+:103090000000000200008DF60008000000000002A1
+:1030A00000008E04001000000000000480000000FA
+:1030B0000000000000000000800000000000000090
+:1030C0000000000080000000000000000000000080
+:1030D00000000000000000000000000000000000F0
+:1030E00000000000000000000000000000000000E0
+:1030F00000000000000000000000000000000000D0
+:1031000080000000000000000000000080000000BF
+:1031100000000000000000000000000000000000AF
+:10312000000000008000000000000000000000001F
+:10313000800000000000000000000000800000008F
+:1031400000000000000000008000000000000000FF
+:1031500000000000000030000040000000000008F7
+:1031600000003008004000000000002800003390FC
+:1031700001C0001000000008000032000020000024
+:1031800000000020000037200000000000000008C0
+:103190000000102006200038000000080000A000F9
+:1031A000000000000000200000003EA90000000018
+:1031B0000000000100003EC8000000000000000206
+:1031C00000001C4000E00008000000088000000033
+:1031D00000000000000000000000400000080000A7
+:1031E0000000000100004001000800000000000194
+:1031F00000004040000800040000000200004060A1
+:103200000008000400000004000040000008000066
+:10321000000000040000400400080000000000045A
+:10322000000040400000000000000008000040488E
+:103230000000000000000008000080000000000006
+:1032400000000010000050400001000400000001D8
+:1032500000005000000000000000002000005008A6
+:1032600000100000000000040000500C00100000DE
+:1032700000000001000052C7000000000000000133
+:10328000000052C6000000000000000100003000F5
+:103290000030001800000004000030040030001866
+:1032A0000000000400003008003000180000000298
+:1032B0000000300A00300018000000020000300C4E
+:1032C00000300018000000010000300D0030001830
+:1032D000000000010000300E003000180000000166
+:1032E000000030100030001800000004000030140E
+:1032F00000300018000000040000500001000080B1
+:1033000000080004000050040100008000080004D0
+:103310000000000A000000000000000000005068EB
+:1033200001000080000000010000506901000080E1
+:10333000000000010000506C01000080000000024D
+:103340000000506E0100008000000002000050707C
+:1033500001000080000000040000507401000080A3
+:103360000000000400005066010000800000000220
+:103370000000506401000080000000010000506067
+:103380000100008000000002000050620100008087
+:103390000000000200005050010000800000000406
+:1033A000000050540100008000000004000050584C
+:1033B00001000080000000040000505C010000805B
+:1033C000000000040000507C0100008000000001AB
+:1033D0000000507D01000080000000010000401846
+:1033E00000100000000000040000409000100000E9
+:1033F00000000004000040980010000000000004DD
+:103400000000411000000000000000020000411216
+:103410000000000000000002000041140000000055
+:103420000000000200004116000000000000000241
+:103430000000604000080000000000020000604240
+:1034400000080000000000020000604400080000C6
+:103450000000000400006080000800000000000878
+:10346000000060C00040000800000008000060008C
+:1034700000080000000000020000600200080000D8
+:1034800000000001000060040008000000000002CD
+:103490000000634000080000000000080000638096
+:1034A0000008000000000004000063840008000021
+:1034B00000000001000063C00008000000000002DE
+:1034C000000063C400080000000000020000640067
+:1034D0000008000000000004000070000010000060
+:1034E0000000000400007004001000000000000450
+:1034F00000007008001000000000000400007000D0
+:103500000008000000000002000070020008000037
+:10351000000000010000700400080000000000022C
+:10352000000070400008000000000002000070442D
+:1035300000080000000000020000704600080000C3
+:1035400000000002000076480008000000000008AB
+:10355000000070800008000000000002000070847D
+:10356000000800000000000200007688000800004B
+:10357000000000080000804000080000000000017A
+:1035800000008041000800000000000100008042AF
+:103590000008000000000001000080430008000057
+:1035A0000000000100008000000800000000000290
+:1035B00000008002000800000000000100008004FC
+:1035C0000008000000000002000080C000080000A9
+:1035D00000000002000080C200080000000000029D
+:1035E000000080C40008000000000002000080808D
+:1035F00000080000000000010000808100080000B9
+:1036000000000001000080820008000000000001AE
+:10361000000080830008000000000001000080849A
+:103620000008000000000001000080850008000084
+:10363000000000010000808600080000000000017A
+:1036400000006000000800000000000200006002AE
+:1036500000080000000000010000600400080000F5
+:10366000000000020000604200C0001800000002DC
+:103670000000604000C00018000000020000604C24
+:1036800000C00018000000080000604400C00018DE
+:10369000000000080000605700C000180000000192
+:1036A0000000605400C000180000000200006056D6
+:1036B00000C0001800000001000066400008000083
+:1036C00000000008000066800008000000000008FC
+:1036D000000066C000080000000000080000D94299
+:1036E00000180000000000020000DE4000000000A2
+:1036F000000000000000E0000000000000000004E6
+:103700000000DD4000000000000000040000DD4477
+:1037100000000000000000040000DD480000000080
+:10372000000000040000DD4C000000000000000468
+:103730000000DD5000000000000000040000DD5427
+:1037400000000000000000040000DD580000000040
+:10375000000000040000DD40000000000000002028
+:103760000000DA0000000000000000040000DA00A1
+:1037700000000000000000680000BB6000000000C6
+:10378000000000000000D000000000000000000465
+:103790000000B0C000000000000000040000B0C441
+:1037A00000000000000000040000B0C8000000009D
+:1037B000000000040000B0C0000000000000001085
+:1037C0000000D6B000000000000000040000D6B4E5
+:1037D00000000000000000040000D6B80000000057
+:1037E000000000040000D6BC00000000000000043F
+:1037F0000000D6B000000000000000100000D34818
+:1038000000000000000000080000D3580000000085
+:103810000000008000000010000000000000000018
+:103820000000D35800000000000000080000000065
+:0838300006020900000000007F
+:00000001FF
diff --git a/firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex b/firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex
deleted file mode 100644
index aef9aa62242..00000000000
--- a/firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex
+++ /dev/null
@@ -1,15456 +0,0 @@
-:1000000000005310000000680000070C000053803F
-:100010000000318000005A90000000B000008C18F1
-:100020000000C13400008CD0000000D800014E0850
-:100030000000F1F000014EE800000074000240E012
-:100040000000525C00024158000000B8000293B862
-:100050000001213C0002947800000FFC0003B5B8B9
-:10006000000000040003C5B8020400480000000FAF
-:1000700002040054000000450204005C0000000679
-:100080000204007000000004020400780000000078
-:100090000204007C121700000204008022170000F6
-:1000A00002040084321700000604008800000005E6
-:1000B0000204009C12150000020400A0221500009A
-:1000C000020400A432150000060400A80000000489
-:1000D000020400B802100000020400BC001000007E
-:1000E000020400C010100000020400C42010000030
-:1000F000020400C830100000020400CC40100000D0
-:10010000060400D000000003020400DC0010000020
-:10011000020400E012140000020400E422140000B3
-:10012000020400E832140000020400EC4214000053
-:10013000060400F000000003010401240000000098
-:1001400001040128000000000104012C000000004F
-:100150000104013000000000020401D00000890603
-:1001600002040258000000360204025C000000365F
-:10017000020402600810000002040264081000007B
-:1001800002040004000000FF02040008000000FF59
-:100190000204000C000000FF02040010000000FF39
-:1001A000020400140000007F02040018000000FF99
-:1001B0000204001C000000FF02040020000000FFF9
-:1001C000020400240000003E020400280000000099
-:1001D0000204002C0000003F020400300000003F39
-:1001E000020400340000003F020400380000003F19
-:1001F0000204003C0000003F020400400000003FF9
-:10020000020400440000003F020404CC000000018E
-:1002100002042008000002110204200C0000020069
-:10022000020420100000020402042014000002193D
-:100230000204201C0000FFFF020420200000FFFF3A
-:10024000020420240000FFFF020420280000FFFF1A
-:1002500002042038000000200604203C0000000FAB
-:1002600002042078000000210604207C0000000F1A
-:10027000020420B800000001060420BC0000000FAA
-:10028000020420F800000001060420FC0000003FEA
-:10029000020421F800000001060421FC0000000F08
-:1002A0000204223807FFFFFF0204223C0000007F07
-:1002B0000204224007FFFFFF020422440000003F27
-:1002C00001042248000000000104224C000000004C
-:1002D000010422500000000001042254000000002C
-:1002E00001042258000000000104225C000000000C
-:1002F00001042260000000000104226400000000EC
-:1003000001042268000000000104226C00000000CB
-:1003100001042270000000000104227400000000AB
-:1003200001042278000000000104227C000000008B
-:10033000020422C00000FFFF020422C40000FFFFED
-:10034000020422C80000FFFF020422CC0000FFFFCD
-:100350000C042000000003E80A0420000000000153
-:100360000B042000000000030605400000000D0003
-:100370000205004400000020020500480000003291
-:1003800002050090021500200205009402150020CD
-:1003900002050098000000300205009C08100000D3
-:1003A000020500A000000036020500A40000003095
-:1003B000020500A800000031020500B000000004A2
-:1003C000020500B400000005020500C000000000A6
-:1003D000020500C400000004020500D40000000172
-:1003E00002050114000000010205011C00000001CB
-:1003F00002050120000000020205020400000001C5
-:100400000205020C0000004002050210000000403E
-:100410000205021C00000020020502200000001C52
-:100420000205022400000020060502400000000A28
-:1004300004050280002000000205005000000007B3
-:1004400002050054000000070205005800000000EB
-:100450000205005C000000080205006000000001C9
-:100460000605006400000003020500D80000000635
-:100470000205000400000001020500080000000160
-:100480000205000C00000001020500100000000140
-:100490000205001400000001020500180000000120
-:1004A0000205001C00000001020500200000000100
-:1004B00002050024000000010205002800000001E0
-:1004C0000205002C000000010205003000000001C0
-:1004D00002050034000000010205003800000001A0
-:1004E0000205003C00000001020500400000000180
-:1004F000020500E00000000D020500E80000000019
-:10050000020500F000000000020500F800000000F5
-:10051000020500E40000002D020500EC00000020B0
-:10052000020500F400000020020500FC000000208D
-:10053000020500E00000001D020500E800000010B8
-:10054000020500F000000010020500F80000001095
-:10055000020500E40000003D020500EC0000003050
-:10056000020500F400000030020500FC000000302D
-:10057000020500E00000004D020500E80000004018
-:10058000020500F000000040020500F800000040F5
-:10059000020500E40000006D020500EC00000060B0
-:1005A000020500F400000060020500FC000000608D
-:1005B000020500E00000005D020500E800000050B8
-:1005C000020500F000000050020500F80000005095
-:1005D000020500E40000007D020500EC0000007050
-:1005E000020500F400000070020500FC000000702D
-:1005F0000406100002000020020600DC00000001DA
-:100600000406020000030220020600DC00000000D5
-:100610000718040000AD0000081807D800050223E1
-:10062000071C000029920000071C8000312A0A657F
-:10063000071D000034A316B0071D80002E7A23D9B1
-:10064000071E000003502F78081E07F03F02022506
-:10065000021800BC0000003001180000000000007B
-:10066000011800040000000001180008000000004C
-:100670000118000C0000000001180010000000002C
-:100680000118001400000000021800200000000102
-:1006900002180024000000020218002800000003D5
-:1006A0000218002C000000000218003000000004B6
-:1006B0000218003400000001021800380000000099
-:1006C0000218003C00000001021800400000000475
-:1006D0000218004400000000021800480000000159
-:1006E0000218004C00000003021800500000000037
-:1006F0000218005400000001021800580000000415
-:100700000218005C000000000218006000000001F8
-:1007100002180064000000030218006800000000D6
-:100720000218006C000000010218007000000004B4
-:100730000218007400000000021800780000000495
-:100740000218007C00000003061800800000000270
-:10075000021800A400007FFF021800A8000003FF99
-:1007600002180224000000000218023400000000F9
-:100770000218024C00000000021802E4000000FF12
-:100780000618100000000400021B8BC000000001CE
-:10079000021B800000000034021B80400000001893
-:1007A000021B80800000000C021B80C000000020A3
-:1007B0000C1B8300000864700A1B830000000157B3
-:1007C0000B1B83000000055F0A1B83400000000034
-:1007D0000C1B8340000002260B1B8340000000011D
-:1007E000021B838000086470021B83C00000022685
-:1007F000021B1480000000010A1B1480000000008E
-:10080000021B944000000001061B944800000002F7
-:10081000061A1000000002B3041A1ACC00010227C5
-:10082000061A1AD000000008061A2008000000C8A6
-:10083000061A200000000002041A1BF8009002288B
-:10084000061A371800000004061A371000000002CC
-:10085000061A500000000002061A500800000004AA
-:10086000061A501800000004061A50280000000460
-:10087000061A503800000004061A50480000000410
-:10088000061A505800000004061A506800000004C0
-:10089000061A507800000002041A52C0000202B882
-:1008A000061A405000000006041A4068000202BA0E
-:1008B000041A4040000402BC041A8000000102C077
-:1008C000061A800400000003041A8010000102C10F
-:1008D000061A801400000003041A8020000102C2DE
-:1008E000061A802400000003041A8030000102C3AD
-:1008F000061A803400000003041A8040000102C47C
-:10090000061A804400000003041A8050000102C54A
-:10091000061A805400000003041A8060000102C619
-:10092000061A806400000003041A8070000102C7E8
-:10093000061A807400000003041A8080000102C8B7
-:10094000061A808400000003041A8090000102C986
-:10095000061A809400000003041A80A0000102CA55
-:10096000061A80A400000003041A80B0000102CB24
-:10097000061A80B400000003041A80C0000102CCF3
-:10098000061A80C400000003041A80D0000102CDC2
-:10099000061A80D400000003041A80E0000102CE91
-:1009A000061A80E400000003041A80F0000102CF60
-:1009B000061A80F400000003041A8100000102D02E
-:1009C000061A810400000003041A8110000102D1FC
-:1009D000061A811400000003041A8120000102D2CB
-:1009E000061A812400000003041A8130000102D39A
-:1009F000061A813400000003041A8140000102D469
-:100A0000061A814400000003041A8150000102D537
-:100A1000061A815400000003041A8160000102D606
-:100A2000061A816400000003041A8170000102D7D5
-:100A3000061A817400000003041A8180000102D8A4
-:100A4000061A818400000003041A8190000102D973
-:100A5000061A819400000003041A81A0000102DA42
-:100A6000061A81A400000003041A81B0000102DB11
-:100A7000061A81B400000003041A81C0000102DCE0
-:100A8000061A81C400000003041A81D0000102DDAF
-:100A9000061A81D400000003041A81E0000102DE7E
-:100AA000061A81E400000003041A81F0000102DF4D
-:100AB000061A81F400000003041A8200000102E01B
-:100AC000061A820400000003041A8210000102E1E9
-:100AD000061A821400000003041A8220000102E2B8
-:100AE000061A822400000003041A8230000102E387
-:100AF000061A823400000003041A8240000102E456
-:100B0000061A824400000003041A8250000102E524
-:100B1000061A825400000003041A8260000102E6F3
-:100B2000061A826400000003041A8270000102E7C2
-:100B3000061A827400000003041A8280000102E891
-:100B4000061A828400000003041A8290000102E960
-:100B5000061A829400000003041A82A0000102EA2F
-:100B6000061A82A400000003041A82B0000102EBFE
-:100B7000061A82B400000003041A82C0000102ECCD
-:100B8000061A82C400000003041A82D0000102ED9C
-:100B9000061A82D400000003041A82E0000102EE6B
-:100BA000061A82E400000003041A82F0000102EF3A
-:100BB000061A82F400000003041A8300000102F008
-:100BC000061A830400000003041A8310000102F1D6
-:100BD000061A831400000003041A8320000102F2A5
-:100BE000061A832400000003041A8330000102F374
-:100BF000061A833400000003041A8340000102F443
-:100C0000061A834400000003041A8350000102F511
-:100C1000061A835400000003041A8360000102F6E0
-:100C2000061A836400000003041A8370000102F7AF
-:100C3000061A837400000003041A8380000102F87E
-:100C4000061A838400000003041A8390000102F94D
-:100C5000061A839400000003041A83A0000102FA1C
-:100C6000061A83A400000003041A83B0000102FBEB
-:100C7000061A83B400000003041A83C0000102FCBA
-:100C8000061A83C400000003041A83D0000102FD89
-:100C9000061A83D400000003041A83E0000102FE58
-:100CA000061A83E400000003041A83F0000102FF27
-:100CB000061A83F400000003041A840000010300F4
-:100CC000061A840400000003041A841000010301C2
-:100CD000061A841400000003041A84200001030291
-:100CE000061A842400000003041A84300001030360
-:100CF000061A843400000003041A8440000103042F
-:100D0000061A844400000003041A845000010305FD
-:100D1000061A845400000003041A846000010306CC
-:100D2000061A846400000003041A8470000103079B
-:100D3000061A847400000003041A8480000103086A
-:100D4000061A848400000003041A84900001030939
-:100D5000061A849400000003041A84A00001030A08
-:100D6000061A84A400000003041A84B00001030BD7
-:100D7000061A84B400000003041A84C00001030CA6
-:100D8000061A84C400000003041A84D00001030D75
-:100D9000061A84D400000003041A84E00001030E44
-:100DA000061A84E400000003041A84F00001030F13
-:100DB000061A84F400000003041A850000010310E1
-:100DC000061A850400000003041A851000010311AF
-:100DD000061A851400000003041A8520000103127E
-:100DE000061A852400000003041A8530000103134D
-:100DF000061A853400000003041A8540000103141C
-:100E0000061A854400000003041A855000010315EA
-:100E1000061A855400000003041A856000010316B9
-:100E2000061A856400000003041A85700001031788
-:100E3000061A857400000003041A85800001031857
-:100E4000061A858400000003041A85900001031926
-:100E5000061A859400000003041A85A00001031AF5
-:100E6000061A85A400000003041A85B00001031BC4
-:100E7000061A85B400000003041A85C00001031C93
-:100E8000061A85C400000003041A85D00001031D62
-:100E9000061A85D400000003041A85E00001031E31
-:100EA000061A85E400000003041A85F00001031F00
-:100EB000061A85F400000003041A860000010320CE
-:100EC000061A860400000003041A8610000103219C
-:100ED000061A861400000003041A8620000103226B
-:100EE000061A862400000003041A8630000103233A
-:100EF000061A863400000003041A86400001032409
-:100F0000061A864400000003041A865000010325D7
-:100F1000061A865400000003041A866000010326A6
-:100F2000061A866400000003041A86700001032775
-:100F3000061A867400000003041A86800001032844
-:100F4000061A868400000003041A86900001032913
-:100F5000061A869400000003041A86A00001032AE2
-:100F6000061A86A400000003041A86B00001032BB1
-:100F7000061A86B400000003041A86C00001032C80
-:100F8000061A86C400000003041A86D00001032D4F
-:100F9000061A86D400000003041A86E00001032E1E
-:100FA000061A86E400000003041A86F00001032FED
-:100FB000061A86F400000003041A870000010330BB
-:100FC000061A870400000003041A87100001033189
-:100FD000061A871400000003041A87200001033258
-:100FE000061A872400000003041A87300001033327
-:100FF000061A873400000003041A874000010334F6
-:10100000061A874400000003041A875000010335C4
-:10101000061A875400000003041A87600001033693
-:10102000061A876400000003041A87700001033762
-:10103000061A877400000003041A87800001033831
-:10104000061A878400000003041A87900001033900
-:10105000061A879400000003041A87A00001033ACF
-:10106000061A87A400000003041A87B00001033B9E
-:10107000061A87B400000003041A87C00001033C6D
-:10108000061A87C400000003041A87D00001033D3C
-:10109000061A87D400000003041A87E00001033E0B
-:1010A000061A87E400000003041A87F00001033FDA
-:1010B000061A87F400000003041A880000010340A8
-:1010C000061A880400000003041A88100001034176
-:1010D000061A881400000003041A88200001034245
-:1010E000061A882400000003041A88300001034314
-:1010F000061A883400000003041A884000010344E3
-:10110000061A884400000003041A885000010345B1
-:10111000061A885400000003041A88600001034680
-:10112000061A886400000003041A8870000103474F
-:10113000061A887400000003041A8880000103481E
-:10114000061A888400000003041A889000010349ED
-:10115000061A889400000003041A88A00001034ABC
-:10116000061A88A400000003041A88B00001034B8B
-:10117000061A88B400000003041A88C00001034C5A
-:10118000061A88C400000003041A88D00001034D29
-:10119000061A88D400000003041A88E00001034EF8
-:1011A000061A88E400000003041A88F00001034FC7
-:1011B000061A88F400000003041A89000001035095
-:1011C000061A890400000003041A89100001035163
-:1011D000061A891400000003041A89200001035232
-:1011E000061A892400000003041A89300001035301
-:1011F000061A893400000003041A894000010354D0
-:10120000061A894400000003041A8950000103559E
-:10121000061A895400000003041A8960000103566D
-:10122000061A896400000003041A8970000103573C
-:10123000061A897400000003041A8980000103580B
-:10124000061A898400000003041A899000010359DA
-:10125000061A899400000003041A89A00001035AA9
-:10126000061A89A400000003041A89B00001035B78
-:10127000061A89B400000003041A89C00001035C47
-:10128000061A89C400000003041A89D00001035D16
-:10129000061A89D400000003041A89E00001035EE5
-:1012A000061A89E400000003041A89F00001035FB4
-:1012B000061A89F400000003041A8A000001036082
-:1012C000061A8A0400000003041A8A100001036150
-:1012D000061A8A1400000003041A8A20000103621F
-:1012E000061A8A2400000003041A8A3000010363EE
-:1012F000061A8A3400000003041A8A4000010364BD
-:10130000061A8A4400000003041A8A50000103658B
-:10131000061A8A5400000003041A8A60000103665A
-:10132000061A8A6400000003041A8A700001036729
-:10133000061A8A7400000003041A8A8000010368F8
-:10134000061A8A8400000003041A8A9000010369C7
-:10135000061A8A9400000003041A8AA00001036A96
-:10136000061A8AA400000003041A8AB00001036B65
-:10137000061A8AB400000003041A8AC00001036C34
-:10138000061A8AC400000003041A8AD00001036D03
-:10139000061A8AD400000003041A8AE00001036ED2
-:1013A000061A8AE400000003041A8AF00001036FA1
-:1013B000061A8AF400000003041A8B00000103706F
-:1013C000061A8B0400000003041A8B10000103713D
-:1013D000061A8B1400000003041A8B20000103720C
-:1013E000061A8B2400000003041A8B3000010373DB
-:1013F000061A8B3400000003041A8B4000010374AA
-:10140000061A8B4400000003041A8B500001037578
-:10141000061A8B5400000003041A8B600001037647
-:10142000061A8B6400000003041A8B700001037716
-:10143000061A8B7400000003041A8B8000010378E5
-:10144000061A8B8400000003041A8B9000010379B4
-:10145000061A8B9400000003041A8BA00001037A83
-:10146000061A8BA400000003041A8BB00001037B52
-:10147000061A8BB400000003041A8BC00001037C21
-:10148000061A8BC400000003041A8BD00001037DF0
-:10149000061A8BD400000003041A8BE00001037EBF
-:1014A000061A8BE400000003041A8BF00001037F8E
-:1014B000061A8BF400000003041A8C00000103805C
-:1014C000061A8C0400000003041A8C10000103812A
-:1014D000061A8C1400000003041A8C2000010382F9
-:1014E000061A8C2400000003041A8C3000010383C8
-:1014F000061A8C3400000003041A8C400001038497
-:10150000061A8C4400000003041A8C500001038565
-:10151000061A8C5400000003041A8C600001038634
-:10152000061A8C6400000003041A8C700001038703
-:10153000061A8C7400000003041A8C8000010388D2
-:10154000061A8C8400000003041A8C9000010389A1
-:10155000061A8C9400000003041A8CA00001038A70
-:10156000061A8CA400000003041A8CB00001038B3F
-:10157000061A8CB400000003041A8CC00001038C0E
-:10158000061A8CC400000003041A8CD00001038DDD
-:10159000061A8CD400000003041A8CE00001038EAC
-:1015A000061A8CE400000003041A8CF00001038F7B
-:1015B000061A8CF400000003041A8D000001039049
-:1015C000061A8D0400000003041A8D100001039117
-:1015D000061A8D1400000003041A8D2000010392E6
-:1015E000061A8D2400000003041A8D3000010393B5
-:1015F000061A8D3400000003041A8D400001039484
-:10160000061A8D4400000003041A8D500001039552
-:10161000061A8D5400000003041A8D600001039621
-:10162000061A8D6400000003041A8D7000010397F0
-:10163000061A8D7400000003041A8D8000010398BF
-:10164000061A8D8400000003041A8D90000103998E
-:10165000061A8D9400000003041A8DA00001039A5D
-:10166000061A8DA400000003041A8DB00001039B2C
-:10167000061A8DB400000003041A8DC00001039CFB
-:10168000061A8DC400000003041A8DD00001039DCA
-:10169000061A8DD400000003041A8DE00001039E99
-:1016A000061A8DE400000003041A8DF00001039F68
-:1016B000061A8DF400000003041A8E00000103A036
-:1016C000061A8E0400000003041A8E10000103A104
-:1016D000061A8E1400000003041A8E20000103A2D3
-:1016E000061A8E2400000003041A8E30000103A3A2
-:1016F000061A8E3400000003041A8E40000103A471
-:10170000061A8E4400000003041A8E50000103A53F
-:10171000061A8E5400000003041A8E60000103A60E
-:10172000061A8E6400000003041A8E70000103A7DD
-:10173000061A8E7400000003041A8E80000103A8AC
-:10174000061A8E8400000003041A8E90000103A97B
-:10175000061A8E9400000003041A8EA0000103AA4A
-:10176000061A8EA400000003041A8EB0000103AB19
-:10177000061A8EB400000003041A8EC0000103ACE8
-:10178000061A8EC400000003041A8ED0000103ADB7
-:10179000061A8ED400000003041A8EE0000103AE86
-:1017A000061A8EE400000003041A8EF0000103AF55
-:1017B000061A8EF400000003041A8F00000103B023
-:1017C000061A8F0400000003041A8F10000103B1F1
-:1017D000061A8F1400000003041A8F20000103B2C0
-:1017E000061A8F2400000003041A8F30000103B38F
-:1017F000061A8F3400000003041A8F40000103B45E
-:10180000061A8F4400000003041A8F50000103B52C
-:10181000061A8F5400000003041A8F60000103B6FB
-:10182000061A8F6400000003041A8F70000103B7CA
-:10183000061A8F7400000003041A8F80000103B899
-:10184000061A8F8400000003041A8F90000103B968
-:10185000061A8F9400000003041A8FA0000103BA37
-:10186000061A8FA400000003041A8FB0000103BB06
-:10187000061A8FB400000003041A8FC0000103BCD5
-:10188000061A8FC400000003041A8FD0000103BDA4
-:10189000061A8FD400000003041A8FE0000103BE73
-:1018A000061A8FE400000007041A62C0002003BF7C
-:1018B000061A1AF000000042061AAF0000000008E5
-:1018C000061AE00000000540061AD0000000007271
-:1018D000061AD24800000010061AD6B000000020F8
-:1018E000061AD47000000090061AD46800000002A6
-:1018F000061AA000000001C4061A30000000001003
-:10190000061A308000000010061A31000000001096
-:10191000061A318000000010061A33000000001281
-:10192000061A339000000070061AD4580000000216
-:10193000061AD34800000002061AD35800000020FF
-:10194000061AA710000001C4061A3040000000105B
-:10195000061A30C000000010061A314000000010C6
-:10196000061A31C000000010061A334800000012A9
-:10197000061A355000000070061AD46000000002FC
-:10198000061AD35000000002061AD3D80000002027
-:10199000021AAE2000000000061A500000000002EB
-:1019A000061A508000000012041A4000000203DFF3
-:1019B000041A63C0000203E1061A7000000000046C
-:1019C000061A320000000008021AAE2400000000CF
-:1019D000061A501000000002061A50C8000000123B
-:1019E000041A4008000203E3041A63C8000203E576
-:1019F000061A701000000004061A322000000008C9
-:101A0000021AAE2800000000061A50200000000252
-:101A1000061A511000000012041A4010000203E7D9
-:101A2000041A63D0000203E9061A702000000004C3
-:101A3000061A324000000008021AAE2C0000000016
-:101A4000061A503000000002061A51580000001219
-:101A5000041A4018000203EB041A63D8000203EDD5
-:101A6000061A703000000004061A326000000008F8
-:101A7000021AAE3000000000061A504000000002BA
-:101A8000061A51A000000012041A4020000203EFC1
-:101A9000041A63E0000203F1061A7040000000041B
-:101AA000061A328000000008021AAE34000000005E
-:101AB000061A505000000002061A51E800000012F9
-:101AC000041A4028000203F3041A63E8000203F535
-:101AD000061A705000000004061A32A00000000828
-:101AE000021AAE3800000000061A50600000000222
-:101AF000061A523000000012041A4030000203F7A8
-:101B0000041A63F0000203F9061A70600000000472
-:101B1000061A32C000000008021AAE3C00000000A5
-:101B2000061A507000000002061A527800000012D7
-:101B3000041A4038000203FB041A63F8000203FD94
-:101B4000061A707000000004061A32E00000000857
-:101B50000200A2A4000002090200A270000000001E
-:101B60000200A274000000000200A2700000000049
-:101B70000200A274000000000200A2700000000039
-:101B80000200A274000000000200A2700000000029
-:101B90000200A27400000000020100B40000000175
-:101BA000020100B800000001020100CC00000001A9
-:101BB000020100D000000001020100DC0000000171
-:101BC0000201010000000001020101040000000107
-:101BD0000201007C003000000201008400000028A7
-:101BE0000201008C0000000002010130000000042E
-:101BF0000201025C00000001020103280000000055
-:101C0000020160580000FFFF020160700000000741
-:101C10000201055400000030020100C40000000170
-:101C2000020100F800000001020100F000000001C4
-:101C3000020100800030000002010088000000283E
-:101C400002010090000000000201013400000004C5
-:101C5000020102DC000000010201032C0000000070
-:101C60000201605C0000FFFF0201607400000007D9
-:101C70000201056400000030020100C800000001FC
-:101C8000020100FC00000001020100F4000000015C
-:101C9000020C100000000028020C200800000211B5
-:101CA000020C200C00000200020C201000000204B4
-:101CB000020C201C0000FFFF020C20200000FFFF90
-:101CC000020C20240000FFFF020C20280000FFFF70
-:101CD000020C203800000000020C203C00000037FD
-:101CE000020C204000000021020C204400000020D3
-:101CF000060C20480000001D020C20BC0000000162
-:101D0000060C20C00000003F020C21BC00000001B6
-:101D1000020C21C000000001020C21C400000001DF
-:101D2000060C21C80000001C020C223807FFFFFF30
-:101D3000020C223C0000007F020C224007FFFFFF44
-:101D4000020C22440000003F010C22480000000069
-:101D5000010C224C00000000010C22500000000089
-:101D6000010C225400000000010C22580000000069
-:101D7000010C225C00000000010C22600000000049
-:101D8000010C226400000000010C22680000000029
-:101D9000010C226C00000000010C22700000000009
-:101DA000010C227400000000010C227800000000E9
-:101DB000010C227C00000000020C22D80000FFFF72
-:101DC000020C22DC0000FFFF020C22E00000FFFFFB
-:101DD000020C22E40000FFFF0C0C2000000003E8CE
-:101DE0000A0C2000000000010B0C20000000000382
-:101DF000020C400800001011020C400C0000100002
-:101E0000020C401000001004020C401400001021CD
-:101E1000020C401C0000FFFF020C40200000FFFFEE
-:101E2000020C40240000FFFF020C40280000FFFFCE
-:101E3000020C403800000046020C403C0000000C40
-:101E4000060C404000000002020C40480000001850
-:101E5000020C404C000000F0060C40500000001F37
-:101E6000020C40CC00000001060C40D00000003AFB
-:101E7000020C41B800000001060C41BC0000000348
-:101E8000020C41C800000001020C41CC000000011E
-:101E9000060C41D00000001A020C423807FFFFFF79
-:101EA000020C423C0000007F020C424007FFFFFF93
-:101EB000020C42440000003F010C424800000000B8
-:101EC000010C424C00000000010C425000000000D8
-:101ED000010C425400000000010C425800000000B8
-:101EE000010C425C00000000010C42600000000098
-:101EF000010C426400000000010C42680000000078
-:101F0000010C426C00000000010C42700000000057
-:101F1000010C427400000000010C42780000000037
-:101F2000010C427C00000000010C42800000000017
-:101F3000020C42D80000FFFF020C42DC0000FFFF51
-:101F4000020C42E00000FFFF020C42E40000FFFF31
-:101F50000C0C4000000003E80A0C400000000001E7
-:101F60000B0C400000000003060D400000000A00BA
-:101F7000020D004400000032020D008C021500200A
-:101F8000020D009002150020020D009408100000C0
-:101F9000020D009800000036020D00A000000000B5
-:101FA000020D00A400000004020D00A800000004BF
-:101FB000060D00AC00000002020D00B80000000297
-:101FC000020D00C000000001020D00C80000000268
-:101FD000020D00CC00000002020D015C00000001B7
-:101FE000020D016400000001020D01680000000202
-:101FF000020D020400000001020D020C000000208E
-:10200000020D021000000040020D0214000000400A
-:10201000020D022000000003020D0224000000183F
-:10202000060D028000000012040D0300001803FFDB
-:10203000060D03600000000C020D004C00000001C2
-:10204000020D005000000002020D005400000000CC
-:10205000020D005800000008060D005C000000049E
-:10206000020D00C400000004020D00040000000185
-:10207000020D000800000001020D000C000000012C
-:10208000020D001000000001020D0014000000010C
-:10209000020D001800000001020D001C00000001EC
-:1020A000020D002000000001020D002400000001CC
-:1020B000020D002800000001020D002C00000001AC
-:1020C000020D003000000001020D0034000000018C
-:1020D000020D003800000001020D003C000000016C
-:1020E000020D011400000009020D011C0000000A8D
-:1020F000020D012400000000020D012C0000000070
-:10210000020D013400000000020D013C0000000B34
-:10211000020D014400000000020D0118000000291A
-:10212000020D01200000002A020D012800000020FD
-:10213000020D013000000020020D013800000020D7
-:10214000020D01400000002B020D0148000000209C
-:10215000020D011400000019020D011C0000001AFC
-:10216000020D012400000010020D012C00000010DF
-:10217000020D013400000010020D013C0000001BA4
-:10218000020D014400000010020D0118000000398A
-:10219000020D01200000003A020D0128000000306D
-:1021A000020D013000000030020D01380000003047
-:1021B000020D01400000003B020D0148000000300C
-:1021C000020D011400000049020D011C0000004A2C
-:1021D000020D012400000040020D012C000000400F
-:1021E000020D013400000040020D013C0000004BD4
-:1021F000020D014400000040020D011800000069BA
-:10220000020D01200000006A020D0128000000609C
-:10221000020D013000000060020D01380000006076
-:10222000020D01400000006B020D0148000000603B
-:10223000020D011400000059020D011C0000005A9B
-:10224000020D012400000050020D012C000000507E
-:10225000020D013400000050020D013C0000005B43
-:10226000020D014400000050020D01180000007929
-:10227000020D01200000007A020D0128000000700C
-:10228000020D013000000070020D013800000070E6
-:10229000020D01400000007B020D014800000070AB
-:1022A000060E200000000800020E004C0000003264
-:1022B000020E009402150020020E00980215002064
-:1022C000020E009C00000030020E00A0081000006A
-:1022D000020E00A400000036020E00A8000000302C
-:1022E000020E00AC00000031020E00B4000000033A
-:1022F000020E00B800000000020E00C40000000042
-:10230000020E00CC00000006020E00D80000000102
-:10231000020E014400000001020E014C0000000109
-:10232000020E015000000002020E02040000000133
-:10233000020E020C00000040020E021000000040DD
-:10234000020E021C00000004020E02200000002009
-:10235000020E02240000000E020E02280000001BE4
-:10236000060E030000000012040E0280001B04177A
-:10237000060E02EC00000005020E00540000000CE6
-:10238000020E00580000000C020E005C000000006D
-:10239000020E006000000010020E00640000001039
-:1023A000060E006800000003020E00DC00000003BF
-:1023B000020E000400000001020E000800000001EF
-:1023C000020E000C00000001020E001000000001CF
-:1023D000020E001400000001020E001800000001AF
-:1023E000020E001C00000001020E0020000000018F
-:1023F000020E002400000001020E0028000000016F
-:10240000020E002C00000001020E0030000000014E
-:10241000020E003400000001020E0038000000012E
-:10242000020E003C00000001020E0040000000010E
-:10243000020E004400000001020E01100000000F17
-:10244000020E011800000000020E01200000000032
-:10245000020E012800000000020E01140000002FEF
-:10246000020E011C00000020020E012400000020CA
-:10247000020E012C00000020020E01100000001FBF
-:10248000020E011800000010020E012000000010D2
-:10249000020E012800000010020E01140000003F8F
-:1024A000020E011C00000030020E0124000000306A
-:1024B000020E012C00000030020E01100000004F3F
-:1024C000020E011800000040020E01200000004032
-:1024D000020E012800000040020E01140000006FEF
-:1024E000020E011C00000060020E012400000060CA
-:1024F000020E012C00000060020E01100000005FBF
-:10250000020E011800000050020E012000000050D1
-:10251000020E012800000050020E01140000007F8E
-:10252000020E011C00000070020E01240000007069
-:10253000020E012C000000700730040000D60000DD
-:10254000083007D80005043207340000322A0000A2
-:102550000734800031300C8B0735000038D018D894
-:10256000073580002F82270D07360000263632EE11
-:102570000836710031E00434023000BC0000003045
-:1025800001300000000000000130000400000000E5
-:1025900001300008000000000130000C00000000C5
-:1025A00001300010000000000130001400000000A5
-:1025B0000230002000000001023000240000000270
-:1025C00002300028000000030230002C0000000050
-:1025D000023000300000000402300034000000012E
-:1025E00002300038000000000230003C0000000112
-:1025F00002300040000000040230004400000000EF
-:1026000002300048000000010230004C00000003CE
-:1026100002300050000000000230005400000001B1
-:1026200002300058000000040230005C000000008E
-:10263000023000600000000102300064000000036E
-:1026400002300068000000000230006C0000000151
-:10265000023000700000000402300074000000002E
-:1026600002300078000000040230007C000000030B
-:102670000630008000000002023000A400007FFF4E
-:10268000023000A8000003FF023002240000000016
-:1026900002300234000000000230024C0000000052
-:1026A000023002E40000FFFF0630200000000800B6
-:1026B00002338BC000000001023380000000001ACA
-:1026C000023380400000004E023380800000001082
-:1026D000023380C0000000200C33830000086470C7
-:1026E0000A338300000001570B3383000000055FAD
-:1026F0000A338340000000000C33834000000226B0
-:102700000B338340000000010233838000086470B3
-:10271000023383C00000022602331480000000014F
-:102720000A3314800000000006328000000001021D
-:1027300006322008000000C8063220000000000217
-:1027400004328520008F04360632875C00000009C1
-:1027500006323EB00000000606323ED00000000205
-:1027600006323E800000000A04323EA8000204C582
-:1027700006323E00000000200632500000000940F2
-:102780000632400000000004043294C0000204C776
-:1027900006324110000000020632D0000000007036
-:1027A0000632DB00000000D40632DEA0000000028A
-:1027B0000632E00000000800063324000000011883
-:1027C0000632100000000188063250000000002090
-:1027D00006325100000000200632520000000020A6
-:1027E0000632530000000020063254000000002092
-:1027F000063255000000002006325600000000207E
-:102800000632570000000020063258000000002069
-:10281000063259000000002006325A000000002055
-:1028200006325B000000002006325C000000002041
-:1028300006325D000000002006325E00000000202D
-:1028400006325F0000000020063284F00000000223
-:1028500004328500000204C9063285080000000227
-:102860000632DE90000000020633286000000118E6
-:102870000632162000000188063250800000002039
-:1028800006325180000000200632528000000020F5
-:1028900006325380000000200632548000000020E1
-:1028A00006325580000000200632568000000020CD
-:1028B00006325780000000200632588000000020B9
-:1028C000063259800000002006325A8000000020A5
-:1028D00006325B800000002006325C800000002091
-:1028E00006325D800000002006325E80000000207D
-:1028F00006325F8000000020063284F800000002EB
-:1029000004328510000204CB063285180000000254
-:102910000632DE98000000020232845000000000FF
-:102920000632401000000002023284540000000011
-:1029300006324020000000020232845800000000ED
-:1029400006324030000000020232845C00000000C9
-:1029500006324040000000020232846000000000A5
-:102960000632405000000002023284640000000081
-:10297000063240600000000202328468000000005D
-:1029800006324070000000020232846C0000000039
-:10299000063240800000000207200400007300009F
-:1029A00008200780001004CD072400002AF1000051
-:1029B0000724800027670ABD0824D35063FC04CF96
-:1029C000022000BC000000300120000000000000D8
-:1029D00001200004000000000120000800000000A9
-:1029E0000120000C00000000012000100000000089
-:1029F000012000140000000002200020000000015F
-:102A00000220002400000002022000280000000331
-:102A10000220002C00000000022000300000000412
-:102A200002200034000000010220003800000000F5
-:102A30000220003C000000010220004000000004D1
-:102A400002200044000000000220004800000001B5
-:102A50000220004C00000003022000500000000093
-:102A60000220005400000001022000580000000471
-:102A70000220005C00000000022000600000000155
-:102A80000220006400000003022000680000000033
-:102A90000220006C00000001022000700000000411
-:102AA00002200074000000000220007800000004F2
-:102AB0000220007C000000030620008000000002CD
-:102AC000022000A400007FFF022000A8000003FFF6
-:102AD0000220022400000000022002340000000056
-:102AE0000220024C00000000022002E40000FFFF70
-:102AF000062020000000080002238BC00000000117
-:102B00000223800000000010022380400000001219
-:102B10000223808000000030022380C00000000EED
-:102B20000C238300000864700A238300000001570F
-:102B30000B2383000000055F0A2383400000000090
-:102B40000C238340000002260B2383400000000179
-:102B50000223838000086470022383C000000226E1
-:102B600002231480000000010A23148000000000EA
-:102B7000062210000000004206222008000000C8C3
-:102B800006222000000000020622B00000000330F0
-:102B90000622F400000000530422F54C000104D189
-:102BA0000622F550000000030422F55C000104D267
-:102BB0000622F560000000030422F56C000104D336
-:102BC0000622F570000000030422F57C000104D405
-:102BD0000622F580000000030422F58C000104D5D4
-:102BE0000622F590000000030422F59C000104D6A3
-:102BF0000622F5A0000000030422F5AC000104D772
-:102C00000622F5B0000000030422F5BC000104D840
-:102C10000622F5C0000000460622E2000000044043
-:102C200004221240009004D906223000000000C0A7
-:102C30000622670000000100062290000000040048
-:102C400004226B0800200569062211F0000000062E
-:102C50000422120800060589062212200000000244
-:102C600006224000000005C00622C0000000000649
-:102C70000422C0180006058F0622C0300000000A9A
-:102C80000422C058000605950622C0700000000A04
-:102C90000422C0980006059B0622C0B00000000A6E
-:102CA0000422C0D8000605A10622C0F00000000AD8
-:102CB0000422C118000605A70622C1300000000A40
-:102CC0000422C158000605AD0622C1700000000AAA
-:102CD0000422C198000605B30622C1B00000000A14
-:102CE0000422C1D8000605B90622C1F00000000A7E
-:102CF0000422C218000605BF0622C2300000000AE6
-:102D00000422C258000605C50622C2700000000A4F
-:102D10000422C298000605CB0622C2B00000000AB9
-:102D20000422C2D8000605D10622C2F00000000A23
-:102D30000422C318000605D70622C3300000000A8B
-:102D40000422C358000605DD0622C3700000000AF5
-:102D50000422C398000605E30622C3B00000000A5F
-:102D60000422C3D8000605E90622C3F00000000AC9
-:102D70000422C418000605EF0622C4300000000A31
-:102D80000422C458000605F50622C4700000000A9B
-:102D90000422C498000605FB0622C4B00000000A05
-:102DA0000422C4D8000606010622C4F00000000A6E
-:102DB0000422C518000606070622C5300000000AD6
-:102DC0000422C5580006060D0622C5700000000A40
-:102DD0000422C598000606130622C5B00000000AAA
-:102DE0000422C5D8000606190622C5F00000000A14
-:102DF0000422C6180006061F0622C6300000000A7C
-:102E00000422C658000606250622C6700000000AE5
-:102E10000422C6980006062B0622C6B00000000A4F
-:102E20000422C6D8000606310622C6F00000000AB9
-:102E30000422C718000606370622C7300000000A21
-:102E40000422C7580006063D0622C7700000000A8B
-:102E50000422C798000606430622C7B00000000AF5
-:102E60000422C7D8000606490622C7F00000000A5F
-:102E70000422C8180006064F0622C8300000000AC7
-:102E80000422C858000606550622C8700000000A31
-:102E90000422C8980006065B0622C8B00000000A9B
-:102EA0000422C8D8000606610622C8F00000000A05
-:102EB0000422C918000606670622C9300000000A6D
-:102EC0000422C9580006066D0622C9700000000AD7
-:102ED0000422C998000606730622C9B00000000A41
-:102EE0000422C9D8000606790622C9F00000000AAB
-:102EF0000422CA180006067F0622CA300000000A13
-:102F00000422CA58000606850622CA700000000A7C
-:102F10000422CA980006068B0622CAB00000000AE6
-:102F20000422CAD8000606910622CAF00000000A50
-:102F30000422CB18000606970622CB300000000AB8
-:102F40000422CB580006069D0622CB700000000A22
-:102F50000422CB98000606A30622CBB00000000A8C
-:102F60000422CBD8000606A90622CBF00000000AF6
-:102F70000422CC18000606AF0622CC300000000A5E
-:102F80000422CC58000606B50622CC700000000AC8
-:102F90000422CC98000606BB0622CCB00000000A32
-:102FA0000422CCD8000606C10622CCF00000000A9C
-:102FB0000422CD18000606C70622CD300000000A04
-:102FC0000422CD58000606CD0622CD700000000A6E
-:102FD0000422CD98000606D30622CDB00000000AD8
-:102FE0000422CDD8000606D90622CDF00000000A42
-:102FF0000422CE18000606DF0622CE300000000AAA
-:103000000422CE58000606E50622CE700000000A13
-:103010000422CE98000606EB0622CEB00000000A7D
-:103020000422CED8000606F10622CEF00000000AE7
-:103030000422CF18000606F70622CF300000000A4F
-:103040000422CF58000606FD0622CF700000000AB9
-:103050000422CF98000607030622CFB00000000A22
-:103060000422CFD8000607090622CFF00000000A8C
-:103070000422D0180006070F0622D0300000000AF4
-:103080000422D058000607150622D0700000000A5E
-:103090000422D0980006071B0622D0B00000000AC8
-:1030A0000422D0D8000607210622D0F00000000A32
-:1030B0000422D118000607270622D1300000000A9A
-:1030C0000422D1580006072D0622D1700000000A04
-:1030D0000422D198000607330622D1B00000000A6E
-:1030E0000422D1D8000607390622D1F00000000AD8
-:1030F0000422D2180006073F0622D2300000000A40
-:103100000422D258000607450622D2700000000AA9
-:103110000422D2980006074B0622D2B00000000A13
-:103120000422D2D8000607510622D2F00000000A7D
-:103130000422D318000607570622D3300000000AE5
-:103140000422D3580006075D0622D3700000000A4F
-:103150000422D398000607630622D3B00000000AB9
-:103160000422D3D8000607690622D3F00000000A23
-:103170000422D4180006076F0622D4300000000A8B
-:103180000422D458000607750622D4700000000AF5
-:103190000422D4980006077B0622D4B00000000A5F
-:1031A0000422D4D8000607810622D4F00000000AC9
-:1031B0000422D518000607870622D5300000000A31
-:1031C0000422D5580006078D0622D5700000000A9B
-:1031D0000422D598000607930622D5B00000000A05
-:1031E0000422D5D8000607990622D5F00000000A6F
-:1031F0000422D6180006079F0622D6300000000AD7
-:103200000422D658000607A50622D6700000000A40
-:103210000422D698000607AB0622D6B00000000AAA
-:103220000422D6D8000607B10622D6F00000000A14
-:103230000422D718000607B70622D7300000000A7C
-:103240000422D758000607BD0622D7700000000AE6
-:103250000422D798000607C30622D7B00000000A50
-:103260000422D7D8000607C90622D7F00000000ABA
-:103270000422D818000607CF0622D8300000000A22
-:103280000422D858000607D50622D8700000000A8C
-:103290000422D898000607DB0622D8B00000000AF6
-:1032A0000422D8D8000607E10622D8F00000000A60
-:1032B0000422D918000607E70622D9300000000AC8
-:1032C0000422D958000607ED0622D9700000000A32
-:1032D0000422D998000607F30622D9B00000000A9C
-:1032E0000422D9D8000607F90622D9F00000000A06
-:1032F0000422DA18000607FF0622DA300000000A6E
-:103300000422DA58000608050622DA700000000AD6
-:103310000422DA980006080B0622DAB00000000A40
-:103320000422DAD8000608110622DAF00000000AAA
-:103330000422DB18000608170622DB300000000A12
-:103340000422DB580006081D0622DB700000000A7C
-:103350000422DB98000608230622DBB00000000AE6
-:103360000422DBD8000608290622DBF00000000A50
-:103370000422DC180006082F0622DC300000000AB8
-:103380000422DC58000608350622DC700000000A22
-:103390000422DC980006083B0622DCB00000000A8C
-:1033A0000422DCD8000608410622DCF00000000AF6
-:1033B0000422DD18000608470622DD300000000A5E
-:1033C0000422DD580006084D0622DD700000000AC8
-:1033D0000422DD98000608530622DDB00000000A32
-:1033E0000422DDD8000608590622DDF00000000A9C
-:1033F0000422DE180006085F0622DE300000000A04
-:103400000422DE58000608650622DE700000000A6D
-:103410000422DE980006086B0622DEB00000000AD7
-:103420000422DED8000608710622DEF00000000A41
-:103430000422DF18000608770622DF300000000AA9
-:103440000422DF580006087D0622DF700000000A13
-:103450000422DF98000608830622DFB00000000A7D
-:103460000422DFD8000608890622DFF00000000AE7
-:103470000422E0180006088F0622E0300000000A4F
-:103480000422E058000608950622E0700000000AB9
-:103490000422E0980006089B0622E0B00000000A23
-:1034A0000422E0D8000608A10622E0F00000000A8D
-:1034B0000422E118000608A70622E1300000000AF5
-:1034C0000422E158000608AD0622E1700000000A5F
-:1034D0000422E198000608B30622E1B00000000AC9
-:1034E0000422E1D8000608B90622E1F00000000439
-:1034F0000622153800000002062211E80000000232
-:103500000622F3000000000802221148000000001B
-:1035100006225900000000060622330000000002C7
-:1035200006226040000000300622F3200000000860
-:103530000222114C0000000006225918000000066B
-:10354000062233080000000206226100000000305D
-:103550000622F34000000008022211500000000083
-:103560000622593000000006062233100000000237
-:10357000062261C0000000300622F360000000084F
-:1035800002221154000000000622594800000006E3
-:10359000062233180000000206226280000000307C
-:1035A0000622F380000000080222115800000000EB
-:1035B00006225960000000060622332000000002A7
-:1035C00006226340000000300622F3A0000000083D
-:1035D0000222115C0000000006225978000000065B
-:1035E000062233280000000206226400000000309A
-:1035F0000622F3C000000008022211600000000053
-:103600000622599000000006062233300000000216
-:10361000062264C0000000300622F3E0000000082B
-:103620000222116400000000062259A800000006D2
-:1036300006223338000000020622658000000030B8
-:103640000216100000000028021700080000000207
-:103650000217002C000000030217003C00000004C9
-:10366000021700440000000002170048000000029A
-:103670000217004C0000009002170050000000905C
-:103680000217005400800090021700580810000034
-:10369000021700700000000602170078000009FF02
-:1036A0000217007C0000076C021701C4081000001C
-:1036B0000217034400000001021704000000008A02
-:1036C00002170404000000800217040800000081B3
-:1036D0000217040C00000080021704100000008A8A
-:1036E0000217041400000080021704180000008173
-:1036F0000217041C00000080021704300000008A3A
-:103700000217043400000080021704380000008112
-:103710000217043C00000080021704400000008AE9
-:1037200002170444000000800217044800000081D2
-:103730000217044C00000080021704800000008A79
-:103740000217048400000080021704880000008132
-:103750000217048C0000008002170038007C10045F
-:10376000021700040000000F021701EC0000000225
-:10377000021701F400000002021701EC0000000231
-:10378000021701F400000002021701EC0000000221
-:10379000021701F400000002021701EC0000000211
-:1037A000021701F400000002021701EC0000000201
-:1037B000021701F400000002021701EC00000002F1
-:1037C000021701F400000002021701EC00000002E1
-:1037D000021701F400000002021701EC00000002D1
-:1037E000021701F400000002061640240000000247
-:1037F000021640700000001C021642080000000182
-:1038000002164210000000010216422000000001D2
-:10381000021642280000000102164230000000019A
-:103820000216423800000001021642600000000249
-:103830000C16401C0003D0900A16401C0000009C8F
-:103840000B16401C000002710216403000000028D8
-:10385000021640340000002C0216403800000030F0
-:103860000216404400000020021640000000000143
-:10387000021640D8000000010216400800000001B6
-:103880000216400C0000000102164010000000016A
-:1038900002164240000000000216424800000000EC
-:1038A000061642700000000202164250000000009E
-:1038B0000216425800000000061642800000000276
-:1038C00002166008000012140216600C00001200BC
-:1038D00002166010000012040216601C0000FFFFB8
-:1038E000021660200000FFFF021660240000FFFFA8
-:1038F000021660280000FFFF02166038000000205A
-:103900000216603C00000010061660400000000235
-:1039100002166048000000230216604C00000024DC
-:1039200002166050000000250216605400000026B8
-:1039300002166058000000270216605C00000011AB
-:103940000216606000000000021660640000002B98
-:10395000021660680000002C0216606C0000002D4A
-:1039600002166070000000EC021660740000000097
-:1039700002166078000000290216607C0000002A10
-:10398000021660800000002F061660840000000D03
-:10399000021660B800000001061660BC00000008B6
-:1039A000021660DC00000001061660E00000000462
-:1039B000021660F000000001061660F4000000032B
-:1039C0000216610000000001061661040000002DCF
-:1039D000021661B800000001061661BC0000000874
-:1039E000021661DC00000001061661E00000000420
-:1039F000021661F000000001061661F400000003E9
-:103A00000216620000000001061662040000000DAC
-:103A10000216623807FFFFFF0216623C0000007FBB
-:103A20000216624007FFFFFF021662440000003FDB
-:103A300001166248000000000116624C0000000000
-:103A400001166250000000000116625400000000E0
-:103A500001166258000000000116625C00000000C0
-:103A600001166260000000000116626400000000A0
-:103A700001166268000000000116626C0000000080
-:103A80000116627000000000011662740000000060
-:103A900001166278000000000116627C0000000040
-:103AA000011662D400000000021662D80000FFFF79
-:103AB000021662DC0000FFFF021662E00000FFFF5A
-:103AC000021662E40000FFFF0C166000000003E82D
-:103AD0000A166000000000010B16600000000003E1
-:103AE0000216804000000006021680440000000517
-:103AF000021680480000000A0216804C00000005F3
-:103B00000216805400000002021680CC000000045F
-:103B1000021680D000000004021680D400000004C9
-:103B2000021680D800000004021680DC00000004A9
-:103B3000021680E000000004021680E40000000489
-:103B4000021680E800000004021688040000000647
-:103B5000021680300000007C021680340000003D18
-:103B6000021680380000003F0216803C0000009CD6
-:103B70000216E6E8000060000216E6EC00006000B5
-:103B80000216E6F0000060000216E6F40000600095
-:103B900002168234000025E40216823800008000FC
-:103BA00002168094000025E3021681F400000C0840
-:103BB000021681F800000040021681FC000001009E
-:103BC0000216820000000020021682040000001786
-:103BD00002168208000000800216820C000002001B
-:103BE00002168210000000000216823C0000001342
-:103BF00002168220008F008F0216821C008F008F19
-:103C0000021680F0000000070216821801FF01FF73
-:103C10000216821401FF01FF061680F40000000264
-:103C20000216811C0000000502168120000000051C
-:103C300002168124000000050216812800000008F9
-:103C40000216812C000000060216813000000007D9
-:103C50000616813400000004021680FC00000000FB
-:103C600006168144000000020216814C0000000488
-:103C7000021681500000000102168154000000026B
-:103C800002168158000000050216815C0000000544
-:103C90000216816000000005021681640000000524
-:103CA0000216816800000008021681000000000072
-:103CB0000216816C000000060216817000000007E9
-:103CC00006168174000000060216818C00000004B4
-:103CD000021681900000000102168104000000001D
-:103CE000021681940000000202168198000000056F
-:103CF0000216819C00000005021681A0000000054C
-:103D0000021681A400000005021681A80000000828
-:103D1000021681AC00000006021681B00000000708
-:103D2000061681B40000000202168108000000009F
-:103D3000061681BC00000004021681CC00000004BD
-:103D4000021681D000000001021681D4000000029A
-:103D5000021681D800000005021681DC0000000573
-:103D6000021681E0000000050216810C000000042C
-:103D7000021681E400000005021681E80000000838
-:103D8000021681EC00000006021681F00000000718
-:103D900002168110000000010216811400000002CA
-:103DA00002168118000000050216809C0000004CDD
-:103DB000021680A00000004C061680C4000000021D
-:103DC000021680A400000000021680A80000000077
-:103DD000021680AC0000004C061680B00000000502
-:103DE0000216E6F80000020402168240003F003F7F
-:103DF00002168244003F003F061682900000000435
-:103E000002168248008000800216824C00800080EA
-:103E100002168250010001000216825401000100C6
-:103E20000616825800000002021682600040004020
-:103E30000216826400400040021682681E001E00C6
-:103E40000216826C1E001E000216827040004000A6
-:103E500002168274400040000216827880008000C2
-:103E60000216827C800080000216828020002000E2
-:103E700002168284200020000616828800000002BC
-:103E8000021680900000004B021680600000014086
-:103E900002168064000001400616808800000002BF
-:103EA00002168068000000000216806C000000000E
-:103EB00002168070000000C0061680740000000525
-:103EC0000216880C0101010102168810010120046C
-:103ED000021688142008100102168818010101201A
-:103EE0000216881C0101010102168820010120042C
-:103EF00002168824200810010216882801010120DA
-:103F00000216882C200810010216883001010120B9
-:103F100002168834010101010216883801012004CB
-:103F20000216883C20081001021688400101012079
-:103F3000021688440101010102168848010120048B
-:103F40000216E6BC000000000216E6C000000002F7
-:103F50000216E6C4000000040216E6C800000006CF
-:103F60000216E79400000001021680EC000000FF3A
-:103F700002140000000000010215C024000000002F
-:103F80000215C0EC000000010215C0F000000001A5
-:103F90000615C10000000002021400040000000128
-:103FA00002140008000000010214000C00000001CF
-:103FB000021400300000000102140034000000016F
-:103FC0000214004000000001021400440000FFFF42
-:103FD00006140004000000030214000000000000AA
-:103FE000060280000000200002020058000000329B
-:103FF000020200A003150020020200A40315002005
-:10400000020200A801000030020200AC081000000B
-:10401000020200B000000036020200B400000030CE
-:10402000020200B800000031020200BC00000002E1
-:10403000020200C000000005020200C400000002ED
-:10404000020200C800000002020200D000000007C7
-:10405000020200DC00000000020200E00000000597
-:10406000020200E400000003020200F00000000170
-:10407000020200FC00000006020201200000000015
-:104080000202013400000002020201B0000000013F
-:104090000202020C000000010202021400000001F2
-:1040A00002020218000000020202040400000001E3
-:1040B0000202040C00000040020204100000004054
-:1040C0000202041C00000004020204200000002080
-:1040D0000202042400000002020204280000002062
-:1040E000060205000000001204020480002008BF40
-:1040F000020200600000000F0202006400000007DE
-:1041000002020068000000000202006C0000000EC5
-:10411000020200700000000E06020074000000039E
-:10412000020200F40000000402020004000000018A
-:1041300002020008000000010202000C0000000161
-:104140000202001000000001020200140000000141
-:1041500002020018000000010202001C0000000121
-:104160000202002000000001020200240000000101
-:1041700002020028000000010202002C00000001E1
-:1041800002020030000000010202003400000001C1
-:1041900002020038000000010202003C00000001A1
-:1041A0000202004000000001020200440000000181
-:1041B00002020048000000010202004C0000000161
-:1041C000020200500000000102020108000000C8C5
-:1041D0000202011800000002020201C400000000F7
-:1041E000020201CC00000000020201D40000000223
-:1041F000020201DC00000002020201E4000000FFF4
-:10420000020201EC000000FF0202010000000000B9
-:104210000202010C000000C80202011C00000002A2
-:10422000020201C800000000020201D000000000EC
-:10423000020201D800000002020201E000000002B8
-:10424000020201E8000000FF020201F0000000FF8E
-:10425000020201040000002002020108000000C860
-:104260000202011800000002020201C40000000066
-:10427000020201CC00000000020201D40000000292
-:10428000020201DC00000002020201E4000000FF63
-:10429000020201EC000000FF020201000000001019
-:1042A0000202010C000000C80202011C0000000212
-:1042B000020201C800000000020201D0000000005C
-:1042C000020201D800000002020201E00000000228
-:1042D000020201E8000000FF020201F0000000FFFE
-:1042E000020201040000003002020108000000C8C0
-:1042F0000202011800000002020201C400000000D6
-:10430000020201CC00000000020201D40000000201
-:10431000020201DC00000002020201E4000000FFD2
-:10432000020201EC000000FF020201000000004058
-:104330000202010C000000C80202011C0000000281
-:10434000020201C800000000020201D000000000CB
-:10435000020201D800000002020201E00000000297
-:10436000020201E8000000FF020201F0000000FF6D
-:10437000020201040000006002020108000000C8FF
-:104380000202011800000002020201C40000000045
-:10439000020201CC00000000020201D40000000271
-:1043A000020201DC00000002020201E4000000FF42
-:1043B000020201EC000000FF0202010000000050B8
-:1043C0000202010C000000C80202011C00000002F1
-:1043D000020201C800000000020201D0000000003B
-:1043E000020201D800000002020201E00000000207
-:1043F000020201E8000000FF020201F0000000FFDD
-:1044000002020104000000700728040000B500004B
-:10441000082807B8000908DF072C000028E9000079
-:10442000072C800036700A3B072D000035BE17D8D8
-:10443000072D80003B1B2548072E000035D8340F80
-:10444000072E80001B224186082EBFD0280608E1D7
-:10445000022800BC0000003001280000000000001D
-:1044600001280004000000000128000800000000EE
-:104470000128000C000000000128001000000000CE
-:1044800001280014000000000228002000000001A4
-:104490000228002400000002022800280000000377
-:1044A0000228002C00000000022800300000000458
-:1044B000022800340000000102280038000000003B
-:1044C0000228003C00000001022800400000000417
-:1044D00002280044000000000228004800000001FB
-:1044E0000228004C000000030228005000000000D9
-:1044F00002280054000000010228005800000004B7
-:104500000228005C0000000002280060000000019A
-:104510000228006400000003022800680000000078
-:104520000228006C00000001022800700000000456
-:104530000228007400000000022800780000000437
-:104540000228007C00000003062800800000000212
-:10455000022800A400007FFF022800A8000003FF3B
-:10456000022802240000000002280234000000009B
-:104570000228024C00000000022802E40000FFFFB5
-:104580000628200000000800022B8BC0000000015C
-:10459000022B800000000000022B80400000001869
-:1045A000022B80800000000C022B80C000000066FF
-:1045B0000C2B8300000864700A2B83000000015755
-:1045C0000B2B83000000055F0A2B834000000000D6
-:1045D0000C2B8340000002260B2B834000000001BF
-:1045E000022B838000086470022B83C00000022627
-:1045F000022B1480000000010A2B14800000000030
-:10460000022B944000000001062B94480000000299
-:10461000062A9A7000000004042A9A80000408E325
-:10462000062A9A9000000002042A9A98000208E7DD
-:10463000062A900000000048062A2008000000C852
-:10464000062A200000000002062A912800000086A9
-:10465000062AC00000000120062A9348000000033B
-:10466000042A9354000108E9062A9FB000000002C2
-:10467000042A9418000208EA042A9CD0000108ECDD
-:10468000062A9CD400000011042A9D20008F08ED0A
-:10469000062A9F5C00000005042A30000002097C05
-:1046A000062A300800000100062A404000000010E1
-:1046B000042A40000010097E042A84080002098EA2
-:1046C000042ACF4000040990042ACF600002099414
-:1046D000062A9FA000000004062A60000000054092
-:1046E000062A9D1800000002062AB00000000050B3
-:1046F000062ABB7000000070062ABB68000000029A
-:10470000062AB94800000004062AD000000008006C
-:10471000062AC48000000150062A942000000032BE
-:10472000062A502000000002062A50300000000235
-:10473000062A500000000002062A50100000000265
-:10474000022A520800000001042A9AA000020996D9
-:10475000062A95B000000022042A96380001099824
-:10476000062A963C00000003062A96E0000000227C
-:10477000042A976800010999062A976C0000000333
-:10478000062A981000000022042A98980001099A2D
-:10479000062A989C00000003062A99400000002287
-:1047A000042A99C80001099B062A99CC000000033D
-:1047B000062ABB5800000002062AC9C000000150AA
-:1047C000062A94E800000032062A50280000000261
-:1047D000062A503800000002062A50080000000295
-:1047E000062A501800000002022A520C00000001A4
-:1047F000042A9AA80002099C062A96480000002272
-:10480000042A96D00001099E062A96D400000003CF
-:10481000062A977800000022042A98000001099FC8
-:10482000062A980400000003062A98A80000002227
-:10483000042A9930000109A0062A993400000003D7
-:10484000062A99D800000022042A9A60000109A1D2
-:10485000062A9A6400000003062ABB6000000002DA
-:10486000022ACF0000000000042A9AB0001009A21A
-:10487000062A50480000000E022ACF040000000063
-:10488000042A9AF0001009B2062A50800000000E97
-:10489000022ACF0800000000042A9B30001009C241
-:1048A000062A50B80000000E022ACF0C00000000BB
-:1048B000042A9B70001009D2062A50F00000000E56
-:1048C000022ACF1000000000042A9BB0001009E269
-:1048D000062A51280000000E022ACF140000000012
-:1048E000042A9BF0001009F2062A51600000000E15
-:1048F000022ACF1800000000042A9C3000100A028F
-:10490000062A51980000000E022ACF1C0000000069
-:10491000042A9C7000100A12062A51D00000000ED2
-:1049200002101008000000010210105000000001E9
-:10493000021010000003D000021010040000003D1F
-:104940000910180002000A220910110000100C22A0
-:1049500006101140000000080910116000100C3210
-:10496000061011A00000001806102400000000E04E
-:104970000210201C00000000021020200000000196
-:10498000021020C0000000020210200400000001FC
-:104990000210200800000001021030D800000001C1
-:1049A00009103C0000050C420910380000050C47B6
-:1049B0000910392000050C4C09103B0000050C5172
-:1049C000021040D400000030021040D80000003037
-:1049D00006104C00000001000210402800000010EA
-:1049E0000210404400003FFF021040580028000021
-:1049F000021040840084924A0210405800000000D7
-:104A0000021041380000000102104138000000018E
-:104A1000021041380000000102104138000000017E
-:104A2000021041380000000102104138000000016E
-:104A3000021041380000000102104138000000015E
-:104A40000212049001F680400212051400003C108E
-:104A500002120494FFFFFFFF02120498FFFFFFFF02
-:104A60000212049CFFFFFFFF021204A0FFFFFFFFE2
-:104A7000021204A4FFFFFFFF021204A8FFFFFFFFC2
-:104A8000021204ACFFFFFFFF021204B0FFFFFFFFA2
-:104A9000021204B8FFFFFFFF021204BCFFFFFFFF7A
-:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A
-:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A
-:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16
-:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2
-:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2
-:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2
-:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91
-:104B1000021204FCFFFFFFFF02120500FFFFFFFF70
-:104B200002120504FFFFFFFF02120508FFFFFFFF4F
-:104B30000212050CFFFFFFFF02120510FFFFFFFF2F
-:104B4000021204D4F800C000021204B4F0005000B5
-:104B500002120390000000080212039C00000008EB
-:104B6000021203A000000008021203A400000002C9
-:104B7000021203BC00000004021203C00000000582
-:104B8000021203C400000004021203D0000000005F
-:104B90000212036C00000001021201BC0000004080
-:104BA000021201C000001808021201C4000008032C
-:104BB000021201C800000803021201CC00000040EC
-:104BC000021201D000000003021201D40000080309
-:104BD000021201D800000803021201DC00000803E1
-:104BE000021201E000010003021201E400000803C8
-:104BF000021201E800000803021201EC00000003A9
-:104C0000021201F000000003021201F40000000390
-:104C1000021201F800000003021201FC0000000370
-:104C2000021202000000000302120204000000034E
-:104C300002120208000000030212020C000000032E
-:104C4000021202100000000302120214000000030E
-:104C500002120218000000030212021C00000003EE
-:104C600002120220000000030212022400000003CE
-:104C700002120228000024030212022C0000002F5E
-:104C80000212023000000009021202340000001972
-:104C900002120238000001840212023C000001836B
-:104CA0000212024000000306021202440000001932
-:104CB00002120248000000060212024C0000030625
-:104CC0000212025000000306021202540000030602
-:104CD0000212025800000C860212025C0000030659
-:104CE00002120260000003060212026400000006C5
-:104CF00002120268000000060212026C00000006A8
-:104D00000212027000000006021202740000000687
-:104D100002120278000000060212027C0000000667
-:104D20000212028000000006021202840000000647
-:104D300002120288000000060212028C0000000627
-:104D40000212029000000006021202940000000607
-:104D500002120298000000060212029C00000006E7
-:104D6000021202A000000306021202A400000013B7
-:104D7000021202A800000006021202B00000100495
-:104D8000021202B400001004021203240010644056
-:104D90000212032800106440021205B40000000152
-:104DA000021205F800000040021205FC0000001984
-:104DB00002120600000000010212066C0000000151
-:104DC000021201B000000001021207D80000000327
-:104DD000021207D800000003021207D800000003E7
-:104DE000021207D800000003021207D800000003D7
-:104DF000021207D800000003021207D800000003C7
-:104E0000021207D8000000030600A0000000000CFA
-:104E10000200A050000000000200A05400000000AA
-:104E20000200A0EC555400000200A0F05555555565
-:104E30000200A0F4000055550200A0F8F0000000A8
-:104E40000200A0FC555400000200A1005555555524
-:104E50000200A104000055550200A108F000000066
-:104E60000200A19C000000000200A1A000010000BF
-:104E70000200A1A4000050140200A1A8000000003C
-:104E80000200A6A8000000000200A6AC000000007E
-:104E90000200A6D0000000000200A45C00000C008C
-:104EA0000200A61C000000030200A070FFF55FFFD7
-:104EB0000200A0740000FFFF0200A078F00003E0F1
-:104EC0000200A07C000000000200A0800000A00002
-:104ED0000600A084000000050200A0980FE000007A
-:104EE0000600A09C000000070200A0B8000004001B
-:104EF0000600A0BC000000030200A0C800001000D3
-:104F00000600A0CC000000030200A0D80000400072
-:104F10000600A0DC000000030200A0E80001000081
-:104F20000600A22C000000040200A688000000FC7D
-:104F30000600A68C000000070200A6F40000000096
-:104F40000200A10CFF5C00000200A110FFF55FFF52
-:104F50000200A1140000FFFF0200A118F00003E00E
-:104F60000200A11C000000000200A1200000A0001F
-:104F70000600A124000000050200A1380FE0000097
-:104F80000600A13C000000070200A1580000080034
-:104F90000600A15C000000030200A16800002000E0
-:104FA0000600A16C000000030200A1780000800050
-:104FB0000600A17C000000030200A188000200009E
-:104FC0000600A23C000000040200A6B0000000FCA5
-:104FD0000600A6B4000000070200A6F800000000CA
-:104FE0000200A030000000000200A0340000000019
-:104FF0000200A038000000000200A03C00000000F9
-:105000000200A040000000000200A04400000000D8
-:105010000200A048000000000200A04C00000000B8
-:10502000020090C40000E000020090CC0000F300F9
-:10503000020090D400000003020091A000000001D3
-:105040000600917000000003020090EC0000600078
-:10505000020090F400007300020090FC00000003C6
-:10506000020091A8000000010600918800000003E2
-:10507000020091000000400002009108000053006F
-:105080000200911000000004020091AC0000000139
-:1050900006009194000000020200919C00000001B3
-:1050A000020090D800006000020090E00000730051
-:1050B000020090E800000003020091A4000000013B
-:1050C0000200917C000000010200918000000001BC
-:1050D00002009184000000000200912800000300FB
-:1050E0000200916C0003F0080200912C0000030004
-:1050F0000200913000000300020091340000030020
-:1051000002009138000003000200913C00000300FF
-:1051100002009140000003000200942C00000001F6
-:1051200002009430000000010200943400000001ED
-:105130000200942C000000010200943000000001E5
-:1051400002009434000000010200942C00000001D1
-:1051500002009430000000010200943400000001BD
-:105160000200942C000000010200943000000001B5
-:1051700002009434000000010200942C00000001A1
-:10518000020094300000000102009434000000018D
-:105190000200942C00000001020094300000000185
-:1051A00002009434000000010200942C0000000171
-:1051B000020094300000000102009434000000015D
-:1051C0000200942C00000001020094300000000155
-:1051D0000200943400000001021300780000003047
-:1051E0000213003C000061A8061301080000000340
-:1051F000021301040000000002130134000000004B
-:10520000061301080000000302130104000000005F
-:10521000021301340000000006130108000000031F
-:10522000021301040000000002130134000000001A
-:10523000061301080000000302130104000000002F
-:1052400002130134000000000613010800000003EF
-:1052500002130104000000000213013400000000EA
-:1052600006130108000000030213010400000000FF
-:1052700002130134000000000613010800000003BF
-:1052800002130104000000000213013400000000BA
-:1052900006130108000000030213010400000000CF
-:1052A0000213013400000000021100B800000001E8
-:1052B0000216E6E8000020000216E6EC00002000DE
-:1052C0000216E6F0000065550216E6F4000065558A
-:1052D00002168150000000000216817400000001D7
-:1052E00002168178000000010216817C0000000196
-:1052F0000216818000000001021681840000000176
-:105300000216818800000001021681B4000000012D
-:10531000021681B800000001021681BC00000001E5
-:10532000021681C000000001021681C400000001C5
-:10533000021681C800000001021681100000000062
-:105340000216824000BF00BF061682440000000221
-:105350000216824C00BF00BF0216E6C40000000126
-:105360000216E6C8000000030216E79400000000E1
-:10537000042ACF40000A0C56000000000000000084
-:1053800000000034000000000000000000000000E9
-:10539000000000000000000000000000000000000D
-:1053A0000000000000000000000000000034003594
-:1053B00000000000000000000000000000000000ED
-:1053C00000000000000000000000000000000000DD
-:1053D0000000000000000000003500600000000038
-:1053E00000000000000000000000000000000000BD
-:1053F00000000000000000000000000000000000AD
-:1054000000000000006000910000000000000000AB
-:1054100000910095009500990099009D009D00A1C4
-:1054200000A100A500A500A900A900AD00AD00B134
-:1054300000B100B500000000000000000000000006
-:10544000000000000000000000000000000000005C
-:1054500000000000000000000000000000B5031183
-:105460000311031B031B03250325032C032C033308
-:105470000333033A033A0341034103480348034F0C
-:10548000034F03560356035D0000000000000000B8
-:10549000000000000000000000000000000000000C
-:1054A00000000000000000000000000000000000FC
-:1054B00000000000000000000000000000000000EC
-:1054C00000000000000000000000000000000000DC
-:1054D00000000000000000000000000000000000CC
-:1054E00000000000000000000000000000000000BC
-:1054F00000000000000000000000000000000000AC
-:10550000000000000000000000000000000000009B
-:10551000000000000000000000000000000000008B
-:10552000000000000000000000000000000000007B
-:105530000000000000000000035D035E00000000AA
-:1055400000000000035E035F035F0360036003610C
-:10555000036103620362036303630364036403651B
-:10556000036503660000000000000000000000006A
-:10557000000000000000000000000000000000002B
-:10558000000000000000000000000000000000001B
-:105590000366036D036D0379037903850000000042
-:1055A00000000000000000000000000000000000FB
-:1055B00000000000000000000000000000000000EB
-:1055C00000000000000000000000000000000000DB
-:1055D00000000000000000000000000000000000CB
-:1055E00000000000000000000385038600000000AA
-:1055F00000000000000000000000000000000000AB
-:10560000000000000000000000000000000000009A
-:1056100000000000038603B100000000000000004D
-:10562000000000000000000000000000000000007A
-:10563000000000000000000000000000000000006A
-:1056400003B103E0000000000000000000000000C3
-:10565000000000000000000000000000000000004A
-:1056600000000000000000000000000003E0040F44
-:105670000000000000000000040F04160416041DC2
-:10568000041D04240424042B042B043204320439A2
-:1056900004390440044004470447047A0000000031
-:1056A00000000000047A047E047E048204820486E2
-:1056B0000486048A048A048E048E0492049204965A
-:1056C0000496049A049A04EA04EA05000500051603
-:1056D000051605180518051A051A051C051C051ED2
-:1056E000051E052005200522052205240524052682
-:1056F00005260693000000000000000006930698AF
-:105700000698069D069D06A206A206A706A706AC59
-:1057100006AC06B106B106B606B606BB06BB06BCAD
-:105720000000000000000000000000000000000079
-:105730000000000000000000000000000000000069
-:10574000000000000000000006BC06E000000000B1
-:105750000000000006E006E206E206E406E406E6D3
-:1057600006E606E806E806EA06EA06EC06EC06EEB9
-:1057700006EE06F006F00705070507080708070B01
-:105780000000000000000000000000000000000019
-:105790000000000000000000000000000000000009
-:1057A000070B074F00000000000000000000000091
-:1057B00000000000000000000000000000000000E9
-:1057C000000000000000000000000000074F07E19B
-:1057D00000000000000000000000000000000000C9
-:1057E00000000000000000000000000000000000B9
-:1057F000000000000000000007E107EF00000000CB
-:105800000000000000000000000000000000000098
-:105810000000000000000000000000000000000088
-:105820000000000007EF082C00000000000000004E
-:10583000082C08350835083E083E08470847085038
-:1058400008500859085908620862086B086B087408
-:10585000087408D508D508EA08EA08FF08FF090215
-:1058600009020905090509080908090B090B090EB0
-:10587000090E09110911091409140917091709203A
-:105880000000000000000000000000000000000018
-:105890000000000000000000000000000000000008
-:1058A00000000000000000000920092600000000A0
-:1058B00000000000000000000000000000000000E8
-:1058C00000000000000000000000000000000000D8
-:1058D000000000000926092B000000000000000065
-:1058E00000000000000000000000000000000000B8
-:1058F00000000000000000000000000000000000A8
-:10590000092B0933000000000000000009330934AE
-:10591000093409350935093609360937093709388F
-:10592000093809390939093A093A093B00000000E8
-:105930000000000000000000000000000000000067
-:105940000000000000000000000000000000000057
-:105950000000000000000000093B09AC000000004E
-:105960000000000009AC09AD09AD09AE09AE09AFF0
-:1059700009AF09B009B009B109B109B209B209B357
-:1059800009B309B409B409C809C809DB09DB09EF7F
-:1059900009EF09F009F009F109F109F209F209F337
-:1059A00009F309F409F409F509F509F609F609F707
-:1059B00009F70A1600000000000000000A160A1984
-:1059C0000A190A1C0A1C0A1F0A1F0A220A220A258F
-:1059D0000A250A280A280A2B0A2B0A2E0A2E0A3020
-:1059E00000000000000000000A300A330A330A36C3
-:1059F0000A360A390A390A3C0A3C0A3F0A3F0A4277
-:105A00000A420A450A450A480A480A4900000000B5
-:105A10000000000000000000000000000000000086
-:105A20000000000000000000000000000000000076
-:105A3000000000000A490A610000000000000000A8
-:105A40000000000000000000000000000000000056
-:105A50000000000000000000000000000000000046
-:105A60000A610A620000000000000000000000005F
-:105A70000000000000000000000000000000000026
-:105A80000000000000000000000000000000000016
-:105A9000000100000002070000030E0000041500D2
-:105AA00000051C000006230000072A000008310042
-:105AB00000093800000A3F00000B4600000C4D00B2
-:105AC000000D5400000E5B00000F62000010690022
-:105AD000001170000012770000137E000014850092
-:105AE00000158C000016930000179A000018A10002
-:105AF0000019A800001AAF00001BB600001CBD0072
-:105B0000001DC400001ECB00001FD2000000D90001
-:105B10000000200000004000000060000000800045
-:105B20000000A0000000C0000000E0000001000034
-:105B30000001200000014000000160000001800021
-:105B40000001A0000001C0000001E0000002000010
-:105B500000022000000240000002600000028000FD
-:105B60000002A0000002C0000002E00000030000EC
-:105B700000032000000340000003600000038000D9
-:105B80000003A0000003C0000003E00000040000C8
-:105B900000042000000440000004600000048000B5
-:105BA0000004A0000004C0000004E00000050000A4
-:105BB0000005200000054000000560000005800091
-:105BC0000005A0000005C0000005E0000006000080
-:105BD000000620000006400000066000000680006D
-:105BE0000006A0000006C0000006E000000700005C
-:105BF0000007200000074000000760000007800049
-:105C00000007A0000007C0000007E0000008000037
-:105C10000008200000084000000860000008800024
-:105C20000008A0000008C0000008E0000009000013
-:105C30000009200000094000000960000009800000
-:105C40000009A0000009C0000009E000000A0000EF
-:105C5000000A2000000A4000000A6000000A8000DC
-:105C6000000AA000000AC000000AE000000B0000CB
-:105C7000000B2000000B4000000B6000000B8000B8
-:105C8000000BA000000BC000000BE000000C0000A7
-:105C9000000C2000000C4000000C6000000C800094
-:105CA000000CA000000CC000000CE000000D000083
-:105CB000000D2000000D4000000D6000000D800070
-:105CC000000DA000000DC000000DE000000E00005F
-:105CD000000E2000000E4000000E6000000E80004C
-:105CE000000EA000000EC000000EE000000F00003B
-:105CF000000F2000000F4000000F6000000F800028
-:105D0000000FA000000FC000000FE0000010000016
-:105D10000010200000104000001060000010800003
-:105D20000010A0000010C0000010E00000110000F2
-:105D300000112000001140000011600000118000DF
-:105D40000011A0000011C0000011E00000120000CE
-:105D500000122000001240000012600000128000BB
-:105D60000012A0000012C0000012E00000130000AA
-:105D70000013200000134000001360000013800097
-:105D80000013A0000013C0000013E0000014000086
-:105D90000014200000144000001460000014800073
-:105DA0000014A0000014C0000014E0000015000062
-:105DB000001520000015400000156000001580004F
-:105DC0000015A0000015C0000015E000001600003E
-:105DD000001620000016400000166000001680002B
-:105DE0000016A0000016C0000016E000001700001A
-:105DF0000017200000174000001760000017800007
-:105E00000017A0000017C0000017E00000180000F5
-:105E100000182000001840000018600000188000E2
-:105E20000018A0000018C0000018E00000190000D1
-:105E300000192000001940000019600000198000BE
-:105E40000019A0000019C0000019E000001A0000AD
-:105E5000001A2000001A4000001A6000001A80009A
-:105E6000001AA000001AC000001AE000001B000089
-:105E7000001B2000001B4000001B6000001B800076
-:105E8000001BA000001BC000001BE000001C000065
-:105E9000001C2000001C4000001C6000001C800052
-:105EA000001CA000001CC000001CE000001D000041
-:105EB000001D2000001D4000001D6000001D80002E
-:105EC000001DA000001DC000001DE000001E00001D
-:105ED000001E2000001E4000001E6000001E80000A
-:105EE000001EA000001EC000001EE000001F0000F9
-:105EF000001F2000001F4000001F6000001F8000E6
-:105F0000001FA000001FC000001FE00000200000D4
-:105F100000202000002040000020600000208000C1
-:105F20000020A0000020C0000020E00000210000B0
-:105F3000002120000021400000216000002180009D
-:105F40000021A0000021C0000021E000002200008C
-:105F50000022200000224000002260000022800079
-:105F60000022A0000022C0000022E0000023000068
-:105F70000023200000234000002360000023800055
-:105F80000023A0000023C0000023E0000024000044
-:105F90000024200000244000002460000024800031
-:105FA0000024A0000024C0000024E0000025000020
-:105FB000002520000025400000256000002580000D
-:105FC0000025A0000025C0000025E00000260000FC
-:105FD00000262000002640000026600000268000E9
-:105FE0000026A0000026C0000026E00000270000D8
-:105FF00000272000002740000027600000278000C5
-:106000000027A0000027C0000027E00000280000B3
-:1060100000282000002840000028600000288000A0
-:106020000028A0000028C0000028E000002900008F
-:10603000002920000029400000296000002980007C
-:106040000029A0000029C0000029E000002A00006B
-:10605000002A2000002A4000002A6000002A800058
-:10606000002AA000002AC000002AE000002B000047
-:10607000002B2000002B4000002B6000002B800034
-:10608000002BA000002BC000002BE000002C000023
-:10609000002C2000002C4000002C6000002C800010
-:1060A000002CA000002CC000002CE000002D0000FF
-:1060B000002D2000002D4000002D6000002D8000EC
-:1060C000002DA000002DC000002DE000002E0000DB
-:1060D000002E2000002E4000002E6000002E8000C8
-:1060E000002EA000002EC000002EE000002F0000B7
-:1060F000002F2000002F4000002F6000002F8000A4
-:10610000002FA000002FC000002FE0000030000092
-:10611000003020000030400000306000003080007F
-:106120000030A0000030C0000030E000003100006E
-:10613000003120000031400000316000003180005B
-:106140000031A0000031C0000031E000003200004A
-:106150000032200000324000003260000032800037
-:106160000032A0000032C0000032E0000033000026
-:106170000033200000334000003360000033800013
-:106180000033A0000033C0000033E0000034000002
-:1061900000342000003440000034600000348000EF
-:1061A0000034A0000034C0000034E00000350000DE
-:1061B00000352000003540000035600000358000CB
-:1061C0000035A0000035C0000035E00000360000BA
-:1061D00000362000003640000036600000368000A7
-:1061E0000036A0000036C0000036E0000037000096
-:1061F0000037200000374000003760000037800083
-:106200000037A0000037C0000037E0000038000071
-:10621000003820000038400000386000003880005E
-:106220000038A0000038C0000038E000003900004D
-:10623000003920000039400000396000003980003A
-:106240000039A0000039C0000039E000003A000029
-:10625000003A2000003A4000003A6000003A800016
-:10626000003AA000003AC000003AE000003B000005
-:10627000003B2000003B4000003B6000003B8000F2
-:10628000003BA000003BC000003BE000003C0000E1
-:10629000003C2000003C4000003C6000003C8000CE
-:1062A000003CA000003CC000003CE000003D0000BD
-:1062B000003D2000003D4000003D6000003D8000AA
-:1062C000003DA000003DC000003DE000003E000099
-:1062D000003E2000003E4000003E6000003E800086
-:1062E000003EA000003EC000003EE000003F000075
-:1062F000003F2000003F4000003F6000003F800062
-:10630000003FA000003FC000003FE000003FE00170
-:1063100000000000000001FF0000020000007FF804
-:1063200000007FF800000A90000035000000000126
-:106330000000FF00000000000000FF00000000005F
-:106340000000FF00000000000000FF00000000004F
-:106350000000FF00000000000000FF00000000003F
-:106360000000FF00000000000000FF00000000002F
-:106370000000FF00000000000000FF00000000001F
-:106380000000FF00000000000000FF00000000000F
-:106390000000FF00000000000000FF0000000000FF
-:1063A0000000FF00000000000000FF0000000000EF
-:1063B0000000FF00000000000000FF0000000000DF
-:1063C0000000FF00000000000000FF0000000000CF
-:1063D0000000FF00000000000000FF0000000000BF
-:1063E0000000FF00000000000000FF0000000000AF
-:1063F0000000FF00000000000000FF00000000009F
-:106400000000FF00000000000000FF00000000008E
-:106410000000FF00000000000000FF00000000007E
-:106420000000FF00000000000000FF00000000006E
-:106430000000FF00000000000000FF00000000005E
-:106440000000FF00000000000000FF00000000004E
-:106450000000FF00000000000000FF00000000003E
-:106460000000FF00000000000000FF00000000002E
-:106470000000FF00000000000000FF00000000001E
-:106480000000FF00000000000000FF00000000000E
-:106490000000FF00000000000000FF0000000000FE
-:1064A0000000FF00000000000000FF0000000000EE
-:1064B0000000FF00000000000000FF0000000000DE
-:1064C0000000FF00000000000000FF0000000000CE
-:1064D0000000FF00000000000000FF0000000000BE
-:1064E0000000FF00000000000000FF0000000000AE
-:1064F0000000FF00000000000000FF00000000009E
-:106500000000FF00000000000000FF00000000008D
-:106510000000FF00000000000000FF00000000007D
-:106520000000FF00000000000000FF00000000006D
-:106530000000FF00000000000000FF00000000005D
-:106540000000FF00000000000000FF00000000004D
-:106550000000FF00000000000000FF00000000003D
-:106560000000FF00000000000000FF00000000002D
-:1065700000000000140AFF000000000100000000FD
-:106580000020100100000000010090000000010048
-:1065900000009002000090040000900600009008A7
-:1065A0000000900A0000900C0000900E0000901077
-:1065B0000000901200009014000090160000901847
-:1065C0000000901A0000901C0000901E0000902017
-:1065D00000009022000090240000902600009028E7
-:1065E0000000902A0000902C0000902E00009030B7
-:1065F0000000903200009034000090360000903887
-:106600000000903A0000903C0000903E0000904056
-:106610000000904200009044000090460000904826
-:106620000000904A0000904C0000904E00009050F6
-:1066300000009052000090540000905600009058C6
-:106640000000905A0000905C0000905E0000906096
-:106650000000906200009064000090660000906866
-:106660000000906A0000906C0000906E0000907036
-:106670000000907200009074000090760000907806
-:106680000000907A0000907C0000907E00009080D6
-:1066900000009082000090840000908600009088A6
-:1066A0000000908A0000908C0000908E0000909076
-:1066B0000000909200009094000090960000909846
-:1066C0000000909A0000909C0000909E000090A016
-:1066D000000090A2000090A4000090A6000090A8E6
-:1066E000000090AA000090AC000090AE000090B0B6
-:1066F000000090B2000090B4000090B6000090B886
-:10670000000090BA000090BC000090BE000090C055
-:10671000000090C2000090C4000090C6000090C825
-:10672000000090CA000090CC000090CE000090D0F5
-:10673000000090D2000090D4000090D6000090D8C5
-:10674000000090DA000090DC000090DE000090E095
-:10675000000090E2000090E4000090E6000090E865
-:10676000000090EA000090EC000090EE000090F035
-:10677000000090F2000090F4000090F6000090F805
-:10678000000090FA000090FC000090FE00009100D4
-:1067900000009102000091040000910600009108A1
-:1067A0000000910A0000910C0000910E0000911071
-:1067B0000000911200009114000091160000911841
-:1067C0000000911A0000911C0000911E0000912011
-:1067D00000009122000091240000912600009128E1
-:1067E0000000912A0000912C0000912E00009130B1
-:1067F0000000913200009134000091360000913881
-:106800000000913A0000913C0000913E0000914050
-:106810000000914200009144000091460000914820
-:106820000000914A0000914C0000914E00009150F0
-:1068300000009152000091540000915600009158C0
-:106840000000915A0000915C0000915E0000916090
-:106850000000916200009164000091660000916860
-:106860000000916A0000916C0000916E0000917030
-:106870000000917200009174000091760000917800
-:106880000000917A0000917C0000917E00009180D0
-:1068900000009182000091840000918600009188A0
-:1068A0000000918A0000918C0000918E0000919070
-:1068B0000000919200009194000091960000919840
-:1068C0000000919A0000919C0000919E000091A010
-:1068D000000091A2000091A4000091A6000091A8E0
-:1068E000000091AA000091AC000091AE000091B0B0
-:1068F000000091B2000091B4000091B6000091B880
-:10690000000091BA000091BC000091BE000091C04F
-:10691000000091C2000091C4000091C6000091C81F
-:10692000000091CA000091CC000091CE000091D0EF
-:10693000000091D2000091D4000091D6000091D8BF
-:10694000000091DA000091DC000091DE000091E08F
-:10695000000091E2000091E4000091E6000091E85F
-:10696000000091EA000091EC000091EE000091F02F
-:10697000000091F2000091F4000091F6000091F8FF
-:10698000000091FA000091FC000091FEFFFFFFFF64
-:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
-:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
-:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
-:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
-:1069D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
-:1069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
-:1069F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
-:106A0000FFFFFFFFFFFFFFFFFFFFFFFF000000038F
-:106A100000BEBC20000000000000000500000003D4
-:106A200000BEBC20000000000000000500000003C4
-:106A300000BEBC20000000000000000500000003B4
-:106A400000BEBC20000000000000000500000003A4
-:106A500000BEBC2000000000000000050000000394
-:106A600000BEBC2000000000000000050000000384
-:106A700000BEBC2000000000000000050000000374
-:106A800000BEBC2000000000000000050000200047
-:106A9000000040C000006180000082400000A300B0
-:106AA0000000C3C00000E480000105400001260092
-:106AB000000146C000016780000188400001A90074
-:106AC0000001C9C00001EA8000020B4000022C0056
-:106AD00000024CC000026D8000028E400002AF0038
-:106AE0000002CFC00002F0800000114000008000D2
-:106AF000000103800001870000020A8000028E006E
-:106B000000031180000395000004188000049C001D
-:106B100000051F800005A300000626800006AA00CD
-:106B200000072D800007B100000834800008B8007D
-:106B300000093B800009BF00000A4280000AC6002D
-:106B4000000B4980000BCD00000C5080000CD400DD
-:106B5000000D578000005B0000007FF800007FF808
-:106B60000000022A000035000000FF0000000000C5
-:106B70000000FF00000000000000FF000000000017
-:106B80000000FF00000000000000FF000000000007
-:106B90000000FF00000000000000FF0000000000F7
-:106BA0000000FF00000000000000FF0000000000E7
-:106BB0000000FF00000000000000FF0000000000D7
-:106BC0000000FF00000000000000FF0000000000C7
-:106BD0000000FF00000000000000FF0000000000B7
-:106BE0000000FF00000000000000FF0000000000A7
-:106BF0000000FF00000000000000FF000000000097
-:106C00000000FF00000000000000FF000000000086
-:106C10000000FF00000000000000FF000000000076
-:106C20000000FF00000000000000FF000000000066
-:106C30000000FF00000000000000FF000000000056
-:106C40000000FF00000000000000FF000000000046
-:106C50000000FF00000000000000FF000000000036
-:106C60000000FF00000000000000FF000000000026
-:106C70000000FF00000000000000FF000000000016
-:106C80000000FF00000000000000FF000000000006
-:106C90000000FF00000000000000FF0000000000F6
-:106CA0000000FF00000000000000FF0000000000E6
-:106CB0000000FF00000000000000FF0000000000D6
-:106CC0000000FF00000000000000FF0000000000C6
-:106CD0000000FF00000000000000FF0000000000B6
-:106CE0000000FF00000000000000FF0000000000A6
-:106CF0000000FF00000000000000FF000000000096
-:106D00000000FF00000000000000FF000000000085
-:106D10000000FF00000000000000FF000000000075
-:106D20000000FF00000000000000FF000000000065
-:106D30000000FF00000000000000FF000000000055
-:106D40000000FF00000000000000FF000000000045
-:106D50000000FF00000000000000FF000000000035
-:106D60000000FF00000000000000FF000000000025
-:106D70000000FF00000000000000FF000000000015
-:106D80000000FF00000000000000FF000000000005
-:106D90000000FF00000000000000FF0000000000F5
-:106DA0000000FF00000019000000000000000000CB
-:106DB000FFFFFFFF000000000393870000000000BA
-:106DC0000393870000007FF800007FF800000BA30A
-:106DD00000001500000000FF000000FF000000FFA1
-:106DE000000000FF000000FF000000FF000000FFA7
-:106DF000000000FF0000FF00000000000000FF0096
-:106E0000000000000000FF00000000000000FF0084
-:106E1000000000000000FF00000000000000FF0074
-:106E2000000000000000FF00000000000000FF0064
-:106E3000000000000000FF00000000000000FF0054
-:106E4000000000000000FF00000000000000FF0044
-:106E5000000000000000FF00000000000000FF0034
-:106E6000000000000000FF00000000000000FF0024
-:106E7000000000000000FF00000000000000FF0014
-:106E8000000000000000FF00000000000000FF0004
-:106E9000000000000000FF00000000000000FF00F4
-:106EA000000000000000FF00000000000000FF00E4
-:106EB000000000000000FF00000000000000FF00D4
-:106EC000000000000000FF00000000000000FF00C4
-:106ED000000000000000FF00000000000000FF00B4
-:106EE000000000000000FF00000000000000FF00A4
-:106EF000000000000000FF00000000000000FF0094
-:106F0000000000000000FF00000000000000FF0083
-:106F1000000000000000FF00000000000000FF0073
-:106F2000000000000000FF00000000000000FF0063
-:106F3000000000000000FF00000000000000FF0053
-:106F4000000000000000FF00000000000000FF0043
-:106F5000000000000000FF00000000000000FF0033
-:106F6000000000000000FF00000000000000FF0023
-:106F7000000000000000FF00000000000000FF0013
-:106F8000000000000000FF00000000000000FF0003
-:106F9000000000000000FF00000000000000FF00F3
-:106FA000000000000000FF00000000000000FF00E3
-:106FB000000000000000FF00000000000000FF00D3
-:106FC000000000000000FF00000000000000FF00C3
-:106FD000000000000000FF00000000000000FF00B3
-:106FE000000000000000FF00000000000000FF00A3
-:106FF000000000000000FF00000000000000FF0093
-:10700000000000000000FF00000000000000FF0082
-:10701000000000000000FF00000000000000FF0072
-:10702000000000000000FF00000000000000FF0062
-:1070300000000000FFFFFFFFFFFFFFFFFFFFFFFF5C
-:10704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
-:10705000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
-:10706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
-:10707000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
-:10708000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
-:10709000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
-:1070A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
-:1070B000FFFFFFFF00000000000028AD00002918BE
-:1070C0000000291900000005000000070000FF0073
-:1070D0000FFFFFFF0000FF000FFFFFFF000000FF9A
-:1070E0000000FF000000FF000FFFFFFF0000FF0097
-:1070F0000FFFFFFF000000FF0000FF000000FF0087
-:107100000FFFFFFF0000FF000FFFFFFF000000FF69
-:107110000000FF000000FF000FFFFFFF0000FF0066
-:107120000FFFFFFF000000FF0000FF000000FF0056
-:107130000FFFFFFF0000FF000FFFFFFF000000FF39
-:107140000000FF000000FF000FFFFFFF0000FF0036
-:107150000FFFFFFF000000FF0000FF000000FF0026
-:107160000FFFFFFF0000FF000FFFFFFF000000FF09
-:107170000000FF000000FF000FFFFFFF0000FF0006
-:107180000FFFFFFF000000FF0000FF000000FF00F6
-:107190000FFFFFFF0000FF000FFFFFFF000000FFD9
-:1071A0000000FF000000FF000FFFFFFF0000FF00D6
-:1071B0000FFFFFFF000000FF0000FF000000FF00C6
-:1071C0000FFFFFFF0000FF000FFFFFFF000000FFA9
-:1071D0000000FF000000FF000FFFFFFF0000FF00A6
-:1071E0000FFFFFFF000000FF0000FF000000FF0096
-:1071F0000FFFFFFF0000FF000FFFFFFF000000FF79
-:107200000000FF000000FF000FFFFFFF0000FF0075
-:107210000FFFFFFF000000FF0000FF000000FF0065
-:107220000FFFFFFF0000FF000FFFFFFF000000FF48
-:107230000000FF000000FF000FFFFFFF0000FF0045
-:107240000FFFFFFF000000FF0000FF000000FF0035
-:107250000FFFFFFF0000FF000FFFFFFF000000FF18
-:107260000000FF000000FF000FFFFFFF0000FF0015
-:107270000FFFFFFF000000FF0000FF000000FF0005
-:107280000FFFFFFF0000FF000FFFFFFF000000FFE8
-:107290000000FF000000FF000FFFFFFF0000FF00E5
-:1072A0000FFFFFFF000000FF0000FF000000FF00D5
-:1072B0000FFFFFFF0000FF000FFFFFFF000000FFB8
-:1072C0000000FF000000FF000FFFFFFF0000FF00B5
-:1072D0000FFFFFFF000000FF0000FF000000FF00A5
-:1072E0000FFFFFFF0000FF000FFFFFFF000000FF88
-:1072F0000000FF000000FF000FFFFFFF0000FF0085
-:107300000FFFFFFF000000FF0000FF000000FF0074
-:107310000FFFFFFF0000FF000FFFFFFF000000FF57
-:107320000000FF000000FF000FFFFFFF0000FF0054
-:107330000FFFFFFF000000FF0000FF000000FF0044
-:107340000FFFFFFF0000FF000FFFFFFF000000FF27
-:107350000000FF000000FF000FFFFFFF0000FF0024
-:107360000FFFFFFF000000FF0000FF000000FF0014
-:107370000FFFFFFF0000FF000FFFFFFF000000FFF7
-:107380000000FF000000FF000FFFFFFF0000FF00F4
-:107390000FFFFFFF000000FF0000FF000000FF00E4
-:1073A0000FFFFFFF0000FF000FFFFFFF000000FFC7
-:1073B0000000FF000000FF000FFFFFFF0000FF00C4
-:1073C0000FFFFFFF000000FF0000FF000000FF00B4
-:1073D0000FFFFFFF0000FF000FFFFFFF000000FF97
-:1073E0000000FF000000FF000FFFFFFF0000FF0094
-:1073F0000FFFFFFF000000FF0000FF000000FF0084
-:107400000FFFFFFF0000FF000FFFFFFF000000FF66
-:107410000000FF000000FF000FFFFFFF0000FF0063
-:107420000FFFFFFF000000FF0000FF000000FF0053
-:107430000FFFFFFF0000FF000FFFFFFF000000FF36
-:107440000000FF000000FF000FFFFFFF0000FF0033
-:107450000FFFFFFF000000FF0000FF000000FF0023
-:107460000FFFFFFF0000FF000FFFFFFF000000FF06
-:107470000000FF000000FF000FFFFFFF0000FF0003
-:107480000FFFFFFF000000FF0000FF000000FF00F3
-:107490000FFFFFFF0000FF000FFFFFFF000000FFD6
-:1074A0000000FF000000FF000FFFFFFF0000FF00D3
-:1074B0000FFFFFFF000000FF0000FF000000FF00C3
-:1074C0000FFFFFFF0000FF000FFFFFFF000000FFA6
-:1074D0000000FF000000FF000FFFFFFF0000FF00A3
-:1074E0000FFFFFFF000000FF0000FF000000FF0093
-:1074F0000FFFFFFF0000FF000FFFFFFF000000FF76
-:107500000000FF000000FF000FFFFFFF0000FF0072
-:107510000FFFFFFF000000FF0000FF000000FF0062
-:107520000FFFFFFF0000FF000FFFFFFF000000FF45
-:107530000000FF000000FF000FFFFFFF0000FF0042
-:107540000FFFFFFF000000FF0000FF000000FF0032
-:107550000FFFFFFF0000FF000FFFFFFF000000FF15
-:107560000000FF000000FF000FFFFFFF0000FF0012
-:107570000FFFFFFF000000FF0000FF000000FF0002
-:107580000FFFFFFF0000FF000FFFFFFF000000FFE5
-:107590000000FF000000FF000FFFFFFF0000FF00E2
-:1075A0000FFFFFFF000000FF0000FF000000FF00D2
-:1075B0000FFFFFFF0000FF000FFFFFFF000000FFB5
-:1075C0000000FF000000FF000FFFFFFF0000FF00B2
-:1075D0000FFFFFFF000000FF0000FF000000FF00A2
-:1075E0000FFFFFFF0000FF000FFFFFFF000000FF85
-:1075F0000000FF000000FF000FFFFFFF0000FF0082
-:107600000FFFFFFF000000FF0000FF000000FF0071
-:107610000FFFFFFF0000FF000FFFFFFF000000FF54
-:107620000000FF000000FF000FFFFFFF0000FF0051
-:107630000FFFFFFF000000FF0000FF000000FF0041
-:107640000FFFFFFF0000FF000FFFFFFF000000FF24
-:107650000000FF000000FF000FFFFFFF0000FF0021
-:107660000FFFFFFF000000FF0000FF000000FF0011
-:107670000FFFFFFF0000FF000FFFFFFF000000FFF4
-:107680000000FF000000FF000FFFFFFF0000FF00F1
-:107690000FFFFFFF000000FF0000FF000000FF00E1
-:1076A0000FFFFFFF0000FF000FFFFFFF000000FFC4
-:1076B0000000FF000000FF000FFFFFFF0000FF00C1
-:1076C0000FFFFFFF000000FF0000FF000000FF00B1
-:1076D0000FFFFFFF0000FF000FFFFFFF000000FF94
-:1076E0000000FF000000FF000FFFFFFF0000FF0091
-:1076F0000FFFFFFF000000FF0000FF000000FF0081
-:107700000FFFFFFF0000FF000FFFFFFF000000FF63
-:107710000000FF000000FF000FFFFFFF0000FF0060
-:107720000FFFFFFF000000FF0000FF000000FF0050
-:107730000FFFFFFF0000FF000FFFFFFF000000FF33
-:107740000000FF000000FF000FFFFFFF0000FF0030
-:107750000FFFFFFF000000FF0000FF000000FF0020
-:107760000FFFFFFF0000FF000FFFFFFF000000FF03
-:107770000000FF000000FF000FFFFFFF0000FF0000
-:107780000FFFFFFF000000FF0000FF000000FF00F0
-:107790000FFFFFFF0000FF000FFFFFFF000000FFD3
-:1077A0000000FF000000FF000FFFFFFF0000FF00D0
-:1077B0000FFFFFFF000000FF0000FF000000FF00C0
-:1077C0000FFFFFFF0000FF000FFFFFFF000000FFA3
-:1077D0000000FF000000FF000FFFFFFF0000FF00A0
-:1077E0000FFFFFFF000000FF0000FF000000FF0090
-:1077F0000FFFFFFF0000FF000FFFFFFF000000FF73
-:107800000000FF000000FF000FFFFFFF0000FF006F
-:107810000FFFFFFF000000FF0000FF000000FF005F
-:107820000FFFFFFF0000FF000FFFFFFF000000FF42
-:107830000000FF000000FF000FFFFFFF0000FF003F
-:107840000FFFFFFF000000FF0000FF000000FF002F
-:107850000FFFFFFF0000FF000FFFFFFF000000FF12
-:107860000000FF000000FF000FFFFFFF0000FF000F
-:107870000FFFFFFF000000FF0000FF000000FF00FF
-:107880000FFFFFFF0000FF000FFFFFFF000000FFE2
-:107890000000FF000000FF000FFFFFFF0000FF00DF
-:1078A0000FFFFFFF000000FF0000FF000000FF00CF
-:1078B0000FFFFFFF0000FF000FFFFFFF000000FFB2
-:1078C0000000FF000000FF000FFFFFFF0000FF00AF
-:1078D0000FFFFFFF000000FF0000FF000000FF009F
-:1078E0000FFFFFFF0000FF000FFFFFFF000000FF82
-:1078F0000000FF000000FF000FFFFFFF0000FF007F
-:107900000FFFFFFF000000FF0000FF000000FF006E
-:107910000FFFFFFF0000FF000FFFFFFF000000FF51
-:107920000000FF000000FF000FFFFFFF0000FF004E
-:107930000FFFFFFF000000FF0000FF000000FF003E
-:107940000FFFFFFF0000FF000FFFFFFF000000FF21
-:107950000000FF000000FF000FFFFFFF0000FF001E
-:107960000FFFFFFF000000FF0000FF000000FF000E
-:107970000FFFFFFF0000FF000FFFFFFF000000FFF1
-:107980000000FF000000FF000FFFFFFF0000FF00EE
-:107990000FFFFFFF000000FF0000FF000000FF00DE
-:1079A0000FFFFFFF0000FF000FFFFFFF000000FFC1
-:1079B0000000FF000000FF000FFFFFFF0000FF00BE
-:1079C0000FFFFFFF000000FF0000FF000000FF00AE
-:1079D0000FFFFFFF0000FF000FFFFFFF000000FF91
-:1079E0000000FF000000FF000FFFFFFF0000FF008E
-:1079F0000FFFFFFF000000FF0000FF000000FF007E
-:107A00000FFFFFFF0000FF000FFFFFFF000000FF60
-:107A10000000FF000000FF000FFFFFFF0000FF005D
-:107A20000FFFFFFF000000FF0000FF000000FF004D
-:107A30000FFFFFFF0000FF000FFFFFFF000000FF30
-:107A40000000FF000000FF000FFFFFFF0000FF002D
-:107A50000FFFFFFF000000FF0000FF000000FF001D
-:107A60000FFFFFFF0000FF000FFFFFFF000000FF00
-:107A70000000FF000000FF000FFFFFFF0000FF00FD
-:107A80000FFFFFFF000000FF0000FF000000FF00ED
-:107A90000FFFFFFF0000FF000FFFFFFF000000FFD0
-:107AA0000000FF000000FF000FFFFFFF0000FF00CD
-:107AB0000FFFFFFF000000FF0000FF000000FF00BD
-:107AC0000FFFFFFF0000FF000FFFFFFF000000FFA0
-:107AD0000000FF000000FF000FFFFFFF0000FF009D
-:107AE0000FFFFFFF000000FF0000FF000000FF008D
-:107AF0000FFFFFFF0000FF000FFFFFFF000000FF70
-:107B00000000FF000000FF000FFFFFFF0000FF006C
-:107B10000FFFFFFF000000FF0000FF000000FF005C
-:107B20000FFFFFFF0000FF000FFFFFFF000000FF3F
-:107B30000000FF000000FF000FFFFFFF0000FF003C
-:107B40000FFFFFFF000000FF0000FF000000FF002C
-:107B50000FFFFFFF0000FF000FFFFFFF000000FF0F
-:107B60000000FF000000FF000FFFFFFF0000FF000C
-:107B70000FFFFFFF000000FF0000FF000000FF00FC
-:107B80000FFFFFFF0000FF000FFFFFFF000000FFDF
-:107B90000000FF000000FF000FFFFFFF0000FF00DC
-:107BA0000FFFFFFF000000FF0000FF000000FF00CC
-:107BB0000FFFFFFF0000FF000FFFFFFF000000FFAF
-:107BC0000000FF000000FF000FFFFFFF0000FF00AC
-:107BD0000FFFFFFF000000FF0000FF000000FF009C
-:107BE0000FFFFFFF0000FF000FFFFFFF000000FF7F
-:107BF0000000FF000000FF000FFFFFFF0000FF007C
-:107C00000FFFFFFF000000FF0000FF000000FF006B
-:107C10000FFFFFFF0000FF000FFFFFFF000000FF4E
-:107C20000000FF000000FF000FFFFFFF0000FF004B
-:107C30000FFFFFFF000000FF0000FF000000FF003B
-:107C40000FFFFFFF0000FF000FFFFFFF000000FF1E
-:107C50000000FF000000FF000FFFFFFF0000FF001B
-:107C60000FFFFFFF000000FF0000FF000000FF000B
-:107C70000FFFFFFF0000FF000FFFFFFF000000FFEE
-:107C80000000FF000000FF000FFFFFFF0000FF00EB
-:107C90000FFFFFFF000000FF0000FF000000FF00DB
-:107CA0000FFFFFFF0000FF000FFFFFFF000000FFBE
-:107CB0000000FF000000FF000FFFFFFF0000FF00BB
-:107CC0000FFFFFFF000000FF0000FF000000FF00AB
-:107CD0000FFFFFFF0000FF000FFFFFFF000000FF8E
-:107CE0000000FF000000FF000FFFFFFF0000FF008B
-:107CF0000FFFFFFF000000FF0000FF000000FF007B
-:107D00000FFFFFFF0000FF000FFFFFFF000000FF5D
-:107D10000000FF000000FF000FFFFFFF0000FF005A
-:107D20000FFFFFFF000000FF0000FF000000FF004A
-:107D30000FFFFFFF0000FF000FFFFFFF000000FF2D
-:107D40000000FF000000FF000FFFFFFF0000FF002A
-:107D50000FFFFFFF000000FF0000FF000000FF001A
-:107D60000FFFFFFF0000FF000FFFFFFF000000FFFD
-:107D70000000FF000000FF000FFFFFFF0000FF00FA
-:107D80000FFFFFFF000000FF0000FF0000001000D9
-:107D900000002080000031000000418000005200FF
-:107DA00000006280000073000000838000009400E7
-:107DB0000000A4800000B5000000C5800000D600CF
-:107DC0000000E6800000F7000001078000011800B5
-:107DD00000012880000139000001498000015A009B
-:107DE00000016A8000017B0000018B8000019C0083
-:107DF0000001AC800001BD000001CD800001DE006B
-:107E00000001EE800001FF0000000F8000007FF8FD
-:107E100000007FF8000005F60000350010000000AB
-:107E2000000028AD000029180000291900000005F5
-:107E3000000000060001000100050206CCCCCCC900
-:107E40007058103C0000FF00000000000000FF0020
-:107E5000000000000000FF00000000000000FF0024
-:107E6000000000000000FF00000000000000FF0014
-:107E7000000000000000FF00000000000000FF0004
-:107E8000000000000000FF00000000000000FF00F4
-:107E9000000000000000FF00000000000000FF00E4
-:107EA000000000000000FF00000000000000FF00D4
-:107EB000000000000000FF00000000000000FF00C4
-:107EC000000000000000FF00000000000000FF00B4
-:107ED000000000000000FF00000000000000FF00A4
-:107EE000000000000000FF00000000000000FF0094
-:107EF000000000000000FF00000000000000FF0084
-:107F0000000000000000FF00000000000000FF0073
-:107F1000000000000000FF00000000000000FF0063
-:107F2000000000000000FF00000000000000FF0053
-:107F3000000000000000FF00000000000000FF0043
-:107F4000000000000000FF00000000000000FF0033
-:107F5000000000000000FF00000000000000FF0023
-:107F6000000000000000FF00000000000000FF0013
-:107F7000000000000000FF00000000000000FF0003
-:107F8000000000000000FF00000000000000FF00F3
-:107F9000000000000000FF00000000000000FF00E3
-:107FA000000000000000FF00000000000000FF00D3
-:107FB000000000000000FF00000000000000FF00C3
-:107FC000000000000000FF00000000000000FF00B3
-:107FD000000000000000FF00000000000000FF00A3
-:107FE000000000000000FF00000000000000FF0093
-:107FF000000000000000FF00000000000000FF0083
-:10800000000000000000FF00000000000000FF0072
-:10801000000000000000FF00000000000000FF0062
-:10802000000000000000FF00000000000000FF0052
-:10803000000000000000FF00000000000000FF0042
-:10804000000000000000FF00000000000000FF0032
-:10805000000000000000FF00000000000000FF0022
-:10806000000000000000FF00000000000000FF0012
-:10807000000000000000FF00000000000000FF0002
-:108080000000000000000001CCCC0201CCCCCCCC24
-:10809000CCCC0201CCCCCCCCCCCC0201CCCCCCCC4A
-:1080A000CCCC0201CCCCCCCCCCCC0201CCCCCCCC3A
-:1080B000CCCC0201CCCCCCCCCCCC0201CCCCCCCC2A
-:1080C000CCCC0201CCCCCCCC00000000FFFFFFFFE9
-:1080D000030303031342020250505020706080508B
-:1080E0000200020006040604000E0000011600D67D
-:1080F000002625A0002625A0002625A0002625A0D4
-:1081000000720000012300F3002625A0002625A010
-:10811000002625A0002625A00000FFFF000000008B
-:108120000000FFFF000000000000FFFF0000000053
-:108130000000FFFF000000000000FFFF0000000043
-:108140000000FFFF000000000000FFFF0000000033
-:108150000000FFFF000000000000FFFF0000000023
-:108160000000FFFF000000000000FFFF0000000013
-:108170000000FFFF000000000000FFFF0000000003
-:108180000000FFFF000000000000FFFF00000000F3
-:108190000000FFFF000000000000FFFF00000000E3
-:1081A0000000FFFF000000000000FFFF00000000D3
-:1081B0000000FFFF000000000000FFFF00000000C3
-:1081C0000000FFFF000000000000FFFF00000000B3
-:1081D0000000FFFF000000000000FFFF00000000A3
-:1081E0000000FFFF000000000000FFFF0000000093
-:1081F0000000FFFF000000000000FFFF0000000083
-:108200000000FFFF000000000000FFFF0000000072
-:108210000000FFFF000000000000FFFF0000000062
-:108220000000FFFF000000000000FFFF0000000052
-:108230000000FFFF000000000000FFFF0000000042
-:108240000000FFFF000000000000FFFF0000000032
-:108250000000FFFF000000000000FFFF0000000022
-:108260000000FFFF000000000000FFFF0000000012
-:108270000000FFFF000000000000FFFF0000000002
-:108280000000FFFF000000000000FFFF00000000F2
-:108290000000FFFF000000000000FFFF00000000E2
-:1082A0000000FFFF000000000000FFFF00000000D2
-:1082B0000000FFFF000000000000FFFF00000000C2
-:1082C0000000FFFF000000000000FFFF00000000B2
-:1082D0000000FFFF000000000000FFFF00000000A2
-:1082E0000000FFFF000000000000FFFF0000000092
-:1082F0000000FFFF000000000000FFFF0000000082
-:108300000000FFFF000000000000FFFF0000000071
-:108310000000FFFF00000000FFFFFFF3318FFFFFB1
-:108320000C30C30CC30C30C3CF3CF300F3CF3CF391
-:108330000000CF3CCDCDCDCDFFFFFFF130EFFFFFF3
-:108340000C30C30CC30C30C3CF3CF300F3CF3CF371
-:108350000001CF3CCDCDCDCDFFFFFFF6305FFFFF5D
-:108360000C30C30CC30C30C3CF3CF300F3CF3CF351
-:108370000002CF3CCDCDCDCDFFFFF4061CBFFFFFEB
-:108380000C30C305C30C30C3CF300014F3CF3CF323
-:108390000004CF3CCDCDCDCDFFFFFFF2304FFFFF2E
-:1083A0000C30C30CC30C30C3CF3CF300F3CF3CF311
-:1083B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF22
-:1083C0000C30C30CC30C30C3CF3CF300F3CF3CF3F1
-:1083D0000010CF3CCDCDCDCDFFFFFFF731EFFFFF3C
-:1083E0000C30C30CC30C30C3CF3CF300F3CF3CF3D1
-:1083F0000020CF3CCDCDCDCDFFFFFFF5302FFFFFCF
-:108400000C30C30CC30C30C3CF3CF300F3CF3CF3B0
-:108410000040CF3CCDCDCDCDFFFFFFF3318FFFFF2F
-:108420000C30C30CC30C30C3CF3CF300F3CF3CF390
-:108430000000CF3CCDCDCDCDFFFFFFF1310FFFFFD1
-:108440000C30C30CC30C30C3CF3CF300F3CF3CF370
-:108450000001CF3CCDCDCDCDFFFFFFF6305FFFFF5C
-:108460000C30C30CC30C30C3CF3CF300F3CF3CF350
-:108470000002CF3CCDCDCDCDFFFFF4061CBFFFFFEA
-:108480000C30C305C30C30C3CF300014F3CF3CF322
-:108490000004CF3CCDCDCDCDFFFFFFF2304FFFFF2D
-:1084A0000C30C30CC30C30C3CF3CF300F3CF3CF310
-:1084B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF21
-:1084C0000C30C30CC30C30C3CF3CF300F3CF3CF3F0
-:1084D0000010CF3CCDCDCDCDFFFFFFF730EFFFFF3C
-:1084E0000C30C30CC30C30C3CF3CF300F3CF3CF3D0
-:1084F0000020CF3CCDCDCDCDFFFFFFF5304FFFFFAE
-:108500000C30C30CC30C30C3CF3CF300F3CF3CF3AF
-:108510000040CF3CCDCDCDCDFFFFFFFF30CFFFFFE3
-:108520000C30C30CC30C30C3CF3CF3CCF3CF3CF3C3
-:108530000000CF3CCDCDCDCDFFFFFFFF30CFFFFF03
-:108540000C30C30CC30C30C3CF3CF3CCF3CF3CF3A3
-:108550000001CF3CCDCDCDCDFFFFFFFF30CFFFFFE2
-:108560000C30C30CC30C30C3CF3CF3CCF3CF3CF383
-:108570000002CF3CCDCDCDCDFFFFFFFF30CFFFFFC1
-:108580000C30C30CC30C30C3CF3CF3CCF3CF3CF363
-:108590000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9F
-:1085A0000C30C30CC30C30C3CF3CF3CCF3CF3CF343
-:1085B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF7B
-:1085C0000C30C30CC30C30C3CF3CF3CCF3CF3CF323
-:1085D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF53
-:1085E0000C30C30CC30C30C3CF3CF3CCF3CF3CF303
-:1085F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF23
-:108600000C30C30CC30C30C3CF3CF3CCF3CF3CF3E2
-:108610000040CF3CCDCDCDCDFFFFFFF3320FFFFFAC
-:108620000C30C30CC30C30C3CF3CF300F3CF3CF38E
-:108630000000CF3CCDCDCDCDFFFFFFF1310FFFFFCF
-:108640000C30C30CC30C30C3CF3CF300F3CF3CF36E
-:108650000001CF3CCDCDCDCDFFFFFFF6305FFFFF5A
-:108660000C30C30CC30C30C3CF3CF300F3CF3CF34E
-:108670000002CF3CCDCDCDCDFFFFF4061CBFFFFFE8
-:108680000C30C305C30C30C3CF300014F3CF3CF320
-:108690000004CF3CCDCDCDCDFFFFFFF2304FFFFF2B
-:1086A0000C30C30CC30C30C3CF3CF300F3CF3CF30E
-:1086B0000008CF3CCDCDCDCDFFFFFF8A042FFFFFBB
-:1086C0000C30C30CC30C30C3CF3CC000F3CF3CF321
-:1086D0000010CF3CCDCDCDCDFFFFFF9705CFFFFFE5
-:1086E0000C30C30CC30C30C3CF3CC000F3CF3CF301
-:1086F0000020CF3CCDCDCDCDFFFFFFF5310FFFFFEB
-:108700000C30C30CC30C30C3CF3CF300F3CF3CF3AD
-:108710000040CF3CCDCDCDCDFFFFFFF3320FFFFFAB
-:108720000C30C30CC30C30C3CF3CF300F3CF3CF38D
-:108730000000CF3CCDCDCDCDFFFFFFF1302FFFFFAF
-:108740000C30C30CC30C30C3CF3CF300F3CF3CF36D
-:108750000001CF3CCDCDCDCDFFFFFFF6305FFFFF59
-:108760000C30C30CC30C30C3CF3CF300F3CF3CF34D
-:108770000002CF3CCDCDCDCDFFFFFF061CBFFFFFDC
-:108780000C30C30CC30C30C3CF3CC014F3CF3CF34C
-:108790000004CF3CCDCDCDCDFFFFFFF2304FFFFF2A
-:1087A0000C30C30CC30C30C3CF3CF300F3CF3CF30D
-:1087B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF1E
-:1087C0000C30C30CC30C30C3CF3CF300F3CF3CF3ED
-:1087D0000010CF3CCDCDCDCDFFFFFFF731CFFFFF58
-:1087E0000C30C30CC30C30C3CF3CF300F3CF3CF3CD
-:1087F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF21
-:108800000C30C30CC30C30C3CF3CF3CCF3CF3CF3E0
-:108810000040CF3CCDCDCDCDFFFFFFFF30CFFFFFE0
-:108820000C30C30CC30C30C3CF3CF3CCF3CF3CF3C0
-:108830000000CF3CCDCDCDCDFFFFFFFF30CFFFFF00
-:108840000C30C30CC30C30C3CF3CF3CCF3CF3CF3A0
-:108850000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDF
-:108860000C30C30CC30C30C3CF3CF3CCF3CF3CF380
-:108870000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBE
-:108880000C30C30CC30C30C3CF3CF3CCF3CF3CF360
-:108890000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9C
-:1088A0000C30C30CC30C30C3CF3CF3CCF3CF3CF340
-:1088B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF78
-:1088C0000C30C30CC30C30C3CF3CF3CCF3CF3CF320
-:1088D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF50
-:1088E0000C30C30CC30C30C3CF3CF3CCF3CF3CF300
-:1088F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF20
-:108900000C30C30CC30C30C3CF3CF3CCF3CF3CF3DF
-:108910000040CF3CCDCDCDCDFFFFFFFF30CFFFFFDF
-:108920000C30C30CC30C30C3CF3CF3CCF3CF3CF3BF
-:108930000000CF3CCDCDCDCDFFFFFFFF30CFFFFFFF
-:108940000C30C30CC30C30C3CF3CF3CCF3CF3CF39F
-:108950000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDE
-:108960000C30C30CC30C30C3CF3CF3CCF3CF3CF37F
-:108970000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBD
-:108980000C30C30CC30C30C3CF3CF3CCF3CF3CF35F
-:108990000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9B
-:1089A0000C30C30CC30C30C3CF3CF3CCF3CF3CF33F
-:1089B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF77
-:1089C0000C30C30CC30C30C3CF3CF3CCF3CF3CF31F
-:1089D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF4F
-:1089E0000C30C30CC30C30C3CF3CF3CCF3CF3CF3FF
-:1089F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF1F
-:108A00000C30C30CC30C30C3CF3CF3CCF3CF3CF3DE
-:108A10000040CF3CCDCDCDCDFFFFFFFF30CFFFFFDE
-:108A20000C30C30CC30C30C3CF3CF3CCF3CF3CF3BE
-:108A30000000CF3CCDCDCDCDFFFFFFFF30CFFFFFFE
-:108A40000C30C30CC30C30C3CF3CF3CCF3CF3CF39E
-:108A50000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDD
-:108A60000C30C30CC30C30C3CF3CF3CCF3CF3CF37E
-:108A70000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBC
-:108A80000C30C30CC30C30C3CF3CF3CCF3CF3CF35E
-:108A90000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9A
-:108AA0000C30C30CC30C30C3CF3CF3CCF3CF3CF33E
-:108AB0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF76
-:108AC0000C30C30CC30C30C3CF3CF3CCF3CF3CF31E
-:108AD0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF4E
-:108AE0000C30C30CC30C30C3CF3CF3CCF3CF3CF3FE
-:108AF0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF1E
-:108B00000C30C30CC30C30C3CF3CF3CCF3CF3CF3DD
-:108B10000040CF3CCDCDCDCD000C0000000700C003
-:108B200000028130000B8158000202100001023067
-:108B3000000F024000010330000C0000000800C0DC
-:108B400000028140000B8168000202200001024007
-:108B500000070250000202C00010000000080100DF
-:108B600000028180000B81A8000202600001828067
-:108B7000000E829800080380001000000001010030
-:108B80000002811000090138000201C8000101E85B
-:108B9000000E01F8000002D8CCCCCCCCCCCCCCCC94
-:108BA000CCCCCCCCCCCCCCCC00002000CCCCCCCC15
-:108BB000CCCCCCCCCCCCCCCCCCCCCCCC0000200005
-:108BC000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCE5
-:108BD00004002000CCCCCCCCCCCCCCCCCCCCCCCCE1
-:108BE000CCCCCCCC4100200003030303034202029F
-:108BF0005050502070608050131313131342121200
-:108C000050505020706080500301020000000000AE
-:108C100000000000000000001F8B080000000000A2
-:108C2000000BFB51CFC0F0038A0F093230688A2055
-:108C3000F8C4E05C760686751C0C0C5BB849D3075B
-:108C4000C32C0C0C0CDA4CE4E905E1FBBC0C0CAFBA
-:108C50008098850F559C871342FF015AC0C7CAC030
-:108C6000A0C1865DFF3A35043B408581A11C88D9AF
-:108C7000941818CC5411E2D2EA0C0C3380FC04A8EE
-:108C8000D81D201DAB46BE9B47F1E0C1378D51F981
-:108C90005B0DA169012A7E0B4D7E1B54BE4A074223
-:108CA000DF36C66E6EB50E71F69FB546E5AFB4C63B
-:108CB000AFFEAE3D2AFF209AFAAD503E00C5D55B0F
-:108CC000A7D8030000000000000000000000000022
-:108CD0001F8B080000000000000BED7D7F7C14D589
-:108CE000B5F8999DD9D9D9CDEE6608096C20E02454
-:108CF000861AFB82DFE577A841878034B63CDF8A9D
-:108D00005AD3D6F6BB506C551456BF3EE1F56933C5
-:108D1000F941122262049FDAD61F2B554BFB6C8956
-:108D2000942AAD3FDE024AF1F5C743AAD5D7A22F58
-:108D3000FE80AA455FC4D2D87E51DE3DE7DEC9CEB3
-:108D40004C76930DD01F7FBCF081E1CEDC1FE79EF7
-:108D500073EE39E79E73EE8DEAF3C3C7CE05388E06
-:108D60003FECD913028059D9A771F5BCAEBE99006A
-:108D70004721D2D35D0AD0A68009AC6C1D88A41F00
-:108D800094007F6A14565E2D7F3CDE5D097067D1CA
-:108D9000D7EEC3FA6B2C0502ECD9DD0C9039837D3C
-:108DA0000F453743314011A4B6E277F6937890F53A
-:108DB00037109C9C866876FC32F0D1B80015FAA179
-:108DC00022AA07C765F6CF81E47C18072083FDB38C
-:108DD000067A593FCAF3721AC795E5C5FA8B55D979
-:108DE0007EBC4F595721A389FEF01FF9B2E26438C7
-:108DF0007FFD35072AB73E5D93AD7F06444A0FFDE0
-:108E00001DFB8F020AC123AF07C4C3D130A4E5CA3A
-:108E1000FCFD0C341B5B9FF6231EBF509C989ABF31
-:108E20009E8DA7AE668D9E1DCD3A6402000C64B384
-:108E3000B7963DC3606EAE1DDA6E0148842FCDB08B
-:108E4000089EF6B02F5D5489502701187EFD881FBB
-:108E500009DF2FD1CC1CEDED279432FCD8F36578D7
-:108E60000C02EF0FD8FC1E64FD0571FC1CF8BA085B
-:108E7000C72F63DFAB878E6FCD3CF1F1436702EC08
-:108E80000B23BE4D84017C7A0AE282DE9F9486E940
-:108E900047D05931783F23E1BDA8C6971D97FD0DF6
-:108EA0001A21179F0462256EBEF1F225E2A90CE992
-:108EB0006548AF4FC9F6AB22DD72E0EB4A81AFFEE9
-:108EC000F989A604C3C7DA66B05E73B4936360A67B
-:108ED00073E069B568678FA794B27A39FA076811A9
-:108EE000EBC772D52F14BE9B4E10BE9BFF42F0DD28
-:108EF00026F89D49287AF6CF4F129CDEFE72AD2FE0
-:108F0000B68807CB21256DF990BF4B21FE207BF859
-:108F100035BECEECEFDF073FF5B303250E1BA74DA3
-:108F2000C0D73F9FCBBFB5D3D4F46689E4910BCEB5
-:108F300087517EB1769224F0A1F502F25FD1070A43
-:108F4000C05884CF844404605D7583369CFC015D09
-:108F5000F9539FCD775543F9EEE36C18842B14CE6B
-:108F60008DA7EF0FCAD1CBACD7583F5A90BD3F1D4C
-:108F7000FB2D8D55CC069C1DFDF8C577907CF271BC
-:108F80005CB7C758BDD942CECAD43FC911A8009218
-:108F9000F7B2A84FE3B0FA01362D733A7BE2FB1A21
-:108FA000318E34B45F6FBB0128E1F811F0D8725DE7
-:108FB0008627A89F41789404E1CBFBDECFDEEBE16E
-:108FC000937F7FB265BF9167BC1E89F869A4F6AF35
-:108FD000087E19C29F79E8BA5FAC33057A4D383DF7
-:108FE000CB47367F9D281F9D349FB0E1495FE4E168
-:108FF000130B52B46E5835AB7BDAE8F925079F6442
-:109000009CF5174B63F83C9438F10B834721BED590
-:10901000393C65D34BA93F09D7F819D88328231EBB
-:10902000D87C97D9ED214EEB3584768EA33D9B1CE1
-:10903000C12BC99290FBBCDE0D629DCF6BA8E0F006
-:1090400083E8DF032FEB4F73F627438587CF39DCA7
-:109050001B242EDF58FD0CE1D33BBE2211BC322471
-:109060002C1F6BB7598CEF955FF673BBE86FBD048F
-:109070004DBD61BE9E9638F4618324E484C6D799C1
-:10908000573EF991AF669C385F152AD7174BB9F553
-:109090000EB38A621746F2EB9D629FAD0F323141EB
-:1090A000B751D1FD74A9C445F742E15D7682F04E17
-:1090B0001C0A6F417C76A6E41B959EBCE104E10B83
-:1090C0007AE03B557C3D43F059A1F0DBEB60B4F016
-:1090D000CB43F15BD03A9A3B4AF8369F207ECB7C5B
-:1090E000B69D24E0CBB36EE7097A5BC0F9436176A5
-:1090F00038EE730A85EFD191E103F804FB6BBD6A8A
-:10910000990AD96B0013009E6E79D5B2942C7C26F7
-:1091100070B93EDAF1F78C4C3F31FE5B96599D1DDC
-:10912000FFF996B75CE32B8C7F90D90A1DF7854237
-:10913000E70DEFB9E6FDBAF49E6BDC13C5FBC18207
-:10914000C7FFA36BDEEF4B7F74CF3BCCE67D7AE1AC
-:10915000E3FEFE04F9B152AC97064977E9817CF64B
-:10916000FB0C41D7BBEDFA36BC79EA9F29E06A2FA8
-:10917000B0FE44D1FFE70AACDF2BFAEFC5FA652356
-:10918000D73F5DD44F15585FF2F175984F7FCE975A
-:109190006CFC816BFFD1A6713F88D9A640F09CA1E1
-:1091A0007E13AB21F5ED3E467BAB35A0B79592DF44
-:1091B00084FC226B0012E837F92624EB7CAC1F6399
-:1091C000C74DF761BD238AA677EBC01724FB1E3C71
-:1091D00010D9DC5D991D6FB59C6C929097DAA2FA5C
-:1091E00083E45F493549EC59668575F4DB0C5425F9
-:1091F0005A9696E23C0CDD62FDFCFA8A8B76627927
-:109200009326E9322BFFCB39736FFB0C6B35F0E102
-:10921000CE974EC37AD3C655B592BC3425C44F6998
-:109220005C35E5287B5E7C71561FE03F8B1D6566D3
-:10923000077CB6E9122EFFC5F7CF27DDE54B1A2FC5
-:1092400071B5BF34E1FE9E9D0FF07DC7B9DCFF30E4
-:109250005095FA2F0ED7C72A2DEE5FA0F9EA565483
-:10926000EF66F35CFFE1B5545EDF52ABB7B2F2E7F5
-:10927000AEF4B72C65CFB004BACC9652715CA5F9A8
-:10928000029BAF5AC7768FE73CDB35DBC8BFFF2AAE
-:10929000363DF38C5F9C8593CDB3E9EADC70ABFA85
-:1092A000FB13DE60F6D2C0CEA089F084F7CAE9A035
-:1092B0004474DD3909E9621527397D40AA66CF2358
-:1092C0008D3AA07FA4A13169C8ACBC31A6C5030604
-:1092D000DAC9190DF11E411ACC65EFE3BE20DA633D
-:1092E000AAFE07EA5F17DF7BE255E3D13FF2E3E630
-:1092F000351315B6DE77345BF47CB4B98B9EDB9BFB
-:109300007B262ACC88DFD27C173DEDF9A12431ECF5
-:10931000F9C9B8AF365B91DF06FCCC34423CCEF7DE
-:10932000D1FE7603CA113FCAE1745B14DFD7C1B422
-:109330006E40B9C4E5CBC6F8B6DDF87E633D4C435C
-:10934000926D3437B745D93CAE2B87E9D8F7CE9725
-:109350001FE3DF2B607A8095773536905CED89FBD3
-:10936000D2814A82FF7CE4E79E461F3093078AEB56
-:10937000185C0EBC0662EEF2AE4626B066123ED215
-:1093800001293B7F852D33C4C746B32AE8DC57CF7C
-:10939000DAE76E7F66DA5DDE88ED87F14BCDED733F
-:1093A000D79FF392BBCC24DB2B837CC0F1F8AF3E7C
-:1093B000260F76BF3CDE67E1BC4D3E4FF6E4FEC2B1
-:1093C000982F8DC6E716813F1BBF03112E5F3636DF
-:1093D000733F603E78367EEAAAD8707E03B5B1232B
-:1093E00081FE54B5B1270167E1332D9EBD09A79FCA
-:1093F000D57EBE88C68FC35FD211DB58B2B4360BA0
-:109400008FB7FE785925793750C6BF77C45ED3979A
-:10941000D63AFB93BCDFB5CBC3CEEFDCAF32506E98
-:109420007F3FA22D0DE7683F897DCF4197A532FF91
-:10943000FEF4CB81863B901F057E77BFFC13AD1AEF
-:10944000F1FDBC0CC8671BF73590BC453E4379B1B4
-:109450008BF1455F2DD27FFD2BCE755B5CE72E3304
-:10946000BEE2FCC5FAC5A17E86F4601DFEBBF0CB52
-:10947000EE157ED93DCD317A3EDD6CD07357730D3C
-:109480007DCF34C7A9FC54731D959F6836A9FCE3B2
-:10949000E6462AEF684E50F9D1E6267A6E6F4ED234
-:1094A000734BF315F464FC4BFCBCA13925FCC06B79
-:1094B0005CFCF0F7F1808BFF3E5DE32E9F6F9C918B
-:1094C0005DD7ECEF2763EEF279FA275DE5059ABBED
-:1094D0003C1FBEE2EAEFDC0FBEEC2ACFEBEF70D50B
-:1094E0003FFB4D77796EDF439EF5E22ECFDAB7C7AB
-:1094F000B31EDDE5E2BA43AEFE023177F97E1432E7
-:109500005C4E117F74C45A4B72F2CFE0F78DA12FDD
-:10951000B9BECBD47E64FE59D65589FC93F6C52DD1
-:10952000943B26E7275BEE78F9C4A6DB48FC65C3CD
-:10953000F197E6ABFFE5A7E1F9A9607EA85772F2C3
-:109540008397EE5EFE18226704BFFC2F1FFC6DF0B0
-:1095500001CC64C42ECFAF5773D877649F061240F6
-:10956000F69D1FED34477B75722A69E6D09F57F947
-:10957000E66F95593F8152E8C0786840C9E3E795A6
-:10958000F93E25A0F1EFC16A93ECB26230A6CB633D
-:1095900000AE796C5EF932F6FEE7421F765C089603
-:1095A000C4FA1B37414DE23EA6B8DABDDF7B46E682
-:1095B000FB18FBB9E9879126FC0EA5334798378F36
-:1095C000D7C8136737FDC660CF0B666F59CBDE86F1
-:1095D000AA9319F2019596927D9A0C19D4AF5997D6
-:1095E000B67CA518478338DA8972D884241B67AE05
-:1095F000CFFC05CE9BD947FF21CFCADA3D9BC4F3F0
-:1096000047621D5EE4337F29EA3D3F5C3D7BDC1110
-:10961000E905494BE2FEA9F8830C447F69DC653F0C
-:10962000D9F353948499C8616FFC4EE04BD2E34D5B
-:10963000DC0FA202CA877CF50FCAB6FFC972ED071C
-:109640008BA13F23231C311E6F82631719174E1DF8
-:109650000A87AA2492380EC6AB37B371DAC77CC624
-:10966000483AC6F948E67E2A2966123CAACEE1515C
-:1096700095B899C8C14703021EBB1F3B6E26C5FAA9
-:10968000A12F9C856F6D30D184FB256B8C4A786A45
-:109690008FB8EDAF190AEFA75A3CDBFDB9ED438057
-:1096A00056BE1F1E57A761FF6D750D1ADAD78C1DA8
-:1096B00068BFD21E5E523C9CBDBD5ED8BFDD280F88
-:1096C00003180FD785BC8AD1B33DBCAD11D7C1D12A
-:1096D0005A8687CAFCFD44E2EEB86E514DC813C7E6
-:1096E0004D139C41A3C413EF9DE06AE71FA7F8EC5C
-:1096F000B8364823C3DF21E0B7EB752A294DCF895F
-:10970000273EBE5D0EC4DCF0FEF9F0C7DB17F97B27
-:10971000F55C709D2ABCE58BC3DA4F75AC9A4A7331
-:109720007F4ACCB90E3E2BF84B1DABA5483E69F9DC
-:10973000BE8778FB7082FC5B5A38614055361EABA1
-:10974000E17A70E0E95AD1EED78A4FACCB540CFDE8
-:109750005C92916A427ED22AD83A9286B6B39F49E9
-:10976000D1BEF3C3FFF712AD93328DD68964B075C5
-:1097700094631C4931AF56D8F31DD9BC46C1F8CC0F
-:10978000477232D77A5921E0D116270CAD8A427838
-:109790003CDFC303C73A85EB834336FC568AFC564D
-:1097A00085C2BFA640F8ED7118FCED02FEB5C3C13D
-:1097B000DF26E02901A3857C990697B300171ACE0E
-:1097C000BC8B37C4F825424E314C11DDECEFFF2540
-:1097D000FA29743E1B059C23CDE78D2C3DEEC579FF
-:1097E000B0F9DC87F3CA379F7B041C6F285CCF6815
-:1097F000898411AB22559F93AF9E1070F42B228E5B
-:10980000665D3B2ABEFAD702E7F144962E8F09BA6D
-:10981000EC186E1E8F8A79F4C830F70DF4339E2E43
-:10982000F40E2C71D1E5A8C04F4FC0A6CB752EBA4F
-:10983000FC4ECCABD0F93C53209F1DCDD2E5393145
-:109840009FFDC3CDC751FF4551FF25519FFCE74701
-:10985000952B5AAD5AFC9E38A0CCCA8EC7EABDECF7
-:10986000AC776DFB2CBBDEABC80F5223D783ACDECD
-:109870006BCE7A605DD08AF6DB5A8C897E02E081FD
-:10988000F6AF3688766F52BBC583FDBF25D607B5C8
-:109890005BD73EBFD50A53BD77F07DCB828FEC7A84
-:1098A000EFBAE15D61C37184E04D0CC2F1BEB3DE7D
-:1098B00013CAE7A9BF217947B19282EC1F7F699251
-:1098C000F2F74A20D283FEC50E2545FE640C36A071
-:1098D0001F7275204EA92A23F9A3CB2EE6ED7445FD
-:1098E000237F6A005270177BBFA154A1F8C862257C
-:1098F00019F1A31D21252D0AAE827E590BF63FD604
-:10990000A0FC2F1B9EDB8ABED845FD3078B0DF3B24
-:109910008BA23B91AF364E520DE4AB9D936E20BFB0
-:10992000F96D2D3C7FF0B6F355DA676D7A3942FA5E
-:1099300077AD12FF2CD6B74CD5403FFAEAD0472F6F
-:109940002D67E5BE96625D3A87E641705B3E48B49E
-:10995000CD74E42332B80371CAA7233FDC6D8D3C7C
-:10996000AEC37ECAB1FDEA0546BCDB40F1C5E418D2
-:10997000FBDE59A792FD7A5B45D57C1C6F539D4653
-:10998000F6C6A6C5552DE4C7AB0B91BFB2246C48F3
-:10999000E8678FCE519901CECAA5460BDA9B91D9C3
-:1099A0002140BF5349051F2F7206901FCA0F3D89E2
-:1099B0006AF68C76A990198BFD2DC97C09ED99BAB0
-:1099C00000F9E1D9C4F6D78EA39437FE23FF0C101B
-:1099D0001EFF441910EF367DA33D83ED87CD638CC8
-:1099E000A60BAC9729AC5EA44B81CC8C02EAF51493
-:1099F000582F5D60BD0CAF17800B87CDE78338CF44
-:109A000023D4D81F9EC7E8C82BACE4F6BBD36EF1B5
-:109A10007BBE8F362FF42ABFC80B9D0373785EE898
-:109A2000F0EDED7CD091E60BE0CBC2298F5C7F6D31
-:109A3000F3F07E63FFB81B62987FD959F655F1BCED
-:109A4000913FCBC5FBF2353194779DE5E27BF98DF3
-:109A50004DB9F6AF77FAB91CAE81C4B0742811F0D5
-:109A60001F62B0637E4F8DC2EA47F2D7574B7DC36A
-:109A7000E6596A8AD540EB76B18FD66D008501AE86
-:109A80009B0ABE8EFD904A54F37855B4DCB17EFC3F
-:109A9000F57B68FDFCA25C06A98EE813473C7AF9C9
-:109AA000C4CB170170942B4F9E4FB6FE99F8C4DFBC
-:109AB0002517B47EFC3D05D64B17582F53583DB59E
-:109AC0004B2A48AEA83D05D64B17582FC3EBAD9D8A
-:109AD000AB727D0E7F68C578BFFF139AABBCF613DF
-:109AE00021F7F7B3C3AE72C72C777B75B6BB7DC7C2
-:109AF0006C777B750E6F1FEC800518CF2F749D1C43
-:109B00003CC17552A30D5F3F5237C2BAD2F420B6A2
-:109B10002F510CC89492BE4A0BBD95331E7E9ACA33
-:109B2000D77F959FC7CF6F53F420EE23FFD6E72949
-:109B3000A93C9FC09EEF48F0DAF2F7B7B2B0B7F297
-:109B4000E47D438C9F7FF043288E768EB1506B78F6
-:109B500085E1D1FF2CCF7BF7F6FB8A9A9CA63AF6DB
-:109B6000C5CC3E83A4C30F737E99C2F36D181DD07C
-:109B70001E5221D158C9FA6BABF0913DA28447D057
-:109B80001B150EB995232F2FEB970213CF53D02718
-:109B90000360FE9B7CDC501C08EE08F4D166BA180A
-:109BA00053E54E07180386C493BEE212CF13ACD719
-:109BB000519E95064F75BF9751BF92791B1C2F1A66
-:109BC00045BF4A1FE5CB9CF27E478037087753BFDD
-:109BD0006C97547A7C6CB65F7F2C452F314F56764C
-:109BE000E4CBE1B908CA37F1C53394DF30214AFB31
-:109BF000B2B5A5D7B9F2C1FF59AD72F98754BDE32B
-:109C00005A09E3BA15579B7DC3F079331357E4F72C
-:109C1000AC586EF6D5E4AF3798A78FF99E39D64188
-:109C2000879A4CA3FD6E4D0EF3FDBC92227F63A775
-:109C300054321DF32DEC7A4A0593B40CAEC84CD3C4
-:109C4000C2FD5EE7585F1CED5405D6EF93CE62ED82
-:109C5000E4C571A7FFD2FB542A94B79DF3B95D65A3
-:109C60007A12E1147AB26D047E1FD1EE51E3C95C21
-:109C70007ED16FAB7C5FEB0FE5FEDE176A78409D0F
-:109C800035146F8F217E717F3B06BAA4FFC3D9873D
-:109C9000F2A52AF6BC8478585BB62836DC7CD90657
-:109CA000EAF0205D18897F16321F4179300C1C3F85
-:109CB000CC0507840BF37FEB0BE3C48783F65229B3
-:109CC00088FD98199518DF870457DE32737306CF25
-:109CD00043F897864DA49F6C6E01F457DB76936C26
-:109CE000865EF5113DEBB9FD54C3ED2193FDC179BD
-:109CF00044EB87B7AB654FF939D56D0FB535EF003C
-:109D0000679E9BF75C85FD4C871A5ECC8D8FC2F6F3
-:109D1000C3B7337EC13CFB8DCD1A22057A9A752AD2
-:109D20006F688E51797DB341CFF6E61A7ADE8C4D9D
-:109D3000E7E2F9A7545725C35B57EC81D8E5ACCAD5
-:109D4000ED283B288FEFDE05682F770F96D93690E8
-:109D5000C1DD3D09785E9F7AEB02DCE7770741F8C9
-:109D600015DA16A05D9D2DDFD1361FCBC2CF10EACC
-:109D7000BC6F01EEF76F17F90FA098DA250EBD77CB
-:109D80005AC04FFC477B576A6FB5617F414594E1EC
-:109D90009105EE3298084F50E3E505816DD43F8977
-:109DA0000036DEA7033FE0E34D11F96DB54B46C029
-:109DB00023F7EF5BAAC1FD5DB525143F52E3717433
-:109DC000BFC2ED6304DC05F6034A92EB3B718E2FB4
-:109DD000FFBA1941AF093846A23F4307F9D1EDF365
-:109DE00069CA0BB9F5F4A91EF776FFE8F0A2D6F51B
-:109DF0005B7886ED09353927C0DA47CCDE4C252B58
-:109E00004717672C5ABE058E3B3660E7392669FD39
-:109E1000DB7856746E77ACF0D0D15FCAE3754171D0
-:109E2000FEA4507893AA1847F4030F37940F67AF36
-:109E300095257C68840DCA8BB18D21E19CE1E531CB
-:109E40006689AB5C5C37C1553F12AF727DF7EB1F83
-:109E5000777D3F513A5DE299C7A784DD6897CFF5DA
-:109E6000CEB3C07E0F1627560570DD34404D8AE113
-:109E7000F5CE2F3C44F80F0DAED385ED6605E58396
-:109E80008B753D8F9775FB7B5DBB59CFCA86FD7D7A
-:109E9000062F9BF6F738AF6FD9DFA7F2EF28F759F7
-:109EA000F96B9D67B45BF81D5AC96F0B152958E211
-:109EB000A0CFD8F10DAD08DFF8CBD2318BBDEFFECE
-:109EC00050E6F2007A62CE7A776ADC0FFDCC943BE2
-:109ED00062E8AF5C77E64331207927E58C07FE3CEA
-:109EE000C0F3C5CA42899E00AD77B3BF98F1E1A126
-:109EF000876483EB21E535D4873E8BE7E3AB10DF46
-:109F000067A25D54C3FDD521F19DE85899AD3F4846
-:109F1000574FF9EF34AED77F87491B0CCEEF159B17
-:109F2000F7D0B890961AD97AAFB0A01FCF1F81B0E2
-:109F3000FB26F2A6509A48939F6F12C3A7CCBE4F40
-:109F4000BEB8BFC5CF706D5CA6FB7089542D8FFB6A
-:109F500048C00DDA9163A5E3ECF93DA417CAE39B71
-:109F60005280FA7BED990F35215E02997F0283E1E1
-:109F7000ED1F27A5C040FF6F80C315B8AC07483E52
-:109F800057F7109EBDF85A3788F7B40BEF3F0970AA
-:109F90007F7E2CC9DB0DD65358BDA943EB75077BDB
-:109FA000E6AB68BF4DE178F48EF35E4012E776DDF4
-:109FB00070D8FD7AEBDF1210716D2D4DF18D67CEEB
-:109FC000BC21867EEDCE298CFEB5F9E97F4B80E77A
-:109FD0005B19C76E22B9DB3D6923C533D7556F26A0
-:109FE0007BF228B323F0FC747765EEF69DCD3C3F01
-:109FF000E65CB8BBB18AD1A7F37999FCB4DE7ADF0D
-:10A000000954B9E28D5A857B3FC8F8AF0FE5E8489F
-:10A01000FC27471EE0EB72947C8766213FCF50D629
-:10A020008EF6805F94EF0E1C6F13FA9FE47FF9F2B7
-:10A030001E70E64BBE2FF82213E0722658C1F9A31A
-:10A04000DB6F494EFAC5D8FBF98E76F9E8968F1F7B
-:10A050001E17EBE17D25DE44CA5F49E9B9E4B3127E
-:10A06000FBF42F173ACE7BB52B694D47F86B364A78
-:10A070004EBBF61B6632A439F627A1D805BF5C8813
-:10A08000FB1F259E739FFE29D38C6A6CFC9B9B61F2
-:10A0900046359E4B50AC00D6BB59C934D2BEA2DA6D
-:10A0A00047FEF27515D7EDC53C2BABD617C76A6DC9
-:10A0B00015BB1AAB0CE4976D9467FAA6BE2486FD17
-:10A0C0000462EA8CEAB194DF9DC079876B59BF0EB8
-:10A0D0007ADBE3DE2DF8F65BBA3959E3F2E034EDD2
-:10A0E0002F200FDE87788C1B590CCF39F65743F1A0
-:10A0F000CCF3043A2B86E0798EE6E0EB00E27906B9
-:10A10000C9FB9CFE0B86E7B35D780686E7A9593C40
-:10A110007757703C77D66CEEAA72E2B966D7DE4A02
-:10A1200003C7E7787E48E3E773438867079C5E3C94
-:10A1300087255BFF7CAC1DF9D6CBF70CEF7F8FF04A
-:10A14000D8EF3F0AFC82ECE1B1E313176AE43F4920
-:10A15000D1FEE94E29AF5EBA442B402F758A757443
-:10A16000A7C03FEBFF0BD47FA9E8DFD6B7421FFEA5
-:10A1700083F66F0B501FB27ACBA89E9EA27DF06033
-:10A180003D0B86D5A3ACDD95C447614FFF268C4AB5
-:10A190001FB37EAEA37E34CFF8069C949E67FDDE8F
-:10A1A00044FD2A9E7E4FB13DC1C6E926FC81070FC2
-:10A1B0007F663B2696F4F083D2E3927B363F942F62
-:10A1C00077D7CBAFD77AB85E1B6AD710DFFEBC73E8
-:10A1D000CF6EDC27BDA99BDF46BC8E761DD876608E
-:10A1E0005928B94DE376209D83B0BE51946E636DBE
-:10A1F00095E33D511E7F77EBA3F1B63D54CDF5407D
-:10A2000070947A699FB0D73AC6301955CC9EFE44F7
-:10A21000532E3FC3339A9DB7E6B69B7F8373243F8B
-:10A220005182FC6BEDB1CFECE863B4331B7B20971C
-:10A230009C4F86923FC7F9A9BA65927A15FE917C28
-:10A24000FD9626AC9D7B6792DCEDC7BC461072186C
-:10A250004D6BF4C74519DE0E69E4C288A37FADECEF
-:10A26000626B3ECAB10AC62F587F5CD33E29992B38
-:10A270003E6EEF7F10881CFB97719F9B9DA47CB85E
-:10A28000C53347D8DFB4D8F6EB6F715E87D49E0B29
-:10A29000A638F06ED3E90E2971E179284FE7713ABB
-:10A2A000158F924E03824EB098E7A19E7BEC5C8D99
-:10A2B000FC8B115F02FDF0417F8F5EE2E0A3713EF7
-:10A2C00048F68E02FE7AE8DF7D1CF77F611FED778E
-:10A2D000BBC3CBBE83F7EF58BA1A9F6264C7ED6663
-:10A2E000FABEC4A17FBCFEAAC17DF4E2C2F265A79A
-:10A2F000587328DE9FBD3FC89D7FC018AB06F3860C
-:10A3000056CBDC7F7E67D1D7280F618D15D003A592
-:10A31000A4C7C8FE5B27F2D93A453EDB5A91CFE687
-:10A32000B7566FC5FA9B0012E8976C9997A2787F91
-:10A3300054D1F4D638C2919A837A225A6AAFCF1F89
-:10A340002FC4F53958B6BED1DEC0E61B8DD9E58DD8
-:10A3500064BFB5B77079F3D9E00B0BAD7A64C53E35
-:10A36000A2C7A6BA25C5308C3F325CEBCE9F0B55F9
-:10A37000875C65ADA2C455564B270C1BB7F819FA7C
-:10A380008966E17CFA208E70E6C9179E12E476B6E3
-:10A390002C4FEBCF60BEC1D96A7CB381E7A8DD79D1
-:10A3A0009CED416E0F3E8A0E218AE30ABEA8E3713E
-:10A3B000D5A2B955BD180782319C2F304FD0C90F97
-:10A3C000F9F8E2AF8D1F5FD1E118E65DDCD21A0526
-:10A3D000CC73B965EEAFE21903E56A5F0CF333DACB
-:10A3E00098246965DF37CCFD9591CB9F7C404B2E3F
-:10A3F0000F22FEC209B2BF223393F4FC6BCF6B2451
-:10A400007ADE19E47A6E8AA0A782F49C99A5E7BA4D
-:10A410003A46CF99D975BE4EE9D10AA1E7F9387EFF
-:10A4200019CAA1FFA67DDBCD75BE46944306F45242
-:10A43000FEED865A9F0FFBFF6BE1C5862B3C97C94B
-:10A4400047A25326817A61435CF1A11CF99BE3C3C7
-:10A450008FFAE87D017CF8C35C7CB85CD0432EDACF
-:10A46000D7942BEF6E4A5072E1653DD28BE3A591F4
-:10A47000E3C5F757C1CBA0BED0922B916FAE88A990
-:10A48000B4EF564ABA3A285EC4F41EC61B56C8A694
-:10A4900081F126F8969FDFC7847ADBA15FFE180C56
-:10A4A00072FB445EBF88E2186C6AB82F63E58F0DBB
-:10A4B0001B0F4DFBFB9DF79478F3325E0BBAE31054
-:10A4C000472A961423BDF2F5F776F35E1DCFD5DA51
-:10A4D000F919DEEF2B6448E53AB72885346167F651
-:10A4E000AA84871B99AE9D86F8F8D8423C9FD9591B
-:10A4F000D13A8EEC1871AE61C5966775C501E70A51
-:10A5000085A9BFE943E763E37705AAC91247FBF4CE
-:10A510005E577B6FBBC1FE447B66B7F9430C3E536D
-:10A5200049EDC578B37D7E43DD323F436A330FDCAE
-:10A530008C8E270577A1E7388E3CD0D681FB6DB491
-:10A54000BF3EC1F8E4B78FC8F156F6F58ABBCF58C5
-:10A5500088E75A0F01E7179B3E6F3DD0362E175FF5
-:10A56000E4A3CF79A12087E714F3D759210F7FF512
-:10A570005E549C8153CF5F8BF3F197C0CFE15E8E29
-:10A580000FB86B6C4E3AE59BCF209DEC7682CFBC2A
-:10A59000EDF3B5637C95E07C95899E5D085F097855
-:10A5A0006DFA9D2CBC23F155608D6CE079AE4A2587
-:10A5B0004172B3B3F43A4BDCEB48F99E72CFB48CE2
-:10A5C000B8D74AE4B54306ED8940A949767448DC1A
-:10A5D000CFA355BBE5A612739F9B8835253276BF66
-:10A5E000E8BF0CAC5169DCC1F8711832C12896790A
-:10A5F0009C14C51FEE2B02F04DF27BB27639FD9E06
-:10A60000F65311F96A98CB4BF7B2C1E747C86F719F
-:10A610008F13BB78F8FC1A6F7D082BC62107DEF379
-:10A62000B753E090639FB341DC2B6AE3DFDCB29465
-:10A63000F2CA83E08BD3FE20D661E1BEAF43ACE724
-:10A640004E7CCEC573BCD375DAAF55F0788B257DC3
-:10A6500099FC0CF6B9337B3CFBBC995D6F24FAAFD7
-:10A66000C6F594637DEF0A717D3AF0B5D47FE33E81
-:10A67000C4FA1318780FC5E3CD1F509CFA9CCC5B2D
-:10A6800032FAF79F098DA37ECEE9EF931738D6E50E
-:10A6900039E21C0740AF9CEB9C97DF0AEC427E78C6
-:10A6A000EA30DF8F3D75F808D9E14FFDDE9746BEF1
-:10A6B0007BEA83E1F31E1E17FB22BBDEE3BFE7F656
-:10A6C000D9E34A6F512EFB2E3B7E9AEF070FBBF961
-:10A6D00015945E19F965E0A67D32FA071E6FD6A4BF
-:10A6E000D799FC9927E679CEE13E19F74D23CD6B3A
-:10A6F000AB87BEF63CB7D6737B746BFD9110FAFF47
-:10A70000B73EC1E77BB49E9F8FCD07EFAE669EDF5D
-:10A71000B1F589DCF86898C7F7C70D7EA334A75D4B
-:10A72000EB3967B54093DDE7BB4E317CBBEBB9DD60
-:10A73000B55B89874F049EBCEBBBAEA711DD08510A
-:10A740004836CE9708BDFB5D7E92035F6FF932E617
-:10A750006B2C0D9B12EE65A12FF3249B5789A92525
-:10A76000F0DE98E2FA1E6932E677C4781EF937AF58
-:10A770007E2DF3322BDFDC5444655D379E5B84F81D
-:10A7800028D5C99F72337A5C48407F732DE627D065
-:10A790007A64E5C0CD3DE7A13F4B012E2F98C56BF4
-:10A7A00028E3E85E3F72D2E4931BEC473A1EC8B63A
-:10A7B000CB3B4F4FDE6D00960C2FC796F3FA16FB7E
-:10A7C0008372A8C49367A22F74E7A5443DFD4F454B
-:10A7D0005BB5AC80BCF2931C670C6CD30CDC67D708
-:10A7E000FAF434D607630CE60D861B9981C4E83968
-:10A7F000460709CDE591F0BE0EA091FBBF33E03CCA
-:10A80000A7D350C4E5D584AB6E97709F7134CEB892
-:10A81000621A96DFCC997FD52EE4C76059DF45F2E6
-:10A82000B4037AF7525C20E9233BFCE6DAD631CE5A
-:10A83000F64B8B24DB1F28E80F86323B4B7F363FDD
-:10A840003378D65F8EFEB1E56EBC8F962ED714712D
-:10A85000793512FD4F761C9B6E43D7478BA0DB03E7
-:10A860001417EDAE195EEE0FA5DB36D277E1DADC18
-:10A87000F9BAD715492E796C3F3548419CF1892C9E
-:10A88000EE6796C7CF6EBA7F18F9233BEF67866CE9
-:10A890003FE38C1E13E356E3A1C7C473DF8CA7E329
-:10A8A0001940FE3601ED24661E111FC99EFDDC46CF
-:10A8B000C14741789EDAB35560E9A45752A03BF2F4
-:10A8C00054CE93C371F45FACD3C3742F12CA4F9E9E
-:10A8D000BFC3F3FC8B39480CBFFD80F22D542E838F
-:10A8E000857EBF7A01AFC4F80EF3FB0FBC7500F78D
-:10A8F0002BE1996E3A29078A28AF2DE43D2772E0B3
-:10A900009A6B687FE3A1E368F3FEBF5F24ECFF224C
-:10A910000893DD24DAE7CBDFB3ED7E1BBFC6B108B9
-:10A92000E5ED741C90081F659313F7E3FE0C7E257C
-:10A9300003CFCB0413F3F656FF74167D1F1A574846
-:10A9400054225DDE3A50A4B75616922F9948B6B0FD
-:10A95000FAC68140BCD520D5E2D3908E7D12D1516C
-:10A960001AA751BED6EA7FF7DF1F18265FCB8E3FAE
-:10A970000E96158BE29B5DC674CD294FCA42C95F06
-:10A980001639E3F622AEEBF5AF07C3EDB16760F41D
-:10A99000F18FD2F120E2F29F5F84F64B17AE019E59
-:10A9A0001747797A5DE5BCFC46D1944518DFE98A02
-:10A9B000F07271F8C8792D246713E4FF5BC3180E99
-:10A9C000F1087BFDE21E4963FC85C3C80BEFFCD791
-:10A9D0002BFB284FFE9EF0FEF3CF40FAC47DE48FA0
-:10A9E000BBE7FA6DAEFB93DED41BDE2FA2F5AAB750
-:10A9F000637C7A62D2CED774C74526A0D660F39B1B
-:10AA0000C408E3677838ED626845B6A9BCACB71CEA
-:10AA1000F7C96B4BB78DE1E7FD17EA87C86E972939
-:10AA20003E9D0F5EAF9D9E6FBE76BCDDDBFEAE0829
-:10AA3000BF47D51B17F3FA831E44FC9651FE2C60CA
-:10AA4000FE6CA7BF2F673CEA8D22EED76CAF5894FF
-:10AA5000B81CE7A598730F327CDC5B1AA57D90FFCC
-:10AA6000A2DA4B7D0E7BC3CE6753C47ECE5F9A22A3
-:10AA7000B9A86866D719182F7A5EC61505153D3B2B
-:10AA800025B4E7EDFB2010AD174FE5F3C579058040
-:10AA9000DBC5785EE1B863DE1073F8C1509E88FDB7
-:10AAA000DB29A0F7B4F0ACA1F49DDFC5F3D0635768
-:10AAB000F0F34D1395DCF41E7F99EEE3F1AF534BA9
-:10AAC000E77CEDF3C53DEF8AA8B47EA6E8ABF7E2DC
-:10AAD0003D771D567112E33103FE5417CAAB0DFFCB
-:10AAE000E883CD34FFD1E937454FD03D7A15297D34
-:10AAF0003A2EEF7CEDEE48ED0A129E2D9ECFE0FD42
-:10AB00007E7998EB9B9E94EF36FC6E3E9DDAE9C70A
-:10AB10007D678CEFABED7D783294BC3CECB0CF75AB
-:10AB2000D3223E9A92BC94E4C0405961F72F0CE2C4
-:10AB30002B4F1EF31D11AE97A718AB79BF9386F765
-:10AB4000CBDA78F9A04B16BF1721134438FC8C914F
-:10AB500013B82E6EE472E2EE35BBE8BD7263DF7CA3
-:10AB6000FEBDBF05F5EA1D3EB82297DFA82DC2E362
-:10AB70004193CDCC3AD41B93533E40FBF4F688412D
-:10AB8000EFC75FC6F1D43509E238EC69D81FFBCFB7
-:10AB90009E4A95F4D2D852A0FB92C6AE01D2DB6396
-:10ABA0006B206DB072D7CEB93BD1BE55AB218EAE06
-:10ABB000EBDD953758680F6CAA0013F5B8FF46B661
-:10ABC000C0587DD5F0A53150BC29B58CEE6959CB64
-:10ABD000D6255263ADD140F6C3D1182F072AF839D4
-:10ABE00098AE331582C3BE7F9CEC4EA61FFCB5FD0C
-:10ABF000265EFD65C015D48F7F2EA7AB71573D9D96
-:10AC000053EB1AF310DD4B635D033CDE69C7A515FA
-:10AC1000C65F6C9CF62BF49CFE9523A1E4B79DFCCB
-:10AC2000C0F891E44C17E613E4C0676798E3F30EAD
-:10AC300021E706FCF0298A97B4F8E83E176FFD6516
-:10AC400002FF775B4BFEE10C23AB6FECEF078B0C45
-:10AC5000977FA3E20395E6B348BE1174A43BB39378
-:10AC6000E8FE17BC18F4745A9617943BCEB3DC1B5D
-:10AC7000EF85C98867DB2EAAE5F68C7DEE91E12190
-:10AC8000730FFBAED705E87ED1F14DB9ED23B5408A
-:10AC9000FBA8ABC8FC6918F30D443EFFD7972F21E2
-:10ACA0007D9FEFDEDABB235CCEDF2559951D489FE3
-:10ACB00049FCFE196FBD83C25E64F620F1CD268B80
-:10ACC000DFBBB5896D7D1E45BEBA9EDFF3C7DEF3DF
-:10ACD000730E06D079F1D80DCBB45CEBD51B57CEF3
-:10ACE000B7EE826A5F3257BCA556D0AD24AECFF71F
-:10ACF000F1E983E9B0478B6A81EEFFD2197DD0F686
-:10AD0000AD805E4ABADFD858528971A15B6F540D8D
-:10AD10007C7F5F65AFB510E72D41EF839823A3F4E7
-:10AD20009A781EBD223ECEE8769CF72EAE7894CE61
-:10AD3000C3DFFE54000275783FA9E7F7D938E9234D
-:10AD400067E96CEBAB7CF32BF4790BC397F3F780DB
-:10AD5000308833388F220B0CBA1FD9E8253BF4A872
-:10AD60001544DD0A467D2FD72BED2178308EF7CCA8
-:10AD7000F2F2A6F054C0FB6735A597EC754DAFA273
-:10AD8000725175A29BECF369DBF55CFAE153914AD1
-:10AD900097DF24E4895369C91B9AB89F56852939DE
-:10ADA000D6D9C12285DBD3AC29C573ADE1E5EDC9A8
-:10ADB000F2C79B42DFE8D97D32F107C92E468F707A
-:10ADC000C5A2B764C77D9C61EFF9622F3D3DE59355
-:10ADD000A5E73AA4A723BEA0D52735A49FC1EC249C
-:10ADE000B2FBEB019CF7A66FD22C7E0F8361F82C8F
-:10ADF000077ECB85DDA77CA0D079DBBB9676D0FE25
-:10AE0000632CEB03F37AD933E7BDD3078B785E78F5
-:10AE10005751624984F27281EE195E27E4C679F2D5
-:10AE2000CF8298871504A6E7908F16FBE0C11C74AB
-:10AE30002D8F703CA743E6E722B3F2CFF77129F7D5
-:10AE40007DA276FB83C20F50B81CE6F39D620ED044
-:10AE500079D2819B0AD3DF036C6EFBD02E57E25C64
-:10AE60004FF719D03E93EE7F4AA3DEDD145B4278A4
-:10AE7000BF0FF529DA56B55C4FFA53DC4F0C864408
-:10AE8000F7CA86C4BD1BF7A58E3C8B76CFD11A05B9
-:10AE90003D3E10AC485AA85F8BABFB2C09F56C69A2
-:10AEA0009AE2C74C8F598867E3AE4504B75FE96DF6
-:10AEB000417D99562084FA7C008D4966C73D127EFB
-:10AEC000A403F35DFCB5695064DCD70338EFF737B2
-:10AED000602FD9597EA687C96E52FA5A502EB5D71F
-:10AEE000EB14D739EDC63E70EEEFD8B8B7E2B81321
-:10AEF0004AD97846567F7AED8D7C7606D3B3222FD9
-:10AF0000674107EEDF6829B1F2C3E1ED1D686F7E8E
-:10AF10004B37BF4EFC93679FC1F8E29E48D9E8F9D2
-:10AF2000E2B9B09B2F06FD27C2EFBAAC4E087A30CB
-:10AF30002EFD0D83FBCABD7EC0F99F7BECBE3DF7A5
-:10AF4000307CC8A84FC972E9D9F324FBBE1CFDB000
-:10AF5000AC7CE581A92ACABD5F4D90F1EC30F25975
-:10AF600014F9E71DF0917FE81DD81F9DE180676708
-:10AF700084AF13E8F2BFD6E7F03F5EDEC3CBB6FC8A
-:10AF8000FBCA5DEEF29761C938B4BFBE7CBB1FD26D
-:10AF900012FEDE29F7BEF99108CF37FF0AA43A1056
-:10AFA000CF6BC5F9A46B1E9BAAA2FD74E50CBD1264
-:10AFB000E39F361CCF0A3DFD36E363C3210FAF0A82
-:10AFC000A755CC977A7DFB8CCF9C0DD84FBA6302E6
-:10AFD000FA0FC7404E3DFEA52E379C23CDC30BB7BD
-:10AFE0007DDE281F1CCA1629A71FECC588DB0F763B
-:10AFF000B2F7B31F45FB7856F6F7D7D9796627DB4A
-:10B00000EF9FF2F47B8D86175103AC527A1AA5AAF2
-:10B010006CDC2BE8B7CC8968FFED989FC1DC7547E5
-:10B02000BDAE02EB35FA86A937D27C5687EE8DA2EB
-:10B03000BFA84F8244AEFB77CA42C931D15943EF12
-:10B04000E101F1FB820EBD62DF63DFBF08FD7C0121
-:10B0500060FB7B7A2AC407E4FF91D05EEDC9989526
-:10B06000183F565CFC5184F11466F7AE12F6655138
-:10B070008DFBBBD71F747A94AFEB7AE823FB3FAA12
-:10B080008533329E6BAD73E73FDD59F44592BB2BA0
-:10B09000F7F9C9CE5C09C6ADF533691D921FECFA0C
-:10B0A00075A7539CF8FA32236EA15C83B8496D3DB5
-:10B0B0007CB7EA0309D20E3FC12AA55FC5F5B68A5F
-:10B0C000E90FE7FBEB62B2F1468EDFDF643FFDA0E4
-:10B0D00019E11AC4838F9FA7D559D931CF233D5287
-:10B0E000238FCB19C5170FB37FBF2EA6D238CBD66F
-:10B0F0004D29E6FE21B7DC7C57E8A99F3CFC2D9545
-:10B10000EEA3FAEEAB17201E563C2E83C6C67DF783
-:10B11000E10864487FA555D45F576D9773EA77CCF3
-:10B1200074A2BC94ADDC7F79D5B6407A316B7FD503
-:10B13000A3AF9F050CBE775BFBF74CC475F05DEECB
-:10B140005704ABEFAC8BD8FBAB14F8BFB9ECA9CF6D
-:10B1500047B9BD7DF847454DB8BEA52D3BBF48FD5D
-:10B16000F65EEA0F38E2734BA2FC7C2CABC7FDA065
-:10B17000DF91D25372C4EF6CBFFBE1EF481CBE1DE0
-:10B18000FE7410E1DB72BF9A6470ACDAF21EC993F0
-:10B19000055BBF17453CACDAE18ED3ADD8FA610749
-:10B1A000E6A1AC90A17F31F2B37C8CCA474DAD5F74
-:10B1B00026B9CFCF57AF2492B07A3FF8EDA2DFB0D7
-:10B1C000EF6FC7640832D1FBF6BE83EAE3584E86C0
-:10B1D00053B8C35DB5C32DF7566D799DF222741F28
-:10B1E000F4579C8DF9016EBEF6D667EB4745FB69B7
-:10B1F00055EFBAF7D0AE5CB5FD9D5FA3FC58E59165
-:10B200009F6FE37FCA87FAA9DBA29EFB69B61496FB
-:10B210003FB1E27B47EFB5D8B887B7FDEE5ECCB360
-:10B22000BFFAA3F7EFFD67B4179E0AEA28FF577D20
-:10B23000F7852838F8F11EB1FEDE9D045639ABF7CC
-:10B24000EE7F06D278A0F5DD277F3B19CFC9BDFB85
-:10B25000C81FC719ACFEF54F9E47F7F25FFFC30545
-:10B26000E387B3AB905FD301275C69A2ABB143E244
-:10B27000C6CB13E2E9A1C7E1470654B477FF2041EA
-:10B280003FEAB995BD1FAAB83FD963423FE267F7CD
-:10B29000F6D7F77C9595DF61F409E4A00F9BFF4496
-:10B2A0001FE96F2626D973E5F6D71721BCABA09FFF
-:10B2B000F4E9107A3ECFE839334B4FEFF7A3704CE7
-:10B2C000C57DC1AA8719FDCE423A32FA9D35947EDA
-:10B2D000EFE07FE60EA5DFE351F7BD0947E1EAFBAA
-:10B2E000CA7163BA7D6CCE3C886C9C61F87B506CF3
-:10B2F0007930127EAF90385C5D51F3A728EF0F6F65
-:10B300002B1AA4EF62A4EFF78E4E46E3ED4D7FFFBC
-:10B3100017110FFD4F0674FCFD12573DF922ADB316
-:10B32000777FF89C6A505C07A2D26C5686C19FFD5D
-:10B33000C0CA2BB90F1CAE79E0FF2FFA356B7F0D19
-:10B34000EB02F7998C6E54DEC3D61DD1217D61A32B
-:10B35000817A335D46F35E99E6EB61657AE7C578FD
-:10B360001F8517EFFE62FB3ED02C3DF1BE8395DBBF
-:10B370005F5D847C978F9EF6FC759CFF1CF6FD013B
-:10B38000F77AF5D65FC9D627E9292F7DD33B7F8190
-:10B39000CF77EF0F28783EE35D71AFAE97EE59FCA3
-:10B3A0008B73F3A38C431DF7F0C7601C4AE0293F61
-:10B3B0007FF0753ED2FC468BBF77A2868B8F6C3CAC
-:10B3C0001E3E965BFE4F2CE6726325F434A2E9EC38
-:10B3D000B55714485A132BB3F01E46FB82C17BF8B5
-:10B3E000BB32F9853A7A77931CF7CA8B9590FBF7B5
-:10B3F0006FD516737B71E58E9D67A15C3BBCEB47F7
-:10B40000C49F2B1F7E55C57DC79E2D3F50FB6AB341
-:10B41000EB01F543DA81EFC3DFDF79169707B9FD5A
-:10B420005E73C57C563DE1EE7FD5C3EFB9FA5F612F
-:10B43000F592BD30D2386F2BE6A538DFB7F7F9E9C2
-:10B440001EC2B77BE5C65C76F0E462BFCB0EEE7839
-:10B450006ED16FF03CECCCFD21BA7F717BAB39FE35
-:10B4600016B4DFF6FB457CD1FC1DDAA5DB9F0B9102
-:10B470009F67FBFECF503E90DDDF631E7CCE79DE02
-:10B480005A1061FDCDE94BCC948DA172A3EE00DB87
-:10B49000EF39F8E0FAE71AC7A3DCC7FDB181BF5F57
-:10B4A0004E89D3392C39BA88F2CC65DDA70773EA07
-:10B4B0006FDE9F3FCCF7937EC698CEFBDCCF3DF688
-:10B4C0001FB47FEF88FB72E2E13E817FFBF73FD93B
-:10B4D000EFD74B9C6FAC67793C24DFFADAD81C8B32
-:10B4E000573354DEDA5C17C7B8CFB5C5FCBE9EB182
-:10B4F0006F18129E2D99DB674CC7F917432FE0791F
-:10B50000FFDB9BF5B8333E5476D86CC17A67BF0930
-:10B5100071AC87E3E27E6DB4E35AC5FCDCF3907155
-:10B520006B7B092F858CAB9DC0B8B79E8271C327FA
-:10B53000806780CD058DEBCDB3F28EAF4EE379639E
-:10B54000DEF192B63E10F1055A7AC3F8DBFCA29FF9
-:10B55000A5C586EBF7958192A17BABB3791769A955
-:10B560007326C6EF06CF1B2734C77963F69DCE1B23
-:10B57000B7993C0F96B5A375D025FC1318CF5CE6A0
-:10B5800080F705219F0215A918DA5F9D79E211AFB6
-:10B59000083EEF8C346838999DFAF4E2BE61F48677
-:10B5A000B2E69B339CE792153D23B9E2C8E6EB7403
-:10B5B0007F56BEF6DEF8A20D7FE7CE7F82AAA9985D
-:10B5C000379B80D61C706E17EB07EB5562BD581287
-:10B5D0005A1CF5D4189FA75DEE147EA1576E7DA569
-:10B5E00093E2F679F0B443D0F30574CC97D1F64DDD
-:10B5F000C3F86F57C44772B22B98FB1EFBFF2CF6A3
-:10B60000B9E4A48AE71FC90FBB8FF68DC6B1974D69
-:10B61000BC1FE9D65A95FC6091FAFD543E6AFAC8FF
-:10B62000FACF871FFB3E83C1721EFF53BDCEE9BB1D
-:10B63000DBDC46F9B1D74D558DE1F22D426BA6C545
-:10B64000316F425B73761CCF6B876AF8EF61D8303D
-:10B650000FE26106DF863CFCF13F595ADE2D008087
-:10B66000000000001F8B080000000000000BED7DB3
-:10B670000B5C54D79DF0B93377EE3C813B30C0F082
-:10B68000BE8310D1623A28A2363E2E0F0D3E62468E
-:10B69000C4A809D6D13C4A2218B436A11B1B2E02DD
-:10B6A00082F8C2266BCDAE4D47A22D6DD31653DA6C
-:10B6B000358FF61B4C74ED635B626CE2F6D30613B8
-:10B6C00037AB59D365B7CDD6ED9736DFF9FFCFBD90
-:10B6D000CCBDC30C68DAF4B7FB7D4B7EC9C9B9E7B2
-:10B6E000F53FFFF37F9FC77C4AE4089949C8EE2DD8
-:10B6F000840C151342F8B08DB808D95762B2433A9A
-:10B70000284F4F1AA6E987F0B7606C6A6DFEDB1907
-:10B71000553322F9CEBC442E48FBD999F73819A6E7
-:10B72000A9F5831612A0EDAD3C91FB69EA96C960BC
-:10B730009287E6E55B7C561F4D5D24C3544ADB953A
-:10B74000DFC2EDF08DED7F30E711EF5BB45DBA4CF9
-:10B750003220ED2C17324C3A787ABED04402749CD9
-:10B760008E72612DC0690D7F9E480991F2274513A5
-:10B7700021A9F47B5D8F2CC3FC08C90824C03C4977
-:10B78000468DAE5E0F47D6F4178F1DFF10E087B6CB
-:10B79000DFAD96EF9BF3CEA17B29FCA22C95986997
-:10B7A00037FB06AF92FC69341FBE2A73302F0F9906
-:10B7B0006E2763FB817A3E5A2FD11B241B00CEECEF
-:10B7C0006112A4E327160D1398BF43229249C27E4B
-:10B7D00010FEA4D92344A1F592E60E7B9569BA7EAA
-:10B7E000FE608E09A719E649D7D1D15CEA2F48211E
-:10B7F000C4D63CDF5F40D725811F2222ED2741625E
-:10B80000F88F6EF7CF490C3F1A5E7ACA6F490AC6A5
-:10B81000E87F747D5BCEA4F1165DBEBC670DE0DFF2
-:10B82000E2092A30FFC4D90C2F5A79A2344C643A69
-:10B830006E2261F324A5443E4693845285C0387439
-:10B8400048593F9F07547A7C409D0FFCC969588F27
-:10B8500010FA29415E74D57C2BE479F256112BFF46
-:10B86000D0477041DFB2A979F3D87CBCF94C94EE93
-:10B870006A21E42DDD7C6DD974FE5ABFF4DF1E0B06
-:10B88000C900FC7E54BC09DE61A407EDFB3675FEE1
-:10B8900016CF30E2670CFE8A19FE9CC50C7FCE28BD
-:10B8A000FCED55DBEFFD2F86BF513C71A63540877F
-:10B8B000D178D4EA578CC2AD205DD276847C0AF26E
-:10B8C000816AE0DF1E3BCB1F12EFAC06FE00BE9A82
-:10B8D000805F08C9A44D7AB82E28CF1545ECDF7AD1
-:10B8E0001F9507FA7C50930F6C5C97CF5F4D283DF6
-:10B8F000139F891CA328ED9AAB7861BDBA9153229E
-:10B90000FDFFA33809EB774A8289FB244DCF2C4CED
-:10B9100007B9D966EBB1C17CBB2C3DD84F5B8E49D2
-:10B92000EC8D21DF4EABF335373B671C9D111F8F2C
-:10B9300066810463F1FDDBAA7C6B1B7CEA8C99D2E7
-:10B94000072F09929DC20B4CFFB6B6BEF9B43DE974
-:10B950001FF2F9609C441CC7A5C2E52A349156DF4A
-:10B96000C4701E57E98A6FB68F0B270F70C69033CD
-:10B970001A9CED00A7273E9CCE9C0AA453BED985F5
-:10B98000E30C8A125B0F4B936D239D9FAB35496A85
-:10B99000A5E92EBEA9AB0ED2210B5168150B91CF94
-:10B9A0005450B8F969D309A1FD745C9A659B04B43D
-:10B9B000DFDC43023A391F74042F89B43F5E0C92D6
-:10B9C00020859377293280F1AC4A07DABA91A264D4
-:10B9D00042E6D0F182FC0C90A7CEA080A9D68F467B
-:10B9E000274E8B4CC462E8C7248740DF416773222F
-:10B9F000F5E6BB19DEDAE6860354F691EE129EEC0C
-:10BA0000A09FDA8B28BD24D1BC45EEAAA3F8E87E1E
-:10BA1000D5427A757CA08D9BEB66FAC74E6A93C2BD
-:10BA2000D0B7F9B037388E3EB603DE68BBE60BBE42
-:10BA3000EFBCA2E115FE15133CEF38917633809FE1
-:10BA4000DF27C5AB4DA6F8FDFCAE45FACE2B3A7903
-:10BA5000D54C98FE20444A5F312D7EBBDD2D6446D7
-:10BA6000416124BF870F213EBB5DBD5DF9749E8A95
-:10BA7000DFE42FA4EB45B24B0D788A4E096965725D
-:10BA800070CCBAAE96C2B47D779189B702BD1690DC
-:10BA90009019F092ED41BED4D635E8607463F13070
-:10BAA000396976C998DA008F20EFCC7BBCE3C96B8B
-:10BAB0001BF0490C3C16B9291E3FF1DF0F8F1E37D2
-:10BAC000C1D499509304F8232FEF22D23400C3C875
-:10BAD0007F5A3B8DDEA3E75FFDDF7CFE1A9DC4AF7E
-:10BAE000AF68F6103F48AB660549A89BC37CC0967B
-:10BAF000864D29E854A5D8C2ADA09A72EAFA334E11
-:10BB000011D0CFEDE23B36145DFE0F53C6EB9F27FD
-:10BB1000EF68F83447C6D3E3C7047AE78C25748C02
-:10BB20008BE02941FCB47790DC089E9A6C208F3A18
-:10BB30005D5BCFF84A2378EACC7E4EDCA0A3F72BDE
-:10BB40006285E2A6F8D809766D0C7972AFBBA21DAA
-:10BB5000CA05536C797E48956B5480F30BE9380B1A
-:10BB6000468C789AA7E2697EFA3B8FC134A994E4A7
-:10BB70000915C815017F15E0AD6A4D00C882085946
-:10BB80001F7C2288F45025025E3865B2E943E78DB8
-:10BB9000E32F1EBE5C1C09C482FB19B1E6881BF4AE
-:10BBA0004931C59BCEFEA08421A27CD4D6C5E5999F
-:10BBB00080AED8BABD7C31DDA4D0AA9D5E5308FC0E
-:10BBC000190B69EA02BC93736602765A5A3803CBA2
-:10BBD000ADDEFC10E8BBB4B09DC8E82788213BADC2
-:10BBE0007F70ED5D7ED443D76F23614A3728CB4009
-:10BBF0008E65CB61B0A779512A374B30CEA336F092
-:10BC00006F3ABD354984D9DB24961ED8E20EFE007A
-:10BC1000D68DBF3E1FFB33D998DCBBD1F97C69655B
-:10BC200022013BC07E810B812E3BB0727ED77029F2
-:10BC3000C8CD841E2B4DDB78250C7A4CB96097005B
-:10BC4000DF5B0B95DB4D342DFF95BD88A7DFBB383F
-:10BC5000871FF0D05548979CF6F3BBA79C2142F371
-:10BC60003B572E1F49827E8E9A25287FF2C3A64F0E
-:10BC7000823D65FB603FFA8736D53F247CD32C5844
-:10BC80003FFB479413BBF91EA4FF5D05D36D7AF902
-:10BC90009EEA080E035EB4BCDD4BE5DB0CA4A7B73F
-:10BCA00086293D99148E7C48E9D3E6DAE63D25C124
-:10BCB0007CE9778D3E7C917A11BE35E63D14D760E4
-:10BCC0006712726431D8919D206FD06E250A07EB00
-:10BCD00096C1CADF3FB06231D8A19D76AD7CE562E6
-:10BCE000599F57FE7006F3AADDEB4FF6EC82FA9EE1
-:10BCF0002CD2C4F01320AB74F64C41328FEBD6E754
-:10BD0000967FEFD6D9CD1A5D761530BA7CF9626789
-:10BD100035C8CD4E4A975609E87097C14FD6528D17
-:10BD20000E3B0B189DC5C3BBE57A0909EBEC408BB4
-:10BD3000A707E9D1E609A01D1D5D7F450AB363345D
-:10BD4000FAB77909F2834D0A3E753FF287CB0FECC3
-:10BD5000672D68221CA5138BC8FCE189E6110F3EF4
-:10BD60008DFE3B0BF215A0D7F745E227E3D4B75C75
-:10BD70002FC5F96C71CB93927578F4E451BCC798D8
-:10BD8000CF5792D97C3A027581FB69BF72BDA4205E
-:10BD9000DF7889BF1BF412257FB03BA9BDF9C9E448
-:10BDA000543D9E983DA2F5AF704D8316E0730F6D24
-:10BDB00047BFB6939714587A8B2764E0EF2FA604F9
-:10BDC00067EBFBE145E61F2E34BB4CE423E0673F05
-:10BDD000F5CBC293A99FD82262BAA7C58B69578BAE
-:10BDE0008469778B4CC256EAFE90EBE7EF053BDBAC
-:10BDF000E540F826A28B8E163FB66F6F99CDFAE11B
-:10BE0000343A9FBA0BE8C261D2F8C4BF0BE83CC910
-:10BE1000AC959761BE8763E58F242F58AC14E37C03
-:10BE200050EE754D30AE395486EB77F3FDABF25BD7
-:10BE3000C5DFFE798F54E703FDBD6126FA38C618C9
-:10BE40007A09B3F16EB4FFAE6C13CAD3FDF3769EDC
-:10BE5000F1D1BCE575DAFF78F4D8C3FA8FDB9F0621
-:10BE6000EFE02E84D74AD7DB4EFBB38A4CDEC7E324
-:10BE700087E8F9D294207F7808CAE9FD836BC9CBA3
-:10BE8000C09F7458BB087C1A9021DE25B4531CFB5C
-:10BE900041DF06C2CF80BEB571E418CD0B2ADF505A
-:10BEA000B5AFBC4CFB11641BE9A6ED06E7DD45A070
-:10BEB0005DE72B360A13A5D3947CB417EC85B5A4A3
-:10BEC0008DD6DB596D2766FA3D69FE1A02FDEDFC41
-:10BED000991DFBF79D9982FCBA4B647C34A11CF23E
-:10BEE0009A4858AFC76D8E483E1FE4E57D24300D5B
-:10BEF000F9FA693D5F533DD90BFC24902A8570A067
-:10BF0000871FF0333B4451E569E05832DA81016C18
-:10BF10001FB10B9B8808FC7ACE1CEA06BFC4DC80EC
-:10BF200046DF22F361DB30F2B5BC3CA38C10170373
-:10BF300081ECF287492EE025C34C6D31204B818482
-:10BF4000A9DEE8A1FF007CFC85AB17C8AD84A4AFD7
-:10BF5000110CF3E02F382F996E05F8587D4D0FF135
-:10BF6000171A1BA13E4F74F5D19FA94B1ACF2F8CE6
-:10BF7000B6E30793557FD0497240EFB5B79C206F69
-:10BF80005B22FDF05171252DD5ECF9875358DC6209
-:10BF9000949E2446DF2F503F1DE8B1E31766D21B65
-:10BFA00083BEAF27FB0CF66E46D014991FFDF795A4
-:10BFB0008BD68A8306FA1C7FFDB3EA8DED739A1C3B
-:10BFC000063CE635271BF23E25D3507F5257BEA1D3
-:10BFD000BCB067AAA17CF2A1E986FC94D0A70CF5BD
-:10BFE0003FD15761C84FEB5F62A8FFC91335867C0C
-:10BFF00049F86E43FD1967361ACA670E3D64289FDB
-:10C00000757EAB213F67F8AF0CF5BD41F1E409E067
-:10C010004F4A8F668AAF5D19CA21D09FC36DD48EF7
-:10C020009BCFEC63D0B7249BA8F631554C694057A1
-:10C03000ECAF1DF400C8F93D8F85BF807AD2E407CC
-:10C04000FEE50B16C91BA15DBB68225E9D1C911607
-:10C0500011F85EB1C78DDFE5D256E40F81AA0D7BE2
-:10C0600022E86DE37A10F376D20FF0BDC1E0E3452C
-:10C0700025A67C12B28DF46F25F72405C6B1FB2CE2
-:10C0800092B1FECDD2BF2F45A5FF1C4AFFE689DB4A
-:10C090006B74FF90499E9CC2FCC3AA731E83DF830E
-:10C0A000781DF57B6CA41DD8A9BC6E24EB14ABAE37
-:10C0B000FA3756D3879FB871FF269ABF684A714EE8
-:10C0C000D7C9CBE4B566DF8FD587330CF65974DA60
-:10C0D00096F810CA3B2A17CB530C72315005F31354
-:10C0E0007819E5A2F6DDD73715E57297C8EC944EBE
-:10C0F00089F2E538F88A96CB5F4E9698BF18473E8E
-:10C100000B54CE82C2DDB9F2D35D8037791B41BDBD
-:10C11000447510CAD9E8FEA95D7537C2E965F4A473
-:10C12000F9439ABF65A3F203FC2B9B44105F568A28
-:10C130002F27DA478FA27D49E721817D64F550FBE7
-:10C1400013F43DB53F99BDF9E7B52FF361DE7AFBF6
-:10C150004FD5972187DC94921ABFFF17E3EC479DD8
-:10C1600049D6FCEEFF9EF427A718F1A1D1A146679E
-:10C1700056203A3ADEFB125B77DA2291D3F62F246F
-:10C18000F84F10E9E5D4ECB34A25AC5BD0255BA9A8
-:10C190005EDD37BB06DB0993780272266178C33215
-:10C1A000D093A494C90985FE03F4E62836CA0D5B32
-:10C1B000941E15401F278ED5BB9A7CD0FCF389E4D2
-:10C1C000CBB752D438D92C324B2F5FE2F9E19A7CAD
-:10C1D000D1F0B0E0831611ED8E0F68B9664FD07EB6
-:10C1E0002C397C00E2CC829FC84762F0DFCBAA5E8C
-:10C1F000EE3B6997812E5D6B04F4B332FDE172C8AA
-:10C200006736113FE067F670980469FF3FF4B0F5B8
-:10C21000C8F48738B0CF332F873880F3A085C58521
-:10C2200032B785387DDCE89AEAC7FDEEE2A37E5896
-:10C23000F78A3C17F2E9671713A48F21EFC69E72A5
-:10C24000D857984BFCC03F2E0F4F32217FDE1A4249
-:10C2500079E21F51A8AF4392E944614DAFB490E930
-:10C26000F751FFFDDD161BA6D75A444C2BF38A0766
-:10C2700017D07A5B7D0E8C1774E43B709CCE5C010A
-:10C28000C7F98F9C87F2C02EF8758B17EB773DDED0
-:10C290005404F184CE93FF8971CD083D53AC7901EC
-:10C2A0009E30EEF710BEC90BFBBE49F20CDC27ED49
-:10C2B000B404FF7103C413D70AFE6331F837E9E50C
-:10C2C0001FA19F0CF8013CB4DB195EACCE26BF1B4E
-:10C2D000E2FD93C8FA15B1F854C513A530B340E98F
-:10C2E0003789910611E686DA1241AFFA493F059B7C
-:10C2F000583A421CEC8790074509E245D9B6D02050
-:10C300009467D78BFE36AC4F705F415B278B9D04E3
-:10C310008EBBA05E98DB42BFBFE811D9FA0D8570D5
-:10C32000DFFD37176E1FCC21F1F97B4F4BF5D92A72
-:10C330005D3CD64562EF0BFFCB6D15160FEDF77622
-:10C34000806D26ACF7AC71F5E38DF67BBB8753E3CC
-:10C350001393D3C15E6EE663DB996691AD0FC47F24
-:10C36000C08FDE5A28A5BB5DFA7E183ECC279FC73A
-:10C37000F57116B3F9B77DEF8DCD8F513AF977DAB4
-:10C3800010E255AF5CFC0CFA8FEF254BFBC1EF526E
-:10C390007E6C26B0CEEF7D7FD669589431F36E392E
-:10C3A00093CCEBE249EF7DFBD5320BEDFFBDE75EB1
-:10C3B0002DE3510885101F5A79E387AF9541FC4A58
-:10C3C00068FE4DE6650AAF52418A9A204F0D68E635
-:10C3D000876E591A1E076F07D31ED802F1C2509BF1
-:10C3E0004BE4A8BDF625E71F05A0C766809FA60FF2
-:10C3F000DB4676727489B9F4779754D1FEB6728AA7
-:10C40000E2E2006F8A15FC0A72C1EA07BAD95AC87B
-:10C41000F4E5D607C59002722CDCC4C8DDF65AE6F6
-:10C42000652A87ED3F0DC11900D2CE052A13207E63
-:10C43000378D20BDDF76AD290FF695DD44C8073A6C
-:10C44000B498CCD8CFC84567A817E56FD32C9043D4
-:10C45000AD171F9D0CEBF57B55BE6871B73453D3F8
-:10C46000813A1FC4DDFC1877DBCDF7639C3EDE7C90
-:10C470009D5EB6AFC0571235DEF5DBEE7076841EDA
-:10C4800034FE8A6EB7B785F861BC975A6C98BED0F7
-:10C4900022627AA2C58BE9F75B244C075A8A30EDF9
-:10C4A0006BF1FB0B2C00E76C4C3B2C647D40476729
-:10C4B0005FF0B0FDC87B92CABF0074FE24EDF73276
-:10C4C0006DF745DAFE32AD3FAF366C86B8CCBC11A5
-:10C4D0002A2F2528EFC2EFFB697F506F6CB9AD049E
-:10C4E000CA4BABFBC380C7D262FA9D407F7D587FA9
-:10C4F0007FCB093F2B1FAAB450FC96FE96953BE7D5
-:10C50000D27E68DEA9F643C72F61F567637F745C4E
-:10C51000CCC7E8B784C173A224163CD1F5A9956FA6
-:10C5200026548F88F0BFE0EF59240EF75138123EA1
-:10C5300006F2F882B51CF4E79E12926FA2FACD9231
-:10C540005AC041FEA966229A4BA8CACBA8D9554E1B
-:10C55000A09D8CDF95557CE8980FF513F6ABE9A705
-:10C56000E4EA30EA9D243FC937BB69CAD381A753A7
-:10C5700054DF4722E70D503EB13CAE076D2756937E
-:10C58000C8790332717DAA5FA2CA63D3DB474D210C
-:10C590003EA63FF771701EB1835F4B7DFD7E924BCF
-:10C5A000F3AA7DF645B5DEFE7965491B21BFF8810A
-:10C5B000A7200EFE1BE2E5603F7EB47D943D77B878
-:10C5C000E54C5A55A1AA1440DE6F138FE8EDDC6CE0
-:10C5D00085D2AB8E0F7A9AF8EA5E8C2F04336A7498
-:10C5E000FAADC312CCA0CC4BAE3FF18F8B413E8055
-:10C5F000BE06393D7784E9F751BDFE5B261F357BCA
-:10C600004250D76B9FBCB12D01F7D3A83E92C0AE6C
-:10C6100008920ADA3EB17CEBCBF09D9418BF270854
-:10C620008C8F32BD210EF2999EC04F3CB0DF907CC2
-:10C63000487E86CEF7B7035609E8AFEFE4DA7A888A
-:10C640001B3E4C12253BED27F3A54B02C0D1611ACE
-:10C65000168008473CCD4B786A0775089A9CA486DB
-:10C660000F5DFF8E34552E90DF7757D1FA074DC1FD
-:10C67000AB54578ED63FE8086E813CFD936D54AFA6
-:10C68000EF1D8DA36FEB96294DEC55E3E6239ECF6E
-:10C69000762BD990A7F5DD2CDF4EDBEF750F794DAA
-:10C6A000349FC86DE93E930379ADFE966E85B6BFA3
-:10C6B000EA61E700882BE803B9379A17693E41978A
-:10C6C000E7599ED858DA77F23F05D0431D6923A772
-:10C6D000B3009F3FE4FA41BE36BEFCF541C86FAEE1
-:10C6E0002712C4E7324F1CC175F8AAB97C04F0D6F2
-:10C6F000D7724644431DFEB475A176EA142FC17863
-:10C70000B210E242F960BF15F798D07EDB4E49B017
-:10C7100004F0DD9506EB5C91C6FC812921DA8F8E51
-:10C720007FA650BEB34E0775651919D6FB5BC46F63
-:10C73000027811E5F01FE57F2F01FDD4375B714CC6
-:10C74000A5E36DDAC0FB5B25D03FA15601D6FF04FF
-:10C75000877AC2772663C73768FE5A7F4A2FF81B4D
-:10C76000961D8C3E37F9FAD3A6D3B4C3CEE86293B4
-:10C770005BCDBB8DF976D59EF4BA157732FDBEF947
-:10C78000C4815C3000AF1E9B857EE4660D1E720086
-:10C79000E1B93A3827E9363ADFC69FB2B866E340D6
-:10C7A000C912987FE31E13013F6EF300A5271D7F7A
-:10C7B000ECA37C284FA6F3907BA6F2943E02070BD5
-:10C7C00096DAE9FA7E3D5F16015FF569B7EEB6517C
-:10C7D000E7E8EB823805E8A13EAD7437D0D3A6393F
-:10C7E0006F213D26A596FEA49AE2EBE8DDD54B40ED
-:10C7F000ACA599185F5282433967766F43FCFF6B93
-:10C800003919B1BA119DB8CF9907FF47E19B2CCADE
-:10C8100015505F5C465D22A053217012EC10A5C23A
-:10C820008671D20A711996E7AE21A66E0ACF112938
-:10C8300039B99536B517C826B053F2030E8C7F9AD6
-:10C8400013AA76803F7AEC1CCB47D6E912E2C55199
-:10C8500014EAB7D17E6E71F122F8226966D906EB2F
-:10C86000467979E85829F00BB303942F1663BCE797
-:10C870006022A97F8EB63B6ADAD8FD235AEF68B2F0
-:10C8800087805DD9C171EB6BF07BC5D4AD743D8EF3
-:10C89000AAEB6776FB4558AFA36E637E2FB7F141D5
-:10C8A000C0DB23A92F2E81F9A559E59E140ADFE7E5
-:10C8B000525FECF666209EF36DB4FC737FFD42B7C9
-:10C8C0008DE2FD68AB9C29EAF293FF40A536CEE3EA
-:10C8D00005E453DEFDC587808F69F98F6D54FF7EB7
-:10C8E0003D59B307587941BEC6D7D4AF9D4DE168D5
-:10C8F0001DCD2BB622D8F78AD4AFA27CFED5A7CD0A
-:10C9000044EB1FEC09C79C7E9BC38CF3200EB067E1
-:10C91000A6F168CF38DC6C5D1D53F2D14E3A6A67E0
-:10C92000F81AC93161F922F3B322C407AC53781362
-:10C930009EE5214D01D0CF7C364F58BCF7B03C4529
-:10C9400082B029DB1FE47A56A07F682FD2ED071250
-:10C95000F0638DFB877C54BED03A9C61A27AD87379
-:10C960006105974BFBFB6CAAEA2F7A4806C4631F4C
-:10C970004D6572E6D18072BB45021A1B66E75649C7
-:10C98000603AA4E9EB0AD2C73BBF32F65C4018ED2F
-:10C99000B23D2E938AB749BBC305D45E763D27824C
-:10C9A0001CA16A7EC761D06F1E1EE9A610F89FE623
-:10C9B000B7B9591CDED7B7E44BB3C13E7CB5D00440
-:10C9C000FCCF8B7E11CED99527942681DDC68FD2E0
-:10C9D000E9EB4BC240378373EE043F5000FEA59F46
-:10C9E0000FDBD9F9D0910CD20F7161DE2B13FD3E14
-:10C9F000A1C6BF3B5B6C98527FFE5DD01F5FEB22F0
-:10CA0000B84F2078039897DA09077CF1F2A7EEC6B1
-:10CA1000719FE10349EB40DE9E63763D900BC63982
-:10CA2000C24F7010E778DF16488279EF771BEDBFB1
-:10CA3000B23466C776A632F9D9D9C2E2A0C2F54FA0
-:10CA4000605CA7C3A2C923D7D2F05CB0E783788E1D
-:10CA5000D61ADC2683BCB21145117571725BB631F2
-:10CA6000DE255CBF95C58752D938D1E70D5C9CD6D1
-:10CA70007FC1EEF1FC032D8D3E9FD04C02288FC864
-:10CA8000103BF7B06D57657AB2AE9F6D9C9C2E8EB1
-:10CA9000431F0F5F379390EE9CCAC3FC8800F37965
-:10CAA000F8BA80DF897738B115F66528C175C33AC1
-:10CAB0003EFF5DD44B0ED213860373568853E8CEE7
-:10CAC00085122F3F324AFFF911FEC07D752E067F79
-:10CAD00048C67CF47EFAA3E03BD37F77387F2DC035
-:10CAE0003CDFAB242360871232BC08F8B7B1D28197
-:10CAF00071EA87498FCD06062EDF23EAE3C58D0351
-:10CB000097123794E23E960476F0C32F951BE254B9
-:10CB1000DAF9302DBFF9C4068C1F3E7CF49A30B58B
-:10CB200014C118B2507FACD1D673C69A1FA96FB783
-:10CB300004952CA0FF975AE52CFAE95B00279CABE3
-:10CB40006A9E340BFCBFDF8AF519802727AFEA8F76
-:10CB50003536D41FED76EAAF019D5E9C8CFA9416B3
-:10CB6000F3A09FB5F15778181D8EA8FE7C023533CF
-:10CB700001BF1D8EC01566B41399A7F64E47B24685
-:10CB800037CDDDA0FF0E0A11B908933DE860F9E446
-:10CB9000B4E6EE76A687B1FEC893FC6EB0873AEC99
-:10CBA0006ADE43307F50E8413F41F9BE5502380FFD
-:10CBB0003A027EF007951D5324D02755E92E9C8715
-:10CBC000E5EFACBD200F333DC1AB60B7100FB38FA5
-:10CBD000DE4BBD904B5C31FB19E16EA41FAFB11F62
-:10CBE000FB5C36FE7B9C39B0A334528FB60FE3B9A1
-:10CBF000807B6C18FFD1EA1FB618ED642D9D92C69C
-:10CC0000E20C204F80AFB5EF42F03EE45F2B69426B
-:10CC1000FEB57A8DFB451A3F0BD7A718E297DF4A7E
-:10CC2000F5E1FA687240B85E8CE59D2A9DEE847D40
-:10CC3000F471C7498E33CE0C9413F1C72953E5081C
-:10CC400051E3493C9E33D3F824BEBC30C671A3E502
-:10CC50009F966AF2EF884AC7FF600F2E4CA3FFFF32
-:10CC600050A87F91035B076F85F5F9A36AF716F566
-:10CC70001D3809E47745945B5353E13C957C1CD205
-:10CC80009BE59BFA3436DE5839C6E20FDB1E945022
-:10CC90003F3FC3FB1DFE1870D75F771AE4577EAA8B
-:10CCA00084FDD5F30ACAB1FAEB8958FED1FBB793DC
-:10CCB000D08CF1FA7761F968FFFDACFF973FF5E39F
-:10CCC00083B3A1FFE3169355E7CF6D3BBE301DE262
-:10CCD00095DBEC542E1BF95606BEE57D64D40F029D
-:10CCE0003EDFAFF945CAA2DD5573C16ED5F1F96CCF
-:10CCF000B0BF22ED79BACEFB1D5AFB3B77833D34A2
-:10CD0000A6BE33AA7EBED6FF6AEC3F1A1E4D8E40E9
-:10CD10001EEC2DFE0F560D3E9443074C51FD8DCA5F
-:10CD2000A520F6B7690EB33392FEBAFE270A0FF4B8
-:10CD3000172ACF023BEB4122C139E768BC27A9740F
-:10CD4000587F7D92615D23F8BEC5F0FD9F5BBC24DA
-:10CD5000A4E3B7CF04B72D027E4BD2D689283BB1CE
-:10CD6000DDE12C12D2F1DDFFC0F151E1B82D0E1C36
-:10CD7000F3FFC270F80C7C1981A3C0F0FDA3C2615F
-:10CD8000B65DCFBCACCB5B4492A5CF97846D599771
-:10CD90007576CB8C33A2213F73C86BA83FEBBC6484
-:10CDA000289F335C6428BFED8ADF909F3732DB50C9
-:10CDB0007FC175D9902F278B0DF52B6D2B0CF98525
-:10CDC000E25A43FD696A9CFC76EF0643BDC5D283F7
-:10CDD000867A4273CA77C07E59F0C1021BF8173BAE
-:10CDE0005DA6EA10C5CF4E3E684B8E211FCBD47E88
-:10CDF00047F59D370DDB2F149BDA411E2EA4AE7034
-:10CE00001BB5D7D2EB02EDA0F7AB45229AD16F0E3E
-:10CE1000B1F8C9072BABE0FB9D8B89D8ED8EE46F91
-:10CE2000FF2B42206FCD96F15C9BBDD884E7067640
-:10CE300017D78CBBFFB04FB5DFF744E9FB51FA3190
-:10CE4000B3F393D1DF8BD3195D1D58B08FC03E81F2
-:10CE5000CD15C27B3E8353767A21FFA505DFF6828E
-:10CE60009FD135E5112FD04F67CE570DE7F21C0546
-:10CE70006C7F26BADFBF55FB2DB8FEA80DF4E7EE98
-:10CE80006C86CFE87ADAF9F4DD361637FFB8E6B902
-:10CE9000F8639AE7E5746667EDB68530FEDF5DF40A
-:10CEA000F1C07FAF3ACE81058F1306EFE3780EB95C
-:10CEB0002B4790F47A564BE1DE28CCA7D3B7D30B9F
-:10CEC0007AB7CBF788C1FEB7C27C628C63F3323C81
-:10CED000ED163FDEF93CFE27CF6767CC7D775B9C84
-:10CEE00079156BF3F2AAF7283EA6793DF5179E5700
-:10CEF000581D2F359DD9A7BB25C64749E6C0CFF39E
-:10CF00007DF1F92F69B6F19C5282DFE807E417043E
-:10CF1000C63D7F745EC54F3C7E5D635152018ED726
-:10CF20005BD839DB7380479A9E0F4EAA80FB0AAF0D
-:10CF3000C3792D0EDAEF48186F1DD606CD063827B7
-:10CF4000920F25E9F9888FD56B8CED56059CC6F3B9
-:10CF500052EA39038AA7FD105FD6F036669DFF4C72
-:10CF6000788A476F378AA7EEA29BC3D344F49D9A71
-:10CF70002E21BD4C84278D8EE2F5F3FF2A1D2DBE98
-:10CF800071FC20FD7CDCF8F9AF463FF7A64B37C4B7
-:10CF900067FFBFE2E7F11BC4CFE8796B81D4C73AE2
-:10CFA00007D2E915900E27734D6717839FBDD88C64
-:10CFB000F1B3D70E1734927C7D3DA6075E5B36A990
-:10CFC00011CF8F553BF1ACD65953EC7E5F53F1F145
-:10CFD00090D7AD9EA7F3A782DD7BB67AE5B8F322A2
-:10CFE000CBCCC6F38BC411999F99F64BA40A8C9FA6
-:10CFF00051BC1E1B67DDB5758B37DE8DAEDBD9EA04
-:10D00000B69B5A376D3C8AA798EDEEF6E6DF10DF47
-:10D01000C309768637761EA0EF7166B7F701BE6941
-:10D02000BFBF84A20CB0FF09C6FD56AF493F02F056
-:10D03000BEE665F1F001416AC47741562EDB0DE78B
-:10D0400051CEAD727310D2D0E038A6AE67595D6C88
-:10D05000BBF339B53CD29E2393A5B1F58EA876CF0C
-:10D06000AA3A0EED07C2CB39FA773FFE21AA3CBAA5
-:10D07000FD4BDE442C3F17E73CE6B7D4F6AB6BC75D
-:10D080006F4FEA53F0DC1F21528EFE3EFA285DA955
-:10D090007CB0C21BFCBE97D67F9D0B7EF973104FF0
-:10D0A0009DE2C2F33D84273ED8F71FED8797F1BC80
-:10D0B000C6E54686F7E87E75FD85BDA9F1FB8B8741
-:10D0C0005F6D5EDA78A524807E1DA926E27E36BEDD
-:10D0D00019CE39DC59499A707C5E427852DEA4FE42
-:10D0E0009C2F421F174CD23ABC48A3F633F0FBCA20
-:10D0F000A5D0CFC05993B8C3171FEE78F2E09F5464
-:10D10000FAF198833BE05C0159CFC53CB7F72BAFF0
-:10D110001DEBEDF78EEED7E338B73C19B448B4DF1A
-:10D12000BBD4736784047356E8C6DFAFCE3BBA9DA9
-:10D13000C7CCF6C7C91B66C45F5FEF4339B1F8E7D8
-:10D1400035D55EDEEF2D32F8C7B5812D16B06B6B8D
-:10D1500097ADB0482E289718DDA970F409C19C122C
-:10D1600057044F71E58F8A9F81F3413CB7B1BE9957
-:10D17000C373C7C5DB19FDADDF3E686AA4E911952D
-:10D180000F57C03E93AE3F77069B5F5FAF2317E01C
-:10D19000EFD39FBFA0707CFA10C1B89D2DE3E93D8D
-:10D1A00010B71BE6881AE7332D87FD8661755FACE3
-:10D1B0009096B702BC55A9C8E7EBB7AF403FFF96C2
-:10D1C0006AE6E70F0804CF01BD392F2104EF1D10D7
-:10D1D0009B3CF828CDBFF58724D2ED8FD0C71342F2
-:10D1E000781AD0476A5BE073B1E2D35206E3F3DF0B
-:10D1F000BAD83E5E3CBC9C55E5A956AF86972CB18B
-:10D20000EAAFAC36CA350DFE146BF83D12239E3ED4
-:10D210004A8FA1F1F5DD2F5439FD5A94BF547B3E5E
-:10D22000B6DF3237433DA71BAAD884FA4AB14A7801
-:10D23000B65885C7A3AC467C7EB8948890BFD32AE5
-:10D240003D0DF0DD556B8E92C321EC67FD32A76179
-:10D250005E4FF4FE781ADC4BCA2F60F2F7FD2217FE
-:10D260009E137F80340970FEAB8E28F3912F896462
-:10D2700001FA3EA7E24F83EF1C91136682BC683629
-:10D28000C7E4AFBB543A3A17A85C85E7DFDBCD783B
-:10D290001EE1526DCA72887F2B018B1F8E375D6A2B
-:10D2A0005F9970BF6E5D35BDA7D935E78395E3EA19
-:10D2B000AF5501E37AF5093DB8FFA75490A66394F2
-:10D2C000CE267FF9F2DE59347F36642A61E7DCD856
-:10D2D0007CCF86B2B473F1844FA3EBAE165D350DEF
-:10D2E000637DE56FD8BCD6D58516C296D83D877AC2
-:10D2F000F6CDA2F9860CB7BAEF387F1EF0EBAF9AE5
-:10D30000C7B707A2E9E996271D867CD97922E07B79
-:10D3100014DB62EB87F7B29C6C5F87F7E7C23AAC2D
-:10D32000DB1EBB9E3BDB85F5AEFED15C1FCBEF3E2B
-:10D3300090C5D6637D3D17539E1FC84A60E50DB169
-:10D34000FB5F95E954E59D980BEBB23E0EBC2B328A
-:10D3500013118EB73B56AF83FDFB2B51F655452677
-:10D360008343CA64E72BAFF6BED09106F4B09313A3
-:10D37000E11CD95B6EFF14A0BF0DED97D0CF4F57C6
-:10D38000EB3BD2034F66D0F4EEF3CF9D82FA0375E8
-:10D39000C4CF49F1F5C0E10C4D0F68F7A2357DD837
-:10D3A00063077D04FF0BFBAB1404252919D65D79B7
-:10D3B00008CFC5F43A44760FCA3F536F577F43A551
-:10D3C000E7AB476F6EBDEFA937DA4567C1FEF3449F
-:10D3D000ECBFAB82B4B7948E7B95D25B2B9D0FF9DB
-:10D3E000E0895BF5FA46E38778E3DEA81D78F5E887
-:10D3F000CDD98113CDF36719BE1BB203DFAF7E62B7
-:10D400005FA904F3ECB93596BCD5E4F22F55B918F1
-:10D410004D2F5AFA4B55CE5F098D0FD7670E19E184
-:10D4200059D7648447E38F2BA13607BCAB45479F90
-:10D4300006EBACD9A5A46AE60DBD17120FCE5FAB03
-:10D4400074F2AB66338F72EF2887F1E95F353F9155
-:10D45000182B6E153DFFAB264A0F401F4FF3287F58
-:10D460000AEB379C4C9322F4F87F543CFCA974A837
-:10D47000C9574D9F44B7FFAF4A779A3E9B88EE3C11
-:10D4800071E28F07326C88BF0DBC28C0FED1810CC1
-:10D4900089E589B8C80BF6EB6C76EE9D4AA85C78F6
-:10D4A00057E26AAF03EF8329DDD650215DC72BBD5C
-:10D4B000B74DD1AFE3EC4CB61EEB1BDC3B61CBFAB6
-:10D4C0008AC9BF381DD6AF86BDEF71EE7CF2A2745B
-:10D4D000DAFE892113BC9045D66DDB6086F9CDCC90
-:10D4E000647A64FDF657D1EEBB59BA5EDF64D4E7C7
-:10D4F0005FCE10553DC1ECF03BA95D00E708E3E1CC
-:10D50000A13093E1E19EFAE3284FEFDDCEA13CBDCF
-:10D510002593E1E35E3E847299B433FB99D8283EAB
-:10D52000A85CBA0493007CFC35C7CE77F30141FFB9
-:10D53000FEC6FD7B562F043B309A3FBEA7E2E92B87
-:10D5400099EA3B84E9C13B33D13F0C70D0DF5B9F4C
-:10D5500067F0AEDFBE05CF275FCC50ED6B953F2F58
-:10D56000C23ACD8CCC2F459DDF05C7C836D0179465
-:10D570006F4C78BEE47533C275F5ABDF6C827AE22E
-:10D580005417DEF7423B96E6FB9627845A75F13A2C
-:10D59000CDAEC9F7337EA8E565835DD890E933D871
-:10D5A000E9D1F6C6FFE80396F6A878FA4BE983C3FB
-:10D5B000AA5DF0A7EA834754FE8FD60BA37CBC93E9
-:10D5C000F1F1A5F3FFBE10F2D17CFCADCC8FA69794
-:10D5D000A2F9F74AEFDD48D7CA1222161AFCA39C1B
-:10D5E00010F8C1A3F41FF1933838DFF644EF4FA6CB
-:10D5F000419CEBD2DED5EB628DFF4416B3B33626E9
-:10D600004A267C1FF2754667D17222BADD285FC4B4
-:10D61000892FD6D6CC41FFF05CCD6DB970EF2DDAF5
-:10D620003F18539F935357817FDCAAFAC7FBACF591
-:10D63000BD31E0F566317CE6178C9C027CBFDFC013
-:10D64000E17D62F8D3DBE9779FF7FF60581A0BEFB3
-:10D65000685EF34FB6B3F1A2C779575DB751FF4487
-:10D66000A1FE09C5F370AD3911CEB16AFEC9B0F2A1
-:10D67000E7F54FDE2423FF300BD6F9686CB81CEABF
-:10D68000FCAF08C17D73281C579798FD0AF08B8961
-:10D69000B6D3F925D1EDFEA8CEE7CDED37298FCE53
-:10D6A0001BE3C9F1F86D14AE3F91DFFA84911CE0E1
-:10D6B000FB378F7C70F15198CF1107BE3F16DDCF3D
-:10D6C000D7B2CCAA7FE0403ED0F4EF80D0B3F905CA
-:10D6D000DAEECD3B32FD3B888E2F08E50BFAFDC21A
-:10D6E0001F295FF851BE211FF7F53AEB63F9298333
-:10D6F000AA3F141DB7117BBFD1047EB14CFC167D2F
-:10D70000DCE90D75DD7FA1CAA5A22CA63FEFAA5DBD
-:10D710002140BCE8FED1781141E7429C9A7D04FC8F
-:10D72000CBD7D47B02CAC68498F1DE992A5E278AB9
-:10D730001FACA933FAF577D51AE5C73BA1FC513DDB
-:10D740005238CE7E9446BFF1C6BB51FDD117BAB94F
-:10D75000FD8089E6F7D9AC1BD31FAB48D33C8C7353
-:10D76000D0F581B496344D7B81C2F3CEA19509608A
-:10D7700047FD82906AB4E33FF8EC34BD5D1254F18A
-:10D78000FC7EED67EF00727943689A164BFF44C741
-:10D79000697E118A7D2EE32E55AEBEA1DDA7B82B82
-:10D7A000763C7F8B3AEE1B75E3F34D74DCA67699DD
-:10D7B00071DE4A16B387DEA86B7304995FCDC6FD90
-:10D7C0001B362EE82DBD5DAA64FD79F4E330C4EF6D
-:10D7D000619CED84403CA54F50A6EACF5DA5643323
-:10D7E0003CE4178DBF0FA5EDA768F5A2EDAC9F67D0
-:10D7F0004A867BB3B5CB8C70B569F62D11310E72AC
-:10D8000015F4A527A22FEFB4FA1F043A202E09CB56
-:10D810004FA878BFBBFEDF2C307F2A3F3BF01EDBDA
-:10D82000599308F2B3EC7CC8A2C7CB851BF4AB2E8E
-:10D83000A8F6C2447234BF6804E5DBFB2117DE8F13
-:10D8400078F30BBFB3C4EAB7F67A96E11CF1FA405D
-:10D85000ECB88A98258C8B6731CB88BFF5D773F1EC
-:10D860005C703CFBFF10C8AF99608F1EE9D0DBFFF6
-:10D870004F6549AAFDAFCA339ED9FDF1E2AF432AF5
-:10D880009D4D147FD5F4B3562F7AFDB5345A5F0EF3
-:10D89000ABFC1C5DEF52D68DD1DDA81D1387EEE2E7
-:10D8A0008DABF91F5ADC37BF98B68FB12F33661C8A
-:10D8B000B55EF4386F46ADCF183F224EDC2E299B63
-:10D8C000E13718276E9794CDE2766709D38B4AC863
-:10D8D000897AECCAD17BF781B9F7C0E2CF9D06F512
-:10D8E000D6A8C66BEAEA5F3D057EAAE65744ECF18E
-:10D8F000601BEC935DDDC1A1BD113D4EB45DDE0842
-:10D90000EF15822055E307456619E3D4E43176BE6E
-:10D91000DFD3BC1AED4B2D3EDD27047624D0EFB7C4
-:10D920006CFFB76DA05F353FFE2D8BFF411667661C
-:10D93000F6EE855E17DE73DD3AEAFFF931DE38CAAE
-:10D94000FF6AFC71A2F518953771D6632279132FFF
-:10D950002EA2A5A3FB2C8254F80A9C4BE512FDBD18
-:10D9600034AD11080F78A859CEA19F5923C84B3167
-:10D97000DEFCAAC90479DF72DF6E3807BFB2DA2293
-:10D98000DBA5C8FE4BE96B0D85AF807F41270C7E80
-:10D99000ECC02FA57F82FBC1AF2FB64BB03F727694
-:10D9A0009E34E8A1F9B3777022D83D558BEF374FFD
-:10D9B00083F15671F80E8DB399A8E7B56F5D5E5986
-:10D9C00040C8370044DDBD8F1A6D9F4659BB0FEE2E
-:10D9D000CD4E4D1D30B9284ABF7B78ED3E1B85AB3F
-:10D9E000A335E085FB78F76597EC83FB786969F2EE
-:10D9F000D0026A471DCC9EB11CF2037FA3F557BA33
-:10DA00000FEEDFBD680AFA385AFE83EC65CB79D891
-:10DA10008F98A48DBF1ECBEF5AF2E0B16DB4FFB763
-:10DA20000F6F590E67D7CBEAB4F11F595EC953FA8D
-:10DA30009FABE51F4B84BCC74922FB4CB309B144E3
-:10DA4000EEF7E179F781D1FB7C2DCBE1FCF8EBE53A
-:10DA50004D95708FB3ECCB1DFB8AA710326B59B973
-:10DA600028D3FCDC9C2F2F77C2FE31A1F448F3723F
-:10DA7000CE57107E8FD9A4F61FDA2767033CCA540D
-:10DA800028E79467F655BBE13EC2F06920CB879B3F
-:10DA90007B6C69867B098A0CA68970A23C9C85E018
-:10DAA000A8FBDAD9E169ECBE9D9A2F62718AD1BCDC
-:10DAB00097E50776C4BE7FF2610E935F038ED8E5CB
-:10DAC0003D2ADF6BFBAF49E789FC6C0CFEFF3CC4D1
-:10DAD000FD6746F8E914C4433CF8E45C532BECC3FF
-:10DAE000DA189CF1F671F7A9E314B426E13B45CBB3
-:10DAF0009A9CF8AECE243F9337948BF89520FFCDB7
-:10DB0000268433D5CCE17B26690E123C4ED3D41447
-:10DB1000F6BEC9328A6A787764E1A4C0513CDF9BC3
-:10DB20009E51D206E7EB5A7FCE831DA6B51F0BA7E9
-:10DB3000B805E04C35D7946C29D6E1AF98C14DD7E4
-:10DB40005D6D277F13DE7B19189A9A0F767565B67F
-:10DB50006488CB940DD558E05CEAE51C554E48AC82
-:10DB60007D6A25932B235BD4F72A6CFE12435C5FFE
-:10DB70009D7F65E7B22F41BD86210B817388DB8EC7
-:10DB800097E33BFDF1F8BF01CEBBEBF476031FC674
-:10DB900073E60D70DE7D06F4F75301CE37423FE0A9
-:10DBA0001FC0BD0EB09B52DB62AFB716576EB8EE0A
-:10DBB00026CA0CFD7786AF48FF1E2C9F685E91FE3B
-:10DBC0008CF7F8C6F6A7DEE7D3F0CEAB781762C3C2
-:10DBD000F9AA469714DF261D3DAD52E98B4A3F7CDA
-:10DBE000D7F7C2F2E25EFD7B0584EC60E73A78BAD3
-:10DBF0008E604F0E39F07DE0329EC9C7B2A16451EC
-:10DC0000E1C6D285B6AE03C94DF83ED1C80A2EE6AC
-:10DC1000EF0F9CD7E052EDA7F4BAA079830E3E8DAA
-:10DC2000FE23FD0F7D41E38F75C8B77B197C606FC4
-:10DC3000C03CFCE169FA73201AFCB753D981E7496B
-:10DC4000DB54FCDFE10AF57211BC8DC57FD604EB15
-:10DC5000998BE5654327059867431C3EFD650E3BA0
-:10DC600027927E3E9C08E703966633FD35D03FC37E
-:10DC70007E1BF0C53213E124366FB033CB34F94A42
-:10DC8000DEFB590595AFE9A3792A5F2558875179BD
-:10DC90001BB6D922F57F9AF3DEF276AA3F3C567680
-:10DCA0001F8CDA8F36A2BB8768CD61F1DBD9C1D872
-:10DCB000FBD6C3390906B9F5547325799BCE6F6538
-:10DCC00036D3E7B387157C2749E3EB68B95498C38B
-:10DCD000D6D197C3ECF18F5F2E7113C8A515AA5C3E
-:10DCE00062E5C4136880F234937A2F4164EBBEF18D
-:10DCF00047330A210EB7D56B96E09EC34ACE9FF3F9
-:10DD00002D3A4EAD4DEA489022F4514B6C920BF0F7
-:10DD10004D47807BAF35CBEC98873FB03BFEBD874E
-:10DD200063F447A4A4DA71EC5A0D9EAD5E01C7DB23
-:10DD3000B8AB3029A887930F3C8BF13DA70AA72DDC
-:10DD40004A5FF1C67C5A5AB8D164D695BB98FEEAB0
-:10DD5000F6CAE539605FAAE79BA2EDA27BB23983E0
-:10DD60001CD6ECA2DF79199F50FE45FF319DFA8F3A
-:10DD700004EE7BF407F03C183C605488F775D9FB3F
-:10DD8000C66F1D2773C14FD2FAB92BA7D8D06FDD4C
-:10DD90006ABA489FA4CC69AB942FEBE4D919F57DFE
-:10DDA0007A4A0F33815F57E710633B73201BEE9570
-:10DDB0009374AB1FE4CD29217018D757246E58DF18
-:10DDC00085E62D87912ECCC4DD86E7A48E60FBEA24
-:10DDD000BA9152B4533F308741EFFC3C3703E339EB
-:10DDE000A94E46B7A7EC4DD88E275232CA1155EE30
-:10DDF000FD3C770ABE7FA1C9CFC87D16AD1F567EF8
-:10DE00008A5B910DEFC49E4A9D5CD2C619ED1DB090
-:10DE10007F22F6D2F3FB6EA7FC38ABBA3F4C61A66B
-:10DE200052E5A5E58FD2FA5B7298FE3BE50B0CC07C
-:10DE3000B8A7DC4404F8670F079F85FC62AF13DFC7
-:10DE400071D3D623CDC47E1F264DFDFD15E01348AA
-:10DE5000C55CC66F8773D93ABEA3E6D31263FF9E33
-:10DE6000CC7FA8F57AE0FE1FADD75D1EFBDEE81E75
-:10DE7000958F1B6D3DD570955E77CF13EF2DF38495
-:10DE8000DA55B4CADE1CD60FD56788AFCACE3AFCC5
-:10DE90003DB1F78756E1BBAEA3BFF301EF54D17597
-:10DEA0000F9395FB01EFC22FCC787EB3C3C2E8522B
-:10DEB000700745B88794E28CEDEF7E578527C5CC77
-:10DEC000DEEBD6EE2F58D4FBFCC7547B2CD15B8BFA
-:10DED000721DDE58937CF02EDB08DECFD5D631FAEA
-:10DEE0003CAE45BDC77FF3F643491CFBA1D4603F60
-:10DEF00068E346DB1117E13D6E5DBC7B9DF7DC42BC
-:10DF0000A2ABFF6932DC01FD7D7A5B96212E11CF39
-:10DF1000FEF8912A6FC15E5062C22518BE5FA47ED2
-:10DF2000A0A21FFF0A1B3F32AE9328BA71F7E6C8C2
-:10DF30003FCEC1F8CD5C11DFB1B0133C0F5BA6BE84
-:10DF40005F47F513BE5748F55235C86FCD2F02BE57
-:10DF5000179380AFCBCFE6A4EAF4A4DA2E5A1EDDE5
-:10DF6000A1DA0177A8FA26E9BC66373A248E8BE855
-:10DF70009DB17A8B53EDE868F918AD178C7635A50D
-:10DF80005B456F078CE11715AF374F1F93E2D0C782
-:10DF90002D7F11FBB26C6ED03C0DE4663547601FDF
-:10DFA00064569551DF3B7299DFE1C8751ACEE1D610
-:10DFB000D419EB25423DE0AB5CE70DF9297A7DC42D
-:10DFC0009941EEB1FE36ABF4E07BF7AC00EF372EB3
-:10DFD000C965F650499E9C9A4BD3237FA8EC83DFFA
-:10DFE000A11869E549AF07DAC97DC31E98974D04AA
-:10DFF0003FB57C6D55D1115A6EF9A905DF9D2427D7
-:10E0000062FBF7AE664EBE8FF273BE2AE71A3C6C17
-:10E010005E0D9EB05040E1C86C60F064F70F72BCBA
-:10E020004EEE65D7B37AC5B91683FEF1439EC2772B
-:10E030006BAE16BF0CB5C2EFA164D7CB3CE8BBCC2E
-:10E040007E8EA8EF6EE27BA9997ED6BFCB1FE2EE53
-:10E050002D8ECCBBCBB4A218F445579AD30FFAE25D
-:10E060007379C1329877C3857018D036EBC2100F20
-:10E0700076DFFE3C79167CD7E62799C54CD81F770A
-:10E080005E60F0F544D13F21BBD575E965F0B9027A
-:10E0900025004F5AA284EF10D1BF7CD0AB69C9AA2A
-:10E0A000DE482341782F88D8683DB0831CB49EFE9B
-:10E0B000DE260994C23E412875DA74D0730B1DFE2A
-:10E0C0009336D0AFD37DD3E15DA1170EC78EA7D70E
-:10E0D000AA7A87C27FA71EFE78FC31FADEBA5ACF31
-:10E0E00012C78FD6E8DE591DDB5EA59A00CBCBD7D1
-:10E0F0007AEE86F934B40BF81B5D1ADEF7E70536C5
-:10E10000E6A6C23A1DE1805F33FBCB91AE32159E8D
-:10E11000805DD1EEC80DC13BB2EDC99F4A07FCC777
-:10E1200083BBA1D92CDFA7E7E77601D7E348D4F971
-:10E1300035CDCF782C97E9A3D37981AD30FEE613A6
-:10E1400007F09CE083472F09E3BDEB73A378E3EA74
-:10E1500099FFD2B086BD9751BE96473ADCD42EE0E7
-:10E16000BBEA0DCF1E0FE37EF17682FBA00DFDC74B
-:10E170004FC33BAD590DF24CFDEF126435B077E360
-:10E18000D212467F1F5400BD9DD9BFA201E95A2477
-:10E1900022413A0AA2DD956D63F6A886DFD34238A4
-:10E1A00017E267A74DC4DF46CBAF59942289E6AF8B
-:10E1B000F91C7E787FE1EF8FBF213D067886B81885
-:10E1C000BC7B9017FC12E0A3BB959D27EF5E48ED4A
-:10E1D0001E5A6FA1936C85FCC2361701FEB8513CE4
-:10E1E000CC8AA28B59DB199FFC283751E55782EF67
-:10E1F000291DCF4D50EDA8601DDAAF741E9D731020
-:10E200002E9C87982B7F15E9564CC671331BC29CF8
-:10E21000FEFE899646E84A7E3637F566E0ECC77D15
-:10E22000C64DAA9C295F7B947B5B47072FE69A919A
-:10E230006E329F3DC2817F48CB5B177AB03EC607E6
-:10E24000339F657ED3265A7EBF41AE6CC0F97439C8
-:10E2500098FD48E5CA4980EB94690BBEEF776A3AAE
-:10E26000C17766EFB8103E8DE25985F794C0D6931A
-:10E27000A77868A5F99FE54A38FE6921781FACFBAD
-:10E28000E94C76BFBBCBB403DF3BD5F83E9A4F7F5A
-:10E2900096CBFCC9CC3547398827789CCC9ED4E0F6
-:10E2A000D3EA95E4559C05FCCEAA1E423C34AEE16F
-:10E2B000D97D0D159E8542A000FCB461B5BF93AB1E
-:10E2C000BF6D3E44E16B2CE6909E9FFCBB57912EA8
-:10E2D0001B7B38F6BB413DAF0AAB74FED5C1EFBD29
-:10E2E0008A7A65E9008B1F340E1CE7EF7581BE3911
-:10E2F00089F4D948E9CF5E0AEBC6ECD86B96702E4C
-:10E30000E8CB68FA745633B90831D742F60E1CEEE2
-:10E31000FF86D6DAD0EED7E4AFA8C209EF08827C38
-:10E32000FD8DCAEF5AFF117FD5EE07FAF6BD3BFD12
-:10E3300024BCEBD6E8E7FC701EF93F46F50993D7FD
-:10E340005222FC7660A4FF68FCE5E631F91A438F9F
-:10E350007C184B8F687AD6F77405BE97ACAD1FAFAB
-:10E36000E27D54BFE7B1FB578979BC0A8FEC853851
-:10E37000B644F9B9BB14DEF50B144B809F54A71FAC
-:10E38000E23B7FEF7E5DDAA0C3D76981F23BCD9F90
-:10E39000CE77203C942F92F274EBD750CC7E67EA74
-:10E3A000C9EFAE40BC36C0DA51BC3604EFBB0FF14A
-:10E3B000EC25E231902F4126BF1AD6DCC5DE05D709
-:10E3C000F4DF731CE2BF4171E13BD74BFB57207D6B
-:10E3D000128FDD5FC8A15CC375D6F84CCCD5F61D95
-:10E3E000D8BB43D4AF6F857889E6D727D605940488
-:10E3F000692C9FA6A87EFD4CD5AFB7CCB6FD59FDC4
-:10E40000FA4DCD3F41FFE721EF8F30D5F884FA8DEB
-:10E41000067EBA2D8FD92D929A56E431BEDC54DA9D
-:10E420008FF4BFE97213F28FAB9AC911D705A3FC21
-:10E43000D3E260D4836374E8EC5F04FB110BBFC2CA
-:10E44000892007E2C1FD19AEE967705E851C67E7A8
-:10E4500028167CF0F344FD3BA435798CBEAFF599CA
-:10E460004918F0CD3709E3D9BFF1FACB0957CDF9F7
-:10E4700027BA7EFFD29784E782AE3DBBF2F3905776
-:10E480008E26E139929C702DD2C535CF1C3FD081AC
-:10E49000A78DE1E95A7F25D2CFBBE99209DE096B4E
-:10E4A000ED7F623EFC5E74BD0AD7BBDF3537031ECD
-:10E4B000767CED3BF3E15DC94D212E05EE9B5DEBD6
-:10E4C000FBCA1F41EFD51F7D18CF7DB57DF37FA11E
-:10E4D000DD6D0A1D61DFFB9244A877F59903F30116
-:10E4E000BF6DFD6D58FEEE3347307FF26BDF311F9D
-:10E4F0002A8DD0F1BBDF3DF2C3DF433E9088F77237
-:10E500001A824F3E0E79529BC8EE5D055F11F4BF33
-:10E51000DF75F0F820F2A146174BFB39F5DD30012D
-:10E52000CF7968F4FB56457119F01DA550BF793EAF
-:10E53000CD7727D4C78A23EE51E7DB00B408E3AEDA
-:10E54000E142C0075D82D287F25CECCF0579EE2C08
-:10E550000E0BF02EE9EABAE3F3D9CF10B662F94A0E
-:10E560001B3B2F368DF20BBC1F457B3BFA21C4F7BA
-:10E57000BA1E5C07FD1D3613D19C118177B320A113
-:10E580007FB4B986F3530E231CD9762A15F6C79AA1
-:10E59000897AAE8BD5EBA2EEA52D19F510B1D3B4C7
-:10E5A0006C5BEC38E893792E953E19BF660EACC8CB
-:10E5B00006F9413C567FA12FD25FCEF9A66E78DED8
-:10E5C0003FB37E6811CC6349D18619300F0FC4FB6D
-:10E5D00040BF282EECBF11E293949FBEAACAC73455
-:10E5E0003180EF8CD8E4402AFC269B640DE0396E24
-:10E5F000697DC0D20A72861FC95D858AF09861FF65
-:10E60000F0A025983113FAEB52F5D351063F6D8FE8
-:10E61000FD4995B207DAD3FEB13F5B9DCCE36FBEF7
-:10E62000D9D83AFCEB0F6E3F668C9787C6F45FEA49
-:10E6300002FDA2ACC17593049CEFBB5015F1ADDC9B
-:10E64000AA8F6347C77B409EC17EEFE9BCF2C1BC85
-:10E65000D448AAC581A2F1CC4BB49CF65321C998E9
-:10E6600092BE1BBB77A6C9EDCD7B54BDFBE22594C2
-:10E670003B9B833CD3BBC1CBA877FFA545266F53FB
-:10E68000C3F2E0F39790BEEF3DC1F4EEE61325022E
-:10E69000D0B3F61EF2E68A6BA87F153341BADE2CA2
-:10E6A000F49FF642FFDDC44D2D7BB279FEF02D20A4
-:10E6B000FF7EFDBC7D0DB43F653221BD9DEAFDC4EA
-:10E6C00091364E0F1FF303B8FA10F2E366D52E28E9
-:10E6D0005F7BDF01F0C71AEBD9EF116C1E50F98B8D
-:10E6E000FA6380DFCD275E45FAD1EC5EDFD3354893
-:10E6F0006F6E4A6FF8BB095543081FFDF317D2D45C
-:10E700005DC5DEC55D52545206F47672F50F778210
-:10E71000DEDE5C4544E8FF608EFC3CBEFFFB3C87D0
-:10E72000EF511EB4F454C03DC9830B2511F8637337
-:10E73000B076543FE1F9EA60ED00F28F679D1FEC7F
-:10E7400087EED620DAD5DD194EB40B0E3EDF8AFAFD
-:10E7500073B3E4F0C3EF992C3DC16DC5F68A8B30DD
-:10E76000F839B4F397866EC3735B1A3E96560DE77D
-:10E770003279C1E0FEB565E8D330EF5F7FCF0A6F35
-:10E780007E8FD2DFFF05D640AE560080000000002D
-:10E790001F8B080000000000000BDD7D0B7854D5B6
-:10E7A000B5F03A73CE3C1226939327E1E9C90308EA
-:10E7B00098841308EF872704102BB583F2B2220E3A
-:10E7C000C823424846C48AD77E37830331526F6FCD
-:10E7D000AC2FEAA576A06AD12B106DAC51030DA821
-:10E7E00014ABB5D1528A16BDA3222F918CE083DEE3
-:10E7F000D2F2AFB5F639C9CC640262EDFFF9FFE998
-:10E800005737FBECF7DAEBBDD7DE9336D9BFF18E85
-:10E8100032802BD561BAAC03A42B6DBE3B3201D242
-:10E8200000F435986FB07B9D3A9647FE430A6DCE53
-:10E83000C5EFD3C0081501E4DF23192137408A262C
-:10E840000164516A335307C008C0BF0691AA811200
-:10E850006F31C027B5067C3800F84FCB0658CEFF85
-:10E860000058B1A8D5A1617F554F89FE329D46E978
-:10E870002D989EA3BFCB305F013778B13C4B966E8D
-:10E8800098C1A98D53ABDC4A8799F3C87D64E1BD7B
-:10E890005370FEDFA9043D0987E85D88DF310F7EF4
-:10E8A000080DC0F9F7AEF4F6D5A83C73A92E633E67
-:10E8B0002B03BE4FE591350ED82C75ED7724AD6B4B
-:10E8C00004D5F39649582FAB678A1EA4A1E4725B66
-:10E8D00012B52B95F4CD1AE5AF7E14084E59BD74D0
-:10E8E000EA072064C2C15B66C37A47B353F4F5F408
-:10E8F0003DF407E56A84C7244DB5CA4BA99DE601DE
-:10E90000585FDAD96E4ABE97FB9BD233490FE23C7F
-:10E91000A737044A204FC0C1EBEE8443684DF2DCB8
-:10E9200050143CC6131CB07D6830CC6D2C22F87B93
-:10E93000ABA89F6C9B9EB11E3715DC81926B526811
-:10E940009C20C36B00CD03D329B83E3FF59BEF5D00
-:10E95000C5F0C84AD113C163CF25021EBBE76C9333
-:10E960003760BDEA2229E4C4F9DDFFE28C525A6720
-:10E97000F54CB70E98AFF6290B695C08B8E031CCBE
-:10E98000836FD1BD53305F5DE9D5D76BBCEE455485
-:10E99000DE3733495F8FE50F3E2F1994AF0EB84332
-:10E9A0004998BFB259E04375F3D3CA8D98F620BC9D
-:10E9B0007353BB40C98CE2CEF900ACE1F9544F3A35
-:10E9C000D1FF656C1F9041972762DE111EA8E3FA04
-:10E9D000AB27860712BC4E3E9F3497DABF62B30561
-:10E9E000689C57365FBA292875EDE7A4DDDB44EB58
-:10E9F0003F89EB0F60F96F9FFF7388E8612DD28329
-:10EA00009C837BB4462BA7F2F55340A57DB1F66BF2
-:10EA10008F23504878B5272F99F183E6E945381FB1
-:10EA2000A77FF602B8F5126F8D8670AEB6B5D629FF
-:10EA3000D46E4B06C018CCBF70F7409FBB2B9CB167
-:10EA40003DEF8B4B01C65F57A847281885572E17F7
-:10EA5000D2DA304E036E4C7BAC16F089EFE74ECD28
-:10EA6000CDFDAC7085F7E0CE41CDEA065736E29198
-:10EA70002F59E3EF49F680D107E7E3682E6FED8366
-:10EA8000E5D9E9F81FDAB7CD3D42B46FD9D9E07BBB
-:10EA90002641BFAB4C3CB3F6A5211D182FB33DA2B8
-:10EAA000FECF4DBAF98949975BCC348A2E62F1DEEC
-:10EAB000EDCB253E919D0CBEC604E359ED717E5C05
-:10EAC0006ECD0B5CD84F26B5D36C8CDF717417CA32
-:10EAD0002A1E4674372559DFED227A1A963B2C08F8
-:10EAE0009DE320247267A474C5035A07D10FAD8B30
-:10EAF000E8ACBB7A0DBB047F8AC7CB674C3AA9222E
-:10EB00005CC7796F93901E13EEB3E8A7DE966B7B1C
-:10EB100010E7FBA3FD32F3D9F87A56BAAB16A0750D
-:10EB20001040DEC66B53BDC5DDD7DB66D6FB71ADCD
-:10EB30008B53B7AEAD51B0FFA12D5AA90C349E3600
-:10EB400089C60BE078B4CF2913E15319E1E319DD4D
-:10EB50005078672EE179E35C5AD750256C2B25BE9F
-:10EB6000EBB5416BA1E0DFE7F0FF3DE72643ABAB40
-:10EB700033DFCB971E93EF53D93BA67E3F7F5E4C8E
-:10EB8000F925AB87C494E70686C5E4F3EBC7C6D482
-:10EB90001FD03029263F68C37762EA0F0E5D1D93B0
-:10EBA000BF74CBF763EA17372E8C299FF48FFCDDF7
-:10EBB0003F253CA7F527E073561AD17279FF8636B8
-:10EBC000C7AE3F7574ECFA158800D1FBA4E4BFEA28
-:10EBD00089E8D94A5341F92C6CB5233EE0D26C0F39
-:10EBE000E23CCAFF2C87D627988785CF567E922293
-:10EBF000C78C6BF1890BE1579EEFFCF8F263C217EB
-:10EC0000E779E6FD0F39215DAAB9820F28E0E5F525
-:10EC1000A74E9C7BDEF5DBE3D70F1AE3BD87D69FBB
-:10EC200000EFE3D79F3A3A761FACF5E7F90637874E
-:10EC3000B19FCFE74A2C5FF651D198AEFDBD1BB70F
-:10EC4000CED9AB52599F01EF3509EB77CEE34E9EFB
-:10EC5000C7F54EF02782C374130E95B982DE2F4498
-:10EC60009FEF9BF3F81FA24F4CDD6B73991E619FC2
-:10EC70001C1A805D2DAC9776F544BC48F7B9592F26
-:10EC80005BA8B44269949CBFDFA4EF074DFADE5045
-:10EC9000AB723F0FD7E670BAB156E3EF8FD416725E
-:10ECA0001AAAD5F9FBE6DAD19C3E8AFA18A58FD7C5
-:10ECB0004EE3744BAD97EB3D593B97D3A76A7DFC70
-:10ECC000DDDA9FEBCDFD016F06CBB3F8F5CC5F9598
-:10ECD000182F412EE2F6F391CEE4F3F0B52EEDE5D8
-:10ECE00079A9E7C3A3D50773B7BF1C8507D7E5A6E6
-:10ECF000641EEE81FF1805A3CEC9176EFF65ADB681
-:10ED0000FD65FB85E9C2C21738FBE18044F5AEA77B
-:10ED100031C722BFC9DDDC1070770F9F4E3C8AC31C
-:10ED2000572FE22B7E2D21D9DE8BCAC3BDA3C7F995
-:10ED300093B9CF567EE64C81AFF1FDDE6FE2DF2C5A
-:10ED4000C24F2C9F1D47AFA77385FC3C9D2BF4F44D
-:10ED5000FDDDF08B7B726DA6FC14FB3E6B9FE04BE0
-:10ED600077F6983FC197605C294F8BA1CFD9336369
-:10ED7000F771BF5DF0B7FD7F92436B12ECFF85DA50
-:10ED80005BEB896FF72773BD9FFE7F466FFBAF4D2F
-:10ED9000617D7EBFDDD72F2B6A7FF65FDB636EA2BE
-:10EDA0007DFFDF5CBBD8AF421548BE433A18A407CD
-:10EDB000E192020ED2E5A0403D4C7482C610D145CE
-:10EDC000F778A9C0618B9E64826712EBE39FCF4CFA
-:10EDD000E1FD079F6A4054FFA0A8AC976EFB2EEAA6
-:10EDE0000A349E82E3A11E0ABAAD73FFF2E8BFC9DE
-:10EDF0009DFC5AEE9EDE2E8407161F994D7CE43C46
-:10EE0000F2BA6BBB8BE32387888F5CFACDF3118B4F
-:10EE10008EE1EC8D03BC295DCB67111FE90DF0D3AA
-:10EE2000DCB7998F7C6D3859746BEA13F1FCA4DB65
-:10EE300076CD9917907F263F57FCF561C48BDBE4B4
-:10EE40009486F5D8E42EC5FF73CA07020A3C86A94A
-:10EE500073F5E9DE878673B7850AD71BC2F69D5323
-:10EE6000F1FF32CCF6A053A57A0FF5F8F7ED945FD9
-:10EE70008D1CD389E99749FD4380B640699EE03FE8
-:10EE8000B2EB4CEF4351F3B3ABD0273A5FDAEAEA87
-:10EE900073286ADF86EF5563F223DA7262EA8F3AEB
-:10EEA000A0C5948F0917C6948F3BAAC7E427444690
-:10EEB000C7D4BFEC8C11932F872B62EA57B866C476
-:10EEC000E4A7A8D7C6D4BF3C67414CF915DA4DB1C9
-:10EED000FD157887E7E1BA173ADCF5522ADA69B905
-:10EEE0004619E59393ABFD0BC84E5AE3516122D509
-:10EEF0000E85086E750E97BA1EF9D40792D11F10B1
-:10EF00004FEFB3A1D59D8FF5E530507AD0A697523B
-:10EF10009A676CF1119D6E2F4CD6681F920702B450
-:10EF2000919C52F424407EE2E811F95D01EDCB6F33
-:10EF30006CF01826DB5554F4A97E736688ECDFACC0
-:10EF400064DF15348FF5B606CF1ADA671B781FCB4E
-:10EF500064BCFAC968CC1F7E41B1119E6D6FB1DDF2
-:10EF60003316F39F61F7329637B59DF8C995981F10
-:10EF7000DA66D7A9F65090D94E5CAEC03D4A7AF712
-:10EF800078F6F10F843D15FFFD677982DF6755083C
-:10EF90003B33BEFC8E3C21DF3E76242E5F6EB6AF47
-:10EFA000B86BFA43C4D7EC6D7620BFC5AA2CA32753
-:10EFB0009C4F5F3D930FA1E15179C50BAA9BBE0FFA
-:10EFC000E4EF1577CD83B05BF4437EAC5549464FF3
-:10EFD000F23B7C3C29F13C6E31E7613FD3A39B7E41
-:10EFE0003DFCFDE3BCF3AFD37E2609421989DABBB1
-:10EFF000F97B563071FB7BCCF13F4E4F5C5EDFD12D
-:10F000007F2F086444B7137CA7739CBE5C6E3F934C
-:10F01000068184EBC8E4EF9063E410DEEC423A270B
-:10F020007E519E96ED0024F1F91079C540F8CF206D
-:10F030009300F1145C7A29F12950EC91B04517281E
-:10F040003F1680F201D90B3644C67338B51B56DB28
-:10F050003F0847D1D10C23360F543F4ADE7C427D16
-:10F06000E37A928714A612BE9F022D554D805F56FB
-:10F070003ACF257B95A8F51CEC464F6A33E178B072
-:10F080005762383E6FF2B191F320A1BED696E711D8
-:10F090007659A1DEF37C7283E0EBCB88EE377E1FDE
-:10F0A00032B9FCABC219F182E57AE4BBEE10FB2960
-:10F0B000BF71785BF8DD27062F3EC98F9F777F2EC3
-:10F0C0002FE8EB7D2B8FE58A3690E4629349BF4DA4
-:10F0D0008AD163989BF8185426827F9F7C534F8D6A
-:10F0E0005B771318390BC8AFA1D875E267C932F83E
-:10F0F0009F4E00FFF875A79AF3C6F6735BA93D789B
-:10F1000074C1E7C0EBCA463D9FFE854B280FBC6922
-:10F11000A7FEE7F93DFA7A54813ECF13FAF40208CC
-:10F12000DB890F77819F3BD34E7EDB78387A419B1A
-:10F130002FE55F189EE905C6E7041F9B4BCDDE8ACD
-:10F14000EB9C1FF000F9696E98079E629C8FEFBBE5
-:10F15000E96F185877E155434AD6527AE9F83A9957
-:10F160005B4F66BD4F0AF491CF5DFAD5F5BE3A8F7D
-:10F17000AF90E8E390A42D61384808079237BD8F1F
-:10F180000F5C1005C715FDCA7F9F9F45E7036064AC
-:10F1900090BF788793FD56B001580FADD9397813D9
-:10F1A000C9852FF27DAF51BD51934DFFAD11197837
-:10F1B00075CAC5C30BFFEC44271782976CD2FB417D
-:10F1C0004F62BC19972FF6EBABD24B66BE8043045F
-:10F1D000E1B0B9EC9BA717845F0CFF782D5FF05F5F
-:10F1E0002BB5E0366A5AAC7FF735731DAFE57B3837
-:10F1F000FD22DFCB706EEFF7E9E12492FF0E5C7F1A
-:10F2000002BCF7764337DDADBF3B7AF9A6F8F2C111
-:10F21000E4C4F35CFC2D99E71B344FE2F32589E746
-:10F22000F96F17894FB83F4B5CF9DFFC3CBFC8371B
-:10F23000DEC8A779A6279EE74F2F129EC8EC96B48A
-:10F2400062BDD9C807A9DE373D5F082C984272E835
-:10F250001A9FF0FF1723C7253E845379F4DC70D240
-:10F260006FF5751B88EFACF4E80195F9C81BF982BE
-:10F270000F8281F399394D627F52FB884F97288422
-:10F28000EFD9D09A46FC6AA793FDD9F1EB0F99EB21
-:10F29000473A799CE004D32303899F1C1C98984F1C
-:10F2A0003C1E5FBF3EC2F2697D7962FD749B49AF2F
-:10F2B0002B5C0DD3B26DD1E72BB84099B86CC0E888
-:10F2C00043F2B64C5D4BFCC4817289E0EAE833A49A
-:10F2D00027ED07E6BD12F981735E3F207918DE271E
-:10F2E0003AE097D739CEF1DABD6A81BD7B7EBE5C4C
-:10F2F0007E66A43FC17AB66ABE5DF95176E3F22D0F
-:10F30000AFAA05D1FE7108DB800547C4E6E5F341ED
-:10F31000D36FD0132ECA6F509C29E865453F2FCB81
-:10F3200007921B643FD7BD30A6943617F50F20FB1C
-:10F33000209292CCF222D87B6CA11605CF0FF32D30
-:10F34000FD53EE46AF74C47C7FB7D685266567FE55
-:10F35000FAA3FBA6903E3F1FC2EBA8FEFC553DE87A
-:10F3600008B2639D1DFD9D9162F4DBCEFE15FE5E2D
-:10F37000EE72B7CA433175FF2EE17E6CD58CA304C3
-:10F38000CFB5FD8C63B4CE78F805EE1A9FC67E0427
-:10F3900082DF655DF7BDBB7DFEAB669CA6FE5EE8C9
-:10F3A000A75A7E1D9DCFE392ADF361453DECEA8403
-:10F3B000F757DD9764D3BF88FAC4399AB701557EF1
-:10F3C0009ACF3C8BBEE3F41C2814FE803A4FDBBA84
-:10F3D0005D517478832D9225E476781D3999FE6706
-:10F3E0004712F38FF61DBFEDE7E3F3344BEFE8214F
-:10F3F0009FEBF1D5E767F917ECC989F569EB1C6359
-:10F40000B7BDA880F5123AE71D8D79495B44F6AA8D
-:10F41000A2821EC4F5955F8ED884FD4D92FBB68402
-:10F42000711D9FC3D9E40998FE2788F5AF7AF3A32D
-:10F4300074F2634E52ECC7A3F953BC1F684041AC51
-:10F440003FF914CC4B6D25B88C4F67B86C6F99940D
-:10F450004AFD943C3FB927A5BB6AEB55C5DEE90FD1
-:10F460008A9F7F793776E9B002A177BE9E6C0C2B1C
-:10F47000C0B4BC9BF58F32EB85938D5105599DFD32
-:10F4800051FD44F1106D832C3FAE80EB358105AC0E
-:10F490006FD95CC857897FA2FE2AABE4272CB03312
-:10F4A000BD1BA0A9D9EC3714FB8F7C5DC1FC0433D4
-:10F4B0002FD5BF1DA4761B6FF1F03938F83420F931
-:10F4C0008080E173813AC9CF7E0717C57D60BA5E3F
-:10F4D000D237902E26DB2219822E4222AE017C0AE0
-:10F4E000E57F2B85831427B0D6F5EF3F273FB81172
-:10F4F00054206922E615603F63E0600A9FCBF1CC9F
-:10F50000701E4E6B5E663EC5CCB7CF9A3A6D00A6B4
-:10F51000B7253FE2213C0D4BC847B19F2F93FFBD5C
-:10F5200095E9C69FACDB7B937FE93DCE4B2B937572
-:10F530002987FC4F9E42D2535743B2EEC4710C77D9
-:10F540007180C67568C0FEF86468E475B8DD9F0414
-:10F5500008282AA812DB4FC9BE65056CAF009F932F
-:10F560001F7E2F6533AD3F493DD57A077ECA0083A4
-:10F57000EB65C4C9C72CF72A89E337BC4A9C5CF405
-:10F580004904FF9E73E3BFC7CA4B171C54899F48A9
-:10F59000ADDE9C73C89FDA086E659D706B53845D09
-:10F5A00067C12D30C9FF4B826BE04EA71ACCECDE51
-:10F5B000DF86001A45FA789BBA642BD547C3096CDD
-:10F5C000D45F8E585FA0D229F641F16DA5F6EFD831
-:10F5D0007354B27B2C3C7B68A0C9AFBBF1773C5025
-:10F5E00020F4A3EAF4C3D524E70007B5F50738995A
-:10F5F000727424F10D9497F5242F93EC06C3DB92DB
-:10F600009B2B9AD600D15575F30220BEF28EE41BD7
-:10F61000F032DB23C076D99C6981576C1AF9B26647
-:10F62000AE7363FA49411EE3D7FE57A6BEC26C48CB
-:10F63000761753BBD2CBBC53B270DC6031E8776233
-:10F64000BD60926FEBB3B4AE3765FD318DE2212A18
-:10F65000E0C3E12632E1F74DB333D86F9A5911A9CF
-:10F66000A37881C8DDA0527C4F17FA388BEB1B09B9
-:10F67000F00B1E0BFB59A4B612FEF4427C93D4CEC1
-:10F68000F247A93C5FE42FC37C8DD852C86F29FF95
-:10F69000DE0882479B0C141655D322D968FCFC99CE
-:10F6A000C359AF29A0F2CCE8F2B4E54F61BE60EED9
-:10F6B000049DC849B3F97E762B95BF01BC0E30F985
-:10F6C000F7A838FA1DD749375C5EDA91F757D07C36
-:10F6D0005FB919D88EAD31E56D0CBDD162B1CC18D2
-:10F6E00049F8D7D10F503F15667E9CA2723F7DFD31
-:10F6F00060F205EFC607F89CC0A6937FB24E6A6021
-:10F70000F840C0CFFA1EC5CD10BDF49FB76BB79DB2
-:10F7100006CB1474A7EF157457065E99E03552BDF9
-:10F720003B48E3CF9997CB7C66CC5160B830E5611C
-:10F730007E429AC4FB943F209FF165BC4BAF97116A
-:10F740008F64B9343F09C79B3B4FE2F38959735D1E
-:10F750002109FF390BE983E3A1145FEE6CC4F7398B
-:10F760003E499CFB627E5E943F1EB5613E379BED39
-:10F7700004FFD309F0397F80C077AB7DCD5A478C29
-:10F780007FE792016EE1E71830F59302E6BF22AE03
-:10F79000252BD91B117CA381F9D4611BEADFA4FFBF
-:10F7A00082C1FAF63526BD5BFC6296710BDBC1B3F4
-:10F7B000BCB17AF43BB4274407D74AACE7CE997B77
-:10F7C0007E3DFB5C8164C6DDF455599E99DF35D0E2
-:10F7D000D89EBE9AF49C12FC380DF59028FD7EDE72
-:10F7E0006D67D3B87ECFC7579CBB0451A152F09729
-:10F7F0001A8427F1CBF26B15A697EAB50E8EFFAAF5
-:10F80000695E63CF267CFE21E8025FDFAFEB83F306
-:10F81000EC53658C90B528BF4D554822BACE269E34
-:10F82000C3F08F38C82F37DBA157D1BA66A7831A28
-:10F830004843BCBCF68A8DD4FF5A17A832CADBDE17
-:10F840002D6F8608AF9095EB849388391CD7D657D7
-:10F85000EDC1E70BF5B6611CB755EF49D1A3E3A4A1
-:10F86000D6AFE9C43B8AD7D29C304C35F737919D4F
-:10F87000346480E0570F4AC0F22270AD8BE19C9552
-:10F880002FE295B2527547308DF88D66D5E338BBBF
-:10F8900007EDBE5EC3310DA15A29F647B48BA7FB15
-:10F8A000AC0CB39F1E9A1444629CD9525A6623B87A
-:10F8B000B953748A4FB4FAAD4836ECC4B72A8648B7
-:10F8C00023820CCF4DCA22D24F9362F9BEDD2EF6B1
-:10F8D00005DE157C3F5E0EA21C60BE4F7EFB6019EC
-:10F8E000CBAF8A01592C0FB89FD58A4B75EAD0450A
-:10F8F0009E657A2185FC5CC31064A4AFB7E5786788
-:10F9000050FC5EE07585FD6A6573F5EB1647EDEB1F
-:10F91000E60E391099CFF1503FD4FB503CD4DAF2C7
-:10F92000CE3CC53D56428383F0BD324E3E2E73BF62
-:10F93000CC7AE4B247ED9DF80B1427AAE713FFA891
-:10F940007AAA8B3F88F954273F8BB32F417D89D604
-:10F950003302F931F121A3204566FF32CC13721432
-:10F960001E97C82F267B56D793DC6B97521AE4B2AA
-:10F970004E3E39C2DCAFBB14EF4B141F1B407DE978
-:10F980003115BACA01F0B3FE3211E526E9D152CBE6
-:10F990001C99C6DDB814FBA6F37C255C41F9DB9607
-:10F9A0008A735208DCCCE760E3024E95E8FFCBE4B3
-:10F9B000FE6BCD71FD7664D6C7D41F727F80FB428B
-:10F9C0007A8B44FC10CB7B4FC3A64807E35A8E705A
-:10F9D0007F1B33045DC4EB312FDBDC219B8DF86E84
-:10F9E00080E54E128472087E4681E0B36507049F6D
-:10F9F0007D2E801AB44CAAACFF9AE9B9AC0772F913
-:10FA0000D80870FCCC0EF0559BFACE5D034650B47E
-:10FA1000A85FF071535FB0F4B82971FB78B9FB7E31
-:10FA200085F8D6E5395DF64BA6FEA781C4FAE21546
-:10FA3000DAF9F99661F12588E54BB97096F70FEE82
-:10FA4000DE732BF90982717A50F022F5A05EB9BEFF
-:10FA50005FD0FAE2F5A1EEE2299F1A7071F194A845
-:10FA600041CC27F935D6B2B3E2F0A77ACFF1F9F756
-:10FA70004027DE75E07360D375B40E94E72AD97D14
-:10FA8000D26F1E62BA5E8BF5E4F104CD83C1FFC272
-:10FA90007CAB0DFC14AF003EF534E1A92577911342
-:10FAA000319ED42D1678374A11F9BEA8C8125E06C9
-:10FAB00047C7EBEBBE5CF2471B65C51C1F6BC9E378
-:10FAC000E13683F16404E81954CFC2939161518EF9
-:10FAD000F8F11AF19371D3105FF228CE76541FD249
-:10FAE000BBCA4163FC288F936B15EE990AD17985C7
-:10FAF0002B7EFF0D3E779C6CE2C714F5EBE1C7252A
-:10FB0000841F96DC423DF9AE38FBE2AE38FBE22BB7
-:10FB1000E0C7918BC18FC845E247BBFD87EF05CA9F
-:10FB2000D89EF5CBFDBBE287D472DB927B88DE8367
-:10FB30002940FBFE74925AE1C679D6548AB8F3E1A3
-:10FB4000BF2F08523E7B452EEB854FA7E92F71B999
-:10FB50005F9497B519720AE6F3576139E69FCEF5BF
-:10FB60005650BE66359663FD11FB7C41CA17FC50AA
-:10FB70009497DEE97F2985E47C40B47FE1589DECD1
-:10FB8000C1F2509DD9BEBCA182F235F5A2FDC803D9
-:10FB9000A120E507DF23C6B7F4CECB4CFEF9B47441
-:10FBA000EAA5DBA93FE49F9B917F8E3B61946EC3E6
-:10FBB000FC22D56623BC5D1C09D8091F0EDBAA46B2
-:10FBC00012FEC0425F0EE19993EC56B9937FD9C8FB
-:10FBD000A983ED262A76D6FB5E95FC0AD59B4624A2
-:10FBE000417276B4EE22FE4EF1C89B51DE1499F2BA
-:10FBF000C88ADFA57B0433A2F6AB68A090F356BD9C
-:10FC0000EC748117F0B0C00B2BBEB8F52190C8DFA3
-:10FC1000426B633F449778633FCBEF50BFE2618410
-:10FC2000B797539C31965F3E56C419979E3B3D351E
-:10FC3000915D347CA0B0E78F9AF722ACEF95A15C80
-:10FC40001BD1CFD3843CBD099EDA1F495F7A9AC687
-:10FC50001ACB200DC068DA47912F7FBCEF7DF57D70
-:10FC60000196DAFC0AE111F497749AFF556DFEC90A
-:10FC7000BC9E2A80EFF54AB00E53DE2F093A368B30
-:10FC80003811C17F6699FB764C9DF7CAED6C3F7BBE
-:10FC9000743B8E3369FC00A6FB9973258BEEBF3352
-:10FCA00090F4603AC1607FB68FE3DD6F8290830687
-:10FCB000B9298EEE97BB3F7B8FE4D2F22DB174BD94
-:10FCC000025A1DC2DF1C79E46DECBF72438A4AF20E
-:10FCD0006745636CBDCA0DBF3F209574E50395165B
-:10FCE0001F08C5F2015438041F7868089F7FADCC07
-:10FCF00091B54319E4FFF0B3BC4F0221EFEF52F48A
-:10FD000030D35F8B53D851A67E7E9B2CF4F32470A6
-:10FD100069EE42E2C336335E55E4ADF1212ECEE505
-:10FD200054C3CDCC6FAC78180420CBFB5381CBD51A
-:10FD3000683F5B079F8FA3F7D2969EAD74DFC0F23A
-:10FD4000B3A07EC0F6152C424E378EF910EF9BB44F
-:10FD50000CFF3F86D6E5E0753DD4A33FF3F7D548C9
-:10FD600010CE52B28B95E256EA7388A02717D111B4
-:10FD7000F1F769B1F65612083D7E789BF0E38CE806
-:10FD800094FB75B4BF4ED05D42EE3700D157B7F645
-:10FD90008A7B55427B852514F63F7B9AE0EB17B2B0
-:10FDA00057BAB3473AF63309F5364C67FA92B6D3E9
-:10FDB000BA2F3B9B9A92289E6A66B9EC25BB6CA62B
-:10FDC000DDC84A4FA0E73F60EAD91DF57D6EEE4FD2
-:10FDD000F1656CA7F825ECB795F87FDBEB8E8471A5
-:10FDE000C98AD9BF6237D444FD5F454EA9287FBB7D
-:10FDF000E2CBE67EBF017DE579DA977879E4D81D1C
-:10FE0000774E098181D171054F0F12FC6E4281F14D
-:10FE10009B81744E94D49FF99D568AF6541FCE73DD
-:10FE20007F076FBE9CE3243E03E38271126BA3FC49
-:10FE3000E707D3129F8BBC61F2D7148A7DC3F47697
-:10FE4000CDF8038D7FD421CE5D8E269BA9479C5B88
-:10FE5000BDD3515FF0C788C5276DA2FC687AEC79E5
-:10FE60008D55EF94D9EE50ADCBBB36CAFFAA3DE419
-:10FE7000F4939CCECA37EF71AC02B69FDB9F4FDB89
-:10FE800014BDAF670796A70CA2F8A27CC3D18BE084
-:10FE9000F8BC907FD54AD841FBFBF025BEA334EFD8
-:10FEA0006A0D8C67A81F2DECB8A698EC06111FD21E
-:10FEB0006E1776607B9248AD799D1D382365109D45
-:10FEC000CBDE1C66BED8919F1166BE7776A097C721
-:10FED0006D9F65959BF9FF10790D549DE65BEE32A1
-:10FEE000ED8742752DFB5D51EF23BF4DFCF901C03D
-:10FEF00078A11F9BF19E46DFBFF3395E777E7E9B24
-:10FF0000ABED95FFC2EFF34D7FB0AFF9D357EED015
-:10FF1000187F0ED3B80B4249C071DFFFA45FBFBD8D
-:10FF20005F1BAF677D79A4FFC3651C2FC07EB5152D
-:10FF30002DBF65BEBEC2A2FBA658BAEF65C2F14294
-:10FF4000E76AF1E72DDF009D0D1C9440EFFB35C9FA
-:10FF50006BC4AF29F274E66BA79A24F68768D05673
-:10FF600047705E29897D59F9EA8D150ECA2F0695CD
-:10FF7000F97C533C3FF305494F585E0F2CEF4A2163
-:10FF80003F95E05DB357261F02DFB7D1A2F824DD0D
-:10FF9000B7D1A2EC62BA6F139DA7FB36D1F5E9BECB
-:10FFA0004D7439DDB7892EA7FB36D179BA6F135D51
-:10FFB0009FEEDB44E7E9BE4D747DBA6F139DA7FB4E
-:10FFC00036D1F58F80FFC1F112C175E206826BD385
-:10FFD0001AA74A70C5ED7AAB289BC519E31FDDCB84
-:10FFE00089EE67B967AA6305C2614F8E0CD268BA01
-:10FFF00077B32CA6DFE57215FB0950ED6039E2C737
-:020000021000EC
-:10000000FF313CE522B6933F6F962003F175E986F8
-:1000100038FDA1E5DE3AD2B76F0AC57E5F0E517E8C
-:10002000F7DCAEE7404B0699F1C0BDA137E1F31410
-:10003000D9ADD33E9FDA27EB4E305D00B4CF5B8560
-:100040003FB214063D349EF7D10E218D8E4744F900
-:10005000A98D722890DB793E746AEFAF0EFBB0DE9B
-:10006000D25EB24A74E7CC89DDEF242D76BF7B14D3
-:10007000C6EE778A1EBBDFA9A363F73B1ECE694697
-:10008000ECFE833C9DE1BCBC0F9A77387EC6B45829
-:100090007CB0E03B1AFF27F05563F82E41F83E2C68
-:1000A000D1B9DA3D7BFA685DE15CDD7CAF83F4D7E2
-:1000B0008B85F37D7170FE1CC657B819B830D335E7
-:1000C000B2535F2ADBEBE72081636ADF0AF35EAF9E
-:1000D00038DF31E18AFA0BDB0B51E750F5B2CCFA8D
-:1000E000CC26A267233385F980BEA107EFD73097CE
-:1000F000E86F31F8983F2D8ED36B96BAEF77905E0C
-:1001000013BF4E9A0DF95D2A5B845E13BFDE2EFE8F
-:10011000A842B5B58FE0DB8D0FEBB4CC168B4FFB4F
-:10012000C88F91096D0ED263BAE38333728C5F93EB
-:10013000DC402E06040F610AF05F427DB2A6A35890
-:10014000F8E79D7EE1E787401ACF6314887970A3B2
-:10015000287FFF2825C47E073429D8BF64D963F1DE
-:10016000F084BED2DAB7B05FF92530E1A8CB92AD0A
-:10017000D37F8F56A041FAF5C8CF84FE34DAD51864
-:1001800054B4AEF6F927F9E639B762C67F5EE01CD3
-:1001900092E64F7E8E6BCCF8BB092DA35EA17CC787
-:1001A000B9E4CE57FBD07E8DDFF9FB0C4ADF92B469
-:1001B000C7EEC0F1AF96045EC4DB95C11DE334DA2F
-:1001C000FFCB242FFB2BA682BFAFB047423CAF89A9
-:1001D0002E1FEBB5369761E7F328D37F09109E4AAF
-:1001E0007AFA32DDC1F358AB7E3095FC31CBC1F4E5
-:1001F000C734C7EE5F177B28CE0EAAC2FDA77EE3E9
-:10020000ED9E047814170F102BEF17145AF7CA45F8
-:10021000BC8A06E2FE77A5E947AA746DF4887338B4
-:1002200094737DA18BDDA410E0C7F07985BD90EDBE
-:1002300062B407F8BC5F73248AD7033593CFD56FB8
-:1002400074CF64BE7C637D17BF0EE3F5E2860BAC12
-:10025000CBD413C6D3379CFFE1419A90FBC9D3F7A7
-:100260001A545CD6D63F5A9FAD7188FBB9E0CF884F
-:10027000B9B730B8509C7B97997A53A5CB8453611A
-:10028000A08EF4E30EBDA98BBDF8F5EEC958F12E92
-:1002900008AFA242C6E306CF9ACCCEF31D6B1D9FDA
-:1002A0008C687BBC15E125A74C76117F5CD1CF37DC
-:1002B0008CEAF73B103E4C74036E8DF5F593CDC779
-:1002C000F6CB799DEB423C7B701CADA35956C5BD66
-:1002D000F940DD38ECB7BD54E05DF7F6AF8027CECE
-:1002E000EBB2C2ACAEF3B2E2ECA7C845A9E128BDBF
-:1002F0003DC3845FFB10EF146A57F6C7BE1E9AAF6A
-:100300003DAF714F6FD28B6F157A31EE2BFB41648D
-:100310003B48A4974E91CFDE42F95339A092FD9904
-:10032000D923207B48CF5B00EC2702DDAF13AAC89E
-:10033000FD8AD84ECEBE15ED27ECF7DD5537A6D198
-:10034000FDFEEC944569F96E8A6FC2A90EC0BC64CB
-:10035000F38AFBD9CFBCF76F65543E8FFDD2D73BF4
-:10036000C53973EE0FFEB69CE900B474E7181ACFD6
-:10037000C7EF0B44D2649E5FF9B59F0D27FDAAF726
-:1003800059F730D2CF7AD1392F8274A8491F9755A7
-:100390004486FBDD9D70CACC4F6CBF649BF03898DF
-:1003A0007C72369D8758F7301EEAF1069F879F348E
-:1003B000CF4FF28C69A984E707075AE75AAD59E491
-:1003C000B2AA4E3252E7D03CDF94F97EC567AA91BB
-:1003D0009A86E527C1CBFA63A0CDCEE744ABEEAE5B
-:1003E000E899EEEE3E6E7F4DA1B06FAAE2E2A2AABE
-:1003F0009456079D6755FD9371514D6871273A0FCB
-:10040000B3D65F9DA68032145309BCE7ABF7E23F39
-:10041000E48470DC629677777FE3E7E6FAACFB1959
-:10042000D5743F033FAD7ABEBC279CC70EAD3E33AB
-:100430002EE61E04D96BB4BEEA3313F97BC55D27E3
-:100440001C84DFD40F3D8560DDCFE80ECED985C298
-:10045000DEA8A67B0D19D1DF051D77F69FC9E54FF4
-:100460009A707B72AF6DDAE604F37CBD50D8DD4341
-:10047000B214F6175CDA0AC6A604E35AF5ACF70D17
-:10048000BA9B57D3A4F07C9A37C505271A6FA709E2
-:10049000476BBE4DE9E1255E71CE3A90DE2FE8C88C
-:1004A000AB91FE5747F1D3B3A67FA0E93BE1FEFC39
-:1004B0005EC615C28EED6E9FE7F4F3A5137F18A9F3
-:1004C000B4DEFA4A269B5D407EB49EF35A6D242723
-:1004D0003BF84F37FBDD096739E61E4C57383BB810
-:1004E000BCE3FE19181E299BE410B03EF0D01F4B50
-:1004F0001C0E1CFF980D22C477A6C87DA7BE4079AC
-:10050000B41F882E8FB1ECC07483CCF7998E3D9ABE
-:10051000EF20BB6C49394464E45BC7DEEA5F477196
-:1005200097DA02D424C7A1BAB336F6FCB1128C3DD7
-:1005300029D8EEC603DED456CC2FBA27568E1D7BA3
-:10054000EBC70EB207A4856E3FC515E13CA7BE8080
-:10055000F9C5CD0EBE9FB5E4FEF8FE62F5E06C5322
-:10056000DEC6EBC39F179AFAF048184972E685DA9F
-:1005700066F17E8E791F11F53F23119E587A7028FF
-:1005800079D2DF99EF43A34C7C699C92B8FE92220A
-:10059000B10F2B1F3BEDF068DDD3D971E42705388F
-:1005A000FE895A95D3ACC1866B30F63F60B02F659B
-:1005B00030B697B548FF4FD8CF29CE4111DF385F0D
-:1005C00043F7D448DECE157A8253BEB992F5D13EB8
-:1005D000A006597FF1FBD99F6E43FD248DE2376E53
-:1005E000913DEC6F10EF078DF968511AAD37F3BFED
-:1005F000E73C4D70A53B0E40EFB0941BA5C4DFD780
-:10060000CF70F379FF265B80FBA140ADBB109EA1AC
-:1006100027C7EC26F77941E3BD93C8EE535B76B567
-:1006200092BD526FFB740FC525D44F043DC8D00E48
-:10063000F138352D339EA6F6FD67BA75BA5FBA3E1E
-:10064000D72855A3FAD720F21EE99927AB6CEC37CF
-:100650003DD5FC0B3EAF42FB2E42CAF7A9AA3CF6A1
-:100660009B59713F7CF697C06F7802E51B44DDE72C
-:100670005ED1B4C946FAF8A5B451517155D6BCAA99
-:10068000EE6CCDBE8EE4EE130ACBD1CCDF5CC1F1B3
-:1006900003B98A26113CAF9354A18F9A7AF2B560C0
-:1006A000FD35BC42FAE942D293110F3F94421CAF90
-:1006B00069839667A9FDDC1CA10F82D63882FCD71E
-:1006C000E12AF37DA2E5F634D26FAC7382EEF0A19D
-:1006D0003B3F0FF6B4E41D1CF7A404EC6FAAB14530
-:1006E000FAD3FC8EDB13CBD779834D3E30D01F621B
-:1006F000799E0EEA6334AF025F2ED165B54D5BC9BA
-:100700007EAF7D5E8E0F6997D4F498775ED4865F56
-:1007100093DE5D6353857D73C028A5F398F6194574
-:10072000FCEECB497BB83FF311E47B149775EB13D8
-:100730004D3315845B756FD4BB30BFF9895D3315BC
-:100740007A87272FBCC486F95707FF45940F091FE6
-:10075000A6FC1F9FF848940F0B2FA1FD39F9C4691F
-:100760009127030C11EC6F4FFCEFCC00AEEBB8E916
-:10077000FF043D3C9FE659FDC2205BB47FF1C86099
-:10078000C1378F27897AC773E186AB49FF280CF3FD
-:100790007D18ABDE6B83CDFB0426FEDFF462522BAB
-:1007A000C5095BED202771FF41B3DD4DE67B59485C
-:1007B0007FBFA27A2FE768E9BCCF479147115C9EC3
-:1007C0001FCCE73D370D4EE7FA049FF4A2AEE32DB0
-:1007D00023394F72C01E7BFFADC1DC2F2812FD579D
-:1007E000F756D3683FB2D3859D811B927617BF63BE
-:1007F000B0C9D4ABC4FE64CA6A695065B9339CEC15
-:10080000E697CFF62D65BBB9A29BFB9E83851CBBEB
-:100810002928C689F4D2D4CD7CEF1C0C8A4779B93B
-:10082000396973F47B29274DF81E199C26E0D7B14E
-:100830000F3D251E2768C2A52FC2BBB8137FACF69B
-:10084000175AF7F67FD1BABBEC5399989FB51E8023
-:100850007B051C707E69A8E71F5F63B61B6DCD43E7
-:10086000637AB8E9C5DB3708FEA7A5B3DD0E3F11F3
-:10087000707059E316F1F9E40A530F96036F38C804
-:10088000DE5851DFC6EFAFAD6814EF6D75D29DB184
-:100890002A9ACE32F3C53A33652333C8F488EB6322
-:1008A0007A34CC788358FCE980773C1D77E94F4B4C
-:1008B0008FED4FE3FEBADB87B08917DFD83E041314
-:1008C000C3B383BFC4C1AF831E73CD76458867654C
-:1008D0005DE9F18FDDD171EED71CCFBC77B2E27646
-:1008E000335E558BC5E3154DB9B685459DF5EF6E65
-:1008F000BCD71B1D4FEB6A5A1020F957D352CE714B
-:10090000B52B9EDBFAEB00B65FB6FD010F05531F5A
-:10091000531AB2492FAE7A6C9DC7A0731625E021F9
-:10092000BE792C244F4B747F75D41029461FABA67B
-:100930007F62FFC79FFC5BDDBFE1FCBF9050BF4201
-:10094000785737FDB58EECB73D862B4272FBA81267
-:100950009E4A72F4A6056E3FBD2F58D31CAB4F2D97
-:10096000FBE503D91A077707FAD8589F6AED43EDDC
-:10097000AA1FB5EB64BF57EF93751C066A20524758
-:10098000F38B6F5FD3F8A183E0AAA23ED8775CD740
-:1009900072E4248CF7354D3FFA54F6507AEC1D285A
-:1009A000A1FEA2FC1108F7CA6EF4B2C221B1F7028F
-:1009B0002CF840288BF59BE0130F95BC8FF33AF190
-:1009C000E86B1EA9285A5EDE29CEA91A6FFCF90B26
-:1009D0005AF772F524E907CEAE7A80D62C0925BBEA
-:1009E00045A455F6560FF905AA36D9F5007EAEDABC
-:1009F000FA8BC7E95C05DE76EA74F458B5F5B48382
-:100A0000DE3FAB928C88C47A1678A4919DFBB47CAF
-:100A1000EB47C25FD54B86E9B84FCB7EF5B9A86FDF
-:100A2000402409EB2F7FFA7DF66F55F9DC7E578263
-:100A30007DAA68DCE508BB13EC53E3FB53490F0ABE
-:100A40003EF125EFC3B19D12F4CCEDDABE72D3476F
-:100A50000EA29B13B8211969025E649FD634CA0B9B
-:100A60001CA989F6ADF52AD2FFB09CFD2017DA3F0C
-:100A7000D7101074F1DCD66D640F54BEE3D4A7D345
-:100A8000B8DB6EF100EEFF11C52FF0FD67EBB20D84
-:100A90001CB7D21EC8563915DF2B1FB995F170E966
-:100AA0009BB766B35E07462FDB685E6F2F5AE7E29F
-:100AB0008DB3789D4BC0C77858F933E1CFF85C818E
-:100AC0006989EE1B6F1F22E487136E2E21FAF81C32
-:100AD0007B223FCC11078878DEB7C43B644EB83A1E
-:100AE00035FA9DB93B8708391080D07BF4FE640D40
-:100AF000DAC5C417E4373F9F4AFDACCA55FC4E9592
-:100B0000D71F30E1259D13F11C9A62C59DE6E17E59
-:100B1000BD39A527D9C14E38E5B8BE8CDF69D0C82C
-:100B2000FF1BD58EE17664B33359423BFF4876E232
-:100B30007B84EF99EBC0BFB7200A9F6AB61C617C2B
-:100B400002B4BB527344FE61A243B48B52116E9F38
-:100B5000EDFBD0D19BFC1D99361840F36DFB88F35B
-:100B6000A0676954DFEABFA6D919F32E49CDA31FA8
-:100B7000C5D1B333EEBD133FC3B3065235D2378F61
-:100B80003822535FA471705C8AD75C72BF33E6BDB4
-:100B9000B04E7C71747ECFEDA44FCBBE5A6AD27F2B
-:100BA000FCFAE3F9C19371FC0036667DA5F79FAAB4
-:100BB000ECA1C7093E5548AF01A657417FA8A347FE
-:100BC00006203D7CFCD44BFBBF4F7EBA467BE674CF
-:100BD0001E2D96CF563E83F44BFE348477924E7C86
-:100BE000F64B07E9BD39156807E3BC3F76EB74297E
-:100BF000AD2BDDE2F78474EB063ED7FABFC55F97F5
-:100C000076C35FF7C5C1F373284AA53B0CC79F5C49
-:100C10007E09FB15E2E06BD9BBF17CB37A88C67024
-:100C20008EE79BF8B71FA2E0B8ECBF3F61BCFDA206
-:100C3000973807AB7EF4AF2CBF10AC1127E26D756F
-:100C4000E853CEAF23F9C5F95D33E9BCBAEBBA631B
-:100C5000E1195FBEC1E4471DF7DCEE8400C5DD4548
-:100C600076C8FC0E433BCEA58EF4F3A772F99C70B8
-:100C70009DA9EFB7AB110FE9E7EBD2AC3CDC40EF3D
-:100C8000C1B4074AD400B54F32E30FBC114F5A9498
-:100C90009EF47E8BEC21BD2E1C826989DF050CF24F
-:100CA0003CC2D05DF91A715F4B3EBB2D6CDAF54E3C
-:100CB0001C2FBCE6CB6D746E7E4871F1B9E5A23590
-:100CC000733C7CFFAF25FF3F092F16BF8A70247A43
-:100CD0000A188E5E08E71B0508D0FC08F079B09C66
-:100CE00052B6E745ACB704014CE724F1FE9465E049
-:100CF0004D6DCDEDEA374139E820F9BF14E511FB20
-:100D0000BD37C6962F6BF998F16C591C9EF908CF28
-:100D10007A75C5B3DC4B4DFF4A29949AE7BA6CCF7C
-:100D2000B7EF95F93CFF940B58DFA0735EDC3138C8
-:100D3000D522F3FE9C7A4A0A71BC61204BBCDF8A43
-:100D4000F84E7A968587F1F67D7C7AE2D97747D29C
-:100D50003DB1AA5FFFA5E4BF303DF1EBB707BE4848
-:100D6000F9E7FEDCFF2FD0B57EC5CEBFB21DD3BEE6
-:100D7000D3C9FED0F69DBFED4F72B9FD05A74EF861
-:100D8000DB7EA753C435EC4CE177CCDAFB09BF5DC1
-:100D900070C7972561965B6B791FA75FEAE0FD3E00
-:100DA000D5F2379623A75A9C1AADA366670FF68F24
-:100DB000D5BC901422FF40FB8E2F4746BF77F5CF5E
-:100DC000AEA7DABC4FD39E0273296EA63D4DC4591F
-:100DD000D6BC38E6176BC81E69DAE520FF7FC56F01
-:100DE000FE5E427CA9FD995D0EE25B68973E02883B
-:100DF0001F732EFDE903F65E745F0CD8DE3E7DE9BD
-:100E00003BB3E87DACAE701170684738D0BA102E95
-:100E100095A49775078FEA6F2D3C3E657BA2AA6566
-:100E200014D351275C24437C4F09B9245AFFF31E85
-:100E3000F21BB5E7A1FCD769DD5F9690FE74A17542
-:100E4000FFC7A5E27DEEFFE7D76D838B5AF753DF2F
-:100E5000DA750BFC1F76A926DEA78AA383AE78FE7F
-:100E6000DC0F38BF2D45E7F97E45FA7FFD5BBBFE01
-:100E7000AFBCEF25E4B7BDD87DFFF85BBBEE0BED53
-:100E8000FBABE6BEA7A874BFAE7DC7DFFBF37ABF9E
-:100E9000E2BA938BBEADFCEDFCEBEED08F64AF8B72
-:100EA0009ED8BA075ADB344CD775A3A78C2AB2FC5C
-:100EB00010C21E914D7D631D0C3336915D857A06FF
-:100EC000D901EB3245BE1EF50799EF0F72B00AD477
-:100ED000F7D5C5BBB68A1F54CCDBFF7C23C7B3ACA8
-:100EE000CBFE0EE495D17985F06304D7E8BE5DD8DA
-:100EF0003E9866D3823A3D57B5D2B709CBD5DEB21C
-:100F00004AF6CD3AED6A57F43B168ADB1163A7B86F
-:100F1000E3EC8DE402478C5D9204BB55F2C327E9F4
-:100F20000AC7FF3921AA3DD6CF2A12EFF42743285A
-:100F3000A0BA2F1E4E8BBE3E9C5C7CAF5235E104A6
-:100F40008641EB766A0AEB610AA0FD28D621EC4EB9
-:100F500084A316054730ED50C504B9A20D6338A22D
-:100F600001A14D1A4D70F5331C83BD6495E1DAD9AA
-:100F70001FAF3B7E1FD6699320CFD4C725FD9B872B
-:100F8000F3D822111F100F672BCDF795AF21FD77F6
-:100F9000D51A71CEF5CCEFBEC3F9263BEAC374CFA8
-:100FA00030D5B7A288FC8E5E43223A5D3543BC2F14
-:100FB0005846F7C032C9D41771B899AEBEA0B0BFB9
-:100FC00012ED0CF657AA40F69F3C091AD91FE855B6
-:100FD000E2E27A558E7B0ADE2CE29EA01034F14EBE
-:100FE0004B6CFC4F601214525CC314B9AA81E675B5
-:100FF0000A521A28EED2616FEDCFFEE17E008F918A
-:10100000BFA5FC8B8D549E8B7A3DD07D32A5F53DDE
-:101010008A6FB84D4E058EAB8AE0A728B85D76C6BC
-:10102000054A149CCB212D267FA2DFE126B213F2C4
-:10103000024E9582C72A5CBD62DA9FE87586C70BAF
-:101040003A5D2AD94753D4DC98F6B267EF7B64D770
-:10105000BC916E63BBE0F29CC131EDAFFAE0C4C657
-:101060000526CED23ABEF7AEB8A78AF6D623AF632E
-:10107000BB37EF0720BFF1155A694CBB66D3BF12CF
-:101080009962E7F766AE2C1C13336E737837C3A5ED
-:101090002A0B243A0FAEB2214960BDEFEAE531F5E3
-:1010A000BE37FA8A987E67183362F255ABBF0025C7
-:1010B0000360DCEAB340EF0796B636C6B41FBEB78E
-:1010C00039A6BEE7753485302DDDA705291D75507D
-:1010D000DC231D8EFB41E71BCDE1853AC5EB14D324
-:1010E00005D0323A16F0565018F2C8A3FE9728BD24
-:1010F00050FC3298EFB2269BE7AFEB6DA1C605B965
-:1011000014FFD3F0E35D12C743EE263C1D1D69A812
-:1011100048C5EA63CF34BE446953DBF87A7AC7B373
-:101120000AA08DE5AFDBC6E70253E4961289ED9F76
-:101130001EC39D51E72EDDBDD7F9A3D2F27D4548F0
-:10114000476B738C865DC4F727BD3B5FCEEB5A0FB0
-:101150005425128DE73F2AF51EA6384D2B4E2AB98D
-:101160004216BF4771B98893A9B3E94926F362FDD6
-:10117000409D6AE738FE65C582BF8D6CDBDCE82EDA
-:1011800023BBD3A5D1BE2667C4DEF3BE71B4B8B706
-:10119000F7459179BEA2A859D7931FBC3845B4270B
-:1011A0001F1F8D37DDC6FA94E780BEC78EF9FB0A94
-:1011B000F7A9C4CE9AA67F10E0F74D0FB44D903436
-:1011C000809EF794DAC80E87BD76FE7D99A6C2C9C7
-:1011D000A70BA87CFA5B1CC3B86BC22F0B49BEAD32
-:1011E0001C3CE4BCEF8C7ACE48A045C5412C2BD6E4
-:1011F000783E1E25CCEF1279CE285CEE99A7DBFA5B
-:10120000478DB77282D0FF560E4EDE4A78EB3960BA
-:1012100088B8A842B73680E9239CC37C4209E75CC2
-:101220009F22E2ABB4F3BCF37F7CCB88349263198A
-:10123000E57A1AF94133B6CA1DF7CE683D3FA6FFDD
-:10124000D0C13AACDF3F19E7B58562D744792BF2BC
-:101250002458EFB0CA9125613E43B2CAD7CF9E5CF5
-:10126000C4EF31C6D41F9AD751DF70E574F6AF15BD
-:10127000AFDFBFB688E037CA467125EB7F67E777F7
-:1012800006709DAC4FAC447A06E97CF0EC710178B5
-:101290007AB8FC90A4C5BD9FDB5A4CF982BEBE4112
-:1012A000C558FF92B3A9FC0EC067F5492CFF2E3933
-:1012B000FB3D7EAFB3C961F4BF9DFD37491C6F365E
-:1012C000E3E68F37AC26BABEEA7821C52858EF5737
-:1012D000D6A85F303FB0E2EC3AE187F88B78FF6345
-:1012E0005B679EF883A7139E06BDCFB53E0ABEF48A
-:1012F0009B2F334C78FA8A37CE5E8BFD6B8BA6E53D
-:10130000105D9E0637C7F59D561F9F4DF33DBDC529
-:10131000CE41B44D26BF0C149AEF11648673E85E7B
-:101320007EF19B368E473A88F860203EE4B7BE993E
-:101330005E4CED3295748A6F383DFECFFC6EC2E98B
-:101340001F0207172F0B3B185E4D998B2ACA19FFF6
-:10135000B574F23F58F06D34FB79B8D4B8B298FD4B
-:101360005CE67D1163EC45BD3FB96BC2977C2EB046
-:101370003617F5FC340A393E5347EF4BAECCB5B3C4
-:101380005C5A99F6C5D44CC2F7725784DE81A859CD
-:10139000FD19C317BBC98DBE07A69C91418B8ADF7F
-:1013A000D2868AFD571483F75F39E3E0F2AAD5A706
-:1013B000996F5BED4F98E7ABF42E23DD17AAFA8700
-:1013C000CCF746911FD64BC328DDED5819C54FA069
-:1013D000F1D30E3E3F14F7EABEE96F25939F728664
-:1013E000A4CEA2F9B56C3B339BE2056624A9B328D1
-:1013F000DEA06EDBFBB329BE60463F7516C517DC69
-:10140000573C790E97F7521FB0A1FC7AB964BEC859
-:10141000E7AA7FA2FC535BEF98C3F553C4BEDFB6C7
-:1014200075CE9C00F36337D3C1A9FA1E21E779E892
-:1014300060E9EA1721FA3DDB2EE5E6EF49C15CC120
-:10144000F73EB9BB0FBFDB09056D1C2FB6BE58F8C0
-:10145000FB3BCF5741A5F3D5CC7C30C8DF9CF95C72
-:1014600092F85DA2436DFD097E4736DEF203F2A7D6
-:10147000AE9080DFD1AF026D24D1D5425BF83D4AFA
-:101480005F1CEEBBB798F5A9368E775DBA7A27CF89
-:10149000EF53DD8C5B562345DEAFF54E04F69FF02F
-:1014A0009D88D838E30F6CDA40EA5731E1B2506ECC
-:1014B0009BEF10F37A94E6B5227D17C7392B6A5B50
-:1014C000B64FE851856C3FE524F37BD175BDDF292C
-:1014D00049F43B088DB528EF91E49EA96DE674F5BB
-:1014E00050607CEBA9841D3AF6537D40C89D916DF8
-:1014F0001F38A2E319779BF04D357FEF2A3E1E7708
-:1015000037C9A5A8B88315BD5BFB927E68ED6BE774
-:10151000BEB4F635F70568BE99192F3D45EF9D50CD
-:101520009CEB0FE93CE3B9A456F25B778F27D63EDC
-:10153000887937250BBE11793689F5A6F8751C34E4
-:10154000E76DAD2762CADFEED61131E5EBBF6A1D4C
-:101550001193BFC7AFC7A26FEBBB45DF5DDB8BF954
-:101560005F3CDE897B6D17C23B8BFF5483AF50DC41
-:101570009716FCC682B7354F0B6E4DDDC4E32AAB20
-:101580009F8F598FD236898C1E482D11EF5F298D80
-:101590005700ED87B2BA85EB75B71E39E5333EC704
-:1015A00059A6819FF4DEF875554123B7EBBAAE0812
-:1015B000F3E3159AE0C75DE3F823CC9FABD13E235C
-:1015C0007DDC5A77079FC6F5137D4F4086C37C9319
-:1015D000EE124A645FF862F4E372BA31117D6EE58F
-:1015E000BA39263F45BD3DA6FEE5396B62CAAFD08C
-:1015F000EE8E29BFB2F0DE98FC77F59FC6E9F79B27
-:10160000E2F4FB2762CAC787DB58FF7EA3761AC7BE
-:10161000A74F3C1A613DBCB556E5FCEEDA1C4E5FA7
-:10162000AED598FEF7D41672BAB756E7EFBFAB1D2A
-:10163000CDE9EBB506A76DB55E4EE3F946595BB84B
-:101640008CFCFBA33353F93C6AE350DFF525140708
-:10165000B92F5244F837F640E34B240AF2439FBEB9
-:1016600047F54EAB0E8E475CBB6BCC1F6EC17CC684
-:10167000EB322469E7D38B6430A2F0C7333D0C749E
-:10168000FEED01F13E567CFD8525424F9E0B61F13A
-:101690009EC06A3E0187B92EF5152393C54684EC9A
-:1016A000F6B9E0673DD4B65ABC5333177428237B90
-:1016B000D607FE7B381E29F67D01AF3163DDAFB062
-:1016C0007C36DD3BC5F6DF7737F2BDF267F6A64F15
-:1016D0002EC5EFD77A25FE9D8F033BEFBAD5C5F611
-:1016E000AF75FFF41DDBC5E8130B4B047DB54B7ADA
-:1016F0001BCD379026DE2F8A6F37CA5CE755C108AD
-:10170000EB1F11D43F28DECCA2CB19EA2173FD9A3E
-:101710002D750CD1C71ABEDF50D5A6E94184F798C4
-:1017200043822E46205DD0BE8D3D2AE86024D20142
-:10173000CB41D33EB4E800EDA997A8FDA983A03B17
-:10174000B17DDDC41FC9647F8DF92C14A4F4B2B33C
-:10175000915DE7B07C5C9BF8DDA40BD993965EDAD3
-:10176000523B97F16867AD8FD3D6DA4A133FFD9CA1
-:101770007FB97635E7F7D40638DD5B5B6FE2670348
-:1017800097BF5EBB81F36FD4864C3CDDC2DF3592E0
-:1017900067089FBB4B4C39ED2A37ED0A917A8D359E
-:1017A00076BEE78F9F889FCCA5B9127E544A21E26E
-:1017B000DF75E9013BE5EB92690F68D601AE7F9DCD
-:1017C0001B5A490E54E5BC28F4B0383C29CFBC86DE
-:1017D000F164A619C77A20BDEE5607E2C389C6FB9D
-:1017E000ECB1EF8D5E1C5E2C73AFE57B7DF17CF17F
-:1017F000267A8F42EECA0F0174BDAC4CDCEFA238E2
-:10180000BDAFCAEF555B9B795F4CDC7FA9EEEBE681
-:1018100038DB7F9D9C514D39030BA87E87FD9D7C55
-:10182000703EBD8FD7052E71F6F7E141627F2DFB2B
-:101830001BF54CF64BB58764B6BF2A731B3C6C7F17
-:101840008F8E78683F6FDA2103EB8B8A38EF5D4A21
-:101850001D6914D7D3BA7F1CCB99557B882F2D33A4
-:10186000CF7BE3CF6DABE9BC574A04EF30C7D52F30
-:1018700037CF7BE3D75D3DFE089FF7565FE05EE91B
-:101880007B25B1BFE7137F7FB73B7CA17882E8F768
-:101890005C4F9EAD653BEDC8B63B1E0AF4FDD7ED2F
-:1018A000DFADA5DECF4A441C35DF9BB3F6B3CEFCDB
-:1018B0005DCEBA492EBEC7D03E42E5F76FDA25F1BC
-:1018C000FE4EFB5F415FA3D1FB3AEACB24172ED338
-:1018D0001DCC574787C57B01E3E95E6282F702268C
-:1018E0001C0A0553A8DDC100FBA3C6ECF305E9DE25
-:1018F000EDA8D70D99C8ABF465AF4C7860C9274BFC
-:101900005E75D295796F8E6232F2BF3AFD698B4671
-:10191000E7907ED761B7BAA7F23B45A75B81A349A1
-:101920002DBFD8F083864CF712461CF20549DED64F
-:101930009976E6A813013915BF4FF8CCCF76D018A9
-:10194000B453E552718FDA8882AFE5D7B2F89CC5FF
-:10195000D7AC7B7BAAC3B785FCCFF04212BFFF1286
-:101960003FEF41436DD67BD6838612DF33EFE94DDF
-:1019700091CFEE3A4776419B8817B8E46CFBE3645D
-:10198000F7AC7AB607DF53BB907D50A39E4EA89F5D
-:101990005A698D4D9CA30CABD08693BD497A2BD947
-:1019A000A1965D1A5FBFAC74D2D8A15934AFF16D66
-:1019B00006E1B76A3B2F7ED7ACFEF4BC76A1357E3C
-:1019C000CD8E11EAC228BFD5EAA19219C7F2F5DE81
-:1019D000A19E10991B23C7BEED7A1FD26119E11792
-:1019E000D98624A7BE4F3B80EBB80E5A595FB9DEAB
-:1019F000FC1D8B1B001CD1F7646F0483F9C39F741B
-:101A00005F0DE1CD6288CCA77C8D14A97A1141F8D5
-:101A1000C9C4716AAED6555E5FAC7C4E36EFC1C6A6
-:101A2000C3FD4E136F2DFEDFEDFEC4F1FFF65295A0
-:101A3000EF41B73F3BCE46E738EDBF97F9FD54ACD9
-:101A4000C87C25384CDC3B1D3ECF7C8704F9CA009E
-:101A5000BD2B5F393D7ECE64F61FD1C106C59F2ADE
-:101A60007AE1F551F7CD82E6EFBA6CC194E22553E5
-:101A7000E78595E8F3B39F9AF32FBF7632903D74D4
-:101A8000952AECCEAB5C90798678E1D9D345B390BA
-:101A9000415C45FAEC707E87FD618273C73B20C4D0
-:101AA0008F2EC17D7B5F9CF3C14D12FB4B9B9B44F2
-:101AB000BE78711AAFEBABEE23F6DCA304D7BFB848
-:101AC000491946F43D343D924774593CE6ED74099A
-:101AD000E75562DEC7C269D743D4EF5BBD6BAEE3A7
-:101AE000F3A1C6369ADFD0F4B6F5F7917EF9AC0DC6
-:101AF000C86F7864CCED4B204A2E7B4A27FD8AEADA
-:101B00006D97CC77EA7688DF33C016D9D1FEAD3F2A
-:101B1000E915CF53BD56D3CF00AB9EE77BFC3354C2
-:101B2000B1073039CBFC3DC948FF44BF2F649D67E6
-:101B30000D25580AFF23BF2BB6DDF44FBE39F483C1
-:101B400039E45F84D6481ECDE34892B847ED29F5C5
-:101B5000FD8EF8CC50F2F3D23A7E26FC0347D2FC3D
-:101B60007C8FE46DE4CF747EFC975A17A7EFA27DBB
-:101B700044E9FFA07D44E9FB681F51FA21DA47944C
-:101B80002E3E839DE2FECDD08DB799BF76B38EEE0B
-:101B9000F94BC0D4EF13FF4ED35B26FC4B9A0EDDFE
-:101BA000D983F0A059E6F8E8E26715D64F4FB68C16
-:101BB0008AF95D52A4D7C3B4BE92E63FFE84EE59C3
-:101BC000973429AAA4D1BDECD3D91C7F18373F8202
-:101BD000039D37447638C4EF2999F3DD9ED6B69E2F
-:101BE000DA6F7F368F6648E738020F773813FEDEEC
-:101BF000B0156FF7C450A17F7DCF19298B3E7F8C24
-:101C00008F4F633FF018C2E7823FD03881BD320C5E
-:101C100060BC8CF56FF4D3C53D042B2DDEE1E038BC
-:101C2000E5ED3BF65F7D25F6F77F00222F54BD00E2
-:101C3000800000001F8B080000000000000BCD7D1D
-:101C40000B7854D5B5F09A39F34A32934CC2000957
-:101C5000123809AF00018664121212E024048A8A45
-:101C60007482D482A28EB462541E23D29ADED23FF2
-:101C700027244012830605CA558401C1C7FDFCAE66
-:101C8000D102175BF44E50A9F6B73422E2A354C731
-:101C900047552C4A8A62EBAD2DFF5A6B9F939933BF
-:101CA0004C0222FC97F0E9CE3E7B9FFD58EFC73EE9
-:101CB0003BB3265E5E24C900A7E9670A80CBDB1729
-:101CC000A008604CE9D70FDCEFC1F2599BDB0400A0
-:101CD000F360DB3437F6BBCED1F1A21BEBD7BBDF11
-:101CE0009B968EF51B334D07A8BC49CE999E812546
-:101CF0004088DFFF515EC5810CACCDF456DB024E4F
-:101D0000800A9000F2807F4EE37F531D29008E6889
-:101D10007D9ABB8FA1FEBDCCCB0CFD2F978718DA27
-:101D2000AFCC1B6D68D7E79DE92D34F41B97D19597
-:101D30001B74D23EBEBAA71CF70326080FA37DED85
-:101D4000FEF2EDDBB19C35719E8FF67F0CDAAE1999
-:101D50008D1BFDA4A479E3FDF4B245B165F503B88C
-:101D6000857EC7F6E3103E5286ED926BF9813BF11A
-:101D7000BDDB322590BC00359BADEF4762D6B10488
-:101D8000FC6961EC77DB0EE37380882DEC03B83DD2
-:101D9000E00CB62000173D81ED0E433B8FBB78AFC2
-:101DA000CD4DED4BC0126DCF01A83D9AF3E40B3140
-:101DB000E38DCBE8BCEF7E1C6FDC9E39EE065CDF6A
-:101DC00093A55F0F90719FE55E97E723040D4C800C
-:101DD00009A711E42039CD80FD4EBD2485245CD7B0
-:101DE00034E99BD4483E3EAF423C67E17B26F90F85
-:101DF00065D8AEBE2CC14E1CE76F75F2932F5869A3
-:101E00007CB8D19F1FA50B80950C5FBD7CAB0E7F6E
-:101E10001D01F0C73A07977FAA7373F96E5D269785
-:101E2000EFD5C95C7E5097C7E5AC431068C7F1FE9B
-:101E3000FCF7F1007D681C15A06FB41C67F39A07CE
-:101E4000E03ABA7E2F85B6E37EBF289F9006B4CED7
-:101E50006F70FE620D0F4802D5448CA5F8DF8FB776
-:101E6000BD98E5E3E7AA0BA75AF27709141C77B9E6
-:101E7000D724C65DD4F1629627DA0ECBDF33F48720
-:101E800015A603867A638EB1DE5A7120F67D1D0E8B
-:101E9000F1E52D9BEFB0055C58AE372921E799EDB0
-:101EA000FA7AA6ED4F524C389E659F3D64C7FD2DD2
-:101EB000712BA0607F0B80D29E7FE67B00F50CE744
-:101EC000791204DB138C5B47E312BDEF4F02E93C50
-:101ED000C67D0B6983D6A3FE973DB413DF7B2B4DE4
-:101EE000017FCC3C2DDAF89FA5B7FDE22BECF7D9AA
-:101EF00033404FB00E73693D63777D6C3663392E86
-:101F000059D0C95877C49C81E5899A7F6C3CE261BD
-:101F100032F59B26637B6ED71107A2FCBEF6AB366B
-:101F200039106F6F9BCD00034020BE04FBE31854B3
-:101F30007FD07BD5DC46FCFDCAFD4961F379ECE737
-:101F400041E445A6A34AC1EF3710DD88791440511A
-:101F5000B37415E8F32A241F68FF547FADDDFFE654
-:101F60007AA233E8DA48F2E13840B885D7AFA4C6A0
-:101F7000F2FFD2677FC2FCB9280BF99E04E066C16C
-:101F8000BF0EFC773A97F83534DD89EBBD358CFC14
-:101F90000F179FFF9FF13AA37C3E22219F1FBA1289
-:101FA000EB4B9F91BC766C3EB96F98E0278DEF7537
-:101FB0003ED7E1B87493C47CA9D73FDF27CD08256D
-:101FC00080F7368D2E86285DB369BE65CF5AA00591
-:101FD000D7B76CD288FEB1E3C7BFB7B44902396640
-:101FE000FC279FB3D710BFC8D0D5AF1AF967DCB3B1
-:101FF000A7322AF24559CFF868D3E44DD720FF180D
-:1020000094D726FF9F7E8EF301E27127C2A7327319
-:102010006E36CD3FDB094ACB7806CB1C07CA89ABAD
-:102020000588E0EA92EBB201E1B919D12521DDCDB5
-:1020300051AA5FBF0EF1F80373E02A92F3C7BC43C5
-:1020400078FC6B5CCBAD606672CD36E17873E7D817
-:102050000B693FB31A045DBF9EDE759C9EBF3E298F
-:10206000C5D480EFBD6E8246C888EEE375AB3F9B5A
-:10207000E80D37EEFE08F163524649A7537A9617EA
-:1020800044C91FE97894A2F26F9AE454699E936E52
-:1020900033D3BD25ABD546EBBA154207149C7789DF
-:1020A000376C23F9773BB82D5462D1D54D1F447F4F
-:1020B000E5FFE8388DEF2FE9944226ECDF5ED70E7E
-:1020C00016C4EFD3757BB91CFCCDE0C6CB101ECB7C
-:1020D000C7DBBC2DA4B734FA32AB26389D405F9DD8
-:1020E000499F96683BAEBBC2E10C4BA9F4D87A3C41
-:1020F000761D8DD94ACA78DC8FBAA63C9DE99368D3
-:102100006170749FE36C004E92F33B5358CE1F7B7B
-:10211000AED84C783AF63B6BC844F52D23DEB8D3E5
-:10212000C7752079732CC36BB6517B466E48C5F6D4
-:102130005BCCA0925C86ED426E3D3FE9AE77488E67
-:102140002DDFE932D94D828E653401A447D7BEF325
-:10215000EF38CEADC8AC766F546F2C9AF2E8C62734
-:10216000900E1699DBEE29C767A7203CD68DF0FCB0
-:102170008BA97D38E9ED8F1FB287CDF4DEC323B77D
-:102180004B38FECBA98191B41FC854FAE7E0F39A0B
-:10219000437DA105DF9FFAE83F0F92DEBCF5C9BE83
-:1021A000CC5F3ADD4F233EC4F59C403EA4F59CDC59
-:1021B0003784F92E8A7F0187C5280FC8246ADEB1CB
-:1021C000CE4FF80C24CBFCDC02AA7219E17BEF4D58
-:1021D00040765381645288CEBB9A115EA633E9499A
-:1021E000196FE6F7169951BF121D06E44282C7091E
-:1021F000935CA0F105D07ADE7F6EE4F6167C7FAEAC
-:10220000D63F4A774797FC86E86EB3DD6BC7251C3F
-:102210004F32EA7DBD9C393E9DF9E516C79760298E
-:102220008C3E5F52FBB5B19E0F0AC98D8206B9F094
-:102230000E2CEFD4E07EC548FFF7C7E3FBB7B5AF80
-:10224000DBF38A4CF36EFEE9DB34EF4B4E9E175EF8
-:1022500011F03B6112FAA55BBF3AFECAE3A3E4E1C9
-:10226000F5EACF3F7EE88DB1011CFFE3DDA38703D4
-:10227000D2DD02A9F3A307115F9FBB3ADFF93996BC
-:102280004FBF74A81FC12F7EBD8B6ABF004B8C1C33
-:102290003A6E32F17E17D13EF0F96F0AFD3733BE48
-:1022A0002DA827106E0B5AC66C2779304DCA4F23C4
-:1022B000BBE9C431E3FAE2D7A98FAFAF4F1F5FEF9D
-:1022C000B78CE08F709838CE2DF4ABADF373C2EFBE
-:1022D000677B469B9015A3CF333AC7A6E747F1E447
-:1022E00057EAADD4EF1A12F5888AB90E81D7B935FD
-:1022F000A650430EF7E3F6EBF039E1BDC2D3C0F5CB
-:10230000394ED467D87F51E66F785D24E81CA8D792
-:102310007E00FA4FF5AA5F61BF3797A5B25C987B44
-:102320004B9B95ECDC6E79A6BE6D3E3DFADBCB3364
-:10233000849EECEE07CCC3A43F013767C1FA24ADFD
-:102340006E2AF963C3AF483EDF99EA95D064841AD8
-:1023500019C2C4D7272144F05E6D0AB2BDE7203D03
-:1023600080658BC99B69C1523277F5019E27C47085
-:102370009A06010BD57F6B8A3400BEB7CA539949C0
-:10238000F4FF2638FD6417FD207DF51892A395EE25
-:102390009973E9F96C35D5DD82FB6DB4CA77E793A3
-:1023A000FDF303C94B76AF0E175D7FCCB578AD0456
-:1023B000DF7E41D9AB22FD16BEA2384C0C7F874A86
-:1023C000E3BE6109F6A575BDE55C3FC664263B2DFD
-:1023D000E41A839B7DFBD07F14FD1EDFFF2328932F
-:1023E000C81E98F35B07CBF19B40667EFF11282C3B
-:1023F000C76F8600D76F8188F54B7CEFDDD2FFD9A0
-:10240000B91FA2FB7A77E257BBC9AE9F2BB5F7CDB8
-:10241000C176B512F248CFFCDAF17FB646701D4A9C
-:10242000830592D0BEFA35D129D9EF475DA19DD859
-:10243000EFAEE42DA91D588F9884FDA556069FA4E4
-:10244000FEAA19FC0D58F64D0E3C4F7CF8CB14310A
-:102450004EADC5E126F94806168DF3D13B2EA67781
-:10246000D2BB3761BD0CB145F03AD157D09BFA577A
-:1024700060B97BC2EAED5468DC53B27727BD3AD528
-:10248000CCEFC36999D75116A75F7CA3CDFC3EFC66
-:1024900043E6F72775590CFAC537CE1C7C1AF73777
-:1024A000E5EF965EF5CECD05827F7C7DCCC144F60E
-:1024B000E0FF68FC851092683D0D7B4DA116264219
-:1024C000611F94E9F40891D5446FE50041A27BD8DF
-:1024D0008B7A4C9F2797F7FFB9EA233AC476B60761
-:1024E000DB9F2739690F0A3EC1FA54DA8F23085E51
-:1024F000B2D750218305EB49F8A290BB6E203BB6C2
-:10250000A502DAA93E092212E17B0A417A08F9C341
-:1025100032D3ED5450B8AED3F1F740E5F272087102
-:1025200079258485BE07B9F1299CFFAA4F40EC6745
-:102530005498E91D1D19F747686FC0E5B798C9EEB3
-:10254000F0FD30B1BF30A840870B22C473EE709904
-:102550000E814C31BF80879D9EFBA2F070C4C123C9
-:1025600089E0E18DC203E710F03803BE023E931408
-:10257000840FCAA7C9D025D13C8A66DF548297CB85
-:102580002AF073D90B5C5EA8F79C09979248C01299
-:10259000C84F009FA989E96684069F3F1600CB2F8C
-:1025A0005DFE5C5B20F3735D0E217F66923D1A2F0A
-:1025B0009FF4E7BE94CA2F64A487AA82AC7916D48C
-:1025C00067BEC2CA3B8760FDEAA7F344BDACF257C1
-:1025D000B958FF41C128511F5759684578D59B46C6
-:1025E000CFABC2FA90806923F1E5F27AB4AB715FA8
-:1025F00081A47B8244C7A60C709BB03D505FE42D44
-:10260000C07A00E912106E7629A79EE06CFF397837
-:102610001B7015196981C905B8DEFCF99DAB053E33
-:102620002BFBCFC5FEC73BAD6CB7ACB10583842790
-:102630006477777D69747FC79FFE790D3D7F7A004F
-:10264000B849BF80472EF4BBCE5C8FD9015C5F8C4C
-:102650007283E21F38DF4C9A2F80EA49A6753D2528
-:102660008508FECBEBA7B13F7024CFFFFD82BE31C2
-:10267000E3E33EA4F134AFD073E0C92924B8958CCC
-:10268000F45F4BFD4EB850BEA651BBC0434F6563CF
-:10269000813297E68D7F6E4EF9E6862538CF52A4BB
-:1026A0001192D38B0B0237D2B84BCD914185F86C88
-:1026B00065CA3B36A60B05E993E403F12BEDB7069B
-:1026C000E991E87ABFE057E40077B7FD8AF8F5F8BA
-:1026D000BB6E58E813224EC2FF15CF0D3E8F6635F4
-:1026E0008D7F3BAD63A9D4B590E8F2F3F4D76C7F4E
-:1026F00066BE1C28E84E935B4B9FFB9AF9E7593363
-:102700000425CD3F8618BE5BFA5C9285FCC3A59F6D
-:10271000422805DF2FDBF77803F93BA5E8FF939FFD
-:10272000BC78D753CC6FFB485F22E896FEF7B3CF57
-:102730003F487C7A6512C7A126BD767408D94153FB
-:102740008E461A106D70E2D9372E13F4AFFB257F39
-:10275000339D8F1E9F26ADB887F0BD0CF16FC7F972
-:10276000969982A26E75B855967BC24FAED1F6F19E
-:1027700019746E9CCF72453D504AFBC99480E56345
-:1027800048F81332FE23FEBFFD686835AD13A46F11
-:102790006C246F4EA15F4CFBBAFDB178BFA3EB4038
-:1027A00029F9DDE417E33E17B71BDB97C6EA870478
-:1027B0007EF296022D1E960DD9B4AF5FA33FF4C1F1
-:1027C000309A777E1AD9871329AE90405EEAFE715F
-:1027D00028B9F29102B697DB25E287324BE2FE0B75
-:1027E000F3855FACDBFFCB1E92D88F5BF6509F5119
-:1027F000EC276BFC0A612FF3EF93A45788CE022FCE
-:1028000003D1C12DDA9E60731FA6B95B9B4CECC748
-:10281000D8A53BBCA4F7C73DD2FFB67F63BA4975C4
-:102820004326D527CC7DCCC3F655908435FA556C1C
-:10283000673E99DE954BF33F992E838AF3352475D5
-:10284000E5929C559F757849EFC6AFFBED02E10F0D
-:102850000C098FDF14F1083C139FE7BC54BA89F0D0
-:102860007C12F99CF0B7CC35BC3F38C96E989C19E6
-:10287000C1B241B3D3731E1B95361BE1E2A3F5C66B
-:10288000D8D51DAF5E9342F6F26E8B3FC58DFD4EDF
-:102890001ECE35F841F16551189153D84BFB1B33CF
-:1028A000870412C05D2F7D9B2C0C2F9D6E7F5DA732
-:1028B000C00756C247B9D8876A77DB7D447FA1A994
-:1028C000E44F2EBB19DC2DD87BD9CB0F3738A8DECF
-:1028D0000C4CCD27E97FD4FF137388ECF15FA68CF5
-:1028E000BDB71CEBBB8E59849FA22A87F263EC58BC
-:1028F0007BA6196403BD764A8B491E13DD23BD26D2
-:10290000C9C920C7D0634A5E86A1EEF20E30BC9FD3
-:1029100056926B684F574619DA8BA13612C0F514E0
-:10292000654AEE10AEB8CF8C0243BB1DE93A4CEBC2
-:10293000FC52D85125F84FE8DB20DB4365118007B6
-:10294000900E261E37DA59259136F637930E5B0C1A
-:102950007100FB59E250C9851A7F0D8481C45F481C
-:10296000FF5E9263270F8BB893ACC17359B6D0CF7B
-:10297000CB5E96D80E5C76CCCC7AE22478BBF14361
-:10298000F251E7BB78B8F7F51BE1DC7FAE11AE5929
-:1029900001235C2FAB31C2353B6884EBE05A235CEA
-:1029A0007354231C87344D34F41FD65669A88FD82E
-:1029B0007485A1FFC8D06C437DF463D71AFA8F6980
-:1029C0005F60681FB7F736437B3C5D8D0F2F33B4D4
-:1029D000DB538F305D1D40BA32A13E287CE9DFE237
-:1029E000E8C2C2702F1AE8F48662F0AFE23FC27FFD
-:1029F00099969798006A03F1E385C2FF1584FF94C6
-:102A000028FE75B9DA139FEAF81D42FA9AE565794E
-:102A100084F07EB22485E9E5E04B270F2B40F84F88
-:102A20008502DCEFAC29228E22C9C126A2934E700A
-:102A3000B591FDB9C61264FF4545B3702729E53845
-:102A40007FF3FB25E86FC6ACB35A49024BCC7EC777
-:102A500087DB0DF5C297F61AFA1775860DF5F18723
-:102A600041227D55F0A6F7792A8B3E5438FC55FC5F
-:102A700049F0792A4BBF0CDE45FA37DECFBD5AAD9F
-:102A800097D2C8AFFF7BFBF368D6A07F364825BF3F
-:102A9000377247AAD73400E191FC4E03F9DF807604
-:102AA000B4159511B80FB23E98EF10EFFF2D69F2F3
-:102AB0002AEA6F42FF9CF08E70C9237BAF1692BD4D
-:102AC0000417B25BC80F832B843DBFDAA4B23D9AD2
-:102AD00084F628D9230D157EB697A74370203DBFF5
-:102AE000069455C4779219ED577CFE3F23028D85DD
-:102AF0004562B1443F777D21B3FF3D85FC6906A661
-:102B000002A4F74ED0EFB43E78691EC5E34F902E75
-:102B1000C3F5B7B5BC304F253BC303EE08AE3B2031
-:102B200040069B0B03F7D0B8EF9BDCAB0BF1DD83CA
-:102B300013FF3288EC917585C2EEB34B0829A4814E
-:102B4000FEF315A0E78DD9CA7D8545D1384B4FF4EA
-:102B5000A3C733F5F8E6AEBA309716B75722BA8B4B
-:102B60008F3B46CCEEAAF1A4FF9699D8EFFC0B2D33
-:102B7000AE94E7496539EF804E7B3A2F99FDFFEB24
-:102B800035BC991D9DAB7E8EEFDD1014F6D60293F9
-:102B900097FDF5DB338F731CC52E99C047FE505A45
-:102BA000FE76117FD1E3259749DFC6CE3ADB7E6FF3
-:102BB000CF3C668857C1137D12C6D7A3E3ABACFFE9
-:102BC00062F6B9659347E835F2F3DF6FCEAE84D491
-:102BD00044F37CCEF1ABEB83AF1AF8E2C6DAB70C64
-:102BE0007C7093FA9EA13DE2E9B252BC32B2276BEF
-:102BF0003AC5D73FDB6D2F263C20FE0F16C6C4EB2F
-:102C000022CDA3AB60ECB9ECF72FBC8EA3759D8CE5
-:102C1000577DBFEFD4BDC9F5485D84CBF8FDEAF11F
-:102C200011BD4471D844F6CC5D12CA0BF277495EEF
-:102C30007862E405401ED9FF7749A3BC44EFB6FD96
-:102C4000C147A9BDABDEEEDEEEE3F808C74D6A91E1
-:102C50002EC86E00A7787F81CDC176E81D3EE12F9A
-:102C60001EADF8EA06B25F7320D58B32107FC27FAB
-:102C7000A2B8C97C531AEBFFD55907B8FE61338857
-:102C8000BC514DF821F25797A6A60ABB58C1FE5871
-:102C90003F9161E6FAA11181AF981FF3C39CDF5801
-:102CA000DA5FC4F3C01319447CF833D9FFB5E05799
-:102CB0007780DA6B32D0DF46FAFDC4AC8E35116B0B
-:102CC000ED1A70AD05F1FE49B2FA395934637CFD55
-:102CD000AE253FF3139BE0DF49BB4ECF53113E1FA0
-:102CE0009A24F6CFD5674C1CAF0167C4568D7ED8A9
-:102CF000038303561F8EDF66457BD2299ECF1E13AA
-:102D00008DCB9EB0624971D024513A7DC2EE75F9E7
-:102D1000449E532F4710CCB09CE4D3E57CEB708AE3
-:102D2000BF9DDC6C07925B38BF42FE96FAAC88E32D
-:102D3000F7CBF02F028117F71A5CAF6788FC05F11B
-:102D40009F4742BF16F721FB720CF167726053B1C7
-:102D5000FDFD3DF66D84BFEEF51E16F1B0CF9A472E
-:102D600073BC5BA713D9A7C5BD7F0C20DA2FDB4648
-:102D7000ED8B5F7EFF1D8ACFFDA63030D487ED0B33
-:102D8000CC7231C9C9C5A91D1CA72BF6C93C2FAEF1
-:102D900097F78B72AB117D7158EC88705CEF6CF11A
-:102DA000FB9EF6FFD9CD9D1BF3395E2D8F25B9A271
-:102DB000CF8BEB28A675E8FBD4D7111DA777FED1E2
-:102DC000E3D07AFDE387D60CD7F20837FA13E8E5AB
-:102DD000AB743AB6268EFBD768F88CC74FC18860B3
-:102DE00088E3796E703760FD5A0D4E9FCDC3FD703C
-:102DF0003C44194FF85D3CDBE92538EBE3F7CB8029
-:102E0000C053BDCC73C548FF1CA2BFDB82224FA0BC
-:102E1000B723FD893867730AD3EBE2E7DE7AE7E789
-:102E200038CBAD8F8E2924FDA1BF1F0F6784EF70B3
-:102E30005ACF0249E4CF10BE37D1F8F1F981F385BA
-:102E4000EB89EC4ED60B27B6FD2C44EB3B91056E7F
-:102E500013F2E3E27DBF7DD33496E8C41996B084C3
-:102E60005DC6F857BC9E7243E03A92237694236481
-:102E7000DFD8F5F7065A0CEF55672A77F9D81F55B2
-:102E8000EE2679645785BF362450C1F5E556E1AF8B
-:102E9000EDEA34CBC4DFBB2C10223DBEFCD50C9533
-:102EA000ECC7E56877B0A79317E4F54232FA41E939
-:102EB00009EC069357E6785C5A600DC14BFAD1D401
-:102EC000079FC889FAA3BABE2CD2F4BD927F6303D0
-:102ED0008DEFD3E281686772BCB314029A1DA1C55D
-:102EE000E19A0F701C4297DB3698EBA0F8CF9ABEA0
-:102EF0000B1CE41FCA382CC7D73CB3D3A0173B72B6
-:102F0000551D4ADA11D1BAB5073F5E3F1FC06BECC1
-:102F100047DB0512D6D07AD5814823FEDA3AEB7723
-:102F20005D2F60D932E691C84A6AFBE6B44476A4C4
-:102F300043B303B8E847EB14EFD906AEBEC384FA37
-:102F400033D96B81F763F4A00339FFFD3C6D5EB2AA
-:102F50000732BBDBFF4078EB691F17AB24F8BC6F6F
-:102F6000EDA5DDE6AD49240F12C28BC8C433FD18B0
-:102F7000D16332C4EC9BED9E98BA14072F89CAEE38
-:102F800076E57482FCE577DDD7AABAF0AB1F1AECC0
-:102F90008110AFDF6AF18317E9C9E6C176C3390C46
-:102FA00055CB7F220117C7ECEF1CF64576B955DBF0
-:102FB00097F522EF8BC6F5F7BBA4D7A75EE2EB0B24
-:102FC0005FE2F885EA4B1B7E4AF5A50D3FF5125FDF
-:102FD0005FF812C72FCCBEB4D7A7CCBEB4F1AB5E9E
-:102FE000E2EB0B5FE2F885AB2F6DF829575FDAF063
-:102FF000532FF1F5852F6DFCAA6C073ACB81CFCD0D
-:10300000A6379A4374CE46AA0A73DE3857058E4710
-:10301000A73603E72BB67B851FA5C7E947D2103239
-:10302000FA2D567716D9D1DB1BEFABFC318E732A04
-:1030300013174FF9FCEC230A8DB36D1A70FEC2D939
-:10304000F8D1518A7FE540D81BCEA1B89A04E11887
-:10305000BBF4FA600A8463FC896AA58FA15ED43947
-:10306000C0D0FF964D430CED37B78D36B4FFA8A9FD
-:10307000D050BF492D33F4B7434E4B1EE55D1B2D99
-:103080005ECA8359686FA567C20D76D8F83D05FF03
-:10309000911F9383167DF7B8B88F74D56618D7192A
-:1030A000D77EB67C407C3E614EB1964FE8FE7E41B5
-:1030B000BC0F6E4FC2B8A79E4FD0F139DC92C4F856
-:1030C0005AA78A7CD39A69C28F9C1A729B286FA9CF
-:1030D000E36FB44672FABEB7D519FDC9F446772539
-:1030E000FBA34DC0F9DCDC2A7348C9A138C1C04A32
-:1030F00007E239B443D04708047D841A81F385A1DF
-:10310000AADC95D47E2A047C0A46A78FD1550B678A
-:1031100052DCB53EBB5F16C51972AA043D2CDD6BAF
-:10312000A4034AE7D256D30F4BBCFEF4FA8C02CA72
-:10313000E79D819727049CF5F3E7E97170CFDB6188
-:10314000C44B3CDEBE2D5ED614C77F57F2EDF06255
-:103150009B2177A4519C540599E2322F660F373397
-:103160001C9ABC8C9F19D88DF830A70938DF134FF3
-:103170008FAD7510AE8AE1DF1C6F5821FC4C93F2C5
-:103180002B99CFF0DDFEC0A744195FDB9A44FE16F1
-:10319000CB641A1FF6CA0328AE105267F3BAB737CA
-:1031A000DB92E93CDF57F566A0F3F2DB73E40194B0
-:1031B00017DBFE8C696EECF920A40ABB3993F7612A
-:1031C0003797706911A5A2956011ED6189EA835660
-:1031D00098E3F0A94AD49E3E2339EEB962A2FE5B81
-:1031E0008A73193E694A86015FD61223BF23180FDE
-:1031F000E5A37C1C4CBFCB4457824E42AF4BA195FC
-:103200001C5FE932D510DD68E72DD257CD06CA47DD
-:10321000D567FF742ECBAF7A1BC31D5608BAD0F307
-:1032200082D6264187F1F4E3F21AE9C72A0D3489E0
-:10323000FC96E01F7D1DDB146DDE2C0954967BB6D9
-:1032400001C467D6B8F1EC243C49DE78045F3A61EA
-:1032500036D07BCE123BE7B1413ACAF8B74E00E810
-:1032600013734E217EBD675DE777A4F30FBF239DE7
-:10327000EBF267AD57933F45E25CE429A46B8A1FEC
-:103280004DADEA04FEFE0ADC26A247A4835959C5C7
-:103290007CF4817F76911CB213BCAAD3A8DDD5A99A
-:1032A0004C25FA9D2EBDA2B8709CB587059DA37EC6
-:1032B0007989EAADCD16A0732628674C3FA2794BD9
-:1032C000EDEE952479A481E369DD853E943B1447B6
-:1032D0007CC5282F8A3A8D70CB8D97EB3DC0B127E6
-:1032E0003D110F47D7040D8EC508C721DF1E8E364E
-:1032F000AFD0C3E92542CEBE98FD537ED57D589C04
-:10330000AB495780E1FA852AF4F274E97898E4CB66
-:103310003A05E50BB6CFD0DADD25429EE870CED572
-:10332000E0ACCB9375F32183F8DE4DF2C44970FD18
-:1033300088F5765B9180334084F39FA98AE09335CA
-:1033400056F0529CB6ADD4E9A57861AEA2C1B7499A
-:103350008397094C04DF78BA9421A68EEB4B8DAB92
-:103360007F5BF8964ED0F4643F283E1FF8AE4B4981
-:1033700015FC3654C0C7EA8CF0B9E6A61C8B77253D
-:10338000F275470EC21BDB9B5E17F0FEA5D67FD5FC
-:1033900018E07A53DFD5990CAF9C859944CF4DD670
-:1033A0003695F2584D3AFD69E7C25C9A9C9886FCC6
-:1033B000BD00DF5F8DF289F290A92501078DD794BA
-:1033C0006F0189F7BFD99B68FF0E9FCD20072FABF8
-:1033D00031C235250E8E49DF91FF7F3CE1BBF1FF05
-:1033E00076FA15FBAD1906D0C979C89083E0642B35
-:1033F00099984C74D4D2BA9DEB32849A7271FF0FB3
-:103400003B85FDD5D23ABBD7F351214D2E6CA97324
-:1034100070795F9D9BCBB6BA4C2EEFA993D97E698C
-:10342000ADCBE3B2A5CECB65535D0997ABEA14EE05
-:1034300027ADCDA860395C051CCF5E99F239E7DF76
-:10344000E3E7CB518D7A6C706DB201EE7D6618F5B5
-:1034500055BA62D457748E29B6DDE51D65684FC92B
-:103460002B30D493E48986FE5326047E3981E48090
-:10347000A7324E0F223F8E899EB36B6915DF4BE951
-:10348000F0D3F59353E3F33556EF00CA3B395B05B0
-:103490009F366B765E13C111CB6405F8DC8CEDB002
-:1034A000E40D01F1FF6AA6F38771EEFE488B1DD98A
-:1034B000D7286427B4C8C28EB78238F76BCBF4879D
-:1034C0006BF07912EA2FCAEBDAE6A6B05C78D8E3A3
-:1034D000F4D239DB96D6656E5E8F579CA771E3BF39
-:1034E000447980F8F3358EA1C67339D6B39C6FFC4E
-:1034F000754FF4DA9491508E9C2167BBF32FEF6BDC
-:103500007429F22FF778043CED3DC8A3D6387BD957
-:10351000A9E55F60A02F61FFA83D25F20BAD717199
-:103520007BF4C312E66FDE9A2071FF3F4F9085BF98
-:10353000660903C96B9717DF8FF53B14F17DE8B976
-:10354000CE8F3F3E4F8C7C0A2407FE3C019F2B4FC1
-:10355000083B254916DFA1D84051583E81C887D085
-:10356000591FD237A95ABEA75BCE908888A13BE7E6
-:1035700019FEAEC88BD06716443F96E8FB17C4BF50
-:10358000FDB66523F9C3C37A69A7FC5002B9E02AE6
-:10359000D1BF1F832E4F3180EEBA23FC5C2589E119
-:1035A000172678359AD6CDC8C5E7A95E8B173100A6
-:1035B0001525F25E3A5FB14A4965FDBEAA446E2701
-:1035C000FEF942717A091FADF955ACAC93867DC8FE
-:1035D000A2B7B1C4C676BA8E87246D5E444F679594
-:1035E0000E67ECEFCC9B11ADE37FCD6336725EAF1F
-:1035F000E5AA4738DFD732EB3F38DFB73A6B7A1EA0
-:10360000C9BDA492E9C7F82097861F660DD2237919
-:10361000C6FCDEE9D3A2CE70A0F8849607048F31F1
-:10362000CF6791FD86F92F349E60A0D0436051F89A
-:103630007B8333E95BF0B5DEAF673E50F5EF4E5765
-:10364000D2F9E0268F90A34DE07D3340F55724AFAB
-:103650002AD3F38237E9BCE9EA8116C6CBEACCD992
-:103660004DC28E177E53936725E76DE3F5369DD7E0
-:103670008C95DB745E3356BE37C9B37BD5CB59010D
-:10368000739CDE37BE9F1D34EA1FFDBDA4CC2B5FAB
-:10369000AB8A392FD56CF13B485EACF2DC678AD53A
-:1036A000730F2881052531E793AC99B3F83D7BB6BC
-:1036B0002FE1BAAE50948544DFB8FF5EED81F59AF4
-:1036C0005CDCA8E997B3ED7393D6FF01ADFF66D23A
-:1036D000EB23A2F8193EF4F26496CFEB441C8379F5
-:1036E00020665EA524B082D615C5AB390A17A4D3CF
-:1036F000E1F957B0DDD1B06E7632E169E7FADED795
-:10370000A3E7D5F57E7A1E353EBF6EF3980DF0DF48
-:10371000A3C985175C0B2B1F40D0EC6C13F4D4B0FD
-:103720004EE891E14F887D9C4987C6F5EE6CEBDD54
-:103730000E8AEF4F91C56E3AE17A465C7D405CFFA0
-:10374000DCB8F65171ED0571F58971FD2BE3EA578F
-:10375000C4F59F1D57BF36AEFF82B8F6DBE2DA979D
-:10376000C5D5FFCD884FDFB56989E0188F3FBDDF34
-:10377000B9E2EF5D5FC57EA2A3E13083E945A7B75B
-:1037800073C543D4DEF5339DD94A46B17CDF81F65B
-:1037900015D9433BDB2ADDE27C4760E56E8D3E4870
-:1037A0003F58368879D0CE4AE6F89CD36390236799
-:1037B000C3B709328CEDB17668EE85C7F7D9E93326
-:1037C000A4D917BDAF5BE7E32913FC27490E414895
-:1037D000F899BA5DBB4D15FCB34D5D50B99EE46DD3
-:1037E0009359C49FB5FB50E86E1D11270F684A38E6
-:1037F000C2F18426CD4F68D3E4C95A4D9EDCADF9A1
-:10380000094943839B28EE9B7C988FE740B3AFE048
-:10381000AF0B103FF797166FA3EFC7EE1E53F2F8EA
-:10382000C35877FD5D827021DAE9635B14B259DA1F
-:10383000948C243A4F946272B4939FB8AAB0CD3F4F
-:1038400014FBADDD7FACFD79C4B39C69F3A2CE0758
-:10385000D9D265227A837C2F7F9786EB54C9C6B272
-:103860009677D5253A77BAF60AB7898CB0F419B2AB
-:1038700099CE11F79910E85B8AF018DC046605EB25
-:10388000196A98CFE25C532A0BFFEA196428DE6FAD
-:103890005716C1EBAB66DB7EAAF68C0F90B438DD11
-:1038A0007995FA38698234E887E38EB245ABAB8FFD
-:1038B0006CA6F3D04E49D4A73CF3F8FC95F9D1FAA5
-:1038C00098671E1FB812DB5B0B0799489EA67B52B8
-:1038D00013DE137375A9909FDB9B170E4EE48FE9DF
-:1038E000A53C13383021E76B25D1D4042C876AA579
-:1038F000AC3DCF14F52B35B8C9B55ABB4794177AF0
-:103900009EF8F1E794BA753B7B809F8D6CC877F683
-:1039100033D88B5797F6622FA279CCF1DAAD56796E
-:10392000009D23DCDA6C03BAFF616B3688EF905799
-:10393000D9F8DC2858DC03AE7145D71D5AD56F1E67
-:10394000D14DC80486386EA6065FFB4493768EF28E
-:103950009B307DC7B755CBF36C8588DB9D1F8BE70C
-:103960005FCD27BCEA78DE57FAAFCD449F1DD90B57
-:103970002B37E27BEB1ACD1C3759D798CB744EE32B
-:10398000907D746AC52133D9ADF9D06E263B7F1482
-:103990007D793D84AE400A70D9AEC9E7FFD4FCF80A
-:1039A00061A0F0F341D0C5C0F9B438F01382CB1058
-:1039B000126D12F18FDBE4C07996EC4BAF48A4B7DF
-:1039C000EB4AF5EF7AA1C652ACF91732C3B78EF8BD
-:1039D000281EBE74429FE38E8ABF9EDA9D7B5F0DD8
-:1039E0005F86D5DD6F18E993F0363B46CF6CD4E0A7
-:1039F000E7F6FA15C2E1B5C581167A7FC9A6BF1EE2
-:103A0000207354565533BDFF14E11D9F2F0C07A79B
-:103A1000D33063BCE14AEA3FBA76DB7E8AA7E5058C
-:103A2000EFA8EC8FEB1BAE54577A888694C0FD3418
-:103A3000CED0CE48850BEBCE4DAF86B3783D6379C3
-:103A4000BC5C7D3D480FD54C476E11C7D7F04BF895
-:103A5000A773CB0B370BF8607B16EFCFE2CE8A5DF6
-:103A6000FFB669FDF8BB8578BA68D5E0F758148EC3
-:103A70006035FA358F2582A34EA73A3C6E78A26B4B
-:103A800015E53AE7873A5F2439E8DFE49EC6F2B0ED
-:103A900038F024BDEF6BF337701E7057275D47D4A5
-:103AA0000D1FA7D249D7BB603FE569C2FBD615EF12
-:103AB0005772BC782F88B8589C3ED44BAB129F6786
-:103AC00010F7E58CDB6BB493915E958D9E587A353B
-:103AD00073BE33A4E9935013D22FCDB742D06F48B1
-:103AE0005DE64E44678F687A658746B7FAF3A13D75
-:103AF0009CBB3C54DAED27664A46781EEA8DEFD32C
-:103B0000C0CBFC807C7084FA65101F607DF00A37A2
-:103B1000D3A7CE074BF6FEF500DD67E3F4C905B188
-:103B2000F7D745343C227DBE43EF2FD9D475807C36
-:103B3000C5C12B047D7E4C77871545E90CFDC7F781
-:103B4000A89F4E3FF1FB78571B4F2EF67F4C785CB9
-:103B5000B829C8E321FF1C2BE5713AC349CC724A4E
-:103B600025ED676B1BB8693FF65F1474905C3855A0
-:103B70006B62B8DE981F5E65C6F2FAA160A5EB869F
-:103B8000AA33916C72298F6BCCFF0D6B33E20FE976
-:103B9000E76F344F91276013C1EBA08DE5690F7477
-:103BA00011D57BAA0EFF157172D73CB1177A3ED79B
-:103BB00071D7162B8E8945DF621DE7D84F8F379D51
-:103BC000193F1DC5FE434BD36CFD9CF00CBA8F67AB
-:103BD0003BC54F11AEAB9A7AB7572F58FCB4F9A436
-:103BE000889FAE008E03AD4C196B4A44379740FC5A
-:103BF00074CAC444F1D3C87B063B735593900B3A07
-:103C0000FC86578D4C16792948A57C891E1FD3F751
-:103C100075B7664F3669706B21B8313C05DCDA0840
-:103C20006E0C4F1D6E33843F425F8853BCD66316C3
-:103C300079B1910B3651BEE054A6C893D767DB44E7
-:103C40007B8EC82F9C411F9931F634F2C19A667160
-:103C50009F08BECF79B517B30F3886509E33D3CCAB
-:103C600071DAED9EFB6AB6733D99F9CF0A6A5B1E65
-:103C7000CE3BFCC3B9EA027A5E62E773F27A3EA7F2
-:103C8000A5AFC8E7B8F2B47C4EDC7C76B8A9B28D9B
-:103C9000E6CB137E4B8F74ECD3F2115A1E2823DF30
-:103CA00098AF70C4E52BE2F3956B9A17ECDF2EE228
-:103CB0002B2C9F87FF7824FB63F1F3B8671AFDB7BD
-:103CC0003523753FEA1147A2EF1852AB8CF4D8A206
-:103CD000E1BBA1AFC8479C6D7C284F36F8552D79C4
-:103CE000E71647D0FB911FEA4ED03FDE0F3D1FFF86
-:103CF000D6CDE31BEF074CE0DF6E99C8F11441DF2E
-:103D00006B9AC5FEBBE3699A5FA59F3FD2C7B16AB4
-:103D10007E1CD773A2724ACF870D75DB985E876AC7
-:103D2000F74535FC7B4A68650EE5D76675513E72EE
-:103D3000E80E89F3EE439D7ECE43746C98CEF9F184
-:103D4000BEC981A727C6C49F76B87E9AC9F9022D3D
-:103D5000DECFF7E6A0DE53D715762A64EF8E04BED9
-:103D60006727392E1F107F3F4E7C7D4E99D0C39917
-:103D7000D741C27B4F3E9F28DACFF4DFAF6038A136
-:103D8000BF9B2CE4ADA2D7FFBFE4A976B61DE2EF3E
-:103D90007D4EF94093B3FF0997A29C3D5112389E86
-:103DA00050CE5ABA58CE8627289F919E5C4E177DDA
-:103DB000101E6E4C7C3F8F5C76A9E2E16981877CA6
-:103DC0001D0FF75C92F942C4437659223CA05F452F
-:103DD000F06AF32983A85D29510653D98D8F1F26D8
-:103DE000E68B5965C2EEBB58F858A7E1E35EC207FF
-:103DF000C769642D4E93C7CF9B357CAC39031FEF49
-:103E00000B7C94E8F878EEBCF09151956168779757
-:103E10001BF191EACB35D49DF9467C240F2D308CD3
-:103E2000B7BC4C16F7240D9C68E877263E8CFEC084
-:103E30009DF45E2FF6E8C04067057D4B34606E7BD5
-:103E400007C9E64C7F5B0595FA3E37C7F9737AB927
-:103E50005CC35FE6D4C4F85DA0F15BC644E526030D
-:103E60003D7C2F317FD668FD979728B794C5F2F334
-:103E70009589FB2FD1FADF3641591CDB1F7FD64BCA
-:103E800031F6784FFB0E242BCBCB78FD224FB6A317
-:103E90003E95F3663B92E476CA57ABF54EC3BD75CB
-:103EA00083E937AC67FEE89B0E95CED9D13D4168DA
-:103EB000596DBBA35FEE1A6CDA96317C25C1B1A9AE
-:103EC0006C88B8BF7591FF6DCAEF28EA09ED1CD266
-:103ED0007CBEEFC814EE63A27BB2C09D714EF92385
-:103EE0009467E25EB7C120BE238620EB41C90FE98B
-:103EF000F4DDB205FC225F4EFDC5F785BCF9140860
-:103F000073DD0511AEA7697EDE0365393C6E3AC8E4
-:103F1000260124AF89E4A8CEA70E4F90E9DF53EB2A
-:103F200036AD245FCE0250467EA073207FCF0B9526
-:103F3000A0523ECB040EB6334DEB0F7CCD793AFD4B
-:103F4000FBC397FB88EF0FCF717FE7DAAF91EEE508
-:103F5000F344EFE56BD4EC01FD5E3EB532C8DF976C
-:103F6000AB2BEDEE06CF99DF973F3A31B08BF0FDEA
-:103F7000B7A4412191640E4E98EDBAA0E3872FF2C9
-:103F8000F8AF5CE4F1DFEC6DFCBBE9D752CAEBF9AA
-:103F90008F123F37B88AD9EED4CB78BC5DA12811F7
-:103FA000EA27395E1BF0619FA83DE73C6A627FA863
-:103FB000C124CE9FA9EF99D8EE827C41074E19F219
-:103FC00072C645C7717A838345DC49C45FEAFF74D2
-:103FD000D708B2BF7F99322B9286E31D7C55D87FDC
-:103FE00096A991CD74BF73FF349B773BF2DD3DDA28
-:103FF0007AEDA513EEBD137FBD798A90172E8BF74E
-:10400000F2023EB7343342F6A3ABD82253AEC01906
-:1040100097D76CB5B42553BCB275C77D15A3B0FB5B
-:1040200063752FB91B137CEFE9D4F29A23A5C472F0
-:10403000F09F939244DCCB67BC4FD85AAE9D2B497E
-:104040008554B2232DFF52D2129D07D04B7DFE2204
-:104050004FA48ABEBF8ED0256E88E7A292EAA464E0
-:104060000F9F8BE824F8567AC30EB27F1F5F10BCF7
-:1040700035F6FBD3D61270911DEF9B22CEC36E5046
-:104080002417DDAFF160C4C2F78E3FB8E8E9E6144B
-:10409000ACEF3D6A76133C5AFDEF3993B1FE388E92
-:1040A0004BF2EEE00E71CE529D0FA16108BF56F2A9
-:1040B0002AB1BE5B11E7B2D9212BD6AEEA43F8FF95
-:1040C00075725F016F0856D3BD9DEB5226F37D9646
-:1040D000D973443C78BA74B483DE7FB0C4CEF81B85
-:1040E000A29DD331A9D57C9F65DFF9C6733A0F2E07
-:1040F000EF5409BFEE52BB5BE5F3974ED7587CDF18
-:10410000F5A8192456715D3CF974C929D6E5157EC8
-:10411000EEE37258A5FB8EFBE27BF56EBE35D170E7
-:104120001E68F726E19FA68D777A91D271BD71E75F
-:1041300085F475B5E1BAE8DE63D7508E4764CC31BB
-:10414000AE2F2DCE6F70C6D5A79677DFE3339CF0E8
-:10415000FD85FFA785AF71AB574EE47FB6D64167AB
-:1041600055CCB904670F71C09AC982AE6D592F380A
-:10417000C84EF9C27FC4433878E59F073EBC97CA52
-:104180007FFD6ED75284CFEFBF7E73C793B4BFDA83
-:10419000BB0F11BDEAFE189FC1C4F5BC586D63B8D2
-:1041A000F96768E7397D1D2F587DDCCEF9A5B5FB91
-:1041B00093B87D64398492B07DA445C9BA99E8AEBC
-:1041C00053F2D6CB3488388FA8E37FED0D7E138C65
-:1041D000213CFA25BA0F639A76BE76C3229009FF76
-:1041E000B645ED7C5EDDB75C9C57F729D5497CDE92
-:1041F000748E99CF87D4575F73F930ACEFBA5CDC1B
-:104200004F3563B9328FE75704BDA475169B9713DA
-:104210005D6689FB9AF4F3A645D0C5DF7F8CF4B6C2
-:1042200077D848DECC4700D3FA5A357C69718322AF
-:104230005FA74AF6A4CB6BC463461CDEE2F1BA4228
-:10424000C7E34818497894A12D99F4E14300ED742F
-:10425000AFC086E54FCFA3F36C5FA8690CAF9EF8A3
-:10426000F91DB4579511740F8B83CB4EB457A9DC4D
-:1042700085F62A95AE60C575CB71DD7BDE38F8D248
-:104280000F71BA594AF5957444AB48CB7B81BA7427
-:104290005025AEFF06E25E51DF4289C4777D92A1D0
-:1042A000BED66389FE3D00FCD595A5FF7D80D35B1E
-:1042B00094A108964C8B968F11F559E487C4B4EFFE
-:1042C0009E69EC5FB63F66FC81B8DEC5366E0FEDC9
-:1042D0005BBA45B5C4B43F87F572805735FBF1FA38
-:1042E0009D66FFF604F2EDDD7261475AFE052AC9AC
-:1042F000B52FD14E23FF5E322B2CDF21D72227BAD8
-:10430000570F00E561AC5F2E1BE5EBE51A5F58FC2B
-:1043100015A0E5C7E01B3DFE803F7BFE388BEF63B9
-:104320005A35C4C2F70FA13EF0F696AFB3782C9F72
-:10433000C6DEDBF5AC2EBF87C1309AFF4B28FF43AA
-:1043400005F341CCBD0DC4F76DCF5FB614E7F11D89
-:104350004DE638AAE45A9FC2F731D535B13C7F40CB
-:1043600009FCB63CE67C4963FAC242922FFA3999BD
-:10437000E8BD47D798BFCDBDF71DD50780F4C297DC
-:10438000485AF65EE8B0B16EEF115AC7EABA762E17
-:104390009D6E85858DDD12E4B8CF154AE04FB43EA1
-:1043A0007B26B6C7F089D58DEF19FC0EE37D9CB254
-:1043B0003BE224B86F28F9C049F3B71E167CBDE173
-:1043C000F0EC24E2BB56EFA124E29B2FE8E2C7EF1A
-:1043D000C0273EE5559661BBDF48BD9EE8674F4369
-:1043E0001ADB150797DF7F2DF1CF8DBFF801C3BB17
-:1043F0009B6FE0E14195CE18BE818799AEBBF9462F
-:10440000ABF7CC377F67BEDADDCD37A2EECB074303
-:10441000FDE04C63FF6EBEA0F1912F1EAFB073BBE9
-:104420007DD2C35BD418BE3A49F558BEF909F24DA6
-:1044300002B93F7D9246DF17986F522E32DF0C9DF6
-:10444000A4C9CFEFCE3763275D14BED9633A1FBE30
-:10445000B9EC4CBEA99AD4F7DBF34DAB3BCCE7E902
-:104460005AE79813FE7D900F347939757EA0B28D8E
-:10447000EC1A45DCDF374D9A99E5F3109F497487B4
-:1044800034EA4FA1CF0F5EDFFD7D06EB67FDFEF541
-:10449000F58450B293160BBAE9AC1371DF6952F987
-:1044A000B4C5A477E93B024A3553F694EC02D4FB39
-:1044B00032D985D05EE1C179365499A04DA62D0739
-:1044C000AB87F1F861B6CF8668717FA7942FBE677E
-:1044D0009A29FEEE85FE5D4CB562BC5FB6FF59ECD5
-:1044E000265C770AF931EE12F17750164D8AD7BF64
-:1044F0006887E0FA3A07DA984E362857F71A273ACB
-:10450000E35CB52F98302FF9D6249376CFBEF233E3
-:10451000A2B3DD6F6C49A673127B24E0F339F383F9
-:104520004FCD23BE73A942DEB4AEF833A52361D7C5
-:10453000B41F1AF5347C6AD4D3F0A9514F6BF51E21
-:10454000E58D7AC2A8A7B57AB79ED6EADD7A5AABCE
-:1045500047E5CDA7063DBD61D2A70679F31ED5CFAD
-:10456000414F1F9E7471F4F4A88B2C6F9EBE70F2A5
-:1045700066DFA4BE1743DE1C392F79937DA6BC39B4
-:10458000743EF2C6B5B943A5F4CCC21EF8A056C31A
-:10459000FB5B65CADB343E949C5BBC269EBE3AAA9C
-:1045A00017AEA6BF2BF3A557F87F3DBDEFAAFDD5EB
-:1045B00091C6183FDC65E914DF23D4EEE1E7B76C60
-:1045C0007E95E3B1675D2F5D105A74A65E45BBC84A
-:1045D000C1F4EB35732EFC7CD7D13A47F0DB95CF95
-:1045E000DEC1FC945C6E9C4FB77F3BAA6D669EAFAC
-:1045F00044C8E99EECA19EE6FDA05C16F7FFC5CD80
-:104600001F4FBF489FE9938B981E2D742FF8179D5D
-:10461000C07FA7EABF4E6EFCBF8A7C49E9C51193F3
-:10462000CF834EA76BF84CB06FEFC5DDF705E3CF36
-:10463000E993CFC38E3E4CFBEE9B70DFDF67385EA5
-:10464000B47D5F30FFE1E6F3C1F7BBE5DDFBE6EFEC
-:104650005132B47D6FF8E735EF515C63C3BFAE7D77
-:104660008AE21AF77D9DB78DE21AFABD726910FDD4
-:1046700091F5EF8F102E2EBFF89E24634ECC774518
-:10468000C0FE7DF4BB13B2377CDDEDFF2BF7CA9182
-:104690007DD2DBBD72AD36635C4F2FAF2A17F64A71
-:1046A000AB691DC72336A05F558F78EB9823E211C5
-:1046B000AD68A7B0DC9953D0AB7DB4AB4EE1B85335
-:1046C0006B9D9FCB7BEB6670B9EBB5256524777D41
-:1046D000AF2D62BDE7F3FAAF7B1881E4AEF8D049A5
-:1046E000CFEFF5E8FE90B05FD2C87EC1FAC393D792
-:1046F0006F8D8D0B8CFAEFE15BD481D178555B66C1
-:104700008CDD23C7FA51A012B944FD28AC1BEC9AEA
-:1047100011EC47ED26BB06EBED934718EC1A7D9E96
-:10472000B566A821BB66ED0EF38C4476CDACF2C421
-:104730007E14D6390FE27039F8FB7F49FBFB5F51DD
-:104740007EE9DDAEC99D7271ED9ADF4FBE30F18713
-:104750006E3ED6EC990714E50D4DAE7C47F9B1D10C
-:104760004CF1E36F2B3F4692FCC837C88FCFCE4742
-:104770007ECC2A771BE2A20765B5CF58B2D37798D3
-:10478000A15ED6F42FD63BD1AF31219C7E5221B110
-:104790009FB3C10BFCF7FDA64BF35F267AD8BDC8CB
-:1047A000CCDFBB3FA88873220FCD11E7A91E5E5E48
-:1047B000309B3E235A9772C3DD4914D72E17F70456
-:1047C0004C97CA39CEFDE00C61E7643BDB2FA7FDB7
-:1047D0001FACB000D1D5D9E2DC146EE778B5E6475E
-:1047E00081B499FD0ED70F2D6E3AAF1A1FBF769682
-:1047F0007CCCDFCD83F40A7FDF7DB6F8F5B78D5B27
-:104800000F98F29DE3D6CC8F35CF0DBF41759E49F1
-:104810009F4726CBE25C620F7A2C9E9F3BAAA7A7FC
-:10482000457A3917E524FB29E61E59FD7BD659E563
-:10483000621E27D94F8551BAE8A82EEEF55EDA94AC
-:10484000DA678EC4E685522CED3C5E4AED3E7EBEB4
-:104850009ECE2F90CCB27859AE3E5E89F239C178A7
-:10486000FBEA8287092EBFAEAB3D4C71EA49964EFA
-:1048700089FE9EEBDE3A95EB7BEA9AB8DC55D7C60B
-:10488000FDD6D76DE2F2BEBA103FBFB7EE31AEDF54
-:104890005DD7CEF5C773C53C132D211E6752178E09
-:1048A0001FC30F659FE03C31782E8DA886F6096FF7
-:1048B0003619DA8B3ADB0CF5BEFE4D86FE7D66843A
-:1048C0000CED6F950502538AE85CC363867ECEFCCF
-:1048D0007643FD5CFD850BDD6F654AAAE51FC8AF19
-:1048E0008302484F4867E9B5B2CA79F31AC197FD08
-:1048F0006BBD61AA6F71D998BF75BAE433CB26B18D
-:104900007E53CC3DB51D2E717EB2A1AF88A734FC7D
-:104910004CD4B76489F391C3AB447EA461A0B8972B
-:1049200044CFC36F7169F793F8C43D1A83F223FC37
-:10493000DDED20EDEFC139CB45FECC0D6ECECF378E
-:10494000D481F67D6284F31D1960F68AFBD5159932
-:10495000FF9E920542F5385F43BE5BBD85E44C3057
-:10496000D56BF6F29F960D99298F48E2899330ED29
-:104970009ADED1F2F2491F009F3BE886CFE7E27B47
-:1049800084DA2EBEB7A97F6D17E7E3B6FC42DC637D
-:10499000130FD78E5F7CC5F72A6DFDD95759C4D444
-:1049A0005BBBCFED7425C57E8FB6A52695EF5BD892
-:1049B0005A9BCBE728B6D688EF8D6510FBDDB2C8D1
-:1049C000C6E730B6D69ACD24274F2DB2305CF4F529
-:1049D000C7CFAB7FBFB94E3BD773AF76AE67AD766F
-:1049E000CEEA6EED5C4FB376CE6A8D763E76159D3F
-:1049F000EBB1133CC5B99EADB50B14ED3CAB7E2FAE
-:104A000003C35742F8F2772A56D86B1A07F4870C7B
-:104A1000196EF1DFC7665425C79DE7319EB74AF589
-:104A20000D30D49DF9C6F356C9434719CFA90E34AA
-:104A30009EEFB1798CE77A2CCE4AE3F9D058FA444C
-:104A4000609A566CAC27FC77FF7D477AD88FFF7E43
-:104A50005C37FD86F47340129D4349637ACDAC12F6
-:104A6000F499A17D0FE3864E2E53915EA874529E59
-:104A70005DA273902AD351F4FB37A5577A3ADFBF72
-:104A80000720AD4CFCF700F473087FD1ECA8A553C8
-:104A9000944FA71445E7BB7F8A723CB6AE973DC9D9
-:104AA00085FFADF2FF01C18CE32B00800000000008
-:104AB0001F8B080000000000000BB555CF4B1B41B9
-:104AC00014FEB2BBD144A35934B6865A481A520DCB
-:104AD000A4B06D37A225D2D5869283C8163C78E85B
-:104AE00021879CFAE358E86D635B904A24A9422F22
-:104AF00052C8C11E0A821EFC03621B7A8E680B52CA
-:104B000029C18AE7405B7A11D23793AC899BC47A7A
-:104B1000E940F2F266E6FDF8BEF7E6E50D68798158
-:104B200090A2DD137D40245A2A3848065468B930D3
-:104B3000305324E9A2FDB5AA94359114C0A9095CAB
-:104B40009ABA1E2F4912D9C9163BFDD4CECEEF8D8D
-:104B500031BB0126252EAF1F39000FB015B3E51666
-:104B6000FDC0C20E9DABC0EF315B0E7E96DC49A549
-:104B700032CA4D01917D69BDDE4BC02CFB49F17AF3
-:104B8000C73D0309F29F3180FC30BBF3D0CD745791
-:104B9000343BE5A33C427B4548E42F5284DC078646
-:104BA000AFAC81F6E7AFDE17258AFB6109B84CFB95
-:104BB0000BF652EC11DDDB1AEF945F28CCCFB4FD7D
-:104BC000299DCF5C1121325DB71F962855D860AB67
-:104BD0005C237EA25255A755A1CF0334E894F70C6D
-:104BE000D347EABAFB243029535ECF0FFC1B8591D3
-:104BF000BA5D805261FBB7B51ECF71376D8410AAC4
-:104C000088751C15B6EE36CB3F866FA360673821DA
-:104C100030BED43D21E7A738BD5F96BB183EB1A892
-:104C20008B25B2478C508F13CE3DDD8D73FC7D6795
-:104C3000FC7502078683CBA22173B9650C72796C6F
-:104C4000F8B83C3246B83C34142E4BC61897408A0C
-:104C5000D7B3D3061E2F63C47763C1F6F1645B59E3
-:104C60006775C78484F7ACCE432AB76BBA17253F64
-:104C70000D7C115DBC190A3D6F2799FDBB27028F82
-:104C8000B91ADDF4EAE166FBD56753E7E24E1B7320
-:104C9000BBAFECEDCF5D1D486CB6F0FBB2D6C740A4
-:104CA00096E711880B58A43CBC0EC529D3FDF4B679
-:104CB00093F7754871E49C0CDF9A0B3F4C1CD43F72
-:104CC000CB696A19829CD524997AEAD46F8F42F90C
-:104CD00034F45560FAE320AB677A223FA8138ED5EF
-:104CE0009B9FE786C92EB5232288E6BC5E6B369E65
-:104CF00097892B202982DC027F3B5C8F6BF618F2B0
-:104D0000F0B960E5DF7ADFAC3BADB4345A7BA2B4D6
-:104D1000125D898C4675D2D66D9C07A70FFC7D77F6
-:104D200040CB33BC17C80FB8433CE7238994AB9EF4
-:104D30004FBB3A997974D7FACF9B2C3B12846FF909
-:104D40001F7DD8672F3A58BD9692423CD7228FF5E7
-:104D5000DA9C5B526F39D97B44B8751EFD716B9F2D
-:104D600056F35991C83F9B4F2AF96FC1F737C67761
-:104D7000B59FF745AA6B46137CAC9FFB891B8D4200
-:104D8000F547904B116FD9A8A0E4E9FC97DAA17020
-:104D9000F796F9D0145F6DE8A36BCD73675B73551D
-:104DA000E74D1041366F7E0ECDBAF32DEA6B4A9374
-:104DB0004773EE34F358AEE24C567122DCFA3DD71D
-:104DC000EB355F1BEA488867FBE6EB797DD38E7F86
-:104DD0006B1FAC2475779EFE1FF0691FBE1B8C8F66
-:104DE000B3EFAF1D6F569E8EFF334FD6F3A23957E8
-:104DF0002E88F3A2F74CFD2FDBA790A6F00700004A
-:104E000000000000000000001F8B080000000000F0
-:104E1000000BFB51CFC0F0030977F3A0F2BFA3F161
-:104E200057F1A3F2CBB851F99E68FC2634FDE7D1C7
-:104E3000E4591820B4233BAA38B158988381410E15
-:104E400088353950C5F3A1E6D6002DE807E215AC48
-:104E500084CD7A27C5C0F05F9681E12890AE06E246
-:104E60004B4036931C0303AF34038307104703F111
-:104E70003B190686A940FA25106F9086E8E3048A5C
-:104E80009D9421CFFD6D42E4E91BC5D4C1B7955077
-:104E9000F993B51918AEE93030A8E941F8E791E483
-:104EA0009D806253B421EC70550686BDBA0C0C8708
-:104EB00095B09B1B0194DF07948FD0C36FBF831104
-:104EC0002A7FAB352AFF8B212AFFB2272ABFD61BA8
-:104ED000955FEA03A10135720CD6D80300000000EB
-:104EE00000000000000000001F8B08000000000010
-:104EF000000BCD7D0B7C15E595F899C79D3BF79987
-:104F00004972031708308941A2061C204040C44959
-:104F1000081A6C8A17A44A5DAA576A2D228F2B6241
-:104F20004D5D6B26EFF0B08DE856FE6AF5C26A97CC
-:104F30005AADD1D296B6DA26802EB61422A5D6B6B0
-:104F4000ECBF415D6D5965A35BD4B5B4EC77CE374A
-:104F500093CC5C6E1EF6F1B371BBC337F33DCE77D5
-:104F6000BE73CE775EDF7715D107FA250067F08F25
-:104F70003DCF170160E6C0335A01A57239C0262122
-:104F800068848BD8F34FD2F2CE30FB06567CE9947E
-:104F90008176578340F59F2F6A8DF7B2EFED93BE70
-:104FA0001A8732567FBC40F59D7ACEF30690000AF0
-:104FB000004A3A56AA09D6CFA6318D2AD66FD7B75E
-:104FC0002D0736DEA91205241CAF287BFBD67A807C
-:104FD000AEC90097C056B538C6CA47256333641BAF
-:104FE000A788C671CAFEB8085DA5407F67D8FF369E
-:104FF0007D290909366ECBA4AF2E47B895AE9B40EC
-:105000008F00DC3626093A7B3F0D449A9752618126
-:10501000C9CAAA6EC5AD29678FD38E7829C35E3BF6
-:10502000E24B2303EF97387861F8C8C00BC05C00EF
-:105030000DA67759580E00B5CFECD7B4C7D7E223E9
-:105040001BFFECF9F3F1A7824E7800B5239E880C84
-:10505000C0B3C9D7D725317C5B45603CC6AAE4B054
-:10506000712A5DFD648ED73F4FB9C3B3FE5310CE96
-:10507000029A8720BBFACB8467965D6F169B393EF8
-:105080009D79E5CCE3E30CD7FFE588E202ACDF11C4
-:10509000B7222E7A942D0FDE83767DCDF4D61B0CAD
-:1050A0003F21C4CF4CC48F15477A74E8580AEB0DE2
-:1050B000356C3E0516F449B94436268C02C8C77FC4
-:1050C000B126B2A65722BD8E32595DF67D74CC6AE8
-:1050D00090D8FB31F3D282CC9E1178487B23040810
-:1050E0004DC9196A6471BAEF9CD1DECBE8F614445D
-:1050F0003A36B36793CCFA45BC1D8BA41F632035A9
-:105100005C9C7AA4979523960C8DE5342EF1E1ED05
-:10511000D2F9C66646D29B6DFA6FAF57E9D95AAF3E
-:1051200041971FA0B93E4ECFFB4377FD1BF65F674B
-:10513000F9353F7BCA9DB73E85E52680048E1789E9
-:10514000F1FE4156B5C7342C8389788F94F0E74B34
-:10515000881706E7571926112F3FB0F1A44317F11E
-:105160006B93B13407B2E0D379864ABD7C16D08305
-:10517000ACE540D91FCFF3947DDA584F7D8042C211
-:105180001B9599A85825707914917BC0403819BE99
-:10519000B2CA055BAE48D2B4BE2E36BFF06CC5D8DD
-:1051A000C99ADE2D78F96B8CC0E9A34C50E91983BC
-:1051B000BE7D67102F8698DECCC60A4E2BEEEC8A99
-:1051C000E1988A3189AD63D097D6F2B2F01794CBCB
-:1051D0006FF53A70177FFCF891A4EE5422CBB87F9C
-:1051E000B0D7EF92D38755E47F759A98489721BC42
-:1051F00056824D1EB6EAB288F3FEF8E01E7ABD8EE6
-:10520000DBFCDC0A2AD59771BDCA07D6ABDD60EBA3
-:1052100085FC53CED7AB5DB6D491ACD7E3001EBCB2
-:1052200084FAF1D2C9F152F631E3A569EFF244965E
-:1052300079B4DAEB29836194121E141DE1DCDAC023
-:10524000E9D662749B4DFE0E860729E7583C5976D5
-:1052500036DEAF12F8380B6C3E71F0B4C9106BD269
-:1052600061C453470DCAADAD25A28872E9E3C2936C
-:1052700003D7E67EB8D21CAED28F172E29D4B53C08
-:105280001B3FB666F0E316849BD35D0DA73BF1632D
-:10529000A53B07AE00F2035FE7045F67F91F629D5D
-:1052A0005BFBD739C9D739FEF1ACB3B39F836A2C06
-:1052B000C7755BA5313E6470DC2C59CAF5B8BF8652
-:1052C0000478CC607480F08F617A66B8F1655D0710
-:1052D000B84F08707D435A919374C1BB4A663ACB6C
-:1052E000747CBFF5DCE410F380B4AFAFD78193F1E9
-:1052F0006FDDB186B6FD2E38BF24446204E76C989A
-:105300008D70BE1B5E9AD30583F777A25E6D907D8C
-:1053100000EFD75B6DFB7D677FBF59825436FDF28E
-:10532000415B2E80DAA9D0FCEF643C380DF1706E41
-:105330003544D97A841B47E13C20CC3ECE61FDEC5C
-:105340000A34C82EFC0E369F7EBC3AED98BAE3CFE5
-:105350003BBBFD60ED3E14928F080CBF2D31B11A9E
-:10536000E1524B208D6BE0DFB5A46B2C0C0E6F4B24
-:10537000EC6F03EFA0EB66D77B37DCD80AAC5D930C
-:10538000CF38A0333A692E108D461880C3A1176715
-:105390005D1C3C8E745D7EDB4F5F5B2F05D233411D
-:1053A00097A6FDF5747500E9EA82BF3F5DBDF18FF8
-:1053B0004B572784827F5CBA52EA24FD75666714D6
-:1053C000C9269793DA4A8BD61FC7667249EA98D6E0
-:1053D00085F212E2CC3EE3C380C8CA8A6672BD176A
-:1053E0000C40FD552DF1CA495FA1574EC6979B5DF4
-:1053F0004EBF9B751C57A171D13CC271E53074053D
-:10540000A25856A81F24E733E7303CC18335C5BCFA
-:105410009D81ED069B8F8CEDD878A87E9C29C27665
-:10542000FF9493C862F70ECCDF3B4E7C59222711C4
-:1054300019797D08CBFA1B2EBC0FDE4E86371CBCBB
-:1054400030FA2F453F49C100FECD5DB790FF2200E5
-:10545000A241765D61AB855FDBF0FFCDC17D9FF33F
-:10546000755BE1740DF52D60FB0DBEB7842F0096C2
-:105470003F1474E25B673C299C00A21BBBDE70EB0F
-:105480007F3BF25316FE5E21727DE3FDBB52FF8D22
-:10549000F6A0B559D01F63783D54FF01BCC6F87221
-:1054A00065D7790AFA3DAE134751BD95F38A940545
-:1054B000AE7E5602B70B017AE52511F7B80D5C0FE9
-:1054C000ED94F6E2BC5FAD90D2B8FFBD5AF13FA4B7
-:1054D0009FBF6A4A6944F2ABED57E60C25770ED5BB
-:1054E000737BD6A977C894687F3F24F786B3E9F128
-:1054F00003E3A769FC2B2A24EF3E2DF7CAB8FEEF81
-:105500007F097CA83F1FAA5785D72631E317E7C933
-:10551000E868654591827E87E1E6B5C8F68339F88B
-:1055200075E6D91C16699ECDE12AF25B356BEF92C8
-:10553000FD788ABD47793018BC8EDFAA595B9A1571
-:105540001F4A84EB5B8A2F99DDDEB4E7EB9433FDD1
-:10555000590E7CAD616E17B586395CAD31318DFC6D
-:10556000DF1ACF3EAEF36CB2E173EA35C7B85EDA4C
-:10557000CCE4C948E091C35E7818DA8EA0BF64BC61
-:105580002D6BF26B7B1A3E8F7676326C4A06BEE943
-:105590001126B0F2B8B8049B35366E4D557B356395
-:1055A00081BC1589171918301A3A2AD10F38F14BD6
-:1055B0001BBBBFC6E6356E8E5FC3767935A9EEE7B5
-:1055C00058BBB14CCC49ACDDE8636BD7A29CFD174E
-:1055D000B41351105B3736A01FAB1987980BF0B08E
-:1055E000B8A212FD6C3270B9C0A49E2E8F42FF0C7F
-:1055F00090736630F9C0FE8433FE817683E12D62BC
-:10560000CB2B9A37C9ABA543CBAB8DBC7F8BFD872A
-:10561000F266DCC078D47ECC2AC583C7D119DFF707
-:10562000DB74E987257FD771C6C2D200EA2791656E
-:10563000A296C6FAD0998B7EA8516B64E8C2EFE5BA
-:105640001D0D4C7C0C8B7726F76AB8DF38292C713E
-:10565000C1FB2B91FB9926DC715410D0EF6B309578
-:105660007E1A96EBA665A3D36D367DF6976B560A28
-:10567000491A2FB16812CAB55A91ECDE7F59363DEE
-:10568000D7DDFE037B9C81F5075D9E8565BEFEF23E
-:1056900032D10C4CFDCBD75FFE88EB9FBF51F1ECB4
-:1056A000A71F755D64B43D0A865FFFBF761C67DD8A
-:1056B000CEE60F2E1F27DC511D40F9775F6268B9D7
-:1056C00072F6BA2DA5751BB50CCC7416B9129004E0
-:1056D000CFBEEA3C554881C1D6593A2A917C9346BF
-:1056E000CF5ABE03061F578A2919F69BDD9F65EE28
-:1056F0002B61EBFF4970FE7A649443B52887502EE6
-:1057000095FB5E77FB4718C607CA0CF76F7F71DF02
-:105710007E9447169347E83FCDFC5E8B65173D5C52
-:105720002AF1FD77EF777E79AEC0C6396CF8753F08
-:105730007B7550E87983FCBE9512EDC7089F3A0B44
-:10574000DB032927874DC9AC66F57BCA05DA47FD1F
-:10575000F0D2B5FF4CED4314EFE899F7DA972F62DA
-:10576000ED3F79B10F39876302DBC7D93F51AF39BC
-:10577000DDFBE58B58FD8317E70FA96FD5E27C5D54
-:105780007472C5B3DEF20AA43784FF3FDEAC7D90AD
-:105790008D771872127E7C5670F80E237C48F7BD08
-:1057A000BF7E03F5C243A640FEA8C3153F8FA13DAF
-:1057B0005E690AA42F2E9E27A4FD59E6B978DE2D36
-:1057C0001327B0FE1246480BB0EF072BDFD97A1132
-:1057D00083F78AEF4B77E3F3E41EA920593638BCF0
-:1057E000CEFB2B4CEFFB7EBD189216E21D341E97AC
-:1057F000F0C58CB89B5EFBF518396166F3B7AD91C7
-:10580000B8FF51D00CD2EFE4B002388FC1EADF38D4
-:1058100008FDE6405F97847038FAF7E92B75B73CCE
-:1058200074E050E44412C791340576A29E917B95B2
-:10583000EE9E7FBDC4E34242DC2478148DC3A3C82E
-:105840008699CDDF5467C3E3F403D061B7EF83DEFD
-:10585000F0007C2D81C472F45B58B9DC7FD81CF158
-:10586000FA0377DBFD3CE6F4E783AC71158046EA8A
-:10587000BF6A54858AFD3755703D490783FCE3CDE7
-:10588000CC6E8421F4BAADB6BCD88CF10D3FC639CC
-:10589000343BCE11E7FA53F819F2939D2A13C9AE9F
-:1058A00019AC9F88E1D54742A55E3BC6D15F027A1D
-:1058B0005E861FC8EBF7F18D924547EF437A1D0EC8
-:1058C000FE7E3DCFAED726A7542D2B9ED243EA7342
-:1058D0007F3FFCF1F6215FA7960DAEBF15DE1CBA27
-:1058E000CAEC5FC95752698ADB25E21E7DC09693D8
-:1058F0004ABE9AC27D01D4C1BE0779FB30FB8EF14E
-:105900008C7042477F8A043C2EA4221FB8F0F38E8D
-:10591000DDEE1A59B4F5F914C541053D457E3BB598
-:1059200090F18F70763BE7D96BB76FFBD3ADAF10BB
-:105930007F14A8C41F82CEF827CB388D92F996C465
-:105940009EEB24F36D7CFAFE2C25B3F1C97FD9724E
-:1059500045AD4DE86A31C515C91EC9842320F37EC3
-:105960006F74E0B75214A71C29FC1F8C107E671CB3
-:1059700006BF2C1710FC3E7C0E06BF64C393077A4B
-:10598000838C724DE7F2156089EED64B6E90B9BCF0
-:10599000C8B3E513C02D71B7BD759DDDCF48E79342
-:1059A000278F6C3ECEB86C3E1364BE1E13E521D625
-:1059B00063BC0DC70D32DFEFD4EA841E67EB923B68
-:1059C000085DCDB3E148C9A2AD57DCF291E8EA82A7
-:1059D00011CE63DEC0BACCB6D7A562A879CCB2E747
-:1059E000D121C19CD7512F3EC7F1F72CF5ACCB6D1F
-:1059F000367E3AFCCEBA6CF0ACCBCDF6BC463A9FC4
-:105A000085767FC3CDE7B681755962CF67E950F3DC
-:105A100071D5BFDAAEBFDCAE4F76C76D726923DADF
-:105A2000198D5262855C30301EABF71977BD779ABD
-:105A30004E35D8F5AEC7F7420DDFFF58BD95EE7A6B
-:105A400060451BD13FD082B602B3634A9AE756D96C
-:105A5000ED5651BBDAFEFE6FB2F983DA059A854640
-:105A60002B4CF5D662BD86057F76EAADF3C27B810D
-:105A700003EF0682B7BA1F8E5BDDF5E6C9E3A8BF68
-:105A8000B3E20E23F407F962C9768CF3E741A4036D
-:105A9000F33C5AE5D42398076059323C86F9047EDA
-:105AA00043401F5BB422F56F582FD762F635AE5BCB
-:105AB00055EA292C5B22249ACA299F80F205EA64C0
-:105AC00055F31B987F61C07656D662721AEDF316B5
-:105AD0002169E1BEF83329F96599E4ABB6A201FB6F
-:105AE000CFD7B99E0EBDB46F3970DD13BA96F21FD1
-:105AF00072195CE88F6AC980EBFED0846EDC6FEFB0
-:105B00002D50484F66065629CA97DBA5A081FD7522
-:105B1000177C81E0DDD6C0F31BB67DF20B04EF7D70
-:105B20000250DCF63E1FCF6FB8C7A76A8D1AF61772
-:105B30001DF339CA87C8D1FCE5361C08DF278A095E
-:105B4000BE7CD02A6F10487C75A37DDB52A190BE2D
-:105B5000BC2D36BD92FAAB50494FBD2F31BD81F4FB
-:105B60008E8A20F9E8F3C306D9ADD1D90A58588EE8
-:105B7000190DA867466605310706F20B01930B2045
-:105B80003219D258F6414747097B46DB995D924F5F
-:105B90007613DC80766F05C33BDA11967904ED92BB
-:105BA00030D87FD24113E7ED1B2701FA3D9CF58DDC
-:105BB00076F4B71FD2EE8AA64758AF6B64F522ED94
-:105BC000CCEE9F31827A1D23AC971E61BD2E5E6F95
-:105BD000587F87C1ED3D95FD87765B20D36E0E7BA8
-:105BE000ED615FC6F7CC785CE633331E7242F6C6D1
-:105BF00043866BEFC441869B2F3A25FAE19486AF2A
-:105C0000EFE89B837D57C65E153759FB9631D7C4A5
-:105C100049AE8D59C19FE3EDF7E397DBE56BECF2FD
-:105C20008AE56616F93EDAC7E57029FA4386F23B43
-:105C300000D71FDF60B09F1130796968FF49A6DE89
-:105C40009B29EF54D9AA427EDD96E07E4D3F322358
-:105C5000F26121901FD607A98E1294136046178E09
-:105C60001AE01F9FF98289FC7C688C044205AD8F85
-:105C700041FEF40C3AC9A40B7F863FE7AFA5930B16
-:105C80007DDE78ECDF8A4E94766944FCA3748CB098
-:105C90005E7A84F5BA4656CFDF2E8CAC5EC708EB31
-:105CA000A54758AF8BD76B9DA3F0FD1CBEDB689654
-:105CB00030B8E7AA9E72EBDCA0F7FB45614FB96DE7
-:105CC000A642FBBF53F6CF523DE53626E73DDF67E0
-:105CD00087A9BCA9A5AB8A6D6523E693FFFC0BF9E8
-:105CE000A4541DC62F5D2166D86D197CA5EA016CF0
-:105CF0009F2FEB80F953F931BE4FB1A799CE82DFC8
-:105D0000476CFEDF29F3FCCD6DB21E40FBF11F7D19
-:105D10009E0D3E0EAF33DFE1E075E4EF9B92AD6F79
-:105D20000D96F751CDF3326508525E6649B5596557
-:105D300032B924BFC8E36099FD5EAB249FF6B9EC8D
-:105D400061594BF2F89EDDDFA20299F41299C93530
-:105D5000D47B1448D414511C51247F9F1C1E66DF31
-:105D60002874C9ADE221E0B6F358E9930E50F93B2F
-:105D70003E6ED00092AF11E825633A07B59E73508E
-:105D80004FD305A0F686C0FDE7F334DCF76281BF90
-:105D900075BF2BA85FC1BC07CE843E42BF722FF9EE
-:105DA0003BFFE6FD0E036F00F37B2FA01042CC9D5E
-:105DB000DFEB8BA7E8259C3E73469A05BC09FD25C1
-:105DC00029BE2E8B06F943616C94ECB296D806D5A9
-:105DD000BDAE7FF4157BFC268AD67A8B1065CFC2C8
-:105DE0003566EF10747E068331E81F29BCC1EC1DB7
-:105DF000623FED8F6762BC3E0B1FB42AC934EAEFE5
-:105E0000D68430B7E7E514F919DB84BCE99BCB5D98
-:105E1000F45BA874215C9172D3427BAF2D5F345048
-:105E20004F95616B8F3095B5936A8D64163D62A076
-:105E3000BD7CC23D9F98E2D5A79A86A1F79661F4F2
-:105E40001E9F6224B3F943272BDCAEF505B37FBF59
-:105E500043AC2A51669E8D37A6E673FB3617DA856A
-:105E60000B39F950BE43E10BAF201E5A0A2E8D0F9D
-:105E7000355FD0BC7997378AE634656838666683C3
-:105E800063A4F9205AB54174D8AF2FC5385DA39EDD
-:105E9000248CC27C0FFE7777F9CE2ECC03F15DCF38
-:105EA000E3B292B90BD04FEDE84D92193C2ED27A65
-:105EB000CEE3FA5329D7874CF61FCE233A6F68BD3D
-:105EC0005ACA282F51BCFA5053FD1EC0F8BC03BF5C
-:105ED000E3C7CB9CD75CB1EAEAECF818993D7C1F8C
-:105EE000A317988CF1281591021DF51A95BF5C1F18
-:105EF000A7F2D67A9D9ECDF5A5F4DC824DE7209FD2
-:105F0000A7DA8B18DEDAE38FC63FC7AADC87B28335
-:105F1000F6FD6B17A09EBCB9BFCCCC4006F7660C53
-:105F200078333DE256E58A0568BF6F0E80ED57581D
-:105F3000B0C0F494AF6AAAC4B2ED67D8DC7A1DD5BC
-:105F4000BF6F3CD8E7204CF553AE7DEF11C547FC41
-:105F50008D7B0B6F6F36617F01D92EC32D0BBC6516
-:105F600030119E80CACBFB940DD43F890036DE4FA2
-:105F7000955BF97893B81F1FCA960E8347EED70733
-:105F800045E7F2B32C8FF25914C340F72BDC976B23
-:105F9000C33DD27EE424DFEF8E66DF2F07F86698DC
-:105FA0007DCD8663B8F567E8B0FD1049B070DC5F61
-:105FB000F038E2DF7BDCFB7C1F0D2F4A459F85E735
-:105FC00047E629C9EF21BD47CCCEAE22568ED67604
-:105FD00059C4BE231CF75E45B3E79D24FE77F0EC61
-:105FE000E81DFFE5F3AEA32F66521E5220CCF96FD9
-:105FF000A4F0F6A27E3573A01F78A26ACC50FA5A9C
-:1060000041424425AC5F5EE4D704D118EB2FE79AF8
-:10601000799E724EC5584FFD8851ECF9EED3CEF7FC
-:106020007CFF4BD7E91719F3F889AD373AE51F67BD
-:10603000CE7384FD3AE5EEDE0562295B87976B251A
-:10604000D2EF5EAE7DEDBE19584E4814BF3DB5BCD3
-:10605000C9878C7414CCC84CF4872525DB9F6E8EC1
-:10606000477CFE02FFC9C67B09F73D269F0EDBE792
-:106070007F989C188FE79F0E5F3C7B3CAEEB611FC7
-:10608000E76FB03A483EFDDC071E79F0735BFE18FF
-:106090006DDB9BD00F7954E065A96DFB028BE28329
-:1060A0005B5B2F637ACB951C85B0B456C86A0F44EE
-:1060B000FC0AE1E3432119F1B3799AD57A4B0CF349
-:1060C000DF74207DD50F09D2CBEAC0AA1451DF615D
-:1060D000F447716EB9AF309BDEF1737B3FF7C39528
-:1060E000A4EF2FADCDF5A131EFAF99E6433FEA958F
-:1060F00035953EB0F565CD059F9810E8FCD4B25AB1
-:10610000FF4EC4EB32D9F4658B6B5D99F07BF6A939
-:10611000690C8708FF51FBDC03405FA13BDE34CDF7
-:10612000CFED9D78C9D0F68203B7535E523BED792F
-:10613000C403C3369D4701B5AFF0DA88BBDF9013C7
-:10614000178E60BF2F2FFF2CDF9F195DA05FF1C559
-:10615000E39FF7515C7659BE87FF96564B1EF813A6
-:10616000F3429EF255B557E60CA97F24FD19F2CCF7
-:10617000B2CF618A2487371F13483EE44CE84B6353
-:106180009E26BC2C01D7FF1CFFEB5CF2BF46C7F577
-:10619000E9A82FC06F43DA632EF9D96CD3E560E329
-:1061A0003FE7E77AAD9C5743F1EDF78F0B3ACE57B7
-:1061B000C8AB9B8CF39515B311C76D2E12D318F78E
-:1061C000BEBD789B8AEBBDA9E4A3E981BE188FF719
-:1061D000EB96361DD97FB07669939F23C87CBFC6E6
-:1061E000CFE32D2DD652AD049771BF5689F30F140E
-:1061F00042D673A68CFED7F8D16F1FB380C7D713D2
-:10620000A45797A82B290F571E3B74BC36136FB2A7
-:106210001D07CCACF7A44D8F25153BA9DFF7CF1B8D
-:10622000BA5F072F1F1822F4D8FA04D65781CD87FA
-:10623000E17F4B29CFC36D2E7B86F02C9995A4CF9F
-:10624000FAB49489F5B694AD24BA6C6175F2D9D0DC
-:10625000B9D59D744E73CB9F787CE2C9B6FD4DA82D
-:106260003F6CE9BE0930AF32184F03CA8F2D536E11
-:1062700054110F5B7600F4201DCB9DE4940BD9FEE6
-:10628000F0900669664941A8CC04940B791A3F53F3
-:10629000B9375E05B86E5BCAC140D6CC4FA71A307D
-:1062A000F4B325CEE3DFC152B3A608E11E23921852
-:1062B000D021D98EE5E65A99E6D1AA717CA0DD7588
-:1062C000C6C9EFC23C98126E7795A07F9FF5AF7C50
-:1062D00089CF5BDF5E427EA22DB92F9BA8EF5A9F2C
-:1062E00004631270BD96F40499D111F65FA7655D41
-:1062F000F7AD62F29B7E57FC5ED67401E934133F22
-:10630000EFFBE0729C77F334117666D137F6F879BB
-:10631000BC2E6D2CBDA238CB38CFF9754F9E80FEB8
-:106320008142700F567FA09E4C7E7D343C16B17921
-:1063300014D4707F29649C638D4192ECDBD160356D
-:10634000203F3AE757C755277E95644F29B28CF214
-:10635000E9063BCFEAE479AEACB00532E857FF86F8
-:10636000CDF7A6033E40BC5D72FA9117305FCA5765
-:10637000E1D728BF0A3A5EC0FCCD1B983A86E59B60
-:106380008E4D5130FFE7E5B112E6C620FF44910E75
-:10639000DF0691F2CFDE8623D1192E3A7FCBDE774E
-:1063A00050B2A21C69CAE5F392C3AD3D5214D75D49
-:1063B000B67A9DFC3D5298785E3B84D97B95B28F2E
-:1063C0001A48FEB5F37C21273FF2731DDEFCA1CFF6
-:1063D0006FF7966F84A5A3906F6E640A5D9AF57B44
-:1063E000933BEF8B8D7FD4CFF583CF43AA15F79FD7
-:1063F000363B3F66EDF7A62848D737CDD08AF01C4C
-:1064000086338F3FF8B91D7A82F1A9EEE2FFD5B14C
-:1064100034E52767CEEFEDDD0BBA92ACFC9A2EA7E0
-:10642000B89DED9D679BAF6731E67B5977FB6CBDEF
-:10643000C19BE7B87A57A589F9620C7B7ABEB73D54
-:10644000C1FFD976EF7C87C347E6FC1D7D70B0F9AC
-:1064500028BB84ACF97E21D59B2FD5A4F278A3D993
-:10646000244360FED9E7A3ADAA149D6FB61AFD5A66
-:10647000538CE29314FFAB638483F1BD7255A77E06
-:10648000DE0F4C48039D4348CD46FDE8AFED778EC7
-:10649000CAF9F06FDDEFFC41E05DABF62AC89FEB77
-:1064A000E58E1AA178E07C40C06799E318BEFD7BB9
-:1064B00096748D034FBDF611D63B8047A04750AF71
-:1064C000461CA2BF93F6BEF5EF4FFCAB82FBF7DB99
-:1064D0008F1F5F8C72EEE61F4AA0B27A279F88401A
-:1064E00017ED3B6905E5F2EADD12AD3FC85DB3AEDD
-:1064F000F4E4DB37D1FC6F7E2A42FBC3EA67FCE998
-:106500005AD67EF5775F9B0A8C6F4F36F6BD300EFC
-:10651000F1F7B8C0F318ACDEA957B2F7AB65B82EE7
-:106520005B1EC2F52AE7ABB7BE1F5A8EFBBBB0ABF2
-:10653000FB5AEAB7F36A9FDF257F97ABDC9E66F5CF
-:106540004CFC6E7D43484F12387CD9F2F2DEFA06DD
-:10655000F7A3ACDEE34B639EE2EA5D3B9424ABB76A
-:106560007ED73B44DF0B9E7A328A7858BFC77B1EAA
-:10657000E1E6A7FED43AB79CCE3BF5D5A2FC934EFC
-:1065800053F994A9F6F13C78EE8F59471CCBEA7D7C
-:10659000FBCD4B7FC3BE9F884B106022E544CF7F6D
-:1065A0002A3FC472329C62A28CF5EF7BD5CD87EB7B
-:1065B00077BD46E78E349129B017E179888CEF19C1
-:1065C000F5999EABA03C5CDFB9E91D9497EB77BFD2
-:1065D000FD6BA4BBF520BFEAE6E713F88F3167C770
-:1065E000B336A95E3FDD2938388B1C00BBF2B3DA25
-:1065F0008B4E3CCBE1EF9B9F3CF530EA116F3DF3B6
-:106600005F0FE3FD0C6BFEFC3F0F635E2BFC28A0CD
-:10661000A1DC5AFFF82FA2E0C2FFA3B67C38F98DA7
-:106620007FFBFA030C0F277FE527AC9D7CEECD099D
-:10663000784FC7C9A7FF7714EA1F1B9F5B381AE979
-:106640006CE377168C1EEA1C28D26DDAEF5EDF341D
-:10665000BFDF608F809B20C0B3F633635DE0609F37
-:10666000827AEF7B02F46DCE65EF3BFFA4A0FEF2D1
-:1066700082097D88A77DBB5F7BE10E567E9BAD9333
-:106680003FCB3AB1F98F13697F63ECC39EEB765F22
-:1066900079C5C5E5F8F419D8FD7AE8A37DE3ACF532
-:1066A0003DCAD6B77C607D33BF9F82D30AE27FFDAF
-:1066B000136C3DA7E2BAB2F59C7AF67ABE8DFF98CC
-:1066C00073F67AEE53BDFEB853B0E69107F0E3EEF1
-:1066D000FCACF6ADB39E6BBFF3A921F572473E0C3F
-:1066E00087673ADFCBE0FA8A6AFE5C45BE7DE69BAF
-:1066F0005F7F20C6D7B99621E6E493A726E0618D97
-:10670000DFF9FAAE453CF43DE7D7508F5AFDDC2F58
-:1067100089EF4E7EE7253AD7C3FEA202DBEF4E4259
-:10672000FFDF1160E575022FACD5FB2EFD35EB7751
-:106730002DEBC23268FD2EFD7539AE9FDA47EB9125
-:106740005E52A3A3FC4D17D0BCD7A5397FAC4B77C5
-:106750002F437F7626DE2301279F70605DD15FBACD
-:106760006EF7F14B91FE065B4F67FE1ACE7F36FB4C
-:10677000FEA8977F07E5577B7D4FEE785F41FDAA26
-:10678000EB878A26323BFFA4AF4F198BFBCDD39208
-:1067900086E78D33D77D00FF8D59CF1D673E33E9E6
-:1067A000C31FC81EBF76F0341CBF0F3FBF8F86BF0C
-:1067B00053F63E9C89C7B74E67DF0FCE09707B6EDC
-:1067C0001D74D4A08A99B99FF920658D2B1A80B7C2
-:1067D000B5532239FFD62EEEA7C99417EB06B1CFD9
-:1067E000A639E3ECE99E8A72EDADBDDFB7E992D33D
-:1067F000FDBA278E2B96BD3FA45DF85D3F88BFFB99
-:1068000022BBBFF5CF66EF6FFD13EF64EDEF846C35
-:106810005E8DF09FE8F1515ED2894E29AB9D3B29F8
-:10682000E0F3E85DAD9159AFE4B076523448795762
-:106830004D8DE62FD14F6A1DF1D97E00E377986F19
-:10684000D51409D239F7A6E88D745F92D35F730629
-:106850009EE47882EC27399628E731B0B4C78EF1F0
-:10686000318270C30DB255887AFFA1A23765ECF76B
-:1068700030EA912EBBFEB00C2DF9E5782E42301A8D
-:10688000208B7F23A3FFC43C0974B79FB06B8CF8A7
-:1068900007D6DE7F544A236AEB20D545E7020AA1DA
-:1068A000F3B12CFD3D54AF93FD5C94B88EFC3FFEDC
-:1068B00054CA447DAD70A3562CEA838F3B3EE58DD0
-:1068C0005F8F6594FF071CE7808FF441D8F5F8E3EC
-:1068D0008F8FE25B0AEAE52FE093C9BF4B56E9854B
-:1068E000587EC89E37E3013AC738DE4AC828E78495
-:1068F000D81219F58B85A984BCD2B59E0B63C258FA
-:10690000DC4FD383DC03F5BD00DF3F1B1AAEA23C96
-:10691000F607BF24125D3F18B8AC10F96C7FEEEC9F
-:1069200030FAD7BAD7CE3A3899C1392E2C019A9C71
-:10693000FBC2439FDB7CD8F62FECB4EF1F7AD4CE9A
-:106940002FFFBA8DB75DF5A5F47CBCDEA0EF4FD468
-:106950005750B9B3BE869ECFD427E87DF48E60121F
-:10696000E97377FD727A3F0EDE1170FDBF5B9FA465
-:10697000F2A3815C827FE29D2026D9FB85888FF07F
-:10698000C0BC1D78D2B6DDFDBDC08F9B912FFAF142
-:106990009881EF4BA04750D17F1513745CF7BA80F4
-:1069A000CEF35C33F03BC1DF27605CAEEE4E9E0F52
-:1069B000F1B0E03DEF70BF2DFFBF6DF3E93BD1E4D7
-:1069C0009301D6CFBB35CB4A491F02AD0CE9E66136
-:1069D0002171D828223C7BCE9DACCE4B7E3BE0F291
-:1069E0000F4F68E776FDF6802DDF368288F4363E5D
-:1069F000053AD29B33EFBD957A21CAC5BD8240EBE3
-:106A00008DF456EAA2B77EFA0DD879C9F1ECFBF8FD
-:106A100000FD72FE8FCF2DBDA71AF1B241243F4871
-:106A2000137E72B5FBD0A62366B78816D2F32A91DF
-:106A3000FCB9138F1D172630F874ED9B01BCB72BE2
-:106A40003E016C7F536700E9EBC155DCBFF8B563CD
-:106A5000FC1CD3A98DC54B26B3FA8B197E30189533
-:106A6000B7A8C4E3B774CE2F7C4D4DE46843F8B7A4
-:106A700032F3DEEE9F78D707396C9C71C7423A9E9D
-:106A800087B967E28FBA15561EDB2B903F696C38C9
-:106A90003519D7B3F2FF7F634CAF6B1D1E589B9A1D
-:106AA000887A63EBC46F09C807634FFF58C07D64E1
-:106AB000A2967C33C0D6619C6C9F139653B3D12EA3
-:106AC000B8262FF17B5CB74461FAD3484FA76A36EA
-:106AD000FE3BF6EFC421EBEAF4DCC92EF990799E77
-:106AE000E2A1D4D0FE4C67FE0FE1FC87A8E7CCDF23
-:106AF00059BF5335B135281733F199D96FDEA265E7
-:106B0000438EFF907D8F189BBF3FE8A2CFC254AF4A
-:106B10008CED9CF683C55D33E7DBEF271A619CB6ED
-:106B2000D307F948174FFF71C2B70F03924E424285
-:106B3000FFD4DE40724C7026DE1F97A232938E94F3
-:106B4000CF7E412EE7DF07467D7D0CF19D9C2EA276
-:106B5000BC8F118ED702894425EE73866864DB07EB
-:106B6000A60439DDCF8314F947C5D09D43C7F90B7F
-:106B7000BD71FEAD409300AB4BB5E31F206BE80F3A
-:106B80003B00D3D10F991FE4FC5E2973FB72C60151
-:106B90007D87C4FD56D292880B7FB6DFCEC7BB6619
-:106BA00070DF099A8EE7BEA6750B2E7E7D3F949C02
-:106BB0008FEBA6C4B93FD2174BD279CB855258245C
-:106BC0007F6E0797FF759050CFE37119C079EB1076
-:106BD0001771BF7F68233FDFAE6B2182FBA1984E08
-:106BE000E53A5B4FF9B14D47DFB7E5FEF76C7AF94F
-:106BF0000ECA7DF62CE935F7E730B8BE6DCBFFA79E
-:106C00006DF9FF942DFF671EED856F94933C363030
-:106C1000EFF9CBDBE28D38CD27EB4DAAB7B37E156C
-:106C20003DF7E58E16F7B07A8F6E1477223F3FAAB4
-:106C30008DBE1CEFBB4A9BA221B0C60F59DB164488
-:106C400019FC3B5481E2670FD7A7A8DD0E556F549E
-:106C5000319EC2AC650BC9A0AE87C21E95BFEBD3F7
-:106C60006A58BDAF75E45D8E71B87B6B646AE7F0FE
-:106C7000913E73033687689E3F886C9557D0A59EDA
-:106C80008376FA4691FAF94AE033EA02F61C3FFEAF
-:106C9000887A998E8B71DC4CB1EF0B1892711E15AE
-:106CA000BDBD16964B5E0F53BEF6AC577AE16956E2
-:106CB0002E5A15A1F278CBCB175376F75A1D0C8EAE
-:106CC000F16FF1EFD579BFB73A59FD9C0D51EAAF9D
-:106CD000EAF55E01E9D957EE3D7FB5DDF7AB7D11F1
-:106CE000367EEC604240BCED15B4059812627D9A88
-:106CF0009FBF197D00AAF07D3CBA88D6615BB08841
-:106D0000E8E76BCD47E237219E36C69AD1CCD9B79A
-:106D100071039D4FF06FDCC8F5A014F77F8FBF6D36
-:106D2000BFF079977C286C96B3FAEDB605FD3C4E22
-:106D3000B271596232076F7F18F5BD12EEAF2C6A3F
-:106D4000A9F6E43539F1910F85E4B620D94D3C4ED2
-:106D5000226B297A7FB184BA227B7DBBC8F5A4441B
-:106D60004FC0ED87D16FE3F7B365C2B13328131C71
-:106D7000CD56F52A941777CF54E400C231D9BE9F7F
-:106D8000C58E43F6EF63427267D0E3B7E7708D6755
-:106D9000A80C21DC5D3D9FEE64FD7C9072F63133E2
-:106DA000487AD23D22F1C7D6727E0E709FF16E17DF
-:106DB000DE73E1F0538B2112FF6E9385B4C0FAD9D4
-:106DC000565E9C7B1ED24F0C776F9AAF8A782E91BD
-:106DD0007D3C8703CCBDE817F7A35F9CAD77C9B1B5
-:106DE000D07191FC7FDEFCEF22CBBBFE629DF7DC15
-:106DF000DD78A6F4B8F39581114D3F9DD1FE5ABDC3
-:106E0000F73F901F968788CEC032A395A3307DD1DF
-:106E1000FE936AE9FC7349C63983076CFBFD61FB8D
-:106E20001C219CBE05506E3D609FBF7E608D18D4B6
-:106E3000195E9EB78ED0BE39BEAEAB9202339ADFDA
-:106E4000935FEDBF536BC4FDB528E5CD13AACCC845
-:106E50000B2AF92BF3AC8F05BD76EADE134103EF65
-:106E6000C34B1F950CD467BF7CC70C927FD66AAE0C
-:106E7000B7A457E53D80E75DF20530F0BDD3AF63C1
-:106E8000BFBE1BCC23BE49CF61DF73985C89742ED3
-:106E90005A85EB05395A630CCF43DF0EDFC2FE572C
-:106EA000F1F5AF2C04BA5FA7300674CE993D379F39
-:106EB0008BFCBF51C498389C41398F725CED7911BD
-:106EC000DFE75E2ED2FD3945CDD67938CFBD73C709
-:106ED0008E45FAD81AE6E75E9A841468086F01E7CF
-:106EE000871D912ECA07BDBB468446A428864B0346
-:106EF000FB5919DC49792C08EF4CA23BD2BB304638
-:106F000081FC685D1FE4FBCE69EB3CF42B4743BD7D
-:106F10009DFB583FE136C5D8C9FAD951E9BDA76EE6
-:106F20005288EF778190E0C4F70321F634B702E589
-:106F30002DB2B9107F33BEB280F6058DEC2A27BE84
-:106F40001FDDBB482C9AC29FC52EFEDD69CBD9B48C
-:106F50009DB7F0B0BD7F38FAC603B6DDB0D5DE37D9
-:106F60008ACC2B1A15A4DB55300DF154B2A6535818
-:106F700099CDBE6FF7CAD54C7E9998C92F29EF39A4
-:106F8000D571AB8A3DDF23C6F99EEF148AC17567C0
-:106F9000FB37E2B92D5026A1DE370312A65BAE0CFB
-:106FA000B6FFE707CDA9A18FA0FF44438914EA9F4C
-:106FB00099FAF745F6BA5C1B48CCC1F588CE5D4E10
-:106FC000793C6B03898BA87F392DA03C9D87ED62AE
-:106FD00059E1A5E4AF11C05BFD51E005D9A0F35C18
-:106FE000B74BCE7DB6DEF35C90717F6DE6FDB4F3FA
-:106FF000FF7827DD4FDB2230450FCB39F6FDB47E1D
-:107000007E3F6D4B84DB5D2D761ED53A1B0FD785F9
-:10701000F87DAF6B6C3A9D1FCA7EFF91E3F74AA1E2
-:107020006CC07AA3B3DF3B861A15F6377F5CF6EFA8
-:10703000A9108F3BCE9F38F4381B701CD6CFACA064
-:10704000B936E4F2AFCC0899EBDDE55B43767E918F
-:107050009C20BDD294F97E581434378666BAF06B02
-:107060003FF31695D379BE53F6793ED66EBB407882
-:1070700095B491E0DDD1FF5B04FD1E9283BF607A81
-:107080005F96F5783F18B5C49C817894A31FED0AEC
-:10709000717B92D1DB263E8F34E5418741BF07EFFC
-:1070A000811887F770EBE85738F6F0BFA2BCBDB87F
-:1070B000A706F5A7B53F90E87EBBB3F0B586D19D96
-:1070C0002B1FC5793FF6837164074F9492F7875C55
-:1070D000F6C7D8557D0AD23BC25FCDE1E7F9D3426E
-:1070E000FA3C6E0F00C5715A6E8A7BF20933ED913E
-:1070F0003CBCE780E48A427A5D265C8E3DE19433B5
-:10710000CF231CB2E908FFF451784F38706556362A
-:1071100025E4AF9990A4E76CD0E9C9EC964E9C07A2
-:10712000E33F1DE16C0C4DB808E7F177C4DB8F42FB
-:1071300033FFF1F0E6D07151F2927E3ACE76FFF550
-:10714000FDA128C9DBBA6311D2FBA37BBF48742D14
-:1071500031BA0EC406F265EAC0CEA30F4327EABDDA
-:1071600045C97A3A177A8AD131F62B69FC1CAB0CE7
-:107170005A02E336528CF3874F2ED5440DE3B29674
-:107180001FF30EAC623050D6A23FD20D6F7938F9A2
-:10719000A61B8FB71FBB87E4EDB581E4095CCFDB8D
-:1071A0004B2C3F6A762E39FC965B0E0B10D691FF66
-:1071B000E69FE6FB65655297911E16304E47BC2F41
-:1071C0008424952F038B9E8B204DCF4FE09546A4B2
-:1071D000C7D9E716BAAE16DDE716FAF3B9CB9D7C30
-:1071E0000E1EA72AB0E9106C3BF5F9E54B1B16B251
-:1071F000F1D9E29B188FFAEA729ECFE39F2DD3F963
-:10720000D582DEEB6B314E04CBB85EE6E441E4D5CB
-:107210007AF5B4B3EEB73AF6FB63D82EF39C9CA391
-:10722000AF65EE5BCE33535FCB0B673F3F39D8BEC4
-:10723000931957A8C37F72FBD5B6AB1339EE7BE326
-:10724000339F87EAFB9AF7BBF2CC0FE3FD4659F771
-:10725000011EEF8DEEFD7DEDB272BA5FCEC094C916
-:107260009EFAAEF9AF4F1AB08313F3729F477F7443
-:10727000A23A77BAC4F0BE38FE5EF3FE7C80256683
-:10728000F7FCD75DF3ECD118B459F484FEF14CDF70
-:1072900087EEFDF76D85CB97167BBC881D1F6B13A2
-:1072A0002D3FF1ABED7FFB4321B7D31DFB3EDB7CD4
-:1072B0009B095FBD61A487C1E6FBD930DF4F472D35
-:1072C00037E8BEFC26FBBEFCA6F14EFE96A1A13E11
-:1072D00079633897DF57102EA1F86A53F71CF2270D
-:1072E000171CF4913F7DD4B2A460B9F6C57BEBB90D
-:1072F000FFF52B4CBFC37C902D4CAFC3F2DECA59B7
-:107300002ADA0BB746A653BC7673BDE1C917719E46
-:10731000781F5DD2E5DF6B4A546918EF6DAE9DAE04
-:10732000A2DD217DB29CCAF279D33BAA183F7F66C9
-:10733000EBD44B0B302E51C6EF23BB8E951B4A98D6
-:107340001D1DE6FBEC21E3F530E2A92AAC3BF4433A
-:10735000EBE85B96347D2817E25A15E6CA38EFC190
-:10736000A62FF69EF4EBB795E44D6136FF43F6BDCC
-:10737000586D4AAA7443199E8B670207FDC42AF709
-:1073800013221D34CF18807B838DDFB9F6B84C20D3
-:10739000894FBBD64F89F3F56B136155B6F5B933F9
-:1073A000CCF59B66CDD486A4234DFED0737F68793F
-:1073B0008CE7E7C7181DB9F8F96C7AE7FC541E4E44
-:1073C00034870B502E42698AE61F26F943EDA481CB
-:1073D0007B2CE361B31DEBFD2CD7CE872EE479D057
-:1073E000EC7D6B0E96E514C977471F6C93B93E3759
-:1073F000527D306FD146D207DF65AC45F6D92737CD
-:1074000092DCDEE853E9FEBFBDF3648A6745CF81B5
-:10741000EBDC768B14B1EFFF8F70BF3CFE4E427AEF
-:1074200032D77BF09C47340474CEA56F3CCF2F6DD0
-:10743000831D35E7107C9334F77E56399EFB19EE99
-:10744000AE0AAE72FB1BE6E4F27C91FDB995BF4734
-:107450003A280BA7AB90352FD0A017F369A08A9FCD
-:107460001F130AF9391B1F182AE7D76A0DEF0D15EC
-:107470002049E7CF065D3FF0DE2FFAB89C6E0C2264
-:10748000DE62DCAF13D92E50D29ED46976E1D99D4D
-:10749000C6DCA53F0813BE1306F277F7AC20D97BF4
-:1074A000EF752B647FBE7713FC06FD49EFF972C0C0
-:1074B000624BF52351FCCD536CBE7D8C597762FE37
-:1074C00097C6BF4FDB2A90BFE9471F06C721BD1BE8
-:1074D0005110F1F72C16337D8227094208E3B3D10E
-:1074E00005D07509B6EF0E13FE7CF19FCE7F7D06A9
-:1074F000ED3F21B102CF6B890FE2FC9F89431EB69D
-:107500009FF1BF5512FAAF1C7DE81E2D7904E19D55
-:107510000DD6AA6ED6FE6E85F3D7DD794A1AE394AE
-:10752000D30B44D243C0174A4F62DF171F78BD1AEE
-:10753000F33B17574CC39A383EADF7442D790CE90D
-:10754000AF5A5B529DCBEA971FD549FE5E1ABF65C5
-:107550003F96671DE3659F9FEBF1A8C7B8CF072C47
-:10756000FE6002CDEBCD30D7679BE3668F290CC957
-:107570005719F7F27ACF173874C0B6751DF3D2E9F0
-:10758000DF3AD145D2270EF89FA0C2B0CF9F38F482
-:10759000600A1F851E7687F9BED086F966B1817CA8
-:1075A000B3365B7F1B69BE59263FE52D92691DDE10
-:1075B00065FA16DEE771369FDC42F77F66F29303C9
-:1075C000E7E6F2BC18CA61876FB4D977925CF65FC0
-:1075D000AFD07DA60E1F39FC332BA79F8FBE82F242
-:1075E0006259585FC853344C70F3C995C3F0D562E3
-:1075F000E8DB1F63E5C53258394C041D9AF3BB9292
-:10760000092E3EC9C4E7E27902BCEA9183BCECC210
-:10761000B7D67F0F70163B79B0753922F3730F0E12
-:107620009FE2EFB1E0F9B176D100DC8F1A73571AFF
-:1076300011364FB936770DF2C3162191427E88CCB0
-:107640007E2B7423C3FB7BA3981689FE437DE553F1
-:10765000C4EFAF84C82EBB7BD66A8A4BBD7753720A
-:1076600022EE2F9B18DE5FA5FD3C3D5AA45CDBDEBD
-:10767000D13C6F428FF36732CEDF83FD3D6D974D76
-:10768000BB5E2FD563EBEB919B07A29C0F0E44F9D9
-:107690003EB549E950911EFA8A54CD9DAF7C897D53
-:1076A000BFF0CD113BAE78BA49C7F8C4CD11DEEEBC
-:1076B000DEFA4ED25736D5EFA1677E6D1A303F2ED7
-:1076C000586AE9A857A87F5E20E03E0BE7F3783BB5
-:1076D000BE6F70E96B9FB2E5B68AF700B179AB8DEA
-:1076E00096EEBE77561585ACF703FD24CAFDBF6A3A
-:1076F00023D07775EFFFA3BC84FC1243F81C961BC4
-:107700003BE87763025DFC7DACC4146E70F51BAB87
-:10771000EDF4EC8FAAD82B933D54079A85C69DDCD7
-:107720005B8D7EB7F6A5C10ECC57CEA423FC7BD5CE
-:10773000450FEA9FAF24BD088E70BDB4BA5825FA34
-:107740006DA95376A05FEF0FB12ACA536FB2F196BD
-:10775000391F8CAB334D8FFC64969FC7D7ADC93CA6
-:10776000BE8E658CAFE313E3EBF8C4F83A7EC7F83E
-:107770003A96BF556F5219E3EC58C6383B9631BE66
-:107780008E658CABE3734FFD2A7AFEA03E45DF9FEA
-:10779000ADAFA3F225B6DC8452FE3B5FED5F544CE7
-:1077A000CC8BFAA1BD3EFBCCA5AB7E8E7E40881A69
-:1077B000B85F070E36BEF213BB4CF75FC78BF3D131
-:1077C0002F093111309ED01ADFC674CC81F905E43F
-:1077D0007B41A778BAB50AF31977460E5D2A33FDC7
-:1077E000A1247E4B551E2BEF8A1C6DC5FCD173F571
-:1077F00086E53B5C653D327DF5D3DA407962D90E92
-:1078000039C8BE3F79F7CBAD28070231AEF77D2FDF
-:10781000F2AB4B1B1849741533C506E558919246D7
-:107820003ABE01D76912CE83EB2D9F80A638E6EFD2
-:107830004DD495E9C87FAC7E17A7FB91D5FF2106F3
-:1078400061669EDD6EA87A62F988EAD1F9DBC1EA49
-:10785000E17761887E5AA049EB61B06FF1F1FDD507
-:107860002AE0FEDF761FE7FBF6007F4EC8E1F4F763
-:107870004EB4EAAE287BDE15E5EBDB1EE0F70EF436
-:107880004D11E9F778A04EF827ECE70B6341C3BC34
-:10789000C7E9538AF351FF3F62D3C3A48911BE6F76
-:1078A000FFB34AFBF665139F6CCE63E549FF6A1888
-:1078B000B80F6F012388F7B65A5B45CA23FA66F9F9
-:1078C00039794B58F50B667E270FF5DEE9B6DC49B2
-:1078D000DBF64943CB8D13D13E78EF252EF78EDBB7
-:1078E000E3ECF0F5A4683D6786E91C054007E9254F
-:1078F0000D7199F2BFC431FCA9F8B46BE85ECC16E7
-:1079000085EE6152FE345B257FEA077EFB1EE21E98
-:10791000D257944052CB65EF3B2C91FC0F4D5A301F
-:107920008DF7616D094FA7DF65B0CA648A876D293D
-:10793000E3719D50E42ABAEFEA2BDD01AADF12566B
-:10794000290F385DB6FB40550C9FA286FB7EDA5CA2
-:107950004AF7535A9AA8513E31FB177D5F13233FD4
-:107960000F9D2BC6EF6B781CC237FA20959B3EA566
-:1079700051FF60E7ED93EA25E2EF4424BABDF7CD6D
-:10798000F6FDF442F483ACE6E752A66A4BBB9F6374
-:10799000DF9B4D3551CCF8A1457B776F08CB2B8011
-:1079A000E2A4A129AF3786B0FE0D9AC1F3B0F83931
-:1079B00008B0EF376E2E5BD6FD1FD8FFF2104C32A9
-:1079C000B07EB58AFC0ACDF002DE475568EB33A1E4
-:1079D000DCE902EA632DB574ED2683CF7B7EA03906
-:1079E000EF7215E9465A9C47E3B480A9627DAB5615
-:1079F000A67DB130AC76A1DFA0D0F63B38F2203FB7
-:107A0000E53A47C0FE37768DEC396730FA066FB934
-:107A100020E37EDD0B6DFAC9C45BE63CF363CFE483
-:107A2000223CF96BE844C459F0DF1B9BBE04E735E8
-:107A300046DB2BEC28279346D3F17E714835B8F30B
-:107A400030FE5A78A79635F7203D4CD565D0195EA3
-:107A50002E84BE46EC7F8B4DFFED45DEFDF9886D33
-:107A6000D7303EFD7C7426C63344B05CFD63BCC396
-:107A700072C1734E7B9EA73CA963ACA7FEE4EDC523
-:107A80009EEFE7A5CFF77CBF60D7744F794AE75CDC
-:107A90004FFD0BF75479CAD3BA2EF7D49F7160A962
-:107AA000A73CB3E71A4FFDD9AFACF47C9FD3BBDA48
-:107AB000F3FDA2DF6DF0942FEEBBC353DFD1EB33A8
-:107AC000F7CDEBA37F993E8FBFFBE33E4F9C692F21
-:107AD0009C756FCE9F9B748CFF4194DF932BE3FECC
-:107AE000CECA1BBEC8ED2E75BEA1A3BCB9DAA6CB0B
-:107AF000D579E63A94AF955195F60939CCEBC9E1C1
-:107B00004B491F99B09DC9A919648FF57FC7387477
-:107B10007BBD35BFC4E5AF0A681D80F95F95D11AFA
-:107B2000BA2FD0692F6B26605EDCD5519DDF73C301
-:107B3000AC59BA074067ED5DF362F61F5D1DD1C712
-:107B4000EC43D4EBFBED3F3987E2BECCFE23FBD008
-:107B500008727B104E4BF4DDF88A40F7F333FB8E4E
-:107B6000ECC367C2CC3E9C86F658EF1694437D3F2B
-:107B700093298EC8FEC8FE2B67F6DFE65CB71FBCF4
-:107B8000B7089F69D0C6E2B35BE9124717913D7809
-:107B90001FD2F36736BEB40AFB9D52CEEFD56B1FE2
-:107BA000551B473DB9BDA893F8A4AF48E6FB909C90
-:107BB0002875FBF77E6CAF7748FD26D9A16C1D4870
-:107BC0002E3BEBB045E84DE3FD85D61783E4EF9EF1
-:107BD000F05BFF11E437B5581D87F97FC63EC5C479
-:107BE000F1EEB5F15CAC4DABC29F792C892FD98BEE
-:107BF000CF7375A68FB06769E93D7BF1F974949FE7
-:107C00005F3DDF78BA0A658C3A9FFBADE5A94ABAB9
-:107C100051407F3383238BDDD1EF9F886EE7F7FDE3
-:107C200094C86F20FDA1D67F864DA1324FA5B871B3
-:107C300000E942A027D153400ED1FE12C043A858FC
-:107C4000AE10D218EA42FD15F3412BF3B6131D38DE
-:107C50007A2DEABB496E1FFF18F11AABF5AE7F48CB
-:107C6000FD16E1A9D93EEFDC9EAB1FAC62E3B6176F
-:107C700014E7A1CF16FD294B5CF2679FBDEF3E9242
-:107C8000237AE4CF6CCC519839A017317ED82E9E40
-:107C900083F02628BE1E3828913D1FB8B3837E5F2F
-:107CA00035A0593A90FE6FE9D86F75F172F2FFFD79
-:107CB0004F6C3AE9C181BA1F65C55BA0570273C614
-:107CC000E0F88C9EFB00E903302AA8E33E5B170B2B
-:107CD0009A3BB2D8079F8D70FFD9A6098E3F3341DA
-:107CE000E75D5BD0DF16C6AD4D15314FE7D69F156A
-:107CF000EC74DF07716B01F74F0E367E80D999491E
-:107D0000177C9B58BF28C75B4E2FA9A1FB54719BC2
-:107D100029C7F3A0653BC84F6FDB4B9FB5F17A7362
-:107D200084E37182020B76A03CC963FA114369A512
-:107D3000ED5771FC2FF11C1ED7372C90B85FCEE7A2
-:107D4000EC5BE219BC8746075D99651FF127159822
-:107D5000EF6BECFFBAF15CE039EDAE7D0E703FF0F9
-:107D600096276FF796CF4B7BCB4C8B7E19F58065B2
-:107D700000DCAFB1CBFB3D0CA60FE328639DFBF30A
-:107D800013FC9CA0CA2040FA2EEB4C777F8DCD2FA0
-:107D9000E1DC7399715FFE94DD69D25FAEB07FCF95
-:107DA00023F31EF7B1F8FB1E53695E9E7D74BA4F34
-:107DB000227F03FA890C979F68A2A67BEC2AC7DF73
-:107DC0009329D783C7EE01F685ECF5A41FEF43D5C1
-:107DD000CAD0AFD05A78D76F8F970FF8575AE5D4DB
-:107DE0009BC7C97FC9F4AF18F77FA05FFAD69FDDA4
-:107DF000F6DFC75D7ECA77A2C9A9E8CFB87F226F38
-:107E0000EFDC97EA9CE77BB7467E5ED0391C4917CA
-:107E10001CB7975A977175253D06FD438E7FC5F1B6
-:107E2000235C9367DE857CB7C53892DAC7FAADFA72
-:107E3000951FB09F85D2C103F528EFC6CB942FA222
-:107E4000CD5EF34810FD99F89D95AB8AF4D1C41F1F
-:107E50002FFAC89FD066F3BD732ED5F1C77CC2B68A
-:107E6000032ECB71F4282B689FC708A29E7CC12EDD
-:107E7000B6869EFD90FB031DBFDF944EEFF7F3F136
-:107E80008837F93D77507E933187E7378D5A9EDEEC
-:107E90008BEB7CA1BDCE18B7AA9C35103F1DBD222F
-:107EA000BD17F5D0A9769E52D98BCFD34FF9825406
-:107EB00028217D9D8FF949AC9DB15FF69C0719057E
-:107EC00002E5F98C3A2A1969D6CFD467BDDFCBC059
-:107ED000552E42F8BCE5CCB81453B7DEB95EC0DF0E
-:107EE000454D0928CFB6AE6036022BAFCAB1F38B31
-:107EF000CE8573916E174A6103EFCDDBF00B89F2EB
-:107F00008BFDC727FF12E3A3F012CFA7D4CEE1F178
-:107F100056EDA792C12420682198362D3C10C7FA4F
-:107F2000EA1903EFD0EFF78F3DCED61DF7A12798C2
-:107F3000DD5FE2433B5EA37227B3FBB1FC0CB3FBF6
-:107F4000F1B99BD9FDF8FEBBCCEEC7F21E66F7E394
-:107F5000F307CCEEC7F7CF32BB1FCBFB732BC91F88
-:107F6000DF83F7194DC6DFB5DD4DF98C6DAA4F43A0
-:107F7000FAC994679595B7AACB187E378717521C14
-:107F8000A56A21CFA76FCD5948F674BF9F2EC3CFE6
-:107F900039E0B7EB151CBF1D1E6D8EDBF66CBFFF05
-:107FA0003369D0BD05C3F7633AFD90FFF4AC7E6C36
-:107FB0003FEADB5FFCF5D79BD8A7B533B7B5078B96
-:107FC000F13C4F8A7FB7F30A337F4F6BEDEE06CA61
-:107FD000F353C61C4DE1BAEE2E0F93BE81BFB7849A
-:107FE000723BD34E74ECC34C7DDC7966EE87997995
-:107FF00030115B2F192E2FE36E5F8AE2D656039362
-:108000002FB85FD4A7E7BFEE3BDB6F3B56CBCB3837
-:108010007FCCF3AEFC07783E5E3B2435F7FC9D73C6
-:108020000F64F31573FFA1DB6F1B2C49D3BD0CC18B
-:10803000B049FAA2C0F448D22BB524C5015B07F9B8
-:10804000DDEC376D39D130E62ADAEF5B5FF491BEB3
-:10805000556DE7BF358D51A9DC3466569CF2262359
-:10806000B3D4DE2CFD6C88140FB9BF4A6CFFD787E0
-:10807000D8FF253F3FEFD5B4778E8AE7A2DAC32B2E
-:108080007BD06E6F8FC7C8FFDF3D6696E7DE712934
-:108090005E41F7544861AE674B7195F46C19E75F28
-:1080A0003650DFA9B72F87EF238CCDC98F190877FA
-:1080B000503DBF9C30D1DFE28FF1FC62BFC6E3854B
-:1080C000C11211D42CE7309ECDE1E7ACDACB921A85
-:1080D000FA75DAE3329DE768D7A70F166F25BDE87A
-:1080E0008F3982877E9B6CBF43D32A85F4C2445D5F
-:1080F000AE569D4FE711FA90CFDBC38D2AC65F9530
-:1081000031E543F6AB68BCDFFF03837E3D1F008093
-:10811000000000001F8B080000000000000BCD7D58
-:108120000D6014D5B5F09D9DD99F24BBC924BB9B80
-:10813000ECE68F09241A34E026243168C449083C4F
-:10814000F4212E021A5A2A1B1045050968EB6AB55C
-:10815000D9908010A4067F2A4F2CDD58B0F6ABD6FC
-:1081600068E92BAF455E50E4F9839AAA55B0A8019F
-:10817000ACD53EB511A4A5EAFBF8CE397726D9993E
-:10818000CC26417DEF7BD832DC99FB73EEB9E7FF5B
-:108190009E7BF7D429F87321636D7B52545609CF27
-:1081A000A58E784A1163E1687976C324C6BE951519
-:1081B000FE22C3CF98C3B3488EB919B333A676C392
-:1081C000F394D64E7F7A658131A827CABF98F29E74
-:1081D00077E877FD29A66F661168CF8AA5F7FB5C63
-:1081E0008CD914269CB24199B9E5F7CF66F4E7948F
-:1081F000887FF706C29EE4FD785CBF9CF2DEA4A1F6
-:10820000ED9697F5394485B1F5DB3AC30CCA9F0B5F
-:1082100050A842B8636A1ECCEB869D2B59A48CB142
-:108220008D52AF4B0638367E292C0C970DED7F31E1
-:10823000CEA70A7B95620827FCB19D3A07FE5698A7
-:10824000E2A8662C0FDF8CC527FF0EA3EC3905FDD5
-:1082500097F740B9548307FE3FE93963B9AAD75865
-:108260003EF780B1CC58C81E9EC0D8EB2DD0E999FE
-:108270008CCD39F4E12196CED8DC58E8D9A77C8C96
-:10828000E5AAAE705C666C1E0B3DFB3694F31AD308
-:10829000584F0806B7B1A5B82E30CD378B01BE4672
-:1082A00046B0B2BCA5A98CB906FB9F2F67D23A3560
-:1082B000F635CD641319FBE1AD6D8C413FB17A21E8
-:1082C000BE1DE09FDDB06DF638783E50692B781802
-:1082D0001B45ECEFE1FC5CD0D929986FA66DE598C1
-:1082E000B1503F3C354D68837A3F3CEFACF5C5500B
-:1082F000EE9D5E1242BC03BEDE1B980FE07F5E98CF
-:10830000B7D7C77FA5F2D8DC71F0DC52F9E46C7CFA
-:10831000CE49AC0FFDCDAAE96A75407F972E532A4E
-:10832000B0BF7083B17D5EADB10C90F3F9C0BFBC3E
-:108330005943E11D091EF3F87A7F0FB428847FF6B4
-:1083400025D003E0338C9FA07D58EA974280E7DC7C
-:108350005A418D03DDE4A982DA65C10F1D1A3F98E9
-:10836000F12FC63218F259FD3C31DE0155725D76AF
-:10837000C27FEE4C21AEC0F8B94BFB7B4E41F97287
-:10838000973D2EC2F7ACCC6E01BF3FB08CB1CE2270
-:10839000022FBD2E617D1F70ADB117C2F7794191DB
-:1083A000D9800E58ED381A8FE0184BF838C2F1E139
-:1083B000227CE42D0B3DFB6318FF8A1AA72C42FD9B
-:1083C0002B1AF9771DBE8D12D0197CDF0874162385
-:1083D0003A938E24E267CEA1E5CB911EE798DE1793
-:1083E000435D9CEFC7930F9C5108702D173A67A40B
-:1083F000012829F666C670A1018348D73A3FEA787A
-:108400005ABEA395F83181CFECA7909FF1DFD984B4
-:108410001AE2B3A75DBF92516EECCEECDBC2808452
-:10842000B7CA2CD690CFD8BFA7F69F2D4079BB7C7A
-:10843000F9BA7517C0F794FE5FB072C69CCE6FCFC5
-:108440009891504E4DBD86CA3E6D1C98428CAFF738
-:10845000C0B8441FFF2973F836A86C930865C92675
-:108460006F0A150DB6CBC276C230EDC26C9364D1E3
-:10847000CEADB7033CAD85F54BD5E695AA7DB76982
-:10848000F0248E2F21DE64C52DC07A48D32519E94A
-:10849000E5EBC2913DD2BC236C937DDCD0760076B7
-:1084A000AB0EBFCD1AFE387E4F1CDF3E0CFCDF3416
-:1084B0003E46EACFA17D3F6DF8A0FAEAECE4F34531
-:1084C000B8ECA8AF14C56D4BE8E7AE3DFF78F11CE2
-:1084D000205E693E0BA5401F925D954340E765F223
-:1084E000BD2EEC5CCA6C9023C00FEBA1ACC2FBF5B7
-:1084F000DD9D2E05DE9715DFBD0E89BEAC2795A14B
-:108500003C98C0E4CC47A1DF09B2C47A70D52ED81C
-:108510006B4B8332BB84854AA0DF8C3DA9244F324C
-:108520008BCEFBA900E36666BA546C9F9659FD5347
-:1085300046F4C11429011F6975AFD7A7215CB3594F
-:1085400008595112E2AC0E996C3CF0109433A76DAF
-:10855000630D50AEF8D8A388C8D312D7771DD81EA4
-:10856000F5743BDB87FA25A8C99F750E7913E98F4F
-:10857000EB2486FA236DC2BD02C2F3007425025FAC
-:10858000969565CD6E8072D97E5B4851703E9D4256
-:1085900021CE272092DED2F1A9CB918A4F7B38D30E
-:1085A0008F67F1ED007FBB3DDE83F22A36F90A7951
-:1085B0003BC0937B5582BCC6BFFA010708EF4B97BF
-:1085C0006DEF2842FA96DE4BEC2FE3D3780FCA33D7
-:1085D00056D718C6F6BE999241FEA76AF22CD5A4CA
-:1085E000075AB2EC24CF747DC054499161DE8236C3
-:1085F0006FF68330E903270BB91C64AF2C203B4492
-:10860000607DC2A934983F5644B80BF83C86B4AF9D
-:10861000E6ED5920E4423BC799DADC8CF5E163567C
-:108620002B2057B82E5545FD2C38982B5801F3B602
-:10863000B14837D049ABC0242C0F8ED7C3703CA7AC
-:108640002BAD1DEDAEA75D6D36C45FDB73A03F6043
-:108650001E77D85923DA056D72C89505EDA39AFDEA
-:10866000B6AA7C6C0E963380B67BD16E90C232D2A5
-:10867000E52A7F710E83F7E9DEBE6FA39CFDA7CCD0
-:108680005FCF7015801CAD873AE781DCDFF4F8BA64
-:10869000582D8C77328F2909769E536A66684F3938
-:1086A0004F161ADEF7B4C08CCE1C2CAB6E5B038E5B
-:1086B000735DA64278AD63723BB6AB03642809EBE9
-:1086C000E23C1964CA24ABFEF30DEF7BC04E529C12
-:1086D000A3E93F8D29A589FD8F4BD2FF19A6FE6521
-:1086E000CBFE07FBF51AFA5D2331B2A3633E37AD2B
-:1086F000BBD92E589D59BF2213ED51276BEEB6B052
-:108700003B5B336D04F71D81E65E15DAD733607C81
-:10871000A0930BBF3C2232B26760A5805E58BED4E6
-:108720003F40C763B11EA75F5B4C6028972E94EC57
-:10873000063E99C28C65B35D54026B8DE3DA3C95BD
-:10874000BD483FABFCA98AD3027EFDD9DBC2A6148B
-:1087500097C07C53C34B19F0F10399FB5C6B02503B
-:108760004EE774F248E61F67A0BFD02B70FA5BE3B8
-:10877000B3115EC2F5395D6242BF61072B41B91882
-:1087800046FA76737870FC5E7FFE431D16E383D84D
-:1087900035D80FB355614A71C2BC7A353B7860BC9D
-:1087A000A9795DC80703E33959158D2702FE13C760
-:1087B000CBFE6AE3FD1EE7573638DEECE9C6F9CD9D
-:1087C00076C834BFD91AFFEAE3FD1EE757F415C691
-:1087D000C3F9258EF74FC6F9CD76CA34BFD922A783
-:1087E000AF81F1B2BFDA78BD2DA56407DFE100F9F2
-:1087F0000474925ABEC3350EC6BDC365970565B0F5
-:108800005D5DDD8DAEB9A87BDD53A7FB619CFA6988
-:108810005039177B993ABDAE98B14D02A78BFFDC5A
-:10882000F4E7754817C767AE2A257DA2D9D79762A6
-:1088300055D0C7974A1CDE59F9EE786B021E1F000F
-:1088400039A2021C0F02BFABC08F5B812FB11C6F1E
-:1088500009D0F321B0D7F1B90DE0C5EF0FB784A867
-:10886000FC484B0D3DF57E4A6BB8DD3EBED6DA6E58
-:108870003F238BFB7D9B82F2FCAB50AFD5A586508E
-:108880002FB29AF3999A6857B3E6A753E0FBC6CB89
-:108890005939EAC6333673B87D0DD964B7A796EF58
-:1088A000ED6D81F21D925D41BD7C87C26658F9CDA8
-:1088B00045A867AAD05EE5EDD9F9DC0FF385FBF694
-:1088C000A2DE9B83763AE0D53FB76F2FFA7F978180
-:1088D0005D4E7A991DDEFB367C7F1DFCBF0E2C8B16
-:1088E0006E264379D61C3F8D0F7FD2EBB2D17EE747
-:1088F0007FEE99798CFC8A700AD70B3E36FBD93D06
-:10890000086FC8A1C4A93F765F18F940B52B1D2494
-:108910000AC276D4D37ED4D3F0BDEEB093D910BEC4
-:10892000690E926B73E71AFD864D293D32DA3F9B43
-:10893000CA7DAC15FABF6CA6F1BBD3C9F92D6CF298
-:108940001B6699CA2021B9DF2D2EC8407BFF0E7C03
-:10895000357928DEA2875AEFD89B40A779591E1F88
-:10896000C501CE6067A03C3BC1CAEE6AC08FF95911
-:1089700064AC98DBFFBD2576C75E40FD2B28F7AAC7
-:1089800090BEB9DC18CA1F1C9EC95ABD075A7AA7E7
-:10899000BC5732085FAE1417500FE42D85F709F36A
-:1089A000957C7101FD1D263E5A8EFE8D791E0F08A5
-:1089B0008F0699C578FA339749EF235E7029519E47
-:1089C0009BE73B79C87C6B5F296656FCA46C427BB5
-:1089D0006ED67362A85519C4873EFFFF69BE3AAAD6
-:1089E000E919A6FA580FD0CB2B40EF1DDC8F616838
-:1089F000A7EAF40A15C87EBAF452F88E74A1AA0543
-:108A000088CF57C6F66FBB1ADB81EC68437F57B738
-:108A1000837A0EDAD00EFAAAFD5E7A9D83EC2DC61B
-:108A20001AE4F74B07FB4BB63ED8EFFB09FA73C0CD
-:108A30004EC43FD59AE843185B4301B2076E01FB71
-:108A400018FDFD68C387523AFF7E24C14EC53F47DB
-:108A500012FA6BDBF3734101B8BA5ABAA7BC674F7D
-:108A600090174B65DB1AB4E75AE302C5217AA01EC2
-:108A7000D80363972AB676C0FF55D80FD2A749AE60
-:108A80008F6D877E12ED94DAB9F2A3400FED65F594
-:108A90009D2178AEDFCCE3657AFD81B8992F46FE43
-:108AA000B99D353301E074A4FCE0277D301FB54D3E
-:108AB000622953A06CE7F60E7BDB4372417437FFEB
-:108AC0000CBF076220B770DEF5CD8F63396663E1B6
-:108AD0003678DE9FC6DB472597EC0C619CA47D06AB
-:108AE0004E3F3318B92F0BF0B7263B95E4A0E31D9A
-:108AF000CF4328A71C99154BD1EE5910FD7E18E3E2
-:108B000091B2972D0C5BD0D702CD7E8867F1B8CBA0
-:108B1000217B4F4126C05D17AC8F63BF43EA477F7F
-:108B200040FD4D11ADEDB09D5A3F5B6CD672E10931
-:108B3000EDFB15CB9FFCF061984F5AB13B84E4B636
-:108B4000FE1CB643B00DADBFCB1FE94E8423A55824
-:108B500096280ECABA27A33DB7FE8B07BB1F079402
-:108B6000677DE126399B257AE24291A1FDCEACAA30
-:108B7000A1ED77FFE38D00AECFEE1446FA95B11765
-:108B80002F427F72E34099C5048C73666AE5D8234F
-:108B900017A986F2E28BEAB08CB40B4439F99EEF48
-:108BA000AE8F617B819759EC7BBCBE9DD7CFD1BE88
-:108BB0004FB9F8A39FDE85FAA0DA417EE846CD0ED4
-:108BC000D2E13BDF2B12FD9CEF1D1E8F0735B9E074
-:108BD0001A3D1E0F5AE17177507D0BDFA7B06E0171
-:108BE000E938E50BD74DD8FE5F5A58F82A807D8BBF
-:108BF000B2E3E77729D4FEB0151ECF0AAA47B0BD6D
-:108C00006BF9919FDE0570787438CE65372581E366
-:108C10002FC3ADE78E6C2EE7E6F9B8DEC8D2EC4D77
-:108C200087A337301B9E72E58F6E9441DEAC2DEA30
-:108C30006EB48A3F9FF0DAA85D6692787B8697E3F0
-:108C40006D574EF87384A35D7ED285E3A70A2C8C02
-:108C5000F537D4F43121A1DFB37D7C1D006E9B1765
-:108C6000DAA54E662AD2998779E20CE8CC53C9E19D
-:108C7000DF10789D29D0CE530A4F37BEEF23FE4731
-:108C800097830B351074507668F491714FC745483F
-:108C90000F59A24E6F791D482F0E9B5E3FEF622C3D
-:108CA0007765F172B92FAF23960F7AC6016D502EFA
-:108CB000E43AC8DE31CF2F4783B7C3AFFABD7E0B8E
-:108CC0007C3AFB689D364E708462B0AE536CBD8DAD
-:108CD0008BF1DBC56EB2D7E07D633C61FED3353AE4
-:108CE0009CEEE5F6D6C67FB81AE316EB918C4E27BC
-:108CF0007A4F9B4E277AADE9F41CC47F029D7EC655
-:108D0000ACE9B4DAAA3DD0E9B956F8309745A66E79
-:108D10006E0200A5CFA73F72176AAB7FAEDDFC38AD
-:108D20003CA77CE196BC50473C83919D687371F9E8
-:108D30003E28F723D3B07F496EA6F7A23B4CFB3504
-:108D40002F65F1FE87F47B6EF566945BA3E8378CA4
-:108D5000F336F73BC6CBE19D72B13B12B7C0FB497E
-:108D6000AFC4FD521F1F3F19BF94FAB8DF9C945F38
-:108D700074FACF0947108E91F8E5C2417E593A3A0C
-:108D80007ED941FC9256C6F9252D09BFB09893F8BB
-:108D9000636D112FDF728F8FF861807F622546FE31
-:108DA000899518F867DABD2554DFDC3E1DE76D8133
-:108DB0009798579F47B805E7A19E2DB78B646FF42E
-:108DC0003194535DAC7F8F13F9B056086D87B7B3FC
-:108DD00062BD0D2E05BFF7B2D9607FACD3E87E2B04
-:108DE000C283FE50B516CF927AD9659EA17CECA9BC
-:108DF000EC298D24E0BF40C3E3E5BEF05D387E176B
-:108E0000EB1B8F7669B275BA5783F7A6807AAF15D8
-:108E10009D8FA47776A2DEF1E393C39DF585AB1910
-:108E2000E58099CFA7DCF0DB0F1F1EA69F5F6B705C
-:108E30003CA63D4F83EF1FF35AE9E9A0FA4B13DF3D
-:108E4000570A632DF9FED756ED81EFFFD50A1F5F54
-:108E500083CF9FB6E2F307BDBCFF91F02CF9389E9B
-:108E600025DFD7C3F3116D9DDE3A7D3CBF9504CF5E
-:108E70007FF4FA4785E72349E4EB512FC1618BE189
-:108E8000BE00F23BFAEFEBCE8DF5E37EA8051CFFAA
-:108E900099D88F4BE1FD8069FF9900743EE5F37529
-:108EA000A188055F42BB6389F0EBEDEEF5CA9A1F1E
-:108EB000A1AC44BB7ACB3FBB693F01F4E0DFBCDF30
-:108EC000AC9CB7F92CE4F1141B974397DF73783D02
-:108ED000C669BE46FFE956FD3FAFD1D748FABF2865
-:108EE00041FF633F6679D7C5783CA5C31FC9F71119
-:108EF000BEFA2E42F9B4F5D62C01FDBA7CB5474036
-:108F0000FBDFAFE9978D5EEECFE8EDB64A3D828498
-:108F1000F59B65212618FA3B63B8FECC70007CE314
-:108F200011BECB7DEA59F8BCD73B60EF9D963D540E
-:108F30001D502BB03DC8E94A1C5F3DD328A7F579E9
-:108F4000D8C2DDAC0FF50BB8DF710BBAF26BFA12B9
-:108F5000FAB980FAD1E47D954FA72BDEDFE9EA1B51
-:108F6000806FBA06DF0C7C9AE133E36524386F46E4
-:108F700038797F9725C299AC3FDDBFD6D789F46990
-:108F8000425C67E1A0BEBE12FB73ADB1C5986F90A5
-:108F90007F757D0D922915FBDFE2E071D42DCBEEBC
-:108FA000AEC37C83AEDBE4724449EE52AEE7946517
-:108FB000851457BD56EBD70CFF407B47F7F8496542
-:108FC00034EE721CF7C25AD683722303ED048A3F33
-:108FD000C812C617B29C9D018CCBAE173A1B17A1C5
-:108FE0001EBDC84DFA9605E65AC6A7F4A71E7FD245
-:108FF000E7CD029523D46FA5FA725A6733DA49A3F5
-:10900000AEEFECB4B4AB7EA8D95530BFF5C3E235B2
-:10901000E0A3F8968EDFA1E3F0F5AB0B370B88EFFA
-:10902000D4321812583235DC499BADB6E238EB43E6
-:10903000FBA914E885FA7BDD32EE37D8DF5A1DAE86
-:1090400007911EBF2E5C7ABDE4E3F17AB87F46F14A
-:109050000E37975BF401CAC79EF35AEE1FE8CF3B69
-:109060005A645502FD734C5632305E7887A6071954
-:109070000B052EF3FCF7D71B9C479CC73B4DF5A374
-:109080008CD33D0BB8C8BEC3307C22DDBCE6E3FE0A
-:10909000684776F8392E1F4321A46B28BF80F867F4
-:1090A0002E287BA8BC9FCAF240F965AA1FE0F5995B
-:1090B0002C8F0ACFD0EE0FD44E1AE8E74DEAD73DF9
-:1090C00030EE41FAEE1B28FF91BEE7F3FAA31D270D
-:1090D000615DF9FC7B459AFF67929A81FBA39747F4
-:1090E00017539C687EF45A7AAE6B91EB301EF77280
-:1090F0004B7F7B3B3C2F9FBF5846BB7FFE927B68DC
-:10910000FF5EEFFF52F42B90DF156906D94545B697
-:10911000F036F720BF0DC2D1AEE599F535201DB967
-:1091200054D6DF510EED6B3E6D6F37E4397552FE4C
-:109130004C8A227D9E1857D7E5E0C70EF573DFE90C
-:10914000D1B169BE8CED85F13F7317C76344D7F584
-:10915000B215BFE8F34ED6BF3EEF647246C79FFE1E
-:109160007E7D7185CCF37FE206BCA4943450BECFE3
-:10917000A58206A7C7A5F11BAF370BC679B28CE84D
-:109180004341FA9DA5F97166BDA08FFBB12352E45E
-:10919000F7E37E0363B75558E07794783BD0B23459
-:1091A000DC604779DC9D42FBF74CA638BF5EAF31EF
-:1091B000C9FC2FF0733DC29C2ACD67C3ED1971B471
-:1091C0003B3634FD5AC6E04ADA84CFAA62F814FA74
-:1091D0004F2C42F972BB87F2311A9B4E54B526F4DC
-:1091E000BFF0997F7361BCB771C26A3FC65D16322A
-:1091F000E9B3C47C07F3B88DD11B886E63AD42A37D
-:1092000095BFF56636E7EB85982223527F4712F724
-:10921000919B940A07C6279A62C6FD1CD0900EA4A3
-:109220008FC5EBCCEF13F67344EC9FD1BC63B899B8
-:10923000877A6F8D8DE86D0BE00DFDC0425097F879
-:109240007C333B4BE3C75EC2E77F373C6F66CB7C2A
-:10925000DFCDC562695983749313E964A89F3C9577
-:1092600002ED6FFA3C7A7E4437E9A97BDD7A19F486
-:1092700016E03F5CA6D939C5FCBB0DCBE8FFA4F5D1
-:10928000EEB5011FAFB9EFE98B03E3A1BFB248C050
-:109290002653F905C98FF6172FB3D8D32FEC257BAA
-:1092A000563E4B0801FFB7EF7EE1B902F2E7357B8E
-:1092B0006CF70B648FE965C67A18CCA72B75A0AC48
-:1092C000BA02501E3B508E6179AB66C7AFB96FF7DB
-:1092D0000BED649F8463FE043D59C7787CF99BD6EF
-:1092E0008F5D81AB3A319F28566C237F2FD5C48F79
-:1092F0008FFA1D54AF28277237C233EBB67E09E3CD
-:109300000D8EE0EB3E9403638A8FA96381FEC7D480
-:10931000F2341956CAC7ED2A5E45764397B62EF049
-:10932000BFD5A8F706D7A7D7B43E7C3DC295BDB43C
-:109330003E9EB25E5A2F1B9629EEC7F7E32FA9E493
-:10934000F686ECE4FB0ADBFD9C1F76F8B97FBBC315
-:10935000CFFDD38CE2BB29BE9332C346F533B4A70D
-:10936000598EEFF04B9A3CE7F8D81D8C74FB13EC48
-:1093700056781F2EAD44F9E6CBC27DD6BA62E926F7
-:10938000A4E79F68FE29ACD35DB44E45BED4085F08
-:10939000B7DFF8FD16EB563ABA757BA32542F22AE1
-:1093A000D9BA5D3E5F0C5BC5DD5ED0F0F049E39F4E
-:1093B0007E84D359EEEA77E03ECCFAE24D86BC6A71
-:1093C000D78ED93D980BADE755AF4E4BAF45B96D34
-:1093D0001EF78D2FFFC387F89DF90FA7A57CFC54BE
-:1093E000938FAFB734523B586045CA2639C078DEF8
-:1093F000CB409E9870CA49D37B03F3D0AE24D66786
-:109400006C6EF830ED572F0A880CF7C71732635E81
-:10941000198BEA79C13C0FF60D095C5340E11B3111
-:10942000210498624DD26C5DAE18F2C3E6CD9DBDAD
-:109430000FF7E1176BFBF0205F0CDF9798F2C6AED9
-:10944000686C0A3768DF8FD3DF71C2D35C85DB8D30
-:1094500073DD6ED2AFF3C2F3C30D09FB716FFE97DC
-:109460006899877E41B68E9770B8A164285E16858C
-:109470000587AC8C8C1F333EEA248EAF260D5F66C9
-:10948000FC98F1B078EE6C5A7FF3FCDF7085093FF1
-:109490006F007E305FD88C0FC6229720DDBE395F0B
-:1094A00064681F4F1767DA314F60F16C81617ED1BC
-:1094B00012164AE7F9C1EAAC6909F09AF168C6D711
-:1094C000E2A758A807FA5D7C9F87D6EF550D3F624B
-:1094D000CF5F695E619857079FD7119EBF2AD3BCA3
-:1094E0002E53CB9FF5C1F7483B485BC54A8FF0F937
-:1094F0002C82F974C843F5C90956DB8C74B2C49444
-:10950000B76086CF0CFF4C94839387EEE357646B70
-:10951000FBF8135948DBC7CFA0630D21FFB0790BCF
-:10952000837CCEE96B6174F6C078D8AFC022036546
-:1095300019F03BF379EFC679F0EF550151C13CC109
-:10954000D9F3C7ADC1F9875938A3A708EDFD7E3B14
-:10955000CA91CB1898B1D0EE429824EADB70430A46
-:1095600095F57E8F757E6A273D1E61CDDB69FF5DB7
-:10957000C9983B21B97C591570D078663B656679EE
-:109580004906CA0B333E743CCD43BCA4115E269EF3
-:109590000E5E5E445D85FE2CC6D1601DFBAF65ECA2
-:1095A000A1F2C1FD6396AF727B329BD1FEFFB5D9AC
-:1095B000999ADDD14C7187059A5E3864678D4FB8F2
-:1095C000F93E7245827CFC56B0EEDAEC043B55DF86
-:1095D0004776B33EC2DF952E778F3891E8EEA30130
-:1095E000FA20F9A5E76B46285F53CC58A6505C2CAF
-:1095F0002D7D22CB00BB98F179831F7353B61FDFFB
-:1096000017C6D10898F9FC4FD7CD5306D76DFD5535
-:10961000DB3B511EA72CF9558C3A57783E479AB63A
-:109620006E75DABA0DD8D1A5F03E01BFC73A353B09
-:10963000AC548BE3E31F281F2B56E3C3F9AFFA3A70
-:10964000A69482FF61C823EC247CEBEB094E443FD7
-:10965000F265242051CEB08DB9C83F8EDCC2F33103
-:109660001632652BE6072D8CDA8F25F613094A048E
-:1096700047647D8A163709513F8B82BC1F56CAFD4D
-:10968000BC01BA8F41FB84FC479B0B4C496C9FC9C2
-:1096900042E83F417FD9A8EFD9BA8471C60E1D3781
-:1096A000597FE676A2B67F2B3A43A150829CDEAE6C
-:1096B000D9CFC70295DDB6B1C9F1B7C8E555A584C4
-:1096C000BCD8234157A3555C4CEF4FD7DF0376221C
-:1096D000BBE6C5443BD1ED687AF1B90B12EC44D638
-:1096E000F422EEFB7F553BF1E5ECA617DB617E7FB4
-:1096F0007FFB9F287FFC5833084CC0A3373A951D49
-:10970000F5A27C90497F1536824785C9DF92321ECB
-:10971000E93D259AA74A09F9B26F662B04BFB758ED
-:10972000A5FD3268DA8DAEB8570A0988B7BBB5B85F
-:109730001910EEF8D99EC4767CDEFA784E974C70FC
-:1097400038F4F158A895F2EB6732D2237A1E88CE0E
-:10975000D77A3F47B38DF1BA51F0F3D16CFF507E09
-:1097600016C5E6776F4739F1A2487ED87702B7D0A1
-:109770007B733CE0E36C6E1F8E11231FA35CE86DCE
-:109780007CED3B3743BB153B9C2154C3CBBFF7E17A
-:109790000FAB14C4135FFFF94B16DF5785F32A9103
-:1097A00064DADF28E0711847AB40FE6B4A9123BCB6
-:1097B000039E877D75B93909701DF6355079EC0C1B
-:1097C0000ED731E8B343C1769B1AC95FF4F07DEF41
-:1097D000638A92C148AE30B22744277FBA73785C5F
-:1097E000D89DC3E379520EC7B7EBA4408B8474DDD8
-:1097F0008CFB16528CF2A05D27257AEF10044B7B70
-:109800004DEFCF75128433E22BCDDCDE41EF713E9C
-:10981000D85EF432837DE3CFE176B27F008E340EE2
-:1098200087D7DC4F3A7FAFF19F198E15D9538388C4
-:1098300097C33E353787C751B81C76BF70409838FC
-:109840001A79CCF3F52F094A2E8AEBDD2EC44B4052
-:109850003E75941E5B4372ABC8D58CE7A412EC270F
-:10986000819FBBE1E72A06EDD3FE69732A317ACDE9
-:1098700094074243EDAD772B4FCC9B8305EDFCC4A1
-:1098800095BAEC8D4119ECB977B4629332762D8696
-:10989000FA2FADE5F6D962B4CF4224B70C7697D94A
-:1098A0003E7383BE9F0374B12420C94817663BAD45
-:1098B000A3721ED9351D60D760BEF6503B8DCB9B81
-:1098C0003BA336A642BD976B45F2335E2EED7BFE81
-:1098D00042D417357685F44569FF9D73E8FB241A59
-:1098E000C7ADF977509F9F7708A5C54BE0DD2BB535
-:1098F00047DD8B13D6FBE59AA3E3D12FD89A24BF7B
-:10990000428FD3ECBD95E77FBD7BAF107722DE6E33
-:10991000136DD8EFC2720FE5AD4E13DD34CEE28D7C
-:1099200062DC493854D3A7650FDA8D4CACCD7E0D7F
-:10993000F170979DE1F9C1829BFA0C76EEC2A8D135
-:109940009E8B3483FDA39CBE1D68B6FFCC76CCF203
-:109950001CCD7EA9601568BFBCDCB2931D2D19B467
-:10996000636625D9FFD6ED98F36CF5DFD5E899F657
-:109970000F6649D6FBFB9768FE290B717F709AF83A
-:1099800011ADD7B190A420FEDCB7BC40E73ADCFFB4
-:109990002586ADC6BB33C7A1EFC791BCDD5A914642
-:1099A00079D77B6E3D2BA78FD64BB9BF16D7FF0556
-:1099B0003BC9C164FA2D252AB2629898272AD05350
-:1099C0005FCF31D11496A81FC624C953F8710E9FDA
-:1099D00087FF3666433F3B33C6542BBF54AF07FE69
-:1099E000E8748C5143FD9E4C80EF86621BC5FD756B
-:1099F000BF34C5CECFFBDA77AD8CA17F3A06E0430A
-:109A00003814800FE57051348DCA63A35E7A8E8B53
-:109A100066D2B3389A47DF4BA2E3E87946B488DED2
-:109A20009F193D9BCAA5D149F41C1F2DA7E759D109
-:109A3000F3E97936E82DAC5716ADA3E784E83FD3B8
-:109A4000FB89D139F43C273A9B9EA1E8B7E97B79A1
-:109A500074313D2BA24DF47E52F47A2A57466FA4FE
-:109A6000725574253DABA3DFA7E7B9D1367AD6444A
-:109A70005BA9DEE4E8062A9F17BD879EE74737D13A
-:109A8000B336BA85BEEBFC9CA6D9D32F05B6C994D4
-:109A90006FCF7ACA503E26E3C3439A3CAECF51F70C
-:109AA00022FDE9F5F66BE70ECCF50EE40C9F77F39B
-:109AB0009AB65E9F848EFC088FD3EAEBB63E307C6C
-:109AC0001C8195F946D8B7E2F37B2647E1F42B7564
-:109AD00092BDB1B599513E98A7B2574079D3159030
-:109AE0006658D1913BC0F3C08A722247517FB88338
-:109AF000EFEDC5FDA84B63BDBEA9482F215FEA5419
-:109B0000E86F4CBB8DDC6B85C90296950626F7B0D5
-:109B1000C1780ED85706BD260574FBAD77E62484C0
-:109B2000E7ACE20AB25FB5FDE4FDB78E65E8776C9D
-:109B300075F40812CACB558C25DAE15BD72E7A383A
-:109B4000F19C8614E0FC39661D7B1AE364459D4A4E
-:109B50003D9E271CB7597D1A533C4BE291FA54287D
-:109B60009FF948EC697C8EEF8ED7A7C1F3EC9D3D41
-:109B70004FA3F899D0D357EF86F239CFB16730FCB5
-:109B800054DEAB4CF54079D201F519DC26A9EA8BFD
-:109B90004C4D57109E785B3AC0B3F51D30B4A05CB5
-:109BA000F351A7086EC9E0FA83DDF644C2BAA414E3
-:109BB000F7AA22FC33FF26B91CE5EC56A92F25B3E2
-:109BC0006CE8FA74E1BC719EA057B66BFBE872C2F8
-:109BD0007A8402821E0FF40512E2815DEDAF523CE1
-:109BE000B02B55AEC35057FF34263FA4201D733F02
-:109BF0002175CD58D24F3ADD017E0DF6A414E074E4
-:109C0000B775C0DEB4C66F08F15BF5BF07BFFF9E36
-:109C1000A3C9AF24F87D09E7111C998FEB029C2F93
-:109C2000818F2F085425AF77B5867F339EB74AF2D0
-:109C300059842F37B3C5CA07D7AD49A3EF91F0FABE
-:109C4000EDFF65745B13181EAFACD2CBE3CC5A7E2C
-:109C50005A3279B33FC93991E6C01039C7E3A5320A
-:109C6000C8B971C9E55C6D6004F99524DFE1F6803F
-:109C70009EEF10FE7E601471FD3B6D721DE6BBC44D
-:109C80002632F213C0BE6CC7FC9D3131A582B6B13D
-:109C90005028231E2BCE263FBD08EC0DA98261AAB9
-:109CA000630F3E2FA9CCB42D2AC3BC068DDFE4A6DA
-:109CB0004022BFE9FA7E901F75BAC8EAA273164027
-:109CC000AF984FB84BC3D3603F3C1EB1F696DCAEA5
-:109CD0008E0439D815CAA3B25E3F19FDBEA57D0713
-:109CE0007941FBFD97D45AE79BFC6B40D4EC9C7EFA
-:109CF00015E93C3685C974DEB9FD08C9A74C904FFB
-:109D000042110F0FE1F8F9D1D487314EFBEB40B689
-:109D100026CFE5D4CB3DFFFFE8B9037C75E2A75A17
-:109D2000790F9EAB18037A484139590BB057A29E60
-:109D300073D0BA2B8CAFA352CBE23D02E1AD07FD4D
-:109D4000E6988D9FCFD8EFE85649EF383265CC3F83
-:109D5000D9E58FEC0DF893F3859CA694E3A2FE6100
-:109D6000F37533DD41CCCB9153B1FC2A94EFACC1F8
-:109D70003CA13EA695EF744FFEEAF1873F04AEDDAD
-:109D80008FFB54D501F535A467A0EB3F205CEA9921
-:109D9000B244F1E151EE3FE9FC39C84F72B9CE4F00
-:109DA0004D65240FDFC5FEF5FE92D937FFA2C9CF5E
-:109DB000FEC0F0F68D4EF7A76DDF68F0BE3302FFF0
-:109DC000CF7CFEB5CDDBD860FCCF93FB46AFA4A023
-:109DD000BD3D951D9D8471AF5E4EF78CC7F9548CC7
-:109DE000FF011DA454BA4C715B6186167719365E6B
-:109DF000ABC793F5789F1ED74BD7E80A2F0C403D91
-:109E00009E5E234B8BA8BF3E7619F4E709723CE9AE
-:109E10007C8D720BF7E75D6BB2A4B16583FD82A404
-:109E20002439D5D5C8E48E4CBEFF9A01F2A573350E
-:109E3000233F2FF6B248FD1F576D1F3AA1DEF14AAE
-:109E40004020CA05952972B6760E81885C267A75FF
-:109E500032D68DFE36FB41C8E5C038F7E702530124
-:109E6000EEFD9F8BF49430C20D8D2E099587B07155
-:109E70005D466D08F703C5A35006381B326A33B040
-:109E8000BC7FFFA410B388DF5D116932C497CC7822
-:109E90001AA8F79D3594AFB06584FDCF9AA043B75B
-:109EA0003B2B8268EF5CD5DFEE5006F73FF57DBDBA
-:109EB00060F19317E13D3BC165DCFECC65F1D64412
-:109EC000BB29617FB116FBD932B8BFD87B46E2FE11
-:109ED000E28ADCDBF0E8FEBF0CEC2F46CEC1FAAA2A
-:109EE000B7BB1CE953CF87DDEFE0FB006CD28B3EA4
-:109EF000C5823E16943FEB277AD4FC8921DFB5B8A2
-:109F000099D90F9E1534C6F18F87E664F4E0C72413
-:109F1000717C3D9EA7FBC118AF932DF9CE887F7D44
-:109F2000FC0502F763995D2079A7EB4D902791A07E
-:109F30009F9A513C5A750A94AF753CB45821BF287A
-:109F4000897C19D837603D2556FBAC0BB4BC13F3A4
-:109F5000FB5B825C3F2FB0F338A5B0724904C75D4C
-:109F6000107409CE043BE9EA20D75FFAFE8B23F791
-:109F70006415E2D9E1882856F336EFA35C1D64032B
-:109F8000E7DD42167A2F199E0ED83B695FEEC012AC
-:109F900091CEEB1E8F9C4BF73E24930B6F21FD94CB
-:109FA0003016CEE5E30DAEA335DEF43C19F37ED5D5
-:109FB000C0F7A6143A7F63CE97794CC3DB3E0D2FD2
-:109FC000FFDDF932FB34FCBDA4C567F478D6254922
-:109FD000E4FD79B6FA47888E4688CB9CA1E7FB68FA
-:109FE000F861CF8CA77B3936F4DAE32902C263A388
-:109FF000FDCBC63F8821B4BFF4766E93BCD0F37717
-:10A00000F472DA4981C513F611D2A46E8A93A69D23
-:10A0100094E8BD99FFEE30F19FBE2EC9D6595F1767
-:10A02000F3FB2E6D5D0E34FD5B00CFBB6C4861967B
-:10A03000F9445F048DF177731E40B27DEE835ABB05
-:10A04000E391C93928971B1DB192D1F0BD8E9F377E
-:10A05000BEFC8D0BF96CC349E70CABF57835C8FD38
-:10A0600016D0A7EB12F7413DF35F6BC75ED324E335
-:10A070003EA8AE4FF57DD0B44AF33E9AF53EE806D1
-:10A08000662D1F93ED830ED9FFD4F4ED896092FD08
-:10A09000CFB2E1CFB3EFD6E879A4BC8F2B1CFCBCC8
-:10A0A000ACF9FD8B03EBB0BEE047C05737363969DA
-:10A0B000F7A9A7C9497CB8B82985E2B28BCB79BC8E
-:10A0C00077F17D82B65F678CC3BE04F262199EAFE2
-:10A0D000D7F4CE5116AE467B7456A560D8270FD75D
-:10A0E000A618CAF397DCF312DE9BF0728D5DA1F81F
-:10A0F00033F41543BBA096E72932A5FF4E8C73EBD2
-:10A10000F1677DFD5FAE3D4AF7A0C5C0CE2F096166
-:10A11000FC5924FE7AF9F549FC5E3A61703F5C0116
-:10A120003B61C379E328DFE360D9B728CEBB01E305
-:10A13000E230D30D5FFE6606D11128E518F2EBC4BC
-:10A14000AC38CAC7C5132AB2912E9F99F8B907E354
-:10A15000A2EFDE76DC8FEBD4D7D24C7907E67537E9
-:10A16000C799CDF1E5D38D279F9B3B902740F4F015
-:10A1700092299EACCB2BB3FC4888275F983B8A780A
-:10A18000B22EB77439A1CBAF83651D6F3F04FF3C7E
-:10A190001871124C6F69F31EE04B8D2E0FEA7CF89C
-:10A1A000A593EC916726FE96F2ADF47A2DC14CE2B0
-:10A1B000C36F95C5EDB43F8B790AA583EB323F722F
-:10A1C000ED4019BBFDF6D29506FA18905323CAB19B
-:10A1D000E1E59498CBE313C9F235753E18AA7F4A9E
-:10A1E000C84E4DFBBD3DEE2AFAEA7AA8B1E9D70A7E
-:10A1F000B683E7666A3FD111895BE827333C69275C
-:10A2000045169F94F85EE1EF07F48083BEC7EA9598
-:10A21000D5AB7DDC9E6E23FE8C3969FFDCA7B6E4EE
-:10A22000427D9F5F8D213D3CEC535B7313E4699B42
-:10A230009DEF478A361679C2022F4FE56A7A9985D3
-:10A2400003D8DF9A3AE3792EFDB93D97EFEFEDF1B0
-:10A250005707D0BE6E3B5C1E40FED9EBA9267B3B68
-:10A26000D9BADDA5F313CAAF92417F62A3B6DEC0AF
-:10A27000A22AEEE3AEB1870389F1C675B93C8F23FC
-:10A280007DF293BD6837B7C936CA136C9379FE75F2
-:10A29000BB5B9AB14D6BE733B493F47354745F8630
-:10A2A000E436E6573FA5D93BC9E6F954AE4DBB5F4E
-:10A2B000B4E7DE5A6150AFD88FD4B9E8FE07A6CA1A
-:10A2C0003CBF2964C8A7B66BFAA5DE94AF21CA5F6C
-:10A2D000CD6F0BFA23BB722DFCB63D3EF5295CEF2A
-:10A2E000A81473227D445DD67CFF8CB6AE3FD0E6C9
-:10A2F0006BBE575534DDFB209AEE7D88D537FFAC19
-:10A300000FE96DB5536EF3D13D0F74EF4314AF5C9D
-:10A3100082E7DF53783E0BF87FE7F2F306A13E9425
-:10A32000AF2CE0A2785467BEAAE64359F4D81E5A6F
-:10A330000DFDB5A9F52A1E5DE974DBBA709F2F33B8
-:10A34000183988F398EA9148EF745E9C4A7A08BEFF
-:10A35000A77039C264A19AFC41BA34057D703C5F94
-:10A36000660F38289ED516617DCE71FCFC3FF653F2
-:10A37000C77AF6D716A1BDEDAA443CED0F4DCA88A9
-:10A3800058C809FD69DEFF7FFBBB6F1652BEAA18D5
-:10A39000F908FBEB6D5CBC11F7F557EC1443B88F73
-:10A3A000F09DEF1D3C839F3732EE33DF9F36A50FC4
-:10A3B000F559D4EDA07A7B3CD59D88A736C1D389C9
-:10A3C000FE6EDBE1953F413CB6B5F238B719CF7B65
-:10A3D0003DDFA3FB358EC372627DF3FD1AAC73259E
-:10A3E0005F27A78BF62D61BE2CAF8AAF23C5070F61
-:10A3F00079E81EA8E3FB9F71237C5F63DE697955D2
-:10A40000C3CD3B5F26FB45A31F2685D7E1BC6E1657
-:10A410003D9D1D3EBC270DD61BE1DE65277FFFFE5F
-:10A42000B4745AD728C087EB2A7A1A5474C9FEBA72
-:10A4300053A4758E4ACD342F1693D8767CBFEBC4C7
-:10A440000FCF473A50B368574B2C6826BCFC15F029
-:10A45000B2DA022F403F4579B85FB4EB46EAA7D3A2
-:10A46000E192D1B269F354D379E5D1DE2F5296C788
-:10A47000F924E17E91B2BC2A8BFA9A9F85FE368E32
-:10A480005B27B3CFE26C10EFC9F257CED7FA1FE8C3
-:10A4900067E4FC95F313C7D7C7FD1AEB3AFD74D6F2
-:10A4A000B5CDF57FA7A39DA58AE9A1944228E33AFB
-:10A4B00021FE719D70BDB4B80DA92005E940EEC91B
-:10A4C000433AB8313D84F43992DC90185F77BB048D
-:10A4D000F40C769D538E1CA0B38B5ABC479727660D
-:10A4E0003E6B7319E5559B7E2FDFA1D1C92BA09739
-:10A4F000AB71DDCC726BB474B2324F30DF43B33228
-:10A50000CF9F9C4EECC1F08D8877C4535E05C52B60
-:10A51000BE8BF5F7EF177738C6E2783C6ED61F642E
-:10A52000F2430979593A3CEDB8D9CDE3D414FF9000
-:10A530001A19C33C386F694890CB464547ED89F0FE
-:10A540007D037474D77074E466BD745E63B99E9FB6
-:10A55000B363F8FC9CAFAB7F603DBB109E36CFF77A
-:10A56000883ED7DA5D32BF47EDF4D6F5D1A1EBFADC
-:10A57000E8F0EB1A791CBFAB79D5748F11AB692267
-:10A58000BB69975F7D13F3C5981432C8C521FCA33E
-:10A59000C9ED9BCF54285F7577AB26E75A9D32DA19
-:10A5A000E3CFFA6E7C1CEBDFCD9430C643A7D856C0
-:10A5B000119EFE0AF37B284472B514F77DA22C3558
-:10A5C000A4E9D1A7110F339456210BDEFB162836D0
-:10A5D000BA8654D9C46C65A3C7C34B43E5E04B238B
-:10A5E000C8C15E8D9E6F427AD6CFDB279383874E9C
-:10A5F0005F0E1EFA86E5E09FF34E43AF7F03F2E65F
-:10A600003384DF2C6FDC1A3F5F1962218C978F3601
-:10A610009F0DEC4D05F9AB2EDD45F4D3F68440F9E2
-:10A6200052608747A8EC7191B0D9EB71F0FCDF1D47
-:10A63000FCBB58CFF16CC6D39779593CEFA67B652C
-:10A640005832E449C5881FEE528FC9C522E6F7D7B4
-:10A65000123D7B357B46CFEB4FD7E4FF809E9F6951
-:10A66000A3F1BC055CBE7BC1DE41BB88497D0CFD0E
-:10A67000F89BF378FE3EF003D1378C12467EC8A8D3
-:10A68000914C795A9C5FFC12B777327D4C205D83E8
-:10A690007962F0FE04D813783F41A66A6C7773EABA
-:10A6A0009502EAADBE2677B340E7F4C37B7E0CE5A6
-:10A6B0002CCCF702BEF1CE30D6F7B384B2857F1E24
-:10A6C000AB67A598B75896AFF9E90E1620FDA8F923
-:10A6D000E9FA7D81E2C8795F95F9A3882F9E97AF4B
-:10A6E000E79918F571770AB38CAFFD473E975B0D7C
-:10A6F0007D75F56857AFF230B2AB56A1EEC472A6C5
-:10A7000083EEB509EDA97459DD5791A9DA0CF7F379
-:10A710007A67A41AEEBDF587B30CE59CC65C43FDD1
-:10A720006064ACE17BDED2B30CDF0B9A2B0CE5311D
-:10A73000D1F30CF58B00C189E571EB2E36D42FE9EE
-:10A74000BCCC503E73F3B70CF5C7C71719BE9FFDBD
-:10A75000C87586EF13BA5719CAE7ECBCD550BF8D40
-:10A7600059DFDFB9219FCB29E0779263ADEEFA463E
-:10A77000FA1D0DD96188F32FD1EAEDC9AC2EC57849
-:10A7800048DB91F252F287D3CF1BD61F36CBC5647C
-:10A79000F2D8FCBE5D1BEF93A7DFAF5E86748E42DE
-:10A7A0001EE4D227EEB7D6E29CD697F1BC04FD7723
-:10A7B00031CCF7F20FEC534A2ACD67419683599D6D
-:10A7C0000F5892AF58EE2FB40B2117EE1525C39BEF
-:10A7D0004E8F23E1ED4EADDED7C5DB21C118074218
-:10A7E0007DF284055C7BF307EE3B78389FEBABCAC8
-:10A7F00054F230F83D0EA7AB4F7438409F3C915F48
-:10A8000035343FFC93C6D7AEBE5FC1FA57F3FAB6F4
-:10A810005029AE4BB27DA5BDF9E67DA5AAA528E7D6
-:10A8200016785285C4FB9A7FA5D5D3E3D96DE99FED
-:10A83000D3BE529B23543A9A7DA55FE19D1B558858
-:10A840007F858FA7AFAB5D0DC896FE9DD98E61CF7A
-:10A85000E33D1831B74479C366FF2EAAC96DDD9F69
-:10A8600093F6D691BFDFE61E4B791F6DEA2AD29789
-:10A870009D49FC5CD0977F447C4EF5DC64F0E70694
-:10A88000E3012A8D076DC96E6A4BF0FF715DD5FB40
-:10A89000F9BDDADF801FFC51FE69D8090AE37EF0BA
-:10A8A00071C6F1745CB5919D701CEC0494BF6B246F
-:10A8B00046FBDEB14A41B1F28B3B576BF6E16A8E43
-:10A8C00037F37EB7D9CEB824B492F0B606E8C955AE
-:10A8D00089F1386EFFAEB1F3FB37656F3880FAB699
-:10A8E000DFEF600F01B47BFD3C3EA7E3E5ABCAA3FD
-:10A8F000CC8221767266C13076F234B1AC1BEF6D3A
-:10A900003D7692C745143C8AE8C37BC8F9FAAD7A14
-:10A910007E4E6C05EAA922A919F3D745A664205EEC
-:10A92000563C27B2B88072CC989F6F67CD3FC278F3
-:10A930001CF3F1F731E66A453B29A3C6A8C7325597
-:10A94000A31EF3CEC832E935A31ECB6934EAB16049
-:10A95000C4A8C7F2965698F49A518F8D89D69BF465
-:10A960009A518F8D5B779949AF19F5D8999B8D7A5C
-:10A970006C7CDCA8C7CE7E649549AF19F5D8393B0D
-:10A98000571BBE97F77418BE4F7AEE6E43B9AAF7FD
-:10A990000143FD730F3C64F83EB9EFFF18BE03A2FC
-:10A9A0005FC5F30C780F2D2EE2F91F3C69FCCE54E5
-:10A9B00007E6E35F8FE733611D2FE8FFADA13FD6C8
-:10A9C000C9CF2DC4E03F5CAF3FB308DD0300726C1C
-:10A9D0005F1EB4BB212E847A18EAA727DEC77D9BB1
-:10A9E0006B0322F9712B30D88AF4F0A8278EF4700B
-:10A9F000CD66E3F9876BE3C6720CE847C1B802D0B5
-:10AA00000FD2D7F5A6DF8D007B90E8ED7A456A4638
-:10AA1000BBD24C5F7FD6E92BA6BE8AE739F4F9EAB0
-:10AA2000F3B3EBE74F35FA5335FA63E22E82FBFAC4
-:10AA30003C917E7F479FAF0AFFF1EF1F39701E27C1
-:10AA4000760ACC8BFBFB2CB62FCF623E37ECDCE4D6
-:10AA500040FE34CFCB3C8F21766A81715F719AE8DA
-:10AA60000E11DFBD2E923EA229209F3DC6CFEBAD39
-:10AA70007A5EA47331C887E82F88B146C2CB0AC07A
-:10AA80000BDE1BAEDBADC7B476C71E14E97CF34802
-:10AA9000FCA868F870068CFC98A2A49AE8C988DF24
-:10AAA000B452237F5EFFCE450E945FFB00DF420D64
-:10AAB000639E90915FAF1797D13E9F8E6705FEC34F
-:10AAC0007125307571DE37C0BC7B94A1F85DBA6B1F
-:10AAD000D3DA3C0BBA1909BF8F1618F7E9F4FDB9A0
-:10AAE0003AC08EC322AF54C7DF2EBFFA24CAC76450
-:10AAF000FEF0EE02E3BEFA28FCE1DD89F2F61BF07F
-:10AB0000879F2F1856CFF5CF427FCAC9D2431D1653
-:10AB1000713F89C93D18AFB537F3B8DF60FCEE1B54
-:10AB20008FF3BC5B5045F7CE919E4B91F4384FE8C4
-:10AB30004004ED938CB342981735DA38C75F0A8624
-:10AB4000C439FE52307C9CE34D3C4FA866E436D8B5
-:10AB50009099A45029DDEF8C20F03CA44F118F4335
-:10AB6000F2758BB3B4FC6365D8FCE34BB4FDDDEA4E
-:10AB7000807A12E180FE3EC7E7C07D6C957EEA27B1
-:10AB80007D847E62F5DC5E8BD93C9D6DDC5EA37DB1
-:10AB9000A66F208E915E887EA99BE3BFCDC1E3B6F0
-:10ABA000A71B670B160EC17BB07018BCFFFDED1C18
-:10ABB0007E6E3504D6417972FAD6CF61EAE5F59911
-:10ABC000467F796D0587AB441BFFDBD9DC1F985CA2
-:10ABD000C8F94FCFBBC4BCC5940A28CFE4E794F4AE
-:10ABE00073AD7A3F930B3D54FFB340FDE4423FE623
-:10ABF000CDF2FB77D6661AEFE1F9B8A06E32CE6BD4
-:10AC000092D6FFE442C6F399C772B8CC79A77FD336
-:10AC1000EAFFADA09E9E788E16FD1287285AE27339
-:10AC20004A218F13E8F7DE4CD7CFCFDDC7CFD799B6
-:10AC3000EF5D003E79037F1FEAE89D76F2F7401F43
-:10AC4000D1F9B92579FC1CA2F93E8548A9BC0FC5EC
-:10AC5000EB095666792FCF903C8743B750FEDDCB8A
-:10AC600093992C0447CE7BB8BCD0783FC257384765
-:10AC70007765E128F21E166AE7E8FA52B91EEB0F73
-:10AC8000BAE20F59F8BB516D9DEED4FC5ADC9FC659
-:10AC90007D72BCDFDB6ABF3C5AC8E967B4E7AAEF44
-:10ACA000764422C8B7E673D5C9CE53F739FAD6E44D
-:10ACB00020BCE35908EDF79C05F29E1CA897DAA08A
-:10ACC000D0F9C7B5452CBD06BF97DB4278AE2373DC
-:10ACD000AEBCD68E7C5ACCB20428F7C5E6D0F87745
-:10ACE00036325904B8BA0AF93EFAC2DB3EA5F1FC85
-:10ACF000B5303585CE9D4F47FF2CD6C8E8DE42F3F0
-:10AD00003CEFD6F8C5B586DF9393516C9D877FB72E
-:10AD1000468F20B736215FD415B31DFCFC2C3FA70E
-:10AD200080D7D253FE662895F6052F8575E3FBE79D
-:10AD3000BDB47E3705A6DE8FEBA9F39B43CB533022
-:10AD40009F27EF2A3CBDF3E4A90BACE1FD9DB6DEE5
-:10AD50004DFEF0CF10DED4D24EFEFBA55F9E3A250D
-:10AD6000566B3FEDA860FB4804F55F0AE83F019F82
-:10AD70008A4CE768994BA0F3B02EA599E82AA5263E
-:10AD8000E4C5DF456357D918DEE332556BAF363281
-:10AD9000017F4F827201494E9B7E5F420DB5B742E3
-:10ADA000FB69B86F16C2BCEFD052ECAFC19D2A63ED
-:10ADB0007C33A5B8B90ED7EBD985BC8FBB939C97D4
-:10ADC000D0CFD90FDE3FB5EC95BDB509F70AACBDC4
-:10ADD000FA15E3FD5357BFF275EE9F3AB8F5EA57FF
-:10ADE000FE27EE15D0E51BA8213BDAF507447E8F40
-:10ADF000DE5F9FBAC28EEBB0B68E7523DE639F0313
-:10AE00009E5D8378B6D7879FDD8276C9AAF410FF4E
-:10AE10003D91D87710CE77D2988CEDF57C43819513
-:10AE200092BE9EDB2890FDC0A4FE1BB03C7F579ACB
-:10AE30008CFEC35F9F7AB32006F4F9F6EDC73D9808
-:10AE40009FFAAED4EF41B83EB8ED350FE2EFEDDB3F
-:10AE500044CA43A173DF0979625F6AF4B5604CF8B4
-:10AE600038D2D7C296FFAA4EB4CF58D44FFAFEDAE2
-:10AE700038409C68F73E9266F85DD1E5DD5E435947
-:10AE8000D7F3CB9DD6E7E62BC770B974EDA35D8EE3
-:10AE90003C05C78FD8C7C03C3FD0CE017DB0C3436F
-:10AEA00076BC0ECFA247CB1D680FBFBBCBC97A289B
-:10AEB0002ED86B676EAE3F30EF22C2871E02E7BE10
-:10AEC000DD790EE4B32502EB771273B37D88EF3F93
-:10AED00069FE9F791E4BDE961DB8BE4BEA583F9E19
-:10AEE0003B5B7493B0F666A8BF28E226BFDF3C4FF9
-:10AEF000B3BEB906EFB311ACEE816BDEF73BE8E70A
-:10AF00002AE807EDCF259DC6EFC79EBB71DF161857
-:10AF100077C74E07D98BD78C10EF1F3F46D34BD541
-:10AF2000ECDC53E348FF654C5092DB1DBA3EFAA0BF
-:10AF3000855192CA5FF0F77DE1F9518B4CCFE385E3
-:10AF40000AADC7F53BF7ECA3DF16967AAB51DECD21
-:10AF50007C7E71DAB7D8605E517557DB335B88153C
-:10AF6000F47CD51E8AEFD568F7BF5CA39DFFA83A95
-:10AF700060CE57DDF3ECEFD06E83F99FCEBD3D0B75
-:10AF800046796FCFB1E7A6A6D1F9001D2FE7025E83
-:10AF9000C4AF8F9764ED9627F9DD169D9F8E6B7A6F
-:10AFA000F7AA6DB3D7E6C2F86D4FFDB910E3C7310C
-:10AFB000C6E9BBEA41FEFB3F55EE6CA23717D267EC
-:10AFC00010F16ABAE721C6DE6009F47DCDAE34A285
-:10AFD0009300D843CE1A7CC3E9B50AEFED44FA7E5C
-:10AFE0009DB77769FE6D64D7EDBCFEEF1CB23340B0
-:10AFF0007C19B0D1B32760ABB1B867CB7CBF58A781
-:10B00000B1FC89BDAF10E5CA35263FF413C13A3F04
-:10B01000EDCA3163497E5DA5A8D3310F60090BAF3E
-:10B02000E5F15B7E6FCF0752E7BEEF23BF6F13588A
-:10B030000CF0B4FC378FFD2BCAB1EB1EBF2F1DE502
-:10B04000D8875267368EB76CFB9A74BC5FE60329CB
-:10B05000968EED3F8C737936445F8E11B47D293521
-:10B060005D00997C03911AFCFFAAFEB5B7C2387F38
-:10B07000033C23DFDFB0E31F54DEA7BAFA5900FB1D
-:10B08000ED9B8E705CDBE46E6E0DA17F69E4CFEB0F
-:10B090007E765FB642791EB13C0D7F79D8EE866D23
-:10B0A00076CAF3453F1E8759C1FA697EE6F62BBA88
-:10B0B0008F3A505ECB36D69F7FFED0EF602139901D
-:10B0C000DF56ECD8F0A9988ECF0FDFC2DF835A612C
-:10B0D000B24F976AF2DB4CFFBF30D13DE087E20B05
-:10B0E00031808BFF1C1397E36D3FBF7FE26180EFE0
-:10B0F000A36D2FA6E3EF4DE8F4AFDFF37CAC7BF15B
-:10B1000042C730F7087DA2F1C9807ED0F493B21314
-:10B1100000CB81E22EFE5C66EF493F1FE6BBACCB65
-:10B120001E429A5FF698A8BAD1AE3AE8247B64D959
-:10B1300063C7896E97096ABF407A8EA5A31CD7D7CB
-:10B14000EBFAC7FE341DE5F4F54191CD0456BCEE93
-:10B150005727787DA0F314A87FFD1387A77F1FCB07
-:10B16000204F5C16EB35B57B8FA3CF6DB15EDD87CD
-:10B17000A7637CBEEDE77FA7F5F870B7C0728A863B
-:10B18000B65FDAF5278A837D040BE3CDE4F8427DD0
-:10B19000B3A25B6C726458AD5FCFACDF56D277CA96
-:10B1A0000B1F691D378C615C3FFEE6B15FFE16E048
-:10B1B00058FA96333413C7FDE58DE90CE8E0CF5219
-:10B1C00033A7FB1FAFC946FDBDD41ECB96E9C9DF2F
-:10B1D0002FDDFA5DA2C76B7EFFDD6C6DBF2168239A
-:10B1E00079100BE23C973C388FE679358B103D2E79
-:10B1F000FD31BF67F104F8D9567E42A5C2E59693AA
-:10B20000AD9C78AB0FE526DED902703818BFAFEBE6
-:10B21000559EFFEE64976524DAB90E85DB7331160F
-:10B220007F07EDCE15A09651AE89BF3F311DFBB90A
-:10B23000A9486A76527CD4FAFE9AFF075C96D1033D
-:10B2400000800000000000001F8B080000000000CC
-:10B25000000BE57D0B741445D670F5F4BC425E43DB
-:10B260001E100884CE3B488803492001D481400C3D
-:10B27000CA63025151220C014380BC445670F5DB75
-:10B28000740820B0AC06659515740704C5E706047C
-:10B290008135C2441483EEC128AC8B2F761004791B
-:10B2A000C980B08EFFB2F2DF7BAB3BE99E2402BBCC
-:10B2B0007EE7EC7FFEEC598BDB555D5D75DF75AB92
-:10B2C000EA4E1583BF04C6F23E1ED5DD9BCE98859F
-:10B2D0005D30DF9BC5D845C6A467EC8C5531A3EC27
-:10B2E000B532FABB12CFD889F5962EC28D5076634F
-:10B2F000650DD0FE0AFEDDD2564E9704C6B2A9F9FE
-:10B30000276C106395F82F09FAD974227F0DF4CBBE
-:10B310006244161EC3E167A218B395845487E7C040
-:10B32000F70E1E35F7847A39CAC0926D50DFF20DE0
-:10B33000C1CC1E2D617BB5FFAA1D16E651C703FFC8
-:10B34000AFDAF08D99613F06E6EB35B47D3D63D50C
-:10B3500019BF8EC279844BCBA13C61F6E5BF85DF76
-:10B3600081EF6E84EF94AE82F6699AFEB69EFC9CE5
-:10B3700065607B73DBF378FCEF423E2FB138DC1560
-:10B38000C2D84C9826CB6D3FFF055FD63EFAAEA6DD
-:10B39000BF0C2934EA7830FC63301B7C456C7B9F02
-:10B3A000AD8D66AC47FBF77FA8911F7DD7846FCB2F
-:10B3B0008C41937293FB05C453F96716BB0C782C30
-:10B3C0007FED92D9003013982FB92B63A75FDDF37F
-:10B3D000E93D309FD30DA6A831F4554798D0AD0D67
-:10B3E000EF655BBEC95F03ED4D80F720A067E5D632
-:10B3F0001FCC06681F93C77C1618FFE9282763FD3A
-:10B40000116FA6AFBD1ABCE5C1736F088D23D610AE
-:10B4100083A52796415919C5EC1E78BFF2A06897FD
-:10B42000105FCCB7C416D2FEFDAA86A30174D1D793
-:10B4300033E6333BF1BB5B7F7B5E0CD3E2DDF8B5DB
-:10B4400057837715CF8178BD3B00AF97587A387C0A
-:10B45000869D7A794E1F577A7BFCAA78FDAE8621AD
-:10B4600093B73EBFD047223C4B3BE043DDA1AE51FA
-:10B470002919FB9469F038FB95B3C4BFFFE821326A
-:10B4800011F8A672C38F4B90AF00AD3E0BF06FA5C5
-:10B49000FB3CC18B1D561F23B8A948C8E868DE7A5B
-:10B4A0007C06D6F742A466B7D1DFB490C9A1D0AF6D
-:10B4B000EF6DD1BD1E86764EF28545C0FC1607B1F4
-:10B4C000A94E28CFD914B8AB0AB3A9D3609CE7E43E
-:10B4D0000C9B8CEF05B1490D409F734E5F58D79080
-:10B4E000B6791F6914C32468EF75B3828690F67C21
-:10B4F000C8581D7DDFCB3AABAFA5718E122FBFEEC2
-:10B5000085EF5D908DCC02DFF3D6FEF0BA17CA63EB
-:10B5100046AB0DF134A3F6AE306680EF37268E9F32
-:10B5200004EDEEDB07F8A3E939CC3D00BFD3F9D435
-:10B53000D9B74C7E6A18CC4F0CCDDAFB16BC5F0A2B
-:10B540008815815F67ACD0E3673673867BE2516E06
-:10B550004D6D7C42FF759B3DF0DE4C5748F572F80F
-:10B560006ED95A7DFDECC6D3C45FB303F8CB85FC1E
-:10B57000D5A33D7F6D54F96B001B80FC354A0C311F
-:10B58000203F9F6B16DD1678E7C222135B02F08521
-:10B59000570537837E2E34422384777098C9D1C4EF
-:10B5A000B72A9FAB783B83FC97DA1E9FADF5DBBED5
-:10B5B0001AF43034297FF38B8C35509E79F3B39491
-:10B5C000B710DEFEB7B82F58FBF679BB7E9C42E37E
-:10B5D000DA656138AE73BBDE8F7B18E13F5BECC888
-:10B5E000B7E7165A1C0CF5DDAE507732D6F7067E5B
-:10B5F00000BAD7BDFD4306EA7BC616111D5B243396
-:10B6000095171AFF7958C079345A249C47D52E4093
-:10B6100002BC5FF5E72037C3F7DFFE61902BE497AC
-:10B620009B4FA599B9883F43D9A42DC8BF5D990305
-:10B63000E753F556EEF3B5F0FD8AAD4DE6E9509FC0
-:10B64000B7FB5F19A88FCE6D6932A3BEFACEE47D39
-:10B650008E017F7C214DAE37019EBF0B85CE7A32A5
-:10B66000362F7E8D530EE9082F1C0FE7000F382F61
-:10B67000C04B993BBD737C5CF8AFC5C7F929F8FD99
-:10B68000F2C6C14C8CD7E24570F0E7A16EAB40F337
-:10B69000E7CF77FD90C142AE3E5F5BBC99E4FDFF12
-:10B6A00097F966C4FFB7D297F3FB9B12B74B817C27
-:10B6B000DF9EAFB73F48F0EBA1761AEF35CAFBB873
-:10B6C000FFDAF9FFEFD0BBFCBF76BE57A3F73E858C
-:10B6D000DEA1360BEAADB7FF15C7AE63DEBFFD7F57
-:10B6E00074DEADFE8FC16ECD82F17DCEDC770C179E
-:10B6F000C82BE9D01FD9112F507BA6AC3BC6297EA1
-:10B70000451DFB7AE434F8AE0CFE04FAFB75215FAC
-:10B710001B0F02DC027E02FA170C9D13C0434BD1B3
-:10B7200000F772B4DBC66A6603D8F4E97482279521
-:10B73000FC68CC82F677809F87EDF7D77A67D44292
-:10B74000FDFEAE06A90EE0F18E89C95B01B6F514C7
-:10B750006DB88EA973645A25CDF8C6E7E8D723F7EC
-:10B7600004AC2BEE9AA4AFBF93AD8F36427F779691
-:10B7700099981BA6744740FBA7E26D34CFBB58F5E0
-:10B78000625BC8F5E3E9783C5F9FD5B181CD12E2F9
-:10B79000C521DA37B2F678638837C44B4C265B6E26
-:10B7A000C7AF788D0701B628FE15FC913CDE116508
-:10B7B0007D01F1646173D983D0DF25C9588DED2DEA
-:10B7C0000CD68D7CDCC215A13DDEE04F320E225737
-:10B7D0009C4830DEF100433CE3F33E31BAF769DECA
-:10B7E0008178BE7EBC2E4C7E0AF15A146A77235FA4
-:10B7F000389E8F36C2F7EA00CF82D0864F154F8130
-:10B80000787F0B7943E397AB653AF34D41BF338CB7
-:10B8100085D99743FF61D65ECCC8E7E1B3F4C0C2D7
-:10B82000C670BD268E600DCB61BDC6728C675AE7AF
-:10B830009540F59E87E1BDBAFBE17DC46B2F2639AB
-:10B8400089FF8B6DC7FBE132CFC5AE04B7F99F1FEF
-:10B85000E580FF194F25F1ED471BB8BF7969D81B6B
-:10B860004B0680283198B33C08FD5CE54FF616E3A3
-:10B870007B2233D871FDCB1C0EC93608FB65B4AEF4
-:10B8800009CF31E8D6BF5D1D5D74788B2C88D0C19F
-:10B89000D1CE9EBAF6DD2725E8EA7BB86ED0D5C7B3
-:10B8A000960DD4C1BDAB87E8DAF759304207C7CB54
-:10B8B000B7E9DA272E9DA08393EBEFD1B54F5D5DFD
-:10B8C000A2ABEFEB9EADABEFB769AE0EEEDFF06B68
-:10B8D0005DFB1B772CD4D50FF02CD7D567363FA155
-:10B8E00083B35B9ED1B51F7C68BDAE3ED7FBB2AEC5
-:10B8F0007EE8B75B74F04DBE3FEBDADFE27F4707CF
-:10B900000F671FEADAE7590FE8E051B62F74ED6FC1
-:10B910008D391A10EFB0C90F64A11A037E02391BCA
-:10B920002D9DD6B587155A31F28D49E187DBD3BEFF
-:10B93000D7D58FB5FF53D79F9955031190ADEAA97D
-:10B94000ECC21AA80C612D543ED4DF757B02CAC329
-:10B9500073F21264AAFDB93FC4A11DF968D803327D
-:10B96000F2DDA518661307C07898CF887C6D08BEF5
-:10B97000DCCBA5891B85F945E6C9043EF40B54DAF6
-:10B98000FCC1CC13097CE80FA232C21F49CF23FDB2
-:10B990005DA98CF2C7D2F3687F0F2ABBF913A9EC1B
-:10B9A000EE8FA732C6DF8FCA1EFEBE54F6F467D2F2
-:10B9B0007BB1FE0154F6F20FA5E7BDFDB954C6F9FF
-:10B9C000F3E8791FFF702A25FFED54C6FB47539912
-:10B9D000E09F48ED12FD855426F927D3F364FFDD7F
-:10B9E00054A6F8A75399EA9F46659A7F0E957DFD68
-:10B9F000B3A8BCC1FF00BDD7CF7F3F95E9FE87E963
-:10BA0000797FFF435466F8EBA8BCD15F4BA5DDFFFF
-:10BA10005B6A37C0BF8CCA81FE27E979A67F25956E
-:10BA200059FE35F43CDBFF072A07F99FA772B07F68
-:10BA30001D9539FE57A8CCF5BF44E510FF1BF4DE79
-:10BA400050FF662A87F9DFA2E737F9775279B37F8B
-:10BA50000F3DBFC5DF44A5C3FF213D1FEEDF47E516
-:10BA600008FF017A9EE7FF98CA91FE2FE8F928FFA8
-:10BA70006754E6FB8F5279ABFF089505FED3548ED1
-:10BA8000F69FA4F236FFF7F4DEEDFEF3548EF1FFDD
-:10BA9000939E8FF5FF48656B3C619829402FB6EA6D
-:10BAA0003FC3152859484487F1B6D6F7157DBC32F7
-:10BAB000F83986718F71D502ADD39F0EFEEE5DD23F
-:10BAC00093B91609E1C5D8B407FF8EAD1B63F7E241
-:10BAD0003F24C69A722DB47EDFFF3FFCBD25C38F85
-:10BAE0007EF900DAC7FB2D0CED63A0FE55BFFB51BC
-:10BAF000CE9E68F4C3960CF49663FCE577F1DE62A3
-:10BB00002CB727707FE4F5046E6FB72518A87CBCAE
-:10BB1000BF8DCAE2FB93C3294E15756DF3BAA4D845
-:10BB20007DB5FD1F921438C41747F6E21AFBB9D64B
-:10BB3000768BADBFF923C6751C7546167433C046A7
-:10BB40006EEFE52F43DD1B614AF288EA1731CE2301
-:10BB50002FB4D8EAA210CFBFF913B65FC098D302B2
-:10BB6000E53309AEFDA8177E088A73837184BFEAA6
-:10BB7000C113427FD1FE3FFF5FEEFFF8CFF5FF77A5
-:10BB8000858F6E4D749E4A40BFC0E8C8403A8C58BD
-:10BB9000D8438C82F7A7AD106CC847D3170DC847A0
-:10BBA000FE18C81C1427BD37924D7576E0974524C2
-:10BBB0001A14FF4232DF05E339CB9807FD89128959
-:10BBC000115F96340A6E99E2D08EB0B160BFCB148B
-:10BBD000BE2D595A6B9E0FED2A7AF0781973F378BF
-:10BBE0009915FE877234A77EDD5E0A378A97293E53
-:10BBF0007609FD5E609D399BDAC763E7639C7987B0
-:10BC0000D98676A3A221209E1B10370B8C9705277F
-:10BC10008646A1BC323BB3F3387748E9DFF07B2C92
-:10BC20004C12A3AE8E17353E2B31A93BE27194988E
-:10BC30001E8EEB980BCDC9E10C4B49EA8EED5C40B2
-:10BC40008B162805A36B303E077CCA48575F6DB042
-:10BC50007B3D8CEB08D813291385DB35D88CF1C8D4
-:10BC6000CF7BB3E502518DFCB0AA0D22F9F5DE853C
-:10BC7000FF5C8271EC59F1465A074CC3983B8E6FBA
-:10BC80006757B72C50BF8477DF6B02C55D653637C9
-:10BC900006E3BA9AFD10F26B9D8BA3C7E5209D9633
-:10BCA000761D68415AC98E4F93BA69E8B3A88EF0E1
-:10BCB0005A1213C9E9B3C3447E2DD0A716E933CB7A
-:10BCC0006D3AA6C5F32576D98CFB31254BCF13BD34
-:10BCD00066B7D14BD7AEA2BE89E80A74D23DAFAAEF
-:10BCE0003EA1C6D18FFD1CBD86272AF14D855E1869
-:10BCF0003FBF0B2B1F8924FD50BCD0935CADE1D31B
-:10BD0000C07D89A41943C29D200F053D393D98D1BE
-:10BD1000DE0DE9F9FD8A6CA257209D0A7E9A4EF449
-:10BD2000609F87B28D309E7B13D9D409F07CAA1214
-:10BD30007FBDB76E7401C6CBEF4EE4FAF223587F95
-:10BD40003A60FDF9718D953940351FA8B111FCD7C6
-:10BD50009A1882FF562351F9594D1A95C7CCACACAD
-:10BD600041235FC000661CDF5445AEA626AAFB52E5
-:10BD7000F36230EE5EF0D3816C03AA50B9A170D4A7
-:10BD80004DB8BE002468F033A928987C6915F69A4E
-:10BD90006CF931A83F9609F68D4857E7505D7B96C0
-:10BDA00096D906A3FD32727E02BE588FFC77F798B3
-:10BDB000485DFB3B97C6EAE0F989128DAFB0205190
-:10BDC000F7FC9EE27E3A789A1FD6F3F0A924A9C028
-:10BDD0002043FF17FF62227EBE583DB8FB7C0E1346
-:10BDE000DF05E2FF9859A63882BCDE6247FDF76D99
-:10BDF00010E7EF6FFF2ABAEB68DD2B53DCE592D535
-:10BE000026E13AE5C1E9721CD63F180C2EF900C4B0
-:10BE100097C8307EC05EB690FE9CBE5A6032CA881B
-:10BE20008FD17A79DE4B169AE78CD5227365129FF3
-:10BE3000C461FB79D112F5776FA2D480FCECDB688A
-:10BE4000B1AF87DAE95EE57D6120ED8354CCFDDB9F
-:10BE50006123CA434A4B06C6F78BE33DD1A807CFFF
-:10BE60006C30D1BE5785B8AE34044834E7776F8460
-:10BE7000E54A247E84DF531F47AFC3F9B7CDD74DC2
-:10BE800071116F1FE7B38980CF53A5EE0C5A273F7E
-:10BE9000C2E3F1EDF1C2484FC986306923CE77BACB
-:10BEA0006BB02D5D6B0FF9BEDF7493BD9B3D1DB96B
-:10BEB0003FAB07EA81632B4C05187701BD3F0EF1BC
-:10BEC00074AC3ED2B09C16555B88BF4A8C9259FB2D
-:10BED000DD9215A283DA837E2F447BBD5274B1C1FB
-:10BEE00008D753FFF252C185FB4E492CA73BF2ED18
-:10BEF00003F70FEE8EF398D2C93EE37720332ECDB1
-:10BF00003ED6ECB745A71BBF97E53516F5D78E9FF4
-:10BF1000C781925C4B7BCD453A6D0EB22F9750AFE7
-:10BF20002686E33AF5E441B01BF08D59754D1912A0
-:10BF3000B05EF903DB890E65E31A523CF0FC63AB9B
-:10BF4000EBFD4498C2B73D1A9E1A8A71A2C6E7E378
-:10BF500064B4830BF8FEDAEC9767F5D1FAF3EDFDE4
-:10BF6000091663C8C1C2D34D00BCB824968FF89D92
-:10BF7000CC1A94F8859BC627A1D2057CD8CAF9FEB5
-:10BF8000DB74837DCA812C447FA80DE9A2F677D4A7
-:10BF9000C4E35C9F270A3A3B1C9DC4E57BBA81CB76
-:10BFA0001DDB25109F02C13E4DD2D8CB2AB682ECB4
-:10BFB000654CACC870DFEE646284A217B8FD9B8349
-:10BFC000F60FF7856D02C947F9268BDB0DFC9598B6
-:10BFD000C4E573B6F9B5A70662F3F86A337E67D68F
-:10BFE00056813D034D4F99DCA52DB82F655BB728D1
-:10BFF00082DE33D9DDC8A78A7EB7824240BD3013C6
-:10C00000FF09F515AB04B787F8C549766806C64D34
-:10C0100070FD8F7A5EA347DAE9F700BD7E1FD3DBA0
-:10C020002356AFB72FCEE0502B8E73F62AEED7B63D
-:10C030008D4764570057A52EF7DE71345E81E222EA
-:10C0400081DF9F89E3C3F1C2F83CF6EB1F4FA99D46
-:10C05000CB6979BDE07677303E15AFE1C39884F6C1
-:10C0600079CE06C18DFC382AEA7EC2EF6CC06F24FF
-:10C07000E2557686DD05702930929BE22B1CFF5538
-:10C080006B39FE81CE9F68EDEE37513E33E2F51BF2
-:10C09000B09F32EE0756FF4074DF0BF445F99DB5B3
-:10C0A000D96DC68DC8D3AC3E2C04F97EF5C77B7123
-:10C0B00059F0CDAA37BAE1FAB538C2936C00BD1574
-:10C0C00029473C5170531BFF05DAEB767639003F68
-:10C0D0003273921D6A8727EB8A16DCF76E473F257D
-:10C0E0002E761FFE0BF073DF06D11194A16BA79C77
-:10C0F000479089FFCB641FF9096530CF3A1B3E9505
-:10C10000F3112FF7D919E9DDEB1D6FE03899584C81
-:10C11000FC89713DF443FEDDF106FA1F85493FEFCE
-:10C120007F04EA9140FFE34B93C3B010FDBE8FF94B
-:10C13000BEF845A3A737CAEFC5A8043BB468D3A38C
-:10C14000D103BBA39E57F568A962B7D47EEF437BAA
-:10C1500005F0F1D56F8421DD55FACF443B91DE66C1
-:10C16000271E9C0EFDC3F71EDC1E44FD9F1D0B7693
-:10C170000AFA2C7EF6FD30A6D17F0BFBB82A92502E
-:10C180009FA8764D5C176703FE52F5E5D5D65D9DF9
-:10C19000CE2B24605EA1FA7995E0BC32DBFA9BAE2F
-:10C1A000CCEBEBA57C3E4757F0F9CD68372F6EF707
-:10C1B0001F7CDE6297C92FF044A31C7EBB596475B7
-:10C1C000445FEE375CB2023F0DC0F8CD0AB2EB27F8
-:10C1D000A39984719D4EEDF74A0BF905B3B6F1FDB5
-:10C1E000D653C2F0EEB4F1FFAE27EC2194EB2D2232
-:10C1F000433BD4369E56BBBD2A295A63B7AF116F55
-:10C200001867457B5609A843BEAF6CECCEF09CCBBB
-:10C210008AE1AC41A47D782FE93160218A4F831FE8
-:10C22000AE8B375898DD6A453A75127FFD47F2F9B3
-:10C230002973091FBE14C4BFFAFDAA2E1E5377F43A
-:10C240006B360BE4D754CC1B1E369CE17778DC6C44
-:10C250004B12B753DB143D2738AA292E063E8DED2D
-:10C26000711CD75A1E1F66EFB006C42FC2143F368A
-:10C27000F07908928D150FE471792BDAB51003D996
-:10C28000B5403C7CAD7CA7423490FF5B6EE67EF00F
-:10C2900039819FFF7847B18FEF24717FF8FD241E0D
-:10C2A0008738877E20F47BEE268BBB5640B7D54877
-:10C2B000EB64E3308B1BFD19A335C42366207A8D14
-:10C2C000DFB5CA33E06B0A6B31213DC7E5DCBF093E
-:10C2D000E773B827B3895DA9DA89FB08934933303E
-:10C2E000B6DFF4E57B188F94A1AD086B85C93927BB
-:10C2F0007A63FBB508C3FC0F0735BC877196C3F1A1
-:10C300004686FB02F2DB16B2FFA611DEDE14A7ECB6
-:10C31000C258DD008CC7EC598C7CB4372632CD0670
-:10C32000EDA71ABBD845AE7F469EC7F196097CFFA4
-:10C330006691371BE973235B643B6EA5AD85AD57F2
-:10C34000227F8E7F8CECB8CA0730A6F211F08F21C5
-:10C350008C33560EE15307035E09FE2169DE8455D6
-:10C36000BD70D344EA8F742E4FF019713FC527304A
-:10C37000DF7AC0C31D393EA303E9E5600DE3817F89
-:10C380003DFB9880DF4111C0EFDEE54918857860FC
-:10C3900069120B87FAF14689E05E052C4254F60DCE
-:10C3A000308E7568A8407430582513CEDB59200CA8
-:10C3B000C47DD1F285D736CEA08DBF99B06A18C0A2
-:10C3C00006035FCF3EC4D7B393E523A3C84F1AC675
-:10C3D00004E4C3AA880613ADA3415E70FC03A01B4E
-:10C3E0002DFE261BBD7C7C6530BE5C948B24E2E375
-:10C3F0007BAA05F227ABCC1DC735A293D57D399B0F
-:10C4000084EDE7C0BF90AFE7346E4FC6EFAD103894
-:10C410001FCC51F9EC55BD5C0E4E66C4A79DF1755D
-:10C4200096D27F56B2819FE36AFD5E03D9DD398DD6
-:10C43000EF1FC2756567FD57589887F0F2B685E221
-:10C440000782C19744744144021D26A33F092EE28E
-:10C45000C064EE27AAFC598AFE4722963C2E620051
-:10C46000E589F6B0ACFE7933222DF0FC11383E742C
-:10C470000E68F686C0E79AB88AA8D33B14F714CCA6
-:10C48000BE19381EE1E6203BEAE3C9E6065A9707E3
-:10C49000B633D5733FCBB494FB59B4AF06B0650542
-:10C4A000F73327F7F2F567A4E76CF9423C6BF58B9D
-:10C4B0004BF9A7E179B9CE2FB6601C01E35EABB9A9
-:10C4C0003F6854FCD792157A7F61F2228DBF48DD18
-:10C4D000FA2A70BCA6478229EE62417F42E307FC3C
-:10C4E000DD5028A31E96138C74FED2C402FD0927CA
-:10C4F000E3F14CFEDCA8F88923934DBA7D3779042B
-:10C500004B433C14A31E4A4455E35C8AF1BC0B2CFC
-:10C51000B41EE366A3C44728FE575CCBCFA505C66F
-:10C52000FF2E54BFF72CB6C77A7C3EBFCB4F71B8F5
-:10C53000BF09CB52A77033C87797C3975C281FA059
-:10C54000A84C28EF41FBBF41583084332107BFEF8F
-:10C550007916FB97CD561BEAADA783C3A89F050BA1
-:10C56000048A0F2FB27179FBEACBD0F5A8A7D47853
-:10C57000EF92E199ABF1DCD26F92774FB0F646F5CE
-:10C58000C0E8DC1218C64F1C309FA2CB203704BF76
-:10C5900037C1110E7CFE9E6F8A15F0B46AE37B13DF
-:10C5A0008CC08FE77EEF7B0EE11736EEE7F0EF7C75
-:10C5B000714108271F986004393A57ABF6776082BB
-:10C5C00003F7DDFFC0E13AA897012E46FD86F31E72
-:10C5D00022D0BA7F23DAA5E8B6784FB1E11D5E8E8E
-:10C5E000601EB49F576BF7A764E746B4D762E8B103
-:10C5F00050F42FB6A63A08DE92E87C2C19FDA083F1
-:10C60000EE6ED118C732B016A40BD8314747FBD213
-:10C610001B93B8FC6E4EE1FDA9F8827E9E4E8EBE45
-:10C62000FE7E6E69DF8FFBDF194F9754E8275BD7DB
-:10C63000CF4BFF4E3FE501FDA87E1B38C012EAA993
-:10C64000D3698E77719E737EE318B115F5CF7E9115
-:10C65000F8F4FBEAED2968F7BF7FD51289F66FCEB3
-:10C66000EB3BE34A318EA0F845A79B3E334BF07E6F
-:10C67000A55F640ED0D3557E81CACAAD4DE6FC7469
-:10C680003C57DB64CED38CAB5C192770BA7182C681
-:10C690008FD997ACC69F57D278E7BC7ED288F49CDE
-:10C6A0006368388EE78FD9101EF70A9CDF16E5BD48
-:10C6B000C378DEA08338C047C9DCEF88E9E7D88FAC
-:10C6C000F3DB8CFA1CF9C5C0CF8704B6EF9EC2FB22
-:10C6D0002BEEC2F57CF6417BE9015AF76518442838
-:10C6E000071DAA3697C0F30389230E25771887F410
-:10C6F000F13864238F431647B4CC0363C622522E0D
-:10C700003C81F276FBD3AA7C80E8817E29B0A870B8
-:10C71000D0C491C3789C0BE14B1B0D4FE239C2E6AC
-:10C720002E2DBF3A80F66159285B0F7276EFE0D06C
-:10C73000B82D308EE972B800B6930DB784A64C833D
-:10C740007627128647A4F0F327E41F9E48709EC503
-:10C75000F179E3830DE08C309799C7B35C1F88149F
-:10C76000CF726504BBDC1DE0EBB482CF8814EE9F72
-:10C77000351B609C03711CFC7C2FFCC56DC178D3FC
-:10C78000C23E02F29DFAFD5B1387774DC96EFBFE38
-:10C79000AD89CE9F92A3B5EDC319B6BFD671FC5338
-:10C7A000B1A75D5338BD9CC380BF347A7FC2C860D7
-:10C7B0001D5C34269239B4F1CDA2581D3CA93851E4
-:10C7C000D7FE9E19FD74F5632D2D59D5D7E1EF8B5A
-:10C7D0006169E1B4FECFE6EB90AF1A2F7D3A19FD07
-:10C7E000D80DA25D8079CD7A7BE3A743A97789E252
-:10C7F0005CA79A45B247E0DE9AB5FB2767590B9DC7
-:10C800003B36765D44F66F4E0C3FDF3DCBADDFFF30
-:10C8100050E3F21DED9BA03D2BC773311DED9BB482
-:10C82000C5E37F76FF243345590F0F6403F97AF887
-:10C83000CC5E9829CBDBD144F4AADB27DA9155EB07
-:10C840007A0B4C8071DEBAD5E20E82719FDD79C41D
-:10C850002C69F64FAAFC600022F1BD23663C4F759F
-:10C860002099EBEDCAC6F366867CD1783FC9754B3B
-:10C87000932B2A1AED17F8ABDBB290BF1AB2D0FE99
-:10C88000351B6C4EDC0F9BB37434C599C3FD93A963
-:10C890002CAF1F4DFD56F827125CE90F26F823B187
-:10C8A00065EBC7D8CFD3E136B4E71546F955A44BAD
-:10C8B00085149C89FB55955B3FBEF86BB4A3367E0F
-:10C8C000AF63ACF84916D68FED6333D475C5F10666
-:10C8D000513F2D23BEC842BB5480EB02785EBE257B
-:10C8E000D785723FBC2ED486722FE279B20EF874CF
-:10C8F0006A0AD72F262F1FEF287F21F5D7BABE4F00
-:10C9000049A0F9ABB0297A8311F5873A0F13187C47
-:10C910002C6FF3F7A3B26A6BA111CFC57F90F67CA1
-:10C9200014E209DA876099347228E999EFAB078736
-:10C93000B30EF4965A5A143D3C19F530F45794E668
-:10C94000F835CAE5B847BC462BEAD110AB0DF73F26
-:10C95000C6E50C904A35F311DFB91B5712E0ABF86E
-:10C960004CE8074C8652ABB7A776625FE41483E2CB
-:10C9700017D5F2739DAA7E5FF504C375D8147E5651
-:10C98000AB55AE2A94F6EAFB2D02F707E46D3CAEF8
-:10C990005F91E67A12C7DB329C4DDA42FAB425AEDB
-:10C9A00030F4971B7F98B185E81C66930CB8AFA054
-:10C9B000D6AF6E9D0797EFABCD63B1D2FE23912D1D
-:10C9C00040BEF8E8965B5A1CD06FD3C39999A2C6B3
-:10C9D0004EBD94C2CF35339BEF32E98B5DC112EA75
-:10C9E00081B1B8F790D5E6F7E379488C6B54EDB296
-:10C9F000ACC7F3605561B0CE87EF8FE9E77A09F1F4
-:10CA0000D1B43BF722DEA371E0C20CE4DCD138F8EC
-:10CA1000229EB3775841DBD8D10F72BC4CFABF933A
-:10CA2000F15E4D9F258D9C1385FEC4F73024B4B76D
-:10CA300060F7B30E72D889F8722DE5F2E752E47010
-:10CA40009AC2BF258A1C4E3372399CBA2ADC86F101
-:10CA5000CE924784FE785E8E49A176540126E4CBBF
-:10CA60004CE44FCE97E5FEAE8A3CC72BFD70FE0F1F
-:10CA700094CF4A7F24B553E5F4E534D7216EE75AC5
-:10CA8000B216C0B86E03B946BDE75AD8230BE5A469
-:10CA90008D4FCC36E427E09398520D1FD435FD68B6
-:10CAA000443E310D13884F2C50E669F8C8D9EA9FEF
-:10CAB000D8F2BBA15FB528DEB09CB5D57F95A2FAB0
-:10CAC00029D7C6EF1F28ED4B42C08FA0F84F18C3DF
-:10CAD000F8DA852889E2A47397C1200105734D9E79
-:10CAE000648CC3CCBD3F88E260A507AB97844AED58
-:10CAF000E975B73F83F69727FA93A83C90E83A8DFB
-:10CB0000F898E6BF53C163C635EDCF653B78DCCD01
-:10CB1000E4B6D8D7C563DCCD25D27E5C6F667B9248
-:10CB2000EC94BA1FC7E36E18CFC3F85EE0FE1AC6D6
-:10CB3000E1703D6D8932E8F609DBC5E386EBF7D39A
-:10CB4000CA9B3E196480FA53F10E8ACB79FBB88CEC
-:10CB5000A9308FD913DCAF9BB4FB6C0A1E1B8C9ED3
-:10CB600064B4A30DD51C3F0D2BC402DA6F622CB840
-:10CB700050735EF76A7C3CDB9F48F851ED8BAAB797
-:10CB8000B7D7D0A1CF56FD7D35BB53A1F07B05F2C1
-:10CB9000BBBDBD9D51F935909F55FD6C8A3E487ACD
-:10CBA000E8367805FD07555F17E40D1D86767EE8AB
-:10CBB0004B895BFF0CF38F4C7365A502FFDCF24AD7
-:10CBC000EFAC3500DF66741B6D21D7A20F7F349167
-:10CBD0003E7CA490913E8452AB0F4D9DF8E1B9A9E3
-:10CBE000D7A7CF5395F6E0C772FF10F4B5B6BF8A4A
-:10CBF000B4116370FC85A9DC4EFE52E3EE4C8F1736
-:10CC0000A6AAF2796D7AFC66A5FDD5F4F88C54AE2F
-:10CC1000C703F5366863D2DBE7DEEE4B71B2C30CB7
-:10CC2000F43CDAB3C6606963BCE69C7B9770B75688
-:10CC3000AFC7F49B3E03F9FD1AF4FA7D88BF7F5716
-:10CC4000AFE7176E26BF0AFE9CE36F86F5C76F61DC
-:10CC50007D87F047B0BE8B6F2F0F817210C8F7B081
-:10CC60001ED9FA318CAFF9A93E1477003920BEAF36
-:10CC700000BE473950E5A572EB8070DC37607F114C
-:10CC800019EAFF403928C87BC588712AD4E388AFE8
-:10CC90003D20F3A86702ED843FD5B50AE7AFCA830C
-:10CCA0002A0757E7A39D265C979ACACF733D0FA525
-:10CCB00056CF77E6CFFCE13AF9FFD1D46BF3035EB0
-:10CCC0004DE5F7207E41FE7935F5DAFC82D752FF3B
-:10CCD00023BFE02DE21FD49FB87EBBFD437BF87CD1
-:10CCE000CE3F742E11F8210BE3CECD837ADB314E8B
-:10CCF00073FB15EED7834E27BF3ED0AF9EACE8BF87
-:10CD0000A94A9CE0409AB32595CB2BF9EDC3138338
-:10CD100007A0BDBA567F6F725435C338D35428B5B7
-:10CD20007AC28274EBC05FFF6BEAF5D9EF3DD7485A
-:10CD3000DFE3A9FFB19FE7BB167D90E4B04E447CD2
-:10CD40007EEF3132C4D3D5D603A6D51CCF2ABCD8AA
-:10CD50006354ED6624DA4DE08FF3FF097F8CCD6BD1
-:10CD6000B86805BA86A7198B301E78279EB5A078BB
-:10CD70008669952309F50D53F70528DEF191A8C2C0
-:10CD8000E68323611CB73FC9DAF60DA07ED4B0F06C
-:10CD9000D6F888C0DADA87A5890757D0B8F97915A7
-:10CDA000E6F21AF93E990267011CAA817302E0B506
-:10CDB000BC7D98D1CB6CDA7E14FD33CEC6F705DA94
-:10CDC000F6F37CF95DD1FFDB2AD8707FE19E61E745
-:10CDD000CC18CF199BE7DD1B0BEDE2D3428B42C091
-:10CDE000C4DFB355A0F10ED814B54A4EA2235B0E92
-:10CDF0003C6F589EC3F74D2C0D4DF98E0EF87040C8
-:10CE00009ADE4EE19FB11BC5C7E8CFD22030731622
-:10CE1000EF2721FEDADE47FAD1FB09F4BEC712750F
-:10CE2000EDEFDF358C39DC1DF0D12D698A3EC4B8B9
-:10CE3000B0DA3FD0646283E0E8286E73ABD2BEC53F
-:10CE400060A86080A7F19BD25661DC6B14E37C5133
-:10CE5000B829B548E6FCC71C01F3FDB9F166A7E99E
-:10CE6000D767F827E9DFF7FC1CBE86B6C39742FFF9
-:10CE7000323D9F841B9DEF7E0FE3088F126CE8A765
-:10CE8000563A8356B070A4BBC2D7F2C022C73098BE
-:10CE90005F10D3C5F15AF95ACE2C42BEAE646AFB7C
-:10CEA000EC55487FA7A1B53DE7F346A1F5FD342336
-:10CEB000C34FD0FB733665ADC23839D083EA09362B
-:10CEC000FE0C9F3704C0C302E4827198E412F5326D
-:10CED000E027B983FDDBA50A7ECF0AFC7C53CB0893
-:10CEE000EECFB524F0F2C534EEBF3DAEE0F169A55A
-:10CEF0006CE9A2C143AF363AC39F07D7039A7913AF
-:10CF00009EEE8E52E62D4F2C1A03F36A8960FD05C2
-:10CF1000E093759BC6AF5AA4E193E7374D2C423C92
-:10CF2000B4F627171E443CDEADE0E9C54D130E22D2
-:10CF30001FE1911394B78A1CBEFF6AD9FA7187F278
-:10CF400036B73DFFC8985FA1821809DF131CA62CD5
-:10CF5000DE4F4207F859D0FE7D47C0FBCC14753D2B
-:10CF6000EF2BF4191340BF8200FA8D0C808BF57003
-:10CF70009B1F0C3D83FF54B263E5E26E183FDB2438
-:10CF8000D01D2BD0CF66019E37A6DD5B14D203F9EE
-:10CF90005432C5425B4FDAD483D6BE208FA8BF4837
-:10CFA000FFBA485F4F443927785A91E346E49BEA39
-:10CFB000C531D07E6F5AC92ABCF77ACFA2952644D4
-:10CFC000FA0769335619A1DFBBB3FEB417FB330A66
-:10CFD000A507C7083FC3A7F501F3581B00CB01ED18
-:10CFE000575D459F2F0A78FF9180FA1501F0EA00FE
-:10CFF00078A9FEFD6933F8FEE534A01F22EE6AF23F
-:10D00000E24D6B5D37B4DA2F01EDD9877A7EBFBD73
-:10D010008EC327373D50B4344403A7FDAA48CBBF85
-:10D0200026C55E4C8E723A3AE2DF439DF14F5AA01C
-:10D030005D9375E7120F33A6B3BF7B443DDC24AA92
-:10D04000F2B5F0E0BC74CD7EA05C5B84F194CEF7C9
-:10D050002BE422DCAFB8FD71B57D4D9143333FB574
-:10D060007DFEBFAE88F8BD2B6935451B68FF4FD9E3
-:10D07000BF8BE0E52D97AF84215DF2F1FC28D677D8
-:10D08000F124CF4DD7CC8F35A4E0FC9A1EE6F70DE6
-:10D09000E53AA007C87909B3D3FE775378F8821729
-:10D0A000A0FD9E87C50568BF0E2F88A4F346E3FB4D
-:10D0B000727F7B4F789F6EF701DC143CD58C71D565
-:10D0C000A6474751F98EE858E203E4F7EAFB5851C6
-:10D0D000485FAC0F27BCC4BCB4ACA816E420B6AF04
-:10D0E00044EFBB226CDD76A01FBADCC470FF89312F
-:10D0F000FB73C427BFB3909F3AADB61FEDF794FC06
-:10D10000BE30BF07B42B596CA2F83FFCD17D0CD7C1
-:10D11000F25166AC9FB14829E55BA9DCFDD31B1F2A
-:10D1200066D0BE8E48E77676F9238E8324B3AFE5CA
-:10D13000FE745FE1A8925F656B5F576A5F18C7D79F
-:10D140006792285F0AB3496113D06FBBC191D6378C
-:10D15000BAADDDEE9F44DAAF7AEB4C4937DCDF1B2A
-:10D16000D897F3CB2E7F49B7128D5D2F3D6B243CB2
-:10D17000EF364BF3506FECEED25B90496E1B2231D1
-:10D18000CE3A43F19B814F16BCD1011FF6E92B1219
-:10D190005E8E5916E05958D6F4DBE861382EF5BD9D
-:10D1A000EC83AE3ACC1763EA250DD4FAC7B9C9238C
-:10D1B0006EC6F1B6F1D706D2E7E41F033CBAEFBA68
-:10D1C0005532D80FB607FC7A1C4794231FF9493D06
-:10D1D0008FC7621A52B47185363F74A122FFBCDD3D
-:10D1E00057783818BEFFD5AB4174EEEB2BF98B5056
-:10D1F000AD7FACCAC7CCB0FF39DC42EBE2704988E6
-:10D2000003BE31D61C7F08DE2B7DD6447AB3F4D919
-:10D21000E8477C580FF4C42DC3C0EF3EDF979F074B
-:10D22000E85C3EB6148DECA5958FCD4538DFCEE495
-:10D23000637ADFCD9DC8474D37E4A3FC674D74BECC
-:10D24000BAB84BF59D18472C36DCC8EA607C239EA3
-:10D25000FD5537DC6799F9AC85E8EA0D0D3DCEE761
-:10D26000D5271EE7D56A7FFA727DE5ADCD257B21F6
-:10D270001AC03B03FD2D2E31D17A44EC6626BD2722
-:10D2800086D9797D1716BF10ECF2E2D01C09E9EBC4
-:10D2900056E401EA25E4B3BCF049B7E1B996C30B03
-:10D2A00012691FEC6416DF079BF5D0F361E87F7EFF
-:10D2B000358F9FEF9E8DF976709DFB6FEE7B552924
-:10D2C000F976FEB7F6BD9EE8ABDC1B6ADDF7E2E758
-:10D2D00040F72CC8CCE278619205F1143780F072E7
-:10D2E000AB95494180173182A5A0FE51F7BDC45FBF
-:10D2F00073FD241A045AA71FAB91297F415E9895AC
-:10D300003FFF35BFB7273E55C8681F2CAA9AF6C104
-:10D310004211AF18BF159813E5E768903DEEFE7413
-:10D32000E4BF20A2E7CCE7667DFA872CA4DBD828EF
-:10D330005D3C41E13FF5FD13B537D1F84E08CC8691
-:10D34000F63EEF8FA923913E4DA2EBA9BB496F0694
-:10D35000D3FE39B3797F3718E099B5B0CE66C837B8
-:10D360003DE212D2DBFA99B9F0E114A477DE1F8313
-:10D370003C78FE66C6A2A0D5780EA3BC91DFF39ED2
-:10D38000B6EC7B3A8FCBE28DD518E7FC7A51103F93
-:10D39000A7BE7530F1CF34033FE7C2E2CC145F2A59
-:10D3A0000F51E05E39046BEE2F99911EEAFD9BBD93
-:10D3B000A857E0FBC7557CA0DF887A573D47CFAA26
-:10D3C0002594FF6283D0E139AFBFF5E5FEE9B438BB
-:10D3D0003B9D17AD78CC625F18CFE92C0EC2EF32BF
-:10D3E0005A1755187CF9ABB15F0393B6D970FDD0CD
-:10D3F000528AEB6DB63595F210541999D11C01CFB4
-:10D4000025AECFD4F1544985B7123F19D921630411
-:10D41000E2B1E5D316E48F85A112C6452ABADA5DDA
-:10D42000D46FA8D5C6ED84F25D1C7B22F281DF1C8F
-:10D43000817CF0A960B0F0FC030E03D49F63BCBEF6
-:10D44000F53B8B96A5D3BCAD36C3881EC877E7F3F2
-:10D4500057C37BB73229A107DE135B1679E724ACEB
-:10D460007F4D24BD04C2F4580EFA7BAF8999B84EA3
-:10D470009DB66C0FCD6FCEE6017883804D7BFD00AD
-:10D48000D9A7390A7F7995736B25006F463C2A7AB4
-:10D49000C125B26A8A8729786CC5AF525FB1CC4486
-:10D4A000F4A8586C213A57D4FE8DFAAD086DE98680
-:10D4B000F4A8D866A2FC1DD61BF83C4A6A7B0F3B39
-:10D4C00004E32E3185DB0478542E8F35235C5E2FE8
-:10D4D00010AC7EAF62D95FBB19D2797F585A0C7CF1
-:10D4E0009FB5ADDFE838B467A75F8D8C9BA6A1FB25
-:10D4F000E945DBC370DFF968902719CFF9FAEE0F21
-:10D50000B2E3B942359E767A5132BF0F646B09C5DA
-:10D51000FDEA19F31223D0CE1DB679CC587FB8217D
-:10D520001E8FCC3187CD360C6187F146824F2BE7B9
-:10D5300048E80FF3070A9C6FCA5FDD634E80EFF582
-:10D54000BF81E3E7EC6B47F70E417C001FD950FF2A
-:10D55000C4B5A4A01DAE30B4A4C4227D5E16C85FBD
-:10D5600080F5A903F38F54225F0D047DA8F055E5E3
-:10D57000D6EDF3513E2BDE3C998F783D3B969931A9
-:10D580003E56A1CC1FD68FEF1AA17DC59675F98C9A
-:10D59000BFFF2EF29D6AEF015E6402B8D9CCE18C28
-:10D5A0001BB87E6E367B29EF5DF39D8CD1FE999181
-:10D5B0008DC47640797E0F401495FB69D531137880
-:10D5C000DE3D597B7EAE12EBD3DBEA3BE39BF137CA
-:10D5D00018143A5BC82E8D47BC00EC5DB62D0CF9D3
-:10D5E000E2EC6B7BF60E41B9D822D898561E54391E
-:10D5F0008CF3F17AC0DF1388BF2DE7F3310FC5EC50
-:10D6000033A112D250C5932A6F2A5EAA18C7838A03
-:10D61000972AA38227A5DEA9E0A19CF9A83F76A6B8
-:10D62000BFB411FB7FF347DA6F3B3B8D09FC9C30A5
-:10D63000CF8BA6CECF15A1DFDFAFBD81F3FD146583
-:10D640009EE5366E17CBA398543B80F8CC6156F319
-:10D650004B4293B39B8FE8C6BF5A9183567AE33C03
-:10D66000609C5E03BF2718A8BFE6297C75A476B22C
-:10D6700007F5CA6C19FAC94279B04DC17D4EF6BAA8
-:10D68000A8E86FB0999AEFE6BD7284F81074971409
-:10D69000016B16D3261807FA5F677A53BC30AFBB0D
-:10D6A00097E6BD718C8D19409F1C11BCA13BD01E0B
-:10D6B0003C24929E52C7E9903F247A381AB87C22C3
-:10D6C000BF607CB0552F048CB75619AFC560F7E228
-:10D6D000B960B650A0FB6BE2C2B3A187B8BDA34846
-:10D6E000625BFF37BD8BFB918E8B61924035762359
-:10D6F000B6ABBC189680F6FB88127738B2787B58A8
-:10D7000089860E4F75F69D258325A47F5EC8A18767
-:10D71000518E1E53DA359BED2317A03EB81426E137
-:10D7200079A9E608391DFDA866035BCA22381F1ACD
-:10D73000BBB5E10FE485F007F5D293B636B954C70F
-:10D740000D74F320DDA0BD83CB919DF6312AA3F8A3
-:10D75000BEE8D5E529D34BFAA95690D667B5B5539F
-:10D76000EFE53DAACC9B64A45B9B3D40FE447B67F8
-:10D7700051F21805E641BDB557D738C45F5588D575
-:10D78000804BB8C0FA40B86D3D556D443F9F2D8A1F
-:10D79000D9ABBD97763448A6FB67BE1E225B0FF45B
-:10D7A000A8BDFF7D7E9EB791DFDB52ED34FCAD68F6
-:10D7B000E53F78AF2CEB7C3EEAD717732D74AFA909
-:10D7C0006BBF04FACE29D6601E8EF6FFDB96FC30C6
-:10D7D000A96D7D72D3458F184EFE42BC6E7D507E82
-:10D7E000E65D92E70AD642F7B1A72D3B307630D2FC
-:10D7F000FB25139D1F98511F4F76EEE486E999385B
-:10D80000DF698B93099EB5F13E0E2FE3F90FA72D2B
-:10D81000CE7E01FDAFA3418E7CE467DF4AC186EB7B
-:10D82000ABA11BB31FB907EA8786F6E98AE3FE6A54
-:10D83000C3D1B148F7AF1688A49F1C1B9EBC13EB45
-:10D840001D3B44BC3106EB19DB2398D79419C36DFB
-:10D85000E817A8E70BEB4C5CDF9E51F4C231454F53
-:10D860001C53F82FAFAE2E05FD25DF3AB047B8EFB9
-:10D870006DF695D2F96EC1665F0FFCF2AD2013CC48
-:10D880006CB684DA5CBCCFB296F2E39C4BB6D8D0CF
-:10D890004FBED7C2ECE8D7DEBBBBF7405C2A38945A
-:10D8A00075D5D848FE5D155FEAF74F2BDF65E28A34
-:10D8B00052DA7788941250BF352BE7C68F2AE33DA2
-:10D8C000B9E8A53BD12F38B929398269F07E52C910
-:10D8D000D3340BF4E0960ED67BFE1BD4B8839BBEEC
-:10D8E00053A6C403F799EA7B61DECFC0FB5D27D660
-:10D8F0000559313F6FE03DAF13266E3FDADDF7DAB1
-:10D90000A18703F3DC068EA7753D1378FFBF5F4840
-:10D91000877EBC2A6781EFB7BB4F9E746DE7AB3043
-:10D920002F19DEF7DE7303A3F74606FFEB0DD4D7FE
-:10D93000A5F5161BDEBF3F1624D17A48CE66D24627
-:10D94000B43356291CD7F3C7F665D2F9BFD22F19C5
-:10D95000C955E956D18DA98ADF5D99FAF83080EF73
-:10D96000DB6AB2E3FB2757ADBC938B993ECF420EE7
-:10D97000E3F23913D6491E5BDBBA2870BD347BF560
-:10D9800066BA47F84BAD97D4385220BE73FBE9F323
-:10D990002D04DE9FDB0D6C9333B03DBECFD4B86851
-:10D9A0005DF45D4D1995B90DEBF26225BC4F71E444
-:10D9B000B1A12837A1E1140F3953534D9B78DFED06
-:10D9C000C8BC8CF743DF0A09B7A1BEF8AE66817206
-:10D9D000B940E113852F6FDADA24C6326ADF3814D2
-:10D9E000DAEF0A09A7BB2E498E9C70B4F32A5D03B7
-:10D9F000EF37ABF33BF510A7AB3ADE539BA687A1FD
-:10DA0000DFD9B426B23117FA9383C36DE86FCF54D0
-:10DA1000CEBF1C5FCDF5CDB7D6F017C6E0F999B5EE
-:10DA200013BBE1BAEE3E93CF6C877EED6F1786E1B4
-:10DA30007AFF1BA3370CEF1B7F03ED3D68278C6E2D
-:10DA400011F5DC900246FB78433C4626C5D3963957
-:10DA5000F145EE19A31BE97ADA7371CF15E4A3330C
-:10DA6000068A770166F65C81F6F6D03E1427BC6F15
-:10DA7000275F6FB27F75E1F501F7169FE8C7F5D212
-:10DA800089B56F8CA3F5F906930DC7F9DD86BF76CE
-:10DA9000C37338B3193F5FFFED2681E6311BF831C0
-:10DAA000281EF5038F83CE06BD6F15DAF361DEA65F
-:10DAB0005AE2C3D9C08716F4D31C3C1FF36CCCC701
-:10DAC0002CB176F93FBA2A7C3707F80EEFEFFED279
-:10DAD000793F96F70B3CB7CAF950A5BB8A1795FE5C
-:10DAE0006D7CC874F905231A060C8F656DFA40BD6C
-:10DAF000DFC18CDE15784F63BE185A8FF9AAF61B6A
-:10DB0000ABFF48795B6423DB48F69CA561BEBCF99A
-:10DB1000E20D768C07D699AB5BF3BA607D605E1739
-:10DB20003184BF5F88F98961BE21E9F1F4BD09360E
-:10DB3000FB2844B729CA4B710131CFE0A07B79752E
-:10DB4000165A3707EAA15714FADE86BE03FA3DFDDE
-:10DB5000F8796DF5DE9F5A82A1E98DFC5E181C7183
-:10DB60004982263B5EF9FC0EDCA72D1C1AF1AB4462
-:10DB7000F87E53BF2377E0BD8DC2CC886D0900EFDE
-:10DB800079E5EFBCFEC6886C13FA01C2D7778C44E6
-:10DB9000BFB19FE3CD7E9AEFA8FDC2F39DF8FCF3E1
-:10DBA00038D7DBFDF8BE6929D2FB9C10C6F3BD2532
-:10DBB000F9280EAABEF7B1C00EBF25B4C15E138B03
-:10DBC000C3BC06CDFDB83EEDAC8C4A77ECE5DFD7A3
-:10DBD0003F470A7D8FEB4C65FFC76095CCE8FF3966
-:10DBE000ED663BCFAFC89C56F0ABC62BFC5B62BD6D
-:10DBF0003C92EC6F35B35B3081C952FD7DACBE6D9C
-:10DC0000F7F6D65ECFBD3D26F33C7C754A1EBECEF0
-:10DC1000EE510A8DEFFF88FE65E0FDA9CCBFB4BCD4
-:10DC2000897C320EF80AED45560B87C72B7C52B122
-:10DC30007D2CE57B9EFBB1C98D7EC22CC51F4B722E
-:10DC4000756112B4BB04F28B7AE1CC384F0AEA8FCB
-:10DC50001335AC3E09145681D5E543BA34C7BF4FDE
-:10DC600079D14EACAD0B43BFE72CAC27C64017E5CE
-:10DC70008A7FCF2E8B9E5BD00F8EEFBB7EB986DF67
-:10DC80007EECC7EDFF99784F1CAE6FE4780BCFD7D1
-:10DC900078790FE5792E48189D8D71A4FD353BD814
-:10DCA000D1E4B6F73ABB8F32C43082A56BF625C7F4
-:10DCB000193B3EA7F1AD9A4F7303B7DF16633DE5FD
-:10DCC000D1025256D712ECA4B8520CF228C687A53E
-:10DCD00007085E328BD9E81E6BDB3E1DDD0755E978
-:10DCE000EFB05F1989EDC601FD51DF18AC3E23C2CC
-:10DCF000CE027E3EA52F100EF5894AFF51E2238FFA
-:10DD0000211DE62AF7B8E60AD51C3659E99C6BA016
-:10DD10007EC4B86631E94D796F2EFA63A02729AF2A
-:10DD200082A21725F81FE545CA5967A66657CF8B0B
-:10DD3000B437F73FD08F19E9FA3CE22A9D54FFAA85
-:10DD4000333AA97A12E835E87AE8A5E6299BFB2C54
-:10DD50008F77CE7D767ACC40C21B481CFA43317F48
-:10DD6000A2B8CA4C650E6C6D24F1B1698453427D32
-:10DD70003B76472C93E0D1AC1D029D6F1DB32392DF
-:10DD8000E0307F0F9E5749B1F7635FEC3E02E393AB
-:10DD9000275FF8621EE6BD1FF35B46F16343700820
-:10DDA000E59B104728791CC490F7F01EEB05C95875
-:10DDB0008DF6CAC9DAE50F3010FD9BF9395958E5DF
-:10DDC000C99C4EFCDEDFDC7DDCCECF1DCEF7052FFF
-:10DDD000E01BD0FE429148799A9E0ECE20FFADEE18
-:10DDE0000E13DD8F60B2E3135C574D52F8C112037E
-:10DDF0000B4B0DBD822490570D7D1E0D7AEC3D1707
-:10DE0000F4EF857597D013FCD8B4085DBD510EFAB8
-:10DE100006F3C79A62449B1BC61F6AEFA9EBCF2982
-:10DE2000969B309EC25CDC8F56F98B89678C746F31
-:10DE30007E18CF5F71C724FD3D49D3B0F323C9DEFF
-:10DE40000CD3FBDFCEABE46D5AA0F2535FD657C9BB
-:10DE50004B4FF6FFC2417E3F4462CED5AABCA0FE26
-:10DE600007EFE669C4CF9DCD26E696087FAF61FD3A
-:10DE700005D962C37840AB1F9E04EF45A191B4124F
-:10DE80009F635E50ED3C312FA8162F9817540B63FB
-:10DE90005E506D7BCC0BAAADC7BCA0DA7ACC0BAAC6
-:10DEA00085312FA8B63DE605D5C2981754DB1EF381
-:10DEB000826A61CC0BAA6D8F7941B5F59817545BD6
-:10DEC0008F7941B530E605D5B6C7BCA0DA7ACC0B60
-:10DED000AAADC7BCA05A18F3826ADB635E506D3DE1
-:10DEE000E605D5D6635E502D8C7941B5ED312FA86E
-:10DEF00016C6BCA0DAF69817540B635E506D7BCC47
-:10DF00000BAAADC73CA0DA7ACCFBA98531EFA7B646
-:10DF10007D0B5B948C766C67BCAB393D1AF79DBE6C
-:10DF2000257E3E742FF033CA61F3441BE52FBCCE2F
-:10DF300075624BBAB26E51F8F7120B9982E7D03B7B
-:10DF40007B5FE5CF97F09D6CB2074B897F59683DA9
-:10DF5000FA738F1A1D741F4A6EE0F7139991FB0133
-:10DF6000F345C5FF51F242CC1725F2033077B0518B
-:10DF7000339EAE0E2B336AF0105960D3C1D1CE1848
-:10DF80005DFBEE93245D7D0F579AAE3EB6CCAE831B
-:10DF90007B57E7E8DAF759E0D0C1F17281AE7DE254
-:10DFA00052A70E4EAE9FA46B9FBADAA5ABEFEB2E35
-:10DFB000D3D5F7DB54AD83FB372CD0B5BF7187AC1D
-:10DFC000AB1FE059AAABCF6CAED7C1D92DAB75ED65
-:10DFD000071F72EBEA73BD9B74F543BF6DD0C13769
-:10DFE000F976E8DADFE2F7E8E0E16C9FAE7D9EF5D6
-:10DFF000631D3CCAF699AEFDAD314774F5A3A593F8
-:10E00000BAFAF2D3DCBF6775B03EC0386508CFAF4F
-:10E0100051E9610DE85FDC9E765ED7DE1405EB0505
-:10E02000E09F0AD087E8F7FDD0258EF231B3EA30C1
-:10E030003BDEFB964754FF517BCF7BACFD47DDF7C2
-:10E040009F0E0EF304D1FAC24AF6F6A6FEFCBE59A4
-:10E050006B3E11F53E3BF3B198280A09F9D03F1207
-:10E06000F01796000E73F0BCD0E00791FF6403BF79
-:10E0700008FDCDD67591213E1EED72709B5FDCEBE5
-:10E080008A26CFCBD5FCE2DBF1DBD994A7D7D11F11
-:10E09000CAD90D9BF3719D358BC94B703F51CDB3E0
-:10E0A000B83F481FDF52CBD156C0AFE67BFB82EAB8
-:10E0B0007B0DFC19791F6D3D43ED5BFB55E25F0263
-:10E0C0004C76AEA6FFC760FD6704B9AEAF01F90399
-:10E0D0007FE8891A1BC1AB6A62087EAA46A27275E4
-:10E0E0004D1A95CFD4D8A97E6D4D0EC1CFD5380825
-:10E0F00076D71450B9BEC649CF37D44C22F8851A0A
-:10E1000017959B6ACAA87CB9A69AEA5FAD5940F0F8
-:10E11000EB3532950D354BE9F9969A7A82B7D6AC44
-:10E1200026F8CD1A37953B6A3651F9E79A06AA6F59
-:10E1300004FF0DE15D351E823D35CD04BF53D34252
-:10E14000F0BB358708DE5BE3A5B2B9E65B2A3FA8E2
-:10E15000F151FD5F6AFC049F51F621E6F71774F751
-:10E16000F154D8C88E717F0FF356601E861CD3778A
-:10E170003F971F37900EA794FE4D23C05DC23872A3
-:10E18000CF94F5759A75455D7F1EB7AC35F0FC2DC3
-:10E19000B53D99AD8EFC7607E3E7B4B8DF3E13FFDB
-:10E1A00025C1D3A89ABDB8DE28ADE679CAB3911FC0
-:10E1B000D3881FFF725DEB34655DB025D1F904F2A1
-:10E1C000230B717F1A9FD5768FFE40A2EBF7F8FCE8
-:10E1D00042F57D7BB1F54C9B3D053F32D6E289C6C9
-:10E1E000FC5FBE7DA27DBDD4F9F7AA94FB0F9DD63E
-:10E1F000EF3AD90BED55C14F22C5F5F79B4227E108
-:10E200003EFF8B0A3E5EEC6FD0957725395FE88F35
-:10E21000FBFBC9D52F3C20B4DDDF1F8F4B7C90EF7B
-:10E220004226511E9C89CCF11EBAE077802388F0EB
-:10E230005D4CA6F24482EB4F389FBB610182B06B0C
-:10E240008825AEA3F9048E67A7329E9DCA38D47282
-:10E250006E927307F6772CD9A11BCF8B4A7EA171E2
-:10E26000CCF71C8EEB1F6F9F3F2E24B6E1BB359E73
-:10E27000C2AA294F4631E3F19447312F46545B5EE1
-:10E280000C75FD50BC8FFFCE11FDA1FD9C1F4FEB07
-:10E29000DBC0BC194B86EFE17930603D86F77F8BA0
-:10E2A000EFFF15E95FFC3D28BCB73BBFCB61CA332C
-:10E2B000E39D05BC1A4B793578DE1B17203096F2AA
-:10E2C0006A50BD7003FCBF078ECB9A66A4F175A19E
-:10E2D0007C274F07EFA7BC341853B074C5BCC7F1F7
-:10E2E00034CFFDCEF3DCEF8EF2D1FDD42D89AEAF6D
-:10E2F000FAF338F953991827427EC2EFD8DC747EBE
-:10E300000DF8C92C008A6646013F75E06FA87C5362
-:10E31000A9DCC3519F033F9E407C7FB773701AF204
-:10E320004DD5AE5C09F15D67E0F7E9E40F947D41FE
-:10E33000E5F710C4F0F47574EF009D71A46F6E28BA
-:10E34000DD3B6812D982CD1DE8576B06A7F3FE1896
-:10E350009E4FB22E607F52C8E07417947663DFD967
-:10E360004779C82A9B79BC9A6579D39D1D9CCBAA15
-:10E370005AF0DBA79234F3A8DA71849FE762DE7467
-:10E38000ED392E49E957E53FD11CEA5A17A21D5F26
-:10E39000AB1C5832B2490E8EE3BDEE711629FC2E2D
-:10E3A000817E1FEC3BCC2FE3FAA38DCE03AAE702BC
-:10E3B0006730279533C17222DF3BE595747F7E3647
-:10E3C0006BA0E79539D3E310AE62BE9131B83E5AE7
-:10E3D0005AFB1E868326D6AF1CD503E635C13DED1C
-:10E3E0003D2C0B3708C76589E42806BFEF15AA172F
-:10E3F000F784EFDDF3EAF0C518B71E27723AB00FC5
-:10E40000391D8A819FC588F6F303B9E993114D72CE
-:10E4100043E357E5A6782173E0F903F57E48AB1C8A
-:10E42000E5CCF97B2CEEE1803F89FC5AB5CB12415B
-:10E43000EB53CC3383FA4A919FC546EE5FCA98DA14
-:10E4400094F427F7374C0E259F17E3FEC81C99AFAD
-:10E45000C74E99B8BC9DFA2AD48DFC3DBFCBEB7159
-:10E46000241F26553E7E9A42E77B18F81F37B7F7E0
-:10E470003F5AF3CCF462E46FB03857CCC0C4367B5B
-:10E480007ECAE01E14C6F3F23B105F7B63F8FA7994
-:10E490000EE6A1C1FAAE4E09E3A5A7A2AD745F28AE
-:10E4A00030CF1963769A9F49991F8C6C12FAD31654
-:10E4B00025AE561730DF1F82E268BED270D6C0D0BC
-:10E4C000B130DAE4E928F70F703B31BFCB6F5CF86D
-:10E4D0007D6F10B30943693E148F950DCC59C7E386
-:10E4E000B334BF0546AB0DCFE52C99267A05B213A0
-:10E4F000304E8CE74559ED3CAFAA9A7F3B70BC0E7D
-:10E50000FDF8AC710CE7E710992F68281F2F8E4F8C
-:10E51000067A107D009EA6191FF4EBA6FC3FC1925F
-:10E520000DFDB0E67F3DC0E3CBB5DC7F84F16F220B
-:10E53000FAF480F1C75E7DFC26645118FFDC0CAE56
-:10E54000A7EA700751443BDB95F4EF8420E7FDC850
-:10E550008749AEE5BDE6625C23D762C7F81DBB5CA8
-:10E56000D70BF554089328AFD63807CFAB05DD2D70
-:10E57000427E28C4BC7536F203CE68F3B0B180F891
-:10E580001A9085E2AB1330BEC6EF12BD8BF1D9896C
-:10E59000CAF9E6BEEC4B157F145F13717C14AF769D
-:10E5A000D1382D4859288330CE437470D33C82999A
-:10E5B000478967B7907FB052E1C3218718D9892175
-:10E5C00021DC4EEC3AC2DC78EEABE9C73BF342A16A
-:10E5D0007ED77923E929C013E503FCF35FB95DD940
-:10E5E00075F2782CEE07D4FEB83716FDC45D269779
-:10E5F0005885EFE75A6C0BED6D718DC643213CAE2B
-:10E60000A3C4F96E52E6D9C85AEAAAA03EA787C8A1
-:10E61000300E987DD0138CF28C396A3BDA6F1C7601
-:10E62000D1ACFB5D0B934D0FE7300D1C8F21B280F9
-:10E63000DFFFBCCE75EE6B199DFCEEE799A86BFA77
-:10E64000DDCF2C651E8F6638DFCC20BB364154F001
-:10E650002E20BE400F3421BE9FA930D3EF1A34556F
-:10E66000987B7835E3AB9FF50FC2EFEE7FFD83EC2F
-:10E67000D6EE6C353F4E43103E37CBA114777BE688
-:10E68000B281E26E6BCABEA6F5497D0EA3DF11AB67
-:10E69000BF5C427EC0A502869B48ACF6E6FF53866F
-:10E6A000F0E33759E97B81E37F1BFC790F10EA2DFA
-:10E6B000F0E73DA9E0AF803F8F30DE67C5721BF801
-:10E6C000F358BAC19FC7F239F0E7B11DFAF3583ECB
-:10E6D00003FE3C96ABC19FC7F229F0E7B1DD2AF0FB
-:10E6E000E7B17C02FC797C0EE3CAA3711D62746FF2
-:10E6F0007F6170D832F433243994FC8D8F1C03BBB6
-:10E70000783576F6E68B061D9D879DD1FFBECD90B0
-:10E710006311BADF3FC9F9B2A7AE7ED0C1045D7DF7
-:10E72000BCACFF7D9B3E0B7EFEF76D62CB4604FCCE
-:10E730003ECE6D01BF9FA3FF7D9B68E73D01BFBF3C
-:10E74000A3FF7D9BC7957C992A1D53A4D782902F48
-:10E75000D6944D08671DF8176AF984420F157EF2AA
-:10E760002171524771E4F01BB9BD7FE72BCBBE0D81
-:10E7700080CFDD2CDC8971F7DD0E03E9A5675687B4
-:10E78000501CD6E21D7212F967B78349C83FCF5CAF
-:10E790001ED105C7331CC888CF63CBB87DEA79A3E7
-:10E7A00044FC1C5BE613F1BEE82D977D76E4C72799
-:10E7B000C3F8EF6C41BFEE85D0DF3B6307F5C5388A
-:10E7C000CE3321C0CF286F1E5F7012C0E1570C0CF2
-:10E7D000F523D84ACAF32FFF2144398F7A85EEC337
-:10E7E00085A34E07BDB4BB8C7F3FC57B3958EB0F6B
-:10E7F0003DFED3D5F0C288AF3AADBF6D76028EB77D
-:10E800000DEFA01AA14C6165EC31C44739979FFA0E
-:10E810003203C9D3259027C40FCC9AE8C25AF4F228
-:10E82000FE04CA87960EE509CB709ECFAC32D26E3D
-:10E83000D928F1D57D37C22B6B0E8AB4CD2ED97C69
-:10E84000C11DF977EAB8D738F8FC22ECCC80762ED7
-:10E8500002F0E9A6FD6C7BADF6F7ACFEA0C8E7EFD1
-:10E8600015F97C5AE1075C6F233C4A5C3B3A05C7CB
-:10E8700091C3F535D053C0FB58976630FA1DD1DFF0
-:10E88000172574E928CFF72A651CCF29F35A8BFD89
-:10E89000923C73B91F25160FC77ED63819E9F1359A
-:10E8A0008EAF6B316E77A988F7DBE711AF80F8ED9B
-:10E8B00055ED13B0FFDEF33C54BA9571F62C6BA105
-:10E8C0007AB53FC9EEE6FC5EFE356B86F9E2215B68
-:10E8D00091ECC519CA8FBAC668646887519F217CBC
-:10E8E000C96AC43312ACE7AC630CEF33D78718693D
-:10E8F0009F624DE5298257DA381C2657A7E3F98B2A
-:10E900009DCA7CC264996077C07C52A4A9E1DADF19
-:10E91000730D2CB72B78DEA6E063A7C965B800E3BA
-:10E9200018FC37917EBFA3B3F7543B9BF3A521405E
-:10E93000FF74D1C93FFEC69E62171EBA11D7CFB26F
-:10E9400093EC82BA6EDB3686DBD795C1533EC47535
-:10E950007F91C2474F078F7B0FEB0F8CE6BF83D3AE
-:10E9600034FAD6DE5A3DB94319F77605EFB9B2E36A
-:10E97000AB79D0BED069C191811973F4FE15F4E76B
-:10E980001C23DA3D40B783D9AA3C388351EEDE1907
-:10E99000339D1DC2FE0BF8BED3B68289F45C62CEF5
-:10E9A000DBFBC37B9FB418C99F81E73F2B8FFB150F
-:10E9B000FCFF4519C7070AFE9B153EDD8B76241523
-:10E9C000E32C6954BEA3D8118F6247762976A451EF
-:10E9D000B1233BD18EA4E2BC2651B94DB12359A33A
-:10E9E0009F243FE912E6C515D08E54B22530CE7C67
-:10E9F00018BFD8817D1B9F2306FC4E56B08E4EB7A4
-:10EA0000A745EAE0D1526CC0EF742506FC8E573F53
-:10EA10005D7D9E3533E077C086EADADFE21F11F0D4
-:10EA20003B627A3B32E4D804BD3FF3E53DBAFA419C
-:10EA3000074B74F532FE03E69B7D8CF1FCB2C1C33B
-:10EA40007E87FC927DDCA8FE3E33EDA3A9FE56A096
-:10EA5000FF93CD5AF7F10CB48F273309CF75D256F7
-:10EA60006582AE9EFCA78326672C9E3FAC2D04BE1C
-:10EA7000C37388074BC730DA8707FE0579CA769ECD
-:10EA8000F892F28D8AC599E4275D34EAF6D37203D1
-:10EA9000F6C59C23F5FB66D957D937FBFB8DCABE5B
-:10EAA000433B7F2CE29AFC31902711C7FD74F09410
-:10EAB0003D88B79D9F713BD5F4D983B1F8FC5D6C5F
-:10EAC0000AFD6CFFE641F2BBB6B7CA872B58EB6F65
-:10EAD0006DF3727BF1E6C1841DB8CEC88A16480F6B
-:10EAE000661D993B99F8F1A0817E9F33A5A02A1855
-:10EAF000F1B2EDD0C260FDFD298D7E204269F48324
-:10EB000088AC1CA1AF8FD2F06102278EB6FDFF0545
-:10EB10006B92E82C00800000000000001F8B0800B2
-:10EB200000000000000BED7D0B7814D5BDF8999D19
-:10EB30007D25BB81CD03DD401226E161541E9BF78C
-:10EB40002624611202460DB0101E414298243C5208
-:10EB5000AB3655ABD18FDE4C08841051A2B515AC45
-:10EB60008F958AEDEDE316AD045494E5E903840531
-:10EB70008346455D10D1DBD2BF28D0DA7EF4F37F27
-:10EB80007EBF7326D9193601FAB8ADBD37F9747254
-:10EB900066CE9C39E7F77E9D0321D790809DE0CF1C
-:10EBA000D722FC3FD3D02E2081F4F076A9A17D831B
-:10EBB000A1FF4C43FB2643FF3ADDF3ADA19983153A
-:10EBC00027FD1B7E265E78DDDC4C48E0AABE7E3940
-:10EBD000669FE8197361BFDC6E53DFB8F4BF1D1F79
-:10EBE0002C319D4B20A4AB5BF4DB52E9F5E812A27B
-:10EBF00066D371BA4D7E22E0D544E8F3AD3DAC6DED
-:10EC000023AA631C7DBEB9DBECE99008D9CEBF3BDB
-:10EC1000DAB770B02F869089E6D311BF2B9F37F5F6
-:10EC2000AD8FC07833079308FDB4EB4E3E6EA0D98C
-:10EC30008ED76DCD2E12B0F53D176372BA7D741E5E
-:10EC40005D219387DEA6F32F8D2774DDBB9C8B1D82
-:10EC5000302E9D2F214329163C49552D230991E83B
-:10EC6000BC4D741D9B4326D241D7997D847D3FDBEB
-:10EC700022C7BB22C09510931EFE178C477F004E03
-:10EC80004ED1DF41E1B2F38339F1E3E8F82F748B21
-:10EC900004E663551A1CBEB1B4DDC3E6A58D3BC9BD
-:10ECA0002EEAE050421C3A7C149D8ED3B5B38FD12E
-:10ECB00079D2F7ADD2F47880EFC5E64948B4818EB9
-:10ECC000E20CEDA1BAFEA3258AB7B1FDE3E1058E02
-:10ECD00087CD8007BAB017A23C55BE08F0DAFCA178
-:10ECE000B5C11F76FF3F3C142843E06AC26BF63182
-:10ECF000932740E173AEDBE401E0E5BB3AC5C6080B
-:10ED0000E3149CD0D3676E77B40E5E44AC1E900FB4
-:10ED10009A8EB6ACDA1DD6FF1E4F4CC24907FD23B2
-:10ED20008FE4E1FA2FF2FE1F9BD555BB2D948E295F
-:10ED3000C96EA2FD88AB9290C4FEFB13B29C325BFD
-:10ED40001F1C892B9E2EEE52F0D489EF5D80AF7E82
-:10ED5000DEEF1B4765F0A4E0857EABC6F97EE88157
-:10ED600071423344F8FE838EDBC4109DF7238EDBA3
-:10ED700076017DEEFF935502BEDEF1A7AE24B8BF4B
-:10ED80002F634B12D0FD3EFA4E10D667A658A36DE6
-:10ED9000ABBAC001F4F546F761E41F89046F1C9F0C
-:10EDA0000D6D93A783767B39BD723019006EAF71FC
-:10EDB0003AD9CBF97537E7D79DCD6ECEC7125E5FD6
-:10EDC000694EC7FBDB9A3DD87EB1D98BEDADCD3214
-:10EDD000B6BB9ACBF17AA8D987F70F365761FBCD2E
-:10EDE0006685D161FA1D65208FCE255100D0752D25
-:10EDF000774C3347C2E7F5929ECFAE73EBF96C3296
-:10EE00008573787B927D98812F47E89E4FFCEA1AA4
-:10EE1000DDF3A2D399BAF684CF0A74FDF343A5BA01
-:10EE2000765ECF0DBAFE33CB2A75CF7D85F3F5F331
-:10EE3000139D285FB6BB0494CBD3B2EB75CFB7C399
-:10EE40001F2087ED825F4D05B8540E284F03801FA9
-:10EE50001BC091F1F1AB1C3F7B003F36C00B83FF21
-:10EE6000CB007FDA7E09E04DAF3967955D83259051
-:10EE7000030DD8B6A60F767A28FC5F768A28FFB7EE
-:10EE80003437E27BFBCED59D1571BE0E09F0B29DE5
-:10EE9000CF679F45392B26405B90960B17CE2BA74B
-:10EEA00047CFEFA3CB17A2DCDCDE7DDC01F4F6CA92
-:10EEB0005797A6F7B47EAF92CA49401FC5DD545795
-:10EEC000A55E5CFF697AEB62E36BFD40AF46D2174B
-:10EED000C6716FF84A11095DC7CB3DEA0F62A01DEC
-:10EEE000F89628D1766E8F3209F0B63B5D708902B4
-:10EEF000F69B24C3BCCF1FBE11EEBF12329B60DE57
-:10EF0000FBCFC71158C776AA776DB4DF1B64C49ACC
-:10EF1000F114DE819E2FF7015FAA4E8B6714B97042
-:10EF20001E291922CA87CD636C26613CE83B330950
-:10EF30008C013E57109E5D5FA539E1BA395DE4F75B
-:10EF400083C8EF5767B8F0BD97CF672640DB448290
-:10EF5000280F02674DE5FE08EBBD1ABE436548CE9B
-:10EF6000F98F1C2EDA7FEFD93A07C897577AD8F86D
-:10EF700039CB420E80D3BEAF3638E1FEF6F42C1CFE
-:10EF800077C7D8A5685F6C3F6B42BADE3E669533A3
-:10EF9000331BD7E901D86D3F5BB72603E8BAC78CAE
-:10EFA0006D89282408F496CEF4ECE6B375E4307D40
-:10EFB0007ECE23FA81CE7248E7DE4170FF8A555635
-:10EFC00092C6E06FBE82905BD9CB64924B2F074A0A
-:10EFD0007BF4FAC41AAA9E3503EC08A067DA9E6A8D
-:10EFE0008ED73DDFF7EEF2849980170A6FB8F7CA23
-:10EFF000D9DBF78D05F9E367EDDF1F7DDA3A985E1F
-:10F000005BC6AE1A761BF4DBECF0D82478A2902F06
-:10F01000693BEFACD90FF6468E533F8F7D57572291
-:10F02000DC379F65F6D5B974B69EED9E7AF2007D09
-:10F03000EF656E7F4D3A36B202BEB79FDA4F60572A
-:10F04000BCE4F94D7C16C833AFA8A3370A1FA497B8
-:10F0500073DD04C7A13F83A6523814B22E940F7DEE
-:10F06000ADDFA1CFF7E5DB5CCB29AAB79FDFB9EB1A
-:10F0700076DACE4B14894857F22DBF7E7EF93F7366
-:10F08000E8DAB77EA6B74B6C44E0FADC8972A03FA1
-:10F09000FE9970DAAA7B6FAAD9A61B378F843D47E9
-:10F0A0007C5AFB9EA75EDC3ED9C2E59A669F6CB196
-:10F0B00028F37D40D7C15917D1A3CBB9FE6D447950
-:10F0C000B195104F470695EB578B32F0E1B9A37617
-:10F0D0008463DE23332610D4D7CA04E00724C63065
-:10F0E0007BC07BF422F68A4B2509B9FC5304AEE6BB
-:10F0F0009321DABF9DAAF9AF4187737D6E1CB73F9C
-:10F10000BDFFA06310CAFDC232A6171E711C403D90
-:10F11000DFF501D5F302FB4688E27D36FC017AFF7C
-:10F12000032BF67FE97A01E58866375412D94255F8
-:10F130001C99E63D6BBE9FE2CF67AF197B2BBDBE2E
-:10F14000F46ED730E0DF97C03E40F9D0E860F6417A
-:10F150008C1A4FA7B8ADC7867CB8E5B489D8C16F03
-:10F16000D866433AA57C7ADF58FA9D6D41662F74C4
-:10F170009DE6F6DE3607F2C98EDFB379742D733063
-:10F180003FE39455067B7CCBB21884F36829266054
-:10F1900086F19AD8F83D1CAF6F73BCEEE3FAEA75BE
-:10F1A000AEAF5E057B02F517B32776813D41AF3BDD
-:10F1B000B83DB11DF419BD3E7FFAB9F7812FCF6D6F
-:10F1C0008B42BB733449DF04F3DAE6B4E23C8D7062
-:10F1D0009EA7E8F9606E95DE6EA818A3B71B6E189F
-:10F1E000394CD72E4F1AA17B7F4AC2B5BAE765CEFC
-:10F1F0002CBD3C324FD0B5E5F37ABB61BAF7463D42
-:10F200003DC9617603CA3BBDDF383BDC6F4C053C32
-:10F21000313F674BCFED88C72D47D3062B6176C2B0
-:10F22000560EE72D4799FEDC1AFA32468960477C74
-:10F23000C6FBFD96E3E314C7C77FA7C82732860045
-:10F24000BF7CC9E46F3F74ACBDAFBDF799FFE3412C
-:10F25000E17A7DB828219368EDDF77BD3F1A9E5F84
-:10F260002A5F503A6D0F513CDF2DC67476D0575649
-:10F27000991B9F84B6AA9AC9C66C0447BA199F5FA6
-:10F28000E30179DC1AD3F85378BEB9C5E6DA900009
-:10F290007CF41FBF86761365051BBDFE312AC54F62
-:10F2A00028AB59334D38AF672CBE611ED09B826F9F
-:10F2B000FEADB4BFBADEEAD9285D381F67A6A0311B
-:10F2C000FB56D04322E7FB3F0B8A3393DE977F291F
-:10F2D000A09C8E9208EA051BF105807F48833C1FA5
-:10F2E000F8839828FFD0EBBD594A1CF42732915C73
-:10F2F000741C646DFA3D21B8F74F029D978534AABE
-:10F30000308EAD814A18CACF0F662889D8DF3C13EA
-:10F31000C77F7E2A2120CFE872B09D7D177175C40A
-:10F32000D2F911C5F4256DCFA7FE3E7CDFE4B80508
-:10F33000F5D4FBFF6DF28B11ECA55E38DF62391559
-:10F34000D2E82CED42FAE9E274B135D587F2D7F86C
-:10F350007E6626F307B77C344D04FACAB60F92C115
-:10F36000AEA00B146750F9BEF5F80D8EDA08EF4D1C
-:10F37000CEAECDCC1CD2D7CE0E6E126B9DE8CF8B0D
-:10F38000B0AECDF46F58D78BDDA600E0F79CD38AE2
-:10F39000F2A4BF75E487F471883CB007C2F88D9081
-:10F3A0006AD7C96B01DE9DC2D7D786D3977C5F38F9
-:10F3B0007D3D7F217D219CEF7E2B1DE1DA2A30FAF5
-:10F3C00052297DC173B5B411E94B35115F6B36D24B
-:10F3D0001BBEDF64B6BB6C54422ECD4C43BAE98AE7
-:10F3E000A9783F20E1F746CC447FAE86FB733528F1
-:10F3F000E75F3FC2E4BC715D3B8ECC1916027B62B5
-:10F40000D4DC61C0E75DA00086C2F473E7817DD9DA
-:10F41000DBA6E8423B70328190157D9E3D4F86FE13
-:10F42000D76BED1CD6BF84F55F92F9F07A159E2F4D
-:10F43000E0CF4925EBAFB5D5BC7925D0DF62C2F668
-:10F4400007BCFF431E7929D0E383197203E02F0321
-:10F450008C167AFD64BC7C33DC5F9A4970BD778D75
-:10F46000976F096FFF669C7C5B787B73AF9FDAC9EF
-:10F47000FDD45BD12E7DBD6726DAB312F1DD087AAB
-:10F48000E7F5208B476D1E39B01F7480DBF3FBB9A5
-:10F490009FFA06C8A3AB409F303F750FF7537771B3
-:10F4A000BDB283FBA9DBB95E7999FB492F713FE9B6
-:10F4B00005F053AF023BA48AC749989F9A3D6A5210
-:10F4C00019DA112ECD4F4D89E8A74EF7EAF5CD5444
-:10F4D0008F5EDFDC981E6FD02F7A7D332541AF6FB2
-:10F4E000CA9CD71AF44B96AEBF7C5EEFA7169F2D31
-:10F4F000D5F52F3CA5F7530B4ECCD4F55F9A2921B7
-:10F500001EBD476FD2F5CBEDAED3F5EBC39B0FF12C
-:10F5100064551F77821DB779643DC71BB31734BC90
-:10F52000755D046FAF72BCEDE178DBC5F1B683E3C6
-:10F530006D3BB7075EE6787B89DB032F70BC6DE11E
-:10F5400078DBCCE30B0738DEF673BCBDC1FDDDEC28
-:10F5500051BBD03F3B779A70BC3D2146C25B79924C
-:10F5600068C083C380073DDE4ACDC30C784833E0D2
-:10F57000E11A5DBBF054A6010F05BAB6F768A90100
-:10F58000FE3718EC864ADD730D6F533DF30DF455CD
-:10F59000AFEB77C9FCE66476DE5FCB6F7BB91DB756
-:10F5A0009BE36D27E00DE3441E1E8FF0F2B82FB3EE
-:10F5B000E35EE478DBCAE3425D8037B0EF38DE5AC1
-:10F5C000479E413BFEDC790D6F0722E2ED72F9EDBB
-:10F5D0003AB73E2E34D9A58F0B4DB2EBF9AD84E886
-:10F5E000EDBB895FE9F9ADE8B4DEBE9BF0999EDF23
-:10F5F000F24333756D6A0724640D013D7593EEBDCA
-:10F600009C609DAE1FF59398DFE2E17ADF5F89FA97
-:10F61000A86D2AD38F940FD1FE7EE67BD40EC8E866
-:10F6200083C7F306FFE9F97EF4F7E82C66D774BDCB
-:10F630005F8370CD01FD1DA15F06EF9791E5C2AB21
-:10F64000CD4CD4E84C9CE6EEA1743EE691CCEE3174
-:10F65000C7AC812003FC044DB97D7692E8F4111803
-:10F660009FDA4B195961F6A0D9D548C06E106D0FBD
-:10F6700055C3BA8868F2A0DE35D847A4C125DF0E8D
-:10F68000F76F1FE4E9A0B05892158BF370934D16F5
-:10F69000B033EECD920B605C711283C7E664EABBB7
-:10F6A00053786C8E626D95C26B236D8B83AB117E2C
-:10F6B0005D145E62068C9F40EEA2F3AACCB2323893
-:10F6C000CC235C9F6ED4EB43301868FB9968D69EC0
-:10F6D0009DF5CC3C35A94FFFD6FCA66BBD4AC7199A
-:10F6E000ED1C5A4FC6D171D7A97160678EA1F30383
-:10F6F000F968726C4B8E647FF76787A9E3E4594021
-:10F700001F7771FD3A9A42C49CD9FFFBCF44FBBEE0
-:10F710000DF8CD067884C5BDA66631FBAC12C6C90E
-:10F7200041FB520EB72F49B012DB6D198CBE7EB271
-:10F730006626D29B93C24B8C85F933F8CDBF93D10B
-:10F74000D7E5AE439BFF0074E20BB7A7C3E8E4AE76
-:10F750004874422A3C6EF4D7FBB3E75436DF566E4A
-:10F760003F6A76B22D49B39BFD1C0E24501087577B
-:10F770003299C235CE45305E53E332F9FD146451FF
-:10F78000B19902CA9D3281B852617499303C564891
-:10F79000E1F2C7181FF41E8D36C8F738831E1EAA63
-:10F7A0006B179F4D33F889D70CA8E7CB9C130CFA45
-:10F7B0006992AE7F79D28D063FB6D2E0E7EAF58452
-:10F7C0009998558E2F13C62D544132E7C27D82F889
-:10F7D000097B8E7E672F9C1F93AB905FB95F63E4BC
-:10F7E000D77BB32484B3E0627E8DC60FDAFB1AFCAC
-:10F7F000AC6E86D7B5B99A7EF2A0DEB105BE4520C3
-:10F80000AE4A6D68795318BD6D68B6BF5F368A9091
-:10F81000A79BC9FB651479FE66175E9F6876E3F5C2
-:10F82000B16609AF8F36A763BF75CD1E6CFFA8D92F
-:10F830008BD7879B65BCFF507339B63B9B7DD85EE9
-:10F84000D35C85D78E6605EF8F342BAA9DAE6B6493
-:10F850003BF1A87429A33AE9F7C2E036A29DCE2372
-:10F860000CEEA9AA4BD71EDEE4D6F54F6E9474CFEA
-:10F870008735A4EB9E272A1E5DFBCA2AAFAEFF1078
-:10F880009FAC6BC79797EBFAC7CA3E5D3BC653A5C3
-:10F89000EBEF485774CF7716170C0E0DC0C70F3516
-:10F8A00007820C2EC12083D36B41069F1EBC9E0293
-:10F8B000F94BF118670EA2BC88CB7651D2A1F8B2F1
-:10F8C000B3FC5ABCD923C4868D1F5F4EC74B0F9F14
-:10F8D0002F1D4FE79FF9915E623C41DD7D477A8F96
-:10F8E000EEBDC9A2B314F211870A458C7B1D2A8C88
-:10F8F0008F01FBE53E8B6B6A36A5C7834744CF0675
-:10F90000780F5E88202F8F71BDE8186747B9307D6A
-:10F9100085B04144A265EFD7758F8818F73CF87D14
-:10F920005205EB72EC7C4102BA985E581B1F15E63B
-:10F93000AF4D0FFCA9CC0DF75764E446D1D1A6B763
-:10F94000A75AEBC7F4AD4BEB57B7426F5FF6D1BD8B
-:10F95000DF0EEB18AD7EDF0EF2AD236903B63BD2AE
-:10F9600007CE93FC96DB619F713BEC248FC39CE038
-:10F9700076D871EEF784B81DF621B7C38E72FBF905
-:10F980003D6E87F570BFE76D6E3F7773FBF930B75B
-:10F99000C33AD29F9B82F2F097021123F8A9DAF5BD
-:10F9A000DB3FD3DB61DFF2EBEDB0A5EBF476D8E221
-:10F9B0004EBD1D56DFAEB7C36A55BD1DB6B0496F0B
-:10F9C000872D68D4CBC3F90D9374ED798A3ECE367A
-:10F9D000B74A6F3F6BF899EDD3CBC5CA72BDFDDC5A
-:10F9E000DF7A5F0A5C8FF91F40E2C7617AAF379F09
-:10F9F0000B7A85D245F679AA57300EEE6B85FCC995
-:10FA000056E842F56F9129F816E47DC8DB2281B8EB
-:10FA1000D3CE73B915D323D05FAEAAA79BEAA3FABE
-:10FA2000F8C64D77EAE13AE316BD5F622DD7C355BC
-:10FA30004ED2FB2595463DE3D3C355250A01BA3482
-:10FA4000EA1B93E31609E4F7E5EA1D2BA17A85B5D5
-:10FA5000757AC70A77D274CF51EFB467B3785D2E49
-:10FA60009D07180B2D5179FB3D146E3BDF35639DCF
-:10FA7000089DE0E19154FF14C3DF147E2F5B14B5A1
-:10FA800011F26C3C2F42C453BBBE43FB5B87B1BC3D
-:10FA900008F9CA7C02C657E82FE02B97D076989ECB
-:10FAA000CB09B2E761F3D53DFF31E06CC0F9C887FF
-:10FAB00047E6FE4FCE272601EC21329E8CC77A8383
-:10FAC00050DC25C5578DF7B303CC0ECA4E62769035
-:10FAD0003779A6C8F34F04421E5E13B1633C3385E9
-:10FAE000F837429C337ABF631A6DB6C29089E0271B
-:10FAF000E9F97F56C5C0F979A31F76BD34C2E0B7D6
-:10FB00005D6BF0EBF4FC6F2306FB254424B027115A
-:10FB10000726DD7384D3614E472DC7DAE6C3BA5E8C
-:10FB200048E6F9154E3F1338BE08D9B4AB963EF7F8
-:10FB3000BA4502FE868DA8F1E3A1BE28D82843DE8F
-:10FB400021CF6B7321DEC4651EB44B4F31FC78E9C5
-:10FB50002FE0CF4BC2F005F83BAAC79FCDF0FC24A5
-:10FB6000A7A70BE7C5E8E89F372F035D39E32EA968
-:10FB70008EC578BF24288B31747E7B5C02E651F7FA
-:10FB8000041B8325B47DC6CDEA865625CD34E37C9F
-:10FB9000893C6832C5C314BE5E2FCF6B753513B474
-:10FBA0003B9E6FB6E395904611E4519BFBF678D0EF
-:10FBB0008F5D29CA30A84FEB1A12BB02F2F39B2DBE
-:10FBC000B14991EA5A7658F2509F76ED48344BF499
-:10FBD000FD12B3CB0CEF9524D589E0EF5DD743D070
-:10FBE0002E28492298CF7ABE3970887D4FC13A1CA1
-:10FBF000BA8E49609F96B96A27C524407C96DA364A
-:10FC000012D8B9B1E8BFEE1E6243BCD95C4BCBBE83
-:10FC10004BD7772051248297E2C7433C01D0034958
-:10FC20004E8F1F86735B8E039C1BE8EFD7697D7A2E
-:10FC300081F2F9F1707CE491B036E615F4EDA1396A
-:10FC4000BC0E8AE347220AD659B4F5B0FA32128ABA
-:10FC50009C67F988DB0D5A7CFF28B71BDEE371B780
-:10FC600043DC6E6833C46FDEE276C36E6E37ECE55C
-:10FC700076C36BDC6E7883DB0DFBB9DDD0EB2F1028
-:10FC8000B505F28AF3883D04FEC2815A0667F70A79
-:10FC9000C15F0EF970A5D3574AEFDB5658507E0E60
-:10FCA0004F525B203E6EAB5227C33ADCD59D2D7080
-:10FCB0006D29EE4884FBF3949347C1CF067A999A55
-:10FCC000CBF99DE261AD95C179DDE218CF72A067F5
-:10FCD000654905F64B6270B3D35F8077E222550029
-:10FCE0003A702B161DBC6B0DF09D07ED30F9110D10
-:10FCF000F448E179BD06F72C92C5E0AE4601DCA3DD
-:10FD00006A39DCD31322F2C93A0E770D2E3B8A6F83
-:10FD100036A9B4EB5B49AC6EE2ADC29B4D07E8FC83
-:10FD2000BB6511F3AFDD49BC4E907FD738DE3BDCBD
-:10FD30009E5D5B3A70BCEE20EFD7DB6E27926D7054
-:10FD4000D838A5F75924FA7E55607532F0C5DA41E6
-:10FD50005A9ED883F6F564B1F0CD543ACF20AF83E4
-:10FD6000D4E4E51CC26163F8DE5B7C9DFDCDE7ADAC
-:10FD7000D21B2D121D7756E01E02DFB3991BDDE169
-:10FD8000F5A5DD7C7EAB66DC41802F8329A71BD0E7
-:10FD90008FF7D924B0BB87277956021DB89314CBAF
-:10FDA000F7E8FD69541E4A2E9856E78E04E847DFAF
-:10FDB000799400BD5CB309E8E1AD643BCA9DFEE601
-:10FDC00073811EF113B447FAD32354FEA03D64ABF4
-:10FDD000F8F428F8B595A4D113A0EF05B33D4380FE
-:10FDE0008F499505F5733AFD0DCFAB69D74A83FE70
-:10FDF00076782D03CAE1E1E79BDBC1EF780BF807CA
-:10FE0000F3A02406EA73821577D8013ED393D37604
-:10FE1000027E48893D348AC26155E1CA0500AF556A
-:10FE2000154B5D02D055D1087C1E2CB19F848A9C55
-:10FE30009E9255C95218BC57AD26C50AC03BF92E33
-:10FE4000F712BAAEB4A43F342B946F7A2CCCEF796E
-:10FE5000A7F47749A961FDC7E694FC2C07F8DACD31
-:10FE6000E87CB455498B541FACD1794B7134C665CD
-:10FE70008ED7B27A057A7F65137D55A1FAAAC3D3CE
-:10FE8000C7C78B393D458D3ADB00FD95D53609FD59
-:10FE900033B1BAAD89B6ABC05E02FBE9610BF2A526
-:10FEA000C6CFC98D7AB9A918F8B6CAC0D71A3FED1E
-:10FEB000BC908F6300AF51B58C9FB4F519D735EF67
-:10FEC0002B6AE7C41362F4EFDE5D34229AE9B130A5
-:10FED000FB763CCA26C94AD7378BD3D32C4E4F94D6
-:10FEE0002477C07C0EDE33622AE04B6DA17E00CC0D
-:10FEF0006D99A5CFFE4D837592415EBAFE594D6254
-:10FF000006F8A7E44E4B1F3DA6E9BE87F50273C273
-:10FF1000DB40AFAAFC0ED81110CE848FFEF1D8A121
-:10FF20003DADF47BDD43E3498B07C73BC1E4A384CC
-:10FF3000E31D2C140779E1F9BDA33220854FC2E9F6
-:10FF4000958E1F52D9F39A7B4664A2B9C9DB1F2D47
-:10FF50001B021564C45761E9EB0FFF2B3323FE67C7
-:10FF60002F133640FC6FB4F8C5E95DB4FFAC4A9B73
-:10FF7000A7958E3FFBC13A0BD8FD95AAB2A79EF676
-:10FF8000ABA474E177E13A747C72D84C2C30CE612A
-:10FF900059209DB43D6B969E6F6A96E9DB467BE4E3
-:10FFA000488C9262A2EF7F2AD8C8067ADDB17EE93A
-:10FFB0001330DE270FDAB0AE90C0B772410F101EBB
-:10FFC0009F949FB8873EAF5B6723901799C7EDFD5D
-:10FFD00041B9A938AEC9518DEFD776C4A05F7C7204
-:10FFE000FD95E300FFED718DB7413DF527B14A0D59
-:10FFF000E0B56ED5B526888FB447774E86FE9F9ABA
-:020000022000DC
-:10000000886B43066D4B0F59603E3DD43E8078AB04
-:1000100036CFDAF630FCC37773591C779A89289B60
-:1000200022D8350FE6F6D627A8B6B0F93F9C2BE1CB
-:10003000FD6969716D3F80EF50ECBB3C1C2EB0EE4A
-:10004000C92C2EDA9EE4A91942DB2704E25A9E004D
-:1000500057F943E04FF57E1BD988E827D8DF3A6C83
-:10006000E8531D61FEFF383EAF8F63D9F3E3EE68BE
-:100070003FACF3B8C4DAAADBE9477A362BE97362FE
-:10008000D87A842B6017049BDF9118C99A86F820D0
-:10009000D273745E750F3F82F8DD4CE103FCD9E347
-:1000A00092DA76D0799CA4CA5A85E7EE4727033CBA
-:1000B000EFC8A4849A78219CEECD8DC3F99C5CD7BF
-:1000C0001A8375262EA258AFE883476DE796BB8545
-:1000D00071A8E755263F18FF09244CBE53FC4ECBB0
-:1000E000FFA1A50ED61B453A012FA6DD2BEC30CF84
-:1000F00079B516CC8F3989AF1CE469EDC302B6E936
-:10010000CF1AD017759CBFDAA5B8BD40C7C7C11EAE
-:10011000477FEFB13D501F50CBE557D5223D9D2E77
-:10012000769B75FC32A349CF3F749DBAF6FA5C56B4
-:10013000D7D9E3FD2401F4733B5D36C0E5D336C166
-:10014000BF01E5AB2F25BCBE2E35D7A4C5E1254B9D
-:1001500018FCEB28FDD581DEB093CED24458F7A829
-:100160002940EFD623D1384F237CFFD5E1F071B27F
-:10017000543384CEE7634AC750FF737C7D2BDA2F5C
-:10018000F023EAF8DAD506F4BD84CEF25117D2A7EF
-:1001900075C6D83E7AD1E053BB2E752FF4737F1EFF
-:1001A0002351E789D4BA0B96823DD94B4706F8C054
-:1001B0009ACDDA7746F4D1193E8F406793685F6E27
-:1001C0001F23BFD496F5E6F55206AA5F467C1700BA
-:1001D0005EC7CF873C9426E7D616BF817470C645AC
-:1001E000FC22F36BDF06B91FC3E7A61239509F004C
-:1001F000CA84EA5D17DE437F399EAF37B64978AFD0
-:100200002C8B90B826F1BD327A33B62C18003D61A4
-:100210007373BDBB2DEFD7A3AF80DD0D04E3348333
-:10022000A22B3C015C8D2B11F729585C8960FF3CA7
-:1002300028085510B71F44F47655BC011E24DB7CFA
-:1002400022DC2E8FE6F27EE9E41102FA3BE57AFF2A
-:10025000D46CB08B7EDE4BD76CFD12FC49E1D846E6
-:10026000FD3790537181CE4EA0CF1A6AB7FA71FD57
-:100270001ECCEB58CB04F2A8D017BFFA67C52F2EBF
-:100280008883F1F8457F71302D1E50C96E517F472C
-:100290007143DEAFD24DFD9C416067DDEC46BFC9C6
-:1002A0007D12ED522BB74BA3462D72B1FC19E31F03
-:1002B0002D1E60A42B635CC9C87F46BBF4B7B9DCB4
-:1002C0007EBA865C7339F1012D8EBF2A9DF93DAB54
-:1002D000D2EB9643FDDA39EEF7B85413E271CE2C27
-:1002E00001F1A8D96B73BCA76701FF69F50717F384
-:1002F0007B3A0C7E48B4F729598EA03FAD792C2E5D
-:10030000E42864CFE7D889D91E963FB0E5313D3760
-:1003100087EA413B5DE234BE8F683AD1E7A7E2F855
-:1003200038DA95FE04337375F5827179EC3EE64355
-:100330006D3C1F6AE7F582251967777D0DF76556D5
-:10034000076C936B1FFF1E8543F4AC188F09E957A8
-:10035000D9F843F093673950DE26A44B58F75A95E5
-:1003600064F720EDABF2DBE097A19D29C194659481
-:10037000B77329FF065C03F83BF681E3664ECDDFD9
-:10038000296474D51B5FF231F96DA2BF404FB3AB46
-:10039000F4F4325719987E32F3787C89EFE31A1D12
-:1003A0003ABFE36BA40BC6BF6B53583EFA5C05ED36
-:1003B00003F9DB7EEC71CDBF755AA85F44F112944E
-:1003C0007721BD07D389251CDFBE425157DF10CCF2
-:1003D00027D12EEAF7042D24F941DA6F903CF70675
-:1003E00017F8BE25B6985AD41B7E9D7D7F908E7BD4
-:1003F000CCD9FF3C8C74BE7AD4128CFF3F703D0583
-:10040000199DFF6A483863FDDE73F3C16F7B00DA24
-:10041000585FF08BF9506FF74094D6EEFAB11C5646
-:100420006F70E796977FAC1652BFC64EF52D1DCF65
-:100430002111CC5311B209E5B308F14090CF63C24A
-:10044000E08B7E831EDE463B5E2C647114D1C0F7C8
-:10045000C6EFDE9CA7DF6FD7DFBA8DEFD19FAA6B07
-:10046000F4F47F7BDE00F5B2C6F79D503F1173F9BF
-:1004700075075490627E5A24260FF8CBA494E0F7B7
-:100480000417A32B9030A0072D8D833C0837DA8EFC
-:1004900002BDE0776871559C7414E05F847C620053
-:1004A000F5399D4A481801FDB5FA03857CEDB8740D
-:1004B000B947E5318E2395B3FCF2BB3209C1F7464B
-:1004C0003FBACE970BFEFA11AA6725D0E337AB10DF
-:1004D0002F3BBB8C607EC0E152B04D3F156A754129
-:1004E000DC8AB56B288C402FDBDCFAFAD71DC58F70
-:1004F0009658E9F3B632166F3DD81C787705A5B546
-:10050000B6C20294972BA063D87C833BA3AC108720
-:1005100051D4EFDAC16EFE689968856B7079AD0AC7
-:100520008B7E3751DD244810775008F8F9D665AD39
-:100530009381AFDEB5A89E3827E655314FDCBE5C0F
-:10054000BD15FC1E59AA284FA57CB4A1DD8CFB8CDF
-:100550008E95FE2E490AE3C3535C9E1ED811F5000A
-:10056000C06195600F45C1D5A26C589D00DFB37A7C
-:100570005AE814DF6DF941327C67D5E2559E9DF053
-:10058000BCC5063B50C9AAF5F62A187755F212F7F2
-:1005900092B071EDC3AC8D703F38B40DEB5A9472CC
-:1005A0008F352A16D6F5450CE467DB9765C5032D14
-:1005B000B6255A53EAA1DF923FBE990778974C9827
-:1005C000B7B5BA3B2DB0EEE16E4585FCF85F72948D
-:1005D00057F3E83CE7351D9B8C757365B12BE13A09
-:1005E000FCFC77DA01FEEFF2784C28B10EF3B56D22
-:1005F0008BEAED30DFE98969CBC3E3316D858BEDA3
-:10060000A3E97B696E53EDD24117D2471BC45FC685
-:10061000C3BCE87AC642BF3F342BB45F28D95A1511
-:10062000699FD6F13CE6EFD95B97A6415CA46DBD0E
-:100630001DD233A44D50D6417E404D7546AC631F4C
-:10064000EB65EFD528AEC95609F183FC762AAFE7F2
-:10065000C7EA48B02B19FEEC6662B784E9BFB1392E
-:10066000259FE685F9D1177C37B10DF5419BC0F880
-:1006700077ECD6CF7F0CF5C2BFCAF17D0EEFAD6A25
-:1006800057D601BC886A27838AFBE793D06A9242D7
-:10069000A83C6E6BB15545AA430B2D12A7019F5084
-:1006A0000E3A3628254C2E2FAF4F83F848A8E52A5E
-:1006B000E4EEDEFEEBED1F021E42EBD363411F862C
-:1006C00092EBD2D2806E395D1AC7DF94C7ECC95F56
-:1006D00067F92C5EB02BC7B0BC67459ECFE645BD21
-:1006E000DDE9063BF71B40B72930DF7F22DDA29E04
-:1006F0003B9E770AE98AB82E2D1FE9232133E65362
-:100700008BFF8CF1DE8EB1DAFE27161FD4ECDEA84B
-:1007100051275680DFEACBD7F25D857BC05F9FA66D
-:10072000E5532B587CD0457F23C5077D86F8E03400
-:10073000435BB337A778B97DC2EDDB24A9D3570A51
-:100740007277BFE8017F229930BD32A342F0839DCA
-:10075000DD521C6DC779E7F33827F7BFE6F179BFA3
-:10076000D76C27904F32390A57C2FCA715B0F93B16
-:100770001A32720212C87716E7260D3609E3268070
-:10078000FC44D2EBA7F96010BA9E790D4BD1DEEF95
-:10079000835F0B8BF310BD3FE12306FF6111B3C7ED
-:1007A000347F6BBEC13E30DAFBC638755F5E609346
-:1007B0001DE8E9EC98CC8369123E56035A3E80F658
-:1007C0005BE8ED5E190A933FDD5C3F1C6E96DF5BD4
-:1007D00041D7BFD2F7133BD06987D96F077DD2517C
-:1007E0007E470CD05F47B5580E7C1F6C2EC77E0726
-:1007F0009A7D786DF6327DB12F47BEDB1B1677AE42
-:100800002C2F796F4578DD837CFD7B2BC2E63FDDA5
-:100810003B43D7D6E86CBA481A3745902FBFF2321F
-:10082000FE3753BD8F7586E22F3D03D5DF507FF530
-:100830006C38FCD678F5F6EC7D634A070F64B76830
-:10084000EBD3E0A2AD5B7BDEDF3CEFFA1BE7F9D434
-:1008500065CED3383F6DDEFDF59F0EC28AF2FF5D97
-:100860005B4BAAA12E765F8EF22CC8A3CA326125FB
-:10087000E44B0FF378E2E1C218DCE7BE279DF97B79
-:10088000D10D8C6FA2CB6660DEEF72F17B9397D9AE
-:1008900095B30A05BF4CFF9CC2F7DBBF97CEF2B9F8
-:1008A0002DC53F7F13F2D0EF145958BC97C8D3A67B
-:1008B00086E5B1D65AFD01C827BDD75BA771CBCA63
-:1008C000BB683B5A932B55FABCC3AC59FAFCE17494
-:1008D000439E21DA2057821ADC7329DC47F4C1BD1C
-:1008E0003F7FA23FFA20E6D3D9A0878CF0B9CD0094
-:1008F0001FA3FF327D9B811F2ED18FD9D09EBD07B4
-:10090000F26A2AB5274701FEE0117D2F5A7E16D3E1
-:100910002051F98C1E47874EAD01BDD84D5500E8DA
-:1009200097B533EF5807ED7354EF035EFAFB8EE68D
-:10093000BFFD2A473EE38D503FD02B47C03E180FE6
-:1009400079C1C8F641F7A2495323DA0733EBD372D2
-:10095000605E33F4F641F7FAF2C7B3E03ED807F42D
-:10096000A73BBF5E671F90F2AC8BC087C9DDA85163
-:10097000D911EBF47C398A2B3F6C3D8EF446125E24
-:10098000CFF879AE1C9B4FDF9FC1E308DAF7A8FDD3
-:10099000B5DB12A17E51FB5EA697C53D49793CD3DC
-:1009A0000FFC7A313C6A75D4F759643CEF458B7B78
-:1009B00069FD3CF94CCEB6A7C90DF09C38332F32F7
-:1009C0006E8B16E748CFB882D70D4BA4D71FFAB36A
-:1009D00020E1F308FE1E81BC6474D2E9DD2EDAE565
-:1009E00013AF920370283AED57211F62AB10D05E0F
-:1009F000B22511B46B2ED5BFBAD47EED501C00FECB
-:100A0000561D8B97976498B11DAD881B402E4C3CAA
-:100A10003F5800B9E153C4A760BED1F2179FFD044F
-:100A2000F435D5FB1087F19146DC67EDB4F8303E24
-:100A3000D1514147CE8038CC724B1AC6D3539F8DCB
-:100A400071C3D7FCED102FB779D87EA82AAFBA12A0
-:100A5000CECD985E344A20F4F9341F8BDFCC81F878
-:100A60000D8C3BEBF40E88FFCCF632F9057E1BE8CB
-:100A7000CDB9F5778FFD91F4D7C46DFCEDF1D918A0
-:100A80004F92305E60880FD90AA7607C48AB53F163
-:100A9000158AB8BF9B2439F11C0A637CC718CF3173
-:100AA000C67B8CF19DEFE6B37D1A9A3DD598AF8F4A
-:100AB00017DE0D7B1072C05EA2A292F275878524AC
-:100AC0007752FA3C58F229B993CEC3F94313D48034
-:100AD000D37E7A3BEC52E55690CA958F6121BB5E7E
-:100AE000B7807F5B2DD7627CCF48F70FE5B378DD09
-:100AF0008A7CA72E1F1C6C6EE2EF47A980E7EA9163
-:100B0000567F546ADF3897CA1F8FE6CA0FE433BF97
-:100B1000A213E89C7814DC4F5091E7D2D12D691CC8
-:100B2000423E0E8BDF18BFABCD471BFF72E7713F14
-:100B300087F7A5F2C9DAE202BB957EFF0CC5B18842
-:100B4000FA921AD461F1692D7EAEBD570379832CD8
-:100B5000B02305CC1F68F7C3E2D866A0DBE82445C4
-:100B60008E74DED4A1FCDE3C15E631B5EF104141B8
-:100B7000B950CFF335DA7866E26E413E00DAD6E658
-:100B80002546889B138FDD4649A66E8D4820FEE3DF
-:100B9000247227C49FADED166C13B56A2FD8E98B6C
-:100BA000385F580BA7EC85B89AC617C6BC8D554C54
-:100BB0009A02C3D677EAF357C6FC94D19ED6E2EBED
-:100BC00066FA1198D7FFD3F04115B57869EB7D0A25
-:100BD000D7F30D5DAF46571559DF7643FD495B945A
-:100BE000B2AE96CE4B7DDC8EF10A07CC0D6012A022
-:100BF000BF20271FF7FE04E4EF5FF2D9F9376D023B
-:100C0000AB47D99DF88784F0FD0B7FE1FCFB74BEF8
-:100C1000C4E222661280FD52644C02F285567F7255
-:100C20003091D981D38B1607EEA0ED5FF07AC96BB6
-:100C30008B366AF9FE4125B9044B3F002E6BADACF3
-:100C40002EEDE0D566AC2723E2FE9D7724F4D5EDAA
-:100C50005EBB49EF57DE98AEB7078DF69FD5D08EB5
-:100C60002BE072ADB7FE44B1631D5922AF23E3F30D
-:100C700037F2C9CF9A595EE3E7BCEEFF977CFFE5F8
-:100C80007FF1FABD4D7CFFE5737CDFAC06F7FB2CF2
-:100C90000AC6A38F5D4F6DBAD8BE38E0DAE27BDDBD
-:100CA000C0C7E30B587C68B2E8DC097AAA6F9FC51D
-:100CB000C0E7845596EBF366B37DFABCD9DC2A7D98
-:100CC000DEEC0F59B2A76008ECC368580EE714CCED
-:100CD000582162BE726DDB19D4B3E70AD1DABE5077
-:100CE0003EF07D18DA3E0EED7E69013BB7C8B133A8
-:100CF000D102F5F83356C44E81F83971655E92FD24
-:100D00007603C4DC613ECB5D16380F62462011E3EA
-:100D1000A1B5ED9737CEEA5157609CBA37CE4FAEAA
-:100D20005900EF1FD2E2FC6AFA0288F31FE271FE5B
-:100D3000EA826B1F07FFE8E97C7926C06359BE5C35
-:100D4000599003F7995CA0EDD9E16DFAF35AACFE26
-:100D5000FC896A78AFBF78BA3849688C542FB2B82A
-:100D6000A037CE5507EF137B6F9C6B116B77E23E7C
-:100D7000BB26FEDDD6F748038CD3FA2269782E8293
-:100D8000DDFD9D02411BEF16982F716BFACD775B4D
-:100D9000A4F1445B6C0AF8FDC7787D9971BCA6028A
-:100DA000B61F938E7717BE9FD43BBF261C9F8FD74D
-:100DB000B77FC615034CEBA8514C3D949E489B88C9
-:100DC00075278E2ED754A84B225346601DCBA1B257
-:100DD000CA7F89FD3487CA7EF36FB99FE63705A9BC
-:100DE000480717DB4FE398499448718D97385DEEBB
-:100DF0002CCC1A1C1A004FD6A67D41B0337ADB6684
-:100E00008540DECFDA7400EFDF17E5AA89685F70EE
-:100E10003A6D2B5BE48394D0AAE42962B8FDF2BB5F
-:100E20006C654F4184FD8967469EDD05AA69669918
-:100E3000601612D0DEF608547E662F9B21BA25423A
-:100E4000BC8D0F4EBA923E9F9544FDBBB0751734D2
-:100E50003CBB8BB22B292C3BD49A40FBBD98AB1CDE
-:100E600082F18BDDD26E68CFF26560DDFB7DB1046F
-:100E7000EDBC63A3ACFE0DA917CEFB049F3795CB49
-:100E8000CBCD972197DB9AF5F9EF55C9A397C3FC12
-:100E90004797921048D834F7E912C8FF8DCD514ECC
-:100EA000005FA5B9896C1B87F7651296BF318E1B51
-:100EB0003581E9DBD1A1A4FB219E7C50F3F78B2F78
-:100EC000DBDFFF221CDEC6EB31CDDF5F19D9DF3F50
-:100ED000B6283E723EA0ADBE0EF201C756EAFDFD39
-:100EE00063EBDD35B0CFEF18F7F78F4DA6FEFE9818
-:100EF000FEF301DA3AA91CB24D00B9D39B0FE0769C
-:100F00003B8F6BFB72E468784EFD79075CEFCD9206
-:100F10009D13E0B9EA5A80FB9149E47DB2E4319730
-:100F20000C7E8EB6AF3DD3AB0C81F7B5FDB2A341BD
-:100F3000B4C5415ED4755B247A9626307EF9EBF316
-:100F4000A4BD794C13EEA3BEC438FDA5F693BC9B9B
-:100F5000583D8E99D519462596BA213F756E8C1D40
-:100F6000F57B3BFC2F4CAFA61428B91386848F6306
-:100F7000385F55BAB4EF6A75FAA0AF40BF74135228
-:100F80000EF2E681D8468C7B9471BC1AAFD74D70B7
-:100F9000713DEB4A0078A614F8A620DE9FDF24E11D
-:100FA00039B0FC7E7FF5FDC6793C63F57D80FBEBB7
-:100FB0004B4589D5E511E48BABD25DA8A735FBABDA
-:100FC0006E422A3B578184465AE93A5BE55DCE2C56
-:100FD000DAEFA3C7CC19F0DA4F638805E6ED4BA72B
-:100FE000728EAEA3D4AD0C1F483EC28944262F5C3E
-:100FF0000382C98DD778765505B87F013F3E767656
-:1010000008D8E33F7D9CE5A7AE7A7C91BD2E6CFCB1
-:10101000472670B999C4E65F230B7E2915E6731A3B
-:10102000F350332493472690373E77642EC409A9A2
-:10103000FD360ADB67B01D944C5990D7FEC8FDE51C
-:1010400011E87FD5F7175F81F4CFE1B17059D6333E
-:1010500068E7E728DF03FC070BCFC48C188376FC16
-:101060003AA0FF8502F145B213EEE778BB416EBCB2
-:1010700009E8EC06D94660DF5AB0C48670FF699172
-:101080002081DF3A1D681EE2398F9931DE4CE17113
-:101090000B3CDFEF71E0B9D1A5F2B36668FF61AC3C
-:1010A00040AE1C401F5F365C0BCF0C017EFC08E895
-:1010B0002FC2FCEB38FF6AFC44E15E8AF39259BD13
-:1010C000487F74F579BEBC0EE8B23D4D69C073111E
-:1010D0005D332FE95CC4E93FF363ED9EEDE9C6A102
-:1010E0002442FDD741CE27C6FBFF3981F9054B3895
-:1010F0007F5CF5F8D9FDD7035F2FB3B800AF4FE79A
-:10110000FB7E0178EBF5BBFECE7264B2588DF80B16
-:1011100056D0B9E3390E2406DAD3469A117F6A29EC
-:101120003FE7E32EE26A8DC5B7B06D5F26209F3999
-:101130009C9D5560349BF31B8FCC86F74A44DCD7CB
-:101140001FB6CF65C03AB210DF7FD606FBCFA82D01
-:101150001F5C216AE76E1181CAB6609999DBF79F1F
-:101160003E2ED33F9FE1F5991F14894F407DE61134
-:10117000136B1F2A125396D3EF8452D83C3A1E1495
-:101180003C2D125C9F5A07F9CBFA26C1534EDB3532
-:10119000817B7A20C4B5E4611B0157E1931F2E9D2A
-:1011A00002EB39E32678BEECDC44C6374A90F84DB2
-:1011B000A97DFEED87C9C4AFE54B611F9D97EB99F3
-:1011C00087601F1B9DF775EA77D5BB216F4AFD5ECF
-:1011D00088ABC579583E333A68F6F809F8BBAC3E9F
-:1011E000B2ED7E813C04E3886B5AC13FB7F17ADDF2
-:1011F00068B916FDC7384A9F1268D09059B78FADAD
-:101200009E2848BFF1E5943332E0AAF78FB32FB29E
-:101210009F6DEE8221B1C02FE726E8F765F4175FD6
-:10122000D7AE70DE0DE0A78BE757B752BB1DD6FBDC
-:1012300022B5DBE1BA8DDAED701FCEA9862BEC6703
-:1012400083EB4E6AB7C315F6B3C115F6B3C115F6F5
-:10125000B3C17BB09F0DAEB09F0DF71F16A981C122
-:10126000009F926802F9A1360BA33335D98AFE4656
-:10127000A08860FE3E986CDDB01CE27502C3931A34
-:10128000CB9E0763949BB19D3A86E577CD9E14D89B
-:1012900047B842182381FDD46E55B07EF9D8723319
-:1012A00081FAE5D054E103C8BB10C1E411A97DB3B4
-:1012B000FDEBDB10FE8B656282BAF4E5706E28C828
-:1012C000E3CFC806169F0B8A70BE5C6B0CE1756499
-:1012D00037F9654A7F2705ADBD57017F7422C404E5
-:1012E000907E7729F07C7193C0DBAFFAE59150D7FF
-:1012F000A03D7FF349882FAE30B4BB4DBCAD0E7F0F
-:1013000012C63BA27D4F1D5603E31D49D39E272ED7
-:1013100084F6C751DAFB9F2F84F783BDF33989E345
-:101320008592B5FE520DB67BFDE7050AB687B0FE85
-:10133000EB77EE7B0AFCE5BFF778AD8A8A717C75A6
-:1013400016211B6323F0FF44511F0F95055D3C548C
-:101350008BBF9B1CD557E2FEB3076C28173F4E2668
-:10136000E887F417170D8BD7635CF4E713FB897FCD
-:101370001285C0B855100FF4E05795F0FD69446828
-:101380002450A7EE3B1523811D694D0A8BDF71198F
-:101390003050BCB0B591C507838A85A8A97D75FD7D
-:1013A000D6425ED7CFE3855A1D83B5F047BABC81DC
-:1013B000315E48C45B301FED5BA48F074E572E2F64
-:1013C0005E584D02962B81FE65C103FE7BB54BF93D
-:1013D000F00AB4F7AF61E7334AAF61DC54DB37069C
-:1013E00077E0DCA92ABEE68E5B8F7D7005EDE75FB6
-:1013F0001E25C166FCF9B794E0FBF9748510DFAADD
-:101400002E4A4378E77CE6794D0279EA3679989955
-:10141000E6FB7E22D80B8B62316FB2E0CE8C0F617F
-:101420009CC5AA03DFA37625A7F7AE27809E4408B4
-:101430005C86B5B35334FA9BFD04D0FFC478AD1D70
-:10144000FDA45C484889557B3F07DBF314CE7F6AD7
-:10145000FA93C07F474A357A7DA3069ECF1ED13BC3
-:101460001ED2F74487D6BE71213C6FEF1DAF1EBF61
-:10147000F70E9C6C84ED494F823E2A99A1E9ABE3BB
-:101480004FC0F86DD5DAFBA3FD108F9A6FD2F887A5
-:10149000F8819F15D2DB96412FBECFF9FFC8B64D1C
-:1014A0003550D77593F65CDD84EBADE6ED77B62964
-:1014B0004F023FFDDBAFEF7FF87BC6F602129C7C4C
-:1014C00065761F5F18E5D56BC54C8E781B9E05723F
-:1014D00025D58D4FE1F96E100F60F9ACC4593E90DF
-:1014E0001776D1433983F8DC2E8C731AC7595CC444
-:1014F000ECEB4F0BF579B136435ECCC7F353FD8D62
-:10150000F3269F4F7B69643F766C4EE99785503F89
-:10151000404E8B309E8B020CCE276BC952BE82FB95
-:101520009475F1DC4D2AB23C709FFAC52AD899D344
-:101530002838210FDB52FC28C6E943F916DD792053
-:101540005A9E73AD5546F9F809AFEB985F2A4FBE26
-:1015500087B66B878A6403D6793831DF601E667D73
-:101560000AE53ACF7B6AE7714CBBC8BE08E3BE947C
-:10157000CFF97ACF147658403EAB449D5C968DF2FD
-:101580003A08F5C626C71ACC03DB8A2D9847D0F255
-:10159000CF0A3FFF5BCBFB4E3C3F98E9F7742DAE83
-:1015A0003B70FE5769DAE143FBA0532426E1C27C7D
-:1015B000F0629F9A0CF52CD3CA6270BF4055DDEBE8
-:1015C00038FEA11482E70447CF6AC4FD41666A1F52
-:1015D000CA00179E2FD6EA63869FFF0EEE1BADD77B
-:1015E000EACDC58A0360A7DA1EA17E1674E0F96011
-:1015F0002D5F3CC320EF171756A29E25D48E1F15D2
-:101600000BDF1978DFF3031359FEF84427ABE7F734
-:1016100016E9F3C0F759589CAF3D4D4F571B273281
-:101620007FF5075C9FEE2CFE7915DACFC4E481BC10
-:1016300018798C9D0B073116DC6F653C8F397D0E58
-:10164000DA758F0DA74BA4B6B6B9E97D8C2B0AEBE2
-:10165000D87B9F8D238DE0B798CDAC4D2F2AE4FF2A
-:1016600033BDCAD422A8B368FA10FBB7AAACDEBB5C
-:10167000BFF8CDBC226D9F088BDFCC77EFED817D6D
-:10168000657F731CC7B0EFD527B1FA929585929606
-:1016900047C0730929E15AC05E4C29F0D5C3BCC9C3
-:1016A000984D12CC4393373B5EF9760DC81B224709
-:1016B000CE4B6B7CDF66C84BFBDCECFD378BEFAEB3
-:1016C00081F30DFACB433C5C2268F1B53B8A605E46
-:1016D000095ADE40BE13DABD7A1416E4D5E9D18585
-:1016E0000DFF0BF4689FDDFE760D8CF74D9B3FA53B
-:1016F000ABFF42BC96B3F8D9376DFE1326C87B60AA
-:10170000FEFFE8EF8C99E07B0BBEB35A90AB9C2CAC
-:10171000B9E711F479BE778B06C8F35D2CFEF07F34
-:10172000F18681E30D62F1BF66BCC10A7BA87290AD
-:101730008FAE2C06F95CC8F8E8DF5DEED1F5E6C0A7
-:101740007A570B9BFCD123FEFEFE7E4A8132A918FC
-:10175000F5A062DA49E96775899DD9330106DFDEB4
-:101760007806CCDFAB8B673CD9F00F8867D0F55695
-:10177000227ECBF8F7BFF9F8BB15E12B337BE2DF14
-:10178000903E57E3FA36B1F5FD13BEBF1EE9E5976B
-:101790008C5E7AE1C3EDA430F82C6CF8E7C0E75713
-:1017A000089FAD6C7EDF007CEE42787AD87C2FE615
-:1017B0005F1F2D1434B9FC06BE97CDE8E043B0AFEF
-:1017C00099DF3DE94AA9CFEF7E34573E50CCEA631A
-:1017D00082C5BAFA4FF910B407F08B8FC0F3087EB8
-:1017E000F1FBC5DF40BFD859C4E0D69777F1B3739A
-:1017F0006F49D50D57D3EF7C48E10DF1B68E261118
-:10180000ED8B734904CF03D0EC8D502CABDFBB7054
-:101810003F581981FD88B67C76CE88763E8059ACDB
-:101820001E1C902E84EB81418A15EABC96C8196D66
-:10183000B0BF75D29A2F70DF9555B6E1BFAB39DCDA
-:10184000EDB1DC097E34F573AF83786A830BF7D191
-:1018500069FBCAB4FD1F4B02F3F6C23EDB0E4A0F12
-:1018600089F43BD3CB2CC7C3D76FB437CC86B6F142
-:10187000DF354D98A8AF07A4F047FBE7DC3A561FC9
-:10188000D761263BA1FEA35E15FD2DB4BD718D80F1
-:10189000E7712EA270027F7F52672AD6935B93D89E
-:1018A0007967DABF7B4AE9A0331FECBF2322C17FEF
-:1018B000C78EEF27D3CEF98E9A7A1ACFDBFA98AE7D
-:1018C0001FCEEFD1CE9998C1E9448367544B3CC2F7
-:1018D000E51C850B01B8F0FD36D39A583EB8AD7AB9
-:1018E0007110C8BBA6F08B1591EA52E6B8F5E7A5D2
-:1018F0001BE319C6F3C6CDC43718F6D54D2F2C51AE
-:10190000C15EB5F17ACD6822E3B9161FAFF9093B84
-:10191000D7A2CCA23B47C4F8DD68039DDA0C71075F
-:10192000239D1AF1729D012F1BCDEC9CC1B66ED187
-:10193000A3D2DB6D0F2F6A877DF9EAC32656374F96
-:10194000643CF7A98D5ABCB8FF9C4E16E2F573397A
-:101950003C35BC10D268017EABD6F6A19B1A57C2AB
-:101960007ED2797C1FFA4D6413EE3358001604FDC5
-:10197000EE4208918B70AE8C6465CE818BC03CEAE0
-:10198000ABD83919265803E4091E3621BFB6B977FA
-:10199000E2BFFB15186A893D99CEFC8948F66C6F49
-:1019A0005C8142E264581CFFFFE2577F5BFC2AB770
-:1019B000889D47D5161570E5A7B2F326A09E29B7D6
-:1019C00048423918B42829B8DF61FDA72AD081B66A
-:1019D000DF81FE2CBB427F6EC2FA8903F87F45454A
-:1019E00004C76B4B0D25835CFBB09FBACAEDE03892
-:1019F000303DB46122E6DFA9FD9B0D728FD9BF1582
-:101A000079BEA7F13EDFE7ACC5913EF12AFF39313F
-:101A100007F6E71094C3B60AC10FFB77A63B853DD6
-:101A200082D4F77D62AC63FF5F9AB7BA93FB6DC156
-:101A30002882E720055349D57311F0F1835216A788
-:101A40000C6644C697F69CDA19EF4CCC61FED020A8
-:101A50004614A7ACFAF8C00703D18786C7F8C9F2C5
-:101A6000471373FADA0FE4299F40BB55F17D0078E4
-:101A70003DA98A12E8151250F03CBF69FF21BA0057
-:101A80008EFFE83CDCCAC2D44BCAC355039D0D503F
-:101A90002F78B9D7FF0FF9613D6B0080000000007F
-:101AA0001F8B080000000000000BED7D0D7854D561
-:101AB00099F0B973EFFC24998409041C24C00D0229
-:101AC000461BDC81802440E0CE4C12124860F83581
-:101AD00002E285008D5DB451791458BAB921102005
-:101AE000A260BFB4B5EAA34310DCDDFAD4D475AD6F
-:101AF00088AE23A2A55DD4A8A1C6556910E4B3ADF4
-:101B0000ED870A6BEBA7F57BDFF79C3B73EF64C2B5
-:101B10009FB14B9FFDC2A337E79EBFF7BCE7FD3FD8
-:101B2000EFB939EA648C4D82FF8CC2655A01632D8E
-:101B300058BE9CE18FC6A0BCB8BFA59C0B4D3B799D
-:101B4000FBD1DAFF891A2319D399E82FDABF23F1E1
-:101B5000F6478303A28697B145A21ECA3A96CDFEE8
-:101B60008C29794105FAD749667997A658E7CBDAE7
-:101B7000A5C17C279CF6F19788F18AB42F69FC48AF
-:101B80007CFE2FA31A948F27C17F03E3E552EDCF8C
-:101B9000D47E65BCFD9F755CEF49C92C8FD2B1FF27
-:101BA0001197D9FF8A6538FF3D79BC7E6A6854D4A5
-:101BB000B804E1F9A6C7BFD0F647A7A88C0D047CEE
-:101BC000D4FD2C7C19FCBAA47E97AC43BFA3CEC82D
-:101BD0007B2C07C8EC5E49DD037D8A58BBCC6402D0
-:101BE000DB258F87213489B5C05C2B42F0BF09808B
-:101BF00047AF83CF6304A21AD0D9E2A9269DD64469
-:101C000071DEDEE8EE9DE0771FC27527E0FEEE5242
-:101C10001BDCC6A865DA9404DCE110B487F116DF9A
-:101C200072931FE15C3CC25CDF249AA739DBECD7DE
-:101C30007DD6795F7BA194F0BD383E4F25B55F9C82
-:101C40006E8E37278AF326E05A48FB91806BA80DE9
-:101C50009F81D042C267C417DD3C08F013F1B38006
-:101C600001F85C54D728EB05163E32C22AF1913FA9
-:101C70005E8EDAF9A880F8A8AFE11A3629B24D8352
-:101C80007D62F9ED6A64CC37B1EE98F3325CB7212E
-:101C9000D1BA4D3A5AE2B3D0BB07D6AD9AE52B97ED
-:101CA000D579FB62DE8E329AF723C0374BF01333BF
-:101CB000062FD3BC173E5E9377B90BE15EA5495A58
-:101CC00014DA7F853FD312CFA35324E217C0E7BFB6
-:101CD000123E8B009F99F89E111F3C5E18F9B906C1
-:101CE000F54CD51D07002E97E6612D8083AA8991BA
-:101CF0007DD49EEDF423FE01001AA7F975A6209F5E
-:101D0000016F051C93A1EC6435ED29E6FD61C84126
-:101D1000ED9B18AB6807F8C66FF4AD8A7813F5BE73
-:101D2000320E5796781EC9ECBE6120CCDF0D551BD4
-:101D300061FC260398179E1FD4495109D6FC416EB9
-:101D4000645631943BF21C818D307DC73AF7D03513
-:101D5000D0BE2BCF1B40E8BAB27766FA60FC0F0208
-:101D6000B2C0D74DEF235F1FC98CF39381FAA5430F
-:101D7000E0F7D75A711BF2D3DB2A2F3F50FAF7EF67
-:101D80001B05486FCCC706011EB007F0AA23638A63
-:101D9000C70DF3BACA419C605F1FD35D50EFC67A8E
-:101DA00058E29C1FECFEC13C95E4C6CB23AF65AC6A
-:101DB00006DFABD85F31BA3D34AFF295444FE6BC95
-:101DC0003631AEABB5E9A526809FF9651642DEF245
-:101DD000F3F67ED6DDF89503C787723E43127CE1A9
-:101DE0002B58BF24CAF8F3152CD1CB2215790857EC
-:101DF0003E0BB4C07C7374E789783D7F6C57AE1599
-:101E000070223CF2868A6278A6D7D9DBCDCC87B225
-:101E100027519ED15A1B42BCCFD0A0DB58C60EB76B
-:101E2000D6C66A01CEC3456E9F049876E52AB6F6FB
-:101E30003359FB26C43B530F1D94012F4BC57C4DDA
-:101E4000BE39EF31E8B72A1F4AB0FE23FF10CC9C01
-:101E50009083FC26071CA28DC3C407A3764E079768
-:101E6000D30109DA373D63EEDBC436E4033943B20C
-:101E700095832EB37E4C1BF2E191B85C1DB91CCB4F
-:101E80000BAE30F926B30DF96A5A8659762D473EC6
-:101E9000EA569C429E0D6C433AD96A8E67EC20F953
-:101EA000F21633EB1D541F89CBBFF25D585EE81369
-:101EB000F018DF2779D8A4717D72D50BB16EE322BB
-:101EC000DA037F5E19447E8B7079975C3FA933DA21
-:101ED00094857C07F819A5F6E4B7F54199F828A28E
-:101EE0007D2CE3FE95D603CE60FFC23552E704A4F5
-:101EF0004F850D45BE6F6E009D3E0ACA2FA6B9D410
-:101F00004C94EBBE722D05FFFE3CC8F97752D09B76
-:101F100073127157C80A91EE9A1BD69AFD0DDC5FB9
-:101F20007DA42B9A96D7FB38AF851D24673A24DF12
-:101F30007CAE9F6586FA3978EF15DE629668F758B1
-:101F400098EBE5C6426D7A10E69D05E297C11E3614
-:101F50004EBD3F1282794E143B036EE233ED0DE429
-:101F6000B3B9828676B834B60EE546B1DBB71165F3
-:101F7000B75CE05C0B656508F02B962B387DEBF0C9
-:101F8000EFAB1138AE92A07F8063CE5A3B3F28CC96
-:101F900042DF50BF28989973F25B50B89A5D8DEB81
-:101FA000BFCBE95B8A726CEB08DF2D5679F6689837
-:101FB000CBB1A858EF81A9FF5283F8F994390228D0
-:101FC0003FF6A647489E1DCB62AC0D75BEC654DFDA
-:101FD00020E46BBE0E297F21C3F60F0E87250C0669
-:101FE00038D6BED3515A08EFEFE3FD3EBC86D53359
-:101FF0007CAFF0323C0C632CB63B4AEDEE0C8EA06D
-:1020000079D943018F07691F9AE37E7B59BB139FE0
-:102010008E8C6787EA29F6C77CB2D5CE8FE27840EE
-:102020005E024D88EB9698EEF80AD72FE43FD0E990
-:1020300006DC1F90FAA447267D78CA466FE3822A01
-:10204000C1914C77D0AF89FACD37FB31A76EB1D7AC
-:10205000D7077F146D1C49FA681BB5F3823ECAB1DD
-:10206000E9A3BB8229F4D1C84AED6EFE9E97A1FF79
-:10207000BDBDF4FF5FA9FA43FB1FD27B8F4EF8AAC8
-:102080009AA8FD08CBE38799F2041A1681FC186020
-:10209000CA8FF41BEBA658E48F31E1619437D7EB7C
-:1020A00092A8CF7F98F44EC8ECFFABA57679B4E048
-:1020B00061BB3C9A7923D627E44FED4376F9137E32
-:1020C00018E545708ED06BECFD8770FCE62566FF49
-:1020D000D1D120DA250E531EB228F2A1CEE2659BA3
-:1020E0001D79E4D9F6A5A8E74CBF8919ED0F213C6D
-:1020F000A69FF1D6B3FAC3A817412EB2E3261F8CD0
-:10210000E8C9EFA61C30E9C7B40F5F7B31AA1BD02A
-:102110006E6E8516B3EE4BDCCEECE6764FC2BEFC9F
-:10212000DFDCFEEE7BFBF1759ABF80D3DB3730FE40
-:102130007BD6F14D7B0ADE7713FD89F7979A3F072F
-:10214000F09D26F8C673F82EA2FF17B4EE00D75301
-:102150007F0578D343163FE012C4E7B04B1CBE7135
-:1021600021DCEF2ABEDF8F69CC94E31308EE1E74E6
-:1021700070DEF45F42E396F2755BC6D5ACF3F5E62C
-:10218000AF43BB327BBB38FF54105C62DCB3F4AFAF
-:10219000B6B78BF78F842CF4D9077CBEC8BABFDFE3
-:1021A000801C5945E38FE4E3CF4BE0F126EBFBFFC6
-:1021B0001F373B279DEF207AAAE7F4741EF6F60F2F
-:1021C00010BFDBA4763D8BE2448689F7FB701C7858
-:1021D000DFED82F731B11F8F14471EC0F658F48F20
-:1021E000B3F827C6DC5D085FC23F81810A2CFA9EE6
-:1021F0005DB70BD763EAFB27428B761940277298AD
-:10220000B77FF4C0CBCB70FDC965B04BFE99F63FEC
-:1022100007EC92316497FC0BC275AE7101FE76C279
-:10222000C3D39C6E52D43F49E33EC6EBB7BAB81D48
-:10223000FBD6924FC98ED36E551D68C7997AFDF9AA
-:1022400010B767C11EA9887A7BDA8DCF8B781A8C7C
-:10225000FB3CCDDBCEF1DF199133D1DE4CD82D31F3
-:10226000F2831276D50AA2A3B85DC5BE4DE5A96278
-:102270009FDF087D679980F7571C0F623DE76EDF8F
-:102280004170F879FB14F59D345E2E8793790F9D8C
-:1022900040BF95E895FF8C7440799528049D0B4AC2
-:1022A00072C06E39D02AA948262BEF33F7F976E2AF
-:1022B0008BB8DD26F8F07A41C79F84D6D33E5E7F87
-:1022C000DAE4FFFDD47E7CDC4F5D4FF0BF2DE213DE
-:1022D000DF0BAF37E1FB90E053397CDFC0F8A70993
-:1022E0003F8CE3A786194EB4CBD0AFDCC37AEEEFB8
-:1022F00017228E03FDFE2FF5F370B86A7489ECF790
-:10230000C88A634EA4F7A59D4C4B451F72D865F64D
-:1023100097C364970BFF36C0E342C9EDD3C2717A0D
-:102320004AA3F63E3EDF86E2480696A7E8AF870757
-:10233000F1ADF1A03D1A2995A22D79E8DF78CB4ABD
-:10234000A13CC7C1BAC9EF636C33C67DDDCF2AACEF
-:102350002540AD55C512D7012EFD35FA910BC43E6F
-:10236000CF61F1F88A03E33596F80DF981EEF09D1F
-:10237000F9AD2AC55D286EE3F2CBE45704EF5E4168
-:10238000F191F422B7CF8DF3C8B9E4E7BA1E10F18A
-:10239000A2F9DCBF74C03FB4A3D3D732F2DF666DBD
-:1023A00097A22AD4BB357BFCA576C3A926F2EF56AB
-:1023B000309F067EA25264AF7725F9AF8D857A00F3
-:1023C000F172F2BE5A07E22358C9FDB093F75DE1FE
-:1023D00045FE4BF6A34FA21F4D52AA871F6DACC3FB
-:1023E000F89AC58F5ED3877E74386CF7A38715473C
-:1023F000CAC248E78A46F2EDC0D44973C95FDE2EEF
-:102400003337B43FDE3AFED522281BDB9500861B0E
-:102410003E706A4BB1DE007F5A1E46DBC430BE35CB
-:102420005BC07FBCF85429C2AFDD3E2C80F47EFC3B
-:102430006E37E1F9F8CAEC68068C97B5FDB34D69C3
-:10244000D0FFE5E8100CB2C5FDEB643F1CDC2703B0
-:10245000E9E6381BCA5A701F141FC37195FAAC8085
-:102460001148F8DBB3F37D068EA7473318EE7BECFB
-:10247000974C3A99CFE8C801E9780E539D5898C710
-:102480003427E27F01D3A97C1DF09B7405CE976FA2
-:10249000101D00DF61FC6E7DA17E13E1E3414E1F44
-:1024A000EC1E65179E571C37EECD443EDB9B6E8FAE
-:1024B0003798CF3522DEE0413F7F4C9FFAF9EB0899
-:1024C0001E2127CE43AE34F0FDE4FC7A1AFDDF81F5
-:1024D000A427EB90CF3B441CF89E6C1E3F690D7304
-:1024E000B992FC0486CFC1FE17AA27405FEE08DB35
-:1024F000FDF89D583E0F7DF94392334FF2753687B4
-:1025000099297F7E1CE676809A45F11410C5D7F292
-:10251000FDC59FCF25FD611C5F7B4CA2FD4A531971
-:10252000C921378BC4383119623D6CC3207BBFBDD4
-:1025300067EB776390CFFF4191FE136C57720A28C7
-:1025400014DAB9AB781C7CB6577A495213ED8E6019
-:102550001C2A55DC5FC85168167380BDB2230BF688
-:1025600000E3DB4AA01FCAEBB71AB4A368C31D6916
-:10257000A8A06797524FF2A3EB3E39DA085D5F6D72
-:10258000601DA5A37A8E5BB32478F484451ECD2EFE
-:102590007BC403429135E5B71D92305EAFB9553724
-:1025A000F4EFC88CDC83F17AE37599ED017817CEEE
-:1025B000AF3C7AC2221F92C785F998012CFB56982E
-:1025C000C7315F0CBA63D3009E1586144579B0C23B
-:1025D00038E6C478E5D2B5CB980EFBE42A3AA6E0FB
-:1025E0007E96077DB4CED94532332C70DD7FADD6D3
-:1025F00011E6F19D37687F03713BEA4D2C079D5A28
-:1026000096AF20118734CF051E0BEF267BB4239B9A
-:10261000D1FC113F8B36A2FCD296B9BAF19CC51FF2
-:10262000A1B8E9E1B04AF3AE6CDD45F0A44FF998EA
-:10263000E001DB39E6E8DF13DF261FBC2EF0DE2CDD
-:10264000F0DE1B9E3F09F3789E599E5DA664229E94
-:10265000DF50543AE7E88DBFE796DAF7C7EDAFB041
-:10266000959BB4DB1D484F275BE528EE133C5FC10B
-:102670007D3B0DFBC6F212E37464B21AAB7E36F7F3
-:10268000674AA94C7099FBB3743BDF9FA5DB838439
-:1026900097A5A595AEC1FC5CAD1D689BE945CB181F
-:1026A000E2C5A51D53508EF5B65FC06FEE528BFD8F
-:1026B0007811F1F37EA516BBF69B8EEFC37C4369C0
-:1026C000BE243BFBAF75BE60D25327CAD582845C63
-:1026D0002D2BE5FA20F969CA558B3D49714D0B1C2C
-:1026E000CBEB2E020E934F904F516E84774ACEEE75
-:1026F00002DC7FE0D731689FFD76F36539C8378CFF
-:10270000E8C151CAF9C635658E0BFDA695F77DACBB
-:10271000A0BE027C4E277C0A393CB694997A6806A2
-:10272000D1451DA78BFFEE731D806709C1B984C316
-:1027300079A99D3B7DA73A525F4AE7402097BC1894
-:102740008FF789FD674379DCFBC2CE373F68BD9DBB
-:10275000A11D38E70F992ADA818B8AF768796ACA4E
-:10276000F34D55B29D6FD68618F9158C8506B37357
-:102770009E6F269F9FF63CEF345E6ACA49D8DDC93A
-:10278000E79DC9E79AAC97F3CF9EE79D2F561503B7
-:102790009C3302B24F5513E799AE2927DF65D7F472
-:1027A0003CEFFC12D623F099C32CEBED1AAAB6C766
-:1027B00000BE96C19E401B6FCEE46B1378043DE0D3
-:1027C00071C33C9BCA007EB497F3DA7E308FD9F098
-:1027D000E8223C5C201EE97C1BF1D22A4537627F4F
-:1027E000A5DE4079BE92F9D4FB0389FD8C8F977FDB
-:1027F0008786F2F91F6ABDCC01FCBF39E736B60CFB
-:10280000DAA71F4E6332B43FACDE46FB7DF8A34C23
-:1028100015CF7BDD7ECB3E085C2A267C724F3FE9DC
-:10282000AFB08F1E64B91EFBA8B695A29E3DDFFD1A
-:102830007BA4387204F9D803FA5A199778DF3594D3
-:10284000E3B3FB2A166D937AEE23E05B23BF339F3D
-:10285000EDDA48F5F50CE3039B24C6F19D44178E91
-:102860008C0D069E6BBB967BC98F6AAAAF277CBF77
-:102870000EF8367C9CBFF09CEA2CFC65D2059306D2
-:102880009D3F5D24EFFBE1D65AB6F6D2DED75EF867
-:10289000737729DA3DE7BBAF5593B57E6513ACFB83
-:1028A000AC65970DB4F2AD21F2520CDA47633E638A
-:1028B0007BB27BDA51978BBC14186F30F61F52C66F
-:1028C000441C501B82E579C3597DAABC17E774EEFE
-:1028D000C72C01139CE22A463ADB331EBDAC9DEFA8
-:1028E0000D42BFCEB84AC532530F4591AE6AF912B8
-:1028F000D8911DBBBAB07E362CD69143AF54870514
-:102900003F81B23C1AB778F5B15754AA0ED0F82ED1
-:1029100010FEE8A72EC197944FC2A27B480EE86C28
-:102920002EC8FB1BD648EF61BB1A2383A15F9BC84F
-:10293000AB783429AF829767E78A7AE3DFDA6CE70E
-:1029400098C60B49FAEDAD36AB3FC58C63A4DF6C7E
-:10295000F685459F1D79E9F7CB0DEB39A6F1318D51
-:102960007F7489395FD16EFB39E69734BE19A7664B
-:10297000EC332A2F89973F27FD6AC691FF5436B161
-:1029800096C74DF5B9B8FF7258AA47FB08148C26B4
-:1029900051BCC6D786FE34D8FFF3B0FE6F7D9D6074
-:1029A00087DC5C6639FFF85B83FFB819DF370E2FD1
-:1029B000D70A2E7D7801DF0F10BE2B38BEFF06E050
-:1029C000FD59598A73804B08BE9708BEF839C47FF9
-:1029D0003B3C6F9559FCCF6F7ABEC993B513484FF6
-:1029E000DFC03A4E9559F20FCEA3FD7F517B715E49
-:1029F0009A5C7F73B98FC7B1C439F1DBF173BCAC9A
-:102A00005A1CAF3B71AE47E75E8973C4E157044778
-:102A10005AE11FBE1BDB9BE78853CBF36A292FBA11
-:102A200097734C0DEB156B7F95FAB724CDE712F534
-:102A3000F3CBBF556BD8F07335B5EF486A5F23D63B
-:102A4000B7BC7CDC6EC3820FF038A97D5C2EB189E7
-:102A5000B5F673C709B5D673C7D5E513779BE7FFFE
-:102A6000E5881F714EFB3F1D1FC172E16F8AF37233
-:102A7000930E874DD242E5132E3D7861FF16965B8B
-:102A8000E8FFAF30DF8A724BDEC585F68FF3A3D047
-:102A9000FB66FE04E0F7165CC7CDD355C27F72BE5D
-:102AA00084E92746BA5914FD96C92C2AE3B944246F
-:102AB000A0338C83C6F9DAD06A295E17BF1F51B1E3
-:102AC000DB7E3FA27137DA1709FDFD54AD3DCFA182
-:102AD000DC06F78E979F32D7DD546EC967E8EBF1BD
-:102AE000574FB7E3255E16F8597CCB8F87DAEF5F37
-:102AF0004476D33946FCFEC5229A3791DFF1EDDDED
-:102B0000F6FC8E35544EEC5743D27E7DCF06D71758
-:102B1000E50D04974BE4BDB95648BDDCAFB89EE463
-:102B20008279AE0B659B5CA0F23700D741938E048F
-:102B30009FC6E1EC919FB76C37C699FA7A7E8B5CA1
-:102B40007809E9A2EFF1CEEF779878EFED7EC7F53F
-:102B5000AA59FE6E6D5DC1D79F17F3FFCA53E61FDA
-:102B60005DEC3AF87D1157F27D11B6AED62E7FCED0
-:102B70001BBED3A9E5CFF9F5FFB277F9F317943F60
-:102B80004D5E07DD47D1FD2CE57D949BA7F373A92E
-:102B9000387F8AFB28F376A4F6A7FF7E3A8F5F9BE7
-:102BA000F1EEA0EBD40AEB79D70051EF9B1ECF1BBF
-:102BB000F04DC771D772F886A13CC4F31EA6300D44
-:102BC000786AFEBCA1B9085FD37FF2F1981FFCE4DC
-:102BD000CCC47893C578E63C2FCCC9ACB1E635E4DB
-:102BE0009AF34C97CCF8F4B0E988CF0D7C1D72BFF6
-:102BF000D574CF2BEE571BAD24BF9A9DA69FFDE049
-:102C00006E92677139F463A28B056E93FEA3BBAD20
-:102C100071E3B25FECE67A158A788E97E8775F2DDC
-:102C2000F979E7E85768E27993D82F23BE5FE3117B
-:102C3000EE73F5B7F8D1312927E1473F5EA84D4142
-:102C40003C833F5D723EE3009EC2B42F6BECFE8876
-:102C5000A57EFA745B5ED2A9D567CB4B9A3BFDEC9F
-:102C600079497313F43077BACDAE0F674EC038C9C7
-:102C70006047CA7B14BAD8D7447ED74F69BF9A4DF4
-:102C8000BE13E57BB279FD0DBF78BC56C07FE374FF
-:102C9000CBF98579DEC20A0EC530CE63C92FD21CAE
-:102CA000D6B84FF89813C75BBA5D4A993FD3835F94
-:102CB000B68AF1B7C7F7F1E6E93C1EAD63DCF17AFD
-:102CC00073DC6F37D2B8352BF8B8C97C73A788533B
-:102CD000DD99A0E33B691C2D9E6FB30ECB9832E0CB
-:102CE0001E9718DFBCDF1374469EC3739D66435264
-:102CF00051BEEA6B97D1B922AB606C14EC5370F003
-:102D000088ED283ACCF98657F0FD825F4BB19D1FC4
-:102D100024A43118F3C497D1B9F3B51ACF5B9958ED
-:102D2000D5280F5429AFA505F7AD78FEAE265CF681
-:102D3000754B7E26A7CA67E988E7B3B037460E020F
-:102D4000FE16F0E1BD903530CFDBF17C96AAB23BA8
-:102D5000ACF92C91AF97CF62C6FF168700AF967D76
-:102D6000CBAEE078CDAEE0784D9C03333ABF1DCDBD
-:102D70006A665C85F165BCB705AF3BC43DB733B946
-:102D80002C8AE7FF8D53D3298ED79DCDE85C15366D
-:102D900024ABFA5ACC23E13F69A34A298EEB86750E
-:102DA000E13AF05C3676250C2F2FE9174B41CFAF77
-:102DB00066E92CE0C5B8BFB19901DD84F57BE97CFB
-:102DC0006EF88A8FEB70DEA5BA5B4512B8BECE579F
-:102DD00046795CAB03CE3B300EE9979986F1EC2A3D
-:102DE000E7FBFC9CC643789A5DCACB265EDC4C7937
-:102DF000DF8A1725A9BCF6DDC62D072DED5DB1B420
-:102E00004C3C177C69BAC80712F78A98EC253A3807
-:102E1000E37744F11CAA4361071480A35697E9FCA9
-:102E20007DCFF65B5FC1FB634BFD4AC001EB0CAF8E
-:102E30009528FFEB7A1FC7D3670DC6968360C3A69C
-:102E40000D1E41E730677C1E8AC6372FD943717B40
-:102E5000A0970E05F37AD6C90CCFBDCDFCA7398259
-:102E60005E4C3CA62DFB94F07206CFC3112F45D9C2
-:102E70009407350BF0A1FAE89C7F13E2299DD5C792
-:102E800006C0BC0BFD0E16B3C4A161FDB63C3218E2
-:102E90009BF2CE147A63AB27FCA4AF0BF37C34B95E
-:102EA0002A86FB7AA688EF2B940348EFAC94D3A92B
-:102EB00089FFF4243A7527E58725D36932FE4F232D
-:102EC000DE2DF7B9F6282C10437AEB94C9BEE86ED4
-:102ED00055B228EFAAD54179578C45E91ED31ED6A5
-:102EE0003FD082723326D139C175026F26DE19AB0D
-:102EF000DFBC1CE3DCF559018CFF3347FD66CC8F4A
-:102F0000BA3E9A41F9778B583BE541DD801E32CCC1
-:102F10007B23F3B9B0BC9C05E829B102BA5FB2507B
-:102F200097882F7416ABBE0AF017BBDC996DCDAB3A
-:102F3000EA35AF09567ED2721ED1BF42C84B8FEE22
-:102F4000E7799EBAB8F7A3517E507659A9474F2129
-:102F50006FA715EB832B0626CA8AAF9ED1F9747131
-:102F60006448C58444FF470BB55C6C37AE481B8A88
-:102F7000CFBD68E7813E081F1AF508EA83C6424DB7
-:102F8000C5F6C9F2EA78EFF977B1B540775D28AFB9
-:102F9000288FB080F8B0AFF2EF0A2B7AE4DF4DA8AB
-:102FA000B0E4DF1D75F27B65948B3C99F5BC9FB650
-:102FB000F63AAA37EFA725DF4B630FF2322CC86829
-:102FC000198BF777EB69DD26DE93F1C3C4BDB4C579
-:102FD000FE97BBA46BFA206FCD07C6DDE0B3D187A7
-:102FE000C1EF2F57DFDA954379840AE51136E7F10F
-:102FF000FBCB9BB00926028DE4F6E097425F6DC9DA
-:10300000AEF707A07E8B93E7C3B07C9DCD1B9318D2
-:10301000F7CB0AD93C175A8A7400761FD94BA6BD44
-:103020006AB6AB157A6195D00B8F17465612FE1310
-:10303000F9DDABB03FF3C6A20EF3DC8EFFD03990C2
-:10304000693F1C19524FF9346E2DB5BD706B455C4C
-:103050009FDF4AE3B79AFA5CBB0DCBD306F8E623B1
-:103060009FB9C2326B433D36FB6692BB4F61DE288F
-:10307000D83413F5C6F020D8EF860A71DE54978D48
-:10308000E8621D1ACF278D95D4FB51DF6D199CFA8C
-:10309000DEF761B1CEF1C34EC938EE96658C6D1C7A
-:1030A0008BF833288FCD5800B204CAE0EE1FC473EA
-:1030B000190FDA01C5A817797B5F1DB4817D6C17E4
-:1030C000F80F8E06FA41FB6B943D1FC97C9AED9276
-:1030D000F3AD409467E2BA93F3DCCC7CAB2EC5C869
-:1030E0000CA4807F76D91A0FE56BE52EF7A09E6CB5
-:1030F000D6C2345E72DEDB965C3614E14ACE6B33A8
-:10310000F3A6CC7C2973DC7FAAB0E7B5B9FD5C6F70
-:10311000C193F2647E5AA1F2EF5268F6FC3633BFD7
-:1031200006DB537E4D2EE3F935FE7A86FDDC50C674
-:10313000F611917F969C570572E86744573DEC2342
-:1031400046764673B1C81B60DAE665681FE1F96D23
-:1031500020857D050201F5A00BF413D62BF2EA0AB7
-:103160004CE5F9BA76D4B4E2C8CB48972E7F5CCE52
-:103170001E22781372F697580F72F65756397BE66F
-:1031800090F108E66F6E91381D6E01BC3F91823E52
-:103190008E5448828F53D3CF1F04BD361646DEC2ED
-:1031A00079B41C7EBFE342EDCCE6849DC9F1D847DB
-:1031B0007626E0E377840F21A7011FBF473893F1FC
-:1031C000003F9B506E58F24C3FC57EBDE59926F7F7
-:1031D000BFD87BC212C80DFE1D09ED2F0857D5447C
-:1031E00095EB5D218F13F76D2F4E5E773A408E027F
-:1031F0003C681358DBFB2AB99C2B98ACFB2A492F5F
-:10320000F3FBBEDB82FCBE2F8B69A4F78F64EA352B
-:10321000C8A72C7FDC39E66B14F9B47A5D84E4FC32
-:10322000DC73B4DF48ED0B268BF5E6F727FDB14DD7
-:10323000D2EE4B9713E573ADCF53A98DAA447F53BC
-:103240008FD0F712B6E43B54039676CF44FD5BB8BB
-:10325000AE2DF91B69FF5A80E024909BB31CA7EEAA
-:103260001E21513EF0D3523F787AC0634B41D7457F
-:10327000023F60C5523D7B57F35BE31CB595F1B847
-:103280008A884BFCF323D67B4C732B7FB202E3F18D
-:10329000A61EC378C91329E82224C691DDB7DAF443
-:1032A0006472BBD24A7E0F645EA5381F107A6F81AC
-:1032B0009BFB51EC30C067D1AB05934315955C6E19
-:1032C0001992451F9AFA8F6A2CEFDD7E7EFF847576
-:1032D000DAC731D7B942D0A9392FD0EBFC4A1EBF8B
-:1032E000585069A95F20331EEFE8B0E30BE0594462
-:1032F000F03076A217781E49094F971D9E1571BAB6
-:10330000D556E078A09757E2736B08E82E057EC784
-:103310004C08DD84F50A33B68EC83BABDD5A8FEB23
-:1033200030CB16BBF5B64ABB3CBDBD92CBD3359571
-:10333000244752CFDB50C9E5629F7D3FE03CF9FD59
-:103340002EFC3505DFB4743F99710DB09ADB6DDC4E
-:103350004EFC5930EE1CFCC5F9F9C661F5A4E79E98
-:103360001376C8734EA6607E0DF0582055DE4FAC24
-:10337000D2B43BA243102FCFF46277C4DBF5925F47
-:103380007F25DB997131F647CB942319647F9C6EBE
-:10339000CB403DFFCC89504AFBE3B9DC9D4352D979
-:1033A0001FFB7AB13F9EAE14F6C7072EB2274A3EE6
-:1033B000E4F647C9873B65B423FEBD52A5F5149FCB
-:1033C000E8907580BB04ED0F18679FB03FB03DD902
-:1033D0001FA777CA0857F1871DD4AF04CA687F14A6
-:1033E000F7627F001432E2E1E992963771FF92D7DB
-:1033F0005B355EFF85956E8BBA3B28CE63F66BC955
-:10340000DF98A1D37EDBE9675A3197BB897E9CDECA
-:1034100093DBF546676572D5D66E58D73696B99365
-:10342000F23295FA87B16C180AE56BE10736906EB7
-:10343000EE9C0D306463BBFA47BB51BF186E1F7E14
-:10344000DFE0B3F4A5DCDF59C37CCEC90979444B76
-:1034500007D08C9018CFE5F13581BDF4A38C2CC238
-:10346000E35A9F19D7D9593102FADF79E548BAFFF3
-:1034700013BA170682F2E44E99EACD38D02B83199D
-:10348000E5E903FFCEAA86F1278AF141DF69B74358
-:10349000FB05C21E2B97BDD4FEAE7CDE7EB271AAA8
-:1034A0000ECBC5DD2E15EF993179837C0BC66FD11C
-:1034B0002E81F6773D1B29F3407DFA118004C77BEE
-:1034C000D745710C0DFE21FF4EE86C277C669C7081
-:1034D000D9E21BE920E16216FBC5955466F2927EA3
-:1034E000A9E493F9EC110F9A21E211D7B0BFFB0ABE
-:1034F000ECAD336CC3565CA37B54E8C5DDAC677F91
-:1035000033DEF0FBF19A7706ECE348A74EFECBBE24
-:103510000AC035ECD3BED6D699D720DE772A14DF81
-:103520003DBA3E83F669FFBDCA2E8C2B1D053EE5D4
-:10353000F1F3B52B915EF7679A6516C3F8DCFEF8D8
-:10354000F70A07F07A515667043E40DF78FF40D112
-:10355000DE68E5F56699DDB512F337F60FE6E51995
-:10356000337EBA07DB63C637F9D76B8F7B53C9CF7E
-:10357000513355DB3D8F5945B7723A3E473F90F77F
-:10358000D7CC18D8B35F5A35F7B3F62F0110C7223E
-:103590009EF4C21930FEBEAEDBB68E81A9C64F596D
-:1035A000DF41727440F79A54723F3483DBCBB1929F
-:1035B00028F95DE0CB73BF972907318F751653C784
-:1035C000A17FBF63EA33FF710DCCF36AF1A871727A
-:1035D0000ABEBE61C688A475BD2E2F47B9F4D1FBC3
-:1035E000F353C981E64ABDC2BE1E7E4EDAB45321F2
-:1035F000FCD7FDC7278F60FE43AC6427C5F1F6FDFD
-:10360000C1C1D06FD93786DBFF78534FCEE913F8AD
-:103610005A27A6A03B806F492AF846CF643C4F74D6
-:10362000BCB614EB93E15531DE0DF08299154039AB
-:1036300092F6DBEF77605C735FB783822B674EB4E3
-:10364000C948822D5D234AD16C9D56754C46922AFD
-:10365000F1DDBB198F80F50DB28DFF2676A5DBCA93
-:1036600037D40FB09517D70D49F023C3FB4057D877
-:10367000CA6EFFD5B6729015DACAF3AB26DBC62B3D
-:10368000F3856DE5E9FE99B6F695EA3C5B7966FE51
-:10369000625BFBEA40ADAD3E523056C1AB7C409719
-:1036A000CD88AF8C4E8DF87C4BD76D3EA48B58499E
-:1036B00084FCEA23991DB918B77EA597EFCB75CC8A
-:1036C00090857E07D308E524E8F38DD989F6C111EA
-:1036D000DDB6B8FCCF67707DFD84A0EF73DF87E3B4
-:1036E000FAF97CEFC125EBE1D957DD4672A965BE39
-:1036F0001CC57B554DF96F78F1FED82BF3793CA1B1
-:103700002517D6E9A5BC0CE2AF17175C3714CFD745
-:10371000D2F3F50128FF4DFD1DCE8FB2E3509FEE91
-:103720008BB22BF09E19946BC57DB370017F3F5A0D
-:10373000BC5F854FD0DBE5167C25EBE3A067EC4B47
-:10374000E036B0A97FF2D177FCE617F0B84FE9E98F
-:103750006829DEAB9EA9BD70905F9FE6F2E7D59227
-:10376000DFE5F4A2B7FFDDCE0FAF133FEC3B31F73F
-:10377000ACF2FF370D3CCEFE548387C5607DEF363B
-:10378000F8E8F99F0D7E7AFF7A834ACFE6867C7A45
-:10379000C61A0254FF6643113D0F3668F47CB9A186
-:1037A000829E871A22D4EE570D35F43CDCA0D3FB61
-:1037B000F76770BEBC54E0D1F2CDB842E44587440F
-:1037C000789D8F29BB933ED464AB7C07BCFE76C644
-:1037D000849E78BD583D122B691F12E17A2B251F5C
-:1037E00039679AF76EB99D3C4B27991F87CF857132
-:1037F000BA9C449CCE8D264D7F82F32F7D09E77EB7
-:1038000011C7D99FCD6A9EE0FED42689F48D6F2C16
-:1038100097E7F7474224CF078E4D2DCFF37AC8F3B1
-:1038200065A4B7D8218C9F627A110AE395387FEAA4
-:10383000B888D12FEFAC78A0734B130F96FD1A3ECA
-:1038400033051F9C0B0FC9EB9F56AC8D9E3981DF52
-:103850004771F6EFA94746777FA1616CEAE9020E4E
-:10386000EF8EF7E7F6437BC58D4129F2DFC1702B60
-:10387000C2FD66665EC19EBADC9EE3FCA6A49DF412
-:10388000FA5D713BE701B26392DBC1CF41C203EA4B
-:103890002D0B1E52C881693353D04199FC6CF746F9
-:1038A000E8BFBF9B51DC4C459B1AE07F46E1DF6BD4
-:1038B000D8FFA183F07CC623917C74AFBBDD83313C
-:1038C000EEA7BFC7DB19D512DD63C838B04F453B43
-:1038D00035D8AD0FC0EF8E15C52A9DF89DD0D09478
-:1038E000B181340B1D8414BB9E444B35AE77282820
-:1038F000D63FA97C79A2BD8CFB3F2251CEA3FBD73A
-:103900008B705D734FD533B540C459BD29F1B45A9E
-:10391000B2C4DD1416D83A318FECCE8397E3F9CDDB
-:1039200028169589AE0CF2BF4D78656F84EEE79945
-:103930007EFAE792B60AE7EB317E9D46E76FCCE16F
-:10394000A0F3B7F585FA2D33E99C3EE97CC6F7F282
-:103950009F25D0695B1D2C86F68591E522FC25EF1D
-:10396000D7B8A2CADBB1BFFF6BFBF53B25EBF70273
-:1039700046ABD3C89F3A03FE14DE476952F83D298F
-:10398000E3DDCCE81E0292E5A3DD76A77C7500F7A7
-:10399000FF4719FF48FED15A5824FA5FDB851CBE49
-:1039A00007E5303CB73BB9BFD5DCE8F6B5E5A0BFCD
-:1039B00095653840717D96362CCA609DAD33B93E11
-:1039C00077B31BFA45C69C057EE19F38E3FB9EEB6F
-:1039D000237F4394BD2EDDF109FA7547E428C6DD47
-:1039E000B68D7DB06639E26FAC879F7F2A31750E48
-:1039F0001A683E83E558EEF1CB4C398971DAAD6037
-:103A0000CCE039EFDDE21E6E66C061B377FA15D9FE
-:103A1000EDB59FF411DC2E9444E8B7E6B8A2988F78
-:103A2000A3A2DC02B8B7FA1DC45F9B542E1F3679DF
-:103A3000358F2FC5FE6E417CBB7B9F5FCEDBE4C321
-:103A4000B8F74EAF83F877ABAA6CCB83F2562F371B
-:103A50006A9B544745AAFCAEEE99DCBE8226699467
-:103A60000F159C4BF64E6FF3B4887D37CBE905BA42
-:103A7000467CA60622B89E266F8E84FB62D6EF9FF8
-:103A800029097DC5E3CADB84FD949EDF1EC3B84EC1
-:103A9000F3E05585882E0FD84327E1BDA7A09DEC04
-:103AA00027EFE52E3D15BC27C478DB9C810AC4E7CF
-:103AB000B64C0733007FDBF27A39DF12FAB2491DC8
-:103AC0001721FA067C8C927AB67B5EECF366E74EA1
-:103AD0003FDE5BDB366A21E5856D1BCAE5F3EAC391
-:103AE000BFDED388FE83FA5DF609F24D8E42FBA657
-:103AF000B28007F55CB34FF1615C607CCE1D9EA087
-:103B000045CE25F38973F0DC1ABC4F78A6283D809A
-:103B1000482F930FD377459A032077F3306FA9DEB0
-:103B200067FD5E00D8DD9F21FF9F8B4E55A67B1061
-:103B3000BF303ED1516FFB970C8F1725D3B8B3B46C
-:103B4000CFD66B527DC7645415C7AB4937CE73D0FF
-:103B5000CDB9E0B7E9C5DC845E1C5875D92A3C7F35
-:103B6000BE9BF1FACB0EFF8EFCF4E4F2D7E5CF2634
-:103B70006527C9EDA6912EA2A7E4FEDBF2383CEF43
-:103B8000CC3C29E20431E2DF6C0F8F37DD53D43FA8
-:103B90002D955C2E1BAF8FA9B2D81BD9A5EDA46FB4
-:103BA0005D558CC76BD5886F248CE3ED94814601FD
-:103BB000DF8E2FFE744CBD783C2A3BEB5904C6CBFC
-:103BC000EA94893EF1E70B9083FD841CDC32FC8F84
-:103BD0000CF347765CA10478DECA4781B3E993AC65
-:103BE00029F678D285C68BAAAA441E431A4BE379DC
-:103BF00043552185F2751C5CCF6AF0DF2021222419
-:103C0000B1FF83C451948AAF789C2C670923B919FA
-:103C1000CF5FC1EFCFE0383A237B042FD062BBCB1C
-:103C200057737B2B97754B781E381CB37864A47739
-:103C30002E3FCFB05C07E5EFC034987F22190ED23B
-:103C40008B3F1C7E540AC2DB7B8A578D457C24AF98
-:103C5000636595887BC5D771763C9870F6359D9ADB
-:103C6000FABBC9C3F5B1068A3B0D8DE5A4F8679987
-:103C7000BC81EB63C3ED437DDDA4D43F8E65E81DBD
-:103C8000A1786952FCF3B3341E1F95EE603EA998EB
-:103C9000E29FF9B84F6B597A00E393FD14DD83F589
-:103CA000192315FABB0C60774FC4F396845FAE7A84
-:103CB00079BEDC5ACA2B7C1EF51AB43BF0C5D9E597
-:103CC000D193E7D06B2D9D23BD145FF7D466A03F41
-:103CD000FE947FC461F46FCE7878BE97D9EE40D25F
-:103CE000F74F9A859C3B5C25E2E8699FC9D87F9A8B
-:103CF0005F5530AF2EE4194BF2BD494A7D5ED05975
-:103D0000C5F5C168F5354E67ABCDEF96AD26F9FF29
-:103D10004EA6A0DF3A7D31C59585BDC7344DF55D12
-:103D20009BB0F34C7DE9577CC6CD388EC8B7EAB15D
-:103D3000CE033731FC1E0BF35BE2B32370FE7EF142
-:103D40003C3BE2E724FBAE377CB608FFB8C91FA2B4
-:103D50003C8D3328B3529C9F984FB0530FA29C9A2E
-:103D6000D061972F19F976F9B2D5514F795FC6D541
-:103D7000CC877921AC2AE0B7DAC960AFFEB28ACE2F
-:103D800077ED76E74DD58C7F673B5B55304E13F66C
-:103D900004199E4B28B93AC3FD70F90367DD8FB64D
-:103DA0002AAEF79BF39747D0AFD931F53B8497F113
-:103DB000153C0FD56C07FAF29D2A8B7F63E6299C90
-:103DC000F7F7947C0ECA5F3CDF3852CB9495FC7BAE
-:103DD0004AFEE5F43DA5A73CFC7B4A0732F50CB44E
-:103DE000BF2EF47B4ACBAB39BD863CDF7E71DA084F
-:103DF0000B9EBA74CA1F71F94FD1F9CD34916F92ED
-:103E00001C2F72BBEBE9BC2D5652BFD81A2F36F1CE
-:103E1000D726F4F66F4A74CA0BEAEDEF4198ED101D
-:103E200063B82EB788876E29594FF89F5B914DF183
-:103E30002845C4A35CA774CA038E8ED733AA2DF875
-:103E400077E71AA4EF32FE91F1FBEE9FF3FBEE1938
-:103E50001B5908EFB787BE1847E754A1581AF1D984
-:103E6000D4D301FA5E7599FCD8D611507FA053A126
-:103E7000EFC81F989A9E837AEDD34E6EDF661CB80A
-:103E8000EAF0DF41B9A4B316630220770096FE3D45
-:103E9000D731F5B4E36BF99913D0CFB49C9798E37D
-:103EA000FEBCE110D1C7930D1DF4DCD710A3674B06
-:103EB00043173D8B142D8CEB29EAA0B34B36E90454
-:103EC000D45BE0287A17FA5BE8C1375E1F5F4DFCD0
-:103ED000D7616B9791DF656B077E6E11B653FC1C43
-:103EE0009F2EFCCE188C3FBB8B6D96D4FF51F26A8F
-:103EF0005175DFC8AB1BAB079E4D5EF1F3D45097F5
-:103F0000F8AE58123FFE5795CABF8F64F2A53857D6
-:103F100035F5F456FC15F46953D677B87C8BE76F0A
-:103F2000F0FB8AE677E9EF78E5E45ECCEB697E5B4F
-:103F3000D41B9FEFC5F3DCC4DFCDF8E32ABC77F2D6
-:103F4000023AB76087BEFBCAB3ABF0FB410B6BB262
-:103F5000150DE00BE3016C76E2BE8C99D7988CB717
-:103F6000DF543BCCEFD0511CBE7904FFFB06C9EDFA
-:103F70005EAC167E9B6AFFBB1FE9BDDC137AAE9A6E
-:103F8000CB8B5F0ABC6D75F13C85DEEE837CBFFA9E
-:103F9000ECF741DE14F5E7BAFFF113D1EE0931EF8A
-:103FA000B04991FB51FE987F97E349F13EFEF73807
-:103FB000FC2CE5386D42EE5E3ECB27F653A3EF9F17
-:103FC000C1788F107D88BF9F60D64FFA305EFF4F5B
-:103FD000541FFF3B093AC589CCFB786DD51D7B1B6F
-:103FE0002DDFFF6A8E7F5791E739FD51E02DF9698A
-:103FF000DE47897F3F8A1DDEAB59BE1FF540F59B2A
-:1040000027C5F7AD9EA6F58A7B38DB70BD03E9FDB9
-:104010007E7A9FF43D81A75E39B8577C47F179825B
-:10402000BB3EF93B5DEFEEB57E1F615BF53BAB44FC
-:10403000FB97683CF15DAF147421E8F6E85EBC1FA5
-:104040007A1EE3BD46E389EF72ADABE67CD41B3D3F
-:1040500043FB23046FFC7BC5B51ED42B897BFF4734
-:10406000083FE781AFA334AF6ECECBF125BB39BF9C
-:1040700098F964265DB0597C3F3656C7F3744F12E9
-:104080001C2BFA0C0FA7089EA47B48E75AC7E385B0
-:1040900091CF080E7F3C1FF94F34CED784C7BC3F69
-:1040A00096CC1FFD6649661EB46B16CE931BFF6E41
-:1040B000A77B561FCC0BE366D33889EF81F69F951B
-:1040C0005AFE5CD0B84C3DBFFC12B3FCFF0015C8D3
-:1040D0004EA0007100000000000000000000000081
-:1040E0001F8B080000000000000BF3176060F85100
-:1040F0008FC09C687C5AE3BF4C0C0CFACC0C0C971C
-:10410000D818189C39191884F8C833E7229ABE7B4E
-:1041100040B366F030302C636560D809C47A5CD84F
-:10412000F5D90822D847817E5F01C417E91C06A390
-:1041300078F0E01A11068649A208BE9E18AA7CAD46
-:104140000882AD2345995D4E40FD008850BECB806E
-:1041500003000000000000001F8B080000000000AA
-:10416000000BD57D0D7854D5B5E83A3367CEFC26E3
-:104170003949069884104F42C0A84007080A1675AE
-:1041800012C146E5B663DA6A6CA91DAC527F61B410
-:1041900056B956CC4908C92484101015A9CAE02F75
-:1041A0005A6D53456B9FE5DE09508ABDBE277AD50F
-:1041B000AAD5DE5829AD566DBC9692BE8770F75AC7
-:1041C0007B9FCC39273393A14ADB875FBBB3CFFEFC
-:1041D0005B7BFDEDB5D75E7B8FE27041F509004753
-:1041E000F1DF5900F7FB01605C3A9DF9BD2F5FFDDF
-:1041F000781DFBDBEF0E3FC89299BF985F119B962D
-:10420000AE3F0724AAD7F08BC57F0456EFDFC1A9C4
-:10421000B9D9A79D0543FE30CBEB9213B09D1BEAA5
-:104220004BFF25C8CA871DE16E964F1D760480F5A9
-:1042300033039CD80968A006A2D3D977F9CB45608F
-:10424000EADF9E9EB949865429C0AE95204759BDE4
-:10425000D505A72D1E0C00BCD092FACBFE290091EB
-:10426000D449B2C6FAD9DDB297F2FFD6B2EF2FFB2E
-:104270005D003128A6711AE67F242F61ED76B9A082
-:10428000B99FB56B8848AE25A6F162623EBBBCA261
-:104290005CAD97339617B072F6BD217841C6F2181F
-:1042A0009B11D52B16FD0C0F3AB19E06437E9AE763
-:1042B000E1A68CF39C20DA19F9BA413EDF9D6F1D0F
-:1042C0003A1FE99082A2A81BD3C3D56F22BE073C38
-:1042D0009206550CBF83E7117E53885FD6C5A1B700
-:1042E00039BE777DE208B7327C3778D44098E54113
-:1042F00066F460E50D0188105C324B191CE70BB8C1
-:104300002F166913A644178DE832E06174098C0DED
-:10431000EF599B1482D798E700CE338F76065DD98C
-:10432000D740B480B583CC7C301A3F6CBCD9C70E63
-:10433000A781D7E8FC81BFECF700FD3BCAFEB75070
-:104340007DEE2FFB6BD3F9B386F759F28CA3C173C3
-:104350002A8317FFD43095FF3C689457F1721C27CD
-:10436000D1A2FDB986F15F5F0BFCB986F15F6F8B5F
-:1043700087F23D2D2AE5BB5B42944FC8AC09A3638D
-:10438000A207923A6B5F1C61F54DE315CD65ED4CCC
-:10439000F01584554BDE5F1BB2D4F76A9AA53CA199
-:1043A0005DEF4832BA774D73249D12C2C164E44474
-:1043B00084C3432903F7D5109B4F0D6F026B5DDA61
-:1043C000AFAA119E179DD0C6F2855AC47129CB574A
-:1043D000869C900CB3F10B8700587F8995001B5881
-:1043E0007F3D334F755CCAF2DDF3DCAA530548B25A
-:1043F000FE136ED6CF9194B60AFB99AE84B11FE836
-:10440000937F8B78F2B0FF8E56034CD694B71D8500
-:1044100000553AFB6E9E9F5B0FA15C17CDB57E9F4A
-:10442000AC2DBD1658FDC960FA5E95A6A731AE91B8
-:10443000B78F671FE78415B6FE6DFD566A83F5EAF0
-:10444000B474BF27C050AB1AF867EE37D220219D55
-:10445000C2A025671E3FB8032B3E2EDE3F3B8DE7F3
-:104460001E17D78376791B0407E90F90C74184C1D3
-:10447000A5698E6437EBA7BBCA41FCA3AD8624EACD
-:10448000ADB593F6C531DF5DA5686D2C5F55BBA753
-:10449000599A01B066924A7CD7BDC30D6D610E4733
-:1044A00090F169A5C1A74706EBAB910F25086F6096
-:1044B000E555DA8156ACAFBEEAD35C7347CF0F56F1
-:1044C000F0F9539ECD7F08FF9833BADF5FCE5122BB
-:1044D00051E45B1D926E064F574D5BA3CEC6B95794
-:1044E0009701E5A77B65FF6B88E7C4140EAF7DDEFF
-:1044F000959AB204F91ACCE3B3F12A6B2EBC1AE7F1
-:104500006587C3D017DF6F51491EEF6AA9A5F4DE96
-:1045100016B51FF5C45D9F3833E2F77C89EBE7CD14
-:10452000AEA803E1D3E739920F92FE896DBE92E502
-:10453000EFF9EEF859B80E5C3FCF41FAE5CF3D1CDC
-:10454000DFF7487D1703D55734AA6F93FF7BE54803
-:10455000DBB758FD7B42A5A03379AE74ED3BF74441
-:10456000EC6F45F54C9DF577CF0D1BDEC6F695F348
-:10457000A66A4ED67EF2DC036FB2451CEE3A3218C4
-:104580008A0630CFE5BA72C5F8FE1AC62713B5BE43
-:10459000EB70FCCAB98A96AC4AF3650584699C1332
-:1045A0009AFD9052C7E6CF8A6B72F3E7F1D3037F8F
-:1045B0001FB92A47B92A4DC3BD59D82776BA2F92B9
-:1045C0001CC42F23723597CBD513A7733A1B727572
-:1045D000D7A4BE778B58BEF71B9C4FED7C5E35F79A
-:1045E000403DD2B587C94F4908A0CCAD7D2CB17CE8
-:1045F000EF122187730F484B59FB3FBDE2D300E513
-:104600006971667D9D8D9FD3A975DC7B6F70344485
-:1046100059BD5F5E3EF58F6E1C6FB1A2A19CF5CABD
-:10462000B534BEF65D45D34DF4AC5CCCE489F157AE
-:10463000E50D427E6C7235D6F8899624BCC3E468D9
-:104640007D4B08228C6EEB5A3492AFB542CED01619
-:10465000853296177206B5B3289FCDFE046825B93A
-:10466000F368298831FAAC677D43397E4F4522F3E0
-:10467000014A50579D4EE0A41C6C6D5F37520E11DD
-:10468000C6F4D02B89BCFE473DC2C653C33CFF6C69
-:10469000EB1FF5554C08D77B797E87545BAFCF373E
-:1046A000B7DF43FD1BF5593ED55063EA0FFB9F660C
-:1046B00086C7518FF58DFE5E6F2DAFD7D9F8EB44CD
-:1046C0005E692BE6F9E3DC7F8FD41F624C0F6B6CC5
-:1046D000FDF448024FFA7F442281F438774AEF46CE
-:1046E000744BF91F228827A3FC07ADFFA1EBACFE9A
-:1046F0004710BD4B627498B520560E8CEEFEC61462
-:10470000A029B5DE86EFF4FC5EA4F905A6F1FC7DD8
-:10471000AD9F4410DF46F9D352412BE21BF92630FE
-:104720001E20444202B0E9E73D573E8F7FD79600F6
-:10473000CC63E3687DA0B13E1C357109F71DA1C5AE
-:10474000F2018B3C08BE63F03D2EB174D6FCD8D785
-:104750007029CC009F6E86CF187F2C780D38B2F36D
-:10476000271FDFCE470DE7CC7D613E932FFF3E57DD
-:10477000D8ADE13C5409F5780902C5F45AF1915DD0
-:10478000442790FB436847DBFB2D59500E49D33C2F
-:104790003F6B7ADE85798EB797CD7465F957CD7802
-:1047A0007C1CEBCD19CD77C6FCBC383F403B98CD87
-:1047B000AFCE3CBF279B717ED9F0669FDF3A6F5F1B
-:1047C000733483FE3DD321F6BB67CEFD12F6CFC610
-:1047D00003D45F5E6D88F4AF8AE3B1AD66D1915DBD
-:1047E000CDB8B5CD369E3A9F8D577BFCF039161F5C
-:1047F0000798FED2583D4738371FDBE5D998B71FD9
-:10480000E72D211FF1FD807DDE008C8F0AFEFF9DCC
-:10481000F7C732A7E70DAC7F9DCF8BCBC73F685E54
-:104820001F3F5F4AF28AF038393F8732F1D73B9217
-:1048300066D9E7DAF93ADBBCFE517C3A7A5EB9F127
-:104840007CBCF550BEFAB5ED551FE1B1F732BE4F55
-:10485000E8DDBB90FC0EBDCF9F3D01E1284C9C02E2
-:104860001166FF4EC5FE597FBD867DB1A96E8CFED7
-:10487000B97D71670BF4B74F0178AA7090F6C30C3D
-:104880004E6ABF99D99F49A6E0EA5EBCC1BB848D40
-:10489000B7F98A0D5EF42BF50A7BB1EEC507D69FFA
-:1048A000C3F039E1F292994EC60ABD5EE3FBF6E72A
-:1048B000A6B2EF9B2E13DF85FF8A7D7F11EB874425
-:1048C000FD6C70952983B128C90B83CB847FA3FC31
-:1048D0004907B74B9F403BEB44DCCF703BABCCD799
-:1048E000B704E95BB859D1EE9346F7FBBF853EBDEF
-:1048F00013ED3436DFBB2EEF2847BB6AE7D653777C
-:104900000510AECB80F4F989C987065C1A8EAF4BCF
-:1049100088E7275C60D859B4CE975F66D0B5493A2E
-:10492000BB86DA093B8BE7BF3FB2AE7E9DEC968A31
-:1049300018CF3FDDF6DDFA55B2A95CFF767DA422E3
-:104940005DFE42DBB5F5B8EECEF2C4DE98CF483757
-:104950008BE9BD550C8E59B2E68C23BF6C0A66B448
-:1049600017B73DE7694E32FC6EDB3A75F2E519D6B2
-:10497000114645A2B3919FBDD72A674F20FEDC8820
-:10498000476EB7F630F462FD504C5B85F89CBD175E
-:10499000C2B81FCDA6EFB2D13174B755DFCD92ADFD
-:1049A000F33A5EF3F90854BEDF16FDB375FD250733
-:1049B0009F8F13E568B6CCE5FFD3CE278578E276E6
-:1049C000C46F32F5FFF79AEFAC001B27F8D98F13AD
-:1049D000B28D93AD5FBBBED21B4092D11F5F0E6103
-:1049E00084A778411CD08FEF0CEC0BE9CCDE93D57B
-:1049F000414A5DC1A190CEF4AE12D2CA307557843F
-:104A0000CBF03BDB1F09F9E86C25BD3A92EF6A4514
-:104A10003DBA0EF3247F6BA87CC3487E2DE56F9BC7
-:104A2000C4E5F304E7ED03A887AB51D930B8D60E3F
-:104A3000BCDE8C7E80D2DD81309A1AA58130A01E2A
-:104A400036CA7B07DE0D79D08EDB1D002FE3F7120F
-:104A50003502E6F6EB06FE1A525979409407825168
-:104A60004BF9868193CA420C453E51EE0BC5A8FC1A
-:104A7000B68179651ADA31BB032A7EF757C469DC3F
-:104A8000B37F718D83FCB18B1C49B7495F2516CD6F
-:104A900022FDBE588A9DE464F4A8FF458F07ED8788
-:104AA000C4EE6913F03BD93CE44F92FF2FEE47313F
-:104AB0007B94ECA0807AE014412F679A1E3D785ECB
-:104AC000417E607E4E9110E7147A432A85E3EB85A0
-:104AD0009C4E8CA3D3FE676ABF37EDAFA6FC3E4B5E
-:104AE000BE404D46701F2D07997E60EDFD113D8241
-:104AF00074572A78DE1908A7507F6CFA0684116C67
-:104B000099E113EBAF9BC7F21AD23F4AEDBBE6F037
-:104B1000BC128AE9984FCCE47977453C85F9352772
-:104B2000F1FC2683CEF088950FE04F44F7AE91BCA0
-:104B3000B70DCB1306DF80BF0DCBD79CC1F56CB989
-:104B40005CBF13F1BF69A0AB6C29EBBF08F981F51D
-:104B50005FB4384CF432E872A7E6A0F5D6A0CB9D3E
-:104B6000DA2C3A279859C4304113D2881E334FB8F3
-:104B7000DEA1E279C7298EE483129E4FF5780759AA
-:104B8000BD4DB5B3A8BC52760AFF00F7873F28FC9D
-:104B900001D5CCBA40BBE341B15EEFBC7D6A11B632
-:104BA000DBB9F97F11BDCF741653BB35B5FCFCE6FC
-:104BB00019B64EA39FEEE9160FA53F62FDC598BE3C
-:104BC0007EBCC543E90F5A544A1F617A1CD31E5656
-:104BD0009E42BF032B4FB17CFFA0A311E5FFF61649
-:104BE000669AB1F6B7B5783E96A7A0BF42A5FCBAC3
-:104BF0009610E5BFED685AE1E4FE14FF3436AFA726
-:104C00005EAA21FF5EF875473489F356A174515DA1
-:104C1000FABB819F6F3B1A5622BFFE7050A67140AF
-:104C20001EEC3E2573BD36AC37E37599F7171CDCD7
-:104C3000707E3063BD4EACF7D87E0E377852BE2CF6
-:104C4000FDF520BCD3DE12F085522559FA5B8FF5B5
-:104C50001EDD2FE00B24BB4FCE5CEF0E1CF7E4B73C
-:104C6000047C15C90DE7651EF7FBD89FA784DB2BD5
-:104C70009F437F461DAD035B25933C6F5CA24B0EAB
-:104C800046674FE9601CEB4DAF8B4BD56CFCE025C4
-:104C900071C9319DDB190E96F7623F2C3DA59695A3
-:104CA000B37A1BB1BCC0548EED597AD2345E1EFC6F
-:104CB000A6B57C446F378361A7A6D0D91AFA8A3586
-:104CC0003FD5C1F5E3B3CEDFD623BF4F5578F97F8B
-:104CD000631EEDAE45B6FA3E9EFFAD51BF90B7776D
-:104CE000C83CEF29E1F32EDCEC49A2DDB57E61473B
-:104CF000E8D2407ABEC5E7246A316FCC6FFD399B9C
-:104D000043979AE653FC85BB6B2F9D967D5DF16AB8
-:104D10000E8898D6DDA97DD32052FACFAF5FBE6A48
-:104D20005A37705D9920D6850973F9BAC2F0A67317
-:104D30007B95E36DDD1956BC159D69C5DBBA33ADB6
-:104D4000782B3A2B37DE7E29C6CF863F367EC43C91
-:104D5000FE8673ADE3979C671D7FC379D6F14BCE7A
-:104D6000FFD4E3A7CC7CD3576F1D5F6DB08EDFD728
-:104D7000601D5F3DFBD38D6FD0A76BE02EEBBA5E5D
-:104D8000170533FD12035D21CBBA1EE6EBBA51BE07
-:104D900066E0A7215CDFBDB8BEA37FA696AFEF3368
-:104DA000DFF928847EFB7567EC09E13E631DABBB30
-:104DB0006F5A7ADDD879C68D8E4759BFDF3989AFF2
-:104DC0003303673CED41FDBFA696AF3309719EDB0F
-:104DD000DD923A788D2B3DAF828497F67B467EC478
-:104DE0005E82DFD5231F266A1DC25E2A6B8B305B75
-:104DF000D473926CC9774DE3E537B797B5E9E84BC3
-:104E000091F5325C87FCB5F0E76919F65BC6F806E8
-:104E10003CD9C7E7FBE2F4F8936DE34FB68C6FE43F
-:104E2000BDD379B92ED734203C9BC4BEF906F9779F
-:104E3000A45F8E1F7CD3DB223566F8783E0D1FCF32
-:104E40001BF0DD2ACF68D06BFE9EF09D66C3DF6944
-:104E500036FC9D66C1DF0A79EE31E1CF5EAFC7C691
-:104E60009F5743E426791CCA1190BD199755711EAE
-:104E7000C4FBAB93857CE1F818B7B344494EA9E273
-:104E8000E54D6C5D5B2C8B7D98A8DF68CB1BF62B0A
-:104E90002E4747C90F93D97E5580EB6D6677841FE7
-:104EA00024BD1E26794AEF3BB81F4396A39168069E
-:104EB0007D7087CCCF872535DC8C70CA0185FCA836
-:104EC000D9EAF7C992B0AF75CBF94E110CA59C0881
-:104ED0004708283E090E7F59BB60FA683814391A12
-:104EE000C3719CAA02F7B171DA8B2FD4CC714C8FAD
-:104EF00018F08422048FA2727814391CC9E407BE0A
-:104F00004FE67E0BA31F06A1683F0468271AF0AD89
-:104F1000F6469B97A03D5FAC109EDA0BACE7E5BF71
-:104F200011F37A41A4ED59CEFD00A331307E69FC26
-:104F30005CB24357CD6DF0205F6A10F6A0BFBE3D56
-:104F400090399EC848ED766782D9A598EF6076299A
-:104F5000A6ED81271A71DD39887C9CE15C7B44CF0A
-:104F6000851D9032ED3FFDB53E4859FCA74982D3DF
-:104F7000AB9558BEBB43E59676AEF132D9F3ED0161
-:104F80004712438DC682BF43C06FD4EB94E31E35F6
-:104F90008FFDB23B6485F7F8E18FB7F7BBFAD54CCC
-:104FA000707D567833F8CADEBF52AAC4C92E96A3C4
-:104FB0002133FF3B5D9C4F95524F9CDBEBD9CA7D63
-:104FC000BC7D8095A35D1C886A78FEC2449EE2C4C5
-:104FD0003C280726FC4C14EDDA5DE23C1AE2E4AF13
-:104FE00095B47833F291A742A1F3017B3B23F58975
-:104FF000F69D9F7CE735928F711E920F4963F29365
-:10500000619CC7E4C878174B37C9910998BA8E38A4
-:105010006399E4649C8BCBB1271AD53C3CD4242300
-:10502000FCB345BF7D06FC7A9CCEBDF285BF3A4FEE
-:10503000F867A7E19FE19A43F07F0ED36CF04F171A
-:10504000F094427800F7EDC8A0D82FC0059AF95C1B
-:10505000AE57F45B2AE003B88EE8669477093CE427
-:105060003B9FF979CEA7373D9F46319F7373CDE7BC
-:105070000B623EBD2EBE5E791AA35A88F1554916C1
-:10508000BA2C15FD6F1EA1CB75C7C4575FCD731E1B
-:105090004BD3F35822F8EAD25CF3880978FA9C30B3
-:1050A0006F3FC6CF4C16EB0D3459E8B2C5E02B3735
-:1050B0005F3700AEB7D0E576D14FBEF3599EE77C9F
-:1050C000B6A4E7F33D41975B72CDC754BF55D46F8B
-:1050D00013724576CB16D78E36B43F1E93A31DAE02
-:1050E00039E9F158BD4E73BD89ABBB8D7A6BF0BB0E
-:1050F000B468A45E8F185FD845F7D37E6C35DA1894
-:10510000CCBEF9E2EA171AD01E67ED3650FF51BE49
-:105110006EB276B799FB9FBDFA8E3651EF4EACD783
-:105120007AF611A3FF4DE6FEB7B852061C77131CA2
-:105130008D23FDDD63AEB7D4D5DFC6CF092BD403F5
-:105140007E935D13CAEFDCC7158C2506D15F090578
-:105150007D687774C8F12D83C80FCCC87B907DBF64
-:10516000C91D9124B67EAA91F8C358AF4477AB4EBF
-:10517000A45B43FC4798D71D10C5B8C83BFDB76E6C
-:10518000C1FC0AD9A3BAC3686F697434D41B9429CB
-:105190009E67B514D3715D3C24C79E7191DDC3BA7F
-:1051A00064E3DC54AA25BB25F4DF82C4ED0E0ED7E0
-:1051B0007AFF250984C3CDE0C2F8E0D536B8D878A7
-:1051C000B42FEF1AC7E36D40865A19FB73FAC2D8A1
-:1051D000DFC0B81B09DE44AB5BC5F689293712BCBA
-:1051E000AC2C4AF179AE38C1DBE9F2A8188F77A769
-:1051F0007FD9268CB75BA117517D8203E73FB99A0F
-:10520000E0F7423CB5A40AD5575FC481F02C522880
-:105210002E3911DC40FBDBEE456C9163E376D76EF3
-:10522000D0B1DDC1453E8AAFF306FA00E3AD4ACF07
-:105230005700E380BCC13EB2334BCEF3F17C05D0C6
-:1052400038259FE7F1B22E1854AB595A9AE071C72E
-:10525000DDB54DFA12B463E6F27854D0232F617CA9
-:105260005B31887FCE8A01ECDF35D109CE709ABEE2
-:10527000A57D23ED8B6219E465A45E32CF7AA9FC8B
-:10528000EA9524E4FCEAF5E5592F9967BD14AFE7E8
-:10529000860B8A32C57B8CF0FD0285EC0F23BEADF8
-:1052A0009059FE23F64915B7DBCDF68A0B94B4BDB1
-:1052B000827CE65C9C138E156FB606779BEC9BA0F8
-:1052C0005210A4FDC669701AC9E518ED0FB5E8C102
-:1052D000DDAEB1E78B129632F9C9C7AABF06ED3D24
-:1052E00077F672FF8C0B43A4CFA67F4DA48B793A3F
-:1052F000937D9F8669B3C87F4DE4173747328C573B
-:10530000AF703D5C0BD19C74F00AF80FE0993F6BD5
-:10531000522BB3FA19CEC78D3430CD61B31BADFA21
-:10532000CE23EB0D74CE51CBE307DD288C283761FB
-:1053300020FDE282945A4DE78B91C225E3D3F2E33C
-:105340000A8D27F9F93F654E90E6127DC288473BEA
-:105350009FD8F92260E38B4FCB27171F273EF127F9
-:105360009C79C98FBF2FCF7AC93CEBA5F2AB174808
-:1053700048F9D5EBCBB35E32CF7A295E6FCDBF282B
-:10538000C2DF7AFE2AF4C3F8BFE8B1E4D77CD16764
-:105390002DFF52C092EF39D7DA3E709EB57DCF799E
-:1053A000D6F681F379FB273BBE7A36FA79F29593EC
-:1053B000DFFD8D7252EBC95DBF64D11872E5D16912
-:1053C0003FE99535480571FD62EB9444692499C124
-:1053D000BE7B4EC8FFF32EEEC749C83AED6BFFD92E
-:1053E000E7F90385FB8D8CF98E05AFA17F7FEF1464
-:1053F000F696DDFE1AF1EB1C3E7AF454D42380C1FC
-:10540000D2A06A6C6AE8C7055F184345BC357D7455
-:105410003E6DEFBF0BCFEBB8DF25D46482E33937A5
-:10542000F7ABFCBCAA2344E7B553EE08E13EBD6BE5
-:105430009294D1CF7244E1E782D5313FD9199D9A38
-:1054400087F461D7247E8FA9CBD547FEE3AE2A6BC4
-:105450007B8FB01F8E287CBCAE957140FB7FF5948E
-:105460003B9A715C77EA5F4163707F77529CE247B9
-:105470003BDC7C1FE08EE880EB8247D3E9FCDD0E4D
-:105480004FC2881B82BE509369DE4D6ECE373F6798
-:10549000F3C9675EEF280AD557231C7FD9F0B5E31F
-:1054A00018F175B99BF7AB85BC84AF837540EB09E8
-:1054B00012D2C9E84824D6F0FF06C1CC6FF6F51821
-:1054C000C027F8ED28E535F9E29CFCD425FC30EB4B
-:1054D000D00FC352EDEEAFE5E4E74EB19EBBE1EB7A
-:1054E000D4AF5B8B4750DFF96AFBE052C22F4460B8
-:1054F000BCE03B82B73DE2C0F30580F0666627FA68
-:10550000C675855339FC629E5AEB7A77ACEBD96C41
-:10551000375BCFFCE9F5EC20F49013768D03AEC831
-:1055200074FFC358CFB4E0C539E7DDD5C2FD5600DE
-:10553000B7403FCEE76527F1B3A306F4F58C5EEEE6
-:105540005A99E21CDC913E5CA4C15303296F61F6B9
-:1055500079BD2AF84E0BE51E77ADC0F71AA4D389A2
-:1055600039EC2C7434B37DD9AB9DF7AFC2FD5BF140
-:10557000022E07237C2FF759F87358E17E8D2EAF4A
-:10558000D64AF12C55DC3F62EFB75BC06997AB445C
-:1055900096FB3486DCFE55D1B81EF2F491DFC19043
-:1055A0002F4DFB57D2735D93DA3C88A784B681FCFC
-:1055B000C4076B14C07B30767D300287C0FF59D0A2
-:1055C000E3C1FB4ADD2F3BE9FEABBD9E17376526E5
-:1055D000BF9EBFD6AA7FC7D227777E4A7DF21343EC
-:1055E000EE47EB135A7F2FEF6CDF85F4E9F272FF81
-:1055F0007549A30E4B4CF3ED11E32F768B75A18209
-:10560000C3D1E552EBCD742A66DFEBCD7A330B7D47
-:10561000B2D1FD220C069C9386C33EBF87DCBC5EE4
-:10562000098E3F6D6C3C8CA603C7C32A77663EF893
-:10563000ACE6D3E6CE8F8FEF16F5EE167835E6356D
-:10564000969C18FDF70B7C152FB0E97D59B7D0DF7C
-:1056500069E0ADD156CF63AD67E04776737BC5583F
-:1056600027C6EAFF2D85F387BDFF6C72F89B1139C1
-:10567000D4C92F6B8CE3861F4448EE985EEE9E09DA
-:10568000501018247F01DBEBF378A76014CCE73AC5
-:1056900076FD65E8FF6CFAC8BE6F19ABBE12547296
-:1056A000DA49865D5322EE4D7A443CF00629F339FF
-:1056B000CFB09023A6D8F38AEBC33011DCB74114E6
-:1056C000C4FDBFC8402BCB8F0F2B5A37FA3FE48560
-:1056D000035B597EDCCFDCD01D4697CB82810186EF
-:1056E000AF35114F14CB2778AA46EE69F59D8A7E17
-:1056F0002D6E7781F396D7F01EF0F88B6440BCBA1C
-:10570000611EC5691F5CC174D8CCD1F08C9701268D
-:1057100096B054F807E8FC10B7945FB1AD8B8B4C92
-:1057200079F4037BACEB5EBEF3B6C393ADDD98F0CA
-:10573000A4F7A1FB717C37E45ED78E757E23766D6E
-:105740009EF332EEA319DFAB869DA0E1FDF66189E1
-:10575000D21386FD94560E7B299D345C0A1A235A77
-:10576000C57031A5138727D2F7F2E1324ACB8627DD
-:10577000531A1AAEA2B478F8144AD5E193285D2FD3
-:10578000E4B0687836E58DFB6F85C333295F30FC64
-:10579000794A03C3F378B9384F5DBF3206E8AF5694
-:1057A000701D62F2B17AE1525A97ECF35AEFE1EBD5
-:1057B0007087B827DC61D3DBFDA2FC510F97FBF5A6
-:1057C000422E408E83D96F7E8FA8B7BE3A46F677B9
-:1057D00087B11E962DB5AC87F6FA1D59EE273F6DA1
-:1057E000940B78A0B6690CFAF0F357773046F706B9
-:1057F0000062A497408E59F46E87017F9EF708D708
-:105800002F7C9AF8D8CB0419430BBD5FB8BBF901C4
-:10581000D43BE7DC78C56E26771FB863377970DC38
-:105820002F5C454CF7FD65378750BFAD5F7807DDCE
-:105830006F42F31BE39A3BCFB925FE00711DA3CB4A
-:10584000746A77ABC7740EDAB5F4E6E687587F5A08
-:10585000BB033413BF56DEE203CDACBF0E97966197
-:10586000FB8A1B4A2CDFCBAF29B7B433EE49842E19
-:10587000ABB6D453179C6CA957387F96B59D382783
-:105880000FD49D6E69E70E1878E5E7888CFE96F5D3
-:10589000A353CA4CC7B887EBCB6C7C73A187AF6BA3
-:1058A000E9FE73D32D5BFFF9DE0B49F347D6799000
-:1058B000BD1B4F2C5A80F6945B8DD13D9563AF7F15
-:1058C0007CE7916F3DBBBE2A447D558AFA44A234E1
-:1058D00080FAAA14F5889752A3DEB1DEB75D8BFA81
-:1058E0002660D2377398DC67E0878037B7BE3945CA
-:1058F000944FF1727DB356F0959D6F42A2DE5AD45B
-:1059000037D3C6D637216F6E7D33538CF78FD6379A
-:105910005DB3EE887D8BE5BCA7DDDD7C3F4B3B674F
-:10592000DE4879A62F642F2BEF3CF596F8FD263D37
-:105930000287FF93F3A5E087A2B956FD61F45F10DB
-:10594000B6E911431EFE46B93E22F8351B7DF67FAF
-:105950004AB93E729CE4FA88A77B019E2FE62BD7BA
-:10596000A3EB1FDF79E45B4F6F80D459B82F99EA1E
-:105970004BAE42BF9BA32FCCEFE5C5286EA7EB39FA
-:1059800097F0F370FFDF2C4FE43CE49F599EE82230
-:105990002F6B7F7D953601D76996FF227E37E5A371
-:1059A000B67C93ADFE576CF90B6DF59BCDE5094DBB
-:1059B0009B80E78B89BD2E3A1F4C688EC64CFC74C9
-:1059C000AE97F3CB5E4F3486FD9D983C7902D2852D
-:1059D000E52FA5FEBCBC3F96BFCC965F4AE3A7F37C
-:1059E00057D8CAAFB2955F63CB2F33D7EF3A32F9AE
-:1059F0004E7A7FE3972EC07B0976385F117AA273C7
-:105A0000CACDB1362E973761FBCEA9B7C42F05E2B8
-:105A10000BF2A33903B6FD1FE33333BFEC15FDFCD6
-:105A20007CD28DB46FEA64FB278A63443F5E06FC38
-:105A3000FCDA2BDEE1D2AEA4FB0F89B2EBC9CFD1E9
-:105A400059D146710A073585CE67135599DB1B7E00
-:105A5000A6CE8ACCE708BFC6205C933D0235DCFFAA
-:105A6000876270D481EF0971FDBEBAAA83F4AB924C
-:105A7000BA92FB37CA62E4DFB84FD04F09C4C9AF4E
-:105A8000E0AE8867DCD7778EE0C3EAD7DC69E04315
-:105A9000EC234DF820396CEBFA6037AEAF096F6636
-:105AA00039FBB197CB992B94DFF8A3E7CFD7872D9C
-:105AB00078A925C3BE36E1E271F2FA24EE0790D947
-:105AC0003866BF827DBC9179DAF6D9F70A3C25BCED
-:105AD0003CCEDEE8CF0ECFC3A2DEC35EEE5730E68B
-:105AE00025AB7C9CB1FA7F162F6BA11F40B5FB2123
-:105AF000AC7AEE1651DF15B4D6CB869F9523F8E12C
-:105B0000F15806FF8EC5EFC6387B112EDACF66DE60
-:105B1000876B87E752FCC64128E8EBC67DB3ACBE75
-:105B200086711C37B16D12FA4557C93AC527E81A74
-:105B3000A80FD2F9273F7FB8C9797218F59D47C4DD
-:105B40005500C655044D7189C2CF79A7FFD687B1DC
-:105B50007C85EE56F17D9361EF641EB77A7805C5BA
-:105B60005374B19D3A8E7BC85B99C4F7AC9C453D9C
-:105B700064CF3B9D33E399E24C651FE7DBB30EAF87
-:105B8000233DDBA1F17B371D72CC53320D5DD53A3D
-:105B9000C96B97963B7ED11E07E952EDF187567C83
-:105BA0004DF771FA26C4FA9BF0869BCDF149219FEF
-:105BB00097CA87BD56F83A11BE00C215A778D244DD
-:105BC00085C381783B5EF019E32A558E28E22508CB
-:105BD000318A57F184641AD7E1E7F8CD362E68F29E
-:105BE000FBE6F7638E173E47D6DF18E727197CC41C
-:105BF0004FDA024FC336CC3FE7A4F5D43ECE7E5FEA
-:105C0000EC349FC92F2CAB317A77C6E8EFDC713CBE
-:105C1000CE5BAE00F2E32B106DAC62F35F55C1DFDB
-:105C200059940363C44554D8FD15D9CEE5F8F988D5
-:105C3000719E53FF073EAE4FC40B14C020058B1658
-:105C4000A14A9F8CF1029AC4DF81084B3CAE7C3E96
-:105C5000C59107BD9F75BF8BA95F29B21E8EFA8FB4
-:105C6000A15F7990FC5C9F79BF63C0EB85BBA95FA6
-:105C70000C4D3D5A9AEE17F52F39950E1F3D8AE7C8
-:105C8000664E30FE713B5C76F07B55505E48718706
-:105C9000AB83D77BCC746DF5555BD65745EDB84ECD
-:105CA0002AC47B9FD7440673F0E56A9423F42356F5
-:105CB0005C1619ACCD5ECF805366D3CFE40FED50A8
-:105CC00062C956B4172B033C5E558ED3F948A754CE
-:105CD00032ABBBCEC4BF154A0AE12AA88BE818CF65
-:105CE000D859EA08631C960C3DFBE87D27E7A270B3
-:105CF0002E79952BE4F7CCF3D9ECB3C681AC1A839B
-:105D0000DF570B7D9DADDCA5846399F4F0E33EB1D4
-:105D10008EF932977FEC6F78D49761DDD921F454F6
-:105D2000673153A59FE3EC837C2057EC790DF1B0EC
-:105D30007ADC39B9F5936AD54FFFE58FFC04C7C902
-:105D400001C7B399E0007C4C210FBB5F5D40C18867
-:105D5000E978A020E76B8C0392C6D37928FD5B5BC2
-:105D6000775F0AED6ED7924004E9E78C6C035C47DD
-:105D70008DB82067C4F7B683E8399FC707D5723F4F
-:105D80006B84FD477164F373C78D396DF95FD9E991
-:105D9000DCF20CBD1761C06FC4A9DBE7F5A4BFE15D
-:105DA0002DDF9C4CF8C86F1FB491F10B307ED9C029
-:105DB000D6778614E86B5129DFDB12A27C4F8B4625
-:105DC000697B4B2DA56BB0E93C8CFF8827AA703FFF
-:105DD000127A207439ABB2116942712D5B17E23E21
-:105DE000B27B240FBAC4E0EEC6FBF1CC0EFDAB6F64
-:105DF000C342B443BBC5BB3BA0772C44BB2C9DBF67
-:105E00006B35DA85DD228E565D73DF42DC3F6E9C9A
-:105E100064EC93239EAF9AECAF297E17F11FEDD56A
-:105E2000A8FDAAD5D89F571679D8BED09A8708C2A0
-:105E3000E3F5F0FCB9FEA7081E52016CBC0BFC4F49
-:105E4000537EE314E17798D634061EB91FA3C3A787
-:105E5000713B685A09F929947018AF17C0C66201DE
-:105E6000779EFDE0FE87D6BB9733AF9769B919637C
-:105E70005D13708C457F860EB22F500FEB38EE2BE2
-:105E8000FCFCFC788FBBD1756C7851E60EE978F597
-:105E90006BA72F76869FB52F88F4A7AA58BE70519E
-:105EA0004A27F1CD73DC32BFB84FC6E68BF26FE004
-:105EB000D9B03BAE433A8E4BF7E70A46E8BCCD2B50
-:105EC000DE13CE17DEA53ED5D20F3CD65096EBDCC6
-:105ED000655CD481414623FAA2B4D127823578BECD
-:105EE000385262C917CD2DB7D42F08575BCA5DEA67
-:105EF000C996F2BF954E5FF7A916BE8EDAE6B5D009
-:105F0000569E6FBFDE154E0DDF83AC920D7B740382
-:105F1000DD4B3E883846FDD83793EEE9428D710F50
-:105F200001285EC5AB45883F7D10A6755AA9B0DA39
-:105F3000A972D06AA7869AF594D12FC6677B572895
-:105F400034EEC83A15E0F120C63919EDD727A3AAD7
-:105F5000FBDEDE2ADE2E6CBE7F6F4F65715E4677FC
-:105F6000EFABC63E4FB58F13FA4AEE38357B7D084E
-:105F7000C8DA0193FC656F27C301D3BB1A5B91F6A6
-:105F800073D2F88F6C5B427E0F37303B9AE17955C4
-:105F9000E84288B17976601546BF04A68CCF3B42B3
-:105FA000B3548AC3D7385D1D1E2E27DFF16B967858
-:105FB0000E6780CB89516F2CFADFE48478A6F5EC6C
-:105FC000153FDF271FBA35FE27DC5FEA2F01BDE34F
-:105FD000DADF324CEF5CD6A5CE75A2DFE435FF7870
-:105FE0009A4FDDEE88F36C533F75C0DFFB66FF9C74
-:105FF000667FAAE11F86C31E8A0BDE9EE271C1DBAB
-:1060000053FFBDEB28E6F73AE85DD1EDFB72DB57B5
-:10601000FDC2BE32EAF5EFE5FBD57E19FC25B9ECF1
-:106020001C71FF6D66CA1677288313E97F68A5E6A1
-:10603000447BA7BFC523E1BA3F4BCCB32E1571E219
-:106040007A3AD6BC76DAE86BCC13EF1FE23CDB037E
-:10605000FC3E60BBCAE64B7CCDDFCBCE06EFC8BEB4
-:106060005FCD8C0FA580BF7BA1B8626AA6798F75C2
-:106070004FD180AF03E19330E5707504391D3A428A
-:10608000B9E9B04AC067D46B0F723AB433FB201F32
-:1060900078E480151E66E34968170620D9486F9A90
-:1060A000E9F012EE8348556888879DA97B105EBC95
-:1060B0007781F67C719D7439DEFB8871FBB0A02E70
-:1060C00095DA1124F3248AF7324A0707526FB1F2A6
-:1060D0003DCD7E7AEC49BD7C7F0AFB91D521929F14
-:1060E0006E1C8CECA3C91D68EFACC63F994A9FD0CB
-:1060F000133A07ED0F19B85E6012A7C9E3857D92C8
-:1061000041DE4DE7FBD25177BA5D36BCD9ED4E3753
-:1061100034E5D657E2BC5F67FFA1BE516DF723ECB3
-:1061200076AE3D0EFE0CD4E7E3F2B887F129C7291D
-:1061300082FB3CF81E82B3D6A1E23BCC4CA517E310
-:10614000FD1F7F448614A3675160909ECE1A0BEF0B
-:106150004CFF35F2B8D17E30DF236D0A703F50B06E
-:10616000A94E92F83D020DDFDD0C36ED0D67E253CE
-:10617000833F47F28127483FAE866402E34EF446F0
-:1061800007AD6BDDB5D5C5E6FDD1750149EC430D15
-:10619000FA83269F9AA63F9B5FC43BE3EF47FF929B
-:1061A0004556BC1F2B5D5606B85E1A8BFE9F761CAB
-:1061B000836EA3E5A355D06D23E9BFAE9AFCF44AE4
-:1061C0009A6EF791BCFA6B2192CCD0AE4DD0CB7EBB
-:1061D0006FDF0371C0DFA3708A7854E784539BB7E5
-:1061E000420EBA8C8AB3E2FD3803DC9FB656F285C4
-:1061F00071A8B559FCCB350592D0FF833C9E6FDE6C
-:106200009E109E1FF7CC3910C2738EDE4F329F4313
-:106210009E5B20CE4522AFD33EA0770EF70BE23F28
-:10622000D43B37F13FA15A7F7713BE63B6F64DBF1B
-:10623000C51EEA68C9ED6F50CAAF88A19D71E86DAF
-:1062400049C3F5462A5F7122C235306F29BD3BD262
-:1062500051B793CE617AC2B9E962C4997688B8E839
-:1062600091F1B39C1B1E12F25AAD5F4DF6656FD9CA
-:106270004B34CEDABADCE3E07B59B9EE45791C1039
-:10628000237FB1ED5CF70D31DE1B01713EE18A7EAB
-:10629000697215FE2E874EFEB1F1B5D10107C35BC1
-:1062A0005341ECD500A36BEFBC1BCB100E7C27C673
-:1062B0004CF720F69F01BEF1050E8BDD74A83AFE67
-:1062C0005F2BEBF0F729A6D2BBF546BD9E2C71ECF7
-:1062D000271B74D6BCB4EFE9C0B87F065F4F597E68
-:1062E000F837E87C163CEF998CEDB3C4F91AA97D18
-:1062F000BD1F0BEF763CF4BA06290EAA57CA3C9F85
-:10630000730BB8DCF5AE4CF173B57907E85C2D90F2
-:106310007A9DE227BE3B671F9DAB5516707A601CC5
-:1063200025DA518573F97B80D9E4E85E413F59B5A0
-:10633000D60379D072EEB32520CECB82B9FB33E001
-:1063400004CF203FEF192D97B4FE3CD8F3C01E7A3E
-:1063500037055274AED0F18A13EFA68EE061945CDB
-:1063600025F8EFC2F4E2C6E3741CE7D60EF493F40A
-:106370001AE76C33F9BE49AE4BD1399BA740B3D86D
-:10638000EB81B0F12E627EF30CE05AC4FDC332AE55
-:10639000ABE88F47F8DA675E48FEB46C74FD8E3F59
-:1063A00036BB609CD9AFCFF75DFF6C7C7828A059D5
-:1063B000EC433B3FBAE11BC7B4AFCBE65F3E24E4FE
-:1063C0003388154DFBA46F162899F1FBD64563E180
-:1063D000F79B99F17BB10FE13D747BE6DF2732D269
-:1063E000BB6CFAEE2E231E057F24A48CFAABBA20D8
-:1063F000C3BC8D75F55081F17E4FCC87EB46B53E21
-:10640000DF87E33FD473A90FC77D68536E7A1AE321
-:106410006F11E78B49F1EE88519E147CB9D5A6E740
-:106420005F16727D8F90AF873C511FFD5EC5AE8BAE
-:10643000CF3B89E1AF9AF105BA14B52E28C9357E54
-:10644000956EDB971CE3BD96DE025B7C6F9EF73496
-:106450003F2D5EB622FF9C8E78F877927B67AA88E4
-:10646000E4A9FA1ACE37D5970DA5705F3B79A3231F
-:10647000A9511C4B8CF052768DAC514C9BB8F77ADD
-:10648000A258DFC1798BA312CBF1DEB88A6E17F563
-:106490006B140F73B7F5F73F1EF244DA14B47F1391
-:1064A00014E908D53DD6DFCB9808A6DFAB60E396AC
-:1064B000BDF92EFD7E4A99ED77413E2DDE77FC83B6
-:1064C000F09E94C167D6C79A04D14C7AFF3F055F0E
-:1064D0006AADBBF93B06F100BC633AE760F42B41BF
-:1064E000BB608BBEA11EF1A927203C25831EFB6D3E
-:1064F00081DFF81D9FDDF8CE82AB82DF3F5BBDE41C
-:10650000C2C11D4C656DB9A5C1721FC0A4177E5BC9
-:1065100040EB13D70B49BD89A7879DC427537A2029
-:1065200089BF83B260637CC085A27E0D7F87BA2C51
-:10653000A14B0ACB5733F395750F93AF005E7F31B4
-:106540002423C447F06A687CFAF74E2A07AF1BC0C1
-:106550007DF11EB62FC6DF51317EAFC4E097897141
-:106560002B7F4C4958F3136CFC626F5FADC17938D7
-:106570007E4D8F03705F37AED9541FFB83A1771F09
-:1065800066E34FD98D0F33B2B42F77FF32C45C85E9
-:106590000C9F4FDD1AF8652D9BE0FD3D0DA58897FA
-:1065A000873C40711107A31E7A7701A299CF9346C9
-:1065B000F1AD61F767A99FD697BC9EB1EE75BE2974
-:1065C000F1772E2AD5B7ABD0CFF92AFFDDBAF4BBCD
-:1065D00015A7D3BB15218873FB11A294B60BFE54EB
-:1065E000CFAEA8427F68E22DBF8AF7B3D452AB3F4B
-:1065F0004D2E69A4F7C046ECEE126677B3F244B1B3
-:10660000558FD61772BB355CC8EF85AA7EDE0F7832
-:10661000F432B3DEDF582859CB037AD9974DE50D14
-:10662000A27D42BC5B7E56E1799D68CFA81359FDDF
-:106630000CFCB9408C6B944330BC0FDFFFD8F48D59
-:10664000A639E6F57C63213FDF514F10E35664869F
-:106650002B51C5C7BD4D8CBBB1D0FA6E1CA83C35C3
-:10666000BEDF5170A3B49FE1FB900B1A305E65D57D
-:10667000384712DF4DBB69BC1117965B4F18741871
-:10668000C1B7CAE391CAAF50673933C8B1916E6ED2
-:10669000E47E2AFBF74BC43CDAAF68E8AB61704597
-:1066A0007673B9730721E3391093EF4B0AE7645807
-:1066B000F7DB1B691F77A838F7BA6FDFE7CAC2BFDD
-:1066C00068AFD72AE8A4BD1CA2A7B8DB43DC9F684B
-:1066D000F47FA88CFB15EDEDBA6CFD7BA1298271CE
-:1066E000C678BE8AE7AA4A0D24F1BEA92FD8A756BC
-:1066F00069181FB04FC7FD91060C8FE8670B03D9CF
-:1067000075ED21BE1F95437DF50E8C278146D56C16
-:1067100087958BDF5534F2AE40ACB590ECA1884440
-:106720007891F979FE2157F25CC4E7AA2A07647AC6
-:10673000A7BFA790DBB99BB5A617AA32D06F7DA1E2
-:1067400066B19FCB87B9FD9DAD7EBA1E876F841F52
-:10675000433ADD3F008DF3635341E4F6C24CE7B7A3
-:10676000865E117EC84BE70A850BDA45BF66F3B833
-:1067700072AF8B62D3CF3ABC650FEA5F27D3BFDD20
-:10678000F43B727D7BD00F7919DE7F62F92BDF9CA1
-:10679000AE54B2F257CB9DE2D1F968218EFB01389D
-:1067A000C85FF201BC5438DB44BF270B15BEDE24A2
-:1067B0005CA4470D7FDCE57D2E8B5EFDF6266B7EAF
-:1067C00029348D473FC5D28D2E4832FC5E69D3BB3C
-:1067D000F717F273A26F43BC03D7CFD5E2FCEFDA11
-:1067E0009F4C57506EAE9CAD56394DF7AE9E2DE482
-:1067F000F6DD7B8C8F34939C5D15482AB88F7B67C0
-:10680000FBEC0B3F0FD84FB2A31CFD69C599E30009
-:10681000BF95B0C239D63CEC701BE779D9E090B790
-:106820004919FD42CF154A167FFC2A0F7F0F29B266
-:106830004A06EF9918870774CF4F7FB380DEEFD6F3
-:106840001BE21457A7B7B9D555418AB3A378BA1537
-:106850008C60F8FED001C17F465C1D33284EC37D9D
-:10686000DAB59E4105FDCACBE57823FE749A712EF8
-:10687000E376C5221319FCAE67EA5313C1522F9178
-:1068800067BDBD52755EF51A1D39FAFB50E8C95F48
-:106890003C76BF82EBCF078FBEFD4594C3AB9F759F
-:1068A000025ECDFBF0B10248D1FE21A9A09C5FB5EC
-:1068B000DD99F11D098631EAFFEA1F15905EBCEAF9
-:1068C000097772116B7FD5D3EFCC00264F1FB60D21
-:1068D000ED9988F87B54E2E785FAE00C5C9FAE9274
-:1068E000E19B99DE1DF31671797FFFA7FE66A49FD9
-:1068F000B46DE012EAB7FF2297F95D7C28E2EB0F56
-:10690000ABC7E3261F91925332E80F633FF4FE2397
-:106910003CAEE4AA675C490C09BE6ADB5625C6E0BA
-:1069200058BEED23E297B37FF47821E261F9334E4C
-:106930008B1D71F58F3EE9389DD1F96A270C2D42E8
-:1069400039761EA6FCC18867C84972CDE35396917B
-:106950000A60F59EFCFD39BF66E5EF859C8021AE9F
-:10696000EFEDFB9DF22CE6630166B961FF56BE5E5A
-:10697000BEED1D857EC7C80143159FC7F30FAB9DB4
-:1069800064AF0F30A4A09E5ADEDFF59193F1DBF2E5
-:10699000ED1FBC817CB7DC261FEFE11F65A3EDF383
-:1069A000994536FB7C5B695EF6D1D58F1FBC17FD20
-:1069B00011EF3FF1C77BF11EED35473EBEF77B1867
-:1069C00017F66F5E15E57BF9A3AF148249FF9F5F51
-:1069D000C4D7CD0F1F79F8A1CD6CFE1FBEEE266C7B
-:1069E0007DB8E3F795E8FFF9F0C77F1D8FFEA01B88
-:1069F000762CA4DFADB9E1A9B327E45A17915F93D0
-:106A0000E6DF5714E746DA33121A93003F13A98DD5
-:106A10001ED037A4E0BAF6170986BA8BD9F7FE4F15
-:106A200014B4CFF6446008F1B36BFB3B7B6E66F9A0
-:106A30000F187DDC19E8C3E63FD141FA99890D4B67
-:106A4000976DFFF297CEA8C3D44576F8721822BD91
-:106A5000398AAE2F33BAD6A5E96A2F3F0887153C8D
-:106A60003758FE18A3E30CA427A3E38CD174FC00D1
-:106A7000FF98379A8E571559E3920EC2355B3663ED
-:106A8000E1F6D28CE7BCC63EEBDAA7BE9AD37E32E3
-:106A9000F4C25878BE42E2709D5A14B9B908E5EBC9
-:106AA000891F3CB439C8E9BC8821E6C3C70F560228
-:106AB000E3933FB8862E413C0CED70ABB8BE5FB59A
-:106AC000E357246F1F3EF5A2A2517C0B144AA7B2D4
-:106AD0003C8CFC7B09587E99C433D73EF0FFCE79BD
-:106AE00083B5BF167F3A5525FA517E0F933FA247D3
-:106AF000F282460DF56E721CCD7B5992CBC5B2E485
-:106B0000C05730AECF8EF7278B1C86FE1FA12BC639
-:106B10008D2DDBFEF639C87FD9E869CC5FC5F99FBA
-:106B2000C6CA1FB0CA6D563915F4FD70EB2105EDCC
-:106B300083D4B38AEA60F6F087AE2185D6C71F3BBF
-:106B4000D507C3A3E99EC6BF883F3AC67DF80FEDBF
-:106B5000722EF033969C8F3DAF63C3DBDD451ADFA9
-:106B60005FD9F0F7FEE1CCFAFF39A1379641BCB10D
-:106B70007CF2E8F54B86A83EB12A0DEFFB183FC624
-:106B8000E07DFF5127ED0F3BFA77911EB7EB8B6548
-:106B900059ECE8378AB83DB0EC998119A8D7DEDF07
-:106BA000F953E2CB658FBDADA0FF66CFB62795C187
-:106BB000696939C0F5C1FC3B38EFFF706006EAAF88
-:106BC000E559E2007F2FE6B3FC67D6FE973FF691CA
-:106BD000A5FFABF57E85FC64638CF39E1CB908E7CA
-:106BE000FBDE3E179E60C07BFDCEC64C76CEF362C8
-:106BF0007D34F0D45170EA6B4578EE55C2DF616C9C
-:106C00006F8DFC8A7EBFF74597D8DF465E437B6673
-:106C100055B142F711DA0B2E247FBDD15F9F0D9F36
-:106C20006A50ADC7FD80BA205A67DE5719F0174782
-:106C30001C16F86F28689CA005F8FE4C63FB8FFFBC
-:106C400001AB8A1A34008000000000001F8B08008E
-:106C500000000000000BD57C0B7C54D5B5F73A73CF
-:106C6000CE3CC24C2627AFC9D37892F09480431211
-:106C7000DEB40E0491226A505AA9F5AB03F28821C2
-:106C8000C9A4F8E25ABFCB8444F4029F8D95166ADA
-:106C9000693B70A152217690A0B10DDC012C060554
-:106CA0006F105F78B18D5A152B246314B4575BEFC6
-:106CB0005A6B9FC3CC9C4C84DEFBFBBEDFEF0BBF4B
-:106CC00076BBCFD9679FB5D7FAAFD7DEEB0C28DEFE
-:106CD000DCEA5400D93D6B366461AB5AD41409E048
-:106CE0002BFABB2AD6028400C603585DD5E0776133
-:106CF000AB5A407300FF7D45FFA7785B7BF0F97BC3
-:106D0000E5D4D6B5348FB5F157D4872605B657F2FA
-:106D1000B0914A25DDBFC2BBB61860A3F39F1FA781
-:106D2000FB2B8376D58E6D73EA3DBFA5FE0609AABF
-:106D300065EAD3F3383E6875A8DB55BC9E0E0BC2DE
-:106D400065317AF25424321BA00CE9A016FFFC3006
-:106D500001DF2B488266A8031C012959A120B5C672
-:106D6000730FAAFE62757CAC2FBBBAC18FF35E2D88
-:106D7000BB2CB4FE07732D217B31B537A641D9401A
-:106D80003E18ED03ABAA213262F0FBADD98E855BD4
-:106D900080E90E5A681D9223B49D08F181A67A807D
-:106DA00069030DFF873C74C4D18D037CB40E45BFCD
-:106DB0006FC565D14D3B04B94D213960EB84084066
-:106DC00029D2AD96B05C52A1479F240AD563006ECC
-:106DD0004CF57F93D6993BB451A2EB1EA8E6B612B0
-:106DE000FC12DDB738EBF2FC5FB33E58A09CE9190A
-:106DF000A9CB175FB1C12AF8AF28A00C29273A36D2
-:106E0000ABEF8FC679E87E268D0AB21CC6557D672A
-:106E1000740BC181888FE3F323336764126E8C7126
-:106E2000CD8EA29312F2DB27A7A82945D85790331D
-:106E3000C4A753A9CCA71F4DC399F1FE8F4FA56ED0
-:106E400095511E8F48024F41C213E10A1A1F277C39
-:106E5000B8113F6BE9B9198DBF65BC58A0BAB952DA
-:106E6000E7A487F827FE106F8CA7958A43B57B8926
-:106E7000B73E4DA1796C105A2B11BD7EE6A7035A7F
-:106E8000B91D02616E5DD0CDED5DC4E76C92839754
-:106E9000FB69D0D33A149F9BA356D7AA78FDC7B3FA
-:106EA00033245A9F0B549DBF8579D41F94BF3391CF
-:106EB000BF8E187FEDC44FE7407E3A40653EA47B0D
-:106EC000C1BB761CCF0B115CC723D321243388545C
-:106ED00050112F39FA3A33C127117D841F5A5FF6BA
-:106EE00002B13EF3FB72A195C7E54398DB42E8E6A9
-:106EF00036C3A14A0AD3734A97EF3BF09533468FC6
-:106F0000D1DA09C138FFB9429CBF98B9ED963CB4BB
-:106F10007EE3AF9A71F887CA83BE2A1CA7F85D3E4C
-:106F20003B2EE5FF54CE201082F5720548AEAE9E92
-:106F30008573C18DC3BD36888CA4D9834C5FCA4884
-:106F4000D137EC8B1D051531E8C7E7ACA73E3C45B2
-:106F5000CF59216E1CD121DF9A467C7F982E4C1E82
-:106F6000C8F795A79AB29E8B9B77AB9A9A45EB840C
-:106F70008930F12B39F63C4CCA402333F0F9CF5617
-:106F800005B39EB3C6F8D0E2F867C6A50F019CF220
-:106F90004DEC138EB36238465CB29D0BAEB6ABCDF2
-:106FA000598C43C6E94A64901DDBCF528A42BC7EAD
-:106FB000689C7823DA618BC3274978BD4E75878832
-:106FC0003FF5AEF02CB61326BB317DBE1AC9C77192
-:106FD0007D8DE025BE6EDC73C369E26B9F07347B59
-:106FE000BAC0856F02D909C38E8026A37CD748E337
-:106FF0001C12B6F5ED1FBFF47B1C9FD229838CF7C2
-:10700000FB70CDDDB46EC5974E4274C2FA04FD6EBE
-:107010007608FD31D669D6D77F749D28799E9FE585
-:107020002093FD5DFF2FF47C3FA4B6D2F84D0ABE3D
-:107030009AE6EFB286B6231F561C91196F2BDAA47D
-:1070400010909C152D8DFAF7BE2883C01FF0FD7B94
-:107050007F55CA789461F48FA6E1F381CD562F5AFB
-:107060004C48F725FAABCCD943408BC301047D2FA4
-:10707000E722BF16EBFCDAE87C780BD1B3A949F81C
-:10708000A7ECEA8C84F19FA55C6F5B8AF36B79486F
-:10709000D714C24DE7F035D85F5E20AB329A889C9A
-:1070A00005F989FEB1D5FA0EE99F86FF08DF86FD56
-:1070B0005A4AF68BEC907C3FFBBF7320FC9F02C2C8
-:1070C000FF35A0BD8AE07CCB3689E78DF96A3A1F8F
-:1070D000595380ED1DA1C4EBCB4189F5D9CFBA47F7
-:1070E000921D580943BC766920FE2DE9887F0289EC
-:1070F0000B5C420E2E2FD997FE5764AF5DB082F520
-:1071000095F84E7644EE19B1711ACE17E8B242489E
-:10711000237989FBFD9BE550B038A61FFD5D7B9868
-:107120001FCBF2901F884F7B6E22FF53B444FE3B6F
-:1071300047667CAD3C52BD267ECA7399FFC86FA0DE
-:10714000F9D32695243EAFF37B24FE13FCF6319D44
-:107150004B3B24784C223EAF3F5CA00DE46B43C711
-:107160002336D2FF8BF1D5CCC7D1E9BA1DD1F9783E
-:107170000E3A0FE8A8AC7678D894F03A14B5753A80
-:10718000E1B410F5967062D66B837FD62CD567C3B9
-:107190007197D1385C5FBE232C94D10BCA09C2CB46
-:1071A0002261779B551FFB23C3DE3A2FD8ED77E191
-:1071B0002B6CB3E6553E4438BA534A6D952B07EA1B
-:1071C000EDBA31F7B0FD2A5C8DF698FD6A629C1627
-:1071D0005EE5F02E467A9E5C05DEC5C3009E5AA58C
-:1071E000726B8EDF0C7DDF8CF19B5DF8679E5741E3
-:1071F000FCAE55C9FE7855A2F3611BB09EF69541D1
-:10720000682BBE3F1CF9D4A391BD2E8F5E5F8DF11C
-:1072100045600954539CF1AF1922AE7B466F6765F8
-:10722000D8B85D5B6D011FBEA7B7530E49485FAF6D
-:10723000EA3B7215D99D4EABC6F1951A7DE97B7C70
-:10724000BF425D8BFCCCB3B48EA3F7E2F8D9219C8E
-:10725000B7AFF35DF7ED717EB9B7E3D1511407FD18
-:10726000CC0235E124F1D0F2740BC731BD23DFF13C
-:10727000E0B2A1DE11B501E2E9C19EC66A8AA7EEBD
-:10728000746A4C97AD7D7AA480F1338FE3E3E7967F
-:107290000E61BCED3D0321D2BB59F2ADD78EC1FECC
-:1072A000E45715AF9D95CA77FDC2093C84E5BEE160
-:1072B000CB8A4DC4BF00F273355F6C3D41F27AF664
-:1072C000CF0A90DE55363EFDAE1FD7793817D13044
-:1072D0000960822F5C11C151333BD3A7937E074EC7
-:1072E00001EBEBF86E2501B720D71D2A20BBF286F3
-:1072F000080F27BE61BA0F4199E2FFC93D89D7A7A0
-:107300005E04EFFF62D80D377808EF8FADEA807723
-:10731000C92FEAFE331F17988C9F06BEF738673CCB
-:10732000922EE2769970EB55928F7F2743C4F91B1A
-:10733000BE9425C2655F14BCAB915F7D8BF379DD94
-:107340007D9F524086ED97F2EC709278EBD7E9364C
-:1073500096DFCF6C02F73F5BEA0A35E17A0E2EAD7D
-:10736000BDBC07DF77FE9FFC97AB5F1707A369B132
-:107370004C6279A511DFEF9CD722B11E426B1EF142
-:10738000CD3CDED013436F0C7DC95B3AC41F4AF27B
-:107390009EE1B43EA46FC6D291928D70BB5F029203
-:1073A00063EF6AA4EB6BE2C720AC2E207A021D9F2C
-:1073B000D8C85F3B3A255F28C9F8C3E96EE65FEF9E
-:1073C000EA60D354E4D73D8BF059D20B5B6B71B2BA
-:1073D000F983B0A1008343684BD704EE1D701BE90D
-:1073E0002528AD79E4B77B3BAABE4576FD31D44371
-:1073F0008A1B7E66F532DDC17A80EDC4160A3CB187
-:107400005F783D6C591B974776A74F3F958EF39D4C
-:107410004A5779DE4CBF5722BABD7FFBCC4DF3F7FC
-:107420007D6E67F9E5930EC7C56D9FA60BFEACC9CF
-:10743000F0BDC678A9C96263EAF5BBBD8B2B00AE6F
-:10744000EC407EC7E13226B720AF3BC31F647A32DF
-:10745000BA3171E2FCCBA751BC1CD08D334424500F
-:1074600026C4EC73A5A3305220F287700EF237A326
-:10747000E6C76CAF53D00E53280EDD8979115B64DB
-:107480007C9E749FEC42B32AE2AC967461E75A1E6C
-:107490005142CDF8DECD4A4FCA306C8B7DDA0C45B7
-:1074A000237B5FC6F3E6DE05ACDF164748223BE4EC
-:1074B0002CFD45FA85B86B2AC0EEBFC9CC7FB39CC2
-:1074C00046EB7AB126C3FF05F1756C57F420856F42
-:1074D000DE14C824B9CE925DBCEEC96785FD31DBF0
-:1074E0001B39F2AB9F91BDE9D3F3A724F6E676F200
-:1074F000AF86BD01B9EC10E167EA8B7A9AA9DB1976
-:10750000CC3E980F138FFA9B5D49ECCB24A84E43D9
-:10751000165FD4BE98E588C1FE857E2132A3A20BFA
-:10752000F528EE79B33D2AC8D0FDAF6E8FCEC1B439
-:107530009CABB5185ECA577A0FD9E3F061D8A11891
-:107540005E428C33F37B24705CE8ABA5643F8ECA4B
-:10755000696477A6A3DC71FE2E5D4FD23F0D7D8B53
-:10756000E4BFA1F39A14C2F5535D550E529B15B9B1
-:10757000B2F6678C9F9503F383A0C385EC9DF15E03
-:107580002B3834D748E28785F920ABD88F7B7F7FB3
-:10759000AB349BEC220A2D6DFE98C1EDC18A5C1BB9
-:1075A000BFE7A9AE9234C2910B30BF45F955764A78
-:1075B0001C2798716DC67133BEC0C2796335C7137D
-:1075C000B214D6F71D12F3D2E2E064F65377611ECF
-:1075D0004E716B7F17FA2D6C9F423F4F714AB36B10
-:1075E00016AFDB58AF41DF5DA93372A06CE0FA8DB6
-:1075F00036F0B90CA1CCB8BE12B5118E039FDB12C8
-:10760000AE1BFC1C8C0F063FA7103FA5FF3E3FA7FB
-:107610006608B99AF9FA3F5D7FE18A49906C5FE0AC
-:10762000FF97F54F05FFEF7B44BEF55AAE27664F37
-:107630000A57CC9697211F26503CEE8DD90707FE9E
-:10764000237C8DED68657B3309ED0DC5990575616A
-:10765000B62F137345BE64B61B5776C24D641F2701
-:1076600047302EBD04FBF129FD471EEFE3FC32033A
-:10767000E91EF7FC82E5BBF0D2580D32E7E27BC68B
-:10768000762B5EF27BD09D99745FC0EC378CB8D4BA
-:107690008847CDE38C78D4F0270D3A1FFE3DC3FF19
-:1076A00064065D57D520E91BEA55F8312FC35EA368
-:1076B00078A13BBD7A37DF1F190E721E50022AEDEA
-:1076C000EBA0BE721C56E97045E4B103F5D369D254
-:1076D000C330F285F609822E4B689834900E0CB7B1
-:1076E0008314F7E103FCFEA5BABF28C4312CB4060D
-:1076F000E0F8BF702CF8C9EF1696638BEB3CA6C779
-:10770000232F995AA4FB79E2AB5581A0BDFC1FA79A
-:1077100097482C2827FEF8FE40EB77CCF631FD0584
-:107720002A78298E2F50C29217DF9F51A74917360A
-:10773000910C3F8DF315CCD5D85F160CC53E8DA7A7
-:107740007827895C7A32ACBCCE7A47CF611BF221B4
-:1077500030B771B6DB128BD3ED56BFAF80F68F3AE0
-:1077600044BC0EB4DF379EED9244EB516608FE0434
-:1077700054915FB94065BB59A9CBB1D23197F77726
-:10778000C827DA270F5CB7A4F97870FE7CD0829303
-:107790006376D5C87F701AA0F798ED6ADFBED72F41
-:1077A0000BA23EBEF5BF3F4905BCFF27259A4AFC08
-:1077B000387DFF89541FF2E3ADFB45FEF27D537C1B
-:1077C000A4640AB92ECEACFE82F87ADBAABF4D883B
-:1077D000B72FB0329BF5E28E904CC9F005FD59BE33
-:1077E000C3C97BCF46BF3E9C99D037F4A0DE0E8D37
-:1077F000C9E2EA6999222FBA63D7161BE5D18B3308
-:10780000FDA999D83FADC77FA7DB53793FC0A067DB
-:10781000D1AE7136E2F79F3AED106103D96D157262
-:10782000F65D2F4DA0CD7BF167A6F3F0FE021BEDB8
-:107830009F2F91202AF6B5E0F0CFB1FF5EAE0C6B22
-:10784000BD03D7B1E42DD56641F92C990ED120EABC
-:10785000D5A2BBA435F7E2F8457E17457003D6B92B
-:10786000309898E72FD3E395DB1FB29AF2A4C6C3F2
-:10787000B45FB618E7A17C76496BE2FDFEAE3B0F24
-:10788000FF9CFC40878DFDC0B28BE44FE332F5785E
-:1078900065024CFCAA94E295B21F956983DB25230F
-:1078A0005E39BD0A083CF097550E6ECFAC52B9FD5B
-:1078B00042B7D7CB3B0E1C665C2BDD13C8CF3ED541
-:1078C000F5AEF3162DE637BEB9E593433FC77E0507
-:1078D000ADB398EC65C44A78BC4AF71BCBF438A426
-:1078E000E273B3DF38F087DF539E8DEBDFCE19D71D
-:1078F000A5C523B782F2693C1F0C3F62E6477F575C
-:10790000A99370323F33713FF67FCA97C19EAB9700
-:1079100011D749EC87A14F5F64087C2FDE366F4D8D
-:107920003EBEBF79DF07453DC22EBD069E185ED123
-:10793000D033DE960144D7223EFD9DFF7498F87443
-:1079400098F03689FA97F1FDDC2AC42FEAEDB2CE21
-:107950000FDF84B1AC5FB9965C6A23B9945F9A710A
-:1079600068C69F196FBDD69E22B20F669CF54A89E4
-:10797000E76446BB34539C5F2CD67CB328DF45B705
-:10798000B646E5F508FB775A693DFC43D2DB6D123C
-:10799000E787F5CFB43D4DF6A8F6B73F71933DFAB2
-:1079A0005069F5D0FBEAB63FE0F6915D52826E7AFF
-:1079B000FEC390B04BE6F775EA7C34CE052EF8A5F1
-:1079C00087A26BEE437E9C477D26FD6D68FFEB9A98
-:1079D000FB28CFF039A294779E567A66111D772C3A
-:1079E0007435367929BF4D5C77EDE33FF168BC7F94
-:1079F0001C2CD0F9C7F96AC336AB3782F336BC22E8
-:107A00007BE9350188F2FACCCF07C2EFDAC87EAB4A
-:107A10001688164E1D781FC56823BD09B4AFFB58E4
-:107A200076532BE415203EC79D33D4E876D88CE3FB
-:107A30005D99FABE888E5FE40FEFA706912EDA3FBC
-:107A40008290B0C7CDBFD938F66DA4EFCCB617DDA4
-:107A50005259FCB9C26A96477FF8F65F392C83E326
-:107A6000B757C77B2C6E09F1735A87240E833A45AA
-:107A70005B678DB8296FABDB62F506F1725D9B0C1D
-:107A80000EF25F27ED1C37D4B57DC2F8AC937C5164
-:107A9000691C2FC32DC5C511CBDBDE9B45F676795E
-:107AA0009E0C7351A56AF79C13E37D104DC1F1CB79
-:107AB00077BF3DEB87D447BC3B92C8AB2A7CC0263E
-:107AC000F4C624AFF0DBB3281E6EFECD672C8F0FFB
-:107AD000F74B90533CF0F99A2DEFD9C89F9C41C1C8
-:107AE00064A60B7E91DF0884E585B6B464F28B5CF6
-:107AF000FFBB4ABECFFB7F1793E37A3A6B1BCF786D
-:107B00007FF2774847CD9B76EF5C7AEF9377BA01A7
-:107B100071F081D22870FF8B073CE4876BAC418FFA
-:107B2000CAADB85EF3CBBB198FCB8EDFED11F98DEB
-:107B30002F4FEC1705F3689D4B367F9BD7B914FC8C
-:107B40008CC79A5FC8D5B44F734E81D9BB93E84DAB
-:107B5000659688B7ECF083B1F789F300A0FCFC03CD
-:107B60007DDF34F8B2CC719B1D6E4C9B17B7FF6460
-:107B7000CF12F62A08A13FD2B96A00DD2B9F831CE1
-:107B80003F378BE6B9AB5869A473225C7F50E79707
-:107B9000F415EF0B80A6C4C55955C7AFCEA17D31F2
-:107BA0003BF4DBFE5725C7D51AC53D71CF31DF3E0B
-:107BB000D86A1F225D89AD27F9BEE9ED5986FEC35B
-:107BC000CB1087A7C08E0F184F80FE3B2D57F41F98
-:107BD000237D5CE46A4C43BE7DFACABB363AD70AC1
-:107BE000E27A8611BDDDEF711FBCD91A8D37E60F21
-:107BF00074D863E781A4D7DBDE33E975E27DF4DF77
-:107C0000CCCF00A46994B77D608BCE227F1EC4F7D1
-:107C1000527DC1D20DF684F3C6185E4CE78BBA7E56
-:107C20001AFB9CCB4CF198D19AEDC29559897601FB
-:107C30003667273D5F34E72175D6D0AF893F75277A
-:107C4000ED9CBFD4B509FDC3803A3A0CF5E1A35DC4
-:107C5000875EBB05D7F151D89A3597DF96686F6B71
-:107C60009E42FDC5F132F23B85EDED671C4F19FEDA
-:107C7000E823175E1C93446FF17A52BD7501DBB3A4
-:107C8000FF577676D92076F6BB5903E284347C0D13
-:107C9000FCE589E597537C61E6AF615FCD76F393B0
-:107CA0004C2DA9DD04DDCF1B7CACDD7996717B3ECC
-:107CB0004F9C37356CFB2BFB31646BD48EB86D0851
-:107CC0007DCCFD07C88F71FFC07C696CB27527F24F
-:107CD000D37CFF32922DE723D1EF139F658BDB2BF3
-:107CE000F6E7543ECF6F26BF49765A5381E40833F6
-:107CF000204C7187D4F9FC5FE97DE6BC223803464D
-:107D000036F2B92EAC8BAFCF092B7A3D4530797D59
-:107D10004EB32D769E4BF7073BCF7D5FB7575E97EF
-:107D2000CAE508D62C4D4E5657E2ADB224CD237E7F
-:107D30009225CE774AB3C5BA8F650979B4C8D5FA0A
-:107D400046A3C897680F95ED5FBA9BCF83AD7A7D48
-:107D500006CE9CCBE7074ECB27C812D8BDA17A8EA2
-:107D600042FBC315963B4BB1DFB5E1F6390AE2C7DA
-:107D70003BD5B2A704FB2F6C582CFA575A2AAC08F3
-:107D8000FDC7834BE6CCA47D03CBDB3FA5F529AB38
-:107D900015A0FA91D296F7B87F97559C5F353CBBFA
-:107DA000B786DEDF20A12090FF2DEE7023D731E4CF
-:107DB00082BA9A368FB53D7EBABF260FF3799447C3
-:107DC00024CDFFDB2CF22B8E885B2BA1BCD2B7F12C
-:107DD0007B785F79D94A3921AE53EC838FDE333516
-:107DE00097ECEEFF85F7FF5B56F6E0EF3FF3D4B577
-:107DF0000B68FC68195419E72B57B42AEADB31BF2A
-:107E0000A6BCCD9043B922F85EE6B2713ED792EEA1
-:107E1000CB253C1D239C665F7ADBACD70FC94E8116
-:107E20000339CDD2B81BDB5774F9BFAAF383FE68C0
-:107E30005FA06F5FCE56AE5B816811C95796B7B62B
-:107E4000113FA24D0A6CA5FDD77D8FB7113E5FB7DC
-:107E50003978FFE8E6B4F5D62B90E47247D19D045B
-:107E6000FE37A55D7753BB2FDBDF9325E68DD0BCB6
-:107E7000B77C5F16F3BA1A53C97F820FF54AECD369
-:107E800070FC0E7ED42BA2F920EAD5383205897514
-:107E90004E663AE4B45D4CC7CD7641C78250497313
-:107EA0000FD231CE1EBA8CF22B7C7F94E4700B86FD
-:107EB0005B84E760217491DC5EBFEDCA2D627D8535
-:107EC000ACAFACFF7CFE7EE6499A2F80F3D3396AD3
-:107ED00040EAE1FE1EC5A1065561DF17C6EDBB3DB8
-:107EE0000BAD27CAC4FE7E33E51D53F5BCD8D87F41
-:107EF00033EA0D2676F9AB5C64B0E54E99ECCA39ED
-:107F00008CD7C88E99F7DD269BECEFD48E8FD82EB8
-:107F10005FEC3CD099ADDBE37CC8A77584E93C906D
-:107F2000025EDD4F7AE93C3089FEC79D0766660B2D
-:107F3000397DED79E09DBABDD1A84E0ED7D18F1312
-:107F400093DCFA8F2E82F24AAE476884F4C1FD6A50
-:107F5000BBC9FE1B381FF38A7A3BD9B331AFC06D62
-:107F6000B4DEABF5F393FED3C0F580E37A1C5C1F5F
-:107F700068EDB28642525C3DCA490BD7A3F4833701
-:107F8000C4F52B41BB1A647B3996EB4F5A4EEAE796
-:107F9000BD7A3D438560D93F5C0F61AE7F98E29E1C
-:107FA000242FACE4F31990260DAC7F9822DF2A939E
-:107FB0005D81A3429E17EA20E43299D6752E0240D5
-:107FC00029DA8457E2E48DFF9B981594B9FCE954B3
-:107FD000E2F529265C98E57F6DB61EDFE8F21FB456
-:107FE0008EE443B1AF360EC6721D89D55C47F2866A
-:107FF000850B366375241521D2B7094D62DFF8620F
-:10800000753CE63A1D731D4E9E3F914F0535572432
-:10801000DCBFACB13CA17FF9CA2909E38BD1A1C671
-:10802000F74B1F9A93307E58EB8D09FD119B6E49DB
-:10803000183F2AB428E1FEE81DB549EB5E0C9C8C84
-:1080400009AF48B8BFD1F9E4BB84AF963C59A578D5
-:10805000FECA8EFB4C7531D31817538C7D785DFEAC
-:10806000465D1D9581119FC7A3FC1F2BA6B8E9FE95
-:108070002A491B88036F24C87EFC1FC5C17A931D43
-:1080800030F4FF62FB373FD6FD849C5224519CE3C1
-:10809000C3B82A652AD5118B737B784BD4AB7C96F9
-:1080A000F2778E8B34C9ED856FD25B5589E2A07B68
-:1080B000AB348E83EE1D527480F60F7A7EE0F64A62
-:1080C000F903EB42CD75A0190EDF64E0AD11510745
-:1080D000D982869EEC7F708683E38C872D96DBAAFF
-:1080E000E3E87F225BD89F27B245BEF5735B783704
-:1080F000D901C5016A539E789E8A1F802A7B502E23
-:10810000EE4C10F561F0C6DA9985E43F7B466AE9EA
-:10811000543F8BFD6FE06525C4FEE4966685F3BC95
-:10812000D5CE27D99F942BC29F8C9385DF403FD219
-:1081300041F6F14DE97EAB88B38256924F810382BE
-:10814000EE72F6AF7C4E9C0E59D28A32AA4FBDE039
-:10815000B7B4AF104C876AA75A884FFD8B653E0FA6
-:108160007E8948427AFB6B46719D73FF85FA3F2DED
-:108170008DF2EBFEC58F9EBDBB32A697276DC9F36E
-:10818000BC8BEDBBD56C793495CE514E8E8484FA80
-:108190008C37B3457EF866B62CEA0C42EF79884DF1
-:1081A0007D4BBE184E4407A4EE352E1CF2E0A61FF0
-:1081B00054935C6CEDF382B4AF69ECE35FC8033BAE
-:1081C000A773FDB6912FDDFCBAD8D7BBF98BC47D60
-:1081D000EB8FB2C5B9C047F43E6CCBBBFCE3496E34
-:1081E000379042F0BEB27F3CC507D52A68E4F71746
-:1081F000F817DE7D14FBF3D64B1CEFD37D1A7F23DB
-:10820000CA90EE9F00EFAB7B91BECFB3053DF3A1CB
-:10821000DA4A74BEF6FDFA54C2D3EBE9627C54022A
-:108220006D6BDC7C37E8F3BDFEFDE57B294FA7F7DE
-:10823000D1FB891E7AFF3C154AA8FF1AF8CFBE5A17
-:108240003CF0BD3781CFAAD77B59C94F9642A8EDE4
-:1082500069B2AB472CDEB5C06D2493FD929DFD52F3
-:108260005F53F4C97B90CE3FD5FE75AF847CFDE3B0
-:10827000C2E8AF9FC6EBDFDD248386B8F838C32F92
-:108280007BE2EAB44F2EFE2495F889F1CAF69F925C
-:10829000DEEDB47BA9AEE3CDDA9DC3E3E3FA54CFC0
-:1082A00074073D07932EED3CADEA89C98CBF15DB01
-:1082B00005FE56FC66440EE16C45EA05DC89FEF6D7
-:1082C000523E279D2041D2FC783FE24D1BC17535BF
-:1082D000A021CEF67F2EEACAF71CCDA820FA14F012
-:1082E0005F16BF9E3D2FDD329AEB79DFC8BA243A84
-:1082F000496783687F6F665389F181AE270B3A33F4
-:108300002BF478729487E2B9DFFFE6EC7F105FF61A
-:10831000EDDCFE43D6914BE3C3C03A5A7527DB2709
-:10832000230FA3BA57CAD30E59D84F5E2DDFCF798A
-:1083300018D56970DE35A488C7A3C151ADC2BE8906
-:10834000EF24300E6EF672BD27EBEB4A55C42D4676
-:108350009E245BBCB98AF8C8E0C5A93C7F09D0FE61
-:10836000989B122BC35E611CE1962DBABD029F0340
-:10837000F3D3D1BA3D9BE5F15EDB22CE6B12E24F27
-:10838000EC57ED4A127756E33F8E3B37FB9B53D8B1
-:108390002F6D96CB28EEF03922E4C7CD71E7545803
-:1083A000CFFB0003E2CFE7FE7249F1E7F73CFF3D68
-:1083B000BFB3D4A3B1FD098F14762E1C19C2790E58
-:1083C000FE55907E0DA5BD003A07CD13AD4DEA1DBB
-:1083D000E940FDACF594AF7B681AC265A8E00FF5E3
-:1083E00051A450AA7D72E82B8A03BB15965FFF73D8
-:1083F000577CED772495A887E4EC2387A770BD739D
-:108400005F97D08FB60CEDDFA7529E8171E65624A0
-:108410003145E9B1A52759CFD3647F511FC21E91C1
-:1084200047393AC4B9A843F301D99714551D478970
-:10843000B9317EB147D8DDFAC36F16D9503E672DEA
-:1084400047DD74BE52B7F729372E179A33FD0F90C8
-:10845000FE2C3FF9F20495EBDCB61451FE1D8EBCE8
-:108460003C83E3B3D9C8DA7183AF27B0A9823E4217
-:1084700080864D99DC8EA27D15BC14888875F676B1
-:10848000346724DB1F08FCDB5B0769BD3B8FA570ED
-:10849000DCB233BB9BF520380F603BF2FB89CF4742
-:1084A000F37C0830A6E38A6A4D227FFF0B7D3D3BBB
-:1084B000F5FCB2F77399C719F38EE9982EAB88AB28
-:1084C000B248EB41AEE3EAB46B24DF946D20F8D3FD
-:1084D00099C2756181FDD788BC335D9C47B70D8912
-:1084E000FE91DE13DD67D7A84E35456D850C9CBF28
-:1084F000CD26FCEC2804FE53AED875E37D299D1BE8
-:10850000F92308C405D7E3A528ADF00D573CFF5368
-:1085100099DEFD1E11EFB40D89585CE4273057DA5F
-:10852000CA74C5E8047EAF41E7288E8BDB6CD1F7B7
-:1085300069BF1DE9520917A340D0099D23348A570A
-:10854000525471AE9EA26ADEA03490AEC05808614B
-:1085500070000FAF860B7ACE758443627D07EA42C6
-:108560005B891EC70417AF9B392DAE4F866C52EC4A
-:10857000F9139E65EB5A0A695DC20F2A4A98CFC764
-:10858000DD0B40A5F3EF14C5C77952CA7CD09A50D1
-:108590005E4E878FEF7B708EA6C9DC8F10FD2ADDC3
-:1085A000A77D9B34D53907E94EFB328D9F6BE8B62A
-:1085B00072DD79DDDF6F4A2BC3F59DB11CBC6717F7
-:1085C000B61F2D0C0FA773DA0969FEB7C81E3F73DB
-:1085D0006AD1BA3138FE2F6D56EF5CB24B3DC11FE8
-:1085E000D3B97DED13568DFCE2836FF447BE22F9BB
-:1085F0003E2BB15DECB38AFBD8D79AF07E43E707F8
-:10860000363AD7BAA6E36D1BED7FAFCCF1BF4F7AF8
-:1086100030A9A3A98AF836195A9B699F13ED21D76F
-:108620004B847385BDE87F65F8D6A6383EBB72F4EF
-:108630007DEFA8FF72D29B4E5D3FF7537C84ED5EC9
-:108640003D4EDB7BE0BBA55ADCF969100EF27EE003
-:108650006A788EEB3A8DEB7D216536E168F46B8E9E
-:10866000DB7C7138B3E5087DB7E9EFFB798EFF4B12
-:10867000D6DB03EFD8DCB8FEC09FC345E4AFC21819
-:10868000CF7D5D1D69C0A42F17EA8E4E03DB919D3F
-:10869000AF7570FCBDF33E359DF41EE98734ECEFF9
-:1086A000C5F882F4686FB1D0BBA657CF8FA5FDE2A5
-:1086B000F3FB965F4EFCEAF5580D7CCF18427AB476
-:1086C0001BD88E197A58467A28D1F77B62BFA78CBF
-:1086D000F04D7A67EB9EC37AB7D702A477886FC64E
-:1086E0003BE25BA538A44C45BCF3F323588FDBBABF
-:1086F0005FBE82EBD991BDC3C651DFC2F86A8BCC95
-:108700000949F87CA53572909EAFC4F7376931BD31
-:10871000AC9412EB7A167B449DAC611F7FA0EB6793
-:1087200078A496E6C5F14E594EC07F9C9F147DDD1E
-:108730008FDEBBF127EB36A0BE94FA2A2C1328DE7D
-:108740003926B31FD8AFC7C92BFE30E5865DE23AA4
-:10875000FBCF888E8B837ADCFCDCAA5CEE935FD047
-:10876000502EE3B1F55550BD7763156DC54D9ADDBB
-:108770007A88DA29D5E12A3A2E9CB6A0FB90F8C671
-:10878000CD379AF0D67EF05BA3B94EFAA41DE83B34
-:10879000CEF6FF8CFEF1095CFF3DFB91DF90342E9D
-:1087A00061BCA1C766FC0D86933EA9E7FAA968974C
-:1087B000AFDBF8EB6B1574E80D04045CFF9C8DDBFC
-:1087C000D605D1079EC8F15D9783F8FB22D77F5D60
-:1087D0000EF2ADEFF87F7AC89FEC7DE51D37F9E129
-:1087E000769B6F34E1AABD04F38824789C9263657C
-:1087F000FF5A3948BD49638EC8B78607611DE1A598
-:10880000A15D5643E4A77DDDD793DF781F5949FB6F
-:10881000DA4BA707DD942FD5EC3DC475FA463EBD73
-:1088200004F43FF9D659C4FF73B9223F5EBAC19A26
-:1088300090DF8E80888DCE91037E5763044552630E
-:108840008A3BEEE8D8C2DF8DD46E4B7CAE8EE2144C
-:108850008450DD45F2E3C61C7D9FA4144A294E4195
-:10886000DCF03E49F455D9BB15B8BEAA8BEAAB760D
-:108870005A049F9C0E6849CB88C52B23F27C4BC8B9
-:10888000DE2D31FC875EAF146D93F87B8A513B443B
-:10889000BE3CE5B4B685BF930AFAB84EAF86084031
-:1088A000BAA728415EFF94DC5208E2FA27A1792694
-:1088B0007D59DA2985989FFA772F0AFE13FB459B8D
-:1088C00065FECE6FB30499C5346F94F953ABEF1FB7
-:1088D0002EDF91787E51B7E9F8610A95EAC3A6F3D5
-:1088E000209D3FE6F39DA7E83F929CEFFC24478F35
-:1088F000E78AA028E1BBBCAE4BFB2EEF238A075CC6
-:1089000074F8080971F91E1D470DFABAEB42B25806
-:10891000378A82EAA36FD76112002FF3A91E714232
-:108920003880F542DE463D632D54DBA88EACBEBDDB
-:10893000E9309DBF2DD5E35A339E90A1CCAF657A27
-:10894000DD50CDE6C4FBB53A5F6A4D7C69F04B263D
-:10895000FA44DC7DA9F4A1E5FA0EE1A0769795EB47
-:10896000B9CFC1AD5C7F55DFBE85E959AACB6F2079
-:10897000BD415ECF325C0FE9D3A5D26B96DF3103E8
-:10898000E757C01509F29B9D7949F22B057539AD62
-:10899000AFBF4BE4B5FD5D25BC2F61E0C5FCFC2CF1
-:1089A0003D8EBE66938837CF765439291EE83BAAA0
-:1089B0007825C47DC5B14FDDF4FD4DF93E19E89C25
-:1089C000B4AFB3625D10EDE59EAEA13769E807CAAA
-:1089D0008F29EC372A8E9587528AA95FEE2CE53ACB
-:1089E000132D93F2009C87FD70DFD1A127CA384E6A
-:1089F0009F5949296AD3D17227C50B7B40EC6F4838
-:108A0000C72A337BE2FCCA7B3962BF614DEEBB0FE4
-:108A1000939DBA66B795F783AFB1465FA23C6C4FA2
-:108A200097E26DC27EDDB145AB5348DEBF91BC1409
-:108A3000761FEE5E9145E735F59D56D5CEF4DE7D89
-:108A400090EE077749DE61383EB0EFEAD16DB44F62
-:108A5000B4A5C24BEC35DE579EAE3D4AF5AE90E76D
-:108A6000E4BCFD9ACBACEC5FCFE43BFF752EAEAB24
-:108A7000D6B76516D9E133BFDBC375157D6D12E43A
-:108A80004AB48F7CE849AAF739F3F4711B9D075764
-:108A9000B51FE7BA8DC1FCC1D910E28EF3F6561BA3
-:108AA000E537F55B8C7E0F7F8F52ADC7510DDBDE56
-:108AB000E67E2DE50184C7CD7248C3FF3CB4EF19B3
-:108AC0003E1F6ED825EA3E2EDCDF26F17D03EF8BBC
-:108AD00074BBB51C34C6FB7203EF7A7D9481F773C7
-:108AE0003097EBB496EF7A84F1BD44C7B7B96E0AFC
-:108AF0002DB0AD2C4BE82BEDB799BFFFBB43C7F7AB
-:108B00001D17C1F7A85C1DDFA36014E1FBFC7451C5
-:108B10004F77FEF81027CD7FFE08EFBE7E1DCED921
-:108B2000EF1ED5E382FE88C567BB3236AEB7E313CE
-:108B3000FE0E3170B4DF467527B33A3F6679CCED4F
-:108B40003C3093F87D1DF8EB887FD7753A558A83C2
-:108B5000E7F6087B36A7D3CEE713D741B885E4DC28
-:108B6000B7FFF1960CC2CDAF056E0C3BB74CE7EBEF
-:108B7000B5653F9845F97BADEE0FFBBBEE9CC57626
-:108B8000671C1453BC3747FFCE7B4E58B7439B132B
-:108B9000F94EE7D424B7864E3BD79B5C0B3D36F2AB
-:108BA00067D7EAFED3EC27FBF29C2CE720FAAB61F7
-:108BB00038BE6E97A98E52E9617AFA3B6C7CDED59D
-:108BC00060F2BFD372AD09F51783E1D32CAFDB722E
-:108BD000757FA2CB6B6E54D431CC7945F6D2F94374
-:108BE00057647519C50B06DFCCF2EAD24AD3BEEE44
-:108BF000F7125ED2E37CA37F83FEFD5B586D75C5E3
-:108C0000E7EDCFE75AF473CED04F2B709D7749D064
-:108C10004D38C4FCE6867229697EB33217C73F5FC0
-:108C200078FBFA71F1F98D6FCB708AF71E44BB5255
-:108C300051C9F53BDD7C5EA8B4CEA573B0C02EABA8
-:108C400097F29A4087CCF14060973D64C179AF219B
-:108C50001C215DD59DD2D58423CC1B5A72D13ECD2B
-:108C6000A32D651C37AF03E3117C6EDECC8F197F1B
-:108C700047868A75F72B5A4EB23CC2C81F1A3E1758
-:108C8000F1AA71BD01ED008D6FD0BF4B6B3FF8D7DE
-:108C9000A2E2543AB7FDAC6821C5A9B9227F31E2FE
-:108CA000D528C6AB257ABC4275174B85E860E973B9
-:108CB000F7D9C87E1DA61FB6A0FA49D5BF86F261B6
-:108CC000D50F8D3FA240436A613D6A209D221CEE74
-:108CD00095C4FECDB356AA0D81A69787705D60EF4F
-:108CE0006BE21CCAACEFBD8BBAD95E9C5FE86A240C
-:108CF000BC2D2FDBB206230C18BDFF75B637A37F42
-:108D000067532D6A6C5D4DF4DD1DE7692D09F17225
-:108D10006F47B38DF7A1E3BF1B2E19181FD55F64F2
-:108D20001FEB79935D41FA39DEED3B22ABB42F8422
-:108D30007CFC657E3CBFF478A8FD600AFBAFBEE317
-:108D4000AE10C5FD7FD1F17846DF976F9A24333F8F
-:108D50002C93453B7AFF3325245F92871FEDFDCE90
-:108D6000FDCF5CE1E37DF490A823DE9158875D1F81
-:108D70004EACB336F81AD0F98A740DA7EF950DBA38
-:108D8000F62A3D6E6F123D92A4832C2F8B9498E7A8
-:108D9000069E95ABE3EB48713DB791DD3B69E88BEF
-:108DA00012F5901F7E2B5763DC34750AF95AF68949
-:108DB00016DFFF1DB15F63E5F70FB83F235847F794
-:108DC000CF173BB9BE013E0FCEA5FE3D25E2F7030E
-:108DD000EE79B97644FC3E1D48221F0F58A35CEF84
-:108DE00017386E61FA02C7FB3D435D6417B7CCA428
-:108DF0003ADA6B757B71B8C45943380FD27B736212
-:108E0000F32CC915E71B40EBCD8D7D5F69AC773541
-:108E1000DCC87C58ADE3EA3FF4BC1EF3A8F3B949C3
-:108E2000F2A8C1E2DF0B74EBF1D3F9E9DA89EF21A3
-:108E30000ECA8F2841CAD7F7BC911222FFDFB46F48
-:108E4000D99F281F0EBC69078A43EED9BF6C04D78F
-:108E5000E1FBFD57923D39BFFF8E2BB98E5112DFDA
-:108E6000970689BE5C8AA75EF5509C54BFEF55AE4D
-:108E700073ACDF3BFE518A9F305EBA96AE631CC373
-:108E8000F82B3F56C9F8DB73B432B3940807AF939D
-:108E9000E6AD3FA270DD63FD91CA17E7525C736CCB
-:108EA00006C74F46BC5441F938C54F478626C44FC4
-:108EB000A979827F7D075278FF438212811F189A19
-:108EC000809FBAF63F709C5187F62E1E47C673C529
-:108ED000790ACF332C4FC74F58F2313E768BB6AE5E
-:108EE000630FAF6FB935CCF26EDA6515F7DB446B03
-:108EF000D44907212348FC78912EA11CE6D842854D
-:108F0000946FBE502CF20DB33C9EC813E7852F9C86
-:108F100014DF19BF30DD3F22D9F7C6419821F27026
-:108F200049E777BB7576B2EF7977E489FD09772653
-:108F3000249C4B1AEDA379425FE6D8C43E95F9BE56
-:108F40003FCFF03FB08ECE634ECCB5AAC6EFB7E4AC
-:108F5000A1DDBD1E8C3FEFABF3B3E89C4BE4D50025
-:108F60003D33C91E7E9BF6F929FE9A24FCBAB1CF87
-:108F70003F6F333C20F6F96FB5925D30EA4BE6F96E
-:108F8000CCF157F5D534CF8DE8DF699E9B6627DE9F
-:108F9000FFF645E2AE0579BA1F1F0EC3455EE172CA
-:108FA000923F38D76555655E476868B2EF0B0DFB99
-:108FB000737895383FEA42BB486DD3A8D779DFEA8A
-:108FC0008503279F4C67BB9A0225C8E2ABBEFC9382
-:108FD00027D93C4D17F4757E02FE0C799DA53CA067
-:108FE0006CA0BCEECCB3E8DF259DB1F1F926343E90
-:108FF000649107FF2EA969D4672DA44F67F5EF5E32
-:1090000090BE227B9CDD3F9BF731DFBF6706448328
-:1090100078FFC0283BFBBFFA99129F1FD447843FBB
-:10902000AC9F2FFCE1F0F6792C97EFA05C7C5E36CC
-:1090300013AF515DAE21EFABBEEC9B69E493748E30
-:10904000D34438673B9DC56D7DFBDB2D7C5E897EFF
-:1090500097E2C21B2625CA6D04F81FC8C6FB37CF8E
-:1090600096BCE84106C8FDE65BE7B1DC6FD2BF8F76
-:10907000B998DC7F9BE7FF691EE97D77FF77C62003
-:109080008B5E18F54111F9D7864170BD55E72F0C5D
-:109090008D3E4DE765DE0BE7E97F7F3AFE3CBDC4C0
-:1090A000E3DF924776D5F2A5FB0AA0F97A7EB942B2
-:1090B000223901EBC5607AB5439F7F479E2ADE9334
-:1090C00025CE8746E9FD17ACA142FE9EA2ECD2CE8A
-:1090D000019B9E7D7E2CD9B9DE0347C6DAE2E47A95
-:1090E0006605DA07F237FB0EF1F78731DC5974DCDD
-:1090F00029DC4AD28DBA1F4DC4E119C221D9E7DD5E
-:1091000087AEA7FCF16CFB4D599216E767F79E708E
-:109110000F8B9BF7ACFEBB1898B70DFF766A3C9D92
-:109120000F309D67C3623ED4FFE1378D89BFDF6C8E
-:109130007C67C7787E7064239FD31B785640E0D944
-:10914000F83D8C0BDF55DA80BF7B0CEEB7737D45A5
-:109150009F355A941EA72F1F1A7244981566312BFB
-:10916000B9DE75226CA8E273024CDED74DA6CFEFB4
-:10917000C2B2A80F6DE4BAC5698DE025DC4AB0998A
-:10918000FB13668BF3F229D02D135DDF8428B73EE5
-:1091900050156A67508519B6931C6199C2ADB6F631
-:1091A000834EC257C4A3A4BFEF10A5A7C9E4175BA1
-:1091B000BF02EF1B78C5C1180425FD4E3F2B5FD8B9
-:1091C0007FAF53E863F4ACF8DD936F400FD33F55A6
-:1091D000E9667A53352D83CE4B763FB742A6FA9790
-:1091E000FDA04549CFBC998DBCFF169D0EE1ADE9B0
-:1091F000B1F54EA2F5AAB1FE940560A1F54AB04BB7
-:10920000ACBF1132E87C6C3244F83D5711C1B8DE76
-:10921000E9A029D4B7E517EB7C16F95B959EBF59F9
-:109220001C41AEFB49CD17B8762A2139AF92B7B6AB
-:10923000C38FD0F94CA958E744BCCEE7388D82EEF5
-:109240000BFE3A5FD8BB29106639430DA82FF28F69
-:109250002BCC54895F52C463A1DF13BB54BEF67993
-:1092600080E977DF1EEDFD6165ECDCCBDB99C3F5B2
-:10927000D0EB254B5426BA1C85A21E3A0261FE2E65
-:109280003392F87B67C5F9375E9E4F7ECF2FBEC302
-:1092900035D775EE086DE5BA9B0541640FCD5308CF
-:1092A00070DA13AB03B09684F8BE95CED955AE33C1
-:1092B000ADA07C715FB6FFF2FC6CAE371DC6932982
-:1092C000A1F1D5A931BC2365FCFB3B4E486D257B44
-:1092D000D4ACD7D30655B75ECF54C4EBD0D0CEF3C1
-:1092E0008F4828A2AEFBDE2A517F7AEF90FD5CE723
-:1092F000DB23812A15D0F9FF7EAE03A61F86B316A5
-:109300007CCDF97F96FEBB0F25FE372696EA461EDA
-:109310009F6B3E95CAF5AFCA0C9F4675BCE67AF1C5
-:10932000D296F10FF5705E6AD06BAA1357BC7CFF22
-:109330005EDDBE363BC4EF0049ABEDAA348DBE7F87
-:109340005FC1BF63D54CA141257DF7BE829FA73A7F
-:10935000662A02ED4DF3DF44FC32FF2E15C2ABFF4F
-:10936000059A376D38EFF72593C734431E968175FC
-:109370005228875B49BE46DDAD516F4B80A0753BDF
-:109380007DE277F054C409FFEE1F42C94EB8F4994C
-:109390007FCF43D4FFB6E8FC47BA7670DDA7437CA5
-:1093A000A76D7CCF6BE69B81DFFF02B9D77EA25011
-:1093B00053000000000000001F8B080000000000A8
-:1093C000000B9B22C3C0F0A31E81F9A551F9E8F858
-:1093D000049A3C0B0303C34F205ECC835F1F2E1CFB
-:1093E000CB8260BB883330E88A3230E801F1142048
-:1093F0009E0AC49F81585B8C814107887381EC3C35
-:10940000207607626BA0DA2F1C0C0CDDC20C0CD38B
-:109410008078A130AAB92F1821B41217038329101C
-:10942000333263B77FAA1A03C3011D043F5D9781DE
-:1094300061AB3E797E19C5430F6F7344E51FB5429A
-:10944000E57FB06160B07742F08F5991667E35500C
-:109450006F8D136EF9A36EA8FCBD1EA87C0B34F9AA
-:109460001D61101A00FB3B7C21B8030000000000C6
-:1094700000000000000000001F8B0800000000003A
-:10948000000BED7D7D7C1CC59560F5C7F4F47CAACE
-:10949000471ED9235B323DD2D8964186B62DDB32AA
-:1094A000B6714B06472424194CE20802B9C136AC08
-:1094B000B3E1B809770B0EC1D1E8FBC3B219192F7C
-:1094C000311C81417CC4102E281F9775127219031C
-:1094D000C9CF9BCB651D4238270739A1F8D87C6ED0
-:1094E00074EC19CF5D08DE7AAFAAA5E9D67CD986DF
-:1094F0004DFE38F9472AD5FDAAEABD57AF5EBDF744
-:10950000EA758D22BA48EC2242CEC2DF6642DE7294
-:109510001142D6CC96A976234B5A68F934317AE9B0
-:10952000A34BB46CBB40CB15FE4951D009B92C9C60
-:109530002644242436F1301129DC509D4246A28471
-:1095400078F46D55C43FDBAFB3ECED2224BBACF82F
-:109550007BE9F9E1881EA0FD3DB5B6D3A4FD0C7DE5
-:10956000A5B5D36C9E7D5F0B8352FC1A08C5A686F9
-:1095700090FEFAFB89182664908EBD8CFEA7DE93C0
-:109580002071DA4EC90E137D05C085105EFDFA0903
-:10959000F166FA7CD0453A2768A91E4D657D14EF27
-:1095A0004B9FD35649941E8F6C8ABFA5754F44CCF0
-:1095B000A4808EC841ECF734A50B867AAFE8590D2C
-:1095C000F4503A365648CFC662F43C974A013D976C
-:1095D0001DD557E6D3A3D6317AD4BA1E9CA7D31192
-:1095E0004A4FF442E8F90CD233C8E91974D0F34178
-:1095F0004ECF768B9EDA01A467A09ED2431FB9EFAF
-:109600004991388557819E00C0D9E919007A9A0B93
-:10961000D0A3FE79E8F92B2E6F49A0674D797A9295
-:10962000404F4D05F4F8D344A3CF3D4430279AE78B
-:10963000E2E5E17C5CF1F5742445FB1DFE9384F3C7
-:109640004C576464DB8A59B8498ED7F7A203914915
-:1096500090AF25F74708ED6FB85E407867BF0F10F1
-:1096600005E1B53AB31BFABFF888BDFFE17A86AFD2
-:1096700005FF7B3E8FBF2712B65BE08F0F437D78DF
-:10968000C9374802C671A5231AB48BB276FD4BD6F2
-:10969000764EFA0BB567F40CEF4DA13CABD9CF2059
-:1096A000BFFEA63E4D745AF71C4910E0BF1261F888
-:1096B00058ED295E845C0E64DF699A0C3F4216D235
-:1096C000794ADD994DD1F162E9DBD538E5C7706D96
-:1096D0008F0A740FE9073B416F9D8E29448A025E11
-:1096E00085F960C9C56632AA36D0F9EC7D59324693
-:1096F000C85CB8140857CD6C5DF68B24DB44F0EFE2
-:109700002C017A1238FFFD4BEE47BA15A06B05D03D
-:1097100095243A7DFE2D2E3FEEAFA708C895AAA747
-:1097200022A91573C71902FE3743AFE9C8B63CFA40
-:109730007F6ECD2F9D57C7FC225F1E206636057CAD
-:10974000F1D8E7CD2AFF9EF3FDB2BA14F2B7DCF8E8
-:1097500073E967E3FF1DD1B11FA2A623F1C02C3E20
-:10976000C3AEC91E906BBA268D2728C8A5749CB6B7
-:109770003C7E3BC79BA1534EDBE4F81B9C4FC39E32
-:10978000E9E7F3FB73E2F35D0EF75DA26169D17562
-:10979000E951364EB9FE7F022CAE0178C7BA92531A
-:1097A00036BEDFCDE12F7BCE0E578C3F9F9DE14F24
-:1097B0002A02F268AD47F833E713C24506FFFC6B97
-:1097C00009590EFF8736F9C3CD9377C2D27A259C0B
-:1097D000380DED6F23898BBC8D74BDB8125F847218
-:1097E000AB6CBE85FD12BFF6C6255CEE24D4036CBF
-:1097F0003CDA3DA1FD07787FB2D041089567772B11
-:10980000C98C50D4AE925ECD0A949F070931166878
-:1098100079FBFA14DBD7D76B992DB09F6F90292174
-:1098200074BC2AA279A004F82C850BAEF11B742419
-:10983000E2261FAF8A17901B4F0B4979AAE8F8ADB3
-:109840008A6D5D78CC0401BD108890AC2748F58DF9
-:10985000100823FEEBC83A86BF2E407FD5B2DE2D1E
-:10986000D371A498688CD3A7551BC9FA1D7972A827
-:109870000B4C7EBB63A208740D50FDEFA64B325813
-:109880004FD73BAC8708B5370AC8ED8C7ECF49244B
-:109890003B8FF69B13487635ADFBC9FA046D97767E
-:1098A00093F5A7705C628C1790B3ED029B5721363D
-:1098B0007DF62CDA0524F33EB40BD2B88E9558DA37
-:1098C000847D403583861BA6FDED7B995E938909D7
-:1098D00072128AA5B355F05E5F1A057C17C492E434
-:1098E000F566564EE5E1ABFA5311B49FA24B859E47
-:1098F000BC7DEC18959FA93C791BDACBEC80FEE887
-:1099000000D7339F44FD69BDFF04E79332499101BD
-:10991000BA7425D320CC95EB21A1B09ED8C9E98596
-:10992000BF2BD7DAE5559ECFE5950EE19609CAD74C
-:10993000E0532403F8524E3E7F33AD5FF2A24A4615
-:10994000A87C35931322C8CFA5641A4B8368129460
-:10995000AB8881650B8963F987362AF7B4BCCDA43F
-:10996000F2DE80F2FF51818EFFFBFAC4B2207DEE61
-:1099700089A52E87FD85CAFF76784EE5440079AA31
-:109980003649C1FD3224B0F53A266B1E801B3309DF
-:10999000EAC743426F0AF689216E270D79886D1D4B
-:1099A0001FE0740FF132144B9049985F3A2FA0D703
-:1099B0008F456FC575EC96597D80CE0BCADD26B6F6
-:1099C0008F39F150615E569CFF3C6CFFF3CFC38032
-:1099D0005053701E06611EB60B4C7F2ABF62E39780
-:1099E000A00FF7E99DDD8F22FF9553E7066FD1BFEA
-:1099F000D6A137D7713DB7814C2F96A91EB9DD9DF1
-:109A0000556401F1FE02E0FDD6CF4E7C02E82193C1
-:109A10008965B04F51BC1F16504F26C9093ABEFC8C
-:109A2000B294013F45F45DA3264AF82944A3FA4CB9
-:109A3000E5FAAC01FEB74E7BC33757FF2E9DF8AB5E
-:109A400093686F10353102FA69535205B9E8ADDBFE
-:109A5000A6821C0DD6D13AC84D445185CB68E92762
-:109A60001D207F96FD3110D931140D83DD63AC8547
-:109A70006EADF1B7441244C0E78979EEA8FDF92F25
-:109A800061FD6B898844E95332EF5381CE7E6D9B33
-:109A90009AEF7729FE4444A1723808E3C1F8AEE496
-:109AA000F1680BE84FB2BA07F4B99624AB41BE2374
-:109AB000ED88E796BAB80AEFDD9155C4AD038BE3A4
-:109AC00068570D84EDFEDC60DD1DE456844F92374F
-:109AD000FC73ED6BB73F4994BC7D02C691F2E6D9A9
-:109AE0002D27B340971429AC77FF07977F518FE359
-:109AF0007E43D29F37552AF72E2E03AE08F9997070
-:109B000069DE3C85F3F61D3A4F031EA3B3D0BAA419
-:109B10003B88BD5F4320EADACAFB9DDD6FF9BCA735
-:109B2000D70D4DE2BC07D230EFBD54EFE3BEFA6A69
-:109B300020F30425A17B53F21178EF4AC9A4278CA6
-:109B4000DD34C13E779774B101F27700F846378E65
-:109B5000D12E15CB912E0DCBA1AE08969FF77DEEA1
-:109B60008B93B4DD9E945B73831CA4EF7A16FAA3E7
-:109B70005E777C04FA0DD3FEA15F59D59ED0A0CEAE
-:109B8000F61D578C95378A8C8F55A217F16D119958
-:109B90001DAE1313E525AD95F6D3AB5AED766EC029
-:109BA000F0CEAE07FA9FAFA9DA56F7E80B6DF0CE0C
-:109BB000F5F26391E90D971C2746339485F5F85922
-:109BC000414238495A390DF687BC4041BBA05FB0CD
-:109BD000EBED8745B6DF3D26AA4867844CBF7096FB
-:109BE000F2C3A58968F704430D1359E04F8D622C29
-:109BF000A145D035A95517188F84E5DF4DE6ADF3A3
-:109C0000A7043326FE05F0690EFDDDED36B9DE272B
-:109C1000B2FDEE2C5F2F92DBEC043D13A1624850A5
-:109C20003EF447810FA26FA3D144F9D01F5274F0C4
-:109C300087FABAC582FB8E930F52D58D11D08F4E05
-:109C4000BE7F97CBD1339CEF9BDFFE30EA89FD9A34
-:109C5000D891F103DF4E74809EEF6B114590F3BFF6
-:109C600018FE39E8D833C3BF193A906F7D61663763
-:109C70008F6A547E603D8799FCE824DB81EF0D4AB2
-:109C80009730972E27FFDE6BFA2CBE5785C478A637
-:109C900019F09B8E237E1BE582F8FD6BF1DDC2CBB4
-:109CA0003F835796E165FC65E0F594901887F57D54
-:109CB00080CBEB01795205BD10B3E4C6C7D6D15CA9
-:109CC000BD24D8E49DF6F325E8E75EE887C2DF2BE4
-:109CD0004FDBFAB1E002C007B62EE26C5DC87FD65A
-:109CE0007561E135C2F1D64986C9755361B97EAF58
-:109CF000F1B2F6D31EDF1504F44DC81F47FB7B817C
-:109D00003F9E057EF5D6283AD83FD451C2FD1A9B16
-:109D1000EA797E52CDF608C0F707B6A35DDEEF8A7A
-:109D2000A39D7EBCE61BE6CD94AEDEB7AB88DBA080
-:109D3000FE80EF8AE33AE8C5E312FA6BBD6F372E77
-:109D4000481698671FC4C728FE5EC00FED6A65C637
-:109D500008077C7BFD54F1D17EDE6C2619D0A72E3E
-:109D6000BF1901BBBB77856AF420549C007F7B7CC4
-:109D70009F684D34CF6DEFF30F7C5ABA74761CFA9E
-:109D8000279C05DB97EEE1E0C7237D82ED7D413C1A
-:109D9000CAD55DB3750DFBA7755D85AE05F36CE3A4
-:109DA0002CDF292D4D32EC9BC46BC0FCC7E21D3D5E
-:109DB0007F043EFDBD847AD0C99FBF93125E69CDFA
-:109DC0006CDD154EE0BC59FD5D5D23A31E95EB488F
-:109DD000C62DC0A8F10EB06F7BEB448CAFC9FE6DF1
-:109DE0005525EDEEBACAEC6EC2E31E963CB4FD8A70
-:109DF0008DEB3598FE0E90490271952AC2E21A2128
-:109E0000A20B04DB1B421C83251B319E12F6BCDB1C
-:109E1000FDDE88FD0AE61839EB3B877E65DA6FE3E5
-:109E20007BD06F197C3DE421EC97AA87F0D979B3F8
-:109E3000FDBA22497C48DE3E7B565A4B5813FC4BF8
-:109E4000A07CCBA281EB932C0C1A4FD0A23F7C8735
-:109E5000CD9FFA88D4608B9B2ADAC0A785202DEB92
-:109E60006E3327F3F483737E3B6120F02FEB7699FA
-:109E70009315E80D30BB0BC5A5069444A61BF6EF61
-:109E8000C57E8C2312398971E141A17A15D8CF168C
-:109E90009C5CA76401AF408B99027D31384F34241C
-:109EA00003FA1D3D01FE0091AE311225E24B729D79
-:109EB000FC9B7C7AFEAD1408239E3CCED55B46DE2F
-:109EC00007BA4A9F4F288A9128E4CFA42466BF2866
-:109ED000DEC2EFAF54DAF74A6BE6F22D0DBCA3CF2A
-:109EE0000743D4E5BE8C890FC8815CF7FD93C0871A
-:109EF00081DAAD9152F4128DDA39797E91A19823ED
-:109F000052693C0E14C283F8A9F0AC2F310E9F5F4A
-:109F1000ED4A83C53B4029C2791CB7CF28DE416199
-:109F20003ED3D3F0B7BF653C0B7134D7CD7E13E67B
-:109F30004F328F1089C2FFA85622422BD4BDAF8B5F
-:109F4000389F1B0DD4574DCCBF33E93FA023B851E8
-:109F5000B1ED5BA03F67F6AD28C8BFBDFEB4648F0E
-:109F600067F6761D25BF5C328B3F7D64168A17CB62
-:109F70004AFB44617E5457C48F43545E08959783CF
-:109F8000D46FA44C2169EA3742FD00F51B09FA930E
-:109F90003A967D5D4D58EE83A6EBE1FC2C39148D8D
-:109FA00042BCF4F1C82D14E410E80E3C57F1B6435E
-:109FB000FC7CC4AAD32702D4F939CB0F7BFFD80687
-:109FC000F198110FAB1332DD66DAEA520FC4FB478A
-:109FD00002ACFD2F257F3B9C471CE2E7484436D569
-:109FE0008FE6F9FF39C98574800DC4DAFFBE1BFA0C
-:109FF000F3C8BC9EAA477C66EA948F808F4765F5BC
-:10A00000BABEC5D83FAA003A5EACEF2236DE126671
-:10A01000DF93E66D65F8D883F27F3D1CC201CDCD9C
-:10A02000D570A84C14C320B0DD1C0A71BC2BEC8782
-:10A03000C809B6DFF1B852F17553665FE378949BB7
-:10A040007F027E29C42FA81E4EC1B83F2DBC4FBF32
-:10A05000DBE31E729D1B5F94D6E9944C59FCB7520A
-:10A060004293693D604E64A3B41EBC269BC2E55B6F
-:10A07000E1B8BF93341E0F4DE0FAB7F82C6BCCEE6D
-:10A08000B8D2318FAEB089E7921E3F5B7F95E2BBBD
-:10A090001EC6C9EB873CD35E1B0F146F571317679F
-:10A0A000ED2DFADFBC0EEFACBD46FF0B99D5B67AAD
-:10A0B00055EB421B7CC068B0BD776917DBDE9FEFB4
-:10A0C0003C5DEAA0A3D1E21FAF479C74562C77B247
-:10A0D000CEF7B914B31F67EA7C3F2E577F7B99BD3B
-:10A0E000CEFA75931BAA987DC3EC987F43388C13E6
-:10A0F0000F234FFF4A00C7EABA2810CBBECD36CD9A
-:10A10000EDBF57FD1CC6E1CC5E9978AE981BA74BFE
-:10A11000B52731CE96EA716BBD618CBB619C6D0F2A
-:10A1200035E4DDB4BCCD95D80DF27BC6B33843829F
-:10A13000D06F721DC4AD7B1DF104A73CC51EBABE15
-:10A14000E07999550E75B1F89F5557EB0AE701DC98
-:10A150002DB3F3FAEFBB1277031EA01B09C66909E2
-:10A16000AE0397CEF6C763D1ADE4D7E8FFB3F331C2
-:10A1700085A44E36527AD2D45F1BD1816EB64E86FC
-:10A18000A25BD5187D3E1612B94D378DF653BA6DC8
-:10A190007E2DACA72A791ACFEDAA6285F1B95716A0
-:10A1A000F9BCDD54923EE77CDC048156DA6EAC5E8D
-:10A1B0001091FFF562E6098847D589B8AEF79BCACA
-:10A1C000A370D4BEBFA5FA7A8CA79B8A28211D59FB
-:10A1D000B5D03AECE776532F8F9F1EA8637EEBB184
-:10A1E000B6375438AF3960B4633E809CFE11B61F59
-:10A1F000E4FC4EAF9CC238F96091F3971E99F9F9CF
-:10A20000BD016F67A6E0FB20BE4F47DB9E7F00E8E5
-:10A21000A0FAF709F4CF48ED2E4A87666AAB80DFD3
-:10A2200063F5A6F86B90AB4D22CA5910E272129CEE
-:10A230008BDAFDE7B14D229EB3A635BF01F6FB696F
-:10A24000F34D821B91ACD5C2F962D5AB1B34DC2B2C
-:10A25000A9BD539B67E7576D4CAE83F9B2E8729383
-:10A260006B0BCE87B0784F02F879D72AA2833FE6EE
-:10A270005EDC91FD02EDF7CC7AB706AAE0CAC09584
-:10A28000D9EF803CD16D05FC6477D8CC82DDE4E960
-:10A29000F4119DBE0F4626D08E52231231C1AEFA64
-:10A2A000BF12CE17D51948977C68FD89CDB4BDB2D1
-:10A2B000495C80765933DB6F34FA0FF61B3566B78D
-:10A2C000AB245716FBBB77F2513C57561C76954C86
-:10A2D000F2E0C1EEDAB4EDC38D05F481554A934145
-:10A2E0003CD725D28D25ED6CFFAB9FFC8717F3F88B
-:10A2F0003E253BEC746EBF59FD14B3DFCE74EDFE0A
-:10A300008717A92C275C2C0E2A2BE66F605D4EF177
-:10A31000F3C53147DE4DC2C5D6CB19BE8E6166C1CD
-:10A32000DF06FF18F8D577D576E66711C3E6C7D004
-:10A33000F57E46CEF3B3ADFD2E6D96F62766F35A45
-:10A34000FC9E5889BC966BE584EC2A91D762ADD708
-:10A35000E14D2689D0F91D0D914C0FCCEF6693ECA1
-:10A3600004791588D1A331F869EB1C250A72781598
-:10A37000D905EB57970D3887EC6FFC1075148BE3FC
-:10A380002B87EDF2516E1EF738E67191CB6E87BBCD
-:10A3900048BC2A1B853846E47AC0637F5831603D4B
-:10A3A000BAC41B77EFD0E7CE2359C7F4862B9C2580
-:10A3B00085C6B5F879BBCB5CE68238BB629C4C8025
-:10A3C000FCB72BE8F73AE16F72F13C962891C13E59
-:10A3D0004BC13A81F5DB61B2BC31414B3E6820FA9A
-:10A3E00071DBB956EC2DCC677B4822C9791B09B9C2
-:10A3F000CE15657AA66D3BB37B3E40042904F00977
-:10A40000DCBF6A4D4DA07D9361CB2ED36E8E5C9BDD
-:10A41000A727AFE3F239FB3E11F9A8EDBD8BE11997
-:10A42000E076B3B63372ED8A02ED4385F5E407B802
-:10A430005C5FE7E2F6446A27E605F5EB37C681CFB5
-:10A440007D9B4D6317682D9011C847F1139B7D4C80
-:10A45000E5FB3AE0A7153F92B53896963D506CFE65
-:10A460009D76802B62CF3BA9F4DC3676E8FA92E346
-:10A4700038F7672BBF0D345F3E9F5C9C0FCD7CBDD2
-:10A48000CCDA4B69BEDE0DCC079214330171494919
-:10A4900020367B6B8CCB8BE465EF9D7850FFF94EBB
-:10A4A00058A752D044FF9AF85B98DD261BFAB505F1
-:10A4B000F0B7CE391FE379BCB1F48770FF1B0DB53F
-:10A4C000E3BED7A795D61FD6BEBA995CA342DCAE31
-:10A4D000BFB8FE18CDD71F4A58B4AF63EEDF53FAAA
-:10A4E000F5427CB6F814E1F1D2DEC0F648C9B8A056
-:10A4F000E37CC550CC07902FC5F9F685F3E1DB2846
-:10A50000CFABDBDBFFD2F33C0FC1AEAF5716D5D7D5
-:10A51000FFC9A64FB9BE7E0FF9FFDCBBC1FF4AE3FE
-:10A52000309E3D927E6A1E55F1720AE919D60FA639
-:10A53000301E03EB1BEC80741BE62B901841BD080A
-:10A540000D41DF797413F9E6E57126A5CEBECF483B
-:10A5500061AFAD1EE94C11C857837E816ECF1E05D9
-:10A56000C7B5F84D6D16CC27B3EC4B584EE08F14A1
-:10A57000CB4FB34A2B7E03C73867719FFAEC71E06B
-:10A58000EF693FC1FDA138FDF671221F8997D64FB3
-:10A590000E78E297F5370A9C0BCE6D279337F2F4CD
-:10A5A000DAFF71E813F3C8CD9DA847896840FCB273
-:10A5B00037B29D2428DE0384E9932128D7433EC97E
-:10A5C0002A0DFCDFEFBB74D65E67FE9DA8F238BD96
-:10A5D0005E99BF7717DD870AD93F4B15661F9FF934
-:10A5E0005CF20F9097901A1174D8DF4E75E5D07E0B
-:10A5F000DA915DAE405EDA72653EC2ED381455B652
-:10A60000E4ADCF1D849DFB5344947C3D6AAD3F2552
-:10A61000ED7E1EE89C4AB3B8C654FA9FF15C7FEA0F
-:10A62000B09401A64E0D5D5772FD9CE27ADB823B31
-:10A63000755832A1BFD490905942DB9F92CD60C132
-:10A640003C009261E7C1BC7E4B5AB2C9E599BD0995
-:10A6500005F4CCA92E55F8259D9B5B814E8AFF8E73
-:10A660007454019FAC1C5DF314FB7C5A74F643BE1A
-:10A670004274367FA73FFC26D27B9A3E974AC4930A
-:10A6800046B89EE80F17D6275E7EFEEA75650AE794
-:10A690003D38E8F535D9D7A585DF20CFA718D418E0
-:10A6A0005E831111E761B0AEB41EEBE3F360C1F558
-:10A6B00047D8796BBF1C572BC1C7A5D9F129368E56
-:10A6C000BA71A203B6F92A92E8688F227B5F8238BA
-:10A6D00002860E75F09F9E3A762BC4816FF69B42E0
-:10A6E000041E4E67BF43EB0BA8BF03F6A966668442
-:10A6F000C52D90D72911881B3F947C33FB1AF8A3F2
-:10A70000D4FF817A484F86DE077A289610605DED87
-:10A7100007E58F9D7FB0B7AD99AF3F5AFFD440FB9F
-:10A72000168843CA24CEE319A20EF97AB8F4C5E21A
-:10A730007A02B4E759F76CBBA2743AFC2237D956B7
-:10A74000DAFFDECDE053F41FE89D050E3F2BD46900
-:10A75000B7BBAB1CEFC7B8BC16F32BDFAD71E693EC
-:10A7600097543897555B442D03F0241982FD3678B1
-:10A77000A34CC08E9FAF6BDD10E22BC7F77D84E545
-:10A78000B9C11711F9EBEF4985D9B18B6E7F5C80A8
-:10A79000FDE93478D92BA19E330AC9AFD3EE1BD281
-:10A7A000A7309E38404E7434823DBF4BC4F3A4FDA5
-:10A7B0002D0743F9EDBFC7C7999D7FA2CB6BF1541D
-:10A7C00016FD79A5453461DF3ADFF977FAC9E5E688
-:10A7D000BF76B7DD2E3ED779F93120BEA6FCFC5FEF
-:10A7E000E838D6BCCD5D1F4C6F2EBAFD458CE38C8E
-:10A7F0001AA5F5CDDC797B09E72DD842CC42719CB6
-:10A8000057F83EE6CCEB53499218909FF832DB7F25
-:10A81000A4C6B591F112FA478A39FC0FDE4FEE1645
-:10A82000424EC07E2BEB65BE879B3824D37DD3B7C9
-:10A8300067C3217935E4679998E735DC65E2F399D8
-:10A84000F9778B1C5F81886BB95ED1F1FCF3908C3A
-:10A85000F68648CE421C846844B7E48E005CC7216B
-:10A8600019E3313ACF23A0A0F3A11D41BDB4129248
-:10A870003D6BF09C1EFB818E581CA693D569439CB2
-:10A88000279769225E725ABD83F2739F87D7755EE0
-:10A890000FF1BAC6EB515E2707B1EE53681DE2F225
-:10A8A000AEB486752FAF4779BD9AD743BCDEC0EBF7
-:10A8B000C241ACEF53587F237286F5EFE5759DD703
-:10A8C000AB795DE3F5065E27E36C7C37ABC37E882E
-:10A8D000751FAF47797D1EAF8778BD91D78571AC65
-:10A8E000179B3F6FCC44FECECE7F07E31B21DCDFFE
-:10A8F0008C3BEA9DB3F079FE687F972EE49F1FBAE8
-:10A900008AC49F56B9999E996E8B639E12F5175211
-:10A9100053F9E78E91C2F26EF27633E7E6610A5799
-:10A92000307EDD5D705D548ADFD6F3C4EF23FF4ACD
-:10A93000F8DDE0B6D63DF3CFA7DB0CC4D3D99FB387
-:10A940001DD85B24EF9CDE2B675210AFA13612FAA4
-:10A950003B2ED59ECF7A979B9D7376BB593E6B2F2E
-:10A96000C76FBA8D9D3FF42FF166C685B971C6BF1A
-:10A9700071B378C20F2C3CD509F47B7C39BA62D113
-:10A980000F627ED470ACBD4CFEBAFCFFF2FD656771
-:10A990001CE49FE11D1DC7EB2FCCA7BB66F4CD8D3A
-:10A9A000A9290AAB7AE873F067B470A42E3F6F9AB6
-:10A9B000BF278228A17E799BC259F92212F6CFE2E5
-:10A9C000C5752C5E2C71781C27CABE633057C13EFA
-:10A9D000439F37F17184B9FD3ADB65DDD56CBE3834
-:10A9E0003E567E8A449EC37E66F091E3C82FE7738D
-:10A9F000C843D6FC17FEFC42EB2EBDC8786976FE34
-:10AA000052AEFD17B9BCCC91CF22F3FA1FDD969D53
-:10AA10003261423E902547967C9DAF1C5DB09CC044
-:10AA200086D4525C4E522489EB46069773E5B9CB27
-:10AA30004B0139C9E6C3D7A8217E9E6FA0BC507CCC
-:10AA400064945B8DE153B32A8CFD09B0C697410F26
-:10AA5000BC0E7CA0F45EA286381F589CC20BE78C0B
-:10AA600079ED297188AF20095CEF33B8CD2A5BE717
-:10AA70009BDAEB18FE84F7EFC097F6A7E6F727916D
-:10AA80003A879C33BC3FA6B2F9A5F0F89DDF9CF154
-:10AA90006501F195483C25D2769FE2F04EFD659523
-:10AAA0007B397EC322D9CDBE938C93FCEF2A7DAA3D
-:10AAB000C8BF7B64EBCCA99F5C2057ABCF5FAE2AAD
-:10AAC000D5EB356AE17D87EAF92688F715DB774E05
-:10AAD000AA33FB41139FB7739AF7DF811E5A333BAA
-:10AAE0009F95E27B091FF75CF13D3517DF8AE4ECA7
-:10AAF0004DAE272AC56FF379E2F79203BF774BAECD
-:10AB0000DFE6FB51A5F87FEC3CE5E18773F95BD10B
-:10AB10003A12D573E3EFA7CE13BF5F38F12BB26EB5
-:10AB20001595F12B45987CC8FCFCA552FCBACAE3EC
-:10AB3000C7F3C5B6F69931B4D7D01FDFAF6EED4B72
-:10AB4000C9B3F89984E9F5731DFFDE8AC7FF509FEA
-:10AB500029CF8EFF05F543B6F165D94061AB74DCB2
-:10AB6000872B1D37F5511BDDCF0C7DD436EEF9F266
-:10AB7000FDCB158F7F938DEEE7866EB2D3ED373028
-:10AB80009FB8D271BF739EEBFD371C5F9FAAD9F6A9
-:10AB90008162F6FBDBDCAEBD45D56C725C0CFE4D14
-:10ABA0006EAF7CB042F853BCFF460B9F32F09FE182
-:10ABB000F87FA642F8DF717CD65788CF0FF83A2C81
-:10ABC000B67F7A39DF7DA023F3FC9A0BCD5BDAE503
-:10ABD0004E081E38E7FC7A177E27F8A6AC6A10EFFD
-:10ABE000241D04ED71CFAB8171965792E2FE7F2256
-:10ABF00025303D8CF12D57D8B09DC7597E972CC775
-:10AC0000CD42E76D210FD37F826674B2F5AE10C8D6
-:10AC1000432A06EFF3148EBF549169CC3F21117E75
-:10AC20008EF4F6757AC17302398E792D92A69071E1
-:10AC30003A4E5F68BB9E9FB71CB3F08998888FA27D
-:10AC4000317C14D9300BE529D77BD8BC5AFD58FE8E
-:10AC5000A1109926EC1E07865FBF27DE0979E2A9BD
-:10AC600090827CEA0BD8CFC7AFE7FDBC9FD3D7E774
-:10AC70002A9D27D63EBF15F3957A5B59BE924E0C9E
-:10AC8000CCEFECF397BED760B48BC5FF4778FED30B
-:10AC9000107C3F0ADF13C3F7A3CBA0FD57F13BBCE9
-:10ACA000D3CD62C9FB7102863DCEEE6BB27FCF631E
-:10ACB000C5E53DBAFDBB1E77C4FE5D8F6BBE8C79CA
-:10ACC0005D7D7E763E500E7F2BEFDD821B9493AA36
-:10ACD00056904F19DBB9803B62C7F7BDE31F6BEF9E
-:10ACE000734D6885F07AB7F8562CDE30436F959235
-:10ACF000CC30BD61CBCFE8E2F2E5AE5293A097A98C
-:10AD0000DE2DF2DECBDAFBE3981FA246E23AC6A3C1
-:10AD1000F93EA0C27AC8E3D3E7AD75E915AD7C630F
-:10AD2000CCEB107413CF1F555847C2DC7633F36A4F
-:10AD3000C9FD9FB644709DD4A8B84E047D1ABFEBE0
-:10AD4000728EB3CC631EF4C0F998C7BC0F4AD73BD0
-:10AD500052A2D07A19F3303DAA5E13D7D5067455A6
-:10AD6000D1EE71E2F12C5F7F7E0BFF9489F917958C
-:10AD7000E2FF7085F85BE350FC9F063D4BF1FF124C
-:10AD800094C5F07F8AEBA36AA277E39EAD333D4B77
-:10AD9000C8B57A7E7CDDEB65FD56733D45489B2D3D
-:10ADA000AFC7C5E9AA949EA3965E2B438F352EA507
-:10ADB000E7453E1FDF2B351F2F707ABC5EB66FA9AB
-:10ADC00087E33A5D9A6469917999E278CCF7F2B8B1
-:10ADD00052AAED9CE4EAC715D231353B2FAFF17989
-:10ADE000F945293A5EE5729596C8FA53B09F365AEE
-:10ADF000F90BDB6CF3B288F327EDB6E6A5DD362F51
-:10AE0000A1739C97DF5648CFA2D97939C3E725575C
-:10AE10004ACEF2E0FFC4E1DFE1F068272EF2FEB196
-:10AE20000FCECB9679E2A2B766767FA3709277CDEC
-:10AE30002CDCE7878F5B706E84EB988153BD79FDC6
-:10AE400091D4EB7D70FEDDCFBFFFF8C170E02ADE4C
-:10AE50002E88EDAE61F4D07655F9FD3F3BFCB2D5BE
-:10AE6000FF3C80EBDEF28E0517CE875BE47DC78268
-:10AE70008BC073E1F04C7FB5F9784C79FEA98FE572
-:10AE8000EB38F2BDB4CAF21D5CE104DEE7504D02BE
-:10AE90006989960332BB5F21458DEA27207FD69DC5
-:10AEA000C8920AEC2E5165EDDCD4DE82F3E3791A08
-:10AEB00039E6D1C10531C861FAFE4058467FE00E3F
-:10AEC0004FA2C55BC3F0C43C80D7983DD6ED6FE17F
-:10AED000711486D798EF1343D09F46F182FE3FEF5F
-:10AEE0000B1E03F883F50AE6F31EABBF13EDC4B1E6
-:10AEF0006E99C0FBB1AB15B413EF7B2D80FB70BF17
-:10AF00006C5C8FF90FA6A283DD7897F79D9390A7CD
-:10AF10003CD95DA50957203D887F4A24F15EEC9F0E
-:10AF2000D99D7B28FE900F8C5B17F4DBC1FC18C207
-:10AF3000F39CEFDAA263DE8C4ED8FD4D83AD0AE6BA
-:10AF4000298DD535B4C178F7B5AA6877DC774D433C
-:10AF500037E673B77A31F7ADDAAF0B90DF135CA742
-:10AF600010F810A43AAC7783DD1958EB853BBF4845
-:10AF7000751D1B2FB08CE03D7F2E928EC768191C6B
-:10AF800052F01EA7FBAED996DD09764D2BCB5FA6FE
-:10AF900084BD145B4B889FB392483F24808F6B1114
-:10AFA0003BCFB7E639989E695FF21C3198A9102E05
-:10AFB0005B195C6048C6FCE4B270E90AE13215C274
-:10AFC00065195CD9F37B9E4FA9D27F1087F338F3C4
-:10AFD000B1FDA5BF8B3BD77CDD31AF3DEFBA5C7BCC
-:10AFE0002B4FB71CBD70983983A7541EDECAB32BF4
-:10AFF000F6DE35FFCE087C97365873372FEF616544
-:10B000002D7F5EBB2782F745D6F2F7B5F7E0FD91BD
-:10B01000CE7EFE0BD7C74D245E721EAA39FE6F503E
-:10B02000DC219EDD2497C90770E6FB39F49E2AA730
-:10B03000DA71DD5EC3F28B66BE9FACE3DF8D906498
-:10B040003C86F12C33B872FEECFA716DFC3EAE1FFB
-:10B05000EBBB493A3FEC7B49879C38E5C2EDC84FD2
-:10B06000B9503979E53D9213D79054D1FA71A52B97
-:10B0700084CB540897AD0C4E19122AD22B4ABA42EF
-:10B08000B84C85705906D7BF5EE1FBFA703FC4B774
-:10B090005C97ABB67AFFE55EFBFB0D7E5B7D608D5A
-:10B0A000BDBDB2D6DE7E60ADBDBDB28EB5377C878C
-:10B0B000AE4AC52A5F27FFEB3CD749935A1A3ED0C8
-:10B0C0005A665DA99A07DA57CB3A81FB85E87E95E7
-:10B0D000E1FB56C1F8CF561F5BFF577B35DBFD7494
-:10B0E0007FE97436F918BE16BDE5F0B5F4EF3F4AB6
-:10B0F000DCEE2A92771F029D538B8F17417FC78EFC
-:10B10000BDB510ECCA675F5F87F79AF67ED0CA9B21
-:10B1100031301F523EE9FD38E8AD67E97E0BF93862
-:10B120001321E3F82560CF044402F63275A3F05EE4
-:10B130008F678FCA687FF43E57DAEF7FA68BE509E9
-:10B140003D0D7E3FD5FF47F8BD5B4FF27BB71EEF4D
-:10B15000D2B11CEF6AC2F7992E03EB0F77B562F9F3
-:10B16000509789CF1FECEAC0FAE1AE38D6EFEFEA8C
-:10B17000C4F2DEAE0496FBBB7663B9AF2B89E570F3
-:10B18000D71E2C07BB522C6FB36B887FBF96C6F2BD
-:10B19000D2EF4C8D5C0276925FC4EFC08AE1BF6251
-:10B1A000C21E77B8E4883DEEB03C638F372C3B6C11
-:10B1B0008F372C4937D8DE370E5D6C7B1F4DADB213
-:10B1C000D52FDA73B90DBE3ED96EAB2FDAFD7E1BDB
-:10B1D0007C6D629B3D1FACF3061BBCB67187ED7D99
-:10B1E000B0E5AF6D757FF31D36786FEC6E5B1DEECD
-:10B1F0007DCE87BFD6D7C0E281E1111B9CEC3F68B2
-:10B2000083DB35DF7CC4B706F2F183685F3EFBAABF
-:10B2100080F95DF3161BAF03DFC92B12CA13B99275
-:10B22000E5C3CF6B485E06F7941139B9EEBA40F921
-:10B230007BA4AD788F146C4D80BC9E795DD0C1DE4F
-:10B2400015827B964D1690C7DDA7936402E2923C6F
-:10B25000CFAC7121314DDACE4BF5091E2E926476BA
-:10B260002FC62D45FC8EEA312181F926D46636FEA3
-:10B27000B30679F4CEFD77C3CF7787F17E04B4CBE4
-:10B28000DB0EB44E0D51F8F1150ADE7733075FC7B8
-:10B29000FD76BFF5313F78DF5E16AF6C7C7E7D8337
-:10B2A0000A76784B621EB8AA337A23FB33FC4E2908
-:10B2B000A01B6BE10A80402C4D763603DC0913E2BB
-:10B2C000B614FE6BBEBCF1028F9F4879E9F3E547E7
-:10B2D000128DF0D9C4F85E162F1D1F5E2ADE4AC7F4
-:10B2E00069C82E1797A2BFF324BBD77D48176FA557
-:10B2F0007AA1E1505CDC5A806FE37F2A1C4F9DF4F9
-:10B3000049D87EBC3B83F7CB79B3DFC47B38AD79BA
-:10B31000F135EB6202FA3D9C10C15E1BDFCBBED360
-:10B320001B17A20B239CCE6E079D8017A58BDC0AF2
-:10B33000E5434971AB9F3D6F0CCCF60BEF77C2FB39
-:10B340004C4ADCE2AF887FA6179E3FCEF9772423D4
-:10B3500096E49F7EC2047EAB31CA3FBD14FFEE6708
-:10B36000FCA37CBBD53F975F33F0295D5CDB9CC7BA
-:10B370006FDE1EF8726B01BECEF089B64F60FBA87F
-:10B38000B89A8F0B7C68A074EF2CD44E88F271327F
-:10B39000F671281F6FCD8BA7C39F3F2F4FC48287A5
-:10B3A000BF8EB53C4F91D2ED9A0CED84EFAFDB9A96
-:10B3B00013780F70BF5FC4FB85FAFD5FCDE23DFDE2
-:10B3C0001A41BD29CB66CF4FC22C0EDD23145AA7DC
-:10B3D000763F01BE4CC9FF9EACCF6FE5E197B197B8
-:10B3E000F8BDC212BF575891E31D51B69E8D6E3203
-:10B3F0001B5F9D3BFE41A45B8AD8F7DFBE5DF67DF7
-:10B400002FA6DD8071ECDE7065DF0DB973CCBE5404
-:10B41000383EAE9C8FDD779CF3209E666E1E969B19
-:10B4200073212CAFC82DC2F79B72B558DF986BC43F
-:10B43000FA865C14CBCB7397E0F3F5B9E5586FCD82
-:10B44000ADC6725D6E253E5F9BDB80F535B9F55864
-:10B450006FC96DC17275AE0DCB55B90FE0FB95B9D3
-:10B46000ABB16EE4AEC37279EE5A2C9B721FC7F774
-:10B47000CB72D7637D696E27D697E46EC67A2CF7B8
-:10B4800029AC37E63E896543EEDF6319CD7D1ADFCF
-:10B49000EBB9CF62FDA2DC67B0BE38D78BF5FA5CA2
-:10B4A00037D6EB72FBB0BE28378CE5C2DC7D58D6B0
-:10B4B000E6C6F0FD82DC0358CECF3D86CF43B947C8
-:10B4C000B1D4725FE2F7453F856530F7352C03B99B
-:10B4D000AFE07B7FEEDB58F7E5BE89A537F7029634
-:10B4E0006AEE1896E5E6A9DCF74F9BC93C9B5C6CBD
-:10B4F000CA2DB4D5374CDBF7EFF5BFBAD8565F3756
-:10B50000B9CA565F73F2725BFFAB4FD8F7EF95C7BE
-:10B51000DF6FB71FB2F6FD7B59E606BBFD7078877B
-:10B52000DD7E48FFB5AD1E1DBAC36E3FA4ECFB77B0
-:10B53000FD1EFBFEBD283962B71F761FB4C12F2048
-:10B540000F3AF2C9C76DF055E6D336F840EB571DF8
-:10B55000E72B19A6FF8D6FD99EAB4DCF173C87897E
-:10B560001DBA1ABFDB3F5D27F27B86F8BDADFC7EBE
-:10B5700034E77C56733D302FC7FCA7305F7735B07A
-:10B58000EEF2F29EC0CE88E6D919F31AF4AFBC48A9
-:10B59000EB67162B4637AD5B7686055FF6772B1487
-:10B5A000633245F174BDEAC67BE78460A70971B5D3
-:10B5B000BBA604DCEFAB17119E1FD1D1C1E213C4AF
-:10B5C000BA4F07EFF719ACB7DEEF7C1FBE8FB2FAA8
-:10B5D00071FFDEAD10471D7459EFBFF43E8C7378D8
-:10B5E00058FDBFFB770DC0FBEAAA8908ECB3FB8AC4
-:10B5F0009C6FFE4FBFC2EC7DBFF923FF9AD97BA69B
-:10B600005F09275EF2D3E7B7A9898BE0CA6EB8E776
-:10B610001EEE71DE2A9B3F01B86B65F3653FEE0BB2
-:10B6200076FFE15AC87D5D83F702FE0CDE4BC1A3B5
-:10B6300098DF5FFD817BF0BEAAC100C5C75F1C9F7C
-:10B64000FFE69766F61B62ED370D184F457B7020BD
-:10B650004AF0DE8CC1503C05F7F9A5BEA792270C35
-:10B66000A03BCD9295787EE2E072DD920BDBFE444A
-:10B67000483C0B717C5FC2AF83BDE6272730FF22B9
-:10B6800048A6B1D48826D8EEDBB6E8AF67F4C3FD90
-:10B69000FF7E3C87378F4E629C3549F8FDD56FC1E0
-:10B6A00073CA9733FE35C5F97295740FD1E8F80F58
-:10B6B000537B12E87898307CF773FF5426C97823BF
-:10B6C0008FF7E4DF2321BFFA4D941B2BDE234B1BA6
-:10B6D0003BF07A177E8F4307FD07F6614DBC74BCC3
-:10B6E000C7796FC3B9C67BC20167BCC78FE7C9A75B
-:10B6F0009B4B7F0767C57DF63797BEB732C3FDBE4C
-:10B7000087F979EF43FCBCF741EEF71DE67EDFFDDC
-:10B71000E0F7E1BD5ACCEF3B007EDF32382F366DCB
-:10B72000DF978C16B9FF251A12B89CED41FBDEC7D6
-:10B73000EF2BA29E2BDAF35E6ECFF7FA7BE6C3FD0A
-:10B740000CBE10C9809FB0FBEA71FC7E969262C06D
-:10B75000FD00B7FFFA8DF9FF8ED6631162BBDFC91A
-:10B76000DBECB82FA1DC3872C6847E7DD46F481B19
-:10B77000C5F973CEFDAA19E239AF7ED93D3FD6BDDA
-:10B780006DD4034F81FCF9806E0DE4EADB38CE699D
-:10B790003E0E91361EC7FB0C2F934929399833CEA4
-:10B7A00039CADFAE80E3F7291CF2A7CBA407EFA9C3
-:10B7B000E1DF43EA7EC39B1F5FB1E4B0B799C51FC9
-:10B7C000BA5FFF18FE6EC08B355B17E6FB7FD6773E
-:10B7D0004ABD2D0C8E5A7DB8CEF7779FD43FA9CFA6
-:10B7E000C23D65C169A5E3194F5870A30C2ED06204
-:10B7F0008885EEEFFB22DF4FBEEC3353819AD9717F
-:10B80000F59E8E1B504FAC51F17CC6D9EECBBEC419
-:10B8100050202F3FC1EA3FBF3DC85789F6E952ED9E
-:10B8200017DFDDF17352BAFDE1C09AE2EDEBEEE80D
-:10B8300078B00CFE99C2E3A71EC173A608FBDDB267
-:10B84000EE5AA501FCE57D6BA8BF4CE7E1C5155B91
-:10B85000F15ED9BED02B7A2139A2FD7EA9145E9467
-:10B860002F9D65E8FA5AB9F64269BABE5D86AF27E0
-:10B87000CBF0E58552ED295F0F97C1FFBF16C63F9C
-:10B880007511E01DA863F1BAEE7ACA57F0D7D6B0A9
-:10B890003884B51E1E1F2BCAD757CAF0A59CBCFE04
-:10B8A000E202E5F58D52E35720AFFF5486AFE5E4A1
-:10B8B000F5AD62F28AE7A4E72FAF42F0C2E4D513F8
-:10B8C0002CCDD772F21A2AD5BE0279AD2D857F050F
-:10B8D000F21A2D34BE9B508508F67E333B17DBDD14
-:10B8E000C6EE237335B17DD7F7EA17D13EEAA3FB45
-:10B8F000D3BC56D8A7A7EEBFBD65765F76EE3BCE2C
-:10B90000FE9CFBE6EDFFFB49DC37037CBFB3F0F1A7
-:10B91000E8CE7E4ADF6771AEE37AE17798F27EDFA8
-:10B92000E2E2C7EDDFAD5EF878F67DDDDB42C7A76A
-:10B93000EF091D7F0B9E233E83E7884B0F5DE8B820
-:10B94000A5E19B1E727C8F7B8E76C02D41BB1DDADC
-:10B95000B0E76B8FE0FD23BC9F06D9C4DFED93C930
-:10B9600095ECBE9321962F24EDF9CA23A756E7DD67
-:10B970002B4574313F3F481A9A78E4541E1D39888C
-:10B98000F7B0F832E62DC6B4CBD19E181C2D6DC78A
-:10B990007E99EFE3CFF0F38BA7B91D7B84E72D3EB3
-:10B9A0000976EC3238C760E717E360C7629E632B05
-:10B9B000CF7334799E630796CFF1F3876F751DC6F9
-:10B9C000F747BB32587EA3EB08965FEF9AC0F75F4C
-:10B9D000ED3A8AF589AE2CB38757DE897A66960EE2
-:10B9E00067DCAA341D971DB5C741564CD8CF312E00
-:10B9F00039623FC7589EB19F632C3B6C8F832C49A3
-:10BA0000DBCF311A87ECE718BE26FB398647B7C76C
-:10BA100041DC91F73BCE41B639CE41ECE718F54910
-:10BA2000FB39C6A2DDF638486DC27E8EB1A0F36E3A
-:10BA30001B7CC8ECB17F17DF6A8F836C9AB69F5F5F
-:10BA40006CF8D583F6B8CFA43D0EB2EEA43D0EB28D
-:10BA5000E6C4576DF5D5C7EDF18F0FFB122F823E6F
-:10BA60005D9975C641264598BF9FFBD9F99FE55F53
-:10BA700053F81F80FEBC4AF2673750B97FEC28BBF1
-:10BA8000DFFD31C2CE3309F90FE82FC833FE8289BA
-:10BA9000FA47E2FA67ECCAA957C09F91F7337FE7EC
-:10BAA00076615D56CDF7775CFF28E4AF6B4973FA9A
-:10BAB0000D65FA970DF473E432FEC8DC7E99DE9AC8
-:10BAC000BDDFBC25057954F28C3FF201873F523728
-:10BAD0008CBF6335AFB43F32679C73D4436F058B23
-:10BAE000F8C31111F967F923FB5AB83F42D87752CE
-:10BAF000567F961E1A8B945E87D63D2D63DC6F9120
-:10BB0000FD85CFB1AD7C99B196CAF2BA7F1064E7DA
-:10BB100049149AFBC3FF5F3EDE4DF9B8BCAA88BF4B
-:10BB2000FA1ECB4731B873950F197406C6236F19E7
-:10BB300084EF985C50BF7CB6AEF07AF0DEDBB642A4
-:10BB40005EC81EC2CE75C8CBECBED57278C436DED8
-:10BB50005432FFC18AAFFE496379BBB1D69B306FC7
-:10BB6000F2341DA3D47DDACE3C0B299C841FDB83E9
-:10BB7000EFD80B9EF7FCB49AE593C73A3F51D26ECB
-:10BB800071FE1E58CC2C7DBFEE30C7FF85D716A0A6
-:10BB9000BDBA6F88E963B973C5F3208F8F833C1AF0
-:10BBA000184F5197035D4332DEA7E6D709C6051744
-:10BBB000FB49A63B0A7C3552708F17FDC373E5190C
-:10BBC000F91CB2DB51672C3EC54BF3B5ECEF19AC59
-:10BBD000D7312F4DD649520BE1FA216F84113F5CCA
-:10BBE000B783AD06FBDD3B8A8FA6CD6DEFC4CBB925
-:10BBF0003EE55D57603CA941B0D6A7CF803C9DD3C0
-:10BC00007E7FC97BDEE6F47B8EEBF19939EBF19A0E
-:10BC10009E9FC2B8A32C7E44F6D0BFBC734E677FF4
-:10BC2000D67AB4EA2FBC76177ED732387A07BBAF04
-:10BC3000B88EDF0B36CAF46331BCAC78D0016E1F0E
-:10BC40003E71A8BD07F8DB47D74DBE3E5AF2B71F7D
-:10BC5000F126D8B96235944F1E66DF6B2F7D6017D1
-:10BC60007FBE039F1F68DDD68EFECF21620259C1C1
-:10BC7000F5A754F67E4A43F8F0F471B81769299590
-:10BC8000378885DFBBB1C584DFA8AC0A89ED504A8F
-:10BC9000A393A877492B3197E830AE8CBF9FB33878
-:10BCA000451E057C168F2646403E499A18F0BE2A4E
-:10BCB0001CDF763585AFA282095756A7087BBF38AF
-:10BCC000A9E1FCC5461307AF06F86682BFCB45DF86
-:10BCD00063BD6EB786F93FBED1C921B8F79A8EC150
-:10BCE000DFD33A7DBF30C1DA074627D35BD02F9927
-:10BCF000799FDED202F70EB2F7F228A507DE4718C9
-:10BD00003E29327D02DECF0FB3F7CA28DB1FEFDDFD
-:10BD1000B803EFD3A3E3E37D532EFEFC31CEFF58EF
-:10BD2000E73B27601C2B1F2345E2B67BA99CEBDE7B
-:10BD3000FAFDBF5E6EC7FBD4455F3895771FC33EE3
-:10BD40007E5FB577D4BE3FFFB18AEDB3C7B89E29F9
-:10BD5000772F1B247A839CFF0B555919960080007E
-:10BD6000000000001F8B080000000000000BC53D14
-:10BD70000B7854D599E7DEB9F3CA4CC29D300993CC
-:10BD80009099DC840422043A814041512711111515
-:10BD90006D44DB066B7508C8FB11514BB4DADC90BF
-:10BDA00004921060B0AE44E43189A2A8A08382D28C
-:10BDB00096DA01B3145DBB4DAD456AD146D0A808F3
-:10BDC0003452517657D7FDFFFFDC4BE64E2689D61D
-:10BDD000ED6EBE4F0FE79EF7FF3EFFF9CF19C61875
-:10BDE000FB2A17FE5795C4A2058CFE285F99CAA2AC
-:10BDF000B698FCFC4C637930D7982F1F69CC7BC672
-:10BE00001ADBBB2F36947F7E1D631D4EC8487E1BF8
-:10BE100083543A7AB3AD6C3463B5EEE5943F7FBB9F
-:10BE20005E1E48C27C9E7CD28EE58F5555D8582127
-:10BE300063AB3C330605E1FB57F87779EFB4A19A81
-:10BE4000B1A895B135D5214A9BAA5B286D2E6222F7
-:10BE50002B666CED6831DC96C3D8EAC219D45FBD9D
-:10BE6000BBFFFEDAB0BF118C85AB6D946EAD96A9A9
-:10BE7000BFCDD51E4A6BAB154A37551750DA52ED78
-:10BE8000A77A0F554FA434541DA0745DF5342A7F52
-:10BE9000BEBA8CF2BBABCB297DB63A48DF7755CF23
-:10BEA000A7F4E9EA4A4A9FACAEA2F4896A95D2EDBA
-:10BEB000D50D94AAB2C8581AACE74A7F6619CCFFD0
-:10BEC000D12B5979A4B0F7BC5559E0F56480E578D9
-:10BED000C6925828CADC882FE84B61CCDE10623647
-:10BEE0008047E662F886F9AA10B342DE3387E7D7C7
-:10BEF000E138D0AE8AB100C28D15B0F076809B4D8E
-:10BF000009B159305EC0ABB21B92199BAE8D83DF75
-:10BF1000118E6A8ECA105F272C81EBE434EC8751B6
-:10BF200079FEFE8E8388D6311D91524C0B0F8744CB
-:10BF300009D291532A579A201D345915B1FD2A8FE1
-:10BF4000582AC078E7AAC4B009BA568AD94113E47E
-:10BF50001F2B14C34D307E73091345C46306E05193
-:10BF6000E8596FD2F9AD2C3A0EF05A3563104B00F8
-:10BF70000F3D1D3A5FECA147F82F2398D443AFF053
-:10BF8000DFEA50FFEDC7EC110DF50B77C6B52F8436
-:10BF9000F6FDD0D3C8C78CED0B362719E6B3DAD33C
-:10BFA000FFF8F9E7AFA775F645B7A72C153F43B8DB
-:10BFB000EBF9F4F397B1E860C6DE72CA84CFD46BB4
-:10BFC000EFF3040B69B82926A007298B859B04CCC5
-:10BFD00006D86C80AB19FED524F33CC2DD04486A58
-:10BFE000F223BB2A019682A93FC0C6601AA0FC2199
-:10BFF00073B0591E8FF932FE5D0E121D345F045D61
-:10C000005C8CFD6437042643FEFBF0CF4CC6AE0FBC
-:10C010005D344D85FCE7E6A05805E3AFF5727E5C24
-:10C02000E11B9B84EB7EB4B97F7EACD5F851CF9BEE
-:10C030009C0126403FB90DF258A4A3BEDA3DD8209A
-:10C040004E0B27E8F729A45F987F7DC30C391F5753
-:10C05000DD8E328B31AB9311BDC5D787F53E85F0B0
-:10C0600035BBF93AD36E2AA3346FE7245B19F0C3CA
-:10C07000E7C9FDE3AF316EFE76183292605E1F6A4B
-:10C08000F3CA7BED17241F3F1FDD3F5DE972EF7C94
-:10C0900058641D885FA98CE469DA4D419607EB5915
-:10C0A0000DFCE244B9F7E58D0D3980577583487270
-:10C0B000409F7FFCB826A5B34484F2D5071630050F
-:10C0C000C6377BCA985A88795D3E4718F6EF707676
-:10C0D0000470BD0E160A98A07F475550C5EF168F05
-:10C0E000CA90CE56675CA84FF2764D481411BEAB8D
-:10C0F000B2C4301328654EE4F76246F9E48CE702D7
-:10C100002292CD17309F09D00FFEDB84F05699881C
-:10C11000EBC8677E27CCCB56D01D10A17E1EDB1747
-:10C120004579602B61FE26E49F8C2301A45BF50E0C
-:10C13000E6CF27320F923C6252D086F22AB7650CC6
-:10C14000F1834D8908B8EE1F5882EFC5F28BC5C345
-:10C15000E5D8EA2F4D09E5EABF6A7231A90FBC396B
-:10C160005CBCFC73B3720DE91BC8B725A023B38B6D
-:10C17000CBF13679C6EF0B941EBED4CBDFC2458E11
-:10C18000EFC9E79EB7D0BCF36EFAF1205C4F5F7445
-:10C19000B04AA3AFF583B8DCCD9B7C6900E17D0E8E
-:10C1A000E6DA24F4AEBF609042F5F4BCE434CAC7CA
-:10C1B000AF3F3F89E452DEA97B381F78FBA7577D4C
-:10C1C0009E9F7B8DF6809867233D5D1F12492ED57B
-:10C1D000BA459602F9AD481F3928303BED17C17AB0
-:10C1E0006C6F9818E27B6B55A9A84279728E142661
-:10C1F000FAF37447519CD9257600E903F0ABB8D225
-:10C2000010EF13087E59C51101E9FA94A617E1AFA2
-:10C21000CE0374E6E34B46FE1EE182EF819D02975A
-:10C22000031E2E07CCCCAF5A717CD0881118CFF1E9
-:10C230008689BE331689DE0FF92459F4A3DC5C5BD2
-:10C24000BC321DF9CDE162A4BFE65FDD46F209E430
-:10C25000AA7F13C8D1A51F75A52F837C9E87CB5DB0
-:10C260001D1E498516835E18701C291C403DE9106F
-:10C27000983FE4EF1BCEDFB85F5B98D9FFA17E410A
-:10C2800061A4135F687F3B549A1FAE1BFAB5B25F7F
-:10C29000D138E7B47198E9D861846FD27724664ABF
-:10C2A000C01F7D8E63BAA55FFD50756CC1EFDB6367
-:10C2B000E8F73657B2BB6B14FCE3BBECBB5FA18263
-:10C2C000303989BECE813D81E32A367610F375CDB3
-:10C2D0006238117F7C5E3DFFF7ED80BCB59A5EAFA2
-:10C2E00079D75A4AF4395E0C5BA17E7BDAD4CCCE86
-:10C2F00018BED0E5706D31D70340DD0CF9616DCD0E
-:10C30000516581D253EF49BD9EDCBFBED8AED76B1D
-:10C31000E6F5928BFD623041FD27347E7AC611B876
-:10C32000CF35BE675C65E5B49B490E8DB73153824E
-:10C33000F53DE308D6B962F858EF3FB63DD26F3FFE
-:10C34000ED9B5D697DB7F7DD3BED2DD67FFB07FBF0
-:10C350006B9FB57CDAA601E6BF39F1FCD56DD82E0E
-:10C36000D9636148E7351996DC06C8AF196FF15BF0
-:10C37000010FEDA3A77A106F75AE234A227A827E51
-:10C380009FE86F5E0097F201D6F5EC00702D17FA6A
-:10C390005FD78BFDB507B81E1D002EBF1900AE2D4F
-:10C3A00003CCFFB789DBABD938EFE42C0BE9931A48
-:10C3B0002FC0D58DFC0070653DFCF0D8863EE1FABB
-:10C3C000FA40F436C0BADE1A002F03D1EBF101E0D7
-:10C3D0003A10BD9EFC96F47AB60FB86EC3797F0B07
-:10C3E0007AFDF25BD2AB39F5DBD16B726AFF72601A
-:10C3F000207A4DEBAFFDD7A0576FA2F95B9923A030
-:10C40000A2FD53C8F5F8FC1291F4BAB980EB5FC7EE
-:10C41000B127488FD6819E1A3C11F5F5F187961603
-:10C42000F7E8E778FD13DF5FBCFE5CFAC9E3CC8E6A
-:10C4300078D4F49E3E1FBB12DFCF8FFAB5E3BEE97E
-:10C44000B8491E16B58FE9693FF2318BC18EFBF6F4
-:10C45000E319F57B52318C8FFE0418FF8A89A857A7
-:10C4600077FA912E873FF86DC7EDBF7EC16663FFF7
-:10C47000DFD41E98950AF680A3C71EC8AD7A7EDB6E
-:10C480007B837BFAC995024C06BA91D814B2DB586B
-:10C4900003F36FC7E2AADDDBDE1BD7630F0047881B
-:10C4A000B89FD0C7313544B6BD17B38EF37398B675
-:10C4B0000FABA47D4F9E7C7112D2F1EAE6FEEDE255
-:10C4C00067343DBE53F3373D85FE264877A0BF094C
-:10C4D000D2C7D1DF04E963E86F1A81FE29EE6F6AE3
-:10C4E000427F9315ED0FEE6F5A85FE2648F7A31F86
-:10C4F0000CD25F6A7EB07DD5614A5FA8DE41E99EBD
-:10C50000EA08953F57BD8FF291EA28E59B8B7E4262
-:10C5100072A6671DDC3ECF93757F5DFFEBF8CE3EC4
-:10C52000E33E6274C4E82719B523D590BF289C69FF
-:10C53000A83FA225D7509E1F1A69281FD630D69033
-:10C5400077145C6CA86F574A8D74E5B9C6503F47A5
-:10C550009D61C86757DD6CA8EFADAC30940F9DBFEF
-:10C56000D0509E115C6EC80F29BFD750DF15586997
-:10C57000281F34B1C9507E69F70386FC251F6E322F
-:10C58000D49FD4D96628FFEED1A70CE5E33B9E33B8
-:10C59000E4C71DFEA5A1FEF71CC128CAC3A2E8413D
-:10C5A00023BFB04E11F1D79EC268FF6387FD7B2089
-:10C5B000813DF95F83F83ED6CA4691BD7B0EE459B2
-:10C5C0005311B6AF0CE1FE3A17CA9A14DC9A8705EC
-:10C5D000368CA1AF286A4F89E5876F260770A78F31
-:10C5E000F57DF0877CF95FFAFE75875DBD0CC7CFDE
-:10C5F000E3F2589555D207F1ED75BF50DE8E998361
-:10C60000B0BC4E2E9513C9851396E089583D11BFD5
-:10C61000DFCD0B24B3008ED7A0FBC5B8DC33F12AE5
-:10C620002CF7D8558705F483958F49C5F5E8FE9C0E
-:10C63000D51ABFD66B7C6A6597A8E8AF38A7EDFB23
-:10C640009869B2BF3F39150FAF6F2AD7BE488DDF4B
-:10C65000E74C8FBE8FE33748E144FA524F75799625
-:10C66000F7C66DFDE24787AF8E4793DC1140FD6A48
-:10C67000532A5985B3379C4C599C1EFED9EB1E3A60
-:10C68000D828CFCFB1C2D240EED7586FF9ADB40E93
-:10C690001D9FF1F5D655F37D5733E295CE1164CD4C
-:10C6A000DFCFF12B4E0CAC44F8A6C03E1AFD02A21F
-:10C6B0003FCA3A13CC7BD044237D25FB8D72D051E9
-:10C6C00060948392D32807CDFE4A16413F2D8CC338
-:10C6D000881E830CFDB6F81FF19F3C10DF5D121021
-:10C6E00062E87020FEC321BE1A3630BFFEA3FCDD17
-:10C6F0003E279DFABF47E36FE0689EAAEC75A49FB2
-:10C700008A891A0131E5877F81792F386C263FCFDE
-:10C71000E55F6C3BB405FDD113AD32FAA3190B1DD7
-:10C72000FA3594CF09D8CA30BFE0D8688B0FCA8FCA
-:10C7300064021178B0BC2C05E5C069264E433FDD8C
-:10C7400069F67ACAB81839B764B085FB7F1ACCC7C6
-:10C750003B6D38BC4AE753B787785E5FD7BC16633A
-:10C760007E2E9B912EC138731F34A3E4630B987403
-:10C77000BC538703D0C18F07CBB49E79AC72950CA4
-:10C78000E3D69BF9F9CC9217475B100F0BC6C9395A
-:10C79000A6A29E79DC3D98FB014F02BD29D69EEFF3
-:10C7A0000B9D610BCAE5137BC6FDE01286FD845725
-:10C7B00065A25FD305F688D21BBEB31B8CF31C6841
-:10C7C0001DF1F3666C25C1A3AF79483B844022FF7D
-:10C7D00079ED60C180C75ADBCFB675C23C03B51294
-:10C7E000B35F0679899F1FA9C792C3DB517E975615
-:10C7F0003ED1097050575AE55A48373A7EF62CD642
-:10C80000AF0284E1F9D3CEC10AF79FDA7D613C5FC4
-:10C81000007DF3DD19C9DFBEDFDDFFA47E5FC07ED2
-:10C82000D37AF7BBC4D669C173B46552E5344144C9
-:10C83000BF22AF6735070343D19FB8AF283A5431C1
-:10C84000D46BF89AF50E0BB95FABDE34B19FFECE18
-:10C8500068F2EDB73B1FB5A0DC3AFDD4BBD7E3BE11
-:10C8600068D1AF4CCC06F5CEEC4C6651B2FBC2168B
-:10C87000B45F17EE3105C2948F4EB8313996AF6B65
-:10C88000A9FF45CF26D3BE6AE173D6F07468BFF026
-:10C8900085136318C883332BBB0F0D45F83D2590D6
-:10C8A0001DCDD4CE3137C2F78512BBAD2C81DDF161
-:10C8B000678D1F4EFDC2518EF426EC38702BF51B90
-:10C8C000F9A1D91AA3C73A069B099F508FFCDBEA4E
-:10C8D0009342385FE0F3BB6174ECFC6A78BD27B922
-:10C8E0003F77E13E73D88EF3DBD16A0942BD653BE9
-:10C8F0003E21FABEE2D95D29088765FB4C06B9B630
-:10C90000E8D92F575D0C785E6462DDD3498F7F4193
-:10C91000F973015BB789E450204500B9B59444161A
-:10C92000D47BFE83A97F81F2931E13B3832838D969
-:10C93000F1BEE557980F3A2B991FFB37F2E1B21D74
-:10C94000272C382F5964DD59C0E8977D1AC397AC5E
-:10C95000777DC6BA2D286797451A3F3101BD2DDB7B
-:10C9600073FA2DA4BB6571FC7C12FF91D15B5F0A49
-:10C97000EE787DF9DA0486E7F43B601334A96F7D25
-:10C98000A9F3F7A25DE7B6AA30FEA9E73EDEAA0248
-:10C99000CA17FFF7DFB7FE14F7492FD965944BCBC1
-:10C9A0009EFA530A8B817F969B9F279D79F289C7B8
-:10C9B00037011CCEFCD94A503BF3EB0F7C0AC0FD7B
-:10C9C000CCEEFF48C7F3A5BB7E7DE510A4B3BBF654
-:10C9D0005E31A4BF7D05D26DD81A8BDF30F5AFEC88
-:10C9E0008371864076BF96C6E1E5D4EECF2D784EB2
-:10C9F000F499C0BA51FE2E8D7C6941FBEC508075D4
-:10CA0000239C5EDE73E2D0BD903F0D78B226C0134A
-:10CA1000AC7FA8487A253A14F5CBD23D377EEFD2C9
-:10CA2000624CCD7E05F1C4BA49DEF7C2EF1B80DF50
-:10CA3000E21EFCC6979F635F5810FECB76023EC78E
-:10CA4000205E019F637AE3F334FE63526F7C5ED213
-:10CA50000B9F8BB76DC2C23D8309FF7DE173C9DEB9
-:10CA6000EFF76B67E9F2612038CF17F8BCACEEC086
-:10CA7000B56EE4B3E71CAA87E3393C1DCACEEC3A95
-:10CA8000E74367C887E6EE5B110EDDBFB6CA786E76
-:10CA9000BFF0D76F12DF9DD9FB070BE21FFE528458
-:10CAA00009906717FE5E67905FCA6D70B684754F18
-:10CAB0007DAB1853D6ADFA097F943F047C48F80843
-:10CAC000DF304D41F91B4EA3752F0D73FE581A3EF2
-:10CAD000709330A637DCEBDDA276FED3835761225C
-:10CAE000E2F3DDA9487F7DE1535FBF8CEBFF2E941D
-:10CAF0003F66E4DFF8FA4B815F717FD40BBFE1033F
-:10CB0000FF8EE99956AB24802D7406ED04676FBC47
-:10CB1000F7C09FEBE76F6A1F57C7D187DE5E87D3E9
-:10CB200040FC3ED0FABE29FC96B815031DE9703CC6
-:10CB3000F545627DF088263F96B2CA6999C37AEBC3
-:10CB400033132B53870A3DF35D1531919C3FB5C3D9
-:10CB500044E733F1F262299EDB2618E74937B763D1
-:10CB600096EE3B3006E5DAA983BFD0E892D3FDD23A
-:10CB70009DEF5A544D3F8463E5731FE7C0CF6BF3BD
-:10CB80005EB63F717FCB767E92B0BF9352E087381E
-:10CB9000FF931D66A642172723A684710B5BDC66F4
-:10CBA00083DDB52A79C2D141B82F48495270DDB52D
-:10CBB0002B036FE2B9A8FABA99CEF999E4FFD00A2B
-:10CBC000E5B5C9490AFAF36A53E63225468FD7C557
-:10CBD000C149F294D1F99DE42E2BE67BBAB0E1BCB9
-:10CBE000D70C04113B6FD0BB59A897DE29FAC08C33
-:10CBF000EBFC6B9C1DF95789AD1A02FDFD5515FC28
-:10CC0000354AA2FD81B1FFE07D26A6C4F4BFD4DA87
-:10CC1000FD0ECE87FDC6CED02E33BD6417509E2CA0
-:10CC2000DB6AA6FDD732D85621DC3ED8620FAB9026
-:10CC3000DFF87CF5ADA897FEB6D5CAF05CE2E5BD9D
-:10CC40002BBAEE41B9F488C0D09FFEB75F547F86FF
-:10CC50007A79C166581DC893798EEEC7B1FDBC675D
-:10CC600087B25A68FFB11099809BD9AEB4E804DC52
-:10CC70008774EDCAF0ABD4CF8B4BB1DF33CF3AA87A
-:10CC8000DF33BF7993C639F39B64D26BFAFCC1DE04
-:10CC90005662F538D8DBCA053E207B3B260FE32CD5
-:10CCA000C23CAF2F7CA5C93C947F8B3005BA5FB4E2
-:10CCB0006F5000FDBB31F5A89F65D6EE9FF869FF68
-:10CCC000AD668AB4778A66223F2EDA611CFF3FDCAC
-:10CCD000DCAE5A66E99ECBEB873239DF76503B4BB0
-:10CCE0009A46AF5A797C7BBDBE94966BA8A7B75F76
-:10CCF0006A659589F8C0A5F5BB68C797238CFD7157
-:10CD0000BAED3D0EFF7EB7C0C87FC276DB29EE6C60
-:10CD1000B1253A3C15F8F6050B9B8FFCBB38253A3C
-:10CD2000DC05E3FD4A939B8B93200FDF33B57960DD
-:10CD30007DCC335BE719C4EB9217ED74AEB2E4859A
-:10CD4000373F437C9E421803C64EA5757CF653A020
-:10CD500083535B4C4C057B6D8935EA7B04F5D46EBF
-:10CD60002B6B43FE7EE915D25BA79FB38AFD9D53D3
-:10CD70002F890035D87AAF432D6505954E8CB709BC
-:10CD800088ADB86F386C0AD7C0D8555260E5B3B8D3
-:10CD9000BEC366DA679C9DC30A705F799665FA55D3
-:10CDA000C2BFF2A604E52B5E350B89E290CCE741C9
-:10CDB000A88F033E387F2D532095CE0FA37485A5F1
-:10CDC0007204CA5D930C8B2B243F01D9ED66B79F8B
-:10CDD000CD8374452A0B22FC98F39A0BFCF57B401B
-:10CDE000E9F2879521D86E521A972B73D20357A672
-:10CDF000917C71CAE457D2E854DDCBE7F9B990E4ED
-:10CE0000AF8179E59DBFF73684EFF2770525F6FC13
-:10CE10003C3ECEB34A52DE548A69BD248FF2E424EC
-:10CE200086703D2BF3B8BEB3739441AE18B9BCA65F
-:10CE30005A26F9D158EDA17475750153C8BFE6A7FC
-:10CE4000BC495BBFB550A53835E469FCB33ACB02A9
-:10CE500068E7E19CF2153CEE0F121D593D95E49BED
-:10CE6000B23919ED634D4E95CD83D4ECE4F03139F0
-:10CE7000CB083E162D2FB54C2778427BFA7E797A67
-:10CE80007011C2C39635D220972CEEB1867C2F78D4
-:10CE9000E9F8DFF57F053746706AACB651BABA7A61
-:10CEA00022C1ABBE3A40F9FF07B83DC0E17631C6BA
-:10CEB0005AC4C0ADD490EF136E0F03DFB863F90608
-:10CEC000E0887CC392FCDB13AC3F3E7DA81A17C7F9
-:10CED000D803D52D94EADF53FBD0DB9FA4713BA090
-:10CEE0008A056BCC74BEC5FD2DCCADB2AC093DFE40
-:10CEF0004DE651998279E455C4CBD12482DDF2B755
-:10CF0000EDE43736C95257AC5C5B7E9D3204E59741
-:10CF1000A9EA517662708C1F6D7A995D21B8FA0585
-:10CF2000F4A7D66A7AB3FE02FE8C7CB0A65AA1742E
-:10CF3000ADC60FEB357ED88078867CAD9F9F6F366F
-:10CF40004F63A417FF05F27C1F1F65B171262E7F6A
-:10CF5000246A067C938C54288D529CEF516B381FA9
-:10CF6000E3A80A19C5D1B98EDE43FE63C6221EF4BA
-:10CF7000A7B934B8B1FDB9AE99C9B43C33D73BCCED
-:10CF8000C4D39019EDF178B8D6FA0FDA707FDDD7F7
-:10CF90007C4ADE5920E0789FCF243431F72D91A3CD
-:10CFA00015B00E67B383F46ABABF321BFD7BEC98F1
-:10CFB00095E8D3E90F0AF362F097DE875D7767FAA9
-:10CFC000D57F45FAEB4459067AE88196617684F379
-:10CFD0001A73C483F26E8D8BEB0FA51CA0F0DD9E3F
-:10CFE00076AF687230A5D8C8EFBA7C95278F35D058
-:10CFF000AF2E5753A718E95C97ABCFA7717FC59C9D
-:10D00000F4B24FD2201D7C7E33F1613CDDE7C917BD
-:10D010009707DDA80798BF09ED35B419D18E7B5766
-:10D0200008737AE7FEA9B39D396D68E7C0AE80E466
-:10D030008A8AFC4078EA7EF92B68B74B930F2B6DF8
-:10D04000336CB8DE06A02386E77A403F08E07540DF
-:10D050003F9886807E387F4CA454A74F4F7A8E210C
-:10D060002ED0947748E4F1F222F99E25D8DF396179
-:10D070003CE9C0241BDA7B92D97F18E55477B218BB
-:10D0800041BD59EF9C610BA0FFC6554C78FF2CB9F0
-:10D0900022BBBF3827B05BC86F2B3BFDEC388EC37B
-:10D0A00018F96D4DF25886FBC45DCE8E24DCB7585E
-:10D0B000D345C3BCE6A407BDE931F9D138BA862F00
-:10D0C000EC7697D64FFC7817A56B7ECB2C95056236
-:10D0D000CE2DAA74FA5654362586BF57E64F6518EA
-:10D0E0007F11CFD77DCAADEDDF4E6ED56687095F64
-:10D0F000E67879E10639EEA45415659CB777CD8FB3
-:10D100008A88AE2E4DC7FDA1B3ED821D72796E02E5
-:10D11000FA3A3A7208C5675ED033B06B2E243DB33D
-:10D120007122B747343DC3F5D3D96607E9A7B37376
-:10D130002A299EEA6CF31005E9EEC0BA4BC6203CE2
-:10D14000E69E6F640ACC6FDEF94994CE6FF939A57B
-:10D15000152DAD40E48CD5AC9DB76E26B43BF1B037
-:10D1600089E283BAC2E3CE5441BEABD9CA4C304E39
-:10D17000D7E63BB3D12FDE05E3A07DD5B5399FE8D7
-:10D18000AB0BE046F906637D8C0B36015E2A18C7AF
-:10D190000BFC2F80F5E7BE626A4D642755ACB706DD
-:10D1A000129DEF5C286F496CB7D5E23F33F07F9555
-:10D1B00023105E25EFDC938DEBD5F97F452AC8233C
-:10D1C00084D73B5696C81F7F79FA9573912E2F4FBF
-:10D1D0000F2CE578494DE85FEBA17F3EEE0911EC9D
-:10D1E0005BC24B30E506839F95FB314F68F62FB34A
-:10D1F000F5519EA2B59713972F69FEF8D0FD0CEF5D
-:10D2000029549621D1EBFB691383FDB480FBDF1B0E
-:10D2100028FE599F0FD8A944C70CF081F2658EE60D
-:10D22000EF01B87FCF02DF4FBC6212903E7AE8294F
-:10D230009882768BB0E6BA95BBA0FCEF87F9FE6CBE
-:10D24000C1F90D24EF8435A3374E82EF77BE6226F5
-:10D25000395FD374C9FA5B00BF9FBE66A2FCFCF3C2
-:10D2600076AAF7D1FDFE8DB740BDEEDF99C90EFF5E
-:10D27000F4F09514FFF891D9E827983084F3F1F38E
-:10D280001A3FCF3DBF86EC0FBD7C6EC36C8B4274E2
-:10D29000BA8EBECFC5439B4C9CFFF7FFAD44C2F393
-:10D2A0001C46F7149E7FE8866B57925E1B4BF6FE7A
-:10D2B000BCB5567FA278D0E7D31583FC99D7D94C5B
-:10D2C000FD32B08BDCE95A7F317264DEF9C1C407EC
-:10D2D0004C5619C619CFD5E4C985F96D361BE4C97A
-:10D2E00047F6C47E9097D3F93E6AEEF94B88BF7A31
-:10D2F000AFEF32FA3E571FB793F363CF7A364E4AF9
-:10D30000B49E9E754CA6FA1FB9128F7F52836F5739
-:10D31000F57C1600B95461857A4E1CFFCE55138BEF
-:10D32000711DAE5421665DF35A16B140CCBAE66D5C
-:10D330009E65A988E9B7070FCB0C783899BE90F0A5
-:10D3400070677AD911E49B8A35978E417A9CD7D23F
-:10D3500048703E61F6FB50BE7ED072674AA238D854
-:10D3600093F1F869D1F003F66E710C7E74BCC4B70A
-:10D37000EF7A7BDE6718D7D4F530376EFA82572FF5
-:10D38000BCE524869B3484E3AD0BF46D90E0A6BC31
-:10D390007014E97AADC38F74DD37FC46B1607FF05D
-:10D3A000EBC37E057BE74B943B12FA68F11CB28518
-:10D3B000D3C14070EB1957A38392C4EB197B613D35
-:10D3C000554C05863D6E19880E7ECA545B3FEBB8FE
-:10D3D00040073F37D0C1D88D4DD7AE847A1FA2BD4C
-:10D3E00032A237FE8F5BD4948BF1DCA7C944E74AA5
-:10D3F000C793D4F49B79BE08E5F1F194D0F5784E4B
-:10D40000A3E7176CCF4F991533EE070D008704F093
-:10D410001B3B4431F8A12ED04F9ECA0A27FCF3E8EB
-:10D42000E78439F13DBECBD34B260C413B2594D844
-:10D430005FABA7BABC360D725ED867A2FE3CEECCDD
-:10D44000FD2C0CA5F5E9C1D221E3317EF427B7A16B
-:10D450003C387E5C207D5BF3F68A11A8D7E2ED04B0
-:10D46000D87F36E0B9E70A537288EC50A9721B9D49
-:10D4700083AA12DB5E8CFB94CA4DEFE5A3DFB08A72
-:10D4800052A6D9A12B4C23FD4DE497AD7C02CF4988
-:10D49000814864AC2FB14A3A3705415886F98D0E60
-:10D4A0007EEE5A25D9646B4C5CC2624D9ED757976D
-:10D4B000FDFC3DF443DB5426A7637B2E3725C6EDE8
-:10D4C000AFFFC479C6E87B8B3928FB711F2AB032C5
-:10D4D000E40BB314A47B4E668FBB488DC1C3C2213D
-:10D4E000DC7EB4B7B737E4407BFBEDBF93510F5AF6
-:10D4F000611CF4B3D9B2A4B3B1FE6AB33B42F7984E
-:10D50000585ECC77B0AB9C859037F80160BEFDD8F3
-:10D5100085BF12FC9ECF901E6B383C26228820FDD2
-:10D52000F39C61AD2897274A75268C3B9A797B3E00
-:10D53000E537CEFE6A7867027A98B97F7507DA33E5
-:10D5400033F767CCC6F38399CEE1EF630ADB055B63
-:10D5500012B47F5960912648A7D81EA5B8C6973542
-:10D56000FF583BE663F462BB466F60E74CDB0DE9B6
-:10D570004C5BC87C47618F3F2D7EDC0D1ADFB79B6B
-:10D58000236923910E601C5CC78FF787BF0FAA9F8A
-:10D59000DD12095F371AF0732BEB36231C834CA680
-:10D5A000730FDDAF5BC1FC5A9ED1FEF42F8BCD6DA6
-:10D5B0004827F1FDDD12E5FDFDB81DFA83F4D6C361
-:10D5C000DDFF8A6A391891A73A584C7FFBFC871C0B
-:10D5D000AC777FF170F64B36931A03574091180BD6
-:10D5E000F75EF01D547E0D1BD3379FF5C09BCF23F4
-:10D5F0001E1F9F6211F0E9234302BB906FEF1D12C3
-:10D600007806D3C5B66E9F047473C41D7C0EF34BAD
-:10D610004DC1EC7480C7696F70441AC2A523F1F93B
-:10D620006B3C7FE7959FDE827C736B8DC410CFAB24
-:10D63000F67EB005F9F2B419F808F6032FDFF341CE
-:10D6400032D2CD1260C05879F24E553ED94F67F7AD
-:10D650008CE8F7BEC93B9ABFE4558D4FF475DE8662
-:10D660000C08E3DDB6C741FB99DBAA4C17F6594815
-:10D67000EFB755F1F81026758CB9C96077D669E710
-:10D680006CBDFBC17D447C3F5DD5C16DC4F752705C
-:10D6900002DADD27AAE76F43F9123F4FC5137C7BFF
-:10D6A00008E9B75986B8DB39CD0BB6C5F2A15EBF24
-:10D6B000B60FF9BA7FB8B64E1B1F8F29DF29714EFE
-:10D6C000A07B99F4678FDADE1562E861A0F158DE7D
-:10D6D00094C005B940F7E545E64CEFDD5F7C3DBD04
-:10D6E0007F4FD515ECC4385C5FE0DC90F103CF9F31
-:10D6F000793479A6B5D3BFDB83218676A1FD8B4132
-:10D700006427EC1FCEFD0F9F6A760173C27A91C128
-:10D71000421B03FF1FEB8581E95EA67DB335615C8B
-:10D72000519A47E274133954624B30BF5EFD452570
-:10D73000F675EAED1FCEA85F749391BF6B7812ED7A
-:10D740006B2AAA6A699FDD08F203F541FC7C8E37DB
-:10D750003DA2A01EB05B420AFA451B87A7E7AC8436
-:10D760007620D5C8EF634F0A2952EC77CD1F645F4E
-:10D770001952707FDB989F49DFF5FE1A052E6775F9
-:10D78000BE68847DDF73E417F37B66605CE91BE1B0
-:10D7900069C9D0AE6D158B9A7C8C1DF4658EC27DE7
-:10D7A0006EA8DE42E77B8D0562C61CC8A7786DE4D3
-:10D7B0001F6B754567E23D5A559048BF865CCAD5D8
-:10D7C000C9E8DF5D39A403E5DFC13B2CB4DE359346
-:10D7D00044DA8F592F7E2F7405F67F17F3A35E6D01
-:10D7E0003BFF7C8B13E5F051D8CFA2DF103B0579CE
-:10D7F000D436EDAC1DF773A918570774B3D91CA123
-:10D80000796DAAB152BF9B5A2DE589F0F77E864407
-:10D81000F5C34227C5070F66113BC2F58169333650
-:10D82000E641BB9C3C26E37E7E4DE1596DBF19303D
-:10D83000F1F328DD8FC8ECDA79964D3BA7B2C5C667
-:10D84000173E12DA43FE43C7F4084FA789E47F8EE0
-:10D850009FC7520FF7E33926774C433DE1281699CD
-:10D8600080FECD3C26E0BAE4696D748F39A780F55F
-:10D87000D19EAF5B0E40FB62DE1E7D42F2D76C3F55
-:10D88000D7C3E30CD7A21F0ACAC366BF7035CC2327
-:10D890007C9D2CA84A4FBD6A0FD7AFDBA0FF28C9DB
-:10D8A000D130ADCB57108922BDF9168B84A7B513A3
-:10D8B0008FD3B9C003C5BA1FD54FF3D85C73E4004A
-:10D8C000DA5F9BEF6664276D46190AED365FC7C2C3
-:10D8D000FC3C8965A27CDBB4C0722D9DE71702FC7D
-:10D8E000054A13CEFB4719365AB7EFBE07A2784F49
-:10D8F0003FC9CFEFDF429AB07E6D8689E6BFC91C73
-:10D90000CE40FF485F743143C387AF4AB3AB58C8BA
-:10D9100083785DA7C187DD3496FB17A480121BC7EF
-:10D92000D5A34FB81F03D64771AD83EB2CA48FC48A
-:10D93000E9D199B8AED4020BBB2A07F98BC34D1DB0
-:10D940002DF2B833166E41FE6CBD289DE249578B0F
-:10D95000610FDD132FB5D079F2C189E2CCF950BE49
-:10D96000BECE427E08C813BF8402B9ADC86F8EC94F
-:10D97000A5E5F321BF41B6C808DFDA42D98E745C51
-:10D980001B106501F2EBCAF47B128CDE3128329950
-:10D99000EC0550BE2D43441F2DDB2608C4EFF58156
-:10D9A000D2D030F85E2FBB85583FC05E0DFF8BB2E2
-:10D9B000CBF67A906F020F8486291C97D20422310D
-:10D9C000FA4B66D1F91873D35AFFF851BA0F556460
-:10D9D000A3FBB3DEBB42E574DFF1228B82786D3BA3
-:10D9E0003F7814ADAFCEA2203F6F10C25723DF6F38
-:10D9F000BEE3908A7E75FBFB4E8C1D66CECE4FAA91
-:10DA0000317ECC596C893BC76222CA717D5CE71BB1
-:10DA100051A2A74E21F8C764F2FF143615B8299E0B
-:10DA20007902C273DDC56F15CC4D4017D0DE993E2B
-:10DA300016ED65313A610CCA29AEC7982467C4E275
-:10DA4000778337F3CFE867DA5A02F3C7F1AABA6EE1
-:10DA5000A179058EFC14ED2AE7B18FBE4C3CCFD7DF
-:10DA6000498F241F7344C531982E994EF6596C3D49
-:10DA700090FB8DD981BF7A00BEBB6AB8DC6FBE9DBA
-:10DA8000D1BB13F8571003DFE64290D2F4000140F7
-:10DA90001EEB15CAE4475F2D2A9128C2738C8DE8CE
-:10DAA00069080B925C8B5FAFE358E31D1877E4F0D5
-:10DAB0001BE77956C32FFE49E9745E819628B3644B
-:10DAC000CCB1A3FCDB3D56C9C0FDF603AEC47AFE63
-:10DAD0004F197C5FB44B486C9FFF2DC3CEFB075999
-:10DAE000199D40A86214D70779319DCE6DC8C96DC4
-:10DAF00015B95C60D730D27B29459D767FCC784FB5
-:10DB00006BE3D01FF433486BC7E4EE680DACBF1570
-:10DB1000A816EFB5A578391C9D6A0F1CB1BEACAD37
-:10DB20000BF8A06644310251A6FAACCC42E72220A1
-:10DB30000DD5AFC41E38246BF5374D94041BCC2B88
-:10DB4000178021407DD7348BE11C45AE3BA262F9A2
-:10DB50004F4D4C499DD833FE9622165E09E30F0ABD
-:10DB600018E19D7CD70B2BD02E8FA7039CC1857EFF
-:10DB700031547C8EB15DFA2DBDF880E049F304D0BC
-:10DB800034BFC1DA2C0094E61D921E1F4BF277BC05
-:10DB9000A943457F280624ED85F98F7CF28DC04E80
-:10DBA000C83707399F2517BCB002E9D291C9F1F4F3
-:10DBB00047F42D43FA0893FF8E713B6A95A8203EE7
-:10DBC000B64673498F3732A90CF1D458794444B919
-:10DBD000BE660FF30B02D2FF7F5B63E77753460EFF
-:10DBE000C7BBA490FC937CFCFEE89A42D181F2F57D
-:10DBF000E01D2F90DEDB724064C8FFA5BF3DF6B08C
-:10DC000003E9FACF56CA37BF524972E327D04E4DC7
-:10DC1000E03F1F482FC7D7CF5BD226E0F944F6FC80
-:10DC2000C82BC3513E8724FF55888FF91D0184936B
-:10DC300052CCCFD99CD3A3F44E88825A0D6C522576
-:10DC4000A4A5CDBC9CDD944AFBA8D1D6CE866B6042
-:10DC50007E8F3C2931D497266B24631EF46B7AD1D6
-:10DC6000899AA0D7FEE891E9D10C94E3499514066E
-:10DC7000DD6B7E6F67703EF44D575E1D0EFDBA265C
-:10DC80007358DA43430EA0BC449B19EF553854AE89
-:10DC9000E7D649E100C679AFBB2B68C1F199B67FE1
-:10DCA000695C52F138C2F984A6F758E57C7AAFC4B2
-:10DCB000A7F18BA38A9524DA673DE049E2F12DF7BD
-:10DCC0008B07903F7C0146FA43AE8A4447687A1935
-:10DCD000272EDFF75C23EA17E76291D6B14EEAA858
-:10DCE000C17725D6DDC5E41AA5777FFF68FBE51966
-:10DCF000567E2E8A384EEB5907B9E440BEF9E62726
-:10DD00005E4708C71DDFB38E247D1D059D94D7E7B0
-:10DD1000B12D10F95AF3D8A0AD634D067FA7C851B5
-:10DD2000D849EFB3C4CBFB958E77E8FD9830D8EA9D
-:10DD300026BA8F16B906F3CAB322E3F7B58CFCDD19
-:10DD40002BAFD155FC7785C58C938374C7F10C74C8
-:10DD5000A7D94FC077361401A2F215F93142FC9DC4
-:10DD60009C387AFCA7CBC5D87943FFC90D4CA0B825
-:10DD7000B8C54C29CDE82D179926176D4C8DA2FCFE
-:10DD8000FBBF968B2007492E36C34A07C34E25B9E1
-:10DD9000BDE90ED4E3BA3C1C8F38C177A254F375A9
-:10DDA000A585B42FA27CD1C3AF36D37B43A276DE48
-:10DDB000A5C105DD500897CF3D8A419F3E84FF8075
-:10DDC00075EC6E4FBDB610C6DB589E5B84FB0B7BBB
-:10DDD000E845B20F7C853C7EC557C5CFCF1D797312
-:10DDE0001F8FBD17B730C342F4B750A7BFAA900723
-:10DDF000C75987FDA27CCEB390BE7C8445B83ED483
-:10DE0000ECD3168F1647ACD1553C9FC4CBA771BF3E
-:10DE10007397A27CCF10AC32EEE7503F1F4C37EA2D
-:10DE20006BA4175D5FB774AC74A13F2C47F3F7E7A1
-:10DE3000D88C710E45995C5F7FA5F901568B95B41E
-:10DE4000DF544B45DAC7E9F477418FC7C1311E7EF5
-:10DE500048A8AB26507C0CE5534ABA19F2EF56207D
-:10DE6000D90D5066CB5034FB402638B7FE581C8B7A
-:10DE7000F272777B851DFDEB82CF7635EE0FD70BE7
-:10DE80002C8A72737DC9EB1457D254053DC3A29CF2
-:10DE900005E22CCB98DE78063EA6FDAA43B576A017
-:10DEA0005F2B126DA3B885A6F0A1998CDBB10CE3B2
-:10DEB000529A0A56662E44F95E50568CF86DADB7EC
-:10DEC00050DC8C5CC012FA11DED7F631DF548F398A
-:10DED000F4FDE5E2C4FBCA6B32F9FE362281A8826A
-:10DEE000F96415887EE4FFAC3A4BC2795CAAE1295B
-:10DEF0002D93DF0F6BAD3F9441EF63899561D61F82
-:10DF0000BE60FA2BD363F031A90F7C78747C483A59
-:10DF10003E5CB3880F3B3B442E6F49AFAD63F2CDFF
-:10DF2000A81FD54A0BD9B18D66BE2F6F2BD4F842EE
-:10DF3000B6B522B17D53BA4E5922D23D1CEF449161
-:10DF4000F6898EC5CF515CD323ACFB1594778063E3
-:10DF50001A2FBE7D79A6A8C15111FCB49FE67804A2
-:10DF6000BCD27C36E7A7B7C6F2E9039A1DFD8087CD
-:10DF7000F3E9E6FA87884FBFEE3C75B95DABD9D1BE
-:10DF80000B02410BAA0355289B9A81FAF331E6470D
-:10DF900038319393ECF20FB1498C5FF6CEACE0C20E
-:10DFA000CC98F345395049EF165E89EF0A41FB0FD3
-:10DFB00022FC3EE80791E74BE8DDAD2023665EC01A
-:10DFC0003A04627290A1DB21EF912254EE990F7313
-:10DFD00071D1ED48CADB6CA0176142A7ABF9FD8B8C
-:10DFE0002EEDBDC8C7B5F7223FC6F721211DDDB212
-:10DFF000BAF4111C4F918228334EE27B9178FF795D
-:10E00000E25B14177D0A646D930BE3617E5542F762
-:10E010004FEE65B23809F36B4B31EEF9CE97ACDABF
-:10E020003DC98E9578EFE55111D60D6DD648A0EF1C
-:10E0300087615183501943C7BB2EED48C173BED3CE
-:10E04000911BFBF51FE3FD417A2F3393E369836353
-:10E0500029DD2F9BEB8CFAB0FD81DD4F3CBE09C65C
-:10E06000FB78AF8DDE35D9E858EAC3F28F1F7ED337
-:10E0700087FAE2F4DE372D89CE27974891A9788F69
-:10E080006CB13A88AD84F99744665928FE64E7017B
-:10E09000BA9FB6440E5AB0FFC52DBB293F65E71F96
-:10E0A0007C58FE6626D713A733823EF44BE4B5585E
-:10E0B000A322E89F5DB9A18509CFD933456DDE2F35
-:10E0C00051FF1B1D2F1D42BC9C7ED84A7EB7030FFB
-:10E0D000FF96FA3DB5F7459AEFC7BBDEBC15EDE9F3
-:10E0E000C58CF9519E9FB66B7E3D5B474AECFE7630
-:10E0F0009F060F3D7F3A59DB07670D504F3B8F61FD
-:10E100004E803FDD1FE848C1FB851F9B831684C7F7
-:10E11000228407A425000794FB8B2202CD73514B68
-:10E120002BDDB75AB487FB071701BC082E2D0768F3
-:10E13000FE4732B9DC38B5F78F3E7A9F628F95F68D
-:10E14000CFFABA1739833E848FBE5E80035FF7AE85
-:10E15000AF87A7B93A9E5AFE40F35ABC87CF6BF1FE
-:10E160004E3E8FB97B004F4EC4D32CC2FFA9BD4C8D
-:10E17000C17B305DBBDF3C89F6CCE9BD3605ED0ADD
-:10E180007D5E59206E53C6221F717DCCF608A48F88
-:10E1900099D441E7394B6459C6F7092E94872D610C
-:10E1A0002E4F3B4A8742F9D30F8AF48E25932323BF
-:10E1B000D1BFFA61A67EFFA7C3877EB15D9786882F
-:10E1C0003E3F4AD6E02D75F8307E66C3D0E0879991
-:10E1D000B1F878F7C591B8EE15A6CADF7A719C2719
-:10E1E000787CE8E7B9957FBD9FE63DCC70DE189F4F
-:10E1F00002DC52F0FCBB406441BA97BCE7E5A4D80E
-:10E2000073E82F33B9BEDAE87887EE239EC6F71C91
-:10E21000693E118AD31A1EA8F0E139DF47CC19C430
-:10E2200073D98F1F7B99E26DBA3274FF5307D53BC8
-:10E23000B5E7E5544C2BB4787816BE91E418C0B11C
-:10E24000C13636917CD4EE1785F9BDB13302084C46
-:10E25000D4135B7438575A6618CE75B81CCDDA9C47
-:10E26000D34EFE9670E2FB66F1F237EFC14974AE11
-:10E270007C8E253E57665A9CDC0A5312C5DF6C74AF
-:10E28000FC8CEEDF56A95619EFAF1CD7E4E27BDA1F
-:10E290007B0B9F27A5A822D0CDF34383DEA169BDC8
-:10E2A000EFE156AC59E243F856E0B9076D6AB65D46
-:10E2B00087F1845D694C7B9F9445097E66BDFC5F58
-:10E2C00078B98BE78B873EB316ED13842FB7531FB6
-:10E2D000BD0EE31ABB7278791996437E566659E1F2
-:10E2E00050EE3711E81C89995D5D36AEC213C1A3AB
-:10E2F000072E12EBD2ED6AA83C7B2823B8427F138D
-:10E3000086D2BE1EFA1BFDEDFB03BCABB6D4FF8567
-:10E310007E6CFF5BFD44482F89417CEB0ABEF9B956
-:10E32000FE7BB494C94DAE6FDFFF3FDA7E852920B6
-:10E330007E8474384824BAD7F9BAEBE11145B8FFA6
-:10E34000B734DC1145B5D9955C6AC980EFE7147E16
-:10E350007E72FB831B0CEFA8EA69FC7BB5FA399E41
-:10E360006598F17C76D5502E8F560DEDF113E2B9FC
-:10E370001C1E57D1C619FE9AD3291486DBE9AC526C
-:10E38000C4F8C382761BBDD77B11034101F31FC5BF
-:10E39000A222EAEFD1AC93F2DF411040BE882926D9
-:10E3A000CC8F63DD3E69189E3F4757A19D76C41D03
-:10E3B000AC43BAFDECE18E770428FF4966F0979DE7
-:10E3C000E8EF1CCAED5427988548CF32A64087A2B3
-:10E3D00063BA2791DCBF004F593A157BDE76831470
-:10E3E00058C7F9224BEE72F4C05997070BB5F7974F
-:10E3F000F4F6279F7C2297DE1DEA7907BCDFFBC07D
-:10E4000073AB163CF8D8B87ECA3539BBAB267C73E3
-:10E41000ACBE6FD3E0BC7DA868B00B6154B2E39E84
-:10E42000BA81DB4FBB2E0DAC7C14E56D8B89F6D326
-:10E430001FB5FC91BF8753C6C8AEEB6BDC8FE2F013
-:10E44000FED1F62732F97947D8A0DF173CFE8B9131
-:10E45000B1F1960066C53D81BFC341783FE457AD39
-:10E4600026A4D232F2C75858258F53C1F90EC3F7EC
-:10E47000B822943A5907A529AC9B5299C9E49F4EFA
-:10E48000657E4ADDAC8CD274562970FB2E44692619
-:10E490008B509A85F629FA7B5837A50ADEF88C89C5
-:10E4A000DFC8C513D361F8DE6E19FF1E171F2421C4
-:10E4B0001EC72590E7717141D28E2A92E7181794F2
-:10E4C000EFEEFD9E822EBF370C2DFD13CABFE787EE
-:10E4D000068E20FD1C7EE6557EBF62AD40F6F50936
-:10E4E000FB748B02A87B3A3540EF80A8222BDB0E11
-:10E4F000FA7D8EEEFFC73F3D4E1881D96C3E151B4D
-:10E50000BFC36CCE023C2F9EAD559DAD9D83CCD636
-:10E51000FC20F8CE19BFA7E7A7FBF6B3B5F387D960
-:10E5200071FE1716B21AFC282AFE03D6313B24D0FE
-:10E53000B9C1ECA4E92F75B2BEE924A63FBAF757DA
-:10E5400011E7871AD09F15979F13DFDE26305B3ABD
-:10E550007EE7F4F4F4650AD975BA3F0B084EA1764C
-:10E560000DD677C92F14BA32100BA7E42CBE6FB5A5
-:10E5700087AE4A49F4EE929ECE01FBCC9CDABB3DBD
-:10E58000EC085DC8F7BA1CD6E93C0737B6C84705A2
-:10E590009684EFAEEAE91A4DDF37DD1F62386F7BF4
-:10E5A000F41E7A8FFA6EAF4ABE5A5B6198EE07246A
-:10E5B00015843D6A82F935E13BCEC05F4DC9C67313
-:10E5C00093C5599CFF1767F1F3DD4317A597E279CF
-:10E5D000F66A85BFEBBA5AE1BF47B03A6BA0F7C8FD
-:10E5E0006D867BF2AB066FA57780EC5F6C63684F3E
-:10E5F000DAA5C4F7526ED2E0BA41ABBF71F056F261
-:10E600009334E4F3F3FDF8FA07F21FA2F71F1B732C
-:10E6100060BF8BE9FD2AF55F9FFF5039B6B7451BF8
-:10E620000DF7797F94C5E59A6D0FA747539E259CFA
-:10E630008BF4208528BE40AFD7D8C779D2B42CAE92
-:10E640008F9ACC61BA27D3A4D9438BB31CEBC82FC4
-:10E6500097D57614F9F55C1EA3F3467BF4493A4747
-:10E66000B01558985DD07E0F00E33B0A23841F74D9
-:10E6700036450D741BF3EEBDA977FF755F853CB879
-:10E68000BEC69C108D3FD07A2FD5E0D9A8E9D746D9
-:10E69000BBF11C6DAE86EF2B75B8EC67244FFA8189
-:10E6A0000BD97BD336E75E8FF3B1ED1B108E86FA64
-:10E6B00039AC7C50227E8997FFCE4231EE1D2581F8
-:10E6C000E6756E8FA0BDBBC8DFB1E8B1032216ECC2
-:10E6D000F75F37571CBC1AE6B330E80C60FCE41354
-:10E6E0009BDBE89EFEA217CD149F30BC7316978368
-:10E6F0002DFC7D45FD7DA38B5AAC86F7A696B09880
-:10E70000F71761BC45C73E3AC6E89EB1F1BBFE6E45
-:10E71000C01AFC90204E2DFEDD8175597DBC3B500A
-:10E7200098D84F13FFEEC0CE88487A6339C6B1D26D
-:10E730003E606B29EE7BAA8E09E437E8CD87CA9646
-:10E740003C734C5EF0133DAAC94981ED09F8E94FCD
-:10E750005E4E0FBBF0508DECFEFBD645B330AD6383
-:10E7600078DE547B9724E3B9766D3889EE97D4CA66
-:10E770006218E346BCC9A536F43F329728E33DB49E
-:10E78000A9A6C974EFC972B7348EDE696D5BD881F2
-:10E79000F7EA6A3D12433EF6BA781C01CB10E97DD8
-:10E7A0009A3AF975D76CDCC739F93DBD6C99851576
-:10E7B00001EDBA00C3F365D8AC5446C1F4F20A8146
-:10E7C00028BE77C52659E5EDFC9D99EB8B26901F59
-:10E7D00098FE0EB44E8DFE1AC709D8CA10FF53EE2C
-:10E7E00076933D18F69818C6011ECFCA21385A9262
-:10E7F0004BA36FE3FC663AC8B71B56C554C4C32B82
-:10E80000ADAB665C05DFCD6189E21D0ABEACBDF92A
-:10E810002A68DFDD6AA1FB163A9C943AC9F07E8330
-:10E82000EF3E63DE12F75E85C462CA21FFC72CED9E
-:10E830007C9295B3686C1CAF3BC00FDD6527BD5B58
-:10E84000D709FC49E71F5AFE4F5A7E87394478DFC3
-:10E85000F1B640FED583AD73B3495E3A966E73E070
-:10E86000BEF0283FC7EC4B3E3F9AA5E8EF7CD8B5F9
-:10E87000772AECE8F78AA7A7BA6AE6C738435BB8F5
-:10E880003D6914E2F7B0997E3FA05E938F9293CBDF
-:10E89000719D6EE2D3FA38FAAB37FB0B4250BFFEE4
-:10E8A0004B93B66F3C797D7432863D28B4AF3667A2
-:10E8B000313FB287D9DD9129C33C46BD68F1E3EF12
-:10E8C000334C7DB67010CAF9512FCF24F9867042AF
-:10E8D0007C4955163FDAC9D62AB75F1A87F59C449A
-:10E8E00097679D16B287A42A4788ECAFD6091E25E4
-:10E8F000765F512DFB2533FE6E8D8DD2557DC8FB85
-:10E900006C9758867E578B662FBBBC5C9EBABC0E3C
-:10E910007EBEA8AD739BA4CE407ADE0674837137A9
-:10E9200007EEE3F4BD3CC3467A73F92BC386F4E7E4
-:10E930001F7CBCDAE3CF03C06EBDAF82FCB625F707
-:10E94000BCD78874B73CD926231D9A52866F9C8CFD
-:10E9500074FFAA99EE79D6264F5066C7F4674A9994
-:10E96000E8417898443513E979F8965DD74B939050
-:10E970004ED44D789F7F8CF75FAE9740BEEC4856E3
-:10E9800033F1BC6C82F7619E4F533709507E997703
-:10E990000BCF7BD54C11F253BDAD3C9FAF6EC2FC8B
-:10E9A000F5DEED3C3F9AEBA31F789F24795E6BF672
-:10E9B00097A37FFA19987F613EBE93CAD3720D2E3A
-:10E9C0007AF973F8DD8CEFAAF234BEFC05ADDDBE3A
-:10E9D0003ECA7FA995EFEFA3FF97B476D13EDA1F29
-:10E9E000D4DAB5F7D1FE90D6EE701FE5AF6AE5AF89
-:10E9F000F5D1FFBF6BED3AFA68FFBAD6EE8D3EDA7D
-:10EA00001FD1DA1DEDA3FC2DADFC585CFFEF68F5BE
-:10EA10003BB5EFBEE486B7D05EF381BC427952903D
-:10EA2000DC40FEAEAD55C544FFB5E3B9FED7E9DD28
-:10EA3000A7DD0BE8F0F2B8D20E2FB76F966B745EBD
-:10EA4000724FDEFAC94887BFE3F714417F1CC57BCC
-:10EA5000B8EA3D22F9F796BFC2DF95597E8F44E7A9
-:10EA60001B3A3DEAEDF5F987B579D669E9422F7F82
-:10EA70002F2347F5F8A7C7E847B36CCCDB809F305E
-:10EA8000FEBFCECDF54CC13DA50D786E520B7A067A
-:10EA9000D757EFB444D1FF552F4B545EE72E0DE10D
-:10EAA00079BF2A4BA487EADDA9517CAFB9AEAED8B5
-:10EAB000F0DE679D2CD1FB31926B8A6DB613E5C6F3
-:10EAC0007419E5671D93534BE85C0DF669A84FAACE
-:10EAD0004A65943B392E772ACAE55BB3F9BADA93D3
-:10EAE000BBEC788F42BA5FA4B70286CB12F17B5E93
-:10EAF0009D1856601EEDF272F2BF6E6FD6CE1419DD
-:10EB00003F4FD4E5FC8E9F4D253D560B7A4C213D61
-:10EB1000C60615A5F7DCDF948E8DB2A0DE92334DCC
-:10EB2000CC0C72F9803795C6DDFE20D75BF9A0B713
-:10EB3000F09DB56DC58CBFF3E6B1915FB742629EA3
-:10EB4000C1317ECC035E6EC733D3743FEEB3F3F1B5
-:10EB50003DC418F80E0B19F556CE007A2BBB0AE40B
-:10EB6000654C7DAB4736E49FF26AEFADFA991FED35
-:10EB70009BA9CF6E267D7216F50943FDF2EF49A3DE
-:10EB800050BF801EB1B2DE725097C7BADDA2CBE98A
-:10EB90005A4D6FD4C6E98D81E5EEDF5F1941F42946
-:10EBA0001ADEA1E94BFE2EC73801A04B735020BDE1
-:10EBB000C2A420DDEF1F086E6673998CF6F840F052
-:10EBC00033A77DEA42396D0E4AFEF712DC931A082C
-:10EBD000BE7A3D8B6DE816D46B9F1E5B51807EAF75
-:10EBE00055E68E593B916E854174BF43D1FC0E5B57
-:10EBF000ABF7B113F9F8FB3D7FD95C87BF8FC50236
-:10EC000032F94B324A156C67877DFA60B2E3F87EC1
-:10EC100093C9C1D042B4E75FB428782E70F819EDDB
-:10EC2000FD06AF93E079E7EEBBA89D59A8F4F0F399
-:10EC30007E46F05E9D994A76B9B2C3A6D98D1FAFC4
-:10EC40000FE441BF62A780FAE7F7D95BD7DB501F1B
-:10EC500069FB0198D9F770FF13095BB4FA78D19D6D
-:10EC6000B1DDF8E334DCFF1C903CB176A8E97B53BE
-:10EC7000B2F03C541E25417FEEAD96F5662F968B83
-:10EC80007AFB005E1E42F1A5E725C0C3D3ED5AB959
-:10EC9000EA5E3F05E6B3DBA28F0F06F5441C4FD4B6
-:10ECA000E829793DF6BFAB546F7F7A3DFE3E17CC25
-:10ECB000E75A13ECC1727D9EF5CE8C9EF97AB37D36
-:10ECC000EB6BA0BFD34A670A6EE396B4BE978E7A09
-:10ECD0007B7539BF3F8C0C80FE11FD1EF105BCED2C
-:10ECE000B9414557ECDF0EFD674A21142D33751EDF
-:10ECF0007200DC96ECABB499457CBFAB4CC5F7BB5E
-:10ED0000F4764BF6CC223B67D9FE224A13B43B8CF7
-:10ED1000F767FE817636CBD718EF74F4F5A53B156F
-:10ED2000BC3753D9E034517DC6FD5F89D7A7B73FC3
-:10ED3000BDF3F51FE0786794CEF46BA0F6EA28C027
-:10ED400025413BBDBE7EBFBAD81328F2C1F74F3173
-:10ED5000600CE59654E9C7FA115B88EEB1D9CDA1F4
-:10ED600032D42700FA30C629E869B12F8F9FA3C497
-:10ED70007D8FE7AF888D0D9E8EF2F22E89CEDD233A
-:10ED800036D53106F2CDB04FA98129AD2C3A3216D5
-:10ED9000E3059AF73A49AED7DED5EE2944BEF25BD9
-:10EDA00018DABDCD977664E03BF875775BCA1F43F0
-:10EDB000FA8D2EF7DC1E638779B3791CB7D7152A35
-:10EDC000477EB4033FA23E6E34076DF86E8A9A21E7
-:10EDD000525CB51DCA5FA372AF56EE9F7615EDCBA0
-:10EDE0004419E7559F37675A29EA354F2AFF1DC254
-:10EDF000FC29E5F3A03C2C5B6424AF45D9153723EF
-:10EE00009C9E96FC95C87F4F3B9D32C66381AC2487
-:10EE10007D20E5BB293ECBAADD77F216713D7F410F
-:10EE2000FFF9B81EABF3F138FCE6E48E1B4AA05D97
-:10EE3000D2BDA2AC42FF8D773F5486F1895BEE3E96
-:10EE4000F2078C6F6D4A97E89D815D35D100D6EB56
-:10EE50001658471BFE2E52D58C0EDC8FAE658A826B
-:10EE6000F6FA2E614608F573779AC4DAA07E529EB0
-:10EE7000315ED559688C97CA5A6CCC376607EFF665
-:10EE8000513C5071098E9326280A3E1D5CDCC12836
-:10EE90003E3F3D2F4FC6B8EE94E2B838D8C9C67E83
-:10EEA00052A718CBDDD3E3E2B66E32967B6E31E625
-:10EEB00033E718F3EFEBF4E8E1E70FFAEF3D6CB955
-:10EEC000FB71867ABAF18B4114CF8A7044BB3D69DD
-:10EED000B8E4C77311AFA56326C6C1B19149642FC9
-:10EEE0001DF4253105F2D6A58CE4A935357200F75D
-:10EEF000AB56512E534943450EBCEDC6DFEB32D124
-:10EF0000B96C3CFCBC5EEE1F7456F2DF858B485139
-:10EF1000B223ECF70C926BFCB8758CF3C32E8EC940
-:10EF2000F378EF2D3EED1CC5A3C7A9115E6165887E
-:10EF3000B7498C7E3FD27BF77B6A14E6B156C9ABEA
-:10EF4000443B63B5D849E3A815CE20EEBBD330CE01
-:10EF5000DB84F1DE2AA5F1F8D8A9D197C2E68410A6
-:10EF60008F9E5922C58FD41F4AAAC3C3977AEDBD7D
-:10EF7000063D8E4DA7CBBD3E6E7FEE6E17C500FAE7
-:10EF8000C16FC96B437CEBF996A0BB95E2FA8B2A63
-:10EF90003B912ED975DC0E053D40F7B2F538313D79
-:10EFA000AEB0339BD3F707D9A2210E9CE28862E270
-:10EFB000C0E9E8CE8447172119CF7BBC456532CA2A
-:10EFC000999FEBF72F18EF179F2FA47383E962E047
-:10EFD00022CD9F8E76DD606DBCC16E2940EFBBC334
-:10EFE0009C44A8FF20E3F507E7ED5981F7AE7623AF
-:10EFF000E120FFDCCEE11C4FB719EDA1B2D1082F03
-:10F0000001F461566F3A167C2D741E587F2F4BB554
-:10F0100016F5A6EBF1266EFF742F5028CE72203A1B
-:10F020003FE173713F76DA2619EDDBCCBC076BE864
-:10F030001ECCBD4C467D97D9DE7103FABDE2F921A5
-:10F04000EC4819CBE3E4BE991FDE64E2FCC18648BC
-:10F0500084B7F8F8D2F878526FB64B3B87023D90F0
-:10F060008CF701E42B304EB0FB1E46EF0494BED863
-:10F070007CF3BF417F9FE55B6494D7D96F049F7099
-:10F08000C0BC3EFB45301BE5F456A9D3EE8AF17BAC
-:10F090004A22BF7FD64B5E6BF4A1A0DEF0FCE3A951
-:10F0A00017E91B882B92973E4A467FD5B675BFB7A6
-:10F0B000A5FD1FDA2DAA3984768BAF5DCF67901D31
-:10F0C00096FD06CF8FDD9AB15E95106E8BC95F7489
-:10F0D000D03B97FC45D25BDC5F34DA1408639EFDBD
-:10F0E000C54E71773BF6DE321FE3D5EAD3AFA1DF21
-:10F0F0003D1993CDF79D85D93A7F1BD72F590241F2
-:10F10000E49BF8EFC3B3F5F3C4B20F6701FE463FCB
-:10F110006AA1B8BB02B1A22107F9A1D144F8AC3071
-:10F12000294BD7C4ECD3EAD34B2667A7D1BE8005C1
-:10F1300061C3A09C17581098CDE73E5E82F49A0DEB
-:10F140006C86F2255BE506647655120BC6D0A97273
-:10F150005EA2FAF5E981C9D99ADCC3731FB3C6D29E
-:10F160004FA796B159A897E11BEA5DF3CE247EDE46
-:10F17000E336DE8F349978BCC8D5DABACD78AE33B1
-:10F1800016DF7B13A3D631BDEB5FAFC149B239A304
-:10F19000A641E8277BED28DDBB8C3B07C6FD2DC5CE
-:10F1A000E52C66E40745B850FE4E99BFDB5DC5E32C
-:10F1B000016AEF63029E05D46AF754D45BF9EF0E3F
-:10F1C000B34040C1F755688BA9E0FFA2C4BF1E1B26
-:10F1D0004BC5FA19AC83E218593B5378BC84F1DC77
-:10F1E000696B1FEF40E97E00A9CA44FB94512FDBF5
-:10F1F000F9EF4355317A279CDE6CC2FDEF7D2C2C54
-:10F20000093D7EB80EAF42EDF4F3D85D5FBE43BF5B
-:10F21000C75C20B6055F23BB21596E43FD9864E4AB
-:10F2200043FDFEDAFD1A1FE2EF490763CE8F7CEA49
-:10F23000718AB7CF66DD35B8CFCAAE4A35E0F982FC
-:10F240005FF6FC50161C17DB6F98F3759E44EF7445
-:10F2500029E77D54BEB55A19A0FFDC3EFACF207ACB
-:10F26000EABBFF2C2ADF16FDD4753D80626BF77B6D
-:10F27000AE32A5C76E8D87B3EF3EA3FCFECEBEF8BF
-:10F2800078720E17BB39E0BE01E066BF5FF4B7329B
-:10F29000FCDD1B63BD6939E75CFCBC5CAF1F75DF3F
-:10F2A00088F561DFDBAAE0EFE818EB9795BCEFE2A9
-:10F2B000E7EE7A7D3EBFCBCF1BEBC5E3277EBE30AA
-:10F2C000AFB4EFC7CCEB0A9BD5505E3EABD7BCD2F8
-:10F2D0007E1833AFAB3CC6FAC19AC4F3BAB6C0DAF3
-:10F2E000EFBCF47ADF9BF8F5EAC5AFE3C669D63E1A
-:10F2F000E0CEEBFFB0FCEBF5FBA3F9FDD7BBAD2AED
-:10F300007E1C95E409C8CD0E944F154C5985EF84A9
-:10F31000336752C2B8E0C91A7F9C423F059E930EE4
-:10F320000DBC89F2F1A497C7FD1E7E666108CF610E
-:10F3300096EFB52878DEE1D5FCD620781621FFEED1
-:10F34000B6C92E8C07147D8A763FAA2307E3F97687
-:10F35000EF387233C93D66B46760BF5682FA1A440B
-:10F3600018DDCB780DDBA5C5C65104C8FEAB17FD73
-:10F370007FA47DD50FF8BE4A8FDF8FB5B3D8841E2A
-:10F380003B4B8FDFDEA08D733E9BFB03C1CE570549
-:10F39000B2F3258A6FFEB9AD6303DE3FFAB9DBED48
-:10F3A000C2FDCC416DDEBADDA8DF6B18322BAFC8D1
-:10F3B00094005E17F44852CF7D098CA374E5E5D123
-:10F3C000BB1868E78D2DC47E395CFF07CA89A75634
-:10F3D00000800000000000001F8B080000000000FB
-:10F3E000000BDD7D0B7C14D5B9F8999DD957B2BBC4
-:10F3F000990D4B1E3CC26EDE8100130831A095258D
-:10F40000448C96D20D3E0ADAE292F094BC00ADF143
-:10F41000CAAD13121110356A44A0800B8A62AF681E
-:10F42000E8450D08DE1035B5B7D886B6B6D67AF9F8
-:10F43000AFC0452A086B1FEAFD17CBFFFBBE339315
-:10F44000EC4E7655AAB7F7FEFEF187B367CECC79BE
-:10F450007CE77B7FDF3973AF893156CA989A2F8555
-:10F460007609F05B666C4D19636EF8C9B2197B447E
-:10F47000EE734B50FF88479255A8EFC9F232368998
-:10F48000B1BDAF994C7E0F638F7D3777A7E81B28FE
-:10F490006F0A7A766079A489053B1DD888BC8CC137
-:10F4A000FDBD36D9BDBE048A529FAFDA09E5DDBF86
-:10F4B000B949703196398A517BB5CDD3D989898CB8
-:10F4C000BD6889BC7A11C7B35108ED82765EEA281F
-:10F4D0009921C1FB0B4F336687476BEFBCEE9193CD
-:10F4E00043189B7C529E86F76BB7BA1511EE37F422
-:10F4F00035CDC07E581353F214C6D2C569A213DAB3
-:10F5000049BFEFA8D20A437EB4C7DB158672648771
-:10F51000A0ECF462FDF292E5C5F0BCC3EF75C07CCF
-:10F52000E7E350E9BE7B8619DFBBCEA2B4413B675F
-:10F53000CD6C4E273C7711FFA60E5CE77FD75BCEE4
-:10F5400060FCF33BEF9C4FFDCA00B24C28DB641A11
-:10F5500087CD2BA7B640393D89D9EC13182B5B2DED
-:10F56000F7DE85FD2F75CA3B01C6AE72B9F7873845
-:10F57000AFA62C5954B0F310C1416F7FA13F606119
-:10F58000D0EF98DD16688CD1DF45F837B633B63C3E
-:10F59000BE2BB65CD21D5B9EF8466CF97998231B96
-:10F5A000CAD814DBF06D2701DE3D87AC0CC7BBEC7D
-:10F5B0004C52C80AF03E60660CE7AFEEB1123E4C0A
-:10F5C0005FE6F0237E9CF920698715CA87DF49A290
-:10F5D000E76FFD173B7FDED4F91C96D5E792193E05
-:10F5E000BF6C4867592A8CFBE5CFC45B02C57C5AC7
-:10F5F000666CFFB9A21DEBB17E6267990CF75F1CC8
-:10F60000CD581FD64BA17138CF17FF2652BB91673B
-:10F61000ACA19DD0EE99FD4F3F87F03AF3CCF0546A
-:10F6200001C67CB969E7C4F558DFE2F4EE84FB5308
-:10F63000CE3C9B138C5A9765BBAD31F35CE61568E5
-:10F640009ECD927FF513B83E47CC844F2B17866A28
-:10F65000BBE1FD954296A2623B16C0D3622C2BE91A
-:10F660006EC0D7292E8EB72BED508EB3EEFAB5664D
-:10F6700093C8821307CAC7D73D4DE3293CFD36E145
-:10F68000F501B36A4A4238AE13945D30FE0376D773
-:10F69000389682D7AC10E2CD3F794D343E98D70FE3
-:10F6A0001B102FDE14959D2C717F8519BFDF5A39F1
-:10F6B000F173EAA15FDF38C6CEFF21E9163F8CA3C4
-:10F6C0006053ECBA178562CBAB113E806F352CEAE4
-:10F6D000BE0FC793BD2683E884D1780A4FBF7B93C2
-:10F6E0000FC63BCCCA9A102EC67EEFC379403B3F73
-:10F6F000FA11B45348CD881745DE9E370DD641A385
-:10F70000AB97054E47F077DB70A0B76502E72FFA9D
-:10F71000FD658671E8ED976A70F2589407C3B4FEF0
-:10F720005619D7FF83BBAB1E39691E3C9E5377FB2E
-:10F73000FD9551F7176D5ADE9B09EFD5ED1D3A4146
-:10F740008C826FDD33AFA6DD0CF7CFEE96146481AB
-:10F7500075739F7A600A3EF78CD889E3C57A3FCCEF
-:10F76000F76CE7EB2E7C6ED156F704D13BF0FEE24E
-:10F770004D57F92B0B07E079A974FA5239E773CB8F
-:10F780003ACD211BD245E75B3386239E6E12943C13
-:10F79000E8A74C0A8A4877CE52BF599DCCD8D40BE3
-:10F7A000FFD63B0CEA1B0F4D2A5B0FF5EB4D81EBAF
-:10F7B000BE8574B75D5476C16B2FFC7A455A306AAA
-:10F7C0007D7A34FC5F7F631DB5A3026EE40153EFC5
-:10F7D00029AC998EE529C54CB0023F769D66FE9016
-:10F7E00003FB636F9B52193B7DF09E719289F8D1A8
-:10F7F000CD482767984B41BA3BE06CFA15F5B7C77F
-:10F800004CFD4DED4E1190FF1E785250D63384477B
-:10F810002CFD9D3EBDDA358DD3F52D01920326E6F4
-:10F8200081F6963C3196F8807EDFB87E4B43063AEF
-:10F8300036E0C5096D5E889AD1F8657C6EC84CD5F6
-:10F8400082F458D70CF2228A6EEA4EB65B98637047
-:10F850003F8CF5E32F43FC05BC645E9AAF9DF80630
-:10F86000FC0936C0DB0FF0570E2F33E8FF5681A698
-:10F87000C6968DEECC473E274872455BE6007F6515
-:10F88000E521E2F367E1E77A05F942E731A47794ED
-:10F89000A5BB50BEC8DDE7B660BD3ACA8FFC68188C
-:10F8A00022295CD9F3C9C47FCF7AC34FD1FBCF8E55
-:10F8B0005554B87D1EE9C541EFB952A3F8534BE743
-:10F8C000ABAE3094CFEC1D5221BA106F7FE6C279F7
-:10F8D0007ED039A4C2E24ACC378C7C134646F07DF8
-:10F8E0000F7F02DE25F9FC661FC2BB0D842ECAB352
-:10F8F000214D254D71D64D7FCF63692AF122FFF846
-:10F900009E43413E9E6AAB7D1CE535FEF9E1FE1F3C
-:10F91000DF18B213D7FF614DAECE17783F7A3B4365
-:10F920007D9C9FBC71383F250CFDFC917953505E46
-:10F93000ECC90964F8E07E46459F5F0478645CCBBF
-:10F94000945678F584A87C5F86F558C0405EE2B591
-:10F95000346841BEC2DA86D278195366203C17CF8C
-:10F9600004F897F032CAB7A5018BB21EE470ADC49B
-:10F97000E15DBB5B08B5C258166C8885C7A20EEB6B
-:10F98000005EE0FFB646D5433F4BA5D01A945B23FB
-:10F9900040F318520EF8F064ECF3CB58378DABEE11
-:10F9A000D98BD67870FE8B06E73D39FE09383F616A
-:10F9B000B68DC6B3728F40F2D563E9247D22B21CA6
-:10F9C000F8318C97FD9AAFC34D9ABED478E77CFF8F
-:10F9D00002B89E6FAEF52F802A2235E4231D2984BC
-:10F9E0003FCB2A3B7B89AF30F9C73767607BCC2F91
-:10F9F0006379A393EB7BECC95791AFFC85C99D88D4
-:10FA000087539608F4FE945F8B3B01C3D94DFDEB01
-:10FA1000172038D679998C707CC71CA079AB4B998C
-:10FA2000BC0BF84A9D2DA0EB5FF2D5309F45AC8909
-:10FA3000E65DEDCBA6792E61ED54AE67610B1371D7
-:10FA40007DCB52105FFFC4145A5FD093983D753040
-:10FA50005E21FCFD51705BB235B6CC9E8C2A6723CB
-:10FA60009CA11C05FF867D17ADFE38707FB45F1E1C
-:10FA7000858AAAC746E3710BE1DF316D5D1EBD616A
-:10FA80005126F2910751211EA635508EFC177E4D4E
-:10FA9000A172B70DDA4F9AD85FA6FAB2D5BCDCB026
-:10FAA000E3C5C0A62B00DCE660A60C8B532B067AC0
-:10FAB0004D00D739B9C1154857B5267F9644FCC4C7
-:10FAC0009F1F8071B066BEBE8F4D682A6A8AA37F71
-:10FAD000E8E3DF2874769B908FECE7FA85B3346215
-:10FAE0008EE6FF1B7C5CBEA7F48469FD232F080C07
-:10FAF000F5DECDC24399B88E9B33BD422BCCA974A1
-:10FB00005FCB34E237C08BF2605DEBF7BDD73B1CB7
-:10FB1000CAA5557DB84C30EFC0F2D7919E2725710C
-:10FB2000BD39B9698709DA4BBFA570422BE0E743BD
-:10FB30003E2FF59334B1FD30B61359EE9577423B25
-:10FB400019AB55DF8A62ECBFA985F0B79AD1FDA148
-:10FB5000DF59D582CFDD378CA58AF81C6B11F0B93F
-:10FB60003543055A8F35F3D99C1FC3556232E99D41
-:10FB700023E6C842CB642C374D23FCF2CAEE9F65C6
-:10FB80006299B5A5805EFDA88B919E39D424DE5282
-:10FB90000DD74727F072EA2AC1BF9388E121825727
-:10FBA000BA955509A9FC7EA89848D8BF97EA43346E
-:10FBB000FEF4E94D25388EF41C7EF55882A65CE8EB
-:10FBC000FFC851736835CCF388862FB7EDA8488FEE
-:10FBD000E6BB47CEDA2413E8754732747DB6DB8185
-:10FBE000FAEC6D25D3D39118B373AB52705D3D59C8
-:10FBF000B1F5E7CDFE9489483F474586EBF7678727
-:10FC00003F05F5CFCB2D7CFCC6753FACAD67E3A7B8
-:10FC1000020B45C9B3C6391F939DD0F8A91473FFD1
-:10FC2000ECDD368622AE5FEE2DE99981CFD5B3BEED
-:10FC3000358887F59DC92C1445179727C5EF57A719
-:10FC400087C64F45A6C6EDD7127BFFD3214C1D12A8
-:10FC5000EFB9B4D8FB308F9872D727FDF3C0FBAC57
-:10FC60003CEC0A809D3813E52894CF874CAA793C58
-:10FC7000AAF15CFE9D93C32ED4CF415E36E1BA9CBF
-:10FC8000F386491E9E67AC0AEB2F37996EA9C6F51D
-:10FC90009522AED9CE817EF47A7C3F7A1DCFCDB14C
-:10FCA000B06E5A9F088D03E1A71630B6E5E04716FF
-:10FCB0002FEA11070F13FC747C8986A31AC56FD233
-:10FCC0005AFBBA4D4057177C9FB51783C13AB447CA
-:10FCD000E70B17DBFD2024D244530C9F482EEDE7A1
-:10FCE0001BC4A61E35893A9F79A872444C999E1F61
-:10FCF000785FA8AE04BE525ACCDFB7649B8EAE4686
-:10FD000059C6DA697C308F2C845F7FD966283BA086
-:10FD10003C36AA2C1BEA3D86FA0C4379047FFEACE4
-:10FD2000B33B0BED5777B6A55A023A3D9BD93D4FF1
-:10FD300080F286565B752594EB4BB9BC6E3828284B
-:10FD4000246E34F835285CEF7428614B6D31C2A104
-:10FD5000AF17F94A5D97200B400F8ECEBDDD54C61C
-:10FD6000F7BC51EF750AF45E5DE77BF45EC2F60BFB
-:10FD70004D44E7EB0B8FF3E73ADF27BDE0DEB6E556
-:10FD800001646CBD662FF105B0E2FCC3E1C586AE2F
-:10FD90006A16740CF0D77399FE5789BF1E1264A4BB
-:10FDA000CF7E3CC5761D0374A13FFFFBB107DF4248
-:10FDB000B523F9B68F5A2478FE3FEADF9F847AE1B3
-:10FDC000EF3539B251081561BF5B58B008E5E0F76F
-:10FDD000EAF30E9BE0B963E6F036E4BDD5D959D518
-:10FDE00012F0B563CEF04801E4FC75D945BC3C3453
-:10FDF000BC0DE1F92FD9A309BEC74686479AA0FCDE
-:10FE00009D9D37F0725E781B96D59D7EFEFCD8F0E6
-:10FE10004811DECF51A755574279971C9FAEAFCE00
-:10FE2000E67AB43EBEDF4FF45764A39E57C7E5CFD2
-:10FE3000BC5BDF998BFC769E89C90CF8F4AEB327C6
-:10FE4000F6EC0278EC6A4E663B393A0624D087D34A
-:10FE500039EA839C6827BE1EF1019F27E7515F584E
-:10FE60008072F2249B77BD6F605DF4FED34737ED5F
-:10FE7000C5F6D3E715931C117DFE67B17FFDFA76B9
-:10FE8000115CE1F967B365CEBF45939F9EBFCB1967
-:10FE9000C2E71FB4F37901FDD03A3BB475F95E3681
-:10FEA000E793DFCBE67AA4E2BB8ADABB49D7C7D7B0
-:10FEB000760E1D0DE3EA105827DA35EF98996A2778
-:10FEC0003D2689F4A10E1C3BD63F941952A19F9B5D
-:10FED000051640FEA2F3930EB73F3335CAAEE928AC
-:10FEE00081B263C08EEDA8F6672679F09A66421D4E
-:10FEF0005FE74F1D3EFE9E2E9FD25B793FE90F16B6
-:10FF0000EDC4F9244B8CE4DDC239F93B5B483F98E2
-:10FF10004DF3677E7FA600ED9D5C9A6D4238EAEB5B
-:10FF20007561A2BF99E62572BB5C5F371DBECF66C7
-:10FF300073BBB95604FD02F04EC90D527BA06F8C05
-:10FF400023C1AEE91BCF22D246C19949E14978FFCE
-:10FF5000FF43786DC7FAAF0AAFFA66E023A62FC158
-:10FF60004734386E14BACDE99C8F90DD8CF7511E62
-:10FF7000DDE10BFE383B8A1EE6DD554F7AA63EAE2C
-:10FF8000E43B5EAAFA0E433AFC80E86EDE3F25931E
-:10FF90009D6BD40375FB4AD7571F4EE0AFECD6E6F6
-:10FFA000A7E87E596D1CC9C5E13DF703BC529953C2
-:10FFB000463E7ACC121EABC0FBC74CC1275EC27155
-:10FFC0000F1365E02183DA6BCE11A93DBB8E272C80
-:10FFD000E21AED19C093758027367CBFDA42F673BA
-:10FFE000873BB47911E2C90D2314D54B7298E859B7
-:10FFF0006D4EA6FACB4DC719FA9923936519F54CA6
-:020000023000CC
-:10000000C02BAAEF989B1F52B9BF40B593FF34296C
-:10001000B413F1AE040080EDCD1D4DF568AF939F94
-:1000200063AE8DF73718AFB85D5DC078BD4FC3DBE9
-:10003000A5D984B769AD8CFB2924FFB8EA287D6176
-:100040004C0EE723C9A5E1177E8BFAE706BB92C7E2
-:10005000B80988FE0FD69E4EED01BE7C48F8C73821
-:100060005E2E78C0B983F33DA50CE17CAFB39DDD76
-:1000700049FE2B338D7FABBD9BF47093CDEB463F98
-:10008000F13C916DCCC7F65ACD32E28911DE2939A7
-:100090009CAF0DF667866F8FF667CEB3AAD62CACF1
-:1000A000BFDB4E7681EED79C97C2E94AF76B227D83
-:1000B000C6930BBA5FF3160DAF06D5AFFFAFBC1AF0
-:1000C00068EFFF6878A6F47C9A37DFC1E78DFE9170
-:1000D0001AFC05FDD6ACB2BF877ED01AD5DC6D7593
-:1000E000211FB9CA1F8EB2D3D8263E8FE09BE610DF
-:1000F000C2A959621B9FC2F551F9FC572E0C2D8DD8
-:100100009ED7160B9F97FA4FCE98796D71B1255FE8
-:10011000CFBCFE3029765EA72769F362B634784FEC
-:100120009373B7343BDF13C6C115E70557B60AE62C
-:10013000553830AFABD1961B4AEBD9148F0EAF4E6A
-:10014000B88EFF4BE6DBFE983FDE7C8DF3DC93E35D
-:10015000AFCA994474D32D970EE0757033CCAB14AD
-:10016000D77568A885D695E327632E05F9D8CA8583
-:10017000302FBCB6A4933F6B9ED5DB857E5DF6C366
-:10018000146D9E8CF8C0CACD23892E016F39DD3ED7
-:10019000C6E3412BEDDCCFB072B9ACA832CEFFC7BD
-:1001A00064074780BF925ED21CCBD7BF180EF6AC57
-:1001B0009AE26838D8B2E617C75977D54AF89C68EA
-:1001C000DDFF8F18B95DC849EC6763AB62FD14E8C9
-:1001D0006FEC2F8B83CB46BF07637FB3C63EAF2642
-:1001E000886F84BF178D47C7CC1A1EDD6927F9A316
-:1001F000E3D131279FAF118F1868D148C7FABC8D62
-:10020000709C87708C1387007CCA43381ED3EC33F4
-:10021000C0A73C84A34E07B734737E6084DB338968
-:10022000F9DA579B87018FBFEA3CF4FA44F3D0F523
-:10023000DB4DC2F2CD889F9B3299DC4A7A70782CD4
-:10024000DA491E4BA808C7B5C502F40BEDD668FD08
-:10025000932703E6F7A723DC2F7A5CEBD738AEAE03
-:100260001CDD2F1AEB376B7445B6A31ED298C4E57C
-:10027000E1B9434EA21B961B9E87FAF7F9035686F7
-:10028000FCB54108E7E373E704FF7C7AAE25D98B20
-:100290007251F7379E7891FB1B5506F62FFAF982BB
-:1002A000DC5FDAA8FE6C0DAEC3C51CA909EDCFC694
-:1002B000AE58FF1ACCCF85F33D67627DF87C83187A
-:1002C0005A8A26EB460BD707369A5827AEDF805D51
-:1002D0007E3C9FEC844C99A13FA8C1F45EFE8A2825
-:1002E0003BBE41AB6FC8E2FE298C47939F1DBBF21A
-:1002F0000D864BC386339F613CAD619F915E62E981
-:10030000A96EA02C5C14B0BDA87ADF003D913D8E93
-:100310007858C9427902FAD57839B9AA2F8471ED93
-:1003200046CDEF3AB4273C03F505676927433EDA2B
-:10033000789ADB21530EEE7815FD6DEEAABE91A8DA
-:1003400092346AF107A3FD33F9E04322FA8774FB84
-:1003500025CA1F55343BC61FB99ADE43FF16F61750
-:10036000C65BE8D796B89EBB51D373411F26BEB972
-:10037000B0BD80F461D45751EFD0FD63A887A03E93
-:100380003A27B7C2920BF3FC6B6E85903B89F74717
-:10039000763F3A5D267F0EFFD2E0A33F877EB2CF45
-:1003A0008F03707D6A8AC1FFBFE2A74309CF0F2484
-:1003B000D05387E6F6FBFFD3D1FFBF42F0A6239EC2
-:1003C0009F1283E4E75FCC54F21F2F45BF3AF1C17F
-:1003D0006EF24BDFDAC494F514470FAEC172FD1212
-:1003E00026AF47BF746590EAD12FFDCDC93C4EE5DD
-:1003F0008DC25F8C034597D96E28C7F0E93EF27332
-:1004000037400B5B14F423C43EDFC842D325C48BB2
-:10041000AE8BD698763A389C6ED1F065B39DFBB71B
-:10042000A7ACDA21B2283F43CA04BFEF1EA4879FBE
-:100430009AC9BFFA9FDAFAEAF0D89353918CEB95F8
-:10044000847E1F7CEE1E2BC9D99326B604F1E541AC
-:1004500037BB6536FAB3EE66FE5C33E2859C15ED7C
-:10046000EFD2AFEB0FD897209E4DCBE576807E3F45
-:100470009263A632F9AB493F4DA6F83BB0A571880F
-:100480008765D9BA5ECCC6A19FFC3D8D3F35DCE8BF
-:1004900008627B6113E767B372B93F6156AE85D6D8
-:1004A0004F2FF7FB8B343C837EA8BDA4892C26FEFE
-:1004B0007743FFF30F697628A3F96E5C9AC4F5E8D9
-:1004C0007E7C37113F4B2E0E5882C44F2A889F45A1
-:1004D000FEE0F0225CAACED42DC579FC714E12C389
-:1004E0007C85055A7CA929D74DEDEAF1A438FAD7C5
-:1004F000CDDD9E0179A3E3A72E670E38F9BC2F3519
-:100500002FC078AD5A5F44FC5B1FC714835E92888E
-:100510002E9AB57533C6C500AEC9C8670F98B8DD49
-:100520007500108BFC569D5ADC12EC64940307F6A0
-:1005300015909E3D5FF3A7829C24FB2A02F282AFB6
-:100540007770F3427CAE338FE2B9EF9943CF3C85AD
-:10055000F2F610B723F4F53870607808E977CA9995
-:100560000B5908FF03A77F341CE3E407B4B8649D6C
-:10057000A53B9FEC7D0BD753EB5CDDF908BF9735AE
-:10058000BCA94B8232DC1F3934F830F21F3DAF007A
-:10059000DF73D37CBC2EF4379CD0ECC8E36057E209
-:1005A000B8805AFA305E0AEB9D89E5C8BA74AEEF9E
-:1005B000C1B8102F4E1C1A4BF3DB68E678ACEE176F
-:1005C000C83F71DC1C39D50CCF1FCF9CC85A64942E
-:1005D000779F3ED58BED6F179955C6BC8D4F3EEE7C
-:1005E00082E7CF839D8B7EB35A53604626F28B17EA
-:1005F000B9BD6E5C07947FD171BC732C92457EBDF2
-:1006000025D99D883FE70E16513E12F3C84C8572DE
-:10061000E37E6EDF18E3CB27CDB1F86F6C17E7856B
-:10062000FEB546FC8DF23DFAFD38ED7D51F99C3961
-:100630009C7F27C063AA37D8931B65A736BE924913
-:10064000FCF8C4FD9FD07AB2761E373D69F6CFC361
-:10065000F1B92BBB2D3551F8F83B8D3FD75AB9BCBA
-:1006600006FE6B89E6377A7D59058B1BDF7F5BA31E
-:1006700073671F977B83EB399EDFCE9E10915FFCE3
-:100680002ED74BED8DD2F2146E677F3A6C45FDA4E8
-:10069000B384F22046ADEA263E00E325FC3CB9399E
-:1006A00085F823DBC0F175D10FADC43F1681FCE0A6
-:1006B000F636CFCB621B78FEC5A97B7C84CF65ABB9
-:1006C000BBCB881EDC4C41BDE4A5B6F75411EAE76C
-:1006D000EF164A30EF6C7E9B8FEC945BF7F9687DE8
-:1006E000A7687CBDD6EAA73C33F6388FC32D78784F
-:1006F00029F5539FCCDC22E97F210BCAE525BB05F8
-:10070000867435A593F3FF3AA9FB30EA91C6BC097C
-:10071000168A8D2FA33C62517A26CA1F66B00B62DF
-:10072000D75DBD24F96B9437E6BCF8F217EC3D4B6E
-:100730001E5F572E27F60A9C6F68F2B71EE52FEA58
-:100740006A9ADCD3E5E6624D6E9E12B9DC5E647D8A
-:1007500088AEC3F37C34CE5B311E4CF1CF8805F5F7
-:10076000934478315C1B978E1723304966E8005E0E
-:10077000D49DEEEEB5929DA9BC8871EEBA55ACDB66
-:100780000976DA22A989E4C33099C9948F373D48A4
-:10079000E34A5F09FA39ACF3228CDD4EB874BD60D0
-:1007A000901E6090FFFAB8753C31EA7F535685443D
-:1007B0008A33E533BAAF5F65D65982E3ADB671FDD2
-:1007C000BBDAE6E816D1DEAC349F8DB637AA257FBA
-:1007D000791EC9CB11EE53638845306C57F1F9ABE4
-:1007E000464F1AD02B934B236BEE87F6CC6C9C09AB
-:1007F000F9A4DEBFE89BB6B818E37A521FD92B2CB8
-:1008000083C9BBA0BFEB8B395C93611D76005CCDC7
-:10081000924AF033DB64778B1BD7BF8FE23291A112
-:100820008CFC74FA7A6D733215F31CAF2FE6F47DED
-:100830007D31F727C3FB14FF3517C2FBD07EC501FE
-:100840003BD1E5C7FB9D2194CF207746B9A13EED72
-:10085000F760A740F9DC0127E929E73479E1D1FD08
-:10086000B56C0DB5779386372AAB188EF60813AEA4
-:100870001D0E6367BA9E5CEF4E14C7D4EA7D7D37C8
-:1008800072FCB592BEF0B13BFC7D2CC37828276783
-:10089000B686578DFBA697DC85FC3BE05038D483A9
-:1008A00025A8FF58C5DB6EB401B06788AB2277225C
-:1008B000DE8F74C85678A572D4BBBF990BE53FECA8
-:1008C00033332BE2CFAEEB52BAF135C99F11183B4F
-:1008D000783C4B43E6E3E1283A5EB63BB65CDF1971
-:1008E0005B6E64D2F17014FF6F7E77E92F5E8BC26E
-:1008F000B7BBF29C9E53C90C7D6FCA45A0A79377E6
-:1009000077B113280BC5EFA6207F5C00E41F4FAF23
-:10091000F8E4EE25BF780D9E932C15AD1C9FBC16F8
-:10092000A4AF1AD01BE2D9A125797C7DADD6A6D380
-:100930003B003ED697AD4A0BBC352B2FB801DF6F7D
-:1009400030457A715DADA3CE8E437F76C5A80B94FA
-:100950004FF0F13F3305E1F4B17D1AE1D3C79BEDD0
-:100960005EB4533BB21CDC0FFB8A1012B8DD326B55
-:10097000521AE68BD05C808F45D66C463E3DD92A14
-:10098000AF9669BA3613AD37586F70EDB0A86BD01B
-:10099000AFDA0106648B82765E9F0B89E197B88E91
-:1009A00088DFE2B3161BFCF4B5F98B5AE0B9658118
-:1009B0002486797CD2675200F1EC5E6C2ACAEED9AB
-:1009C0009DC7E54FBD2D6C9906CF355EB8AD6AA8C1
-:1009D00069C0CF6F3507FDC361DCE6AE92EEE17012
-:1009E0006B71F374B2EF80DF72BE7888F3C5C577A0
-:1009F0004EA3FBC2EC2A9AEF29982FC2E5D5CD561B
-:100A00009AEFA9910EB2B74F6D13A8BC58B6501EFD
-:100A100020E82743A679F0BE59B6B2C1F068DC746D
-:100A2000EF9ACD50FFF34C910980FFEF6FFD09C5A0
-:100A300023DE67BC7F759F487ACFFB72A4AC1BE1B5
-:100A4000E96D7245DB938BB78901E4978BB7DDFEC7
-:100A5000F3C908B7D93795223CA6BA6F4BF33A06CB
-:100A6000EA757D4F4A2D7F0AE972EA67D3FBA6A299
-:100A7000DEB50DE806C62D995810ED8FD7B65D4D41
-:100A8000FAF6E2EA2437CECFBB75D70C946FEF5756
-:100A90000F33D1BCF6084C4678B89BD3F0FE6241C8
-:100AA0000AC4C3AB45793C9E306D9443417FC3E299
-:100AB000B744C217A0B31B318E50BFCD4CFAFC6BAC
-:100AC000B3DFF9CD5CCF009D09B337CD9A82CF3F1C
-:100AD0006DA6E7FBF5A9AD1FBE8B7E01FC03C98E99
-:100AE0007288E067A43BEBA855F9382E23FD2D5EF4
-:100AF000DD94CFE3FB9746876C2BD021F0E3B34026
-:100B000027174D7F171DFEF952E8908D488D91DF14
-:100B100083F99E4ACFE9F1519BC2FCBB1C940FE3C1
-:100B200017805F8FCC97884E46E65BE839E9BF5661
-:100B3000EC7E13E0F4785ED0928F7A17F397A07C66
-:100B4000F646E40A74C53A34BD916DE5F9E1685F93
-:100B5000E0FA6F1CCA9E5A1FE59FC9CCD7ECC0BCF7
-:100B6000600AB673EE77177A71BD1AB2CE8E43BDA6
-:100B7000BAF1D33F535E85E320CFC7712811CA5322
-:100B8000327B02848F3ADF6F54B81C32CEAB2D9F7C
-:100B9000DBAD8D9E08B5B3BF80D3BB1E8FDCD29C6E
-:100BA0004471A12D9E909DFB5940DF83F667968A84
-:100BB000C4676CA5AD0CE5182B17299E33F5C22F21
-:100BC00018C6BF7E7EC57405F54A47E9ABD2109CB6
-:100BD00067B959AB7F7E6D36D4FFE28AABC83E5A07
-:100BE00091217A51AF9A599AA392FCF4F3BCDDA9F2
-:100BF0001752880E672D9D457AA53EDE00B3791DFC
-:100C00008027B38158A3F39B675D61F73AA2F0EBAD
-:100C10008FED4215D7ABBD29D78FE57EA1CE622ED1
-:100C2000CFA3E1B022C342FDFF3577DA6484EFD46D
-:100C30002BF93A7CB0C71A5A0DFD7E608F6F47566C
-:100C4000E5737F6BB6740DF1A5DBF658293E7F4640
-:100C500088FFFCAD6B45CA2B5ABA566021E8EF837A
-:100C6000675ECA42BEFE875D2F65D5448D27D1FBE6
-:100C70000BF313F977BB1744DBDB332D3C2EC02677
-:100C80005863FCBB335D5A7EFE978C777C2BA19F0B
-:100C9000FFA72370BC6FF6FBF9DF18111DEFE88F7B
-:100CA0005B29DCCF6F8C57E596FFBB365E9E0FDD70
-:100CB0002C69E355AC3C6EB190C7C5571E1A4278FB
-:100CC00037D3127980E259AF88B216D7F0DBE8FD4E
-:100CD0000C5E9F605ECCEFCFF59491BF89C6237404
-:100CE00009DD4ED757981FE3710CE3FC6A0E8A7139
-:100CF000E3727F2D9079BCB3384276D5F1379EC030
-:100D0000C87B3FBEDB0FFA4CD179F4FDFAAC86DF2D
-:100D1000D7217EC3FCEC6B7939115E27E25719F9B4
-:100D20009C8E75FC3EBE362705F1ED1E5B43B81761
-:100D3000E0E71753987D1894B5F8BFFA2ECF6315E6
-:100D4000A3EC1CA4836DEF3AC9CE6935373D8EFB09
-:100D50007ED41689ED82FB9EA486500B94BD662737
-:100D6000E54DDD91346B07DA7561507005287F928F
-:100D7000746C07EA09CC96C2CCD08F5AA1BD6FB172
-:100D8000C9ADA05F3C96EC22FED2BC8091FC4E67C0
-:100D9000DD82000039989FCDFDB4CB5E1428FF188A
-:100DA000281EF53E2527BE3EBA57A38B5F61020D74
-:100DB000C6E5A7C77FEE60BEEE179382E1283BEF42
-:100DC0005E41F112DF813FCC8F34B3BEB9C497418D
-:100DD0008FFF05C883E1E28FC93F7BE2EEE0E3F1DC
-:100DE000F649E8D705D3E3DBE9AF6BE32B6C174299
-:100DF0006617D1AF69470CFD6A713C679A0212060B
-:100E0000E3B73C4E97CBF47CF94DE8B71F56CEC7FD
-:100E1000E8F28719EA1719EDD7B0E010A4A729E97D
-:100E200028DF562E8CF5A765D4ACCD24BF5ECDF758
-:100E300067A1FCDE6476AC1552F01AEB8FDB64F030
-:100E4000C77D115FC84848379333D0BFB16920FED2
-:100E500047F8D33A5F0E8902CD8245C7B5D35ABD54
-:100E6000BD41D483A6D9949DCA60FA61E54A06CEF5
-:100E7000ABBC80C34FA7E7460D35858302D9A58358
-:100E8000F9A106CFFA11044F7BFB1D64372597703B
-:100E90003F76F2D29A20F29F64E03F68C7592C4D0A
-:100EA00002ADFF146EB7AD147879E5345956E17987
-:100EB0008B4BCB97BD96E767AFB40783D1F1B4CB2B
-:100EC0004D2BA645E7E5CA0CDE473E3C87F737D3F6
-:100ED000B68AE705074147CA1C80638506C7DCF26E
-:100EE000249EA77EBB8DFC5B5BEDED345E9397DBB0
-:100EF000D935EBEDC4EF868B851437E93173FC509F
-:100F00009D36A257A5E76DCA0F1B7E598657F4453B
-:100F1000E1CF6DBC5EC70B66C82BB058BCBDE8BF47
-:100F20008381289897B252F0F656D0BCE488AAE0A4
-:100F3000BC35BE3C2E89CB11303733385C795CCC64
-:100F4000B05E8037DCAF3ED6C1FD462CE825BDCB78
-:100F500030DFC178B3BF10F96D4F3FDE7415C6E3C3
-:100F6000B70FBABDBD3BA3F18579D7A05FF53E139E
-:100F70008BAC8F873F4AAC9D6FCC9333DAFB0DCDA2
-:100F8000D3039AFDA1DA683D2D647F34DC392DC08E
-:100F9000ED8FC216F43F35AE024905EF4C3F28D81D
-:100FA000B0BDC6392EB2BF1BBBF652FCBCA18A290C
-:100FB000388C1ACD3FACCFF3B899C7F14066756253
-:100FC000FCBEC31DDE8EFBF23A96EA793C3CAF458F
-:100FD000ED12B43C1E3DEF2B720CFD9F1D8297FC61
-:100FE000A0FDFBFB60FD79FECEA5E581398B033EBC
-:100FF000B4C42FCF7BE29749932E218F563DD381E6
-:1010000079B289F3685FBF01EB6DB8165A3DA20152
-:10101000E8CB7AD96FF762FECE40BD0476A7AD4B20
-:10102000E0EFABD7DE709544FB72B4F2A147D01F5E
-:10103000FEA09DC5F4173D3EC9D03E9A960EAFFE68
-:10104000FCB6D9D8DEA313B4B2FAB787FD30BE0719
-:10105000CDB1ED11CA68EF6341EFCF3BE6998E0D3C
-:101060002306F476D0E3EF2E9834A0BFDFFBCECC7E
-:10107000F6F1D057B2FC27DA07A5EBE18D1E9E579B
-:101080006BC4F3F51A1F037B7806AAD6F7CE591E58
-:10109000C076FBF3DE0ECEF7A31DACE7BD35AE0A7E
-:1010A000D07E28D0FB1F28C03CDADF9D3D7598A17B
-:1010B0009DF901F9031A3F95B8DF19EC0701F0C556
-:1010C00076F021C21FB6DB1C42D74E875B65888F46
-:1010D0001D878449885F8C3565DD00B03F55E0DFB2
-:1010E00088F33897203EFE7C01B7DB1B0B2B36E7DD
-:1010F00023AC9F1418EAE3EB0BFF487645C3FEAB25
-:101100002645EFDF5BDAF528DF07B6DB1C77DECF9D
-:1011100017883C8F78FF0B143FF9202410CD2D91B8
-:1011200042EBD0DE5CB2C48496152B0DCDA73C59A2
-:1011300036C7C270FC8F1670B834EEBE4EC5FD8443
-:101140008DF00F48806D092C227D7BCB1C9B03E327
-:10115000D88D8535CB89DFC9497E34E58CE3ECCF6A
-:101160007FBB3389F268D67799ABD04E2A03BAF8A1
-:101170005707F2D5A3BE1DC83F874C105B65CC3323
-:101180008CAF7FBF50C4F5873621A07EBB94E2228E
-:101190002C3A9F795417B7BF7A0B2C31FEC9DE0267
-:1011A00089DEBB42ED9B8EB8F68A144E467BB89121
-:1011B000F93F42BF170B38BC1417629DE40FF4DCF3
-:1011C000ED25BBC9E609DF371EEBAF90C86ED2FD37
-:1011D00008E7F6A7933E36A530F82BC48B3231FCD6
-:1011E000C8B7116EF7495A7C89F395ACEB1C13D044
-:1011F000BE327BB83E63077D06F7895CB9EEE4CF6B
-:10120000A6236FF504488F6020E470BFF9749BC07B
-:10121000E32B06BD99C94A25BE3F43F34BE7C16A9C
-:101220009DB2116AB65D1C82FE0C8F8AF07E032689
-:101230003004EAAF62FE365C97BF6A76E4460BD7AD
-:10124000D7379A6CA4AFEBFA70B2A78FECC4FA4E02
-:1012500081FAA92FFC31ED1758A6E5A5F7E7874BD2
-:1012600061CA973F5790ACE96F6DDC1FC5FAC81F84
-:10127000C69EE5EB009A27E5D1EB70D7F3CAF5F6E9
-:101280002C5ABCB45EF3E702C0A8FEBF0A74BD705E
-:10129000B5165FD5F3FE79BF4CF29645FB1D375668
-:1012A00033D647E3F2BA70BCF7A4054C85F0FE7163
-:1012B000C063C4B3E36B9343B8DF6BA3D0E7C7B895
-:1012C000875AC2E319467C4A2FE4FDA6F4446650CF
-:1012D000DED5FE04FB8ABA62F715017F58FE3AF4A8
-:1012E000535AFA8E82F8FDA05B7BFF1A46F9E4C6DA
-:1012F0007D45230ABDFF3BF71529827F275CC71672
-:10130000BAF9BE217D5F91C2D74BCFE330EE273AC9
-:1013100097D92DF1FCFFF0F65D242FAD6417BEFCCC
-:10132000616F1BFA99CF975814DC479176D31B6DE8
-:10133000944F23484D188F34EA034FF8A65F563870
-:1013400009F7A5BDA850BEB0411F48E407A05869E1
-:10135000949FE89AC2AFD70F606FFFC485F87646B6
-:10136000883C8079ACEA21316E1EEB92C244FE00CB
-:10137000FF9C68FDB44DCFF77227C5E43FB625C882
-:10138000F74AA4F74B09F3BCAE21FDADAD3FCFAB9F
-:101390004AD7DF62F358E5A4CFB597F5FEABC2BEDE
-:1013A00098B8FC3F6B74F2C5F3D4EC9804F34B642B
-:1013B000B75D6A9E81110E6D09E4E83D85F1F7DFA6
-:1013C0000258648CCBB7615C1EAE92C054F29FEDA4
-:1013D000EDCF33E8267FF10B05E4F7B226CC33E0FE
-:1013E000F967D2A1022F3E77AF39E0477B46DD6B2C
-:1013F000D6E440E819F49BB41DCA243F1B2B0C8F84
-:1014000043FE28B96764E0B9066D1A7ED67DF93CC3
-:1014100083C791CF19F30C7684263C90CDEDE7BEBF
-:1014200064D0CB76302EA7D483DCAF09E326BF5E31
-:10143000E4FE91A4AF0AB36D348F13AF58775A49C5
-:101440000F57286FA026439451BE7454979D42F9BC
-:1014500075021457A4E3DA5B5791FD9A687D6AD749
-:10146000C6C671F5FB5F769D5E29E4FACE71B4EFD6
-:1014700049D0AAE42F5EB256384CF9BA8638723792
-:10148000F2109213B179011FDBA7513CF6FB0F5705
-:10149000531C56DFB7ABEFD7655ABCC5BB562239D4
-:1014A000E1DD2D84BC3E4E2626B2ED65139D1F0264
-:1014B000E26D0B8A4415A8E632B82D9804D453BDCA
-:1014C0006D504E8779AD93D40C786EC7DBC9E47F3D
-:1014D000BDD7E3D5F65170FB4BDD2090FE07ED92B2
-:1014E000FDACB601DE403BE1421E17F8B490FBA70D
-:1014F000014542341EEDDAA6E551E8FDB53053371B
-:101500005E4D02BFDE2B4B55F1F43BBDBD367393F0
-:101510000DE32D9191268A677E6CF1CFA178606AE8
-:101520003E437BB1CDD9B4B68AD7130FFDD81E097F
-:1015300050FD37246E28306F2A8EF7371ADD18D702
-:1015400075617B6CD918EF379E4350CB8205993972
-:1015500083F7E5FF4693871FAFF769EBA250BCBC4A
-:10156000CDECFDA50FE5E33A89E470CB080E37D347
-:10157000487ECD7657CE2139EC06FD94C6CBC79F69
-:10158000FD0D8F80F4D7E6E6F8F555C73DE81C81E0
-:10159000A27C1A6F1B1A0DD05FDB3A21C4E1C5C7CC
-:1015A000FD65FDD559455FAF9C3A21284F75239EB7
-:1015B00039423F44BF5F6D8B55467E7646D0E87F0B
-:1015C0009D48FC6CCB92542A1F5F9B477EA07EBA3D
-:1015D0003DBD66399EAFF065F3B694228E173F3756
-:1015E000F8E16ACA85A3D88E11EE8850922E7FE06A
-:1015F000D5E9D715CF40FED86062DE74D407D61A7D
-:10160000F2430CF43CD51BBCB208ED0F4B5F2FE747
-:1016100053E17C89F46FBB82707BD47462EF4F100E
-:101620005FF6DA29DFB06155E429F457BABDC1ABE2
-:10163000F0BDB377BE3343F05273A4279D3F5440AF
-:10164000E775D4B419CE41D8109B97C2D6A6F2BC88
-:101650008F8ED8FBB85F3FE6BD41F92AED9ABE1DDB
-:101660002C42FB62EA953CCFEFC3A5268678F1A118
-:101670009DE38F7ABF5393334A7EB45E5BA3D93721
-:10168000FDF871BF9DF0A356DBE7645C8F7AC40F51
-:1016900058B73A0D3F3E7CE1B27CC48FB37B2FCB71
-:1016A00047FCD8686EF7237DCDC90D2E2A82719D27
-:1016B000BC2AD06BE27C29FF52F0F676E3B8FE41FB
-:1016C000FA55475122BDC3FBDDE8784B8F99FBC922
-:1016D000547BEC3EA19E4BF4AB26F68F15E5C6FA83
-:1016E000C70A73E3EA5736FBE7EA57973E0F46FB14
-:1016F000C4F4384C8F33F2C05351F05A69E7F928DB
-:101700002B8B64592DC1F9D5E4D0BEB3DFD9949D9C
-:10171000C2D73ACF183FE02B1772D6B4E338FCDCBF
-:101720006FF98AE4EDBD1CFA7D8571BFA571DEBF3E
-:101730002DE0F933BADDADDB81C6FE0F68EBFDB3FA
-:1017400022FF21B4ABA75EB8487E84D3782E0FF475
-:101750006B0BFD2BD973ECA020D3BE352F8F8336B6
-:10176000EC5FF804FA5D9786B4F8E53E81ECF5A5E8
-:101770004F7E44F5E7BA6AA9DE7150E8C63868E3DF
-:101780000813C96D3DFF41F7FF341E2C21BF8FEEBA
-:10179000FF8171EC473F4DB2276221BE85F625BC23
-:1017A000D720F1F86E8387292AB2DAAE58BF899E16
-:1017B0001FB52560217ADF725008A13D9E6609FAA7
-:1017C00046103C47C894DFA2F18DB78BFC17905FA1
-:1017D000E9F96B7B72FCEF14F1BCB72CCA93D7D636
-:1017E00023D81F17E2FB2CFEF26BBECF229C805F3A
-:1017F000FF67919E677B23E9CF7F618194F8F9E7CA
-:10180000219E7FDE9FEFC6F3CCEB6632B6DECDCBFA
-:1018100078CE4C3D9E33A370F9D96D909FD165CCA5
-:101820002FEB8EE29B75521FE5B1EBE7CA60BE5904
-:10183000F4F30DB84F2387E79DC5B4A3F1D37471BA
-:1018400005C57FE2C45DBF1B6D7F1CD1EDAC127D71
-:101850005F4DC482FE9D952D9E08C6118E38B5FD44
-:10186000BE5A3EED4A7BE404FA3F563E934EFB4798
-:10187000FAF5FB3D56CD7FCEF1BE8EFF648D4B8ECB
-:10188000939DDF88FBFA85017A9A99D02EFB692E09
-:10189000C6638EF4DB656FE4E2FE1B9DCFD6299C08
-:1018A0005FD475097C1F5667EC3E9CDCD15FAFBEF0
-:1018B000A03F97E8FD8AD189ECD92F8233E7B7475B
-:1018C00012ED5FD2F8A40E47233FBA54F8E9F5FDB4
-:1018D000F003BA267E6B809FD18FA6FBC3589B4C2A
-:1018E000FE32D0493A319F53F7877D5979F89DD11F
-:1018F000FF33F2F0FBA313C9C3AFB63E89E4C4A51E
-:10190000AECB207988EB332EB13CCC2DFF776DDC4C
-:10191000C63C046DDC863C8423E6C82C7E8E05C064
-:10192000C737380F2121FE7D411EC2DF314F431ED4
-:10193000C2E7CFD39887F0F8A1C75C18AAC3FD6AA5
-:10194000E877E8D965A6F8FB0CD1E1E7F96122CF89
-:1019500027657E3A8FB3D16627FF82317F0E38D557
-:101960009A26D42FCB41EFC7FD3CDB5A492ED767CF
-:101970008AE4ABC47C41D91B273F53AA4EE9F60E3B
-:10198000CE13C3FC773A17E012F3C4F68EEECFD72E
-:10199000F4FD9DF99AFB477F893C31258FF3A757CA
-:1019A0001D7F1A127D5E66453118EAC589F3F47F02
-:1019B000A2D14DB296DF6B935416ED8F4AF4DE2F11
-:1019C00046737BE7554BE4ED4ED4ABA0198C7B6698
-:1019D00058C09A2E1DD8EF7EAA207014F394411F90
-:1019E000A1F53DB7FFB7E4EF7F3C93C99837FFB847
-:1019F00059A575568732C26B3D9F41EFE72ECDFF4B
-:101A0000FD65F9CFFBFF60B9208DF9EF910B5F1BEE
-:101A1000DF1994F7C4E9F1EFE037447FFDFCC4CC53
-:101A2000E341FA79175F28E7BE6E3E63C8D74834B2
-:101A3000AFBF1630C29FC23181EC31E417F3939FE0
-:101A4000F152E55F7229E843088F7D562F929A4D37
-:101A50003BD7826DC8D4FDA2FC7CC1074792DEF95A
-:101A6000A19D8F573FAF439FCFE5630CF8F915ED6C
-:101A7000582537F08D3130BF93D3FCB4EFF75E2794
-:101A8000D7DB22CFF0BC77E3F9134037FC3C0EEDF7
-:101A9000DC5FE33EFA6F1BC7F70F92DF0DFFDBE958
-:101AA000E812E5F7A5CF23D69E3DE2E4798503F65B
-:101AB000EC7FDBBC2E495EEB79C665157D9ABF5F76
-:101AC00060E8EFD7FB69ECE3FB741ED2D653BFFF8F
-:101AD0005BCDBFF7D618FFC388AFA5A5DDDB71BF0F
-:101AE0004A0373318CBB3774DEB1FB4D0FDF7F4B84
-:101AF000E5421EAF640107EDCF7E3C2FB8750CC9DF
-:101B0000C1F01AA4CF511E56867183F585B359AD25
-:101B100083F21042583F6A5578FB9BA59487D58481
-:101B2000F4AAE721975DFCD39AAA521A2FF97F3DB8
-:101B3000D6D8733B0E8FE1F24CBFBE3246D0E2AE38
-:101B4000FE4C1CCFD9257C3F6AA3C72FA31F598FFA
-:101B50007B277BFB286FA0611F378ACAD056C4FA47
-:101B6000BB46107D35EC9B5682F150D6692FA1F310
-:101B70007E7FCFCFD93E7BE730F2374E290CBE8433
-:101B80007CC9591ABA06EDE851D00FC64DCFEEBD4B
-:101B9000A62418876FA68BA92AC695D345D6F9889F
-:101BA0003CC0B7C07E9E4BFEE23511F2633D3D86E0
-:101BB000DF6FF470B9DE78B09A2D740C941D9ED846
-:101BC000FD573F2BBAEA691CC7D363242D2F93E737
-:101BD00081FA400D43BFA1119F7C5A1E68B596E75C
-:101BE000CC54DB407E73F617E781EAE3D3CB7A1E51
-:101BF00068F2A7DC7ECF962D9437E25CCBF92A5BA6
-:101C0000C5286E7045A46F7A0AC029B7A3FB0A8461
-:101C1000530A829DCE7F0DDF371EEE7B864857A08C
-:101C20003F647BF3841ED47FA5757DDFC025F1B6AC
-:101C3000CB15E8627C3C2F7082E480D454887CA968
-:101C4000E22D33DFA7B42E99F4CA8EAC3ADAA7742A
-:101C5000EE1D6BDC7308F4ABCA566760DC217BEDCC
-:101C6000AF282FC0B94F88BB9FADB2D8A1ED635A42
-:101C70009D81710CE7DA3EB51CDACFBE5F609A1920
-:101C80009D2964A07F5832A17CADEDE2E7DBD5B69B
-:101C9000BB2B6C246FB8BF865DE1213922ADFBA65A
-:101CA00009F984D4025A2CCCF3F2621E9FCEEB9039
-:101CB0004D28A7FEED33316E1CC9563CB0DF05C17F
-:101CC000556F8DF466F806F27CF47D2EBABFA75FDF
-:101CD000FEEC9B4FFE9E4BCFEB8EDC4C79839FA599
-:101CE000517C65A68BDB232088B4F35D62DF1F7413
-:101CF000BE8BA6B7E876B1910E8C79D2B9E5C388D0
-:101D00002E808F766E9163F85EDC7CE96689EBDD70
-:101D1000300FCB4A1CC7B40C05FD735F363FDD683E
-:101D20004FF7EB399A5EA28FFBEFCDE7D6EBEB30A6
-:101D30008F3B8EFF43D76BDAF47DD09FF1F3B7462C
-:101D400069F6C4F1F57F1DC7CF39D4F346427495C7
-:101D5000CCC03F097FC257AA8807FBDCA686628AEF
-:101D60002F35503BEBF8F9FEA3D6E6AC2E2FC5ABD2
-:101D7000CC0480F7F103CB4651FC16E8222F0E5D10
-:101D8000BC3FC6CCDB5F974C782C3DC4280B52720D
-:101D9000A7111E4B8F727C7D6F0CC72F3D6F4D8F2F
-:101DA00003BE35263817F729F69FCBD19CC4CFE563
-:101DB000D0F2BF9DCDEFECC1F32EB66B71E09E5714
-:101DC000C6CCA6F8DC3A4940FBF063F7FC51E8BF0B
-:101DD0005BA0E1B953EA63B2239A5E7B68FF60F6C9
-:101DE00021BEEF49D2F254A5759E1D889FA22F48AF
-:101DF000FB24BFD1D62D521E947CF2912A2FDA1DDE
-:101E0000110BE6AD7DD0224556BB497F8AF193196F
-:101E1000FD5E4CEAA4BC9CE6E27FAC1DB2B138A1E9
-:101E2000FEF495F65FB02FF04F7D55BC4EE49FBA9F
-:101E3000F47918F75D70FB84BDC2F39BE2CC2BC62E
-:101E40007FF9B5CF4BF75B1AF3D506D131F77FE8B1
-:101E5000F6901E7F607E35269FBCC72C77A3DE835D
-:101E6000F9B92F28A8573F6D8FCE27FB370DEFFB11
-:101E7000CFFD63213BEED73FAFED376692B216E35D
-:101E8000A07788CE76B4EF5A31CF1FF54B84AF10D0
-:101E9000B5DFE15D27E53D344B7C3F0453F97E8A95
-:101EA000950B9B9EC6F757B6A4CB087FB5A2E979E0
-:101EB000DA2F61628156B87EA27DEF421F8F9EFFAE
-:101EC0009F487E0ECAFFFF82FD0B9909F62FFC8703
-:101ED00086F7850B18ED5F606BFD3B705C1D2D1266
-:101EE000C3786F6A152F8F926CF4FD153BE6510F86
-:101EF000A1FDA694EF1C017862DEB61DF3A887E071
-:101F0000FE127ECEA130BB8AF02F15E0837A41AB62
-:101F1000999F6BA8DEE0207C9A5EC5E397A9010B30
-:101F2000F19FF34CA1BC7B15CF3FF3209EAD26FC67
-:101F30008C38D328FE9A9ACBF5487BC062B2F92838
-:101F40004F9AF03522E879D29CEF75CCF752FE7AA1
-:101F5000FF39870B19ADCFBABC1999F8DD8161D76C
-:101F600059048CD7E872A642C38F8E1DDAFBF5FCAC
-:101F70007D3C0711C7C756F2F7FBCF41FC1EAF6F80
-:101F800096C2748E10E830DA397CBC7EE5DC34A26F
-:101F90001F51DBE7CA6ED2F2F4057EEED4CAB9C394
-:101FA00078BD8BF341766B9226CFB5F76F4F0D69F5
-:101FB000F1029E6FBFD4A49D1FD0CE62E2B91A9DDC
-:101FC000A57EC17E8D8707F2EE899E5BAF9129AF1A
-:101FD000503FC7B1C261E1FBB86CB174F542712AE0
-:101FE000C7FB72C586FDDEE2F3FBC6C6F50F87E6CA
-:101FF00047F395613A5FB9D562B0CBD2395C5D9158
-:10200000ED7CBF97F592ECB2C471C5673263E38A89
-:10201000BB33A3E38AFAFA562CB1105FE9707B5FF9
-:10202000C3FCA32D005A3C17CF38EF2DFDE75B878B
-:10203000ECA8971AEDC12309F28CE68FE5768F9212
-:10204000C00F317F6C22F992204E5B62FD6F8A37A0
-:1020500073FEDB93607F5F3FBC74BDC9668C7BA859
-:1020600097E4F7E9B1FD80F8A0BF5562F62BA16CAB
-:10207000D88F067C90F8A2BADA2AB77A908FFE80C1
-:10208000F8623358AED628BE08E6E865C88F7BEE06
-:102090002EA4EFD9BC76B742D7F376A1531C8FD7C5
-:1020A000C83CD498163F77F8463CEFF9BC3392858C
-:1020B000E743DFF3FC9BDFA1F2D0C8312CB73D270B
-:1020C000CDA1725E643B9E17BDE5B935BC1E696C3F
-:1020D00018633F187BD77754077D7F614D1FEAF760
-:1020E000A5863C7EC3F9B5B8DF14E793EEB050DCAB
-:1020F000375DDBE7CB2A35FF10667A21DD65965028
-:102100009E9E8379F7F561FD082E77A1BE05CF4726
-:102110006DCDF3F13834E37C808DD0F238585845DA
-:102120007F54ABCF4DEFF7EB77FBAC5A1E18EFFFA8
-:10213000E80BFC5C1F7DFF3263F248B41B1D5E168A
-:1021400053D6CF8366923C12CF6F6DD5F0402FBF30
-:10215000941E0C8D8DB22B8F5E754731CEF3C31755
-:10216000EFCA457DEA6AED3B5046BC6A1CCFF17B65
-:1021700075F2DFE6211F7F5B7429E43F480FFE08FC
-:10218000F9C6424FCB2437E04FA53C8DBE373345CF
-:102190009D2B205F715FCFC7E7AE0C080B8B07BE8E
-:1021A00043333428919F9E053B44D4B7879E0CC887
-:1021B000089F3A5B244B82767EE309BE80E3FC787D
-:1021C000FE7BDFA7BCBC61478FE1B99247CDEDD361
-:1021D0005D884F3EED1C6126D1BE9ADEE1A3766A92
-:1021E000DFD3E1FB6BF2042D0EDB5D8972E15AC691
-:1021F000F116CB58FF4DED9CB419323F777346A9C9
-:102200008FBE8F368B4524C487196F075C0CE9E3BA
-:10221000FA6069BC732BF42BCB307BA3E9E71A6F10
-:102220005419FE7DB330B6FC2D25B6FCEDF2CF0A75
-:10223000A2CBD592FF9708CF97052E7FD4C95CFE1D
-:10224000C8AC7335CAC71F35C91328AEEE11542C5C
-:102250008F796918E525B10C9ECF30DA951DE270B3
-:10226000C8D98AF38A809CDFE9C1EF2CF1F3AFD2A1
-:10227000DEB6ECC0F31598D7BB15E9F0457321E540
-:102280006DA6396AFEB585F41927CB233EE5DD4AF4
-:1022900078EDB479F1BB0F879D3C1FA1F52113C5E3
-:1022A0009B0497CDE487E7C49D1297FFCE25D3B159
-:1022B0005E2C83050159DDE3E6DF6D6A9DC4CCAB7E
-:1022C0004B70DD94B7492F72DA28DFBFD255F85D25
-:1022D000AC175D163A0FE2B0B32CA8F5C7B0FD27D6
-:1022E0009D4BE87DE4D16630C87BECDCBF2E827D5F
-:1022F000BC9AF74FDF67135730AD7F1BB360B986C9
-:1023000051FE7E8F5BE6E3BDDD44F110ACBF92C6AB
-:1023100067A37AFDFCC281FDB2D3243AC75D605A3F
-:102320007CAC85CA8F697CB0D52C1F463C55FFC05C
-:1023300018AE47A5EB53A203D1E452E8BC1D3FCB36
-:10234000F5A431EEB380E7C534B91BF3D9C5152E1A
-:10235000B29B51F3C1FAE1F893E85AF2B332CD35AA
-:1023600043FDF98F231E8F125800D723388EEFA319
-:102370007DC2747413E55738025605FAB1DCC4689F
-:102380007D95E4F8FB64C78FE3743A78FDCA323078
-:102390008F4370957BF1DAEA2CF7E2BE9F1EB7926D
-:1023A00011882AC7599710E2CDC0BAD8BA4DE37048
-:1023B0003D142FEA175FDC1ED43B703E1A7F1DA62A
-:1023C00078D10ECD75413BC0F79521F1E7111CC7BF
-:1023D000FD8B9DDAB97AC6FA99E34C5FF73C0DF8AC
-:1023E000F715E799163BCFAF719C61E16B18A79881
-:1023F00005E3730C8C0F7ED2395FD73A4C845FD7DC
-:10240000EAE72D15C6EEBB30EEB3606CD566E4335B
-:10241000576BF9A315C9FF4C7EFC6B40CF47B9D66B
-:102420009BFC835CCCDF9C91D2D2C689A3E9EC42B1
-:10243000E4C73681F8CE3759F71ABC7F7E5AF0715F
-:10244000770EF1FDDBC60DC5F3538305A950FED011
-:10245000DC9EBBDC477CF1F67193709C11A2BB6BD8
-:10246000F17B6C487733436D58863E9AE8DC2DA0AB
-:1024700043A45B9D0E078F1FE8129E1FDEE4A2FDA2
-:1024800050DB58376D68CB60ED02F7B73491DC62F2
-:10249000DE9103F304A29D616BA279FCA44525F9AA
-:1024A00070B5FB1109CB4F2AC1F538AE39E33FA215
-:1024B000F3F259C6FC02B43B61BCF7E13CFEA7C68F
-:1024C0003B789FFAE7EFA3F847D9A3CF6B74ADDB56
-:1024D000A39E24D027609C5EC1A530D01FFBED5386
-:1024E000B38DF21206F6F5466A69FFB09012407994
-:1024F000A6EFEB35F2DDA95772BEFBE17297B29AF7
-:10250000CE39DC4D7669E3F50E7DDF2FE95F8D4B2B
-:102510004CDABE5F81E44A03B3D1B943FDDFAB833C
-:102520003F216DE0BB1E0770FF6FE9E7EDFFF5D2BD
-:10253000FE6275158FD3F7DB77F532B75FF5EF43A2
-:10254000DC9EAD9FE3CFF594E5EC4BD9B771F60572
-:1025500093DEC8524C9AFDCAF5858EC95E59651442
-:102560005FE57AF85C0BD56F4C0AD1F7566AC576F1
-:102570004292E3E3DCBADFD34EDF65B228F9C82725
-:10258000F438EB9CDCE07F225E2F2CF66709309557
-:102590005A0B8F9F021D6CED83B7AA58D393F8BDD9
-:1025A000AE6B58D3AF4D3944076710DFE78CF9881D
-:1025B0007FC76B800ECE623B36C6FD01D76A71A223
-:1025C000973F7CAA0DD7FDBCC0F8FEAE42E3FEAE3D
-:1025D000C09FC7F17896F63D9E58BE13358E936620
-:1025E0003E0E8F28D2382EC41BC7203A6421EA1F22
-:1025F000D6B789F69F1BF0C8381EE1E01DB43F6EC8
-:10260000EBCD4C1627A31CEFB3233C472046E4E058
-:102610003C83C9E327913C0FE2B968BA5D3D68DCB1
-:10262000A283D6F5C6B9FD793AB332CB304EC4FB9E
-:102630007D2CB9E151F47B34DE6C26FE5E7D702C7E
-:10264000E969BDAA55C6244856C9F36B14F80FC7EB
-:102650003587F9AF72433BD7C9D574CEDAF5338DE0
-:102660007939EA3D4DF0FE0D5A9ECF8DD79B8F47AD
-:10267000EB9BE7CD1BCC0807B5D6D1244EC1F6A401
-:1026800081F77D83E132E89CA736CE9F18E839D8E0
-:102690007E6B7927F1A7447C6AFC787E2E14B455B2
-:1026A000F077E6FB5C36FE4BE4FB4CD0CE857ACD72
-:1026B0001CA1F33B5F1FBA78EB729867C10F8BE9DF
-:1026C000FBA557A52D7DF221283FBD6534955F4FB1
-:1026D000BBF9B6A358BF3D9FCA95A68FE6213D140E
-:1026E00096CDBD16BFFBFA9A9DB7939114ECA886C0
-:1026F000E732C6654FC003612A2D117AEE9BE3EBEA
-:1027000027A23FA63289978F94FC760295B3B5F243
-:1027100084974763F935E1A379F1F8E29842A1BBC8
-:1027200008E46D652A7F7EE6846786A11D5F59C136
-:10273000CB639469EB72B0DEF4C779F1F4A505E3DD
-:10274000F97CA75E38DF36C4836161FE3DD297FC19
-:10275000EFD1F73902206F71FF7EA09CC7E102FE26
-:102760001209BF0755E1E7E5E98E964CE483B38291
-:1027700096528CBBCA0E5F1B7E1F31A57CDA245C8F
-:10278000F7E9A06E639C13E86B09C27FCE651F65F5
-:10279000B9482FD5E94B3613BD273EA7B19EAF5B95
-:1027A0002C3D407B2B906EE65C1E2B3F07D1AB018E
-:1027B0000FAFB58DE0780772D15A3E985E8DFC9BC5
-:1027C000ADE914A2E9751BE2A54874BB1AC76531CF
-:1027D000F579F1FE2841192D7F0EFD9E37BFEBA341
-:1027E0003810DC102F8FC337E04FD2F57C3E0A59EA
-:1027F0004EA3FC659ED773F0B7F43E6E071133A964
-:10280000FF8771FE6C0D1FCF363CBF44447B2FF811
-:1028100004F289860CFE9D498CEB239D66E8FCAA98
-:102820002B76BEADE5CAAD6E71F0784D360EC7EBB6
-:10283000357DECADE6C0D01218EC8DACC98CF37DC3
-:102840002CD9A5623CB7B1869F43F92FE9C1271166
-:102850001EA2493D1486F242E6E7DFAF94FCBBC6F8
-:1028600047E95F0DDABA34D8DEA57C36FCC3F351F4
-:1028700006C1A3CBC84763E73FB02E7D9978CDC48E
-:10288000F35772709ECA5A31CE7C98D4B42EDA4F68
-:10289000FFD817FAE919F7B72856ED3C95C8BC6878
-:1028A0007F5CABB3E9F1683B19CC323A07E9484B9E
-:1028B0002E8B8777BA9E7444D0FC5AA0F7A23EF0C4
-:1028C00049D2DF483F018A0998B3D0AF358BF4185D
-:1028D000C16293317E9D519341F8BA09F412F4B369
-:1028E000AB159D39E42FDF2E323CB760000E30125D
-:1028F000DF007E7E383E9B7FF7AB1F1E2AF1518B97
-:102900004988AB5F7D38DEA49D9FCAF79736D8AC67
-:102910003CFF53FB9E859EC7D2602B5ED344F3B32E
-:1029200071FA31ACD3A0BC16639E9C2D9DF40B793B
-:102930000253501E0ECE8331DA092ACDE35BFDF13E
-:1029400005C6F59F3B9DA4FF7C4B8B2F08B33FA58D
-:10295000F54905FCB27A308EE015D05E492D3D2A4E
-:10296000B1B103DF9FC4EF36A13FAB2B3BF87FC76C
-:1029700047C5E3DF9CF434E5851C33F138A8113EEC
-:102980006685C7816416A67CD5068D5FFD3F379CA2
-:10299000204A0080000000001F8B0800000000009B
-:1029A000000BE57D09785445B67FDDBEBD25E924E1
-:1029B0009D104242583AAC4102762721806C4D80EE
-:1029C000880A4C585450841B886C59059D41C73166
-:1029D0001D02880ECE84272A4F511B0444079846B7
-:1029E000D9D4C8B48088CF2D6E336E8F495C5925F9
-:1029F000864171C637FECFEFD4BDA46F13067CCBE2
-:102A0000F79FF73DF8B438B7EADEAA3AE7D4D9EA37
-:102A100054B5D8633BD19825F8CF8FDDF0FF4E49F0
-:102A20005FF61542053C02704088F642ECEE50E439
-:102A3000F052795269C847E5DF7ABB8518807A2D54
-:102A4000B3A89F1049EECC91491E027FF8F1C71F31
-:102A5000F3859882AAEE427CDA5D4BC47BD78BA2C9
-:102A600031564588E4B19A4D73093146A5FFE50911
-:102A7000D1B245093AE8F9687F8C45A4085179C874
-:102A8000160C12BCF055EA84E0858FAA4141708B88
-:102A9000F0AE6944FB80C31DA0F2A1B8FEBF1D4A81
-:102AA000E5678FDABC0EF41BF0BF9345FD96A05F7F
-:102AB000827BAFB1088F539F17FDD727182B3C5946
-:102AC000AD70DFCDC926B85FA8A3A9FDE57BBA9993
-:102AD000EA7DE1CB4CF5B987724CF080862B4CED4A
-:102AE000077E50608207375E6D6A3FE4C824133C5E
-:102AF000ACF90653FB11676799EA4B130A0F2EA630
-:102B0000F91E4C538532488891A2D4D4BE542DB3BB
-:102B10000B0BFDA3CEF66923BD57457F999EEA7442
-:102B20002BF07C668F22DA650A31778DAC37DE9B1D
-:102B300057BF6A790695F383E6E7A5C2DA0AD37B25
-:102B40008B3F99FFD68188FE7AA7145B92A8BCDAE6
-:102B50001B9FF2651C262C06FEA8325DBD61D0E9E4
-:102B60003DD5EB90A4603A2FDCAA04EF253AF6128B
-:102B70003D1F02DD88CE22E8015D657DCB5A351808
-:102B8000A07EBEAB9EF7D6011BC18772D73412FD63
-:102B9000E7D638DC2AD53BD2CCF48CF198E91997EA
-:102BA00065A667BCD74CCFC441667A26F9CDF46CD4
-:102BB00037D64CCFF645667A76986AA667BA66A687
-:102BC00067C63C333D3B5799E9D975B1999E9981C8
-:102BD00005A6FA68FEEDBE62A1A9FEA1B8BD5F6AB6
-:102BE0008487948EAADB414BAF67DD1DA6EF097584
-:102BF0009C7D19E1AB344315AABB950F02F457AE87
-:102C0000EB2A5E5F73880F1E263A9C112B0F6678A5
-:102C1000CEE7878A3DABEC589F3F951F7E0D3EE87F
-:102C2000DBCA07C47789F8CE8FF833E2FCD2A0F371
-:102C300044AB7F9597E4C806AFB61AE5D4DEDF74DF
-:102C4000B192DC1045C5BD8BE2857089E619E0A71D
-:102C50000A91E0BD17A5F3934CF00BFE38D2E97F43
-:102C60007ED1C34A785374BC892879A6D4FF29132E
-:102C7000F35E4BCCA8A2FD849002F9D54934A4435D
-:102C80003EA58B2A05659AF0AE50316E4FE756F996
-:102C900097C184B184E9FD0F4B6CCCBF4BE2FA6F56
-:102CA000015F7E502BF9F2349A0C16E20611B2E164
-:102CB0003B1FC63ED219FD1510C295C1A8ACBB0979
-:102CC000E39F8EF17B85B84934DAF0F19942D8510F
-:102CD000160B0F97B385DF8EF76F16E1E598CC1FC3
-:102CE00053B45DC04785AA754D053E3A3574819C45
-:102CF00015AFB7C3A02F8857435EBF8B7F52BBE38E
-:102D0000DEA2BDF8CE28A7E7D607083FFB2C625EFF
-:102D100088E822C6B5E3710B6B51BF49FDDAFACEE4
-:102D20001296EF2F289A067C07D29DDE8D40725AAC
-:102D3000E81985E67759B227E7DEA4D6F66F782D35
-:102D4000DC9E582FA050FBA777C432BEFA76589766
-:102D50008C79FDD47E3FF4FADFC3B88DF6179BAFB4
-:102D6000DDEE5D701BF5DBAC88AAF53488F774BA2C
-:102D70006438887F68BC196A82B716748B9B71B0FF
-:102D80003DE1A1A283F629F4D2D4EBAF5A0E58D973
-:102D9000D7CEB390C677AAB8311FE325FC7F89FE52
-:102DA000CB9C847F9ADAC9CE5AEF44304591C43F18
-:102DB000FDA35F519BE397E339A0E37F7707ED1411
-:102DC000FAD96769E8E2051DAD0DF94C47B79CD704
-:102DD00049BBC4CB85F05010D7793AF05FE27078E8
-:102DE00055C2678122BFFB79E2CC199534EE9B2D49
-:102DF00045A961D534EEFFE071BB8ABBA663DC3622
-:102E00007DDCCEF63ADE3DD95857171A772DBE4FE6
-:102E1000780AFC4A096ECCC4F3F05380770BB7FBF9
-:102E20005E1FAD398BD4CBCD354A703DD5BFA5E300
-:102E3000F9511BB5C3BA748AE41A1ADFCF862D5B29
-:102E40008776BFD69C3CEE8DC27BD9EA4CD043B08E
-:102E5000BCCFB85B09D6123C4B7899EF4B445197E5
-:102E60001DD42EC3A7A5FA681C7F8EFBFB804C0BDC
-:102E70002FE301EFD177762DE9E0BD17D0D04BE3FA
-:102E8000FF2C921CE87FD278A9776ED6F1364514D4
-:102E9000F13ABD4E5471490BFE6405B59B4AFFC221
-:102EA000FA24B81FC6370DB0AF755D4F170D5CCE55
-:102EB00010EE171BE95BEFD474B8ED766A33C9D214
-:102EC000DCC5AE629DD2BACD64FCF7F311FEBF1D26
-:102ED000F3F6610578BF93E418E8BDBAFD25F1F17A
-:102EE0004445E293D6ED00E081D66D9ECF12B17ECF
-:102EF00046B797FC6775F7FC47EB870463427AAAED
-:102F000010574A51281E3A9D2052689E0DDDD4A0CC
-:102F100023137AFA4EEB0E9A6703D9130ECCDB5FBC
-:102F2000DCF114D58F257D7BAF94AFF1018227F8BA
-:102F300055712FF341E3D2F9F4FCF541544FED5FA5
-:102F4000A911F17904BFE2B3796B890FC79CD50E43
-:102F500024523981E47E985A5F9DB66A34EC83B17D
-:102F60009D488F44E889AB7B98615A089D40A76BC8
-:102F7000747C8FCB36EB9D09D03B46FB36F40EC9F3
-:102F80005715F8BDD1A7EB9FCBC465D03FFBABF77E
-:102F900088CF48BF187A6814CD30947D613D64B500
-:102FA00017CCF631DE3C76AC8F59566A0F7CBBB538
-:102FB0008E1323D6CB4BF90AE3D7438AC742F37F5C
-:102FC000EB901A047EACFEF010E06FE18B0AF3E99F
-:102FD000233EAD02DFFBDAD638077CD330343751DD
-:102FE00050FF9F56D3407AD3FAAD760A3FAD852F76
-:102FF000ABDD0C1FA94EE3F258B587CB13D5595C56
-:10300000FF75B597E1FDBEA25FE07BB3567C63D54B
-:10301000B2D17F15DB478B6AAC02F45A14BF50C2A1
-:1030200036A71B42F8EECE072D7104DF1D54BCD02D
-:103030008BF3770497C34C2BADF7DB5D042FEA9C31
-:103040003CCA85F60F28CCF5730E551DC474BF7E9F
-:10305000EFD3EBC68BD6F9969F5584464B2E7B80DB
-:103060007F39FAFFAA7A108FEB68B59FC7E5AF6F7B
-:103070003AD88EBE77BC7A2CC3FFEE2B5A09BEF528
-:103080008B6FD88E18BFA5C90A3B638C5FF183CEC6
-:10309000C3FD2218247CADB149BDB286F40AE4C058
-:1030A000C87E931EBD5540EE6B0FA29F6B93678F3A
-:1030B00081BD3A615031DBAFD7FF20D87E35F8FFB4
-:1030C00062EBC8231ABECEA0FE4E06247E5A76BC02
-:1030D000CB708B95F04333DEBBA3B454907DD0729C
-:1030E000F61DF99CDAB19DBA53B65B6893ED16EE06
-:1030F000FC75323F57946611A1EF8E131D05E12137
-:10310000CE99F1E8E7849FE35B7F91A645F0D7F184
-:10311000E4D0B71F414EFEBBC5BB9EF954FBEC7912
-:10312000C8D1A56E96335FDB425F3E0C39DB99F464
-:103130002AD757C54D223EABB00B8DF94E687D01A5
-:103140001F8F15338B5CB23F4F6FF91CFCD86BDBC4
-:1031500043DD7EE969ED6F73E8E68F1E061DB67DDF
-:103160009C70198DB78F2A422AE62FE438021B6221
-:10317000B99FB267EE49F613FC94225A54E6F72041
-:10318000F3F3AF6D622AFACD52ACF6C5C9E457DD50
-:10319000B73B03F3EEAD8A2A95D6E5ECDF3C97F119
-:1031A0001CBDF724C92295C6FF82CDFBF51E7CF716
-:1031B000511A3FF5FBE47DE539908725FF32FF3258
-:1031C000E0E18F105A4487DFEDDECEF602F1A477FE
-:1031D00014C9B57EAB5F5A924EED2F5FDB64E948B0
-:1031E000A56F83528BB274CBF6776AA8BF5CB7A584
-:1031F0000AF6EBC73E0F8F2B27B46EBD023DF0C31E
-:10320000131DB12EB3577F53D0515CD8CEF85D97C4
-:103210000F5A8A3D2C17F8FD9DF593DFBD51C08EE6
-:10322000210B06E32DB67B59AFD1B46DC0CF8EEE26
-:10323000EBF0FE2E4B80F5556096B4734E1605FEEE
-:1032400015F32FA7F60182CB7D0D4DB7537D795233
-:103250003711A0F91F092E9A86FA818A70033F154B
-:103260003B1E28EC48F0C9A1C2AB50FFF3769E2E5E
-:10327000647DD8996C757C6F476DEA0DD087D90550
-:103280000354AA2F5243DC9FA894FD55D66F7702B2
-:1032900026D427ABC46749F523F767785AE96369F1
-:1032A000FC4DA695BED79EF429C6BB2633905EE59D
-:1032B0006AD5BF19BEA21F587EB9EF2FC677BEA030
-:1032C00071C13EBB547D69B754CDE7F1A409776065
-:1032D00070EB773B5BC2F3310F5A1DEE007D67A3A5
-:1032E000BB611AB723F8B7DCAFE6CA1900FB8AB096
-:1032F0009E22F57B2DFA754FEE027A5D6AFF0FC5AF
-:10330000FD9DEDB44A4B82D791D76AE74C6D57FBD0
-:103310006223D1EB910E5A1AFAB959B79385D5EBBE
-:1033200081DCBFA3833F3D87ED34D2C316D6BF9D5A
-:103330007322ECE673769BF3D2F4EFEF3AF8BBE33B
-:10334000FD4B6DEFD1E312E7E4F0991C931CAE8DB9
-:10335000B70B1F3DAF5DEDE038863860293B48FE76
-:10336000CA307CC2D2FABD45F1391DA01F6A8568FA
-:10337000135F7B69FD6B84DB30E90D8DE4C0F0B336
-:10338000CDAAC672A2617F621EE4ADF0C77B103782
-:10339000B0082D423F467F87E85580F98D14714271
-:1033A0008BD0B37E9164C7BA15AEE44B9C77F80915
-:1033B000B3FED9F744E4BC87B67C1007138CF0D178
-:1033C00001E585E6F5A23EAF3F605E543E9F5F3467
-:1033D0002587BE3FEC2F6E2BE637CC3AB18BAF1B67
-:1033E0008FFB068C7BF85F2CE671FF106B822F75CC
-:1033F000FCB729E4D8818FBFB107B1FEEA612BD0B9
-:103400003CEAE76707B1DE77D945C009BF67929DFF
-:10341000EDE0FAF8403CE46ABDE20E21FEF482AD34
-:10342000619AF48B847BA30FFCFBE623E0FF1B5A1D
-:10343000EC0AE2591D1DE24BD857424D141B532292
-:10344000BEDFDECD710E157A2397E0C1FAF36976FF
-:103450007E5E6B13AC2703D362795CAB93AA5EEB01
-:1034600047F5AB6B32BC3472F18108AEE886FA3BAB
-:103470005596E7432CEB373E08BF67621AEB99D5A8
-:1034800049E18C4AB49F7F993740FCB0EBEF2AEBBF
-:103490008FD53E7F7AB20B7290E43CD179F5447FB0
-:1034A0007A6C0ACA540BE6DB91E43C3FCFA4765415
-:1034B0007E6493ED3ED4E946984E87BC7DB8A4A7C0
-:1034C00080FC599753703FE8840A27F1F3B59204C2
-:1034D00062DACD0F88DBD14E53836A26F0F29BFB74
-:1034E0007A117CC32CD58D38DDB5F3629A94FE54E5
-:1034F0006A6AD891402F4C19E38FF4D7D7E5F8EFDB
-:10350000079DCB437DBA7F1EC1C7D36EEEF973C84A
-:10351000874FC98F86DFBD2C557B84D7E91E1FB727
-:10352000DB43C6CD8FD0134E4F7FB6B74B0C3F3326
-:103530003C1BF8DDDBEC643BF642FC2084D77919B8
-:103540007DFF418B08819FBBEA7ABD160100D0390F
-:1035500014C37C307692D3CFF12A97653DECE8C74F
-:10356000895ED06F819D0EA617094AA6DF837B3B3B
-:10357000B35E9AA9CBB1DAA9B1FC5EED765BD0025D
-:103580003A2BC1A736E1BD1763587F96D905FB2BAF
-:1035900065CFF7653ED865F7672E43BF7B1D526F39
-:1035A000277812B9FEDFDA09D4BFA0EBEBB2D870EE
-:1035B000AF24A253E7F65A3DE8417C57C5CFEDF260
-:1035C000F9E160C13AAC4B41F64DDC7082857F1D5C
-:1035D000E45580ECA08D5E493F8C4BABEDBC1EE307
-:1035E000D5681CA0B3B843E5F91CA6B58CF91DAE8F
-:1035F000EACCE352268D4DBF99EA3F5B18C771D7DD
-:10360000C34507CFC00E389CA6F2BA270975DF4024
-:10361000AA279DDB702FC195F33F7D73203DADA898
-:10362000FDB0CB1E4F2BDEA72F291F27880FA62FFB
-:10363000B8738248B8F07A9D5EE6804FD9BABE85ED
-:103640001DCE9D8449AE1FCBF17F8879DB73B54FCA
-:10365000C00F95D9646F131F7D6D6F780C7195CF76
-:103660003CDA9FF1FCD4735F6DC273616DEEC5FCF3
-:10367000E16C2C445CA6CC22E34A0FE56A5FE03B98
-:1036800096C604A65F65C8C1F48BCB6E9072F1CE6E
-:103690004BD307C7EA37EE52A89FD2D8FA0A2ED5E5
-:1036A000607FE8ABE34A3841E9CEF8D5B0AE4EB81A
-:1036B000C309A08F6691F65EE9E6E879D25053110E
-:1036C000771342FAA921FB101AD70212BD0FBBF1E2
-:1036D000DCDEDA3EB3958EF41DA6A3707D32E3974F
-:1036E00068FF549F9C7B09EFA5497B7E3324F37CC4
-:1036F000FC45C3C67CCE1F8FBE4E8AC2095827C761
-:1037000015B94E4E0829BF029B63F478811CC7D7B8
-:10371000CF75E071A4EAEBE86B456FF79443B623ED
-:10372000DE833D53FA7BC9770FDABCAC3703A44F75
-:10373000202F4BDB49B8D491E686BDD5510D586298
-:10374000C197D582D70B8D8DD7E5F16D19FCBE21C0
-:10375000D7449110906BA5DBD2D74BBB4EF79B3172
-:10376000016ABFE077B23FC090FFC79ECED0FB9703
-:10377000EB299AAED178C8CE9571AEDAF8FC0EFF7F
-:1037800028BE9995F6F15A88A0076D725D07E2A5EB
-:103790001E21BB256D623FEC4FD84DDFFD3ADE3E6A
-:1037A000D3EFC23E85F9B9F1BD41B9D2EFEC1A456C
-:1037B000F78E6AF34BB097C41382E544F43846E0C1
-:1037C0003DA2DBD34F9FA3B32AE94E8C64F09787C9
-:1037D000F1276CA0CF8776838EB766905C2F05AEFD
-:1037E000BAB5E271974FCB801EF91A30E17B5712C0
-:1037F000C1D9B0B7A4FE3060831ED17CBAE4C3390E
-:10380000198D904FB9D23FA88D49E82F12517609F2
-:10381000420ED4105E514F7A70665136FCE1B1F71A
-:103820007F6E6B9DCF97D57E3FA9A073F09C353EF0
-:1038300027D6E7DCB53EE7AC087AD46ECE3DE4216E
-:10384000BC9FD86C456452D45A83BFB92205CFD5EA
-:10385000504070BD13F83EE1DAF726DACD599B945B
-:10386000A346C8A7B96BC6F84B22E8D077B3992E08
-:10387000FD4266F8F23D66F8E7A4DB31BF9FFA9E91
-:103880002F6C86730F99E1DD839AD51FA19F5C96FB
-:10389000A05341D9A2FE08F91E5483F033BADE5971
-:1038A00034793CC147D6CEF682CC73DF5F920FFAF3
-:1038B0009DDC79F7AE727AEF48B2C50BFFEAB80823
-:1038C000FD713CD1634EFD2ABBD583F99AF97C97F3
-:1038D00045E7DBA7651C707ED05C7FBE7CA8D1E38A
-:1038E0004E222B92AFA2E94FFD5EE7A781952D9E58
-:1038F0007C3FEC9F79E388E1697C8343ABECC27544
-:1039000029FD0418AFD604114EA3F135DD1DCFF10A
-:10391000972B168F129FD1F7CAADEEFC5FD23C6792
-:10392000391577C0DD1A576FDA9E5E017DBAD16D09
-:10393000F1928F23DC83AA0E66E4C19F1021B71792
-:1039400071FDBB96C3EF9F5795C0F8992F821C97C6
-:103950009FB5D4D12A1FE9BF929551E3591D514F0C
-:10396000F398B7D6DC7EC1861F1D91B0E1975E51FA
-:10397000BF4EC57C6FD6C7AD0626B05EBE428F5720
-:103980007C8EA6A46FB6762FDA9D8BF6AB47CA7AEB
-:10399000AB53D7B37EF6F3CA5D760FCB33EBDBCBFD
-:1039A000797F87D621F4C3A1F8393F87BC3BED145A
-:1039B0006E870FED3586BF6C27FD42DEB7A0F6A7F8
-:1039C000D72AACD7CBDB49B8FC09258818703982D7
-:1039D000B6809F9471DA321D1FE0137FC47C40AF24
-:1039E0004858D419F1F130FBBF1555C20B3B4010BC
-:1039F0001DFD06DE783F2A6C3F023D1B50420FFB47
-:103A000060EF99BF53B9E74747247C2EBE4CA4AB67
-:103A1000E1EF07198FAA5DF821C7D5BB62D96E27E0
-:103A200005100BFD6ED3ED6BB122D81EFA6A35F48A
-:103A30001595CB743B3CB04AEAABD549FE5E6ED4DB
-:103A4000AF4AF7020F3728BA7F0BBB3E09F6F53EA7
-:103A5000EEB75971BBD727A1BD08C4A4B07D2DFD19
-:103A600084BFABACEF9AC97E5F0F7BDD170A633C66
-:103A7000AB1FC8647BFD0543EFDD1723EDF9F3EDC4
-:103A80006EB6AFC4FDD27EFC4808E9F7F6D0BE039F
-:103A9000DD67AB45BC1955B2C49F8EEF964CB25B47
-:103AA000400F31EFD2F645365A65FFCD345FC4EB97
-:103AB0003F578A0E5A22EC60679ED40FF905FE4DDF
-:103AC0007A3B2FDA9558DE663C9458841BFEFCC680
-:103AD000B3AAB012BCB1CE115C42AF9474F3F75AE2
-:103AE000988DF7647CEAB04FCAFBB83CE10F52995D
-:103AF0009427F555529EC5548AD132CEF2798CE482
-:103B0000C3E9A2A890F7073C52DE47CFA3B3FE9DBE
-:103B1000127B83793C9FEC67BA90CE732F017F8F25
-:103B20009676C7E7B728ACCF693EBDDC04E7FF4B0C
-:103B30000CC7173FD7F591815FE29F0188A31972E7
-:103B40002B49E797D5F7049F8A217CAFB211DF801C
-:103B50006EC4371BF398EE6C17AE9E96CA74BF41C5
-:103B6000A7ABB82F9EE936C4629178BE2F9DF14C69
-:103B7000EDC55FF1DE188FB4E72FD10F23BA0FC860
-:103B80001B70BE3F66D05B588303FED1FE4DF9EE3D
-:103B9000ADBB02C4FF0B7EFF4082A07647AD75A986
-:103BA0005E7ABF6CE3B2043F9547AC810437F57F82
-:103BB00034A88E0DB681EF453A3F60FF4049C5BE3F
-:103BC000AB94E3C79EFEDBF23B689CDF2AA219F2AE
-:103BD000B162C7F7CBEFA0F91DF43B9B214F8F5883
-:103BE0001B0B2177E717BBAA6ABC58BFE638FE82D9
-:103BF000271F48F530BE031996345EFF1978AF626F
-:103C000083CD0BBFAEE23DD5EBC1BA17CDCB31BEF4
-:103C1000E8F72B439FD9817FB74534771AD246BD49
-:103C20006864395FB9E3D7DFA809288F7E04FFA253
-:103C3000326AFF609EBEBF12BD8F303BCF9CC74033
-:103C4000F8E13C86008DAB27B38B8C3BD73EF5501B
-:103C5000FF26D80D1B5E4B50B25BF70F8C7D9796FD
-:103C6000D0ECC79FF75C785D7EADC78D5BE926E53C
-:103C700098670F0DAC83408081CB325B3801F67EB4
-:103C8000D93A1BCB91B2AD4F6C7A18FCF6A1C3DBCD
-:103C9000D303F8B41DF2A04CF1372B2CDF458292F0
-:103CA000DF4AAFD2AD5F143E02FB3A5D15E3885E9A
-:103CB0000B9E3D23DBFB45730CB52FDDDE5408FF67
-:103CC000A04C735539DBA0D7A8D04BF646571BF450
-:103CD0000A3515729CEAA9EF981E47F72AA243E617
-:103CE000F9EFCF5BF7855D48FFA0B95D92C417F48B
-:103CF0005D65482DB6279EDF9EBE3FE1F93CAE775D
-:103D0000C35FB9181D4701178813EC8E1749D0DB24
-:103D10001F3982E340DF6D8B1204F1FF57D62AC9A9
-:103D2000F78F2E4B859D37CF16487573299FCF7B14
-:103D3000EC36E6C7B94A55AA3B9BF93DDD3288E728
-:103D40009B8E79DEBCF65A9EE71CA1313FCE7B5498
-:103D50002D0A5279C62AC66E6F63DD9CD4E5944362
-:103D6000DCD21FEBE40C7D097AFC2BDDAF0FBC230A
-:103D7000FD6987989418B99FB457978B01113C0C33
-:103D80003D50D960E33885FAF699427CE7D64C6B12
-:103D900015F23D68FE011D5FCA8FD27FF120EFA1B1
-:103DA00012FF227D3AEAED311D1AB3F1FD16FB4DEB
-:103DB000D4EF5FE0277A4DEF31DEBE5AEF88552E03
-:103DC000A73255DAEFD1F3E8344031ECB877440448
-:103DD0003F556EFE8AF949A4A922314DC2D8BF7061
-:103DE000CF72552512DEFEF2DE6776C4BF032916B8
-:103DF000D113E36DF88261E16DEF417BE3FB957BCD
-:103E00001C221CB96E377C11B5AECDF54254313E43
-:103E10002B45A207FAFB2B7B73E10BE887FADD4801
-:103E2000FDCC21FB2B6CB2AF9A0B1F813CD9637781
-:103E300073FC81ECCF7004DF9CDB1FD5F705E7EA4C
-:103E4000F2201A0FD1F2E1AB28F960BC2FD6B6BD33
-:103E50001FD52A17022C4FCB6C22003BA3EC430743
-:103E6000EB8FB2AD723D0A92A73D697D1CDFB2FFB8
-:103E70008F37C09F0DD952C671AF66F93BEF992FAE
-:103E8000785EB309FF315EC8DFEFECF07FD346897F
-:103E90006607F68B57FAECE0FBF3D6313D6F731DE6
-:103EA000AF5458BEFD57E52EE1DB0E7BEB62EB75A0
-:103EB000EE05E46EF20073DED019919D380495EEA4
-:103EC000E2AEBC7F10855F03AFD172F4E93C4F9B3B
-:103ED0007294FEFC5144E0518846E6E36F492E623D
-:103EE0001FAE62C3F7ACD708ADCD0EE2E38AE03770
-:103EF0000C2F835E63F8A52988579E3F6F333EA33E
-:103F0000EBDF03EFD3D08B9EB3B15D50562FF31C84
-:103F1000E93DF63B2A11AFE7D67507335222E1603F
-:103F2000141C8A6AEF8F828BA2DA6B517095A97D7F
-:103F3000D99EFDEC67D1B84DED1C8BAF613FE47CA1
-:103F4000BB22C878ADDCF18D3D00FEE8D46C875C07
-:103F5000B42D1181787ABFF94595EDDE539EE604C4
-:103F6000D829CB62A41D77CAADC349062C6616D3E7
-:103F7000384E05FABB9157D01C23E32DA78A9A131C
-:103F80009222FCF6A67A35C143ED1B83626CDB7985
-:103F900031B58CD74671A17A69CF8D517FD826F380
-:103FA00045ADC241FD35D67CB70DF1A4CFC97F82A6
-:103FB000FD5252737D02F65F4ED577FFD954F881DA
-:103FC000AFAA9CF325027E3BF226664B528A23223F
-:103FD000F0E0509A9F1A9F77F005F857C428D8FF51
-:103FE0002C591965DF88A2C430FCE9D5D1F90D41FF
-:103FF0003BEC9BB9A467218FE6AD35D72FA83FCE08
-:10400000EB6541D47AD1F4B871F47A596CAC179F4E
-:10401000F0E9F9969CD777EA90CAFCD5B2D42696F7
-:10402000A7C8BC5AE4A3B4D4CB7C9D963D1216011C
-:104030003D0F485FB706DE4E603DF5BEB0DD7262F3
-:10404000E7BFE7FF12FCB3EBE3FE8F507962D7873F
-:10405000BD5E00BCFB4F5D3E16E7B71FB5F7FB1911
-:104060003CAEBD0E81719DDAFB4A17D81BA79E7727
-:10407000703EC2A9250EB6D7037BE3396E71AAB391
-:10408000B4876B5FFCAE7F23EBE3A54CC72706D854
-:10409000A55D55FF37D68F2DF50E0FE651B9378E3A
-:1040A000D755E5F331BCAF76EAC5EFF223E371FFF4
-:1040B000D5F918FBF0A7E2C5D467C0BFBAFD5FF918
-:1040C000C2E0276AE02FEF78C93E1B79257FF88F81
-:1040D000FE90AFA79E7989E5EFD7B6C6C710DBDCA7
-:1040E000B6F3C0C3B674C4F5E8631D85B87297F51E
-:1040F00046AC9FF3F122F1708AF08079115EE6C13F
-:104100002EBF103E5EFEA7C5C73733A49C1B28B048
-:10411000EFD38A17C52F9FC773BC8AE62F9FEFFD89
-:10412000AE3FE4D0C5E6FB19E6DBFEFFCE7C95FC96
-:104130007FD6F94A7EBF678087C719CDF7E7F3F5C9
-:10414000EE9F33BC2DDECBE3BDC4F59E99FF7F8B84
-:10415000BF47FCD3CEF762F47E55A777BC1BFBA00C
-:10416000A75EFC8F2EE227CC7BC6FF523E37ECF9D0
-:1041700002D57BC847ED5F13A1F7BC996C95B46974
-:104180008FFC3ADF88A7487F6A14FEE541FB9CA5B7
-:1041900021AC07B227E0C7D4BA720EBC4DF02B6435
-:1041A00027A8BC2F2BE349AFA4F98232BE5B2510B0
-:1041B000CF2AF8D36C865FF75D7900792585AA8CC4
-:1041C000C7ECAFF16E68A079EC4FB2786A091EDDDA
-:1041D00069F6E7DBA9DEDD5175C33FABED94EBF487
-:1041E000448C6FB4CBEC675D13E5275DE531D78F69
-:1041F00015CFA460BF6E6CB64DE07C4E21DA47F857
-:1042000095F3F3DD3CCFAB44DD52B7EBA7E3E939DF
-:104210003DAF92F0C2FB36814EAA9E1767C69B0047
-:10422000DE5280975CB6DF03C27BE06D82ADBA7D63
-:1042300025F4FDC74267FC26F8D10E51100E127C02
-:10424000C663AD427BAB207F58CE93FDE868BC09C6
-:10425000DDAFB6EA2418DD69541878C6F3AE69A656
-:10426000F779DED178FEE978DDD76911F09A16EF9B
-:104270000D822F3A3D9B82386B2DE159515AF169DD
-:10428000E0291AEFBFA1B14A7F5DE2BB93D567C5B4
-:104290003A1BA6DBF3A3AD4912EED4A016F1FA0B3C
-:1042A0004ABEFE8BD70A7B64A42B89F349857ECE58
-:1042B00042D5F7C39161C7E320FF1479B913ADDA92
-:1042C000ABF99C8FEF1605F05B0B4408F15BA5FE84
-:1042D00095EFE11FE17C4911EF6B1EFC00706FA7A9
-:1042E0002B0C7F50ACB59E38672723EE1F75BE623E
-:1042F000C2A0ED2341AF598BE919E2586ECF41AC12
-:10430000C7E2FB1D1ED0AF93B581EBC9D772D70CA6
-:10431000C66E7588E1D812B2F4D3D1EE9591DC7EE9
-:1043200091702B4948B70B29805D6E99AF46CEEB53
-:10433000B780ED4BE33DB5326E22C04F3D5076C3A2
-:10434000F765FBB4D1F43DE4BB098DEDE5D81E1C47
-:104350000912DD9422DE7FEFDA5DE645342F73B07B
-:10436000BF537C77E75E904BE30ACC71EBA103650A
-:104370003CC7289F1A28E5886AF1A6E13BB396F668
-:1043800061FF4B8D2D2ADF093C6E8B633E2F5E7ED5
-:10439000D3F801F4FDE26DEDBC18E6B109DBF3657D
-:1043A000FB69B7BD4FCFB5CD31FCFCF581DAF7F92C
-:1043B000C833503C3376D28359D7EEB7A751175A3A
-:1043C00068E249C41D2704B6BF897DCE0953546EE7
-:1043D0003F41CFFF144BE378DF7C7CE01B6B1A7D01
-:1043E0006F3C3935A86F8A7177B985C65FACC79BBA
-:1043F0006D03E53A546385F68C0BE3EADCAB1B3DB9
-:104400001F2F643E74F4BA1DA9B7EF3ACAEB4901F5
-:104410007E9418F7FABCD6F6F80EBE7BA58E0FF781
-:1044200040B9EF6BC084578E8B97AC7034754F409A
-:10443000690BF7A6B27A7041CA40AA1FD74D14AED5
-:10444000C1776F57C57A1E6F7331C7D9E3B33CA0EC
-:104450008326EA38DF48ACEEC9FB394D2305F34F1C
-:10446000D3AA4C83DE9C9F64F8734D23BD0791BF94
-:10447000D53CD2E95DEF457E4B288C38CAE13572D8
-:10448000BFA66B6DB807E46CB34FEE837CB138D731
-:10449000033EB9F981C909909FB357AB6107F87D15
-:1044A000A5396F49B8BD9C373EBB6EA41DFE6B8914
-:1044B000CB6FC7BCAE1AA4790742FEEBE7222FC32D
-:1044C0009870EEA7AEF875F87D6A02AD67AC3FABA9
-:1044D00027017E7574DE53A59EDF64C0CB52B5C143
-:1044E000F8DEAC44CF363E5FB9B83BC7556F1F28E6
-:1044F000E5AFB0867B003F8FD15AC0FA3C912FF9CF
-:104500006F5CB2BB978BF93746605E4D36772FF004
-:1045100073D3B2180BF0346E89E4E37BAC727D0583
-:10452000FD1E4B80DE8FD1F9777A8DB5681DF5D3EE
-:10453000C929ACF1C9C85BD3DC18C7F840CD61F814
-:10454000D7B3757D357BA53C3FD67594A4ABB0360B
-:104550008C6E47CF8F6CCCCC415EBCC137F5830BE2
-:104560008A0646D07F5C81BFB03D7D679CC5D30283
-:10457000395C324579A9BBE4836B07B23F5FCFEB6F
-:10458000BC85E4842309E7061B248C7C55C88DBABE
-:1045900087FCCE08BFDD2E7670BDBD44E6A376B5A0
-:1045A000876B38FFEA16E15E42F026B223AC362173
-:1045B00036573BB97CBA9AE45D4F21B654A731BC5B
-:1045C000ADDAC365A83A8B9F3F53ED657847F52078
-:1045D000867755FB19DE533D96CBE7AB8BF879B464
-:1045E000FC99ED9AC3F2C4DD8B683DF87CBE99E17D
-:1045F000A17141FE3885FB6EE4D30A29EF92B2A483
-:10460000FC11BA3CEAD647F0F99BDB410FC2BB6D07
-:10461000C5480B9FF7B436A683EFC6A827B6EE466B
-:10462000BC639E8BF3B25A4423AF931661F106F23A
-:10463000A4FC7110DF75BD6B6C66649EFA8DF3147B
-:10464000618DE0AF9BAA628435423FCD5C9C648261
-:10465000A72F7EF7E50EF4FD3EDDB47B41FFC37767
-:104660007DF9E89FE8F9E3771DEB29CFF5FEB02E41
-:1046700032EED2229A256C75F27EFCE377A4A7B6BF
-:10468000EB26BF077ACDC23F3CA04FF3D127B10E36
-:1046900097A9DE25047F04FA103E3FD1E953BCAC54
-:1046A000FBF25F605DFB9D5E85BE73F88EBE858309
-:1046B000A8FDE3FA7E945841788DD43369527F7D0A
-:1046C0000AFD9524F55901E46858EAAD4F7F951A23
-:1046D000B81BF5B724787102425BD1213097E09581
-:1046E0003EBB57455CAF5E2C47DC86702CED8A8064
-:1046F000CDACC71A3B25211E6C9C938ECB0B3AF98F
-:104700009C167584FD985959FB443AE4529DE2C6C3
-:104710007E0DCE753A9321DF14DE1F451ED014D2D4
-:1047200097CF0E54797D9DCAB772790D92E508AF87
-:1047300031C2CBF1999295D41EF2B1CE679F13216D
-:104740007F67E9CF676759B8349EEFD3BFD77185CC
-:104750006F2AF8A323EAB351E64CC5F83ABA0AAD7A
-:104760004AC4FE6FFD402BF7772A5FF67B0D884A1F
-:10477000EFDF9BD5CD7E73369FCF62BD65F4332BC3
-:104780002B677937E8EB9523811D516BF3A6A55074
-:10479000BB97075AF579E8E7C29D323FBBEC027A36
-:1047A000C388D31DC13FE539499EEF826DBFDB86CB
-:1047B00073120B3E76B0FE5A70B9D44B223B983F31
-:1047C00099039AE6B8F8E8DF9D3C78378DE724CE68
-:1047D0003121DEBFE3333BF24369D95425A60356AA
-:1047E0009B90671A1D9F3DB0EDE38436E3E23BD416
-:1047F0004B8B8B2B3F24402F18F319F3E29954D89D
-:104800005995CA59DE67AA7C9124751BF38E8E8B4D
-:104810009F8B9F8B95DFA88833DF79A4CDF87974BF
-:104820001CF0FB81D1FB11AE02C8893387D420F67E
-:10483000D35B823D13451BFD1BF1F3CA35F4523B9C
-:10484000AC4B4F22F6C34E5DC02E1F3E48FA2F27B9
-:10485000F578FBA92D2AFB4BA7B6C407619F566CC0
-:10486000B9FF20F6292B36286C9E978B06C617E1D8
-:10487000513823F518F2DDDAC1B8F624425E19E3A7
-:104880002BFD5D7C15F86A7E48F16FA471B4383D4C
-:1048900089ED23C6D17190E4CF5247289FF1AA8FAA
-:1048A000DB3D48CA41A3DDFCFAFB392E4DEDBE6667
-:1048B0007BE7F77182F30445F39B18DFF1B5B95E2E
-:1048C000EC2BCE0F6DAFE0FC8E2D716EC4218EE906
-:1048D00079CEC6777AE9FDF51A24ED94E3FAFEDD88
-:1048E000F16DF27C3AC689F5744C31E70B66EBEF5B
-:1048F00065EBF87A475FC746FBF9A1A6841ED4FE94
-:10490000AB3DEF72993F48AE97F9AE86FED0BB5FE4
-:10491000ED88E3FDF8AF763C528838F3C9D0C8146F
-:10492000F0FF397F6D904DD261AD3A16F812419982
-:1049300067530EBCE6468EB3DDBA4066E43A93F99F
-:1049400046C7773C9B60C96EA563B9B3CA89F3A11A
-:10495000953B6E29021F1FB4497CDA774C0CE0D8D6
-:104960007365BD4F807F799DA573FB159688760E84
-:104970009B97ED62DB9E623FDA1B71E8853B6D7CA5
-:10498000BE70C6E59EEB6FC43A7CCDC67458D8C7DE
-:10499000733DE72335A89CBFBC305384617F2CBA9C
-:1049A0003D7E1DF6C38CF1CEC895EBBD6C8522FC17
-:1049B00034AFB2A02A342A3B12DD03C8514A6B1C23
-:1049C00080FCC9A6CCE03DBD52F8BC6F787D4A6B37
-:1049D0009E29ADE35E3817593E2899E7FDE0B442C1
-:1049E000D67787ED2200B9107846E6E1947593F901
-:1049F000D10F83EFD15F72B8573B9AEF099DAE6537
-:104A000093C2BD909751F64C3AE7659CB0CBFD52EE
-:104A10003CC77E71590EBD4FED52F47C5EBC9F14B5
-:104A2000C14765B3BC1EB45393BD1E9F0BE3757F96
-:104A3000CD76EBCE7801BBD5B23B5ECFAF8AE13C01
-:104A400072E3BD9A41D22E4ED1E9296E90F9980FAA
-:104A5000DA64BEEA831BD3F97E0CA3FD83366D1A9C
-:104A6000EC27CC03F6FA7C7B5D2FECBB18E39D9F13
-:104A700050C7E33CA1F3F9FCD83A9917AE9F3B46E7
-:104A80007BC04D7A1E7BF3530ECE5F3996DEF02D40
-:104A9000C67BECA93EC88101BEE7ECE17AB21F8972
-:104AA0009E0B9E7684517FF42919B73E6A0B7E0BCC
-:104AB000397CF4D1767C3EEA68FB603EE707286EDD
-:104AC0000BECB3A38A0EDBDC6C5776B5134CED53BD
-:104AD000628505F93B6327AD9981FC86960D0EB082
-:104AE000A738B6E9A154F66B842791F36C0EA9029E
-:104AF000743BF6F4DFFA44DA2F46B9608339EFAE3F
-:104B00002953DA9546FD3A7D5DAED3D7F5C64152BD
-:104B10004F95C7851EECC6F393F826FAB07F470A77
-:104B20003E9EF327B6F65420371E16C19F7F9CC7C2
-:104B30005EB60779F365CF3CF526F66B8F594403D3
-:104B4000EC0FE5AECD3FC7FD1C29BF49643D24C431
-:104B5000069EDF51B73CD74A0B96E73FBF838417C9
-:104B60004CDEDC0BF041D2390AADAF051685FB5F98
-:104B7000B0AB1FE7DB113D2CBC4FB65DD5C743364C
-:104B800025F0B749E62B8F4B0E6E82BDD7FC6877B8
-:104B900081F3EE63D4B5FD41BFD31BE22CE0A7F255
-:104BA000BB87240E01DEDE5205EC8FD3566F87C81B
-:104BB000384234BEA2F3C0BFD5E55319AD3B9CFFCC
-:104BC0002CDDF528DF2F520ABE045E9E56781FBBEF
-:104BD00074F99087984FDFB4899ED4EF89D0FD098E
-:104BE00091F469D4E5E2B9EFD8BDDCBE94DACBF735
-:104BF0005F4BE0716EB2715E4B345D2FF9FDA7D54E
-:104C00004B7AFFDCFC436417F43F1F0FA745C3CF6B
-:104C10003FA6EFFF654B0CFB83E401F039B6E3B62A
-:104C2000D01CCCFBF8D618965FC793A49CF88AE4F6
-:104C300069A037C671CD6F994FDF99CCE7FDE606C5
-:104C4000CDDF35FAFD02721C7CD7CE9B08BFB3FCCA
-:104C50002D290F895E3FE3F7DFB2F1FBD1F338A0D6
-:104C6000BF776E9D6E8D63BE38DE51D2E3F8B6DE3F
-:104C7000AC9F9A92DC82F9E6299BACB785BAC00E4C
-:104C80003EBEB5B7AF36E2BBC793425DDC11CF9BEA
-:104C90006CC1E503A53C6D865F2CC2246AF3915F6D
-:104CA0002458CE1BEF953A5736C04E417E6F7E0E8C
-:104CB000976147F2F979BAE392A53F396CB08C0F4E
-:104CC00070CE6AAA9E4FCE764FC80E39AEE9F66115
-:104CD000D996E83C5F59DFC9789FD65D8A91576CB9
-:104CE000C17843F6348E3708CF3334DED2A5B7CC43
-:104CF00047FE7869D5AA1B613F955AC5583B8DABD5
-:104D00004951791C4D3162E624D89191FD44D86F08
-:104D1000BD079F8BD30A772ADBAD6CDCF71D2CF522
-:104D20001DE03AFA5ED9526525BE6FC8170E14A66B
-:104D3000B6E20979ADC8EF691AA9D75F60DE4D36D2
-:104D4000591F3D6F633C23064B39D594E9F9ED506B
-:104D5000D0E50D95CF779DFE213731B90D3BAD558F
-:104D6000DFDB5BF36C69FCE3605BD377DC83A5BCC2
-:104D70002BA5F1619CBDD69AF3CAB33698E1CBB6A8
-:104D800098E1EC1D66B87FBD19F61E30C3797ABF75
-:104D9000F0B3716E197E364AF8D91E87F4B301C399
-:104DA000CF46093F1BCFE16703869F0D187E366013
-:104DB00003DFF0B701C3DF46FDAF743C097F381550
-:104DC000F99A151699E74BF4F0F339A66976D3B939
-:104DD00094532FCA7329C40F52DECF77F13A791852
-:104DE0002D06432FC9F594F2BC23B884DE1BE1D114
-:104DF000E60EC67A5DF3CD1CF05D45B746CE7B6D01
-:104E00005AF64AAFFBA95DA3122F605754ACF9665E
-:104E100006ECA8248F568EF695B10DCB0772DC3EBA
-:104E2000CCF2A3B1C6F3D60849478EBF14ABB8295C
-:104E300083EAE725B7993F149D772E569AF3CC2F36
-:104E400096771ECD07861DF8B8AD39DDCD7EFAD038
-:104E5000C710E75DA8C4BBE1A77F162396E0FEA0BC
-:104E6000C0AB324FADE5904DE60DAC54D68B08FB90
-:104E7000E4D73ABE0D78F6D95CB6C7CFC12B158BF7
-:104E8000B85C881E5A7313FCEBD3F32C6C779F9E8F
-:104E90005750D81EF61FF9655813B89F2B72BCB82F
-:104EA0009F2B927F703F97F9DC4447537BDCCF65A3
-:104EB0003E377199A97EF2CA5C537D49D110537D6A
-:104EC0000F21C7B768BE1C5F09E9077F3BC04B389D
-:104ED0006F71116847764A1725B09CE5F23A85CF85
-:104EE0008D7B16AF28045E4E103B238E60F0CD6C98
-:104EF0005DBF086BC00EBE3B9322EB8F2A0D5FDEB9
-:104F00004DEF9DF4D56DC2D529272D6B1F1CEA41AD
-:104F10007EFDBA2E6E5A87B72AA154889E3579DA5B
-:104F2000AEC1ED919FD23891F713B7B74FAE81DD87
-:104F30007968C09B83D0DF1695F3260C7EE96293D7
-:104F400071BA75838866644FACAB93F9BCEBEADA4F
-:104F5000C5F688D87F31E6D9023A08944B525338C7
-:104F60002E241A300FB2DB97C06E3B7D48DAEDC6B7
-:104F70007C7A2C0D775A44F5B76E8F61FC7CAEFBC2
-:104F80000D27FABCD4DF83F31BD57BBAA8B0072C5E
-:104F90005B36C18F70A4686F82EFE7ADEBF927DC59
-:104FA000EFB5E07D55E03CCD17AB47250CA6EF1CD7
-:104FB000DB6AF38E23F8EEBA27ECF093175883766A
-:104FC000CEC37C6A9D1D79C9576E5EC7CFE76C2E34
-:104FD000E6BCCBB9A28AFDC823FAB92C63DEF30A7A
-:104FE00094B56EE22FEF15920FE7C5CAFD3CE2E7DC
-:104FF0009731AFD39B151FECC72945DBEDC5D0CF4B
-:105000003ABF7AA64E1D03FE6B09C9FB395A5E579B
-:10501000E5BD63535499177381FB7C269FCD64FED5
-:105020009E72B62FFB59D786FB483F365BCA8F96D8
-:105030007A95F7E35A5EDF9F3219DFABB7F1EEDD09
-:105040003C7B833CFF6F11553847E099DA20F92A01
-:105050005354C1FE5BF4C6BB07B1EE16653A3D582A
-:105060000F454355137F568E8E33F1EF54916C3AB2
-:1050700047731D924A22E029E3BA9BDA5F3FA56F8E
-:10508000943CC869AD67797045D439C002135C4E51
-:10509000E59D904FE26AD37BE562526B3BF8C31B00
-:1050A000A4DD5ABE23693DF6C5E759A43F345593A4
-:1050B000CF2BF6C8E742C49E3B978EF3F8880F9833
-:1050C000CE6DEBFB7CE897E381DD1B38AED39C4EC5
-:1050D000F292305A9ED568473C8DCCE566C449CBE8
-:1050E0000304A35FBF68AEC5F911ABC4AFCBEBEE51
-:1050F000B624BD952F2A7698F3AD2A0EBDCBED8C44
-:105100007CC6E87AB2D39777C4B8C7293E3E37B990
-:10511000A5C98E78D014AD13DF4B117D5F5A59A805
-:1051200089C779ED9E5437F66D2BA2EE495B7885E1
-:1051300047EA273DFE8F7B86A49DD06097715BD7A1
-:105140003E0BAF3F792FCF39BE9C6791F70544E105
-:10515000659CEF7DEEAF63BACC43035EAC117889FA
-:10516000E623E0C91A81A73942E2690E499320C1BA
-:105170001DC16791F8F989F89A8B7F50FDDC3D4A93
-:1051800010F96FD1F899A33532FEE668AEAAA0FBFC
-:10519000FCF954DCF9C141C8A76DE9F25EC368FCB3
-:1051A000CD150DCBE1F7CE25BD114E62BEB03BD97A
-:1051B0004F53BCD0DB9E418D769B94671CE76D7985
-:1051C000FD5D5E772D5E5AD5E00B41F5D4DEE5F747
-:1051D000342F6923CF77D259193FB9EEAC95CB293B
-:1051E000E3CCEBEEDAB3A9FCFCA7E2A50278069FBC
-:1051F00023AE97D0C63D7B88F3259C3F5F633FC4B9
-:1052000090C3AD769D396FF942F65F749CF0AE2B7A
-:10521000F47CC1016280296FF902764774DEB2A185
-:10522000C75B5C524F8E51B3DFF2D0BC8B5F55D958
-:105230004FF74C1D6BE1F3E3AFCAFBF1B465679A1E
-:10524000C09F5ABC85E5E0C2F86E7CAF85A6C7ED6D
-:105250008C7EBAD4B44B45FCAF38C6CDF9F8C53511
-:105260006A11F45731B5F344B45BBEB47B17E885DB
-:105270004FEFE9FD5880D6CBA7B7A7A422EEFFD900
-:10528000325B0A49CE73ED3E5D36A60BF2333E5BD0
-:10529000E5981A6C033F9B747D517ED707ACB74EDF
-:1052A0005A5E4F984AEF972DDB9980B4FFD265EF95
-:1052B000E6BBC9A4B8224FDB7805EFAFAEDBE4064E
-:1052C000BEDCEBF83E815D242EF17EF1B2654CF739
-:1052D000058ADCAFBE55097F3982DA9D8859953041
-:1052E0003513B7A10ACED338B3215E3F8F56C379A9
-:1052F000432762C91EA0F64762243E8F6C8FF7F2E7
-:105300009D18DE4017F6DFDACBFD9D524BFD751878
-:10531000CF5529DAAE2B06601CC14D692AB7E3735D
-:10532000EB5A4DCFC4B6E21FE7E6A9EB69D8DB28FC
-:10533000616F235F06F63660D8DB28616FE379E59D
-:105340001AB3FDD6A0EF171AF1E0AEB5CD3ED8BB2B
-:1053500081029155C57A765CC1BF426FBD2AED8549
-:10536000458A774523DB4BF175F03B6BADD2CE0E12
-:105370007C22CF45D19F2CC8A75FA89779B19FFF0A
-:1053800050DC5D8FA3FD62EC0FE5E1DE53B2BD2280
-:10539000F875C459A7883C773B928CB04878943311
-:1053A000DDD47E8C3BD3547F655A1F53FD551E9F21
-:1053B00009BE266BB0A9FD78EF4813FCB34157999D
-:1053C000DA4FF44F34C193C74E33B5BFB6A8D854A3
-:1053D0007FFDD4F9A6FA69DA2D26F8C679B79BDAEB
-:1053E000DF545563AA17A2EA49E0C71F90F7B0D56A
-:1053F000C37F72E0FE17279754FF7BE4318F24515F
-:10540000CFF7AEBC71DBE380F721AF9956DCD0510A
-:1054100096AAB6E2F8B62132AEA80DF5FF7805FBE4
-:10542000B90D7C8F2662B7E0BB94211EDDCF96CFED
-:105430003B598DB855433ADF9710D5FE42ED86C6ED
-:10544000ED3BED2196BBF385C76EB20E461EC4BE82
-:10545000DCEE04EF1DD2749395E4CDD021FB9EEDDC
-:1054600046F0C117FACC60F8F27DA7513FA5FE0BBC
-:10547000593F59B069D230E4DE9B02C47743477488
-:105480005BE995719136CFB71B25F08473E1C013AA
-:10549000CA30F13DCA7DC4F7280F10DF97905C3BFE
-:1054A000487C8FF210F99978FE6FE467A27C9DFC2E
-:1054B0004C946F927F89B281FC4B94EF544FE5F28C
-:1054C000BD6A8DDFFB63F53C2E3FA8AEE2E71F55BA
-:1054D0002FE6F293EA003FBF7C888C23B848EF4068
-:1054E000BF57200F06F902D1F72C57B9F9FE835A9E
-:1054F0005D6F897A3DAF661FF9AFC067A335E94B91
-:1055000067EBFEE285FD7DABF832C26E9B68F50F5E
-:1055100019C2F4EDE4E6FD21FDF90B5ECD3F84E810
-:10552000FB7EE6E49EB92AF45DD5CB8954F7BEA58F
-:10553000EDFB2753747EF10DF58FC17BC39C8779FA
-:105540003FDD934ED6EA108615D05FC991F1CB614D
-:10555000D6865AD4D77E2F3CF09B5F8AFF23EF83F9
-:10556000D792B98CF3C7CA59E9AF0CD7F7EF6BBF25
-:1055700097FBF7C33176AA1FE696F5B53793A6F3E6
-:10558000A13EC4DF1F8ED3CEF27C9B296F67F4D976
-:1055900086515CEFB27B906F3ADC1996DF730A3765
-:1055A000E2CB2FC5EF92FD8F91FD6FF83ECCDF87E8
-:1055B000F7691B8CF1B78E67098FAF41DE4F972DCE
-:1055C000DBD7EAED876BD47F12C65725C7574CED62
-:1055D000E5F859CE0DC73793E06DCBFAD834793E54
-:1055E00079F459BDDE2BE7DBC12A619C29417D4658
-:1055F0003B4DF8A9BF8C0CE145FC6D784A433AB7A6
-:10560000D7F319E2ADF27B895E791F578FBF6A72BB
-:105610003F801080F11B7949C6BAED9C1C4E879DD6
-:10562000D779A19DBF97A16EF7415EE7F8B400E876
-:1056300067755A787EB57E795EFEED173D9D711FC8
-:10564000E944DD5EFF07F45F26E9BF57D21F97BC30
-:1056500065B4C2CA1CFA6F709BF497F8227EC1FC35
-:1056600089FE4C0FD053A7BF62E047A7FF397A2DC0
-:1056700089ACD7F9E37CFA8724BD757E1AEE94795C
-:1056800013680FFA0FB34A7EA88D91F91E2FC51724
-:105690003E8C7BB208374588CF0F33F8A54A9E1F52
-:1056A000FEDF4AFF3CABBC47CE51E6E47BEA2EC6A8
-:1056B0000F339B4521EEE93CEBD35220278ACF7A6A
-:1056C0000E029E2D4616C23C37EA959CB6EBB5BF3E
-:1056D00034DB001BCFB3D06E406BBDD5F94E1CE45C
-:1056E0009EF11DA3DD95E7B5CB71425F2C1A135ACD
-:1056F0000BFD35B6C6CA716BB24C183E44FA4CE687
-:1057000073FA137CA991F99FDE030BF370BFA83CD9
-:10571000BF255CD2AEF6D05FC8D5C21F8A96A23F25
-:10572000A16EB1C2EF38837C5AFA4E618AD93E1F0E
-:105730001BB5BF7E75F6576C8F5F7D917BAE8F0C6E
-:10574000D1F7DD3345E67FF29ED1E621AC672FED40
-:105750009ED12C51CF7C30BA58E673D1FC2D3988BC
-:10576000DBF84515E0425165051F8C157556E95764
-:10577000FA4F54E4B1D7CEF8B94684F9F9785228F3
-:1057800050263F23F601BC3F6EC274DC1F3C2A77D3
-:10579000540F3C8FB83FCF36B43DDF9FF76777C4D7
-:1057A000FD79FB46CBF5B6F05A196FDAE7ECDEA6C9
-:1057B0001DFA2AE9DB1E3D8117C1E5CBA48F7BD002
-:1057C000BC5F217D0CF8EAAC1A81F70A3DE6BC23E8
-:1057D000E3FD6BDCA384B5DD85F5DD35FD9FEB04D2
-:1057E0003CBF96D47B34E8F55AD2C0D188C7BF9667
-:1057F000D4C1224B879DCB7EBB7BB4353E637DB449
-:10580000F657C8FD19F7058F6E2FEF0B8EC6EBD537
-:105810002264C2EF381DBF3F01AFDEB6F09A82C3EB
-:105820008EED81CF77771979538827F758DAC0F052
-:10583000AD36B90ECA778F2F405EF4C2F7657EC7CA
-:10584000510C057A77F1101EFFF0C583853597F767
-:10585000A302C0779953E2F164E0A5FEB8D73CDC1F
-:105860004E1B89FEBF5AABF279FB93CFC4703CEE5E
-:1058700048F0D904E0D3E0E332D5B3D28B75F89A7F
-:105880002AEF59FA617F17DC437A21BE267EBE7A61
-:10589000685BFCEC227EEE773E3F8B0DF21E83327E
-:1058A00067619B7436FCCEA41C3FCB1FB708DF0298
-:1058B000FEAF10D23FAA70BE2EEFA92418E75EA358
-:1058C000EDAAFC586A4FF576A7CC1736E89DE19013
-:1058D000F75866C40937E22042CBBD0CE3FDB4BBE8
-:1058E000BF187821BF764B64DEDAF0705FDE771E7A
-:1058F0007B48E57CF75762E5BDEF8D440F85ECD31F
-:105900002BFB56B9BA111DE7E66B65785FA83FA877
-:10591000E8F7F59E8A68C7F1F35C17FBD93FD15FC2
-:10592000BF75A8EEAFF717FDFFE1EF29B497F70EAB
-:105930002F7C353788712FAC21AD96C2BF8BC1F754
-:10594000C4D5C23FCF6C953BC3452FFEBD8C5129BA
-:1059500036CE33FFDFF67B0A1942E3F5F79FFD5D94
-:1059600085B1F2D179BFAB9091B0E28096D2FABB0B
-:105970001AD1BFAB90A1DF672D3C527F18BFA73073
-:1059800042F8392F7F4C9A59AF8C728F3CE0E6D2A7
-:105990001CEFC9B8483ED7B34375BD7231BA970BF7
-:1059A0009DEEF25C27F840FF7D9420F8D3F87D143B
-:1059B00083EEC6EFA4D4B697BF93F2CFF6BB28D13F
-:1059C000F489FE9D9468FA44FF6ECA702D96F134F6
-:1059D000AACCC57C6DD0692AFD657B00E77295FF76
-:1059E0007E7A1D8DA2D719B17200EE293D552CE5A6
-:1059F000FA85F4FF06AFFF14E4C58F8827E1BC8B5E
-:105A000053C643FCB55611335CE07E42CE97FD454C
-:105A1000ADBC07AAD62AE30101A22BEEC5FB2EF6E8
-:105A2000EFF23E47B28F6C1D1197A9E2F70376A7FC
-:105A3000BBD60B7A27309F2C5E2CCF031FB6D4F138
-:105A4000EF5DCCCCAE52B07F792C535386B547BCBA
-:105A5000B868FB1C8ECB570D847C9FF1074717D489
-:105A6000CFE82AEF8F14D98D0322ED911919322F27
-:105A70002B66982EC7BD320FCB354CFA09F15E3735
-:105A80009F6B28CE167A7EABE832A31FF8F813B6C8
-:105A9000E35B3CD2AE6EB4C97B2C03AFCA7C9EB52F
-:105AA00055EFB0DDBF91EC5A55DA376BEEE3384372
-:105AB00082C03EEEE331CD49187FEF35C2642FF44A
-:105AC000093A4D79C97D37BB4D70BF509AA9FDE5A4
-:105AD0007B3CA67A5F38CB549F7BC86B8207340C23
-:105AE00032B51FF881DF040F6E1C6B6A3FE44891EA
-:105AF000091E3DAC9B8CFB8327693E3316B983F2AC
-:105B00001E7D1927E96A97F654EDEDD29F30F2D742
-:105B1000357D1D44E7AF77B6CAFC757B95D46B9A8B
-:105B20004BFAB7EE64E156F95C4C03C3B81B82F341
-:105B3000C603E63CF34E4EE95F59464BFFC3AEE762
-:105B400099C766C9732F465E39F9157EE0BB876831
-:105B50009CC6BF77A0DF271ACDCF453ADDA3C7DDAE
-:105B6000D52ECFD3D5DE6EE7FD73CD656F5212CE45
-:105B70001FCFED0325FF6F74B67DEFD38C61328E9E
-:105B800012CA2DBA6E18B57B8CD416DB5FE7F5E729
-:105B90006D84BCABFD959DF3C62FD6DF8CCBE57C29
-:105BA000A65B2C332766B33FC8E7008D7E2BF47EBF
-:105BB000278D50DA9CDF8CC466BE774D24DA3DE039
-:105BC0005FCDB59C6177AC4852DBC07BEBB90C99DB
-:105BD000A77FD3CAD07DBD699CD3ED753679E140EE
-:105BE000D0067E18574076A40FF1D782475D448FC8
-:105BF000C7165B390E76DB8B2FCEC0D5F4E3453369
-:105C0000F3031251B09F08FB53CD691DF7B1E13288
-:105C1000EFFB415C2CCDF6CC0F3CAE163D3ED222C4
-:105C200042E7CE4F04DAE037CD7590CF21B8174A5E
-:105C30007EEA1C71CE0AFEE7FFD47909811D52EA83
-:105C4000C75627E439C78BE0CF38A7E2B9C556B4A9
-:105C5000DE85F32262AC128187FF182EE3FC878673
-:105C6000497AA31DE4D185DA91DD9788FD8516E197
-:105C700049745F24AEFE3F31FF0CAB8C337471CAA4
-:105C8000F3229DAD1ACB0B7B967ECFDD79FCAECB9C
-:105C90000D3D4ED6C92AD77D27AF5CD7E7CB85030C
-:105CA000FC7DBB26EF4D8BC62FFF8988AB18E757CD
-:105CB00062474B3962C88573E7507A4A3FD4A6CB16
-:105CC00087600F0BE71DDC1D6F5EC7DFEBF261AD78
-:105CD000A12F02E4C7E79BE484C0BE5EED3295E5E8
-:105CE00004C9C9831A8DB318F7B2B85B7F1FEEE6FB
-:105CF00007A41E1BEE2F7A10FB26B356DBC43ADE38
-:105D00005790F7C3CED5E3E4C581A8FB59747BFC5B
-:105D1000CC4AC58DDF8D98BDC25C3FD7F5E527F035
-:105D20001F6F8EBEA7C6D8AFBB481CE0E830DD4E63
-:105D3000F70AAF9E7FBF04E33B1394F75E9F3BAF30
-:105D4000A4C77F5A82CF4AF84E21227F47C2B00BA8
-:105D50000CD8837DB2887B5808BFB159D0EF4BADCA
-:105D60006DE6371AF83D97E7A1EFD351B96419FBF7
-:105D70003332BF81E401EFCB9DA07AD8812702A7FF
-:105D8000B9FD891D319C5772D2D7D01FFBB7C63ED3
-:105D90005D0F4DEE63B5EC8897F90D2E8B8437CBF4
-:105DA0007BEC17FC35D81F7E6C63E059D33907AD07
-:105DB000D1BCCF175D6A353BD9DFBC224F4B1E8E5D
-:105DC000BC74ABD7E925F81ED73EBEA76B1CF98F74
-:105DD000906BC84B599622C7CFF22B705AE2AF4A4C
-:105DE000E2EF6764E8417EBE2F487A228E29C8AB75
-:105DF000A5B2383C98FBFFA9FB6093CFFAE4FEEF15
-:105E0000D921FCBEB66230C359C1E6911F50BFD73D
-:105E1000692E0FE248D7D6FE624C2C7DBAF15F5D49
-:105E2000CBB8EC6C3E3F6094BEE1528F34DADAAE10
-:105E30005FAFCB9F3F0C17FA7D3592DF17D628BC9A
-:105E4000AFB6103C0EF83E793FA7019FAED3E131CB
-:105E5000125EB44CC2504DB08367E9BF93B6498F10
-:105E6000BF60FE28317FC405B6E8F119CC1F25E6D6
-:105E70008FE790578021AF00435E0186BC420979CD
-:105E800085E75F248DE27D6DECDB8D8E584FD8B7B2
-:105E90001B1DB13EB06F170963DF2EB23DF6ED2238
-:105EA000EBB16F17598F7DBB4818FB7691EDB16F41
-:105EB00017098B4157B5C2906BFE89267832F903DA
-:105EC000A323D633F6ED22BF8F7D3BD3F7B45B4CD3
-:105ED000EFDF28169BDEC7BE5D64FB998B15D3BE32
-:105EE0009E10CDACD767AF69C77C94E12BAA04BFE5
-:105EF000FF39EEEFB7D9BAB17CE038C6C2F258AF7D
-:105F0000A477DD58497F8B3C1FA134F3EF0B9CBE77
-:105F1000D32EE131E6FC6DA3C4BED7689BDCF7420B
-:105F2000897D2F94D8F742897DAFD13DE5BE174AD0
-:105F3000EC7BE139F6BD5062DF0B25F6BD5062DF28
-:105F40000B25F6BD5062DF0BEF61DF0B25F6BDF0D0
-:105F50001CFB5E28B1EF85E787691C2511720CF6E2
-:105F60007A0F939F497C68F233DD2618F67A647BBA
-:105F7000D8EB91F5B0D723EB61AF47C2B0D723DBA5
-:105F8000C35E8F8443C33CBCDE60B747BE07BB3DE6
-:105F900012EE57177819B1B5F16BBF3E80B2315E82
-:105FA000790CE70D43C3A7CCC47E66638CD22589E8
-:105FB00064BAAD66DACCD1B0C3F5FCC7FEA2D90293
-:105FC000F9A3C199CCE373869C57DAEFFB74AE6FEB
-:105FD00030CEC5E10FD1DDB743F0EFCE18FBEDC6F3
-:105FE000FB5E52DBFC7B517AFB56B8ED76D1FD1B94
-:105FF000ED38B72A621C38D18CBC19DF9DAE1CF875
-:10600000219B2C0AE7996C5A22F3A2A3F9EA0B5DB3
-:106010003E6DB26CDF877330CDC58A17E73E7AD408
-:10602000697CCEACDF7461517DADF3E9FD7802E7A8
-:10603000D5BEA1CB3D63FC467C94E4059F1F1CDAD2
-:10604000DC302A91DA6B8191FC3B38E3ECD26E2094
-:106050003FF40AF8937D038A7F7D049FFF69B8D4DB
-:106060006F5A408EE3C9C727C8F762E57B4F3E9E53
-:10607000C0FD4F58AA709ED9D02DC28F73CA8DFA19
-:10608000F8FB6E09ABE8AF78A9ECCFF86EF1DA2E29
-:10609000769CE736F0552C1A47E33E6991A7E04E0F
-:1060A00059D1CBAAB15DDA61BADB023BE852CF41EC
-:1060B0000DCB4B1A833C44512FF8DED0F1796F9B06
-:1060C000E6CBE8CAC7EFA00AF60DB5C02D16F43B23
-:1060D0008110D00EF16482311F4D13559984DFEB8E
-:1060E000A61633BEB3A60B05F8EE337D9D2585DEDF
-:1060F000EBABBD6481BDD6AFAE914B631EDEA14953
-:106100002AE07136F7188C7FDC1885E547741E0F7E
-:10611000EC038697DA589F1BF6C3C2F873793E7F6B
-:10612000429ECFE94336CEF339BDF40CD717EF8C3E
-:10613000E1BC1E6D8DC272CDB01B8CBC9DB25BDE0E
-:10614000CF077E8E6506372575673D9F3802F93487
-:10615000DDB627E008CE89A53BAFC3D1BDD34B77D1
-:10616000CADFABD5F7778CDF3D15D97ECE0733EC90
-:1061700040A1D6DB23F7718CDF4F23F9C9ED4EEF39
-:10618000B1BBF9F7EBF4DF3B35E23EC56FE41E042B
-:106190005E8B1F95BF7F366BC5AAC2A904CFF13BAA
-:1061A000C3F85DACE87CACF95176E0C57EEFB4CFC6
-:1061B000083DFED36AFF31BF9C795DDA7FC56FEC85
-:1061C000BF56DA2B36CEFB9F5E23E37562BBE0FB46
-:1061D0008FA6D78CB2E01EE9E93BFD5EC5D36A0706
-:1061E000BEA5DB2D93CE66307EDFD5ED946B917F1F
-:1061F0004AF81DD718A3E7ABA57379FD59998F3AD3
-:10620000C925D77BE37382EDE9968043E611D60B6F
-:106210003DBFD5CC773E41FC41F4B9CCAFEC47DA79
-:10622000F278D83DF4BDA9B083DA818F8B97215FD6
-:1062300096DE66BB339A8F2759C353F0FD495E1B28
-:10624000F3D73FE263DCCB714E2E89AA9771CE5F04
-:106250006C90BFE3305593FCDD57E7EF19717AFC82
-:10626000C925E34BE7E2011824626681AD33912F23
-:106270003C03C90B1D795A7EE4EBC567CBFAD97F85
-:10628000D83A73299C990BC425D43BEC7C7FB5E6A6
-:1062900072F2EFD05C284E80F800E4E34DB7FAECE0
-:1062A000B322E463C1C882D5FE0111E71DEF9179E5
-:1062B000500BEFE9D9A1ADF3B646399BF08BF53120
-:1062C00023B1F1369C37AF1921FCA307C9DF99E44C
-:1062D00079E1C44D167E6F52C25B47BCFFE715D90A
-:1062E0008C0F867F35E28599C8872977361682DD3F
-:1062F0002AB3ABC622EFBA550E69FE8C4CC8215F9B
-:1063000018BF1B76A1B8C3D611920ED1F187D9D987
-:10631000523E0BFDBEF04FEFD9BD0DF2DC18FFA7CA
-:1063200017F87D8C8D232CFFADE73CA2CF777CD076
-:10633000477B6804E21A167F13F2E83BAA757AFEDF
-:10634000ACBCD7C3A06F4CDD771CEF28D1EFC327BF
-:1063500079C2FEE42CBFD35B0339922596E3BCD00F
-:106360000C5534F3BEF1797497787C7CDA5FE723BF
-:106370001FF7F15FC5CAF33A3AFEA6DB1B5E7666ED
-:10638000B6E2EFE3C5FF6293F22BDC13FB723754E6
-:10639000C5707E5BC1C8A22D186F5CB697EFC1585F
-:1063A000ED97FCE4EC56F47BC8C1F2952F3D86FBDB
-:1063B000122AEB33F977658AF7F896E39C63C148B4
-:1063C0006D07DE2B76B9F9DE908AA549AC9F66741D
-:1063D000D0CFBF8B66DE8733F0FE861E9FBA7FA4C8
-:1063E000FCFE29DDCF80209C686A77A1389DCCBF58
-:1063F000417E0EE28F9A6B17C709DC77C87B2AECC7
-:10640000E23D197F4C6B3B6E90A1C71BD3BD323E62
-:1064100064E0EFDEAC592CE76C463CF71CFECCE7A1
-:10642000318DD2ED97F6C2AC5B15F6574B56AB7C6F
-:10643000AE7C8C3A8EEF7159B84AF1F0FA7AA03BF3
-:10644000E77B2FBC87AC310FCE97790A3BE4E1BEE6
-:1064500075C50DBB643A681111DF29593398D75BB4
-:106460004990CA36EE3535CA1B57EDEFFC9C0764E0
-:10647000F4F3FE6589DB6F4F8E58EFB3EB14D3FD59
-:106480000A062CF02316ED717F3D29481AC7F41E29
-:106490001E05FB8A6EBFC4C34DB766DAF17B24D3F9
-:1064A000E9CB969C0BF7FFFFBBFC7FC4BFEF53000B
-:1064B000800000001F8B080000000000000BED7D35
-:1064C0000B7854E5B5E8BF67CF2BC94CD879910458
-:1064D00048D80904C2439C109EF5C1CE0B2610601B
-:1064E00092808227840904091EF446D4126C940910
-:1064F00099C41051138D0629EA80C0A16A25564F10
-:106500008516DB017C8B8A20D6B636191E8A6D7DF6
-:10651000A470A8F67C54EF5AEBDF3B99D99904D0CC
-:10652000F6DCDEFBDDF8E1CEBFFFF7FAD77BAD7F0F
-:10653000A7289DBDCA2631D6DD2A48DBD318AB94E7
-:1065400014F3441B63DFE2CF0CC696B5088A6F7C58
-:106550006FB9289D2D75413952B1333699B10A4929
-:106560003627A7E15332C7C2FB65B71F30B178C6E3
-:10657000968F644CC882F6B10EB30DC75F05E30B6E
-:106580008CDD20F90BB0FE86F132AB8B81F6DE2C70
-:106590003383F9DC9BF83CEEA618F31550AE304A75
-:1065A000E6142897453286ED617D3EEC5FE957CCD5
-:1065B000B1361C972D2DB1F1F5C606ADAF425D6F1A
-:1065C000654B8C7945C8FB56930CE5C58C291D415C
-:1065D000FBD39E331481F6B3CC5B9CDA0EEBADF4A7
-:1065E000D8259CB7D2A8981DB82E1C17FA2D6E6B13
-:1065F00037A505F5BF423150BF198A4CCFA2747F31
-:106600008680FBBD35C281EB5D2CB598109E451A86
-:106610009C1FE6705821F93370FC15560E076DBCAF
-:10662000CA363E4FDFF5717857B6559865A8BFD189
-:10663000E84A6D87FE37C23A3DF05CBCF94086807F
-:10664000CFEA088700E7C12477AACBDEDBFF938778
-:10665000AF4FA5FDC3FA11DE76873C3309D6B3BC34
-:10666000051623D393E62DCF66D51D4170BB5E3151
-:106670003296804F033D594BBB621D0CF060FC67A6
-:10668000B8F9480EEEA37E0C631B601F6EDBCF7360
-:10669000709FD29D8C89D361BD9BDEA3FAE5494CE6
-:1066A00012A0DECC5E10B0DE5C097DA0CC3C054AB9
-:1066B00020938FF56D3A63293832B4B701FE789292
-:1066C000195B3755A67917B3C0623602C6D9540C88
-:1066D00073C03A13F93ACB07B1EA9F8581579BBA49
-:1066E000DE1BD4F32E33B097596C6FFDDDEA79973A
-:1066F000213E07F5C7F170DCD55A7DAE3FE3D6F1F8
-:10670000BDEDB579CB62793FA407C4C3D52A1E601D
-:10671000FB35D49E970B44DB8606D8CF9AFB449F6B
-:1067200045C0E7930D83B1FC9CE040B8FF79CD8B69
-:10673000EF5C07CF3F3DB2AD1CF7A7AD63C5D7599E
-:106740004C8E83F3FDFA2A7A56FAA73339BBEF3E13
-:106750000F4F75FF48991C843F0FFD74941BE6FF93
-:10676000F3B36F65209C3F021C1001CEFFF6D327C8
-:106770004D2CBD77FDCB9ADE3355D882E12510BC78
-:106780009A338FD2F92DCFE4FD967BFF5281E7C17A
-:106790006C663923ADEFF957789FE3ED6B1CD4DEBF
-:1067A0006DFB809FFF102689C9173F6FED7CF5E7D1
-:1067B000FEB8C9E54F12F07C5A42E85FBFFFC7D46C
-:1067C00075FB54FABB41C5E31BAA5AA9DFB2A68ADE
-:1067D000274558F7628D7E2B43DF6BE773769389ED
-:1067E000CEE7ECA68CC6242C77F0F3F977B163C220
-:1067F0005A68F7E7D53B6F494EC755FB525D57F0D6
-:10680000F361D9FC7CF0B912CE87C5853D9F3DC1AF
-:10681000E7B3F2097E3ECB9F7DFB0FBF9009FFF8E7
-:10682000FEEEB3F890FF2EEB78EEF80FE0FDE2A657
-:1068300056531AB4FBB59246FBD2FA2FAFCE9258FC
-:1068400034ECAF699B09F9C0AF15392C9E6B7065AC
-:1068500046CE671E37C1D9C6503D13627BDB2F661B
-:106860004A22F211E619C676C6F75DFF9F543A2A0E
-:106870004A779813917F3544B1ED12AEA3E27E368C
-:10688000A16F7BED792A82D3C5329807E9F3548E44
-:106890002315E9A2CC6008A137ED7942A5AFA1513B
-:1068A0001D8B71BD43E398540F20FE71A4926B8041
-:1068B000797FFC03AB54EFC0FE6E19EB2D562679A1
-:1068C00000E4DB0DF244C24FC6AAEF494658062643
-:1068D00023DF1BB93AF0175C1FA253C444FEB4C3B4
-:1068E000BE2D391C4FA0CC06F3F77E7CA6183B8842
-:1068F0004F45D670FC33B3F7A96C06BE8578ABF56F
-:106900001BCA8E08F83E19D682F337672EA3F333DD
-:106910008DE4F4D2DFFEBEBDC4FD9D4A73FB484E3C
-:106920004430697B0CED6F0D967BF697C91403F428
-:106930002FFFD115DB9A61C85375CA4133D49F5AD2
-:1069400067A3FEFFA8FDEAF7B9B8B222649F3D74C1
-:10695000D3027C2D0D9FD9A9B8CEB3569808EA4F23
-:10696000DD1A6140F89F4AE3FA0263017B099CCB80
-:10697000AEF5F0AB85B1DDEBADF47C6A3D20D368BC
-:10698000C69E599F44E567D7CBF4EC589F49EFD397
-:106990007338FE95452AD12897BBEBECD2768487D5
-:1069A0009FD34D67CD088203E8099C1FAB7A41A7AE
-:1069B00014B0C706F169901FF7A1BC633523D84E08
-:1069C00098A2B3E594DD301EF192AF4F6B7FBBA967
-:1069D00085ADC3768F0ABE9D306ED4EDEF1524A22F
-:1069E0009C6E4BCB12A0DF929A73C40F97D806CB44
-:1069F0000CE5B8CDDD3815EB37A7491BA05B545B20
-:106A000056670DF45FE11DEDC0F6B70B7223CD5B49
-:106A10002738705EF851AC53800FE06F505E697B91
-:106A200075A4CA2F0DC82F97DFBFAE3119CA270C26
-:106A3000AC5B04D014198A6762B9684B8CA31EE55D
-:106A40006D3DDF0FDB0A7CD4DACB470BA7B9AECEA6
-:106A50008173661700DF60FCB1B03626E27E3A141F
-:106A60005C3F03BD6327C3F5BACCD8FF972ABFECC0
-:106A70006C3B6197D5F32946BA71779FB807CFD59C
-:106A8000667034CB28DFE5776584FB1B22DB2E2381
-:106A9000FEF0FA35765E0FCF0D0D50BF669BE843D2
-:106AA000781488658303A87F6D16892FAED8563A6F
-:106AB00018F58D155046F9B505A7027C6A6CCBE335
-:106AC000ED5A0B1EF1003F4D15980BF9D16963A0EB
-:106AD00018E1F1E9B6C4D83AD4F76EAE1FC5A0BE2E
-:106AE00072DB3DA9F8FC745BC422E4E3F952717EC9
-:106AF0000CEA3F5B63B244B997CEAA72389DDD744D
-:106B0000735E22CABBD5DF1C7A5C02B9BA0270542C
-:106B10008271CF7744F93CD064F5FABDA922A096E2
-:106B200025DEBD3C07F0EBDF0DFBAF9B8E7258F00E
-:106B3000ED4AA6F672A2148E8E357D0AF058063CF8
-:106B4000BDF9EE0F699CCF0D87E72D86FEAB6F7EFA
-:106B50003E1AC7F9F7878F4D91E0FD0F26B9FF1751
-:106B60008EFF2761DB2E0940C2366F9B80F2A33A6D
-:106B70008771BE1AEBBA6E3187AF63BBDCFF7C5501
-:106B80007B0582A7565EE21B6466A897FA9959C2F4
-:106B9000A7C4480FFE54643528DF35BD447B5FAF82
-:106BA000C2E5D3412DA978FEAB76B5A7A2FCF8A328
-:106BB0009D97DD3B5E5B7127ACC3DD669018E09D61
-:106BC000DBC848EF5DEEE1FA34AB026692DC3BFFD6
-:106BD0007D3951B4FE559BB343E41EC8479AE78FF5
-:106BE00046E6C4750CAFEFCE42FDE9F746FF0A3C1E
-:106BF000D7DF837EEA49C373E2F8F7FB167126BE3E
-:106C0000F7DC2EB00C01CBCFDB47DA480F33105F37
-:106C1000FFA5C9B713DADB2775F891EFDDFC42CC8D
-:106C200044046381383E11F167CD3ED3CCA15C9F13
-:106C30009270F6D546BF39DCB9DDA4EA513DE517BF
-:106C40009E3323DEAF7E06F401A4CF17041FEA377C
-:106C5000AB3B9E7B75088C77CBDE8A6C9C476B7F49
-:106C6000CB0B1C0E112C602E0DD2AB2B32631B876D
-:106C7000028F7CF6C0474B1F862D55E039FD80B151
-:106C80007D333E70D78DC4A744FB64C66ED2C74126
-:106C9000BF32A3FCBFD9CBC7BB39F368633AEDABB6
-:106CA000388E059DFF9E1C13F5D3FAC3BEA95FBDA8
-:106CB000F5EE2702B05EA5DEC822AE85B2917DB4A6
-:106CC0000BE1C7A2A59DB80F233BFD2A3CD78A83C1
-:106CD00058333CB756AFF90F6A5F67914478D6DFF7
-:106CE0005CBB2700F3C9227331E8EFC9ADA6F13CC4
-:106CF000662E7FDAA39E7DF44628D72CB03900BDDE
-:106D0000A11C4DF0D9FF4303F1F964D67DC800CF33
-:106D10004406540400FA539AFB30E237FDC0B86BC6
-:106D20006F937DC88F81830B88E75FBE74261BD766
-:106D30007DEDF0C039C42B53DD19773ED0FFFB3910
-:106D400012D74FC607B2B15DC24195AF198F907C83
-:106D50003425C9B1A8AFF8712C5CDFDF0C8407FBC8
-:106D600005FF9338AF06A7885CAEFF19B2DC7F4001
-:106D7000FEA708A63BFCD07EBE10EDC0FD1E891507
-:106D80003326023D7F69FA280DC7F500DA8A437B76
-:106D9000F5D85C75E9E621D336235C7200A0EC6A75
-:106DA000B065C6C7322394EF65866E0BAC23B7FB84
-:106DB00077DBEAA02C3D38888920AAEA2352592E95
-:106DC0008C2F1C848DC27E0E8E3FB81CD7796FB776
-:106DD00095219C983554CF351B92FD3F427CAE8E59
-:106DE00076B02494431D59C88FD82D364733B45FED
-:106DF000722190F1BF502EFDED30E9E963D2DD5FE5
-:106E0000E17E8688CA0937D4DF2BF9473C80E3D777
-:106E10004439EAB81C61C1EBDFBFEE6FD171D0EF2E
-:106E2000CBEE51C63DD0EE4BC5EA000D9675DE396E
-:106E3000EEE5ABA07CB52A4FF4EBFA324936A2DD81
-:106E4000F165B7D58F7AC89736834F0090E6EE3F4D
-:106E5000F4A100F23BD76AF38BD1D8CFF459B0BC80
-:106E6000614752623E194722867D0BF01CACCAA5D1
-:106E70006B0785DA8F4372B91D342497F31FA3EC97
-:106E800020389FF5185933E2218332CE6BB44ACDB6
-:106E9000B0BE5FD9762D01CA6767BF4E1F8472E30B
-:106EA000ECFE1183D8F8FEF9E231D427404F583A6E
-:106EB0005149CB9DDC2B5F17AA708968B9DE84F03D
-:106EC000A8077834033C16DA0C7E0BEC8B2D088572
-:106ED00003ABE92E47BC61866807D20D9E2F9EBF8B
-:106EE0002C18BAD9557DCF7BC605C9FF23282F8121
-:106EF000F344B8969FFDE48A07189DDB15B9097421
-:106F00008E0D57B2DEF3FB573B2F667434E139AC7C
-:106F100015ED2D780EF546AEEF7900B776C650B771
-:106F20005D782E6BEB47D2390DAE073E81764A9DD8
-:106F3000916D8F47BE7294DAEF54F54196594D7CAE
-:106F4000A6BCDE2221FCBE8A8CA6FE0CCED5342443
-:106F50001C9FE17CA5A692115F593ABE5AC0734F9F
-:106F6000C219603F9D86801DF71988002D129EEB87
-:106F700072D389CE87224718C1CF19FB3FB6CEBE48
-:106F80001DF98D681DFAD8691045ACA93B7A2CAC67
-:106F9000AB4D601DB42F93CA3F56D9489F6B8BF100
-:106FA000117F6B5B38CC817BFD92A9F55591C45F55
-:106FB000AE3218A8DCBD7830D9636D31C05A71BCCF
-:106FC000C563496FF8F93722B7D73218AFCF62A33C
-:106FD00036637D71268DF74B8D5FDD67A7F1DA8A09
-:106FE00095E448AA1F6CC0FE4BD3DCB7217E0C1180
-:106FF000793B503CA8DD962D4A329EE7961233B578
-:107000007B44702D5E81E35C6123BD31B038F2D9E1
-:107010005DFC38FDE85FEAACE1FBD6E860DD54CE0C
-:107020004F877B4E3C8AFCC3930B27624379F1C5A3
-:1070300012C46B458C76000AF739E7AF7AF09C757D
-:107040000370597C6427D9EB72064360C3F9492C5D
-:1070500017F1E410C013DA7B4C70CEF1FC9C37C4FE
-:10706000E339CFDB167CCE309E672DBC17D6443B70
-:10707000846974CE99387E0D8B74A07DDD737EBFDC
-:10708000F265E1533438922C008BBDE9EE8755FA56
-:1070900025F83EF607D81FC0A5DC1298DC82FAB9A5
-:1070A00081557584E1034FE472FB4062DD2694AFA5
-:1070B0004B35FCAFD5E17F6058CC27512AFE43BF4A
-:1070C00017135DDBF01C3E178E4DC19787FF2E2EE8
-:1070D0000A37FE4F54F9F266BC6B37B61F693C386D
-:1070E000EC36D437D65948FF65170E0DC379D7A6AD
-:1070F000B99EC6FA8891DD66F44F7526779B707F3E
-:107100009D8BFF94827AD6D29AD7883E2F757D1BAD
-:10711000A22698506EC638B34C01E89FE8CC7A0599
-:10712000CFE5E85C8B6C09E3073930776A0AEA43FC
-:10713000C70AA7A620BF3C9602244FF2D461473E5F
-:107140006ADA7B851DD779CC994D6599C96AB9747E
-:1071500040FEFA67E0AF7E5004FE08F61A3ECF808C
-:10716000BDE6077EFB31D86BF83C05F61ABE3F0141
-:10717000F61A3EBBD63BE8FD31E788BD8817E75BD2
-:10718000B81F65B9D111562F5BFD8CC8FC1A7F83DF
-:107190007F37ED880A29576D8D0B29DFD8061864D3
-:1071A000ED2D576E1A1152D6F4CF65DE7121EFDD49
-:1071B000B5D921E5FF67E0DBC4E18BFEF27F25F85E
-:1071C000E2CF269077A5F80BE0F7DB9367111F3D20
-:1071D00026B0EA3878C6489CFF195D02F9DDF0A7B1
-:1071E00005E47609FE027463B4C90D58EF85F60F05
-:1071F000425BB47DD1FE60CC61AA80F70B9D111279
-:10720000CAF3EB5835D1D922D642CF1B58073DCB14
-:10721000D8117A96334E875F5604A6E0F3837877C9
-:107220005A1EAC7FB5D5FD443CDA6D29EED171C84C
-:107230008F6CB16497F6774EA8613355CFB54D5139
-:10724000F7053F0B70EDD0EF68D4843BEE907BE701
-:10725000D1C687F9AECC433E63E2F3BC3D796A0AFE
-:10726000F207E64A08B1A7FA9BAF559593154E0E63
-:1072700027F4D962F9F442C1B701CA075A2D66F45E
-:107280002F9CDE6852F5F5BBC9CE3D719CFB654E67
-:1072900037CC4A45FCAB6B1D9D8A787EDA2437D407
-:1072A00000FC4F4F07FEED203F8E03E5C349A79D2D
-:1072B000FA83A488CE82735BAEEEEFA4EC30AF838A
-:1072C000F60B9345E681F66E4F5A34AE5FDBB77E20
-:1072D000DDCB365942F060FEB4D0F24266EEC5B75F
-:1072E000343C6F736F3DEA4962D920F7007677CD61
-:1072F00047ABDE7D39085F6FC8B3C723DF6453D95E
-:10730000D46FC5DEFEFDC1F7ABF555EFBE6CEA8567
-:10731000AF865793F25CCBF19CE0B519E916E062B9
-:1073200040797C6C2F87636BD4B5F75D0570287945
-:107330005F641CCEE59EDF233EEFE37E7DFD3C01D6
-:10734000A4EBD148AF9CAE2BBCEF91FDB6B4B6D840
-:1073500084EB2BB175A7A0DFE9C05DA353F05C8E71
-:10736000CE1D9D827CE350E1E8C76E8771BB8A44E5
-:107370008705F0E940D1B9FBB07CAC569470DEAE25
-:10738000BDE754FED2FDF65458DF174E13C9A1AE27
-:10739000BDFF1C3E53B20FF80CCC7FDEC7F9CC4AC0
-:1073A000A38B35C2BC2B012E68C7FFB3F9CDC5F83E
-:1073B000CC5193AB2001E1552738D0FF56576821B7
-:1073C000FDE128D08785E353C3EDC827A781FD2BB6
-:1073D00021BEB926A34D796CEF88048417F32847A2
-:1073E00033A7F4E2FBF2DA9545E85F679B4C27513F
-:1073F000EF466708CAE712663C1908C253F70BA6A6
-:10740000DE32E1B5F1642008AFF578BA4787A7E727
-:10741000D98554733AAF3F32B897EFE14F307FB917
-:1074200045F437B2B45EBCFD6BE17BE5A824005F98
-:10743000F905E2EB0F27A6BD141082F8CA25F2B1B8
-:10744000D6A86F48EEB5477D4372EF7821977B074A
-:107450000AAF3FF83BC4FBBB38DE1F5B3895F0F248
-:107460009809E419C0EB686D7634964F6D2A253A79
-:10747000D3E8473F4F978AFF5ABBA5C66E93230CAC
-:107480007EBA6BC590F3CC7861C920F407F4B77E5F
-:107490006D5CAD9D36EE525D5C573FEE27795C4FDB
-:1074A000CCD85136E0F86000F6F6437EC2227BF17C
-:1074B00055443DE07AE601F87439397CBA8AAE2742
-:1074C0007A3CEED4E8D2CD301E7B7481E843FDB522
-:1074D000CB798EE8F43CD0298DD1CFBC9FAAF4F9AA
-:1074E000894A9FA755FAD4EAC59D0F5F77038E5B43
-:1074F0002B129F3EBA203B01E7FBE38E0C9A17D676
-:10750000034605E8212FFFBD024C34E40F76E45F0B
-:10751000C7010E6827942E2C257BBAD4E44808A70F
-:1075200027E8F7AD1FEFC05C8B81F1F188DF95DCB8
-:1075300055CA1A912F001C103F8F637BA82FD9C901
-:10754000FDC087B07D7C309C4693BE727CB7E04026
-:10755000D161DAFB773B9EC32A5F28BF58B9392A2D
-:10756000E4DC56B4C485944B0AF93E8ED78EA0FD58
-:107570005FEEF969FD2FF5FC6F52FBE39ABF253DE5
-:107580002536643C0452E87CE9BAFAB1BAFA89219A
-:10759000E58BE1E309152F34397222425E122EBECB
-:1075A000D435CF52159CA7313B9FFB5B66E773FF39
-:1075B000CBE5CAD582FCF072B5BFFE1A7F1A95E7FB
-:1075C0002ACA4739EA2F35E1BE2E951F05C9E105C4
-:1075D000D43F2098B17FAB2A67AB3A38DEB547DDA0
-:1075E000FF2AE2D5E7AA9E0E7849FCFE0B95DF7FC5
-:1075F000F19F6AF9A702E1E5A17D6BA3516F3FB34B
-:10760000777434DA61273BEAA391EFCBCC13FD0307
-:10761000C0C7CF5C203F61BA4F3B06969F7F54F9AD
-:10762000CE193C07929B129DC729557E9E40F94971
-:10763000F23E939E47517E42FD82E7543D7DB74026
-:10764000F4BFCAD812DE3FBD23945F556D8DD2C9F9
-:10765000C950B959B96968487999774448D95D1BC7
-:107660002A370BC432E2EB677C1C8EA5CEEC90F679
-:107670006764395A22F870387C6192A311CF4EFAB0
-:10768000E2A283E945E3BF477570388D7040FCF492
-:10769000960E8827A7D4FE5A19EC4213CE5B6A7562
-:1076A000BC128F7E844D8203E3540C78CE3438C7ED
-:1076B000230BB29E6C0ED233A40291F0F984F750E2
-:1076C0007932F21F30C0D0CFFB5AEDA154F4AF563F
-:1076D0003C13457A937EDECAA2503EF3594371EEC5
-:1076E000EFA15FE9FBA2CF8AF0288A21FEB5E0393D
-:1076F000D12742B9AB362F3A781F67543AD4E4CE3B
-:107700004A6375D873ACDA1A7A8EA5457534CEB152
-:1077100087850E61103C0F4C0749DAB75FA991EFDE
-:107720007FE53322F977577AFFF236C61557821E66
-:10773000886AC26B4DF5F310AF4FB84C06E2A71D37
-:1077400071F3103E9E05A22303DA1F6E1A41787E64
-:10775000B2296F30CEF772BE48747566AFC5205C33
-:10776000094F9789F9C95EF5D3797EE62D25B97160
-:1077700006E1827A905122BA78379FFB914EC03849
-:10778000586F003A417DB8CB273A7D61E8E3DD7C54
-:107790007E1EA72E3C40F8F3AAEF5034EA15273A94
-:1077A000F8F8A76AA5688C4FBDE5CDB6D3FA8A6014
-:1077B0005CD47BF75D4F72F28C97E323AE93ECC3FE
-:1077C000262E3F8E7997DF3F1DE0F1F92691F4CE0A
-:1077D000CF9B4AE74DC7F3DE64A2725EF1428A6F27
-:1077E0001CF371F972DC77AA1CCFEF8C174E1FCAFD
-:1077F00075FBA6BE3D291ECFD944F850F94CE8B917
-:107800002CDC144A5FF0139D057A5725FE26E3FF12
-:10781000949968272D4B02F909947BA2A8D484FE81
-:10782000C9124FA83CB2B06213E21DEA97D86ED9D4
-:1078300063A593FD487F1E81E4E5D217009F603D5C
-:10784000A61D5793BCAB68B184CC5B521B6A1F2D3D
-:10785000D3D9437A7BE9B2E585A9BA3C9CBC1854DC
-:10786000A0CA0526CD44B89F04C3BA390BE0F982FB
-:10787000A860F9BC3782F867C5D2B3D7A87AE9B552
-:107880008807CCE161D3343B3D88CE9679459D9EF7
-:107890001E0A5FD09F3F41FDB8294E95A39E52F22C
-:1078A000D78DCA53620A701D976A7F5FB27E5BAE46
-:1078B000EAB7E5A4DF1E5B08F202F673149B04F539
-:1078C0003FB0F07AF2EB1C9F7B3DE9B9C77BFC3AF5
-:1078D0002ED5AF730D9DDBF122C067921B0EAD3C20
-:1078E000A01EA1F18B8FD57338A5F2C9132A9FEC86
-:1078F00052EDAD46555E78557971BC48B5B7E21981
-:10790000C90BA3516197C2676E6C8BD2C987389D32
-:107910001D3554773EA1F262B7CB3DB300E0664916
-:107920001A1BF2DE244D0C2967ECD84FFEE3F3322C
-:10793000CF27BA077102E3250B797E16B37690FF45
-:1079400078A143A6FAA1182784F66852611E898699
-:107950009FDA7B299EBFD7CAB1B0EB3A6C97D6416C
-:10796000E5FA858C611ECC486D1C00471DE8094373
-:10797000D18F0DF324818186ED357C1FB6A095DA79
-:10798000E5563149807655056984E7494C21FE3238
-:1079900078355330DF85F99EA7764FDE0DFB00BCAE
-:1079A0000FD4CF20BBBCD41ACDE3DD201F07C6B354
-:1079B0003A4E3FCE38D25B8619396AF68BB76ABB2E
-:1079C0008BE16D901E7407D10533903FA2356A821A
-:1079D00009F1B4C4E622BF01E0F5923BD05FF99211
-:1079E00099FB091672FFE4D1C2A98FA1BD3B618F3B
-:1079F0008D7CC94757003E137FEFE676426DA9079D
-:107A0000E5DE074E2EE7C6EDF9CC80F96E5D7B9979
-:107A100003CB876A9F3FFB26D2CB0281EC8C63B5F8
-:107A2000799C2F33E6C2FCCD63CEBC0D549E0686F6
-:107A30007116D283B2C188EB00B83653FDF2FB2633
-:107A4000A3BE735824FC4D52F38C243CD7E4DE7261
-:107A5000BCA296D95E2A2715F1FCC05FA8FA41871F
-:107A60007A9E3F51EDA05D2ADDB4A974F3A04A3798
-:107A70001BF5FED0AD9C6E46191DF745417994C7A4
-:107A80004E72E6DDA253B46EA07F09E3B969856248
-:107A9000F32480DB384B80F8742988BD0DB09F9C9F
-:107AA000A23ACA5F2C75338A57942CA8A3F50530E7
-:107AB000B67415EA4D7582A8D6237F1C17E7A7F682
-:107AC00025562661FF52E77307300F77A11B40034D
-:107AD000E5FC057502C1A702C683F6076A1FA2F17D
-:107AE0008E57F1751CB5F3FEC72A98E481720673B0
-:107AF0001EBC9DAFD385F1D0E3B5CF1F20782FE01A
-:107B0000F0BEEA5343083D66F92343E87AEC8ED889
-:107B100090FAD19B878494135CE921EDE39CA1F456
-:107B20001E39726248FD3167A901E5ECF9055A7EFC
-:107B30000FF78B69765DCE1E9B01E171DD5C51F321
-:107B4000E31AD860B4BA18F97D9B543D91B58C60A6
-:107B500098BFF1E49D06CA0FD8B8A0DE8A790FE776
-:107B60003B8C745E302EF191E3FB8D34AE35CD2B22
-:107B7000A01FF35E80B318A4FF3569F24DF5ABE3A7
-:107B80007A8C41EB899519668CF5B46F53F1E92134
-:107B9000751DC0B7734C38AF8BE3495C113398A0A7
-:107BA0007FC2022EA7F574D9A1F6FF89DA7F978AE2
-:107BB0008F5DCE273744225C1631D2470AC4D51BCD
-:107BC00022701D458CE8B1C37F3032587FFC457F61
-:107BD000E32CC82EA0713C9C8F8E9D2FD447E0B91A
-:107BE0006E0DFCE91D78FEF2F3C60DD1B0DEA704E0
-:107BF000D68114A5F14F4DFFBEEA8B26AA1F3B117B
-:107C00004C34A8FFE517CDBCFD1426A3BFEB17AA83
-:107C1000DC6952E92763C778F22F9EDF6C26BB67C9
-:107C2000D7BC95DBDB60BDA3E7DCF5D40B882FF375
-:107C3000EEFADD0B72AF9E5F3A2FB913F3F747AD43
-:107C4000B733E40FDABC193B3ECBA5754B468678BB
-:107C5000FAF4CE9F2FC3F17EB22BD2A0C0F84F6FA3
-:107C600037127F1973EF63DB37B3BEFE985267A8F4
-:107C70009DFF938DED4FEDC5F735CF3F713A284FFE
-:107C8000E7D8DC7B52D06F7A747D555B7E46FFFC73
-:107C9000B3D4CCDC18BF73FEF2B39FBD05F3FFC6AF
-:107CA0003D6662B01D306A26F7FF1C5D5FD3960FFC
-:107CB00076EA5891E72930A36703C263EC8B8365AA
-:107CC000D4DF80148C6E80A57376844181FDFDC65F
-:107CD00067DC467C60F6C60C3CCFDCA78B0E7E8A48
-:107CE000E77C5CC5F77EF491A3EA39F5944D32C187
-:107CF000DDF39295DB378A9C42F6B1434E2909D2D7
-:107D0000E78EDEA5C5971C7F403E5E521645716525
-:107D10002DEE223AFFD2807C7EE9B4EAC912AD3F53
-:107D2000348E3F04E1978D715E1EAFF7788C8CF234
-:107D300082606B48276BC5B1946FF2E1AA1F52BCF9
-:107D4000DE53679132E2296EB007CB35C0772C93B2
-:107D5000288EEB43A1BD7826F7239C5B54FF9859EE
-:107D6000EE1FFEDE8B9C8F493D1FFDFBC533B91E08
-:107D70005A8FE79211722E07DD93C29C4BB495F097
-:107D80004B3B1731BA89CE85596D9998F791C851F7
-:107D90000AF7F336CAA1CEE3DC5FF69BB2DBEAD684
-:107DA00042F9EC85410CE9428BAB9427F1FC033A94
-:107DB00012E05B26B57FA2AA77231F43BDBB5C8D73
-:107DC000BB742E611477D1C63B5F3348E2E3DD42DA
-:107DD0007A737935D03FCA92A85F917ED13082E71D
-:107DE0004794DBBA9750BEAA607060DC3C51A7D7BD
-:107DF0007B5835AD37F17D91FCF986A84DD43F1104
-:107E0000C02366612B330181DAA36007A315F34910
-:107E100086E00B3948CF52F375136B5EE4FA511EBE
-:107E2000F44C0E994FF896D65FFFB1887CA0C6221D
-:107E300023DFC3DC2CE4DB04BF34C4A376EA2FDDEC
-:107E4000C424BCC7C11426C74FE17E309C4FBF7EFF
-:107E5000188FEB85A09FE17E855A3EFFD639FC1E28
-:107E600008DBCFE460BB8505AF67444859F59385CF
-:107E7000964D49E61039F59B0BA583AA07F0D7E884
-:107E8000FB1B64D7C07EDFAA20BB2BBDB7BD9627E6
-:107E9000A6C179488DE58410DD7FBFDD2EE5E99927
-:107EA00080CF36E6CA7D13E0E17E5F247967883AA9
-:107EB0004CF0084470F8F4E8B38BB8BE0BDA791DC7
-:107EC000E55B83BCC3F3C33CED5180EFCC139A2731
-:107ED000A0CDABC5973A557E1C480B2C718581C748
-:107EE000C1993C7FA16BFD9714EF2E47FD167039A9
-:107EF000B0E1CF21F73F4616E71C9C497EB7D03C46
-:107F0000044D2F45394BF8EBE172B6D3934D7CE726
-:107F10003CB3B790FEAFE7374646791F6BC548477D
-:107F200033F9EDEEA6BC911A8F45B2C073AE23D4DF
-:107F30001F337F5AA83C2856E274F222D4DFB5D012
-:107F4000151A271AD9B68EF8D779D49B88DFF1F5A0
-:107F500018D5BC3213DE2F11D15EF7D0F3B0CA9F13
-:107F6000DF51F5CC08E4AFF03E0A13CB011FED2C36
-:107F700040E54188F22330A55DA67CC738A650397C
-:107F800081B9A9ACE54126331F3DB5FC961416A076
-:107F9000F270D487442429999E23D00E19817A9EA9
-:107FA000A327DE4379937969142F2866CA1FB05D31
-:107FB00051F6E724F78AAE67944F0A9C64B9827938
-:107FC000250BB5322C14CB054C45CE7A5E5FA895B7
-:107FD000BDCB15E8DF99C3DB1B5FDBF8A4C746FC0C
-:107FE0004BADBF87D7F7941B97E760D964A0B2A4C5
-:107FF000B62FCE574CB3009F936731C2835FE729FA
-:1080000096E0B23B4F89082EAF2950A26625F49620
-:108010009FCF55ECC1E5AE5C655070FBA1054A0CE5
-:108020002FF33CD7F74D4A0ADABBF0B35B98C2F1A5
-:10803000107F5E35B993711CE51981E06501BEDDE5
-:108040004C7CDBC5904E816CAC9847047CC67C07A9
-:10805000D4B38966CAF73344D95207F247EAE92B09
-:1080600060627BD14F576C748FC675E9F99EE079D9
-:10807000ED6F98C703F4908B7A7E408D87046AB9C0
-:108080003F40A313EDBD7EBE8BE13D5382FCBCE9B6
-:10809000BDE3F6B77E3D1E1F51F5BDA3AABEF7BED8
-:1080A000EA97EED96FC018F389B597BEFBE79F46F4
-:1080B000F64910FFECBBDF534B4C5C7E48282F3A4F
-:1080C00023D8A270F72AFB5B5F54DE4CD72CCAA7DB
-:1080D0001826519C81697C9FF39B4EFC15F8E0B8F3
-:1080E000419AFDEAB0221C3258D2EC4C98B7D5C95F
-:1080F000487FADCF3F5882FCE77C19483058D7A95C
-:10810000DB4F23C531610FB7275A5218ADD79E26D2
-:1081100045A0BED4A0F24D0B8B291C89EB1F662411
-:1081200079AB5F7743B44FC0B8E2107F04F76FC4F8
-:10813000335F048C33C4E97052DE8A47949C582E16
-:1081400063F332A1BCAC4D949D30CEA1B65256091A
-:10815000E3564E033E4719E93C9F2256C5E371168C
-:1081600046F916ED09368A577B378E3EB002F9661E
-:10817000B2C832A0FDF886894EF47BD6DB62632953
-:10818000E6A4AEA7DEE6781DEF61782403BF4722A0
-:108190002956CC43DF76BBD189FC3CE5B949D16295
-:1081A00010FC4F79CF46607EFB139281EA9FA8CDE9
-:1081B000B5DE68C37B847E85F20CA4938A0DE6DD70
-:1081C000026D1261BCFBAB4EB68C62FDE343B4D3CF
-:1081D0001C82A7510EB3CE0F1AEAB734E9F4830715
-:1081E00066A9F1A4296C0A9EF3954F5D30A19EBB50
-:1081F000D426931F3DB749A0FC94C001472A9ED3C3
-:10820000A9FB4693DFDCDB24AA7E6B07F9AD0329CB
-:108210002C15EFD754B408A4178BDEBFD461BFE18F
-:108220009972328E337C527772B0BFEC89BB7E1864
-:10823000817CD45B6650FDDC8CC69165C59A06FBDB
-:10824000FFD82BF0FC099324E03D66FBC36204AE2B
-:10825000ABCBC4FD14CDC04FF17E6E734EC980749C
-:1082600068FA1AD61964B734C4A747E2BCBDF8ABA4
-:10827000907FFD744B36C547B637E5523E887E9CED
-:108280007BD7B30EB44F1AD65BE9D9A73ED595EA92
-:1082900080FE1FB7E6348290621F1F589584F783D3
-:1082A00056B4585844183C3EDD3A95E65B81F79841
-:1082B00071DE966233F2FD596D396684DBBDEB9554
-:1082C000E782E7692E76BF827C2FAAE539C2131BAD
-:1082D000F37B109EBFBE464945FDE274060B9B270B
-:1082E000F9EE2CAE67BC758D8BEE937C9C12BEDDD7
-:1082F000B1595CDF9F8DC43219F3D6D83B2B01CE28
-:1083000015404F75F0EA54537634E2AD89AD262618
-:10831000F59BB2520FDA73E7506F077EDE78D775A0
-:108320009B2BA15DC3DDA3DE45F67CA599EBCDECCF
-:108330000391E802F4C20AA4CFFF5A6095EA83F8D9
-:108340002FEA8F4A487E1A971BA626D16F067E6EAB
-:10835000DAFFC9DFD1DE41BC5582F0987EA6A8764F
-:10836000819AAF913485B471FA69987D9DCFCF30F1
-:10837000EEB2DC8AE7A9D7D3FBE0499F75048D8F65
-:108380007A6E3E532282D6012CC14FFE72379FB7C0
-:10839000A79D5A6F0406F36D90FEAEAFD7F6317A03
-:1083A000B38E5E9DDCAE03F80E18AF1BE30BED97AA
-:1083B000E16474CE6345E5E0272867DB45CAAB1E60
-:1083C000D7CEE3FFE78731F213F5379EC67FF1C7BB
-:1083D00038588523C0B531BE84CEB3BF7E66DF1169
-:1083E000256D42AF7D382629745D5ABB8C9E7DDD9C
-:1083F000C622B93ED881F699C5077C6F023E8F2808
-:1084000028BF33B7DD2E0DB46F3D3FC31F19D6BB58
-:10841000423D3219700DF9C3C79B05550F614923C1
-:10842000A7D0D545923FD85F09E27FC05778DE9E3E
-:108430004F20F834B79EDA7E2FF961EC0EDE8A9F6A
-:10844000D704A6C9419E07A4DD1364189A1ADC1B41
-:108450009FD2E0F8E9EE0DCF3E05AFCE3CB3E60B80
-:108460007C5A129645233CEF895F706D32B49B6055
-:10847000F625213F5DE9B3F4C13BAB862F69783F18
-:108480002FB4DE9214B47EF8D7BCEFA9CDCB504EFA
-:10849000EDB33A30351CF1CB13029F407A31D05303
-:1084A000D75DFF41F7F323A5B34B28BFBDD642F7F5
-:1084B000BAF4F07D729641CBA7A4FB1A1A3D45B4DD
-:1084C0008C66E85F3CA9DA4D2737819D0AE5C65ADC
-:1084D000B38CDF35E872142B4961C633D79A4FE06D
-:1084E000B9B2603B31BD779FDAF85D1EEE876C84D0
-:1084F000F18530FEBE8B8DF7AD4B59E904FCB21609
-:10850000BB56E1F3D4A6E5B4DF9ABDB55D6F429BDF
-:1085100086C1EE9B9D09B8EE11530474441A65BAE6
-:10852000EFE7F5FE8CE449CB347807F67C4B8731D6
-:1085300002F50F8FD740F1DB968EF8C89128A76C13
-:1085400086B071D6279C1C5EBDF2C4151DAC0F35DC
-:10855000E7737D48D853767F3AC0CB7B9CE7296A86
-:10856000FA87A4E2CD388B44FC59F2F23CB75E7D29
-:1085700088EBD5E751AF467D6972A5142C9F1AA2EE
-:10858000F977302AF31D1EBC87996763243F86E381
-:108590006505F45BD8986F561A7E27C3C1303F3704
-:1085A00016F41F19303BB18DEB3B91369B43413C98
-:1085B00056385D59E13F846764A6C2701EA34EBF62
-:1085C00030EBF40751577ED409FAC438D6A34FC80C
-:1085D000CC118D70B6DF37701E87E6CF05BD89EEF2
-:1085E000997918C01FF1D4EAA1F389064382E859AA
-:1085F00051E4F8C1BD7A3FDE67E3FE1589E24582AA
-:10860000D2487EFBADD9DCBF91CC78DC6B88C2ED63
-:10861000F909D33C5406FB81E250EC572C12F9F2D5
-:108620006E97FB39C48F34600368FFC58E67029173
-:10863000FB77D4CB59CDA5C5957E7C90FBFFBC863E
-:1086400048C7F63078FFCE1C2E97230FC1DE50BFEF
-:10865000BDDE4AF75B0AC4679A089F2619C8AFEDCA
-:108660006547248AE7AB7C36A6D8F5A693E2B2AE7E
-:1086700034847F92112C2A5076CDAA1F37E58EF4D0
-:108680004814F51F26FF9CE0E101D865C0BF6D3599
-:10869000F1B199F0FEF19A0D04573981FBC9B47B11
-:1086A000E77112BFDFDFEC3AEBC1FBBD1D73F8FDD4
-:1086B0009FC862E3EC74280FAF0D084877F7D89590
-:1086C00045A89734C93FA3F348CB920DE82F1B6A06
-:1086D00064AF5B2632F66C0CAF474189F58FD80743
-:1086E0006F0BCE27D9A1EEFB1121BCBEB2760ED7FF
-:1086F0006B3AF7012007A17DCC54FBFBA94AB2B726
-:108700007BCA0037E8FF8087DBCFDDCEA72A3D2379
-:10871000C92EE2F59EDFF2F6182F85FAA237D6545D
-:108720007AA0FDE369E1E7CD2CE2F07DFC8DEEC798
-:10873000308EF5D73A1EC7EAFF9CFDCC00BC658B96
-:108740009DA5B22B81CFAD322F0AF71D9975459C9F
-:108750008F74DA3A085E0CE479F455748F5EAFAF2B
-:108760005A918ECE49DBEBA6CA9C8F4C9E4257FB9A
-:1087700039EEE9C6BDB8DEEA4842FDB37E5577035F
-:10878000F28FFA03AB3EC47BE9E56566D25BCB8D25
-:10879000D5BF453BC87898E7BFE03726100F860065
-:1087A0003FC2FBA6B3AAF8F92D95B8BF56D8F391EE
-:1087B0002B0FFDB1C946C24B4D8F1D67513CE89749
-:1087C000DDA2E6B73371581DDEF7320E15C9EF1B77
-:1087D000550B7A2DEE2F9FE7EB2AF01FF2214DCF9C
-:1087E000B58D3786E4F59A7579BD465D1EF0D8C221
-:1087F000503E649F3C69407DEA576007E33AF703C7
-:108800001FC2A71FEC617C1E047B1D9F2F83BD8EA2
-:108810007EF057D767D2F3F5F50E7AFFE6FA69F4E2
-:108820009C911A30213E933F9AFC36CC2F905F4F9B
-:10883000C3B36D2373A1EED91C5EBF68F6C8FFF009
-:108840005C0DF5F16A7BCF3784873D65367645EE62
-:1088500078F28353F9D5C2CC15E4275AA0E4170265
-:108860009E24185C15F89D0776A785E216FAFDBCD4
-:1088700057A8E59184B7E3197EC220D48F535238AC
-:10888000B97F3FCE23025FC7DAB7D6EC40FA18545F
-:108890006C74211EA7A687C60F9E2FE47429CCE610
-:1088A000CFD437DDC307BAAFAFD1477FF5F5FB00B3
-:1088B0000506F55FEFB5B36BB1BE3E263C5D95A8EE
-:1088C00074D5EFF8366E4FB2D9406F43B1ACB70FE5
-:1088D00003945F72AE26CF4FE4F6BDE9AD3B05E9E8
-:1088E000AD2BC657877662D781559BF13B2122D2AB
-:1088F0001B9205D21BC63F347AABE1E7B114E90DF8
-:108900007E9D55FB9E2B0FE93189D397B067FF1AE7
-:10891000CAC7B88BE7D168F416A3E6CB47491D64F4
-:108920002FD28739B01FD0DE1601EFF17CF211256E
-:108930007F88450E7738BABB4C7ADBFC3DE9EDD732
-:10894000D704287FA2334D49427DC66BE27EABCB74
-:10895000A5C3ACD966FEFD8C2B7CC938CE16759CA0
-:1089600059C34E90FFAFC8EA10519E39650ED782A9
-:1089700049D9F4BDA18F0A79BF6FE62B1D445FD79B
-:108980007D4A7EDE0403A7DFF7DED8417221A5E130
-:1089900068F12CC4977522E9DBFA7DC5CD53E366F7
-:1089A000029F1734AFE4E038E221952EE575C73811
-:1089B0009F8F615206AC27C9239538312E74B5813B
-:1089C000BE2732A8F8680CCA676D3C38B824CC378B
-:1089D00041D5D73AB12F3DC24F876970083D1F2E50
-:1089E0001CC02F7B31FE51A8D2311E3DF971D57BC1
-:1089F0009297EBB7EDD78F784578BFA44F95AFF539
-:108A0000269EFF01AD25FC2EC0CB2EF79942F2FB2E
-:108A1000EAF4BFFD92DF8DFB58134D7EE52423D78A
-:108A2000F792649EB732947908CE5AFC4DD31765FD
-:108A300085E717DD50ECFE0BC2691B930FA03CB31A
-:108A400039D8228AAF813C43BCD8ED52CED2BCDFAC
-:108A5000510FCC2C56FE7B207C2ABE4EF906C7EF68
-:108A6000AF3EA7F8BF0E7D8BF45FC6FDA54BCBAA2A
-:108A700029376B08D849B8DE996A7E46FD305EAF6B
-:108A8000F957BD095AFC549987F993D12ABCC659A4
-:108A90005CAC02FA77A11CC6FB7B87037EBC176C1B
-:108AA000C17B6412FA5119F58FA9117C32F6173F78
-:108AB0007B05E345A63CFA9C0863D3B83DA0DDBF27
-:108AC00091F22FCFDF98325BF5374E6493103EA9B9
-:108AD00006F9A1E9F03EFBD18263783C931F5B115C
-:108AE00087E272EAB68652FCDED6AA9D1F6F437FEC
-:108AF000E8F4DF5A189E07E88F7E63D87CAE7F9833
-:108B00001C21BA2A29FACF4A8F11F951783CED2A53
-:108B100052F54FC4D3F8103CBD7A76783C25FDE77A
-:108B20007BE0E9CCD9A1785AA4C3D359B313BE17BB
-:108B30009ECEC775FF37C6A9609CB30B95E2D903DB
-:108B4000E065F64265E140F541F101B2FB46B169ED
-:108B5000D6E0EF1E6ACF56949703E427C46E3C49D3
-:108B6000F971F535E7284FB9CB76F26DB483FEABDA
-:108B7000C62207FBB3407F0FD1D75B40AE78C09EC3
-:108B8000FCA088E7411F5A67F1CF40BDB696DF478A
-:108B900028AFDD2660BEF790AA6AC10DFC2D5101F9
-:108BA000D311FAC728865EFF09FCBBD27484F4D9BE
-:108BB0007690C71E625FFC5E9A26FFC759AADF4007
-:108BC0003BB5FEEF46C7063C67261D407E5408F4C1
-:108BD00084F1CD6BBA41BE058DF7C6BE69E4579BE3
-:108BE000F135C8BF203F4E0E8C185CCEB32687F4FB
-:108BF0002B90D242EA67258D09A9D7E8BE33468D6E
-:108C0000AB4CDE918FF82356F03C8542392BA47D86
-:108C10007B592E7D0FE0CAE9FCFEDD9CCCE921E307
-:108C2000EBF582ABE13FA47751A707E8F504BD5E01
-:108C3000F0E3D9AA5EA0DE57D9680CE4127F623C4B
-:108C4000AF6EF8855F131DB4CB1CCFBD6567291FC0
-:108C5000A31EEC7FF4370D0DCA2F45BA98600E9015
-:108C60007F6ECB622B9DC7967D4FD1772334FF1744
-:108C7000D00DD1D1845C89F25CC7DB1FA4FE6C15DA
-:108C800097B37ABA146A5F24FD6FEB7CD81BD8EBDC
-:108C9000B9F3D2B8BCDD1F203F04BBD3CC506E7AF1
-:108CA0002503E58DFD58F0470823907E15924F2C43
-:108CB00089495ECA977C8F7F4F9131C7C66434FD66
-:108CC00015CA6B04B4EF7E43CDA345BC8D7032C78B
-:108CD0000628478DE7F41D3B899F8FCDC1CBD2D5A8
-:108CE000BCACD9DB3149AC05F36287E278D036BE43
-:108CF0008649F5E4D7F053FD30273B524FF3F3FE9E
-:108D00008995CCD50465B15A51FDCD6E35BEDE4D89
-:108D100071EF74C11189FE8D11A28BE2DED14CA2DC
-:108D2000B8F810564DCF28C1CF99C777E423570222
-:108D300000505EB09BCCF4FD8CDCA76D8CBE6FB494
-:108D4000CABC9DF2B20232F911EF39CEEFE16DB13A
-:108D5000FF90E2044D6FF3FB04F7A4783EC478E67D
-:108D6000905A81E13D56B18AC711C4D745C72CA896
-:108D7000176B5BE93B70895506F26B5D69AE3E404F
-:108D8000E770B785BE1FD705FDD1CFD56E3730A2AE
-:108D900057601E3DFE54F8E9BAC645718BAEBF0F51
-:108DA0002279C7747ECE7A37D7BFEBE3CD1CBF6C78
-:108DB00067FF807CBB313E92EEC72DBAB6FA6DE4F8
-:108DC000235BDE131D1B54FF33FAFF87E32F987FCD
-:108DD0006076A5A1DE69AE0AEFA73433D7BB93D185
-:108DE0005F7AD7CAA481F4A87EE3223683DF1C7D94
-:108DF000E9719186721E07D1D6A9EDB3D1B6465856
-:108E000026E36FDF332E52D64F5C24502D20BF1F38
-:108E10008EF513103EDC6FFD5DE322CFCCE5F2F65C
-:108E200072E322DABEE7AABF170162ABF91D14177D
-:108E3000A07333F4AE2F088E3B707DE5F89BCCDF3A
-:108E4000639C61BE5A7EFB99A39FA15FFFF0EE83F6
-:108E5000CFE073C68527CAD6005E144FB393BFF721
-:108E6000DD1FC53CCC870B8D1FCC755842FCF7F835
-:108E700083F849EB10F8BDFCE0FA62DDBA728DA10F
-:108E8000F1807C5B68FB99F1A1F5CE61A16533AB04
-:108E9000263CD5EF7743D4DD9427D7781B73F00CAD
-:108EA000F1A0F3102F5E360F3387DD97866FCC91DC
-:108EB0004674DFFE3EA77BD74BB7BFB196EC580395
-:108EC000DD9F3FB7A8E19EB764C40F33F3D0384E9F
-:108ED00005F1E8AB9F8E7F87623A92DB7323B45F24
-:108EE00096C7BF17D5279EA0FAF387D71CE8C80FEF
-:108EF0008EF70E76AF9E03FC7CB8EDAC807AC8F09E
-:108F00009A97A9FEBAC59307C4A38C9A431DF94149
-:108F1000DFF5CB30BA0CE8C7C8A87995DEF7A7F71C
-:108F200018640FCFDF2B33CB646FA9796A192ADE5F
-:108F30006494717FAB94CEE5CD1613976F1EA8167F
-:108F4000AF82FFB5E9F3DD385F3F3F8DDFEB60C0F7
-:108F500085905F69E3E9E59926076C0AD72333CA50
-:108F60001EE17245CB176CD3E7C5B91F44F808550D
-:108F70008DD46E6B9EDA6E3FD74FD96C26A15C867E
-:108F80007D86CD137D748E1A2FEA273F8D69F6E317
-:108F900082D73FC4FCBCCBB61FFB1977466A20ECD6
-:108FA0007DDB3D85DC7EEC8C08A4201FEE3485D76C
-:108FB000DF1B17CCFCE99C01F457CCAB4598F66B52
-:108FC0002F7CC7BCDA0FD57891162FD5F26B99D1CB
-:108FD0003711BFF39969FBE0068A83F693577B8FBD
-:108FE000DD11C07BEEDE8A08C776F6DDFDEB279C3F
-:108FF0009C9FEE98C3B8FF5E175FD0AFFB83393DEF
-:109000007185E373E85E58F8B842CF3E93C3FBE343
-:10901000AE98A7DDF757EF2B39B9DEA79814162EB7
-:109020000F54CB77D7BF077BE8CC9C20BF9EBB2ECD
-:1090300083FC76F5268EB71E997F4F50D31F6DA8FF
-:109040003F921ED542F5D1555C9FD4F42C498D6BCF
-:10905000E8E909E8E3AF388F60E374ABE9893DF4F0
-:10906000711DD007D0E530C6E34A06356F74989578
-:10907000A7A07F573DAAAFFDF4B5FD3BD94F753B87
-:1090800023C87EAADAFE06EA55ED35DC4FD869AF73
-:109090007E03BF7FE0794F24BDA9BFFE9A1D95389E
-:1090A0002FD48EC2B822E263A2CD27C857A01D15C7
-:1090B00030B9617DE56847D9306FD53DAC28A1AFA7
-:1090C0003DD575F79F29DF15ECCD94A27F047FD0A5
-:1090D000F9970EAA791007469E25BF8958C3ED3D22
-:1090E000B186C7438D653C6E6154B81FC50CF2084C
-:1090F0005D819A1F658B23D48FD295C2FD2889F993
-:10910000D57ED4034DD32C9242F291FB55B4BCF6DC
-:109110007116DF1B781FA33ECBC8300F1D1455B24C
-:10912000032D6A7C83957179A5F94DF479D3369D29
-:109130009F44EF47C92F0AF59B3C2EC8F74E87790D
-:109140009EDF5CF016A2ED7F6E5D11857E93177D2C
-:109150000D7354BFC9A3B89E7D1F72BF49D73E6E21
-:1091600017B95181B92A1CFEF58953911F64DDE1BD
-:10917000F5142FD3FC5089552A3CD4B80FC217E1FF
-:10918000293A393C6374F0F40ED3E2422A3C133896
-:109190007CCB8B5CE47792109E522F3C353F95F749
-:1091A00070077D5FDBB2CE227B089E9F91BD6A4235
-:1091B0007822FCBFA71FEA9622D52E55E139F1D1BE
-:1091C000EC87F03BC1931E2B3D86CF29DB6E8BBB1A
-:1091D000019ED3763E548A4FF63A8F13FC752EE7E4
-:1091E0005798D91D4C8F3715CA21DF83D7E0A9E1E5
-:1091F00061AFFF8E913FB65CE2FEFC72150F33103B
-:109200006EC1FE3C4728DCB6A8F992C6FC6A0FDAAC
-:10921000BBC37570D3F0B01EE186FC2EC62C7BC894
-:109220007F572BA03DD41F1E0E6FBB3C3C7C588744
-:10923000873FDB9C7D2FC2EB85ADA56FE1F3E7BED9
-:10924000DBA2105E7B773C34A71FB82587F07974CA
-:109250007227F485DB8962F70EE40F331C3E23F19D
-:1092600059C037B47BB7374DB486C66734FEE8B40F
-:1092700086931F17F72FADA1BCC2FAB235C41FBB2E
-:109280007AF863B71DF3102F953FE6CDE5F7FACBDB
-:109290006BBE7A6506C035AFE604D19F11E88FCE6C
-:1092A000ADF68441CDC76011202F12CB981FE3C7C4
-:1092B0004398D51725507E02F14D2FE639E3074A32
-:1092C000F57E0AE9D5BF09441C4C3024011FC7DCD8
-:1092D000A92B490EBE5934B92F9F6D2F3390FF67CC
-:1092E000BBEA1F2C5BE03A8CEDB4F8D66E97F276B1
-:1092F000D1F7F36B1F2F0AF21776C6B01EFF1A7E46
-:109300001F3CAF669B807928436A6F25F99058A669
-:1093100030940FB7CEE67462CC9768BF7DFD6DDDEB
-:1093200079682774E28DF62CC2838F110F3A6B9EF9
-:10933000243CB87215F78F74D69C8B0B8F073511B0
-:10934000DFCDCFB83D444E7A6BF8774C3AEDCAEB9F
-:1093500019978107CB543CD0E424CA1BC427635916
-:10936000E051F4630F017C88484379C9F9B108F2F0
-:109370002A0AF623F6E37FD4E8A10BD6661984F710
-:1093800084F5F900D5B4EE7365B9FEA903ACEF928C
-:10939000F300D4B864BD1A975C5AC3F3573BD77D2A
-:1093A0005580EB3D5706F601C0657B9983E1F9CD09
-:1093B00002C52A600B9EA74FDEEAB0B909BD71480D
-:1093C0002D9E7FA2D8958AEF67004E25C5625EAFBD
-:1093D0001AEF19A67E075A87FF80E7A3E6925F4E31
-:1093E00022B9A1F9D119EA8D76C46F6534D64F3010
-:1093F00057274B84DFEEF1586EDF7727E52FF4FA1D
-:1094000007793EDCF7F66F459B29BF52F36F79ED84
-:10941000DCBF55C10205685F531C01F976AB85BE00
-:10942000D75029C866F2AF95B895B9A4F7B8281FE8
-:10943000D6BDC02A911F6CD5AE64E417E58D22C954
-:10944000EBFEEC92BE7476997C46A5BBEFC067AE8E
-:109450009F7B697C6631EE2F88CFDC30F77BF099FB
-:10946000F78B42F90BEA9D75304F9E4A4F3DFB56F4
-:10947000E3F818BF8AC80AD247D5FDEAE9A88F5E8B
-:10948000FA7F1F5DDD83700D43571BF1FD65D055DD
-:10949000EB45E8EA413CCF20BA6AFF17A5ABA72FFE
-:1094A00085AE94B92C344F3A8E7FE7795C9C81E786
-:1094B00059FE1FCE931EA3DAD9FA3C69C6AAA95C4D
-:1094C000046743E7A396E74D6232C6992CDB5EDE64
-:1094D0003456E6E305FB3B99CECFC9747E4DBD7E85
-:1094E00017C60F1AE2F73CFCD4EF0E8F855F9F7E04
-:1094F000F6BF49AF7D7BA640F7C9E78DFE6A3FEA1C
-:10950000A0C51B97A9F30CECF7FC67FB39F127D832
-:10951000AFAADF5763D4DDEABD81CBF37332C7ADA9
-:10952000F47DF3F66AE640B85FCCEFD95ECBF3A6E4
-:10953000B5BC66D74B950F2F9CC4F3E9D0EFA9F7C4
-:10954000776AF9CAF5B665A4E79F54ACDC1FABF3A4
-:10955000772E8B936FA17B8C7DFD9D91F3FE01FE99
-:10956000CEDBE7C8DC4FA3F37B96CE52E2E70D904B
-:10957000CFD019E360C8EFF26C3E01E3B5EC4236A0
-:10958000F97586D802F47DADF29A1CD2034716BB5A
-:10959000D3701C637EF7E72F4EA27C03070EA5E76E
-:1095A000CBA067A6CFA33CB67F8E9FE09FE5E7FBED
-:1095B00068CEE5DD9FFF08E13D79807BF472E0B184
-:1095C0002878FF789D9DBEAFF5FC6C59CD3FE84EE5
-:1095D0006981FA77EF3A7310FD13BE3603C3FB6D52
-:1095E00097EA3F6AB8885E6CD6D9475B7AF462DF47
-:1095F0001B5383F4E286F5CE7DA7C38CA3E9C5BBDC
-:1096000074FEA3721BD78BCB6DDD26B40FCAE3BFEC
-:109610007E05F34E8D55AC03E5E210A59AF4E144C6
-:1096200089513EF1FF8FCBB37F685CFEFE79A1715B
-:10963000F9096A3E0AF278FCFE4F97E6479DC6F5A7
-:10964000868D466EAF78157817268EAE8FCB0FBFFE
-:10965000B087E2F2ED7BAD748F6FCBBE663E5E0EDF
-:109660009330CF3C99A9FA5A11F797EAF58FC74D75
-:109670008A356D12E2BB81EE13E23D41F28BECB50F
-:109680006E437FD3783BCFE7CE7D67F14ECAE7D6F6
-:10969000F443D043492F2E0BD07799CA250723BE18
-:1096A000133FCD4FF1F15A81F06BD93C4E6F4BF324
-:1096B0007DA41F0E2993047E4FCCC3EDF8541E7772
-:1096C0008E44FC82A662268FFB4A474407C69DEF64
-:1096D000C3A6D3F1FE2AE3DFAB986EA0BF43D12E21
-:1096E0007427215F6E1594647C82CE44F71E9F8D93
-:1096F0005106E3DF93AA4F31D0DF933A54D09884D8
-:10970000EB6BAA6B4D42BDF015D52FDE5AF009E583
-:109710003F98C6833E9846CFB07F77F4C1F982FA6E
-:1097200077043B92E87B08ACE543C2AB4C33E37F64
-:10973000E7C7E15F8EF474DA46FAC203828FDF1363
-:10974000B25BE93E5ECB18737225ACA7D96E266D6D
-:10975000C23B66E6913478DF9C2045631CC09B9633
-:109760002EA1FFC81BD3F83AFA419AD3D219E6FBCF
-:1097700037954DA1F879D3056030D0B37EECA8774A
-:1097800027C3FB8D4280BE1BE4996E60984FD8368C
-:10979000666672F0BD4C51D2CB4907C9055136D02F
-:1097A0003D3F518D678B7DE2D9A1F1E949EABE6564
-:1097B000D6B288EE81C69B25DC6FF998920FE99EA0
-:1097C0005BBC99F282CA4D8C7FF7630CA373D1C343
-:1097D000AF7E7D685CC1680B5DDF460C4C531EF6A6
-:1097E0009695881F0D0853CAE3BE7725F2A5869E7D
-:1097F000FA465E8EE0E5AFE7D5AD44392833FEF793
-:10980000491A3279DE65794209F1E1725320EC7729
-:109810007E2FB61E99F914753CF63F39DEC631E647
-:1098200045BEF1171FAFF75C407DFE0EE36AEDF415
-:10983000E3EAFBFD4FB5EF6F9F89F3B5BC7A46793C
-:1098400010A422AAF7D9504F36AAFCB03E778ACF8F
-:109850002F233FF070BA883184CDB3ED9F3E82C68E
-:10986000E749BDC46F697CFCF64C4DA11FF923BECE
-:109870002F49EAA59B9EFC0B753CA87A15E5C3D63B
-:10988000F942CFBAA5C1BDE3FEA62CDB8F761CD86A
-:1098900019729C230CFDA9791AD43E8DF26D283FD4
-:1098A000868D65C447B4F646755E7DDEC66E152F9F
-:1098B0002E376FE334EE6112C91AB207BDBF6DA136
-:1098C000FC25861FA342FF5C9644F7E1EED5DAD96A
-:1098D00019D971DA3944B0DE1FB4D392B482CC46C0
-:1098E000E23DC38DA327D0DFA77C74F7833FC1FC83
-:1098F0008DCDCF6CF8233E23474EB87FDA24BC478A
-:109900006F70A8B9D4643F69F934B67FDBFC35EADF
-:10991000A9FA7C95C6F12B5AE8F882CF311DFF2EAB
-:10992000B2A0A07FDF62B36DA7EFF95805B21FC4E4
-:10993000871269FD4995A1E7DE2E281FE077FF3CDD
-:10994000F709C447231CA1F9377A7BA3A9E75C4335
-:10995000ED940784F071EFD7E6733923EAEE89B608
-:109960009A64FA8E6DEB46112399AC759D85F8D9F2
-:10997000EFE72F5989DF19BF03191ED4B75F63A61C
-:10998000BF6BD56E97AE5B8465559E6971E607AE79
-:1099900018E50BFEFB47AFA29C85F95AAE31933C0C
-:1099A00060C66ECA63D7DF0FEF6367E9F0EE6278D7
-:1099B00076C3FC5835DFC04772A5C7BE1F6DE0F700
-:1099C000A0471BFE25EE41BBE787B7EFBFEF3D6821
-:1099D0008AEB25F4A55F2DFF6F4354EA62DC7FC359
-:1099E0002C337D2FEE72EDDED6752B495E786E65D9
-:1099F0008E0C47DFBC30D74B23097FC42691FC7106
-:109A0000BDF8C5EDDA5FCC33F5FC9D166B109FD425
-:109A1000F2821E52EF153FE46AA4FC19AF93DF2BCC
-:109A20008E685949F6722BE8619857A5D9C727A7C0
-:109A3000A54F1128EF47F1E0773D4EE6AA79415254
-:109A4000687E0B53F3FBB4F95AA7A5D37C5EB4C769
-:109A500007C003A353CDDFD38DD7C3AFD1EE0EB272
-:109A600097C1EEFEDB7CD8DFFD36073AE3A0FE654A
-:109A7000AA6793622FE91E6817FE0AED7E50AAD0EE
-:109A80009F48F9DF0A551CCD00800000000000004F
-:109A90001F8B080000000000000BAD3B0D7054D57B
-:109AA000B9DFFDD9BB1BB29BDC0D9BB8C1106F02A7
-:109AB000D1203F5E304913C572F303244AEDCD0F28
-:109AC00009BE01DEA26871ECD4ADB5BED03ACDC5F9
-:109AD0006C4888084BC4065F1D8D54FBDAB1D5D4A1
-:109AE000D7D7878EED5B90E7F84FDADAAA333E1BC3
-:109AF000D1F2FA3A9D37E96BB1E98C2DEFFBBE73D9
-:109B00002FD95D36809438E3E1DC73CE77CEF9FE51
-:109B10007FCEB655D53AF91180E350080AB61F85B5
-:109B2000CC35610078DF6706CC2500A7E86F1540CB
-:109B30007FD20729EC836A0260BB0E263775E07C72
-:109B400058E88327B15122CBF9FBD690ADCA4180AA
-:109B500012BB12A078667D1BEC57EFC2F1AB7C63A1
-:109B60002D500390D80ABA834BB684922AF5570336
-:109B700038801BAF351A031508B7F505DA086055AC
-:109B800078240232C0B2E70F94C5687FC7FA7975AE
-:109B90001DD054FE5BEC9FB09B717DFF1B8A791F2B
-:109BA0007FD10FC770BD1A5560182148CFAC8C4EBD
-:109BB000E279D4E089F7A000E0BA29809680587B4A
-:109BC0008AE04F07A0A57AA6DF8890D3FBCD81D28B
-:109BD0008CF9ABF58A8C71052C3325E1B9A38B3256
-:109BE000E6856A6B743A6F9BB13CE3FB0DD50D19AA
-:109BF000EBA1453D3E89FD95F8DFA94A8227FA3C55
-:109C00005E01105C82FDB4F52AA4F571FC1A3B14C8
-:109C100039B1183B9F81CF9C52882EE60620BA802E
-:109C20006C3E897829793E30998FF803CB32222512
-:109C3000880F1A3200BE6CE3E25AEC074FC884FF6B
-:109C400047F271EF52C4B33E29139D401F97F83B72
-:109C5000C0F830223BAA5A3C0FA2A02770DEA5E034
-:109C6000483AF6435148527F3E24793EFE251F6C08
-:109C700040B60888F5051D60EEC5F1FC258E24610F
-:109C8000BFA8154C05E105CD0989CEA9E37A05F9F0
-:109C9000A01452DC2F6B85897E866FDD47EB4B7BF2
-:109CA000411F2825B00E8F8F6D0487CEF33898E0C2
-:109CB00057081F36C002000DE2DC5E064611221175
-:109CC000BE0DE60AEA57C1242115A93A2651FF1212
-:109CD00018D7A90F90027B2936936AF84480A70011
-:109CE000F1A9C7AFD92DED74C2A30B4E1EBFD1DAB7
-:109CF00066237F77DF545B180BCEBE4EED7D71BCC3
-:109D0000E5EA99FEB76D83E542ED5DCBF2A2F6BEC2
-:109D1000C4E3476DFB2B36D26319C20FACF8F4F8DD
-:109D20005FA6097C2624301D9C9F78EEFAE8161C5D
-:109D3000779E0B985540F8457C125FD407A65E6964
-:109D400010EB891E11A407E1BB6809488483F9441C
-:109D500007FCAE211D76311D930CB73C0EE60E7745
-:109D60005FEA97221D882E63A0CF21BC2AF14F47BE
-:109D700007FE4338971C0A3C3E2C1176912E0B2E81
-:109D80000A5DBE752174C9A607DC3B17A0E16CFB18
-:109D90003A4CC76F49A93C69019105E983F7919055
-:109DA0003E84CF28087A680026E12917FEA99F572C
-:109DB00003C67DDC17F3899E4EC30CFF1722FF8B71
-:109DC000BE90AF30D241F4059D22242FD88FDAE324
-:109DD000BCBE682BD80F94123D2C469E0F62DCFA55
-:109DE000614AA2B65232995E0B145BA67EBE9412F3
-:109DF00048464A923E28009DE9330FE2DC467C53F8
-:109E0000874F91BE0ECA634E05B5CF36D23EFDEBED
-:109E100050C390CA0F8D34325FDE0E7A15F25DB9F1
-:109E200066B1FE2EBF52351D231D5FF7317C30AC6D
-:109E300003646FCAE5100CD7CCEC9BF099D124D207
-:109E4000EB58E8C491187E9F53AA80DF9CC1F37140
-:109E50009FB81FC1542E257910F211ADC7B384CF1E
-:109E6000D46F5155F06D701BE20FF1B19906104F90
-:109E7000D2D0BFF3F7479A85BEFBAE1DFB88F885AD
-:109E8000F413E3CF029DF4936E02EB4DD9707E4341
-:109E900076F1E490DF203E85E4A815C07DB6B8FBDE
-:109EA0006C19F27F2015A4DD33E18794A79F2B69FD
-:109EB000BD5DC8FC6C4A10A83BFF7517CAFFD05B9C
-:109EC0004CCC764EBE6D7C6665E1E492D9E76924A0
-:109ED0001F73D3D7093A6911E4A7208DBFC4E3E704
-:109EE00082E3EB3D9C21671E1C5FD46638BEDEA377
-:109EF00042DEC86E213D6F43BB358CF8FE474BD721
-:109F0000045F4EFD27D9F39BE30526D9734611CE96
-:109F1000BB25298D0D233FDE0A718DF85482850EF5
-:109F2000D16FB32399C338A572D7D602F617A045CF
-:109F300027FC48A96B95538B3F051E5D3C6D4EFD7C
-:109F40008FCF08115E43F0A1375E3933FEC78D0B0A
-:109F50008ED51AA4B483D544DF7C97BEA8899CD73C
-:109F6000F09CBE4F0A615847EECFFFC61BABF07C9A
-:109F700003BF504CA582E6696021BC3920EC783ED5
-:109F8000C9E902E297F1D41DC46FBD853ADDD79BC4
-:109F900007EE3C076216DD331FF500C195F37733FA
-:109FA0007FE6176886C2CC8F1A27FD1E01E4BB121C
-:109FB0004635FF156BA914C9577153C0DC91095F71
-:109FC0003A45EB112694B8F790CEDC7F29F5033C97
-:109FD000D478CADDCF0AA4ED97D5F745D3FA20C6C9
-:109FE0009DF4F9A606A934BC9E961757CEBC7307FC
-:109FF000835AA6BC64ADF3E8B1C427F8635E198C3C
-:10A00000EDC0F30E0D1D6C247D335A0C861F8706A0
-:10A01000377F47029CDF44BA98EC4F0B8CF925DA66
-:10A02000C718AEC6BEAF2CC8FC73C96FEDD41D08EF
-:10A03000E70BF57EDD409CCCFBBDA537E2F86D65F6
-:10A0400001D342FA26DCF94E0BFA5962FB5F915FAD
-:10A050007AAB7B5EA605CAE1BDEDC2CF52C35D3BC4
-:10A060005FC3F9FBE629A0905E53369A649F6E5554
-:10A0700001E616617FBF8FFD3EF4EFF83EFE964C81
-:10A08000BFEFB6477C197D5F969FF8F576F403899C
-:10A0900068AE1F38D00EBC2F9D67EE8ABF1F3E04EE
-:10A0A00023AC3F97AA13B29EC3AE7AF8979E0932AB
-:10A0B000FE7F528C78A575605B7762DF8F78247E97
-:10A0C00045455D508B78B2E89F06F9C93FBA8BE6EB
-:10A0D000FB4F22FFD27C25D87227D1E152174F20A7
-:10A0E000CE65E17F74EE6C7FD89FE50F679FDBA3A1
-:10A0F000C3631E7EEAA08EF083FE39FB07DEBDB28D
-:10A10000EFF3421F6A0EE4A59FF605B84DF5E9DCB2
-:10A110001EE98B727BB4CF801674AC5EEAABE6F6B8
-:10A12000E53E93BFBFDA57CFAD878FD9F44DA8581E
-:10A13000667F61DFBDF2180993BA447FE50AE2DB6E
-:10A14000B714561F3A1879EA02B643A0E2BCCB5ABC
-:10A15000D5318BEEE2C63F97B87CB6D83F75D88F25
-:10A16000EB92A560DE470BD16E6FAD99897FAE9BF8
-:10A170009267E40428DE9933636780E29DB919FD94
-:10A18000E6C0A519F357EB0B32C63DFA3ED628E4DC
-:10A19000666D7471C6FC7D2D4DA92F905FDFE0D7F1
-:10A1A000159DE29FAB33C66FA8BE36031E28EB4C4D
-:10A1B000D2D3451BD3E8C6F7CFA4ABB6EDEC719074
-:10A1C00047E7F7DA33E3A1D9E89BCDB71E5E8B4EA4
-:10A1D000E355C495098A2B0DBAF712690B82DA731D
-:10A1E000DA2FB1C00ECDECABD6637CB9ECE2C797E9
-:10A1F00005145F56E48A2F3FD2897FCF195FB66678
-:10A20000C6970559783B577CA97564EA95F3C5E76D
-:10A21000E6F2F81BB514EFBDAEB01FA8B4C6D9FE68
-:10A22000CD9D50CCB508B7D8F5C74224F3386F732D
-:10A23000ADC6FEE53E988C92DDDF2B215691FFE7FF
-:10A240002E314B49DF3C1DB64A6EA238BF4D360F4A
-:10A25000E292171BBF1925BF63D78EC7A36894600E
-:10A260005187CCFB261B4F6C22B9520DF4E3246EB0
-:10A27000ADB11CFE8937FFAB033EB6037B37696384
-:10A2800012CEDF1BD2BB3750DFDD0711C2F676B42A
-:10A29000F6F231F2FFAEEC3004BF801325FA3FB87E
-:10A2A000A9AE948D948AFDA534DD643B3E1C32AD8D
-:10A2B0005B887F7E1304073F3D20E90512D98B4D53
-:10A2C000B2FE24DE73B475C5BB5BB1BF2BA8992465
-:10A2D000F089705D29F197B219DD1EEC8FB48EBC48
-:10A2E0004CEBD52A99FB894D971F23F779B4586F0A
-:10A2F000ABA4386F7525611A94439FF4515E231106
-:10A300003E11A5F5FDD788F5B3D147D1D3EC39700F
-:10A31000FE82CFAB2C94531AC2515E38F15782A7FC
-:10A32000A4DB71D6E3997EC57058A32001D6FF7CCB
-:10A33000E1F71C9554B965111D4751E6094F9B374C
-:10A340007514523CB5D937599CCB5E0CA07E4D5D3F
-:10A3500091E66F4632FD846CF8FC5747F8C53F59CB
-:10A36000748D123774C1BFC48D6BC652843748B622
-:10A370005652DC1B147679363CA8C14C3C78F01957
-:10A380001EFE4FE9CDB3F2D2F080D74A91BF73479A
-:10A3900087C4F4FF22F141AD3806C51DDEB9D4569D
-:10A3A00099D779FA01F978C338F1878BF7289A0C95
-:10A3B0009243EF1C5F75E1DD739AAF706A49DA3939
-:10A3C000566A2E3C93E3E2AB342157F02BC57CD286
-:10A3D000C84127D77FE3F51533E3AA7BFE2B0E6830
-:10A3E00019FA7788F6C77BBCBDB1F3ACF1F2A2B124
-:10A3F000CC75DFE9003EEF958A75E404F95257C841
-:10A40000634F22A8C557C82CCF27D1FF22BB361BCC
-:10A410003C8FFE2C6225CC5D407ED9CE4807F3F9F7
-:10A420006CEBB4B109AB6219ED0BF171E4AF45D13E
-:10A43000CC7379F3BE73FA5E5F8139741E74C8C938
-:10A440001EF9C75216E9693FC291B0AD7EFC6EFDA0
-:10A450006CF7F6431A7CC4E74792D0574E18F8BE03
-:10A460008977C7587EE0D0D48724DF894525C63058
-:10A47000CB0B4417D6913F22EEE5CBA2D3709E8042
-:10A4800033B25CF8A9236EDF592AE042BA9CE2FAA3
-:10A490003C37AFF242C702C6BB467A8688AC5AE563
-:10A4A000C41741F5878E8EFC3027B80FC2D8FA2327
-:10A4B0005B1C6A57951B7BEAF15C238B64B66323B4
-:10A4C000A1D8E303A487160573CAC76BAE5E1C222E
-:10A4D000BEE5F8092C99E44EF284046232D26B9402
-:10A4E000391FE0FD8EB0C867E9C9FA9B118F6FBBB9
-:10A4F0007C81F7E1F5D9F0DF3D13FE13C4AF0917F6
-:10A5000038C1D982707EEDCA0590412971E33EDCE5
-:10A510002F6024EBC95F98ECD0C5B8BADCA4FB8FE0
-:10A520008473EF37E9EE67C97189E65DB251AC8794
-:10A530008058B7579ADA705CD093E589F6A7F17C1A
-:10A5400033533F64C3CDABCED4575A59E6FCFF75A5
-:10A55000F92F3B1E7A40CA7DCEC24E71DF55E5C051
-:10A56000F688F8E2BE1C7C912DEF1AE53F11EEDF74
-:10A57000880EBC9FD03B4175A229BF86EC3B98FD5D
-:10A580008CD8C37CDFFBF26FE43879E00691E7D02A
-:10A5900054A1B7CB362018B4C7F64F5A1CEA2B7714
-:10A5A00083EE0F9F89874F1BEF91BD71D2D6873BFA
-:10A5B00081CFA9A4C781788FA4CFB891F64DEE5270
-:10A5C00080FC80E476FF865C76BBB8C3E7E95D8EED
-:10A5D0006B55972FC0AC0019D71F784BE1BCC081D9
-:10A5E000FA9D1C17276CCD902A284FF1086CC7F1F3
-:10A5F0003F5A32FBADBD87EEFDF5ABB8EC784B654D
-:10A600009D24B31CC1AD38FF38C6C5E43793FC6543
-:10A61000E46310B181BA99FD922D95BC5F02F79366
-:10A62000CEA2E7541BE3D66567C23B6D8FB3F2231E
-:10A630000325B1DA4EBCDFBEA0A8B3285E7EA42BF2
-:10A64000725E791D0392A95ED22B1B81F1106A1BE9
-:10A6500081ED944F888A38E348AD5FF0D776C98D95
-:10A66000CFA0053C3D857FEB361A0FCF25FBF28E40
-:10A670001FAA70BCE9A9D755EA8F94CA75143F5F29
-:10A68000A54DDE7F158DD7F9587F3422255319FC4F
-:10A6900091F2CB513E8FE6B68A685312B5CD81FC5C
-:10A6A0000C7DBD5ACF8C3FF64C1F510A893F753047
-:10A6B00025C4F39E46D32A24DD634EF6D3F73DAB83
-:10A6C0000D73D8207F38334ED9D3A6097D5A21EC9B
-:10A6D000CEC861E361F2AF067BF3D8FF7CA04C16D5
-:10A6E000F75E0863C40F6D46665C33325EB96B215A
-:10A6F000C959D2C7F9F2EF8F8BF95B772C1FA3B83A
-:10A700005477FDD5ADA54DEC87C280987743F5E22F
-:10A71000ACFB4FE8C417C9ED3E20FC0F96DD3C446E
-:10A72000F9D00F12BEAB495C5EED3432E2C22D03AC
-:10A73000B7729D6840839BE8FC7B3669CCFF7B8ABF
-:10A740003F38700BE9E9E2398CE7D14D5A692C4D5D
-:10A750001EFED6E9673918DD24FC8B621962E339E5
-:10A76000C6FFD629F4D0E76E07BE4F01DA65033F76
-:10A77000196A3CE5277C9401FC335D27FAD1437CC0
-:10A78000FF5619AAF08823918DECBF65F359B0AB41
-:10A790008AE19DB68FF572061E7D7E3BCE79EE1B5B
-:10A7A000C0207DD5D28A7D8AEF376A40FCE68FDEF5
-:10A7B000CDF72CC27E1EF603AD4947C57E6061EC25
-:10A7C0006AF25B5FDCDE334479167F44D689DFFCB6
-:10A7D0001B6FB33B697E8D0FF2707C000C294AE73A
-:10A7E0007424207D6D40AC95FCF591A8AC53DE66D9
-:10A7F0005D62FD36DA7F5D640E109D37B7C9BCDF40
-:10A80000494BE3A45531391A94FF2A09B2DD7DDFA3
-:10A81000177FB807E7BF8FF47260E65E873A2BF9BF
-:10A820009E794666FC1C8024DBE195D6C446DA6737
-:10A8300065BD46150D38D270E200F9EBA3B57ED3A5
-:10A840008FE71A6D9018DF1FD7FAC6F0A8F0536D86
-:10A8500042A17D7FFA31F246452EF93DBBDC64CF43
-:10A86000DF53DF11207ED809135D841F675A66FB12
-:10A87000953DAFA14BD07F27E285F0ECE079AB2886
-:10A880002E9A42B942E8E169FBBBB760FBA54E9541
-:10A89000E77DB55476A82E34D8A6B19C0C866243C9
-:10A8A00015D4477EE7782812637E1E298DB01C7A66
-:10A8B000FB8C34745713BFBC519BC77EFB973B4F37
-:10A8C000DCEE2C44FDA1FCFE5F9FA1F8A94C637A4D
-:10A8D0000EFAECD4ABC4D76DC25F3C3AFF1E96BBF8
-:10A8E000818D3703E10D9CF83B54B71AA86960F8D5
-:10A8F0005EBE6164BEC8270D44EE7228BF91AA17E0
-:10A90000F905ABF820E7F3BCBC52A3ABC716FBE3D9
-:10A91000AF54D1BADB55511756CA12A40FFC945745
-:10A92000A2756A66BEEBBAA9CC38785E561C9C9DAF
-:10A930006782C0C4C24EB4A7BFEBCCCC2BD1155894
-:10A940008E6BFC1C2F8ED68B3828E98B97EA4BCE6A
-:10A9500094E3375D3F78A22F801C00F0F33E9DFB0F
-:10A9600005D61F76CC45506FF545F9FBE7573E2ECF
-:10A97000A5AFDB53B33E60B0DE988C12DC6C7D91EA
-:10A98000CD07BD9D7398BE18A701D177CF14307E37
-:10A99000430D2B52C4A727FF041C877EB6652208EF
-:10A9A0009567AE4FD139FD94FF12E73C4AE7F45367
-:10A9B000FE4B9CEFE53E83DB57FBAAB95DD3052236
-:10A9C000CFEFE983CB501F20DE5ACA449FE49FECAF
-:10A9D0007051E4669BF8CB1F557592EF40593225B4
-:10A9E000A5E983D150FC5DB2CB83C541E6BFEC73D2
-:10A9F0005DDE25BB762F7E13C1DD837009EF2F6EE0
-:10AA0000FFEF8716D03E6F29CC57451BBBB7B1DE91
-:10AA100041BD90C7FE86D087C9E220E71D46B757E3
-:10AA20004951EC6FDE211CDD73CA3DEE3386EB8E9F
-:10AA3000A0BEA6FE20CA39DD67B0E1833B689F8FC8
-:10AA4000FF32872A7C48EF5FB1DCBF8101C8DC8B15
-:10AA500028F79E9CBDFE8B43DF233933C0EE39249B
-:10AA6000EECF7A70343491A4FB0FFE52815C78BB38
-:10AA700050BA82757E7EC8983A75F8542447DDD066
-:10AA80001275C3FEF11F71DF59075085FD477D56D2
-:10AA900080F8E0D11DF259EB868FEE387BDD706CCB
-:10AAA000BF0C7E7DE61C97C224E7592984A73AE0B3
-:10AAB000000D617B4357EC962EF623455DD168A0CF
-:10AAC0009C03F5F539E43F1FB5ADAD3C1E2962BBD3
-:10AAD0001F55C75364D7A3542F37E8FD82C3754F62
-:10AAE000CACFD2FB85ECFBF7FB269BF87E3885EAC4
-:10AAF00095D9F54929F86351DF5F20EA905E7D72B0
-:10AB0000993679F07EC2D34D01C643FF73D7BC435B
-:10AB1000F52FAF8E1F75EBC0FA36D077887BDCDB64
-:10AB20004571D00BA21E0AD7E03D96D3269395ED32
-:10AB30004BB9BEB983EE71AEF39F6FDD709DABDF95
-:10AB400090B9C7489E7FEDE2D39BF74D92C75AF26A
-:10AB50001345DE1A0A34D6F34D4F0541217F39A43F
-:10AB60001D2439D90293AB499EFAC3C26F4BECF353
-:10AB7000B1DF36DA65F03EC59AC5EF178ABF966732
-:10AB8000EE403089C37A01E591AEE9B446BBF81CCA
-:10AB9000C9AE0E3AC790C2FAEEFDAAD5FC8EA94DF9
-:10ABA0002A64795475AB3C5D5F1EEACAFD1E695587
-:10ABB000F95407EF1F9281E2AD449EF9B241F8FECD
-:10ABC00089CA70DB40BC5782ADBA3484F7EC0F1EE3
-:10ABD00067FAACAAF22F27FD74C8B5AF8950EEB85A
-:10ABE000EE59171FFFD01EFB21D1E17A986A26FD8E
-:10ABF00086A26D3AFCAE45C46B87485F8A78F75EE3
-:10AC0000B96E26AFF5922F7688EE6B7D5FF813FE56
-:10AC1000A8F0EB3152E37CD007EDD67304771DF139
-:10AC2000790D2B2A7872790E3977CF714797F51FF6
-:10AC300004EF98BBDF32DDE2BAEB3290CDFE485A2A
-:10AC40005DDD38BFBABAA4FF58D4D3AF157C0C2F42
-:10AC500038820F9B40277942FE3B46E7F3DE972C74
-:10AC60007B7E5B05D75D2EB0BE9DDF61BD4DF04E96
-:10AC7000D9F6BBD4BEBFBD0718DE79BED758551E66
-:10AC80008FDA48A7C13CE1373FDD686EB0D3F23FB1
-:10AC900073D60B7B3267BD88C717233B4D88776F10
-:10ACA0006CC72F87FA00D12B1BFE401F8C531D68E9
-:10ACB000B6FDB55D7705284FDC5FD614A0F768892F
-:10ACC000605321F507CBAC28ED3FD0D7FADC4755D0
-:10ACD000C44782EF9DF9221F9144FDECA4E5494F42
-:10ACE00075297CAEE63248513EDD1F147E911FE38C
-:10ACF000456329F9CDF56CCFF1FB38A50EFCEB0DC2
-:10AD0000116F5B265841728340227CA18E3CBD9E10
-:10AD10004C5E73591CE85CB3C1515A703DC5A365C4
-:10AD20003AFB2157AED7196ED89267E278387F7C0C
-:10AD3000ED3B07BE8ACE812F6F9E2777D978AA5C1C
-:10AD4000AFF0F95E0CDFC3F7824F9A59CEFCA8F042
-:10AD5000A89E5FBD5EE8192568412CC4E1BF44F898
-:10AD600049D0039B2533F8455F91F1ABE8715EE76D
-:10AD70002F3321B694F0A14B848FECFB2F7BFEBBCD
-:10AD80002D84B757B608BDBA4A75F5471CEF82FC4B
-:10AD9000B9D3D56FE0DAA5B63C6177D6C1CF8222B0
-:10ADA000AF2DF87419BAE381A233F5ABD73EEDE6C7
-:10ADB00095B3BFFF6E7D9EF0878C71D6EFFDAD021F
-:10ADC0007E2824FCD083432BD87F58535A35275DE7
-:10ADD0003F5EEC3A61765DF05C75C019BEB10274FD
-:10ADE000CE3FEA7739EDC6ECFC713FF18F8FE42658
-:10ADF000C0ED19E3E576D424B99A6F398074DB1974
-:10AE00008E47897F060E6F7F87EA24EAEB8A49FE28
-:10AE1000A6AADA40F3D614C7593ED696594075A56E
-:10AE2000FBFBAC1FA6C31D6E8F6D5B4FEF84F471EF
-:10AE30008BE00421E5903DBA7EAE15B773D0E16E8C
-:10AE4000577F7CD06E7F693DF2E12AD29D2B007E38
-:10AE5000695B7752FF7CF5D599F2D41A20BD7FE16A
-:10AE6000F2D411A0FB0D96D9FC4E6BF0670A79580D
-:10AE7000A7E70DBAF23438FF1E88A5C9D5EEF559FB
-:10AE80007A27E2EA9D88C57231E2EA1955B7593E40
-:10AE90007C244F4BD2F44CC4D33316CBA31AF1E429
-:10AEA000C9953F92A720BD0F9E6A263F6500C43B0F
-:10AEB000C66CF9FA7E7BEC61A2C355C5FFD7596118
-:10AEC000CCBCFF340C214F83652EBFCF7F96F9FF9A
-:10AED00024F23F3D16EE0F5666F0BBD7AE9C5620CF
-:10AEE00085A4B86E5AE2F6B3D3F9DCAE9ACEE3D6B7
-:10AEF0009A9ECB6DE37498DBA6E94BB96D9E2EE567
-:10AF0000B6651AF9FE6AE4FFE90A6ED74C2FE676B9
-:10AF1000EDF4226E5BA7AFE6796DD3CBB9BD7EFAB7
-:10AF20005A6E6F986E10FB504DA82827FF5339EBCF
-:10AF300022F0BFE9507D74E0F0EDEF107E7CBAC6E0
-:10AF4000799444B88EEB3D3E35CEFC7FB04CE8F7AB
-:10AF5000B541419F6CFEFFA03DF632F16D36FF8397
-:10AF60004FBCDB52E9DD560DFB396F327F9FE1EFBD
-:10AF7000BEF417CA83A2FF718CE877A1F6FFB45F15
-:10AF80005992E9570E1667FA9503F33DBFD23F4633
-:10AF900075B0AD92C1EFC4F23B621FF2FE606FA1CB
-:10AFA000F1585740277F2A115E130D627FF34E053B
-:10AFB00028DF87FEC56F781EEA07B21BE72BAFBFFD
-:10AFC000B4851C78F397C17139FE29FC93F7E99F8A
-:10AFD0000D67CAFD6CEB3CB9BF1CAAF372D9D9222C
-:10AFE0005FB3907B5DC87DA2CC1EA27C4B224BEE52
-:10AFF0003D3B8A78C890FBFC6E57EE5D392E8A88FF
-:10B00000771F4524F7C857E16EC3ADFF64DA51D509
-:10B010009DEF6B15F5ADE688D0AB6AABD017AA9E55
-:10B020006947916F8ABB73F8138E2AFCE3B6AA7F37
-:10B030003B6DCFC8AE1645C252216EADFF69D2A19D
-:10B040003CD6617501CB77B61C25F415CCE787D5C6
-:10B0500066C825FFE72D4761CF8E586C47B2E77968
-:10B06000F23470B88DF1E2D995C3786F2BCD9EACD8
-:10B07000D5051ED09EACE8CE614F56955B313BC7DF
-:10B08000399BBA855FFADA75B6F017D14F243F25A0
-:10B09000E1CBED0734750BFFA7A8D5FD7D8501F148
-:10B0A000B9A8075B5B53CD54C340796EA2FDAFB323
-:10B0B00026FB4906FB8323113A3FCA6733D1E1429D
-:10B0C000E5B3BA5DF885D03B97FD16AF3D17DF7B42
-:10B0D000FE8EC7FFD9F39EAEB036E4C2CB0FBA45A1
-:10B0E0005C7370E8D90CFED8A32EB8DE3472EA5532
-:10B0F000CBBC287AF5FCFC8AC368E758AFCEEE5784
-:10B100007C25171FCCE6577CAD5BC49BE8576C27AA
-:10B110003AAD5A22FC8A1F74C3C5F5171AEE627C39
-:10B120005DA8BF30D27D767FE140B7E72FC4596F6D
-:10B13000F85DBDF169FD851CFEC1A3CCBF30A550F3
-:10B14000FD0F516D8A7C88D023A8670ED238C6F1D6
-:10B15000EC2F1C0C0A7EB15C3D734797FD04D16354
-:10B160004FBDF0172E961CA0DFF734C13D5F793834
-:10B17000DF79554FAC1C9A243F0742497A37DD4F9F
-:10B18000EF95287E7C2F24DE11E05128EFFF4FCA77
-:10B190009526D9B9D1FC6F3C46F37B1D15E8DDE05F
-:10B1A000FE3E917FDEEDE6FFF6FBE2FF328970EEB8
-:10B1B000DFE1D70FE2F89FE7143832F2D49FF3CAE9
-:10B1C000C7E85DD031570FF96153612EBE9A399FA0
-:10B1D000789F4B4F574EF1EF3ACA74CE93BBF88924
-:10B1E000683638087FE77C99EB233BDBBF7880E447
-:10B1F000C76917792E2EB4E278645E54E43BD08D93
-:10B20000A94FCB8B28A09EA07CFC10BD514FABBF9B
-:10B2100016DB1847A7C51921D3CEE81B100307F783
-:10B22000D91B91393F3FB852C44583C17840CFA163
-:10B230005F76F565BE53CA6E95454F24E92DF183BF
-:10B2400051D5A4F4E870754D1BE53113BA78B4A458
-:10B2500085653B571D3BDC23B9F97893EDB6FAB908
-:10B260008EC25C76C56B87FA449ED6EB07168E5B62
-:10B27000C49F5A8565F3EF75C211C949CB2FFFDE14
-:10B28000D5133B2533B50A91B63324EC44C0485A54
-:10B29000329E77A0F836AE47060C074ED0F78549A8
-:10B2A000F810DB488916CB5977EF11F1CC4E5F8C43
-:10B2B000F7DB59AA729D726745EEBCD75F5DBDACE6
-:10B2C000859B6CCEFF8755AE2767CF9B72F949D31C
-:10B2D000ACA8CEF1F76D06DD2B311F389739D57349
-:10B2E000E7533B82C49F36E747F6BB79126DDE36E3
-:10B2F000C6FBEE7255A73CDC6A65DD0EDAE7415409
-:10B30000BBE49F64F3817F7E4D1ED73FD7C9FC66A7
-:10B31000339B2FE8EDDB04F9696A8AFD251FBCC366
-:10B32000798BDD3547B86FC084DB17FCE2D59B22F3
-:10B330002E3F9E61275C7A2549AE72F0CFFDE51362
-:10B340006CBF1F6898D840759B602460B6E23DF6DC
-:10B350002DB739BFBDBB5666BF35DFFD3DCE83EB94
-:10B360008AC28497DDB547582F679FC777E415F6E3
-:10B370003B826A8AF317C1B28F389E7DC83DC7DA17
-:10B380007A214F05A6D0C3055D71D071DFE2B79475
-:10B390003103FBD2BC971D1FD50F6E126F8B352D5D
-:10B3A000C57E467EFD1A89CEF766A90212C1505E9F
-:10B3B000E0F7BA600BF9F6DE6597746919F17D184C
-:10B3C000D2FA15E27704E9EFA840D978D6F766BD3E
-:10B3D000EFDD7EEC681ABC9E1EF75DAF5B673BD766
-:10B3E000FA3FF76D3B761495FF83356797ABBDAE9B
-:10B3F000DEDBD357CF74F2F8CBE3B7085D71C5EC51
-:10B40000EBF787C773FA25A33D82AFCFA58F0AFC60
-:10B41000E36CE7F75E379E9187FCBAAB1FBEDE2375
-:10B42000E4482F9FE2BCE55EF79DD3DE3CD8F06C8C
-:10B430008E7B3DD6A309793ACDCF9E1FF0CE85F9FC
-:10B4400001F3BB44FC105991477E00E2F3657AE7B3
-:10B45000F6A78866409A3C0F8432FD50CF0FF86DF6
-:10B460008FF0035E2CFE98ED786130C5763C6866FF
-:10B47000E609B2EDB8E68B715CA9956A9E9EE17A09
-:10B4800057F0ED6F3CE5903E48EDE2FA513EF26F29
-:10B490009E488D3BB9E8044B32DFDD7CB107F83CB8
-:10B4A00011233ED148F6A54BE57AC87EF9BD431F6E
-:10B4B00012BA9271B05DB8C3CCB7BB27F8FD8ECB82
-:10B4C000F7E7A227FD7D52E7FE6E85DE715CFB6625
-:10B4D0007DAEB8C36BE97D55E67BF84F2717CF7B70
-:10B4E00072910779422ED6C903E40FAC93F9DD0AB5
-:10B4F0003DEF55EBDC9423D5FDE964746F7A1F248E
-:10B50000B9F5A40533F2029F17EF5E4E6E13EF6894
-:10B51000F877860BE877A193FCFBC1CBE895AB32BB
-:10B52000A3DF4E42994CF562E788249DF6932EA541
-:10B53000278FA64CEB1682CD6DF6B92F87387FAFDB
-:10B540008624B757C238B74B6082DB6530C5AD057E
-:10B55000426F994745DD6305980A7DAF019BDB3A51
-:10B5600088735B0F496EBF79ED97FE70332EF9AF8C
-:10B570001EB72E7F1A2F02AF39E43B458FFEBDFB6D
-:10B580007B787EB0C760B93B17BD07C242DF369BF0
-:10B5900013ECDF878236EB615F44F0B707C7374BA8
-:10B5A000BEF8EFF5A3B27F67F2FF2B2134C6D03F80
-:10B5B0000000000000000000000000180000000073
-:10B5C000000000000000004000000000000000003B
-:10B5D0000000002800000000000000000000001033
-:10B5E000000000000000000000000020000000003B
-:10B5F000000000000000001000000000000000003B
-:10B600000000000800000000000000000000000032
-:10B6100000000000000000000000003900000000F1
-:10B6200000000000000000380000000000000000E2
-:10B630000000000000000000000000000000000802
-:10B6400000000000000000000000000000000000FA
-:10B65000000000000000000C0000000000000000DE
-:10B660000000000E000000000000000000000004C8
-:10B6700000000000000000000000001800000000B2
-:10B68000000000000000001C00000000000000009E
-:10B690000000001C0000000000000000000000137B
-:10B6A00000000000000000000000003A0000000060
-:10B6B0000000000000000001000000000000000089
-:10B6C0000000000200000000000000000000000177
-:10B6D000000000000000000000000010000000005A
-:10B6E000000000000000005000000000000000000A
-:10B6F0000000000000000000000000000000000347
-:10B700000000000000000000000000AB000000008E
-:10B710000000000000000008000000000000000021
-:10B720000000C00000100000000000080000C00879
-:10B7300000100000000000020000C0000010000027
-:10B740000000001000009FB0000000000000000892
-:10B750000000C08000100000000000040000C0884D
-:10B7600000100000000000020000C0800010000077
-:10B770000000001000009120000000000000000800
-:10B780000000934000010004000000010000934805
-:10B7900000000000000000020000935000000000C4
-:10B7A00000000008000093540000000000000002A8
-:10B7B00000009418000000000000000800009358EA
-:10B7C000000800000000000800009AB000400000DF
-:10B7D00000000040000093980008000000000008EE
-:10B7E000000093D80008000000000008000094202A
-:10B7F00000C8000000000098000095B0009800000C
-:10B8000000000028000095F00098000000000028CB
-:10B810000000C480054000300000054000009D206D
-:10B82000000800000000000100009D210008000049
-:10B8300000000001000020080010000000000010BF
-:10B8400000002000000000000000000800009CD85C
-:10B85000000800000000000200009D180000000029
-:10B8600000000001000000010000000000000000D6
-:10B8700000000009000000000000000000000002BD
-:10B8800000000000000000000000CF2000000000C9
-:10B89000000000200000CF46000000000000000172
-:10B8A0000000600000200000000000200000730085
-:10B8B000000800000000000800009FA00000000039
-:10B8C0000000000100009FA800000000000000012F
-:10B8D00000009F60000000000000001000009F6357
-:10B8E000000000000000000100009F610000000057
-:10B8F0000000000100009F66000000000000000141
-:10B9000000009F67000000000000000000009F682A
-:10B91000000000000000000400009F6C0000000018
-:10B9200000000004000000520000000000000000C1
-:10B930000000000300000000000000000000000301
-:10B9400000000000000000000000000500000000F2
-:10B9500000000000000000020000000000000000E5
-:10B9600000060000000000000000002000009F70A2
-:10B97000000000000000000100009F900000000097
-:10B98000000000080000005300000000000000005C
-:10B9900000009F98000000000000000200009F9C33
-:10B9A000000000000000000100009F9D000000005A
-:10B9B000000000010000000900000000000000007D
-:10B9C0000000000100000000000000000000004432
-:10B9D0000000000000000000000000010000000066
-:10B9E0000000000000000050000000000000000007
-:10B9F000000000890000000000000000000012C8E4
-:10BA00000080000000000080000000010000000035
-:10BA1000000000000000A000071000000000071058
-:10BA200000001AC800000000000000080000AEC0BE
-:10BA300000080000000000080000AE400008000000
-:10BA4000000000080000AE800008000000000008B0
-:10BA5000000020080010000000000010000020007E
-:10BA600000000000000000080000A01007100040C7
-:10BA70000000004000001BF800080000000000016A
-:10BA800000001BF9000800000000000100001AD0AF
-:10BA9000000000000000000100001AD800000000B3
-:10BAA0000000000200001ADA00000000000000029E
-:10BAB0008000000000000000000000000000AF0057
-:10BAC000000000000000002000001B78002800009B
-:10BAD000000000040000E000002000000000002042
-:10BAE0000000F300000800000000000800001AF049
-:10BAF000000000000000010800001B3700000000EB
-:10BB00000000000100001B0F000000000000000109
-:10BB100000001B70000000000000000400001B7407
-:10BB200000000000000000040000005000000000C1
-:10BB30000000000000000003000000000000000002
-:10BB400000000005000000000000000000000006EA
-:10BB500000000000000000000000000700000000DE
-:10BB60000000000000001BC80000000000000001F1
-:10BB700000001BE800000000000000080000005169
-:10BB8000000000000000000000001BD000000000CA
-:10BB90000000000400001BD40000000000000004AE
-:10BBA00000001BD8000000000000000400001BDCA7
-:10BBB00000000000000000080000B00000180000B5
-:10BBC000000000180000C00000400000000000401D
-:10BBD0000000C00000400002000000010000C001A1
-:10BBE00000400002000000000000E2000020000011
-:10BBF000000000200000E204000200080020000213
-:10BC00008000000000000000000000000000E200D2
-:10BC100000080020000000040000F40000280000DC
-:10BC2000000000280000F540001000000000001097
-:10BC30000000F5C000200000000000200000F5C05A
-:10BC400000020020000000020000F30000200000BD
-:10BC5000000000200000200800100000000000107C
-:10BC60000000200000000000000000080000110893
-:10BC70000008000000000008000011680008000033
-:10BC800000000008000011A80008000000000008E3
-:10BC900000001240000800000000000100001241F6
-:10BCA0000008000000000001000040000020000427
-:10BCB00000000010000059000030001800000010C3
-:10BCC0000000590800300018000000020000570072
-:10BCD00000080000000000010000570100080000FB
-:10BCE00000000001000011E8000000000000000159
-:10BCF000000011F00000000000000001000011F839
-:10BD000000000000000000100000124400080000C5
-:10BD1000000000040000400000200000000000209F
-:10BD20000000530000100000000000100000153853
-:10BD300000000000000000010000000300000000FF
-:10BD400000000000000000000000000000000000F3
-:10BD500000000001000000000000000000000004DE
-:10BD600000000000000000000000150800000000B6
-:10BD7000000000010000152800000000000000087D
-:10BD800000000050000000000000000000008308D8
-:10BD900000800000000000800000000100000000A2
-:10BDA000000000000000200800100000000000104B
-:10BDB00000002000000000000000000800008410C7
-:10BDC0000008000000000008000084700008000067
-:10BDD0000000000800060000046000280000046065
-:10BDE00000008520000800000000000100008521FF
-:10BDF00000080000000000018000000000000000BA
-:10BE000000000000000084080000000000000001A5
-:10BE1000000084F40008000000000002000084F626
-:10BE2000000800000000000200008504001000006F
-:10BE300000000004000087600000000000000020F7
-:10BE400000006000002000000000002000007300DF
-:10BE500000080000000000080000000300000000CF
-:10BE600000000000000000050000000000000000CD
-:10BE700000000006000000000000000000000007B5
-:10BE80000000000000000000000088080000000022
-:10BE900000000001000088280000000000000008E9
-:10BEA00000000050000000000000000000008810AA
-:10BEB00000000000000000040000881400000000E2
-:10BEC00000000004000088180000000000000004CA
-:10BED0000000881C00000000000000080000300086
-:10BEE0000040000000000008000030080040000092
-:10BEF000000000280000339001C00010000000087E
-:10BF00000000320000200000000000200000372068
-:10BF1000000000000000000800001020062000388B
-:10BF2000000000080000A000000000000000200049
-:10BF300000003EA9000000000000000100003EC813
-:10BF4000000000000000000280000000000000006F
-:10BF50000000000000006000002000000000000859
-:10BF60000000400000080000000000010000400147
-:10BF7000000800000000000100004040000800042C
-:10BF800000000002000040600008000400000004FF
-:10BF90000000400000080000000000040000400411
-:10BFA0000008000000000004000040400000000005
-:10BFB00000000008000040480000000000000008E9
-:10BFC0000000800000000000000000100000504051
-:10BFD000000100040000000100005000000000000B
-:10BFE00000000020000050080010000000000004C5
-:10BFF0000000500C0010000000000001000052C7BB
-:10C000000000000000000001000052C60000000017
-:10C0100000000001000030000030001800000004A3
-:10C020000000300400300018000000040000300858
-:10C0300000300018000000020000300A0030001834
-:10C04000000000020000300C003000180000000169
-:10C050000000300D00300018000000010000300E1C
-:10C0600000300018000000010000301000300018FF
-:10C07000000000040000301400300018000000042C
-:10C08000000050000100008000080004000050047F
-:10C0900001000080000800040000000A0000000009
-:10C0A0000000000000005068010000800000000156
-:10C0B0000000506901000080000000010000506C89
-:10C0C00001000080000000020000506E01000080AE
-:10C0D0000000000200005070010000800000000419
-:10C0E0000000507401000080000000040000506651
-:10C0F0000100008000000002000050640100008088
-:10C1000000000001000050600100008000000002FB
-:10C11000000050620100008000000002000050504A
-:10C120000100008000000004000050540100008065
-:10C1300000000004000050580100008000000004CE
-:10C140000000505C01000080000000040000507CF2
-:10C1500001000080000000010000507D010000800F
-:10C160000000000100004018001000000000000462
-:10C170000000409000100000000000040000409803
-:10C18000001000000000000400004110000000004A
-:10C190000000000200004112000000000000000248
-:10C1A00000004114000000000000000200004116E1
-:10C1B00000000000000000020000604000080000D5
-:10C1C00000000002000060420008000000000002C1
-:10C1D00000006044000800000000000400006080CF
-:10C1E0000008000000000008000060C000400008D7
-:10C1F00000000008000060000008000000000002CD
-:10C20000000060020008000000000001000060045F
-:10C210000008000000000002000063400008000069
-:10C220000000000800006380000800000000000417
-:10C23000000063840008000000000001000063C0EB
-:10C240000008000000000002000063C400080000B5
-:10C25000000000020000640000080000000000046C
-:10C2600000007000001000000000000400007004D6
-:10C270000010000000000004000070080010000022
-:10C280000000000400009000000800000000000210
-:10C29000000090020008000000000001000090046F
-:10C2A00000080000000000020000904000080000AC
-:10C2B000000000020000904400080000000000029E
-:10C2C00000009046000800000000000200009648B0
-:10C2D0000008000000000008000090800008000036
-:10C2E000000000020000908400080000000000022E
-:10C2F0000000968800080000000000080000804050
-:10C30000000800000000000100008041000800005B
-:10C310000000000100008042000800000000000151
-:10C3200000008043000800000000000100008000C1
-:10C330000008000000000002000080020008000069
-:10C34000000000010000800400080000000000025E
-:10C35000000080C00008000000000002000080C251
-:10C360000008000000000002000080C40008000077
-:10C3700000000002000080800008000000000001B2
-:10C3800000008081000800000000000100008082A1
-:10C390000008000000000001000080830008000089
-:10C3A000000000010000808400080000000000017F
-:10C3B0000000808500080000000000010000808669
-:10C3C00000080000000000010000600000080000FC
-:10C3D00000000002000060020008000000000001F0
-:10C3E000000060040008000000000002000060423D
-:10C3F00000C00018000000020000604000C00018EB
-:10C40000000000020000604C00C00018000000089E
-:10C410000000604400C000180000000800006057E1
-:10C4200000C00018000000010000605400C00018A7
-:10C43000000000020000605600C00018000000016B
-:10C440000000664000080000000000080000668050
-:10C450000008000000000008000066C0000800009E
-:10C46000000000080000DA4200180000000000028E
-:10C470000000DE4000000000000000000000E000BE
-:10C4800000000000000000040000D0C00000000018
-:10C49000000000040000D0C4000000000000000400
-:10C4A0000000D0C800000000000000040000D0CC54
-:10C4B00000000000000000040000D0D000000000D8
-:10C4C000000000040000D0D40000000000000004C0
-:10C4D0000000D0D800000000000000040000D0C020
-:10C4E00000000000000000200000DB000000000051
-:10C4F000000000040000DB000000000000000068F5
-:10C500000000B94800000000000000000000D0005A
-:10C5100000000000000000040000B0C000000000A7
-:10C52000000000040000B0C400000000000000048F
-:10C530000000B0C800000000000000040000B0C00F
-:10C5400000000000000000100000D6B00000000055
-:10C55000000000040000D6B4000000000000000449
-:10C560000000D6B800000000000000040000D6BCA7
-:10C5700000000000000000040000D6B00000000031
-:10C58000000000100000D348000000000000000878
-:10C590000000D358000000000000008000000010E0
-:10C5A00000000000000000000000D3580000000060
-:10C5B0000000000800000000060205000000000066
-:00000001FF
diff --git a/firmware/bnx2x/bnx2x-e2-6.2.9.0.fw.ihex b/firmware/bnx2x/bnx2x-e2-6.2.9.0.fw.ihex
new file mode 100644
index 00000000000..8405e719e7f
--- /dev/null
+++ b/firmware/bnx2x/bnx2x-e2-6.2.9.0.fw.ihex
@@ -0,0 +1,15473 @@
+:1000000000005310000000680000070C000053803F
+:100010000000318000005A90000000B000008C18F1
+:100020000000C13400008CD0000000D800014E0850
+:100030000000F26400014EE800000074000241502C
+:1000400000005250000241C8000000B40002942099
+:10005000000121EC000294D800000FFC0003B6C898
+:10006000000000040003C6C8020400480000000F9E
+:1000700002040054000000450204005C0000000679
+:100080000204007000000004020400780000000078
+:100090000204007C121700000204008022170000F6
+:1000A00002040084321700000604008800000005E6
+:1000B0000204009C12150000020400A0221500009A
+:1000C000020400A432150000060400A80000000489
+:1000D000020400B802100000020400BC001000007E
+:1000E000020400C010100000020400C42010000030
+:1000F000020400C830100000020400CC40100000D0
+:10010000060400D000000003020400DC0010000020
+:10011000020400E012140000020400E422140000B3
+:10012000020400E832140000020400EC4214000053
+:10013000060400F000000003010401240000000098
+:1001400001040128000000000104012C000000004F
+:100150000104013000000000020401D00000890603
+:1001600002040258000000360204025C000000365F
+:10017000020402600810000002040264081000007B
+:1001800002040004000000FF02040008000000FF59
+:100190000204000C000000FF02040010000000FF39
+:1001A000020400140000007F02040018000000FF99
+:1001B0000204001C000000FF02040020000000FFF9
+:1001C000020400240000003E020400280000000099
+:1001D0000204002C0000003F020400300000003F39
+:1001E000020400340000003F020400380000003F19
+:1001F0000204003C0000003F020400400000003FF9
+:10020000020400440000003F020404CC000000018E
+:1002100002042008000002110204200C0000020069
+:10022000020420100000020402042014000002193D
+:100230000204201C0000FFFF020420200000FFFF3A
+:10024000020420240000FFFF020420280000FFFF1A
+:1002500002042038000000200604203C0000000FAB
+:1002600002042078000000210604207C0000000F1A
+:10027000020420B800000001060420BC0000000FAA
+:10028000020420F800000001060420FC0000003FEA
+:10029000020421F800000001060421FC0000000F08
+:1002A0000204223807FFFFFF0204223C0000007F07
+:1002B0000204224007FFFFFF020422440000003F27
+:1002C00001042248000000000104224C000000004C
+:1002D000010422500000000001042254000000002C
+:1002E00001042258000000000104225C000000000C
+:1002F00001042260000000000104226400000000EC
+:1003000001042268000000000104226C00000000CB
+:1003100001042270000000000104227400000000AB
+:1003200001042278000000000104227C000000008B
+:10033000020422C00000FFFF020422C40000FFFFED
+:10034000020422C80000FFFF020422CC0000FFFFCD
+:100350000C042000000003E80A0420000000000153
+:100360000B042000000000030605400000000D0003
+:100370000205004400000020020500480000003291
+:1003800002050090021500200205009402150020CD
+:1003900002050098000000300205009C08100000D3
+:1003A000020500A000000036020500A40000003095
+:1003B000020500A800000031020500B000000004A2
+:1003C000020500B400000005020500C000000000A6
+:1003D000020500C400000004020500D40000000172
+:1003E00002050114000000010205011C00000001CB
+:1003F00002050120000000020205020400000001C5
+:100400000205020C0000004002050210000000403E
+:100410000205021C00000020020502200000001C52
+:100420000205022400000020060502400000000A28
+:1004300004050280002000000205005000000007B3
+:1004400002050054000000070205005800000000EB
+:100450000205005C000000080205006000000001C9
+:100460000605006400000003020500D80000000635
+:100470000205000400000001020500080000000160
+:100480000205000C00000001020500100000000140
+:100490000205001400000001020500180000000120
+:1004A0000205001C00000001020500200000000100
+:1004B00002050024000000010205002800000001E0
+:1004C0000205002C000000010205003000000001C0
+:1004D00002050034000000010205003800000001A0
+:1004E0000205003C00000001020500400000000180
+:1004F000020500E00000000D020500E80000000019
+:10050000020500F000000000020500F800000000F5
+:10051000020500E40000002D020500EC00000020B0
+:10052000020500F400000020020500FC000000208D
+:10053000020500E00000001D020500E800000010B8
+:10054000020500F000000010020500F80000001095
+:10055000020500E40000003D020500EC0000003050
+:10056000020500F400000030020500FC000000302D
+:10057000020500E00000004D020500E80000004018
+:10058000020500F000000040020500F800000040F5
+:10059000020500E40000006D020500EC00000060B0
+:1005A000020500F400000060020500FC000000608D
+:1005B000020500E00000005D020500E800000050B8
+:1005C000020500F000000050020500F80000005095
+:1005D000020500E40000007D020500EC0000007050
+:1005E000020500F400000070020500FC000000702D
+:1005F0000406100002000020020600DC00000001DA
+:100600000406020000030220020600DC00000000D5
+:100610000718040000AD0000081807D800050223E1
+:10062000071C000029920000071C8000312A0A657F
+:10063000071D000034A216B0071D80002E7A23D9B2
+:10064000071E000003502F78081E07F03F02022506
+:10065000021800BC0000003001180000000000007B
+:10066000011800040000000001180008000000004C
+:100670000118000C0000000001180010000000002C
+:100680000118001400000000021800200000000102
+:1006900002180024000000020218002800000003D5
+:1006A0000218002C000000000218003000000004B6
+:1006B0000218003400000001021800380000000099
+:1006C0000218003C00000001021800400000000475
+:1006D0000218004400000000021800480000000159
+:1006E0000218004C00000003021800500000000037
+:1006F0000218005400000001021800580000000415
+:100700000218005C000000000218006000000001F8
+:1007100002180064000000030218006800000000D6
+:100720000218006C000000010218007000000004B4
+:100730000218007400000000021800780000000495
+:100740000218007C00000003061800800000000270
+:10075000021800A400007FFF021800A8000003FF99
+:1007600002180224000000000218023400000000F9
+:100770000218024C00000000021802E4000000FF12
+:100780000618100000000400021B8BC000000001CE
+:10079000021B800000000034021B80400000001893
+:1007A000021B80800000000C021B80C000000020A3
+:1007B0000C1B8300000864700A1B830000000157B3
+:1007C0000B1B83000000055F0A1B83400000000034
+:1007D0000C1B8340000002260B1B8340000000011D
+:1007E000021B838000086470021B83C00000022685
+:1007F000021B1480000000010A1B1480000000008E
+:10080000021B944000000001061B944800000002F7
+:10081000061A1000000002B3041A1ACC00010227C5
+:10082000061A1AD000000008061A2008000000C8A6
+:10083000061A200000000002041A1BF8009002288B
+:10084000061A371800000004061A371000000002CC
+:10085000061A500000000002061A500800000004AA
+:10086000061A501800000004061A50280000000460
+:10087000061A503800000004061A50480000000410
+:10088000061A505800000004061A506800000004C0
+:10089000061A507800000002041A52C0000202B882
+:1008A000061A405000000006041A4068000202BA0E
+:1008B000041A4040000402BC041A8000000102C077
+:1008C000061A800400000003041A8010000102C10F
+:1008D000061A801400000003041A8020000102C2DE
+:1008E000061A802400000003041A8030000102C3AD
+:1008F000061A803400000003041A8040000102C47C
+:10090000061A804400000003041A8050000102C54A
+:10091000061A805400000003041A8060000102C619
+:10092000061A806400000003041A8070000102C7E8
+:10093000061A807400000003041A8080000102C8B7
+:10094000061A808400000003041A8090000102C986
+:10095000061A809400000003041A80A0000102CA55
+:10096000061A80A400000003041A80B0000102CB24
+:10097000061A80B400000003041A80C0000102CCF3
+:10098000061A80C400000003041A80D0000102CDC2
+:10099000061A80D400000003041A80E0000102CE91
+:1009A000061A80E400000003041A80F0000102CF60
+:1009B000061A80F400000003041A8100000102D02E
+:1009C000061A810400000003041A8110000102D1FC
+:1009D000061A811400000003041A8120000102D2CB
+:1009E000061A812400000003041A8130000102D39A
+:1009F000061A813400000003041A8140000102D469
+:100A0000061A814400000003041A8150000102D537
+:100A1000061A815400000003041A8160000102D606
+:100A2000061A816400000003041A8170000102D7D5
+:100A3000061A817400000003041A8180000102D8A4
+:100A4000061A818400000003041A8190000102D973
+:100A5000061A819400000003041A81A0000102DA42
+:100A6000061A81A400000003041A81B0000102DB11
+:100A7000061A81B400000003041A81C0000102DCE0
+:100A8000061A81C400000003041A81D0000102DDAF
+:100A9000061A81D400000003041A81E0000102DE7E
+:100AA000061A81E400000003041A81F0000102DF4D
+:100AB000061A81F400000003041A8200000102E01B
+:100AC000061A820400000003041A8210000102E1E9
+:100AD000061A821400000003041A8220000102E2B8
+:100AE000061A822400000003041A8230000102E387
+:100AF000061A823400000003041A8240000102E456
+:100B0000061A824400000003041A8250000102E524
+:100B1000061A825400000003041A8260000102E6F3
+:100B2000061A826400000003041A8270000102E7C2
+:100B3000061A827400000003041A8280000102E891
+:100B4000061A828400000003041A8290000102E960
+:100B5000061A829400000003041A82A0000102EA2F
+:100B6000061A82A400000003041A82B0000102EBFE
+:100B7000061A82B400000003041A82C0000102ECCD
+:100B8000061A82C400000003041A82D0000102ED9C
+:100B9000061A82D400000003041A82E0000102EE6B
+:100BA000061A82E400000003041A82F0000102EF3A
+:100BB000061A82F400000003041A8300000102F008
+:100BC000061A830400000003041A8310000102F1D6
+:100BD000061A831400000003041A8320000102F2A5
+:100BE000061A832400000003041A8330000102F374
+:100BF000061A833400000003041A8340000102F443
+:100C0000061A834400000003041A8350000102F511
+:100C1000061A835400000003041A8360000102F6E0
+:100C2000061A836400000003041A8370000102F7AF
+:100C3000061A837400000003041A8380000102F87E
+:100C4000061A838400000003041A8390000102F94D
+:100C5000061A839400000003041A83A0000102FA1C
+:100C6000061A83A400000003041A83B0000102FBEB
+:100C7000061A83B400000003041A83C0000102FCBA
+:100C8000061A83C400000003041A83D0000102FD89
+:100C9000061A83D400000003041A83E0000102FE58
+:100CA000061A83E400000003041A83F0000102FF27
+:100CB000061A83F400000003041A840000010300F4
+:100CC000061A840400000003041A841000010301C2
+:100CD000061A841400000003041A84200001030291
+:100CE000061A842400000003041A84300001030360
+:100CF000061A843400000003041A8440000103042F
+:100D0000061A844400000003041A845000010305FD
+:100D1000061A845400000003041A846000010306CC
+:100D2000061A846400000003041A8470000103079B
+:100D3000061A847400000003041A8480000103086A
+:100D4000061A848400000003041A84900001030939
+:100D5000061A849400000003041A84A00001030A08
+:100D6000061A84A400000003041A84B00001030BD7
+:100D7000061A84B400000003041A84C00001030CA6
+:100D8000061A84C400000003041A84D00001030D75
+:100D9000061A84D400000003041A84E00001030E44
+:100DA000061A84E400000003041A84F00001030F13
+:100DB000061A84F400000003041A850000010310E1
+:100DC000061A850400000003041A851000010311AF
+:100DD000061A851400000003041A8520000103127E
+:100DE000061A852400000003041A8530000103134D
+:100DF000061A853400000003041A8540000103141C
+:100E0000061A854400000003041A855000010315EA
+:100E1000061A855400000003041A856000010316B9
+:100E2000061A856400000003041A85700001031788
+:100E3000061A857400000003041A85800001031857
+:100E4000061A858400000003041A85900001031926
+:100E5000061A859400000003041A85A00001031AF5
+:100E6000061A85A400000003041A85B00001031BC4
+:100E7000061A85B400000003041A85C00001031C93
+:100E8000061A85C400000003041A85D00001031D62
+:100E9000061A85D400000003041A85E00001031E31
+:100EA000061A85E400000003041A85F00001031F00
+:100EB000061A85F400000003041A860000010320CE
+:100EC000061A860400000003041A8610000103219C
+:100ED000061A861400000003041A8620000103226B
+:100EE000061A862400000003041A8630000103233A
+:100EF000061A863400000003041A86400001032409
+:100F0000061A864400000003041A865000010325D7
+:100F1000061A865400000003041A866000010326A6
+:100F2000061A866400000003041A86700001032775
+:100F3000061A867400000003041A86800001032844
+:100F4000061A868400000003041A86900001032913
+:100F5000061A869400000003041A86A00001032AE2
+:100F6000061A86A400000003041A86B00001032BB1
+:100F7000061A86B400000003041A86C00001032C80
+:100F8000061A86C400000003041A86D00001032D4F
+:100F9000061A86D400000003041A86E00001032E1E
+:100FA000061A86E400000003041A86F00001032FED
+:100FB000061A86F400000003041A870000010330BB
+:100FC000061A870400000003041A87100001033189
+:100FD000061A871400000003041A87200001033258
+:100FE000061A872400000003041A87300001033327
+:100FF000061A873400000003041A874000010334F6
+:10100000061A874400000003041A875000010335C4
+:10101000061A875400000003041A87600001033693
+:10102000061A876400000003041A87700001033762
+:10103000061A877400000003041A87800001033831
+:10104000061A878400000003041A87900001033900
+:10105000061A879400000003041A87A00001033ACF
+:10106000061A87A400000003041A87B00001033B9E
+:10107000061A87B400000003041A87C00001033C6D
+:10108000061A87C400000003041A87D00001033D3C
+:10109000061A87D400000003041A87E00001033E0B
+:1010A000061A87E400000003041A87F00001033FDA
+:1010B000061A87F400000003041A880000010340A8
+:1010C000061A880400000003041A88100001034176
+:1010D000061A881400000003041A88200001034245
+:1010E000061A882400000003041A88300001034314
+:1010F000061A883400000003041A884000010344E3
+:10110000061A884400000003041A885000010345B1
+:10111000061A885400000003041A88600001034680
+:10112000061A886400000003041A8870000103474F
+:10113000061A887400000003041A8880000103481E
+:10114000061A888400000003041A889000010349ED
+:10115000061A889400000003041A88A00001034ABC
+:10116000061A88A400000003041A88B00001034B8B
+:10117000061A88B400000003041A88C00001034C5A
+:10118000061A88C400000003041A88D00001034D29
+:10119000061A88D400000003041A88E00001034EF8
+:1011A000061A88E400000003041A88F00001034FC7
+:1011B000061A88F400000003041A89000001035095
+:1011C000061A890400000003041A89100001035163
+:1011D000061A891400000003041A89200001035232
+:1011E000061A892400000003041A89300001035301
+:1011F000061A893400000003041A894000010354D0
+:10120000061A894400000003041A8950000103559E
+:10121000061A895400000003041A8960000103566D
+:10122000061A896400000003041A8970000103573C
+:10123000061A897400000003041A8980000103580B
+:10124000061A898400000003041A899000010359DA
+:10125000061A899400000003041A89A00001035AA9
+:10126000061A89A400000003041A89B00001035B78
+:10127000061A89B400000003041A89C00001035C47
+:10128000061A89C400000003041A89D00001035D16
+:10129000061A89D400000003041A89E00001035EE5
+:1012A000061A89E400000003041A89F00001035FB4
+:1012B000061A89F400000003041A8A000001036082
+:1012C000061A8A0400000003041A8A100001036150
+:1012D000061A8A1400000003041A8A20000103621F
+:1012E000061A8A2400000003041A8A3000010363EE
+:1012F000061A8A3400000003041A8A4000010364BD
+:10130000061A8A4400000003041A8A50000103658B
+:10131000061A8A5400000003041A8A60000103665A
+:10132000061A8A6400000003041A8A700001036729
+:10133000061A8A7400000003041A8A8000010368F8
+:10134000061A8A8400000003041A8A9000010369C7
+:10135000061A8A9400000003041A8AA00001036A96
+:10136000061A8AA400000003041A8AB00001036B65
+:10137000061A8AB400000003041A8AC00001036C34
+:10138000061A8AC400000003041A8AD00001036D03
+:10139000061A8AD400000003041A8AE00001036ED2
+:1013A000061A8AE400000003041A8AF00001036FA1
+:1013B000061A8AF400000003041A8B00000103706F
+:1013C000061A8B0400000003041A8B10000103713D
+:1013D000061A8B1400000003041A8B20000103720C
+:1013E000061A8B2400000003041A8B3000010373DB
+:1013F000061A8B3400000003041A8B4000010374AA
+:10140000061A8B4400000003041A8B500001037578
+:10141000061A8B5400000003041A8B600001037647
+:10142000061A8B6400000003041A8B700001037716
+:10143000061A8B7400000003041A8B8000010378E5
+:10144000061A8B8400000003041A8B9000010379B4
+:10145000061A8B9400000003041A8BA00001037A83
+:10146000061A8BA400000003041A8BB00001037B52
+:10147000061A8BB400000003041A8BC00001037C21
+:10148000061A8BC400000003041A8BD00001037DF0
+:10149000061A8BD400000003041A8BE00001037EBF
+:1014A000061A8BE400000003041A8BF00001037F8E
+:1014B000061A8BF400000003041A8C00000103805C
+:1014C000061A8C0400000003041A8C10000103812A
+:1014D000061A8C1400000003041A8C2000010382F9
+:1014E000061A8C2400000003041A8C3000010383C8
+:1014F000061A8C3400000003041A8C400001038497
+:10150000061A8C4400000003041A8C500001038565
+:10151000061A8C5400000003041A8C600001038634
+:10152000061A8C6400000003041A8C700001038703
+:10153000061A8C7400000003041A8C8000010388D2
+:10154000061A8C8400000003041A8C9000010389A1
+:10155000061A8C9400000003041A8CA00001038A70
+:10156000061A8CA400000003041A8CB00001038B3F
+:10157000061A8CB400000003041A8CC00001038C0E
+:10158000061A8CC400000003041A8CD00001038DDD
+:10159000061A8CD400000003041A8CE00001038EAC
+:1015A000061A8CE400000003041A8CF00001038F7B
+:1015B000061A8CF400000003041A8D000001039049
+:1015C000061A8D0400000003041A8D100001039117
+:1015D000061A8D1400000003041A8D2000010392E6
+:1015E000061A8D2400000003041A8D3000010393B5
+:1015F000061A8D3400000003041A8D400001039484
+:10160000061A8D4400000003041A8D500001039552
+:10161000061A8D5400000003041A8D600001039621
+:10162000061A8D6400000003041A8D7000010397F0
+:10163000061A8D7400000003041A8D8000010398BF
+:10164000061A8D8400000003041A8D90000103998E
+:10165000061A8D9400000003041A8DA00001039A5D
+:10166000061A8DA400000003041A8DB00001039B2C
+:10167000061A8DB400000003041A8DC00001039CFB
+:10168000061A8DC400000003041A8DD00001039DCA
+:10169000061A8DD400000003041A8DE00001039E99
+:1016A000061A8DE400000003041A8DF00001039F68
+:1016B000061A8DF400000003041A8E00000103A036
+:1016C000061A8E0400000003041A8E10000103A104
+:1016D000061A8E1400000003041A8E20000103A2D3
+:1016E000061A8E2400000003041A8E30000103A3A2
+:1016F000061A8E3400000003041A8E40000103A471
+:10170000061A8E4400000003041A8E50000103A53F
+:10171000061A8E5400000003041A8E60000103A60E
+:10172000061A8E6400000003041A8E70000103A7DD
+:10173000061A8E7400000003041A8E80000103A8AC
+:10174000061A8E8400000003041A8E90000103A97B
+:10175000061A8E9400000003041A8EA0000103AA4A
+:10176000061A8EA400000003041A8EB0000103AB19
+:10177000061A8EB400000003041A8EC0000103ACE8
+:10178000061A8EC400000003041A8ED0000103ADB7
+:10179000061A8ED400000003041A8EE0000103AE86
+:1017A000061A8EE400000003041A8EF0000103AF55
+:1017B000061A8EF400000003041A8F00000103B023
+:1017C000061A8F0400000003041A8F10000103B1F1
+:1017D000061A8F1400000003041A8F20000103B2C0
+:1017E000061A8F2400000003041A8F30000103B38F
+:1017F000061A8F3400000003041A8F40000103B45E
+:10180000061A8F4400000003041A8F50000103B52C
+:10181000061A8F5400000003041A8F60000103B6FB
+:10182000061A8F6400000003041A8F70000103B7CA
+:10183000061A8F7400000003041A8F80000103B899
+:10184000061A8F8400000003041A8F90000103B968
+:10185000061A8F9400000003041A8FA0000103BA37
+:10186000061A8FA400000003041A8FB0000103BB06
+:10187000061A8FB400000003041A8FC0000103BCD5
+:10188000061A8FC400000003041A8FD0000103BDA4
+:10189000061A8FD400000003041A8FE0000103BE73
+:1018A000061A8FE400000007041A62C0002003BF7C
+:1018B000061A1AF000000042061AAF0000000008E5
+:1018C000061AE00000000540061AD0000000007271
+:1018D000061AD24800000010061AD6B000000020F8
+:1018E000061AD47000000090061AD46800000002A6
+:1018F000061AA000000001C4061A30000000001003
+:10190000061A308000000010061A31000000001096
+:10191000061A318000000010061A33000000001281
+:10192000061A339000000070061AD4580000000216
+:10193000061AD34800000002061AD35800000020FF
+:10194000061AA710000001C4061A3040000000105B
+:10195000061A30C000000010061A314000000010C6
+:10196000061A31C000000010061A334800000012A9
+:10197000061A355000000070061AD46000000002FC
+:10198000061AD35000000002061AD3D80000002027
+:10199000021AAE2000000000061A500000000002EB
+:1019A000061A508000000012041A4000000203DFF3
+:1019B000041A63C0000203E1061A7000000000046C
+:1019C000061A320000000008021AAE2400000000CF
+:1019D000061A501000000002061A50C8000000123B
+:1019E000041A4008000203E3041A63C8000203E576
+:1019F000061A701000000004061A322000000008C9
+:101A0000021AAE2800000000061A50200000000252
+:101A1000061A511000000012041A4010000203E7D9
+:101A2000041A63D0000203E9061A702000000004C3
+:101A3000061A324000000008021AAE2C0000000016
+:101A4000061A503000000002061A51580000001219
+:101A5000041A4018000203EB041A63D8000203EDD5
+:101A6000061A703000000004061A326000000008F8
+:101A7000021AAE3000000000061A504000000002BA
+:101A8000061A51A000000012041A4020000203EFC1
+:101A9000041A63E0000203F1061A7040000000041B
+:101AA000061A328000000008021AAE34000000005E
+:101AB000061A505000000002061A51E800000012F9
+:101AC000041A4028000203F3041A63E8000203F535
+:101AD000061A705000000004061A32A00000000828
+:101AE000021AAE3800000000061A50600000000222
+:101AF000061A523000000012041A4030000203F7A8
+:101B0000041A63F0000203F9061A70600000000472
+:101B1000061A32C000000008021AAE3C00000000A5
+:101B2000061A507000000002061A527800000012D7
+:101B3000041A4038000203FB041A63F8000203FD94
+:101B4000061A707000000004061A32E00000000857
+:101B50000200A2A4000002090200A270000000001E
+:101B60000200A274000000000200A2700000000049
+:101B70000200A274000000000200A2700000000039
+:101B80000200A274000000000200A2700000000029
+:101B90000200A27400000000020100B40000000175
+:101BA000020100B800000001020100CC00000001A9
+:101BB000020100D000000001020100DC0000000171
+:101BC0000201010000000001020101040000000107
+:101BD0000201007C003000000201008400000028A7
+:101BE0000201008C0000000002010130000000042E
+:101BF0000201025C00000001020103280000000055
+:101C0000020160580000FFFF020160700000000741
+:101C10000201055400000030020100C40000000170
+:101C2000020100F800000001020100F000000001C4
+:101C3000020100800030000002010088000000283E
+:101C400002010090000000000201013400000004C5
+:101C5000020102DC000000010201032C0000000070
+:101C60000201605C0000FFFF0201607400000007D9
+:101C70000201056400000030020100C800000001FC
+:101C8000020100FC00000001020100F4000000015C
+:101C9000020C100000000028020C200800000211B5
+:101CA000020C200C00000200020C201000000204B4
+:101CB000020C201C0000FFFF020C20200000FFFF90
+:101CC000020C20240000FFFF020C20280000FFFF70
+:101CD000020C203800000000020C203C00000037FD
+:101CE000020C204000000021020C204400000020D3
+:101CF000060C20480000001D020C20BC0000000162
+:101D0000060C20C00000003F020C21BC00000001B6
+:101D1000020C21C000000001020C21C400000001DF
+:101D2000060C21C80000001C020C223807FFFFFF30
+:101D3000020C223C0000007F020C224007FFFFFF44
+:101D4000020C22440000003F010C22480000000069
+:101D5000010C224C00000000010C22500000000089
+:101D6000010C225400000000010C22580000000069
+:101D7000010C225C00000000010C22600000000049
+:101D8000010C226400000000010C22680000000029
+:101D9000010C226C00000000010C22700000000009
+:101DA000010C227400000000010C227800000000E9
+:101DB000010C227C00000000020C22D80000FFFF72
+:101DC000020C22DC0000FFFF020C22E00000FFFFFB
+:101DD000020C22E40000FFFF0C0C2000000003E8CE
+:101DE0000A0C2000000000010B0C20000000000382
+:101DF000020C400800001011020C400C0000100002
+:101E0000020C401000001004020C401400001021CD
+:101E1000020C401C0000FFFF020C40200000FFFFEE
+:101E2000020C40240000FFFF020C40280000FFFFCE
+:101E3000020C403800000046020C403C0000000C40
+:101E4000060C404000000002020C40480000001850
+:101E5000020C404C000000F0060C40500000001F37
+:101E6000020C40CC00000001060C40D00000003AFB
+:101E7000020C41B800000001060C41BC0000000348
+:101E8000020C41C800000001020C41CC000000011E
+:101E9000060C41D00000001A020C423807FFFFFF79
+:101EA000020C423C0000007F020C424007FFFFFF93
+:101EB000020C42440000003F010C424800000000B8
+:101EC000010C424C00000000010C425000000000D8
+:101ED000010C425400000000010C425800000000B8
+:101EE000010C425C00000000010C42600000000098
+:101EF000010C426400000000010C42680000000078
+:101F0000010C426C00000000010C42700000000057
+:101F1000010C427400000000010C42780000000037
+:101F2000010C427C00000000010C42800000000017
+:101F3000020C42D80000FFFF020C42DC0000FFFF51
+:101F4000020C42E00000FFFF020C42E40000FFFF31
+:101F50000C0C4000000003E80A0C400000000001E7
+:101F60000B0C400000000003060D400000000A00BA
+:101F7000020D004400000032020D008C021500200A
+:101F8000020D009002150020020D009408100000C0
+:101F9000020D009800000036020D00A000000000B5
+:101FA000020D00A400000004020D00A800000004BF
+:101FB000060D00AC00000002020D00B80000000297
+:101FC000020D00C000000001020D00C80000000268
+:101FD000020D00CC00000002020D015C00000001B7
+:101FE000020D016400000001020D01680000000202
+:101FF000020D020400000001020D020C000000208E
+:10200000020D021000000040020D0214000000400A
+:10201000020D022000000003020D0224000000183F
+:10202000060D028000000012040D0300001803FFDB
+:10203000060D03600000000C020D004C00000001C2
+:10204000020D005000000002020D005400000000CC
+:10205000020D005800000008060D005C000000049E
+:10206000020D00C400000004020D00040000000185
+:10207000020D000800000001020D000C000000012C
+:10208000020D001000000001020D0014000000010C
+:10209000020D001800000001020D001C00000001EC
+:1020A000020D002000000001020D002400000001CC
+:1020B000020D002800000001020D002C00000001AC
+:1020C000020D003000000001020D0034000000018C
+:1020D000020D003800000001020D003C000000016C
+:1020E000020D011400000009020D011C0000000A8D
+:1020F000020D012400000000020D012C0000000070
+:10210000020D013400000000020D013C0000000B34
+:10211000020D014400000000020D0118000000291A
+:10212000020D01200000002A020D012800000020FD
+:10213000020D013000000020020D013800000020D7
+:10214000020D01400000002B020D0148000000209C
+:10215000020D011400000019020D011C0000001AFC
+:10216000020D012400000010020D012C00000010DF
+:10217000020D013400000010020D013C0000001BA4
+:10218000020D014400000010020D0118000000398A
+:10219000020D01200000003A020D0128000000306D
+:1021A000020D013000000030020D01380000003047
+:1021B000020D01400000003B020D0148000000300C
+:1021C000020D011400000049020D011C0000004A2C
+:1021D000020D012400000040020D012C000000400F
+:1021E000020D013400000040020D013C0000004BD4
+:1021F000020D014400000040020D011800000069BA
+:10220000020D01200000006A020D0128000000609C
+:10221000020D013000000060020D01380000006076
+:10222000020D01400000006B020D0148000000603B
+:10223000020D011400000059020D011C0000005A9B
+:10224000020D012400000050020D012C000000507E
+:10225000020D013400000050020D013C0000005B43
+:10226000020D014400000050020D01180000007929
+:10227000020D01200000007A020D0128000000700C
+:10228000020D013000000070020D013800000070E6
+:10229000020D01400000007B020D014800000070AB
+:1022A000060E200000000800020E004C0000003264
+:1022B000020E009402150020020E00980215002064
+:1022C000020E009C00000030020E00A0081000006A
+:1022D000020E00A400000036020E00A8000000302C
+:1022E000020E00AC00000031020E00B4000000033A
+:1022F000020E00B800000000020E00C40000000042
+:10230000020E00CC00000006020E00D80000000102
+:10231000020E014400000001020E014C0000000109
+:10232000020E015000000002020E02040000000133
+:10233000020E020C00000040020E021000000040DD
+:10234000020E021C00000004020E02200000002009
+:10235000020E02240000000E020E02280000001BE4
+:10236000060E030000000012040E0280001B04177A
+:10237000060E02EC00000005020E00540000000CE6
+:10238000020E00580000000C020E005C000000006D
+:10239000020E006000000010020E00640000001039
+:1023A000060E006800000003020E00DC00000003BF
+:1023B000020E000400000001020E000800000001EF
+:1023C000020E000C00000001020E001000000001CF
+:1023D000020E001400000001020E001800000001AF
+:1023E000020E001C00000001020E0020000000018F
+:1023F000020E002400000001020E0028000000016F
+:10240000020E002C00000001020E0030000000014E
+:10241000020E003400000001020E0038000000012E
+:10242000020E003C00000001020E0040000000010E
+:10243000020E004400000001020E01100000000F17
+:10244000020E011800000000020E01200000000032
+:10245000020E012800000000020E01140000002FEF
+:10246000020E011C00000020020E012400000020CA
+:10247000020E012C00000020020E01100000001FBF
+:10248000020E011800000010020E012000000010D2
+:10249000020E012800000010020E01140000003F8F
+:1024A000020E011C00000030020E0124000000306A
+:1024B000020E012C00000030020E01100000004F3F
+:1024C000020E011800000040020E01200000004032
+:1024D000020E012800000040020E01140000006FEF
+:1024E000020E011C00000060020E012400000060CA
+:1024F000020E012C00000060020E01100000005FBF
+:10250000020E011800000050020E012000000050D1
+:10251000020E012800000050020E01140000007F8E
+:10252000020E011C00000070020E01240000007069
+:10253000020E012C000000700730040000D60000DD
+:10254000083007D80005043207340000322B0000A1
+:1025500007348000314B0C8B0735000038C518DE7E
+:10256000073580002F90271007360000268F32F5A0
+:102570000836716031D40434023000BC00000030F1
+:1025800001300000000000000130000400000000E5
+:1025900001300008000000000130000C00000000C5
+:1025A00001300010000000000130001400000000A5
+:1025B0000230002000000001023000240000000270
+:1025C00002300028000000030230002C0000000050
+:1025D000023000300000000402300034000000012E
+:1025E00002300038000000000230003C0000000112
+:1025F00002300040000000040230004400000000EF
+:1026000002300048000000010230004C00000003CE
+:1026100002300050000000000230005400000001B1
+:1026200002300058000000040230005C000000008E
+:10263000023000600000000102300064000000036E
+:1026400002300068000000000230006C0000000151
+:10265000023000700000000402300074000000002E
+:1026600002300078000000040230007C000000030B
+:102670000630008000000002023000A400007FFF4E
+:10268000023000A8000003FF023002240000000016
+:1026900002300234000000000230024C0000000052
+:1026A000023002E40000FFFF0630200000000800B6
+:1026B00002338BC000000001023380000000001ACA
+:1026C000023380400000004E023380800000001082
+:1026D000023380C0000000200C33830000086470C7
+:1026E0000A338300000001570B3383000000055FAD
+:1026F0000A338340000000000C33834000000226B0
+:102700000B338340000000010233838000086470B3
+:10271000023383C00000022602331480000000014F
+:102720000A3314800000000006328000000001021D
+:1027300006322008000000C8063220000000000217
+:1027400004328520008F04360632875C00000009C1
+:1027500006323EB00000000606323ED00000000205
+:1027600006323E800000000A04323EA8000204C582
+:1027700006323E00000000200632500000000940F2
+:102780000632400000000004043294C0000204C776
+:1027900006324110000000020632D0000000007036
+:1027A0000632DB00000000D40632DEA0000000028A
+:1027B0000632E00000000800063324000000011883
+:1027C0000632100000000188063250000000002090
+:1027D00006325100000000200632520000000020A6
+:1027E0000632530000000020063254000000002092
+:1027F000063255000000002006325600000000207E
+:102800000632570000000020063258000000002069
+:10281000063259000000002006325A000000002055
+:1028200006325B000000002006325C000000002041
+:1028300006325D000000002006325E00000000202D
+:1028400006325F0000000020063284F00000000223
+:1028500004328500000204C9063285080000000227
+:102860000632DE90000000020633286000000118E6
+:102870000632162000000188063250800000002039
+:1028800006325180000000200632528000000020F5
+:1028900006325380000000200632548000000020E1
+:1028A00006325580000000200632568000000020CD
+:1028B00006325780000000200632588000000020B9
+:1028C000063259800000002006325A8000000020A5
+:1028D00006325B800000002006325C800000002091
+:1028E00006325D800000002006325E80000000207D
+:1028F00006325F8000000020063284F800000002EB
+:1029000004328510000204CB063285180000000254
+:102910000632DE98000000020232845000000000FF
+:102920000632401000000002023284540000000011
+:1029300006324020000000020232845800000000ED
+:1029400006324030000000020232845C00000000C9
+:1029500006324040000000020232846000000000A5
+:102960000632405000000002023284640000000081
+:10297000063240600000000202328468000000005D
+:1029800006324070000000020232846C0000000039
+:10299000063240800000000207200400007300009F
+:1029A00008200780001004CD072400002AE400005E
+:1029B0000724800027670ABA0824D35063FC04CF99
+:1029C000022000BC000000300120000000000000D8
+:1029D00001200004000000000120000800000000A9
+:1029E0000120000C00000000012000100000000089
+:1029F000012000140000000002200020000000015F
+:102A00000220002400000002022000280000000331
+:102A10000220002C00000000022000300000000412
+:102A200002200034000000010220003800000000F5
+:102A30000220003C000000010220004000000004D1
+:102A400002200044000000000220004800000001B5
+:102A50000220004C00000003022000500000000093
+:102A60000220005400000001022000580000000471
+:102A70000220005C00000000022000600000000155
+:102A80000220006400000003022000680000000033
+:102A90000220006C00000001022000700000000411
+:102AA00002200074000000000220007800000004F2
+:102AB0000220007C000000030620008000000002CD
+:102AC000022000A400007FFF022000A8000003FFF6
+:102AD0000220022400000000022002340000000056
+:102AE0000220024C00000000022002E40000FFFF70
+:102AF000062020000000080002238BC00000000117
+:102B00000223800000000010022380400000001219
+:102B10000223808000000030022380C00000000EED
+:102B20000C238300000864700A238300000001570F
+:102B30000B2383000000055F0A2383400000000090
+:102B40000C238340000002260B2383400000000179
+:102B50000223838000086470022383C000000226E1
+:102B600002231480000000010A23148000000000EA
+:102B7000062210000000004206222008000000C8C3
+:102B800006222000000000020622B00000000330F0
+:102B90000622F400000000530422F54C000104D189
+:102BA0000622F550000000030422F55C000104D267
+:102BB0000622F560000000030422F56C000104D336
+:102BC0000622F570000000030422F57C000104D405
+:102BD0000622F580000000030422F58C000104D5D4
+:102BE0000622F590000000030422F59C000104D6A3
+:102BF0000622F5A0000000030422F5AC000104D772
+:102C00000622F5B0000000030422F5BC000104D840
+:102C10000622F5C0000000460622E2000000044043
+:102C200004221240009004D906223000000000C0A7
+:102C30000622670000000100062290000000040048
+:102C400004226B0800200569062211F0000000062E
+:102C50000422120800060589062212200000000244
+:102C600006224000000005C00622C0000000000649
+:102C70000422C0180006058F0622C0300000000A9A
+:102C80000422C058000605950622C0700000000A04
+:102C90000422C0980006059B0622C0B00000000A6E
+:102CA0000422C0D8000605A10622C0F00000000AD8
+:102CB0000422C118000605A70622C1300000000A40
+:102CC0000422C158000605AD0622C1700000000AAA
+:102CD0000422C198000605B30622C1B00000000A14
+:102CE0000422C1D8000605B90622C1F00000000A7E
+:102CF0000422C218000605BF0622C2300000000AE6
+:102D00000422C258000605C50622C2700000000A4F
+:102D10000422C298000605CB0622C2B00000000AB9
+:102D20000422C2D8000605D10622C2F00000000A23
+:102D30000422C318000605D70622C3300000000A8B
+:102D40000422C358000605DD0622C3700000000AF5
+:102D50000422C398000605E30622C3B00000000A5F
+:102D60000422C3D8000605E90622C3F00000000AC9
+:102D70000422C418000605EF0622C4300000000A31
+:102D80000422C458000605F50622C4700000000A9B
+:102D90000422C498000605FB0622C4B00000000A05
+:102DA0000422C4D8000606010622C4F00000000A6E
+:102DB0000422C518000606070622C5300000000AD6
+:102DC0000422C5580006060D0622C5700000000A40
+:102DD0000422C598000606130622C5B00000000AAA
+:102DE0000422C5D8000606190622C5F00000000A14
+:102DF0000422C6180006061F0622C6300000000A7C
+:102E00000422C658000606250622C6700000000AE5
+:102E10000422C6980006062B0622C6B00000000A4F
+:102E20000422C6D8000606310622C6F00000000AB9
+:102E30000422C718000606370622C7300000000A21
+:102E40000422C7580006063D0622C7700000000A8B
+:102E50000422C798000606430622C7B00000000AF5
+:102E60000422C7D8000606490622C7F00000000A5F
+:102E70000422C8180006064F0622C8300000000AC7
+:102E80000422C858000606550622C8700000000A31
+:102E90000422C8980006065B0622C8B00000000A9B
+:102EA0000422C8D8000606610622C8F00000000A05
+:102EB0000422C918000606670622C9300000000A6D
+:102EC0000422C9580006066D0622C9700000000AD7
+:102ED0000422C998000606730622C9B00000000A41
+:102EE0000422C9D8000606790622C9F00000000AAB
+:102EF0000422CA180006067F0622CA300000000A13
+:102F00000422CA58000606850622CA700000000A7C
+:102F10000422CA980006068B0622CAB00000000AE6
+:102F20000422CAD8000606910622CAF00000000A50
+:102F30000422CB18000606970622CB300000000AB8
+:102F40000422CB580006069D0622CB700000000A22
+:102F50000422CB98000606A30622CBB00000000A8C
+:102F60000422CBD8000606A90622CBF00000000AF6
+:102F70000422CC18000606AF0622CC300000000A5E
+:102F80000422CC58000606B50622CC700000000AC8
+:102F90000422CC98000606BB0622CCB00000000A32
+:102FA0000422CCD8000606C10622CCF00000000A9C
+:102FB0000422CD18000606C70622CD300000000A04
+:102FC0000422CD58000606CD0622CD700000000A6E
+:102FD0000422CD98000606D30622CDB00000000AD8
+:102FE0000422CDD8000606D90622CDF00000000A42
+:102FF0000422CE18000606DF0622CE300000000AAA
+:103000000422CE58000606E50622CE700000000A13
+:103010000422CE98000606EB0622CEB00000000A7D
+:103020000422CED8000606F10622CEF00000000AE7
+:103030000422CF18000606F70622CF300000000A4F
+:103040000422CF58000606FD0622CF700000000AB9
+:103050000422CF98000607030622CFB00000000A22
+:103060000422CFD8000607090622CFF00000000A8C
+:103070000422D0180006070F0622D0300000000AF4
+:103080000422D058000607150622D0700000000A5E
+:103090000422D0980006071B0622D0B00000000AC8
+:1030A0000422D0D8000607210622D0F00000000A32
+:1030B0000422D118000607270622D1300000000A9A
+:1030C0000422D1580006072D0622D1700000000A04
+:1030D0000422D198000607330622D1B00000000A6E
+:1030E0000422D1D8000607390622D1F00000000AD8
+:1030F0000422D2180006073F0622D2300000000A40
+:103100000422D258000607450622D2700000000AA9
+:103110000422D2980006074B0622D2B00000000A13
+:103120000422D2D8000607510622D2F00000000A7D
+:103130000422D318000607570622D3300000000AE5
+:103140000422D3580006075D0622D3700000000A4F
+:103150000422D398000607630622D3B00000000AB9
+:103160000422D3D8000607690622D3F00000000A23
+:103170000422D4180006076F0622D4300000000A8B
+:103180000422D458000607750622D4700000000AF5
+:103190000422D4980006077B0622D4B00000000A5F
+:1031A0000422D4D8000607810622D4F00000000AC9
+:1031B0000422D518000607870622D5300000000A31
+:1031C0000422D5580006078D0622D5700000000A9B
+:1031D0000422D598000607930622D5B00000000A05
+:1031E0000422D5D8000607990622D5F00000000A6F
+:1031F0000422D6180006079F0622D6300000000AD7
+:103200000422D658000607A50622D6700000000A40
+:103210000422D698000607AB0622D6B00000000AAA
+:103220000422D6D8000607B10622D6F00000000A14
+:103230000422D718000607B70622D7300000000A7C
+:103240000422D758000607BD0622D7700000000AE6
+:103250000422D798000607C30622D7B00000000A50
+:103260000422D7D8000607C90622D7F00000000ABA
+:103270000422D818000607CF0622D8300000000A22
+:103280000422D858000607D50622D8700000000A8C
+:103290000422D898000607DB0622D8B00000000AF6
+:1032A0000422D8D8000607E10622D8F00000000A60
+:1032B0000422D918000607E70622D9300000000AC8
+:1032C0000422D958000607ED0622D9700000000A32
+:1032D0000422D998000607F30622D9B00000000A9C
+:1032E0000422D9D8000607F90622D9F00000000A06
+:1032F0000422DA18000607FF0622DA300000000A6E
+:103300000422DA58000608050622DA700000000AD6
+:103310000422DA980006080B0622DAB00000000A40
+:103320000422DAD8000608110622DAF00000000AAA
+:103330000422DB18000608170622DB300000000A12
+:103340000422DB580006081D0622DB700000000A7C
+:103350000422DB98000608230622DBB00000000AE6
+:103360000422DBD8000608290622DBF00000000A50
+:103370000422DC180006082F0622DC300000000AB8
+:103380000422DC58000608350622DC700000000A22
+:103390000422DC980006083B0622DCB00000000A8C
+:1033A0000422DCD8000608410622DCF00000000AF6
+:1033B0000422DD18000608470622DD300000000A5E
+:1033C0000422DD580006084D0622DD700000000AC8
+:1033D0000422DD98000608530622DDB00000000A32
+:1033E0000422DDD8000608590622DDF00000000A9C
+:1033F0000422DE180006085F0622DE300000000A04
+:103400000422DE58000608650622DE700000000A6D
+:103410000422DE980006086B0622DEB00000000AD7
+:103420000422DED8000608710622DEF00000000A41
+:103430000422DF18000608770622DF300000000AA9
+:103440000422DF580006087D0622DF700000000A13
+:103450000422DF98000608830622DFB00000000A7D
+:103460000422DFD8000608890622DFF00000000AE7
+:103470000422E0180006088F0622E0300000000A4F
+:103480000422E058000608950622E0700000000AB9
+:103490000422E0980006089B0622E0B00000000A23
+:1034A0000422E0D8000608A10622E0F00000000A8D
+:1034B0000422E118000608A70622E1300000000AF5
+:1034C0000422E158000608AD0622E1700000000A5F
+:1034D0000422E198000608B30622E1B00000000AC9
+:1034E0000422E1D8000608B90622E1F00000000439
+:1034F0000622153800000002062211E80000000232
+:103500000622F3000000000802221148000000001B
+:1035100006225900000000060622330000000002C7
+:1035200006226040000000300622F3200000000860
+:103530000222114C0000000006225918000000066B
+:10354000062233080000000206226100000000305D
+:103550000622F34000000008022211500000000083
+:103560000622593000000006062233100000000237
+:10357000062261C0000000300622F360000000084F
+:1035800002221154000000000622594800000006E3
+:10359000062233180000000206226280000000307C
+:1035A0000622F380000000080222115800000000EB
+:1035B00006225960000000060622332000000002A7
+:1035C00006226340000000300622F3A0000000083D
+:1035D0000222115C0000000006225978000000065B
+:1035E000062233280000000206226400000000309A
+:1035F0000622F3C000000008022211600000000053
+:103600000622599000000006062233300000000216
+:10361000062264C0000000300622F3E0000000082B
+:103620000222116400000000062259A800000006D2
+:1036300006223338000000020622658000000030B8
+:103640000216100000000028021700080000000207
+:103650000217002C000000030217003C00000004C9
+:10366000021700440000000002170048000000029A
+:103670000217004C0000009002170050000000905C
+:103680000217005400800090021700580810000034
+:10369000021700700000000602170078000009FF02
+:1036A0000217007C0000076C021701C4081000001C
+:1036B0000217034400000001021704000000008A02
+:1036C00002170404000000800217040800000081B3
+:1036D0000217040C00000080021704100000008A8A
+:1036E0000217041400000080021704180000008173
+:1036F0000217041C00000080021704300000008A3A
+:103700000217043400000080021704380000008112
+:103710000217043C00000080021704400000008AE9
+:1037200002170444000000800217044800000081D2
+:103730000217044C00000080021704800000008A79
+:103740000217048400000080021704880000008132
+:103750000217048C0000008002170038007C10045F
+:10376000021700040000000F021701EC0000000225
+:10377000021701F400000002021701EC0000000231
+:10378000021701F400000002021701EC0000000221
+:10379000021701F400000002021701EC0000000211
+:1037A000021701F400000002021701EC0000000201
+:1037B000021701F400000002021701EC00000002F1
+:1037C000021701F400000002021701EC00000002E1
+:1037D000021701F400000002021701EC00000002D1
+:1037E000021701F400000002061640240000000247
+:1037F000021640700000001C021642080000000182
+:1038000002164210000000010216422000000001D2
+:10381000021642280000000102164230000000019A
+:103820000216423800000001021642600000000249
+:103830000C16401C0003D0900A16401C0000009C8F
+:103840000B16401C000002710216403000000028D8
+:10385000021640340000002C0216403800000030F0
+:103860000216404400000020021640000000000143
+:10387000021640D8000000010216400800000001B6
+:103880000216400C0000000102164010000000016A
+:1038900002164240000000000216424800000000EC
+:1038A000061642700000000202164250000000009E
+:1038B0000216425800000000061642800000000276
+:1038C00002166008000012140216600C00001200BC
+:1038D00002166010000012040216601C0000FFFFB8
+:1038E000021660200000FFFF021660240000FFFFA8
+:1038F000021660280000FFFF02166038000000205A
+:103900000216603C00000010061660400000000235
+:1039100002166048000000230216604C00000024DC
+:1039200002166050000000250216605400000026B8
+:1039300002166058000000270216605C00000011AB
+:103940000216606000000000021660640000002B98
+:10395000021660680000002C0216606C0000002D4A
+:1039600002166070000000EC021660740000000097
+:1039700002166078000000290216607C0000002A10
+:10398000021660800000002F061660840000000D03
+:10399000021660B800000001061660BC00000008B6
+:1039A000021660DC00000001061660E00000000462
+:1039B000021660F000000001061660F4000000032B
+:1039C0000216610000000001061661040000002DCF
+:1039D000021661B800000001061661BC0000000874
+:1039E000021661DC00000001061661E00000000420
+:1039F000021661F000000001061661F400000003E9
+:103A00000216620000000001061662040000000DAC
+:103A10000216623807FFFFFF0216623C0000007FBB
+:103A20000216624007FFFFFF021662440000003FDB
+:103A300001166248000000000116624C0000000000
+:103A400001166250000000000116625400000000E0
+:103A500001166258000000000116625C00000000C0
+:103A600001166260000000000116626400000000A0
+:103A700001166268000000000116626C0000000080
+:103A80000116627000000000011662740000000060
+:103A900001166278000000000116627C0000000040
+:103AA000011662D400000000021662D80000FFFF79
+:103AB000021662DC0000FFFF021662E00000FFFF5A
+:103AC000021662E40000FFFF0C166000000003E82D
+:103AD0000A166000000000010B16600000000003E1
+:103AE0000216804000000006021680440000000517
+:103AF000021680480000000A0216804C00000005F3
+:103B00000216805400000002021680CC000000045F
+:103B1000021680D000000004021680D400000004C9
+:103B2000021680D800000004021680DC00000004A9
+:103B3000021680E000000004021680E40000000489
+:103B4000021680E800000004021688040000000647
+:103B5000021680300000007C021680340000003D18
+:103B6000021680380000003F0216803C0000009CD6
+:103B70000216E6E8000060000216E6EC00006000B5
+:103B80000216E6F0000060000216E6F40000600095
+:103B900002168234000025E40216823800008000FC
+:103BA00002168094000025E3021681F400000C0840
+:103BB000021681F800000040021681FC000001009E
+:103BC0000216820000000020021682040000001786
+:103BD00002168208000000800216820C000002001B
+:103BE00002168210000000000216823C0000001342
+:103BF00002168220008F008F0216821C008F008F19
+:103C0000021680F0000000070216821801FF01FF73
+:103C10000216821401FF01FF061680F40000000264
+:103C20000216811C0000000502168120000000051C
+:103C300002168124000000050216812800000008F9
+:103C40000216812C000000060216813000000007D9
+:103C50000616813400000004021680FC00000000FB
+:103C600006168144000000020216814C0000000488
+:103C7000021681500000000102168154000000026B
+:103C800002168158000000050216815C0000000544
+:103C90000216816000000005021681640000000524
+:103CA0000216816800000008021681000000000072
+:103CB0000216816C000000060216817000000007E9
+:103CC00006168174000000060216818C00000004B4
+:103CD000021681900000000102168104000000001D
+:103CE000021681940000000202168198000000056F
+:103CF0000216819C00000005021681A0000000054C
+:103D0000021681A400000005021681A80000000828
+:103D1000021681AC00000006021681B00000000708
+:103D2000061681B40000000202168108000000009F
+:103D3000061681BC00000004021681CC00000004BD
+:103D4000021681D000000001021681D4000000029A
+:103D5000021681D800000005021681DC0000000573
+:103D6000021681E0000000050216810C000000042C
+:103D7000021681E400000005021681E80000000838
+:103D8000021681EC00000006021681F00000000718
+:103D900002168110000000010216811400000002CA
+:103DA00002168118000000050216809C0000004CDD
+:103DB000021680A00000004C061680C4000000021D
+:103DC000021680A400000000021680A80000000077
+:103DD000021680AC0000004C061680B00000000502
+:103DE0000216E6F80000020402168240003F003F7F
+:103DF00002168244003F003F061682900000000435
+:103E000002168248008000800216824C00800080EA
+:103E100002168250010001000216825401000100C6
+:103E20000616825800000002021682600040004020
+:103E30000216826400400040021682681E001E00C6
+:103E40000216826C1E001E000216827040004000A6
+:103E500002168274400040000216827880008000C2
+:103E60000216827C800080000216828020002000E2
+:103E700002168284200020000616828800000002BC
+:103E8000021680900000004B021680600000014086
+:103E900002168064000001400616808800000002BF
+:103EA00002168068000000000216806C000000000E
+:103EB00002168070000000C0061680740000000525
+:103EC0000216880C0101010102168810010120046C
+:103ED000021688142008100102168818010101201A
+:103EE0000216881C0101010102168820010120042C
+:103EF00002168824200810010216882801010120DA
+:103F00000216882C200810010216883001010120B9
+:103F100002168834010101010216883801012004CB
+:103F20000216883C20081001021688400101012079
+:103F3000021688440101010102168848010120048B
+:103F40000216E6BC000000000216E6C000000002F7
+:103F50000216E6C4000000040216E6C800000006CF
+:103F60000216E79400000001021680EC000000FF3A
+:103F700002140000000000010215C024000000002F
+:103F80000215C0EC000000010215C0F000000001A5
+:103F90000615C10000000002021400040000000128
+:103FA00002140008000000010214000C00000001CF
+:103FB000021400300000000102140034000000016F
+:103FC0000214004000000001021400440000FFFF42
+:103FD00006140004000000030214000000000000AA
+:103FE000060280000000200002020058000000329B
+:103FF000020200A003150020020200A40315002005
+:10400000020200A801000030020200AC081000000B
+:10401000020200B000000036020200B400000030CE
+:10402000020200B800000031020200BC00000002E1
+:10403000020200C000000005020200C400000002ED
+:10404000020200C800000002020200D000000007C7
+:10405000020200DC00000000020200E00000000597
+:10406000020200E400000003020200F00000000170
+:10407000020200FC00000006020201200000000015
+:104080000202013400000002020201B0000000013F
+:104090000202020C000000010202021400000001F2
+:1040A00002020218000000020202040400000001E3
+:1040B0000202040C00000040020204100000004054
+:1040C0000202041C00000004020204200000002080
+:1040D0000202042400000002020204280000002062
+:1040E000060205000000001204020480002008BF40
+:1040F000020200600000000F0202006400000007DE
+:1041000002020068000000000202006C0000000EC5
+:10411000020200700000000E06020074000000039E
+:10412000020200F40000000402020004000000018A
+:1041300002020008000000010202000C0000000161
+:104140000202001000000001020200140000000141
+:1041500002020018000000010202001C0000000121
+:104160000202002000000001020200240000000101
+:1041700002020028000000010202002C00000001E1
+:1041800002020030000000010202003400000001C1
+:1041900002020038000000010202003C00000001A1
+:1041A0000202004000000001020200440000000181
+:1041B00002020048000000010202004C0000000161
+:1041C000020200500000000102020108000000C8C5
+:1041D0000202011800000002020201C400000000F7
+:1041E000020201CC00000000020201D40000000223
+:1041F000020201DC00000002020201E4000000FFF4
+:10420000020201EC000000FF0202010000000000B9
+:104210000202010C000000C80202011C00000002A2
+:10422000020201C800000000020201D000000000EC
+:10423000020201D800000002020201E000000002B8
+:10424000020201E8000000FF020201F0000000FF8E
+:10425000020201040000002002020108000000C860
+:104260000202011800000002020201C40000000066
+:10427000020201CC00000000020201D40000000292
+:10428000020201DC00000002020201E4000000FF63
+:10429000020201EC000000FF020201000000001019
+:1042A0000202010C000000C80202011C0000000212
+:1042B000020201C800000000020201D0000000005C
+:1042C000020201D800000002020201E00000000228
+:1042D000020201E8000000FF020201F0000000FFFE
+:1042E000020201040000003002020108000000C8C0
+:1042F0000202011800000002020201C400000000D6
+:10430000020201CC00000000020201D40000000201
+:10431000020201DC00000002020201E4000000FFD2
+:10432000020201EC000000FF020201000000004058
+:104330000202010C000000C80202011C0000000281
+:10434000020201C800000000020201D000000000CB
+:10435000020201D800000002020201E00000000297
+:10436000020201E8000000FF020201F0000000FF6D
+:10437000020201040000006002020108000000C8FF
+:104380000202011800000002020201C40000000045
+:10439000020201CC00000000020201D40000000271
+:1043A000020201DC00000002020201E4000000FF42
+:1043B000020201EC000000FF0202010000000050B8
+:1043C0000202010C000000C80202011C00000002F1
+:1043D000020201C800000000020201D0000000003B
+:1043E000020201D800000002020201E00000000207
+:1043F000020201E8000000FF020201F0000000FFDD
+:1044000002020104000000700728040000B300004D
+:10441000082807B8000908DF072C000028CB000097
+:10442000072C8000365D0A33072D0000347017CB4F
+:10443000072D80003A9424E8072E000036C7338EFB
+:10444000072E80001CE94140082EC5D0274608E110
+:10445000022800BC0000003001280000000000001D
+:1044600001280004000000000128000800000000EE
+:104470000128000C000000000128001000000000CE
+:1044800001280014000000000228002000000001A4
+:104490000228002400000002022800280000000377
+:1044A0000228002C00000000022800300000000458
+:1044B000022800340000000102280038000000003B
+:1044C0000228003C00000001022800400000000417
+:1044D00002280044000000000228004800000001FB
+:1044E0000228004C000000030228005000000000D9
+:1044F00002280054000000010228005800000004B7
+:104500000228005C0000000002280060000000019A
+:104510000228006400000003022800680000000078
+:104520000228006C00000001022800700000000456
+:104530000228007400000000022800780000000437
+:104540000228007C00000003062800800000000212
+:10455000022800A400007FFF022800A8000003FF3B
+:10456000022802240000000002280234000000009B
+:104570000228024C00000000022802E40000FFFFB5
+:104580000628200000000800022B8BC0000000015C
+:10459000022B800000000000022B80400000001869
+:1045A000022B80800000000C022B80C000000066FF
+:1045B0000C2B8300000864700A2B83000000015755
+:1045C0000B2B83000000055F0A2B834000000000D6
+:1045D0000C2B8340000002260B2B834000000001BF
+:1045E000022B838000086470022B83C00000022627
+:1045F000022B1480000000010A2B14800000000030
+:10460000022B944000000001062B94480000000299
+:10461000062A9A7000000004042A9A80000408E325
+:10462000062A9A9000000002042A9A98000208E7DD
+:10463000062A900000000048062A2008000000C852
+:10464000062A200000000002062A912800000086A9
+:10465000062AC00000000120062A9348000000033B
+:10466000042A9354000108E9062A9FB000000002C2
+:10467000042A9418000208EA042A9CD0000108ECDD
+:10468000062A9CD400000011042A9D20008F08ED0A
+:10469000062A9F5C00000005042A30000002097C05
+:1046A000062A300800000100062A404000000010E1
+:1046B000042A40000010097E042A84080002098EA2
+:1046C000042ACF4000040990042ACF600002099414
+:1046D000062A9FA000000004062A60000000054092
+:1046E000062A9D1800000002062AB00000000050B3
+:1046F000062ABB7000000070062ABB68000000029A
+:10470000062AB94800000004062AD000000008006C
+:10471000062AC48000000150062A942000000032BE
+:10472000062A502000000002062A50300000000235
+:10473000062A500000000002062A50100000000265
+:10474000022A520800000001042A9AA000020996D9
+:10475000062A95B000000022042A96380001099824
+:10476000062A963C00000003062A96E0000000227C
+:10477000042A976800010999062A976C0000000333
+:10478000062A981000000022042A98980001099A2D
+:10479000062A989C00000003062A99400000002287
+:1047A000042A99C80001099B062A99CC000000033D
+:1047B000062ABB5800000002062AC9C000000150AA
+:1047C000062A94E800000032062A50280000000261
+:1047D000062A503800000002062A50080000000295
+:1047E000062A501800000002022A520C00000001A4
+:1047F000042A9AA80002099C062A96480000002272
+:10480000042A96D00001099E062A96D400000003CF
+:10481000062A977800000022042A98000001099FC8
+:10482000062A980400000003062A98A80000002227
+:10483000042A9930000109A0062A993400000003D7
+:10484000062A99D800000022042A9A60000109A1D2
+:10485000062A9A6400000003062ABB6000000002DA
+:10486000022ACF0000000000042A9AB0001009A21A
+:10487000062A50480000000E022ACF040000000063
+:10488000042A9AF0001009B2062A50800000000E97
+:10489000022ACF0800000000042A9B30001009C241
+:1048A000062A50B80000000E022ACF0C00000000BB
+:1048B000042A9B70001009D2062A50F00000000E56
+:1048C000022ACF1000000000042A9BB0001009E269
+:1048D000062A51280000000E022ACF140000000012
+:1048E000042A9BF0001009F2062A51600000000E15
+:1048F000022ACF1800000000042A9C3000100A028F
+:10490000062A51980000000E022ACF1C0000000069
+:10491000042A9C7000100A12062A51D00000000ED2
+:1049200002101008000000010210105000000001E9
+:10493000021010000003D000021010040000003D1F
+:104940000910180002000A220910110000100C22A0
+:1049500006101140000000080910116000100C3210
+:10496000061011A00000001806102400000000E04E
+:104970000210201C00000000021020200000000196
+:10498000021020C0000000020210200400000001FC
+:104990000210200800000001021030D800000001C1
+:1049A00009103C0000050C420910380000050C47B6
+:1049B0000910392000050C4C09103B0000050C5172
+:1049C000021040D400000030021040D80000003037
+:1049D00006104C00000001000210402800000010EA
+:1049E0000210404400003FFF021040580028000021
+:1049F000021040840084924A0210405800000000D7
+:104A0000021041380000000102104138000000018E
+:104A1000021041380000000102104138000000017E
+:104A2000021041380000000102104138000000016E
+:104A3000021041380000000102104138000000015E
+:104A40000212049001F680400212051400003C108E
+:104A500002120494FFFFFFFF02120498FFFFFFFF02
+:104A60000212049CFFFFFFFF021204A0FFFFFFFFE2
+:104A7000021204A4FFFFFFFF021204A8FFFFFFFFC2
+:104A8000021204ACFFFFFFFF021204B0FFFFFFFFA2
+:104A9000021204B8FFFFFFFF021204BCFFFFFFFF7A
+:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A
+:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A
+:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16
+:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2
+:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2
+:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2
+:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91
+:104B1000021204FCFFFFFFFF02120500FFFFFFFF70
+:104B200002120504FFFFFFFF02120508FFFFFFFF4F
+:104B30000212050CFFFFFFFF02120510FFFFFFFF2F
+:104B4000021204D4F800C000021204B4F0005000B5
+:104B500002120390000000080212039C00000008EB
+:104B6000021203A000000008021203A400000002C9
+:104B7000021203BC00000004021203C00000000582
+:104B8000021203C400000004021203D0000000005F
+:104B90000212036C00000001021201BC0000004080
+:104BA000021201C000001808021201C4000008032C
+:104BB000021201C800000803021201CC00000040EC
+:104BC000021201D000000003021201D40000080309
+:104BD000021201D800000803021201DC00000803E1
+:104BE000021201E000010003021201E400000803C8
+:104BF000021201E800000803021201EC00000003A9
+:104C0000021201F000000003021201F40000000390
+:104C1000021201F800000003021201FC0000000370
+:104C2000021202000000000302120204000000034E
+:104C300002120208000000030212020C000000032E
+:104C4000021202100000000302120214000000030E
+:104C500002120218000000030212021C00000003EE
+:104C600002120220000000030212022400000003CE
+:104C700002120228000024030212022C0000002F5E
+:104C80000212023000000009021202340000001972
+:104C900002120238000001840212023C000001836B
+:104CA0000212024000000306021202440000001932
+:104CB00002120248000000060212024C0000030625
+:104CC0000212025000000306021202540000030602
+:104CD0000212025800000C860212025C0000030659
+:104CE00002120260000003060212026400000006C5
+:104CF00002120268000000060212026C00000006A8
+:104D00000212027000000006021202740000000687
+:104D100002120278000000060212027C0000000667
+:104D20000212028000000006021202840000000647
+:104D300002120288000000060212028C0000000627
+:104D40000212029000000006021202940000000607
+:104D500002120298000000060212029C00000006E7
+:104D6000021202A000000306021202A400000013B7
+:104D7000021202A800000006021202B00000100495
+:104D8000021202B400001004021203240010644056
+:104D90000212032800106440021205B40000000152
+:104DA000021205F800000040021205FC0000001984
+:104DB00002120600000000010212066C0000000151
+:104DC000021201B000000001021207D80000000327
+:104DD000021207D800000003021207D800000003E7
+:104DE000021207D800000003021207D800000003D7
+:104DF000021207D800000003021207D800000003C7
+:104E0000021207D8000000030600A0000000000CFA
+:104E10000200A050000000000200A05400000000AA
+:104E20000200A0EC555400000200A0F05555555565
+:104E30000200A0F4000055550200A0F8F0000000A8
+:104E40000200A0FC555400000200A1005555555524
+:104E50000200A104000055550200A108F000000066
+:104E60000200A19C000000000200A1A000010000BF
+:104E70000200A1A4000050140200A1A8000000003C
+:104E80000200A6A8000000000200A6AC000000007E
+:104E90000200A6D0000000000200A45C00000C008C
+:104EA0000200A61C000000030200A070FFF55FFFD7
+:104EB0000200A0740000FFFF0200A078F00003E0F1
+:104EC0000200A07C000000000200A0800000A00002
+:104ED0000600A084000000050200A0980FE000007A
+:104EE0000600A09C000000070200A0B8000004001B
+:104EF0000600A0BC000000030200A0C800001000D3
+:104F00000600A0CC000000030200A0D80000400072
+:104F10000600A0DC000000030200A0E80001000081
+:104F20000600A22C000000040200A688000000FC7D
+:104F30000600A68C000000070200A6F40000000096
+:104F40000200A10CFF5C00000200A110FFF55FFF52
+:104F50000200A1140000FFFF0200A118F00003E00E
+:104F60000200A11C000000000200A1200000A0001F
+:104F70000600A124000000050200A1380FE0000097
+:104F80000600A13C000000070200A1580000080034
+:104F90000600A15C000000030200A16800002000E0
+:104FA0000600A16C000000030200A1780000800050
+:104FB0000600A17C000000030200A188000200009E
+:104FC0000600A23C000000040200A6B0000000FCA5
+:104FD0000600A6B4000000070200A6F800000000CA
+:104FE0000200A030000000000200A0340000000019
+:104FF0000200A038000000000200A03C00000000F9
+:105000000200A040000000000200A04400000000D8
+:105010000200A048000000000200A04C00000000B8
+:10502000020090C40000E000020090CC0000F300F9
+:10503000020090D400000003020091A000000001D3
+:105040000600917000000003020090EC0000600078
+:10505000020090F400007300020090FC00000003C6
+:10506000020091A8000000010600918800000003E2
+:10507000020091000000400002009108000053006F
+:105080000200911000000004020091AC0000000139
+:1050900006009194000000020200919C00000001B3
+:1050A000020090D800006000020090E00000730051
+:1050B000020090E800000003020091A4000000013B
+:1050C0000200917C000000010200918000000001BC
+:1050D00002009184000000000200912800000300FB
+:1050E0000200916C0003F0080200912C0000030004
+:1050F0000200913000000300020091340000030020
+:1051000002009138000003000200913C00000300FF
+:1051100002009140000003000200942C00000001F6
+:1051200002009430000000010200943400000001ED
+:105130000200942C000000010200943000000001E5
+:1051400002009434000000010200942C00000001D1
+:1051500002009430000000010200943400000001BD
+:105160000200942C000000010200943000000001B5
+:1051700002009434000000010200942C00000001A1
+:10518000020094300000000102009434000000018D
+:105190000200942C00000001020094300000000185
+:1051A00002009434000000010200942C0000000171
+:1051B000020094300000000102009434000000015D
+:1051C0000200942C00000001020094300000000155
+:1051D0000200943400000001021300780000003047
+:1051E0000213003C000061A8061301080000000340
+:1051F000021301040000000002130134000000004B
+:10520000061301080000000302130104000000005F
+:10521000021301340000000006130108000000031F
+:10522000021301040000000002130134000000001A
+:10523000061301080000000302130104000000002F
+:1052400002130134000000000613010800000003EF
+:1052500002130104000000000213013400000000EA
+:1052600006130108000000030213010400000000FF
+:1052700002130134000000000613010800000003BF
+:1052800002130104000000000213013400000000BA
+:1052900006130108000000030213010400000000CF
+:1052A0000213013400000000021100B800000001E8
+:1052B0000216E6E8000020000216E6EC00002000DE
+:1052C0000216E6F0000065550216E6F4000065558A
+:1052D00002168150000000000216817400000001D7
+:1052E00002168178000000010216817C0000000196
+:1052F0000216818000000001021681840000000176
+:105300000216818800000001021681B4000000012D
+:10531000021681B800000001021681BC00000001E5
+:10532000021681C000000001021681C400000001C5
+:10533000021681C800000001021681100000000062
+:105340000216824000BF00BF061682440000000221
+:105350000216824C00BF00BF0216E6C40000000126
+:105360000216E6C8000000030216E79400000000E1
+:10537000042ACF40000A0C56000000000000000084
+:1053800000000034000000000000000000000000E9
+:10539000000000000000000000000000000000000D
+:1053A0000000000000000000000000000034003594
+:1053B00000000000000000000000000000000000ED
+:1053C00000000000000000000000000000000000DD
+:1053D0000000000000000000003500600000000038
+:1053E00000000000000000000000000000000000BD
+:1053F00000000000000000000000000000000000AD
+:1054000000000000006000910000000000000000AB
+:1054100000910095009500990099009D009D00A1C4
+:1054200000A100A500A500A900A900AD00AD00B134
+:1054300000B100B500000000000000000000000006
+:10544000000000000000000000000000000000005C
+:1054500000000000000000000000000000B5031183
+:105460000311031B031B03250325032C032C033308
+:105470000333033A033A0341034103480348034F0C
+:10548000034F03560356035D0000000000000000B8
+:10549000000000000000000000000000000000000C
+:1054A00000000000000000000000000000000000FC
+:1054B00000000000000000000000000000000000EC
+:1054C00000000000000000000000000000000000DC
+:1054D00000000000000000000000000000000000CC
+:1054E00000000000000000000000000000000000BC
+:1054F00000000000000000000000000000000000AC
+:10550000000000000000000000000000000000009B
+:10551000000000000000000000000000000000008B
+:10552000000000000000000000000000000000007B
+:105530000000000000000000035D035E00000000AA
+:1055400000000000035E035F035F0360036003610C
+:10555000036103620362036303630364036403651B
+:10556000036503660000000000000000000000006A
+:10557000000000000000000000000000000000002B
+:10558000000000000000000000000000000000001B
+:105590000366036D036D0379037903850000000042
+:1055A00000000000000000000000000000000000FB
+:1055B00000000000000000000000000000000000EB
+:1055C00000000000000000000000000000000000DB
+:1055D00000000000000000000000000000000000CB
+:1055E00000000000000000000385038600000000AA
+:1055F00000000000000000000000000000000000AB
+:10560000000000000000000000000000000000009A
+:1056100000000000038603B100000000000000004D
+:10562000000000000000000000000000000000007A
+:10563000000000000000000000000000000000006A
+:1056400003B103E0000000000000000000000000C3
+:10565000000000000000000000000000000000004A
+:1056600000000000000000000000000003E0040F44
+:105670000000000000000000040F04160416041DC2
+:10568000041D04240424042B042B043204320439A2
+:1056900004390440044004470447047A0000000031
+:1056A00000000000047A047E047E048204820486E2
+:1056B0000486048A048A048E048E0492049204965A
+:1056C0000496049A049A04EA04EA05000500051603
+:1056D000051605180518051A051A051C051C051ED2
+:1056E000051E052005200522052205240524052682
+:1056F00005260693000000000000000006930698AF
+:105700000698069D069D06A206A206A706A706AC59
+:1057100006AC06B106B106B606B606BB06BB06BCAD
+:105720000000000000000000000000000000000079
+:105730000000000000000000000000000000000069
+:10574000000000000000000006BC06E000000000B1
+:105750000000000006E006E206E206E406E406E6D3
+:1057600006E606E806E806EA06EA06EC06EC06EEB9
+:1057700006EE06F006F00705070507080708070B01
+:105780000000000000000000000000000000000019
+:105790000000000000000000000000000000000009
+:1057A000070B074F00000000000000000000000091
+:1057B00000000000000000000000000000000000E9
+:1057C000000000000000000000000000074F07E19B
+:1057D00000000000000000000000000000000000C9
+:1057E00000000000000000000000000000000000B9
+:1057F000000000000000000007E107EF00000000CB
+:105800000000000000000000000000000000000098
+:105810000000000000000000000000000000000088
+:105820000000000007EF082C00000000000000004E
+:10583000082C08350835083E083E08470847085038
+:1058400008500859085908620862086B086B087408
+:10585000087408D508D508EA08EA08FF08FF090215
+:1058600009020905090509080908090B090B090EB0
+:10587000090E09110911091409140917091709203A
+:105880000000000000000000000000000000000018
+:105890000000000000000000000000000000000008
+:1058A00000000000000000000920092600000000A0
+:1058B00000000000000000000000000000000000E8
+:1058C00000000000000000000000000000000000D8
+:1058D000000000000926092B000000000000000065
+:1058E00000000000000000000000000000000000B8
+:1058F00000000000000000000000000000000000A8
+:10590000092B0933000000000000000009330934AE
+:10591000093409350935093609360937093709388F
+:10592000093809390939093A093A093B00000000E8
+:105930000000000000000000000000000000000067
+:105940000000000000000000000000000000000057
+:105950000000000000000000093B09AC000000004E
+:105960000000000009AC09AD09AD09AE09AE09AFF0
+:1059700009AF09B009B009B109B109B209B209B357
+:1059800009B309B409B409C809C809DB09DB09EF7F
+:1059900009EF09F009F009F109F109F209F209F337
+:1059A00009F309F409F409F509F509F609F609F707
+:1059B00009F70A1600000000000000000A160A1984
+:1059C0000A190A1C0A1C0A1F0A1F0A220A220A258F
+:1059D0000A250A280A280A2B0A2B0A2E0A2E0A3020
+:1059E00000000000000000000A300A330A330A36C3
+:1059F0000A360A390A390A3C0A3C0A3F0A3F0A4277
+:105A00000A420A450A450A480A480A4900000000B5
+:105A10000000000000000000000000000000000086
+:105A20000000000000000000000000000000000076
+:105A3000000000000A490A610000000000000000A8
+:105A40000000000000000000000000000000000056
+:105A50000000000000000000000000000000000046
+:105A60000A610A620000000000000000000000005F
+:105A70000000000000000000000000000000000026
+:105A80000000000000000000000000000000000016
+:105A9000000100000002070000030E0000041500D2
+:105AA00000051C000006230000072A000008310042
+:105AB00000093800000A3F00000B4600000C4D00B2
+:105AC000000D5400000E5B00000F62000010690022
+:105AD000001170000012770000137E000014850092
+:105AE00000158C000016930000179A000018A10002
+:105AF0000019A800001AAF00001BB600001CBD0072
+:105B0000001DC400001ECB00001FD2000000D90001
+:105B10000000200000004000000060000000800045
+:105B20000000A0000000C0000000E0000001000034
+:105B30000001200000014000000160000001800021
+:105B40000001A0000001C0000001E0000002000010
+:105B500000022000000240000002600000028000FD
+:105B60000002A0000002C0000002E00000030000EC
+:105B700000032000000340000003600000038000D9
+:105B80000003A0000003C0000003E00000040000C8
+:105B900000042000000440000004600000048000B5
+:105BA0000004A0000004C0000004E00000050000A4
+:105BB0000005200000054000000560000005800091
+:105BC0000005A0000005C0000005E0000006000080
+:105BD000000620000006400000066000000680006D
+:105BE0000006A0000006C0000006E000000700005C
+:105BF0000007200000074000000760000007800049
+:105C00000007A0000007C0000007E0000008000037
+:105C10000008200000084000000860000008800024
+:105C20000008A0000008C0000008E0000009000013
+:105C30000009200000094000000960000009800000
+:105C40000009A0000009C0000009E000000A0000EF
+:105C5000000A2000000A4000000A6000000A8000DC
+:105C6000000AA000000AC000000AE000000B0000CB
+:105C7000000B2000000B4000000B6000000B8000B8
+:105C8000000BA000000BC000000BE000000C0000A7
+:105C9000000C2000000C4000000C6000000C800094
+:105CA000000CA000000CC000000CE000000D000083
+:105CB000000D2000000D4000000D6000000D800070
+:105CC000000DA000000DC000000DE000000E00005F
+:105CD000000E2000000E4000000E6000000E80004C
+:105CE000000EA000000EC000000EE000000F00003B
+:105CF000000F2000000F4000000F6000000F800028
+:105D0000000FA000000FC000000FE0000010000016
+:105D10000010200000104000001060000010800003
+:105D20000010A0000010C0000010E00000110000F2
+:105D300000112000001140000011600000118000DF
+:105D40000011A0000011C0000011E00000120000CE
+:105D500000122000001240000012600000128000BB
+:105D60000012A0000012C0000012E00000130000AA
+:105D70000013200000134000001360000013800097
+:105D80000013A0000013C0000013E0000014000086
+:105D90000014200000144000001460000014800073
+:105DA0000014A0000014C0000014E0000015000062
+:105DB000001520000015400000156000001580004F
+:105DC0000015A0000015C0000015E000001600003E
+:105DD000001620000016400000166000001680002B
+:105DE0000016A0000016C0000016E000001700001A
+:105DF0000017200000174000001760000017800007
+:105E00000017A0000017C0000017E00000180000F5
+:105E100000182000001840000018600000188000E2
+:105E20000018A0000018C0000018E00000190000D1
+:105E300000192000001940000019600000198000BE
+:105E40000019A0000019C0000019E000001A0000AD
+:105E5000001A2000001A4000001A6000001A80009A
+:105E6000001AA000001AC000001AE000001B000089
+:105E7000001B2000001B4000001B6000001B800076
+:105E8000001BA000001BC000001BE000001C000065
+:105E9000001C2000001C4000001C6000001C800052
+:105EA000001CA000001CC000001CE000001D000041
+:105EB000001D2000001D4000001D6000001D80002E
+:105EC000001DA000001DC000001DE000001E00001D
+:105ED000001E2000001E4000001E6000001E80000A
+:105EE000001EA000001EC000001EE000001F0000F9
+:105EF000001F2000001F4000001F6000001F8000E6
+:105F0000001FA000001FC000001FE00000200000D4
+:105F100000202000002040000020600000208000C1
+:105F20000020A0000020C0000020E00000210000B0
+:105F3000002120000021400000216000002180009D
+:105F40000021A0000021C0000021E000002200008C
+:105F50000022200000224000002260000022800079
+:105F60000022A0000022C0000022E0000023000068
+:105F70000023200000234000002360000023800055
+:105F80000023A0000023C0000023E0000024000044
+:105F90000024200000244000002460000024800031
+:105FA0000024A0000024C0000024E0000025000020
+:105FB000002520000025400000256000002580000D
+:105FC0000025A0000025C0000025E00000260000FC
+:105FD00000262000002640000026600000268000E9
+:105FE0000026A0000026C0000026E00000270000D8
+:105FF00000272000002740000027600000278000C5
+:106000000027A0000027C0000027E00000280000B3
+:1060100000282000002840000028600000288000A0
+:106020000028A0000028C0000028E000002900008F
+:10603000002920000029400000296000002980007C
+:106040000029A0000029C0000029E000002A00006B
+:10605000002A2000002A4000002A6000002A800058
+:10606000002AA000002AC000002AE000002B000047
+:10607000002B2000002B4000002B6000002B800034
+:10608000002BA000002BC000002BE000002C000023
+:10609000002C2000002C4000002C6000002C800010
+:1060A000002CA000002CC000002CE000002D0000FF
+:1060B000002D2000002D4000002D6000002D8000EC
+:1060C000002DA000002DC000002DE000002E0000DB
+:1060D000002E2000002E4000002E6000002E8000C8
+:1060E000002EA000002EC000002EE000002F0000B7
+:1060F000002F2000002F4000002F6000002F8000A4
+:10610000002FA000002FC000002FE0000030000092
+:10611000003020000030400000306000003080007F
+:106120000030A0000030C0000030E000003100006E
+:10613000003120000031400000316000003180005B
+:106140000031A0000031C0000031E000003200004A
+:106150000032200000324000003260000032800037
+:106160000032A0000032C0000032E0000033000026
+:106170000033200000334000003360000033800013
+:106180000033A0000033C0000033E0000034000002
+:1061900000342000003440000034600000348000EF
+:1061A0000034A0000034C0000034E00000350000DE
+:1061B00000352000003540000035600000358000CB
+:1061C0000035A0000035C0000035E00000360000BA
+:1061D00000362000003640000036600000368000A7
+:1061E0000036A0000036C0000036E0000037000096
+:1061F0000037200000374000003760000037800083
+:106200000037A0000037C0000037E0000038000071
+:10621000003820000038400000386000003880005E
+:106220000038A0000038C0000038E000003900004D
+:10623000003920000039400000396000003980003A
+:106240000039A0000039C0000039E000003A000029
+:10625000003A2000003A4000003A6000003A800016
+:10626000003AA000003AC000003AE000003B000005
+:10627000003B2000003B4000003B6000003B8000F2
+:10628000003BA000003BC000003BE000003C0000E1
+:10629000003C2000003C4000003C6000003C8000CE
+:1062A000003CA000003CC000003CE000003D0000BD
+:1062B000003D2000003D4000003D6000003D8000AA
+:1062C000003DA000003DC000003DE000003E000099
+:1062D000003E2000003E4000003E6000003E800086
+:1062E000003EA000003EC000003EE000003F000075
+:1062F000003F2000003F4000003F6000003F800062
+:10630000003FA000003FC000003FE000003FE00170
+:1063100000000000000001FF0000020000007FF804
+:1063200000007FF800000A90000035000000000126
+:106330000000FF00000000000000FF00000000005F
+:106340000000FF00000000000000FF00000000004F
+:106350000000FF00000000000000FF00000000003F
+:106360000000FF00000000000000FF00000000002F
+:106370000000FF00000000000000FF00000000001F
+:106380000000FF00000000000000FF00000000000F
+:106390000000FF00000000000000FF0000000000FF
+:1063A0000000FF00000000000000FF0000000000EF
+:1063B0000000FF00000000000000FF0000000000DF
+:1063C0000000FF00000000000000FF0000000000CF
+:1063D0000000FF00000000000000FF0000000000BF
+:1063E0000000FF00000000000000FF0000000000AF
+:1063F0000000FF00000000000000FF00000000009F
+:106400000000FF00000000000000FF00000000008E
+:106410000000FF00000000000000FF00000000007E
+:106420000000FF00000000000000FF00000000006E
+:106430000000FF00000000000000FF00000000005E
+:106440000000FF00000000000000FF00000000004E
+:106450000000FF00000000000000FF00000000003E
+:106460000000FF00000000000000FF00000000002E
+:106470000000FF00000000000000FF00000000001E
+:106480000000FF00000000000000FF00000000000E
+:106490000000FF00000000000000FF0000000000FE
+:1064A0000000FF00000000000000FF0000000000EE
+:1064B0000000FF00000000000000FF0000000000DE
+:1064C0000000FF00000000000000FF0000000000CE
+:1064D0000000FF00000000000000FF0000000000BE
+:1064E0000000FF00000000000000FF0000000000AE
+:1064F0000000FF00000000000000FF00000000009E
+:106500000000FF00000000000000FF00000000008D
+:106510000000FF00000000000000FF00000000007D
+:106520000000FF00000000000000FF00000000006D
+:106530000000FF00000000000000FF00000000005D
+:106540000000FF00000000000000FF00000000004D
+:106550000000FF00000000000000FF00000000003D
+:106560000000FF00000000000000FF00000000002D
+:1065700000000000140AFF000000000100000000FD
+:106580000020100100000000010090000000010048
+:1065900000009002000090040000900600009008A7
+:1065A0000000900A0000900C0000900E0000901077
+:1065B0000000901200009014000090160000901847
+:1065C0000000901A0000901C0000901E0000902017
+:1065D00000009022000090240000902600009028E7
+:1065E0000000902A0000902C0000902E00009030B7
+:1065F0000000903200009034000090360000903887
+:106600000000903A0000903C0000903E0000904056
+:106610000000904200009044000090460000904826
+:106620000000904A0000904C0000904E00009050F6
+:1066300000009052000090540000905600009058C6
+:106640000000905A0000905C0000905E0000906096
+:106650000000906200009064000090660000906866
+:106660000000906A0000906C0000906E0000907036
+:106670000000907200009074000090760000907806
+:106680000000907A0000907C0000907E00009080D6
+:1066900000009082000090840000908600009088A6
+:1066A0000000908A0000908C0000908E0000909076
+:1066B0000000909200009094000090960000909846
+:1066C0000000909A0000909C0000909E000090A016
+:1066D000000090A2000090A4000090A6000090A8E6
+:1066E000000090AA000090AC000090AE000090B0B6
+:1066F000000090B2000090B4000090B6000090B886
+:10670000000090BA000090BC000090BE000090C055
+:10671000000090C2000090C4000090C6000090C825
+:10672000000090CA000090CC000090CE000090D0F5
+:10673000000090D2000090D4000090D6000090D8C5
+:10674000000090DA000090DC000090DE000090E095
+:10675000000090E2000090E4000090E6000090E865
+:10676000000090EA000090EC000090EE000090F035
+:10677000000090F2000090F4000090F6000090F805
+:10678000000090FA000090FC000090FE00009100D4
+:1067900000009102000091040000910600009108A1
+:1067A0000000910A0000910C0000910E0000911071
+:1067B0000000911200009114000091160000911841
+:1067C0000000911A0000911C0000911E0000912011
+:1067D00000009122000091240000912600009128E1
+:1067E0000000912A0000912C0000912E00009130B1
+:1067F0000000913200009134000091360000913881
+:106800000000913A0000913C0000913E0000914050
+:106810000000914200009144000091460000914820
+:106820000000914A0000914C0000914E00009150F0
+:1068300000009152000091540000915600009158C0
+:106840000000915A0000915C0000915E0000916090
+:106850000000916200009164000091660000916860
+:106860000000916A0000916C0000916E0000917030
+:106870000000917200009174000091760000917800
+:106880000000917A0000917C0000917E00009180D0
+:1068900000009182000091840000918600009188A0
+:1068A0000000918A0000918C0000918E0000919070
+:1068B0000000919200009194000091960000919840
+:1068C0000000919A0000919C0000919E000091A010
+:1068D000000091A2000091A4000091A6000091A8E0
+:1068E000000091AA000091AC000091AE000091B0B0
+:1068F000000091B2000091B4000091B6000091B880
+:10690000000091BA000091BC000091BE000091C04F
+:10691000000091C2000091C4000091C6000091C81F
+:10692000000091CA000091CC000091CE000091D0EF
+:10693000000091D2000091D4000091D6000091D8BF
+:10694000000091DA000091DC000091DE000091E08F
+:10695000000091E2000091E4000091E6000091E85F
+:10696000000091EA000091EC000091EE000091F02F
+:10697000000091F2000091F4000091F6000091F8FF
+:10698000000091FA000091FC000091FEFFFFFFFF64
+:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1069D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1069F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:106A0000FFFFFFFFFFFFFFFFFFFFFFFF000000038F
+:106A100000BEBC20000000000000000500000003D4
+:106A200000BEBC20000000000000000500000003C4
+:106A300000BEBC20000000000000000500000003B4
+:106A400000BEBC20000000000000000500000003A4
+:106A500000BEBC2000000000000000050000000394
+:106A600000BEBC2000000000000000050000000384
+:106A700000BEBC2000000000000000050000000374
+:106A800000BEBC2000000000000000050000200047
+:106A9000000040C000006180000082400000A300B0
+:106AA0000000C3C00000E480000105400001260092
+:106AB000000146C000016780000188400001A90074
+:106AC0000001C9C00001EA8000020B4000022C0056
+:106AD00000024CC000026D8000028E400002AF0038
+:106AE0000002CFC00002F0800000114000008000D2
+:106AF000000103800001870000020A8000028E006E
+:106B000000031180000395000004188000049C001D
+:106B100000051F800005A300000626800006AA00CD
+:106B200000072D800007B100000834800008B8007D
+:106B300000093B800009BF00000A4280000AC6002D
+:106B4000000B4980000BCD00000C5080000CD400DD
+:106B5000000D578000005B0000007FF800007FF808
+:106B60000000022A000035000000FF0000000000C5
+:106B70000000FF00000000000000FF000000000017
+:106B80000000FF00000000000000FF000000000007
+:106B90000000FF00000000000000FF0000000000F7
+:106BA0000000FF00000000000000FF0000000000E7
+:106BB0000000FF00000000000000FF0000000000D7
+:106BC0000000FF00000000000000FF0000000000C7
+:106BD0000000FF00000000000000FF0000000000B7
+:106BE0000000FF00000000000000FF0000000000A7
+:106BF0000000FF00000000000000FF000000000097
+:106C00000000FF00000000000000FF000000000086
+:106C10000000FF00000000000000FF000000000076
+:106C20000000FF00000000000000FF000000000066
+:106C30000000FF00000000000000FF000000000056
+:106C40000000FF00000000000000FF000000000046
+:106C50000000FF00000000000000FF000000000036
+:106C60000000FF00000000000000FF000000000026
+:106C70000000FF00000000000000FF000000000016
+:106C80000000FF00000000000000FF000000000006
+:106C90000000FF00000000000000FF0000000000F6
+:106CA0000000FF00000000000000FF0000000000E6
+:106CB0000000FF00000000000000FF0000000000D6
+:106CC0000000FF00000000000000FF0000000000C6
+:106CD0000000FF00000000000000FF0000000000B6
+:106CE0000000FF00000000000000FF0000000000A6
+:106CF0000000FF00000000000000FF000000000096
+:106D00000000FF00000000000000FF000000000085
+:106D10000000FF00000000000000FF000000000075
+:106D20000000FF00000000000000FF000000000065
+:106D30000000FF00000000000000FF000000000055
+:106D40000000FF00000000000000FF000000000045
+:106D50000000FF00000000000000FF000000000035
+:106D60000000FF00000000000000FF000000000025
+:106D70000000FF00000000000000FF000000000015
+:106D80000000FF00000000000000FF000000000005
+:106D90000000FF00000000000000FF0000000000F5
+:106DA0000000FF00000019000000000000000000CB
+:106DB000FFFFFFFF000000000393870000000000BA
+:106DC0000393870000007FF800007FF800000BA30A
+:106DD00000001500000000FF000000FF000000FFA1
+:106DE000000000FF000000FF000000FF000000FFA7
+:106DF000000000FF0000FF00000000000000FF0096
+:106E0000000000000000FF00000000000000FF0084
+:106E1000000000000000FF00000000000000FF0074
+:106E2000000000000000FF00000000000000FF0064
+:106E3000000000000000FF00000000000000FF0054
+:106E4000000000000000FF00000000000000FF0044
+:106E5000000000000000FF00000000000000FF0034
+:106E6000000000000000FF00000000000000FF0024
+:106E7000000000000000FF00000000000000FF0014
+:106E8000000000000000FF00000000000000FF0004
+:106E9000000000000000FF00000000000000FF00F4
+:106EA000000000000000FF00000000000000FF00E4
+:106EB000000000000000FF00000000000000FF00D4
+:106EC000000000000000FF00000000000000FF00C4
+:106ED000000000000000FF00000000000000FF00B4
+:106EE000000000000000FF00000000000000FF00A4
+:106EF000000000000000FF00000000000000FF0094
+:106F0000000000000000FF00000000000000FF0083
+:106F1000000000000000FF00000000000000FF0073
+:106F2000000000000000FF00000000000000FF0063
+:106F3000000000000000FF00000000000000FF0053
+:106F4000000000000000FF00000000000000FF0043
+:106F5000000000000000FF00000000000000FF0033
+:106F6000000000000000FF00000000000000FF0023
+:106F7000000000000000FF00000000000000FF0013
+:106F8000000000000000FF00000000000000FF0003
+:106F9000000000000000FF00000000000000FF00F3
+:106FA000000000000000FF00000000000000FF00E3
+:106FB000000000000000FF00000000000000FF00D3
+:106FC000000000000000FF00000000000000FF00C3
+:106FD000000000000000FF00000000000000FF00B3
+:106FE000000000000000FF00000000000000FF00A3
+:106FF000000000000000FF00000000000000FF0093
+:10700000000000000000FF00000000000000FF0082
+:10701000000000000000FF00000000000000FF0072
+:10702000000000000000FF00000000000000FF0062
+:1070300000000000FFFFFFFFFFFFFFFFFFFFFFFF5C
+:10704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10705000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10707000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10708000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10709000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1070A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1070B000FFFFFFFF00000000000028AD00002918BE
+:1070C0000000291900000005000000070000FF0073
+:1070D0000FFFFFFF0000FF000FFFFFFF000000FF9A
+:1070E0000000FF000000FF000FFFFFFF0000FF0097
+:1070F0000FFFFFFF000000FF0000FF000000FF0087
+:107100000FFFFFFF0000FF000FFFFFFF000000FF69
+:107110000000FF000000FF000FFFFFFF0000FF0066
+:107120000FFFFFFF000000FF0000FF000000FF0056
+:107130000FFFFFFF0000FF000FFFFFFF000000FF39
+:107140000000FF000000FF000FFFFFFF0000FF0036
+:107150000FFFFFFF000000FF0000FF000000FF0026
+:107160000FFFFFFF0000FF000FFFFFFF000000FF09
+:107170000000FF000000FF000FFFFFFF0000FF0006
+:107180000FFFFFFF000000FF0000FF000000FF00F6
+:107190000FFFFFFF0000FF000FFFFFFF000000FFD9
+:1071A0000000FF000000FF000FFFFFFF0000FF00D6
+:1071B0000FFFFFFF000000FF0000FF000000FF00C6
+:1071C0000FFFFFFF0000FF000FFFFFFF000000FFA9
+:1071D0000000FF000000FF000FFFFFFF0000FF00A6
+:1071E0000FFFFFFF000000FF0000FF000000FF0096
+:1071F0000FFFFFFF0000FF000FFFFFFF000000FF79
+:107200000000FF000000FF000FFFFFFF0000FF0075
+:107210000FFFFFFF000000FF0000FF000000FF0065
+:107220000FFFFFFF0000FF000FFFFFFF000000FF48
+:107230000000FF000000FF000FFFFFFF0000FF0045
+:107240000FFFFFFF000000FF0000FF000000FF0035
+:107250000FFFFFFF0000FF000FFFFFFF000000FF18
+:107260000000FF000000FF000FFFFFFF0000FF0015
+:107270000FFFFFFF000000FF0000FF000000FF0005
+:107280000FFFFFFF0000FF000FFFFFFF000000FFE8
+:107290000000FF000000FF000FFFFFFF0000FF00E5
+:1072A0000FFFFFFF000000FF0000FF000000FF00D5
+:1072B0000FFFFFFF0000FF000FFFFFFF000000FFB8
+:1072C0000000FF000000FF000FFFFFFF0000FF00B5
+:1072D0000FFFFFFF000000FF0000FF000000FF00A5
+:1072E0000FFFFFFF0000FF000FFFFFFF000000FF88
+:1072F0000000FF000000FF000FFFFFFF0000FF0085
+:107300000FFFFFFF000000FF0000FF000000FF0074
+:107310000FFFFFFF0000FF000FFFFFFF000000FF57
+:107320000000FF000000FF000FFFFFFF0000FF0054
+:107330000FFFFFFF000000FF0000FF000000FF0044
+:107340000FFFFFFF0000FF000FFFFFFF000000FF27
+:107350000000FF000000FF000FFFFFFF0000FF0024
+:107360000FFFFFFF000000FF0000FF000000FF0014
+:107370000FFFFFFF0000FF000FFFFFFF000000FFF7
+:107380000000FF000000FF000FFFFFFF0000FF00F4
+:107390000FFFFFFF000000FF0000FF000000FF00E4
+:1073A0000FFFFFFF0000FF000FFFFFFF000000FFC7
+:1073B0000000FF000000FF000FFFFFFF0000FF00C4
+:1073C0000FFFFFFF000000FF0000FF000000FF00B4
+:1073D0000FFFFFFF0000FF000FFFFFFF000000FF97
+:1073E0000000FF000000FF000FFFFFFF0000FF0094
+:1073F0000FFFFFFF000000FF0000FF000000FF0084
+:107400000FFFFFFF0000FF000FFFFFFF000000FF66
+:107410000000FF000000FF000FFFFFFF0000FF0063
+:107420000FFFFFFF000000FF0000FF000000FF0053
+:107430000FFFFFFF0000FF000FFFFFFF000000FF36
+:107440000000FF000000FF000FFFFFFF0000FF0033
+:107450000FFFFFFF000000FF0000FF000000FF0023
+:107460000FFFFFFF0000FF000FFFFFFF000000FF06
+:107470000000FF000000FF000FFFFFFF0000FF0003
+:107480000FFFFFFF000000FF0000FF000000FF00F3
+:107490000FFFFFFF0000FF000FFFFFFF000000FFD6
+:1074A0000000FF000000FF000FFFFFFF0000FF00D3
+:1074B0000FFFFFFF000000FF0000FF000000FF00C3
+:1074C0000FFFFFFF0000FF000FFFFFFF000000FFA6
+:1074D0000000FF000000FF000FFFFFFF0000FF00A3
+:1074E0000FFFFFFF000000FF0000FF000000FF0093
+:1074F0000FFFFFFF0000FF000FFFFFFF000000FF76
+:107500000000FF000000FF000FFFFFFF0000FF0072
+:107510000FFFFFFF000000FF0000FF000000FF0062
+:107520000FFFFFFF0000FF000FFFFFFF000000FF45
+:107530000000FF000000FF000FFFFFFF0000FF0042
+:107540000FFFFFFF000000FF0000FF000000FF0032
+:107550000FFFFFFF0000FF000FFFFFFF000000FF15
+:107560000000FF000000FF000FFFFFFF0000FF0012
+:107570000FFFFFFF000000FF0000FF000000FF0002
+:107580000FFFFFFF0000FF000FFFFFFF000000FFE5
+:107590000000FF000000FF000FFFFFFF0000FF00E2
+:1075A0000FFFFFFF000000FF0000FF000000FF00D2
+:1075B0000FFFFFFF0000FF000FFFFFFF000000FFB5
+:1075C0000000FF000000FF000FFFFFFF0000FF00B2
+:1075D0000FFFFFFF000000FF0000FF000000FF00A2
+:1075E0000FFFFFFF0000FF000FFFFFFF000000FF85
+:1075F0000000FF000000FF000FFFFFFF0000FF0082
+:107600000FFFFFFF000000FF0000FF000000FF0071
+:107610000FFFFFFF0000FF000FFFFFFF000000FF54
+:107620000000FF000000FF000FFFFFFF0000FF0051
+:107630000FFFFFFF000000FF0000FF000000FF0041
+:107640000FFFFFFF0000FF000FFFFFFF000000FF24
+:107650000000FF000000FF000FFFFFFF0000FF0021
+:107660000FFFFFFF000000FF0000FF000000FF0011
+:107670000FFFFFFF0000FF000FFFFFFF000000FFF4
+:107680000000FF000000FF000FFFFFFF0000FF00F1
+:107690000FFFFFFF000000FF0000FF000000FF00E1
+:1076A0000FFFFFFF0000FF000FFFFFFF000000FFC4
+:1076B0000000FF000000FF000FFFFFFF0000FF00C1
+:1076C0000FFFFFFF000000FF0000FF000000FF00B1
+:1076D0000FFFFFFF0000FF000FFFFFFF000000FF94
+:1076E0000000FF000000FF000FFFFFFF0000FF0091
+:1076F0000FFFFFFF000000FF0000FF000000FF0081
+:107700000FFFFFFF0000FF000FFFFFFF000000FF63
+:107710000000FF000000FF000FFFFFFF0000FF0060
+:107720000FFFFFFF000000FF0000FF000000FF0050
+:107730000FFFFFFF0000FF000FFFFFFF000000FF33
+:107740000000FF000000FF000FFFFFFF0000FF0030
+:107750000FFFFFFF000000FF0000FF000000FF0020
+:107760000FFFFFFF0000FF000FFFFFFF000000FF03
+:107770000000FF000000FF000FFFFFFF0000FF0000
+:107780000FFFFFFF000000FF0000FF000000FF00F0
+:107790000FFFFFFF0000FF000FFFFFFF000000FFD3
+:1077A0000000FF000000FF000FFFFFFF0000FF00D0
+:1077B0000FFFFFFF000000FF0000FF000000FF00C0
+:1077C0000FFFFFFF0000FF000FFFFFFF000000FFA3
+:1077D0000000FF000000FF000FFFFFFF0000FF00A0
+:1077E0000FFFFFFF000000FF0000FF000000FF0090
+:1077F0000FFFFFFF0000FF000FFFFFFF000000FF73
+:107800000000FF000000FF000FFFFFFF0000FF006F
+:107810000FFFFFFF000000FF0000FF000000FF005F
+:107820000FFFFFFF0000FF000FFFFFFF000000FF42
+:107830000000FF000000FF000FFFFFFF0000FF003F
+:107840000FFFFFFF000000FF0000FF000000FF002F
+:107850000FFFFFFF0000FF000FFFFFFF000000FF12
+:107860000000FF000000FF000FFFFFFF0000FF000F
+:107870000FFFFFFF000000FF0000FF000000FF00FF
+:107880000FFFFFFF0000FF000FFFFFFF000000FFE2
+:107890000000FF000000FF000FFFFFFF0000FF00DF
+:1078A0000FFFFFFF000000FF0000FF000000FF00CF
+:1078B0000FFFFFFF0000FF000FFFFFFF000000FFB2
+:1078C0000000FF000000FF000FFFFFFF0000FF00AF
+:1078D0000FFFFFFF000000FF0000FF000000FF009F
+:1078E0000FFFFFFF0000FF000FFFFFFF000000FF82
+:1078F0000000FF000000FF000FFFFFFF0000FF007F
+:107900000FFFFFFF000000FF0000FF000000FF006E
+:107910000FFFFFFF0000FF000FFFFFFF000000FF51
+:107920000000FF000000FF000FFFFFFF0000FF004E
+:107930000FFFFFFF000000FF0000FF000000FF003E
+:107940000FFFFFFF0000FF000FFFFFFF000000FF21
+:107950000000FF000000FF000FFFFFFF0000FF001E
+:107960000FFFFFFF000000FF0000FF000000FF000E
+:107970000FFFFFFF0000FF000FFFFFFF000000FFF1
+:107980000000FF000000FF000FFFFFFF0000FF00EE
+:107990000FFFFFFF000000FF0000FF000000FF00DE
+:1079A0000FFFFFFF0000FF000FFFFFFF000000FFC1
+:1079B0000000FF000000FF000FFFFFFF0000FF00BE
+:1079C0000FFFFFFF000000FF0000FF000000FF00AE
+:1079D0000FFFFFFF0000FF000FFFFFFF000000FF91
+:1079E0000000FF000000FF000FFFFFFF0000FF008E
+:1079F0000FFFFFFF000000FF0000FF000000FF007E
+:107A00000FFFFFFF0000FF000FFFFFFF000000FF60
+:107A10000000FF000000FF000FFFFFFF0000FF005D
+:107A20000FFFFFFF000000FF0000FF000000FF004D
+:107A30000FFFFFFF0000FF000FFFFFFF000000FF30
+:107A40000000FF000000FF000FFFFFFF0000FF002D
+:107A50000FFFFFFF000000FF0000FF000000FF001D
+:107A60000FFFFFFF0000FF000FFFFFFF000000FF00
+:107A70000000FF000000FF000FFFFFFF0000FF00FD
+:107A80000FFFFFFF000000FF0000FF000000FF00ED
+:107A90000FFFFFFF0000FF000FFFFFFF000000FFD0
+:107AA0000000FF000000FF000FFFFFFF0000FF00CD
+:107AB0000FFFFFFF000000FF0000FF000000FF00BD
+:107AC0000FFFFFFF0000FF000FFFFFFF000000FFA0
+:107AD0000000FF000000FF000FFFFFFF0000FF009D
+:107AE0000FFFFFFF000000FF0000FF000000FF008D
+:107AF0000FFFFFFF0000FF000FFFFFFF000000FF70
+:107B00000000FF000000FF000FFFFFFF0000FF006C
+:107B10000FFFFFFF000000FF0000FF000000FF005C
+:107B20000FFFFFFF0000FF000FFFFFFF000000FF3F
+:107B30000000FF000000FF000FFFFFFF0000FF003C
+:107B40000FFFFFFF000000FF0000FF000000FF002C
+:107B50000FFFFFFF0000FF000FFFFFFF000000FF0F
+:107B60000000FF000000FF000FFFFFFF0000FF000C
+:107B70000FFFFFFF000000FF0000FF000000FF00FC
+:107B80000FFFFFFF0000FF000FFFFFFF000000FFDF
+:107B90000000FF000000FF000FFFFFFF0000FF00DC
+:107BA0000FFFFFFF000000FF0000FF000000FF00CC
+:107BB0000FFFFFFF0000FF000FFFFFFF000000FFAF
+:107BC0000000FF000000FF000FFFFFFF0000FF00AC
+:107BD0000FFFFFFF000000FF0000FF000000FF009C
+:107BE0000FFFFFFF0000FF000FFFFFFF000000FF7F
+:107BF0000000FF000000FF000FFFFFFF0000FF007C
+:107C00000FFFFFFF000000FF0000FF000000FF006B
+:107C10000FFFFFFF0000FF000FFFFFFF000000FF4E
+:107C20000000FF000000FF000FFFFFFF0000FF004B
+:107C30000FFFFFFF000000FF0000FF000000FF003B
+:107C40000FFFFFFF0000FF000FFFFFFF000000FF1E
+:107C50000000FF000000FF000FFFFFFF0000FF001B
+:107C60000FFFFFFF000000FF0000FF000000FF000B
+:107C70000FFFFFFF0000FF000FFFFFFF000000FFEE
+:107C80000000FF000000FF000FFFFFFF0000FF00EB
+:107C90000FFFFFFF000000FF0000FF000000FF00DB
+:107CA0000FFFFFFF0000FF000FFFFFFF000000FFBE
+:107CB0000000FF000000FF000FFFFFFF0000FF00BB
+:107CC0000FFFFFFF000000FF0000FF000000FF00AB
+:107CD0000FFFFFFF0000FF000FFFFFFF000000FF8E
+:107CE0000000FF000000FF000FFFFFFF0000FF008B
+:107CF0000FFFFFFF000000FF0000FF000000FF007B
+:107D00000FFFFFFF0000FF000FFFFFFF000000FF5D
+:107D10000000FF000000FF000FFFFFFF0000FF005A
+:107D20000FFFFFFF000000FF0000FF000000FF004A
+:107D30000FFFFFFF0000FF000FFFFFFF000000FF2D
+:107D40000000FF000000FF000FFFFFFF0000FF002A
+:107D50000FFFFFFF000000FF0000FF000000FF001A
+:107D60000FFFFFFF0000FF000FFFFFFF000000FFFD
+:107D70000000FF000000FF000FFFFFFF0000FF00FA
+:107D80000FFFFFFF000000FF0000FF0000001000D9
+:107D900000002080000031000000418000005200FF
+:107DA00000006280000073000000838000009400E7
+:107DB0000000A4800000B5000000C5800000D600CF
+:107DC0000000E6800000F7000001078000011800B5
+:107DD00000012880000139000001498000015A009B
+:107DE00000016A8000017B0000018B8000019C0083
+:107DF0000001AC800001BD000001CD800001DE006B
+:107E00000001EE800001FF0000000F8000007FF8FD
+:107E100000007FF8000005F60000350010000000AB
+:107E2000000028AD000029180000291900000005F5
+:107E3000000000060001000100090206CCCCCCC9FC
+:107E40007058103C0000FF00000000000000FF0020
+:107E5000000000000000FF00000000000000FF0024
+:107E6000000000000000FF00000000000000FF0014
+:107E7000000000000000FF00000000000000FF0004
+:107E8000000000000000FF00000000000000FF00F4
+:107E9000000000000000FF00000000000000FF00E4
+:107EA000000000000000FF00000000000000FF00D4
+:107EB000000000000000FF00000000000000FF00C4
+:107EC000000000000000FF00000000000000FF00B4
+:107ED000000000000000FF00000000000000FF00A4
+:107EE000000000000000FF00000000000000FF0094
+:107EF000000000000000FF00000000000000FF0084
+:107F0000000000000000FF00000000000000FF0073
+:107F1000000000000000FF00000000000000FF0063
+:107F2000000000000000FF00000000000000FF0053
+:107F3000000000000000FF00000000000000FF0043
+:107F4000000000000000FF00000000000000FF0033
+:107F5000000000000000FF00000000000000FF0023
+:107F6000000000000000FF00000000000000FF0013
+:107F7000000000000000FF00000000000000FF0003
+:107F8000000000000000FF00000000000000FF00F3
+:107F9000000000000000FF00000000000000FF00E3
+:107FA000000000000000FF00000000000000FF00D3
+:107FB000000000000000FF00000000000000FF00C3
+:107FC000000000000000FF00000000000000FF00B3
+:107FD000000000000000FF00000000000000FF00A3
+:107FE000000000000000FF00000000000000FF0093
+:107FF000000000000000FF00000000000000FF0083
+:10800000000000000000FF00000000000000FF0072
+:10801000000000000000FF00000000000000FF0062
+:10802000000000000000FF00000000000000FF0052
+:10803000000000000000FF00000000000000FF0042
+:10804000000000000000FF00000000000000FF0032
+:10805000000000000000FF00000000000000FF0022
+:10806000000000000000FF00000000000000FF0012
+:10807000000000000000FF00000000000000FF0002
+:108080000000000000000001CCCC0201CCCCCCCC24
+:10809000CCCC0201CCCCCCCCCCCC0201CCCCCCCC4A
+:1080A000CCCC0201CCCCCCCCCCCC0201CCCCCCCC3A
+:1080B000CCCC0201CCCCCCCCCCCC0201CCCCCCCC2A
+:1080C000CCCC0201CCCCCCCC00000000FFFFFFFFE9
+:1080D000030303031342020250505020706080508B
+:1080E0000200020006040604000E0000011600D67D
+:1080F000002625A0002625A0002625A0002625A0D4
+:1081000000720000012300F3002625A0002625A010
+:10811000002625A0002625A00000FFFF000000008B
+:108120000000FFFF000000000000FFFF0000000053
+:108130000000FFFF000000000000FFFF0000000043
+:108140000000FFFF000000000000FFFF0000000033
+:108150000000FFFF000000000000FFFF0000000023
+:108160000000FFFF000000000000FFFF0000000013
+:108170000000FFFF000000000000FFFF0000000003
+:108180000000FFFF000000000000FFFF00000000F3
+:108190000000FFFF000000000000FFFF00000000E3
+:1081A0000000FFFF000000000000FFFF00000000D3
+:1081B0000000FFFF000000000000FFFF00000000C3
+:1081C0000000FFFF000000000000FFFF00000000B3
+:1081D0000000FFFF000000000000FFFF00000000A3
+:1081E0000000FFFF000000000000FFFF0000000093
+:1081F0000000FFFF000000000000FFFF0000000083
+:108200000000FFFF000000000000FFFF0000000072
+:108210000000FFFF000000000000FFFF0000000062
+:108220000000FFFF000000000000FFFF0000000052
+:108230000000FFFF000000000000FFFF0000000042
+:108240000000FFFF000000000000FFFF0000000032
+:108250000000FFFF000000000000FFFF0000000022
+:108260000000FFFF000000000000FFFF0000000012
+:108270000000FFFF000000000000FFFF0000000002
+:108280000000FFFF000000000000FFFF00000000F2
+:108290000000FFFF000000000000FFFF00000000E2
+:1082A0000000FFFF000000000000FFFF00000000D2
+:1082B0000000FFFF000000000000FFFF00000000C2
+:1082C0000000FFFF000000000000FFFF00000000B2
+:1082D0000000FFFF000000000000FFFF00000000A2
+:1082E0000000FFFF000000000000FFFF0000000092
+:1082F0000000FFFF000000000000FFFF0000000082
+:108300000000FFFF000000000000FFFF0000000071
+:108310000000FFFF00000000FFFFFFF3318FFFFFB1
+:108320000C30C30CC30C30C3CF3CF300F3CF3CF391
+:108330000000CF3CCDCDCDCDFFFFFFF130EFFFFFF3
+:108340000C30C30CC30C30C3CF3CF300F3CF3CF371
+:108350000001CF3CCDCDCDCDFFFFFFF6305FFFFF5D
+:108360000C30C30CC30C30C3CF3CF300F3CF3CF351
+:108370000002CF3CCDCDCDCDFFFFF4061CBFFFFFEB
+:108380000C30C305C30C30C3CF300014F3CF3CF323
+:108390000004CF3CCDCDCDCDFFFFFFF2304FFFFF2E
+:1083A0000C30C30CC30C30C3CF3CF300F3CF3CF311
+:1083B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF22
+:1083C0000C30C30CC30C30C3CF3CF300F3CF3CF3F1
+:1083D0000010CF3CCDCDCDCDFFFFFFF731EFFFFF3C
+:1083E0000C30C30CC30C30C3CF3CF300F3CF3CF3D1
+:1083F0000020CF3CCDCDCDCDFFFFFFF5302FFFFFCF
+:108400000C30C30CC30C30C3CF3CF300F3CF3CF3B0
+:108410000040CF3CCDCDCDCDFFFFFFF3318FFFFF2F
+:108420000C30C30CC30C30C3CF3CF300F3CF3CF390
+:108430000000CF3CCDCDCDCDFFFFFFF1310FFFFFD1
+:108440000C30C30CC30C30C3CF3CF300F3CF3CF370
+:108450000001CF3CCDCDCDCDFFFFFFF6305FFFFF5C
+:108460000C30C30CC30C30C3CF3CF300F3CF3CF350
+:108470000002CF3CCDCDCDCDFFFFF4061CBFFFFFEA
+:108480000C30C305C30C30C3CF300014F3CF3CF322
+:108490000004CF3CCDCDCDCDFFFFFFF2304FFFFF2D
+:1084A0000C30C30CC30C30C3CF3CF300F3CF3CF310
+:1084B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF21
+:1084C0000C30C30CC30C30C3CF3CF300F3CF3CF3F0
+:1084D0000010CF3CCDCDCDCDFFFFFFF730EFFFFF3C
+:1084E0000C30C30CC30C30C3CF3CF300F3CF3CF3D0
+:1084F0000020CF3CCDCDCDCDFFFFFFF5304FFFFFAE
+:108500000C30C30CC30C30C3CF3CF300F3CF3CF3AF
+:108510000040CF3CCDCDCDCDFFFFFFFF30CFFFFFE3
+:108520000C30C30CC30C30C3CF3CF3CCF3CF3CF3C3
+:108530000000CF3CCDCDCDCDFFFFFFFF30CFFFFF03
+:108540000C30C30CC30C30C3CF3CF3CCF3CF3CF3A3
+:108550000001CF3CCDCDCDCDFFFFFFFF30CFFFFFE2
+:108560000C30C30CC30C30C3CF3CF3CCF3CF3CF383
+:108570000002CF3CCDCDCDCDFFFFFFFF30CFFFFFC1
+:108580000C30C30CC30C30C3CF3CF3CCF3CF3CF363
+:108590000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9F
+:1085A0000C30C30CC30C30C3CF3CF3CCF3CF3CF343
+:1085B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF7B
+:1085C0000C30C30CC30C30C3CF3CF3CCF3CF3CF323
+:1085D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF53
+:1085E0000C30C30CC30C30C3CF3CF3CCF3CF3CF303
+:1085F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF23
+:108600000C30C30CC30C30C3CF3CF3CCF3CF3CF3E2
+:108610000040CF3CCDCDCDCDFFFFFFF3320FFFFFAC
+:108620000C30C30CC30C30C3CF3CF300F3CF3CF38E
+:108630000000CF3CCDCDCDCDFFFFFFF1310FFFFFCF
+:108640000C30C30CC30C30C3CF3CF300F3CF3CF36E
+:108650000001CF3CCDCDCDCDFFFFFFF6305FFFFF5A
+:108660000C30C30CC30C30C3CF3CF300F3CF3CF34E
+:108670000002CF3CCDCDCDCDFFFFF4061CBFFFFFE8
+:108680000C30C305C30C30C3CF300014F3CF3CF320
+:108690000004CF3CCDCDCDCDFFFFFFF2304FFFFF2B
+:1086A0000C30C30CC30C30C3CF3CF300F3CF3CF30E
+:1086B0000008CF3CCDCDCDCDFFFFFF8A042FFFFFBB
+:1086C0000C30C30CC30C30C3CF3CC000F3CF3CF321
+:1086D0000010CF3CCDCDCDCDFFFFFF9705CFFFFFE5
+:1086E0000C30C30CC30C30C3CF3CC000F3CF3CF301
+:1086F0000020CF3CCDCDCDCDFFFFFFF5310FFFFFEB
+:108700000C30C30CC30C30C3CF3CF300F3CF3CF3AD
+:108710000040CF3CCDCDCDCDFFFFFFF3320FFFFFAB
+:108720000C30C30CC30C30C3CF3CF300F3CF3CF38D
+:108730000000CF3CCDCDCDCDFFFFFFF1302FFFFFAF
+:108740000C30C30CC30C30C3CF3CF300F3CF3CF36D
+:108750000001CF3CCDCDCDCDFFFFFFF6305FFFFF59
+:108760000C30C30CC30C30C3CF3CF300F3CF3CF34D
+:108770000002CF3CCDCDCDCDFFFFFF061CBFFFFFDC
+:108780000C30C30CC30C30C3CF3CC014F3CF3CF34C
+:108790000004CF3CCDCDCDCDFFFFFFF2304FFFFF2A
+:1087A0000C30C30CC30C30C3CF3CF300F3CF3CF30D
+:1087B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF1E
+:1087C0000C30C30CC30C30C3CF3CF300F3CF3CF3ED
+:1087D0000010CF3CCDCDCDCDFFFFFFF731CFFFFF58
+:1087E0000C30C30CC30C30C3CF3CF300F3CF3CF3CD
+:1087F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF21
+:108800000C30C30CC30C30C3CF3CF3CCF3CF3CF3E0
+:108810000040CF3CCDCDCDCDFFFFFFFF30CFFFFFE0
+:108820000C30C30CC30C30C3CF3CF3CCF3CF3CF3C0
+:108830000000CF3CCDCDCDCDFFFFFFFF30CFFFFF00
+:108840000C30C30CC30C30C3CF3CF3CCF3CF3CF3A0
+:108850000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDF
+:108860000C30C30CC30C30C3CF3CF3CCF3CF3CF380
+:108870000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBE
+:108880000C30C30CC30C30C3CF3CF3CCF3CF3CF360
+:108890000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9C
+:1088A0000C30C30CC30C30C3CF3CF3CCF3CF3CF340
+:1088B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF78
+:1088C0000C30C30CC30C30C3CF3CF3CCF3CF3CF320
+:1088D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF50
+:1088E0000C30C30CC30C30C3CF3CF3CCF3CF3CF300
+:1088F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF20
+:108900000C30C30CC30C30C3CF3CF3CCF3CF3CF3DF
+:108910000040CF3CCDCDCDCDFFFFFFFF30CFFFFFDF
+:108920000C30C30CC30C30C3CF3CF3CCF3CF3CF3BF
+:108930000000CF3CCDCDCDCDFFFFFFFF30CFFFFFFF
+:108940000C30C30CC30C30C3CF3CF3CCF3CF3CF39F
+:108950000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDE
+:108960000C30C30CC30C30C3CF3CF3CCF3CF3CF37F
+:108970000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBD
+:108980000C30C30CC30C30C3CF3CF3CCF3CF3CF35F
+:108990000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9B
+:1089A0000C30C30CC30C30C3CF3CF3CCF3CF3CF33F
+:1089B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF77
+:1089C0000C30C30CC30C30C3CF3CF3CCF3CF3CF31F
+:1089D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF4F
+:1089E0000C30C30CC30C30C3CF3CF3CCF3CF3CF3FF
+:1089F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF1F
+:108A00000C30C30CC30C30C3CF3CF3CCF3CF3CF3DE
+:108A10000040CF3CCDCDCDCDFFFFFFFF30CFFFFFDE
+:108A20000C30C30CC30C30C3CF3CF3CCF3CF3CF3BE
+:108A30000000CF3CCDCDCDCDFFFFFFFF30CFFFFFFE
+:108A40000C30C30CC30C30C3CF3CF3CCF3CF3CF39E
+:108A50000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDD
+:108A60000C30C30CC30C30C3CF3CF3CCF3CF3CF37E
+:108A70000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBC
+:108A80000C30C30CC30C30C3CF3CF3CCF3CF3CF35E
+:108A90000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9A
+:108AA0000C30C30CC30C30C3CF3CF3CCF3CF3CF33E
+:108AB0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF76
+:108AC0000C30C30CC30C30C3CF3CF3CCF3CF3CF31E
+:108AD0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF4E
+:108AE0000C30C30CC30C30C3CF3CF3CCF3CF3CF3FE
+:108AF0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF1E
+:108B00000C30C30CC30C30C3CF3CF3CCF3CF3CF3DD
+:108B10000040CF3CCDCDCDCD000C0000000700C003
+:108B200000028130000B8158000202100001023067
+:108B3000000F024000010330000C0000000800C0DC
+:108B400000028140000B8168000202200001024007
+:108B500000070250000202C00010000000080100DF
+:108B600000028180000B81A8000202600001828067
+:108B7000000E829800080380001000000001010030
+:108B80000002811000090138000201C8000101E85B
+:108B9000000E01F8000002D8CCCCCCCCCCCCCCCC94
+:108BA000CCCCCCCCCCCCCCCC00002000CCCCCCCC15
+:108BB000CCCCCCCCCCCCCCCCCCCCCCCC0000200005
+:108BC000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCE5
+:108BD00004002000CCCCCCCCCCCCCCCCCCCCCCCCE1
+:108BE000CCCCCCCC4100200003030303034202029F
+:108BF0005050502070608050131313131342121200
+:108C000050505020706080500301020000000000AE
+:108C100000000000000000001F8B080000000000A2
+:108C2000000BFB51CFC0F0038A0F093230688A2055
+:108C3000F8C4E05C760686751C0C0C5BB849D3075B
+:108C4000C32C0C0C0CDA4CE4E905E1FBBC0C0CAFBA
+:108C50008098850F559C871342FF015AC0C7CAC030
+:108C6000A0C1865DFF3A35043B408581A11C88D9AF
+:108C7000941818CC5411E2D2EA0C0C3380FC04A8EE
+:108C8000D81D201DAB46BE9B47F1E0C1378D51F981
+:108C90005B0DA169012A7E0B4D7E1B54BE4A074223
+:108CA000DF36C66E6EB50E71F69FB546E5AFB4C63B
+:108CB000AFFEAE3D2AFF209AFAAD503E00C5D55B0F
+:108CC000A7D8030000000000000000000000000022
+:108CD0001F8B080000000000000BED7D7F7C14D589
+:108CE000B5F8999DD9D9D9CDEE6608096C20E02454
+:108CF000861AFB82DFE577A841878034B63CDF8A9D
+:108D00005AD3D6F6BB506C551456BF3EE1F56933C5
+:108D1000F941122262049FDAD61F2B554BFB6C8956
+:108D2000942AAD3FDE024AF1F5C743AAD5D7A22F58
+:108D3000FE80AA455FC4D2D87E51DE3DE7DEC9CEB3
+:108D40004C76930DD01F7FBCF081E1CEDC1FE79EF7
+:108D500073EE39E79E73EE8DEA0BC2C7CE05388EEF
+:108D60003FECD913028059D9A771F5BCAEBE99006A
+:108D70004721D2D35D0AD0A68009AC6C1D88A41F00
+:108D800094007F6A14565E2D7F3CDE5D097067D1CA
+:108D9000D7EEC3FA6B2C0502ECD9DD0C9039837D3C
+:108DA0000F453743314011A4B6E277F6937890F53A
+:108DB00037109C9C866876FC32F0D1B80015FAA179
+:108DC00022AA07C765F6CF81E47C18072083FDB38C
+:108DD000067A593FCAF3721AC795E5C5FA8B55D979
+:108DE0007EBC4F595721A389FEF01FF9B2E26438C7
+:108DF0007FFD35072AB73E5D93AD7F06444A0FFDE0
+:108E00001DFB8F020AC123AF07C4C3D130A4E5CA3A
+:108E1000FCFD0C341B5B9FF6231EBF509C989ABF31
+:108E20009E8DA7AE668D9E1DCD3A6402000C64B384
+:108E3000B7963DC3606EAE1DDA6E0148842FCDB08B
+:108E4000089EF6B02F5D5489502701187EFD881FBB
+:108E500009DF2FD1CC1CEDED279432FCD8F36578D7
+:108E60000C02EF0FD8FC1E64FD0571FC1CF8BA085B
+:108E7000C72F63DFAB878E6FCD3CF1F1436702EC08
+:108E80000B23BE4D84017C7A0AE282DE9F9486E940
+:108E900047D05931783F23E1BDA8C6971D97FD0DF6
+:108EA0001A21179F0462256EBEF1F225E2A90CE992
+:108EB0006548AF4FC9F6AB22DD72E0EB4A81AFFEE9
+:108EC000F989A604C3C7DA66B05E73B4936360A67B
+:108ED00073E069B568678FA794B27A39FA076811A9
+:108EE000EBC772D52F14BE9B4E10BE9BFF42F0DD28
+:108EF00026F89D49287AF6CF4F129CDEFE72AD2FE0
+:108F0000B68807CB21256DF990BF4B21FE207BF859
+:108F100035BECEECEFDF073FF5B303250E1BA74DA3
+:108F2000C0D73F9FCBBFB5D3D4F46689E4910BCEB5
+:108F300087517EB1769224F0A1F502F25FD1070A43
+:108F4000C05884CF844404605D7583369CFC015D09
+:108F5000F9539FCD775543F9EEE36C18842B14CE6B
+:108F60008DA7EF0FCAD1CBACD7583F5A90BD3F1D4C
+:108F7000FB2D8D55CC069C1DFDF8C577907CF271BC
+:108F80005CB7C758BDD942CECAD43FC911A8009218
+:108F9000F7B2A84FE3B0FA01362D733A7BE2FB1A21
+:108FA000318E34B45F6FBB0128E1F811F0D8725DE7
+:108FB0008627A89F41789404E1CBFBDECFDEEBE16E
+:108FC000937F7FB265BF9167BC1E89F869A4F6AF35
+:108FD000087E19C29F79E8BA5FAC33057A4D383DF7
+:108FE000CB47367F9D281F9D349FB0E1495FE4E168
+:108FF000130B52B46E5835AB7BDAE8F925079F6442
+:109000009CF5174B63F83C9438F10B834721BED590
+:10901000393C65D34BA93F09D7F819D88328231EBB
+:10902000D87C97D9ED214EEB3584768EA33D9B1CE1
+:10903000C12BC99290FBBCDE0D629DCF6BA8E0F006
+:1090400083E8DF032FEB4F73F627438587CF39DCA7
+:109050001B242EDF58FD0CE1D33BBE2211BC322471
+:109060002C1F6BB7598CEF955FF673BBE86FBD048F
+:109070004DBD61BE9E9638F4618324E484C6D799C1
+:10908000573EF991AF669C385F152AD7174BB9F553
+:109090000EB38A621746F2EB9D629FAD0F323141EB
+:1090A000B751D1FD74A9C445F742E15D7682F04E17
+:1090B0001C0A6F417C76A6E41B959EBCE104E10B83
+:1090C0007AE03B557C3D43F059A1F0DBEB60B4F016
+:1090D000CB43F15BD03A9A3B4AF8369F207ECB7C5B
+:1090E000B69D24E0CBB36EE7097A5BC0F9436176A5
+:1090F00038EE730A85EFD191E103F804FB6BBD6A8A
+:10910000990AD96B0013009E6E79D5B2942C7C26F7
+:1091100070B93EDAF1F78C4C3F31FE5B96599D1DDC
+:10912000FFF996B75CE32B8C7F90D90A1DF7854237
+:10913000E70DEFB9E6FDBAF49E6BDC13C5FBC18207
+:10914000C7FFA36BDEEF4B7F74CF3BCCE67D7AE1AC
+:10915000E3FEFE04F9B152AC97064977E9817CF64B
+:10916000FB0C41D7BBEDFA36BC79EA9F29E06A2FA8
+:10917000B0FE44D1FFE70AACDF2BFAEFC5FA652356
+:10918000D73F5DD44F15585FF2F175984F7FCE975A
+:109190006CFC816BFFD1A6713F88D9A640F09CA1E1
+:1091A0007E13AB21F5ED3E467BAB35A0B79592DF44
+:1091B00084FC226B0012E837F92624EB7CAC1F6399
+:1091C000C74DF761BD238AA677EBC01724FB1E3C71
+:1091D00010D9DC5D991D6FB59C6C929097DAA2FA5C
+:1091E00083E45F493549EC59668575F4DB0C5425F9
+:1091F0005A9696E23C0CDD62FDFCFA8A8B76627927
+:109200009326E9322BFFCB39736FFB0C6B35F0E102
+:10921000CE974EC37AD3C655B592BC3425C44F6998
+:109220005C35E5287B5E7C71561FE03F8B1D6566D3
+:10923000077CB6E9122EFFC5F7CF27DDE54B1A2FC5
+:1092400071B5BF34E1FE9E9D0FF07DC7B9DCFF30E4
+:109250005095FA2F0ED7C72A2DEE5FA0F9EA565483
+:10926000EF66F35CFFE1B5545EDF52ABB7B2F2E7F5
+:10927000AEF4B72C65CFB004BACC9652715CA5F9A8
+:10928000029BAF5AC7768FE73CDB35DBC8BFFF2AAE
+:10929000363DF38C5F9C8593CDB3E9EADC70ABFA85
+:1092A000FB13DE60F6D2C0CEA089F084F7CAE9A035
+:1092B0004474DD3909E9621527397D40AA66CF2358
+:1092C0008D3AA07FA4A13169C8ACBC31A6C5030604
+:1092D000DAC9190DF11E411ACC65EFE3BE20DA633D
+:1092E000AAFE07EA5F17DF7BE255E3D13FF2E3E630
+:1092F000351315B6DE77345BF47CB4B98B9EDB9BFB
+:109300007B262ACC88DFD27C173DEDF9A12431ECF5
+:10931000F9C9B8AF365B91DF06FCCC34423CCEF7DE
+:10932000D1FE7603CA113FCAE1745B14DFD7C1B422
+:109330006E40B9C4E5CBC6F8B6DDF87E633D4C435C
+:10934000926D3437B745D93CAE2B87E9D8F7CE9725
+:109350001FE3DF2B607A8095773536905CED89FBD3
+:10936000D2814A82FF7CE4E79E461F3093078AEB56
+:10937000185C0EBC0662EEF2AE4626B066123ED215
+:1093800001293B7F852D33C4C746B32AE8DC57CF7C
+:10939000DAE76E7F66DA5DDE88ED87F14BCDED733F
+:1093A000D79FF392BBCC24DB2B837CC0F1F8AF3E7C
+:1093B000260F76BF3CDE67E1BC4D3E4FF6E4FEC2B1
+:1093C000982F8DC6E716813F1BBF03112E5F3636DF
+:1093D000733F603E78367EEAAAD8707E03B5B1232B
+:1093E00081FE54B5B1270167E1332D9EBD09A79FCA
+:1093F000D57EBE88C68FC35FD211DB58B2B4360BA0
+:109400008FB7FE785925793750C6BF77C45ED3979A
+:10941000D63AFB93BCDFB5CBC3CEEFDCAF32506E98
+:109420007F3FA22D0DE7683F897DCF4197A532FF91
+:10943000FEF4CB81863B901F057E77BFFC13AD1AEF
+:10944000F1FDBC0CC8671BF73590BC453E4379B1B4
+:109450008BF1455F2DD27FFD2BCE755B5CE72E3304
+:10946000BEE2FCC5FAC5A17E86F4601DFEBBF0CB52
+:10947000EE157ED93DCD317A3EDD6CD07357730D3C
+:109480007DCF34C7A9FC54731D959F6836A9FCE3B2
+:10949000E6462AEF684E50F9D1E6267A6E6F4ED234
+:1094A000734BF315F464FC4BFCBCA13925FCC06B79
+:1094B0005CFCF0F7F1808BFF3E5DE32E9F6F9C918B
+:1094C0005DD7ECEF2763EEF279FA275DE5059ABBED
+:1094D0003C1FBEE2EAEFDC0FBEEC2ACFEBEF70D50B
+:1094E0003FFB4D77796EDF439EF5E22ECFDAB7C7AB
+:1094F000B31EDDE5E2BA43AEFE023177F97E1432E7
+:109500005C4E117F74C45A4B72F2CFE0F78DA12FDD
+:10951000B9BECBD47E64FE59D65589FC93F6C52DD1
+:10952000943B26E7275BEE78F9C4A6DB48FC65C3CD
+:10953000F197E6ABFFE5A7E1F9A9607EA85772F2C3
+:109540008397EE5EFE18226704BFFC2F1FFC6DF0B0
+:1095500001CC64C42ECFAF5773D877649F061240F6
+:10956000F69D1FED34477B75722A69E6D09F57F947
+:10957000E66F95593F8152E8C0786840C9E3E795A6
+:10958000F93E25A0F1EFC16A93ECB26230A6CB633D
+:1095900000AE796C5EF932F6FEE7421F765C089603
+:1095A000C4FA1B37414DE23EA6B8DABDDF7B46E682
+:1095B000FB18FBB9E9879126FC0EA5334798378F36
+:1095C000D7C8136737FDC660CF0B666F59CBDE86F1
+:1095D000AA9319F2019596927D9A0C19D4AF5997D6
+:1095E000B67CA518478338DA8972D884241B67AE05
+:1095F000CFFC05CE9BD947FF21CFCADA3D9BC4F3F0
+:1096000047621D5EE4337F29EA3D3F5C3D7BDC1110
+:10961000E905494BE2FEA9F8830C447F69DC653F0C
+:10962000D9F353948499C8616FFC4EE04BD2E34D5B
+:10963000DC0FA202CA877CF50FCAB6FFC972ED071C
+:109640008BA13F23231C311E6F82631719174E1DF8
+:109650000A87AA2492380EC6AB37B371DAC77CC624
+:10966000483AC6F948E67E2A2966123CAACEE1515C
+:1096700095B899C8C14703021EBB1F3B6E26C5FAA9
+:10968000A12F9C856F6D30D184FB256B8C4A786A45
+:109690008FB8EDAF190AEFA75A3CDBFDB9ED438057
+:1096A00056BE1F1E57A761FF6D750D1ADAD78C1DA8
+:1096B00068BFD21E5E523C9CBDBD5ED8BFDD280F88
+:1096C00003180FD785BC8AD1B33DBCAD11D7C1D12A
+:1096D0005A8687CAFCFD44E2EEB86E514DC813C7E6
+:1096E0004D139C41A3C413EF9DE06AE71FA7F8EC5C
+:1096F000B8364823C3DF21E0B7EB752A294DCF895F
+:10970000273EBE5D0EC4DCF0FEF9F0C7DB17F97B27
+:10971000F55C709D2ABCE58BC3DA4F75AC9A4A7331
+:109720007F4ACCB90E3E2BF84B1DABA5483E69F9DC
+:10973000BE8778FB7082FC5B5A38614055361EABA1
+:10974000E17A70E0E95AD1EED78A4FACCB540CFDE8
+:109750005C92916A427ED22AD83A9286B6B39F49E9
+:10976000D1BEF3C3FFF712AD93328DD68964B075C5
+:1097700094631C4931AF56D8F31DD9BC46C1F8CC0F
+:10978000477232D77A5921E0D116270CAD8A427838
+:109790003CDFC303C73A85EB834336FC568AFC564D
+:1097A00085C2BFA640F8ED7118FCED02FEB5C3C13D
+:1097B000DF26E02901A3857C990697B300171ACE0E
+:1097C000BC8B37C4F825424E314C11DDECEFFF2540
+:1097D000FA29743E1B059C23CDE78D2C3DEEC579FF
+:1097E000B0F9DC87F3CA379F7B041C6F285CCF6815
+:1097F000898411AB22559F93AF9E1070F42B228E5B
+:10980000665D3B2ABEFAD702E7F144962E8F09BA6D
+:10981000EC186E1E8F8A79F4C830F70DF4339E2E43
+:10982000F40E2C71D1E5A8C04F4FC0A6CB752EBA4F
+:10983000FC4ECCABD0F93C53209F1DCDD2E5393145
+:109840009FFDC3CDC751FF4551FF25519FFCE74701
+:10985000952B5AAD5AFC9E38A0CCCA8EC7EABDECF7
+:10986000AC776DFB2CBBDEABC80F5223D783ACDECD
+:109870006BCE7A605DD08AF6DB5A8C897E02E081FD
+:10988000F6AF3688766F52BBC583FDBF25D607B5C8
+:109890005BD73EBFD50A53BD77F07DCB828FEC7A84
+:1098A000EFBAE15D61C37184E04D0CC2F1BEB3DE7D
+:1098B00013CAE7A9BF217947B19282EC1F7F699251
+:1098C000F2F74A20D283FEC50E2545FE640C36A071
+:1098D0001F7275204EA92A23F9A3CB2EE6ED7445FD
+:1098E000237F6A005270177BBFA154A1F8C862257C
+:1098F00019F1A31D21252D0AAE827E590BF63FD604
+:10990000A0FC2F1B9EDB8ABED845FD3078B0DF3B24
+:109910008BA23B91AF364E520DE4AB9D936E20BFB0
+:10992000F96D2D3C7FF0B6F355DA676D7A3942FA5E
+:1099300077AD12FF2CD6B74CD5403FFAEAD0472F6F
+:109940002D67E5BE96625D3A87E641705B3E48B49E
+:10995000CD74E42332B80371CAA7233FDC6D8D3C7C
+:10996000AEC37ECAB1FDEA0546BCDB40F1C5E418D2
+:10997000FBDE59A792FD7A5B45D57C1C6F539D4653
+:10998000F6C6A6C5552DE4C7AB0B91BFB2246C48F3
+:10999000E8678FCE519901CECAA5460BDA9B91D9C3
+:1099A0002140BF5349051F2F7206901FCA0F3D89E2
+:1099B0006AF68C76A990198BFD2DC97C09ED99BAB0
+:1099C00000F9E1D9C4F6D78EA39437FE23FF0C101B
+:1099D0001EFF441910EF367DA33D83ED87CD638CC8
+:1099E000A60BAC9729AC5EA44B81CC8C02EAF51493
+:1099F000582F5D60BD0CAF17800B87CDE78338CF44
+:109A000023D4D81F9EC7E8C82BACE4F6BBD36EF1B5
+:109A10007BBE8F362FF42ABFC80B9D0373785EE898
+:109A2000F0EDED7CD091E60BE0CBC2298F5C7F6D31
+:109A3000F3F07E63FFB81B62987FD959F655F1BCED
+:109A4000913FCBC5FBF2353194779DE5E27BF98DF3
+:109A50004DB9F6AF77FAB91CAE81C4B0742811F0D5
+:109A60001F62B0637E4F8DC2EA47F2D7574B7DC36A
+:109A7000E6596A8AD540EB76B18FD66D008501AE86
+:109A80009B0ABE8EFD904A54F37855B4DCB17EFC3F
+:109A9000F57B68FDFCA25C06A98EE813473C7AF9C9
+:109AA000C4CB170170942B4F9E4FB6FE99F8C4DFBC
+:109AB0002517B47EFC3D05D64B17582F53583DB59E
+:109AC0004B2A48AEA83D05D64B17582FC3EBAD9D8A
+:109AD000AB727D0E7F68C578BFFF139AABBCF613DF
+:109AE00021F7F7B3C3AE72C72C777B75B6BB7DC7C2
+:109AF0006C777B750E6F1FEC800518CF2F749D1C43
+:109B00003CC17552A30D5F3F5237C2BAD2F420B6A2
+:109B10002F510CC89492BE4A0BBD95331E7E9ACA33
+:109B2000D77F959FC7CF6F53F420EE23FFD6E72949
+:109B3000A93C9FC09EEF48F0DAF2F7B7B2B0B7F297
+:109B4000E47D438C9F7FF043288E768EB1506B78F6
+:109B500085E1D1FF2CCF7BF7F6FB8A9A9CA63AF6DB
+:109B6000C5CC3E83A4C30F737E99C2F36D181DD07C
+:109B70001E5221D158C9FA6BABF0913DA28447D057
+:109B80001B150EB995232F2FEB970213CF53D02718
+:109B90000360FE9B7CDC501C08EE08F4D166BA180A
+:109BA00053E54E07180386C493BEE212CF13ACD719
+:109BB000519E95064F75BF9751BF92791B1C2F1A66
+:109BC00045BF4A1FE5CB9CF27E478037087753BFDD
+:109BD0006C97547A7C6CB65F7F2C452F314F56764C
+:109BE000E4CBE1B908CA37F1C53394DF30214AFB31
+:109BF000B2B5A5D7B9F2C1FF59AD72F98754BDE32B
+:109C00005A09E3BA15579B7DC3F079331357E4F72C
+:109C1000AC586EF6D5E4AF3798A78FF99E39D64188
+:109C2000879A4CA3FD6E4D0EF3FDBC92227F63A775
+:109C300054321DF32DEC7A4A0593B40CAEC84CD3C4
+:109C4000C2FD5EE7585F1CED5405D6EF93CE62ED82
+:109C5000E4C571A7FFD2FB542A94B79DF3B95D65A3
+:109C60007A12E1147AB26D047E1FD1EE51E3C95C21
+:109C70007ED16FAB7C5FEB0FE5FEDE176A78409D0F
+:109C800035146F8F217E717F3B06BAA4FFC3D9873D
+:109C9000F2A52AF6BC8478585BB62836DC7CD90657
+:109CA000EAF0205D18897F16321F4179300C1C3F85
+:109CB000CC0507840BF37FEB0BE3C48783F65229B3
+:109CC00088FD98199518DF870457DE32737306CF25
+:109CD00043F897864DA49F6C6E01F457DB76936C26
+:109CE000865EF5113DEBB9FD54C3ED2193FDC179BD
+:109CF00044EB87B7AB654FF939D56D0FB535EF003C
+:109D0000679E9BF75C85FD4C871A5ECC8D8FC2F6F3
+:109D1000C3B7337EC13CFB8DCD1A22057A9A752AD2
+:109D20006F688E51797DB341CFF6E61A7ADE8C4D9D
+:109D3000E7E2F9A7545725C35B57EC81D8E5ACCAD5
+:109D4000ED283B288FEFDE05682F770F96D93690E8
+:109D5000C1DD3D09785E9F7AEB02DCE7770741F8C9
+:109D600015DA16A05D9D2DDFD1361FCBC2CF10EACC
+:109D7000BC6F01EEF76F17F90FA098DA250EBD77CB
+:109D80005AC04FFC477B576A6FB5617F414594E1EC
+:109D90009105EE3298084F50E3E505816DD43F8977
+:109DA0000036DEA7033FE0E34D11F96DB54B46C029
+:109DB00023F7EF5BAAC1FD5DB525143F52E3717433
+:109DC000BFC2ED6304DC05F6034A92EB3B718E2FB4
+:109DD000FFBA1941AF093846A23F4307F9D1EDF365
+:109DE00069CA0BB9F5F4A91EF776FFE8F0A2D6F51B
+:109DF0005B7886ED09353927C0DA47CCDE4C252B58
+:109E00004717672C5ABE058E3B3660E7392669FD39
+:109E1000DB7856746E77ACF0D0D15FCAE3754171D0
+:109E2000FEA4507893AA1847F4030F37940F67AF36
+:109E300095257C68840DCA8BB18D21E19CE1E531CB
+:109E40006689AB5C5C37C1553F12AF727DF7EB1F83
+:109E5000777D3F513A5DE299C7A784DD6897CFF5DA
+:109E6000CEB3C07E0F1627560570DD34404D8AE113
+:109E7000F5CE2F3C44F80F0DAED385ED6605E58396
+:109E80008B753D8F9775FB7B5DBB59CFCA86FD7D7A
+:109E9000062F9BF6F738AF6FD9DFA7F2EF28F759F7
+:109EA000F96B9D67B45BF81D5AC96F0B152958E211
+:109EB000A0CFD8F10DAD08DFF8CBD2318BBDEFFECE
+:109EC00050E6F2007A62CE7A776ADC0FFDCC943BE2
+:109ED00062E8AF5C77E64331207927E58C07FE3CEA
+:109EE000C0F3C5CA42899E00AD77B3BF98F1E1A126
+:109EF000876483EB21E535D4873E8BE7E3AB10DF46
+:109F000067A25D54C3FDD521F19DE85899AD3F4846
+:109F1000574FF9EF34AED77F87491B0CCEEF159B17
+:109F2000F7D0B890961AD97AAFB0A01FCF1F81B0E2
+:109F3000FB26F2A6509A48939F6F12C3A7CCBE4F40
+:109F4000BEB8BFC5CF706D5CA6FB7089542D8FFB6A
+:109F500048C00DDA9163A5E3ECF93DA417CAE39B71
+:109F60005280FA7BED990F35215E02997F0283E1E1
+:109F7000ED1F27A5C040FF6F80C315B8AC07483E52
+:109F800057F7109EBDF85A3788F7B40BEF3F0970AA
+:109F90007F7E2CC9DB0DD65358BDA943EB75077BDB
+:109FA000E6AB68BF4DE178F48EF35E4012E776DDF4
+:109FB00070D8FD7AEBDF1210716D2D4DF18D67CEEB
+:109FC000BC21867EEDCE298CFEB5F9E97F4B80E77A
+:109FD0005B19C76E22B9DB3D6923C533D7556F26A0
+:109FE0007BF228B323F0FC747765EEF69DCD3C3F01
+:109FF000E65CB8BBB18AD1A7F37999FCB4DE7ADF0D
+:10A000000954B9E28D5A857B3FC8F8AF0FE5E8489F
+:10A01000FC27471EE0EB72947C8766213FCF50D629
+:10A020008EF6805F94EF0E1C6F13FA9FE47FF9F2B7
+:10A030001E70E64BBE2FF82213E0722658C1F9A31A
+:10A04000DB6F494EFAC5D8FBF98E76F9E8968F1F7B
+:10A050001E17EBE17D25DE44CA5F49E9B9E4B3127E
+:10A06000FBF42F173ACE7BB52B694D47F86B364A78
+:10A070004EBBF61B6632A439F627A1D805BF5C8813
+:10A08000FB1F259E739FFE29D38C6A6CFC9B9B61F2
+:10A0900046359E4B50AC00D6BB59C934D2BEA2DA6D
+:10A0A00047FEF27515D7EDC53C2BABD617C76A6DC9
+:10A0B00015BB1AAB0CE4976D9467FAA6BE2486FD17
+:10A0C0000462EA8CEAB194DF9DC079876B59BF0EB8
+:10A0D0007ADBE3DE2DF8F65BBA3959E3F2E034EDD2
+:10A0E0002F200FDE87788C1B590CCF39F65743F1A0
+:10A0F000CCF3043A2B86E0798EE6E0EB00E27906B9
+:10A10000C9FB9CFE0B86E7B35D780686E7A9593C40
+:10A110007757703C77D66CEEAA72E2B966D7DE4A02
+:10A1200003C7E7787E48E3E773438867079C5E3C94
+:10A1300087255BFF7CAC1DF9D6CBF70CEF7F8FF04A
+:10A14000D8EF3F0AFC82ECE1B1E313176AE43F4920
+:10A15000D1FEE94E29AF5EBA442B402F758A757443
+:10A16000A7C03FEBFF0BD47FA9E8DFD6B7421FFEA5
+:10A1700083F66F0B501FB27ACBA89E9EA27DF06033
+:10A180003D0B86D5A3ACDD95C447614FFF268C4AB5
+:10A190001FB37EAEA37E34CFF8069C949E67FDDE8F
+:10A1A00044FD2A9E7E4FB13DC1C6E926FC81070FC2
+:10A1B0007F663B2696F4F083D2E3927B363F942F62
+:10A1C00077D7CBAFD77AB85E1B6AD710DFFEBC73E8
+:10A1D000CF6EDC27BDA99BDF46BC8E761DD876608E
+:10A1E0005928B94DE376209D83B0BE51946E636DBE
+:10A1F00095E33D511E7F77EBA3F1B63D54CDF5407D
+:10A2000070947A699FB0D73AC6301955CC9EFE44F7
+:10A21000532E3FC3339A9DB7E6B69B7F8373243F8B
+:10A220005182FC6BEDB1CFECE863B4331B7B20971C
+:10A230009C4F86923FC7F9A9BA65927A15FE917C28
+:10A24000FD9626AC9D7B6792DCEDC7BC461072186C
+:10A250004D6BF4C74519DE0E69E4C288A37FADECEF
+:10A26000626B3ECAB10AC62F587F5CD33E29992B38
+:10A270003E6EEF7F10881CFB97719F9B9DA47CB85E
+:10A28000C53347D8DFB4D8F6EB6F715E87D49E0B29
+:10A29000A638F06ED3E90E2971E179284FE7713ABB
+:10A2A000158F924E03824EB098E7A19E7BEC5C8D99
+:10A2B000FC8B115F02FDF0417F8F5EE2E0A3713EF7
+:10A2C00048F68E02FE7AE8DF7D1CF77F611FED778E
+:10A2D000BBC3CBBE83F7EF58BA1A9F6264C7ED6663
+:10A2E000FABEC4A17FBCFEAAC17DF4E2C2F265A79A
+:10A2F000587328DE9FBD3FC89D7FC018AB06F3860C
+:10A3000056CBDC7F7E67D1D7280F618D15D003A592
+:10A31000A4C7C8FE5B27F2D93A453EDB5A91CFE687
+:10A32000B7566FC5FA9B0012E8976C9997A2787F91
+:10A3300054D1F4D638C2919A837A225A6AAFCF1F89
+:10A340002FC4F53958B6BED1DEC0E61B8DD9E58DD8
+:10A3500064BFB5B77079F3D9E00B0BAD7A64C53E35
+:10A36000A2C7A6BA25C5308C3F325CEBCE9F0B55F9
+:10A37000875C65ADA2C455564B270C1BB7F819FA7C
+:10A380008966E17CFA208E70E6C9179E12E476B6E3
+:10A390002C4FEBCF60BEC1D96A7CB381E7A8DD79D1
+:10A3A0009CED416E0F3E8A0E218AE30ABEA8E3713E
+:10A3B000D5A2B955BD180782319C2F304FD0C90F97
+:10A3C000F9F8E2AF8D1F5FD1E118E65DDCD21A0526
+:10A3D000CC73B965EEAFE21903E56A5F0CF333DACB
+:10A3E00098246965DF37CCFD9591CB9F7C404B2E3F
+:10A3F0000F22FEC209B2BF223393F4FC6BCF6B2451
+:10A400007ADE19E47A6E8AA0A782F49C99A5E7BA4D
+:10A410003A46CF99D975BE4EE9D10AA1E7F9387EFF
+:10A4200019CAA1FFA67DDBCD75BE46944306F45242
+:10A43000FEED865A9F0FFBFF6BE1C5862B3C97C94B
+:10A4400047A25326817A61435CF1A11CF99BE3C3C7
+:10A450008FFAE87D017CF8C35C7CB85CD0432EDACF
+:10A46000D7942BEF6E4A5072E1653DD28BE3A591F4
+:10A47000E3C5F757C1CBA0BED0922B916FAE88A990
+:10A48000B4EF564ABA3A285EC4F41EC61B56C8A694
+:10A4900081F126F8969FDFC7847ADBA15FFE180C56
+:10A4A00072FB445EBF88E2186C6AB82F63E58F0DBB
+:10A4B0001B0F4DFBFB9DF79478F3325E0BBAE31054
+:10A4C000472A961423BDF2F5F776F35E1DCFD5DA51
+:10A4D000F919DEEF2B6448E53AB72885346167F651
+:10A4E000AA84871B99AE9D86F8F8D8423C9FD9591B
+:10A4F000D13A8EEC1871AE61C5966775C501E70A51
+:10A5000085A9BFE943E763E37705AAC91247FBF4CE
+:10A510005E577B6FBBC1FE447B66B7F9430C3E536D
+:10A5200049EDC578B37D7E43DD323F436A330FDCAE
+:10A530008C8E270577A1E7388E3CD0D681FB6DB491
+:10A54000BF3EC1F8E4B78FC8F156F6F58ABBCF58C5
+:10A5500088E75A0F01E7179B3E6F3DD0362E175FF5
+:10A56000E4A3CF79A12087E714F3D759210F7FF512
+:10A570005E549C8153CF5F8BF3F197C0CFE15E8E29
+:10A580000FB86B6C4E3AE59BCF209DEC7682CFBC2A
+:10A59000EDF3B5637C95E07C95899E5D085F097855
+:10A5A0006DFA9D2CBC23F155608D6CE079AE4A2587
+:10A5B0004172B3B3F43A4BDCEB48F99E72CFB48CE2
+:10A5C000B8D74AE4B54306ED8940A949767448DC1A
+:10A5D000CFA355BBE5A612739F9B8835253276BF66
+:10A5E000E8BF0CAC5169DCC1F8711832C12896790A
+:10A5F0009C14C51FEE2B02F04DF27BB27639FD9E06
+:10A60000F65311F96A98CB4BF7B2C1E747C86F719F
+:10A610008F13BB78F8FC1A6F7D082BC62107DEF379
+:10A62000B753E090639FB341DC2B6AE3DFDCB29465
+:10A63000F2CA83E08BD3FE20D661E1BEAF43ACE724
+:10A640004E7CCEC573BCD375DAAF55F0788B257DC3
+:10A6500099FC0CF6B9337B3CFBBC995D6F24FAAFD7
+:10A66000C6F594637DEF0A717D3AF0B5D47FE33E81
+:10A67000C4FA1318780FC5E3CD1F509CFA9CCC5B2D
+:10A6800032FAF79F098DA37ECEE9EF931738D6E50E
+:10A6900039E21C0740AF9CEB9C97DF0AEC427E78C6
+:10A6A000EA30DF8F3D75F808D9E14FFDDE9746BEF1
+:10A6B0007BEA83E1F31E1E17FB22BBDEE3BFE7F656
+:10A6C000D9E34A6F512EFB2E3B7E9AEF070FBBF961
+:10A6D00015945E19F965E0A67D32FA071E6FD6A4BF
+:10A6E000D799FC9927E679CEE13E19F74D23CD6B3A
+:10A6F000AB87BEF63CB7D6737B746BFD9110FAFF47
+:10A70000B73EC1E77BB49E9F8FCD07EFAE669EDF5D
+:10A71000B1F589DCF86898C7F7C70D7EA334A75D4B
+:10A72000EB3967B54093DDE7BB4E317CBBEBB9DD60
+:10A73000B55B89874F049EBCEBBBAEA711DD08510A
+:10A740004836CE9708BDFB5D7E92035F6FF932E617
+:10A750006B2C0D9B12EE65A12FF3249B5789A92525
+:10A76000F0DE98E2FA1E6932E677C4781EF937AF58
+:10A770007E2DF3322BDFDC5444655D379E5B84F81D
+:10A7800028D5C99F72337A5C48407F732DE627D065
+:10A790007A64E5C0CD3DE7A13F4B012E2F98C56BF4
+:10A7A00028E3E85E3F72D2E4931BEC473A1EC8B63A
+:10A7B000CB3B4F4FDE6D00960C2FC796F3FA16FB7E
+:10A7C0008372A8C49367A22F74E7A5443DFD4F454B
+:10A7D0005BB5AC80BCF2931C670C6CD30CDC67D708
+:10A7E000FAF434D607630CE60D861B9981C4E83968
+:10A7F000460709CDE591F0BE0EA091FBBF33E03CCA
+:10A80000A7D350C4E5D584AB6E97709F7134CEB892
+:10A81000621A96DFCC997FD52EE4C76059DF45F2E6
+:10A82000B4037AF7525C20E9233BFCE6DAD631CE5A
+:10A83000F64B8B24DB1F28E80F86323B4B7F363FDD
+:10A840003378D65F8EFEB1E56EBC8F962ED714712D
+:10A85000793512FD4F761C9B6E43D7478BA0DB03E7
+:10A860001417EDAE195EEE0FA5DB36D277E1DADC18
+:10A87000F9BAD715492E796C3F3548419CF1892C9E
+:10A88000EE6796C7CF6EBA7F18F9233BEF67866CE9
+:10A890003FE38C1E13E356E3A1C7C473DF8CA7E329
+:10A8A0001940FE3601ED24661E111FC99EFDDC46CF
+:10A8B000C14741789EDAB35560E9A45752A03BF2F4
+:10A8C00054CE93C371F45FACD3C3742F12CA4F9E9E
+:10A8D000BFC3F3FC8B39480CBFFD80F22D542E838F
+:10A8E000857EBF7A01AFC4F80EF3FB0FBC7500F78D
+:10A8F0002BE1996E3A29078A28AF2DE43D2772E0B3
+:10A900009A6B687FE3A1E368F3FEBF5F24ECFF224C
+:10A910000893DD24DAE7CBDFB3ED7E1BBFC6B108B9
+:10A92000E5ED741C90081F659313F7E3FE0C7E257C
+:10A9300003CFCB0413F3F656FF74167D1F1A574846
+:10A9400054225DDE3A50A4B75616922F9948B6B0FD
+:10A95000FAC68140BCD520D5E2D3908E7D12D1516C
+:10A960001AA751BED6EA7FF7DF1F18265FCB8E3FAE
+:10A970000E96158BE29B5DC674CD294FCA42C95F06
+:10A980001639E3F622AEEBF5AF07C3EDB16760F41D
+:10A99000F18FD2F120E2F29F5F84F64B17AE019E59
+:10A9A0001747797A5DE5BCFC46D1944518DFE98A02
+:10A9B000F07271F8C8792D246713E4FF5BC3180E99
+:10A9C000F1087BFDE21E4963FC85C3C80BEFFCD791
+:10A9D0002BFB284FFE9EF0FEF3CF40FAC47DE48FA0
+:10A9E000BBE7FA6DAEFB93DED41BDE2FA2F5AAB750
+:10A9F000637C7A62D2CED774C74526A0D660F39B1B
+:10AA0000C408E3677838ED626845B6A9BCACB71CEA
+:10AA1000F7C96B4BB78DE1E7FD17EA87C86E972939
+:10AA20003E9D0F5EAF9D9E6FBE76BCDDDBFEAE0829
+:10AA3000BF47D51B17F3FA831E44FC9651FE2C60CA
+:10AA4000FE6CA7BF2F673CEA8D22EED76CAF5894FF
+:10AA5000B81CE7A598730F327CDC5B1AA57D90FFCC
+:10AA6000A2DA4B7D0E7BC3CE6753C47ECE5F9A22A3
+:10AA7000B9A86866D719182F7A5EC61505153D3B2B
+:10AA800025B4E7EDFB2010AD174FE5F3C579058040
+:10AA9000DBC5785EE1B863DE1073F8C1509E88FDB7
+:10AAA000DB29A0F7B4F0ACA1F49DDFC5F3D0635768
+:10AAB000F0F34D1395DCF41E7F99EEE3F1AF534BA9
+:10AAC000E77CEDF3C53DEF8AA8B47EA6E8ABF7E2DC
+:10AAD0003D771D567112E33103FE5417CAAB0DFFCB
+:10AAE000E883CD34FFD1E937454FD03D7A15297D34
+:10AAF0003A2EEF7CEDEE48ED0A129E2D9ECFE0FD42
+:10AB00007E7998EB9B9E94EF36FC6E3E9DDAE9C70A
+:10AB10007D678CEFABED7D783294BC3CECB0CF75AB
+:10AB2000D3223E9A92BC94E4C0405961F72F0CE2C4
+:10AB30002B4F1EF31D11AE97A718AB79BF9386F765
+:10AB4000CBDA78F9A04B16BF1721134438FC8C914F
+:10AB500013B82E6EE472E2EE35BBE8BD7263DF7CA3
+:10AB6000FEBDBF05F5EA1D3EB82297DFA82DC2E362
+:10AB70004193CDCC3AD41B93533E40FBF4F688412D
+:10AB8000EFC75FC6F1D43509E238EC69D81FFBCFB7
+:10AB90009E4A95F4D2D852A0FB92C6AE01D2DB6396
+:10ABA0006B206DB072D7CEB93BD1BE55AB218EAE06
+:10ABB000EBDD953758680F6CAA0013F5B8FF46B661
+:10ABC000C0587DD5F0A53150BC29B58CEE6959CB64
+:10ABD000D6255263ADD140F6C3D1182F072AF839D4
+:10ABE00098AE331582C3BE7F9CEC4EA61FFCB5FD0C
+:10ABF000265EFD65C015D48F7F2EA7AB71573D9D96
+:10AC000053EB1AF310DD4B635D033CDE69C7A515FA
+:10AC1000C65F6C9CF62BF49CFE9523A1E4B79DFCCB
+:10AC2000C0F891E44C17E613E4C0676798E3F30EAD
+:10AC300021E706FCF0298A97B4F8E83E176FFD6516
+:10AC400002FF775B4BFEE10C23AB6FECEF078B0C45
+:10AC5000977FA3E20395E6B348BE1174A43BB39378
+:10AC6000E8FE17BC18F4745A9617943BCEB3DC1B5D
+:10AC7000EF85C98867DB2EAAE5F68C7DEE91E12190
+:10AC8000730FFBAED705E87ED1F14DB9ED23B5408A
+:10AC9000FBA8ABC8FC6918F30D443EFFD7972F21E2
+:10ACA0007D9FEFDEDABB235CCEDF2559951D489FE3
+:10ACB00049FCFE196FBD83C25E64F620F1CD268B80
+:10ACC000DFBBB5896D7D1E45BEBA9EDFF3C7DEF3DF
+:10ACD000730E06D079F1D80DCBB45CEBD51B57CEF3
+:10ACE000B7EE826A5F3257BCA556D0AD24AECFF71F
+:10ACF000F1E983E9B0478B6A81EEFFD2197DD0F686
+:10AD0000AD805E4ABADFD858528971A15B6F540D8D
+:10AD10007C7F5F65AFB510E72D41EF839823A3F4E7
+:10AD20009A781EBD223ECEE8769CF72EAE7894CE61
+:10AD3000C3DFFE54000275783FA9E7F7D938E9234D
+:10AD400067E96CEBAB7CF32BF4790BC397F3F780DB
+:10AD5000308833388F220B0CBA1FD9E8253BF4A872
+:10AD60001544DD0A467D2FD72BED2178308EF7CCA8
+:10AD7000F2F2A6F054C0FB6735A597EC754DAFA273
+:10AD8000725175A29BECF369DBF55CFAE153914AD1
+:10AD900097DF24E4895369C91B9AB89F56852939DE
+:10ADA000D6D9C12285DBD3AC29C573ADE1E5EDC9A8
+:10ADB000F2C79B42DFE8D97D32F107C92E468F707A
+:10ADC000C5A2B764C77D9C61EFF9622F3D3DE59355
+:10ADD000A5E73AA4A723BEA0D52735A49FC1EC249C
+:10ADE000B2FBEB019CF7A66FD22C7E0F8361F82C8F
+:10ADF000077ECB85DDA77CA0D079DBBB9676D0FE25
+:10AE0000632CEB03F37AD933E7BDD3078B785E78F5
+:10AE10005751624984F27281EE195E27E4C679F2D5
+:10AE2000CF8298871504A6E7908F16FBE0C11C74AB
+:10AE30002D8F703CA743E6E722B3F2CFF77129F7D5
+:10AE40007DA276FB83C20F50B81CE6F39D620ED044
+:10AE500079D2819B0AD3DF036C6EFBD02E57E25C64
+:10AE60004FF719D03E93EE7F4AA3DEDD145B4278A4
+:10AE7000BF0FF529DA56B55C4FFA53DC4F0C864408
+:10AE8000F7CA86C4BD1BF7A58E3C8B76CFD11A05B9
+:10AE90003D3E10AC485AA85F8BABFB2C09F56C69A2
+:10AEA0009AE2C74C8F598867E3AE4504B75FE96DF6
+:10AEB000417D99562084FA7C008D4966C73D127EFB
+:10AEC000A403F35DFCB5695064DCD70338EFF737B2
+:10AED000602FD9597EA687C96E52FA5A502EB5D71F
+:10AEE000EB14D739EDC63E70EEEFD8B8B7E2B81321
+:10AEF0004AD97846567F7AED8D7C7606D3B3222FD9
+:10AF0000674107EEDF6829B1F2C3E1ED1D686F7E8E
+:10AF10004B37BF4EFC93679FC1F8E29E48D9E8F9D2
+:10AF2000E2B9B09B2F06FD27C2EFBAAC4E087A30CB
+:10AF30002EFD0D83FBCABD7EC0F99F7BECBE3DF7A5
+:10AF4000307CC8A84FC972E9D9F324FBBE1CFDB000
+:10AF5000AC7CE581A92ACABD5F4D90F1EC30F25975
+:10AF600014F9E71DF0917FE81DD81F9DE180676708
+:10AF700084AF13E8F2BFD6E7F03F5EDEC3CBB6FC8A
+:10AF8000FBCA5DEEF29761C938B4BFBE7CBB1FD26D
+:10AF900012FEDE29F7BEF99108CF37FF0AA43A1056
+:10AFA000CF6BC5F9A46B1E9BAAA2FD74E50CBD1264
+:10AFB000E39F361CCF0A3DFD36E363C3210FAF0A82
+:10AFC000A755CC977A7DFB8CCF9C0DD84FBA6302E6
+:10AFD000FA0FC7404E3DFEA52E379C23CDC30BB7BD
+:10AFE0007DDE281F1CCA1629A71FECC588DB0F763B
+:10AFF000B2F7B31F45FB7856F6F7D7D9796627DB4A
+:10B00000EF9FF2F47B8D86175103AC527A1AA5AAF2
+:10B010006CDC2BE8B7CC8968FFED989FC1DC7547E5
+:10B02000BDAE02EB35FA86A937D27C5687EE8DA2EB
+:10B03000BFA84F8244AEFB77CA42C931D15943EF12
+:10B04000E101F1FB820EBD62DF63DFBF08FD7C0121
+:10B0500060FB7B7A2AC407E4FF91D05EEDC9989526
+:10B06000183F565CFC5184F11466F7AE12F6655138
+:10B070008DFBBBD71F747A94AFEB7AE823FB3FAA12
+:10B080008533329E6BAD73E73FDD59F44592BB2BA0
+:10B09000F7F9C9CE5C09C6ADF533691D921FECFA0C
+:10B0A00075A7539CF8FA32236EA15C83B8496D3DB5
+:10B0B0007CB7EA0309D20E3FC12AA55FC5F5B68A5F
+:10B0C000E90FE7FBEB62B2F1468EDFDF643FFDA0E4
+:10B0D00019E11AC4838F9FA7D559D931CF233D5287
+:10B0E000238FCB19C5170FB37FBF2EA6D238CBD66F
+:10B0F0004D29E6FE21B7DC7C57E8A99F3CFC2D9545
+:10B10000EEA3FAEEAB17201E563C2E83C6C67DF783
+:10B11000E10864487FA555D45F576D9773EA77CCF3
+:10B1200074A2BC94ADDC7F79D5B6407A316B7FD503
+:10B13000A3AF9F050CBE775BFBF74CC475F05DEECB
+:10B140005704ABEFAC8BD8FBAB14F8BFB9ECA9CF6D
+:10B1500047B9BD7DF847454DB8BEA52D3BBF48FD5D
+:10B16000F65EEA0F38E2734BA2FC7C2CABC7FDA065
+:10B17000DF91D25372C4EF6CBFFBE1EF481CBE1DE0
+:10B18000FE7410E1DB72BF9A6470ACDAF21EC993F0
+:10B19000055BBF17453CACDAE18ED3ADD8FA610749
+:10B1A000E6A1AC90A17F31F2B37C8CCA474DAD5F74
+:10B1B00026B9CFCF57AF2492B07A3FF8EDA2DFB0D7
+:10B1C000EF6FC7640832D1FBF6BE83EAE3584E86C0
+:10B1D00053B8C35DB5C32DF7566D799DF222741F28
+:10B1E000F4579C8DF9016EBEF6D667EB4745FB69B7
+:10B1F00055EFBAF7D0AE5CB5FD9D5FA3FC58E59165
+:10B200009F6FE37FCA87FAA9DBA29EFB69B61496FB
+:10B210003FB1E27B47EFB5D8B887B7FDEE5ECCB360
+:10B22000BFFAA3F7EFFD67B4179E0AEA28FF577D20
+:10B23000F7852838F8F11EB1FEDE9D045639ABF7CC
+:10B24000EE7F06D278A0F5DD277F3B19CFC9BDFB85
+:10B25000C81FC719ACFEF54F9E47F7F25FFFC30545
+:10B26000E387B3AB905FD301275C69A2ABB143E244
+:10B27000C6CB13E2E9A1C7E1470654B477FF2041EA
+:10B280003FEAB995BD1FAAB83FD963423FE267F7CD
+:10B29000F6D7F77C9595DF61F409E4A00F9BFF4496
+:10B2A0001FE96F2626D973E5F6D71721BCABA09FFF
+:10B2B000F4E9107A3ECFE839334B4FEFF7A3704CE7
+:10B2C000C57DC1AA8719FDCE423A32FA9D35947EDA
+:10B2D000EFE07FE60EA5DFE351F7BD0947E1EAFBAA
+:10B2E000CA7163BA7D6CCE3C886C9C61F87B506CF3
+:10B2F0007930127EAF90385C5D51F3A728EF0F6F65
+:10B300002B1AA4EF62A4EFF78E4E46E3ED4D7FFFBC
+:10B3100017110FFD4F0674FCFD12573DF922ADB316
+:10B32000777FF89C6A505C07A2D26C5686C19FFD5D
+:10B33000C0CA2BB90F1CAE79E0FF2FFA356B7F0D19
+:10B34000EB02F7998C6E54DEC3D61DD1217D61A32B
+:10B35000817A335D46F35E99E6EB61657AE7C578FD
+:10B360001F8517EFFE62FB3ED02C3DF1BE8395DBBF
+:10B370005F5D847C978F9EF6FC759CFF1CF6FD013B
+:10B38000F77AF5D65FC9D627E9292F7DD33B7F8190
+:10B39000CF77EF0F28783EE35D71AFAE97EE59FCA3
+:10B3A0008B73F3A38C431DF7F0C7601C4AE0293F61
+:10B3B0007FF0753ED2FC468BBF77A2868B8F6C3CAC
+:10B3C0001E3E965BFE4F2CE6726325F434A2E9EC38
+:10B3D000B55714485A132BB3F01E46FB82C17BF8B5
+:10B3E000BB32F9853A7A77931CF7CA8B9590FBF7B5
+:10B3F0006FD516737B71E58E9D67A15C3BBCEB47F7
+:10B40000C49F2B1F7E55C57DC79E2D3F50FB6AB341
+:10B41000EB01F543DA81EFC3DFDF79169707B9FD5A
+:10B420005E73C57C563DE1EE7FD5C3EFB9FA5F612F
+:10B43000F592BD30D2386F2BE6A538DFB7F7F9E9C2
+:10B440001EC2B77BE5C65C76F0E462BFCB0EEE7839
+:10B450006ED16FF03CECCCFD21BA7F717BAB39FE35
+:10B4600016B4DFF6FB457CD1FC1DDAA5DB9F0B9102
+:10B470009F67FBFECF503E90DDDF631E7CCE79DE02
+:10B480005A1061FDCDE94BCC948DA172A3EE00DB87
+:10B49000EF39F8E0FAE71AC7A3DCC7FDB181BF5F57
+:10B4A0004E89D3392C39BA88F2CC65DDA70773EA07
+:10B4B0006FDE9F3FCCF7937EC698CEFBDCCF3DF688
+:10B4C0001FB47FEF88FB72E2E13E817FFBF73FD93B
+:10B4D000EFD74B9C6FAC67793C24DFFADAD81C8B32
+:10B4E000573354DEDA5C17C7B8CFB5C5FCBE9EB182
+:10B4F0006F18129E2D99DB674CC7F917432FE0791F
+:10B50000FFDB9BF5B8333E5476D86CC17A67BF0930
+:10B5100071AC87E3E27E6DB4E35AC5FCDCF3907155
+:10B520006B7B092F858CAB9DC0B8B79E8271C327FA
+:10B53000806780CD058DEBCDB3F28EAF4EE379639E
+:10B54000DEF192B63E10F1055A7AC3F8DBFCA29FF9
+:10B55000A5C586EBF7958192A17BABB3791769A955
+:10B560007326C6EF06CF1B2734C77963F69DCE1B23
+:10B57000B7993C0F96B5A375D025FC1318CF5CE6A0
+:10B5800080F705219F0215A918DA5F9D79E211AFB6
+:10B59000083EEF8C346838999DFAF4E2BE61F48677
+:10B5A000B2E69B339CE792153D23B9E2C8E6EB7403
+:10B5B0007F56BEF6DEF8A20D7FE7CE7F82AAA9985D
+:10B5C000379B80D61C706E17EB07EB5562BD581287
+:10B5D0005A1CF5D4189FA75DEE147EA1576E7DA569
+:10B5E00093E2F679F0B443D0F30574CC97D1F64DDD
+:10B5F000C3F86F57C44772B22B98FB1EFBFF2CF6A3
+:10B60000B9E4A48AE71FC90FBB8FF68DC6B1974D69
+:10B61000BC1FE9D65A95FC6091FAFD543E6AFAC8FF
+:10B62000FACF871FFB3E83C1721EFF53BDCEE9BB1D
+:10B63000DBDC46F9B1D74D558DE1F22D426BA6C545
+:10B64000316F425B73761CCF6B876AF8EF61D8303D
+:10B650000FE26106DF863CFCF13F58523CAB0080B4
+:10B66000000000001F8B080000000000000BED7DB3
+:10B670000B5C54D79DF0B93377EE3C813B30C0F082
+:10B68000BE8310D1623A28A2363E2E0F0D3E62468E
+:10B69000C4A809D6D13C4A2218B436A11B1B2E02DD
+:10B6A00082F8C2266BCDAE4D47A22D6DD31653DA6C
+:10B6B000358FF61B4C74ED635B626CE2F6D30613B8
+:10B6C00037AB59D365B7CDD6ED9736DFF9FFCFBD90
+:10B6D000CCBDC30C68DAF4B7FB7D4B7EC9C9B9E7B2
+:10B6E000F53FFFF37F9FC77C4AE4089949C8EE2DD8
+:10B6F000840C151342F8B08DB808D95762B2433A9A
+:10B70000284F4F1AA6E987F0B7606C6A6DFEDB1907
+:10B71000553322F9CEBC442E48FBD999F73819A6E7
+:10B72000A9F5831612A0EDAD3C91FB69EA96C960BC
+:10B730009287E6E55B7C561F4D5D24C3544ADB953A
+:10B74000DFC2EDF08DED7F30E711EF5BB45DBA4CF9
+:10B750003220ED2C17324C3A787ABED04402749CD9
+:10B760008E72612DC0690D7F9E480991F2274513A5
+:10B7700021A9F47B5D8F2CC3FC08C90824C03C4977
+:10B78000468DAE5E0F47D6F4178F1DFF10E087B6CB
+:10B79000DFAD96EF9BF3CEA17B29FCA22C95986997
+:10B7A00037FB06AF92FC69341FBE2A73302F0F9906
+:10B7B0006E2763FB817A3E5A2FD11B241B00CEECEF
+:10B7C0006112A4E327160D1398BF43229249C27E4B
+:10B7D00010FEA4D92344A1F592E60E7B9569BA7EAA
+:10B7E000FE608E09A719E649D7D1D15CEA2F48211E
+:10B7F000C4D63CDF5F40D725811F2222ED2741625E
+:10B80000F88F6EF7CF490C3F1A5E7ACA6F490AC6A5
+:10B81000E87F747D5BCEA4F1165DBEBC670DE0DFF2
+:10B82000E2092A30FFC4D90C2F5A79A2344C643A69
+:10B830006E2261F324A5443E4693845285C0387439
+:10B8400048593F9F07547A7C409D0FFCC969588F27
+:10B8500010FA29415E74D57C2BE479F256112BFF46
+:10B86000D0477041DFB2A979F3D87CBCF94C94EE93
+:10B870006A21E42DDD7C6DD974FE5ABFF4DF1E0B06
+:10B88000C900FC7E54BC09DE61A407EDFB3675FEE1
+:10B8900016CF30E2670CFE8A19FE9CC50C7FCE28BD
+:10B8A000FCED55DBEFFD2F86BF513C71A63540877F
+:10B8B000D178D4EA578CC2AD205DD276847C0AF26E
+:10B8C000816AE0DF1E3BCB1F12EFAC06FE00BE9A82
+:10B8D000805F08C9A44D7AB82E28CF1545ECDF7AD1
+:10B8E0001F9507FA7C50930F6C5C97CF5F4D283DF6
+:10B8F000139F891CA328ED9AAB7861BDBA9153229E
+:10B90000FDFFA33809EB774A8289FB244DCF2C4CED
+:10B9100007B9D966EBB1C17CBB2C3DD84F5B8E49D2
+:10B92000EC8D21DF4EABF335373B671C9D111F8F2C
+:10B9300066810463F1FDDBAA7C6B1B7CEA8C99D2E7
+:10B94000072F09929DC20B4CFFB6B6BEF9B43DE974
+:10B950001FF2F9609C441CC7A5C2E52A349156DF4A
+:10B96000C4701E57E98A6FB68F0B270F70C69033CD
+:10B970001A9CED00A7273E9CCE9C0AA453BED985F5
+:10B98000E30C8A125B0F4B936D239D9FAB35496A85
+:10B99000A5E92EBEA9AB0ED2210B5168150B91CF94
+:10B9A0005450B8F969D309A1FD745C9A659B04B43D
+:10B9B000DFDC43023A391F74042F89B43F5E0C92D6
+:10B9C00020859377293280F1AC4A07DABA91A264D4
+:10B9D00042E6D0F182FC0C90A7CEA080A9D68F467B
+:10B9E000274E8B4CC462E8C7248740DF416773222F
+:10B9F000F5E6BB19DEDAE6860354F691EE129EEC0C
+:10BA0000A09FDA8B28BD24D1BC45EEAAA3F8E87E1E
+:10BA1000D5427A757CA08D9BEB66FAC74E6A93C2BD
+:10BA2000D0B7F9B037388E3EB603DE68BBE60BBE42
+:10BA3000EFBCA2E115FE15133CEF38917633809FE1
+:10BA4000DF27C5AB4DA6F8FDFCAE45FACE2B3A7903
+:10BA5000D54C98FE20444A5F312D7EBBDD2D6446D7
+:10BA6000416124BF870F213EBB5DBD5DF9749E8A95
+:10BA7000DFE42FA4EB45B24B0D788A4E096965725D
+:10BA800070CCBAAE96C2B47D779189B702BD1690DC
+:10BA90009019F092ED41BED4D635E8607463F13070
+:10BAA000396976C998DA008F20EFCC7BBCE3C96B8B
+:10BAB0001BF0490C3C16B9291E3FF1DF0F8F1E37D2
+:10BAC000C1D499509304F8232FEF22D23400C3C875
+:10BAD0007F5A3B8DDEA3E75FFDDF7CFE1A9DC4AF7E
+:10BAE000AF68F6103F48AB660549A89BC37CC0967B
+:10BAF000864D29E854A5D8C2ADA09A72EAFA334E11
+:10BB000011D0CFEDE23B36145DFE0F53C6EB9F27FD
+:10BB1000EF68F83447C6D3E3C7047AE78C25748C02
+:10BB20008BE02941FCB47790DC089E9A6C208F3A18
+:10BB30005D5BCFF84A2378EACC7E4EDCA0A3F72BDE
+:10BB40006285E2A6F8D809766D0C7972AFBBA21DAA
+:10BB5000CA05536C797E48956B5480F30BE9380B1A
+:10BB6000468C789AA7E2697EFA3B8FC134A994E4A7
+:10BB70000915C815017F15E0AD6A4D00C882085946
+:10BB80001F7C2288F45025025E3865B2E943E78DB8
+:10BB9000E32F1EBE5C1C09C482FB19B1E6881BF4AE
+:10BBA0004931C59BCEFEA08421A27CD4D6C5E5999F
+:10BBB00080AED8BABD7C31DDA4D0AA9D5E5308FC0E
+:10BBC000190B69EA02BC93736602765A5A3803CBA2
+:10BBD000ADDEFC10E8BBB4B09DC8E82788213BADC2
+:10BBE0007F70ED5D7ED443D76F23614A3728CB4009
+:10BBF0008E65CB61B0A779512A374B30CEA336F092
+:10BC00006F3ABD354984D9DB24961ED8E20EFE007A
+:10BC1000D68DBF3E1FFB33D998DCBBD1F97C69655B
+:10BC200022013BC07E810B812E3BB0727ED77029F2
+:10BC3000C8CD841E2B4DDB78250C7A4CB96097005B
+:10BC4000DF5B0B95DB4D342DFF95BD88A7DFBB383F
+:10BC5000871FF0D05548979CF6F3BBA79C2142F371
+:10BC60003B572E1F49827E8E9A25287FF2C3A64F0E
+:10BC7000823D65FB603FFA8736D53F247CD32C5844
+:10BC80003FFB479413BBF91EA4FF5D05D36D7AF902
+:10BC90009EEA080E035EB4BCDD4BE5DB0CA4A7B73F
+:10BCA00086293D99148E7C48E9D3E6DAE63D25C124
+:10BCB0007CE9778D3E7C917A11BE35E63D14D760E4
+:10BCC0006712726431D8919D206FD06E250A07EB00
+:10BCD00096C1CADF3FB06231D8A19D76AD7CE562E6
+:10BCE000599F57FE7006F3AADDEB4FF6EC82FA9EE1
+:10BCF0002CD2C4F01320AB74F64C41328FEBD6E754
+:10BD0000967FEFD6D9CD1A5D761530BA7CF9626789
+:10BD100035C8CD4E4A975609E87097C14FD6528D17
+:10BD20000E3B0B189DC5C3BBE57A0909EBEC408BB4
+:10BD3000A707E9D1E609A01D1D5D7F450AB363345D
+:10BD4000FAB77909F2834D0A3E753FF287CB0FECC3
+:10BD5000672D68221CA5138BC8FCE189E6110F3EF4
+:10BD60008DFE3B0BF215A0D7F745E227E3D4B75C75
+:10BD70002FC5F96C71CB93927578F4E451BCC798D8
+:10BD8000CF5792D97C3A027581FB69BF72BDA4205E
+:10BD9000DF7889BF1BF412257FB03BA9BDF9C9E448
+:10BDA000543D9E983DA2F5AF704D8316E0730F6D24
+:10BDB00047BFB6939714587A8B2764E0EF2FA604F9
+:10BDC00067EBFBE145E61F2E34BB4CE423E0673F05
+:10BDD000F5CBC293A99FD82262BAA7C58B69578BAE
+:10BDE0008469778B4CC256EAFE90EBE7EF053BDBAC
+:10BDF000E540F826A28B8E163FB66F6F99CDFAE11B
+:10BE0000343A9FBA0BE8C261D2F8C4BF0BE83CC910
+:10BE1000AC959761BE8763E58F242F58AC14E37C03
+:10BE200050EE754D30AE395486EB77F3FDABF25BD7
+:10BE3000C5DFFE798F54E703FDBD6126FA38C618C9
+:10BE40007A09B3F16EB4FFAE6C13CAD3FDF3769EDC
+:10BE5000F1D1BCE575DAFF78F4D8C3FA8FDB9F0621
+:10BE6000EFE02E84D74AD7DB4EFBB38A4CDEC7E324
+:10BE700087E8F9D294207F7808CAE9FD836BC9CBA3
+:10BE8000C09F7458BB087C1A9021DE25B4531CFB5C
+:10BE900041DF06C2CF80BEB571E418CD0B2ADF505A
+:10BEA000B5AFBC4CFB11641BE9A6ED06E7DD45A070
+:10BEB0005DE72B360A13A5D3947CB417EC85B5A4A3
+:10BEC0008DD6DB596D2766FA3D69FE1A02FDEDFC41
+:10BED000991DFBF79D9982FCBA4B647C34A11CF23E
+:10BEE0009A4858AFC76D8E483E1FE4E57D24300D5B
+:10BEF000F9FA693D5F533DD90BFC24902A8570A067
+:10BF0000871FF0333B4451E569E05832DA81016C18
+:10BF10001FB10B9B8808FC7ACE1CEA06BFC4DC80EC
+:10BF200046DF22F361DB30F2B5BC3CA38C10170373
+:10BF300081ECF287492EE025C34C6D31204B818482
+:10BF4000A9DEE8A1FF007CFC85AB17C8AD84A4AFD7
+:10BF5000110CF3E02F382F996E05F8587D4D0FF135
+:10BF6000171A1BA13E4F74F5D19FA94B1ACF2F8CE6
+:10BF7000B6E30793557FD0497240EFB5B79C206F69
+:10BF80005B22FDF05171252DD5ECF9875358DC6209
+:10BF9000949E2446DF2F503F1DE8B1E31766D21B65
+:10BFA00083BEAF27FB0CF66E46D014991FFDF795A4
+:10BFB0008BD68A8306FA1C7FFDB3EA8DED739A1C3B
+:10BFC000063CE635271BF23E25D3507F5257BEA1D3
+:10BFD000BCB067AAA17CF2A1E986FC94D0A70CF5BD
+:10BFE0003FD15761C84FEB5F62A8FFC91335867C0C
+:10BFF00049F86E43FD1967361ACA670E3D64289FDB
+:10C00000757EAB213F67F8AF0CF5BD41F1E409E067
+:10C010004F4A8F668AAF5D19CA21D09FC36DD48EF7
+:10C020009BCFEC63D0B7249BA8F631554C694057A1
+:10C03000ECAF1DF400C8F93D8F85BF807AD2E407CC
+:10C04000FEE50B16C91BA15DBB68225E9D1C911607
+:10C0500011F85EB1C78DDFE5D256E40F81AA0D7BE2
+:10C0600022E86DE37A10F376D20FF0BDC1E0E3452C
+:10C0700025A67C12B28DF46F25F72405C6B1FB2CE2
+:10C0800092B1FECDD2BF2F45A5FF1C4AFFE689DB4A
+:10C090006B74FF90499E9CC2FCC3AA731E83DF830E
+:10C0A000781DF57B6CA41DD8A9BC6E24EB14ABAE37
+:10C0B000FA3756D3879FB871FF269ABF684A714EE8
+:10C0C000D7C9CBE4B566DF8FD587330CF65974DA60
+:10C0D00096F810CA3B2A17CB530C72315005F31354
+:10C0E0007819E5A2F6DDD73715E57297C8EC944EBE
+:10C0F00089F2E538F88A96CB5F4E9698BF18473E8E
+:10C100000B54CE82C2DDB9F2D35D8037791B41BDBD
+:10C11000447510CAD9E8FEA95D7537C2E965F4A473
+:10C12000F9439ABF65A3F203FC2B9B44105F568A28
+:10C130002F27DA478FA27D49E721817D64F550FBE7
+:10C1400013F43DB53F99BDF9E7B52FF361DE7AFBF6
+:10C150004FD5972187DC94921ABFFF17E3EC479DD8
+:10C1600049D6FCEEFF9EF427A718F1A1D1A146679E
+:10C1700056203A3ADEFB125B77DA2291D3F62F246F
+:10C18000F84F10E9E5D4ECB34A25AC5BD0255BA9A8
+:10C190005EDD37BB06DB0993780272266178C33215
+:10C1A000D093A494C90985FE03F4E62836CA0D5B32
+:10C1B000941E15401F278ED5BB9A7CD0FCF389E4D2
+:10C1C000CBB752D438D92C324B2F5FE2F9E19A7CAD
+:10C1D000D1F0B0E0831611ED8E0F68B9664FD07EB6
+:10C1E0002C397C00E2CC829FC84762F0DFCBAA5E8C
+:10C1F000EE3B6997812E5D6B04F4B332FDE172C8AA
+:10C200006736113FE067F670980469FF3FF4B0F5B8
+:10C21000C8F48738B0CF332F873880F3A085C58521
+:10C2200032B785387DDCE89AEAC7FDEEE2A37E5896
+:10C23000F78A3C17F2E9671713A48F21EFC69E72A5
+:10C24000D857984BFCC03F2E0F4F32217FDE1A4249
+:10C2500079E21F51A8AF4392E944614DAFB490E930
+:10C26000F751FFFDDD161BA6D75A444C2BF38A0766
+:10C2700017D07A5B7D0E8C1774E43B709CCE5C010A
+:10C28000C7F98F9C87F2C02EF8758B17EB773DDED0
+:10C290005404F184CE93FF8971CD083D53AC7901EC
+:10C2A0009E30EEF710BEC90BFBBE49F20CDC27ED49
+:10C2B000B404FF7103C413D70AFE6331F837E9E50C
+:10C2C0001FA19F0CF8013CB4DB195EACCE26BF1B4E
+:10C2D000E2FD93C8FA15B1F854C513A530B340E98F
+:10C2E0003789910611E686DA1241AFFA493F059B7C
+:10C2F000583A421CEC8790074509E245D9B6D02050
+:10C300009467D78BFE36AC4F705F415B278B9D04E3
+:10C310008EBBA05E98DB42BFBFE811D9FA0D8570D5
+:10C32000DFFD37176E1FCC21F1F97B4F4BF5D92A72
+:10C330005D3CD64562EF0BFFCB6D15160FEDF77622
+:10C34000806D26ACF7AC71F5E38DF67BBB8753E3CC
+:10C350001393D3C15E6EE663DB996691AD0FC47F24
+:10C36000C08FDE5A28A5BB5DFA7E183ECC279FC73A
+:10C37000F57116B3F9B77DEF8DCD8F513AF977DAB4
+:10C3800010E255AF5CFC0CFA8FEF254BFBC1EF526E
+:10C390007E6C26B0CEEF7D7FD669589431F36E392E
+:10C3A00093CCEBE249EF7DFBD5320BEDFFBDE75EB1
+:10C3B0002DE3510885101F5A79E387AF9541FC4A58
+:10C3C00068FE4DE6650AAF52418A9A204F0D68E635
+:10C3D000876E591A1E076F07D31ED802F1C2509BF1
+:10C3E0004BE4A8BDF625E71F05A0C766809FA60FF2
+:10C3F000DB4676727489B9F4779754D1FEB6728AA7
+:10C40000E2E2006F8A15FC0A72C1EA07BAD95AC87B
+:10C41000F4E5D607C59002722CDCC4C8DDF65AE6F6
+:10C42000652A87ED3F0DC11900D2CE052A13207E63
+:10C43000378D20BDDF76AD290FF695DD44C8073A6C
+:10C44000B498CCD8CFC84567A817E56FD32C9043D4
+:10C45000AD171F9D0CEBF57B55BE6871B73453D3F8
+:10C46000813A1FC4DDFC1877DBCDF7639C3EDE7C90
+:10C470009D5EB6AFC0571235DEF5DBEE7076841EDA
+:10C4800034FE8A6EB7B785F861BC975A6C98BED0F7
+:10C4900022627AA2C58BE9F75B244C075A8A30EDF9
+:10C4A0006BF1FB0B2C00E76C4C3B2C647D40476729
+:10C4B0005FF0B0FDC87B92CABF0074FE24EDF73276
+:10C4C0006DF745DAFE32AD3FAF366C86B8CCBC11A5
+:10C4D0002A2F2528EFC2EFFB697F506F6CB9AD049E
+:10C4E000CA4BABFBC380C7D262FA9D407F7D587FA9
+:10C4F0007FCB093F2B1FAAB450FC96FE96953BE7D5
+:10C50000D27E68DEA9F643C72F61F567637F745C4E
+:10C51000CCC7E8B784C173A224163CD1F5A9956FA6
+:10C5200026548F88F0BFE0EF59240EF75138123EA1
+:10C5300006F2F882B51CF4E79E12926FA2FACD9231
+:10C540005AC041FEA966229A4BA8CACBA8D9554E1B
+:10C55000A09D8CDF95557CE8980FF513F6ABE9A705
+:10C56000E4EA30EA9D243FC937BB69CAD381A753A7
+:10C5700054DF4722E70D503EB13CAE076D2756937E
+:10C58000C8790332717DAA5FA2CA63D3DB474D210C
+:10C590003EA63FF771701EB1835F4B7DFD7E924BCF
+:10C5A000F3AA7DF645B5DEFE7965491B21BFF8810A
+:10C5B000A7200EFE1BE2E5603F7EB47D943D77B878
+:10C5C000E54C5A55A1AA1440DE6F138FE8EDDC6CE0
+:10C5D00085D2AB8E0F7A9AF8EA5E8C2F04336A7498
+:10C5E000FAADC312CCA0CC4BAE3FF18F8B413E8055
+:10C5F000BE06393D7784E9F751BDFE5B261F357BCA
+:10C600004250D76B9FBCB12D01F7D3A83E92C0AE6C
+:10C6100008920ADA3EB17CEBCBF09D9418BF270854
+:10C620008C8F32BD210EF2999EC04F3CB0DF907CC2
+:10C63000487E86CEF7B7035609E8AFEFE4DA7A888A
+:10C640001B3E4C12253BED27F3A54B02C0D1611ACE
+:10C65000168008473CCD4B786A0775089A9CA486DB
+:10C660000F5DFF8E34552E90DF7757D1FA074DC1FD
+:10C67000AB54578ED63FE8086E813CFD936D54AFA6
+:10C68000EF1D8DA36FEB96294DEC55E3E6239ECF6E
+:10C69000762BD990A7F5DD2CDF4EDBEF750F794DAA
+:10C6A000349FC86DE93E930379ADFE966E85B6BFA3
+:10C6B000EA61E700882BE803B9379A17693E41978A
+:10C6C000E7599ED858DA77F23F05D0431D6923A772
+:10C6D000B3009F3FE4FA41BE36BEFCF541C86FAEE1
+:10C6E0002712C4E7324F1CC175F8AAB97C04F0D6F2
+:10C6F000D7724644431DFEB475A176EA142FC17863
+:10C70000B210E242F960BF15F798D07EDB4E49B017
+:10C7100004F0DD9506EB5C91C6FC812921DA8F8E51
+:10C720007FA650BEB34E0775651919D6FB5BC46F63
+:10C73000027811E5F01FE57F2F01FDD4375B714CC6
+:10C74000A5E36DDAC0FB5B25D03FA15601D6FF04FF
+:10C75000877AC2772663C73768FE5A7F4A2FF81B4D
+:10C76000961D8C3E37F9FAD3A6D3B4C3CEE86293B4
+:10C770005BCDBB8DF976D59EF4BA157732FDBEF947
+:10C78000C4815C3000AF1E9B857EE4660D1E720086
+:10C79000E1B93A3827E9363ADFC69FB2B866E340D6
+:10C7A000C912987FE31E13013F6EF300A5271D7F7A
+:10C7B000ECA37C284FA6F3907BA6F2943E02070BD5
+:10C7C00096DAE9FA7E3D5F16015FF569B7EEB6517C
+:10C7D000E7E8EB823805E8A13EAD7437D0D3A6393F
+:10C7E0006F213D26A596FEA49AE2EBE8DDD54B40ED
+:10C7F000ACA599185F5282433967766F43FCFF6B93
+:10C800003919B1BA119DB8CF9907FF47E19B2CCADE
+:10C8100015505F5C465D22A053217012EC10A5C23A
+:10C820008671D20A711996E7AE21A66E0ACF112938
+:10C8300039B99536B517C826B053F2030E8C7F9AD6
+:10C8400013AA76803F7AEC1CCB47D6E912E2C55199
+:10C8500014EAB7D17E6E71F122F8226966D906EB2F
+:10C86000467979E85829F00BB303942F1663BCE797
+:10C870006022A97F8EB63B6ADAD8FD235AEF68B2F0
+:10C8800087805DD9C171EB6BF07BC5D4AD743D8EF3
+:10C89000AAEB6776FB4558AFA36E637E2FB7F141D5
+:10C8A000C0DB23A92F2E81F9A559E59E140ADFE7E5
+:10C8B000525FECF666209EF36DB4FC737FFD42B7C9
+:10C8C0008DE2FD68AB9C29EAF293FF40A536CEE3EA
+:10C8D00005E453DEFDC587808F69F98F6D54FF7EB7
+:10C8E0003D59B307587941BEC6D7D4AF9D4DE168D5
+:10C8F0001DCD2BB622D8F78AD4AFA27CFED5A7CD0A
+:10C9000044EB1FEC09C79C7E9BC38CF3200EB067E1
+:10C91000A6F168CF38DC6C5D1D53F2D14E3A6A67E0
+:10C92000F81AC93161F922F3B322C407AC53781362
+:10C930009EE5214D01D0CF7C364F58BCF7B03C4529
+:10C9400082B029DB1FE47A56A07F682FD2ED071250
+:10C95000F0638DFB877C54BED03A9C61A27AD87379
+:10C960006105974BFBFB6CAAEA2F7A4806C4631F4C
+:10C970004D6572E6D18072BB45021A1B66E75649C7
+:10C98000603AA4E9EB0AD2C73BBF32F65C4018ED2F
+:10C99000B23D2E938AB749BBC305D45E763D27824C
+:10C9A0001CA16A7EC761D06F1E1EE9A610F89FE623
+:10C9B000B7B9591CDED7B7E44BB3C13E7CB5D00440
+:10C9C000FCCF8B7E11CED99527942681DDC68FD2E0
+:10C9D000E9EB4BC240378373EE043F5000FEA59F46
+:10C9E0000FDBD9F9D0910CD20F7161DE2B13FD3E14
+:10C9F000A1C6BF3B5B6C98527FFE5DD01F5FEB22F0
+:10CA0000B84F2078039897DA09077CF1F2A7EEC6B1
+:10CA1000719FE10349EB40DE9E63763D900BC63982
+:10CA2000C24F7010E778DF16488279EF771BEDBFB1
+:10CA3000B23466C776A632F9D9D9C2E2A0C2F54FA0
+:10CA4000605CA7C3A2C923D7D2F05CB0E783788E1D
+:10CA5000D61ADC2683BCB21145117571725BB631F2
+:10CA6000DE255CBF95C58752D938D1E70D5C9CD6D1
+:10CA70007FC1EEF1FC032D8D3E9FD04C02288FC864
+:10CA8000103BF7B06D57657AB2AE9F6D9C9C2E8EB1
+:10CA9000431F0F5F379390EE9CCAC3FC8800F37965
+:10CAA000F8BA80DF897738B115F66528C175C33AC1
+:10CAB0003EFF5DD44B0ED213860373568853E8CEE7
+:10CAC00085122F3F324AFFF911FEC07D752E067F79
+:10CAD00048C67CF47EFAA3E03BD37F77387F2DC035
+:10CAE0003CDFAB242360871232BC08F8B7B1D28197
+:10CAF00071EA87498FCD06062EDF23EAE3C58D0351
+:10CB000097123794E23E960476F0C32F951BE254B9
+:10CB1000DAF9302DBFF9C4068C1F3E7CF49A30B58B
+:10CB200014C118B2507FACD1D673C69A1FA96FB783
+:10CB300004952CA0FF975AE52CFAE95B00279CABE3
+:10CB40006A9E340BFCBFDF8AF519802727AFEA8F76
+:10CB50003536D41FED76EAAF019D5E9C8CFA9416B3
+:10CB6000F3A09FB5F15778181D8EA8FE7C023533CF
+:10CB700001BF1D8EC01566B41399A7F64E47B24685
+:10CB800037CDDDA0FF0E0A11B908933DE860F9E446
+:10CB9000B4E6EE76A687B1FEC893FC6EB0873AEC99
+:10CBA0006ADE43307F50E8413F41F9BE5502380FFD
+:10CBB0003A027EF007951D5324D02755E92E9C8715
+:10CBC000E5EFACBD200F333DC1AB60B7100FB38FA5
+:10CBD000DE4BBD904B5C31FB19E16EA41FAFB11F62
+:10CBE000FB5C36FE7B9C39B0A334528FB60FE3B9A1
+:10CBF000807B6C18FFD1EA1FB618ED642D9D92C69C
+:10CC0000E20C204F80AFB5EF42F03EE45F2B69426B
+:10CC1000FEB57A8DFB451A3F0BD7A718E297DF4A7E
+:10CC2000F5E1FA687240B85E8CE59D2A9DEE847D40
+:10CC3000F471C7498E33CE0C9413F1C72953E5081C
+:10CC400051E3493C9E33D3F824BEBC30C671A3E502
+:10CC50009F966AF2EF884AC7FF600F2E4CA3FFFF32
+:10CC600050A87F91035B076F85F5F9A36AF716F566
+:10CC70001D3809E47745945B5353E13C957C1CD205
+:10CC80009BE59BFA3436DE5839C6E20FDB1E945022
+:10CC90003F3FC3FB1DFE1870D75F771AE4577EAA8B
+:10CCA00084FDD5F30ACAB1FAEB8958FED1FBB793DC
+:10CCB000D08CF1FA7761F968FFFDACFF973FF5E39F
+:10CCC00083B3A1FFE3169355E7CF6D3BBE301DE262
+:10CCD00095DBEC542E1BF95606BEE57D64D40F029D
+:10CCE0003EDFAFF945CAA2DD5573C16ED5F1F96CCF
+:10CCF000B0BF22ED79BACEFB1D5AFB3B77833D34A2
+:10CD0000A6BE33AA7EBED6FF6AEC3F1A1E4D8E40E9
+:10CD10001EEC2DFE0F560D3E9443074C51FD8DCA5F
+:10CD2000A520F6B7690EB33392FEBAFE270A0FF4B8
+:10CD3000172ACF023BEB4122C139E768BC27A9740F
+:10CD4000587F7D92615D23F8BEC5F0FD9F5BBC24DA
+:10CD5000A4E3B7CF04B72D027E4BD2D689283BB1CE
+:10CD6000DDE12C12D2F1DDFFC0F151E1B82D0E1C36
+:10CD7000F3FFC270F80C7C1981A3C0F0FDA3C2615F
+:10CD8000B65DCFBCACCB5B4492A5CF97846D599771
+:10CD90007576CB8C33A2213F73C86BA83FEBBC6484
+:10CDA000289F335C6428BFED8ADF909F3732DB50C9
+:10CDB0007FC175D9902F278B0DF52B6D2B0CF98525
+:10CDC000E25A43FD696A9CFC76EF0643BDC5D283F7
+:10CDD000867A4273CA77C07E59F0C1021BF8173BAE
+:10CDE0005DA6EA10C5CF4E3E684B8E211FCBD47E88
+:10CDF00047F59D370DDB2F149BDA411E2EA4AE7034
+:10CE00001BB5D7D2EB02EDA0F7AB45229AD16F0E3E
+:10CE1000B1F8C9072BABE0FB9D8B89D8ED8EE46F91
+:10CE2000FF2B42206FCD96F15C9BBDD884E7067640
+:10CE300017D78CBBFFB04FB5DFF744E9FB51FA3190
+:10CE4000B3F393D1DF8BD3195D1D58B08FC03E81F2
+:10CE5000CD15C27B3E8353767A21FFA505DFF6828E
+:10CE60009FD135E5112FD04F67CE570DE7F21C0546
+:10CE70006C7F26BADFBF55FB2DB8FEA80DF4E7EE98
+:10CE80006C86CFE87ADAF9F4DD361637FFB8E6B902
+:10CE9000F8639AE7E5746667EDB68530FEDF5DF40A
+:10CEA000F1C07FAF3ACE81058F1306EFE3780EB95C
+:10CEB0002B4790F47A564BE1DE28CCA7D3B7D30B9F
+:10CEC0007AB7CBF788C1FEB7C27C628C63F3323C81
+:10CED000ED163FDEF93CFE27CF6767CC7D775B9C84
+:10CEE00079156BF3F2AAF7283EA6793DF5179E5700
+:10CEF000581D2F359DD9A7BB25C64749E6C0CFF39E
+:10CF00007DF1F92F69B6F19C5282DFE807E417043E
+:10CF1000C63D7F745EC54F3C7E5D635152018ED726
+:10CF20005BD839DB7380479A9E0F4EAA80FB0AAF0D
+:10CF3000C3792D0EDAEF48186F1DD606CD063827B7
+:10CF4000920F25E9F9888FD56B8CED56059CC6F3B9
+:10CF500052EA39038AA7FD105FD6F036669DFF4C72
+:10CF6000788A476F378AA7EEA29BC3D344F49D9A71
+:10CF70002E21BD4C84278D8EE2F5F3FF2A1D2DBE98
+:10CF800071FC20FD7CDCF8F9AF463FF7A64B37C4B7
+:10CF900067FFBFE2E7F11BC4CFE8796B81D4C73AE2
+:10CFA00007D2E915900E27734D6717839FBDD88C64
+:10CFB000F1B3D70E1734927C7D3DA6075E5B36A990
+:10CFC00011CF8F553BF1ACD65953EC7E5F53F1F145
+:10CFD00090D7AD9EA7F3A782DD7BB67AE5B8F322A2
+:10CFE000CBCCC6F38BC411999F99F64BA40A8C9FA6
+:10CFF00051BC1E1B67DDB5758B37DE8DAEDBD9EA04
+:10D00000B69B5A376D3C8AA798EDEEF6E6DF10DF47
+:10D01000C309768637761EA0EF7166B7F701BE6941
+:10D02000BFBF84A20CB0FF09C6FD56AF493F02F056
+:10D03000BEE665F1F001416AC47741562EDB0DE78B
+:10D0400051CEAD727310D2D0E038A6AE67595D6C88
+:10D05000BBF339B53CD29E2393A5B1F58EA876CF0C
+:10D06000AA3A0EED07C2CB39FA773FFE21AA3CBAA5
+:10D07000FD4BDE442C3F17E73CE6B7D4F6AB6BC75D
+:10D080006F4FEA53F0DC1F21528EFE3EFA285DA955
+:10D090007CB0C21BFCBE97D67F9D0B7EF973104FF0
+:10D0A0009DE2C2F33D84273ED8F71FED8797F1BC80
+:10D0B000C6E54686F7E87E75FD85BDA9F1FB8B8741
+:10D0C0005F6D5EDA78A524807E1DA926E27E36BEDD
+:10D0D00019CE39DC59499A707C5E427852DEA4FE42
+:10D0E0009C2F421F174CD23ABC48A3F633F0FBCA20
+:10D0F000A5D0CFC05993B8C3171FEE78F2E09F5464
+:10D10000FAF198833BE05C0159CFC53CB7F72BAFF0
+:10D110001DEBEDF78EEED7E338B73C19B448B4DF1A
+:10D12000BBD4736784047356E8C6DFAFCE3BBA9DA9
+:10D13000C7CCF6C7C91B66C45F5FEF4339B1F8E7D8
+:10D1400035D55EDEEF2D32F8C7B5812D16B06B6B8D
+:10D1500097ADB0482E289718DDA970F409C19C122C
+:10D1600057044F71E58F8A9F81F3413CB7B1BE9957
+:10D17000C373C7C5DB19FDADDF3E686AA4E911952D
+:10D180000F57C03E93AE3F77069B5F5FAF2317E01C
+:10D19000EFD39FBFA0707CFA10C1B89D2DE3E93D8D
+:10D1A00010B71BE6881AE7332D87FD8661755FACE3
+:10D1B0009096B702BC55A9C8E7EBB7AF403FFF96C2
+:10D1C0006AE6E70F0804CF01BD392F2104EF1D10D7
+:10D1D0009B3CF828CDBFF58724D2ED8FD0C71342F2
+:10D1E000781AD0476A5BE073B1E2D35206E3F3DF0B
+:10D1F000BAD83E5E3CBC9C55E5A956AF86972CB18B
+:10D20000EAAFAC36CA350DFE146BF83D12239E3ED4
+:10D210004A8FA1F1F5DD2F5439FD5A94BF547B3E5E
+:10D22000B6DF3237433DA71BAAD884FA4AB14A7801
+:10D23000B65885C7A3AC467C7EB8948890BFD32AE5
+:10D240003D0DF0DD556B8E92C321EC67FD32A76179
+:10D250005E4FF4FE781ADC4BCA2F60F2F7FD2217FE
+:10D260009E137F80340970FEAB8E28F3912F896462
+:10D2700001FA3EA7E24F83EF1C91136682BC683629
+:10D28000C7E4AFBB543A3A17A85C85E7DFDBCD783B
+:10D290001EE1526DCA72887F2B018B1F8E375D6A2B
+:10D2A0005F9970BF6E5D35BDA7D935E78395E3EA19
+:10D2B000AF5501E37AF5093DB8FFA75490A66394F2
+:10D2C000CE267FF9F2DE59347F36642A61E7DCD856
+:10D2D0007CCF86B2B473F1844FA3EBAE165D350DEF
+:10D2E000637DE56FD8BCD6D58516C296D83D877AC2
+:10D2F000F6CDA2F9860CB7BAEF387F1EF0EBAF9AE5
+:10D30000C7B707A2E9E996271D867CD97922E07B79
+:10D3100014DB62EB87F7B29C6C5F87F7E7C23AAC2D
+:10D32000DB1EBB9E3BDB85F5AEFED15C1FCBEF3E2B
+:10D3300090C5D6637D3D17539E1FC84A60E50DB169
+:10D34000FB5F95E954E59D980BEBB23E0EBC2B328A
+:10D3500013118EB73B56AF83FDFB2B51F655452677
+:10D360008343CA64E72BAFF6BED09106F4B09313A3
+:10D37000E11CD95B6EFF14A0BF0DED97D0CF4F57C6
+:10D38000EB3BD2034F66D0F4EEF3CF9D82FA0375E8
+:10D39000C4CF49F1F5C0E10C4D0F68F7A2357DD837
+:10D3A00063077D04FF0BFBAB1404252919D65D79B7
+:10D3B00008CFC5F43A44760FCA3F536F577F43A551
+:10D3C000E7AB476F6EBDEFA937DA4567C1FEF3449F
+:10D3D000ECBFAB82B4B7948E7B95D25B2B9D0FF9DB
+:10D3E000E0895BF5FA46E38778E3DEA81D78F5E887
+:10D3F000CDD98113CDF36719BE1BB203DFAF7E62B7
+:10D400005FA904F3ECB93596BCD5E4F22F55B918F1
+:10D410004D2F5AFA4B55CE5F098D0FD7670E19E184
+:10D4200059D7648447E38F2BA13607BCAB45479F90
+:10D4300006EBACD9A5A46AE60DBD17120FCE5FAB03
+:10D4400074F2AB66338F72EF2887F1E95F353F9155
+:10D45000182B6E153DFFAB264A0F401F4FF3287F58
+:10D460000AEB379C4C9322F4F87F543CFCA974A837
+:10D47000C9574D9F44B7FFAF4A779A3E9B88EE3C11
+:10D4800071E28F07326C88BF0DBC28C0FED1810CC1
+:10D4900089E589B8C80BF6EB6C76EE9D4AA85C78F6
+:10D4A00057E26AAF03EF8329DDD650215DC72BBD5C
+:10D4B000B74DD1AFE3EC4CB61EEB1BDC3B61CBFAB6
+:10D4C0008AC9BF381DD6AF86BDEF71EE7CF2A2745B
+:10D4D000DAFE892113BC9045D66DDB6086F9CDCC90
+:10D4E000647A64FDF657D1EEBB59BA5EDF64D4E7C7
+:10D4F0005FCE10553DC1ECF03BA95D00E708E3E1CC
+:10D50000A13093E1E19EFAE3284FEFDDCEA13CBDCF
+:10D510002593E1E35E3E847299B433FB99D8283EAB
+:10D52000A85CBA0493007CFC35C7CE77F30141FFB9
+:10D53000FEC6FD7B562F043B309A3FBEA7E2E92B87
+:10D5400099EA3B84E9C13B33D13F0C70D0DF5B9F4C
+:10D5500067F0AEDFBE05CF275FCC50ED6B953F2F58
+:10D56000C23ACD8CCC2F459DDF05C7C836D0179465
+:10D570006F4C78BEE47533C275F5ABDF6C827AE22E
+:10D580005417DEF7423B96E6FB9627845A75F13A2C
+:10D59000CDAEC9F7337EA8E565835DD890E933D871
+:10D5A000E9D1F6C6FFE80396F6A878FA4BE983C3FB
+:10D5B000AA5DF0A7EA834754FE8FD60BA37CBC93E9
+:10D5C000F1F1A5F3FFBE10F2D17CFCADCC8FA69794
+:10D5D000A2F9F74AEFDD48D7CA1222161AFCA39C1B
+:10D5E00010F8C1A3F41FF1933838DFF644EF4FA6CB
+:10D5F000419CEBD2DED5EB628DFF4416B3B33626E9
+:10D600004A267C1FF2754667D17222BADD285FC4B4
+:10D61000892FD6D6CC41FFF05CCD6DB970EF2DDAF5
+:10D620003F18539F935357817FDCAAFAC7FBACF591
+:10D63000BD31E0F566317CE6178C9C027CBFDFC013
+:10D64000E17D62F8D3DBE9779FF7FF60581A0BEFB3
+:10D65000685EF34FB6B3F1A2C779575DB751FF4487
+:10D66000A1FE09C5F370AD3911CEB16AFEC9B0F2A1
+:10D67000E7F54FDE2423FF300BD6F9686CB81CEABF
+:10D68000FCAF08C17D73281C579798FD0AF08B8961
+:10D69000B6D3F925D1EDFEA8CEE7CDED37298FCE53
+:10D6A0001BE3C9F1F86D14AE3F91DFFA84911CE0E1
+:10D6B000FB378F7C70F15198CF1107BE3F16DDCF3D
+:10D6C000D7B2CCAA7FE0403ED0F4EF80D0B3F905CA
+:10D6D000DAEECD3B32FD3B888E2F08E50BFAFDC21A
+:10D6E0001F295FF851BE211FF7F53AEB63F9298333
+:10D6F000AA3F141DB7117BBFD1047EB14CFC167D2F
+:10D70000DCE90D75DD7FA1CAA5A22CA63FEFAA5DBD
+:10D710002140BCE8FED1781141E7429C9A7D04FC8F
+:10D72000CBD7D47B02CAC68498F1DE992A5E278AB9
+:10D730001FACA933FAF577D51AE5C73BA1FC513DDB
+:10D740005238CE7E9446BFF1C6BB51FDD117BAB94F
+:10D75000FD8089E6F7D9AC1BD31FAB48D33C8C7353
+:10D76000D0F581B496344D7B81C2F3CEA19509608A
+:10D7700047FD82906AB4E33FF8EC34BD5D1254F18A
+:10D78000FC7EED67EF00727943689A164BFF44C741
+:10D79000697E118A7D2EE32E55AEBEA1DDA7B82B82
+:10D7A000763C7F8B3AEE1B75E3F34D74DCA67699DD
+:10D7B00071DE4A16B387DEA86B7304995FCDC6FD90
+:10D7C0001B362EE82DBD5DAA64FD79F4E330C4EF6D
+:10D7D000619CED84403CA54F50A6EACF5DA5643323
+:10D7E0003CE4178DBF0FA5EDA768F5A2EDAC9F67D0
+:10D7F0004A867BB3B5CB8C70B569F62D11310E72AC
+:10D8000015F4A527A22FEFB4FA1F043A202E09CB56
+:10D810004FA878BFBBFEDF2C307F2A3F3BF01EDBDA
+:10D82000599308F2B3EC7CC8A2C7CB851BF4AB2E8E
+:10D83000A8F6C2447234BF6804E5DBFB2117DE8F13
+:10D8400078F30BBFB3C4EAB7F67A96E11CF1FA405D
+:10D85000ECB88A98258C8B6731CB88BFF5D773F1EC
+:10D860005C703CFBFF10C8AF99608F1EE9D0DBFFF6
+:10D870004F6549AAFDAFCA339ED9FDF1E2AF432AF5
+:10D880009D4D147FD5F4B3562F7AFDB5345A5F0EF3
+:10D89000ABFC1C5DEF52D68DD1DDA81D1387EEE2E7
+:10D8A0008DABF91F5ADC37BF98B68FB12F33661C8A
+:10D8B000B55EF4386F46ADCF183F224EDC2E299B63
+:10D8C000E13718276E9794CDE2766709D38B4AC863
+:10D8D000897AECCAD17BF781B9F7C0E2CF9D06F512
+:10D8E000D6A8C66BEAEA5F3D057EAAE65744ECF18E
+:10D8F000601BEC935DDDC1A1BD113D4EB45DDE0842
+:10D90000EF15822055E307456619E3D4E43176BE6E
+:10D91000DFD3BC1AED4B2D3EDD27047624D0EFB7C4
+:10D920006CFFB76DA05F353FFE2D8BFF411667661C
+:10D93000F6EE855E17DE73DD3AEAFFF931DE38CAAE
+:10D94000FF6AFC71A2F518953771D6632279132FFF
+:10D950002EA2A5A3FB2C8254F80A9C4BE512FDBD18
+:10D9600034AD11080F78A859CEA19F5923C84B3167
+:10D97000DEFCAAC90479DF72DF6E3807BFB2DA2293
+:10D98000DBA5C8FE4BE96B0D85AF807F41270C7E80
+:10D99000ECC02FA57F82FBC1AF2FB64BB03F727694
+:10D9A0009E34E8A1F9B3777022D83D558BEF374FFD
+:10D9B00083F15671F80E8DB399A8E7B56F5D5E5986
+:10D9C00040C8370044DDBD8F1A6D9F4659BB0FEE2E
+:10D9D000CD4E4D1D30B9284ABF7B78ED3E1B85AB3F
+:10D9E000A335E085FB78F76597EC83FB786969F2EE
+:10D9F000D0026A471DCC9EB11CF2037FA3F557BA33
+:10DA00000FEEDFBD680AFA385AFE83EC65CB79D891
+:10DA10008F98A48DBF1ECBEF5AF2E0B16DB4FFB763
+:10DA20000F6F590E67D7CBEAB4F11F595EC953FA8D
+:10DA30009FABE51F4B84BCC74922FB4CB309B144E3
+:10DA4000EEF7E179F781D1FB7C2DCBE1FCF8EBE53A
+:10DA50004D95708FB3ECCB1DFB8AA710326B59B973
+:10DA600028D3FCDC9C2F2F77C2FE31A1F448F3723F
+:10DA7000CE57107E8FD9A4F61FDA2767033CCA540D
+:10DA800028E79467F655BBE13EC2F06920CB879B3F
+:10DA90007B6C69867B098A0CA68970A23C9C85E018
+:10DAA000A8FBDAD9E169ECBE9D9A2F62718AD1BCDC
+:10DAB00097E50776C4BE7FF2610E935F038ED8E5CB
+:10DAC0003D2ADF6BFBAF49E789FC6C0CFEFF3CC4D1
+:10DAD000FD6746F8E914C4433CF8E45C532BECC3FF
+:10DAE000DA189CF1F671F7A9E314B426E13B45CBB3
+:10DAF0009A9CF8AECE243F9337948BF89520FFCDB7
+:10DB0000268433D5CCE17B26690E123C4ED3D41447
+:10DB1000F6BEC9328A6A787764E1A4C0513CDF9BC3
+:10DB20009E51D206E7EB5A7FCE831DA6B51F0BA7E9
+:10DB3000B805E04C35D7946C29D6E1AF98C14DD7E4
+:10DB40005D6D277F13DE7B19189A9A0F767565B67F
+:10DB50006488CB940DD558E05CEAE51C554E48AC82
+:10DB60007D6A25932B235BD4F72A6CFE12435C5FFE
+:10DB70009D7F65E7B22F41BD86210B817388DB8EC7
+:10DB800097E33BFDF1F8BF01CEBBEBF476031FC674
+:10DB900073E60D70DE7D06F4F75301CE37423FE0A9
+:10DBA0001FC0BD0EB09B52DB62AFB716576EB8EE0A
+:10DBB00026CA0CFD7786AF48FF1E2C9F685E91FE3B
+:10DBC0008CF7F8C6F6A7DEE7D3F0CEAB781762C3C2
+:10DBD000F9AA469714DF261D3DAD52E98B4A3F7CDA
+:10DBE000D7F7C2F2E25EFD7B0584EC60E73A78BAD3
+:10DBF0008E604F0E39F07DE0329EC9C7B2A16451EC
+:10DC0000E1C6D285B6AE03C94DF83ED1C80A2EE6AC
+:10DC1000EF0F9CD7E052EDA7F4BAA079830E3E8DAA
+:10DC2000FE23FD0F7D41E38F75C8B77B197C606FC4
+:10DC3000C03CFCE169FA73201AFCB753D981E7496B
+:10DC4000DB54FCDFE10AF57211BC8DC57FD604EB15
+:10DC5000998BE5654327059867431C3EFD650E3BA0
+:10DC600027927E3E9C08E703966633FD35D03FC37E
+:10DC70007E1BF0C53213E124366FB033CB34F94A42
+:10DC8000DEFB590595AFE9A3792A5F2558875179BD
+:10DC90001BB6D922F57F9AF3DEF276AA3F3C567680
+:10DCA0001F8CDA8F36A2BB8768CD61F1DBD9C1D872
+:10DCB000FBD6C3390906B9F5547325799BCE6F6538
+:10DCC00036D3E7B387157C2749E3EB68B95498C38B
+:10DCD000D6D197C3ECF18F5F2E7113C8A515AA5C3E
+:10DCE00062E5C4136880F234937A2F4164EBBEF18D
+:10DCF00047330A210EB7D56B96E09EC34ACE9FF3F9
+:10DD00002D3A4EAD4DEA489022F4514B6C920BF0F7
+:10DD10004D47807BAF35CBEC98873FB03BFEBD874E
+:10DD200063F447A4A4DA71EC5A0D9EAD5E01C7DB23
+:10DD3000B8AB3029A887930F3C8BF13DA70AA72DDC
+:10DD40004A5FF1C67C5A5AB8D164D695BB98FEEAB0
+:10DD5000F6CAE539605FAAE79BA2EDA27BB23983E0
+:10DD60001CD6ECA2DF79199F50FE45FF319DFA8F3A
+:10DD700004EE7BF407F03C183C605488F775D9FB3F
+:10DD8000C66F1D2773C14FD2FAB92BA7D8D06FDD4C
+:10DD90006ABA489FA4CC69AB942FEBE4D919F57DFE
+:10DDA0007A4A0F33815F57E710633B73201BEE9570
+:10DDB0009374AB1FE4CD29217018D757246E58DF18
+:10DDC00085E62D87912ECCC4DD86E7A48E60FBEA24
+:10DDD000BA9152B4533F308741EFFC3C3703E339EB
+:10DDE000A94E46B7A7EC4DD88E275232CA1155EE30
+:10DDF000FD3C770ABE7FA1C9CFC87D16AD1F567EF8
+:10DE00008A5B910DEFC49E4A9D5CD2C619ED1DB090
+:10DE10007F22F6D2F3FB6EA7FC38ABBA3F4C61A66B
+:10DE200052E5A5E58FD2FA5B7298FE3BE50B0CC07C
+:10DE3000B8A7DC4404F8670F079F85FC62AF13DFC7
+:10DE400071D3D623CDC47E1F264DFDFD15E01348AA
+:10DE5000C55CC66F8773D93ABEA3E6D31263FF9E33
+:10DE6000CC7FA8F57AE0FE1FADD75D1EFBDEE81E75
+:10DE7000958F1B6D3DD570955E77CF13EF2DF38495
+:10DE8000DA55B4CADE1CD60FD56788AFCACE3AFCC5
+:10DE90003DB1F78756E1BBAEA3BFF301EF54D17597
+:10DEA0000F9395FB01EFC22FCC787EB3C3C2E8522B
+:10DEB000700745B88794E28CEDEF7E578527C5CC77
+:10DEC000DEEBD6EE2F58D4FBFCC7547B2CD15B8BFA
+:10DED000721DDE58937CF02EDB08DECFD5D631FAEA
+:10DEE0003CAE45BDC77FF3F643491CFBA1D4603F60
+:10DEF00068E346DB1117E13D6E5DBC7B9DF7DC42BC
+:10DF0000A2ABFF6932DC01FD7D7A5B96212E11CF39
+:10DF1000FEF8912A6FC15E5062C22518BE5FA47ED2
+:10DF2000A0A21FFF0A1B3F32AE9328BA71F7E6C8C2
+:10DF30003FCEC1F8CD5C11DFB1B0133C0F5BA6BE84
+:10DF40005F47F513BE5748F55235C86FCD2F02BE57
+:10DF5000179380AFCBCFE6A4EAF4A4DA2E5A1EDDE5
+:10DF6000A1DA0177A8FA26E9BC66373A248E8BE855
+:10DF70009DB17A8B53EDE868F918AD178C7635A50D
+:10DF80005B456F078CE11715AF374F1F93E2D0C782
+:10DF90002D7F11FBB26C6ED03C0DE4663547601FDF
+:10DFA00064569551DF3B7299DFE1C8751ACEE1D610
+:10DFB000D419EB25423DE0AB5CE70DF9297A7DC42D
+:10DFC0009941EEB1FE36ABF4E07BF7AC00EF372EB3
+:10DFD000C965F650499E9C9A4BD3237FA8EC83DFFA
+:10DFE000A11869E549AF07DAC97DC31E98974D04AA
+:10DFF0003FB57C6D55D1115A6EF9A905DF9D2427D7
+:10E0000062FBF7AE664EBE8FF273BE2AE71A3C6C17
+:10E010005E0D9EB05040E1C86C60F064F70F72BCBA
+:10E020004EEE65D7B37AC5B91683FEF1439EC2772B
+:10E030006BAE16BF0CB5C2EFA164D7CB3CE8BBCC2E
+:10E040007E8EA8EF6EE27BA9997ED6BFCB1FE2EE53
+:10E050002D8ECCBBCBB4A218F445579AD30FFAE25D
+:10E060007379C1329877C3857018D036EBC2100F20
+:10E0700076DFFE3C79167CD7E62799C54CD81F770A
+:10E080005E60F0F544D13F21BBD575E965F0B9027A
+:10E0900025004F5AA284EF10D1BF7CD0AB69C9AA2A
+:10E0A000DE482341782F88D8683DB0831CB49EFE9B
+:10E0B000DE260994C23E412875DA74D0730B1DFE2A
+:10E0C0009336D0AFD37DD3E15DA1170EC78EA7D70E
+:10E0D000AA7A87C27FA71EFE78FC31FADEBA5ACF31
+:10E0E00012C78FD6E8DE591DDB5EA59A00CBCBD7D1
+:10E0F0007AEE86F934B40BF81B5D1ADEF7E70536C5
+:10E10000E6A6C23A1DE1805F33FBCB91AE32159E8D
+:10E11000805DD1EEC80DC13BB2EDC99F4A07FCC777
+:10E1200083BBA1D92CDFA7E7E77601D7E348D4F971
+:10E1300035CDCF782C97E9A3D37981AD30FEE613A6
+:10E1400007F09CE083472F09E3BDEB73A378E3EA74
+:10E1500099FFD2B086BD9751BE96473ADCD42EE0E7
+:10E16000BBEA0DCF1E0FE37EF17682FBA00DFDC74B
+:10E170004FC33BAD590DF24CFDEF126435B077E360
+:10E18000D212467F1F5400BD9DD9BFA201E95A2477
+:10E1900022413A0AA2DD956D63F6A886DFD34238A4
+:10E1A00017E267A74DC4DF46CBAF59942289E6AF8B
+:10E1B000F91C7E787FE1EF8FBF213D067886B81885
+:10E1C000BC7B9017FC12E0A3BB959D27EF5E48ED4A
+:10E1D0001E5A6FA1936C85FCC2361701FEB8513CE4
+:10E1E000CC8AA28B59DB199FFC283751E55782EF67
+:10E1F000291DCF4D50EDA8601DDAAF741E9D731020
+:10E200002E9C87982B7F15E9564CC671331BC29CF8
+:10E21000FEFE899646E84A7E3637F566E0ECC77D15
+:10E22000C64DAA9C295F7B947B5B47072FE69A919A
+:10E230006E329F3DC2817F48CB5B177AB03EC607E6
+:10E24000339F657ED3265A7EBF41AE6CC0F97439C8
+:10E2500098FD48E5CA4980EB94690BBEEF776A3AAE
+:10E26000C17766EFB8103E8DE25985F794C0D6931A
+:10E27000A77868A5F99FE54A38FE6921781FACFBAD
+:10E28000E94C76BFBBCBB403DF3BD5F83E9A4F7F5A
+:10E2900096CBFCC9CC3547398827789CCC9ED4E0F6
+:10E2A000D3EA95E4559C05FCCEAA1E423C34AEE16F
+:10E2B000D97D0D159E8542A000FCB461B5BF93AB1E
+:10E2C000BF6D3E44E16B2CE6909E9FFCBB57912EA8
+:10E2D0001B7B38F6BB413DAF0AAB74FED5C1EFBD29
+:10E2E0008A7A65E9008B1F340E1CE7EF7581BE3911
+:10E2F00089F4D948E9CF5E0AEBC6ECD86B96702E4C
+:10E30000E8CB68FA745633B90831D742F60E1CEEE2
+:10E31000FF86D6DAD0EED7E4AFA8C209EF08827C38
+:10E32000FD8DCAEF5AFF117FD5EE07FAF6BD3BFD12
+:10E3300024BCEBD6E8E7FC701EF93F46F50993D7FD
+:10E340005222FC7660A4FF68FCE5E631F91A438F9F
+:10E350007C184B8F687AD6F77405BE97ACAD1FAFAB
+:10E36000E27D54BFE7B1FB578979BC0A8FEC853851
+:10E37000B644F9B9BB14DEF50B144B809F54A71FAC
+:10E38000E23B7FEF7E5DDAA0C3D76981F23BCD9F90
+:10E39000CE77203C942F92F274EBD750CC7E67EA74
+:10E3A000C9EFAE40BC36C0DA51BC3604EFBB0FF14A
+:10E3B000EC25E231902F4126BF1AD6DCC5DE05D709
+:10E3C000F4DF731CE2BF4171E13BD74BFB57207D6B
+:10E3D000128FDD5FC8A15CC375D6F84CCCD5F61D95
+:10E3E000D8BB43D4AF6F857889E6D727D605940488
+:10E3F000692C9FA6A87EFD4CD5AFB7CCB6FD59FDC4
+:10E40000FA4DCD3F41FFE721EF8F30D5F884FA8DEB
+:10E41000067EBA2D8FD92D929A56E431BEDC54DA9D
+:10E420008FF4BFE97213F28FAB9AC911D705A3FC21
+:10E43000D3E260D4836374E8EC5F04FB110BBFC2CA
+:10E44000892007E2C1FD19AEE967705E851C67E7A8
+:10E4500028167CF0F344FD3BA435798CBEAFF599CA
+:10E460004918F0CD3709E3D9BFF1FACB0957CDF9F7
+:10E4700027BA7EFFD29784E782AE3DBBF2F3905776
+:10E480008E26E139929C702DD2C535CF1C3FD081AC
+:10E49000A78DE1E95A7F25D2CFBBE99209DE096B4E
+:10E4A000ED7F623EFC5E74BD0AD7BBDF3537031ECD
+:10E4B000767CED3BF3E15DC94D212E05EE9B5DEBD6
+:10E4C000FBCA1F41EFD51F7D18CF7DB57DF37FA11E
+:10E4D000DD6D0A1D61DFFB9244A877F59903F30116
+:10E4E000BF6DFD6D58FEEE3347307FF26BDF311F9D
+:10E4F0002A8DD0F1BBDF3DF2C3DF433E9088F77237
+:10E500001A824F3E0E79529BC8EE5D055F11F4BF33
+:10E51000DF75F0F820F2A146174BFB39F5DD30012D
+:10E52000CF7968F4FB56457119F01DA550BF793EAF
+:10E53000CD7727D4C78A23EE51E7DB00B408E3AEDA
+:10E54000E142C0075D82D287F25CECCF0579EE2C08
+:10E550000E0BF02EE9EABAE3F3D9CF10B662F94A0E
+:10E560001B3B2F368DF20BBC1F457B3BFA21C4F7BA
+:10E57000BA1E5C07FD1D3613D19C118177B320A113
+:10E580007FB4B986F3530E231CD9762A15F6C79AA1
+:10E59000897AAE8BD5EBA2EEA52D19F510B1D3B4C7
+:10E5A0006C5BEC38E893792E953E19BF660EACC8CB
+:10E5B00006F9413C567FA12FD25FCEF9A66E78DED8
+:10E5C0003FB37E6811CC6349D18619300F0FC4FB6D
+:10E5D00040BF282EECBF11E293949FBEAACAC73455
+:10E5E0003180EF8CD8E4402AFC269B640DE0396E24
+:10E5F000697DC0D20A72861FC95D858AF09861FF65
+:10E60000F0A025983113FAEB52F5D351063F6D8FE8
+:10E61000FD4995B207DAD3FEB13F5B9DCCE36FBEF7
+:10E62000D9D83AFCEB0F6E3F668C9787C6F45FEA49
+:10E6300002FDA2ACC17593049CEFBB5015F1ADDC9B
+:10E64000AA8F6347C77B409EC17EEFE9BCF2C1BC85
+:10E65000D448AAC581A2F1CC4BB49CF65321C998E9
+:10E6600092BE1BBB77A6C9EDCD7B54BDFBE22594C2
+:10E670003B9B833CD3BBC1CBA877FFA545266F53FB
+:10E68000C3F2E0F39790BEEF3DC1F4EEE61325022E
+:10E69000D0B3F61EF2E68A6BA87F153341BADE2CA2
+:10E6A000F49FF642FFDDC44D2D7BB279FEF02D20A4
+:10E6B000FF7EFDBC7D0DB43F653221BD9DEAFDC4EA
+:10E6C00091364E0F1FF303B8FA10F2E366D52E28E9
+:10E6D0005F7BDF01F0C71AEBD9EF116C1E50F98B8D
+:10E6E000FA6380DFCD275E45FAD1EC5EDFD3354893
+:10E6F0006F6E4A6FF8BB095543081FFDF317D2D45C
+:10E700005DC5DEC55D52545206F47672F50F778210
+:10E71000DEDE5C4544E8FF608EFC3CBEFFFB3C87D0
+:10E72000EF511EB4F454C03DC9830B2511F8637337
+:10E73000B076543FE1F9EA60ED00F28F679D1FEC7F
+:10E7400087EED620DAD5DD194EB40B0E3EDF8AFAFD
+:10E7500073B3E4F0C3EF992C3DC16DC5F68A8B30DD
+:10E76000F839B4F397866EC3735B1A3E96560DE77D
+:10E770003279C1E0FEB565E8D330EF5F7FCF0A6F35
+:10E780007E8FD2DFFF05D640AE560080000000002D
+:10E790001F8B080000000000000BDD7D0B7854D5B6
+:10E7A000B5F03A73CE3C1226939327E1E9C90308EA
+:10E7B00098841308EF872704102BB583F2B2220E3A
+:10E7C000C823424846C48AD77E37830331526F6FCD
+:10E7D000AC2FEAA576A06AD12B106DAC51030DA821
+:10E7E00014ABB5D1528A16BDA3222F918CE083DEE3
+:10E7F000D2F2AFB5F639C9CC640262EDFFF9FFE998
+:10E800005737FBECF7DAEBBDD7DE9336D9BFF18E85
+:10E8100032802BD561BAAC03A42B6DBE3B3201D242
+:10E8200000F435986FB07B9D3A9647FE430A6DCE53
+:10E83000C5EFD3C0081501E4DF23192137408A262C
+:10E840000164516A335307C008C0BF0691AA811200
+:10E850006F31C027B5067C3800F84FCB0658CEFF85
+:10E860000058B1A8D5A1617F554F89FE329D46E978
+:10E870002D989EA3BFCB305F013778B13C4B966E8D
+:10E8800098C1A98D53ABDC4A8799F3C87D64E1BD7B
+:10E890005370FEDFA9043D0987E85D88DF310F7EF4
+:10E8A000080DC0F9F7AEF4F6D5A83C73A92E633E67
+:10E8B0002B03BE4FE591350ED82C75ED7724AD6B4B
+:10E8C00004D5F39649582FAB678A1EA4A1E4725B66
+:10E8D00012B52B95F4CD1AE5AF7E14084E59BD74D0
+:10E8E000EA072064C2C15B66C37A47B353F4F5F408
+:10E8F0003DF407E56A84C7244DB5CA4BA99DE601DE
+:10E90000585FDAD96E4ABE97FB9BD233490FE23C7F
+:10E91000A737044A204FC0C1EBEE8443684DF2DCB8
+:10E9200050143CC6131CB07D6830CC6D2C22F87B93
+:10E93000ABA89F6C9B9EB11E3715DC81926B526811
+:10E940009C20C36B00CD03D329B83E3FF59BEF5D00
+:10E95000C5F0C84AD113C163CF25021EBBE76C9333
+:10E960003760BDEA2229E4C4F9DDFFE28C525A6720
+:10E97000F54CB70E98AFF6290B695C08B8E031CCBE
+:10E98000836FD1BD53305F5DE9D5D76BBCEE455485
+:10E99000DE3733495F8FE50F3E2F1994AF0EB84332
+:10E9A0004998BFB259E04375F3D3CA8D98F620BC9D
+:10E9B0007353BB40C98CE2CEF900ACE1F9544F3A35
+:10E9C000D1FF656C1F9041972762DE111EA8E3FA04
+:10E9D000AB27860712BC4E3E9F3497DABF62B30561
+:10E9E000689C57365FBA292875EDE7A4DDDB44EB58
+:10E9F0003F89EB0F60F96F9FFF7388E8612DD28329
+:10EA00009C837BB4462BA7F2F55340A57DB1F66BF2
+:10EA10008F23504878B5272F99F183E6E945381FB1
+:10EA2000A77FF602B8F5126F8D8670AEB6B5D629FF
+:10EA3000D46E4B06C018CCBF70F7409FBB2B9CB167
+:10EA40003DEF8B4B01C65F57A847281885572E17F7
+:10EA5000D2DA304E036E4C7BAC16F089EFE74ECD28
+:10EA6000CDFDAC7085F7E0CE41CDEA065736E29198
+:10EA70002F59E3EF49F680D107E7E3682E6FED8366
+:10EA8000E5D9E9F81FDAB7CD3D42B46FD9D9E07BBB
+:10EA90002641BFAB4C3CB3F6A5211D182FB33DA2B8
+:10EAA000FECF4DBAF98949975BCC348A2E62F1DEEC
+:10EAB000EDCB253E919D0CBEC604E359ED717E5C05
+:10EAC0006ECD0B5CD84F26B5D36C8CDF717417CA32
+:10EAD0002A1E4674372559DFED227A1A963B2C08F8
+:10EAE0009DE320247267A474C5035A07D10FAD8B30
+:10EAF000E8ACBB7A0DBB047F8AC7CB674C3AA9222E
+:10EB00005CC7796F93901E13EEB3E8A7DE966B7B1C
+:10EB100010E7FBA3FD32F3D9F87A56BAAB16A0750D
+:10EB20001040DEC66B53BDC5DDD7DB66D6FB71ADCD
+:10EB30008B53B7AEAD51B0FFA12D5AA90C349E3600
+:10EB400089C60BE078B4CF2913E15319E1E319DD4D
+:10EB50005078672EE179E35C5AD750256C2B25BE9F
+:10EB6000EBB5416BA1E0DFE7F0FF3DE72643ABAB40
+:10EB700033DFCB971E93EF53D93BA67E3F7F5E4C8E
+:10EB8000F925AB87C494E70686C5E4F3EBC7C6D482
+:10EB90001FD03029263F68C37762EA0F0E5D1D93B0
+:10EBA000BF74CBF763EA17372E8C299FF48FFCDDF7
+:10EBB0003F253CA7F527E073561AD17279FF8636B8
+:10EBC000C7AE3F7574ECFA158800D1FBA4E4BFEA28
+:10EBD00089E8D94A5341F92C6CB5233EE0D26C0F39
+:10EBE000E23CCAFF2C87D627988785CF567E922293
+:10EBF000C78C6BF1890BE1579EEFFCF8F263C217EB
+:10EC0000E779E6FD0F39215DAAB9820F28E0E5F525
+:10EC1000A74E9C7BDEF5DBE3D70F1AE3BD87D69FBB
+:10EC200000EFE3D79F3A3A761FACF5E7F90637874E
+:10EC3000B19FCFE74A2C5FF651D198AEFDBD1BB70F
+:10EC4000CED9AB52599F01EF3509EB77CEE34E9EFB
+:10EC5000C7F54EF02782C374130E95B982DE2F4498
+:10EC60009FEF9BF3F81FA24F4CDD6B73991E619FC2
+:10EC70001C1A805D2DAC9776F544BC48F7B9592F26
+:10EC80005BA8B44269949CBFDFA4EF074DFADE5045
+:10EC9000AB723F0FD7E670BAB156E3EF8FD416725E
+:10ECA0001AAAD5F9FBE6DAD19C3E8AFA18A58FD7C5
+:10ECB0004EE3744BAD97EB3D593B97D3A76A7DFC70
+:10ECC000DDDA9FEBCDFD016F06CBB3F8F5CC5F9598
+:10ECD000182F412EE2F6F391CEE4F3F0B52EEDE5D8
+:10ECE00079A9E7C3A3D50773B7BF1C8507D7E5A6E6
+:10ECF000641EEE81FF1805A3CEC9176EFF65ADB681
+:10ED0000FD65FB85E9C2C21738FBE18044F5AEA77B
+:10ED100031C722BFC9DDDC1070770F9F4E3C8AC31C
+:10ED2000572FE22B7E2D21D9DE8BCAC3BDA3C7F995
+:10ED300093B9CF567EE64C81AFF1FDDE6FE2DF2C5A
+:10ED4000C24F2C9F1D47AFA77385FC3C9D2BF4F44D
+:10ED5000FDDDF08B7B726DA6FC14FB3E6B9FE04BE0
+:10ED600077F6983FC197605C294F8BA1CFD9336369
+:10ED7000F771BF5DF0B7FD7F92436B12ECFF85DA50
+:10ED80005BEB896FF72773BD9FFE7F466FFBAF4D2F
+:10ED9000617D7EBFDDD72F2B6A7FF65FDB636EA2BE
+:10EDA0007DFFDF5CBBD8AF421548BE433A18A407CD
+:10EDB000E192020ED2E5A0403D4C7482C610D145CE
+:10EDC000F778A9C0618B9E64826712EBE39FCF4CFA
+:10EDD000E1FD079F6A4054FFA0A8AC976EFB2EEAA6
+:10EDE0000A349E82E3A11E0ABAAD73FFF2E8BFC9DE
+:10EDF0009DFC5AEE9EDE2E8407161F994D7CE43C46
+:10EE0000F2BA6BBB8BE32387888F5CFACDF3118B4F
+:10EE10008EE1EC8D03BC295DCB67111FE90DF0D3AA
+:10EE2000DCB7998F7C6D3859746BEA13F1FCA4DB65
+:10EE300076CD9917907F263F57FCF561C48BDBE4B4
+:10EE40009486F5D8E42EC5FF73CA07020A3C86A94A
+:10EE500073F5E9DE878673B7850AD71BC2F69D5323
+:10EE6000F1FF32CCF6A053A57A0FF5F8F7ED945FD9
+:10EE70008D1CD389E99749FD4380B640699EE03FE8
+:10EE8000B2EB4CEF4351F3B3ABD0273A5FDAEAEA87
+:10EE900073286ADF86EF5563F223DA7262EA8F3AEB
+:10EEA000A0C5948F0917C6948F3BAAC7E427444690
+:10EEB000C7D4BFEC8C11932F872B62EA57B866C476
+:10EEC000E4A7A8D7C6D4BF3C67414CF915DA4DB1C9
+:10EED000FD157887E7E1BA173ADCF5522ADA69B905
+:10EEE0004619E59393ABFD0BC84E5AE3516122D509
+:10EEF0000E85086E750E97BA1EF9D40792D11F10B1
+:10EF00004FEFB3A1D59D8FF5E530507AD0A697523B
+:10EF10009A676CF1119D6E2F4CD6681F920702B450
+:10EF2000919C52F424407EE2E811F95D01EDCB6F33
+:10EF30006CF01826DB5554F4A97E736688ECDFACC0
+:10EF400064DF15348FF5B606CF1ADA671B781FCB4E
+:10EF500064BCFAC968CC1F7E41B1119E6D6FB1DDF2
+:10EF60003316F39F61F7329637B59DF8C995981F10
+:10EF7000DA66D7A9F65090D94E5CAEC03D4A7AF712
+:10EF800078F6F10F843D15FFFD677982DF6755083C
+:10EF90003B33BEFC8E3C21DF3E76242E5F6EB6AF47
+:10EFA000B86BFA43C4D7EC6D7620BFC5AA2CA32753
+:10EFB0009C4F5F3D930FA1E15179C50BAA9BBE0FFA
+:10EFC000E4EF1577CD83B05BF4437EAC5549464FF3
+:10EFD000F23B7C3C29F13C6E31E7613FD3A39B7E41
+:10EFE0003DFCFDE3BCF3AFD37E2609421989DABBB1
+:10EFF000F97B563071FB7BCCF13F4E4F5C5EDFD12D
+:10F000007F2F086444B7137CA7739CBE5C6E3F934C
+:10F01000068184EBC8E4EF9063E410DEEC423A270B
+:10F020007E519E96ED0024F1F91079C540F8CF206D
+:10F030009300F1145C7A29F12950EC91B04517281E
+:10F040003F1680F201D90B3644C67338B51B56DB28
+:10F050003F0847D1D10C23360F543F4ADE7C427D16
+:10F06000E37A928714A612BE9F022D554D805F56FB
+:10F070003ACF257B95A8F51CEC464F6A33E178B072
+:10F080005762383E6FF2B191F320A1BED696E711D8
+:10F090007659A1DEF37C7283E0EBCB88EE377E1FDE
+:10F0A00032B9FCABC219F182E57AE4BBEE10FB2960
+:10F0B000BF71785BF8DD27062F3EC98F9F777F2EC3
+:10F0C0002FE8EB7D2B8FE58A3690E4629349BF4DA4
+:10F0D0008AD163989BF8185426827F9F7C534F8D6A
+:10F0E0005B771318390BC8AFA1D875E267C932F83E
+:10F0F0009F4E00FFF875A79AF3C6F6735BA93D789B
+:10F1000074C1E7C0EBCA463D9FFE854B280FBC6922
+:10F11000A7FEE7F93DFA7A54813ECF13FAF40208CC
+:10F12000DB890F77819F3BD34E7EDB78387A419B1A
+:10F130002FE55F189EE905C6E7041F9B4BCDDE8ACD
+:10F14000EB9C1FF000F9696E98079E629C8FEFBBE5
+:10F15000E96F185877E155434AD6527AE9F83A9957
+:10F160005B4F66BD4F0AF491CF5DFAD5F5BE3A8F7D
+:10F17000AF90E8E390A42D61384808079237BD8F1F
+:10F180000F5C1005C715FDCA7F9F9F45E7036064AC
+:10F1900090BF788793FD56B001580FADD9397813D9
+:10F1A000C9852FF27DAF51BD51934DFFAD11197837
+:10F1B00075CAC5C30BFFEC44271782976CD2FB417D
+:10F1C0004F62BC19972FF6EBABD24B66BE8043045F
+:10F1D000E1B0B9EC9BA717845F0CFF782D5FF05F5F
+:10F1E0002BB5E0366A5AAC7FF735731DAFE57B3837
+:10F1F000FD22DFCB706EEFF7E9E12492FF0E5C7F1A
+:10F2000002BCF7764337DDADBF3B7AF9A6F8F2C111
+:10F21000E4C4F35CFC2D99E71B344FE2F32589E746
+:10F22000F96F17894FB83F4B5CF9DFFC3CBFC8371B
+:10F23000DEC8A779A6279EE74F2F129EC8EC96B48A
+:10F2400062BDD9C807A9DE373D5F082C984272E835
+:10F250001A9FF0FF1723C7253E845379F4DC70D240
+:10F260006FF5751B88EFACF4E80195F9C81BF982BE
+:10F270000F8281F399394D627F52FB884F97288422
+:10F28000EFD9D09A46FC6AA793FDD9F1EB0F99EB21
+:10F29000473A799CE004D32303899F1C1C98984F1C
+:10F2A0003C1E5FBF3EC2F2697D7962FD749B49AF2F
+:10F2B0002B5C0DD3B26DD1E72BB84099B86CC0E888
+:10F2C00043F2B64C5D4BFCC4817289E0EAE833A49A
+:10F2D00027ED07E6BD12F981735E3F207918DE271E
+:10F2E0003AE097D739CEF1DABD6A81BD7B7EBE5C4C
+:10F2F0007E66A43FC17AB66ABE5DF95176E3F22D0F
+:10F30000AFAA05D1FE7108DB800547C4E6E5F341ED
+:10F31000D36FD0132ECA6F509C29E865453F2FCB81
+:10F3200007921B643FD7BD30A6943617F50F20FB1C
+:10F33000209292CCF222D87B6CA11605CF0FF32D30
+:10F34000FD53EE46AF74C47C7FB7D685266567FE55
+:10F35000FAA3FBA6903E3F1FC2EBA8FEFC553DE87A
+:10F3600008B2639D1DFD9D9162F4DBCEFE15FE5E2D
+:10F37000EE72B7CA433175FF2EE17E6CD58CA304C3
+:10F38000CFB5FD8C63B4CE78F805EE1A9FC67E0427
+:10F3900082DF655DF7BDBB7DFEAB669CA6FE5EE8C9
+:10F3A000A75A7E1D9DCFE392ADF361453DECEA8403
+:10F3B000F757DD9764D3BF88FAC4399AB701557EF1
+:10F3C0009ACF3C8BBEE3F41C2814FE803A4FDBBA84
+:10F3D0005D517478832D9225E476781D3999FE6706
+:10F3E0004712F38FF61DBFEDE7E3F3344BEFE8214F
+:10F3F0009FEBF1D5E767F917ECC989F569EB1C6359
+:10F40000B7BDA880F5123AE71D8D79495B44F6AA8D
+:10F41000A2821EC4F5955F8ED884FD4D92FBB68402
+:10F42000711D9FC3D9E40998FE2788F5AF7AF3A32D
+:10F4300074F2634E52ECC7A3F953BC1F684041AC51
+:10F440003FF914CC4B6D25B88C4F67B86C6F99940D
+:10F450004AFD943C3FB927A5BB6AEB55C5DEE90FD1
+:10F460008A9F7F793776E9B002A177BE9E6C0C2B1C
+:10F47000C0B4BC9BF58F32EB85938D5105599DFD32
+:10F4800051FD44F1106D832C3FAE80EB358105AC0E
+:10F490006FD95CC857897FA2FE2AABE4272CB03312
+:10F4A000BD1BA0A9D9EC3714FB8F7C5DC1FC0433D4
+:10F4B0002FD5BF1DA4761B6FF1F03938F83420F931
+:10F4C0008080E173813AC9CF7E0717C57D60BA5E3F
+:10F4D000D237902E26DB2219822E4222AE017C0AE0
+:10F4E000E57F2B85831427B0D6F5EF3F273FB81172
+:10F4F00054206922E615603F63E0600A9FCBF1CC9F
+:10F50000701E4E6B5E663EC5CCB7CF9A3A6D00A6B4
+:10F51000B7253FE2213C0D4BC847B19F2F93FFBD5C
+:10F5200095E9C69FACDB7B937FE93DCE4B2B937572
+:10F530002987FC4F9E42D2535743B2EEC4710C77D9
+:10F540007180C67568C0FEF86468E475B8DD9F0414
+:10F5500008282AA812DB4FC9BE65056CAF009F932F
+:10F560001F7E2F6533AD3F493DD57A077ECA0083A4
+:10F57000EB65C4C9C72CF72A89E337BC4A9C5CF405
+:10F580004904FF9E73E3BFC7CA4B171C54899F48A9
+:10F59000ADDE9C73C89FDA086E659D706B53845D09
+:10F5A00067C12D30C9FF4B826BE04EA71ACCECDE51
+:10F5B000DF86001A45FA789BBA642BD547C3096CDD
+:10F5C000D45F8E585FA0D229F641F16DA5F6EFD831
+:10F5D0007354B27B2C3C7B68A0C9AFBBF1773C5025
+:10F5E00020F4A3EAF4C3D524E70007B5F50738995A
+:10F5F000727424F10D9497F5242F93EC06C3DB92DB
+:10F600009B2B9AD600D15575F30220BEF28EE41BD7
+:10F61000F032DB23C076D99C6981576C1AF9B26647
+:10F62000AE7363FA49411EE3D7FE57A6BEC26C48CB
+:10F63000761753BBD2CBBC53B270DC6031E8776233
+:10F64000BD60926FEBB3B4AE3765FD318DE2212A18
+:10F65000E0C3E12632E1F74DB333D86F9A5911A9CF
+:10F66000A37881C8DDA0527C4F17FA388BEB1B09B9
+:10F67000F00B1E0BFB59A4B612FEF4427C93D4CEC1
+:10F68000F247A93C5FE42FC37C8DD852C86F29FF95
+:10F69000DE0882479B0C141655D322D968FCFC99CE
+:10F6A000C359AF29A0F2CCE8F2B4E54F61BE60EED9
+:10F6B000049DC849B3F97E762B95BF01BC0E30F985
+:10F6C000F7A838FA1DD749375C5EDA91F757D07C36
+:10F6D0005FB919D88EAD31E56D0CBDD162B1CC18D2
+:10F6E00049F8D7D10F503F15667E9CA2723F7DFD31
+:10F6F00060F205EFC607F89CC0A6937FB24E6A6021
+:10F70000F840C0CFFA1EC5CD10BDF49FB76BB79DB2
+:10F7100006CB1474A7EF157457065E99E03552BDF9
+:10F720003B48E3CF9997CB7C66CC5160B830E5611C
+:10F730007E429AC4FB943F209FF165BC4BAF97116A
+:10F740008F64B9343F09C79B3B4FE2F38959735D1E
+:10F750002109FF390BE983E3A1145FEE6CC4F7398B
+:10F760003E499CFB627E5E943F1EB5613E379BED39
+:10F7700004FFD309F0397F80C077AB7DCD5A478C29
+:10F780007FE792016EE1E71830F59302E6BF22AE03
+:10F79000252BD91B117CA381F9D4611BEADFA4FFBF
+:10F7A00082C1FAF63526BD5BFC6296710BDBC1B3F4
+:10F7B000BCB17AF43BB4274407D74AACE7CE997B77
+:10F7C0007E3DFB5C8164C6DDF455599E99DF35D0E2
+:10F7D000D89EBE9AF49C12FC380DF59028FD7EDE72
+:10F7E0006D67D3B87ECFC7579CBB0451A152F09729
+:10F7F0001A8427F1CBF26B15A697EAB50E8EFFAAF5
+:10F80000695E63CF267CFE21E8025FDFAFEB83F306
+:10F81000EC53658C90B528BF4D554822BACE269E34
+:10F82000C3F08F38C82F37DBA157D1BA66A7831A28
+:10F830004843BCBCF68A8DD4FF5A17A832CADBDE17
+:10F840002D6F8608AF9095EB849388391CD7D657D7
+:10F85000EDC1E70BF5B6611CB755EF49D1A3E3A4A1
+:10F86000D6AFE9C43B8AD7D29C304C35F737919D4F
+:10F87000346480E0570F4AC0F22270AD8BE19C9552
+:10F880002FE295B2527547308DF88D66D5E338BBBF
+:10F8900007EDBE5EC3310DA15A29F647B48BA7FB15
+:10F8A000AC0CB39F1E9A1444629CD9525A6623B87A
+:10F8B000B953748A4FB4FAAD4836ECC4B72A8648B7
+:10F8C00023820CCF4DCA22D24F9362F9BEDD2EF6B1
+:10F8D00005DE157C3F5E0EA21C60BE4F7EFB6019EC
+:10F8E000CBAF8A01592C0FB89FD58A4B75EAD0450A
+:10F8F0009E657A2185FC5CC31064A4AFB7E5786788
+:10F9000050FC5EE07585FD6A6573F5EB1647EDEB1F
+:10F91000E60E391099CFF1503FD4FB503CD4DAF2C7
+:10F92000CE3CC53D56428383F0BD324E3E2E73BF62
+:10F93000CC7AE4B247ED9DF80B1427AAE713FFA891
+:10F940007AAA8B3F88F954273F8BB32F417D89D604
+:10F950003302F931F121A3204566FF32CC13721432
+:10F960001E97C82F267B56D793DC6B97521AE4B2AA
+:10F970004E3E39C2DCAFBB14EF4B141F1B407DE978
+:10F980003115BACA01F0B3FE3211E526E9D152CBE6
+:10F990001C99C6DDB814FBA6F37C255C41F9DB9607
+:10F9A0008A735208DCCCE760E3024E95E8FFCBE4B3
+:10F9B000FE6BCD71FD7664D6C7D41F727F80FB428B
+:10F9C0007A8B44FC10CB7B4FC3A64807E35A8E705A
+:10F9D0007F1B33045DC4EB312FDBDC219B8DF86E84
+:10F9E00080E54E128472087E4681E0B36507049F6D
+:10F9F0007D2E801AB44CAAACFF9AE9B9AC0772F913
+:10FA0000D80870FCCC0EF0559BFACE5D034650B47E
+:10FA1000A85FF071535FB0F4B82971FB78B9FB7E31
+:10FA200085F8D6E5395DF64BA6FEA781C4FAE21546
+:10FA3000DAF9F99661F12588E54BB97096F70FEE82
+:10FA4000DE732BF90982717A50F022F5A05EB9BEFF
+:10FA50005FD0FAE2F5A1EEE2299F1A7071F194A845
+:10FA600041CC27F935D6B2B3E2F0A77ACFF1F9F756
+:10FA70004027DE75E07360D375B40E94E72AD97D14
+:10FA8000D26F1E62BA5E8BF5E4F104CD83C1FFC272
+:10FA90007CAB0DFC14AF003EF534E1A92577911342
+:10FAA000319ED42D1678374A11F9BEA8C8125E06C9
+:10FAB00047C7EBEBBE5CF2471B65C51C1F6BC9E378
+:10FAC000E13683F16404E81954CFC2939161518EF9
+:10FAD000F8F11AF19371D3105FF228CE76541FD249
+:10FAE000BBCA4163FC288F936B15EE990AD17985C7
+:10FAF0002B7EFF0D3E779C6CE2C714F5EBE1C7252A
+:10FB0000841F96DC423DF9AE38FBE2AE38FBE22BB7
+:10FB1000E0C7918BC18FC845E247BBFD87EF05CA9F
+:10FB2000D89EF5CBFDBBE287D472DB927B88DE8367
+:10FB30002940FBFE74925AE1C679D6548AB8F3E1A3
+:10FB4000BF2F08523E7B452EEB854FA7E92F71B999
+:10FB50005F9497B519720AE6F3576139E69FCEF5BF
+:10FB60005650BE66359663FD11FB7C41CA17FC50AA
+:10FB70009497DEE97F2985E47C40B47FE1589DECD1
+:10FB8000C1F2509DD9BEBCA182F235F5A2FDC803D9
+:10FB9000A120E507DF23C6B7F4CECB4CFEF9B47441
+:10FBA000EAA5DBA93FE49F9B917F8E3B61946EC3E6
+:10FBB000FC22D56623BC5D1C09D8091F0EDBAA46B2
+:10FBC00012FEC0425F0EE19993EC56B9937FD9C8FB
+:10FBD000A983ED262A76D6FB5E95FC0AD59B4624A2
+:10FBE000417276B4EE22FE4EF1C89B51DE1499F2BA
+:10FBF000C88ADFA57B0433A2F6AB68A090F356BD9C
+:10FC0000EC748117F0B0C00B2BBEB8F52190C8DFA3
+:10FC1000426B633F449778633FCBEF50BFE2618410
+:10FC2000B797539C31965F3E56C419979E3B3D351E
+:10FC3000915D347CA0B0E78F9AF722ACEF95A15C80
+:10FC40001BD1CFD3843CBD099EDA1F495F7A9AC687
+:10FC50001ACB200DC068DA47912F7FBCEF7DF57D70
+:10FC60000196DAFC0AE111F497749AFF556DFEC90A
+:10FC7000BC9E2A80EFF54AB00E53DE2F093A368B30
+:10FC80003811C17F6699FB764C9DF7CAED6C3F7BBE
+:10FC9000743B8E3369FC00A6FB9973258BEEBF3352
+:10FCA00090F4603AC1607FB68FE3DD6F8290830687
+:10FCB000B9298EEE97BB3F7B8FE4D2F22DB174BD94
+:10FCC000025A1DC2DF1C79E46DECBF72438A4AF20E
+:10FCD0006745636CBDCA0DBF3F209574E50395165B
+:10FCE0001F08C5F2015438041F7868089F7FADCC07
+:10FCF00091B54319E4FFF0B3BC4F0221EFEF52F48A
+:10FD000030D35F8B53D851A67E7E9B2CF4F32470A6
+:10FD100069EE42E2C336335E55E4ADF1212ECEE505
+:10FD200054C3CDCC6FAC78180420CBFB5381CBD51A
+:10FD3000683F5B079F8FA3F7D2969EAD74DFC0F23A
+:10FD4000B3A07EC0F6152C424E378EF910EF9BB44F
+:10FD50000CFF3F86D6E5E0753DD4A33FF3F7D548C9
+:10FD600010CE52B28B95E256EA7388A02717D111B4
+:10FD7000F1F769B1F65612083D7E789BF0E38CE806
+:10FD800094FB75B4BF4ED05D42EE3700D157B7F645
+:10FD90008A7B55427B852514F63F7B9AE0EB17B2B0
+:10FDA00057BAB3473AF63309F5364C67FA92B6D3E9
+:10FDB000BA2F3B9B9A92289E6A66B9EC25BB6CA62B
+:10FDC000DDC84A4FA0E73F60EAD91DF57D6EEE4FD2
+:10FDD000F1656CA7F825ECB795F87FDBEB8E8471A5
+:10FDE000C98AD9BF6237D444FD5F454EA9287FBB7D
+:10FDF000E2CBE67EBF017DE579DA977879E4D81D1C
+:10FE0000774E098181D171054F0F12FC6E4281F14D
+:10FE10009B81744E94D49FF99D568AF6541FCE73DD
+:10FE20007F076FBE9CE3243E03E38271126BA3FC49
+:10FE3000E707D3129F8BBC61F2D7148A7DC3F47697
+:10FE4000CDF8038D7FD421CE5D8E269BA9479C5B88
+:10FE5000BDD3515FF0C788C5276DA2FC687AEC79E5
+:10FE60008D55EF94D9EE50ADCBBB36CAFFAA3DE419
+:10FE7000F4939CCECA37EF71AC02B69FDB9F4FDB89
+:10FE800014BDAF670796A70CA2F8A27CC3D18BE084
+:10FE9000F8BC907FD54AD841FBFBF025BEA334EFD8
+:10FEA0006A0D8C67A81F2DECB8A698EC06111FD21E
+:10FEB0006E1776607B9248AD799D1D382365109D45
+:10FEC000CBDE1C66BED8919F1166BE7776A097C721
+:10FED0006D9F65959BF9FF10790D549DE65BEE32A1
+:10FEE000ED8742752DFB5D51EF23BF4DFCF901C03D
+:10FEF00078A11F9BF19E46DFBFF3395E777E7E9B24
+:10FF0000ABED95FFC2EFF34D7FB0AFF9D357EED015
+:10FF1000187F0ED3B80B4249C071DFFFA45FBFBD8D
+:10FF20005F1BAF677D79A4FFC3651C2FC07EB5152D
+:10FF30002DBF65BEBEC2A2FBA658BAEF65C2F14294
+:10FF4000E76AF1E72DDF009D0D1C9440EFFB35C9FA
+:10FF50006BC4AF29F274E66BA79A24F68768D05673
+:10FF600047705E29897D59F9EA8D150ECA2F0695CD
+:10FF7000F97C533C3FF305494F585E0F2CEF4A2163
+:10FF80003F95E05DB357261F02DFB7D1A2F824DD0D
+:10FF9000B7D1A2EC62BA6F139DA7FB36D1F5E9BECB
+:10FFA0004D7439DDB7892EA7FB36D179BA6F135D51
+:10FFB0009FEEDB44E7E9BE4D747DBA6F139DA7FB4E
+:10FFC00036D1F58F80FFC1F112C175E206826BD385
+:10FFD0001AA74A70C5ED7AAB289BC519E31FDDCB84
+:10FFE00089EE67B967AA6305C2614F8E0CD268BA01
+:10FFF00077B32CA6DFE57215FB0950ED6039E2C737
+:020000021000EC
+:10000000FF313CE522B6933F6F962003F175E986F8
+:1000100038FDA1E5DE3AD2B76F0AC57E5F0E517E8C
+:10002000F7DCAEE7404B0699F1C0BDA137E1F31410
+:10003000D9ADD33E9FDA27EB4E305D00B4CF5B8560
+:100040003FB214063D349EF7D10E218D8E4744F900
+:10005000A98D722890DB793E746AEFAF0EFBB0DE9B
+:10006000D25EB24A74E7CC89DDEF242D76BF7B14D3
+:10007000C6EE778A1EBBDFA9A363F73B1ECE694697
+:10008000ECFE833C9DE1BCBC0F9A77387EC6B45829
+:100090007CB0E03B1AFF27F05563F82E41F83E2C68
+:1000A000D1B9DA3D7BFA685DE15CDD7CAF83F4D7E2
+:1000B0008B85F37D7170FE1CC657B819B830D335E7
+:1000C000B2535F2ADBEBE72081636ADF0AF35EAF9E
+:1000D00038DF31E18AFA0BDB0B51E750F5B2CCFA8D
+:1000E000CC26A267233385F980BEA107EFD73097CE
+:1000F000E86F31F8983F2D8ED36B96BAEF77905E0C
+:1001000013BF4E9A0DF95D2A5B845E13BFDE2EFE8F
+:10011000A842B5B58FE0DB8D0FEBB4CC168B4FFB4F
+:10012000C88F91096D0ED263BAE38333728C5F93EB
+:10013000DC402E06040F610AF05F427DB2A6A35890
+:10014000F8E79D7EE1E787401ACF6314887970A3B2
+:10015000287FFF2825C47E073429D8BF64D963F1DE
+:10016000F084BED2DAB7B05FF92530E1A8CB92AD0A
+:10017000D37F8F56A041FAF5C8CF84FE34DAD51864
+:1001800054B4AEF6F927F9E639B762C67F5EE01CD3
+:1001900092E64F7E8E6BCCF8BB092DA35EA17CC787
+:1001A000B9E4CE57FBD07E8DDFF9FB0C4ADF92B469
+:1001B000C7EEC0F1AF96045EC4DB95C11DE334DA2F
+:1001C000FFCB242FFB2BA682BFAFB047423CAF89A9
+:1001D0002E1FEBB5369761E7F328D37F09109E4AAF
+:1001E0007AFA32DDC1F358AB7E3095FC31CBC1F4E5
+:1001F000C734C7EE5F177B28CE0EAAC2FDA77EE3E9
+:10020000ED9E047814170F102BEF17145AF7CA45F8
+:10021000BC8A06E2FE77A5E947AA746DF4887338B4
+:1002200094737DA18BDDA410E0C7F07985BD90EDBE
+:1002300062B407F8BC5F73248AD7033593CFD56FB8
+:1002400074CF64BE7C637D17BF0EE3F5E2860BAC12
+:10025000CBD413C6D3379CFFE1419A90FBC9D3F7A7
+:100260001A545CD6D63F5A9FAD7188FBB9E0CF884F
+:10027000B9B730B8509C7B97997A53A5CB8453611A
+:10028000A08EF4E30EBDA98BBDF8F5EEC958F12E92
+:1002900008AFA242C6E306CF9ACCCEF31D6B1D9FDA
+:1002A0008C687BBC15E125A74C76117F5CD1CF37DC
+:1002B0008CEAF73B103E4C74036E8DF5F593CDC779
+:1002C000F6CB799DEB423C7B701CADA35956C5BD66
+:1002D000F940DD38ECB7BD54E05DF7F6AF8027CECE
+:1002E000EBB2C2ACAEF3B2E2ECA7C845A9E128BDBF
+:1002F0003DC3845FFB10EF146A57F6C7BE1E9AAF6A
+:100300003DAF714F6FD28B6F157A31EE2BFB41648D
+:100310003B48A4974E91CFDE42F95339A092FD9904
+:10032000D923207B48CF5B00EC2702DDAF13AAC89E
+:10033000FD8AD84ECEBE15ED27ECF7DD5537A6D198
+:10034000FDFEEC944569F96E8A6FC2A90EC0BC64CB
+:10035000F38AFBD9CFBCF76F65543E8FFDD2D73BF4
+:10036000C53973EE0FFEB69CE900B474E7181ACFD6
+:10037000C7EF0B44D2649E5FF9B59F0D27FDAAF726
+:1003800059F730D2CF7AD1392F8274A8491F9755A7
+:100390004486FBDD9D70CACC4F6CBF649BF03898DF
+:1003A0007C72369D8758F7301EEAF1069F879F348E
+:1003B000CF4FF28C69A984E707075AE75AAD59E491
+:1003C000B2AA4E3252E7D03CDF94F97EC567AA91BB
+:1003D0009A86E527C1CBFA63A0CDCEE744ABEEAE5B
+:1003E000E899EEEE3E6E7F4DA1B06FAAE2E2A2AABE
+:1003F0009456079D6755FD9371514D6871273A0FCB
+:10040000B3D65F9DA68032145309BCE7ABF7E23F39
+:10041000E48470DC629677777FE3E7E6FAACFB1959
+:10042000D5743F033FAD7ABEBC279CC70EAD3E33AB
+:100430002EE61E04D96BB4BEEA3313F97BC55D27E3
+:100440001C84DFD40F3D8560DDCFE80ECED985C298
+:10045000DEA8A67B0D19D1DF051D77F69FC9E54FF4
+:100460009A707B72AF6DDAE604F37CBD50D8DD4341
+:10047000B214F6175CDA0AC6A604E35AF5ACF70D17
+:10048000BA9B57D3A4F07C9A37C505271A6FA709E2
+:10049000476BBE4DE9E1255E71CE3A90DE2FE8C88C
+:1004A000AB91FE5747F1D3B3A67FA0E93BE1FEFC39
+:1004B0005EC615C28EED6E9FE7F4F3A5137F18A9F3
+:1004C000B4DEFA4A269B5D407EB49EF35A6D242723
+:1004D0003BF84F37FBDD096739E61E4C57383BB810
+:1004E000BCE3FE19181E299BE410B03EF0D01F4B50
+:1004F0001C0E1CFF980D22C477A6C87DA7BE4079AC
+:10050000B41F882E8FB1ECC07483CCF7998E3D9ABE
+:10051000EF20BB6C49394464E45BC7DEEA5F477196
+:1005200097DA02D424C7A1BAB336F6FCB1128C3DD7
+:1005300029D8EEC603DED456CC2FBA27568E1D7BA3
+:10054000EBC70EB207A4856E3FC515E13CA7BE8080
+:10055000F9C5CD0EBE9FB5E4FEF8FE62F5E06C5322
+:10056000DEC6EBC39F179AFAF048184972E685DA9F
+:1005700066F17E8E791F11F53F23119E587A7028FF
+:1005800079D2DF99EF43A34C7C699C92B8FE92220A
+:10059000B10F2B1F3BEDF068DDD3D971E42705388F
+:1005A000FE895A95D3ACC1866B30F63F60B02F659B
+:1005B00030B697B548FF4FD8CF29CE4111DF385F0D
+:1005C00043F7D448DECE157A8253BEB992F5D13EB8
+:1005D000A006597FF1FBD99F6E43FD248DE2376E53
+:1005E000913DEC6F10EF078DF968511AAD37F3BFED
+:1005F000E73C4D70A53B0E40EFB0941BA5C4DFD780
+:10060000CF70F379FF265B80FBA140ADBB109EA1AC
+:1006100027C7EC26F77941E3BD93C8EE535B76B567
+:1006200092BD526FFB740FC525D44F043DC8D00E48
+:10063000F138352D339EA6F6FD67BA75BA5FBA3E1E
+:10064000D72855A3FAD720F21EE99927AB6CEC37CF
+:100650003DD5FC0B3EAF42FB2E42CAF7A9AA3CF6A1
+:100660009B59713F7CF697C06F7802E51B44DDE72C
+:100670005ED1B4C946FAF8A5B451517155D6BCAA99
+:10068000EE6CCDBE8EE4EE130ACBD1CCDF5CC1F1B3
+:1006900003B98A26113CAF9354A18F9A7AF2B560C0
+:1006A000FD35BC42FAE942D293110F3F94421CAF90
+:1006B00069839667A9FDDC1CA10F82D63882FCD71E
+:1006C000E12AF37DA2E5F634D26FAC7382EEF0A19D
+:1006D0003B3F0FF6B4E41D1CF7A404EC6FAAB14530
+:1006E000FAD3FC8EDB13CBD779834D3E30D01F621B
+:1006F000799E0EEA6334AF025F2ED165B54D5BC9BA
+:100700007EAF7D5E8E0F6997D4F498775ED4865F56
+:1007100093DE5D6353857D73C028A5F398F6194574
+:10072000FCEECB497BB83FF311E47B149775EB13D8
+:100730004D3315845B756FD4BB30BFF9895D3315BC
+:100740007A87272FBCC486F95707FF45940F091FE6
+:10075000A6FC1F9FF848940F0B2FA1FD39F9C4691F
+:100760009127030C11EC6F4FFCEFCC00AEEBB8E916
+:10077000FF043D3C9FE659FDC2205BB47FF1C86099
+:10078000C1378F27897AC773E186AB49FF280CF3FD
+:100790007D18ABDE6B83CDFB0426FEDFF462522BAB
+:1007A000C5095BED202771FF41B3DD4DE67B59485C
+:1007B0007FBFA27A2FE768E9BCCF479147115C9EC3
+:1007C0001FCCE73D370D4EE7FA049FF4A2AEE32DB0
+:1007D00023394F72C01E7BFFADC1DC2F2812FD579D
+:1007E000F756D3683FB2D3859D811B927617BF63BE
+:1007F000B0C9D4ABC4FE64CA6A695065B9339CEC15
+:10080000E697CFF62D65BBB9A29BFB9E83851CBBEB
+:100810002928C689F4D2D4CD7CEF1C0C8A4779B93B
+:10082000396973F47B29274DF81E199C26E0D7B14E
+:100830000F3D251E2768C2A52FC2BBB8137FACF69B
+:10084000175AF7F67FD1BABBEC5399989FB51E8023
+:100850007B051C707E69A8E71F5F63B61B6DCD43E7
+:10086000637AB8E9C5DB3708FEA7A5B3DD0E3F11F3
+:10087000707059E316F1F9E40A530F96036F38C804
+:10088000DE5851DFC6EFAFAD6814EF6D75D29DB184
+:100890002A9ACE32F3C53A33652333C8F488EB6322
+:1008A0007A34CC788358FCE980773C1D77E94F4B4C
+:1008B0008FED4FE3FEBADB87B08917DFD83E041314
+:1008C000C3B383BFC4C1AF831E73CD76458867654C
+:1008D0005DE9F18FDDD171EED71CCFBC77B2E27646
+:1008E000335E558BC5E3154DB9B685459DF5EF6E65
+:1008F000BCD71B1D4FEB6A5A1020F957D352CE714B
+:10090000B52B9EDBFAEB00B65FB6FD010F05531F5A
+:10091000531AB2492FAE7A6C9DC7A0731625E021F9
+:10092000BE792C244F4B747F75D41029461FABA67B
+:100930007F62FFC79FFC5BDDBFE1FCBF9050BF4201
+:10094000785737FDB58EECB73D862B4272FBA81267
+:100950009E4A72F4A6056E3FBD2F58D31CAB4F2D97
+:10096000FBE503D91A077707FAD8589F6AED43EDDC
+:10097000AA1FB5EB64BF57EF93751C066A20524758
+:10098000F38B6F5FD3F8A183E0AAA23ED8775CD740
+:1009900072E4248CF7354D3FFA54F6507AEC1D285A
+:1009A000A1FEA2FC1108F7CA6EF4B2C221B1F7028F
+:1009B0002CF840288BF59BE0130F95BC8FF33AF190
+:1009C000E86B1EA9285A5EDE29CEA91A6FFCF90B26
+:1009D0005AF772F524E907CEAE7A80D62C0925BBEA
+:1009E00045A455F6560FF905AA36D9F5007EAEDABC
+:1009F000FA8BC7E95C05DE76EA74F458B5F5B48382
+:100A0000DE3FAB928C88C47A1678A4919DFBB47CAF
+:100A1000EB47C25FD54B86E9B84FCB7EF5B9A86FDF
+:100A2000402409EB2F7FFA7DF66F55F9DC7E578263
+:100A30007DAA68DCE508BB13EC53E3FB53490F0ABE
+:100A40003EF125EFC3B19D12F4CCEDDABE72D3476F
+:100A50000EA29B13B8211969025E649FD634CA0B9B
+:100A60001CA989F6ADF52AD2FFB09CFD2017DA3F0C
+:100A7000D7101074F1DCD66D640F54BEE3D4A7D345
+:100A8000B8DB6EF100EEFF11C52FF0FD67EBB20D84
+:100A90001CB7D21EC8563915DF2B1FB995F170E966
+:100AA0009BB766B35E07462FDB685E6F2F5AE7E29F
+:100AB0008DB3789D4BC0C77858F933E1CFF85C818E
+:100AC0006989EE1B6F1F22E487136E2E21FAF81C32
+:100AD0007B223FCC11078878DEB7C43B644EB83A1E
+:100AE00035FA9DB93B8708391080D07BF4FE640D40
+:100AF000DAC5C417E4373F9F4AFDACCA55FC4E9592
+:100B0000D71F30E1259D13F11C9A62C59DE6E17E59
+:100B1000BD39A527D9C14E38E5B8BE8CDF69D0C82C
+:100B2000FF1BD58EE17664B33359423BFF4876E232
+:100B30007B84EF99EBC0BFB7200A9F6AB61C617C2B
+:100B400002B4BB527344FE61A243B48B52116E9F38
+:100B5000EDFBD0D19BFC1D99361840F36DFB88F35B
+:100B6000A0676954DFEABFA6D919F32E49CDA31FA8
+:100B7000C5D1B333EEBD133FC3B3065235D2378F61
+:100B80003822535FA471705C8AD75C72BF33E6BDB4
+:100B9000B04E7C71747ECFEDA44FCBBE5A6AD27F2B
+:100BA000FCFAE3F9C19371FC0036667DA5F79FAAB4
+:100BB000ECA1C7093E5548AF01A657417FA8A347FE
+:100BC00006203D7CFCD44BFBBF4F7EBA467BE674CF
+:100BD0001E2D96CF563E83F44BFE348477924E7C86
+:100BE000F64B07E9BD39156807E3BC3F76EB74297E
+:100BF000AD2BDDE2F78474EB063ED7FABFC55F97F5
+:100C000076C35FF7C5C1F373284AA53B0CC79F5C49
+:100C10007E09FB15E2E06BD9BBF17CB37A88C67024
+:100C20008EE79BF8B71FA2E0B8ECBF3F61BCFDA206
+:100C3000973807AB7EF4AF2CBF10AC1127E26D756F
+:100C4000E853CEAF23F9C5F95D33E9BCBAEBBA631B
+:100C5000E1195FBEC1E4471DF7DCEE8400C5DD4548
+:100C600076C8FC0E433BCEA58EF4F3A772F99C70B8
+:100C70009DA9EFB7AB110FE9E7EBD2AC3CDC40EF3D
+:100C8000C1B4074AD400B54F32E30FBC114F5A9498
+:100C90009EF47E8BEC21BD2E1C826989DF050CF24F
+:100CA0003CC2D05DF91A715F4B3EBB2D6CDAF54E3C
+:100CB0001C2FBCE6CB6D746E7E4871F1B9E5A23590
+:100CC000733C7CFFAF25FF3F092F16BF8A70247A43
+:100CD0000A188E5E08E71B0508D0FC08F079B09C66
+:100CE00052B6E745ACB704014CE724F1FE9465E049
+:100CF0004D6DCDEDEA374139E820F9BF14E511FB20
+:100D0000BD37C6962F6BF998F16C591C9EF908CF28
+:100D10007A75C5B3DC4B4DFF4A29949AE7BA6CCF7C
+:100D2000B7EF95F93CFF940B58DFA0735EDC3138C8
+:100D3000D522F3FE9C7A4A0A71BC61204BBCDF8A43
+:100D4000F84E7A968587F1F67D7C7AE2D97747D29C
+:100D50003DB1AA5FFFA5E4BF303DF1EBB707BE4848
+:100D6000F9E7FEDCFF2FD0B57EC5CEBFB21DD3BEE6
+:100D7000D3C9FED0F69DBFED4F72B9FD05A74EF861
+:100D8000DB7EA753C435EC4CE177CCDAFB09BF5DC1
+:100D900070C7972561965B6B791FA75FEAE0FD3E00
+:100DA000D5F2379623A75A9C1AADA366670FF68F24
+:100DB000D5BC901422FF40FB8E2F4746BF77F5CF5E
+:100DC000AEA7DABC4FD39E0273296EA63D4DC4591F
+:100DD000D6BC38E6176BC81E69DAE520FF7FC56F01
+:100DE000FE5E427CA9FD995D0EE25B68973E02883B
+:100DF0001F732EFDE903F65E745F0CD8DE3E7DE9BD
+:100E00003BB3E87DACAE701170684738D0BA102E95
+:100E100095A49775078FEA6F2D3C3E657BA2AA6566
+:100E200014D351275C24437C4F09B9245AFFF31E85
+:100E3000F21BB5E7A1FCD769DD5F9690FE74A17542
+:100E4000FFC7A5E27DEEFFE7D76D838B5AF753DF2F
+:100E5000DA750BFC1F76A926DEA78AA383AE78FE7F
+:100E6000DC0F38BF2D45E7F97E45FA7FFD5BBBFE01
+:100E7000AFBCEF25E4B7BDD87DFFF85BBBEE0BED53
+:100E8000FBABE6BEA7A874BFAE7DC7DFFBF37ABF9E
+:100E9000E2BA938BBEADFCEDFCEBEED08F64AF8B72
+:100EA0009ED8BA075ADB344CD775A3A78C2AB2FC5C
+:100EB00010C21E914D7D631D0C3336915D857A06FF
+:100EC000D901EB3245BE1EF50799EF0F72B00AD477
+:100ED000F7D5C5BBB68A1F54CCDBFF7C23C7B3ACA8
+:100EE000CBFE0EE495D17985F06304D7E8BE5DD8DA
+:100EF0003E9866D3823A3D57B5D2B709CBD5DEB21C
+:100F00004AF6CD3AED6A57F43B168ADB1163A7B86F
+:100F1000E3EC8DE402478C5D9204BB55F2C327E9F4
+:100F20000AC7FF3921AA3DD6CF2A12EFF42743285A
+:100F3000A0BA2F1E4E8BBE3E9C5C7CAF5235E104A6
+:100F40008641EB766A0AEB610AA0FD28D621EC4EB9
+:100F500084A316054730ED50C504B9A20D6338A22D
+:100F600001A14D1A4D70F5331C83BD6495E1DAD9AA
+:100F70001FAF3B7E1FD6699320CFD4C725FD9B872B
+:100F8000F3D822111F100F672BCDF795AF21FD77F6
+:100F9000D51A71CEF5CCEFBEC3F9263BEAC374CFA8
+:100FA00030D5B7A288FC8E5E43223A5D3543BC2F14
+:100FB0005846F7C032C9D41771B899AEBEA0B0BFB9
+:100FC00012ED0CF657AA40F69F3C091AD91FE855B6
+:100FD000E2E27A558E7B0ADE2CE29EA01034F14EBE
+:100FE0004B6CFC4F601214525CC314B9AA81E675B5
+:100FF0000A521A28EED2616FEDCFFEE17E008F918A
+:10100000BFA5FC8B8D549E8B7A3DD07D32A5F53DDE
+:101010008A6FB84D4E058EAB8AE0A728B85D76C6BC
+:10102000054A149CCB212D267FA2DFE126B213F2C4
+:10103000024E9582C72A5CBD62DA9FE87586C70BAF
+:101040003A5D2AD94753D4DC98F6B267EF7B64D770
+:10105000BC916E63BBE0F29CC131EDAFFAE0C4C657
+:101060000526CED23ABEF7AEB8A78AF6D623AF632E
+:10107000BB37EF0720BFF1155A694CBB66D3BF12CF
+:101080009962E7F766AE2C1C13336E737837C3A5ED
+:101090002A0B243A0FAEB2214960BDEFEAE531F5E3
+:1010A000BE37FA8A987E67183362F255ABBF0025C7
+:1010B0000360DCEAB340EF0796B636C6B41FBEB78E
+:1010C00039A6BEE7753485302DDDA705291D75507D
+:1010D000DC231D8EFB41E71BCDE1853AC5EB14D324
+:1010E00005D0323A16F0565018F2C8A3FE9728BD24
+:1010F00050FC3298EFB2269BE7AFEB6DA1C605B965
+:1011000014FFD3F0E35D12C743EE263C1D1D69A812
+:1011100048C5EA63CF34BE446953DBF87A7AC7B373
+:101120000AA08DE5AFDBC6E70253E4961289ED9F76
+:101130001EC39D51E72EDDBDD7F9A3D2F27D4548F0
+:10114000476B738C865DC4F727BD3B5FCEEB5A0FB0
+:101150005425128DE73F2AF51EA6384D2B4E2AB98D
+:101160004216BF4771B98893A9B3E94926F362FDD6
+:10117000409D6AE738FE65C582BF8D6CDBDCE82EDA
+:1011800023BBD3A5D1BE2667C4DEF3BE71B4B8B706
+:10119000F7459179BEA2A859D7931FBC3845B4270B
+:1011A0001F1F8D37DDC6FA94E780BEC78EF9FB0A94
+:1011B000F7A9C4CE9AA67F10E0F74D0FB44D903436
+:1011C000809EF794DAC80E87BD76FE7D99A6C2C9C7
+:1011D000A70BA87CFA5B1CC3B86BC22F0B49BEAD32
+:1011E0001C3CE4BCEF8C7ACE48A045C5412C2BD6E4
+:1011F000783E1E25CCEF1279CE285CEE99A7DBFA5B
+:10120000478DB77282D0FF560E4EDE4A78EB3960BA
+:1012100088B8A842B73680E9239CC37C4209E75CC2
+:101220009F22E2ABB4F3BCF37F7CCB88349263198A
+:10123000E57A1AF94133B6CA1DF7CE683D3FA6FFDD
+:10124000D0C13AACDF3F19E7B58562D744792BF2BC
+:101250002458EFB0CA9125613E43B2CAD7CF9E5CF5
+:10126000C4EF31C6D41F9AD751DF70E574F6AF15BD
+:10127000AFDFBFB688E037CA467125EB7F67E777F7
+:1012800006709DAC4FAC447A06E97CF0EC710178B5
+:101290007AB8FC90A4C5BD9FDB5A4CF982BEBE4112
+:1012A000C558FF92B3A9FC0EC067F5492CFF2E3933
+:1012B000FB3D7EAFB3C961F4BF9DFD37491C6F365E
+:1012C000E3E68F37AC26BABEEA7821C52858EF5737
+:1012D000D6A85F303FB0E2EC3AE187F88B78FF6345
+:1012E0005B679EF883A7139E06BDCFB53E0ABEF48A
+:1012F0009B2F334C78FA8A37CE5E8BFD6B8BA6E53D
+:10130000105D9E0637C7F59D561F9F4DF33DBDC529
+:10131000CE41B44D26BF0C149AEF11648673E85E7B
+:101320007EF19B368E473A88F860203EE4B7BE993E
+:101330005E4CED3295748A6F383DFECFFC6EC2E98B
+:101340001F0207172F0B3B185E4D998B2ACA19FFF6
+:10135000B574F23F58F06D34FB79B8D4B8B298FD4B
+:101360005CE67D1163EC45BD3FB96BC2977C2EB046
+:101370003617F5FC340A393E5347EF4BAECCB5B3C4
+:101380005C5A99F6C5D44CC2F7725784DE81A859CD
+:10139000FD19C317BBC98DBE07A69C91418B8ADF7F
+:1013A000D2868AFD571483F75F39E3E0F2AAD5A706
+:1013B000996F5BED4F98E7ABF42E23DD17AAFA8700
+:1013C000CCF746911FD64BC328DDED5819C54FA069
+:1013D000F1D30E3E3F14F7EABEE96F25939F728664
+:1013E000A4CEA2F9B56C3B339BE2056624A9B328D1
+:1013F000DEA06EDBFBB329BE60463F7516C517DC69
+:10140000573C790E97F7521FB0A1FC7AB964BEC859
+:10141000E7AA7FA2FC535BEF98C3F553C4BEDFB6C7
+:1014200075CE9C00F36337D3C1A9FA1E21E779E892
+:1014300060E9EA1721FA3DDB2EE5E6EF49C15CC120
+:10144000F73EB9BB0FBFDB09056D1C2FB6BE58F8C0
+:10145000FB3BCF5741A5F3D5CC7C30C8DF9CF95C72
+:1014600092F85DA2436DFD097E4736DEF203F2A7D6
+:10147000AE9080DFD1AF026D24D1D5425BF83D4AFA
+:101480005F1CEEBBB798F5A9368E775DBA7A27CF89
+:10149000EF53DD8C5B562345DEAFF54E04F69FF02F
+:1014A0009D88D838E30F6CDA40EA5731E1B2506ECC
+:1014B0009BEF10F37A94E6B5227D17C7392B6A5B50
+:1014C000B64FE851856C3FE524F37BD175BDDF292C
+:1014D00049F43B088DB528EF91E49EA96DE674F5BB
+:1014E00050607CEBA9841D3AF6537D40C89D916DF8
+:1014F0001F38A2E319779BF04D357FEF2A3E1E7708
+:1015000037C9A5A8B88315BD5BFB927E68ED6BE774
+:10151000BEB4F635F70568BE99192F3D45EF9D50CD
+:101520009CEB0FE93CE3B9A456F25B778F27D63EDC
+:10153000887937250BBE11793689F5A6F8751C34E4
+:10154000E76DAD2762CADFEED61131E5EBBF6A1D4C
+:101550001193BFC7AFC7A26FEBBB45DF5DDB8BF954
+:101560005F3CDE897B6D17C23B8BFF5483AF50DC41
+:101570009716FCC682B7354F0B6E4DDDC4E32AAB20
+:101580009F8F598FD236898C1E482D11EF5F298D80
+:101590005700ED87B2BA85EB75B71E39E5333EC704
+:1015A00059A6819FF4DEF875554123B7EBBAAE0812
+:1015B000F3E3159AE0C75DE3F823CC9FABD13E235C
+:1015C0007DDC5A77079FC6F5137D4F4086C37C9319
+:1015D000EE124A645FF862F4E372BA31117D6EE58F
+:1015E000BA39263F45BD3DA6FEE5396B62CAAFD08C
+:1015F000EE8E29BFB2F0DE98FC77F59FC6E9F79B27
+:10160000E2F4FB2762CAC787DB58FF7EA3761AC7BE
+:10161000A74F3C1A613DBCB556E5FCEEDA1C4E5FA7
+:10162000AED598FEF7D41672BAB756E7EFBFAB1D2A
+:10163000CDE9EBB506A76DB55E4EE3F946595BB84B
+:101640008CFCFBA33353F93C6AE350DFF525140708
+:10165000B92F5244F837F640E34B240AF2439FBEB9
+:1016600047F54EAB0E8E475CBB6BCC1F6EC17CC684
+:10167000EB322469E7D38B6430A2F0C7333D0C749E
+:10168000FEED01F13E567CFD8525424F9E0B61F13A
+:101690009EC06A3E0187B92EF5152393C54684EC9A
+:1016A000F6B9E0673DD4B65ABC5333177428237B90
+:1016B000D607FE7B381E29F67D01AF3163DDAFB062
+:1016C0007C36DD3BC5F6DF7737F2BDF267F6A64F15
+:1016D0002EC5EFD77A25FE9D8F033BEFBAD5C5F611
+:1016E000AF75FFF41DDBC5E8130B4B047DB54B7ADA
+:1016F0001BCD379026DE2F8A6F37CA5CE755C108AD
+:10170000EB1F11D43F28DECCA2CB19EA2173FD9A3E
+:101710002D750CD1C71ABEDF50D5A6E94184F798C4
+:1017200043822E46205DD0BE8D3D2AE86024D20142
+:10173000CB41D33EB4E800EDA997A8FDA983A03B17
+:10174000B17DDDC41FC9647F8DF92C14A4F4B2B33C
+:10175000915DE7B07C5C9BF8DDA40BD993965EDAD3
+:10176000523B97F16867AD8FD3D6DA4A133FFD9CA1
+:101770007FB97635E7F7D40638DD5B5B6FE2670348
+:1017800097BF5EBB81F36FD4864C3CDDC2DF3592E0
+:1017900067089FBB4B4C39ED2A37ED0A917A8D359E
+:1017A00076BEE78F9F889FCCA5B9127E544A21E26E
+:1017B000DF75E9013BE5EB92690F68D601AE7F9DCD
+:1017C0001B5A490E54E5BC28F4B0383C29CFBC86DE
+:1017D000F164A619C77A20BDEE5607E2C389C6FB9D
+:1017E000ECB1EF8D5E1C5E2C73AFE57B7DF17CF17F
+:1017F000267A8F42EECA0F0174BDAC4CDCEFA238E2
+:10180000BDAFCAEF555B9B795F4CDC7FA9EEEBE681
+:1018100038DB7F9D9C514D39030BA87E87FD9D7C55
+:10182000703EBD8FD7052E71F6F7E141627F2DFB2B
+:101830001BF54CF64BB58764B6BF2A731B3C6C7F17
+:101840008F8E78683F6FDA2103EB8B8A38EF5D4A21
+:101850001D6914D7D3BA7F1CCB99557B882F2D33A4
+:10186000CF7BE3CF6DABE9BC574A04EF30C7D52F30
+:1018700037CF7BE3D75D3DFE089FF7565FE05EE91B
+:101880007B25B1BFE7137F7FB73B7CA17882E8F768
+:101890005C4F9EAD653BEDC8B63B1E0AF4FDD7ED2F
+:1018A000DFADA5DECF4A441C35DF9BB3F6B3CEFCDB
+:1018B0005DCEBA492EBEC7D03E42E5F76FDA25F1BC
+:1018C000FE4EFB5F415FA3D1FB3AEACB24172ED338
+:1018D0001DCC574787C57B01E3E95E6282F702268C
+:1018E0001C0A0553A8DDC100FBA3C6ECF305E9DE25
+:1018F000EDA8D70D99C8ABF465AF4C7860C9274BFC
+:101900005E75D295796F8E6232F2BF3AFD698B4671
+:10191000E7907ED761B7BAA7F23B45A75B81A349A1
+:101920002DBFD8F083864CF712461CF20549DED64F
+:101930009976E6A813013915BF4FF8CCCF76D018A9
+:10194000B453E552718FDA8882AFE5D7B2F89CC5FF
+:10195000D7AC7B7BAAC3B785FCCFF04212BFFF1286
+:101960003FEF41436DD67BD6838612DF33EFE94DDF
+:1019700091CFEE3A4776419B8817B8E46CFBE3645D
+:10198000F7AC7AB607DF53BB907D50A39E4EA89F5D
+:101990005A698D4D9CA30CABD08693BD497A2BD947
+:1019A000A1965D1A5FBFAC74D2D8A15934AFF16D66
+:1019B00006E1B76A3B2F7ED7ACFEF4BC76A1357E3C
+:1019C000CD8E11EAC228BFD5EAA19219C7F2F5DE81
+:1019D000A19E10991B23C7BEED7A1FD26119E11792
+:1019E000D98624A7BE4F3B80EBB80E5A595FB9DEAB
+:1019F000FC1D8B1B001CD1F7646F0483F9C39F741B
+:101A00005F0DE1CD6288CCA77C8D14A97A1141F8D5
+:101A1000C9C4716AAED6555E5FAC7C4E36EFC1C6A6
+:101A2000C3FD4E136F2DFEDFEDFEC4F1FFF65295A0
+:101A3000EF41B73F3BCE46E738EDBF97F9FD54ACD9
+:101A4000C87C25384CDC3B1D3ECF7C8704F9CA009E
+:101A5000BD2B5F393D7ECE64F61FD1C106C59F2ADE
+:101A60007AE1F551F7CD82E6EFBA6CC194E22553E5
+:101A7000E78595E8F3B39F9AF32FBF7632903D74D4
+:101A8000952AECCE292EC84C225E78F674D12C64AF
+:101A90001057913E3B9CDF617F98E0DCF10E08F12E
+:101AA000A34B70DFDE17E77C7093C4FED2E626916D
+:101AB0002F5E9CC6EBFAAAFB883DF728C1F52F6E76
+:101AC0005286117D0F4D8FE4115D168F793B5DC2FB
+:101AD000799598F7B170DAF510F5FB56EF9AEBF8B7
+:101AE0007CA8B18DE63734BD6DFD7DA45F3E6B03F0
+:101AF000F21B1E1973FB128892CB9ED249BFA27AA9
+:101B0000DB25F39DBA1DE2F70CB04576B47FEB4FB1
+:101B10007AC5F354AFD5F433C0AAE7F91EFF0C55CC
+:101B2000EC014CCE327F4F32D23FD1EF0B59E75907
+:101B3000430996C2FFC8EF8A6D37FD936F0EFD60B3
+:101B40000EF917A1359247F3389224EE517B4A7D66
+:101B5000BF233E3394FCBCB48E9F09FFC091343F39
+:101B6000DF23791BF9339D1FFFA5D6C5E9BB681F8D
+:101B700051FA3F681F51FA3EDA47947E88F611A564
+:101B80008BCF60A7B87F3374E36DE6AFDDACA37B8A
+:101B9000FE1230F5FBC4BFD3F49609FF92A643773B
+:101BA000F6203C6896393EBAF85985F5D3932DA3B3
+:101BB000627E9714E9F530ADAFA4F98F3FA17BD6D3
+:101BC000254D8A2A69742FFB7436C71FC6CD8FE056
+:101BD00040E70D911D0EF17B4AE67CB7A7B5ADA796
+:101BE000F6DB9FCDA319D2398EC0C31DCE84BF377B
+:101BF0006CC5DB3D3154E85FDF7346CAA2CF1FE3FB
+:101C0000E3D3D80F3C86F0B9E00F344E60AF0C033D
+:101C1000182F63FD1BFD74710FC14A8B7738384E46
+:101C200079FB8EFD575F89FDFD1F8FB61B3100804C
+:101C3000000000001F8B080000000000000BCD7D9D
+:101C40000B7854D5B5F09A39F34A32934CC2000957
+:101C5000123809AF00018664121212E024048A8A45
+:101C60007482D482A28EB462541E23D29ADED23FF2
+:101C700027244012830605CA558401C1C7FDFCAE66
+:101C8000D102175BF44E50A9F6B73422E2A354C731
+:101C900047552C4A8A62EBAD2DFF5A6B9F939933BF
+:101CA0004C0222FC97F0E9CE3E7B9FFD58EFC73EE9
+:101CB0003BB3265E5E24C900A7E9670A80CBDB1729
+:101CC000A008604CE9D70FDCEFC1F2599BDB0400A0
+:101CD000F360DB3437F6BBCED1F1A21BEBD7BBDF11
+:101CE0009B968EF51B334D07A8BC49CE999E812546
+:101CF0004088DFFF515EC5810CACCDF456DB024E4F
+:101D0000800A9000F2807F4EE37F531D29008E6889
+:101D10007D9ABB8FA1FEBDCCCB0CFD2F978718DA27
+:101D2000AFCC1B6D68D7E79DE92D34F41B97D19597
+:101D30001B74D23EBEBAA71CF70326080FA37DED85
+:101D4000FEF2EDDBB19C35719E8FF67F0CDAAE1999
+:101D50008D1BFDA4A479E3FDF4B245B165F503B88C
+:101D6000857EC7F6E3103E5286ED926BF9813BF11A
+:101D7000BDDB322590BC00359BADEF4762D6B10488
+:101D8000FC6961EC77DB0EE37380882DEC03B83DD2
+:101D9000E00CB62000173D81ED0E433B8FBB78AFC2
+:101DA000CD4DED4BC0126DCF01A83D9AF3E40B3140
+:101DB000E38DCBE8BCEF7E1C6FDC9E39EE065CDF6A
+:101DC00093A55F0F90719FE55E97E723040D4C800C
+:101DD00009A711E42039CD80FD4EBD2485245CD7B0
+:101DE00034E99BD4483E3EAF423C67E17B26F90F85
+:101DF00065D8AEBE2CC14E1CE76F75F2932F5869A3
+:101E00007CB8D19F1FA50B80950C5FBD7CAB0E7F6E
+:101E10001D01F0C73A07977FAA7373F96E5D269785
+:101E2000EFD5C95C7E5097C7E5AC431068C7F1FE9B
+:101E3000FCF7F1007D681C15A06FB41C67F39A07CE
+:101E4000E03ABA7E2F85B6E37EBF289F9006B4CED7
+:101E50006F70FE620D0F4802D5448CA5F8DF8FB776
+:101E6000BD98E5E3E7AA0BA75AF27709141C77B9E6
+:101E7000D724C65DD4F1629627DA0ECBDF33F48720
+:101E800015A603867A638EB1DE5A7120F67D1D0E8B
+:101E9000F1E52D9BEFB0055C58AE372921E799EDB0
+:101EA000FA7AA6ED4F524C389E659F3D64C7FD2DD2
+:101EB000712BA0607F0B80D29E7FE67B00F50CE744
+:101EC000791204DB138C5B47E312BDEF4F02E93C50
+:101ED000C67D0B6983D6A3FE973DB413DF7B2B4DE4
+:101EE000017FCC3C2DDAF89FA5B7FDE22BECF7D9AA
+:101EF00033404FB00E73693D63777D6C3663392E86
+:101F000059D0C95877C49C81E5899A7F6C3CE261BD
+:101F100032F59B26637B6ED71107A2FCBEF6AB366B
+:101F200039106F6F9BCD00034020BE04FBE31854B3
+:101F30007FD07BD5DC46FCFDCAFD4961F379ECE737
+:101F400041E445A6A34AC1EF3710DD88791440511A
+:101F5000B37415E8F32A241F68FF547FADDDFFE654
+:101F60007AA233E8DA48F2E13840B885D7AFA4C6A0
+:101F7000F2FFD2677FC2FCB9280BF99E04E066C16C
+:101F8000BF0EFC773A97F83534DD89EBBD358CFC14
+:101F90000F179FFF9FF13AA37C3E22219F1FBA1289
+:101FA000EB4B9F91BC766C3EB96F98E0278DEF7537
+:101FB0003ED7E1B87493C47CA9D73FDF27CD08256D
+:101FC00080F7368D2E86285DB369BE65CF5AA00591
+:101FD000D7B76CD288FEB1E3C7BFB7B44902396640
+:101FE000FC279FB3D710BFC8D0D5AF1AF967DCB3B1
+:101FF000A7322AF24559CFF868D3E44DD720FF180D
+:1020000094D726FF9F7E8EF301E27127C2A7327319
+:102010006E36CD3FDB094ACB7806CB1C07CA89ABAD
+:102020000588E0EA92EBB201E1B919D12521DDCDB5
+:1020300051AA5FBF0EF1F80373E02A92F3C7BC43C5
+:1020400078FC6B5CCBAD606672CD36E17873E7D817
+:102050000B693FB31A045DBF9EDE759C9EBF3E298F
+:10206000C5D480EFBD6E8246C888EEE375AB3F9B5A
+:10207000E80D37EEFE08F163524649A7537A9617EA
+:1020800044C91FE97894A2F26F9AE454699E936E52
+:1020900033D3BD25ABD546EBBA154207149C7789DF
+:1020A000376C23F9773BB82D5462D1D54D1F447F4F
+:1020B000E5FFE8388DEF2FE9944226ECDF5ED70E7E
+:1020C00016C4EFD3757BB91CFCCDE0C6CB101ECB7C
+:1020D000C7DBBC2DA4B734FA32AB26389D405F9DD8
+:1020E000499F96683BAEBBC2E10C4BA9F4D87A3C41
+:1020F000761D8DD94ACA78DC8FBAA63C9DE99368D3
+:102100006170749FE36C004E92F33B5358CE1F7B7B
+:10211000AED84C783AF63B6BC844F52D23DEB8D3E5
+:10212000C7752079732CC36BB6517B466E48C5F6D4
+:102130005BCCA0925C86ED426E3D3FE9AE77488E67
+:102140002DDFE932D94D828E653401A447D7BEF325
+:10215000EF38CEADC8AC766F546F2C9AF2E8C62734
+:10216000900E1699DBEE29C767A7203CD68DF0FCB0
+:102170008BA97D38E9ED8F1FB287CDF4DEC323B77D
+:102180004B38FECBA98191B41FC854FAE7E0F39A0B
+:10219000437DA105DF9FFAE83F0F92DEBCF5C9BE83
+:1021A000CC5F3ADD4F233EC4F59C403EA4F59CDC59
+:1021B0003784F92E8A7F0187C5280FC8246ADEB1CB
+:1021C000CE4FF80C24CBFCDC02AA7219E17BEF4D58
+:1021D00040765381645288CEBB9A115EA633E9499A
+:1021E000196FE6F7169951BF121D06E44282C7091E
+:1021F000935CA0F105D07ADE7F6EE4F6167C7FAEAC
+:10220000D63F4A774797FC86E86EB3DD6BC7251C3F
+:102210004F32EA7DBD9C393E9DF9E516C79760298E
+:102220008C3E5F52FBB5B19E0F0AC98D8206B9F094
+:102230000E2CEFD4E07EC548FFF7C7E3FBB7B5AF80
+:10224000DBF38A4CF36EFEE9DB34EF4B4E9E175EF8
+:1022500011F03B6112FAA55BBF3AFECAE3A3E4E1C9
+:10226000F5EACF3F7EE88DB1011CFFE3DDA38703D4
+:10227000D2DD02A9F3A307115F9FBB3ADFF93996BC
+:102280004FBF74A81FC12F7EBD8B6ABF004B8C1C33
+:102290003A6E32F17E17D13EF0F96F0AFD3733BE48
+:1022A0002DA827106E0B5AC66C2779304DCA4F23C4
+:1022B000BBE9C431E3FAE2D7A98FAFAF4F1F5FEF9D
+:1022C000B78CE08F709838CE2DF4ABADF373C2EFBE
+:1022D000677B469B9015A3CF333AC7A6E747F1E447
+:1022E00057EAADD4EF1A12F5888AB90E81D7B935FD
+:1022F000A650430EF7E3F6EBF039E1BDC2D3C0F5CB
+:10230000394ED467D87F51E66F785D24E81CA8D792
+:102310007E00FA4FF5AA5F61BF3797A5B25C987B44
+:102320004B9B95ECDC6E79A6BE6D3E3DFADBCB3364
+:10233000849EECEE07CCC3A43F013767C1FA24ADFD
+:102340006E2AF963C3AF483EDF99EA95D064841AD8
+:1023500019C2C4D7272144F05E6D0AB2BDE7203D03
+:1023600080658BC99B69C1523277F5019E27C47085
+:102370009A06010BD57F6B8A3400BEB7CA539949C0
+:10238000F4FF2638FD6417FD207DF51892A395EE25
+:102390009973E9F96C35D5DD82FB6DB4CA77E793A3
+:1023A000FDF303C94B76AF0E175D7FCCB578AD0456
+:1023B000DF7E41D9AB22FD16BEA2384C0C7F874A86
+:1023C000E3BE6109F6A575BDE55C3FC664263B2DFD
+:1023D000E41A839B7DFBD07F14FD1EDFFF2328932F
+:1023E000C81E98F35B07CBF19B40667EFF11282C3B
+:1023F000C76F8600D76F8188F54B7CEFDDD2FFD9A0
+:10240000B91FA2FB7A77E257BBC9AE9F2BB5F7CDB8
+:10241000C176B512F248CFFCDAF17FB646701D4A9C
+:10242000830592D0BEFA35D129D9EF475DA19DD859
+:10243000EFAEE42DA91D588F9884FDA556069FA4E4
+:10244000FEAA19FC0D58F64D0E3C4F7CF8CB14310A
+:102450004EADC5E126F94806168DF3D13B2EA67781
+:10246000D2BB3761BD0CB145F03AD157D09BFA577A
+:1024700060B97BC2EAED5468DC53B27727BD3AD528
+:10248000CCEFC36999D75116A75F7CA3CDFC3EFC66
+:1024900043E6F72775590CFAC537CE1C7C1AF73777
+:1024A000E5EF965EF5CECD05827F7C7DCCC144F60E
+:1024B000E0FF68FC851092683D0D7B4DA116264219
+:1024C000611F94E9F40891D5446FE50041A27BD8DF
+:1024D0008B7A4C9F2797F7FFB9EA233AC476B60761
+:1024E000DB9F2739690F0A3EC1FA54DA8F23085E51
+:1024F000B2D750218305EB49F8A290BB6E203BB6C2
+:10250000A502DAA93E092212E17B0A417A08F9C341
+:1025100032D3ED5450B8AED3F1F740E5F272087102
+:1025200079258485BE07B9F1299CFFAA4F40EC6745
+:102530005498E91D1D19F747686FC0E5B798C9EEB3
+:10254000F0FD30B1BF30A840870B22C473EE709904
+:102550000E814C31BF80879D9EFBA2F070C4C123C9
+:1025600089E0E18DC203E710F03803BE023E931408
+:10257000840FCAA7C9D025D13C8A66DF548297CB85
+:102580002AF073D90B5C5EA8F79C09979248C01299
+:10259000C84F009FA989E96684069F3F1600CB2F8C
+:1025A0005DFE5C5B20F3735D0E217F66923D1A2F0A
+:1025B0009FF4E7BE94CA2F64A487AA82AC7916D48C
+:1025C00067BEC2CA3B8760FDEAA7F344BDACF257C1
+:1025D000B958FF41C128511F5759684578D59B46C6
+:1025E000CFABC2FA90806923F1E5F27AB4AB715FA8
+:1025F00081A47B8244C7A60C709BB03D505FE42D44
+:10260000C07A00E912106E7629A79EE06CFF397837
+:102610001B7015196981C905B8DEFCF99DAB053E33
+:102620002BFBCFC5FEC73BAD6CB7ACB10583842790
+:102630006477777D69747FC79FFE790D3D7F7A004F
+:10264000B849BF80472EF4BBCE5C8FD9015C5F8C4C
+:102650007283E21F38DF4C9A2F80EA49A6753D2528
+:102660008508FECBEBA7B13F7024CFFFFD82BE31C2
+:10267000E3E33EA4F134AFD073E0C92924B8958CCC
+:10268000F45F4BFD4EB850BEA651BBC0434F6563CF
+:10269000813297E68D7F6E4EF9E6862538CF52A4BB
+:1026A0001192D38B0B0237D2B84BCD914185F86C88
+:1026B00065CA3B36A60B05E993E403F12BEDB7069B
+:1026C000E991E87ABFE057E40077B7FD8AF8F5F8BA
+:1026D000BB6E58E813224EC2FF15CF0D3E8F6635F4
+:1026E0008D7F3BAD63A9D4B590E8F2F3F4D76C7F4E
+:1026F00066BE1C28E84E935B4B9FFB9AF9E7593363
+:102700000425CD3F8618BE5BFA5C9285FCC3A59F6D
+:10271000422805DF2FDBF77803F93BA5E8FF939FFD
+:10272000BC78D753CC6FFB485F22E896FEF7B3CF57
+:102730003F487C7A6512C7A126BD767408D94153FB
+:102740008E461A106D70E2D9372E13F4AFFB257F39
+:10275000339D8F1E9F26ADB887F0BD0CF16FC7F972
+:10276000969982A26E75B855967BC24FAED1F6F19E
+:1027700019746E9CCF72453D504AFBC99480E56345
+:1027800048F81332FE23FEBFFD686835AD13A46F11
+:102790006C246F4EA15F4CFBBAFDB178BFA3EB4038
+:1027A00029F9DDE417E33E17B71BDB97C6EA870478
+:1027B0007EF296022D1E960DD9B4AF5FA33FF4C1F1
+:1027C000309A777E1AD9871329AE90405EEAFE715F
+:1027D00028B9F29102B697DB25E287324BE2FE0B75
+:1027E000F3855FACDBFFCB1E92D88F5BF6509F5119
+:1027F000EC276BFC0A612FF3EF93A45788CE022FCE
+:1028000003D1C12DDA9E60731FA6B95B9B4CECC748
+:10281000D8A53BBCA4F7C73DD2FFB67F63BA4975C4
+:102820004326D527CC7DCCC3F655908435FA556C1C
+:10283000673E99DE954BF33F992E838AF3352475D5
+:10284000E5929C559F757849EFC6AFFBED02E10F0D
+:102850000C098FDF14F1083C139FE7BC54BA89F0D0
+:102860007C12F99CF0B7CC35BC3F38C96E989C19E6
+:10287000C1B241B3D3731E1B95361BE1E2A3F5C66B
+:10288000D8D51DAF5E9342F6F26E8B3FC58DFD4EDF
+:102890001ECE35F841F16551189153D84BFB1B33CF
+:1028A000870412C05D2F7D9B2C0C2F9D6E7F5DA732
+:1028B000C00756C247B9D8876A77DB7D447FA1A994
+:1028C000E44F2EBB19DC2DD87BD9CB0F3738A8DECF
+:1028D0000C4CCD27E97FD4FF137388ECF15FA68CF5
+:1028E000BDB71CEBBB8E59849FA22A87F263EC58BC
+:1028F0007BA6196403BD764A8B491E13DD23BD26D2
+:10290000C9C920C7D0634A5E86A1EEF20E30BC9FD3
+:1029100056926B684F574619DA8BA13612C0F514E0
+:10292000654AEE10AEB8CF8C0243BB1DE93A4CEBC2
+:10293000FC52D85125F84FE8DB20DB4365118007B6
+:10294000900E261E37DA59259136F637930E5B0C1A
+:102950007100FB59E250C9851A7F0D8481C45F481C
+:10296000FF5E9263270F8BB893ACC17359B6D0CF7B
+:10297000CB5E96D80E5C76CCCC7AE22478BBF14361
+:10298000F251E7BB78B8F7F51BE1DC7FAE11AE5929
+:1029900001235C2FAB31C2353B6884EBE05A235CEA
+:1029A0007354231C87344D34F41FD65669A88FD82E
+:1029B0007485A1FFC8D06C437DF463D71AFA8F6980
+:1029C0005F60681FB7F736437B3C5D8D0F2F33B4D4
+:1029D000DB538F305D1D40BA32A13E287CE9DFE237
+:1029E000E8C2C2702F1AE8F48662F0AFE23FC27FFD
+:1029F00099969798006A03F1E385C2FF1584FF94C6
+:102A000028FE75B9DA139FEAF81D42FA9AE565794E
+:102A100084F07EB22485E9E5E04B270F2B40F84F88
+:102A20008502DCEFAC29228E22C9C126A2934E700A
+:102A3000B591FDB9C61264FF4545B3702729E53845
+:102A40007FF3FB25E86FC6ACB35A49024BCC7EC777
+:102A500087DB0DF5C297F61AFA1775860DF5F18723
+:102A600041227D55F0A6F7792A8B3E5438FC55FC5F
+:102A700049F0792A4BBF0CDE45FA37DECFBD5AAD9F
+:102A800097D2C8AFFF7BFBF368D6A07F364825BF3F
+:102A9000377247AAD73400E191FC4E03F9DF807604
+:102AA000B4159511B80FB23E98EF10EFFF2D69F2F3
+:102AB0002AEA6F42FF9CF08E70C9237BAF1692BD4D
+:102AC0000417B25BC80F832B843DBFDAA4B23D9AD2
+:102AD00084F628D9230D157EB697A74370203DBFF5
+:102AE000069455C4779219ED577CFE3F23028D85DD
+:102AF0004562B1443F777D21B3FF3D85FC6906A661
+:102B000002A4F74ED0EFB43E78691EC5E34F902E75
+:102B1000C3F5B7B5BC304F253BC303EE08AE3B2031
+:102B200040069B0B03F7D0B8EF9BDCAB0BF1DD83CA
+:102B300013FF3288EC917585C2EEB34B0829A4814E
+:102B4000FEF315A0E78DD9CA7D8545D1384B4FF4EA
+:102B5000A3C733F5F8E6AEBA309716B75722BA8B4B
+:102B60008F3B46CCEEAAF1A4FF9699D8EFFC0B2D33
+:102B7000AE94E7496539EF804E7B3A2F99FDFFEB24
+:102B800035BC991D9DAB7E8EEFDD1014F6D60293F9
+:102B900097FDF5DB338F731CC52E99C047FE505A45
+:102BA000FE76117FD1E3259749DFC6CE3ADB7E6FF3
+:102BB000CF3C668857C1137D12C6D7A3E3ABACFFE9
+:102BC00062F6B9659347E835F2F3DF6FCEAE84D491
+:102BD00044F37CCEF1ABEB83AF1AF8E2C6DAB70C64
+:102BE0007C7093FA9EA13DE2E9B252BC32B2276BEF
+:102BF0003AC5D73FDB6D2F263C20FE0F16C6C4EB2F
+:102C000022CDA3AB60ECB9ECF72FBC8EA3759D8CE5
+:102C1000577DBFEFD4BDC9F5485D84CBF8FDEAF11F
+:102C200011BD4471D844F6CC5D12CA0BF277495EEF
+:102C30007862E405401ED9FF7749A3BC44EFB6FD96
+:102C4000C147A9BDABDEEEDEEEE3F808C74D6A91E1
+:102C50002EC86E00A7787F81CDC176E81D3EE12F9A
+:102C60001EADF8EA06B25F7320D58B32107FC27FAB
+:102C7000A2B8C97C531AEBFFD55907B8FE61338857
+:102C8000BC514DF821F25797A6A60ABB58C1FE5871
+:102C90003F9161E6FAA11181AF981FF3C39CDF5801
+:102CA000DA5FC4F3C01319447CF833D9FFB5E05799
+:102CB0007780DA6B32D0DF46FAFDC4AC8E35116B0B
+:102CC000ED1A70AD05F1FE49B2FA395934637CFD55
+:102CD000AE253FF3139BE0DF49BB4ECF53113E1FA0
+:102CE0009A24F6CFD5674C1CAF0167C4568D7ED8A9
+:102CF000038303561F8EDF66457BD2299ECF1E13AA
+:102D00008DCB9EB0624971D024513A7DC2EE75F9E7
+:102D1000449E532F4710CCB09CE4D3E57CEB708AE3
+:102D2000BF9DDC6C07925B38BF42FE96FAAC88E32D
+:102D3000F7CBF02F028117F71A5CAF6788FC05F11B
+:102D40009F4742BF16F721FB720CF167726053B1C7
+:102D5000FDFD3DF66D84BFEEF51E16F1B0CF9A472E
+:102D600073BC5BA713D9A7C5BD7F0C20DA2FDB4648
+:102D7000ED8B5F7EFF1D8ACFFDA63030D487ED0B33
+:102D8000CC7231C9C9C5A91D1CA72BF6C93C2FAEF1
+:102D900097F78B72AB117D7158EC88705CEF6CF11A
+:102DA000FB9EF6FFD9CD9D1BF3395E2D8F25B9A271
+:102DB000CF8BEB28A675E8FBD4D7111DA777FED1E2
+:102DC000E3D07AFDE387D60CD7F20837FA13E8E5AB
+:102DD000AB743AB6268EFBD768F88CC74FC18860B3
+:102DE00088E3796E703760FD5A0D4E9FCDC3FD703C
+:102DF0003C44194FF85D3CDBE92538EBE3F7CB8029
+:102E0000C053BDCC73C548FF1CA2BFDB82224FA0BC
+:102E1000B723FD893867730AD3EBE2E7DE7AE7E789
+:102E200038CBAD8F8E2924FDA1BF1F0F6784EF70B3
+:102E30005ACF0249E4CF10BE37D1F8F1F981F385BA
+:102E4000EB89EC4ED60B27B6FD2C44EB3B91056E7F
+:102E500013F2E3E27DBF7DD33496E8C41996B084C3
+:102E60005DC6F857BC9E7243E03A92237694236481
+:102E7000DFD8F5F7065A0CEF55672A77F9D81F55B2
+:102E8000EE2679645785BF362450C1F5E556E1AF8B
+:102E9000EDEA34CBC4DFBB2C10223DBEFCD50C9533
+:102EA000ECC7E56877B0A79317E4F54232FA41E939
+:102EB00009EC069357E6785C5A600DC14BFAD1D401
+:102EC000079FC889FAA3BABE2CD2F4BD927F6303D0
+:102ED0008DEFD3E281686772BCB314029A1DA1C55D
+:102EE000E19A0F701C4297DB3698EBA0F8CF9ABEA0
+:102EF0000B1CE41FCA382CC7D73CB3D3A0173B72B6
+:102F0000551D4ADA11D1BAB5073F5E3F1FC06BECC1
+:102F100047DB0512D6D07AD5814823FEDA3AEB7723
+:102F20005D2F60D932E691C84A6AFBE6B44476A4C4
+:102F300043B303B8E847EB14EFD906AEBEC384FA37
+:102F400033D96B81F763F4A00339FFFD3C6D5EB2AA
+:102F50000732BBDBFF4078EB691F17AB24F8BC6F6F
+:102F6000EDA5DDE6AD49240F12C28BC8C433FD18B0
+:102F7000D16332C4EC9BED9E98BA14072F89CAEE38
+:102F800076E57482FCE577DDD7AABAF0AB1F1AECC0
+:102F90008110AFDF6AF18317E9C9E6C176C3390C46
+:102FA00055CB7F220117C7ECEF1CF64576B955DBF0
+:102FB00097F522EF8BC6F5F7BBA4D7A75EE2EB0B24
+:102FC0005FE2F885EA4B1B7E4AF5A50D3FF5125FDF
+:102FD0005FF812C72FCCBEB4D7A7CCBEB4F1AB5E9E
+:102FE000E2EB0B5FE2F885AB2F6DF829575FDAF063
+:102FF000532FF1F5852F6DFCAA6C073ACB81CFCD0D
+:10300000A6379A4374CE46AA0A73DE3857058E4710
+:10301000A73603E72BB67B851FA5C7E947D2103239
+:10302000FA2D567716D9D1DB1BEFABFC318E732A04
+:1030300013174FF9FCEC230A8DB36D1A70FEC2D939
+:10304000F8D1518A7FE540D81BCEA1B89A04E11887
+:10305000BBF4FA600A8463FC896AA58FA15ED43947
+:10306000C0D0FF964D430CED37B78D36B4FFA8A9FD
+:10307000D050BF492D33F4B7434E4B1EE55D1B2D99
+:103080005ECA8359686FA567C20D76D8F83D05FF03
+:10309000911F9383167DF7B8B88F74D56618D7192A
+:1030A000D77EB67C407C3E614EB1964FE8FE7E41B5
+:1030B000BC0F6E4FC2B8A79E4FD0F139DC92C4F856
+:1030C0005AA78A7CD39A69C28F9C1A729B286FA9CF
+:1030D000E36FB44672FABEB7D519FDC9F446772539
+:1030E000FBA34DC0F9DCDC2A7348C9A138C1C04A32
+:1030F00007E239B443D04708047D841A81F385A1DF
+:10310000AADC95D47E2A047C0A46A78FD1550B678A
+:1031100052DCB53EBB5F16C51972AA043D2CDD6BAF
+:10312000A4034AE7D256D30F4BBCFEF4FA8C02CA72
+:10313000E79D819727049CF5F3E7E97170CFDB6188
+:10314000C44B3CDEBE2D5ED614C77F57F2EDF06255
+:103150009B2177A4519C540599E2322F660F373397
+:103160001C9ABC8C9F19D88DF830A70938DF134FF3
+:103170008FAD7510AE8AE1DF1C6F5821FC4C93F2C5
+:103180002B99CFF0DDFEC0A744195FDB9A44FE16F1
+:10319000CB641A1FF6CA0328AE105267F3BAB737CA
+:1031A000DB92E93CDF57F566A0F3F2DB73E40194B0
+:1031B00017DBFE8C696EECF920A40ABB3993F7612A
+:1031C0003797706911A5A2956011ED6189EA835660
+:1031D00098E3F0A94AD49E3E2339EEB962A2FE5B81
+:1031E0008A73193E694A86015FD61223BF23180FDE
+:1031F000E5A37C1C4CBFCB4457824E42AF4BA195FC
+:103200001C5FE932D510DD68E72DD257CD06CA47DD
+:10321000D567FF742ECBAF7A1BC31D5608BAD0F307
+:1032200082D6264187F1F4E3F21AE9C72A0D3489E0
+:10323000FC96E01F7D1DDB146DDE2C0954967BB6D9
+:1032400001C467D6B8F1EC243C49DE78045F3A61EA
+:1032500036D07BCE123BE7B1413ACAF8B74E00E810
+:1032600013734E217EBD675DE777A4F30FBF239DE7
+:10327000EBF267AD57933F45E25CE429A46B8A1FEC
+:103280004DADEA04FEFE0ADC26A247A4835959C5C7
+:103290007CF4817F76911CB213BCAAD3A8DDD5A99A
+:1032A0004C25FA9D2EBDA2B8709CB587059DA37EC6
+:1032B0007989EAADCD16A0732628674C3FA2794BD9
+:1032C000EDEE952479A481E369DD853E943B1447B6
+:1032D0007CC5282F8A3A8D70CB8D97EB3DC0B127E6
+:1032E0003D110F47D7040D8EC508C721DF1E8E364E
+:1032F000AFD0C3E92542CEBE98FD537ED57D589C04
+:10330000AB495780E1FA852AF4F274E97898E4CB66
+:103310003A05E50BB6CFD0DADD25429EE870CED572
+:10332000E0ACCB9375F32183F8DE4DF2C44970FD18
+:1033300088F5765B9180334084F39FA98AE09335CA
+:1033400056F0529CB6ADD4E9A57861AEA2C1B7499A
+:103350008397094C04DF78BA9421A68EEB4B8DAB92
+:103360007F5BF8964ED0F4643F283E1FF8AE4B4981
+:1033700015FC3654C0C7EA8CF0B9E6A61C8B77253D
+:10338000F275470EC21BDB9B5E17F0FEA5D67FD5FC
+:1033900018E07A53DFD5990CAF9C859944CF4DD670
+:1033A0003695F2584D3AFD69E7C25C9A9C9886FCC6
+:1033B000BD00DF5F8DF289F290A92501078DD794BA
+:1033C0006F0189F7BFD99B68FF0E9FCD20072FABF8
+:1033D00031C235250E8E49DF91FF7F3CE1BBF1FF05
+:1033E00076FA15FBAD1906D0C979C89083E0642B35
+:1033F00099984C74D4D2BA9DEB32849A7271FF0FB3
+:103400003B85FDD5D23ABBD7F351214D2E6CA97324
+:1034100070795F9D9BCBB6BA4C2EEFA993D97E698C
+:10342000ADCBE3B2A5CECB65535D0997ABEA14EE05
+:1034300027ADCDA860395C051CCF5E99F239E7DF76
+:10344000E3E7CB518D7A6C706DB201EE7D6618F5B5
+:1034500055BA62D457748E29B6DDE51D65684FC92B
+:103460002B30D493E48986FE5326047E3981E48090
+:10347000A7324E0F223F8E899EB36B6915DF4BE951
+:10348000F0D3F59353E3F33556EF00CA3B395B05B0
+:103490009F366B765E13C111CB6405F8DC8CEDB002
+:1034A000E40D01F1FF6AA6F38771EEFE488B1DD98A
+:1034B000D7286427B4C8C28EB78238F76BCBF4879D
+:1034C0006BF07912EA2FCAEBDAE6A6B05C78D8E3A3
+:1034D000F4D239DB96D6656E5E8F579CA771E3BF39
+:1034E000447980F8F3358EA1C67339D6B39C6FFC4E
+:1034F000754FF4DA9491508E9C2167BBF32FEF6BDC
+:103500007429F22FF778043CED3DC8A3D6387BD957
+:10351000A9E55F60A02F61FFA83D25F20BAD717199
+:103520007BF4C312E66FDE9A2071FF3F4F9085BF98
+:10353000660903C96B9717DF8FF53B14F17DE8B976
+:10354000CE8F3F3E4F8C7C0A2407FE3C019F2B4FC1
+:10355000083B254916DFA1D84051583E81C887D085
+:10356000591FD237A95ABEA75BCE908888A13BE7E6
+:1035700019FEAEC88BD06716443F96E8FB17C4BF50
+:10358000FDB66523F9C3C37A69A7FC5002B9E02AE6
+:10359000D1BF1F832E4F3180EEBA23FC5C2589E119
+:1035A000172678359AD6CDC8C5E7A95E8B173100A6
+:1035B0001525F25E3A5FB14A4965FDBEAA446E2701
+:1035C000FEF942717A091FADF955ACAC93867DC8FE
+:1035D000A2B7B1C4C676BA8E87246D5E444F679594
+:1035E0000E67ECEFCC9B11ADE37FCD6336725EAF1F
+:1035F000E5AA4738DFD732EB3F38DFB73A6B7A1EA0
+:10360000C9BDA492E9C7F82097861F660DD2237919
+:10361000C6FCDEE9D3A2CE70A0F8849607048F31F1
+:10362000CF6791FD86F92F349E60A0D0436051F89A
+:103630007B8333E95BF0B5DEAF673E50F5EF4E5765
+:10364000D2F9E0268F90A34DE07D3340F55724AFAB
+:103650002AD3F38237E9BCE9EA8116C6CBEACCD992
+:103660004DC28E177E53936725E76DE3F5369DD7E0
+:103670008C95DB745E3356BE37C9B37BD5CB59010D
+:10368000739CDE37BE9F1D34EA1FFDBDA4CC2B5FAB
+:10369000AB8A392FD56CF13B485EACF2DC678AD53A
+:1036A000730F2881052531E793AC99B3F83D7BB6BC
+:1036B0002FE1BAAE50948544DFB8FF5EED81F59AF4
+:1036C0005CDCA8E997B3ED7393D6FF01ADFF66D23A
+:1036D000EB23A2F8193EF4F26496CFEB441C8379F5
+:1036E00020665EA524B082D615C5AB390A17A4D3CF
+:1036F000E1F957B0DDD1B06E7632E169E7FADED795
+:10370000A3E7D5F57E7A1E353EBF6EF3980DF0DF48
+:10371000A3C985175C0B2B1F40D0EC6C13F4D4B0FD
+:103720004EE891E14F887D9C4987C6F5EE6CEBDD54
+:103730000E8AEF4F91C56E3AE17A465C7D405CFFA0
+:10374000DCB8F65171ED0571F58971FD2BE3EA578F
+:10375000C4F59F1D57BF36AEFF82B8F6DBE2DA979D
+:10376000C5D5FFCD884FDFB56989E0188F3FBDDF34
+:10377000B9E2EF5D5FC57EA2A3E13083E945A7B75B
+:1037800073C543D4DEF5339DD94A46B17CDF81F65B
+:1037900015D9433BDB2ADDE27C4760E56E8D3E4870
+:1037A0003F58368879D0CE4AE6F89CD36390236799
+:1037B000C3B709328CEDB17668EE85C7F7D9E93326
+:1037C000A4D917BDAF5BE7E32913FC27490E414895
+:1037D000F899BA5DBB4D15FCB34D5D50B99EE46DD3
+:1037E0009359C49FB5FB50E86E1D11270F684A38E6
+:1037F000C2F18426CD4F68D3E4C95A4D9EDCADF9A1
+:10380000094943839B28EE9B7C988FE740B3AFE048
+:10381000AF0B103FF797166FA3EFC7EE1E53F2F8EA
+:10382000C35877FD5D827021DAE9635B14B259DA1F
+:10383000948C243A4F946272B4939FB8AAB0CD3F4F
+:1038400014FBADDD7FACFD79C4B39C69F3A2CE0758
+:10385000D9D265227A837C2F7F9786EB54C9C6B272
+:103860009677D5253A77BAF60AB7898CB0F419B2AB
+:1038700099CE11F79910E85B8AF018DC046605EB25
+:10388000196A98CFE25C532A0BFFEA196428DE6FAD
+:103890005716C1EBAB66DB7EAAF68C0F90B438DD11
+:1038A0007995FA38698234E887E38EB245ABAB8FFD
+:1038B0006CA6F3D04E49D4A73CF3F8FC95F9D1FAA5
+:1038C00098671E1FB812DB5B0B0799489EA67B52B8
+:1038D00013DE137375A9909FDB9B170E4EE48FE9DF
+:1038E000A53C13383021E76B25D1D4042C876AA579
+:1038F000AC3DCF14F52B35B8C9B55ABB4794177AF0
+:103900009EF8F1E794BA753B7B809F8D6CC877F683
+:1039100033D88B5797F6622FA279CCF1DAAD56796E
+:10392000009D23DCDA6C03BAFF616B3688EF905799
+:10393000D9F8DC2858DC03AE7145D71D5AD56F1E67
+:10394000D14DC80486386EA6065FFB4493768EF28E
+:103950009B307DC7B755CBF36C8588DB9D1F8BE70C
+:103960005FCD27BCEA78DE57FAAFCD449F1DD90B57
+:103970002B37E27BEB1ACD1C3759D798CB744EE32B
+:10398000907D746AC52133D9ADF9D06E263B7F1482
+:103990007D793D84AE400A70D9AEC9E7FFD4FCF80A
+:1039A00061A0F0F341D0C5C0F9B438F01382CB1058
+:1039B000126D12F18FDBE4C07996EC4BAF48A4B7DF
+:1039C000EB4AF5EF7AA1C652ACF91732C3B78EF8BD
+:1039D000281EBE74429FE38E8ABF9EDA9D7B5F0DD8
+:1039E0005F86D5DD6F18E993F0363B46CF6CD4E0A7
+:1039F000E7F6FA15C2E1B5C581167A7FC9A6BF1EE2
+:103A0000207354565533BDFF14E11D9F2F0C07A79B
+:103A1000D33063BCE14AEA3FBA76DB7E8AA7E5058C
+:103A2000EFA8EC8FEB1BAE54577A888694C0FD3418
+:103A3000CED0CE48850BEBCE4DAF86B3783D6379C3
+:103A4000BC5C7D3D480FD54C476E11C7D7F04BF895
+:103A5000A773CB0B370BF8607B16EFCFE2CE8A5DF6
+:103A6000FFB669FDF8BB8578BA68D5E0F758148EC3
+:103A70006035FA358F2582A34EA73A3C6E78A26B4B
+:103A800015E53AE7873A5F2439E8DFE49EC6F2B0ED
+:103A900038F024BDEF6BF337701E7057275D47D4A5
+:103AA0000D1FA7D249D7BB603FE569C2FBD615EF12
+:103AB0005772BC782F88B8589C3ED44BAB129F6786
+:103AC00010F7E58CDB6BB493915E958D9E587A353B
+:103AD00073BE33A4E9935013D22FCDB742D06F48B1
+:103AE0005DE64E44678F687A658746B7FAF3A13D75
+:103AF0009CBB3C54DAED27664A46781EEA8DEFD32C
+:103B0000C0CBFC807C7084FA65101F607DF00A37A2
+:103B1000D3A7CE074BF6FEF500DD67E3F4C905B188
+:103B2000F7D745343C227DBE43EF2FD9D475807C36
+:103B3000C5C12B047D7E4C77871545E90CFDC7F781
+:103B4000A89F4E3FF1FB78571B4F2EF67F4C785CB9
+:103B5000B829C8E321FF1C2BE5713AC349CC724A4E
+:103B600025ED676B1BB8693FF65F1474905C3855A0
+:103B70006B62B8DE981F5E65C6F2FAA160A5EB869F
+:103B8000AA33916C72298F6BCCFF0D6B33E20FE976
+:103B9000E76F344F91276013C1EBA08DE5690F7477
+:103BA00011D57BAA0EFF157172D73CB1177A3ED79B
+:103BB00071D7162B8E8945DF621DE7D84F8F379D51
+:103BC000193F1DC5FE434BD36CFD9CF00CBA8F67AB
+:103BD0003BC54F11AEAB9A7AB7572F58FCB4F9A436
+:103BE000889FAE008E03AD4C196B4A44379740FC5A
+:103BF00074CAC444F1D3C87B063B735593900B3A07
+:103C0000FC86578D4C16792948A57C891E1FD3F751
+:103C100075B7664F3669706B21B8313C05DCDA0840
+:103C20006E0C4F1D6E33843F425F8853BCD66316C3
+:103C300079B1910B3651BEE054A6C893D767DB44E7
+:103C40007B8EC82F9C411F9931F634F2C19A667160
+:103C50009F08BECF79B517B30F3886509E33D3CCAB
+:103C600071DAED9EFB6AB6733D99F9CF0A6A5B1E65
+:103C7000CE3BFCC3B9EA027A5E62E773F27A3EA7F2
+:103C8000A5AFC8E7B8F2B47C4EDC7C76B8A9B28D9B
+:103C9000E6CB137E4B8F74ECD3F2115A1E2823DF30
+:103CA00098AF70C4E52BE2F3956B9A17ECDF2EE228
+:103CB0002B2C9F87FF7824FB63F1F3B8671AFDB7BD
+:103CC0003523753FEA1147A2EF1852AB8CF4D8A206
+:103CD000E1BBA1AFC8479C6D7C284F36F8552D79C4
+:103CE000E71647D0FB911FEA4ED03FDE0F3D1FFF86
+:103CF000D6CDE31BEF074CE0DF6E99C8F11441DF2E
+:103D00006B9AC5FEBBE3699A5FA59F3FD2C7B16AB4
+:103D10007E1CD773A2724ACF870D75DB985E876AC7
+:103D2000F74535FC7B4A68650EE5D76675513E72EE
+:103D3000E80E89F3EE439D7ECE43746C98CEF9F184
+:103D4000BEC981A727C6C49F76B87E9AC9F9022D3D
+:103D5000DECFF7E6A0DE53D715762A64EF8E04BED9
+:103D60006727392E1F107F3F4E7C7D4E99D0C39917
+:103D7000D741C27B4F3E9F28DACFF4DFAF6038A136
+:103D8000BF9B2CE4ADA2D7FFBFE4A976B61DE2EF3E
+:103D90007D4EF94093B3FF0997A29C3D5112389E86
+:103DA00050CE5ABA58CE8627289F919E5C4E177DDA
+:103DB000101E6E4C7C3F8F5C76A9E2E16981877CA6
+:103DC0001D0FF75C92F942C4437659223CA05F452F
+:103DD000F06AF32983A85D29510653D98D8F1F26D8
+:103DE000E68B5965C2EEBB58F858A7E1E35EC207FF
+:103DF000C769642D4E93C7CF9B357CAC39031FEF49
+:103E00000B7C94E8F878EEBCF09151956168779757
+:103E10001BF191EACB35D49DF9467C240F2D308CD3
+:103E2000B7BC4C16F7240D9C68E877263E8CFEC084
+:103E30009DF45E2FF6E8C04067057D4B34606E7BD5
+:103E400007C9E64C7F5B0595FA3E37C7F9737AB927
+:103E50005CC35FE6D4C4F85DA0F15BC644E526030D
+:103E60003D7C2F317FD668FD979728B794C5F2F334
+:103E70009589FB2FD1FADF3641591CDB1F7FD64BCA
+:103E800031F6784FFB0E242BCBCB78FD224FB6A317
+:103E90003E95F3663B92E476CA57ABF54EC3BD75CB
+:103EA00083E937AC67FEE89B0E95CED9D13D4168DA
+:103EB000596DBBA35FEE1A6CDA96317C25C1B1A9AE
+:103EC0006C88B8BF7591FF6DCAEF28EA09ED1CD266
+:103ED0007CBEEFC814EE63A27BB2C09D714EF92385
+:103EE0009467E25EB7C120BE238620EB41C90FE98B
+:103EF000F4DDB205FC225F4EFDC5F785BCF9140860
+:103F000073DD0511AEA7697EDE0365393C6E3AC8E4
+:103F1000260124AF89E4A8CEA70E4F90E9DF53EB2A
+:103F200036AD245FCE0250467EA073207FCF0B9526
+:103F3000A0523ECB040EB6334DEB0F7CCD793AFD4B
+:103F4000FBC397FB88EF0FCF717FE7DAAF91EEE508
+:103F5000F344EFE56BD4EC01FD5E3EB532C8DF976C
+:103F6000AB2BEDEE06CF99DF973F3A31B08BF0FDEA
+:103F7000B7A4412191640E4E98EDBAA0E3872FF2C9
+:103F8000F8AF5CE4F1DFEC6DFCBBE9D752CAEBF9AA
+:103F90008F123F37B88AD9EED4CB78BC5DA12811F7
+:103FA000EA27395E1BF0619FA83DE73C6A627FA863
+:103FB000C124CE9FA9EF99D8EE827C41074E19F219
+:103FC00072C645C7717A838345DC49C45FEAFF74D2
+:103FD000D708B2BF7F99322B9286E31D7C55D87FDC
+:103FE00096A991CD74BF73FF349B773BF2DD3DDA28
+:103FF0007AEDA513EEBD137FBD798A90172E8BF74E
+:10400000F2023EB7343342F6A3ABD82253AEC01906
+:1040100097D76CB5B42553BCB275C77D15A3B0FB5B
+:1040200063752FB91B137CEFE9D4F29A23A5C472F0
+:10403000F09F939244DCCB67BC4FD85AAE9D2B497E
+:104040008554B2232DFF52D2129D07D04B7DFE2204
+:104050004FA48ABEBF8ED0256E88E7A292EAA464E0
+:104060000F9F8BE824F8567AC30EB27F1F5F10BCF7
+:1040700035F6FBD3D61270911DEF9B22CEC36E5046
+:104080002417DDAFF160C4C2F78E3FB8E8E9E6144B
+:10409000ACEF3D6A76133C5AFDEF3993B1FE388E92
+:1040A0004BF2EEE00E71CE529D0FA16108BF56F2A9
+:1040B0002AB1BE5B11E7B2D9212BD6AEEA43F8FF95
+:1040C00075725F016F0856D3BD9DEB5226F37D9646
+:1040D000D973443C78BA74B483DE7FB0C4CEF81B85
+:1040E000A29DD331A9D57C9F65DFF9C6733A0F2E07
+:1040F000EF5409BFEE52BB5BE5F3974ED7587CDF18
+:10410000F5A8192456715D3CF974C929D6E5157EC8
+:10411000EEE37258A5FB8EFBE27BF56EBE35D170E7
+:104120001E68F726E19FA68D777A91D271BD71E75F
+:1041300085F475B5E1BAE8DE63D7508E4764CC31BB
+:10414000AE2F2DCE6F70C6D5A79677DFE3339CF0E8
+:10415000FD85FFA785AF71AB574EE47FB6D64167AB
+:1041600055CCB904670F71C09AC982AE6D592F380A
+:10417000C84EF9C27FC4433878E59F073EBC97CA52
+:104180007FFD6ED75284CFEFBF7E73C793B4BFDA83
+:10419000BB0F11BDEAFE189FC1C4F5BC586D63B8D2
+:1041A000F96768E7397D1D2F587DDCCEF9A5B5FB91
+:1041B00093B87D64398492B07DA445C9BA99E8AEBC
+:1041C00053F2D6CB3488388FA8E37FED0D7E138C65
+:1041D000213CFA25BA0F639A76BE76C3229009FF76
+:1041E000B645ED7C5EDDB75C9C57F729D5497CDE92
+:1041F000748E99CF87D4575F73F930ACEFBA5CDC1B
+:104200004F3563B9328FE75704BDA475169B9713DA
+:104210005D6689FB9AF4F3A645D0C5DF7F8CF4B6C2
+:1042200077D848DECC4700D3FA5A357C69718322AF
+:104230005FA74AF6A4CB6BC463461CDEE2F1BA4228
+:10424000C7E34818497894A12D99F4E14300ED742F
+:10425000AFC086E54FCFA3F36C5FA8690CAF9EF8A3
+:10426000F91DB4579511740F8B83CB4EB457A9DC4D
+:1042700085F62A95AE60C575CB71DD7BDE38F8D248
+:104280000F71BA594AF5957444AB48CB7B81BA7427
+:104290005025AEFF06E25E51DF4289C4777D92A1D0
+:1042A000BED66389FE3D00FCD595A5FF7D80D35B1E
+:1042B00094A108964C8B968F11F559E487C4B4EFFE
+:1042C0009E69EC5FB63F66FC81B8DEC5366E0FEDC9
+:1042D0005BBA45B5C4B43F87F572805735FBF1FA38
+:1042E0009D66FFF604F2EDDD7261475AFE052AC9AC
+:1042F000B52FD14E23FF5E322B2CDF21D72227BAD8
+:10430000570F00E561AC5F2E1BE5EBE51A5F58FC2B
+:1043100015A0E5C7E01B3DFE803F7BFE388BEF63B9
+:104320005A35C4C2F70FA13EF0F696AFB3782C9F72
+:10433000C6DEDBF5AC2EBF87C1309AFF4B28FF43AA
+:1043400005F341CCBD0DC4F76DCF5FB614E7F11D89
+:104350004DE638AAE45A9FC2F731D535B13C7F40CB
+:1043600009FCB63CE67C4963FAC242922FFA3999BD
+:10437000E8BD47D798BFCDBDF71DD50780F4C297DC
+:10438000485AF65EE8B0B16EEF115AC7EABA762E17
+:104390009D6E85858DDD12E4B8CF154AE04FB43EA1
+:1043A0007B26B6C7F089D58DEF19FC0EE37D9CB254
+:1043B0003BE224B86F28F9C049F3B71E167CBDE173
+:1043C000F0EC24E2BB56EFA124E29B2FE8E2C7EF1A
+:1043D000C0273EE5559661BBDF48BD9EE8674F4369
+:1043E0001ADB150797DF7F2DF1CF8DBFF801C3BB17
+:1043F0009B6FE0E14195CE18BE818799AEBBF9462F
+:10440000ABF7CC377F67BEDADDCD37A2EECB074303
+:10441000FDE04C63FF6EBEA0F1912F1EAFB073BBE9
+:104420007DD2C35BD418BE3A49F558BEF909F24DA6
+:1044300002B93F7D9246DF17986F522E32DF0C9DF6
+:10444000A4C9CFEFCE3763275D14BED9633A1FBE30
+:10445000B9EC4CBEA99AD4F7DBF34DAB3BCCE7E902
+:104460005AE79813FE7D900F347939757EA0B28D8E
+:10447000EC1A45DCDF374D9A99E5F3109F497487B4
+:1044800034EA4FA1CF0F5EDFFD7D06EB67FDFEF541
+:10449000F58450B293160BBAE9AC1371DF6952F987
+:1044A000B4C5A477E93B024A3553F694EC02D4FB39
+:1044B00032D985D05EE1C179365499A04DA62D0739
+:1044C000AB87F1F861B6CF8668717FA7942FBE677E
+:1044D0009A29FEEE85FE5D4CB562BC5FB6FF59ECD5
+:1044E000265C770AF931EE12F17750164D8AD7BF64
+:1044F0006887E0FA3A07DA984E362857F71A273ACB
+:10450000E35CB52F98302FF9D6249376CFBEF233E3
+:10451000A2B3DD6F6C49A673127B24E0F339F383F9
+:104520004FCD23BE73A942DEB4AEF833A52361D7C5
+:10453000B41F1AF5347C6AD4D3F0A9514F6BF51E21
+:10454000E58D7AC2A8A7B57AB79ED6EADD7A5AABCE
+:1045500047E5CDA7063DBD61D2A70679F31ED5CFAD
+:10456000414F1F9E7471F4F4A88B2C6F9EBE70F2A5
+:1045700066DFA4BE1743DE1C392F79937DA6BC39B4
+:10458000743EF2C6B5B943A5F4CCC21EF8A056C31A
+:10459000FB5B65CADB343E949C5BBC269EBE3AAA9C
+:1045A00017AEA6BF2BF3A557F87F3DBDEFAAFDD5EB
+:1045B00091C6183FDC65E914DF23D4EEE1E7B76C60
+:1045C0007E95E3B1675D2F5D105A74A65E45BBC84A
+:1045D000C1F4EB35732EFC7CD7D13A47F0DB95CF95
+:1045E000DEC1FC945C6E9C4FB77F3BAA6D669EAFAC
+:1045F00044C8E99EECA19EE6FDA05C16F7FFC5CD80
+:104600001F4FBF489FE9938B981E2D742FF8179D5D
+:10461000C07FA7EABF4E6EFCBF8A7C49E9C51193F3
+:10462000CF834EA76BF84CB06FEFC5DDF705E3CF36
+:10463000E993CFC38E3E4CFBEE9B70DFDF67385EA5
+:10464000B47D5F30FFE1E6F3C1F7BBE5DDFBE6EFEC
+:104650005132B47D6FF8E735EF515C63C3BFAE7D77
+:104660008AE21AF77D9DB78DE21AFABD726910FDD4
+:1046700091F5EF8F102E2EBFF89E24634ECC774518
+:10468000C0FE7DF4BB13B2377CDDEDFF2BF7CA9182
+:104690007DD2DBBD72AD36635C4F2FAF2A17F64A71
+:1046A000AB691DC72336A05F558F78EB9823E211C5
+:1046B000AD68A7B0DC9953D0AB7DB4AB4EE1B85335
+:1046C0006B9D9FCB7BEB6670B9EBB5256524777D41
+:1046D000AF2D62BDE7F3FAAF7B1881E4AEF8D049A5
+:1046E000CFEFF5E8FE90B05FD2C87EC1FAC393D792
+:1046F0006F8D8D0B8CFAEFE15BD481D178555B66C1
+:104700008CDD23C7FA51A012B944FD28AC1BEC9AEA
+:1047100011EC47ED26BB06EBED934718EC1A7D9E96
+:10472000B566A821BB66ED0EF38C4476CDACF2C421
+:104730007E14D6390FE27039F8FB7F49FBFB5F51DD
+:104740007EE9DDAEC99D7271ED9ADF4FBE30F18713
+:104750006E3ED6EC990714E50D4DAE7C47F9B1D10C
+:104760004CF1E36F2B3F4692FCC837C88FCFCE4742
+:104770007ECC2A771BE2A20765B5CF58B2D37798D3
+:10478000A15ED6F42FD63BD1AF31219C7E5221B110
+:104790009FB3C10BFCF7FDA64BF35F267AD8BDC8CB
+:1047A000CCDFBB3FA88873220FCD11E7A91E5E5E48
+:1047B000309B3E235A9772C3DD4914D72E17F70456
+:1047C0004C97CA39CEFDE00C61E7643BDB2FA7FDB7
+:1047D0001FACB000D1D5D9E2DC146EE778B5E6475E
+:1047E00081B499FD0ED70F2D6E3AAF1A1FBF769682
+:1047F0007CCCDFCD83F40A7FDF7DB6F8F5B78D5B27
+:104800000F98F29DE3D6CC8F35CF0DBF41759E49F1
+:104810009F4726CBE25C620F7A2C9E9F3BAAA7A7FC
+:10482000457A3917E524FB29E61E59FD7BD659E563
+:10483000621E27D94F8551BAE8A82EEEF55EDA94AC
+:10484000DA678EC4E685522CED3C5E4AED3E7EBEB4
+:104850009ECE2F90CCB27859AE3E5E89F239C178A7
+:10486000FBEA8287092EBFAEAB3D4C71EA49964EFA
+:1048700089FE9EEBDE3A95EB7BEA9AB8DC55D7C60B
+:10488000FDD6D76DE2F2BEBA103FBFB7EE31AEDF54
+:104890005DD7CEF5C773C53C132D211E6752178E09
+:1048A0001FC30F659FE03C31782E8DA886F6096FF7
+:1048B0003619DA8B3ADB0CF5BEFE4D86FE7D66843A
+:1048C0000CED6F950502538AE85CC363867ECEFCCF
+:1048D0007643FD5CFD850BDD6F654AAAE51FC8AF19
+:1048E0008302484F4867E9B5B2CA79F31AC197FD08
+:1048F0006BBD61AA6F71D998BF75BAE433CB26B18D
+:104900007E53CC3DB51D2E717EB2A1AF88A734FC7D
+:104910004CD4B76489F391C3AB447EA461A0B8972B
+:1049200044CFC36F7169F793F8C43D1A83F223FC37
+:10493000DDED20EDEFC139CB45FECC0D6ECECF378E
+:10494000D481F67D6284F31D1960F68AFBD5159932
+:10495000FF9E920542F5385F43BE5BBD85E44C3057
+:10496000D56BF6F29F960D99298F48E2899330ED29
+:104970009ADED1F2F2491F009F3BE886CFE7E27B47
+:1049800084DA2EBEB7A97F6D17E7E3B6FC42DC637D
+:10499000130FD78E5F7CC5F72A6DFDD95759C4D444
+:1049A0005BBBCFED7425C57E8FB6A52695EF5BD892
+:1049B0005A9BCBE728B6D688EF8D6510FBDDB2C8D1
+:1049C000C6E730B6D69ACD24274F2DB2305CF4F529
+:1049D000C7CFAB7FBFB94E3BD773AF76AE67AD766F
+:1049E000CEEA6EED5C4FB376CE6A8D763E76159D3F
+:1049F000EBB1133CC5B99EADB50B14ED3CAB7E2FAE
+:104A000003C35742F8F2772A56D86B1A07F4870C7B
+:104A1000196EF1DFC7665425C79DE7319EB74AF589
+:104A20000D30D49DF9C6F356C9434719CFA90E34AA
+:104A30009EEFB1798CE77A2CCE4AE3F9D058FA444C
+:104A4000609A566CAC27FC77FF7D477AD88FFF7E43
+:104A50005C37FD86F47340129D4349637ACDAC12F6
+:104A6000F499A17D0FE3864E2E53915EA874529E59
+:104A70005DA273902AD351F4FB37A5577A3ADFBF72
+:104A80000720AD4CFCF700F473087FD1ECA8A553C8
+:104A9000944FA71445E7BB7F8A723CB6AE973DC9D9
+:104AA00085FFADF2FF01C18CE32B00800000000008
+:104AB0001F8B080000000000000BB555CF4B1B41B9
+:104AC00014FEB2BBD144A35934B6865A481A520DCB
+:104AD000A4B06D37A225D2D5869283C8163C78E85B
+:104AE00021879CFAE358E86D635B904A24A9422F22
+:104AF00052C8C11E0A821EFC03621B7A8E680B52CA
+:104B000029C18AE7405B7A11D23793AC899BC47A7A
+:104B1000E940F2F266E6FDF8BEF7E6E50D68798158
+:104B200090A2DD137D40245A2A3848065468B930D3
+:104B3000305324E9A2FDB5AA94359114C0A9095CAB
+:104B40009ABA1E2F4912D9C9163BFDD4CECEEF8D8D
+:104B500031BB0126252EAF1F39000FB015B3E51666
+:104B6000FDC0C20E9DABC0EF315B0E7E96DC49A549
+:104B700032CA4D01917D69BDDE4BC02CFB49F17AF3
+:104B8000C73D0309F29F3180FC30BBF3D0CD745791
+:104B9000343BE5A33C427B4548E42F5284DC078646
+:104BA000AFAC81F6E7AFDE17258AFB6109B84CFB95
+:104BB0000BF652EC11DDDB1AEF945F28CCCFB4FD7D
+:104BC000299DCF5C1121325DB71F962855D860AB67
+:104BD0005C237EA25255A755A1CF0334E894F70C6D
+:104BE000D347EABAFB243029535ECF0FFC1B8591D3
+:104BF000BA5D805261FBB7B51ECF71376D8410AAC4
+:104C000088751C15B6EE36CB3F866FA360673821DA
+:104C100030BED43D21E7A738BD5F96BB183EB1A892
+:104C20008B25B2478C508F13CE3DDD8D73FC7D6795
+:104C3000FC7502078683CBA22173B9650C72796C6F
+:104C4000F8B83C3246B83C34142E4BC61897408A0C
+:104C5000D7B3D3061E2F63C47763C1F6F1645B59E3
+:104C60006775C78484F7ACCE432AB76BBA17253F64
+:104C70000D7C115DBC190A3D6F2799FDBB27028F82
+:104C8000B91ADDF4EAE166FBD56753E7E24E1B7320
+:104C9000BBAFECEDCF5D1D486CB6F0FBB2D6C740A4
+:104CA00096E711880B58A43CBC0EC529D3FDF4B679
+:104CB00093F7754871E49C0CDF9A0B3F4C1CD43F72
+:104CC000CB696A19829CD524997AEAD46F8F42F90C
+:104CD00034F45560FAE320AB677A223FA8138ED5EF
+:104CE0009B9FE786C92EB5232288E6BC5E6B369E65
+:104CF00097892B202982DC027F3B5C8F6BF618F2B0
+:104D0000F0B960E5DF7ADFAC3BADB4345A7BA2B4D6
+:104D1000125D898C4675D2D66D9C07A70FFC7D77F6
+:104D200040CB33BC17C80FB8433CE7238994AB9EF4
+:104D30004FBB3A997974D7FACF9B2C3B12846FF909
+:104D40001F7DD8672F3A58BD9692423CD7228FF5E7
+:104D5000DA9C5B526F39D97B44B8751EFD716B9F2D
+:104D600056F35991C83F9B4F2AF96FC1F737C67761
+:104D7000B59FF745AA6B46137CAC9FFB891B8D4200
+:104D8000F547904B116FD9A8A0E4E9FC97DAA17020
+:104D9000F796F9D0145F6DE8A36BCD73675B73551D
+:104DA000E74D1041366F7E0ECDBAF32DEA6B4A9374
+:104DB0004773EE34F358AEE24C567122DCFA3DD71D
+:104DC000EB355F1BEA488867FBE6EB797DD38E7F86
+:104DD0006B1FAC2475779EFE1FF0691FBE1B8C8F66
+:104DE000B3EFAF1D6F569E8EFF334FD6F3A23957E8
+:104DF0002E88F3A2F74CFD2FDBA790A6F00700004A
+:104E000000000000000000001F8B080000000000F0
+:104E1000000BFB51CFC0F0030977F3A0F2BFA3F161
+:104E2000D7F3A3F2CBB851F99E68FC2634FDE7D145
+:104E3000E4591820B4233BAA38B158988381410E15
+:104E400088353950C5F3A1E6D6002DE807E215AC48
+:104E500084CDFA2C05748F1C03C32920DD00C4D730
+:104E6000651918D8817C216906065F204E00E2CFC3
+:104E7000320C0CB380F43B20DE2A0DD1C707143B63
+:104E800027439EFBBB85C8D3378AA9831F28A1F27D
+:104E900067683330DCD66160D0D683F0AF20C9BB01
+:104EA00003C5666A43D831AA0C0C877419184E28BA
+:104EB00061373716287F18281FAB87DF7E572354AA
+:104EC000FE2E6B54FE4F4354FE134F547E9F372AE1
+:104ED000BFD107420300BDE0D98DD8030000000018
+:104EE00000000000000000001F8B08000000000010
+:104EF000000BCD7D0D7C15D595F8998F376FDE674A
+:104F000026C90B3C20C02404891AE8000182224EE5
+:104F100042B0C14DF181546997EA93B53622C81366
+:104F2000B1A6AE6D26DFE1AB8DE85656AD3E586DAD
+:104F3000A9D51A2D6D6957DB04D0C52D8548A9B5B3
+:104F40002DFB6F50575B16D9E816755D5AFEF79C1E
+:104F50003B93CC3C5E3EECC7CFC6ED0E77E67E9C25
+:104F60007BEE39E79EAF7B9F220640BF1CE01CFE14
+:104F7000B1E7452200CC197C462BA0542E07D8243B
+:104F8000048D70117BFE415AD91566DFC08A2F9FB0
+:104F90003ED8EE5A10A8FEF3456DF13EF6BD63EA29
+:104FA00057E350C6EA4F14A8BE53CF79DE0812402B
+:104FB000014049E76A35C1FAD934AE49C5FA1DFA4C
+:104FC000F695C0C63B53A28084E315656FDFD6001B
+:104FD000D03D0DE072D8AA16C758F998646C866C5B
+:104FE000E314D1384ED91F17A1BB14E8EF1CFBDF27
+:104FF000A62F2621C1C66D9DFAD59508B7D27D335F
+:10500000E811803BC6254167EF678248F3522A2C9E
+:10501000305959D5ADB835FDFC713A102F65D86BB4
+:10502000677C7964F0FD32072F0C1F197801B804F2
+:10503000408359DD16960340ED33FB35EDF1B5F8AD
+:10504000E8C63F7FFE7CFC19A0131E40ED8C272292
+:1050500083F06CF2F5774B0CDF5611188FB12A39BB
+:105060006C9C4A573F99E30DCC53EEF4ACFF74842B
+:10507000B380E621C8AEFE32E1996BD79BCB668E3A
+:105080004F675E390BF83823F57F25A2B800EB7720
+:10509000C6AD888B1E65CB83F7A05D5F33BDF586FB
+:1050A000C24F08F13307F163C5911E1D3A96C27ACB
+:1050B000630D9B4F8105FD522E918D096300F2F126
+:1050C0005FAC89ACE99548AF634C56977D1F1BB325
+:1050D0001A25F67EDC82B420B367041ED2DE0801F6
+:1050E0004253728E1A599CEEBB6677F431BA3D0377
+:1050F00091CECDECD92CB37E116FC723E9C71848E8
+:105100008D97A51EE963E588254353398D4B7C783F
+:10511000A77491B19991F4669BFE3B1A547AB63507
+:1051200068D0ED07686988D3F3FED097BE81FDD7BC
+:105130005B7ECDCF9E72D7ED4F61B9192081E345DB
+:1051400062BC7F9055ED310DCB6022DE2325FCF94A
+:1051500012E285C1F9558649C4CB0F6D3CE9D04DAB
+:10516000FCDA6C2CCF812CF8749EA1522F9F05F491
+:10517000206B3958F6C7F33C659F36DE531FA0906D
+:10518000F04665262AEA042E8F22722F180827C3BC
+:105190005756B960CB15499AD9DFCDE6179EA718A7
+:1051A000BB58D36D8297BFC6099C3ECA04959E31F9
+:1051B000E8DF7F0EF16288E9CD6CACE0CCE2AEEEC8
+:1051C000188EA91853D93A067D692D2F0B7F41B946
+:1051D0007CAACF81BBF8A3C78F24F5A41259C6FDC2
+:1051E000BDBD7E979F3DA222FFAB33C544BA0CE103
+:1051F000B5126CF2B05597459CF74707F7F0EB7581
+:10520000C2E6E73650A9BE8CEB553EB85E1D065B84
+:105210002FE49F72BE5E1DB2A58E66BD1E07F0E034
+:10522000253480972E8E97B28F182FCDFB5626B23D
+:10523000CCA3CD5E4F190CA394F0A0E808E7D646A6
+:105240004EB716A3DB6CF277283C4839C7E3C9B2E6
+:10525000F3F17E8DC0C75964F38983A74D865893B7
+:105260000E239E3A6B506E6D2D1145944B1F159E6B
+:105270001CB8360FC095E670957EB47049A1EE95C6
+:10528000D9F8B12D831FB720DC9CEE6A38DD891F69
+:1052900029DD397005901FF83A27F83ACB7F13EBD8
+:1052A000DC36B0CE49BECEF18F669D9DFD1C5463A9
+:1052B00025AE5B9DC6F890C1718B642937E0FE1A5C
+:1052C00012E03183D101C23F8EE999E1A697751DA5
+:1052D000E03E21C0F50D69554ED2056F9DCC749608
+:1052E00059F87EEB05C961E601695F7F9F0327E3FB
+:1052F000DFFAE38DED075C707E5188C408CE79300B
+:105300000FE17C27BC3CA71B86EEEF6483DA28FB09
+:1053100000DE6BB0DA0FF8CEFF7E8B04A96CFAE5E5
+:1053200083B65C00B54BA1F9DFCD787026E2E1824F
+:105330006A88B2F508378DC17940987D9CCFFAD93B
+:105340001D68945DF81D6A3E037875DA3175C79F54
+:10535000777EFBA1DA7D20241F11187E5B63623506
+:10536000C2A596401AD7C0BF7B59F778181ADED667
+:10537000D85F06DE21D7CDAEF74EB8A90D58BB6673
+:105380009F71506774D252201A4D300887432FCE38
+:10539000BA38781CEDBAFC6680BEB65E01A467829E
+:1053A0002ECDFCF3E9EA20D2D5C57F7DBA7AE36F32
+:1053B00097AE4E0A057FBB74A5D44BFAEBCCCE2832
+:1053C000924D2E27B5D516AD3F8ECDE492D439B38C
+:1053D0001BE525C4997DC68701919515CDE47A2FEB
+:1053E0001880FAAB5AE29593BE42AF9C8CAF34BBA7
+:1053F0009D7E37EB38AE42E3A27984E3CA61E80EC2
+:1054000044B1AC503F48CEE7A6303CC18335C5BC63
+:105410009D81ED869A8F8CEDD878A87E9C2BC276E4
+:105420007F9F93C862F70ECEDF3B4E7C452227114B
+:10543000197D7D08CBFA1B2EBC0FDD4E86371CBCB8
+:1054400030FA2F453F49C120FECDDDB791FF220044
+:10545000A241765D619B855FDBF1FFCDC77D9FF348
+:10546000757BE12C0DF52D60FB0DBEB784CF039647
+:105470003F1074E25B673C299C00A21BBBDE48EB3B
+:105480007F27F25316FE5E25727DE3BD2FA5FE1B1E
+:10549000ED416BB3A03FC6F07AB8E17D788DF1E5C0
+:1054A000EAEE0B15F47B5C2F8EA17AAB1714298BD7
+:1054B0005CFDAC066E1702F4C9CB22EE711BB91E5F
+:1054C000DA25EDC379BF5A21A571FF7BB5E27F488C
+:1054D0003F7FD594D288E4573BAECE194EEE1C6E7A
+:1054E000E0F6AC53EFB029D1FE7E58EE0B67D3E364
+:1054F00007C74FD3F8575548DE7D5AEE9371FDDF4D
+:10550000FB22F8507F3EDCA00AAF4D65C62FCE933C
+:10551000D1D1EA8A2205FD0E23CD6B89ED0773F008
+:10552000EBCCB3252CD23C5BC255E4B76AD1DE216B
+:10553000FBF10C7B8FF26028781DBF558BB63C2B9E
+:105540003E9408D7B7145F32BBBD69CFD72967FA3D
+:10555000B31CF8DAC2DC2E6A0B73B8DA62621AF98D
+:10556000BF2D9E7D5CE7D96CC3E7D46B8971BDB458
+:1055700085C993D1C02387BDF030B41D457FC94490
+:105580005BD6E4D7F6367E0EEDEC64D8940C7CD373
+:105590002B4C62E5097109366B6CDC9AAA8E6AC6DF
+:1055A0000279AB122F3230602C7456A21F70F217A2
+:1055B00037F67C8DCD6BC27CBF86EDF26A523DCF53
+:1055C000B176E399989358BBB1C7D7AD4339FB4F38
+:1055D0006827A220B66E6A443F560B0E7109C0C3FD
+:1055E000E2AA4AF4B3C9C0E502937ABA3C06FD3395
+:1055F00040CE99A1E403FB13CEF907DB0D85B788F4
+:105600002DAF68DE24AF960F2FAF36F2FE2DF61FBA
+:10561000CA9B0983E351FB71758A078F6333BE1FF1
+:10562000B0E9D20FCBFEAAE38C87E501D44F222B41
+:10563000442D8DF5A12B17FD5063D6CAD08DDFCB3D
+:105640003B1B99F81811EF4CEED570BF715258E61C
+:1056500082F79722F7334DBAEB9820A0DFD7602A64
+:10566000FD4C2CD7CFCC46A7DB6DFA1C28D7AC1647
+:1056700092345E62C954946BB522D9BDFFB46256B0
+:10568000AEBBFDFBF63883EB0FBA3C17CB7CFDE5D8
+:1056900015A21998F1A7AFBFFC21D73F7FA3E2D98C
+:1056A0004F3FECBAC8687B148CBCFE7FEE38CEBA94
+:1056B0009DCF1F5C3E4EBAAB3A80F2EFBEC4F07293
+:1056C000E5FC755B4EEB36660598E92C72252009E2
+:1056D0009E7DD579AA900283ADB3744C22F9268DB4
+:1056E0009DBB72270C3DAE145332EC37BB3FCBDC75
+:1056F0005FC2D6FF13E0FCF5CA28876A510EA15C91
+:105700002AF7BDEEF68F308C0F9619EEDFFAC2FE47
+:1057100003288F2C268FD07F9AF9BD16CB2E7AB80E
+:1057200042E2FBEFBEEFFEE202818D73C4F0EB7E3E
+:10573000F6EA90D0FB06F97D2B25DA8F113E752E07
+:10574000B607524E8E989259CDEAF7960BB48FFA5F
+:10575000E1A5EBFE91DA8728DED1BBE0B52F5FCA69
+:10576000DA7FE2321F720EC704B68FB37FA25E7378
+:10577000B6EFCB97B2FA872ECB1F56DFAAC5F9BA80
+:10578000E8E4AA67BDE555486F08FF7FBC59FB20D8
+:105790001BEF08E424FCF8ACE0F01D41F890EEFBB0
+:1057A0007EF506EA85874D81FC51472A7E16437BAC
+:1057B000BCD214485F5CBA4048FBB3CC73E982DBCF
+:1057C000264F62FD258C901660DF0F55BEBDF55249
+:1057D00006EF553F90B6E1F3F45EA920593634BC8C
+:1057E000CEFBAB4CEFFB01BD189216E21D341E97A9
+:1057F000F0C58CB89B5E07F418396166F3B7AD95B8
+:10580000B8FF51D00CD2EFE4B002388FA1EADF34F8
+:1058100004FDE6407FB7847038FAF7D9AB75B73C22
+:1058200074E050E44412C791340576A19E917B8DBB
+:10583000EE9E7F83C4E34242DC2478148DC3A3C868
+:105840008699CDDF546FC3E3F403D069B7EF87BE09
+:10585000F0207CAD81C44AF45B58B9DC7FD812F1EA
+:10586000FA03F7D8FD3CE6F4E783AC71158026EA2D
+:10587000BF6A4C858AFD3757703D490783FCE32D8D
+:10588000CC6E8461F4BAADB6BCD88CF10D3FC6398C
+:10589000343BCE11E7FA53F819F2939D2913C9AEA0
+:1058A00019AA9F88E1D54742A55E3BC6D15F027A1F
+:1058B0005E861FC8EBF7F18D914547EF437A1D09CE
+:1058C000FE013DCFAED72EA7542D2B9ED2C3EA7337
+:1058D0007F3DFCF1F6215F97960DAEBF14DE1CBA3A
+:1058E000CAEC5FC95752698ADB25E21E7DC09693D8
+:1058F0004ABE9AC27D01D4A1BE0779FB30FB8EF16E
+:105900008C7042477F8A043C2EA4221FB8F0F3B665
+:10591000DDEED3B268EBF3298A830A7A8AFC766AD1
+:1059200021E31FE1FC76CEB3CF6EDFFE87DB5F2184
+:10593000FE2850893F049DF14F96719A24F394C438
+:105940009EB74AE65BF8F4FD514A66E393FFB2E581
+:105950008A5A9BD0D5628A2B923D92094740E6FD38
+:10596000DEE4C06FA5284E395AF8DF1F25FCCE387B
+:105970000C7E592E20F87DF81C0A7EC986270FF46C
+:105980004619E59ACEE52BC032DDAD97DC28737958
+:105990009167CB2780DBE26E7BEB7ABB9FD1CE2772
+:1059A0004F1EDD7C9C71D97C26C97C3D26CBC3ACC7
+:1059B000C7441B8E1B65BEDFA9D5093DCED6257712
+:1059C00008BA5A60C39192455BAFB8ED43D1D5C5D3
+:1059D000A39CC782C1759967AF4BC570F3986BCF15
+:1059E000A35382F9AFA35E3CC5F1F72CF7ACCB1DF6
+:1059F000367E3AFDCEBA6CF0ACCB2DF6BC463B9F62
+:105A0000C5767F23CDE78EC1755966CF67F970F3F0
+:105A100071D5BFD6AEBFD2AE4F76C71D726913DA4D
+:105A2000194D5262955C30381EABF71977BDB79BA4
+:105A3000CF34DAF56EC0F7420DDFFF58BDD5EE7AF0
+:105A400060459BD03FD08AB602B3634A5A2EA9B2B2
+:105A5000DBD551BBDA81FE6FB6F983DA055A8426AD
+:105A60002B4CF5D661BDC6457F74EADDEA85F76249
+:105A700007DE0D046FF5001CB7BBEB2D9027507FA0
+:105A8000E7C51D46E90FF2C5921D18E7CF834827E9
+:105A9000E679B4C9A947300FC0B264780CF309FCA9
+:105AA00086803EB66845EA1B582FD762F635AE5B56
+:105AB00055EA292C5B22249ACB299F80F205EA65BE
+:105AC00055F31B987F61C00E56D662721AEDF356DD
+:105AD0002169E1BEF85329F96599E4ABB6AA11FB37
+:105AE000CFD7B99E0E7DB46F3970DD13BA8EF21F19
+:105AF00072195CE88F6ACD80EBFED0A41EDC6FEFDC
+:105B00002D50484F66065629CA973BA5A081FDF542
+:105B1000147C9EE0DDDEC8F31BB67FE2F304EF7D6C
+:105B20000250DCF63E1FCF6FB8C7A76A4D1AF617B2
+:105B30001DF759CA87C8D1FCE5361C08DFDF1513ED
+:105B40007CF9A055DE2890F8EA41FBB6B542217DEC
+:105B5000797B6C5625F557A1929E7A5F625623E9B0
+:105B60001D1541F2D1E7870DB25BA3F314B0B01C51
+:105B7000331A51CF8CCC0D620E0CE417022617405D
+:105B8000641AA4B1EC83CECE12F68C7630BB249F7F
+:105B9000EC26B811EDDE0A8677B4232CF328DA253B
+:105BA00061B0FFA44326CEDB374102F47B38EB1B08
+:105BB000ED1C683FACDD154D8FB25EF7E8EA453A63
+:105BC00098DD3F7B14F53A47592F3DCA7ADDBCDE9C
+:105BD00088FE0E83DB7B2AFB0FEDB640A6DD1CF6AC
+:105BE000DAC3BE8CEF99F1B8CC67663CE4A4EC8DC7
+:105BF000878CD4DE89838C345F744A0CC0298D5C19
+:105C0000DFD13787FAAE8CBF266EB2F6ADE33E1D0C
+:105C100027B9366E157F4EB4DF4F5C69973F6D979D
+:105C200057AD34B3C8F7B13E2E874BD11F329CDF3E
+:105C300001B8FEF80683FD9C80C94BC3FB4F32F5CB
+:105C4000DE4C79A7CA5615F2EBF604F76BFA9119F8
+:105C5000910F0B81FCB03E487596A09C0033BA783A
+:105C6000CC20FFF8CC174CE4E7C3E324102A687D6E
+:105C70000CF2A767D049265DF833FC397F2E9D7C56
+:105C8000CCE78DC7FEA5E844E99046C53F4AE72822
+:105C9000EBA54759AF7B74F5FC1DC2E8EA758EB2DF
+:105CA0005E7A94F5BA79BDB6F90ADFCFE17B4D662D
+:105CB0000983FB12D5536EBB24E8FD7E69D8536E71
+:105CC0009FA3D0FEEF94FD73554FB99DC979CFF7CF
+:105CD00079612A6F6AEDAE625BD9A8F9E43FFF44AF
+:105CE0003E295547F04B578819765B065FA97A0025
+:105CF000DBE7CB3A60FE547E8CEF53EC69A6B3E051
+:105D0000F7119BFF77C93C7F73BBAC07D07EFC5B70
+:105D10009F67A38FC3EBCC7724781DF9FBA664EBB8
+:105D20005B43E57D54F3BC4C1982949759526D56F0
+:105D3000994C2EC92FF2385866BFD729C9A77D2E96
+:105D40007B58D6923CBE67F7B7A44026BD44667226
+:105D50000DF51E05123545144714C9DF278747D8AE
+:105D6000370A5D72AB7818B8ED3C56FAA40354FEBE
+:105D7000968F1B3480E46B04FAC898CE41AD670A55
+:105D8000EA69BA00D4DE10B8FF7C8186FB5E2CF095
+:105D900097EE7715F52B98F7C0B9D087E857EE2323
+:105DA0007FE75FBCDF11E00D607EEFC5144288B96C
+:105DB000F37B7DF114BD84B3E7CE49738137A1BF76
+:105DC00024C5D765D1207F288C8F925DD61ADBA0A1
+:105DD000BAD7F5FF7CC51EBF89A2B5DD2644D9B36D
+:105DE00070ADD9370C9D9FC3600CFA470A6F34FB26
+:105DF00086D94F07E29918AFCFC2076D4A328DFAA4
+:105E0000BB3529CCED7939457EC676216FD6E67251
+:105E100017FD162ADD0857A4DCB4D0DE6BCF170DB2
+:105E2000D45365D8DA2BCC60EDA45A2399458F184A
+:105E30006C2F9F74CF27A678F5A9E611E8BD7504ED
+:105E4000BDC7A718C96CFED0690AB76B7DC1ECDF6E
+:105E5000EF12AB4A9439E7E38DA9F9DCBECD850E8C
+:105E6000E1639C7C28DFA1F08557100FAD0557C476
+:105E7000879B2F68DEBCCB9B4473A6323C1C73B25D
+:105E8000C131DA7C10ADDA203A1CD097629CAE5159
+:105E90004F12C660BE07FFDB56BEAB1BF3407C371C
+:105EA000F0B8AC64EE06F4533B7A9364064F88B4C2
+:105EB0009E0BB8FE54CAF52193FD87F3882E185E19
+:105EC000AF9632CACB14AF3ED4DCB017303EEFC031
+:105ED000EFF8F132E7758958756D767C8CCE1EBE71
+:105EE0008FD10B4CC378948A4881CE068DCA5F6EE1
+:105EF0008853796B834ECF9686527A6EC1A6F39102
+:105F0000CF531D450C6F1DF147E39F6555EE43D9F7
+:105F100041FBFE758B504FDE3C50666620837B3321
+:105F200006BC991E71BB72D522B4DF3707C0F62BB1
+:105F30002C5A647ACAD7345762D9F6336C6EBB9E3A
+:105F4000EADF3711EC7310A6FA49D7BEF788E223CF
+:105F5000FEC6BD85B7379BB1BF806C97E1B645DE05
+:105F60003298084F40E5E5FDCA06EA9F44001BEF62
+:105F700027CAED7CBCA9DC8F0F65CB47C023F7EBAC
+:105F800083A273F9599647F92C8A61A0FB15EECBD1
+:105F9000B5E11E6D3F7292EF77C7B2EF97837C3306
+:105FA000C2BE66C331D2FA3374D87E88245838EE24
+:105FB000CF791CF1AF3DEE7DBE0F8717A5A2DFC2E2
+:105FC000F3230B94E4F791DE23665777112B476B8D
+:105FD000BB2D62DF518E7BAFA2D9F34E12FF3B780F
+:105FE00076F48EFFF279D7D11733290F2910E6FC0A
+:105FF000375A78FB50BF9A33D80F3C51356E387DF5
+:10600000AD2021A21236202FF26B82688C0D947382
+:10601000CD3C4F39A762BCA77EC428F67CF7691730
+:1060200079BEFFA9EBF4F38C79FCBBAD373AE51FE1
+:1060300067CE7394FD3AE59EBE4562295B87976BF8
+:1060400025D2EF5EAE7DEDBED9584E4814BF3DB3AC
+:10605000B2D9878C740CCCC81CF4872525DB9F6EC5
+:106060004E447CFE1CFFC9C67B09F73D269F8ED897
+:10607000E77F989C9888E79F8E5C366F22AEEB1185
+:106080001FE76FB03A493EFDCC071E79F0335BFE47
+:1060900018ED3B9AD10F794CE065A97DC7228BE2C0
+:1060A000835BDB3ECEF496AB390A6179AD90D51EA9
+:1060B00088F815C2C7074232E267F334ABF5D61849
+:1060C000E6BFE940FAAA1F12A497D5835529A2BEBC
+:1060D000C3E88FE2DC727F6136BDE367F67EEE8750
+:1060E000AB49DF5F5E9BEB4363DE5F33D3877ED4D8
+:1060F000AB6B2A7D60EBCB9A0B3E3121D0F9A91511
+:10610000B5FE5D88D715B2E9CB16D7BA3AE1F7EC00
+:106110005333190E11FE63F6B90780FE4277BC694E
+:10612000A69FDB3BF192E1ED05076EA7BCAC76E6DE
+:10613000F38807866D3A8F026A7FE1751177BF2178
+:10614000272E1CC17E5F5EF90F7C7F6674817EC541
+:10615000174F7CCE4771D915F91EFE5B5E2D79E095
+:106160004F2C0879CAD7D45E9D33ACFE91F467C832
+:1061700033CB3E8729921CDE7C5C20F99033A93F0B
+:106180008D799AF0B2045CFF73FCAF9790FF353ABB
+:10619000A15F477D017E13D21E73C9CF169B2E8748
+:1061A0001AFF393FD76BE5BC1A8A6FBF7742D071AF
+:1061B000BE425EFD349CAFAC984D386E4B9198C694
+:1061C000B8F79DC5DB555CEF4D251F4E0FF4C57824
+:1061D000BC5FB7B459C8FE43B54B9BFC1C41E6FB02
+:1061E000B57E1E6F69B5966B25B88C07B44A9C7F47
+:1061F000A010B29E3365F4BFD68F7EFB98053CBEDF
+:106200009E20BDBA445D4D79B8F2F8E1E3B59978C6
+:1062100093ED386066BD276D7A2CA9D845FDBE7711
+:10622000E1F0FD3A7879DF10A1D7D627B0BE0A6C2D
+:106230003E0CFF5B4A791E6E4BD9338467C9AC2490
+:106240007DD6A7A54CACB7A56C35D1652BAB93CF4C
+:1062500086CEADEEA2739A5BFEC0E3134FB61F6805
+:1062600046FD614BCFCD807995C1781A507E6C99EF
+:106270007E938A78D8B213A017E958EE22A75CC89B
+:10628000F687873448334B0A426526A05CC8D3F8AA
+:1062900099CA7DF12AC075DB520E06B2667E3AD5E8
+:1062A00088A19F2D711EFF0E969A354508F73891EB
+:1062B000C4800EC90E2CB7D4CA348F368DE303EDDB
+:1062C000AE734E7E17E6C19470BBAB04FDFBAC7F92
+:1062D000E58B7CDEFA8E12F2136DC97DD9447DD731
+:1062E000FA04185381EBB5A427C88C8EB0FF7A2D21
+:1062F000EBBA6F1593DFF2BBE2F7B2A60B48A79992
+:10630000F879CF0757E2BC5B668AB02B8BBEB1D75A
+:10631000CFE3756963F955C559C679CEAF7BF204F1
+:10632000F4F715827BA8FA83F564F2EBA3E1B1845C
+:10633000CDA3A086FB4B21E31C6B0C9264DF8E0582
+:10634000AB11F9D139BF3AA13AF1CB247B4A91156F
+:10635000944F37D4795627CF7375852D9041BFF66A
+:10636000D76CBE371FF401E2EDF2B38FBC80F95257
+:10637000BE0ABF46F955D0F902E66FDEC8D4312C0B
+:10638000DF7C7CBA82F93F2F8F97303706F9278A56
+:1063900074F81688947FF6161C8DCE76D1F9297B79
+:1063A000DF41C98A72A43997CF4B0EB7F54A515CC9
+:1063B00077D9EA73F2F74861E279ED1066EF55CAD2
+:1063C0003E6A24F9D7C1F3859CFCC8CF767AF3875F
+:1063D0003EB7C35BBE09968F41BEB989297469D6A1
+:1063E000EFCDEEBC2F36FE313FD70F3E07A936DC8E
+:1063F0007FDAEDFC9875DF9FAE205DDF3C5B2BC242
+:106400007318CE3C7EEFE776E849C6A7BA8BFFD774
+:10641000C4D2949F9C39BFB7F62CEA4EB2F26BBA45
+:106420009CE276B6779EEDBEDEA598EF656DF3D95A
+:106430007A8337CF71CDEE4A13F3C518F6F47C6F2B
+:106440007B82FF1F3ABCF31D091F99F377F4C1A1AA
+:10645000E6A3EC16B2E6FB85546FBE54B3CAE38DD7
+:1064600066B30C8185E79F8FB6AA5274BED96AF2D3
+:106470006BCD318A4F52FCAF9E110EC6F7CA559DA7
+:10648000FA792F30290D740E21350FF5A33FB7DFB0
+:10649000F92AE7C3BF74BF0B8780779DDAA7207FF7
+:1064A000AE973B6B84E2C1F301019F654E60F8F645
+:1064B000EF5DD63D013CF53A4659EF201E811E4561
+:1064C000BD1A7198FE4EDBFBD6BF3DF12F0AEEDF01
+:1064D0006F3D7E6229CAB95BFE550295D53BFD44EE
+:1064E00004BA69DF492B2897D7EC9168FD41EE9EED
+:1064F0007BB527DFBE99E67FCB5311DA1FD63CE38D
+:106500004FD7B2F66BBEF7DA0C607C7BBAA9FF8579
+:106510000988BFC7059EC760F5CDB89ABD5F23C384
+:10652000F5D9F2106E50395F9DFA416825EEEFC241
+:10653000EE9EEBA8DFAE6B7D7E97FC5DA9727B9A29
+:10654000D533F1BBF54D213D55E0F065CBCB3BF5A7
+:106550004DEE4759B3D797C63CC535BB772A495648
+:106560006FFDEEB789BE173DF56414F1B07EAFF74D
+:106570003CC22D4FFDA1ED92723AEFD45F8BF24FEA
+:106580003A4BE533A6DACFF3E0B93FE656E2585688
+:10659000EF3B6F5EF16BF6FD645C82001329277B95
+:1065A000FF53F9572C27C32926CA58FFBE57DD7C55
+:1065B000B87EF76B74EE481399027B299E87C8F862
+:1065C0009E519FE9B90ACAC3F55D9BDE4679B97E43
+:1065D000CF5BBF42BA5B0FF2AB6E7E3E89FF18778E
+:1065E0007E3C6B93EAF5D39D814373C901B03B3F79
+:1065F000ABBDE8C4B31CFEBEE5C9330FA31E71EAF0
+:1066000099FF7A18EF6758FBC7FF7918F35AE147EB
+:10661000010DE5D6FAC77F1E0517FE1FB5E5C3E9D4
+:106620006F7EE3EB0F303C9CFEA59FB076FAB93746
+:1066300027E13D1DA79FFEDF31A87F6C7C6EF158DE
+:10664000A4B38DDF5D3476B873A048B769BF7B7D96
+:10665000D3FC7E83BD026E8200CFDACF8C7581437E
+:10666000FD0AEABDEF0AD0BF3997BDEFFA8382FA7F
+:10667000CB0B26F4239EF6EF79ED85BB58F92DB6AA
+:106680004EFE2CEBC4E63F41A4FD8DB10F7BDEBA7C
+:10669000E7EAAB2E2BC7A7CFC0EED7433FED1BE7F2
+:1066A000ADEF31B6BEE583EB9BF9FD0C9C5510FFB9
+:1066B000EB9F60EB3903D795ADE78CF3D7F32DFC57
+:1066C000C7FCF3D773BFEAF5C79D81B58F3C801F28
+:1066D000F7E467B56F9DF55CF7DD4F0EAB973BF2C6
+:1066E00061243CD3F95E06D75754F3672AF2ED33A1
+:1066F000DFFAFA0331BECEB50C31A79F3C33090F48
+:106700006BFCD6D77F1DE2A1FF39BF867AD49AE70A
+:106710007E417C77FABB2FD1B91EF61715D87E774C
+:106720001A06FE8E022BDF2AF0C23ABDFF8A5FB145
+:106730007ED7B12E2C83D6EF8A5F95E3FAA9FDB4FC
+:106740001EE965353ACADF7401CDFBD634E78F5BAD
+:10675000D33D2BD09F9D89F748C0C9271C5C57F4B7
+:1067600097DEBAE7C415487F43ADA7337F0DE73FF7
+:106770008F7D7FD4CBBF43F2ABBDBEA777BEA7A0B2
+:106780007ED5FDAF8A26323BFFB4AF5F198FFBCDBC
+:10679000D39286E78D33D77D10FF4D59CF1D673ECD
+:1067A00033E9C31FC81EBF76F03412BF8F3CBF0F42
+:1067B00087BF33F63E9C89C75367B3EF075302DCAC
+:1067C0009EBB153A6B50C5CCDCCF7C90B226140D25
+:1067D000C2DBD625919C3FB59BFB6932E5C5AD4335
+:1067E000D867339D71F6F6CC40B9766ADF0F6CBA84
+:1067F000E4747FEB132714CBDE1FD22EFCAE1FC236
+:10680000DF7DA9DDDFFA67B3F7B7FE89B7B3F677A7
+:106810005236AF45F84FF6FA282FE9649794D5CE53
+:106820009D1AF079F4AEB6C8DC5772583B291AA409
+:10683000BCABE626F317E827B58EFA6C3F80F15B18
+:10684000CCB76A8E04E99C7B73F426BA2FC9E9AFF2
+:1068500025034F723C41F6931C4B94F31858DA63AE
+:10686000C7F81841B8E106D92A44BDFF70D19B3260
+:10687000F67B04F548975D7F4486D6FC723C172171
+:10688000188D90C5BF91D17F628104BADB4FD83D8E
+:106890004EFC3D6BEF3F26A511B5F590EAA67301BE
+:1068A00085D0F55896FE1E6AD0C97E2E4A5C4FFEF2
+:1068B0001F7F2A65A2BE56B8512B16F5A1C79D9819
+:1068C000F2C6AFC733CAFF3D8E73D047FA20EC7EC5
+:1068D000FCF1C7C7F02D05F5F217F0C9E4DFE57547
+:1068E0007A21961FB2E7CD7880CE314EB41232CAEB
+:1068F0003921B64C46FD62712A21AF76ADE7E298A8
+:10690000301EF7D3F410F7407D3FC0F7CFC6C66BFB
+:10691000288FFDC12F8A44D70F063E5E887C7620E3
+:10692000775E18FD6B3DEBE61E9AC6E09C10960064
+:106930004DCEFDE1E1CF6D3E6CFB1776D9F70F3DF3
+:106940006AE7977FDDC6DBEE86527A3EDE60D0F7DF
+:10695000271A2AA8DCD55043CF671A12F43E7A577B
+:106960003089F4B9A76125BD9F006F0BB8FEDF6BBE
+:106970004852F9D1402EC13FF96E1093ECFD62C42C
+:10698000477870DE0E3C69DBEEFE7EE0C72DC8174F
+:106990000378CCC0F7E5D02BA8E8BF8A093AAE7BD4
+:1069A0007D40E779AE19F89DE4EF17302E577F3719
+:1069B000CF877858F09E77B8DF96FFDFB1F9F4DD26
+:1069C00068F2C9007BBE53B3A294F421D0CA906E82
+:1069D0001E1612478C22C2B3E7DCC9FABCE4770268
+:1069E0002EFFF0A40E6ED7EF08D8F26D2388486F03
+:1069F0001353A023BD39F3DE57A917A25CDC270887
+:106A0000B4DE486FA52E7A1BA0DF809D971CCFBEF9
+:106A10008F0FD22FE7FFF825A5F754235E3688E4C1
+:106A20000769C64FAE761FD874C4EC16D1427AAE51
+:106A300013C99F3BF9F8096112834FD7BE15C07B7C
+:106A4000BBE293C0F637750590BE1EACE3FEC5AF42
+:106A50001DE7E798CE6C2C5E368DD55FCAF083C1FA
+:106A6000A8BC25251EBFA5737EE16B6A22471BC605
+:106A7000BF9599F776FFE42FBD9FC3C699703CA4DC
+:106A8000E379987B26FFA84761E5F17D02F993C67B
+:106A90008753D3703D2BFFDF37C7F5B9D6E181753A
+:106AA000A9C9A837B64DFEB6807C30FEEC8F05DC58
+:106AB000474AB4E49BB83E1364FB9CB09C9A87762B
+:106AC000C1F57989DFE1FB4461FA53484F676A36C3
+:106AD000FE1BF6EFC421EBEBF5DC692EF990799EF5
+:106AE000E2A1D4F0FE4C67FE0FE1FC87A9E7CCDF02
+:106AF00059BF3335B1B5281733F199D96FDE9215E7
+:106B0000C38EFF907D8F189BBF3FE8926B85A93E97
+:106B100019DB39ED878ABB66CE77C04F34CA386D32
+:106B2000970FF2912E9EFEBF49DF3902483A0909BC
+:106B3000FD53FB02C97108CF5C4851994947CA67A8
+:106B4000377239FF3E30E6EBE388EFE47411E57D00
+:106B50008C72BC5648242A719F334423DB3E303D5F
+:106B6000C8E97E01A4C83F2A86EE1E3ECE5FE88DAE
+:106B7000F36F059A0458DDAA1DFF0059437FD841E1
+:106B800098857EC8FC20E7F74A99DB97B30FEA3B6C
+:106B900025EEB79296455CF8B3FD763EDE3583FB75
+:106BA0006ED0743CF735B34770F1EB7BA1E4C220A3
+:106BB000ABAFC4B93FD2174BD279CBC55258247F63
+:106BC0006E2797FFF590502FE47119C079EB1017DD
+:106BD00071BF7F68233FDFAE6B2182FBA1984EE53A
+:106BE0007A5B4FF9B14D473FB0E5FEF76D7AF92E6C
+:106BF000CA7DA49B3EF3400E83EB3BB6FC7FDA9646
+:106C0000FF4FD9F27FCEB13EF86639C96303F39ED8
+:106C1000BFBC3DDE84D37CB2C1A47ABB1AEAE8B91A
+:106C20003F77ACB897D57B74A3B80BF9F9516DECED
+:106C30009578DF55DA140D81357EC8DABE28CAE0B2
+:106C4000DFA90A143F7BB82145ED76AA7A938AF131
+:106C500014662D5B4806F5BD14F6A8FC6DBF56C33F
+:106C6000EA7DAD33EF4A8CC3DD5B23533B878FF462
+:106C7000391BB03944F3FC4164ABBC826E750ADA4F
+:106C8000E91B45EAE72B81CFA88BD873E2C4A3EABE
+:106C9000C7755C8C13668A7D5FC4908CF3A8E8EBA3
+:106CA000B3B05CF27A98F2B5E7BED2074FB3725137
+:106CB0005D84CA132D2F5F4CDFD367753238269E53
+:106CC000E2DFABF37E6775B1FA391BA2D45FD5EB77
+:106CD0007D02D2B3AFDC7BFE6A87EF97FB236CFCAF
+:106CE000D8A1848078DB27688B3025C4FA143F7FD5
+:106CF00033F62054E1FB787409ADC3F66011D1CFAF
+:106D0000D75A8EC66F463C6D8CB5A099B37FE3060B
+:106D10003A9FE0DFB891EB4129EEFF9E78C701E191
+:106D2000732EF950D82267F5DB6D0FFA799C64E376
+:106D30008AC4340EDE8130EA7B25DC5F59D45AEDFB
+:106D4000C96B72E2231F08C9ED41B29B789C44D6FF
+:106D500052F4FE32097545F6FA4E91EB4989DE8010
+:106D6000DB0FA3DFC1EF67CB8463575026385AACE3
+:106D7000EA3A9417DBE6287200E19866DFCF62C733
+:106D80002107F63121B9CB2DD7648DC33591A132BE
+:106D9000847077F77EAA8BF5F37ECAD9C7CC20E939
+:106DA00049F788C41F5BCBF939C0FDC63BDD78CFFE
+:106DB00085C34FAD8648FCBB5D16D202EB677B797D
+:106DC00071EE85483F31DCBD69BE2AE2B944F6F177
+:106DD0001C0E30F7A15FDC8F7E71B6DE25C743271E
+:106DE00044F2FF79F3BF8B2CEFFA8BF5DE73771348
+:106DF00099D2E3CE57064634037446FB6BF5BEFFCB
+:106E0000407E5819223A03CB8C568EC1F445FB4F75
+:106E1000AAA5F3CF2519E70C1EB0EDF787ED738413
+:106E200070F63640B9F5807DFEFA81B5625067781C
+:106E300079DE3A4AFBE6C4FAEE4A0ACC687E4F7E17
+:106E4000B5FF6EAD09F7D7A294374FA832232FA80C
+:106E5000E4CFCCB33E1EF4DAA9FB4E060DBC0F2FD7
+:106E60007D4C32509FFDF25DB349FE596BB8DE9206
+:106E7000AECB7B00CFBBE40B60E07BA75FC77E7D22
+:106E80002798477C939ECFBEE730B912E95A5287C4
+:106E9000EB05395A530CCF43DF09DFC6FEEBF8FA96
+:106EA000571602DDAF5318033AE7CC9E9B2F40FEE6
+:106EB000DF28624C1CCEA19C4739AEF6BE88EF732A
+:106EC000AF14E9FE9CA216EB429CE7BE4BC68F476F
+:106ED000FAD81AE6E75E9A851468086F01E7879D7D
+:106EE000916ECA07DD562342135214C3A581FDAC2F
+:106EF0000EEEA23C1684770ED11DE95D18A3407EEC
+:106F0000B46E08F27DE7AC7521FA95A3A1BEAEFD83
+:106F1000AC9F70BB62EC62FDECACF4DE533735C461
+:106F2000F7BB404870E2FB81107B9A5B81F216D977
+:106F30005C88BF195F5940FB8246769513DF8FEE60
+:106F40005B22164DE7CF6217FFEEB2E56CDACE5B3F
+:106F500078D8DE3F1C7DE301DB6ED86AEF1B45E687
+:106F6000554D0AD26D1DCC443C95ACED125667B31D
+:106F7000EF3BBC7235935F2667F24BCA7B4E75427E
+:106F80005DB1E77BC4B8C8F39D4231B8EE6CFF46F3
+:106F90003CB707CA24D4FB6643C274CB95A1F6FF65
+:106FA000FCA03923F421F49F68289142FD3353FF5C
+:106FB000BED45E97EB0289F9B81ED14B56521ECF54
+:106FC000BA40E252EA5F4E0B284F1760BB58567822
+:106FD00029F96B14F0567F18784136E83CD79D921A
+:106FE000739FADF73C1764DC5F9B793FEDC2FFBB3D
+:106FF0009BEEA76D1598A287E51CFB7E5A3FBF9FAD
+:10700000B635C2EDAE563B8FEA561B0FD787F87DDB
+:10701000AF6B6D3A5D18CA7EFF91E3F74AA16CC071
+:107020007A63B3DF3B861A15F6B77042F6EFA91004
+:107030008F3B2E9C3CFC381B701CD6CFDCA0B92E9D
+:10704000E4F2AFCC0E99EBDDE5DB43767E919C203C
+:10705000BDD294F97E5814343786E6B8F06B3FF30E
+:107060009694D379BE33F6793ED66E87407895B440
+:10707000D1E0DDD1FF5B05FD1E92833F677A5F960D
+:10708000F5782F18B5C49CC17894A31FED0E717BC1
+:1070900092D1DB263E8F34E5418741BF07EF8198CF
+:1070A00080F770EBE85738FEF0BFA0BCBDACB70668
+:1070B000F5A7753F94E87EBBF3F0B596D19D2B1FE5
+:1070C000C5793FFEFD0964074F9692F7875CF6F19C
+:1070D000F8BA7E05E91DE1AFE6F0F3FC69217D21F8
+:1070E000B70780E238AD37C73DF98499F6481EDE10
+:1070F0007340724521BD2E132EC79E70CA99E711A9
+:107100000EDB74847FFA18BC271CB8322B9B12F25A
+:10711000D71C48D2731EE8F464764B17CE83F19FD8
+:107120008E703685265D8AF3F82BE2ED47A1397F14
+:107130007B7873E8B82879F9001D67BBFFFAFE5029
+:1071400094E46DFDF108E9FDD17D5F20BA96185DEC
+:10715000076283F932F560E7D187A10BF5DEA264FF
+:10716000039D0B3DC3E818FB95347E8E55062D819B
+:10717000711B29C6F9C327976AA2867159CB8F79EB
+:1071800007563118286BD11FE986B73C9C7CD38DFC
+:10719000C73B8FDF43F2F6BA40F224AEE79D259657
+:1071A0001F353B971C3EE596C3028475E4BF856797
+:1071B000F97E5999D465A487458CD311EF8B214969
+:1071C000E58F8345CF2590A6E7DFE19546A4C7D993
+:1071D000E716BAAF15DDE71606F2B9CB9D7C0E1E99
+:1071E000A72AB0E9106C3BF5F995CB1B17B3F1D981
+:1071F000E29B188FFAEA4A9ECFE39F27D3F9D58204
+:10720000BE1B6A314E042BB85EE6E441E4D57AF544
+:10721000B4F3EEB73AFEBBE3D82EF39C9CA3AF6564
+:10722000EE5BCE33535FCB0B673F3F39D4BE931930
+:1072300057A8C77F72FBD5B6AB1339EE7BE3339FFC
+:10724000871BFA5B0EB8F2CC8FE0FD4659F7011EA2
+:10725000EF8DEEFB5DED8A72BA5FCEC094C9DE861B
+:10726000EE85AF4F1DB483130B729F477F74A23A14
+:107270007796C4F0BE34FE6ECB817C806566CFC24B
+:10728000D75DF3ECD518B459F48481F14CDF07EEE7
+:10729000FDF72D85CB97567BBC881D1F6B172D3FA7
+:1072A000F1ABED7FFB7D21B7D31DFB3EDB7C5B08A3
+:1072B0005F7D61A487A1E6FB0F61BE9F8E5969D0F7
+:1072C0007DF9CDF67DF9CD139DFC2D43437DF2A6CE
+:1072D000702EBFAF205C42F1D5E69EF9E44F2E3808
+:1072E000E4237FFA981549C172ED8BF73670FFEBF6
+:1072F00057987E87F9205B985E87E57D957355B436
+:10730000176E8FCCA278EDE606C3932FE23CF13ED8
+:10731000BAA4CBBFD79CA8D230DEDB523B4B45BBD7
+:1073200043FA443995E50B677556317EFECCD61984
+:107330005714605CA28CDF47763D2B3796303B3A82
+:10734000CCF7D9C3C6EB61C453555877E887D6D17B
+:10735000B72269FA502EC4B52ACC9571DE834D5FF1
+:10736000EC3DE9D76F29C99BC36CFE87ED7BB1DA91
+:107370009554E986323C17CF040EFA8955EE27441E
+:107380003A68993D08F7061BBF97D8E33281243E3F
+:10739000ED5A3F25CED7AF5D84BA6CEB737798EB8F
+:1073A000372D9AA90D4B479AFC81E7FED0F218CFF2
+:1073B000CF8F313A72F1F3F9F4CEF9A93C9C680908
+:1073C00017A05C84D214CD3F4CF287DA4983F7587A
+:1073D000C6C36607D63B9A6BEB2F853C0F9ABDDF81
+:1073E0009243F34B917C77F4C17699EB73A3D50765
+:1073F000F3966C247DF01DC65A649F7D6223C9ED0F
+:107400008D3E95EEFFDBB740A67856740A5CEFB66A
+:107410005BA4887DFF7F84FBE5F17712D2D3B8DED1
+:1074200083E73CA221A0732EFD13797E693BECAC6F
+:107430009942F04DD5DCFB59E544EE67D85615ACC2
+:1074400073FB1B16E6F278D98BB995BFC3F9978504
+:10745000D355C89A176BD087F93450C5CF8F09859B
+:10746000FC9C8D0F0C95F36BB586F7860A90A4F300
+:107470006743AE1F78EF177D5C4E3705116F31EE15
+:10748000D789EC1028694FEA32BBF1EC4E7BEEF263
+:107490001F223D32B967207FF7CC0D92BDF76E8F6A
+:1074A00042F6E7BB37C3AFD19FF4AE2F072CB654DB
+:1074B0003F12C55F3FC5E6DBCF987517E67F69FCD5
+:1074C000FBCCAD02F99B7EF4417002D2BB110511D9
+:1074D0007FCF6229D32778922084303E1B5D04DD64
+:1074E0009763FB9E30E1CF17FFC9C2D767D3FE1366
+:1074F000122BF0BC96F820CEFF9938E461FBD9FF3F
+:107500005B25A1FFCAD187BEAA258F22DEE6815561
+:10751000D7C3DA6F53387F6DCB53D218A79C552051
+:10752000921E02BE507A2AFBBEF4E0EBD598DFB97A
+:10753000B46226D6C4F169BD4BB4E4719C77B5B68C
+:10754000AC3A97D52F3FA693FCBD227EDB012CCF12
+:107550003DCECB3E3FD7E3518F719F0F58FAFE24AB
+:107560009AD79B61AECFB6C4CD5E531896AF32EEBC
+:10757000E5F59E2F70E8806DEB3AE6A5D3BF75A2C6
+:107580008BA44F1CF43F4185619F3F71E8C1143EBD
+:107590000C3DEC09F37DA11DF3CD6283F966EDB6D8
+:1075A000FE36DA7CB34C7ECA5B22D33ABCC3F42DE0
+:1075B000BCCFE37C3EB98DEEFFCCE42707CECDE512
+:1075C000793194C30EDF68F3EE26B9ECBF41A1FB1D
+:1075D0004C1D3E72F8E7D29C013EBA0FE5C58AB059
+:1075E000BE98A76898E0E693AB47E0ABA5D07F20B4
+:1075F000C6CA4B65B07298083A3CFFB725935C7CCD
+:107600009289CFA50B0478D5230779D9856F6DE0D2
+:107610001EE02C76F250EB7254E6E71E1C3EC5DFEE
+:1076200063C1F3631DA201B81FB5E7AE36226CDD5E
+:10763000E4DADCB5C80F5B84440AF92132EF54E880
+:107640002686F777C7302D12FD87FAEAA788DF5F15
+:1076500009915DB66DEE1A8A4BBD7B737232EE2FC7
+:107660009B18DE5FA5FD3C3D56A45CDBBEB13C6FC4
+:10767000428FF36732CEDF83FD3D6D974DBB5E1FBA
+:10768000D563EBEB919B3F8D723EF86994EF539B72
+:10769000944E15E9A1BF48D5B2E52BA722BCFEE563
+:1076A0007E28C7FB18D968941FD0AA4A353BC95910
+:1076B000C2E5C4E5534A77B9CF5739EDEE6DE822FC
+:1076C000BD6653C35E7AE6D7A601F3E882A5968E1F
+:1076D000FA87FAC74502EEC770118FCBE3FB4697D6
+:1076E0005EF7695BBEAB785F101B4F6DB274F7FD40
+:1076F000B4AA2864BD47E84894FB89D526A0EFEAE0
+:10770000BE7FA6FC85FC1243F82C969B3AE9F765F0
+:1077100002DDFC7DACC4146E74F51BABEDF2ECA382
+:10772000AAD82793DD540F9A8546A0DC578DFEB961
+:107730008EE5C14ECC6BCEA437FC7BD54537EA1F16
+:10774000AF26FD098E72FDB5BA58253A6FAD577652
+:10775000A2FFEFF7B12ACA67EF88089EFC02E7890B
+:10776000F177A611923FCDF2F338BC358DC7E1B168
+:107770008C71787C621C1E9F1887C7EF1887C7F230
+:10778000B71B4C2A633C1ECB188FC732C6E1B18CA5
+:10779000F1777CEE6DA8A3E70F1B52F4FDD9867A32
+:1077A0002A5F6ECB5728E5BF07D6F105C5C4FCA9F3
+:1077B0006E7B7DF69BCBEB7E86FE42881AB8AF07C8
+:1077C0000E35BDF2EF7699EEC98E17E7A3FF126270
+:1077D0002260DCA12DBE9DE9A283F30BC8F7824E87
+:1077E0007177AB0EF31EBFB1ADF70A99E91F25F112
+:1077F000DBAAF258F9C96D2FB7619EE9057AE3CA91
+:107800009DAEB21E99B5E6696DB03CB96CA71C641B
+:10781000DF9F89FCB20DE54520C6F5C367B7FD9A29
+:10782000F4C3EE62A600A1BC2B52D248EF37E23A75
+:107830004DC579F07CEEBF83E638E6F94DD6955913
+:10784000C8A7AC7E37E78F51D6C760CD9CF3DB0D60
+:10785000574F2C1F553D3AA73B643DF65D18A69F38
+:107860005668D67A19EC5B7C7C1FB60AB89FB8C301
+:10787000C7E54347803FA7E438F90D55CDD102CC89
+:10788000FBE17CDC11E0F713F44F17E9777BA05E96
+:10789000F87BECE7F3E341C3FCC859D38BF3D14E3B
+:1078A000F8854D0F532747F8FEFE8F2AEDEF1F9FF7
+:1078B000FC644B1E2B4FFD17C3C0FD7A0B1841947F
+:1078C00027D6562E4FBE553E256F19AB7EF19CEF45
+:1078D000E6A17E3CCF964F69DB8E696CBD6932DADA
+:1078E00011EFBEC4E5E31BB67CD9E9EB4DD17ACEEE
+:1078F00009D3790B804ED25F1AE332E58989E3F828
+:1079000053F1699FA6FB335B15BAAF49F9C33C95A8
+:10791000FCAEEFFBEDFB8A7B49AF5102492D97BDD1
+:10792000EFB444F253346BC134DE9BB5253C8B7EFF
+:10793000BFC12A93296EB6A58CC77F42916BE85EC2
+:10794000ACAFF404A87E6B58A57CE174D99E835536
+:10795000317C8A1AEA07697339DD636969A246795D
+:10796000C7EC5FF47D6D8CFC4174FE18BFAFE5F190
+:107970000ADFD843546EFEA446FD839DDF4F2A9A4A
+:1079800088BF2791E8F1DE4BDBFF938FA1BF640D29
+:107990003FBF32435BDEF31CFBDE62AA8962C60F87
+:1079A000ADDA3BFB42585E05144F0D4D7FBD298477
+:1079B000F56FD40C9EAFC5CF4B807D0F724BD98A2B
+:1079C0009EFFC0FE578660AA81F5AB55E4576881DB
+:1079D00017F0DEAA428288BDCF9D25A0DED65A4B85
+:1079E000D77332F8BCE70C5AF2AE54916EA4A57965
+:1079F000344E2B982AD6B76A65DA3F0BC36A37FA3A
+:107A0000170A6DFF84230FF253AEF306EC7FE3D722
+:107A1000CA9EF308636FF4960B32EEE12DB7E927A7
+:107A2000136F99F3CC8F3D938BF0E4AFA59313E7DD
+:107A3000C17F6F6CD6329CD7386D9FB0B39C4C1F02
+:107A40004DC77BC821D5E8CED7F873E19D51D6D27A
+:107A50008BF4304397416778F918F43761FF5B6C1A
+:107A6000FAEF28F2EEE3BFB0ED1FC6A76BA37330A9
+:107A7000EE2182E5EA1FE322960B9E291D799EF2F4
+:107A8000D4CEF19EFAD376147BBE5F98BEC8F3FDC8
+:107A9000E2DDB33CE5E95D9778EA7F6C6F95A73C42
+:107AA000B3FB4A4FFDD907977BCA737A3FEDA93FD5
+:107AB000EF95D59EEFF3FBD678BE5FFADB0D9EF215
+:107AC00065FD7779EA3BFA7FE6BE795394CBA30F45
+:107AD000ABF7E3EF03B9CF1D67DA15E7DDAFF3C707
+:107AE000661DE38410E5F7E9CAB8BFB3F2862F70CC
+:107AF000FB4C5D68E8286F5645B97C5D9F67DE8E5C
+:107B0000F2B532AAD23E2187793D397C05E923932B
+:107B1000763039359BECB681EF18AFEE68B016962B
+:107B2000B8FC5A01AD13304FAC325A43F70A3AED64
+:107B300065CD04CC9F5B15D5B91EC4AC5EBA2F4091
+:107B400067ED5DF36276225D31D1CFEC48D4FF075B
+:107B5000EC443987E2C3CC4E243BD20872BB11CE31
+:107B60004AF4DDF88A40F7F8333B90ECC867C2CCA2
+:107B70008E9C89765BDF169443FD3F9529DEC8FE17
+:107B8000C84E2C6776E2E65CB7BFBCAF089F69D0F1
+:107B9000C6E3B347E916C71691DDF8CF48CF9FD9A2
+:107BA000F8521DF63BBD9CDFBFD731A6368EFA7466
+:107BB000475117F1497F91CCF7213951EAF6031E5D
+:107BC000B0F7AB90FA2DB257D93A905C76D6618B6C
+:107BD000D097C67B0EAD2F04C92F3EE937FEA3C850
+:107BE0006F6AB13A01F3048DFD8A89E3DD6BE3B975
+:107BF000589B59853F0759125FB60F9F17E84C1FD6
+:107C000061CFD2D27BF6E1F37B51327AE122E3E914
+:107C10002A9431EA42EEDF966728E92601FDD20C6C
+:107C20008E2CF689F394A23BF8BD4025F21B487FC9
+:107C3000681D9C6353A8CC5329BE1C40BA10E84968
+:107C4000F4149043B4BF04F0B02A962B843486C455
+:107C5000507FC5BCD1CABC1D44078E5E8BFA6E92A4
+:107C6000DBD10790DE62B5DEF50FA9DF263CB5D883
+:107C7000E7A23B72F543556CDC8E82E23CF4EDA248
+:107C8000DF65994BFE1CB4F7DD477344474F20F97D
+:107C9000B30073190A06F522C60F3BC429086F8288
+:107CA000E2F0814312D9FD81BB3BE97758039AA5E5
+:107CB00003E9FF968EFD5617AF243FE1FFC466919E
+:107CC0001E1CA8FF5156BC05FA2430670F8DCFE863
+:107CD000050F903E0063823AEEB3F5B1A0B9338B45
+:107CE0007D5017B1ED9F498EDF3341E7625BD12FA5
+:107CF00017C6AD4D15319FE7F69F1678EC9ADB0B52
+:107D0000B81F73A8F103CC1E4DBAE0DBC4FA4539A5
+:107D1000DE7A76590DDDBB8ADB4C399E1B2DDB49A3
+:107D2000FEFCB3CD3AE67DD5D9784D61320FC3DF85
+:107D3000240516ED447992C7F42386D24ADBFFE28C
+:107D4000F86926E6F0F8BF6181C4FD773E67DF126F
+:107D5000CFE17D353AE8CA5CFB2A005281F9BEC604
+:107D6000FEAF07CF0F4EE970ED7380FB81B73C6D1E
+:107D700087B77C61DA5B665AF4CBA807AC00E0FEFB
+:107D80008FDDDEEF61307D186F19EFDCB39FE0E728
+:107D900009550601D2775957BAE76B6C7E09E73E61
+:107DA000CC8C7BF5A7EF4993FE7295FDBB1F99F72D
+:107DB000BD8FC7DF019941F3F2ECA3B37C12F92523
+:107DC000D09F64B8FC49259AEEB1AB1CBF50A65CAD
+:107DD0000F1EBF07D817B2EB937EBC37552B43FF5E
+:107DE000435BE1977E73A27CD00FD326A7DE3C4194
+:107DF0007E4EA67FC5B89F04FDD7B7FFF48EFF3E29
+:107E0000E1F267BE1B4DCE46BFC7FD93797BE75EAF
+:107E100055E7DCDF3B35F2F382CEE148BAE0B8B398
+:107E2000D4FA385757D2E3D08FE4F8611C7FC3F5FA
+:107E30007926E9E75B8CA3A9FDACDFAA5FFA01FB19
+:107E4000592C1D3AD880F26EA24C7925DABCB58F38
+:107E500004D1EF89DF59B9AA481F4BFCF1A28FFC6E
+:107E60000EED36DF3BE7571DBF4D2287F347AD6D63
+:107E70000FB09906ED731B41D4932FDECDD6D0B34E
+:107E80001F72BFA1E31F9CDEE5FD7E111E0527FFCB
+:107E9000E84ECA8332E6F33CA8312BD3FB709D3FFA
+:107EA00066AF33C6B72AE70EC659C7AE4AEF433DA1
+:107EB00074869DCF54F6E2F3F493BF20154A485FD1
+:107EC00017611E136B671C903DE746C68040F94062
+:107ED000638E49469AF533E359EFF73270958B106C
+:107EE0003E6F39337EC5D4ADB76F10F0F7535302F0
+:107EF000CAB3ADAB988DC0CAEB72EC3CA40BE002E8
+:107F0000A4DBC552D8C0FBF536FC5CA23C64FF89FB
+:107F100069BFC0382ABCC4F32EB5293C2EABFD4442
+:107F2000329804042D0433678607E35D5F3D67E004
+:107F30005DFB037EB4C7D9BAE33EF404B3FB4B7CCC
+:107F400068C76B54EE62763F969F61763F3EF7308E
+:107F5000BB1FDF7F8FD9FD58DECBEC7E7CFE90D936
+:107F6000FDF8FE5966F763F9C5DCCA2D397330BEDA
+:107F7000554AF4149CB987F21EDB559F86F4932969
+:107F8000CF2A2B6F575730FC6E0E2FA6784BD56239
+:107F90009E77BF256731D9D303FEBC0C7FE8A07F55
+:107FA000AF4F70FC7B78043A6EDBB3037ED2A44102
+:107FB000F71B8CDC8FE9F4437ED6F3FAB1FDAD6F8D
+:107FC0007DE1575F6F669FD6CDD9DE112CC6733F1A
+:107FD00029FEDDCE3FCCFCDDAD757B1A291F501983
+:107FE000772C85EBBAA73C4CFA06FE2E13CAED4C53
+:107FF0003BD1B10F33F571E799B91F66E6CB446CFD
+:10800000BD64A4FC8D6DBE14C5B7AD46265F70BFC0
+:1080100068482F7CDD77BE7F77B29697714E99E7DF
+:1080200067F90FF2BCBD0E486AEEF93BE723C8E6DC
+:108030002BE67E46B77F375892A6FB1B826193F4EE
+:108040004581E991A4576A498A17B60DF1FBDAA771
+:108050006C39D138EE1ADAEFDB5EF491BE556DE77C
+:10806000C9358F53A9DC3C6E6E9CF22B2373D5BEB1
+:108070002CFD6C88140FBBBF4A6CFFD787D9FF2536
+:108080003F3F17D6BC6FBE8AE7A73AC2AB7BD16E23
+:10809000EF88C7284ED0336EAEE77E72295E41F777
+:1080A000594861AE674B7195F46C19E75F3658DF3C
+:1080B000A9773087D30F6373F26306C29D54CF2F25
+:1080C000274CF4B7F8633C0FD9AFF1B862B0440461
+:1080D00035CB798D1EDB2FDE5196D4D0AFD31197DF
+:1080E000E9DC47873E6BA8B82CBFEF42F3FA079B49
+:1080F0006DBF43739D427A61A23E57ABCEA7730B0F
+:108100006790CF3BC24D2AC669FF3F82909C4F00CB
+:10811000800000001F8B080000000000000BCD7DD8
+:108120000B7C14D5B9F8999DD9577637996437C91E
+:10813000E6C90402060DB8818487C6380991A222D7
+:108140002E0235B4B42C0414E415D1B6ABD5B2214B
+:10815000098F2025581F282DDD50B02FBD8D96DEAC
+:1081600052ABFD6F04B9A8A8A97A15FDA146B43E8B
+:10817000EECF6A04BDC547FFFCBFEF3B33C9CE64F9
+:108180003604B5F77FB1653833E7F19DEF7CEFF347
+:108190009DB38EBCCA60CCC758CB3FC5862E2F3C42
+:1081A0008B18EB8127934219AC9C318F2C3096CDE4
+:1081B000D869FC73317CEF76ABAC129ECB1C717727
+:1081C0000963E168454EFD44C6166685990CF51CA9
+:1081D000BEC5720CDADB1953B13FBD9DFE0C627F48
+:1081E000558C89F26F6BDEF20FFEAE3FC5F41D2C8D
+:1081F0008270944A6FF7BA18B3294C386D8332F302
+:10820000CA6F9FC7E8CF6911FFEE09867DA9FBF110
+:10821000B9FEADE6AD8983DBAD2AEF75880A639BB5
+:10822000F7748419943F131482CBCE626A01CC6B2D
+:10823000F5FEEB5904E6BF55EA71C900C7D62F8495
+:1082400085E1F2C1FD2FD3F003088B219CF0C776A6
+:10825000FA7CF85B618A63126305F866243EF9775D
+:1082600018A5FB34F45F91807299060FFC7FE261E0
+:1082700063B9AAC7589E7CD458662C640F8F63ECF0
+:108280008575D0E9398CCD39F6DE3196CED8DC58FB
+:10829000E8F147038CE5ABAE705C666C1E0B3DFEEF
+:1082A0002A940B1A3C2C1182C16D6C19AE0B4CF345
+:1082B000A55280AF8111ACAC60591A63AE81FEBF8C
+:1082C0002B67123E1A7A17CD64E319FBF1CD2D8C82
+:1082D000413FB13A21BE17E09F5DBF67F62878DEC7
+:1082E0005B692BBA0F1B45EC6FE1FC5CD0D9699838
+:1082F0006FA6EDFA1123A17E789A4768817A3FBE76
+:10830000E0DCCDA550EE993E3A8478077CBDD53FA0
+:108310001FC0FFBC306FAF8FFF6CE589B9A3E0B918
+:10832000B3F2A1D9F89C935C1FFA9B35A5B3D90190
+:10833000FD5DB9529980FD85EB8DED0BAA8D6580B1
+:108340009CD609E7EBCF1A0CEF99E0318FAFF777A6
+:10835000EF3A85F0CFBE007A007C86F113B40F4B64
+:108360007D5208F09C5F2DA871A09B0255503B2DBB
+:10837000F8619B463F66FC8BB10C867C56374F8C70
+:10838000B743957C979DF09F3F53882B307EFEB27C
+:10839000BEC469287FD3658F8BF03D2BB34BC0EFF4
+:1083A000F7AE64ACA384C04BAF4D5ADF7B5D6DF676
+:1083B00062F83E2F4F6436A003563D8AC6233846E6
+:1083C000123E8E737CB8081F052B438FFF0CC6BF6F
+:1083D0007A8A5316A1FED50DFCBB0EDF5609E80CB8
+:1083E000BE6F053A8B119D49C793F133E7D8AA5563
+:1083F000488F734CEFC7CA8CE8EAEF538F8E29067B
+:10840000B856091D333C008ADBDEC4182E346010D8
+:10841000E95AE7471D4FABF635133F26F199FD3476
+:10842000F233FE3B8750437CF698EBF732CA8DBFA0
+:1084300064F6EE6440C2BF9059ACBE9AB1FF93D6C9
+:10844000779E00E5DF74346CDA74117C77F7FD9663
+:108450005530E6DCF89D19338A06CA69EDCB67CC46
+:10846000B808FBE3E3C014627CBDFBC725FAE893C0
+:10847000397C5B54B65D84B26493B7874A06DA658B
+:10848000613B61887661B65DB268E7D5DB019E36F7
+:10849000C0FAA569F34AD3BEDB347892C797106F50
+:1084A000B2E215603DA4E9928CF4F255E1C839D3EB
+:1084B000BC236CBB7DD4E0760076B30EBFCD1AFE34
+:1084C000387E4F1EDF3E04FC5F373ECED49F43FB19
+:1084D0007ED6F041F5F539A9E78B70D9515F298A2D
+:1084E000D796D4CFB6EE4F9F3A1F88579ACF426E99
+:1084F000E843B2AB7208E8BC5CBEC3859D4B99F5FE
+:108500007204F86133945578BFB9ABC3A5C0FBF2D0
+:10851000D2DB3721D19727D218CA83714CCEBC1F2A
+:10852000FA1D274B2C81AB76D1419B07CAEC0A166A
+:108530001A0DFD6674A7913CC92CB9E017028C9BFB
+:1085400099E952B1BD2773D22F18D10753A4247CC7
+:10855000786A5FA8F3205CB35908595112E2AC164F
+:10856000996C2C637BA19C79C91E560FE5097FF796
+:108570002922F2B4C4F55D3BB6473DDDCA0EA17EAB
+:10858000C9D3E4CF2687BC9DF4C7751243FDE1191A
+:10859000778780F0DC0B5D89C097E5E559B3EBA1E7
+:1085A0005C7EC41652149C4F87508CF3098AA4B782
+:1085B000747CEA7264C24709CEF463597C2FC0DF31
+:1085C0006A8F27505EC5A65E2DEF0578F29724C905
+:1085D0006BFCAB0F7080F03E7DD5DEF612A46FE928
+:1085E000ADE4FE323E8A27509EB1DA8630B60FCC1B
+:1085F000940CF23F4D936769263DD09A65273AD196
+:10860000F50153254586790BDABCD98FC2A40F9C9E
+:108610002CE47290BDB280EC1081F50AA73D307F4A
+:10862000AC887017F1790C6A3F89B767C1900BED80
+:108630001C675A5313D6878F59CD805CE1BA341525
+:10864000F5B3E060AEBC09306F1B8B74019D340B39
+:108650004CC2F2C0780986E3395D9E56B4BB1E73E6
+:10866000B5D8107F2D87417FC03C36DA19B7FFE4BB
+:10867000902B0BDA4735FB6D6DC5C85C2C67E4E8C1
+:1086800076615846BA5C9B5D9A8BF661BABFF7DBA0
+:108690002867676EFFE30C17CAD53AA87301E89DF7
+:1086A000CC8736C540EE3A4F153025C9CE734A4DBA
+:1086B0000CED29E7A962C3FBC43A98D1390365D50B
+:1086C0006BABC771D6642A84D75A26B762BB5A40AF
+:1086D0008692B42ECE53794C9968D57FA1E17D0264
+:1086E000EC24C5399CFE3D4C294BEE7F548AFEC7D5
+:1086F00098FA972DFB1FE8D76FE8B74D626447C71C
+:10870000025E5A77B35DB031B3EEC64CB4479DAC50
+:10871000A9CBC2EEDC906923BADB186CEA51A17DCB
+:108720001D03C6073AB9F88BE322237B06560AE8F5
+:1087300085154A7DFD743C12EB71FAB5C50486724D
+:10874000E962C96EE0931A662C9BEDA27361AD11CC
+:108750005F365F650FD2CFDAEC34C56901BFFEEC3E
+:1087600059C76A4A47C37CD3C2CB18F0F1CFB71FB1
+:1087700076B505A19CCEE9E481EDAFCE88C1FC7A47
+:10878000044E7F6D011BE1255C97DB2926F51B76E6
+:10879000B0D12817C348DF5E0E0F8EDF935DB8BBE4
+:1087A000DD627C10BB06FB61B62AD49426CDAB47B4
+:1087B000B383FBC79B56D0897CD03F9E9355D1781D
+:1087C00022E03F79BC9C2F37DE5F717EE503E3CD6D
+:1087D0009E6E9CDF6C874CF39BADF1AF3EDE5F710C
+:1087E0007E255F623C9C5FF278DF30CE6FB653A689
+:1087F000F9CD16397DF58F97F3E5C6EB59574676D7
+:10880000F04607C827A093B48A7DAE5130EE469754
+:108810005D16948176B5B537B8E6A2EEF54E9B9E0F
+:108820000DE3D45D0295F3B19769D36B4B19DB2E41
+:1088300070BAE8CBFCAF4DE8479E9CB9B68CF48982
+:10884000665F5F8955411F5F29717867157AE3CDAF
+:108850004978BC17E4880A70FC14F85D057EDC05D5
+:108860007C89E5F8BA203D7783BD8ECF3D002F7E11
+:10887000BF6F5D88CABF5A37859E7A3F6553B8DDA2
+:108880003EB6DADA6E3F2F8BDBEDDBF3E4F94B50CB
+:10889000AFD5A685502FB229173235D9AE664D8F88
+:1088A000B9E1FBD66FB20AD48D637670B803F5399F
+:1088B00064B7A7551CEC5907E58D925D41BDBC51CD
+:1088C0006133ACFCE631A867603CA793B7671772C9
+:1088D0003F2C10EE3D887A6F0EDAE980D7ECB9BDF7
+:1088E00007D1FFBB0AEC72D2CBEC8D83AFC2F71776
+:1088F000C0FF6BC7B2E865329467CDC9A6F1E14FFE
+:108900007A6D0EDAEFFCCF4F669E20BF22ECE67A3E
+:1089100021C0663FDE8DF0861C4A9CFA6377869103
+:108920000F54BBD24EA2206C473D9D8D7A1ABED704
+:10893000BEE1643684EF1207C9B5B9738D7EC37684
+:10894000774246FB677B45803543FF57CD347E77C2
+:108950003A39BF854D7EC32C5319AC2DAE77C50572
+:108960001968EF6FC4575307E32D7AAC79E3C1243C
+:108970003A55B27C81B73DB8106C0CCAB34F58F968
+:10898000B67AFC589845C68AB9FD3FD6C5361E044E
+:10899000D4BF80720FE5AD83CB8DC1FCC1E1A9D1FD
+:1089A000E4E3BDEB7A6ADE1A3D005FBE1417500F98
+:1089B000142C83F749F395027101FD1D26DE5F81BA
+:1089C000FE8D791EF70AF7E7318BF1F4673E93DEEF
+:1089D00046BCE052A23C37CFB766D07CAB9F2D653A
+:1089E00056FCA46C477B6ED66131D4AC0CE0439F3F
+:1089F000FFFF345FBDABE19BA90196007A7916E8D1
+:108A0000BD9DFB310CED549D5EA102D94F575E090F
+:108A1000DF912E54B508F1F9ECC8BE3DD7603B900C
+:108A20001D2DE8EFEA7650E2651BDA415FB6DF2BD9
+:108A3000AF7390BDC558BDFC76D9407FA9D607FB62
+:108A40007D3B497FF6DB89F8679226FA10C6E6502F
+:108A500090EC819BC03E467F3F5AFF9E94CEBF1F45
+:108A60004FB253F1CFF1A4FE5ABA7F2D280057E739
+:108A7000BAAE9AB7EC03E3962C936D6D68CF35C709
+:108A8000058A4324A01ED803239729B656C0FF1297
+:108A9000EC07E9D324D747B6423FC9764AF55CF9DB
+:108AA0007EA087D6F2BA8E103C37EFE0F132BD7E61
+:108AB0007FDC2C1023FFDCCE9A9800703ADC3FFA62
+:108AC000792FCC476D9198BB06CA766EEFB0577D73
+:108AD0002417446FD32FF17B3006720BE75DD7F478
+:108AE0003B2CC76C2CDC02CFBB3DBC7D5472C94E05
+:108AF00058BF76B975064E3F272F726F168CD796E2
+:108B0000934672D0F19A6F37CA2947E6846568F7B1
+:108B10002C88FE308CF148D9CF16862DE86B816603
+:108B20003FECD5E8EC983D519409704FCFABDB9BFF
+:108B30005565513FFA23EAAF46B4B6C31ED5FAD9FC
+:108B400069B3960BFF9EC5E39D57AF7AE8BDFB6006
+:108B50003E9E526F08C96DF3F96C9F601B5CBF3B72
+:108B60003BF287ACA478ABBB5496280ECABAA6A237
+:108B70003DB7F9F39F76FD0E509EF5B997E46C96DC
+:108B8000E88B0B2586F68F26CF436FFF974F5F0C40
+:108B9000E2FAFCC5CD48BFB2D8D397AA18D7D4CB38
+:108BA000F046C072A65EFEEDA5E86F0E94AFB9B4B4
+:108BB00016CB48BB409435FEE866D4CF5B05A611C2
+:108BC000F14DBCBE9DD72FD4BED75CF6FE2FB6A10B
+:108BD0003E98E4203F74AB6607E9F0A97E91F0A3CC
+:108BE000FA87C6E36B1A9E5DC3C7E36B567838906D
+:108BF000A7BE8EF875B32E01E9D8FDB9EB466C7FA0
+:108C0000CF3A165E02B0EF54F6FD7A9B42EDDFB626
+:108C10005A87F3F3D477B2088EE3BFD80670F8749E
+:108C20003826B31B53C0F1E150EBF9A71C2EE7BE69
+:108C300015E0CF2CCDDE74387A82B3E12957DE758A
+:108C4000830CF2664349578355FCF9333FF70332EF
+:108C500053C4DB037E4E7FDDB9E1D30847ABFC9004
+:108C60000BC74F135818EB6F99D2CB84A47E4301E6
+:108C70008E6780DBE987766953998A74E663BE382C
+:108C8000033AF35572F8B7045F600AB4F395C1D3A1
+:108C90008BEF7B89FFD1E5E0F400820ECA0E8D3E9A
+:108CA00002FEAD97A29D9F25EAF457D48EF4E2B060
+:108CB00069F563459761B9338B9727DD51D41E2B36
+:108CC000043DE380362817F21D64EF98E75718E05B
+:108CD000F3DB96ADE6FBB32DF0E9ECA575DA3ACE01
+:108CE000118AC1BAD6D87A1A1AF1DB655EB2D7E01A
+:108CF0007D433C69FE976BF8BADCCFEDADAD9FBA12
+:108D00001AE216EB918A4E276AEDCF824E27FA2D92
+:108D1000E803E8B412F19F44A71F336B3ABDD06F4C
+:108D200041E740A7D5F8DE8C0F735964EA8E450001
+:108D3000A0F4D9F45F6D436D7579F58EDFC1B3E6AC
+:108D400073AFE4873AE2184676A2CDC5E5FB80DC36
+:108D50008F5C86704B7213BD17BD61DAAF792E2B15
+:108D600045BF9327ED40B9358C7EE721DCE67E4B8D
+:108D7000FD8CD6A3E6326F246E81F77FFA256E1F35
+:108D80000778BD54FC322E60A3EF29F945A7FFDC1C
+:108D9000F05284E34CFC523FC02FAB86C72FFB88B8
+:108DA0005F3CE59C5F3C29F80523D1289F3794F070
+:108DB000F28FFCB9C40FFDFCC3CAE87B3FFFB0B221
+:108DC000CBB0ACF3CF658132AA6F6E9F8EF3B6C085
+:108DD0004B9B5F9F47B815D7553D4F6E15C9DEE8D1
+:108DE0006528A73A595FB713F9B05A08ED85B7B3AC
+:108DF000623DF52E05BFF7B0D9607F6CD5E87E17D0
+:108E0000C283FED0242D9E25F5B0AB7C83F9D857C4
+:108E100099288B24E17FA486C76F07C277E0F89D6D
+:108E2000AC772CDAA5A9D6E91E6DBC9B82EA3D562B
+:108E30007C7F26BDF328EA9D6C7CF27EB23E7735BE
+:108E4000A11C30F379CDEA87DFBB6F887E1ED6F098
+:108E5000F6D0D9F3FD4329F8FEF726BEAF14465AE3
+:108E6000F2FDC329F8FECF567CFF15F8FC3FACF8A5
+:108E7000BCD33F3C3CBB035CBFBBB5F5FDB2787EC9
+:108E800047C3EFEBFEB3B6035EB7C213E0B9779802
+:108E9000787EC76A9D00CFEFFA69BD6D31DC17405F
+:108EA0007E47FF7DD3E4581FEE875AC0D197DC8FF1
+:108EB0004BE1FD8069FFB100745EF3D9A650C48216
+:108EC0002FA1DD3F92E1D7DBDDE397B5B8B3723D6B
+:108ED000DAD53B2FF7F2FD846CF5732B7EF80AEBA5
+:108EE000EF0C58C8E31A1B9743DFF6BF4576DE57F1
+:108EF000E8DF6FD5FF331A7D9D49FF8F49D2FFD838
+:108F00008F59DE75321E4FD9961D290910BE7A2F52
+:108F100045F9B4EBE62C01FDBA423521A0FD9FAF27
+:108F20008D77BB5F21FAD2DBED92128284F59B64D0
+:108F3000212618FA3B6FA8FECC70007CE30324DFE7
+:108F4000D4F3F1798FA6CFCED61EBA30A84E0E70CC
+:108F5000393D15C757CF31CA697D1EB67017EB452D
+:108F6000FD02EE77DC82AEF2357D09FDD4513F9AE9
+:108F7000BCBF20206BFE29EFEF6CF50DC07739F6F2
+:108F800007FD5E61059F192F6782F3960138AF0ECA
+:108F900058E825737FBA7FADAF13E9D3A4B8CE12DA
+:108FA0008D5E80AF1A113E579B2DC60203FCABEBC2
+:108FB0006B904C69D8FF4E078FA3EE5C797B2DE652
+:108FC0001B74DE2257204AF297713DA7AC2CA6B83D
+:108FD000EA6AAD5F33FCFDED1D5D632796D3B86B88
+:108FE00071DC8BAB5902E54606DA09147F90258CBB
+:108FF0002F64393B821897DD2C74342C463D7AA9B6
+:1090000097F42D0BCEB58C4FE94F3DFEA4CF9B05B9
+:109010002BCF50BF99EACB9E8E26B493865DDFD9C5
+:10902000616957FD44B3AB607E3F1E12AFC100C5FE
+:10903000B774FC0E1E87AF5F6DB849407CA795C31F
+:1090400090C09269E10EDA6CB595C6592FDA4F657A
+:10905000402FD4DF0B9671BF81FE36E8707522FD7C
+:109060007C55B8F47AA9C7E3F570FF8CE21D5E2E3B
+:10907000B7E803944F1CF65BEE1FE8CF8DEB645509
+:1090800002FD73425632305EB851D383E09905AF8A
+:10909000F2FDEBEB0DCC23CEE39DA6FA51C6E99E83
+:1090A000055D64DF61183E996E8E6A74B02D27FCF1
+:1090B0007480E4482884740DE567495EBAA0ECA387
+:1090C000F25FA92CF7979FA7FA415E9FC9F2B0F013
+:1090D0000CED5EA176527F3FC7A8ECED1FF7351A65
+:1090E00027D05FEEA5EF85BCFE70C7495A573EFFFB
+:1090F0001E91E6FFB1A466E0FEE837A38D14279A1F
+:109100001F5D4ECF4DEBE45A8CC73DB3AEAFB515E6
+:109110009EDF9CDF28A3DD3F7FE94F68FF5EEFFF06
+:109120004AF42B90DF156906D94525B6F01EEF00ED
+:10913000BF0DC0D1AAE9FBDE7AA42397CAFADA2BC5
+:10914000A0FD948F5A5B0D794E1D943FE356A4CF3A
+:1091500092E3EABA1CFCBB433D1D383B3A36CD973F
+:10916000B18330FEC7DED2788CE8BA4EB6E2177D06
+:10917000DEA9FAD7E79D4ACEE8F8D3DF6F2E9D200F
+:10918000F3FC9FB8012FEED1F594EF73A5A0C1E9D0
+:109190007369FCC6EBCD82711E2A27FA50907E6758
+:1091A000697E9C592FE8E3FEDD1119938DEDE0CD2A
+:1091B0002D132CF03B4CBC1D5DB72C5C6F4779DC4C
+:1091C000E5A6FD7B26539C5FAFD79062FE75D95C08
+:1091D0008F30A74AF3D9726B461CED8E2D8BFE2083
+:1091E0006370C533EEE32ACCD7F4087D9F2C46F993
+:1091F00072AB8FF2311A167D52D59CD4FFC2037F19
+:109200007261BCB761DCFA6C8CBB2C64D2C7C9F943
+:109210000EE6711BA2AB896E63CD428395BF752CA0
+:1092200087F3F5424C9111A9BFE3C9FBC88B9409A0
+:109230000E8C4F2C8A19F77340433A903E1A379997
+:10924000DF27EDE788D83FA379C770330FF55E9B22
+:109250008DE86D27E00DFDC0625097F83C9693A510
+:10926000F1410FE1F35F0DCFB11C6E0F395D2CE6BC
+:10927000C91AA09BDC480743FDE4AB14687F33E0C8
+:10928000D3F323BA484FDDE1D5CBA0B700FFE1729D
+:10929000CDCE29E5DF6D5846FFC7D373D0067CDC01
+:1092A0009EFDF865C1B1D05F79246893A9FCA44400
+:1092B000F6212F33F6F89307C99E95CF1542C0FFCC
+:1092C00052F793878BC89FD7ECB1EE27C91EEB2FBF
+:1092D000B30483F974A6F597555710CA23FBCB3115
+:1092E0002CEFD2ECF8F6ECEE275BC93E09B7652708
+:1092F000E9EF5AC6E3CB5FB77EEC0C2EE9C07CA247
+:1093000058A98DFCBD34133F3E98EDA07A637223BB
+:109310007767C373D62D7D12C61B1C792F04500EA0
+:109320008C283DA18E04FA1F51CDD36458191FB764
+:10933000B3742DD90D9DDABAC0FFD6A3DE1B589F9A
+:109340001ED3FAF0F50857F6D0FAF8CA7B68BD6C60
+:1093500058A6B81FDF8FBFA292DB1BB293EF2BFC86
+:10936000269BC75DFF942D6A4FEE976694DE4EF103
+:109370001DF70C1BD5CFD09E6639FEA76CC9A05730
+:109380000EE445FE909D64B7C2FB705925CAB740F4
+:1093900016EEB3D6964A37223DFF5CF34F619DEE41
+:1093A000A0752A09A445F8BA3D62B96E65C35BB7DA
+:1093B00017D745485EA55AB76FCE17C35671B76722
+:1093C000353C7CD0F0B7BB902D57B9FA1CB80FB321
+:1093D000B974BB21AFDAB56F760273A1F5BCEAF5BB
+:1093E0009EF46A94DBE6715FFCE23F0288DF999F9E
+:1093F0003A2DE5E37F6BF2F185750DD40E16589189
+:1094000072480E309EF7D29F27269C76D2F45EC417
+:109410003CB4EF12EB333637FC06ED572F0E8A0CB7
+:10942000F7C71732635E198BEA79C13C0FF645091D
+:109430005C5340E18B31210498628BA4D9BA5C3132
+:10944000E487CD9B3BFB10EEC3376AFBF0205F0C3B
+:10945000DF979AF2C6AE6E5814AED7BE9FA4BFE394
+:1094600034AFB90AB71BE77ABDA45FE785E787EB9E
+:1094700093F6E35EFAA76899875E97A3E3251CAE8F
+:109480001F3D182F8BC3824356CE8C1F333E6A2557
+:109490008EAF451ABECCF831E3A171EE6C5A7FF362
+:1094A000FC5F7485093F2F027E305FD88C0FC62287
+:1094B0005720DDBE345F64681F4F1767DA314FA055
+:1094C00071B6C030BF68290BA5F3FC6075D625497D
+:1094D000F09AF168C657E3A32C94807E1BEFF4D179
+:1094E000FA3DA7E1474C7C48F30AC3BCDAF9BC8ECD
+:1094F000F3FC5599E675955AF17800BE475A41DA62
+:109500002A567A84CF6731CCA75D1EAC4F3E61D519
+:109510004D48274B4D790B66F8CCF0CF4439387560
+:10952000F03EFEE41C5F80CE2F8C67216D1F3F83D1
+:109530008E3584B287CC5B18E0734E5F0BA3B3FB10
+:10954000C7C37E0516E92FCB80DF994FF8B7CE83CE
+:109550007FAF0D8A0AE609CE9E3FAA0DE71F66E19E
+:109560008C4409DAFB7D76942357313063A1DDC545
+:109570003049D4B7E17A3795F57E4F747C64273D46
+:109580001E614D7B69FF5DC9983B2EB57C591B74EC
+:10959000D078663B6566C5E80C9417667CE878FA77
+:1095A000568E96DF309E8D3F1BBCF4A0EC457F1697
+:1095B000E368B08E7DCB19DB5D31B07FCC0A556E90
+:1095C0004FE630DAFF5F9D93A9D91D4D147758A05F
+:1095D000E9856376D6F0A097EF234F48928F0BF37F
+:1095E0006A57E724C5FBF47D642FEB25FC7DD7E5A6
+:1095F0004D88E389EEDEEFA70F925F7ABE6684F2B4
+:1096000035C58C950AC5C53CE9E35906D8C58CCF4C
+:109610001BFC989B7230AEE7298EA31130F3895F53
+:109620006C9AA70CACDBE6257B3B105CF7D2DFC75E
+:10963000A87385E77378B475ABD5D6ADDF8E2E836E
+:10964000F749F83DD1A1D961655A1C1FFF40F94483
+:10965000A91A1FCA7FD5D7D15D06FE87218FB08397
+:10966000F0A7AF2738117DC89791A04439C336E6DB
+:1096700022FF387213CFC758C8945D981FB4306A60
+:109680003F91DC4F244F2238229BDD5ADC2444FDDD
+:109690002CCEE3FDB032EEE7F5D37D0CDA27E53FC3
+:1096A000DA5C604A62FB4C1642FF09FACB417DCF7F
+:1096B00036258D3372F0B8A9FA33B713B5FD5BD1F7
+:1096C000190A8592E4F46F72B89E3C11ACECB28D2D
+:1096D0004C8DBFC52EBF2A25E5C51ECF733558C595
+:1096E000C5F4FE74FDDD6F27C6963F956C277A376B
+:1096F000343E75F8A2243B31D6F814C515F5F2595D
+:10970000DA89CFDFD5F8542BCCEF1FAF7E83F2C7B9
+:109710004F3481C0043CFAA3D3D89B7E940F32E926
+:10972000AFE206F0A830F95B52C622BDBBA305AA82
+:1097300094942F7B2C4721B8FDA52AED9741D32E79
+:1097400074C5FD524840BCDDAEC5CD8070C7CEF6B5
+:1097500025B7E37E883E9ED325131C0E7D3C166AFA
+:10976000A6FCFA998CF4889E07A2F3B5DECFBB392C
+:10977000C678DD30F8F9DD9CAAC1FC2C8A4DAFDF3C
+:109780008A72E22991FCB0EF046FA2F7E678C089F3
+:109790001C6E1F8E102327502EF4343CFF9D1F405B
+:1097A000BB35FB9C2154C3ABBEFFDE8FAB14C4138F
+:1097B0005FFFF94B1BEFACC2798D9664DADF28E2CC
+:1097C000711847B340FEABBBC411DE07CFB703B57A
+:1097D000237293E07A3B504FE59133385C27A0CF5A
+:1097E0007605DB6D6F207FD1C7F7BD4F280A9DEF4F
+:1097F000133D8CEC09D1C99F99B9DC2ECDCCE5780D
+:10980000766B4FD729811609E9BA09F72DA418E517
+:1098100041BB4E49F4DE210896F69ADE9FEB140810
+:1098200067C497C7DCDE41EF713ED85EF433837DB9
+:10983000938FEDABF0C9E9DD75CAC3E1F09BFB493D
+:10984000E7EF35FE33C37163CEB462C4CBDB017581
+:10985000442E8F6F7339EC7DF2A8307E38F298E792
+:10986000EB5F9127B928AE77AB101F0DF2A9BDECC5
+:10987000441BC9AD1257139E934AB29F047EEE86D5
+:109880009FAB18B04FFB2E995389D16BA6DC1B1AE6
+:109890006C6FBD5EF9C9BC3958D0CE4F7C5797BDAF
+:1098A0003128833DF79A565CA48CDC80A1FE2BAB5B
+:1098B000B97DD688F65988E496C1EE32DB675ED072
+:1098C000F773802E96062519E9C26CA7B557CE23EB
+:1098D000BBA61DEC1ACCD71E6CA77179735BD4C6DE
+:1098E00054A8F74CB5487EC63365BD4F5C8CFA6210
+:1098F0008A5D217D51D677DB1CFA3E91C6F16AFE66
+:109900001DD4E7E71D429EF86878F76CF59BDEC62C
+:10991000A4F57E66CA9B63D12FD89522BF428FD310
+:109920001CBC99E77FBD7E87107722DE6E116DD853
+:10993000EFC20A1FE5AD5E227A699CC6AD62DC49C2
+:109940003854D32FC919B01B99589DF33CE2619B41
+:109950009DE1F9C1A21B7B0D76EEC2A8D19E8B348E
+:1099600081FDA39CBD1D68B6FFCC76CCDA5CCDAE84
+:109970009BC026A0FDF2CCBAFDECCDD10376CCACD9
+:1099800014FBDFBA1D7381ADEEE65C1E17A4FD83E8
+:109990005992F5FEFE559A7FCA42DC1FBC447C9F5B
+:1099A000D6EB444852107FDE9B9EA4731DDE7F8A57
+:1099B00061ABF1B6E7727F7C978391BCDD35C14323
+:1099C00079D7DD379F9BDB4BEBA5DC5D8DEBFFA4EF
+:1099D0009DE4602AFDE68E8AAC1426E68B0AF4D458
+:1099E000D77344D4CD92F5C38814790ABB73B9DC1C
+:1099F000CEBE85D9D0CFCE8C31D5CA2FD5EB813F05
+:109A00003A1D63D4503F9109F0AD2EB551DC5FF79C
+:109A10004BDD767EDED7FEC8F531F44F47007C087B
+:109A20008702F0A11C2E897AA83C32EAA7E7A86831
+:109A3000263D4BA305F47D7474143DC7444BE8FDEB
+:109A400039D1F3A85C169D48CFB1D10A7A9E1BBDCF
+:109A5000909EE781DEC27AE5D15A7A8E8B5E4EEF18
+:109A6000C747E7D0F3FCE86C7A86A2DFA6EF15D1F2
+:109A7000467A4E882EA2F713A32BA85C19BD81CA83
+:109A800055D1EBE93929FA437A4E8EB6D0734AB4F0
+:109A900099EA4D8D6EA1F205D19FD0F3C2E8767A96
+:109AA000564777D2779D9F3D9A3DFD74708F4CF954
+:109AB000F62C518EF231151FBEA1E9856FE4AA4F35
+:109AC000A03CD5EB1DD1CE1D98EBBD9A3B74DECDED
+:109AD000D15C4E9F1F848EDF85C769F575DB1C1C2A
+:109AE0003A8EC0CA0367D8B7E2F33B9CCBDBEF9258
+:109AF0003AC8DED8D5C4281FCC57D923503E43508E
+:109B00009A61454799417EBE6B4C6EE45D9CA737D8
+:109B1000EFAD83B81F7565AC27300DE92514489B60
+:109B200006FD8D68B5917BAD3059C0B252CFE404CB
+:109B30001B88E7807D65D06BEEA04D8BFFF4CC9C3D
+:109B400088F09C5B3A81EC576D3FF9C8CD2319FA38
+:109B50001DBB1C09414279B996B1643B7CD786C5CF
+:109B6000F7259FD370071D9C8F36B1C7304E56D254
+:109B7000A1D4E179C2513BD4C730C573743C52972C
+:109B800006E5737E157B0C9F63BBE2751E789EB75E
+:109B90003FF118BA4FE312BD755E289F7F981DC034
+:109BA000F053458F32CD07E58947D503B84D52D5DF
+:109BB0001B9996AE203CF196748067D76B60684124
+:109BC00079CAFB1D22B82503EB0F76DB8349EBE254
+:109BD0002EED5145F867E18D7205CAD95D52AF3B54
+:109BE000B37CF0FA74E2BC719EA057F66AFBE8728F
+:109BF000D27A5405053D1E9817AC1A880776B63EF2
+:109C000047F1C0CE34B916435D7D973079B7827481
+:109C1000CCFD84B4B691A49F74BA03FC1AEC49B786
+:109C2000D6EFAE7E7BD31ABF55FFCBF07B50A3E7B8
+:109C300054F87D1AE79177663E9E1EE47615F07122
+:109C40005D303B75BD15412E4FCD78DE25C9E7123D
+:109C5000BEBCCC16AB1858B76B34FA3E135E23FF6C
+:109C6000CBF07A517068BCB24A3F8F336BF969A967
+:109C7000E4CD9114E744BEA7E13149CEF178A90CB7
+:109C8000726E546A39578B70650F21BF52E43BAC3A
+:109C9000D7E8BB3B3B1C0B669F39AE7F9B4DAEC5E7
+:109CA0007C97D878467E02D897AD98BF3322A64CD1
+:109CB000A06D2C14CA88C709E7919F5E02F686340E
+:109CC0008161AA63029F575466DA1697635E83C662
+:109CD0006FF2A26032BFE9FA7E801F75BAC8EAA4AB
+:109CE000731640AF984FD8ADE169A01F1E8FD87092
+:109CF000537E677B921CEC0C155059AF9F8A7E5F98
+:109D0000D7E9B7F539DAEFBFA2DA3ADFE4CF41514C
+:109D1000CB3BEA5391CE63354CA6F3CEADC7493E5B
+:109D200065827C124A787808C72F8CA6DD8771DAA5
+:109D30008783399A3F2EA77DD3F7FF8F9EB781AFD8
+:109D40004E7E66B5DC8DE72A46801E52504E560385
+:109D5000EC95A8E71CB4EE0AE3EBA854B3784220D4
+:109D6000BC25D06F8ED9F8F98C238E2E95F48E23D6
+:109D700053C6FC93EEECC813C121F842F62815B87F
+:109D8000A8AF0457CDF4E6615E8E9C86E597A07C73
+:109D9000DB14CC13EA655AF936EFD42F1F7F7865B0
+:109DA000C78A23B84F7561503D8AF0005DBF827449
+:109DB000AD9E234B141F1EE6FE93CE9F03FC24573B
+:109DC000E8FCB4A89CE4E15BC1A4FDAC54F6CD2E44
+:109DD0004D7E7E121CDABED1E9FEACED1B0DDE37E6
+:109DE00035B9948AFF673EF1FC8E3D6C20FEE7CBCF
+:109DF0007FB14752D0DE9EC6DE9C8871AF1E4EF703
+:109E00008CC7F9548CFF011DB82B5DA6B8AD30434B
+:109E10008BBB0C19AFD5E3C97ABC4F8FEBA56B7424
+:109E2000851706A01E4F9F224B8BA9BF5E7615E6B5
+:109E300037E5D90C7C8D720BF7E75D6D59D2C8F20E
+:109E4000817E196B2239D5D9C0E4F64CBEFF9A0148
+:109E5000F2A5633D233F2FF68C48FD9F546DEF61C3
+:109E6000CEF7C94A4020CA059529728E760E8188A0
+:109E70005C267A7532D685FE36FB51C8E5C038F7C8
+:109E800067025301EE239F89F49430C20D8DAE0812
+:109E90005584B0716D467508F703C537A10C70D6AF
+:109EA00067546760F9C89189216611BFBB3AB2C88F
+:109EB000105F32E3A9BFDE77DA285F61E719F63F6A
+:109EC0002FCA73E876E7E43CDCFF5CD2D7EA5006A1
+:109ED000F63FF57DBDBCD2872EC57B76F25672FB70
+:109EE000339FC59B93EDA6A4FDC5DABC2ADC4FEFDA
+:109EF000DF5FEC1993BCBFB826FF163CBA7F4FFF5B
+:109F0000FE62A412EBABFEAE0AA44F3D1FF688839F
+:109F1000EF03B0894F05140BFA5850F17836D1A3EE
+:109F2000E64F0CFAAEC5CDCC7EF09C3C631CFF64C2
+:109F3000684E46023FA688E3EBF13CDD0FC6789DF4
+:109F40006CC97746FCEBE32F10B81FCBEC02C93B82
+:109F50005D6F823C598AF88666148F569D02E56BC8
+:109F60009D0C352AE417A5902FFDFB062C31DA6AEB
+:109F70009F75819677627EFFA33CAE9716D8799C39
+:109F800052B87E6904C75D90E7129C4976D28A3C3C
+:109F9000AEC7F5FD1747FEA92AC4B3C31151ACE6FD
+:109FA0006DDE475981B66015C753C842EFA5C2D3CD
+:109FB000517B07EDCB1D5D2AD279DD9391C974EFFA
+:109FC000432AB9F00AD2CF68C6E6E5733D34B08EB5
+:109FD000D678D3F364CCFB55FDDF17B9E9FC8D3996
+:109FE0005FE6210D6F4F6978F957E7CB3CA5E1EFAC
+:109FF000692D3EA3C7B3AE4821EF2FB0D53D90C722
+:10A00000E38C43C665CED3F37D34FCB00363E95ED5
+:10A010008E2D3DF6B85B40786CB47FD9F09F620816
+:10A02000ED2FBD9DD7242FF4FC1DBDEC3925B07854
+:10A03000D23E8247EAA238A9E79444EFCDFC775B91
+:10A040005EFFFE22F19FBE2EA9D6595F17F3FBFBE0
+:10A05000B47539BAE84F413CEFB2C5CD2CF38958FD
+:10A06000BE31FE6ECE0348B5CFFD9AD6FFC9C8D427
+:10A070005C94CB0D8ED8E8E1F0BD8E9F17BFF8A39E
+:10A080000BF96CCB29E70CABF57849D34FA04F37D0
+:10A0900025EF83FAE63FDF8ABD7A24E33EA8AE4F80
+:10A0A000F57D504FA5791FCD7A1F740BB3968FA9FC
+:10A0B000F64107ED7F6AFAF6B3BC14FB9FE5439FB8
+:10A0C000673F90C78695F771B5839F9735BFEFD1EE
+:10A0D000F8EE646473D15DC057372C7252965262A9
+:10A0E0009193F8B071919BE2B28D153CDEDB78A7BD
+:10A0F000A0EDD719E3B04F83BC5809E33FABE99D0E
+:10A1000037597812DAA3B32A05C33E79B8DA6D2835
+:10A11000CF5FFA93A7F1DE8467A6D8158A3F435F25
+:10A1200031B40BAA799E2253FA6EC338B71E7FD67C
+:10A13000D7FF99EA37E91EB418D8F9A343187F1658
+:10A1400089BF9E796122BF974E18D80F57C04ED84D
+:10A1500072C128CAF778B9FC5B14E7DD8271719887
+:10A16000E9962FFE3883E80894720CF9757C561C2A
+:10A17000E563E3B80939489707C67FE6C3B8E8EB5B
+:10A18000B79CCCC675EA5DD7447907E67537C799A1
+:10A19000CDF1E5B38D2757E71BE9E169533C5997AA
+:10A1A0005766F991144FAECF1F463C59975BBA9C46
+:10A1B000D0E5D7CBE5EDAFEE867FBE1C71124CAF7C
+:10A1C00068F3EEE74B8D2E5FD6F9F00B27D9230706
+:10A1D000C63F4CF9567ABDD6BC4CA2AF6F95C7EDC1
+:10A1E000B43F8B790A6503EB323FB2BCBF8CDD7E96
+:10A1F0007BD9F506FAE8975367946343CB29573E1A
+:10A20000B7C352E56BF6A4D43FA3C94EF5FCD51EE7
+:10A2100077957C793DD4B0E80F0AB683E70E6A3FA4
+:10A22000DE11895BE827333C9E53228B4F4C7EAF77
+:10A23000F0F7FD7AC041DF6375CAFAF5016E4FB7DA
+:10A24000107FC69CB8EE52B6DA8A749097ADB6E528
+:10A2500043BBDF06D40DF949F2B4C5CEF723451B45
+:10A260008B3C688197C7F235BCB07010FB6BAB3587
+:10A270009EE7D29FBFC997B4F3189382685FB7BCBB
+:10A28000511144FE39E89B44F676AA75DBA6F31318
+:10A29000CAAFD103FEC4566DBD814555DCC76DB351
+:10A2A0008783C9F1C6ADF99CAED2A73ED48376733D
+:10A2B0008B6CA33CC11699E75FB77AA5197BB4767E
+:10A2C00001433B493F4745F765485E637EF5636858
+:10A2D000EF54A59EE763F9DC3FB4B3C41DD5C2803B
+:10A2E0005EB11FAF75D1FD0F4C95797E53C8904F6D
+:10A2F0006DD7F44B9D295F4394BF9CDF569C1DE9AD
+:10A30000C6F534FB6D8702EA63F83E2AC59C481FF8
+:10A31000519735DF1FD6D6B5459BAFF95E55D17441
+:10A32000EF8368BAF72156D7F4CB5EA4B7F54EB9E0
+:10A330002540F73CD0BD0F51BC72099EFF70F37CE5
+:10A3400016F0FF26F3F306A15E94AF2CE8A2785432
+:10A3500047A1AA164259F4D976AF87FE5AD43A15C6
+:10A360008FAE74786D9DB8CF979317790DE731CD87
+:10A370002791DEE9B82C8DF4107C777339C26461C3
+:10A3800012F98374690AFAE078BECC1E74503CABB3
+:10A3900025C27A9DA3F8F97FA4F75A9638525D82B8
+:10A3A000F6B6AB12F17424343123622127F4A77975
+:10A3B000FFFFD5EFBD544CF9AA62E4A37CDAF76F36
+:10A3C000DC8AFBFA6BF68B21DC47F8CEF75F1EC305
+:10A3D000CF1B19F799EFF6D4F4A23E8B7A1D54AF38
+:10A3E000DB37A903F1D422F83AD0DF6D79E3FA9F85
+:10A3F000231E5B9A799CDB8CE783BEEFD3FD1A2783
+:10A400006139B1BEF97E0DD6713D5F27A78BF62D60
+:10A4100061BEF6822ABE8E141F3CE6A37BA04E1EB0
+:10A4200039E045F8BEC2BC65EC37F5BC0B65D257C8
+:10A430001AFD3029BC09E7F503D1D7D11EC07BD264
+:10A4400060BD11EE47ECE4EFDFED49A7758D027CAE
+:10A45000B8AEA2AF5E4597ECC3FD22AD73546AA2BD
+:10A4600079B198C4F6E2FB473EF9F18548076A16D0
+:10A47000ED6A89454D84970F012FEB2DF002F433DF
+:10A48000A600FDE5476EA07E3A1C2E192D9B16DF17
+:10A49000243AAF3CDCFB452A0A847E7F4BBB5FA499
+:10A4A00002FB1D545FF3B3D0DFC6EFB532FB38CEED
+:10A4B00006F09E2A7F452D30DACFC3C85F510B2CA2
+:10A4C000FCBBAFB0AE97170C49CFC6756D71FDDF01
+:10A4D000E96867A9627AC85D0C655C27C43FAE1362
+:10A4E000AE9716B72115A4201DC88902A4831BD2DC
+:10A4F00043489F67921B12E3EB6E97809EC1AE7339
+:10A50000CA91A37476518BF7E8F2C4CC672D2EA3C1
+:10A51000BC6AD1EFE53B363C7905F4B202F16096B6
+:10A520005BC3A593EF0FA693EF0F45276979E12849
+:10A530007E473C154CA078C5CD583E7244DCE718E8
+:10A5400089E3F1B8595F1E937727E565E9F06CC69A
+:10A55000CD6ED2CB3C6F4A6A600CF3E0FC652141C2
+:10A560002E1F161D6DFE9AE9E88EA1E48397F5D0A3
+:10A57000798D557A7ECEBEA1F373BEAAFE81F5BC5D
+:10A580000FE169F17D9FE87383DD25F37BD4CE6E07
+:10A590005D1F2C10CCF70B3D988CB7C1EB1AD987F7
+:10A5A000EBA8164CA27B8CD8944564377567ABC773
+:10A5B000305F8C4921835C1CC43F9ADCFEC1390AA0
+:10A5C000E5ABFEA5599373CD4E19EDF1C70337FCEA
+:10A5D0000EEBDFCE9430C6436B6C6B094F1FC2FC91
+:10A5E000768748AE96E1BE4F94A585343DFA1F08A4
+:10A5F000CF0CA559C882F781058A8DAE2155B63397
+:10A600005BF9F0F1F0DC603C3C37141E400EFEA715
+:10A6100046CF37223DEBE7ED53C9C137B4FECF42F9
+:10A620000EBE91CC5F5F03FDBE3FB47EFBDAE5CD8D
+:10A63000A7389E59DE78357EFE6E8885305E3EDC1A
+:10A640007C36B03715E4AFDA7417D14FCB8302E50F
+:10A650004B811D1EA1B2CF45C2E6A0CFC1F37FF74B
+:10A66000F1EF621DC7B3194F42213F9FB5AAEBFA24
+:10A67000B064C8938AF1F39AEA09B954C4FCFE6A3B
+:10A68000A267BF66CFE879FDE99AFCEFD7F3336D97
+:10A69000349EBF88CB773FD83B681731A997A11F5D
+:10A6A000FF83029EBF0FFC40F40DA384911F32A6CE
+:10A6B00048A63C2DCE2FD912B77732034C205D83AC
+:10A6C0007962F0FE13B027F07E824CD5D8EE076990
+:10A6D000DF15506FF52EF23609740E3EDCFD33287F
+:10A6E0006761BE17F08D7F86B17E364B2A5BF8E737
+:10A6F000B13A5686798B15855ABCCDC182A41F35D7
+:10A700003F5DBF2F503C73DED7D4C261F8E9171705
+:10A71000EA79C2467DDCE56696F1B523855C1FD5F6
+:10A72000F7D6D6A15DBDD6C7C8AE5A8BBA13CB99A2
+:10A730000EBAD726D45DE9B2BAAF2253B519EEE707
+:10A74000F5CF4833DC7B9B1DCE3294731BF20DF5A5
+:10A75000F322230DDF0B969D6BF85ED434C1501E9F
+:10A7600011BDC050BF04109C5C1EB5E93243FDD141
+:10A770001D5719CAE7ECF896A1FED8F862C3F7F3A3
+:10A780007E759DE1FBB8AEB586F2F9FB6F36D46FEE
+:10A7900061D6F777766878057E2739D6ECAD6BA061
+:10A7A000DFD1901D8638FF755ABDEECC4965180F74
+:10A7B00069395E5146FE70FA0543FAC366B9984A94
+:10A7C0001E9BDF6F2EE4F2F383C7DE9EB412E91CFA
+:10A7D000853CC8A50FBCAF6CC0396D2EE77909FA6E
+:10A7E000EF6298EFE5EFDFA794549ACF822C07B37E
+:10A7F0003A1F705DA162B9BFD02A845CB857940A31
+:10A800006F478689B7EDDA3CBE2ADE8E09C638105E
+:10A81000EA93072DE07A42E32BD057BF453E047DF3
+:10A820005599461E06BFC7E16CF5890E07E8937F70
+:10A830002FCC1E9C1FFE41C3F3D7DCAD60FD6B78AF
+:10A840007D5BA80CD725D5BED21385E67DA5AA656C
+:10A8500028E716F8D284E4FB9AF76BF5F478764B88
+:10A86000FA67B4AFD4E208950D675F697F21E3F71B
+:10A87000E0E2FA6627ADAB5D0DCA96FE9DD98E610A
+:10A880004FE03D1831AF4479C366FF2EAAC96DDD94
+:10A890009F930ED692BFDFE21D49791F2DEA5AD24F
+:10A8A000971D29FC5CD097BDB83ED37C371AFCB904
+:10A8B0008178804AE3415BB29B5A92FC7F6CA7DEB1
+:10A8C000CDEFD5FE1AFCE08F0ACFC2FF5718F783F1
+:10A8D0004F328EA793AA8DEC84936027A0FC6D93D2
+:10A8E00018ED7BC72A05C5CA2FEE58AFD987EB39BB
+:10A8F000DECCFBDD663BE38AD0F584B736A0275774
+:10A9000025CE9FDBBF6D767EFFA6EC0F0751DFF6ED
+:10A91000653BD86E80F660368FCFE978F9B2F228C1
+:10A92000A76890FF93533484FF738958DE85F7B688
+:10A930009E38C5E3220A1E450CE03DE47CFDD63E70
+:10A940003127B606F55489D484F9EB225332102FFF
+:10A950006B0E8B2C2EA01C33E6E7DB59D35D188FD2
+:10A960006301FE3EC65CCD6827654C31EAB14CD52B
+:10A97000A8C7FC33B24C7ACDA8C7721B8C7A2C2F97
+:10A9800062D46305CB2698F49A518F8D88D699F4BA
+:10A990009A518F8DDA749549AF19F5D8393B8C7A75
+:10A9A0006C6CDCA8C7CEFBD55A935E33EAB1F3F7E3
+:10A9B000AF377CAF48B41BBE4F3C7CBBA15CD573AA
+:10A9C000AFA1FEE4A3BB0DDFA7F6FEC6F01D10FD90
+:10A9D0001C9E67C07B6871112F7CF721E377A63A34
+:10A9E000301F7F059ECF8475BCA8EF61437FAC8389
+:10A9F0009F5B88C17FB85EEFB008DD030072EC504A
+:10AA000001B45B1D17420986FAE9C1B771DF6679A7
+:10AA100050243F6E0D065B911EEEF7C5911EAEDD14
+:10AA2000613CFFB03C6E2CC7807E148C2B00FD2057
+:10AA30007DAD30FD6E04D883446F2B14A909ED4A17
+:10AA4000337DBDA3D3574C7D0ECF73E8F3D5E767B5
+:10AA5000D7CF9F6AF4A76AF4C7C44708EE1505224A
+:10AA6000FDFE8E3E5F15FEE3DFDF77E03C3ED92F33
+:10AA7000303FC0710D8B1D2AB098CFEAFDDB1DC899
+:10AA80009FE67999E761B653DB8A8CFB489788DEAD
+:10AA900010F1DD0B22E9239A02F2D903FCBCDEDAC5
+:10AAA00027443A17837C88FE82186B20BCAC01BC1B
+:10AAB000E0BDE1BADD7A426B77E2A7229D6F3E13DB
+:10AAC0003F2A1A3E9C41233FBA9534133D19F1EBBE
+:10AAD0002933F2E78AD72E75A0FC3A04F816A6307F
+:10AAE000E60B19F97585B892F6F9743C2BF01F8EB8
+:10AAF0002B81A98BF35E0DF34E2883F1BBEC91ED16
+:10AB00001B0A2CE8E64CF87DB0C8B8DFAEEFCFD515
+:10AB100002761C1679A53AFEBAB3D53FA27C4CE565
+:10AB20000F1F283A6B7FF840D1D7EB0F3F5334A467
+:10AB30003FDC370BFD29274B0FB55BC4FD242627CF
+:10AB4000305E6B6FE271BF81F8DDD71EE7790BE1F4
+:10AB50009464AE27DD921EE7091D8DA07D92716E73
+:10AB600008F3A2861BE7F870B01EFB70283D06F6BE
+:10AB7000C5313C4FA866E4D7DB9099A45019DDEFAE
+:10AB80008C20F03CA4FF46F806E5EB966669F9C711
+:10AB9000CA90F9C75768FBBB1706D57F221CD0DFC8
+:10ABA00069ECAFFF3EB6CA6CEA27FD0CFDC4EAB8FB
+:10ABB000BD16B3F93A5AB8BD46FB4C5F431CC35FA0
+:10ABC0008C712D2FC77F8B83C76DCF36CE565C3CE3
+:10ABD00028BE545C3C447CE91FAFE6F273AB21B065
+:10ABE0000E2A52D3B77E0E532F6FCE34FACB1B26CC
+:10ABF00070B8CE2DE6EB1ED1CEE3D668653DEF12E0
+:10AC0000F316DD13A03C939F53D2CFB5EAFDD414C5
+:10AC1000FBA8FEA7C1BA1AC4C786127EFFCE864C17
+:10AC2000E33D3C278A6A6B705E53B4FE6B8A193F22
+:10AC30003731523BB7698A177CAED5FFBCA88E9ED0
+:10AC4000788E16FD1287285AE2735AB14DBBEF86F3
+:10AC5000D173BA7E7EEE4E7EBECE7CEF02F0C98B03
+:10AC6000F8FB506FDE66277F0FF4119D9F5B5AC083
+:10AC7000CF219AEF538894C98750BC7EC2CA2DEF6A
+:10AC8000E51994E770EC26CABF7B662A9385BC332E
+:10AC9000E73D7CBBB85F5F85BEE439BAC6E261E4DC
+:10ACA0006B2DD1CED1F5A6713DD697E78AEFB6F0E0
+:10ACB000776FD5E8F236CDAFC5FD69DC27C7FBBDA0
+:10ACC000ADF6CB6F2DE6FBC3C33D577DBB231241D1
+:10ACD000BE359FAB4E759EBAD7D1DB968BF08E6595
+:10ACE00021B4DF7317C8DDB9502FAD5EA1F38F1B00
+:10ACF0004A58FA14FC5E610BE1B98ECCB9F2063BFE
+:10AD000094334B599600E5DED81C1AFFB606268B05
+:10AD100000D77DC5FC3E8485B77C44E36557C3D42A
+:10AD2000143A773E1DFDB35803A37B0BCDF3BC5BF8
+:10AD3000A35F571BBF2727A3D43A0FFFEE62DDBFE7
+:10AD40000EDF85F45B5BCAF6F1F3B3FC9C025E4B4D
+:10AD50004FF99BA134DA17BC12D68DEF9FF7D0FACA
+:10AD6000DD149CF6536CA7F39B43CB53309F27BF56
+:10AD7000AFF8ECCE93A72DB08637A1ADF735D9E16A
+:10AD8000FB918ED2CA3AF8EF977E71FAB43849FB3C
+:10AD9000694705DB4722A8FFDCA0FF047C2A329D1F
+:10ADA000A3652E81CEC3BA9426A22BF794901F7F61
+:10ADB000178D2DB131BCC7659AD65E6D6002FE9EBF
+:10ADC00004E502929C36FDBE841A6A6D86F697E011
+:10ADD000BE5908F3BE43CBB0BF7A6F9A8CF14D7762
+:10ADE00069532DAED7E30B791FB7A7382FA19FB3B7
+:10ADF0001FB87F6ACDB3867B051CCB9F35DC2BC08B
+:10AE0000963FFB55EE1578AD78F9B3FF13F70AE8D6
+:10AE1000F20DD4901DEDFAA322BF47EFC347AFB6A2
+:10AE2000E33A6CA8655D88F7D8678067D7009EED28
+:10AE300075E1C777A25DB2363DC47F4F24F61D840D
+:10AE4000F3350F93B1BD9E6F28B032D2D7731B0478
+:10AE5000B21F98D4B71ACBF31FF1C8E83F7CF8E8CB
+:10AE60004B4531A0CF576F3DE9C3FCD4D7A53E1F5A
+:10AE7000C2F5EE2DCFFBF0FEAE576F11290F85CE38
+:10AE80007D27E5890923387D2D1A113E85F4B5709B
+:10AE9000DD3F2725DB672C9A4DFA7E791C204EB6C4
+:10AEA0007B7FE531FCAEE8AA2EBFA1ACEBF9554E95
+:10AEB000EB73F35347703E5C7E7FA7A340C1F12341
+:10AEC0006923A0FEBBDA39A077F7F9C88ED7E1591C
+:10AED0007C7F8503EDE1D71F71B204C5057BECCC07
+:10AEE000CBF507E65D44F8D083E03CF4970207F227
+:10AEF000D95281F53989B9D921C4F7DF34FFCF3C64
+:10AF00008FA5AFCA0E5CDFA5B5AC0FCF9D2DBE518E
+:10AF1000D8F003A8BF38E225BFDF3C4FB3BEB91657
+:10AF2000EFB311ACEE816B3AF467E86709F483F68E
+:10AF3000E7D20EE3F713876F38B413C6DDB7DF41EE
+:10AF4000F6E2B56788F78F1FA1E9A5496CF2E951D0
+:10AF5000A4FF32C629A9ED0E5D1FBDBB8E5192CA5A
+:10AF60007FE1EFFBC2F3FD75323D4F152BB41E2B75
+:10AF7000F6771FA2DF16967A26A1BC9BF944A3E7B9
+:10AF80005B6C20AF685267CB819D5455CF574D50B5
+:10AF90007C6F8A76FFCBB5DAF98FAAA3E67CD5EE73
+:10AFA000C7FF8C761BCCFF6CEEED5930CC7B7B4E13
+:10AFB0001C9EE6413A993D42F37F26035EC4AF8E64
+:10AFC0009754ED56A5F8DD169D9F4E697A66C99E89
+:10AFD000D91BF261FC9647DF29C6F8718C71FAAE75
+:10AFE000FA29FFFD9F2A6F0ED19B0BE9330F9B9827
+:10AFF000EE7988B11759127D5FFB8887E82408F63F
+:10B0000090730ABEE1F45A85F776227DBFC0DBBBA0
+:10B0100034FF36F2C8ADBCFE9F1DB233487C19B474
+:10B02000D13311B44DB1B867CB7CBF5887B1FC8127
+:10B03000BDB718E5CAB5263FF403C13A3FAD71C4A8
+:10B0400048C2C712459D8E79004B5978038FDFF2B5
+:10B050007B7BDE953A0EFD10F97D8FC06280A7558F
+:10B060007F7CE0DF518E5DF7BB3BD3518EBD2775F2
+:10B07000E4E0782BF7B6A5A31E78578AA563FBF703
+:10B08000E25C9E0DD29723044D0EABE902C8E4D5D5
+:10B09000446AF0FF257D1B6E8671FE1BF08C7CBF21
+:10B0A0007ADFA7543EA4BAFA5810FBED9D8E702C9F
+:10B0B0005FE46D6A0EA17F69E4CFEB7E79678E4213
+:10B0C000791EB1020D7F05D86EF51E3BE5F9A21F72
+:10B0D0008FC3AC617D343F73FB355D6F3A505ECBFF
+:10B0E00036D65778E1E0EF60213990DFD6ECDBF21D
+:10B0F00091988ECFF75EC1DF835A63B24F9769F2A2
+:10B10000DB4CFF5D26BA07FC507C210670F19F6383
+:10B11000E272BCE5D7778F7F03E07B7FCF53E9F8FE
+:10B120007B133AFDEBF73C9FE86A5CE818E21EA14E
+:10B130000F343EE9D70F9A7E52F60360B9507C84F3
+:10B140003F57DA13E917C27C5776DA4348F32B1FCF
+:10B1500010552FDA552F3BC91E59F9C049A2DB956E
+:10B1600082DA27909E63E928C7F5F55AF1C0DFA679
+:10B17000A39C5E9127B299C08AD7FDFE135E1FE89B
+:10B18000DC0DF5573CF8C6F41F6219E489CB62BDAB
+:10B19000A675753B7ABD16EBD5F5C6748CCFB7FC9A
+:10B1A000FA1FB41EEFFD4560B92583DB2FEBFC1BB6
+:10B1B000C5C1DE8785F167727CA1BE59D3252E7289
+:10B1C0006458AD5F62D6C395F49DF2C2CFB48E1DB4
+:10B1D0002318D78F7F7CE0DF1E063896BDE20CCDAA
+:10B1E000C471FFED86740674F08ED4C4E9FE676DF9
+:10B1F00039A8BF97D96339323DF9FB65BBBE47F427
+:10B2000078ED5FBF97A3ED37E4D9481EC4F2709E76
+:10B210004B7F3A8FE6790D8B103D2EFB19BF67F1FE
+:10B2200013F0B3ADFC84A90AE71B27BB7EFCCD015C
+:10B23000949B78670BC0E160FCBEAEE778FEBB93E1
+:10B240005D95916CE77A146ECFC558FC35B43BD749
+:10B25000805A46B9F6FF003503B31E008000000097
+:10B260001F8B080000000000000BE5BD0B7C54C5DF
+:10B27000F5383E77EFBE425E4B5E8457B8791224B4
+:10B28000C485249040D485400C0AB8404494884B2F
+:10B29000C010202101AD60A5CD860002C53628551D
+:10B2A00014B40B8245451B31086AC08D2886EA1705
+:10B2B000438D165BA18B2008045810EAFA2DCAEFC3
+:10B2C0009C33F766EFDD243C5ABF9F4FFF9F7FFA08
+:10B2D000A9C3B93377EECC79CF9999B3E2814BF911
+:10B2E000BF8C62ECE1787DA5C9C25805D33B3D66B1
+:10B2F000867FC215814A493F189FC35F0263790761
+:10B300004675F3A4316662178CF767327611EA9FAF
+:10B31000B36ADE6357E2193BB1D1D445B819CA18F4
+:10B32000565A07EDAFE0DF6DFEB25482CEA3A9F905
+:10B330005F18F43F97BE04FD6C3991BF0EFA65B1FA
+:10B34000220B8FE5F073303E4B71486578367CAF49
+:10B35000E5A8B107D43BA3742C19C7DBFC0DC1CC05
+:10B360001A2D617BA5FF8A9D26E656C603FFAFD83E
+:10B37000F48D91613F3AE6ED35AC7D3D6395E9880A
+:10B38000870A162EAD84F284D19BFF2E7E07BEBBAA
+:10B3900019BE53B206DAA7AAFAAB3FF937968EED7B
+:10B3A0008DFEE7F1F8DFC58C65412116853B42181B
+:10B3B0009B8938CC693FFF855F553FFE81AABF0C52
+:10B3C0002934EA7830FC63081B7245F4BFCFD603FA
+:10B3D00092BAB77FFFFB2AE7E31F18F06D27E1B1B0
+:10B3E000CCE07A09F154F6A5C9EA043C96BD76C9C9
+:10B3F000A88B422A326F7257C64E6FDDF3C57D307F
+:10B400009FD37586A831F4555B9810E3C77BE9B6E6
+:10B410006FF2D7417B03E03D08E839B7FE7BA30E0E
+:10B42000DAC7E631AF09C67F3ACACED800C49BE17D
+:10B430006B8F0A6F79F0DC1342E3E8A98BC5D2DD8C
+:10B44000934139378A59DDF0FEDC16D12A21BE98A6
+:10B45000779925A4FDFB15754703E8A2AD67CC6B72
+:10B46000B4E377EB7F735E0C53E35DFFB5478577FD
+:10B4700005CF81789D8A78EDEFC7EB2596160E9F54
+:10B4800061A75E99D3C791D61EBF0A5ECF563164BD
+:10B4900072FFF33E12E159DA091FEA06750D72C90F
+:10B4A000D8174C85C7D9AF9E21FEFD67779189C01B
+:10B4B000377337FDB00CF90AD0EA3501FFCE759D20
+:10B4C0002778A9CDEC650437160AE91DCD5B8BCF33
+:10B4D000C0FA78446AB49FFE86C5CC190AFD7A7713
+:10B4E00089AE8D30B47392372C02E6B734883D6054
+:10B4F00087F29C4586BB2A307B601A8CF39C33DD37
+:10B50000E2C4F782D8E43AA0CF39BB37AC6B887F6E
+:10B51000DE471AC43009DA7B5CACA02EA43D1F3292
+:10B520005643DFF7B0CEEAAB491E4689975FF7C0B6
+:10B53000F72E38F5CC04DFF3547FFFBA07CA637ADD
+:10B54000B305F134A3FA9E30A683EF3724DE351914
+:10B55000DA3DB80FF047D3B319BB037EA7F3A9B305
+:10B560006F99F3E95C989F189AB9F75D78BF04105A
+:10B570002B02BFCE58A5C5CF6C660F77C7A3DC1AC8
+:10B58000FC7C42FF7519DDF0DE4C4748E54AF86E59
+:10B59000E97A6DFDEC86D3C45FB303F8CB81FCD5AB
+:10B5A000BD3D7FBDA2C8ED403610F96B9418A24393
+:10B5B0007E3ED724BA4CF0CE852506B60CE00B5B58
+:10B5C0000517837E2E3440238477729839A3896FC0
+:10B5D000153E57F0D68AFCD7B73D3EDBEAB71F1AB7
+:10B5E000FC1834297BEBEFE9EBA06C7DEBCB947777
+:10B5F00011DEF1D7B8BFB3F6EDF376FF3095C6B5DF
+:10B60000DBC4705CE7767F14F718C2EF98ACC8B75C
+:10B61000E7169B6C0CF5DDEE505732D6F7067E0030
+:10B62000BAD7ECFA3E1DF53D634B888E9F4B462AF8
+:10B630002F34FCEBB080F3683049388F8ADD80040A
+:10B6400078BFE29D2017C3F7777D3FD811F2F3CD85
+:10B6500067AE9139883F43D9E46DC8BF5D990DE766
+:10B6600053F16ECE8BD5F0FDF2FA46E374A8CF7B92
+:10B67000EFC774D447E7B6351A515F9D35785E60E1
+:10B6800056E4DFFB6B0D80E7B3A1D0590FC61EDD7A
+:10B69000F0BCDD19D2115E381ECE011E705E80979F
+:10B6A00052575AE7F8F8FEBF161FE7A7E2F7CB1A82
+:10B6B0008630315E8D17C1C69F87BACC02CD9F3FC1
+:10B6C000DFFD7D3A0BB9F67CA3E38D24EFFF7F9974
+:10B6D0006F46FC7F2B7D39BFBF2B4934BE40BE6F08
+:10B6E000CFD73B1E21F8F5502B8DF73AE57DE27F51
+:10B6F000EDFCFF6FE83DEFBF76BED7A2F73E99DEC7
+:10B70000A11613EAAD5D3FC6B11B9877EDFF47E781
+:10B71000DDE6FFE8ACE64C18DFDF98EBEEE10279FE
+:10B72000251DFA23BBE2B5EB8E71B25F51C3BE1E7D
+:10B73000390DBEEB047F02FDFD9A90AFF52D003769
+:10B74000839F80FE0543E704F0D05C38D0B512ED4E
+:10B75000B6BE925900367C319DE0C9C53FE833A1A1
+:10B76000FDDDE0E761FBFDD59E19D550BFBFAB4EB7
+:10B77000AA01F82EDBC4E47A802D3D440BAE636A47
+:10B780006C19664935BEBBB2B5EB91FB02D615F715
+:10B790004CD6D64F621BA3F5D0DFA4520373C194DD
+:10B7A000EE0E68BF2EDE42F8BA87552EB584DC381F
+:10B7B0009E4ECB78AA61839A24C48B4DB46E66EDFD
+:10B7C000F1C6106F8897D80CB6D28A5FF1E85B009B
+:10B7D00036C9FE15FC913CDE1D657E09F16462F3FD
+:10B7E000D923D0DF25495F89ED4D0CD68D7CDCB4A3
+:10B7F000DE0CC41B93D79F26990477D91E628867F5
+:10B800007CDE2756F33ECD3B10CF378ED7C5C94FD0
+:10B81000235E0B43AD2EE40BDB8BD17AF85E0DE09B
+:10B820005910FCF854F0148877F43969FD27E35B6C
+:10B8300029D398772AFA9D612CCCBA12FA0F33F7E4
+:10B84000627A3E0FAFA93B161686EB357104AB5BEF
+:10B8500009EB3596AD6F6D9B5702D5BB1F83F76A19
+:10B86000E6C1FB88D75E4CB213FF1759707D2330B9
+:10B8700007BB12ECF73F3FCD06FF339E4AE2DB4F9A
+:10B8800037717FF352EE9BCB0682283198B3733029
+:10B89000FAB9F29FD35384EF894C67C5F52FB3D91A
+:10B8A00024CB60EC97D1BA263C5BA759FF76B575DF
+:10B8B000D1E02DB220420347DB7B68DA779B9CA066
+:10B8C000A9EFEEB84953DFB3749006EE5D3954D357
+:10B8D000BECFC2111A38DE7987A67DE2F2091A3886
+:10B8E000B9F63E4DFBBE6B8B35F5FD5CB335F5FD12
+:10B8F000B7CCD7C003EA7EA9697FF3CEC59AFA8197
+:10B90000EE959AFA8CA627357056F3739AF6430E85
+:10B910006ED4D4E7785ED1D40FFB769B06BEC5FB10
+:10B920008EA6FD6DBEF735F070F6B1A67D9EF9339B
+:10B930000D3CCAF2774DFBDB638F06C43B2CCE87F0
+:10B9400032518D013F819C8D964E6BDA83C75C84AA
+:10B950007C6390F9E1CED4EF34F563ADFFD2F467A8
+:10B960006495400464AB5A2ABBB03A2A43583395D5
+:10B97000BF1EE0B027A05CBCE05C864CB53FE7FB97
+:10B9800038B4239FE63EE444BEBB14CB2CE24018FF
+:10B990000FF3EA91AF75C1977B395471A3309FC8FB
+:10B9A000DC19C0873E814A8B2F98B923810F7D41D6
+:10B9B0005446F822E979A4AF2B9551BE9EF43CDAA7
+:10B9C000D79DCA185F2295DD7CF154C6FAFA53D987
+:10B9D000DDD78FCA1EBE0C7AAFA76F2095BD7CC382
+:10B9E000E8796F5F0E9571BE3C7ADEC7379C4AC915
+:10B9F000772795F1BED15426F82652BB44DF782A2A
+:10BA0000937C53E879B2EF5E2A537CD3A9ECEB9B8D
+:10BA10004665AA6F0E95FD7CB3A8BCC9F710BDD7CB
+:10BA2000DF378FCA34DF63F47C80EF512AD37D3552
+:10BA300054DEECABA6D2EAFB0DB51BE85B41E5207A
+:10BA4000DF53F43CC3B79ACA4CDF3A7A9EE57B9643
+:10BA5000CAC1BE17A91CE2DB4065B6EF552A737C4C
+:10BA60002F5339D4F726BD37CCF70695B9BE77E901
+:10BA7000F92DBEB7A9BCD5B7879EDFE66BA4D2E689
+:10BA8000FB989E0FF7EDA37284EF337A9EE73B405D
+:10BA9000E548DFDFE9F928DF9754E6FB8E5279BBF2
+:10BAA000EF089505BED3548EF69DA4F20EDF77F411
+:10BAB000DE9DBEF3548EF1FD8B9E8FF5FD40655BE0
+:10BAC0003C21D710A017DBF49FEE0AC67942223A38
+:10BAD0008CB7B5BD2FEBE3D5C12F308C7B8CAB146D
+:10BAE000689DFE4CF0D90F484FE69824849762D3A6
+:10BAF000EEFC3B9618C6EEC77F488C35E69868FD8D
+:10BB0000BEFF57FCBD65C38F7EF510DAC779268668
+:10BB1000F63150FF2ADFFD347B4F34FA61CB0679D2
+:10BB2000CA30FEF244BCA708CB860481ECC59B72E8
+:10BB3000F94E828ECA3503B8FD2E9A971C4E71AA13
+:10BB4000A8EB9BD7FFA2DD8FF6B77F2189F7C34211
+:10BB5000BC71642FAEB39FEB6DB7D4FCEB3F605C60
+:10BB6000C756A36741B702ACE7F6DEF955A86B33B9
+:10BB70004CC939A2F28F18E7712E36596AA210CF3C
+:10BB8000BFFE13B65FC898DD04E51F121C9F254059
+:10BB90003FDF07C5B9C038C25FE59009A13F6BFF21
+:10BBA000FFF83FEEFF34EAB5CEFAFF87CC476312C9
+:10BBB000EDE7701C4C6F4B473A8C58DC5D8C82F77C
+:10BBC000A7AD122CC847D3970CCC47FE18C46C14F1
+:10BBD00027BD3F923D60EFC02FEB96A893FD0BC9A8
+:10BBE000780F8CE70CB81CE84F144B8CF8B2B841B6
+:10BBF0007039290E6D0B1B0BF6BB54E6DBE2E5D565
+:10BC0000C605D0AEBC3B8F9731178F9799E17F283F
+:10BC100047736A37ECA570A37899E26397D0EF0574
+:10BC2000D699B3A57D3C7601C699771A2D6837CA97
+:10BC3000EB02E2B90171B3C0789925518EC75A99C8
+:10BC400095C7B9434AFE8ADF63619218756DBC28B7
+:10BC5000F1598949DD108FA3C4B4705CC75C684A90
+:10BC60000E67584A52376CE7005A344329E81D439F
+:10BC7000F039E0D38974F55607BB36C2B88E803DE3
+:10BC8000913270408E21468C47FEAD375B2910D52E
+:10BC9000C80FABD824925FEF59FCAF6518C79E154B
+:10BCA000AFA775C0348CB9E3F8DEEEEA720AD42F80
+:10BCB000E1DDFB9A407157279B1F8B71DDC07D141E
+:10BCC000FBD2E871D948A7E55D079990564EDB177E
+:10BCD00049312AFA2CA921BC16C74672FAEC3490D5
+:10BCE0005F0BF4A946FACC72198EA9F17C895D36F6
+:10BCF000E27E4CF1F2F344AFD97E7A69DA95D73619
+:10BD0000125D814E9AE71595279438FAB1ABD12B85
+:10BD10003F805E183FBF072B1745927E285AEC4E96
+:10BD2000AE54F169E0BE44D28CA1E1769087821EC8
+:10BD30009C1E4C6F8D417A7EB72A8BE81548A782EE
+:10BD40009FA6133DD8DF42D96618CFFD89EC810943
+:10BD5000F0FC0139FE7A7FCDE8028C974F4DE4EB81
+:10BD6000934F61FD6983F5E7812A33B3816AFEACA5
+:10BD7000CA42F0E755B104FFB54AA2F2CBAA542A51
+:10BD80008F1959699D4ABE80018C38BE192857D138
+:10BD9000582AEBC3876331EE5EF0D367593A52A954
+:10BDA0006F8E1FD51BD7178004157E261706932F7D
+:10BDB000ADC01E83253F16F5C70AC1BA19E96A1F2F
+:10BDC000A669CF5233FC30DA2F3DE727E08B8DC8D0
+:10BDD0007FF78E89D4B49FB4BCA7065E9428D1F8AF
+:10BDE000C617246A9EDF57D45F034FF3C17A1E3E05
+:10BDF000952415E89CD0FFC54F0CC4CF172B877432
+:10BE00005BC061E2BB40FC1F333A298EE0DC68B2C4
+:10BE1000A2FEFB3688F3F7B79F8BAE1A5AF73A2982
+:10BE2000EE72C96C91709DF2C874671CD63F120CFB
+:10BE30002EF940C497C8307EC05E3191FE9CBE563C
+:10BE4000604E94112FA3F5F2C32F9B689E33D68AC0
+:10BE5000CC91417C1287ED1F8E96A8BFFB13A53AAB
+:10BE6000E467EF66937523D44EF7C8EF0B83681F22
+:10BE7000A47CFE5F0FEB511E529AD371AD5514EFA7
+:10BE80008E463DD8BAC940FB5EE5E286921020D1CD
+:10BE90009C27DE0CCB9148FC08BFA70E446FC0F96D
+:10BEA000FBE7EBA2B8C8377DEC1B13419F9E2A71BC
+:10BEB000A5D33A79118FC7B7C70B233DE5D4854980
+:10BEC0009B71BED31D432C696A7BC8F7FDA61BACD2
+:10BED00031D634E4FECCEEA8078EAD321460DC051A
+:10BEE000F4FE38C4D3B1DA48DD4A5A546D23FE2A31
+:10BEF000D64B46F5778B5789366A0FFA7D3CDAEBDD
+:10BF0000D5A2830D41B896FA772E171CB8EF94C4CA
+:10BF1000B2BB21DF3E346F48379CC7D44EF619CFF1
+:10BF200082CC3854FB58B3778976177E2FD3A32F52
+:10BF30001CA01E3F8F03253996F79A8F747A23C869
+:10BF4000BA5242BD9A188EEBD4932D6037E01BB3E2
+:10BF50006A1AD32560BDB28776101D4AC7D5A5B829
+:10BF6000E1F901B3E313C4E3B7DDEB9E1E8671A2D2
+:10BF70008617E39C680717F2FDB5D9AFCCEAA3F6A4
+:10BF8000E7DBFB132C56978D853B4600BC38249687
+:10BF90008FF89DC2EAE4F8858BC627A1D2057C58AC
+:10BFA000CAF8FEDB749D75EA679988FE500BD2458E
+:10BFB000E9EFA881C7B9FE21CBB362877B24713F2B
+:10BFC0006BBA8ECB1DDB2D109F02C1BE4852D9CB60
+:10BFD0000AB68AEC656C4F91E1BEDDD9C408592FD1
+:10BFE00070FB3707ED1FEE0B5B04928FB22D269787
+:10BFF0000BF82B3589CBE76CE36B4F0FC2E6F1955D
+:10C0000046FCCEAC7A813D074D4F195C25CDB82F4B
+:10C0100065D9B02482DE33585DC8A7B27E3783422B
+:10C0200040BD3013FF09F5E56B04979BF8C54E76CC
+:10C030006806C64D70FD8F7A5EA547DAE9F700BD48
+:10C04000FE200BD8D7AFD5DA177B70A819C7397B7C
+:10C050000DF76BFDE311D915C05589C3B5771C8D5C
+:10C0600057A0B848E0F767E2F870BC303EB7F5C6B5
+:10C07000C75362E5725A562BB85C1D8C4FC16B7862
+:10C080002E93D03ECFD924B8901F4745CD23FCCE68
+:10C0900006FC46225E9DF6B07B002E014672517C66
+:10C0A00085E3BF623DC73FD0F92F6ABBFB4D94D7F4
+:10C0B0008878FD06ECA713F7032BBF27BAEF05FA24
+:10C0C000A2FCCE7AC365C48DC8D3AC362C04F97EED
+:10C0D000ED81BDB82CF866CD9B31B87E2D8A7027D6
+:10C0E000EB406F45B2E8270B6EF1F35FA0BD6E67C2
+:10C0F0009703F0E36476B243EDF0645ED58CFBDE2B
+:10C10000EDE827C7C51EC47F017E1EDC24DA82D27B
+:10C1100035EDE4F3084EC25BA9D34B7E4229CCB384
+:10C12000C6824F9DF9889707AD8CF4EE8D8E3770DF
+:10C130009C4C2C22FEC4B81EFA21FFEE7803FD8F22
+:10C14000494957F73F02F548A0FFF195C1A65B8C1E
+:10C150007EDF01BE2F7E51EFEE8DF27B312AC10AC8
+:10C160002DFC7A347A5037D4F38A1E2D91ED96D275
+:10C17000EF8368AF003EBEF6CD30A4BB42FF9968A6
+:10C1800027D2FC76E291E9D03F7CEF911D41D4FFAC
+:10C1900099B160A7A0CFA2E73F0A632AFDF7781FF5
+:10C1A000C7FC24D4278A5D1337C45980BF147D7916
+:10C1B000AD7557A7F30A099857A8765EC538AF0C36
+:10C1C0007F7FD3E5797DBD9CCFE7E82A3EBF19ED9F
+:10C1D000E6C5EDFE232F9AAC4EF20BDCD12887DFAB
+:10C1E000BE21B21AA22FF71B2E99819F0662FC6610
+:10C1F00015D9F593D14CC2B84EA7F67BB589FC8210
+:10C2000059DBF97EEB29617837DAF8FFC01DF62893
+:10C21000CAF53691A11DF28FA7CD6E3F9BA4B6DB68
+:10C22000D789378CB3A23D9B0BA843BE9FDBD08D33
+:10C23000E1399755C3599D48FBF01ED263C04214A3
+:10C240009F063F5C136F3031ABD98C74EA24FEFA41
+:10C25000CFE4F353E7133EBC29887FE5FB155DDC93
+:10C26000866EE8D7BC21905F53FEF0F0B0E10CBFC2
+:10C27000C3E3663B92B89D7A07F51CCC4BB0555290
+:10C280005C0C7C1ACBEF705CEB797C98BDCFEA102C
+:10C29000BF0853FC58C7E7214816563488C7E5CD78
+:10C2A00068D7427464D702F17042FE4EB9A823FFEA
+:10C2B000B7CCC8FDE073023FFFF1916C1F3F4AE22B
+:10C2C000EBCC4F92783CE11CFA81D0EFB95B4CAEDD
+:10C2D0006A01DD563DAD93F5B92617FA337A7388B6
+:10C2E0005B4C47F4EACFB6C933E06B2A6B36203D8E
+:10C2F000C765CFDB82F339DC8359C4AE546DC77D8B
+:10C300008429A41918DB6FF8EA438C473AA1AD08D9
+:10C310006B8529D9277A63FBF508C3FC0F07D57D08
+:10C32000887196C3F17A86FB02CE5D26B2FF861134
+:10C330009EDE14A7ECC258CD408CC7EC598A7CB461
+:10C34000373632D502ED1FD077B18A5CFF8C3C8F37
+:10C35000E32D15F8FECD124F16D2E766B6C472DC97
+:10C360004C5B0BF55722AFC63F7A765CE10318535E
+:10C37000D908F8C750C6192B9BF0A98101AF045FFB
+:10C38000DEF4C88435B9B869220D403A972578F5AE
+:10C39000B89FE215987723E0E1EE6CAFDE86F4B249
+:10C3A000B1BABB807FDDFB9880DF4111C0EFDEE3D7
+:10C3B0004E18857860A9120B87FABBF412C1BD0A2A
+:10C3C000588428EF1B601CEBE03081E8A0334B065B
+:10C3D0009CB7BD401884FBA2658BAF6F9C61C9D52B
+:10C3E00034CE329D8EAF671FE5EBD929CE23A3C88B
+:10C3F0004FCA6502F26145449D81D6D1202F38FE97
+:10C4000081D08D1A7F53F41E3EBE52185F0ECA456E
+:10C4100012F1F17D9502F99315C68EE31A3D9295BE
+:10C42000759745C2F673E05FC8D7731A7624E3F7B1
+:10C4300056099C0FE6287CB6552B97B9C9ECAA7C07
+:10C440009D93CCF93A2799F37572DBF7EAC8EECEE3
+:10C4500069F8E820AE2B3BEBBFDCC4DC84975D269B
+:10C460008A1F083A6F12D1051109749882FE24B808
+:10C4700088439223B89F2EF36709FA1F8958F2B8B0
+:10C48000880E9427DAC3D2DA178D88B4C0F347E058
+:10C49000F8D039A0D99B029FABE22AA246EF50DC2C
+:10C4A00053307A67E078845B83ACA88FA718EB6879
+:10C4B0005D1ED8CE50CBFD2CC372EE67D1BE1AC024
+:10C4C000A655DCCF9CD2CB3B80919EB3E40BF1AC64
+:10C4D000CD2F2EE19F86E7651ABFD88471048C7B2F
+:10C4E000ADE5FEA05EF65F8B5769FD85294B54FED6
+:10C4F0002275EB2DC7F11A160553DCC584FE84CADC
+:10C500000FF8876EBC13F5B033414FE72F0D2CD0D9
+:10C510009FB0331ECFE4CFF5B29F383AD9A0D97F70
+:10C52000738E60A9888722D44389A86AECCB319E98
+:10C53000778185D662DC6C94B888E27F45D5FC5C57
+:10C540005A60FCEF42E587CF637BACC7E70BBAFCD0
+:10C550001487FB9BB02CB50BB782BFD1E5F0250744
+:10C56000CA07282AC3508C03EEFF06614117CE8408
+:10C570006CFCBEFB79ECDF69345B506F3D131C46ED
+:10C58000FD2C5C28507C788985CBDBA1AF4237A29B
+:10C590009E52E2BDCB8667ACC5734B359B1B27987B
+:10C5A0007BA37A60746E8939F7FEC506F329BC0C4B
+:10C5B0007243F047136CE1C0E71F7AA79A014FCF8F
+:10C5C00026374DD0839C9CFBBDF705845F4D3EC054
+:10C5D000E127BC7141086FFE9CC3D54A7F9F4FC0C5
+:10C5E000FECE3DCBE1E550EF84EF17A17EC3790F7E
+:10C5F0001568DDFF8AEC7F2BF19E22DDFBBC1CC1A0
+:10C60000DC683FAFD5AE3ED9FE0AFA3B62E8B150D6
+:10C61000F42FDEEE6B7B05EDF78E44FB53C948AF7C
+:10C6200016574C34C6B174AC19E90276CCD6D1BEDB
+:10C63000F42B493C4EF3568A9DDE57F005FDACFFC6
+:10C6400077FA1999C2C7A5EA67F3BFD34F78DF76A7
+:10C65000E3793D39FAC6FB9917D08FE2B781032CF5
+:10C66000A19EF2A6DAF6E1F8E6FCDA36A21EF5CFD4
+:10C670007E91F8F4BBCA1D2968F7BFDB6A8A44FBC8
+:10C6800037E7F5B7E34A308E20FB45A71BBF344A96
+:10C69000F0FE5C9FC86CA0A72B7C029573EB1B8DF2
+:10C6A000F96978AEB6D198A71A57993C4EE074FD57
+:10C6B00004951FB33F5927EBCDD554CE79FDA41E69
+:10C6C000E9394757771CCF1FB3A13CEE1538BF1D82
+:10C6D000B2DE3D8CE70D3A8803B4C8FAB9777FDB48
+:10C6E0006788B7B7509F030CE6CAD111BE7AA5F090
+:10C6F000711475E17A3EABC55AF219ADFBD27522C1
+:10C7000094830F561A8BE1F9C1C41187105FEDE3D2
+:10C71000905E1E876CE071C8A288E687C198B16EF2
+:10C720002F5D7CD20CEBB83B9F91E503450FF44B9A
+:10C7300081499197E0892373799C0BE1FF4D363C49
+:10C7400085E7089BBA34FFE233B40F2B42D94690F9
+:10C75000B3FB8784C66D83714C77860B603BD970C1
+:10C760005368CA3468D79A30BC5B0AE92746FE6131
+:10C770006B82FD02CED7131FAC036784398C3C9EBD
+:10C78000E5F8B348F12C477AB0C3D501BEBC323EC0
+:10C79000BBA5F0FD9D261D8C73108E839FEF85BF7A
+:10C7A000B86D186F5ADC4740BE53BE3F2671788C77
+:10C7B000FAFB6312ED624AB4BA7D38C3F6D73B0E7A
+:10C7C00096C2C71193C2E965CF05FE52E9FD092360
+:10C7D000833570E198486653AFEF0A7B6AE0C9453C
+:10C7E000899AF6F7CDE8AFA91F6B6ACEACBC017F82
+:10C7F0005F0C4B0DA7F57F165F871C6AB8F4C51454
+:10C80000F46337895601E6356BD7E62F8651EF1270
+:10C81000C5B94E3589648FC0BD35AAF74FCEB06615
+:10C820003A77ACEFBA84ECDF9C587EBE7B964BBB6C
+:10C83000FFA1C4E53BDA37417B5686E7623ADA3737
+:10C84000F1C7E3AFBA7F929D22AF8707B1417C3D2C
+:10C85000DCBA1766CAF2763612BD6AF6895664D516
+:10C860009ADE0213609CB7D79B5C4130EE336F1F9A
+:10C87000314AAAFD930A5F35062DE0BD23463C4FA1
+:10C8800075305922FACD6D386F64C017B737CC2395
+:10C89000B96E6E744445A3FD027F757B26F2575D29
+:10C8A00026DABF269DC58EFB6173968FA63873B8B6
+:10C8B0006F0A9565B5A3A9DF72DF4482E7FA8209A2
+:10C8C000FE546CAE3F80FD3C136E417B5EAE776ED6
+:10C8D00045BA944BC119B85F35B7FEC0C55FA21DFC
+:10C8E000B5F07B1D63C5BF6462FDD83E165D4D5734
+:10C8F0001C6F10F5D33CE2EF9968970A705D00CF8A
+:10C90000CBB6E53850EE87D7845A50EE453C4FD62B
+:10C91000019FCE48E1FE9EC1C3C73BCA379EFA5372
+:10C92000EA67A72450BD021BA237E9517F28F330E4
+:10C9300080C1C7F20E5F7F2A2BEAC7EBF15CFC9F38
+:10C94000535F8C423C41FB102C93460E233DF35D1C
+:10C95000E59070D681DE524A93AC87A7A01E86FE72
+:10C96000EE4DB555A11C8E5BE4D19B518F86982D61
+:10C97000B8FF312E7BA054A29A8FF8FEBDB892006A
+:10C980005FC56B40BB3D054AB5DE7EA013FBB234EC
+:10C9900045D1DBD54467C50EB12D4F325C874DE5DF
+:10C9A00067B5DAE46ABE2CD7CAFBCD02F7079CDB79
+:10C9B000795C7F7EAA632DEA91E6E16CF236D2A71C
+:10C9C000CD71E3437FBEF187E99B89CE611649872C
+:10C9D000FB0A4AFDF36DF3E0F27DAD79AC94DB7FA9
+:10C9E0002AB285C8179FDE765BB30DFA6D7C2C23C7
+:10C9F0004354D9A9D753F8F94766F15E267DB13B78
+:10CA000058423D3016F71E32FD7E3F9E87C4B84621
+:10CA1000C56ED3463C0F561106EB7CF8FEF8FE8E31
+:10CA2000D7917E8DEFE55CC47B34365C98819CDBCE
+:10CA30001A865CC473F63633681B2BFA41B63F91F5
+:10CA4000BEED64BCD7D2674923E744A13FF11D0C7A
+:10CA500009ED2DD8FDCC160EDB115F8EE55CFE1CBA
+:10CA6000B21C4E93F9B75896C3697A2E870FAC095A
+:10CA7000B760BCB378913000CFCB3129D48A2AC0BB
+:10CA8000807C9981FCC9F9B2CCD75596E778B91F5B
+:10CA9000CEFF81F239D71749ED1439FD53AAE310BF
+:10CAA000B72BCD990B615C77805CA3DE732CEE9E77
+:10CAB0008972E2E713A305F909F824B644C50735DE
+:10CAC0008D3FE8914F0CB902F18909CA3C151FD975
+:10CAD000DBFC134B7E0CFA554BE2752B99BFFEEB3A
+:10CAE00014659FFCFAF8FD53B97D7108F81114FF25
+:10CAF0000963185FBB1025519C74FE0A1824A060BE
+:10CB0000BEC19D8C7198F9F382280E56D252B92C71
+:10CB1000546A4FAF7B7DE9B4BF3CD19744E5C14433
+:10CB20008717E5659A6F928CC7F4EBDA9FCBB2F169
+:10CB3000B89BC165B26E88C7B89B43A4FDB8DECC74
+:10CB4000F214D929653F8EC7DD309E87F1BDC0FD47
+:10CB5000358CC3E17ADA14A5D3EC13B68BC70DD7A5
+:10CB6000EEA79535FE65B00EEA4FC5DB282EF74DD2
+:10CB70001F47505F98C7EC09AED70DEA7D36198F75
+:10CB8000757A7732DAD1BA4A8E9FBA556201ED379B
+:10CB900031163C5E755EF75A7C3CDB9748F851ECE9
+:10CBA0008BA2B77754D1A1CF36FD7D2DBB532EF389
+:10CBB0007B39F2BBB5BD9D51F835909F15FD6C8852
+:10CBC0006E213D7407BC82FE83A2AF0BF286E5A204
+:10CBD0009D1FF67262FD3B30FFD854470EE2E5B66A
+:10CBE000577B67AE03F80EBD4B6F09B91E7DF88306
+:10CBF00081F4E1A2F18CF421946A7D68E8C40FBF4E
+:10CC0000B5EF8DF1779ADC1EFC58EE1F82BE56F709
+:10CC1000373F75C4F8BED074525F6E277FAE717710
+:10CC2000A6C727F5BD313D9E278FFF5A7A7C565FF8
+:10CC3000AEC703F5366863D2DBE776F5A338D96172
+:10CC4000067A1EED5943B0B4395E75CEBD4BB84B74
+:10CC5000ADD77BF79F3E0BE97A1D7A7D36B6FB7721
+:10CC6000F57AFEF837C8AF823FFB5DB7C2FAE3370B
+:10CC7000B0BE43F85358DFC5B79787403908E47B07
+:10CC8000588FD41F80F1353DDD87E20E2007C4F7B1
+:10CC9000E5C0F728078ABCCCAD1F188EFB06EC1345
+:10CCA00091A1FE0F948382BC57F518A7423D8EF8E0
+:10CCB000DA03328F7A26D04EFCD8D7F12CF28F22AD
+:10CCC0000F8A1C5C9B8FDE36E0BAD450769EEB79DF
+:10CCD00028D57ABE337FE6851BE4FF55D7C93F6F61
+:10CCE000FCFCFCF3C675F2CFB6FF847F9246BE4BC8
+:10CCF000FC83FA13D76F777E6C0D5FC0F987CE2562
+:10CD0000023F6462DCB969706F2BC669EEBCC2FD7C
+:10CD10007AD0E9E4D707FAD55364FDF7801C2738A9
+:10CD2000986AFFBC2F9757F2DB8727060F447B7565
+:10CD3000BDFEDE94A84A6683E70F40A9D61326A459
+:10CD40005B07FEFADF6E90BE4DD749DFD37DFF63F0
+:10CD50003FEF52DFEBF0F3926CE68988CFEFDC7A9D
+:10CD60008678BAD67AC0B096E3B9CD5F77EB15BBBB
+:10CD700019897613F8E39FFF097F8CCDABBB68065A
+:10CD8000BA466D3116EAA1FD243C6B41F10CD31A71
+:10CD90005B12EA1BA6EC0B50BCE35351869DE69652
+:10CDA00091308E3B9F62FE7D03A81F951BDE161FF0
+:10CDB0001198BF7DE41643CB2A8A3FF0F32ACCE1D9
+:10CDC000D1F37D3219CE043854056707C0EB79FBE7
+:10CDD00030BD87F1731FF27359FF8CB3F07D01FFF3
+:10CDE0007E9E37BF2BFA7FF58205F717EECB3D67A6
+:10CDF000C478CED83CCFDE9ED02E654B7861483FBC
+:10CE0000785E2FD07807A7765BE34CA2235B363C95
+:10CE10006F5896CDF74D4C758DF9B60EF87070AA17
+:10CE2000D64EE19F3E86E263F467AA13983193F7EA
+:10CE300093107F7DEF23FDE8FD047ADF6D8ABAFE53
+:10CE4000F7EFC9653657077C345269877161A57F52
+:10CE5000A0C9C43AC1D651DC664C2A9797669DAEEC
+:10CE60009C019E0A53FBAFC1B8D728C6F96252EAAB
+:10CE70004D854E1E4762B680F95E6DBC433B98AF50
+:10CE8000A47DDF7D357CD95215B957DE97E95FAABD
+:10CE9000E59370BDFD83EF601CE1518205FDD4B9BF
+:10CEA000F6A0552C1CE92EF335CB2AB4E5C2FC8242
+:10CEB00098268ED7C6D76C70E1C834F9DE3ED567A8
+:10CEC000AF41FADB756DED399F37086DEFA7EA19B1
+:10CED0007E82DEAF4C1DB206E37E400FAA2738E902
+:10CEE0002A7C5E1700E706C805E330C925EA65C05D
+:10CEF0004F7207FBB74FC8F83D23F0F34DCD23B871
+:10CF00003FD79CC0CBADA9DC7F5B23E371BDDCBE0A
+:10CF1000B98B0A0FBDFC74863F37AE0754F3263C2D
+:10CF2000DD1BA5CC7B52E118985773041B20009F92
+:10CF3000BC943A61CD92DEFEF7B7A44E223EF1F7E3
+:10CF400057D88276FC5E194F5B53EF6EC17A3C7204
+:10CF500082F2569ECDF75F4DF5073A94B705EDF98D
+:10CF6000C789F915CA8991F03DC166C8E4FD2474EA
+:10CF7000809F5FB57FDF16F03E3344DDC8FB327D16
+:10CF8000C604D0AF20807E2303E0222DECF783A1DE
+:10CF900067F09F8A77AE5E1A83F1B32D02DDB1028E
+:10CFA000FD6C14E079E396070A43703D2A4A869E99
+:10CFB000D0F6C32DD35ACCA0BFC6A3FE227D5C4CB5
+:10CFC000FA7A22CA39C1D30B6D3723DF542E8D85EF
+:10CFD000F61F6F99B106EFBDDEB764B50191FEE9AA
+:10CFE0009692357AE8F7DECC3FEDC5FEF4D5A52D57
+:10CFF0006384ABF0696DC03CD607C0CE80F66BAEE3
+:10D00000A1CF9704BCBF28A07E5500BC36005EAE01
+:10D010007D7FDA0CBE7F390DE88788BB96BC7C9398
+:10D02000DAE617B4D92F01EDD9C75A7EBFB386C34C
+:10D0300067531F295C1EA282B72C2854F3AF41B658
+:10D040001753A2ECB68EF8F75067FC931A68D79C7A
+:10D050009A73898719D3D8DF3DA2166E1495F12EE5
+:10D060006D79384DB51FC89614E23E51E7FB158B1C
+:10D070000B71BFE2CEDF29F58B0B6DAAF929EDF319
+:10D080007FBC22E2F7F42F57176EA2FD3F79FF2EE7
+:10D090008297B75DBE128674C9C7F3A358DFC59DDA
+:10D0A0003C5F6DE7595D0ACEAFF1317EDFD05903A9
+:10D0B000F400392F6656DAFF6E0C0F5FF812B4DFFA
+:10D0C000F398B810EDD7E1859174DEA8B01FF7C7CB
+:10D0D000F684F7897910E0C6E0078C18576D7C7CE0
+:10D0E0001495EF8BB6655E407EFCCBB564C71B83A1
+:10D0F000C3092FBDFBAD2AC42D59A99F44787444A0
+:10D10000586276A21FBAD2C070FF8931EB0BC427D8
+:10D110004F98C84F9D56DD9FF67B8A7F3F3EBF3BB1
+:10D12000B42B5E6AA0F83FFCD17D0CC7CA5146AC57
+:10D130009FB1442E9DB753F9DE4F6F7E9C4EFB3A54
+:10D14000229DDBD9ED8B380E92CCBE760EA0FB0A69
+:10D1500047E5FC2A6FF773A4F583797CDD9A44F9DF
+:10D160005298450A9B807EDB4DB601FDA2FDEDDEA7
+:10D17000FB49A4FDAA775B8B63906E43FA717ED95D
+:10D18000ED2B8E2956D9F592337AC2F37B46E961AD
+:10D19000D41BEF75E92D38496EEB2231CE3A43F6B8
+:10D1A0009B814F16BED9011F26F513A9DF63A68503
+:10D1B00078169635FE263A17C7A5BC97D5E2A8C1C2
+:10D1C0007C31865ED220B57F7C6BF2883C9C879F49
+:10D1D000BFFE48FA9CFC6380C7BDFCE21A27DABC9C
+:10D1E0003DE0D7E338A26CF958AF9CC763B175290D
+:10D1F000EAB882DF0F5D2CCB3F6F77080F07C3F7CC
+:10D200000F6D0DA2735F879C7F0F55FBC78A7CCC87
+:10D210000CFBD5E1665A17874B421CF08DBEEAF82D
+:10D22000A3F05EC9F306D29B25CF472FF2623DD013
+:10D2300013B70C03BFBBA51F3F0FD0B97CD407C8E1
+:10D2400047FD55E5A3F4E5370B378574241F5531A9
+:10D25000C847F9CF1BE87C755197CA4918472CD2AB
+:10D26000DDCC6A607C239EFF450CEEB3CC7CDE44B3
+:10D2700074F584861EE7F3EA138FF36AB33FFDB8B3
+:10D28000BEF254E790BD1075E09D81FE16971968B7
+:10D290003D22C61849EF8961565EDF85C52F06BB62
+:10D2A000BC34345B42FA6E4679C8A27A09F92C2F55
+:10D2B0007CF21D78AEE5F0C244DA073B99C9F7C1AC
+:10D2C000663DFA6218FA9F871EE6E7BB6763BE1DDC
+:10D2D0005CE7FE9BFB5E1572BE9DFFAB7DAF67FA00
+:10D2E00005EE7BF173A07B16666472BC30C984784E
+:10D2F0008A1B4878B9DDCCA420C08B18C15250FFDE
+:10D3000028FB5EE22FB97E127502ADD38F55392905
+:10D310007F415E98993FFF25BFB7273E3D9ED13E96
+:10D32000585425ED8345C8789D26303BCACFD1207F
+:10D330006BDCBC34E4BF20A2E7CC17667DF16C2621
+:10D34000D26D6C94269E80FC17ED7FFF44F52D3442
+:10D35000BE1302B3A0BDCFFB43DF91489F46D1F17E
+:10D36000F4BDA4378369FF9C593C4F0C01786635A6
+:10D37000ACB319F24DF7B884347F3F33173F968230
+:10D38000F4CEFB43901BCFDFCC5812B416CF619480
+:10D3900035F07BDED3567C47E77159BCBE12E39C67
+:10D3A0005F2F09E2E7D4EB8710FF4CD3F1732E2CEB
+:10D3B000CE48F1A5B21019EE954DB0EAFE9211E9F2
+:10D3C000A1DCBFF918F50A7CFFB4820FF41B51EF02
+:10D3D0002AE7E859A584F25FA4133A3CE7F5553FE4
+:10D3E000EE9F4E8BB3D279D1F2DF9AAC8BE3399DAD
+:10D3F00045559EB9729D377F2DF6AB63D2760BAE45
+:10D400001F9A4B70BDCDEAFB521E820A3DD31B23EF
+:10D41000E0B9C4F599329E0A69FCEDC44F7A7650A2
+:10D420001F81786CFEA219F96371A8847191F2AE24
+:10D430005607F51B6AB6703B217F17C79E887CE0B4
+:10D440003346201F7C21E84C3CFF804D07F5E71850
+:10D45000AF6FFBCE921569346FB34537A23BF2DD57
+:10D46000F9FCB5F0DEED4C4AE88EF7C456444E9A0E
+:10D470008CF5AF89A49740987E9B8DFEDE6B62068B
+:10D48000AE53A7ADD843F39BF3C640BC41C0A6BD85
+:10D49000FE19D9A739327F79E4736BC500BF01A5A6
+:10D4A000FE266E271C22ABAC2358D0EC572AF5E59C
+:10D4B0002B0C448FF2A526A27379F55FA9DFF2D079
+:10D4C000E618A447F97603E5EF08BD49A2F6C5D5ED
+:10D4D000BD730FC2B88B0DE116011E9539C71A1125
+:10D4E0002EAB150856BE57BEE2F3185D1AEF0F4B70
+:10D4F000938EEFB3FAFB8D8E437B767A6B64DC34CC
+:10D5000015DD4F2FD91186FBCE4783DCC978CED7E6
+:10D510003B2FC88AE70A9578DAE925C9FC3E90A531
+:10D520003914F7AB673C9C188176EEB0C56DC4FA30
+:10D53000C375F178648ED92C965C846DFA9B093E94
+:10D540002D9F23A13FCC1F2870BE29DBBAC79800AE
+:10D55000DF1B24E3E7CC6B47F70E457C001F5950D7
+:10D56000FFC435A7A01D2ED735A7F444FABC2290DE
+:10D57000BF00EB531BE61F998B7C3508F4A1CC57F9
+:10D5800073EB772C40F92C7FEB643EE2F5CC5866C8
+:10D59000C4F858B93C7F583F7EA087F6E5DB36E4F7
+:10D5A00033FEFE07C8778ABD07788901E026238706
+:10D5B000336EE2FCD364F450DEBBA6498CD1FE99F5
+:10D5C0009E8DC47640797E0F4014E5FB6995B113BA
+:10D5D00078DE3DA7FAFCDC5CAC4FF3D777C6378525
+:10D5E000325F14579BC82E15CA78F1ACD81E867CC2
+:10D5F00071E6B53D7B87A25C6C132C4C2D0F8A1C09
+:10D60000C679793DE0EF49C4DFB6F3F998876276D1
+:10D610006BA8843454F0A4C89B82970AC6F1A0E09A
+:10D62000A5422FE349AEBF5BC64319F3527FAC75E9
+:10D6300080B419FB7FEB07DA6F3B338D09FC9C301C
+:10D64000CF8BA6CCCF11A1DDDF5F26CF6FFA4DDCEB
+:10D650006E9659B85D2C8B6252F540E2339B51C9EE
+:10D660002F094DCEBC714433FEE7653968A337CE30
+:10D6700003C6E9D1F17B8281FAEB51197F47AAA752
+:10D68000B851AFCC76423F99280F96A9B8CFC95E62
+:10D690001765FD0D32A9FA6EDEAB47880F41774959
+:10D6A00011B066316C8171A0FFD5DA9BE28579DD1E
+:10D6B0003C34EFCD632C4C07FAE488E009DD89F6B1
+:10D6C000E05191F494324E9BF363A287AD8ECB2749
+:10D6D000F20BC60715390D1CEF3279BC269DD58398
+:10D6E000E782D96281EEAF898BCF841EE4F68E2269
+:10D6F00089FEFE6FF900F7236D17C324816AAC7AA7
+:10D700006C37F7625802DAEF2372DCE1C8D21D6190
+:10D71000C52A3AACEBEC3BCB864848FFBC90838FE4
+:10D72000A11C3D759320F3BF75E442D40797C22432
+:10D730003C2FD514E14C433FAA49C796B308CE8786
+:10D74000FA183FFE405E087F502F3D65F1CBA532B1
+:10D750006EA09B1BE906ED6D5C8EACB48F31378AF1
+:10D76000EF8B5E5B9E323CA49FAA056963A6BF9DBA
+:10D77000722FEF7179DE2423317E7B80FC89F6CE17
+:10D7800024E7310ACC837A7BAFAE7188BF8A10B3AD
+:10D790000E977081F581B07F3D55A9473F9F2D8938
+:10D7A000DDABBE977634C849F7CFBCDD45B611E88E
+:10D7B000513DEF237E9EB781DFDB52EC34FCAD6A36
+:10D7C000E33F78AF34F37C3EEAD73FE698E85E5318
+:10D7D0004C7F7EDEE514AB330E47FBFF6D737E9806
+:10D7E000E45F9FDC72D12D8693BF10AF591F94B5B3
+:10D7F0007E40F25CCE9AE93EF6B4159F8D1D82F410
+:10D800007ED940E70766D4C6939D3BB9697A06CEB8
+:10D8100077DAD26482676D7E90C32B78FEC3694B42
+:10D82000B35E42FFEB68902D1FF9D9BB5AB0E0FA06
+:10D830006AD8E6AC45F741FDB0D03E5D71DC873675
+:10D840001D1D8B743FB45024FD64DBF4D424ACB7AD
+:10D85000ED14F1C618AC672C8B30AF29D3875BD0A1
+:10D860002F50CE17D618B8BE3D2FEB87936D25E706
+:10D87000D3BC9A9A14F497BC1BC01EE1BEB7D15B0F
+:10D8800042E7BB058B7523F0CBB782936066B1246A
+:10D8900054E7E07D96F5941FE75CB2C9827EF2FD05
+:10D8A000266645BFF6FEF77A0FC2A5824D5E578DFC
+:10D8B0008DE4DF55F0A57CDF2BF33D135795D0BEEB
+:10D8C00043A49480FAAD493E377E541EEFC9252FFC
+:10D8D0004F42BFE0E496E408A6C2FB49394FD32C7F
+:10D8E000D083DB3A58EFFD7893127770D1774AE511
+:10D8F00078E03E436D2FCCFB1978BFEBC486203314
+:10D90000E6E70DBCE775C2C0ED47BBFB5E3BB570FB
+:10D91000609EDBC0F12865BBFBFFFD433AF4E315D5
+:10D92000390B7CBFDD7DF2A4EB3B5F8579C9F0BE8E
+:10D9300077D34D8CC63932F8C737515F97D49A2CBC
+:10D9400078FFFE589044EB2167169336A39D314B28
+:10D95000E1B89E3FB62F83CEFF957CC548AE4AEA1C
+:10D960004517A62AFE6075DFDFE502FC60BDC18AAF
+:10D97000EF9F5CB37A1217336D9E856CC6E57326F4
+:10D98000AC93DC16FFBA2870BD347BED1B748FF0AE
+:10D99000E75A2F2971A4407CDFDA5FCE4FDAC9FD48
+:10D9A000B9F7806DB207B5C7776B9583D64567AB7E
+:10D9B0004AA9CCA9DB90D753C2FB14477E3B0CE5A8
+:10D9C00026349CE221AD5595B489777667C665BC4F
+:10D9D0001FFA6E48B805F5C5D9AA85F2E502994F38
+:10D9E00064BEBCA5BE51ECC9A87DC33068BF3B2452
+:10D9F0009CEEBA24D9B2C3D1CE2B740DBCDFACCC13
+:10DA0000EFD4A39CAECA784F6D991E867E67E3BAA9
+:10DA1000C8869C283C9E1B6E417F7BA67CFEE5F859
+:10DA20005AAE6FBE3587BF3406CFCFAC9F1883EB9D
+:10DA3000BA070D5EA315FAB5EE1A1F8671BC6FF416
+:10DA40009E30BC6FFC0DB477A39DD0BB44D4734310
+:10DA50000B18EDE30D75EB99144F5BE6C41739AD68
+:10DA60007A17D2F5B4FBE29E2BC847AD3A8A77010C
+:10DA700066F65C81F6D6D03E14277CF06DBEDE647F
+:10DA80003F76E1F501F7169FE9CFFD9613EBDF1C1A
+:10DA900047EBF34D060B8EF3ECA6CF63F01CCE6C78
+:10DAA000C6CFD77FBB45A079CC067E0C8A47FDC088
+:10DAB000E3A0B341EF9B85F67C98B7A59AF8703642
+:10DAC000F021E6F59E6DE3F99867633E6689B5CB74
+:10DAD000FFD155E6BB39C077787FF7E7CEFBF13B46
+:10DAE000850F03E45EA1BB821785FE7E3E649AFC2F
+:10DAF0008211750387F7647E7DA0DCEF607ACF2A00
+:10DB0000BCA7B1400CADC57C55FBF5957FA0BC2DE5
+:10DB10004E3DDB4CF69CA562BEBC05E24D568C0723
+:10DB2000D6182BDBF2BA607D605E173184BF3F1ED2
+:10DB3000F313C37CBBA6C5D3F72658ACA310DD8670
+:10DB4000280FC505C43C9D8DEEE5D59868DD1CA861
+:10DB500087EA64FADE95C6F5D0FFF4E7E7B5957B72
+:10DB60007F4A099AB137F2FBF8E0884B1234D9D5D5
+:10DB7000FFD0DDB84F3B7E58C42F12E1FB7B5F3DE9
+:10DB8000CAE18C88ED090037F5FFFA6EBCC731FE9B
+:10DB9000E6882C03FA01D5C7EE1E09F0F1FEB67730
+:10DBA000FBABBEA3F40BCF77E3F37FC439DEEF4FBB
+:10DBB000CFBD2548EF734218CFF796E4A538A8F2F9
+:10DBC000DE01811D7E57F0C31E038BC3BC06FF839D
+:10DBD000BA3BBAF3B27B9AED63FE7DED73A4D077C6
+:10DBE000B8CE94F77F7466C988FE9FDD6AB4F2FCF4
+:10DBF0008ACC6E06BFEA2E997F8BCD974792FDADFA
+:10DC0000645613263059AEBD8FD5CF7F6F6FFD8D13
+:10DC1000DCDB634E9E87AF46CEC3D7D93D4AA1E138
+:10DC2000A31FD0BF0CBC3F95F149F35BC827E3802D
+:10DC3000AFD05E643673F82E994FCA778CA57CCF2F
+:10DC4000F30F185CE827CC92FDB12447172641BB9F
+:10DC50004B20BFA8175AC7B953507F9CA862B5493B
+:10DC6000A0B00ACC8E4BFD014F4DF11F515EB41395
+:10DC7000EB6BC2D0EF3903EB8931D04599ECDFB3C0
+:10DC8000CBA2FB36F483E3FB6D5CA9E2B79F643E55
+:10DC90006B8D77C7E1FAC6196FE2F91A2FEFA13C35
+:10DCA000CF0509A3B3308EB4BF6A273B9AEC7FAF90
+:10DCB000B3FB284375230C69AA7DC971FA8ECF691D
+:10DCC0009C51F2696EE2F6DBA4AFA53C5A40CACA89
+:10DCD0006A82ED14578A451EC5F8B0F410C1CB66B0
+:10DCE000310BDD63F5EFD3D17D5085FE36EB959199
+:10DCF000D86E1CD01FF58DCEECD5236C2FE0E753EA
+:10DD0000FA01E1509F28F41F252EFA2DD261BE7C26
+:10DD10008F6BBE50C9618399CEB906EA478C6B16EA
+:10DD200091DE74EECD417F0CF424E55590F5A2040C
+:10DD3000FFA3BC48D91B8CD4ECDA7991F6E6FC073A
+:10DD4000FA31234D9B475CA193E25F754627454F0F
+:10DD500002BD86A5455F3FBD943C65F39FE7F1CECC
+:10DD6000F9CF4F8F1D44780389437F28ED4F44C47A
+:10DD700099F21CD8FA48E263C308BB84FA76ECCE69
+:10DD80009E4C8247B3760A74BE75CCCE4882C37C63
+:10DD9000DD795E25D9DE8FFD63B711189F3CF9D27E
+:10DDA000DF1FC6BCF7637EC3287EAC0B0EA17C13BD
+:10DDB000E208398F8318F221DE63BD20F1DFA1B0C4
+:10DDC000B376F9037444FF267E4E1656794E4E27DD
+:10DDD0007EEF6FFE3E6EE7E70FE7FB8217F00D6800
+:10DDE0007FA150A43C4DCF04A793FF5673B781EE9B
+:10DDF0004730A7ED2FB8AE9A2CF383291616962A32
+:10DE00007A054920AF2AFA3C1EF4DB0F1DD0BF076C
+:10DE1000D65D420FC682532334F57A67D037983FD8
+:10DE2000D6102B5A5C30FE506B0F4D7F76B1CC80F4
+:10DE3000F114E6E07EB4C25F4C6CD5D3BDF95C9EB4
+:10DE4000BFE2EEC9DA7B9286DCF323C9DEE46AFD29
+:10DE50006FFB35F236FD4AE1A77EAC9F9C979EECA6
+:10DE6000FF85167E3F4462F6B58ABCA0FE07EFE64A
+:10DE700019C4CFA42603734984BFD7B0FE82D364EC
+:10DE8000C178409B1F9E04EF45A19134139F635EB0
+:10DE900050F53C312FA81A2F9817540D635E50751A
+:10DEA0007BCC0BAAAEC7BCA0EA7ACC0BAA86312FDA
+:10DEB000A8BA3DE60555C3981754DD1EF382AA6142
+:10DEC000CC0BAA6E8F7941D5F59817545D8F7941A7
+:10DED000D530E60555B7C7BCA0EA7ACC0BAAAEC7C9
+:10DEE000BCA06A18F382AADB635E50753DE6055557
+:10DEF000D7635E50358C7941D5ED312FA81AC6BC59
+:10DF0000A0EAF69817540D635E50757BCC0BAAAE51
+:10DF1000C73CA0EA7ACCFBA98631EFA7BA7D335B78
+:10DF2000928C766C77BCE37FD268DFE95BE2E783B3
+:10DF3000F7033FA31C364DB450FEC21B5C277E9EE8
+:10DF400026EFF7C8FC7B89854CC573E89DBDAFF013
+:10DF5000E7EBB2BF01F66039F12F0BAD457FEE71F3
+:10DF6000BD8DEE4339EBF8FD44A6E77EC00251F6C5
+:10DF70007FE4BC100B4489FC00CC1DAC578DA7ABD3
+:10DF8000CDCCF42A3C4416583470B43D56D3BEDB95
+:10DF9000644953DFDD91AAA9EF596AD5C0BD2BB3FF
+:10DFA00035EDFB2CB469E0786781A67DE272BB0693
+:10DFB0004EAE9DAC69DF77AD4353DFCF55AAA9EFD5
+:10DFC000BFA552030FA85BA8697FF34EA7A67EA04A
+:10DFD0007BB9A63EA3A956036735AFD5B41F72D04F
+:10DFE000A5A9CFF16CD1D40FFBB64E03DFE2DDA9BA
+:10DFF000697F9BCFAD8187B37D9AF679E6031A7866
+:10E0000094E54B4DFBDB638F68EA474B2735F5659D
+:10E01000A7B97FCF6A607D8071CA109E5F63AE9B97
+:10E02000D5A17F7167EA794D7B4314AC17807FCA15
+:10E03000411FA2DFF77D9738CAC7CC2AC3AC78EF5F
+:10E04000DB39A2F20FEA7BDE63AD3F68BEFF4C70A6
+:10E05000983B88D61766B2B7230624907D6CCB27F1
+:10E06000A2DC67675E161B4521212FFA4702FEC21C
+:10E0700012C061369E171AFC20F29F2CE017A1BF38
+:10E08000D9B62ED2C5C7A35D0EF6FBC5BDAEA8F2AC
+:10E09000BC5CCB2FA66F67519EDE5103301E5EF72E
+:10E0A000463EAEB36631E732DC4F54F22CEE0FD26F
+:10E0B000C6B79472B419F0ABFADEBEA0DA5E83AED6
+:10E0C00022EFA3CDADD4BEAD5F39FE25C064E7AB72
+:10E0D000FAFF2DACFFF420D7B555207FE00F3D5956
+:10E0E0006521784D552CC14F574954AEAD4AA5F224
+:10E0F000B92A2BD5AFAFCA26F8852A1BC1AEAA0212
+:10E100002A3756D9E9F9A6AAC904BF54E5A0724B2B
+:10E11000552995AF545552FDD6AA8504BF5EE5A496
+:10E12000B2AE6A393DDF56554B707DD55A82DFAAB3
+:10E130007251B9B36A0B95EF54D5517D03F86F084E
+:10E14000EFAE7213ECAE6A22F8FDAA66823FA83ADF
+:10E1500048F0DE2A0F954D55DF52F9E72A2FD57F7B
+:10E1600052E523B855DE87583440D0DCC753603DB4
+:10E170003BC6FD3DCC5B817918B20D67AF961F376A
+:10E18000900EA7E4FE0D23C05DC238728F948D35CA
+:10E19000AA75C5F201DC5FACD6F1FC2DD53D98A582
+:10E1A00086FC761BE3E7B4B8DF3E13FF25C1D3A896
+:10E1B000AABDB8DE28A9E479CAB3901F53891F3FCE
+:10E1C000B9A1759ABC2ED891687F6600AE43425CB7
+:10E1D0005FC467FAEFD11F4C743C877C7AA1F2C10F
+:10E1E000BDD87AA6C59A821F196B724763FE2FEFBE
+:10E1F0003ED1BA51EAFC7B15F2FD874EEB779FECDE
+:10E2000085F6AAE02791E2FAFB0DA193719F7FABFF
+:10E210008C8FAD03749AB228C9FE2A8EE74472E54A
+:10E220004B0F09FEFBFB77E1121FE47B3C93280FA9
+:10E23000CE4466FB105DF0BBC11144F81EE6A4B2EB
+:10E2400035C1518FEFDF0B0B10841D434D711DCD78
+:10E2500027703CBBE5F1EC96C7A1940B92ECBB1088
+:10E260006FC7926D9AF16C95F3338C63DE17705C17
+:10E27000FFDC75FEB890E8C7775B3C8555529E8CF5
+:10E2800022C6E3298F635E8C287F5E0C65FD50B447
+:10E290008FFFCE11FDA1FD5C104FEBDBC0BC19CB95
+:10E2A00086EFE17930603D86F77F8BE6FD82F42FC3
+:10E2B000FE1E14DEDB5DD0E530E599F1CC025EEDAB
+:10E2C00049793578DE1B0720B027E5D5A07AE1260D
+:10E2D000F87F771C9739554FE3EB42F94E9E09DEE4
+:10E2E0004F796930A660EA8A798F79BC66BFFD3CB8
+:10E2F000F7BBA3BC743F7547A2E3EB013C4EFE7431
+:10E3000006C689909FF03B16179D5F037E320A80F8
+:10E31000A29951C04F1DF81B0ADFCC95EFE128CF21
+:10E32000811F5B11DF67DF1E928A7C53B13B47423E
+:10E330007CD7E8F87D3AE79FE57D41F9F710C4F016
+:10E34000B40D74EF009D71A46F4E28DD3B6814D9A5
+:10E35000C2373AD0AFA1E95CDEF7C7F27C92350153
+:10E36000FB93C6744E77633AE787B1EFEFA33C6443
+:10E37000739B78BC9A657AD2EC1D9CCBAA58F89B0B
+:10E38000A79354F3A8D879849FE7629E34F539AEF9
+:10E3900064F9FB0AFF89C650C78610F5F878FC01BE
+:10E3A000E420243D8BE4E038DEEB1E6792C2EF11DF
+:10E3B000E8F7C1CE627E19C71F2C741E503917387A
+:10E3C00083D9A99C099613F9DEEE5C4DF7E767B394
+:10E3D0003A7A3E377B7A1CC215CC3B3216D747CBF4
+:10E3E000AB3FC470D0C4DAD5A3BAC3BC26B8A67DEF
+:10E3F00088E5F84DC271A74472D43B1DF7B785CAB2
+:10E40000A53DE07BF76D1DBE14E3D6E3444E07F651
+:10E4100031A74311F0B318D17E7E203749E95C6EF5
+:10E4200068FC8ADC142D66363C7FA0DC0F6993A360
+:10E43000EC39FFE8897B38E04F22BF56EC3645D0F7
+:10E44000FA14F3CCA0BE92E567A99EFB974E4C6DE3
+:10E450004AFA93FB1B069B9CCF8B717F648E93AF14
+:10E46000C74E19B8BC9D3A14EA42FE5ED0E5F538B5
+:10E47000920F83221F3F4DA5F33D0CFC8F5BDBFB0E
+:10E480001F6D79667A31F237589C237650A2DF9E51
+:10E490009FD2B90687F1BCFCA3105F7B63F9FA79C0
+:10E4A0000EE6A1C1FAAE7609E3A5A7A2CD745F2856
+:10E4B00030CF1963569A9F419E1F8C6C32FAD32637
+:10E4C00039AE561330DFEF83E268BED27056C7D044
+:10E4D000B1D05B9CD351EE1FE2766241975F3BF077
+:10E4E000FB9E20661186D17C281EEBD4317B0D8FDC
+:10E4F000CFD2FC16EACD163C97B36C9AE811C84E01
+:10E50000C038319E1765B6F2BCAA4AFEEDC0F1DAFA
+:10E51000B4E333C7319C9F4D64DEA0617CBC383EC0
+:10E5200027D083E803F034D5F8A05F17E5FF0996FC
+:10E530002CE88735FDF8108F2F5773FF11C6BF8564
+:10E54000E8D31DC6DFF3DAE337208BC2F817A4C780
+:10E5500013DFD5E00EA28876B62BE9DF0941F64736
+:10E56000900F931C2B7BCDC7B8468EC98AF13B76A2
+:10E57000B9A617EAA91026515EAD71369E570BBA9F
+:10E580005B82FC301EF3D659C80F6855E761630102
+:10E59000F135200BC55727607C8DDF25FA00E3B3EA
+:10E5A00013E5F3CDFDD8570AFE28BE26E2F8285E13
+:10E5B000EDA0719A90B25006619C87E8E0A27904C0
+:10E5C00033B71CCF6E26FF60B5CC87430F32B21332
+:10E5D0004343B89DD87D84B9F0DC57E30F93F242F2
+:10E5E000A17EF7793DE929C013E5037CE7736E57F7
+:10E5F000769F3CDE13F703AA7FD8DB13FDC4DD064C
+:10E60000875881EFE7982C8BADFEB846C3C1101E2A
+:10E61000D791E37CB7C8F36C60CD3515509FDD5DB5
+:10E62000641807CC6A7107A33C638EDA8EF61B73FD
+:10E630002F1A35BF6B61B068E16CA682E3F1E85137
+:10E64000C0EF7FDEE03A775BBAF6F729DB7EF7B3FF
+:10E6500035EABA7EF733539EC7AA74FBBBE964D789
+:10E66000268832DE05C417E88146C4F773E546FA0A
+:10E670005D83C67263778F6A7CB5B3FE49F87DEF20
+:10E68000C77F92DD7A2F4BC98F531784CF8DCE5021
+:10E690008ABB3D77594771B775A55FD3FAA4369BFE
+:10E6A000D1EF88D55E2E263FE05201C34D24567D22
+:10E6B000EBFF9622FCBB5BCCF4BDC0F1EF027FDE2A
+:10E6C0000D847A17FC79775FC6DE067F1E61BCCFAA
+:10E6D0008AE576F0E7B174813F8FE50BE0CF633BCD
+:10E6E000F4E7B17C0EFC792CD7823F8FE5D3E0CFE5
+:10E6F00063BB35E0CF63F924F8F3F81CC69547E314
+:10E700003AC8E8DEFEE2E0B015E86748CE50F237DE
+:10E710003EB50DEAE251D9D95B2FEA3474CE6DD5FE
+:10E72000FEBECDD063119ADF3FC9FEAA87A67E70D8
+:10E730004B82A63EDEA9FD7D9B3E0BAFFEFB363D28
+:10E740004B4704FC3ECE1D01BF9FA3FD7D9B68FB94
+:10E750007D01BFBFA3FD7D9BDFC9F932153AA648F5
+:10E76000AF05215FAC2B9D10CE3AF02F94F2499962
+:10E770001E0AFCD4A3E2E48EE2C85137737BFFFE8D
+:10E7800021D3BE4D80CFF758B81DE3EEEFD974A466
+:10E79000979E5B1B4271589367E849E49FF76C4C66
+:10E7A00042FE79EEF2882E389EE140467CDEB3943C
+:10E7B000DBA73E374BC4CF3D4BBD22DE17BDEDB2CC
+:10E7C000D78AFCF85418FF9D2DE8D7B518FA7B7F3F
+:10E7D000ECE07E18C7792E04F819E5CDED0D4E0258
+:10E7E00038FC8A8EA17E045B4979FE9DCF86C8E7FE
+:10E7F00051AFD07DB870D4E9A097DE2BE5DF4FF1A3
+:10E800005C0E56FB43BFFBE95A7861C4579DD6DFC7
+:10E81000313B01C7EBC73BA84628535829FB2DE2E3
+:10E82000A38CCB4F6DA98EE4E912C813E207664DA5
+:10E830007461CD5A797F12E5434D87B2841538CF84
+:10E84000E7D6E869B76C94B875DFCDF0CABA16910F
+:10E85000B6D9258B37B823FF4E19F73A1B9F5F8433
+:10E8600095E9D0CE45003E5DB49F6DAD56FF9ED577
+:10E87000B3B27CFE5E96CF67647EC0F536C2A3C499
+:10E88000F5A353701CD95C5F033D05BC8F75690609
+:10E89000A3DF11FD7D6142978EF27CAF91C7F182BB
+:10E8A0003CAFF5D82FC93397FB5162D170EC679D0F
+:10E8B0009D911E5F67FBBA1AE376970A79BF7D16B2
+:10E8C0007904C46FAF4AAF80FDF77ED84DA54B1ECB
+:10E8D000678FD266AA57FA93AC2ECEEF655FB32648
+:10E8E000982F1EB215C95EB4527ED4757A3D433B53
+:10E8F0008CFA0CE14B663D9E91603D661D63789FEE
+:10E90000B936444FFB14EBE69E2278B585C361CE41
+:10E91000CA343C7FF1B63C9F30A7936057C07C520D
+:10E92000A407C2D5BFE71A58EE90F1BC5DC6C7DB9D
+:10E930000687EE028C63C85F45FAFD8ECEDE53EC8F
+:10E940006CF657BA00FDD34523FFF81B7BB25DF888
+:10E95000F5CDB87E76DAC92E28EBB6ED63B87D5DCD
+:10E960001D3CF5635CF717CA7CF44CF0B80FB1FEA0
+:10E97000B3D1FC77701A47DFDE5BAD2777CAE3DEE1
+:10E9800021E33DC7693BF430B41F6F37E1C8C08C49
+:10E99000D97AFF02FAB38F11AD6EA05B4B96220FAE
+:10E9A000F66094BBF7C74C6707B1FF02BEEFB4BD7A
+:10E9B00060223D9798FDCE01F0DE5F9AF5E4CFC06E
+:10E9C000F3ABCAE37E19FF9FC8E3F8B38CFF269927
+:10E9D0004FF7A21DE98B7196542ADF97ED885BB63D
+:10E9E00023BB653BD220DB91B7D18EF4C5794DA610
+:10E9F00072BB6C4732473F457ED225CC8B2BA01D86
+:10EA000099CB96C138F361FC6207F6EDAE6C31E04C
+:10EA100077B2823574BA333552038F967A06FC4E3C
+:10EA20005762C0EF78F5D7D4E79933027E076C9828
+:10EA3000A6FD6DBE1101BF23A6B523438F4DD0FAAD
+:10EA4000335FDDA7A91FDC52ACA977E23F60BE5956
+:10EA5000C718CF2F1B9CFB04F24BD671BDF2FBCC29
+:10EA6000B48FA6F85B81FE4F166BDBC7D3D13E9EF9
+:10EA7000934978AE93B6961334F5E43FB518EC3D60
+:10EA8000F1FC61F578E03B3C87D8523286D13E3CC0
+:10EA9000F02FC85396FDC457946F542CCA203FE9F9
+:10EAA000A25EB39F9613B02F661FA9DD37CBBAC6FF
+:10EAB000BED9B19B3BF91DF6D688EBF2C7409E4408
+:10EAC0001CF733C153F720DEDEFE92DBA9C62F1FF1
+:10EAD000E989CF3FC0A6D0CF8E6F1E21BF6B479B69
+:10EAE0007C3882D5FED6760FB7176FB524ECC47587
+:10EAF0004666B4407A30F3C8FC29C48F2D3AFA7DBB
+:10EB0000CE94828A60C4CBF6838B83B5F7A754FA80
+:10EB10008108A5D20F22B232FFBDBEFF07E9D10F97
+:10EB200034008000000000001F8B0800000000007F
+:10EB3000000BED7D0B7C14D5B9F8999D7D25BB812B
+:10EB40000D09B08104260960AA3C36EF4D48C22465
+:10EB5000048C1AC8427804C1304978A48A9AAAB5AC
+:10EB6000D86233211062A4121F55B08A2BADDAF699
+:10EB7000F6B65425A0A22CCFAA5058306844D4052C
+:10EB800014ADA5F7A284D6F6CFFFE73DDF77CE24FC
+:10EB90003BC32640DB7B5B7B6FF8E9E4CC3973E653
+:10EBA0009CEFFD3A134208F94AA4FF8B1F4E0269FD
+:10EBB000047FBE4A81FFA7F4B6A19F5C4D02F6F028
+:10EBC0007686A19D6F185F62685F6F183FD3D0BED5
+:10EBD000D130BE56D7BF2D3473A0E2A4BFC3CFA49B
+:10EBE0008BAF5B1A09095CD53B2EDBEC133D632F21
+:10EBF0001E97D369EA9D97FEB7F3FD25A6F3F1842E
+:10EC000074748A7E5B32BD1E5F42D42C3A4FA7C912
+:10EC10004F04BC9A08EDDFD6C5DA36A23AC6D3FE59
+:10EC20002D9D664F9B44C80EFEDE31BE85037D31AF
+:10EC3000844C329F8DF85EF982A9777F04E69B3978
+:10EC4000904418A75D77F179038D76BC6E6F74914F
+:10EC500080ADB75F8CC9EEF4D17574844C1E7A9B7D
+:10EC6000AEBF248ED07DEF762E76C0BC74BD840CF2
+:10EC700023E4DACD23AA9A461122D1759BE83EB649
+:10EC8000844CA48DEE33EB287B7F96458E734580B4
+:10EC90002B21263DFC2F9A8FFE009C9CA2BF8DC28B
+:10ECA00065D7FB73E2C6D3F95FEA1409ACC7AAD4EF
+:10ECB0003B7CE368BB8BAD4B9B77B25DD4C1A19825
+:10ECC0003874F8283C3B48D7CE3A41D7499FB74AD9
+:10ECD000157100DF4BAD939068031D0D32B487E9C9
+:10ECE000C68F9128DEC6F58D8797381EB6001EE8C0
+:10ECF000C65E8AF254F922C06BCB07D67A7FD8FD64
+:10ED0000660F054A365C4D78CD3A61F204287CCE18
+:10ED1000779A3C00BC3C57BBD810619EFC8FF4F442
+:10ED200099D319AD83171117F4CB07CB8F37ADD912
+:10ED30001336FEFB9E98F8D3D7D05F72492EEEFFB4
+:10ED400012CFFFA9515DB3C742E99892EC663A8EA3
+:10ED5000B82A0949E87B3C212B717F1A1C892B8E2C
+:10ED60006EEE72F0D48ECF5D84AF3E9EEF9D472550
+:10ED700064308527052F8C5B3BDEF7B887B6496882
+:10ED80008608EF7FD0719B18A2EB7ECC71DB6EA062
+:10ED9000CF037FB64AC0D73BFFDC9108F7F7A76FD8
+:10EDA0004D04BADF4FDF1D84FD9929D668DBAADE4A
+:10EDB000E400FA7AB3F308F28F4482374CC882B683
+:10EDC000C9D34687BD9A563990F403B7D7399DEC1D
+:10EDD000E3FCBA87F3EBAE4637E76309AFAF35A67E
+:10EDE000E1FDED8D1E6CBFDCE8C5F6B64619DB1DF6
+:10EDF0008D65783DDCE8C3FB871AABB0FDDB46854B
+:10EE0000D161DA9DA5208FCE275200D07DAD744C04
+:10EE10003747C2E775929ECFAE75EBF96C0A8573E2
+:10EE2000787BB27DB8812F5375FD93BEBC5AD75FF6
+:10EE3000783643D79EF869BE6E7C5EA844D7CEED87
+:10EE4000BA5E377E6669A5AEDF57305FBF3ED189B7
+:10EE5000F265874B40B93C3DAB4ED7BF037E0139CD
+:10EE60006C17FC6A32C0A5B25F791A00FCD8008E1C
+:10EE70008C8F7FC3F1B317F06303BC30F8BF0AF087
+:10EE8000A7ED5700DEF49ADDADEC1E28811CA8C763
+:10EE9000B6356DA0D343E1FFAA5344F9BFB5B10124
+:10EEA0009FDB7FBEB65BC4F53A24C0CB0EBE9EFD91
+:10EEB00016A55B8C87B620AD142E5E5776979EDF25
+:10EEC000C7942D44B9B9A3F3A403E8EDB52F2F4F90
+:10EED000EF69E37E432A27037D1475525D957C69B3
+:10EEE000FDA7E9AD4BCDAF8D03BD1A495F18E7BD56
+:10EEF000FE4B4524741FAF76A90FC7403BF04D5120
+:10EF0000A2ED9C2E6532E06D4F9AE012051C375938
+:10EF100086755F387203DC7F2D6436C1BA0F5C18CA
+:10EF200044601F3BA8DEB5D1716F92D4B51328BCE5
+:10EF3000035D5FEC07BE549D16CF6872F13A52D361
+:10EF400045942B5BC6DA4CC204D0776612180B7C52
+:10EF5000AE203C3BBE4C71C2754B9AC8EF0791DFA7
+:10EF6000C7A7BBF0B9572F64C443DB4482280F0204
+:10EF7000DDA6327F84FD8E87F750B9937DE143870C
+:10EF80008B8EDFD75DEB00F9F25A179B3F7B45C8AC
+:10EF90000170DAFFE52627DCDF919689F3EE1CB7D6
+:10EFA00014ED8B1DDD26A4EB1D63D73833B2709FA3
+:10EFB0001E80DD8EEEDAB5E940D75D666C4B4421EC
+:10EFC00041A0B734A667B774D79223B4FFBC47F407
+:10EFD000039D6593F67D03E0FE90355692C2E06F87
+:10EFE0001E42C8ADEC6132D9A59703255D7A7D62DA
+:10EFF0000D2D983503EC08A067DA9E668ED3F5EFE9
+:10F000007F7765FC4CC00B8537DC7BADFB8EFDE369
+:10F0100040FEF859FB0FC77F621D48AF4DE3D60C89
+:10F02000BF0DC66D71786C12F428E40BDACEED36A4
+:10F03000FBC1DEC876EAD7B1FF1B9508F72DDDCC02
+:10F04000BE3A9FC6F6B3C353471EA0CFBDCAEDAFAD
+:10F05000C9274695C3FB0E50FB09EC8A573C2FC4C9
+:10F0600065823CF38A3A7AA3F0417A39DF49701E0F
+:10F07000FA33601A8543011B42F9D0D77C3BEDDFA0
+:10F080009F6773ADA4A8DE7161D7EE3B683B374143
+:10F090002422DDC937FDFAF5E5FDD4A16BDFFAA91D
+:10F0A000DE2EB11181EB7327CA81BEF867E259AB3E
+:10F0B000EEB969669B6EDE5C12D68FF8B4F6F62761
+:10F0C0005FDA3ED9CAE59A669F6CB528F37D40D7D2
+:10F0D000C15997D0A32BB9FE6D4079B18D104F5B0C
+:10F0E0003A95EBDF1065E0C3F3C7ED08C7DCC766F0
+:10F0F0004C24A8AF9589C00F488C61F680F7F8259D
+:10F10000EC15974AE273F8AB085CCDA743747C2BEF
+:10F1100055F35F810EE7FADC386F5F7AFF41C70075
+:10F1200094FB05A54C2F3CE638887ABEE37DAAE720
+:10F1300005F68E10C5FB6CF805F4FEFB561CFFCAE5
+:10F140007502CA11CD6EA824B285AA3832DDDB6DF6
+:10F15000FE01C59FCF5E3DEE567A7DE5DD8EE1C0B6
+:10F16000BFAF807D80F2A1C1C1EC8318358E2E71B6
+:10F170007B970DF970EB5913B183DFB0DD86744ACC
+:10F18000F9F4FE71F43DDB83CC5EE838CBEDBDEDE8
+:10F190000EE4939D7F60EBE858E1607EC619AB0CEE
+:10F1A000F6F8D6153108E731524CC00CF32D67F351
+:10F1B0007771BCBECDF1BA9FEBAB37B8BEFA0DD8B4
+:10F1C00013A8BF983DB11BEC097ADDC9ED891DA0DC
+:10F1D000CFE8F5C5B3CFBF077C797E7B14DA9D639A
+:10F1E00048DA6658D776A715D76984F33C45CF0728
+:10F1F00073ABF47643F958BDDD70FDA8E1BA7659DA
+:10F2000062AAEEF9A9F1D7E8FA4B9D997A79649E42
+:10F21000A86BCB17F4764385F7063D3DC9617603AD
+:10F22000CA3BBDDF383BDC6F4C063C313F676BD7D8
+:10F230001D88C7ADC753062A6176C2360EE7ADC733
+:10F2400099FEDC16FA22468960477CCAC77DC6F162
+:10F250007186E3E33F46C8BF4B1F0CFCF20593BF2A
+:10F260007DD0B1F6BCF6DCA7FE5303C2F5FA4851D7
+:10F270004226D1DA7FE8786F0CF45F2E5F503A6D4A
+:10F280000D513C7F478C696FA38FAC31373C056DC6
+:10F2900055359367B2101C6966ECBFDA03F2B839D2
+:10F2A000A6E139E8DFD264736D8A073EFAFEAFA0AB
+:10F2B000BD9CB2828D5EFF1435C24F28AB39324CF3
+:10F2C00038FFB316DF700FE84DC137FF563A5EDDE9
+:10F2D00060F53C235DBC9ED80C4163F66DA087446D
+:10F2E000CEF77F1194D80C7A5FFE8580723A4A225D
+:10F2F000A8176CC41700FE21F5F27CE00F62A2FC97
+:10F3000043AF8D99CA50184F6422B9E83CC8DAF46B
+:10F310007D4270DF9F05BA2E0B6950611E5B3D95E3
+:10F3200030949F1F4D5746E078F34C9CFFC569848D
+:10F33000803CA3DBC176D6DDC4D5164B286B2BA64B
+:10F340002F687B3EF5F7E1FD26C732D453EFFDCEA3
+:10F35000E41723D84B3D705E6639130A8B8F18E98A
+:10F36000A783D3C5B6641FCA5FE3F3B900170AC702
+:10F37000AD1F4E1781BEB2EC0364B02BE806C51971
+:10F3800054BE6F3B79BDA326C273D767D5E4660C24
+:10F39000EE6D6705378B354EF4E745D8D716FA3B47
+:10F3A000ECEBE54E5300F07BDE694579D2D73EF2B7
+:10F3B00042FA38442ED80361FC46C80217F88B0283
+:10F3C0006917BEBA269CBEE4FBC3E9EBC58BE90B0B
+:10F3D000E1FC9DB7D210AECD02A32F95D217F4ABAE
+:10F3E000250D485FAA89F89AB390DEF0F9E566BB6F
+:10F3F000CB4625E4B28C147C4F474CF97B0109DFE6
+:10F40000973A13FDB96AEECF55A39C7FE32893F397
+:10F41000C67DED3C3A677808EC89D17387039F7706
+:10F42000800218068BCA9B27EBDA248076E0140250
+:10F43000212B80C03CB03F3BAED3DA5ED62E66E3D4
+:10F440006F79FED10D2AB46FE2FDEA6CD6AFB549F3
+:10F45000FEBC62685B4CD83E09E3E9FB1EF3C8CBF7
+:10F46000006F8FA6CBB7025DE680D142AF9F4D9073
+:10F470006F87F6B20C82FBFDDE04F95B304E6B6FDA
+:10F480001B2FDF19DEDED2E3A7B6733FF556B44B70
+:10F49000DFE89A89F6AC447C3780DE7923C8E251F4
+:10F4A0005B46F5EF071DE4F6FC01EEA7BE09F2E8A6
+:10F4B0002AD027CC4FDDCBFDD4DD5CAFECE47EEA77
+:10F4C0000EAE575EE57ED22BDC4F7A09FCD4ABC082
+:10F4D0000EA9E27112E6A7668D9E5C8A76844BF3D4
+:10F4E000534744F4532BBC7A7D33CDA3D73737A48D
+:10F4F000C519F48B5EDF4C8DD7EB9B52E73506FDCB
+:10F5000092A91B2F5FD0FBA945DD25BAF10567F451
+:10F510007E6AFE473375E39765488847EFF11B75B0
+:10F52000E3723A6B75E37AF1E6433C59D5279D6067
+:10F53000C76D1955C7F1C6EC050D6F1D97C0DB6F80
+:10F5400038DEF672BCEDE678DBC9F1B683DB03AFDB
+:10F5500072BCBDC2ED819738DEB672BC6DE1F1853B
+:10F56000831C6F0738DEDEE4FE6ED6E8DDE89F9D83
+:10F570003F4B38DE368A91F05696281AF0E030E09C
+:10F58000418FB712F370031E520C78B85AD72E3839
+:10F590009361C043BEAEED3D5E6280FFF506BBA148
+:10F5A00052D7AFE16D9A67BE81BEEA74E32E9BDF4E
+:10F5B0009CCCCEFB6BF96D1FB7E3F670BCED02BCC3
+:10F5C000619CC8C3E3115E1EF76576DCCB1C6FDB64
+:10F5D000785CA803F006F61DC75BF3A87368C79FA5
+:10F5E000BFA0E1ED6044BC5D29BF5DEBD6C785A639
+:10F5F000B8F471A1C9763DBF1513BD7D37E94B3D08
+:10F60000BF159ED5DB77133FD5F35B5E68A6AE4D85
+:10F61000ED8084CC6CD05337EA9ECB0ED6EAC6512F
+:10F620003F89F92D1EAEF7FD95A88F5AA631FD48EA
+:10F63000F910EDEF67BF4DED80F45E78BC68F09F88
+:10F640005EEC437F5F93C9F477C77BD508D76CD056
+:10F65000DF91F20B7C5C4EA60BAF363351A33370B7
+:10F66000997B86D1F5984731BBC71CB316820CF045
+:10F670001334E5F4DA49A2D347607E6A2FE5648645
+:10F68000E97DB3AB8180DD20DA1E5A00FB22A2C9DE
+:10F69000837AD7601F917A977C07DCBF6380A78D40
+:10F6A000C2E296CC585C879B6CB6809DD198294F5E
+:10F6B00002788A93193CB62451DF9DC2634B146BC8
+:10F6C000AB145ECFD0B6387001C2AF83C24B4C874B
+:10F6D000F9E3C9DD745D55995606877984E953F5D8
+:10F6E00039A65F7BF421351868FBD968D6BEF18551
+:10F6F0009FCE53137BF56F5DE64BA84FC73887D578
+:10F7000091F174DEF5EA20B033C7D2F5817C34394B
+:10F71000B62745B2BFFBB2C3568F97E7C17EBEC7BF
+:10F72000F5EB180A117346DFCF3F1BEDBB05F09BCD
+:10F7300005F0088B7BCDCC64766B15CC3318ED4B84
+:10F7400039DCBE24C14A6CB7A433FAFAF1DA99481D
+:10F750006F4E0A2F3116D6CFE037FF2E465F57BACD
+:10F760000F6DFDFDD0892FDC9E0EA393EF45A213F4
+:10F7700052EE71A3BFDE973DA7B2F53673FB51B3CE
+:10F78000936D899ADDECC7F558287BE40FC22B995D
+:10F7900042E13AC845305E53ED32F9FD14645160E0
+:10F7A000F083DC2915882B19669709C363B9142ED9
+:10F7B0007F8CF141EFF168837C1F64D0C3C374ED8B
+:10F7C000A2EE14839F7875BF7ABED439D1A09F264C
+:10F7D000EBC69725DE60F0632B0D7EAE5E4F9889F9
+:10F7E00059E5F83261DC421524730EDC27889FB09E
+:10F7F0007EF43B7BE0FC845C85FCCAFD1A23BF36AB
+:10F80000664A0867C1C5FC1A8D1FB4E735F859DD93
+:10F810000CAFEB7234FDE441BD630B7C93405C950F
+:10F82000DAD0F2E6307ADBD4687FAF7434213F69F6
+:10F8300024EF9552E4F91B5D78DDD8E8C6EB138D13
+:10F84000125E1F6F4CC371EB1B3DD87EB4D18BD7BA
+:10F85000471A65BCFF506319B6DB1B7DD85EDB58C9
+:10F8600085D7B64605EF8F322BAA9DEE6B542BF150
+:10F87000A8742BA3DBE9FBC2E096DA4AD71106F79E
+:10F8800064D5A56B8F5CEED68D4F6A9074FDC3EB8B
+:10F89000D374FD098A47D71E5AE5D58D1FEC9375A1
+:10F8A000EDB8B232DDF858D9A76BC778AA74E31D5A
+:10F8B000698AAE7F5751FEC0503F7CFC506320C820
+:10F8C000E0120C3238BD1E64F0E9C2EBE75CFE0EBC
+:10F8D0003207515E0CCA7251D2A1F8B2B3FC5A9CE5
+:10F8E000D923C486CD1F5746E74B0B5F2F9D4FE7AB
+:10F8F0009FF9915E623C41DD7D475A97EEB929A29E
+:10F90000B304F211870B448C7B1D2E888B01FBE521
+:10F910007E8B6B5A16A5C7434745CF26780E1E88A7
+:10F92000202F4F70BDE8186F47B950B14AD8242234
+:10F93000D1B2E76B3B5323C63D0FDD4BAA605F8E10
+:10F940005D2F494017150535715161FE5A45E0CFCD
+:10F95000A56EB8BF2A3D278ACE56D19A6CAD1BDB67
+:10F96000BB2F6D5CED2ABD7DD94BF77E3BEC638CE4
+:10F970007AAF1DE45B5BE2266CB7A5F59F27F98C97
+:10F98000DB619F723BEC348FC37CC4EDB093DCEF42
+:10F9900009713BEC036E871DE7F6F3316E877571D5
+:10F9A000BFE76D6E3F7772FBF908B7C3DAD29E9F4F
+:10F9B0008AF2F017021123F8A9DAF5969FEAEDB062
+:10F9C0006FFAF576D8D2F57A3B6C71BBDE0EAB6B75
+:10F9D000D5DB6135AADE0E5BB85C6F87DDD4A097FE
+:10F9E00087F3EB27EBDAF3147D9C6D6E95DE7ED604
+:10F9F000F033DBA7978B95657AFBB9AFFDBE12B8E4
+:10FA00000EF33F80C453617AAF279F0B7A85D245AE
+:10FA1000D605AA57300EEE6B86FCC9361842F56F34
+:10FA2000A129F816E47DC8DB2281B8D3AEF339E50D
+:10FA30001511E82F47D5D3CD82E3FAF8C68D77E9C3
+:10FA4000E13A6399DE2FB196E9E12A27EAFD924A6D
+:10FA5000A39EF1E9E1AA1285005D1AF58DC9B14CAA
+:10FA600002F97DA57AC74AA85E616D9DDEB1C29D8F
+:10FA7000145D3FEA9D1F64B17A831CBA0E30169A5A
+:10FA8000A2720F7828DC76BD6BC63A11BAC023A3E8
+:10FA9000A8FE2982DF29FC5EB5286A03E4D9785ED6
+:10FAA00084886776DF4EC75B87B3BC08F9D2FC1148
+:10FAB000CCAFD07F80AF1C42DB617A2E3BC8FAC34B
+:10FAC000D6ABEBF703CE06F7B71EF9C8A89CFFC963
+:10FAD000F5C4C49F06A137814CC07A83D0A0CB8ADD
+:10FAE000AF1AEF6705981D9495C8EC206FD24C9122
+:10FAF000E79F08843CBC2662C778E608E27F06E2FE
+:10FB00009CD1071CD369B319A64C003F49CFFFB362
+:10FB1000CAFBCFCF1BFDB0EBA45483DF768DC1AF02
+:10FB2000D3F3BF8D18EC971091C09E441C9874FDC0
+:10FB300008A777381D359D68990FFB7A2989E75703
+:10FB400038FD4CE4F82264F3EE1ADAEF758B04FC0E
+:10FB50000D1B51E326407D51B04186BC43AED7E634
+:10FB600042BC892B3C68979E61F8F1D27F803F2F81
+:10FB700009C317E0EFB81E7F3643FFEF393D5DBC88
+:10FB80002E4647FFB87519E8CA39E8B2EA588CF72B
+:10FB90008B83B21843D7B7D725601E756FB0215835
+:10FBA0004CDBE7DCAC6E684DE24C33AE97C803A685
+:10FBB000503C4CE5FBF5F2BC56472341BBE3C54640
+:10FBC0003B5E096910411EB5B8EF8803FDD831428C
+:10FBD000190EF5691D836357417E7E8B25363152A0
+:10FBE0005DCB4E4B2EEAD38E9D0966893E5F6C76C7
+:10FBF00099E1B9E2C45A11FCBD6BBB08DA05C589AD
+:10FC000004F3592F36060EB3F729588743F73119F5
+:10FC1000ECD35257CDE4987888CF52DB46023B377D
+:10FC200016FDD73D836D88379B6B69E9B7E8FE0EFB
+:10FC3000268844F052FC788827007A20D1E9F1C365
+:10FC4000746ECB4980733DFD0778D1F402E5F393E0
+:10FC5000E1F8C825616DCC2BE8DB23B3F5F891887A
+:10FC60008275162D5DACBE8C8422E7593EE4768306
+:10FC700016DF3FCEED86633CEE7698DB0D2D86F8E1
+:10FC8000CD5BDC6ED8C3ED867DDC6E789DDB0D6FC1
+:10FC900072BBE100B71B7AFC05A236415E711EB152
+:10FCA00087C05F3858C3E0EC5E25F8CB201FAEB4A8
+:10FCB000FB4AE87DDB2A0BCACF91896A13C4C76D62
+:10FCC00055EA14D8877B417B135C9B8ADA12E0FEED
+:10FCD0003CE5F471F0B3815EA6E5707EA7785867C5
+:10FCE00065705EBF38C6B312E85959528EE31219D7
+:10FCF000DCECF41FC03B61912A001DB8158B0EDEB1
+:10FD00003506F8CE837698FC88067AA4F09C9ECDC2
+:10FD1000EBCF32492683BB1A05708FAAE1704F8B57
+:10FD20008FC827EB39DC35B8EC2CBAD9A4D2A16F37
+:10FD300025B2BA89B70A6E361DA4EBEF9445CCBF45
+:10FD40007626F23A41FE5EE37CEF707B765D49FFFA
+:10FD5000F1BA437C5C4FBB9548B68161F394DC6F8C
+:10FD600091E8F35581FB92802FD60DD0F2C41EB4DA
+:10FD7000AFA78805BF4DA6EB0CF23A484D5ECE21E9
+:10FD80001C3686F7BDC5F7D9D77ADE2AB9C122D18C
+:10FD9000796705EE21F03E9BB9C11D5E5FDAC9D7D8
+:10FDA000B766C69D04F83238E26C3DFAF13E9B041A
+:10FDB00076F7C844CF6AA00377A262F936BD3F9DAB
+:10FDC000CA43C905CB6ADF190FE3E8338F13A09745
+:10FDD000AB37033DBC956447B9D3D77A2ED2237E87
+:10FDE00082F6485F7A84CA1FB4876CE59F1C07BF00
+:10FDF000B692347802F4B960966730F031A9B2A0B7
+:10FE00007E4EA3FFC2F36ADAB5D2A0BF1D5E4BBF20
+:10FE10007278E485C656F03BDE02FEC13C2889813B
+:10FE2000FA9C60F99D76804F4552CA2EC00F29B6C4
+:10FE300087465338AC29587D13C06B4DF952970053
+:10FE40007455988AFDC162FB69A8C8E92A5E9324AB
+:10FE500085C17BCD7DA448017827DDED5E42F79515
+:10FE600092F8C74685F24D9785F93DEF94FC3E31F7
+:10FE7000396C7C4676F1BF67435CC7CDE87C8C5516
+:10FE80004989541FACD179535134C6654ED6B07AE6
+:10FE9000057A7FF572FAA842F5559BA7978F1773DD
+:10FEA0007A8A1ADD5D0FE395FB6C12FA67E282969F
+:10FEB000E5B45D05F612D84F8F58902F357E4E6A07
+:10FEC000D0CB4DC5C0B75506BED6F8E9379AFCEC85
+:10FED000E5E318C06B540DE3276D7FC67DCDFB9223
+:10FEE000DA39718418FDBB7717A546333D1666DFF6
+:10FEF0004E40D92459E9FE66717A9AC5E98992E49F
+:10FF00004E58CFA17B52A701BED426EA07C0DA56CD
+:10FF1000587AEDDF14D82719E0A5FB9FB55C4C0794
+:10FF2000FF94DC65E9A5C714DDFBB05E604E781B6D
+:10FF3000E85595DF013B02C299F0D23F9D38BCB72E
+:10FF400099BEAF73581C69F2E07C1F31F928E17C3F
+:10FF5000870AC4015EE8FFEEE87448E193707AA571
+:10FF6000F38754D65F7D4F6A069A9BBCFDE18AC138
+:10FF70005041467CE596DEF1F0BF5233E27FF60A4F
+:10FF80006113C4FFC6889F9FDD4DC7CFAAB4799A7D
+:10FF9000E9FCB31FACB580DD5FA92A7BEBE8B84A6A
+:10FFA0004A177E17EE43C72747CCC402F31C9105BE
+:10FFB000D24EDBB366E9F9A67A85BE6DB4478EC62C
+:10FFC00028234CF4F94F041BD944AF3B372CDD08F0
+:10FFD000F37DFCA00DEB0A09BC2B07F400E1F1490D
+:10FFE00079E33DB4BF76BD8D405E641EB7F7E37222
+:10FFF00092715E9363013E5FD316837EF1E90D43F8
+:020000022000DC
+:10000000C703FE5B0735DC06F5D41FC72AD580D7AA
+:10001000DA35D798203ED21ADD3E05C67F6222AE81
+:100020004DE9B42D3D6481F57451FB00E2ADDA3A3F
+:100030006B5AC3F00FFBCA6171DCE926A26C8E60BB
+:10004000D73C9A23703D4B545BD8FA37E448787F0D
+:100050007ACAA09687E13D14FB2E0F870BEC7B0A32
+:100060008B8BB6267AAA07D3F6470271AD8C87AB85
+:10007000FC01F0A7FA031B7906D14F70BC75F8B0EC
+:10008000A7DBC2FCFF4CFEDE53B1ACFFA43BDA0F92
+:10009000FB3C29B1B6EA76FA919ECD4ADA9C18B6B5
+:1000A0001F61089C8260EB3B1A235953101F447A4E
+:1000B0009EAEABF691C710BF5B287C803FBB5C5205
+:1000C000CB4EBA8ED35459ABD0EF7E7C0AC0F3CE60
+:1000D0000C4AA80917C3A9316710AEE7F4FAE6186D
+:1000E000AC337111C53AA4171E35ED5BBF238C47A5
+:1000F0003DAF32F9C1F84F2061F29DE2777ADE0F11
+:100100002DB5B0DF28D20E7831ED59658775CEABAD
+:10011000B1607ECC497C65204F6B1E11B04D7FD6FF
+:1001200082BEA8E5FCD52A0DDA07747C12EC71F4C6
+:10013000F79ED80BF501355C7E552DD2D3E962B719
+:1001400059C72F3396EBF987EE53D7DE98C3EA3AB7
+:10015000BBBC1FC7837E6EA5DB06B87CD222F837F6
+:10016000A17CF58D08AFAF1B9363D2E2F092250C12
+:10017000FEB594FE6A416FD8497B09D83579A3A7AB
+:1001800002BD5B8F46E33A8DF0FD6787C3A924A9C2
+:100190007A305DCF294AC750FF73724333DA2FF0AC
+:1001A00023EAF8DAD502F4BD84AEF27117D2A7754E
+:1001B000C6B85E7AD1E053B33E791F8C73FF678C6B
+:1001C000449D2752E3CE5F0AF6640F1D19E0037BBE
+:1001D000366BEF49EDA533EC8F406765742CC38B0C
+:1001E0008AFC5253DA93D71BD15FFD32E23B9FE288
+:1001F000B5237D3EE4A13439B7AEE84DA483732E18
+:10020000E217995FFB36C8FD18BE3695C881BA78EB
+:10021000502654EFBAF01EFACB717CBFB1CB856388
+:10022000A599840C5A2E1E2BA537634B8301D0133E
+:100230003637D7BBDB737F3566089C6E2018A7194D
+:10024000105DEE09E06E5C09784EC1E24A00FBE702
+:100250004141A882B8FD00A2B7ABE20CF02059E6FC
+:100260008FC2EDF2682EEF974E4915D0DF29D3FBF0
+:10027000A766835DF4AB1C93E65FE055825F291CA3
+:100280005BA8FF06726A50A0BD1DE8B39ADAAD7E86
+:10029000DCBF07F33AD652813C2EF4C6AFFE51F1D3
+:1002A0008B8BE2603C7ED1571C4C8B0754B25BD4E5
+:1002B000DF51DC90F7AB74533F6700D85937BBD19F
+:1002C0006F729F46BBD4CAEDD2A8D18B5C2C7FC67F
+:1002D000F8478B0718E9CA185732F29FD12EFDCF85
+:1002E0001C6E3F5D4DAEBE92F88016C75F93C6FC94
+:1002F0009E3569B52BA17EED3CF77B5CAA09F138F0
+:1003000067968078D4ECB539DEB3B380FFB4FA8356
+:100310004BF93D6D063F24DAFBB42C47D09F8E5C31
+:1003200046478E02D63FC74ECCF6B0FC813397E9E4
+:10033000DF39540FDAE916A7F3734415449F9F1A67
+:100340009ACBE4AC76A53FC18C1C5DBDE0D0DCB09F
+:100350007CA88DE743EDBC5EB038BD7BF757705F7E
+:100360006675C036B9E6C96F533844CF8AF19890A4
+:100370007E95677E087EF22C07CADBF83409EB5EB7
+:10038000AB12ED1EA47D557E1BFC32B43325D892F2
+:100390008CF2762EE5DF80AB1F7FC7DE7FDCCCA939
+:1003A000F93B058CAE7AE24B3E26BF4DF41FD0D30D
+:1003B000EC2A3DBDCC55FAA79FDC5CFD39AE31A1DE
+:1003C0000B3BBF42BA60FCBB6E04CB479F2FA763B9
+:1003D000207FDB873DAEF9B74E0BF58B285E82F2AE
+:1003E0006EA4F7601AB184E3DB5720EAEA1B827936
+:1003F00024DA45FD9EA085243D48C70D90E75EEFB9
+:1004000002DFB7D81653837AC3AFB3EF0FD1794F5A
+:1004100038FB5E8791CEEF1BBD04E3FF0F5C4741C5
+:1004200046D77F1F249CB15E6FCB7CF0DB1E8036ED
+:10043000D6DFFDFBFC62684769ED6D3F92C3EA0DB4
+:10044000EEC90DFC482DA07E8D9DEA5B3A9F4322AC
+:1004500098A7226433CA6711E281209FC786C1171B
+:10046000FD063DBC8D76BC58C0E228A281EF8DEF21
+:10047000BD3D97F339C7535FFB363E477FAAAED6E3
+:10048000D3FF7772FBA997353EEF84FA89982BAF9B
+:100490003BA08214F3D3223179C05F262504DF27E5
+:1004A000B8185D8184013D686918E041B8D17614BF
+:1004B000E805BF438BABE2A2A300FF22E41303A82D
+:1004C000CFE95242422A8CD7EA0F14F295E3F2E5C3
+:1004D0001E95C7388F54C6F2CBEFCA2404EF1BF326
+:1004E000F87A5F0EF8EB47A99E95408FDFAC42BCCF
+:1004F000AC7B05C1FC80C3A5609BBE2AD4EC82B84E
+:10050000156B575318815EB6B9F5F5AF3B8B1E2FAF
+:10051000B6D2FE9652166F3DD418787715A5B596CB
+:10052000827C9497AB6060D87A83BBA2AC10875171
+:10053000D46FD9C16EFE708568856B70658D0A9B1E
+:100540007E3741DD2C4810775008F8F9D615CD5389
+:1005500080AFDEB5A89E414ECCAB629EB875A57A41
+:100560002BF83DB2545E964CF96853AB19CF199DE8
+:1005700028F97DA214C6879FE732BFE1E0CEA80725
+:10058000000E6B047B280AAE1665D37DF1F03EABFE
+:10059000A7892EF1DDA68793E03D6B16AFF1EC82C3
+:1005A000FE261B9C40256B36D8AB60DE35494BDC04
+:1005B0004BC2E6B50FB736C0FDE0B016AC6B51CA02
+:1005C0003CD6A858D8D7E731909F6D5D911907B4F4
+:1005D000D892601D5107E396FCE9B7B98077C984CA
+:1005E000795BABBBDD02FB1EE95654C88F9B72944E
+:1005F0000340AFF3969F98827573A5B1ABE13AF2D1
+:10060000C2EDAD00FF77793C2694508BF9DA964520
+:100610007576586F4542CACAF0784C4BC162FB18D8
+:10062000FA5C8ADB54B374C0C5F4D102F19709B007
+:100630002EBA9F7130EE8F8D0A1D174AB256453A79
+:10064000A7F509D747F6E6A529101769D96087F4F9
+:100650000C691194F5901F50939D11EBD833BC0C8D
+:10066000EED58A6B8A5542FC20BF7DBEF5D88FD46B
+:1006700051605732FCD9CDC46E09D37F19D9C567F3
+:1006800072C3FCE88BDE9BD082FAA04560FC9BE144
+:10069000FDE247502FFC7CB6AF1BE0B7A655590FC3
+:1006A000F022AA9D0C28EA9B4F42F7911184CAE3DD
+:1006B00096265B55A43AB4D022713AF009E5A0130E
+:1006C000034684C9E5957529101F09355D85DCDD74
+:1006D000337E83FD03C04368435A2CE8C350526DF8
+:1006E0004A0AD02DA74BE3FC5BB81DF062A62FDAB7
+:1006F0000B76E55896F79C91EB73629BB4BBC1CE29
+:10070000FD1AD06D2AACF71F48B7A8E73ED9FA1FEB
+:100710004857C47579F9481F0999319F5AF4178CC5
+:10072000F7B68DD3CE3FB1F8A066F7468DFE6815BB
+:10073000F8ADBE3C2DDF55B017FCF5E95A3EB59C2F
+:10074000C5075DF45FA4F8A0CF101F9C6E686BF620
+:10075000E60D5EBD7D9B28B5FB4A40EE1E103DE0D8
+:100760004F2411A65766940B7EB0B39B8AA2EDB8B6
+:10077000EE3C1EE7E4FED73CBEEE638D7602F92424
+:1007800093A36035AC7F7A3E5BBFA33E3D3B2081A7
+:100790007C67716E526F93306E02C84F203D7E9A17
+:1007A0000F26A1FB9957BF14EDFD5EF835B1F81087
+:1007B000D1FB133E62F01F16317B4CF3B7E61BEC06
+:1007C00003A3BD6F8C53F7E60536DB819EBAC7667F
+:1007D0001C4A91B05B0D68F9003A6EA1B773752899
+:1007E0004CFE7472FD70A4513EB68AEE7FB5EFC721
+:1007F00076A0D336B3DF0EFAA4ADECCE18A0BFB608
+:10080000056219F07DB0B10CC71D6CF4E1759597C8
+:10081000C9BB60B6BCC21B1677AE2C2B3EB62ABC39
+:10082000EE41BEEED8AAB0F5577867E8DA1A9D55C2
+:1008300088A4617304F9F2BC97D9ED66AAF7B1CE2A
+:1008400050FC85A7BFFA1BEAAF7687C3EF41AFDE46
+:100850009EBD7F6CC9C0FEEC166D7F1A5CB47D6BCB
+:10086000FD7DADF37B7FE33A9FF5EAEDB94BADD368
+:10087000B83E6DDD7D8DAF0061350CD659BA00EA0A
+:100880006283D94A07C8A3CA526135E44B8FF07816
+:10089000E29182183CE7BE378DF97BD1F58C6FA2CF
+:1008A0004B6760DEEF4AF17BA397D995B30A04BF8B
+:1008B0004C7F9DCACFDB1F4B63F9DCA6A29FFF16BE
+:1008C000F2D0EF145A58BC97C8D3A785E5B1D659D2
+:1008D000FD01C8271DEBA9D358B6FA6EDA8ED6E40F
+:1008E0004A953EEF306B963E7F5861C833441BE417
+:1008F000CA518D3E7228DC537BE1DE973FD1177DD4
+:1009000010F3D92CD04346F8DC66808FD17FA9D86C
+:100910006EE087CBF46336B566ED85BC9A4AEDC9C7
+:10092000D1803FE8A2CF45CBBFC634C8803C468FBC
+:10093000634267D6825EECA42A00F4CBBA9977AE04
+:1009400087F679AAF7012F7DBD47F3DF9ECF96BFCB
+:10095000F446A81FE89123601F4C80BC6064FBA094
+:1009600073D1E46911ED83997529D9B0AE197AFB79
+:10097000A07343D99399701FEC03FAD39957A7B387
+:100980000F4859E625E0C3E46ED4E8AC88757AB325
+:10099000B395C17961FB71A43590F07AC6EE1C79EC
+:1009A00008F4CFE07104ED7DD4FEDA638950BFA86E
+:1009B000BD2FD7CBEAF049591CD30FFC7A293C6AEA
+:1009C00075D4F75B64FCDE8B16F7D2C665E731FBA6
+:1009D000B03545AE877EE2CCB8C4BC4D5A9C232DC1
+:1009E0007D08AF1B96488F3FF41741C2FE08FE1EDC
+:1009F00081BC6474E2D93D2E3AE433AF929F970DE7
+:100A0000E728FC2AE4436CE502DA4BB6448276CD53
+:100A1000E5FA57973BAE158A03C0DFAA65F1F2E20B
+:100A20007433B6A3157113C8854917060A20377C9D
+:100A30008AF834AC375AFEFCD31F83BEA67A1FE275
+:100A4000303ED280E7AC9D161FC627DACAE9CCE952
+:100A50001087596949C1787AF2AF63DCF0367F2B91
+:100A6000C4CB6D1E761EAACAABAE86EF6654148E3A
+:100A70001608ED9FEE63F19B3910BF8179679DDD0C
+:100A800009F19FD95E26BFC06F03BD39B7EE3BE3C6
+:100A90001E95FE9AB88DBF352E0BE34912C60B0C7E
+:100AA000F1215BC1548C0F69752ABE0211CF779377
+:100AB00044277E87C218DF31C6738CF11E637CE742
+:100AC000EE3C5627ACD953DFCED3DB532BE00CC220
+:100AD00060B097A8A8A47CDD662149ED943E0F156F
+:100AE0007F42EEA2EB70FED00435E0749C21CE78FC
+:100AF00099722B48E5CA29D8C8EE372CE0DF2E9032
+:100B00006B30BE67A4FBC7B8FCBA2FCFA9ABEB080C
+:100B1000362EE7CF47A980E705A3ACFEA8E4DE792F
+:100B20002E973F9ECA911FCE637EC50F81CE894707
+:100B3000C1F30433725D3ABA250D83C9A9B0F88DAB
+:100B4000F1BDDA7AB4F9AF741D0F71785F2E9FACE6
+:100B50002BCAB75BE9FBCF511C8BA82FA9411D16EF
+:100B60009FD6E2E7DA73D59037C8043B52C0FC81C8
+:100B7000763F2C8E6D06BA8D4E54E448DF9B7A3B4F
+:100B8000AF276E8A794CED3D4450502ED4F17C8DC8
+:100B9000369F99B89B900F80B6B5758911E2E6C46F
+:100BA00063B75192A95D2B1288FF3889DC0EF1677B
+:100BB0006BAB05DB44ADDA0776FA22CE17D682A9F5
+:100BC000FB20AEA6F185316F631513A7C2B475ED96
+:100BD000FAFC95313F65B4A7B5F8BA99BE04D6754D
+:100BE0000EF0C1F6EB172F6FBF4FE37EBEA6FBD50D
+:100BF000E8AA3CF31637D49FB44429EB6BE8BAD487
+:100C000027ED18AF70C0DA002601FA0FE4E493DE96
+:100C10001FE379F67CF65D9A1681D5A3EC49F8635B
+:100C20007CF8F905533EA39B9FE549388EEACF0037
+:100C30009C972263E3912FB4FA934309CC0EAC281E
+:100C40005C1CB893B6FF8DD74B5E53F88C96EF1FA4
+:100C5000509C43B0F403E0B2CECAEAD20E7DC38CFE
+:100C6000F564443CB0EBCEF8DEBADD6B36EBFDCA82
+:100C70001BD2F4F6A0D1FEB31ADA43F38D75648A61
+:100C80001DEBC812781D195FBF914F7EDAC8F21AAA
+:100C90003FE775FFBFE0E72F7FC9EBF736F3F39728
+:100CA000CFF373B31ADCEFB728188F3E711DB5E987
+:100CB000627BE380EB8ABEEBC6F3FBF9CCCF9A22D2
+:100CC0003A77819EEA3D67D1FF77C22ACBF479B3A8
+:100CD000D93E7DDE6C6E953E6FF6FF32E5ECFC6C26
+:100CE000388751BF12BE5330639588F9CA752DE716
+:100CF00050CF9E2F406BFBA2F71CE6E730B4731C6D
+:100D0000DAFD6BF3D9F7911CBB122C508F3F635562
+:100D1000EC54889F1357C665D96F15107387FCCFA5
+:100D20004A9705BE0731239080F1D09AD62B9BE7D6
+:100D3000BED143304EDD13E757C7DE04F2F9B016DB
+:100D4000E727D7DC0471FEC33CCE5FF3F2B827C1BE
+:100D50003FFA599E3C17E0D1942757C1B586AF871B
+:100D6000B66FCC1FDCDBA63FAFC7EABF3F5193DFB6
+:100D70004F3C5D9C2C3444AA17B939BF27CEB5141B
+:100D8000E627F69E38D737613E626FC77376F7E67F
+:100D900033F9D47C8CD4C33CCD2F93FAE723D8DD30
+:100DA00077E50BDA7CDFC2E7DD9A7EF3DDC9E6D7B3
+:100DB000CF27DA624780DF7F82D79719E7BB37DF1B
+:100DC0008AE3E87CDFC3F9127BD6776FF8FA7ACF33
+:100DD000CFB86280691DD58AA98BD2136911B1EE93
+:100DE000C4D1E19A067549646A2AD6B11C2EADFCBD
+:100DF000A7384F73B8F4857FC9F334DBF2932FEB38
+:100E00003C8D63265122C535029C2E7715640E0C4D
+:100E1000F58327EBF2FD41B0337ADA668540DECF09
+:100E2000BAFC20DEBF3FCA551DD1BEE0F2ADA574AD
+:100E3000910F52426B92A68AE1F6CBD92CE5CDFCFC
+:100E400008E713CF8DEADE0DAA6966A96016E2D124
+:100E5000DEF608547E66AD9821BA2542BC0D0F4ED1
+:100E60001E4AFB672552FF2E6CDFF9F5BFDE4DD918
+:100E70009514941E6E8EA7E376E4286F03FD16B9D1
+:100E8000A53DD09EE54BC7BAF7FB6309DA79274643
+:100E90005BFD9B922F5EF7EF7AE5F24AF315C8E50A
+:100EA00096467DFE7B4DD29895B0FE3125240412E6
+:100EB00036C57DB618F27F19D9CAEF605D296E225A
+:100EC000DBC6E37D9984E56F8CF30E98C8F0342679
+:100ED00094F80388271FD2FCFDA22BF6F7FF180E0B
+:100EE0006FE3F584E6EFAF8EECEF9F581417391FD0
+:100EF000D052570BF98013ABF5FEFE890DEE6A3820
+:100F0000E77782FBFB27A6507F7F6CDFF9006D9FA0
+:100F1000540E3927EAF201DC6EE771EDD9D9F2C03F
+:100F200089D9E8CFBBE0DA9829C7E278D575139E56
+:100F3000472691CFC992275C32F839DAB9F65CAF0F
+:100F4000320C9ED7CECB8E01D13608F2A2AEDB2278
+:100F5000D1F368BEBEBF3E4FDA93C734E139EACB66
+:100F60008CD35FEE38C9BB99D5E398599D61544243
+:100F7000891BF253E7C7DA51BFB7C2FFC2F46A6AEE
+:100F8000BE3271E2E0F0790CDF57952EEFBD5A9D2D
+:100F90003EE82BD02F9D849481BC7920B601E31EBE
+:100FA000D771B819AFE513395E892B1EE0999AEF16
+:100FB000BB01F0415EDC2CE17760F9FDBEEAFB8D00
+:100FC000EB78D6EA7B1FCFD7978812ABCB23C81715
+:100FD00057A5B9504F6BF6D7D2894C6EDA48689452
+:100FE00095EEB359DEEDCCA4E33E7CC29C0E8F3D62
+:100FF00017432CB06E5F1A9573741F256E65647F5E
+:10100000F211BE4864F2C2352098DC788D635755E2
+:1010100080FB17F1E313DD83C11E7FEE49969FBA73
+:10102000EAC945F6DAB0F99F98C8E566225B7FB554
+:101030002CF8A56458CF59CC43CD904C1E9940DE76
+:10104000F8FCD1B91027A4F6DB686C9FC376503248
+:1010500065425EFB43F7174761FC55F72E1E82F48D
+:10106000CFE1B17045E6B368E7E728DF05FC070B81
+:10107000CEC5A48E453B7E3DD0FF4281F822D909E2
+:101080000F71BC5D2F37DC087476BD6C23706E2D3C
+:10109000586C43B83F572848E0B75600CD433CE76B
+:1010A0000933C69B293C9641FF018F03BF1B5D227C
+:1010B000FFDA0CED3F8E13C8D07EF4F115C3B5E016
+:1010C000DC60E0C70F81FE22AC7F295FBFC64F14F2
+:1010D000EE25B82E99D58BF44557DD79F2934097DC
+:1010E000AD294A3D7E17D135F3B2BE8B58F1533F3F
+:1010F000D6EED97ED2308C44A8FF3AC4F9C478FF2A
+:101100009713997D770BE78FAB9EEC3E701DF0F542
+:101110000A8B0BF0FAB33CDF66584F8FDFF57796FA
+:101120002353C40588BF60395D3B7EC781C4407BC3
+:10113000FA2833E24F2DE1DFF9B89BB89A63F12921
+:101140006CDB5708C8670E677B1518CDE6BC86A315
+:10115000B3E1B96211CFF5879D73E9B78E2CC4CF87
+:101160009FB5C0F9336ACB075789DA77B7884065EE
+:101170005BB0D4CCEDFBCF9E94E9AFCFF2FACC9329
+:10118000AF5A36421DCB51136BBFFDAA65C44AFA54
+:101190009ED008B68EB607054F9304D7A7D743FE57
+:1011A000B26EB9E029A3EDEAC03D5D10E25AF288C3
+:1011B0008D80ABF0F10F974E85FD9C7313FCBEEC58
+:1011C000DC04C6374A90F84DC9BDFEED0749C4AFEF
+:1011D000E54BE11C9D97EB9987E01C1B5DF7B5EA99
+:1011E000B7D4EF40DE94FABD10571BE461F9CCE8A8
+:1011F000A0D9E327E0EFB2FAC8961F08E421984788
+:101200005CDB0CFEB98DD7EB46CB35E83F0EA2F484
+:101210002981060D9975E7D8EA8882F41B5746396B
+:10122000231DAE7AFF38EB12E7D9E6DE343816F824
+:10123000E52F13F5E732FA8AAF6B57F8DE0DE0A71A
+:1012400083E757B751BB1DF6FB32B5DBE1BA9DDA38
+:10125000ED701FBE530D5738CF06D75DD46E872B68
+:101260009C67832B9C67832B9C6783E7E03C1B5C1C
+:10127000E13C1B9E3F2C540303013EC5D104F243C5
+:101280002D1646676A9215FD8D4021C1FC7D30C93F
+:10129000BA6925C4EB0486273596F50763949BB19C
+:1012A0009D3C96E577CD9E11708E7095305602FB71
+:1012B000A9D5AA60FDF289956602F5CBA169C2FBAA
+:1012C00090772182C92352FB66C757B721FC17CB01
+:1012D000C40475E92BE1BBA1208F3F259B587C2ED0
+:1012E00028C2F7E59A6308A7C73ABF4C65F669417B
+:1012F0006B1F52C09F9D043101A4DF030AF42F5ECF
+:101300002EF076D02F8F82BA06DEAF1E7A0AFCD777
+:10131000558676A7497B3EE52998EF68CFFB465472
+:10132000CB40EF295A7FE242689F8AD29EFF7C2100
+:101330009EE7D2D6A37E8AF38592B4F1A9D5D01FB9
+:10134000EAA9935B82EB0D0D66E3FF6D57E7D3E0EF
+:101350002FFFBDE76B56548CE3ABB3087926F662DA
+:10136000FAFA7892A88F87CA822E1EAAC5DF4D8E00
+:101370000543F1FCD90336948BA79208FA217DC569
+:1013800045C3E2F51817FDD524AD9ED910FF240AF8
+:101390008179AB201EE8C1B72AE1E7D388D040A00D
+:1013A0004EDD772646023BD29A1816BFE332A0BF25
+:1013B000786173038B0F06150B51937BEBFAAD0528
+:1013C000BCAE9FC70BB53A066BC1A3BABC81315EF8
+:1013D00048C465988FF62DD2C7032B942B8B172EFC
+:1013E0002001CB50A07F59F080FFBEC0A57C300407
+:1013F000EDFDABD9F719A5D7316EAA9D1B833BF044
+:10140000DDA92ABEE7B65B4FBC3F848EF3AF8C925A
+:10141000E030FEFC65C5F87C1EDD21C4B76A0AF128
+:10142000F02DC9FED4F3BA04F2D46DF23033CD7787
+:101430006F02D80B8B62316F72D35DE91FC03C8B9A
+:1014400055073E47ED4A4EEF2F6D047A1221701971
+:10145000D6CE1AA1D15BD546E0AF49715A3BE629F9
+:10146000E08762ABF6BC17DBF3148DFFAE790AF4AC
+:10147000C7D1128DBE0F54C3F3B3537BE643FA9E1C
+:10148000E4D0DAD317427F6BCF7C4B36C27CEFC0FF
+:10149000978DB03DF529E0E7E2195C5FA91F6D84E7
+:1014A000F95B1668F34FF0C3771EE79BB4E7A3FC24
+:1014B000B07E85686D2ACF68FB3DCEFFC70A5EA867
+:1014C000067EB9B1A7FF05DCEF02DE3E5E50F714E1
+:1014D000F4FFCBEFEF7FF87DC6F64D2438656856F4
+:1014E0002F5F18E5D56F8B981CF1D6FF1AC8952C85
+:1014F00068781ABFEF06F10096CF4A98E503796144
+:10150000173D943388CFEDC238A7719E9B0B595C71
+:10151000FD4C813E2FD662C88BF9787EAAAF798EBA
+:1015200014B1795A4B22FBB119D9257F2A80FA01CF
+:10153000725684F95C1460F07DB2964CE5FFC37D71
+:10154000CABAF8DD4D2AB23C709FFAC52AD899D3A1
+:101550002938210FDB54F438C6E9437916DDF7400A
+:10156000B43CE73AAB8CF2F1635ED731BF449E7274
+:101570000FF0FF30916CC23A0F27E61BCCC3AD4F82
+:10158000A35CE7794FED7B1CD32F712EC2782EA57B
+:101590009BC3FF5C419B05E4B34AD429A55928AFFE
+:1015A00083506F6C72ACC53CB0ADC88279042DFF1E
+:1015B000ACF0EF7F6B79DF49170632FD9EA6C5754B
+:1015C000FBCFFF2ACB77FAD03E68178949B8381F7E
+:1015D000BCD8A726413DCBF4D2183C2F5055FB0672
+:1015E000CE7F7804C1EF0447CF6AC0F341666A1F1B
+:1015F000CA00179E2FD6EA63465EB81DCF8DD66906
+:10160000F5E662F941B0536D8F513F0BD997C14553
+:10161000CB17CF30C8FBC50595A86709B5E347C709
+:10162000C27BFA3FF7FCF0A458A49B8FDA593D7FA8
+:101630006121CF97F03CF0FD1616E76B4DD1D3D565
+:10164000CF27317F65FD244677BB8A7E5E85F633E2
+:101650003179202F469E60DF8583180B9EB7327E3E
+:101660008F396D0EDA754F8CA45BA4B6B679F97B11
+:10167000185714D6B3E73E1D4F1AC06F319B599BC4
+:101680005E54C8FFE77A9599855097B5FC031CDF37
+:10169000ACB27AEFBEE237D5859ABE67F19BF9EE20
+:1016A0007D5D70AEEC6F8EE318CEBDFA24565FD22E
+:1016B000562069F946FC2E21255C0BD88BA9F9BE72
+:1016C000FA428C6F6D96601D9ABCD957741BCA275D
+:1016D0002247CE4B6B7CDF62C84BFBDCECF923AFBF
+:1016E000DD530D7F17A2AF3CC4B3C53D7983E5F848
+:1016F000FE782D6F20DF03ED5E3D4A37E4D5E9D15A
+:1017000085F5FF0BF4688FDDAE76A11DFB755B3FA1
+:10171000A5AB1710AF652C7EF6755BBF3C517E13F1
+:10172000F8F9BFFB3DE9137D5D00A7FB04B9CAC909
+:10173000927B1E419FE7FBA0B09F3CDFA5E20FFF1D
+:10174000176FE83FDE602FD2E7E1FF59E20D0E3858
+:10175000433518F928B108F8A880F1D1BFBADCA345
+:10176000FBCD2F827CBAB0D91F9DFAF7F7F753F360
+:1017700095B222D4838A6917A59FFB8AEDCC9E0976
+:1017800030F8F6C633E8FABDBA78C653F5FF0DF166
+:101790000CBADF2AC46F297FFFD71F7F77207C65B3
+:1017A000664FFC0BD2E703B8BFCD6C7FFF80F76FAD
+:1017B000447AF905A3975EF8303B290C3E0BEBFF0A
+:1017C00031F0791EE1B38DADEF6B80CFD7119E1E46
+:1017D000B6DE4BF9D7270A044D2E1FC27D66313A7B
+:1017E00038C5ED6BEA774F1E2AF5FADD4FE5C86F75
+:1017F00015313BF76891AEFE537E1BEEF7E3171FE2
+:1018000083FE087E7108EE7FDDFCE2D8429647EC4D
+:10181000CDBBF8D9776F49D5F5DFA0EFF980C21BB2
+:10182000E26D6DCB45B42FCE2712FC1E80666F840F
+:101830006259FDDEC5E7C14A099C47B4E5B1EF8CAA
+:1018400068DF07308B0B0606A48BE17A7080628517
+:101850003AAF25727A0B9C6F9DBCF6733C77659509
+:101860006DF8773547BA3D96BBC08FA67EEEB510B2
+:101870004FAD77E1393AED5C9976FE634960DE3E23
+:101880003867DB46E92181BEA7A2D472327CFF46CD
+:101890007BC36C681BFFAE69C2247DDE83C21FED73
+:1018A0009FF3EB597D5C9B99EC82FA8F3A55F437A4
+:1018B000D1F6336B05FC1EE7220A27F0F727B7277E
+:1018C000633DB935917DEF4CFBBBA7940EDAF3C0B5
+:1018D000FE3B2A12FC3B76FC3C99F69DEFA869671B
+:1018E000F17B5BA7E8FEE1FB3DDA772666703AD133
+:1018F000E019D5148770394FE142002EFCBCCDF4BD
+:10190000E52C1FDCB2607110C8BBBAE0F35591EA58
+:1019100052E6B8F5DF4B37C6338CDF1B3713DF4099
+:101920003857575150AC82BD6AE3F59AD144C6EF9F
+:101930005A9C5AFB63F65D8B528BEE3B22C6F746F0
+:101940001BE8D466883B18E9D4889772035E9E3101
+:10195000B3EF0CB6748A1E95DE6E7964512B9CCB66
+:10196000571F31B1BA7922E3779F5AA8C58BE7CFC9
+:10197000E962215E3F97C353C30B210D16E0B70503
+:10198000DA397453C36A384F3A8F9F43BF916CC69C
+:10199000730637810541DFBB1042E4227C5746B213
+:1019A00032E7C045601D7555EC3B1926D803E409A4
+:1019B0001E3121BFB6B877E1DFFD0A0CB3C49E4EDD
+:1019C00063FE44247BB627AE4021713A2C8EFF7F04
+:1019D000F1ABBF2D7E35B17010AB9B880AB8F29287
+:1019E000D9F726A09E6962A1C4CE2758941178DE4B
+:1019F00061C3272AD08176DE81FEAC18A2FF6EC2B9
+:101A0000C649FDF87F258584D54727879240AE7D5E
+:101A1000D0475DE5E1E29EBACAE72661FE9DDABFE6
+:101A20005920F798FD3B23D7F7B3496817B373CE16
+:101A30005A1CE933AFF24B185F087F3F270BCFE703
+:101A4000F8E1FC4E8553D82B48BDEF27C63AF6FF88
+:101A5000A579AB7BB8DF168C22F81DA46032A97A79
+:101A60003E023E9E29617644303D32BEB47E6A67B6
+:101A70001C9FC4FDA1018C28CE58F5F18193809F55
+:101A80003EFF0E1DC7E3E829F2478877DE7E385710
+:101A90002132D4F72ABEF701AFA7555102BD420249
+:101AA0000A7ECF6FFAF74557A4BFA7F8CF7EFD2F68
+:101AB000E87FAE8400800000000000001F8B08005B
+:101AC00000000000000BED7D0D7854D5B5E83E73A5
+:101AD000CEFC24998409061C24E849001B6DC0E152
+:101AE000279000813393842490C0F0A741221E08E0
+:101AF000D0DC5EB44111634B9B0381102222BE8B6C
+:101B0000AFBCFEE824185AEFB37DD4CB6745D48E22
+:101B1000012D5AD4E0851A2BA54110B1CF7E8F5EDE
+:101B2000E5B5CFE7FB7C6BAD7DF6CC39930920C6DC
+:101B30005EFADD3B7E7E877DF6DFDA6BAFFFBDF6BA
+:101B4000492D8B3AAFCD628C6952A0131EB53EFD74
+:101B5000E4502CB39B59E74478A88723F224C65657
+:101B6000B2D84F7540B986FEC558DB5DA77E3F14DD
+:101B7000DA4536A6A86C3A634B5607A97F11F332B3
+:101B8000199E6DD372181BC258C1B9C06115CABA6B
+:101B9000DF11906898F0778741BFF08A4CB50DC689
+:101BA00059560CAF0A183BE984E714F8DF98B64C95
+:101BB000CB87FE58BE8E3A680CCA4B065BCAD9D09A
+:101BC000F4186F5FA8FD35628C82F199D9DF6CFF44
+:101BD000AEC4DB9F0F66470C2F63B79BF550D6B1A1
+:101BE0002CFA33969E1354A07FBD24CAED9A629DB1
+:101BF000EFDA766D1A63679CF6F16BCDF16669AE2C
+:101C0000761C2F1C9BDFD5AE41F97402FC77305E49
+:101C1000BE557350FB95B1F60E5AEF594994C7EA79
+:101C2000583EEE12FDF39769B0DEED39BC3E1C1A4A
+:101C30001B31B2AF3E78BEEAF1BF303CD354A2AB09
+:101C4000C2FA5F945C0BFFAC6D6897752FD259F8A0
+:101C5000F70CE8D17844523BA14F21DB2B3399C0DC
+:101C600076C94097533489B5C15CEB4212F50F7BBE
+:101C70001D7C1EA328A2019D2D992EE8745904E70E
+:101C8000ED8FEEFEF4D29AC70CEB3A8D354B6D70AA
+:101C90001B636D702FEA82F6505E72F73FF811CE2B
+:101CA00025B9627D2511A4BF964CD1EFC38BCE7BA5
+:101CB000EAA56AA2F725B179E653FB25A962BCDB48
+:101CC000A91CC7E79D767C1A372EC3F9045CA1D006
+:101CD0009D84CFB02FB219F93DEC670103F0797BF9
+:101CE000FD0659CFB7F09151A5121FF963E5889D04
+:101CF0008F0A888F061AAE9153C23FD440CEB0BC33
+:101D0000BD6A78CC57B16E9093B86E43A2750B3A0A
+:101D1000AAF559E8DD03EB564539B0ACDE3B10F3CC
+:101D20007697D1BC1F01BE599C9F98919BC03F974D
+:101D3000375EB377B90BE15EA5495A04DA7F8EBFEF
+:101D400019F1E7E9699CDE019F2F6BF0648580CF74
+:101D5000747CCF488EEF9B107E95F0ACEA8E2E807F
+:101D6000CBA579581BE060DEE4F06FA83DDBE147CE
+:101D7000FC0300D4BEE5285390CF80B7028EA95053
+:101D800076B29ABD49E6FD69C841F3363356B117BC
+:101D9000E09BB8D1B72AEC8DD7E79671B8547CC2D6
+:101DA000B8C7D37BEF1802F3F732E6DB08E3371B43
+:101DB000C0BCF07CBF5E8A48B0E6F7B3C3738AA0AC
+:101DC000DC9DE3086C84E9BB1F708F580BED7B72C0
+:101DD000BC0184AE277347BA0FC67F3F209BF8BA79
+:101DE000E73DE4EBE3E9317E3250BF749BF83DA759
+:101DF000853A908FDF5179F967A56BDF43FE6279F1
+:101E0000CCC786021EB007F0AA236D9AC70DF3BA9D
+:101E1000668238C1BE3EA6BBA0DE8DF5B0C4798F08
+:101E2000EE7E74018E61D4BC32CAA2475D4C317A19
+:101E30003D34AFF2395790CC39293EAE6B67F3CBC6
+:101E4000CDA88FFD320B216FF9797B3FEBDDF0B927
+:101E500003C787721E43127CE97358BF6496F1F77B
+:101E6000392CD1CBC2153908571E0BA0BE9DA73BFC
+:101E7000CFC4EAF9639B32C98413E191D75714C1E7
+:101E800033B5DEDE6E761E943DF1F2AC9D7521C455
+:101E9000FB2C0DBA8D63ECC8CEBA681DC079A4D0F6
+:101EA000ED9300D3AE6CC5D67E36DBBB09F10E7662
+:101EB000C52119F0B2D49CAFD937EFF70CFAADCAEF
+:101EC0008312ACFFF87782E90559C86F72C061B61A
+:101ED00071087C306AE77470391D90A07DF37362DD
+:101EE000DFB40EE403394DB295832E513FA903F9B7
+:101EF000E2784CAE8E598EE5452305DF0CED403D72
+:101F000039234D94072D47BEED559CA63CBBBE031F
+:101F1000E559AB18CFD8457CFD3613F5691D484708
+:101F2000E198FC9BDB8EE55B7D263CC60F491E36A7
+:101F30006B5C9F4C7DE9D55EE30ADA037F16059161
+:101F40000FC35CDE25D64F391669CE30EDBAD16AA3
+:101F50005F7EDB1694898FC2DA9F65DCBFD206C034
+:101F600019EC5F498D74AC00E953612390EF5B9AE3
+:101F700080F74743F9608A4B4D47B9EE9BA925E1AD
+:101F8000DF57830E1AAF2AE8CD3AFB75683F814DC3
+:101F900040BA6B696A14FD0DDC5F7D942B9292D37D
+:101FA000FF38A74AB81CE8967C0BB97E9619EAE779
+:101FB000E02323BD452CDEEEC5122E0F5A26688B7A
+:101FC00083F09C03E297C11E6E98FE837008E63989
+:101FD00053E40CB889CFB4B790CFE69B34F4B04B40
+:101FE000630FA0DC2872FB36A2EC96F39D8D505651
+:101FF0008603BF62B982D3B70EFF7D9E8BE32A7141
+:10200000FA0738E635DAF9416116FA86FAD5C1746D
+:10201000BEFE9BD9CDB8FE079DBEA528C75A737DCD
+:10202000775BE5D9FE122EC79E36D7DB35FD9F6B59
+:10203000103F1F334700E5C79ED430C9B353198CF6
+:1020400075A0CED798EA1B8A7CCDD721E5DDCAB032
+:10205000FD8F6E80250C03381ADFED2E9D00EF7783
+:10206000F17EE7C6B20686EF155E8687618CC37681
+:1020700027A9DDD6602ECDCF1E0B783C48FBD01CA7
+:10208000F7DBCBF63AF1E9487B7E849E647FC4930C
+:10209000AD767E14C303F21268425CB7C474C7E71E
+:1020A000B87E53FE039D6E273AADE17A64CAB9F358
+:1020B000367A2B0DAAD42E91EEA0DFA3D46FA1E81F
+:1020C000C79CBAC55EDF168C443628A48F7E48EDC7
+:1020D000BCA08FB26CFAE8C7F43E411F4DAAD41ED3
+:1020E0000F16C4CBD07F3795FBF6EF0C26D167D007
+:1020F000FEA734AE47277CCD9BAC3D89E589D70B45
+:1021000079020D0B417E5C23CAE977D64FB3CA9F93
+:10211000C2C751DE2CD625B3FEEB8F237F1F0F09DC
+:1021200079736429CA93983C62358FDBE4119B7301
+:1021300027D6C7E40F5BF5188E17933F6CE6E328AC
+:102140003F82F3845E3BF3188EDF522BC6BF25120D
+:1021500044BBC421FAA744900F7526CA763BF27798
+:10216000D3FE65A9D56F62EC5F1ED32C7EC689694C
+:10217000758F931E3486B0D3820F72FBF2BB90032F
+:10218000827E847D78EAE093BA01ED5654686F59F7
+:10219000F7256667F672BB276E5F9EE7F6F7C0DB32
+:1021A0008FA769FE7C4E6F5FC1F8FFCB3ABEB0A728
+:1021B000E0FDBF59DF5F6DFE1CC0E70A21BD4FE4A3
+:1021C000F05D41FF8C10AE2FC0F5D4DF00DE6C9ABD
+:1021D000CFF403AE427C064243AE6AF84A09BE2AF7
+:1021E000BEDF2F6A313A2D4F4E07974DFF73695F5F
+:1021F0004AF9BA2DE3CEA7F755822FD4A4FE3AB4FC
+:10220000BBCDDE2ED6FF7682CB1CF722FDEFB4B716
+:102210008BF55F6EA5CF01E0F3D5D6FDFD0AE4484E
+:10222000238D3F8A8FBF328EC7EF58DFFF67DCEC0C
+:102230009274DE4EFBDEC0E9E932ECED9F60FBAD4F
+:10224000D25E3D83E24486C0FB3F23DEE17DAF0BDF
+:10225000DEBF65EEC79345E19FE17B2CFAC75BFCCF
+:10226000136309AD2FEE9FC040F9567DAFB75BF504
+:10227000FDA1505D3BC22B97F0F6FBBBDE5C86EB0D
+:102280004F2C835D7280D6930576C918B24B9EC7DA
+:10229000F2A5C605F8BBA8DFB39C6E92D4BF42740A
+:1022A000F514AF6F75713BF6EDDA8FC98ED3D6A8F2
+:1022B0000EB4E3845E3F1AE27E00D82315116F5FEF
+:1022C000BBF1684812783B4AE3EEE5F83F1696D337
+:1022D000D1DE8CD92DEC55F283E276D55DEDB88F49
+:1022E00071BBAA81CAD3CD7D3E13BA779909EF0994
+:1022F0008E07733D976EFF1EC1E1E7ED93D49FA556
+:10230000F1B2399CCC7BF80CFAAD44AFFC37CA0172
+:10231000E5556621E85C549C05764BD74E4945321D
+:1023200059B94BECF3FA769BDF68F2E162938E9534
+:1023300092E665185F58FC89E0FF437CFD313FB5AC
+:1023400099E07FC78C4F3C8CED397C9F12FC2A872B
+:10235000EF2B18DF55427619C74F0D339C689789CC
+:10236000F382C4FDCD287188FD4D2F213B99C355C3
+:10237000A34B64BF87579C7222BD2F3DC6B464F443
+:1023800031A4C425E24F43A8BFD7F46F033C2E9479
+:10239000D87E78492C5E359CE0F4F1F936148547F7
+:1023A00060FF69FAD192A17C6B3C688F864BA5488F
+:1023B0005B0EFA37DEB25228CF73B05EF2FB18DB49
+:1023C0008C715FF7F30A6B0B506B55B1C475804B82
+:1023D0007F8B7EE422739FE7B1587CC581F11A4B55
+:1023E000FC86FC4077C9FD793B558ABB50DCC6E5CD
+:1023F00097C9AF083EB482E223A9856E9F1BE7917F
+:10240000B3C9CF75FDD08C172DE4FEA503FE433B69
+:102410003AB59191FF36679B1451A1DEADD9E32FF8
+:1024200075EBCF37937FB782F934F01395427BBDBC
+:102430002BC17F6D99A087104F6777D539101FC1C9
+:102440004AEE879DDD35D28BFC97E8479F453F9A42
+:10245000A4541F3FDA7800E36B163F7AED00FAD1FF
+:102460008B4AC08F465964FAD1238BC2B7113D28DD
+:102470001AC9B7AEE953E693BFBC4D666E687F7A62
+:10248000E7C4370AA16C6C5302186E78DFA92DC51A
+:102490007A03FC69F97ADA2686F1ADB926FCA78BB6
+:1024A000CE9722FCDABDD70790DE4F3FE4263C9F53
+:1024B0005E99194983F132B6FD65530AF47F2532DE
+:1024C0001C836C31FF3AD10F672C6220DD9C6623A0
+:1024D000581BEE83E26338AED290113002717F7BDD
+:1024E0006E9ECFC0F1F4481AC37D8FBECAA4B379E3
+:1024F0008C8E1C908EE731D58985054C7322FE1792
+:10250000319DCAB701BF492371BE3C83E800F80E74
+:10251000E3774D13F4EF10BDFF88D307DBAEB4E3D0
+:1025200079C569E39174E4B33DA9F6788378B698E8
+:10253000FCE9413F7FCC80FAF90F5AE5C465C895A4
+:1025400047F87E727E7595301A07F4643DF279B7CC
+:102550001907DE9EC9E3277BCC3849E213183E0BEE
+:10256000FB7F513D01FAB29DE08DFBF11D08CF6567
+:10257000E8CB9F12DCFBF83A7721DC5CFEFCF7121B
+:102580006E07A819144F01513C89EF2FFE3E95F4B8
+:102590005FE07CDA5312ED578ACA480EB95938CA3F
+:1025A0008989E3117EEB87DAFB3D7BB17E6B827C10
+:1025B000FE3F16EA2FE0FCC5E78142A19DBB8AC71A
+:1025C000C1E77AA5972535DEEE38C6A192ECF779FA
+:1025D000538E42B3A803EC958733600FF2717F02EC
+:1025E00083505EBFDDA49D441BEE7853053D7B9474
+:1025F00006921F3DBBE4C806E8FA4613EB2E1DDD2C
+:1026000077DC9ADAE0C933167934B7EC090F08455C
+:10261000D69CD77158C278BDE656DDD0BF3B3DBCD5
+:102620001DE3F5C651997502BCB72EAC3C79C622A4
+:102630001F12C785F998012CFB61894C701F0CBAD9
+:10264000A333308E60481194072B8C534E8C572E39
+:102650006D5CC674D82757E12905EDC29AA08FDAC0
+:10266000CF2D94996181EBF149DA7B8867A08B3398
+:10267000B4BF81981DF53E96834E2DC3971F8F439F
+:102680008A7381174B9E22FBB83B93D1FC613F8B31
+:102690006C80F94BB465AE5E3C67F187296E7AB207
+:1026A00044A57957EE6C277852A7FD99E001DB39F4
+:1026B000EA18DC17DF820F8E9A786F31F1DE1F9EE9
+:1026C00095521ECF13E5B9654A3AE2F92D45A57337
+:1026D0008EFEF87B7EA97D7FDCFE0A5BB959BBD7F5
+:1026E00081F47476A71CC17D82E7EBB86F9FC0BEF2
+:1026F000B19CF838DDE9ACC6AA9FC5FECC29B5EF80
+:10270000CFD26D7C7F966E0B125E969656BA86F18E
+:1027100073B5BD40DB4C2F5CC6102F2EED9482723A
+:10272000ACBFFD027E1B568AFC6BDA8F57103FCF81
+:1027300029B5D8B55F757C1FE6BBA534899DFDB76B
+:102740003A5F10F4740CE56A7E5CAEDE56CAE5684A
+:10275000E253C8558B3D49714D0B1CCBEBAF000EBE
+:10276000C127C8A728374A7648CEDE7CDC7FE0D771
+:1027700031689F7DB819F35156F919D14356A94ACA
+:1027800074ED9A36CF85F278E5AE3F2BA8AF009F67
+:102790008B4B2D72B8A494093D544BEFEB395DFC83
+:1027A0007B9FEB003C77D3BED77238AFB673A7756B
+:1027B000D5E18DA5740E0472C98BF1789FD04323A7
+:1027C00078DCFB8B9D6FBEBFF35E8676E0BC3FA5D9
+:1027D000AB6807DE5ED4A9E5A849CF3755C976BEF8
+:1027E000591762E45730161AC62E79BE99787EDAE8
+:1027F000F7BCD378B9392B6E77279E77269E6BB2BC
+:102800007ECE3FFB9E771EAC2A02386705649FAAE6
+:10281000C6CF335DD3CE9E6063FB9E770E32F52E1E
+:1028200043ED6D596FCF08756F14F3A38679021DC0
+:10283000BC399327C5F1087AC0E38679369501FC47
+:10284000682FE7743CBA80D9F0E8223C7C413CD246
+:10285000F936E265A714D988FD950603E5F94AE63D
+:10286000537F1088EF676CBCBC751ACAE7EFD47948
+:102870009903F87F73D63D6C19B44F3D92C26468DA
+:102880007F44BD87F6FBC847E92A9EF7BAFD967DCF
+:102890003071A908F8E4BE7ED2DF601F3DC8727DAA
+:1028A000F651ED28453D7BB9FBF76451F803E4632D
+:1028B0000FE86B657CFC7DCF088ECFDE9B58A44370
+:1028C000EABB8F806F8DFCCE3CD6BE91EA1B18C64A
+:1028D0000736498CE33B812E1C69EB0D3CD7762DE6
+:1028E000F7921FD5DCD040F83E0AF8367C9CBFF04A
+:1028F0009CEA22FC25E88249432F9F2E12F7FDC84F
+:10290000CE3AD67875EF6B3FFCB9BB14ED9ECBDDAC
+:10291000D77953B59CB202EB3E6B23CB8658F9D6E0
+:10292000E07E0938C0E44F2E64AC33B3AF1D956F21
+:10293000E6A5C0785FC7F1C69431330EA88DC1F209
+:10294000821B5843B2BC976BCBB93F560B2622C5AE
+:10295000558C54CABBACF5EDF83DE5611A37A9D6E4
+:102960003CCC3ABE0476FCE1F61EAC9F0B8B756442
+:10297000D12BCACB14F80995E5D0B845AB4FBDAE05
+:10298000527580C67781F0473FB5165F523E098B7E
+:1029900074921CD0D97C90F777AC95289FB3C64829
+:1029A00063E8D7C6F32AF626E455F0F2DC6CB3DE12
+:1029B00078B1C37E8EF9DA72DB39A6D19BA0DFFE37
+:1029C00048FACF665F58F4D9072F7FB2DC50ACE7E6
+:1029D000989FD2F8276BC57CC1DDC17CEB39A66B13
+:1029E00037C223E2D4F0DB6D3DA704C8A92CE2C8AE
+:1029F000A933B53A8C87ED9BA0AFC0FD914BA406DF
+:102A0000B48F40C16812C56B7C1DE84F83FDBF12B7
+:102A1000EBFFDED70976485399E5FCE3EF0DFED3D3
+:102A200022BE6F1C5F8EF05DEDF002BE7F46F8AEF9
+:102A3000E0F8FE3B80F7605952FFE4AA81EF6D8217
+:102A40002F760EF1EF0ECF876596F38BAF7A3E6D42
+:102A5000AAF6BF71FD5FC13A1C33711D66FEC165E8
+:102A6000B4F7507BF3BC34B1BE69A6E93F98E7C424
+:102A7000EFC4CEF1AEADC3F17AE3E77A74EE153F61
+:102A800047CC1B89E78871F8F3687E718E189E79B0
+:102A9000731DE545F7738E391FEB4759FBDFB41BF8
+:102AA000F9AC2D613E9759BF6AE6448237BEDE0914
+:102AB000345F7742FB1A737D6B674EDD6D58F00112
+:102AC0009DA87D4C2E31AD0EE78B9F3B4EAFB39E44
+:102AD000DF7E6FA6B65B9CFFCF443A36CF69FFA37B
+:102AE000E363C14C1EDF11E7E5820E474ED116228B
+:102AF0009EAE367861FFEAADF4FF37986FDD4C0B80
+:102B00003F7DD1FE317E34F5BEC89F00FC1A88DFC0
+:102B1000A6723569BE84F013C3BD2C827ECB5416D9
+:102B200091F15C221CD019C641637C6D54125FBBCD
+:102B300062F723E6ED46F917BF1FD1B61BED8BB840
+:102B4000FEFE559D3DCF616E9DF57CBEFD955F8976
+:102B5000753F6AE593811EFF7BE576BCC4CA267E7D
+:102B600096DCFDDF46D8EF5F2CA679DE89DDBFA8B5
+:102B7000DB6DBFC7D0B0DB9EDFF15D3B5CACD50E3B
+:102B8000176BB1ED574679EB6E03CA2E33EFCDB517
+:102B900042EAE77EC572920BE25C17CA36B940E59D
+:102BA000EC8187EBB7828E4C3E8DC1D9273FEF9BDE
+:102BB000BBEDF9790333BF452EBC8DFC30F078E7CF
+:102BC000F73B04DEFBBBDFB15815E5C6BAFAFC2FB4
+:102BD0003F2FE6FF59E5C9975F07BF2FE24ABC2F99
+:102BE000C236D6D9E5CF65C3E72A4F2A7F2EAFFF7D
+:102BF000A0F27EE58F0FC76DF63AE83E8AEE674990
+:102C0000EFA33495F373A9187F9AF751163C9CDC17
+:102C10009FFEAEE94F8B7877D0757E85F5BC6B74DF
+:102C2000398F6FE796C7F25072697D8D1CBE00CA5E
+:102C3000433CEF610AD380A7162E18918DF035FF23
+:102C40008E8FC7FCE027A7C7C7AB36E713F3BC34AA
+:102C50002FBDC69AD730D69C27109F2F40F3ADE7E3
+:102C6000EB9007ADA67B5E31BFDAF831E1B5C5293F
+:102C7000FCEC4EE2EF78DCB883E4CE22B7A0FF276D
+:102C8000775BFD89DB7EFD14C9370C5FE0395EBCE4
+:102C90005F7BDDE5F42B2B37F5F12673BF8CD87EF7
+:102CA000CD44B82FD5DFE24747A5ACB81FBD6F8232
+:102CB0003607FB833F3DB7BCE0D2E3009E16119E72
+:102CC000D6DAFD114BFDE2725B5ED2F9D517CB4B24
+:102CD0005A61EE7B7F79492BCA6379242BCA2DE791
+:102CE0004AC17925E905182719E6487A8FE21E734B
+:102CF0005FE3F95DBFA4F5B408BE33CBDB3379FDE8
+:102D0000B77EFD6C9DC9576BCA2DE717E2BC85E500
+:102D10001F8E629CC7925FA439AC719F92534EA4E0
+:102D200087A5DBA4A4F9337DF8A5D51C7F5B6C1FB8
+:102D30009BCA797C5FC7B8E36231EE3736D0B835CD
+:102D40002BF8B8897CB3D5C4DFD6389EB6129EB4B2
+:102D500058BECD8358C69401F7F8F8F8E27E4FD0FC
+:102D6000197E01CF755A0C4945F9AA372EA3734530
+:102D700056013C09FB141C96BB0D4587986F5C05FA
+:102D80009F0FFE598AEDFCC042C630B06B2B96D126
+:102D9000B9F3248DE7AD4CAEDA200F5129AFE547EA
+:102DA000B8AEA285EDCDB8BCDB6A7F2127CB67E941
+:102DB0008EE5B3B0B7460D05FE36E1C37B216B61EE
+:102DC0009E7762F92C5565EBACF92CE12F97CF2259
+:102DD000E27F4B428057CBBE8D34D739B282E33588
+:102DE0007E0ECCE8FCF6465633EB268C2FE3BD2D49
+:102DF00078DD6DDE73BB90CD2278FEBF617A2AC587
+:102E0000F17A33199DABC28664544FC23C12FE4B1B
+:102E1000195D4A715C37AC0BD781E7B2D1AFC1F015
+:102E200072EDA068127A7E234367012FC6FD8DCD17
+:102E30000CCFD5F447E87CEE86157FAEC77997EACC
+:102E40006E15496071BDAF8CF2B856079CEB300E21
+:102E5000E9979986F1EC2AE77BFC9CC643789A5B5C
+:102E6000CACB022F6EA6BC67C58B92506E3CB16177
+:102E7000CB214B7B5734251DCF05DF2E4FB7DD2BE4
+:102E800062B297E8E082DF11C173A86E85752900F0
+:102E9000479D2ED3F97BE7B635AFE3FDB1A57E257F
+:102EA000E0807596344A94FFB5D8C7F1F49726634D
+:102EB000CB21B0615386E5D239CC059F87A2F12D95
+:102EC000B59D14B7077AE95630AFE70199E1B9B774
+:102ED000C87F9A67D28BC063CAB28F092F17F03CA4
+:102EE0001CF1529849795073001FAA8FCEF93721EF
+:102EF0009E525943F41A98F756BF83452D7168586E
+:102F0000BF2D8F0CC6A6BC3385DED8EA093FA90FBA
+:102F100094F07C34B92A8AFB7AA190EF2B94034871
+:102F2000EFAC94D3A9C07F6A029DBA13F2C312E931
+:102F3000B40FFE2BEC78EF5458208AF4764C26FB25
+:102F4000A277A7924179573B1D9477C55884EE31FB
+:102F500075B2C18136949B5189CE096E33F126F04A
+:102F6000CE58C3E6E518E76EC80860FC9F391A36EC
+:102F7000637ED4E2481AE5DFDDCEF6521ED41DE8AA
+:102F800021C3BC77329F0BCBCB59809E12CBA7FBC2
+:102F900025B7EA12F185CEA2D53701FEA2D7393383
+:102FA000AD7955FDE635C1CACF5ACE23465598F2C4
+:102FB000D2A3FB799EA76EDEFBD1283F28B3ACD409
+:102FC000A32791B7A545FAD72B0A2C7918BE064638
+:102FD000E7D345E1311543E2FD9F9AA08DC5F2E4A8
+:102FE00042ED166CBF07ED3CD0078B0E8F7D02F5CE
+:102FF00059CB046D3CD627CAABD3FDE7DF451B8117
+:10300000EE7A505E511E613EF1E140E5DF9555F4E8
+:10301000C9BF2BA7F598F977279DFC5E19E5224FCC
+:10302000657DEFA735DE46F5E27E5AE2BD34F62334
+:103030005E8605196DE3F0FE6E03AD5BE03D113F6A
+:10304000CCBC97B6C4FF4A8F347600F2D67C60DCE5
+:103050000DBB187D18FCFE72F59A9E2CCA235428CD
+:103060008FB02587DF5FDE844D30116814B7070706
+:10307000557239BE25B3C11F80FA2D4E9E0FC3F283
+:1030800074B6604C7CDC4195B238176A403A00BB9C
+:103090008FEC2561AF8A76F7997AA1B14212F7CE0B
+:1030A000EEC7F696FCEE46DA0F6F34E210E776FCD8
+:1030B00047E740C27E383EBC81F269DC5A727BA190
+:1030C000B922A6CF9B69FC9D429F6B9B70FC19D7D0
+:1030D000F816229FB94A64D6817A6CEE5D24779FF8
+:1030E000C1BC51B06926EB1B4A86C27E3F52619E2D
+:1030F00037D56722BA58B7C6F349A3C50D7ED47732
+:103100005B8625BFF77DB282DBCF13AF3F2FE3B8DD
+:103110005B9681A7320EF167501E9BB1086409943B
+:10312000C1DD3F84E7321EB4038A502FF2F6BE7A27
+:103130006803FBD865E22B7823D00FDACFA3EDF933
+:1031400048E229DA25E65B81284FC77527E6B98969
+:103150007CAB1EC5480F24817F6ED95A0FE56B6585
+:103160002FF7A09E6CD14A68BCC4BCB72DD96C04A3
+:10317000C29598D726F2A644BE9418F7B90A4E27EE
+:10318000226FCAEDE77A0B9E942713AD50CDFBBB9F
+:10319000F6FC36915F83ED29BF269BF1FC1A7F0375
+:1031A000C37E6E2863FBB0997F9698570572E8201E
+:1031B000D1411FFB88919DD15264E60D306DF332F1
+:1031C000B48FF0FC3690C4BE0281807AD005FA0933
+:1031D000EB15797505A6F27C593BAAB428DC83F07F
+:1031E000B9FC3139FB3B82372E67DF35E5EC09ABA3
+:1031F0009C75BFBAF509B4BBB7489C0EB700DE9FFB
+:103200004E421F1F98FCB6253339FD7C6ED26BCB26
+:1032100084F08738BE96C5EF777C513BB3256E6747
+:10322000723C0E909D09F8F8CC2AA7011FFF2F19B8
+:103230001EE0B709E58625CFD45959D07F9E696233
+:10324000FF2BBD277C0DC80DE43FF0077D95E40FF3
+:10325000723A16F2387EDFF6CAE4F53107C85180BB
+:10326000076D026BFBDC4A2EE7C64DD5732B492F49
+:10327000F3FBBE5B83FCBE2F8B6AA4F78FA7EB35F5
+:10328000C8A72C6FFC25E6DB60E6D3EAF56192F374
+:10329000F32FD17EA339BFB9DEBCC1A43FB64ADA51
+:1032A000AE54395EBED4FAAEABD42623FCCD7A98A8
+:1032B000BE97B025CFA11AB0B47F9AAC17E3FB2D0F
+:1032C000791B69FFDA80E024909B731CE71FCA9585
+:1032D000281FF85969103C3DE0B125A1EB59959C98
+:1032E000EEC18AA57A7642F35BE31C6B4DFD16CFE7
+:1032F0000778FA09EB3DA61595FB5618163D86F1A1
+:1033000092A793D0C5C24ACE3FB27B8D4D4F26B611
+:10331000BBB5D245ED56569AF10853EF2D72733F67
+:103320008A1D01F82C7A75DCD4D0EDB4AF063324B5
+:103330008B3E14FA8F6A2CEFDD7E7EFF841DB38FE7
+:1033400023D6799F49A7625EA0D755C81FA077BF33
+:1033500081F388FA4532E3F18E6E3BBE009ED59C28
+:10336000CED88A587E96051ECDC1C78DC1D1638740
+:10337000E33E733FC64DD5EEC371401FAFC3676BCD
+:1033800008E82D095EC71784BE8DF50A335A73739A
+:103390002E6AAF6EC076A26CB1579B2BEDF6EA2673
+:1033A0005C2FC8D1CDF87E4F6AF2797798F81AB0C1
+:1033B000EF065C269F3F88FF4CC22F6DBDFBD2C637
+:1033C000028BB9DDC6BDC497F9E32FC1579C8FEFBF
+:1033D000BCBE81F4DB0BA6FDF1829329985703BC98
+:1033E000154896EF73B452D81B91E18897E7FAB16C
+:1033F0003762EDFAC9ABFF1ADB9176257647DBB46D
+:10340000E36964777CD29186FAFDB933A1A476C7CB
+:103410000BD93B8627B33BF6F76377BC6ADAA7077D
+:10342000DF77911D517C8EDB1DC5E776C8683FBCF8
+:1034300059A9D27A8ACE74CB3AC05D8C76078CB308
+:10344000DFB43BB03DD91D9FEC9011AEA273DDD42B
+:10345000AF18CA687714F56377001432E2E1D9E255
+:10346000B67FC5FD4B5CEFBC897A8F956E0B7BBB3D
+:1034700029BE23FAB5E56D4CD369BFEDF4535AA4C8
+:10348000DAF2E20B7B39BD27B6EB8FCECAE4AAD6BF
+:103490005E58D75696BE83F2319586C7B16C180A2E
+:1034A000FF3E1E7E5F039EF7CF051832B15DC34F0E
+:1034B0007A51AF186E1F7ED7E02FA94BB99FB396F4
+:1034C000F99C53E37288960EA01921733C97C7D7D5
+:1034D0000C76D2F7D332088F8D3E11CFD951910B94
+:1034E000FDEFFFDA28BAF7137A040682F2D46332CA
+:1034F000D58BF8CFEBC318E5E703FFCEA986F127FC
+:103500009BE3839ED3EE85F68B4C3B6CA6ECA5F635
+:103510000FE6F1F6538DF3F5582EEA75A978BF8CB6
+:10352000C9EBE5BB316E8BF608B47FF0F9709907F3
+:10353000EA538F032438DE0917C52F447CA1E0D855
+:103540005EC267DA19972DAE910A122F6AB15B5CE1
+:10355000096526D70E4A269FC433310E71ED2CD350
+:103560001F1DCB6EF91CECAC0B6C7D2BAED13D3A24
+:10357000747037EBDB5FC419CE4FD446CC827D1C10
+:10358000E5D4C96FD95F01B8867DDABF73E7ECB1C6
+:1035900088F71D0AC5754F7E3B8DF6E9C0234A3B6F
+:1035A000C6934E029FF2F8ADB112E9F5403A13E727
+:1035B00040518CCB1D88DD67CE5EA959CAE35E2BD6
+:1035C0007C1FF5E08121A2FD8F79BD281BFFB4127D
+:1035D000F3360E0CE3E525AF3DD369101DF72AE461
+:1035E00057379EF626939F9366DBE9784EE11A4E95
+:1035F000C797E807F27EC6AC24FD52AAB97F75A032
+:1036000016401A8778D24B67015FEFEFB9A7750CA8
+:103610004C3571DAB7BB498E5ED3BB3699DC5F306F
+:103620008BDB53D1E208F95BE0C3737F97298730C6
+:103630007F750E53C7A35FFFF0F4E77E3316E6797C
+:10364000A368F47839095FDF3D2B97C689C37754A7
+:103650005E8E72E9A3F716269303DFAFD417DBD78C
+:10366000C3CF479B772884FF0766FFDF2730EF2112
+:103670005ABC83E277FBFFE460E8AFEC1FC3ED7E4A
+:10368000BCA187DFA51C00F8764E4E427700DF5DB7
+:10369000B30AFAC2377936E3F9A113B56F617D2217
+:1036A000BC2AC6B9015E30AF022847523EFC2FDD6E
+:1036B00018CFDCDFEBA0A0CA85331D3292605B4FD0
+:1036C0006E299AAB33AA4EC94852C5BE4736E3D1DC
+:1036D000AFBE5EB6F1DFE49E545BF98E866B6CE59F
+:1036E00025F5C3E3FCC8F01ED0485BD9EDBFD95621
+:1036F0000EB209B6F2C2AAA9B6F1CA7C25B672B951
+:103700007FB6AD7DA5BAC0569E9DB7C4D6BE3A5011
+:1037100067AB0FE78F53F00A1FD0E5F771BFD38E69
+:1037200069C4E75B7AEEF1215D448BC3E44F1F4F20
+:10373000EFCEC678F5EBFD7C57EED42CAECFEEBCC9
+:103740001E4C239493A0CF3766C6DB07737B6DF1C5
+:10375000F8C3B3B87D7A7056623CBEBF7B705C3FE5
+:103760005FEEFDB7443D3CF7A67B482EB52D942374
+:10377000789FAA39EF2D2FDE1B7B7D218F23B46527
+:10378000C33ABD948F41FC7570D16D23F05C2D352B
+:103790004FBF06E5BFD0DF257911761AEA537D11B8
+:1037A0003612EF9741B9CEBC675692CFDFDF68BEC5
+:1037B0005F854FD0DB332DF84AD4C741CFB897C1CE
+:1037C0005D60D3FFEAA3EFF72DCCE7F19ED24F2245
+:1037D000A5789F7AB6F6D2217E6D9ACB9F378AFF65
+:1037E00098D58FDE7ED3CEAF47891FF69F997F5144
+:1037F000F9FF87261E5F7FA6C9C3A2B0BE134D3E48
+:103800007AFEAEC94FEF8F36A9F46C69CAA367B4CC
+:103810002940F5FFDA5448CF434D1A3D5F69AAA00D
+:10382000E7E1A630B57BADA9869E479A747AFFF191
+:103830002CCE97570B3C5A9E8827840F3A24C2EB14
+:10384000424CD59D724E93ADF21DF0FA6932BC5ECA
+:10385000A91E8916EF1D1EE67A2A291F0D9D2DEE41
+:1038600085713B798E4E323F069F0BE37359F1F819
+:103870009C1B4D9AC104E7A0D9050307E701337EDD
+:10388000732093D53CCDFDBA4D12E91BDF382ECF06
+:103890007F100E913C1F322EB93CCFE923CF979178
+:1038A000DE6287316E8A6945288CD7E1FCC9E32145
+:1038B000C6A09C8BE281CE2B051E2CFB15B8123CBA
+:1038C00024AEBFB4489B8CE3E03D14E7E0BE7AE44D
+:1038D000C6DECF348C493D9BCFE17DF8BDF983D066
+:1038E0005E7163308AEC1570F00A71BF99698FB40C
+:1038F00077D667F71DE70FC57B49AF3F18B3739EB7
+:10390000203B26B11DFC0E111E506F59F090440E45
+:103910008493ADBF4C7EBE7723F43FD0CB285EA608
+:10392000A24D0DF03FA7F0EF341C38E7203C5FF0CC
+:1039300048241FDD0FDCEBC1D8F6B3DFE5ED8C6A60
+:1039400089EE2FA475ED57D14E0DF6EAD7E0F7C6F4
+:103950000AA3954EFC3E6868DAB8408A850E428A12
+:103960005D4FA2A51AD33B140C1B9C50BE2EDE5EED
+:10397000C6FDCF8D9773E8DEF53FCE063A9D7FBE3C
+:1039800081A9F9667C35399E564B96789BC202AD6B
+:103990009373C8EE3C741D9EDB8C661199E8CA20B7
+:1039A000FF5BC02B7BC3742F4FF8E99F4ADAFDB34E
+:1039B00093D80FAC5EA37337E670D0B95BD304BD68
+:1039C00069369DCF279CCBF85EF93F12E8B45607C5
+:1039D0008BA27D6164B8087F89FB35B9B07213AEE4
+:1039E000CBFFA5FDFA1D92F53B0137AA33C89FBA5C
+:1039F00000FE14DE436956F8FD28E3447AA4938060
+:103A0000647968B7DD2FDF1CC0FDFF7EDAF7C83FA1
+:103A10006A047F0BFDAF6DA61CBE3F35A383818278
+:103A2000DAE66CF81F58DF22B17007FA5B29D74736
+:103A300058461CAECED95C9FBBD91D8390CFBCBE6F
+:103A40009927CF4C48E6EF71FFC419DBF76C1FF9DB
+:103A50001B66D9EBD2FD98F7D8326EF52EBC8F6578
+:103A60000CF1F0F34E25ACCE03FC3C64DEAB653EBE
+:103A7000836559EEEFCB4C398BF1D9563066F07C2B
+:103A8000F79709F038AF101E174A18F447B35C11C6
+:103A9000CCAF51511E015CAD7E07F1CD2695F3FDF3
+:103AA00026AFE6F125D9B72D884777FFFB29E76CCC
+:103AB000F2611C7B87D7417CD9AA2A5B73A0DCEA20
+:103AC00055F8F75A554745B27CAD8F6673BB099AD6
+:103AD000A4507E53703ED931FDCDD366EEA728A702
+:103AE000E6EB1AF18F1A08E37A9ABD5912C63745E8
+:103AF000FDAFCDF1459C78AB6917A5E6ED8D62BCB5
+:103B0000A665D8AA09882E0FD83967E1BD277F2F6F
+:103B1000D9452D433C35C9CEBFCECFE671B6ADCE2B
+:103B20004005E2736BBA831980BFAD39C9F5608F68
+:103B3000B97FCDEAF830D12DE063B4D4B7DD6F4C56
+:103B40007DB9D9B9C38FF7D0B68EBE95F2BCB68E0B
+:103B5000E072B7F1C889CE0DF9C80FDF62FF86FCAD
+:103B600090A5D0BEA92CE041FDD5E2537CE8EF4FF3
+:103B7000CC5AE7095AE497A0FFED6887C0D3396CA7
+:103B80007E0DD2E385C2D40022BD4C3E42DF0969DE
+:103B900009803CCDC13CA4069FF5FE3FD8D37215E9
+:103BA000C0951E70D8ECED4185767F4165BA87E8F7
+:103BB0007318A7A3FEF62F111E2F4A9CF117699FB9
+:103BC000A9D724FB2EC9B82A8E574137CE4BD0CD6A
+:103BD000A5E0B7E9BBECB8BECBA91AB10ACF2F1E3E
+:103BE00062BC7EE491F39DE8AF2796BF2C7F362B15
+:103BF0003B481E378F72113D25F6DF9AC3E1F9600D
+:103C0000F647341F861570DF323D3C8EB4BD7070B0
+:103C10004A32793B6BA25E5465B18B324BF7921EF0
+:103C20001D5CC5087F5E35EC1B05E3788FC940A39A
+:103C3000806FC7677F3DA55E391E951D0D2CCCC7D3
+:103C4000233983BFCF40BE6598FA64CB0D6F30CC6B
+:103C50009FD93E5209C89487702470313BDA5B6863
+:103C60008F137DD138504D95998F92C252781E5046
+:103C70005548A1FC1B07D79F1AFC3FD4BCC22E9904
+:103C8000FB3FD43C5A52F1158F7F65D5325A4F2CE9
+:103C90001F05BF2783E3E88CEC0CBC108BEDAE5BFB
+:103CA000CDEDA86CD62BE1F9DE0D98952323BD73DD
+:103CB000F97981653B281F07A6C17C12C97090BEA7
+:103CC000FBAF379C9482F0767BD1AA71B83F89EB29
+:103CD000585365C6B362EBB8381E049C034DA74227
+:103CE0002F377BB89ED54021A7A0119C10D72C93CD
+:103CF000D7535CB3C570FB500F372BA077B3A877B1
+:103D000098E2A00971CDBFA4F0B8A7B48EF9A4229F
+:103D10008A6BE6E13E35B2D400C61D0729BA07EB2F
+:103D2000D346298CD355C3643C3F89FBDBAA97E774
+:103D3000BF35529EE0AF50AF41BBAECF2E2E8FF6B7
+:103D40005D42AFB51D1BE5A5B8B9A72E0DFDEC670B
+:103D5000FCB947D06FB9E0E1F95BA25D57C2F74CFF
+:103D60005A4C39D75365C6C753FE2263FF197E5597
+:103D7000C13CB990671CC9F76629F93940AF29DF02
+:103D80006E54DFE474B65A7C876C35C9FF77D34D27
+:103D9000FAADD79750BCD8B4E398A6A9BE4971FB39
+:103DA0004DE84BBFE233EEC271CCFCA93EEBECFA1E
+:103DB0000786DF57617E4BDC3517E71F14CB9BC3AB
+:103DC000F913EDB6FEF0D966FABDCDFE10E55D5CE7
+:103DD000409995E45C443CC1FEEC463955D06D9762
+:103DE0002F697976F9D2EA68A03C2EE366E6C33CF7
+:103DF0000F5615F05BED5FB0438F571133DBEDC904
+:103E0000FBAAB9BCEBCA54158CBF9478820CCF1BAB
+:103E1000946C9DE17EB8FC818BEEC7CFABB8DE6FB2
+:103E2000C95B1E467FE5E1E9DF24BC4CACE079A527
+:103E3000A21DE8CB0FAA2C7E8BC83BB8ECEF23F970
+:103E40001C948F78B9F1A1B6692BF9F791FCCBE9F5
+:103E5000FB48CF78F8F791BAD2F534B4BFBEE8F793
+:103E600091EEAEE6F41AF27CE3E08C5C0B9E7A7481
+:103E7000CA0771F9CFD3B9CC0C337F24310EE47665
+:103E800037D0395AB4B86189350E2CF0F77393AE38
+:103E9000FF50AC539E4F7F7FDF41B4438CE1BADCCF
+:103EA000669C734BF1B709FFF32B3229CEA49871AE
+:103EB00026D7799DF27A3B27EAD7565BF49D3BDB08
+:103EC000207D97F63DC6EFAF7FCAEFAFA76D6421A7
+:103ED000BCAF1EFA6C3C9D3F85A229C467D33F0945
+:103EE000D0F7A7CBE4A75A73A1BEEB9842DF85EFCA
+:103EF0009A9E9A857AEDE363DCBE4DEBBAE9C82D54
+:103F0000502E3E5687BE3EC81D806570DF754CFF43
+:103F1000C4F1A5FCC702F41F2DE72062DC5F361D4B
+:103F200026FAD8D7D44DCFFD4D517AB635F5D0B35A
+:103F300050D14A703D85DD7426C9A69C817A0B1C40
+:103F40008527A0BF851E864CD4B56AE2BF6E5BBBD9
+:103F5000B4BC1E5B3BF05F4BAB0B308F87E3D3856C
+:103F6000DF0D83F1E7F6B0CD92FA1F4A5EADAA1ECF
+:103F70001879F58FD505179357FC9C34D4637E27A9
+:103F80002C811F1DD52AF90D31BE34CF4B859E6E75
+:103F9000C57F823E6DCEF826976FB17C0C7EFF50B8
+:103FA0007C677EE3EB1FEDA1BCD277CC7A83FD4426
+:103FB000B3D433F6C92ABC0FF2123AAF60879E7BA6
+:103FC000BD6B15DE9BBEB52653D100BE123C58CD4D
+:103FD0008CDF7F11798A8978FB9FD59CAF8FE7FAB8
+:103FE00028BEDE92CBFF5E4162BB37ABB9BC409AC4
+:103FF000B0FE1D8FD47EEEFDBC2AC635F1D6EAE2B6
+:10400000F907FDDDEF78ACFAE2F73BFE60D65FEA38
+:104010003EC72FCD795FC4790B282F720FD285F858
+:104020003B1B51F37DECEF6BF859D2717E6ECADD0C
+:104030001BE7F8CCFDD414F33BD47B893ECCBF877F
+:1040400020EAA79C8BD5EFA3F9627FF740A7F88FF2
+:10405000B85FF7F3EADFEED960F99E574BEC3B8986
+:104060003C6FE95313FEC4A7B85F12FB1E147B6BB1
+:104070008F66F91ED44FAADF396B7EAFEA10C16795
+:10408000DEAB79348E875FD3FB84EF0374BDFEDA39
+:104090001EF33ECE6FA8BE21F1BB5BEFEDB1DEEFAC
+:1040A00079B4FAD42AB3FD515AA7F99DAE247461AC
+:1040B000D2ED993D789FF032C67B97C633BFB3B53A
+:1040C000D9E4A3FEE819DA9FA2F6B1EF0FD7795031
+:1040D000AFC4EFF1BFBBC7F6FDACFEF1F5475AB771
+:1040E0002EE665667E13E717911F26E8C23B87EF31
+:1040F000C776931FF0FE1FF55F316078F88CD69578
+:1041000070AFE852EBD837212CCF4138FCB1FC62BC
+:1041100085CA5F121E711F2C913F86CF91445EF3BA
+:10412000609A273BF61DCE6B06625E1877048D13EE
+:10413000FFBEE7F57392CB9F2F342E532F2F6F4482
+:1041400094FF3F19A999BA607100000000000000B7
+:104150001F8B080000000000000BF3176060F8518F
+:104160008FC09C687C5AE3BF4C0C0CFACC0C0C97AB
+:10417000D818189C39191884F8C833E7229ABE7BDE
+:1041800040B366F030302C636560D809C47A5CD8DF
+:10419000F5D90822D847817E5F01C417E91C06A320
+:1041A00078F0E01A11068649A208BE9E18AA7CADD6
+:1041B0000882AD2345995D4E40FD008850BECB80FE
+:1041C00003000000000000001F8B0800000000003A
+:1041D000000BD57D0F7C54C5B5F0DCDDBB77FF2728
+:1041E00037C9029B10E24DF863D04037103058D4E5
+:1041F0004D041A90D7AE69ABB1A576A14A151156F8
+:104200006B9567D5DCFCDF841002A202455954107F
+:10421000ADB6A9A2B59FE5BD0D508A7D7E9FE8533E
+:10422000AB56FB62A5B45AA5F1594AFA7D086FCE88
+:1042300099B9D97B6FEE6E962A6DBFF86B87B9F38B
+:10424000EFCCF93767CE9C99956C6E52760E21A70C
+:10425000E1EF12421EF21242C6A4D2CAEF7DF986E5
+:1042600027AAE8BFBDCED04E9A54FE626E71B4222A
+:10427000557F1611B05EED2F96FC91D07AFF4EEC73
+:104280008A937EDAE71FF486685E15EC04DA394912
+:104290004DC1BF0468F9902DD445F3C993361FA1D1
+:1042A000FD4C2776E8842844F645A6D1EFE29773C3
+:1042B00089AE7F737AF16691240B08D97F27112389
+:1042C000B45E9BFF8225033E425E6C4CFEE5C864F3
+:1042D00042C2C9A9A242FB39D07808F3FFD678F8C8
+:1042E0002F471C8444491E8E533BF72371296DB719
+:1042F000DF411AFA68BBDAB0E058AA1B2FCAE7B34D
+:10430000DFCDCBE51AD1B2DC4FCBE9F7DAC0E596C9
+:10431000E5513A23AC97C7FB191AB0433D850C7A97
+:10432000719E27EB2DE7398EB7D3F255036CBEFB98
+:10433000DE3E7119D0214972234E484F96BD05F8D3
+:10434000EE77090A29A5F81D5884F84D027E6917F1
+:1043500027DE61F8DEFF892DD444F15DEB927D21EB
+:104360009A2722A5072DAFF59130C225D294C271AC
+:104370001987FB2A9ED6438A7451902EFD2E4A1728
+:10438000DFE8F05EB2594278B579F6C33CB368A76E
+:10439000D1957EF545FCB41DB1E68391F8A1E3CD3E
+:1043A0003C733835BC46E6F6FFE5888BE0DF69FAFA
+:1043B000BFF9F2F37F39529ECA5F3274D890A71CBE
+:1043C0004D5CB329BCF04F0552F1CF035A79292B2C
+:1043D0008771E28DCA9F2751FEEB6D247F9E44F9C1
+:1043E000AFA7D185F9EE4619F35D8D41CCC745DA0B
+:1043F00084D231DE4D122A6D9F17A6F575E3E5567E
+:10440000D3763AF8FC21D990F796070DF5DD8A624C
+:10441000288F2B37DB1294EE9D15B6845D0038A8EB
+:104420008C9C0B70B830A5E0BE16A4F399C49A908A
+:10443000750EE5576500CF4B76D24CF3394AD8B6A6
+:104440008CE64B82769208D1F1730609A1FDC5EF87
+:10445000246423EDAFBB72B66D19CD77CD71CA76EA
+:10446000999004ED3FEEA4FD9C4A2A2DD0CF34292B
+:1044700004FD905EF1B7802717FDEF741921131525
+:10448000E91D5B0E21A52AFDAE9F9F530D825CE7BF
+:10449000561BBF4F5496DF4868FD8944F7BD34452D
+:1044A0004F6D5C2D6F1ECF3CCE396B4CFD9BFA2DB2
+:1044B00051066AE48A54BFE790C126D9F7CFDC6F72
+:1044C000B856003A858892A83C7B70FBD67C9C77D6
+:1044D00064660ACFDD0EA607CDF236406CA83F8891
+:1044E000388684295C8A624B74D17EBA4A6DC83F93
+:1044F0004A1B4980DE5A37E1700CF25DA592D24C1E
+:10450000F3A5E5071B84E984AC9D2023DF75ED75D9
+:1045100092E610832340F9B444E3D353033565C0D6
+:104520008702096DA4E5A5CAD126A82FBFE6511CB4
+:10453000D523E747D6B0F9639ECE7F10FE316B647A
+:10454000BFBF9C258523C0B72A4938293C9D939A33
+:10455000EB543ACE03AA48407EBAEEEC7B1DF01C29
+:104560009FCCE035CFBB449196025F13FDF874BC3D
+:10457000924957DC00F332C3A1E98BEF37CA288F89
+:104580005B1ACB317DA051EE033DB1E513BB257E17
+:104590002F13987EDEEA88D8003E758E2DB113F574
+:1045A0004F74EBF5347FFF77C7CE8075E0E6393680
+:1045B000D42F7FEE66F8BE5FE8BD8A607D49C1FA00
+:1045C00026F97F400C377F8BD6BF3F5840542ACF07
+:1045D000258EC30BCF85FED69455AAB4BFFB6FD9E9
+:1045E000F80EB42F993345B1D3F613AB8FBE4517F0
+:1045F00071B2E5D44030E2833C93EB923563FB2605
+:10460000513E19AFF4DE04E397544B4AA234C597E8
+:10461000C52484E39CD3E025497974FE2C5E9999E6
+:104620003FCF9E1EF8FBC85511C855410AEEADDCC0
+:104630003E31D37DB160437E1996AB6A26574F5EFB
+:10464000C8E8ACC9D59609BDEFE5D27CCF37189F35
+:104650009AF9BCB4FA680DD0B59BCA4F7E909042CF
+:10466000A7F2B140F33D4BB91C561F1596D3F67F08
+:104670007AD5A31090A725D6FA3A1D3FA752E3B8E2
+:104680000FDC62AB8DD07ABFBC76CA1F9D30DE12C4
+:10469000490139EB11CB717CE5BB92A2EAE859B232
+:1046A00084CA13E5AF925BB8FC98E46AB4F1E38D79
+:1046B00009F22E95A30D8D4112A6745BDFA8A07C94
+:1046C000ADE37206B62829A4792E67A47C06E6D34A
+:1046D000D99F8434A1DCB994248952FA6CA07D93CB
+:1046E00022F89E0C87E712920FBAEA42042769A3C8
+:1046F0006BFBFAE17212A64C4F7A049E57FFA88614
+:10470000E9787288E59F6BFAA3DA428570839BE5AE
+:10471000F70AE535EA5C7DFB83D8BF569FE693B583
+:104720009374FD41FF157A786C35505FEBEF8DA6E1
+:10473000A21A958EBF9EE7A5E63C963FCBFD770B70
+:104740007D41CAF464ADA99F6E81E349FD8F70D8A5
+:10475000971AE73EE1BDB06A28FF4318F0A495FF21
+:10476000A0E93F5495D6FF8844B608940E33E64539
+:104770008B08A5BBB72E49C094DA60C2776A7E2F3A
+:10478000E1FC7C152CFF60D32761C0B756FE8CE09E
+:104790006F027C03DFF8C6121244212164F3CFBB01
+:1047A000AF7F01FE5D9E4FC81C3A8ED24B14DA8754
+:1047B0006D524C807D47708978D4200F9CEF287C07
+:1047C0004F08349D3137FA35580A2DE053F5F0691A
+:1047D000E38F06AF06477AFE64E39BF9A87641F5BE
+:1047E0008B73A97C790F3B424E05E6210BA0C7F3E2
+:1047F0000128AAD7F24EED473A11B12F0876B4B985
+:10480000DFFC794524A19BE7674DCF2D9067787B2E
+:10481000454F579A7F4D8FC727A0DEAC917CA7CD1F
+:10482000CF0DF3236007D3F955E9E7F75403CC2FF5
+:104830001DDECCF35BEFEE6D8858E8DF8B6D7CBF3F
+:104840007B71F597A07F3A1E01FDE5560651FFCA20
+:10485000301EDD6AE69EDADF005BDB74E3C973E9D4
+:1048600078E5670F9FA3F1B18FEA2F85D6B3853224
+:10487000F3B1599EB5797B61DE02F011DB0F98E749
+:104880004D08E523FFFFBFF3FE5864F4BC85F6AF87
+:10489000B27931F9F807CDEBE3170A505E011E3B00
+:1048A000E3E7A0157FBD2B28867DAE99AFD3CDEB76
+:1048B0001FC5A723E79519CF675B0F65AB5F9B5FAC
+:1048C000F3201E7BAE61FB849E43F3D1EFD0F3C295
+:1048D000A5E3008E9CF8F9244CEDDF29D03FEDAF25
+:1048E00047B32F36578DD23FB32FEE6B247DAD9358
+:1048F00009793A6700F7C3144E6CBF95DA9F09AA8D
+:10490000E0AA5EBAC5BD948EB7F5BA8D6EF02BF5F0
+:10491000707BB1EAA587372CA0F81C776D7EA59D2A
+:10492000B2428F5BFBBEE7F929F4FBE66BF877EE4A
+:10493000BFA2DF5F82FA415E3F1D5C85D2403482B8
+:10494000F242E1D2E15F2B7FCAC6ECD227C1CE3A58
+:1049500017F633CCCE2AF4F42E05FAE66C959407BC
+:104960008591FDFE6FAE4FEF033B8DCE77CBB5ED5E
+:10497000456057EDDB317BBF0FE0BA86A03E3F3785
+:10498000B1ABDFA1C0F8AA00787ED241343B0BD78F
+:10499000F9A26B34BAD60B974EC276DCCE62F9EF31
+:1049A0000FAFAB5F47BBA538CAF2CF347FB7A64580
+:1049B000D495ABDFAE0917A7CA5F6CBEB106D6DDD2
+:1049C00019AEE89B7329E96650BDD742E198212AC8
+:1049D000F618F0CBE680A5BDB8FB79574382E277A5
+:1049E000F78E2913AFB55847281591CE5A7EE62188
+:1049F000A39C3D09F873021E99DDDA4DD10BF583B6
+:104A000051A505F039F31009C17E349DBE4B47C74F
+:104A1000E036A3BE9B211AE775B6E6F31191D97E65
+:104A20009BF74FD7F5976D6C3E7690A3992293FF35
+:104A30004F3B9F24E089D911BFB1EAFFEF35DF1961
+:104A40003E3A4EE0B31F27681A275DBF667DA5D6A4
+:104A50001241047F7C1109013C79F36204FCF87671
+:104A6000DFE1A04AED3D511EC0D411180CAA54EF4D
+:104A70004A41A510526771A810BED3FD11978F8EC1
+:104A800026D4ABC3F9CE26D0A3EB218FF2B716CB39
+:104A9000370EE7D761FEEE094C3ECFB1DFD30F7A78
+:104AA000B80C940D856B5DFF1B0DE0072838E00BFB
+:104AB00081A951E00B11D0C35A794FFF7B4117D820
+:104AC00071077CC44DF93D5F0E137DFBF5FD7F0D35
+:104AD000CAB4DCC7CB7D8188A17C63FFD4C22045EA
+:104AE0009187977B82512CBFBB7F4EA10276CC0170
+:104AF0009F0CDFBDC5311CF7D25FACB4A13F76B1CE
+:104B00002DE1D4E9ABF8E219A8DF9708D1A9764ADC
+:104B10008F9A5F74BBC07E881FA81807DFD1E6415B
+:104B20007F92F87F613F0AD9D36807F9E4A3E7735E
+:104B30007AD953F4E886F30AF403B3738A383FA7AB
+:104B4000506B9349185FCD6174A21C9DF23F63FBCB
+:104B500043297F35E60F1BF27E3911867DB418A0FC
+:104B6000FA81B6F786D530D05D2A6679BB2F9404DA
+:104B7000FDB1F91B2404608B149F507FFD1C9A57D4
+:104B800080FE116CDF398BE5A56054857CBC92E515
+:104B90009DC5B124E4D74E65F9CD1A9DC9A3463E03
+:104BA000207F42BA770EE7DDCD501ED7F886789B7E
+:104BB000A17CED454CCF168935FB00FF9BFB3B0BE1
+:104BC00097D3FE73811F68FFB94B42482F8D2EF794
+:104BD00029365C6F35BADCA7CCC07382CA5C8A09FF
+:104BE0009C9082F4A83CE7669B0CE71DE7DB123B38
+:104BF00005389FEA760FD07A9BCB6760798968E7A2
+:104C0000FE01E60FDFC9FD0165D4BA00BB63275F73
+:104C1000AFF7DD332517DAEDDBFABF90DE17DBF3F4
+:104C2000B0DDDA72767EF32C5DA7C14FF74CA30B93
+:104C3000D31FD1FEA2545F3FD1E8C2F4078D32A644
+:104C40008F523D0E69372D4F82DF81962769BE6FE7
+:104C5000C05607F27F4F2335CD68FBBB1B5D1F8B12
+:104C600093C15F21637E7D6310F3DFB6D5AFB133AF
+:104C70007F8AB782CEEBE99727A17F2FF4862D920A
+:104C80008079CBA4607155EABB869F6FDB6AEF0425
+:104C90007EFDE18088E31071A0EB7CEB7ACD506F54
+:104CA000FA1B22EB2F30B0F1B28065BD0EA8F7F8E9
+:104CB00011063771253D69FAEB06782BDEE6F00523
+:104CC00093F969FADB00F51E3BC2E1F325BACEB3D6
+:104CD000AE772F8C7BDEDB1CBEE2C4C645D6E37EFE
+:104CE0001FFA73E5337BE573E0CFA8C2756087A038
+:104CF00093E74D4B55C146E9EC2A188841BD6955EB
+:104D000031A18C8E1FB83A26D8A6313BC346F36E2C
+:104D1000E887A6E797D3725A6F1394FB75E5D09E88
+:104D2000A6532B5879E09BC6F261BDDD40343B357C
+:104D300009CED6E0578CF92936A61F9FB3FFB606D9
+:104D4000F87D8AC4CAFF1BF260772D36D5F7B0FC18
+:104D50006FB5FA39ACBD4D6479573E9B77CE565747
+:104D600002ECAE0DF3DB83CB7CA9F9E62D889743EB
+:104D70005E9BDF86055B83CB74F3C9FBC2B6F2652D
+:104D800015E9D715B7622361DDBA3BA5B782840B5D
+:104D9000FEF9F5CB5775EB06AC2BE3F8BA30AE9ABB
+:104DA000AD2B146F2AB35719DED65F64C45BEEC512
+:104DB00046BCADBFD888B7DC4B32E3ED977CFC74C2
+:104DC000F8A3E387F5E36F5C681C3F7F9171FC8D6E
+:104DD0008B8CE3E75FF6A9C74FEAF9A6B7C638BEE2
+:104DE0005C6B1CBFB7D638BE7CE9A71B5FA34F67BF
+:104DF000FF16E3BA5E15217AFAC5FB3B8386753D43
+:104E0000C4D675AD7C6DFF4F83B0BEBB617D07FF1F
+:104E10004C395BDF2BDFFD28087EFBF5171D0CC22C
+:104E20003E633DAD7BB822B56EECBBE856DB63B4A8
+:104E3000DFEF4C65EB4CFF45CFB840FFAF2D67EB84
+:104E40004C9C9FE77635268FAF74A4E6E58FBB7147
+:104E5000BFA7E587ED25F2BB1AE0C378B98DDB4B20
+:104E600085CD616A8BBAA68A867C67052BBFBDB5E6
+:104E7000B059055F8AA816C23AE42D277FAEB0D894
+:104E80006F69E36BF0A41F9FED8B53E34F348D3FAD
+:104E9000D130BE96774F63E5AA38A916E0D9CCF792
+:104EA000CDB788BF43FD72F6E09BD61C9EA4878FCA
+:104EB000E553F0B1BC06DF5DE2F45A75D2DF13BEF4
+:104EC0000B4CF8BBC084BF0B0CF85B23569F11FE44
+:104ED000CCF5BA4DFC790309DF268E013922686FC3
+:104EE000C644999F07B1FEAA442E5F303EC4ED2C04
+:104EF0009512934B59793D5DD796887C1FC6EBD7A9
+:104F000099F29AFD0ACBD169F4C358DBAF12617AEA
+:104F10009BDA1DA19DA8D743284FA97D07F363887D
+:104F200062241CB1D007F78AEC7C5890430D00A78F
+:104F3000E893D08F9AAE7EAF2870FB5A359CEFE491
+:104F400092C1A41DE008128C4F2227BFAC5C3E6DBD
+:104F5000241C921889C2387659220FD2715AF3AEA6
+:104F600050F4714C8F6AF004C3088F2433782431D5
+:104F700014B6F2033F2832BF85D60F8590B71F24A1
+:104F800060276AF0B5B9230D4BC19ECF93104FAD8A
+:104F90007EE379F96FF8BC5EE4696B9A733F02D1E6
+:104FA0001810BF34B61AEDD096EA5A17F0A542424F
+:104FB0002EF0D7B7FAACE389B4D46C77C6A95D0AF2
+:104FC000F9766A9742DAEA7BB20ED69DE3C0C7163D
+:104FD000E7DAC37A2E642349DDFED35BEE214983F1
+:104FE000FF348170BA957CC37767B0C8D0CE315694
+:104FF000447BBED5674B40A8D168F0B773F8B57A4B
+:105000001D62CC2567B15F76068DF09E3DFCB1F642
+:105010005E479F6C05D76785378DAFCCFD4B05523A
+:105020000CED623112D4F3BFDDC1F8542A70C5987B
+:10503000BD9EAEDCC3DAFB6839D8C5BE8802E72F57
+:1050400054E4314ECC0572A0C3CF78DEAED5C1CFCB
+:10505000A3490CFDB582126B003E72154B783E6081
+:105060006EA7A51EDEBEE393EFBC8EF231C685F2BD
+:105070002128547E2CC6795C0C8F75D074B3181E11
+:1050800007A9E3943D6A2527631C4C8E5D9188E255
+:1050900062A12696F0CFE4FDF66AF0AB313CF7CA88
+:1050A00016FEB22CE19F99827FBA6316C2FF39487F
+:1050B000D3C13F8DC3534042FDB06F0706857E09C3
+:1050C000B95CD19FCBF5F07E0B387C84DC8474D343
+:1050D000CA3B391EB29DCFDC2CE7D3939A4F1D9F5C
+:1050E000CFC24CF3F9029F4F8F83AD57AEBA8812EF
+:1050F000A47C959F862ECB79FF5B87E972D319F14B
+:10510000D557B39CC7F2D43C9672BE5A96691E51CD
+:105110000E4FAF9DCC3902F13313F97A43EA0D7487
+:10512000D9AEF19593AD1B84DC6CA0CB3DBC9F6CDC
+:10513000E7B33ACBF96C4FCDE77B9C2E77649A8F1F
+:10514000AE7E13AFDFCCE50AED96ED8EBDCD607F70
+:105150003C2E46DA1DB352E3D17A1DFA7AE3DBBA6C
+:10516000B47A6BE1BBB078B85E371F9FDB450FE1C7
+:105170007EAC0D6C0C6ADF7CB1EDC55AB0C769BB63
+:105180008DD87F84AD9BB4DDDDFAFE67B6DDDBCC68
+:10519000EBDD07F59A2E3DA5F5BF59DFFF764752A7
+:1051A00083631BC25137DCDFFDFA7ACB1D7DCDEC6A
+:1051B0009CB0583EEAD5D935C1ECCE7D1C81687CC7
+:1051C00000FC95C4DF0B7647BB18DB3E00FC408D2E
+:1051D000BC9DF4FB6DCEB020D0F5530EC71E817A76
+:1051E000F9AA53B603DD6A633F82BC6A2311888B38
+:1051F000BCCF7BD776C8AF115DB23304F696824739
+:10520000433D0111E379DA84A80AEBE20931FAACF3
+:1052100003ED1EDA251DE7B60225D12580FF96088D
+:10522000CCEE60706DF05E1D07389C142E880F6EFA
+:1052300033C145C7C37D79E718166F4344522E42E8
+:105240007F764F08FAEB1F732BC21B6F72CAD03EDA
+:105250003EF95684979645303ECF1143783B1C2E3D
+:1052600019E2F1EEF3AEDA0CF1766BD45CAC8F7030
+:10527000C0FC279621FC6E124B2E2D05F5D51BB6D2
+:10528000013C8B258C4B8E0736E2FEB66B315DE41C
+:10529000E8B85DE51B5568777CB107E3EBDCBE5EE3
+:1052A00002F15605974904E280DC815EB433F317BE
+:1052B0007958BE98E038F99F67F1B20E322097D145
+:1052C000B420CEE28EBBCAEBD5A560C754B37854E8
+:1052D000A2865F86F8B63CC2FFECC5FDD0BF63BCBA
+:1052E0009DD84329FA16F40EB7CF8D5AC8CB70BD9E
+:1052F0004496F592D9D5CB8F8BD9D5EBCDB25E2222
+:10530000CB7A4956CF492ECFB58AF718E6FB7912EA
+:10531000DA1F5A7C5B0EB5FC87ED935266B7EBED56
+:1053200015079152F60AF0997D494638D6BCD51436
+:1053300038A0B36F02923F80FB8D0BC8052897A35E
+:10534000B43FD1A8060E38469F2F485852E7271F72
+:10535000ADFE5AB0F79CE9CBBDD3AF08A23E9BF699
+:10536000359E2E616925FD5E016903CF7F8DE7972C
+:1053700034842DC6AB91981E2E27918C747073F8CF
+:105380008FC2993F6D522ED2FA16E7E35AEAABB0BC
+:1053900099EC46A3BE73896A2D9E7394B3F8412796
+:1053A0000823C84D88A07E7190A45C86E78BE19CA1
+:1053B000A56353F2E3088E45F9F93F85762254231D
+:1053C0007D428047339F98F9C267E28B4FCB2757C6
+:1053D0009D253EF1C6ED59C98FB737CB7A892CEBA5
+:1053E00025B3ABE78B0BD9D5EBCDB25E22CB7A4997
+:1053F000566FEDBF48DCDF7A590BF861BC5F74195A
+:10540000F26BBFE831967FC967C8772F34B6F72DA6
+:1054100032B6EF5E646CEFBB8CB57FAAFDAB9782B2
+:105420009F275B39F9DDDF2827E5AECCF5F3178F31
+:1054300022572E15F7936E5121C900AC5F749D124F
+:10544000300D272CECBBE7B9FCBFE0607E9CB8A810
+:10545000E2BEF69F7D9E3F9098DF489BEF68F06A22
+:10546000FAF7F7766E6F99EDAF61BFCEC9D3A76734
+:10547000831E21102C4D64854E8DEA1B0FF1842074
+:1054800054C4539EC0F36973FF5D705EC7FC2EC1A8
+:105490007A1D1CCF3B995FE5E7A5ED413CAF9DBA76
+:1054A0002B08FBF4AE0982A59FE594C4CE05CBA2E0
+:1054B0005EB4333A1417EAC3AE09EC1E5397238146
+:1054C000FEE3AE52637B17B71F4E496CBCAE3B6325
+:1054D00004ECFFB6A9BB1A605C67F25F8942E1FE8B
+:1054E000EE8418C68FB63BD93EC0195609AC0B2EB8
+:1054F00045C5F377333C712D6E882482F5BA79D790
+:105500003B19DFFC9CCE279B79BD2B49585F0E339E
+:10551000FCA5C3D7DE33C4D7B54ED6AF127423BEB5
+:105520008E57135C4F8090F6D9048FC6D9DF20D1F7
+:10553000F387793D060A337E3B8D7945BC2A233FAC
+:1055400099FD30CAB6AF65E4E70EBE9E3BC9D7B140
+:105550005FA7120B83BEF35624C832C42F0993B140
+:105560009CEF14F8BF56D546E5977241682B6575D8
+:10557000EF98CE50D2227E6998FE1592515ECE7081
+:105580003D9BE9A4EB9937B59E1D27DDE884EDB678
+:1055900091EBACF0AEAD674AE0AA8CF3EE6A647EA4
+:1055A0002B42EE207D309F57EC481F5B395137501E
+:1055B0007A392B443CE7704E4A10A0B3AB9C24DDF3
+:1055C00039E9E7F51AE73B259879DC1E8EEF6E4E38
+:1055D000A774F5BAF9B9E76B1D0FB5C0FE2D6F1EA4
+:1055E000938361BE171306FE1C92985FA3CBAD3464
+:1055F000613C4B29F38F8C983787D32C57F134F7C4
+:105600006934B9FDABA4303DE44AA0DF41932F4596
+:10561000F957D4735D139A5DC0D471E541F4131F3B
+:105620002F9708DC8331EB032DD5ECC84B48B70B23
+:10563000EE2BAD7DC51EEAB280D70D44D0F9F5CC76
+:10564000FA7A347D72DFA7D4273FD1E47EA43E41AD
+:10565000FA5CDBD1BA1FE8D3E566FEEBFC3A952C89
+:10566000D5CDB79B8FBFC4C9D7856206479743AED8
+:10567000D1D3298F7EAFD1EBCD34F44947F72B211D
+:105680001870560A0EF3FC763959BD7C18BF627447
+:105690003C8CA403C3438BD39A0F3EABF9343BB38A
+:1056A000E3E36DBCDE368E576D5EA3C989D67F1FDE
+:1056B000C757DE3C93DE175503FDED1ADEEA4CF5C5
+:1056C0005CC67A1A7E4427B357B47562B4FEDF967F
+:1056D000187F98FB4F2787BF19964315FDB2DA381C
+:1056E0004EF21CFA0F8E53BDDC5549F7A3BE418C18
+:1056F0002FA07B7D8C6F82F82FBDDE35EB2F4DFF09
+:10570000A7D347E67DCB68F5A58094D14ED2EC9A1D
+:105710007C7E6FD2C5E381370AD6E73C435C8EA816
+:1057200062CF2AAE0FC244001F2442F8FDBF707F33
+:1057300013CD8F0D494A17F83FC4F9FD3B687ECC65
+:10574000CF9CA42B042E9779FDFD94DFD6865D11A6
+:10575000281FE72A1DBEA7D53B1BFC5ACCEE22F61C
+:105760003B5E877BC063AF1409E0D549E6609CF6D9
+:10577000F13594769523E1192B12323E9FA6DC3F3A
+:1057800080E787B0A5FC8A119F64B12E0F7E6097D9
+:1057900071DDCB76DE6678D2B51B159ED43EF4085B
+:1057A0008CEF2499D7B5339DDFB05D9BE5BCB4FB8E
+:1057B00068DAF7D2213B51E07EFB9080E939435E05
+:1057C0004C4B86DC984E182A200A255AF1501EA60A
+:1057D000E387C6E3F7A2A1424C0B8726621A1C2A74
+:1057E000C5346FE87C4CE5A1A9986EE072983B3413
+:1057F00013F3DAFDB79CA14ACCFB873E8FA96F68F3
+:105800000E2BE7E7A91BEE8C12F0574BB00E51F9A7
+:10581000689BBF1CD725F3BC36B8D83ADCCEEF095D
+:10582000B79BF4761F2F7FCCC5E47E03970B22C66F
+:1058300088DE6F7E3FAFB7A12C8AF677BBB61E1607
+:105840002E37AC87E6FAED69EE273FA395737848CB
+:1058500079FD28F461E7AFCE4014EF0D101245BD7D
+:1058600044C4A841EFB66BF067798F70C3FC6790B2
+:105870008FDD549021B4D0FD856D0D0F83DE5970FE
+:10588000EB7507A8DC7DE88CDEE68271BFB002997B
+:10589000EEFBAB6E0F82DF77C3FC7BF17E1398DFEC
+:1058A00010D7DCB1E08ED8C3C87551B4B369BBBBA7
+:1058B0005CBA73D0CEE5B737ECA2FD29AD36A2E8CD
+:1058C000F8B5E40E0F51F4FAEB644121B42FBE2574
+:1058D000DFF0BD686591A19D764F22784D99A19E1C
+:1058E0003CEF3C43BD9CB9338CEDF839B9AFEA428B
+:1058F000433BA74FC32B3B47A4F437AC1F1D823556
+:105900001D632EA62FD3F1CD152EB6AEA5FACF4C22
+:10591000B774FD677B2F24C51F69E781E710B1F8D5
+:10592000E279604F39E528DE5339F3FA67771ED9FB
+:10593000D633EBAB1CD05705A04F044C7DA0AF0A6B
+:10594000408FB831D5EA9DE97DDB75A06F7C3A7D4B
+:10595000338BCABD053FF8DC99F5CDF9BC7CB29B11
+:10596000E99B759CAFCC7C13E4F5D681BEA9185D8C
+:10597000DF04DD99F54D251FEF1FAD6F3A67DC1B86
+:10598000FD16CDB92FD8D6F0104D3B2A6FC53CD5AA
+:1059900017A29B9677CCBE23F6904E8F9093FFC9AB
+:1059A000F892F3436EB5517F68FDFB43263DA2C9D3
+:1059B000C3DF28D7A738BFA6A3CF914F29D7A7CE3B
+:1059C000925C9F7275CD83F3C56CE57A64FDB33B41
+:1059D0008F6CEBA9B5247909EC4BA678122DE0BFAA
+:1059E000B4F586D8BDBC28C6ED743EEFE07E1EE659
+:1059F000FF9BE10A2F02FE99E18A2C76D3F63797B6
+:105A00002AE3609DA6F92FC2775D3E62CAD79BEA62
+:105A10007FC594BFC254BF415F1E57947170BE18BA
+:105A20003FE4C0F3C1B862ABB3E2A7856EC62F876F
+:105A30005C9128F4776EE2BC7140179A5F86FDB9DD
+:105A4000597F347F8D29BF1CC74FE5AF3395AF30E9
+:105A500095AF34E557E9EB779E9A781FBEBFF14BBF
+:105A600007D969E14F7A95EB898EC9B7479B995C55
+:105A7000DE06ED3BA6DC115B46902F08C06DF79962
+:105A8000F67F94CFF4FC7288F7F3F309B7E2BEA96E
+:105A900083EE9F308E11FC7816F8F9B59BBFC3A535
+:105AA0005C8FF71FE28537A39FA3A3B819E3148E79
+:105AB0002B129ECFC64BADDB7736323F5347B1F545
+:105AC00039C2AF210857678F9049CCFF076270DA5F
+:105AD00006EF0931FDDE56DA8EFA554A5ECFFC1B21
+:105AE0008551F46F3CC8E927F962E8577016C72C56
+:105AF000F7F51DC3F830FA35F769F8E0FB481D3EAD
+:105B0000500E9B3B3F3C00EB6BDC6D2D673F7633CB
+:105B1000397304B31B7FE4FCD9FAB01D2EB558ECE1
+:105B20006BE30E1627AF4E607E00918EA3F72B9885
+:105B3000C71B9EA7699FFD00C753DCCDE2ECB5FEF5
+:105B4000CCF03CC2EB3DE2667E056D5EA2CCC61990
+:105B5000ADFFE7E0B216F80164B31FC2A8E7EEE0BC
+:105B6000F51D0163BD74F8B973183F2C1E4BE3DFBC
+:105B7000D1F85D1BE710C085FB59EB7DB872B21AF6
+:105B8000E3378E137F6F17EC9B45F97588E3B88D6B
+:105B90006E93C0CFDF22AAE85F501522EFC4F34F07
+:105BA00076FE709BFDBC10E83B178FAB20105711A1
+:105BB000D0C525829FF35C8CB37804CAD7A84E1950
+:105BC000DE3719724F6471AB27D7603C4527DDA9DA
+:105BD000C3B827DC250978CFCA9EDB8DF6BCDD5E15
+:105BE00019B38A33153D8C6F2F39B91EF56CBBC2C2
+:105BF000EEDDB48B51577E05B8AA5594D74E257368
+:105C0000FCA2390ED2219BE30F8DF89AE661F48D48
+:105C1000F3F537EE0E35E8E393821E37960FB98D14
+:105C2000F075007C3E802B86F1A4F1629B0DF0762E
+:105C3000B6E0D3C6954A6D11C04B8044315EC515A0
+:105C400014715C9B97E137DDB844113FD0BF1F73DF
+:105C5000B6F039BCFE46193F89C483FCA4CC73D589
+:105C6000EE86FCF3CC2F6F1EE788277A8147E71773
+:105C700016E528FAB7B4FE168E6171DE6231C1FBFB
+:105C80008A1289D495D2F9B714B3771645DF2871F3
+:105C900011C5667F45BA7339763E824554446BFE22
+:105CA000C0C6F5F078013F19C060D15C50E91321FE
+:105CB0005E4011D83B102181C595CFC538F280FBDD
+:105CC000B3EE7709F62B843790D3DE33E8571C40C8
+:105CD0003FD767DEEF28F0BAC936EC1742534F17AB
+:105CE000A4FA05FD8B4EA593A74FC3B9999D687F74
+:105CF000CC0E176DEC5E1529CAC1B8C3B6C0CD2E47
+:105D00003D5D9B3C6586F55592DB6F1272E0DEE7E8
+:105D1000CAF04006BE6C0339023F62F135E181F200
+:105D2000F4F53438453A7D2B7F68BB144D3481BD82
+:105D300058E263F1AA620CCF473A84FC195D553AE8
+:105D4000FE2D96920097BF2AAC423C6347812D04FA
+:105D5000715822E93E8CEF3BD9178732C9AB582CDA
+:105D6000BEAF9FCF568F310EA465147E6FE3FA3A13
+:105D70005DB9430A45ADF4F0131EBE8E79ACCB3F3E
+:105D8000F6D63EE6B15877F6723DD5914755E9E72C
+:105D900018FB001F88C5075F073CB48D5990593F19
+:105DA000C946FDF45FDEF04F609C0C703C67050750
+:105DB00081C714B2B0FBE579188C988A070A30BE07
+:105DC000863820612C9CD2B2BF75550F26C1EE7665
+:105DD0002CF585817EF6F06E02EBA81617640F7B1A
+:105DE000DEB1213DE7B2F8A072E6670DD3FF308E39
+:105DF0006C6EE6B831BB29FF2B339D1B9FC5F72284
+:105E000034F8B53875F3BC9EF2D6BEED9965858F32
+:105E1000ECF6419B28BF10CA2F1BE9FA4E91427A3B
+:105E20001B65CCF7340631DFDDA860DADA588EE97D
+:105E30005A683A07E23F62F152D88F041F0E5E4B58
+:105E4000AB6C029A605CCB8EF9B08FEC1ACE135516
+:105E5000807325B81F4FEDD0BF7A36CEE7E76C3C94
+:105E60006EB67D3E9EA30DE7B7B4815DD8C5E368ED
+:105E7000E5B50FCE87FDE3A609DA3E39ECFAAACEE6
+:105E8000FE9AEC75B073A652AD7D4B1BF4E7167904
+:105E90009EEC996FCC9330C0E376B1FC42EFD3080F
+:105EA0000FAA003ADEE5DE6730BF6932F73B54D413
+:105EB0008F8247E6C768F728CC0EAAC8473F8514EB
+:105EC0000AC1F502B2298FC39D653FB0FFC1F5EE4F
+:105ED00015EBF5322537A3AC6B1C8ED1E84FD18181
+:105EE000F605E86115C67DD58EF270B6C7DDE438DB
+:105EF00033BC48D5832A5CFDDAE7895EE4A5EDFD75
+:105F0000E1BE6429CDE72C4EAA28BE598E5BE8E598
+:105F1000F7C9E87C41FE353C6B76C74D40C731A9D7
+:105F2000FE1C8130BE23E1E6EF09670BEF728F6C38
+:105F3000E8873C5E5B98E9DC654CC4064146C3FAE1
+:105F4000A2A0CEC38335583E2F9C6FC8E7561719C1
+:105F5000EAFB43658672877C9EA1FC6FA5D3D73D83
+:105F6000B281AF23A679CD379567DBAF7B8D5D819D
+:105F7000F7204B45CD1EDD88F7928F038E413FF60B
+:105F800056E23D5D3249BB8740C210AFE256C2C8FF
+:105F90009F1E12C2755A2A36DAA962C068A7061B6C
+:105FA000D4A4D62FC425B8D74838EEF03AE563F12B
+:105FB00020DA3919EED72782AAFBDEA152D6CE32DB
+:105FC0009E414B457E5E8677EF4B473F4F358F13A3
+:105FD000FC4AE63835737DE21395A33AF94BDF4E60
+:105FE000244775EF6AEC00DACF4AE13FBC7B29FA1F
+:105FF0003D9C84DAD114CF2DC12B4894CEB31DAA79
+:1060000050FAC521A57CDE1E9C21631CBEC2E86A35
+:10601000733139F98E5731C473D87D4C4EB47AA39D
+:10602000D1FF363B8959AD67AF7AD93EF9C45DB12E
+:106030003FC1FE527D99E03BAE7D8D43F8CE655564
+:1060400072A11DFC26AF7BC7E27CAA0E84ED97EA05
+:10605000FAA922ECBD6FFA67D7FB5335FF3039E957
+:10606000C2B8E03D491617BC27F9DFFB4F43FE904D
+:106070000DDF15DD7338B37DD5C7ED2BAD5EDF21A8
+:10608000B65FED1389373F939DC3EFBF55264D7122
+:106090008722B103FD4FDCA9D8C1DEE96B7409B0DA
+:1060A000EECFE0F3AC4A86EDB09E8E36AF7D26FA99
+:1060B0006AF384FB8730CF561FBB0FD82AD3F9224F
+:1060C0005FB3F7B2D3C13BBCEF97ADF121F9D9BBB8
+:1060D0001792232A5BCD7BB47B8A1A7CED009F004C
+:1060E0002983AB3DC0E8D01ECC4C87160E9F56AF1F
+:1060F00035C0E8D04AED836CE0117D4678A88D2745
+:10610000805DE823893A7CD34C252FC33E08558512
+:106110000278D897BC1FE0857B1760CFE75509D779
+:10612000C2BD8F28B30FFD55C9E4DE009A2711B810
+:10613000975130D09F7C9B961F6CF0E2634FF2B575
+:106140004792D08F280FA2FC74C160681F4D6C0766
+:106150007BA70DFE4955FAB8EEE002B03F44C2F409
+:10616000029538451CCBED130B79D79DEF0BA79DFE
+:10617000A976E9F066B63B9DA43EB3BEE2E7FD2AF0
+:10618000FD0FF48D6CBA1F61B673CD71F017813EAF
+:106190001F93C53D8C4F394E2E79D005EF21D8CBBA
+:1061A0006D32BCC34C557A1EDCFFF1864502718D01
+:1061B000B9BE017C3A6B34BC53FD57C7E246FB883D
+:1061C000FE1E69BD8FF98102F55582C0EE1128F0DF
+:1061D000EE66A0FE50C88A4F35FE1CCEFB9E44FDE5
+:1061E000D8461271883B51EB6CB8AE759597E5E9CE
+:1061F000F74737F904BE0FD5E84F1471768AFE745D
+:106200007E61F7F4BF1FFDF3171BF17EA674B9D3AF
+:10621000C7F4D268F4FFB4E368741B291F4D9C6E69
+:106220009B50FF754ECA4EAFA4E8F620CAABB79C90
+:10623000841316ED9A39BDCCF7F65D2446E0F728B5
+:10624000ECAF307BDA3E6E76C30E92812E23E2AC49
+:10625000583F761FF3A7AD133C21186A5D1AFFF271
+:1062600024BFC0F5FF008BE79B733008E7C7DDB3A1
+:106270008E06E19CA3E713EB73C8857E7E2E127E0B
+:1062800003F7013DB3985F10FE40EFDCC6FE49CA3C
+:10629000D4F736C33B66EBDEF21AECA1F6C6CCFEB1
+:1062A00006A9E8BA28D81927DE1114586F84A23538
+:1062B000E7025CFD7396E3BB23ED55FBF01CA63BA8
+:1062C00094992E5A9C6FBB29DE36DDB9E1092EAFB9
+:1062D00065EA0D685FF614BE8CE3ACABCA3C0EBC3D
+:1062E0009795299ED7652351F4179BCE75DFE4E37C
+:1062F000BDE9E3E7138EC8972696C2EF72A8E81FA0
+:106300001B5B1EE9B751BCD5FBA3AFF9285D7BE64B
+:10631000DC5A0870C03B317ABA07A07F0BF8C6FA86
+:106320006D06BBE94459ECBFEEAC82DFA79882EF63
+:10633000D66BF5BAD3C4B19FA7D15971E3BEA71DDF
+:10634000E2FE297CDD85D9E15FA3F325E405D7448E
+:10635000680F71BE19F8D9BCDE8F8677331E7A1CA0
+:10636000031807D52358CF67A19FC95DCF9D4976F4
+:10637000AE36E7289EABF9926F60FCC477671DC606
+:1063800073B5123FA387DF378071A539D5EC3DC0C7
+:106390007472F400A79F281BEB1171C070EEB3DD7F
+:1063A000C7CFCB0299FBD3E024AE0176DE33522E69
+:1063B00071FDD9D9FDF0417C378524F15CA1FD55F3
+:1063C0003BDC4D1DC6C308B98AB3DF85E9818DC7A3
+:1063D0008530CE5DEDE027E9D1CED92AD9BE49ACD2
+:1063E0004AE2399BCBAF18E3AF43DABB88D9CDD3B0
+:1063F000076B11F30F8BB0AE823F1EE06BADBC029A
+:10640000FD69E9E8FA1D6F74A67F8CDEAFCFF65DFB
+:10641000FF6C7C78C2A718EC43333F3AC937CE688B
+:106420005F97CEBF7C82CB67002AEAF649DFF44B48
+:10643000D6F87DFBCAD1F0FB4D6BFC5EE501784FD1
+:10644000DC63FDFB445ABAC5A4EFB668F128F0231B
+:106450002185D85FE9E516F3D6D6D5137EEDFD9EEE
+:10646000A807D68D3275AE07C6DFD5BDCC03E3EEE7
+:10647000DA9C999EDAF8DBF9F96282DF77D1CA13E8
+:106480009C2F7798F4FC2B5CAEEFE7F2B5CB15F1BF
+:10649000E0EF55ECBF6AD1548ABF32CA17E05254BC
+:1064A0003A497EA6F14B55D3BEE40CEFB5F4F84D56
+:1064B000F1BD59DED3FCB478D901FC7321E0E1DFF2
+:1064C00051EEEDC95C94A7B2958C6FCAAE194CC25F
+:1064D000BE76E2265B42C1389628E2A570A5A86088
+:1064E0004C1BBFF77A2E5FDF89FD0E5B0994C3BD9D
+:1064F0007119DC2EF2D7301E669BF1F73F76B9C2D8
+:10650000CD12D8BF718C742465DDC6DFCB184F74F3
+:10651000BF5741C72D7CEB3DFCFD9442D3EF827CFD
+:106520005ABCEFFD07E13D21128F5E1F2B028958F7
+:10653000E9FDFFE47CA9341D60EF18C47CE45DDD57
+:106540003907A55F3ED805DBD58D35804F354E42E6
+:10655000932DF4D86FFD5EED777C0EC03B0B8E6201
+:1065600076FFAC6DE915037BA9CADA7E472DB13AF7
+:106570005FA17AE1B77E5C9F985E48A8F52C3D69E3
+:10658000473E99DC4D12F03B28F336C5FA1D20EA50
+:106590002BD93BD48571559068BE8C9AAFB47B32B1
+:1065A000F13AC2EA2F218930F211792D3836F57B84
+:1065B00027250337F5C3BEF820DD17C3EFA868BF52
+:1065C00057A2F1CBF898913F26C78DF971267E31FD
+:1065D000B72F53C822187F52B78DC0BE6E4C83AE02
+:1065E0003EF44706DF7B848E3FF9003CCC48D3DE87
+:1065F000CCFD8B24EAC8A1F87CFA2EDF2FCBE9046E
+:106600001FEAAE2D00BCEC721176EF22E2C27717C2
+:1066100048C4FA3C6904DF6A767F9AFA297DC9EAA0
+:1066200069EB5EC75B027BE7A2447EA714FC9CAFCC
+:10663000B1DFAD4BBD5B7121BE5B112431663F9272
+:1066400008A6AD9C3FE54B8B4BC11F1A7FDB2BC3CC
+:10665000FD2CB9C0E84F13F3EBF03DB061BB3B9F9D
+:10666000DADDB43C9E67D4A33539CC6E0DE5B07B42
+:10667000A1B297F5435C6AA15EEF6FCA118CE53E4B
+:10668000B5F0CBBAF25ADE3ECEDF2DBF24675107FC
+:10669000D833F2785ADF823FE7F171B57212081DE4
+:1066A00086F73F367FA37E967E3DDF94C3CE77E4A8
+:1066B00073F8B8C5D670C54BD9B877F37137E518FC
+:1066C000DF8D23324BB5EFF7FA6F158E507C9F703C
+:1066D000905A88576919634BC0BB69B78DD5E2C220
+:1066E00032EB098D0EC3F896593C52D175F20CBBB2
+:1066F000851C6BE9D63AE6A7327FBF9ACFA3F5BADD
+:10670000DADE4914AEF0012677CE00B13C07A2F2E2
+:106710007D75CE2C8B75BFB50EF77127F232AFFBAE
+:10672000E67DAEC8FD8BE67A4D9C4ECA2B417C8A35
+:10673000BB35C8FC895AFF270A995FD1DCAED3D498
+:10674000BF9BD48721CE18CE57E15C559A4412499D
+:10675000DA8F27D02B972A101F705885FD91422879
+:106760001EC1CF162268D7B506D97E540CF6D6D8EE
+:10677000209E84D4C97A3BAC88FFAEA29677F8A25B
+:106780004D39680F8505C48BC8CEF34F38120B0105
+:106790009F2DA53662F54E7F770EB373B72AF52F7E
+:1067A000965AD06F438E62B09F8B8698FD9DAE7EC9
+:1067B000AA1E836F981F832ADE3F200AE3C77A7FD1
+:1067C000F89E1CABF35B4DAF703FE4B26AAE7089CC
+:1067D00072E5AFE93CAE3FE4C0D8F44B4E6E3F08E3
+:1067E000FAD74EF56F17FE8E5CEF41F0435E03F76C
+:1067F0009F68FEFAB7A64925B4FCB5223B7F743EDC
+:106800009203E37E486CE82FF990BC9C335347BF5A
+:10681000A77224B6DEC41DA847357FDCB5BD0E8344
+:106820005EFDF666637E39A91F0B7E8AE59B1C24FC
+:1068300041F17BBD49EF3E94C3CE89BE4D62EDB0C0
+:106840007EB6F1F3BF1B7F324D02B9B97EA65C6AFA
+:10685000D7DDBB7A2E87D977EF533E527472B6C21A
+:106860009790601FF7EE9E99577C9E403F89F622D5
+:10687000F0A7E559C7017E2B6E8473B47998E1D6F1
+:10688000CEF3D2C121EE162CFD42CFE708067F7C65
+:106890008B8BBD87146E1189FB6288C3A3020B70BA
+:1068A000BFE5C7F7BBD5DA18C6D5A9CD4EB9258047
+:1068B0007176184FB786120CDE1F3ACAF94F8BABB0
+:1068C000A306C505B04FBBD13520815F79B518ABA4
+:1068D000839F4ED3CE659C8E68783C85DFF16C4DEE
+:1068E000723C31D48B6759EF90509655BD3A5B8618
+:1068F000FE8E713DF98BC71F9260FDF9F0B177BE36
+:10690000087278C373760257F38E3DEE2749DC3F59
+:10691000242490F3157BEC96EF48508C61FF37FCF4
+:10692000C88F7A71C593CEC462DA7EC533EF4E2725
+:10693000549E8E350F1E1C0FF87B4C60E785EAC015
+:1069400074589F5688E49B56EF8EB97399BC7FF0BC
+:10695000536F03D04FD8DD7F35F6DB77A543FF2E8D
+:106960003EC965EB0FADC7E2261F1512932DF487C4
+:10697000B61FFAE0511657B2E2594702428257EC6D
+:10698000DE2145291CAB777F84FC72E98F9EC8010C
+:106990003CAC7ED66EB0236EF8D127ED17523ADFAD
+:1069A0006027838B418EED27317F3CEC1AB4A35CCA
+:1069B000B3F89455A80268BDA77EBFE0D7B4FCFD2C
+:1069C000A09D4088EBFB877F273D07F9A88F5A6E73
+:1069D000D0BF91AF57EF7E57C2DF31B291C1E2CF46
+:1069E000C3F987D14E32D7276450023DB5BAAFF311
+:1069F000233BE5B7D57B3E7C13F86EB5493EDE8779
+:106A00007F148EB4CF2B734DF6F9EE82ACECA31B42
+:106A10009E38FE00F8233E78F28F0FC03DDA95A72E
+:106A20003E7EE07B1017F66F6E19E47BF563AFE6F0
+:106A3000109DFEBF2C97AD9BC71E7D64D7563AFFB5
+:106A4000636F38115BC7F6FEBE04FC3FC77EFCD700
+:106A5000B1E00FBA65EF7CFCDD9A5B9EBE745CA66C
+:106A60007511F835A1FF7D457E6EA43C2B80314920
+:106A7000C8CF786AA207E91D94605DFB8B4006BB16
+:106A8000F2E8F7BE4F24B0CF0E86C920E067FF9E24
+:106A9000770FDE4EF31F52FA382DE843E73FDE86CC
+:106AA000FA998A0D4D57EDF9F2972EAA82D4817684
+:106AB000F86A32887A73045D5FA174AD4AD1D55CFF
+:106AC0007E9C9C94E0DC60F5E3948ED3819E948E52
+:106AD000D347D2F143F8C79C91745C916B8C4B3ACD
+:106AE0004E566EDF0A857B0A2CCF79B57DD68D4F49
+:106AF0007F35A3FDA4E985D1F07C9DC0E09A9D1B64
+:106B0000BE3D17E4EBC91FECDA1A60745E4C1173DA
+:106B1000EC89E32584F2C91F1C8357031E06F73A4C
+:106B20006558DF57ECFD15CADBB1A75F92148C6F77
+:106B30002139C26C9A27C37F2F139A5F25B0CC8D61
+:106B40000FFFBF056FD2F637C2431E32D20FF307D5
+:106B5000A9FC213D1297D729A077136370DEAB12F1
+:106B60004C2E5625FABF02717D66BC3F956BD3F45F
+:106B7000FF305D216E6CD59E771600FFA5A3A7366A
+:106B80007F19E67F012D7FD828B769E594D3F7D820
+:106B90008E1312D807C9E724D946EDE1638E410967
+:106BA000D7C71FDBE59DA191744FE19FC71F9DE1F2
+:106BB0003EFC876639E7F8194DCE479FD799E16DBE
+:106BC0005BAEC2F65726FC7D70D25AFF3FCFF5C6AA
+:106BD0002A12AB2B9A3872FD1249441D5F9A82F734
+:106BE00003881FA3F07EF0981DF787ED7DFB518F82
+:106BF0009BF5C5AA3476F49BB9CC1E58F56CFF748E
+:106C0000D06B1FECFB29F2E5AAC7DF91C07F737040
+:106C1000F753D240454A0E607DD0FF0ECE073FECC1
+:106C20009F0EFA6B759A38C0DFF3F9ACFE99B1FF8D
+:106C3000D58F7F64E8FF06B54F423FD928E3BC2FCC
+:106C400086AF84F9BE7FD8012718E4FD3E7B9D9571
+:106C50009DF3025F1F353CB5FB67BF9E0BE75EF9F6
+:106C6000EC1DC6D6A6F0AFF0F77B5F72F0FD6DF8B5
+:106C700075B0675AF224BC8FD0EABF02FDF55A7F87
+:106C8000BD267CCA01B906F603F2BC48957E5FA515
+:106C9000C19F17B619E0BFC55F374EF1B1FD9942EC
+:106CA000F71FFF03B64D466E008000000000000095
+:106CB0001F8B080000000000000BD57C0B7C54D516
+:106CC000B5F73A73CE3CC24C2627AFC9D37892F0C1
+:106CD00094804312DEB40E0491226A505AA9F5AB97
+:106CE00003F28821C9A4F8E25ABFCB8444F4029F7E
+:106CF0008D95166A693B70A152217690A0B10DDC8A
+:106D0000012C06056F105F78B18D5A152B24631482
+:106D1000B4575BEF5A6B9FC3CC9C4C84DEFBFBBE2D
+:106D2000DFEF0BBF76BBCFD9679FB5D7FAAFD7DE02
+:106D3000EB0C28DEDCEA5400D93D6B366461AB5ABB
+:106D4000D41409E02BFABB2AD6028400C603585D8E
+:106D5000D5E07761AB5A407300FF7D45FFA7785BB4
+:106D60007BF0F97BE5D4D6B5348FB5F157D48726BF
+:106D700005B657F2B0914A25DDBFC2BBB61860A375
+:106D8000F39F1FA7FB2B8376D58E6D73EA3DBFA5BE
+:106D9000FE0609AA65EAD3F3383E6875A8DB55BC40
+:106DA0009E0E0BC265317AF25424321BA00CE9A06E
+:106DB00016FFFC3001DF2B488266A8031C0129590D
+:106DC000A120B5C6730FAAFE62757CAC2FBBBAC1F9
+:106DD0008FF35E2DBB2CB4FE07732D217B31B537AD
+:106DE000A641D9403E18ED03ABAA213262F0FBADBB
+:106DF000D98E855B80E90E5A681D9223B49D08F1F7
+:106E000081A67A8069030DFF873C74C4D18D037C11
+:106E1000B40E45BF6FC565D14D3B04B94D213960F6
+:106E2000EB84084029D2AD96B05C52A1479F240A5A
+:106E3000D563006E4CF57F93D6993BB451A2EB1EFF
+:106E4000A8E6B612FC12DDB738EBF2FC5FB33E5891
+:106E5000A09CE919A9CB175FB1C12AF8AF28A00CF3
+:106E600029273A36ABEF8FC679E87E268D0AB21C09
+:106E7000C6557D67740BC181888FE3F32333676444
+:106E8000126E8C71CD8EA29312F2DB27A7A8294532
+:106E9000D8579033C4A753A9CCA71F4DC399F1FE6F
+:106EA0008F4FA56E95511E8F48024F41C213E10AC4
+:106EB0001A1F277CB8113F6BE9B9198DBF65BC5803
+:106EC000A0BAB952E7A487F827FE106F8CA7958A5D
+:106ED00043B57B89B73E4DA1796C105A2B11BD7E0D
+:106EE000E6A7035AB91D02616E5DD0CDED5DC4E722
+:106EF0006C928397FB69D0D33A149F9BA356D7AA71
+:106F000078FDC7B333245A9F0B549DBF8579D41F96
+:106F100094BF3391BF8E187FEDC44FE7407E3A4057
+:106F2000653EA47BC1BB761CCF0B115CC723D3216C
+:106F30002433885450112F39FA3A33C127117D84F4
+:106F40001F5A5FF602B13EF3FB72A195C7E5439865
+:106F5000DB42E8E636C3A14A0AD3734A97EF3BF017
+:106F60009533468FD1DA09C138FFB9429CBF98B931
+:106F7000ED963CB47EE3AF9A71F887CA83BE2A1CB3
+:106F8000A7F85D3E3B2EE5FF54CE201082F572053A
+:106F900048AEAE9E8573C18DC3BD36888CA4D9839F
+:106FA0004C5FCA48D137EC8B1D051531E8C7E7ACFB
+:106FB000A73E3C45CF59216E1CD121DF9A467C7FEC
+:106FC000982E4C1EC8F795A79AB29E8B9B77AB9ACA
+:106FD0009A45EB848930F12B39F63C4CCA40233377
+:106FE000F0F9CF5605B39EB3C6F8D0E2F867C6A550
+:106FF0000F019CF24DEC138EB36238465CB29D0BD0
+:10700000AEB6ABCD598C43C6E94A64901DDBCF5276
+:107010008A42BC7E689C7823DA618BC3274978BD9D
+:107020004E7587883FF5AEF02CB61326BB317DBE7A
+:107030001AC9C7717D8DE025BE6EDC73C369E26B32
+:107040009F07347BBAC0856F02D909C38E8026A3FF
+:107050007CD748E31C12B6F5ED1FBFF47B1C9FD212
+:1070600029838CF7FB70CDDDB46EC5974E4274C298
+:10707000FA04FD6E7608FD31D669D6D77F749D2857
+:10708000799E9FE52093FD5DFF2FF47C3FA4B6D24F
+:10709000F84D0ABE9AE6EFB286B6231F561C911928
+:1070A0006F2BDAA410909C152D8DFAF7BE2883C0A3
+:1070B0001FF0FD7B7F55CA789461F48FA6E1F381C0
+:1070C000CD562F5A4C48F725FAABCCD943408BC349
+:1070D00001047D2FE722BF16EBFCDAE87C780BD1A8
+:1070E000B3A949F8A7ECEA8C84F19FA55C6F5B8A91
+:1070F000F36B7948D714C24DE7F035D85F5E20AB0B
+:10710000329A889C05F989FEB1D5FA0EE99F86FF6F
+:1071100008DF86FD5A4AF68BEC907C3FFBBF73205C
+:10712000FC9F02C2FF35A0BD8AE07CCB3689E78D8B
+:10713000F96A3A1F595380ED1DA1C4EBCB4189F583
+:10714000D9CFBA47921D580943BC766920FE2DE974
+:10715000887F02890B5C420E2E2FD997FE5764AFB1
+:107160005DB082F595F84E7644EE19B1711ACE17DE
+:10717000E8B24248237989FBFD9BE550B038A61F51
+:10718000FD5D7B981FCBF2901F884F7B6E22FF53D3
+:10719000B444FE3B47667CAD3C52BD267ECA739923
+:1071A000FFC86FA0F9D32695243EAFF37B24FE13CE
+:1071B000FCF6319D4B3B24784C223EAF3F5CA00D4A
+:1071C000E46B43C72336D2FF8BF1D5CCC7D1E9BAE4
+:1071D0001DD1F9780E3A0FE8A8AC7678D894F03A39
+:1071E00014B5753AE1B410F5967062D66B837FD60C
+:1071F0002CD567C37197D1385C5FBE232C94D10B1B
+:10720000CA09C2CB2261779B551FFB23C3DE3A2FED
+:10721000D8ED77E12B6CB3E6553E4438BA534A6D4E
+:10722000952B07EAEDBA31F7B0FD2A5C8DF698FD93
+:107230006A629C165EE5F02E467A9E5C05DEC5C34A
+:10724000009E5AA5726B8EDF0C7DDF8CF19B5DF882
+:10725000679E5741FCAE55C9FE7855A2F3611BB03D
+:107260009EF69541682BBE3F1CF9D4A391BD2E8F8D
+:107270005E5F8DF145600954539CF1AF1922AE7BDE
+:10728000466F6765D8B85D5B6D011FBEA7B7530E2B
+:1072900049485FAFEA3B7215D99D4EABC6F1951ACE
+:1072A0007DE97B7CBF425D8BFCCCB3B48EA3F7E25F
+:1072B000F8D9219CB7AFF35DF7ED717EB9B7E3D193
+:1072C000511407FDCC0235E124F1D0F2740BC73123
+:1072D000BD23DFF1E0B2A1DE11B501E2E9C19EC636
+:1072E0006A8AA7EE746A4C97AD7D7AA480F1338FD9
+:1072F000E3E3E7960E61BCED3D0321D2BB59F2AD4D
+:10730000D78EC1FEE45715AF9D95CA77FDC2093CE3
+:1073100084E5BEE1CB8A4DC4BF00F273355F6C3D9E
+:1073200041F27AF6CF0A90DE55363EFDAE1FD77990
+:107330003817D1300960822F5C11C151333BD3A77C
+:10734000937E074E01EBEBF86E2501B720D71D2A7F
+:1073500020BBF286080F27BE61BA0F4199E2FFC930
+:107360003D89D7A75E04EFFF62D80D377808EF8F0D
+:10737000ADEA8077C92FEAFE331F17988C9F06BEAF
+:10738000F738673C922EE2769970EB55928F7F2703
+:1073900043C4F91BBE9425C2655F14BCAB915F7DED
+:1073A0008BF379DD7D9F524086ED97F2EC709278F9
+:1073B000EBD7E93696DFCF6C02F73F5BEA0A35E19F
+:1073C0007A0E2EADBDBC07DF77FE9FFC97AB5F1733
+:1073D00007A369B14C6279A511DFEF9CD722B11EDA
+:1073E000426B1EF1CD3CDED013436F0C7DC95B3A7E
+:1073F000C41F4AF29EE1B43EA46FC6D291928D7032
+:10740000BB5F029263EF6AA4EB6BE2C720AC2E2055
+:107410007A021D9FD8C85F3B3A255F28C9F8C3E9A7
+:107420006EE65FEFEA60D354E4D73D8BF059D20BA0
+:107430005B6B71B2F983B0A1008343684BD704EE54
+:107440001D701BE92528AD79E4B77B3BAABE4576C4
+:10745000FD31D4438A1B7E66F532DDC17A80EDC4EE
+:10746000160A3CB15F783D6C591B974776A74F3F92
+:10747000958EF39D4A5779DE4CBF5722BABD7FFBEC
+:10748000CC4DF3F77D6E67F9E5930EC7C56D9FA6EA
+:107490000BFEACC9F0BDC678A9C96263EAF5BBBDF5
+:1074A0008B2B00AEEC407EC7E13226B720AF3BC34A
+:1074B0001F647A32BA3171E2FCCBA751BC1CD08D6B
+:1074C0003344245026C4EC73A5A3305220F28770B5
+:1074D0000EF237A3E6C76CAF53D00E53280EDD89EA
+:1074E00079115B647C9E749FEC42B32AE2AC967483
+:1074F00061E75A1E5142CDF8DECD4A4FCA306C8B3F
+:107500007DDA0C45237B5FC6F3E6DE05ACDF16476C
+:1075100048223BE42CFD45FA85B86B2AC0EEBFC972
+:10752000CC7FB39C46EB7AB126C3FF05F1756C574F
+:10753000F420856FDE14C824B9CE925DBCEEC96715
+:1075400085FD31DB1B39F2AB9F91BDE9D3F3A72455
+:10755000F6E676F2AF86BD01B9EC10E167EA8B7A08
+:107560009AA9DB19CC3E980F138FFA9B5D49ECCB9F
+:1075700024A84E43165FD4BE98E588C1FE857E21BF
+:1075800032A3A20BF528EE79B33D2AC8D0FDAF6E29
+:107590008FCEC1B49CABB5185ECA577A0FD9E3F051
+:1075A00061D8A1185E428C33F37B24705CE8ABA5F4
+:1075B000643F8ECA696477A6A3DC71FE2E5D4FD24C
+:1075C0003F0D7D8BE4BFA1F39A14C2F5535D550EB8
+:1075D000529B15B9B2F6678C9F9503F383A0C385C0
+:1075E000EC9DF15E2B3834D748E28785F920ABD883
+:1075F0008F7B7F7FAB349BEC220A2D6DFE98C1ED13
+:10760000C18A5C1BBFE7A9AE9234C2910B30BF4563
+:10761000F955764A1C2798716DC67133BEC0C27980
+:107620006335C713B214D6F71D12F3D2E2E064F645
+:107630005377611E4E716B7F17FA2D6C9F423F4F3F
+:10764000714AB36B16AFDB58AF41DF5DA93372A04F
+:107650006CE0FA8D36F0B90CA1CCB8BE12B5118E23
+:10766000039FDB12AE1BFC1C8C0F063FA7103FA52F
+:10767000FF3E3FA76608B99AF9FA3F5D7FE18A4964
+:10768000906C5FE0FF97F54F05FFEF7B44BEF55A26
+:10769000AE27664F0A57CC9697211F26503CEE8D99
+:1076A000D90707FE237C8DED68657B3309ED0DC599
+:1076B00099057561B62F137345BE64B61B5776C224
+:1076C0004D641F2747302EBD04FBF129FD471EEFF7
+:1076D000E3FC3203E91EF7FC82E5BBF0D2580D3221
+:1076E000E7E27BC6762B5EF27BD09D99745FC0EC9F
+:1076F000378CB8D48847CDE38C78D4F0270D3A1F67
+:10770000FE3DC3FF64065D57D520E91BEA55F831FD
+:107710002FC35EA378A13BBD7A37DF1F190E721EFF
+:1077200050022AEDEBA0BE721C56E97045E4B1038D
+:10773000F5D369D2C330F285F609822E4B689834AE
+:10774000900E0CB78314F7E103FCFEA5BABF28C462
+:10775000312CB406E0F8BF702CF8C9EF1696638B95
+:10776000EB3CA6C7232F995AA4FB79E2AB5581A025
+:10777000BDFC1FA797482C2827FEF8FE40EB77CCCE
+:10778000F631FD052A78298E2F50C29217DF9F51BE
+:10779000A7491736910C3F8DF315CCD5D85F160C41
+:1077A000C53E8DA77827895C7A32ACBCCE7A47CFAC
+:1077B000611BF22130B771B6DB128BD3ED56BFAF30
+:1077C00080F68F3A44BC0EB4DF379EED9244EB5105
+:1077D0006608FE0454915FB94065BB59A9CBB1D28C
+:1077E0003197F777C827DA270F5CB7A4F97870FECE
+:1077F0007CD082936376D5C87F701AA0F798ED6A23
+:10780000DFBED72F0BA23EBEF5BF3F4905BCFF2709
+:10781000259A4AFC387DFF89541FF2E3ADFB45FEF3
+:10782000F27D537CA4640AB92ECEACFE82F87ADBDA
+:10783000AABF4D88B72FB0329BF5E28E904CC9F0AD
+:1078400005FD59BEC3C97BCF46BF3E9C99D037F4D6
+:10785000A0DE0E8DC9E2EA6999222FBA63D7161B02
+:10786000E5D18B33FDA999D83FADC77FA7DB53790D
+:107870003FC0A067D1AE7136E2F79F3AED106103C9
+:10788000D96D1572F65D2F4DA0CD7BF167A6F3F093
+:10789000FE021BED9F2F91202AF6B5E0F0CFB1FF3D
+:1078A0005EAE0C6BBD03D7B1E42DD56641F92C99C2
+:1078B0000ED120EAD5A2BBA435F7E2F8457E1745E4
+:1078C0007003D6B9309898E72FD3E395DB1FB29AAF
+:1078D000F2A4C6C3B45FB618E7A17C76496BE2FD9B
+:1078E000FEAE3B0FFF9CFC40878DFDC0B28BE44F8A
+:1078F000E332F57865024CFCAA94E295B21F9569D3
+:1079000083DB25235E39BD0A083CF097550E6ECF08
+:10791000AC52B9FD42B7D7CB3B0E1C665C2BDD13D6
+:10792000C8CF3ED5F5AEF3162DE637BEB9E5934385
+:107930003FC77E05ADB398EC65C44A78BC4AF71BD7
+:10794000CBF438A4E273B3DF38F087DF539E8DEBBE
+:10795000DFCE19D7A5C523B782F2693C1F0C3F6261
+:10796000E6477F57A99370323F33713FF67FCA973E
+:10797000C19EAB9711D749EC87A14F5F64087C2F5C
+:10798000DE366F4D3EBEBF79DF07453DC22EBD06D8
+:107990009E185ED1D033DE960144D7223EFD9DFF76
+:1079A0007498F87498F03689FA97F1FDDC2AC42FA0
+:1079B000EAEDB2CE0FDF84B1AC5FB9965C6A23B951
+:1079C000945F9A7168C69F196FBDD69E22B20F66EA
+:1079D0009CF54A89E76446BB34539C5F2CD67CB344
+:1079E00028DF45B7B646E5F508FB775A693DFC4305
+:1079F000D2DB6D12E787F5CFB43D4DF6A8F6B73F61
+:107A000071933DFA5069F5D0FBEAB63FE0F6915D1F
+:107A100052826E7AFEC390B04BE6F775EA7C34CEA4
+:107A2000052EF8A587A26BEE437E9C477D26FD6D53
+:107A300068FFEB9AFB28CFF039A294779E567A66BE
+:107A4000111D772C7435367929BF4D5C77EDE33FF6
+:107A5000F168BC7F1C2CD0F9C7F96AC336AB3782FA
+:107A6000F336BC227BE9350188F2FACCCF07C2EFAE
+:107A7000DAC87EAB1688164E1D781FC56823BD096F
+:107A8000B4AFFB5876532BE415203EC79D33D4E8A2
+:107A900076D88CE35D99FABE888E5FE40FEFA70677
+:107AA000912EDA3F8290B0C7CDBFD938F66DA4EFE2
+:107AB000CCB617DD5259FCB9C26A96477FF8F65F1B
+:107AC000392C83E3B757C77B2C6E09F1735A87248F
+:107AD0000E833A455B678DB8296FABDB62F506F123
+:107AE000725D9B0C0EF25F27ED1C37D4B57DC2F89A
+:107AF000AC937C51691C2FC32DC5C511CBDBDE9B1C
+:107B000045F676799E0C7351A56AF79C13E37D10B8
+:107B10004DC1F1CB77BF3DEB87D447BC3B92C8AB9F
+:107B20002A7CC026F4C624AFF0DBB3281E6EFECD3F
+:107B3000672C8F0FF74B90533CF0F99A2DEFD9C873
+:107B40009F9C41C164A60B7E91DF0884E585B6B495
+:107B500064F28B5CFFBB4ABECFFB7F1793E37A3A9C
+:107B60006B1BCF787FF2774847CD9B76EF5C7AEF3F
+:107B70009377BA0171F081D22870FF8B073CE487BC
+:107B80006BAC418FCAADB85EF3CBBB198FCB8EDF28
+:107B9000ED11F98D2F4FEC1705F3689D4B367F9B48
+:107BA000D7B914FC8CC79A5FC8D5B44F734E81D92E
+:107BB000BB93E84D659688B7ECF083B1F789F30085
+:107BC000A0FCFC037DDF34F8B2CC719B1D6E4C9B96
+:107BD00017B7FF64CF12F62A08A13FD2B96A00DDB9
+:107BE0002B9F831C3F378BE6B9AB5869A473225C8B
+:107BF0007F50E797F415EF0B80A6C4C55955C7AF62
+:107C0000CEA17D313BF4DBFE5725C7D51AC53D71AA
+:107C1000CF31DF3ED86A1F225D89AD27F9BEE9ED7D
+:107C20005986FEC3CB1087A7C08E0F184F80FE3B2E
+:107C30002D57F41F237D5CE46A4C43BE7DFACABB1A
+:107C4000363AD70AE27A8611BDDDEF711FBCD91A28
+:107C50008D37E60F74D863E781A4D7DBDE33E9758F
+:107C6000E27DF4DFCCCF00A46994B77D608BCE2297
+:107C70007F1EC4F7527DC1D20DF684F3C6185E4C48
+:107C8000E78BBA7E1AFB9CCB4CF198D19AEDC2954A
+:107C9000598976013667273D5F34E72175D6D0AF25
+:107CA000893F7527ED9CBFD4B509FDC3803A3A0CD6
+:107CB000F5E1A35D875EBB05D7F151D89A3597DF13
+:107CC00096686F6B9E42FDC5F132F23B85EDED6724
+:107CD0001C4F19FEE823175E1C93446FF17A52BDC6
+:107CE0007501DBB3FF577676D92076F6BB5903E2F0
+:107CF00084347C0DFCE589E597537C61E6AF615FD8
+:107D0000CD76F3934C2DA9DD04DDCF1B7CACDD7962
+:107D100096717B3E4F9C37356CFB2BFB31646BD4EB
+:107D20008EB86D087DCCFD07C88F71FFC07C696C73
+:107D3000B27527F2D37CFF32922DE723D1EF139F48
+:107D4000658BDB2BF6E7543ECF6F26BF49765A533F
+:107D500081E40833204C7187D4F9FC5FE97DE6BCEF
+:107D60002238034636F2B92EAC8BAFCF092B7A3DC1
+:107D70004530797D4EB32D769E4BF7073BCF7D5F27
+:107D8000B7575E97CAE508D62C4D4E5657E2ADB2AE
+:107D900024CD237E9225CE774AB3C5BA8F65097963
+:107DA000B4C8D5FA46A3C897680F95ED5FBA9BCFC4
+:107DB00083AD7A7D06CE9CCBE7074ECB27C812D881
+:107DC000BDA17A8E42FBC315963B4BB1DFB5E1F600
+:107DD000390AE2C73BD5B2A704FB2F6C582CFA57DF
+:107DE0005A2AAC08FDC7834BE6CCA47D03CBDB3F0E
+:107DF000A5F529AB15A0FA91D296F7B87F97559CB7
+:107E00005F353CBBB786DEDF20A12090FF2DEE70F2
+:107E100023D731E482BA9A368FB53D7EBABF260F9A
+:107E2000F379944724CDFFDB2CF22B8E885B2BA1BA
+:107E3000BCD2B7F17B785F79D94A3921AE53EC8354
+:107E40008FDE333597ECEEFF85F7FF5B56F6E0EFFC
+:107E50003FF3D4B50B68FC68195419E72B57B42AC3
+:107E6000EADB31BFA6BCCD9043B922F85EE6B27121
+:107E70003ED792EECB253C1D239C665F7ADBACD7C8
+:107E80000FC94E810339CDD2B81BDB5774F9BFAA95
+:107E9000F383FE685FA06F5FCE56AE5B816811C949
+:107EA0005796B7B6113FA24D0A6CA5FDD77D8FB787
+:107EB000113E5FB73978FFE8E6B4F5D62B90E4724F
+:107EC00047D19D04FE37A55D7753BB2FDBDF93259C
+:107ED000E68DD0BCB77C5F16F3BA1A53C97F820F08
+:107EE000F54AECD370FC0E7ED42BA2F920EAD538EB
+:107EF000320589754E663AE4B45D4CC7CD7641C70C
+:107F0000825049730FD231CE1EBA8CF22B7C7F94F3
+:107F1000E4700B865B84E760217491DC5EBFEDCA80
+:107F20002D627D85ACAFACFF7CFE7EE6499A2F804A
+:107F3000F3D3396A40EAE1FE1EC5A1065561DF1799
+:107F4000C6EDBB3D0BAD27CAC4FE7E33E51D53F520
+:107F5000BCD8D87F33EA0D2676F9AB5C64B0E54E29
+:107F600099ECCA398CD7C88E99F7DD269BECEFD4F3
+:107F70008E8FD82E5FEC3CD099ADDBE37CC8A77523
+:107F800084E93C90025EDD4F7AE93C3089FEC79D72
+:107F90000766660B397DED79E09DBABDD1A84E0E1E
+:107FA000D7D18F1393DCFA8F2E82F24AAE476884C2
+:107FB000F4C1FD6ABBC9FE1B381FF38A7A3BD9B3F3
+:107FC00031AFC06DB4DEABF5F393FED3C0F580E303
+:107FD0007A1C5C1F68EDB28642525C3DCA490BD7E1
+:107FE000A3F48337C4F52B41BB1A647B3996EB4F5E
+:107FF0005A4EEAE7BD7A3D438560D93F5C0F61AEDA
+:108000007F98E29E242FACE4F31990260DAC7F9864
+:1080100022DF2A935D81A3429E17EA20E43299D69B
+:10802000752E024029DA8457E2E48DFF9B9815945F
+:10803000B9FCE954E2F529265C98E57F6DB61EDFB0
+:10804000E8F21FB48EE443B1AF360EC6721D89D577
+:108050005C47F286850B366375241521D2B7094D2E
+:1080600062DFF862753CE63A1D731D4E9E3F914FEC
+:1080700005355724DCBFACB13CA17FF9CA2909E31F
+:108080008BD1A1C6F74B1F9A93307E58EB8D09FD1B
+:10809000119B6E49183F2AB428E1FEE81DB549EB53
+:1080A0005E0C9C8C09AF48B8BFD1F9E4BB84AF9695
+:1080B0003C59A578FECA8EFB4C7531D31817538CEA
+:1080C0007D785DFE465D1D9581119FC7A3FC1F2B2A
+:1080D000A6B8E9FE2A491B88036F24C87EFC1FC589
+:1080E000C17A931D30F4FF62FB373FD6FD849C526A
+:1080F00024519CE3C3B82A652AD5118B737B784B36
+:10810000D4AB7C96F2778E8B34C9ED856FD25B55FC
+:1081100089E2A07BAB348E83EE1D527480F60F7A19
+:108120007EE0F64AF903EB42CD75A0190EDF64E05C
+:10813000AD115107D982869EEC7F708683E38C87D0
+:108140002D96DBAAE3E87F225BD89F27B245BEF5D8
+:10815000735B7837D901C5016A539E789E8A1F8068
+:108160002A7B502EEE4C10F561F0C6DA9985E43F7B
+:108170007B466AE9543F8BFD6FE06525C4FEE496BB
+:108180006685F3BCD5CE27D99F942BC29F8C93854F
+:10819000DF403FD241F6F14DE97EAB88B382569283
+:1081A0004F810382EE72F6AF7C4E9C0E59D28A321A
+:1081B000AA4FBDE0B7B4AF104C876AA75A884FFDED
+:1081C0008B653E0F7E8948427AFB6B46719D73FF3B
+:1081D00085FA3F2D8DF2EBFEC58F9EBDBB32A69773
+:1081E000276DC9F3BC8BEDBBD56C793495CE514E60
+:1081F0008E8484FA8C37B3457EF866B62CEA0C423E
+:10820000EF79884D7D4BBE184E4407A4EE352E1CE9
+:10821000F2E0A61F54935C6CEDF382B4AF69ECE31B
+:108220005FC8033BA773FDB6912FDDFCBAD8D7BB5F
+:10823000F98BC47DEB8FB2C5B9C047F43E6CCBBBA4
+:10824000FCE3496E379042F0BEB27F3CC507D52AA9
+:1082500068E4F717F817DE7D14FBF3D64B1CEFD359
+:108260007D1A7F23CA90EE9F00EFAB7B91BECFB308
+:10827000053DF3A1DA4A74BEF6FDFA54C2D3EBE928
+:10828000627C54026D6BDC7C37E8F3BDFEFDE57B60
+:10829000294FA7F7D1FB891E7AFF3C154AA8FF1A80
+:1082A000F8CFBE5A3CF0BD3781CFAAD77B59C94F12
+:1082B0009642A8ED69B2AB472CDEB5C06D2493FDA4
+:1082C000929DFD525F53F4C97B90CE3FD5FE75AFB2
+:1082D000847CFDE3C2E8AF9FC6EBDFDD248386B874
+:1082E000F838C32F7BE2EAB44F2EFE2495F889F1CB
+:1082F000CAF69F92DEEDB47BA9AEE3CDDA9DC3E36F
+:10830000E3FA54CF74073D07932EED3CADEA89C9DB
+:108310008CBF15DB05FE56FC66440EE16C45EA0594
+:10832000DC89FEF6523E279D2041D2FC783FE24D8B
+:108330001BC17535A021CEF67F2EEACAF71CCDA849
+:1083400020FA14F05F16BF9E3D2FDD329AEB79DFE5
+:10835000C8BA243A496783687F6F665389F181AE52
+:10836000270B3A332BF478729487E2B9DFFFE6ECFF
+:108370007F105FF6EDDCFE43D6914BE3C3C03A5A63
+:108380007527DB27230FA3BA57CAD30E59D84F5EE0
+:108390002DDFCF7918D56970DE35A488C7A3C15108
+:1083A000ADC2BE89EF24300E6EF672BD27EBEB4AEC
+:1083B00055C42D469E245BBCB98AF8C8E0C5A93CCB
+:1083C0007F09D0FE989B122BC35E611CE1962DBAEB
+:1083D000BD029F03F3D3D1BA3D9BE5F15EDB22CE14
+:1083E0006B12E24FEC57ED4A127756E33F8E3B3764
+:1083F000FB9B53D82F6D96CB28EEF03922E4C7CDE6
+:1084000071E75458CFFB0003E2CFE7FE7249F1E772
+:10841000F73CFF3DBFB3D4A3B1FD098F14762E1CEA
+:1084200019C2790EFE55907E0DA5BD003A07CD13F9
+:10843000AD4DEA1DE940FDACF594AF7B681AC2650D
+:10844000A8E00FF551A450AA7D72E82B8A03BB1552
+:10845000965FFF73577CED772495A887E4EC23871C
+:10846000A770BD735F97D08FB60CEDDFA7529E81CA
+:1084700071E656243145E9B1A52759CFD3647F5120
+:108480001FC21E9147393AC4B9A843F301D99714C2
+:10849000551D4789B9317EB147D8DDFAC36F16D96A
+:1084A000503E672D47DD74BE52B7F729372E179A15
+:1084B00033FD0F90FE2C3FF9F20495EBDCB614511E
+:1084C000FE1D8EBC3C83E3B3D9C8DA7183AF27B0FD
+:1084D000A9823E4280864D99DC8EA27D15BC14880F
+:1084E0008875F676346724DB1F08FCDB5B0769BD03
+:1084F0003B8FA570DCB233BB9BF520380F603BF29D
+:10850000FB89CF47F37C0830A6E38A6A4D227FFFC0
+:108510000B7D3D3BF5FCB2F77399C719F38EE998D3
+:108520002EAB88ABB248EB41AEE3EAB46B24DF94E8
+:108530006D20F8D399C2756181FDD788BC335D9CED
+:1085400047B70D89FE91DE13DD67D7A84E35456D1F
+:10855000850C9CBFCD26FCEC2804FE53AED875E3F9
+:108560007D299D1BF92308C405D7E3A528ADF00D8F
+:10857000573CFF5399DEFD1E11EFB40D89585CE4A2
+:10858000273057DACA74C5E8047EAF41E7288E8BDE
+:10859000DB6CD1F769BF1DE9520917A340D0099DD3
+:1085A00023348A57525471AE9EA26ADEA03490AE34
+:1085B000C058086170000FAF860B7ACE7584436295
+:1085C0007D07EA425B891EC70417AF9B392DAE4F6A
+:1085D000866C52ECF9139E65EB5A0A695DC20F2A4C
+:1085E0004A98CFC7DD0B40A5F3EF14C5C77952CA2F
+:1085F0007CD09A505E4E878FEF7B708EA6C9DC8F41
+:1086000010FD2ADDA77D9B34D53907E94EFB328D5D
+:108610009F6BE8B672DD79DDDF6F4A2BC3F59DB144
+:108620001CBC6717B61F2D0C0FA773DA0969FEB7BC
+:10863000C81E3F736AD1BA3138FE2F6D56EF5CB257
+:108640004B3DC11FD3B97DED13568DFCE2836FF412
+:1086500047BE22F93E2BB15DECB38AFBD8D79AF026
+:108660007E43E707363AD7BAA6E36D1BED7FAFCC62
+:10867000F1BF4F7A30A9A3A98AF836195A9B699F8E
+:1086800013ED21D74B847385BDE87F65F8D6A638F6
+:108690003EBB72F47DEFA8FF72D29B4E5D3FF75355
+:1086A0007C84ED5E3D4EDB7BE0BBA55ADCF96910B6
+:1086B0000EF27EE06A788EEB3A8DEB7D216536E135
+:1086C00068F46B8EDB7C7138B3E5087DB7E9EFFBAE
+:1086D000798EFF4BD6DB03EFD8DCB8FEC09FC345D5
+:1086E000E4AFC218CF7D5D1D69C0A42F17EA8E4E7E
+:1086F00003DB919DAF7570FCBDF33E359DF41EE923
+:108700008734ECEFC5F882F4686FB1D0BBA657CFC1
+:108710008FA5FDE2F3FB965F4EFCEAF5580D7CCF8A
+:1087200018427AB41BD88E197A58467A28D1F77B2A
+:1087300062BFA78CF04D7A67EB9EC37AB7D702A4CD
+:1087400077886FC63BE25BA538A44C45BCF3F323A6
+:10875000588FDBBA5FBE82EBD991BDC3C651DFC271
+:10876000F86A8BCC0949F87CA53572909EAFC4F7A6
+:10877000376931BDAC9412EB7A167B449DAC611F16
+:108780007FA0EB6778A496E6C5F14E594EC07F9C5A
+:108790009F147DDD8FDEBBF127EB36A0BE94FA2A55
+:1087A0002C1328DE3926B31FD8AFC7C92BFE30E5FE
+:1087B000865DE23AFBCF888E8B837ADCFCDCAA5C98
+:1087C000EE935FD0502EE3B1F55550BD7763156D34
+:1087D000C54D9ADD7A88DA29D5E12A3A2E9CB6A0D1
+:1087E000FB90F8C6CD379AF0D67EF05BA3B94EFA6F
+:1087F000A41DE83BCEF6FF8CFEF1095CFF3DFB912A
+:10880000DF90342E61BCA1C766FC0D86933EA9E7BC
+:10881000FAA96897AFDBF8EB6B1574E80D04045CFC
+:10882000FF9C8DDBD605D1079EC8F15D9783F8FBD1
+:1088300022D77F5D0EF2ADEFF87F7AC89FEC7DE521
+:108840001D37F9E1769B6F34E1AABD04F3882478E3
+:108850009C926365FF5A3948BD49638EC8B7860745
+:10886000611DE1A5A15D5643E4A77DDDD793DF78C7
+:108870001F5949FBDA4BA707DD942FD5EC3DC47592
+:10888000FA463EBD04F43FF9D659C4FF73B9223FFE
+:108890005EBAC19A90DF8E80888DCE91037E576339
+:1088A000044552638A3BEEE8D8C2DF8DD46E4B7C20
+:1088B000AE8EE2148450DD45F2E3C61C7D9FA41405
+:1088C0004A294E41DCF03E49F455D9BB15B8BEAA41
+:1088D0008BEAAB765A049F9C0E6849CB88C52B2344
+:1088E000F27C4BC8DE2D31FC875EAF146D93F87BB4
+:1088F0008A513B44BE3CE5B4B685BF930AFAB84EF4
+:10890000AF860840BAA728415EFF94DC5208E2FA1D
+:1089100027A179267D59DA2985989FFA772F0AFEB3
+:1089200013FB459B65FECE6FB30499C5346F94F974
+:1089300053ABEF1F2EDF91787E51B7E9F8610A95AE
+:10894000EAC3A6F3209D3FE6F39DA7E83F929CEF84
+:10895000FC24478FE78AA028E1BBBCAE4BFB2EEF7F
+:10896000238A075C74F8080971F91E1D470DFABACD
+:10897000EB42B258378A82EAA36FD76112002FF315
+:10898000A91E71423880F542DE463D632D54DBA8B6
+:108990008EACBEBDE9309DBF2DD5E35A339E90A16C
+:1089A000CCAF657ADD50CDE6C4FBB53A5F6A4D7C4D
+:1089B00069F04B26FA44DC7DA9F4A1E5FA0EE1A0AA
+:1089C000769795EBB9CFC1AD5C7F55DFBE85E95990
+:1089D000AACB6F20BD415ECF325C0FE9D3A5D26B2D
+:1089E00096DF3103E757C01509F29B9D7949F22BB9
+:1089F000057539ADAFBF4BE4B5FD5D25BC2F61E01A
+:108A0000C5FCFC2C3D8EBE66938837CF7654392941
+:108A10001EE83BAA7825C47DC5B14FDDF4FD4DF9B4
+:108A20003E19E89CB4AFB3625D10EDE59EAEA13790
+:108A300069E807CA8F29EC372A8E9587528AA95F81
+:108A4000EE2CE53A132D93F2009C87FD70DFD1A147
+:108A500027CA384E9F5949296AD3D17227C50B7B43
+:108A600040EC6F48C72A337BE2FCCA7B3962BF61A6
+:108A70004DEEBB0F939DBA66B795F783AFB1465FD6
+:108A8000A23C6C4F97E26DC27EDDB145AB5348DE30
+:108A9000BF91BC14761FEE5E9145E735F59D56D526
+:108AA000CEF4DE7D90EE077749DE61383EB0EFEA26
+:108AB000D16DB44FB4A5C24BEC35DE579EAE3D4AE6
+:108AC000F5AE90E7E4BCFD9ACBACEC5FCFE43BFFA6
+:108AD000752EAEABD6B76516D9E133BFDBC37515BE
+:108AE0007D6D12E44AB48F7CE849AAF739F3F4713A
+:108AF0001B9D0757B51FE7BA8DC1FCC1D910E28E87
+:108B0000F3F6561BE537F55B8C7E0F7F8F52ADC7B2
+:108B1000510DDBDEE67E2DE50184C7CD7248C3FF33
+:108B20003CB4EF193E1F6ED825EA3E2EDCDF26F15D
+:108B30007D03EF8B74BBB51C34C6FB7203EF7A7DEB
+:108B40009481F7733097EBB496EF7A84F1BD44C704
+:108B5000B7B96E0A2DB0AD2C4BE82BEDB799BFFF1E
+:108B6000BB43C7F71D17C1F7A85C1DDFA36014E165
+:108B7000FBFC74514F77FEF81027CD7FFE08EFBE47
+:108B80007E1DCED9EF1ED5E382FE88C567BB323687
+:108B9000AEB7E313FE0E3170B4DF467527B33A3F2C
+:108BA0006679CCED3C3093F87D1DF8EB887FD77566
+:108BB0003A558A83E7F6087B36A7D3CEE713D74129
+:108BC000B885E4DCB7FFF1960CC2CDAF056E0C3B67
+:108BD000B74CE7EBB5653F9845F97BADEE0FFBBBB6
+:108BE000EE9CC576671C1453BC3747FFCE7B4E58AE
+:108BF000B7439B13F94EE7D424B7864E3BD79B5C13
+:108C00000B3D36F267D7EAFED3EC27FBF29C2CE74C
+:108C100020FAAB6138BE6E97A98E52E9617AFA3BB1
+:108C20006C7CDED560F2BFD372AD09F51783E1D35A
+:108C30002CAFDB72757FA2CB6B6E54D431CC7945EF
+:108C4000F6D2F94357647519C50B06DFCCF2EAD2A8
+:108C50004AD3BEEEF7125ED2E37CA37F83FEFD5BB8
+:108C6000586D75C5E7EDCFE75AF473CED04F2B7032
+:108C70009D7749D04D38C4FCE6867229697EB332AF
+:108C800017C73F5F78FBFA71F1F98D6FCB708AF7E8
+:108C90001E44BB5251C9F53BDD7C5EA8B4CEA57322
+:108CA000B0C02EAB97F29A4087CCF14060973D64FC
+:108CB000C179AF211C215DD59DD2D58423CC1B5A0F
+:108CC00072D13ECDA32D651C37AF03E3117C6EDE60
+:108CD000CC8F197F47868A75F72B5A4EB23CC2C893
+:108CE0001F1A3E17F1AA71BD01ED008D6FD0BF4B69
+:108CF0006B3FF8D7A2E2543AB7FDAC6821C5A9B9D9
+:108D0000227F31E2D528C6AB257ABC4275174B8548
+:108D1000E860E973F7D9C87E1DA61FB6A0FA49D549
+:108D2000BF86F261D50F8D3FA240436A613D6A2044
+:108D30009D221CEE95C4FECDB356AA0D81A6978741
+:108D4000705D60EF6BE21CCAACEFBD8BBAD95E9C64
+:108D50005FE86A24BC2D2FDBB206230C18BDFF751B
+:108D6000B637A37F67532D6A6C5D4DF4DD1DE7694F
+:108D70002D09F1726F47B38DF7A1E3BF1B2E1918B0
+:108D80001FD55F641FEB79935D41FA39DEED3B221D
+:108D9000ABB42F847CFC657E3CBFF478A8FD600AF0
+:108DA000FBAFBEE3AE10C5FD7FD1F17846DF976F14
+:108DB0009A24333F2C93453B7AFF3325245F9287D7
+:108DC0001FEDFDCEFDCF5CE1E37DF490A823DE91A5
+:108DD00058875D1F4EACB336F81AD0F98A740DA7C8
+:108DE000EF950DBAF62A3D6E6F123D92A4832C2F9B
+:108DF0008B9498E7069E95ABE3EB48713DB791DD08
+:108E00003B69E88B12F5901F7E2B5763DC34750AA3
+:108E1000F95AF68916DFFF1DB15F63E5F70FB83F1A
+:108E2000235847F7CF173BB9BE013E0FCEA5FE3DF5
+:108E300025E2F703EE79B97644FC3E1D48221F0F68
+:108E400058A35CEF17386E61FA02C7FB3D435D64BF
+:108E500017B7CCA43ADA6B757B71B8C45943380F95
+:108E6000D27B7362F32CC915E71B40EBCD8D7D5F80
+:108E700069AC7735DCC87C58ADE3EA3FF4BC1EF33F
+:108E8000A8F3B949F2A8C1E2DF0B74EBF1D3F9E919
+:108E9000DA89EF210ECA8F2841CAD7F7BC91122276
+:108EA000FFDFB46FD99F281F0EBC69078A43EED934
+:108EB000BF6C04D7E1FBFD57923D39BFFF8E2BB944
+:108EC0008E5112DF970689BE5C8AA75EF5509C54CE
+:108ED000BFEF55AE73ACDF3BFE518A9F305EBA9652
+:108EE000AE631CC3F82B3F56C9F8DB73B432B3949E
+:108EF0000807AF93E6AD3FA270DD63FD91CA17E7A7
+:108F0000525C736C06C74F46BC5441F938C54F4795
+:108F10008626C44FA979827F7D075278FF4382124B
+:108F2000811F189A809FBAF63F709C5187F62E1EBB
+:108F300047C673C5790ACF332C4FC74F58F2313E1D
+:108F4000768BB6AE630FAF6FB935CCF26EDA6515BE
+:108F5000F7DB446BD44907212348FC78912EA11CF0
+:108F6000E6D84285946FBE502CF20DB33C9EC813D8
+:108F7000E7852F9C14DF19BF30DD3F22D9F7C641AA
+:108F80009821F27049E777BB7576B2EF7977E4897B
+:108F9000FD097726249C4B1AEDA379425FE6D8C4DD
+:108FA0003E95F9BE3FCFF03FB08ECE634ECCB5AA12
+:108FB000C6EFB7E4A1DDBD1E8C3FEFABF3B3E89C79
+:108FC0004BE4D5003D33C91E7E9BF6F929FE9A2459
+:108FD000FCBAB1CF3F6F333C20F6F96FB5925D30EC
+:108FE000EA4BE6F9CCF157F5D534CF8DE8DF699E31
+:108FF0009B6627DEFFF645E2AE0579BA1F1F0EC35A
+:10900000455EE172923F38D76555655E476868B244
+:10901000EF0B0DFB737895383FEA42BB486DD3A840
+:10902000D779DFEA8503279F4C67BB9A0225C8E200
+:10903000ABBEFC9327D93C4D17F4757E02FE0C792C
+:109040009DA53CA06CA0BCEECCB3E8DF259DB1F1A2
+:10905000F926343E649107FF2EA969D4672DA44FE9
+:1090600067F5EF5E90BE227B9CDD3F9BF731DFBF53
+:109070006706448378FFC0283BFBBFFA99129F1F05
+:10908000D447843FAC9F2FFCE1F0F6792C97EFA0FA
+:109090005C7C5E3613AF515DAE21EFABBEEC9B69DD
+:1090A000E493748ED34438673B9DC56D7DFBDB2D07
+:1090B0007C5E897E97E2C21B2625CA6D04F81FC814
+:1090C000C6FB37CF96BCE84106C8FDE65BE7B1DCDE
+:1090D0006FD2BF8FB998DC7F9BE7FF691EE97D7770
+:1090E000FF77C6208B5E18F54111F9D7864170BD18
+:1090F00055E72F0C8D3E4DE765DE0BE7E97F7F3AA4
+:10910000FE3CBDC4E3DF924776D5F2A5FB0AA0F989
+:109110007A7EB942223901EBC5607AB5439F7F4719
+:109120009E2ADE9325CE8746E9FD17ACA142FE9E1E
+:10913000A2ECD2CE019B9E7D7E2CD9B9DE0347C620
+:10914000DAE2E47A6605DA07F237FB0EF1F78731E7
+:10915000DC5974DC29DC4AD28DBA1F4DC4E119C236
+:1091600021D9E7DD87AEA7FCF16CFB4D599216E7DC
+:1091700067F79E700F8B9BF7ACFEBB1898B70DFF7F
+:10918000766A3C9D0F309D67C3623ED4FFE1378D08
+:1091900089BFDF6C7C67C7787E7064239FD31B78A0
+:1091A0005640E0D9F83D8C0BDF55DA80BF7B0CEEE2
+:1091B000B7737D459F355A941EA72F1F1A72449886
+:1091C0001566312BB9DE75226CA8E273024CDED72E
+:1091D0004DA6CFEFC2B2A80F6DE4BAC5698DE025E8
+:1091E000DC4AB099FB13668BF3F229D02D135DDFB7
+:1091F0008428B73E50156A67508519B6931C61994B
+:10920000C2ADB6F6834EC257C4A3A4BFEF10A5A744
+:10921000C9E4175BBF02EF1B78C5C1180425FD4EDA
+:109220003F2B5FD87FAF53E863F4ACF8DD936F401A
+:109230000FD33F55E9667A53352D83CE4B763FB732
+:1092400042A6FA97FDA04549CFBC998DBCFF169D5B
+:109250000EE1ADE9B1F54EA2F5AAB1FE940560A10B
+:10926000F54AB04BACBF1132E87C6C3244F83D5744
+:1092700011C1B8DEE9A029D4B7E517EB7C16F95B7C
+:10928000959EBF591C41AEFB49CD17B8762A2139AE
+:10929000AF92B7B6C38FD0F94CA958E744BCCEE71C
+:1092A000388D82EE0BFE3A5FD8BB29106639430D2C
+:1092B000A82FF28F2BCC54895F52C463A1DF13BB5C
+:1092C00054BEF67980E977DF1EEDFD6165ECDCCBFD
+:1092D000DB99C3F5D0EB254B5426BA1C85A21E3A68
+:1092E0000261FE2E3392F87B67C5F9375E9E4F7E92
+:1092F000CF2FBEC335D775EE086DE5BA9B05416427
+:109300000FCD530870DA13AB03B09684F8BE95CE38
+:10931000D955AE33ADA07C715FB6FFF2FC6CAE37B1
+:109320001DC69329A1F1D5A931BC2365FCFB3B4E99
+:10933000486D257BD4ACD7D30655B75ECF54C4EB6C
+:10934000D0D0CEF38F4828A2AEFBDE2A517F7AEF31
+:1093500090FD5CE7DB23812A15D0F9FF7EAE03A6E2
+:109360001F86B3167CCDF97F96FEBB0F25FE3726F0
+:1093700096EA461E9F6B3E95CAF5AFCA0C9F46758E
+:10938000BCE67AF1D296F10FF5705E6AD06BAA1343
+:1093900057BC7CFF5EDDBE363BC4EF0049ABEDAA97
+:1093A000348DBE7F5FC1BF63D54CA141257DF7BE23
+:1093B000829FA73A662A02ED4DF3DF44FC32FF2E6E
+:1093C00015C2ABFF059A376D38EFF72593C73443C5
+:1093D0001E9681755228875B49BE46DDAD516F4BA5
+:1093E00080A0753B7DE277F054C409FFEE1F42C9AF
+:1093F0004EB8F4997FCF43D4FFB6E8FC47BA7670F5
+:10940000DDA7437CA76D7CCF6BE69B81DFFF02B9B4
+:10941000D77EA250530000000000000000000000B2
+:109420001F8B080000000000000B9B25C3C0F0A3A9
+:109430001E8145A551F9E8F81C9A3C0B0303C34F64
+:10944000205ECC835F1F2E1CCB82607B893330185B
+:109450008B32309800F12C209E0DC43F81D8508C67
+:1094600081C108888B81EC1220F6056247A0DA2FB3
+:109470001C0C0C13851918E600F1726154735F30EF
+:109480004268252E060653206664C66E3FA73AD072
+:109490005E5D04FF23906D6F409E5F46F1D0C35523
+:1094A0004EA8FC7C6B54FE2C5B0606666704BFC0AE
+:1094B0009A34F3ED817A1D9C71CB77BAA3F21B3DF0
+:1094C00051F97FDC50F935E1101A008D579524B819
+:1094D00003000000000000001F8B080000000000D7
+:1094E000000BED7D7D9C14D595E8A9AEEAEAEACFA4
+:1094F000A9197AA04706A8611A19E3A0050C30281B
+:1095000048CDA0384693349890D1D5BC168821090F
+:10951000CFD7F1ED2A1AC9F47CCFC0800DB2067DF9
+:10952000515B0C89262621899B3559B3698DC92346
+:10953000D96C168D9B47B2B86F243C379F9B79EE50
+:1095400043FABD90B0F79C7B6BA6ABA6BF00DDE4F1
+:109550008F37FCCCCDA9BA1FE79C7BEEB9E79C7B8B
+:10956000EAB6EAF1437C1EC059FC5B03F0A6170083
+:10957000964D95E94E33076DACFC1C98FDECD1A5DA
+:109580007AAE5362E5A2D0B84732002E8F66003C17
+:1095900000F1C38F8287D51B695461671380DFD8C0
+:1095A0005003A1A97EDD657F0F406E61E9F7F20BE4
+:1095B000A33123CCFA7B6A79B7C5FA19F9727BB764
+:1095C000D53AF5BE010765F8CD07864D3DC0E09C54
+:1095D00007C113051866632F64FF69F72521C1DAF7
+:1095E000A9B951301661BD5AAAAF3D73D4731B7B24
+:1095F0003EEC85EEC3ACD49E4DE7820CEFCB9ED300
+:1096000097C88C1EBF62797EC5607FCC934D231DA9
+:10961000B17DD4EF2946170EF576D1B314E9617404
+:10962000ACAA929E55A5E8792E9D467A2E7FD658F3
+:109630005C488FD6C8E9D11AFB689E4EC5183D4DCF
+:109640001742CF3D44CFB0A067D845CFBB043D1BE8
+:109650006D7A1A86889EA1398C1EF6C8775F1A1219
+:10966000ACBE86F484B19E939E21A4A7B5083DDAD2
+:109670001F879E0F09794B213DCB2AD393427AEA6B
+:10968000ABA02794019D3DF783641D6E9D8E975F6F
+:10969000F071D13399589AF53BFA7B99E699ADC8A8
+:1096A000D8864553F5C6055EDF691A8A8DA37C2DE1
+:1096B000783006ACBFD13912D577F7FB10A8547FAC
+:1096C00066A3D58BFDBFE34967FFA37338BE76FD64
+:1096D000DF8879FC0DC8D46E5628318AF0E882AF55
+:1096E0004112C7F166623AB66BE2ED06172CEF1E27
+:1096F0000F156BCFE919DD912679D672F710BFFEF1
+:10970000624E060C06FB9F4C02F25F8D717CECF6FC
+:109710000C2F802B90ECBB2C8BE30770119BA7F4D4
+:109720005DB9341B2F9EB9434B307E8C36F46948AB
+:10973000F788B1AF1BF5D6A9B80A7213E2559C0F92
+:10974000B65CAC81316D3E9BCFFE576473274CAF46
+:109750009746E1AA9F82959007722D407F6701E9A5
+:1097600049D2FC0F2E7890E85691AE4548570A0C26
+:10977000F6FC1B427E7CCFA401E54A33D2B1F4A2B1
+:10978000E9E38C20FF5BB1D74C6C4301FD3FB5E7AB
+:1097900097CDAB6B7E892F0F81954B235FFCCE79E4
+:1097A000B3CBEF09BE5FDE9826FE561A7F3AFD7CEA
+:1097B000FCBF0683FA012D134B84A7F019F58EF731
+:1097C000A15CB335691E62552E63E37414F0DB3D72
+:1097D000DE249D4AC621C75F137C1AF54FBC50D8C2
+:1097E0009F1B9F6F897ADF029D4A9BAECB9EE5E36C
+:1097F00054EAFF47C8E27AACEF5A574ADAC1F77B1E
+:1098000045FDCB9F73D62BC59F8F4FF2271D437904
+:10981000B4D723FE59330184C8D05F6839C025F816
+:109820007F5893DFDE367E172EADE3D1E4296CBF7F
+:109830000D92F302CD6CBD78939FC5729D62BD49B8
+:10984000FD42487FFD52217732E9013E1EEB1E5852
+:10985000FF61D19F2275013079F6B543762743ED3C
+:109860001AF9784E62FCDC0760CED20BF6F5137C59
+:109870005F5FA967D7E27E7EA5C20861E3D580EE6F
+:10988000C712EBE758BDC8B290C946021FFC594D3C
+:10989000A288DCF8DB20EDAF61E3B7AB8E75E1B7F2
+:1098A00092807A211C839C3F02A04BE128E1BF02F9
+:1098B0005670FC0D09FBAB538C5E858D23C73DE6CE
+:1098C00041F6B46615ACDC54208786C4E5B737EEA4
+:1098D000F1205D434CFFFBD8928CCC61EB1DD7434C
+:1098E0008CD91B45E47652BFE765C8CD60FDE625FF
+:1098F000C82D657008562659BB8C0F569EA471C1A1
+:109900003C5844CE364A7C5EA5F8C4D9B3641740AF
+:10991000F65AB20B32B48ED578C6C27D40B322A6B9
+:109920000FA7FDCCFD5CAF2960A19CD4C633B91A4A
+:109930007C6F5CDC84F8CE8AA7E0B5565E9E28C0BA
+:10994000570BA563643F355D2CF515EC63CF33F9F8
+:109950003951206F233BB81D30D83424F4CC8749CB
+:109960007FDAEF3F20F8A48E3364902E43CDCE975C
+:10997000A6CBF588545C4F6C16F4E2DFD5CB9DF294
+:10998000AACC14F2CA86F02940F235FC1464115FA7
+:10999000C6C9176E63F0A52F6AB093C9572B1CF583
+:1099A000A0FC5C0613549AA0CB582E0193CA3648EB
+:1099B00050F9DB0E26F7ACDC6631799F4FF2FF3EA3
+:1099C000898DFF9B39C98511F6DC1F4F5F81FB0B29
+:1099D00093FF8DF89CC98984F2546741D1FDB2563A
+:1099E000E2EB75AFA2FBB1DE5E0B483FEE97FAD318
+:1099F000B84F8C083B69C40F8E75BC47D03D22CA56
+:109A0000DA7812C6717ED9BCA05E7FBEE9765AC7ED
+:109A10003E85C3436C5E48EE56F37DCC8D8786F35E
+:109A2000B2E8FCE761E31F7F1E86A4FAA2F3308C44
+:109A3000F3B051E2FA53FD391FBF0C7DB44F6FEE06
+:109A40007D9CF8AF9E3CB7FA36FDCB5D7A7385D02E
+:109A50007357C2C45C85E9913B7C39559108EF4747
+:109A600010EF377F72F403480F8C2717E23EC5F0E2
+:109A70007E54223D9982A36C7CE515398B7E8A2722
+:109A80007883962CE3A780CEF49926F4D97CFCDF6A
+:109A900046FDF5E074FD7BF1E10F1D237B03B4E48B
+:109AA0004ED44FAB531ACA457FE3060DE568B89113
+:109AB000C128373155932E676508BA50FE6CFB6399
+:109AC00028B669A4298A768FB91CBBB5C75F1B4B22
+:109AD0008244CF93337C4DCEE73FC3F5AF2763324B
+:109AE000A34FCD5EAB219D83FA06ADD0EF5243C9A3
+:109AF00098CAE47018C7C3F1BDA9234D6DA83F6192
+:109B0000691FEA733D054B51BE639D84E7DAC68445
+:109B100086EF7DB125E03390C509B2AB86A24E7FBA
+:109B20006EB8F14EB89DEAA7E0F5D074FBDA174A9B
+:109B3000815AB04FE03872C13CFB94540EE99263F5
+:109B4000C5F5EE3F09F9F71809DA6F20F3494B63C1
+:109B500072EF1532E08DC14FA4CB0AE6295AB0EF5F
+:109B6000B0791AF29BDDC5D625DB419CFD9A1268BF
+:109B7000CBABEF776ABF15F39E5931324EF31ECE51
+:109B8000E0BCF733BD4FFBEAF170F61023A1777507
+:109B9000EA317CEF4D2BD017A56E5A709FBB5B7ED0
+:109BA0008789F2B707F9C6368EB11E8DCA9D3D3A38
+:109BB00095233D312A3F19FCC467C759BBED699F06
+:109BC000EE4339C8DCFD25EC8F79DD899DD86F9493
+:109BD000F58FFD2A9A7E484798EF3BDE382F6FF1CC
+:109BE000703ED67802846F9B87DBE10658242F19DC
+:109BF000BDBC9F5ED3EEB473C366606A3DB0FF82A6
+:109C00002D750ED86F5CE4A8EF5E2F2F79B8DEF0CB
+:109C10002A09305BB12CAEC7CF4A32D593E5C513C4
+:109C2000687F28B354B20B0625A7DE7ED4C3F7BBEA
+:109C3000273C1AD11983896F9F65FCF0EA1EB27B1D
+:109C400022B5F30FE7903FF5AAB9801511EFB85E82
+:109C500057643C882ABF1E2F58E74F4956DCF3272C
+:109C6000C0A769F4F7763AE47A9787EF7767C57A01
+:109C7000917D5637EA9918134320F9301E473E78F4
+:109C800082ABCC16C687C15AD5407F68A0D7537423
+:109C9000DF71F341AEB92586FAD1CDF76F09397A74
+:109CA0005AF07DCD99F7909ED8AD7BBAB221E4DB16
+:109CB000D12ED4F3036D1E0FCAF99F0CFF5C746C98
+:109CC0009FE4DF241DC4B78128B79BC774263FB823
+:109CD0009EA35C7E0CC875D17B93D1254DA7CBCDBF
+:109CE000BFB79B3E9BEF35B59E44B615F19B481020
+:109CF0007EAB94A2F8FD47F1DDC62B3489578EE385
+:109D000065FE69E0F594943C88EB7B8F90D73DCA63
+:109D1000B8867A216ECB4D90AFA3E97A4972C83BE1
+:109D2000EBE7F3D8CFFDD80FAB7FBF32E1E8C7AE8A
+:109D300017463EF07591E0EB42F9A3AE0B1BAF9DC9
+:109D4000026F03B25CAE5B8ACBF5DB8D97BD9FF6ED
+:109D500005AF02D437B5A104D9DFB342891CF2ABF9
+:109D6000BF5E35D0FE618E12EDD7D4D428F093EAD1
+:109D700037C6B0FE607823D9E583DE04D9E947EA27
+:109D8000BF66DDC6E8EA3F53033E93F903C1AB8EDD
+:109D900018A8178FC8E4AFF59F699E952A32CF4166
+:109DA0008C8F31FC03881FD9D5EAA4118EF8F68771
+:109DB00098E263FDBCD10A59D4A7DE901543BBBB22
+:109DC0007F9166F651AD04207FFB821F684FB64E2F
+:109DD0006F1F0C0D7D4CBE6C6A1CF6279D45DB97F2
+:109DE000EDE1E8C7137D92E37D513C2AC1DE29589D
+:109DF000A7FE196C68D8B5649D6D9EE23BA3A5458E
+:109E0000C17D130226CE7F3CD1D5F73BE4D3F76466
+:109E1000D2836EFEFCB59C0CC8CBA6606F3449F3B0
+:109E200066F7775DBD427A546984AC4FC251135DC9
+:109E300068DFF6377A28BEA68436D494B5BB1BAB50
+:109E4000B3BB41C43D6C79E8F8391F376072FD1D22
+:109E50008671C0B84A0DF0B8462D1812507B534A8F
+:109E600050B06415C553A2FEB7BADF5BA85FC9DA6C
+:109E70000B6783E7D0AFC2FA6D7E1BFAAD80AF1FD0
+:109E80003E45FD32F5103D3B63AA5F6F2C450FE167
+:109E9000CCD9B3F272E04DE82F49F2AD784C5A9F1D
+:109EA0007051C43CC48AC1E89D0E7FEABDF27C4774
+:109EB000DC54D5873E264558D9B8CD1A2FD00FEEA1
+:109EC000F9EDC681D0BF6CDC628D57A137D0EC2E86
+:109ED00016971A5293D95EDCBFE786288E084A8A05
+:109EE000E2C2C352DD12B49FED7A4AA39A43BCC2C8
+:109EF0006D561AF5C5F00C8F299BD8EFD851F40791
+:109F000040BEC14C96892F298DCA2F0BE9F9CF721B
+:109F1000384A788A38577F05791FEA297F3EA1AAF7
+:109F200066B2983F9396B9FDA2068ABFBF5AEDDC90
+:109F3000212F9BCEB70CF28E3D1FAE652EF7E55C50
+:109F40007C500E94C6EF1E433E0C35AC8B95A31788
+:109F50007466E714F845A66AED94CBE3B1A7181E22
+:109F60001062C2B3B2CC38627EF5AB4D1EEF40A595
+:109F700088E771C23E637847A4995C4FE3DFEEB691
+:109F800083398CA3796F0B59387FB2F524C8ACFEA6
+:109F90000F1B6490DA110EBCE6A1F95C6592BE6AF3
+:109FA000E1FE9DC5FE211D9155AA63DF42FD39B931
+:109FB0006F35A1FC3BE1CFC9CE78667FCFB3F0B35C
+:109FC0000553F8B34756B178B1A2761E2ECE8FBA9C
+:109FD000AAF8B19FC90B3079D9C7FC46C614C8305E
+:109FE000BF11E13DCC6F04F2270D2A077A5AA8DC95
+:109FF000854D57E2F9596AA4A909E3A59F8E7D9082
+:10A0000055D98FBA83CE55029D183FDF69C3EC89BD
+:10A0100084B03867F941FFEF3A301EB3D3CF618087
+:10A02000890ECB01CB7D18EFDF19E6ED7F26873A4D
+:10A03000F13C62BF384702C5D2DE57E0FFE7652F2B
+:10A04000D18136106FFF9B5EECCFAF08383D87F0B3
+:10A050009984191F111FBFC6E1C681B9D43FA90059
+:10A06000365E7C601E1F6F01B7EFA17543053EF69B
+:10A0700091FCDF84877048736B1D1E2A836A9A8067
+:10A08000DBCDFE5A817795FD8092E4FB9D882B9570
+:10A090005E3715F6358147A5F907F44B317EC1F4DB
+:10A0A000701AC7FDC7E2FBF45B3DEE7EEFB9F145E8
+:10A0B0006D9F482B8CC57F29277585C161EB70AEDC
+:10A0C00089C1911B72695ABE558EFB6B5917F1D02D
+:10A0D00024AD7F9BCF8ACEED8EAB5DF3E88D5A74B5
+:10A0E0002EE90FF1F5572DBE2B719C827EE0E9CE53
+:10A0F0008644B874BBFA8467CADE62FFCDE80A4CB6
+:10A10000D96BECBF5AABCE01D7B45FE4A81F36E7DA
+:10A110003BDE7BF57738DE9FEF3C5DE6A2A3D9E618
+:10A120009F80636E3AAB963BC510FB5C9ADB8F93C6
+:10A13000B0D88F2BC167163A61DEAF0F6EAEE1F675
+:10A140000DB763FE13883A6E3CCC02FD2B633D0EC7
+:10A150001B1E096CFB36D732BDFF7EED131487B38F
+:10A16000FA15F05F353D4E97EE4C519C2DDDE7D34F
+:10A17000FBA31477A338DB7666C8FB58B9CD9BDC0C
+:10A180008AF27BDA3F370B11EC37B502E3D6FDAE2E
+:10A1900078825B9EE29FBAA9E879995D8EF4F0F827
+:10A1A0009F0D6B8DC5F300EE55F879FD77BDC97B2A
+:10A1B000110FD48D40715AA075E035F8FEF87CD3AC
+:10A1C0003AF805F9FFFC7C4C85F4B166464F86F9F8
+:10A1D0006B3B0DA49BAF9391A6755A9C3DDF5BEB47
+:10A1E0001136DD04D94F998E990DB89E6A94093ABB
+:10A1F000B7AB8917C7E77EC523E6EDD6B2F4B9E75A
+:10A20000E3560CB4B2767BE7481EE2FF1C4FF61013
+:10A21000C6A31A3DB4AE775BEAE378D4BEBBADEE1D
+:10A22000268AA75BAA47263A725AB1753828ECA647
+:10A230007E113FDDD3C8FDD6E73B5ED7F0BC668F0D
+:10A24000D949F9004AE687D47E58F03BB3F804C5F3
+:10A25000C9874B9CBFF429DCCFEF0F07BAB345DFAA
+:10A2600047E87DA6A9E38587900EA67F0F917F061C
+:10A270000D5B181DBAA52F417EEF9D63797E81721B
+:10A28000B5DA437216C1B89C8CE7A24EFF79EF6A2B
+:10A290000F9DB366F49089F6FB29EB0DA08D48D194
+:10A2A0001BF07CB1E6F8953AED95CCDE6928B0F369
+:10A2B0006B56A556E07CD974F9607DD1F990E66EB5
+:10A2C0004F223FEF5E0206FA63BEB95DB94758BF41
+:10A2D000A757FA7454055787AFCE7D13E5896D2BC8
+:10A2E000E827FBA2560EED267F77100CF63E123BB8
+:10A2F0004C76941693C142BBEAFFCA345F4C671098
+:10A300005DCAFE9547D7B0F6EA6ACF2CB2CB5AF9B0
+:10A310007EA3B37FB8DF6871A75D257B73D4DFFDB3
+:10A32000E38FD3B9B2EAB2AB1428A88F76D7EA0D7F
+:10A33000EF692EA20FEC521E8FD0B92EC8B794B57C
+:10A34000B343C73FFC0F2F16F0FD84E2B2D385FD67
+:10A3500066F753CA7E3BDDB3F51F5E64B29CF4F230
+:10A3600038A8A25ABFC47579429C2FEE75E5DD244A
+:10A37000BD7CBD9C16EB186716FD6DF48F915F03D5
+:10A38000D76CE47E16980E3F86ADF7D34A819F6D59
+:10A39000EF7719ABBC3F3195D712F2C7CBE4B5AC20
+:10A3A00057928AB74C5E8BBD5E47575B1063F33B99
+:10A3B000560BD93E9CDF35166C467995C0ECD379A7
+:10A3C000FD09FB1CA509E5F01AD882EBD7504C3CDF
+:10A3D000871C6C7E3773144BE3AB449DF251691EAE
+:10A3E000B7BBE671B6D769877B2151936BC23846FC
+:10A3F000EC26C463775435713D7A3DB76CDD644C0F
+:10A400009F4758C1F586379A8362E3DAFCBCC36B79
+:10A410002DF4629C5D358F2551FE3B55F27BDDF5B9
+:10A420006FF58A3C962650D03E4BE33AC1F5DB658A
+:10A43000F1BC31494F3D6C12FA09C7B956FC4DCAFF
+:10A4400067FB940CA919AB006EF436713DD3B19142
+:10A45000DB3DD78324D762FD24ED5F0D962EB1BE80
+:10A4600061D4B6CBF4DB62EB0BF4E48D423EA7DEA5
+:10A470002763EF73BCF7723CC3C26ED637C7D62FC3
+:10A480002AD2BEB6B89EBC5EC8F58D5E614FA437B9
+:10A49000535ED0A0714B02F93CB0C632B7A0D64291
+:10A4A00019C17C941038EC6326DF37223FEDF89118
+:10A4B000A227A8B4ED8152F3EFB603BC3167DE49A1
+:10A4C000B5E7B6F1FD37951DC7BD3FDBF96DA8F9BE
+:10A4D0000AF9E4157C6815EB65CA5ECA88F56E5208
+:10A4E0003E90AC5A498C4BCA1238ECADBD425EE48A
+:10A4F000007FEFC683F9CF77E13A952316F9D7109D
+:10A500006AE3769B621AEB8BE06F9F733E21F278D1
+:10A51000E39977D3FE3756DB49FBDE805E5E7FD85A
+:10A52000FBEA1AB841C3B8DD6069FD3156A83FD4D3
+:10A53000A8C7B98E857FCFE8378AF1D9E6534CC4D6
+:10A540004BFBC31B6365E382AEF31553B51E22BEFE
+:10A5500094E6DB23E7C3B7319157B763F0E51744BF
+:10A560001E82535F2F2EA9AFBFE0D0A7425FBF8DE1
+:10A57000FC7FEEADE07FB57118FF76D9383983A93D
+:10A5800078254DF48C1AFBD2148FC1F58D7640A638
+:10A5900083F215200EA417B121EA3BBF6111DF023F
+:10A5A00022CEA4363AF719391A70C0B1EE3460BE23
+:10A5B0001AF68B74FBB7AB34AECD6F66B3503E99D1
+:10A5C0006D5FE272427FA4547E9A5DDAF11B3CC655
+:10A5D000394BFBD4C78F207F4F8580F687D2F43B61
+:10A5E000C789BD37515E3FB9EA4348315E2F722EAD
+:10A5F00038BD9D02AF17E8B5FFE3D227D693B775F4
+:10A60000931E058F89F1CBFED8464832BC8780EB7C
+:10A6100093112C57623EC9121DFDDFEF7A0DDEDE6D
+:10A62000E0FE9D4713717AA33A7FEF6EB60F15B324
+:10A630007F2E56B97D7CFA13A9DF625E427AA76449
+:10A64000E0FE76B2274FF6D3A6DC252AE6A55DA26A
+:10A65000CEA47A9BF637A96B0BD6E726E0E7FE0C73
+:10A6600011B5508FDAEB4FCDF85E403A4F64785C0D
+:10A67000E344E6DFE85CFFC401398B4C3D31726393
+:10A68000D9F57352E86DBBDEC903B285FDA547A4B9
+:10A69000EC02D6FEA462458AE60140969F070BF8BD
+:10A6A0008319D92197A7772455D433277B34E967B9
+:10A6B0006C6E6E473A19FE9B324D2AFA6495E89A01
+:10A6C000A13AE7D3A67310F3159AA6F27706A36F03
+:10A6D00010BDA7D873B94C3C69A7D01383D1E2FA57
+:10A6E0002420CE5F03DE6CF1BC0717BDC116E7BAAC
+:10A6F000B4F11B16F914C33AC76B38E6A179186E8A
+:10A700002CAFC706C43CD8F50663FCBC755049683D
+:10A71000D5E0E3D59DF8941A475B75B80BB7F91AE5
+:10A7200048767536117B5FC63802850E0DF49F9E04
+:10A73000923EC4D6CB0F6F0B59520C1F4EE4BEC9CC
+:10A74000E898C5FC1DB44F752B2BCD6DC3BC4E19BD
+:10A75000306EFCC89FBF917B15FD51E6FF205C6BFE
+:10A76000A4D65F6B601E5C52C275B51B953F75FE2B
+:10A77000AEFE8E56B1FE18FCD1A1CEB5188754207E
+:10A7800021E2191E03F3F568E97B4AEB09D49E67C1
+:10A790007D53ED4AD2E9F28B7CB0A1BCFFBD95D7C9
+:10A7A0004FB37FA87766B9FCACDA6EA7DD5DE37ABC
+:10A7B000BF57C86B29BFF2AD1A6726BCACE1B9AC74
+:10A7C000D6E6D1B3581F52B5B8DF466E5100EDF84A
+:10A7D0009986DE8B21BE4A7CDF053CCF0DBF8828E1
+:10A7E0005C7F9F51B91DDB78E7A725DC9F4EA197C1
+:10A7F000BD18E1BC594C7EDD76DF887182E2894369
+:10A8000070B4AB19EDF92D1E3A4FDADDB6AFB6B024
+:10A81000FD77C43853F30F86B29C4E65C99F57DB52
+:10A820003C16EE5BE73BFF6E3FB9D2FC376C75DA46
+:10A83000C5E73A2F2F21E2CB2ACFFF858E63CFDBEE
+:10A84000F4F5C1F566E39D2F521C67CC2CAF6FA6C3
+:10A85000CFDBCB346F9136B08AC5717E2CF6317761
+:10A860005E9F062930313FF115BEFFC8CDCB63078F
+:10A87000CBE81F39EEF23F443FF90F021CC5FD56ED
+:10A88000312A7C0F7778BFC2F6CDE0F62BF72B4B41
+:10A89000313FCBA23CAFD11E8B9E4FCEBFCF23F01A
+:10A8A00095C0B35CE81583CE3FF72B646F78E02C3E
+:10A8B000C6414007C3963BC07A5DFB158AC7182284
+:10A8C0008F80559D89ED80F4D2624CF6ACA7737AE7
+:10A8D000EA073BE271986E0EB386344F5ECB22BC22
+:10A8E000948C7627E3E72EBF800D01D70A581770A6
+:10A8F0009380611FC14195C11897F7667482030266
+:10A900006E12709D806B053C5FC0D23E8277A9BC01
+:10A91000BF9D4A96F71F10B021E03A01EB029E2F2F
+:10A920006038C8C7F77118F7438283026E12F00CC3
+:10A9300001D70AB859C0D241824BCD5F206E117F3A
+:10A94000A7E6BF8BF30D40F89B0917DC3D55BFC050
+:10A950001F1DEC31A4C2F3436F89F8D3121FD73304
+:10A96000131D09CA5362FE42FA44E1B963ACB8BC94
+:10A970005BA2DDE4B97994D52B1ABFEE2DBA2EAACD
+:10A98000C56FDD79E2F7DEFF20FC6EF6D9EB9EFBAA
+:10A99000E7131D26E1E9EECFDD0EED2D2838A70FD8
+:10A9A00028D934C66B988D44FE8E5773E6B3DEED1E
+:10A9B000E3E79CBD3E9ECFDA2FF09BE8E0E70F83F4
+:10A9C0000B02D983D2F438E35FF8783CE1FB369E82
+:10A9D000DA61F27B8279B662C90FE27ED468BCB3D9
+:10A9E00042FEBAF2FF0AFD65771CE4DFF01D1B276B
+:10A9F000102ACEA7BB27F5CD2DE913ACAEE667CF65
+:10AA0000D19FD1A3B1C6C2BC69F11E248F4CFAE517
+:10AA10000CAB67E78BC8D43F8F1737F278B12CEABD
+:10AA2000D3384DFC3B066B09EE33EC798B18479A13
+:10AA3000DEAFBB5DCE57C7E74BE063E7A7C8F01CAE
+:10AA4000F533898F92207EB99F631EB21EBAF0E75C
+:10AA5000170A7B8D12E365F8F94BA5F69F15F232C4
+:10AA60004D3E4BCCEB7FF3D976CA610BF3816C3949
+:10AA7000B2E5EB7CE5E882E50437A4B6D2729286B3
+:10AA800014AD1B055DCEC5E72E2F45E4245758BFF6
+:10AA90005EAB15E7F926C90BC34721B9D5393EF599
+:10AAA0004BA2D49F846B7C21F62060E403A3F75271
+:10AAB000AD56F081C7290278CE58D09E1147F84A8A
+:10AAC000B224F43EAFB746E3EB7C756723C71F445F
+:10AAD000FF2E7C597F5A617F3234BAE49CE3FD7EBD
+:10AAE0008DCF2FAB4FDFF94D1B5F91085F191269B6
+:10AAF0000F6BF75151DFADBFEC7287C06FD4035BB2
+:10AB0000F977920928FCAE32A879C4778F7C9DB979
+:10AB1000F59317E56AE9F9CB55B57ABD5E2BBEEF23
+:10AB2000303DDF82F1BE52FBCE316D723F6811F3D2
+:10AB3000764EF3FE6BD443CBA6E6B35A7C2F15E3D7
+:10AB40009E2BBE27A7E35B959CBD21F444B5F8ADD1
+:10AB5000394FFC5E76E1F756C9F519B11F558BFFE9
+:10AB6000FBCF531E7E309DBF55AD238F766EFCFD0F
+:10AB7000E879E2F7CF6EFC4AAC5B55E3FC4A0397F9
+:10AB80000F459CBF548B5F4F65FC44BED8BA012B68
+:10AB90004EF61AF9E3BBB5750369650A3F0BB85E5B
+:10ABA0003FD7F1EFAF7AFC770F58CAD4F88F68EF30
+:10ABB000768CAF2826095BB5E33E5AEDB8E9F73944
+:10ABC000E87E7AE47D8E71CF97EF5FAC7AFC5B1DF7
+:10ABD000743F3772AB93EE9049F9C4D58EFBCDF339
+:10ABE0005CEFBF14F80635DDB10F94B2DFCF08BBC0
+:10ABF000F6839AEE90E352F5DF10F6CABBAAAC7F5B
+:10AC000052F4DF6CE353A1FE3D02FF7BAAACFF6B65
+:10AC100081CFCA2AF1F9BE5887A5F6CF80E07B1014
+:10AC20007564815F73A1794B5B7C49C98FE79CCFC9
+:10AC3000F4D077826F289A8EF14EE802B2C7FDC732
+:10AC4000C307795E495AF8FFC9B4C4F530C5B7BC2B
+:10AC500051D3711E67FB5D8A92B08A9DB7D5FAB950
+:10AC6000FE9374B39BAF7715300FA954FDA0BF7846
+:10AC7000FCA5062628FF0462E21CE9CC8D46D173B0
+:10AC8000022541792DB2AEC24136CE40ED46A33009
+:10AC90006F396EE313B3081F55E7F8A88A6915CB1F
+:10ACA000539EE3E7F36AF763FB87526C02F83D0EAD
+:10ACB0001CBF417FA21BF3C4D3B52AF16920EC3C31
+:10ACC0001FBF49F4F34E41DF80B77C9E58E7CC7636
+:10ACD000CA57EA6FE7F94A069894DF39102A7FAF1E
+:10ACE000C1580F8FFFEF14F94F23F8FD287E4F8CCA
+:10ACF000DF8F2EC4F65FA1EFF04EB57ACADE8F1358
+:10AD0000369D71F6608BF37B1E3B2EEF379CDFF593
+:10AD1000F862CEEF7ABC3315CAEB1A08F1F3814A18
+:10AD2000F8DB79EF76BD6125A5E945F994759C0BB3
+:10AD3000F8624E7CDF3EFEF1F641EF61BD185E6FBA
+:10AD400015DF4AC51B26E9AD515359AE371CF91919
+:10AD50003D42BE7C355A0AF532D3BB25DE0778FB6F
+:10AD60005082F243B458C2A078B4D807345C0F05BF
+:10AD70007CFAA4BD2E031E3BDF98F23A24C3A2F353
+:10AD8000470DD79134BDDDE4BCDA72FFFBB5315A13
+:10AD900027F51AAD13C998A0EFBADCE32CF45BFBDE
+:10ADA000FC783EE6B71EC0D2FB0739596CBDECF506
+:10ADB000733DAADD9030B4F9E4AA92DDE3C6E34B1B
+:10ADC00062FD856CFCD316E55F548BFFA355E26FE3
+:10ADD0008FC3F0FF1CEA5986FFE7B12C85FF534271
+:10ADE0001FD581D14B7BB6C1F52CC07AA330BE1ED6
+:10ADF00008F07EEB849E02E870E4F578055DD5D21C
+:10AE0000F3ACADD72AD0638FCBE87951CCC777CAE2
+:10AE1000CDC7B7053D8100DFB7B40309832D4DB819
+:10AE2000B8C4BC9C1078CC0C88B852BAE39CE4EA55
+:10AE3000A52AE93831352FAF8A79F9E772741C17E2
+:10AE400072959161E549DC4F9BEDFC850D8E7999FA
+:10AE50002DF893F1D9F3D2E99897DA739C975F555F
+:10AE600049CFECA979392DE6255F4ECE0AEAFF5E7F
+:10AE7000D4FF83A84F76E2ECC0EF06F0BC6CA13F94
+:10AE8000E109D44FED6FAC9E1C583655EF93A347A4
+:10AE9000EC7A3EAAD735594F0B14F407E9D706F0E0
+:10AEA000FC7B507CFFF1FDD1F035A25D84DADDC082
+:10AEB000E961ED6A0AFBFFD2E82B76FF33B05EEF63
+:10AEC000DA3FD8F5A285F56607FE60D78BE173E916
+:10AED000C0647F0D85789CF0FFEB00CFD771E57BD8
+:10AEE000E9D5E53B78A349BACFA10EC2199995439C
+:10AEF0000ABF5F21CD8CEA43983FEB4BE6A00ABB2B
+:10AF0000CBA3F1763E666FE1F9F10C1D9EF71BE8CD
+:10AF100082987080BDDF1355C81FB8D39F6C0BD4C7
+:10AF2000733C290FE0556E8FF586DA441C85E3B536
+:10AF300037F88111EC4F677861FF9F0C469EC7FA86
+:10AF4000FBE6A894CFFBFC9CBBC84EDCDBAB00BE91
+:10AF5000DF7B9D4A76E203AF86691F1E54CC9B2897
+:10AF6000FFC1520DB41BEF0EFCE118E6298FF7D696
+:10AF7000E8D255440FE19FF640A29FFAE776E776C4
+:10AF8000863FE603D3D685FD76713F06449EF3DD0A
+:10AF90006B0DCA9B3180DFDF34DCAE529ED2DEC641
+:10AFA000F91D38DE03ED1AD91D0FDC30BF97F2B959
+:10AFB000DB0394FB56173224CCEF89AC50013F04DD
+:10AFC000A98B1ABD6877869707F0CE2FA86BE4E3AC
+:10AFD000851702DDF3E7854C22CECAC8884AF738C8
+:10AFE0003D70C386DC66B46BDA79FE3223ECE5F89B
+:10AFF0007280906025C83F00C4C73B9B9FE7DBF38E
+:10B000001CC94CB62F7B8E18C956592F575DBDF001
+:10B010008842F9C915EB65AAAC97ADB25E8ED7AB85
+:10B02000787E2FF22935F60FE3707E773E76A8FC06
+:10B030007771E79AAFBB37E0CCBBAED4DECED3ADF1
+:10B04000442F1E664EE22957AE6FE7D9957AEF9DE1
+:10B0500079570CBF4B1BAEBF5794F7F1B2413C6F11
+:10B06000D81EA3FB221BC4FB86FBE8FE48773F7F6C
+:10B070002BF4710B24CACE439DC0FF75863BC6B32B
+:10B080005B940AF900EE7C3F97DED3947427ADDB26
+:10B090001B787ED1E4F7938DE2BB114825E214CFF3
+:10B0A000B2228B674EAD1FEFAAEFD2FAB1BF9B64FD
+:10B0B000F3C3BF9774C9895B2E7CAEFC940B959348
+:10B0C0001FBF4D72E21D91AB5A3FDE4C95F5B25554
+:10B0D000D6CB55574F1D91AAD22B6AA6CA7AD92A28
+:10B0E000EBE578BDC195AAD8D7470731BEE5BD428B
+:10B0F00073C08357049CEFAF0C39E0A165CEF6EA2C
+:10B100007267FBA1E5CEF6EA0ADEDE0CEEBF261D75
+:10B11000AF7E9DFCAFF35C272D5AF9FAE1F60AEBFE
+:10B120004AD3FDD8BE4E3100EF1762FB5556EC5B9B
+:10B1300045E33FEB827CFD5F17D01DF7D3FDA9D31C
+:10B14000D912E4F8DAF456C2D7D6BFFF220BBBAB54
+:10B1500044DE3D7E564079D830DE80FD3D7FCFCC49
+:10B1600006B4E7F6BEB682EEEFE87F979D376352EE
+:10B170003EA472EC9764BFECDDCEEF977EB4D6ECC4
+:10B180008AA3BD12F600DACBCC8DA27B3DF6C63C7D
+:10B19000648FF45F5DFEFE924FF5F03CA187D1EF26
+:10B1A00067FAFF80B877EB4171EFD6FD3D0695BB9E
+:10B1B0007B5AA8DCD5635239DAD3CEF3197B2CF154
+:10B1C000DD5917955FEA49D0F32FF47453F9F99ECE
+:10B1D000243D7FAA672B959FED49D1F3433DDBA921
+:10B1E0007CA2274DCF1FEF19A1F2B19E0C3D1FBAD3
+:10B1F0007A03DD9371EA3E0F7D1D520AFF392967FC
+:10B20000DC61F65667DCA121E98C37CCEA76C61BF7
+:10B21000F455F31DEF236DEF70C0A1D6258EFA8192
+:10B22000F8150E586BEC74C04AE89D0ED87C6E83FE
+:10B2300003BEEC999B1D70EBD39B1CF03B3EFD11B4
+:10B2400007DCF2A93B1DF0C5FBEF75E0171FEB73A0
+:10B25000C0EB83F3F97DE0033B1DCF8DFBF639E0B6
+:10B260008FCCB41E0B623C3413E1F6EC7189F6C14D
+:10B270001973CDDBF03B29F8B14CF204519E0F3F1E
+:10B28000637EEA72BCA70C94D48A1BC395EF91B677
+:10B29000E33D72A43D89F27AFA35C9407B578A6C46
+:10B2A0005F58E8CFD9E5D65329388C71499167A604
+:10B2B0005F0496C5DA05983EA1C34548E57650DCA3
+:10B2C000D243DF5165A424E59B309BD9FC2B1DF3B1
+:10B2D000E8DDFB6F90ECF253519ECFDED1A9350D26
+:10B2E000B0FABB17A926A6784DC3D775BFDDAF82CC
+:10B2F000DC0FDEB583C72BF517FC4D1A6B1F32939D
+:10B3000033D055B5DB8572DFA3EF944286B91CFDBF
+:10B310009A503C039B43588F7FD7C7EA7F3558200C
+:10B32000BFA164CE5259FDD89664B387D5DF2DFAFC
+:10B33000DFBDECC7748F6038F713B898FC9DCFD091
+:10B34000F8E1B6A3707B18F5D338AC2BB28E77FF3B
+:10B35000BEF8F748E34199DAEFEECD82C9DA05721B
+:10B360005FA77B38ED7909B61E8524F6BB6A82BEDD
+:10B37000A1DDBD43A27E764B2FC56282CE5E179DB6
+:10B380008817D2753BEB27D49D94D6B5F2E7CDE173
+:10B39000A97EF1FD667C7F4B4AC23CF76AF8A72282
+:10B3A0009F928C7FB8DEB664A4B2FC337216F25B57
+:10B3B0008B57E2DF839C7F8C6FB7B74EE7D764FD76
+:10B3C000F45158DE5AC06FD11EF9727B11BE4EF295
+:10B3D00089B54F52FB97606988B7433E8419DD9B5E
+:10B3E0008BB5935E12E3649DE3303EDE4ECFD322F5
+:10B3F000BEC8EFF5B4F344ECFAF8D7B55CE42932F3
+:10B40000BABDE3B59BF1FBEB8ED624DD033C18F20D
+:10B41000D0FD4283A1AFE4E89E7E1DE8FB5945B113
+:10B42000FA7E14E571E83EA9D83A75FA09F8654A3A
+:10B43000E1F76403213B0FBF82BD24EE1596C5BD25
+:10B44000C2AA92E86AE2EBD9EC85A9F8EAF4F1F72E
+:10B4500011DD72CCB9FF0E6C71EE7B71FD668A63F3
+:10B46000F747ABFB6EC897E7F6A52AF0F1E683FC39
+:10B47000BEE3BC9FF0B4F233A85C93AFA5F2AAFC84
+:10B480006C7ABF3ADF40F0AA7C33C157E69BA8BC78
+:10B49000227F293D5F99BF84E0F6FC522A57E417CA
+:10B4A000D3F3E5F92B095E965F49705B7E2D954BD2
+:10B4B000F31D542EC95F4FEF17E7AF23D8CCDF48F9
+:10B4C000E525F9F554B6E4FF8CDE2FCCDF44F0C55A
+:10B4D000F9CD042FC8DF46703CFF51829BF31FA6B5
+:10B4E000727EFEBF52D994FF18BD37F21F27785ED7
+:10B4F000FE1E82E7E6FB099E93EF25B831BF8BE085
+:10B50000D9F9512A2FCA3F4065437E2FBD9F957FB1
+:10B5100088CA99F927E8796DFE712AF5FCE7C57D9F
+:10B52000D14F5119C97F95CA70FECBF43E94FF1BD1
+:10B530008283F9AF5319C87F9B4A2DFF3C9595E64E
+:10B54000A9D2F74F6B6086432E56E72F72C0574E35
+:10B5500038F7EF953F77EEDF2BC69738E065C79C4D
+:10B56000FBF7D2A39D8EF78B8FBCD3015F9273EE56
+:10B57000DF0BB3CEFD7BC1814D8EFACD998F38E0C4
+:10B58000A611E7FE3D2FEDDCBFE76CEF73DA2FA9C4
+:10B590009D0EB861AB73DF9E050FBBF2C90F3AEA8F
+:10B5A000D7589F73D40FB77FC575BE92E5FADFFCFD
+:10B5B00086D38E6979A1E8394C7CFF75F4DDFEA94C
+:10B5C000468FB86748DCDB2AEE4773CF679DD00310
+:10B5D00033F2DC7F8A8A75578FEBAE20EF89D91959
+:10B5E000AFA17EB0ED8C19F38D2FBFC8E0D373559A
+:10B5F000B397C1B69D61D7AFF8BB15AA399E6678DF
+:10B600007A8FFBE8DE3929D26D615CEDEE1312DD35
+:10B610006F57371B449EC0755D3C3E01F67D3A7402
+:10B62000BFCFF01CFBFDE66B298ED1C4E123A11D29
+:10B63000EB308E3AECB5DF7FFE5A6AEFE7F0FF0899
+:10B640006D19C2F775358763681FED2A71BEF93F22
+:10B65000432AF1B33664FD30B46CEA9EE9E3D1E4E9
+:10B66000CB21F67C9B969C875776E33DF7788FF34A
+:10B670003AC5FA11D65BAF58AF84685F70FA0FEF26
+:10B68000C7DCD765742FE04FF0BD1C7996F6A3BADE
+:10B69000EBEFA3FBAA86C30C9F50697CFE3E244FB0
+:10B6A000EE3760EF37F3299E4AF6E05013D0BD190C
+:10B6B000C3B58934DEE797FE8E06874CA43BC3935F
+:10B6C00095447EE2F025862D178EFD092091C33822
+:10B6D0007E301932D05E0BC151CABF88C004953A82
+:10B6E000E892E3BE6D9BFE399C7EBCFF3F44E7F0D1
+:10B6F000D6B3E314674D81B8BFFA4D7CCEF8723AE9
+:10B70000B4AC345FAE91EF039D8DFF28B327918ECB
+:10B710004781E33B86FEA98478A6F466EAD7798F51
+:10B720008472FCEB243776BC47915769CD488FB8BB
+:10B73000C7A18BFD43FBB03E513EDEE3BEB7E15CEB
+:10B74000E33DD1B03BDE13A2F3E453ADE5BF83B3D9
+:10B75000E33E63ADE5CF7B9F157EDFD7C479EF3342
+:10B76000E2BCF72BC2EF3B2CFCBE2FA2DFC79E3FF3
+:10B770002DFCBECFA1DFC7E027D1EF2BF8BEE4C977
+:10B7800012F7BF2CAC95849C6D27FB3E28EE2B62F4
+:10B7900023903D1F10F6FC98D93713FD8E602D6461
+:10B7A000D14FD87ADD41FA7E969162E2FD0077FCB6
+:10B7B000E2F599FF85C1F11838EE770AB4BAEE4B7D
+:10B7C000A8348E92B5B0DF20F31B326669FE9C73FD
+:10B7D000BF5A16FCE7D52FBFE7C7BEB78D71328DB4
+:10B7E000F21744BA7594ABBFA1714E897140FEC186
+:10B7F00011BACFF07205CAC9C1B471CE51FEB68478
+:10B800005DBF4FE1923FC0840D46EF3CF1BDA611F4
+:10B810004A37EF61EF9FB84F757C9FED96C7DED733
+:10B820007C14871D5CCCEFE579B17EDD45E80F7EA9
+:10B830007AEF9B4D889FFDDD52BFE98C5BCCBB0F3F
+:10B84000A4C27C9603623FE8D7CBCBB97DAF78FF2B
+:10B8500058F97A0F8A7A5F0C5A7D61D22B13741FC4
+:10B8600064FB89AE9B11DFC77668745EE36EF7C533
+:10B8700060726778D9743C0BDBA3BC9569BFAF5C81
+:10B88000FBE53FEDFA29946FFF70B8BE74FBB697E5
+:10B89000BB1EAE80FFC1E2E3A71FC376F3623CCEBE
+:10B8A000D4DB3044F3BB6B07F79F5F5CB48EEE993B
+:10B8B0001DA8E5F356A4DF2F54E04B7705BAFEAA86
+:10B8C000527BA93C5DDF2CC717C6D76315F8F29DE4
+:10B8D0000A7C3D5001FFBF2FC1D77988F73CFC7D22
+:10B8E00038D6AE770EE32BFA6FC85798BE1E8AF48F
+:10B8F0007BAC1C5E55C8EBF805CAEBCF2BF0B592BC
+:10B90000BC4E5CA0BCE64BC92BE27D01F22A47CAC3
+:10B91000F3B592BC06231726AF33CAB5AF425E67B4
+:10B9200097C3BF0A796D2E36BE0F8216DAD5A75A95
+:10B93000F939D9D60E7E3F99B785EFC3C1E39F256C
+:10B940007B6980ED5733DA71DF3EF1E01D6D53FB0B
+:10B95000B47B1F72F7E7DE47EFF8DF9FA17D342449
+:10B96000F67D1B1FBFE1EEA7FCFD16E73A6E007FD8
+:10B9700097A9E0F72E1A926FF578CE7D3E60F2F12E
+:10B98000818DBF96CE159FA673C59AF60B1DB77C09
+:10B99000FD59DD1766177C28E2B40B666FFFEA637A
+:10B9A000741F89E867B662D1EFF8297035BFFF646C
+:10B9B0001BCF1F92B77FF9B1934B0BEE9982C35205
+:10B9C00061BE90BCEDF063270BF0CA63FC87C79B98
+:10B9D000298F31AE5F11A07BEBC6CA9F67FC40EC9C
+:10B9E000E3DF17E71947C479C677855DFBA2B06B23
+:10B9F0005F10766D4ED8B57F2BECDAE7845DFB0DDA
+:10BA0000719EF1A0388FC8F41C20784F4F56FC4E21
+:10BA1000C993E2774A0E8B7CC967F9B9454F8EDB33
+:10BA2000C78F7FAD19F93145873B8EC5E9B0EF4728
+:10BA300077D3F12ED379DFC6F52D41C7BC5D6738CA
+:10BA4000E322D7C6663BEA5FA3373BDEAFD52E7550
+:10BA5000BCEF80A5CE384BFE0A679C65C21917B9AA
+:10BA6000F2E7CE738D95E3CEB8C88A63373BE32CFB
+:10BA7000479DE71A4B8F38E3228B73773AE0CB9FD1
+:10BA8000BDD7517FD161E7B9C6A54F3AE322B3BA1A
+:10BA9000F739E05AEB61E777F5EDCEB848D874C6D0
+:10BAA00045822D5F71C0EF61FB3DEA4FBFE18C8B9A
+:10BAB000F862CEB8C84F43FC1CD0F6B359BBBF8B5D
+:10BAC00090BF19CA5DC9E4FD8928BFE7FD09485246
+:10BAD0009E2CC09F93DFA04CFA0D16AD7B59E81D3C
+:10BAE000B5E1E48FD1AF517673BFE70E69454E2BB8
+:10BAF000F47BBCFF2215CA87ACBBFD870AFD7B4DDA
+:10BB0000F277940A7EC9F47EB9BE9ABAE7BC2D8D4D
+:10BB1000F954CAA45F72BDCB2FD996A1DFB39A5155
+:10BB2000DE2F9936CE39EA9FD391127E49CC43FC61
+:10BB30003314EE97EC32855F02FC7B29BB3F5BFF41
+:10BB4000A80DE5F5887D5F8BBA88FB0D4AA8F879CA
+:10BB5000B67DDFA4BAB87C7FB65FF37711714F5C16
+:10BB60000D88B8FEFF978FB7523EAEAC29113779DA
+:10BB70009BE5A354BD73950F057506E5837C70188E
+:10BB8000F3417C2E581370CDFDDBD6E1F74DDB8100
+:10BB90009FEFC02BFCDED552FDDBF95DF155B7966A
+:10BBA000CD83B0E3AC522D3FFF8CB7DF4AF993A7AA
+:10BBB000D818E5EED576E75BC8D114FEE81E7ECF37
+:10BBC0005EF4DCE79FEA785C28DEFD81B2F68AFB52
+:10BBD00077C1E256F97B764705FEDF7E7516D9A957
+:10BBE000BBB6717DAC747FF37994C74FA33C9A14B4
+:10BBF00057D12E41BAB62974AF5AC8008A0FCE0D5C
+:10BC000041B6B709F96AA6F13E2FF647E7CB93F2A2
+:10BC1000B9CD79BFC9EF74BE9EE389F27CADF8BBA4
+:10BC2000062B0F77D0774206A4F45A5A3FF07A9445
+:10BC3000F023391D6E37F9EFDF317C747D7A7B3765
+:10BC40005EEEF5A96CB98AE24AB3257B7D064DCC40
+:10BC5000D739150A95BDEF6D5ABFE7B81EBF306DD5
+:10BC60003DDED0F78F38EE9888236D677F05E79D1E
+:10BC7000EEFEECF568C3DF7EF56EFABE6578EC4E3D
+:10BC80007E6F71A3B81F6C8CEBC752781D1272B413
+:10BC90005BD88587F677F6217F07D8BA29D4470B7A
+:10BCA000FEF2BD81243F5FACC3F23307F877DB17A8
+:10BCB0003FB4453CDF44CF1744F9FD470B983C6146
+:10BCC000CC3BBCEC158DBF7F59A7FAD1F1117C7F1D
+:10BCD000B178BFA7BDCDC2DFAA8CD4CEEFC4521EAF
+:10BCE0003B4A7A97CDB9B5C0C07115FA1D9DB923ED
+:10BCF000F038D231772CB1E13AF40FD2C07FAF2DBA
+:10BD00009ADC89F21AC900F597060E1BDB759ABFFB
+:10BD1000F858721FD56FE5F5D97B82E7A6F8FBE0EE
+:10BD200018C317C733D97B03DF73FC1BB7E814AF05
+:10BD30000B8D1D4DAC257FC46ECFE1865B787B6596
+:10BD40008CD183ED6376FBF10CBE9F15E5EDD5310B
+:10BD5000BE3FEE69DF44F7EAB1F1E9DE29AF78FED4
+:10BD600084E07FBCFB5F336BA35379196966FFAE38
+:10BD70002FB29EED756FFF0E60BFF80E49D3663F80
+:10BD800072B2E05E06FB77430363CEFDF94C0D5FB4
+:10BD900097FF1DF5CCB2CAF7B3FD3B5950D3F30062
+:10BDA000800000001F8B080000000000000BC57D14
+:10BDB0000B7854D5B5F03E67CEBC3293E4E43D79C0
+:10BDC0004D4E2040944007081810DB495444458DDF
+:10BDD00068DBE0B53A04E419202296A0D89C9004D0
+:10BDE000F20206EB2F111126281A2BE86041B15AF6
+:10BDF000EF80B9147B6D9B5A2FA2A28DA05114B86D
+:10BE00002915C9DF5FAFFF5A6B9F43E64C2609EA4D
+:10BE1000EDBDF93ED8D967BFD77BAFBDF60E6B102D
+:10BE200059C8C6E8E79B61F09F1A63CC5725B2500A
+:10BE30007E58BE32C3989F3BCC58FFF64B8D79D7C6
+:10BE400078633E798AA1FDF91B18EB744246F2D85B
+:10BE500018A4D2D1DB6CA56318AB4D5E4EF9DEBBE6
+:10BE6000F4726F0CE6F3E418912533B6AD400C3450
+:10BE7000E532F644D5F2C3C320BF3659A43ED7BA43
+:10BE800066C6FBA0DE37F8F3A3FE69433563212BBA
+:10BE900063DBABFD946EAB6EA5B43E79F0767BB5FB
+:10BEA00076CF57DB58681463C16A99F2CF56BB2826
+:10BEB000BFAB5AA1F457D5F9F4BDBDDA43F927ABAE
+:10BEC0008B287DA2DA4BDFDBAAA7537E6B7529E5B1
+:10BED000B7549751BEB5DA47E9C3D50B28F5575784
+:10BEE00052BAA1BA8AEAB554AB94365537D0F7C0E6
+:10BEF000B860596941FF79D6CA00871428BFDA9320
+:10BF0000510AEB79FC6A56168C5A4FA07A1B6500D1
+:10BF1000DA44C6DCCCCF1C85F07B2B633B15C6EC2A
+:10BF20009D7ED50970BD74177CC37CC8AF3A209F35
+:10BF3000FF04CF6FD2C6A962CCCBB05D150BEC0469
+:10BF40007CD8143F9B0DE379B35576732C63376926
+:10BF5000E3E07784AF9AAB32C4EF098BB7544EC19C
+:10BF60007EF8F8313E9F00CB63692B588D05D28453
+:10BF70008A2E668771E21F0A796D900E6BE864BEA7
+:10BF800002C4AF586282799CF38B011374AD4C6587
+:10BF9000A208E337BB383D44AED3DDBB8D852640D8
+:10BFA000BDE42E3B8EBBAE6A663C8B020F3D1DDDB1
+:10BFB0002EF6D127FCBB2410C60FF06F9D7FF0F644
+:10BFC0006965C6F609DE88F605D01EE0102806FC75
+:10BFD00045A1B7F82263FB584F447BD7E0E3C7F491
+:10BFE000DEC8424903D3F3294B790DC25DCF8FECF4
+:10BFF000FD21D57FD729131E12AF5FED4238C3CF85
+:10C00000550867298B059A04CC7AD902C89BE1B7F9
+:10C010002699E76D90374990F7403D55F1B2B198B8
+:10C020007ABC2C0E532FE50F997D1BE589982FE5DF
+:10C03000DF651FD141E012E82203E58DD2E0CD8219
+:10C04000FC8FE1F7298CDD2C8F9EAE42FEBCD927F8
+:10C050005641FFCDD9626007E075A57B7C0CAEFB35
+:10C06000F196C1F9B416F974545FDEE4F43201FAC2
+:10C07000C9AC90C79BD8C0ED1EAA10A707A2F4BBFD
+:10C080005BA3DFFA8A99F2085C7507CA30C6AC4E2A
+:10C090001695DE60BDBB71BDE664BECE945B4B29D8
+:10C0A000CDDB35D9560AFC703E7670FC3546CCDFC8
+:10C0B0000E4306A3E1519B57DE1B2F91BC3C3F86EC
+:10C0C000D3D540FD366BF2AB3720B24EC4AF544AE5
+:10C0D000F235E5561FCB83F5AC4B17034E58CFBA5C
+:10C0E000AF6F69C8057E5237892407F4F9478E6B14
+:10C0F0002AE8124C50BEEEC042A6C0F8665729533B
+:10C100000B30AFCBEB20C3FE1DCE90175390980C95
+:10C11000D7EFA8F2A998B7B854E2E775E917EADBB8
+:10C12000102ECD7E91E4FBDA2C31C0044A9913E63F
+:10C13000736E35A37C4EFA838C24FD57309F49D013
+:10C140000FFE6E42783355C475E4325A471E3BCC1D
+:10C150004CD0CE3686799AA04A7C1E3B80EDD6A57F
+:10C160007F79C08AEBBB97794628D8D847F2080870
+:10C1700094A11C595B2953FDCCD6B1C417FABA7FE0
+:10C1800062F17D1ACE3716179767EBBE364595AF2D
+:10C190008735F9183300FEE21378F97973F05A9471
+:10C1A0009FCD90DF11859EEC5ABD47E5997FCA5718
+:10C1B000FAF8532F7FD7A910DFEAF9CC5E0BCD3BFD
+:10C1C000EFD69FC5E3BA06A287B51A9DF9E3B9FC7D
+:10C1D000CD9B7A8517E17E0EE68AFC1E597F51BC05
+:10C1E00042F3D0F392D328A72E7E7E12C9E3BC532C
+:10C1F000AB383F640F4EB7FA3CCF671BED04316F8D
+:10C20000818A7C5DAF007E15B417D63091EC02E6D2
+:10C21000615C45B138C83FB15A935FF95DF64B2078
+:10C220006F7BCBC410BFDBAA4A4415E09E932B055D
+:10C230004C00F7F82CBF97813DE2286002CE1FF03A
+:10C240003D322105E96012C1337B754810A1D31E30
+:10C25000947D29B4EC3AD7243E0EFE077C3F26019C
+:10C26000D6E9DD2570F9E0E2F2C10CD3B191FCAC66
+:10C27000624118CFF19689BE033F841E807C8C2CCE
+:10C280007A509EB678D6A4221F3A1218E9B505D77F
+:10C29000EE20B905F2D6B30556B4F46477EA32C895
+:10C2A000E7B9F87A74F8C414580CFA61C871A4801C
+:10C2B00017FB7508CCE3F70CA247BE6DBFB600B301
+:10C2C0007FA77E4191A4129F683FEDAA80E3E0BA68
+:10C2D000A15F2B7B99C639A78DC34C6F1C467E8905
+:10C2E000F981C44C51F865C0714CB70FAA37AA8EBA
+:10C2F0002DFC5347183DDF95109BDC3D1A7EB98C11
+:10C300005DF60D2A0E13103CCE03EC4E13AD9FAD1F
+:10C31000413CE7C8DCEE509CEAF00D50FEF86A0B99
+:10C32000C90FBDDFF3D50BFED401486C29E072BF05
+:10C33000E6436B09F6533F4E0C58A15D47CAB48CD7
+:10C340002EF8FEC4A62F73717EBA7D5AEB31F245EA
+:10C35000CE6A4E977ABE55E38B5A79707DB241EF23
+:10C36000AF65F07A0F6BF59E75786B918E81D20573
+:10C37000E4CFA2E3D36FC3F96E7FC0C64C51E4C2D1
+:10C38000B30E5F73C2C4FEF30C6F8FF43648FB5FCD
+:10C390000ED67ED2BBD3DF6583B77F342165E0F64E
+:10C3A000856F4EDF32C4FC1F8F3EBEBA1DDBE5B881
+:10C3B0002C0CF15B93BE96F0DBFC80C563057EEF31
+:10C3C0001833CD8578AB4BE0788BD2EFB383CD0BB0
+:10C3D000E05236C4BA5E18AABD30F8BA5E1D02AE8D
+:10C3E000478780CBA1C1DA035C5B8798FF1FA3CF8F
+:10C3F0005FCDC179E7645948CFD464035C518E2383
+:10C400005C597F7E88D2EF3B43C065287AFDF07B84
+:10C41000D2EBC9C1C6BF087AFDDBF7A4D7FF3B103A
+:10C42000BDE2BCBF07BD4A89DF8F5E9D8983C375AE
+:10C43000287A4D1EACFD45D06BD660F3BF087ACD8F
+:10C440008B36BE9539BC2ADA45055C9F2F281649E4
+:10C45000BF9BF3B91E761C7BCA8BEBAA037D955458
+:10C46000847AFBF8C34B0BFBF474A41E8AEC2F52A6
+:10C470008F2EFDDB93A4479D9ADED7E7635722FBFF
+:10C48000F99741EDBB6F3B6E8C8B85EC63FBDAA7B4
+:10C49000FBFEBBC733EAF9180F1F9FC1F85716A15F
+:10C4A0007EDDE541BA8C2FFABEE30E5E3FADECFBBC
+:10C4B000D9050B12C12E70F4D9059955BFDEFE5176
+:10C4C000525F3F999297C9403712BB8AEC3756C1E9
+:10C4D0003C3BB1B86ACFF68F26F4D903007F01FD4B
+:10C4E00023FA38A68AE0F68FC2E6D53B9769FBB4FB
+:10C4F0004ADA17E5C95362908ED7B50C6E2FBFA1EB
+:10C50000E9F1DF6B7EAAC39A9FEA10FAA920ED40F9
+:10C510003F15A407D14F05E521F45341FE55CD4FFA
+:10C52000F58AE6A7FA8DE6A77A58F393F9D14F4634
+:10C53000FEA880E68F6AD7FC51414A1BAAF753BA7E
+:10C54000B63A44F5DADB5E188EF0E85B07B7DBF34A
+:10C5500064DDBFC7D7C158298B86AF1B3C26C3FEFD
+:10C56000E2FA7C87016FD72A4986FC35AE4C43FD41
+:10C57000ABE5E186F22B6DA30DE5C56C8221FFA32F
+:10C58000DE2986FA57F49418F2977F7A9DA1FEE48B
+:10C59000AE9986FC65476F33D49FD8596E289F703B
+:10C5A0007891A17C5C68B921FF83FDF719EA8F09B6
+:10C5B000AE31948F6E6F3294A7953D18E167DA62C1
+:10C5C000A81F5FB423C28FF42B43B923FF7943FE26
+:10C5D00026D0F728FFECCA6F0CEDACAE8386FCBF0B
+:10C5E000C531DAFFD89D41AF378A3DF9553CDFAF01
+:10C5F00082DD5E4CF632C8B1A671D8BAD28FFBF19B
+:10C600004CF81DED63C0AEC08643EA31CA1D5385A8
+:10C61000C538FE10FC8C1E00ACEF861FE4C7AFF4DB
+:10C62000FD6CBB5DFD218E9FC7E5B02AABE47F8822
+:10C630006CAFFB8BF2DA67C563799D5C2247930789
+:10C64000272CBE93E1FA2172FF9BE78D655E1CAF3C
+:10C6500042F797717967E25558E6B16B0E0BE8FF28
+:10C660002A7B3501D7A3FB79D6697C5AAFF991AD06
+:10C67000EC72F2639CD3E43F334DF50C269F22E12C
+:10C68000F56DE5999814B9CF9911FA18C7AF9002D2
+:10C69000D1F4A49EEA722CEFAD3B07C58F0E5F1D4F
+:10C6A0008F2639E845BD6A532A59B9B33F9C4C5986
+:10C6B000400F71FFFC75E72619E5F839F64AB177A6
+:10C6C000D845ACB7EC0E5A878ECFC87AFA7EAB0548
+:10C6D000F14AF291CBDF5A0DBF6291770DC2370E4E
+:10C6E000F6D1B8FF133D21D6F51DFCC08EFC4443A6
+:10C6F0005E726618EA9B3D952C88FE5B1887113D9B
+:10C70000FA18FA73F11FFA4B4C3287F3C07C773971
+:10C71000F909CE45D82103F11F0EF1CDF0A1F9F5AD
+:10C72000BBF277C7DC54EAFFBE78A6F95F549EAA35
+:10C73000EC4DA49FF2228D8098F2D3F760DE0B0FB0
+:10C740009B49CEFCE8ABED871E03BE341559E526A8
+:10C75000F20CF90FFD16CAE77A6DA5985F786C8C1C
+:10C76000C50DE5473280085C585E1A8772E03413C5
+:10C77000A7A3DFEE347B336E42989CBB27C942F2FD
+:10C780008535988F77D9707895CEB1EEF2F3BCBE2F
+:10C79000AEF9ADC6FC3C3633558271E63D646601A8
+:10C7A00000D642261DEFD2E10074302789FBDFE777
+:10C7B000B3CAB5328C5B6FE6E7364B5E1C63413C17
+:10C7C0002C9C20E79AC6F5CDE3FE2491EA7F06F47F
+:10C7D000A658FBBE2F72062C28974FEC9DF093CBEA
+:10C7E00019F613589B81FECE04B04394FEF09DD3FE
+:10C7F000609CE750EB889C37BA41069B87D42E7823
+:10C80000A3F9D51B9304031E6B6DBFD8DE05F3F4AB
+:10C81000D64ACCFE43C84BFC5C493D161BD889F276
+:10C82000BBA4F2A92E8083BAC62AD742BAD9F18B0B
+:10C83000E7B07E15200CFDB9CF2729348FF376772A
+:10C8400000CF1940DF5C3633F6FBF7FBE23FA9DF90
+:10C8500057B0DF94FEFD2EB17559D09FB84CAA9CFD
+:10C860002E88E857E4F5AC669F3713FD89FBC78532
+:10C87000321543BD868BAC7758187651F5A68B835D
+:10C88000F47746936FBFDBF5B805E5D6E95F7D78B1
+:10C8900023EE8716BF6C6236A87766572C0B91BDC6
+:10C8A00017B0A0DDBA68AFC91BA07C68D22DB1E17A
+:10C8B0007C5D4BFD2F7E2E96F6538B9EB706664011
+:10C8C000FB452F9C18CB401E9C59D3732813E1F7CE
+:10C8D0002B81EC67A6768DBD05BE2F92D89DD1CE5B
+:10C8E0003DFF9AC4ED8E532F39CA90DE84F603774C
+:10C8F00050BFC19F9AAD617AEC489299F009F5C892
+:10C90000DFAD3E2D0446087C7E378F099F5F0DAF5B
+:10C91000F734F7E72EDA6F0ED8717EED6D161FD45F
+:10C920005BD6FE37A2EF2B9FDB1D877058B6DF6802
+:10C93000AF2E7EEEEBB55300CF8B4DAC6706E9F121
+:10C94000AF287FCE6BEB31911CF2C60920B79692CF
+:10C95000C8827ABFFE64DA7B50FE99CBC4EC200A11
+:10C960003EEBFCD8F232E67DCE4AF4682FDB6FE472
+:10C97000C365ED272C382F59643D59C0E83FFC2290
+:10C980008C2F59FFFAB00FB6A09C5D166CFC9B096A
+:10C99000E86DD9DED3EF22DD2D8BE0E7CFF097F401
+:10C9A000FEFAD29A1CA92FDF9884FE72D60E9B9FA6
+:10C9B000C903EB4B9DBF17EF3EB74D85F14F3DFFD0
+:10C9C000F93615505EF15F7FDF763FEE8F5EB5CBB7
+:10C9D000289796FDEA3FE25818FC872573F970E620
+:10C9E000E9A79EDC027038F38E95A076E6B79FB873
+:10C9F0001580FB993DFF3715CF9D56FCF6EA34A410
+:10CA0000B315FBAE4C1B6C5F84741BB086E33740E0
+:10CA1000F855F6C33869907D454B23F0726ACF799B
+:10CA20000B9E0B7D29B01E94BF4B835F5BD03E3BBA
+:10CA3000E4653D08A7D7F69E38741FE44F039EAC0B
+:10CA400051F004EBCF1449AF843251BF2CDD7BCBC6
+:10CA50004D5714626AF6288827D643F2BE1F7EDF40
+:10CA600002FC16F6E137B2FC1CFBCA82F05FB60B83
+:10CA7000F03916F10AF81CDB1F9FA7F197C9FDF1E9
+:10CA8000599C6CB4FBCEB18AED5BB0706F12E17F44
+:10CA9000207C2ED9F7E341ED2C5D3E0C05E7050225
+:10CAA0009F576CB2F7E664E4DBE71DAA8BE33930ED
+:10CAB00003CACEEC3EE76640279F9A7BEE4038F4EF
+:10CAC000FCD62AEF80EF8B7EFB36F1DD997D7FB6B9
+:10CAD00020FEE1274E98047976E1E74D06F9A5DCC2
+:10CAE00006674B58CFB4770B31653DAA87F047F9FD
+:10CAF00043C087848FC0CDD31594BF81145AF7D219
+:10CB000000E78FA58103B70A63FBC3BD3959D4F58C
+:10CB1000D605BC0A4588CF0FA721FD0D844F7DFDAA
+:10CB200032AEFF32287FC2C8BF91F59702BFE2FE46
+:10CB3000A81F7E0307FE88E99936AB24802D740672
+:10CB4000ED04677FBCF7C19FEBE76F6B1FD747F022
+:10CB5000BBDE5E87D350FC3ED4FABE2DFCEE4956B8
+:10CB60000C74A4C3F1D457D1F5411BCA8F8908C7EF
+:10CB7000CAE919C3FBEB33132B553385BEF9AE0D50
+:10CB80009A48CE9F6A07BB5CE82F2F96E2396E94D5
+:10CB9000719ED3E4D4D2FD07C6A25C3B75F0258D0F
+:10CBA0002E39DD2FDDF5A145D5F443205C3E0F7015
+:10CBB0002EFC9236EF65AF44EF6FD9AEBF45EDEF77
+:10CBC00033C9FB539CFF679D66A642179F054D51D5
+:10CBD000E3191E4FE6FAEFC2BA63271D8DC77D41E8
+:10CBE0005C8C82EBAE5DE37D1BCF45D537CD74FE0B
+:10CBF000CF24CFA75628AF8D8D51D08F571B378F9D
+:10CC000029617ABC2E024E92AB94CEEFA4E4D242BC
+:10CC1000BEA70B18CE7FCD4010E1F306BD9B857AF1
+:10CC2000E983719F98719D7F8DB023FF2AB1B5690B
+:10CC3000D0DF5F55C153A344DB1F18FBF7AD36317E
+:10CC400025ACFFA5D69E0F703EEC5FED0CED32D308
+:10CC5000AB7601E5C9B26D66DA7F2D836D15C2ED45
+:10CC600093C7EC0115F29B7F5D7D07EAA5FFDC66AB
+:10CC700065781EF1DABE95DDAB502E3D2A30F4A367
+:10CC8000FFE74BD55FA25E5EB8155607F264BEA300
+:10CC9000E7496C3FFFB94C560BED3F178293703359
+:10CCA000DB9D129A84FB90EEDDE91E95FA797129DD
+:10CCB000F67BE63907F57BE65FDFA671CEFC6B2CD1
+:10CCC000E9357DFE606F2BE17A1CEC6DE5021F906B
+:10CCD000BD1D96877116639ED717BED1641ECABF4D
+:10CCE000C59802DD2FDE1FEF45FF4A583DEA6799E0
+:10CCF000B5E7E71EDA7FAB1922ED9D4219C88F8B8D
+:10CD0000DB8DE37FA3C9BB65969E79BCBE3F83F3F1
+:10CD10006D27B573A668F4AA9547B6D7EBC7A40CE0
+:10CD20008BE887B75F6A6595D1F8204DEB7771FB8B
+:10CD3000D7A38CFD71BAED3F0EFF7EAFC0E340D8A4
+:10CD40001E3BC5A35558422313816F5FB0B005C881
+:10CD5000BF1571A1910930DECB9ADCAC88813C7C97
+:10CD6000CFD0E681F531CF6C5D6710AF4B5EB4D3A9
+:10CD700079CA9217DEFE12F1790A610C183B95D23E
+:10CD8000F9E5FD4007A71E333115ECB525D690FB1C
+:10CD900051D4537BAC6C07F2F7ABAF93DE3AFDBCDA
+:10CDA000551CEC9C7A4910A8C1D67F1D6A09CBAFEF
+:10CDB00074621C8E576CC37DC36153A006C6AE92CD
+:10CDC000BC6B9EC3F51D36D33EE3EC5C968FFBCA6D
+:10CDD000B32CC3A312FE95B725285FF97BB3102DA2
+:10CDE0003EC9DC0B427D02F041EFF54C8154EA1D57
+:10CDF0004EE94A4BE52894BB26191657407E02B2ED
+:10CE0000DBCDC91E361FD29589CC87F063CEEB2EC1
+:10CE1000F0D79F00A5CB1F51D2B0DD8F52CC34EF9D
+:10CE200045A9DEEB53483F3A65B22F343A55F7F146
+:10CE3000799E17623C35189FD37BDF9D08DFE51F85
+:10CE40000A4A783C43643C6895A4BCAD14D27A4944
+:10CE50001EE5C9310CE17A563B773F3B57894F08B5
+:10CE600093CBCDD532C98FC66A17A5EBAAF39942E9
+:10CE7000FE350FE54DDAFAAD052AC507214FE38FE0
+:10CE8000D559EA453B0FE784714126A78FE8C8EAE8
+:10CE9000AA24DF94CDC9681F6B72AA6C3EA46627D2
+:10CEA000878FC9594AF0B16879A97506C113DAD3D9
+:10CEB000F7AB537D77233C6C59971AE4922579BCE4
+:10CEC00021DF0F5E3AFE77FF4FC18D119C1AAB6DCB
+:10CED00094AEAB2E2278D5577B29FFBF00B7D694EE
+:10CEE0008908B7294CB185C3ADC4901F106E8F005F
+:10CEF000DF2487F30DC011F986C5787646597F6423
+:10CF00008AF11028A81FAC6EA554FF9E3880DE3E23
+:10CF10009F2268F1B0BE1A338E23737F0B4B565994
+:10CF2000D6A43EFF2673A94CC13CF22AE2E5680C68
+:10CF3000C16EF9FB76F21B9B64A93B5CAE2DBF4131
+:10CF40004943F965AA7A9C9D088B4733CD28B52BB8
+:10CF500004570F9D53D66A7AB3FE02FE8C7CD05CD8
+:10CF6000AD50BA5EE3878D1A3F6C423C631C8987E3
+:10CF70009F6BB64C67A417FF0FE4F93E3EC4C2E3B3
+:10CF800046123CC19019F04D3252A13444F1BF47D2
+:10CF9000AD8111B9143FE545FA4838BA8AFCC78C0F
+:10CFA000055DE84F4BD0E0C65E1996302B9696672C
+:10CFB000E67A879978EA37A33D1E09D75ACF411BF5
+:10CFC000EEAF079A4FF1070B051CEFFC2C42134BF9
+:10CFD000BE3D78B41CCF4F5B1CA457533D9539E838
+:10CFE000DF63C7AC449F4E8F4F981F86BFD401ECC0
+:10CFF000BA55A9D77E8C7CDB8DB20CE8F0C1D6E1A6
+:10D00000768473B339E84279D79CC0F587520650CD
+:10D01000B8ACAFDD9F3439185768E4775DBECA53AA
+:10D02000C71BE85797AB895719E95C97AB2FA570D9
+:10D030007B6D516AE9799C4F52EF56E2C348BACFF3
+:10D0400093A794F992510F304F13DA6B6833A21DF6
+:10D05000F7A110E0F4CEFD5367BB7277A09D03BB30
+:10D0600002922B2AF203E1A9E7B56F9231DE95CB4C
+:10D070008735B699365C6F03D0111B85FE6C850031
+:10D08000BC01E887D179A047E38F224A75FA74A7DB
+:10D09000E61AE2044D798744C4573DD811144F0C69
+:10D0A000FB3B278C271D986C437B4F327B0EA39C48
+:10D0B000EA891583A837EB9D336D5EF4DF241412E3
+:10D0C000DEBF8C2DCF192C6E09EC16F2DBCA4E0F89
+:10D0D0003B8EE330467E5B933C9EE13E71B7B333BB
+:10D0E00006F72DB1A9A2615E8B527DC353C3F263D3
+:10D0F00070740D5FD8ED6EAD9FC8F17E90AAF92DCA
+:10D10000B354E60D3BB7A8D2E95B51D95561FCBDDC
+:10D1100066C434867117917C3DA0DCDAF9FDE456D3
+:10D120006D4E80F0658E9417C920C79D94AAA28C7D
+:10D13000F3569AFF2581E8EA4A840373EEB86087C4
+:10D14000FC685814FA3A7A691AC56B5ED033B06B32
+:10D150002E203DB3B988DB239A9EE1FAE96C8B83DC
+:10D16000F4D3D9B995144775B6254D41BA3BB0E112
+:10D17000F2B1088F79BD8D4C81F9CDEF9D4CE982DC
+:10D18000D65F525ADEDA0644CE58CDFAF91B664114
+:10D19000BB138F98282EA83B30E14C15E4BB5BAC49
+:10D1A0000CE38EBBB7DE93837EF16E1807EDABEE1A
+:10D1B000AD2388BEBA016E946F30D6C7786113E094
+:10D1C000A59C313D68D38BF5E7BD6E6A8B662795CC
+:10D1D0006FB47AA39DEF5C286F8D6EB7D5E2AFE98F
+:10D1E000F85FE5288457F107AB7270BD3AFFAF4C8A
+:10D1F000047984F0FAC0CAA2F9E3AF4EBDBA227531
+:10D2000022A6DE159832676254FF5A1FFDF3714F54
+:10D210008860DF125E7C71371BFCACDC8F7942B317
+:10D220007F996D80F238ADBD1CBD7C49CBE7871E70
+:10D2300060787FA1B214895EDF4F9B18ECA705DCF4
+:10D24000FFDE4CF1D0FA7CC04E253A66800F942F59
+:10D2500073357F0FC0FD260B7C3FF1BA4940FAE8D9
+:10D26000A3275F1CDA2D42F30D6B7643F9DF0FF332
+:10D27000FDD9C2DE4D24EF84E6319B27C3F77B5EE8
+:10D2800037939CAF69BA7CE3ED80DF2FDE30517EAF
+:10D2900041AF9DEA9D7CC0B3F976A8D7F30733D997
+:10D2A000E15F1CBE9AE21E4F9A8D7E82A9699C8F17
+:10D2B0005FD2F8795E6F33D91F7AF9BC863916854B
+:10D2C000E874037D9F878736785F8195FD7B711EAB
+:10D2D0009EE730BAAFF0D2C3B75EBF86F4DA78B259
+:10D2E000F7E7AFB77AA2C54FBF94AA18E4CFFCAE58
+:10D2F00016EA97815D949CAAF5172647E6F7261152
+:10D300001F30596518673C4F932717E6B7D56C90C7
+:10D310002727EDD1FD20AFA7F27DD4BCDECB89BF9E
+:10D32000FAAFEF87F47D9E3E6E17E7C7BEF56C9EA1
+:10D330001C6D3D7DEB984AF54F26441FBF471BBF30
+:10D34000BB7A01F3825C2AB7423D278E7FCFDAA2F7
+:10D35000425C4742A210B6AEF9AD8B99376C5DF3D3
+:10D36000B7CEB69487F5DB8787E5FF5E2CF5E1A1A4
+:10D37000277509E161556AE931E49BF2E62BC62283
+:10D380003DCE6F6D24389F307BDC285F3F69BD2721
+:10D39000CE17759E8AC18F30BF55C30FD8BB85612C
+:10D3A000F8D1F112D9BEFBFDF95F3E80F2E7116EB4
+:10D3B000DC0C04AF7E78CB8D0EB7188D3EBB41DF01
+:10D3C000FA086ECA0B4791AED73B3C48D703C36FF0
+:10D3D00034F30D06BF01EC57B0774C69785F017DDF
+:10D3E000B4780ED9CAE96028B8F58DABD14171F493
+:10D3F000F514A5E97450C55460D8E396A1E8E07E21
+:10D40000A6DA0659C7053A78D84007459BD7131DB9
+:10D410007C8AF6CAA8FEF83F6E51E3A6E0B94F93A6
+:10D4200089CE958EC7A8A9B7F1FC3894C7C7E3FC8D
+:10D4300037E2398D9E5FB87344DCECB0713F690010
+:10D440003844815F51DA00F493A7B28249FF3CFA75
+:10D4500039618E7EBFEFEAD4E2A969A83FFCD1FD15
+:10D46000B57AAACB6B53BCF3C23E13F5E771E7B0B4
+:10D470002F0350DA9CEA9B8E745197F0F33B511EB8
+:10D480001C3F2E90BEAD797FE528D46B917602ECDF
+:10D490003F1BF0DC73A529D64F76A854B99DCE4129
+:10D4A0005589ED2CC47D4AE5968F46A0DFB08A529F
+:10D4B000A6D9A12B4D977A9AC82F5BF9149E930297
+:10D4C00091C8585F6295746E0A82B014F39B1DFC7C
+:10D4D000DCB54AB2C9D6B0B884E51ABFD45797FEB6
+:10D4E000F223F443DB5426A7627B2E3725C6EDAF2B
+:10D4F0007FE03CC3F4BDC5EC933DB80F155829F24D
+:10D500008559F2D1FD27B32B799C1A8687CA347EC0
+:10D51000DE6EEFE868C885F6F6BBFE20A31EB4C237
+:10D5200038E867B3654967C3FDD5E6E420DD6F627F
+:10D530007961DFC1AE721640DEE00780F90E621736
+:10D54000BE2C785C5F223DD67078142188207D67E0
+:10D55000EEF03694CB45529D09E38E66DD3582F2BE
+:10D560009BE77C33B22B0A3DCC7A655D27DA33B377
+:10D570005E499F83E707B39C233FC614B60BB618DA
+:10D5800068FF9AC0824D905E657B9CE2195FD3FC78
+:10D59000631D980FD38B1D1ABD819D337D0FA4B3DE
+:10D5A0006C7EF3DD057DFEB4C871376B7CDF610EE8
+:10D5B000A65C8A7400E3E03A7EF64AE0C7A0FAD996
+:10D5C000EDC1C00D63003F77B01E33C2D1C7643ACE
+:10D5D000F7D0FDBAE5CCA3E519ED4FDFAB30EF4056
+:10D5E0003A89ECEFF610EFEF671DD01FA4771CEE21
+:10D5F000F93754CBBEA03CCDC1C2FADBEF39E460B1
+:10D60000FDFB8B84B347B299D430B8028AC470B89A
+:10D61000F7836F7CD9756CECC07CD6076F3E8F4862
+:10D620007C7C8145C0A76D69DE5F23BFA969DEBD33
+:10D63000C8BF15B61EB70474732CD9B71FBF2F35DA
+:10D64000F97252011EA7B37DA352102E9DD1CF5F58
+:10D6500023F93BAFECF463C83777D4480CF1BC76C0
+:10D66000DF278F215F9E36031FC17EE0B5559FC423
+:10D6700022DD2C01060C97271F548D20FBE9ECDEE0
+:10D680005183DE1FF940F397746A7CA2AFF34E64B6
+:10D690004018EFCEBD0EDACFDC5965BAB0CF427A72
+:10D6A000BFB38AC78730A973ECAD06BBB36EC07E2B
+:10D6B000701F11D94F77B56F3BF1BDE49B8476F7AE
+:10D6C00089EA05DB51BE44CE73A4CB77228DF4DB0F
+:10D6D0006C43BCEDDC9685DBC3F950AF5F3B807CCF
+:10D6E000F58CD2CE016D7C3CA6FCA0D83989EE6BBE
+:10D6F000D28F3D64FB5008A387A1C6637957792F69
+:10D70000C805DC7FF944E64CEDDF5F643DBD7F5723
+:10D71000D595ECC4045C9FF7FFA5A50C3D7F8B8BD2
+:10D72000CFDFAEB5D3BFDB7D7E8676A1FDAB78B211
+:10D73000133CA3B8FFE11F9A5DC09CB05E6430FF4C
+:10D7400066EFFFC67A61608A17B66FB5468D2BCA41
+:10D7500074491C2FC143C5B628F3EBD75F48621745
+:10D7600053CF338AAF1FDD64E4EF1A1943FB9AF2FB
+:10D77000AA5ADA673782FC407D10399FE34D8F2A21
+:10D78000A807EC16BF827ED1C691A9B96BA01D482F
+:10D7900035F2FBD863FC8A14FE5DF307D9D7F81580
+:10D7A000DCDF368EC8A0EF7A7F8D0297B33A5F3404
+:10D7B000C2BEEF79F28B795C3331AEF4ADC0F45870
+:10D7C00068B7632D0B99DC8C1D74678CC67DAEBF6A
+:10D7D000DE42E77B8DF962FA5CC8C765DBC83FD6DD
+:10D7E00096109A85F76B554122FDEA4F50AE8D4554
+:10D7F000FFEE9AB44E947F07EFB6D07A9B27F3FBE7
+:10D800006AD6291FF9AFC4FE57300FEAD51DBDBF38
+:10D810006EC57702D4A3B09F45BF21760AF268C7D0
+:10D82000F4B376DCCFB930AE0EF0B1D51CA4796D6F
+:10D83000A9B152BF5BDA2C65D1F0F779BA44EB0A93
+:10D84000085D141F9CC4827684EB83D3676ECE83FD
+:10D8500076B9794CC6FD7C73C1596DBFE935F1F3DA
+:10D8600028DD8FC8ECDA79964D3BA7B285C7173E05
+:10D87000EADF4BFE43C78C204FA78BE47F8E9CC70B
+:10D880000A17A77BC7D4CEE9A8271C852213D0BFCF
+:10D8900099C7045C973C7D075DD2C8CD6703B43758
+:10D8A000517BD90BED0B797BF409C917D9BEC2C5E1
+:10D8B000E30CD7A31F0ACA03668F702DCC23708395
+:10D8C0002CA84A5FBD7A17D7AFDBA1FF10C9D100E2
+:10D8D000ADCB9D1F0C21BDB92B44C2D3FAA2E3747A
+:10D8E0002EF060A1EE47F5D03CB6D61C3980F6D7B5
+:10D8F000D67B19D9495B518642BBAD37B0003F4F4B
+:10D90000621928DFB62CB45C4FE7F905007F81D29D
+:10D91000A8F39E9D6E237CBB573F18C2FBFB311EB4
+:10D9200020D45C4AA3D66F4CE770DA620EA4A37FC2
+:10D930006420BA287371BFAABB4AB3AB98DF85785D
+:10D94000DDA0C187DD3A9EFB1724AF121EC7D5A705
+:10D950004FB81F03D64771AD497516D247E28CD038
+:10D960002C5C5762BE855D938BFCC5E1A68E117958
+:10D97000DC190BB4227FB65D924AF1A4EBC4800B94
+:10D98000FDCD6A8985CE930F1689B3F05D848D75C0
+:10D9900016F243409EF8C5EF1DD686FCE6985A5213
+:10D9A000B6A010DFB9B0C808DFDA02D98E745CEB1C
+:10D9B000156501F21B4AF5FB118CDE37186732D969
+:10D9C000F3A17C7BBA883E5AB65D1088DFEBBD259B
+:10D9D000FEE1F0BD5E4E16C2FD002FBBB8DD7B77C9
+:10D9E0004EE9CB2E4803DE07FDC3158E4B6912E3CB
+:10D9F000572CE02796851660CC4D5BFD934771BD93
+:10DA0000EBC7D9E8FE6CF60A7F19CE37F6128B8287
+:10DA100078DDD19B349AD6576751909F3709816B37
+:10DA200091EFB7DE7D4845BFBAFD6327C60E336769
+:10DA3000D7DFAA317ECC59688938C76222CA717D86
+:10DA40005CE75B21A2A72EC1F79758F2FF1434E5DB
+:10DA500027533CF32484E78629EFE6CF8B4217D087
+:10DA6000DE993A1EED653134692CCA29AEC7982477
+:10DA7000A787E3775376C63BE867DA560CF3C7F11E
+:10DA8000AABA6FA779798FDC8F7695F3D8C9AFA33F
+:10DA9000CFF34DD223B1C71C21712CA64B66907DCC
+:10DAA000165E0FE4FEC61CEFC72EA09BDD355CEEB4
+:10DAB000B7DCC5E83D0AFCC90F836F4B014869FE1E
+:10DAC000048D42F50A64F2A3AF13956008E139D6DC
+:10DAD00046F494C67C24D722D7EB38D67837C61DB7
+:10DAE000393CC679F66AFC8D3F522A9D57A025CA5B
+:10DAF0002CE973ED28FFF68C57D271BFFD6042749C
+:10DB00003DFF5E3A6FBF5B886E9F9F4BB7737D0989
+:10DB1000B232348950C528AE0FF2622A9DDB909351
+:10DB2000DB2A72B9C0AE63A4F7E2C675D93D61E3E2
+:10DB3000ED49EF9B27C61FC46BED98DC13AA81F556
+:10DB4000B701D5E27DEEB86C0E47A7DA0747AC2FD8
+:10DB50006BEB023EA81955884094A93E2BB5D0B96D
+:10DB6000084843F51BB10F0EB15AFD2D459280EFC9
+:10DB7000900C036008503F61BAC5708E22D71D51CA
+:10DB8000B1FC7E1353128BFAC67F6C1C0BAC81F177
+:10DB9000E3BD4678C7AE786125DAE591748033B885
+:10DBA000D02F868ACF35B64BBDBD1F1F103C699E56
+:10DBB000009A96B7D80E0B00A5A55DD2E36349FE87
+:10DBC0004E3475AAE80FC580A47D30FF4B9F7ECBF5
+:10DBD000BB0BF22D3ECE67B1F92FAC44BA4CC8E076
+:10DBE000787A077DCB00E74799FC778CDB51AB4413
+:10DBF00005F1B12D348CF47823934A114F8D95475C
+:10DC00004494EBCD7B99471090FEFFCB1A3EBFDBCF
+:10DC1000D2F9390D9314927F929BDF1B6D2E101D4C
+:10DC2000285F0FDEFD02E9BDC70E880CF9BFE4775F
+:10DC3000C71EC1F7815ADEB152BEE5F54A921B3FBD
+:10DC400087766A14FFF9507A39B27EDE921D029E01
+:10DC50004FE42C08BE3E12E5B35FF25C83F858D067
+:10DC600049EF872885FC9CCD392344EF8728A8D528
+:10DC7000C02655FC5ADAC2CBD9AD89B48F1A63EDF0
+:10DC80006AB80EE6F7E8D312437D69B206D3E743DC
+:10DC9000BFA6179DA809FAED8F1E9D114A47391E90
+:10DCA000534961D0FDE677229DCB59F70CE5F72368
+:10DCB000A1DF84A91C96767FDA0194976833E3BDCF
+:10DCC0000A87CAF5DC0629E0C538EF0D2B7C161C47
+:10DCD0009F69FB97C625E54F229C4F6A7A8F552E88
+:10DCE000A0774CDC1ABF38AA5871B47D56AB2B868E
+:10DCF000C7B73C201E40FE707B19E90FB92A181ADD
+:10DD0000A5E9659CB8BCFAF946D42FCE0A91D6B1E4
+:10DD100041EAACC1772536AC60728DD2BFBFEFDA75
+:10DD2000BE2ADD4AF36F451CA7F4AD835C7220DF89
+:10DD3000DC0BA2AFE3611C7762DF3A62F475E47733
+:10DD4000515E9FC7766FF0A2E6B1595BC7A6749982
+:10DD5000524701681A677F79BFC6F101BD2B1300D6
+:10DD60005BDD44F7D182D7615E794E64FCBE96914B
+:10DD7000BFFBE535BA8AFCAEB0B0717291EE389E49
+:10DD800081EE34FB09F8CE86224054BE213F869FA7
+:10DD9000D61F498FFF74B9183E6FE83FB68109144A
+:10DDA0001757C19492F4FE72916972D1C6D410CA09
+:10DDB000BFFF69B9087290E4620BAC3409762AB1EE
+:10DDC0001D4D77A31ED7E5E144C4C914645FDB0D84
+:10DDD000254EDA1751FEB247FED082F191EB44EDA9
+:10DDE000BC4B830BBAA1102E5FBB14833E7D187F02
+:10DDF0008175ECE948BCBE00C6DB5C366C1CEE2FBE
+:10DE0000ECFE17C93E7017F0F81577153F3F77E421
+:10DE1000CD7B32FC5E5C653AB7D32B75FAABF2BBB7
+:10DE2000709C0DD82FCAE73C0BE9CB475990EB43C8
+:10DE3000CD3EDDE6D2FC241A5D45F249A47C9AF081
+:10DE400087E41294EFE98255C6FD1CEAE783A946F0
+:10DE50007D8DF4A2EBEBD6CE3509E80FCBD5FCFDDA
+:10DE6000B936639CC365195C9E99D3F93CD68995F4
+:10DE7000B4DF544B44DAC7E9F477418F47C031121D
+:10DE80007E48A86B27517C0CE5E38A7B18F2EF36BD
+:10DE900020597CE32D2E5DD1E2A6658273DBCFC4D1
+:10DEA000F1282FF77494DBD1BF2EB86DD7E2FE7046
+:10DEB000A3C04228373716BF4971254D55D0332CA2
+:10DEC000CA992FCEB68CED8F67E063DAAF3A546B08
+:10DED00027FAB582A11D14B7D01438348B713B9644
+:10DEE000615C4A53FE9A8C4528DFF34B0B11BF6DE2
+:10DEF000F5168A9B91F359543FC2E7B88F213AF93E
+:10DF0000767ACCA1EF2F2BA2EF2B4B33F8FE3628DD
+:10DF100081A882F964E58B1EE4FFAC3A4BD4795CAE
+:10DF2000A9E1293383DF0F6BAB3F944EEF668995F0
+:10DF3000013618BE60FA6B52C3F03179007CB874B8
+:10DF40007C483A3E1266131F76758A5CDE925EDB71
+:10DF5000C0E4DB503FAA9516B2631BCD7C5FBEA325
+:10DF600040E30BD9D686C4F66DE93A6E8948F7705E
+:10DF7000B28B44DA273A2A9EA7B8A64759CFEB2896
+:10DF8000EFD4027E7F3EB2FD1D19DC7F159414C1D3
+:10DF900043FB698E47C02BCD67EB88D4B6703E6DCE
+:10DFA000D5ECE8561787E3D6FA87894F2F769EBAC5
+:10DFB000DCAED5ECE8855E9F05D5812A944E4B47B3
+:10DFC000FDF9047F878A999C64977F8A4DC2FCB2D1
+:10DFD000ABB27C951961E743B2B752C47A57E3BB41
+:10DFE00042D0FE9320BF0FFA49F0D7C5F40E978FA9
+:10DFF00011332F649D023139C8D09D907749412A51
+:10E00000772D80B924D0ED48CADB6CA0176142A7F8
+:10E01000ABF9FD8B6E7C5F92DE9FE4EF4B7EAEBD75
+:10E020002739A6755DC9A3389E22F950667C86EF14
+:10E030004BE2FDE7A277292EFA14C8DAA6048C87F2
+:10E04000E1F7B7E5FB982C4EC6FCFA128C7BBEE7D5
+:10E0500055AB764FB2730DDE7B795C8475439B665E
+:10E0600009F4FD702C6A102AC3E878F7159D7178C1
+:10E07000CE773A78CBA0FE63BC3F48F3CDE078DAA8
+:10E08000E4584AF7CBE639436E6C7F60CF534F6E4E
+:10E0900081F13EDF67A3F74C363B96BAB1FCF347FC
+:10E0A000DE76A3BE38BDEF6D4BB4F3C92552701AAE
+:10E0B000DE23AB50E3D91A987F7170B685E24F76B4
+:10E0C0001DA0FB694B649F05FBAF68DD43F9AB7690
+:10E0D000FDD98DE5EF67703D713ADDE746BF445EDF
+:10E0E000AB352482FED93DCCBF28EA397B86A8CD4A
+:10E0F000FB55EA7FB3E3D5438897D38F58C9EF76B2
+:10E10000E091DF51BFA7F6BD48F3FD7CF7DB77A0B8
+:10E110003D5DC19807E5F969BBE6D7B375C685EFE4
+:10E120006F5FD5E0A1E74FC76AFBE0AC21EA69E782
+:10E1300031CC09F0A7FB039D7178BFF073B3CF8298
+:10E14000F0588CF080B418E080727F7150A0792E66
+:10E150006E6DA3FB568BF772FFE0628017C1A5F5C9
+:10E1600000CDFF5806971BA7F6FDC54DEF52ECB545
+:10E17000D2FE595FF762A7CF8DF0D1D70B70E0EBDD
+:10E18000DE7D71789AA7E3A9F5CF34AF8ABD7C5EB6
+:10E1900015BBF83CE6ED053C39114FB309FFA7F676
+:10E1A0003105EFC174EF79FB33B4674EEFB32968E3
+:10E1B00057E8F3CA02711B371EF988EB63B6572084
+:10E1C0007DCCA44E3ACF5922CB32BE4F70A13C60D9
+:10E1D000097079DA599209E5CF3C24D2FB964C0EAE
+:10E1E0005E8AFED53319FAF946A71BFD62BBAFF074
+:10E1F000137D9E8CD5E02D75BA317E6673A6EF4CEB
+:10E2000038BF9FFEF0C54B71DD2B4D95BFCBC6715E
+:10E210009EE2F1A1E78755FEF5019AF770C3796395
+:10E22000640A708BC3F3EF7C91F9E85EF2DED7628B
+:10E23000C2CFA14D99DCEFB6D9F101DD473C8DEF9E
+:10E240003CD27C8214A735D25BEEC673BE93CCE978
+:10E25000C373D9CF9F788DE26DBAD375FF5327D59D
+:10E260003BB5F7B5444CCBB5787816B885E418C003
+:10E27000B1C1363E9A7CD4EE1705F8BDB133020821
+:10E280004CD4138FE970AEB4CC349CEB70399AB592
+:10E2900035B783FC2D81E8F7CD22E56FDE4393E9A6
+:10E2A0005CF91C8B7EAECCB438B995A6188ABFD960
+:10E2B000ECF805DDBFAD52AD32DE5F39AEC9C58FBA
+:10E2C000B4F716CEC7C4A922D0CD4B99BEE199139D
+:10E2D000FBDFC32D6F5EE246F896E3B9076D6A7601
+:10E2E000DC807189140F3A85B46D88E067D6CB5B0A
+:10E2F000797902CF4FC9DCB31EDFC344F8723BF516
+:10E30000495E9ECBCB7FA295CFCF281D9F49FA8532
+:10E31000D13B4560912574DBB80A8F068F3EB84823
+:10E32000AC5BB7ABA1F2C24CC6E336324AA7E27A85
+:10E33000A058E07CFFFDFA03BCABB6C4FF867E6C40
+:10E34000FF5DFD04492F893E7CE30ABE79B8FE7B60
+:10E35000BC84C94D09DFBFFFEFDA7EA5C92B9E44FF
+:10E360003A8C1789EE75BEEE7E64D438DCFF5B1AFA
+:10E37000EE0EA1DAEC8E2DB1A4C3F7730A3F3FB9BC
+:10E38000EBA14D86F755F534F21D5BFD1CCF32DC59
+:10E39000783EDB92C9E5514B669FFF0DCFE546E223
+:10E3A0002F0ACFB7A452280CB7D359A588F187F903
+:10E3B0001D367AC7F712068202E63F9A8544D4DFFB
+:10E3C000635817E57F802080FC38A698303F81F5A0
+:10E3D000B8A5E178FE1C5A8B76DAB1645F13D2D906
+:10E3E000978F747E2040F9CF337CBFE982EFEB3307
+:10E3F000F93EC8096621D2B38C29D0A1E898E18AF8
+:10E4000026F72FC053964E859FB7DD2C791F223AF1
+:10E41000665972B7A30FCEBA3C58A4BDBBA4B7FFD0
+:10E42000ECE9A786D17B437DEF850F7A1F785ED517
+:10E43000C2879E983048B9266777D7046E0BD7F706
+:10E44000ED1A9C9FC9D4F5805FD70764C7FDEA66C3
+:10E450006E3FEDBEC2BBE67194B7AD26DA4F9F6C3E
+:10E46000FD0BBDFB78AE94915D37D0B82723F07ECD
+:10E4700072E75319FCBC2360D0EF0B9F7CE9D2F00C
+:10E48000784B00B3923C89BFC341783FE451AD263D
+:10E49000A4D252F2C75858258F53C1F90EC777B886
+:10E4A00082943A5927A571AC875299C9E49F4E646A
+:10E4B0001E4A935929A5A9AC52E0F69D9FD20C168D
+:10E4C000A4340BED53F4F7B01E4A15BCF11916BF76
+:10E4D000310C4F4C87E37BBCA5FC7B447C9084785B
+:10E4E0009C10459E47C40549ED5524CF312E684404
+:10E4F00072FFF71474F9BD39B3E43D94A72F657A20
+:10E500008F617AF8D9DFF3FB15EB05B2AF4FD8670F
+:10E51000581440DD33895E7A07441559E94ED0EF2F
+:10E520007375FF3FFEE871C208CC16F3A9F0F81D21
+:10E530006673E6E379F11CADEA1CED1C648EE60718
+:10E54000C1F7CDF83D3D0FDDB79FA39D3FCC89F0CE
+:10E55000BF30BFD5E04751F11758C71CBF40E70691
+:10E56000736266BCDAC506A693B0FEE8DE5F798406
+:10E570001F6A487F56447E6E647B9BC06CA9F89DE1
+:10E58000D3D3333F54C8AED3FD5940700AB56BB0F6
+:10E590007E487E21FFD5DE70382565F17DABDD7FBD
+:10E5A0004D5CB47797F4742ED867E6C4FEED6147EE
+:10E5B00098807CAFCB619DCE7371638B7C946F0927
+:10E5C0000C1697AABF77DDF4809FE1BCEDA155F44E
+:10E5D0004EF5BDD92AF96A6D0501BA1F10931F7057
+:10E5E000A951E6D784EF3A037F35C51ACF4D966718
+:10E5F00071FE5F9EC5CFB50F5D925A82E7D9EB14CD
+:10E6000091EE0DAF53F8DF2D589735D43BE536C367
+:10E610003DF9B549DBE81D20FB57DB19DA93762974
+:10E62000FABD94DBB4F13769F537276D233F49C351
+:10E63000087EBE1F59FFC08887E9DDC7C65CD8EFDA
+:10E6400062FA804AFDD78F78B80CDBDB428D86FBFF
+:10E65000BCB3B3F8BEDAB697D3A329CF121886F4A9
+:10E6600020F929BE40AFD738C079D28D595C2E36FB
+:10E670009903744FA649B3879667C56D407B675D64
+:10E68000D68EA3C8AFE7F2189D37DA434FD339824D
+:10E690002DDFC2EC82F6770230BEA32048F8416736
+:10E6A00053C840B7317DEF6C98FAF75FF78DDF857F
+:10E6B000EB6BCCF5D3F843ADF74A8D4E1B35FDDA45
+:10E6C00068379EA35568F0BE5E5B97ED1546F26411
+:10E6D00010B890BD77E3D61137A27FCAB67F48380D
+:10E6E0001AEAE7B2B2F868FC1229FF9D0562C43B42
+:10E6F0004A02CDEBDC5E417B6F91BF63D1670704BB
+:10E700002DD8EFBF6D2D3F782DCC6791CFE9C5F89F
+:10E71000C9A7B6EEA07BFA8B5F34537CC2C8AED9D2
+:10E720005C0EB6F27712F5F78D2E69B51ADE9B5A9C
+:10E73000C2C2DE5184F1161F3B798CD13D63E37771
+:10E74000FDDD8066FC10254E2DF2DD8187B222DFD3
+:10E7500023D3DE1D2888EEA7897C7760575024BD1F
+:10E76000B11CE358691FB0AD04F73D55C704F21B57
+:10E77000F4E743E5B13C73585EF0103DAAB131DED9
+:10E780009D51F8E9BD6C4E2FBBF1508DECFEEA0DAA
+:10E79000A12C4CEB189E37D5AE90643CD7AE0DC47F
+:10E7A000D0FD925A590C60DC48766C890DFD8F2C97
+:10E7B0004194F11EDA34D354BAF764B9579A40EF52
+:10E7C000B3EE58D489F7EA6A5D12433ECE4EE0714B
+:10E7D000042C5DA4F769EAE43713E6E03ECEC9EF06
+:10E7E000E9E5C82CA00868D779199E2FC366A53221
+:10E7F00004A657B6E00DE17B576CB255DEC9DF9930
+:10E80000B971DC24F203D3CF81B669A1DFE2385EAF
+:10E810005B29E2FFAA7B93C91E0CB84C0CE3003FB6
+:10E82000CDE2E78296D892D0FB38BF590EF2ED06C2
+:10E83000543111F1F07ADBDA99D7C0777340A278BE
+:10E8400087FCAF6B6FBB06DAF7B459E8BE850E27BD
+:10E85000A54E32BCDFE05E6DCC5B22DEAB9058583B
+:10E8600039E4DFC179905D55C642E171BCC95E7E75
+:10E87000E82E3B894EBA813FE9FC43CBBF8779A0A4
+:10E88000D776B39FF0DEFEBE40FED5836DF37248AF
+:10E890005E3A966EC7BF635275949F630E249F9F26
+:10E8A000CE52F47712ECDA3B1576F47B45D2535D09
+:10E8B00035F3609CA12DD011331AF17BD8ECC1B097
+:10E8C000E67A4D3E4A4E2EC775BA894CEB23E8AF27
+:10E8D000DEECC9F743FDFAAF4DDABEF1F48D485FC7
+:10E8E00092ACD0BEDA9CC53C680E9B933B336498D7
+:10E8F000C7E8172D1EFC7B07D39E2B8847393FFAAC
+:10E90000B55924DF104E882FA9CAE2413BD95A9548
+:10E91000EC9126603D27D1E559A785EC21A9CAE1F4
+:10E9200027FBAB6D924B09937B6BAB658F64C6BFC6
+:10E930008F63A374ED00F23E27412C45BFAB45B376
+:10E9400097D3B475A5653B284DCDE6F273BBA4CE35
+:10E95000A4F77B816E30EEE6C06A4EDFCBD36DA4A8
+:10E960003797BF3E3C6D30FFE093D52E4F1E0076AB
+:10E97000DBEA72F2DB16AFFAA811E96E79AC4D460C
+:10E980003A34C58DDC3C15E9FEF766BAE7591B3B06
+:10E99000499913D69F29AEC885F030896A06D2738B
+:10E9A000C163C11BA5C94827EA16BCCF5F98DD7AB1
+:10E9B000A304F2A53D56CDC0F3B2A9D95B793E457B
+:10E9C000DD22209F6407783E5BCD10213F23FB09A9
+:10E9D0009E1FA16EC1FCADD9ED3C3F86EBA3DBB31E
+:10E9E00077DD88FAA8D6EC2943FFF4B330FF821113
+:10E9F000F87783787A870617BDFC79FC6EC6BF333B
+:10EA0000C4D3C8F217B476FB0728FF8D56FECA00A0
+:10EA1000FDBFAAB50B0DD0FEA0D6AE6380F687B4BD
+:10EA200076870728FFBD56FEC600FDFF516BD7391C
+:10EA300040FB37B5766F0DD0FE88D6EEE800E5EFE7
+:10EA40006AE5C722FAFF40ABDFA57D77C736BC8BEE
+:10EA5000F69A1BE415CA93FCD806F2776DAB2A240C
+:10EA6000FAAF9DC8F5BF4EEF6EED5EC0916C7E6E45
+:10EA700073249BDB01551A9D17AFCADB3815E9F0EB
+:10EA80000FFC9E22E88FA3780F575D25927F6FF9C8
+:10EA9000EBFC5D99E5AB243ADFB8A0F7B4F6FAFCDD
+:10EAA00003DA3CEBB4B4329BBF9791ABBA3C33C2B0
+:10EAB000F4A35936E66DC04F18FF5F97CCF54CFEB6
+:10EAC000AA92063C37A9053D83EBAB775A42E8FF93
+:10EAD000AA97252AAF4B2EF1E379BF2A4BA487EAE8
+:10EAE000931343F84E735D5DA1E1BDCF3A59A2F790
+:10EAF00063A484AB6C739C283766C8283FEB989C52
+:10EB0000584CE76AB04F437D525522A3DCC94D48AB
+:10EB10004E44B93C3787AFAB23B6DB8EF728A4074A
+:10EB2000447A2B60A42C11BFE7D5890105E6D121D9
+:10EB30002F27FFEBCE16ED4C91F1F3445DCEB7FFDE
+:10EB4000621AE9B15AD0630AE931163F2EB5EFFED9
+:10EB5000A6746CB405F5969C61626690CBBFCB4EF3
+:10EB6000A471773EC4F5D608D05BF8CEDAF642C67B
+:10EB7000DF7973D9C8AF5B2E315752981FF377D91D
+:10EB8000DC8E67A6191EDC678FC0F710C3E03BDC84
+:10EB90006FD45BB943E8AD9C2A909761F5AD2ED94F
+:10EBA000900F666BEF2A799807ED9B69CF6D257DF5
+:10EBB0007216F50943FDF2C798D1A85F408F5859E6
+:10EBC0007F39A8CB63DD6ED1E574ADA6376A23F437
+:10EBD000C6D072F7EFAF8F22FA140DEFD00C247F5E
+:10EBE000AB304E00E8DFEC1348AF30C947F7FB8786
+:10EBF000829BD95C2ACBCEA1E1674EF92201E5B414
+:10EC0000D927793E8A724F6A28F8EAF52CB6CCC724
+:10EC100050AF7D716C653EFABDD69A3B67EF42BA44
+:10EC200015E2E97E87A2F91DB655EF672746603CDD
+:10EC3000FC7B5BEB26E0FD71AF4CFE92F41205DB32
+:10EC4000D9619F9E44761CDF6F32D9E75F84F6FC62
+:10EC50008B1605CF050E3FABBDDF90ED2478DEB3FC
+:10EC60006705B5330B952E7EDECF08DEEB3212F949
+:10EC7000DF0969B76976E3998DDE3CE857EC1250FD
+:10EC8000FFFC474EDB461BEA0F6D3FC058DB4DB81B
+:10EC9000FF09062C5A7DBCE8CED81E51D0FDCF5EB0
+:10ECA000C9156E875A6EBA2A0BCF43E5D112F49775
+:10ECB000B1CDBED17C05968B7A7B2F5E1E42F1A52D
+:10ECC000E725C0C3331D5AB99AB6F12A98CF1E8BD7
+:10ECD0003E3E18D445389EA8D193BC11FBDF5DA2FF
+:10ECE000B7EFD9E89D4AF3B9DE047BB07C77E646FE
+:10ECF000677ADF7C87E7E46EAC81B59F56BAE27035
+:10ED00001BB7A4EDA354D4DBEBCAF8FD616400F497
+:10ED10008FE8F7882FE06DEFCD2ABA62FFF3D03F7E
+:10ED2000E20AA06899A9EB9003E0B6647FA5CD2C18
+:10ED3000E2FB5DA52ABEDFA5B75BB27736D939CB3A
+:10ED40005E194769947687F1FECC776867B35CC437
+:10ED500078A7436F2EDDA5E0BD99CA06A789EA33DF
+:10ED6000EEFF8ABE3EBDFDE95D6FFE04C73BA374A6
+:10ED7000A55E07B5D785002E51DAE9F5F5FBD55329
+:10ED80005CDECBDCC07FFF70733E6452A507EB07EF
+:10ED90006D7EBAC76637FB4B519F002A0318A7A0A8
+:10EDA000A753DC79FC5DEC88EF91FC15B4B1A41994
+:10EDB000282F574874EE1EB4A98EB1906F817D4AFA
+:10EDC0000D4C69CDB823E3315EA0659F93E47AEDE5
+:10EDD0008A0E5701F295C7C2D0EE6DB9A2331DDF7E
+:10EDE000BFAFBBD752F604D26F68B9EBAE303B6C05
+:10EDF000780E8FABCF4EF097213FDA811F511F372E
+:10EE00009A7D367C37454D1729AEDA0EE56F50797D
+:10EE1000B656EE997E0DEDCB4419E7559F37777ABC
+:10EE200009EA355722FFFB8423AE2A9B0FE501D95F
+:10EE3000222379DD9D53EE43383D23792A91FF9EAD
+:10EE4000713A658CC7025949FA401A914CF15956EA
+:10EE5000EDBE53F638AEE7F57936B9B9FDD0E4B674
+:10EE6000101E5A623B6F2E867631F789B20AFD3743
+:10EE7000DEFB7029C6273E76EF913F637C6B53AA79
+:10EE800044EF0CECAE0979B15E8FC03A77801DB9C2
+:10EE9000BE6A6627EE47D73345417B7DB730D38FB7
+:10EEA000FAB92745623BA07E4C9E315ED559608CF5
+:10EEB00097CAAA30E637E6F8EEC7754DF8436131D8
+:10EEC0008E9322280A3E1D5CD8C9283E3F352F4F1D
+:10EED000C6B8EEB8C28838D8A9C67E12AF32962717
+:10EEE000CF8888DBBAD558EEBADD98CF986BCC7F47
+:10EEF000AED3A38B9F3FE87FE7E1B17B9F64A8A7D8
+:10EF00001BBF8AA778568423DAED3123250F9E8B09
+:10EF1000645B3A67611C1CBB3486ECA583EE18A6C3
+:10EF200040DEBA94913CB526060FE07ED52ACAA5EC
+:10EF30002A69A8E081F7A1DC01FB5594BF91F0CBD1
+:10EF4000CEE6FE416725FF7B7141294476847D55DD
+:10EF5000BC5CE3C1AD63841FB6222CCFE3BD1F7739
+:10EF6000F3F338BA774F477284575819E26D320B72
+:10EF7000E03B94D9F77EA486601EEB95BC4AB4337F
+:10EF8000D6895D348E5AEEF4E1BE3B05E3BC4D18E4
+:10EF9000EFAD521A898FE7DDDC4E52D85C3FE2D1EB
+:10EFA000355BA4F891FA43317578F852AFBDD7A01C
+:10EFB000C7B1E974F9B29BFBE7F67488A217FDE0CC
+:10EFC000B7E7ED407CEBF9565F721BC5F58FABECF4
+:10EFD00042BA6437703B14F400DDCBD6E3C4F4B816
+:10EFE000C2EE1C1EBF763A47BC80BF901E47141667
+:10EFF000074E4777263CBAF0CB78DE933DAE5446B9
+:10F0000039F34BFDFE05E3FDE2F385746E3043F406
+:10F010005EA2F9D3D1AE4BD2C64B4A96BCF4BE3BEE
+:10F02000CC4984FA0F315E3F296FEF4ABC77B507B0
+:10F030000907F9E72E0EE748BA4DEFF0978E4178B1
+:10F0400009A00FB3FAD3B1E06EA5F3C0FAFB58A242
+:10F05000755C7FBA9E68E2F64FCF4285E22C87A2AC
+:10F06000F393EE04EEC74ED922A37D9B91F7500D8A
+:10F07000DD83B98FC9A8EF323A3A6F46BF57243FB4
+:10F08000041C71E3799CDCB7F3C39B4C9C3F589AFA
+:10F0900044788B8C2F8D8C271D9E93A0F929400FCF
+:10F0A000C4E27D00F94A8C13EC59C5E89D809217A3
+:10F0B0005B6EFB77E8EFCB111619E575CE5BBEA74B
+:10F0C0001C30AF2F5FF2E5A09CDE2675D913C2FC81
+:10F0D0009E92C8EF9F45CAEBE139A246AFA0375CCC
+:10F0E000DF3DCD46FA06E20AE6A58E968108876FD7
+:10F0F000DFF4275BCAFFA0DDA2DAFCF8F746DD1DCE
+:10F100007A3E8BECB09CB778BE685BD6465542B869
+:10F110005590BFE860F63CF21749EF727FD1189323
+:10F12000378079F69E9DE2EEDAF7DDBE00E3D5EAA0
+:10F1300053AF53503F176AFB9FF139425478491639
+:10F14000AF0FF926F27B81065FC64A3F9D0DF81B83
+:10F15000F3B885E2EEF2C5F2865CE4874613E1B3CC
+:10F16000DCA42C6D0EDBA735A71697E44CA47D011B
+:10F17000F3C18641E915980FDF614A3E5E8CF49A2F
+:10F18000036C86F22547E506644E550CF385D1A93C
+:10F19000D22B51FDE6546F498E26F7F0DCC7ACB197
+:10F1A000F43389A56C36EA65F8867AD7BC2B869F3E
+:10F1B000F7241BEF479A4C3C5EE4266DDD663CD796
+:10F1C000198FEFBD8921EBD8FEF56FD5EA49366777
+:10F1D000C8148F7EB2378ED2BDCB887360DCDF520D
+:10F1E0005C4E05233F28C285F2F7C8FCDDEE2A1EDF
+:10F1F0000F50BB9A09781650ABDD5351EFE07F8F6B
+:10F200009879BD0ABEAF425B4C05FF0B11FFBA6C8B
+:10F210002C11EBA7B34E8A63641D4CE1F112C67347
+:10F22000A76D03BC03A5FB01A42A13ED5346BF66DB
+:10F23000E77F17AA8AD13BE1F46613EE7F57B380CC
+:10F2400024F4F9E18E642BD44E3F8FDDFDF50719D0
+:10F250002897F3C51DBE37C86E889577A07E8C3180
+:10F26000F2A17E7FAD56A3936DD532E15B2F77ABD4
+:10F27000C729DE3E87F5D4E03E2BA72AD180E70BD5
+:10F280007ED9DE4CE69B10DE6F80BFAB9B27D13B67
+:10F290005D4AAF9BCAB7552B43F43F6C80FED389C0
+:10F2A0009E06EE3F8BCAB787BE48B81140B1ADE7A6
+:10F2B000A38452A5CF6E8D84B37BB5517EFF607F52
+:10F2C000643C39878BDDEC4DBE19E0667F40F4B4B9
+:10F2D00031FC7B3CC67AD373CF25F0F372BD7E2818
+:10F2E000F916AC0FFBDE3605FFBE8FB17E69F1C7A4
+:10F2F00009FCDC5DAFCFE7F7A35E63BD48FC44CEFD
+:10F3000017E695F2E3B0795D69B31ACACB66F79B4D
+:10F3100057CA4FC3E6758DCB58DF57137D5ED7E7CD
+:10F320005B079D975EEFA6A28BAB17B98E5BA65BC2
+:10F3300007803BAFFFD3B28BEBF75F160C5EEFCECF
+:10F34000AAC871542E272CDE2328E7CA99B216DFEB
+:10F350000967CE98A871C1259A1D7316FD14180F60
+:10F3600097E97D1FE55A4F368F4B39FCEC223F9EC3
+:10F37000C32CDF6751F0BC235BF35B83E0598CFC4B
+:10F38000BBC72627603CA0CDAD68FBABCE5C8CE74D
+:10F39000DBD37EE436927BCC68CFC07EAD18F535EA
+:10F3A0008830BA97F126B64B098FA3F092FD572FFC
+:10F3B0007AFE42FBAA9FF07D951EBF1F6E67B14982
+:10F3C0007D76961EBFBD491BE7BF7286D17CC0CE3D
+:10F3D000A7BF7B9B9A27517CF32F6D9D9BF0FED19D
+:10F3E0002F939313703F73589BB76E37EAF71AD277
+:10F3F00066E78D334581D7FF0791B1925A008000AF
+:10F40000000000001F8B080000000000000BDD7DE5
+:10F410000B7C54D599F8B973EFBC9299C99D64F2ED
+:10F42000E211EEE4C5044298608801AD4C12A0A838
+:10F430002C3BC147412D0E893C227921A8A1B2F570
+:10F44000864484F8206840A0A043148A56ED6011D9
+:10F4500001C11DA2A6764B6DECF661A94B47602950
+:10F4600002C2A8BB487F7F2D7BBEEFDC9B99B99978
+:10F470005150B6DDDF9FFEECCDB9E79ED777BEF7E2
+:10F48000F79D33172FD27F93087928892C0C1413FA
+:10F49000FCC7951162CFCFEFE9741232BCD42B8E2A
+:10F4A000A3EFDFC9D111329E9087E983D07AB9509A
+:10F4B000F06FE3E8DF22212BCBE9F7D030979027DC
+:10F4C000C57EBB40EB9F7408A2CC413B09DBED7CC1
+:10F4D0004BA7F3380879EA8EFC1EDE19296FF03944
+:10F4E000B64279B88EF80216E8445C44E8FB9D26E3
+:10F4F000D1DE594A8B42BFB3C64ACB3B7E7F1B67E6
+:10F500002364C40882FDD5B55693635711B2DB104E
+:10F510007EF322CC673DE7DF46FB79ADBB74AA40A2
+:10F52000DBCF3B4988997E5AB7ECA6278FA71132CB
+:10F53000E1B85809EFEB36DBDD3C7DDFD4DF321577
+:10F54000C6212DC45DE0262493AFE4ADB49FCC4723
+:10F55000DE73B7D329AFEB95F6846839BC9573F7A2
+:10F560004850BFB87431C0C7E2912C74BD7361AA12
+:10F57000F8DE3E550FED6E32B83B683F67F4641617
+:10F58000C0F1A20257F539F70EA982D0F9CF0D2CA0
+:10F590009B8BE38A1464D9B46C12711E26494C6D9E
+:10F5A000A3E5CC2462328F23A47C85D8F7008C5F3E
+:10F5B0006F157B288C6D1562DF8F605D2D3922EF12
+:10F5C00086C1FD0807B5FF791EAF81D07147EF30C6
+:10F5D000D0CED83E5EA4FF8D09C496C7EE892D9784
+:10F5E0000663CB57BD135B7E5562F09E681ABAE581
+:10F5F000388577EF012381F92E3A9DE4375278EF71
+:10F60000D31302EB975F32223E542FB278003F4E65
+:10F610009F4ADA6AA4E5838793F0FBBB7F6266DFCB
+:10F62000EB022F43597E3999C0F78BD202E5A974BA
+:10F63000DEAF7FC9DFE92D66CBD243FF2F176DED1B
+:10F6400084FAAB02E5227DBF7B1421FD502FF84BDD
+:10F65000609DBBFFC663BFE1E78DFE1EDAEFE9BD2B
+:10F660003F7E19E075FAF9A1A91C9DF335BA9EAB4E
+:10F670003AA1BECD2AF5D0F7134FBF98E78BDA97A2
+:10F68000453B8C31EB5C2C71B8CE56C1B3E259D8F6
+:10F690009F437AC4A725F3FC7541DA7E0997E39668
+:10F6A000A11F03C5D36228BB33ED145F27DA18DE30
+:10F6B0002E31D3729C7D579FB51B78E2BB2A523EF8
+:10F6C000BAFAC7381FD7C9F711AFF7E9655D12C09D
+:10F6D0007135E7DE46E7BFCF6C2B2129F0CCF10373
+:10F6E000DEC81225BC745CD78F9A002F7EC5BB7B09
+:10F6F00048E2F15C597FDA3CF9AAAFA8A7E33A4B9C
+:10F700000839F751D29D1E3A8F911B62F7BDC81F71
+:10F710005B5EA5C0A79644BD77C27C725766219DEB
+:10F72000109C8FEBE407B739E97C8718490BC0457B
+:10F730003BEE5A651D2FBC40FB716137FC459EF5C1
+:10F740002765D07D51E8EA758ED111FDB77428A5E3
+:10F75000B7451CE32FEAFB459A79A8FD4F94189F03
+:10F760007218DC6B42B8FF4611F6FFD483D39E3C7F
+:10F77000AE1F3C9F130F7A3C93A3DECFDFB0B82FB0
+:10F780009BB66BD8993E8E8F826FC3F36F66DC4E4B
+:10F79000DF9FD921B8810536CCDEFEF844F8EE793A
+:10F7A0003E00F3857A0F5DEF99C0DB36F86EFE669A
+:10F7B000FB385E8AB45FB0618A67B22B02CFCBA5FB
+:10F7C000D3D72A189F5B14D0FB4D401781DF4D1D06
+:10F7D0000A78BA817317D071CA051F0F74672DF3A9
+:10F7E000E8E509844CFAE25FFB86D0FAE603E3CB56
+:10F7F0003B697DA7CE7BD33F01DD3DCDBBB7015D2E
+:10F80000FFF69E0C5FD4FEBC03FB4BF7A5F3D606B8
+:10F81000EC47A6B85140997AAFABB61ACA138B0918
+:10F8200067A4FCD8769278FC16188FBCAF4B25E401
+:10F83000E4FE874A041DF2A3DB814E4E139B1BE8B6
+:10F840006E9FB5E5DF71BC97F438DEA4600A07FC53
+:10F8500077DF739CBB93003C62E9EFE4C915B64ABD
+:10F8600046D7777A510EE88883F6B7F0D931C807C2
+:10F87000D4F7DAFDABF7C7F6A3C58B8F9475016A91
+:10F8800046E397F6BBB4E9B201E8B1A195CA8B286B
+:10F89000BA6938DE652096C1E3103280BF04F09764
+:10F8A000E2259170BD66E41BF41F67A2787B0AFE17
+:10F8B000CA636542C7BF9BC3A59145A30285C0E744
+:10F8C0003841ACEAC88EF05752E1473E7F86FED9F8
+:10F8D000E906BE103802F40EB2741BC817317876F0
+:10F8E00013D4CB233CC08F860092D227F96932F221
+:10F8F000DF3352683BB67F718C5BA6AFCF01BD583A
+:10F90000B09D2D358A3FB505DEB48568F9F4CEB4D7
+:10F910002ADE0678FB4B1BACF35420ADCA604BCCFF
+:10F9200037B47C93CE0CE1FB21FC49F14E747A9202
+:10F930009D00EF0E2A74419EA5B594B6C4D937B583
+:10F940009DC3D0522A01FFF8BEC5DDC3E0463CB4DA
+:10F95000FCE93B693DB0EFD7E8742817E672AC7F4D
+:10F96000B57D913311BF9666071D117EFD84228FF0
+:10F97000557EFD8495C1E372F9B5F639ADB328051E
+:10F98000E0F7299152403EA59AEA9E013D43AD7FA2
+:10F9900022811E50EA64FCE99D838529214BA4FD48
+:10F9A0009FF3BC6500B7ACAA7E0F4FE79F7503714C
+:10F9B000B7D3651DE3DDF789147FEE2254BEC3B3D0
+:10F9C000CC67003E483AD211BE84B8A7C2FE2F9839
+:10F9D0004EF1A59495411ED77B0DEE4EAA37D40962
+:10F9E0000C3FEA7670FE760AB2BB1E8DDDBFF9DDF4
+:10F9F000C6081EC3FF6D8EAAA7E3D40BFE95206731
+:10FA000087514D29AD82E2EF73B1DF2F22419C5720
+:10FA1000C38B178DF1F0E2BF15BCF8739E6706AC7F
+:10FA20008F9B69C2F92C7989437DC06108A0FE13C0
+:10FA30005E4CE5079D2FF92DC39BFFE4BDB8EEE6B4
+:10FA400065733D77D17D38D75AE7B98B56216B80E6
+:10FA5000FD0E307D6FD1E4401FF24122BE727B1655
+:10FA6000F4E74578501889DB101E028EF7DFBF657A
+:10FA7000F8749BA2375EA39B89EB0AD713B187F278
+:10FA8000B9892F1EC432FDD772FB4478B07EE6B729
+:10FA90001011E0BA80C8064269ED01A713F7AF9EC6
+:10FAA000F41B185DFBDB3368BB26AA6F025F8BA3D8
+:10FAB0003F7C3F1A1F0F6BF0F1F015C3C709884F49
+:10FAC0009F1137E2D36D1A7C3C9C001FDB07F0B11D
+:10FAD0001CF1596D4FF550624E1DFC3DE08B276ABD
+:10FAE0009F176E8E2D93E7A2CAB98017B41C852F7D
+:10FAF0004DBB2E1A3D71F064DD80BCF717D58C89A3
+:10FB0000E6136D38BF230A1EADBB657E36F0E935BE
+:10FB100060700C513AA800F946FFC27D234113EDF5
+:10FB20003FE9AA8132D697AF6065FFD65F7B375C2D
+:10FB30004BC87ABD2F5BA4F0AAE3BD7D3A902FF9A4
+:10FB4000BEE79C6057E83C3902EEABA7D03B0636D7
+:10FB500094E1E353E35A8A5AE2C04F9DFF7A2E1094
+:10FB6000D4019FDECBF4376B59581F2D5FDF703205
+:10FB70003994D21B427C0DBFCA11B02B36726BB3C5
+:10FB800001CF36664B5C3B5D53D9AEB64AC45FCA03
+:10FB9000EB0B28DE35EEFAB06F282D974DEB07F40E
+:10FBA000A3EBF62E7E1BF8E5F824669724B76CD5F8
+:10FBB000D1FE32EF748D6BA7F8F6A653C27192AEE8
+:10FBC000EA3A08FD84174B620FED276B85ECBCA762
+:10FBD00018C66F6943BCAF21F83EFD7BCBDBE0BBB1
+:10FBE000478690541EBE236D1C7CB7329DC3FD58C2
+:10FBF0003997CC7AA518A84844BD7ED82C916B9B28
+:10FC000000E5964AA41749B4FF321BA9AC2385DA54
+:10FC10002DEB6C04F975BA8EBFB3863ED78D63E5C4
+:10FC2000D4E59CA70789772DCE2FD348A671A9ECE0
+:10FC3000BDBF18598E6727D6FB71BF33AB5B4A61D6
+:10FC40001E9979ECE930F874F974FC43EFE9FD2B67
+:10FC5000E83A0F29F8B2746B5566B45C3B74C6245D
+:10FC6000E8A8DE7C284BB5178216B0179696566723
+:10FC700002F3C8CD9F9602FBEAC889AD3FA7F7A45F
+:10FC80005C05F2FB3D9EC0FEFD97C59302F4798DA5
+:10FC900081CD5FBBEF9F29FBD97C8123FE28BA6C05
+:10FCA0009E751EEDB0E60B42CCFB330F9A08A810F0
+:10FCB000037AC5C2DEA9F05D23E95F0978D8184848
+:10FCC00026FE28BAB82629FEB82A3D345FE0891CF2
+:10FCD000775C43ECFB0B69444E8BF75D46EC7BBADB
+:10FCE0008E98F29ECF07D601EF4945C8E6A576F873
+:10FCF00074D05368F99C5F27EBC7029B63FCEBACA5
+:10FD000018B201FFA2FA480BECCB592984FAC63984
+:10FD1000CA9AA01EE4780DECAF10B6CDB446C65119
+:10FD2000EBA17DF43E9E9D652041DC9F30CE03E03B
+:10FD3000278F2464D3FE4F0C12E869FB0F22FC547A
+:10FD40007C8986A31CC56F32DAFB833A4A5725B9F2
+:10FD5000196B8B8BE896F5AA7C216BAD87F2810C31
+:10FD60005E17C32792CB06F806B2A9753A5EE13357
+:10FD7000D96B275F1B5D66DF47DA0FA981FAB26294
+:10FD8000D6BE2277E87B2B40F6922E9C1F5D470E55
+:10FD9000C06FA06CD2942DB43C26AA2C6AEA1D9A9E
+:10FDA000FA2C4D7918FBFE8C359803FE81EADC11A4
+:10FDB0003502A5D333D9C1391C2D3FDAEEAC994CAD
+:10FDC000E9B4B18CE9174DFB39374722F06B723338
+:10FDD000BDDEE20E19EA8A010EFD7DC0571AF670EB
+:10FDE0002247E9C112D819C432B493A2DA05386C9B
+:10FDF000D710F810DB25ECDFA5433AEF741D65DF63
+:10FE000005FE827ACCC31D8BBDC0D8FAF48C6F512D
+:10FE100029E7194A1B36EDA9213E4B84BF9ECDF63A
+:10FE2000BC89FCF50027027D0EE029F46B89D085A2
+:10FE3000FAFD9FC6ECFF1DA849C94B3F6913E8F7BF
+:10FE4000FFD1F897F1A077FF499123EB397F118C0F
+:10FE5000BB89F88A408E7FBFB1E0A08E7E77441FB9
+:10FE6000DA02BCB73DF76A84DF116B683847F59258
+:10FE70008772AB6A040ABF23E9A12D00CFFFC8AD8A
+:10FE800066E5E1A1E13A5A5EDDD3C4CA05A12D5071
+:10FE90007EA567362B8F090DE769FB3CF93684FF99
+:10FEA00036313E5D2FCB65FAAC3ABF87CA3C4B7307
+:10FEB000418F6E60F267CEDD876703BF9DA323226B
+:10FEC000A17C7ADB99632F6DA3F0D8D69A4C7A186F
+:10FED0003A7A056A6F6432D4A772A20BF97AD8C94C
+:10FEE000F41BCAED42E0D74B1E6F923A9D917D51B3
+:10FEF000C7CF1CD5B213FACF9C538C72C4ECF41C40
+:10FF000081F1D5E7F451EC79245764FC9BD779F063
+:10FF1000FB07AC7EF87E8D99AD8BD20FEEB345D941
+:10FF20009735CABAD6E4323D63BA73CA91DCF1A000
+:10FF30009F28F6CEAA40FA283AAF6E8E04C06EA46F
+:10FF40007A8A6C063E5C9F84F64C37CC1DEAD766F5
+:10FF5000FB653ACEED1CF1027F51F949B7DD939D67
+:10FF60001A65377697D2B225E227E8AEF1642739D1
+:10FF7000E099A1031B4AE54FDD4ED64E954F99ED12
+:10FF80006C9CCC35453DB09E6481A0BC9B37ABB02A
+:10FF9000A70DF58399386FE2F16473B4BFE3F5B947
+:10FFA0003A80A3BA5FDBCB3C2FE0BA78E6F750F794
+:10FFB0004D85EF915CE6F7A8E3A97E41F1EEF17C77
+:10FFC0001FF647F58D1214EC8ABE710490767C04FE
+:10FFD000CE44088D87F7FF1FC2AB1FF0E9DBC2AB31
+:10FFE000B195F211DD25F011058EEBB9A03E93F12C
+:10FFF00011F44BC07B9047CF3B7DC773A3E861CE24
+:020000023000CC
+:10000000038DA867AAF34ABEFFB569DF234087A71F
+:1000100090EEE6FC2019FD085A3D50B503557D359C
+:10002000911DF8A9420F6ED5EFADCC23B938F4D2AB
+:1000300063145EA9C42A021F3D62088D71D3F6477E
+:1000400074BE675F83790FE145CA4306F5F7421E28
+:100050008FE39B553C2161DB2847044F56533C31CD
+:1000600041FB1A03DA25DD76FFC6F98027B70C734A
+:10007000CB12CA61A467B93519EBAFD11D25E0C712
+:100080000F4F1045D033295E617DF7EC42BFCCFCA9
+:1000900031B219FDD349FE1EC0BB520A00E86FF60B
+:1000A00028AC077F08FA91669BD87883F18AF92DEE
+:1000B000461256EF54F0B63E17F136A39D303F90EE
+:1000C000E029A989D217BE9FC7F022B92CF4EA1FF4
+:1000D00040FF7CD4EC2E20CC6405FF12E9CAC4FE9C
+:1000E00028BE8CC81BCFE438F47BD7E3D6AD8CEFA9
+:1000F000B9CB01CE0F5BBBC832F40FEA71FE9BCDCA
+:1001000041D4C37526C90E7EF8393C595F08FDB548
+:10011000EB45C0132DBC2BF312F91F42F746FB8BA6
+:10012000E71865630ED43F6846BB40B5FBE6A430D4
+:10013000BA52ED3ED5CFA11D47B5FBEED4D873031F
+:10014000F59D7F2DA8A5FDFD59C13377EF8582B9B7
+:1001500016B66EF03FD5C25F74DCDAE5E60FC1CFAC
+:100160005C2BEB83461BF091299E50949D4636B044
+:1001700075F87EA5F7039C5A05B27E3BEC8FCCD672
+:100180004FEDD8FAE8756D32B075C93FB0C6AC6BAB
+:10019000938DC591BEFDBA3E1A1FBBAE93E3957514
+:1001A0001153066DA7C8B93B5BAD1F7225F409EB6F
+:1001B000A24FB29CAECB1559D7B23CC64FE7287CB4
+:1001C0006C90DCCD637A7C1CBBFDFFC67ABB9EF2D3
+:1001D000C45BAF769D7FCEF3FC202F1DE9262896C9
+:1001E00045F0DAB791AEAB0CF635DDDF86FBCAF031
+:1001F00093109B1BF8D89279745DF06CCB447FE12F
+:100200001CA3B407FCE6E44729CA3A09F281251B7E
+:1002100087235D52BC6574FB14F3BF2C317BD17F07
+:10022000B364B1E8964558FF2B680787297F45BD21
+:10023000A43596AF7F3D1CCC39B5C5D17030E5CC27
+:100240002D8EB3EFB211F139D1BEFF990FDFCBE59F
+:1002500025F69790E5B17E0AF0E70E94F9C165ADF9
+:10026000DF8390BF1963BF9713E051E8FBD1787427
+:1002700044AFE0D13233CA1F158F8E5815BF900698
+:100280008F08D5A2818ED5756BE13807E018C72F8E
+:1002900044F1A900E07844B1CF283E15001C553A3E
+:1002A000B8B395F1032DDCFE9498AF7DBB7568F073
+:1002B000F8DBAE43AD4FB40E55BFDDC02DDE08F800
+:1002C000B9219B88EDA80787C6809DE430F88B6034
+:1002D0005E9B0C947E91AF303FE1678762FDCEDA82
+:1002E000F95CB8647EC1FA4DC42712E1E5E5FAF97C
+:1002F0006A35703BAAC06910BEE733B9A9F5F3357A
+:10030000DBC24F83DED49CC4E4F7D90356A47392B6
+:100310001F9A03F6C2B97D4602F2A0890B15C27777
+:100320006739CF5CFCAE2D590239AEFA738FED669A
+:10033000FE5C99507B9D961B7CCC1FDD2CFF7225AB
+:10034000C0E5629ED002F672F39E587F20DD0F1B3F
+:10035000ECCF591DE987EF9B787F3D98D8EB0D4C8A
+:100360007F59AF23018067C48F70B410ED9A6C91F0
+:1003700080FFAA49F761E13D517E8726A5BE298706
+:10038000F9D3203F01E32E309473305C9A1E3DFD7B
+:1003900025C4579B7669E93B96FE1B2265EE220732
+:1003A000FD45D53B23F48FFE03C08BC9C45FC081DC
+:1003B0001F909593A7F5FB21CFA159F13FA7F78691
+:1003C000A6827E632D0B10E0FBCD2799DD3471FFF3
+:1003D000D637C13F689FD63F1C54A866251EA5B5D9
+:1003E000D726EC5FCB833F4BB5B7A2FC67453363A1
+:1003F000FCA72BB01DF8E360BC10BC82B881C0F430
+:10040000F2F58A5E4EF577E4F3F3BA46A2FE0EFAF1
+:1004100035E849AA3F0FF426D09F77E757CDC8A704
+:10042000EB9C5D50757DFE78361EFA29C04934215B
+:1004300031DEAAF051BF03BFDE57C78514FD8FB070
+:1004400078D03DBF48FF4ABA5C949F307E7F7BB432
+:10045000FF7D9FC6FFBEEFCAC5833281AEEEE1A429
+:100460004CA0AB891AF9B62F811DB0247F201E94B1
+:100470000974ADB63FC1FB30FEA1C61DEA21CE8294
+:100480007226887189BB5B88BB13F3407C2BA1DC8F
+:10049000B890889D14DF1B26FB58FCA38588374E37
+:1004A000607156298ADE208E195D263B6839460E1A
+:1004B000F6631CA489F6B0C90D7E9AD8EF9B89BF5C
+:1004C0005A003CDE73D118D34F37DBD73B15FCDE27
+:1004D0006866F18389CBB7F224CA8F9332CEE37C6E
+:1004E00008E8F7177AF45FFFA7828F2A3CFE9C5733
+:1004F0007513E05512F8D5E0BB878CA8C71CD791BF
+:100500008580DF6BECE4CE99F479F641E2C9D7033C
+:100510001E8B39D1FE44F5D9B9CFBC10E8E219855C
+:10052000EFA9EF2BA051BA120F40FD3F19F3472856
+:10053000FB2F01BA29CF55ED0E520271880F157E9F
+:10054000DA74ABC507FD85748CAFBF98CFE4C08B60
+:10055000F906DC3FB53CE08F53E8828E83FD255DD4
+:100560004562E2D73F53F055F58713254EB7BE3E9F
+:1005700089D92903F4A943FE9B5CEC35F890FF551B
+:1005800021FF0D7F6491002ED34E37D4C33A3E9D98
+:10059000954420DFE62E254EFA6EBE1DFB55E38BFB
+:1005A000FF40BA8889935E2A5DFC3E421731715242
+:1005B0000AD764900BFB74CCAEDD47110BFD8201B2
+:1005C00025EE2E100FC8AD7DBB46A21D3357F15747
+:1005D00053BE81F66B98CA37B6DFBE8DF3E0BB40E1
+:1005E00001E6237CA8F73FBF1DF49903CC4E53F7D7
+:1005F00063DFBEA17EE03B134F7F9103F0DF77F214
+:1006000085A190E7B14F89AB37188285E84F31302B
+:10061000F9DE600B1602FC5E57F0A6218996E9FB15
+:10062000BC745F18F05ACD8B8176765C8F64037F43
+:10063000CE31C54E3F4AED769817A5967E88F7D302
+:10064000FDCE8672787526D3A7E9BC002F8E1D18C3
+:1006500083EB5BAF67782CEFE5D0FF73541F3ED17F
+:100660004ABF3F9A7D156913413E5FD8DE07FD3FC3
+:10067000CD13A30879479F9FDF43BF3F378417C13E
+:100680002F59A7F34ECD067EB19BF943B4FB00F280
+:100690003A3AAE7B968473D06FBA303700F87376EF
+:1006A0007F11E6D3118748645A6EDECBEC476D7E2E
+:1006B000C4717D2CFE6BFB857581FFB219FE067D32
+:1006C00024BA7D9CFEBEAE7C561F2A5C46E13145B5
+:1006D000F24905517E80E637B2518E1C7BEC73DC0B
+:1006E0004FD2C5E2E8C7F59E39303FFBE4A0A13602
+:1006F0000A1FAF2E50FC5046A65F50FE6B88E637AF
+:100700006A7D7915899B9F525EC0E8DCDACFE4F4FC
+:10071000E07A86E7F7926779E0175743320FED6F7B
+:10072000849267732FF9ECA011F4A94029E6F18CAB
+:10073000581E443E40E78BF8797C630AF247F22862
+:10074000C3D7F93F3222FF984FE507F367B0BC42A9
+:10075000F228CB1F3AF19013F1B97C45B01CE9C1E6
+:100760004EDCA047BDD6F1A1CCD3FAB93BB852C8F4
+:100770009B9CDBE1443BF0EE5D4EDCDF890A5FAF22
+:10078000337A304F923CC3E29C773D518FE334265D
+:10079000133B8FFAB5DF007AC4C21D1CC6C32706FF
+:1007A00018FF6F108207414FD7E6FD107F6CBE0126
+:1007B000C82312A5C783FC211ABB2B76DFE54BD2D9
+:1007C00017B472667141427DE1EFA4C77F337D614A
+:1007D0005981AAC7C7EA0B60FF17303C64726D27C6
+:1007E000C7F89CA22F3482BE00BAB022A75539BFE9
+:1007F0004091F32778A667CC37AEC5E79A0296E713
+:1008000070370929790E6103E87F89F0788D322FDE
+:10081000158FBB008FC747F0B8E164B0CF887E0763
+:10082000F76EC8D368584E82566AB7CF175A509E93
+:100830000D118988F9AFD53E9C57E6126AAF51BCBD
+:100840009C0FB1FC7197AFC70CD25B34FA8A3A6F38
+:1008500015AFB5FAF5C4E57E1EE28BBE9104DFABA1
+:100860004F91044A61BE352666DFD4982C411EFCA8
+:100870000F93F567A2EDCF1AC1F322E33BC3EC2738
+:1008800046234B23D0EF74A7E737A3D2237A7B729A
+:100890005978E563B43F3D29D1015F57C7373B2BFA
+:1008A0003F298638AFD08FF62BC962F92C478A19B9
+:1008B0005C93E93E6CA570D50B32C24F6F12ED6DA3
+:1008C00076D8FF7E8CD385D309FA6DD5FDDA622503
+:1008D00032E4151F2966787FA458C4276D8FF9006C
+:1008E0007A176D4FFBAFDA67463E727EAFD50FFACF
+:1008F00004959323ECB43EE34FD40EA4E5B3FBACD4
+:10090000A8579D55E49B43F5DF9395B8FFEF2A78F0
+:100910002393AAA160EF11EE86A174EE44B5431AA9
+:10092000ED89E2DA4ABDB3FF5686BF46D46FCEDB0F
+:1009300043F74199CE0773E0FA14BC6ADE555DFABD
+:1009400000C81BAFC5CDA0EE2B057DCDC82FBDD5F2
+:1009500044813D955F1E5E06783FDC221A6993C98B
+:10096000233EF8FD6C5AFE68979E18017FB6DD9411
+:100970001284668227CB3B66F07CEAFDFAA3A128AD
+:10098000BEB368476CB931105B6E26C2D15094BCBF
+:100990006AFDA0FED76F45E1DBB902AB03F08048EA
+:1009A000C47D91D2D3F107F7906320BBF93B52800D
+:1009B0009FDF45D9563C7AFFFCC185BF7E8B7E27E1
+:1009C00018AA3E2F40FD5232007DD5523D279E9DF4
+:1009D000BF4DE16B4663CBC9AD143EC6D78DEE3635
+:1009E000DAAAB7C0470AD3C13E0EF7C1BE1A479C68
+:1009F0002981F846D5882F30BFE4FCBF1037C0E905
+:100A0000BCB912F1E9FC46B3047E80EE1C0BF3CBBB
+:100A1000BFC1F9396617CE184FEDE9853815E0BB2F
+:100A2000E1951B41AE4C308A2B445CAE4987FB4DAF
+:100A3000AD63FAEC36C82BC1CFDE4D0DF43637D896
+:100A4000D1FD362086A98512CB9FE05F3498E89FC0
+:100A5000CE0E4F511BFD6E91378940DEACF0A5E004
+:100A6000053C7B18BA8AB22B8715323ED3680A1927
+:100A70002AE977CD5F2C9D96AE8BC47D8C7A9F67DB
+:100A8000289DB77E4F6970287DB5A0B51AED672AFD
+:100A90001F185F3CC0F8E2826595F89E9B390DD720
+:100AA0007B82AE17E0F2E64623AEF7C4700BFA3352
+:100AB0004E6CE1B0BC403460DE2DD5A7D22A1DF0CB
+:100AC0005E2F1AC96078346F7878E5465AFF6E3623
+:100AD0004F388AFF7FD9FC738C4FFD85B0F1E55DFF
+:100AE0003CEA697F11C3E54180A7D4628BB6D71772
+:100AF0006CE1BDC02F176CB9F7DD0900B799B79548
+:100B0000013C26D99766489648BDAA9F0AA915DBDD
+:100B1000812E277D59DD3F09F4C42D946EE8BC0574
+:100B20001DF181BDF4D696EFA27DB0A026C90EEBD3
+:100B300093366F9B0AF2F82F354374B8AE9738227C
+:100B4000023CECAD19F07E012778E3E1D5E1021E0D
+:100B5000F1AA7284C50DF271C1EF78C4174A67B764
+:100B6000425CA9718B1EED8FB7661EFEFD6C47843B
+:100B7000CEB8991B664C84EF7FACC7EF07F4BFCDAE
+:100B80001F7F007E17F84735119043083F2DDD1970
+:100B9000472C2F847969E96FC18A964296EF717963
+:100BA000744836333AF41572C8A7BF011D2E2CBC09
+:100BB0000C3A24C35263F48EC17C4F46BC55E3E526
+:100BC0002637F16CB3607E9487A3FC7A6DA180F523
+:100BD0006B0B999D29FCF59E1DBFA2704A2BF4FD5D
+:100BE000A010E42BF194827C96C26215B8E62D8A9F
+:100BF0009E4B36B3F318600FC1FEAF4F27DB3BA30C
+:100C0000FC5F8F417FE9C817DAA19FB37FFCA20F79
+:100C1000F6AB29E74C09D801CD17FE0BF36C2CFB82
+:100C2000597E96C51DC6BC35BDC38BF8A8F2FD66BE
+:100C3000379343DA755D28D4333EED08633F635C38
+:100C40008C3ED5F8F4A6D6248C136E72F8CDCC8FDA
+:100C500045F553DAFFF4321EF98CA9AC9D801C23B4
+:100C6000153CC6F7267DF16B02F1D077AFAD7683E8
+:100C70001E6C297B5348837556E895FA9FAECAA52A
+:100C8000F5BFBE760ADA73F764F112E853D3CBF2FC
+:100C900064949F1E96273FE98B14A4C319F5335023
+:100CA0000F56E7EB2526C942F1642625D6E8F30462
+:100CB00033AE354B9628FCFAB48B9BC6EC0029E585
+:100CC000E631CCEF162866F23C1A0EF7641970FC78
+:100CD000D905952F01BE4CBA8EEDC3A9978CFE1590
+:100CE00074DC53E6F8FADDFE42E647C815AE47BEAF
+:100CF000B4F42523E66B9CE6E27F7FF72A1EF3CC53
+:100D0000EA5771C44FC73BF5FC6B39C0D73FDAF6E1
+:100D10005A4E6DD47C12B5FF6361227F76F0AE68C7
+:100D2000FFC074038B139171C6187FFF749B721EF2
+:100D3000E612E35FFF9430EEF38B6130DF5F0DC4AA
+:100D40007DDE19161DFF1A8863BA59DC471BBFCC1C
+:100D5000AFF83765BEECFC41ABA0CCD76D6471AC8D
+:100D6000792C4F62C98134C4BBE986F0E318DF7C7B
+:100D70008317953897C784EDB3587D8275118F27F7
+:100D8000DF518EFE319C0FB7870B5A6DDF627D8479
+:100D9000C5B5B4EBABDDCFC78DD336BB585E48725B
+:100DA0007118EDC0A3EF3C0B991803F86EDEEFD479
+:100DB000459F5B19D06715FCBE09F09BAECFBC8A7E
+:100DC0009513E175227EF5A822B755FC3EBA2A2F6D
+:100DD00005F0ED215353A88FC2CFC3A710F3105ACB
+:100DE00056F241E40FACC88778052E4491835B3EF0
+:100DF000B0A27DD6AE6F7906CED9C96D02D946DFD5
+:100E00003B929AFC6DB42CE9AD9847777FD28CADBC
+:100E1000608786A882CBD1F2E74947B6829E404CD4
+:100E200029444FC791AB94F60693D84EF58BA79201
+:100E30006DC85F5AEF2228BF334990E32840DC2376
+:100E400073991F7CD16E0EF3E729C583DEE7CE8B45
+:100E5000AF8F168C64FCFB8F905045D7EBAE8EFFA6
+:100E60009D7BA4EAF7137CA128BBF461CE2D29F960
+:100E7000E404F265F5A47F36F265AAC7FF9ACA8337
+:100E8000A1FC2BE8FF3EF6A0EF9978E792D4E75D4E
+:100E9000D5F1FD0A1394715D5D9C5F6F43FAD56DCA
+:100EA0008DA15F25AE6BCD70530903F17C16B7CDD4
+:100EB00027EAF9940D10171952C1E668F38408E87F
+:100EC00017595DD7135F1AD0D3C44C906F4BE6C54A
+:100ED000DAB959B5ABB2D10F597BDF0C90DF1BF4F7
+:100EE00096555C0A3C63FD871B34FEC3AFE30B5988
+:100EF00009E9664216F8633644E2C1883FED73455E
+:100F00003FCFE12A48749E4346BBD4E7033DA8D2B5
+:100F1000E4EE710FA61F52E1CE8275BDA8EE9B4292
+:100F2000CFCD0A6A72FB39B44B07F343059E8DC3DC
+:100F3000109EE6AEFBD16E4A2E657EF7E4FA5A1F8C
+:100F4000F09F64CA7FC08E33185A38DCFF89CC6E9C
+:100F50005BC2B1F2924A5194E9F7069B923F7D033E
+:100F6000ADB7039C7CBE68BFC335BA7B2AA3F3B47C
+:100F70004542DB031F9EC5C69B6E5ACEF2C47D540C
+:100F800047CA8EC0B14A81637E45123B6771AF0983
+:100F9000FD719BCD5D385F9DC4ECECDA4E33F2BB46
+:100FA000A1BC0BE352BD7A861FB2D584F4EAEE7D74
+:100FB0001FF305875E9D25F1CE28FC59CAEA55BC72
+:100FC000209A3C138341EA037F239D881BF2949669
+:100FD00070525F15AE4B0CCB6E58B7C2974B9298C0
+:100FE0001CA1E66616832B8B3B6AF68BE20D8B0306
+:100FF0008CB1303F17F149A87769D63B186FF6BA24
+:1010000080DFF60EE0CD1E573C7EBBC62EF5F544C4
+:10101000E30B9156821FF8111D0977C6C31F77ACE9
+:101020009DAFCD9BD4DAFB4DADD55EC5FE904DB8DE
+:101030009F06B43F9A96557A99FDE16A037F59F36A
+:10104000722AA9689BEAFD9C09FA6B9E6543FBBB6B
+:1010500079CF4ECCA7689A46DC308D5AC59FADAE8D
+:10106000F3A89EC549A9CC0A403E47B73DF4349C3D
+:1010700083EDAE57F3BA589E93BC8753F2BAD43C73
+:10108000C0F011F0D7767312FA6D07CED3D2FD6798
+:10109000F95C979717682DF63AC112FF69C17FFC7A
+:1010A0002629FD32F2AAE582755F9D579D742BD4E7
+:1010B0009B602F947A4003AA2FAB658F59827CAE38
+:1010C00048BD40ED4ED31E8EB597D7DC3245C07378
+:1010D000704AF9F327E1BCEB1A3389192F7A7E8223
+:1010E000A67F302D2D92FAFD1F664EC9C73C48657C
+:1010F000FE154F7A86D1FEF4B1FD21CA28EDA1A0DC
+:101100008EF7C2E863DD8F0E8BE8ED548FFF6CE441
+:10111000F888FEFEF0E1E95D63E958C9E26778EE20
+:1011200050D5C39B1D2CCF5A8BE77F53E414B58752
+:10113000A7826AFDF0ACC55EE877200F72FF5C0FF6
+:10114000D8C16A1E64F3722F9E3FA47ABFCE057980
+:10115000D57F3C73E220013BF314FA039A2F08CCAD
+:101160004F4EED078EE28B69FF5AC41FB243EF0763
+:10117000D74EB75D26808FDD07B8F1805F84B4E479
+:10118000DC42617F9BCB9384FD25C83FC873313F10
+:1011900077B3AB6A6321C0FA398E803EDEE9FA1478
+:1011A000ED8AA6BD53C6479F97ADDFB38E9DBBDCCE
+:1011B000A18FBBEE3C17CB776CDAFB2AC67B4EF9CE
+:1011C00039A4B985827F35D89B0B17EAC0B2226556
+:1011D000FEB998374D661908CCDFACD821CD3B6EEF
+:1011E00092E1FC6E33FD8F9200D9E49D8FFAF6A652
+:1011F00059260BE40934BB6A1723BF13933C60CA1A
+:1012000069E739900FB92C09F3AA3AF7E8A7819D4D
+:10121000544EE9E26716E0ABEF39B702FF4C1BC74B
+:10122000B78B90771A5FFF2E1AC5E45007E795FF3A
+:10123000B90CE338243ABF7DC41E667F4D74196231
+:10124000FD932E66175E2BF75703AEBD218492C126
+:101250001E6E269E4FC0EF45BC1609E3582480FE43
+:1012600040C78312DA4D2647E891B1507FAD8076B2
+:1012700093EA4738BB3713F5B1975DBEEFC23E9690
+:10128000F3A127FF19E0F688A0C4C3185FC9B9C944
+:10129000320EEC2BBD83E93366AACFC0B9A1EB5661
+:1012A0001FFF6535F0568717F50842851CDCEF50A7
+:1012B0006DE2583C48A33713D13D19DA4F55FCD2A3
+:1012C0000574B74E9810353B2EA6813FC32103BC51
+:1012D000DFA10B48A3F55388A783ED0BDBBFF50611
+:1012E000A6AFAFD799505F57F5E164473FDA898DD4
+:1012F000010EC76974BD82E7471629E71406CE0BB5
+:1013000008213C3F51EB4A56E2B01D0C3F493FFAE1
+:10131000C3C88B6C1FA8E689E72A54B8ABE70CD486
+:10132000FE0C4A7CB751F1E75280317A74A9F1DDA5
+:1013300015CA533D07C2C62582541EED775C5F4334
+:10134000483FCE4BB2C17C1FC9F0DEE7A2DF1FA52C
+:10135000780C78767455B29F708047FD1E88D3C88C
+:10136000A52CFEA2C5A7475C9C72CE2C3C15F3F0C1
+:10137000F6263867B627F69C19E50F8BDFA6E394AF
+:10138000951D76037EAFB12BEDAF2778BE407BCEA7
+:10139000AC4BD987FF73E7CCDC9CA7873EB7BAEC90
+:1013A000B1E7CCDC6CBFD43C19EDF9B2B3D94181C3
+:1013B0009D07093DBD0DE5A511EDC2D73FEEEB0040
+:1013C0003FF3B952831BCED564DCF64E07E62B7192
+:1013D000420BC44FB5FAC0EF9CD53F01FA5977CB09
+:1013E0006E37E68F6BF481447E008CED46F9890EF2
+:1013F000B8AEAC1FC0DCF5B90DF0ED34177E1CF2B1
+:101400009AE5037CDCBCE60F5C89E2629E59D1FA66
+:1014100069879AFF674F8AC987ED4890FF9748EF21
+:101420001712E6FD5D8FFA5BC740DEDF34557F8B18
+:10143000CD6B1693BED25E56C79F1672C6E4117C62
+:1014400072C9EB54EC9804EB4B64B75D6E5E841686
+:101450000E1D09E4E85F5D03F13F4D5E8447843C67
+:10146000820EC823A04F812332FACF760EE44504C2
+:10147000D15FFCEA48F47B1913E645B0FC3EE1C0BD
+:101480004809BE7B58EFF5803D23EFD42B72C0FF97
+:101490003CF84D3A0E64A39F8DB84225C01F05FB52
+:1014A000D42CD0AB3A14FC6CB8F4BC88B4A2387914
+:1014B000115BFDE31ECF65F6737F32D5CBB61226E6
+:1014C000A7E4FDCCAF49E78D7EBDF063C3515FE576
+:1014D000669A701DC7DE30F618510F77639E436D14
+:1014E000162F827CE9AE293F01F2EB18555C818E04
+:1014F000EBEE5E8EF66BA2FDA95B151B7756DF5FE8
+:10150000EA3E8D2B62FB7414EC7B14B432FA8B1719
+:10151000AEE20E62FEB626EE5D56441439119BC74C
+:1015200070DE5C89F1D8FB9EA8C138EC7CD282CFFA
+:1015300085A44B89CBB2788BB44A403921EDE0FCCD
+:10154000929391890E6D7B5187F7F550F1B609445E
+:10155000A24CA9E66AFA9AD371A0A74A1DB49C4985
+:10156000D7B55A90B3E8775BDF4F46FFEBC30E4920
+:101570003957C3EC2FF9510EF53FDA2FDACF720746
+:10158000C51BDACFCD452C2ED050C4FCC91445FC68
+:10159000381FE5D9A1E47DA8E3B5115D109E3A8E10
+:1015A0003D1F168569F1F43BB5BF0E7D8B09E22D19
+:1015B000E1E13A8C679E377866613C30B59080BD3A
+:1015C000D8616D59358DD5230F3D6F0E7BB1FE3B34
+:1015D00002331488940AF3BD41D90FEDBECEEB8AD5
+:1015E0002D6BF313B4F77ED411DFC8ECBCC1F760E8
+:1015F000DC50C4E4E1F94EA7B22F6E8C9777E8A5D2
+:10160000DF38413EAE16500EB70D6370D30D67CF75
+:101610005CFBE4592887ED543FC5F9B2F9E77EC772
+:10162000C101FD75D8197E7DDB796BE7BBB4A810CD
+:10163000F7AD038C063A5EC76ACECFE0C5E67DA95A
+:10164000FEEA278AAEAC9C3AC6B9B70701CF2CFE9A
+:101650001F81DFAFAECD28023F3BCD29F4BF9A47B3
+:101660007EB669612A968FAE2A403FD000DD9E5C2F
+:10167000B918EE33B9D47C8AE714BC7857E387AB4A
+:10168000ADE0DE837EB47007841254F9439B56DFCD
+:10169000543C15F863938E4899A00FACD2E4B3681C
+:1016A000E8798AE47BA508EC0F437F1FE353A1424E
+:1016B00001F56FB31BE0B64E776CE7CF015F769A0A
+:1016C000313FB26979783BF82B3325DF5E68776666
+:1016D000D9E1A99C84DDA19E74EEC048BC1FA7B6C9
+:1016E00043738FC7A3B1793464552ACBFBE88E7D51
+:1016F0000FF737C4B41B945FC3F4D6F5065F11D857
+:101700001793AE6379891FD7EB08E0C5C766863F9C
+:10171000F2635645CEB80BA3F5DADF6BF1E3313354
+:10172000E2479D72EE4DBB1F8D801F74DF1A14FCC3
+:10173000F8F8D5AB0B013FCEECBCBA10F063BDBEE0
+:10174000CB03F4B53BDF7718E0717C8AB74FC7F85D
+:1017500052E1E5E0ED4757186F2F55BF328D4A141F
+:101760006F91EE888EB7F4EA999F4C36C79E1BEBBB
+:10177000BD4CBF6A62FF58517EAC7FCC951F57BFEE
+:101780003299BF52BFBAFC75103C37A8C6617AAD1A
+:10179000E1C7B747C16B8999E5A32C291245B91454
+:1017A000D6579B87E710FF6872F77057749D317E9C
+:1017B000C037BEC85BD905F3F030BFE51B82D477D4
+:1017C0000D1DF70DC2FC96DA75DFA8C46154BB5B32
+:1017D000B503B5E3978C627AE6A4519E52B00B260E
+:1017E0007D7111FD0827E11E2C3AAEC9FF33B4E725
+:1017F000C87E4EC4738C128B8336ED9DF72CF85D3A
+:10180000EBFD4AFC721787F67AFD739F60FDD93DA8
+:1018100075586FD9CF05210EDA3C4C87725BCD7FAE
+:1018200050FD3FCDFB4BD1EFA3FA7FE83CC6805D76
+:1018300099EC081B906F817D49DB35092CBEDBE4F8
+:10184000206E1958ED9E58BF899A1FB5C96B407A12
+:10185000DFB49FF3833D9E61F03987213C87892760
+:1018600092237C63FA28CF4AC87352F3EEE0FE9FBE
+:1018700051E3D10F9A83E710F4EA7D2FB1F7F324F7
+:10188000C2E70509E986CC89C6B790260E11BA626F
+:1018900079CCB351DFFE6FE2457DDBA7C1B75002C3
+:1018A000F9D23C4ACD63BE15F57DB5FDE0FC7E3F27
+:1018B000CBEF1FC8CF6379FC0DD309E9B4B332DC99
+:1018C000EBD408F73AB999BC0F6AE47D7419F2E1D8
+:1018D00082517CBE41E8C77302EA3D4E901F17FD5E
+:1018E0007D139CDBC963797231FD28FC3F93BF07F0
+:1018F000E35571E2C47744DB4B8754BBB0543D17CA
+:101900001636803F6A499B230C718F4356E5BCBA5B
+:1019100092AFBCC41C3E06FE9A25CF67E279A201B5
+:101920007BE425A3E2EF6774DAC0FE24CD0B8FA21F
+:101930005FA219EEA5E022FB363DA11DF98B7C8844
+:101940001F1D1AB023DFC987F363AA5C687033FEDA
+:10195000D6B08763E70803B1E7C85E1E7565E58406
+:10196000FA5DA2F6874625B24BBF0ECE0CDF0F25DF
+:101970003A7FA7F075158E5ABCBF5CF8A9F503F045
+:10198000A37C08E583067E5ABF9FEABF231D22FA87
+:10199000F7A80E1580FC53D57F77A9F2FB43054EBF
+:1019A0007F6FF94D4627E243DF6E7F12F1A3CBDD57
+:1019B0009741F21BF6A724B1FCCEAFF83765DEDA0B
+:1019C000BC0965DE9ABC8943FAF00C760F0B858F53
+:1019D0007370DE4442FCFB9ABC896FB04E4DDEC48E
+:1019E00057AF539B37F1CC81A76C105A84F38BE02F
+:1019F00027E9DDA6C77C81A9BCC5C3F2D97896FFCB
+:101A00004A3C785F6FB3C98CFE106DBE1FE5542B46
+:101A10005B401FAEA0760A9C97DAD28E7A4463367A
+:101A20008FBE55C86F14A538F9A4424D4A501A9C70
+:101A3000D706E70BF05E8BCBCC6BBB66B4D581F2DF
+:101A40005722CE6F985F5A3D1AFD0F5F9DD7F65C07
+:101A500001C3FF372D9FA545DFA75B552C13885386
+:101A6000253A0751339A1BC85BC6F38A824CA2E51C
+:101A700071A276B34733FBEC4D43F8FD00E881B427
+:101A80001B88D36619A8F55F16B9AFE13697F7F64C
+:101A9000D1E9A83FE1FE9EDDFB078C4F3C934D440E
+:101AA0003897F08C5EC67D96D309E2B59A7FA18EF9
+:101AB000734E89A35D2AFF593CFAEF2B171EFFBF17
+:101AC000CE7706E569317AFC06FC06E96F809FE86F
+:101AD00059FC4ABDAFE56BE5DC95E6339AFC9244D0
+:101AE000EB6A065AA4F8F3CA68EF8B8C8E3CE817B1
+:101AF000BD5CF9975C46F52180C72EA304A466520D
+:101B0000EE65218F66AB7E5C769FE79AE1A82F7F1A
+:101B10006C66F355EF9B51D7F3B6163FBFA5DDFDBD
+:101B200078BEF7E7405FC72B3D780EFC612BD3DB17
+:101B3000C2CFB33C7DEDFD29946ED87D32CABDE0A5
+:101B4000DA7B20FE38FA1F23BF2F8CFEDFD1AFFED9
+:101B500051F2FBF2D7116B7F1FB2B23CC888FDFD7A
+:101B6000BFB6AECB92D76A5E747955BF129FE008BC
+:101B7000C427D4719AFBD9B9A2A1CA7916F5FD8DF3
+:101B80008A5E7867B167189C9F292B0B3E0DE76B27
+:101B90009A880D7FD7A02970FF8E5F39D8F9662CFF
+:101BA000BB587C95782D785E3FADD057588CF41B90
+:101BB0005A09F439C241CA21CED1E99A49EA2C988E
+:101BC00037310AEA472C0F3DFDAB32CC1B6B017A53
+:101BD00055F3A6CB2F7EB6725A19CE17FDD50E63DC
+:101BE000ECBD333716337B507D4E53E64FB73D1B6C
+:101BF000E67366213BEFDBECF088E0F756E3F4C9CF
+:101C0000523FE63934ED62465139D88A50FFC03030
+:101C1000A4AFA65D95A510BF25017329DE07FE2799
+:101C2000760FFF996543D03FFAB2CB5709F3B696CA
+:101C3000F9AF07BB7F041D07E2BC67765E5FEA8BE6
+:101C4000C33733F95419E2E0993C093C2946F816A8
+:101C5000B5F767A37F7B6518FD6EA5C5EC7DB383E3
+:101C6000C9F5E6FD35649E2552B63862CF8B4D1A14
+:101C700035A514E6515A2C2879A42C6FD549D530B6
+:101C8000F0736AF1C9A9E4ADD62879D9443645F292
+:101C9000B173BF3E6F559D9F5A56F356932F30BF79
+:101CA00043AE68C03C17EB2AC657C97282718E6B6F
+:101CB000C3FDD529144EF9DDC16B014E290076BC58
+:101CC0006F39F4C858FADE91265C0BFE9BA75BC700
+:101CD000F582FE2BACEEFF0E6C89D42556814B3479
+:101CE000ADD0DB887824B4B8802F55FD4ECFCE55CB
+:101CF000AD4E46BDB23BA701CF559D3D6C8C7B2FB1
+:101D000085FA94C98A2C8893E4AEFA77CC63B0EE56
+:101D1000E2E29EBF7BB7D8A29CBB5A91057117EB3C
+:101D2000AA7EB982F69FFB184714333A9BCB027FF9
+:101D3000B6A003F95AB787DDCF58D765AF32A1BC3B
+:101D400061FE2572AD03E588B0FA461DF009A18D4C
+:101D50006AB1749D6F17B3787A41B7A80339F5AFAC
+:101D60005FF271E35E4F1447CEE700B81A8DE1BE13
+:101D70002C67242F493D97A3FAA706E4CFAEB9E814
+:101D80009FBAFC3CF4F0ED98E7F86506C683A6DB45
+:101D9000983D420591723F516CFB41F713297A8BB4
+:101DA0006A176BE9409BD79D5F3104E982F2D1C08D
+:101DB000263186EFC5CDEF6E1598DE4DD7615802FE
+:101DC000F3A8CC72833FF152F3E9B5F6F4809EA3F9
+:101DD000E825EABCBF69FEB95ADF0079E771FC1F4C
+:101DE000AA5ED3A19E33FF92DD1F3742B1278E76C4
+:101DF000FEBF12764FA79AE7E267E754F4947F227A
+:101E0000FE84AE93010F76D9754DC5180F6BC27E57
+:101E100056B3DFFF18B12A6F4545193C45C25178CA
+:101E20001FDDB76804C69B295D14C4A18BC5C5EC32
+:101E3000FE06617532E2B1B09660D6A660CF403C36
+:101E400016D6317C5DA4D0BD9A67A7C62DEF2CF6BF
+:101E50001D2B4E8FBAA7A53589DDD3A2E4AB5B5B02
+:101E60000FBF04F79F3CADC4AD7BDF183D13E38982
+:101E7000AB050EECC3F3F6B923C07F7756E1DF560E
+:101E8000A19F8896687AEDC5F38EB907D8392D41A0
+:101E9000C9AB15563BB6027E9A9D3E3CD7F99D8E46
+:101EA000208F795BE2F127A7496077840D906777EF
+:101EB000AA4D08AFB0A3FE14E327D3FABD8810C023
+:101EC0003C22DD982BAB47A9DF256A2F8D49A83F1F
+:101ED0007DABF322E46BFC53DF16AF13F9A72E7F23
+:101EE0001DDA7322CC3E216FB07CAC38EB8AF15FF7
+:101EF0005EF175A97E4B6D7EDD203A66FE0FD51E24
+:101F000052E325C423C7E4BFF7EAC520E83D904F5C
+:101F1000FCAA1BF4EA1F9BA3F3DFAE1FA38BBDB784
+:101F200092F8CD701F429D723E9A08EE5510B7BDD3
+:101F30009FB776817DD70EE71240BF04F87251E754
+:101F4000333EB0629E46ABC0CE6F10999DFF5832B3
+:101F5000AFE5C7D07E495BA608F097AB5A7E8AE70B
+:101F60003B74C4DB4E9F9F2BBF87A3CE473DAF90F2
+:101F7000487E0E3AAFF035E72DB2139CB758A0E07B
+:101F8000BDEB2E82E72DC82ACF569857779B40206D
+:101F90003E9D3A8D95470826FC7D2633E47DA7E1DA
+:101FA000F958CCCF0E5378429EB919F2BED3E03C1B
+:101FB0000CBBA7939B390DF12F95C207F482763D98
+:101FC000BB9753BEC582F8543D8DC55B53BD06E437
+:101FD0003FE7881BCF09C8707F9F03F06C05E2675D
+:101FE000D89A81F1E2D47CA6479ABD069DC9897929
+:101FF000DD88AF614ECDEB667CAF7BAE84F9F60336
+:10200000F774CE23B83FAB0BA666C3EF920CB9C9E9
+:10201000C0417C499533550A7E746F55DA37B2F664
+:10202000708F27CC8F2C61ED07EEF1FC3EAB6F1566
+:102030004278AF14D561947B2459FD92D919483F59
+:10204000BC722E97DCA69C2BE0D83D644B660F61DA
+:10205000F536C607C9DD498A3C57DADF9BEA57E205
+:1020600005EC7C40BD4EB9EFA08B44C79F553AD3D9
+:10207000FE3E4784CED8F9922722E704909EDBAF3C
+:1020800017310F52BD87B4CA6260E7CE4CB17435C8
+:10209000694C2AC3FB0AB709C65DEBF4FC644C5CCF
+:1020A0003F8D7F6E345F19A2F295BB0D1ABB2C9346
+:1020B000C1D5167E9A9D4F335E965D96380EFA7C9A
+:1020C000766C1C744776741C54DDDFAA8506E42BFD
+:1020D000DD76E92DC897DA44410BF73A6AD7BD6936
+:1020E000E07E76BF19F452AD3D7828415ED4E931E7
+:1020F0004C3F7427F0439C1E93C8CF9520AE5C6A7A
+:10210000FC5F8A8F33FEDB9BE03CE200BC54BDC920
+:10211000A48D7BC897E5F7E935FD10F9A0A75D20F0
+:10212000E6EB6859737E8EF241E48BF20AA3D8EE97
+:10213000003EFA43E48BADD4723546F1456A8E5EBB
+:102140000DFCB8F74117FEDED55B0FBAF179CECCA6
+:1021500005F8B1F00CCF018DE993970DDF83FBCD2E
+:10216000CF59C33970BF794A207516DC577E2E3D92
+:102170007C04CAB69FDEC1CA05E1A7E1BEF3FC9F9D
+:10218000FEF27B58061A1B42975B12FC9E5C0CF712
+:10219000EE8756F6837E5FA63977A0B97F19CEC742
+:1021A000C27A322D068C53672AE792C964C53F0470
+:1021B00099694077D9A598576821D2AE7EA81FC6E5
+:1021C000E42EAD6F83FB7DDB0B9C2C6E4E181F2025
+:1021D000C394BC131292C11FD5EEB463FB01FD6E14
+:1021E0009751C95B63E3BFF72ABB37493D6F4D8801
+:1021F000381CEC468B4462CAEA7DE6441087C3FD76
+:10220000C3ED6ABC5A291FC8F48D2A89B25FDE9BD0
+:10221000727F31ACF3E3DD0FE4833EF55DE577E2F9
+:10222000B478F5D7B14C8EAC48FEDB1CE0E3EFF39D
+:102230003637F80F9666FACAA0BF798EB6F1768A5D
+:102240003F93C54AFC3DAA89F26C0EF88AFD6636BA
+:102250003FFB642F37AF38F23B55E93E01FDF4C434
+:10226000D7CD83BE9D7EDC2B027C1A4CE11C81F60F
+:10227000F381C33709FA3D3FF7C3FB308F70C87B4A
+:1022800047E05ED4F7F45DD536C027A7720F36114C
+:10229000F01C50DFD0113DCAEF6DB1F340059C1228
+:1022A000870D4E06B9700361780B65A8BF51B987D9
+:1022B0006EAAC8EE8D9D5AE6C4DF4F9C41C202E073
+:1022C000C3D4F7BD3602F471B3AF2CDE3D1BEA93E5
+:1022D00064E9A568FAB95E8A2A13C8B7882DFF9306
+:1022E0003BB6FCCF155F8E8C2ED7089E3B60DDAFD2
+:1022F000734CFEC81398FC11496005C8C7175AC42F
+:102300007118577770329447BF3604F3A84816CB3C
+:10231000BF1865CBF53338E46D867585A99CEF71E0
+:10232000C0EFB0B1FBC532DE376C85FB2088246D71
+:10233000063ADCAD77619E6986A5F6676DA8CF5831
+:102340004901F2296933E2B5D524C1EF961CB4B234
+:10235000FC89F6B53A8C37713693CE43BFE37B04E4
+:1023600026FFAD0BABA19E2FA71B426575AF9DFD50
+:10237000AE5BFB78A25F510AFBE67E1FF522AB093C
+:10238000CF274CB6B9EE807ADE66C0FB2B0E5ACB57
+:102390007DCA7804FA7FCEBA10DB038FD653FAEDEC
+:1023A0003533FF3A4FEDE3156C7CFCFD46FE1EA273
+:1023B0008C6F220628D7123C6FD06B17D97CEFD5D3
+:1023C000613C04EAAFC3F999B05EBDCF3272BEB7CB
+:1023D00052C0DF21E088121F6BC3F2530A1F6CD773
+:1023E0008B07014FE58F0881FD986CBB8074C0EBB3
+:1023F0006C6EBC1FC843F21D1984F92CE8F77C866B
+:102400001884FC7BFE1E1BDACDA0F940FD50F813AA
+:10241000E95AF09072C53583E3798E021E8FE08809
+:1024200017F6E354492EF2A36775EF6DC0FC0A8BD3
+:10243000D7E8A6E3186E23B8BFEEE4F8E77AF7967C
+:10244000303A1DBC7FE55990C7C1D92A2478B65BC4
+:102450002B2438A7D46B776779A3CA71F6C50F7898
+:1024600013D91753505702FBE19640BFF8FAFE68A4
+:10247000BD05D623E1BCF8216E09ECD07C1BED87AD
+:10248000F27D775AFC759C52D61150EE2DD4D6FFB2
+:10249000BE4477A5D7A9C1BF6FB9CE8CD8755EC130
+:1024A0007986B82B304F3E87CECF12991FFD13EFA0
+:1024B00051BBC1A243FCBA41BD1FCA157B4E447B30
+:1024C0002E8490E51B81CF7C57C977AD4AFE17F467
+:1024D000E35F4FF57C906B7DC93FCC877CD3A92906
+:1024E0006D1D8C385ACECC037E6CE290EFDC4882B6
+:1024F0002BE1FDB94ADF33F63CE4FB7F2B190FF7E4
+:10250000E9FA46A6D2F2C7FAAEFCC54EE48B1781B3
+:102510002F5A4818E9EE06F8BD46A0BBE9FE0E2882
+:10252000D3315AF09E304A8740B72A1D0E9E3FA5F0
+:102530004BFAFDD0161B9EDFDA428278002F8B7497
+:1025400071CCDFD282728B48C323EBA4443BD5D439
+:1025500082EBF8799B8CF2E1BBF6270528DF5CEA79
+:10256000738CA5F39A35F613FCBD0792357724D802
+:102570009D74BEE963FF81F31D7CAEFEABF3C8FE24
+:102580005EF6E884B1B1F6A823E96F9807277136A3
+:1025900037A1FAE3807DAA37615E42E41C72B80E6F
+:1025A000CF3B73295E9067EA39642DDF9D741DE38C
+:1025B000BB1F2FB6B957E03D923BD02E6DBED9A2BE
+:1025C0009E5346FDAB79A14E39A7CCA15C6922266A
+:1025D000BC2769E0F72CE93F2E23F2BB34FBE0BCBB
+:1025E00072D9579D5796F03CB4BC9CC5E907ECBB2B
+:1025F0004691D9AFEAEF9BDC9BABFE0E05D3531699
+:10260000934BB26FE39C6346BD91A4E814FB95E93C
+:102610000BDD13245126185F657AF86C03D6AF4F93
+:10262000F2E3EF05D5F15D88240D63EDCAFD0F7E61
+:1026300033FEAE98C15D087C428DB3EECEF7358F88
+:10264000A5FB34AFD893C3D1A5D41958FC94D2C1FB
+:10265000E67EDA6A1A69790E7E6FEE7AD2F25B5DF7
+:102660001ED2C1BDF0FDACD19FB0DFA18BD0C17D2A
+:10267000400726C2FC01372871A2D73FDEDE01FBEE
+:102680007E8E23EC3C9A4B7B1ECDFBC3B12C9EA5CA
+:10269000FC9E542CDF899AC7713D9B8783E7711E8E
+:1026A0002BE3CD63101D123F8E4FF7B705CFCB6BD9
+:1026B000F0483B1F6EFFFD789E6FF3ED44E42780EA
+:1026C0001CEF37033C870146E4C13A7DEB609DD99E
+:1026D0009062099354ECEA41F3E62DB8AFB7CE1EF1
+:1026E000C8D399915D0E712236EE53C94DEBC0EF00
+:1026F000D17CBB1EF97BCDFE31A8A7F5C94611924E
+:1027000020C964965FE3A6FF8379CD229E2976DAFD
+:10271000CF4D620DDE0B77F3746D5E8EFC500B6D4A
+:102720007F8B92E773EBCDFAA3D1FAE639FDA37A5A
+:1027300080835C6769E127427F42A4BD73305C06F9
+:10274000DD4BD5C1F813A17A0EF4DF5E1140FE9483
+:10275000884FED1D3B709FDCC86F98EF73702CE2C3
+:10276000ED57E7FB6C57EEB17A4B1FC6FB51DF4EBE
+:102770005FB079315DE7C81F15E3EF1B4FC9A87F34
+:102780006E2D2DFF78D3282CBF9D71FBD2F7A0FEB4
+:10279000E9422C4FD67D3207E8C1553EFB06F85D75
+:1027A000E8B7CCAC9FAC245F770DFD2EAB24771C33
+:1027B0005C6033D910C6EF6E1CDB7815F8632627F2
+:1027C000B1F2A1D23F8CC372AE521EF7FA2828BFD5
+:1027D000C57D32271E5F1CEDE2824554DE4E4E65FC
+:1027E000DF4F1FF7FC10B0E32757B1F26877E5EA37
+:1027F0003CA8D77D3A279EBE7456E1AB93BE38D72E
+:1028000091E680B030FBBDE2D73C1FE2EFCB78A968
+:10281000BC85FB06BC152C0EE7F5940AF07B6655CB
+:102820001E56AEB6B465031F9CE1339441DC55B42B
+:10283000383B44DA2EA5A2723CEC7B3555B721CE4D
+:1028400049E9EB53A4AFAB3FC9B1A15EAAD297A8A7
+:10285000477A4F7CAFE4E76CDF62E981F6F705CA9F
+:10286000CF6B62E5E7207AD5E0E1FF008B7F42C5C0
+:1028700000800000000000001F8B08000000000026
+:10288000000BED7D0B785445D2769F3973CB7D429A
+:102890004248088409F74BC01912205C1D02645994
+:1028A000050C171514E1041002B98DE0EEA2EB9AA5
+:1028B0000901441777E38ACA2AE88080A0C80E0A73
+:1028C000C86A644764237EBA1AAFEBED631345E52B
+:1028D0004E0CA2B89FFFFAD75B7D0E99338405BFDB
+:1028E000CBF3ECF7FC3F3E3E9D3ADDE77475557542
+:1028F00055757575CF55CE4EE15FE60921FC891EF1
+:10290000473E95BD6D271A7B0BFEF74357592A6941
+:10291000427410FABF9521457413A2930870B95EF2
+:10292000D42A421562B2558BF70C12C26E6970E35D
+:102930007917C5D3D745CF45BEC759D41F2F764A7F
+:10294000FEA29F4053F1C395429CB67D922D5285C5
+:1029500008D00375383DF489EEA9D48F82A66ED9CC
+:102960009595E04CA35FA1B85C69E857D62B757FBD
+:10297000E5F7D739E8FD0CEEBF93A73DF093F8AC2F
+:1029800057FC5CBA84F6B8A0F155A40BD73D5EBCE9
+:10299000DCB8324CEFA5D388EFF110B8D73CDE9A03
+:1029A0007CCFA264F5427C2DCEE65961FACE3491FB
+:1029B000E851E9FDF79616B5F712B2D709BF0DE356
+:1029C0007D282E31904CCF2BE724041DF47C670723
+:1029D0006D00E8A15A022F36127CB3F0D9D16EB245
+:1029E000D577059EC70BF9BD0AFADE3D289D448FB9
+:1029F0003C898723A30D7A44E1193DFE56BE346419
+:102A0000A0CC107E86D3856795DAC67884D57F778B
+:102A100023BDFF0B35A1F61E2A1FB2FA2C1BA8FFFF
+:102A2000C0EBB6E06685C72380CFD24F12363AB2EC
+:102A3000A9B40A8685C7C1F54B6E26FCE9BD254AB7
+:102A4000962740CF6B12FC8FE17BCDD556B1311567
+:102A5000DFF76D00FC7A757781F1458F27BDF6A70A
+:102A6000424BA17AC5FF04DA05AA1DAECDD4EEDB38
+:102A7000D87FCCDDC874482AB265111C3369432362
+:102A8000C18ADDE9528869E973D2595ED7DE427C9A
+:102A900020FE050A42DDE603EF475551E38AA40311
+:102AA0006192DD2A9FEB3D44B4F69063831E0105DD
+:102AB0007269B728B38BE28926F877656BB9DE6354
+:102AC0001182F8D43DBFA30FE35EE2151EC80FD1FB
+:102AD0004101DDC55E45A703C913EA15973FE0BA7A
+:102AE000904F4B1BB36F45FD7E0BE14B6501F12B06
+:102AF00005EFC7A9F27DC5D32199FA2F4812FE1020
+:102B0000954B62DCB746D275B8C532BB28477ECF3D
+:102B100049F49BADCF0603CF396B55A1E50A31C609
+:102B200039F7B1C3B9C0775887A28488FA7BFAE431
+:102B3000CCA1F75FB689E9F8BE677FEF9CE21C1E67
+:102B4000872F94C37C5C1102FEA3D33D010FF06B71
+:102B50005EE1017EAA68DEEC011E014716F089C91C
+:102B6000F40404F0AC15B7E545E01F43F803BF3BA0
+:102B7000C6F922C76DE07D313CA3E97D313C2139A6
+:102B8000CEC154AFCBCD1C675C933200A51A7690B2
+:102B9000888A55D4AF33525F45C9B90830DF272E34
+:102BA0001D537498E42DD54E8F20A7B725043712F6
+:102BB000FE136F1BCDCF9529E7589EDBD17C745057
+:102BC0003966BC5B69243CDAE5BD6515FD21A78447
+:102BD00017F0B1360E9A4CF43DD6557B12FAC6C0AA
+:102BE000FF2F839EF06A547FC8224A4239178E6FA6
+:102BF000B72E4F2ED16887DC5538E3C3EA800BE54A
+:102C0000E562F8BFD8A1E839E88D934AC36054560D
+:102C1000F676F17321B46C7C2FD9953D3A197AE29E
+:102C20007BEA6F30F414FDA379D0B7BBF627BC77ED
+:102C3000BD281A67A5F1B61BAFD9341AD738359E0F
+:102C4000E773CB7685F5D5585F8C0574A93C680B86
+:102C500006095EFCAACA745ABC5E0D62D2B608CFE1
+:102C60005ACCC39680C305B97C286EC06F4750F913
+:102C7000D97A9BC7817E03BEB77B53BFF3743EF501
+:102C80005A6B116E832FF47F9F60AC70F76E85FBDB
+:102C90006D6D6782FB873A9ADA5FB1B7ABA9DE1B2D
+:102CA000EE6BAACF3D38D0040F6A18666A3FE48302
+:102CB00002133CB4F12A53FBE147A698E091CD37CB
+:102CC00098DA5F796E8EA9BE34B1B07E298DB73E99
+:102CD0005D150AD9C9D1A2D4D4BE542DB30B62B1AB
+:102CE000A8B57D0A79F4D37FCC4F75A615743EBB89
+:102CF000571129A48F16AC95F5C67B2575F7AD84C1
+:102D00008D5B18343F2F15D65618FAF793856F1E32
+:102D100088E8AF576AB12599CABF7B1252212F624A
+:102D20008818F283CA7CF540DFB4BCAB7A1C42370A
+:102D3000A5042F7E5A09DE437CEC297A3C04BE119F
+:102D40009F45D00DBECAFA96756A3040FD7C5B5532
+:102D5000F2E6011BC10773D7422F2F20BD0CBDE542
+:102D60004837F333C66DE6675C6F333F133C667ECE
+:102D700026E59BF999EC33F33365BC999FED8BCC39
+:102D8000FCEC30DDCCCF0CCDCCCFCC12333F3BFBB9
+:102D9000CDFCECB2D4CCCFECC022537DB4FC765B3E
+:102DA000B5D854FF50DCBE2F34A2436A47D5E5A006
+:102DB000A9D7A3F676D3F7843AC1BE82E8559AA97B
+:102DC0000AD5D52A0701FA4FCE6B3FCFAFF92407BA
+:102DD0000F131FCE8AD5F599EE0BE5A162EF7D7634
+:102DE000CCCF1F2B0FC3BD663920B94BD2DAB06BE5
+:102DF0004669F099FC91D15ED20FD3BCDA582FE925
+:102E000093E9BDBECAB292DE1045C5BD60472EC76C
+:102E10004FB10EFE117ECAA410DBE38BFA29EECE71
+:102E2000ADFA8F9DBF80057AF9C3793696DF65715B
+:102E300003B6432E3FA8917279064D860A71830826
+:102E4000B11FF661EC239DD15F01115C198ACADACA
+:102E50009B80FF4CE04FF6EC26D168C3C7C98EDAE1
+:102E600051160B37977375FFEC66115E89C17C9222
+:102E7000AACD075D2A54AD4B1AE8D1A9218BFDD804
+:102E8000D75380F445E96AE8EB77F027B57BC45B5C
+:102E90005481EF8C71BA6F7DC00D3F80EC03F1451A
+:102EA0004C4861BC85B5A8FF94FE6D7D6719DB8B2E
+:102EB00017144D03BD03194E0FECAD480F3DA3D0C1
+:102EC000F8FAB6730FBC27B9B5FDAFBC867D21C734
+:102ED00086DA3FB92B96E9D5AFC3867618D78FED42
+:102EE000F76EAF6F39F036DA5F6ABC76BB67D1CF69
+:102EF000A8DF6645F8371212EFEA7CC974483F3103
+:102F0000534DF4D4806F71B3EADB131D6EEDA0FD59
+:102F10000EDF9F7EFD4F570256F6A7B817137EA708
+:102F20008B1B07035FA2FF83A82F7312FD6968271D
+:102F30003B6BBD9220144592FEF447FFA236F197F9
+:102F4000F81CD0E9FF6207ED31C8F57E4B439607C8
+:102F50007CB4360C663EBAE4B84EDA255D2E468760
+:102F600082B8CE3341FF790E8747257A1628F2BB07
+:102F7000879366CFAA24BC6FB614A5855513DE4F80
+:102F8000A3BFB2F8E22E19C0DBA6E3ED6CAFD3DD30
+:102F90009D13E99F45E35D83EFC31FFE15F997D9A4
+:102FA000781EDE06F839E1E2F58BC322ED7273B5C7
+:102FB00012DC48F56FEA745E6FA37698974ED1AE37
+:102FC0009AF0BB66E48A0D68F76BCDC9786F169EE0
+:102FD000BE6BB2C10FC1FA3EF32E2558930DBFCA86
+:102FE000C3723F4F1465EDA276AF79B57AE0FFB7B3
+:102FF000B87F0CCAB6F0341EF42E7D67CFB20E9E99
+:103000007B008DB83CF9EF4D9A03FD4F9928EDCE2A
+:10301000CD3ADDA689229EA7C6BA8926FCC90A6ACE
+:10302000379DFEE2F59870F7077E33007B5BE7F58E
+:103030004CD1C0E52CE1E2F5D4DBD51D7E761BB585
+:10304000996269CEB2AB98A7346FB399FEFF0EB9FF
+:10305000F966DC5B8714D0FD0ED263E0F79AF69731
+:1030600025C79315494F9AB79FEBF3360F53EBFCE7
+:10307000FC19DB5ECA9FD5D5E39FCD1F528C891901
+:10308000E4AFFF44AA42F1D09944914AE36CE8AA24
+:1030900006B19E1AA7DE61DD45E36C207FC2817117
+:1030A000FB8A3B9EA6FAF1646FEF91FA352140F05E
+:1030B000249F2AEE6139685CBE909EBF9E4FF5D476
+:1030C000FE956A919047F02B5E9BA786E470DC39F1
+:1030D000ED4012959348EF87A9F555E9F78D857F67
+:1030E00030BE13D991083B715577334C13A113F8B7
+:1030F00074B54EEF093966BB330976C768DF86DDE4
+:1031000021FDAA82BE710375FBD357F485FD79B901
+:103110006AAFF88CEC8B6187C608B9DEB8981DB22F
+:10312000DA0B5206B23FEBB6637ECCC1FA04F476FA
+:10313000691D2747CC97D2210AF3C94D86C742E3C0
+:103140007FF3A01A047DACBEF070D06FF18B0ACB78
+:10315000E9D503B5AC81C48753B6C6F9909B8611F7
+:10316000B94982FAFFB48A10E945F3B7CA297C3419
+:1031700017BEA872317CA42A9DCB63556E2E4F5486
+:10318000F5E6FA53551E86CB0716F5027E73567D7B
+:1031900065859FEF167EF68F96D07A17FC5A92B00F
+:1031A00058C236A70B4AF8AECEF5963882EF0A2AF7
+:1031B0001ED8C585BB822BE308AFD23A9F3D9EE067
+:1031C000259DDB8D8947FB071496FAF907FDF51855
+:1031D000EEA9773FBD6EA2681D6FF93985D7C9EF9B
+:1031E0000FF20D46FF5F56E5335E47AB7C8C97AF21
+:1031F000AEA93E85BE77BC6A3CC3770D2C1A81719F
+:10320000FBC457EC474CDCDE64859F31CEA7F8C089
+:10321000E7513E110C12BDD6DAA45D594B76057A02
+:103220006074FF29EB6F15D0FB5A21DEBFB6DDDCE1
+:1032300071F05727E517B3FF7AFDF782FD5743FE7C
+:103240002F358FDCA2E15426F5773220E9D3B2EB9B
+:103250001D865BAC441F1AF1BE5DA5A582FC83965A
+:10326000736FCBE7D48EFDD4DDB2DD629B6CB77893
+:10327000F7AFDBF9002BA25944ACB78E131F85239F
+:10328000027EFA17E95A847C1D6F17FAE623E8C913
+:103290007FB77836B29C6A9F3D0F3DBADCC57AE6AF
+:1032A000942DF4C5C3D0B39DC9AE72BD3F6E0AC99B
+:1032B00059855D682C7742EB07F878ACE0F800FAA6
+:1032C00073F792CF218F3D773CD4F597EED6FEB6BB
+:1032D0003CFDFB96E7DDA80FF2FCDFB6637DC74738
+:1032E000082ADBB92216787D76EF7399185F2F557F
+:1032F000F8559A67737FF3C7CC3F52FF4F906E41EA
+:103300001CE3059BE7D45EE0B39EF0A1EF3C716F38
+:10331000F940E8B779BF5BD817EF07065A98AE4F68
+:103320003DB793ED3FC998670CE9A9FE6B5E5A96CD
+:1033300041EDAF58D764E948A577935283B274FB47
+:10334000CEB7ABA9BF5C97C50F7F74C54037BF3FF1
+:1033500030B461A302BDFEFDE31D31CF72D67C55B2
+:10336000D0515CDC6F782AEB8396621E572D8F6BF1
+:1033700077DDD4776E14F04BC82301BEC5760FDB22
+:10338000291AB60DFCDED56D03DEDF6309B0FD0939
+:10339000CC917ECBC9A2C0EF31FE726A1F20B8DC8F
+:1033A000DBD0741BD597277715883B1C092E998194
+:1033B0007A9ADE2ED0A762D703851D093E3942785E
+:1033C00014EABF64F79942B66F9DC9F7C6F776D580
+:1033D000A4DD00FB96533048A5FA2235C4FD894A86
+:1033E000D95F65DD4EA7E0F5BC68A792224CAE1B05
+:1033F000FD7266047F2C8DBFC9B6D2F7DA937D04C7
+:10340000BE6BB30319FEF8567BFA9AB7680BEB2331
+:10341000D7FDC5F8CEE78417FCADCBB57F768B7FA3
+:1034200021E3932E5C81A1ADDFED6C092FC43848F8
+:10343000DA5D01FACE6657C30C6E47F06FB95F6D67
+:103440000FE65FA64A544F95F6BA06FDBAA6668106
+:103450005F97DBFF4371FF60BFABD292E871E4B5C9
+:10346000FA2DD3536A5E6C247E6DE8A0EDC7F88C0C
+:10347000B8A4B07ADCD0E3810EBE97F1BCCC49761B
+:10348000D5C2F6F415C0861F7CDE0F735E9E3DDD4F
+:10349000D9C1F717A6E365B677EB7186F37AF5EC39
+:1034A00040935EAD49B00B2F3DAF59E3E0B884388F
+:1034B0006029ABA7F5C7487CC2D2FABD2509033BFA
+:1034C00040DFD708D126BDF6D17CD688B661B203DD
+:1034D0001ACDEB51E79A558DE77DC3CB4979D09F43
+:1034E000C297E0461CC022B4087B17FD1DE2D70935
+:1034F000F06BB488135A84DDF489643BE6AD886FC1
+:103500007799E30E3F6EB627FB1F8F1CF788960F47
+:10351000E2E052113D3AA0BCD8B85ED4C7F5278C82
+:103520008BCA79438AFE01FC467EEDB2627C23ADF4
+:1035300093B3BC5D196F6B2EF53BEA6B8B19EFEF04
+:10354000634DF0E5E2FF3385166A90E3AFEC1C179C
+:10355000AC83EDA771D42DCC0962BEEFB18B801383
+:10356000EB982976F66BEB1202097D51AFB84288D1
+:1035700027BD606B9821D739C2B5D90BF97DE3110E
+:10358000C8FF0D2D7605F1A98E0EF105FC25A126AB
+:1035900089CDA911DF6FEFE2B885EACC5C8FB86204
+:1035A000DD50FDF90C3B3FAFB109B67B8119B18C01
+:1035B000D79A64FF6BFDA97E4DB58C677E2082ABE8
+:1035C000BAA2FE0E95EDC070CBC6CD0F621D333989
+:1035D0009DEDC69AE4706625DA2FECEB09903CEC81
+:1035E000F987CAF6608DD797D12E1E7A50C605D7B7
+:1035F0004CF665C4A6A24CB360BC1D49CFF3F36C76
+:103600006A47E54736D9EE439D6F44E90CE8DB870E
+:10361000E7F510D03F57E7168CCC65FF47C63BAFA8
+:10362000952C10336E7E80E3AD0F6B6A50CD065D36
+:103630007E736F4F826F98A3BA1077BBB62486E370
+:10364000A1D76A7A3C749A390E7B75AE6F642EF1FD
+:10365000BF3CD4A7DBE108399E71738F9F433F7C49
+:103660002A645CFAD769DA38B4137BBDDC6E2F3973
+:103670002B3FC04E38DD03D87F9E67AC1BC3734120
+:10368000DF7DCD4EF64B2F260F42789C7DE9FB0F58
+:103690005A4408F2DC05FC4961B90DC06F0B846225
+:1036A000580EC64F71727CBD25DEC2FB0C8F11BF58
+:1036B00060DF02BBE53E03294AE6DF83FB3AB35DE8
+:1036C0009AADEBB19AE9B1FC5ECD4E5BD0023E2BD8
+:1036D000C16D5BF0DE8B316C3FCBF4386FD9F3FDFD
+:1036E000580EF6D87DD92BD0EF3E07F3B92CD19DDB
+:1036F000C4F5FF962250FF821E772E8B0DF7443CB7
+:10370000BB5B7B6D3EE84172C771F932BB7C7E28A2
+:1037100058C0FB1A82FC95B851040B1FEF4F04C828
+:10372000AFD9EC91FC035E5A4DE78DC057233CC0E6
+:103730006771BB8C971FA2B98CF11DF27766BC94A0
+:1037400029E3336EA6FACF16C7711CF55051FD5907
+:10375000F80187D2559EF7A4A1EE1D42F564731BB4
+:10376000EE21B872E1A76F0CA1A715351F66ED75A4
+:10377000B7D27DE6B2F20982E460E6A23B2689C4B4
+:103780008BCFD799650EAC115BE7B7B063B12661FB
+:10379000D2EB6B727D3590C350AEB612E3AFCC2145
+:1037A000FF99E4E894BDE151C4498EBAB5BB517F9D
+:1037B000FA8F5F6EC173616DEEC9F2E16C2C449CAF
+:1037C000A5CC22E344A3F3B4DFE6B29D4D64FE55DD
+:1037D000861CCCBFB89C06A917EFB83C7B70AC6EBA
+:1037E000F31E85FA298DADABE0520D0E80BD3AAEC9
+:1037F0008413956E4C5F0DF3EA842B9C08FE6816CB
+:10380000E9BF956E8D1EA7DC4F2CC51FBCEE0CD9F1
+:1038100087135E8B48F53EECC2737B6BFBEC563E28
+:10382000D277988F22FE9359BF44FB6D7D06DE430D
+:10383000742F4DDEFB9BE1D917D22F1A36C67321A8
+:103840003EFA3C290A27629E1C57E43C3921A4FE1B
+:103850000A6C8DD1D7FF128F537FECC078A4E9F3A7
+:10386000E894A2B7DBE690ED48F6E0CF94FE41CABB
+:10387000DD8336CF5AB9AF66657D599A22E152474A
+:10388000BA0BFE5647356089855C56099E2F841B0E
+:10389000CFCBE33B32F97D43AF892221A0D74A77D2
+:1038A000646C947E9DBE0EC600A8FDA2A7647F80B6
+:1038B000A1FF8F3D99A9F72FE753345FA3E9F07E6D
+:1038C000AE8C5BD5240CEEF0CFE295BDD33F5E0706
+:1038D00015F4A04DCEEB4082B423E4B7A44FEE8F95
+:1038E000FD06BBE9BBA712ECB37DF1D877303F37BB
+:1038F000BEF769AE5C477689E27B47B5F925F84BA0
+:10390000E271C17A221A8FA3788FF07DF2C9F37C1D
+:103910005625DF49900CF97233FD840DFCF9D06E09
+:10392000F0F1D64CD2EBA5A055D7563AEEF16A99F4
+:10393000B023A7F47DA33DC904E7C0DF92F6C3809E
+:103940000D7E44CBE9B20FE767629F2A2D4FAE0F81
+:103950006A6212078824945941E8816AA22BEAC955
+:103960000EF27EDCB1AAF1F71FB6B58EE78B2A9F67
+:103970008F4CD07978FE5AAF13F373C13AAF734EC0
+:10398000043F6AB6E61E7413DD4F6CB562274BD454
+:103990005883BF19968AE76A2820B8DE097A9F887B
+:1039A000DFFF06DACD5F973C508DD04F0BD68EF3FC
+:1039B000CD8BE043BFAD66BEF40F99E12BF69A6163
+:1039C000377832E8C7BFE70D9BE1DC8366F8B9FCC6
+:1039D00066F507D8A7784BD0A9A06C517F807E0FE1
+:1039E000AA41AC33BADC51347522C147D6CDF5803B
+:1039F000CD0BDE5B3618FC3BB9FBAE3DE5F4DE914A
+:103A000076160FD657C745E8FD89C48FF975F7D9E3
+:103A1000AD6E8CD72CE77B2CBADC3E29E37A0B8386
+:103A2000E6FA0BF543B51E4712BD23E52A9AFFD4EB
+:103A3000EF753E42AC6CE9D4FBE1FF944C2081274A
+:103A4000FC8686EEB38BF8CBE927C072634D14E198
+:103A500074C2AFE9AE048EA70C5B3A467C46DF2BFE
+:103A6000B7BA0663BF7D8E5371617FDB889337EDF4
+:103A7000CCA8803DDDECB278904CE1CAF7D767E680
+:103A8000613D21422E0FE2F477AEC43ABEC49FC816
+:103A9000F45928821C679FB3DCD1AA1FE9FF79ABD8
+:103AA000A3F05913514FE32859676EBF68D30F8EA7
+:103AB00048D858970EABDBA062BC37EB78AB0199C6
+:103AC00037304C8F3F1C4653B2377FEB56549C87A0
+:103AD000F66B46CB7AAB53B7B33E5EE795C7DBDDFB
+:103AE000ACCFAC6FADE4FD1A9A87B00F0713E6FFB9
+:103AF0001CFAEE8C53B81C9C47A231FC458A5C171B
+:103B0000F23E04B53FB34E61BB5E9E22E1F2C79523
+:103B10002062BAE508C2027E42C65DCB747A404E8E
+:103B20007C11E301BF2261516BC4BBC3BCFEADF08D
+:103B30000B0FFC00417CF499F6BDC3F623B0B30132
+:103B400025F4B017FE9EF93B957B7F7044C2E7E3F6
+:103B5000C5C4BA6AFE7E90E9A8DA850F7A5CBD33E7
+:103B600096FD763200B1B0EF36DDBF16AB82ED6167
+:103B7000AFD6C05E51B942F7C303F7497BB526D92A
+:103B8000D7D385FAFB323CA0C30D8ABEBE855F9FAA
+:103B90000CFF7A3FF7DBACB85C1B93D15E0462523A
+:103BA000D9BF96EB847FA86CEF9AC97FC7FEFC1A39
+:103BB0006F280C7CD63C90CDFEFA0B86DDBB3746D9
+:103BC000FAF317FADDEC5F89FBA5FFF891E0BEC5BB
+:103BD0009EEEDA863C92F3B96A116F2ECD5BE6CB8E
+:103BE000C077E74DB15BC00F517279FB1C9BF53C70
+:103BF00098661A2FE2EF8795A27A4B841FFC4C9EA1
+:103C0000B40F830B7C5BF4761EB49B67798BE93031
+:103C1000CF225C58CF6F3EA70A2BC19B6B1DC1659D
+:103C2000F4CABCAEBE9E8B73F09E8C371DF24A7DEB
+:103C30001F97277C41E87FFDBB2FE4594CA5182B2B
+:103C4000E32C8763A41CCE1445851CEF770B53FE31
+:103C50008551BE9227EDDE3C7B83199F4F5E66BE89
+:103C600090CD732D837C8F957EC7E15B14B6E734CE
+:103C70009E9E2E8207FF2E86E38587757B64D097F4
+:103C8000E487F3220CBD95ACCBCB9ABB83DB628877
+:103C9000DEF7D9486EC037921BE4F910DFD92F5CEC
+:103CA00033238DF97E83CE57716F02F36DB8C52231
+:103CB000E97C6F06D399DA8BBFE3BD716EE9CF5F04
+:103CC000E63A8CF8FE37F03D7A3D66F05B58838328
+:103CD000FED97E4CF9734FEF0990FC2FFAC303898C
+:103CE00082DA1DB5D6A679E8FDB2CD2B127D541E21
+:103CF000B106125DD4FFD1A03A3ED806BD3B0F52AB
+:103D0000F4F5902F11797415BA1E3FF6E47FACBC20
+:103D10009DF0FC4611CDD08F15BBBE5B793B8DAFBE
+:103D2000DEE76C863E3D626D2C84DE5D581CEFAF95
+:103D3000F660FE9AE3F28B9E7820CDCDF40E645AA5
+:103D4000D279FE67E2BD8A4D360FD67515EFAA1EF1
+:103D500037E6BD685E09FCA2DFAF0C7D6607FD5D3E
+:103D600016D1DC69781BF5A291F57CE5AE5F7FA5E5
+:103D700026A23CFA11D6179551FB0125FA7E49F48B
+:103D8000BE40C2A084D42F10F0D6F7A3893E9C97E2
+:103D90001020BC7AB0B8C83872CDB6870634C16F6F
+:103DA000D8F45AA292D3BA1F60ECA3B484E63E863C
+:103DB000B8EAC5E6E5A9A838B0A1C7DC7B1599B477
+:103DC0005827CB325B3811FE7ED9061BEB91B2A788
+:103DD0001FDFF230E4ED4387A7871BF0193BF44166
+:103DE00099E26B5658BF8B4465702BBF4A9FFEBC4F
+:103DF000F011F8D719AA9840FC5AF4EC59D9DE27EB
+:103E00009A63A87DE9CEA642AC0FCAB478BFB30DC1
+:103E10007E8D09BD646F8C6F835FA1A6428E536D4A
+:103E2000FB96F971749F223A645FF87EC986CFEDE4
+:103E300042AE0F9A539225BD60EF2A436AB13DE925
+:103E4000C2F6F4FD49CFE771BD0BEB954BF1F124C0
+:103E500068C1F29E2090C758F291233801FCDDB171
+:103E60002411F94F5F5AFD52EED7AF48839F576236
+:103E70000BA4B9B894CF4B1EFD19CBE302C59FE646
+:103E8000E2BC2DD2AFF93CDE0C8CF3E675D7F238EC
+:103E9000E70B8DE5B164BD5A14A4F2AC558CDFD9A3
+:103EA000C6BC796890D4770E71CB00CC93B3F4255F
+:103EB000D8F12FF5757DE06DB99E7688294991FB83
+:103EC000432583A45E0C88E021D881CA061BC7293C
+:103ED000D4B7CE16E23BB7665BFDC8DFA0F107742E
+:103EE0007A293FC8F58B1B790C95F88BECE998B7CC
+:103EF000C67568CCC1F75BEC3751BF5F639DE83195
+:103F0000BDC774FB72A32356B982CAB4B6F3BEEA26
+:103F1000CFCF7FF1B68890A7CAAD5FB23C89745508
+:103F200024A54B18FB11AE39F1FE24A2DBD7EF7E9E
+:103F30006647FC3B906A113D806FC3E70C0B4F7BDB
+:103F400037DA1BDFAFDCEB10E1C879BBE9F3A87906
+:103F50006DAE17C2CFF4AC14496ED8EF2FEDCD85FE
+:103F60002FA01FEA7733F5339FFCAFB0C9BF6A2E8D
+:103F70007C04FA64AFDDC5F107F23FC31172737EB2
+:103F8000BF53DFE75BA0EB83683A44EB87FBA2F407
+:103F900083F1BE58D7F6FE52AB5E08303DCB6C22A3
+:103FA000003FA3EC4307DB8FB2A7E57C14A44F7B53
+:103FB000D0FC38BEFDE5F76FC07A36644B9DC0BDBE
+:103FC0009AF56FC9339FF3B8E612FD633CD0BFDFAB
+:103FD000DAB1FE4D1F239A1D84FFF1D55E3BE4FE4E
+:103FE00082794CCFDB9CC7AB15D66FFF55BD4BF428
+:103FF000E6FCC04BCDD70517D1BB7551743D2B7274
+:1040000092905E2D5CC55D78FF208ABE065DA3F5AB
+:10401000E8B441EE36F528FD7B5F44D051884696E2
+:10402000E36F482F625FAD62D3776CD788ACCDC8A1
+:1040300027AF087EC5F00AD835865F9A8678E58571
+:10404000E336D333BAFE4EC818FD5FF4471BFB05B9
+:104050006575326F91DEE3754725E2F5DCBAB63E51
+:104060003335120E46C1A1A8F6BE28B828AABD163F
+:1040700005FB4DEDCBF6BECCEB2CC2DBD4CEB1F4C0
+:104080006A5E875CE85704791C95BBBEB207201FA7
+:104090009D9AEDD08BB665229040EF37BFA8B2DF76
+:1040A0007BDADD9C083F65458CF4E34EBB7438D960
+:1040B00080C5EC62C2E37460800B7902CD3132DEE0
+:1040C00072BAA839313962DDDE54A726BAA97D63F8
+:1040D000508C6F3BCFA586E753A3B858BDF4E7C615
+:1040E000A9DFEF90F99F5681FCD8C6EA6F77209E32
+:1040F0007498D64FF05FE6555F9F88FD97D375DDC6
+:10410000AE998E75E0ABAA9069D63E3BF220E64AA6
+:10411000568A2322F0E0081A9F9A9057FF02D6573A
+:104120002428D8FF9CB73ACABF11454961ACA7D72C
+:1041300044E72B04EDF06F16909D853E2A5967AE3B
+:104140005F54779CE7CBA2A8F9A2E971E3E8F9D222
+:1041500075B09EB7E0155E3D7F92F3F44E1F545943
+:10416000BE5A96DBC4CA5499278BFC92963A997F23
+:10417000D3B257C222A0E7F5E8F3D6A0DB09CCA75B
+:104180005E17F75B4EECFEF7C1BF84FCECF97800DC
+:10419000F6894FECF9B0E70B809FFB6BD6C7E2C204
+:1041A000F663F67D378BF1DAE710C0EBF4BE57B259
+:1041B000E06F9C7EDEC1F905A79739D85F0FEC4B05
+:1041C000E0B8C5E9CED21FAE79F1DB018D6C8F97D7
+:1041D000331F270EB64BBFAAEE3FD83EB6D439DC0C
+:1041E0001847E5BE389E5795CFC7F0BEDAE917BF2E
+:1041F0001D1C198FFBAF8EC7D8573F9D20A63F03CC
+:10420000F9D5FDFFCA17863E5E8DF5F2AE97EC73C9
+:104210009127F2A7FF3300FAF5F4332FB1FE3D6585
+:104220006B7C14B1CDE97B321EB10D455C8F3ED65F
+:104230005188AFF6CCB811F3E742BA483A9C263A17
+:10424000605C449712F8E517A347E5BF2C3DBE9A82
+:1042500025F5DC10817D9F56BA283EF93C81E35557
+:10426000347EF97CDFB703A0872E35DE7BFF1F1B72
+:10427000EF53186FFB7FC5F14A79CF1DEC66FCA2A6
+:10428000E5FE42B97EEEE70CEF48F030BE9739DF2D
+:104290005FFB971DFFFF0CBF8FFECB8EF752FC7E9E
+:1042A00055E777820BFBA0A75FFC3F59E2478CDB09
+:1042B00039E45F755EFFF3711BFE7C81EA39E8A586
+:1042C000F6AF89D0BB9E6CF64ADAF447060D518CE6
+:1042D000B838AFA7C6E02F37DA0F5C8E734C01F207
+:1042E00027B08EA9891F78E02D825F213F41E57DAF
+:1042F00059194F7A25DD1B94F15DBF403CABE0AF0F
+:1043000073197EDDFB9303C82B2954653CE6E56AEF
+:10431000CFA6061AC7CBC91637CE958DED34F7F068
+:104320004EAA7775545D589FD574CA75BA23F01B91
+:104330001B6F5E675D1DB54EFAA9DB5C3F5E3C936B
+:104340008AFDBAF1393681F33685681FB1AE4C1952
+:1043500022CFF7FC54D42E77C5FF783ACDD5E94467
+:1043600074E17D9B402755CF7333D34D806EA9A058
+:104370004B2EFBEF01E139F016C156DDBF12FAFEFC
+:1043800063A133610BD6D10E51100E127CD66DE5B0
+:10439000F3935641EB61394E5E4747D34DE8EB6AE4
+:1043A000ABCE82B19DC68441673CEF926E7A9FC7C7
+:1043B0001D4DE71F4FD7FD9D9680AEE9099E20E475
+:1043C000A2D3B3A988B3D6109D15A5959E069DA22C
+:1043D000E99E8FCDF541ADF4EE64F55A31CF46EA52
+:1043E000FEFC586BB2843B35A8F25C5E90DB8FF923
+:1043F000DA63853F323A3E99F343857E6E42D5F7C4
+:10440000C39161C778D0FA1479B693ADDA92219C42
+:104410005FEF120558B7168810E2B74ADD2BDF614F
+:104420007D84F32245BCAF59FF01E05E382F86FC46
+:104430008E75D613A6F36E51E72526E5EF1C0D7E8B
+:10444000CD594ACF10C772B9EB311F8BEF77B8C186
+:10445000BF4ED606AEA7B596AB7A2876AB430CC74F
+:10446000CE234F3F03ED5E19CDED970897928C74E4
+:10447000BB109F778C77C97C355ABC7E03D8BE3C75
+:10448000C15D23E32602F2D41D65577C5FB64F1F42
+:104490004BDF43BE9BD0D85F8EEDCE9120D1552906
+:1044A000E2FDF72EDD645E44F30A07AF778AEFEA98
+:1044B000DC137A694281396EFDC510B9AF69945336
+:1044C000F3DD729FC2E249C777E62CEFC3EB2F35CD
+:1044D000B6A87C37E8B8238EE5BC78E54D1307D144
+:1044E000F78B77A47880E6B1493B07CBF6337EF6AD
+:1044F0001E3DD7B6C6F0F39FE76B8F0F419E81E25A
+:104500009EB59B1ECCB9F6657B3A75A185269F4466
+:10451000DC715260E71BD8E79C344DE5F69384CC00
+:104520002B15CBE378DF7C62E02B6B3A7D6F222D7D
+:104530006A50DF14E3CABA85F02FD6E3CD7FD0E707
+:10454000A11A2BB467E28157E79E5DE9F94421F394
+:104550009BA3E7ED71BD7D97311E772AE8A3C4B810
+:10456000701ED6688FEFE0BB5FE9F4785E2F0D9880
+:10457000E8CA71F179AB1C4DDD1251DAC2BDA8EC6D
+:1045800033AC601FE46D425751B816DFBD4D151BAB
+:1045900019DFE6628EB327F476830F9AD0CF77AE19
+:1045A000E9C1FB394DA305CB4FD37DD906BF393FB8
+:1045B000C958CF358DF6D4237FAB79B4D3B3D1832B
+:1045C000FC9650187194436BE57E4D979A7077E88E
+:1045D000D966AFDC07F97C69AE1B7272F303531323
+:1045E000A13FE7AE51C30EC8FB6A73DE9270793803
+:1045F0000F7C6EED683BD6AFF3E27D768CEB4CBE64
+:10460000F611F8659C73EC0B9C708EA7B6F875AC30
+:10461000FBD4449ACF987F567722D6D5D1794F953F
+:104620007A7E9301FF3A4DFB0CDF9B93E4DE01F9A8
+:10463000F87469378EAB76CBD7CF575AC3DD419F1D
+:1046400047692E607E3E3844CADF8476AE9EF12CE8
+:10465000BF3102E36AB2B97A429E9B56C45840A762
+:1046600009CBA41CDF6D95F32BE8735B02F4FEB35A
+:10467000789FBE3BB3DA5AB481FAE9E414D6847663
+:10468000B4CE1DA63D0FFE4C0C541FC2FA7AAE6E7E
+:10469000AFE6AE96E7C1BA8C917C15D686B129F407
+:1046A000FCC8E6EC81C87337E466FEB082BF0F89B0
+:1046B000E0FF84025F617BFACE048BBB057A78DE73
+:1046C00034E5A56E520E7E18C2EBF93A9EE72DA492
+:1046D000271CC93807D82061E4AB426FD43EE4738D
+:1046E00046ACDBED6217D7DBE7C97CD42EF670351C
+:1046F000E75FDD225CCB08DE427E84D526C4D62A65
+:1047000027974F5691BEEB21C4F6AA74867754B909
+:10471000B90C55F5E6E7CF547918DE5595CFF09EE4
+:104720002A1FC37BABC673F97C55113F8FD63F73ED
+:10473000E3E7B33E71F5245E0FBD506E66B9092FF5
+:10474000E81FA770DD85F34742EABBE4DE52FF08AD
+:104750005D1F75ED23EF03E8962FF9615B35DAC233
+:10476000E737AD8D1990BB71EA89A79F43BCA3249D
+:104770009EF3B25A4423CF931661E173D9D03F0E12
+:1047800092BB2E778ECF8ECC3BBFB14411D608F9A9
+:10479000BAC91F23AC11F669F6D264133C73E93B26
+:1047A0007FEE40DFBFB1AB96974F781CBAF38BF525
+:1047B0007FA5E78FDD79AC873CA7FBFD86C8B84BAA
+:1047C0008B6896B0D5C9FBF18FDD9E9196A2DFD3A1
+:1047D000007E19E7A4BBD89B8F3E8179B842F52CA7
+:1047E00023F823F087E8F989CE9FE215DD56FE0213
+:1047F000F3DAE7F428F49D43B7F72BCCA7F68FE95B
+:10480000FB51179CAB4E97F6EB53D8AF6469CF0AB8
+:10481000A047C3D26E7DFAABB4C05DA8BF25D183DB
+:10482000130DDAAA0E810504AFF6DA3D2AE27A7595
+:1048300082EF5D201A4BBF226033DBB1C64EC988C0
+:104840005B1AE79EE3F2824E3E77451D613F664E5E
+:10485000EFFD22037AA9567161BF06E7349DEDA0F2
+:10486000DF14DE1F451ED034B29737E5AB3C3F7FE7
+:104870003FC4CAE559D873A26B8CF0707C66DE6ABF
+:104880006A0FFD58EBB5CF8FD0BF73F4E7737B5B36
+:10489000B8349E97E17BD83F5CE59D0EF9E888FA35
+:1048A0001C9403A703BF8EF185562562FF777EBE59
+:1048B00055EF5FF67B169392E07B7A77B5DF9CC36A
+:1048C000E7ADD86E19FDCCE93D706557D8EBD5A39F
+:1048D000411D5163F3A4A752BBCAF3DF71497FC4E2
+:1048E00029F3B3CB2E62378C38DD11FC29CF3DF292
+:1048F0007817ED786A07CE3D2CFAD8C1F66BD11542
+:10490000D22E899CE0E0A91CD034C7C5C73E75B241
+:10491000FE2EC2E724CE2521DEBFEB333BF24369F6
+:10492000DAF8933200AB4DC8338D8ECF1ED8F171BB
+:10493000629B71F15DEAE5C5C595EF1361178CF1D6
+:104940008C7BF16C1AFCAC4AE51CEF3355BEB822E7
+:10495000ADADFCB0E8B8F8F9F8B958FD15CED757A9
+:10496000DE71A4CDF879741CF0F1FCE8FD88F80242
+:10497000E889B307D520F6D35B823D92441BFD1B2B
+:10498000F1F3CAB5F4520AE6A53B09FB61A72FE291
+:10499000971FC997F6FDA41E6F3FBD5DE5F5D2E9EF
+:1049A000ED0941F8A715DBEFAFC73E65C52685DDEC
+:1049B000F372D1C0F4223A0A67A41D43BE5B0A9C7D
+:1049C0006B7712F495815FE953097EC8D5C290E2F6
+:1049D000DB4C78B438DD49ED23F03800B96A8F3C00
+:1049E000C0D060A6AB8EF7F3BA1E34DA2DACBB9FF5
+:1049F000E3D2D4EE14FB3B7F88139C27289ADF0078
+:104A00007EC7D7E57AB0AFB830B4B382F33BB6C750
+:104A1000B9108738A6E7391BDF69D0FB6BC897FE52
+:104A2000C9717DFFEEF80E79DE1C78623E1D53CC15
+:104A3000F982EFEBEFBD9F2FF7CFEEC05EE2A0D67D
+:104A4000F60B434D89DDA9FD977BDFE1B2516FBFC6
+:104A500030BE6100ECEE97BBE2783FFECB5D8F1479
+:104A600022CE7C32343A15F26F7CFF54BE8DDB9F30
+:104A70005CA78E07BD4450E6D99483AEB99178A661
+:104A80006C086447CE33996F747CD7B389969C5673
+:104A90003E963BFD4E9CF7ACDC754B11E4B8DE2630
+:104AA000E969DF35398063CC95755E01F9E5799662
+:104AB000C1ED575922DA396C1EF68B6D7B8B7D6800
+:104AC0006FC4A117EFB6F179C15957B8AFBF11F351
+:104AD000F0351BF361711FF7F59C8FD4A072FEF2C5
+:104AE000E26C1186FFB1E4B6840DD80F33F09D95CA
+:104AF0002BE77BD92A45F8685C6541790F4747E287
+:104B00007B00394AE98D83903FD9941DBCBB672A4D
+:104B10009FDF0DE3FE1623CF94E6714F9C73EC30BC
+:104B2000B41D8FFBC119856CEF0ED945007A21F0B9
+:104B30008CCCC329EB2AF3A31F86DCA3BF76E19EAE
+:104B40002934DE133A5FCBA6847B222FA3EC990C89
+:104B5000CECB386197FBA5788EFDE2B281F47E3C26
+:104B6000DFCFA119EF2747C851D91C8F1BEDD47691
+:104B70001EB7371EF8BA4EB1DFBA3B41C06FB53C25
+:104B800097A0E757C5701EB9F15EBFA152EE8C7BAE
+:104B90003FC40D321FF3419BCC577D707306DF7706
+:104BA00061B47FD0A6CD80FF8471C05F5F68AFED38
+:104BB000897D1703DF8589B58CE7095DCE17C6D6D9
+:104BC000CABC70FD1C31DA036ED2F3D89BB73938FA
+:104BD0007FE55846C337C0F7D8B63EC88101BDE768
+:104BE000EFE57AF21F899F8B9E7484517F749B8CB2
+:104BF0005B1FB505BF811E3EBA3E85CF471D6D1FA9
+:104C00001CCCF9018ACB02FFECA8A2C33617FB9596
+:104C10005DEC0453FBD4586141FECEF8296B67214B
+:104C2000BFA1659303E2298E6D79288DD735C29D8A
+:104C3000C47936075501BE1D7BF23FFA44FA2F4670
+:104C4000B9689339EFAE295B98EEC9B97AA89C97F9
+:104C500057EBF4BD66A8B453E571A107BBF2F82485
+:104C6000BD893FBCBEA3199AC0F9134FF750A037B6
+:104C70001E16C19F7F9CC7AB6C37F2E6CB9ED9F660
+:104C800006F66B8F594403FC0FE5CEAD3FC77D1B85
+:104C9000A9BF49623B24C4261EDF51973CA74A1393
+:104CA00096C7BFB08384174DDDDA13703DD91C85DC
+:104CB000E6D7228BC2FD2FDAD39FF3ED881F16DED5
+:104CC00027DBA9EAF8904F09FA6D91F9CA13DA05C2
+:104CD000B7C0DF6B5EDF4DE0FCFA3875DD00F0EF4A
+:104CE000CCA6380BE4A9FCAEE149C341B737550166
+:104CF000FFE38CD5D321328E104DAFE83CF0E0506D
+:104D0000A99FCA700F0ECDABD23DEBF9BE9052C831
+:104D100025E8F2A4C2FBD8A52B873FC472FA864DC2
+:104D2000F4A07E4F84EE4F8CE4CF3D43A55F70FE30
+:104D30003B760FB72FA5F6F2FDD71219CF2D36CE41
+:104D40006B89E6EB65BFFFA47A59EF9F1F7F88FC54
+:104D5000820117D2E18C68F8F9C7F4FDAFB7C7F04C
+:104D60007A9056007C8EEDB82D341FE33EFE740C15
+:104D7000EBAFE3C9524F7C49FA34D00B785CFD5B52
+:104D800096D3B7A7F279BF0541F3778D7E7F3B5469
+:104D9000EAF1F2144F12D69DE56F4A7D48FCBA86BF
+:104DA000DF7FD3C6EF478FA3427FEFFC3C7D3A8E77
+:104DB000E5E27847C98FE33B7AB17D6A4A76099686
+:104DC0009B6D36596F0B65C10F3EFE742F6F4DC43E
+:104DD000778F2787B25C11CF9B6CC19543A43E6D42
+:104DE000C6BA588449D50E467E91603D6FBC57EADD
+:104DF0005CDD003F05F9BD8307721976B4BB304F07
+:104E000077423BB99EFC529F779CB39AA6E793B337
+:104E1000DF13B2438F6BBA7F58B63D3ACF57D6D720
+:104E20001BEFD3BC4B35F28A2DC037644FE7788334
+:104E3000703F43F8962EBF6521F2C74BFDF7DD08A2
+:104E4000FFA9D42AC6DB09AF2645653C9A62C4ECAB
+:104E500029F02323FB89F0DFDE6AED47E0DEB6327E
+:104E6000FC41F3E0BDA16E293FB0A4F4BDB2E5CA98
+:104E70006A7CDFD02F1C284C6BA513F25A91DFD32C
+:104E8000345AAFBFC8B89B6CB23E7ADC063E478747
+:104E9000CABCA0A66CF76F47802F7F51F97CD799C9
+:104EA000EF7393DAB5E1A7B5DA7B7B6B9E2DE1FF5B
+:104EB0000D7C6BFACEF3BABE2B25FC8067CF75E66E
+:104EC000BCF2DE9BCC70DFED66386797191E506729
+:104ED000863D07CCF021BD5FACB3710E19EB6C942D
+:104EE0005867BB1D729D0D18EB6C945867E339D65B
+:104EF000D980B1CE068C75366083DE586F03C67AD2
+:104F00001BF5BD86497D2E7CE134E46B5658649ECA
+:104F10002FF1C3C7E79866D84DE7524EBF28CFA5FB
+:104F2000903C487DBF309EE7C9C36831147649CEB6
+:104F3000A7D4E71DC165F4DE38B7963C0C7662ED68
+:104F400057F32177155D1B39EFB569C52B3DEFA7E9
+:104F5000768D4A82805F51B1F6AB59F0A33AB8B56D
+:104F60000EC3089FCAD8869543386E1F66FDD15878
+:104F7000ED7EF34AC9478EBF14ABB8F982EA4BDA2B
+:104F8000B5993F149D772E569BF3CC2F95771E2D08
+:104F900007861FF898AD39C3C5EBF4118F22CEBB3D
+:104FA000584970619DFE598C5886FB8002AFCA3CFF
+:104FB000B59683369937B05AD92822FC93413ABD29
+:104FC0000D78EEB95CF6C7CFC3AB158BB84288EE4F
+:104FD0005A7313D6D7674A2CEC779F2929286C0F70
+:104FE000FF8FD6659813B86F2B125FDCB715293F7A
+:104FF000B86FCB7C6EA2A3A93DEEDB329F9BE86B22
+:10500000AA9FBA3AD7543FAF68B8A9BEBB90F82D53
+:105010005928F19B47F6C197027819E72D2E01EF29
+:10502000C84FC952022B592F6F50F8DCB87BE9AA40
+:1050300042D0E5048933E20886DCCCD5ED8BB0069E
+:10504000EC90BBB3A9B2FEA8D2F0C55DF4DE496F07
+:10505000ED165C8572D2B2EEC1116EE4D76FC872E4
+:10506000D13CBC5509A541F5140CD234C8D9616BAB
+:10507000E364DE4FDCD9BE5D35FCCE8383DEC847FA
+:105080007FDB55CE9B30E425CB26E3741B689D0166
+:10509000FF6A43ADCCE7DD509B12DB3D62FFC518D4
+:1050A000670BF820502E4B4BE5B89068C038C86F9E
+:1050B0005F06BFEDCC41E9B71BE3E9BE3CDC690903
+:1050C000D5DFBA3386E973585F379CE8F3D20037EF
+:1050D000CE6F54EDCD52E10F58B66FC13A22215533
+:1050E0005B0AB92FD9D0E3AFB8AF6BD17BAAC07937
+:1050F0009ACFD78C491C4ADF39F6B4CD3381E0BB57
+:105100006A1FB7639DBCC81AB4731EE6B60D76E479
+:1051100025FF64EB067E3E7F6B31E75D2E107E5EE1
+:10512000471ED1CF6519E32E2950D6B948BE3E1A85
+:1051300026F56349ACDCCF2379FE33C67566ABE256
+:1051400085FF38AD68A7BD989EDFA7B7734F9F3E18
+:105150000EF2D71292F76DB4BCAECA7BC4A6A932C8
+:105160002FE622F7F34C3D97CDF23DED5C3F5E67B5
+:105170005D1BEE23D7B139527FB4D4A9BC1FD7F23F
+:10518000FACBA953F1BD3A1BEFDE95D81BE4F97FAA
+:105190008BF0E31C817B7A8394AB6CE187FFB7E4EF
+:1051A0002FEFD463DE2DC976BA311F8A46A826F9BF
+:1051B000AC1C1B6792DFE9A29DE91CCD75482A89CA
+:1051C00080A74DE8666A7FFDB47E51FA60606B3D52
+:1051D000EB836151E7000B4C70399577403F89AB09
+:1051E0004CEF958B29ADEDB01EDE24FDD6F25DC9E6
+:1051F0001BB12F5E6291EBA1E99A7C5EB1573E171D
+:1052000022F6FCB9749CC7477CC0746E5BDFE74331
+:10521000BF1C0FECD6C0719DE60CD29744D1F2DED4
+:105220008D76C4D3C85D6E469CB43C4030FAF58997
+:10523000E61A9C1FB14AFAC67B5C5D9765B4CA4505
+:10524000C52E73BE55C5C177B89D91CF185D4F9ED1
+:10525000EFCA8EC07B82E2E57393DB9BEC88074D3F
+:10526000D33AF1BD14D1F79F95859A18CF6BF7A665
+:10527000B9B06F5B1175EF59A7E16E699FF4F83F04
+:10528000EE0D927E42835DC66DE3F75B78FEC97BCF
+:1052900076CECB658945DE1710459709DEF7B8BF96
+:1052A0008E19320F0D74B146D0255A8E40276B04EB
+:1052B0009DE60B49A7F9A44D820477849C45D2E76B
+:1052C00047D26B01FEA0FA057B9520F2DFA2E933FD
+:1052D0005F6B64FACDD7E2FD41D785E3A9B8E383DC
+:1052E0007AE8A71D19F29EC268FA2D100D2BB1EEB7
+:1052F0005D4076239CCC726177F23A4DF1C06EBB73
+:10530000F31BED36A9CF38CEDBF2FA3B3CEF5A3C2B
+:1053100034AB211782EAA97DBCCFDDBCAC8D3CDF6C
+:1053200029E764FCE4BA73562EA74D30CFBB6BCF90
+:10533000A5F1F31F4B970AD019728EB85E621BF766
+:10534000E621CE9778E1788DFD10430FB7FA75E628
+:10535000BCE58BF97FD171C2DEC3F538E12031C8DD
+:1053600094B77C11BF233A6FD9B0E32DF1D24E8EA2
+:105370005373DEC4D9C6E257555EA7BBA78FB7F0FB
+:10538000F9F157E57D77DA8AB34D904F2DC1C27A96
+:1053900070714257BED742D3E376463F59D529694B
+:1053A00088FF15C7B8381FBFB85A2D82FD2AA676C8
+:1053B000EE88762B9777CB825DF8F4EE5E8F0668E9
+:1053C000BE7C7A5B6A1AE2FE9FADB0A592E63CDF36
+:1053D000EED315E3B2909FF1D97D8EE9C136E85343
+:1053E000345CDA81F23B3F60BB75D2F27AE2747AC8
+:1053F000BF6CC5EE4484EA4A57BC33D8452EC5E19C
+:105400003CED9AE1BCBFBA610BDF07EDDAC0F709EA
+:1054100068484A6E8F7D8815CCF7458ADCAFBE554B
+:10542000097F7125B53B11735FE2F46CDC6E2A389D
+:105430004FE3ECA604FD3C5A35E70D9D88257F809F
+:10544000DA1F8991F43CB233C1C37762780259BC48
+:105450007E6B2FF7774A2D75D7019F6B52356DF80C
+:1054600020E011DC92AE723B3EB7AE55F7486A2B96
+:10547000FE61945B743B0D7F1B25FC6DE4CBC0DFAC
+:10548000060C7F1B25FC6D3CAF5C6BF6DF6ED7F71F
+:10549000FB8C7870979A662FFCDD4081E8ED673BC6
+:1054A0003BA1E0F7B05BAF4A7F6189E259D5C8FE06
+:1054B00052422DD69D3556E967073E91E7A22082DC
+:1054C000D04FBF50FB7AB09FFF50DC9D8FA1FD52A3
+:1054D000EC0FE5E11E53F2BD22E4F5CA734E1179DB
+:1054E000EE7634396191F0186786A9FD3857B6A970
+:1054F000FE27E97D4CF53F757B4DF0D5BD879ADAE7
+:105500004FF48C36C1D7E4FFD4D47EB26FB2099E7B
+:105510003A7E86A9FDB545C5A6FAEBA72F34D5CFAF
+:10552000D06E31C13796DC666A7F93BFDA542F8420
+:10553000FF09D0C71790F7AAD561FDE4C0FD2F4E33
+:105540002EA9FE0FC8631E4D22CDF7AEFCE5677C89
+:105550008FF57EE435D38C1B31C6E26F2B8EFF07AF
+:105560005DFE6347FAB60DE7756E03DF8B89D82DB4
+:10557000E46E1FECD4A0D6E79DAC46DCAA2143DE46
+:10558000876E6E7FB17623E2F69F7193C8F5AC3BD0
+:10559000739395F4D78821FB73BB21EF79C4E0594D
+:1055A00056D2372386EF7FB62BC1FEBA3B6771FD1B
+:1055B00015FBCFA0FE1F75C3243C55B06B72FB8852
+:1055C000BFDD84FC941157765DED91719136CFB7B4
+:1055D0001B25E88473E1A013CA30C93DCAFD24F736
+:1055E000280F90DCCF23BD564F728FF220AD33F1E0
+:1055F000FCDF689D89F2755A67A27C83D697281BC9
+:10560000687D89F2EDAAE95CBE5BA5F17BEF579559
+:1056100070F941959F9F7F54B594CB4FAA02FCFC33
+:10562000C3E1328E108F7B9313FEC9BDC97E17DF95
+:105630007F50A3DB2D51A7E7D5ECA7F52BE8D96860
+:105640004DFEC2D9BABF78F1F5BE557C11E1B74D18
+:10565000B6FA3E97FCEDE462BDAF3F2FF56AC7A0F6
+:105660004FDECB9EDA235785BDF3FF3989EADEB3DF
+:10567000B47D9FE43E5D5E3E1EE13B8DEF8D741E6A
+:10568000E2FD74770679ABC31956C07F65A08C5FC5
+:105690008EB436D4A0BEE63BE1C6BAF9A584F7794C
+:1056A0001FBC86DC659C3F56CEC9F5CA287DFFBE6F
+:1056B000E63BB97F3F0AB853FD4897ACAFB9992C88
+:1056C0009D17F521FEFE289C7696E7DB4C793B631F
+:1056D000CF358CE1FA78BB1BF9A6A39C61F93DA7F5
+:1056E0007021BEFC52C21ED9FF38D9FFA6EFC2FC02
+:1056F0007DAC3E91973DD2D98ACF32C6AF41DE37DD
+:105700009723DBD7E8ED4769D47F32F0F34BFC8A6F
+:10571000A9BDC49FF5DC287C3319AB6D591F9B2EA6
+:10572000CF278F3DA7D77BE4783B58258C3325A81E
+:10573000CF4CD1848FFACBCC141EC4DF46A536647F
+:10574000707B3D9F21C12ABF97E491F77175FFBB24
+:1057500026F7038800C0DFC84B32E66DE776E10C20
+:10576000F8799D17DBF97B99EA4E2FF4F5A75EAD2A
+:10577000EF08AAB73A2D3CBE1A9F3C2FFFD68BEEFE
+:10578000CEB85F74B2EEAFFF13FE5F81F7473AF712
+:1057900049FEE392B7CC5658994FFF0F6D93FF9295
+:1057A0005E242F183FF19FF9017EEAFC570CFAE8BE
+:1057B000FC3FCFAF6591F5BA7C5CC8FF90E4B72E93
+:1057C0004FA39C326F02EDC1FF9156290F35313244
+:1057D000DFE3A584C287714F16D1A608F1F991863F
+:1057E000BCF8E5F9E1FFADFCCFB3CA7BE41C654E24
+:1057F000BEA7EE52F230BB5914E2DECD8D03B57D6B
+:1058000098D7C5E7DCF580E78AD18570CF8DFAA7F8
+:105810002E52AF7DDD6C036C3C7F1BED06B5D65B75
+:105820009D6FC741EF19DF31DA7DA57FAFB5DD4050
+:10583000FE9D8D25E342EB60BFC6575B396E4D9EE2
+:1058400009C307C99EC97C4E5FA2372D32FFD373AF
+:1058500060711EEE0B95E7B744BCF4ABDDF41FF4AA
+:105860006AE1F745CBD19F50B75BB1EE388B7C5ADC
+:10587000FA4E61AAD93F1F1FB5BF7E55CE97EC8F58
+:105880005F75897BAB7F3742F7A7B345F67FF2DEC2
+:10589000D08747B07EBEBC7B437B8B3A9683B1C535
+:1058A000329F8BC66F1988B88D4FF801170ABF1544
+:1058B00072305ED45AE5BAD277A2228F57ED4C9F50
+:1058C000AB45989F4F24830263720D890FE097E3E5
+:1058D00026CDC47DC06372C774C7F388FBF3FE0096
+:1058E000FC2A54ED6FAE88FBF3F68F95F36DF1B59E
+:1058F00032DEB4DFD9AD4D3FF455B2B7DD7B802E3B
+:1059000082CB3F933DEE4EE37E85EC31E0AB7A57A0
+:105910000BBC57E836E71D19EF5FED1A23AC2917CA
+:10592000B777570FF86327D0F9B5E45E63C1AFD7F7
+:1059300092878C453CFEB5E40E16593AEC5CF67F36
+:10594000AE7B5BF819F3A3B5BF42EECFB8FF776C1F
+:105950007B79FF6F345DAF1221137D27E8F4FD11D1
+:1059600074FD087A349AAEFBF475C57EE73B7B8CF8
+:10597000BC29C493BB2F6F60F8569B9C07E5CF4DA5
+:105980002C405EF4E2F7647EC751A002BBBB7438C2
+:10599000E33F6AE95061CDE5FDA800E85DE6947457
+:1059A0003C19786900EE29AF4FD18E83AF5FAE53BB
+:1059B000F9BCFDC96762381E7724F86C22E869C813
+:1059C0007199EA5ECDBFA7F19A2AEF59FAFEE52C4C
+:1059D000DC2B7A31B92679FE7AC4A036E4399EE40C
+:1059E000B9FF85F22C36C97B0CCA9C856DF2D9585B
+:1059F00077BE30D0C7FAC225C2B740FE2B845C1FE9
+:105A000055385F97F754128C73AFD17ED5E0586A42
+:105A10004FF576A7CC1736F89DE990F75866C6097A
+:105A200017E22042CBED0B7CFB76F7C58DE4FCC280
+:105A30009CED91796BA3C2FD78DF79FC4195F3DD94
+:105A40005F8995F7B837123F14F24F7FD2CF1FDF2F
+:105A500095F8983C444B1B8971A9DFABE8F7F51E1C
+:105A60008A48E1F8796E3CAFB37FE47A3D6BA4AE2F
+:105A70005F068801FFF4F711DACB7B8417BF9A1B0E
+:105A800004DE8BABC9AAA5F2EF5CF03D7135589FDF
+:105A900067B7EA9D51A227FFFEC598541BE799FFFF
+:105AA0006FFB7D844CA1F1FCFBCFFE4EC278F9E880
+:105AB00082DF49C84C5C75404B6DFD9D8CE8DF4929
+:105AC000C8D4EFA7166E693F8CDF47B852F8382F5D
+:105AD0007F5CBAD9AE8C718D3EE0E2D21CEFC9BCBE
+:105AE000443ED74D23F5739D97E27BB9D0F92ECF75
+:105AF00075420EF4DF3B09423E8DDF3B31F86EFC10
+:105B0000EE494D7BF9BB27FF6ABF7312CD9FE8DFDB
+:105B10003D89E64FF4EFA08CD262994E63CAE259F8
+:105B2000AE0D3E4DA7FFD81FC0B95CE5BF9F5FF724
+:105B300047CDD3B362F520DC537ABA58EAF58BD956
+:105B4000FF695EDFEFA16FB6E97ABFC629E321BE28
+:105B50001AAB881925703F21E7CBFEA246DE03551C
+:105B60006395F18000F115F7E27D1BFB0F799F2310
+:105B7000F947B68E88CBF8F9FD80DDE9AAF144FC3F
+:105B80000ED652791EF89045FE9ED4EC1CBF82FDC5
+:105B9000CB4E5DB5A7A0AFD245D1CEF91C97F70F7C
+:105BA000817E9FF5274716EA677591F7478A1CF9AA
+:105BB000BB4106FEB332655ED6B323753DEE9179E7
+:105BC000587B46CAFDC0048F8BCF3514E7083DBF14
+:105BD0005564CDEA0F39FE84FDF816B7F4AB1B6DA2
+:105BE000F21ECBC0AB329F679DFF6DF6FB37935F14
+:105BF000AB4AFF66EDBD1C674814D8C77D2CA6399B
+:105C000019F8F75A2B4CFE429FA0D39497DC6FAB48
+:105C1000CB04F70FA59BDA5FB1D76DAAF7867B9B04
+:105C2000EA730F7A4CF0A0867C53FB211FF84CF0EE
+:105C3000D0C6F1A6F6C38F1499E05323BB4A3A416C
+:105C400026693CB396B882F25E7C1927E96297FE1A
+:105C500054CD6D723D61E4AF6BFA3C88CE5FEF6C62
+:105C600095F9EB76BFB46B5ABC5CDFBADA0997CA18
+:105C7000E7621A18C6DD109C371E30E7997772CAA2
+:105C8000F59565AC5C7FD8F53CF3D8DEF2DC8B9102
+:105C9000574EEB0A1FE8DD5D34CEE0DF2FD0EF1367
+:105CA0008D96E7BF8FD4EF738AC2BB8B5D9EA7AB87
+:105CB000B9CDCEFBE75ABCBD4949BC109F6E7A7E78
+:105CC000E46667DBF73E39474939BB21AF488CA210
+:105CD000768F92D962FFEB82FE3C8DD07735BFB2D2
+:105CE00073DEF8A5FA9B75851CCF4C8B65F6E41C1A
+:105CF0005E0FF23940A3DF74F44BEDFAF874398F7C
+:105D0000EA6F565233DFBB2692EC6EC8AF16BF92D5
+:105D10006157AC4856DBA07BEBB90C99A77FD3EA5F
+:105D2000D0BDBD08CF99F65A9BBC702068833C4C0F
+:105D300028203FD28BF8EB43EBE3891F8FE207EC7F
+:105D4000C8CFE8B2AFDDEC4077F899CD2C0F4844CE
+:105D5000C17E22FC4F75602BDE6BAE9479DFBE51A5
+:105D6000C2B8FF80F16AD1E3232D2274FEFC44A067
+:105D70000D79D3E2EBF91C826BB194A7CE11E7AC9D
+:105D8000B0FEFC9F3A2F21B0434AFDD86A853CE71C
+:105D90007809FA19E754DCB7D88A36C6E3BC881804
+:105DA000AF44D0E1892BA55C2E061DDACB76D04717
+:105DB000176B477E5F12F6175A843BC97589B8FA8C
+:105DC000FFC4F833AD32CE90E594E7453A5B35D663
+:105DD00017F6DEFA3D7717C8BBAE37F4385927AB54
+:105DE0009CF79D3C725E5FA8170EF0F7ED9ABC37EA
+:105DF0002D9ABEFC2F22AE629C5F891D2BF588A1D7
+:105E000017CE9F43E921D7A1365D3F04BB5B38EF36
+:105E1000E0AE04F33C7E7C94A46FA13E8FC9CE27F4
+:105E20007A079BF484C0BE5ECD0A95F504E9C97A71
+:105E30008DF02CC6BD2CAED6DF7BBBF90169C74601
+:105E4000F98A1EC4BEC99C3536B181F715E4FDB090
+:105E50000BF438797120EA7E16DD1F3FBB5A71E1E1
+:105E60007720E6AE32D72F88FFE213AC1F6F8EBECD
+:105E7000A7C6D8AFBB441CE0FE51BAFDF7088F9E01
+:105E80007FBF0CF89D0DCA7BAFCF9F57D2E33F2D4C
+:105E9000C167257C87E07851B45F60C06EEC9345A4
+:105EA000DCC342F48DED0DFBBEDCDA667EA341DF80
+:105EB000F3791EFA3E1D95CB56F07A46E637903EB2
+:105EC000E07DB913540F3FF044E00CB73FB12B868F
+:105ED000F34A4E7A1B0660FFD6D8A7EBAEC97DAC5D
+:105EE000965D0932BF21DE22E1ADF21EFB457F0F38
+:105EF0000EC03AB631F0ACE99C83D668DEE78B2E53
+:105F0000B5EADDBCDE3C9CA7D58D427EBDD5E3F471
+:105F1000107C77FC7EBEA76B02AD1FA1D79097B215
+:105F20002255E2CFFA2B7046D2CF2FE9770D397A7E
+:105F30009C9F27487B228E2968554B65717828F7EE
+:105F4000FF63F7C1A69EF3CAFDDF73C3F97D6DD56C
+:105F500050867B079B477F40FD5EA7C5BB1147BAB4
+:105F6000B6E617E362E9D38DBF8F5FC16567F3F9CA
+:105F700001A3FC58B7238DB6B6EB27E8FA67E19585
+:105F800086BE96F2BEB85AE17DB5C59071C0F7CA1B
+:105F9000FB390DF84CAD0E8F93F092151286698285
+:105FA0001F3C47FFDDB32D7AFC05E34789F1232E23
+:105FB000B05D8FCF60FC28317E3C87BE020C7D0532
+:105FC00018FA0A30F4154AE82B3CFF3C790CEF6BC9
+:105FD00063DF6E6CC47CC2BEDDD888F9817DBB48AE
+:105FE00018FB7691EDB16F17598F7DBBC87AECDB4A
+:105FF00045C2D8B78B6C8F7DBB4858E4FFB415867B
+:106000005EF34D36C153693D3036623E63DF2EF29A
+:10601000FBD8B7337D4FBBC5F4FE8D62A9E97DEC9B
+:10602000DB45B69FBD5431EDEB09D1CC767DEEDA80
+:106030001496A3D7BC451957B6E7DFA9FA99AD2B3B
+:10604000EB078E632C2E8FF5487ED78E97FCB7C852
+:10605000F3114A33FFBEC0993BEC121E67CEDF3608
+:106060004AEC7B8DB5C97D2F94D8F742897D2F945A
+:10607000D8F71ADB43EE7BA1C4BE179E63DF0B2566
+:10608000F6BD5062DF0B25F6BD5062DF0B25F6BD75
+:10609000F01EF6BD5062DF0BCFB1EF8512FB5E78CC
+:1060A0007E88F09817A1C7E0AF7737AD33490E4D22
+:1060B000EB4C970986BF1ED91EFE7A643DFCF5C8DD
+:1060C0007AF8EB9130FCF5C8F6F0D723E11B46B91E
+:1060D000799EC16F8F7C0F7E7B24DCBF36F067C456
+:1060E000D626AE3B7500656382F228CE1BDE70E5D6
+:1060F000B6D9D8BF6C8C51B29249A7DBAA77CC1E17
+:106100000B7BABE73F0E10CD16E81F0D8BC93C3E55
+:1061100067C879A5FDBFCBE0FADBF5FB11F81FF1ED
+:10612000DDBB4BF0EFCE18FBEDC6FB1E32DB288D3E
+:10613000F6AD70DBEDA2FB37DA716E55041E38D177
+:106140008CBC19EF1DF103B10ED9A2FF8EF096653C
+:10615000322F3A5AAE7EABEBA72D969DFB710EA661
+:10616000B958F1E0DC47F75A8DCF99F59F292CAA51
+:10617000B7753CBD1E4BE4BCDA5F5C29ED9181BF75
+:10618000111F257DC1E7074734378C49A2F65A60B5
+:1061900034FF0ECE04BBD07F2FD83F0CEBC97E015D
+:1061A000C5B73142CEABF5EF690189C7138F4D9268
+:1061B000EFC5CAF79E782C91FB9FB45CE13CB3110C
+:1061C000DB850FE794EFD1F1EFB73DACA2BFE2E57D
+:1061D000B23FE3BBC5EBB2EC38CF6DD0AB58348ED9
+:1061E000C57DD2224FC19DB2A2A75563BFB4C34C97
+:1061F00097057ED0E59E831A99973C0E7988A24E2A
+:10620000F0BDA113F3DE328D97C93518BF6B2A7824
+:106210006DA8056EB1A0DF49448014C49309C67807
+:10622000344DF8B389BED74D2F667AF79E2914D026
+:10623000BBCFCC0D96547AAF9FF69205FE5AFFDA8B
+:10624000462E8D71784624AB8027D85CE380FF848E
+:10625000710AEB8FE83C1EF8070C2FB7B13D37FCF5
+:1062600087C509E7F37CFE8A3C9F33076D9CE77383
+:1062700066F959AE2FDE1DC3793DDA5A85F59AE1EC
+:106280003718793B65B7BC3718F439961DDC92DCBA
+:106290008DEDFC1FAF441E4BD79D89381A7762F9EC
+:1062A000EEEBE0529E59BE5BFEFEACBEBF63FC8EC1
+:1062B000A9C8F1713E98E1070AB5CE1EB98F63FCFB
+:1062C0001E1AE94F6E7766AFDDC5BF47A7FF7EA9EF
+:1062D00011F729FE4B6E3DE85ABC5EFE9ED99C55D7
+:1062E000F7154E2778BECF19C6EFA147E7632D8C6F
+:1062F000F2032FF5FBA5C267F6FF2EE6EFFCFFF2D7
+:10630000BFB7FCBF73A5703700800000000000001D
+:106310001F8B080000000000000BED7D0B58556539
+:10632000BAF0B7F6DA37606F5C080AA8E002454DAC
+:10633000C936225EBA2EB9282AE206C4B441DC204E
+:106340002676AC21B3911ACA8D7B4348D6C04469E6
+:106350008ED5D6D433534DD1654A27EB6CB59A2EE2
+:106360009A263975A682ED25B53BE9F1D49CC799EB
+:10637000CEFBBEDF5AB2D776836633E73FFFFFFC22
+:106380007B9E66F1ADEFFE7EEFFD7DBF25136D06B2
+:10639000369EB1337B459F98C258C5BE3DA52C8E15
+:1063A000B1533526C6A05C562F322CB367992F4DBA
+:1063B000C0728E2102CA657F501C82CCD877ABAAEE
+:1063C000F7BF064DF7AF823616C68ABF1FCC5826D8
+:1063D000631DAB642A977E3F86B158C60A0211F44A
+:1063E0007EEEF789F4BCFEFBCBE87DB10DFAC1FC73
+:1063F000811DCCB71AE63BE5B650F9D44EE6C3F999
+:10640000F1173781B111F8070C99C1A43C368CB152
+:10641000D18AB007BAB359DF5F45E3CDFB3E83C6EF
+:10642000BB667C45C300E80FBD1D69D07ED6F8F77A
+:1064300072FAC17A5DEE295922948B8DFE39387E2D
+:10644000B1C3C4DC29F8FE564302D417325613EB0D
+:1064500080F650C6FDBA5CAC468861ECCE89D06946
+:10646000009459CDEB03100E5B98632BBC9AE7AAFE
+:10647000C8C67663CA9820C2D4E551ACA61DF7629F
+:106480000B64155DCED80FF8BB0EDEE322AFC4C59A
+:1064900027BA14A82FEF077F0EA26D29CCCA983D0A
+:1064A0009DD75FA924BABCC3E1EF96758A7520CE4B
+:1064B000C77F43CDD00EE611EF34FB5603FC5D36AB
+:1064C000EB61612C54B8F394C028DEE68754C6868D
+:1064D0004D823FB2E05C0C86854E9867C18A0C7392
+:1064E000657ACF3ACCD9D9F3A6C03EF2F0BC61BCF4
+:1064F000E56B4C3E4B0A3ED3E299ADA75DE87311C4
+:10650000C0578EC575076E17003EF314A6E4C25C33
+:10651000F399B62FE667B08E1BD4B2D7AF049A6C4E
+:10652000040F2ACFF18F70B9611D375B03530193BC
+:10653000D8CFD36BF2130D8CBD61E270B5985CCAF5
+:10654000605887697B867FB08CFB90E83D330612EC
+:106550009D76D8C7DAF6FB46C27BAF22F3FD995B86
+:106560004C0C07623E9313E0BC289D293E84BB91EE
+:10657000E3D191352F3DDD2CF4ACFF8889CD6B0F35
+:10658000B3BF3AC540F36C03BC954732F6DB5556B2
+:106590007A3EB14A6232A0E053AB12A8FC34E0313B
+:1065A0003EDB578DA2F7CFAD7250F9855593A8FC0D
+:1065B000E22A85CADB57E5D3F38FAB9CF4BE60B407
+:1065C000EB1605D6FB9041397C0FEC6F90D8C210CA
+:1065D0006FF1DCAD137ACE37A2E5BB0A3C8F2A9B64
+:1065E00059C6755701685CB08F4AC5EAA8075000C4
+:1065F0006C1B13A05C2EB2EE6647B873E7707C6C20
+:10660000FE7F2D3540BBC7EE8A24BAD5E057663EE3
+:10661000F0BA35A5077E1FD5FEDAC40C746C69325A
+:10662000CC7B434D84A33905F1C3E9C1F546A53BB5
+:10663000CC2E80D7BC298CC6BD32D5D988EF6F5EF1
+:10664000BBEBD10FF0FC76A6985D709E15DB331A7C
+:106650001364ECE7BA5781761536C98C78778B3797
+:10666000C62CE3F9C7033D206EB3EEE4627B0FDC7A
+:10667000B728028D7B7D361FFF1B3C1F6AD7622A1D
+:10668000D2B5E3E7733E3D1C9882F0F200FB581D43
+:1066900083F4F0E2143C77E94EA091C9B01EF63EB7
+:1066A000D59B1398E489391F5E83D90101EB13014F
+:1066B00096EEC93DF06B1E55497CCE043428C604C5
+:1066C000C38F113D85E2CFFBB80F804BE50A6175A2
+:1066D00003CC5FD526FA0401E9ABE00DA2AF564129
+:1066E00026FA7A70983991E84D90907F15F497A723
+:1066F000C643FBEEFB0469B38CF40A738DEB19B748
+:106700006AFD64A2B72A1F3C337BA7CB9FB5EE4935
+:10671000DA21E3312A665C6795A498FB07D1FBA2D6
+:106720001681E822B4FC9A22723A626F9A106E6562
+:10673000C365C19381FBE1F8B160458AB9D286F5A2
+:10674000CC6F807515A4B237B05D772BAC3785CF91
+:10675000332E68DC4A1C37685E68BFD009E57715C0
+:106760003BC1B54292CD8928572489D657B9629743
+:1067700009E1B308E02C64203C1C661B8EBF14C6E4
+:1067800007F8DD20F9F3B0FE867499D5C339547A41
+:1067900033CCC89F5C6BF93CAEA618F3E550AE3025
+:1067A0004AE624289745323A37589F0FFB57013C59
+:1067B000FADB705CB610654B285C2AD4F556B5C47C
+:1067C0009817EBDEB79AE474E26B4A387E214EE10B
+:1067D000785BE92D4A5E87E7EDB64B44B746C5ECDA
+:1067E000C075A9F09DDFB6CE9412D4FF5B158FC59E
+:1067F000291CCF0A52FD6902EEF7D60807AE77BE14
+:10680000D46242789E83F3831C0E8B257F1A8EBF41
+:10681000D8CAE1700E3FDAF4E7DAB33E0EEFAAB65B
+:106820000AA2BF1B8DCEE475D0FF4658A71B9EF36E
+:10683000D7EF4A13F009F42E207F905CC9CE207A5E
+:106840003BFEE0F5C9B47F583FC2DBEE90A722DFE4
+:1068500001BC21B9ABE14F7926A76BADDFE029463A
+:106860009A77F0944BA3D7AAB5EF51FD22A0579485
+:10687000B766F68280F5666084E1E837094786F6F8
+:1068800036C01F77620FFDCE6781F9C85F17AD2D47
+:1068900062AE20FE03F2B6E6B930F09A87EBCD2265
+:1068A000B945E70D74F81AEBDF539FAD9E7759AAEF
+:1068B0009EFE713C1CD7A1D567FBD36E4DEF69AF2F
+:1068C000CD5BD69FF7437A403C74A8F0C1F6CBA9C4
+:1068D0003D2F833C5EDD80FCE13ED16711F0F9780D
+:1068E000C3402C3F0BD216B6F6C5F297DE9D0BCFF8
+:1068F000CF1FDA548EFBD3D6B118F41DE41337AA98
+:10690000F2B9CA1F9E5FFC6292EBBA295941F8F3B3
+:10691000C0EF4720FFFEE2E977D210CE1FDB39BF80
+:10692000FBD9EF1F37B1D49EF55736BD67AAB00526
+:10693000C38BF3BBE65107E9FC168DE2FD1679BF68
+:1069400025F9C5407EA5A59C7FFE15DE6779FB5A1B
+:1069500007B577D9FECCCF7F1093C4C40B9FB77611
+:10696000BEA1E7FEA8C9E94F407D34B54547FFA168
+:10697000FBAF50D75D3585F3B71B543CBEA1BA952C
+:10698000FA5536553C8E7AEF7C8D7EABF4EFB5F33D
+:1069900039B5D644E7736A6D5A23EA8BA7DAF9F959
+:1069A000FC8BD83E7625B4FB62D9D65B1253492FB7
+:1069B0004946BD04CF07F5D21B55FD74099C0FEA6B
+:1069C000A761CEE736D4CBB4F292C7F8F92C7A7A25
+:1069D000DF277F9409FFF8FEEEB3F890FF56B63F2D
+:1069E0007BE84A783FBFA9D59402ED3C5352083E5C
+:1069F000E7F87C4D86C4A2617F4D9B4CC8073CDA0A
+:106A0000BE43F05C832B33723EF328E8F0CD315C5B
+:106A10001E09FD7BDACF674A3CF211E61EC2B6C6FC
+:106A20009DBFFEA7553A2A48759849AE3544B1CD69
+:106A300012AEA3E27E36B677F9753482D305485D8F
+:106A400005E9F3E8144732D285A6BF86B6DFAAD29D
+:106A5000D7E0A8F6F9B8DEC1B120DF01C4BF895480
+:106A6000B251EFF9CD9556C9E3C0FE2E19EB2D5664
+:106A700026A17CDF6C90C7117E827E7F4F22C232BE
+:106A800090857C6FF8B2C0B7B83E44A78871FC69A6
+:106A9000877DBFA3C20B55F181FCBD1F9F49C67600
+:106AA000E25391B51CFF42F50CAD5FA87E11AA57C9
+:106AB000F4B6BF3D17B9BFA3292E1FC98908266D9B
+:106AC0008EA1FD2DC7F2B9FD8D628A01FA97FFF202
+:106AD000F24DA84F1EAD57769BA1FEE81D36EAFF8A
+:106AE0008FDA6FE83EE75755E8F6798E6E5A44B272
+:106AF000334EB56426935D07360F83FAA3B7461865
+:106B000010FE4753B8BE0016A01DF5C46DAA1D891E
+:106B1000FA383E511F6723B93E8EE5A755BB12F5E3
+:106B2000717C7F5CC5BFB248251AE57277BD5DDA1E
+:106B30008CF0F073BAE9AC1D4670003D81F36355EB
+:106B40002FE89402F6FE417C1AE4C77D28EF58ED49
+:106B50003086F65D67CB51BB211DF192AF4F6BBF05
+:106B6000C2D4C2EEC0760F0BBEAD306ED48AF7F23F
+:106B7000E2514EB7A56408D06F41ED69E2870B6C16
+:106B800003658672DCE66A9C88F5EB53A4D5D02DAC
+:106B9000AA2DA3B316FA2FF68E24FB798520937EB7
+:106BA000CFEA05B22B996A1F2CC1BFA0BCC4F6C6A0
+:106BB00070955F1A905F2EBAFF8EC644281F36B0BC
+:106BC0006E11405360289A8AE5820D310E0FCA5B20
+:106BD0000FDF0FDB087CD4DAC3474F4F72B26CA4CF
+:106BE000F7B3806F30FE68581BDA512B4CED0AAEBC
+:106BF0009F81DEB195E17A9DA4C7AF52F1A2B3EDBA
+:106C0000B05D56CF07F5F3E1AEEEC3F7E0B9DA0CAD
+:106C10008E6619E5BBBC5F46B8BF2532D4678733A3
+:106C20005EBFDCCEEBE149FAF1F24DA28F917E5CC2
+:106C3000363080FAD77A91F8E2E24D250351DF58D9
+:106C40000C65945F1B702AC0A7C6B61CDEAE35EF7C
+:106C50002137F0D3648139911F1D33068A101E2716
+:106C600037C5F7AF477DEF66CF0806F5559BEE4970
+:106C7000C6E7C94D11F3908FE74A45B931A8FF6CBB
+:106C80008CC940BB5FA3B3F46C2E0F6EBA39271EBC
+:106C9000E5DDB2BFEF795402B9BA187054423F48EB
+:106CA0007B94CF0D4D96ADDA9E2C026AD9E35C231E
+:106CB000116EFF62D8397732CA61C1B72D91DACB34
+:106CC000F1521F76F371B42B014F6FBEFB431AE7ED
+:106CD0002BC3DEC2F9D07FD9CDCF47E338FFF260B6
+:106CE000C70409DE1F1BEFCAC4F13F17366D93D0EE
+:106CF000AE5DBF692CCA8FF1AA7D54D0DF39773ED3
+:106D000087AF63B3DCFB7CD5DB0582A7565EE0EB87
+:106D10006766A897FA9959C2A7C4480F3E29B25A84
+:106D200094EF9A5EA2BD9F96CDF9CFC97E2DC9780A
+:106D3000FE4BB7AD4B46F9F1999D975D5BFEB4F8FC
+:106D40004E5887ABCD2031C03B979191DEBBC8CD6B
+:106D5000F569560DCC24B167FEA2EC2882F3D2F57A
+:106D6000993AB9878E197CFF9991E5E33A867ABA08
+:106D700033507FFAC8E85F8CE7FA11E8A7E8974933
+:106D8000CFE6F8F7518B3815DFBB57080CFD4F1FC6
+:106D9000B53C6F1FCEFD28E4C7602F9B7C5BA1BD77
+:106DA0007D7CBB1FF9DECD2FC48C4330E689E9F131
+:106DB000883FCB7798A60EE6FA145AD36C99D16F18
+:106DC0000E776E37A97AD4B9F20BCF9A11EF973DAF
+:106DD000D54A7E0550537CA8DF2C6B7FF68D413061
+:106DE000DE2DDB2B32711EADFD2D2F703844B080AF
+:106DF000B92448AFAE18D5BF7130F0C8E5D9F9AEA7
+:106E000007511FC273BA12D424655245BD119F1297
+:106E1000ED9319BB491F07FD8AECEB9BBD7CBC9B26
+:106E2000471D6C4CA57D15C5B2A0F3BF2DDB44E713
+:106E3000A5F5877D533F8FF5EEC702B05EC563644D
+:106E400011D742D9C83EDE86F063D1D256DC879195
+:106E50001D7B039E2BC57EAC199E1B6B96FF2BB52D
+:106E6000AFB748223C3D37D73D1380F964913919BB
+:106E7000F47767D7D0786E33973FEBA29E7EF846C3
+:106E800028D7CEB13900BDA11C4DF0D9F90B03F1C3
+:106E9000F944D6BDC700CF78065404001A92EA6AB6
+:106EA00021BEC3383F5E799BEC437E0C1C5C403CAA
+:106EB000FFE6951399B8EE6B87064E235E99EAA715
+:106EC00057E402FDAFCF56E1921EC8C4760376ABFD
+:106ED0007CCD7880E4A32941EE8FFA8A1FC7C2F5E2
+:106EE000FDD54078B053F03F8EF36A70DAA7D2FB3D
+:106EF0007319AE4DD9F05404D3ED7E683F5B8876AC
+:106F0000E07E0FF417D3C60D433FC4C72938AE1B2C
+:106F1000D0561CDCA3C766AB4B370F9AB41EE132C8
+:106F20000500CAAE065B26BD3F3342F95E66E8B691
+:106F3000C03AB2BBFFB2A91ECAD2AFFB3111449511
+:106F400027229965C3F8C26ED828EC6777FAEE4518
+:106F5000B8CE7BBBAD0CE1C4AC7A3DD76C48F4FF36
+:106F600012F1B926DAC112500EB567203F62B7D8C8
+:106F7000C83FB3E06C20EDE72897FEBA97F4F49F82
+:106F8000A5BA5E46B80E1295C32EA8BF57F20FFBE6
+:106F9000158E5F1BE5A8E7728405AF7FE71D7F8D27
+:106FA0008E857EDF748F303E03EDBE51AC0EF4E76C
+:106FB00075DE39E6B5ABA07CB52A4F42D7F54D82D8
+:106FC0006C44BBE39B6EAB1FF5906F6C06F2736471
+:106FD000EFDCF321FA21B3AD36BF188DFD4C5F060F
+:106FE000CB1B762029E6F8181231EC0780E74055D4
+:106FF0002E5DDB4F6F3F7666733BA853E53F46D966
+:1070000041703EE536B266C44306659CD768959AE2
+:10701000617DAFDAB62D40FFD5A9EF53FBA1DC3877
+:10702000B573583F96DE3B5FEC407D02F484884C9C
+:10703000E5533C7F4DBE96AA708968B9DE84F0F0B6
+:10704000003CD0BF566A33F82DE85F9DA38703ABA1
+:10705000ED2E47BC61866807D20D9E2F9EBF2C186F
+:10706000BAD955E79FF7756725FF2FA1BC00CE134E
+:10707000E15A7EEAF8E5BF62746EDFE23AE01C1B7B
+:10708000AE603DE7F7BFEDBC98D1D184E7B052B414
+:10709000B7E039788C5CDF73036E6D8DA16EDBF029
+:1070A0005C567A86D3390DF4009F403B0598DAE6AA
+:1070B00038E42B07A9FD56CD9F36AA86F84CB9C7F0
+:1070C0002221FCBE8B8CA6FE0CCED534281C9FE161
+:1070D0007CA5B68A115F59985E23E0B927E00CB011
+:1070E0009F4E43C08EFB0C44801609CF6B725255E5
+:1070F000FD1B3882EA67C5FE8FDC61DF8CFC46B47D
+:107100000E7EE4188822D6D41D3D1AD6D526B07638
+:10711000DA9749E51F4B6DA4CFB5C5F888BFB59583
+:107120000E71E05EBF616A7D7524F197AB0C062A93
+:1071300077CF1F48F6585B0CB0561C6FFE68D21B09
+:107140005EFC3B8F9774A7315E9FC146ACC7FAA225
+:107150005134DECB1ABFBACF4EE3B515298991540D
+:107160003FD080FD5B535C137388AE793B503CA8E5
+:10717000DD860D4A229EE7866233B57B4870CE5F7E
+:107180008CE35C6E23BD31303FF2E96DFC38FDE8E5
+:107190005FEAACE5FBD6E840F3AB0F751F7E18F94C
+:1071A000873B1B4E04ED43EBD70B10AF1531DA01D3
+:1071B000287CDE397F770ECF59370097C545769208
+:1071C000BD2EA73104369C9FC4B2114FF6003CA1DE
+:1071D000BDDB04E71CC7CF79751C9E73E1A6E07385
+:1071E00086F1DC2BE1BDB03CDA214CA2731E85E3B5
+:1071F000D7B24807DAD7E7CEEF555F063E4583237F
+:10720000C102B0F83CD5353F27AB478E3CF209ECC4
+:107210000FE0526E0964B5A07E6E60D5ED61F8C0D6
+:10722000A21C6E1F48ACDB84F275A186FF7521F8A5
+:107230001F1812733C4AC57FE8F74ABC73319EC3DE
+:107240005742C7047CB9F76FE2BC70E3DF9CC3F917
+:10725000D68138E7325CDF70E3EE21B7A1BE7187DB
+:1072600085F45F7676CF109CF77729CE9FE378116F
+:10727000C3BBC9BFDE99D86DC2FD75CEFF3C09F511
+:10728000AC85B57F22FABCD8F5AD8E1A6B42B91920
+:10729000939F610A40FFF8FC8CD7F15C0ECEB2C818
+:1072A00096307E905DB32626A13ED4317D6212F2E7
+:1072B000CB8E245833C953871DF9A869FBE5765C4A
+:1072C00067477E26956526ABE5923EF9EB17C05FD2
+:1072D000FDA0087C06F61A3E4F80BDE6077EFB291E
+:1072E000D86BF83C0AF61ABE3F0CF61A3EBB56396C
+:1072F000E87D47FEB0ED8817675AB81F6591D11138
+:10730000562F5BF694C8FC1A7F83FF6EDA12A52B0A
+:10731000576F8CD5956F6C030CB2F694ABD60ED329
+:107320009535FDB3D23B46F7DE5597A92BFF3F03BA
+:10733000DF260E5FF497FF6F822FFED682BC2BC133
+:107340003F00BFF7654D233EDA21B09A5878C64812
+:107350009CFF199D02F9DDF0D70272BB18FF00BA3D
+:1073600031DAE406ACF742FB5F435BB47DD1FE60EB
+:10737000CC61AA80F7A5F91112CAF3B9AC86E86C02
+:107380001E6BA1E70DAC9D9E65EC003DCB19A7C31C
+:107390006F2A0213F0F9719CEB53A4D36556D7639F
+:1073A0007168B725B946C6223FB2F527BBB4B7739B
+:1073B000420D9BA97AAE6D82BA2FF8CDC1B543BFFD
+:1073C0008351636FBF5DEE99471B1FE63B8D7CE3E6
+:1073D0002B139F675FD6C424E40FCC3940674FF569
+:1073E000365FAB2A272BF2399CD0678BE563A50269
+:1073F000C58B77B55ACCE85F38B6C6A4EAEB77936D
+:107400009D7BF810F7CB1C6B98968CF857DF3A32BF
+:1074100019F1FC98496EA805F81F9B0CFCDB417E16
+:107420001C07CA8723F976EA0F92223A03CE6D91A0
+:10743000BABF23B2C37C07B42F4D1499DB81F1F49A
+:1074400094685CBFB6EFD07557AEB5E8F060F6242F
+:107450007DB994997BF02D05CFDBDC538F7A925860
+:10746000D6CFD587DD5DFBF1D2FDAF05E16B72AE06
+:107470003D0EF51A36914DFC41ECE9DF1B7CB57CE5
+:10748000060DBE1A5E7D9FE31C999B45AF29DE86E3
+:10749000717494C71DDB391C5BA3AEBDEF2A80431A
+:1074A000F1FB22E3702E777F84F8BC83FBF543E782
+:1074B00009205D8F447AE5745DE17D8FECB78575B9
+:1074C00045265C5FB1AD3B09FD4EBBEE1A9984E7E2
+:1074D0007270D6C824E41B7BA68F7C64058CDB55B8
+:1074E000203A2C804FBB0A4EDF87E58E3A51C27995
+:1074F000BBB69F56F94BF7BE89B0BEAFF34D24879C
+:10750000BAB6FF73F84CF10EE03330FF191FE733C2
+:107510004B8C4ED608F32E01B8A01DFFCFE63717CF
+:10752000E233074DCE3CCCDBE8AA171CE87FAB9FCB
+:107530006E21FDE120D08785E353C30AE49393C015
+:10754000FE9510DF9C596853766C1F3600E1C5DC50
+:10755000CAC151137AF07D51DD9202F4AFB3B5A6E2
+:1075600023A877A33304E57331331E0904E1A9EBA3
+:1075700005534F99F0DA78241084D7A1787A1BE26A
+:1075800069540F9E9E616793CDA9BCFEC0C01EBE0C
+:1075900087BF60FE728BE86FC478BF86B7FF39FD86
+:1075A000BD72541280AFDC9D0BF8FB8B7129AF04C8
+:1075B0008420BE72917CAC35EAEF24F7D645FD9D60
+:1075C000E4DEA1E95CEEED9A7EFDEEBF20DEDFC5D4
+:1075D000F1BEA37422E1658709E419C0EB605D6622
+:1075E00034968FAE2D213AD3E827749E2E15FFB521
+:1075F000760B8DDD264718FC74D589BAF34C7B6178
+:10760000413FE7E5BDAF5F1B576BA78DBB3024AE95
+:107610001B3AEE13B9DC0E4DDB52D6E7F86000F6EC
+:10762000F4A33C94C81E7C15510FB89EB9013E5D71
+:10763000F91C3E5D05D7133D1ECAD7E8D2C5301EE2
+:107640007B708EE843FDB52BFF34D1E919A0531AA6
+:10765000A397794FAAF4795CA5CF632A7D6AF5E2F6
+:10766000D607E7DE80E3D689C4A70FCEC91C80F316
+:107670007DB6258DE685F550DED15BAF2DACAC1F18
+:107680004EFCC18EFCEB10C001ED8492D212B2A769
+:107690004B4C8E01E1F484D07D878EB76B9685F2DA
+:1076A000C8603CE277C57795B046E40B0007C4CFCD
+:1076B00043D81EEA8BB7723FF01E6C1F170CA791C0
+:1076C000A4AF1CFAADE040D161DAFE373B9EC35255
+:1076D0009F9E5F2C591FA53BB7C52DB1BA72F1749F
+:1076E000BE8F4375C30684CB6BBAD0F969FD2FF604
+:1076F000FC6F52FBE39A7F203DA5BF6E3C04927E57
+:10770000BED490FAD121F5E374E50BE1E361152FC6
+:1077100034397238425E102EBED45568A90ECED3CD
+:1077200088CEE3764B749E1AB7FF917235224FCF05
+:10773000AF2ED45FE34F9FE738A53C94A3FE12CA57
+:10774000DFBA587E14248713F270BD01C18CFD5B33
+:1077500055395BDDCEF16E5DD4FD947FF395AAA71C
+:10776000035E12BFFF5AE5F75FFF412DFF5E20BCAD
+:10777000DCB3636534EAED27B68F8C463BEC48BB3F
+:10778000271AF9BECCDCD157023E7EE904F909D3B1
+:107790009D6CEF5B7E7EA6F29D13780E2437253A12
+:1077A0008FA3AAFC3C8CF293E4FD287A1E44F909CD
+:1077B000F5739E55F5F4DF0A44FF4B8D2DE1FDD3A3
+:1077C0005BF4FCAA7A6354889CD4CBCDAAB58375AC
+:1077D000E54AEF305DD955A7979B796219F1F5130A
+:1077E0003E0EC792FC4C5DFB13B21C2D117C381C65
+:1077F000BE36C9D18867477CB1D1C1F4A2F1DF831D
+:10780000217038867040FCF496F4892747D5FE5ADB
+:1078100019EC4213CE5B6275BC1E877E84B5820371
+:10782000E35498EF3709CEF1C09C8CC79B83F48C4E
+:10783000F7F344C297C3DE3DE5987775060C30F444
+:10784000F3FEA96E4F32FA572B9E8A22BD2974DEB1
+:10785000AA023D9FF9B2A128FB23E857F2BEE8B384
+:10786000223C0A62887FCD7956F48950EEAACB89F2
+:107870000EDEC709950E35B9B3C45813F61CAB37E5
+:10788000EACFB1A4A09EC6E978506817FAC173D7B1
+:107890006490A4E7F72B31F2FD2F794A24FFEE1212
+:1078A000EFB7FB30AEB804F4405413FED4E42944DF
+:1078B000BC3EEC3419889FB6C716227CDC7344CAE0
+:1078C00083DDDB348CF0FC4853CE409CAF4985D33C
+:1078D00089ED168370053C9D26E6277BD54FE7F999
+:1078E000A5B784E4C609840BEA414689E8E2813CF5
+:1078F000EE973F0CE360BD01E804F5E12E9F98EFA1
+:107900000B431F0FA8F31C3DFB2BC29F377C7BA2B0
+:1079100051AF38DCCEC73F5A2745637CEA1D6FA6BE
+:107920009DD65700E3A2DEBBE37A929327BC1C1FCF
+:10793000719D641F3671F9D1E15D74FF6480C75792
+:107940006B45D23BBF6A2A299C8CE7BDD644E59C97
+:10795000A2528A6F74F8B87C39E43B5A8EE777C23A
+:107960000BA70FE5FA1D13F78D8FC37336113E5425
+:107970003DA53F97D2B57AFA825F74C604CACFA4F8
+:10798000B82CA81353D14EAA4C00F909947BB8A087
+:1079900084F22A8BDD7A7964614526C43BD42FB109
+:1079A0005DE52325597EA43FB740F272E10B3CEF21
+:1079B000DAB4E56A9277152D16DDBCC5757AFBA899
+:1079C00032C41E0AB5977EB4BC30D5948793171D78
+:1079D0009A5C60D25484FB1130AC9B33E0FD0B22E7
+:1079E000E5239FF14610FFAC5878EA1A552FBD16D3
+:1079F000F18039DC6C9266A707D159A5570CD1D319
+:107A0000F5F005FDF938EAC74DB1AA1C759790BF8E
+:107A1000EEF31CE510F1FB8BB5BF2F5ABF2D57F5C8
+:107A2000DB72D26F3B4A2D94AF79109B04F5DF5582
+:107A30007A3DF9750ECDBA9EF4DC43E7FC3A4ED59B
+:107A4000AF730D9DDBA102C067921B0EADDCA71EBC
+:107A5000A1F18B4FD57338AAF2C9C32A9FEC52ED1E
+:107A6000AD46555E78557971A840B5B7E218C90B97
+:107A7000A3516117C3676E6C8B0A910FB12176D445
+:107A8000E090F3D1CB8B6545AEC8A940F79684D181
+:107A9000BAF726699CAE9CB66527F98FCFC83C9F84
+:107AA000E81EC4098C9794F2FC2C666D27FF71A91F
+:107AB00043A6FAC1182784F66852611E89869FDAA8
+:107AC0007B298EBFD7CAFD61D7F5D82EA59DCA9E4A
+:107AD00052C6300F66B8360E80A31EF484C1E8C7C4
+:107AE000867912C040C3F61ABE0F99D34AEDB2ABE5
+:107AF000992440BBF4A929C4CF129842FC65E03216
+:107B0000A660BE0BF33D4FED1EBF1BF601781FF0C4
+:107B10005C47767989359AC7BB413EF68D67F53C5F
+:107B20007E991F4B7ACB102347CD5EF1566D77219E
+:107B3000BC0DD283264F25FA34903FA2356AAC099A
+:107B4000F1B4D8E624BF01E0F582DBD15FF98A9970
+:107B5000FB094AB97FF2E0F4898FA0BD3BF6191BFF
+:107B6000F9920F2E067C26FEDECDED84BA1237CABE
+:107B7000BD3FE7733937E6992FE97E44D776E6C0F3
+:107B8000F29EBAE74FBD8DF43247203BA3A32E8768
+:107B9000F365C69C98BFD9919FB39ACA93C030CE63
+:107BA000407A50561B711D00D766AA5F745FD67865
+:107BB000BA6F42F89BA0E6194978AE893DE5384591
+:107BC0002DB3ED544E28E0F9817F54F58376F53CD2
+:107BD0007FA7DA41DB54BA6953E9E6D72ADDAC095D
+:107BE000F5876EE47433C2E8B82F0ACA23DC7692B4
+:107BF00033FB0B8ED2BA81FE258CE7A64C179BC7B0
+:107C000003DCC65802C4A74B40ECAD86FD4C29A846
+:107C1000A7FCC51217A37845F19C7A5A5F00634B05
+:107C200057A1DE542F886A3DF2C731B17E6A5F6C7E
+:107C30006512F62FC97F7617E6E196BA003450CE6A
+:107C40009D532F107C2A603C68BFABEE011AEF50A9
+:107C5000355FC7413BEFDF51C1243794D358FEEE67
+:107C6000157C9D4E8C871EAA7B7E17C17B0E87F7E5
+:107C700055270D3A7ACCF047EAE87AF496FEBAFA3C
+:107C800091EB07E9CA039CA9BAF6B1F97A7A8F1C7D
+:107C90003E4E57DF915F6240397B668E96DFC3FDB3
+:107CA000629A5D37E5199B01E1317796A8F9710D6C
+:107CB0006C205A5D8CFCBE4DAA9EC85A8631CCDF22
+:107CC00078FC4E03E507AC99E3B162DEC3997623F5
+:107CD0009D178C4B7CE4D04E238D6B4DF10AE8C789
+:107CE000BC17E02C06E97F4D9A7C53FDEAB81E6371
+:107CF000D07AFACB0C33C6CEB56F53F1E901751DBE
+:107D0000C0B7A798705E27C793D802663041FF01BD
+:107D100073B89C0EA5CB76B5FFEFD4FEDB547CEC9C
+:107D2000CA7F7C7524C2651E237D244F5CB63A024F
+:107D3000D751C0881EDBFDBB2383F5C73FF636CE87
+:107D40009CCC3C1AC7CDF9E8E8D9822702CF7563ED
+:107D5000E0F377E1F9F2578DABA361BD4F08AC1D9D
+:107D6000294AE39F9AFE7DD5D74D543F7A1C9868E7
+:107D700050FFF2D7CDBCFD0426A3BFEB8FAADC6970
+:107D800052E9276D4B3AF917CFAC3793DDB3AD709D
+:107D9000C9E63658EFC899773DF102E24BE15D7FC5
+:107DA0007941EED1F34B0A133B317F7FC42A3B4329
+:107DB000FEA0CD9BB6E5CB6C5AB7646488A74F6E26
+:107DC0007DB112C7FBDDB6488302E33FB9D948FC59
+:107DD000E5B27B1FD9BC9E9DEF8F29C9D7DBF9BFC8
+:107DE0005BB3EE89EDF8BEF6F9C78E05E5E974CC14
+:107DF000BA2709FDA6075755B7E5A6F5CE3F4BCCE8
+:107E0000CC85F1BBFC97BF7CEE1D98FF03D765E3E3
+:107E100082ED80CFA7727DE7E0AADAB65CB0534767
+:107E20008BEAFD15A37B35C263F44B0365D4DF8079
+:107E3000148C2E8065FE8C088302FBFBC067DC443B
+:107E40007C60C69A343CCFEC270B769FC4733EA46B
+:107E5000E27B2FFAC841F59CCE954D32C1DDFD8AFB
+:107E600095DB378A9C44F6B1434E2A0ED2E70EDEEC
+:107E7000A5C5971C9F201F2F2E8BA2B8B216771175
+:107E8000F3BF6D403EBF70524D9644EBD7C7F1072C
+:107E900021FC3231CECBE3F56EB791515E106C0D03
+:107EA000E964A5389AF24D3E5CFA0B8AD7BBEB2DFC
+:107EB000525A1CC50D9EC1722DF01DCB788AE3FA73
+:107EC0005068274DE37E84D3F33C8F98E5DEE1EFE5
+:107ED000BDC0F998D4F3097D9F348D9F8B07CF25C2
+:107EE0004D772EBBF19ED479E7126D25FCD2CE459D
+:107EF0008C6EA2736156DB28CCFB88E72885FBD902
+:107F00008772A8F310F7977D50765BFD4A289F3A59
+:107F1000DB8F215D687195F2049E7F4047027CCB28
+:107F2000A4F68F57F56EE463A87797AB7197CE05EB
+:107F30008CE22EDA78676AFB497CBC5B486F2EAF17
+:107F400001FA475912F52AE9170DC3787E44B9ADF5
+:107F50007B01E5AB0A0607C6CDE343F47A37ABA154
+:107F6000F5C6BF2F923FDF10B596FAC70378F0FE33
+:107F70002166E8B260BF1218AD984F42570DE52058
+:107F80003D4BCDD78DAF7D89EB4739D03351379FEE
+:107F9000F003ADDFF3A9887CA0D62223DFC3DC2C5D
+:107FA000E4DB04BF14C4A375D45FBA8949788F8316
+:107FB000294CC67B9A823A5FE8FA613CAE17827E12
+:107FC00086FB15EAF8FC1B67F27B206C279383ED98
+:107FD0001616BC9E61BAB2EA27D3974D09669D9CDE
+:107FE000FAE06C49BF9A3EFC35A1FD0DB2B36FBFFC
+:107FF0006F7590DD95DAD35ECB13D3E03CA8D672D3
+:108000005888EEBDDFB222E5E7D3804E6DCC99FDF6
+:1080100036C0C3F5BE48F2CE10B597E01188E0F047
+:1080200039A7CFCEE3FA2E68E7F5946F0DF20ECFA5
+:108030000FF3B44700BE33B73E4F409B578B2F75AD
+:10804000AAFC38901258E00C038F46A4DF2CE4E71A
+:10805000DF50BCBB1CF55BC0E5C0EA2F74F73F4E98
+:10806000164D69C47587E621687AA976AFB4D3CD79
+:10807000E56CA73B93F8CE19666F21FD3F94DF189E
+:1080800019E57DAC14231DCDE4B7BB9BF2466ADD38
+:1080900016C902CF590EBD3F66F624BD3C28526278
+:1080A00043E485DEDF55EAD4C78986B7DD41FCEBC2
+:1080B0000CEA4DC4EFF87A8C6A5E9909EF978868EC
+:1080C000AFBBE9B957E5CFEFAA7A6604F257781F3C
+:1080D0008589E5808F7616A0723F44F96198D22E8B
+:1080E00053BE632C53A83C80B9A8ACE54126321F8F
+:1080F0003DB5FC962416A0F250D487442429999EBD
+:10810000C3D00E19867A9EE35CBC87F22673522890
+:108110005E50C4944FB05D41E65724F70AAE67EA5B
+:108120003DDC138B14287796B29E7BB9986792C773
+:1081300054E4FC7411DE3FEE9CAE958FF3F214DE36
+:10814000FECD3F7DF138DED305FEA5D67FC6EBCF51
+:10815000954F2E9A82659381CAEF637B280FC8538F
+:10816000DE9A06E7FFC9344678E4C955DE092E0FCA
+:10817000CF55F621DE68E5095395FDC1E59539CA6D
+:108180007BC1E5C773948EE0FE5D79CA215ECFF3B3
+:1081900097DE37294968EFC2EFB7C2048E87F87BB4
+:1081A000C3E4FA04DB294F09042F0BF0ED66E2DB90
+:1081B0004E86740A6463C53C22E033E6DBA19E8DE3
+:1081C0003353BE9F21CA96DC973F3294BE0226B637
+:1081D0001DFD744546D717440F217C4F70FFE9AF52
+:1081E00098C703F4908D7A7E408D8704EAB83F40AB
+:1081F000A313ED7DE87C17C27BA604F979537BC6F7
+:10820000ED6DFDA1787C40D5F70EAAFADEFBAA5FE2
+:10821000FADC7E03C698E3D61EFAEE9D7F1AD9F1EA
+:1082200020FE79FE7E8F2E3071F921A1BCE88C08EA
+:108230007F0FBBB7F5EDCF991A974FF95E43248AAC
+:1082400033308DEF737ED3897F021F1CD34FB35F12
+:108250001D5684431A4B98310AE66DCD67A4BF7A48
+:10826000727717D3F70DCA4082C1BA8EAE38861422
+:10827000C78467B83DD192C468BDF6142902F5A53C
+:1082800006956F5A58CCF4E1B8FE214692B7A1EB9F
+:108290006E88F60918571CE48FE0FE8D38E68B8057
+:1082A0007106E53BF2296FC52D4AF9582E6385A367
+:1082B000A05CD926CAF930CE9EB6125605E3564DBB
+:1082C000023E4719E93C9FA2BF8AC7632C8CF22D5E
+:1082D000D60DB051BCDABB66E4AEC5C837134596BF
+:1082E00006EDD31BC6E5A3DFD363EBDF9F624EEA47
+:1082F0007A3C36C79B780FC32D19F83D1249B162FD
+:108300001EFAA615C67CE4E749CF8E8F1683E07F60
+:10831000D47B2A02F3DB1F930C54FF585DB6F5465D
+:108320001BDE23F42B9467201D516C30EF0668137D
+:108330000FE3DD5F7DA46504EB1D1FA2F3CD3A3C86
+:108340008D729843FCA07ABFA529443F28C957F3F2
+:108350003426B00978CE573C71D6847AEE429B4CD5
+:108360007EF4EC2681F25302BB1CC9784E47EF1B0A
+:10837000497E736F93A8FAAD1DE4B70E24B164BCB7
+:108380005F53D122905E2C7ABFADC77E4347C98927
+:1083900038CED0F1DD89C1FEB2C7EEFA4504F25104
+:1083A0006F9941F573331A4796156B0AECFF53AF7B
+:1083B000C0F3274C9280F798ED0F8A11B8AE2E13B8
+:1083C000F75334033FC5FBB9CD538AFBA443D3F71E
+:1083D000B0CE20BBA5212E3512E7EDC15F85FCEBA9
+:1083E000C75A32293EB2B9299BF24142C7B9771523
+:1083F0006B47FBA46195959EE7D5273B931DD0FF66
+:10840000D3D6298D20A4D8A7BB9626E0FDA0C52DE4
+:10841000161611068F8FB54EA4F916E33D669CB76C
+:10842000A5C88C72645ADB1433C2EDDE55CAB3C1E1
+:10843000F31416BBD6205D46B53C4B7862637E379D
+:10844000C2F3DFAE519251BF3896C6C2E6493E90A4
+:10845000CFED8477AE71D27D924F93C2B75B97CF49
+:10846000F335A3A7CBFCFEB891BDBB04E05C01F4DF
+:10847000540FAF8E36654623DE9AD83262521F946F
+:1084800095B8D19E3B8D7A3BF0F3C6BBE6AEAF828A
+:10849000760D778FD88FECE30A33D79BD99F45A20F
+:1084A0000BD00B2B903EFF638E55F204F15FD41F6F
+:1084B000155D7E1A971BA626D16F067E6EDA79FCB3
+:1084C0006F68EF20DE2A41784CBF09AA5DA0E66BF9
+:1084D000244C206D9C7E0D33E6FAFC0CE32E8BAC15
+:1084E000789EA17AFA797872DE3A82C6473D37974C
+:1084F000291141EB0096E0277FB98BCF7BAE9D5AC7
+:108500006F0406F34390FE1E5AAFED63E47A3DBD5F
+:10851000BE93CFF542806F9FF1BACB7CFA7E9FE588
+:10852000333AB7D1A2B2FB38CAD97522E5558F5973
+:10853000C7E3FF678630F213F5369EC67FF1671CEE
+:10854000A8C211E0DA18574CE7D95B3FB3EF80922D
+:1085500032B6C73EBC2C41BF2EADDD67E7F6751BBA
+:108560008BE4FA603BDA67161FF0BDB1F83CA0A0BF
+:10857000FC1EB56985D4D7BE43F919FE6458EF6275
+:10858000F5C864C035E40F9FAE17543D84250C9F99
+:1085900040571749FE607F2588FF015FE1797B3EE8
+:1085A00081E0D3DC7A74F3BDE487B13B782B7E5E47
+:1085B00063992607791E90764F9061686A604F7CB8
+:1085C0004A83E3C9DFAE7EFA097875E2A9E55FE385
+:1085D000D332A0321AE1794FDC9C6B13A1DD58B382
+:1085E0002F01F9E9129FE53CBCB36AF89282F7F3D8
+:1085F000F4F59684A0F5C37FCD3B9E585F89726ADF
+:1086000087D581A9E1885F6E1D7C02A9F85D9CAECB
+:10861000BBFE95EEE7474AA716507E7B9D85EE751B
+:1086200085C27789CA07987A5F43A3A78896910C79
+:10863000FD8B4754BBE9C85AB053A1DC586796F18B
+:10864000BB065D8E222521CC78E63A33FF6E4EB014
+:108650009D98DAB34F6DFC2E37F74336C2F84218B7
+:108660007FDF85C6DB53A48C990EF8BFB7C879F9B4
+:10867000F42CCC6F5A44FBADDD5ED7F536B4B97738
+:10868000A02B03EB8FAC1D36414047A451A6FB7EC7
+:108690005EEF73244F5AF03B3E60CFB7B41B2350BC
+:1086A000FF707B0D14BF6D698F8B1C8E72CA6608BC
+:1086B0001B675D349DC3AB479E38A383F5A1E65C81
+:1086C000AE0F09CF94DD9F0AF0F21EE2798A9AFE7E
+:1086D00021A97833C622117F96BC3CCFAD471FE25B
+:1086E0007AF519D4AB515FCAAA9282E5534334FF9D
+:1086F0000E4655AEC38DF730736C8CE4C750BCACDE
+:10870000807E0B1BF34D4BC1EF643818E6E7F6078C
+:10871000FD4706CC8E6FE3FA4EA4CDE650108F15C0
+:108720004E5756F81FC2337294C2701E63887E6122
+:108730000ED11FC490F282E97A7D42668E6884B3BE
+:10874000FDBEBEF338347F2EE84D74CFCCCD00FE95
+:1087500088A756379D4F34181244CF8A22C70DEC94
+:10876000D1FBF13E1BF7AF48142F129446F2DB6F9A
+:10877000CCE4FE8D44C6E35E83146ECF8F9DE4A6E9
+:1087800032D80F148762AFB248E4CBCB8A5CB723F0
+:108790007EA4001B40FBAF7F3A1388DC2F512F676C
+:1087A000B5171757FACD6EEEFFF31A221D9BC3E0E3
+:1087B000FDAF0BB81F2E720FEC0DF5DBEBAD74BFE8
+:1087C000254F7CAA89F069BC81FCDA5E7640427E46
+:1087D000F2ABE95CDE1F2A72DE3F9DE2B2CE14846A
+:1087E0007F82112C2A5076CDAA1F37E9F6D448D4BF
+:1087F0008B3F4C7C91E0E106D8A5C17F9B6AE3FAF0
+:108800008F82F78FD6AE26B8CA03B89F4CBB771EAF
+:108810002BF1FBFDCDCE536EBCDFBBA22095AFAFDD
+:10882000C8382315CA43EB0202D2DD3D76651EEA45
+:10883000254DF273741E2919B201FD65838DEC4D2F
+:10884000CB38C69E8EE1F5DAF7A31EB20FDC149C7E
+:108850004F52ADEEFB2121BCBE725501DF67E70E22
+:1088600000643FB48F996A7FDB16933D7EAE0C7037
+:1088700043B8B8B9FDFCC274DB62F770B28B78BD47
+:10888000FB2ADE1EE3A5502FBDFD7E15DAE38FA681
+:10889000849FF74B75DE47DFEA7E04E358FF59CF2C
+:1088A000E358BD9FB39F1980B76CB0B3647605F0F1
+:1088B000B9A5E679E1BE2373CD2CCE473A6DED0420
+:1088C0002F06F23CFA2ABA471FAAAF5A918E4E4B96
+:1088D0009BEB27CA9C8F644DA0ABFD1CF742C6BD25
+:1088E000B0DEEA4840FDD3B3B4BB01F98767D7D205
+:1088F0000FF15E7A799999F4D67263CDBFA31D64A6
+:10890000DCCBF35FF01B13880783801FE17DD36905
+:10891000D5FCFC164ADC5F2B3CF3B13307FDB18973
+:1089200046C24B4D8F1D6351DCE897DDA0E6B7339F
+:1089300071483DDEF7320E16C9EF1B55077A2DEE52
+:108940002F97E7EB2AF03FE4439A9E6B4B37EAF20E
+:108950007ACD2179BDC6903CE0AFA7AB79722A1FD2
+:10896000B2678DEF539F7A15EC605CE74EE043F8F9
+:10897000F4833D8CCFDD60AFE3F335B0D7D10FFE8C
+:10898000C6AA51F47C739583DEBFBD6A123DAF4B1E
+:108990000E98109FC91FCDBF33E717C8AFA7E19945
+:1089A00098966DC3EF76F0FA21331BFFD57D35D451
+:1089B000C7A9EDDDAEC5F49D3AADCCD62ECE4E277F
+:1089C0003F38959B67342F46BFCFE652C53A03F038
+:1089D0006480C15981DF7960775A286E11BA9F0788
+:1089E0006768723CBC1DCFF013067A3FCEC0197D7C
+:1089F000F8711E12F83AAEDAFBFE16A48F7E4546D9
+:108A000027E27172AA3E7EB07206D7F35E579FC905
+:108A10006FBB86F6755F5FA38FDEEA3D3B0005FA0C
+:108A2000F55EEFB5B36BB1DE13139EAE06AA74D537
+:108A3000EBF8366E4FB219406F83B11C6A1F0628DF
+:108A4000BFE4746D8E9FC8ED27D35B7712D25B575E
+:108A50008CAF1EEDC4AE5D4BD7E3774244A4372400
+:108A60000BA4378C7F68F456CBCF6321D21BFC3923
+:108A7000ADEE3D670ED26302A72FE1999DCB291F72
+:108A8000E32E9E47A3D15B8C9A2F1F25B593BD483B
+:108A90001FE6C07E407B1B04BCC773FC634AFE100C
+:108AA0000B1CAE7074F723E9AD6CC64FA3B77FBB48
+:108AB0002640F9139D294A02EA335EF5FB813F9671
+:108AC0000ECFCC3073B970B92F11C7D9A08E336DCA
+:108AD000C861F2FF15581D22CAB37C99C3356F7C5B
+:108AE000267D6FC8A7F6DBED5456CC80E780B9270A
+:108AF000C9CF3BC0C0E9F7C1B7CD8B11EF931A0EB8
+:108B0000164D437CB943247D3B745F1F14AA713317
+:108B100081CF0B9A5762701CF11E952EE53B3A38B7
+:108B20009F8F61521AAC27C12D15E7635CE86A0379
+:108B30007D4FA45FD1C11894CFDA78707009986F17
+:108B400082AAAF75DCF9F408BF76D3401D3DB7E0CB
+:108B50003E7AA3E70BF10FFB0C41E31394EFEB52CA
+:108B6000EF49FE58BF6DAF7EC4CBC3FB25AB66712A
+:108B7000BEE131F1FC0F682DE177019A8A5C4FE28A
+:108B80007ECED3FF764A7E17EE637934F995138C47
+:108B90005CDFC36F24F2EFE5B809CE5AFC4DD31762
+:108BA0006585E7172517BBFE80E36E62F22E94679A
+:108BB00036079B47F13590678817CB8A9417675023
+:108BC000FCE5D2F4C02F8B9457895FF7824F03AE38
+:108BD0005776F7856F538AFE63CF0F48FF65DC5FDA
+:108BE000BAB0AC8672B306819D84EB9DAAE6677825
+:108BF00086F07ACDBFEA1DA0C54F9542CC9F8C561A
+:108C0000E135C6E26415D0BF0BE530DEDFDB1BF0DB
+:108C1000E3BD600BDE2393D08FCAA87F4CADE093F9
+:108C2000B1BFF8E5EB182F32E5D0E744189BC4ED4F
+:108C300001EDFE8D94FBE3FC8D87353E318E8D4733
+:108C4000F8241BE40726C3FBCC87F33AF078B21E66
+:108C5000591C8BE272E2A68612FCDED6D2AD9F6E64
+:108C6000427FE8E47FB7303C0FD01FFDC6B0F95C0F
+:108C7000FF303942743570563CD71353C2E3E9E3F1
+:108C8000B354FD13F1344E87A76C66783C25FDE79D
+:108C900027E069E44C3D9E1684E06914CD7BE978B9
+:108CA0001A3B13F0F4559083B8AF17E72A0366F622
+:108CB0008197DF952A897DD507C507C8EE1BC12698
+:108CC0005983BF7BA83D5B515EF6919FD07FCD114C
+:108CD000CA8FF3D49EA63CE52EDB917D6807FD4745
+:108CE000AD450EF66781FEAED3D75B40AEB8C19EF0
+:108CF000DC304B247EB2E70E8BFF3AD46BEBF87D71
+:108D000084F2BA4D02E67B0FAAAE115CC0DFE21519
+:108D1000301DA17F8C62E8F19FC07F57980E903E76
+:108D2000BB0EE4B19BD817BF97A6C9FF31969AB77F
+:108D3000D04EF5FCCDE8588DE7CCA45DC88FA603D6
+:108D40003D617CF39A6E906F41E3BDB56312F9D536
+:108D5000AEFB1EE45F901F670A8C185CCEB126EA5A
+:108D6000FAE54929BAFA690997E9EA35BAEF8C5167
+:108D7000E32A595B72117FC40A9EA7305DCED0B53D
+:108D80005F57964DDF03B86232BF7F3773D464DD1F
+:108D9000F8A17AC1D5F03FA47731440F08D513422A
+:108DA000F5828533F5F740D71803D9C49F18CFABA8
+:108DB0001B7AF6DF880ED6C91CCFBD65A7281FC356
+:108DC00003F63FFA9B0607E597225D8C3507C83FFF
+:108DD000B761BE95CE63C38E27E8BB119AFF0BE83F
+:108DE00086E8686CB64479AEE9F65F537FB694CBFB
+:108DF000D950BA14EA5E22FD6FE36CD81B7E6F6D0A
+:108E0000760A977B3B03E48760779A19CA4DAF6473
+:108E1000A0BCB1DF08FE086118D2AF42F28925304C
+:108E2000C94BF992EFF1EF2932E6589388A6BF4279
+:108E3000798D80F6DD6FA979B488B711F9CCB17A54
+:108E4000327EEF97D377FFF1FC7C6C0E5E96AEE638
+:108E500065CDDE8E49602D98173B18C783B671B576
+:108E60004CF2905FC34FF543F2D9010FCDCFFBC752
+:108E70005731671394C51A45F537BBD4F87A37C50F
+:108E8000BD53054724FA3786894E8A7B473389E2EA
+:108E9000E283580D3DA3043F671E97C847AE00000C
+:108EA000A0BC603799E9FB19D94FDA187DDF68A9B2
+:108EB0007933E5650564F223DE7388DFC3DB60FF89
+:108EC00005C5099AF6F1FB04F724B93FC478E6A07A
+:108ED0003A81BE132E56F33882F8A6E89806F5625A
+:108EE0005D2B7D072EBEDA407EAD2BCC35BBE81C5A
+:108EF000EEB6D0F7E3BAA03FFAB9D6D90D8CE81593
+:108F000098C7397F2AFCBAAE7152DCA2EB6FFD48DC
+:108F1000DEB1103FA7C7C5F56F4F9C99E397EDD41D
+:108F200027C8B71BE322E97EDCBC6B6BF6211FD997
+:108F3000F09EE858ADFA9FD1FF3F14FFC0FC03B389
+:108F40003305F54E7375783FA59939F767A1BFF4DE
+:108F5000AE25097DE951BDC6456C06BF39FAE2E38D
+:108F6000220DE53C0EA2AD53DB67A36DB95029E39A
+:108F70005F3F312E52D64B5C24502320BF1F8AF511
+:108F800063113EDC6F7DA971919AC24B8B8B68FB9C
+:108F90009EA5FE5D0088ADE677505C80CECDD0B357
+:108FA000BE20386EC1F595E35F327F8F7186D96A36
+:108FB00079DF5307BF44BFFEDEDFEE7E0A9FD79DF9
+:108FC0007DAC6C39E045D1243BF97BF7FF32E641BB
+:108FD0003E9C3E7E30CB61D1F9EFF187F849EB1032
+:108FE000F8BDFCE0FAA29075651BF5F1805C9BBEB4
+:108FF000FDD4387D7DFE107DD9CC6A084F43F7BB88
+:109000003AEA6ECA936BBC8D39788678D079881726
+:109010002E9B8798C3EE4BC337E64821BA5FF73ED5
+:10902000A77BE72B2BDE5A4976AC81EECF9F9ED7EC
+:1090300070CF3B32E28799B9699C7C05F1E8BBDFD0
+:10904000A7BF4B311DC9E5BE11DA57E6F0EF459DCC
+:10905000174F50FDF9436B77B5E706C57BEF1DE869
+:10906000721400DE0CB59D12500F195AFB1AD5CFA1
+:109070009D9FD5271EA5D5EE69CF0DFAAE5F9AD17B
+:1090800069403F465AED1BF4BE37BDC720BB79FE91
+:109090005E9959267B4BCD534B53F126AD8CFB5B30
+:1090A000A5542E6F3698B87C7343B57815FC5F5B7A
+:1090B00068BE1BE7EB6726F17B1D0CB810F22B6D29
+:1090C000BC5079A6C9019BC2F5C8B4B287B85CD1BF
+:1090D000F205DB42F3E25C73113E427523B5DB9887
+:1090E000A3B6DBC9F5533683492897619F61F344E2
+:1090F00017A87EDADEF2D398663FCE79F343CCCF61
+:10910000FBD1F6632FE35E971C087BDFF636D56E46
+:10911000ED8C082439B81F38ACFE3EA374EAAD05C7
+:109120007DE8AF98578B30EDD55EB8C4BCDA8D6A58
+:10913000BC488B976AF9B5CCE81B87DFF91C65FB47
+:10914000F30D1407ED25AFF61EBB2380F7DCBD152C
+:10915000118ECDECD2FDEB5BA7737E5A5DC0E81992
+:109160001A5F085DF78602DEFE5091F3E1823EE26F
+:109170000A5AFB0F13C3FBE3BE2DE4FB3F775F29C5
+:109180009FEB7D8A4961E1F240B57CF7D0F7600F33
+:109190003D89EBD0CAAEFA34F2DB794C1C6FDD327C
+:1091A000FF9EA0A63FDA507F243DAA85EAA3ABB973
+:1091B0003EA9E959921AD708A527A08F3FE23C8221
+:1091C0008DD3ADA6279EA38FB9401F409743188F1C
+:1091D0002B19D4BCD121569E827EA97AD4F9F6D31C
+:1091E000F7F64BB29FEAB74690FD54BDF92DD4ABCC
+:1091F000D6D5723F61A7BDE62DFCFE81FB3D91F403
+:10920000A6DEFA6B76D447857A3B0AE38A888FF12B
+:10921000369F205F8E7654C0E482F595A31D65C30A
+:10922000BC555700E1166A4F75DDFD05E5BB82BDF3
+:1092300079B820EB1FC01F42FC4B8DD3393EEF1A8B
+:109240007E8AFC26622DB7F7C45A1E0F3596F1B8F8
+:109250008551E17E1433C82374056A7E940D0EBDDA
+:109260001FA52B89FB51E2736BFCA8079A26592492
+:1092700085E423F7AB6879ED632CBEB7F03E862713
+:10928000C3C8300F1D1455B2032D6A7C03FF410B78
+:1092900094579ADF24346FDA16E22709F5A358674A
+:1092A000E9FD268F0AF2BD93619EE7D7E7BD83688B
+:1092B000FB878D8BA3D06FF292AF61A6EA37791846
+:1092C000D7B3E343EE37E9DAC1ED22172A305785E9
+:1092D000C3BFF3E254E407B966DFE12AF483687E92
+:1092E000A8F86A151E6ADC07E18BF014F3393C63B9
+:1092F00042E0E91DA2C58554780EE0F02D2F709252
+:10930000DF4942784A3DF0D4FC54DEBDEDF47D6D7A
+:10931000CB1D16D94DF0FC92EC5513C213E1FF138F
+:10932000FD50E342E039EEE1CC07F03BC1E31F29F9
+:10933000E9C0E7844DB7C5DE00CF495B1F28C127D0
+:109340007B93C709FE7316E75798D91D4C8F636747
+:10935000C8BA3883064F0D0F7BFC778CFCB1E51241
+:10936000F7E797AB789886700BF6E739F470DBA0D7
+:10937000E64B1A736BDC68EF0E0D819B86871E84AB
+:109380001BF2BB18B3EC26FF5D9D80F6506F78385A
+:10939000B4EDC7E1E1FC59AA3DAFC2EDB9F599F7CB
+:1093A00022BC5ED858F20E3E5FF4DD1685F0DABEC0
+:1093B000E58199BDC02D3198CFEF991E1E6E5B8B54
+:1093C0005DD5B3E0FD750E9F91F82CE01BDABD9BD7
+:1093D0009BC659F5F1198D3FE65BC3C98F0BFB970F
+:1093E00096535EA1A76C39F1C7AE73FCB1DB8E79E1
+:1093F0008817CB1F2D85FCBE7D79ED77AF5F077099
+:10940000CDA93D4CF46704FAA373AB3B6C50F33128
+:109410005804C88BF832E6C7F8F12066F545099480
+:109420009F407CD38B79CEF881D2503F85F4C65FC4
+:1094300005220E261812808F63EED4152407EF9FA5
+:109440001586CFAE2B3390FF67B3EA1F944B9D2D4B
+:10945000D84E8B6F2D2B525A67FD347FE1C3D85FF6
+:10946000F31776C6B073FE35FC3E784EED2601F359
+:109470005006D5DD4AF221BE4C61281FB266CAFCF7
+:109480007BB3B912EDF77C7F5B770EDA099D78A389
+:109490003D83F0E077384F67EDE38407572CE5FE16
+:1094A00091CEDAD3B1E1F1A036E2D2FC8C9B757299
+:1094B000D25BCBBF63D26957DE4CFB11783042C51B
+:1094C000034D4EA2BC417C3296051E463FF620C09D
+:1094D00087881494979C1F8BA0FF44C17EC45EFCB8
+:1094E0008F1A3D74C1DA2CFDF09E70683E400DADC0
+:1094F000FB7459B67F621FEBBBE83C00352EE95187
+:10950000E3920B6B79FE6AE71DDFE5E17A4F978105
+:109510007D0070D95CE660787ED340B10AD882E7DE
+:10952000392F6F358074ACC521B578FED662E7114E
+:109530003CD7EB00A712FA635EAF1AEF19A27E07C1
+:109540003A04FF01CF3FC77130DE837240F3A3338B
+:10955000D41BED88DFCA17583FD65C9328117EBB19
+:10956000BA71FC753BEEA4FC851EFF20CF87FBC9BA
+:10957000FEAD6833E5576AFE2DAF9DFBB72A5880D4
+:10958000FE9D3C8A2320DF6EB5D0F71AAA04D98C41
+:10959000EFF717BB8C85A4F738291FD635C72A915A
+:1095A0001F6CE9B644E417E58D22C9EBDEEC92F3BB
+:1095B000E9EC47F21995EE2E81CF0C2EBC383E9384
+:1095C00054A8E733C9853F217EB67E969EBFA0DEB4
+:1095D000590FF3E4A8F4746EDF6A1C1FE3571119E6
+:1095E00041FAA8BADF503A3A4F2FFDBF8FAE66223C
+:1095F0009CC3D0D5ACC21F4757A58503FAA4ABB90D
+:10960000857ABAFA1996FF17D2D5CF691F17A02B02
+:109610006321D3E749C7F2EF3C8F8935F03CCBFF9C
+:10962000C379D25FCDE4FE8BD03C69C66AA85C00EA
+:109630006743E7A3960BC73319E34C964DAFAD1DB7
+:109640002DF3F182FD9D2CC4CFC942FC9AA1FA5D95
+:10965000183FA8CEEFB9F789BFEC1D0D7F3EF9F496
+:109660007F915EBB6FAA40F7C90B477EB71375D0D9
+:10967000A23595EA3C7DFB3DFFD97E4EFC05FB55AE
+:1096800043F7D51875B77A6FE0C7F93999E356FAF9
+:10969000BEF9BA1AE640B85FC8EFB9AE8EE74D6BB7
+:1096A00079CDCE57AA1E2C1DCFF3E9D0EF19EAEFE2
+:1096B000D4F2953DB64AD2F38F2856EE8F0DF1774E
+:1096C00056C6CAB7D03DC6F3FD9DEF16FE03FC9DFE
+:1096D000930A64FE5DC610BF677CBEF261611F7EA7
+:1096E000B3CE1807437E9763F30918AF656733C994
+:1096F000AF33C816A0EF6B95D74E213DF06491EBC8
+:10970000535CA731B7FBAB97C653BE8103870AE50D
+:10971000CBA0671E2FFC27FA09FE597E3E5F01F79A
+:10972000735DECFD791FC23BAB8F7BF472E0912837
+:1097300078FF68BD9DBEAFB552D5A33B4DDD492D29
+:1097400050BFFFAE13BBD13FE16B3330BCDF76B10E
+:10975000FEA3860BE8C5E610FB68C339BDD8F7D673
+:10976000C420BDB86155FE8E6361C6D1F4E29B662C
+:10977000EBF5E2721BD78BCB6DDD26B40FCAE3BECF
+:109780007F1DF34E8DD5AC1DE5E220A586F4E17872
+:1097900089513EF1FF8FCBB37F685CBE78B63E2E19
+:1097A0003F56CD47411E8FDFFFE9D2FCA893B8DEBC
+:1097B000B0C6C8ED15AF02EFC2C4D143E3F243CF48
+:1097C0003E4371F975DBAD748F6FC38E663EDE1458
+:1097D00026619E792253F5B502EE2F0DD53F1E3539
+:1097E00029D694F188EF06BA4F88F704C92FB2DD65
+:1097F000BA09FD4DE9769ECF6DDEFFF256B73148CE
+:109800003F043D94F4E2B2007D97A95C7230E23BE4
+:109810007193FC141FAF1308BF46CCE6F4B330D7E6
+:1098200047FAE1A03249E0F7C4DCDC8E4FE671E78D
+:1098300048C42F682A8EE2715FE980E8C0B8F37DE2
+:10984000D87432DE5F65FC7B15930DF4EF50AC13DA
+:10985000BA13902FB70A4A223E4167A27B8F4FC7A7
+:109860002803F1DF93F22419E8DF93DA93D7988085
+:10987000EB6BAA6F4D40BD70CD6C1E4769CD3B4E62
+:10988000F90FA674D00753E819F6DF1D9DEB14D429
+:10989000BCC0F604FA1E026BF990F06A9499F17F4D
+:1098A000E7C7E15F84F474CC46FAC2AF041FBF2758
+:1098B00064B7D27DBC96CBCC8955B09E66BB99B4BB
+:1098C00009EF65530FA4C0FBE6015234C601BC2961
+:1098D000A912FA8FBC318D6FA21FA439259561BEE4
+:1098E0007F53D9048A9F379D0506033D3DA347EC6E
+:1098F000CF82F76B84007D37C83DD9C0309FB0ED73
+:10990000B2A989C1F7324529544E3A482E88B2810E
+:10991000EEF9896A3C5B3C2F9EAD8F4F7F3F9BEFFA
+:109920005B662DF3E81E689C59C2FD965F56FC21CC
+:10993000DD738B33535E50B989F1EF7E5CC6E85C12
+:1099400042E1E759A58F2B186DFAF5ADC1C034E59A
+:10995000619F5D82F8D18030A53CEEAF96205F6AB2
+:1099600038577F92D747F0F2CED94797A01C941969
+:10997000FFF7491A46F1BCCBF201C5C487CB4D8134
+:10998000B0DFF9BDD07A64E653D4F1D8FFE4786B48
+:109990002E33CFF3A55F78BC9E7301F5F912C6D5BF
+:1099A000DA858E1BDAEF7FAA7D6FFBFC68F6B9FBC8
+:1099B000719407412AA27A9F0DF564A3CA0F3DD97D
+:1099C000137C7E19F9819BD3458C419767FBDFA6F9
+:1099D000F2D6B800800000001F8B080000000000D5
+:1099E000000BCD3B0D545CD599DF9BF7E6CD10669F
+:1099F000E00D0CC910093E082831045F1288A04907
+:109A000079046240A94EF809B825E944A346DBB3BE
+:109A10009DBAD6923DD932094320989009A9256E66
+:109A20006D8BA9D9B5B547A9DBEDAA47BB9398F5CE
+:109A3000F81FDA5AAB7B3C16539BDDF6B83DF42792
+:109A4000969ED336FB7DDF7D0F6626432069F69C0C
+:109A50009D1C72E7BE77EF77EFFDFE7FEE9C3B87A4
+:109A60009F5A8073562B6B2A9865C09F73607DD672
+:109A7000E0736AF93FD0FD0B0114FAE6C047DD4DF3
+:109A8000F1A24AF1BC25404370BE1B4003889F935E
+:109A9000F0A9050F5FBD74AE182014C4877902AC1D
+:109AA000B67006EE4FBB56C7EFF4039C4538B9C6F7
+:109AB0000C1CDE47113040B0C763FF5A35FCEE9DE9
+:109AC000B4EE35601CD367C62BD6BA571F51216E32
+:109AD000CFC7BFCF5AEBFEB4AB353BE499396F6AC1
+:109AE000BB6C3479DE8774065C27E283D163F83D72
+:109AF000FA6E4CE24D3C837FB8DFE84A6D74109FEC
+:109B00003F688FF3E2B822315FC7FD66C0CC47598A
+:109B1000C878B05E428903E7EFBBBAE2519AFFF022
+:109B2000E3C3DFFA363E3EF29D3DBFA4764149C510
+:109B30005035C2CB341C86403B044A900E4EFA8608
+:109B400078F47CEAC814A21FFBC978DA5B7E678CC4
+:109B5000C99748471C7FC77EC9D4703D97C77354C7
+:109B6000A6FDB92593F62B1F5EC4FB0F6C4FA6FB19
+:109B70008864BE1DC0F19103121CC37E8691B00E95
+:109B8000FEA905C9E39B09BF55D44B18871B3F2885
+:109B900041E7581A7C3F1874303D886E9184FD1F50
+:109BA00072EAB7105E0FED932182200FED74012C45
+:109BB00006F846F0DFEFDE5D02F0853E27E37D64C8
+:109BC0009D3A2AE1FB11AFB6B993FA4B1CC6511D61
+:109BD0000463E2B90EAEB88ACF65AF3778ABCEEB8F
+:109BE000C5D6A9F9E0A1719381A097F9E88D2AE281
+:109BF000A3B765E6A3D4FDA7F2DD5C7C5618CCB113
+:109C0000F0300AC115C89EB279E20CEE0FAE763084
+:109C1000FF2CBFDAC1FB3B5B8003A4D9F9B0AF07CF
+:109C200017B87A866F548BEE7BFD2DA708FC6CF37A
+:109C3000D4D171B3A882D685F05839F27320797FD8
+:109C4000F6B8926979F83B5850C9723726E3595DE6
+:109C5000A371132AA81D37256CCB1EBD5FBB90BC1A
+:109C6000B820017E11C1053E7FAAFC3A21C448DC20
+:109C70009359781B9DBF6FA30AB29406DF73F40F4C
+:109C8000EDBCDB24FA473E0F4629EA096720992FED
+:109C9000832F9430FFC80332B8A444FE6A34895E2F
+:109CA0005FBAD539AD7FDCB61E23BA1B45E0C07D57
+:109CB0001D7E4B66BE391CDCFB0B99E4BB51D525E0
+:109CC000DC7F46ECEE87DAF1FDA1D765631087777C
+:109CD0003FB3EB67AF627BBABA788D544C44322302
+:109CE000DB71FCE9F56E63D010F2378D97626E4C34
+:109CF000F79A99F50E5517F37A515C4FBA001F2861
+:109D00008DEA0744875478D3FABAFBF858C3EA04BB
+:109D1000B95A187A2188E71BF2E0263CF4FE24BFEA
+:109D2000874AE4CBFCD9D7418C325E7E465F71DC3A
+:109D30005F5ACD9304A7A9B42A9249E7826C207C8C
+:109D40007CE8356EF4E190F79D86DB289F99DF1B58
+:109D50007342BC9CF080EB62DB0C135B5A88EF4BC8
+:109D60009CAC3F64FF4A7EBEDD1B541CB8AFFF0CA9
+:109D700016F37AF6FC26F8B2721FBEBFD639DA4067
+:109D8000FC11DD0E5A04A76CF3C614EA6FA00DE2B5
+:109D9000C21BF53A7711C26D7C9E1602A8F50DFB29
+:109DA000C90E553C77A42044EB47CC1F95219E7DDE
+:109DB0000255B0DC351EACC7F9BD6FC8C61E7EA209
+:109DC0001D0FE17C252003D1497A6A6D6002F7A35B
+:109DD00078CEBC075900EB26011A12F8A976CA0DF5
+:109DE0000D097AAE0E2127F6EBDDF949E337684518
+:109DF00049EF65308D38D277636059D2386F55A5F9
+:109E000046FB6DD257263DBFB9AC26693E3428A724
+:109E100027B0BF16FF11DD65107D5BAE3CE5D84F66
+:109E200098AF40421FDFFF25E8F59FC9C4CE75708B
+:109E30001DC94F33189D241F68BC8D63889785CF3B
+:109E4000B92732C9909826DB75C9E2CFAA4D454C97
+:109E50001FC973C641F87F0461C8C81715DA848327
+:109E6000E804DA98C4CF516F0C22B2038AC9E3D058
+:109E7000C069511C77056A6F0DFBDE00C4A8BF04E2
+:109E8000623C1E3FB1C335C8166E313FAB058C83B3
+:109E9000F83EB33C2249D8CF69044346781E635C40
+:109EA000A27D6A385F5E492C19E77E41238CF73228
+:109EB0007C730FCDCFEF06AD2F9FF997DF8F7641E3
+:109EC00084F6F32818E092091FA890969216097359
+:109ED0007B25E839A487BE09C62AEA97C204EB2588
+:109EE00034EF12F517C19826947D9CF5374C28BEA7
+:109EF000336EA1FFD3C9CD8CFC2870C6A60B0EBE55
+:109F0000FF56B37C13EAC1CDB7555DD0DF50BA5FC1
+:109F10004C92DFBB37E98C77A57B23CB8BD2FD122C
+:109F2000BF1FD814BC6E133E2755E05E75F1F8AF25
+:109F300050053EA31218E8CB40F4D99B02DBC85F62
+:109F400079D66D94B2C8233E892FAADD93AFD48809
+:109F5000F9440F3FD283F09D530E12E16009D10105
+:109F60009FAB48877D4CC718C32D0C83B1DB5A9734
+:109F7000FAF94807A2CB28680B08AF72F8E2E8C0EC
+:109F80001F84B3E81937FB470AD165E965A1CBA760
+:109F9000098F174B97547AC0AE5C809AB9F5E95790
+:109FA000A57886B494C882F4C1F348481FC26700FC
+:109FB000043DD0AE1B84A774F8A77E4625E87BB885
+:109FC0002FC6133D233533FC9F8DFC2FFA42BE7CF8
+:109FD0004807D11774F293BC603F101CE3F939DBDA
+:109FE0002178209FE86132F26CBBEC8249F66B8BE2
+:109FF0002583E9B55446070DFB9952DC727E46D99C
+:10A00000AE6781C6F4590C616EFDCEC9E3E7485FC7
+:10A010007B1CA391226A9FAEA3757A9B51C390CA01
+:10A02000F70ED7315FDE035A29F25DA16AB2FE2E28
+:10A03000BC4631227A22BEF608BF49378F90BD292F
+:10A04000747861B07266DDA8D308C4905EA7BC675F
+:10A050004E84F0F9827CB4EFC60C9E4F3BC5F908E4
+:10A06000A67C05C983908F4035EEC577BE7E0B2850
+:10A07000826F3D3B107F888FADF402F1240DFC1BF5
+:10A080003F7FA45EE8BBCF6E0A3D4EFC42FA89F1E9
+:10A09000678246FA493380F5A6438FB09F7076C039
+:10A0A000A5139F426CC424BF629BB5CEB601D707EF
+:10A0B0005256C239A3AE243BEED083D9CCCF86040E
+:10A0C000E41FCC77DEA5F23F74E7CDCB0FA87B6A07
+:10A0D0006DF644F9ECE354928FDCC479824EAA3FCA
+:10A0E000C47E874A72923B371C678AFF62C371063F
+:10A0F000820CC769FB2F64B7909E77A1DD1A447C60
+:10A100007FDA448788F972F23FC89EDF1ECE62BFB5
+:10A110008B5184E3EE8849A383C88F774258253E4C
+:10A1200095A02442F4DB1A91D87F2BDEB73D8BFD3E
+:10A130000568D0083F52FC06F9DCF28BC0A385A766
+:10A14000ADF15F3A752FE1D50B3F4F88B7ECF7BF04
+:10A15000EB5A7AAA4A27A5ED2923FA665AF445B59F
+:10A160001D790DF7E9FC53360C6AE4177FE98D5A27
+:10A17000DC5FDF8F6583E2B34C10F1D50210763CD3
+:10A1800093E47429F1CB58FC33C46FDDD91A9DD701
+:10A190001E07D6B80884D83FCE443D40701D99FBB9
+:10A1A000993F33B354DDF6B721F11C6E89FD608F02
+:10A1B000A572F3D4789CE42B0FFDD8DDC9F02511EE
+:10A1C000CF03C7437C0EE9FCF55758FE3ABEAA3BC5
+:10A1D000370FFF3ED57F87C47890C663DC194FC028
+:10A1E000EBB4BC587266EFDBE35193E525659E4DF9
+:10A1F0008F72A7E08FC5187FEDC6FD0E0C1CAD2336
+:10A200007D3392073A469AD0BFF59F248AB3D693FE
+:10A210002E26FBD300A3144778401F2CC3BEB3C027
+:10A22000C3FCB3E8BF83F1CF209CBBAB5D9A8E38F3
+:10A2300059FC91A9D5E1FBBB0ADC8689F48D5AE370
+:10A24000230DE86789E5DF26BFF44E6BBF4C0B9406
+:10A2500043B3A588F95DF1B5ED7D8DE2DEC532C869
+:10A26000A4D7E42E83ECD39D1830E4A2EB0E5F76E6
+:10A27000B2DF87FE1D9FC7D590ECF7DDF58833A9C7
+:10A28000EF4CF1136B5B92FDC0A616E075693FB908
+:10A29000ABFE7AF8E0F1B3FE5CA18C3BB43476D52A
+:10A2A000C6BFF49487F1FF421EE295F32441F37395
+:10A2B000D877211E895F11235955882793BEEAE478
+:10A2C000277FEF3E1AEF3A8BFC4BE3654FC3E788DD
+:10A2D0000E57587802B12F13FFD1BE53FD61578A34
+:10A2E0003F9CBA6F9B0E77D8F859036B083FE89FE5
+:10A2F000B37F609F2BF53CCF637CDE80BCF4831E74
+:10A3000037B7F11E8DDB133D016E4FF6E8D0808E1E
+:10A31000D54B3D65DCBEDC63F0F3577BAAB9B5F1E4
+:10A32000319BBEF1E639D85F38B4CBC17902A55C68
+:10A330007BE56AE2DBB764561F1AE819CA52B643D6
+:10A34000A0E0B82B1B955193CE62C53F8B2C3E5B92
+:10A35000EE9A3CEEC279B17C30F6D044B4DBDB2B14
+:10A3600067E29F75938E1939018A771624E50BEA07
+:10A370002037A95FEFBE2269FC066D69D27B9BBEC8
+:10A38000DFA81372B331B03C69FCA186F5F1BBC9FB
+:10A39000AFAF7169946F68D25727BDBFB9EC8624FF
+:10A3A0007820371BA4A773BA12E8C6E74FA6ABBA4A
+:10A3B000E3C271904DE7D11439988DBEA97C6BE34F
+:10A3C00035671AAF22AE8C525CA9D3B9CBA56D0804
+:10A3D0006A68DA2F3181F24BF6BA4A35C69715977B
+:10A3E0003FBECCA2F8B2285D7CF921E76DE68C2F48
+:10A3F0001B93E3CBAC14BCCD155FBE7A89F8DC5A55
+:10A4000028F26E39AFCBEC07CA8D61B67FB9E3B2E3
+:10A41000B191424FCB1FF392CCE3B8AD552AFB97D5
+:10A420008760220022AF984FF630B7DCC8277DF353
+:10A43000A4CF5C781BC5F94D0EE3284E79B1EE2B05
+:10A4400001F23BF6ED7E34804609FEA7C5C1FA2E27
+:10A450005677660BC995A2A31F27716B8EA6F14F85
+:10A46000ECF176BEF1E016916F3C68E51B0F5AEBFC
+:10A470002042D8DE8E54897CE3AF5B742BFF17E15A
+:10A48000FCE2E12D6BAC7C23F657D07083EDF8A095
+:10A49000D730EF20FEF9850722F8E880A4654964EB
+:10A4A0002FB63834CA1F8F34AE7A97F249FB3CAAD4
+:10A4B00041021FF5ADC927FE92B7A2DB83FDE1C6BD
+:10A4C000E19769BE52EAE07E74CB559C171CC9D354
+:10A4D0009A8A29CEDB504C9806F9993FF5505E23B5
+:10A4E000EA3B13A0F9BDD78BF9B3D12735FF2F93E2
+:10A4F00026A6F8ADC41157118EFCFC993F13BCF38E
+:10A50000F2F3297EC5A04FE5BC6DFE8FF77E2B527E
+:10A5100042AADCE47CF308CA3CE169EB96966C8ABB
+:10A52000A7B63A27F2D2D90B3BFF39ED6FFA93FD6C
+:10A530008454F8FCB1F36B0ED1D5EDBC2D7EA2B7DF
+:10A54000DC381A27BC41ACB198E25E8FB0CBB3E1E6
+:10A5500041F15CB80E22776798190978B0EB1DD7E6
+:10A56000B68A3CB8D1AADB79C6A47A89D2E8E07968
+:10A57000B67EB0F3E3A975127B1F35AD224F7BFD8C
+:10A580000CBCA4BA89BC56B5E0191C17A7E6B3E702
+:10A59000AAA3CC95CF6EB6CE73B175937B5B81E7E2
+:10A5A000FD7FCD7FDFDBFA7F93FF3EBF5E34CAF2D3
+:10A5B00003CF4CFE9CE43BBA6CA13E28EA4349F52C
+:10A5C0009CD43ACE60868033BC52F8A9C3563FB2C1
+:10A5D00042C04DADEF6458799548EB521187812107
+:10A5E00088AC9885C4171EE5BB110DF96181E71091
+:10A5F000F8B075F9B745A8AD2DD487AA715FC3CB64
+:10A600001C6CC786BDA147FB480F2DF3A4958F8313
+:10A61000AD422F0E10DF72FC04A683E44EB2850417
+:10A62000420EA4D708733EC0D1569FC86769B1EAED
+:10A63000DB118F5F25BEC8E3F3F0FC54F85F3B1FCE
+:10A64000FE63C4AF510B38C1D98670BED93A5D479D
+:10A650008CD07BB7B59E5B8F5593BFF058AB26F47B
+:10A66000B0B2D2A0F30FFBD2AFF798B59EE9084B7A
+:10A67000346E5197980F6E31EFA034D9795AD09338
+:10A68000E589D6A7F79946B27E48859B5176E17A4F
+:10A69000D9D3D3FB4F8E870E48E9F7F9634B0E6B86
+:10A6A0000B81ED11F1C59E347C912AEF2AE53F1113
+:10A6B000EE098B0EB6DEF128E3EB332BC9BE83D156
+:10A6C000CB883DCEE7DD93790BC7C97D378B3C87BF
+:10A6D000AA08BD5DD089606AA8BED210E1BAE1FDCA
+:10A6E000A0B97CE7E3E162E33DB2379184F93FB181
+:10A6F000F823B52E18A3BA20F9B15417A4FE4E576B
+:10A70000673ABBFD6E8BD3B2BFE9EB3B47A8BE8374
+:10A71000F38F545BF59DA0A8EFD43DF508ECC4F78A
+:10A72000BF331DECB74ED7771A8AD7480E9623A0B1
+:10A73000FAF47CEB3BB18679D67782175DDFF9635B
+:10A740002BE2E79047D459A6EB3B6DFE79E5757493
+:10A7500088C5BB49AF7401E3C1DB340C3B299F10B2
+:10A760001071C6892A97E0AF9D92159F4103D87A50
+:10A770000A3FCD5DFAC3B9645FDE714129BE5FFF58
+:10A78000C4EB0AF587F31D6B287EBE569D78F05A00
+:10A790007ABFC6C9FAA30E29194FE28FB8CBC145BB
+:10A7A000F0886AB5B268E312B5F5EECC247DBD4100
+:10A7B0004B8E3F86A64EC8D9C49F1A1812E279A8BC
+:10A7C000CE30B349F71813BDF47C68836E0CEAE40D
+:10A7D0000F27C729434DAAD0A745C2EE0C1FD71F8C
+:10A7E00026FFAABF3B83FDCF03050E71EE1218258D
+:10A7F0007E68D293E39AE1B1E27D2524673127E7B1
+:10A80000CBBF3326C66FDFBD7294E252CDF257B78D
+:10A81000E7AF673F14FAC4B89BCB96A79C7F5C2335
+:10A82000BE88ED7402E1BFBFE0F601CA877E1075F5
+:10A83000AE2671196AD3997F6DBA6DEBBB93EB4469
+:10A840007D2A70DD74688BCAFC3F94F7C1913B4848
+:10A850004FE72D603C8F6C51F34309F270A2CDC5D8
+:10A86000F41ED922FC8B3C0784C6D2BC3FD126F40F
+:10A87000D027EF013E4F16DA651D1FE94A38EE2258
+:10A880007C1400FC231D27F0E1437CFE460794E284
+:10A890001687FD5DECBFA5F2D9785B69525CEBAA27
+:10A8A0007624E1D1E90A8639CF7D33E8A4AF1A1ABC
+:10A8B000B14FF17D970AC46FAEC0FD7CCE1CEC6732
+:10A8C00060DFDD188B28D87797845693DFFAE2CEC5
+:10A8D0008E01CAB3B8FC0E8DF8CDD57557B095C6AC
+:10A8E000573A2103DFF7812E05689F1109485FEB76
+:10A8F000106A247F7D38E0D0286FD31C6DDF41EBD8
+:10A9000037FB1700D1796B9383D73B6BAA9CB4CAF2
+:10A91000234783F25F0B3D6C77DF77861FEEC0F134
+:10A92000EF23BD223073AE5D6DC54CA70C3D397E63
+:10A9300076438CEDF05A73BC8BD6595BAD52450310
+:10A940004ED49C3942FEFA4895CB70E1BE466A244B
+:10A95000C6F7C755CE51BAE7F003755CA6757FF010
+:10A9600031F246513AF9BDB0DCA48E1FAA6E7113C4
+:10A970003FEC458A107E22530EB65FA9E3FE6CD1F0
+:10A980007F2FE285F01CC1FD96525C34897285D020
+:10A990007D53C1C7EFC076559BC2E3BE90EF885090
+:10A9A0005DA8BF496539E9F78606E8FE4F3FF23BEF
+:10A9B000C743FE10F3F370BE9FE5D05E67B86673C1
+:10A9C00019F1CB1B5519ECB757B535DE4B7EFB7A29
+:10A9D000F9A37F798AE2A70295E9D9EF0CC65F2532
+:10A9E000BE6E12FEE2C9250FB0DCF575DD0E8437B0
+:10A9F0008884DFA1BA555F650DC3B7F30DC34B441F
+:10AA00003EA9CF7F5F84F21BF16A915F30F38E72B3
+:10AA10003ECFCE2BD5597A6CB92BFC4A29CDBB47FA
+:10AA2000117561B9204AFAC04579259AA724E7BB78
+:10AA3000D64D26C7C18B53E2E0D43C13B8C74B5A5E
+:10AA4000D19E3ED986F1F17298CE2BD111588E2B22
+:10AA50005D1C2F8E548B3828E60CE76BE5E7CBF1B5
+:10AA60009B961F3CDEE3460E00F8518FC6FD2CF38B
+:10AA700037BB7311D45B3D017E7EEBDA47A5C47909
+:10AA80004395ED6E9DF5C64480E0A6EA8B543E5892
+:10AA9000DBB6C0B20F26107D872681F1EBAD5915CC
+:10AAA000273E3DFB7BE038F4130DE31E283E7F7EFE
+:10AAB0009CF6E9A2FC97D8E749DAA78BF25F627FA0
+:10AAC0002FF7E8DCBEDA53C6ED827610797E5B1F85
+:10AAD0005C89FA00F1D65020FA24FF648773FCB732
+:10AAE0000789BF5C014523F97617C4E252823E18FC
+:10AAF000F186DF25BBDC9FE761FE4BDDD7AFDA1CBB
+:10AB0000D6B9C2B711DC21844B787F71E77F3DB4A1
+:10AB100094D6794B66BECAE9DABC83F50EEA850C99
+:10AB2000F637843E8CE57938EF30B2B354A2FB504F
+:10AB30005B770B47774EB9C7754671DE09D4D7D41A
+:10AB4000EF4739A7F3F4D77CF0195AE7E33F2EE03B
+:10AB5000FB4D235BDE66B97F030390DCCB28F7B6A1
+:10AB60009CC5DE5AFC6D117F073B9E11E7673D389F
+:10AB7000E21D8FD1F9FB7F22433ABC5D2A5DC19C67
+:10AB80009F1F32AA4C1E3FE74F53373445DDB07745
+:10AB9000EC7BDC8F34039462FFEB4ED34D7CF0F5FD
+:10ABA000DD8E0BD60DBFBEFBC275C3D12F3BC0A53A
+:10ABB000CDECE30A98E03C2B85F05407ECA357D882
+:10ABC00066B787AE6E673F52D415F51ACA39505F23
+:10ABD0005B40FEF3C026B38CDFFB73D8EE0794B165
+:10ABE00038D9F500D5CB75BABF10E1BA27E567E9CA
+:10ABF000FE42EAF97B9D13EBF97C3884EA95A9F5CE
+:10AC000049C9F37D51DF5F2AEA90767DB2429D38D3
+:10AC1000FA20E1E93637E3A1F7D9EBDFA1FA975D36
+:10AC2000C70F5875606D0768BBC539CC76F2FB9FBE
+:10AC300017F550B81ECFB192169928DEB482EB9B5F
+:10AC40001BE81C73ED7FBE75C3664BBF2173F33DDC
+:10AC5000C89F59F8B4C7FD4DBB90C76B5591B786D7
+:10AC60002C95F5FCFA273C2093BFEC558F929C6CF9
+:10AC700083890D244FBD3EE1B7450F39D96FFB5491
+:10AC8000BBCE74CD534DBEBF90F7F719C66E0413FB
+:10AC90003DAE65511EE92FADE6A7DA791FB1B616B4
+:10ACA000DAC780CCFAEEFDD20D7C8FA949CA66794D
+:10ACB0005434B330515FEE6A4F7F1FA9B670B2852E
+:10ACC000D7F73A80E2AD6886F1B24EF87E4161B8BE
+:10ACD0004D20EE2BC1764D1AC073F67A4E337D6A45
+:10ACE0004B5D2B493FED6A17715BD49B3EAE7BA059
+:10ACF0005DC49F852DA12F101D6E82C97AD26F2849
+:10AD0000DA4684EFB588786D17E94B11EFEE72AC37
+:10AD100099C96BBDE40CEDA2F39ADF11FE842B20E0
+:10AD2000FC7A8CD4381F74ACC5FC0782DB4C7C5E8B
+:10AD3000C98A0A8EAD3C7F1F519B2EED662FC13B09
+:10AD40006CE9E70ACDE4BA6B05388C5E7F425D5D45
+:10AD50009F5F5D5DD2BE2FEAE937083E86E723821A
+:10AD60000FD78346F284FC7798D6B3EF97543CB75D
+:10AD7000A388EB2E9758DF3ED5627E95E0BDB829BB
+:10AD8000F8353AF7FB3B3B80E1CDF3BE466D6138C9
+:10AD900010443AF56708BFF9C93AA3339890FF7990
+:10ADA000D3A2D79B165D97233B8D8B7B6F6CC7AF70
+:10ADB000826A37D12B157E5F0F8C511D68B6F5D591
+:10ADC0007DF7B9294FDC5BB0DE4DF7D1A29EF5D9F6
+:10ADD000D4EF2F3003B47E5F4FE3B31F96121F09E9
+:10ADE000BE8F2C11F98818EAE748429EF4C576997F
+:10ADF000F7555F0071CAA7BB3CC22F7261BCA8AFF8
+:10AE000020BFB99AED393E1FA3D4C16B963CC9A6A9
+:10AE10000126DD172C0089F0853A727A3E99BCFA3A
+:10AE20008230D0BE66832337E07C8A470B34F643FA
+:10AE30007EDDAE313E7DA663268E87F9E3EBD01C26
+:10AE4000F8CA99035FD37C6DC95D2A9ECE109E8897
+:10AE50004F7C0FF0B9E04FF52C672E547854CFFF9C
+:10AE6000C8C68BC7849097C37F89F013A50B36E5BE
+:10AE700033F8455F91F12B6B619EE72A3020B48255
+:10AE8000F0A149848FD4F3573CF77803E1ED956D39
+:10AE900042AFD62A96FE08E359903F6FB2D605CB53
+:10AEA0002E356508BBD30C3FF488BCB6E0D30A74DA
+:10AEB000C7DD39E7EB57BB7D72967BD74F6ECE105F
+:10AEC000FE903EC6FABDB751C0F77A851F7A74600E
+:10AED00015FB0F37E6972E48D48F97BB4E985A171D
+:10AEE0009CAB0E38C337A69BF6F93BEDBE085D95CB
+:10AEF0009B8D3F1E24FE7192DCB8B93DEF7D613021
+:10AF000060905C2D31238074DBEB0B07887FFA8E19
+:10AF1000EF7C87EA24CAEBB241FEA6A20481C6DD1B
+:10AF2000981766F9D8586002D5951EEC31BF9B087A
+:10AF3000F7969650F966A45BA63666121C0FC423DA
+:10AF4000648F6ECA35C3C13474A8DE2CF4C7B196C1
+:10AF5000E02A9A574BBA7315C0C39BCCD5D49FAF88
+:10AF6000BE3A5F9E1ADDA4F72F5D9E5ADC74BEFECA
+:10AF70008220DFD3EAFFA14C1ED6F4B87E4B9EFAA6
+:10AF8000973C00A104B90A6E4ED13B7E4BEFF84DC1
+:10AF9000968BCD9B752B0F1C64F970923C9527E81E
+:10AFA00019BFAD674C9647C56FCB93257F244F1EC5
+:10AFB000BA1F3C594F7E4A1F887B8CA9F2156E0937
+:10AFC0006DD94C762CEFB7AD45FACCFD4F5D17F23D
+:10AFD000D45F60F1FB92A799FFCF22FFD365E15EBA
+:10AFE0004F7112BFDBEDDA2919E2488A755312B7A7
+:10AFF0009F98CAE4B6762A835B732A97DBBA291F27
+:10B00000B7EBA7AEE0B67E2A9FDB8629E4FBD5C866
+:10B01000FF5345DCDE38B59CDB8D53CBB86D9C5AB5
+:10B02000CDE39AA656727BD3D40DDCDE3C5523D6F5
+:10B03000A19A504E5AFEA772D665E07F2342F5D101
+:10B04000BEE3F7BC43F8716A2AE751A2BE355CEF54
+:10B05000712A61E6FFA30542BF6FF408FAA4F2FF6C
+:10B06000B196D0FE74FC0F4E716F4BA17B5B95ECDB
+:10B07000E70C337F9FE7EFBEF447CA83A2FF7198C6
+:10B08000DF5FA2FD9FF62B1726FB95FD79C97E6534
+:10B09000DF12DBAF748D521D6CBBA4F33DB1532D99
+:10B0A000A17FE6F521B88DDE87DADC1AF95351DF8E
+:10B0B0008D010FF6B7EE9581F27DE85F7C8BF80C81
+:10B0C000503F90DD98AFBC3EBCC9D2EFD6F80A38ED
+:10B0D000ED085F847FF23E7DAD395FEE679B67CB05
+:10B0E000FD55509691CECEE638EB85DC6B42EEA353
+:10B0F00005C101CAB74453E4DEB6A3888724B93F2B
+:10B1000065CBBD25C7397E71EF2387E41EF9EA2799
+:10B110009BC579D1DF4EB2A38A35DED928EA5BF52B
+:10B120007EA1579546A12F142DD98E22DFBC4B74DA
+:10B130004995F78822FCE3A6D27F9DB667645773D2
+:10B14000FC3E291B97D67E3F11A13CD6716529CBC9
+:10B1500077AA1C45B555CCE7C7957A4827FFF396E3
+:10B16000239F6D474CB623A9E36C79EA3BDEC47894
+:10B17000B1EDCA713CB799604F366A020F684F3E15
+:10B1800026FE4A95A7DA4233144CB34FB543F8A5CF
+:10B19000AFAD0B0A7F11FD44F253A2CEF47E80DAEC
+:10B1A00021FC9F9C46EBF7153A8473510F3636C647
+:10B1B000EBA98681F2AC7620BC75E6442FC960AF5E
+:10B1C00067D84FFB47F97475FC15F2F9D126E117E2
+:10B1D00042772EFB2D763B17DFDBFE8ECDFFA9E3FA
+:10B1E0009E2C323BD3E1E5F3165E8E0E3C9DC41FD0
+:10B1F00043CAD29B0C3DAD5E358DCBA257E7E757D6
+:10B200001C473BC77A7576BFE2BA8E347C309B5FB1
+:10B21000F1890E91CF45BF621DCDAB2D177EC5E7DD
+:10B220003BE0F2FA0B35F731BE2ED55FD86CF1DF7B
+:10B230006CFE425787AD37C2AC375C96DEB8587F9C
+:10B24000218D7F703BF32F4CCA54FF43541B221FA8
+:10B2500022F408EA99BBE83DC6F1EC2F1CF5087E04
+:10B26000312D3D736D7B7007E175A85AF80B974B34
+:10B270000ED0EFBBAF236FFEF230DF71A58FAD1D97
+:10B2800098203F07BC31BA37DD4BF795287E7CCF3D
+:10B290002BEE11009451DEFF8BF23506D9B991CC1B
+:10B2A0002F7D83C6774714A07B83433D22FFF7C5DC
+:10B2B000055947017967C8197E6AC2CFBF770D1E4D
+:10B2C000C5F60F1985A39070EFF6B0256F2ED8C282
+:10B2D000F774B3B45B9EFD3037DDFEC4FD5CBABAD3
+:10B2E000728E7FD751A0F13D320B3F596A10227EFA
+:10B2F000922307D747D0DB83EA84BC475F4D5727AB
+:10B30000C7C1F922EF25837286F2EF03B49638178E
+:10B310009FB37FB1FB513A970E218677D0EFE0BC07
+:10B320007BFF5A11EFF47BC26E2D8DDED8D7937C54
+:10B33000FF28B595973D16A33BC287038A4169CF85
+:10B34000C1B2CA26CA4F4635AE0083EA7304D3D5CC
+:10B35000A7C72DF9D4C1607BAC7CB2253B9DBDB0A5
+:10B36000DB010BFF76DF5D326612DFA94566907F59
+:10B3700087E3F34B9184BCF11316FCBD9211AF45EA
+:10B3800064EDF50AFDEFD66326FDDEB82FEF2EAE95
+:10B3900033BAF5089CA1E72531F839E9A77C77E7AE
+:10B3A000689A7DBCD521E294BDCE10AFB7375FE17E
+:10B3B000FAE3DEA2F4F9ACE73B441E49F5AD0F72A7
+:10B3C0005EDFA7709D3875DC53169FF4AB6640E3D3
+:10B3D000B8FA81323A577409708E72EC9D379FD853
+:10B3E0008DFDFD3D41CE7B0C51FE0385B5BFF05E6A
+:10B3F000C6FBFE6B1C1A9D6383FC11DF47385C0D96
+:10B4000006E98FEC6A1C9710471E86D101BA0F77A8
+:10B41000782D70BED46B0493DEF723038E93FFA5C3
+:10B420004CB03E734237D7010EF855BEA73354795E
+:10B430009AFD231DC6394F315429E865D793FC1670
+:10B440003FFAFD773527CAC1018B6E0F52DE9CEFA4
+:10B45000318D41A2FF75A0709CEDF38175E39D5481
+:10B4600017CCF2BB0D0A45F6D70481E474A8CA9143
+:10B47000F67ED450D569DE67EA7E9C277EC9FA2F16
+:10B480004B99E0FC4456D96FD9AE3C64ED63E35A66
+:10B49000E0CD66570B3D9BDD1606FA7D58DE5BF26C
+:10B4A000A88EFDDD85BF8A38493E6E0358A4D37E41
+:10B4B0002778BF879B9F8EF3FEACFBBA203FCFF768
+:10B4C000712128E4D7BE77BDB04D4D8ADFB352EE6F
+:10B4D0004565A6F441EEBAE07DB2EEF7EE3975327D
+:10B4E00001DEA2CEE4FBD973CDFF43CF8E5327916B
+:10B4F0005F0E575E58BE0E59758D584F35D3C9E64D
+:10B50000339BEFB2E88839B3CF1FF28D75A6B3C372
+:10B510001D9D420E52F93195FF34D718DBF143EBF4
+:10B5200092E1DCD029E4F8060B4E4EA19E4FEFEDE0
+:10B530007B4C747FEAE934EB7EBA53E5F1337C6DE2
+:10B54000DBF9772ECDCE2F6B1176DEBF2A83EC3C54
+:10B55000E2F365BAC7F67B940F4890EB3E6FB29F5B
+:10B5600069DBF9C73B457CF062DE5512D9E91CCF97
+:10B5700004FBBF59D5C97980543BAD3A431C37AA67
+:10B58000F9AAAD6FB89EF55AC7FB4F4410CEFEF82E
+:10B590003EAE0F6522FF66484CA7483A3A4179F221
+:10B5A000BD9AF24E10BF63D3855EC85AAB70BD63BF
+:10B5B000C8F15EF587D82AB130042DB883CCB7FB2B
+:10B5C000C7F97E8EC5F773D1933E7F5A63FD2E85F2
+:10B5D000EA88F56F56A78B2BEC96EE4F25DF77BFE9
+:10B5E00038B9F8FB4EABBE9C0119422E9A1D7D6402
+:10B5F000EF9B1D7C2F85AEEF2A6BACD201D5F56990
+:10B6000067F8DE4FF77F24AB5EB474465EE0567198
+:10B61000AFE5EC0E714F867F47B8947EF739C1BF16
+:10B620000FBC926EB1CAEC07B3DC9C850207D583D0
+:10B6300023272469DA0FBA82AE341A0E9A570241D0
+:10B640006E53F77D1584F97919C4B8BD06C6B82DB7
+:10B6500087716E2B60925B9326E07E8D93A2AEB1D4
+:10B660000A0C999E574290DB3510E6B61A62DC7ED2
+:10B67000A5FE6F7F733B4EF9DA797811784D23DFA1
+:10B6800071043A7D7E1BCFAD9D3AF3C95CF4EEF3B5
+:10B690004DB01F5F5F3DCE7EA8D71364FE76FA05DE
+:10B6A0007FDB709CB3E4836D3F49253F69751AFECB
+:10B6B0009DC34F4AFD1DC9FF0229F7D0B3D04500F5
+:10B6C0000000000000000000000000180000000062
+:10B6D000000000000000004000000000000000002A
+:10B6E0000000002800000000000000000000001022
+:10B6F000000000000000000000000020000000002A
+:10B700000000000000000010000000000000000029
+:10B710000000000800000000000000000000000021
+:10B7200000000000000000000000003900000000E0
+:10B7300000000000000000380000000000000000D1
+:10B7400000000000000000000000000000000008F1
+:10B7500000000000000000000000000000000000E9
+:10B76000000000000000000C0000000000000000CD
+:10B770000000000E000000000000000000000004B7
+:10B7800000000000000000000000001800000000A1
+:10B79000000000000000001C00000000000000008D
+:10B7A0000000001C0000000000000000000000136A
+:10B7B00000000000000000000000003A000000004F
+:10B7C0000000000000000001000000000000000078
+:10B7D0000000000200000000000000000000000166
+:10B7E0000000000000000000000000100000000049
+:10B7F00000000000000000500000000000000000F9
+:10B800000000000000000000000000000000000335
+:10B810000000000000000000000000AB000000007D
+:10B820000000000000000008000000000000000010
+:10B830000000C00000100000000000080000C00868
+:10B8400000100000000000020000C0000010000016
+:10B850000000001000009FB0000000000000000881
+:10B860000000C08000100000000000040000C0883C
+:10B8700000100000000000020000C0800010000066
+:10B8800000000010000091200000000000000008EF
+:10B8900000009340000100040000000100009348F4
+:10B8A00000000000000000020000935000000000B3
+:10B8B0000000000800009354000000000000000297
+:10B8C00000009418000000000000000800009358D9
+:10B8D000000800000000000800009AB000400000CE
+:10B8E00000000040000093980008000000000008DD
+:10B8F000000093D800080000000000080000942019
+:10B9000000C8000000000098000095B000980000FA
+:10B9100000000028000095F00098000000000028BA
+:10B920000000C480054000300000054000009D205C
+:10B93000000800000000000100009D210008000038
+:10B9400000000001000020080010000000000010AE
+:10B9500000002000000000000000000800009CD84B
+:10B96000000800000000000200009D180000000018
+:10B9700000000001000000010000000000000000C5
+:10B9800000000009000000000000000000000002AC
+:10B9900000000000000000000000CF2000000000B8
+:10B9A000000000200000CF46000000000000000161
+:10B9B0000000600000200000000000200000730074
+:10B9C000000800000000000800009FA00000000028
+:10B9D0000000000100009FA800000000000000011E
+:10B9E00000009F60000000000000001000009F6346
+:10B9F000000000000000000100009F610000000046
+:10BA00000000000100009F6600000000000000012F
+:10BA100000009F67000000000000000000009F6819
+:10BA2000000000000000000400009F6C0000000007
+:10BA300000000004000000520000000000000000B0
+:10BA400000000003000000000000000000000003F0
+:10BA500000000000000000000000000500000000E1
+:10BA600000000000000000020000000000000000D4
+:10BA700000060000000000000000002000009F7091
+:10BA8000000000000000000100009F900000000086
+:10BA9000000000080000005300000000000000004B
+:10BAA00000009F98000000000000000200009F9C22
+:10BAB000000000000000000100009F9D0000000049
+:10BAC000000000010000000900000000000000006C
+:10BAD0000000000100000000000000000000004421
+:10BAE0000000000000000000000000010000000055
+:10BAF00000000000000000500000000000000000F6
+:10BB0000000000890000000000000000000012C8D2
+:10BB10000080000000000080000000010000000024
+:10BB2000000000000000A000071000000000071047
+:10BB300000001AC800000000000000080000AEC0AD
+:10BB400000080000000000080000AE4000080000EF
+:10BB5000000000080000AE8000080000000000089F
+:10BB6000000020080010000000000010000020006D
+:10BB700000000000000000080000A01007100040B6
+:10BB80000000004000001BF8000800000000000159
+:10BB900000001BF9000800000000000100001AD09E
+:10BBA000000000000000000100001AD800000000A2
+:10BBB0000000000200001ADA00000000000000028D
+:10BBC0008000000000000000000000000000AF0046
+:10BBD000000000000000002000001B78002800008A
+:10BBE000000000040000E000002000000000002031
+:10BBF0000000F300000800000000000800001AF038
+:10BC0000000000000000010800001B3700000000D9
+:10BC10000000000100001B0F0000000000000001F8
+:10BC200000001B70000000000000000400001B74F6
+:10BC300000000000000000040000005000000000B0
+:10BC400000000000000000030000000000000000F1
+:10BC500000000005000000000000000000000006D9
+:10BC600000000000000000000000000700000000CD
+:10BC70000000000000001BC80000000000000001E0
+:10BC800000001BE800000000000000080000005158
+:10BC9000000000000000000000001BD000000000B9
+:10BCA0000000000400001BD400000000000000049D
+:10BCB00000001BD8000000000000000400001BDC96
+:10BCC00000000000000000080000B00000180000A4
+:10BCD000000000180000C00000400000000000400C
+:10BCE0000000C00000400002000000010000C00190
+:10BCF00000400002000000000000E2000020000000
+:10BD0000000000200000E204000200080020000201
+:10BD10008000000000000000000000000000E200C1
+:10BD200000080020000000040000F40000280000CB
+:10BD3000000000280000F540001000000000001086
+:10BD40000000F5C000200000000000200000F5C049
+:10BD500000020020000000020000F30000200000AC
+:10BD6000000000200000200800100000000000106B
+:10BD70000000200000000000000000080000110882
+:10BD80000008000000000008000011680008000022
+:10BD900000000008000011A80008000000000008D2
+:10BDA00000001240000800000000000100001241E5
+:10BDB0000008000000000001000040000020000416
+:10BDC00000000010000059000030001800000010B2
+:10BDD0000000590800300018000000020000570061
+:10BDE00000080000000000010000570100080000EA
+:10BDF00000000001000011E8000000000000000148
+:10BE0000000011F00000000000000001000011F827
+:10BE100000000000000000100000124400080000B4
+:10BE2000000000040000400000200000000000208E
+:10BE30000000530000100000000000100000153842
+:10BE400000000000000000010000000300000000EE
+:10BE500000000000000000000000000000000000E2
+:10BE600000000001000000000000000000000004CD
+:10BE700000000000000000000000150800000000A5
+:10BE8000000000010000152800000000000000086C
+:10BE900000000050000000000000000000008308C7
+:10BEA0000080000000000080000000010000000091
+:10BEB000000000000000200800100000000000103A
+:10BEC00000002000000000000000000800008410B6
+:10BED0000008000000000008000084700008000056
+:10BEE0000000000800060000046000280000046054
+:10BEF00000008520000800000000000100008521EE
+:10BF000000080000000000018000000000000000A8
+:10BF10000000000000008408000000000000000194
+:10BF2000000084F40008000000000002000084F615
+:10BF3000000800000000000200008504001000005E
+:10BF400000000004000087600000000000000020E6
+:10BF500000006000002000000000002000007300CE
+:10BF600000080000000000080000000300000000BE
+:10BF700000000000000000050000000000000000BC
+:10BF800000000006000000000000000000000007A4
+:10BF90000000000000000000000088080000000011
+:10BFA00000000001000088280000000000000008D8
+:10BFB0000000005000000000000000000000881099
+:10BFC00000000000000000040000881400000000D1
+:10BFD00000000004000088180000000000000004B9
+:10BFE0000000881C00000000000000080000300075
+:10BFF0000040000000000008000030080040000081
+:10C00000000000280000339001C00010000000086C
+:10C010000000320000200000000000200000372057
+:10C02000000000000000000800001020062000387A
+:10C03000000000080000A000000000000000200038
+:10C0400000003EA9000000000000000100003EC802
+:10C05000000000000000000280000000000000005E
+:10C060000000000000006000002000000000000848
+:10C070000000400000080000000000010000400136
+:10C08000000800000000000100004040000800041B
+:10C0900000000002000040600008000400000004EE
+:10C0A0000000400000080000000000040000400400
+:10C0B00000080000000000040000404000000000F4
+:10C0C00000000008000040480000000000000008D8
+:10C0D0000000800000000000000000100000504040
+:10C0E00000010004000000010000500000000000FA
+:10C0F00000000020000050080010000000000004B4
+:10C100000000500C0010000000000001000052C7A9
+:10C110000000000000000001000052C60000000006
+:10C120000000000100003000003000180000000492
+:10C130000000300400300018000000040000300847
+:10C1400000300018000000020000300A0030001823
+:10C15000000000020000300C003000180000000158
+:10C160000000300D00300018000000010000300E0B
+:10C1700000300018000000010000301000300018EE
+:10C18000000000040000301400300018000000041B
+:10C19000000050000100008000080004000050046E
+:10C1A00001000080000800040000000A00000000F8
+:10C1B0000000000000005068010000800000000145
+:10C1C0000000506901000080000000010000506C78
+:10C1D00001000080000000020000506E010000809D
+:10C1E0000000000200005070010000800000000408
+:10C1F0000000507401000080000000040000506640
+:10C200000100008000000002000050640100008076
+:10C2100000000001000050600100008000000002EA
+:10C220000000506201000080000000020000505039
+:10C230000100008000000004000050540100008054
+:10C2400000000004000050580100008000000004BD
+:10C250000000505C01000080000000040000507CE1
+:10C2600001000080000000010000507D01000080FE
+:10C270000000000100004018001000000000000451
+:10C2800000004090001000000000000400004098F2
+:10C290000010000000000004000041100000000039
+:10C2A0000000000200004112000000000000000237
+:10C2B00000004114000000000000000200004116D0
+:10C2C00000000000000000020000604000080000C4
+:10C2D00000000002000060420008000000000002B0
+:10C2E00000006044000800000000000400006080BE
+:10C2F0000008000000000008000060C000400008C6
+:10C3000000000008000060000008000000000002BB
+:10C31000000060020008000000000001000060044E
+:10C320000008000000000002000063400008000058
+:10C330000000000800006380000800000000000406
+:10C34000000063840008000000000001000063C0DA
+:10C350000008000000000002000063C400080000A4
+:10C36000000000020000640000080000000000045B
+:10C3700000007000001000000000000400007004C5
+:10C380000010000000000004000070080010000011
+:10C3900000000004000090000008000000000002FF
+:10C3A000000090020008000000000001000090045E
+:10C3B000000800000000000200009040000800009B
+:10C3C000000000020000904400080000000000028D
+:10C3D000000090460008000000000002000096489F
+:10C3E0000008000000000008000090800008000025
+:10C3F000000000020000908400080000000000021D
+:10C40000000096880008000000000008000080403E
+:10C41000000800000000000100008041000800004A
+:10C420000000000100008042000800000000000140
+:10C4300000008043000800000000000100008000B0
+:10C440000008000000000002000080020008000058
+:10C45000000000010000800400080000000000024D
+:10C46000000080C00008000000000002000080C240
+:10C470000008000000000002000080C40008000066
+:10C4800000000002000080800008000000000001A1
+:10C490000000808100080000000000010000808290
+:10C4A0000008000000000001000080830008000078
+:10C4B000000000010000808400080000000000016E
+:10C4C0000000808500080000000000010000808658
+:10C4D00000080000000000010000600000080000EB
+:10C4E00000000002000060020008000000000001DF
+:10C4F000000060040008000000000002000060422C
+:10C5000000C00018000000020000604000C00018D9
+:10C51000000000020000604C00C00018000000088D
+:10C520000000604400C000180000000800006057D0
+:10C5300000C00018000000010000605400C0001896
+:10C54000000000020000605600C00018000000015A
+:10C55000000066400008000000000008000066803F
+:10C560000008000000000008000066C0000800008D
+:10C57000000000080000DA4200180000000000027D
+:10C580000000DE4000000000000000000000E000AD
+:10C5900000000000000000040000D0C00000000007
+:10C5A000000000040000D0C40000000000000004EF
+:10C5B0000000D0C800000000000000040000D0CC43
+:10C5C00000000000000000040000D0D000000000C7
+:10C5D000000000040000D0D40000000000000004AF
+:10C5E0000000D0D800000000000000040000D0C00F
+:10C5F00000000000000000200000DB000000000040
+:10C60000000000040000DB000000000000000068E3
+:10C610000000B94800000000000000000000D00049
+:10C6200000000000000000040000B0C00000000096
+:10C63000000000040000B0C400000000000000047E
+:10C640000000B0C800000000000000040000B0C0FE
+:10C6500000000000000000100000D6B00000000044
+:10C66000000000040000D6B4000000000000000438
+:10C670000000D6B800000000000000040000D6BC96
+:10C6800000000000000000040000D6B00000000020
+:10C69000000000100000D348000000000000000867
+:10C6A0000000D358000000000000008000000010CF
+:10C6B00000000000000000000000D358000000004F
+:10C6C0000000000800000000060209000000000051
+:00000001FF
diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h
index b847fc7b93f..60a7c49dcb4 100644
--- a/include/linux/ath9k_platform.h
+++ b/include/linux/ath9k_platform.h
@@ -23,6 +23,13 @@
struct ath9k_platform_data {
u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
+ u8 *macaddr;
+
+ int led_pin;
+ u32 gpio_mask;
+ u32 gpio_val;
+
+ bool is_clk_25mhz;
};
#endif /* _LINUX_ATH9K_PLATFORM_H */
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
new file mode 100644
index 00000000000..08763e4e848
--- /dev/null
+++ b/include/linux/bcma/bcma.h
@@ -0,0 +1,224 @@
+#ifndef LINUX_BCMA_H_
+#define LINUX_BCMA_H_
+
+#include <linux/pci.h>
+#include <linux/mod_devicetable.h>
+
+#include <linux/bcma/bcma_driver_chipcommon.h>
+#include <linux/bcma/bcma_driver_pci.h>
+
+#include "bcma_regs.h"
+
+struct bcma_device;
+struct bcma_bus;
+
+enum bcma_hosttype {
+ BCMA_HOSTTYPE_NONE,
+ BCMA_HOSTTYPE_PCI,
+ BCMA_HOSTTYPE_SDIO,
+};
+
+struct bcma_chipinfo {
+ u16 id;
+ u8 rev;
+ u8 pkg;
+};
+
+struct bcma_host_ops {
+ u8 (*read8)(struct bcma_device *core, u16 offset);
+ u16 (*read16)(struct bcma_device *core, u16 offset);
+ u32 (*read32)(struct bcma_device *core, u16 offset);
+ void (*write8)(struct bcma_device *core, u16 offset, u8 value);
+ void (*write16)(struct bcma_device *core, u16 offset, u16 value);
+ void (*write32)(struct bcma_device *core, u16 offset, u32 value);
+ /* Agent ops */
+ u32 (*aread32)(struct bcma_device *core, u16 offset);
+ void (*awrite32)(struct bcma_device *core, u16 offset, u32 value);
+};
+
+/* Core manufacturers */
+#define BCMA_MANUF_ARM 0x43B
+#define BCMA_MANUF_MIPS 0x4A7
+#define BCMA_MANUF_BCM 0x4BF
+
+/* Core class values. */
+#define BCMA_CL_SIM 0x0
+#define BCMA_CL_EROM 0x1
+#define BCMA_CL_CORESIGHT 0x9
+#define BCMA_CL_VERIF 0xB
+#define BCMA_CL_OPTIMO 0xD
+#define BCMA_CL_GEN 0xE
+#define BCMA_CL_PRIMECELL 0xF
+
+/* Core-ID values. */
+#define BCMA_CORE_OOB_ROUTER 0x367 /* Out of band */
+#define BCMA_CORE_INVALID 0x700
+#define BCMA_CORE_CHIPCOMMON 0x800
+#define BCMA_CORE_ILINE20 0x801
+#define BCMA_CORE_SRAM 0x802
+#define BCMA_CORE_SDRAM 0x803
+#define BCMA_CORE_PCI 0x804
+#define BCMA_CORE_MIPS 0x805
+#define BCMA_CORE_ETHERNET 0x806
+#define BCMA_CORE_V90 0x807
+#define BCMA_CORE_USB11_HOSTDEV 0x808
+#define BCMA_CORE_ADSL 0x809
+#define BCMA_CORE_ILINE100 0x80A
+#define BCMA_CORE_IPSEC 0x80B
+#define BCMA_CORE_UTOPIA 0x80C
+#define BCMA_CORE_PCMCIA 0x80D
+#define BCMA_CORE_INTERNAL_MEM 0x80E
+#define BCMA_CORE_MEMC_SDRAM 0x80F
+#define BCMA_CORE_OFDM 0x810
+#define BCMA_CORE_EXTIF 0x811
+#define BCMA_CORE_80211 0x812
+#define BCMA_CORE_PHY_A 0x813
+#define BCMA_CORE_PHY_B 0x814
+#define BCMA_CORE_PHY_G 0x815
+#define BCMA_CORE_MIPS_3302 0x816
+#define BCMA_CORE_USB11_HOST 0x817
+#define BCMA_CORE_USB11_DEV 0x818
+#define BCMA_CORE_USB20_HOST 0x819
+#define BCMA_CORE_USB20_DEV 0x81A
+#define BCMA_CORE_SDIO_HOST 0x81B
+#define BCMA_CORE_ROBOSWITCH 0x81C
+#define BCMA_CORE_PARA_ATA 0x81D
+#define BCMA_CORE_SATA_XORDMA 0x81E
+#define BCMA_CORE_ETHERNET_GBIT 0x81F
+#define BCMA_CORE_PCIE 0x820
+#define BCMA_CORE_PHY_N 0x821
+#define BCMA_CORE_SRAM_CTL 0x822
+#define BCMA_CORE_MINI_MACPHY 0x823
+#define BCMA_CORE_ARM_1176 0x824
+#define BCMA_CORE_ARM_7TDMI 0x825
+#define BCMA_CORE_PHY_LP 0x826
+#define BCMA_CORE_PMU 0x827
+#define BCMA_CORE_PHY_SSN 0x828
+#define BCMA_CORE_SDIO_DEV 0x829
+#define BCMA_CORE_ARM_CM3 0x82A
+#define BCMA_CORE_PHY_HT 0x82B
+#define BCMA_CORE_MIPS_74K 0x82C
+#define BCMA_CORE_MAC_GBIT 0x82D
+#define BCMA_CORE_DDR12_MEM_CTL 0x82E
+#define BCMA_CORE_PCIE_RC 0x82F /* PCIe Root Complex */
+#define BCMA_CORE_OCP_OCP_BRIDGE 0x830
+#define BCMA_CORE_SHARED_COMMON 0x831
+#define BCMA_CORE_OCP_AHB_BRIDGE 0x832
+#define BCMA_CORE_SPI_HOST 0x833
+#define BCMA_CORE_I2S 0x834
+#define BCMA_CORE_SDR_DDR1_MEM_CTL 0x835 /* SDR/DDR1 memory controller core */
+#define BCMA_CORE_SHIM 0x837 /* SHIM component in ubus/6362 */
+#define BCMA_CORE_DEFAULT 0xFFF
+
+#define BCMA_MAX_NR_CORES 16
+
+struct bcma_device {
+ struct bcma_bus *bus;
+ struct bcma_device_id id;
+
+ struct device dev;
+ bool dev_registered;
+
+ u8 core_index;
+
+ u32 addr;
+ u32 wrap;
+
+ void *drvdata;
+ struct list_head list;
+};
+
+static inline void *bcma_get_drvdata(struct bcma_device *core)
+{
+ return core->drvdata;
+}
+static inline void bcma_set_drvdata(struct bcma_device *core, void *drvdata)
+{
+ core->drvdata = drvdata;
+}
+
+struct bcma_driver {
+ const char *name;
+ const struct bcma_device_id *id_table;
+
+ int (*probe)(struct bcma_device *dev);
+ void (*remove)(struct bcma_device *dev);
+ int (*suspend)(struct bcma_device *dev, pm_message_t state);
+ int (*resume)(struct bcma_device *dev);
+ void (*shutdown)(struct bcma_device *dev);
+
+ struct device_driver drv;
+};
+extern
+int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
+static inline int bcma_driver_register(struct bcma_driver *drv)
+{
+ return __bcma_driver_register(drv, THIS_MODULE);
+}
+extern void bcma_driver_unregister(struct bcma_driver *drv);
+
+struct bcma_bus {
+ /* The MMIO area. */
+ void __iomem *mmio;
+
+ const struct bcma_host_ops *ops;
+
+ enum bcma_hosttype hosttype;
+ union {
+ /* Pointer to the PCI bus (only for BCMA_HOSTTYPE_PCI) */
+ struct pci_dev *host_pci;
+ /* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */
+ struct sdio_func *host_sdio;
+ };
+
+ struct bcma_chipinfo chipinfo;
+
+ struct bcma_device *mapped_core;
+ struct list_head cores;
+ u8 nr_cores;
+
+ struct bcma_drv_cc drv_cc;
+ struct bcma_drv_pci drv_pci;
+};
+
+extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
+{
+ return core->bus->ops->read8(core, offset);
+}
+extern inline u32 bcma_read16(struct bcma_device *core, u16 offset)
+{
+ return core->bus->ops->read16(core, offset);
+}
+extern inline u32 bcma_read32(struct bcma_device *core, u16 offset)
+{
+ return core->bus->ops->read32(core, offset);
+}
+extern inline
+void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
+{
+ core->bus->ops->write8(core, offset, value);
+}
+extern inline
+void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
+{
+ core->bus->ops->write16(core, offset, value);
+}
+extern inline
+void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
+{
+ core->bus->ops->write32(core, offset, value);
+}
+extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
+{
+ return core->bus->ops->aread32(core, offset);
+}
+extern inline
+void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
+{
+ core->bus->ops->awrite32(core, offset, value);
+}
+
+extern bool bcma_core_is_enabled(struct bcma_device *core);
+extern int bcma_core_enable(struct bcma_device *core, u32 flags);
+
+#endif /* LINUX_BCMA_H_ */
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
new file mode 100644
index 00000000000..083c3b6cd5c
--- /dev/null
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -0,0 +1,302 @@
+#ifndef LINUX_BCMA_DRIVER_CC_H_
+#define LINUX_BCMA_DRIVER_CC_H_
+
+/** ChipCommon core registers. **/
+#define BCMA_CC_ID 0x0000
+#define BCMA_CC_ID_ID 0x0000FFFF
+#define BCMA_CC_ID_ID_SHIFT 0
+#define BCMA_CC_ID_REV 0x000F0000
+#define BCMA_CC_ID_REV_SHIFT 16
+#define BCMA_CC_ID_PKG 0x00F00000
+#define BCMA_CC_ID_PKG_SHIFT 20
+#define BCMA_CC_ID_NRCORES 0x0F000000
+#define BCMA_CC_ID_NRCORES_SHIFT 24
+#define BCMA_CC_ID_TYPE 0xF0000000
+#define BCMA_CC_ID_TYPE_SHIFT 28
+#define BCMA_CC_CAP 0x0004 /* Capabilities */
+#define BCMA_CC_CAP_NRUART 0x00000003 /* # of UARTs */
+#define BCMA_CC_CAP_MIPSEB 0x00000004 /* MIPS in BigEndian Mode */
+#define BCMA_CC_CAP_UARTCLK 0x00000018 /* UART clock select */
+#define BCMA_CC_CAP_UARTCLK_INT 0x00000008 /* UARTs are driven by internal divided clock */
+#define BCMA_CC_CAP_UARTGPIO 0x00000020 /* UARTs on GPIO 15-12 */
+#define BCMA_CC_CAP_EXTBUS 0x000000C0 /* External buses present */
+#define BCMA_CC_CAP_FLASHT 0x00000700 /* Flash Type */
+#define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */
+#define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */
+#define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */
+#define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */
+#define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */
+#define BCMA_PLLTYPE_NONE 0x00000000
+#define BCMA_PLLTYPE_1 0x00010000 /* 48Mhz base, 3 dividers */
+#define BCMA_PLLTYPE_2 0x00020000 /* 48Mhz, 4 dividers */
+#define BCMA_PLLTYPE_3 0x00030000 /* 25Mhz, 2 dividers */
+#define BCMA_PLLTYPE_4 0x00008000 /* 48Mhz, 4 dividers */
+#define BCMA_PLLTYPE_5 0x00018000 /* 25Mhz, 4 dividers */
+#define BCMA_PLLTYPE_6 0x00028000 /* 100/200 or 120/240 only */
+#define BCMA_PLLTYPE_7 0x00038000 /* 25Mhz, 4 dividers */
+#define BCMA_CC_CAP_PCTL 0x00040000 /* Power Control */
+#define BCMA_CC_CAP_OTPS 0x00380000 /* OTP size */
+#define BCMA_CC_CAP_OTPS_SHIFT 19
+#define BCMA_CC_CAP_OTPS_BASE 5
+#define BCMA_CC_CAP_JTAGM 0x00400000 /* JTAG master present */
+#define BCMA_CC_CAP_BROM 0x00800000 /* Internal boot ROM active */
+#define BCMA_CC_CAP_64BIT 0x08000000 /* 64-bit Backplane */
+#define BCMA_CC_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */
+#define BCMA_CC_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */
+#define BCMA_CC_CAP_SPROM 0x40000000 /* SPROM present */
+#define BCMA_CC_CORECTL 0x0008
+#define BCMA_CC_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */
+#define BCMA_CC_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
+#define BCMA_CC_CORECTL_UARTCLKEN 0x00000008 /* UART clock enable (rev >= 21) */
+#define BCMA_CC_BIST 0x000C
+#define BCMA_CC_OTPS 0x0010 /* OTP status */
+#define BCMA_CC_OTPS_PROGFAIL 0x80000000
+#define BCMA_CC_OTPS_PROTECT 0x00000007
+#define BCMA_CC_OTPS_HW_PROTECT 0x00000001
+#define BCMA_CC_OTPS_SW_PROTECT 0x00000002
+#define BCMA_CC_OTPS_CID_PROTECT 0x00000004
+#define BCMA_CC_OTPC 0x0014 /* OTP control */
+#define BCMA_CC_OTPC_RECWAIT 0xFF000000
+#define BCMA_CC_OTPC_PROGWAIT 0x00FFFF00
+#define BCMA_CC_OTPC_PRW_SHIFT 8
+#define BCMA_CC_OTPC_MAXFAIL 0x00000038
+#define BCMA_CC_OTPC_VSEL 0x00000006
+#define BCMA_CC_OTPC_SELVL 0x00000001
+#define BCMA_CC_OTPP 0x0018 /* OTP prog */
+#define BCMA_CC_OTPP_COL 0x000000FF
+#define BCMA_CC_OTPP_ROW 0x0000FF00
+#define BCMA_CC_OTPP_ROW_SHIFT 8
+#define BCMA_CC_OTPP_READERR 0x10000000
+#define BCMA_CC_OTPP_VALUE 0x20000000
+#define BCMA_CC_OTPP_READ 0x40000000
+#define BCMA_CC_OTPP_START 0x80000000
+#define BCMA_CC_OTPP_BUSY 0x80000000
+#define BCMA_CC_IRQSTAT 0x0020
+#define BCMA_CC_IRQMASK 0x0024
+#define BCMA_CC_IRQ_GPIO 0x00000001 /* gpio intr */
+#define BCMA_CC_IRQ_EXT 0x00000002 /* ro: ext intr pin (corerev >= 3) */
+#define BCMA_CC_IRQ_WDRESET 0x80000000 /* watchdog reset occurred */
+#define BCMA_CC_CHIPCTL 0x0028 /* Rev >= 11 only */
+#define BCMA_CC_CHIPSTAT 0x002C /* Rev >= 11 only */
+#define BCMA_CC_JCMD 0x0030 /* Rev >= 10 only */
+#define BCMA_CC_JCMD_START 0x80000000
+#define BCMA_CC_JCMD_BUSY 0x80000000
+#define BCMA_CC_JCMD_PAUSE 0x40000000
+#define BCMA_CC_JCMD0_ACC_MASK 0x0000F000
+#define BCMA_CC_JCMD0_ACC_IRDR 0x00000000
+#define BCMA_CC_JCMD0_ACC_DR 0x00001000
+#define BCMA_CC_JCMD0_ACC_IR 0x00002000
+#define BCMA_CC_JCMD0_ACC_RESET 0x00003000
+#define BCMA_CC_JCMD0_ACC_IRPDR 0x00004000
+#define BCMA_CC_JCMD0_ACC_PDR 0x00005000
+#define BCMA_CC_JCMD0_IRW_MASK 0x00000F00
+#define BCMA_CC_JCMD_ACC_MASK 0x000F0000 /* Changes for corerev 11 */
+#define BCMA_CC_JCMD_ACC_IRDR 0x00000000
+#define BCMA_CC_JCMD_ACC_DR 0x00010000
+#define BCMA_CC_JCMD_ACC_IR 0x00020000
+#define BCMA_CC_JCMD_ACC_RESET 0x00030000
+#define BCMA_CC_JCMD_ACC_IRPDR 0x00040000
+#define BCMA_CC_JCMD_ACC_PDR 0x00050000
+#define BCMA_CC_JCMD_IRW_MASK 0x00001F00
+#define BCMA_CC_JCMD_IRW_SHIFT 8
+#define BCMA_CC_JCMD_DRW_MASK 0x0000003F
+#define BCMA_CC_JIR 0x0034 /* Rev >= 10 only */
+#define BCMA_CC_JDR 0x0038 /* Rev >= 10 only */
+#define BCMA_CC_JCTL 0x003C /* Rev >= 10 only */
+#define BCMA_CC_JCTL_FORCE_CLK 4 /* Force clock */
+#define BCMA_CC_JCTL_EXT_EN 2 /* Enable external targets */
+#define BCMA_CC_JCTL_EN 1 /* Enable Jtag master */
+#define BCMA_CC_FLASHCTL 0x0040
+#define BCMA_CC_FLASHCTL_START 0x80000000
+#define BCMA_CC_FLASHCTL_BUSY BCMA_CC_FLASHCTL_START
+#define BCMA_CC_FLASHADDR 0x0044
+#define BCMA_CC_FLASHDATA 0x0048
+#define BCMA_CC_BCAST_ADDR 0x0050
+#define BCMA_CC_BCAST_DATA 0x0054
+#define BCMA_CC_GPIOPULLUP 0x0058 /* Rev >= 20 only */
+#define BCMA_CC_GPIOPULLDOWN 0x005C /* Rev >= 20 only */
+#define BCMA_CC_GPIOIN 0x0060
+#define BCMA_CC_GPIOOUT 0x0064
+#define BCMA_CC_GPIOOUTEN 0x0068
+#define BCMA_CC_GPIOCTL 0x006C
+#define BCMA_CC_GPIOPOL 0x0070
+#define BCMA_CC_GPIOIRQ 0x0074
+#define BCMA_CC_WATCHDOG 0x0080
+#define BCMA_CC_GPIOTIMER 0x0088 /* LED powersave (corerev >= 16) */
+#define BCMA_CC_GPIOTIMER_OFFTIME 0x0000FFFF
+#define BCMA_CC_GPIOTIMER_OFFTIME_SHIFT 0
+#define BCMA_CC_GPIOTIMER_ONTIME 0xFFFF0000
+#define BCMA_CC_GPIOTIMER_ONTIME_SHIFT 16
+#define BCMA_CC_GPIOTOUTM 0x008C /* LED powersave (corerev >= 16) */
+#define BCMA_CC_CLOCK_N 0x0090
+#define BCMA_CC_CLOCK_SB 0x0094
+#define BCMA_CC_CLOCK_PCI 0x0098
+#define BCMA_CC_CLOCK_M2 0x009C
+#define BCMA_CC_CLOCK_MIPS 0x00A0
+#define BCMA_CC_CLKDIV 0x00A4 /* Rev >= 3 only */
+#define BCMA_CC_CLKDIV_SFLASH 0x0F000000
+#define BCMA_CC_CLKDIV_SFLASH_SHIFT 24
+#define BCMA_CC_CLKDIV_OTP 0x000F0000
+#define BCMA_CC_CLKDIV_OTP_SHIFT 16
+#define BCMA_CC_CLKDIV_JTAG 0x00000F00
+#define BCMA_CC_CLKDIV_JTAG_SHIFT 8
+#define BCMA_CC_CLKDIV_UART 0x000000FF
+#define BCMA_CC_CAP_EXT 0x00AC /* Capabilities */
+#define BCMA_CC_PLLONDELAY 0x00B0 /* Rev >= 4 only */
+#define BCMA_CC_FREFSELDELAY 0x00B4 /* Rev >= 4 only */
+#define BCMA_CC_SLOWCLKCTL 0x00B8 /* 6 <= Rev <= 9 only */
+#define BCMA_CC_SLOWCLKCTL_SRC 0x00000007 /* slow clock source mask */
+#define BCMA_CC_SLOWCLKCTL_SRC_LPO 0x00000000 /* source of slow clock is LPO */
+#define BCMA_CC_SLOWCLKCTL_SRC_XTAL 0x00000001 /* source of slow clock is crystal */
+#define BCMA_CC_SLOECLKCTL_SRC_PCI 0x00000002 /* source of slow clock is PCI */
+#define BCMA_CC_SLOWCLKCTL_LPOFREQ 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
+#define BCMA_CC_SLOWCLKCTL_LPOPD 0x00000400 /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
+#define BCMA_CC_SLOWCLKCTL_FSLOW 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
+#define BCMA_CC_SLOWCLKCTL_IPLL 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */
+#define BCMA_CC_SLOWCLKCTL_ENXTAL 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */
+#define BCMA_CC_SLOWCLKCTL_XTALPU 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */
+#define BCMA_CC_SLOWCLKCTL_CLKDIV 0xFFFF0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */
+#define BCMA_CC_SLOWCLKCTL_CLKDIV_SHIFT 16
+#define BCMA_CC_SYSCLKCTL 0x00C0 /* Rev >= 3 only */
+#define BCMA_CC_SYSCLKCTL_IDLPEN 0x00000001 /* ILPen: Enable Idle Low Power */
+#define BCMA_CC_SYSCLKCTL_ALPEN 0x00000002 /* ALPen: Enable Active Low Power */
+#define BCMA_CC_SYSCLKCTL_PLLEN 0x00000004 /* ForcePLLOn */
+#define BCMA_CC_SYSCLKCTL_FORCEALP 0x00000008 /* Force ALP (or HT if ALPen is not set */
+#define BCMA_CC_SYSCLKCTL_FORCEHT 0x00000010 /* Force HT */
+#define BCMA_CC_SYSCLKCTL_CLKDIV 0xFFFF0000 /* ClkDiv (ILP = 1/(4+divisor)) */
+#define BCMA_CC_SYSCLKCTL_CLKDIV_SHIFT 16
+#define BCMA_CC_CLKSTSTR 0x00C4 /* Rev >= 3 only */
+#define BCMA_CC_EROM 0x00FC
+#define BCMA_CC_PCMCIA_CFG 0x0100
+#define BCMA_CC_PCMCIA_MEMWAIT 0x0104
+#define BCMA_CC_PCMCIA_ATTRWAIT 0x0108
+#define BCMA_CC_PCMCIA_IOWAIT 0x010C
+#define BCMA_CC_IDE_CFG 0x0110
+#define BCMA_CC_IDE_MEMWAIT 0x0114
+#define BCMA_CC_IDE_ATTRWAIT 0x0118
+#define BCMA_CC_IDE_IOWAIT 0x011C
+#define BCMA_CC_PROG_CFG 0x0120
+#define BCMA_CC_PROG_WAITCNT 0x0124
+#define BCMA_CC_FLASH_CFG 0x0128
+#define BCMA_CC_FLASH_WAITCNT 0x012C
+#define BCMA_CC_CLKCTLST 0x01E0 /* Clock control and status (rev >= 20) */
+#define BCMA_CC_CLKCTLST_FORCEALP 0x00000001 /* Force ALP request */
+#define BCMA_CC_CLKCTLST_FORCEHT 0x00000002 /* Force HT request */
+#define BCMA_CC_CLKCTLST_FORCEILP 0x00000004 /* Force ILP request */
+#define BCMA_CC_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
+#define BCMA_CC_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
+#define BCMA_CC_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
+#define BCMA_CC_CLKCTLST_HAVEHT 0x00010000 /* HT available */
+#define BCMA_CC_CLKCTLST_HAVEALP 0x00020000 /* APL available */
+#define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
+#define BCMA_CC_UART0_DATA 0x0300
+#define BCMA_CC_UART0_IMR 0x0304
+#define BCMA_CC_UART0_FCR 0x0308
+#define BCMA_CC_UART0_LCR 0x030C
+#define BCMA_CC_UART0_MCR 0x0310
+#define BCMA_CC_UART0_LSR 0x0314
+#define BCMA_CC_UART0_MSR 0x0318
+#define BCMA_CC_UART0_SCRATCH 0x031C
+#define BCMA_CC_UART1_DATA 0x0400
+#define BCMA_CC_UART1_IMR 0x0404
+#define BCMA_CC_UART1_FCR 0x0408
+#define BCMA_CC_UART1_LCR 0x040C
+#define BCMA_CC_UART1_MCR 0x0410
+#define BCMA_CC_UART1_LSR 0x0414
+#define BCMA_CC_UART1_MSR 0x0418
+#define BCMA_CC_UART1_SCRATCH 0x041C
+/* PMU registers (rev >= 20) */
+#define BCMA_CC_PMU_CTL 0x0600 /* PMU control */
+#define BCMA_CC_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */
+#define BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
+#define BCMA_CC_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */
+#define BCMA_CC_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */
+#define BCMA_CC_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */
+#define BCMA_CC_PMU_CTL_XTALFREQ 0x0000007C /* Crystal freq */
+#define BCMA_CC_PMU_CTL_XTALFREQ_SHIFT 2
+#define BCMA_CC_PMU_CTL_ILPDIVEN 0x00000002 /* ILP div enable */
+#define BCMA_CC_PMU_CTL_LPOSEL 0x00000001 /* LPO sel */
+#define BCMA_CC_PMU_CAP 0x0604 /* PMU capabilities */
+#define BCMA_CC_PMU_CAP_REVISION 0x000000FF /* Revision mask */
+#define BCMA_CC_PMU_STAT 0x0608 /* PMU status */
+#define BCMA_CC_PMU_STAT_INTPEND 0x00000040 /* Interrupt pending */
+#define BCMA_CC_PMU_STAT_SBCLKST 0x00000030 /* Backplane clock status? */
+#define BCMA_CC_PMU_STAT_HAVEALP 0x00000008 /* ALP available */
+#define BCMA_CC_PMU_STAT_HAVEHT 0x00000004 /* HT available */
+#define BCMA_CC_PMU_STAT_RESINIT 0x00000003 /* Res init */
+#define BCMA_CC_PMU_RES_STAT 0x060C /* PMU res status */
+#define BCMA_CC_PMU_RES_PEND 0x0610 /* PMU res pending */
+#define BCMA_CC_PMU_TIMER 0x0614 /* PMU timer */
+#define BCMA_CC_PMU_MINRES_MSK 0x0618 /* PMU min res mask */
+#define BCMA_CC_PMU_MAXRES_MSK 0x061C /* PMU max res mask */
+#define BCMA_CC_PMU_RES_TABSEL 0x0620 /* PMU res table sel */
+#define BCMA_CC_PMU_RES_DEPMSK 0x0624 /* PMU res dep mask */
+#define BCMA_CC_PMU_RES_UPDNTM 0x0628 /* PMU res updown timer */
+#define BCMA_CC_PMU_RES_TIMER 0x062C /* PMU res timer */
+#define BCMA_CC_PMU_CLKSTRETCH 0x0630 /* PMU clockstretch */
+#define BCMA_CC_PMU_WATCHDOG 0x0634 /* PMU watchdog */
+#define BCMA_CC_PMU_RES_REQTS 0x0640 /* PMU res req timer sel */
+#define BCMA_CC_PMU_RES_REQT 0x0644 /* PMU res req timer */
+#define BCMA_CC_PMU_RES_REQM 0x0648 /* PMU res req mask */
+#define BCMA_CC_CHIPCTL_ADDR 0x0650
+#define BCMA_CC_CHIPCTL_DATA 0x0654
+#define BCMA_CC_REGCTL_ADDR 0x0658
+#define BCMA_CC_REGCTL_DATA 0x065C
+#define BCMA_CC_PLLCTL_ADDR 0x0660
+#define BCMA_CC_PLLCTL_DATA 0x0664
+
+/* Data for the PMU, if available.
+ * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
+ */
+struct bcma_chipcommon_pmu {
+ u8 rev; /* PMU revision */
+ u32 crystalfreq; /* The active crystal frequency (in kHz) */
+};
+
+struct bcma_drv_cc {
+ struct bcma_device *core;
+ u32 status;
+ u32 capabilities;
+ u32 capabilities_ext;
+ /* Fast Powerup Delay constant */
+ u16 fast_pwrup_delay;
+ struct bcma_chipcommon_pmu pmu;
+};
+
+/* Register access */
+#define bcma_cc_read32(cc, offset) \
+ bcma_read32((cc)->core, offset)
+#define bcma_cc_write32(cc, offset, val) \
+ bcma_write32((cc)->core, offset, val)
+
+#define bcma_cc_mask32(cc, offset, mask) \
+ bcma_cc_write32(cc, offset, bcma_cc_read32(cc, offset) & (mask))
+#define bcma_cc_set32(cc, offset, set) \
+ bcma_cc_write32(cc, offset, bcma_cc_read32(cc, offset) | (set))
+#define bcma_cc_maskset32(cc, offset, mask, set) \
+ bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set))
+
+extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc);
+
+extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
+extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
+
+extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
+ u32 ticks);
+
+void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value);
+
+u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask);
+
+/* Chipcommon GPIO pin access. */
+u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask);
+u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value);
+u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value);
+u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value);
+u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value);
+u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value);
+
+/* PMU support */
+extern void bcma_pmu_init(struct bcma_drv_cc *cc);
+
+#endif /* LINUX_BCMA_DRIVER_CC_H_ */
diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h
new file mode 100644
index 00000000000..b7e191cf00e
--- /dev/null
+++ b/include/linux/bcma/bcma_driver_pci.h
@@ -0,0 +1,89 @@
+#ifndef LINUX_BCMA_DRIVER_PCI_H_
+#define LINUX_BCMA_DRIVER_PCI_H_
+
+#include <linux/types.h>
+
+struct pci_dev;
+
+/** PCI core registers. **/
+#define BCMA_CORE_PCI_CTL 0x0000 /* PCI Control */
+#define BCMA_CORE_PCI_CTL_RST_OE 0x00000001 /* PCI_RESET Output Enable */
+#define BCMA_CORE_PCI_CTL_RST 0x00000002 /* PCI_RESET driven out to pin */
+#define BCMA_CORE_PCI_CTL_CLK_OE 0x00000004 /* Clock gate Output Enable */
+#define BCMA_CORE_PCI_CTL_CLK 0x00000008 /* Gate for clock driven out to pin */
+#define BCMA_CORE_PCI_ARBCTL 0x0010 /* PCI Arbiter Control */
+#define BCMA_CORE_PCI_ARBCTL_INTERN 0x00000001 /* Use internal arbiter */
+#define BCMA_CORE_PCI_ARBCTL_EXTERN 0x00000002 /* Use external arbiter */
+#define BCMA_CORE_PCI_ARBCTL_PARKID 0x00000006 /* Mask, selects which agent is parked on an idle bus */
+#define BCMA_CORE_PCI_ARBCTL_PARKID_LAST 0x00000000 /* Last requestor */
+#define BCMA_CORE_PCI_ARBCTL_PARKID_4710 0x00000002 /* 4710 */
+#define BCMA_CORE_PCI_ARBCTL_PARKID_EXT0 0x00000004 /* External requestor 0 */
+#define BCMA_CORE_PCI_ARBCTL_PARKID_EXT1 0x00000006 /* External requestor 1 */
+#define BCMA_CORE_PCI_ISTAT 0x0020 /* Interrupt status */
+#define BCMA_CORE_PCI_ISTAT_INTA 0x00000001 /* PCI INTA# */
+#define BCMA_CORE_PCI_ISTAT_INTB 0x00000002 /* PCI INTB# */
+#define BCMA_CORE_PCI_ISTAT_SERR 0x00000004 /* PCI SERR# (write to clear) */
+#define BCMA_CORE_PCI_ISTAT_PERR 0x00000008 /* PCI PERR# (write to clear) */
+#define BCMA_CORE_PCI_ISTAT_PME 0x00000010 /* PCI PME# */
+#define BCMA_CORE_PCI_IMASK 0x0024 /* Interrupt mask */
+#define BCMA_CORE_PCI_IMASK_INTA 0x00000001 /* PCI INTA# */
+#define BCMA_CORE_PCI_IMASK_INTB 0x00000002 /* PCI INTB# */
+#define BCMA_CORE_PCI_IMASK_SERR 0x00000004 /* PCI SERR# */
+#define BCMA_CORE_PCI_IMASK_PERR 0x00000008 /* PCI PERR# */
+#define BCMA_CORE_PCI_IMASK_PME 0x00000010 /* PCI PME# */
+#define BCMA_CORE_PCI_MBOX 0x0028 /* Backplane to PCI Mailbox */
+#define BCMA_CORE_PCI_MBOX_F0_0 0x00000100 /* PCI function 0, INT 0 */
+#define BCMA_CORE_PCI_MBOX_F0_1 0x00000200 /* PCI function 0, INT 1 */
+#define BCMA_CORE_PCI_MBOX_F1_0 0x00000400 /* PCI function 1, INT 0 */
+#define BCMA_CORE_PCI_MBOX_F1_1 0x00000800 /* PCI function 1, INT 1 */
+#define BCMA_CORE_PCI_MBOX_F2_0 0x00001000 /* PCI function 2, INT 0 */
+#define BCMA_CORE_PCI_MBOX_F2_1 0x00002000 /* PCI function 2, INT 1 */
+#define BCMA_CORE_PCI_MBOX_F3_0 0x00004000 /* PCI function 3, INT 0 */
+#define BCMA_CORE_PCI_MBOX_F3_1 0x00008000 /* PCI function 3, INT 1 */
+#define BCMA_CORE_PCI_BCAST_ADDR 0x0050 /* Backplane Broadcast Address */
+#define BCMA_CORE_PCI_BCAST_ADDR_MASK 0x000000FF
+#define BCMA_CORE_PCI_BCAST_DATA 0x0054 /* Backplane Broadcast Data */
+#define BCMA_CORE_PCI_GPIO_IN 0x0060 /* rev >= 2 only */
+#define BCMA_CORE_PCI_GPIO_OUT 0x0064 /* rev >= 2 only */
+#define BCMA_CORE_PCI_GPIO_ENABLE 0x0068 /* rev >= 2 only */
+#define BCMA_CORE_PCI_GPIO_CTL 0x006C /* rev >= 2 only */
+#define BCMA_CORE_PCI_SBTOPCI0 0x0100 /* Backplane to PCI translation 0 (sbtopci0) */
+#define BCMA_CORE_PCI_SBTOPCI0_MASK 0xFC000000
+#define BCMA_CORE_PCI_SBTOPCI1 0x0104 /* Backplane to PCI translation 1 (sbtopci1) */
+#define BCMA_CORE_PCI_SBTOPCI1_MASK 0xFC000000
+#define BCMA_CORE_PCI_SBTOPCI2 0x0108 /* Backplane to PCI translation 2 (sbtopci2) */
+#define BCMA_CORE_PCI_SBTOPCI2_MASK 0xC0000000
+#define BCMA_CORE_PCI_PCICFG0 0x0400 /* PCI config space 0 (rev >= 8) */
+#define BCMA_CORE_PCI_PCICFG1 0x0500 /* PCI config space 1 (rev >= 8) */
+#define BCMA_CORE_PCI_PCICFG2 0x0600 /* PCI config space 2 (rev >= 8) */
+#define BCMA_CORE_PCI_PCICFG3 0x0700 /* PCI config space 3 (rev >= 8) */
+#define BCMA_CORE_PCI_SPROM(wordoffset) (0x0800 + ((wordoffset) * 2)) /* SPROM shadow area (72 bytes) */
+
+/* SBtoPCIx */
+#define BCMA_CORE_PCI_SBTOPCI_MEM 0x00000000
+#define BCMA_CORE_PCI_SBTOPCI_IO 0x00000001
+#define BCMA_CORE_PCI_SBTOPCI_CFG0 0x00000002
+#define BCMA_CORE_PCI_SBTOPCI_CFG1 0x00000003
+#define BCMA_CORE_PCI_SBTOPCI_PREF 0x00000004 /* Prefetch enable */
+#define BCMA_CORE_PCI_SBTOPCI_BURST 0x00000008 /* Burst enable */
+#define BCMA_CORE_PCI_SBTOPCI_MRM 0x00000020 /* Memory Read Multiple */
+#define BCMA_CORE_PCI_SBTOPCI_RC 0x00000030 /* Read Command mask (rev >= 11) */
+#define BCMA_CORE_PCI_SBTOPCI_RC_READ 0x00000000 /* Memory read */
+#define BCMA_CORE_PCI_SBTOPCI_RC_READL 0x00000010 /* Memory read line */
+#define BCMA_CORE_PCI_SBTOPCI_RC_READM 0x00000020 /* Memory read multiple */
+
+/* PCIcore specific boardflags */
+#define BCMA_CORE_PCI_BFL_NOPCI 0x00000400 /* Board leaves PCI floating */
+
+struct bcma_drv_pci {
+ struct bcma_device *core;
+ u8 setup_done:1;
+};
+
+/* Register access */
+#define pcicore_read32(pc, offset) bcma_read32((pc)->core, offset)
+#define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val)
+
+extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
+
+#endif /* LINUX_BCMA_DRIVER_PCI_H_ */
diff --git a/include/linux/bcma/bcma_regs.h b/include/linux/bcma/bcma_regs.h
new file mode 100644
index 00000000000..f82d88a960c
--- /dev/null
+++ b/include/linux/bcma/bcma_regs.h
@@ -0,0 +1,34 @@
+#ifndef LINUX_BCMA_REGS_H_
+#define LINUX_BCMA_REGS_H_
+
+/* Agent registers (common for every core) */
+#define BCMA_IOCTL 0x0408
+#define BCMA_IOCTL_CLK 0x0001
+#define BCMA_IOCTL_FGC 0x0002
+#define BCMA_IOCTL_CORE_BITS 0x3FFC
+#define BCMA_IOCTL_PME_EN 0x4000
+#define BCMA_IOCTL_BIST_EN 0x8000
+#define BCMA_RESET_CTL 0x0800
+#define BCMA_RESET_CTL_RESET 0x0001
+
+/* BCMA PCI config space registers. */
+#define BCMA_PCI_PMCSR 0x44
+#define BCMA_PCI_PE 0x100
+#define BCMA_PCI_BAR0_WIN 0x80 /* Backplane address space 0 */
+#define BCMA_PCI_BAR1_WIN 0x84 /* Backplane address space 1 */
+#define BCMA_PCI_SPROMCTL 0x88 /* SPROM control */
+#define BCMA_PCI_SPROMCTL_WE 0x10 /* SPROM write enable */
+#define BCMA_PCI_BAR1_CONTROL 0x8c /* Address space 1 burst control */
+#define BCMA_PCI_IRQS 0x90 /* PCI interrupts */
+#define BCMA_PCI_IRQMASK 0x94 /* PCI IRQ control and mask (pcirev >= 6 only) */
+#define BCMA_PCI_BACKPLANE_IRQS 0x98 /* Backplane Interrupts */
+#define BCMA_PCI_BAR0_WIN2 0xAC
+#define BCMA_PCI_GPIO_IN 0xB0 /* GPIO Input (pcirev >= 3 only) */
+#define BCMA_PCI_GPIO_OUT 0xB4 /* GPIO Output (pcirev >= 3 only) */
+#define BCMA_PCI_GPIO_OUT_ENABLE 0xB8 /* GPIO Output Enable/Disable (pcirev >= 3 only) */
+#define BCMA_PCI_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
+#define BCMA_PCI_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */
+#define BCMA_PCI_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */
+#define BCMA_PCI_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */
+
+#endif /* LINUX_BCMA_REGS_H_ */
diff --git a/include/linux/can/core.h b/include/linux/can/core.h
index 6f70a6d3a16..5ce6b5d62ec 100644
--- a/include/linux/can/core.h
+++ b/include/linux/can/core.h
@@ -44,8 +44,8 @@ struct can_proto {
/* 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_proto_register(const struct can_proto *cp);
+extern void can_proto_unregister(const struct can_proto *cp);
extern int can_rx_register(struct net_device *dev, canid_t can_id,
canid_t mask,
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index dc80d829424..c6a850ab2ec 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -24,7 +24,10 @@ struct ethtool_cmd {
__u32 cmd;
__u32 supported; /* Features this interface supports */
__u32 advertising; /* Features this interface advertises */
- __u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */
+ __u16 speed; /* The forced speed (lower bits) in
+ * Mbps. Please use
+ * ethtool_cmd_speed()/_set() to
+ * access it */
__u8 duplex; /* Duplex, half or full */
__u8 port; /* Which connector port */
__u8 phy_address;
@@ -33,7 +36,10 @@ struct ethtool_cmd {
__u8 mdio_support;
__u32 maxtxpkt; /* Tx pkts before generating tx int */
__u32 maxrxpkt; /* Rx pkts before generating rx int */
- __u16 speed_hi;
+ __u16 speed_hi; /* The forced speed (upper
+ * bits) in Mbps. Please use
+ * ethtool_cmd_speed()/_set() to
+ * access it */
__u8 eth_tp_mdix;
__u8 reserved2;
__u32 lp_advertising; /* Features the link partner advertises */
@@ -41,14 +47,14 @@ struct ethtool_cmd {
};
static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
- __u32 speed)
+ __u32 speed)
{
ep->speed = (__u16)speed;
ep->speed_hi = (__u16)(speed >> 16);
}
-static inline __u32 ethtool_cmd_speed(struct ethtool_cmd *ep)
+static inline __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
{
return (ep->speed_hi << 16) | ep->speed;
}
@@ -229,6 +235,34 @@ struct ethtool_ringparam {
__u32 tx_pending;
};
+/**
+ * struct ethtool_channels - configuring number of network channel
+ * @cmd: ETHTOOL_{G,S}CHANNELS
+ * @max_rx: Read only. Maximum number of receive channel the driver support.
+ * @max_tx: Read only. Maximum number of transmit channel the driver support.
+ * @max_other: Read only. Maximum number of other channel the driver support.
+ * @max_combined: Read only. Maximum number of combined channel the driver
+ * support. Set of queues RX, TX or other.
+ * @rx_count: Valid values are in the range 1 to the max_rx.
+ * @tx_count: Valid values are in the range 1 to the max_tx.
+ * @other_count: Valid values are in the range 1 to the max_other.
+ * @combined_count: Valid values are in the range 1 to the max_combined.
+ *
+ * This can be used to configure RX, TX and other channels.
+ */
+
+struct ethtool_channels {
+ __u32 cmd;
+ __u32 max_rx;
+ __u32 max_tx;
+ __u32 max_other;
+ __u32 max_combined;
+ __u32 rx_count;
+ __u32 tx_count;
+ __u32 other_count;
+ __u32 combined_count;
+};
+
/* for configuring link flow control parameters */
struct ethtool_pauseparam {
__u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */
@@ -380,27 +414,42 @@ struct ethtool_usrip4_spec {
__u8 proto;
};
+union ethtool_flow_union {
+ struct ethtool_tcpip4_spec tcp_ip4_spec;
+ struct ethtool_tcpip4_spec udp_ip4_spec;
+ struct ethtool_tcpip4_spec sctp_ip4_spec;
+ struct ethtool_ah_espip4_spec ah_ip4_spec;
+ struct ethtool_ah_espip4_spec esp_ip4_spec;
+ struct ethtool_usrip4_spec usr_ip4_spec;
+ struct ethhdr ether_spec;
+ __u8 hdata[60];
+};
+
+struct ethtool_flow_ext {
+ __be16 vlan_etype;
+ __be16 vlan_tci;
+ __be32 data[2];
+};
+
/**
* struct ethtool_rx_flow_spec - specification for RX flow filter
* @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW
* @h_u: Flow fields to match (dependent on @flow_type)
- * @m_u: Masks for flow field bits to be ignored
+ * @h_ext: Additional fields to match
+ * @m_u: Masks for flow field bits to be matched
+ * @m_ext: Masks for additional field bits to be matched
+ * Note, all additional fields must be ignored unless @flow_type
+ * includes the %FLOW_EXT flag.
* @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC
* if packets should be discarded
* @location: Index of filter in hardware table
*/
struct ethtool_rx_flow_spec {
__u32 flow_type;
- union {
- struct ethtool_tcpip4_spec tcp_ip4_spec;
- struct ethtool_tcpip4_spec udp_ip4_spec;
- struct ethtool_tcpip4_spec sctp_ip4_spec;
- struct ethtool_ah_espip4_spec ah_ip4_spec;
- struct ethtool_ah_espip4_spec esp_ip4_spec;
- struct ethtool_usrip4_spec usr_ip4_spec;
- struct ethhdr ether_spec;
- __u8 hdata[72];
- } h_u, m_u;
+ union ethtool_flow_union h_u;
+ struct ethtool_flow_ext h_ext;
+ union ethtool_flow_union m_u;
+ struct ethtool_flow_ext m_ext;
__u64 ring_cookie;
__u32 location;
};
@@ -458,16 +507,10 @@ struct ethtool_rxnfc {
struct compat_ethtool_rx_flow_spec {
u32 flow_type;
- union {
- struct ethtool_tcpip4_spec tcp_ip4_spec;
- struct ethtool_tcpip4_spec udp_ip4_spec;
- struct ethtool_tcpip4_spec sctp_ip4_spec;
- struct ethtool_ah_espip4_spec ah_ip4_spec;
- struct ethtool_ah_espip4_spec esp_ip4_spec;
- struct ethtool_usrip4_spec usr_ip4_spec;
- struct ethhdr ether_spec;
- u8 hdata[72];
- } h_u, m_u;
+ union ethtool_flow_union h_u;
+ struct ethtool_flow_ext h_ext;
+ union ethtool_flow_union m_u;
+ struct ethtool_flow_ext m_ext;
compat_u64 ring_cookie;
u32 location;
};
@@ -558,6 +601,26 @@ struct ethtool_flash {
char data[ETHTOOL_FLASH_MAX_FILENAME];
};
+/**
+ * struct ethtool_dump - used for retrieving, setting device dump
+ * @cmd: Command number - %ETHTOOL_GET_DUMP_FLAG, %ETHTOOL_GET_DUMP_DATA, or
+ * %ETHTOOL_SET_DUMP
+ * @version: FW version of the dump, filled in by driver
+ * @flag: driver dependent flag for dump setting, filled in by driver during
+ * get and filled in by ethtool for set operation
+ * @len: length of dump data, used as the length of the user buffer on entry to
+ * %ETHTOOL_GET_DUMP_DATA and this is returned as dump length by driver
+ * for %ETHTOOL_GET_DUMP_FLAG command
+ * @data: data collected for get dump data operation
+ */
+struct ethtool_dump {
+ __u32 cmd;
+ __u32 version;
+ __u32 flag;
+ __u32 len;
+ __u8 data[0];
+};
+
/* for returning and changing feature sets */
/**
@@ -663,6 +726,22 @@ struct ethtool_rx_ntuple_list {
unsigned int count;
};
+/**
+ * enum ethtool_phys_id_state - indicator state for physical identification
+ * @ETHTOOL_ID_INACTIVE: Physical ID indicator should be deactivated
+ * @ETHTOOL_ID_ACTIVE: Physical ID indicator should be activated
+ * @ETHTOOL_ID_ON: LED should be turned on (used iff %ETHTOOL_ID_ACTIVE
+ * is not supported)
+ * @ETHTOOL_ID_OFF: LED should be turned off (used iff %ETHTOOL_ID_ACTIVE
+ * is not supported)
+ */
+enum ethtool_phys_id_state {
+ ETHTOOL_ID_INACTIVE,
+ ETHTOOL_ID_ACTIVE,
+ ETHTOOL_ID_ON,
+ ETHTOOL_ID_OFF
+};
+
struct net_device;
/* Some generic methods drivers may use in their ethtool_ops */
@@ -683,63 +762,131 @@ void ethtool_ntuple_flush(struct net_device *dev);
bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported);
/**
- * &ethtool_ops - Alter and report network device settings
- * get_settings: Get device-specific settings
- * set_settings: Set device-specific settings
- * get_drvinfo: Report driver information
- * get_regs: Get device registers
- * get_wol: Report whether Wake-on-Lan is enabled
- * set_wol: Turn Wake-on-Lan on or off
- * get_msglevel: Report driver message level
- * set_msglevel: Set driver message level
- * nway_reset: Restart autonegotiation
- * get_link: Get link status
- * get_eeprom: Read data from the device EEPROM
- * set_eeprom: Write data to the device EEPROM
- * get_coalesce: Get interrupt coalescing parameters
- * set_coalesce: Set interrupt coalescing parameters
- * get_ringparam: Report ring sizes
- * set_ringparam: Set ring sizes
- * get_pauseparam: Report pause parameters
- * set_pauseparam: Set pause parameters
- * get_rx_csum: Report whether receive checksums are turned on or off
- * set_rx_csum: Turn receive checksum on or off
- * get_tx_csum: Report whether transmit checksums are turned on or off
- * set_tx_csum: Turn transmit checksums on or off
- * get_sg: Report whether scatter-gather is enabled
- * set_sg: Turn scatter-gather on or off
- * get_tso: Report whether TCP segmentation offload is enabled
- * set_tso: Turn TCP segmentation offload on or off
- * get_ufo: Report whether UDP fragmentation offload is enabled
- * set_ufo: Turn UDP fragmentation offload on or off
- * self_test: Run specified self-tests
- * get_strings: Return a set of strings that describe the requested objects
- * phys_id: Identify the device
- * get_stats: Return statistics about the device
- * get_flags: get 32-bit flags bitmap
- * set_flags: set 32-bit flags bitmap
- *
- * Description:
- *
- * get_settings:
- * @get_settings is passed an &ethtool_cmd to fill in. It returns
- * an negative errno or zero.
- *
- * set_settings:
- * @set_settings is passed an &ethtool_cmd and should attempt to set
- * all the settings this device supports. It may return an error value
- * if something goes wrong (otherwise 0).
- *
- * get_eeprom:
+ * struct ethtool_ops - optional netdev operations
+ * @get_settings: Get various device settings including Ethernet link
+ * settings. The @cmd parameter is expected to have been cleared
+ * before get_settings is called. Returns a negative error code or
+ * zero.
+ * @set_settings: Set various device settings including Ethernet link
+ * settings. Returns a negative error code or zero.
+ * @get_drvinfo: Report driver/device information. Should only set the
+ * @driver, @version, @fw_version and @bus_info fields. If not
+ * implemented, the @driver and @bus_info fields will be filled in
+ * according to the netdev's parent device.
+ * @get_regs_len: Get buffer length required for @get_regs
+ * @get_regs: Get device registers
+ * @get_wol: Report whether Wake-on-Lan is enabled
+ * @set_wol: Turn Wake-on-Lan on or off. Returns a negative error code
+ * or zero.
+ * @get_msglevel: Report driver message level. This should be the value
+ * of the @msg_enable field used by netif logging functions.
+ * @set_msglevel: Set driver message level
+ * @nway_reset: Restart autonegotiation. Returns a negative error code
+ * or zero.
+ * @get_link: Report whether physical link is up. Will only be called if
+ * the netdev is up. Should usually be set to ethtool_op_get_link(),
+ * which uses netif_carrier_ok().
+ * @get_eeprom: Read data from the device EEPROM.
* Should fill in the magic field. Don't need to check len for zero
* or wraparound. Fill in the data argument with the eeprom values
* from offset to offset + len. Update len to the amount read.
* Returns an error or zero.
- *
- * set_eeprom:
+ * @set_eeprom: Write data to the device EEPROM.
* Should validate the magic field. Don't need to check len for zero
* or wraparound. Update len to the amount written. Returns an error
* or zero.
+ * @get_coalesce: Get interrupt coalescing parameters. Returns a negative
+ * error code or zero.
+ * @set_coalesce: Set interrupt coalescing parameters. Returns a negative
+ * error code or zero.
+ * @get_ringparam: Report ring sizes
+ * @set_ringparam: Set ring sizes. Returns a negative error code or zero.
+ * @get_pauseparam: Report pause parameters
+ * @set_pauseparam: Set pause parameters. Returns a negative error code
+ * or zero.
+ * @get_rx_csum: Deprecated in favour of the netdev feature %NETIF_F_RXCSUM.
+ * Report whether receive checksums are turned on or off.
+ * @set_rx_csum: Deprecated in favour of generic netdev features. Turn
+ * receive checksum on or off. Returns a negative error code or zero.
+ * @get_tx_csum: Deprecated as redundant. Report whether transmit checksums
+ * are turned on or off.
+ * @set_tx_csum: Deprecated in favour of generic netdev features. Turn
+ * transmit checksums on or off. Returns a egative error code or zero.
+ * @get_sg: Deprecated as redundant. Report whether scatter-gather is
+ * enabled.
+ * @set_sg: Deprecated in favour of generic netdev features. Turn
+ * scatter-gather on or off. Returns a negative error code or zero.
+ * @get_tso: Deprecated as redundant. Report whether TCP segmentation
+ * offload is enabled.
+ * @set_tso: Deprecated in favour of generic netdev features. Turn TCP
+ * segmentation offload on or off. Returns a negative error code or zero.
+ * @self_test: Run specified self-tests
+ * @get_strings: Return a set of strings that describe the requested objects
+ * @set_phys_id: Identify the physical devices, e.g. by flashing an LED
+ * attached to it. The implementation may update the indicator
+ * asynchronously or synchronously, but in either case it must return
+ * quickly. It is initially called with the argument %ETHTOOL_ID_ACTIVE,
+ * and must either activate asynchronous updates and return zero, return
+ * a negative error or return a positive frequency for synchronous
+ * indication (e.g. 1 for one on/off cycle per second). If it returns
+ * a frequency then it will be called again at intervals with the
+ * argument %ETHTOOL_ID_ON or %ETHTOOL_ID_OFF and should set the state of
+ * the indicator accordingly. Finally, it is called with the argument
+ * %ETHTOOL_ID_INACTIVE and must deactivate the indicator. Returns a
+ * negative error code or zero.
+ * @get_ethtool_stats: Return extended statistics about the device.
+ * This is only useful if the device maintains statistics not
+ * included in &struct rtnl_link_stats64.
+ * @begin: Function to be called before any other operation. Returns a
+ * negative error code or zero.
+ * @complete: Function to be called after any other operation except
+ * @begin. Will be called even if the other operation failed.
+ * @get_ufo: Deprecated as redundant. Report whether UDP fragmentation
+ * offload is enabled.
+ * @set_ufo: Deprecated in favour of generic netdev features. Turn UDP
+ * fragmentation offload on or off. Returns a negative error code or zero.
+ * @get_flags: Deprecated as redundant. Report features included in
+ * &enum ethtool_flags that are enabled.
+ * @set_flags: Deprecated in favour of generic netdev features. Turn
+ * features included in &enum ethtool_flags on or off. Returns a
+ * negative error code or zero.
+ * @get_priv_flags: Report driver-specific feature flags.
+ * @set_priv_flags: Set driver-specific feature flags. Returns a negative
+ * error code or zero.
+ * @get_sset_count: Get number of strings that @get_strings will write.
+ * @get_rxnfc: Get RX flow classification rules. Returns a negative
+ * error code or zero.
+ * @set_rxnfc: Set RX flow classification rules. Returns a negative
+ * error code or zero.
+ * @flash_device: Write a firmware image to device's flash memory.
+ * Returns a negative error code or zero.
+ * @reset: Reset (part of) the device, as specified by a bitmask of
+ * flags from &enum ethtool_reset_flags. Returns a negative
+ * error code or zero.
+ * @set_rx_ntuple: Set an RX n-tuple rule. Returns a negative error code
+ * or zero.
+ * @get_rx_ntuple: Deprecated.
+ * @get_rxfh_indir: Get the contents of the RX flow hash indirection table.
+ * Returns a negative error code or zero.
+ * @set_rxfh_indir: Set the contents of the RX flow hash indirection table.
+ * Returns a negative error code or zero.
+ * @get_channels: Get number of channels.
+ * @set_channels: Set number of channels. Returns a negative error code or
+ * zero.
+ * @get_dump_flag: Get dump flag indicating current dump length, version,
+ * and flag of the device.
+ * @get_dump_data: Get dump data.
+ * @set_dump: Set dump specific flags to the device.
+ *
+ * All operations are optional (i.e. the function pointer may be set
+ * to %NULL) and callers must take this into account. Callers must
+ * hold the RTNL, except that for @get_drvinfo the caller may or may
+ * not hold the RTNL.
+ *
+ * See the structures used by these operations for further documentation.
+ *
+ * See &struct net_device and &struct net_device_ops for documentation
+ * of the generic netdev features interface.
*/
struct ethtool_ops {
int (*get_settings)(struct net_device *, struct ethtool_cmd *);
@@ -778,7 +925,7 @@ struct ethtool_ops {
int (*set_tso)(struct net_device *, u32);
void (*self_test)(struct net_device *, struct ethtool_test *, u64 *);
void (*get_strings)(struct net_device *, u32 stringset, u8 *);
- int (*phys_id)(struct net_device *, u32);
+ int (*set_phys_id)(struct net_device *, enum ethtool_phys_id_state);
void (*get_ethtool_stats)(struct net_device *,
struct ethtool_stats *, u64 *);
int (*begin)(struct net_device *);
@@ -802,6 +949,13 @@ struct ethtool_ops {
struct ethtool_rxfh_indir *);
int (*set_rxfh_indir)(struct net_device *,
const struct ethtool_rxfh_indir *);
+ void (*get_channels)(struct net_device *, struct ethtool_channels *);
+ int (*set_channels)(struct net_device *, struct ethtool_channels *);
+ int (*get_dump_flag)(struct net_device *, struct ethtool_dump *);
+ int (*get_dump_data)(struct net_device *,
+ struct ethtool_dump *, void *);
+ int (*set_dump)(struct net_device *, struct ethtool_dump *);
+
};
#endif /* __KERNEL__ */
@@ -870,6 +1024,11 @@ struct ethtool_ops {
#define ETHTOOL_GFEATURES 0x0000003a /* Get device offload settings */
#define ETHTOOL_SFEATURES 0x0000003b /* Change device offload settings */
+#define ETHTOOL_GCHANNELS 0x0000003c /* Get no of channels */
+#define ETHTOOL_SCHANNELS 0x0000003d /* Set no of channels */
+#define ETHTOOL_SET_DUMP 0x0000003e /* Set dump settings */
+#define ETHTOOL_GET_DUMP_FLAG 0x0000003f /* Get dump settings */
+#define ETHTOOL_GET_DUMP_DATA 0x00000040 /* Get dump data */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
@@ -897,6 +1056,8 @@ struct ethtool_ops {
#define SUPPORTED_10000baseKX4_Full (1 << 18)
#define SUPPORTED_10000baseKR_Full (1 << 19)
#define SUPPORTED_10000baseR_FEC (1 << 20)
+#define SUPPORTED_20000baseMLD2_Full (1 << 21)
+#define SUPPORTED_20000baseKR2_Full (1 << 22)
/* Indicates what features are advertised by the interface. */
#define ADVERTISED_10baseT_Half (1 << 0)
@@ -920,6 +1081,8 @@ struct ethtool_ops {
#define ADVERTISED_10000baseKX4_Full (1 << 18)
#define ADVERTISED_10000baseKR_Full (1 << 19)
#define ADVERTISED_10000baseR_FEC (1 << 20)
+#define ADVERTISED_20000baseMLD2_Full (1 << 21)
+#define ADVERTISED_20000baseKR2_Full (1 << 22)
/* The following are all involved in forcing a particular link
* mode for the device for setting things. When getting the
@@ -992,6 +1155,8 @@ struct ethtool_ops {
#define IPV4_FLOW 0x10 /* hash only */
#define IPV6_FLOW 0x11 /* hash only */
#define ETHER_FLOW 0x12 /* spec only (ether_spec) */
+/* Flag to enable additional fields in struct ethtool_rx_flow_spec */
+#define FLOW_EXT 0x80000000
/* L3-L4 network traffic flow hash options */
#define RXH_L2DA (1 << 1)
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 45266b75409..4609b85e559 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -135,6 +135,8 @@ struct sk_filter
{
atomic_t refcnt;
unsigned int len; /* Number of filter blocks */
+ unsigned int (*bpf_func)(const struct sk_buff *skb,
+ const struct sock_filter *filter);
struct rcu_head rcu;
struct sock_filter insns[0];
};
@@ -153,6 +155,80 @@ extern unsigned int sk_run_filter(const struct sk_buff *skb,
extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
extern int sk_detach_filter(struct sock *sk);
extern int sk_chk_filter(struct sock_filter *filter, int flen);
+
+#ifdef CONFIG_BPF_JIT
+extern void bpf_jit_compile(struct sk_filter *fp);
+extern void bpf_jit_free(struct sk_filter *fp);
+#define SK_RUN_FILTER(FILTER, SKB) (*FILTER->bpf_func)(SKB, FILTER->insns)
+#else
+static inline void bpf_jit_compile(struct sk_filter *fp)
+{
+}
+static inline void bpf_jit_free(struct sk_filter *fp)
+{
+}
+#define SK_RUN_FILTER(FILTER, SKB) sk_run_filter(SKB, FILTER->insns)
+#endif
+
+enum {
+ BPF_S_RET_K = 1,
+ BPF_S_RET_A,
+ BPF_S_ALU_ADD_K,
+ BPF_S_ALU_ADD_X,
+ BPF_S_ALU_SUB_K,
+ BPF_S_ALU_SUB_X,
+ BPF_S_ALU_MUL_K,
+ BPF_S_ALU_MUL_X,
+ BPF_S_ALU_DIV_X,
+ BPF_S_ALU_AND_K,
+ BPF_S_ALU_AND_X,
+ BPF_S_ALU_OR_K,
+ BPF_S_ALU_OR_X,
+ BPF_S_ALU_LSH_K,
+ BPF_S_ALU_LSH_X,
+ BPF_S_ALU_RSH_K,
+ BPF_S_ALU_RSH_X,
+ BPF_S_ALU_NEG,
+ BPF_S_LD_W_ABS,
+ BPF_S_LD_H_ABS,
+ BPF_S_LD_B_ABS,
+ BPF_S_LD_W_LEN,
+ BPF_S_LD_W_IND,
+ BPF_S_LD_H_IND,
+ BPF_S_LD_B_IND,
+ BPF_S_LD_IMM,
+ BPF_S_LDX_W_LEN,
+ BPF_S_LDX_B_MSH,
+ BPF_S_LDX_IMM,
+ BPF_S_MISC_TAX,
+ BPF_S_MISC_TXA,
+ BPF_S_ALU_DIV_K,
+ BPF_S_LD_MEM,
+ BPF_S_LDX_MEM,
+ BPF_S_ST,
+ BPF_S_STX,
+ BPF_S_JMP_JA,
+ BPF_S_JMP_JEQ_K,
+ BPF_S_JMP_JEQ_X,
+ BPF_S_JMP_JGE_K,
+ BPF_S_JMP_JGE_X,
+ BPF_S_JMP_JGT_K,
+ BPF_S_JMP_JGT_X,
+ BPF_S_JMP_JSET_K,
+ BPF_S_JMP_JSET_X,
+ /* Ancillary data */
+ BPF_S_ANC_PROTOCOL,
+ BPF_S_ANC_PKTTYPE,
+ BPF_S_ANC_IFINDEX,
+ BPF_S_ANC_NLATTR,
+ BPF_S_ANC_NLATTR_NEST,
+ BPF_S_ANC_MARK,
+ BPF_S_ANC_QUEUE,
+ BPF_S_ANC_HATYPE,
+ BPF_S_ANC_RXHASH,
+ BPF_S_ANC_CPU,
+};
+
#endif /* __KERNEL__ */
#endif /* __LINUX_FILTER_H__ */
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 2d1c6117d92..b2eee587988 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -884,6 +884,15 @@ struct ieee80211_ht_cap {
#define IEEE80211_HT_CAP_40MHZ_INTOLERANT 0x4000
#define IEEE80211_HT_CAP_LSIG_TXOP_PROT 0x8000
+/* 802.11n HT extended capabilities masks (for extended_ht_cap_info) */
+#define IEEE80211_HT_EXT_CAP_PCO 0x0001
+#define IEEE80211_HT_EXT_CAP_PCO_TIME 0x0006
+#define IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT 1
+#define IEEE80211_HT_EXT_CAP_MCS_FB 0x0300
+#define IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT 8
+#define IEEE80211_HT_EXT_CAP_HTC_SUP 0x0400
+#define IEEE80211_HT_EXT_CAP_RD_RESPONDER 0x0800
+
/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */
#define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03
#define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C
@@ -993,6 +1002,11 @@ struct ieee80211_ht_info {
#define WLAN_CAPABILITY_ESS (1<<0)
#define WLAN_CAPABILITY_IBSS (1<<1)
+
+/* A mesh STA sets the ESS and IBSS capability bits to zero */
+#define WLAN_CAPABILITY_IS_MBSS(cap) \
+ (!((cap) & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)))
+
#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
#define WLAN_CAPABILITY_PRIVACY (1<<4)
@@ -1252,9 +1266,8 @@ enum ieee80211_category {
WLAN_CATEGORY_MULTIHOP_ACTION = 14,
WLAN_CATEGORY_SELF_PROTECTED = 15,
WLAN_CATEGORY_WMM = 17,
- /* TODO: remove MESH_PLINK and MESH_PATH_SEL after */
- /* mesh is updated to current 802.11s draft */
- WLAN_CATEGORY_MESH_PLINK = 30,
+ /* TODO: remove MESH_PATH_SEL after mesh is updated
+ * to current 802.11s draft */
WLAN_CATEGORY_MESH_PATH_SEL = 32,
WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
@@ -1507,6 +1520,7 @@ static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
category = ((u8 *) hdr) + 24;
return *category != WLAN_CATEGORY_PUBLIC &&
*category != WLAN_CATEGORY_HT &&
+ *category != WLAN_CATEGORY_SELF_PROTECTED &&
*category != WLAN_CATEGORY_VENDOR_SPECIFIC;
}
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index be69043d289..0f1325d9829 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -136,6 +136,7 @@ int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr);
extern struct ctl_table ether_table[];
#endif
+int mac_pton(const char *s, u8 *mac);
extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len);
#endif
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 635e1faec41..290bd8ac94c 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -86,7 +86,6 @@ struct vlan_group {
* the vlan is attached to.
*/
unsigned int nr_vlans;
- int killall;
struct hlist_node hlist; /* linked list */
struct net_device **vlan_devices_arrays[VLAN_GROUP_ARRAY_SPLIT_PARTS];
struct rcu_head rcu;
@@ -132,7 +131,8 @@ extern u16 vlan_dev_vlan_id(const struct net_device *dev);
extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
u16 vlan_tci, int polling);
-extern bool vlan_hwaccel_do_receive(struct sk_buff **skb);
+extern bool vlan_do_receive(struct sk_buff **skb);
+extern struct sk_buff *vlan_untag(struct sk_buff *skb);
extern gro_result_t
vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
unsigned int vlan_tci, struct sk_buff *skb);
@@ -166,13 +166,18 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
return NET_XMIT_SUCCESS;
}
-static inline bool vlan_hwaccel_do_receive(struct sk_buff **skb)
+static inline bool vlan_do_receive(struct sk_buff **skb)
{
if ((*skb)->vlan_tci & VLAN_VID_MASK)
(*skb)->pkt_type = PACKET_OTHERHOST;
return false;
}
+static inline struct sk_buff *vlan_untag(struct sk_buff *skb)
+{
+ return skb;
+}
+
static inline gro_result_t
vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
unsigned int vlan_tci, struct sk_buff *skb)
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 48c007dae47..ae28e93fd07 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -382,6 +382,23 @@ struct ssb_device_id {
#define SSB_ANY_ID 0xFFFF
#define SSB_ANY_REV 0xFF
+/* Broadcom's specific AMBA core, see drivers/bcma/ */
+struct bcma_device_id {
+ __u16 manuf;
+ __u16 id;
+ __u8 rev;
+ __u8 class;
+};
+#define BCMA_CORE(_manuf, _id, _rev, _class) \
+ { .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, }
+#define BCMA_CORETABLE_END \
+ { 0, },
+
+#define BCMA_ANY_MANUF 0xFFFF
+#define BCMA_ANY_ID 0xFFFF
+#define BCMA_ANY_REV 0xFF
+#define BCMA_ANY_CLASS 0xFF
+
struct virtio_device_id {
__u32 device;
__u32 vendor;
diff --git a/include/linux/mroute.h b/include/linux/mroute.h
index b21d567692b..46caaf44339 100644
--- a/include/linux/mroute.h
+++ b/include/linux/mroute.h
@@ -244,6 +244,7 @@ struct mfc_cache {
#ifdef __KERNEL__
struct rtmsg;
extern int ipmr_get_route(struct net *net, struct sk_buff *skb,
+ __be32 saddr, __be32 daddr,
struct rtmsg *rtm, int nowait);
#endif
diff --git a/include/linux/net.h b/include/linux/net.h
index 94de83c0f87..1da55e9b6f0 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -42,6 +42,7 @@
#define SYS_RECVMSG 17 /* sys_recvmsg(2) */
#define SYS_ACCEPT4 18 /* sys_accept4(2) */
#define SYS_RECVMMSG 19 /* sys_recvmmsg(2) */
+#define SYS_SENDMMSG 20 /* sys_sendmmsg(2) */
typedef enum {
SS_FREE = 0, /* not allocated */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 0249fe7e387..ca333e79e10 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1020,9 +1020,6 @@ struct net_device {
* part of the usual set specified in Space.c.
*/
- unsigned char if_port; /* Selectable AUI, TP,..*/
- unsigned char dma; /* DMA channel */
-
unsigned long state;
struct list_head dev_list;
@@ -1035,7 +1032,7 @@ struct net_device {
u32 hw_features;
/* user-requested features */
u32 wanted_features;
- /* VLAN feature mask */
+ /* mask of features inheritable by VLAN devices */
u32 vlan_features;
/* Net device feature bits; if you change something,
@@ -1066,6 +1063,8 @@ struct net_device {
#define NETIF_F_NTUPLE (1 << 27) /* N-tuple filters supported */
#define NETIF_F_RXHASH (1 << 28) /* Receive hashing offload */
#define NETIF_F_RXCSUM (1 << 29) /* Receive checksumming offload */
+#define NETIF_F_NOCACHE_COPY (1 << 30) /* Use no-cache copyfromuser */
+#define NETIF_F_LOOPBACK (1 << 31) /* Enable loopback */
/* Segmentation offload features */
#define NETIF_F_GSO_SHIFT 16
@@ -1079,9 +1078,9 @@ struct net_device {
/* Features valid for ethtool to change */
/* = all defined minus driver/device-class-related */
-#define NETIF_F_NEVER_CHANGE (NETIF_F_HIGHDMA | NETIF_F_VLAN_CHALLENGED | \
+#define NETIF_F_NEVER_CHANGE (NETIF_F_VLAN_CHALLENGED | \
NETIF_F_LLTX | NETIF_F_NETNS_LOCAL)
-#define NETIF_F_ETHTOOL_BITS (0x3f3fffff & ~NETIF_F_NEVER_CHANGE)
+#define NETIF_F_ETHTOOL_BITS (0xff3fffff & ~NETIF_F_NEVER_CHANGE)
/* List of features with software fallbacks. */
#define NETIF_F_GSO_SOFTWARE (NETIF_F_TSO | NETIF_F_TSO_ECN | \
@@ -1095,9 +1094,14 @@ struct net_device {
#define NETIF_F_ALL_TSO (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
+#define NETIF_F_ALL_FCOE (NETIF_F_FCOE_CRC | NETIF_F_FCOE_MTU | \
+ NETIF_F_FSO)
+
#define NETIF_F_ALL_TX_OFFLOADS (NETIF_F_ALL_CSUM | NETIF_F_SG | \
NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
- NETIF_F_SCTP_CSUM | NETIF_F_FCOE_CRC)
+ NETIF_F_HIGHDMA | \
+ NETIF_F_SCTP_CSUM | \
+ NETIF_F_ALL_FCOE)
/*
* If one device supports one of these features, then enable them
@@ -1105,7 +1109,12 @@ struct net_device {
*/
#define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \
NETIF_F_SG | NETIF_F_HIGHDMA | \
- NETIF_F_FRAGLIST)
+ NETIF_F_FRAGLIST | NETIF_F_VLAN_CHALLENGED)
+ /*
+ * If one device doesn't support one of these features, then disable it
+ * for all in netdev_increment_features.
+ */
+#define NETIF_F_ALL_FOR_ALL (NETIF_F_NOCACHE_COPY | NETIF_F_FSO)
/* changeable features with no special hardware requirements */
#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO)
@@ -1134,13 +1143,16 @@ struct net_device {
const struct header_ops *header_ops;
unsigned int flags; /* interface flags (a la BSD) */
+ unsigned int priv_flags; /* Like 'flags' but invisible to userspace. */
unsigned short gflags;
- unsigned int priv_flags; /* Like 'flags' but invisible to userspace. */
unsigned short padded; /* How much padding added by alloc_netdev() */
unsigned char operstate; /* RFC2863 operstate */
unsigned char link_mode; /* mapping policy to operstate */
+ unsigned char if_port; /* Selectable AUI, TP,..*/
+ unsigned char dma; /* DMA channel */
+
unsigned int mtu; /* interface MTU value */
unsigned short type; /* interface hardware type */
unsigned short hard_header_len; /* hardware hdr length */
@@ -1281,7 +1293,9 @@ struct net_device {
NETREG_UNREGISTERED, /* completed unregister todo */
NETREG_RELEASED, /* called free_netdev */
NETREG_DUMMY, /* dummy device for NAPI poll */
- } reg_state:16;
+ } reg_state:8;
+
+ bool dismantle; /* device is going do be freed */
enum {
RTNL_LINK_INITIALIZED,
@@ -2513,6 +2527,7 @@ extern struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
extern int netdev_max_backlog;
extern int netdev_tstamp_prequeue;
extern int weight_p;
+extern int bpf_jit_enable;
extern int netdev_set_master(struct net_device *dev, struct net_device *master);
extern int netdev_set_bond_master(struct net_device *dev,
struct net_device *master);
@@ -2550,7 +2565,9 @@ static inline u32 netdev_get_wanted_features(struct net_device *dev)
}
u32 netdev_increment_features(u32 all, u32 one, u32 mask);
u32 netdev_fix_features(struct net_device *dev, u32 features);
+int __netdev_update_features(struct net_device *dev);
void netdev_update_features(struct net_device *dev);
+void netdev_change_features(struct net_device *dev);
void netif_stacked_transfer_operstate(const struct net_device *rootdev,
struct net_device *dev);
@@ -2588,13 +2605,8 @@ static inline int netif_is_bond_slave(struct net_device *dev)
extern struct pernet_operations __net_initdata loopback_net_ops;
-static inline int dev_ethtool_get_settings(struct net_device *dev,
- struct ethtool_cmd *cmd)
-{
- if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
- return -EOPNOTSUPP;
- return dev->ethtool_ops->get_settings(dev, cmd);
-}
+int dev_ethtool_get_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd);
static inline u32 dev_ethtool_get_rx_csum(struct net_device *dev)
{
diff --git a/include/linux/netfilter/ipset/ip_set_getport.h b/include/linux/netfilter/ipset/ip_set_getport.h
index 5aebd170f89..90d09300e95 100644
--- a/include/linux/netfilter/ipset/ip_set_getport.h
+++ b/include/linux/netfilter/ipset/ip_set_getport.h
@@ -22,7 +22,9 @@ static inline bool ip_set_proto_with_ports(u8 proto)
{
switch (proto) {
case IPPROTO_TCP:
+ case IPPROTO_SCTP:
case IPPROTO_UDP:
+ case IPPROTO_UDPLITE:
return true;
}
return false;
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 37219525ff6..32cddf78b13 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -456,72 +456,60 @@ extern void xt_proto_fini(struct net *net, u_int8_t af);
extern struct xt_table_info *xt_alloc_table_info(unsigned int size);
extern void xt_free_table_info(struct xt_table_info *info);
-/*
- * Per-CPU spinlock associated with per-cpu table entries, and
- * with a counter for the "reading" side that allows a recursive
- * reader to avoid taking the lock and deadlocking.
- *
- * "reading" is used by ip/arp/ip6 tables rule processing which runs per-cpu.
- * It needs to ensure that the rules are not being changed while the packet
- * is being processed. In some cases, the read lock will be acquired
- * twice on the same CPU; this is okay because of the count.
- *
- * "writing" is used when reading counters.
- * During replace any readers that are using the old tables have to complete
- * before freeing the old table. This is handled by the write locking
- * necessary for reading the counters.
+/**
+ * xt_recseq - recursive seqcount for netfilter use
+ *
+ * Packet processing changes the seqcount only if no recursion happened
+ * get_counters() can use read_seqcount_begin()/read_seqcount_retry(),
+ * because we use the normal seqcount convention :
+ * Low order bit set to 1 if a writer is active.
*/
-struct xt_info_lock {
- seqlock_t lock;
- unsigned char readers;
-};
-DECLARE_PER_CPU(struct xt_info_lock, xt_info_locks);
+DECLARE_PER_CPU(seqcount_t, xt_recseq);
-/*
- * Note: we need to ensure that preemption is disabled before acquiring
- * the per-cpu-variable, so we do it as a two step process rather than
- * using "spin_lock_bh()".
- *
- * We _also_ need to disable bottom half processing before updating our
- * nesting count, to make sure that the only kind of re-entrancy is this
- * code being called by itself: since the count+lock is not an atomic
- * operation, we can allow no races.
+/**
+ * xt_write_recseq_begin - start of a write section
*
- * _Only_ that special combination of being per-cpu and never getting
- * re-entered asynchronously means that the count is safe.
+ * Begin packet processing : all readers must wait the end
+ * 1) Must be called with preemption disabled
+ * 2) softirqs must be disabled too (or we should use irqsafe_cpu_add())
+ * Returns :
+ * 1 if no recursion on this cpu
+ * 0 if recursion detected
*/
-static inline void xt_info_rdlock_bh(void)
+static inline unsigned int xt_write_recseq_begin(void)
{
- struct xt_info_lock *lock;
+ unsigned int addend;
- local_bh_disable();
- lock = &__get_cpu_var(xt_info_locks);
- if (likely(!lock->readers++))
- write_seqlock(&lock->lock);
-}
+ /*
+ * Low order bit of sequence is set if we already
+ * called xt_write_recseq_begin().
+ */
+ addend = (__this_cpu_read(xt_recseq.sequence) + 1) & 1;
-static inline void xt_info_rdunlock_bh(void)
-{
- struct xt_info_lock *lock = &__get_cpu_var(xt_info_locks);
+ /*
+ * This is kind of a write_seqcount_begin(), but addend is 0 or 1
+ * We dont check addend value to avoid a test and conditional jump,
+ * since addend is most likely 1
+ */
+ __this_cpu_add(xt_recseq.sequence, addend);
+ smp_wmb();
- if (likely(!--lock->readers))
- write_sequnlock(&lock->lock);
- local_bh_enable();
+ return addend;
}
-/*
- * The "writer" side needs to get exclusive access to the lock,
- * regardless of readers. This must be called with bottom half
- * processing (and thus also preemption) disabled.
+/**
+ * xt_write_recseq_end - end of a write section
+ * @addend: return value from previous xt_write_recseq_begin()
+ *
+ * End packet processing : all readers can proceed
+ * 1) Must be called with preemption disabled
+ * 2) softirqs must be disabled too (or we should use irqsafe_cpu_add())
*/
-static inline void xt_info_wrlock(unsigned int cpu)
-{
- write_seqlock(&per_cpu(xt_info_locks, cpu).lock);
-}
-
-static inline void xt_info_wrunlock(unsigned int cpu)
+static inline void xt_write_recseq_end(unsigned int addend)
{
- write_sequnlock(&per_cpu(xt_info_locks, cpu).lock);
+ /* this is kind of a write_seqcount_end(), but addend is 0 or 1 */
+ smp_wmb();
+ __this_cpu_add(xt_recseq.sequence, addend);
}
/*
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index bbfa1093f60..c7ccaae15af 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -77,6 +77,39 @@
*/
/**
+ * DOC: Virtual interface / concurrency capabilities
+ *
+ * Some devices are able to operate with virtual MACs, they can have
+ * more than one virtual interface. The capability handling for this
+ * is a bit complex though, as there may be a number of restrictions
+ * on the types of concurrency that are supported.
+ *
+ * To start with, each device supports the interface types listed in
+ * the %NL80211_ATTR_SUPPORTED_IFTYPES attribute, but by listing the
+ * types there no concurrency is implied.
+ *
+ * Once concurrency is desired, more attributes must be observed:
+ * To start with, since some interface types are purely managed in
+ * software, like the AP-VLAN type in mac80211 for example, there's
+ * an additional list of these, they can be added at any time and
+ * are only restricted by some semantic restrictions (e.g. AP-VLAN
+ * cannot be added without a corresponding AP interface). This list
+ * is exported in the %NL80211_ATTR_SOFTWARE_IFTYPES attribute.
+ *
+ * Further, the list of supported combinations is exported. This is
+ * in the %NL80211_ATTR_INTERFACE_COMBINATIONS attribute. Basically,
+ * it exports a list of "groups", and at any point in time the
+ * interfaces that are currently active must fall into any one of
+ * the advertised groups. Within each group, there are restrictions
+ * on the number of interfaces of different types that are supported
+ * and also the number of different channels, along with potentially
+ * some other restrictions. See &enum nl80211_if_combination_attrs.
+ *
+ * All together, these attributes define the concurrency of virtual
+ * interfaces that a given device supports.
+ */
+
+/**
* enum nl80211_commands - supported nl80211 commands
*
* @NL80211_CMD_UNSPEC: unspecified command to catch errors
@@ -203,6 +236,28 @@
* @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons,
* partial scan results may be available
*
+ * @NL80211_CMD_START_SCHED_SCAN: start a scheduled scan at certain
+ * intervals, as specified by %NL80211_ATTR_SCHED_SCAN_INTERVAL.
+ * Like with normal scans, if SSIDs (%NL80211_ATTR_SCAN_SSIDS)
+ * are passed, they are used in the probe requests. For
+ * broadcast, a broadcast SSID must be passed (ie. an empty
+ * string). If no SSID is passed, no probe requests are sent and
+ * a passive scan is performed. %NL80211_ATTR_SCAN_FREQUENCIES,
+ * if passed, define which channels should be scanned; if not
+ * passed, all channels allowed for the current regulatory domain
+ * are used. Extra IEs can also be passed from the userspace by
+ * using the %NL80211_ATTR_IE attribute.
+ * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan
+ * @NL80211_CMD_SCHED_SCAN_RESULTS: indicates that there are scheduled scan
+ * results available.
+ * @NL80211_CMD_SCHED_SCAN_STOPPED: indicates that the scheduled scan has
+ * stopped. The driver may issue this event at any time during a
+ * scheduled scan. One reason for stopping the scan is if the hardware
+ * does not support starting an association or a normal scan while running
+ * a scheduled scan. This event is also sent when the
+ * %NL80211_CMD_STOP_SCHED_SCAN command is received or when the interface
+ * is brought down while a scheduled scan was running.
+ *
* @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation
* or noise level
* @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to
@@ -410,6 +465,24 @@
* notification. This event is used to indicate that an unprotected
* disassociation frame was dropped when MFP is in use.
*
+ * @NL80211_CMD_NEW_PEER_CANDIDATE: Notification on the reception of a
+ * beacon or probe response from a compatible mesh peer. This is only
+ * sent while no station information (sta_info) exists for the new peer
+ * candidate and when @NL80211_MESH_SETUP_USERSPACE_AUTH is set. On
+ * reception of this notification, userspace may decide to create a new
+ * station (@NL80211_CMD_NEW_STATION). To stop this notification from
+ * reoccurring, the userspace authentication daemon may want to create the
+ * new station with the AUTHENTICATED flag unset and maybe change it later
+ * depending on the authentication result.
+ *
+ * @NL80211_CMD_GET_WOWLAN: get Wake-on-Wireless-LAN (WoWLAN) settings.
+ * @NL80211_CMD_SET_WOWLAN: set Wake-on-Wireless-LAN (WoWLAN) settings.
+ * Since wireless is more complex than wired ethernet, it supports
+ * various triggers. These triggers can be configured through this
+ * command with the %NL80211_ATTR_WOWLAN_TRIGGERS attribute. For
+ * more background information, see
+ * http://wireless.kernel.org/en/users/Documentation/WoWLAN.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -522,6 +595,16 @@ enum nl80211_commands {
NL80211_CMD_UNPROT_DEAUTHENTICATE,
NL80211_CMD_UNPROT_DISASSOCIATE,
+ NL80211_CMD_NEW_PEER_CANDIDATE,
+
+ NL80211_CMD_GET_WOWLAN,
+ NL80211_CMD_SET_WOWLAN,
+
+ NL80211_CMD_START_SCHED_SCAN,
+ NL80211_CMD_STOP_SCHED_SCAN,
+ NL80211_CMD_SCHED_SCAN_RESULTS,
+ NL80211_CMD_SCHED_SCAN_STOPPED,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -545,6 +628,7 @@ enum nl80211_commands {
/* source-level API compatibility */
#define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG
#define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG
+#define NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE NL80211_MESH_SETUP_IE
/**
* enum nl80211_attrs - nl80211 netlink attributes
@@ -886,6 +970,31 @@ enum nl80211_commands {
* changed once the mesh is active.
* @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute
* containing attributes from &enum nl80211_meshconf_params.
+ * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver
+ * allows auth frames in a mesh to be passed to userspace for processing via
+ * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag.
+ * @NL80211_ATTR_STA_PLINK_STATE: The state of a mesh peer link as
+ * defined in &enum nl80211_plink_state. Used when userspace is
+ * driving the peer link management state machine.
+ * @NL80211_MESH_SETUP_USERSPACE_AMPE must be enabled.
+ *
+ * @NL80211_ATTR_WOWLAN_SUPPORTED: indicates, as part of the wiphy capabilities,
+ * the supported WoWLAN triggers
+ * @NL80211_ATTR_WOWLAN_TRIGGERS: used by %NL80211_CMD_SET_WOWLAN to
+ * indicate which WoW triggers should be enabled. This is also
+ * used by %NL80211_CMD_GET_WOWLAN to get the currently enabled WoWLAN
+ * triggers.
+
+ * @NL80211_ATTR_SCHED_SCAN_INTERVAL: Interval between scheduled scan
+ * cycles, in msecs.
+ *
+ * @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported
+ * interface combinations. In each nested item, it contains attributes
+ * defined in &enum nl80211_if_combination_attrs.
+ * @NL80211_ATTR_SOFTWARE_IFTYPES: Nested attribute (just like
+ * %NL80211_ATTR_SUPPORTED_IFTYPES) containing the interface types that
+ * are managed in software: interfaces of these types aren't subject to
+ * any restrictions in their number or combinations.
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -1074,6 +1183,17 @@ enum nl80211_attrs {
NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
+ NL80211_ATTR_SUPPORT_MESH_AUTH,
+ NL80211_ATTR_STA_PLINK_STATE,
+
+ NL80211_ATTR_WOWLAN_TRIGGERS,
+ NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED,
+
+ NL80211_ATTR_SCHED_SCAN_INTERVAL,
+
+ NL80211_ATTR_INTERFACE_COMBINATIONS,
+ NL80211_ATTR_SOFTWARE_IFTYPES,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -1126,7 +1246,9 @@ enum nl80211_attrs {
* @NL80211_IFTYPE_ADHOC: independent BSS member
* @NL80211_IFTYPE_STATION: managed BSS member
* @NL80211_IFTYPE_AP: access point
- * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points
+ * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points; VLAN interfaces
+ * are a bit special in that they must always be tied to a pre-existing
+ * AP type interface.
* @NL80211_IFTYPE_WDS: wireless distribution interface
* @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames
* @NL80211_IFTYPE_MESH_POINT: mesh point
@@ -1168,6 +1290,7 @@ enum nl80211_iftype {
* with short barker preamble
* @NL80211_STA_FLAG_WME: station is WME/QoS capable
* @NL80211_STA_FLAG_MFP: station uses management frame protection
+ * @NL80211_STA_FLAG_AUTHENTICATED: station is authenticated
* @NL80211_STA_FLAG_MAX: highest station flag number currently defined
* @__NL80211_STA_FLAG_AFTER_LAST: internal use
*/
@@ -1177,6 +1300,7 @@ enum nl80211_sta_flags {
NL80211_STA_FLAG_SHORT_PREAMBLE,
NL80211_STA_FLAG_WME,
NL80211_STA_FLAG_MFP,
+ NL80211_STA_FLAG_AUTHENTICATED,
/* keep last */
__NL80211_STA_FLAG_AFTER_LAST,
@@ -1222,6 +1346,36 @@ enum nl80211_rate_info {
};
/**
+ * enum nl80211_sta_bss_param - BSS information collected by STA
+ *
+ * These attribute types are used with %NL80211_STA_INFO_BSS_PARAM
+ * when getting information about the bitrate of a station.
+ *
+ * @__NL80211_STA_BSS_PARAM_INVALID: attribute number 0 is reserved
+ * @NL80211_STA_BSS_PARAM_CTS_PROT: whether CTS protection is enabled (flag)
+ * @NL80211_STA_BSS_PARAM_SHORT_PREAMBLE: whether short preamble is enabled
+ * (flag)
+ * @NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME: whether short slot time is enabled
+ * (flag)
+ * @NL80211_STA_BSS_PARAM_DTIM_PERIOD: DTIM period for beaconing (u8)
+ * @NL80211_STA_BSS_PARAM_BEACON_INTERVAL: Beacon interval (u16)
+ * @NL80211_STA_BSS_PARAM_MAX: highest sta_bss_param number currently defined
+ * @__NL80211_STA_BSS_PARAM_AFTER_LAST: internal use
+ */
+enum nl80211_sta_bss_param {
+ __NL80211_STA_BSS_PARAM_INVALID,
+ NL80211_STA_BSS_PARAM_CTS_PROT,
+ NL80211_STA_BSS_PARAM_SHORT_PREAMBLE,
+ NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME,
+ NL80211_STA_BSS_PARAM_DTIM_PERIOD,
+ NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
+
+ /* keep last */
+ __NL80211_STA_BSS_PARAM_AFTER_LAST,
+ NL80211_STA_BSS_PARAM_MAX = __NL80211_STA_BSS_PARAM_AFTER_LAST - 1
+};
+
+/**
* enum nl80211_sta_info - station information
*
* These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -1233,7 +1387,7 @@ enum nl80211_rate_info {
* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station)
* @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm)
* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute
- * containing info as possible, see &enum nl80211_sta_info_txrate.
+ * containing info as possible, see &enum nl80211_rate_info
* @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station)
* @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this
* station)
@@ -1243,8 +1397,12 @@ enum nl80211_rate_info {
* @NL80211_STA_INFO_LLID: the station's mesh LLID
* @NL80211_STA_INFO_PLID: the station's mesh PLID
* @NL80211_STA_INFO_PLINK_STATE: peer link state for the station
+ * (see %enum nl80211_plink_state)
* @NL80211_STA_INFO_RX_BITRATE: last unicast data frame rx rate, nested
* attribute, like NL80211_STA_INFO_TX_BITRATE.
+ * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute
+ * containing info as possible, see &enum nl80211_sta_bss_param
+ * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected
* @__NL80211_STA_INFO_AFTER_LAST: internal
* @NL80211_STA_INFO_MAX: highest possible station info attribute
*/
@@ -1264,6 +1422,8 @@ enum nl80211_sta_info {
NL80211_STA_INFO_TX_FAILED,
NL80211_STA_INFO_SIGNAL_AVG,
NL80211_STA_INFO_RX_BITRATE,
+ NL80211_STA_INFO_BSS_PARAM,
+ NL80211_STA_INFO_CONNECTED_TIME,
/* keep last */
__NL80211_STA_INFO_AFTER_LAST,
@@ -1686,9 +1846,21 @@ enum nl80211_meshconf_params {
* vendor specific path metric or disable it to use the default Airtime
* metric.
*
- * @NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE: A vendor specific information
- * element that vendors will use to identify the path selection methods and
- * metrics in use.
+ * @NL80211_MESH_SETUP_IE: Information elements for this mesh, for instance, a
+ * robust security network ie, or a vendor specific information element that
+ * vendors will use to identify the path selection methods and metrics in use.
+ *
+ * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication
+ * daemon will be authenticating mesh candidates.
+ *
+ * @NL80211_MESH_SETUP_USERSPACE_AMPE: Enable this option if an authentication
+ * daemon will be securing peer link frames. AMPE is a secured version of Mesh
+ * Peering Management (MPM) and is implemented with the assistance of a
+ * userspace daemon. When this flag is set, the kernel will send peer
+ * management frames to a userspace daemon that will implement AMPE
+ * functionality (security capabilities selection, key confirmation, and key
+ * management). When the flag is unset (default), the kernel can autonomously
+ * complete (unsecured) mesh peering without the need of a userspace daemon.
*
* @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number
* @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
@@ -1697,7 +1869,9 @@ enum nl80211_mesh_setup_params {
__NL80211_MESH_SETUP_INVALID,
NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL,
NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC,
- NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE,
+ NL80211_MESH_SETUP_IE,
+ NL80211_MESH_SETUP_USERSPACE_AUTH,
+ NL80211_MESH_SETUP_USERSPACE_AMPE,
/* keep last */
__NL80211_MESH_SETUP_ATTR_AFTER_LAST,
@@ -2002,4 +2176,189 @@ enum nl80211_tx_power_setting {
NL80211_TX_POWER_FIXED,
};
+/**
+ * enum nl80211_wowlan_packet_pattern_attr - WoWLAN packet pattern attribute
+ * @__NL80211_WOWLAN_PKTPAT_INVALID: invalid number for nested attribute
+ * @NL80211_WOWLAN_PKTPAT_PATTERN: the pattern, values where the mask has
+ * a zero bit are ignored
+ * @NL80211_WOWLAN_PKTPAT_MASK: pattern mask, must be long enough to have
+ * a bit for each byte in the pattern. The lowest-order bit corresponds
+ * to the first byte of the pattern, but the bytes of the pattern are
+ * in a little-endian-like format, i.e. the 9th byte of the pattern
+ * corresponds to the lowest-order bit in the second byte of the mask.
+ * For example: The match 00:xx:00:00:xx:00:00:00:00:xx:xx:xx (where
+ * xx indicates "don't care") would be represented by a pattern of
+ * twelve zero bytes, and a mask of "0xed,0x07".
+ * Note that the pattern matching is done as though frames were not
+ * 802.11 frames but 802.3 frames, i.e. the frame is fully unpacked
+ * first (including SNAP header unpacking) and then matched.
+ * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes
+ * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number
+ */
+enum nl80211_wowlan_packet_pattern_attr {
+ __NL80211_WOWLAN_PKTPAT_INVALID,
+ NL80211_WOWLAN_PKTPAT_MASK,
+ NL80211_WOWLAN_PKTPAT_PATTERN,
+
+ NUM_NL80211_WOWLAN_PKTPAT,
+ MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1,
+};
+
+/**
+ * struct nl80211_wowlan_pattern_support - pattern support information
+ * @max_patterns: maximum number of patterns supported
+ * @min_pattern_len: minimum length of each pattern
+ * @max_pattern_len: maximum length of each pattern
+ *
+ * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when
+ * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the
+ * capability information given by the kernel to userspace.
+ */
+struct nl80211_wowlan_pattern_support {
+ __u32 max_patterns;
+ __u32 min_pattern_len;
+ __u32 max_pattern_len;
+} __attribute__((packed));
+
+/**
+ * enum nl80211_wowlan_triggers - WoWLAN trigger definitions
+ * @__NL80211_WOWLAN_TRIG_INVALID: invalid number for nested attributes
+ * @NL80211_WOWLAN_TRIG_ANY: wake up on any activity, do not really put
+ * the chip into a special state -- works best with chips that have
+ * support for low-power operation already (flag)
+ * @NL80211_WOWLAN_TRIG_DISCONNECT: wake up on disconnect, the way disconnect
+ * is detected is implementation-specific (flag)
+ * @NL80211_WOWLAN_TRIG_MAGIC_PKT: wake up on magic packet (6x 0xff, followed
+ * by 16 repetitions of MAC addr, anywhere in payload) (flag)
+ * @NL80211_WOWLAN_TRIG_PKT_PATTERN: wake up on the specified packet patterns
+ * which are passed in an array of nested attributes, each nested attribute
+ * defining a with attributes from &struct nl80211_wowlan_trig_pkt_pattern.
+ * Each pattern defines a wakeup packet. The matching is done on the MSDU,
+ * i.e. as though the packet was an 802.3 packet, so the pattern matching
+ * is done after the packet is converted to the MSDU.
+ *
+ * In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute
+ * carrying a &struct nl80211_wowlan_pattern_support.
+ * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers
+ * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number
+ */
+enum nl80211_wowlan_triggers {
+ __NL80211_WOWLAN_TRIG_INVALID,
+ NL80211_WOWLAN_TRIG_ANY,
+ NL80211_WOWLAN_TRIG_DISCONNECT,
+ NL80211_WOWLAN_TRIG_MAGIC_PKT,
+ NL80211_WOWLAN_TRIG_PKT_PATTERN,
+
+ /* keep last */
+ NUM_NL80211_WOWLAN_TRIG,
+ MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1
+};
+
+/**
+ * enum nl80211_iface_limit_attrs - limit attributes
+ * @NL80211_IFACE_LIMIT_UNSPEC: (reserved)
+ * @NL80211_IFACE_LIMIT_MAX: maximum number of interfaces that
+ * can be chosen from this set of interface types (u32)
+ * @NL80211_IFACE_LIMIT_TYPES: nested attribute containing a
+ * flag attribute for each interface type in this set
+ * @NUM_NL80211_IFACE_LIMIT: number of attributes
+ * @MAX_NL80211_IFACE_LIMIT: highest attribute number
+ */
+enum nl80211_iface_limit_attrs {
+ NL80211_IFACE_LIMIT_UNSPEC,
+ NL80211_IFACE_LIMIT_MAX,
+ NL80211_IFACE_LIMIT_TYPES,
+
+ /* keep last */
+ NUM_NL80211_IFACE_LIMIT,
+ MAX_NL80211_IFACE_LIMIT = NUM_NL80211_IFACE_LIMIT - 1
+};
+
+/**
+ * enum nl80211_if_combination_attrs -- interface combination attributes
+ *
+ * @NL80211_IFACE_COMB_UNSPEC: (reserved)
+ * @NL80211_IFACE_COMB_LIMITS: Nested attributes containing the limits
+ * for given interface types, see &enum nl80211_iface_limit_attrs.
+ * @NL80211_IFACE_COMB_MAXNUM: u32 attribute giving the total number of
+ * interfaces that can be created in this group. This number doesn't
+ * apply to interfaces purely managed in software, which are listed
+ * in a separate attribute %NL80211_ATTR_INTERFACES_SOFTWARE.
+ * @NL80211_IFACE_COMB_STA_AP_BI_MATCH: flag attribute specifying that
+ * beacon intervals within this group must be all the same even for
+ * infrastructure and AP/GO combinations, i.e. the GO(s) must adopt
+ * the infrastructure network's beacon interval.
+ * @NL80211_IFACE_COMB_NUM_CHANNELS: u32 attribute specifying how many
+ * different channels may be used within this group.
+ * @NUM_NL80211_IFACE_COMB: number of attributes
+ * @MAX_NL80211_IFACE_COMB: highest attribute number
+ *
+ * Examples:
+ * limits = [ #{STA} <= 1, #{AP} <= 1 ], matching BI, channels = 1, max = 2
+ * => allows an AP and a STA that must match BIs
+ *
+ * numbers = [ #{AP, P2P-GO} <= 8 ], channels = 1, max = 8
+ * => allows 8 of AP/GO
+ *
+ * numbers = [ #{STA} <= 2 ], channels = 2, max = 2
+ * => allows two STAs on different channels
+ *
+ * numbers = [ #{STA} <= 1, #{P2P-client,P2P-GO} <= 3 ], max = 4
+ * => allows a STA plus three P2P interfaces
+ *
+ * The list of these four possiblities could completely be contained
+ * within the %NL80211_ATTR_INTERFACE_COMBINATIONS attribute to indicate
+ * that any of these groups must match.
+ *
+ * "Combinations" of just a single interface will not be listed here,
+ * a single interface of any valid interface type is assumed to always
+ * be possible by itself. This means that implicitly, for each valid
+ * interface type, the following group always exists:
+ * numbers = [ #{<type>} <= 1 ], channels = 1, max = 1
+ */
+enum nl80211_if_combination_attrs {
+ NL80211_IFACE_COMB_UNSPEC,
+ NL80211_IFACE_COMB_LIMITS,
+ NL80211_IFACE_COMB_MAXNUM,
+ NL80211_IFACE_COMB_STA_AP_BI_MATCH,
+ NL80211_IFACE_COMB_NUM_CHANNELS,
+
+ /* keep last */
+ NUM_NL80211_IFACE_COMB,
+ MAX_NL80211_IFACE_COMB = NUM_NL80211_IFACE_COMB - 1
+};
+
+
+/**
+ * enum nl80211_plink_state - state of a mesh peer link finite state machine
+ *
+ * @NL80211_PLINK_LISTEN: initial state, considered the implicit
+ * state of non existant mesh peer links
+ * @NL80211_PLINK_OPN_SNT: mesh plink open frame has been sent to
+ * this mesh peer
+ * @NL80211_PLINK_OPN_RCVD: mesh plink open frame has been received
+ * from this mesh peer
+ * @NL80211_PLINK_CNF_RCVD: mesh plink confirm frame has been
+ * received from this mesh peer
+ * @NL80211_PLINK_ESTAB: mesh peer link is established
+ * @NL80211_PLINK_HOLDING: mesh peer link is being closed or cancelled
+ * @NL80211_PLINK_BLOCKED: all frames transmitted from this mesh
+ * plink are discarded
+ * @NUM_NL80211_PLINK_STATES: number of peer link states
+ * @MAX_NL80211_PLINK_STATES: highest numerical value of plink states
+ */
+enum nl80211_plink_state {
+ NL80211_PLINK_LISTEN,
+ NL80211_PLINK_OPN_SNT,
+ NL80211_PLINK_OPN_RCVD,
+ NL80211_PLINK_CNF_RCVD,
+ NL80211_PLINK_ESTAB,
+ NL80211_PLINK_HOLDING,
+ NL80211_PLINK_BLOCKED,
+
+ /* keep last */
+ NUM_NL80211_PLINK_STATES,
+ MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1
+};
+
#endif /* __LINUX_NL80211_H */
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index 3a02e020857..c5336705921 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -588,4 +588,19 @@ struct tc_sfb_xstats {
#define SFB_MAX_PROB 0xFFFF
+/* QFQ */
+enum {
+ TCA_QFQ_UNSPEC,
+ TCA_QFQ_WEIGHT,
+ TCA_QFQ_LMAX,
+ __TCA_QFQ_MAX
+};
+
+#define TCA_QFQ_MAX (__TCA_QFQ_MAX - 1)
+
+struct tc_qfq_stats {
+ __u32 weight;
+ __u32 lmax;
+};
+
#endif
diff --git a/include/linux/rfkill-regulator.h b/include/linux/rfkill-regulator.h
new file mode 100644
index 00000000000..aca36bc8331
--- /dev/null
+++ b/include/linux/rfkill-regulator.h
@@ -0,0 +1,48 @@
+/*
+ * rfkill-regulator.c - Regulator consumer driver for rfkill
+ *
+ * Copyright (C) 2009 Guiming Zhuo <gmzhuo@gmail.com>
+ * Copyright (C) 2011 Antonio Ospite <ospite@studenti.unina.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 __LINUX_RFKILL_REGULATOR_H
+#define __LINUX_RFKILL_REGULATOR_H
+
+/*
+ * Use "vrfkill" as supply id when declaring the regulator consumer:
+ *
+ * static struct regulator_consumer_supply pcap_regulator_V6_consumers [] = {
+ * { .dev_name = "rfkill-regulator.0", .supply = "vrfkill" },
+ * };
+ *
+ * If you have several regulator driven rfkill, you can append a numerical id to
+ * .dev_name as done above, and use the same id when declaring the platform
+ * device:
+ *
+ * static struct rfkill_regulator_platform_data ezx_rfkill_bt_data = {
+ * .name = "ezx-bluetooth",
+ * .type = RFKILL_TYPE_BLUETOOTH,
+ * };
+ *
+ * static struct platform_device a910_rfkill = {
+ * .name = "rfkill-regulator",
+ * .id = 0,
+ * .dev = {
+ * .platform_data = &ezx_rfkill_bt_data,
+ * },
+ * };
+ */
+
+#include <linux/rfkill.h>
+
+struct rfkill_regulator_platform_data {
+ char *name; /* the name for the rfkill switch */
+ enum rfkill_type type; /* the type as specified in rfkill.h */
+};
+
+#endif /* __LINUX_RFKILL_REGULATOR_H */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index d0ae90af0b4..79aafbbf430 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -391,8 +391,8 @@ struct sk_buff {
__u32 rxhash;
+ __u16 queue_mapping;
kmemcheck_bitfield_begin(flags2);
- __u16 queue_mapping:16;
#ifdef CONFIG_IPV6_NDISC_NODETYPE
__u8 ndisc_nodetype:2;
#endif
diff --git a/include/linux/smsc911x.h b/include/linux/smsc911x.h
index 7144e8aa1e4..4dde70e7482 100644
--- a/include/linux/smsc911x.h
+++ b/include/linux/smsc911x.h
@@ -29,6 +29,7 @@ struct smsc911x_platform_config {
unsigned int irq_polarity;
unsigned int irq_type;
unsigned int flags;
+ unsigned int shift;
phy_interface_t phy_interface;
unsigned char mac[6];
};
diff --git a/include/linux/socket.h b/include/linux/socket.h
index d2b5e982f07..4ef98e422fd 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -333,5 +333,7 @@ struct timespec;
extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
unsigned int flags, struct timespec *timeout);
+extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
+ unsigned int vlen, unsigned int flags);
#endif /* not kernel and not glibc */
#endif /* _LINUX_SOCKET_H */
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index 045f72ab5df..252e4482178 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -308,7 +308,7 @@ struct ssb_bus {
/* ID information about the Chip. */
u16 chip_id;
- u16 chip_rev;
+ u8 chip_rev;
u16 sprom_offset;
u16 sprom_size; /* number of words in sprom */
u8 chip_package;
@@ -520,6 +520,7 @@ extern int ssb_bus_may_powerdown(struct ssb_bus *bus);
* Otherwise static always-on powercontrol will be used. */
extern int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl);
+extern void ssb_commit_settings(struct ssb_bus *bus);
/* Various helper functions */
extern u32 ssb_admatch_base(u32 adm);
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h
index 2cdf249b4e5..a08d693d832 100644
--- a/include/linux/ssb/ssb_driver_chipcommon.h
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
@@ -123,6 +123,8 @@
#define SSB_CHIPCO_FLASHDATA 0x0048
#define SSB_CHIPCO_BCAST_ADDR 0x0050
#define SSB_CHIPCO_BCAST_DATA 0x0054
+#define SSB_CHIPCO_GPIOPULLUP 0x0058 /* Rev >= 20 only */
+#define SSB_CHIPCO_GPIOPULLDOWN 0x005C /* Rev >= 20 only */
#define SSB_CHIPCO_GPIOIN 0x0060
#define SSB_CHIPCO_GPIOOUT 0x0064
#define SSB_CHIPCO_GPIOOUTEN 0x0068
@@ -131,6 +133,9 @@
#define SSB_CHIPCO_GPIOIRQ 0x0074
#define SSB_CHIPCO_WATCHDOG 0x0080
#define SSB_CHIPCO_GPIOTIMER 0x0088 /* LED powersave (corerev >= 16) */
+#define SSB_CHIPCO_GPIOTIMER_OFFTIME 0x0000FFFF
+#define SSB_CHIPCO_GPIOTIMER_OFFTIME_SHIFT 0
+#define SSB_CHIPCO_GPIOTIMER_ONTIME 0xFFFF0000
#define SSB_CHIPCO_GPIOTIMER_ONTIME_SHIFT 16
#define SSB_CHIPCO_GPIOTOUTM 0x008C /* LED powersave (corerev >= 16) */
#define SSB_CHIPCO_CLOCK_N 0x0090
@@ -189,8 +194,10 @@
#define SSB_CHIPCO_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
#define SSB_CHIPCO_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
#define SSB_CHIPCO_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
-#define SSB_CHIPCO_CLKCTLST_HAVEHT 0x00010000 /* HT available */
-#define SSB_CHIPCO_CLKCTLST_HAVEALP 0x00020000 /* APL available */
+#define SSB_CHIPCO_CLKCTLST_HAVEALP 0x00010000 /* ALP available */
+#define SSB_CHIPCO_CLKCTLST_HAVEHT 0x00020000 /* HT available */
+#define SSB_CHIPCO_CLKCTLST_4328A0_HAVEHT 0x00010000 /* 4328a0 has reversed bits */
+#define SSB_CHIPCO_CLKCTLST_4328A0_HAVEALP 0x00020000 /* 4328a0 has reversed bits */
#define SSB_CHIPCO_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
#define SSB_CHIPCO_UART0_DATA 0x0300
#define SSB_CHIPCO_UART0_IMR 0x0304
diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h
index 402955ae48c..efbf459d571 100644
--- a/include/linux/ssb/ssb_regs.h
+++ b/include/linux/ssb/ssb_regs.h
@@ -97,7 +97,7 @@
#define SSB_INTVEC_ENET1 0x00000040 /* Enable interrupts for enet 1 */
#define SSB_TMSLOW 0x0F98 /* SB Target State Low */
#define SSB_TMSLOW_RESET 0x00000001 /* Reset */
-#define SSB_TMSLOW_REJECT_22 0x00000002 /* Reject (Backplane rev 2.2) */
+#define SSB_TMSLOW_REJECT 0x00000002 /* Reject (Standard Backplane) */
#define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */
#define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */
#define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index f29197a4b22..9529e49b038 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -26,6 +26,8 @@
#ifndef __STMMAC_PLATFORM_DATA
#define __STMMAC_PLATFORM_DATA
+#include <linux/platform_device.h>
+
/* platform data for platform device structure's platform_data field */
/* Private data for the STM on-board ethernet driver */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 83ecc1749ef..ab71447d0c5 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -610,6 +610,8 @@ asmlinkage long sys_send(int, void __user *, size_t, unsigned);
asmlinkage long sys_sendto(int, void __user *, size_t, unsigned,
struct sockaddr __user *, int);
asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);
+asmlinkage long sys_sendmmsg(int fd, struct mmsghdr __user *msg,
+ unsigned int vlen, unsigned flags);
asmlinkage long sys_recv(int, void __user *, size_t, unsigned);
asmlinkage long sys_recvfrom(int, void __user *, size_t, unsigned,
struct sockaddr __user *, int __user *);
diff --git a/include/linux/tipc.h b/include/linux/tipc.h
index a5b994a204d..f2d90091cc2 100644
--- a/include/linux/tipc.h
+++ b/include/linux/tipc.h
@@ -101,7 +101,7 @@ static inline unsigned int tipc_node(__u32 addr)
* Limiting values for messages
*/
-#define TIPC_MAX_USER_MSG_SIZE 66000
+#define TIPC_MAX_USER_MSG_SIZE 66000U
/*
* Message importance levels
diff --git a/include/linux/usb/rndis_host.h b/include/linux/usb/rndis_host.h
index 05ef5286198..88fceb718c7 100644
--- a/include/linux/usb/rndis_host.h
+++ b/include/linux/usb/rndis_host.h
@@ -256,6 +256,8 @@ struct rndis_keepalive_c { /* IN (optionally OUT) */
#define FLAG_RNDIS_PHYM_NOT_WIRELESS 0x0001
#define FLAG_RNDIS_PHYM_WIRELESS 0x0002
+/* Flags for driver_info::data */
+#define RNDIS_DRIVER_DATA_POLL_STATUS 1 /* poll status before control */
extern void rndis_status(struct usbnet *dev, struct urb *urb);
extern int
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index bebb8efea0a..4b697395326 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -24,12 +24,26 @@
#ifndef _LINUX_WL12XX_H
#define _LINUX_WL12XX_H
-/* The board reference clock values */
+/* Reference clock values */
enum {
- WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */
- WL12XX_REFCLOCK_26 = 1, /* 26 MHz */
- WL12XX_REFCLOCK_38 = 2, /* 38.4 MHz */
- WL12XX_REFCLOCK_54 = 3, /* 54 MHz */
+ WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */
+ WL12XX_REFCLOCK_26 = 1, /* 26 MHz */
+ WL12XX_REFCLOCK_38 = 2, /* 38.4 MHz */
+ WL12XX_REFCLOCK_52 = 3, /* 52 MHz */
+ WL12XX_REFCLOCK_38_XTAL = 4, /* 38.4 MHz, XTAL */
+ WL12XX_REFCLOCK_26_XTAL = 5, /* 26 MHz, XTAL */
+};
+
+/* TCXO clock values */
+enum {
+ WL12XX_TCXOCLOCK_19_2 = 0, /* 19.2MHz */
+ WL12XX_TCXOCLOCK_26 = 1, /* 26 MHz */
+ WL12XX_TCXOCLOCK_38_4 = 2, /* 38.4MHz */
+ WL12XX_TCXOCLOCK_52 = 3, /* 52 MHz */
+ WL12XX_TCXOCLOCK_16_368 = 4, /* 16.368 MHz */
+ WL12XX_TCXOCLOCK_32_736 = 5, /* 32.736 MHz */
+ WL12XX_TCXOCLOCK_16_8 = 6, /* 16.8 MHz */
+ WL12XX_TCXOCLOCK_33_6 = 7, /* 33.6 MHz */
};
struct wl12xx_platform_data {
@@ -38,8 +52,13 @@ struct wl12xx_platform_data {
int irq;
bool use_eeprom;
int board_ref_clock;
+ int board_tcxo_clock;
+ unsigned long platform_quirks;
};
+/* Platform does not support level trigger interrupts */
+#define WL12XX_PLATFORM_QUIRK_EDGE_IRQ BIT(0)
+
#ifdef CONFIG_WL12XX_PLATFORM_DATA
int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 23710aa6a18..582e4ae7075 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -42,8 +42,6 @@ struct prefix_info {
};
-#ifdef __KERNEL__
-
#include <linux/netdevice.h>
#include <net/if_inet6.h>
#include <net/ipv6.h>
@@ -61,16 +59,16 @@ extern int addrconf_set_dstaddr(struct net *net,
void __user *arg);
extern int ipv6_chk_addr(struct net *net,
- struct in6_addr *addr,
+ const 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 net *net,
- struct in6_addr *addr);
+ const struct in6_addr *addr);
#endif
-extern int ipv6_chk_prefix(struct in6_addr *addr,
+extern int ipv6_chk_prefix(const struct in6_addr *addr,
struct net_device *dev);
extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
@@ -89,9 +87,9 @@ extern int ipv6_get_lladdr(struct net_device *dev,
extern int ipv6_rcv_saddr_equal(const struct sock *sk,
const struct sock *sk2);
extern void addrconf_join_solict(struct net_device *dev,
- struct in6_addr *addr);
+ const struct in6_addr *addr);
extern void addrconf_leave_solict(struct inet6_dev *idev,
- struct in6_addr *addr);
+ const struct in6_addr *addr);
static inline unsigned long addrconf_timeout_fixup(u32 timeout,
unsigned unit)
@@ -158,15 +156,15 @@ extern void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len);
/*
* anycast prototypes (anycast.c)
*/
-extern int ipv6_sock_ac_join(struct sock *sk,int ifindex,struct in6_addr *addr);
-extern int ipv6_sock_ac_drop(struct sock *sk,int ifindex,struct in6_addr *addr);
+extern int ipv6_sock_ac_join(struct sock *sk,int ifindex, const struct in6_addr *addr);
+extern int ipv6_sock_ac_drop(struct sock *sk,int ifindex, const struct in6_addr *addr);
extern void ipv6_sock_ac_close(struct sock *sk);
-extern int inet6_ac_check(struct sock *sk, struct in6_addr *addr, int ifindex);
+extern int inet6_ac_check(struct sock *sk, const struct in6_addr *addr, int ifindex);
-extern int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr);
-extern int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr);
+extern int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr);
+extern int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr);
extern int ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
- struct in6_addr *addr);
+ const struct in6_addr *addr);
/* Device notifier */
@@ -285,4 +283,3 @@ extern void if6_proc_exit(void);
#endif
#endif
-#endif
diff --git a/include/net/af_rxrpc.h b/include/net/af_rxrpc.h
index 00c2eaa07c2..03e6e945362 100644
--- a/include/net/af_rxrpc.h
+++ b/include/net/af_rxrpc.h
@@ -12,8 +12,6 @@
#ifndef _NET_RXRPC_H
#define _NET_RXRPC_H
-#ifdef __KERNEL__
-
#include <linux/rxrpc.h>
struct rxrpc_call;
@@ -53,5 +51,4 @@ extern struct rxrpc_call *rxrpc_kernel_accept_call(struct socket *,
unsigned long);
extern int rxrpc_kernel_reject_call(struct socket *);
-#endif /* __KERNEL__ */
#endif /* _NET_RXRPC_H */
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 18e5c3f6758..91ab5b01678 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -41,7 +41,6 @@ struct unix_skb_parms {
spin_lock_nested(&unix_sk(s)->lock, \
SINGLE_DEPTH_NESTING)
-#ifdef __KERNEL__
/* The AF_UNIX socket */
struct unix_sock {
/* WARNING: sk has to be the first member */
@@ -72,4 +71,3 @@ static inline int unix_sysctl_register(struct net *net) { return 0; }
static inline void unix_sysctl_unregister(struct net *net) {}
#endif
#endif
-#endif
diff --git a/include/net/atmclip.h b/include/net/atmclip.h
index 467c531b8a7..497ef6444a7 100644
--- a/include/net/atmclip.h
+++ b/include/net/atmclip.h
@@ -54,8 +54,6 @@ struct clip_priv {
};
-#ifdef __KERNEL__
extern struct neigh_table *clip_tbl_hook;
-#endif
#endif
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 2c0d309c738..0c20227e57f 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -246,6 +246,15 @@ enum {
#define HCI_AT_GENERAL_BONDING 0x04
#define HCI_AT_GENERAL_BONDING_MITM 0x05
+/* Link Key types */
+#define HCI_LK_COMBINATION 0x00
+#define HCI_LK_LOCAL_UNIT 0x01
+#define HCI_LK_REMOTE_UNIT 0x02
+#define HCI_LK_DEBUG_COMBINATION 0x03
+#define HCI_LK_UNAUTH_COMBINATION 0x04
+#define HCI_LK_AUTH_COMBINATION 0x05
+#define HCI_LK_CHANGED_COMBINATION 0x06
+
/* ----- HCI Commands ---- */
#define HCI_OP_NOP 0x0000
@@ -428,6 +437,18 @@ struct hci_rp_user_confirm_reply {
#define HCI_OP_USER_CONFIRM_NEG_REPLY 0x042d
+#define HCI_OP_REMOTE_OOB_DATA_REPLY 0x0430
+struct hci_cp_remote_oob_data_reply {
+ bdaddr_t bdaddr;
+ __u8 hash[16];
+ __u8 randomizer[16];
+} __packed;
+
+#define HCI_OP_REMOTE_OOB_DATA_NEG_REPLY 0x0433
+struct hci_cp_remote_oob_data_neg_reply {
+ bdaddr_t bdaddr;
+} __packed;
+
#define HCI_OP_IO_CAPABILITY_NEG_REPLY 0x0434
struct hci_cp_io_capability_neg_reply {
bdaddr_t bdaddr;
@@ -537,15 +558,17 @@ struct hci_cp_delete_stored_link_key {
__u8 delete_all;
} __packed;
+#define HCI_MAX_NAME_LENGTH 248
+
#define HCI_OP_WRITE_LOCAL_NAME 0x0c13
struct hci_cp_write_local_name {
- __u8 name[248];
+ __u8 name[HCI_MAX_NAME_LENGTH];
} __packed;
#define HCI_OP_READ_LOCAL_NAME 0x0c14
struct hci_rp_read_local_name {
__u8 status;
- __u8 name[248];
+ __u8 name[HCI_MAX_NAME_LENGTH];
} __packed;
#define HCI_OP_WRITE_CA_TIMEOUT 0x0c16
@@ -602,6 +625,14 @@ struct hci_cp_host_buffer_size {
#define HCI_OP_WRITE_INQUIRY_MODE 0x0c45
+#define HCI_MAX_EIR_LENGTH 240
+
+#define HCI_OP_WRITE_EIR 0x0c52
+struct hci_cp_write_eir {
+ uint8_t fec;
+ uint8_t data[HCI_MAX_EIR_LENGTH];
+} __packed;
+
#define HCI_OP_READ_SSP_MODE 0x0c55
struct hci_rp_read_ssp_mode {
__u8 status;
@@ -613,6 +644,13 @@ struct hci_cp_write_ssp_mode {
__u8 mode;
} __packed;
+#define HCI_OP_READ_LOCAL_OOB_DATA 0x0c57
+struct hci_rp_read_local_oob_data {
+ __u8 status;
+ __u8 hash[16];
+ __u8 randomizer[16];
+} __packed;
+
#define HCI_OP_READ_INQ_RSP_TX_POWER 0x0c58
#define HCI_OP_READ_LOCAL_VERSION 0x1001
@@ -747,7 +785,7 @@ struct hci_ev_auth_complete {
struct hci_ev_remote_name {
__u8 status;
bdaddr_t bdaddr;
- __u8 name[248];
+ __u8 name[HCI_MAX_NAME_LENGTH];
} __packed;
#define HCI_EV_ENCRYPT_CHANGE 0x08
@@ -955,6 +993,11 @@ struct hci_ev_user_confirm_req {
__le32 passkey;
} __packed;
+#define HCI_EV_REMOTE_OOB_DATA_REQUEST 0x35
+struct hci_ev_remote_oob_data_request {
+ bdaddr_t bdaddr;
+} __packed;
+
#define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36
struct hci_ev_simple_pair_complete {
__u8 status;
@@ -1033,7 +1076,6 @@ struct hci_sco_hdr {
__u8 dlen;
} __packed;
-#ifdef __KERNEL__
#include <linux/skbuff.h>
static inline struct hci_event_hdr *hci_event_hdr(const struct sk_buff *skb)
{
@@ -1049,7 +1091,6 @@ static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb)
{
return (struct hci_sco_hdr *) skb->data;
}
-#endif
/* Command opcode pack/unpack */
#define hci_opcode_pack(ogf, ocf) (__u16) ((ocf & 0x03ff)|(ogf << 10))
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 441dadbf6a8..6c994c004d1 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -82,6 +82,13 @@ struct link_key {
u8 pin_len;
};
+struct oob_data {
+ struct list_head list;
+ bdaddr_t bdaddr;
+ u8 hash[16];
+ u8 randomizer[16];
+};
+
#define NUM_REASSEMBLY 4
struct hci_dev {
struct list_head list;
@@ -94,7 +101,8 @@ struct hci_dev {
__u8 bus;
__u8 dev_type;
bdaddr_t bdaddr;
- __u8 dev_name[248];
+ __u8 dev_name[HCI_MAX_NAME_LENGTH];
+ __u8 eir[HCI_MAX_EIR_LENGTH];
__u8 dev_class[3];
__u8 major_class;
__u8 minor_class;
@@ -118,6 +126,8 @@ struct hci_dev {
__u16 sniff_min_interval;
__u16 sniff_max_interval;
+ unsigned int auto_accept_delay;
+
unsigned long quirks;
atomic_t cmd_cnt;
@@ -169,6 +179,8 @@ struct hci_dev {
struct list_head link_keys;
+ struct list_head remote_oob_data;
+
struct hci_dev_stats stat;
struct sk_buff_head driver_init;
@@ -216,6 +228,7 @@ struct hci_conn {
__u16 pkt_type;
__u16 link_policy;
__u32 link_mode;
+ __u8 key_type;
__u8 auth_type;
__u8 sec_level;
__u8 pending_sec_level;
@@ -235,6 +248,7 @@ struct hci_conn {
struct timer_list disc_timer;
struct timer_list idle_timer;
+ struct timer_list auto_accept_timer;
struct work_struct work_add;
struct work_struct work_del;
@@ -408,6 +422,7 @@ void hci_conn_check_pending(struct hci_dev *hdev);
struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type);
int hci_conn_check_link_mode(struct hci_conn *conn);
+int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
int hci_conn_change_link_key(struct hci_conn *conn);
int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
@@ -501,10 +516,17 @@ int hci_uuids_clear(struct hci_dev *hdev);
int hci_link_keys_clear(struct hci_dev *hdev);
struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
-int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
- u8 *key, u8 type, u8 pin_len);
+int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
+ bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
+int hci_remote_oob_data_clear(struct hci_dev *hdev);
+struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
+ bdaddr_t *bdaddr);
+int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
+ u8 *randomizer);
+int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
+
void hci_del_off_timer(struct hci_dev *hdev);
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
@@ -754,19 +776,27 @@ int mgmt_index_removed(u16 index);
int mgmt_powered(u16 index, u8 powered);
int mgmt_discoverable(u16 index, u8 discoverable);
int mgmt_connectable(u16 index, u8 connectable);
-int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type);
+int mgmt_new_key(u16 index, struct link_key *key, u8 persistent);
int mgmt_connected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnect_failed(u16 index);
int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status);
-int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr);
+int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure);
int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
-int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value);
+int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value,
+ u8 confirm_hint);
int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr,
u8 status);
int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status);
+int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status);
+int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
+ u8 status);
+int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi,
+ u8 *eir);
+int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name);
+int mgmt_discovering(u16 index, u8 discovering);
/* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 4f4bff1eaed..d09c9b1118e 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -276,63 +276,17 @@ struct l2cap_conn_param_update_rsp {
#define L2CAP_CONN_PARAM_ACCEPTED 0x0000
#define L2CAP_CONN_PARAM_REJECTED 0x0001
-/* ----- L2CAP connections ----- */
-struct l2cap_chan_list {
- struct sock *head;
- rwlock_t lock;
- long num;
-};
-
-struct l2cap_conn {
- struct hci_conn *hcon;
-
- bdaddr_t *dst;
- bdaddr_t *src;
-
- unsigned int mtu;
-
- __u32 feat_mask;
-
- __u8 info_state;
- __u8 info_ident;
-
- struct timer_list info_timer;
-
- spinlock_t lock;
-
- struct sk_buff *rx_skb;
- __u32 rx_len;
- __u8 rx_ident;
- __u8 tx_ident;
-
- __u8 disc_reason;
-
- struct l2cap_chan_list chan_list;
-};
-
-struct sock_del_list {
- struct sock *sk;
- struct list_head list;
-};
-
-#define L2CAP_INFO_CL_MTU_REQ_SENT 0x01
-#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04
-#define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08
-
-/* ----- L2CAP channel and socket info ----- */
-#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
-#define TX_QUEUE(sk) (&l2cap_pi(sk)->tx_queue)
-#define SREJ_QUEUE(sk) (&l2cap_pi(sk)->srej_queue)
-#define BUSY_QUEUE(sk) (&l2cap_pi(sk)->busy_queue)
-#define SREJ_LIST(sk) (&l2cap_pi(sk)->srej_l.list)
-
+/* ----- L2CAP channels and connections ----- */
struct srej_list {
__u8 tx_seq;
struct list_head list;
};
-struct l2cap_pinfo {
- struct bt_sock bt;
+struct l2cap_chan {
+ struct sock *sk;
+
+ struct l2cap_conn *conn;
+
__le16 psm;
__u16 dcid;
__u16 scid;
@@ -341,17 +295,29 @@ struct l2cap_pinfo {
__u16 omtu;
__u16 flush_to;
__u8 mode;
- __u8 num_conf_req;
- __u8 num_conf_rsp;
- __u8 fcs;
+ __le16 sport;
+
__u8 sec_level;
__u8 role_switch;
__u8 force_reliable;
__u8 flushable;
+ __u8 ident;
+
__u8 conf_req[64];
__u8 conf_len;
+ __u8 num_conf_req;
+ __u8 num_conf_rsp;
+
+ __u8 fcs;
+
+ __u8 tx_win;
+ __u8 max_tx;
+ __u16 retrans_timeout;
+ __u16 monitor_timeout;
+ __u16 mps;
+
__u8 conf_state;
__u16 conn_state;
@@ -369,30 +335,61 @@ struct l2cap_pinfo {
__u16 partial_sdu_len;
struct sk_buff *sdu;
- __u8 ident;
-
- __u8 tx_win;
- __u8 max_tx;
__u8 remote_tx_win;
__u8 remote_max_tx;
- __u16 retrans_timeout;
- __u16 monitor_timeout;
__u16 remote_mps;
- __u16 mps;
-
- __le16 sport;
struct timer_list retrans_timer;
struct timer_list monitor_timer;
struct timer_list ack_timer;
- struct sk_buff_head tx_queue;
- struct sk_buff_head srej_queue;
- struct sk_buff_head busy_queue;
+ struct sk_buff *tx_send_head;
+ struct sk_buff_head tx_q;
+ struct sk_buff_head srej_q;
+ struct sk_buff_head busy_q;
struct work_struct busy_work;
- struct srej_list srej_l;
- struct l2cap_conn *conn;
- struct sock *next_c;
- struct sock *prev_c;
+ struct list_head srej_l;
+
+ struct list_head list;
+ struct list_head global_l;
+};
+
+struct l2cap_conn {
+ struct hci_conn *hcon;
+
+ bdaddr_t *dst;
+ bdaddr_t *src;
+
+ unsigned int mtu;
+
+ __u32 feat_mask;
+
+ __u8 info_state;
+ __u8 info_ident;
+
+ struct timer_list info_timer;
+
+ spinlock_t lock;
+
+ struct sk_buff *rx_skb;
+ __u32 rx_len;
+ __u8 tx_ident;
+
+ __u8 disc_reason;
+
+ struct list_head chan_l;
+ rwlock_t chan_lock;
+};
+
+#define L2CAP_INFO_CL_MTU_REQ_SENT 0x01
+#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04
+#define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08
+
+/* ----- L2CAP socket info ----- */
+#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
+
+struct l2cap_pinfo {
+ struct bt_sock bt;
+ struct l2cap_chan *chan;
};
#define L2CAP_CONF_REQ_SENT 0x01
@@ -419,24 +416,23 @@ struct l2cap_pinfo {
#define L2CAP_CONN_RNR_SENT 0x0200
#define L2CAP_CONN_SAR_RETRY 0x0400
-#define __mod_retrans_timer() mod_timer(&l2cap_pi(sk)->retrans_timer, \
+#define __mod_retrans_timer() mod_timer(&chan->retrans_timer, \
jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));
-#define __mod_monitor_timer() mod_timer(&l2cap_pi(sk)->monitor_timer, \
+#define __mod_monitor_timer() mod_timer(&chan->monitor_timer, \
jiffies + msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO));
-#define __mod_ack_timer() mod_timer(&l2cap_pi(sk)->ack_timer, \
+#define __mod_ack_timer() mod_timer(&chan->ack_timer, \
jiffies + msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO));
-static inline int l2cap_tx_window_full(struct sock *sk)
+static inline int l2cap_tx_window_full(struct l2cap_chan *ch)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
int sub;
- sub = (pi->next_tx_seq - pi->expected_ack_seq) % 64;
+ sub = (ch->next_tx_seq - ch->expected_ack_seq) % 64;
if (sub < 0)
sub += 64;
- return sub == pi->remote_tx_win;
+ return sub == ch->remote_tx_win;
}
#define __get_txseq(ctrl) (((ctrl) & L2CAP_CTRL_TXSEQ) >> 1)
@@ -446,24 +442,24 @@ static inline int l2cap_tx_window_full(struct sock *sk)
#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START)
extern int disable_ertm;
-extern const struct proto_ops l2cap_sock_ops;
-extern struct bt_sock_list l2cap_sk_list;
int l2cap_init_sockets(void);
void l2cap_cleanup_sockets(void);
-u8 l2cap_get_ident(struct l2cap_conn *conn);
void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data);
-int l2cap_build_conf_req(struct sock *sk, void *data);
+void __l2cap_connect_rsp_defer(struct l2cap_chan *chan);
int __l2cap_wait_ack(struct sock *sk);
-struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len);
-struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len);
-struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen);
-int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len);
-void l2cap_do_send(struct sock *sk, struct sk_buff *skb);
-void l2cap_streaming_send(struct sock *sk);
-int l2cap_ertm_send(struct sock *sk);
+struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
+struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
+struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len, u16 control, u16 sdulen);
+int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
+void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb);
+void l2cap_streaming_send(struct l2cap_chan *chan);
+int l2cap_ertm_send(struct l2cap_chan *chan);
+
+int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
+int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
void l2cap_sock_set_timer(struct sock *sk, long timeout);
void l2cap_sock_clear_timer(struct sock *sk);
@@ -472,8 +468,10 @@ void l2cap_sock_kill(struct sock *sk);
void l2cap_sock_init(struct sock *sk, struct sock *parent);
struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
int proto, gfp_t prio);
-void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err);
-void l2cap_chan_del(struct sock *sk, int err);
-int l2cap_do_connect(struct sock *sk);
+void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err);
+struct l2cap_chan *l2cap_chan_create(struct sock *sk);
+void l2cap_chan_del(struct l2cap_chan *chan, int err);
+void l2cap_chan_destroy(struct l2cap_chan *chan);
+int l2cap_chan_connect(struct l2cap_chan *chan);
#endif /* __L2CAP_H */
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 5fabfa886b3..4899286ed4e 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -41,6 +41,10 @@ struct mgmt_rp_read_index_list {
__le16 index[0];
} __packed;
+/* Reserve one extra byte for names in management messages so that they
+ * are always guaranteed to be nul-terminated */
+#define MGMT_MAX_NAME_LENGTH (HCI_MAX_NAME_LENGTH + 1)
+
#define MGMT_OP_READ_INFO 0x0004
struct mgmt_rp_read_info {
__u8 type;
@@ -55,6 +59,7 @@ struct mgmt_rp_read_info {
__u16 manufacturer;
__u8 hci_ver;
__u16 hci_rev;
+ __u8 name[MGMT_MAX_NAME_LENGTH];
} __packed;
struct mgmt_mode {
@@ -167,6 +172,33 @@ struct mgmt_rp_user_confirm_reply {
#define MGMT_OP_USER_CONFIRM_NEG_REPLY 0x0016
+#define MGMT_OP_SET_LOCAL_NAME 0x0017
+struct mgmt_cp_set_local_name {
+ __u8 name[MGMT_MAX_NAME_LENGTH];
+} __packed;
+
+#define MGMT_OP_READ_LOCAL_OOB_DATA 0x0018
+struct mgmt_rp_read_local_oob_data {
+ __u8 hash[16];
+ __u8 randomizer[16];
+} __packed;
+
+#define MGMT_OP_ADD_REMOTE_OOB_DATA 0x0019
+struct mgmt_cp_add_remote_oob_data {
+ bdaddr_t bdaddr;
+ __u8 hash[16];
+ __u8 randomizer[16];
+} __packed;
+
+#define MGMT_OP_REMOVE_REMOTE_OOB_DATA 0x001A
+struct mgmt_cp_remove_remote_oob_data {
+ bdaddr_t bdaddr;
+} __packed;
+
+#define MGMT_OP_START_DISCOVERY 0x001B
+
+#define MGMT_OP_STOP_DISCOVERY 0x001C
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
@@ -198,8 +230,8 @@ struct mgmt_ev_controller_error {
#define MGMT_EV_NEW_KEY 0x000A
struct mgmt_ev_new_key {
+ __u8 store_hint;
struct mgmt_key_info key;
- __u8 old_key_type;
} __packed;
#define MGMT_EV_CONNECTED 0x000B
@@ -221,11 +253,13 @@ struct mgmt_ev_connect_failed {
#define MGMT_EV_PIN_CODE_REQUEST 0x000E
struct mgmt_ev_pin_code_request {
bdaddr_t bdaddr;
+ __u8 secure;
} __packed;
#define MGMT_EV_USER_CONFIRM_REQUEST 0x000F
struct mgmt_ev_user_confirm_request {
bdaddr_t bdaddr;
+ __u8 confirm_hint;
__le32 value;
} __packed;
@@ -234,3 +268,24 @@ struct mgmt_ev_auth_failed {
bdaddr_t bdaddr;
__u8 status;
} __packed;
+
+#define MGMT_EV_LOCAL_NAME_CHANGED 0x0011
+struct mgmt_ev_local_name_changed {
+ __u8 name[MGMT_MAX_NAME_LENGTH];
+} __packed;
+
+#define MGMT_EV_DEVICE_FOUND 0x0012
+struct mgmt_ev_device_found {
+ bdaddr_t bdaddr;
+ __u8 dev_class[3];
+ __s8 rssi;
+ __u8 eir[HCI_MAX_EIR_LENGTH];
+} __packed;
+
+#define MGMT_EV_REMOTE_NAME 0x0013
+struct mgmt_ev_remote_name {
+ bdaddr_t bdaddr;
+ __u8 name[MGMT_MAX_NAME_LENGTH];
+} __packed;
+
+#define MGMT_EV_DISCOVERING 0x0014
diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h
index 8eff83b9536..c011281d92c 100644
--- a/include/net/caif/caif_dev.h
+++ b/include/net/caif/caif_dev.h
@@ -11,6 +11,7 @@
#include <net/caif/cfcnfg.h>
#include <linux/caif/caif_socket.h>
#include <linux/if.h>
+#include <linux/net.h>
/**
* struct caif_param - CAIF parameters.
@@ -62,46 +63,45 @@ struct caif_connect_request {
* E.g. CAIF Socket will call this function for each socket it connects
* and have one client_layer instance for each socket.
*/
-int caif_connect_client(struct caif_connect_request *conn_req,
+int caif_connect_client(struct net *net,
+ struct caif_connect_request *conn_req,
struct cflayer *client_layer, int *ifindex,
int *headroom, int *tailroom);
/**
* caif_disconnect_client - Disconnects a client from the CAIF stack.
*
- * @client_layer: Client layer to be removed.
+ * @client_layer: Client layer to be disconnected.
*/
-int caif_disconnect_client(struct cflayer *client_layer);
+int caif_disconnect_client(struct net *net, struct cflayer *client_layer);
+
/**
- * caif_release_client - Release adaptation layer reference to client.
+ * caif_client_register_refcnt - register ref-count functions provided by client.
*
- * @client_layer: Client layer.
+ * @adapt_layer: Client layer using CAIF Stack.
+ * @hold: Function provided by client layer increasing ref-count
+ * @put: Function provided by client layer decreasing ref-count
*
- * Releases a client/adaptation layer use of the caif stack.
- * This function must be used after caif_disconnect_client to
- * decrease the reference count of the service layer.
- */
-void caif_release_client(struct cflayer *client_layer);
-
-/**
- * connect_req_to_link_param - Translate configuration parameters
- * from socket format to internal format.
- * @cnfg: Pointer to configuration handler
- * @con_req: Configuration parameters supplied in function
- * caif_connect_client
- * @channel_setup_param: Parameters supplied to the CAIF Core stack for
- * setting up channels.
+ * Client of the CAIF Stack must register functions for reference counting.
+ * These functions are called by the CAIF Stack for every upstream packet,
+ * and must therefore be implemented efficiently.
*
+ * Client should call caif_free_client when reference count degrease to zero.
*/
-int connect_req_to_link_param(struct cfcnfg *cnfg,
- struct caif_connect_request *con_req,
- struct cfctrl_link_param *channel_setup_param);
+void caif_client_register_refcnt(struct cflayer *adapt_layer,
+ void (*hold)(struct cflayer *lyr),
+ void (*put)(struct cflayer *lyr));
/**
- * get_caif_conf() - Get the configuration handler.
+ * caif_free_client - Free memory used to manage the client in the CAIF Stack.
+ *
+ * @client_layer: Client layer to be removed.
+ *
+ * This function must be called from client layer in order to free memory.
+ * Caller must guarantee that no packets are in flight upstream when calling
+ * this function.
*/
-struct cfcnfg *get_caif_conf(void);
-
+void caif_free_client(struct cflayer *adap_layer);
#endif /* CAIF_DEV_H_ */
diff --git a/include/net/caif/cfcnfg.h b/include/net/caif/cfcnfg.h
index f33d3634113..3e93a4a4b67 100644
--- a/include/net/caif/cfcnfg.h
+++ b/include/net/caif/cfcnfg.h
@@ -46,6 +46,12 @@ enum cfcnfg_phy_preference {
};
/**
+ * cfcnfg_create() - Get the CAIF configuration object given network.
+ * @net: Network for the CAIF configuration object.
+ */
+struct cfcnfg *get_cfcnfg(struct net *net);
+
+/**
* cfcnfg_create() - Create the CAIF configuration object.
*/
struct cfcnfg *cfcnfg_create(void);
@@ -65,17 +71,15 @@ void cfcnfg_remove(struct cfcnfg *cfg);
* @dev: Pointer to link layer device
* @phy_layer: Specify the physical layer. The transmit function
* MUST be set in the structure.
- * @phyid: The assigned physical ID for this layer, used in
- * cfcnfg_add_adapt_layer to specify PHY for the link.
* @pref: The phy (link layer) preference.
* @fcs: Specify if checksum is used in CAIF Framing Layer.
- * @stx: Specify if Start Of Frame extension is used.
+ * @stx: Specify if Start Of Frame eXtention is used.
*/
void
cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
struct net_device *dev, struct cflayer *phy_layer,
- u16 *phyid, enum cfcnfg_phy_preference pref,
+ enum cfcnfg_phy_preference pref,
bool fcs, bool stx);
/**
@@ -88,61 +92,12 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer);
/**
- * cfcnfg_disconn_adapt_layer - Disconnects an adaptation layer.
- *
- * @cnfg: Pointer to a CAIF configuration object, created by
- * cfcnfg_create().
- * @adap_layer: Adaptation layer to be removed.
- */
-int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg,
- struct cflayer *adap_layer);
-
-/**
- * cfcnfg_release_adap_layer - Used by client to release the adaptation layer.
- *
- * @adap_layer: Adaptation layer.
- */
-void cfcnfg_release_adap_layer(struct cflayer *adap_layer);
-
-/**
- * cfcnfg_add_adaptation_layer - Add an adaptation layer to the CAIF stack.
- *
- * The adaptation Layer is where the interface to application or higher-level
- * driver functionality is implemented.
- *
- * @cnfg: Pointer to a CAIF configuration object, created by
- * cfcnfg_create().
- * @param: Link setup parameters.
- * @adap_layer: Specify the adaptation layer; the receive and
- * flow-control functions MUST be set in the structure.
- * @ifindex: Link layer interface index used for this connection.
- * @proto_head: Protocol head-space needed by CAIF protocol,
- * excluding link layer.
- * @proto_tail: Protocol tail-space needed by CAIF protocol,
- * excluding link layer.
- */
-int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
- struct cfctrl_link_param *param,
- struct cflayer *adap_layer,
- int *ifindex,
- int *proto_head,
- int *proto_tail);
-
-/**
- * cfcnfg_get_phyid() - Get physical ID, given type.
- * Returns one of the physical interfaces matching the given type.
- * Zero if no match is found.
+ * cfcnfg_set_phy_state() - Set the state of the physical interface device.
* @cnfg: Configuration object
- * @phy_pref: Caif Link Layer preference
+ * @phy_layer: Physical Layer representation
+ * @up: State of device
*/
-struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
- enum cfcnfg_phy_preference phy_pref);
+int cfcnfg_set_phy_state(struct cfcnfg *cnfg, struct cflayer *phy_layer,
+ bool up);
-/**
- * cfcnfg_get_id_from_ifi() - Get the Physical Identifier of ifindex,
- * it matches caif physical id with the kernel interface id.
- * @cnfg: Configuration object
- * @ifi: ifindex obtained from socket.c bindtodevice.
- */
-int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi);
#endif /* CFCNFG_H_ */
diff --git a/include/net/caif/cfctrl.h b/include/net/caif/cfctrl.h
index e54f6396fa4..9e5425b4a1d 100644
--- a/include/net/caif/cfctrl.h
+++ b/include/net/caif/cfctrl.h
@@ -121,19 +121,10 @@ int cfctrl_linkup_request(struct cflayer *cfctrl,
struct cflayer *user_layer);
int cfctrl_linkdown_req(struct cflayer *cfctrl, u8 linkid,
struct cflayer *client);
-void cfctrl_sleep_req(struct cflayer *cfctrl);
-void cfctrl_wake_req(struct cflayer *cfctrl);
-void cfctrl_getstartreason_req(struct cflayer *cfctrl);
+
struct cflayer *cfctrl_create(void);
-void cfctrl_set_dnlayer(struct cflayer *this, struct cflayer *dn);
-void cfctrl_set_uplayer(struct cflayer *this, struct cflayer *up);
struct cfctrl_rsp *cfctrl_get_respfuncs(struct cflayer *layer);
-bool cfctrl_req_eq(struct cfctrl_request_info *r1,
- struct cfctrl_request_info *r2);
-void cfctrl_insert_req(struct cfctrl *ctrl,
- struct cfctrl_request_info *req);
-struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl,
- struct cfctrl_request_info *req);
-void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer);
+int cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer);
+void cfctrl_remove(struct cflayer *layr);
#endif /* CFCTRL_H_ */
diff --git a/include/net/caif/cffrml.h b/include/net/caif/cffrml.h
index 3f14d2e1ce6..afac1a48cce 100644
--- a/include/net/caif/cffrml.h
+++ b/include/net/caif/cffrml.h
@@ -7,10 +7,15 @@
#ifndef CFFRML_H_
#define CFFRML_H_
#include <net/caif/caif_layer.h>
+#include <linux/netdevice.h>
struct cffrml;
-struct cflayer *cffrml_create(u16 phyid, bool DoFCS);
+struct cflayer *cffrml_create(u16 phyid, bool use_fcs);
+void cffrml_free(struct cflayer *layr);
void cffrml_set_uplayer(struct cflayer *this, struct cflayer *up);
void cffrml_set_dnlayer(struct cflayer *this, struct cflayer *dn);
+void cffrml_put(struct cflayer *layr);
+void cffrml_hold(struct cflayer *layr);
+int cffrml_refcnt_read(struct cflayer *layr);
#endif /* CFFRML_H_ */
diff --git a/include/net/caif/cfmuxl.h b/include/net/caif/cfmuxl.h
index 4e1b4f33423..5847a196b8a 100644
--- a/include/net/caif/cfmuxl.h
+++ b/include/net/caif/cfmuxl.h
@@ -16,7 +16,5 @@ int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid);
struct cflayer *cfmuxl_remove_dnlayer(struct cflayer *layr, u8 phyid);
int cfmuxl_set_dnlayer(struct cflayer *layr, struct cflayer *up, u8 phyid);
struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 linkid);
-bool cfmuxl_is_phy_inuse(struct cflayer *layr, u8 phyid);
-u8 cfmuxl_get_phyid(struct cflayer *layr, u8 channel_id);
#endif /* CFMUXL_H_ */
diff --git a/include/net/caif/cfpkt.h b/include/net/caif/cfpkt.h
index fbc681beff5..6bd200a4754 100644
--- a/include/net/caif/cfpkt.h
+++ b/include/net/caif/cfpkt.h
@@ -16,12 +16,6 @@ struct cfpkt;
*/
struct cfpkt *cfpkt_create(u16 len);
-/* Create a CAIF packet.
- * data Data to copy.
- * len Length of packet to be created
- * @return New packet.
- */
-struct cfpkt *cfpkt_create_uplink(const unsigned char *data, unsigned int len);
/*
* Destroy a CAIF Packet.
* pkt Packet to be destoyed.
@@ -181,22 +175,6 @@ u16 cfpkt_iterate(struct cfpkt *pkt,
u16 (*iter_func)(u16 chks, void *buf, u16 len),
u16 data);
-/* Append by giving user access to packet buffer
- * cfpkt Packet to append to
- * buf Buffer inside pkt that user shall copy data into
- * buflen Length of buffer and number of bytes added to packet
- * @return 0 on error, 1 on success
- */
-int cfpkt_raw_append(struct cfpkt *cfpkt, void **buf, unsigned int buflen);
-
-/* Extract by giving user access to packet buffer
- * cfpkt Packet to extract from
- * buf Buffer inside pkt that user shall copy data from
- * buflen Length of buffer and number of bytes removed from packet
- * @return 0 on error, 1 on success
- */
-int cfpkt_raw_extract(struct cfpkt *cfpkt, void **buf, unsigned int buflen);
-
/* Map from a "native" packet (e.g. Linux Socket Buffer) to a CAIF packet.
* dir - Direction indicating whether this packet is to be sent or received.
* nativepkt - The native packet to be transformed to a CAIF packet
@@ -210,59 +188,6 @@ struct cfpkt *cfpkt_fromnative(enum caif_direction dir, void *nativepkt);
*/
void *cfpkt_tonative(struct cfpkt *pkt);
-/*
- * Insert a packet in the packet queue.
- * pktq Packet queue to insert into
- * pkt Packet to be inserted in queue
- * prio Priority of packet
- */
-void cfpkt_queue(struct cfpktq *pktq, struct cfpkt *pkt,
- unsigned short prio);
-
-/*
- * Remove a packet from the packet queue.
- * pktq Packet queue to fetch packets from.
- * @return Dequeued packet.
- */
-struct cfpkt *cfpkt_dequeue(struct cfpktq *pktq);
-
-/*
- * Peek into a packet from the packet queue.
- * pktq Packet queue to fetch packets from.
- * @return Peeked packet.
- */
-struct cfpkt *cfpkt_qpeek(struct cfpktq *pktq);
-
-/*
- * Initiates the packet queue.
- * @return Pointer to new packet queue.
- */
-struct cfpktq *cfpktq_create(void);
-
-/*
- * Get the number of packets in the queue.
- * pktq Packet queue to fetch count from.
- * @return Number of packets in queue.
- */
-int cfpkt_qcount(struct cfpktq *pktq);
-
-/*
- * Put content of packet into buffer for debuging purposes.
- * pkt Packet to copy data from
- * buf Buffer to copy data into
- * buflen Length of data to copy
- * @return Pointer to copied data
- */
-char *cfpkt_log_pkt(struct cfpkt *pkt, char *buf, int buflen);
-
-/*
- * Clones a packet and releases the original packet.
- * This is used for taking ownership of a packet e.g queueing.
- * pkt Packet to clone and release.
- * @return Cloned packet.
- */
-struct cfpkt *cfpkt_clone_release(struct cfpkt *pkt);
-
/*
* Returns packet information for a packet.
@@ -270,5 +195,4 @@ struct cfpkt *cfpkt_clone_release(struct cfpkt *pkt);
* @return Packet information
*/
struct caif_payload_info *cfpkt_info(struct cfpkt *pkt);
-/*! @} */
#endif /* CFPKT_H_ */
diff --git a/include/net/caif/cfsrvl.h b/include/net/caif/cfsrvl.h
index b1fa87ee099..0f590524184 100644
--- a/include/net/caif/cfsrvl.h
+++ b/include/net/caif/cfsrvl.h
@@ -10,6 +10,7 @@
#include <linux/stddef.h>
#include <linux/types.h>
#include <linux/kref.h>
+#include <linux/rculist.h>
struct cfsrvl {
struct cflayer layer;
@@ -17,12 +18,13 @@ struct cfsrvl {
bool phy_flow_on;
bool modem_flow_on;
bool supports_flowctrl;
- void (*release)(struct kref *);
+ void (*release)(struct cflayer *layer);
struct dev_info dev_info;
- struct kref ref;
+ void (*hold)(struct cflayer *lyr);
+ void (*put)(struct cflayer *lyr);
+ struct rcu_head rcu;
};
-void cfsrvl_release(struct kref *kref);
struct cflayer *cfvei_create(u8 linkid, struct dev_info *dev_info);
struct cflayer *cfdgml_create(u8 linkid, struct dev_info *dev_info);
struct cflayer *cfutill_create(u8 linkid, struct dev_info *dev_info);
@@ -30,8 +32,12 @@ struct cflayer *cfvidl_create(u8 linkid, struct dev_info *dev_info);
struct cflayer *cfrfml_create(u8 linkid, struct dev_info *dev_info,
int mtu_size);
struct cflayer *cfdbgl_create(u8 linkid, struct dev_info *dev_info);
+
+void cfsrvl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
+ int phyid);
+
bool cfsrvl_phyid_match(struct cflayer *layer, int phyid);
-void cfservl_destroy(struct cflayer *layer);
+
void cfsrvl_init(struct cfsrvl *service,
u8 channel_id,
struct dev_info *dev_info,
@@ -41,23 +47,19 @@ u8 cfsrvl_getphyid(struct cflayer *layer);
static inline void cfsrvl_get(struct cflayer *layr)
{
- struct cfsrvl *s;
- if (layr == NULL)
+ struct cfsrvl *s = container_of(layr, struct cfsrvl, layer);
+ if (layr == NULL || layr->up == NULL || s->hold == NULL)
return;
- s = container_of(layr, struct cfsrvl, layer);
- kref_get(&s->ref);
+
+ s->hold(layr->up);
}
static inline void cfsrvl_put(struct cflayer *layr)
{
- struct cfsrvl *s;
- if (layr == NULL)
+ struct cfsrvl *s = container_of(layr, struct cfsrvl, layer);
+ if (layr == NULL || layr->up == NULL || s->hold == NULL)
return;
- s = container_of(layr, struct cfsrvl, layer);
- WARN_ON(!s->release);
- if (s->release)
- kref_put(&s->ref, s->release);
+ s->put(layr->up);
}
-
#endif /* CFSRVL_H_ */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b2b9d28cb4a..bfd6557946b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -387,6 +387,7 @@ enum plink_actions {
* @listen_interval: listen interval or -1 for no change
* @aid: AID or zero for no change
* @plink_action: plink action to take
+ * @plink_state: set the peer link state for a station
* @ht_capa: HT capabilities of station
*/
struct station_parameters {
@@ -397,6 +398,7 @@ struct station_parameters {
u16 aid;
u8 supported_rates_len;
u8 plink_action;
+ u8 plink_state;
struct ieee80211_ht_cap *ht_capa;
};
@@ -422,6 +424,8 @@ struct station_parameters {
* @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled
* @STATION_INFO_SIGNAL_AVG: @signal_avg filled
* @STATION_INFO_RX_BITRATE: @rxrate fields are filled
+ * @STATION_INFO_BSS_PARAM: @bss_param filled
+ * @STATION_INFO_CONNECTED_TIME: @connected_time filled
*/
enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -439,6 +443,8 @@ enum station_info_flags {
STATION_INFO_RX_DROP_MISC = 1<<12,
STATION_INFO_SIGNAL_AVG = 1<<13,
STATION_INFO_RX_BITRATE = 1<<14,
+ STATION_INFO_BSS_PARAM = 1<<15,
+ STATION_INFO_CONNECTED_TIME = 1<<16
};
/**
@@ -473,11 +479,43 @@ struct rate_info {
};
/**
+ * enum station_info_rate_flags - bitrate info flags
+ *
+ * Used by the driver to indicate the specific rate transmission
+ * type for 802.11n transmissions.
+ *
+ * @BSS_PARAM_FLAGS_CTS_PROT: whether CTS protection is enabled
+ * @BSS_PARAM_FLAGS_SHORT_PREAMBLE: whether short preamble is enabled
+ * @BSS_PARAM_FLAGS_SHORT_SLOT_TIME: whether short slot time is enabled
+ */
+enum bss_param_flags {
+ BSS_PARAM_FLAGS_CTS_PROT = 1<<0,
+ BSS_PARAM_FLAGS_SHORT_PREAMBLE = 1<<1,
+ BSS_PARAM_FLAGS_SHORT_SLOT_TIME = 1<<2,
+};
+
+/**
+ * struct sta_bss_parameters - BSS parameters for the attached station
+ *
+ * Information about the currently associated BSS
+ *
+ * @flags: bitflag of flags from &enum bss_param_flags
+ * @dtim_period: DTIM period for the BSS
+ * @beacon_interval: beacon interval
+ */
+struct sta_bss_parameters {
+ u8 flags;
+ u8 dtim_period;
+ u16 beacon_interval;
+};
+
+/**
* struct station_info - station information
*
* Station information filled by driver for get_station() and dump_station.
*
* @filled: bitflag of flags from &enum station_info_flags
+ * @connected_time: time(in secs) since a station is last connected
* @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
@@ -500,6 +538,7 @@ struct rate_info {
*/
struct station_info {
u32 filled;
+ u32 connected_time;
u32 inactive_time;
u32 rx_bytes;
u32 tx_bytes;
@@ -515,6 +554,7 @@ struct station_info {
u32 tx_retries;
u32 tx_failed;
u32 rx_dropped_misc;
+ struct sta_bss_parameters bss_param;
int generation;
};
@@ -655,8 +695,10 @@ struct mesh_config {
* @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes
* @path_sel_proto: which path selection protocol to use
* @path_metric: which metric to use
- * @vendor_ie: vendor information elements (optional)
- * @vendor_ie_len: length of vendor information elements
+ * @ie: vendor information elements (optional)
+ * @ie_len: length of vendor information elements
+ * @is_authenticated: this mesh requires authentication
+ * @is_secure: this mesh uses security
*
* These parameters are fixed when the mesh is created.
*/
@@ -665,8 +707,10 @@ struct mesh_setup {
u8 mesh_id_len;
u8 path_sel_proto;
u8 path_metric;
- const u8 *vendor_ie;
- u8 vendor_ie_len;
+ const u8 *ie;
+ u8 ie_len;
+ bool is_authenticated;
+ bool is_secure;
};
/**
@@ -753,6 +797,35 @@ struct cfg80211_scan_request {
};
/**
+ * struct cfg80211_sched_scan_request - scheduled scan request description
+ *
+ * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans)
+ * @n_ssids: number of SSIDs
+ * @n_channels: total number of channels to scan
+ * @interval: interval between each scheduled scan cycle
+ * @ie: optional information element(s) to add into Probe Request or %NULL
+ * @ie_len: length of ie in octets
+ * @wiphy: the wiphy this was for
+ * @dev: the interface
+ * @channels: channels to scan
+ */
+struct cfg80211_sched_scan_request {
+ struct cfg80211_ssid *ssids;
+ int n_ssids;
+ u32 n_channels;
+ u32 interval;
+ const u8 *ie;
+ size_t ie_len;
+
+ /* internal */
+ struct wiphy *wiphy;
+ struct net_device *dev;
+
+ /* keep last */
+ struct ieee80211_channel *channels[0];
+};
+
+/**
* enum cfg80211_signal_type - signal type
*
* @CFG80211_SIGNAL_TYPE_NONE: no signal strength information available
@@ -1048,6 +1121,38 @@ struct cfg80211_pmksa {
};
/**
+ * struct cfg80211_wowlan_trig_pkt_pattern - packet pattern
+ * @mask: bitmask where to match pattern and where to ignore bytes,
+ * one bit per byte, in same format as nl80211
+ * @pattern: bytes to match where bitmask is 1
+ * @pattern_len: length of pattern (in bytes)
+ *
+ * Internal note: @mask and @pattern are allocated in one chunk of
+ * memory, free @mask only!
+ */
+struct cfg80211_wowlan_trig_pkt_pattern {
+ u8 *mask, *pattern;
+ int pattern_len;
+};
+
+/**
+ * struct cfg80211_wowlan - Wake on Wireless-LAN support info
+ *
+ * This structure defines the enabled WoWLAN triggers for the device.
+ * @any: wake up on any activity -- special trigger if device continues
+ * operating as normal during suspend
+ * @disconnect: wake up if getting disconnected
+ * @magic_pkt: wake up on receiving magic packet
+ * @patterns: wake up on receiving packet matching a pattern
+ * @n_patterns: number of patterns
+ */
+struct cfg80211_wowlan {
+ bool any, disconnect, magic_pkt;
+ struct cfg80211_wowlan_trig_pkt_pattern *patterns;
+ int n_patterns;
+};
+
+/**
* struct cfg80211_ops - backend description for wireless configuration
*
* This struct is registered by fullmac card drivers and/or wireless stacks
@@ -1060,7 +1165,9 @@ struct cfg80211_pmksa {
* wireless extensions but this is subject to reevaluation as soon as this
* code is used more widely and we have a first user without wext.
*
- * @suspend: wiphy device needs to be suspended
+ * @suspend: wiphy device needs to be suspended. The variable @wow will
+ * be %NULL or contain the enabled Wake-on-Wireless triggers that are
+ * configured for the device.
* @resume: wiphy device needs to be resumed
*
* @add_virtual_intf: create a new virtual interface with the given name,
@@ -1187,6 +1294,10 @@ struct cfg80211_pmksa {
* @set_power_mgmt: Configure WLAN power management. A timeout value of -1
* allows the driver to adjust the dynamic ps timeout value.
* @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold.
+ * @sched_scan_start: Tell the driver to start a scheduled scan.
+ * @sched_scan_stop: Tell the driver to stop an ongoing scheduled
+ * scan. The driver_initiated flag specifies whether the driver
+ * itself has informed that the scan has stopped.
*
* @mgmt_frame_register: Notify driver that a management frame type was
* registered. Note that this callback may not sleep, and cannot run
@@ -1204,7 +1315,7 @@ struct cfg80211_pmksa {
* @get_ringparam: Get tx and rx ring current and maximum sizes.
*/
struct cfg80211_ops {
- int (*suspend)(struct wiphy *wiphy);
+ int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
int (*resume)(struct wiphy *wiphy);
struct net_device * (*add_virtual_intf)(struct wiphy *wiphy,
@@ -1373,6 +1484,11 @@ struct cfg80211_ops {
int (*set_ringparam)(struct wiphy *wiphy, u32 tx, u32 rx);
void (*get_ringparam)(struct wiphy *wiphy,
u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
+
+ int (*sched_scan_start)(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_sched_scan_request *request);
+ int (*sched_scan_stop)(struct wiphy *wiphy, struct net_device *dev);
};
/*
@@ -1404,6 +1520,10 @@ struct cfg80211_ops {
* hints read the documenation for regulatory_hint_found_beacon()
* @WIPHY_FLAG_NETNS_OK: if not set, do not allow changing the netns of this
* wiphy at all
+ * @WIPHY_FLAG_ENFORCE_COMBINATIONS: Set this flag to enforce interface
+ * combinations for this device. This flag is used for backward
+ * compatibility only until all drivers advertise combinations and
+ * they will always be enforced.
* @WIPHY_FLAG_PS_ON_BY_DEFAULT: if set to true, powersave will be enabled
* by default -- this flag will be set depending on the kernel's default
* on wiphy_new(), but can be changed by the driver if it has a good
@@ -1415,8 +1535,9 @@ struct cfg80211_ops {
* control port protocol ethertype. The device also honours the
* control_port_no_encrypt flag.
* @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN.
- * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate
- * unicast and multicast TX keys.
+ * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing
+ * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH.
+ * @WIPHY_FLAG_SCHED_SCAN: The device supports scheduled scans.
*/
enum wiphy_flags {
WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -1428,7 +1549,83 @@ enum wiphy_flags {
WIPHY_FLAG_4ADDR_STATION = BIT(6),
WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7),
WIPHY_FLAG_IBSS_RSN = BIT(8),
- WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9),
+ WIPHY_FLAG_MESH_AUTH = BIT(10),
+ WIPHY_FLAG_SUPPORTS_SCHED_SCAN = BIT(11),
+ WIPHY_FLAG_ENFORCE_COMBINATIONS = BIT(12),
+};
+
+/**
+ * struct ieee80211_iface_limit - limit on certain interface types
+ * @max: maximum number of interfaces of these types
+ * @types: interface types (bits)
+ */
+struct ieee80211_iface_limit {
+ u16 max;
+ u16 types;
+};
+
+/**
+ * struct ieee80211_iface_combination - possible interface combination
+ * @limits: limits for the given interface types
+ * @n_limits: number of limitations
+ * @num_different_channels: can use up to this many different channels
+ * @max_interfaces: maximum number of interfaces in total allowed in this
+ * group
+ * @beacon_int_infra_match: In this combination, the beacon intervals
+ * between infrastructure and AP types must match. This is required
+ * only in special cases.
+ *
+ * These examples can be expressed as follows:
+ *
+ * Allow #STA <= 1, #AP <= 1, matching BI, channels = 1, 2 total:
+ *
+ * struct ieee80211_iface_limit limits1[] = {
+ * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), },
+ * { .max = 1, .types = BIT(NL80211_IFTYPE_AP}, },
+ * };
+ * struct ieee80211_iface_combination combination1 = {
+ * .limits = limits1,
+ * .n_limits = ARRAY_SIZE(limits1),
+ * .max_interfaces = 2,
+ * .beacon_int_infra_match = true,
+ * };
+ *
+ *
+ * Allow #{AP, P2P-GO} <= 8, channels = 1, 8 total:
+ *
+ * struct ieee80211_iface_limit limits2[] = {
+ * { .max = 8, .types = BIT(NL80211_IFTYPE_AP) |
+ * BIT(NL80211_IFTYPE_P2P_GO), },
+ * };
+ * struct ieee80211_iface_combination combination2 = {
+ * .limits = limits2,
+ * .n_limits = ARRAY_SIZE(limits2),
+ * .max_interfaces = 8,
+ * .num_different_channels = 1,
+ * };
+ *
+ *
+ * Allow #STA <= 1, #{P2P-client,P2P-GO} <= 3 on two channels, 4 total.
+ * This allows for an infrastructure connection and three P2P connections.
+ *
+ * struct ieee80211_iface_limit limits3[] = {
+ * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), },
+ * { .max = 3, .types = BIT(NL80211_IFTYPE_P2P_GO) |
+ * BIT(NL80211_IFTYPE_P2P_CLIENT), },
+ * };
+ * struct ieee80211_iface_combination combination3 = {
+ * .limits = limits3,
+ * .n_limits = ARRAY_SIZE(limits3),
+ * .max_interfaces = 4,
+ * .num_different_channels = 2,
+ * };
+ */
+struct ieee80211_iface_combination {
+ const struct ieee80211_iface_limit *limits;
+ u32 num_different_channels;
+ u16 max_interfaces;
+ u8 n_limits;
+ bool beacon_int_infra_match;
};
struct mac_address {
@@ -1440,6 +1637,38 @@ struct ieee80211_txrx_stypes {
};
/**
+ * enum wiphy_wowlan_support_flags - WoWLAN support flags
+ * @WIPHY_WOWLAN_ANY: supports wakeup for the special "any"
+ * trigger that keeps the device operating as-is and
+ * wakes up the host on any activity, for example a
+ * received packet that passed filtering; note that the
+ * packet should be preserved in that case
+ * @WIPHY_WOWLAN_MAGIC_PKT: supports wakeup on magic packet
+ * (see nl80211.h)
+ * @WIPHY_WOWLAN_DISCONNECT: supports wakeup on disconnect
+ */
+enum wiphy_wowlan_support_flags {
+ WIPHY_WOWLAN_ANY = BIT(0),
+ WIPHY_WOWLAN_MAGIC_PKT = BIT(1),
+ WIPHY_WOWLAN_DISCONNECT = BIT(2),
+};
+
+/**
+ * struct wiphy_wowlan_support - WoWLAN support data
+ * @flags: see &enum wiphy_wowlan_support_flags
+ * @n_patterns: number of supported wakeup patterns
+ * (see nl80211.h for the pattern definition)
+ * @pattern_max_len: maximum length of each pattern
+ * @pattern_min_len: minimum length of each pattern
+ */
+struct wiphy_wowlan_support {
+ u32 flags;
+ int n_patterns;
+ int pattern_max_len;
+ int pattern_min_len;
+};
+
+/**
* struct wiphy - wireless hardware description
* @reg_notifier: the driver's regulatory notification callback,
* note that if your driver uses wiphy_apply_custom_regulatory()
@@ -1476,6 +1705,11 @@ struct ieee80211_txrx_stypes {
* @priv: driver private data (sized according to wiphy_new() parameter)
* @interface_modes: bitmask of interfaces types valid for this wiphy,
* must be set by driver
+ * @iface_combinations: Valid interface combinations array, should not
+ * list single interface types.
+ * @n_iface_combinations: number of entries in @iface_combinations array.
+ * @software_iftypes: bitmask of software interface types, these are not
+ * subject to any restrictions since they are purely managed in SW.
* @flags: wiphy flags, see &enum wiphy_flags
* @bss_priv_size: each BSS struct has private data allocated with it,
* this variable determines its size
@@ -1506,6 +1740,8 @@ struct ieee80211_txrx_stypes {
*
* @max_remain_on_channel_duration: Maximum time a remain-on-channel operation
* may request, if implemented.
+ *
+ * @wowlan: WoWLAN support information
*/
struct wiphy {
/* assign these fields before you register the wiphy */
@@ -1518,6 +1754,10 @@ struct wiphy {
const struct ieee80211_txrx_stypes *mgmt_stypes;
+ const struct ieee80211_iface_combination *iface_combinations;
+ int n_iface_combinations;
+ u16 software_iftypes;
+
u16 n_addresses;
/* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */
@@ -1543,6 +1783,8 @@ struct wiphy {
char fw_version[ETHTOOL_BUSINFO_LEN];
u32 hw_version;
+ struct wiphy_wowlan_support wowlan;
+
u16 max_remain_on_channel_duration;
u8 max_num_pmkids;
@@ -1726,6 +1968,8 @@ struct cfg80211_cached_keys;
* @mgmt_registrations_lock: lock for the list
* @mtx: mutex used to lock data in this struct
* @cleanup_work: work struct used for cleanup that can't be done directly
+ * @beacon_interval: beacon interval used on this device for transmitting
+ * beacons, 0 when not valid
*/
struct wireless_dev {
struct wiphy *wiphy;
@@ -1766,6 +2010,8 @@ struct wireless_dev {
bool ps;
int ps_timeout;
+ int beacon_interval;
+
#ifdef CONFIG_CFG80211_WEXT
/* wext data */
struct {
@@ -1991,10 +2237,12 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
* @addr: The device MAC address.
* @iftype: The device interface type.
* @extra_headroom: The hardware extra headroom for SKBs in the @list.
+ * @has_80211_header: Set it true if SKB is with IEEE 802.11 header.
*/
void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
const u8 *addr, enum nl80211_iftype iftype,
- const unsigned int extra_headroom);
+ const unsigned int extra_headroom,
+ bool has_80211_header);
/**
* cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame
@@ -2214,6 +2462,24 @@ int cfg80211_wext_siwpmksa(struct net_device *dev,
void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted);
/**
+ * cfg80211_sched_scan_results - notify that new scan results are available
+ *
+ * @wiphy: the wiphy which got scheduled scan results
+ */
+void cfg80211_sched_scan_results(struct wiphy *wiphy);
+
+/**
+ * cfg80211_sched_scan_stopped - notify that the scheduled scan has stopped
+ *
+ * @wiphy: the wiphy on which the scheduled scan stopped
+ *
+ * The driver can call this function to inform cfg80211 that the
+ * scheduled scan had to be stopped, for whatever reason. The driver
+ * is then called back via the sched_scan_stop operation when done.
+ */
+void cfg80211_sched_scan_stopped(struct wiphy *wiphy);
+
+/**
* cfg80211_inform_bss_frame - inform cfg80211 of a received BSS frame
*
* @wiphy: the wiphy reporting the BSS
@@ -2450,6 +2716,22 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp);
/**
+ * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate
+ *
+ * @dev: network device
+ * @macaddr: the MAC address of the new candidate
+ * @ie: information elements advertised by the peer candidate
+ * @ie_len: lenght of the information elements buffer
+ * @gfp: allocation flags
+ *
+ * This function notifies cfg80211 that the mesh peer candidate has been
+ * detected, most likely via a beacon or, less likely, via a probe response.
+ * cfg80211 then sends a notification to userspace.
+ */
+void cfg80211_notify_new_peer_candidate(struct net_device *dev,
+ const u8 *macaddr, const u8 *ie, u8 ie_len, gfp_t gfp);
+
+/**
* DOC: RFkill integration
*
* RFkill integration in cfg80211 is almost invisible to drivers,
@@ -2667,6 +2949,15 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
struct station_info *sinfo, gfp_t gfp);
/**
+ * cfg80211_del_sta - notify userspace about deletion of a station
+ *
+ * @dev: the netdev
+ * @mac_addr: the station's address
+ * @gfp: allocation flags
+ */
+void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp);
+
+/**
* cfg80211_rx_mgmt - notification of received, unprocessed management frame
* @dev: network device
* @freq: Frequency on which the frame was received in MHz
diff --git a/include/net/compat.h b/include/net/compat.h
index 28d5428ec6a..9ee75edcc29 100644
--- a/include/net/compat.h
+++ b/include/net/compat.h
@@ -43,6 +43,8 @@ extern int compat_sock_get_timestampns(struct sock *, struct timespec __user *);
extern int get_compat_msghdr(struct msghdr *, struct compat_msghdr __user *);
extern int verify_compat_iovec(struct msghdr *, struct iovec *, struct sockaddr *, int);
extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr __user *,unsigned);
+extern asmlinkage long compat_sys_sendmmsg(int, struct compat_mmsghdr __user *,
+ unsigned, unsigned);
extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsigned);
extern asmlinkage long compat_sys_recvmmsg(int, struct compat_mmsghdr __user *,
unsigned, unsigned,
diff --git a/include/net/dst.h b/include/net/dst.h
index 75b95df4afe..07a0402c52e 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -16,13 +16,6 @@
#include <net/neighbour.h>
#include <asm/processor.h>
-/*
- * 0 - no debugging messages
- * 1 - rare events and bugs (default)
- * 2 - trace mode.
- */
-#define RT_CACHE_DEBUG 0
-
#define DST_GC_MIN (HZ/10)
#define DST_GC_INC (HZ/2)
#define DST_GC_MAX (120*HZ)
@@ -92,8 +85,6 @@ struct dst_entry {
};
};
-#ifdef __KERNEL__
-
extern u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old);
extern const u32 dst_default_metrics[RTAX_MAX];
@@ -352,7 +343,8 @@ static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb)
}
extern int dst_discard(struct sk_buff *skb);
-extern void *dst_alloc(struct dst_ops * ops, int initial_ref);
+extern void *dst_alloc(struct dst_ops * ops, struct net_device *dev,
+ int initial_ref, int initial_obsolete, int flags);
extern void __dst_free(struct dst_entry * dst);
extern struct dst_entry *dst_destroy(struct dst_entry * dst);
@@ -438,6 +430,5 @@ extern struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig
const struct flowi *fl, struct sock *sk,
int flags);
#endif
-#endif
#endif /* _NET_DST_H */
diff --git a/include/net/flow.h b/include/net/flow.h
index 7fe5a0f9483..c6d5fe5ec1b 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -26,8 +26,8 @@ struct flowi_common {
union flowi_uli {
struct {
- __be16 sport;
__be16 dport;
+ __be16 sport;
} ports;
struct {
@@ -36,8 +36,8 @@ union flowi_uli {
} icmpt;
struct {
- __le16 sport;
__le16 dport;
+ __le16 sport;
} dnports;
__be32 spi;
@@ -70,6 +70,27 @@ struct flowi4 {
#define fl4_gre_key uli.gre_key
};
+static inline void flowi4_init_output(struct flowi4 *fl4, int oif,
+ __u32 mark, __u8 tos, __u8 scope,
+ __u8 proto, __u8 flags,
+ __be32 daddr, __be32 saddr,
+ __be16 dport, __be32 sport)
+{
+ fl4->flowi4_oif = oif;
+ fl4->flowi4_iif = 0;
+ fl4->flowi4_mark = mark;
+ fl4->flowi4_tos = tos;
+ fl4->flowi4_scope = scope;
+ fl4->flowi4_proto = proto;
+ fl4->flowi4_flags = flags;
+ fl4->flowi4_secid = 0;
+ fl4->daddr = daddr;
+ fl4->saddr = saddr;
+ fl4->fl4_dport = dport;
+ fl4->fl4_sport = sport;
+}
+
+
struct flowi6 {
struct flowi_common __fl_common;
#define flowi6_oif __fl_common.flowic_oif
diff --git a/include/net/garp.h b/include/net/garp.h
index f4c295984c4..834d8add9e5 100644
--- a/include/net/garp.h
+++ b/include/net/garp.h
@@ -104,10 +104,12 @@ struct garp_applicant {
struct sk_buff_head queue;
struct sk_buff *pdu;
struct rb_root gid;
+ struct rcu_head rcu;
};
struct garp_port {
struct garp_applicant __rcu *applicants[GARP_APPLICATION_MAX + 1];
+ struct rcu_head rcu;
};
extern int garp_register_application(struct garp_application *app);
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index fccc2180c61..11cf373970a 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -30,8 +30,6 @@
#define IF_PREFIX_ONLINK 0x01
#define IF_PREFIX_AUTOCONF 0x02
-#ifdef __KERNEL__
-
enum {
INET6_IFADDR_STATE_DAD,
INET6_IFADDR_STATE_POSTDAD,
@@ -156,8 +154,8 @@ struct ifacaddr6 {
struct ipv6_devstat {
struct proc_dir_entry *proc_dir_entry;
DEFINE_SNMP_STAT(struct ipstats_mib, ipv6);
- DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6);
- DEFINE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg);
+ DEFINE_SNMP_STAT_ATOMIC(struct icmpv6_mib_device, icmpv6dev);
+ DEFINE_SNMP_STAT_ATOMIC(struct icmpv6msg_mib_device, icmpv6msgdev);
};
struct inet6_dev {
@@ -196,7 +194,7 @@ struct inet6_dev {
struct rcu_head rcu;
};
-static inline void ipv6_eth_mc_map(struct in6_addr *addr, char *buf)
+static inline void ipv6_eth_mc_map(const struct in6_addr *addr, char *buf)
{
/*
* +-------+-------+-------+-------+-------+-------+
@@ -210,7 +208,7 @@ static inline void ipv6_eth_mc_map(struct in6_addr *addr, char *buf)
memcpy(buf + 2, &addr->s6_addr32[3], sizeof(__u32));
}
-static inline void ipv6_tr_mc_map(struct in6_addr *addr, char *buf)
+static inline void ipv6_tr_mc_map(const struct in6_addr *addr, char *buf)
{
/* All nodes FF01::1, FF02::1, FF02::1:FFxx:xxxx */
@@ -303,4 +301,3 @@ static inline int ipv6_ipgre_mc_map(const struct in6_addr *addr,
}
#endif
-#endif
diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h
index ff013505236..3207e58ee01 100644
--- a/include/net/inet6_connection_sock.h
+++ b/include/net/inet6_connection_sock.h
@@ -41,5 +41,5 @@ extern void inet6_csk_reqsk_queue_hash_add(struct sock *sk,
extern void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
-extern int inet6_csk_xmit(struct sk_buff *skb);
+extern int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl);
#endif /* _INET6_CONNECTION_SOCK_H */
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 6ac4e3b5007..e6db62e756d 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -36,7 +36,7 @@ struct tcp_congestion_ops;
* (i.e. things that depend on the address family)
*/
struct inet_connection_sock_af_ops {
- int (*queue_xmit)(struct sk_buff *skb);
+ int (*queue_xmit)(struct sk_buff *skb, struct flowi *fl);
void (*send_check)(struct sock *sk, struct sk_buff *skb);
int (*rebuild_header)(struct sock *sk);
int (*conn_request)(struct sock *sk, struct sk_buff *skb);
@@ -249,7 +249,11 @@ extern int inet_csk_bind_conflict(const struct sock *sk,
extern int inet_csk_get_port(struct sock *sk, unsigned short snum);
extern struct dst_entry* inet_csk_route_req(struct sock *sk,
+ struct flowi4 *fl4,
const struct request_sock *req);
+extern struct dst_entry* inet_csk_route_child_sock(struct sock *sk,
+ struct sock *newsk,
+ const struct request_sock *req);
static inline void inet_csk_reqsk_queue_add(struct sock *sk,
struct request_sock *req,
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index 7a37369f8ea..caaff5f5f39 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -57,7 +57,15 @@ struct ip_options {
unsigned char __data[0];
};
-#define optlength(opt) (sizeof(struct ip_options) + opt->optlen)
+struct ip_options_rcu {
+ struct rcu_head rcu;
+ struct ip_options opt;
+};
+
+struct ip_options_data {
+ struct ip_options_rcu opt;
+ char data[40];
+};
struct inet_request_sock {
struct request_sock req;
@@ -78,7 +86,7 @@ struct inet_request_sock {
acked : 1,
no_srccheck: 1;
kmemcheck_bitfield_end(flags);
- struct ip_options *opt;
+ struct ip_options_rcu *opt;
};
static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
@@ -88,17 +96,21 @@ static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
struct inet_cork {
unsigned int flags;
- unsigned int fragsize;
+ __be32 addr;
struct ip_options *opt;
+ unsigned int fragsize;
struct dst_entry *dst;
int length; /* Total length of all frames */
- __be32 addr;
- struct flowi fl;
struct page *page;
u32 off;
u8 tx_flags;
};
+struct inet_cork_full {
+ struct inet_cork base;
+ struct flowi fl;
+};
+
struct ip_mc_socklist;
struct ipv6_pinfo;
struct rtable;
@@ -140,7 +152,7 @@ struct inet_sock {
__be16 inet_sport;
__u16 inet_id;
- struct ip_options *opt;
+ struct ip_options_rcu __rcu *inet_opt;
__u8 tos;
__u8 min_ttl;
__u8 mc_ttl;
@@ -156,7 +168,7 @@ struct inet_sock {
int mc_index;
__be32 mc_addr;
struct ip_mc_socklist __rcu *mc_list;
- struct inet_cork cork;
+ struct inet_cork_full cork;
};
#define IPCORK_OPT 1 /* ip-options has been held in ipcork.opt */
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
index e6dd8da6b2a..8a159cc3d68 100644
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -80,7 +80,7 @@ static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create)
return inet_getpeer(&daddr, create);
}
-static inline struct inet_peer *inet_getpeer_v6(struct in6_addr *v6daddr, int create)
+static inline struct inet_peer *inet_getpeer_v6(const struct in6_addr *v6daddr, int create)
{
struct inetpeer_addr daddr;
diff --git a/include/net/ip.h b/include/net/ip.h
index 7c416583b71..66dd4914920 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -52,7 +52,7 @@ static inline unsigned int ip_hdrlen(const struct sk_buff *skb)
struct ipcm_cookie {
__be32 addr;
int oif;
- struct ip_options *opt;
+ struct ip_options_rcu *opt;
__u8 tx_flags;
};
@@ -92,7 +92,7 @@ extern int igmp_mc_proc_init(void);
extern int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
__be32 saddr, __be32 daddr,
- struct ip_options *opt);
+ struct ip_options_rcu *opt);
extern int ip_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev);
extern int ip_local_deliver(struct sk_buff *skb);
@@ -104,9 +104,9 @@ 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);
+extern int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl);
extern void ip_init(void);
-extern int ip_append_data(struct sock *sk,
+extern int ip_append_data(struct sock *sk, struct flowi4 *fl4,
int getfrag(void *from, char *to, int offset, int len,
int odd, struct sk_buff *skb),
void *from, int len, int protolen,
@@ -114,15 +114,17 @@ extern int ip_append_data(struct sock *sk,
struct rtable **rt,
unsigned int flags);
extern int ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb);
-extern ssize_t ip_append_page(struct sock *sk, struct page *page,
+extern ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
int offset, size_t size, int flags);
extern struct sk_buff *__ip_make_skb(struct sock *sk,
+ struct flowi4 *fl4,
struct sk_buff_head *queue,
struct inet_cork *cork);
extern int ip_send_skb(struct sk_buff *skb);
-extern int ip_push_pending_frames(struct sock *sk);
+extern int ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4);
extern void ip_flush_pending_frames(struct sock *sk);
extern struct sk_buff *ip_make_skb(struct sock *sk,
+ struct flowi4 *fl4,
int getfrag(void *from, char *to, int offset, int len,
int odd, struct sk_buff *skb),
void *from, int length, int transhdrlen,
@@ -130,9 +132,9 @@ extern struct sk_buff *ip_make_skb(struct sock *sk,
struct rtable **rtp,
unsigned int flags);
-static inline struct sk_buff *ip_finish_skb(struct sock *sk)
+static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4)
{
- return __ip_make_skb(sk, &sk->sk_write_queue, &inet_sk(sk)->cork);
+ return __ip_make_skb(sk, fl4, &sk->sk_write_queue, &inet_sk(sk)->cork.base);
}
/* datagram.c */
@@ -172,8 +174,8 @@ static inline __u8 ip_reply_arg_flowi_flags(const struct ip_reply_arg *arg)
return (arg->flags & IP_REPLY_ARG_NOSRCCHECK) ? FLOWI_FLAG_ANYSRC : 0;
}
-void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg,
- unsigned int len);
+void ip_send_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr,
+ struct ip_reply_arg *arg, unsigned int len);
struct ipv4_config {
int log_martians;
@@ -416,14 +418,15 @@ extern int ip_forward(struct sk_buff *skb);
* Functions provided by ip_options.c
*/
-extern void ip_options_build(struct sk_buff *skb, struct ip_options *opt, __be32 daddr, struct rtable *rt, int is_frag);
+extern void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
+ __be32 daddr, struct rtable *rt, int is_frag);
extern int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb);
extern void ip_options_fragment(struct sk_buff *skb);
extern int ip_options_compile(struct net *net,
struct ip_options *opt, struct sk_buff *skb);
-extern int ip_options_get(struct net *net, struct ip_options **optp,
+extern int ip_options_get(struct net *net, struct ip_options_rcu **optp,
unsigned char *data, int optlen);
-extern int ip_options_get_from_user(struct net *net, struct ip_options **optp,
+extern int ip_options_get_from_user(struct net *net, struct ip_options_rcu **optp,
unsigned char __user *data, int optlen);
extern void ip_options_undo(struct ip_options * opt);
extern void ip_forward_options(struct sk_buff *skb);
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index bc3cde0a810..477ef75f387 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -13,8 +13,6 @@
#ifndef _IP6_FIB_H
#define _IP6_FIB_H
-#ifdef __KERNEL__
-
#include <linux/ipv6_route.h>
#include <linux/rtnetlink.h>
#include <linux/spinlock.h>
@@ -42,6 +40,7 @@ struct fib6_config {
struct in6_addr fc_dst;
struct in6_addr fc_src;
+ struct in6_addr fc_prefsrc;
struct in6_addr fc_gateway;
unsigned long fc_expires;
@@ -107,6 +106,7 @@ struct rt6_info {
struct rt6key rt6i_dst ____cacheline_aligned_in_smp;
u32 rt6i_flags;
struct rt6key rt6i_src;
+ struct rt6key rt6i_prefsrc;
u32 rt6i_metric;
u32 rt6i_peer_genid;
@@ -196,12 +196,12 @@ extern struct dst_entry *fib6_rule_lookup(struct net *net,
pol_lookup_t lookup);
extern struct fib6_node *fib6_lookup(struct fib6_node *root,
- struct in6_addr *daddr,
- struct in6_addr *saddr);
+ const struct in6_addr *daddr,
+ const struct in6_addr *saddr);
struct fib6_node *fib6_locate(struct fib6_node *root,
- struct in6_addr *daddr, int dst_len,
- struct in6_addr *saddr, int src_len);
+ const struct in6_addr *daddr, int dst_len,
+ const struct in6_addr *saddr, int src_len);
extern void fib6_clean_all(struct net *net,
int (*func)(struct rt6_info *, void *arg),
@@ -238,4 +238,3 @@ static inline void fib6_rules_cleanup(void)
}
#endif
#endif
-#endif
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index c850e5fb967..5e91b72fc71 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -21,8 +21,6 @@ struct route_info {
__u8 prefix[0]; /* 0,8 or 16 */
};
-#ifdef __KERNEL__
-
#include <net/flow.h>
#include <net/ip6_fib.h>
#include <net/sock.h>
@@ -84,6 +82,12 @@ extern int ip6_route_add(struct fib6_config *cfg);
extern int ip6_ins_rt(struct rt6_info *);
extern int ip6_del_rt(struct rt6_info *);
+extern int ip6_route_get_saddr(struct net *net,
+ struct rt6_info *rt,
+ const struct in6_addr *daddr,
+ unsigned int prefs,
+ struct in6_addr *saddr);
+
extern struct rt6_info *rt6_lookup(struct net *net,
const struct in6_addr *daddr,
const struct in6_addr *saddr,
@@ -106,9 +110,9 @@ extern int ip6_dst_hoplimit(struct dst_entry *dst);
* support functions for ND
*
*/
-extern struct rt6_info * rt6_get_dflt_router(struct in6_addr *addr,
+extern struct rt6_info * rt6_get_dflt_router(const struct in6_addr *addr,
struct net_device *dev);
-extern struct rt6_info * rt6_add_dflt_router(struct in6_addr *gwaddr,
+extern struct rt6_info * rt6_add_dflt_router(const struct in6_addr *gwaddr,
struct net_device *dev,
unsigned int pref);
@@ -116,17 +120,17 @@ extern void rt6_purge_dflt_routers(struct net *net);
extern int rt6_route_rcv(struct net_device *dev,
u8 *opt, int len,
- struct in6_addr *gwaddr);
+ const struct in6_addr *gwaddr);
-extern void rt6_redirect(struct in6_addr *dest,
- struct in6_addr *src,
- struct in6_addr *saddr,
+extern void rt6_redirect(const struct in6_addr *dest,
+ const struct in6_addr *src,
+ const struct in6_addr *saddr,
struct neighbour *neigh,
u8 *lladdr,
int on_link);
-extern void rt6_pmtu_discovery(struct in6_addr *daddr,
- struct in6_addr *saddr,
+extern void rt6_pmtu_discovery(const struct in6_addr *daddr,
+ const struct in6_addr *saddr,
struct net_device *dev,
u32 pmtu);
@@ -141,6 +145,7 @@ struct rt6_rtnl_dump_arg {
extern int rt6_dump_route(struct rt6_info *rt, void *p_arg);
extern void rt6_ifdown(struct net *net, struct net_device *dev);
extern void rt6_mtu_change(struct net_device *dev, unsigned mtu);
+extern void rt6_remove_prefsrc(struct inet6_ifaddr *ifp);
/*
@@ -186,4 +191,3 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
}
#endif
-#endif
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index e5d66ec88cf..10422ef14e2 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -160,7 +160,8 @@ struct fib_table {
struct hlist_node tb_hlist;
u32 tb_id;
int tb_default;
- unsigned char tb_data[0];
+ int tb_num_default;
+ unsigned long tb_data[0];
};
extern int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
@@ -227,9 +228,9 @@ extern struct fib_table *fib_get_table(struct net *net, u32 id);
/* Exported by fib_frontend.c */
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, u32 mark);
+extern int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
+ u8 tos, int oif, struct net_device *dev,
+ __be32 *spec_dst, u32 *itag);
extern void fib_select_default(struct fib_result *res);
/* Exported by fib_semantics.c */
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 86aefed6140..4fff432aead 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -8,9 +8,6 @@
#include <linux/ip_vs.h> /* definitions shared with userland */
-/* old ipvsadm versions still include this file directly */
-#ifdef __KERNEL__
-
#include <asm/types.h> /* for __uXX types */
#include <linux/sysctl.h> /* for ctl_path */
@@ -668,9 +665,7 @@ struct ip_vs_dest {
struct dst_entry *dst_cache; /* destination cache entry */
u32 dst_rtos; /* RT_TOS(tos) for dst */
u32 dst_cookie;
-#ifdef CONFIG_IP_VS_IPV6
- struct in6_addr dst_saddr;
-#endif
+ union nf_inet_addr dst_saddr;
/* for virtual service */
struct ip_vs_service *svc; /* service it belongs to */
@@ -1256,7 +1251,8 @@ extern int ip_vs_tunnel_xmit
extern int ip_vs_dr_xmit
(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
extern int ip_vs_icmp_xmit
-(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp, int offset);
+(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp,
+ int offset, unsigned int hooknum);
extern void ip_vs_dst_reset(struct ip_vs_dest *dest);
#ifdef CONFIG_IP_VS_IPV6
@@ -1270,7 +1266,7 @@ extern int ip_vs_dr_xmit_v6
(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
extern int ip_vs_icmp_xmit_v6
(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp,
- int offset);
+ int offset, unsigned int hooknum);
#endif
#ifdef CONFIG_SYSCTL
@@ -1432,6 +1428,4 @@ ip_vs_dest_conn_overhead(struct ip_vs_dest *dest)
atomic_read(&dest->inactconns);
}
-#endif /* __KERNEL__ */
-
#endif /* _NET_IP_VS_H */
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 34200f9e680..c033ed00df7 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -77,11 +77,9 @@
/*
* Addr scopes
*/
-#ifdef __KERNEL__
#define IPV6_ADDR_MC_SCOPE(a) \
((a)->s6_addr[1] & 0x0f) /* nonstandard */
#define __IPV6_ADDR_SCOPE_INVALID -1
-#endif
#define IPV6_ADDR_SCOPE_NODELOCAL 0x01
#define IPV6_ADDR_SCOPE_LINKLOCAL 0x02
#define IPV6_ADDR_SCOPE_SITELOCAL 0x05
@@ -91,14 +89,12 @@
/*
* Addr flags
*/
-#ifdef __KERNEL__
#define IPV6_ADDR_MC_FLAG_TRANSIENT(a) \
((a)->s6_addr[1] & 0x10)
#define IPV6_ADDR_MC_FLAG_PREFIX(a) \
((a)->s6_addr[1] & 0x20)
#define IPV6_ADDR_MC_FLAG_RENDEZVOUS(a) \
((a)->s6_addr[1] & 0x40)
-#endif
/*
* fragmentation header
@@ -113,8 +109,6 @@ struct frag_hdr {
#define IP6_MF 0x0001
-#ifdef __KERNEL__
-
#include <net/sock.h>
/* sysctls */
@@ -129,6 +123,15 @@ extern struct ctl_path net_ipv6_ctl_path[];
SNMP_INC_STATS##modifier((net)->mib.statname##_statistics, (field));\
})
+/* per device counters are atomic_long_t */
+#define _DEVINCATOMIC(net, statname, modifier, idev, field) \
+({ \
+ struct inet6_dev *_idev = (idev); \
+ if (likely(_idev != NULL)) \
+ SNMP_INC_STATS_ATOMIC_LONG((_idev)->stats.statname##dev, (field)); \
+ SNMP_INC_STATS##modifier((net)->mib.statname##_statistics, (field));\
+})
+
#define _DEVADD(net, statname, modifier, idev, field, val) \
({ \
struct inet6_dev *_idev = (idev); \
@@ -160,16 +163,16 @@ extern struct ctl_path net_ipv6_ctl_path[];
#define IP6_UPD_PO_STATS_BH(net, idev,field,val) \
_DEVUPD(net, ipv6, 64_BH, idev, field, val)
#define ICMP6_INC_STATS(net, idev, field) \
- _DEVINC(net, icmpv6, , idev, field)
+ _DEVINCATOMIC(net, icmpv6, , idev, field)
#define ICMP6_INC_STATS_BH(net, idev, field) \
- _DEVINC(net, icmpv6, _BH, idev, field)
+ _DEVINCATOMIC(net, icmpv6, _BH, idev, field)
#define ICMP6MSGOUT_INC_STATS(net, idev, field) \
- _DEVINC(net, icmpv6msg, , idev, field +256)
+ _DEVINCATOMIC(net, icmpv6msg, , idev, field +256)
#define ICMP6MSGOUT_INC_STATS_BH(net, idev, field) \
- _DEVINC(net, icmpv6msg, _BH, idev, field +256)
+ _DEVINCATOMIC(net, icmpv6msg, _BH, idev, field +256)
#define ICMP6MSGIN_INC_STATS_BH(net, idev, field) \
- _DEVINC(net, icmpv6msg, _BH, idev, field)
+ _DEVINCATOMIC(net, icmpv6msg, _BH, idev, field)
struct ip6_ra_chain {
struct ip6_ra_chain *next;
@@ -376,8 +379,8 @@ enum ip6_defrag_users {
struct ip6_create_arg {
__be32 id;
u32 user;
- struct in6_addr *src;
- struct in6_addr *dst;
+ const struct in6_addr *src;
+ const struct in6_addr *dst;
};
void ip6_frag_init(struct inet_frag_queue *q, void *a);
@@ -667,5 +670,4 @@ extern int ipv6_static_sysctl_register(void);
extern void ipv6_static_sysctl_unregister(void);
#endif
-#endif /* __KERNEL__ */
#endif /* _NET_IPV6_H */
diff --git a/include/net/ipx.h b/include/net/ipx.h
index 05d7e4a88b4..c1fec6b464c 100644
--- a/include/net/ipx.h
+++ b/include/net/ipx.h
@@ -80,7 +80,6 @@ struct ipx_route {
atomic_t refcnt;
};
-#ifdef __KERNEL__
struct ipx_cb {
u8 ipx_tctrl;
__be32 ipx_dest_net;
@@ -116,7 +115,6 @@ static inline struct ipx_sock *ipx_sk(struct sock *sk)
}
#define IPX_SKB_CB(__skb) ((struct ipx_cb *)&((__skb)->cb[0]))
-#endif
#define IPX_MIN_EPHEMERAL_SOCKET 0x4000
#define IPX_MAX_EPHEMERAL_SOCKET 0x7fff
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 025d4cc7bbf..8c7189c3f6e 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -537,6 +537,21 @@ struct ieee80211_tx_info {
};
};
+/**
+ * ieee80211_sched_scan_ies - scheduled scan IEs
+ *
+ * This structure is used to pass the appropriate IEs to be used in scheduled
+ * scans for all bands. It contains both the IEs passed from the userspace
+ * and the ones generated by mac80211.
+ *
+ * @ie: array with the IEs for each supported band
+ * @len: array with the total length of the IEs for each band
+ */
+struct ieee80211_sched_scan_ies {
+ u8 *ie[IEEE80211_NUM_BANDS];
+ size_t len[IEEE80211_NUM_BANDS];
+};
+
static inline struct ieee80211_tx_info *IEEE80211_SKB_CB(struct sk_buff *skb)
{
return (struct ieee80211_tx_info *)skb->cb;
@@ -1606,6 +1621,18 @@ enum ieee80211_ampdu_mlme_action {
* you should ensure to cancel it on this callback.
* Must be implemented and can sleep.
*
+ * @suspend: Suspend the device; mac80211 itself will quiesce before and
+ * stop transmitting and doing any other configuration, and then
+ * ask the device to suspend. This is only invoked when WoWLAN is
+ * configured, otherwise the device is deconfigured completely and
+ * reconfigured at resume time.
+ *
+ * @resume: If WoWLAN was configured, this indicates that mac80211 is
+ * now resuming its operation, after this the device must be fully
+ * functional again. If this returns an error, the only way out is
+ * to also unregister the device. If it returns 1, then mac80211
+ * will also go through the regular complete restart on resume.
+ *
* @add_interface: Called when a netdevice attached to the hardware is
* enabled. Because it is not called for monitor mode devices, @start
* and @stop must be implemented.
@@ -1681,6 +1708,13 @@ enum ieee80211_ampdu_mlme_action {
* any error unless this callback returned a negative error code.
* The callback can sleep.
*
+ * @sched_scan_start: Ask the hardware to start scanning repeatedly at
+ * specific intervals. The driver must call the
+ * ieee80211_sched_scan_results() function whenever it finds results.
+ * This process will continue until sched_scan_stop is called.
+ *
+ * @sched_scan_stop: Tell the hardware to stop an ongoing scheduled scan.
+ *
* @sw_scan_start: Notifier function that is called just before a software scan
* is started. Can be NULL, if the driver doesn't need this notification.
* The callback can sleep.
@@ -1819,11 +1853,22 @@ enum ieee80211_ampdu_mlme_action {
* @set_ringparam: Set tx and rx ring sizes.
*
* @get_ringparam: Get tx and rx ring current and maximum sizes.
+ *
+ * @tx_frames_pending: Check if there is any pending frame in the hardware
+ * queues before entering power save.
+ *
+ * @set_bitrate_mask: Set a mask of rates to be used for rate control selection
+ * when transmitting a frame. Currently only legacy rates are handled.
+ * The callback can sleep.
*/
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
int (*start)(struct ieee80211_hw *hw);
void (*stop)(struct ieee80211_hw *hw);
+#ifdef CONFIG_PM
+ int (*suspend)(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan);
+ int (*resume)(struct ieee80211_hw *hw);
+#endif
int (*add_interface)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
int (*change_interface)(struct ieee80211_hw *hw,
@@ -1854,6 +1899,12 @@ struct ieee80211_ops {
u32 iv32, u16 *phase1key);
int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct cfg80211_scan_request *req);
+ int (*sched_scan_start)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct cfg80211_sched_scan_request *req,
+ struct ieee80211_sched_scan_ies *ies);
+ void (*sched_scan_stop)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif);
void (*sw_scan_start)(struct ieee80211_hw *hw);
void (*sw_scan_complete)(struct ieee80211_hw *hw);
int (*get_stats)(struct ieee80211_hw *hw,
@@ -1906,6 +1957,9 @@ struct ieee80211_ops {
int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx);
void (*get_ringparam)(struct ieee80211_hw *hw,
u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
+ bool (*tx_frames_pending)(struct ieee80211_hw *hw);
+ int (*set_bitrate_mask)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ const struct cfg80211_bitrate_mask *mask);
};
/**
@@ -2223,6 +2277,18 @@ static inline int ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta,
#define IEEE80211_TX_STATUS_HEADROOM 13
/**
+ * ieee80211_sta_set_tim - set the TIM bit for a sleeping station
+ *
+ * If a driver buffers frames for a powersave station instead of passing
+ * them back to mac80211 for retransmission, the station needs to be told
+ * to wake up using the TIM bitmap in the beacon.
+ *
+ * This function sets the station's TIM bit - it will be cleared when the
+ * station wakes up.
+ */
+void ieee80211_sta_set_tim(struct ieee80211_sta *sta);
+
+/**
* ieee80211_tx_status - transmit status callback
*
* Call this function for all transmitted frames after they have been
@@ -2276,6 +2342,17 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
struct sk_buff *skb);
/**
+ * ieee80211_report_low_ack - report non-responding station
+ *
+ * When operating in AP-mode, call this function to report a non-responding
+ * connected STA.
+ *
+ * @sta: the non-responding connected sta
+ * @num_packets: number of packets sent to @sta without a response
+ */
+void ieee80211_report_low_ack(struct ieee80211_sta *sta, u32 num_packets);
+
+/**
* ieee80211_beacon_get_tim - beacon generation function
* @hw: pointer obtained from ieee80211_alloc_hw().
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
@@ -2545,6 +2622,28 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw);
void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted);
/**
+ * ieee80211_sched_scan_results - got results from scheduled scan
+ *
+ * When a scheduled scan is running, this function needs to be called by the
+ * driver whenever there are new scan results available.
+ *
+ * @hw: the hardware that is performing scheduled scans
+ */
+void ieee80211_sched_scan_results(struct ieee80211_hw *hw);
+
+/**
+ * ieee80211_sched_scan_stopped - inform that the scheduled scan has stopped
+ *
+ * When a scheduled scan is running, this function can be called by
+ * the driver if it needs to stop the scan to perform another task.
+ * Usual scenarios are drivers that cannot continue the scheduled scan
+ * while associating, for instance.
+ *
+ * @hw: the hardware that is performing scheduled scans
+ */
+void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw);
+
+/**
* ieee80211_iterate_active_interfaces - iterate active interfaces
*
* This function iterates over the interfaces associated with a given
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index e0e594f8e9d..62beeb97c4b 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -42,8 +42,6 @@ enum {
#define ND_REACHABLE_TIME (30*HZ)
#define ND_RETRANS_TIMER HZ
-#ifdef __KERNEL__
-
#include <linux/compiler.h>
#include <linux/icmpv6.h>
#include <linux/in6.h>
@@ -102,7 +100,8 @@ extern void ndisc_send_redirect(struct sk_buff *skb,
struct neighbour *neigh,
const struct in6_addr *target);
-extern int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir);
+extern int ndisc_mc_map(const struct in6_addr *addr, char *buf,
+ struct net_device *dev, int dir);
extern struct sk_buff *ndisc_build_skb(struct net_device *dev,
const struct in6_addr *daddr,
@@ -155,8 +154,4 @@ static inline struct neighbour * ndisc_get_neigh(struct net_device *dev, const s
return ERR_PTR(-ENODEV);
}
-
-#endif /* __KERNEL__ */
-
-
#endif
diff --git a/include/net/netevent.h b/include/net/netevent.h
index 22b239c17ea..086f8a5b59d 100644
--- a/include/net/netevent.h
+++ b/include/net/netevent.h
@@ -10,7 +10,6 @@
*
* Changes:
*/
-#ifdef __KERNEL__
struct dst_entry;
@@ -29,4 +28,3 @@ extern int unregister_netevent_notifier(struct notifier_block *nb);
extern int call_netevent_notifiers(unsigned long val, void *v);
#endif
-#endif
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index d0d13378991..c7c42e7acc3 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -14,7 +14,6 @@
#include <linux/netfilter/nf_conntrack_common.h>
-#ifdef __KERNEL__
#include <linux/bitops.h>
#include <linux/compiler.h>
#include <asm/atomic.h>
@@ -326,5 +325,4 @@ do { \
#define MODULE_ALIAS_NFCT_HELPER(helper) \
MODULE_ALIAS("nfct-helper-" helper)
-#endif /* __KERNEL__ */
#endif /* _NF_CONNTRACK_H */
diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h
index 4ee44c84a30..7ca6bdd5bae 100644
--- a/include/net/netfilter/nf_conntrack_tuple.h
+++ b/include/net/netfilter/nf_conntrack_tuple.h
@@ -104,8 +104,6 @@ struct nf_conntrack_tuple_mask {
} src;
};
-#ifdef __KERNEL__
-
static inline void nf_ct_dump_tuple_ip(const struct nf_conntrack_tuple *t)
{
#ifdef DEBUG
@@ -148,8 +146,6 @@ struct nf_conntrack_tuple_hash {
struct nf_conntrack_tuple tuple;
};
-#endif /* __KERNEL__ */
-
static inline bool __nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1,
const struct nf_conntrack_tuple *t2)
{
diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
index aff80b190c1..0346b007086 100644
--- a/include/net/netfilter/nf_nat.h
+++ b/include/net/netfilter/nf_nat.h
@@ -48,7 +48,6 @@ struct nf_nat_multi_range_compat {
struct nf_nat_range range[1];
};
-#ifdef __KERNEL__
#include <linux/list.h>
#include <linux/netfilter/nf_conntrack_pptp.h>
#include <net/netfilter/nf_conntrack_extend.h>
@@ -93,7 +92,4 @@ static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct)
#endif
}
-#else /* !__KERNEL__: iptables wants this to compile. */
-#define nf_nat_multi_range nf_nat_multi_range_compat
-#endif /*__KERNEL__*/
#endif
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 542195d9469..d786b4fc02a 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -54,6 +54,8 @@ struct netns_ipv4 {
int sysctl_rt_cache_rebuild_count;
int current_rt_cache_rebuild_count;
+ unsigned int sysctl_ping_group_range[2];
+
atomic_t rt_genid;
atomic_t dev_addr_genid;
diff --git a/include/net/phonet/pn_dev.h b/include/net/phonet/pn_dev.h
index 13649eb5741..8639de5750f 100644
--- a/include/net/phonet/pn_dev.h
+++ b/include/net/phonet/pn_dev.h
@@ -51,7 +51,7 @@ void phonet_address_notify(int event, struct net_device *dev, u8 addr);
int phonet_route_add(struct net_device *dev, u8 daddr);
int phonet_route_del(struct net_device *dev, u8 daddr);
void rtm_phonet_notify(int event, struct net_device *dev, u8 dst);
-struct net_device *phonet_route_get(struct net *net, u8 daddr);
+struct net_device *phonet_route_get_rcu(struct net *net, u8 daddr);
struct net_device *phonet_route_output(struct net *net, u8 daddr);
#define PN_NO_ADDR 0xff
diff --git a/include/net/ping.h b/include/net/ping.h
new file mode 100644
index 00000000000..682b5ae9af5
--- /dev/null
+++ b/include/net/ping.h
@@ -0,0 +1,55 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Definitions for the "ping" module.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _PING_H
+#define _PING_H
+
+#include <net/netns/hash.h>
+
+/* PING_HTABLE_SIZE must be power of 2 */
+#define PING_HTABLE_SIZE 64
+#define PING_HTABLE_MASK (PING_HTABLE_SIZE-1)
+
+#define ping_portaddr_for_each_entry(__sk, node, list) \
+ hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node)
+
+/*
+ * gid_t is either uint or ushort. We want to pass it to
+ * proc_dointvec_minmax(), so it must not be larger than MAX_INT
+ */
+#define GID_T_MAX (((gid_t)~0U) >> 1)
+
+struct ping_table {
+ struct hlist_nulls_head hash[PING_HTABLE_SIZE];
+ rwlock_t lock;
+};
+
+struct ping_iter_state {
+ struct seq_net_private p;
+ int bucket;
+};
+
+extern struct proto ping_prot;
+
+
+extern void ping_rcv(struct sk_buff *);
+extern void ping_err(struct sk_buff *, u32 info);
+
+#ifdef CONFIG_PROC_FS
+extern int __init ping_proc_init(void);
+extern void ping_proc_exit(void);
+#endif
+
+void __init ping_init(void);
+
+
+#endif /* _PING_H */
diff --git a/include/net/rawv6.h b/include/net/rawv6.h
index f6b9b830df8..cf757723445 100644
--- a/include/net/rawv6.h
+++ b/include/net/rawv6.h
@@ -1,8 +1,6 @@
#ifndef _NET_RAWV6_H
#define _NET_RAWV6_H
-#ifdef __KERNEL__
-
#include <net/protocol.h>
void raw6_icmp_error(struct sk_buff *, int nexthdr,
@@ -20,5 +18,3 @@ int rawv6_mh_filter_unregister(int (*filter)(struct sock *sock,
#endif
#endif
-
-#endif
diff --git a/include/net/route.h b/include/net/route.h
index 8fce0621cad..db7b3432f07 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -35,16 +35,8 @@
#include <linux/cache.h>
#include <linux/security.h>
-#ifndef __KERNEL__
-#warning This file is not supposed to be used outside of kernel.
-#endif
-
#define RTO_ONLINK 0x01
-#define RTO_CONN 0
-/* RTO_CONN is not used (being alias for 0), but preserved not to break
- * some modules referring to it. */
-
#define RT_CONN_FLAGS(sk) (RT_TOS(inet_sk(sk)->tos) | sock_flag(sk, SOCK_LOCALROUTE))
struct fib_nh;
@@ -60,7 +52,7 @@ struct rtable {
int rt_genid;
unsigned rt_flags;
__u16 rt_type;
- __u8 rt_tos;
+ __u8 rt_key_tos;
__be32 rt_dst; /* Path destination */
__be32 rt_src; /* Path source */
@@ -123,7 +115,7 @@ extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
__be32 src, struct net_device *dev);
extern void rt_cache_flush(struct net *net, int how);
extern void rt_cache_flush_batch(struct net *net);
-extern struct rtable *__ip_route_output_key(struct net *, const struct flowi4 *flp);
+extern struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp);
extern struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
struct sock *sk);
extern struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig);
@@ -145,40 +137,33 @@ static inline struct rtable *ip_route_output(struct net *net, __be32 daddr,
return ip_route_output_key(net, &fl4);
}
-static inline struct rtable *ip_route_output_ports(struct net *net, struct sock *sk,
+static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi4 *fl4,
+ struct sock *sk,
__be32 daddr, __be32 saddr,
__be16 dport, __be16 sport,
__u8 proto, __u8 tos, int oif)
{
- struct flowi4 fl4 = {
- .flowi4_oif = oif,
- .flowi4_flags = sk ? inet_sk_flowi_flags(sk) : 0,
- .flowi4_mark = sk ? sk->sk_mark : 0,
- .daddr = daddr,
- .saddr = saddr,
- .flowi4_tos = tos,
- .flowi4_proto = proto,
- .fl4_dport = dport,
- .fl4_sport = sport,
- };
+ flowi4_init_output(fl4, oif, sk ? sk->sk_mark : 0, tos,
+ RT_SCOPE_UNIVERSE, proto,
+ sk ? inet_sk_flowi_flags(sk) : 0,
+ daddr, saddr, dport, sport);
if (sk)
- security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
- return ip_route_output_flow(net, &fl4, sk);
+ security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
+ return ip_route_output_flow(net, fl4, sk);
}
-static inline struct rtable *ip_route_output_gre(struct net *net,
+static inline struct rtable *ip_route_output_gre(struct net *net, struct flowi4 *fl4,
__be32 daddr, __be32 saddr,
__be32 gre_key, __u8 tos, int oif)
{
- struct flowi4 fl4 = {
- .flowi4_oif = oif,
- .daddr = daddr,
- .saddr = saddr,
- .flowi4_tos = tos,
- .flowi4_proto = IPPROTO_GRE,
- .fl4_gre_key = gre_key,
- };
- return ip_route_output_key(net, &fl4);
+ memset(fl4, 0, sizeof(*fl4));
+ fl4->flowi4_oif = oif;
+ fl4->daddr = daddr;
+ fl4->saddr = saddr;
+ fl4->flowi4_tos = tos;
+ fl4->flowi4_proto = IPPROTO_GRE;
+ fl4->fl4_gre_key = gre_key;
+ return ip_route_output_key(net, fl4);
}
extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src,
@@ -196,14 +181,15 @@ static inline int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 s
return ip_route_input_common(skb, dst, src, tos, devin, true);
}
-extern unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, unsigned short new_mtu, struct net_device *dev);
+extern unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph,
+ unsigned short new_mtu, struct net_device *dev);
extern void ip_rt_send_redirect(struct sk_buff *skb);
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(struct net *, unsigned int cmd, void __user *arg);
-extern void ip_rt_get_source(u8 *src, struct rtable *rt);
+extern void ip_rt_get_source(u8 *src, struct sk_buff *skb, struct rtable *rt);
extern int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb);
struct in_ifaddr;
@@ -225,78 +211,93 @@ static inline char rt_tos2priority(u8 tos)
return ip_tos2prio[IPTOS_TOS(tos)>>1];
}
-static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos,
+/* ip_route_connect() and ip_route_newports() work in tandem whilst
+ * binding a socket for a new outgoing connection.
+ *
+ * In order to use IPSEC properly, we must, in the end, have a
+ * route that was looked up using all available keys including source
+ * and destination ports.
+ *
+ * However, if a source port needs to be allocated (the user specified
+ * a wildcard source port) we need to obtain addressing information
+ * in order to perform that allocation.
+ *
+ * So ip_route_connect() looks up a route using wildcarded source and
+ * destination ports in the key, simply so that we can get a pair of
+ * addresses to use for port allocation.
+ *
+ * Later, once the ports are allocated, ip_route_newports() will make
+ * another route lookup if needed to make sure we catch any IPSEC
+ * rules keyed on the port information.
+ *
+ * The callers allocate the flow key on their stack, and must pass in
+ * the same flowi4 object to both the ip_route_connect() and the
+ * ip_route_newports() calls.
+ */
+
+static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32 src,
+ u32 tos, int oif, u8 protocol,
+ __be16 sport, __be16 dport,
+ struct sock *sk, bool can_sleep)
+{
+ __u8 flow_flags = 0;
+
+ if (inet_sk(sk)->transparent)
+ flow_flags |= FLOWI_FLAG_ANYSRC;
+ if (protocol == IPPROTO_TCP)
+ flow_flags |= FLOWI_FLAG_PRECOW_METRICS;
+ if (can_sleep)
+ flow_flags |= FLOWI_FLAG_CAN_SLEEP;
+
+ flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE,
+ protocol, flow_flags, dst, src, dport, sport);
+}
+
+static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
+ __be32 dst, __be32 src, u32 tos,
int oif, u8 protocol,
__be16 sport, __be16 dport,
struct sock *sk, bool can_sleep)
{
- struct flowi4 fl4 = {
- .flowi4_oif = oif,
- .flowi4_mark = sk->sk_mark,
- .daddr = dst,
- .saddr = src,
- .flowi4_tos = tos,
- .flowi4_proto = protocol,
- .fl4_sport = sport,
- .fl4_dport = dport,
- };
struct net *net = sock_net(sk);
struct rtable *rt;
- if (inet_sk(sk)->transparent)
- fl4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
- if (protocol == IPPROTO_TCP)
- fl4.flowi4_flags |= FLOWI_FLAG_PRECOW_METRICS;
- if (can_sleep)
- fl4.flowi4_flags |= FLOWI_FLAG_CAN_SLEEP;
+ ip_route_connect_init(fl4, dst, src, tos, oif, protocol,
+ sport, dport, sk, can_sleep);
if (!dst || !src) {
- rt = __ip_route_output_key(net, &fl4);
+ rt = __ip_route_output_key(net, fl4);
if (IS_ERR(rt))
return rt;
- fl4.daddr = rt->rt_dst;
- fl4.saddr = rt->rt_src;
ip_rt_put(rt);
}
- security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
- return ip_route_output_flow(net, &fl4, sk);
+ security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
+ return ip_route_output_flow(net, fl4, sk);
}
-static inline struct rtable *ip_route_newports(struct rtable *rt,
- u8 protocol, __be16 orig_sport,
- __be16 orig_dport, __be16 sport,
- __be16 dport, struct sock *sk)
+static inline struct rtable *ip_route_newports(struct flowi4 *fl4, struct rtable *rt,
+ __be16 orig_sport, __be16 orig_dport,
+ __be16 sport, __be16 dport,
+ struct sock *sk)
{
if (sport != orig_sport || dport != orig_dport) {
- struct flowi4 fl4 = {
- .flowi4_oif = rt->rt_oif,
- .flowi4_mark = rt->rt_mark,
- .daddr = rt->rt_dst,
- .saddr = rt->rt_src,
- .flowi4_tos = rt->rt_tos,
- .flowi4_proto = protocol,
- .fl4_sport = sport,
- .fl4_dport = dport
- };
- if (inet_sk(sk)->transparent)
- fl4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
- if (protocol == IPPROTO_TCP)
- fl4.flowi4_flags |= FLOWI_FLAG_PRECOW_METRICS;
+ fl4->fl4_dport = dport;
+ fl4->fl4_sport = sport;
ip_rt_put(rt);
- security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
- return ip_route_output_flow(sock_net(sk), &fl4, sk);
+ security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
+ return ip_route_output_flow(sock_net(sk), fl4, sk);
}
return rt;
}
-extern void rt_bind_peer(struct rtable *rt, int create);
+extern void rt_bind_peer(struct rtable *rt, __be32 daddr, int create);
-static inline struct inet_peer *rt_get_peer(struct rtable *rt)
+static inline struct inet_peer *rt_get_peer(struct rtable *rt, __be32 daddr)
{
if (rt->peer)
return rt->peer;
- rt_bind_peer(rt, 0);
+ rt_bind_peer(rt, daddr, 0);
return rt->peer;
}
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
index c01dc99def0..2b447646ce4 100644
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -73,7 +73,6 @@ typedef enum {
SCTP_CMD_INIT_FAILED, /* High level, do init failure work. */
SCTP_CMD_REPORT_DUP, /* Report a duplicate TSN. */
SCTP_CMD_STRIKE, /* Mark a strike against a transport. */
- SCTP_CMD_TRANSMIT, /* Transmit the outqueue. */
SCTP_CMD_HB_TIMERS_START, /* Start the heartbeat timers. */
SCTP_CMD_HB_TIMER_UPDATE, /* Update a heartbeat timers. */
SCTP_CMD_HB_TIMERS_STOP, /* Stop the heartbeat timers. */
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index c70d8ccc55c..942b864f613 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -150,7 +150,6 @@ SCTP_SUBTYPE_CONSTRUCTOR(OTHER, sctp_event_other_t, other)
SCTP_SUBTYPE_CONSTRUCTOR(PRIMITIVE, sctp_event_primitive_t, primitive)
-#define sctp_chunk_is_control(a) (a->chunk_hdr->type != SCTP_CID_DATA)
#define sctp_chunk_is_data(a) (a->chunk_hdr->type == SCTP_CID_DATA)
/* Calculate the actual data size in a data chunk */
@@ -188,15 +187,14 @@ typedef enum {
/* SCTP state defines for internal state machine */
typedef enum {
- SCTP_STATE_EMPTY = 0,
- SCTP_STATE_CLOSED = 1,
- SCTP_STATE_COOKIE_WAIT = 2,
- SCTP_STATE_COOKIE_ECHOED = 3,
- SCTP_STATE_ESTABLISHED = 4,
- SCTP_STATE_SHUTDOWN_PENDING = 5,
- SCTP_STATE_SHUTDOWN_SENT = 6,
- SCTP_STATE_SHUTDOWN_RECEIVED = 7,
- SCTP_STATE_SHUTDOWN_ACK_SENT = 8,
+ SCTP_STATE_CLOSED = 0,
+ SCTP_STATE_COOKIE_WAIT = 1,
+ SCTP_STATE_COOKIE_ECHOED = 2,
+ SCTP_STATE_ESTABLISHED = 3,
+ SCTP_STATE_SHUTDOWN_PENDING = 4,
+ SCTP_STATE_SHUTDOWN_SENT = 5,
+ SCTP_STATE_SHUTDOWN_RECEIVED = 6,
+ SCTP_STATE_SHUTDOWN_ACK_SENT = 7,
} sctp_state_t;
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 01e094c6d0a..b2c2366676a 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -530,7 +530,6 @@ _sctp_walk_params((pos), (chunk), ntohs((chunk)->chunk_hdr.length), member)
#define _sctp_walk_params(pos, chunk, end, member)\
for (pos.v = chunk->member;\
- pos.v <= (void *)chunk + end - sizeof(sctp_paramhdr_t) &&\
pos.v <= (void *)chunk + end - ntohs(pos.p->length) &&\
ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\
pos.v += WORD_ROUND(ntohs(pos.p->length)))
@@ -541,7 +540,6 @@ _sctp_walk_errors((err), (chunk_hdr), ntohs((chunk_hdr)->length))
#define _sctp_walk_errors(err, chunk_hdr, end)\
for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
sizeof(sctp_chunkhdr_t));\
- (void *)err <= (void *)chunk_hdr + end - sizeof(sctp_errhdr_t) &&\
(void *)err <= (void *)chunk_hdr + end - ntohs(err->length) &&\
ntohs(err->length) >= sizeof(sctp_errhdr_t); \
err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length))))
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 9352d12f02d..9148632b820 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -165,6 +165,7 @@ sctp_state_fn_t sctp_sf_do_prm_requestheartbeat;
sctp_state_fn_t sctp_sf_do_prm_asconf;
/* Prototypes for other event state functions. */
+sctp_state_fn_t sctp_sf_do_no_pending_tsn;
sctp_state_fn_t sctp_sf_do_9_2_start_shutdown;
sctp_state_fn_t sctp_sf_do_9_2_shutdown_ack;
sctp_state_fn_t sctp_sf_ignore_other;
@@ -232,9 +233,7 @@ struct sctp_chunk *sctp_make_violation_paramlen(const struct sctp_association *,
const struct sctp_chunk *,
struct sctp_paramhdr *);
struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *,
- const struct sctp_transport *,
- const void *payload,
- const size_t paylen);
+ const struct sctp_transport *);
struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *,
const struct sctp_chunk *,
const void *payload,
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 0f6e60a9c30..795f4886e11 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -564,19 +564,15 @@ struct sctp_af {
int optname,
char __user *optval,
int __user *optlen);
- struct dst_entry *(*get_dst) (struct sctp_association *asoc,
- union sctp_addr *daddr,
- union sctp_addr *saddr);
+ void (*get_dst) (struct sctp_transport *t,
+ union sctp_addr *saddr,
+ struct flowi *fl,
+ struct sock *sk);
void (*get_saddr) (struct sctp_sock *sk,
- struct sctp_association *asoc,
- struct dst_entry *dst,
- union sctp_addr *daddr,
- union sctp_addr *saddr);
+ struct sctp_transport *t,
+ struct flowi *fl);
void (*copy_addrlist) (struct list_head *,
struct net_device *);
- void (*dst_saddr) (union sctp_addr *saddr,
- struct dst_entry *dst,
- __be16 port);
int (*cmp_addr) (const union sctp_addr *addr1,
const union sctp_addr *addr2);
void (*addr_copy) (union sctp_addr *dst,
@@ -898,6 +894,7 @@ struct sctp_transport {
/* Is this structure kfree()able? */
malloced:1;
+ struct flowi fl;
/* This is the peer's IP address and port. */
union sctp_addr ipaddr;
@@ -1061,7 +1058,7 @@ void sctp_transport_set_owner(struct sctp_transport *,
struct sctp_association *);
void sctp_transport_route(struct sctp_transport *, union sctp_addr *,
struct sctp_sock *);
-void sctp_transport_pmtu(struct sctp_transport *);
+void sctp_transport_pmtu(struct sctp_transport *, struct sock *sk);
void sctp_transport_free(struct sctp_transport *);
void sctp_transport_reset_timers(struct sctp_transport *);
void sctp_transport_hold(struct sctp_transport *);
@@ -1400,7 +1397,7 @@ int sctp_has_association(const union sctp_addr *laddr,
int sctp_verify_init(const struct sctp_association *asoc, sctp_cid_t,
sctp_init_chunk_t *peer_init, struct sctp_chunk *chunk,
struct sctp_chunk **err_chunk);
-int sctp_process_init(struct sctp_association *, sctp_cid_t cid,
+int sctp_process_init(struct sctp_association *, struct sctp_chunk *chunk,
const union sctp_addr *peer,
sctp_init_chunk_t *init, gfp_t gfp);
__u32 sctp_generate_tag(const struct sctp_endpoint *);
diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
index 7ea12e8e667..99b027b2adc 100644
--- a/include/net/sctp/ulpevent.h
+++ b/include/net/sctp/ulpevent.h
@@ -132,6 +132,9 @@ struct sctp_ulpevent *sctp_ulpevent_make_authkey(
const struct sctp_association *asoc, __u16 key_id,
__u32 indication, gfp_t gfp);
+struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event(
+ const struct sctp_association *asoc, gfp_t gfp);
+
void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
struct msghdr *);
__u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event);
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index e73ebdae323..32fd5127403 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -91,6 +91,7 @@ typedef __s32 sctp_assoc_t;
#define SCTP_PEER_AUTH_CHUNKS 26 /* Read only */
#define SCTP_LOCAL_AUTH_CHUNKS 27 /* Read only */
#define SCTP_GET_ASSOC_NUMBER 28 /* Read only */
+#define SCTP_GET_ASSOC_ID_LIST 29 /* Read only */
/* Internal Socket Options. Some of the sctp library functions are
* implemented using these socket options.
@@ -353,6 +354,20 @@ struct sctp_authkey_event {
enum { SCTP_AUTH_NEWKEY = 0, };
+/*
+ * 6.1.9. SCTP_SENDER_DRY_EVENT
+ *
+ * When the SCTP stack has no more user data to send or retransmit, this
+ * notification is given to the user. Also, at the time when a user app
+ * subscribes to this event, if there is no data to be sent or
+ * retransmit, the stack will immediately send up this notification.
+ */
+struct sctp_sender_dry_event {
+ __u16 sender_dry_type;
+ __u16 sender_dry_flags;
+ __u32 sender_dry_length;
+ sctp_assoc_t sender_dry_assoc_id;
+};
/*
* Described in Section 7.3
@@ -368,6 +383,7 @@ struct sctp_event_subscribe {
__u8 sctp_partial_delivery_event;
__u8 sctp_adaptation_layer_event;
__u8 sctp_authentication_event;
+ __u8 sctp_sender_dry_event;
};
/*
@@ -391,6 +407,7 @@ union sctp_notification {
struct sctp_adaptation_event sn_adaptation_event;
struct sctp_pdapi_event sn_pdapi_event;
struct sctp_authkey_event sn_authkey_event;
+ struct sctp_sender_dry_event sn_sender_dry_event;
};
/* Section 5.3.1
@@ -407,7 +424,9 @@ enum sctp_sn_type {
SCTP_SHUTDOWN_EVENT,
SCTP_PARTIAL_DELIVERY_EVENT,
SCTP_ADAPTATION_INDICATION,
- SCTP_AUTHENTICATION_INDICATION,
+ SCTP_AUTHENTICATION_EVENT,
+#define SCTP_AUTHENTICATION_INDICATION SCTP_AUTHENTICATION_EVENT
+ SCTP_SENDER_DRY_EVENT,
};
/* Notification error codes used to fill up the error fields in some
@@ -669,6 +688,18 @@ struct sctp_authchunks {
};
/*
+ * 8.2.6. Get the Current Identifiers of Associations
+ * (SCTP_GET_ASSOC_ID_LIST)
+ *
+ * This option gets the current list of SCTP association identifiers of
+ * the SCTP associations handled by a one-to-many style socket.
+ */
+struct sctp_assoc_ids {
+ __u32 gaids_number_of_ids;
+ sctp_assoc_t gaids_assoc_id[];
+};
+
+/*
* 8.3, 8.5 get all peer/local addresses in an association.
* This parameter struct is used by SCTP_GET_PEER_ADDRS and
* SCTP_GET_LOCAL_ADDRS socket options used internally to implement
diff --git a/include/net/snmp.h b/include/net/snmp.h
index 27461d6dd46..479083a78b0 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -72,14 +72,24 @@ struct icmpmsg_mib {
/* ICMP6 (IPv6-ICMP) */
#define ICMP6_MIB_MAX __ICMP6_MIB_MAX
+/* per network ns counters */
struct icmpv6_mib {
unsigned long mibs[ICMP6_MIB_MAX];
};
+/* per device counters, (shared on all cpus) */
+struct icmpv6_mib_device {
+ atomic_long_t mibs[ICMP6_MIB_MAX];
+};
#define ICMP6MSG_MIB_MAX __ICMP6MSG_MIB_MAX
+/* per network ns counters */
struct icmpv6msg_mib {
unsigned long mibs[ICMP6MSG_MIB_MAX];
};
+/* per device counters, (shared on all cpus) */
+struct icmpv6msg_mib_device {
+ atomic_long_t mibs[ICMP6MSG_MIB_MAX];
+};
/* TCP */
@@ -114,6 +124,8 @@ struct linux_xfrm_mib {
*/
#define DEFINE_SNMP_STAT(type, name) \
__typeof__(type) __percpu *name[2]
+#define DEFINE_SNMP_STAT_ATOMIC(type, name) \
+ __typeof__(type) *name
#define DECLARE_SNMP_STAT(type, name) \
extern __typeof__(type) __percpu *name[2]
@@ -124,6 +136,8 @@ struct linux_xfrm_mib {
__this_cpu_inc(mib[0]->mibs[field])
#define SNMP_INC_STATS_USER(mib, field) \
this_cpu_inc(mib[1]->mibs[field])
+#define SNMP_INC_STATS_ATOMIC_LONG(mib, field) \
+ atomic_long_inc(&mib->mibs[field])
#define SNMP_INC_STATS(mib, field) \
this_cpu_inc(mib[!in_softirq()]->mibs[field])
#define SNMP_DEC_STATS(mib, field) \
diff --git a/include/net/sock.h b/include/net/sock.h
index 01810a3f19d..f2046e404a6 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -52,6 +52,7 @@
#include <linux/mm.h>
#include <linux/security.h>
#include <linux/slab.h>
+#include <linux/uaccess.h>
#include <linux/filter.h>
#include <linux/rculist_nulls.h>
@@ -1389,6 +1390,59 @@ static inline void sk_nocaps_add(struct sock *sk, int flags)
sk->sk_route_caps &= ~flags;
}
+static inline int skb_do_copy_data_nocache(struct sock *sk, struct sk_buff *skb,
+ char __user *from, char *to,
+ int copy, int offset)
+{
+ if (skb->ip_summed == CHECKSUM_NONE) {
+ int err = 0;
+ __wsum csum = csum_and_copy_from_user(from, to, copy, 0, &err);
+ if (err)
+ return err;
+ skb->csum = csum_block_add(skb->csum, csum, offset);
+ } else if (sk->sk_route_caps & NETIF_F_NOCACHE_COPY) {
+ if (!access_ok(VERIFY_READ, from, copy) ||
+ __copy_from_user_nocache(to, from, copy))
+ return -EFAULT;
+ } else if (copy_from_user(to, from, copy))
+ return -EFAULT;
+
+ return 0;
+}
+
+static inline int skb_add_data_nocache(struct sock *sk, struct sk_buff *skb,
+ char __user *from, int copy)
+{
+ int err, offset = skb->len;
+
+ err = skb_do_copy_data_nocache(sk, skb, from, skb_put(skb, copy),
+ copy, offset);
+ if (err)
+ __skb_trim(skb, offset);
+
+ return err;
+}
+
+static inline int skb_copy_to_page_nocache(struct sock *sk, char __user *from,
+ struct sk_buff *skb,
+ struct page *page,
+ int off, int copy)
+{
+ int err;
+
+ err = skb_do_copy_data_nocache(sk, skb, from, page_address(page) + off,
+ copy, skb->len);
+ if (err)
+ return err;
+
+ skb->len += copy;
+ skb->data_len += copy;
+ skb->truesize += copy;
+ sk->sk_wmem_queued += copy;
+ sk_mem_charge(sk, copy);
+ return 0;
+}
+
static inline int skb_copy_to_page(struct sock *sk, char __user *from,
struct sk_buff *skb, struct page *page,
int off, int copy)
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index a8122dc5641..5271a741c3a 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -7,8 +7,6 @@
* IPv6 transport protocols
*/
-#ifdef __KERNEL__
-
extern struct proto rawv6_prot;
extern struct proto udpv6_prot;
extern struct proto udplitev6_prot;
@@ -57,5 +55,3 @@ extern const struct inet_connection_sock_af_ops ipv4_specific;
extern void inet6_destroy_sock(struct sock *sk);
#endif
-
-#endif
diff --git a/include/net/wimax.h b/include/net/wimax.h
index c799ba7b708..7328d5019d8 100644
--- a/include/net/wimax.h
+++ b/include/net/wimax.h
@@ -250,7 +250,6 @@
#ifndef __NET__WIMAX_H__
#define __NET__WIMAX_H__
-#ifdef __KERNEL__
#include <linux/wimax.h>
#include <net/genetlink.h>
@@ -518,8 +517,4 @@ extern ssize_t wimax_msg_len(struct sk_buff *);
extern int wimax_rfkill(struct wimax_dev *, enum wimax_rf_state);
extern int wimax_reset(struct wimax_dev *);
-#else
-/* You might be looking for linux/wimax.h */
-#error This file should not be included from user space.
-#endif /* #ifdef __KERNEL__ */
#endif /* #ifndef __NET__WIMAX_H__ */
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 20afeaa3939..b203e14d26b 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -958,6 +958,15 @@ struct sec_path {
struct xfrm_state *xvec[XFRM_MAX_DEPTH];
};
+static inline int secpath_exists(struct sk_buff *skb)
+{
+#ifdef CONFIG_XFRM
+ return skb->sp != NULL;
+#else
+ return 0;
+#endif
+}
+
static inline struct sec_path *
secpath_get(struct sec_path *sp)
{
@@ -1468,7 +1477,7 @@ extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family);
extern __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr);
-extern __be32 xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr);
+extern __be32 xfrm6_tunnel_spi_lookup(struct net *net, const 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);
@@ -1563,8 +1572,8 @@ static inline int xfrm_addr_cmp(const xfrm_address_t *a,
case AF_INET:
return (__force u32)a->a4 - (__force u32)b->a4;
case AF_INET6:
- return ipv6_addr_cmp((struct in6_addr *)a,
- (struct in6_addr *)b);
+ return ipv6_addr_cmp((const struct in6_addr *)a,
+ (const struct in6_addr *)b);
}
}
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index b5fc9f39122..ae8c68f30f1 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -217,18 +217,19 @@ static inline enum ib_mtu iboe_get_mtu(int mtu)
static inline int iboe_get_rate(struct net_device *dev)
{
struct ethtool_cmd cmd;
+ u32 speed;
- if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings ||
- dev->ethtool_ops->get_settings(dev, &cmd))
+ if (dev_ethtool_get_settings(dev, &cmd))
return IB_RATE_PORT_CURRENT;
- if (cmd.speed >= 40000)
+ speed = ethtool_cmd_speed(&cmd);
+ if (speed >= 40000)
return IB_RATE_40_GBPS;
- else if (cmd.speed >= 30000)
+ else if (speed >= 30000)
return IB_RATE_30_GBPS;
- else if (cmd.speed >= 20000)
+ else if (speed >= 20000)
return IB_RATE_20_GBPS;
- else if (cmd.speed >= 10000)
+ else if (speed >= 10000)
return IB_RATE_10_GBPS;
else
return IB_RATE_PORT_CURRENT;
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 25cc41cd8f3..97e966f171c 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -46,7 +46,9 @@ cond_syscall(sys_getsockopt);
cond_syscall(compat_sys_getsockopt);
cond_syscall(sys_shutdown);
cond_syscall(sys_sendmsg);
+cond_syscall(sys_sendmmsg);
cond_syscall(compat_sys_sendmsg);
+cond_syscall(compat_sys_sendmmsg);
cond_syscall(sys_recvmsg);
cond_syscall(sys_recvmmsg);
cond_syscall(compat_sys_recvmsg);
diff --git a/net/802/garp.c b/net/802/garp.c
index c1df2dad8c6..f8300a8b5fb 100644
--- a/net/802/garp.c
+++ b/net/802/garp.c
@@ -544,6 +544,11 @@ static int garp_init_port(struct net_device *dev)
return 0;
}
+static void garp_kfree_rcu(struct rcu_head *head)
+{
+ kfree(container_of(head, struct garp_port, rcu));
+}
+
static void garp_release_port(struct net_device *dev)
{
struct garp_port *port = rtnl_dereference(dev->garp_port);
@@ -554,8 +559,7 @@ static void garp_release_port(struct net_device *dev)
return;
}
rcu_assign_pointer(dev->garp_port, NULL);
- synchronize_rcu();
- kfree(port);
+ call_rcu(&port->rcu, garp_kfree_rcu);
}
int garp_init_applicant(struct net_device *dev, struct garp_application *appl)
@@ -599,6 +603,11 @@ err1:
}
EXPORT_SYMBOL_GPL(garp_init_applicant);
+static void garp_app_kfree_rcu(struct rcu_head *head)
+{
+ kfree(container_of(head, struct garp_applicant, rcu));
+}
+
void garp_uninit_applicant(struct net_device *dev, struct garp_application *appl)
{
struct garp_port *port = rtnl_dereference(dev->garp_port);
@@ -607,7 +616,6 @@ void garp_uninit_applicant(struct net_device *dev, struct garp_application *appl
ASSERT_RTNL();
rcu_assign_pointer(port->applicants[appl->type], NULL);
- synchronize_rcu();
/* Delete timer and generate a final TRANSMIT_PDU event to flush out
* all pending messages before the applicant is gone. */
@@ -617,7 +625,7 @@ void garp_uninit_applicant(struct net_device *dev, struct garp_application *appl
garp_queue_xmit(app);
dev_mc_del(dev, appl->proto.group_address);
- kfree(app);
+ call_rcu(&app->rcu, garp_app_kfree_rcu);
garp_release_port(dev);
}
EXPORT_SYMBOL_GPL(garp_uninit_applicant);
@@ -635,3 +643,9 @@ void garp_unregister_application(struct garp_application *appl)
stp_proto_unregister(&appl->proto);
}
EXPORT_SYMBOL_GPL(garp_unregister_application);
+
+static void __exit garp_cleanup_module(void)
+{
+ rcu_barrier(); /* Wait for completion of call_rcu()'s */
+}
+module_exit(garp_cleanup_module);
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 0eb1a886b37..b2274d1fd60 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -49,11 +49,6 @@ const char vlan_version[] = DRV_VERSION;
static const char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>";
static const char vlan_buggyright[] = "David S. Miller <davem@redhat.com>";
-static struct packet_type vlan_packet_type __read_mostly = {
- .type = cpu_to_be16(ETH_P_8021Q),
- .func = vlan_skb_recv, /* VLAN receive method */
-};
-
/* End of global variables definitions. */
static void vlan_group_free(struct vlan_group *grp)
@@ -128,9 +123,10 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
vlan_gvrp_request_leave(dev);
vlan_group_set_device(grp, vlan_id, NULL);
- if (!grp->killall)
- synchronize_net();
-
+ /* Because unregister_netdevice_queue() makes sure at least one rcu
+ * grace period is respected before device freeing,
+ * we dont need to call synchronize_net() here.
+ */
unregister_netdevice_queue(dev, head);
/* If the group is now empty, kill off the group. */
@@ -330,10 +326,6 @@ static void vlan_sync_address(struct net_device *dev,
static void vlan_transfer_features(struct net_device *dev,
struct net_device *vlandev)
{
- u32 old_features = vlandev->features;
-
- vlandev->features &= ~dev->vlan_features;
- vlandev->features |= dev->features & dev->vlan_features;
vlandev->gso_max_size = dev->gso_max_size;
if (dev->features & NETIF_F_HW_VLAN_TX)
@@ -344,8 +336,8 @@ static void vlan_transfer_features(struct net_device *dev,
#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid;
#endif
- if (old_features != vlandev->features)
- netdev_features_change(vlandev);
+
+ netdev_update_features(vlandev);
}
static void __vlan_device_event(struct net_device *dev, unsigned long event)
@@ -490,9 +482,6 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
if (dev->reg_state != NETREG_UNREGISTERING)
break;
- /* Delete all VLANs for this dev. */
- grp->killall = 1;
-
for (i = 0; i < VLAN_N_VID; i++) {
vlandev = vlan_group_get_device(grp, i);
if (!vlandev)
@@ -511,6 +500,18 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
case NETDEV_PRE_TYPE_CHANGE:
/* Forbid underlaying device to change its type. */
return NOTIFY_BAD;
+
+ case NETDEV_NOTIFY_PEERS:
+ case NETDEV_BONDING_FAILOVER:
+ /* Propagate to vlan devices */
+ for (i = 0; i < VLAN_N_VID; i++) {
+ vlandev = vlan_group_get_device(grp, i);
+ if (!vlandev)
+ continue;
+
+ call_netdevice_notifiers(event, vlandev);
+ }
+ break;
}
out:
@@ -691,7 +692,6 @@ static int __init vlan_proto_init(void)
if (err < 0)
goto err4;
- dev_add_pack(&vlan_packet_type);
vlan_ioctl_set(vlan_ioctl_handler);
return 0;
@@ -712,8 +712,6 @@ static void __exit vlan_cleanup_module(void)
unregister_netdevice_notifier(&vlan_notifier_block);
- dev_remove_pack(&vlan_packet_type);
-
unregister_pernet_subsys(&vlan_net_ops);
rcu_barrier(); /* Wait for completion of call_rcu()'s */
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
index 5687c9b95f3..c3408def8a1 100644
--- a/net/8021q/vlan.h
+++ b/net/8021q/vlan.h
@@ -75,8 +75,6 @@ static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev)
}
/* found in vlan_dev.c */
-int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
- struct packet_type *ptype, struct net_device *orig_dev);
void vlan_dev_set_ingress_priority(const struct net_device *dev,
u32 skb_prio, u16 vlan_prio);
int vlan_dev_set_egress_priority(const struct net_device *dev,
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index ce8e3ab3e7a..41495dc2a4c 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -4,7 +4,7 @@
#include <linux/netpoll.h>
#include "vlan.h"
-bool vlan_hwaccel_do_receive(struct sk_buff **skbp)
+bool vlan_do_receive(struct sk_buff **skbp)
{
struct sk_buff *skb = *skbp;
u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK;
@@ -88,3 +88,86 @@ gro_result_t vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
return napi_gro_frags(napi);
}
EXPORT_SYMBOL(vlan_gro_frags);
+
+static struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
+{
+ if (vlan_dev_info(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) {
+ if (skb_cow(skb, skb_headroom(skb)) < 0)
+ skb = NULL;
+ if (skb) {
+ /* Lifted from Gleb's VLAN code... */
+ memmove(skb->data - ETH_HLEN,
+ skb->data - VLAN_ETH_HLEN, 12);
+ skb->mac_header += VLAN_HLEN;
+ }
+ }
+ return skb;
+}
+
+static 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);
+}
+
+struct sk_buff *vlan_untag(struct sk_buff *skb)
+{
+ struct vlan_hdr *vhdr;
+ u16 vlan_tci;
+
+ if (unlikely(vlan_tx_tag_present(skb))) {
+ /* vlan_tci is already set-up so leave this for another time */
+ return skb;
+ }
+
+ skb = skb_share_check(skb, GFP_ATOMIC);
+ if (unlikely(!skb))
+ goto err_free;
+
+ if (unlikely(!pskb_may_pull(skb, VLAN_HLEN)))
+ goto err_free;
+
+ vhdr = (struct vlan_hdr *) skb->data;
+ vlan_tci = ntohs(vhdr->h_vlan_TCI);
+ __vlan_hwaccel_put_tag(skb, vlan_tci);
+
+ skb_pull_rcsum(skb, VLAN_HLEN);
+ vlan_set_encap_proto(skb, vhdr);
+
+ skb = vlan_check_reorder_header(skb);
+ if (unlikely(!skb))
+ goto err_free;
+
+ return skb;
+
+err_free:
+ kfree_skb(skb);
+ return NULL;
+}
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index b2ff6c8d360..f247f5bff88 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -65,179 +65,6 @@ static int vlan_dev_rebuild_header(struct sk_buff *skb)
return 0;
}
-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 (skb_cow(skb, skb_headroom(skb)) < 0)
- skb = NULL;
- if (skb) {
- /* Lifted from Gleb's VLAN code... */
- memmove(skb->data - ETH_HLEN,
- skb->data - VLAN_ETH_HLEN, 12);
- skb->mac_header += VLAN_HLEN;
- }
- }
-
- 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.
- * This is normal practice and works for any 'now in use' protocol.
- *
- * Also, at this point we assume that we ARE dealing exclusively with
- * VLAN packets, or packets that should be made into VLAN packets based
- * on a default VLAN ID.
- *
- * NOTE: Should be similar to ethernet/eth.c.
- *
- * SANITY NOTE: This method is called when a packet is moving up the stack
- * towards userland. To get here, it would have already passed
- * through the ethernet/eth.c eth_type_trans() method.
- * 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
- *
- */
-int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
- struct packet_type *ptype, struct net_device *orig_dev)
-{
- struct vlan_hdr *vhdr;
- struct vlan_pcpu_stats *rx_stats;
- struct net_device *vlan_dev;
- u16 vlan_id;
- u16 vlan_tci;
-
- skb = skb_share_check(skb, GFP_ATOMIC);
- if (skb == NULL)
- goto err_free;
-
- if (unlikely(!pskb_may_pull(skb, VLAN_HLEN)))
- goto err_free;
-
- vhdr = (struct vlan_hdr *)skb->data;
- vlan_tci = ntohs(vhdr->h_vlan_TCI);
- vlan_id = vlan_tci & VLAN_VID_MASK;
-
- rcu_read_lock();
- vlan_dev = vlan_find_dev(dev, vlan_id);
-
- /* If the VLAN device is defined, we use it.
- * If not, and the VID is 0, it is a 802.1p packet (not
- * really a VLAN), so we will just netif_rx it later to the
- * original interface, but with the skb->proto set to the
- * wrapped proto: we do nothing here.
- */
-
- if (!vlan_dev) {
- if (vlan_id) {
- pr_debug("%s: ERROR: No net_device for VID: %u on dev: %s\n",
- __func__, vlan_id, dev->name);
- goto err_unlock;
- }
- rx_stats = NULL;
- } else {
- skb->dev = vlan_dev;
-
- rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_pcpu_stats);
-
- u64_stats_update_begin(&rx_stats->syncp);
- rx_stats->rx_packets++;
- rx_stats->rx_bytes += skb->len;
-
- skb->priority = vlan_get_ingress_priority(skb->dev, vlan_tci);
-
- pr_debug("%s: priority: %u for TCI: %hu\n",
- __func__, skb->priority, vlan_tci);
-
- switch (skb->pkt_type) {
- case PACKET_BROADCAST:
- /* Yeah, stats collect these together.. */
- /* stats->broadcast ++; // no such counter :-( */
- break;
-
- case PACKET_MULTICAST:
- rx_stats->rx_multicast++;
- break;
-
- 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.
- */
- if (!compare_ether_addr(eth_hdr(skb)->h_dest,
- skb->dev->dev_addr))
- skb->pkt_type = PACKET_HOST;
- break;
- default:
- break;
- }
- u64_stats_update_end(&rx_stats->syncp);
- }
-
- skb_pull_rcsum(skb, VLAN_HLEN);
- vlan_set_encap_proto(skb, vhdr);
-
- if (vlan_dev) {
- skb = vlan_check_reorder_header(skb);
- if (!skb) {
- rx_stats->rx_errors++;
- goto err_unlock;
- }
- }
-
- netif_rx(skb);
-
- rcu_read_unlock();
- return NET_RX_SUCCESS;
-
-err_unlock:
- rcu_read_unlock();
-err_free:
- atomic_long_inc(&dev->rx_dropped);
- kfree_skb(skb);
- return NET_RX_DROP;
-}
-
static inline u16
vlan_dev_get_egress_qos_mask(struct net_device *dev, struct sk_buff *skb)
{
@@ -701,8 +528,8 @@ static int vlan_dev_init(struct net_device *dev)
(1<<__LINK_STATE_DORMANT))) |
(1<<__LINK_STATE_PRESENT);
- dev->features |= real_dev->features & real_dev->vlan_features;
- dev->features |= NETIF_F_LLTX;
+ dev->hw_features = NETIF_F_ALL_TX_OFFLOADS;
+ dev->features |= real_dev->vlan_features | NETIF_F_LLTX;
dev->gso_max_size = real_dev->gso_max_size;
/* ipv6 shared card related stuff */
@@ -756,6 +583,19 @@ static void vlan_dev_uninit(struct net_device *dev)
}
}
+static u32 vlan_dev_fix_features(struct net_device *dev, u32 features)
+{
+ struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
+
+ features &= real_dev->features;
+ features &= real_dev->vlan_features;
+ if (dev_ethtool_get_rx_csum(real_dev))
+ features |= NETIF_F_RXCSUM;
+ features |= NETIF_F_LLTX;
+
+ return features;
+}
+
static int vlan_ethtool_get_settings(struct net_device *dev,
struct ethtool_cmd *cmd)
{
@@ -771,18 +611,6 @@ static void vlan_ethtool_get_drvinfo(struct net_device *dev,
strcpy(info->fw_version, "N/A");
}
-static u32 vlan_ethtool_get_rx_csum(struct net_device *dev)
-{
- const struct vlan_dev_info *vlan = vlan_dev_info(dev);
- return dev_ethtool_get_rx_csum(vlan->real_dev);
-}
-
-static u32 vlan_ethtool_get_flags(struct net_device *dev)
-{
- const struct vlan_dev_info *vlan = vlan_dev_info(dev);
- return dev_ethtool_get_flags(vlan->real_dev);
-}
-
static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
{
@@ -820,32 +648,10 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st
return stats;
}
-static int vlan_ethtool_set_tso(struct net_device *dev, u32 data)
-{
- if (data) {
- struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
-
- /* Underlying device must support TSO for VLAN-tagged packets
- * and must have TSO enabled now.
- */
- if (!(real_dev->vlan_features & NETIF_F_TSO))
- return -EOPNOTSUPP;
- if (!(real_dev->features & NETIF_F_TSO))
- return -EINVAL;
- dev->features |= NETIF_F_TSO;
- } else {
- dev->features &= ~NETIF_F_TSO;
- }
- return 0;
-}
-
static const struct ethtool_ops vlan_ethtool_ops = {
.get_settings = vlan_ethtool_get_settings,
.get_drvinfo = vlan_ethtool_get_drvinfo,
.get_link = ethtool_op_get_link,
- .get_rx_csum = vlan_ethtool_get_rx_csum,
- .get_flags = vlan_ethtool_get_flags,
- .set_tso = vlan_ethtool_set_tso,
};
static const struct net_device_ops vlan_netdev_ops = {
@@ -871,6 +677,7 @@ static const struct net_device_ops vlan_netdev_ops = {
.ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn,
.ndo_fcoe_ddp_target = vlan_dev_fcoe_ddp_target,
#endif
+ .ndo_fix_features = vlan_dev_fix_features,
};
void vlan_setup(struct net_device *dev)
diff --git a/net/9p/client.c b/net/9p/client.c
index a9aa2dd6648..ceab943dfc4 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -1281,7 +1281,7 @@ int
p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
u32 count)
{
- int err, rsize, total;
+ int err, rsize;
struct p9_client *clnt;
struct p9_req_t *req;
char *dataptr;
@@ -1290,7 +1290,6 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
(long long unsigned) offset, count);
err = 0;
clnt = fid->clnt;
- total = 0;
rsize = fid->iounit;
if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
@@ -1346,7 +1345,7 @@ int
p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
u64 offset, u32 count)
{
- int err, rsize, total;
+ int err, rsize;
struct p9_client *clnt;
struct p9_req_t *req;
@@ -1354,7 +1353,6 @@ p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
fid->fid, (long long unsigned) offset, count);
err = 0;
clnt = fid->clnt;
- total = 0;
rsize = fid->iounit;
if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
@@ -1745,7 +1743,7 @@ EXPORT_SYMBOL_GPL(p9_client_xattrcreate);
int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
{
- int err, rsize, total;
+ int err, rsize;
struct p9_client *clnt;
struct p9_req_t *req;
char *dataptr;
@@ -1755,7 +1753,6 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
err = 0;
clnt = fid->clnt;
- total = 0;
rsize = fid->iounit;
if (!rsize || rsize > clnt->msize-P9_READDIRHDRSZ)
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index aa5672b15ea..4a9084395d3 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -716,7 +716,6 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
substring_t args[MAX_OPT_ARGS];
int option;
char *options, *tmp_options;
- int ret;
opts->port = P9_PORT;
opts->rfd = ~0;
@@ -744,7 +743,6 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
if (r < 0) {
P9_DPRINTK(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
- ret = r;
continue;
}
}
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c
index 150e0c4bbf4..844a7a5607e 100644
--- a/net/9p/trans_rdma.c
+++ b/net/9p/trans_rdma.c
@@ -167,7 +167,6 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts)
substring_t args[MAX_OPT_ARGS];
int option;
char *options, *tmp_options;
- int ret;
opts->port = P9_PORT;
opts->sq_depth = P9_RDMA_SQ_DEPTH;
@@ -195,7 +194,6 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts)
if (r < 0) {
P9_DPRINTK(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
- ret = r;
continue;
}
switch (token) {
diff --git a/net/Kconfig b/net/Kconfig
index 79cabf1ee68..878151c772c 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -232,6 +232,20 @@ config XPS
depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS
default y
+config HAVE_BPF_JIT
+ bool
+
+config BPF_JIT
+ bool "enable BPF Just In Time compiler"
+ depends on HAVE_BPF_JIT
+ depends on MODULES
+ ---help---
+ Berkeley Packet Filter filtering capabilities are normally handled
+ by an interpreter. This option allows kernel to generate a native
+ code when filter is loaded in memory. This should speedup
+ packet sniffing (libpcap/tcpdump). Note : Admin should enable
+ this feature changing /proc/sys/net/core/bpf_jit_enable
+
menu "Network testing"
config NET_PKTGEN
diff --git a/net/atm/lec.c b/net/atm/lec.c
index 38754fdb88b..25073b6ef47 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -129,7 +129,6 @@ static struct net_device *dev_lec[MAX_LEC_ITF];
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev)
{
- struct ethhdr *eth;
char *buff;
struct lec_priv *priv;
@@ -138,7 +137,6 @@ static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev)
* LE_TOPOLOGY_REQUEST with the same value of Topology Change bit
* as the Config BPDU has
*/
- eth = (struct ethhdr *)skb->data;
buff = skb->data + skb->dev->hard_header_len;
if (*buff++ == 0x42 && *buff++ == 0x42 && *buff++ == 0x03) {
struct sock *sk;
@@ -1180,7 +1178,6 @@ static int __init lane_module_init(void)
static void __exit lane_module_cleanup(void)
{
int i;
- struct lec_priv *priv;
remove_proc_entry("lec", atm_proc_root);
@@ -1188,7 +1185,6 @@ static void __exit lane_module_cleanup(void)
for (i = 0; i < MAX_LEC_ITF; i++) {
if (dev_lec[i] != NULL) {
- priv = netdev_priv(dev_lec[i]);
unregister_netdev(dev_lec[i]);
free_netdev(dev_lec[i]);
dev_lec[i] = NULL;
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 6da5daeebab..e7c69f4619e 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1538,8 +1538,6 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,
}
/* Build a packet */
- SOCK_DEBUG(sk, "AX.25: sendto: Addresses built. Building packet.\n");
-
/* Assume the worst case */
size = len + ax25->ax25_dev->dev->hard_header_len;
@@ -1549,8 +1547,6 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,
skb_reserve(skb, size - len);
- SOCK_DEBUG(sk, "AX.25: Appending user data\n");
-
/* User data follows immediately after the AX.25 data */
if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
err = -EFAULT;
@@ -1564,8 +1560,6 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,
if (!ax25->pidincl)
*skb_push(skb, 1) = sk->sk_protocol;
- SOCK_DEBUG(sk, "AX.25: Transmitting buffer\n");
-
if (sk->sk_type == SOCK_SEQPACKET) {
/* Connected mode sockets go via the LAPB machine */
if (sk->sk_state != TCP_ESTABLISHED) {
@@ -1583,22 +1577,14 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,
skb_push(skb, 1 + ax25_addr_size(dp));
- SOCK_DEBUG(sk, "Building AX.25 Header (dp=%p).\n", dp);
-
- if (dp != NULL)
- SOCK_DEBUG(sk, "Num digipeaters=%d\n", dp->ndigi);
+ /* Building AX.25 Header */
/* Build an AX.25 header */
lv = ax25_addr_build(skb->data, &ax25->source_addr, &sax.sax25_call,
dp, AX25_COMMAND, AX25_MODULUS);
- SOCK_DEBUG(sk, "Built header (%d bytes)\n",lv);
-
skb_set_transport_header(skb, lv);
- SOCK_DEBUG(sk, "base=%p pos=%p\n",
- skb->data, skb_transport_header(skb));
-
*skb_transport_header(skb) = AX25_UI;
/* Datagram frames go straight out of the door as UI */
diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c
index 5a0dda8df49..60b545e2822 100644
--- a/net/ax25/ax25_iface.c
+++ b/net/ax25/ax25_iface.c
@@ -58,7 +58,7 @@ EXPORT_SYMBOL_GPL(ax25_register_pid);
void ax25_protocol_release(unsigned int pid)
{
- struct ax25_protocol *s, *protocol;
+ struct ax25_protocol *protocol;
write_lock_bh(&protocol_list_lock);
protocol = protocol_list;
@@ -72,7 +72,6 @@ void ax25_protocol_release(unsigned int pid)
while (protocol != NULL && protocol->next != NULL) {
if (protocol->next->pid == pid) {
- s = protocol->next;
protocol->next = protocol->next->next;
goto out;
}
diff --git a/net/batman-adv/aggregation.c b/net/batman-adv/aggregation.c
index af45d6b2031..a8c32030527 100644
--- a/net/batman-adv/aggregation.c
+++ b/net/batman-adv/aggregation.c
@@ -23,11 +23,12 @@
#include "aggregation.h"
#include "send.h"
#include "routing.h"
+#include "hard-interface.h"
-/* calculate the size of the hna information for a given packet */
-static int hna_len(struct batman_packet *batman_packet)
+/* calculate the size of the tt information for a given packet */
+static int tt_len(struct batman_packet *batman_packet)
{
- return batman_packet->num_hna * ETH_ALEN;
+ return batman_packet->num_tt * ETH_ALEN;
}
/* return true if new_packet can be aggregated with forw_packet */
@@ -95,7 +96,6 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet,
return false;
}
-#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
/* create a new aggregated packet and add this packet to it */
static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
unsigned long send_time, bool direct_link,
@@ -106,12 +106,15 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
struct forw_packet *forw_packet_aggr;
unsigned char *skb_buff;
+ if (!atomic_inc_not_zero(&if_incoming->refcount))
+ return;
+
/* own packet should always be scheduled */
if (!own_packet) {
if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
bat_dbg(DBG_BATMAN, bat_priv,
"batman packet queue full\n");
- return;
+ goto out;
}
}
@@ -119,7 +122,7 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
if (!forw_packet_aggr) {
if (!own_packet)
atomic_inc(&bat_priv->batman_queue_left);
- return;
+ goto out;
}
if ((atomic_read(&bat_priv->aggregated_ogms)) &&
@@ -134,7 +137,7 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
if (!own_packet)
atomic_inc(&bat_priv->batman_queue_left);
kfree(forw_packet_aggr);
- return;
+ goto out;
}
skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr));
@@ -165,6 +168,10 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
queue_delayed_work(bat_event_workqueue,
&forw_packet_aggr->delayed_work,
send_time - jiffies);
+
+ return;
+out:
+ hardif_free_ref(if_incoming);
}
/* aggregate a new packet into the existing aggregation */
@@ -251,7 +258,7 @@ void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
{
struct batman_packet *batman_packet;
int buff_pos = 0;
- unsigned char *hna_buff;
+ unsigned char *tt_buff;
batman_packet = (struct batman_packet *)packet_buff;
@@ -260,14 +267,14 @@ void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
orig_interval. */
batman_packet->seqno = ntohl(batman_packet->seqno);
- hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
+ tt_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
receive_bat_packet(ethhdr, batman_packet,
- hna_buff, hna_len(batman_packet),
+ tt_buff, tt_len(batman_packet),
if_incoming);
- buff_pos += BAT_PACKET_LEN + hna_len(batman_packet);
+ buff_pos += BAT_PACKET_LEN + tt_len(batman_packet);
batman_packet = (struct batman_packet *)
(packet_buff + buff_pos);
} while (aggregated_packet(buff_pos, packet_len,
- batman_packet->num_hna));
+ batman_packet->num_tt));
}
diff --git a/net/batman-adv/aggregation.h b/net/batman-adv/aggregation.h
index 062204289d1..7e6d72fbf54 100644
--- a/net/batman-adv/aggregation.h
+++ b/net/batman-adv/aggregation.h
@@ -25,9 +25,9 @@
#include "main.h"
/* is there another aggregated packet here? */
-static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna)
+static inline int aggregated_packet(int buff_pos, int packet_len, int num_tt)
{
- int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_hna * ETH_ALEN);
+ int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_tt * ETH_ALEN);
return (next_buff_pos <= packet_len) &&
(next_buff_pos <= MAX_AGGREGATION_BYTES);
diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c
index 0e9d4350993..abaeec5f624 100644
--- a/net/batman-adv/bat_debugfs.c
+++ b/net/batman-adv/bat_debugfs.c
@@ -241,13 +241,13 @@ static int softif_neigh_open(struct inode *inode, struct file *file)
static int transtable_global_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
- return single_open(file, hna_global_seq_print_text, net_dev);
+ return single_open(file, tt_global_seq_print_text, net_dev);
}
static int transtable_local_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
- return single_open(file, hna_local_seq_print_text, net_dev);
+ return single_open(file, tt_local_seq_print_text, net_dev);
}
static int vis_data_open(struct inode *inode, struct file *file)
diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c
index e449bf6353e..497a0700cc3 100644
--- a/net/batman-adv/bat_sysfs.c
+++ b/net/batman-adv/bat_sysfs.c
@@ -488,22 +488,24 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
(strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0))
goto out;
+ if (!rtnl_trylock()) {
+ ret = -ERESTARTSYS;
+ goto out;
+ }
+
if (status_tmp == IF_NOT_IN_USE) {
- rtnl_lock();
hardif_disable_interface(hard_iface);
- rtnl_unlock();
- goto out;
+ goto unlock;
}
/* if the interface already is in use */
- if (hard_iface->if_status != IF_NOT_IN_USE) {
- rtnl_lock();
+ if (hard_iface->if_status != IF_NOT_IN_USE)
hardif_disable_interface(hard_iface);
- rtnl_unlock();
- }
ret = hardif_enable_interface(hard_iface, buff);
+unlock:
+ rtnl_unlock();
out:
hardif_free_ref(hard_iface);
return ret;
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 150b6ce23df..61605a0f3f3 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -23,6 +23,7 @@
#include "gateway_client.h"
#include "gateway_common.h"
#include "hard-interface.h"
+#include "originator.h"
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/udp.h>
@@ -34,61 +35,76 @@ static void gw_node_free_ref(struct gw_node *gw_node)
kfree_rcu(gw_node, rcu);
}
-void *gw_get_selected(struct bat_priv *bat_priv)
+static struct gw_node *gw_get_selected_gw_node(struct bat_priv *bat_priv)
{
- struct gw_node *curr_gateway_tmp;
- struct orig_node *orig_node = NULL;
+ struct gw_node *gw_node;
rcu_read_lock();
- curr_gateway_tmp = rcu_dereference(bat_priv->curr_gw);
- if (!curr_gateway_tmp)
- goto out;
-
- orig_node = curr_gateway_tmp->orig_node;
- if (!orig_node)
+ gw_node = rcu_dereference(bat_priv->curr_gw);
+ if (!gw_node)
goto out;
- if (!atomic_inc_not_zero(&orig_node->refcount))
- orig_node = NULL;
+ if (!atomic_inc_not_zero(&gw_node->refcount))
+ gw_node = NULL;
out:
rcu_read_unlock();
- return orig_node;
+ return gw_node;
}
-void gw_deselect(struct bat_priv *bat_priv)
+struct orig_node *gw_get_selected_orig(struct bat_priv *bat_priv)
{
struct gw_node *gw_node;
+ struct orig_node *orig_node = NULL;
- spin_lock_bh(&bat_priv->gw_list_lock);
- gw_node = rcu_dereference(bat_priv->curr_gw);
- rcu_assign_pointer(bat_priv->curr_gw, NULL);
- spin_unlock_bh(&bat_priv->gw_list_lock);
+ gw_node = gw_get_selected_gw_node(bat_priv);
+ if (!gw_node)
+ goto out;
+
+ rcu_read_lock();
+ orig_node = gw_node->orig_node;
+ if (!orig_node)
+ goto unlock;
+
+ if (!atomic_inc_not_zero(&orig_node->refcount))
+ orig_node = NULL;
+unlock:
+ rcu_read_unlock();
+out:
if (gw_node)
gw_node_free_ref(gw_node);
+ return orig_node;
}
static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node)
{
struct gw_node *curr_gw_node;
+ spin_lock_bh(&bat_priv->gw_list_lock);
+
if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount))
new_gw_node = NULL;
- spin_lock_bh(&bat_priv->gw_list_lock);
- curr_gw_node = rcu_dereference(bat_priv->curr_gw);
+ curr_gw_node = bat_priv->curr_gw;
rcu_assign_pointer(bat_priv->curr_gw, new_gw_node);
- spin_unlock_bh(&bat_priv->gw_list_lock);
if (curr_gw_node)
gw_node_free_ref(curr_gw_node);
+
+ spin_unlock_bh(&bat_priv->gw_list_lock);
+}
+
+void gw_deselect(struct bat_priv *bat_priv)
+{
+ gw_select(bat_priv, NULL);
}
void gw_election(struct bat_priv *bat_priv)
{
struct hlist_node *node;
- struct gw_node *gw_node, *curr_gw, *curr_gw_tmp = NULL;
+ struct gw_node *gw_node, *curr_gw = NULL, *curr_gw_tmp = NULL;
+ struct neigh_node *router;
uint8_t max_tq = 0;
uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
int down, up;
@@ -102,32 +118,25 @@ void gw_election(struct bat_priv *bat_priv)
if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT)
return;
- rcu_read_lock();
- curr_gw = rcu_dereference(bat_priv->curr_gw);
- if (curr_gw) {
- rcu_read_unlock();
- return;
- }
+ curr_gw = gw_get_selected_gw_node(bat_priv);
+ if (curr_gw)
+ goto out;
+ rcu_read_lock();
if (hlist_empty(&bat_priv->gw_list)) {
-
- if (curr_gw) {
- rcu_read_unlock();
- bat_dbg(DBG_BATMAN, bat_priv,
- "Removing selected gateway - "
- "no gateway in range\n");
- gw_deselect(bat_priv);
- } else
- rcu_read_unlock();
-
- return;
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Removing selected gateway - "
+ "no gateway in range\n");
+ gw_deselect(bat_priv);
+ goto unlock;
}
hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
- if (!gw_node->orig_node->router)
+ if (gw_node->deleted)
continue;
- if (gw_node->deleted)
+ router = orig_node_get_router(gw_node->orig_node);
+ if (!router)
continue;
switch (atomic_read(&bat_priv->gw_sel_class)) {
@@ -135,15 +144,14 @@ void gw_election(struct bat_priv *bat_priv)
gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags,
&down, &up);
- tmp_gw_factor = (gw_node->orig_node->router->tq_avg *
- gw_node->orig_node->router->tq_avg *
+ tmp_gw_factor = (router->tq_avg * router->tq_avg *
down * 100 * 100) /
(TQ_LOCAL_WINDOW_SIZE *
TQ_LOCAL_WINDOW_SIZE * 64);
if ((tmp_gw_factor > max_gw_factor) ||
((tmp_gw_factor == max_gw_factor) &&
- (gw_node->orig_node->router->tq_avg > max_tq)))
+ (router->tq_avg > max_tq)))
curr_gw_tmp = gw_node;
break;
@@ -155,19 +163,25 @@ void gw_election(struct bat_priv *bat_priv)
* soon as a better gateway appears which has
* $routing_class more tq points)
**/
- if (gw_node->orig_node->router->tq_avg > max_tq)
+ if (router->tq_avg > max_tq)
curr_gw_tmp = gw_node;
break;
}
- if (gw_node->orig_node->router->tq_avg > max_tq)
- max_tq = gw_node->orig_node->router->tq_avg;
+ if (router->tq_avg > max_tq)
+ max_tq = router->tq_avg;
if (tmp_gw_factor > max_gw_factor)
max_gw_factor = tmp_gw_factor;
+
+ neigh_node_free_ref(router);
}
if (curr_gw != curr_gw_tmp) {
+ router = orig_node_get_router(curr_gw_tmp->orig_node);
+ if (!router)
+ goto unlock;
+
if ((curr_gw) && (!curr_gw_tmp))
bat_dbg(DBG_BATMAN, bat_priv,
"Removing selected gateway - "
@@ -178,48 +192,50 @@ void gw_election(struct bat_priv *bat_priv)
"(gw_flags: %i, tq: %i)\n",
curr_gw_tmp->orig_node->orig,
curr_gw_tmp->orig_node->gw_flags,
- curr_gw_tmp->orig_node->router->tq_avg);
+ router->tq_avg);
else
bat_dbg(DBG_BATMAN, bat_priv,
"Changing route to gateway %pM "
"(gw_flags: %i, tq: %i)\n",
curr_gw_tmp->orig_node->orig,
curr_gw_tmp->orig_node->gw_flags,
- curr_gw_tmp->orig_node->router->tq_avg);
+ router->tq_avg);
+ neigh_node_free_ref(router);
gw_select(bat_priv, curr_gw_tmp);
}
+unlock:
rcu_read_unlock();
+out:
+ if (curr_gw)
+ gw_node_free_ref(curr_gw);
}
void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node)
{
- struct gw_node *curr_gateway_tmp;
+ struct orig_node *curr_gw_orig;
+ struct neigh_node *router_gw = NULL, *router_orig = NULL;
uint8_t gw_tq_avg, orig_tq_avg;
- rcu_read_lock();
- curr_gateway_tmp = rcu_dereference(bat_priv->curr_gw);
- if (!curr_gateway_tmp)
- goto out_rcu;
-
- if (!curr_gateway_tmp->orig_node)
- goto deselect_rcu;
+ curr_gw_orig = gw_get_selected_orig(bat_priv);
+ if (!curr_gw_orig)
+ goto deselect;
- if (!curr_gateway_tmp->orig_node->router)
- goto deselect_rcu;
+ router_gw = orig_node_get_router(curr_gw_orig);
+ if (!router_gw)
+ goto deselect;
/* this node already is the gateway */
- if (curr_gateway_tmp->orig_node == orig_node)
- goto out_rcu;
-
- if (!orig_node->router)
- goto out_rcu;
+ if (curr_gw_orig == orig_node)
+ goto out;
- gw_tq_avg = curr_gateway_tmp->orig_node->router->tq_avg;
- rcu_read_unlock();
+ router_orig = orig_node_get_router(orig_node);
+ if (!router_orig)
+ goto out;
- orig_tq_avg = orig_node->router->tq_avg;
+ gw_tq_avg = router_gw->tq_avg;
+ orig_tq_avg = router_orig->tq_avg;
/* the TQ value has to be better */
if (orig_tq_avg < gw_tq_avg)
@@ -237,16 +253,17 @@ void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node)
"Restarting gateway selection: better gateway found (tq curr: "
"%i, tq new: %i)\n",
gw_tq_avg, orig_tq_avg);
- goto deselect;
-out_rcu:
- rcu_read_unlock();
- goto out;
-deselect_rcu:
- rcu_read_unlock();
deselect:
gw_deselect(bat_priv);
out:
+ if (curr_gw_orig)
+ orig_node_free_ref(curr_gw_orig);
+ if (router_gw)
+ neigh_node_free_ref(router_gw);
+ if (router_orig)
+ neigh_node_free_ref(router_orig);
+
return;
}
@@ -283,7 +300,15 @@ void gw_node_update(struct bat_priv *bat_priv,
struct orig_node *orig_node, uint8_t new_gwflags)
{
struct hlist_node *node;
- struct gw_node *gw_node;
+ struct gw_node *gw_node, *curr_gw;
+
+ /**
+ * Note: We don't need a NULL check here, since curr_gw never gets
+ * dereferenced. If curr_gw is NULL we also should not exit as we may
+ * have this gateway in our list (duplication check!) even though we
+ * have no currently selected gateway.
+ */
+ curr_gw = gw_get_selected_gw_node(bat_priv);
rcu_read_lock();
hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
@@ -304,22 +329,26 @@ void gw_node_update(struct bat_priv *bat_priv,
"Gateway %pM removed from gateway list\n",
orig_node->orig);
- if (gw_node == rcu_dereference(bat_priv->curr_gw)) {
- rcu_read_unlock();
- gw_deselect(bat_priv);
- return;
- }
+ if (gw_node == curr_gw)
+ goto deselect;
}
- rcu_read_unlock();
- return;
+ goto unlock;
}
- rcu_read_unlock();
if (new_gwflags == 0)
- return;
+ goto unlock;
gw_node_add(bat_priv, orig_node, new_gwflags);
+ goto unlock;
+
+deselect:
+ gw_deselect(bat_priv);
+unlock:
+ rcu_read_unlock();
+
+ if (curr_gw)
+ gw_node_free_ref(curr_gw);
}
void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node)
@@ -329,9 +358,12 @@ void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node)
void gw_node_purge(struct bat_priv *bat_priv)
{
- struct gw_node *gw_node;
+ struct gw_node *gw_node, *curr_gw;
struct hlist_node *node, *node_tmp;
unsigned long timeout = 2 * PURGE_TIMEOUT * HZ;
+ char do_deselect = 0;
+
+ curr_gw = gw_get_selected_gw_node(bat_priv);
spin_lock_bh(&bat_priv->gw_list_lock);
@@ -342,41 +374,56 @@ void gw_node_purge(struct bat_priv *bat_priv)
atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE)
continue;
- if (rcu_dereference(bat_priv->curr_gw) == gw_node)
- gw_deselect(bat_priv);
+ if (curr_gw == gw_node)
+ do_deselect = 1;
hlist_del_rcu(&gw_node->list);
gw_node_free_ref(gw_node);
}
-
spin_unlock_bh(&bat_priv->gw_list_lock);
+
+ /* gw_deselect() needs to acquire the gw_list_lock */
+ if (do_deselect)
+ gw_deselect(bat_priv);
+
+ if (curr_gw)
+ gw_node_free_ref(curr_gw);
}
+/**
+ * fails if orig_node has no router
+ */
static int _write_buffer_text(struct bat_priv *bat_priv,
struct seq_file *seq, struct gw_node *gw_node)
{
struct gw_node *curr_gw;
- int down, up, ret;
+ struct neigh_node *router;
+ int down, up, ret = -1;
gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up);
- rcu_read_lock();
- curr_gw = rcu_dereference(bat_priv->curr_gw);
+ router = orig_node_get_router(gw_node->orig_node);
+ if (!router)
+ goto out;
- ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n",
- (curr_gw == gw_node ? "=>" : " "),
- gw_node->orig_node->orig,
- gw_node->orig_node->router->tq_avg,
- gw_node->orig_node->router->addr,
- gw_node->orig_node->router->if_incoming->net_dev->name,
- gw_node->orig_node->gw_flags,
- (down > 2048 ? down / 1024 : down),
- (down > 2048 ? "MBit" : "KBit"),
- (up > 2048 ? up / 1024 : up),
- (up > 2048 ? "MBit" : "KBit"));
+ curr_gw = gw_get_selected_gw_node(bat_priv);
- rcu_read_unlock();
+ ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n",
+ (curr_gw == gw_node ? "=>" : " "),
+ gw_node->orig_node->orig,
+ router->tq_avg, router->addr,
+ router->if_incoming->net_dev->name,
+ gw_node->orig_node->gw_flags,
+ (down > 2048 ? down / 1024 : down),
+ (down > 2048 ? "MBit" : "KBit"),
+ (up > 2048 ? up / 1024 : up),
+ (up > 2048 ? "MBit" : "KBit"));
+
+ neigh_node_free_ref(router);
+ if (curr_gw)
+ gw_node_free_ref(curr_gw);
+out:
return ret;
}
@@ -384,40 +431,42 @@ int gw_client_seq_print_text(struct seq_file *seq, void *offset)
{
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
+ struct hard_iface *primary_if;
struct gw_node *gw_node;
struct hlist_node *node;
- int gw_count = 0;
-
- if (!bat_priv->primary_if) {
+ int gw_count = 0, ret = 0;
- return seq_printf(seq, "BATMAN mesh %s disabled - please "
- "specify interfaces to enable it\n",
- net_dev->name);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - please "
+ "specify interfaces to enable it\n",
+ net_dev->name);
+ goto out;
}
- if (bat_priv->primary_if->if_status != IF_ACTIVE) {
-
- return seq_printf(seq, "BATMAN mesh %s disabled - "
- "primary interface not active\n",
- net_dev->name);
+ if (primary_if->if_status != IF_ACTIVE) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "primary interface not active\n",
+ net_dev->name);
+ goto out;
}
seq_printf(seq, " %-12s (%s/%i) %17s [%10s]: gw_class ... "
"[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n",
"Gateway", "#", TQ_MAX_VALUE, "Nexthop",
"outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR,
- bat_priv->primary_if->net_dev->name,
- bat_priv->primary_if->net_dev->dev_addr, net_dev->name);
+ primary_if->net_dev->name,
+ primary_if->net_dev->dev_addr, net_dev->name);
rcu_read_lock();
hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
if (gw_node->deleted)
continue;
- if (!gw_node->orig_node->router)
+ /* fails if orig_node has no router */
+ if (_write_buffer_text(bat_priv, seq, gw_node) < 0)
continue;
- _write_buffer_text(bat_priv, seq, gw_node);
gw_count++;
}
rcu_read_unlock();
@@ -425,7 +474,10 @@ int gw_client_seq_print_text(struct seq_file *seq, void *offset)
if (gw_count == 0)
seq_printf(seq, "No gateways in range ...\n");
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
@@ -434,6 +486,7 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
struct iphdr *iphdr;
struct ipv6hdr *ipv6hdr;
struct udphdr *udphdr;
+ struct gw_node *curr_gw;
unsigned int header_len = 0;
if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF)
@@ -498,12 +551,11 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)
return -1;
- rcu_read_lock();
- if (!rcu_dereference(bat_priv->curr_gw)) {
- rcu_read_unlock();
+ curr_gw = gw_get_selected_gw_node(bat_priv);
+ if (!curr_gw)
return 0;
- }
- rcu_read_unlock();
+ if (curr_gw)
+ gw_node_free_ref(curr_gw);
return 1;
}
diff --git a/net/batman-adv/gateway_client.h b/net/batman-adv/gateway_client.h
index 2aa439124ee..1ce8c6066da 100644
--- a/net/batman-adv/gateway_client.h
+++ b/net/batman-adv/gateway_client.h
@@ -24,7 +24,7 @@
void gw_deselect(struct bat_priv *bat_priv);
void gw_election(struct bat_priv *bat_priv);
-void *gw_get_selected(struct bat_priv *bat_priv);
+struct orig_node *gw_get_selected_orig(struct bat_priv *bat_priv);
void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node);
void gw_node_update(struct bat_priv *bat_priv,
struct orig_node *orig_node, uint8_t new_gwflags);
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index b3058e46ee6..dfbfccc9fe4 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -31,9 +31,6 @@
#include <linux/if_arp.h>
-/* protect update critical side of hardif_list - but not the content */
-static DEFINE_SPINLOCK(hardif_list_lock);
-
static int batman_skb_recv(struct sk_buff *skb,
struct net_device *dev,
@@ -110,47 +107,57 @@ out:
return hard_iface;
}
-static void update_primary_addr(struct bat_priv *bat_priv)
+static void primary_if_update_addr(struct bat_priv *bat_priv)
{
struct vis_packet *vis_packet;
+ struct hard_iface *primary_if;
+
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
vis_packet = (struct vis_packet *)
bat_priv->my_vis_info->skb_packet->data;
- memcpy(vis_packet->vis_orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
memcpy(vis_packet->sender_orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ primary_if->net_dev->dev_addr, ETH_ALEN);
+
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
}
-static void set_primary_if(struct bat_priv *bat_priv,
- struct hard_iface *hard_iface)
+static void primary_if_select(struct bat_priv *bat_priv,
+ struct hard_iface *new_hard_iface)
{
+ struct hard_iface *curr_hard_iface;
struct batman_packet *batman_packet;
- struct hard_iface *old_if;
- if (hard_iface && !atomic_inc_not_zero(&hard_iface->refcount))
- hard_iface = NULL;
+ ASSERT_RTNL();
+
+ if (new_hard_iface && !atomic_inc_not_zero(&new_hard_iface->refcount))
+ new_hard_iface = NULL;
- old_if = bat_priv->primary_if;
- bat_priv->primary_if = hard_iface;
+ curr_hard_iface = bat_priv->primary_if;
+ rcu_assign_pointer(bat_priv->primary_if, new_hard_iface);
- if (old_if)
- hardif_free_ref(old_if);
+ if (curr_hard_iface)
+ hardif_free_ref(curr_hard_iface);
- if (!bat_priv->primary_if)
+ if (!new_hard_iface)
return;
- batman_packet = (struct batman_packet *)(hard_iface->packet_buff);
+ batman_packet = (struct batman_packet *)(new_hard_iface->packet_buff);
batman_packet->flags = PRIMARIES_FIRST_HOP;
batman_packet->ttl = TTL;
- update_primary_addr(bat_priv);
+ primary_if_update_addr(bat_priv);
/***
- * hacky trick to make sure that we send the HNA information via
+ * hacky trick to make sure that we send the TT information via
* our new primary interface
*/
- atomic_set(&bat_priv->hna_local_changed, 1);
+ atomic_set(&bat_priv->tt_local_changed, 1);
}
static bool hardif_is_iface_up(struct hard_iface *hard_iface)
@@ -236,9 +243,10 @@ void update_min_mtu(struct net_device *soft_iface)
static void hardif_activate_interface(struct hard_iface *hard_iface)
{
struct bat_priv *bat_priv;
+ struct hard_iface *primary_if = NULL;
if (hard_iface->if_status != IF_INACTIVE)
- return;
+ goto out;
bat_priv = netdev_priv(hard_iface->soft_iface);
@@ -249,14 +257,18 @@ static void hardif_activate_interface(struct hard_iface *hard_iface)
* the first active interface becomes our primary interface or
* the next active interface after the old primay interface was removed
*/
- if (!bat_priv->primary_if)
- set_primary_if(bat_priv, hard_iface);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ primary_if_select(bat_priv, hard_iface);
bat_info(hard_iface->soft_iface, "Interface activated: %s\n",
hard_iface->net_dev->name);
update_min_mtu(hard_iface->soft_iface);
- return;
+
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
}
static void hardif_deactivate_interface(struct hard_iface *hard_iface)
@@ -327,7 +339,7 @@ int hardif_enable_interface(struct hard_iface *hard_iface, char *iface_name)
batman_packet->flags = 0;
batman_packet->ttl = 2;
batman_packet->tq = TQ_MAX_VALUE;
- batman_packet->num_hna = 0;
+ batman_packet->num_tt = 0;
hard_iface->if_num = bat_priv->num_ifaces;
bat_priv->num_ifaces++;
@@ -386,12 +398,13 @@ err:
void hardif_disable_interface(struct hard_iface *hard_iface)
{
struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+ struct hard_iface *primary_if = NULL;
if (hard_iface->if_status == IF_ACTIVE)
hardif_deactivate_interface(hard_iface);
if (hard_iface->if_status != IF_INACTIVE)
- return;
+ goto out;
bat_info(hard_iface->soft_iface, "Removing interface: %s\n",
hard_iface->net_dev->name);
@@ -400,11 +413,12 @@ void hardif_disable_interface(struct hard_iface *hard_iface)
bat_priv->num_ifaces--;
orig_hash_del_if(hard_iface, bat_priv->num_ifaces);
- if (hard_iface == bat_priv->primary_if) {
+ primary_if = primary_if_get_selected(bat_priv);
+ if (hard_iface == primary_if) {
struct hard_iface *new_if;
new_if = hardif_get_active(hard_iface->soft_iface);
- set_primary_if(bat_priv, new_if);
+ primary_if_select(bat_priv, new_if);
if (new_if)
hardif_free_ref(new_if);
@@ -425,6 +439,10 @@ void hardif_disable_interface(struct hard_iface *hard_iface)
hard_iface->soft_iface = NULL;
hardif_free_ref(hard_iface);
+
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
}
static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
@@ -432,6 +450,8 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
struct hard_iface *hard_iface;
int ret;
+ ASSERT_RTNL();
+
ret = is_valid_iface(net_dev);
if (ret != 1)
goto out;
@@ -458,10 +478,7 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
atomic_set(&hard_iface->refcount, 2);
check_known_mac_addr(hard_iface->net_dev);
-
- spin_lock(&hardif_list_lock);
list_add_tail_rcu(&hard_iface->list, &hardif_list);
- spin_unlock(&hardif_list_lock);
return hard_iface;
@@ -475,6 +492,8 @@ out:
static void hardif_remove_interface(struct hard_iface *hard_iface)
{
+ ASSERT_RTNL();
+
/* first deactivate interface */
if (hard_iface->if_status != IF_NOT_IN_USE)
hardif_disable_interface(hard_iface);
@@ -490,20 +509,11 @@ static void hardif_remove_interface(struct hard_iface *hard_iface)
void hardif_remove_interfaces(void)
{
struct hard_iface *hard_iface, *hard_iface_tmp;
- struct list_head if_queue;
-
- INIT_LIST_HEAD(&if_queue);
- spin_lock(&hardif_list_lock);
+ rtnl_lock();
list_for_each_entry_safe(hard_iface, hard_iface_tmp,
&hardif_list, list) {
list_del_rcu(&hard_iface->list);
- list_add_tail(&hard_iface->list, &if_queue);
- }
- spin_unlock(&hardif_list_lock);
-
- rtnl_lock();
- list_for_each_entry_safe(hard_iface, hard_iface_tmp, &if_queue, list) {
hardif_remove_interface(hard_iface);
}
rtnl_unlock();
@@ -514,6 +524,7 @@ static int hard_if_event(struct notifier_block *this,
{
struct net_device *net_dev = (struct net_device *)ptr;
struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev);
+ struct hard_iface *primary_if = NULL;
struct bat_priv *bat_priv;
if (!hard_iface && event == NETDEV_REGISTER)
@@ -531,9 +542,7 @@ static int hard_if_event(struct notifier_block *this,
hardif_deactivate_interface(hard_iface);
break;
case NETDEV_UNREGISTER:
- spin_lock(&hardif_list_lock);
list_del_rcu(&hard_iface->list);
- spin_unlock(&hardif_list_lock);
hardif_remove_interface(hard_iface);
break;
@@ -549,8 +558,12 @@ static int hard_if_event(struct notifier_block *this,
update_mac_addresses(hard_iface);
bat_priv = netdev_priv(hard_iface->soft_iface);
- if (hard_iface == bat_priv->primary_if)
- update_primary_addr(bat_priv);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto hardif_put;
+
+ if (hard_iface == primary_if)
+ primary_if_update_addr(bat_priv);
break;
default:
break;
@@ -559,6 +572,8 @@ static int hard_if_event(struct notifier_block *this,
hardif_put:
hardif_free_ref(hard_iface);
out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
return NOTIFY_DONE;
}
diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h
index a9ddf36e51c..64265991460 100644
--- a/net/batman-adv/hard-interface.h
+++ b/net/batman-adv/hard-interface.h
@@ -45,4 +45,22 @@ static inline void hardif_free_ref(struct hard_iface *hard_iface)
call_rcu(&hard_iface->rcu, hardif_free_rcu);
}
+static inline struct hard_iface *primary_if_get_selected(
+ struct bat_priv *bat_priv)
+{
+ struct hard_iface *hard_iface;
+
+ rcu_read_lock();
+ hard_iface = rcu_dereference(bat_priv->primary_if);
+ if (!hard_iface)
+ goto out;
+
+ if (!atomic_inc_not_zero(&hard_iface->refcount))
+ hard_iface = NULL;
+
+out:
+ rcu_read_unlock();
+ return hard_iface;
+}
+
#endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index 34ce56c358e..fa22ba2bb83 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -153,6 +153,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
{
struct socket_client *socket_client = file->private_data;
struct bat_priv *bat_priv = socket_client->bat_priv;
+ struct hard_iface *primary_if = NULL;
struct sk_buff *skb;
struct icmp_packet_rr *icmp_packet;
@@ -167,15 +168,21 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
return -EINVAL;
}
- if (!bat_priv->primary_if)
- return -EFAULT;
+ primary_if = primary_if_get_selected(bat_priv);
+
+ if (!primary_if) {
+ len = -EFAULT;
+ goto out;
+ }
if (len >= sizeof(struct icmp_packet_rr))
packet_len = sizeof(struct icmp_packet_rr);
skb = dev_alloc_skb(packet_len + sizeof(struct ethhdr));
- if (!skb)
- return -ENOMEM;
+ if (!skb) {
+ len = -ENOMEM;
+ goto out;
+ }
skb_reserve(skb, sizeof(struct ethhdr));
icmp_packet = (struct icmp_packet_rr *)skb_put(skb, packet_len);
@@ -218,23 +225,13 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
goto dst_unreach;
- rcu_read_lock();
orig_node = orig_hash_find(bat_priv, icmp_packet->dst);
-
if (!orig_node)
- goto unlock;
-
- neigh_node = orig_node->router;
+ goto dst_unreach;
+ neigh_node = orig_node_get_router(orig_node);
if (!neigh_node)
- goto unlock;
-
- if (!atomic_inc_not_zero(&neigh_node->refcount)) {
- neigh_node = NULL;
- goto unlock;
- }
-
- rcu_read_unlock();
+ goto dst_unreach;
if (!neigh_node->if_incoming)
goto dst_unreach;
@@ -243,7 +240,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
goto dst_unreach;
memcpy(icmp_packet->orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ primary_if->net_dev->dev_addr, ETH_ALEN);
if (packet_len == sizeof(struct icmp_packet_rr))
memcpy(icmp_packet->rr,
@@ -252,14 +249,14 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
goto out;
-unlock:
- rcu_read_unlock();
dst_unreach:
icmp_packet->msg_type = DESTINATION_UNREACHABLE;
bat_socket_add_packet(socket_client, icmp_packet, packet_len);
free_skb:
kfree_skb(skb);
out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
if (neigh_node)
neigh_node_free_ref(neigh_node);
if (orig_node)
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 709b33bbdf4..0a7cee0076f 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -33,6 +33,9 @@
#include "vis.h"
#include "hash.h"
+
+/* List manipulations on hardif_list have to be rtnl_lock()'ed,
+ * list traversals just rcu-locked */
struct list_head hardif_list;
unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@@ -81,28 +84,29 @@ int mesh_init(struct net_device *soft_iface)
spin_lock_init(&bat_priv->forw_bat_list_lock);
spin_lock_init(&bat_priv->forw_bcast_list_lock);
- spin_lock_init(&bat_priv->hna_lhash_lock);
- spin_lock_init(&bat_priv->hna_ghash_lock);
+ spin_lock_init(&bat_priv->tt_lhash_lock);
+ spin_lock_init(&bat_priv->tt_ghash_lock);
spin_lock_init(&bat_priv->gw_list_lock);
spin_lock_init(&bat_priv->vis_hash_lock);
spin_lock_init(&bat_priv->vis_list_lock);
spin_lock_init(&bat_priv->softif_neigh_lock);
+ spin_lock_init(&bat_priv->softif_neigh_vid_lock);
INIT_HLIST_HEAD(&bat_priv->forw_bat_list);
INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
INIT_HLIST_HEAD(&bat_priv->gw_list);
- INIT_HLIST_HEAD(&bat_priv->softif_neigh_list);
+ INIT_HLIST_HEAD(&bat_priv->softif_neigh_vids);
if (originator_init(bat_priv) < 1)
goto err;
- if (hna_local_init(bat_priv) < 1)
+ if (tt_local_init(bat_priv) < 1)
goto err;
- if (hna_global_init(bat_priv) < 1)
+ if (tt_global_init(bat_priv) < 1)
goto err;
- hna_local_add(soft_iface, soft_iface->dev_addr);
+ tt_local_add(soft_iface, soft_iface->dev_addr);
if (vis_init(bat_priv) < 1)
goto err;
@@ -133,8 +137,8 @@ void mesh_free(struct net_device *soft_iface)
gw_node_purge(bat_priv);
originator_free(bat_priv);
- hna_local_free(bat_priv);
- hna_global_free(bat_priv);
+ tt_local_free(bat_priv);
+ tt_global_free(bat_priv);
softif_neigh_purge(bat_priv);
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index dc248697de7..148b49e0264 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -34,16 +34,18 @@
#define TQ_MAX_VALUE 255
#define JITTER 20
-#define TTL 50 /* Time To Live of broadcast messages */
-#define PURGE_TIMEOUT 200 /* purge originators after time in seconds if no
- * valid packet comes in -> TODO: check
- * influence on TQ_LOCAL_WINDOW_SIZE */
-#define LOCAL_HNA_TIMEOUT 3600 /* in seconds */
+ /* Time To Live of broadcast messages */
+#define TTL 50
-#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator
- * messages in squence numbers (should be a
- * multiple of our word size) */
+/* purge originators after time in seconds if no valid packet comes in
+ * -> TODO: check influence on TQ_LOCAL_WINDOW_SIZE */
+#define PURGE_TIMEOUT 200
+#define TT_LOCAL_TIMEOUT 3600 /* in seconds */
+
+/* sliding packet range of received originator messages in squence numbers
+ * (should be a multiple of our word size) */
+#define TQ_LOCAL_WINDOW_SIZE 64
#define TQ_GLOBAL_WINDOW_SIZE 5
#define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1
#define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1
@@ -55,21 +57,20 @@
#define VIS_INTERVAL 5000 /* 5 seconds */
-/* how much worse secondary interfaces may be to
- * to be considered as bonding candidates */
-
+/* how much worse secondary interfaces may be to be considered as bonding
+ * candidates */
#define BONDING_TQ_THRESHOLD 50
-#define MAX_AGGREGATION_BYTES 512 /* should not be bigger than 512 bytes or
- * change the size of
- * forw_packet->direct_link_flags */
+/* should not be bigger than 512 bytes or change the size of
+ * forw_packet->direct_link_flags */
+#define MAX_AGGREGATION_BYTES 512
#define MAX_AGGREGATION_MS 100
#define SOFTIF_NEIGH_TIMEOUT 180000 /* 3 minutes */
+/* don't reset again within 30 seconds */
#define RESET_PROTECTION_MS 30000
#define EXPECTED_SEQNO_RANGE 65536
-/* don't reset again within 30 seconds */
#define MESH_INACTIVE 0
#define MESH_ACTIVE 1
@@ -84,12 +85,13 @@
#ifdef pr_fmt
#undef pr_fmt
#endif
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt /* Append 'batman-adv: ' before
- * kernel messages */
+/* Append 'batman-adv: ' before kernel messages */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define DBG_BATMAN 1 /* all messages related to routing / flooding /
- * broadcasting / etc */
-#define DBG_ROUTES 2 /* route or hna added / changed / deleted */
+/* all messages related to routing / flooding / broadcasting / etc */
+#define DBG_BATMAN 1
+/* route or tt entry added / changed / deleted */
+#define DBG_ROUTES 2
#define DBG_ALL 3
@@ -175,4 +177,6 @@ static inline int compare_eth(void *data1, void *data2)
return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
}
+#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
+
#endif /* _NET_BATMAN_ADV_MAIN_H_ */
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index ed23a5895d6..40a30bbcd14 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -19,8 +19,6 @@
*
*/
-/* increase the reference counter for this originator */
-
#include "main.h"
#include "originator.h"
#include "hash.h"
@@ -62,6 +60,21 @@ void neigh_node_free_ref(struct neigh_node *neigh_node)
kfree_rcu(neigh_node, rcu);
}
+/* increases the refcounter of a found router */
+struct neigh_node *orig_node_get_router(struct orig_node *orig_node)
+{
+ struct neigh_node *router;
+
+ rcu_read_lock();
+ router = rcu_dereference(orig_node->router);
+
+ if (router && !atomic_inc_not_zero(&router->refcount))
+ router = NULL;
+
+ rcu_read_unlock();
+ return router;
+}
+
struct neigh_node *create_neighbor(struct orig_node *orig_node,
struct orig_node *orig_neigh_node,
uint8_t *neigh,
@@ -79,6 +92,7 @@ struct neigh_node *create_neighbor(struct orig_node *orig_node,
INIT_HLIST_NODE(&neigh_node->list);
INIT_LIST_HEAD(&neigh_node->bonding_list);
+ spin_lock_init(&neigh_node->tq_lock);
memcpy(neigh_node->addr, neigh, ETH_ALEN);
neigh_node->orig_node = orig_neigh_node;
@@ -120,7 +134,7 @@ static void orig_node_free_rcu(struct rcu_head *rcu)
spin_unlock_bh(&orig_node->neigh_list_lock);
frag_list_free(&orig_node->frag_list);
- hna_global_del_orig(orig_node->bat_priv, orig_node,
+ tt_global_del_orig(orig_node->bat_priv, orig_node,
"originator timed out");
kfree(orig_node->bcast_own);
@@ -198,7 +212,7 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr)
orig_node->bat_priv = bat_priv;
memcpy(orig_node->orig, addr, ETH_ALEN);
orig_node->router = NULL;
- orig_node->hna_buff = NULL;
+ orig_node->tt_buff = NULL;
orig_node->bcast_seqno_reset = jiffies - 1
- msecs_to_jiffies(RESET_PROTECTION_MS);
orig_node->batman_seqno_reset = jiffies - 1
@@ -309,8 +323,8 @@ static bool purge_orig_node(struct bat_priv *bat_priv,
&best_neigh_node)) {
update_routes(bat_priv, orig_node,
best_neigh_node,
- orig_node->hna_buff,
- orig_node->hna_buff_len);
+ orig_node->tt_buff,
+ orig_node->tt_buff_len);
}
}
@@ -381,29 +395,34 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
struct hashtable_t *hash = bat_priv->orig_hash;
struct hlist_node *node, *node_tmp;
struct hlist_head *head;
+ struct hard_iface *primary_if;
struct orig_node *orig_node;
- struct neigh_node *neigh_node;
+ struct neigh_node *neigh_node, *neigh_node_tmp;
int batman_count = 0;
int last_seen_secs;
int last_seen_msecs;
- int i;
+ int i, ret = 0;
- if ((!bat_priv->primary_if) ||
- (bat_priv->primary_if->if_status != IF_ACTIVE)) {
- if (!bat_priv->primary_if)
- return seq_printf(seq, "BATMAN mesh %s disabled - "
- "please specify interfaces to enable it\n",
- net_dev->name);
+ primary_if = primary_if_get_selected(bat_priv);
+
+ if (!primary_if) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
+ goto out;
+ }
- return seq_printf(seq, "BATMAN mesh %s "
- "disabled - primary interface not active\n",
- net_dev->name);
+ if (primary_if->if_status != IF_ACTIVE) {
+ ret = seq_printf(seq, "BATMAN mesh %s "
+ "disabled - primary interface not active\n",
+ net_dev->name);
+ goto out;
}
seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n",
SOURCE_VERSION, REVISION_VERSION_STR,
- bat_priv->primary_if->net_dev->name,
- bat_priv->primary_if->net_dev->dev_addr, net_dev->name);
+ primary_if->net_dev->name,
+ primary_if->net_dev->dev_addr, net_dev->name);
seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
"Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop",
"outgoingIF", "Potential nexthops");
@@ -413,40 +432,47 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
rcu_read_lock();
hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
- if (!orig_node->router)
+ neigh_node = orig_node_get_router(orig_node);
+ if (!neigh_node)
continue;
- if (orig_node->router->tq_avg == 0)
- continue;
+ if (neigh_node->tq_avg == 0)
+ goto next;
last_seen_secs = jiffies_to_msecs(jiffies -
orig_node->last_valid) / 1000;
last_seen_msecs = jiffies_to_msecs(jiffies -
orig_node->last_valid) % 1000;
- neigh_node = orig_node->router;
seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:",
orig_node->orig, last_seen_secs,
last_seen_msecs, neigh_node->tq_avg,
neigh_node->addr,
neigh_node->if_incoming->net_dev->name);
- hlist_for_each_entry_rcu(neigh_node, node_tmp,
+ hlist_for_each_entry_rcu(neigh_node_tmp, node_tmp,
&orig_node->neigh_list, list) {
- seq_printf(seq, " %pM (%3i)", neigh_node->addr,
- neigh_node->tq_avg);
+ seq_printf(seq, " %pM (%3i)",
+ neigh_node_tmp->addr,
+ neigh_node_tmp->tq_avg);
}
seq_printf(seq, "\n");
batman_count++;
+
+next:
+ neigh_node_free_ref(neigh_node);
}
rcu_read_unlock();
}
- if ((batman_count == 0))
+ if (batman_count == 0)
seq_printf(seq, "No batman nodes in range ...\n");
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h
index 5cc011057da..e1d641f27aa 100644
--- a/net/batman-adv/originator.h
+++ b/net/batman-adv/originator.h
@@ -34,6 +34,7 @@ struct neigh_node *create_neighbor(struct orig_node *orig_node,
uint8_t *neigh,
struct hard_iface *if_incoming);
void neigh_node_free_ref(struct neigh_node *neigh_node);
+struct neigh_node *orig_node_get_router(struct orig_node *orig_node);
int orig_seq_print_text(struct seq_file *seq, void *offset);
int orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num);
int orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num);
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index e7571879af3..eda99650e9f 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -61,7 +61,7 @@ struct batman_packet {
uint8_t orig[6];
uint8_t prev_sender[6];
uint8_t ttl;
- uint8_t num_hna;
+ uint8_t num_tt;
uint8_t gw_flags; /* flags related to gateway class */
uint8_t align;
} __packed;
@@ -128,8 +128,7 @@ struct vis_packet {
uint8_t entries; /* number of entries behind this struct */
uint32_t seqno; /* sequence number */
uint8_t ttl; /* TTL */
- uint8_t vis_orig[6]; /* originator that informs about its
- * neighbors */
+ uint8_t vis_orig[6]; /* originator that announces its neighbors */
uint8_t target_orig[6]; /* who should receive this packet */
uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */
} __packed;
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index c172f5d0e05..bb1c3ec7e3f 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -64,80 +64,97 @@ void slide_own_bcast_window(struct hard_iface *hard_iface)
}
}
-static void update_HNA(struct bat_priv *bat_priv, struct orig_node *orig_node,
- unsigned char *hna_buff, int hna_buff_len)
+static void update_TT(struct bat_priv *bat_priv, struct orig_node *orig_node,
+ unsigned char *tt_buff, int tt_buff_len)
{
- if ((hna_buff_len != orig_node->hna_buff_len) ||
- ((hna_buff_len > 0) &&
- (orig_node->hna_buff_len > 0) &&
- (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) {
-
- if (orig_node->hna_buff_len > 0)
- hna_global_del_orig(bat_priv, orig_node,
- "originator changed hna");
-
- if ((hna_buff_len > 0) && (hna_buff))
- hna_global_add_orig(bat_priv, orig_node,
- hna_buff, hna_buff_len);
+ if ((tt_buff_len != orig_node->tt_buff_len) ||
+ ((tt_buff_len > 0) &&
+ (orig_node->tt_buff_len > 0) &&
+ (memcmp(orig_node->tt_buff, tt_buff, tt_buff_len) != 0))) {
+
+ if (orig_node->tt_buff_len > 0)
+ tt_global_del_orig(bat_priv, orig_node,
+ "originator changed tt");
+
+ if ((tt_buff_len > 0) && (tt_buff))
+ tt_global_add_orig(bat_priv, orig_node,
+ tt_buff, tt_buff_len);
}
}
static void update_route(struct bat_priv *bat_priv,
struct orig_node *orig_node,
struct neigh_node *neigh_node,
- unsigned char *hna_buff, int hna_buff_len)
+ unsigned char *tt_buff, int tt_buff_len)
{
- struct neigh_node *neigh_node_tmp;
+ struct neigh_node *curr_router;
+
+ curr_router = orig_node_get_router(orig_node);
/* route deleted */
- if ((orig_node->router) && (!neigh_node)) {
+ if ((curr_router) && (!neigh_node)) {
bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n",
orig_node->orig);
- hna_global_del_orig(bat_priv, orig_node,
+ tt_global_del_orig(bat_priv, orig_node,
"originator timed out");
- /* route added */
- } else if ((!orig_node->router) && (neigh_node)) {
+ /* route added */
+ } else if ((!curr_router) && (neigh_node)) {
bat_dbg(DBG_ROUTES, bat_priv,
"Adding route towards: %pM (via %pM)\n",
orig_node->orig, neigh_node->addr);
- hna_global_add_orig(bat_priv, orig_node,
- hna_buff, hna_buff_len);
+ tt_global_add_orig(bat_priv, orig_node,
+ tt_buff, tt_buff_len);
- /* route changed */
+ /* route changed */
} else {
bat_dbg(DBG_ROUTES, bat_priv,
"Changing route towards: %pM "
"(now via %pM - was via %pM)\n",
orig_node->orig, neigh_node->addr,
- orig_node->router->addr);
+ curr_router->addr);
}
+ if (curr_router)
+ neigh_node_free_ref(curr_router);
+
+ /* increase refcount of new best neighbor */
if (neigh_node && !atomic_inc_not_zero(&neigh_node->refcount))
neigh_node = NULL;
- neigh_node_tmp = orig_node->router;
- orig_node->router = neigh_node;
- if (neigh_node_tmp)
- neigh_node_free_ref(neigh_node_tmp);
+
+ spin_lock_bh(&orig_node->neigh_list_lock);
+ rcu_assign_pointer(orig_node->router, neigh_node);
+ spin_unlock_bh(&orig_node->neigh_list_lock);
+
+ /* decrease refcount of previous best neighbor */
+ if (curr_router)
+ neigh_node_free_ref(curr_router);
}
void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
- struct neigh_node *neigh_node, unsigned char *hna_buff,
- int hna_buff_len)
+ struct neigh_node *neigh_node, unsigned char *tt_buff,
+ int tt_buff_len)
{
+ struct neigh_node *router = NULL;
if (!orig_node)
- return;
+ goto out;
+
+ router = orig_node_get_router(orig_node);
- if (orig_node->router != neigh_node)
+ if (router != neigh_node)
update_route(bat_priv, orig_node, neigh_node,
- hna_buff, hna_buff_len);
- /* may be just HNA changed */
+ tt_buff, tt_buff_len);
+ /* may be just TT changed */
else
- update_HNA(bat_priv, orig_node, hna_buff, hna_buff_len);
+ update_TT(bat_priv, orig_node, tt_buff, tt_buff_len);
+
+out:
+ if (router)
+ neigh_node_free_ref(router);
}
static int is_bidirectional_neigh(struct orig_node *orig_node,
@@ -152,65 +169,41 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
uint8_t orig_eq_count, neigh_rq_count, tq_own;
int tq_asym_penalty, ret = 0;
- if (orig_node == orig_neigh_node) {
- rcu_read_lock();
- hlist_for_each_entry_rcu(tmp_neigh_node, node,
- &orig_node->neigh_list, list) {
-
- if (!compare_eth(tmp_neigh_node->addr,
- orig_neigh_node->orig))
- continue;
-
- if (tmp_neigh_node->if_incoming != if_incoming)
- continue;
-
- if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
- continue;
-
- neigh_node = tmp_neigh_node;
- }
- rcu_read_unlock();
+ /* find corresponding one hop neighbor */
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(tmp_neigh_node, node,
+ &orig_neigh_node->neigh_list, list) {
- if (!neigh_node)
- neigh_node = create_neighbor(orig_node,
- orig_neigh_node,
- orig_neigh_node->orig,
- if_incoming);
- if (!neigh_node)
- goto out;
+ if (!compare_eth(tmp_neigh_node->addr, orig_neigh_node->orig))
+ continue;
- neigh_node->last_valid = jiffies;
- } else {
- /* find packet count of corresponding one hop neighbor */
- rcu_read_lock();
- hlist_for_each_entry_rcu(tmp_neigh_node, node,
- &orig_neigh_node->neigh_list, list) {
+ if (tmp_neigh_node->if_incoming != if_incoming)
+ continue;
- if (!compare_eth(tmp_neigh_node->addr,
- orig_neigh_node->orig))
- continue;
+ if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
+ continue;
- if (tmp_neigh_node->if_incoming != if_incoming)
- continue;
+ neigh_node = tmp_neigh_node;
+ break;
+ }
+ rcu_read_unlock();
- if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
- continue;
+ if (!neigh_node)
+ neigh_node = create_neighbor(orig_neigh_node,
+ orig_neigh_node,
+ orig_neigh_node->orig,
+ if_incoming);
- neigh_node = tmp_neigh_node;
- }
- rcu_read_unlock();
+ if (!neigh_node)
+ goto out;
- if (!neigh_node)
- neigh_node = create_neighbor(orig_neigh_node,
- orig_neigh_node,
- orig_neigh_node->orig,
- if_incoming);
- if (!neigh_node)
- goto out;
- }
+ /* if orig_node is direct neighbour update neigh_node last_valid */
+ if (orig_node == orig_neigh_node)
+ neigh_node->last_valid = jiffies;
orig_node->last_valid = jiffies;
+ /* find packet count of corresponding one hop neighbor */
spin_lock_bh(&orig_node->ogm_cnt_lock);
orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num];
neigh_rq_count = neigh_node->real_packet_count;
@@ -288,8 +281,8 @@ static void bonding_candidate_add(struct orig_node *orig_node,
struct neigh_node *neigh_node)
{
struct hlist_node *node;
- struct neigh_node *tmp_neigh_node;
- uint8_t best_tq, interference_candidate = 0;
+ struct neigh_node *tmp_neigh_node, *router = NULL;
+ uint8_t interference_candidate = 0;
spin_lock_bh(&orig_node->neigh_list_lock);
@@ -298,13 +291,12 @@ static void bonding_candidate_add(struct orig_node *orig_node,
neigh_node->orig_node->primary_addr))
goto candidate_del;
- if (!orig_node->router)
+ router = orig_node_get_router(orig_node);
+ if (!router)
goto candidate_del;
- best_tq = orig_node->router->tq_avg;
-
/* ... and is good enough to be considered */
- if (neigh_node->tq_avg < best_tq - BONDING_TQ_THRESHOLD)
+ if (neigh_node->tq_avg < router->tq_avg - BONDING_TQ_THRESHOLD)
goto candidate_del;
/**
@@ -350,7 +342,9 @@ candidate_del:
out:
spin_unlock_bh(&orig_node->neigh_list_lock);
- return;
+
+ if (router)
+ neigh_node_free_ref(router);
}
/* copy primary address for bonding */
@@ -369,13 +363,14 @@ static void update_orig(struct bat_priv *bat_priv,
struct ethhdr *ethhdr,
struct batman_packet *batman_packet,
struct hard_iface *if_incoming,
- unsigned char *hna_buff, int hna_buff_len,
+ unsigned char *tt_buff, int tt_buff_len,
char is_duplicate)
{
struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
+ struct neigh_node *router = NULL;
struct orig_node *orig_node_tmp;
struct hlist_node *node;
- int tmp_hna_buff_len;
+ int tmp_tt_buff_len;
uint8_t bcast_own_sum_orig, bcast_own_sum_neigh;
bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): "
@@ -396,10 +391,12 @@ static void update_orig(struct bat_priv *bat_priv,
if (is_duplicate)
continue;
+ spin_lock_bh(&tmp_neigh_node->tq_lock);
ring_buffer_set(tmp_neigh_node->tq_recv,
&tmp_neigh_node->tq_index, 0);
tmp_neigh_node->tq_avg =
ring_buffer_avg(tmp_neigh_node->tq_recv);
+ spin_unlock_bh(&tmp_neigh_node->tq_lock);
}
if (!neigh_node) {
@@ -424,10 +421,12 @@ static void update_orig(struct bat_priv *bat_priv,
orig_node->flags = batman_packet->flags;
neigh_node->last_valid = jiffies;
+ spin_lock_bh(&neigh_node->tq_lock);
ring_buffer_set(neigh_node->tq_recv,
&neigh_node->tq_index,
batman_packet->tq);
neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
+ spin_unlock_bh(&neigh_node->tq_lock);
if (!is_duplicate) {
orig_node->last_ttl = batman_packet->ttl;
@@ -436,24 +435,23 @@ static void update_orig(struct bat_priv *bat_priv,
bonding_candidate_add(orig_node, neigh_node);
- tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ?
- batman_packet->num_hna * ETH_ALEN : hna_buff_len);
+ tmp_tt_buff_len = (tt_buff_len > batman_packet->num_tt * ETH_ALEN ?
+ batman_packet->num_tt * ETH_ALEN : tt_buff_len);
/* if this neighbor already is our next hop there is nothing
* to change */
- if (orig_node->router == neigh_node)
- goto update_hna;
+ router = orig_node_get_router(orig_node);
+ if (router == neigh_node)
+ goto update_tt;
/* if this neighbor does not offer a better TQ we won't consider it */
- if ((orig_node->router) &&
- (orig_node->router->tq_avg > neigh_node->tq_avg))
- goto update_hna;
+ if (router && (router->tq_avg > neigh_node->tq_avg))
+ goto update_tt;
/* if the TQ is the same and the link not more symetric we
* won't consider it either */
- if ((orig_node->router) &&
- (neigh_node->tq_avg == orig_node->router->tq_avg)) {
- orig_node_tmp = orig_node->router->orig_node;
+ if (router && (neigh_node->tq_avg == router->tq_avg)) {
+ orig_node_tmp = router->orig_node;
spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
bcast_own_sum_orig =
orig_node_tmp->bcast_own_sum[if_incoming->if_num];
@@ -466,16 +464,16 @@ static void update_orig(struct bat_priv *bat_priv,
spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
if (bcast_own_sum_orig >= bcast_own_sum_neigh)
- goto update_hna;
+ goto update_tt;
}
update_routes(bat_priv, orig_node, neigh_node,
- hna_buff, tmp_hna_buff_len);
+ tt_buff, tmp_tt_buff_len);
goto update_gw;
-update_hna:
- update_routes(bat_priv, orig_node, orig_node->router,
- hna_buff, tmp_hna_buff_len);
+update_tt:
+ update_routes(bat_priv, orig_node, router,
+ tt_buff, tmp_tt_buff_len);
update_gw:
if (orig_node->gw_flags != batman_packet->gw_flags)
@@ -496,6 +494,8 @@ unlock:
out:
if (neigh_node)
neigh_node_free_ref(neigh_node);
+ if (router)
+ neigh_node_free_ref(router);
}
/* checks whether the host restarted and is in the protection time.
@@ -597,12 +597,14 @@ out:
void receive_bat_packet(struct ethhdr *ethhdr,
struct batman_packet *batman_packet,
- unsigned char *hna_buff, int hna_buff_len,
+ unsigned char *tt_buff, int tt_buff_len,
struct hard_iface *if_incoming)
{
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct hard_iface *hard_iface;
struct orig_node *orig_neigh_node, *orig_node;
+ struct neigh_node *router = NULL, *router_router = NULL;
+ struct neigh_node *orig_neigh_router = NULL;
char has_directlink_flag;
char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
char is_broadcast = 0, is_bidirectional, is_single_hop_neigh;
@@ -747,14 +749,15 @@ void receive_bat_packet(struct ethhdr *ethhdr,
goto out;
}
+ router = orig_node_get_router(orig_node);
+ if (router)
+ router_router = orig_node_get_router(router->orig_node);
+
/* avoid temporary routing loops */
- if ((orig_node->router) &&
- (orig_node->router->orig_node->router) &&
- (compare_eth(orig_node->router->addr,
- batman_packet->prev_sender)) &&
+ if (router && router_router &&
+ (compare_eth(router->addr, batman_packet->prev_sender)) &&
!(compare_eth(batman_packet->orig, batman_packet->prev_sender)) &&
- (compare_eth(orig_node->router->addr,
- orig_node->router->orig_node->router->addr))) {
+ (compare_eth(router->addr, router_router->addr))) {
bat_dbg(DBG_BATMAN, bat_priv,
"Drop packet: ignoring all rebroadcast packets that "
"may make me loop (sender: %pM)\n", ethhdr->h_source);
@@ -769,9 +772,11 @@ void receive_bat_packet(struct ethhdr *ethhdr,
if (!orig_neigh_node)
goto out;
+ orig_neigh_router = orig_node_get_router(orig_neigh_node);
+
/* drop packet if sender is not a direct neighbor and if we
* don't route towards it */
- if (!is_single_hop_neigh && (!orig_neigh_node->router)) {
+ if (!is_single_hop_neigh && (!orig_neigh_router)) {
bat_dbg(DBG_BATMAN, bat_priv,
"Drop packet: OGM via unknown neighbor!\n");
goto out_neigh;
@@ -789,14 +794,14 @@ void receive_bat_packet(struct ethhdr *ethhdr,
((orig_node->last_real_seqno == batman_packet->seqno) &&
(orig_node->last_ttl - 3 <= batman_packet->ttl))))
update_orig(bat_priv, orig_node, ethhdr, batman_packet,
- if_incoming, hna_buff, hna_buff_len, is_duplicate);
+ if_incoming, tt_buff, tt_buff_len, is_duplicate);
/* is single hop (direct) neighbor */
if (is_single_hop_neigh) {
/* mark direct link on incoming interface */
schedule_forward_packet(orig_node, ethhdr, batman_packet,
- 1, hna_buff_len, if_incoming);
+ 1, tt_buff_len, if_incoming);
bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
"rebroadcast neighbor packet with direct link flag\n");
@@ -819,12 +824,19 @@ void receive_bat_packet(struct ethhdr *ethhdr,
bat_dbg(DBG_BATMAN, bat_priv,
"Forwarding packet: rebroadcast originator packet\n");
schedule_forward_packet(orig_node, ethhdr, batman_packet,
- 0, hna_buff_len, if_incoming);
+ 0, tt_buff_len, if_incoming);
out_neigh:
if ((orig_neigh_node) && (!is_single_hop_neigh))
orig_node_free_ref(orig_neigh_node);
out:
+ if (router)
+ neigh_node_free_ref(router);
+ if (router_router)
+ neigh_node_free_ref(router_router);
+ if (orig_neigh_router)
+ neigh_node_free_ref(orig_neigh_router);
+
orig_node_free_ref(orig_node);
}
@@ -868,8 +880,9 @@ int recv_bat_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
static int recv_my_icmp_packet(struct bat_priv *bat_priv,
struct sk_buff *skb, size_t icmp_len)
{
+ struct hard_iface *primary_if = NULL;
struct orig_node *orig_node = NULL;
- struct neigh_node *neigh_node = NULL;
+ struct neigh_node *router = NULL;
struct icmp_packet_rr *icmp_packet;
int ret = NET_RX_DROP;
@@ -881,28 +894,19 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
goto out;
}
- if (!bat_priv->primary_if)
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
goto out;
/* answer echo request (ping) */
/* get routing information */
- rcu_read_lock();
orig_node = orig_hash_find(bat_priv, icmp_packet->orig);
-
if (!orig_node)
- goto unlock;
-
- neigh_node = orig_node->router;
-
- if (!neigh_node)
- goto unlock;
-
- if (!atomic_inc_not_zero(&neigh_node->refcount)) {
- neigh_node = NULL;
- goto unlock;
- }
+ goto out;
- rcu_read_unlock();
+ router = orig_node_get_router(orig_node);
+ if (!router)
+ goto out;
/* create a copy of the skb, if needed, to modify it. */
if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
@@ -911,20 +915,18 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
icmp_packet = (struct icmp_packet_rr *)skb->data;
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
- memcpy(icmp_packet->orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
icmp_packet->msg_type = ECHO_REPLY;
icmp_packet->ttl = TTL;
- send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
+ send_skb_packet(skb, router->if_incoming, router->addr);
ret = NET_RX_SUCCESS;
- goto out;
-unlock:
- rcu_read_unlock();
out:
- if (neigh_node)
- neigh_node_free_ref(neigh_node);
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ if (router)
+ neigh_node_free_ref(router);
if (orig_node)
orig_node_free_ref(orig_node);
return ret;
@@ -933,8 +935,9 @@ out:
static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
struct sk_buff *skb)
{
+ struct hard_iface *primary_if = NULL;
struct orig_node *orig_node = NULL;
- struct neigh_node *neigh_node = NULL;
+ struct neigh_node *router = NULL;
struct icmp_packet *icmp_packet;
int ret = NET_RX_DROP;
@@ -948,27 +951,18 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
goto out;
}
- if (!bat_priv->primary_if)
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
goto out;
/* get routing information */
- rcu_read_lock();
orig_node = orig_hash_find(bat_priv, icmp_packet->orig);
-
if (!orig_node)
- goto unlock;
-
- neigh_node = orig_node->router;
-
- if (!neigh_node)
- goto unlock;
-
- if (!atomic_inc_not_zero(&neigh_node->refcount)) {
- neigh_node = NULL;
- goto unlock;
- }
+ goto out;
- rcu_read_unlock();
+ router = orig_node_get_router(orig_node);
+ if (!router)
+ goto out;
/* create a copy of the skb, if needed, to modify it. */
if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
@@ -977,20 +971,18 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
icmp_packet = (struct icmp_packet *)skb->data;
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
- memcpy(icmp_packet->orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
icmp_packet->msg_type = TTL_EXCEEDED;
icmp_packet->ttl = TTL;
- send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
+ send_skb_packet(skb, router->if_incoming, router->addr);
ret = NET_RX_SUCCESS;
- goto out;
-unlock:
- rcu_read_unlock();
out:
- if (neigh_node)
- neigh_node_free_ref(neigh_node);
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ if (router)
+ neigh_node_free_ref(router);
if (orig_node)
orig_node_free_ref(orig_node);
return ret;
@@ -1003,7 +995,7 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
struct icmp_packet_rr *icmp_packet;
struct ethhdr *ethhdr;
struct orig_node *orig_node = NULL;
- struct neigh_node *neigh_node = NULL;
+ struct neigh_node *router = NULL;
int hdr_size = sizeof(struct icmp_packet);
int ret = NET_RX_DROP;
@@ -1050,23 +1042,13 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
return recv_icmp_ttl_exceeded(bat_priv, skb);
/* get routing information */
- rcu_read_lock();
orig_node = orig_hash_find(bat_priv, icmp_packet->dst);
-
if (!orig_node)
- goto unlock;
-
- neigh_node = orig_node->router;
-
- if (!neigh_node)
- goto unlock;
-
- if (!atomic_inc_not_zero(&neigh_node->refcount)) {
- neigh_node = NULL;
- goto unlock;
- }
+ goto out;
- rcu_read_unlock();
+ router = orig_node_get_router(orig_node);
+ if (!router)
+ goto out;
/* create a copy of the skb, if needed, to modify it. */
if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
@@ -1078,20 +1060,117 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
icmp_packet->ttl--;
/* route it */
- send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
+ send_skb_packet(skb, router->if_incoming, router->addr);
ret = NET_RX_SUCCESS;
- goto out;
-unlock:
- rcu_read_unlock();
out:
- if (neigh_node)
- neigh_node_free_ref(neigh_node);
+ if (router)
+ neigh_node_free_ref(router);
if (orig_node)
orig_node_free_ref(orig_node);
return ret;
}
+/* In the bonding case, send the packets in a round
+ * robin fashion over the remaining interfaces.
+ *
+ * This method rotates the bonding list and increases the
+ * returned router's refcount. */
+static struct neigh_node *find_bond_router(struct orig_node *primary_orig,
+ struct hard_iface *recv_if)
+{
+ struct neigh_node *tmp_neigh_node;
+ struct neigh_node *router = NULL, *first_candidate = NULL;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(tmp_neigh_node, &primary_orig->bond_list,
+ bonding_list) {
+ if (!first_candidate)
+ first_candidate = tmp_neigh_node;
+
+ /* recv_if == NULL on the first node. */
+ if (tmp_neigh_node->if_incoming == recv_if)
+ continue;
+
+ if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
+ continue;
+
+ router = tmp_neigh_node;
+ break;
+ }
+
+ /* use the first candidate if nothing was found. */
+ if (!router && first_candidate &&
+ atomic_inc_not_zero(&first_candidate->refcount))
+ router = first_candidate;
+
+ if (!router)
+ goto out;
+
+ /* selected should point to the next element
+ * after the current router */
+ spin_lock_bh(&primary_orig->neigh_list_lock);
+ /* this is a list_move(), which unfortunately
+ * does not exist as rcu version */
+ list_del_rcu(&primary_orig->bond_list);
+ list_add_rcu(&primary_orig->bond_list,
+ &router->bonding_list);
+ spin_unlock_bh(&primary_orig->neigh_list_lock);
+
+out:
+ rcu_read_unlock();
+ return router;
+}
+
+/* Interface Alternating: Use the best of the
+ * remaining candidates which are not using
+ * this interface.
+ *
+ * Increases the returned router's refcount */
+static struct neigh_node *find_ifalter_router(struct orig_node *primary_orig,
+ struct hard_iface *recv_if)
+{
+ struct neigh_node *tmp_neigh_node;
+ struct neigh_node *router = NULL, *first_candidate = NULL;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(tmp_neigh_node, &primary_orig->bond_list,
+ bonding_list) {
+ if (!first_candidate)
+ first_candidate = tmp_neigh_node;
+
+ /* recv_if == NULL on the first node. */
+ if (tmp_neigh_node->if_incoming == recv_if)
+ continue;
+
+ if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
+ continue;
+
+ /* if we don't have a router yet
+ * or this one is better, choose it. */
+ if ((!router) ||
+ (tmp_neigh_node->tq_avg > router->tq_avg)) {
+ /* decrement refcount of
+ * previously selected router */
+ if (router)
+ neigh_node_free_ref(router);
+
+ router = tmp_neigh_node;
+ atomic_inc_not_zero(&router->refcount);
+ }
+
+ neigh_node_free_ref(tmp_neigh_node);
+ }
+
+ /* use the first candidate if nothing was found. */
+ if (!router && first_candidate &&
+ atomic_inc_not_zero(&first_candidate->refcount))
+ router = first_candidate;
+
+ rcu_read_unlock();
+ return router;
+}
+
/* find a suitable router for this originator, and use
* bonding if possible. increases the found neighbors
* refcount.*/
@@ -1101,15 +1180,16 @@ struct neigh_node *find_router(struct bat_priv *bat_priv,
{
struct orig_node *primary_orig_node;
struct orig_node *router_orig;
- struct neigh_node *router, *first_candidate, *tmp_neigh_node;
+ struct neigh_node *router;
static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
int bonding_enabled;
if (!orig_node)
return NULL;
- if (!orig_node->router)
- return NULL;
+ router = orig_node_get_router(orig_node);
+ if (!router)
+ goto err;
/* without bonding, the first node should
* always choose the default router. */
@@ -1117,12 +1197,9 @@ struct neigh_node *find_router(struct bat_priv *bat_priv,
rcu_read_lock();
/* select default router to output */
- router = orig_node->router;
- router_orig = orig_node->router->orig_node;
- if (!router_orig || !atomic_inc_not_zero(&router->refcount)) {
- rcu_read_unlock();
- return NULL;
- }
+ router_orig = router->orig_node;
+ if (!router_orig)
+ goto err_unlock;
if ((!recv_if) && (!bonding_enabled))
goto return_router;
@@ -1151,91 +1228,26 @@ struct neigh_node *find_router(struct bat_priv *bat_priv,
if (atomic_read(&primary_orig_node->bond_candidates) < 2)
goto return_router;
-
/* all nodes between should choose a candidate which
* is is not on the interface where the packet came
* in. */
neigh_node_free_ref(router);
- first_candidate = NULL;
- router = NULL;
-
- if (bonding_enabled) {
- /* in the bonding case, send the packets in a round
- * robin fashion over the remaining interfaces. */
-
- list_for_each_entry_rcu(tmp_neigh_node,
- &primary_orig_node->bond_list, bonding_list) {
- if (!first_candidate)
- first_candidate = tmp_neigh_node;
- /* recv_if == NULL on the first node. */
- if (tmp_neigh_node->if_incoming != recv_if &&
- atomic_inc_not_zero(&tmp_neigh_node->refcount)) {
- router = tmp_neigh_node;
- break;
- }
- }
-
- /* use the first candidate if nothing was found. */
- if (!router && first_candidate &&
- atomic_inc_not_zero(&first_candidate->refcount))
- router = first_candidate;
- if (!router) {
- rcu_read_unlock();
- return NULL;
- }
-
- /* selected should point to the next element
- * after the current router */
- spin_lock_bh(&primary_orig_node->neigh_list_lock);
- /* this is a list_move(), which unfortunately
- * does not exist as rcu version */
- list_del_rcu(&primary_orig_node->bond_list);
- list_add_rcu(&primary_orig_node->bond_list,
- &router->bonding_list);
- spin_unlock_bh(&primary_orig_node->neigh_list_lock);
-
- } else {
- /* if bonding is disabled, use the best of the
- * remaining candidates which are not using
- * this interface. */
- list_for_each_entry_rcu(tmp_neigh_node,
- &primary_orig_node->bond_list, bonding_list) {
- if (!first_candidate)
- first_candidate = tmp_neigh_node;
-
- /* recv_if == NULL on the first node. */
- if (tmp_neigh_node->if_incoming == recv_if)
- continue;
-
- if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
- continue;
-
- /* if we don't have a router yet
- * or this one is better, choose it. */
- if ((!router) ||
- (tmp_neigh_node->tq_avg > router->tq_avg)) {
- /* decrement refcount of
- * previously selected router */
- if (router)
- neigh_node_free_ref(router);
-
- router = tmp_neigh_node;
- atomic_inc_not_zero(&router->refcount);
- }
-
- neigh_node_free_ref(tmp_neigh_node);
- }
+ if (bonding_enabled)
+ router = find_bond_router(primary_orig_node, recv_if);
+ else
+ router = find_ifalter_router(primary_orig_node, recv_if);
- /* use the first candidate if nothing was found. */
- if (!router && first_candidate &&
- atomic_inc_not_zero(&first_candidate->refcount))
- router = first_candidate;
- }
return_router:
rcu_read_unlock();
return router;
+err_unlock:
+ rcu_read_unlock();
+err:
+ if (router)
+ neigh_node_free_ref(router);
+ return NULL;
}
static int check_unicast_packet(struct sk_buff *skb, int hdr_size)
@@ -1284,13 +1296,10 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
}
/* get routing information */
- rcu_read_lock();
orig_node = orig_hash_find(bat_priv, unicast_packet->dest);
if (!orig_node)
- goto unlock;
-
- rcu_read_unlock();
+ goto out;
/* find_router() increases neigh_nodes refcount if found. */
neigh_node = find_router(bat_priv, orig_node, recv_if);
@@ -1336,10 +1345,7 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
/* route it */
send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
ret = NET_RX_SUCCESS;
- goto out;
-unlock:
- rcu_read_unlock();
out:
if (neigh_node)
neigh_node_free_ref(neigh_node);
@@ -1438,13 +1444,10 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
if (bcast_packet->ttl < 2)
goto out;
- rcu_read_lock();
orig_node = orig_hash_find(bat_priv, bcast_packet->orig);
if (!orig_node)
- goto rcu_unlock;
-
- rcu_read_unlock();
+ goto out;
spin_lock_bh(&orig_node->bcast_seqno_lock);
@@ -1475,9 +1478,6 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
ret = NET_RX_SUCCESS;
goto out;
-rcu_unlock:
- rcu_read_unlock();
- goto out;
spin_unlock:
spin_unlock_bh(&orig_node->bcast_seqno_lock);
out:
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h
index b5a064c88a4..870f29842b2 100644
--- a/net/batman-adv/routing.h
+++ b/net/batman-adv/routing.h
@@ -25,11 +25,11 @@
void slide_own_bcast_window(struct hard_iface *hard_iface);
void receive_bat_packet(struct ethhdr *ethhdr,
struct batman_packet *batman_packet,
- unsigned char *hna_buff, int hna_buff_len,
+ unsigned char *tt_buff, int tt_buff_len,
struct hard_iface *if_incoming);
void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
- struct neigh_node *neigh_node, unsigned char *hna_buff,
- int hna_buff_len);
+ struct neigh_node *neigh_node, unsigned char *tt_buff,
+ int tt_buff_len);
int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if);
int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if);
int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if);
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index d49e54d932a..33779278f1b 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -121,7 +121,7 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
/* adjust all flags and log packets */
while (aggregated_packet(buff_pos,
forw_packet->packet_len,
- batman_packet->num_hna)) {
+ batman_packet->num_tt)) {
/* we might have aggregated direct link packets with an
* ordinary base packet */
@@ -146,7 +146,7 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
hard_iface->net_dev->dev_addr);
buff_pos += sizeof(struct batman_packet) +
- (batman_packet->num_hna * ETH_ALEN);
+ (batman_packet->num_tt * ETH_ALEN);
packet_num++;
batman_packet = (struct batman_packet *)
(forw_packet->skb->data + buff_pos);
@@ -222,7 +222,7 @@ static void rebuild_batman_packet(struct bat_priv *bat_priv,
struct batman_packet *batman_packet;
new_len = sizeof(struct batman_packet) +
- (bat_priv->num_local_hna * ETH_ALEN);
+ (bat_priv->num_local_tt * ETH_ALEN);
new_buff = kmalloc(new_len, GFP_ATOMIC);
/* keep old buffer if kmalloc should fail */
@@ -231,7 +231,7 @@ static void rebuild_batman_packet(struct bat_priv *bat_priv,
sizeof(struct batman_packet));
batman_packet = (struct batman_packet *)new_buff;
- batman_packet->num_hna = hna_local_fill_buffer(bat_priv,
+ batman_packet->num_tt = tt_local_fill_buffer(bat_priv,
new_buff + sizeof(struct batman_packet),
new_len - sizeof(struct batman_packet));
@@ -244,6 +244,7 @@ static void rebuild_batman_packet(struct bat_priv *bat_priv,
void schedule_own_packet(struct hard_iface *hard_iface)
{
struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+ struct hard_iface *primary_if;
unsigned long send_time;
struct batman_packet *batman_packet;
int vis_server;
@@ -253,6 +254,7 @@ void schedule_own_packet(struct hard_iface *hard_iface)
return;
vis_server = atomic_read(&bat_priv->vis_mode);
+ primary_if = primary_if_get_selected(bat_priv);
/**
* the interface gets activated here to avoid race conditions between
@@ -264,9 +266,9 @@ void schedule_own_packet(struct hard_iface *hard_iface)
if (hard_iface->if_status == IF_TO_BE_ACTIVATED)
hard_iface->if_status = IF_ACTIVE;
- /* if local hna has changed and interface is a primary interface */
- if ((atomic_read(&bat_priv->hna_local_changed)) &&
- (hard_iface == bat_priv->primary_if))
+ /* if local tt has changed and interface is a primary interface */
+ if ((atomic_read(&bat_priv->tt_local_changed)) &&
+ (hard_iface == primary_if))
rebuild_batman_packet(bat_priv, hard_iface);
/**
@@ -284,7 +286,7 @@ void schedule_own_packet(struct hard_iface *hard_iface)
else
batman_packet->flags &= ~VIS_SERVER;
- if ((hard_iface == bat_priv->primary_if) &&
+ if ((hard_iface == primary_if) &&
(atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER))
batman_packet->gw_flags =
(uint8_t)atomic_read(&bat_priv->gw_bandwidth);
@@ -299,15 +301,19 @@ void schedule_own_packet(struct hard_iface *hard_iface)
hard_iface->packet_buff,
hard_iface->packet_len,
hard_iface, 1, send_time);
+
+ if (primary_if)
+ hardif_free_ref(primary_if);
}
void schedule_forward_packet(struct orig_node *orig_node,
struct ethhdr *ethhdr,
struct batman_packet *batman_packet,
- uint8_t directlink, int hna_buff_len,
+ uint8_t directlink, int tt_buff_len,
struct hard_iface *if_incoming)
{
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+ struct neigh_node *router;
unsigned char in_tq, in_ttl, tq_avg = 0;
unsigned long send_time;
@@ -316,6 +322,8 @@ void schedule_forward_packet(struct orig_node *orig_node,
return;
}
+ router = orig_node_get_router(orig_node);
+
in_tq = batman_packet->tq;
in_ttl = batman_packet->ttl;
@@ -324,20 +332,22 @@ void schedule_forward_packet(struct orig_node *orig_node,
/* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast
* of our best tq value */
- if ((orig_node->router) && (orig_node->router->tq_avg != 0)) {
+ if (router && router->tq_avg != 0) {
/* rebroadcast ogm of best ranking neighbor as is */
- if (!compare_eth(orig_node->router->addr, ethhdr->h_source)) {
- batman_packet->tq = orig_node->router->tq_avg;
+ if (!compare_eth(router->addr, ethhdr->h_source)) {
+ batman_packet->tq = router->tq_avg;
- if (orig_node->router->last_ttl)
- batman_packet->ttl = orig_node->router->last_ttl
- - 1;
+ if (router->last_ttl)
+ batman_packet->ttl = router->last_ttl - 1;
}
- tq_avg = orig_node->router->tq_avg;
+ tq_avg = router->tq_avg;
}
+ if (router)
+ neigh_node_free_ref(router);
+
/* apply hop penalty */
batman_packet->tq = hop_penalty(batman_packet->tq, bat_priv);
@@ -359,7 +369,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
send_time = forward_send_time();
add_bat_packet_to_list(bat_priv,
(unsigned char *)batman_packet,
- sizeof(struct batman_packet) + hna_buff_len,
+ sizeof(struct batman_packet) + tt_buff_len,
if_incoming, 0, send_time);
}
@@ -367,6 +377,8 @@ static void forw_packet_free(struct forw_packet *forw_packet)
{
if (forw_packet->skb)
kfree_skb(forw_packet->skb);
+ if (forw_packet->if_incoming)
+ hardif_free_ref(forw_packet->if_incoming);
kfree(forw_packet);
}
@@ -388,7 +400,6 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv,
send_time);
}
-#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
/* add a broadcast packet to the queue and setup timers. broadcast packets
* are sent multiple times to increase probability for beeing received.
*
@@ -399,6 +410,7 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv,
* skb is freed. */
int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
{
+ struct hard_iface *primary_if = NULL;
struct forw_packet *forw_packet;
struct bcast_packet *bcast_packet;
@@ -407,8 +419,9 @@ int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
goto out;
}
- if (!bat_priv->primary_if)
- goto out;
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out_and_inc;
forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
@@ -426,7 +439,7 @@ int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
skb_reset_mac_header(skb);
forw_packet->skb = skb;
- forw_packet->if_incoming = bat_priv->primary_if;
+ forw_packet->if_incoming = primary_if;
/* how often did we send the bcast packet ? */
forw_packet->num_packets = 0;
@@ -439,6 +452,8 @@ packet_free:
out_and_inc:
atomic_inc(&bat_priv->bcast_queue_left);
out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
return NETDEV_TX_BUSY;
}
@@ -526,6 +541,7 @@ void purge_outstanding_packets(struct bat_priv *bat_priv,
{
struct forw_packet *forw_packet;
struct hlist_node *tmp_node, *safe_tmp_node;
+ bool pending;
if (hard_iface)
bat_dbg(DBG_BATMAN, bat_priv,
@@ -554,8 +570,13 @@ void purge_outstanding_packets(struct bat_priv *bat_priv,
* send_outstanding_bcast_packet() will lock the list to
* delete the item from the list
*/
- cancel_delayed_work_sync(&forw_packet->delayed_work);
+ pending = cancel_delayed_work_sync(&forw_packet->delayed_work);
spin_lock_bh(&bat_priv->forw_bcast_list_lock);
+
+ if (pending) {
+ hlist_del(&forw_packet->list);
+ forw_packet_free(forw_packet);
+ }
}
spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
@@ -578,8 +599,13 @@ void purge_outstanding_packets(struct bat_priv *bat_priv,
* send_outstanding_bat_packet() will lock the list to
* delete the item from the list
*/
- cancel_delayed_work_sync(&forw_packet->delayed_work);
+ pending = cancel_delayed_work_sync(&forw_packet->delayed_work);
spin_lock_bh(&bat_priv->forw_bat_list_lock);
+
+ if (pending) {
+ hlist_del(&forw_packet->list);
+ forw_packet_free(forw_packet);
+ }
}
spin_unlock_bh(&bat_priv->forw_bat_list_lock);
}
diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h
index 7b2ff19c05e..247172d71e4 100644
--- a/net/batman-adv/send.h
+++ b/net/batman-adv/send.h
@@ -29,7 +29,7 @@ void schedule_own_packet(struct hard_iface *hard_iface);
void schedule_forward_packet(struct orig_node *orig_node,
struct ethhdr *ethhdr,
struct batman_packet *batman_packet,
- uint8_t directlink, int hna_buff_len,
+ uint8_t directlink, int tt_buff_len,
struct hard_iface *if_outgoing);
int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb);
void send_outstanding_bat_packet(struct work_struct *work);
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 04efe022c13..d5aa60999e8 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -43,8 +43,6 @@ static void bat_get_drvinfo(struct net_device *dev,
static u32 bat_get_msglevel(struct net_device *dev);
static void bat_set_msglevel(struct net_device *dev, u32 value);
static u32 bat_get_link(struct net_device *dev);
-static u32 bat_get_rx_csum(struct net_device *dev);
-static int bat_set_rx_csum(struct net_device *dev, u32 data);
static const struct ethtool_ops bat_ethtool_ops = {
.get_settings = bat_get_settings,
@@ -52,8 +50,6 @@ static const struct ethtool_ops bat_ethtool_ops = {
.get_msglevel = bat_get_msglevel,
.set_msglevel = bat_set_msglevel,
.get_link = bat_get_link,
- .get_rx_csum = bat_get_rx_csum,
- .set_rx_csum = bat_set_rx_csum
};
int my_skb_head_push(struct sk_buff *skb, unsigned int len)
@@ -82,106 +78,365 @@ static void softif_neigh_free_ref(struct softif_neigh *softif_neigh)
kfree_rcu(softif_neigh, rcu);
}
-void softif_neigh_purge(struct bat_priv *bat_priv)
+static void softif_neigh_vid_free_rcu(struct rcu_head *rcu)
{
- struct softif_neigh *softif_neigh, *softif_neigh_tmp;
+ struct softif_neigh_vid *softif_neigh_vid;
+ struct softif_neigh *softif_neigh;
struct hlist_node *node, *node_tmp;
+ struct bat_priv *bat_priv;
- spin_lock_bh(&bat_priv->softif_neigh_lock);
+ softif_neigh_vid = container_of(rcu, struct softif_neigh_vid, rcu);
+ bat_priv = softif_neigh_vid->bat_priv;
+ spin_lock_bh(&bat_priv->softif_neigh_lock);
hlist_for_each_entry_safe(softif_neigh, node, node_tmp,
- &bat_priv->softif_neigh_list, list) {
+ &softif_neigh_vid->softif_neigh_list, list) {
+ hlist_del_rcu(&softif_neigh->list);
+ softif_neigh_free_ref(softif_neigh);
+ }
+ spin_unlock_bh(&bat_priv->softif_neigh_lock);
- if ((!time_after(jiffies, softif_neigh->last_seen +
- msecs_to_jiffies(SOFTIF_NEIGH_TIMEOUT))) &&
- (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE))
- continue;
+ kfree(softif_neigh_vid);
+}
- hlist_del_rcu(&softif_neigh->list);
+static void softif_neigh_vid_free_ref(struct softif_neigh_vid *softif_neigh_vid)
+{
+ if (atomic_dec_and_test(&softif_neigh_vid->refcount))
+ call_rcu(&softif_neigh_vid->rcu, softif_neigh_vid_free_rcu);
+}
- if (bat_priv->softif_neigh == softif_neigh) {
- bat_dbg(DBG_ROUTES, bat_priv,
- "Current mesh exit point '%pM' vanished "
- "(vid: %d).\n",
- softif_neigh->addr, softif_neigh->vid);
- softif_neigh_tmp = bat_priv->softif_neigh;
- bat_priv->softif_neigh = NULL;
- softif_neigh_free_ref(softif_neigh_tmp);
- }
+static struct softif_neigh_vid *softif_neigh_vid_get(struct bat_priv *bat_priv,
+ short vid)
+{
+ struct softif_neigh_vid *softif_neigh_vid;
+ struct hlist_node *node;
- softif_neigh_free_ref(softif_neigh);
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(softif_neigh_vid, node,
+ &bat_priv->softif_neigh_vids, list) {
+ if (softif_neigh_vid->vid != vid)
+ continue;
+
+ if (!atomic_inc_not_zero(&softif_neigh_vid->refcount))
+ continue;
+
+ goto out;
}
- spin_unlock_bh(&bat_priv->softif_neigh_lock);
+ softif_neigh_vid = kzalloc(sizeof(struct softif_neigh_vid),
+ GFP_ATOMIC);
+ if (!softif_neigh_vid)
+ goto out;
+
+ softif_neigh_vid->vid = vid;
+ softif_neigh_vid->bat_priv = bat_priv;
+
+ /* initialize with 2 - caller decrements counter by one */
+ atomic_set(&softif_neigh_vid->refcount, 2);
+ INIT_HLIST_HEAD(&softif_neigh_vid->softif_neigh_list);
+ INIT_HLIST_NODE(&softif_neigh_vid->list);
+ spin_lock_bh(&bat_priv->softif_neigh_vid_lock);
+ hlist_add_head_rcu(&softif_neigh_vid->list,
+ &bat_priv->softif_neigh_vids);
+ spin_unlock_bh(&bat_priv->softif_neigh_vid_lock);
+
+out:
+ rcu_read_unlock();
+ return softif_neigh_vid;
}
static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv,
uint8_t *addr, short vid)
{
- struct softif_neigh *softif_neigh;
+ struct softif_neigh_vid *softif_neigh_vid;
+ struct softif_neigh *softif_neigh = NULL;
struct hlist_node *node;
+ softif_neigh_vid = softif_neigh_vid_get(bat_priv, vid);
+ if (!softif_neigh_vid)
+ goto out;
+
rcu_read_lock();
hlist_for_each_entry_rcu(softif_neigh, node,
- &bat_priv->softif_neigh_list, list) {
+ &softif_neigh_vid->softif_neigh_list,
+ list) {
if (!compare_eth(softif_neigh->addr, addr))
continue;
- if (softif_neigh->vid != vid)
- continue;
-
if (!atomic_inc_not_zero(&softif_neigh->refcount))
continue;
softif_neigh->last_seen = jiffies;
- goto out;
+ goto unlock;
}
softif_neigh = kzalloc(sizeof(struct softif_neigh), GFP_ATOMIC);
if (!softif_neigh)
- goto out;
+ goto unlock;
memcpy(softif_neigh->addr, addr, ETH_ALEN);
- softif_neigh->vid = vid;
softif_neigh->last_seen = jiffies;
/* initialize with 2 - caller decrements counter by one */
atomic_set(&softif_neigh->refcount, 2);
INIT_HLIST_NODE(&softif_neigh->list);
spin_lock_bh(&bat_priv->softif_neigh_lock);
- hlist_add_head_rcu(&softif_neigh->list, &bat_priv->softif_neigh_list);
+ hlist_add_head_rcu(&softif_neigh->list,
+ &softif_neigh_vid->softif_neigh_list);
spin_unlock_bh(&bat_priv->softif_neigh_lock);
+unlock:
+ rcu_read_unlock();
out:
+ if (softif_neigh_vid)
+ softif_neigh_vid_free_ref(softif_neigh_vid);
+ return softif_neigh;
+}
+
+static struct softif_neigh *softif_neigh_get_selected(
+ struct softif_neigh_vid *softif_neigh_vid)
+{
+ struct softif_neigh *softif_neigh;
+
+ rcu_read_lock();
+ softif_neigh = rcu_dereference(softif_neigh_vid->softif_neigh);
+
+ if (softif_neigh && !atomic_inc_not_zero(&softif_neigh->refcount))
+ softif_neigh = NULL;
+
rcu_read_unlock();
return softif_neigh;
}
+static struct softif_neigh *softif_neigh_vid_get_selected(
+ struct bat_priv *bat_priv,
+ short vid)
+{
+ struct softif_neigh_vid *softif_neigh_vid;
+ struct softif_neigh *softif_neigh = NULL;
+
+ softif_neigh_vid = softif_neigh_vid_get(bat_priv, vid);
+ if (!softif_neigh_vid)
+ goto out;
+
+ softif_neigh = softif_neigh_get_selected(softif_neigh_vid);
+out:
+ if (softif_neigh_vid)
+ softif_neigh_vid_free_ref(softif_neigh_vid);
+ return softif_neigh;
+}
+
+static void softif_neigh_vid_select(struct bat_priv *bat_priv,
+ struct softif_neigh *new_neigh,
+ short vid)
+{
+ struct softif_neigh_vid *softif_neigh_vid;
+ struct softif_neigh *curr_neigh;
+
+ softif_neigh_vid = softif_neigh_vid_get(bat_priv, vid);
+ if (!softif_neigh_vid)
+ goto out;
+
+ spin_lock_bh(&bat_priv->softif_neigh_lock);
+
+ if (new_neigh && !atomic_inc_not_zero(&new_neigh->refcount))
+ new_neigh = NULL;
+
+ curr_neigh = softif_neigh_vid->softif_neigh;
+ rcu_assign_pointer(softif_neigh_vid->softif_neigh, new_neigh);
+
+ if ((curr_neigh) && (!new_neigh))
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Removing mesh exit point on vid: %d (prev: %pM).\n",
+ vid, curr_neigh->addr);
+ else if ((curr_neigh) && (new_neigh))
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Changing mesh exit point on vid: %d from %pM "
+ "to %pM.\n", vid, curr_neigh->addr, new_neigh->addr);
+ else if ((!curr_neigh) && (new_neigh))
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Setting mesh exit point on vid: %d to %pM.\n",
+ vid, new_neigh->addr);
+
+ if (curr_neigh)
+ softif_neigh_free_ref(curr_neigh);
+
+ spin_unlock_bh(&bat_priv->softif_neigh_lock);
+
+out:
+ if (softif_neigh_vid)
+ softif_neigh_vid_free_ref(softif_neigh_vid);
+}
+
+static void softif_neigh_vid_deselect(struct bat_priv *bat_priv,
+ struct softif_neigh_vid *softif_neigh_vid)
+{
+ struct softif_neigh *curr_neigh;
+ struct softif_neigh *softif_neigh = NULL, *softif_neigh_tmp;
+ struct hard_iface *primary_if = NULL;
+ struct hlist_node *node;
+
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
+
+ /* find new softif_neigh immediately to avoid temporary loops */
+ rcu_read_lock();
+ curr_neigh = rcu_dereference(softif_neigh_vid->softif_neigh);
+
+ hlist_for_each_entry_rcu(softif_neigh_tmp, node,
+ &softif_neigh_vid->softif_neigh_list,
+ list) {
+ if (softif_neigh_tmp == curr_neigh)
+ continue;
+
+ /* we got a neighbor but its mac is 'bigger' than ours */
+ if (memcmp(primary_if->net_dev->dev_addr,
+ softif_neigh_tmp->addr, ETH_ALEN) < 0)
+ continue;
+
+ if (!atomic_inc_not_zero(&softif_neigh_tmp->refcount))
+ continue;
+
+ softif_neigh = softif_neigh_tmp;
+ goto unlock;
+ }
+
+unlock:
+ rcu_read_unlock();
+out:
+ softif_neigh_vid_select(bat_priv, softif_neigh, softif_neigh_vid->vid);
+
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ if (softif_neigh)
+ softif_neigh_free_ref(softif_neigh);
+}
+
int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
{
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
+ struct softif_neigh_vid *softif_neigh_vid;
struct softif_neigh *softif_neigh;
- struct hlist_node *node;
+ struct hard_iface *primary_if;
+ struct hlist_node *node, *node_tmp;
+ struct softif_neigh *curr_softif_neigh;
+ int ret = 0, last_seen_secs, last_seen_msecs;
+
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
+ goto out;
+ }
- if (!bat_priv->primary_if) {
- return seq_printf(seq, "BATMAN mesh %s disabled - "
- "please specify interfaces to enable it\n",
- net_dev->name);
+ if (primary_if->if_status != IF_ACTIVE) {
+ ret = seq_printf(seq, "BATMAN mesh %s "
+ "disabled - primary interface not active\n",
+ net_dev->name);
+ goto out;
}
seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name);
rcu_read_lock();
- hlist_for_each_entry_rcu(softif_neigh, node,
- &bat_priv->softif_neigh_list, list)
- seq_printf(seq, "%s %pM (vid: %d)\n",
- bat_priv->softif_neigh == softif_neigh
- ? "=>" : " ", softif_neigh->addr,
- softif_neigh->vid);
+ hlist_for_each_entry_rcu(softif_neigh_vid, node,
+ &bat_priv->softif_neigh_vids, list) {
+ seq_printf(seq, " %-15s %s on vid: %d\n",
+ "Originator", "last-seen", softif_neigh_vid->vid);
+
+ curr_softif_neigh = softif_neigh_get_selected(softif_neigh_vid);
+
+ hlist_for_each_entry_rcu(softif_neigh, node_tmp,
+ &softif_neigh_vid->softif_neigh_list,
+ list) {
+ last_seen_secs = jiffies_to_msecs(jiffies -
+ softif_neigh->last_seen) / 1000;
+ last_seen_msecs = jiffies_to_msecs(jiffies -
+ softif_neigh->last_seen) % 1000;
+ seq_printf(seq, "%s %pM %3i.%03is\n",
+ curr_softif_neigh == softif_neigh
+ ? "=>" : " ", softif_neigh->addr,
+ last_seen_secs, last_seen_msecs);
+ }
+
+ if (curr_softif_neigh)
+ softif_neigh_free_ref(curr_softif_neigh);
+
+ seq_printf(seq, "\n");
+ }
rcu_read_unlock();
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
+}
+
+void softif_neigh_purge(struct bat_priv *bat_priv)
+{
+ struct softif_neigh *softif_neigh, *curr_softif_neigh;
+ struct softif_neigh_vid *softif_neigh_vid;
+ struct hlist_node *node, *node_tmp, *node_tmp2;
+ char do_deselect;
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(softif_neigh_vid, node,
+ &bat_priv->softif_neigh_vids, list) {
+ if (!atomic_inc_not_zero(&softif_neigh_vid->refcount))
+ continue;
+
+ curr_softif_neigh = softif_neigh_get_selected(softif_neigh_vid);
+ do_deselect = 0;
+
+ spin_lock_bh(&bat_priv->softif_neigh_lock);
+ hlist_for_each_entry_safe(softif_neigh, node_tmp, node_tmp2,
+ &softif_neigh_vid->softif_neigh_list,
+ list) {
+ if ((!time_after(jiffies, softif_neigh->last_seen +
+ msecs_to_jiffies(SOFTIF_NEIGH_TIMEOUT))) &&
+ (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE))
+ continue;
+
+ if (curr_softif_neigh == softif_neigh) {
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Current mesh exit point on vid: %d "
+ "'%pM' vanished.\n",
+ softif_neigh_vid->vid,
+ softif_neigh->addr);
+ do_deselect = 1;
+ }
+
+ hlist_del_rcu(&softif_neigh->list);
+ softif_neigh_free_ref(softif_neigh);
+ }
+ spin_unlock_bh(&bat_priv->softif_neigh_lock);
+
+ /* soft_neigh_vid_deselect() needs to acquire the
+ * softif_neigh_lock */
+ if (do_deselect)
+ softif_neigh_vid_deselect(bat_priv, softif_neigh_vid);
+
+ if (curr_softif_neigh)
+ softif_neigh_free_ref(curr_softif_neigh);
+
+ softif_neigh_vid_free_ref(softif_neigh_vid);
+ }
+ rcu_read_unlock();
+
+ spin_lock_bh(&bat_priv->softif_neigh_vid_lock);
+ hlist_for_each_entry_safe(softif_neigh_vid, node, node_tmp,
+ &bat_priv->softif_neigh_vids, list) {
+ if (!hlist_empty(&softif_neigh_vid->softif_neigh_list))
+ continue;
+
+ hlist_del_rcu(&softif_neigh_vid->list);
+ softif_neigh_vid_free_ref(softif_neigh_vid);
+ }
+ spin_unlock_bh(&bat_priv->softif_neigh_vid_lock);
+
}
static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
@@ -190,7 +445,9 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
struct bat_priv *bat_priv = netdev_priv(dev);
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
struct batman_packet *batman_packet;
- struct softif_neigh *softif_neigh, *softif_neigh_tmp;
+ struct softif_neigh *softif_neigh = NULL;
+ struct hard_iface *primary_if = NULL;
+ struct softif_neigh *curr_softif_neigh = NULL;
if (ntohs(ethhdr->h_proto) == ETH_P_8021Q)
batman_packet = (struct batman_packet *)
@@ -199,63 +456,52 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN);
if (batman_packet->version != COMPAT_VERSION)
- goto err;
+ goto out;
if (batman_packet->packet_type != BAT_PACKET)
- goto err;
+ goto out;
if (!(batman_packet->flags & PRIMARIES_FIRST_HOP))
- goto err;
+ goto out;
if (is_my_mac(batman_packet->orig))
- goto err;
+ goto out;
softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid);
-
if (!softif_neigh)
- goto err;
+ goto out;
- if (bat_priv->softif_neigh == softif_neigh)
+ curr_softif_neigh = softif_neigh_vid_get_selected(bat_priv, vid);
+ if (curr_softif_neigh == softif_neigh)
+ goto out;
+
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
goto out;
/* we got a neighbor but its mac is 'bigger' than ours */
- if (memcmp(bat_priv->primary_if->net_dev->dev_addr,
+ if (memcmp(primary_if->net_dev->dev_addr,
softif_neigh->addr, ETH_ALEN) < 0)
goto out;
- /* switch to new 'smallest neighbor' */
- if ((bat_priv->softif_neigh) &&
- (memcmp(softif_neigh->addr, bat_priv->softif_neigh->addr,
- ETH_ALEN) < 0)) {
- bat_dbg(DBG_ROUTES, bat_priv,
- "Changing mesh exit point from %pM (vid: %d) "
- "to %pM (vid: %d).\n",
- bat_priv->softif_neigh->addr,
- bat_priv->softif_neigh->vid,
- softif_neigh->addr, softif_neigh->vid);
- softif_neigh_tmp = bat_priv->softif_neigh;
- bat_priv->softif_neigh = softif_neigh;
- softif_neigh_free_ref(softif_neigh_tmp);
- /* we need to hold the additional reference */
- goto err;
- }
-
/* close own batX device and use softif_neigh as exit node */
- if ((!bat_priv->softif_neigh) &&
- (memcmp(softif_neigh->addr,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) {
- bat_dbg(DBG_ROUTES, bat_priv,
- "Setting mesh exit point to %pM (vid: %d).\n",
- softif_neigh->addr, softif_neigh->vid);
- bat_priv->softif_neigh = softif_neigh;
- /* we need to hold the additional reference */
- goto err;
+ if (!curr_softif_neigh) {
+ softif_neigh_vid_select(bat_priv, softif_neigh, vid);
+ goto out;
}
+ /* switch to new 'smallest neighbor' */
+ if (memcmp(softif_neigh->addr, curr_softif_neigh->addr, ETH_ALEN) < 0)
+ softif_neigh_vid_select(bat_priv, softif_neigh, vid);
+
out:
- softif_neigh_free_ref(softif_neigh);
-err:
kfree_skb(skb);
+ if (softif_neigh)
+ softif_neigh_free_ref(softif_neigh);
+ if (curr_softif_neigh)
+ softif_neigh_free_ref(curr_softif_neigh);
+ if (primary_if)
+ hardif_free_ref(primary_if);
return;
}
@@ -285,11 +531,11 @@ static int interface_set_mac_addr(struct net_device *dev, void *p)
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
- /* only modify hna-table if it has been initialised before */
+ /* only modify transtable if it has been initialised before */
if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) {
- hna_local_remove(bat_priv, dev->dev_addr,
+ tt_local_remove(bat_priv, dev->dev_addr,
"mac address changed");
- hna_local_add(dev, addr->sa_data);
+ tt_local_add(dev, addr->sa_data);
}
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
@@ -311,8 +557,10 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
{
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
struct bat_priv *bat_priv = netdev_priv(soft_iface);
+ struct hard_iface *primary_if = NULL;
struct bcast_packet *bcast_packet;
struct vlan_ethhdr *vhdr;
+ struct softif_neigh *curr_softif_neigh = NULL;
int data_len = skb->len, ret;
short vid = -1;
bool do_bcast = false;
@@ -340,11 +588,12 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
* if we have a another chosen mesh exit node in range
* it will transport the packets to the mesh
*/
- if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid))
+ curr_softif_neigh = softif_neigh_vid_get_selected(bat_priv, vid);
+ if (curr_softif_neigh)
goto dropped;
/* TODO: check this for locks */
- hna_local_add(soft_iface, ethhdr->h_source);
+ tt_local_add(soft_iface, ethhdr->h_source);
if (is_multicast_ether_addr(ethhdr->h_dest)) {
ret = gw_is_target(bat_priv, skb);
@@ -358,7 +607,8 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
/* ethernet packet should be broadcasted */
if (do_bcast) {
- if (!bat_priv->primary_if)
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
goto dropped;
if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0)
@@ -374,7 +624,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
/* hw address of first interface is the orig mac because only
* this mac is known throughout the mesh */
memcpy(bcast_packet->orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ primary_if->net_dev->dev_addr, ETH_ALEN);
/* set broadcast sequence number */
bcast_packet->seqno =
@@ -402,6 +652,10 @@ dropped:
dropped_freed:
bat_priv->stats.tx_dropped++;
end:
+ if (curr_softif_neigh)
+ softif_neigh_free_ref(curr_softif_neigh);
+ if (primary_if)
+ hardif_free_ref(primary_if);
return NETDEV_TX_OK;
}
@@ -413,6 +667,7 @@ void interface_rx(struct net_device *soft_iface,
struct unicast_packet *unicast_packet;
struct ethhdr *ethhdr;
struct vlan_ethhdr *vhdr;
+ struct softif_neigh *curr_softif_neigh = NULL;
short vid = -1;
int ret;
@@ -442,7 +697,8 @@ void interface_rx(struct net_device *soft_iface,
* if we have a another chosen mesh exit node in range
* it will transport the packets to the non-mesh network
*/
- if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid)) {
+ curr_softif_neigh = softif_neigh_vid_get_selected(bat_priv, vid);
+ if (curr_softif_neigh) {
skb_push(skb, hdr_size);
unicast_packet = (struct unicast_packet *)skb->data;
@@ -453,7 +709,7 @@ void interface_rx(struct net_device *soft_iface,
skb_reset_mac_header(skb);
memcpy(unicast_packet->dest,
- bat_priv->softif_neigh->addr, ETH_ALEN);
+ curr_softif_neigh->addr, ETH_ALEN);
ret = route_unicast_packet(skb, recv_if);
if (ret == NET_RX_DROP)
goto dropped;
@@ -478,11 +734,13 @@ void interface_rx(struct net_device *soft_iface,
soft_iface->last_rx = jiffies;
netif_rx(skb);
- return;
+ goto out;
dropped:
kfree_skb(skb);
out:
+ if (curr_softif_neigh)
+ softif_neigh_free_ref(curr_softif_neigh);
return;
}
@@ -516,14 +774,15 @@ static void interface_setup(struct net_device *dev)
dev->hard_start_xmit = interface_tx;
#endif
dev->destructor = free_netdev;
+ dev->tx_queue_len = 0;
/**
* can't call min_mtu, because the needed variables
* have not been initialized yet
*/
dev->mtu = ETH_DATA_LEN;
- dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the
- * skbuff for our header */
+ /* reserve more space in the skbuff for our header */
+ dev->hard_header_len = BAT_HEADER_LEN;
/* generate random address */
random_ether_addr(dev_addr);
@@ -548,7 +807,7 @@ struct net_device *softif_create(char *name)
goto out;
}
- ret = register_netdev(soft_iface);
+ ret = register_netdevice(soft_iface);
if (ret < 0) {
pr_err("Unable to register the batman interface '%s': %i\n",
name, ret);
@@ -572,11 +831,10 @@ struct net_device *softif_create(char *name)
atomic_set(&bat_priv->mesh_state, MESH_INACTIVE);
atomic_set(&bat_priv->bcast_seqno, 1);
- atomic_set(&bat_priv->hna_local_changed, 0);
+ atomic_set(&bat_priv->tt_local_changed, 0);
bat_priv->primary_if = NULL;
bat_priv->num_ifaces = 0;
- bat_priv->softif_neigh = NULL;
ret = sysfs_add_meshif(soft_iface);
if (ret < 0)
@@ -632,7 +890,7 @@ static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
cmd->supported = 0;
cmd->advertising = 0;
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
cmd->duplex = DUPLEX_FULL;
cmd->port = PORT_TP;
cmd->phy_address = 0;
@@ -667,12 +925,3 @@ static u32 bat_get_link(struct net_device *dev)
return 1;
}
-static u32 bat_get_rx_csum(struct net_device *dev)
-{
- return 0;
-}
-
-static int bat_set_rx_csum(struct net_device *dev, u32 data)
-{
- return -EOPNOTSUPP;
-}
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 8d15b48d169..7b729660cbf 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -22,43 +22,44 @@
#include "main.h"
#include "translation-table.h"
#include "soft-interface.h"
+#include "hard-interface.h"
#include "hash.h"
#include "originator.h"
-static void hna_local_purge(struct work_struct *work);
-static void _hna_global_del_orig(struct bat_priv *bat_priv,
- struct hna_global_entry *hna_global_entry,
+static void tt_local_purge(struct work_struct *work);
+static void _tt_global_del_orig(struct bat_priv *bat_priv,
+ struct tt_global_entry *tt_global_entry,
char *message);
/* returns 1 if they are the same mac addr */
-static int compare_lhna(struct hlist_node *node, void *data2)
+static int compare_ltt(struct hlist_node *node, void *data2)
{
- void *data1 = container_of(node, struct hna_local_entry, hash_entry);
+ void *data1 = container_of(node, struct tt_local_entry, hash_entry);
return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
}
/* returns 1 if they are the same mac addr */
-static int compare_ghna(struct hlist_node *node, void *data2)
+static int compare_gtt(struct hlist_node *node, void *data2)
{
- void *data1 = container_of(node, struct hna_global_entry, hash_entry);
+ void *data1 = container_of(node, struct tt_global_entry, hash_entry);
return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
}
-static void hna_local_start_timer(struct bat_priv *bat_priv)
+static void tt_local_start_timer(struct bat_priv *bat_priv)
{
- INIT_DELAYED_WORK(&bat_priv->hna_work, hna_local_purge);
- queue_delayed_work(bat_event_workqueue, &bat_priv->hna_work, 10 * HZ);
+ INIT_DELAYED_WORK(&bat_priv->tt_work, tt_local_purge);
+ queue_delayed_work(bat_event_workqueue, &bat_priv->tt_work, 10 * HZ);
}
-static struct hna_local_entry *hna_local_hash_find(struct bat_priv *bat_priv,
+static struct tt_local_entry *tt_local_hash_find(struct bat_priv *bat_priv,
void *data)
{
- struct hashtable_t *hash = bat_priv->hna_local_hash;
+ struct hashtable_t *hash = bat_priv->tt_local_hash;
struct hlist_head *head;
struct hlist_node *node;
- struct hna_local_entry *hna_local_entry, *hna_local_entry_tmp = NULL;
+ struct tt_local_entry *tt_local_entry, *tt_local_entry_tmp = NULL;
int index;
if (!hash)
@@ -68,26 +69,26 @@ static struct hna_local_entry *hna_local_hash_find(struct bat_priv *bat_priv,
head = &hash->table[index];
rcu_read_lock();
- hlist_for_each_entry_rcu(hna_local_entry, node, head, hash_entry) {
- if (!compare_eth(hna_local_entry, data))
+ hlist_for_each_entry_rcu(tt_local_entry, node, head, hash_entry) {
+ if (!compare_eth(tt_local_entry, data))
continue;
- hna_local_entry_tmp = hna_local_entry;
+ tt_local_entry_tmp = tt_local_entry;
break;
}
rcu_read_unlock();
- return hna_local_entry_tmp;
+ return tt_local_entry_tmp;
}
-static struct hna_global_entry *hna_global_hash_find(struct bat_priv *bat_priv,
+static struct tt_global_entry *tt_global_hash_find(struct bat_priv *bat_priv,
void *data)
{
- struct hashtable_t *hash = bat_priv->hna_global_hash;
+ struct hashtable_t *hash = bat_priv->tt_global_hash;
struct hlist_head *head;
struct hlist_node *node;
- struct hna_global_entry *hna_global_entry;
- struct hna_global_entry *hna_global_entry_tmp = NULL;
+ struct tt_global_entry *tt_global_entry;
+ struct tt_global_entry *tt_global_entry_tmp = NULL;
int index;
if (!hash)
@@ -97,125 +98,125 @@ static struct hna_global_entry *hna_global_hash_find(struct bat_priv *bat_priv,
head = &hash->table[index];
rcu_read_lock();
- hlist_for_each_entry_rcu(hna_global_entry, node, head, hash_entry) {
- if (!compare_eth(hna_global_entry, data))
+ hlist_for_each_entry_rcu(tt_global_entry, node, head, hash_entry) {
+ if (!compare_eth(tt_global_entry, data))
continue;
- hna_global_entry_tmp = hna_global_entry;
+ tt_global_entry_tmp = tt_global_entry;
break;
}
rcu_read_unlock();
- return hna_global_entry_tmp;
+ return tt_global_entry_tmp;
}
-int hna_local_init(struct bat_priv *bat_priv)
+int tt_local_init(struct bat_priv *bat_priv)
{
- if (bat_priv->hna_local_hash)
+ if (bat_priv->tt_local_hash)
return 1;
- bat_priv->hna_local_hash = hash_new(1024);
+ bat_priv->tt_local_hash = hash_new(1024);
- if (!bat_priv->hna_local_hash)
+ if (!bat_priv->tt_local_hash)
return 0;
- atomic_set(&bat_priv->hna_local_changed, 0);
- hna_local_start_timer(bat_priv);
+ atomic_set(&bat_priv->tt_local_changed, 0);
+ tt_local_start_timer(bat_priv);
return 1;
}
-void hna_local_add(struct net_device *soft_iface, uint8_t *addr)
+void tt_local_add(struct net_device *soft_iface, uint8_t *addr)
{
struct bat_priv *bat_priv = netdev_priv(soft_iface);
- struct hna_local_entry *hna_local_entry;
- struct hna_global_entry *hna_global_entry;
+ struct tt_local_entry *tt_local_entry;
+ struct tt_global_entry *tt_global_entry;
int required_bytes;
- spin_lock_bh(&bat_priv->hna_lhash_lock);
- hna_local_entry = hna_local_hash_find(bat_priv, addr);
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
+ tt_local_entry = tt_local_hash_find(bat_priv, addr);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
- if (hna_local_entry) {
- hna_local_entry->last_seen = jiffies;
+ if (tt_local_entry) {
+ tt_local_entry->last_seen = jiffies;
return;
}
/* only announce as many hosts as possible in the batman-packet and
- space in batman_packet->num_hna That also should give a limit to
+ space in batman_packet->num_tt That also should give a limit to
MAC-flooding. */
- required_bytes = (bat_priv->num_local_hna + 1) * ETH_ALEN;
+ required_bytes = (bat_priv->num_local_tt + 1) * ETH_ALEN;
required_bytes += BAT_PACKET_LEN;
if ((required_bytes > ETH_DATA_LEN) ||
(atomic_read(&bat_priv->aggregated_ogms) &&
required_bytes > MAX_AGGREGATION_BYTES) ||
- (bat_priv->num_local_hna + 1 > 255)) {
+ (bat_priv->num_local_tt + 1 > 255)) {
bat_dbg(DBG_ROUTES, bat_priv,
- "Can't add new local hna entry (%pM): "
- "number of local hna entries exceeds packet size\n",
+ "Can't add new local tt entry (%pM): "
+ "number of local tt entries exceeds packet size\n",
addr);
return;
}
bat_dbg(DBG_ROUTES, bat_priv,
- "Creating new local hna entry: %pM\n", addr);
+ "Creating new local tt entry: %pM\n", addr);
- hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC);
- if (!hna_local_entry)
+ tt_local_entry = kmalloc(sizeof(struct tt_local_entry), GFP_ATOMIC);
+ if (!tt_local_entry)
return;
- memcpy(hna_local_entry->addr, addr, ETH_ALEN);
- hna_local_entry->last_seen = jiffies;
+ memcpy(tt_local_entry->addr, addr, ETH_ALEN);
+ tt_local_entry->last_seen = jiffies;
/* the batman interface mac address should never be purged */
if (compare_eth(addr, soft_iface->dev_addr))
- hna_local_entry->never_purge = 1;
+ tt_local_entry->never_purge = 1;
else
- hna_local_entry->never_purge = 0;
+ tt_local_entry->never_purge = 0;
- spin_lock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
- hash_add(bat_priv->hna_local_hash, compare_lhna, choose_orig,
- hna_local_entry, &hna_local_entry->hash_entry);
- bat_priv->num_local_hna++;
- atomic_set(&bat_priv->hna_local_changed, 1);
+ hash_add(bat_priv->tt_local_hash, compare_ltt, choose_orig,
+ tt_local_entry, &tt_local_entry->hash_entry);
+ bat_priv->num_local_tt++;
+ atomic_set(&bat_priv->tt_local_changed, 1);
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
/* remove address from global hash if present */
- spin_lock_bh(&bat_priv->hna_ghash_lock);
+ spin_lock_bh(&bat_priv->tt_ghash_lock);
- hna_global_entry = hna_global_hash_find(bat_priv, addr);
+ tt_global_entry = tt_global_hash_find(bat_priv, addr);
- if (hna_global_entry)
- _hna_global_del_orig(bat_priv, hna_global_entry,
- "local hna received");
+ if (tt_global_entry)
+ _tt_global_del_orig(bat_priv, tt_global_entry,
+ "local tt received");
- spin_unlock_bh(&bat_priv->hna_ghash_lock);
+ spin_unlock_bh(&bat_priv->tt_ghash_lock);
}
-int hna_local_fill_buffer(struct bat_priv *bat_priv,
+int tt_local_fill_buffer(struct bat_priv *bat_priv,
unsigned char *buff, int buff_len)
{
- struct hashtable_t *hash = bat_priv->hna_local_hash;
- struct hna_local_entry *hna_local_entry;
+ struct hashtable_t *hash = bat_priv->tt_local_hash;
+ struct tt_local_entry *tt_local_entry;
struct hlist_node *node;
struct hlist_head *head;
int i, count = 0;
- spin_lock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
rcu_read_lock();
- hlist_for_each_entry_rcu(hna_local_entry, node,
+ hlist_for_each_entry_rcu(tt_local_entry, node,
head, hash_entry) {
if (buff_len < (count + 1) * ETH_ALEN)
break;
- memcpy(buff + (count * ETH_ALEN), hna_local_entry->addr,
+ memcpy(buff + (count * ETH_ALEN), tt_local_entry->addr,
ETH_ALEN);
count++;
@@ -223,37 +224,47 @@ int hna_local_fill_buffer(struct bat_priv *bat_priv,
rcu_read_unlock();
}
- /* if we did not get all new local hnas see you next time ;-) */
- if (count == bat_priv->num_local_hna)
- atomic_set(&bat_priv->hna_local_changed, 0);
+ /* if we did not get all new local tts see you next time ;-) */
+ if (count == bat_priv->num_local_tt)
+ atomic_set(&bat_priv->tt_local_changed, 0);
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
return count;
}
-int hna_local_seq_print_text(struct seq_file *seq, void *offset)
+int tt_local_seq_print_text(struct seq_file *seq, void *offset)
{
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
- struct hashtable_t *hash = bat_priv->hna_local_hash;
- struct hna_local_entry *hna_local_entry;
+ struct hashtable_t *hash = bat_priv->tt_local_hash;
+ struct tt_local_entry *tt_local_entry;
+ struct hard_iface *primary_if;
struct hlist_node *node;
struct hlist_head *head;
size_t buf_size, pos;
char *buff;
- int i;
+ int i, ret = 0;
- if (!bat_priv->primary_if) {
- return seq_printf(seq, "BATMAN mesh %s disabled - "
- "please specify interfaces to enable it\n",
- net_dev->name);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
+ goto out;
+ }
+
+ if (primary_if->if_status != IF_ACTIVE) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "primary interface not active\n",
+ net_dev->name);
+ goto out;
}
seq_printf(seq, "Locally retrieved addresses (from %s) "
- "announced via HNA:\n",
+ "announced via TT:\n",
net_dev->name);
- spin_lock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
buf_size = 1;
/* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */
@@ -268,8 +279,9 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset)
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
- return -ENOMEM;
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
+ ret = -ENOMEM;
+ goto out;
}
buff[0] = '\0';
@@ -279,211 +291,225 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset)
head = &hash->table[i];
rcu_read_lock();
- hlist_for_each_entry_rcu(hna_local_entry, node,
+ hlist_for_each_entry_rcu(tt_local_entry, node,
head, hash_entry) {
pos += snprintf(buff + pos, 22, " * %pM\n",
- hna_local_entry->addr);
+ tt_local_entry->addr);
}
rcu_read_unlock();
}
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
seq_printf(seq, "%s", buff);
kfree(buff);
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
-static void _hna_local_del(struct hlist_node *node, void *arg)
+static void _tt_local_del(struct hlist_node *node, void *arg)
{
struct bat_priv *bat_priv = (struct bat_priv *)arg;
- void *data = container_of(node, struct hna_local_entry, hash_entry);
+ void *data = container_of(node, struct tt_local_entry, hash_entry);
kfree(data);
- bat_priv->num_local_hna--;
- atomic_set(&bat_priv->hna_local_changed, 1);
+ bat_priv->num_local_tt--;
+ atomic_set(&bat_priv->tt_local_changed, 1);
}
-static void hna_local_del(struct bat_priv *bat_priv,
- struct hna_local_entry *hna_local_entry,
+static void tt_local_del(struct bat_priv *bat_priv,
+ struct tt_local_entry *tt_local_entry,
char *message)
{
- bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n",
- hna_local_entry->addr, message);
+ bat_dbg(DBG_ROUTES, bat_priv, "Deleting local tt entry (%pM): %s\n",
+ tt_local_entry->addr, message);
- hash_remove(bat_priv->hna_local_hash, compare_lhna, choose_orig,
- hna_local_entry->addr);
- _hna_local_del(&hna_local_entry->hash_entry, bat_priv);
+ hash_remove(bat_priv->tt_local_hash, compare_ltt, choose_orig,
+ tt_local_entry->addr);
+ _tt_local_del(&tt_local_entry->hash_entry, bat_priv);
}
-void hna_local_remove(struct bat_priv *bat_priv,
+void tt_local_remove(struct bat_priv *bat_priv,
uint8_t *addr, char *message)
{
- struct hna_local_entry *hna_local_entry;
+ struct tt_local_entry *tt_local_entry;
- spin_lock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
- hna_local_entry = hna_local_hash_find(bat_priv, addr);
+ tt_local_entry = tt_local_hash_find(bat_priv, addr);
- if (hna_local_entry)
- hna_local_del(bat_priv, hna_local_entry, message);
+ if (tt_local_entry)
+ tt_local_del(bat_priv, tt_local_entry, message);
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
}
-static void hna_local_purge(struct work_struct *work)
+static void tt_local_purge(struct work_struct *work)
{
struct delayed_work *delayed_work =
container_of(work, struct delayed_work, work);
struct bat_priv *bat_priv =
- container_of(delayed_work, struct bat_priv, hna_work);
- struct hashtable_t *hash = bat_priv->hna_local_hash;
- struct hna_local_entry *hna_local_entry;
+ container_of(delayed_work, struct bat_priv, tt_work);
+ struct hashtable_t *hash = bat_priv->tt_local_hash;
+ struct tt_local_entry *tt_local_entry;
struct hlist_node *node, *node_tmp;
struct hlist_head *head;
unsigned long timeout;
int i;
- spin_lock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
- hlist_for_each_entry_safe(hna_local_entry, node, node_tmp,
+ hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
head, hash_entry) {
- if (hna_local_entry->never_purge)
+ if (tt_local_entry->never_purge)
continue;
- timeout = hna_local_entry->last_seen;
- timeout += LOCAL_HNA_TIMEOUT * HZ;
+ timeout = tt_local_entry->last_seen;
+ timeout += TT_LOCAL_TIMEOUT * HZ;
if (time_before(jiffies, timeout))
continue;
- hna_local_del(bat_priv, hna_local_entry,
+ tt_local_del(bat_priv, tt_local_entry,
"address timed out");
}
}
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
- hna_local_start_timer(bat_priv);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
+ tt_local_start_timer(bat_priv);
}
-void hna_local_free(struct bat_priv *bat_priv)
+void tt_local_free(struct bat_priv *bat_priv)
{
- if (!bat_priv->hna_local_hash)
+ if (!bat_priv->tt_local_hash)
return;
- cancel_delayed_work_sync(&bat_priv->hna_work);
- hash_delete(bat_priv->hna_local_hash, _hna_local_del, bat_priv);
- bat_priv->hna_local_hash = NULL;
+ cancel_delayed_work_sync(&bat_priv->tt_work);
+ hash_delete(bat_priv->tt_local_hash, _tt_local_del, bat_priv);
+ bat_priv->tt_local_hash = NULL;
}
-int hna_global_init(struct bat_priv *bat_priv)
+int tt_global_init(struct bat_priv *bat_priv)
{
- if (bat_priv->hna_global_hash)
+ if (bat_priv->tt_global_hash)
return 1;
- bat_priv->hna_global_hash = hash_new(1024);
+ bat_priv->tt_global_hash = hash_new(1024);
- if (!bat_priv->hna_global_hash)
+ if (!bat_priv->tt_global_hash)
return 0;
return 1;
}
-void hna_global_add_orig(struct bat_priv *bat_priv,
+void tt_global_add_orig(struct bat_priv *bat_priv,
struct orig_node *orig_node,
- unsigned char *hna_buff, int hna_buff_len)
+ unsigned char *tt_buff, int tt_buff_len)
{
- struct hna_global_entry *hna_global_entry;
- struct hna_local_entry *hna_local_entry;
- int hna_buff_count = 0;
- unsigned char *hna_ptr;
+ struct tt_global_entry *tt_global_entry;
+ struct tt_local_entry *tt_local_entry;
+ int tt_buff_count = 0;
+ unsigned char *tt_ptr;
- while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) {
- spin_lock_bh(&bat_priv->hna_ghash_lock);
+ while ((tt_buff_count + 1) * ETH_ALEN <= tt_buff_len) {
+ spin_lock_bh(&bat_priv->tt_ghash_lock);
- hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN);
- hna_global_entry = hna_global_hash_find(bat_priv, hna_ptr);
+ tt_ptr = tt_buff + (tt_buff_count * ETH_ALEN);
+ tt_global_entry = tt_global_hash_find(bat_priv, tt_ptr);
- if (!hna_global_entry) {
- spin_unlock_bh(&bat_priv->hna_ghash_lock);
+ if (!tt_global_entry) {
+ spin_unlock_bh(&bat_priv->tt_ghash_lock);
- hna_global_entry =
- kmalloc(sizeof(struct hna_global_entry),
+ tt_global_entry =
+ kmalloc(sizeof(struct tt_global_entry),
GFP_ATOMIC);
- if (!hna_global_entry)
+ if (!tt_global_entry)
break;
- memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN);
+ memcpy(tt_global_entry->addr, tt_ptr, ETH_ALEN);
bat_dbg(DBG_ROUTES, bat_priv,
- "Creating new global hna entry: "
+ "Creating new global tt entry: "
"%pM (via %pM)\n",
- hna_global_entry->addr, orig_node->orig);
+ tt_global_entry->addr, orig_node->orig);
- spin_lock_bh(&bat_priv->hna_ghash_lock);
- hash_add(bat_priv->hna_global_hash, compare_ghna,
- choose_orig, hna_global_entry,
- &hna_global_entry->hash_entry);
+ spin_lock_bh(&bat_priv->tt_ghash_lock);
+ hash_add(bat_priv->tt_global_hash, compare_gtt,
+ choose_orig, tt_global_entry,
+ &tt_global_entry->hash_entry);
}
- hna_global_entry->orig_node = orig_node;
- spin_unlock_bh(&bat_priv->hna_ghash_lock);
+ tt_global_entry->orig_node = orig_node;
+ spin_unlock_bh(&bat_priv->tt_ghash_lock);
/* remove address from local hash if present */
- spin_lock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
- hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN);
- hna_local_entry = hna_local_hash_find(bat_priv, hna_ptr);
+ tt_ptr = tt_buff + (tt_buff_count * ETH_ALEN);
+ tt_local_entry = tt_local_hash_find(bat_priv, tt_ptr);
- if (hna_local_entry)
- hna_local_del(bat_priv, hna_local_entry,
- "global hna received");
+ if (tt_local_entry)
+ tt_local_del(bat_priv, tt_local_entry,
+ "global tt received");
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
- hna_buff_count++;
+ tt_buff_count++;
}
/* initialize, and overwrite if malloc succeeds */
- orig_node->hna_buff = NULL;
- orig_node->hna_buff_len = 0;
-
- if (hna_buff_len > 0) {
- orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC);
- if (orig_node->hna_buff) {
- memcpy(orig_node->hna_buff, hna_buff, hna_buff_len);
- orig_node->hna_buff_len = hna_buff_len;
+ orig_node->tt_buff = NULL;
+ orig_node->tt_buff_len = 0;
+
+ if (tt_buff_len > 0) {
+ orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC);
+ if (orig_node->tt_buff) {
+ memcpy(orig_node->tt_buff, tt_buff, tt_buff_len);
+ orig_node->tt_buff_len = tt_buff_len;
}
}
}
-int hna_global_seq_print_text(struct seq_file *seq, void *offset)
+int tt_global_seq_print_text(struct seq_file *seq, void *offset)
{
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
- struct hashtable_t *hash = bat_priv->hna_global_hash;
- struct hna_global_entry *hna_global_entry;
+ struct hashtable_t *hash = bat_priv->tt_global_hash;
+ struct tt_global_entry *tt_global_entry;
+ struct hard_iface *primary_if;
struct hlist_node *node;
struct hlist_head *head;
size_t buf_size, pos;
char *buff;
- int i;
+ int i, ret = 0;
- if (!bat_priv->primary_if) {
- return seq_printf(seq, "BATMAN mesh %s disabled - "
- "please specify interfaces to enable it\n",
- net_dev->name);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - please "
+ "specify interfaces to enable it\n",
+ net_dev->name);
+ goto out;
}
- seq_printf(seq, "Globally announced HNAs received via the mesh %s\n",
+ if (primary_if->if_status != IF_ACTIVE) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "primary interface not active\n",
+ net_dev->name);
+ goto out;
+ }
+
+ seq_printf(seq,
+ "Globally announced TT entries received via the mesh %s\n",
net_dev->name);
- spin_lock_bh(&bat_priv->hna_ghash_lock);
+ spin_lock_bh(&bat_priv->tt_ghash_lock);
buf_size = 1;
/* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/
@@ -498,8 +524,9 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset)
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
- spin_unlock_bh(&bat_priv->hna_ghash_lock);
- return -ENOMEM;
+ spin_unlock_bh(&bat_priv->tt_ghash_lock);
+ ret = -ENOMEM;
+ goto out;
}
buff[0] = '\0';
pos = 0;
@@ -508,101 +535,104 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset)
head = &hash->table[i];
rcu_read_lock();
- hlist_for_each_entry_rcu(hna_global_entry, node,
+ hlist_for_each_entry_rcu(tt_global_entry, node,
head, hash_entry) {
pos += snprintf(buff + pos, 44,
" * %pM via %pM\n",
- hna_global_entry->addr,
- hna_global_entry->orig_node->orig);
+ tt_global_entry->addr,
+ tt_global_entry->orig_node->orig);
}
rcu_read_unlock();
}
- spin_unlock_bh(&bat_priv->hna_ghash_lock);
+ spin_unlock_bh(&bat_priv->tt_ghash_lock);
seq_printf(seq, "%s", buff);
kfree(buff);
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
-static void _hna_global_del_orig(struct bat_priv *bat_priv,
- struct hna_global_entry *hna_global_entry,
+static void _tt_global_del_orig(struct bat_priv *bat_priv,
+ struct tt_global_entry *tt_global_entry,
char *message)
{
bat_dbg(DBG_ROUTES, bat_priv,
- "Deleting global hna entry %pM (via %pM): %s\n",
- hna_global_entry->addr, hna_global_entry->orig_node->orig,
+ "Deleting global tt entry %pM (via %pM): %s\n",
+ tt_global_entry->addr, tt_global_entry->orig_node->orig,
message);
- hash_remove(bat_priv->hna_global_hash, compare_ghna, choose_orig,
- hna_global_entry->addr);
- kfree(hna_global_entry);
+ hash_remove(bat_priv->tt_global_hash, compare_gtt, choose_orig,
+ tt_global_entry->addr);
+ kfree(tt_global_entry);
}
-void hna_global_del_orig(struct bat_priv *bat_priv,
+void tt_global_del_orig(struct bat_priv *bat_priv,
struct orig_node *orig_node, char *message)
{
- struct hna_global_entry *hna_global_entry;
- int hna_buff_count = 0;
- unsigned char *hna_ptr;
+ struct tt_global_entry *tt_global_entry;
+ int tt_buff_count = 0;
+ unsigned char *tt_ptr;
- if (orig_node->hna_buff_len == 0)
+ if (orig_node->tt_buff_len == 0)
return;
- spin_lock_bh(&bat_priv->hna_ghash_lock);
+ spin_lock_bh(&bat_priv->tt_ghash_lock);
- while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) {
- hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN);
- hna_global_entry = hna_global_hash_find(bat_priv, hna_ptr);
+ while ((tt_buff_count + 1) * ETH_ALEN <= orig_node->tt_buff_len) {
+ tt_ptr = orig_node->tt_buff + (tt_buff_count * ETH_ALEN);
+ tt_global_entry = tt_global_hash_find(bat_priv, tt_ptr);
- if ((hna_global_entry) &&
- (hna_global_entry->orig_node == orig_node))
- _hna_global_del_orig(bat_priv, hna_global_entry,
+ if ((tt_global_entry) &&
+ (tt_global_entry->orig_node == orig_node))
+ _tt_global_del_orig(bat_priv, tt_global_entry,
message);
- hna_buff_count++;
+ tt_buff_count++;
}
- spin_unlock_bh(&bat_priv->hna_ghash_lock);
+ spin_unlock_bh(&bat_priv->tt_ghash_lock);
- orig_node->hna_buff_len = 0;
- kfree(orig_node->hna_buff);
- orig_node->hna_buff = NULL;
+ orig_node->tt_buff_len = 0;
+ kfree(orig_node->tt_buff);
+ orig_node->tt_buff = NULL;
}
-static void hna_global_del(struct hlist_node *node, void *arg)
+static void tt_global_del(struct hlist_node *node, void *arg)
{
- void *data = container_of(node, struct hna_global_entry, hash_entry);
+ void *data = container_of(node, struct tt_global_entry, hash_entry);
kfree(data);
}
-void hna_global_free(struct bat_priv *bat_priv)
+void tt_global_free(struct bat_priv *bat_priv)
{
- if (!bat_priv->hna_global_hash)
+ if (!bat_priv->tt_global_hash)
return;
- hash_delete(bat_priv->hna_global_hash, hna_global_del, NULL);
- bat_priv->hna_global_hash = NULL;
+ hash_delete(bat_priv->tt_global_hash, tt_global_del, NULL);
+ bat_priv->tt_global_hash = NULL;
}
struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr)
{
- struct hna_global_entry *hna_global_entry;
+ struct tt_global_entry *tt_global_entry;
struct orig_node *orig_node = NULL;
- spin_lock_bh(&bat_priv->hna_ghash_lock);
- hna_global_entry = hna_global_hash_find(bat_priv, addr);
+ spin_lock_bh(&bat_priv->tt_ghash_lock);
+ tt_global_entry = tt_global_hash_find(bat_priv, addr);
- if (!hna_global_entry)
+ if (!tt_global_entry)
goto out;
- if (!atomic_inc_not_zero(&hna_global_entry->orig_node->refcount))
+ if (!atomic_inc_not_zero(&tt_global_entry->orig_node->refcount))
goto out;
- orig_node = hna_global_entry->orig_node;
+ orig_node = tt_global_entry->orig_node;
out:
- spin_unlock_bh(&bat_priv->hna_ghash_lock);
+ spin_unlock_bh(&bat_priv->tt_ghash_lock);
return orig_node;
}
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index f19931ca145..46152c38cc9 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -22,22 +22,22 @@
#ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
-int hna_local_init(struct bat_priv *bat_priv);
-void hna_local_add(struct net_device *soft_iface, uint8_t *addr);
-void hna_local_remove(struct bat_priv *bat_priv,
+int tt_local_init(struct bat_priv *bat_priv);
+void tt_local_add(struct net_device *soft_iface, uint8_t *addr);
+void tt_local_remove(struct bat_priv *bat_priv,
uint8_t *addr, char *message);
-int hna_local_fill_buffer(struct bat_priv *bat_priv,
+int tt_local_fill_buffer(struct bat_priv *bat_priv,
unsigned char *buff, int buff_len);
-int hna_local_seq_print_text(struct seq_file *seq, void *offset);
-void hna_local_free(struct bat_priv *bat_priv);
-int hna_global_init(struct bat_priv *bat_priv);
-void hna_global_add_orig(struct bat_priv *bat_priv,
+int tt_local_seq_print_text(struct seq_file *seq, void *offset);
+void tt_local_free(struct bat_priv *bat_priv);
+int tt_global_init(struct bat_priv *bat_priv);
+void tt_global_add_orig(struct bat_priv *bat_priv,
struct orig_node *orig_node,
- unsigned char *hna_buff, int hna_buff_len);
-int hna_global_seq_print_text(struct seq_file *seq, void *offset);
-void hna_global_del_orig(struct bat_priv *bat_priv,
+ unsigned char *tt_buff, int tt_buff_len);
+int tt_global_seq_print_text(struct seq_file *seq, void *offset);
+void tt_global_del_orig(struct bat_priv *bat_priv,
struct orig_node *orig_node, char *message);
-void hna_global_free(struct bat_priv *bat_priv);
+void tt_global_free(struct bat_priv *bat_priv);
struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr);
#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 83445cf0cc9..fab70e8b16e 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -67,7 +67,7 @@ struct hard_iface {
struct orig_node {
uint8_t orig[ETH_ALEN];
uint8_t primary_addr[ETH_ALEN];
- struct neigh_node *router;
+ struct neigh_node __rcu *router; /* rcu protected pointer */
unsigned long *bcast_own;
uint8_t *bcast_own_sum;
unsigned long last_valid;
@@ -75,25 +75,25 @@ struct orig_node {
unsigned long batman_seqno_reset;
uint8_t gw_flags;
uint8_t flags;
- unsigned char *hna_buff;
- int16_t hna_buff_len;
+ unsigned char *tt_buff;
+ int16_t tt_buff_len;
uint32_t last_real_seqno;
uint8_t last_ttl;
unsigned long bcast_bits[NUM_WORDS];
uint32_t last_bcast_seqno;
struct hlist_head neigh_list;
struct list_head frag_list;
- spinlock_t neigh_list_lock; /* protects neighbor list */
+ spinlock_t neigh_list_lock; /* protects neigh_list and router */
atomic_t refcount;
struct rcu_head rcu;
struct hlist_node hash_entry;
struct bat_priv *bat_priv;
unsigned long last_frag_packet;
- spinlock_t ogm_cnt_lock; /* protects: bcast_own, bcast_own_sum,
- * neigh_node->real_bits,
- * neigh_node->real_packet_count */
- spinlock_t bcast_seqno_lock; /* protects bcast_bits,
- * last_bcast_seqno */
+ /* ogm_cnt_lock protects: bcast_own, bcast_own_sum,
+ * neigh_node->real_bits, neigh_node->real_packet_count */
+ spinlock_t ogm_cnt_lock;
+ /* bcast_seqno_lock protects bcast_bits, last_bcast_seqno */
+ spinlock_t bcast_seqno_lock;
atomic_t bond_candidates;
struct list_head bond_list;
};
@@ -125,6 +125,7 @@ struct neigh_node {
struct rcu_head rcu;
struct orig_node *orig_node;
struct hard_iface *if_incoming;
+ spinlock_t tq_lock; /* protects: tq_recv, tq_index */
};
@@ -145,34 +146,34 @@ struct bat_priv {
atomic_t bcast_queue_left;
atomic_t batman_queue_left;
char num_ifaces;
- struct hlist_head softif_neigh_list;
- struct softif_neigh *softif_neigh;
struct debug_log *debug_log;
- struct hard_iface *primary_if;
struct kobject *mesh_obj;
struct dentry *debug_dir;
struct hlist_head forw_bat_list;
struct hlist_head forw_bcast_list;
struct hlist_head gw_list;
+ struct hlist_head softif_neigh_vids;
struct list_head vis_send_list;
struct hashtable_t *orig_hash;
- struct hashtable_t *hna_local_hash;
- struct hashtable_t *hna_global_hash;
+ struct hashtable_t *tt_local_hash;
+ struct hashtable_t *tt_global_hash;
struct hashtable_t *vis_hash;
spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
spinlock_t forw_bcast_list_lock; /* protects */
- spinlock_t hna_lhash_lock; /* protects hna_local_hash */
- spinlock_t hna_ghash_lock; /* protects hna_global_hash */
+ spinlock_t tt_lhash_lock; /* protects tt_local_hash */
+ spinlock_t tt_ghash_lock; /* protects tt_global_hash */
spinlock_t gw_list_lock; /* protects gw_list and curr_gw */
spinlock_t vis_hash_lock; /* protects vis_hash */
spinlock_t vis_list_lock; /* protects vis_info::recv_list */
spinlock_t softif_neigh_lock; /* protects soft-interface neigh list */
- int16_t num_local_hna;
- atomic_t hna_local_changed;
- struct delayed_work hna_work;
+ spinlock_t softif_neigh_vid_lock; /* protects soft-interface vid list */
+ int16_t num_local_tt;
+ atomic_t tt_local_changed;
+ struct delayed_work tt_work;
struct delayed_work orig_work;
struct delayed_work vis_work;
struct gw_node __rcu *curr_gw; /* rcu protected pointer */
+ struct hard_iface __rcu *primary_if; /* rcu protected pointer */
struct vis_info *my_vis_info;
};
@@ -191,14 +192,14 @@ struct socket_packet {
struct icmp_packet_rr icmp_packet;
};
-struct hna_local_entry {
+struct tt_local_entry {
uint8_t addr[ETH_ALEN];
unsigned long last_seen;
char never_purge;
struct hlist_node hash_entry;
};
-struct hna_global_entry {
+struct tt_global_entry {
uint8_t addr[ETH_ALEN];
struct orig_node *orig_node;
struct hlist_node hash_entry;
@@ -261,7 +262,7 @@ struct vis_info {
struct vis_info_entry {
uint8_t src[ETH_ALEN];
uint8_t dest[ETH_ALEN];
- uint8_t quality; /* quality = 0 means HNA */
+ uint8_t quality; /* quality = 0 client */
} __packed;
struct recvlist_node {
@@ -269,11 +270,20 @@ struct recvlist_node {
uint8_t mac[ETH_ALEN];
};
+struct softif_neigh_vid {
+ struct hlist_node list;
+ struct bat_priv *bat_priv;
+ short vid;
+ atomic_t refcount;
+ struct softif_neigh __rcu *softif_neigh;
+ struct rcu_head rcu;
+ struct hlist_head softif_neigh_list;
+};
+
struct softif_neigh {
struct hlist_node list;
uint8_t addr[ETH_ALEN];
unsigned long last_seen;
- short vid;
atomic_t refcount;
struct rcu_head rcu;
};
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
index 19f84bd443a..19c3daf34ac 100644
--- a/net/batman-adv/unicast.c
+++ b/net/batman-adv/unicast.c
@@ -221,15 +221,17 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
struct hard_iface *hard_iface, uint8_t dstaddr[])
{
struct unicast_packet tmp_uc, *unicast_packet;
+ struct hard_iface *primary_if;
struct sk_buff *frag_skb;
struct unicast_frag_packet *frag1, *frag2;
int uc_hdr_len = sizeof(struct unicast_packet);
int ucf_hdr_len = sizeof(struct unicast_frag_packet);
int data_len = skb->len - uc_hdr_len;
- int large_tail = 0;
+ int large_tail = 0, ret = NET_RX_DROP;
uint16_t seqno;
- if (!bat_priv->primary_if)
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
goto dropped;
frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len);
@@ -254,7 +256,7 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
frag1->version = COMPAT_VERSION;
frag1->packet_type = BAT_UNICAST_FRAG;
- memcpy(frag1->orig, bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(frag1->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
memcpy(frag2, frag1, sizeof(struct unicast_frag_packet));
if (data_len & 1)
@@ -269,13 +271,17 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
send_skb_packet(skb, hard_iface, dstaddr);
send_skb_packet(frag_skb, hard_iface, dstaddr);
- return NET_RX_SUCCESS;
+ ret = NET_RX_SUCCESS;
+ goto out;
drop_frag:
kfree_skb(frag_skb);
dropped:
kfree_skb(skb);
- return NET_RX_DROP;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
@@ -289,12 +295,12 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
/* get routing information */
if (is_multicast_ether_addr(ethhdr->h_dest)) {
- orig_node = (struct orig_node *)gw_get_selected(bat_priv);
+ orig_node = (struct orig_node *)gw_get_selected_orig(bat_priv);
if (orig_node)
goto find_router;
}
- /* check for hna host - increases orig_node refcount */
+ /* check for tt host - increases orig_node refcount */
orig_node = transtable_search(bat_priv, ethhdr->h_dest);
find_router:
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index f90212f4208..c39f20cc1ba 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -194,7 +194,7 @@ static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
{
/* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */
if (primary && entry->quality == 0)
- return sprintf(buff, "HNA %pM, ", entry->dest);
+ return sprintf(buff, "TT %pM, ", entry->dest);
else if (compare_eth(entry->src, src))
return sprintf(buff, "TQ %pM %d, ", entry->dest,
entry->quality);
@@ -204,6 +204,7 @@ static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
int vis_seq_print_text(struct seq_file *seq, void *offset)
{
+ struct hard_iface *primary_if;
struct hlist_node *node;
struct hlist_head *head;
struct vis_info *info;
@@ -215,15 +216,18 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
HLIST_HEAD(vis_if_list);
struct if_list_entry *entry;
struct hlist_node *pos, *n;
- int i, j;
+ int i, j, ret = 0;
int vis_server = atomic_read(&bat_priv->vis_mode);
size_t buff_pos, buf_size;
char *buff;
int compare;
- if ((!bat_priv->primary_if) ||
- (vis_server == VIS_TYPE_CLIENT_UPDATE))
- return 0;
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
+
+ if (vis_server == VIS_TYPE_CLIENT_UPDATE)
+ goto out;
buf_size = 1;
/* Estimate length */
@@ -270,7 +274,8 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
spin_unlock_bh(&bat_priv->vis_hash_lock);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out;
}
buff[0] = '\0';
buff_pos = 0;
@@ -328,7 +333,10 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
seq_printf(seq, "%s", buff);
kfree(buff);
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
/* add the info packet to the send list, if it was not
@@ -558,6 +566,7 @@ static int find_best_vis_server(struct bat_priv *bat_priv,
struct vis_info *info)
{
struct hashtable_t *hash = bat_priv->orig_hash;
+ struct neigh_node *router;
struct hlist_node *node;
struct hlist_head *head;
struct orig_node *orig_node;
@@ -571,13 +580,17 @@ static int find_best_vis_server(struct bat_priv *bat_priv,
rcu_read_lock();
hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
- if ((orig_node) && (orig_node->router) &&
- (orig_node->flags & VIS_SERVER) &&
- (orig_node->router->tq_avg > best_tq)) {
- best_tq = orig_node->router->tq_avg;
+ router = orig_node_get_router(orig_node);
+ if (!router)
+ continue;
+
+ if ((orig_node->flags & VIS_SERVER) &&
+ (router->tq_avg > best_tq)) {
+ best_tq = router->tq_avg;
memcpy(packet->target_orig, orig_node->orig,
ETH_ALEN);
}
+ neigh_node_free_ref(router);
}
rcu_read_unlock();
}
@@ -605,11 +618,11 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
struct hlist_node *node;
struct hlist_head *head;
struct orig_node *orig_node;
- struct neigh_node *neigh_node;
+ struct neigh_node *router;
struct vis_info *info = (struct vis_info *)bat_priv->my_vis_info;
struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data;
struct vis_info_entry *entry;
- struct hna_local_entry *hna_local_entry;
+ struct tt_local_entry *tt_local_entry;
int best_tq = -1, i;
info->first_seen = jiffies;
@@ -633,59 +646,61 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
rcu_read_lock();
hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
- neigh_node = orig_node->router;
-
- if (!neigh_node)
+ router = orig_node_get_router(orig_node);
+ if (!router)
continue;
- if (!compare_eth(neigh_node->addr, orig_node->orig))
- continue;
+ if (!compare_eth(router->addr, orig_node->orig))
+ goto next;
- if (neigh_node->if_incoming->if_status != IF_ACTIVE)
- continue;
+ if (router->if_incoming->if_status != IF_ACTIVE)
+ goto next;
- if (neigh_node->tq_avg < 1)
- continue;
+ if (router->tq_avg < 1)
+ goto next;
/* fill one entry into buffer. */
entry = (struct vis_info_entry *)
skb_put(info->skb_packet, sizeof(*entry));
memcpy(entry->src,
- neigh_node->if_incoming->net_dev->dev_addr,
+ router->if_incoming->net_dev->dev_addr,
ETH_ALEN);
memcpy(entry->dest, orig_node->orig, ETH_ALEN);
- entry->quality = neigh_node->tq_avg;
+ entry->quality = router->tq_avg;
packet->entries++;
+next:
+ neigh_node_free_ref(router);
+
if (vis_packet_full(info))
goto unlock;
}
rcu_read_unlock();
}
- hash = bat_priv->hna_local_hash;
+ hash = bat_priv->tt_local_hash;
- spin_lock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
- hlist_for_each_entry(hna_local_entry, node, head, hash_entry) {
+ hlist_for_each_entry(tt_local_entry, node, head, hash_entry) {
entry = (struct vis_info_entry *)
skb_put(info->skb_packet,
sizeof(*entry));
memset(entry->src, 0, ETH_ALEN);
- memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN);
- entry->quality = 0; /* 0 means HNA */
+ memcpy(entry->dest, tt_local_entry->addr, ETH_ALEN);
+ entry->quality = 0; /* 0 means TT */
packet->entries++;
if (vis_packet_full(info)) {
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
return 0;
}
}
}
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
return 0;
unlock:
@@ -725,6 +740,7 @@ static void purge_vis_packets(struct bat_priv *bat_priv)
static void broadcast_vis_packet(struct bat_priv *bat_priv,
struct vis_info *info)
{
+ struct neigh_node *router;
struct hashtable_t *hash = bat_priv->orig_hash;
struct hlist_node *node;
struct hlist_head *head;
@@ -745,19 +761,26 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv,
rcu_read_lock();
hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
/* if it's a vis server and reachable, send it. */
- if ((!orig_node) || (!orig_node->router))
- continue;
if (!(orig_node->flags & VIS_SERVER))
continue;
+
+ router = orig_node_get_router(orig_node);
+ if (!router)
+ continue;
+
/* don't send it if we already received the packet from
- * this node. */
+ * this node. */
if (recv_list_is_in(bat_priv, &info->recv_list,
- orig_node->orig))
+ orig_node->orig)) {
+ neigh_node_free_ref(router);
continue;
+ }
memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
- hard_iface = orig_node->router->if_incoming;
- memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+ hard_iface = router->if_incoming;
+ memcpy(dstaddr, router->addr, ETH_ALEN);
+
+ neigh_node_free_ref(router);
skb = skb_clone(info->skb_packet, GFP_ATOMIC);
if (skb)
@@ -772,60 +795,48 @@ static void unicast_vis_packet(struct bat_priv *bat_priv,
struct vis_info *info)
{
struct orig_node *orig_node;
- struct neigh_node *neigh_node = NULL;
+ struct neigh_node *router = NULL;
struct sk_buff *skb;
struct vis_packet *packet;
packet = (struct vis_packet *)info->skb_packet->data;
- rcu_read_lock();
orig_node = orig_hash_find(bat_priv, packet->target_orig);
-
if (!orig_node)
- goto unlock;
-
- neigh_node = orig_node->router;
+ goto out;
- if (!neigh_node)
- goto unlock;
-
- if (!atomic_inc_not_zero(&neigh_node->refcount)) {
- neigh_node = NULL;
- goto unlock;
- }
-
- rcu_read_unlock();
+ router = orig_node_get_router(orig_node);
+ if (!router)
+ goto out;
skb = skb_clone(info->skb_packet, GFP_ATOMIC);
if (skb)
- send_skb_packet(skb, neigh_node->if_incoming,
- neigh_node->addr);
+ send_skb_packet(skb, router->if_incoming, router->addr);
- goto out;
-
-unlock:
- rcu_read_unlock();
out:
- if (neigh_node)
- neigh_node_free_ref(neigh_node);
+ if (router)
+ neigh_node_free_ref(router);
if (orig_node)
orig_node_free_ref(orig_node);
- return;
}
/* only send one vis packet. called from send_vis_packets() */
static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
{
+ struct hard_iface *primary_if;
struct vis_packet *packet;
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
+
packet = (struct vis_packet *)info->skb_packet->data;
if (packet->ttl < 2) {
pr_debug("Error - can't send vis packet: ttl exceeded\n");
- return;
+ goto out;
}
- memcpy(packet->sender_orig, bat_priv->primary_if->net_dev->dev_addr,
- ETH_ALEN);
+ memcpy(packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
packet->ttl--;
if (is_broadcast_ether_addr(packet->target_orig))
@@ -833,6 +844,10 @@ static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
else
unicast_vis_packet(bat_priv, info);
packet->ttl++; /* restore TTL */
+
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
}
/* called from timer; send (and maybe generate) vis packet. */
@@ -859,8 +874,7 @@ static void send_vis_packets(struct work_struct *work)
kref_get(&info->refcount);
spin_unlock_bh(&bat_priv->vis_hash_lock);
- if (bat_priv->primary_if)
- send_vis_packet(bat_priv, info);
+ send_vis_packet(bat_priv, info);
spin_lock_bh(&bat_priv->vis_hash_lock);
send_list_del(info);
diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h
index 70672544db8..8e6c06158f8 100644
--- a/net/bluetooth/bnep/bnep.h
+++ b/net/bluetooth/bnep/bnep.h
@@ -23,88 +23,88 @@
#include <linux/crc32.h>
#include <net/bluetooth/bluetooth.h>
-// Limits
-#define BNEP_MAX_PROTO_FILTERS 5
-#define BNEP_MAX_MULTICAST_FILTERS 20
-
-// UUIDs
-#define BNEP_BASE_UUID 0x0000000000001000800000805F9B34FB
-#define BNEP_UUID16 0x02
-#define BNEP_UUID32 0x04
-#define BNEP_UUID128 0x16
-
-#define BNEP_SVC_PANU 0x1115
-#define BNEP_SVC_NAP 0x1116
-#define BNEP_SVC_GN 0x1117
-
-// Packet types
-#define BNEP_GENERAL 0x00
-#define BNEP_CONTROL 0x01
-#define BNEP_COMPRESSED 0x02
-#define BNEP_COMPRESSED_SRC_ONLY 0x03
-#define BNEP_COMPRESSED_DST_ONLY 0x04
-
-// Control types
-#define BNEP_CMD_NOT_UNDERSTOOD 0x00
-#define BNEP_SETUP_CONN_REQ 0x01
-#define BNEP_SETUP_CONN_RSP 0x02
-#define BNEP_FILTER_NET_TYPE_SET 0x03
-#define BNEP_FILTER_NET_TYPE_RSP 0x04
-#define BNEP_FILTER_MULTI_ADDR_SET 0x05
-#define BNEP_FILTER_MULTI_ADDR_RSP 0x06
-
-// Extension types
-#define BNEP_EXT_CONTROL 0x00
-
-// Response messages
-#define BNEP_SUCCESS 0x00
-
-#define BNEP_CONN_INVALID_DST 0x01
-#define BNEP_CONN_INVALID_SRC 0x02
-#define BNEP_CONN_INVALID_SVC 0x03
-#define BNEP_CONN_NOT_ALLOWED 0x04
-
-#define BNEP_FILTER_UNSUPPORTED_REQ 0x01
-#define BNEP_FILTER_INVALID_RANGE 0x02
-#define BNEP_FILTER_INVALID_MCADDR 0x02
-#define BNEP_FILTER_LIMIT_REACHED 0x03
-#define BNEP_FILTER_DENIED_SECURITY 0x04
-
-// L2CAP settings
-#define BNEP_MTU 1691
-#define BNEP_PSM 0x0f
-#define BNEP_FLUSH_TO 0xffff
-#define BNEP_CONNECT_TO 15
-#define BNEP_FILTER_TO 15
-
-// Headers
-#define BNEP_TYPE_MASK 0x7f
-#define BNEP_EXT_HEADER 0x80
+/* Limits */
+#define BNEP_MAX_PROTO_FILTERS 5
+#define BNEP_MAX_MULTICAST_FILTERS 20
+
+/* UUIDs */
+#define BNEP_BASE_UUID 0x0000000000001000800000805F9B34FB
+#define BNEP_UUID16 0x02
+#define BNEP_UUID32 0x04
+#define BNEP_UUID128 0x16
+
+#define BNEP_SVC_PANU 0x1115
+#define BNEP_SVC_NAP 0x1116
+#define BNEP_SVC_GN 0x1117
+
+/* Packet types */
+#define BNEP_GENERAL 0x00
+#define BNEP_CONTROL 0x01
+#define BNEP_COMPRESSED 0x02
+#define BNEP_COMPRESSED_SRC_ONLY 0x03
+#define BNEP_COMPRESSED_DST_ONLY 0x04
+
+/* Control types */
+#define BNEP_CMD_NOT_UNDERSTOOD 0x00
+#define BNEP_SETUP_CONN_REQ 0x01
+#define BNEP_SETUP_CONN_RSP 0x02
+#define BNEP_FILTER_NET_TYPE_SET 0x03
+#define BNEP_FILTER_NET_TYPE_RSP 0x04
+#define BNEP_FILTER_MULTI_ADDR_SET 0x05
+#define BNEP_FILTER_MULTI_ADDR_RSP 0x06
+
+/* Extension types */
+#define BNEP_EXT_CONTROL 0x00
+
+/* Response messages */
+#define BNEP_SUCCESS 0x00
+
+#define BNEP_CONN_INVALID_DST 0x01
+#define BNEP_CONN_INVALID_SRC 0x02
+#define BNEP_CONN_INVALID_SVC 0x03
+#define BNEP_CONN_NOT_ALLOWED 0x04
+
+#define BNEP_FILTER_UNSUPPORTED_REQ 0x01
+#define BNEP_FILTER_INVALID_RANGE 0x02
+#define BNEP_FILTER_INVALID_MCADDR 0x02
+#define BNEP_FILTER_LIMIT_REACHED 0x03
+#define BNEP_FILTER_DENIED_SECURITY 0x04
+
+/* L2CAP settings */
+#define BNEP_MTU 1691
+#define BNEP_PSM 0x0f
+#define BNEP_FLUSH_TO 0xffff
+#define BNEP_CONNECT_TO 15
+#define BNEP_FILTER_TO 15
+
+/* Headers */
+#define BNEP_TYPE_MASK 0x7f
+#define BNEP_EXT_HEADER 0x80
struct bnep_setup_conn_req {
- __u8 type;
- __u8 ctrl;
- __u8 uuid_size;
- __u8 service[0];
+ __u8 type;
+ __u8 ctrl;
+ __u8 uuid_size;
+ __u8 service[0];
} __packed;
struct bnep_set_filter_req {
- __u8 type;
- __u8 ctrl;
+ __u8 type;
+ __u8 ctrl;
__be16 len;
- __u8 list[0];
+ __u8 list[0];
} __packed;
struct bnep_control_rsp {
- __u8 type;
- __u8 ctrl;
+ __u8 type;
+ __u8 ctrl;
__be16 resp;
} __packed;
struct bnep_ext_hdr {
- __u8 type;
- __u8 len;
- __u8 data[0];
+ __u8 type;
+ __u8 len;
+ __u8 data[0];
} __packed;
/* BNEP ioctl defines */
@@ -114,10 +114,10 @@ struct bnep_ext_hdr {
#define BNEPGETCONNINFO _IOR('B', 211, int)
struct bnep_connadd_req {
- int sock; // Connected socket
+ int sock; /* Connected socket */
__u32 flags;
__u16 role;
- char device[16]; // Name of the Ethernet device
+ char device[16]; /* Name of the Ethernet device */
};
struct bnep_conndel_req {
@@ -148,14 +148,14 @@ int bnep_del_connection(struct bnep_conndel_req *req);
int bnep_get_connlist(struct bnep_connlist_req *req);
int bnep_get_conninfo(struct bnep_conninfo *ci);
-// BNEP sessions
+/* BNEP sessions */
struct bnep_session {
struct list_head list;
unsigned int role;
unsigned long state;
unsigned long flags;
- atomic_t killed;
+ struct task_struct *task;
struct ethhdr eh;
struct msghdr msg;
@@ -173,7 +173,7 @@ void bnep_sock_cleanup(void);
static inline int bnep_mc_hash(__u8 *addr)
{
- return (crc32_be(~0, addr, ETH_ALEN) >> 26);
+ return crc32_be(~0, addr, ETH_ALEN) >> 26;
}
#endif
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index 03d4d1245d5..ca39fcf010c 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -36,6 +36,7 @@
#include <linux/errno.h>
#include <linux/net.h>
#include <linux/slab.h>
+#include <linux/kthread.h>
#include <net/sock.h>
#include <linux/socket.h>
@@ -131,7 +132,8 @@ static int bnep_ctrl_set_netfilter(struct bnep_session *s, __be16 *data, int len
return -EILSEQ;
n = get_unaligned_be16(data);
- data++; len -= 2;
+ data++;
+ len -= 2;
if (len < n)
return -EILSEQ;
@@ -176,7 +178,8 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
return -EILSEQ;
n = get_unaligned_be16(data);
- data += 2; len -= 2;
+ data += 2;
+ len -= 2;
if (len < n)
return -EILSEQ;
@@ -187,6 +190,8 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
n /= (ETH_ALEN * 2);
if (n > 0) {
+ int i;
+
s->mc_filter = 0;
/* Always send broadcast */
@@ -196,18 +201,22 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
for (; n > 0; n--) {
u8 a1[6], *a2;
- memcpy(a1, data, ETH_ALEN); data += ETH_ALEN;
- a2 = data; data += ETH_ALEN;
+ memcpy(a1, data, ETH_ALEN);
+ data += ETH_ALEN;
+ a2 = data;
+ data += ETH_ALEN;
BT_DBG("mc filter %s -> %s",
batostr((void *) a1), batostr((void *) a2));
- #define INCA(a) { int i = 5; while (i >=0 && ++a[i--] == 0); }
-
/* Iterate from a1 to a2 */
set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter);
while (memcmp(a1, a2, 6) < 0 && s->mc_filter != ~0LL) {
- INCA(a1);
+ /* Increment a1 */
+ i = 5;
+ while (i >= 0 && ++a1[i--] == 0)
+ ;
+
set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter);
}
}
@@ -227,7 +236,8 @@ static int bnep_rx_control(struct bnep_session *s, void *data, int len)
u8 cmd = *(u8 *)data;
int err = 0;
- data++; len--;
+ data++;
+ len--;
switch (cmd) {
case BNEP_CMD_NOT_UNDERSTOOD:
@@ -302,7 +312,6 @@ static u8 __bnep_rx_hlen[] = {
ETH_ALEN + 2, /* BNEP_COMPRESSED_SRC_ONLY */
ETH_ALEN + 2 /* BNEP_COMPRESSED_DST_ONLY */
};
-#define BNEP_RX_TYPES (sizeof(__bnep_rx_hlen) - 1)
static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
{
@@ -312,9 +321,10 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
dev->stats.rx_bytes += skb->len;
- type = *(u8 *) skb->data; skb_pull(skb, 1);
+ type = *(u8 *) skb->data;
+ skb_pull(skb, 1);
- if ((type & BNEP_TYPE_MASK) > BNEP_RX_TYPES)
+ if ((type & BNEP_TYPE_MASK) >= sizeof(__bnep_rx_hlen))
goto badframe;
if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
@@ -367,14 +377,14 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
case BNEP_COMPRESSED_DST_ONLY:
memcpy(__skb_put(nskb, ETH_ALEN), skb_mac_header(skb),
- ETH_ALEN);
+ ETH_ALEN);
memcpy(__skb_put(nskb, ETH_ALEN + 2), s->eh.h_source,
- ETH_ALEN + 2);
+ ETH_ALEN + 2);
break;
case BNEP_GENERAL:
memcpy(__skb_put(nskb, ETH_ALEN * 2), skb_mac_header(skb),
- ETH_ALEN * 2);
+ ETH_ALEN * 2);
put_unaligned(s->eh.h_proto, (__be16 *) __skb_put(nskb, 2));
break;
}
@@ -470,15 +480,14 @@ static int bnep_session(void *arg)
BT_DBG("");
- daemonize("kbnepd %s", dev->name);
set_user_nice(current, -15);
init_waitqueue_entry(&wait, current);
add_wait_queue(sk_sleep(sk), &wait);
- while (!atomic_read(&s->killed)) {
+ while (!kthread_should_stop()) {
set_current_state(TASK_INTERRUPTIBLE);
- // RX
+ /* RX */
while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
skb_orphan(skb);
bnep_rx_frame(s, skb);
@@ -487,7 +496,7 @@ static int bnep_session(void *arg)
if (sk->sk_state != BT_CONNECTED)
break;
- // TX
+ /* TX */
while ((skb = skb_dequeue(&sk->sk_write_queue)))
if (bnep_tx_frame(s, skb))
break;
@@ -555,8 +564,8 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
/* session struct allocated as private part of net_device */
dev = alloc_netdev(sizeof(struct bnep_session),
- (*req->device) ? req->device : "bnep%d",
- bnep_net_setup);
+ (*req->device) ? req->device : "bnep%d",
+ bnep_net_setup);
if (!dev)
return -ENOMEM;
@@ -571,7 +580,7 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
s = netdev_priv(dev);
/* This is rx header therefore addresses are swapped.
- * ie eh.h_dest is our local address. */
+ * ie. eh.h_dest is our local address. */
memcpy(s->eh.h_dest, &src, ETH_ALEN);
memcpy(s->eh.h_source, &dst, ETH_ALEN);
memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN);
@@ -597,17 +606,17 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
SET_NETDEV_DEVTYPE(dev, &bnep_type);
err = register_netdev(dev);
- if (err) {
+ if (err)
goto failed;
- }
__bnep_link_session(s);
- err = kernel_thread(bnep_session, s, CLONE_KERNEL);
- if (err < 0) {
+ s->task = kthread_run(bnep_session, s, "kbnepd %s", dev->name);
+ if (IS_ERR(s->task)) {
/* Session thread start failed, gotta cleanup. */
unregister_netdev(dev);
__bnep_unlink_session(s);
+ err = PTR_ERR(s->task);
goto failed;
}
@@ -631,15 +640,9 @@ int bnep_del_connection(struct bnep_conndel_req *req)
down_read(&bnep_session_sem);
s = __bnep_get_session(req->dst);
- if (s) {
- /* Wakeup user-space which is polling for socket errors.
- * This is temporary hack until we have shutdown in L2CAP */
- s->sock->sk->sk_err = EUNATCH;
-
- /* Kill session thread */
- atomic_inc(&s->killed);
- wake_up_interruptible(sk_sleep(s->sock->sk));
- } else
+ if (s)
+ kthread_stop(s->task);
+ else
err = -ENOENT;
up_read(&bnep_session_sem);
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c
index d935da71ab3..17800b1d28e 100644
--- a/net/bluetooth/bnep/sock.c
+++ b/net/bluetooth/bnep/sock.c
@@ -39,10 +39,10 @@
#include <linux/init.h>
#include <linux/compat.h>
#include <linux/gfp.h>
+#include <linux/uaccess.h>
#include <net/sock.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
#include "bnep.h"
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c
index 67cff810c77..744233cba24 100644
--- a/net/bluetooth/cmtp/capi.c
+++ b/net/bluetooth/cmtp/capi.c
@@ -35,6 +35,7 @@
#include <linux/ioctl.h>
#include <linux/file.h>
#include <linux/wait.h>
+#include <linux/kthread.h>
#include <net/sock.h>
#include <linux/isdn/capilli.h>
@@ -143,7 +144,7 @@ static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
skb_queue_tail(&session->transmit, skb);
- cmtp_schedule(session);
+ wake_up_interruptible(sk_sleep(session->sock->sk));
}
static void cmtp_send_interopmsg(struct cmtp_session *session,
@@ -386,8 +387,7 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl)
capi_ctr_down(ctrl);
- atomic_inc(&session->terminate);
- cmtp_schedule(session);
+ kthread_stop(session->task);
}
static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
diff --git a/net/bluetooth/cmtp/cmtp.h b/net/bluetooth/cmtp/cmtp.h
index 785e79e953c..db43b54ac9a 100644
--- a/net/bluetooth/cmtp/cmtp.h
+++ b/net/bluetooth/cmtp/cmtp.h
@@ -37,7 +37,7 @@
#define CMTP_LOOPBACK 0
struct cmtp_connadd_req {
- int sock; // Connected socket
+ int sock; /* Connected socket */
__u32 flags;
};
@@ -81,7 +81,7 @@ struct cmtp_session {
char name[BTNAMSIZ];
- atomic_t terminate;
+ struct task_struct *task;
wait_queue_head_t wait;
@@ -121,13 +121,6 @@ void cmtp_detach_device(struct cmtp_session *session);
void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb);
-static inline void cmtp_schedule(struct cmtp_session *session)
-{
- struct sock *sk = session->sock->sk;
-
- wake_up_interruptible(sk_sleep(sk));
-}
-
/* CMTP init defines */
int cmtp_init_sockets(void);
void cmtp_cleanup_sockets(void);
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c
index 964ea9126f9..c5b11af908b 100644
--- a/net/bluetooth/cmtp/core.c
+++ b/net/bluetooth/cmtp/core.c
@@ -35,6 +35,7 @@
#include <linux/ioctl.h>
#include <linux/file.h>
#include <linux/init.h>
+#include <linux/kthread.h>
#include <net/sock.h>
#include <linux/isdn/capilli.h>
@@ -235,9 +236,12 @@ static void cmtp_process_transmit(struct cmtp_session *session)
size = min_t(uint, ((tail < 258) ? (tail - 2) : (tail - 3)), skb->len);
- if ((scb->id < 0) && ((scb->id = cmtp_alloc_block_id(session)) < 0)) {
- skb_queue_head(&session->transmit, skb);
- break;
+ if (scb->id < 0) {
+ scb->id = cmtp_alloc_block_id(session);
+ if (scb->id < 0) {
+ skb_queue_head(&session->transmit, skb);
+ break;
+ }
}
if (size < 256) {
@@ -284,12 +288,11 @@ static int cmtp_session(void *arg)
BT_DBG("session %p", session);
- daemonize("kcmtpd_ctr_%d", session->num);
set_user_nice(current, -15);
init_waitqueue_entry(&wait, current);
add_wait_queue(sk_sleep(sk), &wait);
- while (!atomic_read(&session->terminate)) {
+ while (!kthread_should_stop()) {
set_current_state(TASK_INTERRUPTIBLE);
if (sk->sk_state != BT_CONNECTED)
@@ -343,7 +346,8 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
bacpy(&session->bdaddr, &bt_sk(sock->sk)->dst);
- session->mtu = min_t(uint, l2cap_pi(sock->sk)->omtu, l2cap_pi(sock->sk)->imtu);
+ session->mtu = min_t(uint, l2cap_pi(sock->sk)->chan->omtu,
+ l2cap_pi(sock->sk)->chan->imtu);
BT_DBG("mtu %d", session->mtu);
@@ -367,9 +371,12 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
__cmtp_link_session(session);
- err = kernel_thread(cmtp_session, session, CLONE_KERNEL);
- if (err < 0)
+ session->task = kthread_run(cmtp_session, session, "kcmtpd_ctr_%d",
+ session->num);
+ if (IS_ERR(session->task)) {
+ err = PTR_ERR(session->task);
goto unlink;
+ }
if (!(session->flags & (1 << CMTP_LOOPBACK))) {
err = cmtp_attach_device(session);
@@ -406,9 +413,8 @@ int cmtp_del_connection(struct cmtp_conndel_req *req)
/* Flush the transmit queue */
skb_queue_purge(&session->transmit);
- /* Kill session thread */
- atomic_inc(&session->terminate);
- cmtp_schedule(session);
+ /* Stop session thread */
+ kthread_stop(session->task);
} else
err = -ENOENT;
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
index 7ea1979a8e4..3f2dd5c25ae 100644
--- a/net/bluetooth/cmtp/sock.c
+++ b/net/bluetooth/cmtp/sock.c
@@ -34,12 +34,12 @@
#include <linux/file.h>
#include <linux/compat.h>
#include <linux/gfp.h>
+#include <linux/uaccess.h>
#include <net/sock.h>
#include <linux/isdn/capilli.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
#include "cmtp.h"
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 7a6f56b2f49..3163330cd4f 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -269,6 +269,19 @@ static void hci_conn_idle(unsigned long arg)
hci_conn_enter_sniff_mode(conn);
}
+static void hci_conn_auto_accept(unsigned long arg)
+{
+ struct hci_conn *conn = (void *) arg;
+ struct hci_dev *hdev = conn->hdev;
+
+ hci_dev_lock(hdev);
+
+ hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst),
+ &conn->dst);
+
+ hci_dev_unlock(hdev);
+}
+
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
{
struct hci_conn *conn;
@@ -287,6 +300,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
conn->auth_type = HCI_AT_GENERAL_BONDING;
conn->io_capability = hdev->io_capability;
conn->remote_auth = 0xff;
+ conn->key_type = 0xff;
conn->power_save = 1;
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
@@ -311,6 +325,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn);
setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn);
+ setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept,
+ (unsigned long) conn);
atomic_set(&conn->refcnt, 0);
@@ -341,6 +357,8 @@ int hci_conn_del(struct hci_conn *conn)
del_timer(&conn->disc_timer);
+ del_timer(&conn->auto_accept_timer);
+
if (conn->type == ACL_LINK) {
struct hci_conn *sco = conn->link;
if (sco)
@@ -535,36 +553,93 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
return 0;
}
+/* Encrypt the the link */
+static void hci_conn_encrypt(struct hci_conn *conn)
+{
+ BT_DBG("conn %p", conn);
+
+ if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
+ struct hci_cp_set_conn_encrypt cp;
+ cp.handle = cpu_to_le16(conn->handle);
+ cp.encrypt = 0x01;
+ hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
+ &cp);
+ }
+}
+
/* Enable security */
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
{
BT_DBG("conn %p", conn);
+ /* For sdp we don't need the link key. */
if (sec_level == BT_SECURITY_SDP)
return 1;
+ /* For non 2.1 devices and low security level we don't need the link
+ key. */
if (sec_level == BT_SECURITY_LOW &&
(!conn->ssp_mode || !conn->hdev->ssp_mode))
return 1;
- if (conn->link_mode & HCI_LM_ENCRYPT)
- return hci_conn_auth(conn, sec_level, auth_type);
-
+ /* For other security levels we need the link key. */
+ if (!(conn->link_mode & HCI_LM_AUTH))
+ goto auth;
+
+ /* An authenticated combination key has sufficient security for any
+ security level. */
+ if (conn->key_type == HCI_LK_AUTH_COMBINATION)
+ goto encrypt;
+
+ /* An unauthenticated combination key has sufficient security for
+ security level 1 and 2. */
+ if (conn->key_type == HCI_LK_UNAUTH_COMBINATION &&
+ (sec_level == BT_SECURITY_MEDIUM ||
+ sec_level == BT_SECURITY_LOW))
+ goto encrypt;
+
+ /* A combination key has always sufficient security for the security
+ levels 1 or 2. High security level requires the combination key
+ is generated using maximum PIN code length (16).
+ For pre 2.1 units. */
+ if (conn->key_type == HCI_LK_COMBINATION &&
+ (sec_level != BT_SECURITY_HIGH ||
+ conn->pin_length == 16))
+ goto encrypt;
+
+auth:
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
return 0;
- if (hci_conn_auth(conn, sec_level, auth_type)) {
- struct hci_cp_set_conn_encrypt cp;
- cp.handle = cpu_to_le16(conn->handle);
- cp.encrypt = 1;
- hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT,
- sizeof(cp), &cp);
- }
+ hci_conn_auth(conn, sec_level, auth_type);
+ return 0;
+
+encrypt:
+ if (conn->link_mode & HCI_LM_ENCRYPT)
+ return 1;
+ hci_conn_encrypt(conn);
return 0;
}
EXPORT_SYMBOL(hci_conn_security);
+/* Check secure link requirement */
+int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level)
+{
+ BT_DBG("conn %p", conn);
+
+ if (sec_level != BT_SECURITY_HIGH)
+ return 1; /* Accept if non-secure is required */
+
+ if (conn->key_type == HCI_LK_AUTH_COMBINATION ||
+ (conn->key_type == HCI_LK_COMBINATION &&
+ conn->pin_length == 16))
+ return 1;
+
+ return 0; /* Reject not secure link */
+}
+EXPORT_SYMBOL(hci_conn_check_secure);
+
/* Change link key */
int hci_conn_change_link_key(struct hci_conn *conn)
{
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b5a8afc2be3..815269b07f2 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -56,7 +56,6 @@
static void hci_cmd_task(unsigned long arg);
static void hci_rx_task(unsigned long arg);
static void hci_tx_task(unsigned long arg);
-static void hci_notify(struct hci_dev *hdev, int event);
static DEFINE_RWLOCK(hci_task_lock);
@@ -1021,18 +1020,54 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
return NULL;
}
-int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
- u8 *val, u8 type, u8 pin_len)
+static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
+ u8 key_type, u8 old_key_type)
+{
+ /* Legacy key */
+ if (key_type < 0x03)
+ return 1;
+
+ /* Debug keys are insecure so don't store them persistently */
+ if (key_type == HCI_LK_DEBUG_COMBINATION)
+ return 0;
+
+ /* Changed combination key and there's no previous one */
+ if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
+ return 0;
+
+ /* Security mode 3 case */
+ if (!conn)
+ return 1;
+
+ /* Neither local nor remote side had no-bonding as requirement */
+ if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
+ return 1;
+
+ /* Local side had dedicated bonding as requirement */
+ if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
+ return 1;
+
+ /* Remote side had dedicated bonding as requirement */
+ if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
+ return 1;
+
+ /* If none of the above criteria match, then don't store the key
+ * persistently */
+ return 0;
+}
+
+int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
+ bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
{
struct link_key *key, *old_key;
- u8 old_key_type;
+ u8 old_key_type, persistent;
old_key = hci_find_link_key(hdev, bdaddr);
if (old_key) {
old_key_type = old_key->type;
key = old_key;
} else {
- old_key_type = 0xff;
+ old_key_type = conn ? conn->key_type : 0xff;
key = kzalloc(sizeof(*key), GFP_ATOMIC);
if (!key)
return -ENOMEM;
@@ -1041,16 +1076,37 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
+ /* Some buggy controller combinations generate a changed
+ * combination key for legacy pairing even when there's no
+ * previous key */
+ if (type == HCI_LK_CHANGED_COMBINATION &&
+ (!conn || conn->remote_auth == 0xff) &&
+ old_key_type == 0xff) {
+ type = HCI_LK_COMBINATION;
+ if (conn)
+ conn->key_type = type;
+ }
+
bacpy(&key->bdaddr, bdaddr);
memcpy(key->val, val, 16);
- key->type = type;
key->pin_len = pin_len;
- if (new_key)
- mgmt_new_key(hdev->id, key, old_key_type);
-
- if (type == 0x06)
+ if (type == HCI_LK_CHANGED_COMBINATION)
key->type = old_key_type;
+ else
+ key->type = type;
+
+ if (!new_key)
+ return 0;
+
+ persistent = hci_persistent_key(hdev, conn, type, old_key_type);
+
+ mgmt_new_key(hdev->id, key, persistent);
+
+ if (!persistent) {
+ list_del(&key->list);
+ kfree(key);
+ }
return 0;
}
@@ -1082,6 +1138,70 @@ static void hci_cmd_timer(unsigned long arg)
tasklet_schedule(&hdev->cmd_task);
}
+struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
+ bdaddr_t *bdaddr)
+{
+ struct oob_data *data;
+
+ list_for_each_entry(data, &hdev->remote_oob_data, list)
+ if (bacmp(bdaddr, &data->bdaddr) == 0)
+ return data;
+
+ return NULL;
+}
+
+int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+ struct oob_data *data;
+
+ data = hci_find_remote_oob_data(hdev, bdaddr);
+ if (!data)
+ return -ENOENT;
+
+ BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
+
+ list_del(&data->list);
+ kfree(data);
+
+ return 0;
+}
+
+int hci_remote_oob_data_clear(struct hci_dev *hdev)
+{
+ struct oob_data *data, *n;
+
+ list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
+ list_del(&data->list);
+ kfree(data);
+ }
+
+ return 0;
+}
+
+int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
+ u8 *randomizer)
+{
+ struct oob_data *data;
+
+ data = hci_find_remote_oob_data(hdev, bdaddr);
+
+ if (!data) {
+ data = kmalloc(sizeof(*data), GFP_ATOMIC);
+ if (!data)
+ return -ENOMEM;
+
+ bacpy(&data->bdaddr, bdaddr);
+ list_add(&data->list, &hdev->remote_oob_data);
+ }
+
+ memcpy(data->hash, hash, sizeof(data->hash));
+ memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
+
+ BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
+
+ return 0;
+}
+
/* Register HCI device */
int hci_register_dev(struct hci_dev *hdev)
{
@@ -1146,6 +1266,8 @@ int hci_register_dev(struct hci_dev *hdev)
INIT_LIST_HEAD(&hdev->link_keys);
+ INIT_LIST_HEAD(&hdev->remote_oob_data);
+
INIT_WORK(&hdev->power_on, hci_power_on);
INIT_WORK(&hdev->power_off, hci_power_off);
setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev);
@@ -1225,6 +1347,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
hci_blacklist_clear(hdev);
hci_uuids_clear(hdev);
hci_link_keys_clear(hdev);
+ hci_remote_oob_data_clear(hdev);
hci_dev_unlock_bh(hdev);
__hci_dev_put(hdev);
@@ -1274,7 +1397,7 @@ int hci_recv_frame(struct sk_buff *skb)
EXPORT_SYMBOL(hci_recv_frame);
static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
- int count, __u8 index, gfp_t gfp_mask)
+ int count, __u8 index)
{
int len = 0;
int hlen = 0;
@@ -1304,7 +1427,7 @@ static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
break;
}
- skb = bt_skb_alloc(len, gfp_mask);
+ skb = bt_skb_alloc(len, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
@@ -1390,8 +1513,7 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
return -EILSEQ;
while (count) {
- rem = hci_reassembly(hdev, type, data, count,
- type - 1, GFP_ATOMIC);
+ rem = hci_reassembly(hdev, type, data, count, type - 1);
if (rem < 0)
return rem;
@@ -1425,8 +1547,8 @@ int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
} else
type = bt_cb(skb)->pkt_type;
- rem = hci_reassembly(hdev, type, data,
- count, STREAM_REASSEMBLY, GFP_ATOMIC);
+ rem = hci_reassembly(hdev, type, data, count,
+ STREAM_REASSEMBLY);
if (rem < 0)
return rem;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index b2570159a04..f13ddbf858b 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -56,7 +56,9 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
if (status)
return;
- clear_bit(HCI_INQUIRY, &hdev->flags);
+ if (test_bit(HCI_MGMT, &hdev->flags) &&
+ test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
+ mgmt_discovering(hdev->id, 0);
hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
@@ -72,7 +74,9 @@ static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
if (status)
return;
- clear_bit(HCI_INQUIRY, &hdev->flags);
+ if (test_bit(HCI_MGMT, &hdev->flags) &&
+ test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
+ mgmt_discovering(hdev->id, 0);
hci_conn_check_pending(hdev);
}
@@ -195,14 +199,17 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s status 0x%x", hdev->name, status);
- if (status)
- return;
-
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
if (!sent)
return;
- memcpy(hdev->dev_name, sent, 248);
+ if (test_bit(HCI_MGMT, &hdev->flags))
+ mgmt_set_local_name_complete(hdev->id, sent, status);
+
+ if (status)
+ return;
+
+ memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
}
static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
@@ -214,7 +221,7 @@ static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
if (rp->status)
return;
- memcpy(hdev->dev_name, rp->name, 248);
+ memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
}
static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
@@ -821,16 +828,31 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
rp->status);
}
+static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
+
+ BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+ mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash,
+ rp->randomizer, rp->status);
+}
+
static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
{
BT_DBG("%s status 0x%x", hdev->name, status);
if (status) {
hci_req_complete(hdev, HCI_OP_INQUIRY, status);
-
hci_conn_check_pending(hdev);
- } else
- set_bit(HCI_INQUIRY, &hdev->flags);
+ return;
+ }
+
+ if (test_bit(HCI_MGMT, &hdev->flags) &&
+ !test_and_set_bit(HCI_INQUIRY,
+ &hdev->flags))
+ mgmt_discovering(hdev->id, 1);
}
static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
@@ -999,12 +1021,19 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
- if (conn && hci_outgoing_auth_needed(hdev, conn)) {
+ if (!conn)
+ goto unlock;
+
+ if (!hci_outgoing_auth_needed(hdev, conn))
+ goto unlock;
+
+ if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
struct hci_cp_auth_requested cp;
cp.handle = __cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
}
+unlock:
hci_dev_unlock(hdev);
}
@@ -1194,7 +1223,9 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff
BT_DBG("%s status %d", hdev->name, status);
- clear_bit(HCI_INQUIRY, &hdev->flags);
+ if (test_bit(HCI_MGMT, &hdev->flags) &&
+ test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
+ mgmt_discovering(hdev->id, 0);
hci_req_complete(hdev, HCI_OP_INQUIRY, status);
@@ -1214,7 +1245,13 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
hci_dev_lock(hdev);
- for (; num_rsp; num_rsp--) {
+ if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) {
+
+ if (test_bit(HCI_MGMT, &hdev->flags))
+ mgmt_discovering(hdev->id, 1);
+ }
+
+ for (; num_rsp; num_rsp--, info++) {
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
data.pscan_period_mode = info->pscan_period_mode;
@@ -1223,8 +1260,9 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
data.clock_offset = info->clock_offset;
data.rssi = 0x00;
data.ssp_mode = 0x00;
- info++;
hci_inquiry_cache_update(hdev, &data);
+ mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class, 0,
+ NULL);
}
hci_dev_unlock(hdev);
@@ -1402,7 +1440,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
conn->state = BT_CLOSED;
- if (conn->type == ACL_LINK)
+ if (conn->type == ACL_LINK || conn->type == LE_LINK)
mgmt_disconnected(hdev->id, &conn->dst);
hci_proto_disconn_cfm(conn, ev->reason);
@@ -1428,7 +1466,6 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
conn->sec_level = conn->pending_sec_level;
} else {
mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
- conn->sec_level = BT_SECURITY_LOW;
}
clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
@@ -1482,13 +1519,23 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb
hci_dev_lock(hdev);
+ if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags))
+ mgmt_remote_name(hdev->id, &ev->bdaddr, ev->name);
+
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
- if (conn && hci_outgoing_auth_needed(hdev, conn)) {
+ if (!conn)
+ goto unlock;
+
+ if (!hci_outgoing_auth_needed(hdev, conn))
+ goto unlock;
+
+ if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
struct hci_cp_auth_requested cp;
cp.handle = __cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
}
+unlock:
hci_dev_unlock(hdev);
}
@@ -1751,6 +1798,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_cc_pin_code_neg_reply(hdev, skb);
break;
+ case HCI_OP_READ_LOCAL_OOB_DATA:
+ hci_cc_read_local_oob_data_reply(hdev, skb);
+ break;
+
case HCI_OP_LE_READ_BUFFER_SIZE:
hci_cc_le_read_buffer_size(hdev, skb);
break;
@@ -1984,9 +2035,16 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff
if (!test_bit(HCI_PAIRABLE, &hdev->flags))
hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
sizeof(ev->bdaddr), &ev->bdaddr);
+ else if (test_bit(HCI_MGMT, &hdev->flags)) {
+ u8 secure;
- if (test_bit(HCI_MGMT, &hdev->flags))
- mgmt_pin_code_request(hdev->id, &ev->bdaddr);
+ if (conn->pending_sec_level == BT_SECURITY_HIGH)
+ secure = 1;
+ else
+ secure = 0;
+
+ mgmt_pin_code_request(hdev->id, &ev->bdaddr, secure);
+ }
hci_dev_unlock(hdev);
}
@@ -2015,17 +2073,30 @@ static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff
BT_DBG("%s found key type %u for %s", hdev->name, key->type,
batostr(&ev->bdaddr));
- if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && key->type == 0x03) {
+ if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) &&
+ key->type == HCI_LK_DEBUG_COMBINATION) {
BT_DBG("%s ignoring debug key", hdev->name);
goto not_found;
}
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
+ if (conn) {
+ if (key->type == HCI_LK_UNAUTH_COMBINATION &&
+ conn->auth_type != 0xff &&
+ (conn->auth_type & 0x01)) {
+ BT_DBG("%s ignoring unauthenticated key", hdev->name);
+ goto not_found;
+ }
- if (key->type == 0x04 && conn && conn->auth_type != 0xff &&
- (conn->auth_type & 0x01)) {
- BT_DBG("%s ignoring unauthenticated key", hdev->name);
- goto not_found;
+ if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
+ conn->pending_sec_level == BT_SECURITY_HIGH) {
+ BT_DBG("%s ignoring key unauthenticated for high \
+ security", hdev->name);
+ goto not_found;
+ }
+
+ conn->key_type = key->type;
+ conn->pin_length = key->pin_len;
}
bacpy(&cp.bdaddr, &ev->bdaddr);
@@ -2057,11 +2128,15 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff
hci_conn_hold(conn);
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
pin_len = conn->pin_length;
+
+ if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
+ conn->key_type = ev->key_type;
+
hci_conn_put(conn);
}
if (test_bit(HCI_LINK_KEYS, &hdev->flags))
- hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key,
+ hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
ev->key_type, pin_len);
hci_dev_unlock(hdev);
@@ -2136,11 +2211,17 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
hci_dev_lock(hdev);
+ if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) {
+
+ if (test_bit(HCI_MGMT, &hdev->flags))
+ mgmt_discovering(hdev->id, 1);
+ }
+
if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
struct inquiry_info_with_rssi_and_pscan_mode *info;
info = (void *) (skb->data + 1);
- for (; num_rsp; num_rsp--) {
+ for (; num_rsp; num_rsp--, info++) {
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
data.pscan_period_mode = info->pscan_period_mode;
@@ -2149,13 +2230,15 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
data.clock_offset = info->clock_offset;
data.rssi = info->rssi;
data.ssp_mode = 0x00;
- info++;
hci_inquiry_cache_update(hdev, &data);
+ mgmt_device_found(hdev->id, &info->bdaddr,
+ info->dev_class, info->rssi,
+ NULL);
}
} else {
struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
- for (; num_rsp; num_rsp--) {
+ for (; num_rsp; num_rsp--, info++) {
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
data.pscan_period_mode = info->pscan_period_mode;
@@ -2164,8 +2247,10 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
data.clock_offset = info->clock_offset;
data.rssi = info->rssi;
data.ssp_mode = 0x00;
- info++;
hci_inquiry_cache_update(hdev, &data);
+ mgmt_device_found(hdev->id, &info->bdaddr,
+ info->dev_class, info->rssi,
+ NULL);
}
}
@@ -2294,9 +2379,15 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
if (!num_rsp)
return;
+ if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) {
+
+ if (test_bit(HCI_MGMT, &hdev->flags))
+ mgmt_discovering(hdev->id, 1);
+ }
+
hci_dev_lock(hdev);
- for (; num_rsp; num_rsp--) {
+ for (; num_rsp; num_rsp--, info++) {
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
data.pscan_period_mode = info->pscan_period_mode;
@@ -2305,8 +2396,9 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
data.clock_offset = info->clock_offset;
data.rssi = info->rssi;
data.ssp_mode = 0x01;
- info++;
hci_inquiry_cache_update(hdev, &data);
+ mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class,
+ info->rssi, info->data);
}
hci_dev_unlock(hdev);
@@ -2326,7 +2418,7 @@ static inline u8 hci_get_auth_req(struct hci_conn *conn)
/* If remote requests no-bonding follow that lead */
if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
- return 0x00;
+ return conn->remote_auth | (conn->auth_type & 0x01);
return conn->auth_type;
}
@@ -2355,8 +2447,14 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
bacpy(&cp.bdaddr, &ev->bdaddr);
cp.capability = conn->io_capability;
- cp.oob_data = 0;
- cp.authentication = hci_get_auth_req(conn);
+ conn->auth_type = hci_get_auth_req(conn);
+ cp.authentication = conn->auth_type;
+
+ if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
+ hci_find_remote_oob_data(hdev, &conn->dst))
+ cp.oob_data = 0x01;
+ else
+ cp.oob_data = 0x00;
hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
sizeof(cp), &cp);
@@ -2364,7 +2462,7 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
struct hci_cp_io_capability_neg_reply cp;
bacpy(&cp.bdaddr, &ev->bdaddr);
- cp.reason = 0x16; /* Pairing not allowed */
+ cp.reason = 0x18; /* Pairing not allowed */
hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
sizeof(cp), &cp);
@@ -2399,14 +2497,67 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_ev_user_confirm_req *ev = (void *) skb->data;
+ int loc_mitm, rem_mitm, confirm_hint = 0;
+ struct hci_conn *conn;
BT_DBG("%s", hdev->name);
hci_dev_lock(hdev);
- if (test_bit(HCI_MGMT, &hdev->flags))
- mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey);
+ if (!test_bit(HCI_MGMT, &hdev->flags))
+ goto unlock;
+
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
+ if (!conn)
+ goto unlock;
+
+ loc_mitm = (conn->auth_type & 0x01);
+ rem_mitm = (conn->remote_auth & 0x01);
+
+ /* If we require MITM but the remote device can't provide that
+ * (it has NoInputNoOutput) then reject the confirmation
+ * request. The only exception is when we're dedicated bonding
+ * initiators (connect_cfm_cb set) since then we always have the MITM
+ * bit set. */
+ if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
+ BT_DBG("Rejecting request: remote device can't provide MITM");
+ hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
+ sizeof(ev->bdaddr), &ev->bdaddr);
+ goto unlock;
+ }
+
+ /* If no side requires MITM protection; auto-accept */
+ if ((!loc_mitm || conn->remote_cap == 0x03) &&
+ (!rem_mitm || conn->io_capability == 0x03)) {
+
+ /* If we're not the initiators request authorization to
+ * proceed from user space (mgmt_user_confirm with
+ * confirm_hint set to 1). */
+ if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
+ BT_DBG("Confirming auto-accept as acceptor");
+ confirm_hint = 1;
+ goto confirm;
+ }
+
+ BT_DBG("Auto-accept of user confirmation with %ums delay",
+ hdev->auto_accept_delay);
+
+ if (hdev->auto_accept_delay > 0) {
+ int delay = msecs_to_jiffies(hdev->auto_accept_delay);
+ mod_timer(&conn->auto_accept_timer, jiffies + delay);
+ goto unlock;
+ }
+
+ hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
+ sizeof(ev->bdaddr), &ev->bdaddr);
+ goto unlock;
+ }
+
+confirm:
+ mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey,
+ confirm_hint);
+unlock:
hci_dev_unlock(hdev);
}
@@ -2453,6 +2604,41 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
hci_dev_unlock(hdev);
}
+static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
+ struct oob_data *data;
+
+ BT_DBG("%s", hdev->name);
+
+ hci_dev_lock(hdev);
+
+ if (!test_bit(HCI_MGMT, &hdev->flags))
+ goto unlock;
+
+ data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
+ if (data) {
+ struct hci_cp_remote_oob_data_reply cp;
+
+ bacpy(&cp.bdaddr, &ev->bdaddr);
+ memcpy(cp.hash, data->hash, sizeof(cp.hash));
+ memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
+
+ hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
+ &cp);
+ } else {
+ struct hci_cp_remote_oob_data_neg_reply cp;
+
+ bacpy(&cp.bdaddr, &ev->bdaddr);
+ hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
+ &cp);
+ }
+
+unlock:
+ hci_dev_unlock(hdev);
+}
+
static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_le_conn_complete *ev = (void *) skb->data;
@@ -2473,12 +2659,15 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff
}
if (ev->status) {
+ mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status);
hci_proto_connect_cfm(conn, ev->status);
conn->state = BT_CLOSED;
hci_conn_del(conn);
goto unlock;
}
+ mgmt_connected(hdev->id, &ev->bdaddr);
+
conn->handle = __le16_to_cpu(ev->handle);
conn->state = BT_CONNECTED;
@@ -2655,6 +2844,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_le_meta_evt(hdev, skb);
break;
+ case HCI_EV_REMOTE_OOB_DATA_REQUEST:
+ hci_remote_oob_data_request_evt(hdev, skb);
+ break;
+
default:
BT_DBG("%s event 0x%x", hdev->name, event);
break;
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 3c838a65a75..a6c3aa8be1f 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -216,13 +216,13 @@ static ssize_t show_type(struct device *dev, struct device_attribute *attr, char
static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
- char name[249];
+ char name[HCI_MAX_NAME_LENGTH + 1];
int i;
- for (i = 0; i < 248; i++)
+ for (i = 0; i < HCI_MAX_NAME_LENGTH; i++)
name[i] = hdev->dev_name[i];
- name[248] = '\0';
+ name[HCI_MAX_NAME_LENGTH] = '\0';
return sprintf(buf, "%s\n", name);
}
@@ -277,10 +277,12 @@ static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *at
static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
- unsigned long val;
+ unsigned int val;
+ int rv;
- if (strict_strtoul(buf, 0, &val) < 0)
- return -EINVAL;
+ rv = kstrtouint(buf, 0, &val);
+ if (rv < 0)
+ return rv;
if (val != 0 && (val < 500 || val > 3600000))
return -EINVAL;
@@ -299,15 +301,14 @@ static ssize_t show_sniff_max_interval(struct device *dev, struct device_attribu
static ssize_t store_sniff_max_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
- unsigned long val;
-
- if (strict_strtoul(buf, 0, &val) < 0)
- return -EINVAL;
+ u16 val;
+ int rv;
- if (val < 0x0002 || val > 0xFFFE || val % 2)
- return -EINVAL;
+ rv = kstrtou16(buf, 0, &val);
+ if (rv < 0)
+ return rv;
- if (val < hdev->sniff_min_interval)
+ if (val == 0 || val % 2 || val < hdev->sniff_min_interval)
return -EINVAL;
hdev->sniff_max_interval = val;
@@ -324,15 +325,14 @@ static ssize_t show_sniff_min_interval(struct device *dev, struct device_attribu
static ssize_t store_sniff_min_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
- unsigned long val;
+ u16 val;
+ int rv;
- if (strict_strtoul(buf, 0, &val) < 0)
- return -EINVAL;
-
- if (val < 0x0002 || val > 0xFFFE || val % 2)
- return -EINVAL;
+ rv = kstrtou16(buf, 0, &val);
+ if (rv < 0)
+ return rv;
- if (val > hdev->sniff_max_interval)
+ if (val == 0 || val % 2 || val > hdev->sniff_max_interval)
return -EINVAL;
hdev->sniff_min_interval = val;
@@ -511,6 +511,35 @@ static const struct file_operations uuids_fops = {
.release = single_release,
};
+static int auto_accept_delay_set(void *data, u64 val)
+{
+ struct hci_dev *hdev = data;
+
+ hci_dev_lock_bh(hdev);
+
+ hdev->auto_accept_delay = val;
+
+ hci_dev_unlock_bh(hdev);
+
+ return 0;
+}
+
+static int auto_accept_delay_get(void *data, u64 *val)
+{
+ struct hci_dev *hdev = data;
+
+ hci_dev_lock_bh(hdev);
+
+ *val = hdev->auto_accept_delay;
+
+ hci_dev_unlock_bh(hdev);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
+ auto_accept_delay_set, "%llu\n");
+
int hci_register_sysfs(struct hci_dev *hdev)
{
struct device *dev = &hdev->dev;
@@ -545,6 +574,8 @@ int hci_register_sysfs(struct hci_dev *hdev)
debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
+ debugfs_create_file("auto_accept_delay", 0444, hdev->debugfs, hdev,
+ &auto_accept_delay_fops);
return 0;
}
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 5ec12971af6..c405a954a60 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -37,6 +37,7 @@
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/mutex.h>
+#include <linux/kthread.h>
#include <net/sock.h>
#include <linux/input.h>
@@ -55,22 +56,24 @@ static DECLARE_RWSEM(hidp_session_sem);
static LIST_HEAD(hidp_session_list);
static unsigned char hidp_keycode[256] = {
- 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
- 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
- 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
- 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
- 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
- 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
- 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
- 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
- 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
- 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
- 150,158,159,128,136,177,178,176,142,152,173,140
+ 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36,
+ 37, 38, 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45,
+ 21, 44, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 28, 1,
+ 14, 15, 57, 12, 13, 26, 27, 43, 43, 39, 40, 41, 51, 52,
+ 53, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 87, 88,
+ 99, 70, 119, 110, 102, 104, 111, 107, 109, 106, 105, 108, 103, 69,
+ 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, 72, 73,
+ 82, 83, 86, 127, 116, 117, 183, 184, 185, 186, 187, 188, 189, 190,
+ 191, 192, 193, 194, 134, 138, 130, 132, 128, 129, 131, 137, 133, 135,
+ 136, 113, 115, 114, 0, 0, 0, 121, 0, 89, 93, 124, 92, 94,
+ 95, 0, 0, 0, 122, 123, 90, 91, 85, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 29, 42, 56, 125, 97, 54, 100, 126, 164, 166, 165, 163, 161, 115,
+ 114, 113, 150, 158, 159, 128, 136, 177, 178, 176, 142, 152, 173, 140
};
static unsigned char hidp_mkeyspat[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
@@ -461,8 +464,7 @@ static void hidp_idle_timeout(unsigned long arg)
{
struct hidp_session *session = (struct hidp_session *) arg;
- atomic_inc(&session->terminate);
- hidp_schedule(session);
+ kthread_stop(session->task);
}
static void hidp_set_timer(struct hidp_session *session)
@@ -533,9 +535,7 @@ static void hidp_process_hid_control(struct hidp_session *session,
skb_queue_purge(&session->ctrl_transmit);
skb_queue_purge(&session->intr_transmit);
- /* Kill session thread */
- atomic_inc(&session->terminate);
- hidp_schedule(session);
+ kthread_stop(session->task);
}
}
@@ -694,22 +694,10 @@ static int hidp_session(void *arg)
struct sock *ctrl_sk = session->ctrl_sock->sk;
struct sock *intr_sk = session->intr_sock->sk;
struct sk_buff *skb;
- int vendor = 0x0000, product = 0x0000;
wait_queue_t ctrl_wait, intr_wait;
BT_DBG("session %p", session);
- if (session->input) {
- vendor = session->input->id.vendor;
- product = session->input->id.product;
- }
-
- if (session->hid) {
- vendor = session->hid->vendor;
- product = session->hid->product;
- }
-
- daemonize("khidpd_%04x%04x", vendor, product);
set_user_nice(current, -15);
init_waitqueue_entry(&ctrl_wait, current);
@@ -718,10 +706,11 @@ static int hidp_session(void *arg)
add_wait_queue(sk_sleep(intr_sk), &intr_wait);
session->waiting_for_startup = 0;
wake_up_interruptible(&session->startup_queue);
- while (!atomic_read(&session->terminate)) {
+ while (!kthread_should_stop()) {
set_current_state(TASK_INTERRUPTIBLE);
- if (ctrl_sk->sk_state != BT_CONNECTED || intr_sk->sk_state != BT_CONNECTED)
+ if (ctrl_sk->sk_state != BT_CONNECTED ||
+ intr_sk->sk_state != BT_CONNECTED)
break;
while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
@@ -965,6 +954,7 @@ fault:
int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
{
struct hidp_session *session, *s;
+ int vendor, product;
int err;
BT_DBG("");
@@ -989,8 +979,10 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst);
- session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->omtu, l2cap_pi(ctrl_sock->sk)->imtu);
- session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->omtu, l2cap_pi(intr_sock->sk)->imtu);
+ session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->chan->omtu,
+ l2cap_pi(ctrl_sock->sk)->chan->imtu);
+ session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->chan->omtu,
+ l2cap_pi(intr_sock->sk)->chan->imtu);
BT_DBG("ctrl mtu %d intr mtu %d", session->ctrl_mtu, session->intr_mtu);
@@ -1026,9 +1018,24 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
hidp_set_timer(session);
- err = kernel_thread(hidp_session, session, CLONE_KERNEL);
- if (err < 0)
+ if (session->hid) {
+ vendor = session->hid->vendor;
+ product = session->hid->product;
+ } else if (session->input) {
+ vendor = session->input->id.vendor;
+ product = session->input->id.product;
+ } else {
+ vendor = 0x0000;
+ product = 0x0000;
+ }
+
+ session->task = kthread_run(hidp_session, session, "khidpd_%04x%04x",
+ vendor, product);
+ if (IS_ERR(session->task)) {
+ err = PTR_ERR(session->task);
goto unlink;
+ }
+
while (session->waiting_for_startup) {
wait_event_interruptible(session->startup_queue,
!session->waiting_for_startup);
@@ -1053,8 +1060,7 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
err_add_device:
hid_destroy_device(session->hid);
session->hid = NULL;
- atomic_inc(&session->terminate);
- hidp_schedule(session);
+ kthread_stop(session->task);
unlink:
hidp_del_timer(session);
@@ -1105,13 +1111,7 @@ int hidp_del_connection(struct hidp_conndel_req *req)
skb_queue_purge(&session->ctrl_transmit);
skb_queue_purge(&session->intr_transmit);
- /* Wakeup user-space polling for socket errors */
- session->intr_sock->sk->sk_err = EUNATCH;
- session->ctrl_sock->sk->sk_err = EUNATCH;
-
- /* Kill session thread */
- atomic_inc(&session->terminate);
- hidp_schedule(session);
+ kthread_stop(session->task);
}
} else
err = -ENOENT;
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h
index 13de5fa0348..12822cde4b4 100644
--- a/net/bluetooth/hidp/hidp.h
+++ b/net/bluetooth/hidp/hidp.h
@@ -84,8 +84,8 @@
#define HIDP_WAITING_FOR_SEND_ACK 11
struct hidp_connadd_req {
- int ctrl_sock; // Connected control socket
- int intr_sock; // Connteted interrupt socket
+ int ctrl_sock; /* Connected control socket */
+ int intr_sock; /* Connected interrupt socket */
__u16 parser;
__u16 rd_size;
__u8 __user *rd_data;
@@ -142,7 +142,7 @@ struct hidp_session {
uint ctrl_mtu;
uint intr_mtu;
- atomic_t terminate;
+ struct task_struct *task;
unsigned char keys[8];
unsigned char leds;
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c
index 250dfd46237..178ac7f127a 100644
--- a/net/bluetooth/hidp/sock.c
+++ b/net/bluetooth/hidp/sock.c
@@ -85,7 +85,8 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
return err;
}
- if (csock->sk->sk_state != BT_CONNECTED || isock->sk->sk_state != BT_CONNECTED) {
+ if (csock->sk->sk_state != BT_CONNECTED ||
+ isock->sk->sk_state != BT_CONNECTED) {
sockfd_put(csock);
sockfd_put(isock);
return -EBADFD;
@@ -140,8 +141,8 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
#ifdef CONFIG_COMPAT
struct compat_hidp_connadd_req {
- int ctrl_sock; // Connected control socket
- int intr_sock; // Connteted interrupt socket
+ int ctrl_sock; /* Connected control socket */
+ int intr_sock; /* Connected interrupt socket */
__u16 parser;
__u16 rd_size;
compat_uptr_t rd_data;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 2c8dd4494c6..a86f9ba4f05 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -62,168 +62,233 @@ static u8 l2cap_fixed_chan[8] = { 0x02, };
static struct workqueue_struct *_busy_wq;
-struct bt_sock_list l2cap_sk_list = {
- .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
-};
+LIST_HEAD(chan_list);
+DEFINE_RWLOCK(chan_list_lock);
static void l2cap_busy_work(struct work_struct *work);
static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
u8 code, u8 ident, u16 dlen, void *data);
+static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
/* ---- L2CAP channels ---- */
-static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
+static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid)
{
- struct sock *s;
- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
- if (l2cap_pi(s)->dcid == cid)
- break;
+ struct l2cap_chan *c;
+
+ list_for_each_entry(c, &conn->chan_l, list) {
+ if (c->dcid == cid)
+ return c;
}
- return s;
+ return NULL;
+
}
-static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
+static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid)
{
- struct sock *s;
- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
- if (l2cap_pi(s)->scid == cid)
- break;
+ struct l2cap_chan *c;
+
+ list_for_each_entry(c, &conn->chan_l, list) {
+ if (c->scid == cid)
+ return c;
}
- return s;
+ return NULL;
}
/* Find channel with given SCID.
* Returns locked socket */
-static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
+static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid)
{
- struct sock *s;
- read_lock(&l->lock);
- s = __l2cap_get_chan_by_scid(l, cid);
- if (s)
- bh_lock_sock(s);
- read_unlock(&l->lock);
- return s;
+ struct l2cap_chan *c;
+
+ read_lock(&conn->chan_lock);
+ c = __l2cap_get_chan_by_scid(conn, cid);
+ if (c)
+ bh_lock_sock(c->sk);
+ read_unlock(&conn->chan_lock);
+ return c;
}
-static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
+static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident)
{
- struct sock *s;
- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
- if (l2cap_pi(s)->ident == ident)
- break;
+ struct l2cap_chan *c;
+
+ list_for_each_entry(c, &conn->chan_l, list) {
+ if (c->ident == ident)
+ return c;
+ }
+ return NULL;
+}
+
+static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident)
+{
+ struct l2cap_chan *c;
+
+ read_lock(&conn->chan_lock);
+ c = __l2cap_get_chan_by_ident(conn, ident);
+ if (c)
+ bh_lock_sock(c->sk);
+ read_unlock(&conn->chan_lock);
+ return c;
+}
+
+static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
+{
+ struct l2cap_chan *c;
+
+ list_for_each_entry(c, &chan_list, global_l) {
+ if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
+ goto found;
+ }
+
+ c = NULL;
+found:
+ return c;
+}
+
+int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
+{
+ int err;
+
+ write_lock_bh(&chan_list_lock);
+
+ if (psm && __l2cap_global_chan_by_addr(psm, src)) {
+ err = -EADDRINUSE;
+ goto done;
}
- return s;
+
+ if (psm) {
+ chan->psm = psm;
+ chan->sport = psm;
+ err = 0;
+ } else {
+ u16 p;
+
+ err = -EINVAL;
+ for (p = 0x1001; p < 0x1100; p += 2)
+ if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
+ chan->psm = cpu_to_le16(p);
+ chan->sport = cpu_to_le16(p);
+ err = 0;
+ break;
+ }
+ }
+
+done:
+ write_unlock_bh(&chan_list_lock);
+ return err;
}
-static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
+int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
{
- struct sock *s;
- read_lock(&l->lock);
- s = __l2cap_get_chan_by_ident(l, ident);
- if (s)
- bh_lock_sock(s);
- read_unlock(&l->lock);
- return s;
+ write_lock_bh(&chan_list_lock);
+
+ chan->scid = scid;
+
+ write_unlock_bh(&chan_list_lock);
+
+ return 0;
}
-static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
+static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
{
u16 cid = L2CAP_CID_DYN_START;
for (; cid < L2CAP_CID_DYN_END; cid++) {
- if (!__l2cap_get_chan_by_scid(l, cid))
+ if (!__l2cap_get_chan_by_scid(conn, cid))
return cid;
}
return 0;
}
-static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
+struct l2cap_chan *l2cap_chan_create(struct sock *sk)
{
- sock_hold(sk);
+ struct l2cap_chan *chan;
- if (l->head)
- l2cap_pi(l->head)->prev_c = sk;
+ chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
+ if (!chan)
+ return NULL;
- l2cap_pi(sk)->next_c = l->head;
- l2cap_pi(sk)->prev_c = NULL;
- l->head = sk;
-}
+ chan->sk = sk;
-static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
-{
- struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
+ write_lock_bh(&chan_list_lock);
+ list_add(&chan->global_l, &chan_list);
+ write_unlock_bh(&chan_list_lock);
- write_lock_bh(&l->lock);
- if (sk == l->head)
- l->head = next;
+ return chan;
+}
- if (next)
- l2cap_pi(next)->prev_c = prev;
- if (prev)
- l2cap_pi(prev)->next_c = next;
- write_unlock_bh(&l->lock);
+void l2cap_chan_destroy(struct l2cap_chan *chan)
+{
+ write_lock_bh(&chan_list_lock);
+ list_del(&chan->global_l);
+ write_unlock_bh(&chan_list_lock);
- __sock_put(sk);
+ kfree(chan);
}
-static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
+static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
{
- struct l2cap_chan_list *l = &conn->chan_list;
+ struct sock *sk = chan->sk;
BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
- l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
+ chan->psm, chan->dcid);
conn->disc_reason = 0x13;
- l2cap_pi(sk)->conn = conn;
+ chan->conn = conn;
if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
if (conn->hcon->type == LE_LINK) {
/* LE connection */
- l2cap_pi(sk)->omtu = L2CAP_LE_DEFAULT_MTU;
- l2cap_pi(sk)->scid = L2CAP_CID_LE_DATA;
- l2cap_pi(sk)->dcid = L2CAP_CID_LE_DATA;
+ chan->omtu = L2CAP_LE_DEFAULT_MTU;
+ chan->scid = L2CAP_CID_LE_DATA;
+ chan->dcid = L2CAP_CID_LE_DATA;
} else {
/* Alloc CID for connection-oriented socket */
- l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
- l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
+ chan->scid = l2cap_alloc_cid(conn);
+ chan->omtu = L2CAP_DEFAULT_MTU;
}
} else if (sk->sk_type == SOCK_DGRAM) {
/* Connectionless socket */
- l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
- l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
- l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
+ chan->scid = L2CAP_CID_CONN_LESS;
+ chan->dcid = L2CAP_CID_CONN_LESS;
+ chan->omtu = L2CAP_DEFAULT_MTU;
} else {
/* Raw socket can send/recv signalling messages only */
- l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
- l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
- l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
+ chan->scid = L2CAP_CID_SIGNALING;
+ chan->dcid = L2CAP_CID_SIGNALING;
+ chan->omtu = L2CAP_DEFAULT_MTU;
}
- __l2cap_chan_link(l, sk);
+ sock_hold(sk);
- if (parent)
- bt_accept_enqueue(parent, sk);
+ list_add(&chan->list, &conn->chan_l);
}
/* Delete channel.
* Must be called on the locked socket. */
-void l2cap_chan_del(struct sock *sk, int err)
+void l2cap_chan_del(struct l2cap_chan *chan, int err)
{
- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+ struct sock *sk = chan->sk;
+ struct l2cap_conn *conn = chan->conn;
struct sock *parent = bt_sk(sk)->parent;
l2cap_sock_clear_timer(sk);
- BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
+ BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
if (conn) {
- /* Unlink from channel list */
- l2cap_chan_unlink(&conn->chan_list, sk);
- l2cap_pi(sk)->conn = NULL;
+ /* Delete from channel list */
+ write_lock_bh(&conn->chan_lock);
+ list_del(&chan->list);
+ write_unlock_bh(&conn->chan_lock);
+ __sock_put(sk);
+
+ chan->conn = NULL;
hci_conn_put(conn->hcon);
}
@@ -239,29 +304,35 @@ void l2cap_chan_del(struct sock *sk, int err)
} else
sk->sk_state_change(sk);
- skb_queue_purge(TX_QUEUE(sk));
+ if (!(chan->conf_state & L2CAP_CONF_OUTPUT_DONE &&
+ chan->conf_state & L2CAP_CONF_INPUT_DONE))
+ return;
+
+ skb_queue_purge(&chan->tx_q);
- if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
+ if (chan->mode == L2CAP_MODE_ERTM) {
struct srej_list *l, *tmp;
- del_timer(&l2cap_pi(sk)->retrans_timer);
- del_timer(&l2cap_pi(sk)->monitor_timer);
- del_timer(&l2cap_pi(sk)->ack_timer);
+ del_timer(&chan->retrans_timer);
+ del_timer(&chan->monitor_timer);
+ del_timer(&chan->ack_timer);
- skb_queue_purge(SREJ_QUEUE(sk));
- skb_queue_purge(BUSY_QUEUE(sk));
+ skb_queue_purge(&chan->srej_q);
+ skb_queue_purge(&chan->busy_q);
- list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
+ list_for_each_entry_safe(l, tmp, &chan->srej_l, list) {
list_del(&l->list);
kfree(l);
}
}
}
-static inline u8 l2cap_get_auth_type(struct sock *sk)
+static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
{
+ struct sock *sk = chan->sk;
+
if (sk->sk_type == SOCK_RAW) {
- switch (l2cap_pi(sk)->sec_level) {
+ switch (chan->sec_level) {
case BT_SECURITY_HIGH:
return HCI_AT_DEDICATED_BONDING_MITM;
case BT_SECURITY_MEDIUM:
@@ -269,16 +340,16 @@ static inline u8 l2cap_get_auth_type(struct sock *sk)
default:
return HCI_AT_NO_BONDING;
}
- } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
- if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
- l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
+ } else if (chan->psm == cpu_to_le16(0x0001)) {
+ if (chan->sec_level == BT_SECURITY_LOW)
+ chan->sec_level = BT_SECURITY_SDP;
- if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
+ if (chan->sec_level == BT_SECURITY_HIGH)
return HCI_AT_NO_BONDING_MITM;
else
return HCI_AT_NO_BONDING;
} else {
- switch (l2cap_pi(sk)->sec_level) {
+ switch (chan->sec_level) {
case BT_SECURITY_HIGH:
return HCI_AT_GENERAL_BONDING_MITM;
case BT_SECURITY_MEDIUM:
@@ -290,15 +361,14 @@ static inline u8 l2cap_get_auth_type(struct sock *sk)
}
/* Service level security */
-static inline int l2cap_check_security(struct sock *sk)
+static inline int l2cap_check_security(struct l2cap_chan *chan)
{
- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+ struct l2cap_conn *conn = chan->conn;
__u8 auth_type;
- auth_type = l2cap_get_auth_type(sk);
+ auth_type = l2cap_get_auth_type(chan);
- return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
- auth_type);
+ return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
}
u8 l2cap_get_ident(struct l2cap_conn *conn)
@@ -341,11 +411,12 @@ void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *d
hci_send_acl(conn->hcon, skb, flags);
}
-static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
+static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control)
{
struct sk_buff *skb;
struct l2cap_hdr *lh;
- struct l2cap_conn *conn = pi->conn;
+ struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
+ struct l2cap_conn *conn = chan->conn;
struct sock *sk = (struct sock *)pi;
int count, hlen = L2CAP_HDR_SIZE + 2;
u8 flags;
@@ -353,22 +424,22 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
if (sk->sk_state != BT_CONNECTED)
return;
- if (pi->fcs == L2CAP_FCS_CRC16)
+ if (chan->fcs == L2CAP_FCS_CRC16)
hlen += 2;
- BT_DBG("pi %p, control 0x%2.2x", pi, control);
+ BT_DBG("chan %p, control 0x%2.2x", chan, control);
count = min_t(unsigned int, conn->mtu, hlen);
control |= L2CAP_CTRL_FRAME_TYPE;
- if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
+ if (chan->conn_state & L2CAP_CONN_SEND_FBIT) {
control |= L2CAP_CTRL_FINAL;
- pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
+ chan->conn_state &= ~L2CAP_CONN_SEND_FBIT;
}
- if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
+ if (chan->conn_state & L2CAP_CONN_SEND_PBIT) {
control |= L2CAP_CTRL_POLL;
- pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
+ chan->conn_state &= ~L2CAP_CONN_SEND_PBIT;
}
skb = bt_skb_alloc(count, GFP_ATOMIC);
@@ -377,10 +448,10 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
- lh->cid = cpu_to_le16(pi->dcid);
+ lh->cid = cpu_to_le16(chan->dcid);
put_unaligned_le16(control, skb_put(skb, 2));
- if (pi->fcs == L2CAP_FCS_CRC16) {
+ if (chan->fcs == L2CAP_FCS_CRC16) {
u16 fcs = crc16(0, (u8 *)lh, count - 2);
put_unaligned_le16(fcs, skb_put(skb, 2));
}
@@ -390,45 +461,46 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
else
flags = ACL_START;
- hci_send_acl(pi->conn->hcon, skb, flags);
+ hci_send_acl(chan->conn->hcon, skb, flags);
}
-static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
+static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control)
{
- if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
+ if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
control |= L2CAP_SUPER_RCV_NOT_READY;
- pi->conn_state |= L2CAP_CONN_RNR_SENT;
+ chan->conn_state |= L2CAP_CONN_RNR_SENT;
} else
control |= L2CAP_SUPER_RCV_READY;
- control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
- l2cap_send_sframe(pi, control);
+ l2cap_send_sframe(chan, control);
}
-static inline int __l2cap_no_conn_pending(struct sock *sk)
+static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
{
- return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
+ return !(chan->conf_state & L2CAP_CONF_CONNECT_PEND);
}
-static void l2cap_do_start(struct sock *sk)
+static void l2cap_do_start(struct l2cap_chan *chan)
{
- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+ struct l2cap_conn *conn = chan->conn;
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
return;
- if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
+ if (l2cap_check_security(chan) &&
+ __l2cap_no_conn_pending(chan)) {
struct l2cap_conn_req req;
- req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
- req.psm = l2cap_pi(sk)->psm;
+ req.scid = cpu_to_le16(chan->scid);
+ req.psm = chan->psm;
- l2cap_pi(sk)->ident = l2cap_get_ident(conn);
- l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
+ chan->ident = l2cap_get_ident(conn);
+ chan->conf_state |= L2CAP_CONF_CONNECT_PEND;
- l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
- L2CAP_CONN_REQ, sizeof(req), &req);
+ l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ,
+ sizeof(req), &req);
}
} else {
struct l2cap_info_req req;
@@ -461,23 +533,24 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
}
}
-void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
+void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
{
+ struct sock *sk;
struct l2cap_disconn_req req;
if (!conn)
return;
- skb_queue_purge(TX_QUEUE(sk));
+ sk = chan->sk;
- if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
- del_timer(&l2cap_pi(sk)->retrans_timer);
- del_timer(&l2cap_pi(sk)->monitor_timer);
- del_timer(&l2cap_pi(sk)->ack_timer);
+ if (chan->mode == L2CAP_MODE_ERTM) {
+ del_timer(&chan->retrans_timer);
+ del_timer(&chan->monitor_timer);
+ del_timer(&chan->ack_timer);
}
- req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
- req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
+ req.dcid = cpu_to_le16(chan->dcid);
+ req.scid = cpu_to_le16(chan->scid);
l2cap_send_cmd(conn, l2cap_get_ident(conn),
L2CAP_DISCONN_REQ, sizeof(req), &req);
@@ -488,17 +561,15 @@ void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
/* ---- L2CAP connections ---- */
static void l2cap_conn_start(struct l2cap_conn *conn)
{
- struct l2cap_chan_list *l = &conn->chan_list;
- struct sock_del_list del, *tmp1, *tmp2;
- struct sock *sk;
+ struct l2cap_chan *chan, *tmp;
BT_DBG("conn %p", conn);
- INIT_LIST_HEAD(&del.list);
+ read_lock(&conn->chan_lock);
- read_lock(&l->lock);
+ list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
+ struct sock *sk = chan->sk;
- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
bh_lock_sock(sk);
if (sk->sk_type != SOCK_SEQPACKET &&
@@ -510,40 +581,41 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
if (sk->sk_state == BT_CONNECT) {
struct l2cap_conn_req req;
- if (!l2cap_check_security(sk) ||
- !__l2cap_no_conn_pending(sk)) {
+ if (!l2cap_check_security(chan) ||
+ !__l2cap_no_conn_pending(chan)) {
bh_unlock_sock(sk);
continue;
}
- if (!l2cap_mode_supported(l2cap_pi(sk)->mode,
+ if (!l2cap_mode_supported(chan->mode,
conn->feat_mask)
- && l2cap_pi(sk)->conf_state &
+ && chan->conf_state &
L2CAP_CONF_STATE2_DEVICE) {
- tmp1 = kzalloc(sizeof(struct sock_del_list),
- GFP_ATOMIC);
- tmp1->sk = sk;
- list_add_tail(&tmp1->list, &del.list);
+ /* __l2cap_sock_close() calls list_del(chan)
+ * so release the lock */
+ read_unlock_bh(&conn->chan_lock);
+ __l2cap_sock_close(sk, ECONNRESET);
+ read_lock_bh(&conn->chan_lock);
bh_unlock_sock(sk);
continue;
}
- req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
- req.psm = l2cap_pi(sk)->psm;
+ req.scid = cpu_to_le16(chan->scid);
+ req.psm = chan->psm;
- l2cap_pi(sk)->ident = l2cap_get_ident(conn);
- l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
+ chan->ident = l2cap_get_ident(conn);
+ chan->conf_state |= L2CAP_CONF_CONNECT_PEND;
- l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
- L2CAP_CONN_REQ, sizeof(req), &req);
+ l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ,
+ sizeof(req), &req);
} else if (sk->sk_state == BT_CONNECT2) {
struct l2cap_conn_rsp rsp;
char buf[128];
- rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
- rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
+ rsp.scid = cpu_to_le16(chan->dcid);
+ rsp.dcid = cpu_to_le16(chan->scid);
- if (l2cap_check_security(sk)) {
+ if (l2cap_check_security(chan)) {
if (bt_sk(sk)->defer_setup) {
struct sock *parent = bt_sk(sk)->parent;
rsp.result = cpu_to_le16(L2CAP_CR_PEND);
@@ -560,80 +632,77 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
}
- l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
- L2CAP_CONN_RSP, sizeof(rsp), &rsp);
+ l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
+ sizeof(rsp), &rsp);
- if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT ||
+ if (chan->conf_state & L2CAP_CONF_REQ_SENT ||
rsp.result != L2CAP_CR_SUCCESS) {
bh_unlock_sock(sk);
continue;
}
- l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
+ chan->conf_state |= L2CAP_CONF_REQ_SENT;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(sk, buf), buf);
- l2cap_pi(sk)->num_conf_req++;
+ l2cap_build_conf_req(chan, buf), buf);
+ chan->num_conf_req++;
}
bh_unlock_sock(sk);
}
- read_unlock(&l->lock);
-
- list_for_each_entry_safe(tmp1, tmp2, &del.list, list) {
- bh_lock_sock(tmp1->sk);
- __l2cap_sock_close(tmp1->sk, ECONNRESET);
- bh_unlock_sock(tmp1->sk);
- list_del(&tmp1->list);
- kfree(tmp1);
- }
+ read_unlock(&conn->chan_lock);
}
/* Find socket with cid and source bdaddr.
* Returns closest match, locked.
*/
-static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src)
+static struct l2cap_chan *l2cap_global_chan_by_scid(int state, __le16 cid, bdaddr_t *src)
{
- struct sock *s, *sk = NULL, *sk1 = NULL;
- struct hlist_node *node;
+ struct l2cap_chan *c, *c1 = NULL;
+
+ read_lock(&chan_list_lock);
- read_lock(&l2cap_sk_list.lock);
+ list_for_each_entry(c, &chan_list, global_l) {
+ struct sock *sk = c->sk;
- sk_for_each(sk, node, &l2cap_sk_list.head) {
if (state && sk->sk_state != state)
continue;
- if (l2cap_pi(sk)->scid == cid) {
+ if (c->scid == cid) {
/* Exact match. */
- if (!bacmp(&bt_sk(sk)->src, src))
- break;
+ if (!bacmp(&bt_sk(sk)->src, src)) {
+ read_unlock(&chan_list_lock);
+ return c;
+ }
/* Closest match */
if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
- sk1 = sk;
+ c1 = c;
}
}
- s = node ? sk : sk1;
- if (s)
- bh_lock_sock(s);
- read_unlock(&l2cap_sk_list.lock);
- return s;
+ read_unlock(&chan_list_lock);
+
+ return c1;
}
static void l2cap_le_conn_ready(struct l2cap_conn *conn)
{
- struct l2cap_chan_list *list = &conn->chan_list;
- struct sock *parent, *uninitialized_var(sk);
+ struct sock *parent, *sk;
+ struct l2cap_chan *chan, *pchan;
BT_DBG("");
/* Check if we have socket listening on cid */
- parent = l2cap_get_sock_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
+ pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
conn->src);
- if (!parent)
+ if (!pchan)
return;
+ parent = pchan->sk;
+
+ bh_lock_sock(parent);
+
/* Check for backlog size */
if (sk_acceptq_is_full(parent)) {
BT_DBG("backlog full %d", parent->sk_ack_backlog);
@@ -644,22 +713,33 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
if (!sk)
goto clean;
- write_lock_bh(&list->lock);
+ chan = l2cap_chan_create(sk);
+ if (!chan) {
+ l2cap_sock_kill(sk);
+ goto clean;
+ }
+
+ l2cap_pi(sk)->chan = chan;
+
+ write_lock_bh(&conn->chan_lock);
hci_conn_hold(conn->hcon);
l2cap_sock_init(sk, parent);
+
bacpy(&bt_sk(sk)->src, conn->src);
bacpy(&bt_sk(sk)->dst, conn->dst);
- __l2cap_chan_add(conn, sk, parent);
+ bt_accept_enqueue(parent, sk);
+
+ __l2cap_chan_add(conn, chan);
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
sk->sk_state = BT_CONNECTED;
parent->sk_data_ready(parent, 0);
- write_unlock_bh(&list->lock);
+ write_unlock_bh(&conn->chan_lock);
clean:
bh_unlock_sock(parent);
@@ -667,17 +747,18 @@ clean:
static void l2cap_conn_ready(struct l2cap_conn *conn)
{
- struct l2cap_chan_list *l = &conn->chan_list;
- struct sock *sk;
+ struct l2cap_chan *chan;
BT_DBG("conn %p", conn);
if (!conn->hcon->out && conn->hcon->type == LE_LINK)
l2cap_le_conn_ready(conn);
- read_lock(&l->lock);
+ read_lock(&conn->chan_lock);
+
+ list_for_each_entry(chan, &conn->chan_l, list) {
+ struct sock *sk = chan->sk;
- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
bh_lock_sock(sk);
if (conn->hcon->type == LE_LINK) {
@@ -692,30 +773,31 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
sk->sk_state = BT_CONNECTED;
sk->sk_state_change(sk);
} else if (sk->sk_state == BT_CONNECT)
- l2cap_do_start(sk);
+ l2cap_do_start(chan);
bh_unlock_sock(sk);
}
- read_unlock(&l->lock);
+ read_unlock(&conn->chan_lock);
}
/* Notify sockets that we cannot guaranty reliability anymore */
static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
{
- struct l2cap_chan_list *l = &conn->chan_list;
- struct sock *sk;
+ struct l2cap_chan *chan;
BT_DBG("conn %p", conn);
- read_lock(&l->lock);
+ read_lock(&conn->chan_lock);
- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
- if (l2cap_pi(sk)->force_reliable)
+ list_for_each_entry(chan, &conn->chan_l, list) {
+ struct sock *sk = chan->sk;
+
+ if (chan->force_reliable)
sk->sk_err = err;
}
- read_unlock(&l->lock);
+ read_unlock(&conn->chan_lock);
}
static void l2cap_info_timeout(unsigned long arg)
@@ -755,7 +837,9 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
conn->feat_mask = 0;
spin_lock_init(&conn->lock);
- rwlock_init(&conn->chan_list.lock);
+ rwlock_init(&conn->chan_lock);
+
+ INIT_LIST_HEAD(&conn->chan_l);
if (hcon->type != LE_LINK)
setup_timer(&conn->info_timer, l2cap_info_timeout,
@@ -769,6 +853,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
static void l2cap_conn_del(struct hci_conn *hcon, int err)
{
struct l2cap_conn *conn = hcon->l2cap_data;
+ struct l2cap_chan *chan, *l;
struct sock *sk;
if (!conn)
@@ -779,9 +864,10 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
kfree_skb(conn->rx_skb);
/* Kill channels */
- while ((sk = conn->chan_list.head)) {
+ list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
+ sk = chan->sk;
bh_lock_sock(sk);
- l2cap_chan_del(sk, err);
+ l2cap_chan_del(chan, err);
bh_unlock_sock(sk);
l2cap_sock_kill(sk);
}
@@ -793,12 +879,11 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
kfree(conn);
}
-static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
{
- struct l2cap_chan_list *l = &conn->chan_list;
- write_lock_bh(&l->lock);
- __l2cap_chan_add(conn, sk, parent);
- write_unlock_bh(&l->lock);
+ write_lock_bh(&conn->chan_lock);
+ __l2cap_chan_add(conn, chan);
+ write_unlock_bh(&conn->chan_lock);
}
/* ---- Socket interface ---- */
@@ -806,35 +891,39 @@ static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, stru
/* Find socket with psm and source bdaddr.
* Returns closest match.
*/
-static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
+static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr_t *src)
{
- struct sock *sk = NULL, *sk1 = NULL;
- struct hlist_node *node;
+ struct l2cap_chan *c, *c1 = NULL;
- read_lock(&l2cap_sk_list.lock);
+ read_lock(&chan_list_lock);
+
+ list_for_each_entry(c, &chan_list, global_l) {
+ struct sock *sk = c->sk;
- sk_for_each(sk, node, &l2cap_sk_list.head) {
if (state && sk->sk_state != state)
continue;
- if (l2cap_pi(sk)->psm == psm) {
+ if (c->psm == psm) {
/* Exact match. */
- if (!bacmp(&bt_sk(sk)->src, src))
- break;
+ if (!bacmp(&bt_sk(sk)->src, src)) {
+ read_unlock_bh(&chan_list_lock);
+ return c;
+ }
/* Closest match */
if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
- sk1 = sk;
+ c1 = c;
}
}
- read_unlock(&l2cap_sk_list.lock);
+ read_unlock(&chan_list_lock);
- return node ? sk : sk1;
+ return c1;
}
-int l2cap_do_connect(struct sock *sk)
+int l2cap_chan_connect(struct l2cap_chan *chan)
{
+ struct sock *sk = chan->sk;
bdaddr_t *src = &bt_sk(sk)->src;
bdaddr_t *dst = &bt_sk(sk)->dst;
struct l2cap_conn *conn;
@@ -844,7 +933,7 @@ int l2cap_do_connect(struct sock *sk)
int err;
BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
- l2cap_pi(sk)->psm);
+ chan->psm);
hdev = hci_get_route(dst, src);
if (!hdev)
@@ -852,14 +941,14 @@ int l2cap_do_connect(struct sock *sk)
hci_dev_lock_bh(hdev);
- auth_type = l2cap_get_auth_type(sk);
+ auth_type = l2cap_get_auth_type(chan);
- if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA)
+ if (chan->dcid == L2CAP_CID_LE_DATA)
hcon = hci_connect(hdev, LE_LINK, dst,
- l2cap_pi(sk)->sec_level, auth_type);
+ chan->sec_level, auth_type);
else
hcon = hci_connect(hdev, ACL_LINK, dst,
- l2cap_pi(sk)->sec_level, auth_type);
+ chan->sec_level, auth_type);
if (IS_ERR(hcon)) {
err = PTR_ERR(hcon);
@@ -876,7 +965,7 @@ int l2cap_do_connect(struct sock *sk)
/* Update source addr of the socket */
bacpy(src, conn->src);
- l2cap_chan_add(conn, sk, NULL);
+ l2cap_chan_add(conn, chan);
sk->sk_state = BT_CONNECT;
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
@@ -885,10 +974,10 @@ int l2cap_do_connect(struct sock *sk)
if (sk->sk_type != SOCK_SEQPACKET &&
sk->sk_type != SOCK_STREAM) {
l2cap_sock_clear_timer(sk);
- if (l2cap_check_security(sk))
+ if (l2cap_check_security(chan))
sk->sk_state = BT_CONNECTED;
} else
- l2cap_do_start(sk);
+ l2cap_do_start(chan);
}
err = 0;
@@ -901,12 +990,13 @@ done:
int __l2cap_wait_ack(struct sock *sk)
{
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
DECLARE_WAITQUEUE(wait, current);
int err = 0;
int timeo = HZ/5;
add_wait_queue(sk_sleep(sk), &wait);
- while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
+ while ((chan->unacked_frames > 0 && chan->conn)) {
set_current_state(TASK_INTERRUPTIBLE);
if (!timeo)
@@ -932,68 +1022,69 @@ int __l2cap_wait_ack(struct sock *sk)
static void l2cap_monitor_timeout(unsigned long arg)
{
- struct sock *sk = (void *) arg;
+ struct l2cap_chan *chan = (void *) arg;
+ struct sock *sk = chan->sk;
- BT_DBG("sk %p", sk);
+ BT_DBG("chan %p", chan);
bh_lock_sock(sk);
- if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
- l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
+ if (chan->retry_count >= chan->remote_max_tx) {
+ l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
bh_unlock_sock(sk);
return;
}
- l2cap_pi(sk)->retry_count++;
+ chan->retry_count++;
__mod_monitor_timer();
- l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
+ l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
bh_unlock_sock(sk);
}
static void l2cap_retrans_timeout(unsigned long arg)
{
- struct sock *sk = (void *) arg;
+ struct l2cap_chan *chan = (void *) arg;
+ struct sock *sk = chan->sk;
- BT_DBG("sk %p", sk);
+ BT_DBG("chan %p", chan);
bh_lock_sock(sk);
- l2cap_pi(sk)->retry_count = 1;
+ chan->retry_count = 1;
__mod_monitor_timer();
- l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
+ chan->conn_state |= L2CAP_CONN_WAIT_F;
- l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
+ l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
bh_unlock_sock(sk);
}
-static void l2cap_drop_acked_frames(struct sock *sk)
+static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
{
struct sk_buff *skb;
- while ((skb = skb_peek(TX_QUEUE(sk))) &&
- l2cap_pi(sk)->unacked_frames) {
- if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
+ while ((skb = skb_peek(&chan->tx_q)) &&
+ chan->unacked_frames) {
+ if (bt_cb(skb)->tx_seq == chan->expected_ack_seq)
break;
- skb = skb_dequeue(TX_QUEUE(sk));
+ skb = skb_dequeue(&chan->tx_q);
kfree_skb(skb);
- l2cap_pi(sk)->unacked_frames--;
+ chan->unacked_frames--;
}
- if (!l2cap_pi(sk)->unacked_frames)
- del_timer(&l2cap_pi(sk)->retrans_timer);
+ if (!chan->unacked_frames)
+ del_timer(&chan->retrans_timer);
}
-void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
+void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
- struct hci_conn *hcon = pi->conn->hcon;
+ struct hci_conn *hcon = chan->conn->hcon;
u16 flags;
- BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
+ BT_DBG("chan %p, skb %p len %d", chan, skb, skb->len);
- if (!pi->flushable && lmp_no_flush_capable(hcon->hdev))
+ if (!chan->flushable && lmp_no_flush_capable(hcon->hdev))
flags = ACL_START_NO_FLUSH;
else
flags = ACL_START;
@@ -1001,35 +1092,33 @@ void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
hci_send_acl(hcon, skb, flags);
}
-void l2cap_streaming_send(struct sock *sk)
+void l2cap_streaming_send(struct l2cap_chan *chan)
{
struct sk_buff *skb;
- struct l2cap_pinfo *pi = l2cap_pi(sk);
u16 control, fcs;
- while ((skb = skb_dequeue(TX_QUEUE(sk)))) {
+ while ((skb = skb_dequeue(&chan->tx_q))) {
control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE);
- control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
+ control |= chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
- if (pi->fcs == L2CAP_FCS_CRC16) {
+ if (chan->fcs == L2CAP_FCS_CRC16) {
fcs = crc16(0, (u8 *)skb->data, skb->len - 2);
put_unaligned_le16(fcs, skb->data + skb->len - 2);
}
- l2cap_do_send(sk, skb);
+ l2cap_do_send(chan, skb);
- pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
+ chan->next_tx_seq = (chan->next_tx_seq + 1) % 64;
}
}
-static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
+static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
struct sk_buff *skb, *tx_skb;
u16 control, fcs;
- skb = skb_peek(TX_QUEUE(sk));
+ skb = skb_peek(&chan->tx_q);
if (!skb)
return;
@@ -1037,14 +1126,14 @@ static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
if (bt_cb(skb)->tx_seq == tx_seq)
break;
- if (skb_queue_is_last(TX_QUEUE(sk), skb))
+ if (skb_queue_is_last(&chan->tx_q, skb))
return;
- } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
+ } while ((skb = skb_queue_next(&chan->tx_q, skb)));
- if (pi->remote_max_tx &&
- bt_cb(skb)->retries == pi->remote_max_tx) {
- l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
+ if (chan->remote_max_tx &&
+ bt_cb(skb)->retries == chan->remote_max_tx) {
+ l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
return;
}
@@ -1053,39 +1142,39 @@ static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
control &= L2CAP_CTRL_SAR;
- if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
+ if (chan->conn_state & L2CAP_CONN_SEND_FBIT) {
control |= L2CAP_CTRL_FINAL;
- pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
+ chan->conn_state &= ~L2CAP_CONN_SEND_FBIT;
}
- control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
+ control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
| (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
- if (pi->fcs == L2CAP_FCS_CRC16) {
+ if (chan->fcs == L2CAP_FCS_CRC16) {
fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
}
- l2cap_do_send(sk, tx_skb);
+ l2cap_do_send(chan, tx_skb);
}
-int l2cap_ertm_send(struct sock *sk)
+int l2cap_ertm_send(struct l2cap_chan *chan)
{
struct sk_buff *skb, *tx_skb;
- struct l2cap_pinfo *pi = l2cap_pi(sk);
+ struct sock *sk = chan->sk;
u16 control, fcs;
int nsent = 0;
if (sk->sk_state != BT_CONNECTED)
return -ENOTCONN;
- while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
+ while ((skb = chan->tx_send_head) && (!l2cap_tx_window_full(chan))) {
- if (pi->remote_max_tx &&
- bt_cb(skb)->retries == pi->remote_max_tx) {
- l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
+ if (chan->remote_max_tx &&
+ bt_cb(skb)->retries == chan->remote_max_tx) {
+ l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
break;
}
@@ -1096,36 +1185,36 @@ int l2cap_ertm_send(struct sock *sk)
control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
control &= L2CAP_CTRL_SAR;
- if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
+ if (chan->conn_state & L2CAP_CONN_SEND_FBIT) {
control |= L2CAP_CTRL_FINAL;
- pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
+ chan->conn_state &= ~L2CAP_CONN_SEND_FBIT;
}
- control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
- | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
+ control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
+ | (chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
- if (pi->fcs == L2CAP_FCS_CRC16) {
+ if (chan->fcs == L2CAP_FCS_CRC16) {
fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
}
- l2cap_do_send(sk, tx_skb);
+ l2cap_do_send(chan, tx_skb);
__mod_retrans_timer();
- bt_cb(skb)->tx_seq = pi->next_tx_seq;
- pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
+ bt_cb(skb)->tx_seq = chan->next_tx_seq;
+ chan->next_tx_seq = (chan->next_tx_seq + 1) % 64;
if (bt_cb(skb)->retries == 1)
- pi->unacked_frames++;
+ chan->unacked_frames++;
- pi->frames_sent++;
+ chan->frames_sent++;
- if (skb_queue_is_last(TX_QUEUE(sk), skb))
- sk->sk_send_head = NULL;
+ if (skb_queue_is_last(&chan->tx_q, skb))
+ chan->tx_send_head = NULL;
else
- sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
+ chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
nsent++;
}
@@ -1133,41 +1222,39 @@ int l2cap_ertm_send(struct sock *sk)
return nsent;
}
-static int l2cap_retransmit_frames(struct sock *sk)
+static int l2cap_retransmit_frames(struct l2cap_chan *chan)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
int ret;
- if (!skb_queue_empty(TX_QUEUE(sk)))
- sk->sk_send_head = TX_QUEUE(sk)->next;
+ if (!skb_queue_empty(&chan->tx_q))
+ chan->tx_send_head = chan->tx_q.next;
- pi->next_tx_seq = pi->expected_ack_seq;
- ret = l2cap_ertm_send(sk);
+ chan->next_tx_seq = chan->expected_ack_seq;
+ ret = l2cap_ertm_send(chan);
return ret;
}
-static void l2cap_send_ack(struct l2cap_pinfo *pi)
+static void l2cap_send_ack(struct l2cap_chan *chan)
{
- struct sock *sk = (struct sock *)pi;
u16 control = 0;
- control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
- if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
+ if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
control |= L2CAP_SUPER_RCV_NOT_READY;
- pi->conn_state |= L2CAP_CONN_RNR_SENT;
- l2cap_send_sframe(pi, control);
+ chan->conn_state |= L2CAP_CONN_RNR_SENT;
+ l2cap_send_sframe(chan, control);
return;
}
- if (l2cap_ertm_send(sk) > 0)
+ if (l2cap_ertm_send(chan) > 0)
return;
control |= L2CAP_SUPER_RCV_READY;
- l2cap_send_sframe(pi, control);
+ l2cap_send_sframe(chan, control);
}
-static void l2cap_send_srejtail(struct sock *sk)
+static void l2cap_send_srejtail(struct l2cap_chan *chan)
{
struct srej_list *tail;
u16 control;
@@ -1175,15 +1262,15 @@ static void l2cap_send_srejtail(struct sock *sk)
control = L2CAP_SUPER_SELECT_REJECT;
control |= L2CAP_CTRL_FINAL;
- tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
+ tail = list_entry((&chan->srej_l)->prev, struct srej_list, list);
control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
- l2cap_send_sframe(l2cap_pi(sk), control);
+ l2cap_send_sframe(chan, control);
}
static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb)
{
- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+ struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
struct sk_buff **frag;
int err, sent = 0;
@@ -1213,9 +1300,10 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in
return sent;
}
-struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
+struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
{
- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+ struct sock *sk = chan->sk;
+ struct l2cap_conn *conn = chan->conn;
struct sk_buff *skb;
int err, count, hlen = L2CAP_HDR_SIZE + 2;
struct l2cap_hdr *lh;
@@ -1230,9 +1318,9 @@ struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, s
/* Create L2CAP header */
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
- lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
+ lh->cid = cpu_to_le16(chan->dcid);
lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
- put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
+ put_unaligned_le16(chan->psm, skb_put(skb, 2));
err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
if (unlikely(err < 0)) {
@@ -1242,9 +1330,10 @@ struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, s
return skb;
}
-struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
+struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
{
- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+ struct sock *sk = chan->sk;
+ struct l2cap_conn *conn = chan->conn;
struct sk_buff *skb;
int err, count, hlen = L2CAP_HDR_SIZE;
struct l2cap_hdr *lh;
@@ -1259,7 +1348,7 @@ struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size
/* Create L2CAP header */
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
- lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
+ lh->cid = cpu_to_le16(chan->dcid);
lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
@@ -1270,9 +1359,10 @@ struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size
return skb;
}
-struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
+struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
{
- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+ struct sock *sk = chan->sk;
+ struct l2cap_conn *conn = chan->conn;
struct sk_buff *skb;
int err, count, hlen = L2CAP_HDR_SIZE + 2;
struct l2cap_hdr *lh;
@@ -1285,7 +1375,7 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz
if (sdulen)
hlen += 2;
- if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
+ if (chan->fcs == L2CAP_FCS_CRC16)
hlen += 2;
count = min_t(unsigned int, (conn->mtu - hlen), len);
@@ -1296,7 +1386,7 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz
/* Create L2CAP header */
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
- lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
+ lh->cid = cpu_to_le16(chan->dcid);
lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
put_unaligned_le16(control, skb_put(skb, 2));
if (sdulen)
@@ -1308,16 +1398,15 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz
return ERR_PTR(err);
}
- if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
+ if (chan->fcs == L2CAP_FCS_CRC16)
put_unaligned_le16(0, skb_put(skb, 2));
bt_cb(skb)->retries = 0;
return skb;
}
-int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
+int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
struct sk_buff *skb;
struct sk_buff_head sar_queue;
u16 control;
@@ -1325,26 +1414,26 @@ int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
skb_queue_head_init(&sar_queue);
control = L2CAP_SDU_START;
- skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
+ skb = l2cap_create_iframe_pdu(chan, msg, chan->remote_mps, control, len);
if (IS_ERR(skb))
return PTR_ERR(skb);
__skb_queue_tail(&sar_queue, skb);
- len -= pi->remote_mps;
- size += pi->remote_mps;
+ len -= chan->remote_mps;
+ size += chan->remote_mps;
while (len > 0) {
size_t buflen;
- if (len > pi->remote_mps) {
+ if (len > chan->remote_mps) {
control = L2CAP_SDU_CONTINUE;
- buflen = pi->remote_mps;
+ buflen = chan->remote_mps;
} else {
control = L2CAP_SDU_END;
buflen = len;
}
- skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
+ skb = l2cap_create_iframe_pdu(chan, msg, buflen, control, 0);
if (IS_ERR(skb)) {
skb_queue_purge(&sar_queue);
return PTR_ERR(skb);
@@ -1354,9 +1443,9 @@ int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
len -= buflen;
size += buflen;
}
- skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
- if (sk->sk_send_head == NULL)
- sk->sk_send_head = sar_queue.next;
+ skb_queue_splice_tail(&sar_queue, &chan->tx_q);
+ if (chan->tx_send_head == NULL)
+ chan->tx_send_head = sar_queue.next;
return size;
}
@@ -1364,10 +1453,11 @@ int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
static void l2cap_chan_ready(struct sock *sk)
{
struct sock *parent = bt_sk(sk)->parent;
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
BT_DBG("sk %p, parent %p", sk, parent);
- l2cap_pi(sk)->conf_state = 0;
+ chan->conf_state = 0;
l2cap_sock_clear_timer(sk);
if (!parent) {
@@ -1387,14 +1477,14 @@ static void l2cap_chan_ready(struct sock *sk)
/* Copy frame to all raw sockets on that connection */
static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
{
- struct l2cap_chan_list *l = &conn->chan_list;
struct sk_buff *nskb;
- struct sock *sk;
+ struct l2cap_chan *chan;
BT_DBG("conn %p", conn);
- read_lock(&l->lock);
- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+ read_lock(&conn->chan_lock);
+ list_for_each_entry(chan, &conn->chan_l, list) {
+ struct sock *sk = chan->sk;
if (sk->sk_type != SOCK_RAW)
continue;
@@ -1408,7 +1498,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
if (sock_queue_rcv_skb(sk, nskb))
kfree_skb(nskb);
}
- read_unlock(&l->lock);
+ read_unlock(&conn->chan_lock);
}
/* ---- L2CAP signalling commands ---- */
@@ -1540,32 +1630,35 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
static void l2cap_ack_timeout(unsigned long arg)
{
- struct sock *sk = (void *) arg;
+ struct l2cap_chan *chan = (void *) arg;
- bh_lock_sock(sk);
- l2cap_send_ack(l2cap_pi(sk));
- bh_unlock_sock(sk);
+ bh_lock_sock(chan->sk);
+ l2cap_send_ack(chan);
+ bh_unlock_sock(chan->sk);
}
-static inline void l2cap_ertm_init(struct sock *sk)
+static inline void l2cap_ertm_init(struct l2cap_chan *chan)
{
- l2cap_pi(sk)->expected_ack_seq = 0;
- l2cap_pi(sk)->unacked_frames = 0;
- l2cap_pi(sk)->buffer_seq = 0;
- l2cap_pi(sk)->num_acked = 0;
- l2cap_pi(sk)->frames_sent = 0;
+ struct sock *sk = chan->sk;
+
+ chan->expected_ack_seq = 0;
+ chan->unacked_frames = 0;
+ chan->buffer_seq = 0;
+ chan->num_acked = 0;
+ chan->frames_sent = 0;
- setup_timer(&l2cap_pi(sk)->retrans_timer,
- l2cap_retrans_timeout, (unsigned long) sk);
- setup_timer(&l2cap_pi(sk)->monitor_timer,
- l2cap_monitor_timeout, (unsigned long) sk);
- setup_timer(&l2cap_pi(sk)->ack_timer,
- l2cap_ack_timeout, (unsigned long) sk);
+ setup_timer(&chan->retrans_timer, l2cap_retrans_timeout,
+ (unsigned long) chan);
+ setup_timer(&chan->monitor_timer, l2cap_monitor_timeout,
+ (unsigned long) chan);
+ setup_timer(&chan->ack_timer, l2cap_ack_timeout, (unsigned long) chan);
- __skb_queue_head_init(SREJ_QUEUE(sk));
- __skb_queue_head_init(BUSY_QUEUE(sk));
+ skb_queue_head_init(&chan->srej_q);
+ skb_queue_head_init(&chan->busy_q);
- INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
+ INIT_LIST_HEAD(&chan->srej_l);
+
+ INIT_WORK(&chan->busy_work, l2cap_busy_work);
sk->sk_backlog_rcv = l2cap_ertm_data_rcv;
}
@@ -1583,38 +1676,37 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
}
}
-int l2cap_build_conf_req(struct sock *sk, void *data)
+static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
struct l2cap_conf_req *req = data;
- struct l2cap_conf_rfc rfc = { .mode = pi->mode };
+ struct l2cap_conf_rfc rfc = { .mode = chan->mode };
void *ptr = req->data;
- BT_DBG("sk %p", sk);
+ BT_DBG("chan %p", chan);
- if (pi->num_conf_req || pi->num_conf_rsp)
+ if (chan->num_conf_req || chan->num_conf_rsp)
goto done;
- switch (pi->mode) {
+ switch (chan->mode) {
case L2CAP_MODE_STREAMING:
case L2CAP_MODE_ERTM:
- if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE)
+ if (chan->conf_state & L2CAP_CONF_STATE2_DEVICE)
break;
/* fall through */
default:
- pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
+ chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
break;
}
done:
- if (pi->imtu != L2CAP_DEFAULT_MTU)
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
+ if (chan->imtu != L2CAP_DEFAULT_MTU)
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
- switch (pi->mode) {
+ switch (chan->mode) {
case L2CAP_MODE_BASIC:
- if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) &&
- !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING))
+ if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
+ !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
break;
rfc.mode = L2CAP_MODE_BASIC;
@@ -1630,24 +1722,24 @@ done:
case L2CAP_MODE_ERTM:
rfc.mode = L2CAP_MODE_ERTM;
- rfc.txwin_size = pi->tx_win;
- rfc.max_transmit = pi->max_tx;
+ rfc.txwin_size = chan->tx_win;
+ rfc.max_transmit = chan->max_tx;
rfc.retrans_timeout = 0;
rfc.monitor_timeout = 0;
rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
- if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
- rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
+ if (L2CAP_DEFAULT_MAX_PDU_SIZE > chan->conn->mtu - 10)
+ rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
(unsigned long) &rfc);
- if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
+ if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
break;
- if (pi->fcs == L2CAP_FCS_NONE ||
- pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
- pi->fcs = L2CAP_FCS_NONE;
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
+ if (chan->fcs == L2CAP_FCS_NONE ||
+ chan->conf_state & L2CAP_CONF_NO_FCS_RECV) {
+ chan->fcs = L2CAP_FCS_NONE;
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
}
break;
@@ -1658,43 +1750,42 @@ done:
rfc.retrans_timeout = 0;
rfc.monitor_timeout = 0;
rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
- if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
- rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
+ if (L2CAP_DEFAULT_MAX_PDU_SIZE > chan->conn->mtu - 10)
+ rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
(unsigned long) &rfc);
- if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
+ if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
break;
- if (pi->fcs == L2CAP_FCS_NONE ||
- pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
- pi->fcs = L2CAP_FCS_NONE;
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
+ if (chan->fcs == L2CAP_FCS_NONE ||
+ chan->conf_state & L2CAP_CONF_NO_FCS_RECV) {
+ chan->fcs = L2CAP_FCS_NONE;
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
}
break;
}
- req->dcid = cpu_to_le16(pi->dcid);
+ req->dcid = cpu_to_le16(chan->dcid);
req->flags = cpu_to_le16(0);
return ptr - data;
}
-static int l2cap_parse_conf_req(struct sock *sk, void *data)
+static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
struct l2cap_conf_rsp *rsp = data;
void *ptr = rsp->data;
- void *req = pi->conf_req;
- int len = pi->conf_len;
+ void *req = chan->conf_req;
+ int len = chan->conf_len;
int type, hint, olen;
unsigned long val;
struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
u16 mtu = L2CAP_DEFAULT_MTU;
u16 result = L2CAP_CONF_SUCCESS;
- BT_DBG("sk %p", sk);
+ BT_DBG("chan %p", chan);
while (len >= L2CAP_CONF_OPT_SIZE) {
len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
@@ -1708,7 +1799,7 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
break;
case L2CAP_CONF_FLUSH_TO:
- pi->flush_to = val;
+ chan->flush_to = val;
break;
case L2CAP_CONF_QOS:
@@ -1721,7 +1812,7 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
case L2CAP_CONF_FCS:
if (val == L2CAP_FCS_NONE)
- pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
+ chan->conf_state |= L2CAP_CONF_NO_FCS_RECV;
break;
@@ -1735,30 +1826,30 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
}
}
- if (pi->num_conf_rsp || pi->num_conf_req > 1)
+ if (chan->num_conf_rsp || chan->num_conf_req > 1)
goto done;
- switch (pi->mode) {
+ switch (chan->mode) {
case L2CAP_MODE_STREAMING:
case L2CAP_MODE_ERTM:
- if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
- pi->mode = l2cap_select_mode(rfc.mode,
- pi->conn->feat_mask);
+ if (!(chan->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
+ chan->mode = l2cap_select_mode(rfc.mode,
+ chan->conn->feat_mask);
break;
}
- if (pi->mode != rfc.mode)
+ if (chan->mode != rfc.mode)
return -ECONNREFUSED;
break;
}
done:
- if (pi->mode != rfc.mode) {
+ if (chan->mode != rfc.mode) {
result = L2CAP_CONF_UNACCEPT;
- rfc.mode = pi->mode;
+ rfc.mode = chan->mode;
- if (pi->num_conf_rsp == 1)
+ if (chan->num_conf_rsp == 1)
return -ECONNREFUSED;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
@@ -1773,32 +1864,32 @@ done:
if (mtu < L2CAP_DEFAULT_MIN_MTU)
result = L2CAP_CONF_UNACCEPT;
else {
- pi->omtu = mtu;
- pi->conf_state |= L2CAP_CONF_MTU_DONE;
+ chan->omtu = mtu;
+ chan->conf_state |= L2CAP_CONF_MTU_DONE;
}
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
switch (rfc.mode) {
case L2CAP_MODE_BASIC:
- pi->fcs = L2CAP_FCS_NONE;
- pi->conf_state |= L2CAP_CONF_MODE_DONE;
+ chan->fcs = L2CAP_FCS_NONE;
+ chan->conf_state |= L2CAP_CONF_MODE_DONE;
break;
case L2CAP_MODE_ERTM:
- pi->remote_tx_win = rfc.txwin_size;
- pi->remote_max_tx = rfc.max_transmit;
+ chan->remote_tx_win = rfc.txwin_size;
+ chan->remote_max_tx = rfc.max_transmit;
- if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
- rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
+ if (le16_to_cpu(rfc.max_pdu_size) > chan->conn->mtu - 10)
+ rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10);
- pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
+ chan->remote_mps = le16_to_cpu(rfc.max_pdu_size);
rfc.retrans_timeout =
le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
rfc.monitor_timeout =
le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
- pi->conf_state |= L2CAP_CONF_MODE_DONE;
+ chan->conf_state |= L2CAP_CONF_MODE_DONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
@@ -1806,12 +1897,12 @@ done:
break;
case L2CAP_MODE_STREAMING:
- if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
- rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
+ if (le16_to_cpu(rfc.max_pdu_size) > chan->conn->mtu - 10)
+ rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10);
- pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
+ chan->remote_mps = le16_to_cpu(rfc.max_pdu_size);
- pi->conf_state |= L2CAP_CONF_MODE_DONE;
+ chan->conf_state |= L2CAP_CONF_MODE_DONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
@@ -1822,29 +1913,28 @@ done:
result = L2CAP_CONF_UNACCEPT;
memset(&rfc, 0, sizeof(rfc));
- rfc.mode = pi->mode;
+ rfc.mode = chan->mode;
}
if (result == L2CAP_CONF_SUCCESS)
- pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
+ chan->conf_state |= L2CAP_CONF_OUTPUT_DONE;
}
- rsp->scid = cpu_to_le16(pi->dcid);
+ rsp->scid = cpu_to_le16(chan->dcid);
rsp->result = cpu_to_le16(result);
rsp->flags = cpu_to_le16(0x0000);
return ptr - data;
}
-static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
+static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, void *data, u16 *result)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
struct l2cap_conf_req *req = data;
void *ptr = req->data;
int type, olen;
unsigned long val;
struct l2cap_conf_rfc rfc;
- BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
+ BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
while (len >= L2CAP_CONF_OPT_SIZE) {
len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
@@ -1853,27 +1943,27 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
case L2CAP_CONF_MTU:
if (val < L2CAP_DEFAULT_MIN_MTU) {
*result = L2CAP_CONF_UNACCEPT;
- pi->imtu = L2CAP_DEFAULT_MIN_MTU;
+ chan->imtu = L2CAP_DEFAULT_MIN_MTU;
} else
- pi->imtu = val;
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
+ chan->imtu = val;
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
break;
case L2CAP_CONF_FLUSH_TO:
- pi->flush_to = val;
+ chan->flush_to = val;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
- 2, pi->flush_to);
+ 2, chan->flush_to);
break;
case L2CAP_CONF_RFC:
if (olen == sizeof(rfc))
memcpy(&rfc, (void *)val, olen);
- if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
- rfc.mode != pi->mode)
+ if ((chan->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
+ rfc.mode != chan->mode)
return -ECONNREFUSED;
- pi->fcs = 0;
+ chan->fcs = 0;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
@@ -1881,53 +1971,74 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
}
}
- if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode)
+ if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
return -ECONNREFUSED;
- pi->mode = rfc.mode;
+ chan->mode = rfc.mode;
if (*result == L2CAP_CONF_SUCCESS) {
switch (rfc.mode) {
case L2CAP_MODE_ERTM:
- pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
- pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
- pi->mps = le16_to_cpu(rfc.max_pdu_size);
+ chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
+ chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
+ chan->mps = le16_to_cpu(rfc.max_pdu_size);
break;
case L2CAP_MODE_STREAMING:
- pi->mps = le16_to_cpu(rfc.max_pdu_size);
+ chan->mps = le16_to_cpu(rfc.max_pdu_size);
}
}
- req->dcid = cpu_to_le16(pi->dcid);
+ req->dcid = cpu_to_le16(chan->dcid);
req->flags = cpu_to_le16(0x0000);
return ptr - data;
}
-static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
+static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, u16 result, u16 flags)
{
struct l2cap_conf_rsp *rsp = data;
void *ptr = rsp->data;
- BT_DBG("sk %p", sk);
+ BT_DBG("chan %p", chan);
- rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
+ rsp->scid = cpu_to_le16(chan->dcid);
rsp->result = cpu_to_le16(result);
rsp->flags = cpu_to_le16(flags);
return ptr - data;
}
-static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
+void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
+{
+ struct l2cap_conn_rsp rsp;
+ struct l2cap_conn *conn = chan->conn;
+ u8 buf[128];
+
+ rsp.scid = cpu_to_le16(chan->dcid);
+ rsp.dcid = cpu_to_le16(chan->scid);
+ rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
+ rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
+ l2cap_send_cmd(conn, chan->ident,
+ L2CAP_CONN_RSP, sizeof(rsp), &rsp);
+
+ if (chan->conf_state & L2CAP_CONF_REQ_SENT)
+ return;
+
+ chan->conf_state |= L2CAP_CONF_REQ_SENT;
+ l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
+ l2cap_build_conf_req(chan, buf), buf);
+ chan->num_conf_req++;
+}
+
+static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
int type, olen;
unsigned long val;
struct l2cap_conf_rfc rfc;
- BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
+ BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
- if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
+ if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
return;
while (len >= L2CAP_CONF_OPT_SIZE) {
@@ -1944,12 +2055,12 @@ static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
done:
switch (rfc.mode) {
case L2CAP_MODE_ERTM:
- pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
- pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
- pi->mps = le16_to_cpu(rfc.max_pdu_size);
+ chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
+ chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
+ chan->mps = le16_to_cpu(rfc.max_pdu_size);
break;
case L2CAP_MODE_STREAMING:
- pi->mps = le16_to_cpu(rfc.max_pdu_size);
+ chan->mps = le16_to_cpu(rfc.max_pdu_size);
}
}
@@ -1975,9 +2086,9 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd
static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
{
- struct l2cap_chan_list *list = &conn->chan_list;
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
struct l2cap_conn_rsp rsp;
+ struct l2cap_chan *chan = NULL, *pchan;
struct sock *parent, *sk = NULL;
int result, status = L2CAP_CS_NO_INFO;
@@ -1987,12 +2098,14 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
/* Check if we have socket listening on psm */
- parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
- if (!parent) {
+ pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src);
+ if (!pchan) {
result = L2CAP_CR_BAD_PSM;
goto sendresp;
}
+ parent = pchan->sk;
+
bh_lock_sock(parent);
/* Check if the ACL is secure enough (if not SDP) */
@@ -2015,11 +2128,19 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
if (!sk)
goto response;
- write_lock_bh(&list->lock);
+ chan = l2cap_chan_create(sk);
+ if (!chan) {
+ l2cap_sock_kill(sk);
+ goto response;
+ }
+
+ l2cap_pi(sk)->chan = chan;
+
+ write_lock_bh(&conn->chan_lock);
/* Check if we already have channel with that dcid */
- if (__l2cap_get_chan_by_dcid(list, scid)) {
- write_unlock_bh(&list->lock);
+ if (__l2cap_get_chan_by_dcid(conn, scid)) {
+ write_unlock_bh(&conn->chan_lock);
sock_set_flag(sk, SOCK_ZAPPED);
l2cap_sock_kill(sk);
goto response;
@@ -2030,18 +2151,21 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
l2cap_sock_init(sk, parent);
bacpy(&bt_sk(sk)->src, conn->src);
bacpy(&bt_sk(sk)->dst, conn->dst);
- l2cap_pi(sk)->psm = psm;
- l2cap_pi(sk)->dcid = scid;
+ chan->psm = psm;
+ chan->dcid = scid;
+
+ bt_accept_enqueue(parent, sk);
+
+ __l2cap_chan_add(conn, chan);
- __l2cap_chan_add(conn, sk, parent);
- dcid = l2cap_pi(sk)->scid;
+ dcid = chan->scid;
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
- l2cap_pi(sk)->ident = cmd->ident;
+ chan->ident = cmd->ident;
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
- if (l2cap_check_security(sk)) {
+ if (l2cap_check_security(chan)) {
if (bt_sk(sk)->defer_setup) {
sk->sk_state = BT_CONNECT2;
result = L2CAP_CR_PEND;
@@ -2063,7 +2187,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
status = L2CAP_CS_NO_INFO;
}
- write_unlock_bh(&list->lock);
+ write_unlock_bh(&conn->chan_lock);
response:
bh_unlock_sock(parent);
@@ -2089,13 +2213,13 @@ sendresp:
L2CAP_INFO_REQ, sizeof(info), &info);
}
- if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
+ if (chan && !(chan->conf_state & L2CAP_CONF_REQ_SENT) &&
result == L2CAP_CR_SUCCESS) {
u8 buf[128];
- l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
+ chan->conf_state |= L2CAP_CONF_REQ_SENT;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(sk, buf), buf);
- l2cap_pi(sk)->num_conf_req++;
+ l2cap_build_conf_req(chan, buf), buf);
+ chan->num_conf_req++;
}
return 0;
@@ -2105,6 +2229,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
{
struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
u16 scid, dcid, result, status;
+ struct l2cap_chan *chan;
struct sock *sk;
u8 req[128];
@@ -2116,34 +2241,36 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
if (scid) {
- sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
- if (!sk)
+ chan = l2cap_get_chan_by_scid(conn, scid);
+ if (!chan)
return -EFAULT;
} else {
- sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
- if (!sk)
+ chan = l2cap_get_chan_by_ident(conn, cmd->ident);
+ if (!chan)
return -EFAULT;
}
+ sk = chan->sk;
+
switch (result) {
case L2CAP_CR_SUCCESS:
sk->sk_state = BT_CONFIG;
- l2cap_pi(sk)->ident = 0;
- l2cap_pi(sk)->dcid = dcid;
- l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
+ chan->ident = 0;
+ chan->dcid = dcid;
+ chan->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
- if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)
+ if (chan->conf_state & L2CAP_CONF_REQ_SENT)
break;
- l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
+ chan->conf_state |= L2CAP_CONF_REQ_SENT;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(sk, req), req);
- l2cap_pi(sk)->num_conf_req++;
+ l2cap_build_conf_req(chan, req), req);
+ chan->num_conf_req++;
break;
case L2CAP_CR_PEND:
- l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
+ chan->conf_state |= L2CAP_CONF_CONNECT_PEND;
break;
default:
@@ -2155,7 +2282,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
break;
}
- l2cap_chan_del(sk, ECONNREFUSED);
+ l2cap_chan_del(chan, ECONNREFUSED);
break;
}
@@ -2163,15 +2290,17 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
return 0;
}
-static inline void set_default_fcs(struct l2cap_pinfo *pi)
+static inline void set_default_fcs(struct l2cap_chan *chan)
{
+ struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
+
/* FCS is enabled only in ERTM or streaming mode, if one or both
* sides request it.
*/
- if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
- pi->fcs = L2CAP_FCS_NONE;
- else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV))
- pi->fcs = L2CAP_FCS_CRC16;
+ if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
+ chan->fcs = L2CAP_FCS_NONE;
+ else if (!(pi->chan->conf_state & L2CAP_CONF_NO_FCS_RECV))
+ chan->fcs = L2CAP_FCS_CRC16;
}
static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
@@ -2179,6 +2308,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
u16 dcid, flags;
u8 rsp[64];
+ struct l2cap_chan *chan;
struct sock *sk;
int len;
@@ -2187,10 +2317,12 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
- sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
- if (!sk)
+ chan = l2cap_get_chan_by_scid(conn, dcid);
+ if (!chan)
return -ENOENT;
+ sk = chan->sk;
+
if (sk->sk_state != BT_CONFIG) {
struct l2cap_cmd_rej rej;
@@ -2202,62 +2334,62 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
/* Reject if config buffer is too small. */
len = cmd_len - sizeof(*req);
- if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
+ if (chan->conf_len + len > sizeof(chan->conf_req)) {
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
- l2cap_build_conf_rsp(sk, rsp,
+ l2cap_build_conf_rsp(chan, rsp,
L2CAP_CONF_REJECT, flags), rsp);
goto unlock;
}
/* Store config. */
- memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
- l2cap_pi(sk)->conf_len += len;
+ memcpy(chan->conf_req + chan->conf_len, req->data, len);
+ chan->conf_len += len;
if (flags & 0x0001) {
/* Incomplete config. Send empty response. */
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
- l2cap_build_conf_rsp(sk, rsp,
+ l2cap_build_conf_rsp(chan, rsp,
L2CAP_CONF_SUCCESS, 0x0001), rsp);
goto unlock;
}
/* Complete config. */
- len = l2cap_parse_conf_req(sk, rsp);
+ len = l2cap_parse_conf_req(chan, rsp);
if (len < 0) {
- l2cap_send_disconn_req(conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(conn, chan, ECONNRESET);
goto unlock;
}
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
- l2cap_pi(sk)->num_conf_rsp++;
+ chan->num_conf_rsp++;
/* Reset config buffer. */
- l2cap_pi(sk)->conf_len = 0;
+ chan->conf_len = 0;
- if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
+ if (!(chan->conf_state & L2CAP_CONF_OUTPUT_DONE))
goto unlock;
- if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
- set_default_fcs(l2cap_pi(sk));
+ if (chan->conf_state & L2CAP_CONF_INPUT_DONE) {
+ set_default_fcs(chan);
sk->sk_state = BT_CONNECTED;
- l2cap_pi(sk)->next_tx_seq = 0;
- l2cap_pi(sk)->expected_tx_seq = 0;
- __skb_queue_head_init(TX_QUEUE(sk));
- if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
- l2cap_ertm_init(sk);
+ chan->next_tx_seq = 0;
+ chan->expected_tx_seq = 0;
+ skb_queue_head_init(&chan->tx_q);
+ if (chan->mode == L2CAP_MODE_ERTM)
+ l2cap_ertm_init(chan);
l2cap_chan_ready(sk);
goto unlock;
}
- if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
+ if (!(chan->conf_state & L2CAP_CONF_REQ_SENT)) {
u8 buf[64];
- l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
+ chan->conf_state |= L2CAP_CONF_REQ_SENT;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(sk, buf), buf);
- l2cap_pi(sk)->num_conf_req++;
+ l2cap_build_conf_req(chan, buf), buf);
+ chan->num_conf_req++;
}
unlock:
@@ -2269,6 +2401,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
{
struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
u16 scid, flags, result;
+ struct l2cap_chan *chan;
struct sock *sk;
int len = cmd->len - sizeof(*rsp);
@@ -2279,36 +2412,38 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
scid, flags, result);
- sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
- if (!sk)
+ chan = l2cap_get_chan_by_scid(conn, scid);
+ if (!chan)
return 0;
+ sk = chan->sk;
+
switch (result) {
case L2CAP_CONF_SUCCESS:
- l2cap_conf_rfc_get(sk, rsp->data, len);
+ l2cap_conf_rfc_get(chan, rsp->data, len);
break;
case L2CAP_CONF_UNACCEPT:
- if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
+ if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
char req[64];
if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
- l2cap_send_disconn_req(conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(conn, chan, ECONNRESET);
goto done;
}
/* throw out any old stored conf requests */
result = L2CAP_CONF_SUCCESS;
- len = l2cap_parse_conf_rsp(sk, rsp->data,
- len, req, &result);
+ len = l2cap_parse_conf_rsp(chan, rsp->data, len,
+ req, &result);
if (len < 0) {
- l2cap_send_disconn_req(conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(conn, chan, ECONNRESET);
goto done;
}
l2cap_send_cmd(conn, l2cap_get_ident(conn),
L2CAP_CONF_REQ, len, req);
- l2cap_pi(sk)->num_conf_req++;
+ chan->num_conf_req++;
if (result != L2CAP_CONF_SUCCESS)
goto done;
break;
@@ -2317,24 +2452,24 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
default:
sk->sk_err = ECONNRESET;
l2cap_sock_set_timer(sk, HZ * 5);
- l2cap_send_disconn_req(conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(conn, chan, ECONNRESET);
goto done;
}
if (flags & 0x01)
goto done;
- l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
+ chan->conf_state |= L2CAP_CONF_INPUT_DONE;
- if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
- set_default_fcs(l2cap_pi(sk));
+ if (chan->conf_state & L2CAP_CONF_OUTPUT_DONE) {
+ set_default_fcs(chan);
sk->sk_state = BT_CONNECTED;
- l2cap_pi(sk)->next_tx_seq = 0;
- l2cap_pi(sk)->expected_tx_seq = 0;
- __skb_queue_head_init(TX_QUEUE(sk));
- if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
- l2cap_ertm_init(sk);
+ chan->next_tx_seq = 0;
+ chan->expected_tx_seq = 0;
+ skb_queue_head_init(&chan->tx_q);
+ if (chan->mode == L2CAP_MODE_ERTM)
+ l2cap_ertm_init(chan);
l2cap_chan_ready(sk);
}
@@ -2349,6 +2484,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
struct l2cap_disconn_rsp rsp;
u16 dcid, scid;
+ struct l2cap_chan *chan;
struct sock *sk;
scid = __le16_to_cpu(req->scid);
@@ -2356,12 +2492,14 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
- sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
- if (!sk)
+ chan = l2cap_get_chan_by_scid(conn, dcid);
+ if (!chan)
return 0;
- rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
- rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
+ sk = chan->sk;
+
+ rsp.dcid = cpu_to_le16(chan->scid);
+ rsp.scid = cpu_to_le16(chan->dcid);
l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
sk->sk_shutdown = SHUTDOWN_MASK;
@@ -2375,7 +2513,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
return 0;
}
- l2cap_chan_del(sk, ECONNRESET);
+ l2cap_chan_del(chan, ECONNRESET);
bh_unlock_sock(sk);
l2cap_sock_kill(sk);
@@ -2386,6 +2524,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
{
struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
u16 dcid, scid;
+ struct l2cap_chan *chan;
struct sock *sk;
scid = __le16_to_cpu(rsp->scid);
@@ -2393,10 +2532,12 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
- sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
- if (!sk)
+ chan = l2cap_get_chan_by_scid(conn, scid);
+ if (!chan)
return 0;
+ sk = chan->sk;
+
/* don't delete l2cap channel if sk is owned by user */
if (sock_owned_by_user(sk)) {
sk->sk_state = BT_DISCONN;
@@ -2406,7 +2547,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
return 0;
}
- l2cap_chan_del(sk, 0);
+ l2cap_chan_del(chan, 0);
bh_unlock_sock(sk);
l2cap_sock_kill(sk);
@@ -2463,6 +2604,11 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
+ /* L2CAP Info req/rsp are unbound to channels, add extra checks */
+ if (cmd->ident != conn->info_ident ||
+ conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
+ return 0;
+
del_timer(&conn->info_timer);
if (result != L2CAP_IR_SUCCESS) {
@@ -2673,7 +2819,8 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn,
if (err) {
struct l2cap_cmd_rej rej;
- BT_DBG("error %d", err);
+
+ BT_ERR("Wrong link type (%d)", err);
/* FIXME: Map err to a valid reason */
rej.reason = cpu_to_le16(0);
@@ -2687,12 +2834,12 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn,
kfree_skb(skb);
}
-static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
+static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
{
u16 our_fcs, rcv_fcs;
int hdr_size = L2CAP_HDR_SIZE + 2;
- if (pi->fcs == L2CAP_FCS_CRC16) {
+ if (chan->fcs == L2CAP_FCS_CRC16) {
skb_trim(skb, skb->len - 2);
rcv_fcs = get_unaligned_le16(skb->data + skb->len);
our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
@@ -2703,49 +2850,47 @@ static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
return 0;
}
-static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
+static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
u16 control = 0;
- pi->frames_sent = 0;
+ chan->frames_sent = 0;
- control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
- if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
+ if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
control |= L2CAP_SUPER_RCV_NOT_READY;
- l2cap_send_sframe(pi, control);
- pi->conn_state |= L2CAP_CONN_RNR_SENT;
+ l2cap_send_sframe(chan, control);
+ chan->conn_state |= L2CAP_CONN_RNR_SENT;
}
- if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
- l2cap_retransmit_frames(sk);
+ if (chan->conn_state & L2CAP_CONN_REMOTE_BUSY)
+ l2cap_retransmit_frames(chan);
- l2cap_ertm_send(sk);
+ l2cap_ertm_send(chan);
- if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
- pi->frames_sent == 0) {
+ if (!(chan->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
+ chan->frames_sent == 0) {
control |= L2CAP_SUPER_RCV_READY;
- l2cap_send_sframe(pi, control);
+ l2cap_send_sframe(chan, control);
}
}
-static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
+static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, u8 tx_seq, u8 sar)
{
struct sk_buff *next_skb;
- struct l2cap_pinfo *pi = l2cap_pi(sk);
int tx_seq_offset, next_tx_seq_offset;
bt_cb(skb)->tx_seq = tx_seq;
bt_cb(skb)->sar = sar;
- next_skb = skb_peek(SREJ_QUEUE(sk));
+ next_skb = skb_peek(&chan->srej_q);
if (!next_skb) {
- __skb_queue_tail(SREJ_QUEUE(sk), skb);
+ __skb_queue_tail(&chan->srej_q, skb);
return 0;
}
- tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
+ tx_seq_offset = (tx_seq - chan->buffer_seq) % 64;
if (tx_seq_offset < 0)
tx_seq_offset += 64;
@@ -2754,53 +2899,52 @@ static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_s
return -EINVAL;
next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
- pi->buffer_seq) % 64;
+ chan->buffer_seq) % 64;
if (next_tx_seq_offset < 0)
next_tx_seq_offset += 64;
if (next_tx_seq_offset > tx_seq_offset) {
- __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
+ __skb_queue_before(&chan->srej_q, next_skb, skb);
return 0;
}
- if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
+ if (skb_queue_is_last(&chan->srej_q, next_skb))
break;
- } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
+ } while ((next_skb = skb_queue_next(&chan->srej_q, next_skb)));
- __skb_queue_tail(SREJ_QUEUE(sk), skb);
+ __skb_queue_tail(&chan->srej_q, skb);
return 0;
}
-static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
+static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
struct sk_buff *_skb;
int err;
switch (control & L2CAP_CTRL_SAR) {
case L2CAP_SDU_UNSEGMENTED:
- if (pi->conn_state & L2CAP_CONN_SAR_SDU)
+ if (chan->conn_state & L2CAP_CONN_SAR_SDU)
goto drop;
- err = sock_queue_rcv_skb(sk, skb);
+ err = sock_queue_rcv_skb(chan->sk, skb);
if (!err)
return err;
break;
case L2CAP_SDU_START:
- if (pi->conn_state & L2CAP_CONN_SAR_SDU)
+ if (chan->conn_state & L2CAP_CONN_SAR_SDU)
goto drop;
- pi->sdu_len = get_unaligned_le16(skb->data);
+ chan->sdu_len = get_unaligned_le16(skb->data);
- if (pi->sdu_len > pi->imtu)
+ if (chan->sdu_len > chan->imtu)
goto disconnect;
- pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
- if (!pi->sdu)
+ chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC);
+ if (!chan->sdu)
return -ENOMEM;
/* pull sdu_len bytes only after alloc, because of Local Busy
@@ -2808,63 +2952,63 @@ static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 c
* only once, i.e., when alloc does not fail */
skb_pull(skb, 2);
- memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+ memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
- pi->conn_state |= L2CAP_CONN_SAR_SDU;
- pi->partial_sdu_len = skb->len;
+ chan->conn_state |= L2CAP_CONN_SAR_SDU;
+ chan->partial_sdu_len = skb->len;
break;
case L2CAP_SDU_CONTINUE:
- if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
+ if (!(chan->conn_state & L2CAP_CONN_SAR_SDU))
goto disconnect;
- if (!pi->sdu)
+ if (!chan->sdu)
goto disconnect;
- pi->partial_sdu_len += skb->len;
- if (pi->partial_sdu_len > pi->sdu_len)
+ chan->partial_sdu_len += skb->len;
+ if (chan->partial_sdu_len > chan->sdu_len)
goto drop;
- memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+ memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
break;
case L2CAP_SDU_END:
- if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
+ if (!(chan->conn_state & L2CAP_CONN_SAR_SDU))
goto disconnect;
- if (!pi->sdu)
+ if (!chan->sdu)
goto disconnect;
- if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
- pi->partial_sdu_len += skb->len;
+ if (!(chan->conn_state & L2CAP_CONN_SAR_RETRY)) {
+ chan->partial_sdu_len += skb->len;
- if (pi->partial_sdu_len > pi->imtu)
+ if (chan->partial_sdu_len > chan->imtu)
goto drop;
- if (pi->partial_sdu_len != pi->sdu_len)
+ if (chan->partial_sdu_len != chan->sdu_len)
goto drop;
- memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+ memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
}
- _skb = skb_clone(pi->sdu, GFP_ATOMIC);
+ _skb = skb_clone(chan->sdu, GFP_ATOMIC);
if (!_skb) {
- pi->conn_state |= L2CAP_CONN_SAR_RETRY;
+ chan->conn_state |= L2CAP_CONN_SAR_RETRY;
return -ENOMEM;
}
- err = sock_queue_rcv_skb(sk, _skb);
+ err = sock_queue_rcv_skb(chan->sk, _skb);
if (err < 0) {
kfree_skb(_skb);
- pi->conn_state |= L2CAP_CONN_SAR_RETRY;
+ chan->conn_state |= L2CAP_CONN_SAR_RETRY;
return err;
}
- pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
- pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
+ chan->conn_state &= ~L2CAP_CONN_SAR_RETRY;
+ chan->conn_state &= ~L2CAP_CONN_SAR_SDU;
- kfree_skb(pi->sdu);
+ kfree_skb(chan->sdu);
break;
}
@@ -2872,51 +3016,50 @@ static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 c
return 0;
drop:
- kfree_skb(pi->sdu);
- pi->sdu = NULL;
+ kfree_skb(chan->sdu);
+ chan->sdu = NULL;
disconnect:
- l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
kfree_skb(skb);
return 0;
}
-static int l2cap_try_push_rx_skb(struct sock *sk)
+static int l2cap_try_push_rx_skb(struct l2cap_chan *chan)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
struct sk_buff *skb;
u16 control;
int err;
- while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
+ while ((skb = skb_dequeue(&chan->busy_q))) {
control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
- err = l2cap_ertm_reassembly_sdu(sk, skb, control);
+ err = l2cap_ertm_reassembly_sdu(chan, skb, control);
if (err < 0) {
- skb_queue_head(BUSY_QUEUE(sk), skb);
+ skb_queue_head(&chan->busy_q, skb);
return -EBUSY;
}
- pi->buffer_seq = (pi->buffer_seq + 1) % 64;
+ chan->buffer_seq = (chan->buffer_seq + 1) % 64;
}
- if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
+ if (!(chan->conn_state & L2CAP_CONN_RNR_SENT))
goto done;
- control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
- l2cap_send_sframe(pi, control);
- l2cap_pi(sk)->retry_count = 1;
+ l2cap_send_sframe(chan, control);
+ chan->retry_count = 1;
- del_timer(&pi->retrans_timer);
+ del_timer(&chan->retrans_timer);
__mod_monitor_timer();
- l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
+ chan->conn_state |= L2CAP_CONN_WAIT_F;
done:
- pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
- pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
+ chan->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
+ chan->conn_state &= ~L2CAP_CONN_RNR_SENT;
- BT_DBG("sk %p, Exit local busy", sk);
+ BT_DBG("chan %p, Exit local busy", chan);
return 0;
}
@@ -2924,21 +3067,21 @@ done:
static void l2cap_busy_work(struct work_struct *work)
{
DECLARE_WAITQUEUE(wait, current);
- struct l2cap_pinfo *pi =
- container_of(work, struct l2cap_pinfo, busy_work);
- struct sock *sk = (struct sock *)pi;
+ struct l2cap_chan *chan =
+ container_of(work, struct l2cap_chan, busy_work);
+ struct sock *sk = chan->sk;
int n_tries = 0, timeo = HZ/5, err;
struct sk_buff *skb;
lock_sock(sk);
add_wait_queue(sk_sleep(sk), &wait);
- while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
+ while ((skb = skb_peek(&chan->busy_q))) {
set_current_state(TASK_INTERRUPTIBLE);
if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
err = -EBUSY;
- l2cap_send_disconn_req(pi->conn, sk, EBUSY);
+ l2cap_send_disconn_req(chan->conn, chan, EBUSY);
break;
}
@@ -2958,7 +3101,7 @@ static void l2cap_busy_work(struct work_struct *work)
if (err)
break;
- if (l2cap_try_push_rx_skb(sk) == 0)
+ if (l2cap_try_push_rx_skb(chan) == 0)
break;
}
@@ -2968,48 +3111,46 @@ static void l2cap_busy_work(struct work_struct *work)
release_sock(sk);
}
-static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
+static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 control)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
int sctrl, err;
- if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
+ if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
- __skb_queue_tail(BUSY_QUEUE(sk), skb);
- return l2cap_try_push_rx_skb(sk);
+ __skb_queue_tail(&chan->busy_q, skb);
+ return l2cap_try_push_rx_skb(chan);
}
- err = l2cap_ertm_reassembly_sdu(sk, skb, control);
+ err = l2cap_ertm_reassembly_sdu(chan, skb, control);
if (err >= 0) {
- pi->buffer_seq = (pi->buffer_seq + 1) % 64;
+ chan->buffer_seq = (chan->buffer_seq + 1) % 64;
return err;
}
/* Busy Condition */
- BT_DBG("sk %p, Enter local busy", sk);
+ BT_DBG("chan %p, Enter local busy", chan);
- pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
+ chan->conn_state |= L2CAP_CONN_LOCAL_BUSY;
bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
- __skb_queue_tail(BUSY_QUEUE(sk), skb);
+ __skb_queue_tail(&chan->busy_q, skb);
- sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ sctrl = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
sctrl |= L2CAP_SUPER_RCV_NOT_READY;
- l2cap_send_sframe(pi, sctrl);
+ l2cap_send_sframe(chan, sctrl);
- pi->conn_state |= L2CAP_CONN_RNR_SENT;
+ chan->conn_state |= L2CAP_CONN_RNR_SENT;
- del_timer(&pi->ack_timer);
+ del_timer(&chan->ack_timer);
- queue_work(_busy_wq, &pi->busy_work);
+ queue_work(_busy_wq, &chan->busy_work);
return err;
}
-static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
+static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
struct sk_buff *_skb;
int err = -EINVAL;
@@ -3020,80 +3161,80 @@ static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb,
switch (control & L2CAP_CTRL_SAR) {
case L2CAP_SDU_UNSEGMENTED:
- if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
- kfree_skb(pi->sdu);
+ if (chan->conn_state & L2CAP_CONN_SAR_SDU) {
+ kfree_skb(chan->sdu);
break;
}
- err = sock_queue_rcv_skb(sk, skb);
+ err = sock_queue_rcv_skb(chan->sk, skb);
if (!err)
return 0;
break;
case L2CAP_SDU_START:
- if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
- kfree_skb(pi->sdu);
+ if (chan->conn_state & L2CAP_CONN_SAR_SDU) {
+ kfree_skb(chan->sdu);
break;
}
- pi->sdu_len = get_unaligned_le16(skb->data);
+ chan->sdu_len = get_unaligned_le16(skb->data);
skb_pull(skb, 2);
- if (pi->sdu_len > pi->imtu) {
+ if (chan->sdu_len > chan->imtu) {
err = -EMSGSIZE;
break;
}
- pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
- if (!pi->sdu) {
+ chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC);
+ if (!chan->sdu) {
err = -ENOMEM;
break;
}
- memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+ memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
- pi->conn_state |= L2CAP_CONN_SAR_SDU;
- pi->partial_sdu_len = skb->len;
+ chan->conn_state |= L2CAP_CONN_SAR_SDU;
+ chan->partial_sdu_len = skb->len;
err = 0;
break;
case L2CAP_SDU_CONTINUE:
- if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
+ if (!(chan->conn_state & L2CAP_CONN_SAR_SDU))
break;
- memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+ memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
- pi->partial_sdu_len += skb->len;
- if (pi->partial_sdu_len > pi->sdu_len)
- kfree_skb(pi->sdu);
+ chan->partial_sdu_len += skb->len;
+ if (chan->partial_sdu_len > chan->sdu_len)
+ kfree_skb(chan->sdu);
else
err = 0;
break;
case L2CAP_SDU_END:
- if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
+ if (!(chan->conn_state & L2CAP_CONN_SAR_SDU))
break;
- memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+ memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
- pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
- pi->partial_sdu_len += skb->len;
+ chan->conn_state &= ~L2CAP_CONN_SAR_SDU;
+ chan->partial_sdu_len += skb->len;
- if (pi->partial_sdu_len > pi->imtu)
+ if (chan->partial_sdu_len > chan->imtu)
goto drop;
- if (pi->partial_sdu_len == pi->sdu_len) {
- _skb = skb_clone(pi->sdu, GFP_ATOMIC);
- err = sock_queue_rcv_skb(sk, _skb);
+ if (chan->partial_sdu_len == chan->sdu_len) {
+ _skb = skb_clone(chan->sdu, GFP_ATOMIC);
+ err = sock_queue_rcv_skb(chan->sk, _skb);
if (err < 0)
kfree_skb(_skb);
}
err = 0;
drop:
- kfree_skb(pi->sdu);
+ kfree_skb(chan->sdu);
break;
}
@@ -3101,31 +3242,30 @@ drop:
return err;
}
-static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
+static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq)
{
struct sk_buff *skb;
u16 control;
- while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
+ while ((skb = skb_peek(&chan->srej_q))) {
if (bt_cb(skb)->tx_seq != tx_seq)
break;
- skb = skb_dequeue(SREJ_QUEUE(sk));
+ skb = skb_dequeue(&chan->srej_q);
control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
- l2cap_ertm_reassembly_sdu(sk, skb, control);
- l2cap_pi(sk)->buffer_seq_srej =
- (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
+ l2cap_ertm_reassembly_sdu(chan, skb, control);
+ chan->buffer_seq_srej =
+ (chan->buffer_seq_srej + 1) % 64;
tx_seq = (tx_seq + 1) % 64;
}
}
-static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
+static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
struct srej_list *l, *tmp;
u16 control;
- list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
+ list_for_each_entry_safe(l, tmp, &chan->srej_l, list) {
if (l->tx_seq == tx_seq) {
list_del(&l->list);
kfree(l);
@@ -3133,107 +3273,105 @@ static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
}
control = L2CAP_SUPER_SELECT_REJECT;
control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
- l2cap_send_sframe(pi, control);
+ l2cap_send_sframe(chan, control);
list_del(&l->list);
- list_add_tail(&l->list, SREJ_LIST(sk));
+ list_add_tail(&l->list, &chan->srej_l);
}
}
-static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
+static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
struct srej_list *new;
u16 control;
- while (tx_seq != pi->expected_tx_seq) {
+ while (tx_seq != chan->expected_tx_seq) {
control = L2CAP_SUPER_SELECT_REJECT;
- control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
- l2cap_send_sframe(pi, control);
+ control |= chan->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ l2cap_send_sframe(chan, control);
new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
- new->tx_seq = pi->expected_tx_seq;
- pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
- list_add_tail(&new->list, SREJ_LIST(sk));
+ new->tx_seq = chan->expected_tx_seq;
+ chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64;
+ list_add_tail(&new->list, &chan->srej_l);
}
- pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
+ chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64;
}
-static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
+static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
u8 tx_seq = __get_txseq(rx_control);
u8 req_seq = __get_reqseq(rx_control);
u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
int tx_seq_offset, expected_tx_seq_offset;
- int num_to_ack = (pi->tx_win/6) + 1;
+ int num_to_ack = (chan->tx_win/6) + 1;
int err = 0;
- BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq,
- rx_control);
+ BT_DBG("chan %p len %d tx_seq %d rx_control 0x%4.4x", chan, skb->len,
+ tx_seq, rx_control);
if (L2CAP_CTRL_FINAL & rx_control &&
- l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
- del_timer(&pi->monitor_timer);
- if (pi->unacked_frames > 0)
+ chan->conn_state & L2CAP_CONN_WAIT_F) {
+ del_timer(&chan->monitor_timer);
+ if (chan->unacked_frames > 0)
__mod_retrans_timer();
- pi->conn_state &= ~L2CAP_CONN_WAIT_F;
+ chan->conn_state &= ~L2CAP_CONN_WAIT_F;
}
- pi->expected_ack_seq = req_seq;
- l2cap_drop_acked_frames(sk);
+ chan->expected_ack_seq = req_seq;
+ l2cap_drop_acked_frames(chan);
- if (tx_seq == pi->expected_tx_seq)
+ if (tx_seq == chan->expected_tx_seq)
goto expected;
- tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
+ tx_seq_offset = (tx_seq - chan->buffer_seq) % 64;
if (tx_seq_offset < 0)
tx_seq_offset += 64;
/* invalid tx_seq */
- if (tx_seq_offset >= pi->tx_win) {
- l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
+ if (tx_seq_offset >= chan->tx_win) {
+ l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
goto drop;
}
- if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
+ if (chan->conn_state == L2CAP_CONN_LOCAL_BUSY)
goto drop;
- if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
+ if (chan->conn_state & L2CAP_CONN_SREJ_SENT) {
struct srej_list *first;
- first = list_first_entry(SREJ_LIST(sk),
+ first = list_first_entry(&chan->srej_l,
struct srej_list, list);
if (tx_seq == first->tx_seq) {
- l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
- l2cap_check_srej_gap(sk, tx_seq);
+ l2cap_add_to_srej_queue(chan, skb, tx_seq, sar);
+ l2cap_check_srej_gap(chan, tx_seq);
list_del(&first->list);
kfree(first);
- if (list_empty(SREJ_LIST(sk))) {
- pi->buffer_seq = pi->buffer_seq_srej;
- pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
- l2cap_send_ack(pi);
- BT_DBG("sk %p, Exit SREJ_SENT", sk);
+ if (list_empty(&chan->srej_l)) {
+ chan->buffer_seq = chan->buffer_seq_srej;
+ chan->conn_state &= ~L2CAP_CONN_SREJ_SENT;
+ l2cap_send_ack(chan);
+ BT_DBG("chan %p, Exit SREJ_SENT", chan);
}
} else {
struct srej_list *l;
/* duplicated tx_seq */
- if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
+ if (l2cap_add_to_srej_queue(chan, skb, tx_seq, sar) < 0)
goto drop;
- list_for_each_entry(l, SREJ_LIST(sk), list) {
+ list_for_each_entry(l, &chan->srej_l, list) {
if (l->tx_seq == tx_seq) {
- l2cap_resend_srejframe(sk, tx_seq);
+ l2cap_resend_srejframe(chan, tx_seq);
return 0;
}
}
- l2cap_send_srejframe(sk, tx_seq);
+ l2cap_send_srejframe(chan, tx_seq);
}
} else {
expected_tx_seq_offset =
- (pi->expected_tx_seq - pi->buffer_seq) % 64;
+ (chan->expected_tx_seq - chan->buffer_seq) % 64;
if (expected_tx_seq_offset < 0)
expected_tx_seq_offset += 64;
@@ -3241,51 +3379,51 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
if (tx_seq_offset < expected_tx_seq_offset)
goto drop;
- pi->conn_state |= L2CAP_CONN_SREJ_SENT;
+ chan->conn_state |= L2CAP_CONN_SREJ_SENT;
- BT_DBG("sk %p, Enter SREJ", sk);
+ BT_DBG("chan %p, Enter SREJ", chan);
- INIT_LIST_HEAD(SREJ_LIST(sk));
- pi->buffer_seq_srej = pi->buffer_seq;
+ INIT_LIST_HEAD(&chan->srej_l);
+ chan->buffer_seq_srej = chan->buffer_seq;
- __skb_queue_head_init(SREJ_QUEUE(sk));
- __skb_queue_head_init(BUSY_QUEUE(sk));
- l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
+ __skb_queue_head_init(&chan->srej_q);
+ __skb_queue_head_init(&chan->busy_q);
+ l2cap_add_to_srej_queue(chan, skb, tx_seq, sar);
- pi->conn_state |= L2CAP_CONN_SEND_PBIT;
+ chan->conn_state |= L2CAP_CONN_SEND_PBIT;
- l2cap_send_srejframe(sk, tx_seq);
+ l2cap_send_srejframe(chan, tx_seq);
- del_timer(&pi->ack_timer);
+ del_timer(&chan->ack_timer);
}
return 0;
expected:
- pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
+ chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64;
- if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
+ if (chan->conn_state & L2CAP_CONN_SREJ_SENT) {
bt_cb(skb)->tx_seq = tx_seq;
bt_cb(skb)->sar = sar;
- __skb_queue_tail(SREJ_QUEUE(sk), skb);
+ __skb_queue_tail(&chan->srej_q, skb);
return 0;
}
- err = l2cap_push_rx_skb(sk, skb, rx_control);
+ err = l2cap_push_rx_skb(chan, skb, rx_control);
if (err < 0)
return 0;
if (rx_control & L2CAP_CTRL_FINAL) {
- if (pi->conn_state & L2CAP_CONN_REJ_ACT)
- pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
+ if (chan->conn_state & L2CAP_CONN_REJ_ACT)
+ chan->conn_state &= ~L2CAP_CONN_REJ_ACT;
else
- l2cap_retransmit_frames(sk);
+ l2cap_retransmit_frames(chan);
}
__mod_ack_timer();
- pi->num_acked = (pi->num_acked + 1) % num_to_ack;
- if (pi->num_acked == num_to_ack - 1)
- l2cap_send_ack(pi);
+ chan->num_acked = (chan->num_acked + 1) % num_to_ack;
+ if (chan->num_acked == num_to_ack - 1)
+ l2cap_send_ack(chan);
return 0;
@@ -3294,165 +3432,160 @@ drop:
return 0;
}
-static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
+static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_control)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
-
- BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
+ BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, __get_reqseq(rx_control),
rx_control);
- pi->expected_ack_seq = __get_reqseq(rx_control);
- l2cap_drop_acked_frames(sk);
+ chan->expected_ack_seq = __get_reqseq(rx_control);
+ l2cap_drop_acked_frames(chan);
if (rx_control & L2CAP_CTRL_POLL) {
- pi->conn_state |= L2CAP_CONN_SEND_FBIT;
- if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
- if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
- (pi->unacked_frames > 0))
+ chan->conn_state |= L2CAP_CONN_SEND_FBIT;
+ if (chan->conn_state & L2CAP_CONN_SREJ_SENT) {
+ if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
+ (chan->unacked_frames > 0))
__mod_retrans_timer();
- pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- l2cap_send_srejtail(sk);
+ chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ l2cap_send_srejtail(chan);
} else {
- l2cap_send_i_or_rr_or_rnr(sk);
+ l2cap_send_i_or_rr_or_rnr(chan);
}
} else if (rx_control & L2CAP_CTRL_FINAL) {
- pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- if (pi->conn_state & L2CAP_CONN_REJ_ACT)
- pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
+ if (chan->conn_state & L2CAP_CONN_REJ_ACT)
+ chan->conn_state &= ~L2CAP_CONN_REJ_ACT;
else
- l2cap_retransmit_frames(sk);
+ l2cap_retransmit_frames(chan);
} else {
- if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
- (pi->unacked_frames > 0))
+ if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
+ (chan->unacked_frames > 0))
__mod_retrans_timer();
- pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
- l2cap_send_ack(pi);
+ chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ if (chan->conn_state & L2CAP_CONN_SREJ_SENT)
+ l2cap_send_ack(chan);
else
- l2cap_ertm_send(sk);
+ l2cap_ertm_send(chan);
}
}
-static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
+static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u16 rx_control)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
u8 tx_seq = __get_reqseq(rx_control);
- BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
+ BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control);
- pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(sk);
+ chan->expected_ack_seq = tx_seq;
+ l2cap_drop_acked_frames(chan);
if (rx_control & L2CAP_CTRL_FINAL) {
- if (pi->conn_state & L2CAP_CONN_REJ_ACT)
- pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
+ if (chan->conn_state & L2CAP_CONN_REJ_ACT)
+ chan->conn_state &= ~L2CAP_CONN_REJ_ACT;
else
- l2cap_retransmit_frames(sk);
+ l2cap_retransmit_frames(chan);
} else {
- l2cap_retransmit_frames(sk);
+ l2cap_retransmit_frames(chan);
- if (pi->conn_state & L2CAP_CONN_WAIT_F)
- pi->conn_state |= L2CAP_CONN_REJ_ACT;
+ if (chan->conn_state & L2CAP_CONN_WAIT_F)
+ chan->conn_state |= L2CAP_CONN_REJ_ACT;
}
}
-static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
+static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_control)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
u8 tx_seq = __get_reqseq(rx_control);
- BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
+ BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control);
- pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
if (rx_control & L2CAP_CTRL_POLL) {
- pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(sk);
+ chan->expected_ack_seq = tx_seq;
+ l2cap_drop_acked_frames(chan);
- pi->conn_state |= L2CAP_CONN_SEND_FBIT;
- l2cap_retransmit_one_frame(sk, tx_seq);
+ chan->conn_state |= L2CAP_CONN_SEND_FBIT;
+ l2cap_retransmit_one_frame(chan, tx_seq);
- l2cap_ertm_send(sk);
+ l2cap_ertm_send(chan);
- if (pi->conn_state & L2CAP_CONN_WAIT_F) {
- pi->srej_save_reqseq = tx_seq;
- pi->conn_state |= L2CAP_CONN_SREJ_ACT;
+ if (chan->conn_state & L2CAP_CONN_WAIT_F) {
+ chan->srej_save_reqseq = tx_seq;
+ chan->conn_state |= L2CAP_CONN_SREJ_ACT;
}
} else if (rx_control & L2CAP_CTRL_FINAL) {
- if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
- pi->srej_save_reqseq == tx_seq)
- pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
+ if ((chan->conn_state & L2CAP_CONN_SREJ_ACT) &&
+ chan->srej_save_reqseq == tx_seq)
+ chan->conn_state &= ~L2CAP_CONN_SREJ_ACT;
else
- l2cap_retransmit_one_frame(sk, tx_seq);
+ l2cap_retransmit_one_frame(chan, tx_seq);
} else {
- l2cap_retransmit_one_frame(sk, tx_seq);
- if (pi->conn_state & L2CAP_CONN_WAIT_F) {
- pi->srej_save_reqseq = tx_seq;
- pi->conn_state |= L2CAP_CONN_SREJ_ACT;
+ l2cap_retransmit_one_frame(chan, tx_seq);
+ if (chan->conn_state & L2CAP_CONN_WAIT_F) {
+ chan->srej_save_reqseq = tx_seq;
+ chan->conn_state |= L2CAP_CONN_SREJ_ACT;
}
}
}
-static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
+static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_control)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
u8 tx_seq = __get_reqseq(rx_control);
- BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
+ BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control);
- pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
- pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(sk);
+ chan->conn_state |= L2CAP_CONN_REMOTE_BUSY;
+ chan->expected_ack_seq = tx_seq;
+ l2cap_drop_acked_frames(chan);
if (rx_control & L2CAP_CTRL_POLL)
- pi->conn_state |= L2CAP_CONN_SEND_FBIT;
+ chan->conn_state |= L2CAP_CONN_SEND_FBIT;
- if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
- del_timer(&pi->retrans_timer);
+ if (!(chan->conn_state & L2CAP_CONN_SREJ_SENT)) {
+ del_timer(&chan->retrans_timer);
if (rx_control & L2CAP_CTRL_POLL)
- l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
+ l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_FINAL);
return;
}
if (rx_control & L2CAP_CTRL_POLL)
- l2cap_send_srejtail(sk);
+ l2cap_send_srejtail(chan);
else
- l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
+ l2cap_send_sframe(chan, L2CAP_SUPER_RCV_READY);
}
-static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
+static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb)
{
- BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
+ BT_DBG("chan %p rx_control 0x%4.4x len %d", chan, rx_control, skb->len);
if (L2CAP_CTRL_FINAL & rx_control &&
- l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
- del_timer(&l2cap_pi(sk)->monitor_timer);
- if (l2cap_pi(sk)->unacked_frames > 0)
+ chan->conn_state & L2CAP_CONN_WAIT_F) {
+ del_timer(&chan->monitor_timer);
+ if (chan->unacked_frames > 0)
__mod_retrans_timer();
- l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
+ chan->conn_state &= ~L2CAP_CONN_WAIT_F;
}
switch (rx_control & L2CAP_CTRL_SUPERVISE) {
case L2CAP_SUPER_RCV_READY:
- l2cap_data_channel_rrframe(sk, rx_control);
+ l2cap_data_channel_rrframe(chan, rx_control);
break;
case L2CAP_SUPER_REJECT:
- l2cap_data_channel_rejframe(sk, rx_control);
+ l2cap_data_channel_rejframe(chan, rx_control);
break;
case L2CAP_SUPER_SELECT_REJECT:
- l2cap_data_channel_srejframe(sk, rx_control);
+ l2cap_data_channel_srejframe(chan, rx_control);
break;
case L2CAP_SUPER_RCV_NOT_READY:
- l2cap_data_channel_rnrframe(sk, rx_control);
+ l2cap_data_channel_rnrframe(chan, rx_control);
break;
}
@@ -3462,7 +3595,7 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str
static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
u16 control;
u8 req_seq;
int len, next_tx_seq_offset, req_seq_offset;
@@ -3476,51 +3609,51 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
* Receiver will miss it and start proper recovery
* procedures and ask retransmission.
*/
- if (l2cap_check_fcs(pi, skb))
+ if (l2cap_check_fcs(chan, skb))
goto drop;
if (__is_sar_start(control) && __is_iframe(control))
len -= 2;
- if (pi->fcs == L2CAP_FCS_CRC16)
+ if (chan->fcs == L2CAP_FCS_CRC16)
len -= 2;
- if (len > pi->mps) {
- l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
+ if (len > chan->mps) {
+ l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
goto drop;
}
req_seq = __get_reqseq(control);
- req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
+ req_seq_offset = (req_seq - chan->expected_ack_seq) % 64;
if (req_seq_offset < 0)
req_seq_offset += 64;
next_tx_seq_offset =
- (pi->next_tx_seq - pi->expected_ack_seq) % 64;
+ (chan->next_tx_seq - chan->expected_ack_seq) % 64;
if (next_tx_seq_offset < 0)
next_tx_seq_offset += 64;
/* check for invalid req-seq */
if (req_seq_offset > next_tx_seq_offset) {
- l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
goto drop;
}
if (__is_iframe(control)) {
if (len < 0) {
- l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
goto drop;
}
- l2cap_data_channel_iframe(sk, control, skb);
+ l2cap_data_channel_iframe(chan, control, skb);
} else {
if (len != 0) {
BT_ERR("%d", len);
- l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
+ l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
goto drop;
}
- l2cap_data_channel_sframe(sk, control, skb);
+ l2cap_data_channel_sframe(chan, control, skb);
}
return 0;
@@ -3532,33 +3665,35 @@ drop:
static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
{
- struct sock *sk;
+ struct l2cap_chan *chan;
+ struct sock *sk = NULL;
struct l2cap_pinfo *pi;
u16 control;
u8 tx_seq;
int len;
- sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
- if (!sk) {
+ chan = l2cap_get_chan_by_scid(conn, cid);
+ if (!chan) {
BT_DBG("unknown cid 0x%4.4x", cid);
goto drop;
}
+ sk = chan->sk;
pi = l2cap_pi(sk);
- BT_DBG("sk %p, len %d", sk, skb->len);
+ BT_DBG("chan %p, len %d", chan, skb->len);
if (sk->sk_state != BT_CONNECTED)
goto drop;
- switch (pi->mode) {
+ switch (chan->mode) {
case L2CAP_MODE_BASIC:
/* If socket recv buffers overflows we drop data here
* which is *bad* because L2CAP has to be reliable.
* But we don't have any other choice. L2CAP doesn't
* provide flow control mechanism. */
- if (pi->imtu < skb->len)
+ if (chan->imtu < skb->len)
goto drop;
if (!sock_queue_rcv_skb(sk, skb))
@@ -3580,31 +3715,31 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
skb_pull(skb, 2);
len = skb->len;
- if (l2cap_check_fcs(pi, skb))
+ if (l2cap_check_fcs(chan, skb))
goto drop;
if (__is_sar_start(control))
len -= 2;
- if (pi->fcs == L2CAP_FCS_CRC16)
+ if (chan->fcs == L2CAP_FCS_CRC16)
len -= 2;
- if (len > pi->mps || len < 0 || __is_sframe(control))
+ if (len > chan->mps || len < 0 || __is_sframe(control))
goto drop;
tx_seq = __get_txseq(control);
- if (pi->expected_tx_seq == tx_seq)
- pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
+ if (chan->expected_tx_seq == tx_seq)
+ chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64;
else
- pi->expected_tx_seq = (tx_seq + 1) % 64;
+ chan->expected_tx_seq = (tx_seq + 1) % 64;
- l2cap_streaming_reassembly_sdu(sk, skb, control);
+ l2cap_streaming_reassembly_sdu(chan, skb, control);
goto done;
default:
- BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
+ BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
break;
}
@@ -3620,12 +3755,48 @@ done:
static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
{
- struct sock *sk;
+ struct sock *sk = NULL;
+ struct l2cap_chan *chan;
- sk = l2cap_get_sock_by_psm(0, psm, conn->src);
- if (!sk)
+ chan = l2cap_global_chan_by_psm(0, psm, conn->src);
+ if (!chan)
+ goto drop;
+
+ sk = chan->sk;
+
+ bh_lock_sock(sk);
+
+ BT_DBG("sk %p, len %d", sk, skb->len);
+
+ if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
+ goto drop;
+
+ if (l2cap_pi(sk)->chan->imtu < skb->len)
+ goto drop;
+
+ if (!sock_queue_rcv_skb(sk, skb))
+ goto done;
+
+drop:
+ kfree_skb(skb);
+
+done:
+ if (sk)
+ bh_unlock_sock(sk);
+ return 0;
+}
+
+static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct sk_buff *skb)
+{
+ struct sock *sk = NULL;
+ struct l2cap_chan *chan;
+
+ chan = l2cap_global_chan_by_scid(0, cid, conn->src);
+ if (!chan)
goto drop;
+ sk = chan->sk;
+
bh_lock_sock(sk);
BT_DBG("sk %p, len %d", sk, skb->len);
@@ -3633,7 +3804,7 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str
if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
goto drop;
- if (l2cap_pi(sk)->imtu < skb->len)
+ if (l2cap_pi(sk)->chan->imtu < skb->len)
goto drop;
if (!sock_queue_rcv_skb(sk, skb))
@@ -3677,6 +3848,10 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
l2cap_conless_channel(conn, psm, skb);
break;
+ case L2CAP_CID_LE_DATA:
+ l2cap_att_channel(conn, cid, skb);
+ break;
+
default:
l2cap_data_channel(conn, cid, skb);
break;
@@ -3688,8 +3863,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
{
int exact = 0, lm1 = 0, lm2 = 0;
- register struct sock *sk;
- struct hlist_node *node;
+ struct l2cap_chan *c;
if (type != ACL_LINK)
return -EINVAL;
@@ -3697,23 +3871,25 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
/* Find listening sockets and check their link_mode */
- read_lock(&l2cap_sk_list.lock);
- sk_for_each(sk, node, &l2cap_sk_list.head) {
+ read_lock(&chan_list_lock);
+ list_for_each_entry(c, &chan_list, global_l) {
+ struct sock *sk = c->sk;
+
if (sk->sk_state != BT_LISTEN)
continue;
if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
lm1 |= HCI_LM_ACCEPT;
- if (l2cap_pi(sk)->role_switch)
+ if (c->role_switch)
lm1 |= HCI_LM_MASTER;
exact++;
} else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
lm2 |= HCI_LM_ACCEPT;
- if (l2cap_pi(sk)->role_switch)
+ if (c->role_switch)
lm2 |= HCI_LM_MASTER;
}
}
- read_unlock(&l2cap_sk_list.lock);
+ read_unlock(&chan_list_lock);
return exact ? lm1 : lm2;
}
@@ -3761,49 +3937,50 @@ static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
return 0;
}
-static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
+static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
{
+ struct sock *sk = chan->sk;
+
if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
return;
if (encrypt == 0x00) {
- if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
+ if (chan->sec_level == BT_SECURITY_MEDIUM) {
l2cap_sock_clear_timer(sk);
l2cap_sock_set_timer(sk, HZ * 5);
- } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
+ } else if (chan->sec_level == BT_SECURITY_HIGH)
__l2cap_sock_close(sk, ECONNREFUSED);
} else {
- if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
+ if (chan->sec_level == BT_SECURITY_MEDIUM)
l2cap_sock_clear_timer(sk);
}
}
static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
{
- struct l2cap_chan_list *l;
struct l2cap_conn *conn = hcon->l2cap_data;
- struct sock *sk;
+ struct l2cap_chan *chan;
if (!conn)
return 0;
- l = &conn->chan_list;
-
BT_DBG("conn %p", conn);
- read_lock(&l->lock);
+ read_lock(&conn->chan_lock);
+
+ list_for_each_entry(chan, &conn->chan_l, list) {
+ struct sock *sk = chan->sk;
- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
bh_lock_sock(sk);
- if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
+ if (chan->conf_state & L2CAP_CONF_CONNECT_PEND) {
bh_unlock_sock(sk);
continue;
}
if (!status && (sk->sk_state == BT_CONNECTED ||
sk->sk_state == BT_CONFIG)) {
- l2cap_check_encryption(sk, encrypt);
+ l2cap_check_encryption(chan, encrypt);
bh_unlock_sock(sk);
continue;
}
@@ -3811,13 +3988,13 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
if (sk->sk_state == BT_CONNECT) {
if (!status) {
struct l2cap_conn_req req;
- req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
- req.psm = l2cap_pi(sk)->psm;
+ req.scid = cpu_to_le16(chan->scid);
+ req.psm = chan->psm;
- l2cap_pi(sk)->ident = l2cap_get_ident(conn);
- l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
+ chan->ident = l2cap_get_ident(conn);
+ chan->conf_state |= L2CAP_CONF_CONNECT_PEND;
- l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
+ l2cap_send_cmd(conn, chan->ident,
L2CAP_CONN_REQ, sizeof(req), &req);
} else {
l2cap_sock_clear_timer(sk);
@@ -3836,18 +4013,18 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
result = L2CAP_CR_SEC_BLOCK;
}
- rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
- rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
+ rsp.scid = cpu_to_le16(chan->dcid);
+ rsp.dcid = cpu_to_le16(chan->scid);
rsp.result = cpu_to_le16(result);
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
- l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
- L2CAP_CONN_RSP, sizeof(rsp), &rsp);
+ l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
+ sizeof(rsp), &rsp);
}
bh_unlock_sock(sk);
}
- read_unlock(&l->lock);
+ read_unlock(&conn->chan_lock);
return 0;
}
@@ -3866,7 +4043,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
if (!(flags & ACL_CONT)) {
struct l2cap_hdr *hdr;
- struct sock *sk;
+ struct l2cap_chan *chan;
u16 cid;
int len;
@@ -3904,18 +4081,21 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
goto drop;
}
- sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
+ chan = l2cap_get_chan_by_scid(conn, cid);
- if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) {
- BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)",
- len, l2cap_pi(sk)->imtu);
- bh_unlock_sock(sk);
- l2cap_conn_unreliable(conn, ECOMM);
- goto drop;
- }
+ if (chan && chan->sk) {
+ struct sock *sk = chan->sk;
- if (sk)
+ if (chan->imtu < len - L2CAP_HDR_SIZE) {
+ BT_ERR("Frame exceeding recv MTU (len %d, "
+ "MTU %d)", len,
+ chan->imtu);
+ bh_unlock_sock(sk);
+ l2cap_conn_unreliable(conn, ECOMM);
+ goto drop;
+ }
bh_unlock_sock(sk);
+ }
/* Allocate skb for the complete frame (with header) */
conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
@@ -3962,24 +4142,22 @@ drop:
static int l2cap_debugfs_show(struct seq_file *f, void *p)
{
- struct sock *sk;
- struct hlist_node *node;
+ struct l2cap_chan *c;
- read_lock_bh(&l2cap_sk_list.lock);
+ read_lock_bh(&chan_list_lock);
- sk_for_each(sk, node, &l2cap_sk_list.head) {
- struct l2cap_pinfo *pi = l2cap_pi(sk);
+ list_for_each_entry(c, &chan_list, global_l) {
+ struct sock *sk = c->sk;
seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
batostr(&bt_sk(sk)->src),
batostr(&bt_sk(sk)->dst),
- sk->sk_state, __le16_to_cpu(pi->psm),
- pi->scid, pi->dcid,
- pi->imtu, pi->omtu, pi->sec_level,
- pi->mode);
+ sk->sk_state, __le16_to_cpu(c->psm),
+ c->scid, c->dcid, c->imtu, c->omtu,
+ c->sec_level, c->mode);
}
- read_unlock_bh(&l2cap_sk_list.lock);
+ read_unlock_bh(&chan_list_lock);
return 0;
}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 299fe56a966..18dc9888d8c 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -30,6 +30,8 @@
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
+static const struct proto_ops l2cap_sock_ops;
+
/* ---- L2CAP timers ---- */
static void l2cap_sock_timeout(unsigned long arg)
{
@@ -51,7 +53,7 @@ static void l2cap_sock_timeout(unsigned long arg)
if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
reason = ECONNREFUSED;
else if (sk->sk_state == BT_CONNECT &&
- l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
+ l2cap_pi(sk)->chan->sec_level != BT_SECURITY_SDP)
reason = ECONNREFUSED;
else
reason = ETIMEDOUT;
@@ -76,21 +78,10 @@ void l2cap_sock_clear_timer(struct sock *sk)
sk_stop_timer(sk, &sk->sk_timer);
}
-static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
-{
- struct sock *sk;
- struct hlist_node *node;
- sk_for_each(sk, node, &l2cap_sk_list.head)
- if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
- goto found;
- sk = NULL;
-found:
- return sk;
-}
-
static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
{
struct sock *sk = sock->sk;
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct sockaddr_l2 la;
int len, err = 0;
@@ -129,26 +120,20 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
}
}
- write_lock_bh(&l2cap_sk_list.lock);
+ if (la.l2_cid)
+ err = l2cap_add_scid(chan, la.l2_cid);
+ else
+ err = l2cap_add_psm(chan, &la.l2_bdaddr, la.l2_psm);
- if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
- err = -EADDRINUSE;
- } else {
- /* Save source address */
- bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
- l2cap_pi(sk)->psm = la.l2_psm;
- l2cap_pi(sk)->sport = la.l2_psm;
- sk->sk_state = BT_BOUND;
-
- if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
- __le16_to_cpu(la.l2_psm) == 0x0003)
- l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
- }
+ if (err < 0)
+ goto done;
- if (la.l2_cid)
- l2cap_pi(sk)->scid = la.l2_cid;
+ if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
+ __le16_to_cpu(la.l2_psm) == 0x0003)
+ chan->sec_level = BT_SECURITY_SDP;
- write_unlock_bh(&l2cap_sk_list.lock);
+ bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
+ sk->sk_state = BT_BOUND;
done:
release_sock(sk);
@@ -158,6 +143,7 @@ done:
static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
{
struct sock *sk = sock->sk;
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct sockaddr_l2 la;
int len, err = 0;
@@ -182,7 +168,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
goto done;
}
- switch (l2cap_pi(sk)->mode) {
+ switch (chan->mode) {
case L2CAP_MODE_BASIC:
break;
case L2CAP_MODE_ERTM:
@@ -226,10 +212,10 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
/* Set destination address and psm */
bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
- l2cap_pi(sk)->psm = la.l2_psm;
- l2cap_pi(sk)->dcid = la.l2_cid;
+ chan->psm = la.l2_psm;
+ chan->dcid = la.l2_cid;
- err = l2cap_do_connect(sk);
+ err = l2cap_chan_connect(l2cap_pi(sk)->chan);
if (err)
goto done;
@@ -244,6 +230,7 @@ done:
static int l2cap_sock_listen(struct socket *sock, int backlog)
{
struct sock *sk = sock->sk;
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
int err = 0;
BT_DBG("sk %p backlog %d", sk, backlog);
@@ -256,7 +243,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
goto done;
}
- switch (l2cap_pi(sk)->mode) {
+ switch (chan->mode) {
case L2CAP_MODE_BASIC:
break;
case L2CAP_MODE_ERTM:
@@ -269,28 +256,6 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
goto done;
}
- if (!l2cap_pi(sk)->psm && !l2cap_pi(sk)->dcid) {
- bdaddr_t *src = &bt_sk(sk)->src;
- u16 psm;
-
- err = -EINVAL;
-
- write_lock_bh(&l2cap_sk_list.lock);
-
- for (psm = 0x1001; psm < 0x1100; psm += 2)
- if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
- l2cap_pi(sk)->psm = cpu_to_le16(psm);
- l2cap_pi(sk)->sport = cpu_to_le16(psm);
- err = 0;
- break;
- }
-
- write_unlock_bh(&l2cap_sk_list.lock);
-
- if (err < 0)
- goto done;
- }
-
sk->sk_max_ack_backlog = backlog;
sk->sk_ack_backlog = 0;
sk->sk_state = BT_LISTEN;
@@ -360,6 +325,7 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
{
struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
struct sock *sk = sock->sk;
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
BT_DBG("sock %p, sk %p", sock, sk);
@@ -367,13 +333,13 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
*len = sizeof(struct sockaddr_l2);
if (peer) {
- la->l2_psm = l2cap_pi(sk)->psm;
+ la->l2_psm = chan->psm;
bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
- la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
+ la->l2_cid = cpu_to_le16(chan->dcid);
} else {
- la->l2_psm = l2cap_pi(sk)->sport;
+ la->l2_psm = chan->sport;
bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
- la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
+ la->l2_cid = cpu_to_le16(chan->scid);
}
return 0;
@@ -382,6 +348,7 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
{
struct sock *sk = sock->sk;
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct l2cap_options opts;
struct l2cap_conninfo cinfo;
int len, err = 0;
@@ -397,13 +364,13 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
switch (optname) {
case L2CAP_OPTIONS:
memset(&opts, 0, sizeof(opts));
- opts.imtu = l2cap_pi(sk)->imtu;
- opts.omtu = l2cap_pi(sk)->omtu;
- opts.flush_to = l2cap_pi(sk)->flush_to;
- opts.mode = l2cap_pi(sk)->mode;
- opts.fcs = l2cap_pi(sk)->fcs;
- opts.max_tx = l2cap_pi(sk)->max_tx;
- opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
+ opts.imtu = chan->imtu;
+ opts.omtu = chan->omtu;
+ opts.flush_to = chan->flush_to;
+ opts.mode = chan->mode;
+ opts.fcs = chan->fcs;
+ opts.max_tx = chan->max_tx;
+ opts.txwin_size = (__u16)chan->tx_win;
len = min_t(unsigned int, len, sizeof(opts));
if (copy_to_user(optval, (char *) &opts, len))
@@ -412,7 +379,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
break;
case L2CAP_LM:
- switch (l2cap_pi(sk)->sec_level) {
+ switch (chan->sec_level) {
case BT_SECURITY_LOW:
opt = L2CAP_LM_AUTH;
break;
@@ -428,10 +395,10 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
break;
}
- if (l2cap_pi(sk)->role_switch)
+ if (chan->role_switch)
opt |= L2CAP_LM_MASTER;
- if (l2cap_pi(sk)->force_reliable)
+ if (chan->force_reliable)
opt |= L2CAP_LM_RELIABLE;
if (put_user(opt, (u32 __user *) optval))
@@ -446,8 +413,8 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
break;
}
- cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
- memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
+ cinfo.hci_handle = chan->conn->hcon->handle;
+ memcpy(cinfo.dev_class, chan->conn->hcon->dev_class, 3);
len = min_t(unsigned int, len, sizeof(cinfo));
if (copy_to_user(optval, (char *) &cinfo, len))
@@ -467,6 +434,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
{
struct sock *sk = sock->sk;
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct bt_security sec;
int len, err = 0;
@@ -491,7 +459,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
break;
}
- sec.level = l2cap_pi(sk)->sec_level;
+ sec.level = chan->sec_level;
len = min_t(unsigned int, len, sizeof(sec));
if (copy_to_user(optval, (char *) &sec, len))
@@ -511,7 +479,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
break;
case BT_FLUSHABLE:
- if (put_user(l2cap_pi(sk)->flushable, (u32 __user *) optval))
+ if (put_user(chan->flushable, (u32 __user *) optval))
err = -EFAULT;
break;
@@ -528,6 +496,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct l2cap_options opts;
int len, err = 0;
u32 opt;
@@ -543,13 +512,13 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
break;
}
- opts.imtu = l2cap_pi(sk)->imtu;
- opts.omtu = l2cap_pi(sk)->omtu;
- opts.flush_to = l2cap_pi(sk)->flush_to;
- opts.mode = l2cap_pi(sk)->mode;
- opts.fcs = l2cap_pi(sk)->fcs;
- opts.max_tx = l2cap_pi(sk)->max_tx;
- opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
+ opts.imtu = chan->imtu;
+ opts.omtu = chan->omtu;
+ opts.flush_to = chan->flush_to;
+ opts.mode = chan->mode;
+ opts.fcs = chan->fcs;
+ opts.max_tx = chan->max_tx;
+ opts.txwin_size = (__u16)chan->tx_win;
len = min_t(unsigned int, sizeof(opts), optlen);
if (copy_from_user((char *) &opts, optval, len)) {
@@ -562,10 +531,10 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
break;
}
- l2cap_pi(sk)->mode = opts.mode;
- switch (l2cap_pi(sk)->mode) {
+ chan->mode = opts.mode;
+ switch (chan->mode) {
case L2CAP_MODE_BASIC:
- l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE;
+ chan->conf_state &= ~L2CAP_CONF_STATE2_DEVICE;
break;
case L2CAP_MODE_ERTM:
case L2CAP_MODE_STREAMING:
@@ -577,11 +546,11 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
break;
}
- l2cap_pi(sk)->imtu = opts.imtu;
- l2cap_pi(sk)->omtu = opts.omtu;
- l2cap_pi(sk)->fcs = opts.fcs;
- l2cap_pi(sk)->max_tx = opts.max_tx;
- l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
+ chan->imtu = opts.imtu;
+ chan->omtu = opts.omtu;
+ chan->fcs = opts.fcs;
+ chan->max_tx = opts.max_tx;
+ chan->tx_win = (__u8)opts.txwin_size;
break;
case L2CAP_LM:
@@ -591,14 +560,14 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
}
if (opt & L2CAP_LM_AUTH)
- l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
+ chan->sec_level = BT_SECURITY_LOW;
if (opt & L2CAP_LM_ENCRYPT)
- l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
+ chan->sec_level = BT_SECURITY_MEDIUM;
if (opt & L2CAP_LM_SECURE)
- l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
+ chan->sec_level = BT_SECURITY_HIGH;
- l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
- l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
+ chan->role_switch = (opt & L2CAP_LM_MASTER);
+ chan->force_reliable = (opt & L2CAP_LM_RELIABLE);
break;
default:
@@ -613,6 +582,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct bt_security sec;
int len, err = 0;
u32 opt;
@@ -649,7 +619,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
break;
}
- l2cap_pi(sk)->sec_level = sec.level;
+ chan->sec_level = sec.level;
break;
case BT_DEFER_SETUP:
@@ -678,7 +648,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
}
if (opt == BT_FLUSHABLE_OFF) {
- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+ struct l2cap_conn *conn = chan->conn;
/* proceed further only when we have l2cap_conn and
No Flush support in the LM */
if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) {
@@ -687,7 +657,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
}
}
- l2cap_pi(sk)->flushable = opt;
+ chan->flushable = opt;
break;
default:
@@ -702,7 +672,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
{
struct sock *sk = sock->sk;
- struct l2cap_pinfo *pi = l2cap_pi(sk);
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct sk_buff *skb;
u16 control;
int err;
@@ -725,74 +695,77 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
/* Connectionless channel */
if (sk->sk_type == SOCK_DGRAM) {
- skb = l2cap_create_connless_pdu(sk, msg, len);
+ skb = l2cap_create_connless_pdu(chan, msg, len);
if (IS_ERR(skb)) {
err = PTR_ERR(skb);
} else {
- l2cap_do_send(sk, skb);
+ l2cap_do_send(chan, skb);
err = len;
}
goto done;
}
- switch (pi->mode) {
+ switch (chan->mode) {
case L2CAP_MODE_BASIC:
/* Check outgoing MTU */
- if (len > pi->omtu) {
+ if (len > chan->omtu) {
err = -EMSGSIZE;
goto done;
}
/* Create a basic PDU */
- skb = l2cap_create_basic_pdu(sk, msg, len);
+ skb = l2cap_create_basic_pdu(chan, msg, len);
if (IS_ERR(skb)) {
err = PTR_ERR(skb);
goto done;
}
- l2cap_do_send(sk, skb);
+ l2cap_do_send(chan, skb);
err = len;
break;
case L2CAP_MODE_ERTM:
case L2CAP_MODE_STREAMING:
/* Entire SDU fits into one PDU */
- if (len <= pi->remote_mps) {
+ if (len <= chan->remote_mps) {
control = L2CAP_SDU_UNSEGMENTED;
- skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
+ skb = l2cap_create_iframe_pdu(chan, msg, len, control,
+ 0);
if (IS_ERR(skb)) {
err = PTR_ERR(skb);
goto done;
}
- __skb_queue_tail(TX_QUEUE(sk), skb);
+ __skb_queue_tail(&chan->tx_q, skb);
- if (sk->sk_send_head == NULL)
- sk->sk_send_head = skb;
+ if (chan->tx_send_head == NULL)
+ chan->tx_send_head = skb;
} else {
/* Segment SDU into multiples PDUs */
- err = l2cap_sar_segment_sdu(sk, msg, len);
+ err = l2cap_sar_segment_sdu(chan, msg, len);
if (err < 0)
goto done;
}
- if (pi->mode == L2CAP_MODE_STREAMING) {
- l2cap_streaming_send(sk);
- } else {
- if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
- (pi->conn_state & L2CAP_CONN_WAIT_F)) {
- err = len;
- break;
- }
- err = l2cap_ertm_send(sk);
+ if (chan->mode == L2CAP_MODE_STREAMING) {
+ l2cap_streaming_send(chan);
+ err = len;
+ break;
+ }
+
+ if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
+ (chan->conn_state & L2CAP_CONN_WAIT_F)) {
+ err = len;
+ break;
}
+ err = l2cap_ertm_send(chan);
if (err >= 0)
err = len;
break;
default:
- BT_DBG("bad state %1.1x", pi->mode);
+ BT_DBG("bad state %1.1x", chan->mode);
err = -EBADFD;
}
@@ -808,29 +781,9 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms
lock_sock(sk);
if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
- struct l2cap_conn_rsp rsp;
- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
- u8 buf[128];
-
sk->sk_state = BT_CONFIG;
- rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
- rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
- rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
- rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
- l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
- L2CAP_CONN_RSP, sizeof(rsp), &rsp);
-
- if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) {
- release_sock(sk);
- return 0;
- }
-
- l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
- l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(sk, buf), buf);
- l2cap_pi(sk)->num_conf_req++;
-
+ __l2cap_connect_rsp_defer(l2cap_pi(sk)->chan);
release_sock(sk);
return 0;
}
@@ -854,7 +807,8 @@ void l2cap_sock_kill(struct sock *sk)
BT_DBG("sk %p state %d", sk, sk->sk_state);
/* Kill poor orphan */
- bt_sock_unlink(&l2cap_sk_list, sk);
+
+ l2cap_chan_destroy(l2cap_pi(sk)->chan);
sock_set_flag(sk, SOCK_DEAD);
sock_put(sk);
}
@@ -885,7 +839,8 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
void __l2cap_sock_close(struct sock *sk, int reason)
{
- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
+ struct l2cap_conn *conn = chan->conn;
BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
@@ -900,9 +855,9 @@ void __l2cap_sock_close(struct sock *sk, int reason)
sk->sk_type == SOCK_STREAM) &&
conn->hcon->type == ACL_LINK) {
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
- l2cap_send_disconn_req(conn, sk, reason);
+ l2cap_send_disconn_req(conn, chan, reason);
} else
- l2cap_chan_del(sk, reason);
+ l2cap_chan_del(chan, reason);
break;
case BT_CONNECT2:
@@ -917,20 +872,20 @@ void __l2cap_sock_close(struct sock *sk, int reason)
else
result = L2CAP_CR_BAD_PSM;
- rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
- rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
+ rsp.scid = cpu_to_le16(chan->dcid);
+ rsp.dcid = cpu_to_le16(chan->scid);
rsp.result = cpu_to_le16(result);
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
- l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
- L2CAP_CONN_RSP, sizeof(rsp), &rsp);
+ l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
+ sizeof(rsp), &rsp);
}
- l2cap_chan_del(sk, reason);
+ l2cap_chan_del(chan, reason);
break;
case BT_CONNECT:
case BT_DISCONN:
- l2cap_chan_del(sk, reason);
+ l2cap_chan_del(chan, reason);
break;
default:
@@ -942,6 +897,7 @@ void __l2cap_sock_close(struct sock *sk, int reason)
static int l2cap_sock_shutdown(struct socket *sock, int how)
{
struct sock *sk = sock->sk;
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
int err = 0;
BT_DBG("sock %p, sk %p", sock, sk);
@@ -951,7 +907,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
lock_sock(sk);
if (!sk->sk_shutdown) {
- if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
+ if (chan->mode == L2CAP_MODE_ERTM)
err = __l2cap_wait_ack(sk);
sk->sk_shutdown = SHUTDOWN_MASK;
@@ -998,49 +954,47 @@ static void l2cap_sock_destruct(struct sock *sk)
void l2cap_sock_init(struct sock *sk, struct sock *parent)
{
struct l2cap_pinfo *pi = l2cap_pi(sk);
+ struct l2cap_chan *chan = pi->chan;
BT_DBG("sk %p", sk);
if (parent) {
+ struct l2cap_chan *pchan = l2cap_pi(parent)->chan;
+
sk->sk_type = parent->sk_type;
bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
- pi->imtu = l2cap_pi(parent)->imtu;
- pi->omtu = l2cap_pi(parent)->omtu;
- pi->conf_state = l2cap_pi(parent)->conf_state;
- pi->mode = l2cap_pi(parent)->mode;
- pi->fcs = l2cap_pi(parent)->fcs;
- pi->max_tx = l2cap_pi(parent)->max_tx;
- pi->tx_win = l2cap_pi(parent)->tx_win;
- pi->sec_level = l2cap_pi(parent)->sec_level;
- pi->role_switch = l2cap_pi(parent)->role_switch;
- pi->force_reliable = l2cap_pi(parent)->force_reliable;
- pi->flushable = l2cap_pi(parent)->flushable;
+ chan->imtu = pchan->imtu;
+ chan->omtu = pchan->omtu;
+ chan->conf_state = pchan->conf_state;
+ chan->mode = pchan->mode;
+ chan->fcs = pchan->fcs;
+ chan->max_tx = pchan->max_tx;
+ chan->tx_win = pchan->tx_win;
+ chan->sec_level = pchan->sec_level;
+ chan->role_switch = pchan->role_switch;
+ chan->force_reliable = pchan->force_reliable;
+ chan->flushable = pchan->flushable;
} else {
- pi->imtu = L2CAP_DEFAULT_MTU;
- pi->omtu = 0;
+ chan->imtu = L2CAP_DEFAULT_MTU;
+ chan->omtu = 0;
if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
- pi->mode = L2CAP_MODE_ERTM;
- pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
+ chan->mode = L2CAP_MODE_ERTM;
+ chan->conf_state |= L2CAP_CONF_STATE2_DEVICE;
} else {
- pi->mode = L2CAP_MODE_BASIC;
+ chan->mode = L2CAP_MODE_BASIC;
}
- pi->max_tx = L2CAP_DEFAULT_MAX_TX;
- pi->fcs = L2CAP_FCS_CRC16;
- pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
- pi->sec_level = BT_SECURITY_LOW;
- pi->role_switch = 0;
- pi->force_reliable = 0;
- pi->flushable = BT_FLUSHABLE_OFF;
+ chan->max_tx = L2CAP_DEFAULT_MAX_TX;
+ chan->fcs = L2CAP_FCS_CRC16;
+ chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
+ chan->sec_level = BT_SECURITY_LOW;
+ chan->role_switch = 0;
+ chan->force_reliable = 0;
+ chan->flushable = BT_FLUSHABLE_OFF;
}
/* Default config options */
- pi->conf_len = 0;
- pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
- skb_queue_head_init(TX_QUEUE(sk));
- skb_queue_head_init(SREJ_QUEUE(sk));
- skb_queue_head_init(BUSY_QUEUE(sk));
- INIT_LIST_HEAD(SREJ_LIST(sk));
+ chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
}
static struct proto l2cap_proto = {
@@ -1070,7 +1024,6 @@ struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, g
setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
- bt_sock_link(&l2cap_sk_list, sk);
return sk;
}
@@ -1078,6 +1031,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
int kern)
{
struct sock *sk;
+ struct l2cap_chan *chan;
BT_DBG("sock %p", sock);
@@ -1096,11 +1050,19 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
if (!sk)
return -ENOMEM;
+ chan = l2cap_chan_create(sk);
+ if (!chan) {
+ l2cap_sock_kill(sk);
+ return -ENOMEM;
+ }
+
+ l2cap_pi(sk)->chan = chan;
+
l2cap_sock_init(sk, NULL);
return 0;
}
-const struct proto_ops l2cap_sock_ops = {
+static const struct proto_ops l2cap_sock_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = l2cap_sock_release,
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 4476d8e3c0f..dae382ce702 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -36,7 +36,7 @@ struct pending_cmd {
struct list_head list;
__u16 opcode;
int index;
- void *cmd;
+ void *param;
struct sock *sk;
void *user_data;
};
@@ -179,10 +179,12 @@ static int read_controller_info(struct sock *sk, u16 index)
hci_del_off_timer(hdev);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
set_bit(HCI_MGMT, &hdev->flags);
+ memset(&rp, 0, sizeof(rp));
+
rp.type = hdev->dev_type;
rp.powered = test_bit(HCI_UP, &hdev->flags);
@@ -204,7 +206,9 @@ static int read_controller_info(struct sock *sk, u16 index)
rp.hci_ver = hdev->hci_ver;
put_unaligned_le16(hdev->hci_rev, &rp.hci_rev);
- hci_dev_unlock_bh(hdev);
+ memcpy(rp.name, hdev->dev_name, sizeof(hdev->dev_name));
+
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return cmd_complete(sk, index, MGMT_OP_READ_INFO, &rp, sizeof(rp));
@@ -213,7 +217,7 @@ static int read_controller_info(struct sock *sk, u16 index)
static void mgmt_pending_free(struct pending_cmd *cmd)
{
sock_put(cmd->sk);
- kfree(cmd->cmd);
+ kfree(cmd->param);
kfree(cmd);
}
@@ -229,13 +233,14 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
cmd->opcode = opcode;
cmd->index = index;
- cmd->cmd = kmalloc(len, GFP_ATOMIC);
- if (!cmd->cmd) {
+ cmd->param = kmalloc(len, GFP_ATOMIC);
+ if (!cmd->param) {
kfree(cmd);
return NULL;
}
- memcpy(cmd->cmd, data, len);
+ if (data)
+ memcpy(cmd->param, data, len);
cmd->sk = sk;
sock_hold(sk);
@@ -311,7 +316,7 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len)
if (!hdev)
return cmd_status(sk, index, MGMT_OP_SET_POWERED, ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
up = test_bit(HCI_UP, &hdev->flags);
if ((cp->val && up) || (!cp->val && !up)) {
@@ -338,7 +343,7 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len)
err = 0;
failed:
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
}
@@ -363,7 +368,7 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data,
if (!hdev)
return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
if (!test_bit(HCI_UP, &hdev->flags)) {
err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENETDOWN);
@@ -398,7 +403,7 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data,
mgmt_pending_remove(cmd);
failed:
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
@@ -424,7 +429,7 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data,
if (!hdev)
return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
if (!test_bit(HCI_UP, &hdev->flags)) {
err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENETDOWN);
@@ -458,7 +463,7 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data,
mgmt_pending_remove(cmd);
failed:
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
@@ -517,7 +522,7 @@ static int set_pairable(struct sock *sk, u16 index, unsigned char *data,
if (!hdev)
return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
if (cp->val)
set_bit(HCI_PAIRABLE, &hdev->flags);
@@ -533,12 +538,156 @@ static int set_pairable(struct sock *sk, u16 index, unsigned char *data,
err = mgmt_event(MGMT_EV_PAIRABLE, index, &ev, sizeof(ev), sk);
failed:
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
}
+#define EIR_FLAGS 0x01 /* flags */
+#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
+#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
+#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */
+#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
+#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */
+#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
+#define EIR_NAME_SHORT 0x08 /* shortened local name */
+#define EIR_NAME_COMPLETE 0x09 /* complete local name */
+#define EIR_TX_POWER 0x0A /* transmit power level */
+#define EIR_DEVICE_ID 0x10 /* device ID */
+
+#define PNP_INFO_SVCLASS_ID 0x1200
+
+static u8 bluetooth_base_uuid[] = {
+ 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static u16 get_uuid16(u8 *uuid128)
+{
+ u32 val;
+ int i;
+
+ for (i = 0; i < 12; i++) {
+ if (bluetooth_base_uuid[i] != uuid128[i])
+ return 0;
+ }
+
+ memcpy(&val, &uuid128[12], 4);
+
+ val = le32_to_cpu(val);
+ if (val > 0xffff)
+ return 0;
+
+ return (u16) val;
+}
+
+static void create_eir(struct hci_dev *hdev, u8 *data)
+{
+ u8 *ptr = data;
+ u16 eir_len = 0;
+ u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)];
+ int i, truncated = 0;
+ struct list_head *p;
+ size_t name_len;
+
+ name_len = strlen(hdev->dev_name);
+
+ if (name_len > 0) {
+ /* EIR Data type */
+ if (name_len > 48) {
+ name_len = 48;
+ ptr[1] = EIR_NAME_SHORT;
+ } else
+ ptr[1] = EIR_NAME_COMPLETE;
+
+ /* EIR Data length */
+ ptr[0] = name_len + 1;
+
+ memcpy(ptr + 2, hdev->dev_name, name_len);
+
+ eir_len += (name_len + 2);
+ ptr += (name_len + 2);
+ }
+
+ memset(uuid16_list, 0, sizeof(uuid16_list));
+
+ /* Group all UUID16 types */
+ list_for_each(p, &hdev->uuids) {
+ struct bt_uuid *uuid = list_entry(p, struct bt_uuid, list);
+ u16 uuid16;
+
+ uuid16 = get_uuid16(uuid->uuid);
+ if (uuid16 == 0)
+ return;
+
+ if (uuid16 < 0x1100)
+ continue;
+
+ if (uuid16 == PNP_INFO_SVCLASS_ID)
+ continue;
+
+ /* Stop if not enough space to put next UUID */
+ if (eir_len + 2 + sizeof(u16) > HCI_MAX_EIR_LENGTH) {
+ truncated = 1;
+ break;
+ }
+
+ /* Check for duplicates */
+ for (i = 0; uuid16_list[i] != 0; i++)
+ if (uuid16_list[i] == uuid16)
+ break;
+
+ if (uuid16_list[i] == 0) {
+ uuid16_list[i] = uuid16;
+ eir_len += sizeof(u16);
+ }
+ }
+
+ if (uuid16_list[0] != 0) {
+ u8 *length = ptr;
+
+ /* EIR Data type */
+ ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL;
+
+ ptr += 2;
+ eir_len += 2;
+
+ for (i = 0; uuid16_list[i] != 0; i++) {
+ *ptr++ = (uuid16_list[i] & 0x00ff);
+ *ptr++ = (uuid16_list[i] & 0xff00) >> 8;
+ }
+
+ /* EIR Data length */
+ *length = (i * sizeof(u16)) + 1;
+ }
+}
+
+static int update_eir(struct hci_dev *hdev)
+{
+ struct hci_cp_write_eir cp;
+
+ if (!(hdev->features[6] & LMP_EXT_INQ))
+ return 0;
+
+ if (hdev->ssp_mode == 0)
+ return 0;
+
+ if (test_bit(HCI_SERVICE_CACHE, &hdev->flags))
+ return 0;
+
+ memset(&cp, 0, sizeof(cp));
+
+ create_eir(hdev, cp.data);
+
+ if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0)
+ return 0;
+
+ memcpy(hdev->eir, cp.data, sizeof(cp.data));
+
+ return hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
+}
+
static u8 get_service_classes(struct hci_dev *hdev)
{
struct list_head *p;
@@ -590,7 +739,7 @@ static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
if (!hdev)
return cmd_status(sk, index, MGMT_OP_ADD_UUID, ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC);
if (!uuid) {
@@ -607,10 +756,14 @@ static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
if (err < 0)
goto failed;
+ err = update_eir(hdev);
+ if (err < 0)
+ goto failed;
+
err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, NULL, 0);
failed:
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
@@ -635,7 +788,7 @@ static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
if (!hdev)
return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) {
err = hci_uuids_clear(hdev);
@@ -663,10 +816,14 @@ static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
if (err < 0)
goto unlock;
+ err = update_eir(hdev);
+ if (err < 0)
+ goto unlock;
+
err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0);
unlock:
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
@@ -690,7 +847,7 @@ static int set_dev_class(struct sock *sk, u16 index, unsigned char *data,
if (!hdev)
return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
hdev->major_class = cp->major;
hdev->minor_class = cp->minor;
@@ -700,7 +857,7 @@ static int set_dev_class(struct sock *sk, u16 index, unsigned char *data,
if (err == 0)
err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, NULL, 0);
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
@@ -722,7 +879,7 @@ static int set_service_cache(struct sock *sk, u16 index, unsigned char *data,
if (!hdev)
return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
BT_DBG("hci%u enable %d", index, cp->enable);
@@ -732,13 +889,15 @@ static int set_service_cache(struct sock *sk, u16 index, unsigned char *data,
} else {
clear_bit(HCI_SERVICE_CACHE, &hdev->flags);
err = update_class(hdev);
+ if (err == 0)
+ err = update_eir(hdev);
}
if (err == 0)
err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, NULL,
0);
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
@@ -772,7 +931,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys,
key_count);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
hci_link_keys_clear(hdev);
@@ -786,11 +945,11 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
for (i = 0; i < key_count; i++) {
struct mgmt_key_info *key = &cp->keys[i];
- hci_add_link_key(hdev, 0, &key->bdaddr, key->val, key->type,
+ hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type,
key->pin_len);
}
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return 0;
@@ -812,7 +971,7 @@ static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len)
if (!hdev)
return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
err = hci_remove_link_key(hdev, &cp->bdaddr);
if (err < 0) {
@@ -835,7 +994,7 @@ static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len)
}
unlock:
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
@@ -861,7 +1020,7 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
if (!hdev)
return cmd_status(sk, index, MGMT_OP_DISCONNECT, ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
if (!test_bit(HCI_UP, &hdev->flags)) {
err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENETDOWN);
@@ -874,6 +1033,9 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
}
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
+ if (!conn)
+ conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->bdaddr);
+
if (!conn) {
err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENOTCONN);
goto failed;
@@ -893,7 +1055,7 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
mgmt_pending_remove(cmd);
failed:
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
@@ -914,7 +1076,7 @@ static int get_connections(struct sock *sk, u16 index)
if (!hdev)
return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS, ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
count = 0;
list_for_each(p, &hdev->conn_hash.list) {
@@ -945,7 +1107,7 @@ static int get_connections(struct sock *sk, u16 index)
unlock:
kfree(rp);
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
}
@@ -970,7 +1132,7 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data,
if (!hdev)
return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
if (!test_bit(HCI_UP, &hdev->flags)) {
err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENETDOWN);
@@ -992,7 +1154,7 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data,
mgmt_pending_remove(cmd);
failed:
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
@@ -1019,7 +1181,7 @@ static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data,
return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
if (!test_bit(HCI_UP, &hdev->flags)) {
err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
@@ -1040,7 +1202,7 @@ static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data,
mgmt_pending_remove(cmd);
failed:
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
@@ -1063,14 +1225,14 @@ static int set_io_capability(struct sock *sk, u16 index, unsigned char *data,
if (!hdev)
return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
hdev->io_capability = cp->io_capability;
BT_DBG("%s IO capability set to 0x%02x", hdev->name,
hdev->io_capability);
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, NULL, 0);
@@ -1156,7 +1318,7 @@ static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len)
if (!hdev)
return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
if (cp->io_cap == 0x03) {
sec_level = BT_SECURITY_MEDIUM;
@@ -1198,7 +1360,7 @@ static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len)
err = 0;
unlock:
- hci_dev_unlock_bh(hdev);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
@@ -1230,7 +1392,7 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data,
if (!hdev)
return cmd_status(sk, index, mgmt_op, ENODEV);
- hci_dev_lock_bh(hdev);
+ hci_dev_lock(hdev);
if (!test_bit(HCI_UP, &hdev->flags)) {
err = cmd_status(sk, index, mgmt_op, ENETDOWN);
@@ -1248,6 +1410,231 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data,
mgmt_pending_remove(cmd);
failed:
+ hci_dev_unlock(hdev);
+ hci_dev_put(hdev);
+
+ return err;
+}
+
+static int set_local_name(struct sock *sk, u16 index, unsigned char *data,
+ u16 len)
+{
+ struct mgmt_cp_set_local_name *mgmt_cp = (void *) data;
+ struct hci_cp_write_local_name hci_cp;
+ struct hci_dev *hdev;
+ struct pending_cmd *cmd;
+ int err;
+
+ BT_DBG("");
+
+ if (len != sizeof(*mgmt_cp))
+ return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME, EINVAL);
+
+ hdev = hci_dev_get(index);
+ if (!hdev)
+ return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME, ENODEV);
+
+ hci_dev_lock(hdev);
+
+ cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, index, data, len);
+ if (!cmd) {
+ err = -ENOMEM;
+ goto failed;
+ }
+
+ memcpy(hci_cp.name, mgmt_cp->name, sizeof(hci_cp.name));
+ err = hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(hci_cp),
+ &hci_cp);
+ if (err < 0)
+ mgmt_pending_remove(cmd);
+
+failed:
+ hci_dev_unlock(hdev);
+ hci_dev_put(hdev);
+
+ return err;
+}
+
+static int read_local_oob_data(struct sock *sk, u16 index)
+{
+ struct hci_dev *hdev;
+ struct pending_cmd *cmd;
+ int err;
+
+ BT_DBG("hci%u", index);
+
+ hdev = hci_dev_get(index);
+ if (!hdev)
+ return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
+ ENODEV);
+
+ hci_dev_lock(hdev);
+
+ if (!test_bit(HCI_UP, &hdev->flags)) {
+ err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
+ ENETDOWN);
+ goto unlock;
+ }
+
+ if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) {
+ err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
+ EOPNOTSUPP);
+ goto unlock;
+ }
+
+ if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index)) {
+ err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, EBUSY);
+ goto unlock;
+ }
+
+ cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, index, NULL, 0);
+ if (!cmd) {
+ err = -ENOMEM;
+ goto unlock;
+ }
+
+ err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
+ if (err < 0)
+ mgmt_pending_remove(cmd);
+
+unlock:
+ hci_dev_unlock(hdev);
+ hci_dev_put(hdev);
+
+ return err;
+}
+
+static int add_remote_oob_data(struct sock *sk, u16 index, unsigned char *data,
+ u16 len)
+{
+ struct hci_dev *hdev;
+ struct mgmt_cp_add_remote_oob_data *cp = (void *) data;
+ int err;
+
+ BT_DBG("hci%u ", index);
+
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
+ EINVAL);
+
+ hdev = hci_dev_get(index);
+ if (!hdev)
+ return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
+ ENODEV);
+
+ hci_dev_lock(hdev);
+
+ err = hci_add_remote_oob_data(hdev, &cp->bdaddr, cp->hash,
+ cp->randomizer);
+ if (err < 0)
+ err = cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, -err);
+ else
+ err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL,
+ 0);
+
+ hci_dev_unlock(hdev);
+ hci_dev_put(hdev);
+
+ return err;
+}
+
+static int remove_remote_oob_data(struct sock *sk, u16 index,
+ unsigned char *data, u16 len)
+{
+ struct hci_dev *hdev;
+ struct mgmt_cp_remove_remote_oob_data *cp = (void *) data;
+ int err;
+
+ BT_DBG("hci%u ", index);
+
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
+ EINVAL);
+
+ hdev = hci_dev_get(index);
+ if (!hdev)
+ return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
+ ENODEV);
+
+ hci_dev_lock(hdev);
+
+ err = hci_remove_remote_oob_data(hdev, &cp->bdaddr);
+ if (err < 0)
+ err = cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
+ -err);
+ else
+ err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
+ NULL, 0);
+
+ hci_dev_unlock(hdev);
+ hci_dev_put(hdev);
+
+ return err;
+}
+
+static int start_discovery(struct sock *sk, u16 index)
+{
+ u8 lap[3] = { 0x33, 0x8b, 0x9e };
+ struct hci_cp_inquiry cp;
+ struct pending_cmd *cmd;
+ struct hci_dev *hdev;
+ int err;
+
+ BT_DBG("hci%u", index);
+
+ hdev = hci_dev_get(index);
+ if (!hdev)
+ return cmd_status(sk, index, MGMT_OP_START_DISCOVERY, ENODEV);
+
+ hci_dev_lock_bh(hdev);
+
+ cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, index, NULL, 0);
+ if (!cmd) {
+ err = -ENOMEM;
+ goto failed;
+ }
+
+ memset(&cp, 0, sizeof(cp));
+ memcpy(&cp.lap, lap, 3);
+ cp.length = 0x08;
+ cp.num_rsp = 0x00;
+
+ err = hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
+ if (err < 0)
+ mgmt_pending_remove(cmd);
+
+failed:
+ hci_dev_unlock_bh(hdev);
+ hci_dev_put(hdev);
+
+ return err;
+}
+
+static int stop_discovery(struct sock *sk, u16 index)
+{
+ struct hci_dev *hdev;
+ struct pending_cmd *cmd;
+ int err;
+
+ BT_DBG("hci%u", index);
+
+ hdev = hci_dev_get(index);
+ if (!hdev)
+ return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY, ENODEV);
+
+ hci_dev_lock_bh(hdev);
+
+ cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, index, NULL, 0);
+ if (!cmd) {
+ err = -ENOMEM;
+ goto failed;
+ }
+
+ err = hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
+ if (err < 0)
+ mgmt_pending_remove(cmd);
+
+failed:
hci_dev_unlock_bh(hdev);
hci_dev_put(hdev);
@@ -1266,7 +1653,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
if (msglen < sizeof(*hdr))
return -EINVAL;
- buf = kmalloc(msglen, GFP_ATOMIC);
+ buf = kmalloc(msglen, GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -1349,6 +1736,25 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
case MGMT_OP_USER_CONFIRM_NEG_REPLY:
err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 0);
break;
+ case MGMT_OP_SET_LOCAL_NAME:
+ err = set_local_name(sk, index, buf + sizeof(*hdr), len);
+ break;
+ case MGMT_OP_READ_LOCAL_OOB_DATA:
+ err = read_local_oob_data(sk, index);
+ break;
+ case MGMT_OP_ADD_REMOTE_OOB_DATA:
+ err = add_remote_oob_data(sk, index, buf + sizeof(*hdr), len);
+ break;
+ case MGMT_OP_REMOVE_REMOTE_OOB_DATA:
+ err = remove_remote_oob_data(sk, index, buf + sizeof(*hdr),
+ len);
+ break;
+ case MGMT_OP_START_DISCOVERY:
+ err = start_discovery(sk, index);
+ break;
+ case MGMT_OP_STOP_DISCOVERY:
+ err = stop_discovery(sk, index);
+ break;
default:
BT_DBG("Unknown op %u", opcode);
err = cmd_status(sk, index, opcode, 0x01);
@@ -1382,7 +1788,7 @@ struct cmd_lookup {
static void mode_rsp(struct pending_cmd *cmd, void *data)
{
- struct mgmt_mode *cp = cmd->cmd;
+ struct mgmt_mode *cp = cmd->param;
struct cmd_lookup *match = data;
if (cp->val != match->val)
@@ -1455,17 +1861,17 @@ int mgmt_connectable(u16 index, u8 connectable)
return ret;
}
-int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type)
+int mgmt_new_key(u16 index, struct link_key *key, u8 persistent)
{
struct mgmt_ev_new_key ev;
memset(&ev, 0, sizeof(ev));
+ ev.store_hint = persistent;
bacpy(&ev.key.bdaddr, &key->bdaddr);
ev.key.type = key->type;
memcpy(ev.key.val, key->val, 16);
ev.key.pin_len = key->pin_len;
- ev.old_key_type = old_key_type;
return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL);
}
@@ -1481,7 +1887,7 @@ int mgmt_connected(u16 index, bdaddr_t *bdaddr)
static void disconnect_rsp(struct pending_cmd *cmd, void *data)
{
- struct mgmt_cp_disconnect *cp = cmd->cmd;
+ struct mgmt_cp_disconnect *cp = cmd->param;
struct sock **sk = data;
struct mgmt_rp_disconnect rp;
@@ -1539,11 +1945,12 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status)
return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL);
}
-int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr)
+int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure)
{
struct mgmt_ev_pin_code_request ev;
bacpy(&ev.bdaddr, bdaddr);
+ ev.secure = secure;
return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev),
NULL);
@@ -1591,13 +1998,15 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
return err;
}
-int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value)
+int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value,
+ u8 confirm_hint)
{
struct mgmt_ev_user_confirm_request ev;
BT_DBG("hci%u", index);
bacpy(&ev.bdaddr, bdaddr);
+ ev.confirm_hint = confirm_hint;
put_unaligned_le32(value, &ev.value);
return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev),
@@ -1645,3 +2054,110 @@ int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status)
return mgmt_event(MGMT_EV_AUTH_FAILED, index, &ev, sizeof(ev), NULL);
}
+
+int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status)
+{
+ struct pending_cmd *cmd;
+ struct hci_dev *hdev;
+ struct mgmt_cp_set_local_name ev;
+ int err;
+
+ memset(&ev, 0, sizeof(ev));
+ memcpy(ev.name, name, HCI_MAX_NAME_LENGTH);
+
+ cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, index);
+ if (!cmd)
+ goto send_event;
+
+ if (status) {
+ err = cmd_status(cmd->sk, index, MGMT_OP_SET_LOCAL_NAME, EIO);
+ goto failed;
+ }
+
+ hdev = hci_dev_get(index);
+ if (hdev) {
+ hci_dev_lock_bh(hdev);
+ update_eir(hdev);
+ hci_dev_unlock_bh(hdev);
+ hci_dev_put(hdev);
+ }
+
+ err = cmd_complete(cmd->sk, index, MGMT_OP_SET_LOCAL_NAME, &ev,
+ sizeof(ev));
+ if (err < 0)
+ goto failed;
+
+send_event:
+ err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, index, &ev, sizeof(ev),
+ cmd ? cmd->sk : NULL);
+
+failed:
+ if (cmd)
+ mgmt_pending_remove(cmd);
+ return err;
+}
+
+int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
+ u8 status)
+{
+ struct pending_cmd *cmd;
+ int err;
+
+ BT_DBG("hci%u status %u", index, status);
+
+ cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index);
+ if (!cmd)
+ return -ENOENT;
+
+ if (status) {
+ err = cmd_status(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
+ EIO);
+ } else {
+ struct mgmt_rp_read_local_oob_data rp;
+
+ memcpy(rp.hash, hash, sizeof(rp.hash));
+ memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer));
+
+ err = cmd_complete(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
+ &rp, sizeof(rp));
+ }
+
+ mgmt_pending_remove(cmd);
+
+ return err;
+}
+
+int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi,
+ u8 *eir)
+{
+ struct mgmt_ev_device_found ev;
+
+ memset(&ev, 0, sizeof(ev));
+
+ bacpy(&ev.bdaddr, bdaddr);
+ memcpy(ev.dev_class, dev_class, sizeof(ev.dev_class));
+ ev.rssi = rssi;
+
+ if (eir)
+ memcpy(ev.eir, eir, sizeof(ev.eir));
+
+ return mgmt_event(MGMT_EV_DEVICE_FOUND, index, &ev, sizeof(ev), NULL);
+}
+
+int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name)
+{
+ struct mgmt_ev_remote_name ev;
+
+ memset(&ev, 0, sizeof(ev));
+
+ bacpy(&ev.bdaddr, bdaddr);
+ memcpy(ev.name, name, HCI_MAX_NAME_LENGTH);
+
+ return mgmt_event(MGMT_EV_REMOTE_NAME, index, &ev, sizeof(ev), NULL);
+}
+
+int mgmt_discovering(u16 index, u8 discovering)
+{
+ return mgmt_event(MGMT_EV_DISCOVERING, index, &discovering,
+ sizeof(discovering), NULL);
+}
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index c9973932456..5759bb7054f 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -232,6 +232,8 @@ static int rfcomm_l2sock_create(struct socket **sock)
static inline int rfcomm_check_security(struct rfcomm_dlc *d)
{
struct sock *sk = d->session->sock->sk;
+ struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
+
__u8 auth_type;
switch (d->sec_level) {
@@ -246,8 +248,7 @@ static inline int rfcomm_check_security(struct rfcomm_dlc *d)
break;
}
- return hci_conn_security(l2cap_pi(sk)->conn->hcon, d->sec_level,
- auth_type);
+ return hci_conn_security(conn->hcon, d->sec_level, auth_type);
}
static void rfcomm_session_timeout(unsigned long arg)
@@ -710,10 +711,10 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
/* Set L2CAP options */
sk = sock->sk;
lock_sock(sk);
- l2cap_pi(sk)->imtu = l2cap_mtu;
- l2cap_pi(sk)->sec_level = sec_level;
+ l2cap_pi(sk)->chan->imtu = l2cap_mtu;
+ l2cap_pi(sk)->chan->sec_level = sec_level;
if (l2cap_ertm)
- l2cap_pi(sk)->mode = L2CAP_MODE_ERTM;
+ l2cap_pi(sk)->chan->mode = L2CAP_MODE_ERTM;
release_sock(sk);
s = rfcomm_session_add(sock, BT_BOUND);
@@ -1241,6 +1242,7 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
void rfcomm_dlc_accept(struct rfcomm_dlc *d)
{
struct sock *sk = d->session->sock->sk;
+ struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
BT_DBG("dlc %p", d);
@@ -1254,7 +1256,7 @@ void rfcomm_dlc_accept(struct rfcomm_dlc *d)
rfcomm_dlc_unlock(d);
if (d->role_switch)
- hci_conn_switch_role(l2cap_pi(sk)->conn->hcon, 0x00);
+ hci_conn_switch_role(conn->hcon, 0x00);
rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
}
@@ -1890,7 +1892,8 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s)
/* We should adjust MTU on incoming sessions.
* L2CAP MTU minus UIH header and FCS. */
- s->mtu = min(l2cap_pi(nsock->sk)->omtu, l2cap_pi(nsock->sk)->imtu) - 5;
+ s->mtu = min(l2cap_pi(nsock->sk)->chan->omtu,
+ l2cap_pi(nsock->sk)->chan->imtu) - 5;
rfcomm_schedule();
} else
@@ -1909,7 +1912,7 @@ static inline void rfcomm_check_connection(struct rfcomm_session *s)
/* We can adjust MTU on outgoing sessions.
* L2CAP MTU minus UIH header and FCS. */
- s->mtu = min(l2cap_pi(sk)->omtu, l2cap_pi(sk)->imtu) - 5;
+ s->mtu = min(l2cap_pi(sk)->chan->omtu, l2cap_pi(sk)->chan->imtu) - 5;
rfcomm_send_sabm(s, 0);
break;
@@ -1992,7 +1995,7 @@ static int rfcomm_add_listener(bdaddr_t *ba)
/* Set L2CAP options */
sk = sock->sk;
lock_sock(sk);
- l2cap_pi(sk)->imtu = l2cap_mtu;
+ l2cap_pi(sk)->chan->imtu = l2cap_mtu;
release_sock(sk);
/* Start listening on the socket */
@@ -2093,7 +2096,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
continue;
- if (!status)
+ if (!status && hci_conn_check_secure(conn, d->sec_level))
set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
else
set_bit(RFCOMM_AUTH_REJECT, &d->flags);
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 66cc1f0c3df..386cfaffd4b 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -743,6 +743,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
struct sock *sk = sock->sk;
struct sock *l2cap_sk;
struct rfcomm_conninfo cinfo;
+ struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
int len, err = 0;
u32 opt;
@@ -787,8 +788,8 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk;
- cinfo.hci_handle = l2cap_pi(l2cap_sk)->conn->hcon->handle;
- memcpy(cinfo.dev_class, l2cap_pi(l2cap_sk)->conn->hcon->dev_class, 3);
+ cinfo.hci_handle = conn->hcon->handle;
+ memcpy(cinfo.dev_class, conn->hcon->dev_class, 3);
len = min_t(unsigned int, len, sizeof(cinfo));
if (copy_to_user(optval, (char *) &cinfo, len))
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 84bbb82599b..f20c4fd915a 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -104,3 +104,4 @@ module_init(br_init)
module_exit(br_deinit)
MODULE_LICENSE("GPL");
MODULE_VERSION(BR_VERSION);
+MODULE_ALIAS_RTNL_LINK("bridge");
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 21e5901186e..a6b2f86378c 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -74,13 +74,23 @@ out:
return NETDEV_TX_OK;
}
+static int br_dev_init(struct net_device *dev)
+{
+ struct net_bridge *br = netdev_priv(dev);
+
+ br->stats = alloc_percpu(struct br_cpu_netstats);
+ if (!br->stats)
+ return -ENOMEM;
+
+ return 0;
+}
+
static int br_dev_open(struct net_device *dev)
{
struct net_bridge *br = netdev_priv(dev);
netif_carrier_off(dev);
-
- br_features_recompute(br);
+ netdev_update_features(dev);
netif_start_queue(dev);
br_stp_enable_bridge(br);
br_multicast_open(br);
@@ -177,48 +187,11 @@ static void br_getinfo(struct net_device *dev, struct ethtool_drvinfo *info)
strcpy(info->bus_info, "N/A");
}
-static int br_set_sg(struct net_device *dev, u32 data)
-{
- struct net_bridge *br = netdev_priv(dev);
-
- if (data)
- br->feature_mask |= NETIF_F_SG;
- else
- br->feature_mask &= ~NETIF_F_SG;
-
- br_features_recompute(br);
- return 0;
-}
-
-static int br_set_tso(struct net_device *dev, u32 data)
-{
- struct net_bridge *br = netdev_priv(dev);
-
- if (data)
- br->feature_mask |= NETIF_F_TSO;
- else
- br->feature_mask &= ~NETIF_F_TSO;
-
- br_features_recompute(br);
- return 0;
-}
-
-static int br_set_tx_csum(struct net_device *dev, u32 data)
+static u32 br_fix_features(struct net_device *dev, u32 features)
{
struct net_bridge *br = netdev_priv(dev);
- if (data)
- br->feature_mask |= NETIF_F_NO_CSUM;
- else
- br->feature_mask &= ~NETIF_F_ALL_CSUM;
-
- br_features_recompute(br);
- return 0;
-}
-
-static int br_set_flags(struct net_device *netdev, u32 data)
-{
- return ethtool_op_set_flags(netdev, data, ETH_FLAG_TXVLAN);
+ return br_features_recompute(br, features);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -319,21 +292,12 @@ static int br_del_slave(struct net_device *dev, struct net_device *slave_dev)
static const struct ethtool_ops br_ethtool_ops = {
.get_drvinfo = br_getinfo,
.get_link = ethtool_op_get_link,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = br_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = br_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = br_set_tso,
- .get_ufo = ethtool_op_get_ufo,
- .set_ufo = ethtool_op_set_ufo,
- .get_flags = ethtool_op_get_flags,
- .set_flags = br_set_flags,
};
static const struct net_device_ops br_netdev_ops = {
.ndo_open = br_dev_open,
.ndo_stop = br_dev_stop,
+ .ndo_init = br_dev_init,
.ndo_start_xmit = br_dev_xmit,
.ndo_get_stats64 = br_get_stats64,
.ndo_set_mac_address = br_set_mac_address,
@@ -347,6 +311,7 @@ static const struct net_device_ops br_netdev_ops = {
#endif
.ndo_add_slave = br_add_slave,
.ndo_del_slave = br_del_slave,
+ .ndo_fix_features = br_fix_features,
};
static void br_dev_free(struct net_device *dev)
@@ -357,18 +322,49 @@ static void br_dev_free(struct net_device *dev)
free_netdev(dev);
}
+static struct device_type br_type = {
+ .name = "bridge",
+};
+
void br_dev_setup(struct net_device *dev)
{
+ struct net_bridge *br = netdev_priv(dev);
+
random_ether_addr(dev->dev_addr);
ether_setup(dev);
dev->netdev_ops = &br_netdev_ops;
dev->destructor = br_dev_free;
SET_ETHTOOL_OPS(dev, &br_ethtool_ops);
+ SET_NETDEV_DEVTYPE(dev, &br_type);
dev->tx_queue_len = 0;
dev->priv_flags = IFF_EBRIDGE;
dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX |
- NETIF_F_NETNS_LOCAL | NETIF_F_GSO | NETIF_F_HW_VLAN_TX;
+ NETIF_F_NETNS_LOCAL | NETIF_F_HW_VLAN_TX;
+ dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
+ NETIF_F_GSO_MASK | NETIF_F_NO_CSUM |
+ NETIF_F_HW_VLAN_TX;
+
+ br->dev = dev;
+ spin_lock_init(&br->lock);
+ INIT_LIST_HEAD(&br->port_list);
+ spin_lock_init(&br->hash_lock);
+
+ br->bridge_id.prio[0] = 0x80;
+ br->bridge_id.prio[1] = 0x00;
+
+ memcpy(br->group_addr, br_group_address, ETH_ALEN);
+
+ br->stp_enabled = BR_NO_STP;
+ br->designated_root = br->bridge_id;
+ br->bridge_max_age = br->max_age = 20 * HZ;
+ br->bridge_hello_time = br->hello_time = 2 * HZ;
+ br->bridge_forward_delay = br->forward_delay = 15 * HZ;
+ br->ageing_time = 300 * HZ;
+
+ br_netfilter_rtable_init(br);
+ br_stp_timer_init(br);
+ br_multicast_init(br);
}
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index cc4d3c5ab1c..e0dfbc151dd 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -28,6 +28,7 @@
static struct kmem_cache *br_fdb_cache __read_mostly;
static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
const unsigned char *addr);
+static void fdb_notify(const struct net_bridge_fdb_entry *, int);
static u32 fdb_salt __read_mostly;
@@ -62,7 +63,7 @@ static inline int has_expired(const struct net_bridge *br,
const struct net_bridge_fdb_entry *fdb)
{
return !fdb->is_static &&
- time_before_eq(fdb->ageing_timer + hold_time(br), jiffies);
+ time_before_eq(fdb->updated + hold_time(br), jiffies);
}
static inline int br_mac_hash(const unsigned char *mac)
@@ -81,6 +82,7 @@ static void fdb_rcu_free(struct rcu_head *head)
static inline void fdb_delete(struct net_bridge_fdb_entry *f)
{
+ fdb_notify(f, RTM_DELNEIGH);
hlist_del_rcu(&f->hlist);
call_rcu(&f->rcu, fdb_rcu_free);
}
@@ -140,7 +142,7 @@ void br_fdb_cleanup(unsigned long _data)
unsigned long this_timer;
if (f->is_static)
continue;
- this_timer = f->ageing_timer + delay;
+ this_timer = f->updated + delay;
if (time_before_eq(this_timer, jiffies))
fdb_delete(f);
else if (time_before(this_timer, next_timer))
@@ -293,7 +295,7 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf,
fe->is_local = f->is_local;
if (!f->is_static)
- fe->ageing_timer_value = jiffies_to_clock_t(jiffies - f->ageing_timer);
+ fe->ageing_timer_value = jiffies_to_clock_t(jiffies - f->updated);
++fe;
++num;
}
@@ -305,8 +307,21 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf,
return num;
}
-static inline struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head,
- const unsigned char *addr)
+static struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head,
+ const unsigned char *addr)
+{
+ struct hlist_node *h;
+ struct net_bridge_fdb_entry *fdb;
+
+ hlist_for_each_entry(fdb, h, head, hlist) {
+ if (!compare_ether_addr(fdb->addr.addr, addr))
+ return fdb;
+ }
+ return NULL;
+}
+
+static struct net_bridge_fdb_entry *fdb_find_rcu(struct hlist_head *head,
+ const unsigned char *addr)
{
struct hlist_node *h;
struct net_bridge_fdb_entry *fdb;
@@ -320,8 +335,7 @@ static inline struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head,
static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head,
struct net_bridge_port *source,
- const unsigned char *addr,
- int is_local)
+ const unsigned char *addr)
{
struct net_bridge_fdb_entry *fdb;
@@ -329,11 +343,11 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head,
if (fdb) {
memcpy(fdb->addr.addr, addr, ETH_ALEN);
fdb->dst = source;
- fdb->is_local = is_local;
- fdb->is_static = is_local;
- fdb->ageing_timer = jiffies;
-
+ fdb->is_local = 0;
+ fdb->is_static = 0;
+ fdb->updated = fdb->used = jiffies;
hlist_add_head_rcu(&fdb->hlist, head);
+ fdb_notify(fdb, RTM_NEWNEIGH);
}
return fdb;
}
@@ -360,12 +374,15 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
fdb_delete(fdb);
}
- if (!fdb_create(head, source, addr, 1))
+ fdb = fdb_create(head, source, addr);
+ if (!fdb)
return -ENOMEM;
+ fdb->is_local = fdb->is_static = 1;
return 0;
}
+/* Add entry for local address of interface */
int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
const unsigned char *addr)
{
@@ -392,7 +409,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
source->state == BR_STATE_FORWARDING))
return;
- fdb = fdb_find(head, addr);
+ fdb = fdb_find_rcu(head, addr);
if (likely(fdb)) {
/* attempt to update an entry for a local interface */
if (unlikely(fdb->is_local)) {
@@ -403,15 +420,277 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
} else {
/* fastpath: update of existing entry */
fdb->dst = source;
- fdb->ageing_timer = jiffies;
+ fdb->updated = jiffies;
}
} else {
spin_lock(&br->hash_lock);
- if (!fdb_find(head, addr))
- fdb_create(head, source, addr, 0);
+ if (likely(!fdb_find(head, addr)))
+ fdb_create(head, source, addr);
+
/* else we lose race and someone else inserts
* it first, don't bother updating
*/
spin_unlock(&br->hash_lock);
}
}
+
+static int fdb_to_nud(const struct net_bridge_fdb_entry *fdb)
+{
+ if (fdb->is_local)
+ return NUD_PERMANENT;
+ else if (fdb->is_static)
+ return NUD_NOARP;
+ else if (has_expired(fdb->dst->br, fdb))
+ return NUD_STALE;
+ else
+ return NUD_REACHABLE;
+}
+
+static int fdb_fill_info(struct sk_buff *skb,
+ const struct net_bridge_fdb_entry *fdb,
+ u32 pid, u32 seq, int type, unsigned int flags)
+{
+ unsigned long now = jiffies;
+ struct nda_cacheinfo ci;
+ struct nlmsghdr *nlh;
+ struct ndmsg *ndm;
+
+ nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags);
+ if (nlh == NULL)
+ return -EMSGSIZE;
+
+
+ ndm = nlmsg_data(nlh);
+ ndm->ndm_family = AF_BRIDGE;
+ ndm->ndm_pad1 = 0;
+ ndm->ndm_pad2 = 0;
+ ndm->ndm_flags = 0;
+ ndm->ndm_type = 0;
+ ndm->ndm_ifindex = fdb->dst->dev->ifindex;
+ ndm->ndm_state = fdb_to_nud(fdb);
+
+ NLA_PUT(skb, NDA_LLADDR, ETH_ALEN, &fdb->addr);
+
+ ci.ndm_used = jiffies_to_clock_t(now - fdb->used);
+ ci.ndm_confirmed = 0;
+ ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated);
+ ci.ndm_refcnt = 0;
+ NLA_PUT(skb, NDA_CACHEINFO, sizeof(ci), &ci);
+
+ return nlmsg_end(skb, nlh);
+
+nla_put_failure:
+ nlmsg_cancel(skb, nlh);
+ return -EMSGSIZE;
+}
+
+static inline size_t fdb_nlmsg_size(void)
+{
+ return NLMSG_ALIGN(sizeof(struct ndmsg))
+ + nla_total_size(ETH_ALEN) /* NDA_LLADDR */
+ + nla_total_size(sizeof(struct nda_cacheinfo));
+}
+
+static void fdb_notify(const struct net_bridge_fdb_entry *fdb, int type)
+{
+ struct net *net = dev_net(fdb->dst->dev);
+ struct sk_buff *skb;
+ int err = -ENOBUFS;
+
+ skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC);
+ if (skb == NULL)
+ goto errout;
+
+ err = fdb_fill_info(skb, fdb, 0, 0, type, 0);
+ if (err < 0) {
+ /* -EMSGSIZE implies BUG in fdb_nlmsg_size() */
+ WARN_ON(err == -EMSGSIZE);
+ kfree_skb(skb);
+ goto errout;
+ }
+ rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
+ return;
+errout:
+ if (err < 0)
+ rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
+}
+
+/* Dump information about entries, in response to GETNEIGH */
+int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ struct net *net = sock_net(skb->sk);
+ struct net_device *dev;
+ int idx = 0;
+
+ rcu_read_lock();
+ for_each_netdev_rcu(net, dev) {
+ struct net_bridge *br = netdev_priv(dev);
+ int i;
+
+ if (!(dev->priv_flags & IFF_EBRIDGE))
+ continue;
+
+ for (i = 0; i < BR_HASH_SIZE; i++) {
+ struct hlist_node *h;
+ struct net_bridge_fdb_entry *f;
+
+ hlist_for_each_entry_rcu(f, h, &br->hash[i], hlist) {
+ if (idx < cb->args[0])
+ goto skip;
+
+ if (fdb_fill_info(skb, f,
+ NETLINK_CB(cb->skb).pid,
+ cb->nlh->nlmsg_seq,
+ RTM_NEWNEIGH,
+ NLM_F_MULTI) < 0)
+ break;
+skip:
+ ++idx;
+ }
+ }
+ }
+ rcu_read_unlock();
+
+ cb->args[0] = idx;
+
+ return skb->len;
+}
+
+/* Create new static fdb entry */
+static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr,
+ __u16 state)
+{
+ struct net_bridge *br = source->br;
+ struct hlist_head *head = &br->hash[br_mac_hash(addr)];
+ struct net_bridge_fdb_entry *fdb;
+
+ fdb = fdb_find(head, addr);
+ if (fdb)
+ return -EEXIST;
+
+ fdb = fdb_create(head, source, addr);
+ if (!fdb)
+ return -ENOMEM;
+
+ if (state & NUD_PERMANENT)
+ fdb->is_local = fdb->is_static = 1;
+ else if (state & NUD_NOARP)
+ fdb->is_static = 1;
+ return 0;
+}
+
+/* Add new permanent fdb entry with RTM_NEWNEIGH */
+int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+{
+ struct net *net = sock_net(skb->sk);
+ struct ndmsg *ndm;
+ struct nlattr *tb[NDA_MAX+1];
+ struct net_device *dev;
+ struct net_bridge_port *p;
+ const __u8 *addr;
+ int err;
+
+ ASSERT_RTNL();
+ err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
+ if (err < 0)
+ return err;
+
+ ndm = nlmsg_data(nlh);
+ if (ndm->ndm_ifindex == 0) {
+ pr_info("bridge: RTM_NEWNEIGH with invalid ifindex\n");
+ return -EINVAL;
+ }
+
+ dev = __dev_get_by_index(net, ndm->ndm_ifindex);
+ if (dev == NULL) {
+ pr_info("bridge: RTM_NEWNEIGH with unknown ifindex\n");
+ return -ENODEV;
+ }
+
+ if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) {
+ pr_info("bridge: RTM_NEWNEIGH with invalid address\n");
+ return -EINVAL;
+ }
+
+ addr = nla_data(tb[NDA_LLADDR]);
+ if (!is_valid_ether_addr(addr)) {
+ pr_info("bridge: RTM_NEWNEIGH with invalid ether address\n");
+ return -EINVAL;
+ }
+
+ p = br_port_get_rtnl(dev);
+ if (p == NULL) {
+ pr_info("bridge: RTM_NEWNEIGH %s not a bridge port\n",
+ dev->name);
+ return -EINVAL;
+ }
+
+ spin_lock_bh(&p->br->hash_lock);
+ err = fdb_add_entry(p, addr, ndm->ndm_state);
+ spin_unlock_bh(&p->br->hash_lock);
+
+ return err;
+}
+
+static int fdb_delete_by_addr(struct net_bridge_port *p, const u8 *addr)
+{
+ struct net_bridge *br = p->br;
+ struct hlist_head *head = &br->hash[br_mac_hash(addr)];
+ struct net_bridge_fdb_entry *fdb;
+
+ fdb = fdb_find(head, addr);
+ if (!fdb)
+ return -ENOENT;
+
+ fdb_delete(fdb);
+ return 0;
+}
+
+/* Remove neighbor entry with RTM_DELNEIGH */
+int br_fdb_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+{
+ struct net *net = sock_net(skb->sk);
+ struct ndmsg *ndm;
+ struct net_bridge_port *p;
+ struct nlattr *llattr;
+ const __u8 *addr;
+ struct net_device *dev;
+ int err;
+
+ ASSERT_RTNL();
+ if (nlmsg_len(nlh) < sizeof(*ndm))
+ return -EINVAL;
+
+ ndm = nlmsg_data(nlh);
+ if (ndm->ndm_ifindex == 0) {
+ pr_info("bridge: RTM_DELNEIGH with invalid ifindex\n");
+ return -EINVAL;
+ }
+
+ dev = __dev_get_by_index(net, ndm->ndm_ifindex);
+ if (dev == NULL) {
+ pr_info("bridge: RTM_DELNEIGH with unknown ifindex\n");
+ return -ENODEV;
+ }
+
+ llattr = nlmsg_find_attr(nlh, sizeof(*ndm), NDA_LLADDR);
+ if (llattr == NULL || nla_len(llattr) != ETH_ALEN) {
+ pr_info("bridge: RTM_DELNEIGH with invalid address\n");
+ return -EINVAL;
+ }
+
+ addr = nla_data(llattr);
+
+ p = br_port_get_rtnl(dev);
+ if (p == NULL) {
+ pr_info("bridge: RTM_DELNEIGH %s not a bridge port\n",
+ dev->name);
+ return -EINVAL;
+ }
+
+ spin_lock_bh(&p->br->hash_lock);
+ err = fdb_delete_by_addr(p, addr);
+ spin_unlock_bh(&p->br->hash_lock);
+
+ return err;
+}
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 718b60366df..5dbdfdfc3a3 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -36,8 +36,8 @@ static int port_cost(struct net_device *dev)
if (dev->ethtool_ops && dev->ethtool_ops->get_settings) {
struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET, };
- if (!dev->ethtool_ops->get_settings(dev, &ecmd)) {
- switch(ecmd.speed) {
+ if (!dev_ethtool_get_settings(dev, &ecmd)) {
+ switch (ethtool_cmd_speed(&ecmd)) {
case SPEED_10000:
return 2;
case SPEED_1000:
@@ -175,56 +175,6 @@ static void del_br(struct net_bridge *br, struct list_head *head)
unregister_netdevice_queue(br->dev, head);
}
-static struct net_device *new_bridge_dev(struct net *net, const char *name)
-{
- struct net_bridge *br;
- struct net_device *dev;
-
- dev = alloc_netdev(sizeof(struct net_bridge), name,
- br_dev_setup);
-
- if (!dev)
- return NULL;
- dev_net_set(dev, net);
-
- br = netdev_priv(dev);
- br->dev = dev;
-
- br->stats = alloc_percpu(struct br_cpu_netstats);
- if (!br->stats) {
- free_netdev(dev);
- return NULL;
- }
-
- spin_lock_init(&br->lock);
- INIT_LIST_HEAD(&br->port_list);
- spin_lock_init(&br->hash_lock);
-
- br->bridge_id.prio[0] = 0x80;
- br->bridge_id.prio[1] = 0x00;
-
- memcpy(br->group_addr, br_group_address, ETH_ALEN);
-
- br->feature_mask = dev->features;
- br->stp_enabled = BR_NO_STP;
- br->designated_root = br->bridge_id;
- br->root_path_cost = 0;
- br->root_port = 0;
- br->bridge_max_age = br->max_age = 20 * HZ;
- br->bridge_hello_time = br->hello_time = 2 * HZ;
- br->bridge_forward_delay = br->forward_delay = 15 * HZ;
- br->topology_change = 0;
- br->topology_change_detected = 0;
- br->ageing_time = 300 * HZ;
-
- br_netfilter_rtable_init(br);
-
- br_stp_timer_init(br);
- br_multicast_init(br);
-
- return dev;
-}
-
/* find an available port number */
static int find_portno(struct net_bridge *br)
{
@@ -277,42 +227,19 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
return p;
}
-static struct device_type br_type = {
- .name = "bridge",
-};
-
int br_add_bridge(struct net *net, const char *name)
{
struct net_device *dev;
- int ret;
- dev = new_bridge_dev(net, name);
+ dev = alloc_netdev(sizeof(struct net_bridge), name,
+ br_dev_setup);
+
if (!dev)
return -ENOMEM;
- rtnl_lock();
- if (strchr(dev->name, '%')) {
- ret = dev_alloc_name(dev, dev->name);
- if (ret < 0)
- goto out_free;
- }
-
- SET_NETDEV_DEVTYPE(dev, &br_type);
-
- ret = register_netdevice(dev);
- if (ret)
- goto out_free;
-
- ret = br_sysfs_addbr(dev);
- if (ret)
- unregister_netdevice(dev);
- out:
- rtnl_unlock();
- return ret;
+ dev_net_set(dev, net);
-out_free:
- free_netdev(dev);
- goto out;
+ return register_netdev(dev);
}
int br_del_bridge(struct net *net, const char *name)
@@ -364,15 +291,15 @@ int br_min_mtu(const struct net_bridge *br)
/*
* Recomputes features using slave's features
*/
-void br_features_recompute(struct net_bridge *br)
+u32 br_features_recompute(struct net_bridge *br, u32 features)
{
struct net_bridge_port *p;
- u32 features, mask;
+ u32 mask;
- features = mask = br->feature_mask;
if (list_empty(&br->port_list))
- goto done;
+ return features;
+ mask = features;
features &= ~NETIF_F_ONE_FOR_ALL;
list_for_each_entry(p, &br->port_list, list) {
@@ -380,8 +307,7 @@ void br_features_recompute(struct net_bridge *br)
p->dev->features, mask);
}
-done:
- br->dev->features = netdev_fix_features(br->dev, features);
+ return features;
}
/* called with RTNL */
@@ -446,9 +372,10 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
list_add_rcu(&p->list, &br->port_list);
+ netdev_update_features(br->dev);
+
spin_lock_bh(&br->lock);
changed_addr = br_stp_recalculate_bridge_id(br);
- br_features_recompute(br);
if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) &&
(br->dev->flags & IFF_UP))
@@ -496,9 +423,10 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
spin_lock_bh(&br->lock);
br_stp_recalculate_bridge_id(br);
- br_features_recompute(br);
spin_unlock_bh(&br->lock);
+ netdev_update_features(br->dev);
+
return 0;
}
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 0c7badad62a..f3ac1e858ee 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -98,9 +98,10 @@ int br_handle_frame_finish(struct sk_buff *skb)
}
if (skb) {
- if (dst)
+ if (dst) {
+ dst->used = jiffies;
br_forward(dst->dst, skb, skb2);
- else
+ } else
br_flood_forward(br, skb, skb2);
}
diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c
index 3d9fca0e337..7222fe1d546 100644
--- a/net/bridge/br_ioctl.c
+++ b/net/bridge/br_ioctl.c
@@ -181,40 +181,19 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- spin_lock_bh(&br->lock);
- br->bridge_forward_delay = clock_t_to_jiffies(args[1]);
- if (br_is_root_bridge(br))
- br->forward_delay = br->bridge_forward_delay;
- spin_unlock_bh(&br->lock);
- return 0;
+ return br_set_forward_delay(br, args[1]);
case BRCTL_SET_BRIDGE_HELLO_TIME:
- {
- unsigned long t = clock_t_to_jiffies(args[1]);
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if (t < HZ)
- return -EINVAL;
-
- spin_lock_bh(&br->lock);
- br->bridge_hello_time = t;
- if (br_is_root_bridge(br))
- br->hello_time = br->bridge_hello_time;
- spin_unlock_bh(&br->lock);
- return 0;
- }
+ return br_set_hello_time(br, args[1]);
case BRCTL_SET_BRIDGE_MAX_AGE:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- spin_lock_bh(&br->lock);
- br->bridge_max_age = clock_t_to_jiffies(args[1]);
- if (br_is_root_bridge(br))
- br->max_age = br->bridge_max_age;
- spin_unlock_bh(&br->lock);
- return 0;
+ return br_set_max_age(br, args[1]);
case BRCTL_SET_AGEING_TIME:
if (!capable(CAP_NET_ADMIN))
@@ -275,19 +254,16 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
case BRCTL_SET_PORT_PRIORITY:
{
struct net_bridge_port *p;
- int ret = 0;
+ int ret;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if (args[2] >= (1<<(16-BR_PORT_BITS)))
- return -ERANGE;
-
spin_lock_bh(&br->lock);
if ((p = br_get_port(br, args[1])) == NULL)
ret = -EINVAL;
else
- br_stp_set_port_priority(p, args[2]);
+ ret = br_stp_set_port_priority(p, args[2]);
spin_unlock_bh(&br->lock);
return ret;
}
@@ -295,15 +271,17 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
case BRCTL_SET_PATH_COST:
{
struct net_bridge_port *p;
- int ret = 0;
+ int ret;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
+ spin_lock_bh(&br->lock);
if ((p = br_get_port(br, args[1])) == NULL)
ret = -EINVAL;
else
- br_stp_set_path_cost(p, args[2]);
+ ret = br_stp_set_path_cost(p, args[2]);
+ spin_unlock_bh(&br->lock);
return ret;
}
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 59660c909a7..2f14eafdeea 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -413,7 +413,7 @@ out:
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br,
- struct in6_addr *group)
+ const struct in6_addr *group)
{
struct sk_buff *skb;
struct ipv6hdr *ip6h;
@@ -1115,7 +1115,7 @@ static int br_ip4_multicast_query(struct net_bridge *br,
struct net_bridge_port *port,
struct sk_buff *skb)
{
- struct iphdr *iph = ip_hdr(skb);
+ const struct iphdr *iph = ip_hdr(skb);
struct igmphdr *ih = igmp_hdr(skb);
struct net_bridge_mdb_entry *mp;
struct igmpv3_query *ih3;
@@ -1190,7 +1190,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
struct net_bridge_port *port,
struct sk_buff *skb)
{
- struct ipv6hdr *ip6h = ipv6_hdr(skb);
+ const struct ipv6hdr *ip6h = ipv6_hdr(skb);
struct mld_msg *mld = (struct mld_msg *) icmp6_hdr(skb);
struct net_bridge_mdb_entry *mp;
struct mld2_query *mld2q;
@@ -1198,7 +1198,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
struct net_bridge_port_group __rcu **pp;
unsigned long max_delay;
unsigned long now = jiffies;
- struct in6_addr *group = NULL;
+ const struct in6_addr *group = NULL;
int err = 0;
spin_lock(&br->multicast_lock);
@@ -1356,7 +1356,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
struct sk_buff *skb)
{
struct sk_buff *skb2 = skb;
- struct iphdr *iph;
+ const struct iphdr *iph;
struct igmphdr *ih;
unsigned len;
unsigned offset;
@@ -1452,7 +1452,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
struct sk_buff *skb)
{
struct sk_buff *skb2;
- struct ipv6hdr *ip6h;
+ const struct ipv6hdr *ip6h;
struct icmp6hdr *icmp6h;
u8 nexthdr;
unsigned len;
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 74ef4d4846a..e1f5ec75e91 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -219,7 +219,7 @@ static inline void nf_bridge_update_protocol(struct sk_buff *skb)
static int br_parse_ip_options(struct sk_buff *skb)
{
struct ip_options *opt;
- struct iphdr *iph;
+ const struct iphdr *iph;
struct net_device *dev = skb->dev;
u32 len;
@@ -554,7 +554,7 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- struct ipv6hdr *hdr;
+ const struct ipv6hdr *hdr;
u32 pkt_len;
if (skb->len < sizeof(struct ipv6hdr))
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index f8bf4c7f842..ffb0dc4cc0e 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -12,9 +12,11 @@
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/etherdevice.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)
@@ -118,8 +120,9 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
int idx;
idx = 0;
- for_each_netdev(net, dev) {
- struct net_bridge_port *port = br_port_get_rtnl(dev);
+ rcu_read_lock();
+ for_each_netdev_rcu(net, dev) {
+ struct net_bridge_port *port = br_port_get_rcu(dev);
/* not a bridge port */
if (!port || idx < cb->args[0])
@@ -133,7 +136,7 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
skip:
++idx;
}
-
+ rcu_read_unlock();
cb->args[0] = idx;
return skb->len;
@@ -188,20 +191,61 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
return 0;
}
+static int br_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+ if (tb[IFLA_ADDRESS]) {
+ if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
+ return -EINVAL;
+ if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
+ return -EADDRNOTAVAIL;
+ }
+
+ return 0;
+}
+
+static struct rtnl_link_ops br_link_ops __read_mostly = {
+ .kind = "bridge",
+ .priv_size = sizeof(struct net_bridge),
+ .setup = br_dev_setup,
+ .validate = br_validate,
+};
int __init br_netlink_init(void)
{
- if (__rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, br_dump_ifinfo))
- return -ENOBUFS;
+ int err;
- /* Only the first call to __rtnl_register can fail */
- __rtnl_register(PF_BRIDGE, RTM_SETLINK, br_rtm_setlink, NULL);
+ err = rtnl_link_register(&br_link_ops);
+ if (err < 0)
+ goto err1;
+
+ err = __rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, br_dump_ifinfo);
+ if (err)
+ goto err2;
+ err = __rtnl_register(PF_BRIDGE, RTM_SETLINK, br_rtm_setlink, NULL);
+ if (err)
+ goto err3;
+ err = __rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, br_fdb_add, NULL);
+ if (err)
+ goto err3;
+ err = __rtnl_register(PF_BRIDGE, RTM_DELNEIGH, br_fdb_delete, NULL);
+ if (err)
+ goto err3;
+ err = __rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, br_fdb_dump);
+ if (err)
+ goto err3;
return 0;
+
+err3:
+ rtnl_unregister_all(PF_BRIDGE);
+err2:
+ rtnl_link_unregister(&br_link_ops);
+err1:
+ return err;
}
void __exit br_netlink_fini(void)
{
+ rtnl_link_unregister(&br_link_ops);
rtnl_unregister_all(PF_BRIDGE);
}
-
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index 7d337c9b608..6545ee9591d 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -36,6 +36,12 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
struct net_bridge *br;
int err;
+ /* register of bridge completed, add sysfs entries */
+ if ((dev->priv_flags & IFF_EBRIDGE) && event == NETDEV_REGISTER) {
+ br_sysfs_addbr(dev);
+ return NOTIFY_DONE;
+ }
+
/* not a port of a bridge */
p = br_port_get_rtnl(dev);
if (!p)
@@ -60,10 +66,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
break;
case NETDEV_FEAT_CHANGE:
- spin_lock_bh(&br->lock);
- if (netif_running(br->dev))
- br_features_recompute(br);
- spin_unlock_bh(&br->lock);
+ netdev_update_features(br->dev);
break;
case NETDEV_DOWN:
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 387013d3374..54578f274d8 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -64,7 +64,8 @@ struct net_bridge_fdb_entry
struct net_bridge_port *dst;
struct rcu_head rcu;
- unsigned long ageing_timer;
+ unsigned long updated;
+ unsigned long used;
mac_addr addr;
unsigned char is_local;
unsigned char is_static;
@@ -182,7 +183,6 @@ struct net_bridge
struct br_cpu_netstats __percpu *stats;
spinlock_t hash_lock;
struct hlist_head hash[BR_HASH_SIZE];
- u32 feature_mask;
#ifdef CONFIG_BRIDGE_NETFILTER
struct rtable fake_rtable;
bool nf_call_iptables;
@@ -353,6 +353,9 @@ extern int br_fdb_insert(struct net_bridge *br,
extern void br_fdb_update(struct net_bridge *br,
struct net_bridge_port *source,
const unsigned char *addr);
+extern int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb);
+extern int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
+extern int br_fdb_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
/* br_forward.c */
extern void br_deliver(const struct net_bridge_port *to,
@@ -375,7 +378,7 @@ extern int br_add_if(struct net_bridge *br,
extern int br_del_if(struct net_bridge *br,
struct net_device *dev);
extern int br_min_mtu(const struct net_bridge *br);
-extern void br_features_recompute(struct net_bridge *br);
+extern u32 br_features_recompute(struct net_bridge *br, u32 features);
/* br_input.c */
extern int br_handle_frame_finish(struct sk_buff *skb);
@@ -491,6 +494,11 @@ extern struct net_bridge_port *br_get_port(struct net_bridge *br,
extern void br_init_port(struct net_bridge_port *p);
extern void br_become_designated_port(struct net_bridge_port *p);
+extern int br_set_forward_delay(struct net_bridge *br, unsigned long x);
+extern int br_set_hello_time(struct net_bridge *br, unsigned long x);
+extern int br_set_max_age(struct net_bridge *br, unsigned long x);
+
+
/* br_stp_if.c */
extern void br_stp_enable_bridge(struct net_bridge *br);
extern void br_stp_disable_bridge(struct net_bridge *br);
@@ -501,10 +509,10 @@ extern bool br_stp_recalculate_bridge_id(struct net_bridge *br);
extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a);
extern void br_stp_set_bridge_priority(struct net_bridge *br,
u16 newprio);
-extern void br_stp_set_port_priority(struct net_bridge_port *p,
- u8 newprio);
-extern void br_stp_set_path_cost(struct net_bridge_port *p,
- u32 path_cost);
+extern int br_stp_set_port_priority(struct net_bridge_port *p,
+ unsigned long newprio);
+extern int br_stp_set_path_cost(struct net_bridge_port *p,
+ unsigned long path_cost);
extern ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id);
/* br_stp_bpdu.c */
diff --git a/net/bridge/br_private_stp.h b/net/bridge/br_private_stp.h
index 8b650f7fbfa..642ef47a867 100644
--- a/net/bridge/br_private_stp.h
+++ b/net/bridge/br_private_stp.h
@@ -16,6 +16,19 @@
#define BPDU_TYPE_CONFIG 0
#define BPDU_TYPE_TCN 0x80
+/* IEEE 802.1D-1998 timer values */
+#define BR_MIN_HELLO_TIME (1*HZ)
+#define BR_MAX_HELLO_TIME (10*HZ)
+
+#define BR_MIN_FORWARD_DELAY (2*HZ)
+#define BR_MAX_FORWARD_DELAY (30*HZ)
+
+#define BR_MIN_MAX_AGE (6*HZ)
+#define BR_MAX_MAX_AGE (40*HZ)
+
+#define BR_MIN_PATH_COST 1
+#define BR_MAX_PATH_COST 65535
+
struct br_config_bpdu
{
unsigned topology_change:1;
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index 7370d14f634..bb4383e84de 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -484,3 +484,51 @@ void br_received_tcn_bpdu(struct net_bridge_port *p)
br_topology_change_acknowledge(p);
}
}
+
+/* Change bridge STP parameter */
+int br_set_hello_time(struct net_bridge *br, unsigned long val)
+{
+ unsigned long t = clock_t_to_jiffies(val);
+
+ if (t < BR_MIN_HELLO_TIME || t > BR_MAX_HELLO_TIME)
+ return -ERANGE;
+
+ spin_lock_bh(&br->lock);
+ br->bridge_hello_time = t;
+ if (br_is_root_bridge(br))
+ br->hello_time = br->bridge_hello_time;
+ spin_unlock_bh(&br->lock);
+ return 0;
+}
+
+int br_set_max_age(struct net_bridge *br, unsigned long val)
+{
+ unsigned long t = clock_t_to_jiffies(val);
+
+ if (t < BR_MIN_MAX_AGE || t > BR_MAX_MAX_AGE)
+ return -ERANGE;
+
+ spin_lock_bh(&br->lock);
+ br->bridge_max_age = t;
+ if (br_is_root_bridge(br))
+ br->max_age = br->bridge_max_age;
+ spin_unlock_bh(&br->lock);
+ return 0;
+
+}
+
+int br_set_forward_delay(struct net_bridge *br, unsigned long val)
+{
+ unsigned long t = clock_t_to_jiffies(val);
+
+ if (br->stp_enabled != BR_NO_STP &&
+ (t < BR_MIN_FORWARD_DELAY || t > BR_MAX_FORWARD_DELAY))
+ return -ERANGE;
+
+ spin_lock_bh(&br->lock);
+ br->bridge_forward_delay = t;
+ if (br_is_root_bridge(br))
+ br->forward_delay = br->bridge_forward_delay;
+ spin_unlock_bh(&br->lock);
+ return 0;
+}
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 9b61d09de9b..6f615b8192f 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -20,7 +20,7 @@
/* Port id is composed of priority and port number.
- * NB: least significant bits of priority are dropped to
+ * NB: some bits of priority are dropped to
* make room for more ports.
*/
static inline port_id br_make_port_id(__u8 priority, __u16 port_no)
@@ -29,6 +29,8 @@ static inline port_id br_make_port_id(__u8 priority, __u16 port_no)
| (port_no & ((1<<BR_PORT_BITS)-1));
}
+#define BR_MAX_PORT_PRIORITY ((u16)~0 >> BR_PORT_BITS)
+
/* called under bridge lock */
void br_init_port(struct net_bridge_port *p)
{
@@ -255,10 +257,14 @@ void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio)
}
/* called under bridge lock */
-void br_stp_set_port_priority(struct net_bridge_port *p, u8 newprio)
+int br_stp_set_port_priority(struct net_bridge_port *p, unsigned long newprio)
{
- port_id new_port_id = br_make_port_id(newprio, p->port_no);
+ port_id new_port_id;
+
+ if (newprio > BR_MAX_PORT_PRIORITY)
+ return -ERANGE;
+ new_port_id = br_make_port_id(newprio, p->port_no);
if (br_is_designated_port(p))
p->designated_port = new_port_id;
@@ -269,14 +275,21 @@ void br_stp_set_port_priority(struct net_bridge_port *p, u8 newprio)
br_become_designated_port(p);
br_port_state_selection(p->br);
}
+
+ return 0;
}
/* called under bridge lock */
-void br_stp_set_path_cost(struct net_bridge_port *p, u32 path_cost)
+int br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost)
{
+ if (path_cost < BR_MIN_PATH_COST ||
+ path_cost > BR_MAX_PATH_COST)
+ return -ERANGE;
+
p->path_cost = path_cost;
br_configuration_update(p->br);
br_port_state_selection(p->br);
+ return 0;
}
ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id)
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 5c1e5559ebb..68b893ea8c3 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -43,9 +43,7 @@ static ssize_t store_bridge_parm(struct device *d,
if (endp == buf)
return -EINVAL;
- spin_lock_bh(&br->lock);
err = (*set)(br, val);
- spin_unlock_bh(&br->lock);
return err ? err : len;
}
@@ -57,20 +55,11 @@ static ssize_t show_forward_delay(struct device *d,
return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->forward_delay));
}
-static int set_forward_delay(struct net_bridge *br, unsigned long val)
-{
- unsigned long delay = clock_t_to_jiffies(val);
- br->forward_delay = delay;
- if (br_is_root_bridge(br))
- br->bridge_forward_delay = delay;
- return 0;
-}
-
static ssize_t store_forward_delay(struct device *d,
struct device_attribute *attr,
const char *buf, size_t len)
{
- return store_bridge_parm(d, buf, len, set_forward_delay);
+ return store_bridge_parm(d, buf, len, br_set_forward_delay);
}
static DEVICE_ATTR(forward_delay, S_IRUGO | S_IWUSR,
show_forward_delay, store_forward_delay);
@@ -82,24 +71,11 @@ static ssize_t show_hello_time(struct device *d, struct device_attribute *attr,
jiffies_to_clock_t(to_bridge(d)->hello_time));
}
-static int set_hello_time(struct net_bridge *br, unsigned long val)
-{
- unsigned long t = clock_t_to_jiffies(val);
-
- if (t < HZ)
- return -EINVAL;
-
- br->hello_time = t;
- if (br_is_root_bridge(br))
- br->bridge_hello_time = t;
- return 0;
-}
-
static ssize_t store_hello_time(struct device *d,
struct device_attribute *attr, const char *buf,
size_t len)
{
- return store_bridge_parm(d, buf, len, set_hello_time);
+ return store_bridge_parm(d, buf, len, br_set_hello_time);
}
static DEVICE_ATTR(hello_time, S_IRUGO | S_IWUSR, show_hello_time,
store_hello_time);
@@ -111,19 +87,10 @@ static ssize_t show_max_age(struct device *d, struct device_attribute *attr,
jiffies_to_clock_t(to_bridge(d)->max_age));
}
-static int set_max_age(struct net_bridge *br, unsigned long val)
-{
- unsigned long t = clock_t_to_jiffies(val);
- br->max_age = t;
- if (br_is_root_bridge(br))
- br->bridge_max_age = t;
- return 0;
-}
-
static ssize_t store_max_age(struct device *d, struct device_attribute *attr,
const char *buf, size_t len)
{
- return store_bridge_parm(d, buf, len, set_max_age);
+ return store_bridge_parm(d, buf, len, br_set_max_age);
}
static DEVICE_ATTR(max_age, S_IRUGO | S_IWUSR, show_max_age, store_max_age);
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
index fd5799c9bc8..6229b62749e 100644
--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -23,7 +23,7 @@
struct brport_attribute {
struct attribute attr;
ssize_t (*show)(struct net_bridge_port *, char *);
- ssize_t (*store)(struct net_bridge_port *, unsigned long);
+ int (*store)(struct net_bridge_port *, unsigned long);
};
#define BRPORT_ATTR(_name,_mode,_show,_store) \
@@ -38,27 +38,17 @@ static ssize_t show_path_cost(struct net_bridge_port *p, char *buf)
{
return sprintf(buf, "%d\n", p->path_cost);
}
-static ssize_t store_path_cost(struct net_bridge_port *p, unsigned long v)
-{
- br_stp_set_path_cost(p, v);
- return 0;
-}
+
static BRPORT_ATTR(path_cost, S_IRUGO | S_IWUSR,
- show_path_cost, store_path_cost);
+ show_path_cost, br_stp_set_path_cost);
static ssize_t show_priority(struct net_bridge_port *p, char *buf)
{
return sprintf(buf, "%d\n", p->priority);
}
-static ssize_t store_priority(struct net_bridge_port *p, unsigned long v)
-{
- if (v >= (1<<(16-BR_PORT_BITS)))
- return -ERANGE;
- br_stp_set_port_priority(p, v);
- return 0;
-}
+
static BRPORT_ATTR(priority, S_IRUGO | S_IWUSR,
- show_priority, store_priority);
+ show_priority, br_stp_set_port_priority);
static ssize_t show_designated_root(struct net_bridge_port *p, char *buf)
{
@@ -136,7 +126,7 @@ static ssize_t show_hold_timer(struct net_bridge_port *p,
}
static BRPORT_ATTR(hold_timer, S_IRUGO, show_hold_timer, NULL);
-static ssize_t store_flush(struct net_bridge_port *p, unsigned long v)
+static int store_flush(struct net_bridge_port *p, unsigned long v)
{
br_fdb_delete_by_port(p->br, p, 0); // Don't delete local entry
return 0;
@@ -148,7 +138,7 @@ static ssize_t show_hairpin_mode(struct net_bridge_port *p, char *buf)
int hairpin_mode = (p->flags & BR_HAIRPIN_MODE) ? 1 : 0;
return sprintf(buf, "%d\n", hairpin_mode);
}
-static ssize_t store_hairpin_mode(struct net_bridge_port *p, unsigned long v)
+static int store_hairpin_mode(struct net_bridge_port *p, unsigned long v)
{
if (v)
p->flags |= BR_HAIRPIN_MODE;
@@ -165,7 +155,7 @@ static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
return sprintf(buf, "%d\n", p->multicast_router);
}
-static ssize_t store_multicast_router(struct net_bridge_port *p,
+static int store_multicast_router(struct net_bridge_port *p,
unsigned long v)
{
return br_multicast_set_port_router(p, v);
diff --git a/net/caif/Makefile b/net/caif/Makefile
index 9d38e406e4a..ebcd4e7e6f4 100644
--- a/net/caif/Makefile
+++ b/net/caif/Makefile
@@ -5,7 +5,7 @@ caif-y := caif_dev.o \
cffrml.o cfveil.o cfdbgl.o\
cfserl.o cfdgml.o \
cfrfml.o cfvidl.o cfutill.o \
- cfsrvl.o cfpkt_skbuff.o caif_config_util.o
+ cfsrvl.o cfpkt_skbuff.o
obj-$(CONFIG_CAIF) += caif.o
obj-$(CONFIG_CAIF_NETDEV) += chnl_net.o
diff --git a/net/caif/caif_config_util.c b/net/caif/caif_config_util.c
deleted file mode 100644
index d522d8c1703..00000000000
--- a/net/caif/caif_config_util.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland sjur.brandeland@stericsson.com
- * License terms: GNU General Public License (GPL) version 2
- */
-
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <net/caif/cfctrl.h>
-#include <net/caif/cfcnfg.h>
-#include <net/caif/caif_dev.h>
-
-int connect_req_to_link_param(struct cfcnfg *cnfg,
- struct caif_connect_request *s,
- struct cfctrl_link_param *l)
-{
- struct dev_info *dev_info;
- enum cfcnfg_phy_preference pref;
- int res;
-
- memset(l, 0, sizeof(*l));
- /* In caif protocol low value is high priority */
- l->priority = CAIF_PRIO_MAX - s->priority + 1;
-
- if (s->ifindex != 0){
- res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex);
- if (res < 0)
- return res;
- l->phyid = res;
- }
- else {
- switch (s->link_selector) {
- case CAIF_LINK_HIGH_BANDW:
- pref = CFPHYPREF_HIGH_BW;
- break;
- case CAIF_LINK_LOW_LATENCY:
- pref = CFPHYPREF_LOW_LAT;
- break;
- default:
- return -EINVAL;
- }
- dev_info = cfcnfg_get_phyid(cnfg, pref);
- if (dev_info == NULL)
- return -ENODEV;
- l->phyid = dev_info->id;
- }
- switch (s->protocol) {
- case CAIFPROTO_AT:
- l->linktype = CFCTRL_SRV_VEI;
- if (s->sockaddr.u.at.type == CAIF_ATTYPE_PLAIN)
- l->chtype = 0x02;
- else
- l->chtype = s->sockaddr.u.at.type;
- l->endpoint = 0x00;
- break;
- case CAIFPROTO_DATAGRAM:
- l->linktype = CFCTRL_SRV_DATAGRAM;
- l->chtype = 0x00;
- l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
- break;
- case CAIFPROTO_DATAGRAM_LOOP:
- l->linktype = CFCTRL_SRV_DATAGRAM;
- l->chtype = 0x03;
- l->endpoint = 0x00;
- l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
- break;
- case CAIFPROTO_RFM:
- l->linktype = CFCTRL_SRV_RFM;
- l->u.datagram.connid = s->sockaddr.u.rfm.connection_id;
- strncpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume,
- sizeof(l->u.rfm.volume)-1);
- l->u.rfm.volume[sizeof(l->u.rfm.volume)-1] = 0;
- break;
- case CAIFPROTO_UTIL:
- l->linktype = CFCTRL_SRV_UTIL;
- l->endpoint = 0x00;
- l->chtype = 0x00;
- strncpy(l->u.utility.name, s->sockaddr.u.util.service,
- sizeof(l->u.utility.name)-1);
- l->u.utility.name[sizeof(l->u.utility.name)-1] = 0;
- caif_assert(sizeof(l->u.utility.name) > 10);
- l->u.utility.paramlen = s->param.size;
- if (l->u.utility.paramlen > sizeof(l->u.utility.params))
- l->u.utility.paramlen = sizeof(l->u.utility.params);
-
- memcpy(l->u.utility.params, s->param.data,
- l->u.utility.paramlen);
-
- break;
- case CAIFPROTO_DEBUG:
- l->linktype = CFCTRL_SRV_DBG;
- l->endpoint = s->sockaddr.u.dbg.service;
- l->chtype = s->sockaddr.u.dbg.type;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
index a42a408306e..366ca0fb7a2 100644
--- a/net/caif/caif_dev.c
+++ b/net/caif/caif_dev.c
@@ -12,49 +12,51 @@
#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
#include <linux/version.h>
-#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/if_arp.h>
#include <linux/net.h>
#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
+#include <linux/mutex.h>
#include <net/netns/generic.h>
#include <net/net_namespace.h>
#include <net/pkt_sched.h>
#include <net/caif/caif_device.h>
-#include <net/caif/caif_dev.h>
#include <net/caif/caif_layer.h>
#include <net/caif/cfpkt.h>
#include <net/caif/cfcnfg.h>
MODULE_LICENSE("GPL");
-#define TIMEOUT (HZ*5)
/* Used for local tracking of the CAIF net devices */
struct caif_device_entry {
struct cflayer layer;
struct list_head list;
- atomic_t in_use;
- atomic_t state;
- u16 phyid;
struct net_device *netdev;
- wait_queue_head_t event;
+ int __percpu *pcpu_refcnt;
};
struct caif_device_entry_list {
struct list_head list;
/* Protects simulanous deletes in list */
- spinlock_t lock;
+ struct mutex lock;
};
struct caif_net {
+ struct cfcnfg *cfg;
struct caif_device_entry_list caifdevs;
};
static int caif_net_id;
-static struct cfcnfg *cfg;
+
+struct cfcnfg *get_cfcnfg(struct net *net)
+{
+ struct caif_net *caifn;
+ BUG_ON(!net);
+ caifn = net_generic(net, caif_net_id);
+ BUG_ON(!caifn);
+ return caifn->cfg;
+}
+EXPORT_SYMBOL(get_cfcnfg);
static struct caif_device_entry_list *caif_device_list(struct net *net)
{
@@ -65,19 +67,39 @@ static struct caif_device_entry_list *caif_device_list(struct net *net)
return &caifn->caifdevs;
}
+static void caifd_put(struct caif_device_entry *e)
+{
+ irqsafe_cpu_dec(*e->pcpu_refcnt);
+}
+
+static void caifd_hold(struct caif_device_entry *e)
+{
+ irqsafe_cpu_inc(*e->pcpu_refcnt);
+}
+
+static int caifd_refcnt_read(struct caif_device_entry *e)
+{
+ int i, refcnt = 0;
+ for_each_possible_cpu(i)
+ refcnt += *per_cpu_ptr(e->pcpu_refcnt, i);
+ return refcnt;
+}
+
/* Allocate new CAIF device. */
static struct caif_device_entry *caif_device_alloc(struct net_device *dev)
{
struct caif_device_entry_list *caifdevs;
struct caif_device_entry *caifd;
+
caifdevs = caif_device_list(dev_net(dev));
BUG_ON(!caifdevs);
+
caifd = kzalloc(sizeof(*caifd), GFP_ATOMIC);
if (!caifd)
return NULL;
+ caifd->pcpu_refcnt = alloc_percpu(int);
caifd->netdev = dev;
- list_add(&caifd->list, &caifdevs->list);
- init_waitqueue_head(&caifd->event);
+ dev_hold(dev);
return caifd;
}
@@ -87,98 +109,60 @@ static struct caif_device_entry *caif_get(struct net_device *dev)
caif_device_list(dev_net(dev));
struct caif_device_entry *caifd;
BUG_ON(!caifdevs);
- list_for_each_entry(caifd, &caifdevs->list, list) {
+ list_for_each_entry_rcu(caifd, &caifdevs->list, list) {
if (caifd->netdev == dev)
return caifd;
}
return NULL;
}
-static void caif_device_destroy(struct net_device *dev)
-{
- struct caif_device_entry_list *caifdevs =
- caif_device_list(dev_net(dev));
- struct caif_device_entry *caifd;
- ASSERT_RTNL();
- if (dev->type != ARPHRD_CAIF)
- return;
-
- spin_lock_bh(&caifdevs->lock);
- caifd = caif_get(dev);
- if (caifd == NULL) {
- spin_unlock_bh(&caifdevs->lock);
- return;
- }
-
- list_del(&caifd->list);
- spin_unlock_bh(&caifdevs->lock);
-
- kfree(caifd);
-}
-
static int transmit(struct cflayer *layer, struct cfpkt *pkt)
{
+ int err;
struct caif_device_entry *caifd =
container_of(layer, struct caif_device_entry, layer);
- struct sk_buff *skb, *skb2;
- int ret = -EINVAL;
+ struct sk_buff *skb;
+
skb = cfpkt_tonative(pkt);
skb->dev = caifd->netdev;
- /*
- * Don't allow SKB to be destroyed upon error, but signal resend
- * notification to clients. We can't rely on the return value as
- * congestion (NET_XMIT_CN) sometimes drops the packet, sometimes don't.
- */
- if (netif_queue_stopped(caifd->netdev))
- return -EAGAIN;
- skb2 = skb_get(skb);
-
- ret = dev_queue_xmit(skb2);
-
- if (!ret)
- kfree_skb(skb);
- else
- return -EAGAIN;
- return 0;
-}
+ err = dev_queue_xmit(skb);
+ if (err > 0)
+ err = -EIO;
-static int modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl)
-{
- struct caif_device_entry *caifd;
- struct caif_dev_common *caifdev;
- caifd = container_of(layr, struct caif_device_entry, layer);
- caifdev = netdev_priv(caifd->netdev);
- if (ctrl == _CAIF_MODEMCMD_PHYIF_USEFULL) {
- atomic_set(&caifd->in_use, 1);
- wake_up_interruptible(&caifd->event);
-
- } else if (ctrl == _CAIF_MODEMCMD_PHYIF_USELESS) {
- atomic_set(&caifd->in_use, 0);
- wake_up_interruptible(&caifd->event);
- }
- return 0;
+ return err;
}
/*
- * Stuff received packets to associated sockets.
+ * Stuff received packets into the CAIF stack.
* On error, returns non-zero and releases the skb.
*/
static int receive(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pkttype, struct net_device *orig_dev)
{
- struct net *net;
struct cfpkt *pkt;
struct caif_device_entry *caifd;
- net = dev_net(dev);
+
pkt = cfpkt_fromnative(CAIF_DIR_IN, skb);
+
+ rcu_read_lock();
caifd = caif_get(dev);
- if (!caifd || !caifd->layer.up || !caifd->layer.up->receive)
- return NET_RX_DROP;
- if (caifd->layer.up->receive(caifd->layer.up, pkt))
+ if (!caifd || !caifd->layer.up || !caifd->layer.up->receive ||
+ !netif_oper_up(caifd->netdev)) {
+ rcu_read_unlock();
+ kfree_skb(skb);
return NET_RX_DROP;
+ }
+
+ /* Hold reference to netdevice while using CAIF stack */
+ caifd_hold(caifd);
+ rcu_read_unlock();
+
+ caifd->layer.up->receive(caifd->layer.up, pkt);
+ /* Release reference to stack upwards */
+ caifd_put(caifd);
return 0;
}
@@ -189,15 +173,25 @@ static struct packet_type caif_packet_type __read_mostly = {
static void dev_flowctrl(struct net_device *dev, int on)
{
- struct caif_device_entry *caifd = caif_get(dev);
- if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd)
+ struct caif_device_entry *caifd;
+
+ rcu_read_lock();
+
+ caifd = caif_get(dev);
+ if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd) {
+ rcu_read_unlock();
return;
+ }
+
+ caifd_hold(caifd);
+ rcu_read_unlock();
caifd->layer.up->ctrlcmd(caifd->layer.up,
on ?
_CAIF_CTRLCMD_PHYIF_FLOW_ON_IND :
_CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND,
caifd->layer.id);
+ caifd_put(caifd);
}
/* notify Caif of device events */
@@ -208,37 +202,28 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
struct caif_device_entry *caifd = NULL;
struct caif_dev_common *caifdev;
enum cfcnfg_phy_preference pref;
- int res = -EINVAL;
enum cfcnfg_phy_type phy_type;
+ struct cfcnfg *cfg;
+ struct caif_device_entry_list *caifdevs =
+ caif_device_list(dev_net(dev));
if (dev->type != ARPHRD_CAIF)
return 0;
+ cfg = get_cfcnfg(dev_net(dev));
+ if (cfg == NULL)
+ return 0;
+
switch (what) {
case NETDEV_REGISTER:
- netdev_info(dev, "register\n");
caifd = caif_device_alloc(dev);
- if (caifd == NULL)
- break;
+ if (!caifd)
+ return 0;
+
caifdev = netdev_priv(dev);
caifdev->flowctrl = dev_flowctrl;
- atomic_set(&caifd->state, what);
- res = 0;
- break;
- case NETDEV_UP:
- netdev_info(dev, "up\n");
- caifd = caif_get(dev);
- if (caifd == NULL)
- break;
- caifdev = netdev_priv(dev);
- if (atomic_read(&caifd->state) == NETDEV_UP) {
- netdev_info(dev, "already up\n");
- break;
- }
- atomic_set(&caifd->state, what);
caifd->layer.transmit = transmit;
- caifd->layer.modemcmd = modemcmd;
if (caifdev->use_frag)
phy_type = CFPHYTYPE_FRAG;
@@ -256,62 +241,94 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
pref = CFPHYPREF_HIGH_BW;
break;
}
- dev_hold(dev);
- cfcnfg_add_phy_layer(get_caif_conf(),
+ strncpy(caifd->layer.name, dev->name,
+ sizeof(caifd->layer.name) - 1);
+ caifd->layer.name[sizeof(caifd->layer.name) - 1] = 0;
+
+ mutex_lock(&caifdevs->lock);
+ list_add_rcu(&caifd->list, &caifdevs->list);
+
+ cfcnfg_add_phy_layer(cfg,
phy_type,
dev,
&caifd->layer,
- &caifd->phyid,
pref,
caifdev->use_fcs,
caifdev->use_stx);
- strncpy(caifd->layer.name, dev->name,
- sizeof(caifd->layer.name) - 1);
- caifd->layer.name[sizeof(caifd->layer.name) - 1] = 0;
+ mutex_unlock(&caifdevs->lock);
break;
- case NETDEV_GOING_DOWN:
+ case NETDEV_UP:
+ rcu_read_lock();
+
caifd = caif_get(dev);
- if (caifd == NULL)
+ if (caifd == NULL) {
+ rcu_read_unlock();
break;
- netdev_info(dev, "going down\n");
+ }
- if (atomic_read(&caifd->state) == NETDEV_GOING_DOWN ||
- atomic_read(&caifd->state) == NETDEV_DOWN)
- break;
+ cfcnfg_set_phy_state(cfg, &caifd->layer, true);
+ rcu_read_unlock();
- atomic_set(&caifd->state, what);
- if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd)
- return -EINVAL;
- caifd->layer.up->ctrlcmd(caifd->layer.up,
- _CAIF_CTRLCMD_PHYIF_DOWN_IND,
- caifd->layer.id);
- might_sleep();
- res = wait_event_interruptible_timeout(caifd->event,
- atomic_read(&caifd->in_use) == 0,
- TIMEOUT);
break;
case NETDEV_DOWN:
+ rcu_read_lock();
+
caifd = caif_get(dev);
- if (caifd == NULL)
- break;
- netdev_info(dev, "down\n");
- if (atomic_read(&caifd->in_use))
- netdev_warn(dev,
- "Unregistering an active CAIF device\n");
- cfcnfg_del_phy_layer(get_caif_conf(), &caifd->layer);
- dev_put(dev);
- atomic_set(&caifd->state, what);
+ if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd) {
+ rcu_read_unlock();
+ return -EINVAL;
+ }
+
+ cfcnfg_set_phy_state(cfg, &caifd->layer, false);
+ caifd_hold(caifd);
+ rcu_read_unlock();
+
+ caifd->layer.up->ctrlcmd(caifd->layer.up,
+ _CAIF_CTRLCMD_PHYIF_DOWN_IND,
+ caifd->layer.id);
+ caifd_put(caifd);
break;
case NETDEV_UNREGISTER:
+ mutex_lock(&caifdevs->lock);
+
caifd = caif_get(dev);
- if (caifd == NULL)
+ if (caifd == NULL) {
+ mutex_unlock(&caifdevs->lock);
+ break;
+ }
+ list_del_rcu(&caifd->list);
+
+ /*
+ * NETDEV_UNREGISTER is called repeatedly until all reference
+ * counts for the net-device are released. If references to
+ * caifd is taken, simply ignore NETDEV_UNREGISTER and wait for
+ * the next call to NETDEV_UNREGISTER.
+ *
+ * If any packets are in flight down the CAIF Stack,
+ * cfcnfg_del_phy_layer will return nonzero.
+ * If no packets are in flight, the CAIF Stack associated
+ * with the net-device un-registering is freed.
+ */
+
+ if (caifd_refcnt_read(caifd) != 0 ||
+ cfcnfg_del_phy_layer(cfg, &caifd->layer) != 0) {
+
+ pr_info("Wait for device inuse\n");
+ /* Enrole device if CAIF Stack is still in use */
+ list_add_rcu(&caifd->list, &caifdevs->list);
+ mutex_unlock(&caifdevs->lock);
break;
- netdev_info(dev, "unregister\n");
- atomic_set(&caifd->state, what);
- caif_device_destroy(dev);
+ }
+
+ synchronize_rcu();
+ dev_put(caifd->netdev);
+ free_percpu(caifd->pcpu_refcnt);
+ kfree(caifd);
+
+ mutex_unlock(&caifdevs->lock);
break;
}
return 0;
@@ -322,61 +339,60 @@ static struct notifier_block caif_device_notifier = {
.priority = 0,
};
-
-struct cfcnfg *get_caif_conf(void)
-{
- return cfg;
-}
-EXPORT_SYMBOL(get_caif_conf);
-
-int caif_connect_client(struct caif_connect_request *conn_req,
- struct cflayer *client_layer, int *ifindex,
- int *headroom, int *tailroom)
-{
- struct cfctrl_link_param param;
- int ret;
- ret = connect_req_to_link_param(get_caif_conf(), conn_req, &param);
- if (ret)
- return ret;
- /* Hook up the adaptation layer. */
- return cfcnfg_add_adaptation_layer(get_caif_conf(), &param,
- client_layer, ifindex,
- headroom, tailroom);
-}
-EXPORT_SYMBOL(caif_connect_client);
-
-int caif_disconnect_client(struct cflayer *adap_layer)
-{
- return cfcnfg_disconn_adapt_layer(get_caif_conf(), adap_layer);
-}
-EXPORT_SYMBOL(caif_disconnect_client);
-
-void caif_release_client(struct cflayer *adap_layer)
-{
- cfcnfg_release_adap_layer(adap_layer);
-}
-EXPORT_SYMBOL(caif_release_client);
-
/* Per-namespace Caif devices handling */
static int caif_init_net(struct net *net)
{
struct caif_net *caifn = net_generic(net, caif_net_id);
+ BUG_ON(!caifn);
INIT_LIST_HEAD(&caifn->caifdevs.list);
- spin_lock_init(&caifn->caifdevs.lock);
+ mutex_init(&caifn->caifdevs.lock);
+
+ caifn->cfg = cfcnfg_create();
+ if (!caifn->cfg) {
+ pr_warn("can't create cfcnfg\n");
+ return -ENOMEM;
+ }
+
return 0;
}
static void caif_exit_net(struct net *net)
{
- struct net_device *dev;
- int res;
+ struct caif_device_entry *caifd, *tmp;
+ struct caif_device_entry_list *caifdevs =
+ caif_device_list(net);
+ struct cfcnfg *cfg;
+
rtnl_lock();
- for_each_netdev(net, dev) {
- if (dev->type != ARPHRD_CAIF)
- continue;
- res = dev_close(dev);
- caif_device_destroy(dev);
+ mutex_lock(&caifdevs->lock);
+
+ cfg = get_cfcnfg(net);
+ if (cfg == NULL) {
+ mutex_unlock(&caifdevs->lock);
+ return;
}
+
+ list_for_each_entry_safe(caifd, tmp, &caifdevs->list, list) {
+ int i = 0;
+ list_del_rcu(&caifd->list);
+ cfcnfg_set_phy_state(cfg, &caifd->layer, false);
+
+ while (i < 10 &&
+ (caifd_refcnt_read(caifd) != 0 ||
+ cfcnfg_del_phy_layer(cfg, &caifd->layer) != 0)) {
+
+ pr_info("Wait for device inuse\n");
+ msleep(250);
+ i++;
+ }
+ synchronize_rcu();
+ dev_put(caifd->netdev);
+ free_percpu(caifd->pcpu_refcnt);
+ kfree(caifd);
+ }
+ cfcnfg_remove(cfg);
+
+ mutex_unlock(&caifdevs->lock);
rtnl_unlock();
}
@@ -391,32 +407,23 @@ static struct pernet_operations caif_net_ops = {
static int __init caif_device_init(void)
{
int result;
- cfg = cfcnfg_create();
- if (!cfg) {
- pr_warn("can't create cfcnfg\n");
- goto err_cfcnfg_create_failed;
- }
+
result = register_pernet_device(&caif_net_ops);
- if (result) {
- kfree(cfg);
- cfg = NULL;
+ if (result)
return result;
- }
- dev_add_pack(&caif_packet_type);
+
register_netdevice_notifier(&caif_device_notifier);
+ dev_add_pack(&caif_packet_type);
return result;
-err_cfcnfg_create_failed:
- return -ENODEV;
}
static void __exit caif_device_exit(void)
{
- dev_remove_pack(&caif_packet_type);
unregister_pernet_device(&caif_net_ops);
unregister_netdevice_notifier(&caif_device_notifier);
- cfcnfg_remove(cfg);
+ dev_remove_pack(&caif_packet_type);
}
module_init(caif_device_init);
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index 37a4034dfc2..b840395ced1 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -48,6 +48,7 @@ static struct dentry *debugfsdir;
#ifdef CONFIG_DEBUG_FS
struct debug_fs_counter {
atomic_t caif_nr_socks;
+ atomic_t caif_sock_create;
atomic_t num_connect_req;
atomic_t num_connect_resp;
atomic_t num_connect_fail_resp;
@@ -59,11 +60,11 @@ struct debug_fs_counter {
atomic_t num_rx_flow_on;
};
static struct debug_fs_counter cnt;
-#define dbfs_atomic_inc(v) atomic_inc(v)
-#define dbfs_atomic_dec(v) atomic_dec(v)
+#define dbfs_atomic_inc(v) atomic_inc_return(v)
+#define dbfs_atomic_dec(v) atomic_dec_return(v)
#else
-#define dbfs_atomic_inc(v)
-#define dbfs_atomic_dec(v)
+#define dbfs_atomic_inc(v) 0
+#define dbfs_atomic_dec(v) 0
#endif
struct caifsock {
@@ -155,9 +156,10 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
(unsigned)sk->sk_rcvbuf && rx_flow_is_on(cf_sk)) {
- pr_debug("sending flow OFF (queue len = %d %d)\n",
- atomic_read(&cf_sk->sk.sk_rmem_alloc),
- sk_rcvbuf_lowwater(cf_sk));
+ if (net_ratelimit())
+ pr_debug("sending flow OFF (queue len = %d %d)\n",
+ atomic_read(&cf_sk->sk.sk_rmem_alloc),
+ sk_rcvbuf_lowwater(cf_sk));
set_rx_flow_off(cf_sk);
dbfs_atomic_inc(&cnt.num_rx_flow_off);
caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ);
@@ -168,7 +170,8 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
return err;
if (!sk_rmem_schedule(sk, skb->truesize) && rx_flow_is_on(cf_sk)) {
set_rx_flow_off(cf_sk);
- pr_debug("sending flow OFF due to rmem_schedule\n");
+ if (net_ratelimit())
+ pr_debug("sending flow OFF due to rmem_schedule\n");
dbfs_atomic_inc(&cnt.num_rx_flow_off);
caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ);
}
@@ -202,13 +205,25 @@ static int caif_sktrecv_cb(struct cflayer *layr, struct cfpkt *pkt)
skb = cfpkt_tonative(pkt);
if (unlikely(cf_sk->sk.sk_state != CAIF_CONNECTED)) {
- cfpkt_destroy(pkt);
+ kfree_skb(skb);
return 0;
}
caif_queue_rcv_skb(&cf_sk->sk, skb);
return 0;
}
+static void cfsk_hold(struct cflayer *layr)
+{
+ struct caifsock *cf_sk = container_of(layr, struct caifsock, layer);
+ sock_hold(&cf_sk->sk);
+}
+
+static void cfsk_put(struct cflayer *layr)
+{
+ struct caifsock *cf_sk = container_of(layr, struct caifsock, layer);
+ sock_put(&cf_sk->sk);
+}
+
/* Packet Control Callback function called from CAIF */
static void caif_ctrl_cb(struct cflayer *layr,
enum caif_ctrlcmd flow,
@@ -232,6 +247,8 @@ static void caif_ctrl_cb(struct cflayer *layr,
case CAIF_CTRLCMD_INIT_RSP:
/* We're now connected */
+ caif_client_register_refcnt(&cf_sk->layer,
+ cfsk_hold, cfsk_put);
dbfs_atomic_inc(&cnt.num_connect_resp);
cf_sk->sk.sk_state = CAIF_CONNECTED;
set_tx_flow_on(cf_sk);
@@ -242,7 +259,6 @@ static void caif_ctrl_cb(struct cflayer *layr,
/* We're now disconnected */
cf_sk->sk.sk_state = CAIF_DISCONNECTED;
cf_sk->sk.sk_state_change(&cf_sk->sk);
- cfcnfg_release_adap_layer(&cf_sk->layer);
break;
case CAIF_CTRLCMD_INIT_FAIL_RSP:
@@ -519,43 +535,14 @@ static int transmit_skb(struct sk_buff *skb, struct caifsock *cf_sk,
int noblock, long timeo)
{
struct cfpkt *pkt;
- int ret, loopcnt = 0;
pkt = cfpkt_fromnative(CAIF_DIR_OUT, skb);
- memset(cfpkt_info(pkt), 0, sizeof(struct caif_payload_info));
- do {
+ memset(skb->cb, 0, sizeof(struct caif_payload_info));
- ret = -ETIMEDOUT;
+ if (cf_sk->layer.dn == NULL)
+ return -EINVAL;
- /* Slight paranoia, probably not needed. */
- if (unlikely(loopcnt++ > 1000)) {
- pr_warn("transmit retries failed, error = %d\n", ret);
- break;
- }
-
- if (cf_sk->layer.dn != NULL)
- ret = cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt);
- if (likely(ret >= 0))
- break;
- /* if transmit return -EAGAIN, then retry */
- if (noblock && ret == -EAGAIN)
- break;
- timeo = caif_wait_for_flow_on(cf_sk, 0, timeo, &ret);
- if (signal_pending(current)) {
- ret = sock_intr_errno(timeo);
- break;
- }
- if (ret)
- break;
- if (cf_sk->sk.sk_state != CAIF_CONNECTED ||
- sock_flag(&cf_sk->sk, SOCK_DEAD) ||
- (cf_sk->sk.sk_shutdown & RCV_SHUTDOWN)) {
- ret = -EPIPE;
- cf_sk->sk.sk_err = EPIPE;
- break;
- }
- } while (ret == -EAGAIN);
- return ret;
+ return cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt);
}
/* Copied from af_unix:unix_dgram_sendmsg, and adapted to CAIF */
@@ -620,7 +607,9 @@ static int caif_seqpkt_sendmsg(struct kiocb *kiocb, struct socket *sock,
goto err;
ret = transmit_skb(skb, cf_sk, noblock, timeo);
if (ret < 0)
- goto err;
+ /* skb is already freed */
+ return ret;
+
return len;
err:
kfree_skb(skb);
@@ -826,7 +815,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
sk->sk_state == CAIF_DISCONNECTED);
if (sk->sk_shutdown & SHUTDOWN_MASK) {
/* Allow re-connect after SHUTDOWN_IND */
- caif_disconnect_client(&cf_sk->layer);
+ caif_disconnect_client(sock_net(sk), &cf_sk->layer);
break;
}
/* No reconnect on a seqpacket socket */
@@ -852,7 +841,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
sock->state = SS_CONNECTING;
sk->sk_state = CAIF_CONNECTING;
- /* Check priority value coming from socket */
+ /* Check priority value comming from socket */
/* if priority value is out of range it will be ajusted */
if (cf_sk->sk.sk_priority > CAIF_PRIO_MAX)
cf_sk->conn_req.priority = CAIF_PRIO_MAX;
@@ -866,8 +855,10 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
dbfs_atomic_inc(&cnt.num_connect_req);
cf_sk->layer.receive = caif_sktrecv_cb;
- err = caif_connect_client(&cf_sk->conn_req,
+
+ err = caif_connect_client(sock_net(sk), &cf_sk->conn_req,
&cf_sk->layer, &ifindex, &headroom, &tailroom);
+
if (err < 0) {
cf_sk->sk.sk_socket->state = SS_UNCONNECTED;
cf_sk->sk.sk_state = CAIF_DISCONNECTED;
@@ -947,13 +938,14 @@ static int caif_release(struct socket *sock)
* caif_queue_rcv_skb checks SOCK_DEAD holding the queue lock,
* this ensures no packets when sock is dead.
*/
- spin_lock(&sk->sk_receive_queue.lock);
+ spin_lock_bh(&sk->sk_receive_queue.lock);
sock_set_flag(sk, SOCK_DEAD);
- spin_unlock(&sk->sk_receive_queue.lock);
+ spin_unlock_bh(&sk->sk_receive_queue.lock);
sock->sk = NULL;
dbfs_atomic_inc(&cnt.num_disconnect);
+ WARN_ON(IS_ERR(cf_sk->debugfs_socket_dir));
if (cf_sk->debugfs_socket_dir != NULL)
debugfs_remove_recursive(cf_sk->debugfs_socket_dir);
@@ -963,13 +955,12 @@ static int caif_release(struct socket *sock)
if (cf_sk->sk.sk_socket->state == SS_CONNECTED ||
cf_sk->sk.sk_socket->state == SS_CONNECTING)
- res = caif_disconnect_client(&cf_sk->layer);
+ res = caif_disconnect_client(sock_net(sk), &cf_sk->layer);
cf_sk->sk.sk_socket->state = SS_DISCONNECTING;
wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP);
sock_orphan(sk);
- cf_sk->layer.dn = NULL;
sk_stream_kill_queues(&cf_sk->sk);
release_sock(sk);
sock_put(sk);
@@ -1060,16 +1051,18 @@ static void caif_sock_destructor(struct sock *sk)
caif_assert(sk_unhashed(sk));
caif_assert(!sk->sk_socket);
if (!sock_flag(sk, SOCK_DEAD)) {
- pr_info("Attempt to release alive CAIF socket: %p\n", sk);
+ pr_debug("Attempt to release alive CAIF socket: %p\n", sk);
return;
}
sk_stream_kill_queues(&cf_sk->sk);
dbfs_atomic_dec(&cnt.caif_nr_socks);
+ caif_free_client(&cf_sk->layer);
}
static int caif_create(struct net *net, struct socket *sock, int protocol,
int kern)
{
+ int num;
struct sock *sk = NULL;
struct caifsock *cf_sk = NULL;
static struct proto prot = {.name = "PF_CAIF",
@@ -1132,14 +1125,16 @@ static int caif_create(struct net *net, struct socket *sock, int protocol,
cf_sk->conn_req.protocol = protocol;
/* Increase the number of sockets created. */
dbfs_atomic_inc(&cnt.caif_nr_socks);
+ num = dbfs_atomic_inc(&cnt.caif_sock_create);
#ifdef CONFIG_DEBUG_FS
if (!IS_ERR(debugfsdir)) {
+
/* Fill in some information concerning the misc socket. */
- snprintf(cf_sk->name, sizeof(cf_sk->name), "cfsk%d",
- atomic_read(&cnt.caif_nr_socks));
+ snprintf(cf_sk->name, sizeof(cf_sk->name), "cfsk%d", num);
cf_sk->debugfs_socket_dir =
debugfs_create_dir(cf_sk->name, debugfsdir);
+
debugfs_create_u32("sk_state", S_IRUSR | S_IWUSR,
cf_sk->debugfs_socket_dir,
(u32 *) &cf_sk->sk.sk_state);
@@ -1183,6 +1178,9 @@ static int __init caif_sktinit_module(void)
debugfs_create_u32("num_sockets", S_IRUSR | S_IWUSR,
debugfsdir,
(u32 *) &cnt.caif_nr_socks);
+ debugfs_create_u32("num_create", S_IRUSR | S_IWUSR,
+ debugfsdir,
+ (u32 *) &cnt.caif_sock_create);
debugfs_create_u32("num_connect_req", S_IRUSR | S_IWUSR,
debugfsdir,
(u32 *) &cnt.num_connect_req);
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c
index f1f98d967d8..351c2ca7e7b 100644
--- a/net/caif/cfcnfg.c
+++ b/net/caif/cfcnfg.c
@@ -10,6 +10,7 @@
#include <linux/stddef.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
+#include <linux/module.h>
#include <net/caif/caif_layer.h>
#include <net/caif/cfpkt.h>
#include <net/caif/cfcnfg.h>
@@ -18,11 +19,7 @@
#include <net/caif/cffrml.h>
#include <net/caif/cfserl.h>
#include <net/caif/cfsrvl.h>
-
-#include <linux/module.h>
-#include <asm/atomic.h>
-
-#define MAX_PHY_LAYERS 7
+#include <net/caif/caif_dev.h>
#define container_obj(layr) container_of(layr, struct cfcnfg, layer)
@@ -30,6 +27,9 @@
* to manage physical interfaces
*/
struct cfcnfg_phyinfo {
+ struct list_head node;
+ bool up;
+
/* Pointer to the layer below the MUX (framing layer) */
struct cflayer *frm_layer;
/* Pointer to the lowest actual physical layer */
@@ -39,9 +39,6 @@ struct cfcnfg_phyinfo {
/* Preference of the physical in interface */
enum cfcnfg_phy_preference pref;
- /* Reference count, number of channels using the device */
- int phy_ref_count;
-
/* Information about the physical device */
struct dev_info dev_info;
@@ -59,8 +56,8 @@ struct cfcnfg {
struct cflayer layer;
struct cflayer *ctrl;
struct cflayer *mux;
- u8 last_phyid;
- struct cfcnfg_phyinfo phy_layers[MAX_PHY_LAYERS];
+ struct list_head phys;
+ struct mutex lock;
};
static void cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id,
@@ -76,6 +73,9 @@ struct cfcnfg *cfcnfg_create(void)
{
struct cfcnfg *this;
struct cfctrl_rsp *resp;
+
+ might_sleep();
+
/* Initiate this layer */
this = kzalloc(sizeof(struct cfcnfg), GFP_ATOMIC);
if (!this) {
@@ -99,27 +99,33 @@ struct cfcnfg *cfcnfg_create(void)
resp->radioset_rsp = cfctrl_resp_func;
resp->linksetup_rsp = cfcnfg_linkup_rsp;
resp->reject_rsp = cfcnfg_reject_rsp;
-
- this->last_phyid = 1;
+ INIT_LIST_HEAD(&this->phys);
cfmuxl_set_uplayer(this->mux, this->ctrl, 0);
layer_set_dn(this->ctrl, this->mux);
layer_set_up(this->ctrl, this);
+ mutex_init(&this->lock);
+
return this;
out_of_mem:
pr_warn("Out of memory\n");
+
+ synchronize_rcu();
+
kfree(this->mux);
kfree(this->ctrl);
kfree(this);
return NULL;
}
-EXPORT_SYMBOL(cfcnfg_create);
void cfcnfg_remove(struct cfcnfg *cfg)
{
+ might_sleep();
if (cfg) {
+ synchronize_rcu();
+
kfree(cfg->mux);
- kfree(cfg->ctrl);
+ cfctrl_remove(cfg->ctrl);
kfree(cfg);
}
}
@@ -128,132 +134,96 @@ static void cfctrl_resp_func(void)
{
}
+static struct cfcnfg_phyinfo *cfcnfg_get_phyinfo_rcu(struct cfcnfg *cnfg,
+ u8 phyid)
+{
+ struct cfcnfg_phyinfo *phy;
+
+ list_for_each_entry_rcu(phy, &cnfg->phys, node)
+ if (phy->id == phyid)
+ return phy;
+ return NULL;
+}
+
static void cfctrl_enum_resp(void)
{
}
-struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
+static struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
enum cfcnfg_phy_preference phy_pref)
{
- u16 i;
-
/* Try to match with specified preference */
- for (i = 1; i < MAX_PHY_LAYERS; i++) {
- if (cnfg->phy_layers[i].id == i &&
- cnfg->phy_layers[i].pref == phy_pref &&
- cnfg->phy_layers[i].frm_layer != NULL) {
- caif_assert(cnfg->phy_layers != NULL);
- caif_assert(cnfg->phy_layers[i].id == i);
- return &cnfg->phy_layers[i].dev_info;
- }
+ struct cfcnfg_phyinfo *phy;
+
+ list_for_each_entry_rcu(phy, &cnfg->phys, node) {
+ if (phy->up && phy->pref == phy_pref &&
+ phy->frm_layer != NULL)
+
+ return &phy->dev_info;
}
+
/* Otherwise just return something */
- for (i = 1; i < MAX_PHY_LAYERS; i++) {
- if (cnfg->phy_layers[i].id == i) {
- caif_assert(cnfg->phy_layers != NULL);
- caif_assert(cnfg->phy_layers[i].id == i);
- return &cnfg->phy_layers[i].dev_info;
- }
- }
+ list_for_each_entry_rcu(phy, &cnfg->phys, node)
+ if (phy->up)
+ return &phy->dev_info;
return NULL;
}
-static struct cfcnfg_phyinfo *cfcnfg_get_phyinfo(struct cfcnfg *cnfg,
- u8 phyid)
+static int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi)
{
- int i;
- /* Try to match with specified preference */
- for (i = 0; i < MAX_PHY_LAYERS; i++)
- if (cnfg->phy_layers[i].frm_layer != NULL &&
- cnfg->phy_layers[i].id == phyid)
- return &cnfg->phy_layers[i];
- return NULL;
-}
-
+ struct cfcnfg_phyinfo *phy;
-int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi)
-{
- int i;
- for (i = 0; i < MAX_PHY_LAYERS; i++)
- if (cnfg->phy_layers[i].frm_layer != NULL &&
- cnfg->phy_layers[i].ifindex == ifi)
- return i;
+ list_for_each_entry_rcu(phy, &cnfg->phys, node)
+ if (phy->ifindex == ifi && phy->up)
+ return phy->id;
return -ENODEV;
}
-int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer)
+int caif_disconnect_client(struct net *net, struct cflayer *adap_layer)
{
u8 channel_id = 0;
int ret = 0;
struct cflayer *servl = NULL;
- struct cfcnfg_phyinfo *phyinfo = NULL;
- u8 phyid = 0;
+ struct cfcnfg *cfg = get_cfcnfg(net);
caif_assert(adap_layer != NULL);
+
channel_id = adap_layer->id;
if (adap_layer->dn == NULL || channel_id == 0) {
pr_err("adap_layer->dn == NULL or adap_layer->id is 0\n");
ret = -ENOTCONN;
goto end;
}
- servl = cfmuxl_remove_uplayer(cnfg->mux, channel_id);
+
+ servl = cfmuxl_remove_uplayer(cfg->mux, channel_id);
if (servl == NULL) {
- pr_err("PROTOCOL ERROR - Error removing service_layer Channel_Id(%d)",
- channel_id);
+ pr_err("PROTOCOL ERROR - "
+ "Error removing service_layer Channel_Id(%d)",
+ channel_id);
ret = -EINVAL;
goto end;
}
- layer_set_up(servl, NULL);
- ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer);
- if (ret)
- goto end;
- caif_assert(channel_id == servl->id);
- if (adap_layer->dn != NULL) {
- phyid = cfsrvl_getphyid(adap_layer->dn);
-
- phyinfo = cfcnfg_get_phyinfo(cnfg, phyid);
- if (phyinfo == NULL) {
- pr_warn("No interface to send disconnect to\n");
- ret = -ENODEV;
- goto end;
- }
- if (phyinfo->id != phyid ||
- phyinfo->phy_layer->id != phyid ||
- phyinfo->frm_layer->id != phyid) {
- pr_err("Inconsistency in phy registration\n");
- ret = -EINVAL;
- goto end;
- }
- }
- if (phyinfo != NULL && --phyinfo->phy_ref_count == 0 &&
- phyinfo->phy_layer != NULL &&
- phyinfo->phy_layer->modemcmd != NULL) {
- phyinfo->phy_layer->modemcmd(phyinfo->phy_layer,
- _CAIF_MODEMCMD_PHYIF_USELESS);
- }
+
+ ret = cfctrl_linkdown_req(cfg->ctrl, channel_id, adap_layer);
+
end:
- cfsrvl_put(servl);
- cfctrl_cancel_req(cnfg->ctrl, adap_layer);
+ cfctrl_cancel_req(cfg->ctrl, adap_layer);
+
+ /* Do RCU sync before initiating cleanup */
+ synchronize_rcu();
if (adap_layer->ctrlcmd != NULL)
adap_layer->ctrlcmd(adap_layer, CAIF_CTRLCMD_DEINIT_RSP, 0);
return ret;
}
-EXPORT_SYMBOL(cfcnfg_disconn_adapt_layer);
-
-void cfcnfg_release_adap_layer(struct cflayer *adap_layer)
-{
- if (adap_layer->dn)
- cfsrvl_put(adap_layer->dn);
-}
-EXPORT_SYMBOL(cfcnfg_release_adap_layer);
+EXPORT_SYMBOL(caif_disconnect_client);
static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id)
{
}
-int protohead[CFCTRL_SRV_MASK] = {
+static const int protohead[CFCTRL_SRV_MASK] = {
[CFCTRL_SRV_VEI] = 4,
[CFCTRL_SRV_DATAGRAM] = 7,
[CFCTRL_SRV_UTIL] = 4,
@@ -261,49 +231,157 @@ int protohead[CFCTRL_SRV_MASK] = {
[CFCTRL_SRV_DBG] = 3,
};
-int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
- struct cfctrl_link_param *param,
- struct cflayer *adap_layer,
- int *ifindex,
+
+static int caif_connect_req_to_link_param(struct cfcnfg *cnfg,
+ struct caif_connect_request *s,
+ struct cfctrl_link_param *l)
+{
+ struct dev_info *dev_info;
+ enum cfcnfg_phy_preference pref;
+ int res;
+
+ memset(l, 0, sizeof(*l));
+ /* In caif protocol low value is high priority */
+ l->priority = CAIF_PRIO_MAX - s->priority + 1;
+
+ if (s->ifindex != 0) {
+ res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex);
+ if (res < 0)
+ return res;
+ l->phyid = res;
+ } else {
+ switch (s->link_selector) {
+ case CAIF_LINK_HIGH_BANDW:
+ pref = CFPHYPREF_HIGH_BW;
+ break;
+ case CAIF_LINK_LOW_LATENCY:
+ pref = CFPHYPREF_LOW_LAT;
+ break;
+ default:
+ return -EINVAL;
+ }
+ dev_info = cfcnfg_get_phyid(cnfg, pref);
+ if (dev_info == NULL)
+ return -ENODEV;
+ l->phyid = dev_info->id;
+ }
+ switch (s->protocol) {
+ case CAIFPROTO_AT:
+ l->linktype = CFCTRL_SRV_VEI;
+ l->endpoint = (s->sockaddr.u.at.type >> 2) & 0x3;
+ l->chtype = s->sockaddr.u.at.type & 0x3;
+ break;
+ case CAIFPROTO_DATAGRAM:
+ l->linktype = CFCTRL_SRV_DATAGRAM;
+ l->chtype = 0x00;
+ l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
+ break;
+ case CAIFPROTO_DATAGRAM_LOOP:
+ l->linktype = CFCTRL_SRV_DATAGRAM;
+ l->chtype = 0x03;
+ l->endpoint = 0x00;
+ l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
+ break;
+ case CAIFPROTO_RFM:
+ l->linktype = CFCTRL_SRV_RFM;
+ l->u.datagram.connid = s->sockaddr.u.rfm.connection_id;
+ strncpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume,
+ sizeof(l->u.rfm.volume)-1);
+ l->u.rfm.volume[sizeof(l->u.rfm.volume)-1] = 0;
+ break;
+ case CAIFPROTO_UTIL:
+ l->linktype = CFCTRL_SRV_UTIL;
+ l->endpoint = 0x00;
+ l->chtype = 0x00;
+ strncpy(l->u.utility.name, s->sockaddr.u.util.service,
+ sizeof(l->u.utility.name)-1);
+ l->u.utility.name[sizeof(l->u.utility.name)-1] = 0;
+ caif_assert(sizeof(l->u.utility.name) > 10);
+ l->u.utility.paramlen = s->param.size;
+ if (l->u.utility.paramlen > sizeof(l->u.utility.params))
+ l->u.utility.paramlen = sizeof(l->u.utility.params);
+
+ memcpy(l->u.utility.params, s->param.data,
+ l->u.utility.paramlen);
+
+ break;
+ case CAIFPROTO_DEBUG:
+ l->linktype = CFCTRL_SRV_DBG;
+ l->endpoint = s->sockaddr.u.dbg.service;
+ l->chtype = s->sockaddr.u.dbg.type;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int caif_connect_client(struct net *net, struct caif_connect_request *conn_req,
+ struct cflayer *adap_layer, int *ifindex,
int *proto_head,
int *proto_tail)
{
struct cflayer *frml;
+ struct cfcnfg_phyinfo *phy;
+ int err;
+ struct cfctrl_link_param param;
+ struct cfcnfg *cfg = get_cfcnfg(net);
+ caif_assert(cfg != NULL);
+
+ rcu_read_lock();
+ err = caif_connect_req_to_link_param(cfg, conn_req, &param);
+ if (err)
+ goto unlock;
+
+ phy = cfcnfg_get_phyinfo_rcu(cfg, param.phyid);
+ if (!phy) {
+ err = -ENODEV;
+ goto unlock;
+ }
+ err = -EINVAL;
+
if (adap_layer == NULL) {
pr_err("adap_layer is zero\n");
- return -EINVAL;
+ goto unlock;
}
if (adap_layer->receive == NULL) {
pr_err("adap_layer->receive is NULL\n");
- return -EINVAL;
+ goto unlock;
}
if (adap_layer->ctrlcmd == NULL) {
pr_err("adap_layer->ctrlcmd == NULL\n");
- return -EINVAL;
+ goto unlock;
}
- frml = cnfg->phy_layers[param->phyid].frm_layer;
+
+ err = -ENODEV;
+ frml = phy->frm_layer;
if (frml == NULL) {
pr_err("Specified PHY type does not exist!\n");
- return -ENODEV;
+ goto unlock;
}
- caif_assert(param->phyid == cnfg->phy_layers[param->phyid].id);
- caif_assert(cnfg->phy_layers[param->phyid].frm_layer->id ==
- param->phyid);
- caif_assert(cnfg->phy_layers[param->phyid].phy_layer->id ==
- param->phyid);
+ caif_assert(param.phyid == phy->id);
+ caif_assert(phy->frm_layer->id ==
+ param.phyid);
+ caif_assert(phy->phy_layer->id ==
+ param.phyid);
- *ifindex = cnfg->phy_layers[param->phyid].ifindex;
+ *ifindex = phy->ifindex;
+ *proto_tail = 2;
*proto_head =
- protohead[param->linktype]+
- (cnfg->phy_layers[param->phyid].use_stx ? 1 : 0);
- *proto_tail = 2;
+ protohead[param.linktype] + (phy->use_stx ? 1 : 0);
+
+ rcu_read_unlock();
/* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */
- cfctrl_enum_req(cnfg->ctrl, param->phyid);
- return cfctrl_linkup_request(cnfg->ctrl, param, adap_layer);
+ cfctrl_enum_req(cfg->ctrl, param.phyid);
+ return cfctrl_linkup_request(cfg->ctrl, &param, adap_layer);
+
+unlock:
+ rcu_read_unlock();
+ return err;
}
-EXPORT_SYMBOL(cfcnfg_add_adaptation_layer);
+EXPORT_SYMBOL(caif_connect_client);
static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id,
struct cflayer *adapt_layer)
@@ -315,32 +393,37 @@ static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id,
static void
cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv,
- u8 phyid, struct cflayer *adapt_layer)
+ u8 phyid, struct cflayer *adapt_layer)
{
struct cfcnfg *cnfg = container_obj(layer);
struct cflayer *servicel = NULL;
struct cfcnfg_phyinfo *phyinfo;
struct net_device *netdev;
+ rcu_read_lock();
+
if (adapt_layer == NULL) {
- pr_debug("link setup response but no client exist, send linkdown back\n");
+ pr_debug("link setup response but no client exist,"
+ "send linkdown back\n");
cfctrl_linkdown_req(cnfg->ctrl, channel_id, NULL);
- return;
+ goto unlock;
}
caif_assert(cnfg != NULL);
caif_assert(phyid != 0);
- phyinfo = &cnfg->phy_layers[phyid];
+
+ phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phyid);
+ if (phyinfo == NULL) {
+ pr_err("ERROR: Link Layer Device dissapeared"
+ "while connecting\n");
+ goto unlock;
+ }
+
+ caif_assert(phyinfo != NULL);
caif_assert(phyinfo->id == phyid);
caif_assert(phyinfo->phy_layer != NULL);
caif_assert(phyinfo->phy_layer->id == phyid);
- phyinfo->phy_ref_count++;
- if (phyinfo->phy_ref_count == 1 &&
- phyinfo->phy_layer->modemcmd != NULL) {
- phyinfo->phy_layer->modemcmd(phyinfo->phy_layer,
- _CAIF_MODEMCMD_PHYIF_USEFULL);
- }
adapt_layer->id = channel_id;
switch (serv) {
@@ -348,7 +431,8 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv,
servicel = cfvei_create(channel_id, &phyinfo->dev_info);
break;
case CFCTRL_SRV_DATAGRAM:
- servicel = cfdgml_create(channel_id, &phyinfo->dev_info);
+ servicel = cfdgml_create(channel_id,
+ &phyinfo->dev_info);
break;
case CFCTRL_SRV_RFM:
netdev = phyinfo->dev_info.dev;
@@ -365,94 +449,93 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv,
servicel = cfdbgl_create(channel_id, &phyinfo->dev_info);
break;
default:
- pr_err("Protocol error. Link setup response - unknown channel type\n");
- return;
+ pr_err("Protocol error. Link setup response "
+ "- unknown channel type\n");
+ goto unlock;
}
if (!servicel) {
pr_warn("Out of memory\n");
- return;
+ goto unlock;
}
layer_set_dn(servicel, cnfg->mux);
cfmuxl_set_uplayer(cnfg->mux, servicel, channel_id);
layer_set_up(servicel, adapt_layer);
layer_set_dn(adapt_layer, servicel);
- cfsrvl_get(servicel);
+
+ rcu_read_unlock();
+
servicel->ctrlcmd(servicel, CAIF_CTRLCMD_INIT_RSP, 0);
+ return;
+unlock:
+ rcu_read_unlock();
}
void
cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
struct net_device *dev, struct cflayer *phy_layer,
- u16 *phyid, enum cfcnfg_phy_preference pref,
+ enum cfcnfg_phy_preference pref,
bool fcs, bool stx)
{
struct cflayer *frml;
struct cflayer *phy_driver = NULL;
+ struct cfcnfg_phyinfo *phyinfo;
int i;
+ u8 phyid;
+ mutex_lock(&cnfg->lock);
- if (cnfg->phy_layers[cnfg->last_phyid].frm_layer == NULL) {
- *phyid = cnfg->last_phyid;
-
- /* range: * 1..(MAX_PHY_LAYERS-1) */
- cnfg->last_phyid =
- (cnfg->last_phyid % (MAX_PHY_LAYERS - 1)) + 1;
- } else {
- *phyid = 0;
- for (i = 1; i < MAX_PHY_LAYERS; i++) {
- if (cnfg->phy_layers[i].frm_layer == NULL) {
- *phyid = i;
- break;
- }
- }
- }
- if (*phyid == 0) {
- pr_err("No Available PHY ID\n");
- return;
+ /* CAIF protocol allow maximum 6 link-layers */
+ for (i = 0; i < 7; i++) {
+ phyid = (dev->ifindex + i) & 0x7;
+ if (phyid == 0)
+ continue;
+ if (cfcnfg_get_phyinfo_rcu(cnfg, phyid) == NULL)
+ goto got_phyid;
}
+ pr_warn("Too many CAIF Link Layers (max 6)\n");
+ goto out;
+
+got_phyid:
+ phyinfo = kzalloc(sizeof(struct cfcnfg_phyinfo), GFP_ATOMIC);
switch (phy_type) {
case CFPHYTYPE_FRAG:
phy_driver =
- cfserl_create(CFPHYTYPE_FRAG, *phyid, stx);
+ cfserl_create(CFPHYTYPE_FRAG, phyid, stx);
if (!phy_driver) {
pr_warn("Out of memory\n");
- return;
+ goto out;
}
-
break;
case CFPHYTYPE_CAIF:
phy_driver = NULL;
break;
default:
- pr_err("%d\n", phy_type);
- return;
- break;
+ goto out;
}
-
- phy_layer->id = *phyid;
- cnfg->phy_layers[*phyid].pref = pref;
- cnfg->phy_layers[*phyid].id = *phyid;
- cnfg->phy_layers[*phyid].dev_info.id = *phyid;
- cnfg->phy_layers[*phyid].dev_info.dev = dev;
- cnfg->phy_layers[*phyid].phy_layer = phy_layer;
- cnfg->phy_layers[*phyid].phy_ref_count = 0;
- cnfg->phy_layers[*phyid].ifindex = dev->ifindex;
- cnfg->phy_layers[*phyid].use_stx = stx;
- cnfg->phy_layers[*phyid].use_fcs = fcs;
+ phy_layer->id = phyid;
+ phyinfo->pref = pref;
+ phyinfo->id = phyid;
+ phyinfo->dev_info.id = phyid;
+ phyinfo->dev_info.dev = dev;
+ phyinfo->phy_layer = phy_layer;
+ phyinfo->ifindex = dev->ifindex;
+ phyinfo->use_stx = stx;
+ phyinfo->use_fcs = fcs;
phy_layer->type = phy_type;
- frml = cffrml_create(*phyid, fcs);
+ frml = cffrml_create(phyid, fcs);
+
if (!frml) {
pr_warn("Out of memory\n");
- return;
+ kfree(phyinfo);
+ goto out;
}
- cnfg->phy_layers[*phyid].frm_layer = frml;
- cfmuxl_set_dnlayer(cnfg->mux, frml, *phyid);
+ phyinfo->frm_layer = frml;
layer_set_up(frml, cnfg->mux);
if (phy_driver != NULL) {
- phy_driver->id = *phyid;
+ phy_driver->id = phyid;
layer_set_dn(frml, phy_driver);
layer_set_up(phy_driver, frml);
layer_set_dn(phy_driver, phy_layer);
@@ -461,33 +544,95 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
layer_set_dn(frml, phy_layer);
layer_set_up(phy_layer, frml);
}
+
+ list_add_rcu(&phyinfo->node, &cnfg->phys);
+out:
+ mutex_unlock(&cnfg->lock);
}
EXPORT_SYMBOL(cfcnfg_add_phy_layer);
+int cfcnfg_set_phy_state(struct cfcnfg *cnfg, struct cflayer *phy_layer,
+ bool up)
+{
+ struct cfcnfg_phyinfo *phyinfo;
+
+ rcu_read_lock();
+ phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phy_layer->id);
+ if (phyinfo == NULL) {
+ rcu_read_unlock();
+ return -ENODEV;
+ }
+
+ if (phyinfo->up == up) {
+ rcu_read_unlock();
+ return 0;
+ }
+ phyinfo->up = up;
+
+ if (up) {
+ cffrml_hold(phyinfo->frm_layer);
+ cfmuxl_set_dnlayer(cnfg->mux, phyinfo->frm_layer,
+ phy_layer->id);
+ } else {
+ cfmuxl_remove_dnlayer(cnfg->mux, phy_layer->id);
+ cffrml_put(phyinfo->frm_layer);
+ }
+
+ rcu_read_unlock();
+ return 0;
+}
+EXPORT_SYMBOL(cfcnfg_set_phy_state);
+
int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer)
{
struct cflayer *frml, *frml_dn;
u16 phyid;
+ struct cfcnfg_phyinfo *phyinfo;
+
+ might_sleep();
+
+ mutex_lock(&cnfg->lock);
+
phyid = phy_layer->id;
- caif_assert(phyid == cnfg->phy_layers[phyid].id);
- caif_assert(phy_layer == cnfg->phy_layers[phyid].phy_layer);
+ phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phyid);
+
+ if (phyinfo == NULL) {
+ mutex_unlock(&cnfg->lock);
+ return 0;
+ }
+ caif_assert(phyid == phyinfo->id);
+ caif_assert(phy_layer == phyinfo->phy_layer);
caif_assert(phy_layer->id == phyid);
- caif_assert(cnfg->phy_layers[phyid].frm_layer->id == phyid);
+ caif_assert(phyinfo->frm_layer->id == phyid);
- memset(&cnfg->phy_layers[phy_layer->id], 0,
- sizeof(struct cfcnfg_phyinfo));
- frml = cfmuxl_remove_dnlayer(cnfg->mux, phy_layer->id);
+ list_del_rcu(&phyinfo->node);
+ synchronize_rcu();
+
+ /* Fail if reference count is not zero */
+ if (cffrml_refcnt_read(phyinfo->frm_layer) != 0) {
+ pr_info("Wait for device inuse\n");
+ list_add_rcu(&phyinfo->node, &cnfg->phys);
+ mutex_unlock(&cnfg->lock);
+ return -EAGAIN;
+ }
+
+ frml = phyinfo->frm_layer;
frml_dn = frml->dn;
cffrml_set_uplayer(frml, NULL);
cffrml_set_dnlayer(frml, NULL);
- kfree(frml);
-
if (phy_layer != frml_dn) {
layer_set_up(frml_dn, NULL);
layer_set_dn(frml_dn, NULL);
- kfree(frml_dn);
}
layer_set_up(phy_layer, NULL);
+
+ if (phyinfo->phy_layer != frml_dn)
+ kfree(frml_dn);
+
+ cffrml_free(frml);
+ kfree(phyinfo);
+ mutex_unlock(&cnfg->lock);
+
return 0;
}
EXPORT_SYMBOL(cfcnfg_del_phy_layer);
diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c
index 3cd8f978e30..0c00a6015dd 100644
--- a/net/caif/cfctrl.c
+++ b/net/caif/cfctrl.c
@@ -17,7 +17,6 @@
#define UTILITY_NAME_LENGTH 16
#define CFPKT_CTRL_PKT_LEN 20
-
#ifdef CAIF_NO_LOOP
static int handle_loop(struct cfctrl *ctrl,
int cmd, struct cfpkt *pkt){
@@ -51,14 +50,31 @@ struct cflayer *cfctrl_create(void)
this->serv.layer.receive = cfctrl_recv;
sprintf(this->serv.layer.name, "ctrl");
this->serv.layer.ctrlcmd = cfctrl_ctrlcmd;
+#ifndef CAIF_NO_LOOP
spin_lock_init(&this->loop_linkid_lock);
+ this->loop_linkid = 1;
+#endif
spin_lock_init(&this->info_list_lock);
INIT_LIST_HEAD(&this->list);
- this->loop_linkid = 1;
return &this->serv.layer;
}
-static bool param_eq(struct cfctrl_link_param *p1, struct cfctrl_link_param *p2)
+void cfctrl_remove(struct cflayer *layer)
+{
+ struct cfctrl_request_info *p, *tmp;
+ struct cfctrl *ctrl = container_obj(layer);
+
+ spin_lock_bh(&ctrl->info_list_lock);
+ list_for_each_entry_safe(p, tmp, &ctrl->list, list) {
+ list_del(&p->list);
+ kfree(p);
+ }
+ spin_unlock_bh(&ctrl->info_list_lock);
+ kfree(layer);
+}
+
+static bool param_eq(const struct cfctrl_link_param *p1,
+ const struct cfctrl_link_param *p2)
{
bool eq =
p1->linktype == p2->linktype &&
@@ -100,8 +116,8 @@ static bool param_eq(struct cfctrl_link_param *p1, struct cfctrl_link_param *p2)
return false;
}
-bool cfctrl_req_eq(struct cfctrl_request_info *r1,
- struct cfctrl_request_info *r2)
+static bool cfctrl_req_eq(const struct cfctrl_request_info *r1,
+ const struct cfctrl_request_info *r2)
{
if (r1->cmd != r2->cmd)
return false;
@@ -112,23 +128,22 @@ bool cfctrl_req_eq(struct cfctrl_request_info *r1,
}
/* Insert request at the end */
-void cfctrl_insert_req(struct cfctrl *ctrl,
+static void cfctrl_insert_req(struct cfctrl *ctrl,
struct cfctrl_request_info *req)
{
- spin_lock(&ctrl->info_list_lock);
+ spin_lock_bh(&ctrl->info_list_lock);
atomic_inc(&ctrl->req_seq_no);
req->sequence_no = atomic_read(&ctrl->req_seq_no);
list_add_tail(&req->list, &ctrl->list);
- spin_unlock(&ctrl->info_list_lock);
+ spin_unlock_bh(&ctrl->info_list_lock);
}
/* Compare and remove request */
-struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl,
- struct cfctrl_request_info *req)
+static struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl,
+ struct cfctrl_request_info *req)
{
struct cfctrl_request_info *p, *tmp, *first;
- spin_lock(&ctrl->info_list_lock);
first = list_first_entry(&ctrl->list, struct cfctrl_request_info, list);
list_for_each_entry_safe(p, tmp, &ctrl->list, list) {
@@ -144,7 +159,6 @@ struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl,
}
p = NULL;
out:
- spin_unlock(&ctrl->info_list_lock);
return p;
}
@@ -154,16 +168,6 @@ struct cfctrl_rsp *cfctrl_get_respfuncs(struct cflayer *layer)
return &this->res;
}
-void cfctrl_set_dnlayer(struct cflayer *this, struct cflayer *dn)
-{
- this->dn = dn;
-}
-
-void cfctrl_set_uplayer(struct cflayer *this, struct cflayer *up)
-{
- this->up = up;
-}
-
static void init_info(struct caif_payload_info *info, struct cfctrl *cfctrl)
{
info->hdr_len = 0;
@@ -188,10 +192,6 @@ void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid)
cfpkt_addbdy(pkt, physlinkid);
ret =
cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
- if (ret < 0) {
- pr_err("Could not transmit enum message\n");
- cfpkt_destroy(pkt);
- }
}
int cfctrl_linkup_request(struct cflayer *layer,
@@ -205,14 +205,23 @@ int cfctrl_linkup_request(struct cflayer *layer,
struct cfctrl_request_info *req;
int ret;
char utility_name[16];
- struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
+ struct cfpkt *pkt;
+
+ if (cfctrl_cancel_req(layer, user_layer) > 0) {
+ /* Slight Paranoia, check if already connecting */
+ pr_err("Duplicate connect request for same client\n");
+ WARN_ON(1);
+ return -EALREADY;
+ }
+
+ pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
if (!pkt) {
pr_warn("Out of memory\n");
return -ENOMEM;
}
cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_SETUP);
- cfpkt_addbdy(pkt, (param->chtype << 4) + param->linktype);
- cfpkt_addbdy(pkt, (param->priority << 3) + param->phyid);
+ cfpkt_addbdy(pkt, (param->chtype << 4) | param->linktype);
+ cfpkt_addbdy(pkt, (param->priority << 3) | param->phyid);
cfpkt_addbdy(pkt, param->endpoint & 0x03);
switch (param->linktype) {
@@ -275,9 +284,13 @@ int cfctrl_linkup_request(struct cflayer *layer,
ret =
cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
if (ret < 0) {
- pr_err("Could not transmit linksetup request\n");
- cfpkt_destroy(pkt);
- return -ENODEV;
+ int count;
+
+ count = cfctrl_cancel_req(&cfctrl->serv.layer,
+ user_layer);
+ if (count != 1)
+ pr_err("Could not remove request (%d)", count);
+ return -ENODEV;
}
return 0;
}
@@ -297,80 +310,29 @@ int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid,
init_info(cfpkt_info(pkt), cfctrl);
ret =
cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
- if (ret < 0) {
- pr_err("Could not transmit link-down request\n");
- cfpkt_destroy(pkt);
- }
+#ifndef CAIF_NO_LOOP
+ cfctrl->loop_linkused[channelid] = 0;
+#endif
return ret;
}
-void cfctrl_sleep_req(struct cflayer *layer)
-{
- int ret;
- struct cfctrl *cfctrl = container_obj(layer);
- struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
- if (!pkt) {
- pr_warn("Out of memory\n");
- return;
- }
- cfpkt_addbdy(pkt, CFCTRL_CMD_SLEEP);
- init_info(cfpkt_info(pkt), cfctrl);
- ret =
- cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
- if (ret < 0)
- cfpkt_destroy(pkt);
-}
-
-void cfctrl_wake_req(struct cflayer *layer)
-{
- int ret;
- struct cfctrl *cfctrl = container_obj(layer);
- struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
- if (!pkt) {
- pr_warn("Out of memory\n");
- return;
- }
- cfpkt_addbdy(pkt, CFCTRL_CMD_WAKE);
- init_info(cfpkt_info(pkt), cfctrl);
- ret =
- cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
- if (ret < 0)
- cfpkt_destroy(pkt);
-}
-
-void cfctrl_getstartreason_req(struct cflayer *layer)
-{
- int ret;
- struct cfctrl *cfctrl = container_obj(layer);
- struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
- if (!pkt) {
- pr_warn("Out of memory\n");
- return;
- }
- cfpkt_addbdy(pkt, CFCTRL_CMD_START_REASON);
- init_info(cfpkt_info(pkt), cfctrl);
- ret =
- cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
- if (ret < 0)
- cfpkt_destroy(pkt);
-}
-
-
-void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer)
+int cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer)
{
struct cfctrl_request_info *p, *tmp;
struct cfctrl *ctrl = container_obj(layr);
- spin_lock(&ctrl->info_list_lock);
+ int found = 0;
+ spin_lock_bh(&ctrl->info_list_lock);
list_for_each_entry_safe(p, tmp, &ctrl->list, list) {
if (p->client_layer == adap_layer) {
- pr_debug("cancel req :%d\n", p->sequence_no);
list_del(&p->list);
kfree(p);
+ found++;
}
}
- spin_unlock(&ctrl->info_list_lock);
+ spin_unlock_bh(&ctrl->info_list_lock);
+ return found;
}
static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
@@ -522,6 +484,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
rsp.cmd = cmd;
rsp.param = linkparam;
+ spin_lock_bh(&cfctrl->info_list_lock);
req = cfctrl_remove_req(cfctrl, &rsp);
if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) ||
@@ -541,6 +504,8 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
if (req != NULL)
kfree(req);
+
+ spin_unlock_bh(&cfctrl->info_list_lock);
}
break;
case CFCTRL_CMD_LINK_DESTROY:
@@ -584,12 +549,29 @@ static void cfctrl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
switch (ctrl) {
case _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND:
case CAIF_CTRLCMD_FLOW_OFF_IND:
- spin_lock(&this->info_list_lock);
+ spin_lock_bh(&this->info_list_lock);
if (!list_empty(&this->list)) {
pr_debug("Received flow off in control layer\n");
}
- spin_unlock(&this->info_list_lock);
+ spin_unlock_bh(&this->info_list_lock);
break;
+ case _CAIF_CTRLCMD_PHYIF_DOWN_IND: {
+ struct cfctrl_request_info *p, *tmp;
+
+ /* Find all connect request and report failure */
+ spin_lock_bh(&this->info_list_lock);
+ list_for_each_entry_safe(p, tmp, &this->list, list) {
+ if (p->param.phyid == phyid) {
+ list_del(&p->list);
+ p->client_layer->ctrlcmd(p->client_layer,
+ CAIF_CTRLCMD_INIT_FAIL_RSP,
+ phyid);
+ kfree(p);
+ }
+ }
+ spin_unlock_bh(&this->info_list_lock);
+ break;
+ }
default:
break;
}
@@ -599,27 +581,33 @@ static void cfctrl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
static int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt)
{
static int last_linkid;
+ static int dec;
u8 linkid, linktype, tmp;
switch (cmd) {
case CFCTRL_CMD_LINK_SETUP:
- spin_lock(&ctrl->loop_linkid_lock);
- for (linkid = last_linkid + 1; linkid < 255; linkid++)
- if (!ctrl->loop_linkused[linkid])
- goto found;
+ spin_lock_bh(&ctrl->loop_linkid_lock);
+ if (!dec) {
+ for (linkid = last_linkid + 1; linkid < 255; linkid++)
+ if (!ctrl->loop_linkused[linkid])
+ goto found;
+ }
+ dec = 1;
for (linkid = last_linkid - 1; linkid > 0; linkid--)
if (!ctrl->loop_linkused[linkid])
goto found;
- spin_unlock(&ctrl->loop_linkid_lock);
- pr_err("Out of link-ids\n");
- return -EINVAL;
+ spin_unlock_bh(&ctrl->loop_linkid_lock);
+
found:
+ if (linkid < 10)
+ dec = 0;
+
if (!ctrl->loop_linkused[linkid])
ctrl->loop_linkused[linkid] = 1;
last_linkid = linkid;
cfpkt_add_trail(pkt, &linkid, 1);
- spin_unlock(&ctrl->loop_linkid_lock);
+ spin_unlock_bh(&ctrl->loop_linkid_lock);
cfpkt_peek_head(pkt, &linktype, 1);
if (linktype == CFCTRL_SRV_UTIL) {
tmp = 0x01;
@@ -629,10 +617,10 @@ found:
break;
case CFCTRL_CMD_LINK_DESTROY:
- spin_lock(&ctrl->loop_linkid_lock);
+ spin_lock_bh(&ctrl->loop_linkid_lock);
cfpkt_peek_head(pkt, &linkid, 1);
ctrl->loop_linkused[linkid] = 0;
- spin_unlock(&ctrl->loop_linkid_lock);
+ spin_unlock_bh(&ctrl->loop_linkid_lock);
break;
default:
break;
diff --git a/net/caif/cfdgml.c b/net/caif/cfdgml.c
index 054fdb5aeb8..0382dec84fd 100644
--- a/net/caif/cfdgml.c
+++ b/net/caif/cfdgml.c
@@ -108,10 +108,5 @@ static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt)
*/
info->hdr_len = 4;
info->dev_info = &service->dev_info;
- ret = layr->dn->transmit(layr->dn, pkt);
- if (ret < 0) {
- u32 tmp32;
- cfpkt_extr_head(pkt, &tmp32, 4);
- }
- return ret;
+ return layr->dn->transmit(layr->dn, pkt);
}
diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c
index a445043931a..04204b20271 100644
--- a/net/caif/cffrml.c
+++ b/net/caif/cffrml.c
@@ -12,6 +12,7 @@
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/crc-ccitt.h>
+#include <linux/netdevice.h>
#include <net/caif/caif_layer.h>
#include <net/caif/cfpkt.h>
#include <net/caif/cffrml.h>
@@ -21,6 +22,7 @@
struct cffrml {
struct cflayer layer;
bool dofcs; /* !< FCS active */
+ int __percpu *pcpu_refcnt;
};
static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt);
@@ -37,6 +39,12 @@ struct cflayer *cffrml_create(u16 phyid, bool use_fcs)
pr_warn("Out of memory\n");
return NULL;
}
+ this->pcpu_refcnt = alloc_percpu(int);
+ if (this->pcpu_refcnt == NULL) {
+ kfree(this);
+ return NULL;
+ }
+
caif_assert(offsetof(struct cffrml, layer) == 0);
memset(this, 0, sizeof(struct cflayer));
@@ -49,6 +57,13 @@ struct cflayer *cffrml_create(u16 phyid, bool use_fcs)
return (struct cflayer *) this;
}
+void cffrml_free(struct cflayer *layer)
+{
+ struct cffrml *this = container_obj(layer);
+ free_percpu(this->pcpu_refcnt);
+ kfree(layer);
+}
+
void cffrml_set_uplayer(struct cflayer *this, struct cflayer *up)
{
this->up = up;
@@ -112,6 +127,13 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt)
cfpkt_destroy(pkt);
return -EPROTO;
}
+
+ if (layr->up == NULL) {
+ pr_err("Layr up is missing!\n");
+ cfpkt_destroy(pkt);
+ return -EINVAL;
+ }
+
return layr->up->receive(layr->up, pkt);
}
@@ -120,7 +142,6 @@ static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt)
int tmp;
u16 chks;
u16 len;
- int ret;
struct cffrml *this = container_obj(layr);
if (this->dofcs) {
chks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff);
@@ -135,19 +156,44 @@ static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt)
cfpkt_info(pkt)->hdr_len += 2;
if (cfpkt_erroneous(pkt)) {
pr_err("Packet is erroneous!\n");
+ cfpkt_destroy(pkt);
return -EPROTO;
}
- ret = layr->dn->transmit(layr->dn, pkt);
- if (ret < 0) {
- /* Remove header on faulty packet. */
- cfpkt_extr_head(pkt, &tmp, 2);
+
+ if (layr->dn == NULL) {
+ cfpkt_destroy(pkt);
+ return -ENODEV;
+
}
- return ret;
+ return layr->dn->transmit(layr->dn, pkt);
}
static void cffrml_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
int phyid)
{
- if (layr->up->ctrlcmd)
+ if (layr->up && layr->up->ctrlcmd)
layr->up->ctrlcmd(layr->up, ctrl, layr->id);
}
+
+void cffrml_put(struct cflayer *layr)
+{
+ struct cffrml *this = container_obj(layr);
+ if (layr != NULL && this->pcpu_refcnt != NULL)
+ irqsafe_cpu_dec(*this->pcpu_refcnt);
+}
+
+void cffrml_hold(struct cflayer *layr)
+{
+ struct cffrml *this = container_obj(layr);
+ if (layr != NULL && this->pcpu_refcnt != NULL)
+ irqsafe_cpu_inc(*this->pcpu_refcnt);
+}
+
+int cffrml_refcnt_read(struct cflayer *layr)
+{
+ int i, refcnt = 0;
+ struct cffrml *this = container_obj(layr);
+ for_each_possible_cpu(i)
+ refcnt += *per_cpu_ptr(this->pcpu_refcnt, i);
+ return refcnt;
+}
diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c
index 24f1ffa74b0..2a56df7e0a4 100644
--- a/net/caif/cfmuxl.c
+++ b/net/caif/cfmuxl.c
@@ -9,6 +9,7 @@
#include <linux/stddef.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
+#include <linux/rculist.h>
#include <net/caif/cfpkt.h>
#include <net/caif/cfmuxl.h>
#include <net/caif/cfsrvl.h>
@@ -64,66 +65,31 @@ struct cflayer *cfmuxl_create(void)
int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid)
{
struct cfmuxl *muxl = container_obj(layr);
- spin_lock(&muxl->receive_lock);
- cfsrvl_get(up);
- list_add(&up->node, &muxl->srvl_list);
- spin_unlock(&muxl->receive_lock);
- return 0;
-}
-
-bool cfmuxl_is_phy_inuse(struct cflayer *layr, u8 phyid)
-{
- struct list_head *node;
- struct cflayer *layer;
- struct cfmuxl *muxl = container_obj(layr);
- bool match = false;
- spin_lock(&muxl->receive_lock);
-
- list_for_each(node, &muxl->srvl_list) {
- layer = list_entry(node, struct cflayer, node);
- if (cfsrvl_phyid_match(layer, phyid)) {
- match = true;
- break;
- }
-
- }
- spin_unlock(&muxl->receive_lock);
- return match;
-}
-u8 cfmuxl_get_phyid(struct cflayer *layr, u8 channel_id)
-{
- struct cflayer *up;
- int phyid;
- struct cfmuxl *muxl = container_obj(layr);
- spin_lock(&muxl->receive_lock);
- up = get_up(muxl, channel_id);
- if (up != NULL)
- phyid = cfsrvl_getphyid(up);
- else
- phyid = 0;
- spin_unlock(&muxl->receive_lock);
- return phyid;
+ spin_lock_bh(&muxl->receive_lock);
+ list_add_rcu(&up->node, &muxl->srvl_list);
+ spin_unlock_bh(&muxl->receive_lock);
+ return 0;
}
int cfmuxl_set_dnlayer(struct cflayer *layr, struct cflayer *dn, u8 phyid)
{
struct cfmuxl *muxl = (struct cfmuxl *) layr;
- spin_lock(&muxl->transmit_lock);
- list_add(&dn->node, &muxl->frml_list);
- spin_unlock(&muxl->transmit_lock);
+
+ spin_lock_bh(&muxl->transmit_lock);
+ list_add_rcu(&dn->node, &muxl->frml_list);
+ spin_unlock_bh(&muxl->transmit_lock);
return 0;
}
static struct cflayer *get_from_id(struct list_head *list, u16 id)
{
- struct list_head *node;
- struct cflayer *layer;
- list_for_each(node, list) {
- layer = list_entry(node, struct cflayer, node);
- if (layer->id == id)
- return layer;
+ struct cflayer *lyr;
+ list_for_each_entry_rcu(lyr, list, node) {
+ if (lyr->id == id)
+ return lyr;
}
+
return NULL;
}
@@ -131,41 +97,45 @@ struct cflayer *cfmuxl_remove_dnlayer(struct cflayer *layr, u8 phyid)
{
struct cfmuxl *muxl = container_obj(layr);
struct cflayer *dn;
- spin_lock(&muxl->transmit_lock);
- memset(muxl->dn_cache, 0, sizeof(muxl->dn_cache));
+ int idx = phyid % DN_CACHE_SIZE;
+
+ spin_lock_bh(&muxl->transmit_lock);
+ rcu_assign_pointer(muxl->dn_cache[idx], NULL);
dn = get_from_id(&muxl->frml_list, phyid);
- if (dn == NULL) {
- spin_unlock(&muxl->transmit_lock);
- return NULL;
- }
- list_del(&dn->node);
+ if (dn == NULL)
+ goto out;
+
+ list_del_rcu(&dn->node);
caif_assert(dn != NULL);
- spin_unlock(&muxl->transmit_lock);
+out:
+ spin_unlock_bh(&muxl->transmit_lock);
return dn;
}
-/* Invariant: lock is taken */
static struct cflayer *get_up(struct cfmuxl *muxl, u16 id)
{
struct cflayer *up;
int idx = id % UP_CACHE_SIZE;
- up = muxl->up_cache[idx];
+ up = rcu_dereference(muxl->up_cache[idx]);
if (up == NULL || up->id != id) {
+ spin_lock_bh(&muxl->receive_lock);
up = get_from_id(&muxl->srvl_list, id);
- muxl->up_cache[idx] = up;
+ rcu_assign_pointer(muxl->up_cache[idx], up);
+ spin_unlock_bh(&muxl->receive_lock);
}
return up;
}
-/* Invariant: lock is taken */
static struct cflayer *get_dn(struct cfmuxl *muxl, struct dev_info *dev_info)
{
struct cflayer *dn;
int idx = dev_info->id % DN_CACHE_SIZE;
- dn = muxl->dn_cache[idx];
+ dn = rcu_dereference(muxl->dn_cache[idx]);
if (dn == NULL || dn->id != dev_info->id) {
+ spin_lock_bh(&muxl->transmit_lock);
dn = get_from_id(&muxl->frml_list, dev_info->id);
- muxl->dn_cache[idx] = dn;
+ rcu_assign_pointer(muxl->dn_cache[idx], dn);
+ spin_unlock_bh(&muxl->transmit_lock);
}
return dn;
}
@@ -174,15 +144,17 @@ struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 id)
{
struct cflayer *up;
struct cfmuxl *muxl = container_obj(layr);
- spin_lock(&muxl->receive_lock);
- up = get_up(muxl, id);
+ int idx = id % UP_CACHE_SIZE;
+
+ spin_lock_bh(&muxl->receive_lock);
+ up = get_from_id(&muxl->srvl_list, id);
if (up == NULL)
goto out;
- memset(muxl->up_cache, 0, sizeof(muxl->up_cache));
- list_del(&up->node);
- cfsrvl_put(up);
+
+ rcu_assign_pointer(muxl->up_cache[idx], NULL);
+ list_del_rcu(&up->node);
out:
- spin_unlock(&muxl->receive_lock);
+ spin_unlock_bh(&muxl->receive_lock);
return up;
}
@@ -197,58 +169,78 @@ static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt)
cfpkt_destroy(pkt);
return -EPROTO;
}
-
- spin_lock(&muxl->receive_lock);
+ rcu_read_lock();
up = get_up(muxl, id);
- spin_unlock(&muxl->receive_lock);
+
if (up == NULL) {
- pr_info("Received data on unknown link ID = %d (0x%x) up == NULL",
- id, id);
+ pr_debug("Received data on unknown link ID = %d (0x%x)"
+ " up == NULL", id, id);
cfpkt_destroy(pkt);
/*
* Don't return ERROR, since modem misbehaves and sends out
* flow on before linksetup response.
*/
+
+ rcu_read_unlock();
return /* CFGLU_EPROT; */ 0;
}
+
+ /* We can't hold rcu_lock during receive, so take a ref count instead */
cfsrvl_get(up);
+ rcu_read_unlock();
+
ret = up->receive(up, pkt);
+
cfsrvl_put(up);
return ret;
}
static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt)
{
- int ret;
struct cfmuxl *muxl = container_obj(layr);
+ int err;
u8 linkid;
struct cflayer *dn;
struct caif_payload_info *info = cfpkt_info(pkt);
- dn = get_dn(muxl, cfpkt_info(pkt)->dev_info);
+ BUG_ON(!info);
+
+ rcu_read_lock();
+
+ dn = get_dn(muxl, info->dev_info);
if (dn == NULL) {
- pr_warn("Send data on unknown phy ID = %d (0x%x)\n",
+ pr_debug("Send data on unknown phy ID = %d (0x%x)\n",
info->dev_info->id, info->dev_info->id);
+ rcu_read_unlock();
+ cfpkt_destroy(pkt);
return -ENOTCONN;
}
+
info->hdr_len += 1;
linkid = info->channel_id;
cfpkt_add_head(pkt, &linkid, 1);
- ret = dn->transmit(dn, pkt);
- /* Remove MUX protocol header upon error. */
- if (ret < 0)
- cfpkt_extr_head(pkt, &linkid, 1);
- return ret;
+
+ /* We can't hold rcu_lock during receive, so take a ref count instead */
+ cffrml_hold(dn);
+
+ rcu_read_unlock();
+
+ err = dn->transmit(dn, pkt);
+
+ cffrml_put(dn);
+ return err;
}
static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
int phyid)
{
struct cfmuxl *muxl = container_obj(layr);
- struct list_head *node, *next;
struct cflayer *layer;
- list_for_each_safe(node, next, &muxl->srvl_list) {
- layer = list_entry(node, struct cflayer, node);
- if (cfsrvl_phyid_match(layer, phyid))
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(layer, &muxl->srvl_list, node) {
+ if (cfsrvl_phyid_match(layer, phyid) && layer->ctrlcmd)
+ /* NOTE: ctrlcmd is not allowed to block */
layer->ctrlcmd(layer, ctrl, phyid);
}
+ rcu_read_unlock();
}
diff --git a/net/caif/cfpkt_skbuff.c b/net/caif/cfpkt_skbuff.c
index d7e865e2ff6..75d4bfae1a7 100644
--- a/net/caif/cfpkt_skbuff.c
+++ b/net/caif/cfpkt_skbuff.c
@@ -42,22 +42,22 @@ struct cfpkt_priv_data {
bool erronous;
};
-inline struct cfpkt_priv_data *cfpkt_priv(struct cfpkt *pkt)
+static inline struct cfpkt_priv_data *cfpkt_priv(struct cfpkt *pkt)
{
return (struct cfpkt_priv_data *) pkt->skb.cb;
}
-inline bool is_erronous(struct cfpkt *pkt)
+static inline bool is_erronous(struct cfpkt *pkt)
{
return cfpkt_priv(pkt)->erronous;
}
-inline struct sk_buff *pkt_to_skb(struct cfpkt *pkt)
+static inline struct sk_buff *pkt_to_skb(struct cfpkt *pkt)
{
return &pkt->skb;
}
-inline struct cfpkt *skb_to_pkt(struct sk_buff *skb)
+static inline struct cfpkt *skb_to_pkt(struct sk_buff *skb)
{
return (struct cfpkt *) skb;
}
@@ -97,21 +97,20 @@ inline struct cfpkt *cfpkt_create(u16 len)
{
return cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX);
}
-EXPORT_SYMBOL(cfpkt_create);
void cfpkt_destroy(struct cfpkt *pkt)
{
struct sk_buff *skb = pkt_to_skb(pkt);
kfree_skb(skb);
}
-EXPORT_SYMBOL(cfpkt_destroy);
+
inline bool cfpkt_more(struct cfpkt *pkt)
{
struct sk_buff *skb = pkt_to_skb(pkt);
return skb->len > 0;
}
-EXPORT_SYMBOL(cfpkt_more);
+
int cfpkt_peek_head(struct cfpkt *pkt, void *data, u16 len)
{
@@ -123,7 +122,6 @@ int cfpkt_peek_head(struct cfpkt *pkt, void *data, u16 len)
return !cfpkt_extr_head(pkt, data, len) &&
!cfpkt_add_head(pkt, data, len);
}
-EXPORT_SYMBOL(cfpkt_peek_head);
int cfpkt_extr_head(struct cfpkt *pkt, void *data, u16 len)
{
@@ -148,7 +146,6 @@ int cfpkt_extr_head(struct cfpkt *pkt, void *data, u16 len)
memcpy(data, from, len);
return 0;
}
-EXPORT_SYMBOL(cfpkt_extr_head);
int cfpkt_extr_trail(struct cfpkt *pkt, void *dta, u16 len)
{
@@ -171,13 +168,13 @@ int cfpkt_extr_trail(struct cfpkt *pkt, void *dta, u16 len)
memcpy(data, from, len);
return 0;
}
-EXPORT_SYMBOL(cfpkt_extr_trail);
+
int cfpkt_pad_trail(struct cfpkt *pkt, u16 len)
{
return cfpkt_add_body(pkt, NULL, len);
}
-EXPORT_SYMBOL(cfpkt_pad_trail);
+
int cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len)
{
@@ -226,13 +223,11 @@ int cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len)
memcpy(to, data, len);
return 0;
}
-EXPORT_SYMBOL(cfpkt_add_body);
inline int cfpkt_addbdy(struct cfpkt *pkt, u8 data)
{
return cfpkt_add_body(pkt, &data, 1);
}
-EXPORT_SYMBOL(cfpkt_addbdy);
int cfpkt_add_head(struct cfpkt *pkt, const void *data2, u16 len)
{
@@ -259,20 +254,20 @@ int cfpkt_add_head(struct cfpkt *pkt, const void *data2, u16 len)
memcpy(to, data, len);
return 0;
}
-EXPORT_SYMBOL(cfpkt_add_head);
+
inline int cfpkt_add_trail(struct cfpkt *pkt, const void *data, u16 len)
{
return cfpkt_add_body(pkt, data, len);
}
-EXPORT_SYMBOL(cfpkt_add_trail);
+
inline u16 cfpkt_getlen(struct cfpkt *pkt)
{
struct sk_buff *skb = pkt_to_skb(pkt);
return skb->len;
}
-EXPORT_SYMBOL(cfpkt_getlen);
+
inline u16 cfpkt_iterate(struct cfpkt *pkt,
u16 (*iter_func)(u16, void *, u16),
@@ -290,7 +285,7 @@ inline u16 cfpkt_iterate(struct cfpkt *pkt,
}
return iter_func(data, pkt->skb.data, cfpkt_getlen(pkt));
}
-EXPORT_SYMBOL(cfpkt_iterate);
+
int cfpkt_setlen(struct cfpkt *pkt, u16 len)
{
@@ -315,18 +310,6 @@ int cfpkt_setlen(struct cfpkt *pkt, u16 len)
return cfpkt_getlen(pkt);
}
-EXPORT_SYMBOL(cfpkt_setlen);
-
-struct cfpkt *cfpkt_create_uplink(const unsigned char *data, unsigned int len)
-{
- struct cfpkt *pkt = cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX);
- if (!pkt)
- return NULL;
- if (unlikely(data != NULL))
- cfpkt_add_body(pkt, data, len);
- return pkt;
-}
-EXPORT_SYMBOL(cfpkt_create_uplink);
struct cfpkt *cfpkt_append(struct cfpkt *dstpkt,
struct cfpkt *addpkt,
@@ -368,7 +351,6 @@ struct cfpkt *cfpkt_append(struct cfpkt *dstpkt,
dst->len += addlen;
return skb_to_pkt(dst);
}
-EXPORT_SYMBOL(cfpkt_append);
struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos)
{
@@ -406,174 +388,13 @@ struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos)
skb2->len += len2nd;
return skb_to_pkt(skb2);
}
-EXPORT_SYMBOL(cfpkt_split);
-
-char *cfpkt_log_pkt(struct cfpkt *pkt, char *buf, int buflen)
-{
- struct sk_buff *skb = pkt_to_skb(pkt);
- char *p = buf;
- int i;
-
- /*
- * Sanity check buffer length, it needs to be at least as large as
- * the header info: ~=50+ bytes
- */
- if (buflen < 50)
- return NULL;
-
- snprintf(buf, buflen, "%s: pkt:%p len:%ld(%ld+%ld) {%ld,%ld} data: [",
- is_erronous(pkt) ? "ERRONOUS-SKB" :
- (skb->data_len != 0 ? "COMPLEX-SKB" : "SKB"),
- skb,
- (long) skb->len,
- (long) (skb_tail_pointer(skb) - skb->data),
- (long) skb->data_len,
- (long) (skb->data - skb->head),
- (long) (skb_tail_pointer(skb) - skb->head));
- p = buf + strlen(buf);
-
- for (i = 0; i < skb_tail_pointer(skb) - skb->data && i < 300; i++) {
- if (p > buf + buflen - 10) {
- sprintf(p, "...");
- p = buf + strlen(buf);
- break;
- }
- sprintf(p, "%02x,", skb->data[i]);
- p = buf + strlen(buf);
- }
- sprintf(p, "]\n");
- return buf;
-}
-EXPORT_SYMBOL(cfpkt_log_pkt);
-
-int cfpkt_raw_append(struct cfpkt *pkt, void **buf, unsigned int buflen)
-{
- struct sk_buff *skb = pkt_to_skb(pkt);
- struct sk_buff *lastskb;
-
- caif_assert(buf != NULL);
- if (unlikely(is_erronous(pkt)))
- return -EPROTO;
- /* Make sure SKB is writable */
- if (unlikely(skb_cow_data(skb, 0, &lastskb) < 0)) {
- PKT_ERROR(pkt, "skb_cow_data failed\n");
- return -EPROTO;
- }
-
- if (unlikely(skb_linearize(skb) != 0)) {
- PKT_ERROR(pkt, "linearize failed\n");
- return -EPROTO;
- }
-
- if (unlikely(skb_tailroom(skb) < buflen)) {
- PKT_ERROR(pkt, "buffer too short - failed\n");
- return -EPROTO;
- }
-
- *buf = skb_put(skb, buflen);
- return 1;
-}
-EXPORT_SYMBOL(cfpkt_raw_append);
-int cfpkt_raw_extract(struct cfpkt *pkt, void **buf, unsigned int buflen)
-{
- struct sk_buff *skb = pkt_to_skb(pkt);
-
- caif_assert(buf != NULL);
- if (unlikely(is_erronous(pkt)))
- return -EPROTO;
-
- if (unlikely(buflen > skb->len)) {
- PKT_ERROR(pkt, "buflen too large - failed\n");
- return -EPROTO;
- }
-
- if (unlikely(buflen > skb_headlen(skb))) {
- if (unlikely(skb_linearize(skb) != 0)) {
- PKT_ERROR(pkt, "linearize failed\n");
- return -EPROTO;
- }
- }
-
- *buf = skb->data;
- skb_pull(skb, buflen);
-
- return 1;
-}
-EXPORT_SYMBOL(cfpkt_raw_extract);
-
-inline bool cfpkt_erroneous(struct cfpkt *pkt)
+bool cfpkt_erroneous(struct cfpkt *pkt)
{
return cfpkt_priv(pkt)->erronous;
}
-EXPORT_SYMBOL(cfpkt_erroneous);
-
-struct cfpktq *cfpktq_create(void)
-{
- struct cfpktq *q = kmalloc(sizeof(struct cfpktq), GFP_ATOMIC);
- if (!q)
- return NULL;
- skb_queue_head_init(&q->head);
- atomic_set(&q->count, 0);
- spin_lock_init(&q->lock);
- return q;
-}
-EXPORT_SYMBOL(cfpktq_create);
-
-void cfpkt_queue(struct cfpktq *pktq, struct cfpkt *pkt, unsigned short prio)
-{
- atomic_inc(&pktq->count);
- spin_lock(&pktq->lock);
- skb_queue_tail(&pktq->head, pkt_to_skb(pkt));
- spin_unlock(&pktq->lock);
-
-}
-EXPORT_SYMBOL(cfpkt_queue);
-
-struct cfpkt *cfpkt_qpeek(struct cfpktq *pktq)
-{
- struct cfpkt *tmp;
- spin_lock(&pktq->lock);
- tmp = skb_to_pkt(skb_peek(&pktq->head));
- spin_unlock(&pktq->lock);
- return tmp;
-}
-EXPORT_SYMBOL(cfpkt_qpeek);
-
-struct cfpkt *cfpkt_dequeue(struct cfpktq *pktq)
-{
- struct cfpkt *pkt;
- spin_lock(&pktq->lock);
- pkt = skb_to_pkt(skb_dequeue(&pktq->head));
- if (pkt) {
- atomic_dec(&pktq->count);
- caif_assert(atomic_read(&pktq->count) >= 0);
- }
- spin_unlock(&pktq->lock);
- return pkt;
-}
-EXPORT_SYMBOL(cfpkt_dequeue);
-
-int cfpkt_qcount(struct cfpktq *pktq)
-{
- return atomic_read(&pktq->count);
-}
-EXPORT_SYMBOL(cfpkt_qcount);
-
-struct cfpkt *cfpkt_clone_release(struct cfpkt *pkt)
-{
- struct cfpkt *clone;
- clone = skb_to_pkt(skb_clone(pkt_to_skb(pkt), GFP_ATOMIC));
- /* Free original packet. */
- cfpkt_destroy(pkt);
- if (!clone)
- return NULL;
- return clone;
-}
-EXPORT_SYMBOL(cfpkt_clone_release);
struct caif_payload_info *cfpkt_info(struct cfpkt *pkt)
{
return (struct caif_payload_info *)&pkt_to_skb(pkt)->cb;
}
-EXPORT_SYMBOL(cfpkt_info);
diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c
index e2fb5fa7579..0deabb44005 100644
--- a/net/caif/cfrfml.c
+++ b/net/caif/cfrfml.c
@@ -31,9 +31,9 @@ struct cfrfml {
spinlock_t sync;
};
-static void cfrfml_release(struct kref *kref)
+static void cfrfml_release(struct cflayer *layer)
{
- struct cfsrvl *srvl = container_of(kref, struct cfsrvl, ref);
+ struct cfsrvl *srvl = container_of(layer, struct cfsrvl, layer);
struct cfrfml *rfml = container_obj(&srvl->layer);
if (rfml->incomplete_frm)
diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c
index 8303fe3ebf8..2715c84cfa8 100644
--- a/net/caif/cfserl.c
+++ b/net/caif/cfserl.c
@@ -179,15 +179,10 @@ static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt)
static int cfserl_transmit(struct cflayer *layer, struct cfpkt *newpkt)
{
struct cfserl *layr = container_obj(layer);
- int ret;
u8 tmp8 = CFSERL_STX;
if (layr->usestx)
cfpkt_add_head(newpkt, &tmp8, 1);
- ret = layer->dn->transmit(layer->dn, newpkt);
- if (ret < 0)
- cfpkt_extr_head(newpkt, &tmp8, 1);
-
- return ret;
+ return layer->dn->transmit(layer->dn, newpkt);
}
static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
diff --git a/net/caif/cfsrvl.c b/net/caif/cfsrvl.c
index ab5e542526b..535a1e72b36 100644
--- a/net/caif/cfsrvl.c
+++ b/net/caif/cfsrvl.c
@@ -10,6 +10,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/slab.h>
+#include <linux/module.h>
#include <net/caif/caif_layer.h>
#include <net/caif/cfsrvl.h>
#include <net/caif/cfpkt.h>
@@ -27,8 +28,8 @@ static void cfservl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
{
struct cfsrvl *service = container_obj(layr);
- caif_assert(layr->up != NULL);
- caif_assert(layr->up->ctrlcmd != NULL);
+ if (layr->up == NULL || layr->up->ctrlcmd == NULL)
+ return;
switch (ctrl) {
case CAIF_CTRLCMD_INIT_RSP:
@@ -151,14 +152,9 @@ static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl)
return -EINVAL;
}
-void cfservl_destroy(struct cflayer *layer)
+static void cfsrvl_release(struct cflayer *layer)
{
- kfree(layer);
-}
-
-void cfsrvl_release(struct kref *kref)
-{
- struct cfsrvl *service = container_of(kref, struct cfsrvl, ref);
+ struct cfsrvl *service = container_of(layer, struct cfsrvl, layer);
kfree(service);
}
@@ -178,10 +174,8 @@ void cfsrvl_init(struct cfsrvl *service,
service->dev_info = *dev_info;
service->supports_flowctrl = supports_flowctrl;
service->release = cfsrvl_release;
- kref_init(&service->ref);
}
-
bool cfsrvl_ready(struct cfsrvl *service, int *err)
{
if (service->open && service->modem_flow_on && service->phy_flow_on)
@@ -194,6 +188,7 @@ bool cfsrvl_ready(struct cfsrvl *service, int *err)
*err = -EAGAIN;
return false;
}
+
u8 cfsrvl_getphyid(struct cflayer *layer)
{
struct cfsrvl *servl = container_obj(layer);
@@ -205,3 +200,26 @@ bool cfsrvl_phyid_match(struct cflayer *layer, int phyid)
struct cfsrvl *servl = container_obj(layer);
return servl->dev_info.id == phyid;
}
+
+void caif_free_client(struct cflayer *adap_layer)
+{
+ struct cfsrvl *servl;
+ if (adap_layer == NULL || adap_layer->dn == NULL)
+ return;
+ servl = container_obj(adap_layer->dn);
+ servl->release(&servl->layer);
+}
+EXPORT_SYMBOL(caif_free_client);
+
+void caif_client_register_refcnt(struct cflayer *adapt_layer,
+ void (*hold)(struct cflayer *lyr),
+ void (*put)(struct cflayer *lyr))
+{
+ struct cfsrvl *service;
+ service = container_of(adapt_layer->dn, struct cfsrvl, layer);
+
+ WARN_ON(adapt_layer == NULL || adapt_layer->dn == NULL);
+ service->hold = hold;
+ service->put = put;
+}
+EXPORT_SYMBOL(caif_client_register_refcnt);
diff --git a/net/caif/cfutill.c b/net/caif/cfutill.c
index 315c0d60136..98e027db18e 100644
--- a/net/caif/cfutill.c
+++ b/net/caif/cfutill.c
@@ -100,10 +100,5 @@ static int cfutill_transmit(struct cflayer *layr, struct cfpkt *pkt)
*/
info->hdr_len = 1;
info->dev_info = &service->dev_info;
- ret = layr->dn->transmit(layr->dn, pkt);
- if (ret < 0) {
- u32 tmp32;
- cfpkt_extr_head(pkt, &tmp32, 4);
- }
- return ret;
+ return layr->dn->transmit(layr->dn, pkt);
}
diff --git a/net/caif/cfveil.c b/net/caif/cfveil.c
index c3b1dec4acf..3ec83fbc288 100644
--- a/net/caif/cfveil.c
+++ b/net/caif/cfveil.c
@@ -82,13 +82,14 @@ static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt)
int ret;
struct cfsrvl *service = container_obj(layr);
if (!cfsrvl_ready(service, &ret))
- return ret;
+ goto err;
caif_assert(layr->dn != NULL);
caif_assert(layr->dn->transmit != NULL);
if (cfpkt_add_head(pkt, &tmp, 1) < 0) {
pr_err("Packet is erroneous!\n");
- return -EPROTO;
+ ret = -EPROTO;
+ goto err;
}
/* Add info-> for MUX-layer to route the packet out. */
@@ -96,8 +97,8 @@ static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt)
info->channel_id = service->layer.id;
info->hdr_len = 1;
info->dev_info = &service->dev_info;
- ret = layr->dn->transmit(layr->dn, pkt);
- if (ret < 0)
- cfpkt_extr_head(pkt, &tmp, 1);
+ return layr->dn->transmit(layr->dn, pkt);
+err:
+ cfpkt_destroy(pkt);
return ret;
}
diff --git a/net/caif/cfvidl.c b/net/caif/cfvidl.c
index bf6fef2a0ef..b2f5989ad45 100644
--- a/net/caif/cfvidl.c
+++ b/net/caif/cfvidl.c
@@ -60,8 +60,5 @@ static int cfvidl_transmit(struct cflayer *layr, struct cfpkt *pkt)
info = cfpkt_info(pkt);
info->channel_id = service->layer.id;
info->dev_info = &service->dev_info;
- ret = layr->dn->transmit(layr->dn, pkt);
- if (ret < 0)
- cfpkt_extr_head(pkt, &videoheader, 4);
- return ret;
+ return layr->dn->transmit(layr->dn, pkt);
}
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
index 6008d6dc18a..649ebacaf6b 100644
--- a/net/caif/chnl_net.c
+++ b/net/caif/chnl_net.c
@@ -20,7 +20,6 @@
#include <linux/caif/if_caif.h>
#include <net/rtnetlink.h>
#include <net/caif/caif_layer.h>
-#include <net/caif/cfcnfg.h>
#include <net/caif/cfpkt.h>
#include <net/caif/caif_dev.h>
@@ -84,10 +83,11 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
if (!priv)
return -EINVAL;
+ skb = (struct sk_buff *) cfpkt_tonative(pkt);
+
/* Get length of CAIF packet. */
- pktlen = cfpkt_getlen(pkt);
+ pktlen = skb->len;
- skb = (struct sk_buff *) cfpkt_tonative(pkt);
/* Pass some minimum information and
* send the packet to the net stack.
*/
@@ -153,6 +153,18 @@ static void close_work(struct work_struct *work)
}
static DECLARE_WORK(close_worker, close_work);
+static void chnl_hold(struct cflayer *lyr)
+{
+ struct chnl_net *priv = container_of(lyr, struct chnl_net, chnl);
+ dev_hold(priv->netdev);
+}
+
+static void chnl_put(struct cflayer *lyr)
+{
+ struct chnl_net *priv = container_of(lyr, struct chnl_net, chnl);
+ dev_put(priv->netdev);
+}
+
static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow,
int phyid)
{
@@ -190,6 +202,7 @@ static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow,
netif_wake_queue(priv->netdev);
break;
case CAIF_CTRLCMD_INIT_RSP:
+ caif_client_register_refcnt(&priv->chnl, chnl_hold, chnl_put);
priv->state = CAIF_CONNECTED;
priv->flowenabled = true;
netif_wake_queue(priv->netdev);
@@ -257,8 +270,9 @@ static int chnl_net_open(struct net_device *dev)
if (priv->state != CAIF_CONNECTING) {
priv->state = CAIF_CONNECTING;
- result = caif_connect_client(&priv->conn_req, &priv->chnl,
- &llifindex, &headroom, &tailroom);
+ result = caif_connect_client(dev_net(dev), &priv->conn_req,
+ &priv->chnl, &llifindex,
+ &headroom, &tailroom);
if (result != 0) {
pr_debug("err: "
"Unable to register and open device,"
@@ -314,7 +328,7 @@ static int chnl_net_open(struct net_device *dev)
if (result == 0) {
pr_debug("connect timeout\n");
- caif_disconnect_client(&priv->chnl);
+ caif_disconnect_client(dev_net(dev), &priv->chnl);
priv->state = CAIF_DISCONNECTED;
pr_debug("state disconnected\n");
result = -ETIMEDOUT;
@@ -330,7 +344,7 @@ static int chnl_net_open(struct net_device *dev)
return 0;
error:
- caif_disconnect_client(&priv->chnl);
+ caif_disconnect_client(dev_net(dev), &priv->chnl);
priv->state = CAIF_DISCONNECTED;
pr_debug("state disconnected\n");
return result;
@@ -344,7 +358,7 @@ static int chnl_net_stop(struct net_device *dev)
ASSERT_RTNL();
priv = netdev_priv(dev);
priv->state = CAIF_DISCONNECTED;
- caif_disconnect_client(&priv->chnl);
+ caif_disconnect_client(dev_net(dev), &priv->chnl);
return 0;
}
@@ -373,11 +387,18 @@ static const struct net_device_ops netdev_ops = {
.ndo_start_xmit = chnl_net_start_xmit,
};
+static void chnl_net_destructor(struct net_device *dev)
+{
+ struct chnl_net *priv = netdev_priv(dev);
+ caif_free_client(&priv->chnl);
+ free_netdev(dev);
+}
+
static void ipcaif_net_setup(struct net_device *dev)
{
struct chnl_net *priv;
dev->netdev_ops = &netdev_ops;
- dev->destructor = free_netdev;
+ dev->destructor = chnl_net_destructor;
dev->flags |= IFF_NOARP;
dev->flags |= IFF_POINTOPOINT;
dev->mtu = GPRS_PDP_MTU;
@@ -391,7 +412,7 @@ static void ipcaif_net_setup(struct net_device *dev)
priv->conn_req.link_selector = CAIF_LINK_HIGH_BANDW;
priv->conn_req.priority = CAIF_PRIO_LOW;
/* Insert illegal value */
- priv->conn_req.sockaddr.u.dgm.connection_id = -1;
+ priv->conn_req.sockaddr.u.dgm.connection_id = 0;
priv->flowenabled = false;
init_waitqueue_head(&priv->netmgmt_wq);
@@ -453,6 +474,10 @@ static int ipcaif_newlink(struct net *src_net, struct net_device *dev,
pr_warn("device rtml registration failed\n");
else
list_add(&caifdev->list_field, &chnl_net_list);
+
+ /* Take ifindex as connection-id if null */
+ if (caifdev->conn_req.sockaddr.u.dgm.connection_id == 0)
+ caifdev->conn_req.sockaddr.u.dgm.connection_id = dev->ifindex;
return ret;
}
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 733d66f1b05..094fc5332d4 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -84,8 +84,8 @@ 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);
+static const struct can_proto *proto_tab[CAN_NPROTO] __read_mostly;
+static DEFINE_MUTEX(proto_tab_lock);
struct timer_list can_stattimer; /* timer for statistics update */
struct s_stats can_stats; /* packet statistics */
@@ -115,11 +115,29 @@ static void can_sock_destruct(struct sock *sk)
skb_queue_purge(&sk->sk_receive_queue);
}
+static const struct can_proto *can_get_proto(int protocol)
+{
+ const struct can_proto *cp;
+
+ rcu_read_lock();
+ cp = rcu_dereference(proto_tab[protocol]);
+ if (cp && !try_module_get(cp->prot->owner))
+ cp = NULL;
+ rcu_read_unlock();
+
+ return cp;
+}
+
+static inline void can_put_proto(const struct can_proto *cp)
+{
+ module_put(cp->prot->owner);
+}
+
static int can_create(struct net *net, struct socket *sock, int protocol,
int kern)
{
struct sock *sk;
- struct can_proto *cp;
+ const struct can_proto *cp;
int err = 0;
sock->state = SS_UNCONNECTED;
@@ -130,9 +148,12 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
if (!net_eq(net, &init_net))
return -EAFNOSUPPORT;
+ cp = can_get_proto(protocol);
+
#ifdef CONFIG_MODULES
- /* try to load protocol module kernel is modular */
- if (!proto_tab[protocol]) {
+ if (!cp) {
+ /* try to load protocol module if kernel is modular */
+
err = request_module("can-proto-%d", protocol);
/*
@@ -143,22 +164,18 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
if (err && printk_ratelimit())
printk(KERN_ERR "can: request_module "
"(can-proto-%d) failed.\n", protocol);
+
+ cp = can_get_proto(protocol);
}
#endif
- 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;
+ err = -EPROTOTYPE;
goto errout;
}
@@ -183,7 +200,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
}
errout:
- module_put(cp->prot->owner);
+ can_put_proto(cp);
return err;
}
@@ -679,7 +696,7 @@ drop:
* -EBUSY protocol already in use
* -ENOBUF if proto_register() fails
*/
-int can_proto_register(struct can_proto *cp)
+int can_proto_register(const struct can_proto *cp)
{
int proto = cp->protocol;
int err = 0;
@@ -694,15 +711,16 @@ int can_proto_register(struct can_proto *cp)
if (err < 0)
return err;
- spin_lock(&proto_tab_lock);
+ mutex_lock(&proto_tab_lock);
+
if (proto_tab[proto]) {
printk(KERN_ERR "can: protocol %d already registered\n",
proto);
err = -EBUSY;
} else
- proto_tab[proto] = cp;
+ rcu_assign_pointer(proto_tab[proto], cp);
- spin_unlock(&proto_tab_lock);
+ mutex_unlock(&proto_tab_lock);
if (err < 0)
proto_unregister(cp->prot);
@@ -715,17 +733,16 @@ 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)
+void can_proto_unregister(const 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_tab[proto] = NULL;
- spin_unlock(&proto_tab_lock);
+ mutex_lock(&proto_tab_lock);
+ BUG_ON(proto_tab[proto] != cp);
+ rcu_assign_pointer(proto_tab[proto], NULL);
+ mutex_unlock(&proto_tab_lock);
+
+ synchronize_rcu();
proto_unregister(cp->prot);
}
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 8a6a05e7c3c..cced806098a 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -1601,7 +1601,7 @@ static struct proto bcm_proto __read_mostly = {
.init = bcm_init,
};
-static struct can_proto bcm_can_proto __read_mostly = {
+static const struct can_proto bcm_can_proto = {
.type = SOCK_DGRAM,
.protocol = CAN_BCM,
.ops = &bcm_ops,
diff --git a/net/can/raw.c b/net/can/raw.c
index 0eb39a7fdf6..dea99a6e596 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -774,7 +774,7 @@ static struct proto raw_proto __read_mostly = {
.init = raw_init,
};
-static struct can_proto raw_can_proto __read_mostly = {
+static const struct can_proto raw_can_proto = {
.type = SOCK_RAW,
.protocol = CAN_RAW,
.ops = &raw_ops,
diff --git a/net/compat.c b/net/compat.c
index 3649d589536..c578d9382e1 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -722,11 +722,11 @@ EXPORT_SYMBOL(compat_mc_getsockopt);
/* Argument list sizes for compat_sys_socketcall */
#define AL(x) ((x) * sizeof(u32))
-static unsigned char nas[20] = {
+static unsigned char nas[21] = {
AL(0), AL(3), AL(3), AL(3), AL(2), AL(3),
AL(3), AL(3), AL(4), AL(4), AL(4), AL(6),
AL(6), AL(2), AL(5), AL(5), AL(3), AL(3),
- AL(4), AL(5)
+ AL(4), AL(5), AL(4)
};
#undef AL
@@ -735,6 +735,13 @@ asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, uns
return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
}
+asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg,
+ unsigned vlen, unsigned int flags)
+{
+ return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
+ flags | MSG_CMSG_COMPAT);
+}
+
asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags)
{
return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
@@ -780,7 +787,7 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
u32 a[6];
u32 a0, a1;
- if (call < SYS_SOCKET || call > SYS_RECVMMSG)
+ if (call < SYS_SOCKET || call > SYS_SENDMMSG)
return -EINVAL;
if (copy_from_user(a, args, nas[call]))
return -EFAULT;
@@ -839,6 +846,9 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
case SYS_SENDMSG:
ret = compat_sys_sendmsg(a0, compat_ptr(a1), a[2]);
break;
+ case SYS_SENDMMSG:
+ ret = compat_sys_sendmmsg(a0, compat_ptr(a1), a[2], a[3]);
+ break;
case SYS_RECVMSG:
ret = compat_sys_recvmsg(a0, compat_ptr(a1), a[2]);
break;
diff --git a/net/core/dev.c b/net/core/dev.c
index b624fe4d9bd..d94537914a7 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -948,7 +948,7 @@ int dev_alloc_name(struct net_device *dev, const char *name)
}
EXPORT_SYMBOL(dev_alloc_name);
-static int dev_get_valid_name(struct net_device *dev, const char *name, bool fmt)
+static int dev_get_valid_name(struct net_device *dev, const char *name)
{
struct net *net;
@@ -958,7 +958,7 @@ static int dev_get_valid_name(struct net_device *dev, const char *name, bool fmt
if (!dev_valid_name(name))
return -EINVAL;
- if (fmt && strchr(name, '%'))
+ if (strchr(name, '%'))
return dev_alloc_name(dev, name);
else if (__dev_get_by_name(net, name))
return -EEXIST;
@@ -995,7 +995,7 @@ int dev_change_name(struct net_device *dev, const char *newname)
memcpy(oldname, dev->name, IFNAMSIZ);
- err = dev_get_valid_name(dev, newname, 1);
+ err = dev_get_valid_name(dev, newname);
if (err < 0)
return err;
@@ -1007,7 +1007,7 @@ rollback:
}
write_lock_bh(&dev_base_lock);
- hlist_del(&dev->name_hlist);
+ hlist_del_rcu(&dev->name_hlist);
write_unlock_bh(&dev_base_lock);
synchronize_rcu();
@@ -1317,7 +1317,8 @@ void dev_disable_lro(struct net_device *dev)
return;
__ethtool_set_flags(dev, flags & ~ETH_FLAG_LRO);
- WARN_ON(dev->features & NETIF_F_LRO);
+ if (unlikely(dev->features & NETIF_F_LRO))
+ netdev_WARN(dev, "failed to disable LRO!\n");
}
EXPORT_SYMBOL(dev_disable_lro);
@@ -2504,8 +2505,8 @@ static inline void ____napi_schedule(struct softnet_data *sd,
__u32 __skb_get_rxhash(struct sk_buff *skb)
{
int nhoff, hash = 0, poff;
- struct ipv6hdr *ip6;
- struct iphdr *ip;
+ const struct ipv6hdr *ip6;
+ const struct iphdr *ip;
u8 ip_proto;
u32 addr1, addr2, ihl;
union {
@@ -2520,7 +2521,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb)
if (!pskb_may_pull(skb, sizeof(*ip) + nhoff))
goto done;
- ip = (struct iphdr *) (skb->data + nhoff);
+ ip = (const struct iphdr *) (skb->data + nhoff);
if (ip->frag_off & htons(IP_MF | IP_OFFSET))
ip_proto = 0;
else
@@ -2533,7 +2534,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb)
if (!pskb_may_pull(skb, sizeof(*ip6) + nhoff))
goto done;
- ip6 = (struct ipv6hdr *) (skb->data + nhoff);
+ ip6 = (const struct ipv6hdr *) (skb->data + nhoff);
ip_proto = ip6->nexthdr;
addr1 = (__force u32) ip6->saddr.s6_addr32[3];
addr2 = (__force u32) ip6->daddr.s6_addr32[3];
@@ -3078,25 +3079,6 @@ void netdev_rx_handler_unregister(struct net_device *dev)
}
EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
-static void vlan_on_bond_hook(struct sk_buff *skb)
-{
- /*
- * Make sure ARP frames received on VLAN interfaces stacked on
- * bonding interfaces still make their way to any base bonding
- * device that may have registered for a specific ptype.
- */
- if (skb->dev->priv_flags & IFF_802_1Q_VLAN &&
- vlan_dev_real_dev(skb->dev)->priv_flags & IFF_BONDING &&
- skb->protocol == htons(ETH_P_ARP)) {
- struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
-
- if (!skb2)
- return;
- skb2->dev = vlan_dev_real_dev(skb->dev);
- netif_rx(skb2);
- }
-}
-
static int __netif_receive_skb(struct sk_buff *skb)
{
struct packet_type *ptype, *pt_prev;
@@ -3132,6 +3114,12 @@ another_round:
__this_cpu_inc(softnet_data.processed);
+ if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) {
+ skb = vlan_untag(skb);
+ if (unlikely(!skb))
+ goto out;
+ }
+
#ifdef CONFIG_NET_CLS_ACT
if (skb->tc_verd & TC_NCLS) {
skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
@@ -3179,15 +3167,13 @@ ncls:
ret = deliver_skb(skb, pt_prev, orig_dev);
pt_prev = NULL;
}
- if (vlan_hwaccel_do_receive(&skb)) {
+ if (vlan_do_receive(&skb)) {
ret = __netif_receive_skb(skb);
goto out;
} else if (unlikely(!skb))
goto out;
}
- vlan_on_bond_hook(skb);
-
/* deliver only exact match when indicated */
null_or_dev = deliver_exact ? skb->dev : NULL;
@@ -4512,6 +4498,30 @@ void dev_set_rx_mode(struct net_device *dev)
}
/**
+ * dev_ethtool_get_settings - call device's ethtool_ops::get_settings()
+ * @dev: device
+ * @cmd: memory area for ethtool_ops::get_settings() result
+ *
+ * The cmd arg is initialized properly (cleared and
+ * ethtool_cmd::cmd field set to ETHTOOL_GSET).
+ *
+ * Return device's ethtool_ops::get_settings() result value or
+ * -EOPNOTSUPP when device doesn't expose
+ * ethtool_ops::get_settings() operation.
+ */
+int dev_ethtool_get_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
+ return -EOPNOTSUPP;
+
+ memset(cmd, 0, sizeof(struct ethtool_cmd));
+ cmd->cmd = ETHTOOL_GSET;
+ return dev->ethtool_ops->get_settings(dev, cmd);
+}
+EXPORT_SYMBOL(dev_ethtool_get_settings);
+
+/**
* dev_get_flags - get flags reported to userspace
* @dev: device
*
@@ -5116,7 +5126,7 @@ static void rollback_registered_many(struct list_head *head)
list_del(&dev->unreg_list);
continue;
}
-
+ dev->dismantle = true;
BUG_ON(dev->reg_state != NETREG_REGISTERED);
}
@@ -5242,11 +5252,13 @@ u32 netdev_fix_features(struct net_device *dev, u32 features)
}
EXPORT_SYMBOL(netdev_fix_features);
-void netdev_update_features(struct net_device *dev)
+int __netdev_update_features(struct net_device *dev)
{
u32 features;
int err = 0;
+ ASSERT_RTNL();
+
features = netdev_get_wanted_features(dev);
if (dev->netdev_ops->ndo_fix_features)
@@ -5256,24 +5268,60 @@ void netdev_update_features(struct net_device *dev)
features = netdev_fix_features(dev, features);
if (dev->features == features)
- return;
+ return 0;
- netdev_info(dev, "Features changed: 0x%08x -> 0x%08x\n",
+ netdev_dbg(dev, "Features changed: 0x%08x -> 0x%08x\n",
dev->features, features);
if (dev->netdev_ops->ndo_set_features)
err = dev->netdev_ops->ndo_set_features(dev, features);
- if (!err)
- dev->features = features;
- else if (err < 0)
+ if (unlikely(err < 0)) {
netdev_err(dev,
"set_features() failed (%d); wanted 0x%08x, left 0x%08x\n",
err, features, dev->features);
+ return -1;
+ }
+
+ if (!err)
+ dev->features = features;
+
+ return 1;
+}
+
+/**
+ * netdev_update_features - recalculate device features
+ * @dev: the device to check
+ *
+ * Recalculate dev->features set and send notifications if it
+ * has changed. Should be called after driver or hardware dependent
+ * conditions might have changed that influence the features.
+ */
+void netdev_update_features(struct net_device *dev)
+{
+ if (__netdev_update_features(dev))
+ netdev_features_change(dev);
}
EXPORT_SYMBOL(netdev_update_features);
/**
+ * netdev_change_features - recalculate device features
+ * @dev: the device to check
+ *
+ * Recalculate dev->features set and send notifications even
+ * if they have not changed. Should be called instead of
+ * netdev_update_features() if also dev->vlan_features might
+ * have changed to allow the changes to be propagated to stacked
+ * VLAN devices.
+ */
+void netdev_change_features(struct net_device *dev)
+{
+ __netdev_update_features(dev);
+ netdev_features_change(dev);
+}
+EXPORT_SYMBOL(netdev_change_features);
+
+/**
* netif_stacked_transfer_operstate - transfer operstate
* @rootdev: the root or lower level device to transfer state from
* @dev: the device to transfer operstate to
@@ -5389,6 +5437,10 @@ int register_netdevice(struct net_device *dev)
dev->iflink = -1;
+ ret = dev_get_valid_name(dev, dev->name);
+ if (ret < 0)
+ goto out;
+
/* Init, if this function is available */
if (dev->netdev_ops->ndo_init) {
ret = dev->netdev_ops->ndo_init(dev);
@@ -5399,10 +5451,6 @@ int register_netdevice(struct net_device *dev)
}
}
- ret = dev_get_valid_name(dev, dev->name, 0);
- if (ret)
- goto err_uninit;
-
dev->ifindex = dev_new_index(net);
if (dev->iflink == -1)
dev->iflink = dev->ifindex;
@@ -5414,6 +5462,14 @@ int register_netdevice(struct net_device *dev)
dev->features |= NETIF_F_SOFT_FEATURES;
dev->wanted_features = dev->features & dev->hw_features;
+ /* Turn on no cache copy if HW is doing checksum */
+ dev->hw_features |= NETIF_F_NOCACHE_COPY;
+ if ((dev->features & NETIF_F_ALL_CSUM) &&
+ !(dev->features & NETIF_F_NO_CSUM)) {
+ dev->wanted_features |= NETIF_F_NOCACHE_COPY;
+ dev->features |= NETIF_F_NOCACHE_COPY;
+ }
+
/* Enable GRO and NETIF_F_HIGHDMA for vlans by default,
* vlan_dev_init() will do the dev->features check, so these features
* are enabled only if supported by underlying device.
@@ -5430,7 +5486,7 @@ int register_netdevice(struct net_device *dev)
goto err_uninit;
dev->reg_state = NETREG_REGISTERED;
- netdev_update_features(dev);
+ __netdev_update_features(dev);
/*
* Default initial state at registry is that the
@@ -5527,19 +5583,7 @@ int register_netdev(struct net_device *dev)
int err;
rtnl_lock();
-
- /*
- * If the name is a format string the caller wants us to do a
- * name allocation.
- */
- if (strchr(dev->name, '%')) {
- err = dev_alloc_name(dev, dev->name);
- if (err < 0)
- goto out;
- }
-
err = register_netdevice(dev);
-out:
rtnl_unlock();
return err;
}
@@ -6021,7 +6065,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
/* We get here if we can't use the current device name */
if (!pat)
goto out;
- if (dev_get_valid_name(dev, pat, 1))
+ if (dev_get_valid_name(dev, pat) < 0)
goto out;
}
@@ -6153,29 +6197,20 @@ static int dev_cpu_callback(struct notifier_block *nfb,
*/
u32 netdev_increment_features(u32 all, u32 one, u32 mask)
{
- /* If device needs checksumming, downgrade to it. */
- if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM))
- all ^= NETIF_F_NO_CSUM | (one & NETIF_F_ALL_CSUM);
- else if (mask & NETIF_F_ALL_CSUM) {
- /* If one device supports v4/v6 checksumming, set for all. */
- if (one & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM) &&
- !(all & NETIF_F_GEN_CSUM)) {
- all &= ~NETIF_F_ALL_CSUM;
- all |= one & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
- }
+ if (mask & NETIF_F_GEN_CSUM)
+ mask |= NETIF_F_ALL_CSUM;
+ mask |= NETIF_F_VLAN_CHALLENGED;
- /* If one device supports hw checksumming, set for all. */
- if (one & NETIF_F_GEN_CSUM && !(all & NETIF_F_GEN_CSUM)) {
- all &= ~NETIF_F_ALL_CSUM;
- all |= NETIF_F_HW_CSUM;
- }
- }
+ all |= one & (NETIF_F_ONE_FOR_ALL|NETIF_F_ALL_CSUM) & mask;
+ all &= one | ~NETIF_F_ALL_FOR_ALL;
- one |= NETIF_F_ALL_CSUM;
+ /* If device needs checksumming, downgrade to it. */
+ if (all & (NETIF_F_ALL_CSUM & ~NETIF_F_NO_CSUM))
+ all &= ~NETIF_F_NO_CSUM;
- one |= all & NETIF_F_ONE_FOR_ALL;
- all &= one | NETIF_F_LLTX | NETIF_F_GSO | NETIF_F_UFO;
- all |= one & mask & NETIF_F_ONE_FOR_ALL;
+ /* If one device supports hw checksumming, set for all. */
+ if (all & NETIF_F_GEN_CSUM)
+ all &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
return all;
}
diff --git a/net/core/dst.c b/net/core/dst.c
index 0a3920bf361..81a4fa1c95e 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -34,9 +34,6 @@
* 3) This list is guarded by a mutex,
* so that the gc_task and dst_dev_event() can be synchronized.
*/
-#if RT_CACHE_DEBUG >= 2
-static atomic_t dst_total = ATOMIC_INIT(0);
-#endif
/*
* We want to keep lock & list close together
@@ -70,10 +67,6 @@ static void dst_gc_task(struct work_struct *work)
unsigned long expires = ~0L;
struct dst_entry *dst, *next, head;
struct dst_entry *last = &head;
-#if RT_CACHE_DEBUG >= 2
- ktime_t time_start = ktime_get();
- struct timespec elapsed;
-#endif
mutex_lock(&dst_gc_mutex);
next = dst_busy_list;
@@ -147,15 +140,6 @@ loop:
spin_unlock_bh(&dst_garbage.lock);
mutex_unlock(&dst_gc_mutex);
-#if RT_CACHE_DEBUG >= 2
- elapsed = ktime_to_timespec(ktime_sub(ktime_get(), time_start));
- printk(KERN_DEBUG "dst_total: %d delayed: %d work_perf: %d"
- " expires: %lu elapsed: %lu us\n",
- atomic_read(&dst_total), delayed, work_performed,
- expires,
- elapsed.tv_sec * USEC_PER_SEC +
- elapsed.tv_nsec / NSEC_PER_USEC);
-#endif
}
int dst_discard(struct sk_buff *skb)
@@ -167,7 +151,8 @@ EXPORT_SYMBOL(dst_discard);
const u32 dst_default_metrics[RTAX_MAX];
-void *dst_alloc(struct dst_ops *ops, int initial_ref)
+void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
+ int initial_ref, int initial_obsolete, int flags)
{
struct dst_entry *dst;
@@ -175,18 +160,36 @@ void *dst_alloc(struct dst_ops *ops, int initial_ref)
if (ops->gc(ops))
return NULL;
}
- dst = kmem_cache_zalloc(ops->kmem_cachep, GFP_ATOMIC);
+ dst = kmem_cache_alloc(ops->kmem_cachep, GFP_ATOMIC);
if (!dst)
return NULL;
- atomic_set(&dst->__refcnt, initial_ref);
+ dst->child = NULL;
+ dst->dev = dev;
+ if (dev)
+ dev_hold(dev);
dst->ops = ops;
- dst->lastuse = jiffies;
- dst->path = dst;
- dst->input = dst->output = dst_discard;
dst_init_metrics(dst, dst_default_metrics, true);
-#if RT_CACHE_DEBUG >= 2
- atomic_inc(&dst_total);
+ dst->expires = 0UL;
+ dst->path = dst;
+ dst->neighbour = NULL;
+ dst->hh = NULL;
+#ifdef CONFIG_XFRM
+ dst->xfrm = NULL;
+#endif
+ dst->input = dst_discard;
+ dst->output = dst_discard;
+ dst->error = 0;
+ dst->obsolete = initial_obsolete;
+ dst->header_len = 0;
+ dst->trailer_len = 0;
+#ifdef CONFIG_IP_ROUTE_CLASSID
+ dst->tclassid = 0;
#endif
+ atomic_set(&dst->__refcnt, initial_ref);
+ dst->__use = 0;
+ dst->lastuse = jiffies;
+ dst->flags = flags;
+ dst->next = NULL;
dst_entries_add(ops, 1);
return dst;
}
@@ -246,9 +249,6 @@ again:
dst->ops->destroy(dst);
if (dst->dev)
dev_put(dst->dev);
-#if RT_CACHE_DEBUG >= 2
- atomic_dec(&dst_total);
-#endif
kmem_cache_free(dst->ops->kmem_cachep, dst);
dst = child;
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 74ead9eca12..84e7304532e 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -21,6 +21,8 @@
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
+#include <linux/rtnetlink.h>
+#include <linux/sched.h>
/*
* Some useful ethtool_ops methods that're device independent.
@@ -317,7 +319,7 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
dev->wanted_features &= ~features[0].valid;
dev->wanted_features |= features[0].valid & features[0].requested;
- netdev_update_features(dev);
+ __netdev_update_features(dev);
if ((dev->wanted_features ^ dev->features) & features[0].valid)
ret |= ETHTOOL_F_WISH;
@@ -330,7 +332,7 @@ static const char netdev_features_strings[ETHTOOL_DEV_FEATURE_WORDS * 32][ETH_GS
/* NETIF_F_IP_CSUM */ "tx-checksum-ipv4",
/* NETIF_F_NO_CSUM */ "tx-checksum-unneeded",
/* NETIF_F_HW_CSUM */ "tx-checksum-ip-generic",
- /* NETIF_F_IPV6_CSUM */ "tx_checksum-ipv6",
+ /* NETIF_F_IPV6_CSUM */ "tx-checksum-ipv6",
/* NETIF_F_HIGHDMA */ "highdma",
/* NETIF_F_FRAGLIST */ "tx-scatter-gather-fraglist",
/* NETIF_F_HW_VLAN_TX */ "tx-vlan-hw-insert",
@@ -359,8 +361,8 @@ static const char netdev_features_strings[ETHTOOL_DEV_FEATURE_WORDS * 32][ETH_GS
/* NETIF_F_NTUPLE */ "rx-ntuple-filter",
/* NETIF_F_RXHASH */ "rx-hashing",
/* NETIF_F_RXCSUM */ "rx-checksum",
- "",
- "",
+ /* NETIF_F_NOCACHE_COPY */ "tx-nocache-copy",
+ /* NETIF_F_LOOPBACK */ "loopback",
};
static int __ethtool_get_sset_count(struct net_device *dev, int sset)
@@ -499,7 +501,7 @@ static int ethtool_set_one_feature(struct net_device *dev,
else
dev->wanted_features &= ~mask;
- netdev_update_features(dev);
+ __netdev_update_features(dev);
return 0;
}
@@ -544,14 +546,14 @@ int __ethtool_set_flags(struct net_device *dev, u32 data)
}
/* allow changing only bits set in hw_features */
- changed = (data ^ dev->wanted_features) & flags_dup_features;
+ changed = (data ^ dev->features) & flags_dup_features;
if (changed & ~dev->hw_features)
return (changed & dev->hw_features) ? -EINVAL : -EOPNOTSUPP;
dev->wanted_features =
- (dev->wanted_features & ~changed) | data;
+ (dev->wanted_features & ~changed) | (data & dev->hw_features);
- netdev_update_features(dev);
+ __netdev_update_features(dev);
return 0;
}
@@ -908,6 +910,9 @@ static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev,
struct ethtool_rx_ntuple_flow_spec_container *fsc = NULL;
int ret;
+ if (!ops->set_rx_ntuple)
+ return -EOPNOTSUPP;
+
if (!(dev->features & NETIF_F_NTUPLE))
return -EINVAL;
@@ -1441,6 +1446,35 @@ static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr)
return dev->ethtool_ops->set_ringparam(dev, &ringparam);
}
+static noinline_for_stack int ethtool_get_channels(struct net_device *dev,
+ void __user *useraddr)
+{
+ struct ethtool_channels channels = { .cmd = ETHTOOL_GCHANNELS };
+
+ if (!dev->ethtool_ops->get_channels)
+ return -EOPNOTSUPP;
+
+ dev->ethtool_ops->get_channels(dev, &channels);
+
+ if (copy_to_user(useraddr, &channels, sizeof(channels)))
+ return -EFAULT;
+ return 0;
+}
+
+static noinline_for_stack int ethtool_set_channels(struct net_device *dev,
+ void __user *useraddr)
+{
+ struct ethtool_channels channels;
+
+ if (!dev->ethtool_ops->set_channels)
+ return -EOPNOTSUPP;
+
+ if (copy_from_user(&channels, useraddr, sizeof(channels)))
+ return -EFAULT;
+
+ return dev->ethtool_ops->set_channels(dev, &channels);
+}
+
static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr)
{
struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM };
@@ -1618,14 +1652,60 @@ out:
static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
{
struct ethtool_value id;
+ static bool busy;
+ int rc;
- if (!dev->ethtool_ops->phys_id)
+ if (!dev->ethtool_ops->set_phys_id)
return -EOPNOTSUPP;
+ if (busy)
+ return -EBUSY;
+
if (copy_from_user(&id, useraddr, sizeof(id)))
return -EFAULT;
- return dev->ethtool_ops->phys_id(dev, id.data);
+ rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_ACTIVE);
+ if (rc < 0)
+ return rc;
+
+ /* Drop the RTNL lock while waiting, but prevent reentry or
+ * removal of the device.
+ */
+ busy = true;
+ dev_hold(dev);
+ rtnl_unlock();
+
+ if (rc == 0) {
+ /* Driver will handle this itself */
+ schedule_timeout_interruptible(
+ id.data ? (id.data * HZ) : MAX_SCHEDULE_TIMEOUT);
+ } else {
+ /* Driver expects to be called at twice the frequency in rc */
+ int n = rc * 2, i, interval = HZ / n;
+
+ /* Count down seconds */
+ do {
+ /* Count down iterations per second */
+ i = n;
+ do {
+ rtnl_lock();
+ rc = dev->ethtool_ops->set_phys_id(dev,
+ (i & 1) ? ETHTOOL_ID_OFF : ETHTOOL_ID_ON);
+ rtnl_unlock();
+ if (rc)
+ break;
+ schedule_timeout_interruptible(interval);
+ } while (!signal_pending(current) && --i != 0);
+ } while (!signal_pending(current) &&
+ (id.data == 0 || --id.data != 0));
+ }
+
+ rtnl_lock();
+ dev_put(dev);
+ busy = false;
+
+ (void)dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_INACTIVE);
+ return rc;
}
static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
@@ -1743,6 +1823,87 @@ static noinline_for_stack int ethtool_flash_device(struct net_device *dev,
return dev->ethtool_ops->flash_device(dev, &efl);
}
+static int ethtool_set_dump(struct net_device *dev,
+ void __user *useraddr)
+{
+ struct ethtool_dump dump;
+
+ if (!dev->ethtool_ops->set_dump)
+ return -EOPNOTSUPP;
+
+ if (copy_from_user(&dump, useraddr, sizeof(dump)))
+ return -EFAULT;
+
+ return dev->ethtool_ops->set_dump(dev, &dump);
+}
+
+static int ethtool_get_dump_flag(struct net_device *dev,
+ void __user *useraddr)
+{
+ int ret;
+ struct ethtool_dump dump;
+ const struct ethtool_ops *ops = dev->ethtool_ops;
+
+ if (!dev->ethtool_ops->get_dump_flag)
+ return -EOPNOTSUPP;
+
+ if (copy_from_user(&dump, useraddr, sizeof(dump)))
+ return -EFAULT;
+
+ ret = ops->get_dump_flag(dev, &dump);
+ if (ret)
+ return ret;
+
+ if (copy_to_user(useraddr, &dump, sizeof(dump)))
+ return -EFAULT;
+ return 0;
+}
+
+static int ethtool_get_dump_data(struct net_device *dev,
+ void __user *useraddr)
+{
+ int ret;
+ __u32 len;
+ struct ethtool_dump dump, tmp;
+ const struct ethtool_ops *ops = dev->ethtool_ops;
+ void *data = NULL;
+
+ if (!dev->ethtool_ops->get_dump_data ||
+ !dev->ethtool_ops->get_dump_flag)
+ return -EOPNOTSUPP;
+
+ if (copy_from_user(&dump, useraddr, sizeof(dump)))
+ return -EFAULT;
+
+ memset(&tmp, 0, sizeof(tmp));
+ tmp.cmd = ETHTOOL_GET_DUMP_FLAG;
+ ret = ops->get_dump_flag(dev, &tmp);
+ if (ret)
+ return ret;
+
+ len = (tmp.len > dump.len) ? dump.len : tmp.len;
+ if (!len)
+ return -EFAULT;
+
+ data = vzalloc(tmp.len);
+ if (!data)
+ return -ENOMEM;
+ ret = ops->get_dump_data(dev, &dump, data);
+ if (ret)
+ goto out;
+
+ if (copy_to_user(useraddr, &dump, sizeof(dump))) {
+ ret = -EFAULT;
+ goto out;
+ }
+ useraddr += offsetof(struct ethtool_dump, data);
+ if (copy_to_user(useraddr, data, len))
+ ret = -EFAULT;
+out:
+ vfree(data);
+ return ret;
+}
+
/* The main entry point in this file. Called from net/core/dev.c */
int dev_ethtool(struct net *net, struct ifreq *ifr)
@@ -1953,6 +2114,21 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_SGRO:
rc = ethtool_set_one_feature(dev, useraddr, ethcmd);
break;
+ case ETHTOOL_GCHANNELS:
+ rc = ethtool_get_channels(dev, useraddr);
+ break;
+ case ETHTOOL_SCHANNELS:
+ rc = ethtool_set_channels(dev, useraddr);
+ break;
+ case ETHTOOL_SET_DUMP:
+ rc = ethtool_set_dump(dev, useraddr);
+ break;
+ case ETHTOOL_GET_DUMP_FLAG:
+ rc = ethtool_get_dump_flag(dev, useraddr);
+ break;
+ case ETHTOOL_GET_DUMP_DATA:
+ rc = ethtool_get_dump_data(dev, useraddr);
+ break;
default:
rc = -EOPNOTSUPP;
}
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 8248ebb5891..3911586e12e 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -590,7 +590,8 @@ static int dump_rules(struct sk_buff *skb, struct netlink_callback *cb,
int idx = 0;
struct fib_rule *rule;
- list_for_each_entry(rule, &ops->rules_list, list) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(rule, &ops->rules_list, list) {
if (idx < cb->args[1])
goto skip;
diff --git a/net/core/filter.c b/net/core/filter.c
index afb8afb066b..0eb8c4466ea 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -39,65 +39,6 @@
#include <linux/filter.h>
#include <linux/reciprocal_div.h>
-enum {
- BPF_S_RET_K = 1,
- BPF_S_RET_A,
- BPF_S_ALU_ADD_K,
- BPF_S_ALU_ADD_X,
- BPF_S_ALU_SUB_K,
- BPF_S_ALU_SUB_X,
- BPF_S_ALU_MUL_K,
- BPF_S_ALU_MUL_X,
- BPF_S_ALU_DIV_X,
- BPF_S_ALU_AND_K,
- BPF_S_ALU_AND_X,
- BPF_S_ALU_OR_K,
- BPF_S_ALU_OR_X,
- BPF_S_ALU_LSH_K,
- BPF_S_ALU_LSH_X,
- BPF_S_ALU_RSH_K,
- BPF_S_ALU_RSH_X,
- BPF_S_ALU_NEG,
- BPF_S_LD_W_ABS,
- BPF_S_LD_H_ABS,
- BPF_S_LD_B_ABS,
- BPF_S_LD_W_LEN,
- BPF_S_LD_W_IND,
- BPF_S_LD_H_IND,
- BPF_S_LD_B_IND,
- BPF_S_LD_IMM,
- BPF_S_LDX_W_LEN,
- BPF_S_LDX_B_MSH,
- BPF_S_LDX_IMM,
- BPF_S_MISC_TAX,
- BPF_S_MISC_TXA,
- BPF_S_ALU_DIV_K,
- BPF_S_LD_MEM,
- BPF_S_LDX_MEM,
- BPF_S_ST,
- BPF_S_STX,
- BPF_S_JMP_JA,
- BPF_S_JMP_JEQ_K,
- BPF_S_JMP_JEQ_X,
- BPF_S_JMP_JGE_K,
- BPF_S_JMP_JGE_X,
- BPF_S_JMP_JGT_K,
- BPF_S_JMP_JGT_X,
- BPF_S_JMP_JSET_K,
- BPF_S_JMP_JSET_X,
- /* Ancillary data */
- BPF_S_ANC_PROTOCOL,
- BPF_S_ANC_PKTTYPE,
- BPF_S_ANC_IFINDEX,
- BPF_S_ANC_NLATTR,
- BPF_S_ANC_NLATTR_NEST,
- BPF_S_ANC_MARK,
- BPF_S_ANC_QUEUE,
- BPF_S_ANC_HATYPE,
- BPF_S_ANC_RXHASH,
- BPF_S_ANC_CPU,
-};
-
/* No hurry in this branch */
static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size)
{
@@ -145,7 +86,7 @@ int sk_filter(struct sock *sk, struct sk_buff *skb)
rcu_read_lock();
filter = rcu_dereference(sk->sk_filter);
if (filter) {
- unsigned int pkt_len = sk_run_filter(skb, filter->insns);
+ unsigned int pkt_len = SK_RUN_FILTER(filter, skb);
err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM;
}
@@ -638,6 +579,7 @@ void sk_filter_release_rcu(struct rcu_head *rcu)
{
struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
+ bpf_jit_free(fp);
kfree(fp);
}
EXPORT_SYMBOL(sk_filter_release_rcu);
@@ -672,6 +614,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
atomic_set(&fp->refcnt, 1);
fp->len = fprog->len;
+ fp->bpf_func = sk_run_filter;
err = sk_chk_filter(fp->insns, fp->len);
if (err) {
@@ -679,6 +622,8 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
return err;
}
+ bpf_jit_compile(fp);
+
old_fp = rcu_dereference_protected(sk->sk_filter,
sock_owned_by_user(sk));
rcu_assign_pointer(sk->sk_filter, fp);
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 80b2aad3b73..11b98bc2aa8 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -28,6 +28,7 @@
static const char fmt_hex[] = "%#x\n";
static const char fmt_long_hex[] = "%#lx\n";
static const char fmt_dec[] = "%d\n";
+static const char fmt_udec[] = "%u\n";
static const char fmt_ulong[] = "%lu\n";
static const char fmt_u64[] = "%llu\n";
@@ -145,13 +146,10 @@ static ssize_t show_speed(struct device *dev,
if (!rtnl_trylock())
return restart_syscall();
- if (netif_running(netdev) &&
- netdev->ethtool_ops &&
- netdev->ethtool_ops->get_settings) {
- struct ethtool_cmd cmd = { ETHTOOL_GSET };
-
- if (!netdev->ethtool_ops->get_settings(netdev, &cmd))
- ret = sprintf(buf, fmt_dec, ethtool_cmd_speed(&cmd));
+ if (netif_running(netdev)) {
+ struct ethtool_cmd cmd;
+ if (!dev_ethtool_get_settings(netdev, &cmd))
+ ret = sprintf(buf, fmt_udec, ethtool_cmd_speed(&cmd));
}
rtnl_unlock();
return ret;
@@ -166,13 +164,11 @@ static ssize_t show_duplex(struct device *dev,
if (!rtnl_trylock())
return restart_syscall();
- if (netif_running(netdev) &&
- netdev->ethtool_ops &&
- netdev->ethtool_ops->get_settings) {
- struct ethtool_cmd cmd = { ETHTOOL_GSET };
-
- if (!netdev->ethtool_ops->get_settings(netdev, &cmd))
- ret = sprintf(buf, "%s\n", cmd.duplex ? "full" : "half");
+ if (netif_running(netdev)) {
+ struct ethtool_cmd cmd;
+ if (!dev_ethtool_get_settings(netdev, &cmd))
+ ret = sprintf(buf, "%s\n",
+ cmd.duplex ? "full" : "half");
}
rtnl_unlock();
return ret;
@@ -946,7 +942,7 @@ static ssize_t store_xps_map(struct netdev_queue *queue,
} else
pos = map_len = alloc_len = 0;
- need_set = cpu_isset(cpu, *mask) && cpu_online(cpu);
+ need_set = cpumask_test_cpu(cpu, mask) && cpu_online(cpu);
#ifdef CONFIG_NUMA
if (need_set) {
if (numa_node == -2)
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 297bb927224..2e2dce6583e 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -208,11 +208,14 @@ static void net_free(struct net *net)
kmem_cache_free(net_cachep, net);
}
-static struct net *net_create(void)
+struct net *copy_net_ns(unsigned long flags, struct net *old_net)
{
struct net *net;
int rv;
+ if (!(flags & CLONE_NEWNET))
+ return get_net(old_net);
+
net = net_alloc();
if (!net)
return ERR_PTR(-ENOMEM);
@@ -231,13 +234,6 @@ static struct net *net_create(void)
return net;
}
-struct net *copy_net_ns(unsigned long flags, struct net *old_net)
-{
- if (!(flags & CLONE_NEWNET))
- return get_net(old_net);
- return net_create();
-}
-
static DEFINE_SPINLOCK(cleanup_list_lock);
static LIST_HEAD(cleanup_list); /* Must hold cleanup_list_lock to touch */
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 06be2431753..2d7d6d47378 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -539,7 +539,7 @@ int __netpoll_rx(struct sk_buff *skb)
{
int proto, len, ulen;
int hits = 0;
- struct iphdr *iph;
+ const struct iphdr *iph;
struct udphdr *uh;
struct netpoll_info *npinfo = skb->dev->npinfo;
struct netpoll *np, *tmp;
@@ -698,32 +698,8 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
if (*cur != 0) {
/* MAC address */
- if ((delim = strchr(cur, ':')) == NULL)
- goto parse_failed;
- *delim = 0;
- np->remote_mac[0] = simple_strtol(cur, NULL, 16);
- cur = delim + 1;
- if ((delim = strchr(cur, ':')) == NULL)
- goto parse_failed;
- *delim = 0;
- np->remote_mac[1] = simple_strtol(cur, NULL, 16);
- cur = delim + 1;
- if ((delim = strchr(cur, ':')) == NULL)
+ if (!mac_pton(cur, np->remote_mac))
goto parse_failed;
- *delim = 0;
- np->remote_mac[2] = simple_strtol(cur, NULL, 16);
- cur = delim + 1;
- if ((delim = strchr(cur, ':')) == NULL)
- goto parse_failed;
- *delim = 0;
- np->remote_mac[3] = simple_strtol(cur, NULL, 16);
- cur = delim + 1;
- if ((delim = strchr(cur, ':')) == NULL)
- goto parse_failed;
- *delim = 0;
- np->remote_mac[4] = simple_strtol(cur, NULL, 16);
- cur = delim + 1;
- np->remote_mac[5] = simple_strtol(cur, NULL, 16);
}
netpoll_print_options(np);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 6ed9e27d820..67870e9fd09 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -450,7 +450,6 @@ static void pktgen_stop(struct pktgen_thread *t);
static void pktgen_clear_counters(struct pktgen_dev *pkt_dev);
static unsigned int scan_ip6(const char *s, char ip[16]);
-static unsigned int fmt_ip6(char *s, const char ip[16]);
/* Module parameters, defaults. */
static int pg_count_d __read_mostly = 1000;
@@ -557,21 +556,13 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
pkt_dev->skb_priority);
if (pkt_dev->flags & F_IPV6) {
- char b1[128], b2[128], b3[128];
- fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr);
- fmt_ip6(b2, pkt_dev->min_in6_saddr.s6_addr);
- fmt_ip6(b3, pkt_dev->max_in6_saddr.s6_addr);
seq_printf(seq,
- " saddr: %s min_saddr: %s max_saddr: %s\n", b1,
- b2, b3);
-
- fmt_ip6(b1, pkt_dev->in6_daddr.s6_addr);
- fmt_ip6(b2, pkt_dev->min_in6_daddr.s6_addr);
- fmt_ip6(b3, pkt_dev->max_in6_daddr.s6_addr);
- seq_printf(seq,
- " daddr: %s min_daddr: %s max_daddr: %s\n", b1,
- b2, b3);
-
+ " saddr: %pI6c min_saddr: %pI6c max_saddr: %pI6c\n"
+ " daddr: %pI6c min_daddr: %pI6c max_daddr: %pI6c\n",
+ &pkt_dev->in6_saddr,
+ &pkt_dev->min_in6_saddr, &pkt_dev->max_in6_saddr,
+ &pkt_dev->in6_daddr,
+ &pkt_dev->min_in6_daddr, &pkt_dev->max_in6_daddr);
} else {
seq_printf(seq,
" dst_min: %s dst_max: %s\n",
@@ -707,10 +698,9 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
pkt_dev->cur_src_mac_offset);
if (pkt_dev->flags & F_IPV6) {
- char b1[128], b2[128];
- fmt_ip6(b1, pkt_dev->cur_in6_daddr.s6_addr);
- fmt_ip6(b2, pkt_dev->cur_in6_saddr.s6_addr);
- seq_printf(seq, " cur_saddr: %s cur_daddr: %s\n", b2, b1);
+ seq_printf(seq, " cur_saddr: %pI6c cur_daddr: %pI6c\n",
+ &pkt_dev->cur_in6_saddr,
+ &pkt_dev->cur_in6_daddr);
} else
seq_printf(seq, " cur_saddr: 0x%x cur_daddr: 0x%x\n",
pkt_dev->cur_saddr, pkt_dev->cur_daddr);
@@ -1310,7 +1300,7 @@ static ssize_t pktgen_if_write(struct file *file,
buf[len] = 0;
scan_ip6(buf, pkt_dev->in6_daddr.s6_addr);
- fmt_ip6(buf, pkt_dev->in6_daddr.s6_addr);
+ snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_daddr);
ipv6_addr_copy(&pkt_dev->cur_in6_daddr, &pkt_dev->in6_daddr);
@@ -1333,7 +1323,7 @@ static ssize_t pktgen_if_write(struct file *file,
buf[len] = 0;
scan_ip6(buf, pkt_dev->min_in6_daddr.s6_addr);
- fmt_ip6(buf, pkt_dev->min_in6_daddr.s6_addr);
+ snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->min_in6_daddr);
ipv6_addr_copy(&pkt_dev->cur_in6_daddr,
&pkt_dev->min_in6_daddr);
@@ -1356,7 +1346,7 @@ static ssize_t pktgen_if_write(struct file *file,
buf[len] = 0;
scan_ip6(buf, pkt_dev->max_in6_daddr.s6_addr);
- fmt_ip6(buf, pkt_dev->max_in6_daddr.s6_addr);
+ snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->max_in6_daddr);
if (debug)
printk(KERN_DEBUG "pktgen: dst6_max set to: %s\n", buf);
@@ -1377,7 +1367,7 @@ static ssize_t pktgen_if_write(struct file *file,
buf[len] = 0;
scan_ip6(buf, pkt_dev->in6_saddr.s6_addr);
- fmt_ip6(buf, pkt_dev->in6_saddr.s6_addr);
+ snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_saddr);
ipv6_addr_copy(&pkt_dev->cur_in6_saddr, &pkt_dev->in6_saddr);
@@ -1431,11 +1421,6 @@ static ssize_t pktgen_if_write(struct file *file,
return count;
}
if (!strcmp(name, "dst_mac")) {
- char *v = valstr;
- unsigned char old_dmac[ETH_ALEN];
- unsigned char *m = pkt_dev->dst_mac;
- memcpy(old_dmac, pkt_dev->dst_mac, ETH_ALEN);
-
len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
if (len < 0)
return len;
@@ -1443,35 +1428,16 @@ static ssize_t pktgen_if_write(struct file *file,
memset(valstr, 0, sizeof(valstr));
if (copy_from_user(valstr, &user_buffer[i], len))
return -EFAULT;
- i += len;
-
- for (*m = 0; *v && m < pkt_dev->dst_mac + 6; v++) {
- int value;
-
- value = hex_to_bin(*v);
- if (value >= 0)
- *m = *m * 16 + value;
-
- if (*v == ':') {
- m++;
- *m = 0;
- }
- }
+ if (!mac_pton(valstr, pkt_dev->dst_mac))
+ return -EINVAL;
/* Set up Dest MAC */
- if (compare_ether_addr(old_dmac, pkt_dev->dst_mac))
- memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN);
+ memcpy(&pkt_dev->hh[0], pkt_dev->dst_mac, ETH_ALEN);
- sprintf(pg_result, "OK: dstmac");
+ sprintf(pg_result, "OK: dstmac %pM", pkt_dev->dst_mac);
return count;
}
if (!strcmp(name, "src_mac")) {
- char *v = valstr;
- unsigned char old_smac[ETH_ALEN];
- unsigned char *m = pkt_dev->src_mac;
-
- memcpy(old_smac, pkt_dev->src_mac, ETH_ALEN);
-
len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
if (len < 0)
return len;
@@ -1479,26 +1445,13 @@ static ssize_t pktgen_if_write(struct file *file,
memset(valstr, 0, sizeof(valstr));
if (copy_from_user(valstr, &user_buffer[i], len))
return -EFAULT;
- i += len;
-
- for (*m = 0; *v && m < pkt_dev->src_mac + 6; v++) {
- int value;
-
- value = hex_to_bin(*v);
- if (value >= 0)
- *m = *m * 16 + value;
-
- if (*v == ':') {
- m++;
- *m = 0;
- }
- }
+ if (!mac_pton(valstr, pkt_dev->src_mac))
+ return -EINVAL;
/* Set up Src MAC */
- if (compare_ether_addr(old_smac, pkt_dev->src_mac))
- memcpy(&(pkt_dev->hh[6]), pkt_dev->src_mac, ETH_ALEN);
+ memcpy(&pkt_dev->hh[6], pkt_dev->src_mac, ETH_ALEN);
- sprintf(pg_result, "OK: srcmac");
+ sprintf(pg_result, "OK: srcmac %pM", pkt_dev->src_mac);
return count;
}
@@ -2515,7 +2468,6 @@ static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev)
{
struct xfrm_state *x = pkt_dev->flows[pkt_dev->curfl].x;
int err = 0;
- struct iphdr *iph;
if (!x)
return 0;
@@ -2525,7 +2477,6 @@ static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev)
return 0;
spin_lock(&x->lock);
- iph = ip_hdr(skb);
err = x->outer_mode->output(x, skb);
if (err)
@@ -2625,6 +2576,7 @@ static void pktgen_finalize_skb(struct pktgen_dev *pkt_dev, struct sk_buff *skb,
} else {
int frags = pkt_dev->nfrags;
int i, len;
+ int frag_len;
if (frags > MAX_SKB_FRAGS)
@@ -2636,6 +2588,8 @@ static void pktgen_finalize_skb(struct pktgen_dev *pkt_dev, struct sk_buff *skb,
}
i = 0;
+ frag_len = (datalen/frags) < PAGE_SIZE ?
+ (datalen/frags) : PAGE_SIZE;
while (datalen > 0) {
if (unlikely(!pkt_dev->page)) {
int node = numa_node_id();
@@ -2649,38 +2603,18 @@ static void pktgen_finalize_skb(struct pktgen_dev *pkt_dev, struct sk_buff *skb,
skb_shinfo(skb)->frags[i].page = pkt_dev->page;
get_page(pkt_dev->page);
skb_shinfo(skb)->frags[i].page_offset = 0;
- skb_shinfo(skb)->frags[i].size =
- (datalen < PAGE_SIZE ? datalen : PAGE_SIZE);
+ /*last fragment, fill rest of data*/
+ if (i == (frags - 1))
+ skb_shinfo(skb)->frags[i].size =
+ (datalen < PAGE_SIZE ? datalen : PAGE_SIZE);
+ else
+ skb_shinfo(skb)->frags[i].size = frag_len;
datalen -= skb_shinfo(skb)->frags[i].size;
skb->len += skb_shinfo(skb)->frags[i].size;
skb->data_len += skb_shinfo(skb)->frags[i].size;
i++;
skb_shinfo(skb)->nr_frags = i;
}
-
- while (i < frags) {
- int rem;
-
- if (i == 0)
- break;
-
- rem = skb_shinfo(skb)->frags[i - 1].size / 2;
- if (rem == 0)
- break;
-
- skb_shinfo(skb)->frags[i - 1].size -= rem;
-
- skb_shinfo(skb)->frags[i] =
- skb_shinfo(skb)->frags[i - 1];
- get_page(skb_shinfo(skb)->frags[i].page);
- skb_shinfo(skb)->frags[i].page =
- skb_shinfo(skb)->frags[i - 1].page;
- skb_shinfo(skb)->frags[i].page_offset +=
- skb_shinfo(skb)->frags[i - 1].size;
- skb_shinfo(skb)->frags[i].size = rem;
- i++;
- skb_shinfo(skb)->nr_frags = i;
- }
}
/* Stamp the time, and sequence number,
@@ -2918,79 +2852,6 @@ static unsigned int scan_ip6(const char *s, char ip[16])
return len;
}
-static char tohex(char hexdigit)
-{
- return hexdigit > 9 ? hexdigit + 'a' - 10 : hexdigit + '0';
-}
-
-static int fmt_xlong(char *s, unsigned int i)
-{
- char *bak = s;
- *s = tohex((i >> 12) & 0xf);
- if (s != bak || *s != '0')
- ++s;
- *s = tohex((i >> 8) & 0xf);
- if (s != bak || *s != '0')
- ++s;
- *s = tohex((i >> 4) & 0xf);
- if (s != bak || *s != '0')
- ++s;
- *s = tohex(i & 0xf);
- return s - bak + 1;
-}
-
-static unsigned int fmt_ip6(char *s, const char ip[16])
-{
- unsigned int len;
- unsigned int i;
- unsigned int temp;
- unsigned int compressing;
- int j;
-
- len = 0;
- compressing = 0;
- for (j = 0; j < 16; j += 2) {
-
-#ifdef V4MAPPEDPREFIX
- if (j == 12 && !memcmp(ip, V4mappedprefix, 12)) {
- inet_ntoa_r(*(struct in_addr *)(ip + 12), s);
- temp = strlen(s);
- return len + temp;
- }
-#endif
- temp = ((unsigned long)(unsigned char)ip[j] << 8) +
- (unsigned long)(unsigned char)ip[j + 1];
- if (temp == 0) {
- if (!compressing) {
- compressing = 1;
- if (j == 0) {
- *s++ = ':';
- ++len;
- }
- }
- } else {
- if (compressing) {
- compressing = 0;
- *s++ = ':';
- ++len;
- }
- i = fmt_xlong(s, temp);
- len += i;
- s += i;
- if (j < 14) {
- *s++ = ':';
- ++len;
- }
- }
- }
- if (compressing) {
- *s++ = ':';
- ++len;
- }
- *s = 0;
- return len;
-}
-
static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
struct pktgen_dev *pkt_dev)
{
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index d7c4bb4b182..d2ba2597c75 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1007,10 +1007,11 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
s_h = cb->args[0];
s_idx = cb->args[1];
+ rcu_read_lock();
for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
idx = 0;
head = &net->dev_index_head[h];
- hlist_for_each_entry(dev, node, head, index_hlist) {
+ hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
if (idx < s_idx)
goto cont;
if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
@@ -1023,6 +1024,7 @@ cont:
}
}
out:
+ rcu_read_unlock();
cb->args[1] = idx;
cb->args[0] = h;
@@ -1499,6 +1501,7 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
char ifname[IFNAMSIZ];
struct nlattr *tb[IFLA_MAX+1];
int err;
+ LIST_HEAD(list_kill);
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
if (err < 0)
@@ -1522,7 +1525,9 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
if (!ops)
return -EOPNOTSUPP;
- ops->dellink(dev, NULL);
+ ops->dellink(dev, &list_kill);
+ unregister_netdevice_many(&list_kill);
+ list_del(&list_kill);
return 0;
}
@@ -1570,12 +1575,6 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
dev->rtnl_link_state = RTNL_LINK_INITIALIZING;
dev->real_num_tx_queues = real_num_queues;
- if (strchr(dev->name, '%')) {
- err = dev_alloc_name(dev, dev->name);
- if (err < 0)
- goto err_free;
- }
-
if (tb[IFLA_MTU])
dev->mtu = nla_get_u32(tb[IFLA_MTU]);
if (tb[IFLA_ADDRESS])
@@ -1595,8 +1594,6 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
return dev;
-err_free:
- free_netdev(dev);
err:
return ERR_PTR(err);
}
@@ -1879,7 +1876,6 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
int min_len;
int family;
int type;
- int err;
type = nlh->nlmsg_type;
if (type > RTM_MAX)
@@ -1906,11 +1902,8 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (dumpit == NULL)
return -EOPNOTSUPP;
- __rtnl_unlock();
rtnl = net->rtnl;
- err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
- rtnl_lock();
- return err;
+ return netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
}
memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *)));
@@ -1980,7 +1973,7 @@ static int __net_init rtnetlink_net_init(struct net *net)
{
struct sock *sk;
sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX,
- rtnetlink_rcv, &rtnl_mutex, THIS_MODULE);
+ rtnetlink_rcv, NULL, THIS_MODULE);
if (!sk)
return -ENOMEM;
net->rtnl = sk;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 960ea899c86..46cbd28f40f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2994,6 +2994,9 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
skb->destructor = sock_rmem_free;
atomic_add(skb->truesize, &sk->sk_rmem_alloc);
+ /* before exiting rcu section, make sure dst is refcounted */
+ skb_dst_force(skb);
+
skb_queue_tail(&sk->sk_error_queue, skb);
if (!sock_flag(sk, SOCK_DEAD))
sk->sk_data_ready(sk, skb->len);
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index 385b6095fdc..a829e3f60ae 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -122,6 +122,15 @@ static struct ctl_table net_core_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec
},
+#ifdef CONFIG_BPF_JIT
+ {
+ .procname = "bpf_jit_enable",
+ .data = &bpf_jit_enable,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec
+ },
+#endif
{
.procname = "netdev_tstamp_prequeue",
.data = &netdev_tstamp_prequeue,
diff --git a/net/core/utils.c b/net/core/utils.c
index 5fea0ab2190..2012bc797f9 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -296,3 +296,27 @@ void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
csum_unfold(*sum)));
}
EXPORT_SYMBOL(inet_proto_csum_replace4);
+
+int mac_pton(const char *s, u8 *mac)
+{
+ int i;
+
+ /* XX:XX:XX:XX:XX:XX */
+ if (strlen(s) < 3 * ETH_ALEN - 1)
+ return 0;
+
+ /* Don't dirty result unless string is valid MAC. */
+ for (i = 0; i < ETH_ALEN; i++) {
+ if (!strchr("0123456789abcdefABCDEF", s[i * 3]))
+ return 0;
+ if (!strchr("0123456789abcdefABCDEF", s[i * 3 + 1]))
+ return 0;
+ if (i != ETH_ALEN - 1 && s[i * 3 + 2] != ':')
+ return 0;
+ }
+ for (i = 0; i < ETH_ALEN; i++) {
+ mac[i] = (hex_to_bin(s[i * 3]) << 4) | hex_to_bin(s[i * 3 + 1]);
+ }
+ return 1;
+}
+EXPORT_SYMBOL(mac_pton);
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index ae451c6d83b..8c36adfd191 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -40,13 +40,15 @@
int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
+ const struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
struct inet_sock *inet = inet_sk(sk);
struct dccp_sock *dp = dccp_sk(sk);
- const struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
__be16 orig_sport, orig_dport;
- struct rtable *rt;
__be32 daddr, nexthop;
+ struct flowi4 *fl4;
+ struct rtable *rt;
int err;
+ struct ip_options_rcu *inet_opt;
dp->dccps_role = DCCP_ROLE_CLIENT;
@@ -57,15 +59,19 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
return -EAFNOSUPPORT;
nexthop = daddr = usin->sin_addr.s_addr;
- if (inet->opt != NULL && inet->opt->srr) {
+
+ inet_opt = rcu_dereference_protected(inet->inet_opt,
+ sock_owned_by_user(sk));
+ if (inet_opt != NULL && inet_opt->opt.srr) {
if (daddr == 0)
return -EINVAL;
- nexthop = inet->opt->faddr;
+ nexthop = inet_opt->opt.faddr;
}
orig_sport = inet->inet_sport;
orig_dport = usin->sin_port;
- rt = ip_route_connect(nexthop, inet->inet_saddr,
+ fl4 = &inet->cork.fl.u.ip4;
+ rt = ip_route_connect(fl4, nexthop, inet->inet_saddr,
RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
IPPROTO_DCCP,
orig_sport, orig_dport, sk, true);
@@ -77,19 +83,19 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
return -ENETUNREACH;
}
- if (inet->opt == NULL || !inet->opt->srr)
- daddr = rt->rt_dst;
+ if (inet_opt == NULL || !inet_opt->opt.srr)
+ daddr = fl4->daddr;
if (inet->inet_saddr == 0)
- inet->inet_saddr = rt->rt_src;
+ inet->inet_saddr = fl4->saddr;
inet->inet_rcv_saddr = inet->inet_saddr;
inet->inet_dport = usin->sin_port;
inet->inet_daddr = daddr;
inet_csk(sk)->icsk_ext_hdr_len = 0;
- if (inet->opt != NULL)
- inet_csk(sk)->icsk_ext_hdr_len = inet->opt->optlen;
+ if (inet_opt)
+ inet_csk(sk)->icsk_ext_hdr_len = inet_opt->opt.optlen;
/*
* Socket identity is still unknown (sport may be zero).
* However we set state to DCCP_REQUESTING and not releasing socket
@@ -101,8 +107,7 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
if (err != 0)
goto failure;
- rt = ip_route_newports(rt, IPPROTO_DCCP,
- orig_sport, orig_dport,
+ rt = ip_route_newports(fl4, rt, orig_sport, orig_dport,
inet->inet_sport, inet->inet_dport, sk);
if (IS_ERR(rt)) {
rt = NULL;
@@ -391,32 +396,30 @@ struct sock *dccp_v4_request_recv_sock(struct sock *sk, struct sk_buff *skb,
if (sk_acceptq_is_full(sk))
goto exit_overflow;
- if (dst == NULL && (dst = inet_csk_route_req(sk, req)) == NULL)
- goto exit;
-
newsk = dccp_create_openreq_child(sk, req, skb);
if (newsk == NULL)
goto exit_nonewsk;
- sk_setup_caps(newsk, dst);
-
newinet = inet_sk(newsk);
ireq = inet_rsk(req);
newinet->inet_daddr = ireq->rmt_addr;
newinet->inet_rcv_saddr = ireq->loc_addr;
newinet->inet_saddr = ireq->loc_addr;
- newinet->opt = ireq->opt;
+ newinet->inet_opt = ireq->opt;
ireq->opt = NULL;
newinet->mc_index = inet_iif(skb);
newinet->mc_ttl = ip_hdr(skb)->ttl;
newinet->inet_id = jiffies;
+ if (dst == NULL && (dst = inet_csk_route_child_sock(sk, newsk, req)) == NULL)
+ goto put_and_exit;
+
+ sk_setup_caps(newsk, dst);
+
dccp_sync_mss(newsk, dst_mtu(dst));
- if (__inet_inherit_port(sk, newsk) < 0) {
- sock_put(newsk);
- goto exit;
- }
+ if (__inet_inherit_port(sk, newsk) < 0)
+ goto put_and_exit;
__inet_hash_nolisten(newsk, NULL);
return newsk;
@@ -428,6 +431,9 @@ exit_nonewsk:
exit:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
return NULL;
+put_and_exit:
+ sock_put(newsk);
+ goto exit;
}
EXPORT_SYMBOL_GPL(dccp_v4_request_recv_sock);
@@ -491,8 +497,9 @@ static int dccp_v4_send_response(struct sock *sk, struct request_sock *req,
int err = -1;
struct sk_buff *skb;
struct dst_entry *dst;
+ struct flowi4 fl4;
- dst = inet_csk_route_req(sk, req);
+ dst = inet_csk_route_req(sk, &fl4, req);
if (dst == NULL)
goto out;
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index de1b7e37ad5..8dc4348774a 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -54,8 +54,8 @@ static void dccp_v6_hash(struct sock *sk)
/* add pseudo-header to DCCP checksum stored in skb->csum */
static inline __sum16 dccp_v6_csum_finish(struct sk_buff *skb,
- struct in6_addr *saddr,
- struct in6_addr *daddr)
+ const struct in6_addr *saddr,
+ const struct in6_addr *daddr)
{
return csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_DCCP, skb->csum);
}
@@ -87,7 +87,7 @@ static inline __u32 dccp_v6_init_sequence(struct sk_buff *skb)
static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
u8 type, u8 code, int offset, __be32 info)
{
- struct ipv6hdr *hdr = (struct ipv6hdr *)skb->data;
+ const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset);
struct dccp_sock *dp;
struct ipv6_pinfo *np;
@@ -296,7 +296,7 @@ static void dccp_v6_reqsk_destructor(struct request_sock *req)
static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
{
- struct ipv6hdr *rxip6h;
+ const struct ipv6hdr *rxip6h;
struct sk_buff *skb;
struct flowi6 fl6;
struct net *net = dev_net(skb_dst(rxskb)->dev);
@@ -573,7 +573,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
First: no IPv4 options.
*/
- newinet->opt = NULL;
+ newinet->inet_opt = NULL;
/* Clone RX bits */
newnp->rxopt.all = np->rxopt.all;
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 136d41cbcd0..fab108e51e5 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -43,7 +43,7 @@ static void dccp_skb_entail(struct sock *sk, struct sk_buff *skb)
static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
{
if (likely(skb != NULL)) {
- const struct inet_sock *inet = inet_sk(sk);
+ struct inet_sock *inet = inet_sk(sk);
const struct inet_connection_sock *icsk = inet_csk(sk);
struct dccp_sock *dp = dccp_sk(sk);
struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
@@ -136,7 +136,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
- err = icsk->icsk_af_ops->queue_xmit(skb);
+ err = icsk->icsk_af_ops->queue_xmit(skb, &inet->cork.fl);
return net_xmit_eval(err);
}
return -ENOBUFS;
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 4c27615340d..cf26ac74a18 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -747,7 +747,8 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
skip_naddr = cb->args[1];
idx = 0;
- for_each_netdev(&init_net, dev) {
+ rcu_read_lock();
+ for_each_netdev_rcu(&init_net, dev) {
if (idx < skip_ndevs)
goto cont;
else if (idx > skip_ndevs) {
@@ -756,11 +757,11 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
skip_naddr = 0;
}
- if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL)
+ if ((dn_db = rcu_dereference(dev->dn_ptr)) == NULL)
goto cont;
- for (ifa = rtnl_dereference(dn_db->ifa_list), dn_idx = 0; ifa;
- ifa = rtnl_dereference(ifa->ifa_next), dn_idx++) {
+ for (ifa = rcu_dereference(dn_db->ifa_list), dn_idx = 0; ifa;
+ ifa = rcu_dereference(ifa->ifa_next), dn_idx++) {
if (dn_idx < skip_naddr)
continue;
@@ -773,6 +774,7 @@ cont:
idx++;
}
done:
+ rcu_read_unlock();
cb->args[0] = idx;
cb->args[1] = dn_idx;
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 9f09d4fc288..74544bc6fde 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1125,13 +1125,11 @@ make_route:
if (dev_out->flags & IFF_LOOPBACK)
flags |= RTCF_LOCAL;
- rt = dst_alloc(&dn_dst_ops, 0);
+ rt = dst_alloc(&dn_dst_ops, dev_out, 1, 0, DST_HOST);
if (rt == NULL)
goto e_nobufs;
- atomic_set(&rt->dst.__refcnt, 1);
- rt->dst.flags = DST_HOST;
-
+ memset(&rt->fld, 0, sizeof(rt->fld));
rt->fld.saddr = oldflp->saddr;
rt->fld.daddr = oldflp->daddr;
rt->fld.flowidn_oif = oldflp->flowidn_oif;
@@ -1146,8 +1144,6 @@ make_route:
rt->rt_dst_map = fld.daddr;
rt->rt_src_map = fld.saddr;
- rt->dst.dev = dev_out;
- dev_hold(dev_out);
rt->dst.neighbour = neigh;
neigh = NULL;
@@ -1399,10 +1395,11 @@ static int dn_route_input_slow(struct sk_buff *skb)
}
make_route:
- rt = dst_alloc(&dn_dst_ops, 0);
+ rt = dst_alloc(&dn_dst_ops, out_dev, 0, 0, DST_HOST);
if (rt == NULL)
goto e_nobufs;
+ memset(&rt->fld, 0, sizeof(rt->fld));
rt->rt_saddr = fld.saddr;
rt->rt_daddr = fld.daddr;
rt->rt_gateway = fld.daddr;
@@ -1419,9 +1416,7 @@ make_route:
rt->fld.flowidn_iif = in_dev->ifindex;
rt->fld.flowidn_mark = fld.flowidn_mark;
- rt->dst.flags = DST_HOST;
rt->dst.neighbour = neigh;
- rt->dst.dev = out_dev;
rt->dst.lastuse = jiffies;
rt->dst.output = dn_rt_bug;
switch(res.type) {
@@ -1440,8 +1435,6 @@ make_route:
rt->dst.input = dst_discard;
}
rt->rt_flags = flags;
- if (rt->dst.dev)
- dev_hold(rt->dst.dev);
err = dn_rt_set_next_hop(rt, &res);
if (err)
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c
index 99d8d3a4099..bd0a52dd1d4 100644
--- a/net/decnet/dn_table.c
+++ b/net/decnet/dn_table.c
@@ -123,11 +123,11 @@ static inline void dn_rebuild_zone(struct dn_zone *dz,
struct dn_fib_node **old_ht,
int old_divisor)
{
- int i;
struct dn_fib_node *f, **fp, *next;
+ int i;
for(i = 0; i < old_divisor; i++) {
- for(f = old_ht[i]; f; f = f->fn_next) {
+ for(f = old_ht[i]; f; f = next) {
next = f->fn_next;
for(fp = dn_chain_p(f->fn_key, dz);
*fp && dn_key_leq((*fp)->fn_key, f->fn_key);
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 64ca2a6fa0d..0a47b6c3703 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -288,7 +288,6 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = {
.get_drvinfo = dsa_slave_get_drvinfo,
.nway_reset = dsa_slave_nway_reset,
.get_link = dsa_slave_get_link,
- .set_sg = ethtool_op_set_sg,
.get_strings = dsa_slave_get_strings,
.get_ethtool_stats = dsa_slave_get_ethtool_stats,
.get_sset_count = dsa_slave_get_sset_count,
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index 116d3fd3d66..a1d9f3787dd 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -935,7 +935,6 @@ static void aun_data_available(struct sock *sk, int slen)
struct sk_buff *skb;
unsigned char *data;
struct aunhdr *ah;
- struct iphdr *ip;
size_t len;
while ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL) {
@@ -949,7 +948,6 @@ static void aun_data_available(struct sock *sk, int slen)
data = skb_transport_header(skb) + sizeof(struct udphdr);
ah = (struct aunhdr *)data;
len = skb->len - sizeof(struct udphdr);
- ip = ip_hdr(skb);
switch (ah->code)
{
@@ -962,12 +960,6 @@ static void aun_data_available(struct sock *sk, int slen)
case 4:
aun_tx_ack(ah->handle, ECTYPE_TRANSMIT_NOT_LISTENING);
break;
-#if 0
- /* This isn't quite right yet. */
- case 5:
- aun_send_response(ip->saddr, ah->handle, 6, ah->cb);
- break;
-#endif
default:
printk(KERN_DEBUG "unknown AUN packet (type %d)\n", data[0]);
}
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 0dc772d0d12..f2dc69cffb5 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -11,7 +11,7 @@ obj-y := route.o inetpeer.o protocol.o \
datagram.o raw.o udp.o udplite.o \
arp.o icmp.o devinet.o af_inet.o igmp.o \
fib_frontend.o fib_semantics.o fib_trie.o \
- inet_fragment.o
+ inet_fragment.o ping.o
obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
obj-$(CONFIG_PROC_FS) += proc.o
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 807d83c02ef..cc1463156cd 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -105,6 +105,7 @@
#include <net/tcp.h>
#include <net/udp.h>
#include <net/udplite.h>
+#include <net/ping.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/raw.h>
@@ -153,7 +154,7 @@ void inet_sock_destruct(struct sock *sk)
WARN_ON(sk->sk_wmem_queued);
WARN_ON(sk->sk_forward_alloc);
- kfree(inet->opt);
+ kfree(rcu_dereference_protected(inet->inet_opt, 1));
dst_release(rcu_dereference_check(sk->sk_dst_cache, 1));
sk_refcnt_debug_dec(sk);
}
@@ -1008,6 +1009,14 @@ static struct inet_protosw inetsw_array[] =
.flags = INET_PROTOSW_PERMANENT,
},
+ {
+ .type = SOCK_DGRAM,
+ .protocol = IPPROTO_ICMP,
+ .prot = &ping_prot,
+ .ops = &inet_dgram_ops,
+ .no_check = UDP_CSUM_DEFAULT,
+ .flags = INET_PROTOSW_REUSE,
+ },
{
.type = SOCK_RAW,
@@ -1103,14 +1112,19 @@ static int inet_sk_reselect_saddr(struct sock *sk)
struct inet_sock *inet = inet_sk(sk);
__be32 old_saddr = inet->inet_saddr;
__be32 daddr = inet->inet_daddr;
+ struct flowi4 *fl4;
struct rtable *rt;
__be32 new_saddr;
+ struct ip_options_rcu *inet_opt;
- if (inet->opt && inet->opt->srr)
- daddr = inet->opt->faddr;
+ inet_opt = rcu_dereference_protected(inet->inet_opt,
+ sock_owned_by_user(sk));
+ if (inet_opt && inet_opt->opt.srr)
+ daddr = inet_opt->opt.faddr;
/* Query new route. */
- rt = ip_route_connect(daddr, 0, RT_CONN_FLAGS(sk),
+ fl4 = &inet->cork.fl.u.ip4;
+ rt = ip_route_connect(fl4, daddr, 0, RT_CONN_FLAGS(sk),
sk->sk_bound_dev_if, sk->sk_protocol,
inet->inet_sport, inet->inet_dport, sk, false);
if (IS_ERR(rt))
@@ -1118,7 +1132,7 @@ static int inet_sk_reselect_saddr(struct sock *sk)
sk_setup_caps(sk, &rt->dst);
- new_saddr = rt->rt_src;
+ new_saddr = fl4->saddr;
if (new_saddr == old_saddr)
return 0;
@@ -1147,6 +1161,8 @@ int inet_sk_rebuild_header(struct sock *sk)
struct inet_sock *inet = inet_sk(sk);
struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0);
__be32 daddr;
+ struct ip_options_rcu *inet_opt;
+ struct flowi4 *fl4;
int err;
/* Route is OK, nothing to do. */
@@ -1154,10 +1170,14 @@ int inet_sk_rebuild_header(struct sock *sk)
return 0;
/* Reroute. */
+ rcu_read_lock();
+ inet_opt = rcu_dereference(inet->inet_opt);
daddr = inet->inet_daddr;
- if (inet->opt && inet->opt->srr)
- daddr = inet->opt->faddr;
- rt = ip_route_output_ports(sock_net(sk), sk, daddr, inet->inet_saddr,
+ if (inet_opt && inet_opt->opt.srr)
+ daddr = inet_opt->opt.faddr;
+ rcu_read_unlock();
+ fl4 = &inet->cork.fl.u.ip4;
+ rt = ip_route_output_ports(sock_net(sk), fl4, sk, daddr, inet->inet_saddr,
inet->inet_dport, inet->inet_sport,
sk->sk_protocol, RT_CONN_FLAGS(sk),
sk->sk_bound_dev_if);
@@ -1186,7 +1206,7 @@ EXPORT_SYMBOL(inet_sk_rebuild_header);
static int inet_gso_send_check(struct sk_buff *skb)
{
- struct iphdr *iph;
+ const struct iphdr *iph;
const struct net_protocol *ops;
int proto;
int ihl;
@@ -1293,7 +1313,7 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head,
const struct net_protocol *ops;
struct sk_buff **pp = NULL;
struct sk_buff *p;
- struct iphdr *iph;
+ const struct iphdr *iph;
unsigned int hlen;
unsigned int off;
unsigned int id;
@@ -1516,6 +1536,7 @@ static const struct net_protocol udp_protocol = {
static const struct net_protocol icmp_protocol = {
.handler = icmp_rcv,
+ .err_handler = ping_err,
.no_policy = 1,
.netns_ok = 1,
};
@@ -1631,6 +1652,10 @@ static int __init inet_init(void)
if (rc)
goto out_unregister_udp_proto;
+ rc = proto_register(&ping_prot, 1);
+ if (rc)
+ goto out_unregister_raw_proto;
+
/*
* Tell SOCKET that we are alive...
*/
@@ -1686,6 +1711,8 @@ static int __init inet_init(void)
/* Add UDP-Lite (RFC 3828) */
udplite4_register();
+ ping_init();
+
/*
* Set the ICMP layer up
*/
@@ -1716,6 +1743,8 @@ static int __init inet_init(void)
rc = 0;
out:
return rc;
+out_unregister_raw_proto:
+ proto_unregister(&raw_prot);
out_unregister_udp_proto:
proto_unregister(&udp_prot);
out_unregister_tcp_proto:
@@ -1740,11 +1769,15 @@ static int __init ipv4_proc_init(void)
goto out_tcp;
if (udp4_proc_init())
goto out_udp;
+ if (ping_proc_init())
+ goto out_ping;
if (ip_misc_proc_init())
goto out_misc;
out:
return rc;
out_misc:
+ ping_proc_exit();
+out_ping:
udp4_proc_exit();
out_udp:
tcp4_proc_exit();
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 4286fd3cc0e..c1f4154552f 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -73,7 +73,7 @@ static inline struct scatterlist *ah_req_sg(struct crypto_ahash *ahash,
* into IP header for icv calculation. Options are already checked
* for validity, so paranoia is not required. */
-static int ip_clear_mutable_options(struct iphdr *iph, __be32 *daddr)
+static int ip_clear_mutable_options(const struct iphdr *iph, __be32 *daddr)
{
unsigned char * optptr = (unsigned char*)(iph+1);
int l = iph->ihl*4 - sizeof(struct iphdr);
@@ -396,7 +396,7 @@ out:
static void ah4_err(struct sk_buff *skb, u32 info)
{
struct net *net = dev_net(skb->dev);
- struct iphdr *iph = (struct iphdr *)skb->data;
+ const struct iphdr *iph = (const struct iphdr *)skb->data;
struct ip_auth_hdr *ah = (struct ip_auth_hdr *)(skb->data+(iph->ihl<<2));
struct xfrm_state *x;
@@ -404,7 +404,8 @@ static void ah4_err(struct sk_buff *skb, u32 info)
icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
return;
- x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET);
+ x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr,
+ ah->spi, IPPROTO_AH, AF_INET);
if (!x)
return;
printk(KERN_DEBUG "pmtu discovery on SA AH/%08x/%08x\n",
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index a0af7ea8787..2b3c23c287c 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -1857,6 +1857,11 @@ static int cipso_v4_genopt(unsigned char *buf, u32 buf_len,
return CIPSO_V4_HDR_LEN + ret_val;
}
+static void opt_kfree_rcu(struct rcu_head *head)
+{
+ kfree(container_of(head, struct ip_options_rcu, rcu));
+}
+
/**
* cipso_v4_sock_setattr - Add a CIPSO option to a socket
* @sk: the socket
@@ -1879,7 +1884,7 @@ int cipso_v4_sock_setattr(struct sock *sk,
unsigned char *buf = NULL;
u32 buf_len;
u32 opt_len;
- struct ip_options *opt = NULL;
+ struct ip_options_rcu *old, *opt = NULL;
struct inet_sock *sk_inet;
struct inet_connection_sock *sk_conn;
@@ -1915,22 +1920,25 @@ int cipso_v4_sock_setattr(struct sock *sk,
ret_val = -ENOMEM;
goto socket_setattr_failure;
}
- memcpy(opt->__data, buf, buf_len);
- opt->optlen = opt_len;
- opt->cipso = sizeof(struct iphdr);
+ memcpy(opt->opt.__data, buf, buf_len);
+ opt->opt.optlen = opt_len;
+ opt->opt.cipso = sizeof(struct iphdr);
kfree(buf);
buf = NULL;
sk_inet = inet_sk(sk);
+
+ old = rcu_dereference_protected(sk_inet->inet_opt, sock_owned_by_user(sk));
if (sk_inet->is_icsk) {
sk_conn = inet_csk(sk);
- if (sk_inet->opt)
- sk_conn->icsk_ext_hdr_len -= sk_inet->opt->optlen;
- sk_conn->icsk_ext_hdr_len += opt->optlen;
+ if (old)
+ sk_conn->icsk_ext_hdr_len -= old->opt.optlen;
+ sk_conn->icsk_ext_hdr_len += opt->opt.optlen;
sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
}
- opt = xchg(&sk_inet->opt, opt);
- kfree(opt);
+ rcu_assign_pointer(sk_inet->inet_opt, opt);
+ if (old)
+ call_rcu(&old->rcu, opt_kfree_rcu);
return 0;
@@ -1960,7 +1968,7 @@ int cipso_v4_req_setattr(struct request_sock *req,
unsigned char *buf = NULL;
u32 buf_len;
u32 opt_len;
- struct ip_options *opt = NULL;
+ struct ip_options_rcu *opt = NULL;
struct inet_request_sock *req_inet;
/* We allocate the maximum CIPSO option size here so we are probably
@@ -1988,15 +1996,16 @@ int cipso_v4_req_setattr(struct request_sock *req,
ret_val = -ENOMEM;
goto req_setattr_failure;
}
- memcpy(opt->__data, buf, buf_len);
- opt->optlen = opt_len;
- opt->cipso = sizeof(struct iphdr);
+ memcpy(opt->opt.__data, buf, buf_len);
+ opt->opt.optlen = opt_len;
+ opt->opt.cipso = sizeof(struct iphdr);
kfree(buf);
buf = NULL;
req_inet = inet_rsk(req);
opt = xchg(&req_inet->opt, opt);
- kfree(opt);
+ if (opt)
+ call_rcu(&opt->rcu, opt_kfree_rcu);
return 0;
@@ -2016,34 +2025,34 @@ req_setattr_failure:
* values on failure.
*
*/
-static int cipso_v4_delopt(struct ip_options **opt_ptr)
+static int cipso_v4_delopt(struct ip_options_rcu **opt_ptr)
{
int hdr_delta = 0;
- struct ip_options *opt = *opt_ptr;
+ struct ip_options_rcu *opt = *opt_ptr;
- if (opt->srr || opt->rr || opt->ts || opt->router_alert) {
+ if (opt->opt.srr || opt->opt.rr || opt->opt.ts || opt->opt.router_alert) {
u8 cipso_len;
u8 cipso_off;
unsigned char *cipso_ptr;
int iter;
int optlen_new;
- cipso_off = opt->cipso - sizeof(struct iphdr);
- cipso_ptr = &opt->__data[cipso_off];
+ cipso_off = opt->opt.cipso - sizeof(struct iphdr);
+ cipso_ptr = &opt->opt.__data[cipso_off];
cipso_len = cipso_ptr[1];
- if (opt->srr > opt->cipso)
- opt->srr -= cipso_len;
- if (opt->rr > opt->cipso)
- opt->rr -= cipso_len;
- if (opt->ts > opt->cipso)
- opt->ts -= cipso_len;
- if (opt->router_alert > opt->cipso)
- opt->router_alert -= cipso_len;
- opt->cipso = 0;
+ if (opt->opt.srr > opt->opt.cipso)
+ opt->opt.srr -= cipso_len;
+ if (opt->opt.rr > opt->opt.cipso)
+ opt->opt.rr -= cipso_len;
+ if (opt->opt.ts > opt->opt.cipso)
+ opt->opt.ts -= cipso_len;
+ if (opt->opt.router_alert > opt->opt.cipso)
+ opt->opt.router_alert -= cipso_len;
+ opt->opt.cipso = 0;
memmove(cipso_ptr, cipso_ptr + cipso_len,
- opt->optlen - cipso_off - cipso_len);
+ opt->opt.optlen - cipso_off - cipso_len);
/* determining the new total option length is tricky because of
* the padding necessary, the only thing i can think to do at
@@ -2052,21 +2061,21 @@ static int cipso_v4_delopt(struct ip_options **opt_ptr)
* from there we can determine the new total option length */
iter = 0;
optlen_new = 0;
- while (iter < opt->optlen)
- if (opt->__data[iter] != IPOPT_NOP) {
- iter += opt->__data[iter + 1];
+ while (iter < opt->opt.optlen)
+ if (opt->opt.__data[iter] != IPOPT_NOP) {
+ iter += opt->opt.__data[iter + 1];
optlen_new = iter;
} else
iter++;
- hdr_delta = opt->optlen;
- opt->optlen = (optlen_new + 3) & ~3;
- hdr_delta -= opt->optlen;
+ hdr_delta = opt->opt.optlen;
+ opt->opt.optlen = (optlen_new + 3) & ~3;
+ hdr_delta -= opt->opt.optlen;
} else {
/* only the cipso option was present on the socket so we can
* remove the entire option struct */
*opt_ptr = NULL;
- hdr_delta = opt->optlen;
- kfree(opt);
+ hdr_delta = opt->opt.optlen;
+ call_rcu(&opt->rcu, opt_kfree_rcu);
}
return hdr_delta;
@@ -2083,15 +2092,15 @@ static int cipso_v4_delopt(struct ip_options **opt_ptr)
void cipso_v4_sock_delattr(struct sock *sk)
{
int hdr_delta;
- struct ip_options *opt;
+ struct ip_options_rcu *opt;
struct inet_sock *sk_inet;
sk_inet = inet_sk(sk);
- opt = sk_inet->opt;
- if (opt == NULL || opt->cipso == 0)
+ opt = rcu_dereference_protected(sk_inet->inet_opt, 1);
+ if (opt == NULL || opt->opt.cipso == 0)
return;
- hdr_delta = cipso_v4_delopt(&sk_inet->opt);
+ hdr_delta = cipso_v4_delopt(&sk_inet->inet_opt);
if (sk_inet->is_icsk && hdr_delta > 0) {
struct inet_connection_sock *sk_conn = inet_csk(sk);
sk_conn->icsk_ext_hdr_len -= hdr_delta;
@@ -2109,12 +2118,12 @@ void cipso_v4_sock_delattr(struct sock *sk)
*/
void cipso_v4_req_delattr(struct request_sock *req)
{
- struct ip_options *opt;
+ struct ip_options_rcu *opt;
struct inet_request_sock *req_inet;
req_inet = inet_rsk(req);
opt = req_inet->opt;
- if (opt == NULL || opt->cipso == 0)
+ if (opt == NULL || opt->opt.cipso == 0)
return;
cipso_v4_delopt(&req_inet->opt);
@@ -2184,14 +2193,18 @@ getattr_return:
*/
int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
{
- struct ip_options *opt;
+ struct ip_options_rcu *opt;
+ int res = -ENOMSG;
- opt = inet_sk(sk)->opt;
- if (opt == NULL || opt->cipso == 0)
- return -ENOMSG;
-
- return cipso_v4_getattr(opt->__data + opt->cipso - sizeof(struct iphdr),
- secattr);
+ rcu_read_lock();
+ opt = rcu_dereference(inet_sk(sk)->inet_opt);
+ if (opt && opt->opt.cipso)
+ res = cipso_v4_getattr(opt->opt.__data +
+ opt->opt.cipso -
+ sizeof(struct iphdr),
+ secattr);
+ rcu_read_unlock();
+ return res;
}
/**
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
index 85bd24ca4f6..424fafbc8cb 100644
--- a/net/ipv4/datagram.c
+++ b/net/ipv4/datagram.c
@@ -24,6 +24,7 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
struct inet_sock *inet = inet_sk(sk);
struct sockaddr_in *usin = (struct sockaddr_in *) uaddr;
+ struct flowi4 *fl4;
struct rtable *rt;
__be32 saddr;
int oif;
@@ -38,6 +39,8 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
sk_dst_reset(sk);
+ lock_sock(sk);
+
oif = sk->sk_bound_dev_if;
saddr = inet->inet_saddr;
if (ipv4_is_multicast(usin->sin_addr.s_addr)) {
@@ -46,7 +49,8 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
if (!saddr)
saddr = inet->mc_addr;
}
- rt = ip_route_connect(usin->sin_addr.s_addr, saddr,
+ fl4 = &inet->cork.fl.u.ip4;
+ rt = ip_route_connect(fl4, usin->sin_addr.s_addr, saddr,
RT_CONN_FLAGS(sk), oif,
sk->sk_protocol,
inet->inet_sport, usin->sin_port, sk, true);
@@ -54,26 +58,30 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
err = PTR_ERR(rt);
if (err == -ENETUNREACH)
IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
- return err;
+ goto out;
}
if ((rt->rt_flags & RTCF_BROADCAST) && !sock_flag(sk, SOCK_BROADCAST)) {
ip_rt_put(rt);
- return -EACCES;
+ err = -EACCES;
+ goto out;
}
if (!inet->inet_saddr)
- inet->inet_saddr = rt->rt_src; /* Update source address */
+ inet->inet_saddr = fl4->saddr; /* Update source address */
if (!inet->inet_rcv_saddr) {
- inet->inet_rcv_saddr = rt->rt_src;
+ inet->inet_rcv_saddr = fl4->saddr;
if (sk->sk_prot->rehash)
sk->sk_prot->rehash(sk);
}
- inet->inet_daddr = rt->rt_dst;
+ inet->inet_daddr = fl4->daddr;
inet->inet_dport = usin->sin_port;
sk->sk_state = TCP_ESTABLISHED;
inet->inet_id = jiffies;
sk_dst_set(sk, &rt->dst);
- return 0;
+ err = 0;
+out:
+ release_sock(sk);
+ return err;
}
EXPORT_SYMBOL(ip4_datagram_connect);
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index cd9ca0811cf..0d4a184af16 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1369,7 +1369,7 @@ errout:
static size_t inet_get_link_af_size(const struct net_device *dev)
{
- struct in_device *in_dev = __in_dev_get_rtnl(dev);
+ struct in_device *in_dev = rcu_dereference_rtnl(dev->ip_ptr);
if (!in_dev)
return 0;
@@ -1379,7 +1379,7 @@ static size_t inet_get_link_af_size(const struct net_device *dev)
static int inet_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
{
- struct in_device *in_dev = __in_dev_get_rtnl(dev);
+ struct in_device *in_dev = rcu_dereference_rtnl(dev->ip_ptr);
struct nlattr *nla;
int i;
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 03f994bcf7d..a5b413416da 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -276,7 +276,7 @@ error:
static int esp_input_done2(struct sk_buff *skb, int err)
{
- struct iphdr *iph;
+ const struct iphdr *iph;
struct xfrm_state *x = xfrm_input_state(skb);
struct esp_data *esp = x->data;
struct crypto_aead *aead = esp->aead;
@@ -484,7 +484,7 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
static void esp4_err(struct sk_buff *skb, u32 info)
{
struct net *net = dev_net(skb->dev);
- struct iphdr *iph = (struct iphdr *)skb->data;
+ const struct iphdr *iph = (const struct iphdr *)skb->data;
struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data+(iph->ihl<<2));
struct xfrm_state *x;
@@ -492,7 +492,8 @@ static void esp4_err(struct sk_buff *skb, u32 info)
icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
return;
- x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET);
+ x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr,
+ esph->spi, IPPROTO_ESP, AF_INET);
if (!x)
return;
NETDEBUG(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%08x\n",
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 451088330bb..22524716fe7 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -44,6 +44,7 @@
#include <net/arp.h>
#include <net/ip_fib.h>
#include <net/rtnetlink.h>
+#include <net/xfrm.h>
#ifndef CONFIG_IP_MULTIPLE_TABLES
@@ -188,9 +189,9 @@ EXPORT_SYMBOL(inet_dev_addr_type);
* - check, that packet arrived from expected physical interface.
* called with rcu_read_lock()
*/
-int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
- struct net_device *dev, __be32 *spec_dst,
- u32 *itag, u32 mark)
+int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos,
+ int oif, struct net_device *dev, __be32 *spec_dst,
+ u32 *itag)
{
struct in_device *in_dev;
struct flowi4 fl4;
@@ -202,7 +203,6 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
fl4.flowi4_oif = 0;
fl4.flowi4_iif = oif;
- fl4.flowi4_mark = mark;
fl4.daddr = src;
fl4.saddr = dst;
fl4.flowi4_tos = tos;
@@ -212,10 +212,12 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
in_dev = __in_dev_get_rcu(dev);
if (in_dev) {
no_addr = in_dev->ifa_list == NULL;
- rpf = IN_DEV_RPFILTER(in_dev);
+
+ /* Ignore rp_filter for packets protected by IPsec. */
+ rpf = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(in_dev);
+
accept_local = IN_DEV_ACCEPT_LOCAL(in_dev);
- if (mark && !IN_DEV_SRC_VMARK(in_dev))
- fl4.flowi4_mark = 0;
+ fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0;
}
if (in_dev == NULL)
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 11d4d28190b..c779ce96e5b 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -126,7 +126,7 @@ struct tnode {
struct work_struct work;
struct tnode *tnode_free;
};
- struct rt_trie_node *child[0];
+ struct rt_trie_node __rcu *child[0];
};
#ifdef CONFIG_IP_FIB_TRIE_STATS
@@ -151,7 +151,7 @@ struct trie_stat {
};
struct trie {
- struct rt_trie_node *trie;
+ struct rt_trie_node __rcu *trie;
#ifdef CONFIG_IP_FIB_TRIE_STATS
struct trie_use_stats stats;
#endif
@@ -177,16 +177,29 @@ static const int sync_pages = 128;
static struct kmem_cache *fn_alias_kmem __read_mostly;
static struct kmem_cache *trie_leaf_kmem __read_mostly;
-static inline struct tnode *node_parent(struct rt_trie_node *node)
+/*
+ * caller must hold RTNL
+ */
+static inline struct tnode *node_parent(const struct rt_trie_node *node)
{
- return (struct tnode *)(node->parent & ~NODE_TYPE_MASK);
+ unsigned long parent;
+
+ parent = rcu_dereference_index_check(node->parent, lockdep_rtnl_is_held());
+
+ return (struct tnode *)(parent & ~NODE_TYPE_MASK);
}
-static inline struct tnode *node_parent_rcu(struct rt_trie_node *node)
+/*
+ * caller must hold RCU read lock or RTNL
+ */
+static inline struct tnode *node_parent_rcu(const struct rt_trie_node *node)
{
- struct tnode *ret = node_parent(node);
+ unsigned long parent;
+
+ parent = rcu_dereference_index_check(node->parent, rcu_read_lock_held() ||
+ lockdep_rtnl_is_held());
- return rcu_dereference_rtnl(ret);
+ return (struct tnode *)(parent & ~NODE_TYPE_MASK);
}
/* Same as rcu_assign_pointer
@@ -198,18 +211,24 @@ static inline void node_set_parent(struct rt_trie_node *node, struct tnode *ptr)
node->parent = (unsigned long)ptr | NODE_TYPE(node);
}
-static inline struct rt_trie_node *tnode_get_child(struct tnode *tn, unsigned int i)
+/*
+ * caller must hold RTNL
+ */
+static inline struct rt_trie_node *tnode_get_child(const struct tnode *tn, unsigned int i)
{
BUG_ON(i >= 1U << tn->bits);
- return tn->child[i];
+ return rtnl_dereference(tn->child[i]);
}
-static inline struct rt_trie_node *tnode_get_child_rcu(struct tnode *tn, unsigned int i)
+/*
+ * caller must hold RCU read lock or RTNL
+ */
+static inline struct rt_trie_node *tnode_get_child_rcu(const struct tnode *tn, unsigned int i)
{
- struct rt_trie_node *ret = tnode_get_child(tn, i);
+ BUG_ON(i >= 1U << tn->bits);
- return rcu_dereference_rtnl(ret);
+ return rcu_dereference_rtnl(tn->child[i]);
}
static inline int tnode_child_length(const struct tnode *tn)
@@ -482,7 +501,7 @@ static inline void put_child(struct trie *t, struct tnode *tn, int i,
static void tnode_put_child_reorg(struct tnode *tn, int i, struct rt_trie_node *n,
int wasfull)
{
- struct rt_trie_node *chi = tn->child[i];
+ struct rt_trie_node *chi = rtnl_dereference(tn->child[i]);
int isfull;
BUG_ON(i >= 1<<tn->bits);
@@ -660,7 +679,7 @@ one_child:
for (i = 0; i < tnode_child_length(tn); i++) {
struct rt_trie_node *n;
- n = tn->child[i];
+ n = rtnl_dereference(tn->child[i]);
if (!n)
continue;
@@ -674,6 +693,20 @@ one_child:
return (struct rt_trie_node *) tn;
}
+
+static void tnode_clean_free(struct tnode *tn)
+{
+ int i;
+ struct tnode *tofree;
+
+ for (i = 0; i < tnode_child_length(tn); i++) {
+ tofree = (struct tnode *)rtnl_dereference(tn->child[i]);
+ if (tofree)
+ tnode_free(tofree);
+ }
+ tnode_free(tn);
+}
+
static struct tnode *inflate(struct trie *t, struct tnode *tn)
{
struct tnode *oldtnode = tn;
@@ -750,8 +783,8 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn)
inode = (struct tnode *) node;
if (inode->bits == 1) {
- put_child(t, tn, 2*i, inode->child[0]);
- put_child(t, tn, 2*i+1, inode->child[1]);
+ put_child(t, tn, 2*i, rtnl_dereference(inode->child[0]));
+ put_child(t, tn, 2*i+1, rtnl_dereference(inode->child[1]));
tnode_free_safe(inode);
continue;
@@ -792,8 +825,8 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn)
size = tnode_child_length(left);
for (j = 0; j < size; j++) {
- put_child(t, left, j, inode->child[j]);
- put_child(t, right, j, inode->child[j + size]);
+ put_child(t, left, j, rtnl_dereference(inode->child[j]));
+ put_child(t, right, j, rtnl_dereference(inode->child[j + size]));
}
put_child(t, tn, 2*i, resize(t, left));
put_child(t, tn, 2*i+1, resize(t, right));
@@ -803,18 +836,8 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn)
tnode_free_safe(oldtnode);
return tn;
nomem:
- {
- int size = tnode_child_length(tn);
- int j;
-
- for (j = 0; j < size; j++)
- if (tn->child[j])
- tnode_free((struct tnode *)tn->child[j]);
-
- tnode_free(tn);
-
- return ERR_PTR(-ENOMEM);
- }
+ tnode_clean_free(tn);
+ return ERR_PTR(-ENOMEM);
}
static struct tnode *halve(struct trie *t, struct tnode *tn)
@@ -885,18 +908,8 @@ static struct tnode *halve(struct trie *t, struct tnode *tn)
tnode_free_safe(oldtnode);
return tn;
nomem:
- {
- int size = tnode_child_length(tn);
- int j;
-
- for (j = 0; j < size; j++)
- if (tn->child[j])
- tnode_free((struct tnode *)tn->child[j]);
-
- tnode_free(tn);
-
- return ERR_PTR(-ENOMEM);
- }
+ tnode_clean_free(tn);
+ return ERR_PTR(-ENOMEM);
}
/* readside must use rcu_read_lock currently dump routines
@@ -1028,7 +1041,7 @@ static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen)
t_key cindex;
pos = 0;
- n = t->trie;
+ n = rtnl_dereference(t->trie);
/* If we point to NULL, stop. Either the tree is empty and we should
* just put a new leaf in if, or we have reached an empty child slot,
@@ -1314,6 +1327,9 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
}
}
+ if (!plen)
+ tb->tb_num_default++;
+
list_add_tail_rcu(&new_fa->fa_list,
(fa ? &fa->fa_list : fa_head));
@@ -1679,6 +1695,9 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
list_del_rcu(&fa->fa_list);
+ if (!plen)
+ tb->tb_num_default--;
+
if (list_empty(fa_head)) {
hlist_del_rcu(&li->hlist);
free_leaf_info(li);
@@ -1751,7 +1770,7 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct rt_trie_node *c)
continue;
if (IS_LEAF(c)) {
- prefetch(p->child[idx]);
+ prefetch(rcu_dereference_rtnl(p->child[idx]));
return (struct leaf *) c;
}
@@ -1969,6 +1988,7 @@ struct fib_table *fib_trie_table(u32 id)
tb->tb_id = id;
tb->tb_default = -1;
+ tb->tb_num_default = 0;
t = (struct trie *) tb->tb_data;
memset(t, 0, sizeof(*t));
@@ -2264,7 +2284,7 @@ static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
/* walk rest of this hash chain */
h = tb->tb_id & (FIB_TABLE_HASHSZ - 1);
- while ( (tb_node = rcu_dereference(tb->tb_hlist.next)) ) {
+ while ((tb_node = rcu_dereference(hlist_next_rcu(&tb->tb_hlist)))) {
tb = hlist_entry(tb_node, struct fib_table, tb_hlist);
n = fib_trie_get_first(iter, (struct trie *) tb->tb_data);
if (n)
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index e5f8a71d3a2..5395e45dcce 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -83,6 +83,7 @@
#include <net/tcp.h>
#include <net/udp.h>
#include <net/raw.h>
+#include <net/ping.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <linux/errno.h>
@@ -108,8 +109,7 @@ struct icmp_bxm {
__be32 times[3];
} data;
int head_len;
- struct ip_options replyopts;
- unsigned char optbuf[40];
+ struct ip_options_data replyopts;
};
/* An array of errno for error messages from dest unreach. */
@@ -234,7 +234,7 @@ static inline void icmp_xmit_unlock(struct sock *sk)
*/
static inline bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt,
- int type, int code)
+ struct flowi4 *fl4, int type, int code)
{
struct dst_entry *dst = &rt->dst;
bool rc = true;
@@ -253,7 +253,7 @@ static inline bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt,
/* Limit if icmp type is enabled in ratemask. */
if ((1 << type) & net->ipv4.sysctl_icmp_ratemask) {
if (!rt->peer)
- rt_bind_peer(rt, 1);
+ rt_bind_peer(rt, fl4->daddr, 1);
rc = inet_peer_xrlim_allow(rt->peer,
net->ipv4.sysctl_icmp_ratelimit);
}
@@ -291,13 +291,14 @@ static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd,
}
static void icmp_push_reply(struct icmp_bxm *icmp_param,
+ struct flowi4 *fl4,
struct ipcm_cookie *ipc, struct rtable **rt)
{
struct sock *sk;
struct sk_buff *skb;
sk = icmp_sk(dev_net((*rt)->dst.dev));
- if (ip_append_data(sk, icmp_glue_bits, icmp_param,
+ if (ip_append_data(sk, fl4, icmp_glue_bits, icmp_param,
icmp_param->data_len+icmp_param->head_len,
icmp_param->head_len,
ipc, rt, MSG_DONTWAIT) < 0) {
@@ -316,7 +317,7 @@ static void icmp_push_reply(struct icmp_bxm *icmp_param,
icmp_param->head_len, csum);
icmph->checksum = csum_fold(csum);
skb->ip_summed = CHECKSUM_NONE;
- ip_push_pending_frames(sk);
+ ip_push_pending_frames(sk, fl4);
}
}
@@ -329,11 +330,12 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
struct ipcm_cookie ipc;
struct rtable *rt = skb_rtable(skb);
struct net *net = dev_net(rt->dst.dev);
+ struct flowi4 fl4;
struct sock *sk;
struct inet_sock *inet;
__be32 daddr;
- if (ip_options_echo(&icmp_param->replyopts, skb))
+ if (ip_options_echo(&icmp_param->replyopts.opt.opt, skb))
return;
sk = icmp_xmit_lock(net);
@@ -344,65 +346,60 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
icmp_param->data.icmph.checksum = 0;
inet->tos = ip_hdr(skb)->tos;
- daddr = ipc.addr = rt->rt_src;
+ daddr = ipc.addr = ip_hdr(skb)->saddr;
ipc.opt = NULL;
ipc.tx_flags = 0;
- if (icmp_param->replyopts.optlen) {
- ipc.opt = &icmp_param->replyopts;
- if (ipc.opt->srr)
- daddr = icmp_param->replyopts.faddr;
+ if (icmp_param->replyopts.opt.opt.optlen) {
+ ipc.opt = &icmp_param->replyopts.opt;
+ if (ipc.opt->opt.srr)
+ daddr = icmp_param->replyopts.opt.opt.faddr;
}
- {
- struct flowi4 fl4 = {
- .daddr = daddr,
- .saddr = rt->rt_spec_dst,
- .flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
- .flowi4_proto = IPPROTO_ICMP,
- };
- security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
- rt = ip_route_output_key(net, &fl4);
- if (IS_ERR(rt))
- goto out_unlock;
- }
- if (icmpv4_xrlim_allow(net, rt, icmp_param->data.icmph.type,
+ memset(&fl4, 0, sizeof(fl4));
+ fl4.daddr = daddr;
+ fl4.saddr = rt->rt_spec_dst;
+ fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
+ fl4.flowi4_proto = IPPROTO_ICMP;
+ security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
+ rt = ip_route_output_key(net, &fl4);
+ if (IS_ERR(rt))
+ goto out_unlock;
+ if (icmpv4_xrlim_allow(net, rt, &fl4, icmp_param->data.icmph.type,
icmp_param->data.icmph.code))
- icmp_push_reply(icmp_param, &ipc, &rt);
+ icmp_push_reply(icmp_param, &fl4, &ipc, &rt);
ip_rt_put(rt);
out_unlock:
icmp_xmit_unlock(sk);
}
-static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
- struct iphdr *iph,
+static struct rtable *icmp_route_lookup(struct net *net,
+ struct flowi4 *fl4,
+ struct sk_buff *skb_in,
+ const struct iphdr *iph,
__be32 saddr, u8 tos,
int type, int code,
struct icmp_bxm *param)
{
- struct flowi4 fl4 = {
- .daddr = (param->replyopts.srr ?
- param->replyopts.faddr : iph->saddr),
- .saddr = saddr,
- .flowi4_tos = RT_TOS(tos),
- .flowi4_proto = IPPROTO_ICMP,
- .fl4_icmp_type = type,
- .fl4_icmp_code = code,
- };
struct rtable *rt, *rt2;
int err;
- security_skb_classify_flow(skb_in, flowi4_to_flowi(&fl4));
- rt = __ip_route_output_key(net, &fl4);
+ memset(fl4, 0, sizeof(*fl4));
+ fl4->daddr = (param->replyopts.opt.opt.srr ?
+ param->replyopts.opt.opt.faddr : iph->saddr);
+ fl4->saddr = saddr;
+ fl4->flowi4_tos = RT_TOS(tos);
+ fl4->flowi4_proto = IPPROTO_ICMP;
+ fl4->fl4_icmp_type = type;
+ fl4->fl4_icmp_code = code;
+ security_skb_classify_flow(skb_in, flowi4_to_flowi(fl4));
+ rt = __ip_route_output_key(net, fl4);
if (IS_ERR(rt))
return rt;
/* No need to clone since we're just using its address. */
rt2 = rt;
- if (!fl4.saddr)
- fl4.saddr = rt->rt_src;
-
rt = (struct rtable *) xfrm_lookup(net, &rt->dst,
- flowi4_to_flowi(&fl4), NULL, 0);
+ flowi4_to_flowi(fl4), NULL, 0);
if (!IS_ERR(rt)) {
if (rt != rt2)
return rt;
@@ -411,19 +408,19 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
} else
return rt;
- err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(&fl4), AF_INET);
+ err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(fl4), AF_INET);
if (err)
goto relookup_failed;
- if (inet_addr_type(net, fl4.saddr) == RTN_LOCAL) {
- rt2 = __ip_route_output_key(net, &fl4);
+ if (inet_addr_type(net, fl4->saddr) == RTN_LOCAL) {
+ rt2 = __ip_route_output_key(net, fl4);
if (IS_ERR(rt2))
err = PTR_ERR(rt2);
} else {
struct flowi4 fl4_2 = {};
unsigned long orefdst;
- fl4_2.daddr = fl4.saddr;
+ fl4_2.daddr = fl4->saddr;
rt2 = ip_route_output_key(net, &fl4_2);
if (IS_ERR(rt2)) {
err = PTR_ERR(rt2);
@@ -431,7 +428,7 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
}
/* Ugh! */
orefdst = skb_in->_skb_refdst; /* save old refdst */
- err = ip_route_input(skb_in, fl4.daddr, fl4.saddr,
+ err = ip_route_input(skb_in, fl4->daddr, fl4->saddr,
RT_TOS(tos), rt2->dst.dev);
dst_release(&rt2->dst);
@@ -443,7 +440,7 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
goto relookup_failed;
rt2 = (struct rtable *) xfrm_lookup(net, &rt2->dst,
- flowi4_to_flowi(&fl4), NULL,
+ flowi4_to_flowi(fl4), NULL,
XFRM_LOOKUP_ICMP);
if (!IS_ERR(rt2)) {
dst_release(&rt->dst);
@@ -482,6 +479,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
struct icmp_bxm icmp_param;
struct rtable *rt = skb_rtable(skb_in);
struct ipcm_cookie ipc;
+ struct flowi4 fl4;
__be32 saddr;
u8 tos;
struct net *net;
@@ -581,7 +579,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
IPTOS_PREC_INTERNETCONTROL) :
iph->tos;
- if (ip_options_echo(&icmp_param.replyopts, skb_in))
+ if (ip_options_echo(&icmp_param.replyopts.opt.opt, skb_in))
goto out_unlock;
@@ -597,15 +595,15 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
icmp_param.offset = skb_network_offset(skb_in);
inet_sk(sk)->tos = tos;
ipc.addr = iph->saddr;
- ipc.opt = &icmp_param.replyopts;
+ ipc.opt = &icmp_param.replyopts.opt;
ipc.tx_flags = 0;
- rt = icmp_route_lookup(net, skb_in, iph, saddr, tos,
+ rt = icmp_route_lookup(net, &fl4, skb_in, iph, saddr, tos,
type, code, &icmp_param);
if (IS_ERR(rt))
goto out_unlock;
- if (!icmpv4_xrlim_allow(net, rt, type, code))
+ if (!icmpv4_xrlim_allow(net, rt, &fl4, type, code))
goto ende;
/* RFC says return as much as we can without exceeding 576 bytes. */
@@ -613,7 +611,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
room = dst_mtu(&rt->dst);
if (room > 576)
room = 576;
- room -= sizeof(struct iphdr) + icmp_param.replyopts.optlen;
+ room -= sizeof(struct iphdr) + icmp_param.replyopts.opt.opt.optlen;
room -= sizeof(struct icmphdr);
icmp_param.data_len = skb_in->len - icmp_param.offset;
@@ -621,7 +619,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
icmp_param.data_len = room;
icmp_param.head_len = sizeof(struct icmphdr);
- icmp_push_reply(&icmp_param, &ipc, &rt);
+ icmp_push_reply(&icmp_param, &fl4, &ipc, &rt);
ende:
ip_rt_put(rt);
out_unlock:
@@ -637,7 +635,7 @@ EXPORT_SYMBOL(icmp_send);
static void icmp_unreach(struct sk_buff *skb)
{
- struct iphdr *iph;
+ const struct iphdr *iph;
struct icmphdr *icmph;
int hash, protocol;
const struct net_protocol *ipprot;
@@ -656,7 +654,7 @@ static void icmp_unreach(struct sk_buff *skb)
goto out_err;
icmph = icmp_hdr(skb);
- iph = (struct iphdr *)skb->data;
+ iph = (const struct iphdr *)skb->data;
if (iph->ihl < 5) /* Mangled header, drop. */
goto out_err;
@@ -729,7 +727,7 @@ static void icmp_unreach(struct sk_buff *skb)
if (!pskb_may_pull(skb, iph->ihl * 4 + 8))
goto out;
- iph = (struct iphdr *)skb->data;
+ iph = (const struct iphdr *)skb->data;
protocol = iph->protocol;
/*
@@ -758,7 +756,7 @@ out_err:
static void icmp_redirect(struct sk_buff *skb)
{
- struct iphdr *iph;
+ const struct iphdr *iph;
if (skb->len < sizeof(struct iphdr))
goto out_err;
@@ -769,7 +767,7 @@ static void icmp_redirect(struct sk_buff *skb)
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
goto out;
- iph = (struct iphdr *)skb->data;
+ iph = (const struct iphdr *)skb->data;
switch (icmp_hdr(skb)->code & 7) {
case ICMP_REDIR_NET:
@@ -784,6 +782,15 @@ static void icmp_redirect(struct sk_buff *skb)
iph->saddr, skb->dev);
break;
}
+
+ /* Ping wants to see redirects.
+ * Let's pretend they are errors of sorts... */
+ if (iph->protocol == IPPROTO_ICMP &&
+ iph->ihl >= 5 &&
+ pskb_may_pull(skb, (iph->ihl<<2)+8)) {
+ ping_err(skb, icmp_hdr(skb)->un.gateway);
+ }
+
out:
return;
out_err:
@@ -933,12 +940,12 @@ static void icmp_address_reply(struct sk_buff *skb)
BUG_ON(mp == NULL);
for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
if (*mp == ifa->ifa_mask &&
- inet_ifa_match(rt->rt_src, ifa))
+ inet_ifa_match(ip_hdr(skb)->saddr, ifa))
break;
}
if (!ifa && net_ratelimit()) {
printk(KERN_INFO "Wrong address mask %pI4 from %s/%pI4\n",
- mp, dev->name, &rt->rt_src);
+ mp, dev->name, &ip_hdr(skb)->saddr);
}
}
}
@@ -1044,7 +1051,7 @@ error:
*/
static const struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = {
[ICMP_ECHOREPLY] = {
- .handler = icmp_discard,
+ .handler = ping_rcv,
},
[1] = {
.handler = icmp_discard,
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 8f62d66d085..672e476c8c8 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -303,6 +303,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
struct iphdr *pip;
struct igmpv3_report *pig;
struct net *net = dev_net(dev);
+ struct flowi4 fl4;
while (1) {
skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev),
@@ -315,18 +316,13 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
}
igmp_skb_size(skb) = size;
- rt = ip_route_output_ports(net, NULL, IGMPV3_ALL_MCR, 0,
+ rt = ip_route_output_ports(net, &fl4, NULL, IGMPV3_ALL_MCR, 0,
0, 0,
IPPROTO_IGMP, 0, dev->ifindex);
if (IS_ERR(rt)) {
kfree_skb(skb);
return NULL;
}
- if (rt->rt_src == 0) {
- kfree_skb(skb);
- ip_rt_put(rt);
- return NULL;
- }
skb_dst_set(skb, &rt->dst);
skb->dev = dev;
@@ -342,8 +338,8 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
pip->tos = 0xc0;
pip->frag_off = htons(IP_DF);
pip->ttl = 1;
- pip->daddr = rt->rt_dst;
- pip->saddr = rt->rt_src;
+ pip->daddr = fl4.daddr;
+ pip->saddr = fl4.saddr;
pip->protocol = IPPROTO_IGMP;
pip->tot_len = 0; /* filled in later */
ip_select_ident(pip, &rt->dst, NULL);
@@ -649,6 +645,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
struct net_device *dev = in_dev->dev;
struct net *net = dev_net(dev);
__be32 group = pmc ? pmc->multiaddr : 0;
+ struct flowi4 fl4;
__be32 dst;
if (type == IGMPV3_HOST_MEMBERSHIP_REPORT)
@@ -658,17 +655,12 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
else
dst = group;
- rt = ip_route_output_ports(net, NULL, dst, 0,
+ rt = ip_route_output_ports(net, &fl4, NULL, dst, 0,
0, 0,
IPPROTO_IGMP, 0, dev->ifindex);
if (IS_ERR(rt))
return -1;
- if (rt->rt_src == 0) {
- ip_rt_put(rt);
- return -1;
- }
-
skb = alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
if (skb == NULL) {
ip_rt_put(rt);
@@ -689,7 +681,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
iph->frag_off = htons(IP_DF);
iph->ttl = 1;
iph->daddr = dst;
- iph->saddr = rt->rt_src;
+ iph->saddr = fl4.saddr;
iph->protocol = IPPROTO_IGMP;
ip_select_ident(iph, &rt->dst, NULL);
((u8*)&iph[1])[0] = IPOPT_RA;
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 38f23e721b8..61fac4cabc7 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -350,30 +350,24 @@ void inet_csk_reset_keepalive_timer(struct sock *sk, unsigned long len)
EXPORT_SYMBOL(inet_csk_reset_keepalive_timer);
struct dst_entry *inet_csk_route_req(struct sock *sk,
+ struct flowi4 *fl4,
const struct request_sock *req)
{
struct rtable *rt;
const struct inet_request_sock *ireq = inet_rsk(req);
- struct ip_options *opt = inet_rsk(req)->opt;
- struct flowi4 fl4 = {
- .flowi4_oif = sk->sk_bound_dev_if,
- .flowi4_mark = sk->sk_mark,
- .daddr = ((opt && opt->srr) ?
- opt->faddr : ireq->rmt_addr),
- .saddr = ireq->loc_addr,
- .flowi4_tos = RT_CONN_FLAGS(sk),
- .flowi4_proto = sk->sk_protocol,
- .flowi4_flags = inet_sk_flowi_flags(sk),
- .fl4_sport = inet_sk(sk)->inet_sport,
- .fl4_dport = ireq->rmt_port,
- };
+ struct ip_options_rcu *opt = inet_rsk(req)->opt;
struct net *net = sock_net(sk);
- security_req_classify_flow(req, flowi4_to_flowi(&fl4));
- rt = ip_route_output_flow(net, &fl4, sk);
+ flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark,
+ RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
+ sk->sk_protocol, inet_sk_flowi_flags(sk),
+ (opt && opt->opt.srr) ? opt->opt.faddr : ireq->rmt_addr,
+ ireq->loc_addr, ireq->rmt_port, inet_sk(sk)->inet_sport);
+ security_req_classify_flow(req, flowi4_to_flowi(fl4));
+ rt = ip_route_output_flow(net, fl4, sk);
if (IS_ERR(rt))
goto no_route;
- if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
+ if (opt && opt->opt.is_strictroute && fl4->daddr != rt->rt_gateway)
goto route_err;
return &rt->dst;
@@ -385,6 +379,39 @@ no_route:
}
EXPORT_SYMBOL_GPL(inet_csk_route_req);
+struct dst_entry *inet_csk_route_child_sock(struct sock *sk,
+ struct sock *newsk,
+ const struct request_sock *req)
+{
+ const struct inet_request_sock *ireq = inet_rsk(req);
+ struct inet_sock *newinet = inet_sk(newsk);
+ struct ip_options_rcu *opt = ireq->opt;
+ struct net *net = sock_net(sk);
+ struct flowi4 *fl4;
+ struct rtable *rt;
+
+ fl4 = &newinet->cork.fl.u.ip4;
+ flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark,
+ RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
+ sk->sk_protocol, inet_sk_flowi_flags(sk),
+ (opt && opt->opt.srr) ? opt->opt.faddr : ireq->rmt_addr,
+ ireq->loc_addr, ireq->rmt_port, inet_sk(sk)->inet_sport);
+ security_req_classify_flow(req, flowi4_to_flowi(fl4));
+ rt = ip_route_output_flow(net, fl4, sk);
+ if (IS_ERR(rt))
+ goto no_route;
+ if (opt && opt->opt.is_strictroute && fl4->daddr != rt->rt_gateway)
+ goto route_err;
+ return &rt->dst;
+
+route_err:
+ ip_rt_put(rt);
+no_route:
+ IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(inet_csk_route_child_sock);
+
static inline u32 inet_synq_hash(const __be32 raddr, const __be16 rport,
const u32 rnd, const u32 synq_hsize)
{
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 2ada17129fc..6ffe94ca5bc 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -124,7 +124,7 @@ static int inet_csk_diag_fill(struct sock *sk,
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
if (r->idiag_family == AF_INET6) {
- struct ipv6_pinfo *np = inet6_sk(sk);
+ const struct ipv6_pinfo *np = inet6_sk(sk);
ipv6_addr_copy((struct in6_addr *)r->id.idiag_src,
&np->rcv_saddr);
diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c
index 47038cb6c13..85a0f75dae6 100644
--- a/net/ipv4/inet_lro.c
+++ b/net/ipv4/inet_lro.c
@@ -51,8 +51,8 @@ MODULE_DESCRIPTION("Large Receive Offload (ipv4 / tcp)");
* Basic tcp checks whether packet is suitable for LRO
*/
-static int lro_tcp_ip_check(struct iphdr *iph, struct tcphdr *tcph,
- int len, struct net_lro_desc *lro_desc)
+static int lro_tcp_ip_check(const struct iphdr *iph, const struct tcphdr *tcph,
+ int len, const struct net_lro_desc *lro_desc)
{
/* check ip header: don't aggregate padded frames */
if (ntohs(iph->tot_len) != len)
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index 99461f09320..3b34d1c8627 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -84,7 +84,7 @@ int ip_forward(struct sk_buff *skb)
rt = skb_rtable(skb);
- if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
+ if (opt->is_strictroute && ip_hdr(skb)->daddr != rt->rt_gateway)
goto sr_failed;
if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) &&
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index b1d282f11be..0ad6035f636 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -77,22 +77,40 @@ struct ipq {
struct inet_peer *peer;
};
-#define IPFRAG_ECN_CLEAR 0x01 /* one frag had INET_ECN_NOT_ECT */
-#define IPFRAG_ECN_SET_CE 0x04 /* one frag had INET_ECN_CE */
+/* RFC 3168 support :
+ * We want to check ECN values of all fragments, do detect invalid combinations.
+ * In ipq->ecn, we store the OR value of each ip4_frag_ecn() fragment value.
+ */
+#define IPFRAG_ECN_NOT_ECT 0x01 /* one frag had ECN_NOT_ECT */
+#define IPFRAG_ECN_ECT_1 0x02 /* one frag had ECN_ECT_1 */
+#define IPFRAG_ECN_ECT_0 0x04 /* one frag had ECN_ECT_0 */
+#define IPFRAG_ECN_CE 0x08 /* one frag had ECN_CE */
static inline u8 ip4_frag_ecn(u8 tos)
{
- tos = (tos & INET_ECN_MASK) + 1;
- /*
- * After the last operation we have (in binary):
- * INET_ECN_NOT_ECT => 001
- * INET_ECN_ECT_1 => 010
- * INET_ECN_ECT_0 => 011
- * INET_ECN_CE => 100
- */
- return (tos & 2) ? 0 : tos;
+ return 1 << (tos & INET_ECN_MASK);
}
+/* Given the OR values of all fragments, apply RFC 3168 5.3 requirements
+ * Value : 0xff if frame should be dropped.
+ * 0 or INET_ECN_CE value, to be ORed in to final iph->tos field
+ */
+static const u8 ip4_frag_ecn_table[16] = {
+ /* at least one fragment had CE, and others ECT_0 or ECT_1 */
+ [IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0] = INET_ECN_CE,
+ [IPFRAG_ECN_CE | IPFRAG_ECN_ECT_1] = INET_ECN_CE,
+ [IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = INET_ECN_CE,
+
+ /* invalid combinations : drop frame */
+ [IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE] = 0xff,
+ [IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_0] = 0xff,
+ [IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_1] = 0xff,
+ [IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = 0xff,
+ [IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0] = 0xff,
+ [IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_1] = 0xff,
+ [IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = 0xff,
+};
+
static struct inet_frags ip4_frags;
int ip_frag_nqueues(struct net *net)
@@ -524,9 +542,15 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
int len;
int ihlen;
int err;
+ u8 ecn;
ipq_kill(qp);
+ ecn = ip4_frag_ecn_table[qp->ecn];
+ if (unlikely(ecn == 0xff)) {
+ err = -EINVAL;
+ goto out_fail;
+ }
/* Make the one we just received the head. */
if (prev) {
head = prev->next;
@@ -605,17 +629,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
iph = ip_hdr(head);
iph->frag_off = 0;
iph->tot_len = htons(len);
- /* RFC3168 5.3 Fragmentation support
- * If one fragment had INET_ECN_NOT_ECT,
- * reassembled frame also has INET_ECN_NOT_ECT
- * Elif one fragment had INET_ECN_CE
- * reassembled frame also has INET_ECN_CE
- */
- if (qp->ecn & IPFRAG_ECN_CLEAR)
- iph->tos &= ~INET_ECN_MASK;
- else if (qp->ecn & IPFRAG_ECN_SET_CE)
- iph->tos |= INET_ECN_CE;
-
+ iph->tos |= ecn;
IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS);
qp->q.fragments = NULL;
qp->q.fragments_tail = NULL;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index da5941f18c3..8871067560d 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -413,11 +413,6 @@ static struct ip_tunnel *ipgre_tunnel_locate(struct net *net,
dev_net_set(dev, net);
- if (strchr(name, '%')) {
- if (dev_alloc_name(dev, name) < 0)
- goto failed_free;
- }
-
nt = netdev_priv(dev);
nt->parms = *parms;
dev->rtnl_link_ops = &ipgre_link_ops;
@@ -462,7 +457,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
by themself???
*/
- struct iphdr *iph = (struct iphdr *)skb->data;
+ const struct iphdr *iph = (const struct iphdr *)skb->data;
__be16 *p = (__be16*)(skb->data+(iph->ihl<<2));
int grehlen = (iph->ihl<<2) + 4;
const int type = icmp_hdr(skb)->type;
@@ -534,7 +529,7 @@ out:
rcu_read_unlock();
}
-static inline void ipgre_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
+static inline void ipgre_ecn_decapsulate(const struct iphdr *iph, struct sk_buff *skb)
{
if (INET_ECN_is_ce(iph->tos)) {
if (skb->protocol == htons(ETH_P_IP)) {
@@ -546,19 +541,19 @@ static inline void ipgre_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
}
static inline u8
-ipgre_ecn_encapsulate(u8 tos, struct iphdr *old_iph, struct sk_buff *skb)
+ipgre_ecn_encapsulate(u8 tos, const struct iphdr *old_iph, struct sk_buff *skb)
{
u8 inner = 0;
if (skb->protocol == htons(ETH_P_IP))
inner = old_iph->tos;
else if (skb->protocol == htons(ETH_P_IPV6))
- inner = ipv6_get_dsfield((struct ipv6hdr *)old_iph);
+ inner = ipv6_get_dsfield((const struct ipv6hdr *)old_iph);
return INET_ECN_encapsulate(tos, inner);
}
static int ipgre_rcv(struct sk_buff *skb)
{
- struct iphdr *iph;
+ const struct iphdr *iph;
u8 *h;
__be16 flags;
__sum16 csum = 0;
@@ -697,8 +692,9 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
{
struct ip_tunnel *tunnel = netdev_priv(dev);
struct pcpu_tstats *tstats;
- struct iphdr *old_iph = ip_hdr(skb);
- struct iphdr *tiph;
+ const struct iphdr *old_iph = ip_hdr(skb);
+ const struct iphdr *tiph;
+ struct flowi4 fl4;
u8 tos;
__be16 df;
struct rtable *rt; /* Route to the other host */
@@ -714,7 +710,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
if (dev->header_ops && dev->type == ARPHRD_IPGRE) {
gre_hlen = 0;
- tiph = (struct iphdr *)skb->data;
+ tiph = (const struct iphdr *)skb->data;
} else {
gre_hlen = tunnel->hlen;
tiph = &tunnel->parms.iph;
@@ -735,14 +731,14 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
}
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
else if (skb->protocol == htons(ETH_P_IPV6)) {
- struct in6_addr *addr6;
+ const struct in6_addr *addr6;
int addr_type;
struct neighbour *neigh = skb_dst(skb)->neighbour;
if (neigh == NULL)
goto tx_error;
- addr6 = (struct in6_addr *)&neigh->primary_key;
+ addr6 = (const struct in6_addr *)&neigh->primary_key;
addr_type = ipv6_addr_type(addr6);
if (addr_type == IPV6_ADDR_ANY) {
@@ -766,10 +762,10 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
if (skb->protocol == htons(ETH_P_IP))
tos = old_iph->tos;
else if (skb->protocol == htons(ETH_P_IPV6))
- tos = ipv6_get_dsfield((struct ipv6hdr *)old_iph);
+ tos = ipv6_get_dsfield((const struct ipv6hdr *)old_iph);
}
- rt = ip_route_output_gre(dev_net(dev), dst, tiph->saddr,
+ rt = ip_route_output_gre(dev_net(dev), &fl4, dst, tiph->saddr,
tunnel->parms.o_key, RT_TOS(tos),
tunnel->parms.link);
if (IS_ERR(rt)) {
@@ -873,15 +869,15 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
iph->frag_off = df;
iph->protocol = IPPROTO_GRE;
iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb);
- iph->daddr = rt->rt_dst;
- iph->saddr = rt->rt_src;
+ iph->daddr = fl4.daddr;
+ iph->saddr = fl4.saddr;
if ((iph->ttl = tiph->ttl) == 0) {
if (skb->protocol == htons(ETH_P_IP))
iph->ttl = old_iph->ttl;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
else if (skb->protocol == htons(ETH_P_IPV6))
- iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit;
+ iph->ttl = ((const struct ipv6hdr *)old_iph)->hop_limit;
#endif
else
iph->ttl = ip4_dst_hoplimit(&rt->dst);
@@ -927,7 +923,7 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev)
{
struct net_device *tdev = NULL;
struct ip_tunnel *tunnel;
- struct iphdr *iph;
+ const struct iphdr *iph;
int hlen = LL_MAX_HEADER;
int mtu = ETH_DATA_LEN;
int addend = sizeof(struct iphdr) + 4;
@@ -938,12 +934,14 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev)
/* Guess output device to choose reasonable mtu and needed_headroom */
if (iph->daddr) {
- struct rtable *rt = ip_route_output_gre(dev_net(dev),
- iph->daddr, iph->saddr,
- tunnel->parms.o_key,
- RT_TOS(iph->tos),
- tunnel->parms.link);
-
+ struct flowi4 fl4;
+ struct rtable *rt;
+
+ rt = ip_route_output_gre(dev_net(dev), &fl4,
+ iph->daddr, iph->saddr,
+ tunnel->parms.o_key,
+ RT_TOS(iph->tos),
+ tunnel->parms.link);
if (!IS_ERR(rt)) {
tdev = rt->dst.dev;
ip_rt_put(rt);
@@ -1180,7 +1178,7 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr)
{
- struct iphdr *iph = (struct iphdr *) skb_mac_header(skb);
+ const struct iphdr *iph = (const struct iphdr *) skb_mac_header(skb);
memcpy(haddr, &iph->saddr, 4);
return 4;
}
@@ -1196,13 +1194,15 @@ static int ipgre_open(struct net_device *dev)
struct ip_tunnel *t = netdev_priv(dev);
if (ipv4_is_multicast(t->parms.iph.daddr)) {
- struct rtable *rt = ip_route_output_gre(dev_net(dev),
- t->parms.iph.daddr,
- t->parms.iph.saddr,
- t->parms.o_key,
- RT_TOS(t->parms.iph.tos),
- t->parms.link);
-
+ struct flowi4 fl4;
+ struct rtable *rt;
+
+ rt = ip_route_output_gre(dev_net(dev), &fl4,
+ t->parms.iph.daddr,
+ t->parms.iph.saddr,
+ t->parms.o_key,
+ RT_TOS(t->parms.iph.tos),
+ t->parms.link);
if (IS_ERR(rt))
return -EADDRNOTAVAIL;
dev = rt->dst.dev;
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index d7b2b0987a3..c8f48efc5fd 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -268,7 +268,7 @@ int ip_local_deliver(struct sk_buff *skb)
static inline int ip_rcv_options(struct sk_buff *skb)
{
struct ip_options *opt;
- struct iphdr *iph;
+ const struct iphdr *iph;
struct net_device *dev = skb->dev;
/* It looks as overkill, because not all
@@ -374,7 +374,7 @@ drop:
*/
int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
{
- struct iphdr *iph;
+ const struct iphdr *iph;
u32 len;
/* When the interface is in promisc. mode, drop all the crap
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 2391b24e825..c3118e1cd3b 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -36,8 +36,8 @@
* saddr is address of outgoing interface.
*/
-void ip_options_build(struct sk_buff * skb, struct ip_options * opt,
- __be32 daddr, struct rtable *rt, int is_frag)
+void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
+ __be32 daddr, struct rtable *rt, int is_frag)
{
unsigned char *iph = skb_network_header(skb);
@@ -50,9 +50,9 @@ void ip_options_build(struct sk_buff * skb, struct ip_options * opt,
if (!is_frag) {
if (opt->rr_needaddr)
- ip_rt_get_source(iph+opt->rr+iph[opt->rr+2]-5, rt);
+ ip_rt_get_source(iph+opt->rr+iph[opt->rr+2]-5, skb, rt);
if (opt->ts_needaddr)
- ip_rt_get_source(iph+opt->ts+iph[opt->ts+2]-9, rt);
+ ip_rt_get_source(iph+opt->ts+iph[opt->ts+2]-9, skb, rt);
if (opt->ts_needtime) {
struct timespec tv;
__be32 midtime;
@@ -83,9 +83,9 @@ void ip_options_build(struct sk_buff * skb, struct ip_options * opt,
* NOTE: dopt cannot point to skb.
*/
-int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
+int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb)
{
- struct ip_options *sopt;
+ const struct ip_options *sopt;
unsigned char *sptr, *dptr;
int soffset, doffset;
int optlen;
@@ -95,10 +95,8 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
sopt = &(IPCB(skb)->opt);
- if (sopt->optlen == 0) {
- dopt->optlen = 0;
+ if (sopt->optlen == 0)
return 0;
- }
sptr = skb_network_header(skb);
dptr = dopt->__data;
@@ -157,7 +155,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
dopt->optlen += optlen;
}
if (sopt->srr) {
- unsigned char * start = sptr+sopt->srr;
+ unsigned char *start = sptr+sopt->srr;
__be32 faddr;
optlen = start[1];
@@ -499,19 +497,19 @@ void ip_options_undo(struct ip_options * opt)
}
}
-static struct ip_options *ip_options_get_alloc(const int optlen)
+static struct ip_options_rcu *ip_options_get_alloc(const int optlen)
{
- return kzalloc(sizeof(struct ip_options) + ((optlen + 3) & ~3),
+ return kzalloc(sizeof(struct ip_options_rcu) + ((optlen + 3) & ~3),
GFP_KERNEL);
}
-static int ip_options_get_finish(struct net *net, struct ip_options **optp,
- struct ip_options *opt, int optlen)
+static int ip_options_get_finish(struct net *net, struct ip_options_rcu **optp,
+ struct ip_options_rcu *opt, int optlen)
{
while (optlen & 3)
- opt->__data[optlen++] = IPOPT_END;
- opt->optlen = optlen;
- if (optlen && ip_options_compile(net, opt, NULL)) {
+ opt->opt.__data[optlen++] = IPOPT_END;
+ opt->opt.optlen = optlen;
+ if (optlen && ip_options_compile(net, &opt->opt, NULL)) {
kfree(opt);
return -EINVAL;
}
@@ -520,29 +518,29 @@ static int ip_options_get_finish(struct net *net, struct ip_options **optp,
return 0;
}
-int ip_options_get_from_user(struct net *net, struct ip_options **optp,
+int ip_options_get_from_user(struct net *net, struct ip_options_rcu **optp,
unsigned char __user *data, int optlen)
{
- struct ip_options *opt = ip_options_get_alloc(optlen);
+ struct ip_options_rcu *opt = ip_options_get_alloc(optlen);
if (!opt)
return -ENOMEM;
- if (optlen && copy_from_user(opt->__data, data, optlen)) {
+ if (optlen && copy_from_user(opt->opt.__data, data, optlen)) {
kfree(opt);
return -EFAULT;
}
return ip_options_get_finish(net, optp, opt, optlen);
}
-int ip_options_get(struct net *net, struct ip_options **optp,
+int ip_options_get(struct net *net, struct ip_options_rcu **optp,
unsigned char *data, int optlen)
{
- struct ip_options *opt = ip_options_get_alloc(optlen);
+ struct ip_options_rcu *opt = ip_options_get_alloc(optlen);
if (!opt)
return -ENOMEM;
if (optlen)
- memcpy(opt->__data, data, optlen);
+ memcpy(opt->opt.__data, data, optlen);
return ip_options_get_finish(net, optp, opt, optlen);
}
@@ -555,7 +553,7 @@ void ip_forward_options(struct sk_buff *skb)
if (opt->rr_needaddr) {
optptr = (unsigned char *)raw + opt->rr;
- ip_rt_get_source(&optptr[optptr[2]-5], rt);
+ ip_rt_get_source(&optptr[optptr[2]-5], skb, rt);
opt->is_changed = 1;
}
if (opt->srr_is_hit) {
@@ -569,19 +567,18 @@ void ip_forward_options(struct sk_buff *skb)
) {
if (srrptr + 3 > srrspace)
break;
- if (memcmp(&rt->rt_dst, &optptr[srrptr-1], 4) == 0)
+ if (memcmp(&ip_hdr(skb)->daddr, &optptr[srrptr-1], 4) == 0)
break;
}
if (srrptr + 3 <= srrspace) {
opt->is_changed = 1;
- ip_rt_get_source(&optptr[srrptr-1], rt);
- ip_hdr(skb)->daddr = rt->rt_dst;
+ ip_rt_get_source(&optptr[srrptr-1], skb, rt);
optptr[2] = srrptr+4;
} else if (net_ratelimit())
printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");
if (opt->ts_needaddr) {
optptr = raw + opt->ts;
- ip_rt_get_source(&optptr[optptr[2]-9], rt);
+ ip_rt_get_source(&optptr[optptr[2]-9], skb, rt);
opt->is_changed = 1;
}
}
@@ -603,7 +600,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)
unsigned long orefdst;
int err;
- if (!opt->srr || !rt)
+ if (!rt)
return 0;
if (skb->pkt_type != PACKET_HOST)
@@ -637,7 +634,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)
if (rt2->rt_type != RTN_LOCAL)
break;
/* Superfast 8) loopback forward */
- memcpy(&iph->daddr, &optptr[srrptr-1], 4);
+ iph->daddr = nexthop;
opt->is_changed = 1;
}
if (srrptr <= srrspace) {
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 459c011b1d4..98af3697c71 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -140,14 +140,14 @@ static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst)
*
*/
int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
- __be32 saddr, __be32 daddr, struct ip_options *opt)
+ __be32 saddr, __be32 daddr, struct ip_options_rcu *opt)
{
struct inet_sock *inet = inet_sk(sk);
struct rtable *rt = skb_rtable(skb);
struct iphdr *iph;
/* Build the IP header. */
- skb_push(skb, sizeof(struct iphdr) + (opt ? opt->optlen : 0));
+ skb_push(skb, sizeof(struct iphdr) + (opt ? opt->opt.optlen : 0));
skb_reset_network_header(skb);
iph = ip_hdr(skb);
iph->version = 4;
@@ -158,14 +158,14 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
else
iph->frag_off = 0;
iph->ttl = ip_select_ttl(inet, &rt->dst);
- iph->daddr = rt->rt_dst;
- iph->saddr = rt->rt_src;
+ iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr);
+ iph->saddr = saddr;
iph->protocol = sk->sk_protocol;
ip_select_ident(iph, &rt->dst, sk);
- if (opt && opt->optlen) {
- iph->ihl += opt->optlen>>2;
- ip_options_build(skb, opt, daddr, rt, 0);
+ if (opt && opt->opt.optlen) {
+ iph->ihl += opt->opt.optlen>>2;
+ ip_options_build(skb, &opt->opt, daddr, rt, 0);
}
skb->priority = sk->sk_priority;
@@ -312,11 +312,12 @@ int ip_output(struct sk_buff *skb)
!(IPCB(skb)->flags & IPSKB_REROUTED));
}
-int ip_queue_xmit(struct sk_buff *skb)
+int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl)
{
struct sock *sk = skb->sk;
struct inet_sock *inet = inet_sk(sk);
- struct ip_options *opt = inet->opt;
+ struct ip_options_rcu *inet_opt;
+ struct flowi4 *fl4;
struct rtable *rt;
struct iphdr *iph;
int res;
@@ -325,6 +326,8 @@ int ip_queue_xmit(struct sk_buff *skb)
* f.e. by something like SCTP.
*/
rcu_read_lock();
+ inet_opt = rcu_dereference(inet->inet_opt);
+ fl4 = &fl->u.ip4;
rt = skb_rtable(skb);
if (rt != NULL)
goto packet_routed;
@@ -336,14 +339,14 @@ int ip_queue_xmit(struct sk_buff *skb)
/* Use correct destination address if we have options. */
daddr = inet->inet_daddr;
- if(opt && opt->srr)
- daddr = opt->faddr;
+ if (inet_opt && inet_opt->opt.srr)
+ daddr = inet_opt->opt.faddr;
/* If this fails, retransmit mechanism of transport layer will
* keep trying until route appears or the connection times
* itself out.
*/
- rt = ip_route_output_ports(sock_net(sk), sk,
+ rt = ip_route_output_ports(sock_net(sk), fl4, sk,
daddr, inet->inet_saddr,
inet->inet_dport,
inet->inet_sport,
@@ -357,11 +360,11 @@ int ip_queue_xmit(struct sk_buff *skb)
skb_dst_set_noref(skb, &rt->dst);
packet_routed:
- if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
+ if (inet_opt && inet_opt->opt.is_strictroute && fl4->daddr != rt->rt_gateway)
goto no_route;
/* OK, we know where to send it, allocate and build IP header. */
- skb_push(skb, sizeof(struct iphdr) + (opt ? opt->optlen : 0));
+ skb_push(skb, sizeof(struct iphdr) + (inet_opt ? inet_opt->opt.optlen : 0));
skb_reset_network_header(skb);
iph = ip_hdr(skb);
*((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff));
@@ -371,13 +374,13 @@ packet_routed:
iph->frag_off = 0;
iph->ttl = ip_select_ttl(inet, &rt->dst);
iph->protocol = sk->sk_protocol;
- iph->saddr = rt->rt_src;
- iph->daddr = rt->rt_dst;
+ iph->saddr = fl4->saddr;
+ iph->daddr = fl4->daddr;
/* Transport layer set skb->h.foo itself. */
- if (opt && opt->optlen) {
- iph->ihl += opt->optlen >> 2;
- ip_options_build(skb, opt, inet->inet_daddr, rt, 0);
+ if (inet_opt && inet_opt->opt.optlen) {
+ iph->ihl += inet_opt->opt.optlen >> 2;
+ ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0);
}
ip_select_ident_more(iph, &rt->dst, sk,
@@ -773,7 +776,9 @@ static inline int ip_ufo_append_data(struct sock *sk,
(length - transhdrlen));
}
-static int __ip_append_data(struct sock *sk, struct sk_buff_head *queue,
+static int __ip_append_data(struct sock *sk,
+ struct flowi4 *fl4,
+ struct sk_buff_head *queue,
struct inet_cork *cork,
int getfrag(void *from, char *to, int offset,
int len, int odd, struct sk_buff *skb),
@@ -805,7 +810,7 @@ static int __ip_append_data(struct sock *sk, struct sk_buff_head *queue,
maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen;
if (cork->length + length > 0xFFFF - fragheaderlen) {
- ip_local_error(sk, EMSGSIZE, rt->rt_dst, inet->inet_dport,
+ ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport,
mtu-exthdrlen);
return -EMSGSIZE;
}
@@ -1033,7 +1038,7 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
struct ipcm_cookie *ipc, struct rtable **rtp)
{
struct inet_sock *inet = inet_sk(sk);
- struct ip_options *opt;
+ struct ip_options_rcu *opt;
struct rtable *rt;
/*
@@ -1047,7 +1052,7 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
if (unlikely(cork->opt == NULL))
return -ENOBUFS;
}
- memcpy(cork->opt, opt, sizeof(struct ip_options) + opt->optlen);
+ memcpy(cork->opt, &opt->opt, sizeof(struct ip_options) + opt->opt.optlen);
cork->flags |= IPCORK_OPT;
cork->addr = ipc->addr;
}
@@ -1080,7 +1085,7 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
*
* LATER: length must be adjusted by pad at tail, when it is required.
*/
-int ip_append_data(struct sock *sk,
+int ip_append_data(struct sock *sk, struct flowi4 *fl4,
int getfrag(void *from, char *to, int offset, int len,
int odd, struct sk_buff *skb),
void *from, int length, int transhdrlen,
@@ -1094,24 +1099,25 @@ int ip_append_data(struct sock *sk,
return 0;
if (skb_queue_empty(&sk->sk_write_queue)) {
- err = ip_setup_cork(sk, &inet->cork, ipc, rtp);
+ err = ip_setup_cork(sk, &inet->cork.base, ipc, rtp);
if (err)
return err;
} else {
transhdrlen = 0;
}
- return __ip_append_data(sk, &sk->sk_write_queue, &inet->cork, getfrag,
+ return __ip_append_data(sk, fl4, &sk->sk_write_queue, &inet->cork.base, getfrag,
from, length, transhdrlen, flags);
}
-ssize_t ip_append_page(struct sock *sk, struct page *page,
+ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
int offset, size_t size, int flags)
{
struct inet_sock *inet = inet_sk(sk);
struct sk_buff *skb;
struct rtable *rt;
struct ip_options *opt = NULL;
+ struct inet_cork *cork;
int hh_len;
int mtu;
int len;
@@ -1127,28 +1133,29 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
if (skb_queue_empty(&sk->sk_write_queue))
return -EINVAL;
- rt = (struct rtable *)inet->cork.dst;
- if (inet->cork.flags & IPCORK_OPT)
- opt = inet->cork.opt;
+ cork = &inet->cork.base;
+ rt = (struct rtable *)cork->dst;
+ if (cork->flags & IPCORK_OPT)
+ opt = cork->opt;
if (!(rt->dst.dev->features&NETIF_F_SG))
return -EOPNOTSUPP;
hh_len = LL_RESERVED_SPACE(rt->dst.dev);
- mtu = inet->cork.fragsize;
+ mtu = cork->fragsize;
fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen;
- if (inet->cork.length + size > 0xFFFF - fragheaderlen) {
- ip_local_error(sk, EMSGSIZE, rt->rt_dst, inet->inet_dport, mtu);
+ if (cork->length + size > 0xFFFF - fragheaderlen) {
+ ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, mtu);
return -EMSGSIZE;
}
if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL)
return -EINVAL;
- inet->cork.length += size;
+ cork->length += size;
if ((size + skb->len > mtu) &&
(sk->sk_protocol == IPPROTO_UDP) &&
(rt->dst.dev->features & NETIF_F_UFO)) {
@@ -1243,7 +1250,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
return 0;
error:
- inet->cork.length -= size;
+ cork->length -= size;
IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTDISCARDS);
return err;
}
@@ -1262,6 +1269,7 @@ static void ip_cork_release(struct inet_cork *cork)
* and push them out.
*/
struct sk_buff *__ip_make_skb(struct sock *sk,
+ struct flowi4 *fl4,
struct sk_buff_head *queue,
struct inet_cork *cork)
{
@@ -1319,17 +1327,18 @@ struct sk_buff *__ip_make_skb(struct sock *sk,
iph = (struct iphdr *)skb->data;
iph->version = 4;
iph->ihl = 5;
- if (opt) {
- iph->ihl += opt->optlen>>2;
- ip_options_build(skb, opt, cork->addr, rt, 0);
- }
iph->tos = inet->tos;
iph->frag_off = df;
ip_select_ident(iph, &rt->dst, sk);
iph->ttl = ttl;
iph->protocol = sk->sk_protocol;
- iph->saddr = rt->rt_src;
- iph->daddr = rt->rt_dst;
+ iph->saddr = fl4->saddr;
+ iph->daddr = fl4->daddr;
+
+ if (opt) {
+ iph->ihl += opt->optlen>>2;
+ ip_options_build(skb, opt, cork->addr, rt, 0);
+ }
skb->priority = sk->sk_priority;
skb->mark = sk->sk_mark;
@@ -1365,11 +1374,11 @@ int ip_send_skb(struct sk_buff *skb)
return err;
}
-int ip_push_pending_frames(struct sock *sk)
+int ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4)
{
struct sk_buff *skb;
- skb = ip_finish_skb(sk);
+ skb = ip_finish_skb(sk, fl4);
if (!skb)
return 0;
@@ -1394,17 +1403,18 @@ static void __ip_flush_pending_frames(struct sock *sk,
void ip_flush_pending_frames(struct sock *sk)
{
- __ip_flush_pending_frames(sk, &sk->sk_write_queue, &inet_sk(sk)->cork);
+ __ip_flush_pending_frames(sk, &sk->sk_write_queue, &inet_sk(sk)->cork.base);
}
struct sk_buff *ip_make_skb(struct sock *sk,
+ struct flowi4 *fl4,
int getfrag(void *from, char *to, int offset,
int len, int odd, struct sk_buff *skb),
void *from, int length, int transhdrlen,
struct ipcm_cookie *ipc, struct rtable **rtp,
unsigned int flags)
{
- struct inet_cork cork = {};
+ struct inet_cork cork;
struct sk_buff_head queue;
int err;
@@ -1413,18 +1423,21 @@ struct sk_buff *ip_make_skb(struct sock *sk,
__skb_queue_head_init(&queue);
+ cork.flags = 0;
+ cork.addr = 0;
+ cork.opt = NULL;
err = ip_setup_cork(sk, &cork, ipc, rtp);
if (err)
return ERR_PTR(err);
- err = __ip_append_data(sk, &queue, &cork, getfrag,
+ err = __ip_append_data(sk, fl4, &queue, &cork, getfrag,
from, length, transhdrlen, flags);
if (err) {
__ip_flush_pending_frames(sk, &queue, &cork);
return ERR_PTR(err);
}
- return __ip_make_skb(sk, &queue, &cork);
+ return __ip_make_skb(sk, fl4, &queue, &cork);
}
/*
@@ -1447,48 +1460,39 @@ 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.
*/
-void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg,
- unsigned int len)
+void ip_send_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr,
+ struct ip_reply_arg *arg, unsigned int len)
{
struct inet_sock *inet = inet_sk(sk);
- struct {
- struct ip_options opt;
- char data[40];
- } replyopts;
+ struct ip_options_data replyopts;
struct ipcm_cookie ipc;
- __be32 daddr;
+ struct flowi4 fl4;
struct rtable *rt = skb_rtable(skb);
- if (ip_options_echo(&replyopts.opt, skb))
+ if (ip_options_echo(&replyopts.opt.opt, skb))
return;
- daddr = ipc.addr = rt->rt_src;
+ ipc.addr = daddr;
ipc.opt = NULL;
ipc.tx_flags = 0;
- if (replyopts.opt.optlen) {
+ if (replyopts.opt.opt.optlen) {
ipc.opt = &replyopts.opt;
- if (ipc.opt->srr)
- daddr = replyopts.opt.faddr;
+ if (replyopts.opt.opt.srr)
+ daddr = replyopts.opt.opt.faddr;
}
- {
- struct flowi4 fl4 = {
- .flowi4_oif = arg->bound_dev_if,
- .daddr = daddr,
- .saddr = rt->rt_spec_dst,
- .flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
- .fl4_sport = tcp_hdr(skb)->dest,
- .fl4_dport = tcp_hdr(skb)->source,
- .flowi4_proto = sk->sk_protocol,
- .flowi4_flags = ip_reply_arg_flowi_flags(arg),
- };
- security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
- rt = ip_route_output_key(sock_net(sk), &fl4);
- if (IS_ERR(rt))
- return;
- }
+ flowi4_init_output(&fl4, arg->bound_dev_if, 0,
+ RT_TOS(ip_hdr(skb)->tos),
+ RT_SCOPE_UNIVERSE, sk->sk_protocol,
+ ip_reply_arg_flowi_flags(arg),
+ daddr, rt->rt_spec_dst,
+ tcp_hdr(skb)->source, tcp_hdr(skb)->dest);
+ security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
+ rt = ip_route_output_key(sock_net(sk), &fl4);
+ if (IS_ERR(rt))
+ return;
/* And let IP do all the hard work.
@@ -1501,7 +1505,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
sk->sk_priority = skb->priority;
sk->sk_protocol = ip_hdr(skb)->protocol;
sk->sk_bound_dev_if = arg->bound_dev_if;
- ip_append_data(sk, ip_reply_glue_bits, arg->iov->iov_base, len, 0,
+ ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base, len, 0,
&ipc, &rt, MSG_DONTWAIT);
if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) {
if (arg->csumoffset >= 0)
@@ -1509,7 +1513,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
arg->csumoffset) = csum_fold(csum_add(skb->csum,
arg->csum));
skb->ip_summed = CHECKSUM_NONE;
- ip_push_pending_frames(sk);
+ ip_push_pending_frames(sk, &fl4);
}
bh_unlock_sock(sk);
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 3948c86e59c..ab0c9efd1ef 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -131,7 +131,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
static void ip_cmsg_recv_dstaddr(struct msghdr *msg, struct sk_buff *skb)
{
struct sockaddr_in sin;
- struct iphdr *iph = ip_hdr(skb);
+ const struct iphdr *iph = ip_hdr(skb);
__be16 *ports = (__be16 *)skb_transport_header(skb);
if (skb_transport_offset(skb) + 4 > skb->len)
@@ -451,6 +451,11 @@ out:
}
+static void opt_kfree_rcu(struct rcu_head *head)
+{
+ kfree(container_of(head, struct ip_options_rcu, rcu));
+}
+
/*
* Socket option code for IP. This is the end of the line after any
* TCP,UDP etc options on an IP socket.
@@ -497,13 +502,16 @@ static int do_ip_setsockopt(struct sock *sk, int level,
switch (optname) {
case IP_OPTIONS:
{
- struct ip_options *opt = NULL;
+ struct ip_options_rcu *old, *opt = NULL;
+
if (optlen > 40)
goto e_inval;
err = ip_options_get_from_user(sock_net(sk), &opt,
optval, optlen);
if (err)
break;
+ old = rcu_dereference_protected(inet->inet_opt,
+ sock_owned_by_user(sk));
if (inet->is_icsk) {
struct inet_connection_sock *icsk = inet_csk(sk);
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -512,17 +520,18 @@ static int do_ip_setsockopt(struct sock *sk, int level,
(TCPF_LISTEN | TCPF_CLOSE)) &&
inet->inet_daddr != LOOPBACK4_IPV6)) {
#endif
- if (inet->opt)
- icsk->icsk_ext_hdr_len -= inet->opt->optlen;
+ if (old)
+ icsk->icsk_ext_hdr_len -= old->opt.optlen;
if (opt)
- icsk->icsk_ext_hdr_len += opt->optlen;
+ icsk->icsk_ext_hdr_len += opt->opt.optlen;
icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
}
#endif
}
- opt = xchg(&inet->opt, opt);
- kfree(opt);
+ rcu_assign_pointer(inet->inet_opt, opt);
+ if (old)
+ call_rcu(&old->rcu, opt_kfree_rcu);
break;
}
case IP_PKTINFO:
@@ -1081,12 +1090,16 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
case IP_OPTIONS:
{
unsigned char optbuf[sizeof(struct ip_options)+40];
- struct ip_options * opt = (struct ip_options *)optbuf;
+ struct ip_options *opt = (struct ip_options *)optbuf;
+ struct ip_options_rcu *inet_opt;
+
+ inet_opt = rcu_dereference_protected(inet->inet_opt,
+ sock_owned_by_user(sk));
opt->optlen = 0;
- if (inet->opt)
- memcpy(optbuf, inet->opt,
- sizeof(struct ip_options)+
- inet->opt->optlen);
+ if (inet_opt)
+ memcpy(optbuf, &inet_opt->opt,
+ sizeof(struct ip_options) +
+ inet_opt->opt.optlen);
release_sock(sk);
if (opt->optlen == 0)
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 629067571f0..c857f6f49b0 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -27,7 +27,7 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)
{
struct net *net = dev_net(skb->dev);
__be32 spi;
- struct iphdr *iph = (struct iphdr *)skb->data;
+ const struct iphdr *iph = (const struct iphdr *)skb->data;
struct ip_comp_hdr *ipch = (struct ip_comp_hdr *)(skb->data+(iph->ihl<<2));
struct xfrm_state *x;
@@ -36,7 +36,7 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)
return;
spi = htonl(ntohs(ipch->cpi));
- x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr,
+ x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr,
spi, IPPROTO_COMP, AF_INET);
if (!x)
return;
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index cbff2ecccf3..ab7e5542c1c 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -87,8 +87,8 @@
#endif
/* Define the friendly delay before and after opening net devices */
-#define CONF_PRE_OPEN 500 /* Before opening: 1/2 second */
-#define CONF_POST_OPEN 1 /* After opening: 1 second */
+#define CONF_POST_OPEN 10 /* After opening: 10 msecs */
+#define CONF_CARRIER_TIMEOUT 120000 /* Wait for carrier timeout */
/* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */
#define CONF_OPEN_RETRIES 2 /* (Re)open devices twice */
@@ -188,14 +188,14 @@ struct ic_device {
static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */
static struct net_device *ic_dev __initdata = NULL; /* Selected device */
-static bool __init ic_device_match(struct net_device *dev)
+static bool __init ic_is_init_dev(struct net_device *dev)
{
- if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
+ if (dev->flags & IFF_LOOPBACK)
+ return false;
+ return user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
(!(dev->flags & IFF_LOOPBACK) &&
(dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
- strncmp(dev->name, "dummy", 5)))
- return true;
- return false;
+ strncmp(dev->name, "dummy", 5));
}
static int __init ic_open_devs(void)
@@ -203,6 +203,7 @@ static int __init ic_open_devs(void)
struct ic_device *d, **last;
struct net_device *dev;
unsigned short oflags;
+ unsigned long start;
last = &ic_first_dev;
rtnl_lock();
@@ -216,9 +217,7 @@ static int __init ic_open_devs(void)
}
for_each_netdev(&init_net, dev) {
- if (dev->flags & IFF_LOOPBACK)
- continue;
- if (ic_device_match(dev)) {
+ if (ic_is_init_dev(dev)) {
int able = 0;
if (dev->mtu >= 364)
able |= IC_BOOTP;
@@ -252,6 +251,17 @@ static int __init ic_open_devs(void)
dev->name, able, d->xid));
}
}
+
+ /* wait for a carrier on at least one device */
+ start = jiffies;
+ while (jiffies - start < msecs_to_jiffies(CONF_CARRIER_TIMEOUT)) {
+ for_each_netdev(&init_net, dev)
+ if (ic_is_init_dev(dev) && netif_carrier_ok(dev))
+ goto have_carrier;
+
+ msleep(1);
+ }
+have_carrier:
rtnl_unlock();
*last = NULL;
@@ -1324,14 +1334,13 @@ static int __init wait_for_devices(void)
{
int i;
- msleep(CONF_PRE_OPEN);
for (i = 0; i < DEVICE_WAIT_MAX; i++) {
struct net_device *dev;
int found = 0;
rtnl_lock();
for_each_netdev(&init_net, dev) {
- if (ic_device_match(dev)) {
+ if (ic_is_init_dev(dev)) {
found = 1;
break;
}
@@ -1378,7 +1387,7 @@ static int __init ip_auto_config(void)
return err;
/* Give drivers a chance to settle */
- ssleep(CONF_POST_OPEN);
+ msleep(CONF_POST_OPEN);
/*
* If the config information is insufficient (e.g., our IP address or
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index bfc17c5914e..378b20b7ca6 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -276,11 +276,6 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net,
dev_net_set(dev, net);
- if (strchr(name, '%')) {
- if (dev_alloc_name(dev, name) < 0)
- goto failed_free;
- }
-
nt = netdev_priv(dev);
nt->parms = *parms;
@@ -319,7 +314,7 @@ static int ipip_err(struct sk_buff *skb, u32 info)
8 bytes of packet payload. It means, that precise relaying of
ICMP in the real Internet is absolutely infeasible.
*/
- struct iphdr *iph = (struct iphdr *)skb->data;
+ const struct iphdr *iph = (const struct iphdr *)skb->data;
const int type = icmp_hdr(skb)->type;
const int code = icmp_hdr(skb)->code;
struct ip_tunnel *t;
@@ -433,15 +428,16 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
struct pcpu_tstats *tstats;
- struct iphdr *tiph = &tunnel->parms.iph;
+ const struct iphdr *tiph = &tunnel->parms.iph;
u8 tos = tunnel->parms.iph.tos;
__be16 df = tiph->frag_off;
struct rtable *rt; /* Route to the other host */
struct net_device *tdev; /* Device to other host */
- struct iphdr *old_iph = ip_hdr(skb);
+ const struct iphdr *old_iph = ip_hdr(skb);
struct iphdr *iph; /* Our new IP header */
unsigned int max_headroom; /* The extra header space needed */
__be32 dst = tiph->daddr;
+ struct flowi4 fl4;
int mtu;
if (skb->protocol != htons(ETH_P_IP))
@@ -460,7 +456,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
goto tx_error_icmp;
}
- rt = ip_route_output_ports(dev_net(dev), NULL,
+ rt = ip_route_output_ports(dev_net(dev), &fl4, NULL,
dst, tiph->saddr,
0, 0,
IPPROTO_IPIP, RT_TOS(tos),
@@ -549,8 +545,8 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
iph->frag_off = df;
iph->protocol = IPPROTO_IPIP;
iph->tos = INET_ECN_encapsulate(tos, old_iph->tos);
- iph->daddr = rt->rt_dst;
- iph->saddr = rt->rt_src;
+ iph->daddr = fl4.daddr;
+ iph->saddr = fl4.saddr;
if ((iph->ttl = tiph->ttl) == 0)
iph->ttl = old_iph->ttl;
@@ -572,19 +568,21 @@ static void ipip_tunnel_bind_dev(struct net_device *dev)
{
struct net_device *tdev = NULL;
struct ip_tunnel *tunnel;
- struct iphdr *iph;
+ const struct iphdr *iph;
tunnel = netdev_priv(dev);
iph = &tunnel->parms.iph;
if (iph->daddr) {
- struct rtable *rt = ip_route_output_ports(dev_net(dev), NULL,
- iph->daddr, iph->saddr,
- 0, 0,
- IPPROTO_IPIP,
- RT_TOS(iph->tos),
- tunnel->parms.link);
-
+ struct rtable *rt;
+ struct flowi4 fl4;
+
+ rt = ip_route_output_ports(dev_net(dev), &fl4, NULL,
+ iph->daddr, iph->saddr,
+ 0, 0,
+ IPPROTO_IPIP,
+ RT_TOS(iph->tos),
+ tunnel->parms.link);
if (!IS_ERR(rt)) {
tdev = rt->dst.dev;
ip_rt_put(rt);
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 1f62eaeb6de..30a7763c400 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1549,7 +1549,7 @@ static struct notifier_block ip_mr_notifier = {
static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr)
{
struct iphdr *iph;
- struct iphdr *old_iph = ip_hdr(skb);
+ const struct iphdr *old_iph = ip_hdr(skb);
skb_push(skb, sizeof(struct iphdr));
skb->transport_header = skb->network_header;
@@ -1595,6 +1595,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
struct vif_device *vif = &mrt->vif_table[vifi];
struct net_device *dev;
struct rtable *rt;
+ struct flowi4 fl4;
int encap = 0;
if (vif->dev == NULL)
@@ -1612,7 +1613,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
#endif
if (vif->flags & VIFF_TUNNEL) {
- rt = ip_route_output_ports(net, NULL,
+ rt = ip_route_output_ports(net, &fl4, NULL,
vif->remote, vif->local,
0, 0,
IPPROTO_IPIP,
@@ -1621,7 +1622,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
goto out_free;
encap = sizeof(struct iphdr);
} else {
- rt = ip_route_output_ports(net, NULL, iph->daddr, 0,
+ rt = ip_route_output_ports(net, &fl4, NULL, iph->daddr, 0,
0, 0,
IPPROTO_IPIP,
RT_TOS(iph->tos), vif->link);
@@ -1788,12 +1789,14 @@ dont_forward:
return 0;
}
-static struct mr_table *ipmr_rt_fib_lookup(struct net *net, struct rtable *rt)
+static struct mr_table *ipmr_rt_fib_lookup(struct net *net, struct sk_buff *skb)
{
+ struct rtable *rt = skb_rtable(skb);
+ struct iphdr *iph = ip_hdr(skb);
struct flowi4 fl4 = {
- .daddr = rt->rt_key_dst,
- .saddr = rt->rt_key_src,
- .flowi4_tos = rt->rt_tos,
+ .daddr = iph->daddr,
+ .saddr = iph->saddr,
+ .flowi4_tos = iph->tos,
.flowi4_oif = rt->rt_oif,
.flowi4_iif = rt->rt_iif,
.flowi4_mark = rt->rt_mark,
@@ -1825,7 +1828,7 @@ int ip_mr_input(struct sk_buff *skb)
if (IPCB(skb)->flags & IPSKB_FORWARDED)
goto dont_forward;
- mrt = ipmr_rt_fib_lookup(net, skb_rtable(skb));
+ mrt = ipmr_rt_fib_lookup(net, skb);
if (IS_ERR(mrt)) {
kfree_skb(skb);
return PTR_ERR(mrt);
@@ -1957,7 +1960,7 @@ int pim_rcv_v1(struct sk_buff *skb)
pim = igmp_hdr(skb);
- mrt = ipmr_rt_fib_lookup(net, skb_rtable(skb));
+ mrt = ipmr_rt_fib_lookup(net, skb);
if (IS_ERR(mrt))
goto drop;
if (!mrt->mroute_do_pim ||
@@ -1989,7 +1992,7 @@ static int pim_rcv(struct sk_buff *skb)
csum_fold(skb_checksum(skb, 0, skb->len, 0))))
goto drop;
- mrt = ipmr_rt_fib_lookup(net, skb_rtable(skb));
+ mrt = ipmr_rt_fib_lookup(net, skb);
if (IS_ERR(mrt))
goto drop;
if (__pim_rcv(mrt, skb, sizeof(*pim))) {
@@ -2038,20 +2041,20 @@ rtattr_failure:
return -EMSGSIZE;
}
-int ipmr_get_route(struct net *net,
- struct sk_buff *skb, struct rtmsg *rtm, int nowait)
+int ipmr_get_route(struct net *net, struct sk_buff *skb,
+ __be32 saddr, __be32 daddr,
+ struct rtmsg *rtm, int nowait)
{
- int err;
- struct mr_table *mrt;
struct mfc_cache *cache;
- struct rtable *rt = skb_rtable(skb);
+ struct mr_table *mrt;
+ int err;
mrt = ipmr_get_table(net, RT_TABLE_DEFAULT);
if (mrt == NULL)
return -ENOENT;
rcu_read_lock();
- cache = ipmr_cache_find(mrt, rt->rt_src, rt->rt_dst);
+ cache = ipmr_cache_find(mrt, saddr, daddr);
if (cache == NULL) {
struct sk_buff *skb2;
@@ -2084,8 +2087,8 @@ int ipmr_get_route(struct net *net,
skb_reset_network_header(skb2);
iph = ip_hdr(skb2);
iph->ihl = sizeof(struct iphdr) >> 2;
- iph->saddr = rt->rt_src;
- iph->daddr = rt->rt_dst;
+ iph->saddr = saddr;
+ iph->daddr = daddr;
iph->version = 0;
err = ipmr_cache_unresolved(mrt, vif, skb2);
read_unlock(&mrt_lock);
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 89bc7e66d59..fd7a3f68917 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -260,6 +260,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
void *table_base;
const struct xt_table_info *private;
struct xt_action_param acpar;
+ unsigned int addend;
if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
return NF_DROP;
@@ -267,7 +268,8 @@ unsigned int arpt_do_table(struct sk_buff *skb,
indev = in ? in->name : nulldevname;
outdev = out ? out->name : nulldevname;
- xt_info_rdlock_bh();
+ local_bh_disable();
+ addend = xt_write_recseq_begin();
private = table->private;
table_base = private->entries[smp_processor_id()];
@@ -338,7 +340,8 @@ unsigned int arpt_do_table(struct sk_buff *skb,
/* Verdict */
break;
} while (!acpar.hotdrop);
- xt_info_rdunlock_bh();
+ xt_write_recseq_end(addend);
+ local_bh_enable();
if (acpar.hotdrop)
return NF_DROP;
@@ -712,7 +715,7 @@ static void get_counters(const struct xt_table_info *t,
unsigned int i;
for_each_possible_cpu(cpu) {
- seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock;
+ seqcount_t *s = &per_cpu(xt_recseq, cpu);
i = 0;
xt_entry_foreach(iter, t->entries[cpu], t->size) {
@@ -720,10 +723,10 @@ static void get_counters(const struct xt_table_info *t,
unsigned int start;
do {
- start = read_seqbegin(lock);
+ start = read_seqcount_begin(s);
bcnt = iter->counters.bcnt;
pcnt = iter->counters.pcnt;
- } while (read_seqretry(lock, start));
+ } while (read_seqcount_retry(s, start));
ADD_COUNTER(counters[i], bcnt, pcnt);
++i;
@@ -1115,6 +1118,7 @@ static int do_add_counters(struct net *net, const void __user *user,
int ret = 0;
void *loc_cpu_entry;
struct arpt_entry *iter;
+ unsigned int addend;
#ifdef CONFIG_COMPAT
struct compat_xt_counters_info compat_tmp;
@@ -1171,12 +1175,12 @@ static int do_add_counters(struct net *net, const void __user *user,
/* Choose the copy that is on our node */
curcpu = smp_processor_id();
loc_cpu_entry = private->entries[curcpu];
- xt_info_wrlock(curcpu);
+ addend = xt_write_recseq_begin();
xt_entry_foreach(iter, loc_cpu_entry, private->size) {
ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt);
++i;
}
- xt_info_wrunlock(curcpu);
+ xt_write_recseq_end(addend);
unlock_up_free:
local_bh_enable();
xt_table_unlock(t);
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 70491502800..76474384350 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -68,15 +68,6 @@ void *ipt_alloc_initial_table(const struct xt_table *info)
}
EXPORT_SYMBOL_GPL(ipt_alloc_initial_table);
-/*
- We keep a set of rules for each CPU, so we can avoid write-locking
- them in the softirq when updating the counters and therefore
- only need to read-lock in the softirq; doing a write_lock_bh() in user
- context stops packets coming through and allows user context to read
- the counters or update the rules.
-
- Hence the start of any table is given by get_table() below. */
-
/* Returns whether matches rule or not. */
/* Performance critical - called for every packet */
static inline bool
@@ -311,6 +302,7 @@ ipt_do_table(struct sk_buff *skb,
unsigned int *stackptr, origptr, cpu;
const struct xt_table_info *private;
struct xt_action_param acpar;
+ unsigned int addend;
/* Initialization */
ip = ip_hdr(skb);
@@ -331,7 +323,8 @@ ipt_do_table(struct sk_buff *skb,
acpar.hooknum = hook;
IP_NF_ASSERT(table->valid_hooks & (1 << hook));
- xt_info_rdlock_bh();
+ local_bh_disable();
+ addend = xt_write_recseq_begin();
private = table->private;
cpu = smp_processor_id();
table_base = private->entries[cpu];
@@ -430,7 +423,9 @@ ipt_do_table(struct sk_buff *skb,
pr_debug("Exiting %s; resetting sp from %u to %u\n",
__func__, *stackptr, origptr);
*stackptr = origptr;
- xt_info_rdunlock_bh();
+ xt_write_recseq_end(addend);
+ local_bh_enable();
+
#ifdef DEBUG_ALLOW_ALL
return NF_ACCEPT;
#else
@@ -886,7 +881,7 @@ get_counters(const struct xt_table_info *t,
unsigned int i;
for_each_possible_cpu(cpu) {
- seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock;
+ seqcount_t *s = &per_cpu(xt_recseq, cpu);
i = 0;
xt_entry_foreach(iter, t->entries[cpu], t->size) {
@@ -894,10 +889,10 @@ get_counters(const struct xt_table_info *t,
unsigned int start;
do {
- start = read_seqbegin(lock);
+ start = read_seqcount_begin(s);
bcnt = iter->counters.bcnt;
pcnt = iter->counters.pcnt;
- } while (read_seqretry(lock, start));
+ } while (read_seqcount_retry(s, start));
ADD_COUNTER(counters[i], bcnt, pcnt);
++i; /* macro does multi eval of i */
@@ -1312,6 +1307,7 @@ do_add_counters(struct net *net, const void __user *user,
int ret = 0;
void *loc_cpu_entry;
struct ipt_entry *iter;
+ unsigned int addend;
#ifdef CONFIG_COMPAT
struct compat_xt_counters_info compat_tmp;
@@ -1368,12 +1364,12 @@ do_add_counters(struct net *net, const void __user *user,
/* Choose the copy that is on our node */
curcpu = smp_processor_id();
loc_cpu_entry = private->entries[curcpu];
- xt_info_wrlock(curcpu);
+ addend = xt_write_recseq_begin();
xt_entry_foreach(iter, loc_cpu_entry, private->size) {
ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt);
++i;
}
- xt_info_wrunlock(curcpu);
+ xt_write_recseq_end(addend);
unlock_up_free:
local_bh_enable();
xt_table_unlock(t);
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index 31427fb57aa..99cfa28b6d3 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -153,7 +153,7 @@ void nf_nat_set_seq_adjust(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
}
EXPORT_SYMBOL_GPL(nf_nat_set_seq_adjust);
-static void nf_nat_csum(struct sk_buff *skb, struct iphdr *iph, void *data,
+static void nf_nat_csum(struct sk_buff *skb, const struct iphdr *iph, void *data,
int datalen, __sum16 *check, int oldlen)
{
struct rtable *rt = skb_rtable(skb);
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
new file mode 100644
index 00000000000..1f3bb11490c
--- /dev/null
+++ b/net/ipv4/ping.c
@@ -0,0 +1,935 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * "Ping" sockets
+ *
+ * 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.
+ *
+ * Based on ipv4/udp.c code.
+ *
+ * Authors: Vasiliy Kulikov / Openwall (for Linux 2.6),
+ * Pavel Kankovsky (for Linux 2.4.32)
+ *
+ * Pavel gave all rights to bugs to Vasiliy,
+ * none of the bugs are Pavel's now.
+ *
+ */
+
+#include <asm/system.h>
+#include <linux/uaccess.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/in.h>
+#include <linux/errno.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/inet.h>
+#include <linux/netdevice.h>
+#include <net/snmp.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+#include <net/icmp.h>
+#include <net/protocol.h>
+#include <linux/skbuff.h>
+#include <linux/proc_fs.h>
+#include <net/sock.h>
+#include <net/ping.h>
+#include <net/icmp.h>
+#include <net/udp.h>
+#include <net/route.h>
+#include <net/inet_common.h>
+#include <net/checksum.h>
+
+
+static struct ping_table ping_table;
+
+static u16 ping_port_rover;
+
+static inline int ping_hashfn(struct net *net, unsigned num, unsigned mask)
+{
+ int res = (num + net_hash_mix(net)) & mask;
+ pr_debug("hash(%d) = %d\n", num, res);
+ return res;
+}
+
+static inline struct hlist_nulls_head *ping_hashslot(struct ping_table *table,
+ struct net *net, unsigned num)
+{
+ return &table->hash[ping_hashfn(net, num, PING_HTABLE_MASK)];
+}
+
+static int ping_v4_get_port(struct sock *sk, unsigned short ident)
+{
+ struct hlist_nulls_node *node;
+ struct hlist_nulls_head *hlist;
+ struct inet_sock *isk, *isk2;
+ struct sock *sk2 = NULL;
+
+ isk = inet_sk(sk);
+ write_lock_bh(&ping_table.lock);
+ if (ident == 0) {
+ u32 i;
+ u16 result = ping_port_rover + 1;
+
+ for (i = 0; i < (1L << 16); i++, result++) {
+ if (!result)
+ result++; /* avoid zero */
+ hlist = ping_hashslot(&ping_table, sock_net(sk),
+ result);
+ ping_portaddr_for_each_entry(sk2, node, hlist) {
+ isk2 = inet_sk(sk2);
+
+ if (isk2->inet_num == result)
+ goto next_port;
+ }
+
+ /* found */
+ ping_port_rover = ident = result;
+ break;
+next_port:
+ ;
+ }
+ if (i >= (1L << 16))
+ goto fail;
+ } else {
+ hlist = ping_hashslot(&ping_table, sock_net(sk), ident);
+ ping_portaddr_for_each_entry(sk2, node, hlist) {
+ isk2 = inet_sk(sk2);
+
+ if ((isk2->inet_num == ident) &&
+ (sk2 != sk) &&
+ (!sk2->sk_reuse || !sk->sk_reuse))
+ goto fail;
+ }
+ }
+
+ pr_debug("found port/ident = %d\n", ident);
+ isk->inet_num = ident;
+ if (sk_unhashed(sk)) {
+ pr_debug("was not hashed\n");
+ sock_hold(sk);
+ hlist_nulls_add_head(&sk->sk_nulls_node, hlist);
+ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
+ }
+ write_unlock_bh(&ping_table.lock);
+ return 0;
+
+fail:
+ write_unlock_bh(&ping_table.lock);
+ return 1;
+}
+
+static void ping_v4_hash(struct sock *sk)
+{
+ pr_debug("ping_v4_hash(sk->port=%u)\n", inet_sk(sk)->inet_num);
+ BUG(); /* "Please do not press this button again." */
+}
+
+static void ping_v4_unhash(struct sock *sk)
+{
+ struct inet_sock *isk = inet_sk(sk);
+ pr_debug("ping_v4_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
+ if (sk_hashed(sk)) {
+ struct hlist_nulls_head *hslot;
+
+ hslot = ping_hashslot(&ping_table, sock_net(sk), isk->inet_num);
+ write_lock_bh(&ping_table.lock);
+ hlist_nulls_del(&sk->sk_nulls_node);
+ sock_put(sk);
+ isk->inet_num = isk->inet_sport = 0;
+ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
+ write_unlock_bh(&ping_table.lock);
+ }
+}
+
+static struct sock *ping_v4_lookup(struct net *net, u32 saddr, u32 daddr,
+ u16 ident, int dif)
+{
+ struct hlist_nulls_head *hslot = ping_hashslot(&ping_table, net, ident);
+ struct sock *sk = NULL;
+ struct inet_sock *isk;
+ struct hlist_nulls_node *hnode;
+
+ pr_debug("try to find: num = %d, daddr = %ld, dif = %d\n",
+ (int)ident, (unsigned long)daddr, dif);
+ read_lock_bh(&ping_table.lock);
+
+ ping_portaddr_for_each_entry(sk, hnode, hslot) {
+ isk = inet_sk(sk);
+
+ pr_debug("found: %p: num = %d, daddr = %ld, dif = %d\n", sk,
+ (int)isk->inet_num, (unsigned long)isk->inet_rcv_saddr,
+ sk->sk_bound_dev_if);
+
+ pr_debug("iterate\n");
+ if (isk->inet_num != ident)
+ continue;
+ if (isk->inet_rcv_saddr && isk->inet_rcv_saddr != daddr)
+ continue;
+ if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)
+ continue;
+
+ sock_hold(sk);
+ goto exit;
+ }
+
+ sk = NULL;
+exit:
+ read_unlock_bh(&ping_table.lock);
+
+ return sk;
+}
+
+static void inet_get_ping_group_range_net(struct net *net, gid_t *low,
+ gid_t *high)
+{
+ gid_t *data = net->ipv4.sysctl_ping_group_range;
+ unsigned seq;
+ do {
+ seq = read_seqbegin(&sysctl_local_ports.lock);
+
+ *low = data[0];
+ *high = data[1];
+ } while (read_seqretry(&sysctl_local_ports.lock, seq));
+}
+
+
+static int ping_init_sock(struct sock *sk)
+{
+ struct net *net = sock_net(sk);
+ gid_t group = current_egid();
+ gid_t range[2];
+ struct group_info *group_info = get_current_groups();
+ int i, j, count = group_info->ngroups;
+
+ inet_get_ping_group_range_net(net, range, range+1);
+ if (range[0] <= group && group <= range[1])
+ return 0;
+
+ for (i = 0; i < group_info->nblocks; i++) {
+ int cp_count = min_t(int, NGROUPS_PER_BLOCK, count);
+
+ for (j = 0; j < cp_count; j++) {
+ group = group_info->blocks[i][j];
+ if (range[0] <= group && group <= range[1])
+ return 0;
+ }
+
+ count -= cp_count;
+ }
+
+ return -EACCES;
+}
+
+static void ping_close(struct sock *sk, long timeout)
+{
+ pr_debug("ping_close(sk=%p,sk->num=%u)\n",
+ inet_sk(sk), inet_sk(sk)->inet_num);
+ pr_debug("isk->refcnt = %d\n", sk->sk_refcnt.counter);
+
+ sk_common_release(sk);
+}
+
+/*
+ * We need our own bind because there are no privileged id's == local ports.
+ * Moreover, we don't allow binding to multi- and broadcast addresses.
+ */
+
+static int ping_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+{
+ struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
+ struct inet_sock *isk = inet_sk(sk);
+ unsigned short snum;
+ int chk_addr_ret;
+ int err;
+
+ if (addr_len < sizeof(struct sockaddr_in))
+ return -EINVAL;
+
+ pr_debug("ping_v4_bind(sk=%p,sa_addr=%08x,sa_port=%d)\n",
+ sk, addr->sin_addr.s_addr, ntohs(addr->sin_port));
+
+ chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
+ if (addr->sin_addr.s_addr == INADDR_ANY)
+ chk_addr_ret = RTN_LOCAL;
+
+ if ((sysctl_ip_nonlocal_bind == 0 &&
+ isk->freebind == 0 && isk->transparent == 0 &&
+ chk_addr_ret != RTN_LOCAL) ||
+ chk_addr_ret == RTN_MULTICAST ||
+ chk_addr_ret == RTN_BROADCAST)
+ return -EADDRNOTAVAIL;
+
+ lock_sock(sk);
+
+ err = -EINVAL;
+ if (isk->inet_num != 0)
+ goto out;
+
+ err = -EADDRINUSE;
+ isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr;
+ snum = ntohs(addr->sin_port);
+ if (ping_v4_get_port(sk, snum) != 0) {
+ isk->inet_saddr = isk->inet_rcv_saddr = 0;
+ goto out;
+ }
+
+ pr_debug("after bind(): num = %d, daddr = %ld, dif = %d\n",
+ (int)isk->inet_num,
+ (unsigned long) isk->inet_rcv_saddr,
+ (int)sk->sk_bound_dev_if);
+
+ err = 0;
+ if (isk->inet_rcv_saddr)
+ sk->sk_userlocks |= SOCK_BINDADDR_LOCK;
+ if (snum)
+ sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
+ isk->inet_sport = htons(isk->inet_num);
+ isk->inet_daddr = 0;
+ isk->inet_dport = 0;
+ sk_dst_reset(sk);
+out:
+ release_sock(sk);
+ pr_debug("ping_v4_bind -> %d\n", err);
+ return err;
+}
+
+/*
+ * Is this a supported type of ICMP message?
+ */
+
+static inline int ping_supported(int type, int code)
+{
+ if (type == ICMP_ECHO && code == 0)
+ return 1;
+ return 0;
+}
+
+/*
+ * This routine is called by the ICMP module when it gets some
+ * sort of error condition.
+ */
+
+static int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
+
+void ping_err(struct sk_buff *skb, u32 info)
+{
+ struct iphdr *iph = (struct iphdr *)skb->data;
+ struct icmphdr *icmph = (struct icmphdr *)(skb->data+(iph->ihl<<2));
+ struct inet_sock *inet_sock;
+ int type = icmph->type;
+ int code = icmph->code;
+ struct net *net = dev_net(skb->dev);
+ struct sock *sk;
+ int harderr;
+ int err;
+
+ /* We assume the packet has already been checked by icmp_unreach */
+
+ if (!ping_supported(icmph->type, icmph->code))
+ return;
+
+ pr_debug("ping_err(type=%04x,code=%04x,id=%04x,seq=%04x)\n", type,
+ code, ntohs(icmph->un.echo.id), ntohs(icmph->un.echo.sequence));
+
+ sk = ping_v4_lookup(net, iph->daddr, iph->saddr,
+ ntohs(icmph->un.echo.id), skb->dev->ifindex);
+ if (sk == NULL) {
+ ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
+ pr_debug("no socket, dropping\n");
+ return; /* No socket for error */
+ }
+ pr_debug("err on socket %p\n", sk);
+
+ err = 0;
+ harderr = 0;
+ inet_sock = inet_sk(sk);
+
+ switch (type) {
+ default:
+ case ICMP_TIME_EXCEEDED:
+ err = EHOSTUNREACH;
+ break;
+ case ICMP_SOURCE_QUENCH:
+ /* This is not a real error but ping wants to see it.
+ * Report it with some fake errno. */
+ err = EREMOTEIO;
+ break;
+ case ICMP_PARAMETERPROB:
+ err = EPROTO;
+ harderr = 1;
+ break;
+ case ICMP_DEST_UNREACH:
+ if (code == ICMP_FRAG_NEEDED) { /* Path MTU discovery */
+ if (inet_sock->pmtudisc != IP_PMTUDISC_DONT) {
+ err = EMSGSIZE;
+ harderr = 1;
+ break;
+ }
+ goto out;
+ }
+ err = EHOSTUNREACH;
+ if (code <= NR_ICMP_UNREACH) {
+ harderr = icmp_err_convert[code].fatal;
+ err = icmp_err_convert[code].errno;
+ }
+ break;
+ case ICMP_REDIRECT:
+ /* See ICMP_SOURCE_QUENCH */
+ err = EREMOTEIO;
+ break;
+ }
+
+ /*
+ * RFC1122: OK. Passes ICMP errors back to application, as per
+ * 4.1.3.3.
+ */
+ if (!inet_sock->recverr) {
+ if (!harderr || sk->sk_state != TCP_ESTABLISHED)
+ goto out;
+ } else {
+ ip_icmp_error(sk, skb, err, 0 /* no remote port */,
+ info, (u8 *)icmph);
+ }
+ sk->sk_err = err;
+ sk->sk_error_report(sk);
+out:
+ sock_put(sk);
+}
+
+/*
+ * Copy and checksum an ICMP Echo packet from user space into a buffer.
+ */
+
+struct pingfakehdr {
+ struct icmphdr icmph;
+ struct iovec *iov;
+ u32 wcheck;
+};
+
+static int ping_getfrag(void *from, char * to,
+ int offset, int fraglen, int odd, struct sk_buff *skb)
+{
+ struct pingfakehdr *pfh = (struct pingfakehdr *)from;
+
+ if (offset == 0) {
+ if (fraglen < sizeof(struct icmphdr))
+ BUG();
+ if (csum_partial_copy_fromiovecend(to + sizeof(struct icmphdr),
+ pfh->iov, 0, fraglen - sizeof(struct icmphdr),
+ &pfh->wcheck))
+ return -EFAULT;
+
+ return 0;
+ }
+ if (offset < sizeof(struct icmphdr))
+ BUG();
+ if (csum_partial_copy_fromiovecend
+ (to, pfh->iov, offset - sizeof(struct icmphdr),
+ fraglen, &pfh->wcheck))
+ return -EFAULT;
+ return 0;
+}
+
+static int ping_push_pending_frames(struct sock *sk, struct pingfakehdr *pfh,
+ struct flowi4 *fl4)
+{
+ struct sk_buff *skb = skb_peek(&sk->sk_write_queue);
+
+ pfh->wcheck = csum_partial((char *)&pfh->icmph,
+ sizeof(struct icmphdr), pfh->wcheck);
+ pfh->icmph.checksum = csum_fold(pfh->wcheck);
+ memcpy(icmp_hdr(skb), &pfh->icmph, sizeof(struct icmphdr));
+ skb->ip_summed = CHECKSUM_NONE;
+ return ip_push_pending_frames(sk, fl4);
+}
+
+static int ping_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ size_t len)
+{
+ struct net *net = sock_net(sk);
+ struct flowi4 fl4;
+ struct inet_sock *inet = inet_sk(sk);
+ struct ipcm_cookie ipc;
+ struct icmphdr user_icmph;
+ struct pingfakehdr pfh;
+ struct rtable *rt = NULL;
+ struct ip_options_data opt_copy;
+ int free = 0;
+ u32 saddr, daddr, faddr;
+ u8 tos;
+ int err;
+
+ pr_debug("ping_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num);
+
+
+ if (len > 0xFFFF)
+ return -EMSGSIZE;
+
+ /*
+ * Check the flags.
+ */
+
+ /* Mirror BSD error message compatibility */
+ if (msg->msg_flags & MSG_OOB)
+ return -EOPNOTSUPP;
+
+ /*
+ * Fetch the ICMP header provided by the userland.
+ * iovec is modified!
+ */
+
+ if (memcpy_fromiovec((u8 *)&user_icmph, msg->msg_iov,
+ sizeof(struct icmphdr)))
+ return -EFAULT;
+ if (!ping_supported(user_icmph.type, user_icmph.code))
+ return -EINVAL;
+
+ /*
+ * Get and verify the address.
+ */
+
+ if (msg->msg_name) {
+ struct sockaddr_in *usin = (struct sockaddr_in *)msg->msg_name;
+ if (msg->msg_namelen < sizeof(*usin))
+ return -EINVAL;
+ if (usin->sin_family != AF_INET)
+ return -EINVAL;
+ daddr = usin->sin_addr.s_addr;
+ /* no remote port */
+ } else {
+ if (sk->sk_state != TCP_ESTABLISHED)
+ return -EDESTADDRREQ;
+ daddr = inet->inet_daddr;
+ /* no remote port */
+ }
+
+ ipc.addr = inet->inet_saddr;
+ ipc.opt = NULL;
+ ipc.oif = sk->sk_bound_dev_if;
+ ipc.tx_flags = 0;
+ err = sock_tx_timestamp(sk, &ipc.tx_flags);
+ if (err)
+ return err;
+
+ if (msg->msg_controllen) {
+ err = ip_cmsg_send(sock_net(sk), msg, &ipc);
+ if (err)
+ return err;
+ if (ipc.opt)
+ free = 1;
+ }
+ if (!ipc.opt) {
+ struct ip_options_rcu *inet_opt;
+
+ rcu_read_lock();
+ inet_opt = rcu_dereference(inet->inet_opt);
+ if (inet_opt) {
+ memcpy(&opt_copy, inet_opt,
+ sizeof(*inet_opt) + inet_opt->opt.optlen);
+ ipc.opt = &opt_copy.opt;
+ }
+ rcu_read_unlock();
+ }
+
+ saddr = ipc.addr;
+ ipc.addr = faddr = daddr;
+
+ if (ipc.opt && ipc.opt->opt.srr) {
+ if (!daddr)
+ return -EINVAL;
+ faddr = ipc.opt->opt.faddr;
+ }
+ tos = RT_TOS(inet->tos);
+ if (sock_flag(sk, SOCK_LOCALROUTE) ||
+ (msg->msg_flags & MSG_DONTROUTE) ||
+ (ipc.opt && ipc.opt->opt.is_strictroute)) {
+ tos |= RTO_ONLINK;
+ }
+
+ if (ipv4_is_multicast(daddr)) {
+ if (!ipc.oif)
+ ipc.oif = inet->mc_index;
+ if (!saddr)
+ saddr = inet->mc_addr;
+ }
+
+ flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
+ RT_SCOPE_UNIVERSE, sk->sk_protocol,
+ inet_sk_flowi_flags(sk), faddr, saddr, 0, 0);
+
+ security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
+ rt = ip_route_output_flow(net, &fl4, sk);
+ if (IS_ERR(rt)) {
+ err = PTR_ERR(rt);
+ rt = NULL;
+ if (err == -ENETUNREACH)
+ IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
+ goto out;
+ }
+
+ err = -EACCES;
+ if ((rt->rt_flags & RTCF_BROADCAST) &&
+ !sock_flag(sk, SOCK_BROADCAST))
+ goto out;
+
+ if (msg->msg_flags & MSG_CONFIRM)
+ goto do_confirm;
+back_from_confirm:
+
+ if (!ipc.addr)
+ ipc.addr = fl4.daddr;
+
+ lock_sock(sk);
+
+ pfh.icmph.type = user_icmph.type; /* already checked */
+ pfh.icmph.code = user_icmph.code; /* ditto */
+ pfh.icmph.checksum = 0;
+ pfh.icmph.un.echo.id = inet->inet_sport;
+ pfh.icmph.un.echo.sequence = user_icmph.un.echo.sequence;
+ pfh.iov = msg->msg_iov;
+ pfh.wcheck = 0;
+
+ err = ip_append_data(sk, &fl4, ping_getfrag, &pfh, len,
+ 0, &ipc, &rt, msg->msg_flags);
+ if (err)
+ ip_flush_pending_frames(sk);
+ else
+ err = ping_push_pending_frames(sk, &pfh, &fl4);
+ release_sock(sk);
+
+out:
+ ip_rt_put(rt);
+ if (free)
+ kfree(ipc.opt);
+ if (!err) {
+ icmp_out_count(sock_net(sk), user_icmph.type);
+ return len;
+ }
+ return err;
+
+do_confirm:
+ dst_confirm(&rt->dst);
+ if (!(msg->msg_flags & MSG_PROBE) || len)
+ goto back_from_confirm;
+ err = 0;
+ goto out;
+}
+
+static int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ size_t len, int noblock, int flags, int *addr_len)
+{
+ struct inet_sock *isk = inet_sk(sk);
+ struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
+ struct sk_buff *skb;
+ int copied, err;
+
+ pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num);
+
+ if (flags & MSG_OOB)
+ goto out;
+
+ if (addr_len)
+ *addr_len = sizeof(*sin);
+
+ if (flags & MSG_ERRQUEUE)
+ return ip_recv_error(sk, msg, len);
+
+ skb = skb_recv_datagram(sk, flags, noblock, &err);
+ if (!skb)
+ goto out;
+
+ copied = skb->len;
+ if (copied > len) {
+ msg->msg_flags |= MSG_TRUNC;
+ copied = len;
+ }
+
+ /* Don't bother checking the checksum */
+ err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+ if (err)
+ goto done;
+
+ sock_recv_timestamp(msg, sk, skb);
+
+ /* Copy the address. */
+ if (sin) {
+ sin->sin_family = AF_INET;
+ sin->sin_port = 0 /* skb->h.uh->source */;
+ sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
+ memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+ }
+ if (isk->cmsg_flags)
+ ip_cmsg_recv(msg, skb);
+ err = copied;
+
+done:
+ skb_free_datagram(sk, skb);
+out:
+ pr_debug("ping_recvmsg -> %d\n", err);
+ return err;
+}
+
+static int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+{
+ pr_debug("ping_queue_rcv_skb(sk=%p,sk->num=%d,skb=%p)\n",
+ inet_sk(sk), inet_sk(sk)->inet_num, skb);
+ if (sock_queue_rcv_skb(sk, skb) < 0) {
+ ICMP_INC_STATS_BH(sock_net(sk), ICMP_MIB_INERRORS);
+ kfree_skb(skb);
+ pr_debug("ping_queue_rcv_skb -> failed\n");
+ return -1;
+ }
+ return 0;
+}
+
+
+/*
+ * All we need to do is get the socket.
+ */
+
+void ping_rcv(struct sk_buff *skb)
+{
+ struct sock *sk;
+ struct net *net = dev_net(skb->dev);
+ struct iphdr *iph = ip_hdr(skb);
+ struct icmphdr *icmph = icmp_hdr(skb);
+ u32 saddr = iph->saddr;
+ u32 daddr = iph->daddr;
+
+ /* We assume the packet has already been checked by icmp_rcv */
+
+ pr_debug("ping_rcv(skb=%p,id=%04x,seq=%04x)\n",
+ skb, ntohs(icmph->un.echo.id), ntohs(icmph->un.echo.sequence));
+
+ /* Push ICMP header back */
+ skb_push(skb, skb->data - (u8 *)icmph);
+
+ sk = ping_v4_lookup(net, saddr, daddr, ntohs(icmph->un.echo.id),
+ skb->dev->ifindex);
+ if (sk != NULL) {
+ pr_debug("rcv on socket %p\n", sk);
+ ping_queue_rcv_skb(sk, skb_get(skb));
+ sock_put(sk);
+ return;
+ }
+ pr_debug("no socket, dropping\n");
+
+ /* We're called from icmp_rcv(). kfree_skb() is done there. */
+}
+
+struct proto ping_prot = {
+ .name = "PING",
+ .owner = THIS_MODULE,
+ .init = ping_init_sock,
+ .close = ping_close,
+ .connect = ip4_datagram_connect,
+ .disconnect = udp_disconnect,
+ .setsockopt = ip_setsockopt,
+ .getsockopt = ip_getsockopt,
+ .sendmsg = ping_sendmsg,
+ .recvmsg = ping_recvmsg,
+ .bind = ping_bind,
+ .backlog_rcv = ping_queue_rcv_skb,
+ .hash = ping_v4_hash,
+ .unhash = ping_v4_unhash,
+ .get_port = ping_v4_get_port,
+ .obj_size = sizeof(struct inet_sock),
+};
+EXPORT_SYMBOL(ping_prot);
+
+#ifdef CONFIG_PROC_FS
+
+static struct sock *ping_get_first(struct seq_file *seq, int start)
+{
+ struct sock *sk;
+ struct ping_iter_state *state = seq->private;
+ struct net *net = seq_file_net(seq);
+
+ for (state->bucket = start; state->bucket < PING_HTABLE_SIZE;
+ ++state->bucket) {
+ struct hlist_nulls_node *node;
+ struct hlist_nulls_head *hslot;
+
+ hslot = &ping_table.hash[state->bucket];
+
+ if (hlist_nulls_empty(hslot))
+ continue;
+
+ sk_nulls_for_each(sk, node, hslot) {
+ if (net_eq(sock_net(sk), net))
+ goto found;
+ }
+ }
+ sk = NULL;
+found:
+ return sk;
+}
+
+static struct sock *ping_get_next(struct seq_file *seq, struct sock *sk)
+{
+ struct ping_iter_state *state = seq->private;
+ struct net *net = seq_file_net(seq);
+
+ do {
+ sk = sk_nulls_next(sk);
+ } while (sk && (!net_eq(sock_net(sk), net)));
+
+ if (!sk)
+ return ping_get_first(seq, state->bucket + 1);
+ return sk;
+}
+
+static struct sock *ping_get_idx(struct seq_file *seq, loff_t pos)
+{
+ struct sock *sk = ping_get_first(seq, 0);
+
+ if (sk)
+ while (pos && (sk = ping_get_next(seq, sk)) != NULL)
+ --pos;
+ return pos ? NULL : sk;
+}
+
+static void *ping_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ struct ping_iter_state *state = seq->private;
+ state->bucket = 0;
+
+ read_lock_bh(&ping_table.lock);
+
+ return *pos ? ping_get_idx(seq, *pos-1) : SEQ_START_TOKEN;
+}
+
+static void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct sock *sk;
+
+ if (v == SEQ_START_TOKEN)
+ sk = ping_get_idx(seq, 0);
+ else
+ sk = ping_get_next(seq, v);
+
+ ++*pos;
+ return sk;
+}
+
+static void ping_seq_stop(struct seq_file *seq, void *v)
+{
+ read_unlock_bh(&ping_table.lock);
+}
+
+static void ping_format_sock(struct sock *sp, struct seq_file *f,
+ int bucket, int *len)
+{
+ struct inet_sock *inet = inet_sk(sp);
+ __be32 dest = inet->inet_daddr;
+ __be32 src = inet->inet_rcv_saddr;
+ __u16 destp = ntohs(inet->inet_dport);
+ __u16 srcp = ntohs(inet->inet_sport);
+
+ seq_printf(f, "%5d: %08X:%04X %08X:%04X"
+ " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %pK %d%n",
+ bucket, src, srcp, dest, destp, sp->sk_state,
+ sk_wmem_alloc_get(sp),
+ sk_rmem_alloc_get(sp),
+ 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
+ atomic_read(&sp->sk_refcnt), sp,
+ atomic_read(&sp->sk_drops), len);
+}
+
+static int ping_seq_show(struct seq_file *seq, void *v)
+{
+ if (v == SEQ_START_TOKEN)
+ seq_printf(seq, "%-127s\n",
+ " sl local_address rem_address st tx_queue "
+ "rx_queue tr tm->when retrnsmt uid timeout "
+ "inode ref pointer drops");
+ else {
+ struct ping_iter_state *state = seq->private;
+ int len;
+
+ ping_format_sock(v, seq, state->bucket, &len);
+ seq_printf(seq, "%*s\n", 127 - len, "");
+ }
+ return 0;
+}
+
+static const struct seq_operations ping_seq_ops = {
+ .show = ping_seq_show,
+ .start = ping_seq_start,
+ .next = ping_seq_next,
+ .stop = ping_seq_stop,
+};
+
+static int ping_seq_open(struct inode *inode, struct file *file)
+{
+ return seq_open_net(inode, file, &ping_seq_ops,
+ sizeof(struct ping_iter_state));
+}
+
+static const struct file_operations ping_seq_fops = {
+ .open = ping_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_net,
+};
+
+static int ping_proc_register(struct net *net)
+{
+ struct proc_dir_entry *p;
+ int rc = 0;
+
+ p = proc_net_fops_create(net, "icmp", S_IRUGO, &ping_seq_fops);
+ if (!p)
+ rc = -ENOMEM;
+ return rc;
+}
+
+static void ping_proc_unregister(struct net *net)
+{
+ proc_net_remove(net, "icmp");
+}
+
+
+static int __net_init ping_proc_init_net(struct net *net)
+{
+ return ping_proc_register(net);
+}
+
+static void __net_exit ping_proc_exit_net(struct net *net)
+{
+ ping_proc_unregister(net);
+}
+
+static struct pernet_operations ping_net_ops = {
+ .init = ping_proc_init_net,
+ .exit = ping_proc_exit_net,
+};
+
+int __init ping_proc_init(void)
+{
+ return register_pernet_subsys(&ping_net_ops);
+}
+
+void ping_proc_exit(void)
+{
+ unregister_pernet_subsys(&ping_net_ops);
+}
+
+#endif
+
+void __init ping_init(void)
+{
+ int i;
+
+ for (i = 0; i < PING_HTABLE_SIZE; i++)
+ INIT_HLIST_NULLS_HEAD(&ping_table.hash[i], i);
+ rwlock_init(&ping_table.lock);
+}
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index bceaec42c37..11e1780455f 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -154,7 +154,7 @@ 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.
*/
-static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
+static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
{
struct sock *sk;
struct hlist_head *head;
@@ -247,7 +247,7 @@ static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info)
}
if (inet->recverr) {
- struct iphdr *iph = (struct iphdr *)skb->data;
+ const struct iphdr *iph = (const struct iphdr *)skb->data;
u8 *payload = skb->data + (iph->ihl << 2);
if (inet->hdrincl)
@@ -265,7 +265,7 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
{
int hash;
struct sock *raw_sk;
- struct iphdr *iph;
+ const struct iphdr *iph;
struct net *net;
hash = protocol & (RAW_HTABLE_SIZE - 1);
@@ -273,7 +273,7 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
read_lock(&raw_v4_hashinfo.lock);
raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);
if (raw_sk != NULL) {
- iph = (struct iphdr *)skb->data;
+ iph = (const struct iphdr *)skb->data;
net = dev_net(skb->dev);
while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol,
@@ -281,7 +281,7 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
skb->dev->ifindex)) != NULL) {
raw_err(raw_sk, skb, info);
raw_sk = sk_next(raw_sk);
- iph = (struct iphdr *)skb->data;
+ iph = (const struct iphdr *)skb->data;
}
}
read_unlock(&raw_v4_hashinfo.lock);
@@ -314,9 +314,10 @@ int raw_rcv(struct sock *sk, struct sk_buff *skb)
return 0;
}
-static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
- struct rtable **rtp,
- unsigned int flags)
+static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
+ void *from, size_t length,
+ struct rtable **rtp,
+ unsigned int flags)
{
struct inet_sock *inet = inet_sk(sk);
struct net *net = sock_net(sk);
@@ -327,7 +328,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
struct rtable *rt = *rtp;
if (length > rt->dst.dev->mtu) {
- ip_local_error(sk, EMSGSIZE, rt->rt_dst, inet->inet_dport,
+ ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport,
rt->dst.dev->mtu);
return -EMSGSIZE;
}
@@ -372,7 +373,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
if (iphlen >= sizeof(*iph)) {
if (!iph->saddr)
- iph->saddr = rt->rt_src;
+ iph->saddr = fl4->saddr;
iph->check = 0;
iph->tot_len = htons(length);
if (!iph->id)
@@ -455,11 +456,13 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
struct inet_sock *inet = inet_sk(sk);
struct ipcm_cookie ipc;
struct rtable *rt = NULL;
+ struct flowi4 fl4;
int free = 0;
__be32 daddr;
__be32 saddr;
u8 tos;
int err;
+ struct ip_options_data opt_copy;
err = -EMSGSIZE;
if (len > 0xFFFF)
@@ -520,8 +523,18 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
saddr = ipc.addr;
ipc.addr = daddr;
- if (!ipc.opt)
- ipc.opt = inet->opt;
+ if (!ipc.opt) {
+ struct ip_options_rcu *inet_opt;
+
+ rcu_read_lock();
+ inet_opt = rcu_dereference(inet->inet_opt);
+ if (inet_opt) {
+ memcpy(&opt_copy, inet_opt,
+ sizeof(*inet_opt) + inet_opt->opt.optlen);
+ ipc.opt = &opt_copy.opt;
+ }
+ rcu_read_unlock();
+ }
if (ipc.opt) {
err = -EINVAL;
@@ -530,10 +543,10 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
*/
if (inet->hdrincl)
goto done;
- if (ipc.opt->srr) {
+ if (ipc.opt->opt.srr) {
if (!daddr)
goto done;
- daddr = ipc.opt->faddr;
+ daddr = ipc.opt->opt.faddr;
}
}
tos = RT_CONN_FLAGS(sk);
@@ -547,31 +560,23 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
saddr = inet->mc_addr;
}
- {
- struct flowi4 fl4 = {
- .flowi4_oif = ipc.oif,
- .flowi4_mark = sk->sk_mark,
- .daddr = daddr,
- .saddr = saddr,
- .flowi4_tos = tos,
- .flowi4_proto = (inet->hdrincl ?
- IPPROTO_RAW :
- sk->sk_protocol),
- .flowi4_flags = FLOWI_FLAG_CAN_SLEEP,
- };
- if (!inet->hdrincl) {
- err = raw_probe_proto_opt(&fl4, msg);
- if (err)
- goto done;
- }
+ flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
+ RT_SCOPE_UNIVERSE,
+ inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
+ FLOWI_FLAG_CAN_SLEEP, daddr, saddr, 0, 0);
- security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
- rt = ip_route_output_flow(sock_net(sk), &fl4, sk);
- if (IS_ERR(rt)) {
- err = PTR_ERR(rt);
- rt = NULL;
+ if (!inet->hdrincl) {
+ err = raw_probe_proto_opt(&fl4, msg);
+ if (err)
goto done;
- }
+ }
+
+ security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
+ rt = ip_route_output_flow(sock_net(sk), &fl4, sk);
+ if (IS_ERR(rt)) {
+ err = PTR_ERR(rt);
+ rt = NULL;
+ goto done;
}
err = -EACCES;
@@ -583,19 +588,20 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
back_from_confirm:
if (inet->hdrincl)
- err = raw_send_hdrinc(sk, msg->msg_iov, len,
- &rt, msg->msg_flags);
+ err = raw_send_hdrinc(sk, &fl4, msg->msg_iov, len,
+ &rt, msg->msg_flags);
else {
if (!ipc.addr)
- ipc.addr = rt->rt_dst;
+ ipc.addr = fl4.daddr;
lock_sock(sk);
- err = ip_append_data(sk, ip_generic_getfrag, msg->msg_iov, len, 0,
- &ipc, &rt, msg->msg_flags);
+ err = ip_append_data(sk, &fl4, ip_generic_getfrag,
+ msg->msg_iov, len, 0,
+ &ipc, &rt, msg->msg_flags);
if (err)
ip_flush_pending_frames(sk);
else if (!(msg->msg_flags & MSG_MORE)) {
- err = ip_push_pending_frames(sk);
+ err = ip_push_pending_frames(sk, &fl4);
if (err == -ENOBUFS && !inet->recverr)
err = 0;
}
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 99e6e4bb1c7..b24d58e6bbc 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -156,7 +156,7 @@ static u32 *ipv4_cow_metrics(struct dst_entry *dst, unsigned long old)
u32 *p = NULL;
if (!rt->peer)
- rt_bind_peer(rt, 1);
+ rt_bind_peer(rt, rt->rt_dst, 1);
peer = rt->peer;
if (peer) {
@@ -424,7 +424,7 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v)
dst_metric(&r->dst, RTAX_WINDOW),
(int)((dst_metric(&r->dst, RTAX_RTT) >> 3) +
dst_metric(&r->dst, RTAX_RTTVAR)),
- r->rt_tos,
+ r->rt_key_tos,
r->dst.hh ? atomic_read(&r->dst.hh->hh_refcnt) : -1,
r->dst.hh ? (r->dst.hh->hh_output ==
dev_queue_xmit) : 0,
@@ -724,7 +724,7 @@ static inline int compare_keys(struct rtable *rt1, struct rtable *rt2)
return (((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) |
((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) |
(rt1->rt_mark ^ rt2->rt_mark) |
- (rt1->rt_tos ^ rt2->rt_tos) |
+ (rt1->rt_key_tos ^ rt2->rt_key_tos) |
(rt1->rt_oif ^ rt2->rt_oif) |
(rt1->rt_iif ^ rt2->rt_iif)) == 0;
}
@@ -968,10 +968,6 @@ static int rt_garbage_collect(struct dst_ops *ops)
break;
expire >>= 1;
-#if RT_CACHE_DEBUG >= 2
- printk(KERN_DEBUG "expire>> %u %d %d %d\n", expire,
- dst_entries_get_fast(&ipv4_dst_ops), goal, i);
-#endif
if (dst_entries_get_fast(&ipv4_dst_ops) < ip_rt_max_size)
goto out;
@@ -992,10 +988,6 @@ work_done:
dst_entries_get_fast(&ipv4_dst_ops) < ipv4_dst_ops.gc_thresh ||
dst_entries_get_slow(&ipv4_dst_ops) < ipv4_dst_ops.gc_thresh)
expire = ip_rt_gc_timeout;
-#if RT_CACHE_DEBUG >= 2
- printk(KERN_DEBUG "expire++ %u %d %d %d\n", expire,
- dst_entries_get_fast(&ipv4_dst_ops), goal, rover);
-#endif
out: return 0;
}
@@ -1179,16 +1171,6 @@ restart:
rt->dst.rt_next = rt_hash_table[hash].chain;
-#if RT_CACHE_DEBUG >= 2
- if (rt->dst.rt_next) {
- struct rtable *trt;
- printk(KERN_DEBUG "rt_cache @%02x: %pI4",
- hash, &rt->rt_dst);
- for (trt = rt->dst.rt_next; trt; trt = trt->dst.rt_next)
- printk(" . %pI4", &trt->rt_dst);
- printk("\n");
- }
-#endif
/*
* Since lookup is lockfree, we must make sure
* previous writes to rt are committed to memory
@@ -1211,11 +1193,11 @@ static u32 rt_peer_genid(void)
return atomic_read(&__rt_peer_genid);
}
-void rt_bind_peer(struct rtable *rt, int create)
+void rt_bind_peer(struct rtable *rt, __be32 daddr, int create)
{
struct inet_peer *peer;
- peer = inet_getpeer_v4(rt->rt_dst, create);
+ peer = inet_getpeer_v4(daddr, create);
if (peer && cmpxchg(&rt->peer, NULL, peer) != NULL)
inet_putpeer(peer);
@@ -1249,7 +1231,7 @@ void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more)
if (rt) {
if (rt->peer == NULL)
- rt_bind_peer(rt, 1);
+ rt_bind_peer(rt, rt->rt_dst, 1);
/* If peer is attached to destination, it is never detached,
so that we need not to grab a lock to dereference it.
@@ -1347,10 +1329,6 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
unsigned hash = rt_hash(rt->rt_key_dst, rt->rt_key_src,
rt->rt_oif,
rt_genid(dev_net(dst->dev)));
-#if RT_CACHE_DEBUG >= 1
- printk(KERN_DEBUG "ipv4_negative_advice: redirect to %pI4/%02x dropped\n",
- &rt->rt_dst, rt->rt_tos);
-#endif
rt_del(hash, rt);
ret = NULL;
} else if (rt->peer &&
@@ -1399,7 +1377,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
rcu_read_unlock();
if (!rt->peer)
- rt_bind_peer(rt, 1);
+ rt_bind_peer(rt, rt->rt_dst, 1);
peer = rt->peer;
if (!peer) {
icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway);
@@ -1435,7 +1413,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
peer->rate_tokens == ip_rt_redirect_number &&
net_ratelimit())
printk(KERN_WARNING "host %pI4/if%d ignores redirects for %pI4 to %pI4.\n",
- &rt->rt_src, rt->rt_iif,
+ &ip_hdr(skb)->saddr, rt->rt_iif,
&rt->rt_dst, &rt->rt_gateway);
#endif
}
@@ -1467,7 +1445,7 @@ static int ip_error(struct sk_buff *skb)
}
if (!rt->peer)
- rt_bind_peer(rt, 1);
+ rt_bind_peer(rt, rt->rt_dst, 1);
peer = rt->peer;
send = true;
@@ -1507,7 +1485,7 @@ static inline unsigned short guess_mtu(unsigned short old_mtu)
return 68;
}
-unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
+unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph,
unsigned short new_mtu,
struct net_device *dev)
{
@@ -1574,7 +1552,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
dst_confirm(dst);
if (!rt->peer)
- rt_bind_peer(rt, 1);
+ rt_bind_peer(rt, rt->rt_dst, 1);
peer = rt->peer;
if (peer) {
if (mtu < ip_rt_min_pmtu)
@@ -1631,7 +1609,7 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
struct inet_peer *peer;
if (!rt->peer)
- rt_bind_peer(rt, 0);
+ rt_bind_peer(rt, rt->rt_dst, 0);
peer = rt->peer;
if (peer && peer->pmtu_expires)
@@ -1699,22 +1677,26 @@ static int ip_rt_bug(struct sk_buff *skb)
in IP options!
*/
-void ip_rt_get_source(u8 *addr, struct rtable *rt)
+void ip_rt_get_source(u8 *addr, struct sk_buff *skb, struct rtable *rt)
{
__be32 src;
- struct fib_result res;
if (rt_is_output_route(rt))
- src = rt->rt_src;
+ src = ip_hdr(skb)->saddr;
else {
- struct flowi4 fl4 = {
- .daddr = rt->rt_key_dst,
- .saddr = rt->rt_key_src,
- .flowi4_tos = rt->rt_tos,
- .flowi4_oif = rt->rt_oif,
- .flowi4_iif = rt->rt_iif,
- .flowi4_mark = rt->rt_mark,
- };
+ struct fib_result res;
+ struct flowi4 fl4;
+ struct iphdr *iph;
+
+ iph = ip_hdr(skb);
+
+ memset(&fl4, 0, sizeof(fl4));
+ fl4.daddr = iph->daddr;
+ fl4.saddr = iph->saddr;
+ fl4.flowi4_tos = iph->tos;
+ fl4.flowi4_oif = rt->dst.dev->ifindex;
+ fl4.flowi4_iif = skb->dev->ifindex;
+ fl4.flowi4_mark = skb->mark;
rcu_read_lock();
if (fib_lookup(dev_net(rt->dst.dev), &fl4, &res) == 0)
@@ -1767,7 +1749,7 @@ static unsigned int ipv4_default_mtu(const struct dst_entry *dst)
return mtu;
}
-static void rt_init_metrics(struct rtable *rt, const struct flowi4 *oldflp4,
+static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4,
struct fib_info *fi)
{
struct inet_peer *peer;
@@ -1776,7 +1758,7 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *oldflp4,
/* If a peer entry exists for this destination, we must hook
* it up in order to get at cached metrics.
*/
- if (oldflp4 && (oldflp4->flowi4_flags & FLOWI_FLAG_PRECOW_METRICS))
+ if (fl4 && (fl4->flowi4_flags & FLOWI_FLAG_PRECOW_METRICS))
create = 1;
rt->peer = peer = inet_getpeer_v4(rt->rt_dst, create);
@@ -1803,7 +1785,7 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *oldflp4,
}
}
-static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *oldflp4,
+static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *fl4,
const struct fib_result *res,
struct fib_info *fi, u16 type, u32 itag)
{
@@ -1813,7 +1795,7 @@ static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *oldflp4,
if (FIB_RES_GW(*res) &&
FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
rt->rt_gateway = FIB_RES_GW(*res);
- rt_init_metrics(rt, oldflp4, fi);
+ rt_init_metrics(rt, fl4, fi);
#ifdef CONFIG_IP_ROUTE_CLASSID
dst->tclassid = FIB_RES_NH(*res).nh_tclassid;
#endif
@@ -1830,20 +1812,15 @@ static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *oldflp4,
#endif
set_class_tag(rt, itag);
#endif
- rt->rt_type = type;
}
-static struct rtable *rt_dst_alloc(bool nopolicy, bool noxfrm)
+static struct rtable *rt_dst_alloc(struct net_device *dev,
+ bool nopolicy, bool noxfrm)
{
- struct rtable *rt = dst_alloc(&ipv4_dst_ops, 1);
- if (rt) {
- rt->dst.obsolete = -1;
-
- rt->dst.flags = DST_HOST |
- (nopolicy ? DST_NOPOLICY : 0) |
- (noxfrm ? DST_NOXFRM : 0);
- }
- return rt;
+ return dst_alloc(&ipv4_dst_ops, dev, 1, -1,
+ DST_HOST |
+ (nopolicy ? DST_NOPOLICY : 0) |
+ (noxfrm ? DST_NOXFRM : 0));
}
/* called in rcu_read_lock() section */
@@ -1871,36 +1848,38 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
goto e_inval;
spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
} else {
- err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst,
- &itag, 0);
+ err = fib_validate_source(skb, saddr, 0, tos, 0, dev, &spec_dst,
+ &itag);
if (err < 0)
goto e_err;
}
- rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
+ rth = rt_dst_alloc(init_net.loopback_dev,
+ IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
if (!rth)
goto e_nobufs;
+#ifdef CONFIG_IP_ROUTE_CLASSID
+ rth->dst.tclassid = itag;
+#endif
rth->dst.output = ip_rt_bug;
rth->rt_key_dst = daddr;
- rth->rt_dst = daddr;
- rth->rt_tos = tos;
- rth->rt_mark = skb->mark;
rth->rt_key_src = saddr;
+ rth->rt_genid = rt_genid(dev_net(dev));
+ rth->rt_flags = RTCF_MULTICAST;
+ rth->rt_type = RTN_MULTICAST;
+ rth->rt_key_tos = tos;
+ rth->rt_dst = daddr;
rth->rt_src = saddr;
-#ifdef CONFIG_IP_ROUTE_CLASSID
- rth->dst.tclassid = itag;
-#endif
rth->rt_route_iif = dev->ifindex;
rth->rt_iif = dev->ifindex;
- rth->dst.dev = init_net.loopback_dev;
- dev_hold(rth->dst.dev);
rth->rt_oif = 0;
+ rth->rt_mark = skb->mark;
rth->rt_gateway = daddr;
rth->rt_spec_dst= spec_dst;
- rth->rt_genid = rt_genid(dev_net(dev));
- rth->rt_flags = RTCF_MULTICAST;
- rth->rt_type = RTN_MULTICAST;
+ rth->rt_peer_genid = 0;
+ rth->peer = NULL;
+ rth->fi = NULL;
if (our) {
rth->dst.input= ip_local_deliver;
rth->rt_flags |= RTCF_LOCAL;
@@ -1981,8 +1960,8 @@ static int __mkroute_input(struct sk_buff *skb,
}
- err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(*res),
- in_dev->dev, &spec_dst, &itag, skb->mark);
+ err = fib_validate_source(skb, saddr, daddr, tos, FIB_RES_OIF(*res),
+ in_dev->dev, &spec_dst, &itag);
if (err < 0) {
ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr,
saddr);
@@ -2013,7 +1992,8 @@ static int __mkroute_input(struct sk_buff *skb,
}
}
- rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY),
+ rth = rt_dst_alloc(out_dev->dev,
+ IN_DEV_CONF_GET(in_dev, NOPOLICY),
IN_DEV_CONF_GET(out_dev, NOXFRM));
if (!rth) {
err = -ENOBUFS;
@@ -2021,27 +2001,28 @@ static int __mkroute_input(struct sk_buff *skb,
}
rth->rt_key_dst = daddr;
- rth->rt_dst = daddr;
- rth->rt_tos = tos;
- rth->rt_mark = skb->mark;
rth->rt_key_src = saddr;
+ rth->rt_genid = rt_genid(dev_net(rth->dst.dev));
+ rth->rt_flags = flags;
+ rth->rt_type = res->type;
+ rth->rt_key_tos = tos;
+ rth->rt_dst = daddr;
rth->rt_src = saddr;
- rth->rt_gateway = daddr;
rth->rt_route_iif = in_dev->dev->ifindex;
rth->rt_iif = in_dev->dev->ifindex;
- rth->dst.dev = (out_dev)->dev;
- dev_hold(rth->dst.dev);
rth->rt_oif = 0;
+ rth->rt_mark = skb->mark;
+ rth->rt_gateway = daddr;
rth->rt_spec_dst= spec_dst;
+ rth->rt_peer_genid = 0;
+ rth->peer = NULL;
+ rth->fi = NULL;
rth->dst.input = ip_forward;
rth->dst.output = ip_output;
- rth->rt_genid = rt_genid(dev_net(rth->dst.dev));
rt_set_nexthop(rth, NULL, res, res->fi, res->type, itag);
- rth->rt_flags = flags;
-
*result = rth;
err = 0;
cleanup:
@@ -2150,9 +2131,9 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
goto brd_input;
if (res.type == RTN_LOCAL) {
- err = fib_validate_source(saddr, daddr, tos,
+ err = fib_validate_source(skb, saddr, daddr, tos,
net->loopback_dev->ifindex,
- dev, &spec_dst, &itag, skb->mark);
+ dev, &spec_dst, &itag);
if (err < 0)
goto martian_source_keep_err;
if (err)
@@ -2176,8 +2157,8 @@ brd_input:
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,
- &itag, skb->mark);
+ err = fib_validate_source(skb, saddr, 0, tos, 0, dev, &spec_dst,
+ &itag);
if (err < 0)
goto martian_source_keep_err;
if (err)
@@ -2188,36 +2169,42 @@ brd_input:
RT_CACHE_STAT_INC(in_brd);
local_input:
- rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
+ rth = rt_dst_alloc(net->loopback_dev,
+ IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
if (!rth)
goto e_nobufs;
+ rth->dst.input= ip_local_deliver;
rth->dst.output= ip_rt_bug;
- rth->rt_genid = rt_genid(net);
+#ifdef CONFIG_IP_ROUTE_CLASSID
+ rth->dst.tclassid = itag;
+#endif
rth->rt_key_dst = daddr;
- rth->rt_dst = daddr;
- rth->rt_tos = tos;
- rth->rt_mark = skb->mark;
rth->rt_key_src = saddr;
+ rth->rt_genid = rt_genid(net);
+ rth->rt_flags = flags|RTCF_LOCAL;
+ rth->rt_type = res.type;
+ rth->rt_key_tos = tos;
+ rth->rt_dst = daddr;
rth->rt_src = saddr;
#ifdef CONFIG_IP_ROUTE_CLASSID
rth->dst.tclassid = itag;
#endif
rth->rt_route_iif = dev->ifindex;
rth->rt_iif = dev->ifindex;
- rth->dst.dev = net->loopback_dev;
- dev_hold(rth->dst.dev);
+ rth->rt_oif = 0;
+ rth->rt_mark = skb->mark;
rth->rt_gateway = daddr;
rth->rt_spec_dst= spec_dst;
- rth->dst.input= ip_local_deliver;
- rth->rt_flags = flags|RTCF_LOCAL;
+ rth->rt_peer_genid = 0;
+ rth->peer = NULL;
+ rth->fi = NULL;
if (res.type == RTN_UNREACHABLE) {
rth->dst.input= ip_error;
rth->dst.error= -err;
rth->rt_flags &= ~RTCF_LOCAL;
}
- rth->rt_type = res.type;
hash = rt_hash(daddr, saddr, fl4.flowi4_iif, rt_genid(net));
rth = rt_intern_hash(hash, rth, skb, fl4.flowi4_iif);
err = 0;
@@ -2288,7 +2275,7 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
((__force u32)rth->rt_key_src ^ (__force u32)saddr) |
(rth->rt_iif ^ iif) |
rth->rt_oif |
- (rth->rt_tos ^ tos)) == 0 &&
+ (rth->rt_key_tos ^ tos)) == 0 &&
rth->rt_mark == skb->mark &&
net_eq(dev_net(rth->dst.dev), net) &&
!rt_is_expired(rth)) {
@@ -2349,12 +2336,12 @@ EXPORT_SYMBOL(ip_route_input_common);
/* called with rcu_read_lock() */
static struct rtable *__mkroute_output(const struct fib_result *res,
const struct flowi4 *fl4,
- const struct flowi4 *oldflp4,
- struct net_device *dev_out,
+ __be32 orig_daddr, __be32 orig_saddr,
+ int orig_oif, struct net_device *dev_out,
unsigned int flags)
{
struct fib_info *fi = res->fi;
- u32 tos = RT_FL_TOS(oldflp4);
+ u32 tos = RT_FL_TOS(fl4);
struct in_device *in_dev;
u16 type = res->type;
struct rtable *rth;
@@ -2381,8 +2368,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
fi = NULL;
} else if (type == RTN_MULTICAST) {
flags |= RTCF_MULTICAST | RTCF_LOCAL;
- if (!ip_check_mc_rcu(in_dev, oldflp4->daddr, oldflp4->saddr,
- oldflp4->flowi4_proto))
+ if (!ip_check_mc_rcu(in_dev, fl4->daddr, fl4->saddr,
+ fl4->flowi4_proto))
flags &= ~RTCF_LOCAL;
/* If multicast route do not exist use
* default one, but do not gateway in this case.
@@ -2392,29 +2379,31 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
fi = NULL;
}
- rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY),
+ rth = rt_dst_alloc(dev_out,
+ IN_DEV_CONF_GET(in_dev, NOPOLICY),
IN_DEV_CONF_GET(in_dev, NOXFRM));
if (!rth)
return ERR_PTR(-ENOBUFS);
- rth->rt_key_dst = oldflp4->daddr;
- rth->rt_tos = tos;
- rth->rt_key_src = oldflp4->saddr;
- rth->rt_oif = oldflp4->flowi4_oif;
- rth->rt_mark = oldflp4->flowi4_mark;
+ rth->dst.output = ip_output;
+
+ rth->rt_key_dst = orig_daddr;
+ rth->rt_key_src = orig_saddr;
+ rth->rt_genid = rt_genid(dev_net(dev_out));
+ rth->rt_flags = flags;
+ rth->rt_type = type;
+ rth->rt_key_tos = tos;
rth->rt_dst = fl4->daddr;
rth->rt_src = fl4->saddr;
rth->rt_route_iif = 0;
- rth->rt_iif = oldflp4->flowi4_oif ? : dev_out->ifindex;
- /* get references to the devices that are to be hold by the routing
- cache entry */
- rth->dst.dev = dev_out;
- dev_hold(dev_out);
+ rth->rt_iif = orig_oif ? : dev_out->ifindex;
+ rth->rt_oif = orig_oif;
+ rth->rt_mark = fl4->flowi4_mark;
rth->rt_gateway = fl4->daddr;
rth->rt_spec_dst= fl4->saddr;
-
- rth->dst.output=ip_output;
- rth->rt_genid = rt_genid(dev_net(dev_out));
+ rth->rt_peer_genid = 0;
+ rth->peer = NULL;
+ rth->fi = NULL;
RT_CACHE_STAT_INC(out_slow_tot);
@@ -2432,7 +2421,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
#ifdef CONFIG_IP_MROUTE
if (type == RTN_MULTICAST) {
if (IN_DEV_MFORWARD(in_dev) &&
- !ipv4_is_local_multicast(oldflp4->daddr)) {
+ !ipv4_is_local_multicast(fl4->daddr)) {
rth->dst.input = ip_mr_input;
rth->dst.output = ip_mc_output;
}
@@ -2440,9 +2429,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
#endif
}
- rt_set_nexthop(rth, oldflp4, res, fi, type, 0);
+ rt_set_nexthop(rth, fl4, res, fi, type, 0);
- rth->rt_flags = flags;
return rth;
}
@@ -2451,36 +2439,37 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
* called with rcu_read_lock();
*/
-static struct rtable *ip_route_output_slow(struct net *net,
- const struct flowi4 *oldflp4)
+static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4)
{
- u32 tos = RT_FL_TOS(oldflp4);
- struct flowi4 fl4;
- struct fib_result res;
- unsigned int flags = 0;
struct net_device *dev_out = NULL;
+ u32 tos = RT_FL_TOS(fl4);
+ unsigned int flags = 0;
+ struct fib_result res;
struct rtable *rth;
+ __be32 orig_daddr;
+ __be32 orig_saddr;
+ int orig_oif;
res.fi = NULL;
#ifdef CONFIG_IP_MULTIPLE_TABLES
res.r = NULL;
#endif
- fl4.flowi4_oif = oldflp4->flowi4_oif;
- fl4.flowi4_iif = net->loopback_dev->ifindex;
- fl4.flowi4_mark = oldflp4->flowi4_mark;
- fl4.daddr = oldflp4->daddr;
- fl4.saddr = oldflp4->saddr;
- fl4.flowi4_tos = tos & IPTOS_RT_MASK;
- fl4.flowi4_scope = ((tos & RTO_ONLINK) ?
- RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);
+ orig_daddr = fl4->daddr;
+ orig_saddr = fl4->saddr;
+ orig_oif = fl4->flowi4_oif;
+
+ fl4->flowi4_iif = net->loopback_dev->ifindex;
+ fl4->flowi4_tos = tos & IPTOS_RT_MASK;
+ fl4->flowi4_scope = ((tos & RTO_ONLINK) ?
+ RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);
rcu_read_lock();
- if (oldflp4->saddr) {
+ if (fl4->saddr) {
rth = ERR_PTR(-EINVAL);
- if (ipv4_is_multicast(oldflp4->saddr) ||
- ipv4_is_lbcast(oldflp4->saddr) ||
- ipv4_is_zeronet(oldflp4->saddr))
+ if (ipv4_is_multicast(fl4->saddr) ||
+ ipv4_is_lbcast(fl4->saddr) ||
+ ipv4_is_zeronet(fl4->saddr))
goto out;
/* I removed check for oif == dev_out->oif here.
@@ -2491,11 +2480,11 @@ static struct rtable *ip_route_output_slow(struct net *net,
of another iface. --ANK
*/
- if (oldflp4->flowi4_oif == 0 &&
- (ipv4_is_multicast(oldflp4->daddr) ||
- ipv4_is_lbcast(oldflp4->daddr))) {
+ if (fl4->flowi4_oif == 0 &&
+ (ipv4_is_multicast(fl4->daddr) ||
+ ipv4_is_lbcast(fl4->daddr))) {
/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
- dev_out = __ip_dev_find(net, oldflp4->saddr, false);
+ dev_out = __ip_dev_find(net, fl4->saddr, false);
if (dev_out == NULL)
goto out;
@@ -2514,20 +2503,20 @@ static struct rtable *ip_route_output_slow(struct net *net,
Luckily, this hack is good workaround.
*/
- fl4.flowi4_oif = dev_out->ifindex;
+ fl4->flowi4_oif = dev_out->ifindex;
goto make_route;
}
- if (!(oldflp4->flowi4_flags & FLOWI_FLAG_ANYSRC)) {
+ if (!(fl4->flowi4_flags & FLOWI_FLAG_ANYSRC)) {
/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
- if (!__ip_dev_find(net, oldflp4->saddr, false))
+ if (!__ip_dev_find(net, fl4->saddr, false))
goto out;
}
}
- if (oldflp4->flowi4_oif) {
- dev_out = dev_get_by_index_rcu(net, oldflp4->flowi4_oif);
+ if (fl4->flowi4_oif) {
+ dev_out = dev_get_by_index_rcu(net, fl4->flowi4_oif);
rth = ERR_PTR(-ENODEV);
if (dev_out == NULL)
goto out;
@@ -2537,37 +2526,37 @@ static struct rtable *ip_route_output_slow(struct net *net,
rth = ERR_PTR(-ENETUNREACH);
goto out;
}
- if (ipv4_is_local_multicast(oldflp4->daddr) ||
- ipv4_is_lbcast(oldflp4->daddr)) {
- if (!fl4.saddr)
- fl4.saddr = inet_select_addr(dev_out, 0,
- RT_SCOPE_LINK);
+ if (ipv4_is_local_multicast(fl4->daddr) ||
+ ipv4_is_lbcast(fl4->daddr)) {
+ if (!fl4->saddr)
+ fl4->saddr = inet_select_addr(dev_out, 0,
+ RT_SCOPE_LINK);
goto make_route;
}
- if (!fl4.saddr) {
- if (ipv4_is_multicast(oldflp4->daddr))
- fl4.saddr = inet_select_addr(dev_out, 0,
- fl4.flowi4_scope);
- else if (!oldflp4->daddr)
- fl4.saddr = inet_select_addr(dev_out, 0,
- RT_SCOPE_HOST);
+ if (fl4->saddr) {
+ if (ipv4_is_multicast(fl4->daddr))
+ fl4->saddr = inet_select_addr(dev_out, 0,
+ fl4->flowi4_scope);
+ else if (!fl4->daddr)
+ fl4->saddr = inet_select_addr(dev_out, 0,
+ RT_SCOPE_HOST);
}
}
- if (!fl4.daddr) {
- fl4.daddr = fl4.saddr;
- if (!fl4.daddr)
- fl4.daddr = fl4.saddr = htonl(INADDR_LOOPBACK);
+ if (!fl4->daddr) {
+ fl4->daddr = fl4->saddr;
+ if (!fl4->daddr)
+ fl4->daddr = fl4->saddr = htonl(INADDR_LOOPBACK);
dev_out = net->loopback_dev;
- fl4.flowi4_oif = net->loopback_dev->ifindex;
+ fl4->flowi4_oif = net->loopback_dev->ifindex;
res.type = RTN_LOCAL;
flags |= RTCF_LOCAL;
goto make_route;
}
- if (fib_lookup(net, &fl4, &res)) {
+ if (fib_lookup(net, fl4, &res)) {
res.fi = NULL;
- if (oldflp4->flowi4_oif) {
+ if (fl4->flowi4_oif) {
/* Apparently, routing tables are wrong. Assume,
that the destination is on link.
@@ -2586,9 +2575,9 @@ static struct rtable *ip_route_output_slow(struct net *net,
likely IPv6, but we do not.
*/
- if (fl4.saddr == 0)
- fl4.saddr = inet_select_addr(dev_out, 0,
- RT_SCOPE_LINK);
+ if (fl4->saddr == 0)
+ fl4->saddr = inet_select_addr(dev_out, 0,
+ RT_SCOPE_LINK);
res.type = RTN_UNICAST;
goto make_route;
}
@@ -2597,42 +2586,45 @@ static struct rtable *ip_route_output_slow(struct net *net,
}
if (res.type == RTN_LOCAL) {
- if (!fl4.saddr) {
+ if (!fl4->saddr) {
if (res.fi->fib_prefsrc)
- fl4.saddr = res.fi->fib_prefsrc;
+ fl4->saddr = res.fi->fib_prefsrc;
else
- fl4.saddr = fl4.daddr;
+ fl4->saddr = fl4->daddr;
}
dev_out = net->loopback_dev;
- fl4.flowi4_oif = dev_out->ifindex;
+ fl4->flowi4_oif = dev_out->ifindex;
res.fi = NULL;
flags |= RTCF_LOCAL;
goto make_route;
}
#ifdef CONFIG_IP_ROUTE_MULTIPATH
- if (res.fi->fib_nhs > 1 && fl4.flowi4_oif == 0)
+ if (res.fi->fib_nhs > 1 && fl4->flowi4_oif == 0)
fib_select_multipath(&res);
else
#endif
- if (!res.prefixlen && res.type == RTN_UNICAST && !fl4.flowi4_oif)
+ if (!res.prefixlen &&
+ res.table->tb_num_default > 1 &&
+ res.type == RTN_UNICAST && !fl4->flowi4_oif)
fib_select_default(&res);
- if (!fl4.saddr)
- fl4.saddr = FIB_RES_PREFSRC(net, res);
+ if (!fl4->saddr)
+ fl4->saddr = FIB_RES_PREFSRC(net, res);
dev_out = FIB_RES_DEV(res);
- fl4.flowi4_oif = dev_out->ifindex;
+ fl4->flowi4_oif = dev_out->ifindex;
make_route:
- rth = __mkroute_output(&res, &fl4, oldflp4, dev_out, flags);
+ rth = __mkroute_output(&res, fl4, orig_daddr, orig_saddr, orig_oif,
+ dev_out, flags);
if (!IS_ERR(rth)) {
unsigned int hash;
- hash = rt_hash(oldflp4->daddr, oldflp4->saddr, oldflp4->flowi4_oif,
+ hash = rt_hash(orig_daddr, orig_saddr, orig_oif,
rt_genid(dev_net(dev_out)));
- rth = rt_intern_hash(hash, rth, NULL, oldflp4->flowi4_oif);
+ rth = rt_intern_hash(hash, rth, NULL, orig_oif);
}
out:
@@ -2640,7 +2632,7 @@ out:
return rth;
}
-struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *flp4)
+struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *flp4)
{
struct rtable *rth;
unsigned int hash;
@@ -2658,13 +2650,17 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *flp4)
rt_is_output_route(rth) &&
rth->rt_oif == flp4->flowi4_oif &&
rth->rt_mark == flp4->flowi4_mark &&
- !((rth->rt_tos ^ flp4->flowi4_tos) &
+ !((rth->rt_key_tos ^ flp4->flowi4_tos) &
(IPTOS_RT_MASK | RTO_ONLINK)) &&
net_eq(dev_net(rth->dst.dev), net) &&
!rt_is_expired(rth)) {
dst_use(&rth->dst, jiffies);
RT_CACHE_STAT_INC(out_hit);
rcu_read_unlock_bh();
+ if (!flp4->saddr)
+ flp4->saddr = rth->rt_src;
+ if (!flp4->daddr)
+ flp4->daddr = rth->rt_dst;
return rth;
}
RT_CACHE_STAT_INC(out_hlist_search);
@@ -2709,7 +2705,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig)
{
- struct rtable *rt = dst_alloc(&ipv4_dst_blackhole_ops, 1);
+ struct rtable *rt = dst_alloc(&ipv4_dst_blackhole_ops, NULL, 1, 0, 0);
struct rtable *ort = (struct rtable *) dst_orig;
if (rt) {
@@ -2726,7 +2722,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
rt->rt_key_dst = ort->rt_key_dst;
rt->rt_key_src = ort->rt_key_src;
- rt->rt_tos = ort->rt_tos;
+ rt->rt_key_tos = ort->rt_key_tos;
rt->rt_route_iif = ort->rt_route_iif;
rt->rt_iif = ort->rt_iif;
rt->rt_oif = ort->rt_oif;
@@ -2762,15 +2758,10 @@ struct rtable *ip_route_output_flow(struct net *net, struct flowi4 *flp4,
if (IS_ERR(rt))
return rt;
- if (flp4->flowi4_proto) {
- if (!flp4->saddr)
- flp4->saddr = rt->rt_src;
- if (!flp4->daddr)
- flp4->daddr = rt->rt_dst;
+ if (flp4->flowi4_proto)
rt = (struct rtable *) xfrm_lookup(net, &rt->dst,
flowi4_to_flowi(flp4),
sk, 0);
- }
return rt;
}
@@ -2794,7 +2785,7 @@ static int rt_fill_info(struct net *net,
r->rtm_family = AF_INET;
r->rtm_dst_len = 32;
r->rtm_src_len = 0;
- r->rtm_tos = rt->rt_tos;
+ r->rtm_tos = rt->rt_key_tos;
r->rtm_table = RT_TABLE_MAIN;
NLA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN);
r->rtm_type = rt->rt_type;
@@ -2848,7 +2839,9 @@ static int rt_fill_info(struct net *net,
if (ipv4_is_multicast(dst) && !ipv4_is_local_multicast(dst) &&
IPV4_DEVCONF_ALL(net, MC_FORWARDING)) {
- int err = ipmr_get_route(net, skb, r, nowait);
+ int err = ipmr_get_route(net, skb,
+ rt->rt_src, rt->rt_dst,
+ r, nowait);
if (err <= 0) {
if (!nowait) {
if (err == 0)
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 8b44c6d2a79..26461492a84 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -321,10 +321,10 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
* the ACK carries the same options again (see RFC1122 4.2.3.8)
*/
if (opt && opt->optlen) {
- int opt_size = sizeof(struct ip_options) + opt->optlen;
+ int opt_size = sizeof(struct ip_options_rcu) + opt->optlen;
ireq->opt = kmalloc(opt_size, GFP_ATOMIC);
- if (ireq->opt != NULL && ip_options_echo(ireq->opt, skb)) {
+ if (ireq->opt != NULL && ip_options_echo(&ireq->opt->opt, skb)) {
kfree(ireq->opt);
ireq->opt = NULL;
}
@@ -345,17 +345,13 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
* no easy way to do this.
*/
{
- struct flowi4 fl4 = {
- .flowi4_mark = sk->sk_mark,
- .daddr = ((opt && opt->srr) ?
- opt->faddr : ireq->rmt_addr),
- .saddr = ireq->loc_addr,
- .flowi4_tos = RT_CONN_FLAGS(sk),
- .flowi4_proto = IPPROTO_TCP,
- .flowi4_flags = inet_sk_flowi_flags(sk),
- .fl4_sport = th->dest,
- .fl4_dport = th->source,
- };
+ struct flowi4 fl4;
+
+ flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk),
+ RT_SCOPE_UNIVERSE, IPPROTO_TCP,
+ inet_sk_flowi_flags(sk),
+ (opt && opt->srr) ? opt->faddr : ireq->rmt_addr,
+ ireq->loc_addr, th->source, th->dest);
security_req_classify_flow(req, flowi4_to_flowi(&fl4));
rt = ip_route_output_key(sock_net(sk), &fl4);
if (IS_ERR(rt)) {
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 321e6e84dbc..57d0752e239 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -13,6 +13,7 @@
#include <linux/seqlock.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/nsproxy.h>
#include <net/snmp.h>
#include <net/icmp.h>
#include <net/ip.h>
@@ -21,6 +22,7 @@
#include <net/udp.h>
#include <net/cipso_ipv4.h>
#include <net/inet_frag.h>
+#include <net/ping.h>
static int zero;
static int tcp_retr1_max = 255;
@@ -30,6 +32,8 @@ static int tcp_adv_win_scale_min = -31;
static int tcp_adv_win_scale_max = 31;
static int ip_ttl_min = 1;
static int ip_ttl_max = 255;
+static int ip_ping_group_range_min[] = { 0, 0 };
+static int ip_ping_group_range_max[] = { GID_T_MAX, GID_T_MAX };
/* Update system visible IP port range */
static void set_local_port_range(int range[2])
@@ -68,6 +72,53 @@ static int ipv4_local_port_range(ctl_table *table, int write,
return ret;
}
+
+void inet_get_ping_group_range_table(struct ctl_table *table, gid_t *low, gid_t *high)
+{
+ gid_t *data = table->data;
+ unsigned seq;
+ do {
+ seq = read_seqbegin(&sysctl_local_ports.lock);
+
+ *low = data[0];
+ *high = data[1];
+ } while (read_seqretry(&sysctl_local_ports.lock, seq));
+}
+
+/* Update system visible IP port range */
+static void set_ping_group_range(struct ctl_table *table, int range[2])
+{
+ gid_t *data = table->data;
+ write_seqlock(&sysctl_local_ports.lock);
+ data[0] = range[0];
+ data[1] = range[1];
+ write_sequnlock(&sysctl_local_ports.lock);
+}
+
+/* Validate changes from /proc interface. */
+static int ipv4_ping_group_range(ctl_table *table, int write,
+ void __user *buffer,
+ size_t *lenp, loff_t *ppos)
+{
+ int ret;
+ gid_t range[2];
+ ctl_table tmp = {
+ .data = &range,
+ .maxlen = sizeof(range),
+ .mode = table->mode,
+ .extra1 = &ip_ping_group_range_min,
+ .extra2 = &ip_ping_group_range_max,
+ };
+
+ inet_get_ping_group_range_table(table, range, range + 1);
+ ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
+
+ if (write && ret == 0)
+ set_ping_group_range(table, range);
+
+ return ret;
+}
+
static int proc_tcp_congestion_control(ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
@@ -677,6 +728,13 @@ static struct ctl_table ipv4_net_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec
},
+ {
+ .procname = "ping_group_range",
+ .data = &init_net.ipv4.sysctl_ping_group_range,
+ .maxlen = sizeof(init_net.ipv4.sysctl_ping_group_range),
+ .mode = 0644,
+ .proc_handler = ipv4_ping_group_range,
+ },
{ }
};
@@ -711,8 +769,18 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
&net->ipv4.sysctl_icmp_ratemask;
table[6].data =
&net->ipv4.sysctl_rt_cache_rebuild_count;
+ table[7].data =
+ &net->ipv4.sysctl_ping_group_range;
+
}
+ /*
+ * Sane defaults - nobody may create ping sockets.
+ * Boot scripts should set this to distro-specific group.
+ */
+ net->ipv4.sysctl_ping_group_range[0] = 1;
+ net->ipv4.sysctl_ping_group_range[1] = 0;
+
net->ipv4.sysctl_rt_cache_rebuild_count = 4;
net->ipv4.ipv4_hdr = register_net_sysctl_table(net,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index b22d4501054..054a59d21eb 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -999,7 +999,8 @@ new_segment:
/* We have some space in skb head. Superb! */
if (copy > skb_tailroom(skb))
copy = skb_tailroom(skb);
- if ((err = skb_add_data(skb, from, copy)) != 0)
+ err = skb_add_data_nocache(sk, skb, from, copy);
+ if (err)
goto do_fault;
} else {
int merge = 0;
@@ -1042,8 +1043,8 @@ new_segment:
/* Time to copy data. We are close to
* the end! */
- err = skb_copy_to_page(sk, from, skb, page,
- off, copy);
+ err = skb_copy_to_page_nocache(sk, from, skb,
+ page, off, copy);
if (err) {
/* If this page was new, give it to the
* socket so it does not get leaked.
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index f7e6c2c2d2b..3c8d9b6f1ea 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -146,13 +146,15 @@ EXPORT_SYMBOL_GPL(tcp_twsk_unique);
/* This will initiate an outgoing connection. */
int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
+ struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
struct inet_sock *inet = inet_sk(sk);
struct tcp_sock *tp = tcp_sk(sk);
- struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
__be16 orig_sport, orig_dport;
- struct rtable *rt;
__be32 daddr, nexthop;
+ struct flowi4 *fl4;
+ struct rtable *rt;
int err;
+ struct ip_options_rcu *inet_opt;
if (addr_len < sizeof(struct sockaddr_in))
return -EINVAL;
@@ -161,15 +163,18 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
return -EAFNOSUPPORT;
nexthop = daddr = usin->sin_addr.s_addr;
- if (inet->opt && inet->opt->srr) {
+ inet_opt = rcu_dereference_protected(inet->inet_opt,
+ sock_owned_by_user(sk));
+ if (inet_opt && inet_opt->opt.srr) {
if (!daddr)
return -EINVAL;
- nexthop = inet->opt->faddr;
+ nexthop = inet_opt->opt.faddr;
}
orig_sport = inet->inet_sport;
orig_dport = usin->sin_port;
- rt = ip_route_connect(nexthop, inet->inet_saddr,
+ fl4 = &inet->cork.fl.u.ip4;
+ rt = ip_route_connect(fl4, nexthop, inet->inet_saddr,
RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
IPPROTO_TCP,
orig_sport, orig_dport, sk, true);
@@ -185,11 +190,11 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
return -ENETUNREACH;
}
- if (!inet->opt || !inet->opt->srr)
- daddr = rt->rt_dst;
+ if (!inet_opt || !inet_opt->opt.srr)
+ daddr = fl4->daddr;
if (!inet->inet_saddr)
- inet->inet_saddr = rt->rt_src;
+ inet->inet_saddr = fl4->saddr;
inet->inet_rcv_saddr = inet->inet_saddr;
if (tp->rx_opt.ts_recent_stamp && inet->inet_daddr != daddr) {
@@ -200,8 +205,8 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
}
if (tcp_death_row.sysctl_tw_recycle &&
- !tp->rx_opt.ts_recent_stamp && rt->rt_dst == daddr) {
- struct inet_peer *peer = rt_get_peer(rt);
+ !tp->rx_opt.ts_recent_stamp && fl4->daddr == daddr) {
+ struct inet_peer *peer = rt_get_peer(rt, fl4->daddr);
/*
* VJ's idea. We save last timestamp seen from
* the destination in peer table, when entering state
@@ -221,8 +226,8 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
inet->inet_daddr = daddr;
inet_csk(sk)->icsk_ext_hdr_len = 0;
- if (inet->opt)
- inet_csk(sk)->icsk_ext_hdr_len = inet->opt->optlen;
+ if (inet_opt)
+ inet_csk(sk)->icsk_ext_hdr_len = inet_opt->opt.optlen;
tp->rx_opt.mss_clamp = TCP_MSS_DEFAULT;
@@ -236,8 +241,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
if (err)
goto failure;
- rt = ip_route_newports(rt, IPPROTO_TCP,
- orig_sport, orig_dport,
+ rt = ip_route_newports(fl4, rt, orig_sport, orig_dport,
inet->inet_sport, inet->inet_dport, sk);
if (IS_ERR(rt)) {
err = PTR_ERR(rt);
@@ -279,7 +283,7 @@ EXPORT_SYMBOL(tcp_v4_connect);
/*
* This routine does path mtu discovery as defined in RFC1191.
*/
-static void do_pmtu_discovery(struct sock *sk, struct iphdr *iph, u32 mtu)
+static void do_pmtu_discovery(struct sock *sk, const struct iphdr *iph, u32 mtu)
{
struct dst_entry *dst;
struct inet_sock *inet = inet_sk(sk);
@@ -341,7 +345,7 @@ static void do_pmtu_discovery(struct sock *sk, struct iphdr *iph, u32 mtu)
void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
{
- struct iphdr *iph = (struct iphdr *)icmp_skb->data;
+ const struct iphdr *iph = (const struct iphdr *)icmp_skb->data;
struct tcphdr *th = (struct tcphdr *)(icmp_skb->data + (iph->ihl << 2));
struct inet_connection_sock *icsk;
struct tcp_sock *tp;
@@ -647,7 +651,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0;
net = dev_net(skb_dst(skb)->dev);
- ip_send_reply(net->ipv4.tcp_sock, skb,
+ ip_send_reply(net->ipv4.tcp_sock, skb, ip_hdr(skb)->saddr,
&arg, arg.iov[0].iov_len);
TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
@@ -722,7 +726,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
if (oif)
arg.bound_dev_if = oif;
- ip_send_reply(net->ipv4.tcp_sock, skb,
+ ip_send_reply(net->ipv4.tcp_sock, skb, ip_hdr(skb)->saddr,
&arg, arg.iov[0].iov_len);
TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
@@ -765,11 +769,12 @@ static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst,
struct request_values *rvp)
{
const struct inet_request_sock *ireq = inet_rsk(req);
+ struct flowi4 fl4;
int err = -1;
struct sk_buff * skb;
/* First, grab a route. */
- if (!dst && (dst = inet_csk_route_req(sk, req)) == NULL)
+ if (!dst && (dst = inet_csk_route_req(sk, &fl4, req)) == NULL)
return -1;
skb = tcp_make_synack(sk, dst, req, rvp);
@@ -820,17 +825,18 @@ static void syn_flood_warning(const struct sk_buff *skb)
/*
* Save and compile IPv4 options into the request_sock if needed.
*/
-static struct ip_options *tcp_v4_save_options(struct sock *sk,
- struct sk_buff *skb)
+static struct ip_options_rcu *tcp_v4_save_options(struct sock *sk,
+ struct sk_buff *skb)
{
- struct ip_options *opt = &(IPCB(skb)->opt);
- struct ip_options *dopt = NULL;
+ const struct ip_options *opt = &(IPCB(skb)->opt);
+ struct ip_options_rcu *dopt = NULL;
if (opt && opt->optlen) {
- int opt_size = optlength(opt);
+ int opt_size = sizeof(*dopt) + opt->optlen;
+
dopt = kmalloc(opt_size, GFP_ATOMIC);
if (dopt) {
- if (ip_options_echo(dopt, skb)) {
+ if (ip_options_echo(&dopt->opt, skb)) {
kfree(dopt);
dopt = NULL;
}
@@ -1333,6 +1339,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
req->cookie_ts = tmp_opt.tstamp_ok;
} else if (!isn) {
struct inet_peer *peer = NULL;
+ struct flowi4 fl4;
/* VJ's idea. We save last timestamp seen
* from the destination in peer table, when entering
@@ -1345,9 +1352,9 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
*/
if (tmp_opt.saw_tstamp &&
tcp_death_row.sysctl_tw_recycle &&
- (dst = inet_csk_route_req(sk, req)) != NULL &&
- (peer = rt_get_peer((struct rtable *)dst)) != NULL &&
- peer->daddr.addr.a4 == saddr) {
+ (dst = inet_csk_route_req(sk, &fl4, req)) != NULL &&
+ fl4.daddr == saddr &&
+ (peer = rt_get_peer((struct rtable *)dst, fl4.daddr)) != NULL) {
inet_peer_refcheck(peer);
if ((u32)get_seconds() - peer->tcp_ts_stamp < TCP_PAWS_MSL &&
(s32)(peer->tcp_ts - req->ts_recent) >
@@ -1411,19 +1418,16 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
#ifdef CONFIG_TCP_MD5SIG
struct tcp_md5sig_key *key;
#endif
+ struct ip_options_rcu *inet_opt;
if (sk_acceptq_is_full(sk))
goto exit_overflow;
- if (!dst && (dst = inet_csk_route_req(sk, req)) == NULL)
- goto exit;
-
newsk = tcp_create_openreq_child(sk, req, skb);
if (!newsk)
goto exit_nonewsk;
newsk->sk_gso_type = SKB_GSO_TCPV4;
- sk_setup_caps(newsk, dst);
newtp = tcp_sk(newsk);
newinet = inet_sk(newsk);
@@ -1431,15 +1435,21 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
newinet->inet_daddr = ireq->rmt_addr;
newinet->inet_rcv_saddr = ireq->loc_addr;
newinet->inet_saddr = ireq->loc_addr;
- newinet->opt = ireq->opt;
+ inet_opt = ireq->opt;
+ rcu_assign_pointer(newinet->inet_opt, inet_opt);
ireq->opt = NULL;
newinet->mc_index = inet_iif(skb);
newinet->mc_ttl = ip_hdr(skb)->ttl;
inet_csk(newsk)->icsk_ext_hdr_len = 0;
- if (newinet->opt)
- inet_csk(newsk)->icsk_ext_hdr_len = newinet->opt->optlen;
+ if (inet_opt)
+ inet_csk(newsk)->icsk_ext_hdr_len = inet_opt->opt.optlen;
newinet->inet_id = newtp->write_seq ^ jiffies;
+ if (!dst && (dst = inet_csk_route_child_sock(sk, newsk, req)) == NULL)
+ goto put_and_exit;
+
+ sk_setup_caps(newsk, dst);
+
tcp_mtup_init(newsk);
tcp_sync_mss(newsk, dst_mtu(dst));
newtp->advmss = dst_metric_advmss(dst);
@@ -1467,10 +1477,8 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
}
#endif
- if (__inet_inherit_port(sk, newsk) < 0) {
- sock_put(newsk);
- goto exit;
- }
+ if (__inet_inherit_port(sk, newsk) < 0)
+ goto put_and_exit;
__inet_hash_nolisten(newsk, NULL);
return newsk;
@@ -1482,6 +1490,9 @@ exit_nonewsk:
exit:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
return NULL;
+put_and_exit:
+ sock_put(newsk);
+ goto exit;
}
EXPORT_SYMBOL(tcp_v4_syn_recv_sock);
@@ -1764,12 +1775,13 @@ struct inet_peer *tcp_v4_get_peer(struct sock *sk, bool *release_it)
struct inet_sock *inet = inet_sk(sk);
struct inet_peer *peer;
- if (!rt || rt->rt_dst != inet->inet_daddr) {
+ if (!rt ||
+ inet->cork.fl.u.ip4.daddr != inet->inet_daddr) {
peer = inet_getpeer_v4(inet->inet_daddr, 1);
*release_it = true;
} else {
if (!rt->peer)
- rt_bind_peer(rt, 1);
+ rt_bind_peer(rt, inet->inet_daddr, 1);
peer = rt->peer;
*release_it = false;
}
@@ -2527,7 +2539,7 @@ void tcp4_proc_exit(void)
struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb)
{
- struct iphdr *iph = skb_gro_network_header(skb);
+ const struct iphdr *iph = skb_gro_network_header(skb);
switch (skb->ip_summed) {
case CHECKSUM_COMPLETE:
@@ -2548,7 +2560,7 @@ struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb)
int tcp4_gro_complete(struct sk_buff *skb)
{
- struct iphdr *iph = ip_hdr(skb);
+ const struct iphdr *iph = ip_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
th->check = ~tcp_v4_check(skb->len - skb_transport_offset(skb),
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 17388c7f49c..882e0b0964d 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -899,7 +899,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS,
tcp_skb_pcount(skb));
- err = icsk->icsk_af_ops->queue_xmit(skb);
+ err = icsk->icsk_af_ops->queue_xmit(skb, &inet->cork.fl);
if (likely(err <= 0))
return err;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index f87a8eb76f3..599374f65c7 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -578,7 +578,7 @@ found:
void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
{
struct inet_sock *inet;
- struct iphdr *iph = (struct iphdr *)skb->data;
+ const struct iphdr *iph = (const struct iphdr *)skb->data;
struct udphdr *uh = (struct udphdr *)(skb->data+(iph->ihl<<2));
const int type = icmp_hdr(skb)->type;
const int code = icmp_hdr(skb)->code;
@@ -706,12 +706,11 @@ static void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst)
}
}
-static int udp_send_skb(struct sk_buff *skb, __be32 daddr, __be32 dport)
+static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4)
{
struct sock *sk = skb->sk;
struct inet_sock *inet = inet_sk(sk);
struct udphdr *uh;
- struct rtable *rt = (struct rtable *)skb_dst(skb);
int err = 0;
int is_udplite = IS_UDPLITE(sk);
int offset = skb_transport_offset(skb);
@@ -723,7 +722,7 @@ static int udp_send_skb(struct sk_buff *skb, __be32 daddr, __be32 dport)
*/
uh = udp_hdr(skb);
uh->source = inet->inet_sport;
- uh->dest = dport;
+ uh->dest = fl4->fl4_dport;
uh->len = htons(len);
uh->check = 0;
@@ -737,14 +736,14 @@ static int udp_send_skb(struct sk_buff *skb, __be32 daddr, __be32 dport)
} else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */
- udp4_hwcsum(skb, rt->rt_src, daddr);
+ udp4_hwcsum(skb, fl4->saddr, fl4->daddr);
goto send;
} else
csum = udp_csum(skb);
/* add protocol-dependent pseudo-header */
- uh->check = csum_tcpudp_magic(rt->rt_src, daddr, len,
+ uh->check = csum_tcpudp_magic(fl4->saddr, fl4->daddr, len,
sk->sk_protocol, csum);
if (uh->check == 0)
uh->check = CSUM_MANGLED_0;
@@ -774,11 +773,11 @@ static int udp_push_pending_frames(struct sock *sk)
struct sk_buff *skb;
int err = 0;
- skb = ip_finish_skb(sk);
+ skb = ip_finish_skb(sk, fl4);
if (!skb)
goto out;
- err = udp_send_skb(skb, fl4->daddr, fl4->fl4_dport);
+ err = udp_send_skb(skb, fl4);
out:
up->len = 0;
@@ -791,6 +790,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
{
struct inet_sock *inet = inet_sk(sk);
struct udp_sock *up = udp_sk(sk);
+ struct flowi4 fl4_stack;
struct flowi4 *fl4;
int ulen = len;
struct ipcm_cookie ipc;
@@ -804,6 +804,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
struct sk_buff *skb;
+ struct ip_options_data opt_copy;
if (len > 0xFFFF)
return -EMSGSIZE;
@@ -820,6 +821,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
+ fl4 = &inet->cork.fl.u.ip4;
if (up->pending) {
/*
* There are pending frames.
@@ -877,22 +879,32 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
free = 1;
connected = 0;
}
- if (!ipc.opt)
- ipc.opt = inet->opt;
+ if (!ipc.opt) {
+ struct ip_options_rcu *inet_opt;
+
+ rcu_read_lock();
+ inet_opt = rcu_dereference(inet->inet_opt);
+ if (inet_opt) {
+ memcpy(&opt_copy, inet_opt,
+ sizeof(*inet_opt) + inet_opt->opt.optlen);
+ ipc.opt = &opt_copy.opt;
+ }
+ rcu_read_unlock();
+ }
saddr = ipc.addr;
ipc.addr = faddr = daddr;
- if (ipc.opt && ipc.opt->srr) {
+ if (ipc.opt && ipc.opt->opt.srr) {
if (!daddr)
return -EINVAL;
- faddr = ipc.opt->faddr;
+ faddr = ipc.opt->opt.faddr;
connected = 0;
}
tos = RT_TOS(inet->tos);
if (sock_flag(sk, SOCK_LOCALROUTE) ||
(msg->msg_flags & MSG_DONTROUTE) ||
- (ipc.opt && ipc.opt->is_strictroute)) {
+ (ipc.opt && ipc.opt->opt.is_strictroute)) {
tos |= RTO_ONLINK;
connected = 0;
}
@@ -909,22 +921,16 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
rt = (struct rtable *)sk_dst_check(sk, 0);
if (rt == NULL) {
- struct flowi4 fl4 = {
- .flowi4_oif = ipc.oif,
- .flowi4_mark = sk->sk_mark,
- .daddr = faddr,
- .saddr = saddr,
- .flowi4_tos = tos,
- .flowi4_proto = sk->sk_protocol,
- .flowi4_flags = (inet_sk_flowi_flags(sk) |
- FLOWI_FLAG_CAN_SLEEP),
- .fl4_sport = inet->inet_sport,
- .fl4_dport = dport,
- };
struct net *net = sock_net(sk);
- security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
- rt = ip_route_output_flow(net, &fl4, sk);
+ fl4 = &fl4_stack;
+ flowi4_init_output(fl4, ipc.oif, sk->sk_mark, tos,
+ RT_SCOPE_UNIVERSE, sk->sk_protocol,
+ inet_sk_flowi_flags(sk)|FLOWI_FLAG_CAN_SLEEP,
+ faddr, saddr, dport, inet->inet_sport);
+
+ security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
+ rt = ip_route_output_flow(net, fl4, sk);
if (IS_ERR(rt)) {
err = PTR_ERR(rt);
rt = NULL;
@@ -945,18 +951,18 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
goto do_confirm;
back_from_confirm:
- saddr = rt->rt_src;
+ saddr = fl4->saddr;
if (!ipc.addr)
- daddr = ipc.addr = rt->rt_dst;
+ daddr = ipc.addr = fl4->daddr;
/* Lockless fast path for the non-corking case. */
if (!corkreq) {
- skb = ip_make_skb(sk, getfrag, msg->msg_iov, ulen,
+ skb = ip_make_skb(sk, fl4, getfrag, msg->msg_iov, ulen,
sizeof(struct udphdr), &ipc, &rt,
msg->msg_flags);
err = PTR_ERR(skb);
if (skb && !IS_ERR(skb))
- err = udp_send_skb(skb, daddr, dport);
+ err = udp_send_skb(skb, fl4);
goto out;
}
@@ -982,9 +988,9 @@ back_from_confirm:
do_append_data:
up->len += ulen;
- err = ip_append_data(sk, getfrag, msg->msg_iov, ulen,
- sizeof(struct udphdr), &ipc, &rt,
- corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
+ err = ip_append_data(sk, fl4, getfrag, msg->msg_iov, ulen,
+ sizeof(struct udphdr), &ipc, &rt,
+ corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
if (err)
udp_flush_pending_frames(sk);
else if (!corkreq)
@@ -1024,6 +1030,7 @@ EXPORT_SYMBOL(udp_sendmsg);
int udp_sendpage(struct sock *sk, struct page *page, int offset,
size_t size, int flags)
{
+ struct inet_sock *inet = inet_sk(sk);
struct udp_sock *up = udp_sk(sk);
int ret;
@@ -1048,7 +1055,8 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset,
return -EINVAL;
}
- ret = ip_append_page(sk, page, offset, size, flags);
+ ret = ip_append_page(sk, &inet->cork.fl.u.ip4,
+ page, offset, size, flags);
if (ret == -EOPNOTSUPP) {
release_sock(sk);
return sock_no_sendpage(sk->sk_socket, page, offset,
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index d20a05e970d..981e43eaf70 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -18,38 +18,46 @@
static struct xfrm_policy_afinfo xfrm4_policy_afinfo;
-static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos,
- const xfrm_address_t *saddr,
- const xfrm_address_t *daddr)
+static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4,
+ int tos,
+ const xfrm_address_t *saddr,
+ const xfrm_address_t *daddr)
{
- struct flowi4 fl4 = {
- .daddr = daddr->a4,
- .flowi4_tos = tos,
- };
struct rtable *rt;
+ memset(fl4, 0, sizeof(*fl4));
+ fl4->daddr = daddr->a4;
+ fl4->flowi4_tos = tos;
if (saddr)
- fl4.saddr = saddr->a4;
+ fl4->saddr = saddr->a4;
- rt = __ip_route_output_key(net, &fl4);
+ rt = __ip_route_output_key(net, fl4);
if (!IS_ERR(rt))
return &rt->dst;
return ERR_CAST(rt);
}
+static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos,
+ const xfrm_address_t *saddr,
+ const xfrm_address_t *daddr)
+{
+ struct flowi4 fl4;
+
+ return __xfrm4_dst_lookup(net, &fl4, tos, saddr, daddr);
+}
+
static int xfrm4_get_saddr(struct net *net,
xfrm_address_t *saddr, xfrm_address_t *daddr)
{
struct dst_entry *dst;
- struct rtable *rt;
+ struct flowi4 fl4;
- dst = xfrm4_dst_lookup(net, 0, NULL, daddr);
+ dst = __xfrm4_dst_lookup(net, &fl4, 0, NULL, daddr);
if (IS_ERR(dst))
return -EHOSTUNREACH;
- rt = (struct rtable *)dst;
- saddr->a4 = rt->rt_src;
+ saddr->a4 = fl4.saddr;
dst_release(dst);
return 0;
}
@@ -73,7 +81,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
rt->rt_key_dst = fl4->daddr;
rt->rt_key_src = fl4->saddr;
- rt->rt_tos = fl4->flowi4_tos;
+ rt->rt_key_tos = fl4->flowi4_tos;
rt->rt_route_iif = fl4->flowi4_iif;
rt->rt_iif = fl4->flowi4_iif;
rt->rt_oif = fl4->flowi4_oif;
@@ -102,7 +110,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
static void
_decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
{
- struct iphdr *iph = ip_hdr(skb);
+ const struct iphdr *iph = ip_hdr(skb);
u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
struct flowi4 *fl4 = &fl->u.ip4;
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index 805d63ef434..d9ac0a0058b 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -55,7 +55,7 @@ xfrm4_init_temprop(struct xfrm_state *x, const struct xfrm_tmpl *tmpl,
int xfrm4_extract_header(struct sk_buff *skb)
{
- struct iphdr *iph = ip_hdr(skb);
+ const struct iphdr *iph = ip_hdr(skb);
XFRM_MODE_SKB_CB(skb)->ihl = sizeof(*iph);
XFRM_MODE_SKB_CB(skb)->id = iph->id;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 8f13d88d7db..498b927f68b 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -289,19 +289,19 @@ static int snmp6_alloc_dev(struct inet6_dev *idev)
sizeof(struct ipstats_mib),
__alignof__(struct ipstats_mib)) < 0)
goto err_ip;
- if (snmp_mib_init((void __percpu **)idev->stats.icmpv6,
- sizeof(struct icmpv6_mib),
- __alignof__(struct icmpv6_mib)) < 0)
+ idev->stats.icmpv6dev = kzalloc(sizeof(struct icmpv6_mib_device),
+ GFP_KERNEL);
+ if (!idev->stats.icmpv6dev)
goto err_icmp;
- if (snmp_mib_init((void __percpu **)idev->stats.icmpv6msg,
- sizeof(struct icmpv6msg_mib),
- __alignof__(struct icmpv6msg_mib)) < 0)
+ idev->stats.icmpv6msgdev = kzalloc(sizeof(struct icmpv6msg_mib_device),
+ GFP_KERNEL);
+ if (!idev->stats.icmpv6msgdev)
goto err_icmpmsg;
return 0;
err_icmpmsg:
- snmp_mib_free((void __percpu **)idev->stats.icmpv6);
+ kfree(idev->stats.icmpv6dev);
err_icmp:
snmp_mib_free((void __percpu **)idev->stats.ipv6);
err_ip:
@@ -310,8 +310,8 @@ err_ip:
static void snmp6_free_dev(struct inet6_dev *idev)
{
- snmp_mib_free((void __percpu **)idev->stats.icmpv6msg);
- snmp_mib_free((void __percpu **)idev->stats.icmpv6);
+ kfree(idev->stats.icmpv6msgdev);
+ kfree(idev->stats.icmpv6dev);
snmp_mib_free((void __percpu **)idev->stats.ipv6);
}
@@ -813,6 +813,8 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
dst_release(&rt->dst);
}
+ /* clean up prefsrc entries */
+ rt6_remove_prefsrc(ifp);
out:
in6_ifa_put(ifp);
}
@@ -1269,7 +1271,7 @@ static int ipv6_count_addresses(struct inet6_dev *idev)
return cnt;
}
-int ipv6_chk_addr(struct net *net, struct in6_addr *addr,
+int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
struct net_device *dev, int strict)
{
struct inet6_ifaddr *ifp;
@@ -1312,7 +1314,7 @@ static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
return false;
}
-int ipv6_chk_prefix(struct in6_addr *addr, struct net_device *dev)
+int ipv6_chk_prefix(const struct in6_addr *addr, struct net_device *dev)
{
struct inet6_dev *idev;
struct inet6_ifaddr *ifa;
@@ -1443,7 +1445,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
/* Join to solicited addr multicast group. */
-void addrconf_join_solict(struct net_device *dev, struct in6_addr *addr)
+void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr)
{
struct in6_addr maddr;
@@ -1454,7 +1456,7 @@ void addrconf_join_solict(struct net_device *dev, struct in6_addr *addr)
ipv6_dev_mc_inc(dev, &maddr);
}
-void addrconf_leave_solict(struct inet6_dev *idev, struct in6_addr *addr)
+void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr)
{
struct in6_addr maddr;
@@ -2099,7 +2101,7 @@ err_exit:
/*
* Manual configuration of address on an interface
*/
-static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx,
+static int inet6_addr_add(struct net *net, int ifindex, const struct in6_addr *pfx,
unsigned int plen, __u8 ifa_flags, __u32 prefered_lft,
__u32 valid_lft)
{
@@ -2173,7 +2175,7 @@ static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx,
return PTR_ERR(ifp);
}
-static int inet6_addr_del(struct net *net, int ifindex, struct in6_addr *pfx,
+static int inet6_addr_del(struct net *net, int ifindex, const struct in6_addr *pfx,
unsigned int plen)
{
struct inet6_ifaddr *ifp;
@@ -2336,7 +2338,7 @@ static void init_loopback(struct net_device *dev)
add_addr(idev, &in6addr_loopback, 128, IFA_HOST);
}
-static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr)
+static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr)
{
struct inet6_ifaddr * ifp;
u32 addr_flags = IFA_F_PERMANENT;
@@ -3107,7 +3109,7 @@ void if6_proc_exit(void)
#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 net *net, struct in6_addr *addr)
+int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr)
{
int ret = 0;
struct inet6_ifaddr *ifp = NULL;
@@ -3824,7 +3826,7 @@ static inline size_t inet6_if_nlmsg_size(void)
+ nla_total_size(inet6_ifla6_size()); /* IFLA_PROTINFO */
}
-static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib,
+static inline void __snmp6_fill_statsdev(u64 *stats, atomic_long_t *mib,
int items, int bytes)
{
int i;
@@ -3834,7 +3836,7 @@ static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib,
/* Use put_unaligned() because stats may not be aligned for u64. */
put_unaligned(items, &stats[0]);
for (i = 1; i < items; i++)
- put_unaligned(snmp_fold_field(mib, i), &stats[i]);
+ put_unaligned(atomic_long_read(&mib[i]), &stats[i]);
memset(&stats[items], 0, pad);
}
@@ -3863,7 +3865,7 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
IPSTATS_MIB_MAX, bytes, offsetof(struct ipstats_mib, syncp));
break;
case IFLA_INET6_ICMP6STATS:
- __snmp6_fill_stats(stats, (void __percpu **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes);
+ __snmp6_fill_statsdev(stats, idev->stats.icmpv6dev->mibs, ICMP6_MIB_MAX, bytes);
break;
}
}
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index afcc7099f96..b7919f901fb 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -740,7 +740,7 @@ static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto)
static int ipv6_gso_send_check(struct sk_buff *skb)
{
- struct ipv6hdr *ipv6h;
+ const struct ipv6hdr *ipv6h;
const struct inet6_protocol *ops;
int err = -EINVAL;
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 0e5e943446f..674255f5e6b 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -44,7 +44,7 @@
#include <net/checksum.h>
-static int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr);
+static int ipv6_dev_ac_dec(struct net_device *dev, const struct in6_addr *addr);
/* Big ac list lock for all the sockets */
static DEFINE_RWLOCK(ipv6_sk_ac_lock);
@@ -54,7 +54,7 @@ static DEFINE_RWLOCK(ipv6_sk_ac_lock);
* socket join an anycast group
*/
-int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
+int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct net_device *dev = NULL;
@@ -145,7 +145,7 @@ error:
/*
* socket leave an anycast group
*/
-int ipv6_sock_ac_drop(struct sock *sk, int ifindex, struct in6_addr *addr)
+int ipv6_sock_ac_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct net_device *dev;
@@ -252,7 +252,7 @@ static void aca_put(struct ifacaddr6 *ac)
/*
* device anycast group inc (add if not found)
*/
-int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr)
+int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr)
{
struct ifacaddr6 *aca;
struct inet6_dev *idev;
@@ -324,7 +324,7 @@ out:
/*
* device anycast group decrement
*/
-int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr)
+int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr)
{
struct ifacaddr6 *aca, *prev_aca;
@@ -358,7 +358,7 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr)
}
/* called with rcu_read_lock() */
-static int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr)
+static int ipv6_dev_ac_dec(struct net_device *dev, const struct in6_addr *addr)
{
struct inet6_dev *idev = __in6_dev_get(dev);
@@ -371,7 +371,7 @@ static int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr)
* check if the interface has this anycast address
* called with rcu_read_lock()
*/
-static int ipv6_chk_acast_dev(struct net_device *dev, struct in6_addr *addr)
+static int ipv6_chk_acast_dev(struct net_device *dev, const struct in6_addr *addr)
{
struct inet6_dev *idev;
struct ifacaddr6 *aca;
@@ -392,7 +392,7 @@ static int ipv6_chk_acast_dev(struct net_device *dev, struct in6_addr *addr)
* check if given interface (or any, if dev==0) has this anycast address
*/
int ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
- struct in6_addr *addr)
+ const struct in6_addr *addr)
{
int found = 0;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 59dccfbb5b1..1ac7938dd9e 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -430,7 +430,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
u8 type, u8 code, int offset, __be32 info)
{
struct net *net = dev_net(skb->dev);
- struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
+ const struct ipv6hdr *iph = (const struct ipv6hdr *)skb->data;
struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data + offset);
struct xfrm_state *x;
@@ -438,7 +438,8 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
type != ICMPV6_PKT_TOOBIG)
return;
- x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6);
+ x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr,
+ esph->spi, IPPROTO_ESP, AF_INET6);
if (!x)
return;
printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n",
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 83cb4f9add8..11900417b1c 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -372,7 +372,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
struct ipv6hdr *hdr = ipv6_hdr(skb);
struct sock *sk;
struct ipv6_pinfo *np;
- struct in6_addr *saddr = NULL;
+ const struct in6_addr *saddr = NULL;
struct dst_entry *dst;
struct icmp6hdr tmp_hdr;
struct flowi6 fl6;
@@ -521,7 +521,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
struct sock *sk;
struct inet6_dev *idev;
struct ipv6_pinfo *np;
- struct in6_addr *saddr = NULL;
+ const struct in6_addr *saddr = NULL;
struct icmp6hdr *icmph = icmp6_hdr(skb);
struct icmp6hdr tmp_hdr;
struct flowi6 fl6;
@@ -645,8 +645,8 @@ static int icmpv6_rcv(struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
struct inet6_dev *idev = __in6_dev_get(dev);
- struct in6_addr *saddr, *daddr;
- struct ipv6hdr *orig_hdr;
+ const struct in6_addr *saddr, *daddr;
+ const struct ipv6hdr *orig_hdr;
struct icmp6hdr *hdr;
u8 type;
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index f2c5b0fc0f2..8a58e8cf664 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -203,7 +203,7 @@ struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
return dst;
}
-int inet6_csk_xmit(struct sk_buff *skb)
+int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused)
{
struct sock *sk = skb->sk;
struct inet_sock *inet = inet_sk(sk);
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 7548905e79e..4076a0b14b2 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -134,9 +134,9 @@ static __inline__ u32 fib6_new_sernum(void)
# define BITOP_BE32_SWIZZLE 0
#endif
-static __inline__ __be32 addr_bit_set(void *token, int fn_bit)
+static __inline__ __be32 addr_bit_set(const void *token, int fn_bit)
{
- __be32 *addr = token;
+ const __be32 *addr = token;
/*
* Here,
* 1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)
@@ -394,10 +394,11 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
arg.net = net;
w->args = &arg;
+ rcu_read_lock();
for (h = s_h; h < FIB6_TABLE_HASHSZ; h++, s_e = 0) {
e = 0;
head = &net->ipv6.fib_table_hash[h];
- hlist_for_each_entry(tb, node, head, tb6_hlist) {
+ hlist_for_each_entry_rcu(tb, node, head, tb6_hlist) {
if (e < s_e)
goto next;
res = fib6_dump_table(tb, skb, cb);
@@ -408,6 +409,7 @@ next:
}
}
out:
+ rcu_read_unlock();
cb->args[1] = e;
cb->args[0] = h;
@@ -822,7 +824,7 @@ st_failure:
struct lookup_args {
int offset; /* key offset on rt6_info */
- struct in6_addr *addr; /* search key */
+ const struct in6_addr *addr; /* search key */
};
static struct fib6_node * fib6_lookup_1(struct fib6_node *root,
@@ -881,8 +883,8 @@ static struct fib6_node * fib6_lookup_1(struct fib6_node *root,
return NULL;
}
-struct fib6_node * fib6_lookup(struct fib6_node *root, struct in6_addr *daddr,
- struct in6_addr *saddr)
+struct fib6_node * fib6_lookup(struct fib6_node *root, const struct in6_addr *daddr,
+ const struct in6_addr *saddr)
{
struct fib6_node *fn;
struct lookup_args args[] = {
@@ -916,7 +918,7 @@ struct fib6_node * fib6_lookup(struct fib6_node *root, struct in6_addr *daddr,
static struct fib6_node * fib6_locate_1(struct fib6_node *root,
- struct in6_addr *addr,
+ const struct in6_addr *addr,
int plen, int offset)
{
struct fib6_node *fn;
@@ -946,8 +948,8 @@ static struct fib6_node * fib6_locate_1(struct fib6_node *root,
}
struct fib6_node * fib6_locate(struct fib6_node *root,
- struct in6_addr *daddr, int dst_len,
- struct in6_addr *saddr, int src_len)
+ const struct in6_addr *daddr, int dst_len,
+ const struct in6_addr *saddr, int src_len)
{
struct fib6_node *fn;
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index a83e9209cec..027c7ff6f1e 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -57,7 +57,7 @@ inline int ip6_rcv_finish( struct sk_buff *skb)
int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
{
- struct ipv6hdr *hdr;
+ const struct ipv6hdr *hdr;
u32 pkt_len;
struct inet6_dev *idev;
struct net *net = dev_net(skb->dev);
@@ -186,7 +186,7 @@ resubmit:
int ret;
if (ipprot->flags & INET6_PROTO_FINAL) {
- struct ipv6hdr *hdr;
+ const struct ipv6hdr *hdr;
/* Free reference early: we don't need it any more,
and it may hold ip_conntrack module loaded
@@ -242,7 +242,7 @@ int ip6_input(struct sk_buff *skb)
int ip6_mc_input(struct sk_buff *skb)
{
- struct ipv6hdr *hdr;
+ const struct ipv6hdr *hdr;
int deliver;
IP6_UPD_PO_STATS_BH(dev_net(skb_dst(skb)->dev),
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 46cf7bea676..9d4b165837d 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -869,9 +869,9 @@ fail:
return err;
}
-static inline int ip6_rt_check(struct rt6key *rt_key,
- struct in6_addr *fl_addr,
- struct in6_addr *addr_cache)
+static inline int ip6_rt_check(const struct rt6key *rt_key,
+ const struct in6_addr *fl_addr,
+ const struct in6_addr *addr_cache)
{
return (rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) &&
(addr_cache == NULL || !ipv6_addr_equal(fl_addr, addr_cache));
@@ -879,7 +879,7 @@ static inline int ip6_rt_check(struct rt6key *rt_key,
static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
struct dst_entry *dst,
- struct flowi6 *fl6)
+ const struct flowi6 *fl6)
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct rt6_info *rt = (struct rt6_info *)dst;
@@ -930,10 +930,10 @@ static int ip6_dst_lookup_tail(struct sock *sk,
goto out_err_release;
if (ipv6_addr_any(&fl6->saddr)) {
- err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev,
- &fl6->daddr,
- sk ? inet6_sk(sk)->srcprefs : 0,
- &fl6->saddr);
+ struct rt6_info *rt = (struct rt6_info *) *dst;
+ err = ip6_route_get_saddr(net, rt, &fl6->daddr,
+ sk ? inet6_sk(sk)->srcprefs : 0,
+ &fl6->saddr);
if (err)
goto out_err_release;
}
@@ -1150,6 +1150,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
{
struct inet_sock *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk);
+ struct inet_cork *cork;
struct sk_buff *skb;
unsigned int maxfraglen, fragheaderlen;
int exthdrlen;
@@ -1163,6 +1164,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
if (flags&MSG_PROBE)
return 0;
+ cork = &inet->cork.base;
if (skb_queue_empty(&sk->sk_write_queue)) {
/*
* setup for corking
@@ -1202,7 +1204,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
/* need source address above miyazawa*/
}
dst_hold(&rt->dst);
- inet->cork.dst = &rt->dst;
+ cork->dst = &rt->dst;
inet->cork.fl.u.ip6 = *fl6;
np->cork.hop_limit = hlimit;
np->cork.tclass = tclass;
@@ -1212,10 +1214,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
if (np->frag_size)
mtu = np->frag_size;
}
- inet->cork.fragsize = mtu;
+ cork->fragsize = mtu;
if (dst_allfrag(rt->dst.path))
- inet->cork.flags |= IPCORK_ALLFRAG;
- inet->cork.length = 0;
+ cork->flags |= IPCORK_ALLFRAG;
+ cork->length = 0;
sk->sk_sndmsg_page = NULL;
sk->sk_sndmsg_off = 0;
exthdrlen = rt->dst.header_len + (opt ? opt->opt_flen : 0) -
@@ -1223,12 +1225,12 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
length += exthdrlen;
transhdrlen += exthdrlen;
} else {
- rt = (struct rt6_info *)inet->cork.dst;
+ rt = (struct rt6_info *)cork->dst;
fl6 = &inet->cork.fl.u.ip6;
opt = np->cork.opt;
transhdrlen = 0;
exthdrlen = 0;
- mtu = inet->cork.fragsize;
+ mtu = cork->fragsize;
}
hh_len = LL_RESERVED_SPACE(rt->dst.dev);
@@ -1238,7 +1240,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr);
if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) {
- if (inet->cork.length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) {
+ if (cork->length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) {
ipv6_local_error(sk, EMSGSIZE, fl6, mtu-exthdrlen);
return -EMSGSIZE;
}
@@ -1267,7 +1269,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
* --yoshfuji
*/
- inet->cork.length += length;
+ cork->length += length;
if (length > mtu) {
int proto = sk->sk_protocol;
if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){
@@ -1292,7 +1294,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
while (length > 0) {
/* Check if the remaining data fits into current packet. */
- copy = (inet->cork.length <= mtu && !(inet->cork.flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - skb->len;
+ copy = (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - skb->len;
if (copy < length)
copy = maxfraglen - skb->len;
@@ -1317,7 +1319,7 @@ alloc_new_skb:
* we know we need more fragment(s).
*/
datalen = length + fraggap;
- if (datalen > (inet->cork.length <= mtu && !(inet->cork.flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - fragheaderlen)
+ if (datalen > (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - fragheaderlen)
datalen = maxfraglen - fragheaderlen;
fraglen = datalen + fragheaderlen;
@@ -1481,7 +1483,7 @@ alloc_new_skb:
}
return 0;
error:
- inet->cork.length -= length;
+ cork->length -= length;
IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
return err;
}
@@ -1497,10 +1499,10 @@ static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np)
np->cork.opt = NULL;
}
- if (inet->cork.dst) {
- dst_release(inet->cork.dst);
- inet->cork.dst = NULL;
- inet->cork.flags &= ~IPCORK_ALLFRAG;
+ if (inet->cork.base.dst) {
+ dst_release(inet->cork.base.dst);
+ inet->cork.base.dst = NULL;
+ inet->cork.base.flags &= ~IPCORK_ALLFRAG;
}
memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
}
@@ -1515,7 +1517,7 @@ int ip6_push_pending_frames(struct sock *sk)
struct net *net = sock_net(sk);
struct ipv6hdr *hdr;
struct ipv6_txoptions *opt = np->cork.opt;
- struct rt6_info *rt = (struct rt6_info *)inet->cork.dst;
+ struct rt6_info *rt = (struct rt6_info *)inet->cork.base.dst;
struct flowi6 *fl6 = &inet->cork.fl.u.ip6;
unsigned char proto = fl6->flowi6_proto;
int err = 0;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index c1b1bd312df..36c2842a86b 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -162,7 +162,7 @@ static inline void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst)
for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
static struct ip6_tnl *
-ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local)
+ip6_tnl_lookup(struct net *net, const struct in6_addr *remote, const struct in6_addr *local)
{
unsigned int h0 = HASH(remote);
unsigned int h1 = HASH(local);
@@ -194,10 +194,10 @@ ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local)
**/
static struct ip6_tnl __rcu **
-ip6_tnl_bucket(struct ip6_tnl_net *ip6n, struct ip6_tnl_parm *p)
+ip6_tnl_bucket(struct ip6_tnl_net *ip6n, const struct ip6_tnl_parm *p)
{
- struct in6_addr *remote = &p->raddr;
- struct in6_addr *local = &p->laddr;
+ const struct in6_addr *remote = &p->raddr;
+ const struct in6_addr *local = &p->laddr;
unsigned h = 0;
int prio = 0;
@@ -280,11 +280,6 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p)
dev_net_set(dev, net);
- if (strchr(name, '%')) {
- if (dev_alloc_name(dev, name) < 0)
- goto failed_free;
- }
-
t = netdev_priv(dev);
t->parms = *p;
err = ip6_tnl_dev_init(dev);
@@ -321,8 +316,8 @@ failed:
static struct ip6_tnl *ip6_tnl_locate(struct net *net,
struct ip6_tnl_parm *p, int create)
{
- struct in6_addr *remote = &p->raddr;
- struct in6_addr *local = &p->laddr;
+ const struct in6_addr *remote = &p->raddr;
+ const struct in6_addr *local = &p->laddr;
struct ip6_tnl __rcu **tp;
struct ip6_tnl *t;
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
@@ -374,7 +369,7 @@ ip6_tnl_dev_uninit(struct net_device *dev)
static __u16
parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw)
{
- struct ipv6hdr *ipv6h = (struct ipv6hdr *) raw;
+ const struct ipv6hdr *ipv6h = (const struct ipv6hdr *) raw;
__u8 nexthdr = ipv6h->nexthdr;
__u16 off = sizeof (*ipv6h);
@@ -435,7 +430,7 @@ static int
ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
u8 *type, u8 *code, int *msg, __u32 *info, int offset)
{
- struct ipv6hdr *ipv6h = (struct ipv6hdr *) skb->data;
+ const struct ipv6hdr *ipv6h = (const struct ipv6hdr *) skb->data;
struct ip6_tnl *t;
int rel_msg = 0;
u8 rel_type = ICMPV6_DEST_UNREACH;
@@ -535,8 +530,9 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
__u32 rel_info = ntohl(info);
int err;
struct sk_buff *skb2;
- struct iphdr *eiph;
+ const struct iphdr *eiph;
struct rtable *rt;
+ struct flowi4 fl4;
err = ip6_tnl_err(skb, IPPROTO_IPIP, opt, &rel_type, &rel_code,
&rel_msg, &rel_info, offset);
@@ -577,7 +573,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
eiph = ip_hdr(skb2);
/* Try to guess incoming interface */
- rt = ip_route_output_ports(dev_net(skb->dev), NULL,
+ rt = ip_route_output_ports(dev_net(skb->dev), &fl4, NULL,
eiph->saddr, 0,
0, 0,
IPPROTO_IPIP, RT_TOS(eiph->tos), 0);
@@ -590,7 +586,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
if (rt->rt_flags & RTCF_LOCAL) {
ip_rt_put(rt);
rt = NULL;
- rt = ip_route_output_ports(dev_net(skb->dev), NULL,
+ rt = ip_route_output_ports(dev_net(skb->dev), &fl4, NULL,
eiph->daddr, eiph->saddr,
0, 0,
IPPROTO_IPIP,
@@ -669,8 +665,8 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
return 0;
}
-static void ip4ip6_dscp_ecn_decapsulate(struct ip6_tnl *t,
- struct ipv6hdr *ipv6h,
+static void ip4ip6_dscp_ecn_decapsulate(const struct ip6_tnl *t,
+ const struct ipv6hdr *ipv6h,
struct sk_buff *skb)
{
__u8 dsfield = ipv6_get_dsfield(ipv6h) & ~INET_ECN_MASK;
@@ -682,8 +678,8 @@ static void ip4ip6_dscp_ecn_decapsulate(struct ip6_tnl *t,
IP_ECN_set_ce(ip_hdr(skb));
}
-static void ip6ip6_dscp_ecn_decapsulate(struct ip6_tnl *t,
- struct ipv6hdr *ipv6h,
+static void ip6ip6_dscp_ecn_decapsulate(const struct ip6_tnl *t,
+ const struct ipv6hdr *ipv6h,
struct sk_buff *skb)
{
if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY)
@@ -726,12 +722,12 @@ static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t)
static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
__u8 ipproto,
- void (*dscp_ecn_decapsulate)(struct ip6_tnl *t,
- struct ipv6hdr *ipv6h,
+ void (*dscp_ecn_decapsulate)(const struct ip6_tnl *t,
+ const struct ipv6hdr *ipv6h,
struct sk_buff *skb))
{
struct ip6_tnl *t;
- struct ipv6hdr *ipv6h = ipv6_hdr(skb);
+ const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
rcu_read_lock();
@@ -828,7 +824,7 @@ static void init_tel_txopt(struct ipv6_tel_txoption *opt, __u8 encap_limit)
**/
static inline int
-ip6_tnl_addr_conflict(struct ip6_tnl *t, struct ipv6hdr *hdr)
+ip6_tnl_addr_conflict(const struct ip6_tnl *t, const struct ipv6hdr *hdr)
{
return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr);
}
@@ -1005,7 +1001,7 @@ static inline int
ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ip6_tnl *t = netdev_priv(dev);
- struct iphdr *iph = ip_hdr(skb);
+ const struct iphdr *iph = ip_hdr(skb);
int encap_limit = -1;
struct flowi6 fl6;
__u8 dsfield;
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 29e48593bf2..82a809901f8 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -989,8 +989,8 @@ static int mif6_add(struct net *net, struct mr6_table *mrt,
}
static struct mfc6_cache *ip6mr_cache_find(struct mr6_table *mrt,
- struct in6_addr *origin,
- struct in6_addr *mcastgrp)
+ const struct in6_addr *origin,
+ const struct in6_addr *mcastgrp)
{
int line = MFC6_HASH(mcastgrp, origin);
struct mfc6_cache *c;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 85cccd6ed0b..bba658d9a03 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -55,7 +55,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
{
struct net *net = dev_net(skb->dev);
__be32 spi;
- struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
+ const struct ipv6hdr *iph = (const struct ipv6hdr *)skb->data;
struct ip_comp_hdr *ipcomph =
(struct ip_comp_hdr *)(skb->data + offset);
struct xfrm_state *x;
@@ -64,7 +64,8 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
return;
spi = htonl(ntohs(ipcomph->cpi));
- x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6);
+ x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr,
+ spi, IPPROTO_COMP, AF_INET6);
if (!x)
return;
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index f2d98ca7588..3e6ebcdb477 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -92,16 +92,16 @@ static void mld_gq_timer_expire(unsigned long data);
static void mld_ifc_timer_expire(unsigned long data);
static void mld_ifc_event(struct inet6_dev *idev);
static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc);
-static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *addr);
+static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *addr);
static void mld_clear_delrec(struct inet6_dev *idev);
static int sf_setstate(struct ifmcaddr6 *pmc);
static void sf_markstate(struct ifmcaddr6 *pmc);
static void ip6_mc_clear_src(struct ifmcaddr6 *pmc);
-static int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca,
- int sfmode, int sfcount, struct in6_addr *psfsrc,
+static int ip6_mc_del_src(struct inet6_dev *idev, const struct in6_addr *pmca,
+ int sfmode, int sfcount, const struct in6_addr *psfsrc,
int delta);
-static int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca,
- int sfmode, int sfcount, struct in6_addr *psfsrc,
+static int ip6_mc_add_src(struct inet6_dev *idev, const struct in6_addr *pmca,
+ int sfmode, int sfcount, const struct in6_addr *psfsrc,
int delta);
static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
struct inet6_dev *idev);
@@ -246,7 +246,7 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
/* called with rcu_read_lock() */
static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net,
- struct in6_addr *group,
+ const struct in6_addr *group,
int ifindex)
{
struct net_device *dev = NULL;
@@ -447,7 +447,7 @@ done:
int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
{
- struct in6_addr *group;
+ const struct in6_addr *group;
struct ipv6_mc_socklist *pmc;
struct inet6_dev *idev;
struct ipv6_pinfo *inet6 = inet6_sk(sk);
@@ -538,7 +538,7 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
struct group_filter __user *optval, int __user *optlen)
{
int err, i, count, copycount;
- struct in6_addr *group;
+ const struct in6_addr *group;
struct ipv6_mc_socklist *pmc;
struct inet6_dev *idev;
struct ipv6_pinfo *inet6 = inet6_sk(sk);
@@ -748,7 +748,7 @@ static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im)
spin_unlock_bh(&idev->mc_lock);
}
-static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *pmca)
+static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *pmca)
{
struct ifmcaddr6 *pmc, *pmc_prev;
struct ip6_sf_list *psf, *psf_next;
@@ -1048,7 +1048,7 @@ static void igmp6_group_queried(struct ifmcaddr6 *ma, unsigned long resptime)
/* mark EXCLUDE-mode sources */
static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs,
- struct in6_addr *srcs)
+ const struct in6_addr *srcs)
{
struct ip6_sf_list *psf;
int i, scount;
@@ -1076,7 +1076,7 @@ static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs,
}
static int mld_marksources(struct ifmcaddr6 *pmc, int nsrcs,
- struct in6_addr *srcs)
+ const struct in6_addr *srcs)
{
struct ip6_sf_list *psf;
int i, scount;
@@ -1111,7 +1111,7 @@ int igmp6_event_query(struct sk_buff *skb)
{
struct mld2_query *mlh2 = NULL;
struct ifmcaddr6 *ma;
- struct in6_addr *group;
+ const struct in6_addr *group;
unsigned long max_delay;
struct inet6_dev *idev;
struct mld_msg *mld;
@@ -1817,7 +1817,7 @@ err_out:
}
static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
- struct in6_addr *psfsrc)
+ const struct in6_addr *psfsrc)
{
struct ip6_sf_list *psf, *psf_prev;
int rv = 0;
@@ -1853,8 +1853,8 @@ static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
return rv;
}
-static int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca,
- int sfmode, int sfcount, struct in6_addr *psfsrc,
+static int ip6_mc_del_src(struct inet6_dev *idev, const struct in6_addr *pmca,
+ int sfmode, int sfcount, const struct in6_addr *psfsrc,
int delta)
{
struct ifmcaddr6 *pmc;
@@ -1914,7 +1914,7 @@ static int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca,
* Add multicast single-source filter to the interface list
*/
static int ip6_mc_add1_src(struct ifmcaddr6 *pmc, int sfmode,
- struct in6_addr *psfsrc, int delta)
+ const struct in6_addr *psfsrc, int delta)
{
struct ip6_sf_list *psf, *psf_prev;
@@ -2017,8 +2017,8 @@ static int sf_setstate(struct ifmcaddr6 *pmc)
/*
* Add multicast source filter list to the interface list
*/
-static int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca,
- int sfmode, int sfcount, struct in6_addr *psfsrc,
+static int ip6_mc_add_src(struct inet6_dev *idev, const struct in6_addr *pmca,
+ int sfmode, int sfcount, const struct in6_addr *psfsrc,
int delta)
{
struct ifmcaddr6 *pmc;
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 9b210482fb0..43242e6e610 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -126,7 +126,7 @@ static struct mip6_report_rate_limiter mip6_report_rl = {
static int mip6_destopt_input(struct xfrm_state *x, struct sk_buff *skb)
{
- struct ipv6hdr *iph = ipv6_hdr(skb);
+ const struct ipv6hdr *iph = ipv6_hdr(skb);
struct ipv6_destopt_hdr *destopt = (struct ipv6_destopt_hdr *)skb->data;
int err = destopt->nexthdr;
@@ -181,8 +181,8 @@ static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb)
}
static inline int mip6_report_rl_allow(struct timeval *stamp,
- struct in6_addr *dst,
- struct in6_addr *src, int iif)
+ const struct in6_addr *dst,
+ const struct in6_addr *src, int iif)
{
int allow = 0;
@@ -349,7 +349,7 @@ static const struct xfrm_type mip6_destopt_type =
static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb)
{
- struct ipv6hdr *iph = ipv6_hdr(skb);
+ const struct ipv6hdr *iph = ipv6_hdr(skb);
struct rt2_hdr *rt2 = (struct rt2_hdr *)skb->data;
int err = rt2->rt_hdr.nexthdr;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 92f952d093d..7596f071d30 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -324,7 +324,7 @@ static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
return lladdr + prepad;
}
-int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
+int ndisc_mc_map(const struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
{
switch (dev->type) {
case ARPHRD_ETHER:
@@ -611,6 +611,29 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
inc_opt ? ND_OPT_TARGET_LL_ADDR : 0);
}
+static void ndisc_send_unsol_na(struct net_device *dev)
+{
+ struct inet6_dev *idev;
+ struct inet6_ifaddr *ifa;
+ struct in6_addr mcaddr;
+
+ idev = in6_dev_get(dev);
+ if (!idev)
+ return;
+
+ read_lock_bh(&idev->lock);
+ list_for_each_entry(ifa, &idev->addr_list, if_list) {
+ addrconf_addr_solict_mult(&ifa->addr, &mcaddr);
+ ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr,
+ /*router=*/ !!idev->cnf.forwarding,
+ /*solicited=*/ false, /*override=*/ true,
+ /*inc_opt=*/ true);
+ }
+ read_unlock_bh(&idev->lock);
+
+ in6_dev_put(idev);
+}
+
void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
const struct in6_addr *solicit,
const struct in6_addr *daddr, const struct in6_addr *saddr)
@@ -725,8 +748,8 @@ static int pndisc_is_router(const void *pkey,
static void ndisc_recv_ns(struct sk_buff *skb)
{
struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
- struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
- struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
+ const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
+ const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
u8 *lladdr = NULL;
u32 ndoptlen = skb->tail - (skb->transport_header +
offsetof(struct nd_msg, opt));
@@ -901,8 +924,8 @@ out:
static void ndisc_recv_na(struct sk_buff *skb)
{
struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
- struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
- struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
+ const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
+ const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
u8 *lladdr = NULL;
u32 ndoptlen = skb->tail - (skb->transport_header +
offsetof(struct nd_msg, opt));
@@ -945,9 +968,10 @@ static void ndisc_recv_na(struct sk_buff *skb)
}
ifp = ipv6_get_ifaddr(dev_net(dev), &msg->target, dev, 1);
if (ifp) {
- if (ifp->flags & IFA_F_TENTATIVE) {
- addrconf_dad_failure(ifp);
- return;
+ if (skb->pkt_type != PACKET_LOOPBACK
+ && (ifp->flags & IFA_F_TENTATIVE)) {
+ addrconf_dad_failure(ifp);
+ return;
}
/* What should we make now? The advertisement
is invalid, but ndisc specs say nothing
@@ -1014,7 +1038,7 @@ static void ndisc_recv_rs(struct sk_buff *skb)
unsigned long ndoptlen = skb->len - sizeof(*rs_msg);
struct neighbour *neigh;
struct inet6_dev *idev;
- struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
+ const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
struct ndisc_options ndopts;
u8 *lladdr = NULL;
@@ -1411,8 +1435,8 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
{
struct inet6_dev *in6_dev;
struct icmp6hdr *icmph;
- struct in6_addr *dest;
- struct in6_addr *target; /* new first hop to destination */
+ const struct in6_addr *dest;
+ const struct in6_addr *target; /* new first hop to destination */
struct neighbour *neigh;
int on_link = 0;
struct ndisc_options ndopts;
@@ -1445,7 +1469,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
}
icmph = icmp6_hdr(skb);
- target = (struct in6_addr *) (icmph + 1);
+ target = (const struct in6_addr *) (icmph + 1);
dest = target + 1;
if (ipv6_addr_is_multicast(dest)) {
@@ -1722,6 +1746,9 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event,
neigh_ifdown(&nd_tbl, dev);
fib6_run_gc(~0UL, net);
break;
+ case NETDEV_NOTIFY_PEERS:
+ ndisc_send_unsol_na(dev);
+ break;
default:
break;
}
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 28bc1f644b7..30fcee46544 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -13,7 +13,7 @@
int ip6_route_me_harder(struct sk_buff *skb)
{
struct net *net = dev_net(skb_dst(skb)->dev);
- struct ipv6hdr *iph = ipv6_hdr(skb);
+ const struct ipv6hdr *iph = ipv6_hdr(skb);
struct dst_entry *dst;
struct flowi6 fl6 = {
.flowi6_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
@@ -67,7 +67,7 @@ static void nf_ip6_saveroute(const struct sk_buff *skb,
struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry);
if (entry->hook == NF_INET_LOCAL_OUT) {
- struct ipv6hdr *iph = ipv6_hdr(skb);
+ const struct ipv6hdr *iph = ipv6_hdr(skb);
rt_info->daddr = iph->daddr;
rt_info->saddr = iph->saddr;
@@ -81,7 +81,7 @@ static int nf_ip6_reroute(struct sk_buff *skb,
struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry);
if (entry->hook == NF_INET_LOCAL_OUT) {
- struct ipv6hdr *iph = ipv6_hdr(skb);
+ const struct ipv6hdr *iph = ipv6_hdr(skb);
if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) ||
!ipv6_addr_equal(&iph->saddr, &rt_info->saddr) ||
skb->mark != rt_info->mark)
@@ -108,7 +108,7 @@ static int nf_ip6_route(struct net *net, struct dst_entry **dst,
__sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
unsigned int dataoff, u_int8_t protocol)
{
- struct ipv6hdr *ip6h = ipv6_hdr(skb);
+ const struct ipv6hdr *ip6h = ipv6_hdr(skb);
__sum16 csum = 0;
switch (skb->ip_summed) {
@@ -142,7 +142,7 @@ static __sum16 nf_ip6_checksum_partial(struct sk_buff *skb, unsigned int hook,
unsigned int dataoff, unsigned int len,
u_int8_t protocol)
{
- struct ipv6hdr *ip6h = ipv6_hdr(skb);
+ const struct ipv6hdr *ip6h = ipv6_hdr(skb);
__wsum hsum;
__sum16 csum = 0;
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 5a1c6f27ffa..94874b0bdcd 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -340,6 +340,7 @@ ip6t_do_table(struct sk_buff *skb,
unsigned int *stackptr, origptr, cpu;
const struct xt_table_info *private;
struct xt_action_param acpar;
+ unsigned int addend;
/* Initialization */
indev = in ? in->name : nulldevname;
@@ -358,7 +359,8 @@ ip6t_do_table(struct sk_buff *skb,
IP_NF_ASSERT(table->valid_hooks & (1 << hook));
- xt_info_rdlock_bh();
+ local_bh_disable();
+ addend = xt_write_recseq_begin();
private = table->private;
cpu = smp_processor_id();
table_base = private->entries[cpu];
@@ -442,7 +444,9 @@ ip6t_do_table(struct sk_buff *skb,
} while (!acpar.hotdrop);
*stackptr = origptr;
- xt_info_rdunlock_bh();
+
+ xt_write_recseq_end(addend);
+ local_bh_enable();
#ifdef DEBUG_ALLOW_ALL
return NF_ACCEPT;
@@ -899,7 +903,7 @@ get_counters(const struct xt_table_info *t,
unsigned int i;
for_each_possible_cpu(cpu) {
- seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock;
+ seqcount_t *s = &per_cpu(xt_recseq, cpu);
i = 0;
xt_entry_foreach(iter, t->entries[cpu], t->size) {
@@ -907,10 +911,10 @@ get_counters(const struct xt_table_info *t,
unsigned int start;
do {
- start = read_seqbegin(lock);
+ start = read_seqcount_begin(s);
bcnt = iter->counters.bcnt;
pcnt = iter->counters.pcnt;
- } while (read_seqretry(lock, start));
+ } while (read_seqcount_retry(s, start));
ADD_COUNTER(counters[i], bcnt, pcnt);
++i;
@@ -1325,6 +1329,7 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
int ret = 0;
const void *loc_cpu_entry;
struct ip6t_entry *iter;
+ unsigned int addend;
#ifdef CONFIG_COMPAT
struct compat_xt_counters_info compat_tmp;
@@ -1381,13 +1386,13 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
i = 0;
/* Choose the copy that is on our node */
curcpu = smp_processor_id();
- xt_info_wrlock(curcpu);
+ addend = xt_write_recseq_begin();
loc_cpu_entry = private->entries[curcpu];
xt_entry_foreach(iter, loc_cpu_entry, private->size) {
ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt);
++i;
}
- xt_info_wrunlock(curcpu);
+ xt_write_recseq_end(addend);
unlock_up_free:
local_bh_enable();
@@ -1578,7 +1583,6 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
struct xt_table_info *newinfo, unsigned char *base)
{
struct xt_entry_target *t;
- struct xt_target *target;
struct ip6t_entry *de;
unsigned int origsize;
int ret, h;
@@ -1600,7 +1604,6 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
}
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);
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 679a0a3b7b3..00d19173db7 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -64,7 +64,8 @@ ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out)
(memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) ||
memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) ||
skb->mark != mark ||
- ipv6_hdr(skb)->hop_limit != hop_limit))
+ ipv6_hdr(skb)->hop_limit != hop_limit ||
+ flowlabel != *((u_int32_t *)ipv6_hdr(skb))))
return ip6_route_me_harder(skb) == 0 ? ret : NF_DROP;
return ret;
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 24b3558b8e6..18ff5df7ec0 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -141,7 +141,11 @@ static const struct snmp_mib snmp6_udplite6_list[] = {
SNMP_MIB_SENTINEL
};
-static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void __percpu **mib)
+/* can be called either with percpu mib (pcpumib != NULL),
+ * or shared one (smib != NULL)
+ */
+static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void __percpu **pcpumib,
+ atomic_long_t *smib)
{
char name[32];
int i;
@@ -158,14 +162,14 @@ static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void __percpu **mib)
snprintf(name, sizeof(name), "Icmp6%s%s",
i & 0x100 ? "Out" : "In", p);
seq_printf(seq, "%-32s\t%lu\n", name,
- snmp_fold_field(mib, i));
+ pcpumib ? snmp_fold_field(pcpumib, i) : atomic_long_read(smib + i));
}
/* print by number (nonzero only) - ICMPMsgStat format */
for (i = 0; i < ICMP6MSG_MIB_MAX; i++) {
unsigned long val;
- val = snmp_fold_field(mib, i);
+ val = pcpumib ? snmp_fold_field(pcpumib, i) : atomic_long_read(smib + i);
if (!val)
continue;
snprintf(name, sizeof(name), "Icmp6%sType%u",
@@ -174,14 +178,22 @@ static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void __percpu **mib)
}
}
-static void snmp6_seq_show_item(struct seq_file *seq, void __percpu **mib,
+/* can be called either with percpu mib (pcpumib != NULL),
+ * or shared one (smib != NULL)
+ */
+static void snmp6_seq_show_item(struct seq_file *seq, void __percpu **pcpumib,
+ atomic_long_t *smib,
const struct snmp_mib *itemlist)
{
int i;
+ unsigned long val;
- for (i = 0; itemlist[i].name; i++)
- seq_printf(seq, "%-32s\t%lu\n", itemlist[i].name,
- snmp_fold_field(mib, itemlist[i].entry));
+ for (i = 0; itemlist[i].name; i++) {
+ val = pcpumib ?
+ snmp_fold_field(pcpumib, itemlist[i].entry) :
+ atomic_long_read(smib + itemlist[i].entry);
+ seq_printf(seq, "%-32s\t%lu\n", itemlist[i].name, val);
+ }
}
static void snmp6_seq_show_item64(struct seq_file *seq, void __percpu **mib,
@@ -201,13 +213,13 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
snmp6_seq_show_item64(seq, (void __percpu **)net->mib.ipv6_statistics,
snmp6_ipstats_list, offsetof(struct ipstats_mib, syncp));
snmp6_seq_show_item(seq, (void __percpu **)net->mib.icmpv6_statistics,
- snmp6_icmp6_list);
+ NULL, snmp6_icmp6_list);
snmp6_seq_show_icmpv6msg(seq,
- (void __percpu **)net->mib.icmpv6msg_statistics);
+ (void __percpu **)net->mib.icmpv6msg_statistics, NULL);
snmp6_seq_show_item(seq, (void __percpu **)net->mib.udp_stats_in6,
- snmp6_udp6_list);
+ NULL, snmp6_udp6_list);
snmp6_seq_show_item(seq, (void __percpu **)net->mib.udplite_stats_in6,
- snmp6_udplite6_list);
+ NULL, snmp6_udplite6_list);
return 0;
}
@@ -229,11 +241,11 @@ static int snmp6_dev_seq_show(struct seq_file *seq, void *v)
struct inet6_dev *idev = (struct inet6_dev *)seq->private;
seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex);
- snmp6_seq_show_item(seq, (void __percpu **)idev->stats.ipv6,
+ snmp6_seq_show_item(seq, (void __percpu **)idev->stats.ipv6, NULL,
snmp6_ipstats_list);
- snmp6_seq_show_item(seq, (void __percpu **)idev->stats.icmpv6,
+ snmp6_seq_show_item(seq, NULL, idev->stats.icmpv6dev->mibs,
snmp6_icmp6_list);
- snmp6_seq_show_icmpv6msg(seq, (void __percpu **)idev->stats.icmpv6msg);
+ snmp6_seq_show_icmpv6msg(seq, NULL, idev->stats.icmpv6msgdev->mibs);
return 0;
}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 4a1c3b46c56..ae64984f81a 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -67,8 +67,8 @@ static struct raw_hashinfo raw_v6_hashinfo = {
};
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)
+ unsigned short num, const struct in6_addr *loc_addr,
+ const struct in6_addr *rmt_addr, int dif)
{
struct hlist_node *node;
int is_multicast = ipv6_addr_is_multicast(loc_addr);
@@ -154,8 +154,8 @@ EXPORT_SYMBOL(rawv6_mh_filter_unregister);
*/
static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
{
- struct in6_addr *saddr;
- struct in6_addr *daddr;
+ const struct in6_addr *saddr;
+ const struct in6_addr *daddr;
struct sock *sk;
int delivered = 0;
__u8 hash;
@@ -348,7 +348,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
{
struct sock *sk;
int hash;
- struct in6_addr *saddr, *daddr;
+ const struct in6_addr *saddr, *daddr;
struct net *net;
hash = nexthdr & (RAW_HTABLE_SIZE - 1);
@@ -357,7 +357,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
sk = sk_head(&raw_v6_hashinfo.ht[hash]);
if (sk != NULL) {
/* Note: ipv6_hdr(skb) != skb->data */
- struct ipv6hdr *ip6h = (struct ipv6hdr *)skb->data;
+ const struct ipv6hdr *ip6h = (const struct ipv6hdr *)skb->data;
saddr = &ip6h->saddr;
daddr = &ip6h->daddr;
net = dev_net(skb->dev);
@@ -542,8 +542,8 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
goto out;
offset = rp->offset;
- total_len = inet_sk(sk)->cork.length - (skb_network_header(skb) -
- skb->data);
+ total_len = inet_sk(sk)->cork.base.length - (skb_network_header(skb) -
+ skb->data);
if (offset >= total_len - 1) {
err = -EINVAL;
ip6_flush_pending_frames(sk);
@@ -1231,7 +1231,7 @@ struct proto rawv6_prot = {
static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
{
struct ipv6_pinfo *np = inet6_sk(sp);
- struct in6_addr *dest, *src;
+ const struct in6_addr *dest, *src;
__u16 destp, srcp;
dest = &np->daddr;
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 07beeb06f75..7b954e2539d 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -224,7 +224,7 @@ out:
}
static __inline__ struct frag_queue *
-fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst)
+fq_find(struct net *net, __be32 id, const struct in6_addr *src, const struct in6_addr *dst)
{
struct inet_frag_queue *q;
struct ip6_create_arg arg;
@@ -535,7 +535,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
{
struct frag_hdr *fhdr;
struct frag_queue *fq;
- struct ipv6hdr *hdr = ipv6_hdr(skb);
+ const struct ipv6hdr *hdr = ipv6_hdr(skb);
struct net *net = dev_net(skb_dst(skb)->dev);
IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMREQDS);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index fd0eec6f88c..f1be5c5c85e 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -89,12 +89,12 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
#ifdef CONFIG_IPV6_ROUTE_INFO
static struct rt6_info *rt6_add_route_info(struct net *net,
- struct in6_addr *prefix, int prefixlen,
- struct in6_addr *gwaddr, int ifindex,
+ const struct in6_addr *prefix, int prefixlen,
+ const struct in6_addr *gwaddr, int ifindex,
unsigned pref);
static struct rt6_info *rt6_get_route_info(struct net *net,
- struct in6_addr *prefix, int prefixlen,
- struct in6_addr *gwaddr, int ifindex);
+ const struct in6_addr *prefix, int prefixlen,
+ const struct in6_addr *gwaddr, int ifindex);
#endif
static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
@@ -227,9 +227,14 @@ static struct rt6_info ip6_blk_hole_entry_template = {
#endif
/* allocate dst with ip6_dst_ops */
-static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops)
+static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops,
+ struct net_device *dev)
{
- return (struct rt6_info *)dst_alloc(ops, 0);
+ struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, 0);
+
+ memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry));
+
+ return rt;
}
static void ip6_dst_destroy(struct dst_entry *dst)
@@ -290,7 +295,7 @@ static __inline__ int rt6_check_expired(const struct rt6_info *rt)
time_after(jiffies, rt->rt6i_expires);
}
-static inline int rt6_need_strict(struct in6_addr *daddr)
+static inline int rt6_need_strict(const struct in6_addr *daddr)
{
return ipv6_addr_type(daddr) &
(IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
@@ -302,7 +307,7 @@ static inline int rt6_need_strict(struct in6_addr *daddr)
static inline struct rt6_info *rt6_device_match(struct net *net,
struct rt6_info *rt,
- struct in6_addr *saddr,
+ const struct in6_addr *saddr,
int oif,
int flags)
{
@@ -514,7 +519,7 @@ static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict)
#ifdef CONFIG_IPV6_ROUTE_INFO
int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
- struct in6_addr *gwaddr)
+ const struct in6_addr *gwaddr)
{
struct net *net = dev_net(dev);
struct route_info *rinfo = (struct route_info *) opt;
@@ -677,8 +682,8 @@ int ip6_ins_rt(struct rt6_info *rt)
return __ip6_ins_rt(rt, &info);
}
-static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *daddr,
- struct in6_addr *saddr)
+static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_addr *daddr,
+ const struct in6_addr *saddr)
{
struct rt6_info *rt;
@@ -746,7 +751,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *dad
return rt;
}
-static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *daddr)
+static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, const struct in6_addr *daddr)
{
struct rt6_info *rt = ip6_rt_copy(ort);
if (rt) {
@@ -837,7 +842,7 @@ static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *
void ip6_route_input(struct sk_buff *skb)
{
- struct ipv6hdr *iph = ipv6_hdr(skb);
+ const struct ipv6hdr *iph = ipv6_hdr(skb);
struct net *net = dev_net(skb->dev);
int flags = RT6_LOOKUP_F_HAS_SADDR;
struct flowi6 fl6 = {
@@ -881,11 +886,13 @@ EXPORT_SYMBOL(ip6_route_output);
struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig)
{
- struct rt6_info *rt = dst_alloc(&ip6_dst_blackhole_ops, 1);
- struct rt6_info *ort = (struct rt6_info *) dst_orig;
+ struct rt6_info *rt, *ort = (struct rt6_info *) dst_orig;
struct dst_entry *new = NULL;
+ rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, 0, 0);
if (rt) {
+ memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry));
+
new = &rt->dst;
new->__use = 1;
@@ -893,9 +900,6 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
new->output = dst_discard;
dst_copy_metrics(new, &ort->dst);
- new->dev = ort->dst.dev;
- if (new->dev)
- dev_hold(new->dev);
rt->rt6i_idev = ort->rt6i_idev;
if (rt->rt6i_idev)
in6_dev_hold(rt->rt6i_idev);
@@ -1038,13 +1042,12 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
if (unlikely(idev == NULL))
return NULL;
- rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
+ rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev);
if (unlikely(rt == NULL)) {
in6_dev_put(idev);
goto out;
}
- dev_hold(dev);
if (neigh)
neigh_hold(neigh);
else {
@@ -1053,7 +1056,6 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
neigh = NULL;
}
- rt->rt6i_dev = dev;
rt->rt6i_idev = idev;
rt->rt6i_nexthop = neigh;
atomic_set(&rt->dst.__refcnt, 1);
@@ -1212,7 +1214,7 @@ int ip6_route_add(struct fib6_config *cfg)
goto out;
}
- rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
+ rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL);
if (rt == NULL) {
err = -ENOMEM;
@@ -1279,7 +1281,7 @@ int ip6_route_add(struct fib6_config *cfg)
}
if (cfg->fc_flags & RTF_GATEWAY) {
- struct in6_addr *gw_addr;
+ const struct in6_addr *gw_addr;
int gwa_type;
gw_addr = &cfg->fc_gateway;
@@ -1332,6 +1334,16 @@ int ip6_route_add(struct fib6_config *cfg)
if (dev == NULL)
goto out;
+ if (!ipv6_addr_any(&cfg->fc_prefsrc)) {
+ if (!ipv6_chk_addr(net, &cfg->fc_prefsrc, dev, 0)) {
+ err = -EINVAL;
+ goto out;
+ }
+ ipv6_addr_copy(&rt->rt6i_prefsrc.addr, &cfg->fc_prefsrc);
+ rt->rt6i_prefsrc.plen = 128;
+ } else
+ rt->rt6i_prefsrc.plen = 0;
+
if (cfg->fc_flags & (RTF_GATEWAY | RTF_NONEXTHOP)) {
rt->rt6i_nexthop = __neigh_lookup_errno(&nd_tbl, &rt->rt6i_gateway, dev);
if (IS_ERR(rt->rt6i_nexthop)) {
@@ -1509,9 +1521,9 @@ out:
return rt;
};
-static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
- struct in6_addr *src,
- struct in6_addr *gateway,
+static struct rt6_info *ip6_route_redirect(const struct in6_addr *dest,
+ const struct in6_addr *src,
+ const struct in6_addr *gateway,
struct net_device *dev)
{
int flags = RT6_LOOKUP_F_HAS_SADDR;
@@ -1533,8 +1545,8 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
flags, __ip6_route_redirect);
}
-void rt6_redirect(struct in6_addr *dest, struct in6_addr *src,
- struct in6_addr *saddr,
+void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src,
+ const struct in6_addr *saddr,
struct neighbour *neigh, u8 *lladdr, int on_link)
{
struct rt6_info *rt, *nrt = NULL;
@@ -1608,7 +1620,7 @@ out:
* i.e. Path MTU discovery
*/
-static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr,
+static void rt6_do_pmtu_disc(const struct in6_addr *daddr, const struct in6_addr *saddr,
struct net *net, u32 pmtu, int ifindex)
{
struct rt6_info *rt, *nrt;
@@ -1693,7 +1705,7 @@ out:
dst_release(&rt->dst);
}
-void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
+void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *saddr,
struct net_device *dev, u32 pmtu)
{
struct net *net = dev_net(dev);
@@ -1721,7 +1733,8 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
{
struct net *net = dev_net(ort->rt6i_dev);
- struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
+ struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
+ ort->dst.dev);
if (rt) {
rt->dst.input = ort->dst.input;
@@ -1729,9 +1742,6 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
dst_copy_metrics(&rt->dst, &ort->dst);
rt->dst.error = ort->dst.error;
- rt->dst.dev = ort->dst.dev;
- if (rt->dst.dev)
- dev_hold(rt->dst.dev);
rt->rt6i_idev = ort->rt6i_idev;
if (rt->rt6i_idev)
in6_dev_hold(rt->rt6i_idev);
@@ -1753,8 +1763,8 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
#ifdef CONFIG_IPV6_ROUTE_INFO
static struct rt6_info *rt6_get_route_info(struct net *net,
- struct in6_addr *prefix, int prefixlen,
- struct in6_addr *gwaddr, int ifindex)
+ const struct in6_addr *prefix, int prefixlen,
+ const struct in6_addr *gwaddr, int ifindex)
{
struct fib6_node *fn;
struct rt6_info *rt = NULL;
@@ -1785,8 +1795,8 @@ out:
}
static struct rt6_info *rt6_add_route_info(struct net *net,
- struct in6_addr *prefix, int prefixlen,
- struct in6_addr *gwaddr, int ifindex,
+ const struct in6_addr *prefix, int prefixlen,
+ const struct in6_addr *gwaddr, int ifindex,
unsigned pref)
{
struct fib6_config cfg = {
@@ -1814,7 +1824,7 @@ static struct rt6_info *rt6_add_route_info(struct net *net,
}
#endif
-struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *dev)
+struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct net_device *dev)
{
struct rt6_info *rt;
struct fib6_table *table;
@@ -1836,7 +1846,7 @@ struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *d
return rt;
}
-struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr,
+struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr,
struct net_device *dev,
unsigned int pref)
{
@@ -2001,7 +2011,8 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
int anycast)
{
struct net *net = dev_net(idev->dev);
- struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
+ struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
+ net->loopback_dev);
struct neighbour *neigh;
if (rt == NULL) {
@@ -2011,13 +2022,11 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
return ERR_PTR(-ENOMEM);
}
- dev_hold(net->loopback_dev);
in6_dev_hold(idev);
rt->dst.flags = DST_HOST;
rt->dst.input = ip6_input;
rt->dst.output = ip6_output;
- rt->rt6i_dev = net->loopback_dev;
rt->rt6i_idev = idev;
rt->dst.obsolete = -1;
@@ -2043,6 +2052,55 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
return rt;
}
+int ip6_route_get_saddr(struct net *net,
+ struct rt6_info *rt,
+ const struct in6_addr *daddr,
+ unsigned int prefs,
+ struct in6_addr *saddr)
+{
+ struct inet6_dev *idev = ip6_dst_idev((struct dst_entry*)rt);
+ int err = 0;
+ if (rt->rt6i_prefsrc.plen)
+ ipv6_addr_copy(saddr, &rt->rt6i_prefsrc.addr);
+ else
+ err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
+ daddr, prefs, saddr);
+ return err;
+}
+
+/* remove deleted ip from prefsrc entries */
+struct arg_dev_net_ip {
+ struct net_device *dev;
+ struct net *net;
+ struct in6_addr *addr;
+};
+
+static int fib6_remove_prefsrc(struct rt6_info *rt, void *arg)
+{
+ struct net_device *dev = ((struct arg_dev_net_ip *)arg)->dev;
+ struct net *net = ((struct arg_dev_net_ip *)arg)->net;
+ struct in6_addr *addr = ((struct arg_dev_net_ip *)arg)->addr;
+
+ if (((void *)rt->rt6i_dev == dev || dev == NULL) &&
+ rt != net->ipv6.ip6_null_entry &&
+ ipv6_addr_equal(addr, &rt->rt6i_prefsrc.addr)) {
+ /* remove prefsrc entry */
+ rt->rt6i_prefsrc.plen = 0;
+ }
+ return 0;
+}
+
+void rt6_remove_prefsrc(struct inet6_ifaddr *ifp)
+{
+ struct net *net = dev_net(ifp->idev->dev);
+ struct arg_dev_net_ip adni = {
+ .dev = ifp->idev->dev,
+ .net = net,
+ .addr = &ifp->addr,
+ };
+ fib6_clean_all(net, fib6_remove_prefsrc, 0, &adni);
+}
+
struct arg_dev_net {
struct net_device *dev;
struct net *net;
@@ -2189,6 +2247,9 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
nla_memcpy(&cfg->fc_src, tb[RTA_SRC], plen);
}
+ if (tb[RTA_PREFSRC])
+ nla_memcpy(&cfg->fc_prefsrc, tb[RTA_PREFSRC], 16);
+
if (tb[RTA_OIF])
cfg->fc_ifindex = nla_get_u32(tb[RTA_OIF]);
@@ -2331,13 +2392,17 @@ static int rt6_fill_node(struct net *net,
#endif
NLA_PUT_U32(skb, RTA_IIF, iif);
} else if (dst) {
- struct inet6_dev *idev = ip6_dst_idev(&rt->dst);
struct in6_addr saddr_buf;
- if (ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
- dst, 0, &saddr_buf) == 0)
+ if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf) == 0)
NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
}
+ if (rt->rt6i_prefsrc.plen) {
+ struct in6_addr saddr_buf;
+ ipv6_addr_copy(&saddr_buf, &rt->rt6i_prefsrc.addr);
+ NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
+ }
+
if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
goto nla_put_failure;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 5f35d595e4a..1cca5761aea 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -250,11 +250,6 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
dev_net_set(dev, net);
- if (strchr(name, '%')) {
- if (dev_alloc_name(dev, name) < 0)
- goto failed_free;
- }
-
nt = netdev_priv(dev);
nt->parms = *parms;
@@ -447,7 +442,7 @@ out:
}
static int
-isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
+isatap_chksrc(struct sk_buff *skb, const struct iphdr *iph, struct ip_tunnel *t)
{
struct ip_tunnel_prl_entry *p;
int ok = 1;
@@ -460,7 +455,8 @@ isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
else
skb->ndisc_nodetype = NDISC_NODETYPE_NODEFAULT;
} else {
- struct in6_addr *addr6 = &ipv6_hdr(skb)->saddr;
+ const struct in6_addr *addr6 = &ipv6_hdr(skb)->saddr;
+
if (ipv6_addr_is_isatap(addr6) &&
(addr6->s6_addr32[3] == iph->saddr) &&
ipv6_chk_prefix(addr6, t->dev))
@@ -494,7 +490,7 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
8 bytes of packet payload. It means, that precise relaying of
ICMP in the real Internet is absolutely infeasible.
*/
- struct iphdr *iph = (struct iphdr*)skb->data;
+ const struct iphdr *iph = (const struct iphdr *)skb->data;
const int type = icmp_hdr(skb)->type;
const int code = icmp_hdr(skb)->code;
struct ip_tunnel *t;
@@ -552,7 +548,7 @@ out:
return err;
}
-static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
+static inline void ipip6_ecn_decapsulate(const struct iphdr *iph, struct sk_buff *skb)
{
if (INET_ECN_is_ce(iph->tos))
IP6_ECN_set_ce(ipv6_hdr(skb));
@@ -560,7 +556,7 @@ static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
static int ipip6_rcv(struct sk_buff *skb)
{
- struct iphdr *iph;
+ const struct iphdr *iph;
struct ip_tunnel *tunnel;
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
@@ -616,7 +612,7 @@ out:
* comes from 6rd / 6to4 (RFC 3056) addr space.
*/
static inline
-__be32 try_6rd(struct in6_addr *v6dst, struct ip_tunnel *tunnel)
+__be32 try_6rd(const struct in6_addr *v6dst, struct ip_tunnel *tunnel)
{
__be32 dst = 0;
@@ -659,8 +655,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
{
struct ip_tunnel *tunnel = netdev_priv(dev);
struct pcpu_tstats *tstats;
- struct iphdr *tiph = &tunnel->parms.iph;
- struct ipv6hdr *iph6 = ipv6_hdr(skb);
+ const struct iphdr *tiph = &tunnel->parms.iph;
+ const struct ipv6hdr *iph6 = ipv6_hdr(skb);
u8 tos = tunnel->parms.iph.tos;
__be16 df = tiph->frag_off;
struct rtable *rt; /* Route to the other host */
@@ -668,8 +664,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
struct iphdr *iph; /* Our new IP header */
unsigned int max_headroom; /* The extra header space needed */
__be32 dst = tiph->daddr;
+ struct flowi4 fl4;
int mtu;
- struct in6_addr *addr6;
+ const struct in6_addr *addr6;
int addr_type;
if (skb->protocol != htons(ETH_P_IPV6))
@@ -688,7 +685,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
goto tx_error;
}
- addr6 = (struct in6_addr*)&neigh->primary_key;
+ addr6 = (const struct in6_addr*)&neigh->primary_key;
addr_type = ipv6_addr_type(addr6);
if ((addr_type & IPV6_ADDR_UNICAST) &&
@@ -713,7 +710,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
goto tx_error;
}
- addr6 = (struct in6_addr*)&neigh->primary_key;
+ addr6 = (const struct in6_addr*)&neigh->primary_key;
addr_type = ipv6_addr_type(addr6);
if (addr_type == IPV6_ADDR_ANY) {
@@ -727,7 +724,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
dst = addr6->s6_addr32[3];
}
- rt = ip_route_output_ports(dev_net(dev), NULL,
+ rt = ip_route_output_ports(dev_net(dev), &fl4, NULL,
dst, tiph->saddr,
0, 0,
IPPROTO_IPV6, RT_TOS(tos),
@@ -821,8 +818,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
iph->frag_off = df;
iph->protocol = IPPROTO_IPV6;
iph->tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6));
- iph->daddr = rt->rt_dst;
- iph->saddr = rt->rt_src;
+ iph->daddr = fl4.daddr;
+ iph->saddr = fl4.saddr;
if ((iph->ttl = tiph->ttl) == 0)
iph->ttl = iph6->hop_limit;
@@ -844,13 +841,14 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
{
struct net_device *tdev = NULL;
struct ip_tunnel *tunnel;
- struct iphdr *iph;
+ const struct iphdr *iph;
+ struct flowi4 fl4;
tunnel = netdev_priv(dev);
iph = &tunnel->parms.iph;
if (iph->daddr) {
- struct rtable *rt = ip_route_output_ports(dev_net(dev), NULL,
+ struct rtable *rt = ip_route_output_ports(dev_net(dev), &fl4, NULL,
iph->daddr, iph->saddr,
0, 0,
IPPROTO_IPV6,
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 352c26081f5..8b9644a8b69 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -66,7 +66,7 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS],
ipv6_cookie_scratch);
-static u32 cookie_hash(struct in6_addr *saddr, struct in6_addr *daddr,
+static u32 cookie_hash(const struct in6_addr *saddr, const struct in6_addr *daddr,
__be16 sport, __be16 dport, u32 count, int c)
{
__u32 *tmp = __get_cpu_var(ipv6_cookie_scratch);
@@ -86,7 +86,8 @@ static u32 cookie_hash(struct in6_addr *saddr, struct in6_addr *daddr,
return tmp[17];
}
-static __u32 secure_tcp_syn_cookie(struct in6_addr *saddr, struct in6_addr *daddr,
+static __u32 secure_tcp_syn_cookie(const struct in6_addr *saddr,
+ const struct in6_addr *daddr,
__be16 sport, __be16 dport, __u32 sseq,
__u32 count, __u32 data)
{
@@ -96,8 +97,8 @@ static __u32 secure_tcp_syn_cookie(struct in6_addr *saddr, struct in6_addr *dadd
& COOKIEMASK));
}
-static __u32 check_tcp_syn_cookie(__u32 cookie, struct in6_addr *saddr,
- struct in6_addr *daddr, __be16 sport,
+static __u32 check_tcp_syn_cookie(__u32 cookie, const struct in6_addr *saddr,
+ const struct in6_addr *daddr, __be16 sport,
__be16 dport, __u32 sseq, __u32 count,
__u32 maxdiff)
{
@@ -116,7 +117,7 @@ static __u32 check_tcp_syn_cookie(__u32 cookie, struct in6_addr *saddr,
__u32 cookie_v6_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
{
- struct ipv6hdr *iph = ipv6_hdr(skb);
+ const struct ipv6hdr *iph = ipv6_hdr(skb);
const struct tcphdr *th = tcp_hdr(skb);
int mssind;
const __u16 mss = *mssp;
@@ -138,7 +139,7 @@ __u32 cookie_v6_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
static inline int cookie_check(struct sk_buff *skb, __u32 cookie)
{
- struct ipv6hdr *iph = ipv6_hdr(skb);
+ const struct ipv6hdr *iph = ipv6_hdr(skb);
const struct tcphdr *th = tcp_hdr(skb);
__u32 seq = ntohl(th->seq) - 1;
__u32 mssind = check_tcp_syn_cookie(cookie, &iph->saddr, &iph->daddr,
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 4f49e5dd41b..868366470b4 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -76,8 +76,8 @@ static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
static void __tcp_v6_send_check(struct sk_buff *skb,
- struct in6_addr *saddr,
- struct in6_addr *daddr);
+ const struct in6_addr *saddr,
+ const struct in6_addr *daddr);
static const struct inet_connection_sock_af_ops ipv6_mapped;
static const struct inet_connection_sock_af_ops ipv6_specific;
@@ -86,7 +86,7 @@ static const struct tcp_sock_af_ops tcp_sock_ipv6_specific;
static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific;
#else
static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
- struct in6_addr *addr)
+ const struct in6_addr *addr)
{
return NULL;
}
@@ -106,8 +106,8 @@ static void tcp_v6_hash(struct sock *sk)
}
static __inline__ __sum16 tcp_v6_check(int len,
- struct in6_addr *saddr,
- struct in6_addr *daddr,
+ const struct in6_addr *saddr,
+ const struct in6_addr *daddr,
__wsum base)
{
return csum_ipv6_magic(saddr, daddr, len, IPPROTO_TCP, base);
@@ -331,7 +331,7 @@ failure:
static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
u8 type, u8 code, int offset, __be32 info)
{
- struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
+ const struct ipv6hdr *hdr = (const struct ipv6hdr*)skb->data;
const struct tcphdr *th = (struct tcphdr *)(skb->data+offset);
struct ipv6_pinfo *np;
struct sock *sk;
@@ -551,7 +551,7 @@ static void tcp_v6_reqsk_destructor(struct request_sock *req)
#ifdef CONFIG_TCP_MD5SIG
static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
- struct in6_addr *addr)
+ const struct in6_addr *addr)
{
struct tcp_sock *tp = tcp_sk(sk);
int i;
@@ -580,7 +580,7 @@ static struct tcp_md5sig_key *tcp_v6_reqsk_md5_lookup(struct sock *sk,
return tcp_v6_md5_do_lookup(sk, &inet6_rsk(req)->rmt_addr);
}
-static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer,
+static int tcp_v6_md5_do_add(struct sock *sk, const struct in6_addr *peer,
char *newkey, u8 newkeylen)
{
/* Add key to the list */
@@ -645,7 +645,7 @@ static int tcp_v6_md5_add_func(struct sock *sk, struct sock *addr_sk,
newkey, newkeylen);
}
-static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer)
+static int tcp_v6_md5_do_del(struct sock *sk, const struct in6_addr *peer)
{
struct tcp_sock *tp = tcp_sk(sk);
int i;
@@ -753,8 +753,8 @@ static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval,
}
static int tcp_v6_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp,
- struct in6_addr *daddr,
- struct in6_addr *saddr, int nbytes)
+ const struct in6_addr *daddr,
+ const struct in6_addr *saddr, int nbytes)
{
struct tcp6_pseudohdr *bp;
struct scatterlist sg;
@@ -771,7 +771,7 @@ static int tcp_v6_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp,
}
static int tcp_v6_md5_hash_hdr(char *md5_hash, struct tcp_md5sig_key *key,
- struct in6_addr *daddr, struct in6_addr *saddr,
+ const struct in6_addr *daddr, struct in6_addr *saddr,
struct tcphdr *th)
{
struct tcp_md5sig_pool *hp;
@@ -807,7 +807,7 @@ static int tcp_v6_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key,
struct sock *sk, struct request_sock *req,
struct sk_buff *skb)
{
- struct in6_addr *saddr, *daddr;
+ const struct in6_addr *saddr, *daddr;
struct tcp_md5sig_pool *hp;
struct hash_desc *desc;
struct tcphdr *th = tcp_hdr(skb);
@@ -819,7 +819,7 @@ static int tcp_v6_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key,
saddr = &inet6_rsk(req)->loc_addr;
daddr = &inet6_rsk(req)->rmt_addr;
} else {
- struct ipv6hdr *ip6h = ipv6_hdr(skb);
+ const struct ipv6hdr *ip6h = ipv6_hdr(skb);
saddr = &ip6h->saddr;
daddr = &ip6h->daddr;
}
@@ -857,7 +857,7 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
{
__u8 *hash_location = NULL;
struct tcp_md5sig_key *hash_expected;
- struct ipv6hdr *ip6h = ipv6_hdr(skb);
+ const struct ipv6hdr *ip6h = ipv6_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
int genhash;
u8 newhash[16];
@@ -915,7 +915,7 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
#endif
static void __tcp_v6_send_check(struct sk_buff *skb,
- struct in6_addr *saddr, struct in6_addr *daddr)
+ const struct in6_addr *saddr, const struct in6_addr *daddr)
{
struct tcphdr *th = tcp_hdr(skb);
@@ -939,7 +939,7 @@ static void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb)
static int tcp_v6_gso_send_check(struct sk_buff *skb)
{
- struct ipv6hdr *ipv6h;
+ const struct ipv6hdr *ipv6h;
struct tcphdr *th;
if (!pskb_may_pull(skb, sizeof(*th)))
@@ -957,7 +957,7 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb)
static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
struct sk_buff *skb)
{
- struct ipv6hdr *iph = skb_gro_network_header(skb);
+ const struct ipv6hdr *iph = skb_gro_network_header(skb);
switch (skb->ip_summed) {
case CHECKSUM_COMPLETE:
@@ -978,7 +978,7 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
static int tcp6_gro_complete(struct sk_buff *skb)
{
- struct ipv6hdr *iph = ipv6_hdr(skb);
+ const struct ipv6hdr *iph = ipv6_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
th->check = ~tcp_v6_check(skb->len - skb_transport_offset(skb),
@@ -1469,7 +1469,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
First: no IPv4 options.
*/
- newinet->opt = NULL;
+ newinet->inet_opt = NULL;
newnp->ipv6_fl_list = NULL;
/* Clone RX bits */
@@ -1702,7 +1702,7 @@ ipv6_pktoptions:
static int tcp_v6_rcv(struct sk_buff *skb)
{
struct tcphdr *th;
- struct ipv6hdr *hdr;
+ const struct ipv6hdr *hdr;
struct sock *sk;
int ret;
struct net *net = dev_net(skb->dev);
@@ -2028,8 +2028,8 @@ static void get_openreq6(struct seq_file *seq,
struct sock *sk, struct request_sock *req, int i, int uid)
{
int ttd = req->expires - jiffies;
- struct in6_addr *src = &inet6_rsk(req)->loc_addr;
- struct in6_addr *dest = &inet6_rsk(req)->rmt_addr;
+ const struct in6_addr *src = &inet6_rsk(req)->loc_addr;
+ const struct in6_addr *dest = &inet6_rsk(req)->rmt_addr;
if (ttd < 0)
ttd = 0;
@@ -2057,7 +2057,7 @@ static void get_openreq6(struct seq_file *seq,
static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
{
- struct in6_addr *dest, *src;
+ const struct in6_addr *dest, *src;
__u16 destp, srcp;
int timer_active;
unsigned long timer_expires;
@@ -2114,7 +2114,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
static void get_timewait6_sock(struct seq_file *seq,
struct inet_timewait_sock *tw, int i)
{
- struct in6_addr *dest, *src;
+ const struct in6_addr *dest, *src;
__u16 destp, srcp;
struct inet6_timewait_sock *tw6 = inet6_twsk((struct sock *)tw);
int ttd = tw->tw_ttd - jiffies;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 9e305d74b3d..fc0c42a88e5 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -311,7 +311,7 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
struct udp_table *udptable)
{
struct sock *sk;
- struct ipv6hdr *iph = ipv6_hdr(skb);
+ const struct ipv6hdr *iph = ipv6_hdr(skb);
if (unlikely(sk = skb_steal_sock(skb)))
return sk;
@@ -463,9 +463,9 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
struct udp_table *udptable)
{
struct ipv6_pinfo *np;
- struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
- struct in6_addr *saddr = &hdr->saddr;
- struct in6_addr *daddr = &hdr->daddr;
+ const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
+ const struct in6_addr *saddr = &hdr->saddr;
+ const struct in6_addr *daddr = &hdr->daddr;
struct udphdr *uh = (struct udphdr*)(skb->data+offset);
struct sock *sk;
int err;
@@ -553,8 +553,8 @@ drop_no_sk_drops_inc:
}
static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk,
- __be16 loc_port, struct in6_addr *loc_addr,
- __be16 rmt_port, struct in6_addr *rmt_addr,
+ __be16 loc_port, const struct in6_addr *loc_addr,
+ __be16 rmt_port, const struct in6_addr *rmt_addr,
int dif)
{
struct hlist_nulls_node *node;
@@ -633,7 +633,7 @@ drop:
* so we don't need to lock the hashes.
*/
static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
- struct in6_addr *saddr, struct in6_addr *daddr,
+ const struct in6_addr *saddr, const struct in6_addr *daddr,
struct udp_table *udptable)
{
struct sock *sk, *stack[256 / sizeof(struct sock *)];
@@ -716,7 +716,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
struct net *net = dev_net(skb->dev);
struct sock *sk;
struct udphdr *uh;
- struct in6_addr *saddr, *daddr;
+ const struct in6_addr *saddr, *daddr;
u32 ulen = 0;
if (!pskb_may_pull(skb, sizeof(struct udphdr)))
@@ -1278,7 +1278,7 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
static int udp6_ufo_send_check(struct sk_buff *skb)
{
- struct ipv6hdr *ipv6h;
+ const struct ipv6hdr *ipv6h;
struct udphdr *uh;
if (!pskb_may_pull(skb, sizeof(*uh)))
@@ -1328,7 +1328,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, u32 features)
/* Do software UFO. Complete and fill in the UDP checksum as HW cannot
* do checksum of UDP packets sent as multiple IP fragments.
*/
- offset = skb->csum_start - skb_headroom(skb);
+ offset = skb_checksum_start_offset(skb);
csum = skb_checksum(skb, offset, skb->len- offset, 0);
offset += skb->csum_offset;
*(__sum16 *)(skb->data + offset) = csum_fold(csum);
@@ -1382,7 +1382,7 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket
{
struct inet_sock *inet = inet_sk(sp);
struct ipv6_pinfo *np = inet6_sk(sp);
- struct in6_addr *dest, *src;
+ const struct in6_addr *dest, *src;
__u16 destp, srcp;
dest = &np->daddr;
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index bbd48b101ba..3437d7d4eed 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -41,10 +41,8 @@ static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
{
struct ipv6hdr *top_iph;
struct ip_beet_phdr *ph;
- struct iphdr *iphv4;
int optlen, hdr_len;
- iphv4 = ip_hdr(skb);
hdr_len = 0;
optlen = XFRM_MODE_SKB_CB(skb)->optlen;
if (unlikely(optlen))
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 645cb968d45..4d6edff0498 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -20,7 +20,7 @@
static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
{
- struct ipv6hdr *outer_iph = ipv6_hdr(skb);
+ const struct ipv6hdr *outer_iph = ipv6_hdr(skb);
struct ipv6hdr *inner_iph = ipipv6_hdr(skb);
if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph)))
@@ -55,8 +55,8 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
dsfield &= ~INET_ECN_MASK;
ipv6_change_dsfield(top_iph, 0, dsfield);
top_iph->hop_limit = ip6_dst_hoplimit(dst->child);
- ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
- ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
+ ipv6_addr_copy(&top_iph->saddr, (const struct in6_addr *)&x->props.saddr);
+ ipv6_addr_copy(&top_iph->daddr, (const struct in6_addr *)&x->id.daddr);
return 0;
}
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 05e34c8ec91..d879f7efbd1 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -124,7 +124,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
struct flowi6 *fl6 = &fl->u.ip6;
int onlyproto = 0;
u16 offset = skb_network_header_len(skb);
- struct ipv6hdr *hdr = ipv6_hdr(skb);
+ const struct ipv6hdr *hdr = ipv6_hdr(skb);
struct ipv6_opt_hdr *exthdr;
const unsigned char *nh = skb_network_header(skb);
u8 nexthdr = nh[IP6CB(skb)->nhoff];
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 2969cad408d..a6770a04e3b 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -68,7 +68,7 @@ static DEFINE_SPINLOCK(xfrm6_tunnel_spi_lock);
static struct kmem_cache *xfrm6_tunnel_spi_kmem __read_mostly;
-static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
+static inline unsigned xfrm6_tunnel_spi_hash_byaddr(const xfrm_address_t *addr)
{
unsigned h;
@@ -85,7 +85,7 @@ static inline unsigned xfrm6_tunnel_spi_hash_byspi(u32 spi)
return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE;
}
-static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr)
+static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr)
{
struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
struct xfrm6_tunnel_spi *x6spi;
@@ -101,7 +101,7 @@ static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(struct net *net, xfrm_
return NULL;
}
-__be32 xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr)
+__be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr)
{
struct xfrm6_tunnel_spi *x6spi;
u32 spi;
@@ -237,10 +237,10 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
static int xfrm6_tunnel_rcv(struct sk_buff *skb)
{
struct net *net = dev_net(skb->dev);
- struct ipv6hdr *iph = ipv6_hdr(skb);
+ const struct ipv6hdr *iph = ipv6_hdr(skb);
__be32 spi;
- spi = xfrm6_tunnel_spi_lookup(net, (xfrm_address_t *)&iph->saddr);
+ spi = xfrm6_tunnel_spi_lookup(net, (const xfrm_address_t *)&iph->saddr);
return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi) > 0 ? : 0;
}
diff --git a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c
index e97082017f4..52079f19bbb 100644
--- a/net/irda/ircomm/ircomm_core.c
+++ b/net/irda/ircomm/ircomm_core.c
@@ -244,14 +244,8 @@ EXPORT_SYMBOL(ircomm_connect_request);
void ircomm_connect_indication(struct ircomm_cb *self, struct sk_buff *skb,
struct ircomm_info *info)
{
- int clen = 0;
-
IRDA_DEBUG(2, "%s()\n", __func__ );
- /* Check if the packet contains data on the control channel */
- if (skb->len > 0)
- clen = skb->data[0];
-
/*
* If there are any data hiding in the control channel, we must
* deliver it first. The side effect is that the control channel
diff --git a/net/irda/ircomm/ircomm_lmp.c b/net/irda/ircomm/ircomm_lmp.c
index 08fb54dc8c4..3b8095c771d 100644
--- a/net/irda/ircomm/ircomm_lmp.c
+++ b/net/irda/ircomm/ircomm_lmp.c
@@ -75,7 +75,6 @@ static int ircomm_lmp_connect_response(struct ircomm_cb *self,
struct sk_buff *userdata)
{
struct sk_buff *tx_skb;
- int ret;
IRDA_DEBUG(0, "%s()\n", __func__ );
@@ -100,9 +99,7 @@ static int ircomm_lmp_connect_response(struct ircomm_cb *self,
tx_skb = userdata;
}
- ret = irlmp_connect_response(self->lsap, tx_skb);
-
- return 0;
+ return irlmp_connect_response(self->lsap, tx_skb);
}
static int ircomm_lmp_disconnect_request(struct ircomm_cb *self,
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index a39cca8331d..b3cc8b3989a 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -38,6 +38,7 @@
#include <linux/seq_file.h>
#include <linux/termios.h>
#include <linux/tty.h>
+#include <linux/tty_flip.h>
#include <linux/interrupt.h>
#include <linux/device.h> /* for MODULE_ALIAS_CHARDEV_MAJOR */
@@ -1132,7 +1133,6 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
struct sk_buff *skb)
{
struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
- struct tty_ldisc *ld;
IRDA_DEBUG(2, "%s()\n", __func__ );
@@ -1161,15 +1161,11 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
}
/*
- * Just give it over to the line discipline. There is no need to
- * involve the flip buffers, since we are not running in an interrupt
- * handler
+ * Use flip buffer functions since the code may be called from interrupt
+ * context
*/
-
- ld = tty_ldisc_ref(self->tty);
- if (ld)
- ld->ops->receive_buf(self->tty, skb->data, NULL, skb->len);
- tty_ldisc_deref(ld);
+ tty_insert_flip_string(self->tty, skb->data, skb->len);
+ tty_flip_buffer_push(self->tty);
/* No need to kfree_skb - see ircomm_ttp_data_indication() */
diff --git a/net/irda/irlan/irlan_filter.c b/net/irda/irlan/irlan_filter.c
index 9ff7823abec..7977be7caf0 100644
--- a/net/irda/irlan/irlan_filter.c
+++ b/net/irda/irlan/irlan_filter.c
@@ -143,12 +143,8 @@ void irlan_filter_request(struct irlan_cb *self, struct sk_buff *skb)
*/
void irlan_check_command_param(struct irlan_cb *self, char *param, char *value)
{
- __u8 *bytes;
-
IRDA_DEBUG(4, "%s()\n", __func__ );
- bytes = value;
-
IRDA_ASSERT(self != NULL, return;);
IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
diff --git a/net/irda/irlan/irlan_provider.c b/net/irda/irlan/irlan_provider.c
index 5cf5e6c872b..b8af74ab8b6 100644
--- a/net/irda/irlan/irlan_provider.c
+++ b/net/irda/irlan/irlan_provider.c
@@ -128,7 +128,6 @@ static void irlan_provider_connect_indication(void *instance, void *sap,
{
struct irlan_cb *self;
struct tsap_cb *tsap;
- __u32 saddr, daddr;
IRDA_DEBUG(0, "%s()\n", __func__ );
@@ -141,8 +140,6 @@ static void irlan_provider_connect_indication(void *instance, void *sap,
IRDA_ASSERT(tsap == self->provider.tsap_ctrl,return;);
IRDA_ASSERT(self->provider.state == IRLAN_IDLE, return;);
- daddr = irttp_get_daddr(tsap);
- saddr = irttp_get_saddr(tsap);
self->provider.max_sdu_size = max_sdu_size;
self->provider.max_header_size = max_header_size;
diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c
index bb47021c9a5..ccd214f9d19 100644
--- a/net/irda/irlap_event.c
+++ b/net/irda/irlap_event.c
@@ -2227,8 +2227,6 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event,
static int irlap_state_sclose(struct irlap_cb *self, IRLAP_EVENT event,
struct sk_buff *skb, struct irlap_info *info)
{
- int ret = 0;
-
IRDA_DEBUG(1, "%s()\n", __func__);
IRDA_ASSERT(self != NULL, return -ENODEV;);
@@ -2289,7 +2287,6 @@ static int irlap_state_sclose(struct irlap_cb *self, IRLAP_EVENT event,
IRDA_DEBUG(1, "%s(), Unknown event %d, (%s)\n", __func__,
event, irlap_event[event]);
- ret = -EINVAL;
break;
}
diff --git a/net/irda/irproc.c b/net/irda/irproc.c
index 318766e5dbd..b9ac598e211 100644
--- a/net/irda/irproc.c
+++ b/net/irda/irproc.c
@@ -65,15 +65,14 @@ static const struct irda_entry irda_dirs[] = {
void __init irda_proc_register(void)
{
int i;
- struct proc_dir_entry *d;
proc_irda = proc_mkdir("irda", init_net.proc_net);
if (proc_irda == NULL)
return;
for (i = 0; i < ARRAY_SIZE(irda_dirs); i++)
- d = proc_create(irda_dirs[i].name, 0, proc_irda,
- irda_dirs[i].fops);
+ (void) proc_create(irda_dirs[i].name, 0, proc_irda,
+ irda_dirs[i].fops);
}
/*
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 986b2a5e876..e2013e434d0 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -190,7 +190,6 @@ static int afiucv_pm_freeze(struct device *dev)
*/
static int afiucv_pm_restore_thaw(struct device *dev)
{
- struct iucv_sock *iucv;
struct sock *sk;
struct hlist_node *node;
@@ -199,7 +198,6 @@ static int afiucv_pm_restore_thaw(struct device *dev)
#endif
read_lock(&iucv_sk_list.lock);
sk_for_each(sk, node, &iucv_sk_list.head) {
- iucv = iucv_sk(sk);
switch (sk->sk_state) {
case IUCV_CONNECTED:
sk->sk_err = EPIPE;
@@ -381,7 +379,6 @@ static void iucv_sock_close(struct sock *sk)
{
unsigned char user_data[16];
struct iucv_sock *iucv = iucv_sk(sk);
- int err;
unsigned long timeo;
iucv_sock_clear_timer(sk);
@@ -394,8 +391,6 @@ static void iucv_sock_close(struct sock *sk)
case IUCV_CONNECTED:
case IUCV_DISCONN:
- err = 0;
-
sk->sk_state = IUCV_CLOSING;
sk->sk_state_change(sk);
@@ -404,7 +399,7 @@ static void iucv_sock_close(struct sock *sk)
timeo = sk->sk_lingertime;
else
timeo = IUCV_DISCONN_TIMEOUT;
- err = iucv_sock_wait(sk,
+ iucv_sock_wait(sk,
iucv_sock_in_state(sk, IUCV_CLOSED, 0),
timeo);
}
@@ -417,7 +412,7 @@ static void iucv_sock_close(struct sock *sk)
low_nmcpy(user_data, iucv->src_name);
high_nmcpy(user_data, iucv->dst_name);
ASCEBC(user_data, sizeof(user_data));
- err = iucv_path_sever(iucv->path, user_data);
+ iucv_path_sever(iucv->path, user_data);
iucv_path_free(iucv->path);
iucv->path = NULL;
}
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index 8f156bd86be..a15c0152495 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -128,8 +128,8 @@ struct iucv_irq_list {
};
static struct iucv_irq_data *iucv_irq_data[NR_CPUS];
-static cpumask_t iucv_buffer_cpumask = CPU_MASK_NONE;
-static cpumask_t iucv_irq_cpumask = CPU_MASK_NONE;
+static cpumask_t iucv_buffer_cpumask = { CPU_BITS_NONE };
+static cpumask_t iucv_irq_cpumask = { CPU_BITS_NONE };
/*
* Queue of interrupt buffers lock for delivery via the tasklet
@@ -406,7 +406,7 @@ static void iucv_allow_cpu(void *data)
parm->set_mask.ipmask = 0xf8;
iucv_call_b2f0(IUCV_SETCONTROLMASK, parm);
/* Set indication that iucv interrupts are allowed for this cpu. */
- cpu_set(cpu, iucv_irq_cpumask);
+ cpumask_set_cpu(cpu, &iucv_irq_cpumask);
}
/**
@@ -426,7 +426,7 @@ static void iucv_block_cpu(void *data)
iucv_call_b2f0(IUCV_SETMASK, parm);
/* Clear indication that iucv interrupts are allowed for this cpu. */
- cpu_clear(cpu, iucv_irq_cpumask);
+ cpumask_clear_cpu(cpu, &iucv_irq_cpumask);
}
/**
@@ -451,7 +451,7 @@ static void iucv_block_cpu_almost(void *data)
iucv_call_b2f0(IUCV_SETCONTROLMASK, parm);
/* Clear indication that iucv interrupts are allowed for this cpu. */
- cpu_clear(cpu, iucv_irq_cpumask);
+ cpumask_clear_cpu(cpu, &iucv_irq_cpumask);
}
/**
@@ -466,7 +466,7 @@ static void iucv_declare_cpu(void *data)
union iucv_param *parm;
int rc;
- if (cpu_isset(cpu, iucv_buffer_cpumask))
+ if (cpumask_test_cpu(cpu, &iucv_buffer_cpumask))
return;
/* Declare interrupt buffer. */
@@ -499,9 +499,9 @@ static void iucv_declare_cpu(void *data)
}
/* Set indication that an iucv buffer exists for this cpu. */
- cpu_set(cpu, iucv_buffer_cpumask);
+ cpumask_set_cpu(cpu, &iucv_buffer_cpumask);
- if (iucv_nonsmp_handler == 0 || cpus_empty(iucv_irq_cpumask))
+ if (iucv_nonsmp_handler == 0 || cpumask_empty(&iucv_irq_cpumask))
/* Enable iucv interrupts on this cpu. */
iucv_allow_cpu(NULL);
else
@@ -520,7 +520,7 @@ static void iucv_retrieve_cpu(void *data)
int cpu = smp_processor_id();
union iucv_param *parm;
- if (!cpu_isset(cpu, iucv_buffer_cpumask))
+ if (!cpumask_test_cpu(cpu, &iucv_buffer_cpumask))
return;
/* Block iucv interrupts. */
@@ -531,7 +531,7 @@ static void iucv_retrieve_cpu(void *data)
iucv_call_b2f0(IUCV_RETRIEVE_BUFFER, parm);
/* Clear indication that an iucv buffer exists for this cpu. */
- cpu_clear(cpu, iucv_buffer_cpumask);
+ cpumask_clear_cpu(cpu, &iucv_buffer_cpumask);
}
/**
@@ -546,8 +546,8 @@ static void iucv_setmask_mp(void)
get_online_cpus();
for_each_online_cpu(cpu)
/* Enable all cpus with a declared buffer. */
- if (cpu_isset(cpu, iucv_buffer_cpumask) &&
- !cpu_isset(cpu, iucv_irq_cpumask))
+ if (cpumask_test_cpu(cpu, &iucv_buffer_cpumask) &&
+ !cpumask_test_cpu(cpu, &iucv_irq_cpumask))
smp_call_function_single(cpu, iucv_allow_cpu,
NULL, 1);
put_online_cpus();
@@ -564,9 +564,9 @@ static void iucv_setmask_up(void)
int cpu;
/* Disable all cpu but the first in cpu_irq_cpumask. */
- cpumask = iucv_irq_cpumask;
- cpu_clear(first_cpu(iucv_irq_cpumask), cpumask);
- for_each_cpu_mask_nr(cpu, cpumask)
+ cpumask_copy(&cpumask, &iucv_irq_cpumask);
+ cpumask_clear_cpu(cpumask_first(&iucv_irq_cpumask), &cpumask);
+ for_each_cpu(cpu, &cpumask)
smp_call_function_single(cpu, iucv_block_cpu, NULL, 1);
}
@@ -593,7 +593,7 @@ static int iucv_enable(void)
rc = -EIO;
for_each_online_cpu(cpu)
smp_call_function_single(cpu, iucv_declare_cpu, NULL, 1);
- if (cpus_empty(iucv_buffer_cpumask))
+ if (cpumask_empty(&iucv_buffer_cpumask))
/* No cpu could declare an iucv buffer. */
goto out;
put_online_cpus();
@@ -675,15 +675,16 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self,
case CPU_DOWN_PREPARE_FROZEN:
if (!iucv_path_table)
break;
- cpumask = iucv_buffer_cpumask;
- cpu_clear(cpu, cpumask);
- if (cpus_empty(cpumask))
+ cpumask_copy(&cpumask, &iucv_buffer_cpumask);
+ cpumask_clear_cpu(cpu, &cpumask);
+ if (cpumask_empty(&cpumask))
/* Can't offline last IUCV enabled cpu. */
return notifier_from_errno(-EINVAL);
smp_call_function_single(cpu, iucv_retrieve_cpu, NULL, 1);
- if (cpus_empty(iucv_irq_cpumask))
- smp_call_function_single(first_cpu(iucv_buffer_cpumask),
- iucv_allow_cpu, NULL, 1);
+ if (cpumask_empty(&iucv_irq_cpumask))
+ smp_call_function_single(
+ cpumask_first(&iucv_buffer_cpumask),
+ iucv_allow_cpu, NULL, 1);
break;
}
return NOTIFY_OK;
@@ -828,14 +829,14 @@ EXPORT_SYMBOL(iucv_unregister);
static int iucv_reboot_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
- int i, rc;
+ int i;
get_online_cpus();
on_each_cpu(iucv_block_cpu, NULL, 1);
preempt_disable();
for (i = 0; i < iucv_max_pathid; i++) {
if (iucv_path_table[i])
- rc = iucv_sever_pathid(i, NULL);
+ iucv_sever_pathid(i, NULL);
}
preempt_enable();
put_online_cpus();
@@ -866,7 +867,7 @@ int iucv_path_accept(struct iucv_path *path, struct iucv_handler *handler,
int rc;
local_bh_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -915,7 +916,7 @@ int iucv_path_connect(struct iucv_path *path, struct iucv_handler *handler,
spin_lock_bh(&iucv_table_lock);
iucv_cleanup_queue();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -975,7 +976,7 @@ int iucv_path_quiesce(struct iucv_path *path, u8 userdata[16])
int rc;
local_bh_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1007,7 +1008,7 @@ int iucv_path_resume(struct iucv_path *path, u8 userdata[16])
int rc;
local_bh_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1036,7 +1037,7 @@ int iucv_path_sever(struct iucv_path *path, u8 userdata[16])
int rc;
preempt_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1070,7 +1071,7 @@ int iucv_message_purge(struct iucv_path *path, struct iucv_message *msg,
int rc;
local_bh_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1162,7 +1163,7 @@ int __iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
if (msg->flags & IUCV_IPRMDATA)
return iucv_message_receive_iprmdata(path, msg, flags,
buffer, size, residual);
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1235,7 +1236,7 @@ int iucv_message_reject(struct iucv_path *path, struct iucv_message *msg)
int rc;
local_bh_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1274,7 +1275,7 @@ int iucv_message_reply(struct iucv_path *path, struct iucv_message *msg,
int rc;
local_bh_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1324,7 +1325,7 @@ int __iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
union iucv_param *parm;
int rc;
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1411,7 +1412,7 @@ int iucv_message_send2way(struct iucv_path *path, struct iucv_message *msg,
int rc;
local_bh_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1888,7 +1889,7 @@ static int iucv_pm_freeze(struct device *dev)
printk(KERN_WARNING "iucv_pm_freeze\n");
#endif
if (iucv_pm_state != IUCV_PM_FREEZING) {
- for_each_cpu_mask_nr(cpu, iucv_irq_cpumask)
+ for_each_cpu(cpu, &iucv_irq_cpumask)
smp_call_function_single(cpu, iucv_block_cpu_almost,
NULL, 1);
cancel_work_sync(&iucv_work);
@@ -1928,7 +1929,7 @@ static int iucv_pm_thaw(struct device *dev)
if (rc)
goto out;
}
- if (cpus_empty(iucv_irq_cpumask)) {
+ if (cpumask_empty(&iucv_irq_cpumask)) {
if (iucv_nonsmp_handler)
/* enable interrupts on one cpu */
iucv_allow_cpu(NULL);
@@ -1961,7 +1962,7 @@ static int iucv_pm_restore(struct device *dev)
pr_warning("Suspending Linux did not completely close all IUCV "
"connections\n");
iucv_pm_state = IUCV_PM_RESTORING;
- if (cpus_empty(iucv_irq_cpumask)) {
+ if (cpumask_empty(&iucv_irq_cpumask)) {
rc = iucv_query_maxconn();
rc = iucv_enable();
if (rc)
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 7db86ffcf07..d62401c2568 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -712,7 +712,7 @@ static unsigned int pfkey_sockaddr_fill(const xfrm_address_t *xaddr, __be16 port
sin6->sin6_family = AF_INET6;
sin6->sin6_port = port;
sin6->sin6_flowinfo = 0;
- ipv6_addr_copy(&sin6->sin6_addr, (struct in6_addr *)xaddr->a6);
+ ipv6_addr_copy(&sin6->sin6_addr, (const struct in6_addr *)xaddr->a6);
sin6->sin6_scope_id = 0;
return 128;
}
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index c64ce0a0bb0..ed8a2335442 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -954,7 +954,7 @@ static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf)
}
static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
- size_t data_len)
+ struct flowi *fl, size_t data_len)
{
struct l2tp_tunnel *tunnel = session->tunnel;
unsigned int len = skb->len;
@@ -987,7 +987,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
/* Queue the packet to IP for output */
skb->local_df = 1;
- error = ip_queue_xmit(skb);
+ error = ip_queue_xmit(skb, fl);
/* Update stats */
if (error >= 0) {
@@ -1028,6 +1028,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
int data_len = skb->len;
struct l2tp_tunnel *tunnel = session->tunnel;
struct sock *sk = tunnel->sock;
+ struct flowi *fl;
struct udphdr *uh;
struct inet_sock *inet;
__wsum csum;
@@ -1060,14 +1061,21 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
IPSKB_REROUTED);
nf_reset(skb);
+ bh_lock_sock(sk);
+ if (sock_owned_by_user(sk)) {
+ dev_kfree_skb(skb);
+ goto out_unlock;
+ }
+
/* Get routing info from the tunnel socket */
skb_dst_drop(skb);
skb_dst_set(skb, dst_clone(__sk_dst_get(sk)));
+ inet = inet_sk(sk);
+ fl = &inet->cork.fl;
switch (tunnel->encap) {
case L2TP_ENCAPTYPE_UDP:
/* Setup UDP header */
- inet = inet_sk(sk);
__skb_push(skb, sizeof(*uh));
skb_reset_transport_header(skb);
uh = udp_hdr(skb);
@@ -1105,7 +1113,9 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
l2tp_skb_set_owner_w(skb, sk);
- l2tp_xmit_core(session, skb, data_len);
+ l2tp_xmit_core(session, skb, fl, data_len);
+out_unlock:
+ bh_unlock_sock(sk);
abort:
return 0;
@@ -1425,16 +1435,15 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
/* Add tunnel to our list */
INIT_LIST_HEAD(&tunnel->list);
- spin_lock_bh(&pn->l2tp_tunnel_list_lock);
- list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
- spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
- synchronize_rcu();
atomic_inc(&l2tp_tunnel_count);
/* Bump the reference count. The tunnel context is deleted
- * only when this drops to zero.
+ * only when this drops to zero. Must be done before list insertion
*/
l2tp_tunnel_inc_refcount(tunnel);
+ spin_lock_bh(&pn->l2tp_tunnel_list_lock);
+ list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
+ spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
err = 0;
err:
@@ -1626,7 +1635,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
hlist_add_head_rcu(&session->global_hlist,
l2tp_session_id_hash_2(pn, session_id));
spin_unlock_bh(&pn->l2tp_session_hlist_lock);
- synchronize_rcu();
}
/* Ignore management session in session count value */
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index 5c04f3e4270..b6466e71f5e 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -296,12 +296,12 @@ out_in_use:
static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
- int rc;
- struct inet_sock *inet = inet_sk(sk);
struct sockaddr_l2tpip *lsa = (struct sockaddr_l2tpip *) uaddr;
+ struct inet_sock *inet = inet_sk(sk);
+ struct flowi4 *fl4;
struct rtable *rt;
__be32 saddr;
- int oif;
+ int oif, rc;
rc = -EINVAL;
if (addr_len < sizeof(*lsa))
@@ -311,6 +311,8 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
if (lsa->l2tp_family != AF_INET)
goto out;
+ lock_sock(sk);
+
sk_dst_reset(sk);
oif = sk->sk_bound_dev_if;
@@ -320,7 +322,8 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
if (ipv4_is_multicast(lsa->l2tp_addr.s_addr))
goto out;
- rt = ip_route_connect(lsa->l2tp_addr.s_addr, saddr,
+ fl4 = &inet->cork.fl.u.ip4;
+ rt = ip_route_connect(fl4, lsa->l2tp_addr.s_addr, saddr,
RT_CONN_FLAGS(sk), oif,
IPPROTO_L2TP,
0, 0, sk, true);
@@ -340,10 +343,10 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
l2tp_ip_sk(sk)->peer_conn_id = lsa->l2tp_conn_id;
if (!inet->inet_saddr)
- inet->inet_saddr = rt->rt_src;
+ inet->inet_saddr = fl4->saddr;
if (!inet->inet_rcv_saddr)
- inet->inet_rcv_saddr = rt->rt_src;
- inet->inet_daddr = rt->rt_dst;
+ inet->inet_rcv_saddr = fl4->saddr;
+ inet->inet_daddr = fl4->daddr;
sk->sk_state = TCP_ESTABLISHED;
inet->inet_id = jiffies;
@@ -356,6 +359,7 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
rc = 0;
out:
+ release_sock(sk);
return rc;
}
@@ -416,23 +420,28 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
int rc;
struct l2tp_ip_sock *lsa = l2tp_ip_sk(sk);
struct inet_sock *inet = inet_sk(sk);
- struct ip_options *opt = inet->opt;
struct rtable *rt = NULL;
+ struct flowi4 *fl4;
int connected = 0;
__be32 daddr;
+ lock_sock(sk);
+
+ rc = -ENOTCONN;
if (sock_flag(sk, SOCK_DEAD))
- return -ENOTCONN;
+ goto out;
/* Get and verify the address. */
if (msg->msg_name) {
struct sockaddr_l2tpip *lip = (struct sockaddr_l2tpip *) msg->msg_name;
+ rc = -EINVAL;
if (msg->msg_namelen < sizeof(*lip))
- return -EINVAL;
+ goto out;
if (lip->l2tp_family != AF_INET) {
+ rc = -EAFNOSUPPORT;
if (lip->l2tp_family != AF_UNSPEC)
- return -EAFNOSUPPORT;
+ goto out;
}
daddr = lip->l2tp_addr.s_addr;
@@ -467,19 +476,27 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
goto error;
}
+ fl4 = &inet->cork.fl.u.ip4;
if (connected)
rt = (struct rtable *) __sk_dst_check(sk, 0);
if (rt == NULL) {
+ struct ip_options_rcu *inet_opt;
+
+ rcu_read_lock();
+ inet_opt = rcu_dereference(inet->inet_opt);
+
/* Use correct destination address if we have options. */
- if (opt && opt->srr)
- daddr = opt->faddr;
+ if (inet_opt && inet_opt->opt.srr)
+ daddr = inet_opt->opt.faddr;
+
+ rcu_read_unlock();
/* If this fails, retransmit mechanism of transport layer will
* keep trying until route appears or the connection times
* itself out.
*/
- rt = ip_route_output_ports(sock_net(sk), sk,
+ rt = ip_route_output_ports(sock_net(sk), fl4, sk,
daddr, inet->inet_saddr,
inet->inet_dport, inet->inet_sport,
sk->sk_protocol, RT_CONN_FLAGS(sk),
@@ -491,7 +508,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
skb_dst_set(skb, dst_clone(&rt->dst));
/* Queue the packet to IP for output */
- rc = ip_queue_xmit(skb);
+ rc = ip_queue_xmit(skb, &inet->cork.fl);
error:
/* Update stats */
@@ -503,12 +520,15 @@ error:
lsa->tx_errors++;
}
+out:
+ release_sock(sk);
return rc;
no_route:
IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
kfree_skb(skb);
- return -EHOSTUNREACH;
+ rc = -EHOSTUNREACH;
+ goto out;
}
static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index 4c1e540732d..93a41a09458 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -795,11 +795,12 @@ int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, const struct l2tp_nl_cmd_ops
goto out;
l2tp_nl_cmd_ops[pw_type] = ops;
+ ret = 0;
out:
genl_unlock();
err:
- return 0;
+ return ret;
}
EXPORT_SYMBOL_GPL(l2tp_nl_register_ops);
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 513f85cc2ae..f5fdfcbf552 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -2,7 +2,6 @@ config MAC80211
tristate "Generic IEEE 802.11 Networking Stack (mac80211)"
depends on CFG80211
select CRYPTO
- select CRYPTO_ECB
select CRYPTO_ARC4
select CRYPTO_AES
select CRC32
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c
index 4bd6ef0be38..b9b595c0811 100644
--- a/net/mac80211/aes_ccm.c
+++ b/net/mac80211/aes_ccm.c
@@ -54,13 +54,12 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
u8 *cdata, u8 *mic)
{
int i, j, last_len, num_blocks;
- u8 *pos, *cpos, *b, *s_0, *e, *b_0, *aad;
+ u8 *pos, *cpos, *b, *s_0, *e, *b_0;
b = scratch;
s_0 = scratch + AES_BLOCK_LEN;
e = scratch + 2 * AES_BLOCK_LEN;
b_0 = scratch + 3 * AES_BLOCK_LEN;
- aad = scratch + 4 * AES_BLOCK_LEN;
num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN);
last_len = data_len % AES_BLOCK_LEN;
@@ -94,13 +93,12 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
u8 *cdata, size_t data_len, u8 *mic, u8 *data)
{
int i, j, last_len, num_blocks;
- u8 *pos, *cpos, *b, *s_0, *a, *b_0, *aad;
+ u8 *pos, *cpos, *b, *s_0, *a, *b_0;
b = scratch;
s_0 = scratch + AES_BLOCK_LEN;
a = scratch + 2 * AES_BLOCK_LEN;
b_0 = scratch + 3 * AES_BLOCK_LEN;
- aad = scratch + 4 * AES_BLOCK_LEN;
num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN);
last_len = data_len % AES_BLOCK_LEN;
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 0c9d0c07eae..9c0d76cdca9 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -63,7 +63,8 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
lockdep_assert_held(&sta->ampdu_mlme.mtx);
- tid_rx = sta->ampdu_mlme.tid_rx[tid];
+ tid_rx = rcu_dereference_protected(sta->ampdu_mlme.tid_rx[tid],
+ lockdep_is_held(&sta->ampdu_mlme.mtx));
if (!tid_rx)
return;
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 53defafb9aa..c8be8eff70d 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -136,24 +136,35 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
ieee80211_tx_skb(sdata, skb);
}
+void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
+ struct tid_ampdu_tx *tid_tx)
+{
+ lockdep_assert_held(&sta->ampdu_mlme.mtx);
+ lockdep_assert_held(&sta->lock);
+ rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx);
+}
+
int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
enum ieee80211_back_parties initiator,
bool tx)
{
struct ieee80211_local *local = sta->local;
- struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid];
+ struct tid_ampdu_tx *tid_tx;
int ret;
lockdep_assert_held(&sta->ampdu_mlme.mtx);
- if (!tid_tx)
- return -ENOENT;
-
spin_lock_bh(&sta->lock);
+ tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
+ if (!tid_tx) {
+ spin_unlock_bh(&sta->lock);
+ return -ENOENT;
+ }
+
if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) {
/* not even started yet! */
- rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], NULL);
+ ieee80211_assign_tid_tx(sta, tid, NULL);
spin_unlock_bh(&sta->lock);
kfree_rcu(tid_tx, rcu_head);
return 0;
@@ -275,13 +286,13 @@ ieee80211_wake_queue_agg(struct ieee80211_local *local, int tid)
void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
{
- struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid];
+ struct tid_ampdu_tx *tid_tx;
struct ieee80211_local *local = sta->local;
struct ieee80211_sub_if_data *sdata = sta->sdata;
u16 start_seq_num;
int ret;
- lockdep_assert_held(&sta->ampdu_mlme.mtx);
+ tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
/*
* While we're asking the driver about the aggregation,
@@ -310,7 +321,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
" tid %d\n", tid);
#endif
spin_lock_bh(&sta->lock);
- rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], NULL);
+ ieee80211_assign_tid_tx(sta, tid, NULL);
spin_unlock_bh(&sta->lock);
ieee80211_wake_queue_agg(local, tid);
@@ -388,9 +399,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
goto err_unlock_sta;
}
- tid_tx = sta->ampdu_mlme.tid_tx[tid];
+ tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
/* check if the TID is not in aggregation flow already */
- if (tid_tx) {
+ if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) {
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "BA request denied - session is not "
"idle on tid %u\n", tid);
@@ -425,8 +436,11 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
sta->ampdu_mlme.dialog_token_allocator++;
tid_tx->dialog_token = sta->ampdu_mlme.dialog_token_allocator;
- /* finally, assign it to the array */
- rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx);
+ /*
+ * Finally, assign it to the start array; the work item will
+ * collect it and move it to the normal array.
+ */
+ sta->ampdu_mlme.tid_start_tx[tid] = tid_tx;
ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);
@@ -472,16 +486,19 @@ ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid)
static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
struct sta_info *sta, u16 tid)
{
+ struct tid_ampdu_tx *tid_tx;
+
lockdep_assert_held(&sta->ampdu_mlme.mtx);
+ tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
+
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "Aggregation is on for tid %d\n", tid);
#endif
drv_ampdu_action(local, sta->sdata,
IEEE80211_AMPDU_TX_OPERATIONAL,
- &sta->sta, tid, NULL,
- sta->ampdu_mlme.tid_tx[tid]->buf_size);
+ &sta->sta, tid, NULL, tid_tx->buf_size);
/*
* synchronize with TX path, while splicing the TX path
@@ -489,13 +506,13 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
*/
spin_lock_bh(&sta->lock);
- ieee80211_agg_splice_packets(local, sta->ampdu_mlme.tid_tx[tid], tid);
+ ieee80211_agg_splice_packets(local, tid_tx, tid);
/*
* Now mark as operational. This will be visible
* in the TX path, and lets it go lock-free in
* the common case.
*/
- set_bit(HT_AGG_STATE_OPERATIONAL, &sta->ampdu_mlme.tid_tx[tid]->state);
+ set_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state);
ieee80211_agg_splice_finish(local, tid);
spin_unlock_bh(&sta->lock);
@@ -529,7 +546,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
}
mutex_lock(&sta->ampdu_mlme.mtx);
- tid_tx = sta->ampdu_mlme.tid_tx[tid];
+ tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
if (WARN_ON(!tid_tx)) {
#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -607,7 +624,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
return -EINVAL;
spin_lock_bh(&sta->lock);
- tid_tx = sta->ampdu_mlme.tid_tx[tid];
+ tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
if (!tid_tx) {
ret = -ENOENT;
@@ -663,7 +680,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
mutex_lock(&sta->ampdu_mlme.mtx);
spin_lock_bh(&sta->lock);
- tid_tx = sta->ampdu_mlme.tid_tx[tid];
+ tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -689,7 +706,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
ieee80211_agg_splice_packets(local, tid_tx, tid);
/* future packets must not find the tid_tx struct any more */
- rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], NULL);
+ ieee80211_assign_tid_tx(sta, tid, NULL);
ieee80211_agg_splice_finish(local, tid);
@@ -744,7 +761,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
mutex_lock(&sta->ampdu_mlme.mtx);
- tid_tx = sta->ampdu_mlme.tid_tx[tid];
+ tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
if (!tid_tx)
goto out;
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 44049733c4e..be70c70d3f5 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -136,7 +136,10 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
mutex_lock(&sdata->local->sta_mtx);
if (mac_addr) {
- sta = sta_info_get_bss(sdata, mac_addr);
+ if (ieee80211_vif_is_mesh(&sdata->vif))
+ sta = sta_info_get(sdata, mac_addr);
+ else
+ sta = sta_info_get_bss(sdata, mac_addr);
if (!sta) {
ieee80211_key_free(sdata->local, key);
err = -ENOENT;
@@ -157,13 +160,14 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_idx, bool pairwise, const u8 *mac_addr)
{
- struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
+ struct ieee80211_key *key = NULL;
int ret;
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
- mutex_lock(&sdata->local->sta_mtx);
+ mutex_lock(&local->sta_mtx);
+ mutex_lock(&local->key_mtx);
if (mac_addr) {
ret = -ENOENT;
@@ -172,33 +176,24 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
if (!sta)
goto out_unlock;
- if (pairwise) {
- if (sta->ptk) {
- ieee80211_key_free(sdata->local, sta->ptk);
- ret = 0;
- }
- } else {
- if (sta->gtk[key_idx]) {
- ieee80211_key_free(sdata->local,
- sta->gtk[key_idx]);
- ret = 0;
- }
- }
-
- goto out_unlock;
- }
+ if (pairwise)
+ key = key_mtx_dereference(local, sta->ptk);
+ else
+ key = key_mtx_dereference(local, sta->gtk[key_idx]);
+ } else
+ key = key_mtx_dereference(local, sdata->keys[key_idx]);
- if (!sdata->keys[key_idx]) {
+ if (!key) {
ret = -ENOENT;
goto out_unlock;
}
- ieee80211_key_free(sdata->local, sdata->keys[key_idx]);
- WARN_ON(sdata->keys[key_idx]);
+ __ieee80211_key_free(key);
ret = 0;
out_unlock:
- mutex_unlock(&sdata->local->sta_mtx);
+ mutex_unlock(&local->key_mtx);
+ mutex_unlock(&local->sta_mtx);
return ret;
}
@@ -228,11 +223,11 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
goto out;
if (pairwise)
- key = sta->ptk;
+ key = rcu_dereference(sta->ptk);
else if (key_idx < NUM_DEFAULT_KEYS)
- key = sta->gtk[key_idx];
+ key = rcu_dereference(sta->gtk[key_idx]);
} else
- key = sdata->keys[key_idx];
+ key = rcu_dereference(sdata->keys[key_idx]);
if (!key)
goto out;
@@ -330,6 +325,7 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in
static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
{
struct ieee80211_sub_if_data *sdata = sta->sdata;
+ struct timespec uptime;
sinfo->generation = sdata->local->sta_generation;
@@ -342,7 +338,12 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
STATION_INFO_TX_FAILED |
STATION_INFO_TX_BITRATE |
STATION_INFO_RX_BITRATE |
- STATION_INFO_RX_DROP_MISC;
+ STATION_INFO_RX_DROP_MISC |
+ STATION_INFO_BSS_PARAM |
+ STATION_INFO_CONNECTED_TIME;
+
+ do_posix_clock_monotonic_gettime(&uptime);
+ sinfo->connected_time = uptime.tv_sec - sta->last_connected;
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
sinfo->rx_bytes = sta->rx_bytes;
@@ -389,6 +390,16 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
sinfo->plink_state = sta->plink_state;
#endif
}
+
+ sinfo->bss_param.flags = 0;
+ if (sdata->vif.bss_conf.use_cts_prot)
+ sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
+ if (sdata->vif.bss_conf.use_short_preamble)
+ sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
+ if (sdata->vif.bss_conf.use_short_slot)
+ sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
+ sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period;
+ sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int;
}
@@ -452,7 +463,7 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
int size;
int err = -EINVAL;
- old = sdata->u.ap.beacon;
+ old = rtnl_dereference(sdata->u.ap.beacon);
/* head must not be zero-length */
if (params->head && !params->head_len)
@@ -547,8 +558,7 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- old = sdata->u.ap.beacon;
-
+ old = rtnl_dereference(sdata->u.ap.beacon);
if (old)
return -EALREADY;
@@ -563,8 +573,7 @@ static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- old = sdata->u.ap.beacon;
-
+ old = rtnl_dereference(sdata->u.ap.beacon);
if (!old)
return -ENOENT;
@@ -578,8 +587,7 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- old = sdata->u.ap.beacon;
-
+ old = rtnl_dereference(sdata->u.ap.beacon);
if (!old)
return -ENOENT;
@@ -675,6 +683,12 @@ static void sta_apply_parameters(struct ieee80211_local *local,
if (set & BIT(NL80211_STA_FLAG_MFP))
sta->flags |= WLAN_STA_MFP;
}
+
+ if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) {
+ sta->flags &= ~WLAN_STA_AUTH;
+ if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED))
+ sta->flags |= WLAN_STA_AUTH;
+ }
spin_unlock_irqrestore(&sta->flaglock, flags);
/*
@@ -712,15 +726,29 @@ static void sta_apply_parameters(struct ieee80211_local *local,
params->ht_capa,
&sta->sta.ht_cap);
- if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) {
- switch (params->plink_action) {
- case PLINK_ACTION_OPEN:
- mesh_plink_open(sta);
- break;
- case PLINK_ACTION_BLOCK:
- mesh_plink_block(sta);
- break;
- }
+ if (ieee80211_vif_is_mesh(&sdata->vif)) {
+#ifdef CONFIG_MAC80211_MESH
+ if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED)
+ switch (params->plink_state) {
+ case NL80211_PLINK_LISTEN:
+ case NL80211_PLINK_ESTAB:
+ case NL80211_PLINK_BLOCKED:
+ sta->plink_state = params->plink_state;
+ break;
+ default:
+ /* nothing */
+ break;
+ }
+ else
+ switch (params->plink_action) {
+ case PLINK_ACTION_OPEN:
+ mesh_plink_open(sta);
+ break;
+ case PLINK_ACTION_BLOCK:
+ mesh_plink_block(sta);
+ break;
+ }
+#endif
}
}
@@ -921,8 +949,10 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
struct mpath_info *pinfo)
{
- if (mpath->next_hop)
- memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN);
+ struct sta_info *next_hop_sta = rcu_dereference(mpath->next_hop);
+
+ if (next_hop_sta)
+ memcpy(next_hop, next_hop_sta->sta.addr, ETH_ALEN);
else
memset(next_hop, 0, ETH_ALEN);
@@ -1023,26 +1053,30 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
u8 *new_ie;
const u8 *old_ie;
- /* first allocate the new vendor information element */
+ /* allocate information elements */
new_ie = NULL;
- old_ie = ifmsh->vendor_ie;
+ old_ie = ifmsh->ie;
- ifmsh->vendor_ie_len = setup->vendor_ie_len;
- if (setup->vendor_ie_len) {
- new_ie = kmemdup(setup->vendor_ie, setup->vendor_ie_len,
+ if (setup->ie_len) {
+ new_ie = kmemdup(setup->ie, setup->ie_len,
GFP_KERNEL);
if (!new_ie)
return -ENOMEM;
}
+ ifmsh->ie_len = setup->ie_len;
+ ifmsh->ie = new_ie;
+ kfree(old_ie);
/* now copy the rest of the setup parameters */
ifmsh->mesh_id_len = setup->mesh_id_len;
memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
ifmsh->mesh_pp_id = setup->path_sel_proto;
ifmsh->mesh_pm_id = setup->path_metric;
- ifmsh->vendor_ie = new_ie;
-
- kfree(old_ie);
+ ifmsh->security = IEEE80211_MESH_SEC_NONE;
+ if (setup->is_authenticated)
+ ifmsh->security |= IEEE80211_MESH_SEC_AUTHED;
+ if (setup->is_secure)
+ ifmsh->security |= IEEE80211_MESH_SEC_SECURED;
return 0;
}
@@ -1275,9 +1309,10 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
}
#ifdef CONFIG_PM
-static int ieee80211_suspend(struct wiphy *wiphy)
+static int ieee80211_suspend(struct wiphy *wiphy,
+ struct cfg80211_wowlan *wowlan)
{
- return __ieee80211_suspend(wiphy_priv(wiphy));
+ return __ieee80211_suspend(wiphy_priv(wiphy), wowlan);
}
static int ieee80211_resume(struct wiphy *wiphy)
@@ -1320,6 +1355,30 @@ static int ieee80211_scan(struct wiphy *wiphy,
return ieee80211_request_scan(sdata, req);
}
+static int
+ieee80211_sched_scan_start(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_sched_scan_request *req)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ if (!sdata->local->ops->sched_scan_start)
+ return -EOPNOTSUPP;
+
+ return ieee80211_request_sched_scan_start(sdata, req);
+}
+
+static int
+ieee80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ if (!sdata->local->ops->sched_scan_stop)
+ return -EOPNOTSUPP;
+
+ return ieee80211_request_sched_scan_stop(sdata);
+}
+
static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_auth_request *req)
{
@@ -1611,16 +1670,13 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
- int i;
-
- /*
- * This _could_ be supported by providing a hook for
- * drivers for this function, but at this point it
- * doesn't seem worth bothering.
- */
- if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
- return -EOPNOTSUPP;
+ int i, ret;
+ if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) {
+ ret = drv_set_bitrate_mask(local, sdata, mask);
+ if (ret)
+ return ret;
+ }
for (i = 0; i < IEEE80211_NUM_BANDS; i++)
sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
@@ -2064,6 +2120,8 @@ struct cfg80211_ops mac80211_config_ops = {
.suspend = ieee80211_suspend,
.resume = ieee80211_resume,
.scan = ieee80211_scan,
+ .sched_scan_start = ieee80211_sched_scan_start,
+ .sched_scan_stop = ieee80211_sched_scan_stop,
.auth = ieee80211_auth,
.assoc = ieee80211_assoc,
.deauth = ieee80211_deauth,
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 51f0d780daf..186e02f7cc3 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -37,7 +37,7 @@ int mac80211_format_buffer(char __user *userbuf, size_t count,
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
}
-#define DEBUGFS_READONLY_FILE(name, fmt, value...) \
+#define DEBUGFS_READONLY_FILE_FN(name, fmt, value...) \
static ssize_t name## _read(struct file *file, char __user *userbuf, \
size_t count, loff_t *ppos) \
{ \
@@ -45,14 +45,19 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \
\
return mac80211_format_buffer(userbuf, count, ppos, \
fmt "\n", ##value); \
-} \
- \
+}
+
+#define DEBUGFS_READONLY_FILE_OPS(name) \
static const struct file_operations name## _ops = { \
.read = name## _read, \
.open = mac80211_open_file_generic, \
.llseek = generic_file_llseek, \
};
+#define DEBUGFS_READONLY_FILE(name, fmt, value...) \
+ DEBUGFS_READONLY_FILE_FN(name, fmt, value) \
+ DEBUGFS_READONLY_FILE_OPS(name)
+
#define DEBUGFS_ADD(name) \
debugfs_create_file(#name, 0400, phyd, local, &name## _ops);
@@ -130,7 +135,7 @@ static ssize_t reset_write(struct file *file, const char __user *user_buf,
struct ieee80211_local *local = file->private_data;
rtnl_lock();
- __ieee80211_suspend(&local->hw);
+ __ieee80211_suspend(&local->hw, NULL);
__ieee80211_resume(&local->hw);
rtnl_unlock();
@@ -291,11 +296,70 @@ static ssize_t channel_type_read(struct file *file, char __user *user_buf,
return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
}
-static const struct file_operations channel_type_ops = {
- .read = channel_type_read,
- .open = mac80211_open_file_generic,
- .llseek = default_llseek,
-};
+static ssize_t hwflags_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ieee80211_local *local = file->private_data;
+ int mxln = 500;
+ ssize_t rv;
+ char *buf = kzalloc(mxln, GFP_KERNEL);
+ int sf = 0; /* how many written so far */
+
+ sf += snprintf(buf, mxln - sf, "0x%x\n", local->hw.flags);
+ if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
+ sf += snprintf(buf + sf, mxln - sf, "HAS_RATE_CONTROL\n");
+ if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
+ sf += snprintf(buf + sf, mxln - sf, "RX_INCLUDES_FCS\n");
+ if (local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING)
+ sf += snprintf(buf + sf, mxln - sf,
+ "HOST_BCAST_PS_BUFFERING\n");
+ if (local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE)
+ sf += snprintf(buf + sf, mxln - sf,
+ "2GHZ_SHORT_SLOT_INCAPABLE\n");
+ if (local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE)
+ sf += snprintf(buf + sf, mxln - sf,
+ "2GHZ_SHORT_PREAMBLE_INCAPABLE\n");
+ if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
+ sf += snprintf(buf + sf, mxln - sf, "SIGNAL_UNSPEC\n");
+ if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
+ sf += snprintf(buf + sf, mxln - sf, "SIGNAL_DBM\n");
+ if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD)
+ sf += snprintf(buf + sf, mxln - sf, "NEED_DTIM_PERIOD\n");
+ if (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)
+ sf += snprintf(buf + sf, mxln - sf, "SPECTRUM_MGMT\n");
+ if (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)
+ sf += snprintf(buf + sf, mxln - sf, "AMPDU_AGGREGATION\n");
+ if (local->hw.flags & IEEE80211_HW_SUPPORTS_PS)
+ sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_PS\n");
+ if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
+ sf += snprintf(buf + sf, mxln - sf, "PS_NULLFUNC_STACK\n");
+ if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
+ sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_PS\n");
+ if (local->hw.flags & IEEE80211_HW_MFP_CAPABLE)
+ sf += snprintf(buf + sf, mxln - sf, "MFP_CAPABLE\n");
+ if (local->hw.flags & IEEE80211_HW_BEACON_FILTER)
+ sf += snprintf(buf + sf, mxln - sf, "BEACON_FILTER\n");
+ if (local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS)
+ sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_STATIC_SMPS\n");
+ if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS)
+ sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_SMPS\n");
+ if (local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)
+ sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_UAPSD\n");
+ if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
+ sf += snprintf(buf + sf, mxln - sf, "REPORTS_TX_ACK_STATUS\n");
+ if (local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
+ sf += snprintf(buf + sf, mxln - sf, "CONNECTION_MONITOR\n");
+ if (local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)
+ sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_CQM_RSSI\n");
+ if (local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK)
+ sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_PER_STA_GTK\n");
+ if (local->hw.flags & IEEE80211_HW_AP_LINK_PS)
+ sf += snprintf(buf + sf, mxln - sf, "AP_LINK_PS\n");
+
+ rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
+ kfree(buf);
+ return rv;
+}
static ssize_t queues_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
@@ -315,11 +379,9 @@ static ssize_t queues_read(struct file *file, char __user *user_buf,
return simple_read_from_buffer(user_buf, count, ppos, buf, res);
}
-static const struct file_operations queues_ops = {
- .read = queues_read,
- .open = mac80211_open_file_generic,
- .llseek = default_llseek,
-};
+DEBUGFS_READONLY_FILE_OPS(hwflags);
+DEBUGFS_READONLY_FILE_OPS(channel_type);
+DEBUGFS_READONLY_FILE_OPS(queues);
/* statistics stuff */
@@ -395,6 +457,7 @@ void debugfs_hw_add(struct ieee80211_local *local)
DEBUGFS_ADD(uapsd_queues);
DEBUGFS_ADD(uapsd_max_sp_len);
DEBUGFS_ADD(channel_type);
+ DEBUGFS_ADD(hwflags);
DEBUGFS_ADD(user_power);
DEBUGFS_ADD(power);
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index f7ef3477c24..33c58b85c91 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -241,16 +241,12 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key)
if (!key->debugfs.dir)
return;
- rcu_read_lock();
- sta = rcu_dereference(key->sta);
- if (sta)
+ sta = key->sta;
+ if (sta) {
sprintf(buf, "../../stations/%pM", sta->sta.addr);
- rcu_read_unlock();
-
- /* using sta as a boolean is fine outside RCU lock */
- if (sta)
key->debugfs.stalink =
debugfs_create_symlink("station", key->debugfs.dir, buf);
+ }
DEBUGFS_ADD(keylen);
DEBUGFS_ADD(flags);
@@ -286,7 +282,8 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
lockdep_assert_held(&sdata->local->key_mtx);
if (sdata->default_unicast_key) {
- key = sdata->default_unicast_key;
+ key = key_mtx_dereference(sdata->local,
+ sdata->default_unicast_key);
sprintf(buf, "../keys/%d", key->debugfs.cnt);
sdata->debugfs.default_unicast_key =
debugfs_create_symlink("default_unicast_key",
@@ -297,7 +294,8 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
}
if (sdata->default_multicast_key) {
- key = sdata->default_multicast_key;
+ key = key_mtx_dereference(sdata->local,
+ sdata->default_multicast_key);
sprintf(buf, "../keys/%d", key->debugfs.cnt);
sdata->debugfs.default_multicast_key =
debugfs_create_symlink("default_multicast_key",
@@ -316,9 +314,8 @@ void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
if (!sdata->debugfs.dir)
return;
- /* this is running under the key lock */
-
- key = sdata->default_mgmt_key;
+ key = key_mtx_dereference(sdata->local,
+ sdata->default_mgmt_key);
if (key) {
sprintf(buf, "../keys/%d", key->debugfs.cnt);
sdata->debugfs.default_mgmt_key =
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index c04a1396cf8..a01d2137fdd 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -92,6 +92,31 @@ static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf,
}
STA_OPS(inactive_ms);
+
+static ssize_t sta_connected_time_read(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct sta_info *sta = file->private_data;
+ struct timespec uptime;
+ struct tm result;
+ long connected_time_secs;
+ char buf[100];
+ int res;
+ do_posix_clock_monotonic_gettime(&uptime);
+ connected_time_secs = uptime.tv_sec - sta->last_connected;
+ time_to_tm(connected_time_secs, 0, &result);
+ result.tm_year -= 70;
+ result.tm_mday -= 1;
+ res = scnprintf(buf, sizeof(buf),
+ "years - %ld\nmonths - %d\ndays - %d\nclock - %d:%d:%d\n\n",
+ result.tm_year, result.tm_mon, result.tm_mday,
+ result.tm_hour, result.tm_min, result.tm_sec);
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res);
+}
+STA_OPS(connected_time);
+
+
+
static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
@@ -324,6 +349,7 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
DEBUGFS_ADD(flags);
DEBUGFS_ADD(num_ps_buf_frames);
DEBUGFS_ADD(inactive_ms);
+ DEBUGFS_ADD(connected_time);
DEBUGFS_ADD(last_seq_ctrl);
DEBUGFS_ADD(agg_status);
DEBUGFS_ADD(dev);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 9c0d62bb0ea..eebf7a67daf 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -41,6 +41,33 @@ static inline void drv_stop(struct ieee80211_local *local)
local->started = false;
}
+#ifdef CONFIG_PM
+static inline int drv_suspend(struct ieee80211_local *local,
+ struct cfg80211_wowlan *wowlan)
+{
+ int ret;
+
+ might_sleep();
+
+ trace_drv_suspend(local);
+ ret = local->ops->suspend(&local->hw, wowlan);
+ trace_drv_return_int(local, ret);
+ return ret;
+}
+
+static inline int drv_resume(struct ieee80211_local *local)
+{
+ int ret;
+
+ might_sleep();
+
+ trace_drv_resume(local);
+ ret = local->ops->resume(&local->hw);
+ trace_drv_return_int(local, ret);
+ return ret;
+}
+#endif
+
static inline int drv_add_interface(struct ieee80211_local *local,
struct ieee80211_vif *vif)
{
@@ -185,12 +212,39 @@ static inline int drv_hw_scan(struct ieee80211_local *local,
might_sleep();
- trace_drv_hw_scan(local, sdata, req);
+ trace_drv_hw_scan(local, sdata);
ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
trace_drv_return_int(local, ret);
return ret;
}
+static inline int
+drv_sched_scan_start(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_sched_scan_request *req,
+ struct ieee80211_sched_scan_ies *ies)
+{
+ int ret;
+
+ might_sleep();
+
+ trace_drv_sched_scan_start(local, sdata);
+ ret = local->ops->sched_scan_start(&local->hw, &sdata->vif,
+ req, ies);
+ trace_drv_return_int(local, ret);
+ return ret;
+}
+
+static inline void drv_sched_scan_stop(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata)
+{
+ might_sleep();
+
+ trace_drv_sched_scan_stop(local, sdata);
+ local->ops->sched_scan_stop(&local->hw, &sdata->vif);
+ trace_drv_return_void(local);
+}
+
static inline void drv_sw_scan_start(struct ieee80211_local *local)
{
might_sleep();
@@ -552,4 +606,35 @@ static inline void drv_get_ringparam(struct ieee80211_local *local,
trace_drv_return_void(local);
}
+static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
+{
+ bool ret = false;
+
+ might_sleep();
+
+ trace_drv_tx_frames_pending(local);
+ if (local->ops->tx_frames_pending)
+ ret = local->ops->tx_frames_pending(&local->hw);
+ trace_drv_return_bool(local, ret);
+
+ return ret;
+}
+
+static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ const struct cfg80211_bitrate_mask *mask)
+{
+ int ret = -EOPNOTSUPP;
+
+ might_sleep();
+
+ trace_drv_set_bitrate_mask(local, sdata, mask);
+ if (local->ops->set_bitrate_mask)
+ ret = local->ops->set_bitrate_mask(&local->hw,
+ &sdata->vif, mask);
+ trace_drv_return_int(local, ret);
+
+ return ret;
+}
+
#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 45aab80738e..ed9edcbd9aa 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -55,6 +55,70 @@ DECLARE_EVENT_CLASS(local_only_evt,
TP_printk(LOCAL_PR_FMT, LOCAL_PR_ARG)
);
+DECLARE_EVENT_CLASS(local_sdata_addr_evt,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata),
+ TP_ARGS(local, sdata),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ VIF_ENTRY
+ __array(char, addr, 6)
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ VIF_ASSIGN;
+ memcpy(__entry->addr, sdata->vif.addr, 6);
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT VIF_PR_FMT " addr:%pM",
+ LOCAL_PR_ARG, VIF_PR_ARG, __entry->addr
+ )
+);
+
+DECLARE_EVENT_CLASS(local_u32_evt,
+ TP_PROTO(struct ieee80211_local *local, u32 value),
+ TP_ARGS(local, value),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ __field(u32, value)
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ __entry->value = value;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT " value:%d",
+ LOCAL_PR_ARG, __entry->value
+ )
+);
+
+DECLARE_EVENT_CLASS(local_sdata_evt,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata),
+ TP_ARGS(local, sdata),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ VIF_ENTRY
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ VIF_ASSIGN;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT VIF_PR_FMT,
+ LOCAL_PR_ARG, VIF_PR_ARG
+ )
+);
+
DEFINE_EVENT(local_only_evt, drv_return_void,
TP_PROTO(struct ieee80211_local *local),
TP_ARGS(local)
@@ -74,6 +138,21 @@ TRACE_EVENT(drv_return_int,
TP_printk(LOCAL_PR_FMT " - %d", LOCAL_PR_ARG, __entry->ret)
);
+TRACE_EVENT(drv_return_bool,
+ TP_PROTO(struct ieee80211_local *local, bool ret),
+ TP_ARGS(local, ret),
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ __field(bool, ret)
+ ),
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ __entry->ret = ret;
+ ),
+ TP_printk(LOCAL_PR_FMT " - %s", LOCAL_PR_ARG, (__entry->ret) ?
+ "true" : "false")
+);
+
TRACE_EVENT(drv_return_u64,
TP_PROTO(struct ieee80211_local *local, u64 ret),
TP_ARGS(local, ret),
@@ -93,33 +172,25 @@ DEFINE_EVENT(local_only_evt, drv_start,
TP_ARGS(local)
);
+DEFINE_EVENT(local_only_evt, drv_suspend,
+ TP_PROTO(struct ieee80211_local *local),
+ TP_ARGS(local)
+);
+
+DEFINE_EVENT(local_only_evt, drv_resume,
+ TP_PROTO(struct ieee80211_local *local),
+ TP_ARGS(local)
+);
+
DEFINE_EVENT(local_only_evt, drv_stop,
TP_PROTO(struct ieee80211_local *local),
TP_ARGS(local)
);
-TRACE_EVENT(drv_add_interface,
+DEFINE_EVENT(local_sdata_addr_evt, drv_add_interface,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata),
-
- TP_ARGS(local, sdata),
-
- TP_STRUCT__entry(
- LOCAL_ENTRY
- VIF_ENTRY
- __array(char, addr, 6)
- ),
-
- TP_fast_assign(
- LOCAL_ASSIGN;
- VIF_ASSIGN;
- memcpy(__entry->addr, sdata->vif.addr, 6);
- ),
-
- TP_printk(
- LOCAL_PR_FMT VIF_PR_FMT " addr:%pM",
- LOCAL_PR_ARG, VIF_PR_ARG, __entry->addr
- )
+ TP_ARGS(local, sdata)
);
TRACE_EVENT(drv_change_interface,
@@ -150,27 +221,10 @@ TRACE_EVENT(drv_change_interface,
)
);
-TRACE_EVENT(drv_remove_interface,
- TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata),
-
- TP_ARGS(local, sdata),
-
- TP_STRUCT__entry(
- LOCAL_ENTRY
- VIF_ENTRY
- __array(char, addr, 6)
- ),
-
- TP_fast_assign(
- LOCAL_ASSIGN;
- VIF_ASSIGN;
- memcpy(__entry->addr, sdata->vif.addr, 6);
- ),
-
- TP_printk(
- LOCAL_PR_FMT VIF_PR_FMT " addr:%pM",
- LOCAL_PR_ARG, VIF_PR_ARG, __entry->addr
- )
+DEFINE_EVENT(local_sdata_addr_evt, drv_remove_interface,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata),
+ TP_ARGS(local, sdata)
);
TRACE_EVENT(drv_config,
@@ -400,27 +454,22 @@ TRACE_EVENT(drv_update_tkip_key,
)
);
-TRACE_EVENT(drv_hw_scan,
+DEFINE_EVENT(local_sdata_evt, drv_hw_scan,
TP_PROTO(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata,
- struct cfg80211_scan_request *req),
-
- TP_ARGS(local, sdata, req),
-
- TP_STRUCT__entry(
- LOCAL_ENTRY
- VIF_ENTRY
- ),
+ struct ieee80211_sub_if_data *sdata),
+ TP_ARGS(local, sdata)
+);
- TP_fast_assign(
- LOCAL_ASSIGN;
- VIF_ASSIGN;
- ),
+DEFINE_EVENT(local_sdata_evt, drv_sched_scan_start,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata),
+ TP_ARGS(local, sdata)
+);
- TP_printk(
- LOCAL_PR_FMT VIF_PR_FMT,
- LOCAL_PR_ARG,VIF_PR_ARG
- )
+DEFINE_EVENT(local_sdata_evt, drv_sched_scan_stop,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata),
+ TP_ARGS(local, sdata)
);
DEFINE_EVENT(local_only_evt, drv_sw_scan_start,
@@ -489,46 +538,14 @@ TRACE_EVENT(drv_get_tkip_seq,
)
);
-TRACE_EVENT(drv_set_frag_threshold,
+DEFINE_EVENT(local_u32_evt, drv_set_frag_threshold,
TP_PROTO(struct ieee80211_local *local, u32 value),
-
- TP_ARGS(local, value),
-
- TP_STRUCT__entry(
- LOCAL_ENTRY
- __field(u32, value)
- ),
-
- TP_fast_assign(
- LOCAL_ASSIGN;
- __entry->value = value;
- ),
-
- TP_printk(
- LOCAL_PR_FMT " value:%d",
- LOCAL_PR_ARG, __entry->value
- )
+ TP_ARGS(local, value)
);
-TRACE_EVENT(drv_set_rts_threshold,
+DEFINE_EVENT(local_u32_evt, drv_set_rts_threshold,
TP_PROTO(struct ieee80211_local *local, u32 value),
-
- TP_ARGS(local, value),
-
- TP_STRUCT__entry(
- LOCAL_ENTRY
- __field(u32, value)
- ),
-
- TP_fast_assign(
- LOCAL_ASSIGN;
- __entry->value = value;
- ),
-
- TP_printk(
- LOCAL_PR_FMT " value:%d",
- LOCAL_PR_ARG, __entry->value
- )
+ TP_ARGS(local, value)
);
TRACE_EVENT(drv_set_coverage_class,
@@ -964,11 +981,43 @@ TRACE_EVENT(drv_get_ringparam,
)
);
+DEFINE_EVENT(local_only_evt, drv_tx_frames_pending,
+ TP_PROTO(struct ieee80211_local *local),
+ TP_ARGS(local)
+);
+
DEFINE_EVENT(local_only_evt, drv_offchannel_tx_cancel_wait,
TP_PROTO(struct ieee80211_local *local),
TP_ARGS(local)
);
+TRACE_EVENT(drv_set_bitrate_mask,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ const struct cfg80211_bitrate_mask *mask),
+
+ TP_ARGS(local, sdata, mask),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ VIF_ENTRY
+ __field(u32, legacy_2g)
+ __field(u32, legacy_5g)
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ VIF_ASSIGN;
+ __entry->legacy_2g = mask->control[IEEE80211_BAND_2GHZ].legacy;
+ __entry->legacy_5g = mask->control[IEEE80211_BAND_5GHZ].legacy;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT VIF_PR_FMT " 2G Mask:0x%x 5G Mask:0x%x",
+ LOCAL_PR_ARG, VIF_PR_ARG, __entry->legacy_2g, __entry->legacy_5g
+ )
+);
+
/*
* Tracing for API calls that drivers call.
*/
@@ -1147,6 +1196,42 @@ TRACE_EVENT(api_scan_completed,
)
);
+TRACE_EVENT(api_sched_scan_results,
+ TP_PROTO(struct ieee80211_local *local),
+
+ TP_ARGS(local),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT, LOCAL_PR_ARG
+ )
+);
+
+TRACE_EVENT(api_sched_scan_stopped,
+ TP_PROTO(struct ieee80211_local *local),
+
+ TP_ARGS(local),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT, LOCAL_PR_ARG
+ )
+);
+
TRACE_EVENT(api_sta_block_awake,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sta *sta, bool block),
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index b9e4b9bd217..591add22bcc 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -140,14 +140,29 @@ void ieee80211_ba_session_work(struct work_struct *work)
sta, tid, WLAN_BACK_RECIPIENT,
WLAN_REASON_QSTA_TIMEOUT, true);
- tid_tx = sta->ampdu_mlme.tid_tx[tid];
- if (!tid_tx)
- continue;
+ tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
+ if (tid_tx) {
+ /*
+ * Assign it over to the normal tid_tx array
+ * where it "goes live".
+ */
+ spin_lock_bh(&sta->lock);
+
+ sta->ampdu_mlme.tid_start_tx[tid] = NULL;
+ /* could there be a race? */
+ if (sta->ampdu_mlme.tid_tx[tid])
+ kfree(tid_tx);
+ else
+ ieee80211_assign_tid_tx(sta, tid, tid_tx);
+ spin_unlock_bh(&sta->lock);
- if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state))
ieee80211_tx_ba_session_handle_start(sta, tid);
- else if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
- &tid_tx->state))
+ continue;
+ }
+
+ tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
+ if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
+ &tid_tx->state))
___ieee80211_stop_tx_ba_session(sta, tid,
WLAN_BACK_INITIATOR,
true);
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 3e81af1fce5..421eaa6b0c2 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -40,7 +40,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt,
size_t len)
{
- u16 auth_alg, auth_transaction, status_code;
+ u16 auth_alg, auth_transaction;
lockdep_assert_held(&sdata->u.ibss.mtx);
@@ -49,7 +49,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
- status_code = le16_to_cpu(mgmt->u.auth.status_code);
/*
* IEEE 802.11 standard does not require authentication in IBSS
@@ -527,8 +526,6 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
- struct ieee80211_local *local = sdata->local;
- struct ieee80211_supported_band *sband;
u8 bssid[ETH_ALEN];
u16 capability;
int i;
@@ -551,8 +548,6 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
sdata->name, bssid);
- sband = local->hw.wiphy->bands[ifibss->channel->band];
-
capability = WLAN_CAPABILITY_IBSS;
if (ifibss->privacy)
@@ -661,19 +656,22 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
struct sk_buff *req)
{
- struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(req);
struct ieee80211_mgmt *mgmt = (void *)req->data;
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_local *local = sdata->local;
int tx_last_beacon, len = req->len;
struct sk_buff *skb;
struct ieee80211_mgmt *resp;
+ struct sk_buff *presp;
u8 *pos, *end;
lockdep_assert_held(&ifibss->mtx);
+ presp = rcu_dereference_protected(ifibss->presp,
+ lockdep_is_held(&ifibss->mtx));
+
if (ifibss->state != IEEE80211_IBSS_MLME_JOINED ||
- len < 24 + 2 || !ifibss->presp)
+ len < 24 + 2 || !presp)
return;
tx_last_beacon = drv_tx_last_beacon(local);
@@ -685,7 +683,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
mgmt->bssid, tx_last_beacon);
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
- if (!tx_last_beacon && !(rx_status->rx_flags & IEEE80211_RX_RA_MATCH))
+ if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da))
return;
if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 &&
@@ -711,7 +709,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
}
/* Reply with ProbeResp */
- skb = skb_copy(ifibss->presp, GFP_KERNEL);
+ skb = skb_copy(presp, GFP_KERNEL);
if (!skb)
return;
@@ -991,7 +989,8 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
/* remove beacon */
kfree(sdata->u.ibss.ie);
- skb = sdata->u.ibss.presp;
+ skb = rcu_dereference_protected(sdata->u.ibss.presp,
+ lockdep_is_held(&sdata->u.ibss.mtx));
rcu_assign_pointer(sdata->u.ibss.presp, NULL);
sdata->vif.bss_conf.ibss_joined = false;
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index c18396c248d..2025af52b19 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -214,7 +214,7 @@ struct beacon_data {
};
struct ieee80211_if_ap {
- struct beacon_data *beacon;
+ struct beacon_data __rcu *beacon;
struct list_head vlans;
@@ -237,7 +237,7 @@ struct ieee80211_if_vlan {
struct list_head list;
/* used for all tx if the VLAN is configured to 4-addr mode */
- struct sta_info *sta;
+ struct sta_info __rcu *sta;
};
struct mesh_stats {
@@ -442,7 +442,8 @@ struct ieee80211_if_ibss {
unsigned long ibss_join_req;
/* probe response/beacon for IBSS */
- struct sk_buff *presp, *skb;
+ struct sk_buff __rcu *presp;
+ struct sk_buff *skb;
enum {
IEEE80211_IBSS_MLME_SEARCH,
@@ -488,8 +489,13 @@ struct ieee80211_if_mesh {
struct mesh_config mshcfg;
u32 mesh_seqnum;
bool accepting_plinks;
- const u8 *vendor_ie;
- u8 vendor_ie_len;
+ const u8 *ie;
+ u8 ie_len;
+ enum {
+ IEEE80211_MESH_SEC_NONE = 0x0,
+ IEEE80211_MESH_SEC_AUTHED = 0x1,
+ IEEE80211_MESH_SEC_SECURED = 0x2,
+ } security;
};
#ifdef CONFIG_MAC80211_MESH
@@ -562,9 +568,10 @@ struct ieee80211_sub_if_data {
struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
unsigned int fragment_next;
- struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
- struct ieee80211_key *default_unicast_key, *default_multicast_key;
- struct ieee80211_key *default_mgmt_key;
+ struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
+ struct ieee80211_key __rcu *default_unicast_key;
+ struct ieee80211_key __rcu *default_multicast_key;
+ struct ieee80211_key __rcu *default_mgmt_key;
u16 sequence_number;
__be16 control_port_protocol;
@@ -763,8 +770,14 @@ struct ieee80211_local {
/* device is started */
bool started;
+ /* wowlan is enabled -- don't reconfig on resume */
+ bool wowlan;
+
int tx_headroom; /* required headroom for hardware/radiotap */
+ /* count for keys needing tailroom space allocation */
+ int crypto_tx_tailroom_needed_cnt;
+
/* Tasklet and skb queue to process calls from IRQ mode. All frames
* added to skb_queue will be processed, but frames in
* skb_queue_unreliable may be dropped if the total length of these
@@ -794,7 +807,7 @@ struct ieee80211_local {
spinlock_t sta_lock;
unsigned long num_sta;
struct list_head sta_list, sta_pending_list;
- struct sta_info *sta_hash[STA_HASH_SIZE];
+ struct sta_info __rcu *sta_hash[STA_HASH_SIZE];
struct timer_list sta_cleanup;
struct work_struct sta_finish_work;
int sta_generation;
@@ -809,8 +822,8 @@ struct ieee80211_local {
struct rate_control_ref *rate_ctrl;
- struct crypto_blkcipher *wep_tx_tfm;
- struct crypto_blkcipher *wep_rx_tfm;
+ struct crypto_cipher *wep_tx_tfm;
+ struct crypto_cipher *wep_rx_tfm;
u32 wep_iv;
/* see iface.c */
@@ -836,6 +849,10 @@ struct ieee80211_local {
int scan_channel_idx;
int scan_ies_len;
+ bool sched_scanning;
+ struct ieee80211_sched_scan_ies sched_scan_ies;
+ struct work_struct sched_scan_stopped_work;
+
unsigned long leave_oper_channel_time;
enum mac80211_scan_state next_scan_state;
struct delayed_work scan_work;
@@ -1143,6 +1160,12 @@ ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
void ieee80211_rx_bss_put(struct ieee80211_local *local,
struct ieee80211_bss *bss);
+/* scheduled scan handling */
+int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_sched_scan_request *req);
+int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata);
+void ieee80211_sched_scan_stopped_work(struct work_struct *work);
+
/* off-channel helpers */
bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local);
void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local,
@@ -1246,7 +1269,8 @@ int ieee80211_reconfig(struct ieee80211_local *local);
void ieee80211_stop_device(struct ieee80211_local *local);
#ifdef CONFIG_PM
-int __ieee80211_suspend(struct ieee80211_hw *hw);
+int __ieee80211_suspend(struct ieee80211_hw *hw,
+ struct cfg80211_wowlan *wowlan);
static inline int __ieee80211_resume(struct ieee80211_hw *hw)
{
@@ -1259,7 +1283,8 @@ static inline int __ieee80211_resume(struct ieee80211_hw *hw)
return ieee80211_reconfig(hw_to_local(hw));
}
#else
-static inline int __ieee80211_suspend(struct ieee80211_hw *hw)
+static inline int __ieee80211_suspend(struct ieee80211_hw *hw,
+ struct cfg80211_wowlan *wowlan)
{
return 0;
}
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 4054399be90..7dfbe71dc63 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -449,7 +449,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
/* APs need special treatment */
if (sdata->vif.type == NL80211_IFTYPE_AP) {
struct ieee80211_sub_if_data *vlan, *tmpsdata;
- struct beacon_data *old_beacon = sdata->u.ap.beacon;
+ struct beacon_data *old_beacon =
+ rtnl_dereference(sdata->u.ap.beacon);
/* sdata_running will return false, so this will disable */
ieee80211_bss_info_change_notify(sdata,
@@ -1144,10 +1145,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
+ IEEE80211_ENCRYPT_HEADROOM;
ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM;
- ret = dev_alloc_name(ndev, ndev->name);
- if (ret < 0)
- goto fail;
-
ieee80211_assign_perm_addr(local, ndev, type);
memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN);
SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index af3c56482c8..31afd712930 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -101,6 +101,11 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
if (!ret) {
key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
+
+ if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
+ (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
+ key->local->crypto_tx_tailroom_needed_cnt--;
+
return 0;
}
@@ -156,6 +161,10 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
+
+ if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
+ (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
+ key->local->crypto_tx_tailroom_needed_cnt++;
}
void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
@@ -186,7 +195,7 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
assert_key_lock(sdata->local);
if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
- key = sdata->keys[idx];
+ key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
if (uni)
rcu_assign_pointer(sdata->default_unicast_key, key);
@@ -213,7 +222,7 @@ __ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
if (idx >= NUM_DEFAULT_KEYS &&
idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
- key = sdata->keys[idx];
+ key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
rcu_assign_pointer(sdata->default_mgmt_key, key);
@@ -257,9 +266,15 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
else
idx = new->conf.keyidx;
- defunikey = old && sdata->default_unicast_key == old;
- defmultikey = old && sdata->default_multicast_key == old;
- defmgmtkey = old && sdata->default_mgmt_key == old;
+ defunikey = old &&
+ old == key_mtx_dereference(sdata->local,
+ sdata->default_unicast_key);
+ defmultikey = old &&
+ old == key_mtx_dereference(sdata->local,
+ sdata->default_multicast_key);
+ defmgmtkey = old &&
+ old == key_mtx_dereference(sdata->local,
+ sdata->default_mgmt_key);
if (defunikey && !new)
__ieee80211_set_default_key(sdata, -1, true, false);
@@ -388,8 +403,10 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key)
ieee80211_aes_key_free(key->u.ccmp.tfm);
if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
- if (key->local)
+ if (key->local) {
ieee80211_debugfs_key_remove(key);
+ key->local->crypto_tx_tailroom_needed_cnt--;
+ }
kfree(key);
}
@@ -440,17 +457,19 @@ int ieee80211_key_link(struct ieee80211_key *key,
mutex_lock(&sdata->local->key_mtx);
if (sta && pairwise)
- old_key = sta->ptk;
+ old_key = key_mtx_dereference(sdata->local, sta->ptk);
else if (sta)
- old_key = sta->gtk[idx];
+ old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]);
else
- old_key = sdata->keys[idx];
+ old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
__ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
__ieee80211_key_destroy(old_key);
ieee80211_debugfs_key_add(key);
+ key->local->crypto_tx_tailroom_needed_cnt++;
+
ret = ieee80211_key_enable_hw_accel(key);
mutex_unlock(&sdata->local->key_mtx);
@@ -458,8 +477,11 @@ int ieee80211_key_link(struct ieee80211_key *key,
return ret;
}
-static void __ieee80211_key_free(struct ieee80211_key *key)
+void __ieee80211_key_free(struct ieee80211_key *key)
{
+ if (!key)
+ return;
+
/*
* Replace key with nothingness if it was ever used.
*/
@@ -473,9 +495,6 @@ static void __ieee80211_key_free(struct ieee80211_key *key)
void ieee80211_key_free(struct ieee80211_local *local,
struct ieee80211_key *key)
{
- if (!key)
- return;
-
mutex_lock(&local->key_mtx);
__ieee80211_key_free(key);
mutex_unlock(&local->key_mtx);
@@ -492,8 +511,12 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
mutex_lock(&sdata->local->key_mtx);
- list_for_each_entry(key, &sdata->key_list, list)
+ sdata->local->crypto_tx_tailroom_needed_cnt = 0;
+
+ list_for_each_entry(key, &sdata->key_list, list) {
+ sdata->local->crypto_tx_tailroom_needed_cnt++;
ieee80211_key_enable_hw_accel(key);
+ }
mutex_unlock(&sdata->local->key_mtx);
}
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 4ddbe27eb57..d801d535133 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -135,6 +135,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
int __must_check ieee80211_key_link(struct ieee80211_key *key,
struct ieee80211_sub_if_data *sdata,
struct sta_info *sta);
+void __ieee80211_key_free(struct ieee80211_key *key);
void ieee80211_key_free(struct ieee80211_local *local,
struct ieee80211_key *key);
void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
@@ -145,4 +146,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata);
void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata);
+#define key_mtx_dereference(local, ref) \
+ rcu_dereference_protected(ref, lockdep_is_held(&((local)->key_mtx)))
+
#endif /* IEEE80211_KEY_H */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 562d2984c48..0d7b08db8e5 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -33,12 +33,6 @@
#include "cfg.h"
#include "debugfs.h"
-
-static bool ieee80211_disable_40mhz_24ghz;
-module_param(ieee80211_disable_40mhz_24ghz, bool, 0644);
-MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz,
- "Disable 40MHz support in the 2.4GHz band");
-
static struct lock_class_key ieee80211_rx_skb_queue_class;
void ieee80211_configure_filter(struct ieee80211_local *local)
@@ -364,7 +358,8 @@ static void ieee80211_restart_work(struct work_struct *work)
flush_workqueue(local->workqueue);
mutex_lock(&local->mtx);
- WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
+ WARN(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
+ local->sched_scanning,
"%s called with hardware scan in progress\n", __func__);
mutex_unlock(&local->mtx);
@@ -545,7 +540,9 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
},
[NL80211_IFTYPE_MESH_POINT] = {
.tx = 0xffff,
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4),
+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
+ BIT(IEEE80211_STYPE_DEAUTH >> 4),
},
};
@@ -584,8 +581,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
wiphy->flags |= WIPHY_FLAG_NETNS_OK |
WIPHY_FLAG_4ADDR_AP |
- WIPHY_FLAG_4ADDR_STATION |
- WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
+ WIPHY_FLAG_4ADDR_STATION;
if (!ops->set_key)
wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
@@ -656,6 +652,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
setup_timer(&local->dynamic_ps_timer,
ieee80211_dynamic_ps_timer, (unsigned long) local);
+ INIT_WORK(&local->sched_scan_stopped_work,
+ ieee80211_sched_scan_stopped_work);
+
sta_info_init(local);
for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
@@ -686,7 +685,7 @@ EXPORT_SYMBOL(ieee80211_alloc_hw);
int ieee80211_register_hw(struct ieee80211_hw *hw)
{
struct ieee80211_local *local = hw_to_local(hw);
- int result;
+ int result, i;
enum ieee80211_band band;
int channels, max_bitrates;
bool supp_ht;
@@ -701,6 +700,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
WLAN_CIPHER_SUITE_AES_CMAC
};
+ if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns)
+#ifdef CONFIG_PM
+ && (!local->ops->suspend || !local->ops->resume)
+#endif
+ )
+ return -EINVAL;
+
if (hw->max_report_rates == 0)
hw->max_report_rates = hw->max_rates;
@@ -726,18 +732,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
}
channels += sband->n_channels;
- /*
- * Since ieee80211_disable_40mhz_24ghz is global, we can
- * modify the sband's ht data even if the driver uses a
- * global structure for that.
- */
- if (ieee80211_disable_40mhz_24ghz &&
- band == IEEE80211_BAND_2GHZ &&
- sband->ht_cap.ht_supported) {
- sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
- sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
- }
-
if (max_bitrates < sband->n_bitrates)
max_bitrates = sband->n_bitrates;
supp_ht = supp_ht || sband->ht_cap.ht_supported;
@@ -749,17 +743,30 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
return -ENOMEM;
/* if low-level driver supports AP, we also support VLAN */
- if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP))
- local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
+ if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) {
+ hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
+ hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN);
+ }
/* mac80211 always supports monitor */
- local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
+ hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
+ hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
+
+ /* mac80211 doesn't support more than 1 channel */
+ for (i = 0; i < hw->wiphy->n_iface_combinations; i++)
+ if (hw->wiphy->iface_combinations[i].num_different_channels > 1)
+ return -EINVAL;
#ifndef CONFIG_MAC80211_MESH
/* mesh depends on Kconfig, but drivers should set it if they want */
local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT);
#endif
+ /* if the underlying driver supports mesh, mac80211 will (at least)
+ * provide routing of mesh authentication frames to userspace */
+ if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_MESH_POINT))
+ local->hw.wiphy->flags |= WIPHY_FLAG_MESH_AUTH;
+
/* mac80211 supports control port protocol changing */
local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL;
@@ -838,6 +845,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
if (!local->ops->remain_on_channel)
local->hw.wiphy->max_remain_on_channel_duration = 5000;
+ if (local->ops->sched_scan_start)
+ local->hw.wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+
result = wiphy_register(local->hw.wiphy);
if (result < 0)
goto fail_wiphy_register;
@@ -861,8 +871,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
* and we need some headroom for passing the frame to monitor
* interfaces, but never both at the same time.
*/
+#ifndef __CHECKER__
BUILD_BUG_ON(IEEE80211_TX_STATUS_HEADROOM !=
sizeof(struct ieee80211_tx_status_rtap_hdr));
+#endif
local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom,
sizeof(struct ieee80211_tx_status_rtap_hdr));
@@ -879,10 +891,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
local->dynamic_ps_forced_timeout = -1;
- result = sta_info_start(local);
- if (result < 0)
- goto fail_sta_info;
-
result = ieee80211_wep_init(local);
if (result < 0)
wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n",
@@ -945,7 +953,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
rtnl_unlock();
ieee80211_wep_free(local);
sta_info_stop(local);
- fail_sta_info:
destroy_workqueue(local->workqueue);
fail_workqueue:
wiphy_unregister(local->hw.wiphy);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 2a57cc02c61..29e9980c8e6 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -279,57 +279,14 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
*pos++ = 0x00;
- if (sdata->u.mesh.vendor_ie) {
- int len = sdata->u.mesh.vendor_ie_len;
- const u8 *data = sdata->u.mesh.vendor_ie;
+ if (sdata->u.mesh.ie) {
+ int len = sdata->u.mesh.ie_len;
+ const u8 *data = sdata->u.mesh.ie;
if (skb_tailroom(skb) > len)
memcpy(skb_put(skb, len), data, len);
}
}
-u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl)
-{
- /* Use last four bytes of hw addr and interface index as hash index */
- return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex, tbl->hash_rnd)
- & tbl->hash_mask;
-}
-
-struct mesh_table *mesh_table_alloc(int size_order)
-{
- int i;
- struct mesh_table *newtbl;
-
- newtbl = kmalloc(sizeof(struct mesh_table), GFP_KERNEL);
- if (!newtbl)
- return NULL;
-
- newtbl->hash_buckets = kzalloc(sizeof(struct hlist_head) *
- (1 << size_order), GFP_KERNEL);
-
- if (!newtbl->hash_buckets) {
- kfree(newtbl);
- return NULL;
- }
-
- newtbl->hashwlock = kmalloc(sizeof(spinlock_t) *
- (1 << size_order), GFP_KERNEL);
- if (!newtbl->hashwlock) {
- kfree(newtbl->hash_buckets);
- kfree(newtbl);
- return NULL;
- }
-
- newtbl->size_order = size_order;
- newtbl->hash_mask = (1 << size_order) - 1;
- atomic_set(&newtbl->entries, 0);
- get_random_bytes(&newtbl->hash_rnd,
- sizeof(newtbl->hash_rnd));
- for (i = 0; i <= newtbl->hash_mask; i++)
- spin_lock_init(&newtbl->hashwlock[i]);
-
- return newtbl;
-}
-
static void ieee80211_mesh_path_timer(unsigned long data)
{
@@ -573,6 +530,10 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
&elems);
+ /* ignore beacons from secure mesh peers if our security is off */
+ if (elems.rsn_len && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE)
+ return;
+
if (elems.ds_params && elems.ds_params_len == 1)
freq = ieee80211_channel_to_frequency(elems.ds_params[0], band);
else
@@ -586,9 +547,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
if (elems.mesh_id && elems.mesh_config &&
mesh_matches_local(&elems, sdata)) {
supp_rates = ieee80211_sta_get_rates(local, &elems, band);
-
- mesh_neighbour_update(mgmt->sa, supp_rates, sdata,
- mesh_peer_accepts_plinks(&elems));
+ mesh_neighbour_update(mgmt->sa, supp_rates, sdata, &elems);
}
}
@@ -598,7 +557,7 @@ static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
struct ieee80211_rx_status *rx_status)
{
switch (mgmt->u.action.category) {
- case WLAN_CATEGORY_MESH_PLINK:
+ case WLAN_CATEGORY_MESH_ACTION:
mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
break;
case WLAN_CATEGORY_MESH_PATH_SEL:
@@ -611,12 +570,9 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb)
{
struct ieee80211_rx_status *rx_status;
- struct ieee80211_if_mesh *ifmsh;
struct ieee80211_mgmt *mgmt;
u16 stype;
- ifmsh = &sdata->u.mesh;
-
rx_status = IEEE80211_SKB_RXCB(skb);
mgmt = (struct ieee80211_mgmt *) skb->data;
stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index b99e230fe31..e7c5fddb480 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -92,7 +92,7 @@ struct mesh_path {
u8 dst[ETH_ALEN];
u8 mpp[ETH_ALEN]; /* used for MPP or MAP */
struct ieee80211_sub_if_data *sdata;
- struct sta_info *next_hop;
+ struct sta_info __rcu *next_hop;
struct timer_list timer;
struct sk_buff_head frame_queue;
struct rcu_head rcu;
@@ -226,7 +226,8 @@ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata);
/* Mesh plinks */
void mesh_neighbour_update(u8 *hw_addr, u32 rates,
- struct ieee80211_sub_if_data *sdata, bool add);
+ struct ieee80211_sub_if_data *sdata,
+ struct ieee802_11_elems *ie);
bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
void mesh_plink_broken(struct sta_info *sta);
@@ -239,12 +240,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
/* Private interfaces */
/* Mesh tables */
-struct mesh_table *mesh_table_alloc(int size_order);
-void mesh_table_free(struct mesh_table *tbl, bool free_leafs);
void mesh_mpath_table_grow(void);
void mesh_mpp_table_grow(void);
-u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata,
- struct mesh_table *tbl);
/* Mesh paths */
int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, __le16 target_rcode,
const u8 *ra, struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 5bf64d7112b..2b18053070c 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -391,7 +391,6 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
(mpath->flags & MESH_PATH_SN_VALID)) {
if (SN_GT(mpath->sn, orig_sn) ||
(mpath->sn == orig_sn &&
- action == MPATH_PREQ &&
new_metric >= mpath->metric)) {
process = false;
fresh_info = false;
@@ -561,6 +560,14 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
}
+static inline struct sta_info *
+next_hop_deref_protected(struct mesh_path *mpath)
+{
+ return rcu_dereference_protected(mpath->next_hop,
+ lockdep_is_held(&mpath->state_lock));
+}
+
+
static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt,
u8 *prep_elem, u32 metric)
@@ -600,7 +607,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
spin_unlock_bh(&mpath->state_lock);
goto fail;
}
- memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN);
+ memcpy(next_hop, next_hop_deref_protected(mpath)->sta.addr, ETH_ALEN);
spin_unlock_bh(&mpath->state_lock);
--ttl;
flags = PREP_IE_FLAGS(prep_elem);
@@ -633,7 +640,6 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
struct mesh_path *mpath;
u8 ttl;
u8 *ta, *target_addr;
- u8 target_flags;
u32 target_sn;
u16 target_rcode;
@@ -644,7 +650,6 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
return;
}
ttl--;
- target_flags = PERR_IE_TARGET_FLAGS(perr_elem);
target_addr = PERR_IE_TARGET_ADDR(perr_elem);
target_sn = PERR_IE_TARGET_SN(perr_elem);
target_rcode = PERR_IE_TARGET_RCODE(perr_elem);
@@ -654,7 +659,8 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
if (mpath) {
spin_lock_bh(&mpath->state_lock);
if (mpath->flags & MESH_PATH_ACTIVE &&
- memcmp(ta, mpath->next_hop->sta.addr, ETH_ALEN) == 0 &&
+ memcmp(ta, next_hop_deref_protected(mpath)->sta.addr,
+ ETH_ALEN) == 0 &&
(!(mpath->flags & MESH_PATH_SN_VALID) ||
SN_GT(target_sn, mpath->sn))) {
mpath->flags &= ~MESH_PATH_ACTIVE;
@@ -675,12 +681,10 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct mesh_path *mpath;
- u8 *ta;
u8 ttl, flags, hopcount;
u8 *orig_addr;
u32 orig_sn, metric;
- ta = mgmt->sa;
ttl = rann->rann_ttl;
if (ttl <= 1) {
ifmsh->mshstats.dropped_frames_ttl++;
@@ -918,6 +922,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
{
struct sk_buff *skb_to_free = NULL;
struct mesh_path *mpath;
+ struct sta_info *next_hop;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
u8 *target_addr = hdr->addr3;
int err = 0;
@@ -945,7 +950,11 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
mesh_queue_preq(mpath,
PREQ_Q_F_START | PREQ_Q_F_REFRESH);
}
- memcpy(hdr->addr1, mpath->next_hop->sta.addr, ETH_ALEN);
+ next_hop = rcu_dereference(mpath->next_hop);
+ if (next_hop)
+ memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN);
+ else
+ err = -ENOENT;
} else {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
if (!(mpath->flags & MESH_PATH_RESOLVING)) {
@@ -971,20 +980,11 @@ endlookup:
void mesh_path_timer(unsigned long data)
{
- struct ieee80211_sub_if_data *sdata;
- struct mesh_path *mpath;
-
- rcu_read_lock();
- mpath = (struct mesh_path *) data;
- mpath = rcu_dereference(mpath);
- if (!mpath)
- goto endmpathtimer;
- sdata = mpath->sdata;
+ struct mesh_path *mpath = (void *) data;
+ struct ieee80211_sub_if_data *sdata = mpath->sdata;
- if (sdata->local->quiescing) {
- rcu_read_unlock();
+ if (sdata->local->quiescing)
return;
- }
spin_lock_bh(&mpath->state_lock);
if (mpath->flags & MESH_PATH_RESOLVED ||
@@ -1001,8 +1001,6 @@ void mesh_path_timer(unsigned long data)
}
spin_unlock_bh(&mpath->state_lock);
-endmpathtimer:
- rcu_read_unlock();
}
void
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 336ca9d0c5c..83ce48e3191 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -40,6 +40,50 @@ static struct mesh_table *mesh_paths;
static struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */
int mesh_paths_generation;
+
+/* This lock will have the grow table function as writer and add / delete nodes
+ * as readers. When reading the table (i.e. doing lookups) we are well protected
+ * by RCU
+ */
+static DEFINE_RWLOCK(pathtbl_resize_lock);
+
+
+static struct mesh_table *mesh_table_alloc(int size_order)
+{
+ int i;
+ struct mesh_table *newtbl;
+
+ newtbl = kmalloc(sizeof(struct mesh_table), GFP_KERNEL);
+ if (!newtbl)
+ return NULL;
+
+ newtbl->hash_buckets = kzalloc(sizeof(struct hlist_head) *
+ (1 << size_order), GFP_KERNEL);
+
+ if (!newtbl->hash_buckets) {
+ kfree(newtbl);
+ return NULL;
+ }
+
+ newtbl->hashwlock = kmalloc(sizeof(spinlock_t) *
+ (1 << size_order), GFP_KERNEL);
+ if (!newtbl->hashwlock) {
+ kfree(newtbl->hash_buckets);
+ kfree(newtbl);
+ return NULL;
+ }
+
+ newtbl->size_order = size_order;
+ newtbl->hash_mask = (1 << size_order) - 1;
+ atomic_set(&newtbl->entries, 0);
+ get_random_bytes(&newtbl->hash_rnd,
+ sizeof(newtbl->hash_rnd));
+ for (i = 0; i <= newtbl->hash_mask; i++)
+ spin_lock_init(&newtbl->hashwlock[i]);
+
+ return newtbl;
+}
+
static void __mesh_table_free(struct mesh_table *tbl)
{
kfree(tbl->hash_buckets);
@@ -47,7 +91,7 @@ static void __mesh_table_free(struct mesh_table *tbl)
kfree(tbl);
}
-void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
+static void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
{
struct hlist_head *mesh_hash;
struct hlist_node *p, *q;
@@ -55,60 +99,56 @@ void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
mesh_hash = tbl->hash_buckets;
for (i = 0; i <= tbl->hash_mask; i++) {
- spin_lock(&tbl->hashwlock[i]);
+ spin_lock_bh(&tbl->hashwlock[i]);
hlist_for_each_safe(p, q, &mesh_hash[i]) {
tbl->free_node(p, free_leafs);
atomic_dec(&tbl->entries);
}
- spin_unlock(&tbl->hashwlock[i]);
+ spin_unlock_bh(&tbl->hashwlock[i]);
}
__mesh_table_free(tbl);
}
-static struct mesh_table *mesh_table_grow(struct mesh_table *tbl)
+static int mesh_table_grow(struct mesh_table *oldtbl,
+ struct mesh_table *newtbl)
{
- struct mesh_table *newtbl;
struct hlist_head *oldhash;
struct hlist_node *p, *q;
int i;
- if (atomic_read(&tbl->entries)
- < tbl->mean_chain_len * (tbl->hash_mask + 1))
- goto endgrow;
-
- newtbl = mesh_table_alloc(tbl->size_order + 1);
- if (!newtbl)
- goto endgrow;
+ if (atomic_read(&oldtbl->entries)
+ < oldtbl->mean_chain_len * (oldtbl->hash_mask + 1))
+ return -EAGAIN;
- newtbl->free_node = tbl->free_node;
- newtbl->mean_chain_len = tbl->mean_chain_len;
- newtbl->copy_node = tbl->copy_node;
- atomic_set(&newtbl->entries, atomic_read(&tbl->entries));
+ newtbl->free_node = oldtbl->free_node;
+ newtbl->mean_chain_len = oldtbl->mean_chain_len;
+ newtbl->copy_node = oldtbl->copy_node;
+ atomic_set(&newtbl->entries, atomic_read(&oldtbl->entries));
- oldhash = tbl->hash_buckets;
- for (i = 0; i <= tbl->hash_mask; i++)
+ oldhash = oldtbl->hash_buckets;
+ for (i = 0; i <= oldtbl->hash_mask; i++)
hlist_for_each(p, &oldhash[i])
- if (tbl->copy_node(p, newtbl) < 0)
+ if (oldtbl->copy_node(p, newtbl) < 0)
goto errcopy;
- return newtbl;
+ return 0;
errcopy:
for (i = 0; i <= newtbl->hash_mask; i++) {
hlist_for_each_safe(p, q, &newtbl->hash_buckets[i])
- tbl->free_node(p, 0);
+ oldtbl->free_node(p, 0);
}
- __mesh_table_free(newtbl);
-endgrow:
- return NULL;
+ return -ENOMEM;
}
+static u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata,
+ struct mesh_table *tbl)
+{
+ /* Use last four bytes of hw addr and interface index as hash index */
+ return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex, tbl->hash_rnd)
+ & tbl->hash_mask;
+}
-/* This lock will have the grow table function as writer and add / delete nodes
- * as readers. When reading the table (i.e. doing lookups) we are well protected
- * by RCU
- */
-static DEFINE_RWLOCK(pathtbl_resize_lock);
/**
*
@@ -280,7 +320,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
if (!new_node)
goto err_node_alloc;
- read_lock(&pathtbl_resize_lock);
+ read_lock_bh(&pathtbl_resize_lock);
memcpy(new_mpath->dst, dst, ETH_ALEN);
new_mpath->sdata = sdata;
new_mpath->flags = 0;
@@ -295,7 +335,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
hash_idx = mesh_table_hash(dst, sdata, mesh_paths);
bucket = &mesh_paths->hash_buckets[hash_idx];
- spin_lock(&mesh_paths->hashwlock[hash_idx]);
+ spin_lock_bh(&mesh_paths->hashwlock[hash_idx]);
err = -EEXIST;
hlist_for_each_entry(node, n, bucket, list) {
@@ -311,8 +351,8 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
mesh_paths_generation++;
- spin_unlock(&mesh_paths->hashwlock[hash_idx]);
- read_unlock(&pathtbl_resize_lock);
+ spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]);
+ read_unlock_bh(&pathtbl_resize_lock);
if (grow) {
set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags);
ieee80211_queue_work(&local->hw, &sdata->work);
@@ -320,8 +360,8 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
return 0;
err_exists:
- spin_unlock(&mesh_paths->hashwlock[hash_idx]);
- read_unlock(&pathtbl_resize_lock);
+ spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]);
+ read_unlock_bh(&pathtbl_resize_lock);
kfree(new_node);
err_node_alloc:
kfree(new_mpath);
@@ -334,15 +374,21 @@ void mesh_mpath_table_grow(void)
{
struct mesh_table *oldtbl, *newtbl;
- write_lock(&pathtbl_resize_lock);
+ rcu_read_lock();
+ newtbl = mesh_table_alloc(rcu_dereference(mesh_paths)->size_order + 1);
+ if (!newtbl)
+ return;
+ write_lock_bh(&pathtbl_resize_lock);
oldtbl = mesh_paths;
- newtbl = mesh_table_grow(mesh_paths);
- if (!newtbl) {
- write_unlock(&pathtbl_resize_lock);
+ if (mesh_table_grow(mesh_paths, newtbl) < 0) {
+ rcu_read_unlock();
+ __mesh_table_free(newtbl);
+ write_unlock_bh(&pathtbl_resize_lock);
return;
}
+ rcu_read_unlock();
rcu_assign_pointer(mesh_paths, newtbl);
- write_unlock(&pathtbl_resize_lock);
+ write_unlock_bh(&pathtbl_resize_lock);
synchronize_rcu();
mesh_table_free(oldtbl, false);
@@ -352,15 +398,21 @@ void mesh_mpp_table_grow(void)
{
struct mesh_table *oldtbl, *newtbl;
- write_lock(&pathtbl_resize_lock);
+ rcu_read_lock();
+ newtbl = mesh_table_alloc(rcu_dereference(mpp_paths)->size_order + 1);
+ if (!newtbl)
+ return;
+ write_lock_bh(&pathtbl_resize_lock);
oldtbl = mpp_paths;
- newtbl = mesh_table_grow(mpp_paths);
- if (!newtbl) {
- write_unlock(&pathtbl_resize_lock);
+ if (mesh_table_grow(mpp_paths, newtbl) < 0) {
+ rcu_read_unlock();
+ __mesh_table_free(newtbl);
+ write_unlock_bh(&pathtbl_resize_lock);
return;
}
+ rcu_read_unlock();
rcu_assign_pointer(mpp_paths, newtbl);
- write_unlock(&pathtbl_resize_lock);
+ write_unlock_bh(&pathtbl_resize_lock);
synchronize_rcu();
mesh_table_free(oldtbl, false);
@@ -394,7 +446,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
if (!new_node)
goto err_node_alloc;
- read_lock(&pathtbl_resize_lock);
+ read_lock_bh(&pathtbl_resize_lock);
memcpy(new_mpath->dst, dst, ETH_ALEN);
memcpy(new_mpath->mpp, mpp, ETH_ALEN);
new_mpath->sdata = sdata;
@@ -407,7 +459,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
hash_idx = mesh_table_hash(dst, sdata, mpp_paths);
bucket = &mpp_paths->hash_buckets[hash_idx];
- spin_lock(&mpp_paths->hashwlock[hash_idx]);
+ spin_lock_bh(&mpp_paths->hashwlock[hash_idx]);
err = -EEXIST;
hlist_for_each_entry(node, n, bucket, list) {
@@ -421,8 +473,8 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
mpp_paths->mean_chain_len * (mpp_paths->hash_mask + 1))
grow = 1;
- spin_unlock(&mpp_paths->hashwlock[hash_idx]);
- read_unlock(&pathtbl_resize_lock);
+ spin_unlock_bh(&mpp_paths->hashwlock[hash_idx]);
+ read_unlock_bh(&pathtbl_resize_lock);
if (grow) {
set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags);
ieee80211_queue_work(&local->hw, &sdata->work);
@@ -430,8 +482,8 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
return 0;
err_exists:
- spin_unlock(&mpp_paths->hashwlock[hash_idx]);
- read_unlock(&pathtbl_resize_lock);
+ spin_unlock_bh(&mpp_paths->hashwlock[hash_idx]);
+ read_unlock_bh(&pathtbl_resize_lock);
kfree(new_node);
err_node_alloc:
kfree(new_mpath);
@@ -544,11 +596,11 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
int hash_idx;
int err = 0;
- read_lock(&pathtbl_resize_lock);
+ read_lock_bh(&pathtbl_resize_lock);
hash_idx = mesh_table_hash(addr, sdata, mesh_paths);
bucket = &mesh_paths->hash_buckets[hash_idx];
- spin_lock(&mesh_paths->hashwlock[hash_idx]);
+ spin_lock_bh(&mesh_paths->hashwlock[hash_idx]);
hlist_for_each_entry(node, n, bucket, list) {
mpath = node->mpath;
if (mpath->sdata == sdata &&
@@ -566,8 +618,8 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
err = -ENXIO;
enddel:
mesh_paths_generation++;
- spin_unlock(&mesh_paths->hashwlock[hash_idx]);
- read_unlock(&pathtbl_resize_lock);
+ spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]);
+ read_unlock_bh(&pathtbl_resize_lock);
return err;
}
@@ -719,7 +771,7 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
struct hlist_node *p;
int i;
- read_lock(&pathtbl_resize_lock);
+ read_lock_bh(&pathtbl_resize_lock);
for_each_mesh_entry(mesh_paths, p, node, i) {
if (node->mpath->sdata != sdata)
continue;
@@ -734,7 +786,7 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
} else
spin_unlock_bh(&mpath->state_lock);
}
- read_unlock(&pathtbl_resize_lock);
+ read_unlock_bh(&pathtbl_resize_lock);
}
void mesh_pathtbl_unregister(void)
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 44b53931ba5..f4adc091788 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -43,7 +43,7 @@
#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
enum plink_frame_type {
- PLINK_OPEN = 0,
+ PLINK_OPEN = 1,
PLINK_CONFIRM,
PLINK_CLOSE
};
@@ -83,7 +83,7 @@ void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
*/
static inline void mesh_plink_fsm_restart(struct sta_info *sta)
{
- sta->plink_state = PLINK_LISTEN;
+ sta->plink_state = NL80211_PLINK_LISTEN;
sta->llid = sta->plid = sta->reason = 0;
sta->plink_retries = 0;
}
@@ -105,7 +105,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
if (!sta)
return NULL;
- sta->flags = WLAN_STA_AUTHORIZED;
+ sta->flags = WLAN_STA_AUTHORIZED | WLAN_STA_AUTH;
sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
rate_control_rate_init(sta);
@@ -126,11 +126,11 @@ static bool __mesh_plink_deactivate(struct sta_info *sta)
struct ieee80211_sub_if_data *sdata = sta->sdata;
bool deactivated = false;
- if (sta->plink_state == PLINK_ESTAB) {
+ if (sta->plink_state == NL80211_PLINK_ESTAB) {
mesh_plink_dec_estab_count(sdata);
deactivated = true;
}
- sta->plink_state = PLINK_BLOCKED;
+ sta->plink_state = NL80211_PLINK_BLOCKED;
mesh_path_flush_by_nexthop(sta);
return deactivated;
@@ -161,7 +161,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
__le16 reason) {
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
- sdata->u.mesh.vendor_ie_len);
+ sdata->u.mesh.ie_len);
struct ieee80211_mgmt *mgmt;
bool include_plid = false;
static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A };
@@ -181,8 +181,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
IEEE80211_STYPE_ACTION);
memcpy(mgmt->da, da, ETH_ALEN);
memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
- /* BSSID is left zeroed, wildcard value */
- mgmt->u.action.category = WLAN_CATEGORY_MESH_PLINK;
+ memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
+ mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
mgmt->u.action.u.plink_action.action_code = action;
if (action == PLINK_CLOSE)
@@ -237,8 +237,9 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
return 0;
}
-void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data *sdata,
- bool peer_accepting_plinks)
+void mesh_neighbour_update(u8 *hw_addr, u32 rates,
+ struct ieee80211_sub_if_data *sdata,
+ struct ieee802_11_elems *elems)
{
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
@@ -248,8 +249,14 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data
sta = sta_info_get(sdata, hw_addr);
if (!sta) {
rcu_read_unlock();
-
- sta = mesh_plink_alloc(sdata, hw_addr, rates);
+ /* Userspace handles peer allocation when security is enabled
+ * */
+ if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED)
+ cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr,
+ elems->ie_start, elems->total_len,
+ GFP_KERNEL);
+ else
+ sta = mesh_plink_alloc(sdata, hw_addr, rates);
if (!sta)
return;
if (sta_info_insert_rcu(sta)) {
@@ -260,7 +267,8 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data
sta->last_rx = jiffies;
sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
- if (peer_accepting_plinks && sta->plink_state == PLINK_LISTEN &&
+ if (mesh_peer_accepts_plinks(elems) &&
+ sta->plink_state == NL80211_PLINK_LISTEN &&
sdata->u.mesh.accepting_plinks &&
sdata->u.mesh.mshcfg.auto_open_plinks)
mesh_plink_open(sta);
@@ -300,8 +308,8 @@ static void mesh_plink_timer(unsigned long data)
sdata = sta->sdata;
switch (sta->plink_state) {
- case PLINK_OPN_RCVD:
- case PLINK_OPN_SNT:
+ case NL80211_PLINK_OPN_RCVD:
+ case NL80211_PLINK_OPN_SNT:
/* retry timer */
if (sta->plink_retries < dot11MeshMaxRetries(sdata)) {
u32 rand;
@@ -320,17 +328,17 @@ static void mesh_plink_timer(unsigned long data)
}
reason = cpu_to_le16(MESH_MAX_RETRIES);
/* fall through on else */
- case PLINK_CNF_RCVD:
+ case NL80211_PLINK_CNF_RCVD:
/* confirm timer */
if (!reason)
reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT);
- sta->plink_state = PLINK_HOLDING;
+ sta->plink_state = NL80211_PLINK_HOLDING;
mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
spin_unlock_bh(&sta->lock);
mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, plid,
reason);
break;
- case PLINK_HOLDING:
+ case NL80211_PLINK_HOLDING:
/* holding timer */
del_timer(&sta->plink_timer);
mesh_plink_fsm_restart(sta);
@@ -372,14 +380,17 @@ int mesh_plink_open(struct sta_info *sta)
__le16 llid;
struct ieee80211_sub_if_data *sdata = sta->sdata;
+ if (!test_sta_flags(sta, WLAN_STA_AUTH))
+ return -EPERM;
+
spin_lock_bh(&sta->lock);
get_random_bytes(&llid, 2);
sta->llid = llid;
- if (sta->plink_state != PLINK_LISTEN) {
+ if (sta->plink_state != NL80211_PLINK_LISTEN) {
spin_unlock_bh(&sta->lock);
return -EBUSY;
}
- sta->plink_state = PLINK_OPN_SNT;
+ sta->plink_state = NL80211_PLINK_OPN_SNT;
mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
spin_unlock_bh(&sta->lock);
mpl_dbg("Mesh plink: starting establishment with %pM\n",
@@ -396,7 +407,7 @@ void mesh_plink_block(struct sta_info *sta)
spin_lock_bh(&sta->lock);
deactivated = __mesh_plink_deactivate(sta);
- sta->plink_state = PLINK_BLOCKED;
+ sta->plink_state = NL80211_PLINK_BLOCKED;
spin_unlock_bh(&sta->lock);
if (deactivated)
@@ -419,13 +430,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
__le16 plid, llid, reason;
#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
static const char *mplstates[] = {
- [PLINK_LISTEN] = "LISTEN",
- [PLINK_OPN_SNT] = "OPN-SNT",
- [PLINK_OPN_RCVD] = "OPN-RCVD",
- [PLINK_CNF_RCVD] = "CNF_RCVD",
- [PLINK_ESTAB] = "ESTAB",
- [PLINK_HOLDING] = "HOLDING",
- [PLINK_BLOCKED] = "BLOCKED"
+ [NL80211_PLINK_LISTEN] = "LISTEN",
+ [NL80211_PLINK_OPN_SNT] = "OPN-SNT",
+ [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD",
+ [NL80211_PLINK_CNF_RCVD] = "CNF_RCVD",
+ [NL80211_PLINK_ESTAB] = "ESTAB",
+ [NL80211_PLINK_HOLDING] = "HOLDING",
+ [NL80211_PLINK_BLOCKED] = "BLOCKED"
};
#endif
@@ -449,6 +460,11 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
mpl_dbg("Mesh plink: missing necessary peer link ie\n");
return;
}
+ if (elems.rsn_len &&
+ sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
+ mpl_dbg("Mesh plink: can't establish link with secure peer\n");
+ return;
+ }
ftype = mgmt->u.action.u.plink_action.action_code;
ie_len = elems.peer_link_len;
@@ -480,7 +496,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
return;
}
- if (sta && sta->plink_state == PLINK_BLOCKED) {
+ if (sta && !test_sta_flags(sta, WLAN_STA_AUTH)) {
+ mpl_dbg("Mesh plink: Action frame from non-authed peer\n");
+ rcu_read_unlock();
+ return;
+ }
+
+ if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) {
rcu_read_unlock();
return;
}
@@ -550,7 +572,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
event = CNF_ACPT;
break;
case PLINK_CLOSE:
- if (sta->plink_state == PLINK_ESTAB)
+ if (sta->plink_state == NL80211_PLINK_ESTAB)
/* Do not check for llid or plid. This does not
* follow the standard but since multiple plinks
* per sta are not supported, it is necessary in
@@ -585,14 +607,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
reason = 0;
switch (sta->plink_state) {
/* spin_unlock as soon as state is updated at each case */
- case PLINK_LISTEN:
+ case NL80211_PLINK_LISTEN:
switch (event) {
case CLS_ACPT:
mesh_plink_fsm_restart(sta);
spin_unlock_bh(&sta->lock);
break;
case OPN_ACPT:
- sta->plink_state = PLINK_OPN_RCVD;
+ sta->plink_state = NL80211_PLINK_OPN_RCVD;
sta->plid = plid;
get_random_bytes(&llid, 2);
sta->llid = llid;
@@ -609,7 +631,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
}
break;
- case PLINK_OPN_SNT:
+ case NL80211_PLINK_OPN_SNT:
switch (event) {
case OPN_RJCT:
case CNF_RJCT:
@@ -618,7 +640,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
if (!reason)
reason = cpu_to_le16(MESH_CLOSE_RCVD);
sta->reason = reason;
- sta->plink_state = PLINK_HOLDING;
+ sta->plink_state = NL80211_PLINK_HOLDING;
if (!mod_plink_timer(sta,
dot11MeshHoldingTimeout(sdata)))
sta->ignore_plink_timer = true;
@@ -630,7 +652,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
break;
case OPN_ACPT:
/* retry timer is left untouched */
- sta->plink_state = PLINK_OPN_RCVD;
+ sta->plink_state = NL80211_PLINK_OPN_RCVD;
sta->plid = plid;
llid = sta->llid;
spin_unlock_bh(&sta->lock);
@@ -638,7 +660,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
plid, 0);
break;
case CNF_ACPT:
- sta->plink_state = PLINK_CNF_RCVD;
+ sta->plink_state = NL80211_PLINK_CNF_RCVD;
if (!mod_plink_timer(sta,
dot11MeshConfirmTimeout(sdata)))
sta->ignore_plink_timer = true;
@@ -651,7 +673,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
}
break;
- case PLINK_OPN_RCVD:
+ case NL80211_PLINK_OPN_RCVD:
switch (event) {
case OPN_RJCT:
case CNF_RJCT:
@@ -660,7 +682,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
if (!reason)
reason = cpu_to_le16(MESH_CLOSE_RCVD);
sta->reason = reason;
- sta->plink_state = PLINK_HOLDING;
+ sta->plink_state = NL80211_PLINK_HOLDING;
if (!mod_plink_timer(sta,
dot11MeshHoldingTimeout(sdata)))
sta->ignore_plink_timer = true;
@@ -678,7 +700,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
break;
case CNF_ACPT:
del_timer(&sta->plink_timer);
- sta->plink_state = PLINK_ESTAB;
+ sta->plink_state = NL80211_PLINK_ESTAB;
spin_unlock_bh(&sta->lock);
mesh_plink_inc_estab_count(sdata);
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
@@ -691,7 +713,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
}
break;
- case PLINK_CNF_RCVD:
+ case NL80211_PLINK_CNF_RCVD:
switch (event) {
case OPN_RJCT:
case CNF_RJCT:
@@ -700,7 +722,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
if (!reason)
reason = cpu_to_le16(MESH_CLOSE_RCVD);
sta->reason = reason;
- sta->plink_state = PLINK_HOLDING;
+ sta->plink_state = NL80211_PLINK_HOLDING;
if (!mod_plink_timer(sta,
dot11MeshHoldingTimeout(sdata)))
sta->ignore_plink_timer = true;
@@ -712,7 +734,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
break;
case OPN_ACPT:
del_timer(&sta->plink_timer);
- sta->plink_state = PLINK_ESTAB;
+ sta->plink_state = NL80211_PLINK_ESTAB;
spin_unlock_bh(&sta->lock);
mesh_plink_inc_estab_count(sdata);
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
@@ -727,13 +749,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
}
break;
- case PLINK_ESTAB:
+ case NL80211_PLINK_ESTAB:
switch (event) {
case CLS_ACPT:
reason = cpu_to_le16(MESH_CLOSE_RCVD);
sta->reason = reason;
deactivated = __mesh_plink_deactivate(sta);
- sta->plink_state = PLINK_HOLDING;
+ sta->plink_state = NL80211_PLINK_HOLDING;
llid = sta->llid;
mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
spin_unlock_bh(&sta->lock);
@@ -753,7 +775,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
break;
}
break;
- case PLINK_HOLDING:
+ case NL80211_PLINK_HOLDING:
switch (event) {
case CLS_ACPT:
if (del_timer(&sta->plink_timer))
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 64d92d5a7f4..4f6b2675e41 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -90,20 +90,11 @@ enum rx_mgmt_action {
/* no action required */
RX_MGMT_NONE,
- /* caller must call cfg80211_send_rx_auth() */
- RX_MGMT_CFG80211_AUTH,
-
- /* caller must call cfg80211_send_rx_assoc() */
- RX_MGMT_CFG80211_ASSOC,
-
/* caller must call cfg80211_send_deauth() */
RX_MGMT_CFG80211_DEAUTH,
/* caller must call cfg80211_send_disassoc() */
RX_MGMT_CFG80211_DISASSOC,
-
- /* caller must tell cfg80211 about internal error */
- RX_MGMT_CFG80211_ASSOC_ERROR,
};
/* utils */
@@ -759,6 +750,8 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
dynamic_ps_enable_work);
struct ieee80211_sub_if_data *sdata = local->ps_sdata;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+ unsigned long flags;
+ int q;
/* can only happen when PS was just disabled anyway */
if (!sdata)
@@ -767,18 +760,37 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
if (local->hw.conf.flags & IEEE80211_CONF_PS)
return;
+ /*
+ * transmission can be stopped by others which leads to
+ * dynamic_ps_timer expiry. Postpond the ps timer if it
+ * is not the actual idle state.
+ */
+ spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
+ for (q = 0; q < local->hw.queues; q++) {
+ if (local->queue_stop_reasons[q]) {
+ spin_unlock_irqrestore(&local->queue_stop_reason_lock,
+ flags);
+ mod_timer(&local->dynamic_ps_timer, jiffies +
+ msecs_to_jiffies(
+ local->hw.conf.dynamic_ps_timeout));
+ return;
+ }
+ }
+ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+
if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
(!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) {
netif_tx_stop_all_queues(sdata->dev);
- /*
- * Flush all the frames queued in the driver before
- * going to power save
- */
- drv_flush(local, false);
- ieee80211_send_nullfunc(local, sdata, 1);
- /* Flush once again to get the tx status of nullfunc frame */
- drv_flush(local, false);
+ if (drv_tx_frames_pending(local))
+ mod_timer(&local->dynamic_ps_timer, jiffies +
+ msecs_to_jiffies(
+ local->hw.conf.dynamic_ps_timeout));
+ else {
+ ieee80211_send_nullfunc(local, sdata, 1);
+ /* Flush to get the tx status of nullfunc frame */
+ drv_flush(local, false);
+ }
}
if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
@@ -789,7 +801,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
}
- netif_tx_start_all_queues(sdata->dev);
+ netif_tx_wake_all_queues(sdata->dev);
}
void ieee80211_dynamic_ps_timer(unsigned long data)
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index e37355193ed..730778a2c90 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -6,7 +6,7 @@
#include "driver-ops.h"
#include "led.h"
-int __ieee80211_suspend(struct ieee80211_hw *hw)
+int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
{
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_sub_if_data *sdata;
@@ -14,12 +14,23 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
ieee80211_scan_cancel(local);
+ if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
+ mutex_lock(&local->sta_mtx);
+ list_for_each_entry(sta, &local->sta_list, list) {
+ set_sta_flags(sta, WLAN_STA_BLOCK_BA);
+ ieee80211_sta_tear_down_BA_sessions(sta, true);
+ }
+ mutex_unlock(&local->sta_mtx);
+ }
+
ieee80211_stop_queues_by_reason(hw,
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
/* flush out all packets */
synchronize_net();
+ drv_flush(local, false);
+
local->quiescing = true;
/* make quiescing visible to timers everywhere */
mb();
@@ -36,6 +47,16 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
cancel_work_sync(&local->dynamic_ps_enable_work);
del_timer_sync(&local->dynamic_ps_timer);
+ local->wowlan = wowlan && local->open_count;
+ if (local->wowlan) {
+ int err = drv_suspend(local, wowlan);
+ if (err) {
+ local->quiescing = false;
+ return err;
+ }
+ goto suspend;
+ }
+
/* disable keys */
list_for_each_entry(sdata, &local->interfaces, list)
ieee80211_disable_keys(sdata);
@@ -43,11 +64,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
/* tear down aggregation sessions and remove STAs */
mutex_lock(&local->sta_mtx);
list_for_each_entry(sta, &local->sta_list, list) {
- if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
- set_sta_flags(sta, WLAN_STA_BLOCK_BA);
- ieee80211_sta_tear_down_BA_sessions(sta, true);
- }
-
if (sta->uploaded) {
sdata = sta->sdata;
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
@@ -98,6 +114,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
if (local->open_count)
ieee80211_stop_device(local);
+ suspend:
local->suspended = true;
/* need suspended to be visible before quiescing is false */
barrier();
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 778c604d793..8adac67395f 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -417,8 +417,8 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
tx_time_single = mr->ack_time + mr->perfect_tx_time;
/* contention window */
- tx_time_single += t_slot + min(cw, mp->cw_max);
- cw = (cw << 1) | 1;
+ tx_time_single += (t_slot * cw) >> 1;
+ cw = min((cw << 1) | 1, mp->cw_max);
tx_time += tx_time_single;
tx_time_cts += tx_time_single + mi->sp_ack_dur;
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index c06aa3ac6b9..333b5118be6 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -464,6 +464,7 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
const struct mcs_group *group;
unsigned int tx_time, tx_time_rtscts, tx_time_data;
unsigned int cw = mp->cw_min;
+ unsigned int ctime = 0;
unsigned int t_slot = 9; /* FIXME */
unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len);
@@ -480,13 +481,27 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len;
- tx_time = 2 * (t_slot + mi->overhead + tx_time_data);
- tx_time_rtscts = 2 * (t_slot + mi->overhead_rtscts + tx_time_data);
+
+ /* Contention time for first 2 tries */
+ ctime = (t_slot * cw) >> 1;
+ cw = min((cw << 1) | 1, mp->cw_max);
+ ctime += (t_slot * cw) >> 1;
+ cw = min((cw << 1) | 1, mp->cw_max);
+
+ /* Total TX time for data and Contention after first 2 tries */
+ tx_time = ctime + 2 * (mi->overhead + tx_time_data);
+ tx_time_rtscts = ctime + 2 * (mi->overhead_rtscts + tx_time_data);
+
+ /* See how many more tries we can fit inside segment size */
do {
- cw = (cw << 1) | 1;
- cw = min(cw, mp->cw_max);
- tx_time += cw + t_slot + mi->overhead;
- tx_time_rtscts += cw + t_slot + mi->overhead_rtscts;
+ /* Contention time for this try */
+ ctime = (t_slot * cw) >> 1;
+ cw = min((cw << 1) | 1, mp->cw_max);
+
+ /* Total TX time after this try */
+ tx_time += ctime + mi->overhead + tx_time_data;
+ tx_time_rtscts += ctime + mi->overhead_rtscts + tx_time_data;
+
if (tx_time_rtscts < mp->segment_size)
mr->retry_count_rtscts++;
} while ((tx_time < mp->segment_size) &&
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c5d4530d828..7fa8c6be7bf 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -143,7 +143,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
if (status->flag & RX_FLAG_HT) {
/*
* MCS information is a separate field in radiotap,
- * added below.
+ * added below. The byte here is needed as padding
+ * for the channel though, so initialise it to 0.
*/
*pos = 0;
} else {
@@ -403,11 +404,13 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
struct sk_buff *skb = rx->skb;
- if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN)))
+ if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN) &&
+ !local->sched_scanning))
return RX_CONTINUE;
if (test_bit(SCAN_HW_SCANNING, &local->scanning) ||
- test_bit(SCAN_SW_SCANNING, &local->scanning))
+ test_bit(SCAN_SW_SCANNING, &local->scanning) ||
+ local->sched_scanning)
return ieee80211_scan_rx(rx->sdata, skb);
/* scanning finished during invoking of handlers */
@@ -487,22 +490,26 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
* establisment frame, beacon or probe, drop the frame.
*/
- if (!rx->sta || sta_plink_state(rx->sta) != PLINK_ESTAB) {
+ if (!rx->sta || sta_plink_state(rx->sta) != NL80211_PLINK_ESTAB) {
struct ieee80211_mgmt *mgmt;
if (!ieee80211_is_mgmt(hdr->frame_control))
return RX_DROP_MONITOR;
if (ieee80211_is_action(hdr->frame_control)) {
+ u8 category;
mgmt = (struct ieee80211_mgmt *)hdr;
- if (mgmt->u.action.category != WLAN_CATEGORY_MESH_PLINK)
+ category = mgmt->u.action.category;
+ if (category != WLAN_CATEGORY_MESH_ACTION &&
+ category != WLAN_CATEGORY_SELF_PROTECTED)
return RX_DROP_MONITOR;
return RX_CONTINUE;
}
if (ieee80211_is_probe_req(hdr->frame_control) ||
ieee80211_is_probe_resp(hdr->frame_control) ||
- ieee80211_is_beacon(hdr->frame_control))
+ ieee80211_is_beacon(hdr->frame_control) ||
+ ieee80211_is_auth(hdr->frame_control))
return RX_CONTINUE;
return RX_DROP_MONITOR;
@@ -650,7 +657,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
set_release_timer:
mod_timer(&tid_agg_rx->reorder_timer,
- tid_agg_rx->reorder_time[j] +
+ tid_agg_rx->reorder_time[j] + 1 +
HT_RX_REORDER_BUF_TIMEOUT);
} else {
del_timer(&tid_agg_rx->reorder_timer);
@@ -707,6 +714,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
/*
* If the current MPDU is in the right order and nothing else
* is stored we can process it directly, no need to buffer it.
+ * If it is first but there's something stored, we may be able
+ * to release frames after this one.
*/
if (mpdu_seq_num == tid_agg_rx->head_seq_num &&
tid_agg_rx->stored_mpdu_num == 0) {
@@ -1583,7 +1592,7 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
}
static int
-__ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
+__ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control)
{
struct ieee80211_sub_if_data *sdata = rx->sdata;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
@@ -1591,6 +1600,7 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
struct ethhdr *ehdr;
int ret;
+ *port_control = false;
if (ieee80211_has_a4(hdr->frame_control) &&
sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta)
return -1;
@@ -1609,11 +1619,13 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
return -1;
ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type);
- if (ret < 0 || !check_port_control)
+ if (ret < 0)
return ret;
ehdr = (struct ethhdr *) rx->skb->data;
- if (ehdr->h_proto != rx->sdata->control_port_protocol)
+ if (ehdr->h_proto == rx->sdata->control_port_protocol)
+ *port_control = true;
+ else if (check_port_control)
return -1;
return 0;
@@ -1771,7 +1783,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
rx->sdata->vif.type,
- rx->local->hw.extra_tx_headroom);
+ rx->local->hw.extra_tx_headroom, true);
while (!skb_queue_empty(&frame_list)) {
rx->skb = __skb_dequeue(&frame_list);
@@ -1914,6 +1926,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
struct net_device *dev = sdata->dev;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
__le16 fc = hdr->frame_control;
+ bool port_control;
int err;
if (unlikely(!ieee80211_is_data(hdr->frame_control)))
@@ -1930,13 +1943,21 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
sdata->vif.type == NL80211_IFTYPE_AP)
return RX_DROP_MONITOR;
- err = __ieee80211_data_to_8023(rx);
+ err = __ieee80211_data_to_8023(rx, &port_control);
if (unlikely(err))
return RX_DROP_UNUSABLE;
if (!ieee80211_frame_allowed(rx, fc))
return RX_DROP_MONITOR;
+ if (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
+ unlikely(port_control) && sdata->bss) {
+ sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
+ u.ap);
+ dev = sdata->dev;
+ rx->sdata = sdata;
+ }
+
rx->skb->dev = dev;
dev->stats.rx_packets++;
@@ -2189,7 +2210,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
goto handled;
}
break;
- case WLAN_CATEGORY_MESH_PLINK:
+ case WLAN_CATEGORY_MESH_ACTION:
if (!ieee80211_vif_is_mesh(&sdata->vif))
break;
goto queue;
@@ -2352,47 +2373,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
return RX_QUEUED;
}
-static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr,
- struct ieee80211_rx_data *rx)
-{
- int keyidx;
- unsigned int hdrlen;
-
- hdrlen = ieee80211_hdrlen(hdr->frame_control);
- if (rx->skb->len >= hdrlen + 4)
- keyidx = rx->skb->data[hdrlen + 3] >> 6;
- else
- keyidx = -1;
-
- if (!rx->sta) {
- /*
- * Some hardware seem to generate incorrect Michael MIC
- * reports; ignore them to avoid triggering countermeasures.
- */
- return;
- }
-
- if (!ieee80211_has_protected(hdr->frame_control))
- return;
-
- if (rx->sdata->vif.type == NL80211_IFTYPE_AP && keyidx) {
- /*
- * APs with pairwise keys should never receive Michael MIC
- * errors for non-zero keyidx because these are reserved for
- * group keys and only the AP is sending real multicast
- * frames in the BSS.
- */
- return;
- }
-
- if (!ieee80211_is_data(hdr->frame_control) &&
- !ieee80211_is_auth(hdr->frame_control))
- return;
-
- mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL,
- GFP_ATOMIC);
-}
-
/* TODO: use IEEE80211_RX_FRAGMENTED */
static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
struct ieee80211_rate *rate)
@@ -2736,12 +2716,6 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
if (!prepares)
return false;
- if (status->flag & RX_FLAG_MMIC_ERROR) {
- if (status->rx_flags & IEEE80211_RX_RA_MATCH)
- ieee80211_rx_michael_mic_report(hdr, rx);
- return false;
- }
-
if (!consume) {
skb = skb_copy(skb, GFP_ATOMIC);
if (!skb) {
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 489b6ad200d..d20046b5d8f 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -15,6 +15,7 @@
#include <linux/if_arp.h>
#include <linux/rtnetlink.h>
#include <linux/pm_qos_params.h>
+#include <linux/slab.h>
#include <net/sch_generic.h>
#include <linux/slab.h>
#include <net/mac80211.h>
@@ -170,7 +171,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
return RX_CONTINUE;
if (skb->len < 24)
- return RX_DROP_MONITOR;
+ return RX_CONTINUE;
presp = ieee80211_is_probe_resp(fc);
if (presp) {
@@ -850,3 +851,122 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
}
mutex_unlock(&local->mtx);
}
+
+int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_sched_scan_request *req)
+{
+ struct ieee80211_local *local = sdata->local;
+ int ret, i;
+
+ mutex_lock(&sdata->local->mtx);
+
+ if (local->sched_scanning) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ if (!local->ops->sched_scan_start) {
+ ret = -ENOTSUPP;
+ goto out;
+ }
+
+ for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
+ local->sched_scan_ies.ie[i] = kzalloc(2 +
+ IEEE80211_MAX_SSID_LEN +
+ local->scan_ies_len,
+ GFP_KERNEL);
+ if (!local->sched_scan_ies.ie[i]) {
+ ret = -ENOMEM;
+ goto out_free;
+ }
+
+ local->sched_scan_ies.len[i] =
+ ieee80211_build_preq_ies(local,
+ local->sched_scan_ies.ie[i],
+ req->ie, req->ie_len, i,
+ (u32) -1, 0);
+ }
+
+ ret = drv_sched_scan_start(local, sdata, req,
+ &local->sched_scan_ies);
+ if (ret == 0) {
+ local->sched_scanning = true;
+ goto out;
+ }
+
+out_free:
+ while (i > 0)
+ kfree(local->sched_scan_ies.ie[--i]);
+out:
+ mutex_unlock(&sdata->local->mtx);
+ return ret;
+}
+
+int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_local *local = sdata->local;
+ int ret = 0, i;
+
+ mutex_lock(&sdata->local->mtx);
+
+ if (!local->ops->sched_scan_stop) {
+ ret = -ENOTSUPP;
+ goto out;
+ }
+
+ if (local->sched_scanning) {
+ for (i = 0; i < IEEE80211_NUM_BANDS; i++)
+ kfree(local->sched_scan_ies.ie[i]);
+
+ drv_sched_scan_stop(local, sdata);
+ local->sched_scanning = false;
+ }
+out:
+ mutex_unlock(&sdata->local->mtx);
+
+ return ret;
+}
+
+void ieee80211_sched_scan_results(struct ieee80211_hw *hw)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+
+ trace_api_sched_scan_results(local);
+
+ cfg80211_sched_scan_results(hw->wiphy);
+}
+EXPORT_SYMBOL(ieee80211_sched_scan_results);
+
+void ieee80211_sched_scan_stopped_work(struct work_struct *work)
+{
+ struct ieee80211_local *local =
+ container_of(work, struct ieee80211_local,
+ sched_scan_stopped_work);
+ int i;
+
+ mutex_lock(&local->mtx);
+
+ if (!local->sched_scanning) {
+ mutex_unlock(&local->mtx);
+ return;
+ }
+
+ for (i = 0; i < IEEE80211_NUM_BANDS; i++)
+ kfree(local->sched_scan_ies.ie[i]);
+
+ local->sched_scanning = false;
+
+ mutex_unlock(&local->mtx);
+
+ cfg80211_sched_scan_stopped(local->hw.wiphy);
+}
+
+void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+
+ trace_api_sched_scan_stopped(local);
+
+ ieee80211_queue_work(&local->hw, &local->sched_scan_stopped_work);
+}
+EXPORT_SYMBOL(ieee80211_sched_scan_stopped);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 13e8c30adf0..b83870bf60f 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -67,7 +67,8 @@ static int sta_info_hash_del(struct ieee80211_local *local,
{
struct sta_info *s;
- s = local->sta_hash[STA_HASH(sta->sta.addr)];
+ s = rcu_dereference_protected(local->sta_hash[STA_HASH(sta->sta.addr)],
+ lockdep_is_held(&local->sta_lock));
if (!s)
return -ENOENT;
if (s == sta) {
@@ -76,9 +77,11 @@ static int sta_info_hash_del(struct ieee80211_local *local,
return 0;
}
- while (s->hnext && s->hnext != sta)
- s = s->hnext;
- if (s->hnext) {
+ while (rcu_access_pointer(s->hnext) &&
+ rcu_access_pointer(s->hnext) != sta)
+ s = rcu_dereference_protected(s->hnext,
+ lockdep_is_held(&local->sta_lock));
+ if (rcu_access_pointer(s->hnext)) {
rcu_assign_pointer(s->hnext, sta->hnext);
return 0;
}
@@ -228,6 +231,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
+ struct timespec uptime;
int i;
sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp);
@@ -245,6 +249,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
sta->sdata = sdata;
sta->last_rx = jiffies;
+ do_posix_clock_monotonic_gettime(&uptime);
+ sta->last_connected = uptime.tv_sec;
ewma_init(&sta->avg_signal, 1024, 8);
if (sta_prepare_rate_control(local, sta, gfp)) {
@@ -271,7 +277,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
#ifdef CONFIG_MAC80211_MESH
- sta->plink_state = PLINK_LISTEN;
+ sta->plink_state = NL80211_PLINK_LISTEN;
init_timer(&sta->plink_timer);
#endif
@@ -584,7 +590,6 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
{
unsigned long flags;
struct sk_buff *skb;
- struct ieee80211_sub_if_data *sdata;
if (skb_queue_empty(&sta->ps_tx_buf))
return false;
@@ -601,7 +606,6 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
if (!skb)
break;
- sdata = sta->sdata;
local->total_ps_buffered--;
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk(KERN_DEBUG "Buffered frame expired (STA %pM)\n",
@@ -609,7 +613,8 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
#endif
dev_kfree_skb(skb);
- if (skb_queue_empty(&sta->ps_tx_buf))
+ if (skb_queue_empty(&sta->ps_tx_buf) &&
+ !test_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF))
sta_info_clear_tim_bit(sta);
}
@@ -650,10 +655,12 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
if (ret)
return ret;
+ mutex_lock(&local->key_mtx);
for (i = 0; i < NUM_DEFAULT_KEYS; i++)
- ieee80211_key_free(local, sta->gtk[i]);
+ __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]));
if (sta->ptk)
- ieee80211_key_free(local, sta->ptk);
+ __ieee80211_key_free(key_mtx_dereference(local, sta->ptk));
+ mutex_unlock(&local->key_mtx);
sta->dead = true;
@@ -698,6 +705,8 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
cancel_work_sync(&sta->drv_unblock_wk);
+ cfg80211_del_sta(sdata->dev, sta->sta.addr, GFP_KERNEL);
+
rate_control_remove_sta_debugfs(sta);
ieee80211_sta_debugfs_remove(sta);
@@ -766,9 +775,8 @@ static void sta_info_cleanup(unsigned long data)
if (!timer_needed)
return;
- local->sta_cleanup.expires =
- round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL);
- add_timer(&local->sta_cleanup);
+ mod_timer(&local->sta_cleanup,
+ round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL));
}
void sta_info_init(struct ieee80211_local *local)
@@ -781,14 +789,6 @@ void sta_info_init(struct ieee80211_local *local)
setup_timer(&local->sta_cleanup, sta_info_cleanup,
(unsigned long)local);
- local->sta_cleanup.expires =
- round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL);
-}
-
-int sta_info_start(struct ieee80211_local *local)
-{
- add_timer(&local->sta_cleanup);
- return 0;
}
void sta_info_stop(struct ieee80211_local *local)
@@ -900,6 +900,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
struct ieee80211_local *local = sdata->local;
int sent, buffered;
+ clear_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF);
if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS))
drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta);
@@ -992,3 +993,12 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
ieee80211_queue_work(hw, &sta->drv_unblock_wk);
}
EXPORT_SYMBOL(ieee80211_sta_block_awake);
+
+void ieee80211_sta_set_tim(struct ieee80211_sta *pubsta)
+{
+ struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+
+ set_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF);
+ sta_info_set_tim_bit(sta);
+}
+EXPORT_SYMBOL(ieee80211_sta_set_tim);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index b2f95966c7f..c6ae8718bd5 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -43,6 +43,8 @@
* be in the queues
* @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping
* station in power-save mode, reply when the driver unblocks.
+ * @WLAN_STA_PS_DRIVER_BUF: Station has frames pending in driver internal
+ * buffers. Automatically cleared on station wake-up.
*/
enum ieee80211_sta_info_flags {
WLAN_STA_AUTH = 1<<0,
@@ -58,6 +60,7 @@ enum ieee80211_sta_info_flags {
WLAN_STA_BLOCK_BA = 1<<11,
WLAN_STA_PS_DRIVER = 1<<12,
WLAN_STA_PSPOLL = 1<<13,
+ WLAN_STA_PS_DRIVER_BUF = 1<<14,
};
#define STA_TID_NUM 16
@@ -149,6 +152,7 @@ struct tid_ampdu_rx {
*
* @tid_rx: aggregation info for Rx per TID -- RCU protected
* @tid_tx: aggregation info for Tx per TID
+ * @tid_start_tx: sessions where start was requested
* @addba_req_num: number of times addBA request has been sent.
* @dialog_token_allocator: dialog token enumerator for each new session;
* @work: work struct for starting/stopping aggregation
@@ -160,40 +164,18 @@ struct tid_ampdu_rx {
struct sta_ampdu_mlme {
struct mutex mtx;
/* rx */
- struct tid_ampdu_rx *tid_rx[STA_TID_NUM];
+ struct tid_ampdu_rx __rcu *tid_rx[STA_TID_NUM];
unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)];
/* tx */
struct work_struct work;
- struct tid_ampdu_tx *tid_tx[STA_TID_NUM];
+ struct tid_ampdu_tx __rcu *tid_tx[STA_TID_NUM];
+ struct tid_ampdu_tx *tid_start_tx[STA_TID_NUM];
u8 addba_req_num[STA_TID_NUM];
u8 dialog_token_allocator;
};
/**
- * enum plink_state - state of a mesh peer link finite state machine
- *
- * @PLINK_LISTEN: initial state, considered the implicit state of non existent
- * mesh peer links
- * @PLINK_OPN_SNT: mesh plink open frame has been sent to this mesh peer
- * @PLINK_OPN_RCVD: mesh plink open frame has been received from this mesh peer
- * @PLINK_CNF_RCVD: mesh plink confirm frame has been received from this mesh
- * peer
- * @PLINK_ESTAB: mesh peer link is established
- * @PLINK_HOLDING: mesh peer link is being closed or cancelled
- * @PLINK_BLOCKED: all frames transmitted from this mesh plink are discarded
- */
-enum plink_state {
- PLINK_LISTEN,
- PLINK_OPN_SNT,
- PLINK_OPN_RCVD,
- PLINK_CNF_RCVD,
- PLINK_ESTAB,
- PLINK_HOLDING,
- PLINK_BLOCKED
-};
-
-/**
* struct sta_info - STA information
*
* This structure collects information about a station that
@@ -226,6 +208,7 @@ enum plink_state {
* @rx_bytes: Number of bytes received from this STA
* @wep_weak_iv_count: number of weak WEP IVs received from this station
* @last_rx: time (in jiffies) when last frame was received from this STA
+ * @last_connected: time (in seconds) when a station got connected
* @num_duplicates: number of duplicate frames received from this STA
* @rx_fragments: number of received MPDUs
* @rx_dropped: number of dropped MPDUs from this STA
@@ -260,11 +243,11 @@ enum plink_state {
struct sta_info {
/* General information, mostly static */
struct list_head list;
- struct sta_info *hnext;
+ struct sta_info __rcu *hnext;
struct ieee80211_local *local;
struct ieee80211_sub_if_data *sdata;
- struct ieee80211_key *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
- struct ieee80211_key *ptk;
+ struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
+ struct ieee80211_key __rcu *ptk;
struct rate_control_ref *rate_ctrl;
void *rate_ctrl_priv;
spinlock_t lock;
@@ -295,6 +278,7 @@ struct sta_info {
unsigned long rx_packets, rx_bytes;
unsigned long wep_weak_iv_count;
unsigned long last_rx;
+ long last_connected;
unsigned long num_duplicates;
unsigned long rx_fragments;
unsigned long rx_dropped;
@@ -334,7 +318,7 @@ struct sta_info {
u8 plink_retries;
bool ignore_plink_timer;
bool plink_timer_was_running;
- enum plink_state plink_state;
+ enum nl80211_plink_state plink_state;
u32 plink_timeout;
struct timer_list plink_timer;
#endif
@@ -352,12 +336,12 @@ struct sta_info {
struct ieee80211_sta sta;
};
-static inline enum plink_state sta_plink_state(struct sta_info *sta)
+static inline enum nl80211_plink_state sta_plink_state(struct sta_info *sta)
{
#ifdef CONFIG_MAC80211_MESH
return sta->plink_state;
#endif
- return PLINK_LISTEN;
+ return NL80211_PLINK_LISTEN;
}
static inline void set_sta_flags(struct sta_info *sta, const u32 flags)
@@ -416,7 +400,16 @@ static inline u32 get_sta_flags(struct sta_info *sta)
return ret;
}
+void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
+ struct tid_ampdu_tx *tid_tx);
+static inline struct tid_ampdu_tx *
+rcu_dereference_protected_tid_tx(struct sta_info *sta, int tid)
+{
+ return rcu_dereference_protected(sta->ampdu_mlme.tid_tx[tid],
+ lockdep_is_held(&sta->lock) ||
+ lockdep_is_held(&sta->ampdu_mlme.mtx));
+}
#define STA_HASH_SIZE 256
#define STA_HASH(sta) (sta[5])
@@ -497,7 +490,6 @@ void sta_info_set_tim_bit(struct sta_info *sta);
void sta_info_clear_tim_bit(struct sta_info *sta);
void sta_info_init(struct ieee80211_local *local);
-int sta_info_start(struct ieee80211_local *local);
void sta_info_stop(struct ieee80211_local *local);
int sta_info_flush(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index b936dd29e92..1658efaa2e8 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -189,16 +189,19 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
bool acked;
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
- /* the HW cannot have attempted that rate */
- if (i >= hw->max_report_rates) {
+ if (info->status.rates[i].idx < 0) {
+ break;
+ } else if (i >= hw->max_report_rates) {
+ /* the HW cannot have attempted that rate */
info->status.rates[i].idx = -1;
info->status.rates[i].count = 0;
- } else if (info->status.rates[i].idx >= 0) {
- rates_idx = i;
+ break;
}
retry_count += info->status.rates[i].count;
}
+ rates_idx = i - 1;
+
if (retry_count < 0)
retry_count = 0;
@@ -443,3 +446,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
dev_kfree_skb(skb);
}
EXPORT_SYMBOL(ieee80211_tx_status);
+
+void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets)
+{
+ struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+ cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr,
+ num_packets, GFP_ATOMIC);
+}
+EXPORT_SYMBOL(ieee80211_report_low_ack);
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index e840c9cd46d..757e4eb2baf 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -202,7 +202,7 @@ EXPORT_SYMBOL(ieee80211_get_tkip_key);
* @payload_len is the length of payload (_not_ including IV/ICV length).
* @ta is the transmitter addresses.
*/
-int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
+int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm,
struct ieee80211_key *key,
u8 *pos, size_t payload_len, u8 *ta)
{
@@ -223,7 +223,7 @@ int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
* beginning of the buffer containing IEEE 802.11 header payload, i.e.,
* including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the
* length of payload, including IV, Ext. IV, MIC, ICV. */
-int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
+int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm,
struct ieee80211_key *key,
u8 *payload, size_t payload_len, u8 *ta,
u8 *ra, int only_iv, int queue,
diff --git a/net/mac80211/tkip.h b/net/mac80211/tkip.h
index 7e83dee976f..1cab9c86978 100644
--- a/net/mac80211/tkip.h
+++ b/net/mac80211/tkip.h
@@ -15,7 +15,7 @@
u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16);
-int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
+int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm,
struct ieee80211_key *key,
u8 *pos, size_t payload_len, u8 *ta);
enum {
@@ -24,7 +24,7 @@ enum {
TKIP_DECRYPT_INVALID_KEYIDX = -2,
TKIP_DECRYPT_REPLAY = -3,
};
-int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
+int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm,
struct ieee80211_key *key,
u8 *payload, size_t payload_len, u8 *ta,
u8 *ra, int only_iv, int queue,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index bd1224fd216..64e0f7587e6 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1040,14 +1040,11 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
struct ieee80211_radiotap_iterator iterator;
struct ieee80211_radiotap_header *rthdr =
(struct ieee80211_radiotap_header *) skb->data;
- struct ieee80211_supported_band *sband;
bool hw_frag;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len,
NULL);
- sband = tx->local->hw.wiphy->bands[tx->channel->band];
-
info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
tx->flags &= ~IEEE80211_TX_FRAGMENTED;
@@ -1154,7 +1151,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
* packet pass through because splicing the frames
* back is already done.
*/
- tid_tx = tx->sta->ampdu_mlme.tid_tx[tid];
+ tid_tx = rcu_dereference_protected_tid_tx(tx->sta, tid);
if (!tid_tx) {
/* do nothing, let packet pass through */
@@ -1446,11 +1443,8 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
struct ieee80211_tx_data tx;
ieee80211_tx_result res_prepare;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- u16 queue;
bool result = true;
- queue = skb_get_queue_mapping(skb);
-
if (unlikely(skb->len < 10)) {
dev_kfree_skb(skb);
return true;
@@ -1486,12 +1480,7 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
{
int tail_need = 0;
- /*
- * This could be optimised, devices that do full hardware
- * crypto (including TKIP MMIC) need no tailroom... But we
- * have no drivers for such devices currently.
- */
- if (may_encrypt) {
+ if (may_encrypt && local->crypto_tx_tailroom_needed_cnt) {
tail_need = IEEE80211_ENCRYPT_TAILROOM;
tail_need -= skb_tailroom(skb);
tail_need = max_t(int, tail_need, 0);
@@ -1766,6 +1755,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
ret = NETDEV_TX_OK;
goto fail;
}
+ rcu_read_lock();
if (!is_multicast_ether_addr(skb->data))
mppath = mpp_path_lookup(skb->data, sdata);
@@ -1780,13 +1770,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
!(mppath && compare_ether_addr(mppath->mpp, skb->data))) {
hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
skb->data, skb->data + ETH_ALEN);
+ rcu_read_unlock();
meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
sdata, NULL, NULL);
} else {
int is_mesh_mcast = 1;
const u8 *mesh_da;
- rcu_read_lock();
if (is_multicast_ether_addr(skb->data))
/* DA TA mSA AE:SA */
mesh_da = skb->data;
@@ -2266,7 +2256,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
/* headroom, head length, tail length and maximum TIM length */
skb = dev_alloc_skb(local->tx_headroom + 400 +
- sdata->u.mesh.vendor_ie_len);
+ sdata->u.mesh.ie_len);
if (!skb)
goto out;
@@ -2489,7 +2479,6 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
{
struct ieee80211_local *local = hw_to_local(hw);
struct sk_buff *skb = NULL;
- struct sta_info *sta;
struct ieee80211_tx_data tx;
struct ieee80211_sub_if_data *sdata;
struct ieee80211_if_ap *bss = NULL;
@@ -2531,7 +2520,6 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
info = IEEE80211_SKB_CB(skb);
- sta = tx.sta;
tx.flags |= IEEE80211_TX_PS_BUFFERED;
tx.channel = local->hw.conf.channel;
info->band = tx.channel->band;
@@ -2551,8 +2539,9 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
skb_set_network_header(skb, 0);
skb_set_transport_header(skb, 0);
- /* send all internal mgmt frames on VO */
- skb_set_queue_mapping(skb, 0);
+ /* Send all internal mgmt frames on VO. Accordingly set TID to 7. */
+ skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+ skb->priority = 7;
/*
* The other path calling ieee80211_xmit is from the tasklet,
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 556647a910a..d3fe2d23748 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1125,9 +1125,27 @@ int ieee80211_reconfig(struct ieee80211_local *local)
struct sta_info *sta;
int res;
+#ifdef CONFIG_PM
if (local->suspended)
local->resuming = true;
+ if (local->wowlan) {
+ local->wowlan = false;
+ res = drv_resume(local);
+ if (res < 0) {
+ local->resuming = false;
+ return res;
+ }
+ if (res == 0)
+ goto wake_up;
+ WARN_ON(res > 1);
+ /*
+ * res is 1, which means the driver requested
+ * to go through a regular reset on wakeup.
+ */
+ }
+#endif
+
/* restart hardware */
if (local->open_count) {
/*
@@ -1258,6 +1276,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
if (ieee80211_sdata_running(sdata))
ieee80211_enable_keys(sdata);
+ wake_up:
ieee80211_wake_queues_by_reason(hw,
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
@@ -1290,7 +1309,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
}
}
- add_timer(&local->sta_cleanup);
+ mod_timer(&local->sta_cleanup, jiffies + 1);
mutex_lock(&local->sta_mtx);
list_for_each_entry(sta, &local->sta_list, list)
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 2ff6d1e3ed2..a1c6bfd55f0 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -30,17 +30,15 @@ int ieee80211_wep_init(struct ieee80211_local *local)
/* start WEP IV from a random value */
get_random_bytes(&local->wep_iv, WEP_IV_LEN);
- local->wep_tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0,
- CRYPTO_ALG_ASYNC);
+ local->wep_tx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(local->wep_tx_tfm)) {
local->wep_rx_tfm = ERR_PTR(-EINVAL);
return PTR_ERR(local->wep_tx_tfm);
}
- local->wep_rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0,
- CRYPTO_ALG_ASYNC);
+ local->wep_rx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(local->wep_rx_tfm)) {
- crypto_free_blkcipher(local->wep_tx_tfm);
+ crypto_free_cipher(local->wep_tx_tfm);
local->wep_tx_tfm = ERR_PTR(-EINVAL);
return PTR_ERR(local->wep_rx_tfm);
}
@@ -51,9 +49,9 @@ int ieee80211_wep_init(struct ieee80211_local *local)
void ieee80211_wep_free(struct ieee80211_local *local)
{
if (!IS_ERR(local->wep_tx_tfm))
- crypto_free_blkcipher(local->wep_tx_tfm);
+ crypto_free_cipher(local->wep_tx_tfm);
if (!IS_ERR(local->wep_rx_tfm))
- crypto_free_blkcipher(local->wep_rx_tfm);
+ crypto_free_cipher(local->wep_rx_tfm);
}
static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen)
@@ -127,12 +125,11 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local,
/* Perform WEP encryption using given key. data buffer must have tailroom
* for 4-byte ICV. data_len must not include this ICV. Note: this function
* does _not_ add IV. data = RC4(data | CRC32(data)) */
-int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
+int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
size_t klen, u8 *data, size_t data_len)
{
- struct blkcipher_desc desc = { .tfm = tfm };
- struct scatterlist sg;
__le32 icv;
+ int i;
if (IS_ERR(tfm))
return -1;
@@ -140,9 +137,9 @@ int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
icv = cpu_to_le32(~crc32_le(~0, data, data_len));
put_unaligned(icv, (__le32 *)(data + data_len));
- crypto_blkcipher_setkey(tfm, rc4key, klen);
- sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
- crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
+ crypto_cipher_setkey(tfm, rc4key, klen);
+ for (i = 0; i < data_len + WEP_ICV_LEN; i++)
+ crypto_cipher_encrypt_one(tfm, data + i, data + i);
return 0;
}
@@ -186,19 +183,18 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
/* Perform WEP decryption using given key. data buffer includes encrypted
* payload, including 4-byte ICV, but _not_ IV. data_len must not include ICV.
* Return 0 on success and -1 on ICV mismatch. */
-int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
+int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
size_t klen, u8 *data, size_t data_len)
{
- struct blkcipher_desc desc = { .tfm = tfm };
- struct scatterlist sg;
__le32 crc;
+ int i;
if (IS_ERR(tfm))
return -1;
- crypto_blkcipher_setkey(tfm, rc4key, klen);
- sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
- crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
+ crypto_cipher_setkey(tfm, rc4key, klen);
+ for (i = 0; i < data_len + WEP_ICV_LEN; i++)
+ crypto_cipher_decrypt_one(tfm, data + i, data + i);
crc = cpu_to_le32(~crc32_le(~0, data, data_len));
if (memcmp(&crc, data + data_len, WEP_ICV_LEN) != 0)
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h
index 58654ee3351..01e54840a62 100644
--- a/net/mac80211/wep.h
+++ b/net/mac80211/wep.h
@@ -18,12 +18,12 @@
int ieee80211_wep_init(struct ieee80211_local *local);
void ieee80211_wep_free(struct ieee80211_local *local);
-int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
+int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
size_t klen, u8 *data, size_t data_len);
int ieee80211_wep_encrypt(struct ieee80211_local *local,
struct sk_buff *skb,
const u8 *key, int keylen, int keyidx);
-int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
+int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
size_t klen, u8 *data, size_t data_len);
bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index ac3549690b8..d2e7f0e8667 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -190,9 +190,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
u8 *pos, qos_info;
- const u8 *ies;
size_t offset = 0, noffset;
- int i, len, count, rates_len, supp_rates_len;
+ int i, count, rates_len, supp_rates_len;
u16 capab;
struct ieee80211_supported_band *sband;
u32 rates = 0;
@@ -277,7 +276,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
}
/* SSID */
- ies = pos = skb_put(skb, 2 + wk->assoc.ssid_len);
+ pos = skb_put(skb, 2 + wk->assoc.ssid_len);
*pos++ = WLAN_EID_SSID;
*pos++ = wk->assoc.ssid_len;
memcpy(pos, wk->assoc.ssid, wk->assoc.ssid_len);
@@ -287,7 +286,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
if (supp_rates_len > 8)
supp_rates_len = 8;
- len = sband->n_bitrates;
pos = skb_put(skb, supp_rates_len + 2);
*pos++ = WLAN_EID_SUPP_RATES;
*pos++ = supp_rates_len;
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index f1765de2f4b..9dc3b5f26e8 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -87,42 +87,76 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- /* No way to verify the MIC if the hardware stripped it */
- if (status->flag & RX_FLAG_MMIC_STRIPPED)
+ /*
+ * it makes no sense to check for MIC errors on anything other
+ * than data frames.
+ */
+ if (!ieee80211_is_data_present(hdr->frame_control))
+ return RX_CONTINUE;
+
+ /*
+ * No way to verify the MIC if the hardware stripped it or
+ * the IV with the key index. In this case we have solely rely
+ * on the driver to set RX_FLAG_MMIC_ERROR in the event of a
+ * MIC failure report.
+ */
+ if (status->flag & (RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED)) {
+ if (status->flag & RX_FLAG_MMIC_ERROR)
+ goto mic_fail;
+
+ if (!(status->flag & RX_FLAG_IV_STRIPPED))
+ goto update_iv;
+
return RX_CONTINUE;
+ }
+ /*
+ * Some hardware seems to generate Michael MIC failure reports; even
+ * though, the frame was not encrypted with TKIP and therefore has no
+ * MIC. Ignore the flag them to avoid triggering countermeasures.
+ */
if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP ||
- !ieee80211_has_protected(hdr->frame_control) ||
- !ieee80211_is_data_present(hdr->frame_control))
+ !(status->flag & RX_FLAG_DECRYPTED))
return RX_CONTINUE;
+ if (rx->sdata->vif.type == NL80211_IFTYPE_AP && rx->key->conf.keyidx) {
+ /*
+ * APs with pairwise keys should never receive Michael MIC
+ * errors for non-zero keyidx because these are reserved for
+ * group keys and only the AP is sending real multicast
+ * frames in the BSS. (
+ */
+ return RX_DROP_UNUSABLE;
+ }
+
+ if (status->flag & RX_FLAG_MMIC_ERROR)
+ goto mic_fail;
+
hdrlen = ieee80211_hdrlen(hdr->frame_control);
if (skb->len < hdrlen + MICHAEL_MIC_LEN)
return RX_DROP_UNUSABLE;
data = skb->data + hdrlen;
data_len = skb->len - hdrlen - MICHAEL_MIC_LEN;
-
key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
michael_mic(key, hdr, data, data_len, mic);
- if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0) {
- if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
- return RX_DROP_UNUSABLE;
-
- mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx,
- (void *) skb->data, NULL,
- GFP_ATOMIC);
- return RX_DROP_UNUSABLE;
- }
+ if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0)
+ goto mic_fail;
/* remove Michael MIC from payload */
skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
+update_iv:
/* update IV in key information to be able to detect replays */
rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32;
rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16;
return RX_CONTINUE;
+
+mic_fail:
+ mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx,
+ (void *) skb->data, NULL, GFP_ATOMIC);
+ return RX_DROP_UNUSABLE;
}
diff --git a/net/netfilter/ipset/ip_set_getport.c b/net/netfilter/ipset/ip_set_getport.c
index 8d522721268..757143b2240 100644
--- a/net/netfilter/ipset/ip_set_getport.c
+++ b/net/netfilter/ipset/ip_set_getport.c
@@ -11,6 +11,7 @@
#include <linux/skbuff.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
+#include <linux/sctp.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <net/ip.h>
#include <net/ipv6.h>
@@ -35,7 +36,20 @@ get_port(const struct sk_buff *skb, int protocol, unsigned int protooff,
*port = src ? th->source : th->dest;
break;
}
- case IPPROTO_UDP: {
+ case IPPROTO_SCTP: {
+ sctp_sctphdr_t _sh;
+ const sctp_sctphdr_t *sh;
+
+ sh = skb_header_pointer(skb, protooff, sizeof(_sh), &_sh);
+ if (sh == NULL)
+ /* No choice either */
+ return false;
+
+ *port = src ? sh->source : sh->dest;
+ break;
+ }
+ case IPPROTO_UDP:
+ case IPPROTO_UDPLITE: {
struct udphdr _udph;
const struct udphdr *uh;
diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c
index b9214145d35..14281b6b807 100644
--- a/net/netfilter/ipset/ip_set_hash_ipport.c
+++ b/net/netfilter/ipset/ip_set_hash_ipport.c
@@ -491,7 +491,7 @@ static struct ip_set_type hash_ipport_type __read_mostly = {
.features = IPSET_TYPE_IP | IPSET_TYPE_PORT,
.dimension = IPSET_DIM_TWO,
.family = AF_UNSPEC,
- .revision = 0,
+ .revision = 1,
.create = hash_ipport_create,
.create_policy = {
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c
index 4642872df6e..401c8a2531d 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportip.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
@@ -509,7 +509,7 @@ static struct ip_set_type hash_ipportip_type __read_mostly = {
.features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2,
.dimension = IPSET_DIM_THREE,
.family = AF_UNSPEC,
- .revision = 0,
+ .revision = 1,
.create = hash_ipportip_create,
.create_policy = {
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c
index 2cb84a54b7a..4743e540252 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
@@ -574,7 +574,7 @@ static struct ip_set_type hash_ipportnet_type __read_mostly = {
.features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2,
.dimension = IPSET_DIM_THREE,
.family = AF_UNSPEC,
- .revision = 0,
+ .revision = 1,
.create = hash_ipportnet_create,
.create_policy = {
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c
index 8598676f2a0..d2a40362dd3 100644
--- a/net/netfilter/ipset/ip_set_hash_netport.c
+++ b/net/netfilter/ipset/ip_set_hash_netport.c
@@ -526,7 +526,7 @@ static struct ip_set_type hash_netport_type __read_mostly = {
.features = IPSET_TYPE_IP | IPSET_TYPE_PORT,
.dimension = IPSET_DIM_TWO,
.family = AF_UNSPEC,
- .revision = 0,
+ .revision = 1,
.create = hash_netport_create,
.create_policy = {
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index a74dae6c5db..bfa808f4da1 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -1382,15 +1382,7 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
ip_vs_in_stats(cp, skb);
if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol)
offset += 2 * sizeof(__u16);
- verdict = ip_vs_icmp_xmit(skb, cp, pp, offset);
- /* LOCALNODE from FORWARD hook is not supported */
- if (verdict == NF_ACCEPT && hooknum == NF_INET_FORWARD &&
- skb_rtable(skb)->rt_flags & RTCF_LOCAL) {
- IP_VS_DBG(1, "%s(): "
- "local delivery to %pI4 but in FORWARD\n",
- __func__, &skb_rtable(skb)->rt_dst);
- verdict = NF_DROP;
- }
+ verdict = ip_vs_icmp_xmit(skb, cp, pp, offset, hooknum);
out:
__ip_vs_conn_put(cp);
@@ -1412,7 +1404,6 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
struct ip_vs_protocol *pp;
struct ip_vs_proto_data *pd;
unsigned int offset, verdict;
- struct rt6_info *rt;
*related = 1;
@@ -1474,23 +1465,12 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
if (!cp)
return NF_ACCEPT;
- verdict = NF_DROP;
-
/* do the statistics and put it back */
ip_vs_in_stats(cp, skb);
if (IPPROTO_TCP == cih->nexthdr || IPPROTO_UDP == cih->nexthdr ||
IPPROTO_SCTP == cih->nexthdr)
offset += 2 * sizeof(__u16);
- verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset);
- /* LOCALNODE from FORWARD hook is not supported */
- if (verdict == NF_ACCEPT && hooknum == NF_INET_FORWARD &&
- (rt = (struct rt6_info *) skb_dst(skb)) &&
- rt->rt6i_dev && rt->rt6i_dev->flags & IFF_LOOPBACK) {
- IP_VS_DBG(1, "%s(): "
- "local delivery to %pI6 but in FORWARD\n",
- __func__, &rt->rt6i_dst);
- verdict = NF_DROP;
- }
+ verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset, hooknum);
__ip_vs_conn_put(cp);
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 37890f228b1..699c79a5565 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -2069,9 +2069,6 @@ static const struct file_operations ip_vs_info_fops = {
.release = seq_release_net,
};
-#endif
-
-#ifdef CONFIG_PROC_FS
static int ip_vs_stats_show(struct seq_file *seq, void *v)
{
struct net *net = seq_file_single_net(seq);
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 6132b213edd..ee319a4338b 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -87,7 +87,7 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos)
/* Get route to destination or remote server */
static struct rtable *
__ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
- __be32 daddr, u32 rtos, int rt_mode)
+ __be32 daddr, u32 rtos, int rt_mode, __be32 *ret_saddr)
{
struct net *net = dev_net(skb_dst(skb)->dev);
struct rtable *rt; /* Route to the other host */
@@ -98,7 +98,12 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
spin_lock(&dest->dst_lock);
if (!(rt = (struct rtable *)
__ip_vs_dst_check(dest, rtos))) {
- rt = ip_route_output(net, dest->addr.ip, 0, rtos, 0);
+ struct flowi4 fl4;
+
+ memset(&fl4, 0, sizeof(fl4));
+ fl4.daddr = dest->addr.ip;
+ fl4.flowi4_tos = rtos;
+ rt = ip_route_output_key(net, &fl4);
if (IS_ERR(rt)) {
spin_unlock(&dest->dst_lock);
IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n",
@@ -106,18 +111,30 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
return NULL;
}
__ip_vs_dst_set(dest, rtos, dst_clone(&rt->dst), 0);
- IP_VS_DBG(10, "new dst %pI4, refcnt=%d, rtos=%X\n",
- &dest->addr.ip,
+ dest->dst_saddr.ip = fl4.saddr;
+ IP_VS_DBG(10, "new dst %pI4, src %pI4, refcnt=%d, "
+ "rtos=%X\n",
+ &dest->addr.ip, &dest->dst_saddr.ip,
atomic_read(&rt->dst.__refcnt), rtos);
}
+ daddr = dest->addr.ip;
+ if (ret_saddr)
+ *ret_saddr = dest->dst_saddr.ip;
spin_unlock(&dest->dst_lock);
} else {
- rt = ip_route_output(net, daddr, 0, rtos, 0);
+ struct flowi4 fl4;
+
+ memset(&fl4, 0, sizeof(fl4));
+ fl4.daddr = daddr;
+ fl4.flowi4_tos = rtos;
+ rt = ip_route_output_key(net, &fl4);
if (IS_ERR(rt)) {
IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n",
&daddr);
return NULL;
}
+ if (ret_saddr)
+ *ret_saddr = fl4.saddr;
}
local = rt->rt_flags & RTCF_LOCAL;
@@ -125,7 +142,7 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
rt_mode)) {
IP_VS_DBG_RL("Stopping traffic to %s address, dest: %pI4\n",
(rt->rt_flags & RTCF_LOCAL) ?
- "local":"non-local", &rt->rt_dst);
+ "local":"non-local", &daddr);
ip_rt_put(rt);
return NULL;
}
@@ -133,14 +150,14 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
!((ort = skb_rtable(skb)) && ort->rt_flags & RTCF_LOCAL)) {
IP_VS_DBG_RL("Redirect from non-local address %pI4 to local "
"requires NAT method, dest: %pI4\n",
- &ip_hdr(skb)->daddr, &rt->rt_dst);
+ &ip_hdr(skb)->daddr, &daddr);
ip_rt_put(rt);
return NULL;
}
if (unlikely(!local && ipv4_is_loopback(ip_hdr(skb)->saddr))) {
IP_VS_DBG_RL("Stopping traffic from loopback address %pI4 "
"to non-local address, dest: %pI4\n",
- &ip_hdr(skb)->saddr, &rt->rt_dst);
+ &ip_hdr(skb)->saddr, &daddr);
ip_rt_put(rt);
return NULL;
}
@@ -229,8 +246,6 @@ out_err:
/*
* Get route to destination or remote server
- * rt_mode: flags, &1=Allow local dest, &2=Allow non-local dest,
- * &4=Allow redirect from remote daddr to local
*/
static struct rt6_info *
__ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest,
@@ -250,7 +265,7 @@ __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest,
u32 cookie;
dst = __ip_vs_route_output_v6(net, &dest->addr.in6,
- &dest->dst_saddr,
+ &dest->dst_saddr.in6,
do_xfrm);
if (!dst) {
spin_unlock(&dest->dst_lock);
@@ -260,11 +275,11 @@ __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest,
cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
__ip_vs_dst_set(dest, 0, dst_clone(&rt->dst), cookie);
IP_VS_DBG(10, "new dst %pI6, src %pI6, refcnt=%d\n",
- &dest->addr.in6, &dest->dst_saddr,
+ &dest->addr.in6, &dest->dst_saddr.in6,
atomic_read(&rt->dst.__refcnt));
}
if (ret_saddr)
- ipv6_addr_copy(ret_saddr, &dest->dst_saddr);
+ ipv6_addr_copy(ret_saddr, &dest->dst_saddr.in6);
spin_unlock(&dest->dst_lock);
} else {
dst = __ip_vs_route_output_v6(net, daddr, ret_saddr, do_xfrm);
@@ -274,13 +289,14 @@ __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest,
}
local = __ip_vs_is_local_route6(rt);
- if (!((local ? 1 : 2) & rt_mode)) {
+ if (!((local ? IP_VS_RT_MODE_LOCAL : IP_VS_RT_MODE_NON_LOCAL) &
+ rt_mode)) {
IP_VS_DBG_RL("Stopping traffic to %s address, dest: %pI6\n",
local ? "local":"non-local", daddr);
dst_release(&rt->dst);
return NULL;
}
- if (local && !(rt_mode & 4) &&
+ if (local && !(rt_mode & IP_VS_RT_MODE_RDR) &&
!((ort = (struct rt6_info *) skb_dst(skb)) &&
__ip_vs_is_local_route6(ort))) {
IP_VS_DBG_RL("Redirect from non-local address %pI6 to local "
@@ -386,7 +402,7 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
EnterFunction(10);
if (!(rt = __ip_vs_get_out_rt(skb, NULL, iph->daddr, RT_TOS(iph->tos),
- IP_VS_RT_MODE_NON_LOCAL)))
+ IP_VS_RT_MODE_NON_LOCAL, NULL)))
goto tx_error_icmp;
/* MTU checking */
@@ -440,7 +456,8 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
EnterFunction(10);
- if (!(rt = __ip_vs_get_out_rt_v6(skb, NULL, &iph->daddr, NULL, 0, 2)))
+ if (!(rt = __ip_vs_get_out_rt_v6(skb, NULL, &iph->daddr, NULL, 0,
+ IP_VS_RT_MODE_NON_LOCAL)))
goto tx_error_icmp;
/* MTU checking */
@@ -517,7 +534,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
RT_TOS(iph->tos),
IP_VS_RT_MODE_LOCAL |
IP_VS_RT_MODE_NON_LOCAL |
- IP_VS_RT_MODE_RDR)))
+ IP_VS_RT_MODE_RDR, NULL)))
goto tx_error_icmp;
local = rt->rt_flags & RTCF_LOCAL;
/*
@@ -539,7 +556,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
#endif
/* From world but DNAT to loopback address? */
- if (local && ipv4_is_loopback(rt->rt_dst) &&
+ if (local && ipv4_is_loopback(cp->daddr.ip) &&
rt_is_input_route(skb_rtable(skb))) {
IP_VS_DBG_RL_PKT(1, AF_INET, pp, skb, 0, "ip_vs_nat_xmit(): "
"stopping DNAT to loopback address");
@@ -632,7 +649,9 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
}
if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL,
- 0, 1|2|4)))
+ 0, (IP_VS_RT_MODE_LOCAL |
+ IP_VS_RT_MODE_NON_LOCAL |
+ IP_VS_RT_MODE_RDR))))
goto tx_error_icmp;
local = __ip_vs_is_local_route6(rt);
/*
@@ -748,6 +767,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
struct ip_vs_protocol *pp)
{
struct rtable *rt; /* Route to the other host */
+ __be32 saddr; /* Source for tunnel */
struct net_device *tdev; /* Device to other host */
struct iphdr *old_iph = ip_hdr(skb);
u8 tos = old_iph->tos;
@@ -761,7 +781,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
RT_TOS(tos), IP_VS_RT_MODE_LOCAL |
- IP_VS_RT_MODE_NON_LOCAL)))
+ IP_VS_RT_MODE_NON_LOCAL,
+ &saddr)))
goto tx_error_icmp;
if (rt->rt_flags & RTCF_LOCAL) {
ip_rt_put(rt);
@@ -829,8 +850,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
iph->frag_off = df;
iph->protocol = IPPROTO_IPIP;
iph->tos = tos;
- iph->daddr = rt->rt_dst;
- iph->saddr = rt->rt_src;
+ iph->daddr = cp->daddr.ip;
+ iph->saddr = saddr;
iph->ttl = old_iph->ttl;
ip_select_ident(iph, &rt->dst, NULL);
@@ -875,7 +896,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
EnterFunction(10);
if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6,
- &saddr, 1, 1|2)))
+ &saddr, 1, (IP_VS_RT_MODE_LOCAL |
+ IP_VS_RT_MODE_NON_LOCAL))))
goto tx_error_icmp;
if (__ip_vs_is_local_route6(rt)) {
dst_release(&rt->dst);
@@ -992,7 +1014,7 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
RT_TOS(iph->tos),
IP_VS_RT_MODE_LOCAL |
- IP_VS_RT_MODE_NON_LOCAL)))
+ IP_VS_RT_MODE_NON_LOCAL, NULL)))
goto tx_error_icmp;
if (rt->rt_flags & RTCF_LOCAL) {
ip_rt_put(rt);
@@ -1050,7 +1072,8 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
EnterFunction(10);
if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL,
- 0, 1|2)))
+ 0, (IP_VS_RT_MODE_LOCAL |
+ IP_VS_RT_MODE_NON_LOCAL))))
goto tx_error_icmp;
if (__ip_vs_is_local_route6(rt)) {
dst_release(&rt->dst);
@@ -1109,12 +1132,13 @@ tx_error:
*/
int
ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
- struct ip_vs_protocol *pp, int offset)
+ struct ip_vs_protocol *pp, int offset, unsigned int hooknum)
{
struct rtable *rt; /* Route to the other host */
int mtu;
int rc;
int local;
+ int rt_mode;
EnterFunction(10);
@@ -1135,11 +1159,13 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
* mangle and send the packet here (only for VS/NAT)
*/
+ /* LOCALNODE from FORWARD hook is not supported */
+ rt_mode = (hooknum != NF_INET_FORWARD) ?
+ IP_VS_RT_MODE_LOCAL | IP_VS_RT_MODE_NON_LOCAL |
+ IP_VS_RT_MODE_RDR : IP_VS_RT_MODE_NON_LOCAL;
if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
RT_TOS(ip_hdr(skb)->tos),
- IP_VS_RT_MODE_LOCAL |
- IP_VS_RT_MODE_NON_LOCAL |
- IP_VS_RT_MODE_RDR)))
+ rt_mode, NULL)))
goto tx_error_icmp;
local = rt->rt_flags & RTCF_LOCAL;
@@ -1162,7 +1188,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
#endif
/* From world but DNAT to loopback address? */
- if (local && ipv4_is_loopback(rt->rt_dst) &&
+ if (local && ipv4_is_loopback(cp->daddr.ip) &&
rt_is_input_route(skb_rtable(skb))) {
IP_VS_DBG(1, "%s(): "
"stopping DNAT to loopback %pI4\n",
@@ -1227,12 +1253,13 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
#ifdef CONFIG_IP_VS_IPV6
int
ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
- struct ip_vs_protocol *pp, int offset)
+ struct ip_vs_protocol *pp, int offset, unsigned int hooknum)
{
struct rt6_info *rt; /* Route to the other host */
int mtu;
int rc;
int local;
+ int rt_mode;
EnterFunction(10);
@@ -1253,8 +1280,12 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
* mangle and send the packet here (only for VS/NAT)
*/
+ /* LOCALNODE from FORWARD hook is not supported */
+ rt_mode = (hooknum != NF_INET_FORWARD) ?
+ IP_VS_RT_MODE_LOCAL | IP_VS_RT_MODE_NON_LOCAL |
+ IP_VS_RT_MODE_RDR : IP_VS_RT_MODE_NON_LOCAL;
if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL,
- 0, 1|2|4)))
+ 0, rt_mode)))
goto tx_error_icmp;
local = __ip_vs_is_local_route6(rt);
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 237cc1981b8..cb5a2858178 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -1419,6 +1419,7 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
const char *dptr, *end;
s16 diff, tdiff = 0;
int ret = NF_ACCEPT;
+ bool term;
typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust;
if (ctinfo != IP_CT_ESTABLISHED &&
@@ -1453,14 +1454,21 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
if (dptr + matchoff == end)
break;
- if (end + strlen("\r\n\r\n") > dptr + datalen)
- break;
- if (end[0] != '\r' || end[1] != '\n' ||
- end[2] != '\r' || end[3] != '\n')
+ term = false;
+ for (; end + strlen("\r\n\r\n") <= dptr + datalen; end++) {
+ if (end[0] == '\r' && end[1] == '\n' &&
+ end[2] == '\r' && end[3] == '\n') {
+ term = true;
+ break;
+ }
+ }
+ if (!term)
break;
end += strlen("\r\n\r\n") + clen;
msglen = origlen = end - dptr;
+ if (msglen > datalen)
+ return NF_DROP;
ret = process_sip_msg(skb, ct, dataoff, &dptr, &msglen);
if (ret != NF_ACCEPT)
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 0ae14282588..05e9feb101c 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -245,7 +245,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
ret = 0;
release:
nf_ct_put(ct);
- return 0;
+ return ret;
}
static const struct seq_operations ct_seq_ops = {
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 985e9b76c91..e0ee010935e 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -381,7 +381,6 @@ __build_packet_message(struct nfulnl_instance *inst,
struct nfulnl_msg_packet_hdr pmsg;
struct nlmsghdr *nlh;
struct nfgenmsg *nfmsg;
- __be32 tmp_uint;
sk_buff_data_t old_tail = inst->skb->tail;
nlh = NLMSG_PUT(inst->skb, 0, 0,
@@ -428,7 +427,6 @@ __build_packet_message(struct nfulnl_instance *inst,
}
if (outdev) {
- tmp_uint = htonl(outdev->ifindex);
#ifndef CONFIG_BRIDGE_NETFILTER
NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV,
htonl(outdev->ifindex));
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 8a025a585d2..b0869fe3633 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -762,8 +762,8 @@ void xt_compat_unlock(u_int8_t af)
EXPORT_SYMBOL_GPL(xt_compat_unlock);
#endif
-DEFINE_PER_CPU(struct xt_info_lock, xt_info_locks);
-EXPORT_PER_CPU_SYMBOL_GPL(xt_info_locks);
+DEFINE_PER_CPU(seqcount_t, xt_recseq);
+EXPORT_PER_CPU_SYMBOL_GPL(xt_recseq);
static int xt_jumpstack_alloc(struct xt_table_info *i)
{
@@ -1362,10 +1362,7 @@ static int __init xt_init(void)
int rv;
for_each_possible_cpu(i) {
- struct xt_info_lock *lock = &per_cpu(xt_info_locks, i);
-
- seqlock_init(&lock->lock);
- lock->readers = 0;
+ seqcount_init(&per_cpu(xt_recseq, i));
}
xt = kmalloc(sizeof(struct xt_af) * NFPROTO_NUMPROTO, GFP_KERNEL);
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index 5f14c8462e3..bae5756b162 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -422,7 +422,6 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info)
{
int ret_val = -EINVAL;
- const char *type_str = "(unknown)";
struct netlbl_audit audit_info;
if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
@@ -432,15 +431,12 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info)
netlbl_netlink_auditinfo(skb, &audit_info);
switch (nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE])) {
case CIPSO_V4_MAP_TRANS:
- type_str = "trans";
ret_val = netlbl_cipsov4_add_std(info, &audit_info);
break;
case CIPSO_V4_MAP_PASS:
- type_str = "pass";
ret_val = netlbl_cipsov4_add_pass(info, &audit_info);
break;
case CIPSO_V4_MAP_LOCAL:
- type_str = "local";
ret_val = netlbl_cipsov4_add_local(info, &audit_info);
break;
}
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 06cb02796a0..732152f718e 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -591,7 +591,6 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
return -EINVAL;
}
if ((dev = nr_dev_get(&addr->fsa_ax25.sax25_call)) == NULL) {
- SOCK_DEBUG(sk, "NET/ROM: bind failed: invalid node callsign\n");
release_sock(sk);
return -EADDRNOTAVAIL;
}
@@ -632,7 +631,7 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
sock_reset_flag(sk, SOCK_ZAPPED);
dev_put(dev);
release_sock(sk);
- SOCK_DEBUG(sk, "NET/ROM: socket is bound\n");
+
return 0;
}
@@ -1082,8 +1081,6 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock,
sax.sax25_call = nr->dest_addr;
}
- SOCK_DEBUG(sk, "NET/ROM: sendto: Addresses built.\n");
-
/* Build a packet - the conventional user limit is 236 bytes. We can
do ludicrously large NetROM frames but must not overflow */
if (len > 65536) {
@@ -1091,7 +1088,6 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock,
goto out;
}
- SOCK_DEBUG(sk, "NET/ROM: sendto: building packet.\n");
size = len + NR_NETWORK_LEN + NR_TRANSPORT_LEN;
if ((skb = sock_alloc_send_skb(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL)
@@ -1105,7 +1101,6 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock,
*/
asmptr = skb_push(skb, NR_TRANSPORT_LEN);
- SOCK_DEBUG(sk, "Building NET/ROM Header.\n");
/* Build a NET/ROM Transport header */
@@ -1114,15 +1109,12 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock,
*asmptr++ = 0; /* To be filled in later */
*asmptr++ = 0; /* Ditto */
*asmptr++ = NR_INFO;
- SOCK_DEBUG(sk, "Built header.\n");
/*
* Put the data on the end
*/
skb_put(skb, len);
- SOCK_DEBUG(sk, "NET/ROM: Appending user data\n");
-
/* User data follows immediately after the NET/ROM transport header */
if (memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len)) {
kfree_skb(skb);
@@ -1130,8 +1122,6 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock,
goto out;
}
- SOCK_DEBUG(sk, "NET/ROM: Transmitting buffer\n");
-
if (sk->sk_state != TCP_ESTABLISHED) {
kfree_skb(skb);
err = -ENOTCONN;
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index b5362e96022..549527bca87 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -538,7 +538,7 @@ static inline unsigned int run_filter(const struct sk_buff *skb,
rcu_read_lock();
filter = rcu_dereference(sk->sk_filter);
if (filter != NULL)
- res = sk_run_filter(skb, filter->insns);
+ res = SK_RUN_FILTER(filter, skb);
rcu_read_unlock();
return res;
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
index 1566672235d..d2df8f33160 100644
--- a/net/phonet/pn_dev.c
+++ b/net/phonet/pn_dev.c
@@ -418,18 +418,14 @@ int phonet_route_del(struct net_device *dev, u8 daddr)
return 0;
}
-struct net_device *phonet_route_get(struct net *net, u8 daddr)
+struct net_device *phonet_route_get_rcu(struct net *net, u8 daddr)
{
struct phonet_net *pnn = phonet_pernet(net);
struct phonet_routes *routes = &pnn->routes;
struct net_device *dev;
- ASSERT_RTNL(); /* no need to hold the device */
-
daddr >>= 2;
- rcu_read_lock();
dev = rcu_dereference(routes->table[daddr]);
- rcu_read_unlock();
return dev;
}
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
index 58b3b1f991e..438accb7a5a 100644
--- a/net/phonet/pn_netlink.c
+++ b/net/phonet/pn_netlink.c
@@ -264,10 +264,11 @@ static int route_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
struct net *net = sock_net(skb->sk);
u8 addr, addr_idx = 0, addr_start_idx = cb->args[0];
+ rcu_read_lock();
for (addr = 0; addr < 64; addr++) {
struct net_device *dev;
- dev = phonet_route_get(net, addr << 2);
+ dev = phonet_route_get_rcu(net, addr << 2);
if (!dev)
continue;
@@ -279,6 +280,7 @@ static int route_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
}
out:
+ rcu_read_unlock();
cb->args[0] = addr_idx;
cb->args[1] = 0;
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index b1adafab377..8c5bfcef92c 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -52,7 +52,7 @@ static int pn_socket_release(struct socket *sock)
static struct {
struct hlist_head hlist[PN_HASHSIZE];
- spinlock_t lock;
+ struct mutex lock;
} pnsocks;
void __init pn_sock_init(void)
@@ -61,7 +61,7 @@ void __init pn_sock_init(void)
for (i = 0; i < PN_HASHSIZE; i++)
INIT_HLIST_HEAD(pnsocks.hlist + i);
- spin_lock_init(&pnsocks.lock);
+ mutex_init(&pnsocks.lock);
}
static struct hlist_head *pn_hash_list(u16 obj)
@@ -82,9 +82,8 @@ struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *spn)
u8 res = spn->spn_resource;
struct hlist_head *hlist = pn_hash_list(obj);
- spin_lock_bh(&pnsocks.lock);
-
- sk_for_each(sknode, node, hlist) {
+ rcu_read_lock();
+ sk_for_each_rcu(sknode, node, hlist) {
struct pn_sock *pn = pn_sk(sknode);
BUG_ON(!pn->sobject); /* unbound socket */
@@ -107,8 +106,7 @@ struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *spn)
sock_hold(sknode);
break;
}
-
- spin_unlock_bh(&pnsocks.lock);
+ rcu_read_unlock();
return rval;
}
@@ -119,7 +117,7 @@ void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb)
struct hlist_head *hlist = pnsocks.hlist;
unsigned h;
- spin_lock(&pnsocks.lock);
+ rcu_read_lock();
for (h = 0; h < PN_HASHSIZE; h++) {
struct hlist_node *node;
struct sock *sknode;
@@ -140,25 +138,26 @@ void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb)
}
hlist++;
}
- spin_unlock(&pnsocks.lock);
+ rcu_read_unlock();
}
void pn_sock_hash(struct sock *sk)
{
struct hlist_head *hlist = pn_hash_list(pn_sk(sk)->sobject);
- spin_lock_bh(&pnsocks.lock);
- sk_add_node(sk, hlist);
- spin_unlock_bh(&pnsocks.lock);
+ mutex_lock(&pnsocks.lock);
+ sk_add_node_rcu(sk, hlist);
+ mutex_unlock(&pnsocks.lock);
}
EXPORT_SYMBOL(pn_sock_hash);
void pn_sock_unhash(struct sock *sk)
{
- spin_lock_bh(&pnsocks.lock);
- sk_del_node_init(sk);
- spin_unlock_bh(&pnsocks.lock);
+ mutex_lock(&pnsocks.lock);
+ sk_del_node_init_rcu(sk);
+ mutex_unlock(&pnsocks.lock);
pn_sock_unbind_all_res(sk);
+ synchronize_rcu();
}
EXPORT_SYMBOL(pn_sock_unhash);
@@ -548,7 +547,7 @@ static struct sock *pn_sock_get_idx(struct seq_file *seq, loff_t pos)
unsigned h;
for (h = 0; h < PN_HASHSIZE; h++) {
- sk_for_each(sknode, node, hlist) {
+ sk_for_each_rcu(sknode, node, hlist) {
if (!net_eq(net, sock_net(sknode)))
continue;
if (!pos)
@@ -572,9 +571,9 @@ static struct sock *pn_sock_get_next(struct seq_file *seq, struct sock *sk)
}
static void *pn_sock_seq_start(struct seq_file *seq, loff_t *pos)
- __acquires(pnsocks.lock)
+ __acquires(rcu)
{
- spin_lock_bh(&pnsocks.lock);
+ rcu_read_lock();
return *pos ? pn_sock_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
}
@@ -591,9 +590,9 @@ static void *pn_sock_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void pn_sock_seq_stop(struct seq_file *seq, void *v)
- __releases(pnsocks.lock)
+ __releases(rcu)
{
- spin_unlock_bh(&pnsocks.lock);
+ rcu_read_unlock();
}
static int pn_sock_seq_show(struct seq_file *seq, void *v)
@@ -721,13 +720,11 @@ void pn_sock_unbind_all_res(struct sock *sk)
}
mutex_unlock(&resource_mutex);
- if (match == 0)
- return;
- synchronize_rcu();
while (match > 0) {
- sock_put(sk);
+ __sock_put(sk);
match--;
}
+ /* Caller is responsible for RCU sync before final sock_put() */
}
#ifdef CONFIG_PROC_FS
diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig
index 7fce6dfd218..48464ca13b2 100644
--- a/net/rfkill/Kconfig
+++ b/net/rfkill/Kconfig
@@ -22,3 +22,14 @@ config RFKILL_INPUT
depends on RFKILL
depends on INPUT = y || RFKILL = INPUT
default y if !EXPERT
+
+config RFKILL_REGULATOR
+ tristate "Generic rfkill regulator driver"
+ depends on RFKILL || !RFKILL
+ depends on REGULATOR
+ help
+ This options enable controlling radio transmitters connected to
+ voltage regulator using the regulator framework.
+
+ To compile this driver as a module, choose M here: the module will
+ be called rfkill-regulator.
diff --git a/net/rfkill/Makefile b/net/rfkill/Makefile
index 66210535269..d9a5a58ffd8 100644
--- a/net/rfkill/Makefile
+++ b/net/rfkill/Makefile
@@ -5,3 +5,4 @@
rfkill-y += core.o
rfkill-$(CONFIG_RFKILL_INPUT) += input.o
obj-$(CONFIG_RFKILL) += rfkill.o
+obj-$(CONFIG_RFKILL_REGULATOR) += rfkill-regulator.o
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 0198191b756..be90640a277 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -1024,7 +1024,6 @@ static int rfkill_fop_open(struct inode *inode, struct file *file)
* start getting events from elsewhere but hold mtx to get
* startup events added first
*/
- list_add(&data->list, &rfkill_fds);
list_for_each_entry(rfkill, &rfkill_list, node) {
ev = kzalloc(sizeof(*ev), GFP_KERNEL);
@@ -1033,6 +1032,7 @@ static int rfkill_fop_open(struct inode *inode, struct file *file)
rfkill_fill_event(&ev->ev, rfkill, RFKILL_OP_ADD);
list_add_tail(&ev->list, &data->events);
}
+ list_add(&data->list, &rfkill_fds);
mutex_unlock(&data->mtx);
mutex_unlock(&rfkill_global_mutex);
diff --git a/net/rfkill/rfkill-regulator.c b/net/rfkill/rfkill-regulator.c
new file mode 100644
index 00000000000..18dc512a10f
--- /dev/null
+++ b/net/rfkill/rfkill-regulator.c
@@ -0,0 +1,164 @@
+/*
+ * rfkill-regulator.c - Regulator consumer driver for rfkill
+ *
+ * Copyright (C) 2009 Guiming Zhuo <gmzhuo@gmail.com>
+ * Copyright (C) 2011 Antonio Ospite <ospite@studenti.unina.it>
+ *
+ * Implementation inspired by leds-regulator driver.
+ *
+ * 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/err.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/rfkill.h>
+#include <linux/rfkill-regulator.h>
+
+struct rfkill_regulator_data {
+ struct rfkill *rf_kill;
+ bool reg_enabled;
+
+ struct regulator *vcc;
+};
+
+static int rfkill_regulator_set_block(void *data, bool blocked)
+{
+ struct rfkill_regulator_data *rfkill_data = data;
+
+ pr_debug("%s: blocked: %d\n", __func__, blocked);
+
+ if (blocked) {
+ if (rfkill_data->reg_enabled) {
+ regulator_disable(rfkill_data->vcc);
+ rfkill_data->reg_enabled = 0;
+ }
+ } else {
+ if (!rfkill_data->reg_enabled) {
+ regulator_enable(rfkill_data->vcc);
+ rfkill_data->reg_enabled = 1;
+ }
+ }
+
+ pr_debug("%s: regulator_is_enabled after set_block: %d\n", __func__,
+ regulator_is_enabled(rfkill_data->vcc));
+
+ return 0;
+}
+
+struct rfkill_ops rfkill_regulator_ops = {
+ .set_block = rfkill_regulator_set_block,
+};
+
+static int __devinit rfkill_regulator_probe(struct platform_device *pdev)
+{
+ struct rfkill_regulator_platform_data *pdata = pdev->dev.platform_data;
+ struct rfkill_regulator_data *rfkill_data;
+ struct regulator *vcc;
+ struct rfkill *rf_kill;
+ int ret = 0;
+
+ if (pdata == NULL) {
+ dev_err(&pdev->dev, "no platform data\n");
+ return -ENODEV;
+ }
+
+ if (pdata->name == NULL || pdata->type == 0) {
+ dev_err(&pdev->dev, "invalid name or type in platform data\n");
+ return -EINVAL;
+ }
+
+ vcc = regulator_get_exclusive(&pdev->dev, "vrfkill");
+ if (IS_ERR(vcc)) {
+ dev_err(&pdev->dev, "Cannot get vcc for %s\n", pdata->name);
+ ret = PTR_ERR(vcc);
+ goto out;
+ }
+
+ rfkill_data = kzalloc(sizeof(*rfkill_data), GFP_KERNEL);
+ if (rfkill_data == NULL) {
+ ret = -ENOMEM;
+ goto err_data_alloc;
+ }
+
+ rf_kill = rfkill_alloc(pdata->name, &pdev->dev,
+ pdata->type,
+ &rfkill_regulator_ops, rfkill_data);
+ if (rf_kill == NULL) {
+ dev_err(&pdev->dev, "Cannot alloc rfkill device\n");
+ ret = -ENOMEM;
+ goto err_rfkill_alloc;
+ }
+
+ if (regulator_is_enabled(vcc)) {
+ dev_dbg(&pdev->dev, "Regulator already enabled\n");
+ rfkill_data->reg_enabled = 1;
+ }
+ rfkill_data->vcc = vcc;
+ rfkill_data->rf_kill = rf_kill;
+
+ ret = rfkill_register(rf_kill);
+ if (ret) {
+ dev_err(&pdev->dev, "Cannot register rfkill device\n");
+ goto err_rfkill_register;
+ }
+
+ platform_set_drvdata(pdev, rfkill_data);
+ dev_info(&pdev->dev, "%s initialized\n", pdata->name);
+
+ return 0;
+
+err_rfkill_register:
+ rfkill_destroy(rf_kill);
+err_rfkill_alloc:
+ kfree(rfkill_data);
+err_data_alloc:
+ regulator_put(vcc);
+out:
+ return ret;
+}
+
+static int __devexit rfkill_regulator_remove(struct platform_device *pdev)
+{
+ struct rfkill_regulator_data *rfkill_data = platform_get_drvdata(pdev);
+ struct rfkill *rf_kill = rfkill_data->rf_kill;
+
+ rfkill_unregister(rf_kill);
+ rfkill_destroy(rf_kill);
+ regulator_put(rfkill_data->vcc);
+ kfree(rfkill_data);
+
+ return 0;
+}
+
+static struct platform_driver rfkill_regulator_driver = {
+ .probe = rfkill_regulator_probe,
+ .remove = __devexit_p(rfkill_regulator_remove),
+ .driver = {
+ .name = "rfkill-regulator",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init rfkill_regulator_init(void)
+{
+ return platform_driver_register(&rfkill_regulator_driver);
+}
+module_init(rfkill_regulator_init);
+
+static void __exit rfkill_regulator_exit(void)
+{
+ platform_driver_unregister(&rfkill_regulator_driver);
+}
+module_exit(rfkill_regulator_exit);
+
+MODULE_AUTHOR("Guiming Zhuo <gmzhuo@gmail.com>");
+MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
+MODULE_DESCRIPTION("Regulator consumer driver for rfkill");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:rfkill-regulator");
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index a80aef6e3d1..f9ea925ad9c 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -682,10 +682,8 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS)
return -EINVAL;
- if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) {
- SOCK_DEBUG(sk, "ROSE: bind failed: invalid address\n");
+ if ((dev = rose_dev_get(&addr->srose_addr)) == NULL)
return -EADDRNOTAVAIL;
- }
source = &addr->srose_call;
@@ -716,7 +714,7 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
rose_insert_socket(sk);
sock_reset_flag(sk, SOCK_ZAPPED);
- SOCK_DEBUG(sk, "ROSE: socket is bound\n");
+
return 0;
}
@@ -1109,10 +1107,7 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock,
srose.srose_digis[n] = rose->dest_digis[n];
}
- SOCK_DEBUG(sk, "ROSE: sendto: Addresses built.\n");
-
/* Build a packet */
- SOCK_DEBUG(sk, "ROSE: sendto: building packet.\n");
/* Sanity check the packet size */
if (len > 65535)
return -EMSGSIZE;
@@ -1127,7 +1122,6 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock,
/*
* Put the data on the end
*/
- SOCK_DEBUG(sk, "ROSE: Appending user data\n");
skb_reset_transport_header(skb);
skb_put(skb, len);
@@ -1152,8 +1146,6 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock,
*/
asmptr = skb_push(skb, ROSE_MIN_LEN);
- SOCK_DEBUG(sk, "ROSE: Building Network Header.\n");
-
/* Build a ROSE Network header */
asmptr[0] = ((rose->lci >> 8) & 0x0F) | ROSE_GFI;
asmptr[1] = (rose->lci >> 0) & 0xFF;
@@ -1162,10 +1154,6 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock,
if (qbit)
asmptr[0] |= ROSE_Q_BIT;
- SOCK_DEBUG(sk, "ROSE: Built header.\n");
-
- SOCK_DEBUG(sk, "ROSE: Transmitting buffer\n");
-
if (sk->sk_state != TCP_ESTABLISHED) {
kfree_skb(skb);
return -ENOTCONN;
diff --git a/net/rxrpc/ar-ack.c b/net/rxrpc/ar-ack.c
index b6ffe4e1b84..f99cfce7ca9 100644
--- a/net/rxrpc/ar-ack.c
+++ b/net/rxrpc/ar-ack.c
@@ -375,7 +375,6 @@ protocol_error:
*/
static void rxrpc_rotate_tx_window(struct rxrpc_call *call, u32 hard)
{
- struct rxrpc_skb_priv *sp;
unsigned long _skb;
int tail = call->acks_tail, old_tail;
int win = CIRC_CNT(call->acks_head, tail, call->acks_winsz);
@@ -387,7 +386,6 @@ static void rxrpc_rotate_tx_window(struct rxrpc_call *call, u32 hard)
while (call->acks_hard < hard) {
smp_read_barrier_depends();
_skb = call->acks_window[tail] & ~1;
- sp = rxrpc_skb((struct sk_buff *) _skb);
rxrpc_free_skb((struct sk_buff *) _skb);
old_tail = tail;
tail = (tail + 1) & (call->acks_winsz - 1);
diff --git a/net/rxrpc/ar-connevent.c b/net/rxrpc/ar-connevent.c
index 0505cdc4d6d..e7ed43a54c4 100644
--- a/net/rxrpc/ar-connevent.c
+++ b/net/rxrpc/ar-connevent.c
@@ -259,7 +259,6 @@ void rxrpc_process_connection(struct work_struct *work)
{
struct rxrpc_connection *conn =
container_of(work, struct rxrpc_connection, processor);
- struct rxrpc_skb_priv *sp;
struct sk_buff *skb;
u32 abort_code = RX_PROTOCOL_ERROR;
int ret;
@@ -276,8 +275,6 @@ void rxrpc_process_connection(struct work_struct *work)
/* go through the conn-level event packets, releasing the ref on this
* connection that each one has when we've finished with it */
while ((skb = skb_dequeue(&conn->rx_queue))) {
- sp = rxrpc_skb(skb);
-
ret = rxrpc_process_event(conn, skb, &abort_code);
switch (ret) {
case -EPROTO:
diff --git a/net/rxrpc/ar-error.c b/net/rxrpc/ar-error.c
index d4d1ae26d29..5d6b572a670 100644
--- a/net/rxrpc/ar-error.c
+++ b/net/rxrpc/ar-error.c
@@ -139,7 +139,7 @@ void rxrpc_UDP_error_handler(struct work_struct *work)
struct rxrpc_transport *trans =
container_of(work, struct rxrpc_transport, error_handler);
struct sk_buff *skb;
- int local, err;
+ int err;
_enter("");
@@ -157,7 +157,6 @@ void rxrpc_UDP_error_handler(struct work_struct *work)
switch (ee->ee_origin) {
case SO_EE_ORIGIN_ICMP:
- local = 0;
switch (ee->ee_type) {
case ICMP_DEST_UNREACH:
switch (ee->ee_code) {
@@ -207,7 +206,6 @@ void rxrpc_UDP_error_handler(struct work_struct *work)
case SO_EE_ORIGIN_LOCAL:
_proto("Rx Received local error { error=%d }",
ee->ee_errno);
- local = 1;
break;
case SO_EE_ORIGIN_NONE:
@@ -215,7 +213,6 @@ void rxrpc_UDP_error_handler(struct work_struct *work)
default:
_proto("Rx Received error report { orig=%u }",
ee->ee_origin);
- local = 0;
break;
}
diff --git a/net/rxrpc/ar-peer.c b/net/rxrpc/ar-peer.c
index 55b93dc60d0..2754f098d43 100644
--- a/net/rxrpc/ar-peer.c
+++ b/net/rxrpc/ar-peer.c
@@ -36,10 +36,11 @@ static void rxrpc_destroy_peer(struct work_struct *work);
static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer)
{
struct rtable *rt;
+ struct flowi4 fl4;
peer->if_mtu = 1500;
- rt = ip_route_output_ports(&init_net, NULL,
+ rt = ip_route_output_ports(&init_net, &fl4, NULL,
peer->srx.transport.sin.sin_addr.s_addr, 0,
htons(7000), htons(7001),
IPPROTO_UDP, 0, 0);
@@ -156,6 +157,7 @@ struct rxrpc_peer *rxrpc_get_peer(struct sockaddr_rxrpc *srx, gfp_t gfp)
/* we can now add the new candidate to the list */
peer = candidate;
candidate = NULL;
+ usage = atomic_read(&peer->usage);
list_add_tail(&peer->link, &rxrpc_peers);
write_unlock_bh(&rxrpc_peer_lock);
@@ -170,7 +172,7 @@ success:
&peer->srx.transport.sin.sin_addr,
ntohs(peer->srx.transport.sin.sin_port));
- _leave(" = %p {u=%d}", peer, atomic_read(&peer->usage));
+ _leave(" = %p {u=%d}", peer, usage);
return peer;
/* we found the peer in the list immediately */
diff --git a/net/rxrpc/ar-transport.c b/net/rxrpc/ar-transport.c
index 5e0226fe587..92df566930b 100644
--- a/net/rxrpc/ar-transport.c
+++ b/net/rxrpc/ar-transport.c
@@ -111,6 +111,7 @@ struct rxrpc_transport *rxrpc_get_transport(struct rxrpc_local *local,
/* we can now add the new candidate to the list */
trans = candidate;
candidate = NULL;
+ usage = atomic_read(&trans->usage);
rxrpc_get_local(trans->local);
atomic_inc(&trans->peer->usage);
@@ -125,7 +126,7 @@ success:
trans->local->debug_id,
trans->peer->debug_id);
- _leave(" = %p {u=%d}", trans, atomic_read(&trans->usage));
+ _leave(" = %p {u=%d}", trans, usage);
return trans;
/* we found the transport in the list immediately */
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index a7a5583d4f6..2590e91b328 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -239,6 +239,17 @@ config NET_SCH_CHOKE
To compile this code as a module, choose M here: the
module will be called sch_choke.
+config NET_SCH_QFQ
+ tristate "Quick Fair Queueing scheduler (QFQ)"
+ help
+ Say Y here if you want to use the Quick Fair Queueing Scheduler (QFQ)
+ packet scheduling algorithm.
+
+ To compile this driver as a module, choose M here: the module
+ will be called sch_qfq.
+
+ If unsure, say N.
+
config NET_SCH_INGRESS
tristate "Ingress Qdisc"
depends on NET_CLS_ACT
@@ -277,6 +288,7 @@ config NET_CLS_TCINDEX
config NET_CLS_ROUTE4
tristate "Routing decision (ROUTE)"
+ depends on INET
select IP_ROUTE_CLASSID
select NET_CLS
---help---
diff --git a/net/sched/Makefile b/net/sched/Makefile
index 2e77b8dba22..dc5889c0a15 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_NET_SCH_NETEM) += sch_netem.o
obj-$(CONFIG_NET_SCH_DRR) += sch_drr.o
obj-$(CONFIG_NET_SCH_MQPRIO) += sch_mqprio.o
obj-$(CONFIG_NET_SCH_CHOKE) += sch_choke.o
+obj-$(CONFIG_NET_SCH_QFQ) += sch_qfq.o
obj-$(CONFIG_NET_CLS_U32) += cls_u32.o
obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 7490f3f2db8..6b8627661c9 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1673,10 +1673,8 @@ int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
{
int err = 0;
#ifdef CONFIG_NET_CLS_ACT
- __be16 protocol;
struct tcf_proto *otp = tp;
reclassify:
- protocol = skb->protocol;
#endif
err = tc_classify_compat(skb, tp, res);
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
new file mode 100644
index 00000000000..10334340859
--- /dev/null
+++ b/net/sched/sch_qfq.c
@@ -0,0 +1,1137 @@
+/*
+ * net/sched/sch_qfq.c Quick Fair Queueing Scheduler.
+ *
+ * Copyright (c) 2009 Fabio Checconi, Luigi Rizzo, and Paolo Valente.
+ *
+ * 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/init.h>
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/pkt_sched.h>
+#include <net/sch_generic.h>
+#include <net/pkt_sched.h>
+#include <net/pkt_cls.h>
+
+
+/* Quick Fair Queueing
+ ===================
+
+ Sources:
+
+ Fabio Checconi, Luigi Rizzo, and Paolo Valente: "QFQ: Efficient
+ Packet Scheduling with Tight Bandwidth Distribution Guarantees."
+
+ See also:
+ http://retis.sssup.it/~fabio/linux/qfq/
+ */
+
+/*
+
+ Virtual time computations.
+
+ S, F and V are all computed in fixed point arithmetic with
+ FRAC_BITS decimal bits.
+
+ QFQ_MAX_INDEX is the maximum index allowed for a group. We need
+ one bit per index.
+ QFQ_MAX_WSHIFT is the maximum power of two supported as a weight.
+
+ The layout of the bits is as below:
+
+ [ MTU_SHIFT ][ FRAC_BITS ]
+ [ MAX_INDEX ][ MIN_SLOT_SHIFT ]
+ ^.__grp->index = 0
+ *.__grp->slot_shift
+
+ where MIN_SLOT_SHIFT is derived by difference from the others.
+
+ The max group index corresponds to Lmax/w_min, where
+ Lmax=1<<MTU_SHIFT, w_min = 1 .
+ From this, and knowing how many groups (MAX_INDEX) we want,
+ we can derive the shift corresponding to each group.
+
+ Because we often need to compute
+ F = S + len/w_i and V = V + len/wsum
+ instead of storing w_i store the value
+ inv_w = (1<<FRAC_BITS)/w_i
+ so we can do F = S + len * inv_w * wsum.
+ We use W_TOT in the formulas so we can easily move between
+ static and adaptive weight sum.
+
+ The per-scheduler-instance data contain all the data structures
+ for the scheduler: bitmaps and bucket lists.
+
+ */
+
+/*
+ * Maximum number of consecutive slots occupied by backlogged classes
+ * inside a group.
+ */
+#define QFQ_MAX_SLOTS 32
+
+/*
+ * Shifts used for class<->group mapping. We allow class weights that are
+ * in the range [1, 2^MAX_WSHIFT], and we try to map each class i to the
+ * group with the smallest index that can support the L_i / r_i configured
+ * for the class.
+ *
+ * grp->index is the index of the group; and grp->slot_shift
+ * is the shift for the corresponding (scaled) sigma_i.
+ */
+#define QFQ_MAX_INDEX 19
+#define QFQ_MAX_WSHIFT 16
+
+#define QFQ_MAX_WEIGHT (1<<QFQ_MAX_WSHIFT)
+#define QFQ_MAX_WSUM (2*QFQ_MAX_WEIGHT)
+
+#define FRAC_BITS 30 /* fixed point arithmetic */
+#define ONE_FP (1UL << FRAC_BITS)
+#define IWSUM (ONE_FP/QFQ_MAX_WSUM)
+
+#define QFQ_MTU_SHIFT 11
+#define QFQ_MIN_SLOT_SHIFT (FRAC_BITS + QFQ_MTU_SHIFT - QFQ_MAX_INDEX)
+
+/*
+ * Possible group states. These values are used as indexes for the bitmaps
+ * array of struct qfq_queue.
+ */
+enum qfq_state { ER, IR, EB, IB, QFQ_MAX_STATE };
+
+struct qfq_group;
+
+struct qfq_class {
+ struct Qdisc_class_common common;
+
+ unsigned int refcnt;
+ unsigned int filter_cnt;
+
+ struct gnet_stats_basic_packed bstats;
+ struct gnet_stats_queue qstats;
+ struct gnet_stats_rate_est rate_est;
+ struct Qdisc *qdisc;
+
+ struct hlist_node next; /* Link for the slot list. */
+ u64 S, F; /* flow timestamps (exact) */
+
+ /* group we belong to. In principle we would need the index,
+ * which is log_2(lmax/weight), but we never reference it
+ * directly, only the group.
+ */
+ struct qfq_group *grp;
+
+ /* these are copied from the flowset. */
+ u32 inv_w; /* ONE_FP/weight */
+ u32 lmax; /* Max packet size for this flow. */
+};
+
+struct qfq_group {
+ u64 S, F; /* group timestamps (approx). */
+ unsigned int slot_shift; /* Slot shift. */
+ unsigned int index; /* Group index. */
+ unsigned int front; /* Index of the front slot. */
+ unsigned long full_slots; /* non-empty slots */
+
+ /* Array of RR lists of active classes. */
+ struct hlist_head slots[QFQ_MAX_SLOTS];
+};
+
+struct qfq_sched {
+ struct tcf_proto *filter_list;
+ struct Qdisc_class_hash clhash;
+
+ u64 V; /* Precise virtual time. */
+ u32 wsum; /* weight sum */
+
+ unsigned long bitmaps[QFQ_MAX_STATE]; /* Group bitmaps. */
+ struct qfq_group groups[QFQ_MAX_INDEX + 1]; /* The groups. */
+};
+
+static struct qfq_class *qfq_find_class(struct Qdisc *sch, u32 classid)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct Qdisc_class_common *clc;
+
+ clc = qdisc_class_find(&q->clhash, classid);
+ if (clc == NULL)
+ return NULL;
+ return container_of(clc, struct qfq_class, common);
+}
+
+static void qfq_purge_queue(struct qfq_class *cl)
+{
+ unsigned int len = cl->qdisc->q.qlen;
+
+ qdisc_reset(cl->qdisc);
+ qdisc_tree_decrease_qlen(cl->qdisc, len);
+}
+
+static const struct nla_policy qfq_policy[TCA_QFQ_MAX + 1] = {
+ [TCA_QFQ_WEIGHT] = { .type = NLA_U32 },
+ [TCA_QFQ_LMAX] = { .type = NLA_U32 },
+};
+
+/*
+ * Calculate a flow index, given its weight and maximum packet length.
+ * index = log_2(maxlen/weight) but we need to apply the scaling.
+ * This is used only once at flow creation.
+ */
+static int qfq_calc_index(u32 inv_w, unsigned int maxlen)
+{
+ u64 slot_size = (u64)maxlen * inv_w;
+ unsigned long size_map;
+ int index = 0;
+
+ size_map = slot_size >> QFQ_MIN_SLOT_SHIFT;
+ if (!size_map)
+ goto out;
+
+ index = __fls(size_map) + 1; /* basically a log_2 */
+ index -= !(slot_size - (1ULL << (index + QFQ_MIN_SLOT_SHIFT - 1)));
+
+ if (index < 0)
+ index = 0;
+out:
+ pr_debug("qfq calc_index: W = %lu, L = %u, I = %d\n",
+ (unsigned long) ONE_FP/inv_w, maxlen, index);
+
+ return index;
+}
+
+static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
+ struct nlattr **tca, unsigned long *arg)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_class *cl = (struct qfq_class *)*arg;
+ struct nlattr *tb[TCA_QFQ_MAX + 1];
+ u32 weight, lmax, inv_w;
+ int i, err;
+
+ if (tca[TCA_OPTIONS] == NULL) {
+ pr_notice("qfq: no options\n");
+ return -EINVAL;
+ }
+
+ err = nla_parse_nested(tb, TCA_QFQ_MAX, tca[TCA_OPTIONS], qfq_policy);
+ if (err < 0)
+ return err;
+
+ if (tb[TCA_QFQ_WEIGHT]) {
+ weight = nla_get_u32(tb[TCA_QFQ_WEIGHT]);
+ if (!weight || weight > (1UL << QFQ_MAX_WSHIFT)) {
+ pr_notice("qfq: invalid weight %u\n", weight);
+ return -EINVAL;
+ }
+ } else
+ weight = 1;
+
+ inv_w = ONE_FP / weight;
+ weight = ONE_FP / inv_w;
+ if (q->wsum + weight > QFQ_MAX_WSUM) {
+ pr_notice("qfq: total weight out of range (%u + %u)\n",
+ weight, q->wsum);
+ return -EINVAL;
+ }
+
+ if (tb[TCA_QFQ_LMAX]) {
+ lmax = nla_get_u32(tb[TCA_QFQ_LMAX]);
+ if (!lmax || lmax > (1UL << QFQ_MTU_SHIFT)) {
+ pr_notice("qfq: invalid max length %u\n", lmax);
+ return -EINVAL;
+ }
+ } else
+ lmax = 1UL << QFQ_MTU_SHIFT;
+
+ if (cl != NULL) {
+ if (tca[TCA_RATE]) {
+ err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
+ qdisc_root_sleeping_lock(sch),
+ tca[TCA_RATE]);
+ if (err)
+ return err;
+ }
+
+ sch_tree_lock(sch);
+ if (tb[TCA_QFQ_WEIGHT]) {
+ q->wsum = weight - ONE_FP / cl->inv_w;
+ cl->inv_w = inv_w;
+ }
+ sch_tree_unlock(sch);
+
+ return 0;
+ }
+
+ cl = kzalloc(sizeof(struct qfq_class), GFP_KERNEL);
+ if (cl == NULL)
+ return -ENOBUFS;
+
+ cl->refcnt = 1;
+ cl->common.classid = classid;
+ cl->lmax = lmax;
+ cl->inv_w = inv_w;
+ i = qfq_calc_index(cl->inv_w, cl->lmax);
+
+ cl->grp = &q->groups[i];
+ q->wsum += weight;
+
+ cl->qdisc = qdisc_create_dflt(sch->dev_queue,
+ &pfifo_qdisc_ops, classid);
+ if (cl->qdisc == NULL)
+ cl->qdisc = &noop_qdisc;
+
+ if (tca[TCA_RATE]) {
+ err = gen_new_estimator(&cl->bstats, &cl->rate_est,
+ qdisc_root_sleeping_lock(sch),
+ tca[TCA_RATE]);
+ if (err) {
+ qdisc_destroy(cl->qdisc);
+ kfree(cl);
+ return err;
+ }
+ }
+
+ sch_tree_lock(sch);
+ qdisc_class_hash_insert(&q->clhash, &cl->common);
+ sch_tree_unlock(sch);
+
+ qdisc_class_hash_grow(sch, &q->clhash);
+
+ *arg = (unsigned long)cl;
+ return 0;
+}
+
+static void qfq_destroy_class(struct Qdisc *sch, struct qfq_class *cl)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+
+ if (cl->inv_w) {
+ q->wsum -= ONE_FP / cl->inv_w;
+ cl->inv_w = 0;
+ }
+
+ gen_kill_estimator(&cl->bstats, &cl->rate_est);
+ qdisc_destroy(cl->qdisc);
+ kfree(cl);
+}
+
+static int qfq_delete_class(struct Qdisc *sch, unsigned long arg)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_class *cl = (struct qfq_class *)arg;
+
+ if (cl->filter_cnt > 0)
+ return -EBUSY;
+
+ sch_tree_lock(sch);
+
+ qfq_purge_queue(cl);
+ qdisc_class_hash_remove(&q->clhash, &cl->common);
+
+ BUG_ON(--cl->refcnt == 0);
+ /*
+ * This shouldn't happen: we "hold" one cops->get() when called
+ * from tc_ctl_tclass; the destroy method is done from cops->put().
+ */
+
+ sch_tree_unlock(sch);
+ return 0;
+}
+
+static unsigned long qfq_get_class(struct Qdisc *sch, u32 classid)
+{
+ struct qfq_class *cl = qfq_find_class(sch, classid);
+
+ if (cl != NULL)
+ cl->refcnt++;
+
+ return (unsigned long)cl;
+}
+
+static void qfq_put_class(struct Qdisc *sch, unsigned long arg)
+{
+ struct qfq_class *cl = (struct qfq_class *)arg;
+
+ if (--cl->refcnt == 0)
+ qfq_destroy_class(sch, cl);
+}
+
+static struct tcf_proto **qfq_tcf_chain(struct Qdisc *sch, unsigned long cl)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+
+ if (cl)
+ return NULL;
+
+ return &q->filter_list;
+}
+
+static unsigned long qfq_bind_tcf(struct Qdisc *sch, unsigned long parent,
+ u32 classid)
+{
+ struct qfq_class *cl = qfq_find_class(sch, classid);
+
+ if (cl != NULL)
+ cl->filter_cnt++;
+
+ return (unsigned long)cl;
+}
+
+static void qfq_unbind_tcf(struct Qdisc *sch, unsigned long arg)
+{
+ struct qfq_class *cl = (struct qfq_class *)arg;
+
+ cl->filter_cnt--;
+}
+
+static int qfq_graft_class(struct Qdisc *sch, unsigned long arg,
+ struct Qdisc *new, struct Qdisc **old)
+{
+ struct qfq_class *cl = (struct qfq_class *)arg;
+
+ if (new == NULL) {
+ new = qdisc_create_dflt(sch->dev_queue,
+ &pfifo_qdisc_ops, cl->common.classid);
+ if (new == NULL)
+ new = &noop_qdisc;
+ }
+
+ sch_tree_lock(sch);
+ qfq_purge_queue(cl);
+ *old = cl->qdisc;
+ cl->qdisc = new;
+ sch_tree_unlock(sch);
+ return 0;
+}
+
+static struct Qdisc *qfq_class_leaf(struct Qdisc *sch, unsigned long arg)
+{
+ struct qfq_class *cl = (struct qfq_class *)arg;
+
+ return cl->qdisc;
+}
+
+static int qfq_dump_class(struct Qdisc *sch, unsigned long arg,
+ struct sk_buff *skb, struct tcmsg *tcm)
+{
+ struct qfq_class *cl = (struct qfq_class *)arg;
+ struct nlattr *nest;
+
+ tcm->tcm_parent = TC_H_ROOT;
+ tcm->tcm_handle = cl->common.classid;
+ tcm->tcm_info = cl->qdisc->handle;
+
+ nest = nla_nest_start(skb, TCA_OPTIONS);
+ if (nest == NULL)
+ goto nla_put_failure;
+ NLA_PUT_U32(skb, TCA_QFQ_WEIGHT, ONE_FP/cl->inv_w);
+ NLA_PUT_U32(skb, TCA_QFQ_LMAX, cl->lmax);
+ return nla_nest_end(skb, nest);
+
+nla_put_failure:
+ nla_nest_cancel(skb, nest);
+ return -EMSGSIZE;
+}
+
+static int qfq_dump_class_stats(struct Qdisc *sch, unsigned long arg,
+ struct gnet_dump *d)
+{
+ struct qfq_class *cl = (struct qfq_class *)arg;
+ struct tc_qfq_stats xstats;
+
+ memset(&xstats, 0, sizeof(xstats));
+ cl->qdisc->qstats.qlen = cl->qdisc->q.qlen;
+
+ xstats.weight = ONE_FP/cl->inv_w;
+ xstats.lmax = cl->lmax;
+
+ if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
+ gnet_stats_copy_rate_est(d, &cl->bstats, &cl->rate_est) < 0 ||
+ gnet_stats_copy_queue(d, &cl->qdisc->qstats) < 0)
+ return -1;
+
+ return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
+}
+
+static void qfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_class *cl;
+ struct hlist_node *n;
+ unsigned int i;
+
+ if (arg->stop)
+ return;
+
+ for (i = 0; i < q->clhash.hashsize; i++) {
+ hlist_for_each_entry(cl, n, &q->clhash.hash[i], common.hnode) {
+ if (arg->count < arg->skip) {
+ arg->count++;
+ continue;
+ }
+ if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
+ arg->stop = 1;
+ return;
+ }
+ arg->count++;
+ }
+ }
+}
+
+static struct qfq_class *qfq_classify(struct sk_buff *skb, struct Qdisc *sch,
+ int *qerr)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_class *cl;
+ struct tcf_result res;
+ int result;
+
+ if (TC_H_MAJ(skb->priority ^ sch->handle) == 0) {
+ pr_debug("qfq_classify: found %d\n", skb->priority);
+ cl = qfq_find_class(sch, skb->priority);
+ if (cl != NULL)
+ return cl;
+ }
+
+ *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
+ result = tc_classify(skb, q->filter_list, &res);
+ if (result >= 0) {
+#ifdef CONFIG_NET_CLS_ACT
+ switch (result) {
+ case TC_ACT_QUEUED:
+ case TC_ACT_STOLEN:
+ *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
+ case TC_ACT_SHOT:
+ return NULL;
+ }
+#endif
+ cl = (struct qfq_class *)res.class;
+ if (cl == NULL)
+ cl = qfq_find_class(sch, res.classid);
+ return cl;
+ }
+
+ return NULL;
+}
+
+/* Generic comparison function, handling wraparound. */
+static inline int qfq_gt(u64 a, u64 b)
+{
+ return (s64)(a - b) > 0;
+}
+
+/* Round a precise timestamp to its slotted value. */
+static inline u64 qfq_round_down(u64 ts, unsigned int shift)
+{
+ return ts & ~((1ULL << shift) - 1);
+}
+
+/* return the pointer to the group with lowest index in the bitmap */
+static inline struct qfq_group *qfq_ffs(struct qfq_sched *q,
+ unsigned long bitmap)
+{
+ int index = __ffs(bitmap);
+ return &q->groups[index];
+}
+/* Calculate a mask to mimic what would be ffs_from(). */
+static inline unsigned long mask_from(unsigned long bitmap, int from)
+{
+ return bitmap & ~((1UL << from) - 1);
+}
+
+/*
+ * The state computation relies on ER=0, IR=1, EB=2, IB=3
+ * First compute eligibility comparing grp->S, q->V,
+ * then check if someone is blocking us and possibly add EB
+ */
+static int qfq_calc_state(struct qfq_sched *q, const struct qfq_group *grp)
+{
+ /* if S > V we are not eligible */
+ unsigned int state = qfq_gt(grp->S, q->V);
+ unsigned long mask = mask_from(q->bitmaps[ER], grp->index);
+ struct qfq_group *next;
+
+ if (mask) {
+ next = qfq_ffs(q, mask);
+ if (qfq_gt(grp->F, next->F))
+ state |= EB;
+ }
+
+ return state;
+}
+
+
+/*
+ * In principle
+ * q->bitmaps[dst] |= q->bitmaps[src] & mask;
+ * q->bitmaps[src] &= ~mask;
+ * but we should make sure that src != dst
+ */
+static inline void qfq_move_groups(struct qfq_sched *q, unsigned long mask,
+ int src, int dst)
+{
+ q->bitmaps[dst] |= q->bitmaps[src] & mask;
+ q->bitmaps[src] &= ~mask;
+}
+
+static void qfq_unblock_groups(struct qfq_sched *q, int index, u64 old_F)
+{
+ unsigned long mask = mask_from(q->bitmaps[ER], index + 1);
+ struct qfq_group *next;
+
+ if (mask) {
+ next = qfq_ffs(q, mask);
+ if (!qfq_gt(next->F, old_F))
+ return;
+ }
+
+ mask = (1UL << index) - 1;
+ qfq_move_groups(q, mask, EB, ER);
+ qfq_move_groups(q, mask, IB, IR);
+}
+
+/*
+ * perhaps
+ *
+ old_V ^= q->V;
+ old_V >>= QFQ_MIN_SLOT_SHIFT;
+ if (old_V) {
+ ...
+ }
+ *
+ */
+static void qfq_make_eligible(struct qfq_sched *q, u64 old_V)
+{
+ unsigned long vslot = q->V >> QFQ_MIN_SLOT_SHIFT;
+ unsigned long old_vslot = old_V >> QFQ_MIN_SLOT_SHIFT;
+
+ if (vslot != old_vslot) {
+ unsigned long mask = (1UL << fls(vslot ^ old_vslot)) - 1;
+ qfq_move_groups(q, mask, IR, ER);
+ qfq_move_groups(q, mask, IB, EB);
+ }
+}
+
+
+/*
+ * XXX we should make sure that slot becomes less than 32.
+ * This is guaranteed by the input values.
+ * roundedS is always cl->S rounded on grp->slot_shift bits.
+ */
+static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl,
+ u64 roundedS)
+{
+ u64 slot = (roundedS - grp->S) >> grp->slot_shift;
+ unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS;
+
+ hlist_add_head(&cl->next, &grp->slots[i]);
+ __set_bit(slot, &grp->full_slots);
+}
+
+/* Maybe introduce hlist_first_entry?? */
+static struct qfq_class *qfq_slot_head(struct qfq_group *grp)
+{
+ return hlist_entry(grp->slots[grp->front].first,
+ struct qfq_class, next);
+}
+
+/*
+ * remove the entry from the slot
+ */
+static void qfq_front_slot_remove(struct qfq_group *grp)
+{
+ struct qfq_class *cl = qfq_slot_head(grp);
+
+ BUG_ON(!cl);
+ hlist_del(&cl->next);
+ if (hlist_empty(&grp->slots[grp->front]))
+ __clear_bit(0, &grp->full_slots);
+}
+
+/*
+ * Returns the first full queue in a group. As a side effect,
+ * adjust the bucket list so the first non-empty bucket is at
+ * position 0 in full_slots.
+ */
+static struct qfq_class *qfq_slot_scan(struct qfq_group *grp)
+{
+ unsigned int i;
+
+ pr_debug("qfq slot_scan: grp %u full %#lx\n",
+ grp->index, grp->full_slots);
+
+ if (grp->full_slots == 0)
+ return NULL;
+
+ i = __ffs(grp->full_slots); /* zero based */
+ if (i > 0) {
+ grp->front = (grp->front + i) % QFQ_MAX_SLOTS;
+ grp->full_slots >>= i;
+ }
+
+ return qfq_slot_head(grp);
+}
+
+/*
+ * adjust the bucket list. When the start time of a group decreases,
+ * we move the index down (modulo QFQ_MAX_SLOTS) so we don't need to
+ * move the objects. The mask of occupied slots must be shifted
+ * because we use ffs() to find the first non-empty slot.
+ * This covers decreases in the group's start time, but what about
+ * increases of the start time ?
+ * Here too we should make sure that i is less than 32
+ */
+static void qfq_slot_rotate(struct qfq_group *grp, u64 roundedS)
+{
+ unsigned int i = (grp->S - roundedS) >> grp->slot_shift;
+
+ grp->full_slots <<= i;
+ grp->front = (grp->front - i) % QFQ_MAX_SLOTS;
+}
+
+static void qfq_update_eligible(struct qfq_sched *q, u64 old_V)
+{
+ struct qfq_group *grp;
+ unsigned long ineligible;
+
+ ineligible = q->bitmaps[IR] | q->bitmaps[IB];
+ if (ineligible) {
+ if (!q->bitmaps[ER]) {
+ grp = qfq_ffs(q, ineligible);
+ if (qfq_gt(grp->S, q->V))
+ q->V = grp->S;
+ }
+ qfq_make_eligible(q, old_V);
+ }
+}
+
+/* What is length of next packet in queue (0 if queue is empty) */
+static unsigned int qdisc_peek_len(struct Qdisc *sch)
+{
+ struct sk_buff *skb;
+
+ skb = sch->ops->peek(sch);
+ return skb ? qdisc_pkt_len(skb) : 0;
+}
+
+/*
+ * Updates the class, returns true if also the group needs to be updated.
+ */
+static bool qfq_update_class(struct qfq_group *grp, struct qfq_class *cl)
+{
+ unsigned int len = qdisc_peek_len(cl->qdisc);
+
+ cl->S = cl->F;
+ if (!len)
+ qfq_front_slot_remove(grp); /* queue is empty */
+ else {
+ u64 roundedS;
+
+ cl->F = cl->S + (u64)len * cl->inv_w;
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ if (roundedS == grp->S)
+ return false;
+
+ qfq_front_slot_remove(grp);
+ qfq_slot_insert(grp, cl, roundedS);
+ }
+
+ return true;
+}
+
+static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_group *grp;
+ struct qfq_class *cl;
+ struct sk_buff *skb;
+ unsigned int len;
+ u64 old_V;
+
+ if (!q->bitmaps[ER])
+ return NULL;
+
+ grp = qfq_ffs(q, q->bitmaps[ER]);
+
+ cl = qfq_slot_head(grp);
+ skb = qdisc_dequeue_peeked(cl->qdisc);
+ if (!skb) {
+ WARN_ONCE(1, "qfq_dequeue: non-workconserving leaf\n");
+ return NULL;
+ }
+
+ sch->q.qlen--;
+ qdisc_bstats_update(sch, skb);
+
+ old_V = q->V;
+ len = qdisc_pkt_len(skb);
+ q->V += (u64)len * IWSUM;
+ pr_debug("qfq dequeue: len %u F %lld now %lld\n",
+ len, (unsigned long long) cl->F, (unsigned long long) q->V);
+
+ if (qfq_update_class(grp, cl)) {
+ u64 old_F = grp->F;
+
+ cl = qfq_slot_scan(grp);
+ if (!cl)
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ else {
+ u64 roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ unsigned int s;
+
+ if (grp->S == roundedS)
+ goto skip_unblock;
+ grp->S = roundedS;
+ grp->F = roundedS + (2ULL << grp->slot_shift);
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ s = qfq_calc_state(q, grp);
+ __set_bit(grp->index, &q->bitmaps[s]);
+ }
+
+ qfq_unblock_groups(q, grp->index, old_F);
+ }
+
+skip_unblock:
+ qfq_update_eligible(q, old_V);
+
+ return skb;
+}
+
+/*
+ * Assign a reasonable start time for a new flow k in group i.
+ * Admissible values for \hat(F) are multiples of \sigma_i
+ * no greater than V+\sigma_i . Larger values mean that
+ * we had a wraparound so we consider the timestamp to be stale.
+ *
+ * If F is not stale and F >= V then we set S = F.
+ * Otherwise we should assign S = V, but this may violate
+ * the ordering in ER. So, if we have groups in ER, set S to
+ * the F_j of the first group j which would be blocking us.
+ * We are guaranteed not to move S backward because
+ * otherwise our group i would still be blocked.
+ */
+static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl)
+{
+ unsigned long mask;
+ uint32_t limit, roundedF;
+ int slot_shift = cl->grp->slot_shift;
+
+ roundedF = qfq_round_down(cl->F, slot_shift);
+ limit = qfq_round_down(q->V, slot_shift) + (1UL << slot_shift);
+
+ if (!qfq_gt(cl->F, q->V) || qfq_gt(roundedF, limit)) {
+ /* timestamp was stale */
+ mask = mask_from(q->bitmaps[ER], cl->grp->index);
+ if (mask) {
+ struct qfq_group *next = qfq_ffs(q, mask);
+ if (qfq_gt(roundedF, next->F)) {
+ cl->S = next->F;
+ return;
+ }
+ }
+ cl->S = q->V;
+ } else /* timestamp is not stale */
+ cl->S = cl->F;
+}
+
+static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_group *grp;
+ struct qfq_class *cl;
+ int err;
+ u64 roundedS;
+ int s;
+
+ cl = qfq_classify(skb, sch, &err);
+ if (cl == NULL) {
+ if (err & __NET_XMIT_BYPASS)
+ sch->qstats.drops++;
+ kfree_skb(skb);
+ return err;
+ }
+ pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid);
+
+ err = qdisc_enqueue(skb, cl->qdisc);
+ if (unlikely(err != NET_XMIT_SUCCESS)) {
+ pr_debug("qfq_enqueue: enqueue failed %d\n", err);
+ if (net_xmit_drop_count(err)) {
+ cl->qstats.drops++;
+ sch->qstats.drops++;
+ }
+ return err;
+ }
+
+ bstats_update(&cl->bstats, skb);
+ ++sch->q.qlen;
+
+ /* If the new skb is not the head of queue, then done here. */
+ if (cl->qdisc->q.qlen != 1)
+ return err;
+
+ /* If reach this point, queue q was idle */
+ grp = cl->grp;
+ qfq_update_start(q, cl);
+
+ /* compute new finish time and rounded start. */
+ cl->F = cl->S + (u64)qdisc_pkt_len(skb) * cl->inv_w;
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+
+ /*
+ * insert cl in the correct bucket.
+ * If cl->S >= grp->S we don't need to adjust the
+ * bucket list and simply go to the insertion phase.
+ * Otherwise grp->S is decreasing, we must make room
+ * in the bucket list, and also recompute the group state.
+ * Finally, if there were no flows in this group and nobody
+ * was in ER make sure to adjust V.
+ */
+ if (grp->full_slots) {
+ if (!qfq_gt(grp->S, cl->S))
+ goto skip_update;
+
+ /* create a slot for this cl->S */
+ qfq_slot_rotate(grp, roundedS);
+ /* group was surely ineligible, remove */
+ __clear_bit(grp->index, &q->bitmaps[IR]);
+ __clear_bit(grp->index, &q->bitmaps[IB]);
+ } else if (!q->bitmaps[ER] && qfq_gt(roundedS, q->V))
+ q->V = roundedS;
+
+ grp->S = roundedS;
+ grp->F = roundedS + (2ULL << grp->slot_shift);
+ s = qfq_calc_state(q, grp);
+ __set_bit(grp->index, &q->bitmaps[s]);
+
+ pr_debug("qfq enqueue: new state %d %#lx S %lld F %lld V %lld\n",
+ s, q->bitmaps[s],
+ (unsigned long long) cl->S,
+ (unsigned long long) cl->F,
+ (unsigned long long) q->V);
+
+skip_update:
+ qfq_slot_insert(grp, cl, roundedS);
+
+ return err;
+}
+
+
+static void qfq_slot_remove(struct qfq_sched *q, struct qfq_group *grp,
+ struct qfq_class *cl)
+{
+ unsigned int i, offset;
+ u64 roundedS;
+
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ offset = (roundedS - grp->S) >> grp->slot_shift;
+ i = (grp->front + offset) % QFQ_MAX_SLOTS;
+
+ hlist_del(&cl->next);
+ if (hlist_empty(&grp->slots[i]))
+ __clear_bit(offset, &grp->full_slots);
+}
+
+/*
+ * called to forcibly destroy a queue.
+ * If the queue is not in the front bucket, or if it has
+ * other queues in the front bucket, we can simply remove
+ * the queue with no other side effects.
+ * Otherwise we must propagate the event up.
+ */
+static void qfq_deactivate_class(struct qfq_sched *q, struct qfq_class *cl)
+{
+ struct qfq_group *grp = cl->grp;
+ unsigned long mask;
+ u64 roundedS;
+ int s;
+
+ cl->F = cl->S;
+ qfq_slot_remove(q, grp, cl);
+
+ if (!grp->full_slots) {
+ __clear_bit(grp->index, &q->bitmaps[IR]);
+ __clear_bit(grp->index, &q->bitmaps[EB]);
+ __clear_bit(grp->index, &q->bitmaps[IB]);
+
+ if (test_bit(grp->index, &q->bitmaps[ER]) &&
+ !(q->bitmaps[ER] & ~((1UL << grp->index) - 1))) {
+ mask = q->bitmaps[ER] & ((1UL << grp->index) - 1);
+ if (mask)
+ mask = ~((1UL << __fls(mask)) - 1);
+ else
+ mask = ~0UL;
+ qfq_move_groups(q, mask, EB, ER);
+ qfq_move_groups(q, mask, IB, IR);
+ }
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ } else if (hlist_empty(&grp->slots[grp->front])) {
+ cl = qfq_slot_scan(grp);
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ if (grp->S != roundedS) {
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ __clear_bit(grp->index, &q->bitmaps[IR]);
+ __clear_bit(grp->index, &q->bitmaps[EB]);
+ __clear_bit(grp->index, &q->bitmaps[IB]);
+ grp->S = roundedS;
+ grp->F = roundedS + (2ULL << grp->slot_shift);
+ s = qfq_calc_state(q, grp);
+ __set_bit(grp->index, &q->bitmaps[s]);
+ }
+ }
+
+ qfq_update_eligible(q, q->V);
+}
+
+static void qfq_qlen_notify(struct Qdisc *sch, unsigned long arg)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_class *cl = (struct qfq_class *)arg;
+
+ if (cl->qdisc->q.qlen == 0)
+ qfq_deactivate_class(q, cl);
+}
+
+static unsigned int qfq_drop(struct Qdisc *sch)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_group *grp;
+ unsigned int i, j, len;
+
+ for (i = 0; i <= QFQ_MAX_INDEX; i++) {
+ grp = &q->groups[i];
+ for (j = 0; j < QFQ_MAX_SLOTS; j++) {
+ struct qfq_class *cl;
+ struct hlist_node *n;
+
+ hlist_for_each_entry(cl, n, &grp->slots[j], next) {
+
+ if (!cl->qdisc->ops->drop)
+ continue;
+
+ len = cl->qdisc->ops->drop(cl->qdisc);
+ if (len > 0) {
+ sch->q.qlen--;
+ if (!cl->qdisc->q.qlen)
+ qfq_deactivate_class(q, cl);
+
+ return len;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int qfq_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_group *grp;
+ int i, j, err;
+
+ err = qdisc_class_hash_init(&q->clhash);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i <= QFQ_MAX_INDEX; i++) {
+ grp = &q->groups[i];
+ grp->index = i;
+ grp->slot_shift = QFQ_MTU_SHIFT + FRAC_BITS
+ - (QFQ_MAX_INDEX - i);
+ for (j = 0; j < QFQ_MAX_SLOTS; j++)
+ INIT_HLIST_HEAD(&grp->slots[j]);
+ }
+
+ return 0;
+}
+
+static void qfq_reset_qdisc(struct Qdisc *sch)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_group *grp;
+ struct qfq_class *cl;
+ struct hlist_node *n, *tmp;
+ unsigned int i, j;
+
+ for (i = 0; i <= QFQ_MAX_INDEX; i++) {
+ grp = &q->groups[i];
+ for (j = 0; j < QFQ_MAX_SLOTS; j++) {
+ hlist_for_each_entry_safe(cl, n, tmp,
+ &grp->slots[j], next) {
+ qfq_deactivate_class(q, cl);
+ }
+ }
+ }
+
+ for (i = 0; i < q->clhash.hashsize; i++) {
+ hlist_for_each_entry(cl, n, &q->clhash.hash[i], common.hnode)
+ qdisc_reset(cl->qdisc);
+ }
+ sch->q.qlen = 0;
+}
+
+static void qfq_destroy_qdisc(struct Qdisc *sch)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_class *cl;
+ struct hlist_node *n, *next;
+ unsigned int i;
+
+ tcf_destroy_chain(&q->filter_list);
+
+ for (i = 0; i < q->clhash.hashsize; i++) {
+ hlist_for_each_entry_safe(cl, n, next, &q->clhash.hash[i],
+ common.hnode) {
+ qfq_destroy_class(sch, cl);
+ }
+ }
+ qdisc_class_hash_destroy(&q->clhash);
+}
+
+static const struct Qdisc_class_ops qfq_class_ops = {
+ .change = qfq_change_class,
+ .delete = qfq_delete_class,
+ .get = qfq_get_class,
+ .put = qfq_put_class,
+ .tcf_chain = qfq_tcf_chain,
+ .bind_tcf = qfq_bind_tcf,
+ .unbind_tcf = qfq_unbind_tcf,
+ .graft = qfq_graft_class,
+ .leaf = qfq_class_leaf,
+ .qlen_notify = qfq_qlen_notify,
+ .dump = qfq_dump_class,
+ .dump_stats = qfq_dump_class_stats,
+ .walk = qfq_walk,
+};
+
+static struct Qdisc_ops qfq_qdisc_ops __read_mostly = {
+ .cl_ops = &qfq_class_ops,
+ .id = "qfq",
+ .priv_size = sizeof(struct qfq_sched),
+ .enqueue = qfq_enqueue,
+ .dequeue = qfq_dequeue,
+ .peek = qdisc_peek_dequeued,
+ .drop = qfq_drop,
+ .init = qfq_init_qdisc,
+ .reset = qfq_reset_qdisc,
+ .destroy = qfq_destroy_qdisc,
+ .owner = THIS_MODULE,
+};
+
+static int __init qfq_init(void)
+{
+ return register_qdisc(&qfq_qdisc_ops);
+}
+
+static void __exit qfq_exit(void)
+{
+ unregister_qdisc(&qfq_qdisc_ops);
+}
+
+module_init(qfq_init);
+module_exit(qfq_exit);
+MODULE_LICENSE("GPL");
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index c2e628dfaac..7ef87f9eb67 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -169,7 +169,7 @@ static unsigned int sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
}
case htons(ETH_P_IPV6):
{
- struct ipv6hdr *iph;
+ const struct ipv6hdr *iph;
int poff;
if (!pskb_network_may_pull(skb, sizeof(*iph)))
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index 3c06c87cd28..6338413376c 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -140,14 +140,12 @@ void sctp_bind_addr_init(struct sctp_bind_addr *bp, __u16 port)
/* Dispose of the address list. */
static void sctp_bind_addr_clean(struct sctp_bind_addr *bp)
{
- struct sctp_sockaddr_entry *addr;
- struct list_head *pos, *temp;
+ struct sctp_sockaddr_entry *addr, *temp;
/* Empty the bind address list. */
- list_for_each_safe(pos, temp, &bp->address_list) {
- addr = list_entry(pos, struct sctp_sockaddr_entry, list);
- list_del(pos);
- kfree(addr);
+ list_for_each_entry_safe(addr, temp, &bp->address_list, list) {
+ list_del_rcu(&addr->list);
+ call_rcu(&addr->rcu, sctp_local_addr_free);
SCTP_DBG_OBJCNT_DEC(addr);
}
}
diff --git a/net/sctp/debug.c b/net/sctp/debug.c
index bf24fa697de..ec997cfe0a7 100644
--- a/net/sctp/debug.c
+++ b/net/sctp/debug.c
@@ -98,7 +98,6 @@ const char *sctp_cname(const sctp_subtype_t cid)
/* These are printable forms of the states. */
const char *const sctp_state_tbl[SCTP_STATE_NUM_STATES] = {
- "STATE_EMPTY",
"STATE_CLOSED",
"STATE_COOKIE_WAIT",
"STATE_COOKIE_ECHOED",
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index e10acc01c75..c8cc24e282c 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -325,6 +325,7 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc(
struct sctp_transport **transport)
{
struct sctp_association *asoc = NULL;
+ struct sctp_association *tmp;
struct sctp_transport *t = NULL;
struct sctp_hashbucket *head;
struct sctp_ep_common *epb;
@@ -333,25 +334,32 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc(
int rport;
*transport = NULL;
+
+ /* If the local port is not set, there can't be any associations
+ * on this endpoint.
+ */
+ if (!ep->base.bind_addr.port)
+ goto out;
+
rport = ntohs(paddr->v4.sin_port);
hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport);
head = &sctp_assoc_hashtable[hash];
read_lock(&head->lock);
sctp_for_each_hentry(epb, node, &head->chain) {
- asoc = sctp_assoc(epb);
- if (asoc->ep != ep || rport != asoc->peer.port)
- goto next;
+ tmp = sctp_assoc(epb);
+ if (tmp->ep != ep || rport != tmp->peer.port)
+ continue;
- t = sctp_assoc_lookup_paddr(asoc, paddr);
+ t = sctp_assoc_lookup_paddr(tmp, paddr);
if (t) {
+ asoc = tmp;
*transport = t;
break;
}
-next:
- asoc = NULL;
}
read_unlock(&head->lock);
+out:
return asoc;
}
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 5436c692116..741ed164883 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -565,7 +565,7 @@ void sctp_err_finish(struct sock *sk, struct sctp_association *asoc)
*/
void sctp_v4_err(struct sk_buff *skb, __u32 info)
{
- struct iphdr *iph = (struct iphdr *)skb->data;
+ const struct iphdr *iph = (const struct iphdr *)skb->data;
const int ihlen = iph->ihl * 4;
const int type = icmp_hdr(skb)->type;
const int code = icmp_hdr(skb)->code;
@@ -661,7 +661,6 @@ static int sctp_rcv_ootb(struct sk_buff *skb)
{
sctp_chunkhdr_t *ch;
__u8 *ch_end;
- sctp_errhdr_t *err;
ch = (sctp_chunkhdr_t *) skb->data;
@@ -697,20 +696,6 @@ static int sctp_rcv_ootb(struct sk_buff *skb)
if (SCTP_CID_INIT == ch->type && (void *)ch != skb->data)
goto discard;
- /* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR
- * or a COOKIE ACK the SCTP Packet should be silently
- * discarded.
- */
- if (SCTP_CID_COOKIE_ACK == ch->type)
- goto discard;
-
- if (SCTP_CID_ERROR == ch->type) {
- sctp_walk_errors(err, ch) {
- if (SCTP_ERROR_STALE_COOKIE == err->cause)
- goto discard;
- }
- }
-
ch = (sctp_chunkhdr_t *) ch_end;
} while (ch_end < skb_tail_pointer(skb));
@@ -1017,7 +1002,7 @@ static struct sctp_association *__sctp_rcv_asconf_lookup(
/* 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));
+ af = sctp_get_af_specific(param_type2af(param->p.type));
if (unlikely(!af))
return NULL;
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 185fe058db1..0bb0d7cb9f1 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -80,6 +80,13 @@
#include <asm/uaccess.h>
+static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
+ union sctp_addr *s2);
+static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr,
+ __be16 port);
+static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
+ const union sctp_addr *addr2);
+
/* Event handler for inet6 address addition/deletion events.
* The sctp_local_addr_list needs to be protocted by a spin lock since
* multiple notifiers (say IPv4 and IPv6) may be running at the same
@@ -240,37 +247,107 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
/* Returns the dst cache entry for the given source and destination ip
* addresses.
*/
-static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
- union sctp_addr *daddr,
- union sctp_addr *saddr)
+static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
+ struct flowi *fl, struct sock *sk)
{
- struct dst_entry *dst;
- struct flowi6 fl6;
+ struct sctp_association *asoc = t->asoc;
+ struct dst_entry *dst = NULL;
+ struct flowi6 *fl6 = &fl->u.ip6;
+ struct sctp_bind_addr *bp;
+ struct sctp_sockaddr_entry *laddr;
+ union sctp_addr *baddr = NULL;
+ union sctp_addr *daddr = &t->ipaddr;
+ union sctp_addr dst_saddr;
+ __u8 matchlen = 0;
+ __u8 bmatchlen;
+ sctp_scope_t scope;
- memset(&fl6, 0, sizeof(fl6));
- ipv6_addr_copy(&fl6.daddr, &daddr->v6.sin6_addr);
+ memset(fl6, 0, sizeof(struct flowi6));
+ ipv6_addr_copy(&fl6->daddr, &daddr->v6.sin6_addr);
+ fl6->fl6_dport = daddr->v6.sin6_port;
+ fl6->flowi6_proto = IPPROTO_SCTP;
if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
- fl6.flowi6_oif = daddr->v6.sin6_scope_id;
+ fl6->flowi6_oif = daddr->v6.sin6_scope_id;
+ SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl6->daddr);
- SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl6.daddr);
+ if (asoc)
+ fl6->fl6_sport = htons(asoc->base.bind_addr.port);
if (saddr) {
- ipv6_addr_copy(&fl6.saddr, &saddr->v6.sin6_addr);
- SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6.saddr);
+ ipv6_addr_copy(&fl6->saddr, &saddr->v6.sin6_addr);
+ fl6->fl6_sport = saddr->v6.sin6_port;
+ SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr);
+ }
+
+ dst = ip6_dst_lookup_flow(sk, fl6, NULL, false);
+ if (!asoc || saddr)
+ goto out;
+
+ bp = &asoc->base.bind_addr;
+ scope = sctp_scope(daddr);
+ /* ip6_dst_lookup has filled in the fl6->saddr for us. Check
+ * to see if we can use it.
+ */
+ if (!IS_ERR(dst)) {
+ /* Walk through the bind address list and look for a bind
+ * address that matches the source address of the returned dst.
+ */
+ sctp_v6_to_addr(&dst_saddr, &fl6->saddr, htons(bp->port));
+ rcu_read_lock();
+ list_for_each_entry_rcu(laddr, &bp->address_list, list) {
+ if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC))
+ continue;
+
+ /* Do not compare against v4 addrs */
+ if ((laddr->a.sa.sa_family == AF_INET6) &&
+ (sctp_v6_cmp_addr(&dst_saddr, &laddr->a))) {
+ rcu_read_unlock();
+ goto out;
+ }
+ }
+ rcu_read_unlock();
+ /* None of the bound addresses match the source address of the
+ * dst. So release it.
+ */
+ dst_release(dst);
+ dst = NULL;
}
- dst = ip6_route_output(&init_net, NULL, &fl6);
- if (!dst->error) {
+ /* Walk through the bind address list and try to get the
+ * best source address for a given destination.
+ */
+ rcu_read_lock();
+ list_for_each_entry_rcu(laddr, &bp->address_list, list) {
+ if (!laddr->valid && laddr->state != SCTP_ADDR_SRC)
+ continue;
+ if ((laddr->a.sa.sa_family == AF_INET6) &&
+ (scope <= sctp_scope(&laddr->a))) {
+ bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
+ if (!baddr || (matchlen < bmatchlen)) {
+ baddr = &laddr->a;
+ matchlen = bmatchlen;
+ }
+ }
+ }
+ rcu_read_unlock();
+ if (baddr) {
+ ipv6_addr_copy(&fl6->saddr, &baddr->v6.sin6_addr);
+ fl6->fl6_sport = baddr->v6.sin6_port;
+ dst = ip6_dst_lookup_flow(sk, fl6, NULL, false);
+ }
+
+out:
+ if (!IS_ERR(dst)) {
struct rt6_info *rt;
rt = (struct rt6_info *)dst;
+ t->dst = dst;
SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n",
- &rt->rt6i_dst.addr, &rt->rt6i_src.addr);
- return dst;
+ &rt->rt6i_dst.addr, &fl6->saddr);
+ } else {
+ t->dst = NULL;
+ SCTP_DEBUG_PRINTK("NO ROUTE\n");
}
- SCTP_DEBUG_PRINTK("NO ROUTE\n");
- dst_release(dst);
- return NULL;
}
/* Returns the number of consecutive initial bits that match in the 2 ipv6
@@ -286,64 +363,18 @@ static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
* and asoc's bind address list.
*/
static void sctp_v6_get_saddr(struct sctp_sock *sk,
- struct sctp_association *asoc,
- struct dst_entry *dst,
- union sctp_addr *daddr,
- union sctp_addr *saddr)
+ struct sctp_transport *t,
+ struct flowi *fl)
{
- struct sctp_bind_addr *bp;
- struct sctp_sockaddr_entry *laddr;
- sctp_scope_t scope;
- union sctp_addr *baddr = NULL;
- __u8 matchlen = 0;
- __u8 bmatchlen;
+ struct flowi6 *fl6 = &fl->u.ip6;
+ union sctp_addr *saddr = &t->saddr;
- SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p daddr:%pI6 ",
- __func__, asoc, dst, &daddr->v6.sin6_addr);
-
- if (!asoc) {
- ipv6_dev_get_saddr(sock_net(sctp_opt2sk(sk)),
- dst ? ip6_dst_idev(dst)->dev : NULL,
- &daddr->v6.sin6_addr,
- inet6_sk(&sk->inet.sk)->srcprefs,
- &saddr->v6.sin6_addr);
- SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: %pI6\n",
- &saddr->v6.sin6_addr);
- return;
- }
-
- scope = sctp_scope(daddr);
-
- bp = &asoc->base.bind_addr;
+ SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p\n", __func__, t->asoc, t->dst);
- /* Go through the bind address list and find the best source address
- * that matches the scope of the destination address.
- */
- rcu_read_lock();
- list_for_each_entry_rcu(laddr, &bp->address_list, list) {
- if (!laddr->valid)
- continue;
- 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);
- if (!baddr || (matchlen < bmatchlen)) {
- baddr = &laddr->a;
- matchlen = bmatchlen;
- }
- }
- }
-
- if (baddr) {
- memcpy(saddr, baddr, sizeof(union sctp_addr));
- SCTP_DEBUG_PRINTK("saddr: %pI6\n", &saddr->v6.sin6_addr);
- } else {
- pr_err("%s: asoc:%p Could not find a valid source "
- "address for the dest:%pI6\n",
- __func__, asoc, &daddr->v6.sin6_addr);
+ if (t->dst) {
+ saddr->v6.sin6_family = AF_INET6;
+ ipv6_addr_copy(&saddr->v6.sin6_addr, &fl6->saddr);
}
-
- rcu_read_unlock();
}
/* Make a copy of all potential local addresses. */
@@ -465,14 +496,13 @@ static int sctp_v6_to_addr_param(const union sctp_addr *addr,
return length;
}
-/* Initialize a sctp_addr from a dst_entry. */
-static void sctp_v6_dst_saddr(union sctp_addr *addr, struct dst_entry *dst,
+/* Initialize a sctp_addr from struct in6_addr. */
+static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr,
__be16 port)
{
- struct rt6_info *rt = (struct rt6_info *)dst;
addr->sa.sa_family = AF_INET6;
addr->v6.sin6_port = port;
- ipv6_addr_copy(&addr->v6.sin6_addr, &rt->rt6i_src.addr);
+ ipv6_addr_copy(&addr->v6.sin6_addr, saddr);
}
/* Compare addresses exactly.
@@ -531,7 +561,7 @@ static int sctp_v6_is_any(const union sctp_addr *addr)
static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
{
int type;
- struct in6_addr *in6 = (struct in6_addr *)&addr->v6.sin6_addr;
+ const struct in6_addr *in6 = (const struct in6_addr *)&addr->v6.sin6_addr;
type = ipv6_addr_type(in6);
if (IPV6_ADDR_ANY == type)
@@ -959,7 +989,6 @@ static struct sctp_af sctp_af_inet6 = {
.to_sk_daddr = sctp_v6_to_sk_daddr,
.from_addr_param = sctp_v6_from_addr_param,
.to_addr_param = sctp_v6_to_addr_param,
- .dst_saddr = sctp_v6_dst_saddr,
.cmp_addr = sctp_v6_cmp_addr,
.scope = sctp_v6_scope,
.addr_valid = sctp_v6_addr_valid,
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index bf92a5b68f8..1c88c8911dc 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -131,7 +131,8 @@ static inline int sctp_cacc_skip_3_1_d(struct sctp_transport *primary,
static inline int sctp_cacc_skip_3_1_f(struct sctp_transport *transport,
int count_of_newacks)
{
- if (count_of_newacks < 2 && !transport->cacc.cacc_saw_newack)
+ if (count_of_newacks < 2 &&
+ (transport && !transport->cacc.cacc_saw_newack))
return 1;
return 0;
}
@@ -319,7 +320,6 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk)
* chunk.
*/
switch (q->asoc->state) {
- case SCTP_STATE_EMPTY:
case SCTP_STATE_CLOSED:
case SCTP_STATE_SHUTDOWN_PENDING:
case SCTP_STATE_SHUTDOWN_SENT:
@@ -577,6 +577,13 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
* try to send as much as possible.
*/
list_for_each_entry_safe(chunk, chunk1, lqueue, transmitted_list) {
+ /* If the chunk is abandoned, move it to abandoned list. */
+ if (sctp_chunk_abandoned(chunk)) {
+ list_del_init(&chunk->transmitted_list);
+ sctp_insert_list(&q->abandoned,
+ &chunk->transmitted_list);
+ continue;
+ }
/* Make sure that Gap Acked TSNs are not retransmitted. A
* simple approach is just to move such TSNs out of the
@@ -618,9 +625,12 @@ redo:
/* If we are retransmitting, we should only
* send a single packet.
+ * Otherwise, try appending this chunk again.
*/
if (rtx_timeout || fast_rtx)
done = 1;
+ else
+ goto redo;
/* Bundle next chunk in the next round. */
break;
@@ -1683,8 +1693,9 @@ static void sctp_mark_missing(struct sctp_outq *q,
/* SFR-CACC may require us to skip marking
* this chunk as missing.
*/
- if (!transport || !sctp_cacc_skip(primary, transport,
- count_of_newacks, tsn)) {
+ if (!transport || !sctp_cacc_skip(primary,
+ chunk->transport,
+ count_of_newacks, tsn)) {
chunk->tsn_missing_report++;
SCTP_DEBUG_PRINTK(
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 065d99958ce..67380a29e2e 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -332,13 +332,12 @@ static int sctp_v4_to_addr_param(const union sctp_addr *addr,
}
/* Initialize a sctp_addr from a dst_entry. */
-static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct dst_entry *dst,
+static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct flowi4 *fl4,
__be16 port)
{
- struct rtable *rt = (struct rtable *)dst;
saddr->v4.sin_family = AF_INET;
saddr->v4.sin_port = port;
- saddr->v4.sin_addr.s_addr = rt->rt_src;
+ saddr->v4.sin_addr.s_addr = fl4->saddr;
}
/* Compare two addresses exactly. */
@@ -456,35 +455,36 @@ static sctp_scope_t sctp_v4_scope(union sctp_addr *addr)
* addresses. If an association is passed, trys to get a dst entry with a
* source address that matches an address in the bind address list.
*/
-static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
- union sctp_addr *daddr,
- union sctp_addr *saddr)
+static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
+ struct flowi *fl, struct sock *sk)
{
+ struct sctp_association *asoc = t->asoc;
struct rtable *rt;
- struct flowi4 fl4;
+ struct flowi4 *fl4 = &fl->u.ip4;
struct sctp_bind_addr *bp;
struct sctp_sockaddr_entry *laddr;
struct dst_entry *dst = NULL;
+ union sctp_addr *daddr = &t->ipaddr;
union sctp_addr dst_saddr;
- memset(&fl4, 0x0, sizeof(struct flowi4));
- fl4.daddr = daddr->v4.sin_addr.s_addr;
- fl4.fl4_dport = daddr->v4.sin_port;
- fl4.flowi4_proto = IPPROTO_SCTP;
+ memset(fl4, 0x0, sizeof(struct flowi4));
+ fl4->daddr = daddr->v4.sin_addr.s_addr;
+ fl4->fl4_dport = daddr->v4.sin_port;
+ fl4->flowi4_proto = IPPROTO_SCTP;
if (asoc) {
- fl4.flowi4_tos = RT_CONN_FLAGS(asoc->base.sk);
- fl4.flowi4_oif = asoc->base.sk->sk_bound_dev_if;
- fl4.fl4_sport = htons(asoc->base.bind_addr.port);
+ fl4->flowi4_tos = RT_CONN_FLAGS(asoc->base.sk);
+ fl4->flowi4_oif = asoc->base.sk->sk_bound_dev_if;
+ fl4->fl4_sport = htons(asoc->base.bind_addr.port);
}
if (saddr) {
- fl4.saddr = saddr->v4.sin_addr.s_addr;
- fl4.fl4_sport = saddr->v4.sin_port;
+ fl4->saddr = saddr->v4.sin_addr.s_addr;
+ fl4->fl4_sport = saddr->v4.sin_port;
}
SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ",
- __func__, &fl4.daddr, &fl4.saddr);
+ __func__, &fl4->daddr, &fl4->saddr);
- rt = ip_route_output_key(&init_net, &fl4);
+ rt = ip_route_output_key(&init_net, fl4);
if (!IS_ERR(rt))
dst = &rt->dst;
@@ -500,7 +500,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
/* Walk through the bind address list and look for a bind
* address that matches the source address of the returned dst.
*/
- sctp_v4_dst_saddr(&dst_saddr, dst, htons(bp->port));
+ sctp_v4_dst_saddr(&dst_saddr, fl4, htons(bp->port));
rcu_read_lock();
list_for_each_entry_rcu(laddr, &bp->address_list, list) {
if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC))
@@ -526,9 +526,9 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
continue;
if ((laddr->state == SCTP_ADDR_SRC) &&
(AF_INET == laddr->a.sa.sa_family)) {
- fl4.saddr = laddr->a.v4.sin_addr.s_addr;
- fl4.fl4_sport = laddr->a.v4.sin_port;
- rt = ip_route_output_key(&init_net, &fl4);
+ fl4->saddr = laddr->a.v4.sin_addr.s_addr;
+ fl4->fl4_sport = laddr->a.v4.sin_port;
+ rt = ip_route_output_key(&init_net, fl4);
if (!IS_ERR(rt)) {
dst = &rt->dst;
goto out_unlock;
@@ -539,33 +539,27 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
out_unlock:
rcu_read_unlock();
out:
+ t->dst = dst;
if (dst)
SCTP_DEBUG_PRINTK("rt_dst:%pI4, rt_src:%pI4\n",
- &rt->rt_dst, &rt->rt_src);
+ &fl4->daddr, &fl4->saddr);
else
SCTP_DEBUG_PRINTK("NO ROUTE\n");
-
- return dst;
}
/* For v4, the source address is cached in the route entry(dst). So no need
* to cache it separately and hence this is an empty routine.
*/
static void sctp_v4_get_saddr(struct sctp_sock *sk,
- struct sctp_association *asoc,
- struct dst_entry *dst,
- union sctp_addr *daddr,
- union sctp_addr *saddr)
+ struct sctp_transport *t,
+ struct flowi *fl)
{
- struct rtable *rt = (struct rtable *)dst;
-
- if (!asoc)
- return;
+ union sctp_addr *saddr = &t->saddr;
+ struct rtable *rt = (struct rtable *)t->dst;
if (rt) {
saddr->v4.sin_family = AF_INET;
- saddr->v4.sin_port = htons(asoc->base.bind_addr.port);
- saddr->v4.sin_addr.s_addr = rt->rt_src;
+ saddr->v4.sin_addr.s_addr = fl->u.ip4.saddr;
}
}
@@ -847,14 +841,14 @@ static inline int sctp_v4_xmit(struct sk_buff *skb,
SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n",
__func__, skb, skb->len,
- &skb_rtable(skb)->rt_src,
- &skb_rtable(skb)->rt_dst);
+ &transport->fl.u.ip4.saddr,
+ &transport->fl.u.ip4.daddr);
inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ?
IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
- return ip_queue_xmit(skb);
+ return ip_queue_xmit(skb, &transport->fl);
}
static struct sctp_af sctp_af_inet;
@@ -943,7 +937,6 @@ static struct sctp_af sctp_af_inet = {
.to_sk_daddr = sctp_v4_to_sk_daddr,
.from_addr_param = sctp_v4_from_addr_param,
.to_addr_param = sctp_v4_to_addr_param,
- .dst_saddr = sctp_v4_dst_saddr,
.cmp_addr = sctp_v4_cmp_addr,
.addr_valid = sctp_v4_addr_valid,
.inaddr_any = sctp_v4_inaddr_any,
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index b3434cc7d0c..58eb27fed4b 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1075,20 +1075,28 @@ nodata:
/* Make a HEARTBEAT chunk. */
struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
- const struct sctp_transport *transport,
- const void *payload, const size_t paylen)
+ const struct sctp_transport *transport)
{
- struct sctp_chunk *retval = sctp_make_chunk(asoc, SCTP_CID_HEARTBEAT,
- 0, paylen);
+ struct sctp_chunk *retval;
+ sctp_sender_hb_info_t hbinfo;
+
+ retval = sctp_make_chunk(asoc, SCTP_CID_HEARTBEAT, 0, sizeof(hbinfo));
if (!retval)
goto nodata;
+ hbinfo.param_hdr.type = SCTP_PARAM_HEARTBEAT_INFO;
+ hbinfo.param_hdr.length = htons(sizeof(sctp_sender_hb_info_t));
+ hbinfo.daddr = transport->ipaddr;
+ hbinfo.sent_at = jiffies;
+ hbinfo.hb_nonce = transport->hb_nonce;
+
/* Cast away the 'const', as this is just telling the chunk
* what transport it belongs to.
*/
retval->transport = (struct sctp_transport *) transport;
- retval->subh.hbs_hdr = sctp_addto_chunk(retval, paylen, payload);
+ retval->subh.hbs_hdr = sctp_addto_chunk(retval, sizeof(hbinfo),
+ &hbinfo);
nodata:
return retval;
@@ -2242,14 +2250,17 @@ int sctp_verify_init(const struct sctp_association *asoc,
* Returns 0 on failure, else success.
* FIXME: This is an association method.
*/
-int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
+int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
const union sctp_addr *peer_addr,
sctp_init_chunk_t *peer_init, gfp_t gfp)
{
union sctp_params param;
struct sctp_transport *transport;
struct list_head *pos, *temp;
+ struct sctp_af *af;
+ union sctp_addr addr;
char *cookie;
+ int src_match = 0;
/* We must include the address that the INIT packet came from.
* This is the only address that matters for an INIT packet.
@@ -2261,18 +2272,31 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
* added as the primary transport. The source address seems to
* be a a better choice than any of the embedded addresses.
*/
- if (peer_addr) {
- if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE))
- goto nomem;
- }
+ if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE))
+ goto nomem;
+
+ if (sctp_cmp_addr_exact(sctp_source(chunk), peer_addr))
+ src_match = 1;
/* Process the initialization parameters. */
sctp_walk_params(param, peer_init, init_hdr.params) {
+ if (!src_match && (param.p->type == SCTP_PARAM_IPV4_ADDRESS ||
+ param.p->type == SCTP_PARAM_IPV6_ADDRESS)) {
+ af = sctp_get_af_specific(param_type2af(param.p->type));
+ af->from_addr_param(&addr, param.addr,
+ chunk->sctp_hdr->source, 0);
+ if (sctp_cmp_addr_exact(sctp_source(chunk), &addr))
+ src_match = 1;
+ }
if (!sctp_process_param(asoc, param, peer_addr, gfp))
goto clean_up;
}
+ /* source address of chunk may not match any valid address */
+ if (!src_match)
+ goto clean_up;
+
/* AUTH: After processing the parameters, make sure that we
* have all the required info to potentially do authentications.
*/
@@ -2923,7 +2947,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
asconf_param->param_hdr.type != SCTP_PARAM_SET_PRIMARY)
return SCTP_ERROR_UNKNOWN_PARAM;
- switch (addr_param->v4.param_hdr.type) {
+ switch (addr_param->p.type) {
case SCTP_PARAM_IPV6_ADDRESS:
if (!asoc->peer.ipv6_address)
return SCTP_ERROR_DNS_FAILED;
@@ -2936,7 +2960,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
return SCTP_ERROR_DNS_FAILED;
}
- af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type));
+ af = sctp_get_af_specific(param_type2af(addr_param->p.type));
if (unlikely(!af))
return SCTP_ERROR_DNS_FAILED;
@@ -3100,7 +3124,7 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
/* Skip the address parameter and store a pointer to the first
* asconf parameter.
*/
- length = ntohs(addr_param->v4.param_hdr.length);
+ length = ntohs(addr_param->p.length);
asconf_param = (sctp_addip_param_t *)((void *)addr_param + length);
chunk_len -= length;
@@ -3177,7 +3201,7 @@ static void sctp_asconf_param_success(struct sctp_association *asoc,
((void *)asconf_param + sizeof(sctp_addip_param_t));
/* We have checked the packet before, so we do not check again. */
- af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type));
+ af = sctp_get_af_specific(param_type2af(addr_param->p.type));
af->from_addr_param(&addr, addr_param, htons(bp->port), 0);
switch (asconf_param->param_hdr.type) {
@@ -3193,11 +3217,8 @@ static void sctp_asconf_param_success(struct sctp_association *asoc,
local_bh_enable();
list_for_each_entry(transport, &asoc->peer.transport_addr_list,
transports) {
- if (transport->state == SCTP_ACTIVE)
- continue;
dst_release(transport->dst);
- sctp_transport_route(transport, NULL,
- sctp_sk(asoc->base.sk));
+ transport->dst = NULL;
}
break;
case SCTP_PARAM_DEL_IP:
@@ -3207,8 +3228,7 @@ static void sctp_asconf_param_success(struct sctp_association *asoc,
list_for_each_entry(transport, &asoc->peer.transport_addr_list,
transports) {
dst_release(transport->dst);
- sctp_transport_route(transport, NULL,
- sctp_sk(asoc->base.sk));
+ transport->dst = NULL;
}
break;
default:
@@ -3304,7 +3324,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
/* Skip the address parameter in the last asconf sent and store a
* pointer to the first asconf parameter.
*/
- length = ntohs(addr_param->v4.param_hdr.length);
+ length = ntohs(addr_param->p.length);
asconf_param = (sctp_addip_param_t *)((void *)addr_param + length);
asconf_len -= length;
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 5f86ee4b54c..d612ca1ca6c 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -595,8 +595,7 @@ static int sctp_cmd_process_init(sctp_cmd_seq_t *commands,
* fail during INIT processing (due to malloc problems),
* just return the error and stop processing the stack.
*/
- if (!sctp_process_init(asoc, chunk->chunk_hdr->type,
- sctp_source(chunk), peer_init, gfp))
+ if (!sctp_process_init(asoc, chunk, sctp_source(chunk), peer_init, gfp))
error = -ENOMEM;
else
error = 0;
@@ -1415,12 +1414,6 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
SCTP_RTXR_T3_RTX);
break;
- case SCTP_CMD_TRANSMIT:
- /* Kick start transmission. */
- error = sctp_outq_uncork(&asoc->outqueue);
- local_cork = 0;
- break;
-
case SCTP_CMD_ECN_CE:
/* Do delayed CE processing. */
sctp_do_ecn_ce_work(asoc, cmd->obj.u32);
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 76792083c37..7f4a4f8368e 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -393,8 +393,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
goto nomem_init;
/* The call, sctp_process_init(), can fail on memory allocation. */
- if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
- sctp_source(chunk),
+ if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk),
(sctp_init_chunk_t *)chunk->chunk_hdr,
GFP_ATOMIC))
goto nomem_init;
@@ -725,7 +724,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
*/
peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
- if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
+ if (!sctp_process_init(new_asoc, chunk,
&chunk->subh.cookie_hdr->c.peer_addr,
peer_init, GFP_ATOMIC))
goto nomem_init;
@@ -942,18 +941,9 @@ static sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,
{
struct sctp_transport *transport = (struct sctp_transport *) arg;
struct sctp_chunk *reply;
- sctp_sender_hb_info_t hbinfo;
- size_t paylen = 0;
-
- hbinfo.param_hdr.type = SCTP_PARAM_HEARTBEAT_INFO;
- hbinfo.param_hdr.length = htons(sizeof(sctp_sender_hb_info_t));
- hbinfo.daddr = transport->ipaddr;
- hbinfo.sent_at = jiffies;
- hbinfo.hb_nonce = transport->hb_nonce;
/* Send a heartbeat to our peer. */
- paylen = sizeof(sctp_sender_hb_info_t);
- reply = sctp_make_heartbeat(asoc, transport, &hbinfo, paylen);
+ reply = sctp_make_heartbeat(asoc, transport);
if (!reply)
return SCTP_DISPOSITION_NOMEM;
@@ -1464,8 +1454,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
* Verification Tag and Peers Verification tag into a reserved
* place (local tie-tag and per tie-tag) within the state cookie.
*/
- if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
- sctp_source(chunk),
+ if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk),
(sctp_init_chunk_t *)chunk->chunk_hdr,
GFP_ATOMIC))
goto nomem;
@@ -1694,8 +1683,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
*/
peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
- if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
- sctp_source(chunk), peer_init,
+ if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init,
GFP_ATOMIC))
goto nomem;
@@ -1780,8 +1768,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
* side effects--it is safe to run them here.
*/
peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
- if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
- sctp_source(chunk), peer_init,
+ if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init,
GFP_ATOMIC))
goto nomem;
@@ -2412,8 +2399,15 @@ static sctp_disposition_t __sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
/* 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))
+ if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) {
+
+ sctp_errhdr_t *err;
+ sctp_walk_errors(err, chunk->chunk_hdr);
+ if ((void *)err != (void *)chunk->chunk_end)
+ return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
+ }
sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET));
/* ASSOC_FAILED will DELETE_TCB. */
@@ -3204,6 +3198,7 @@ sctp_disposition_t sctp_sf_operr_notify(const struct sctp_endpoint *ep,
sctp_cmd_seq_t *commands)
{
struct sctp_chunk *chunk = arg;
+ sctp_errhdr_t *err;
if (!sctp_vtag_verify(chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -3212,6 +3207,10 @@ sctp_disposition_t sctp_sf_operr_notify(const struct sctp_endpoint *ep,
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t)))
return sctp_sf_violation_chunklen(ep, asoc, type, arg,
commands);
+ sctp_walk_errors(err, chunk->chunk_hdr);
+ if ((void *)err != (void *)chunk->chunk_end)
+ return sctp_sf_violation_paramlen(ep, asoc, type, arg,
+ (void *)err, commands);
sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_OPERR,
SCTP_CHUNK(chunk));
@@ -3320,8 +3319,10 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
struct sctp_chunk *chunk = arg;
struct sk_buff *skb = chunk->skb;
sctp_chunkhdr_t *ch;
+ sctp_errhdr_t *err;
__u8 *ch_end;
int ootb_shut_ack = 0;
+ int ootb_cookie_ack = 0;
SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
@@ -3346,6 +3347,23 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
if (SCTP_CID_ABORT == ch->type)
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ /* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR
+ * or a COOKIE ACK the SCTP Packet should be silently
+ * discarded.
+ */
+
+ if (SCTP_CID_COOKIE_ACK == ch->type)
+ ootb_cookie_ack = 1;
+
+ if (SCTP_CID_ERROR == ch->type) {
+ sctp_walk_errors(err, ch) {
+ if (SCTP_ERROR_STALE_COOKIE == err->cause) {
+ ootb_cookie_ack = 1;
+ break;
+ }
+ }
+ }
+
/* Report violation if chunk len overflows */
ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
if (ch_end > skb_tail_pointer(skb))
@@ -3357,6 +3375,8 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
if (ootb_shut_ack)
return sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands);
+ else if (ootb_cookie_ack)
+ return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
else
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
}
@@ -4343,8 +4363,9 @@ static sctp_disposition_t sctp_sf_violation_chunklen(
/*
* Handle a protocol violation when the parameter length is invalid.
- * "Invalid" length is identified as smaller than the minimal length a
- * given parameter can be.
+ * If the length is smaller than the minimum length of a given parameter,
+ * or accumulated length in multi parameters exceeds the end of the chunk,
+ * the length is considered as invalid.
*/
static sctp_disposition_t sctp_sf_violation_paramlen(
const struct sctp_endpoint *ep,
@@ -5056,6 +5077,30 @@ sctp_disposition_t sctp_sf_ignore_primitive(
***************************************************************************/
/*
+ * When the SCTP stack has no more user data to send or retransmit, this
+ * notification is given to the user. Also, at the time when a user app
+ * subscribes to this event, if there is no data to be sent or
+ * retransmit, the stack will immediately send up this notification.
+ */
+sctp_disposition_t sctp_sf_do_no_pending_tsn(
+ const struct sctp_endpoint *ep,
+ const struct sctp_association *asoc,
+ const sctp_subtype_t type,
+ void *arg,
+ sctp_cmd_seq_t *commands)
+{
+ struct sctp_ulpevent *event;
+
+ event = sctp_ulpevent_make_sender_dry_event(asoc, GFP_ATOMIC);
+ if (!event)
+ return SCTP_DISPOSITION_NOMEM;
+
+ sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(event));
+
+ return SCTP_DISPOSITION_CONSUME;
+}
+
+/*
* Start the shutdown negotiation.
*
* From Section 9.2:
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index 546d4387fb3..0338dc6fdc9 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -107,8 +107,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
#define TYPE_SCTP_FUNC(func) {.fn = func, .name = #func}
#define TYPE_SCTP_DATA { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -128,8 +126,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
} /* TYPE_SCTP_DATA */
#define TYPE_SCTP_INIT { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_do_5_1B_init), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -149,8 +145,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
} /* TYPE_SCTP_INIT */
#define TYPE_SCTP_INIT_ACK { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_do_5_2_3_initack), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -170,8 +164,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
} /* TYPE_SCTP_INIT_ACK */
#define TYPE_SCTP_SACK { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -191,8 +183,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
} /* TYPE_SCTP_SACK */
#define TYPE_SCTP_HEARTBEAT { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -213,8 +203,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
} /* TYPE_SCTP_HEARTBEAT */
#define TYPE_SCTP_HEARTBEAT_ACK { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -234,8 +222,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
} /* TYPE_SCTP_HEARTBEAT_ACK */
#define TYPE_SCTP_ABORT { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_pdiscard), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -255,8 +241,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
} /* TYPE_SCTP_ABORT */
#define TYPE_SCTP_SHUTDOWN { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -276,8 +260,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
} /* TYPE_SCTP_SHUTDOWN */
#define TYPE_SCTP_SHUTDOWN_ACK { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -297,8 +279,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
} /* TYPE_SCTP_SHUTDOWN_ACK */
#define TYPE_SCTP_ERROR { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -318,8 +298,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
} /* TYPE_SCTP_ERROR */
#define TYPE_SCTP_COOKIE_ECHO { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_do_5_1D_ce), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -339,8 +317,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
} /* TYPE_SCTP_COOKIE_ECHO */
#define TYPE_SCTP_COOKIE_ACK { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -360,8 +336,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
} /* TYPE_SCTP_COOKIE_ACK */
#define TYPE_SCTP_ECN_ECNE { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -381,8 +355,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
} /* TYPE_SCTP_ECN_ECNE */
#define TYPE_SCTP_ECN_CWR { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -402,8 +374,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
} /* TYPE_SCTP_ECN_CWR */
#define TYPE_SCTP_SHUTDOWN_COMPLETE { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -446,8 +416,6 @@ static const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][
}; /* state_fn_t chunk_event_table[][] */
#define TYPE_SCTP_ASCONF { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -467,8 +435,6 @@ static const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][
} /* TYPE_SCTP_ASCONF */
#define TYPE_SCTP_ASCONF_ACK { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -496,8 +462,6 @@ static const sctp_sm_table_entry_t addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_
}; /*state_fn_t addip_chunk_event_table[][] */
#define TYPE_SCTP_FWD_TSN { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -524,8 +488,6 @@ static const sctp_sm_table_entry_t prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUN
}; /*state_fn_t prsctp_chunk_event_table[][] */
#define TYPE_SCTP_AUTH { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_ootb), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -553,8 +515,6 @@ static const sctp_sm_table_entry_t auth_chunk_event_table[SCTP_NUM_AUTH_CHUNK_TY
static const sctp_sm_table_entry_t
chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
- /* SCTP_STATE_EMPTY */
- TYPE_SCTP_FUNC(sctp_sf_ootb),
/* SCTP_STATE_CLOSED */
TYPE_SCTP_FUNC(sctp_sf_ootb),
/* SCTP_STATE_COOKIE_WAIT */
@@ -575,8 +535,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
#define TYPE_SCTP_PRIMITIVE_ASSOCIATE { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_do_prm_asoc), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -596,8 +554,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
} /* TYPE_SCTP_PRIMITIVE_ASSOCIATE */
#define TYPE_SCTP_PRIMITIVE_SHUTDOWN { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_error_closed), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -617,8 +573,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
} /* TYPE_SCTP_PRIMITIVE_SHUTDOWN */
#define TYPE_SCTP_PRIMITIVE_ABORT { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_error_closed), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -638,8 +592,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
} /* TYPE_SCTP_PRIMITIVE_ABORT */
#define TYPE_SCTP_PRIMITIVE_SEND { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_error_closed), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -659,8 +611,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
} /* TYPE_SCTP_PRIMITIVE_SEND */
#define TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_error_closed), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -680,8 +630,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
} /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */
#define TYPE_SCTP_PRIMITIVE_ASCONF { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_error_closed), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -713,8 +661,6 @@ static const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPE
};
#define TYPE_SCTP_OTHER_NO_PENDING_TSN { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -722,7 +668,7 @@ static const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPE
/* SCTP_STATE_COOKIE_ECHOED */ \
TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
/* SCTP_STATE_ESTABLISHED */ \
- TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
+ TYPE_SCTP_FUNC(sctp_sf_do_no_pending_tsn), \
/* SCTP_STATE_SHUTDOWN_PENDING */ \
TYPE_SCTP_FUNC(sctp_sf_do_9_2_start_shutdown), \
/* SCTP_STATE_SHUTDOWN_SENT */ \
@@ -734,8 +680,6 @@ static const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPE
}
#define TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -760,8 +704,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
};
#define TYPE_SCTP_EVENT_TIMEOUT_NONE { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -781,8 +723,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
}
#define TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -802,8 +742,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
}
#define TYPE_SCTP_EVENT_TIMEOUT_T1_INIT { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -823,8 +761,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
}
#define TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -844,8 +780,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
}
#define TYPE_SCTP_EVENT_TIMEOUT_T3_RTX { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -865,8 +799,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
}
#define TYPE_SCTP_EVENT_TIMEOUT_T4_RTO { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -886,8 +818,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
}
#define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -907,8 +837,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
}
#define TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -928,8 +856,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
}
#define TYPE_SCTP_EVENT_TIMEOUT_SACK { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_bug), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
/* SCTP_STATE_COOKIE_WAIT */ \
@@ -949,8 +875,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
}
#define TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE { \
- /* SCTP_STATE_EMPTY */ \
- TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
/* SCTP_STATE_COOKIE_WAIT */ \
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index deb82e35a10..6766913a53e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -658,11 +658,15 @@ static int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt)
goto err_bindx_rem;
}
- if (sa_addr->v4.sin_port != htons(bp->port)) {
+ if (sa_addr->v4.sin_port &&
+ sa_addr->v4.sin_port != htons(bp->port)) {
retval = -EINVAL;
goto err_bindx_rem;
}
+ if (!sa_addr->v4.sin_port)
+ sa_addr->v4.sin_port = htons(bp->port);
+
/* FIXME - There is probably a need to check if sk->sk_saddr and
* sk->sk_rcv_addr are currently set to one of the addresses to
* be removed. This is something which needs to be looked into
@@ -1492,7 +1496,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
struct sctp_chunk *chunk;
union sctp_addr to;
struct sockaddr *msg_name = NULL;
- struct sctp_sndrcvinfo default_sinfo = { 0 };
+ struct sctp_sndrcvinfo default_sinfo;
struct sctp_sndrcvinfo *sinfo;
struct sctp_initmsg *sinit;
sctp_assoc_t associd = 0;
@@ -1756,6 +1760,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
/* If the user didn't specify SNDRCVINFO, make up one with
* some defaults.
*/
+ memset(&default_sinfo, 0, sizeof(default_sinfo));
default_sinfo.sinfo_stream = asoc->default_stream;
default_sinfo.sinfo_flags = asoc->default_flags;
default_sinfo.sinfo_ppid = asoc->default_ppid;
@@ -1786,12 +1791,10 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
goto out_free;
}
- if (sinfo) {
- /* Check for invalid stream. */
- if (sinfo->sinfo_stream >= asoc->c.sinit_num_ostreams) {
- err = -EINVAL;
- goto out_free;
- }
+ /* Check for invalid stream. */
+ if (sinfo->sinfo_stream >= asoc->c.sinit_num_ostreams) {
+ err = -EINVAL;
+ goto out_free;
}
timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
@@ -2283,7 +2286,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
trans->param_flags =
(trans->param_flags & ~SPP_PMTUD) | pmtud_change;
if (update) {
- sctp_transport_pmtu(trans);
+ sctp_transport_pmtu(trans, sctp_opt2sk(sp));
sctp_assoc_sync_pmtu(asoc);
}
} else if (asoc) {
@@ -3215,14 +3218,9 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,
if (optlen < sizeof(struct sctp_hmacalgo))
return -EINVAL;
- hmacs = kmalloc(optlen, GFP_KERNEL);
- if (!hmacs)
- return -ENOMEM;
-
- if (copy_from_user(hmacs, optval, optlen)) {
- err = -EFAULT;
- goto out;
- }
+ hmacs= memdup_user(optval, optlen);
+ if (IS_ERR(hmacs))
+ return PTR_ERR(hmacs);
idents = hmacs->shmac_num_idents;
if (idents == 0 || idents > SCTP_AUTH_NUM_HMACS ||
@@ -3257,14 +3255,9 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
if (optlen <= sizeof(struct sctp_authkey))
return -EINVAL;
- authkey = kmalloc(optlen, GFP_KERNEL);
- if (!authkey)
- return -ENOMEM;
-
- if (copy_from_user(authkey, optval, optlen)) {
- ret = -EFAULT;
- goto out;
- }
+ authkey= memdup_user(optval, optlen);
+ if (IS_ERR(authkey))
+ return PTR_ERR(authkey);
if (authkey->sca_keylength > optlen - sizeof(struct sctp_authkey)) {
ret = -EINVAL;
@@ -5283,6 +5276,55 @@ static int sctp_getsockopt_assoc_number(struct sock *sk, int len,
return 0;
}
+/*
+ * 8.2.6. Get the Current Identifiers of Associations
+ * (SCTP_GET_ASSOC_ID_LIST)
+ *
+ * This option gets the current list of SCTP association identifiers of
+ * the SCTP associations handled by a one-to-many style socket.
+ */
+static int sctp_getsockopt_assoc_ids(struct sock *sk, int len,
+ char __user *optval, int __user *optlen)
+{
+ struct sctp_sock *sp = sctp_sk(sk);
+ struct sctp_association *asoc;
+ struct sctp_assoc_ids *ids;
+ u32 num = 0;
+
+ if (sctp_style(sk, TCP))
+ return -EOPNOTSUPP;
+
+ if (len < sizeof(struct sctp_assoc_ids))
+ return -EINVAL;
+
+ list_for_each_entry(asoc, &(sp->ep->asocs), asocs) {
+ num++;
+ }
+
+ if (len < sizeof(struct sctp_assoc_ids) + sizeof(sctp_assoc_t) * num)
+ return -EINVAL;
+
+ len = sizeof(struct sctp_assoc_ids) + sizeof(sctp_assoc_t) * num;
+
+ ids = kmalloc(len, GFP_KERNEL);
+ if (unlikely(!ids))
+ return -ENOMEM;
+
+ ids->gaids_number_of_ids = num;
+ num = 0;
+ list_for_each_entry(asoc, &(sp->ep->asocs), asocs) {
+ ids->gaids_assoc_id[num++] = asoc->assoc_id;
+ }
+
+ if (put_user(len, optlen) || copy_to_user(optval, ids, len)) {
+ kfree(ids);
+ return -EFAULT;
+ }
+
+ kfree(ids);
+ return 0;
+}
+
SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen)
{
@@ -5415,6 +5457,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
case SCTP_GET_ASSOC_NUMBER:
retval = sctp_getsockopt_assoc_number(sk, len, optval, optlen);
break;
+ case SCTP_GET_ASSOC_ID_LIST:
+ retval = sctp_getsockopt_assoc_ids(sk, len, optval, optlen);
+ break;
default:
retval = -ENOPROTOOPT;
break;
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index d3ae493d234..394c57ca2f5 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -211,15 +211,17 @@ void sctp_transport_set_owner(struct sctp_transport *transport,
}
/* Initialize the pmtu of a transport. */
-void sctp_transport_pmtu(struct sctp_transport *transport)
+void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk)
{
- struct dst_entry *dst;
-
- dst = transport->af_specific->get_dst(NULL, &transport->ipaddr, NULL);
+ /* If we don't have a fresh route, look one up */
+ if (!transport->dst || transport->dst->obsolete > 1) {
+ dst_release(transport->dst);
+ transport->af_specific->get_dst(transport, &transport->saddr,
+ &transport->fl, sk);
+ }
- if (dst) {
- transport->pathmtu = dst_mtu(dst);
- dst_release(dst);
+ if (transport->dst) {
+ transport->pathmtu = dst_mtu(transport->dst);
} else
transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
}
@@ -270,22 +272,19 @@ void sctp_transport_route(struct sctp_transport *transport,
{
struct sctp_association *asoc = transport->asoc;
struct sctp_af *af = transport->af_specific;
- union sctp_addr *daddr = &transport->ipaddr;
- struct dst_entry *dst;
- dst = af->get_dst(asoc, daddr, saddr);
+ af->get_dst(transport, saddr, &transport->fl, sctp_opt2sk(opt));
if (saddr)
memcpy(&transport->saddr, saddr, sizeof(union sctp_addr));
else
- af->get_saddr(opt, asoc, dst, daddr, &transport->saddr);
+ af->get_saddr(opt, transport, &transport->fl);
- transport->dst = dst;
if ((transport->param_flags & SPP_PMTUD_DISABLE) && transport->pathmtu) {
return;
}
- if (dst) {
- transport->pathmtu = dst_mtu(dst);
+ if (transport->dst) {
+ transport->pathmtu = dst_mtu(transport->dst);
/* Initialize sk->sk_rcv_saddr, if the transport is the
* association's active path for getsockname().
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index 61b1f5ada96..e70e5fc8789 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -843,7 +843,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_authkey(
ak = (struct sctp_authkey_event *)
skb_put(skb, sizeof(struct sctp_authkey_event));
- ak->auth_type = SCTP_AUTHENTICATION_INDICATION;
+ ak->auth_type = SCTP_AUTHENTICATION_EVENT;
ak->auth_flags = 0;
ak->auth_length = sizeof(struct sctp_authkey_event);
@@ -862,6 +862,34 @@ fail:
return NULL;
}
+/*
+ * Socket Extensions for SCTP
+ * 6.3.10. SCTP_SENDER_DRY_EVENT
+ */
+struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event(
+ const struct sctp_association *asoc, gfp_t gfp)
+{
+ struct sctp_ulpevent *event;
+ struct sctp_sender_dry_event *sdry;
+ struct sk_buff *skb;
+
+ event = sctp_ulpevent_new(sizeof(struct sctp_sender_dry_event),
+ MSG_NOTIFICATION, gfp);
+ if (!event)
+ return NULL;
+
+ skb = sctp_event2skb(event);
+ sdry = (struct sctp_sender_dry_event *)
+ skb_put(skb, sizeof(struct sctp_sender_dry_event));
+
+ sdry->sender_dry_type = SCTP_SENDER_DRY_EVENT;
+ sdry->sender_dry_flags = 0;
+ sdry->sender_dry_length = sizeof(struct sctp_sender_dry_event);
+ sctp_ulpevent_set_owner(event, asoc);
+ sdry->sender_dry_assoc_id = sctp_assoc2id(asoc);
+
+ return event;
+}
/* Return the notification type, assuming this is a notification
* event.
diff --git a/net/socket.c b/net/socket.c
index c2ed7c95ce8..02dc82db3d2 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -542,11 +542,10 @@ int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags)
}
EXPORT_SYMBOL(sock_tx_timestamp);
-static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
- struct msghdr *msg, size_t size)
+static inline int __sock_sendmsg_nosec(struct kiocb *iocb, struct socket *sock,
+ struct msghdr *msg, size_t size)
{
struct sock_iocb *si = kiocb_to_siocb(iocb);
- int err;
sock_update_classid(sock->sk);
@@ -555,13 +554,17 @@ static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
si->msg = msg;
si->size = size;
- err = security_socket_sendmsg(sock, msg, size);
- if (err)
- return err;
-
return sock->ops->sendmsg(iocb, sock, msg, size);
}
+static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
+ struct msghdr *msg, size_t size)
+{
+ int err = security_socket_sendmsg(sock, msg, size);
+
+ return err ?: __sock_sendmsg_nosec(iocb, sock, msg, size);
+}
+
int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
{
struct kiocb iocb;
@@ -577,6 +580,20 @@ int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
}
EXPORT_SYMBOL(sock_sendmsg);
+int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg, size_t size)
+{
+ struct kiocb iocb;
+ struct sock_iocb siocb;
+ int ret;
+
+ init_sync_kiocb(&iocb, NULL);
+ iocb.private = &siocb;
+ ret = __sock_sendmsg_nosec(&iocb, sock, msg, size);
+ if (-EIOCBQUEUED == ret)
+ ret = wait_on_sync_kiocb(&iocb);
+ return ret;
+}
+
int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
struct kvec *vec, size_t num, size_t size)
{
@@ -1854,57 +1871,47 @@ SYSCALL_DEFINE2(shutdown, int, fd, int, how)
#define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen)
#define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags)
-/*
- * BSD sendmsg interface
- */
-
-SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags)
+static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
+ struct msghdr *msg_sys, unsigned flags, int nosec)
{
struct compat_msghdr __user *msg_compat =
(struct compat_msghdr __user *)msg;
- struct socket *sock;
struct sockaddr_storage address;
struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
unsigned char ctl[sizeof(struct cmsghdr) + 20]
__attribute__ ((aligned(sizeof(__kernel_size_t))));
/* 20 is size of ipv6_pktinfo */
unsigned char *ctl_buf = ctl;
- struct msghdr msg_sys;
int err, ctl_len, iov_size, total_len;
- int fput_needed;
err = -EFAULT;
if (MSG_CMSG_COMPAT & flags) {
- if (get_compat_msghdr(&msg_sys, msg_compat))
+ if (get_compat_msghdr(msg_sys, msg_compat))
return -EFAULT;
- } else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr)))
+ } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr)))
return -EFAULT;
- sock = sockfd_lookup_light(fd, &err, &fput_needed);
- if (!sock)
- goto out;
-
/* do not move before msg_sys is valid */
err = -EMSGSIZE;
- if (msg_sys.msg_iovlen > UIO_MAXIOV)
- goto out_put;
+ if (msg_sys->msg_iovlen > UIO_MAXIOV)
+ goto out;
/* Check whether to allocate the iovec area */
err = -ENOMEM;
- iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
- if (msg_sys.msg_iovlen > UIO_FASTIOV) {
+ iov_size = msg_sys->msg_iovlen * sizeof(struct iovec);
+ if (msg_sys->msg_iovlen > UIO_FASTIOV) {
iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
if (!iov)
- goto out_put;
+ goto out;
}
/* This will also move the address data into kernel space */
if (MSG_CMSG_COMPAT & flags) {
- err = verify_compat_iovec(&msg_sys, iov,
+ err = verify_compat_iovec(msg_sys, iov,
(struct sockaddr *)&address,
VERIFY_READ);
} else
- err = verify_iovec(&msg_sys, iov,
+ err = verify_iovec(msg_sys, iov,
(struct sockaddr *)&address,
VERIFY_READ);
if (err < 0)
@@ -1913,17 +1920,17 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags)
err = -ENOBUFS;
- if (msg_sys.msg_controllen > INT_MAX)
+ if (msg_sys->msg_controllen > INT_MAX)
goto out_freeiov;
- ctl_len = msg_sys.msg_controllen;
+ ctl_len = msg_sys->msg_controllen;
if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
err =
- cmsghdr_from_user_compat_to_kern(&msg_sys, sock->sk, ctl,
+ cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl,
sizeof(ctl));
if (err)
goto out_freeiov;
- ctl_buf = msg_sys.msg_control;
- ctl_len = msg_sys.msg_controllen;
+ ctl_buf = msg_sys->msg_control;
+ ctl_len = msg_sys->msg_controllen;
} else if (ctl_len) {
if (ctl_len > sizeof(ctl)) {
ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
@@ -1932,21 +1939,22 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags)
}
err = -EFAULT;
/*
- * Careful! Before this, msg_sys.msg_control contains a user pointer.
+ * Careful! Before this, msg_sys->msg_control contains a user pointer.
* Afterwards, it will be a kernel pointer. Thus the compiler-assisted
* checking falls down on this.
*/
if (copy_from_user(ctl_buf,
- (void __user __force *)msg_sys.msg_control,
+ (void __user __force *)msg_sys->msg_control,
ctl_len))
goto out_freectl;
- msg_sys.msg_control = ctl_buf;
+ msg_sys->msg_control = ctl_buf;
}
- msg_sys.msg_flags = flags;
+ msg_sys->msg_flags = flags;
if (sock->file->f_flags & O_NONBLOCK)
- msg_sys.msg_flags |= MSG_DONTWAIT;
- err = sock_sendmsg(sock, &msg_sys, total_len);
+ msg_sys->msg_flags |= MSG_DONTWAIT;
+ err = (nosec ? sock_sendmsg_nosec : sock_sendmsg)(sock, msg_sys,
+ total_len);
out_freectl:
if (ctl_buf != ctl)
@@ -1954,12 +1962,114 @@ out_freectl:
out_freeiov:
if (iov != iovstack)
sock_kfree_s(sock->sk, iov, iov_size);
-out_put:
+out:
+ return err;
+}
+
+/*
+ * BSD sendmsg interface
+ */
+
+SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags)
+{
+ int fput_needed, err;
+ struct msghdr msg_sys;
+ struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed);
+
+ if (!sock)
+ goto out;
+
+ err = __sys_sendmsg(sock, msg, &msg_sys, flags, 0);
+
fput_light(sock->file, fput_needed);
out:
return err;
}
+/*
+ * Linux sendmmsg interface
+ */
+
+int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
+ unsigned int flags)
+{
+ int fput_needed, err, datagrams;
+ struct socket *sock;
+ struct mmsghdr __user *entry;
+ struct compat_mmsghdr __user *compat_entry;
+ struct msghdr msg_sys;
+
+ datagrams = 0;
+
+ sock = sockfd_lookup_light(fd, &err, &fput_needed);
+ if (!sock)
+ return err;
+
+ err = sock_error(sock->sk);
+ if (err)
+ goto out_put;
+
+ entry = mmsg;
+ compat_entry = (struct compat_mmsghdr __user *)mmsg;
+
+ while (datagrams < vlen) {
+ /*
+ * No need to ask LSM for more than the first datagram.
+ */
+ if (MSG_CMSG_COMPAT & flags) {
+ err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
+ &msg_sys, flags, datagrams);
+ if (err < 0)
+ break;
+ err = __put_user(err, &compat_entry->msg_len);
+ ++compat_entry;
+ } else {
+ err = __sys_sendmsg(sock, (struct msghdr __user *)entry,
+ &msg_sys, flags, datagrams);
+ if (err < 0)
+ break;
+ err = put_user(err, &entry->msg_len);
+ ++entry;
+ }
+
+ if (err)
+ break;
+ ++datagrams;
+ }
+
+out_put:
+ fput_light(sock->file, fput_needed);
+
+ if (err == 0)
+ return datagrams;
+
+ if (datagrams != 0) {
+ /*
+ * We may send less entries than requested (vlen) if the
+ * sock is non blocking...
+ */
+ if (err != -EAGAIN) {
+ /*
+ * ... or if sendmsg returns an error after we
+ * send some datagrams, where we record the
+ * error to return on the next call or if the
+ * app asks about it using getsockopt(SO_ERROR).
+ */
+ sock->sk->sk_err = -err;
+ }
+
+ return datagrams;
+ }
+
+ return err;
+}
+
+SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
+ unsigned int, vlen, unsigned int, flags)
+{
+ return __sys_sendmmsg(fd, mmsg, vlen, flags);
+}
+
static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
struct msghdr *msg_sys, unsigned flags, int nosec)
{
@@ -2113,14 +2223,16 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
*/
if (MSG_CMSG_COMPAT & flags) {
err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
- &msg_sys, flags, datagrams);
+ &msg_sys, flags & ~MSG_WAITFORONE,
+ datagrams);
if (err < 0)
break;
err = __put_user(err, &compat_entry->msg_len);
++compat_entry;
} else {
err = __sys_recvmsg(sock, (struct msghdr __user *)entry,
- &msg_sys, flags, datagrams);
+ &msg_sys, flags & ~MSG_WAITFORONE,
+ datagrams);
if (err < 0)
break;
err = put_user(err, &entry->msg_len);
@@ -2205,11 +2317,11 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
#ifdef __ARCH_WANT_SYS_SOCKETCALL
/* Argument list sizes for sys_socketcall */
#define AL(x) ((x) * sizeof(unsigned long))
-static const unsigned char nargs[20] = {
+static const unsigned char nargs[21] = {
AL(0), AL(3), AL(3), AL(3), AL(2), AL(3),
AL(3), AL(3), AL(4), AL(4), AL(4), AL(6),
AL(6), AL(2), AL(5), AL(5), AL(3), AL(3),
- AL(4), AL(5)
+ AL(4), AL(5), AL(4)
};
#undef AL
@@ -2229,7 +2341,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
int err;
unsigned int len;
- if (call < 1 || call > SYS_RECVMMSG)
+ if (call < 1 || call > SYS_SENDMMSG)
return -EINVAL;
len = nargs[call];
@@ -2304,6 +2416,9 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
case SYS_SENDMSG:
err = sys_sendmsg(a0, (struct msghdr __user *)a1, a[2]);
break;
+ case SYS_SENDMMSG:
+ err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]);
+ break;
case SYS_RECVMSG:
err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]);
break;
@@ -2634,13 +2749,13 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
return -EFAULT;
if (convert_in) {
- /* We expect there to be holes between fs.m_u and
+ /* We expect there to be holes between fs.m_ext and
* fs.ring_cookie and at the end of fs, but nowhere else.
*/
- BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_u) +
- sizeof(compat_rxnfc->fs.m_u) !=
- offsetof(struct ethtool_rxnfc, fs.m_u) +
- sizeof(rxnfc->fs.m_u));
+ BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_ext) +
+ sizeof(compat_rxnfc->fs.m_ext) !=
+ offsetof(struct ethtool_rxnfc, fs.m_ext) +
+ sizeof(rxnfc->fs.m_ext));
BUILD_BUG_ON(
offsetof(struct compat_ethtool_rxnfc, fs.location) -
offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) !=
@@ -2648,7 +2763,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
offsetof(struct ethtool_rxnfc, fs.ring_cookie));
if (copy_in_user(rxnfc, compat_rxnfc,
- (void *)(&rxnfc->fs.m_u + 1) -
+ (void *)(&rxnfc->fs.m_ext + 1) -
(void *)rxnfc) ||
copy_in_user(&rxnfc->fs.ring_cookie,
&compat_rxnfc->fs.ring_cookie,
@@ -2665,7 +2780,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
if (convert_out) {
if (copy_in_user(compat_rxnfc, rxnfc,
- (const void *)(&rxnfc->fs.m_u + 1) -
+ (const void *)(&rxnfc->fs.m_ext + 1) -
(const void *)rxnfc) ||
copy_in_user(&compat_rxnfc->fs.ring_cookie,
&rxnfc->fs.ring_cookie,
diff --git a/net/tipc/addr.h b/net/tipc/addr.h
index 8971aba99ae..e4f35afe320 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -37,14 +37,17 @@
#ifndef _TIPC_ADDR_H
#define _TIPC_ADDR_H
+#define TIPC_ZONE_MASK 0xff000000u
+#define TIPC_CLUSTER_MASK 0xfffff000u
+
static inline u32 tipc_zone_mask(u32 addr)
{
- return addr & 0xff000000u;
+ return addr & TIPC_ZONE_MASK;
}
static inline u32 tipc_cluster_mask(u32 addr)
{
- return addr & 0xfffff000u;
+ return addr & TIPC_CLUSTER_MASK;
}
static inline int in_own_cluster(u32 addr)
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 7dc1dc7151e..fa68d1e9ff4 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -44,13 +44,6 @@
#define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */
-/*
- * Loss rate for incoming broadcast frames; used to test retransmission code.
- * Set to N to cause every N'th frame to be discarded; 0 => don't discard any.
- */
-
-#define TIPC_BCAST_LOSS_RATE 0
-
/**
* struct bcbearer_pair - a pair of bearers used by broadcast link
* @primary: pointer to primary bearer
@@ -414,9 +407,7 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
spin_lock_bh(&bc_lock);
res = tipc_link_send_buf(bcl, buf);
- if (unlikely(res == -ELINKCONG))
- buf_discard(buf);
- else
+ if (likely(res > 0))
bclink_set_last_sent();
bcl->stats.queue_sz_counts++;
@@ -434,9 +425,6 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
void tipc_bclink_recv_pkt(struct sk_buff *buf)
{
-#if (TIPC_BCAST_LOSS_RATE)
- static int rx_count;
-#endif
struct tipc_msg *msg = buf_msg(buf);
struct tipc_node *node = tipc_node_find(msg_prevnode(msg));
u32 next_in;
@@ -470,14 +458,6 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
return;
}
-#if (TIPC_BCAST_LOSS_RATE)
- if (++rx_count == TIPC_BCAST_LOSS_RATE) {
- rx_count = 0;
- buf_discard(buf);
- return;
- }
-#endif
-
tipc_node_lock(node);
receive:
deferred = node->bclink.deferred_head;
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 411719feb80..85209eadfae 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -46,6 +46,8 @@ static u32 media_count;
struct tipc_bearer tipc_bearers[MAX_BEARERS];
+static void bearer_disable(struct tipc_bearer *b_ptr);
+
/**
* media_name_valid - validate media name
*
@@ -342,15 +344,15 @@ struct sk_buff *tipc_bearer_get_names(void)
void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest)
{
tipc_nmap_add(&b_ptr->nodes, dest);
- tipc_disc_update_link_req(b_ptr->link_req);
tipc_bcbearer_sort();
+ tipc_disc_add_dest(b_ptr->link_req);
}
void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest)
{
tipc_nmap_remove(&b_ptr->nodes, dest);
- tipc_disc_update_link_req(b_ptr->link_req);
tipc_bcbearer_sort();
+ tipc_disc_remove_dest(b_ptr->link_req);
}
/*
@@ -493,8 +495,15 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
warn("Bearer <%s> rejected, illegal name\n", name);
return -EINVAL;
}
- if (!tipc_addr_domain_valid(disc_domain) ||
- !tipc_in_scope(disc_domain, tipc_own_addr)) {
+ if (tipc_addr_domain_valid(disc_domain) &&
+ (disc_domain != tipc_own_addr)) {
+ if (tipc_in_scope(disc_domain, tipc_own_addr)) {
+ disc_domain = tipc_own_addr & TIPC_CLUSTER_MASK;
+ res = 0; /* accept any node in own cluster */
+ } else if (in_own_cluster(disc_domain))
+ res = 0; /* accept specified node in own cluster */
+ }
+ if (res) {
warn("Bearer <%s> rejected, illegal discovery domain\n", name);
return -EINVAL;
}
@@ -511,7 +520,7 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
if (!m_ptr) {
warn("Bearer <%s> rejected, media <%s> not registered\n", name,
b_name.media_name);
- goto failed;
+ goto exit;
}
if (priority == TIPC_MEDIA_LINK_PRI)
@@ -527,14 +536,14 @@ restart:
}
if (!strcmp(name, tipc_bearers[i].name)) {
warn("Bearer <%s> rejected, already enabled\n", name);
- goto failed;
+ goto exit;
}
if ((tipc_bearers[i].priority == priority) &&
(++with_this_prio > 2)) {
if (priority-- == 0) {
warn("Bearer <%s> rejected, duplicate priority\n",
name);
- goto failed;
+ goto exit;
}
warn("Bearer <%s> priority adjustment required %u->%u\n",
name, priority + 1, priority);
@@ -544,7 +553,7 @@ restart:
if (bearer_id >= MAX_BEARERS) {
warn("Bearer <%s> rejected, bearer limit reached (%u)\n",
name, MAX_BEARERS);
- goto failed;
+ goto exit;
}
b_ptr = &tipc_bearers[bearer_id];
@@ -552,7 +561,7 @@ restart:
res = m_ptr->enable_bearer(b_ptr);
if (res) {
warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res);
- goto failed;
+ goto exit;
}
b_ptr->identity = bearer_id;
@@ -562,14 +571,18 @@ restart:
b_ptr->priority = priority;
INIT_LIST_HEAD(&b_ptr->cong_links);
INIT_LIST_HEAD(&b_ptr->links);
- b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr,
- disc_domain);
spin_lock_init(&b_ptr->lock);
- write_unlock_bh(&tipc_net_lock);
+
+ res = tipc_disc_create(b_ptr, &m_ptr->bcast_addr, disc_domain);
+ if (res) {
+ bearer_disable(b_ptr);
+ warn("Bearer <%s> rejected, discovery object creation failed\n",
+ name);
+ goto exit;
+ }
info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
name, tipc_addr_string_fill(addr_string, disc_domain), priority);
- return 0;
-failed:
+exit:
write_unlock_bh(&tipc_net_lock);
return res;
}
@@ -620,14 +633,14 @@ static void bearer_disable(struct tipc_bearer *b_ptr)
struct link *temp_l_ptr;
info("Disabling bearer <%s>\n", b_ptr->name);
- tipc_disc_stop_link_req(b_ptr->link_req);
spin_lock_bh(&b_ptr->lock);
- b_ptr->link_req = NULL;
b_ptr->blocked = 1;
b_ptr->media->disable_bearer(b_ptr);
list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
tipc_link_delete(l_ptr);
}
+ if (b_ptr->link_req)
+ tipc_disc_delete(b_ptr->link_req);
spin_unlock_bh(&b_ptr->lock);
memset(b_ptr, 0, sizeof(struct tipc_bearer));
}
diff --git a/net/tipc/core.c b/net/tipc/core.c
index c9a73e7763f..943b6af8426 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -179,8 +179,7 @@ static int __init tipc_init(void)
if (tipc_log_resize(CONFIG_TIPC_LOG) != 0)
warn("Unable to create log buffer\n");
- info("Activated (version " TIPC_MOD_VER
- " compiled " __DATE__ " " __TIME__ ")\n");
+ info("Activated (version " TIPC_MOD_VER ")\n");
tipc_own_addr = 0;
tipc_remote_management = 1;
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 491eff56b9d..0987933155b 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -39,19 +39,17 @@
#include "discover.h"
#define TIPC_LINK_REQ_INIT 125 /* min delay during bearer start up */
-#define TIPC_LINK_REQ_FAST 2000 /* normal delay if bearer has no links */
-#define TIPC_LINK_REQ_SLOW 600000 /* normal delay if bearer has links */
-
-/*
- * TODO: Most of the inter-cluster setup stuff should be
- * rewritten, and be made conformant with specification.
- */
+#define TIPC_LINK_REQ_FAST 1000 /* max delay if bearer has no links */
+#define TIPC_LINK_REQ_SLOW 60000 /* max delay if bearer has links */
+#define TIPC_LINK_REQ_INACTIVE 0xffffffff /* indicates no timer in use */
/**
* struct link_req - information about an ongoing link setup request
* @bearer: bearer issuing requests
* @dest: destination address for request messages
+ * @domain: network domain to which links can be established
+ * @num_nodes: number of nodes currently discovered (i.e. with an active link)
* @buf: request message to be (repeatedly) sent
* @timer: timer governing period between requests
* @timer_intv: current interval between requests (in ms)
@@ -59,6 +57,8 @@
struct link_req {
struct tipc_bearer *bearer;
struct tipc_media_addr dest;
+ u32 domain;
+ int num_nodes;
struct sk_buff *buf;
struct timer_list timer;
unsigned int timer_intv;
@@ -147,7 +147,7 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
}
if (!tipc_in_scope(dest, tipc_own_addr))
return;
- if (!in_own_cluster(orig))
+ if (!tipc_in_scope(b_ptr->link_req->domain, orig))
return;
/* Locate structure corresponding to requesting node */
@@ -214,44 +214,54 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
}
/**
- * tipc_disc_stop_link_req - stop sending periodic link setup requests
+ * disc_update - update frequency of periodic link setup requests
* @req: ptr to link request structure
+ *
+ * Reinitiates discovery process if discovery object has no associated nodes
+ * and is either not currently searching or is searching at a slow rate
*/
-void tipc_disc_stop_link_req(struct link_req *req)
+static void disc_update(struct link_req *req)
{
- if (!req)
- return;
+ if (!req->num_nodes) {
+ if ((req->timer_intv == TIPC_LINK_REQ_INACTIVE) ||
+ (req->timer_intv > TIPC_LINK_REQ_FAST)) {
+ req->timer_intv = TIPC_LINK_REQ_INIT;
+ k_start_timer(&req->timer, req->timer_intv);
+ }
+ }
+}
- k_cancel_timer(&req->timer);
- k_term_timer(&req->timer);
- buf_discard(req->buf);
- kfree(req);
+/**
+ * tipc_disc_add_dest - increment set of discovered nodes
+ * @req: ptr to link request structure
+ */
+
+void tipc_disc_add_dest(struct link_req *req)
+{
+ req->num_nodes++;
}
/**
- * tipc_disc_update_link_req - update frequency of periodic link setup requests
+ * tipc_disc_remove_dest - decrement set of discovered nodes
* @req: ptr to link request structure
*/
-void tipc_disc_update_link_req(struct link_req *req)
+void tipc_disc_remove_dest(struct link_req *req)
{
- if (!req)
- return;
+ req->num_nodes--;
+ disc_update(req);
+}
- if (req->timer_intv == TIPC_LINK_REQ_SLOW) {
- if (!req->bearer->nodes.count) {
- req->timer_intv = TIPC_LINK_REQ_FAST;
- k_start_timer(&req->timer, req->timer_intv);
- }
- } else if (req->timer_intv == TIPC_LINK_REQ_FAST) {
- if (req->bearer->nodes.count) {
- req->timer_intv = TIPC_LINK_REQ_SLOW;
- k_start_timer(&req->timer, req->timer_intv);
- }
- } else {
- /* leave timer "as is" if haven't yet reached a "normal" rate */
- }
+/**
+ * disc_send_msg - send link setup request message
+ * @req: ptr to link request structure
+ */
+
+static void disc_send_msg(struct link_req *req)
+{
+ if (!req->bearer->blocked)
+ tipc_bearer_send(req->bearer, req->buf, &req->dest);
}
/**
@@ -263,56 +273,86 @@ void tipc_disc_update_link_req(struct link_req *req)
static void disc_timeout(struct link_req *req)
{
+ int max_delay;
+
spin_lock_bh(&req->bearer->lock);
- req->bearer->media->send_msg(req->buf, req->bearer, &req->dest);
-
- if ((req->timer_intv == TIPC_LINK_REQ_SLOW) ||
- (req->timer_intv == TIPC_LINK_REQ_FAST)) {
- /* leave timer interval "as is" if already at a "normal" rate */
- } else {
- req->timer_intv *= 2;
- if (req->timer_intv > TIPC_LINK_REQ_FAST)
- req->timer_intv = TIPC_LINK_REQ_FAST;
- if ((req->timer_intv == TIPC_LINK_REQ_FAST) &&
- (req->bearer->nodes.count))
- req->timer_intv = TIPC_LINK_REQ_SLOW;
+ /* Stop searching if only desired node has been found */
+
+ if (tipc_node(req->domain) && req->num_nodes) {
+ req->timer_intv = TIPC_LINK_REQ_INACTIVE;
+ goto exit;
}
- k_start_timer(&req->timer, req->timer_intv);
+ /*
+ * Send discovery message, then update discovery timer
+ *
+ * Keep doubling time between requests until limit is reached;
+ * hold at fast polling rate if don't have any associated nodes,
+ * otherwise hold at slow polling rate
+ */
+
+ disc_send_msg(req);
+
+ req->timer_intv *= 2;
+ if (req->num_nodes)
+ max_delay = TIPC_LINK_REQ_SLOW;
+ else
+ max_delay = TIPC_LINK_REQ_FAST;
+ if (req->timer_intv > max_delay)
+ req->timer_intv = max_delay;
+
+ k_start_timer(&req->timer, req->timer_intv);
+exit:
spin_unlock_bh(&req->bearer->lock);
}
/**
- * tipc_disc_init_link_req - start sending periodic link setup requests
+ * tipc_disc_create - create object to send periodic link setup requests
* @b_ptr: ptr to bearer issuing requests
* @dest: destination address for request messages
- * @dest_domain: network domain of node(s) which should respond to message
+ * @dest_domain: network domain to which links can be established
*
- * Returns pointer to link request structure, or NULL if unable to create.
+ * Returns 0 if successful, otherwise -errno.
*/
-struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr,
- const struct tipc_media_addr *dest,
- u32 dest_domain)
+int tipc_disc_create(struct tipc_bearer *b_ptr,
+ struct tipc_media_addr *dest, u32 dest_domain)
{
struct link_req *req;
req = kmalloc(sizeof(*req), GFP_ATOMIC);
if (!req)
- return NULL;
+ return -ENOMEM;
req->buf = tipc_disc_init_msg(DSC_REQ_MSG, dest_domain, b_ptr);
if (!req->buf) {
kfree(req);
- return NULL;
+ return -ENOMSG;
}
memcpy(&req->dest, dest, sizeof(*dest));
req->bearer = b_ptr;
+ req->domain = dest_domain;
+ req->num_nodes = 0;
req->timer_intv = TIPC_LINK_REQ_INIT;
k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req);
k_start_timer(&req->timer, req->timer_intv);
- return req;
+ b_ptr->link_req = req;
+ disc_send_msg(req);
+ return 0;
+}
+
+/**
+ * tipc_disc_delete - destroy object sending periodic link setup requests
+ * @req: ptr to link request structure
+ */
+
+void tipc_disc_delete(struct link_req *req)
+{
+ k_cancel_timer(&req->timer);
+ k_term_timer(&req->timer);
+ buf_discard(req->buf);
+ kfree(req);
}
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index e48a167e47b..a3af595b86c 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -39,12 +39,11 @@
struct link_req;
-struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr,
- const struct tipc_media_addr *dest,
- u32 dest_domain);
-void tipc_disc_update_link_req(struct link_req *req);
-void tipc_disc_stop_link_req(struct link_req *req);
-
+int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest,
+ u32 dest_domain);
+void tipc_disc_delete(struct link_req *req);
+void tipc_disc_add_dest(struct link_req *req);
+void tipc_disc_remove_dest(struct link_req *req);
void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr);
#endif
diff --git a/net/tipc/link.c b/net/tipc/link.c
index ebf338f7b14..5ed4b4f7452 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -92,7 +92,8 @@ static int link_recv_changeover_msg(struct link **l_ptr, struct sk_buff **buf);
static void link_set_supervision_props(struct link *l_ptr, u32 tolerance);
static int link_send_sections_long(struct tipc_port *sender,
struct iovec const *msg_sect,
- u32 num_sect, u32 destnode);
+ u32 num_sect, unsigned int total_len,
+ u32 destnode);
static void link_check_defragm_bufs(struct link *l_ptr);
static void link_state_event(struct link *l_ptr, u32 event);
static void link_reset_statistics(struct link *l_ptr);
@@ -842,6 +843,25 @@ static void link_add_to_outqueue(struct link *l_ptr,
l_ptr->stats.max_queue_sz = l_ptr->out_queue_size;
}
+static void link_add_chain_to_outqueue(struct link *l_ptr,
+ struct sk_buff *buf_chain,
+ u32 long_msgno)
+{
+ struct sk_buff *buf;
+ struct tipc_msg *msg;
+
+ if (!l_ptr->next_out)
+ l_ptr->next_out = buf_chain;
+ while (buf_chain) {
+ buf = buf_chain;
+ buf_chain = buf_chain->next;
+
+ msg = buf_msg(buf);
+ msg_set_long_msgno(msg, long_msgno);
+ link_add_to_outqueue(l_ptr, buf, msg);
+ }
+}
+
/*
* tipc_link_send_buf() is the 'full path' for messages, called from
* inside TIPC when the 'fast path' in tipc_send_buf
@@ -864,8 +884,9 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
if (unlikely(queue_size >= queue_limit)) {
if (imp <= TIPC_CRITICAL_IMPORTANCE) {
- return link_schedule_port(l_ptr, msg_origport(msg),
- size);
+ link_schedule_port(l_ptr, msg_origport(msg), size);
+ buf_discard(buf);
+ return -ELINKCONG;
}
buf_discard(buf);
if (imp > CONN_MANAGER) {
@@ -1042,6 +1063,7 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
int tipc_link_send_sections_fast(struct tipc_port *sender,
struct iovec const *msg_sect,
const u32 num_sect,
+ unsigned int total_len,
u32 destaddr)
{
struct tipc_msg *hdr = &sender->phdr;
@@ -1057,8 +1079,8 @@ again:
* (Must not hold any locks while building message.)
*/
- res = tipc_msg_build(hdr, msg_sect, num_sect, sender->max_pkt,
- !sender->user_port, &buf);
+ res = tipc_msg_build(hdr, msg_sect, num_sect, total_len,
+ sender->max_pkt, !sender->user_port, &buf);
read_lock_bh(&tipc_net_lock);
node = tipc_node_find(destaddr);
@@ -1069,8 +1091,6 @@ again:
if (likely(buf)) {
res = link_send_buf_fast(l_ptr, buf,
&sender->max_pkt);
- if (unlikely(res < 0))
- buf_discard(buf);
exit:
tipc_node_unlock(node);
read_unlock_bh(&tipc_net_lock);
@@ -1105,7 +1125,8 @@ exit:
goto again;
return link_send_sections_long(sender, msg_sect,
- num_sect, destaddr);
+ num_sect, total_len,
+ destaddr);
}
tipc_node_unlock(node);
}
@@ -1117,7 +1138,7 @@ exit:
return tipc_reject_msg(buf, TIPC_ERR_NO_NODE);
if (res >= 0)
return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
- TIPC_ERR_NO_NODE);
+ total_len, TIPC_ERR_NO_NODE);
return res;
}
@@ -1138,12 +1159,13 @@ exit:
static int link_send_sections_long(struct tipc_port *sender,
struct iovec const *msg_sect,
u32 num_sect,
+ unsigned int total_len,
u32 destaddr)
{
struct link *l_ptr;
struct tipc_node *node;
struct tipc_msg *hdr = &sender->phdr;
- u32 dsz = msg_data_sz(hdr);
+ u32 dsz = total_len;
u32 max_pkt, fragm_sz, rest;
struct tipc_msg fragm_hdr;
struct sk_buff *buf, *buf_chain, *prev;
@@ -1169,7 +1191,6 @@ again:
tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
INT_H_SIZE, msg_destnode(hdr));
- msg_set_link_selector(&fragm_hdr, sender->ref);
msg_set_size(&fragm_hdr, max_pkt);
msg_set_fragm_no(&fragm_hdr, 1);
@@ -1271,28 +1292,15 @@ reject:
buf_discard(buf_chain);
}
return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
- TIPC_ERR_NO_NODE);
+ total_len, TIPC_ERR_NO_NODE);
}
- /* Append whole chain to send queue: */
+ /* Append chain of fragments to send queue & send them */
- buf = buf_chain;
- l_ptr->long_msg_seq_no = mod(l_ptr->long_msg_seq_no + 1);
- if (!l_ptr->next_out)
- l_ptr->next_out = buf_chain;
+ l_ptr->long_msg_seq_no++;
+ link_add_chain_to_outqueue(l_ptr, buf_chain, l_ptr->long_msg_seq_no);
+ l_ptr->stats.sent_fragments += fragm_no;
l_ptr->stats.sent_fragmented++;
- while (buf) {
- struct sk_buff *next = buf->next;
- struct tipc_msg *msg = buf_msg(buf);
-
- l_ptr->stats.sent_fragments++;
- msg_set_long_msgno(msg, l_ptr->long_msg_seq_no);
- link_add_to_outqueue(l_ptr, buf, msg);
- buf = next;
- }
-
- /* Send it, if possible: */
-
tipc_link_push_queue(l_ptr);
tipc_node_unlock(node);
return dsz;
@@ -2407,6 +2415,8 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
*/
static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
{
+ struct sk_buff *buf_chain = NULL;
+ struct sk_buff *buf_chain_tail = (struct sk_buff *)&buf_chain;
struct tipc_msg *inmsg = buf_msg(buf);
struct tipc_msg fragm_hdr;
u32 insize = msg_size(inmsg);
@@ -2415,7 +2425,7 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
u32 rest = insize;
u32 pack_sz = l_ptr->max_pkt;
u32 fragm_sz = pack_sz - INT_H_SIZE;
- u32 fragm_no = 1;
+ u32 fragm_no = 0;
u32 destaddr;
if (msg_short(inmsg))
@@ -2427,10 +2437,6 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
INT_H_SIZE, destaddr);
- msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg));
- msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++));
- msg_set_fragm_no(&fragm_hdr, fragm_no);
- l_ptr->stats.sent_fragmented++;
/* Chop up message: */
@@ -2443,27 +2449,37 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
}
fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE);
if (fragm == NULL) {
- warn("Link unable to fragment message\n");
- dsz = -ENOMEM;
- goto exit;
+ buf_discard(buf);
+ while (buf_chain) {
+ buf = buf_chain;
+ buf_chain = buf_chain->next;
+ buf_discard(buf);
+ }
+ return -ENOMEM;
}
msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE);
+ fragm_no++;
+ msg_set_fragm_no(&fragm_hdr, fragm_no);
skb_copy_to_linear_data(fragm, &fragm_hdr, INT_H_SIZE);
skb_copy_to_linear_data_offset(fragm, INT_H_SIZE, crs,
fragm_sz);
- /* Send queued messages first, if any: */
+ buf_chain_tail->next = fragm;
+ buf_chain_tail = fragm;
- l_ptr->stats.sent_fragments++;
- tipc_link_send_buf(l_ptr, fragm);
- if (!tipc_link_is_up(l_ptr))
- return dsz;
- msg_set_fragm_no(&fragm_hdr, ++fragm_no);
rest -= fragm_sz;
crs += fragm_sz;
msg_set_type(&fragm_hdr, FRAGMENT);
}
-exit:
buf_discard(buf);
+
+ /* Append chain of fragments to send queue & send them */
+
+ l_ptr->long_msg_seq_no++;
+ link_add_chain_to_outqueue(l_ptr, buf_chain, l_ptr->long_msg_seq_no);
+ l_ptr->stats.sent_fragments += fragm_no;
+ l_ptr->stats.sent_fragmented++;
+ tipc_link_push_queue(l_ptr);
+
return dsz;
}
diff --git a/net/tipc/link.h b/net/tipc/link.h
index e6a30dbe1aa..74fbecab1ea 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -228,6 +228,7 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector);
int tipc_link_send_sections_fast(struct tipc_port *sender,
struct iovec const *msg_sect,
const u32 num_sect,
+ unsigned int total_len,
u32 destnode);
void tipc_link_recv_bundle(struct sk_buff *buf);
int tipc_link_recv_fragment(struct sk_buff **pending,
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 6d92d17e7fb..03e57bf92c7 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -68,20 +68,6 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
}
/**
- * tipc_msg_calc_data_size - determine total data size for message
- */
-
-int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect)
-{
- int dsz = 0;
- int i;
-
- for (i = 0; i < num_sect; i++)
- dsz += msg_sect[i].iov_len;
- return dsz;
-}
-
-/**
* tipc_msg_build - create message using specified header and data
*
* Note: Caller must not hold any locks in case copy_from_user() is interrupted!
@@ -89,18 +75,13 @@ int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect)
* Returns message data size or errno
*/
-int tipc_msg_build(struct tipc_msg *hdr,
- struct iovec const *msg_sect, u32 num_sect,
+int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
+ u32 num_sect, unsigned int total_len,
int max_size, int usrmem, struct sk_buff **buf)
{
int dsz, sz, hsz, pos, res, cnt;
- dsz = tipc_msg_calc_data_size(msg_sect, num_sect);
- if (unlikely(dsz > TIPC_MAX_USER_MSG_SIZE)) {
- *buf = NULL;
- return -EINVAL;
- }
-
+ dsz = total_len;
pos = hsz = msg_hdr_sz(hdr);
sz = hsz + dsz;
msg_set_size(hdr, sz);
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index de02339fc17..8452454731f 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -39,41 +39,24 @@
#include "bearer.h"
+/*
+ * Constants and routines used to read and write TIPC payload message headers
+ *
+ * Note: Some items are also used with TIPC internal message headers
+ */
+
#define TIPC_VERSION 2
/*
- * TIPC user data message header format, version 2:
- *
- *
- * 1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * w0:|vers | user |hdr sz |n|d|s|-| message size |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * w1:|mstyp| error |rer cnt|lsc|opt p| broadcast ack no |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * w2:| link level ack no | broadcast/link level seq no |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * w3:| previous node |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * w4:| originating port |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * w5:| destination port |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * w6:| originating node |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * w7:| destination node |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * w8:| name type / transport sequence number |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * w9:| name instance/multicast lower bound |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * wA:| multicast upper bound |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * / /
- * \ options \
- * / /
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
+ * Payload message users are defined in TIPC's public API:
+ * - TIPC_LOW_IMPORTANCE
+ * - TIPC_MEDIUM_IMPORTANCE
+ * - TIPC_HIGH_IMPORTANCE
+ * - TIPC_CRITICAL_IMPORTANCE
+ */
+
+/*
+ * Payload message types
*/
#define TIPC_CONN_MSG 0
@@ -81,6 +64,9 @@
#define TIPC_NAMED_MSG 2
#define TIPC_DIRECT_MSG 3
+/*
+ * Message header sizes
+ */
#define SHORT_H_SIZE 24 /* Connected, in-cluster messages */
#define DIR_MSG_H_SIZE 32 /* Directly addressed messages */
@@ -473,40 +459,11 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
/*
- TIPC internal message header format, version 2
-
- 1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w0:|vers |msg usr|hdr sz |n|resrv| packet size |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w1:|m typ| sequence gap | broadcast ack no |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w2:| link level ack no/bc_gap_from | seq no / bcast_gap_to |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w3:| previous node |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w4:| next sent broadcast/fragm no | next sent pkt/ fragm msg no |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w5:| session no |rsv=0|r|berid|link prio|netpl|p|
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w6:| originating node |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w7:| destination node |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w8:| transport sequence number |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w9:| msg count / bcast tag | link tolerance |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- \ \
- / User Specific Data /
- \ \
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
- NB: CONN_MANAGER use data message format. LINK_CONFIG has own format.
-*/
+ * Constants and routines used to read and write TIPC internal message headers
+ */
/*
- * Internal users
+ * Internal message users
*/
#define BCAST_PROTOCOL 5
@@ -520,7 +477,7 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
#define LINK_CONFIG 13
/*
- * Connection management protocol messages
+ * Connection management protocol message types
*/
#define CONN_PROBE 0
@@ -528,12 +485,41 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
#define CONN_ACK 2
/*
- * Name distributor messages
+ * Name distributor message types
*/
#define PUBLICATION 0
#define WITHDRAWAL 1
+/*
+ * Segmentation message types
+ */
+
+#define FIRST_FRAGMENT 0
+#define FRAGMENT 1
+#define LAST_FRAGMENT 2
+
+/*
+ * Link management protocol message types
+ */
+
+#define STATE_MSG 0
+#define RESET_MSG 1
+#define ACTIVATE_MSG 2
+
+/*
+ * Changeover tunnel message types
+ */
+#define DUPLICATE_MSG 0
+#define ORIGINAL_MSG 1
+
+/*
+ * Config protocol message types
+ */
+
+#define DSC_REQ_MSG 0
+#define DSC_RESP_MSG 1
+
/*
* Word 1
@@ -761,50 +747,11 @@ static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n)
msg_set_bits(m, 9, 0, 0xffff, n);
}
-/*
- * Segmentation message types
- */
-
-#define FIRST_FRAGMENT 0
-#define FRAGMENT 1
-#define LAST_FRAGMENT 2
-
-/*
- * Link management protocol message types
- */
-
-#define STATE_MSG 0
-#define RESET_MSG 1
-#define ACTIVATE_MSG 2
-
-/*
- * Changeover tunnel message types
- */
-#define DUPLICATE_MSG 0
-#define ORIGINAL_MSG 1
-
-/*
- * Routing table message types
- */
-#define EXT_ROUTING_TABLE 0
-#define LOCAL_ROUTING_TABLE 1 /* obsoleted */
-#define SLAVE_ROUTING_TABLE 2
-#define ROUTE_ADDITION 3
-#define ROUTE_REMOVAL 4
-
-/*
- * Config protocol message types
- */
-
-#define DSC_REQ_MSG 0
-#define DSC_RESP_MSG 1
-
u32 tipc_msg_tot_importance(struct tipc_msg *m);
void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
u32 hsize, u32 destnode);
-int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect);
-int tipc_msg_build(struct tipc_msg *hdr,
- struct iovec const *msg_sect, u32 num_sect,
+int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
+ u32 num_sect, unsigned int total_len,
int max_size, int usrmem, struct sk_buff **buf);
static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 6ff78f9c7d6..c68dc956a42 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -74,7 +74,8 @@ static u32 port_peerport(struct tipc_port *p_ptr)
*/
int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
- u32 num_sect, struct iovec const *msg_sect)
+ u32 num_sect, struct iovec const *msg_sect,
+ unsigned int total_len)
{
struct tipc_msg *hdr;
struct sk_buff *buf;
@@ -91,11 +92,14 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
hdr = &oport->phdr;
msg_set_type(hdr, TIPC_MCAST_MSG);
+ msg_set_lookup_scope(hdr, TIPC_CLUSTER_SCOPE);
+ msg_set_destport(hdr, 0);
+ msg_set_destnode(hdr, 0);
msg_set_nametype(hdr, seq->type);
msg_set_namelower(hdr, seq->lower);
msg_set_nameupper(hdr, seq->upper);
msg_set_hdr_sz(hdr, MCAST_H_SIZE);
- res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE,
+ res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE,
!oport->user_port, &buf);
if (unlikely(!buf))
return res;
@@ -161,6 +165,7 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp)
/* Deliver a copy of message to each destination port */
if (dp->count != 0) {
+ msg_set_destnode(msg, tipc_own_addr);
if (dp->count == 1) {
msg_set_destport(msg, dp->ports[0]);
tipc_port_recv_msg(buf);
@@ -414,12 +419,12 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
struct iovec const *msg_sect, u32 num_sect,
- int err)
+ unsigned int total_len, int err)
{
struct sk_buff *buf;
int res;
- res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE,
+ res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE,
!p_ptr->user_port, &buf);
if (!buf)
return res;
@@ -1065,6 +1070,7 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
msg_set_orignode(msg, tipc_own_addr);
msg_set_origport(msg, p_ptr->ref);
msg_set_type(msg, TIPC_CONN_MSG);
+ msg_set_lookup_scope(msg, 0);
msg_set_hdr_sz(msg, SHORT_H_SIZE);
p_ptr->probing_interval = PROBING_INTERVAL;
@@ -1158,12 +1164,13 @@ int tipc_shutdown(u32 ref)
*/
static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_sect,
- struct iovec const *msg_sect)
+ struct iovec const *msg_sect,
+ unsigned int total_len)
{
struct sk_buff *buf;
int res;
- res = tipc_msg_build(&sender->phdr, msg_sect, num_sect,
+ res = tipc_msg_build(&sender->phdr, msg_sect, num_sect, total_len,
MAX_MSG_SIZE, !sender->user_port, &buf);
if (likely(buf))
tipc_port_recv_msg(buf);
@@ -1174,7 +1181,8 @@ static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_se
* tipc_send - send message sections on connection
*/
-int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
+int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect,
+ unsigned int total_len)
{
struct tipc_port *p_ptr;
u32 destnode;
@@ -1189,9 +1197,10 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
destnode = port_peernode(p_ptr);
if (likely(destnode != tipc_own_addr))
res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,
- destnode);
+ total_len, destnode);
else
- res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
+ res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect,
+ total_len);
if (likely(res != -ELINKCONG)) {
p_ptr->congested = 0;
@@ -1202,8 +1211,7 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
}
if (port_unreliable(p_ptr)) {
p_ptr->congested = 0;
- /* Just calculate msg length and return */
- return tipc_msg_calc_data_size(msg_sect, num_sect);
+ return total_len;
}
return -ELINKCONG;
}
@@ -1213,7 +1221,8 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
*/
int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
- unsigned int num_sect, struct iovec const *msg_sect)
+ unsigned int num_sect, struct iovec const *msg_sect,
+ unsigned int total_len)
{
struct tipc_port *p_ptr;
struct tipc_msg *msg;
@@ -1240,23 +1249,23 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
if (likely(destport)) {
if (likely(destnode == tipc_own_addr))
res = tipc_port_recv_sections(p_ptr, num_sect,
- msg_sect);
+ msg_sect, total_len);
else
res = tipc_link_send_sections_fast(p_ptr, msg_sect,
- num_sect, destnode);
+ num_sect, total_len,
+ destnode);
if (likely(res != -ELINKCONG)) {
if (res > 0)
p_ptr->sent++;
return res;
}
if (port_unreliable(p_ptr)) {
- /* Just calculate msg length and return */
- return tipc_msg_calc_data_size(msg_sect, num_sect);
+ return total_len;
}
return -ELINKCONG;
}
return tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect,
- TIPC_ERR_NO_NAME);
+ total_len, TIPC_ERR_NO_NAME);
}
/**
@@ -1264,7 +1273,8 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
*/
int tipc_send2port(u32 ref, struct tipc_portid const *dest,
- unsigned int num_sect, struct iovec const *msg_sect)
+ unsigned int num_sect, struct iovec const *msg_sect,
+ unsigned int total_len)
{
struct tipc_port *p_ptr;
struct tipc_msg *msg;
@@ -1276,6 +1286,7 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest,
msg = &p_ptr->phdr;
msg_set_type(msg, TIPC_DIRECT_MSG);
+ msg_set_lookup_scope(msg, 0);
msg_set_orignode(msg, tipc_own_addr);
msg_set_origport(msg, ref);
msg_set_destnode(msg, dest->node);
@@ -1283,18 +1294,18 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest,
msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
if (dest->node == tipc_own_addr)
- res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
+ res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect,
+ total_len);
else
res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,
- dest->node);
+ total_len, dest->node);
if (likely(res != -ELINKCONG)) {
if (res > 0)
p_ptr->sent++;
return res;
}
if (port_unreliable(p_ptr)) {
- /* Just calculate msg length and return */
- return tipc_msg_calc_data_size(msg_sect, num_sect);
+ return total_len;
}
return -ELINKCONG;
}
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 87b9424ae0e..b9aa34195ae 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -205,23 +205,27 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr);
/*
* TIPC messaging routines
*/
-int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect);
+int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect,
+ unsigned int total_len);
int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain,
- unsigned int num_sect, struct iovec const *msg_sect);
+ unsigned int num_sect, struct iovec const *msg_sect,
+ unsigned int total_len);
int tipc_send2port(u32 portref, struct tipc_portid const *dest,
- unsigned int num_sect, struct iovec const *msg_sect);
+ unsigned int num_sect, struct iovec const *msg_sect,
+ unsigned int total_len);
int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest,
struct sk_buff *buf, unsigned int dsz);
int tipc_multicast(u32 portref, struct tipc_name_seq const *seq,
- unsigned int section_count, struct iovec const *msg);
+ unsigned int section_count, struct iovec const *msg,
+ unsigned int total_len);
int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
struct iovec const *msg_sect, u32 num_sect,
- int err);
+ unsigned int total_len, int err);
struct sk_buff *tipc_port_get_ports(void);
void tipc_port_recv_proto_msg(struct sk_buff *buf);
void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 29d94d53198..33883739664 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -535,6 +535,9 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
if (unlikely((m->msg_namelen < sizeof(*dest)) ||
(dest->family != AF_TIPC)))
return -EINVAL;
+ if ((total_len > TIPC_MAX_USER_MSG_SIZE) ||
+ (m->msg_iovlen > (unsigned)INT_MAX))
+ return -EMSGSIZE;
if (iocb)
lock_sock(sk);
@@ -573,12 +576,14 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
&dest->addr.name.name,
dest->addr.name.domain,
m->msg_iovlen,
- m->msg_iov);
+ m->msg_iov,
+ total_len);
} else if (dest->addrtype == TIPC_ADDR_ID) {
res = tipc_send2port(tport->ref,
&dest->addr.id,
m->msg_iovlen,
- m->msg_iov);
+ m->msg_iov,
+ total_len);
} else if (dest->addrtype == TIPC_ADDR_MCAST) {
if (needs_conn) {
res = -EOPNOTSUPP;
@@ -590,7 +595,8 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
res = tipc_multicast(tport->ref,
&dest->addr.nameseq,
m->msg_iovlen,
- m->msg_iov);
+ m->msg_iov,
+ total_len);
}
if (likely(res != -ELINKCONG)) {
if (needs_conn && (res >= 0))
@@ -640,6 +646,10 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
if (unlikely(dest))
return send_msg(iocb, sock, m, total_len);
+ if ((total_len > TIPC_MAX_USER_MSG_SIZE) ||
+ (m->msg_iovlen > (unsigned)INT_MAX))
+ return -EMSGSIZE;
+
if (iocb)
lock_sock(sk);
@@ -652,7 +662,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
break;
}
- res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov);
+ res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov,
+ total_len);
if (likely(res != -ELINKCONG))
break;
if (m->msg_flags & MSG_DONTWAIT) {
@@ -723,6 +734,12 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
goto exit;
}
+ if ((total_len > (unsigned)INT_MAX) ||
+ (m->msg_iovlen > (unsigned)INT_MAX)) {
+ res = -EMSGSIZE;
+ goto exit;
+ }
+
/*
* Send each iovec entry using one or more messages
*
@@ -753,7 +770,7 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
bytes_to_send = curr_left;
my_iov.iov_base = curr_start;
my_iov.iov_len = bytes_to_send;
- res = send_packet(NULL, sock, &my_msg, 0);
+ res = send_packet(NULL, sock, &my_msg, bytes_to_send);
if (res < 0) {
if (bytes_sent)
res = bytes_sent;
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index aae9eae1340..6cf72686348 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -109,7 +109,7 @@ static void subscr_send_event(struct subscription *sub,
sub->evt.found_upper = htohl(found_upper, sub->swap);
sub->evt.port.ref = htohl(port_ref, sub->swap);
sub->evt.port.node = htohl(node, sub->swap);
- tipc_send(sub->server_ref, 1, &msg_sect);
+ tipc_send(sub->server_ref, 1, &msg_sect, msg_sect.iov_len);
}
/**
@@ -521,7 +521,7 @@ static void subscr_named_msg_event(void *usr_handle,
/* Send an ACK- to complete connection handshaking */
- tipc_send(server_port_ref, 0, NULL);
+ tipc_send(server_port_ref, 0, NULL, 0);
/* Handle optional subscription request */
diff --git a/net/wireless/core.c b/net/wireless/core.c
index fe01de29bfe..c22ef3492ee 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -46,6 +46,11 @@ static struct dentry *ieee80211_debugfs_dir;
/* for the cleanup, scan and event works */
struct workqueue_struct *cfg80211_wq;
+static bool cfg80211_disable_40mhz_24ghz;
+module_param(cfg80211_disable_40mhz_24ghz, bool, 0644);
+MODULE_PARM_DESC(cfg80211_disable_40mhz_24ghz,
+ "Disable 40MHz support in the 2.4GHz band");
+
/* requires cfg80211_mutex to be held! */
struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx)
{
@@ -365,7 +370,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
spin_lock_init(&rdev->bss_lock);
INIT_LIST_HEAD(&rdev->bss_list);
INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
-
+ INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results);
#ifdef CONFIG_CFG80211_WEXT
rdev->wiphy.wext = &cfg80211_wext_handler;
#endif
@@ -411,6 +416,67 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
}
EXPORT_SYMBOL(wiphy_new);
+static int wiphy_verify_combinations(struct wiphy *wiphy)
+{
+ const struct ieee80211_iface_combination *c;
+ int i, j;
+
+ /* If we have combinations enforce them */
+ if (wiphy->n_iface_combinations)
+ wiphy->flags |= WIPHY_FLAG_ENFORCE_COMBINATIONS;
+
+ for (i = 0; i < wiphy->n_iface_combinations; i++) {
+ u32 cnt = 0;
+ u16 all_iftypes = 0;
+
+ c = &wiphy->iface_combinations[i];
+
+ /* Combinations with just one interface aren't real */
+ if (WARN_ON(c->max_interfaces < 2))
+ return -EINVAL;
+
+ /* Need at least one channel */
+ if (WARN_ON(!c->num_different_channels))
+ return -EINVAL;
+
+ if (WARN_ON(!c->n_limits))
+ return -EINVAL;
+
+ for (j = 0; j < c->n_limits; j++) {
+ u16 types = c->limits[j].types;
+
+ /*
+ * interface types shouldn't overlap, this is
+ * used in cfg80211_can_change_interface()
+ */
+ if (WARN_ON(types & all_iftypes))
+ return -EINVAL;
+ all_iftypes |= types;
+
+ if (WARN_ON(!c->limits[j].max))
+ return -EINVAL;
+
+ /* Shouldn't list software iftypes in combinations! */
+ if (WARN_ON(wiphy->software_iftypes & types))
+ return -EINVAL;
+
+ cnt += c->limits[j].max;
+ /*
+ * Don't advertise an unsupported type
+ * in a combination.
+ */
+ if (WARN_ON((wiphy->interface_modes & types) != types))
+ return -EINVAL;
+ }
+
+ /* You can't even choose that many! */
+ if (WARN_ON(cnt < c->max_interfaces))
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
int wiphy_register(struct wiphy *wiphy)
{
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
@@ -439,6 +505,10 @@ int wiphy_register(struct wiphy *wiphy)
if (WARN_ON(ifmodes != wiphy->interface_modes))
wiphy->interface_modes = ifmodes;
+ res = wiphy_verify_combinations(wiphy);
+ if (res)
+ return res;
+
/* sanity check supported bands/channels */
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
sband = wiphy->bands[band];
@@ -451,6 +521,18 @@ int wiphy_register(struct wiphy *wiphy)
return -EINVAL;
/*
+ * Since cfg80211_disable_40mhz_24ghz is global, we can
+ * modify the sband's ht data even if the driver uses a
+ * global structure for that.
+ */
+ if (cfg80211_disable_40mhz_24ghz &&
+ band == IEEE80211_BAND_2GHZ &&
+ sband->ht_cap.ht_supported) {
+ sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
+ }
+
+ /*
* Since we use a u32 for rate bitmaps in
* ieee80211_get_response_rate, we cannot
* have more than 32 legacy rates.
@@ -476,6 +558,13 @@ int wiphy_register(struct wiphy *wiphy)
return -EINVAL;
}
+ if (rdev->wiphy.wowlan.n_patterns) {
+ if (WARN_ON(!rdev->wiphy.wowlan.pattern_min_len ||
+ rdev->wiphy.wowlan.pattern_min_len >
+ rdev->wiphy.wowlan.pattern_max_len))
+ return -EINVAL;
+ }
+
/* check and set up bitrates */
ieee80211_set_bitrate_flags(wiphy);
@@ -614,6 +703,7 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
mutex_destroy(&rdev->devlist_mtx);
list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
cfg80211_put_bss(&scan->pub);
+ cfg80211_rdev_free_wowlan(rdev);
kfree(rdev);
}
@@ -647,6 +737,11 @@ static void wdev_cleanup_work(struct work_struct *work)
___cfg80211_scan_done(rdev, true);
}
+ if (WARN_ON(rdev->sched_scan_req &&
+ rdev->sched_scan_req->dev == wdev->netdev)) {
+ __cfg80211_stop_sched_scan(rdev, false);
+ }
+
cfg80211_unlock_rdev(rdev);
mutex_lock(&rdev->devlist_mtx);
@@ -668,6 +763,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
struct net_device *dev = ndev;
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_registered_device *rdev;
+ int ret;
if (!wdev)
return NOTIFY_DONE;
@@ -734,6 +830,10 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
break;
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION:
+ cfg80211_lock_rdev(rdev);
+ __cfg80211_stop_sched_scan(rdev, false);
+ cfg80211_unlock_rdev(rdev);
+
wdev_lock(wdev);
#ifdef CONFIG_CFG80211_WEXT
kfree(wdev->wext.ie);
@@ -752,6 +852,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
default:
break;
}
+ wdev->beacon_interval = 0;
break;
case NETDEV_DOWN:
dev_hold(dev);
@@ -858,6 +959,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
return notifier_from_errno(-EOPNOTSUPP);
if (rfkill_blocked(rdev->rfkill))
return notifier_from_errno(-ERFKILL);
+ ret = cfg80211_can_add_interface(rdev, wdev->iftype);
+ if (ret)
+ return notifier_from_errno(ret);
break;
}
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 26a0a084e16..bf0fb40e3c8 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -60,8 +60,10 @@ struct cfg80211_registered_device {
struct rb_root bss_tree;
u32 bss_generation;
struct cfg80211_scan_request *scan_req; /* protected by RTNL */
+ struct cfg80211_sched_scan_request *sched_scan_req;
unsigned long suspend_at;
struct work_struct scan_done_wk;
+ struct work_struct sched_scan_results_wk;
#ifdef CONFIG_NL80211_TESTMODE
struct genl_info *testmode_info;
@@ -70,6 +72,8 @@ struct cfg80211_registered_device {
struct work_struct conn_work;
struct work_struct event_work;
+ struct cfg80211_wowlan *wowlan;
+
/* must be last because of the way we do wiphy_priv(),
* and it should at least be aligned to NETDEV_ALIGN */
struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
@@ -89,6 +93,18 @@ bool wiphy_idx_valid(int wiphy_idx)
return wiphy_idx >= 0;
}
+static inline void
+cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev)
+{
+ int i;
+
+ if (!rdev->wowlan)
+ return;
+ for (i = 0; i < rdev->wowlan->n_patterns; i++)
+ kfree(rdev->wowlan->patterns[i].mask);
+ kfree(rdev->wowlan->patterns);
+ kfree(rdev->wowlan);
+}
extern struct workqueue_struct *cfg80211_wq;
extern struct mutex cfg80211_mutex;
@@ -397,12 +413,26 @@ void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
void cfg80211_sme_disassoc(struct net_device *dev, int idx);
void __cfg80211_scan_done(struct work_struct *wk);
void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak);
+void __cfg80211_sched_scan_results(struct work_struct *wk);
+int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
+ bool driver_initiated);
void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
struct net_device *dev, enum nl80211_iftype ntype,
u32 *flags, struct vif_params *params);
void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
+int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev,
+ enum nl80211_iftype iftype);
+
+static inline int
+cfg80211_can_add_interface(struct cfg80211_registered_device *rdev,
+ enum nl80211_iftype iftype)
+{
+ return cfg80211_can_change_interface(rdev, NULL, iftype);
+}
+
struct ieee80211_channel *
rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
int freq, enum nl80211_channel_type channel_type);
@@ -412,6 +442,9 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
u16 cfg80211_calculate_bitrate(struct rate_info *rate);
+int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
+ u32 beacon_int);
+
#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond)
#else
diff --git a/net/wireless/lib80211_crypt_wep.c b/net/wireless/lib80211_crypt_wep.c
index e2e88878ba3..2f265e033ae 100644
--- a/net/wireless/lib80211_crypt_wep.c
+++ b/net/wireless/lib80211_crypt_wep.c
@@ -96,13 +96,12 @@ static int lib80211_wep_build_iv(struct sk_buff *skb, int hdr_len,
u8 *key, int keylen, void *priv)
{
struct lib80211_wep_data *wep = priv;
- u32 klen, len;
+ u32 klen;
u8 *pos;
if (skb_headroom(skb) < 4 || skb->len < hdr_len)
return -1;
- len = skb->len - hdr_len;
pos = skb_push(skb, 4);
memmove(pos, pos + 4, hdr_len);
pos += hdr_len;
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 73e39c171ff..5c116083eec 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -1,5 +1,6 @@
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
+#include "nl80211.h"
#include "core.h"
/* Default values, timeouts in ms */
@@ -53,8 +54,9 @@ const struct mesh_config default_mesh_config = {
const struct mesh_setup default_mesh_setup = {
.path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
.path_metric = IEEE80211_PATH_METRIC_AIRTIME,
- .vendor_ie = NULL,
- .vendor_ie_len = 0,
+ .ie = NULL,
+ .ie_len = 0,
+ .is_secure = false,
};
int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
@@ -72,6 +74,10 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
return -EOPNOTSUPP;
+ if (!(rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
+ setup->is_secure)
+ return -EOPNOTSUPP;
+
if (wdev->mesh_id_len)
return -EALREADY;
@@ -105,6 +111,19 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
return err;
}
+void cfg80211_notify_new_peer_candidate(struct net_device *dev,
+ const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
+ return;
+
+ nl80211_send_new_peer_candidate(wiphy_to_dev(wdev->wiphy), dev,
+ macaddr, ie, ie_len, gfp);
+}
+EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
+
static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
struct net_device *dev)
{
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index aa5df8865ff..493b939970c 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -770,6 +770,15 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
}
EXPORT_SYMBOL(cfg80211_new_sta);
+void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp)
+{
+ struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+ nl80211_send_sta_del_event(rdev, dev, mac_addr, gfp);
+}
+EXPORT_SYMBOL(cfg80211_del_sta);
+
struct cfg80211_mgmt_registration {
struct list_head list;
@@ -954,6 +963,16 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN))
err = -EINVAL;
break;
+ case NL80211_IFTYPE_MESH_POINT:
+ if (memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN)) {
+ err = -EINVAL;
+ break;
+ }
+ /*
+ * check for mesh DA must be done by driver as
+ * cfg80211 doesn't track the stations
+ */
+ break;
default:
err = -EOPNOTSUPP;
break;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4ebce4284e9..2222ce08ee9 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -124,6 +124,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
[NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
+ [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
[NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
.len = NL80211_HT_CAPABILITY_LEN },
@@ -172,6 +173,9 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
[NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
[NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
+ [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
+ [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
+ [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
};
/* policy for the key attributes */
@@ -193,6 +197,15 @@ nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
[NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
};
+/* policy for WoWLAN attributes */
+static const struct nla_policy
+nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
+ [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
+ [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
+ [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
+ [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
+};
+
/* ifidx get helper */
static int nl80211_get_ifidx(struct netlink_callback *cb)
{
@@ -533,6 +546,7 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_P2P_GO:
+ case NL80211_IFTYPE_MESH_POINT:
break;
case NL80211_IFTYPE_ADHOC:
if (!wdev->current_bss)
@@ -550,6 +564,88 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
return 0;
}
+static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
+{
+ struct nlattr *nl_modes = nla_nest_start(msg, attr);
+ int i;
+
+ if (!nl_modes)
+ goto nla_put_failure;
+
+ i = 0;
+ while (ifmodes) {
+ if (ifmodes & 1)
+ NLA_PUT_FLAG(msg, i);
+ ifmodes >>= 1;
+ i++;
+ }
+
+ nla_nest_end(msg, nl_modes);
+ return 0;
+
+nla_put_failure:
+ return -ENOBUFS;
+}
+
+static int nl80211_put_iface_combinations(struct wiphy *wiphy,
+ struct sk_buff *msg)
+{
+ struct nlattr *nl_combis;
+ int i, j;
+
+ nl_combis = nla_nest_start(msg,
+ NL80211_ATTR_INTERFACE_COMBINATIONS);
+ if (!nl_combis)
+ goto nla_put_failure;
+
+ for (i = 0; i < wiphy->n_iface_combinations; i++) {
+ const struct ieee80211_iface_combination *c;
+ struct nlattr *nl_combi, *nl_limits;
+
+ c = &wiphy->iface_combinations[i];
+
+ nl_combi = nla_nest_start(msg, i + 1);
+ if (!nl_combi)
+ goto nla_put_failure;
+
+ nl_limits = nla_nest_start(msg, NL80211_IFACE_COMB_LIMITS);
+ if (!nl_limits)
+ goto nla_put_failure;
+
+ for (j = 0; j < c->n_limits; j++) {
+ struct nlattr *nl_limit;
+
+ nl_limit = nla_nest_start(msg, j + 1);
+ if (!nl_limit)
+ goto nla_put_failure;
+ NLA_PUT_U32(msg, NL80211_IFACE_LIMIT_MAX,
+ c->limits[j].max);
+ if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
+ c->limits[j].types))
+ goto nla_put_failure;
+ nla_nest_end(msg, nl_limit);
+ }
+
+ nla_nest_end(msg, nl_limits);
+
+ if (c->beacon_int_infra_match)
+ NLA_PUT_FLAG(msg,
+ NL80211_IFACE_COMB_STA_AP_BI_MATCH);
+ NLA_PUT_U32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
+ c->num_different_channels);
+ NLA_PUT_U32(msg, NL80211_IFACE_COMB_MAXNUM,
+ c->max_interfaces);
+
+ nla_nest_end(msg, nl_combi);
+ }
+
+ nla_nest_end(msg, nl_combis);
+
+ return 0;
+nla_put_failure:
+ return -ENOBUFS;
+}
+
static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
struct cfg80211_registered_device *dev)
{
@@ -557,13 +653,11 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
struct nlattr *nl_bands, *nl_band;
struct nlattr *nl_freqs, *nl_freq;
struct nlattr *nl_rates, *nl_rate;
- struct nlattr *nl_modes;
struct nlattr *nl_cmds;
enum ieee80211_band band;
struct ieee80211_channel *chan;
struct ieee80211_rate *rate;
int i;
- u16 ifmodes = dev->wiphy.interface_modes;
const struct ieee80211_txrx_stypes *mgmt_stypes =
dev->wiphy.mgmt_stypes;
@@ -594,6 +688,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)
NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
+ if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH)
+ NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH);
NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
sizeof(u32) * dev->wiphy.n_cipher_suites,
@@ -621,20 +717,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
}
}
- nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
- if (!nl_modes)
+ if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
+ dev->wiphy.interface_modes))
goto nla_put_failure;
- i = 0;
- while (ifmodes) {
- if (ifmodes & 1)
- NLA_PUT_FLAG(msg, i);
- ifmodes >>= 1;
- i++;
- }
-
- nla_nest_end(msg, nl_modes);
-
nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
if (!nl_bands)
goto nla_put_failure;
@@ -746,6 +832,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
}
CMD(set_channel, SET_CHANNEL);
CMD(set_wds_peer, SET_WDS_PEER);
+ if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
+ CMD(sched_scan_start, START_SCHED_SCAN);
#undef CMD
@@ -818,6 +906,42 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
nla_nest_end(msg, nl_ifs);
}
+ if (dev->wiphy.wowlan.flags || dev->wiphy.wowlan.n_patterns) {
+ struct nlattr *nl_wowlan;
+
+ nl_wowlan = nla_nest_start(msg,
+ NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
+ if (!nl_wowlan)
+ goto nla_put_failure;
+
+ if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY)
+ NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY);
+ if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT)
+ NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
+ if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT)
+ NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
+ if (dev->wiphy.wowlan.n_patterns) {
+ struct nl80211_wowlan_pattern_support pat = {
+ .max_patterns = dev->wiphy.wowlan.n_patterns,
+ .min_pattern_len =
+ dev->wiphy.wowlan.pattern_min_len,
+ .max_pattern_len =
+ dev->wiphy.wowlan.pattern_max_len,
+ };
+ NLA_PUT(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
+ sizeof(pat), &pat);
+ }
+
+ nla_nest_end(msg, nl_wowlan);
+ }
+
+ if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
+ dev->wiphy.software_iftypes))
+ goto nla_put_failure;
+
+ if (nl80211_put_iface_combinations(&dev->wiphy, msg))
+ goto nla_put_failure;
+
return genlmsg_end(msg, hdr);
nla_put_failure:
@@ -1679,14 +1803,6 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
if (err)
goto out;
- if (!(rdev->wiphy.flags &
- WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS)) {
- if (!key.def_uni || !key.def_multi) {
- err = -EOPNOTSUPP;
- goto out;
- }
- }
-
err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx,
key.def_uni, key.def_multi);
@@ -1837,8 +1953,9 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
struct beacon_parameters *info);
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
struct beacon_parameters params;
- int haveinfo = 0;
+ int haveinfo = 0, err;
if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
return -EINVAL;
@@ -1847,6 +1964,8 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
return -EOPNOTSUPP;
+ memset(&params, 0, sizeof(params));
+
switch (info->genlhdr->cmd) {
case NL80211_CMD_NEW_BEACON:
/* these are required for NEW_BEACON */
@@ -1855,6 +1974,15 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
!info->attrs[NL80211_ATTR_BEACON_HEAD])
return -EINVAL;
+ params.interval =
+ nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
+ params.dtim_period =
+ nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
+
+ err = cfg80211_validate_beacon_int(rdev, params.interval);
+ if (err)
+ return err;
+
call = rdev->ops->add_beacon;
break;
case NL80211_CMD_SET_BEACON:
@@ -1868,20 +1996,6 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
if (!call)
return -EOPNOTSUPP;
- 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 =
@@ -1899,13 +2013,18 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
if (!haveinfo)
return -EINVAL;
- return call(&rdev->wiphy, dev, &params);
+ err = call(&rdev->wiphy, dev, &params);
+ if (!err && params.interval)
+ wdev->beacon_interval = params.interval;
+ return err;
}
static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ int err;
if (!rdev->ops->del_beacon)
return -EOPNOTSUPP;
@@ -1914,7 +2033,10 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
return -EOPNOTSUPP;
- return rdev->ops->del_beacon(&rdev->wiphy, dev);
+ err = rdev->ops->del_beacon(&rdev->wiphy, dev);
+ if (!err)
+ wdev->beacon_interval = 0;
+ return err;
}
static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
@@ -1922,6 +2044,7 @@ static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
[NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
[NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
[NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
+ [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
};
static int parse_station_flags(struct genl_info *info,
@@ -2002,7 +2125,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
const u8 *mac_addr, struct station_info *sinfo)
{
void *hdr;
- struct nlattr *sinfoattr;
+ struct nlattr *sinfoattr, *bss_param;
hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
if (!hdr)
@@ -2016,6 +2139,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
if (!sinfoattr)
goto nla_put_failure;
+ if (sinfo->filled & STATION_INFO_CONNECTED_TIME)
+ NLA_PUT_U32(msg, NL80211_STA_INFO_CONNECTED_TIME,
+ sinfo->connected_time);
if (sinfo->filled & STATION_INFO_INACTIVE_TIME)
NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME,
sinfo->inactive_time);
@@ -2062,6 +2188,25 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_TX_FAILED)
NLA_PUT_U32(msg, NL80211_STA_INFO_TX_FAILED,
sinfo->tx_failed);
+ if (sinfo->filled & STATION_INFO_BSS_PARAM) {
+ bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
+ if (!bss_param)
+ goto nla_put_failure;
+
+ if (sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT)
+ NLA_PUT_FLAG(msg, NL80211_STA_BSS_PARAM_CTS_PROT);
+ if (sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE)
+ NLA_PUT_FLAG(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE);
+ if (sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME)
+ NLA_PUT_FLAG(msg,
+ NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME);
+ NLA_PUT_U8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
+ sinfo->bss_param.dtim_period);
+ NLA_PUT_U16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
+ sinfo->bss_param.beacon_interval);
+
+ nla_nest_end(msg, bss_param);
+ }
nla_nest_end(msg, sinfoattr);
return genlmsg_end(msg, hdr);
@@ -2190,6 +2335,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
memset(&params, 0, sizeof(params));
params.listen_interval = -1;
+ params.plink_state = -1;
if (info->attrs[NL80211_ATTR_STA_AID])
return -EINVAL;
@@ -2221,6 +2367,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
params.plink_action =
nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
+ if (info->attrs[NL80211_ATTR_STA_PLINK_STATE])
+ params.plink_state =
+ nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
+
err = get_vlan(info, rdev, &params.vlan);
if (err)
goto out;
@@ -2260,9 +2410,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
err = -EINVAL;
if (params.listen_interval >= 0)
err = -EINVAL;
- if (params.supported_rates)
- err = -EINVAL;
- if (params.sta_flags_mask)
+ if (params.sta_flags_mask &
+ ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
+ BIT(NL80211_STA_FLAG_MFP) |
+ BIT(NL80211_STA_FLAG_AUTHORIZED)))
err = -EINVAL;
break;
default:
@@ -2324,11 +2475,16 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
params.ht_capa =
nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
+ if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
+ params.plink_action =
+ nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
+
if (parse_station_flags(info, &params))
return -EINVAL;
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
return -EINVAL;
@@ -2804,8 +2960,10 @@ static const struct nla_policy
nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
- [NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE] = { .type = NLA_BINARY,
+ [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
+ [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_DATA_LEN },
+ [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
};
static int nl80211_parse_mesh_config(struct genl_info *info,
@@ -2906,14 +3064,17 @@ static int nl80211_parse_mesh_setup(struct genl_info *info,
IEEE80211_PATH_METRIC_VENDOR :
IEEE80211_PATH_METRIC_AIRTIME;
- if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) {
+
+ if (tb[NL80211_MESH_SETUP_IE]) {
struct nlattr *ieattr =
- tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE];
+ tb[NL80211_MESH_SETUP_IE];
if (!is_valid_ie_attr(ieattr))
return -EINVAL;
- setup->vendor_ie = nla_data(ieattr);
- setup->vendor_ie_len = nla_len(ieattr);
+ setup->ie = nla_data(ieattr);
+ setup->ie_len = nla_len(ieattr);
}
+ setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
+ setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
return 0;
}
@@ -3282,6 +3443,188 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
return err;
}
+static int nl80211_start_sched_scan(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct cfg80211_sched_scan_request *request;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ struct cfg80211_ssid *ssid;
+ struct ieee80211_channel *channel;
+ struct nlattr *attr;
+ struct wiphy *wiphy;
+ int err, tmp, n_ssids = 0, n_channels, i;
+ u32 interval;
+ enum ieee80211_band band;
+ size_t ie_len;
+
+ if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
+ !rdev->ops->sched_scan_start)
+ return -EOPNOTSUPP;
+
+ if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+ return -EINVAL;
+
+ if (rdev->sched_scan_req)
+ return -EINPROGRESS;
+
+ if (!info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
+ return -EINVAL;
+
+ interval = nla_get_u32(info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
+ if (interval == 0)
+ return -EINVAL;
+
+ wiphy = &rdev->wiphy;
+
+ if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
+ n_channels = validate_scan_freqs(
+ info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
+ if (!n_channels)
+ return -EINVAL;
+ } else {
+ n_channels = 0;
+
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++)
+ if (wiphy->bands[band])
+ n_channels += wiphy->bands[band]->n_channels;
+ }
+
+ if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
+ nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS],
+ tmp)
+ n_ssids++;
+
+ if (n_ssids > wiphy->max_scan_ssids)
+ return -EINVAL;
+
+ if (info->attrs[NL80211_ATTR_IE])
+ ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+ else
+ ie_len = 0;
+
+ if (ie_len > wiphy->max_scan_ie_len)
+ return -EINVAL;
+
+ request = kzalloc(sizeof(*request)
+ + sizeof(*ssid) * n_ssids
+ + sizeof(channel) * n_channels
+ + ie_len, GFP_KERNEL);
+ if (!request)
+ return -ENOMEM;
+
+ if (n_ssids)
+ request->ssids = (void *)&request->channels[n_channels];
+ request->n_ssids = n_ssids;
+ if (ie_len) {
+ if (request->ssids)
+ request->ie = (void *)(request->ssids + n_ssids);
+ else
+ request->ie = (void *)(request->channels + n_channels);
+ }
+
+ i = 0;
+ if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
+ /* user specified, bail out if channel not found */
+ nla_for_each_nested(attr,
+ info->attrs[NL80211_ATTR_SCAN_FREQUENCIES],
+ tmp) {
+ struct ieee80211_channel *chan;
+
+ chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
+
+ if (!chan) {
+ err = -EINVAL;
+ goto out_free;
+ }
+
+ /* ignore disabled channels */
+ if (chan->flags & IEEE80211_CHAN_DISABLED)
+ continue;
+
+ request->channels[i] = chan;
+ i++;
+ }
+ } else {
+ /* all channels */
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ int j;
+ if (!wiphy->bands[band])
+ continue;
+ for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
+ struct ieee80211_channel *chan;
+
+ chan = &wiphy->bands[band]->channels[j];
+
+ if (chan->flags & IEEE80211_CHAN_DISABLED)
+ continue;
+
+ request->channels[i] = chan;
+ i++;
+ }
+ }
+ }
+
+ if (!i) {
+ err = -EINVAL;
+ goto out_free;
+ }
+
+ request->n_channels = i;
+
+ i = 0;
+ if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
+ nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS],
+ tmp) {
+ if (request->ssids[i].ssid_len >
+ IEEE80211_MAX_SSID_LEN) {
+ err = -EINVAL;
+ goto out_free;
+ }
+ memcpy(request->ssids[i].ssid, nla_data(attr),
+ nla_len(attr));
+ request->ssids[i].ssid_len = nla_len(attr);
+ i++;
+ }
+ }
+
+ if (info->attrs[NL80211_ATTR_IE]) {
+ request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+ memcpy((void *)request->ie,
+ nla_data(info->attrs[NL80211_ATTR_IE]),
+ request->ie_len);
+ }
+
+ request->dev = dev;
+ request->wiphy = &rdev->wiphy;
+ request->interval = interval;
+
+ err = rdev->ops->sched_scan_start(&rdev->wiphy, dev, request);
+ if (!err) {
+ rdev->sched_scan_req = request;
+ nl80211_send_sched_scan(rdev, dev,
+ NL80211_CMD_START_SCHED_SCAN);
+ goto out;
+ }
+
+out_free:
+ kfree(request);
+out:
+ return err;
+}
+
+static int nl80211_stop_sched_scan(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+
+ if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
+ !rdev->ops->sched_scan_stop)
+ return -EOPNOTSUPP;
+
+ return __cfg80211_stop_sched_scan(rdev, false);
+}
+
static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev,
@@ -4780,6 +5123,194 @@ static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
return cfg80211_leave_mesh(rdev, dev);
}
+static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct sk_buff *msg;
+ void *hdr;
+
+ if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns)
+ return -EOPNOTSUPP;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+ NL80211_CMD_GET_WOWLAN);
+ if (!hdr)
+ goto nla_put_failure;
+
+ if (rdev->wowlan) {
+ struct nlattr *nl_wowlan;
+
+ nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
+ if (!nl_wowlan)
+ goto nla_put_failure;
+
+ if (rdev->wowlan->any)
+ NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY);
+ if (rdev->wowlan->disconnect)
+ NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
+ if (rdev->wowlan->magic_pkt)
+ NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
+ if (rdev->wowlan->n_patterns) {
+ struct nlattr *nl_pats, *nl_pat;
+ int i, pat_len;
+
+ nl_pats = nla_nest_start(msg,
+ NL80211_WOWLAN_TRIG_PKT_PATTERN);
+ if (!nl_pats)
+ goto nla_put_failure;
+
+ for (i = 0; i < rdev->wowlan->n_patterns; i++) {
+ nl_pat = nla_nest_start(msg, i + 1);
+ if (!nl_pat)
+ goto nla_put_failure;
+ pat_len = rdev->wowlan->patterns[i].pattern_len;
+ NLA_PUT(msg, NL80211_WOWLAN_PKTPAT_MASK,
+ DIV_ROUND_UP(pat_len, 8),
+ rdev->wowlan->patterns[i].mask);
+ NLA_PUT(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
+ pat_len,
+ rdev->wowlan->patterns[i].pattern);
+ nla_nest_end(msg, nl_pat);
+ }
+ nla_nest_end(msg, nl_pats);
+ }
+
+ nla_nest_end(msg, nl_wowlan);
+ }
+
+ genlmsg_end(msg, hdr);
+ return genlmsg_reply(msg, info);
+
+nla_put_failure:
+ nlmsg_free(msg);
+ return -ENOBUFS;
+}
+
+static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
+ struct cfg80211_wowlan no_triggers = {};
+ struct cfg80211_wowlan new_triggers = {};
+ struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan;
+ int err, i;
+
+ if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns)
+ return -EOPNOTSUPP;
+
+ if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS])
+ goto no_triggers;
+
+ err = nla_parse(tb, MAX_NL80211_WOWLAN_TRIG,
+ nla_data(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
+ nla_len(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
+ nl80211_wowlan_policy);
+ if (err)
+ return err;
+
+ if (tb[NL80211_WOWLAN_TRIG_ANY]) {
+ if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
+ return -EINVAL;
+ new_triggers.any = true;
+ }
+
+ if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
+ if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
+ return -EINVAL;
+ new_triggers.disconnect = true;
+ }
+
+ if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
+ if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
+ return -EINVAL;
+ new_triggers.magic_pkt = true;
+ }
+
+ if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
+ struct nlattr *pat;
+ int n_patterns = 0;
+ int rem, pat_len, mask_len;
+ struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT];
+
+ nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
+ rem)
+ n_patterns++;
+ if (n_patterns > wowlan->n_patterns)
+ return -EINVAL;
+
+ new_triggers.patterns = kcalloc(n_patterns,
+ sizeof(new_triggers.patterns[0]),
+ GFP_KERNEL);
+ if (!new_triggers.patterns)
+ return -ENOMEM;
+
+ new_triggers.n_patterns = n_patterns;
+ i = 0;
+
+ nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
+ rem) {
+ nla_parse(pat_tb, MAX_NL80211_WOWLAN_PKTPAT,
+ nla_data(pat), nla_len(pat), NULL);
+ err = -EINVAL;
+ if (!pat_tb[NL80211_WOWLAN_PKTPAT_MASK] ||
+ !pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN])
+ goto error;
+ pat_len = nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]);
+ mask_len = DIV_ROUND_UP(pat_len, 8);
+ if (nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]) !=
+ mask_len)
+ goto error;
+ if (pat_len > wowlan->pattern_max_len ||
+ pat_len < wowlan->pattern_min_len)
+ goto error;
+
+ new_triggers.patterns[i].mask =
+ kmalloc(mask_len + pat_len, GFP_KERNEL);
+ if (!new_triggers.patterns[i].mask) {
+ err = -ENOMEM;
+ goto error;
+ }
+ new_triggers.patterns[i].pattern =
+ new_triggers.patterns[i].mask + mask_len;
+ memcpy(new_triggers.patterns[i].mask,
+ nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]),
+ mask_len);
+ new_triggers.patterns[i].pattern_len = pat_len;
+ memcpy(new_triggers.patterns[i].pattern,
+ nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]),
+ pat_len);
+ i++;
+ }
+ }
+
+ if (memcmp(&new_triggers, &no_triggers, sizeof(new_triggers))) {
+ struct cfg80211_wowlan *ntrig;
+ ntrig = kmemdup(&new_triggers, sizeof(new_triggers),
+ GFP_KERNEL);
+ if (!ntrig) {
+ err = -ENOMEM;
+ goto error;
+ }
+ cfg80211_rdev_free_wowlan(rdev);
+ rdev->wowlan = ntrig;
+ } else {
+ no_triggers:
+ cfg80211_rdev_free_wowlan(rdev);
+ rdev->wowlan = NULL;
+ }
+
+ return 0;
+ error:
+ for (i = 0; i < new_triggers.n_patterns; i++)
+ kfree(new_triggers.patterns[i].mask);
+ kfree(new_triggers.patterns);
+ return err;
+}
+
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
@@ -5064,6 +5595,22 @@ static struct genl_ops nl80211_ops[] = {
.dumpit = nl80211_dump_scan,
},
{
+ .cmd = NL80211_CMD_START_SCHED_SCAN,
+ .doit = nl80211_start_sched_scan,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
+ {
+ .cmd = NL80211_CMD_STOP_SCHED_SCAN,
+ .doit = nl80211_stop_sched_scan,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
+ {
.cmd = NL80211_CMD_AUTHENTICATE,
.doit = nl80211_authenticate,
.policy = nl80211_policy,
@@ -5278,6 +5825,22 @@ static struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
+ {
+ .cmd = NL80211_CMD_GET_WOWLAN,
+ .doit = nl80211_get_wowlan,
+ .policy = nl80211_policy,
+ /* can be retrieved by unprivileged users */
+ .internal_flags = NL80211_FLAG_NEED_WIPHY |
+ NL80211_FLAG_NEED_RTNL,
+ },
+ {
+ .cmd = NL80211_CMD_SET_WOWLAN,
+ .doit = nl80211_set_wowlan,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_WIPHY |
+ NL80211_FLAG_NEED_RTNL,
+ },
};
static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -5373,6 +5936,28 @@ static int nl80211_send_scan_msg(struct sk_buff *msg,
return -EMSGSIZE;
}
+static int
+nl80211_send_sched_scan_msg(struct sk_buff *msg,
+ struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ u32 pid, u32 seq, int flags, u32 cmd)
+{
+ void *hdr;
+
+ hdr = nl80211hdr_put(msg, pid, seq, flags, cmd);
+ if (!hdr)
+ return -1;
+
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+
+ return genlmsg_end(msg, hdr);
+
+ nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ return -EMSGSIZE;
+}
+
void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
struct net_device *netdev)
{
@@ -5430,6 +6015,43 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
nl80211_scan_mcgrp.id, GFP_KERNEL);
}
+void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev)
+{
+ struct sk_buff *msg;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return;
+
+ if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0,
+ NL80211_CMD_SCHED_SCAN_RESULTS) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+ nl80211_scan_mcgrp.id, GFP_KERNEL);
+}
+
+void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, u32 cmd)
+{
+ struct sk_buff *msg;
+
+ msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (!msg)
+ return;
+
+ if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+ nl80211_scan_mcgrp.id, GFP_KERNEL);
+}
+
/*
* This can happen on global regulatory changes or device specific settings
* based on custom world regulatory domains.
@@ -5785,6 +6407,44 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
nlmsg_free(msg);
}
+void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ const u8 *macaddr, const u8* ie, u8 ie_len,
+ gfp_t gfp)
+{
+ struct sk_buff *msg;
+ void *hdr;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr);
+ if (ie_len && ie)
+ NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie);
+
+ if (genlmsg_end(msg, hdr) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+ nl80211_mlme_mcgrp.id, gfp);
+ return;
+
+ nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+}
+
void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
struct net_device *netdev, const u8 *addr,
enum nl80211_key_type key_type, int key_id,
@@ -5966,6 +6626,40 @@ void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
nl80211_mlme_mcgrp.id, gfp);
}
+void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, const u8 *mac_addr,
+ gfp_t gfp)
+{
+ struct sk_buff *msg;
+ void *hdr;
+
+ msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_STATION);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
+
+ if (genlmsg_end(msg, hdr) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+ nl80211_mlme_mcgrp.id, gfp);
+ return;
+
+ nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+}
+
int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u32 nlpid,
int freq, const u8 *buf, size_t len, gfp_t gfp)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index e3f7fa88696..2f1bfb87a65 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -12,6 +12,10 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
struct net_device *netdev);
void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
struct net_device *netdev);
+void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, u32 cmd);
+void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev);
void nl80211_send_reg_change_event(struct regulatory_request *request);
void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
@@ -50,6 +54,10 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u16 reason,
const u8 *ie, size_t ie_len, bool from_ap);
+void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ const u8 *macaddr, const u8* ie, u8 ie_len,
+ gfp_t gfp);
void
nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
struct net_device *netdev, const u8 *addr,
@@ -79,6 +87,9 @@ void nl80211_send_remain_on_channel_cancel(
void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *mac_addr,
struct station_info *sinfo, gfp_t gfp);
+void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, const u8 *mac_addr,
+ gfp_t gfp);
int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u32 nlpid, int freq,
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index ab801a1097b..1ad0f39fe09 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -106,6 +106,9 @@ struct reg_beacon {
static void reg_todo(struct work_struct *work);
static DECLARE_WORK(reg_work, reg_todo);
+static void reg_timeout_work(struct work_struct *work);
+static DECLARE_DELAYED_WORK(reg_timeout, reg_timeout_work);
+
/* We keep a static world regulatory domain in case of the absence of CRDA */
static const struct ieee80211_regdomain world_regdom = {
.n_reg_rules = 5,
@@ -669,11 +672,9 @@ static int freq_reg_info_regd(struct wiphy *wiphy,
for (i = 0; i < regd->n_reg_rules; i++) {
const struct ieee80211_reg_rule *rr;
const struct ieee80211_freq_range *fr = NULL;
- const struct ieee80211_power_rule *pr = NULL;
rr = &regd->reg_rules[i];
fr = &rr->freq_range;
- pr = &rr->power_rule;
/*
* We only need to know if one frequency rule was
@@ -1330,6 +1331,9 @@ static void reg_set_request_processed(void)
need_more_processing = true;
spin_unlock(&reg_requests_lock);
+ if (last_request->initiator == NL80211_REGDOM_SET_BY_USER)
+ cancel_delayed_work_sync(&reg_timeout);
+
if (need_more_processing)
schedule_work(&reg_work);
}
@@ -1440,8 +1444,18 @@ static void reg_process_hint(struct regulatory_request *reg_request)
r = __regulatory_hint(wiphy, reg_request);
/* This is required so that the orig_* parameters are saved */
if (r == -EALREADY && wiphy &&
- wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY)
+ wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) {
wiphy_update_regulatory(wiphy, initiator);
+ return;
+ }
+
+ /*
+ * We only time out user hints, given that they should be the only
+ * source of bogus requests.
+ */
+ if (r != -EALREADY &&
+ reg_request->initiator == NL80211_REGDOM_SET_BY_USER)
+ schedule_delayed_work(&reg_timeout, msecs_to_jiffies(3142));
}
/*
@@ -1744,6 +1758,8 @@ static void restore_regulatory_settings(bool reset_user)
{
char alpha2[2];
struct reg_beacon *reg_beacon, *btmp;
+ struct regulatory_request *reg_request, *tmp;
+ LIST_HEAD(tmp_reg_req_list);
mutex_lock(&cfg80211_mutex);
mutex_lock(&reg_mutex);
@@ -1751,6 +1767,25 @@ static void restore_regulatory_settings(bool reset_user)
reset_regdomains();
restore_alpha2(alpha2, reset_user);
+ /*
+ * If there's any pending requests we simply
+ * stash them to a temporary pending queue and
+ * add then after we've restored regulatory
+ * settings.
+ */
+ spin_lock(&reg_requests_lock);
+ if (!list_empty(&reg_requests_list)) {
+ list_for_each_entry_safe(reg_request, tmp,
+ &reg_requests_list, list) {
+ if (reg_request->initiator !=
+ NL80211_REGDOM_SET_BY_USER)
+ continue;
+ list_del(&reg_request->list);
+ list_add_tail(&reg_request->list, &tmp_reg_req_list);
+ }
+ }
+ spin_unlock(&reg_requests_lock);
+
/* Clear beacon hints */
spin_lock_bh(&reg_pending_beacons_lock);
if (!list_empty(&reg_pending_beacons)) {
@@ -1785,8 +1820,31 @@ static void restore_regulatory_settings(bool reset_user)
*/
if (is_an_alpha2(alpha2))
regulatory_hint_user(user_alpha2);
-}
+ if (list_empty(&tmp_reg_req_list))
+ return;
+
+ mutex_lock(&cfg80211_mutex);
+ mutex_lock(&reg_mutex);
+
+ spin_lock(&reg_requests_lock);
+ list_for_each_entry_safe(reg_request, tmp, &tmp_reg_req_list, list) {
+ REG_DBG_PRINT("Adding request for country %c%c back "
+ "into the queue\n",
+ reg_request->alpha2[0],
+ reg_request->alpha2[1]);
+ list_del(&reg_request->list);
+ list_add_tail(&reg_request->list, &reg_requests_list);
+ }
+ spin_unlock(&reg_requests_lock);
+
+ mutex_unlock(&reg_mutex);
+ mutex_unlock(&cfg80211_mutex);
+
+ REG_DBG_PRINT("Kicking the queue\n");
+
+ schedule_work(&reg_work);
+}
void regulatory_hint_disconnect(void)
{
@@ -2125,6 +2183,13 @@ out:
mutex_unlock(&reg_mutex);
}
+static void reg_timeout_work(struct work_struct *work)
+{
+ REG_DBG_PRINT("Timeout while waiting for CRDA to reply, "
+ "restoring regulatory settings");
+ restore_regulatory_settings(true);
+}
+
int __init regulatory_init(void)
{
int err = 0;
@@ -2178,6 +2243,7 @@ void /* __init_or_exit */ regulatory_exit(void)
struct reg_beacon *reg_beacon, *btmp;
cancel_work_sync(&reg_work);
+ cancel_delayed_work_sync(&reg_timeout);
mutex_lock(&cfg80211_mutex);
mutex_lock(&reg_mutex);
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index fbf6f33ae4d..73a441d237b 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -93,6 +93,69 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
}
EXPORT_SYMBOL(cfg80211_scan_done);
+void __cfg80211_sched_scan_results(struct work_struct *wk)
+{
+ struct cfg80211_registered_device *rdev;
+
+ rdev = container_of(wk, struct cfg80211_registered_device,
+ sched_scan_results_wk);
+
+ cfg80211_lock_rdev(rdev);
+
+ /* we don't have sched_scan_req anymore if the scan is stopping */
+ if (rdev->sched_scan_req)
+ nl80211_send_sched_scan_results(rdev,
+ rdev->sched_scan_req->dev);
+
+ cfg80211_unlock_rdev(rdev);
+}
+
+void cfg80211_sched_scan_results(struct wiphy *wiphy)
+{
+ /* ignore if we're not scanning */
+ if (wiphy_to_dev(wiphy)->sched_scan_req)
+ queue_work(cfg80211_wq,
+ &wiphy_to_dev(wiphy)->sched_scan_results_wk);
+}
+EXPORT_SYMBOL(cfg80211_sched_scan_results);
+
+void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
+{
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+ cfg80211_lock_rdev(rdev);
+ __cfg80211_stop_sched_scan(rdev, true);
+ cfg80211_unlock_rdev(rdev);
+}
+EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
+
+int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
+ bool driver_initiated)
+{
+ int err;
+ struct net_device *dev;
+
+ ASSERT_RDEV_LOCK(rdev);
+
+ if (!rdev->sched_scan_req)
+ return 0;
+
+ dev = rdev->sched_scan_req->dev;
+
+ if (!driver_initiated) {
+ err = rdev->ops->sched_scan_stop(&rdev->wiphy, dev);
+ if (err)
+ return err;
+ }
+
+ nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED);
+
+ kfree(rdev->sched_scan_req);
+ rdev->sched_scan_req = NULL;
+
+ return err;
+}
+
static void bss_release(struct kref *ref)
{
struct cfg80211_internal_bss *bss;
@@ -210,7 +273,7 @@ static bool is_mesh(struct cfg80211_bss *a,
{
const u8 *ie;
- if (!is_zero_ether_addr(a->bssid))
+ if (!WLAN_CAPABILITY_IS_MBSS(a->capability))
return false;
ie = cfg80211_find_ie(WLAN_EID_MESH_ID,
@@ -248,11 +311,7 @@ static int cmp_bss(struct cfg80211_bss *a,
if (a->channel != b->channel)
return b->channel->center_freq - a->channel->center_freq;
- r = memcmp(a->bssid, b->bssid, ETH_ALEN);
- if (r)
- return r;
-
- if (is_zero_ether_addr(a->bssid)) {
+ if (WLAN_CAPABILITY_IS_MBSS(a->capability | b->capability)) {
r = cmp_ies(WLAN_EID_MESH_ID,
a->information_elements,
a->len_information_elements,
@@ -267,6 +326,10 @@ static int cmp_bss(struct cfg80211_bss *a,
b->len_information_elements);
}
+ r = memcmp(a->bssid, b->bssid, ETH_ALEN);
+ if (r)
+ return r;
+
return cmp_ies(WLAN_EID_SSID,
a->information_elements,
a->len_information_elements,
@@ -407,7 +470,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
res->ts = jiffies;
- if (is_zero_ether_addr(res->pub.bssid)) {
+ if (WLAN_CAPABILITY_IS_MBSS(res->pub.capability)) {
/* must be mesh, verify */
meshid = cfg80211_find_ie(WLAN_EID_MESH_ID,
res->pub.information_elements,
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 4294fa22bb2..c6e4ca6a7d2 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -93,7 +93,7 @@ static int wiphy_suspend(struct device *dev, pm_message_t state)
if (rdev->ops->suspend) {
rtnl_lock();
- ret = rdev->ops->suspend(&rdev->wiphy);
+ ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan);
rtnl_unlock();
}
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 6a750bc6bcf..f0536d44d43 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -544,7 +544,8 @@ EXPORT_SYMBOL(ieee80211_data_from_8023);
void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
const u8 *addr, enum nl80211_iftype iftype,
- const unsigned int extra_headroom)
+ const unsigned int extra_headroom,
+ bool has_80211_header)
{
struct sk_buff *frame = NULL;
u16 ethertype;
@@ -553,14 +554,18 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
int remaining, err;
u8 dst[ETH_ALEN], src[ETH_ALEN];
- err = ieee80211_data_to_8023(skb, addr, iftype);
- if (err)
- goto out;
+ if (has_80211_header) {
+ err = ieee80211_data_to_8023(skb, addr, iftype);
+ if (err)
+ goto out;
- /* skip the wrapping header */
- eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr));
- if (!eth)
- goto out;
+ /* skip the wrapping header */
+ eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr));
+ if (!eth)
+ goto out;
+ } else {
+ eth = (struct ethhdr *) skb->data;
+ }
while (skb != frame) {
u8 padding;
@@ -803,6 +808,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
return -EBUSY;
if (ntype != otype) {
+ err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr,
+ ntype);
+ if (err)
+ return err;
+
dev->ieee80211_ptr->use_4addr = false;
dev->ieee80211_ptr->mesh_id_up_len = 0;
@@ -896,3 +906,103 @@ u16 cfg80211_calculate_bitrate(struct rate_info *rate)
/* do NOT round down here */
return (bitrate + 50000) / 100000;
}
+
+int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
+ u32 beacon_int)
+{
+ struct wireless_dev *wdev;
+ int res = 0;
+
+ if (!beacon_int)
+ return -EINVAL;
+
+ mutex_lock(&rdev->devlist_mtx);
+
+ list_for_each_entry(wdev, &rdev->netdev_list, list) {
+ if (!wdev->beacon_interval)
+ continue;
+ if (wdev->beacon_interval != beacon_int) {
+ res = -EINVAL;
+ break;
+ }
+ }
+
+ mutex_unlock(&rdev->devlist_mtx);
+
+ return res;
+}
+
+int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev,
+ enum nl80211_iftype iftype)
+{
+ struct wireless_dev *wdev_iter;
+ int num[NUM_NL80211_IFTYPES];
+ int total = 1;
+ int i, j;
+
+ ASSERT_RTNL();
+
+ /* Always allow software iftypes */
+ if (rdev->wiphy.software_iftypes & BIT(iftype))
+ return 0;
+
+ /*
+ * Drivers will gradually all set this flag, until all
+ * have it we only enforce for those that set it.
+ */
+ if (!(rdev->wiphy.flags & WIPHY_FLAG_ENFORCE_COMBINATIONS))
+ return 0;
+
+ memset(num, 0, sizeof(num));
+
+ num[iftype] = 1;
+
+ mutex_lock(&rdev->devlist_mtx);
+ list_for_each_entry(wdev_iter, &rdev->netdev_list, list) {
+ if (wdev_iter == wdev)
+ continue;
+ if (!netif_running(wdev_iter->netdev))
+ continue;
+
+ if (rdev->wiphy.software_iftypes & BIT(wdev_iter->iftype))
+ continue;
+
+ num[wdev_iter->iftype]++;
+ total++;
+ }
+ mutex_unlock(&rdev->devlist_mtx);
+
+ for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) {
+ const struct ieee80211_iface_combination *c;
+ struct ieee80211_iface_limit *limits;
+
+ c = &rdev->wiphy.iface_combinations[i];
+
+ limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits,
+ GFP_KERNEL);
+ if (!limits)
+ return -ENOMEM;
+ if (total > c->max_interfaces)
+ goto cont;
+
+ for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) {
+ if (rdev->wiphy.software_iftypes & BIT(iftype))
+ continue;
+ for (j = 0; j < c->n_limits; j++) {
+ if (!(limits[j].types & iftype))
+ continue;
+ if (limits[j].max < num[iftype])
+ goto cont;
+ limits[j].max -= num[iftype];
+ }
+ }
+ /* yay, it fits */
+ kfree(limits);
+ return 0;
+ cont:
+ kfree(limits);
+ }
+
+ return -EBUSY;
+}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index b4d745ea8ee..9bec2e8a838 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1348,7 +1348,8 @@ static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family)
default:
BUG();
}
- xdst = dst_alloc(dst_ops, 0);
+ xdst = dst_alloc(dst_ops, NULL, 0, 0, 0);
+ memset(&xdst->u.rt6.rt6i_table, 0, sizeof(*xdst) - sizeof(struct dst_entry));
xfrm_policy_put_afinfo(afinfo);
if (likely(xdst))
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index dd78536d40d..d70f85eb786 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1036,15 +1036,15 @@ static struct xfrm_state *__find_acq_core(struct net *net, struct xfrm_mark *m,
case AF_INET6:
ipv6_addr_copy((struct in6_addr *)x->sel.daddr.a6,
- (struct in6_addr *)daddr);
+ (const struct in6_addr *)daddr);
ipv6_addr_copy((struct in6_addr *)x->sel.saddr.a6,
- (struct in6_addr *)saddr);
+ (const struct in6_addr *)saddr);
x->sel.prefixlen_d = 128;
x->sel.prefixlen_s = 128;
ipv6_addr_copy((struct in6_addr *)x->props.saddr.a6,
- (struct in6_addr *)saddr);
+ (const struct in6_addr *)saddr);
ipv6_addr_copy((struct in6_addr *)x->id.daddr.a6,
- (struct in6_addr *)daddr);
+ (const struct in6_addr *)daddr);
break;
}
@@ -2092,8 +2092,8 @@ static void xfrm_audit_helper_sainfo(struct xfrm_state *x,
static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family,
struct audit_buffer *audit_buf)
{
- struct iphdr *iph4;
- struct ipv6hdr *iph6;
+ const struct iphdr *iph4;
+ const struct ipv6hdr *iph6;
switch (family) {
case AF_INET:
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 88f3f07205f..e26e2fb462d 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -702,6 +702,24 @@ static int do_ssb_entry(const char *filename,
return 1;
}
+/* Looks like: bcma:mNidNrevNclN. */
+static int do_bcma_entry(const char *filename,
+ struct bcma_device_id *id, char *alias)
+{
+ id->manuf = TO_NATIVE(id->manuf);
+ id->id = TO_NATIVE(id->id);
+ id->rev = TO_NATIVE(id->rev);
+ id->class = TO_NATIVE(id->class);
+
+ strcpy(alias, "bcma:");
+ ADD(alias, "m", id->manuf != BCMA_ANY_MANUF, id->manuf);
+ ADD(alias, "id", id->id != BCMA_ANY_ID, id->id);
+ ADD(alias, "rev", id->rev != BCMA_ANY_REV, id->rev);
+ ADD(alias, "cl", id->class != BCMA_ANY_CLASS, id->class);
+ add_wildcard(alias);
+ return 1;
+}
+
/* Looks like: virtio:dNvN */
static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
char *alias)
@@ -968,6 +986,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
do_table(symval, sym->st_size,
sizeof(struct ssb_device_id), "ssb",
do_ssb_entry, mod);
+ else if (sym_is(symname, "__mod_bcma_device_table"))
+ do_table(symval, sym->st_size,
+ sizeof(struct bcma_device_id), "bcma",
+ do_bcma_entry, mod);
else if (sym_is(symname, "__mod_virtio_device_table"))
do_table(symval, sym->st_size,
sizeof(struct virtio_device_id), "virtio",